diff --git a/on-premise/cicd/gitea/1_configure/5_secret.yaml b/on-premise/cicd/gitea/1_configure/5_secret.yaml index 2041b65..2016f39 100644 --- a/on-premise/cicd/gitea/1_configure/5_secret.yaml +++ b/on-premise/cicd/gitea/1_configure/5_secret.yaml @@ -63,12 +63,12 @@ stringData: security: INSTALL_LOCK=true server: |- APP_DATA_PATH=/data - DOMAIN=gitea.nativedeck.com + DOMAIN=gitea.inje-private.com ENABLE_PPROF=false HTTP_PORT=3000 PROTOCOL=http - ROOT_URL=http://gitea.nativedeck.com - SSH_DOMAIN=gitea.nativedeck.com + ROOT_URL=http://gitea.inje-private.com + SSH_DOMAIN=gitea.inje-private.com SSH_LISTEN_PORT=2222 SSH_PORT=22 START_SSH_SERVER=true @@ -178,7 +178,7 @@ stringData: local section="$(basename "${config_file}")" if [[ $section == '_generals_' ]]; then - env2ini::log " [ini root]" + section='' else env2ini::log " ${section}" diff --git a/on-premise/cicd/gitea/1_configure/6_pvc.yaml b/on-premise/cicd/gitea/1_configure/6_pvc.yaml index 1e8acf0..4bd0724 100644 --- a/on-premise/cicd/gitea/1_configure/6_pvc.yaml +++ b/on-premise/cicd/gitea/1_configure/6_pvc.yaml @@ -8,6 +8,7 @@ spec: accessModes: - ReadWriteOnce volumeMode: Filesystem + storageClassName: sc-monitoring resources: requests: - storage: 200Gi # default: 10Gi + storage: 50Gi # default: 10Gi diff --git a/on-premise/cicd/gitea/3_apply/1 b/on-premise/cicd/gitea/3_apply/1 new file mode 100644 index 0000000..a495c89 --- /dev/null +++ b/on-premise/cicd/gitea/3_apply/1 @@ -0,0 +1,815 @@ +# Source: gitea/charts/postgresql-ha/templates/pgpool/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: release-name-postgresql-ha-pgpool + namespace: gitea + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/version: 4.5.2 + app.kubernetes.io/component: pgpool +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/component: pgpool + template: + metadata: + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/version: 4.5.2 + app.kubernetes.io/component: pgpool + spec: + + automountServiceAccountToken: false + affinity: + podAffinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/component: pgpool + topologyKey: kubernetes.io/hostname + weight: 1 + nodeAffinity: + + securityContext: + fsGroup: 1001 + fsGroupChangePolicy: Always + supplementalGroups: [] + sysctls: [] + serviceAccountName: release-name-postgresql-ha + # Auxiliary vars to populate environment variables + containers: + - name: pgpool + image: reg.inje-private.com/bitnami/pgpool:4.5.2-debian-12-r2 + imagePullPolicy: "IfNotPresent" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1001 + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + env: + - name: BITNAMI_DEBUG + value: "false" + - name: PGPOOL_BACKEND_NODES + value: 0:release-name-postgresql-ha-postgresql-0.release-name-postgresql-ha-postgresql-headless:5432,1:release-name-postgresql-ha-postgresql-1.release-name-postgresql-ha-postgresql-headless:5432,2:release-name-postgresql-ha-postgresql-2.release-name-postgresql-ha-postgresql-headless:5432, + - name: PGPOOL_SR_CHECK_USER + value: "repmgr" + - name: PGPOOL_SR_CHECK_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-postgresql + key: repmgr-password + - name: PGPOOL_SR_CHECK_DATABASE + value: "postgres" + - name: PGPOOL_ENABLE_LDAP + value: "no" + - name: PGPOOL_POSTGRES_USERNAME + value: "gitea" + - name: PGPOOL_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-postgresql + key: password + - name: PGPOOL_ADMIN_USERNAME + value: "admin" + - name: PGPOOL_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-pgpool + key: admin-password + - name: PGPOOL_AUTHENTICATION_METHOD + value: "scram-sha-256" + - name: PGPOOL_ENABLE_LOAD_BALANCING + value: "yes" + - name: PGPOOL_DISABLE_LOAD_BALANCE_ON_WRITE + value: "transaction" + - name: PGPOOL_ENABLE_LOG_CONNECTIONS + value: "no" + - name: PGPOOL_ENABLE_LOG_HOSTNAME + value: "yes" + - name: PGPOOL_ENABLE_LOG_PER_NODE_STATEMENT + value: "no" + - name: PGPOOL_RESERVED_CONNECTIONS + value: '1' + - name: PGPOOL_CHILD_LIFE_TIME + value: "" + - name: PGPOOL_ENABLE_TLS + value: "no" + - name: PGPOOL_HEALTH_CHECK_PSQL_TIMEOUT + value: "6" + envFrom: + ports: + - name: postgresql + containerPort: 5432 + protocol: TCP + livenessProbe: + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - /opt/bitnami/scripts/pgpool/healthcheck.sh + readinessProbe: + failureThreshold: 5 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - bash + - -ec + - PGPASSWORD=${PGPOOL_POSTGRES_PASSWORD} psql -U "gitea" -d "gitea" -h /opt/bitnami/pgpool/tmp -tA -c "SELECT 1" >/dev/null + resources: + limits: + cpu: 375m + ephemeral-storage: 2Gi + memory: 384Mi + requests: + cpu: 250m + ephemeral-storage: 50Mi + memory: 256Mi + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/pgpool/etc + subPath: app-etc-dir + - name: empty-dir + mountPath: /opt/bitnami/pgpool/conf + subPath: app-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/pgpool/tmp + subPath: app-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/pgpool/logs + subPath: app-logs-dir + volumes: + - name: empty-dir + emptyDir: {} +--- +# Source: gitea/templates/gitea/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: release-name-gitea + namespace: gitea + annotations: + labels: + app: gitea + app.kubernetes.io/name: gitea + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "1.22.1" + version: "1.22.1" +spec: + replicas: 1 + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 100% + selector: + matchLabels: + app.kubernetes.io/name: gitea + app.kubernetes.io/instance: release-name + template: + metadata: + annotations: + checksum/config: 00fd8064076a446a896870db4974c6590fcf51561cf391547e559011465a57d8 + labels: + app: gitea + app.kubernetes.io/name: gitea + app.kubernetes.io/instance: release-name + app.kubernetes.io/version: "1.22.1" + version: "1.22.1" + spec: + + securityContext: + fsGroup: 1000 + initContainers: + - name: init-directories + image: "reg.inje-private.com/nnd002/gitea/gitea:1.22.1-rootless" + imagePullPolicy: IfNotPresent + command: ["/usr/sbin/init_directory_structure.sh"] + env: + - name: GITEA_APP_INI + value: /data/gitea/conf/app.ini + - name: GITEA_CUSTOM + value: /data/gitea + - name: GITEA_WORK_DIR + value: /data + - name: GITEA_TEMP + value: /tmp/gitea + volumeMounts: + - name: init + mountPath: /usr/sbin + - name: temp + mountPath: /tmp + - name: data + mountPath: /data + + securityContext: + {} + resources: + limits: {} + requests: + cpu: 100m + memory: 128Mi + - name: init-app-ini + image: "gitea/gitea:1.22.1-rootless" + imagePullPolicy: IfNotPresent + command: ["/usr/sbin/config_environment.sh"] + env: + - name: GITEA_APP_INI + value: /data/gitea/conf/app.ini + - name: GITEA_CUSTOM + value: /data/gitea + - name: GITEA_WORK_DIR + value: /data + - name: GITEA_TEMP + value: /tmp/gitea + volumeMounts: + - name: config + mountPath: /usr/sbin + - name: temp + mountPath: /tmp + - name: data + mountPath: /data + - name: inline-config-sources + mountPath: /env-to-ini-mounts/inlines/ + + securityContext: + {} + resources: + limits: {} + requests: + cpu: 100m + memory: 128Mi + - name: configure-gitea + image: "gitea/gitea:1.22.1-rootless" + command: ["/usr/sbin/configure_gitea.sh"] + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: 1000 + env: + - name: GITEA_APP_INI + value: /data/gitea/conf/app.ini + - name: GITEA_CUSTOM + value: /data/gitea + - name: GITEA_WORK_DIR + value: /data + - name: GITEA_TEMP + value: /tmp/gitea + - name: HOME + value: /data/gitea/git + - name: GITEA_ADMIN_USERNAME + value: "gitea_admin" + - name: GITEA_ADMIN_PASSWORD + value: "ijinc123!" # sdjo + - name: GITEA_ADMIN_PASSWORD_MODE + value: keepUpdated + volumeMounts: + - name: init + mountPath: /usr/sbin + - name: temp + mountPath: /tmp + - name: data + mountPath: /data + + resources: + limits: {} + requests: + cpu: 100m + memory: 128Mi + terminationGracePeriodSeconds: 60 + containers: + - name: gitea + image: "gitea/gitea:1.22.1-rootless" + imagePullPolicy: IfNotPresent + env: + # SSH Port values have to be set here as well for openssh configuration + - name: SSH_LISTEN_PORT + value: "2222" + - name: SSH_PORT + value: "22" + - name: GITEA_APP_INI + value: /data/gitea/conf/app.ini + - name: GITEA_CUSTOM + value: /data/gitea + - name: GITEA_WORK_DIR + value: /data + - name: GITEA_TEMP + value: /tmp/gitea + - name: TMPDIR + value: /tmp/gitea + - name: HOME + value: /data/gitea/git + ports: + - name: ssh + containerPort: 2222 + - name: http + containerPort: 3000 + livenessProbe: + failureThreshold: 10 + initialDelaySeconds: 200 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: http + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + tcpSocket: + port: http + timeoutSeconds: 1 + resources: + {} + securityContext: + {} + volumeMounts: + - name: temp + mountPath: /tmp + - name: data + mountPath: /data + + volumes: + - name: init + secret: + secretName: release-name-gitea-init + defaultMode: 110 + - name: config + secret: + secretName: release-name-gitea + defaultMode: 110 + - name: inline-config-sources + secret: + secretName: release-name-gitea-inline-config + - name: temp + emptyDir: {} + - name: data + persistentVolumeClaim: + claimName: gitea-shared-storage +--- +# Source: gitea/charts/postgresql-ha/templates/postgresql/statefulset.yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: release-name-postgresql-ha-postgresql + namespace: "gitea" + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/version: 16.3.0 + app.kubernetes.io/component: postgresql + role: data +spec: + replicas: 3 + podManagementPolicy: "Parallel" + serviceName: release-name-postgresql-ha-postgresql-headless + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/component: postgresql + role: data + template: + metadata: + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/version: 16.3.0 + app.kubernetes.io/component: postgresql + role: data + spec: + + automountServiceAccountToken: false + affinity: + podAffinity: + + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: postgresql-ha + app.kubernetes.io/component: postgresql + topologyKey: kubernetes.io/hostname + weight: 1 + nodeAffinity: + + securityContext: + fsGroup: 1001 + fsGroupChangePolicy: Always + supplementalGroups: [] + sysctls: [] + serviceAccountName: release-name-postgresql-ha + hostNetwork: false + hostIPC: false + containers: + - name: postgresql + image: docker.io/bitnami/postgresql-repmgr:16.3.0-debian-12-r15 + imagePullPolicy: "IfNotPresent" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1001 + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + lifecycle: + preStop: + exec: + command: + - /pre-stop.sh + - "25" + # Auxiliary vars to populate environment variables + env: + - name: BITNAMI_DEBUG + value: "false" + # PostgreSQL configuration + - name: POSTGRESQL_VOLUME_DIR + value: "/bitnami/postgresql" + - name: PGDATA + value: "/bitnami/postgresql/data" + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-postgresql + key: postgres-password + - name: POSTGRES_USER + value: "gitea" + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-postgresql + key: password + - name: POSTGRES_DB + value: "gitea" + - name: POSTGRESQL_LOG_HOSTNAME + value: "true" + - name: POSTGRESQL_LOG_CONNECTIONS + value: "false" + - name: POSTGRESQL_LOG_DISCONNECTIONS + value: "false" + - name: POSTGRESQL_PGAUDIT_LOG_CATALOG + value: "off" + - name: POSTGRESQL_CLIENT_MIN_MESSAGES + value: "error" + - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES + value: "pgaudit, repmgr" + - name: POSTGRESQL_ENABLE_TLS + value: "no" + - name: POSTGRESQL_PORT_NUMBER + value: "5432" + # Repmgr configuration + - name: REPMGR_PORT_NUMBER + value: "5432" + - name: REPMGR_PRIMARY_PORT + value: "5432" + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: REPMGR_UPGRADE_EXTENSION + value: "no" + - name: REPMGR_PGHBA_TRUST_ALL + value: "no" + - name: REPMGR_MOUNTED_CONF_DIR + value: "/bitnami/repmgr/conf" + - name: REPMGR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: REPMGR_PARTNER_NODES + value: release-name-postgresql-ha-postgresql-0.release-name-postgresql-ha-postgresql-headless.$(REPMGR_NAMESPACE).svc.cluster.local,release-name-postgresql-ha-postgresql-1.release-name-postgresql-ha-postgresql-headless.$(REPMGR_NAMESPACE).svc.cluster.local,release-name-postgresql-ha-postgresql-2.release-name-postgresql-ha-postgresql-headless.$(REPMGR_NAMESPACE).svc.cluster.local, + - name: REPMGR_PRIMARY_HOST + value: "release-name-postgresql-ha-postgresql-0.release-name-postgresql-ha-postgresql-headless.$(REPMGR_NAMESPACE).svc.cluster.local" + - name: REPMGR_NODE_NAME + value: "$(MY_POD_NAME)" + - name: REPMGR_NODE_NETWORK_NAME + value: "$(MY_POD_NAME).release-name-postgresql-ha-postgresql-headless.$(REPMGR_NAMESPACE).svc.cluster.local" + - name: REPMGR_NODE_TYPE + value: "data" + - name: REPMGR_LOG_LEVEL + value: "NOTICE" + - name: REPMGR_CONNECT_TIMEOUT + value: "5" + - name: REPMGR_RECONNECT_ATTEMPTS + value: "2" + - name: REPMGR_RECONNECT_INTERVAL + value: "3" + - name: REPMGR_USERNAME + value: "repmgr" + - name: REPMGR_PASSWORD + valueFrom: + secretKeyRef: + name: release-name-postgresql-ha-postgresql + key: repmgr-password + - name: REPMGR_DATABASE + value: "repmgr" + - name: REPMGR_FENCE_OLD_PRIMARY + value: "no" + - name: REPMGR_CHILD_NODES_CHECK_INTERVAL + value: "5" + - name: REPMGR_CHILD_NODES_CONNECTED_MIN_COUNT + value: "1" + - name: REPMGR_CHILD_NODES_DISCONNECT_TIMEOUT + value: "30" + envFrom: + ports: + - name: postgresql + containerPort: 5432 + protocol: TCP + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - bash + - -ec + - 'PGPASSWORD=$POSTGRES_PASSWORD psql -w -U "gitea" -d "gitea" -h 127.0.0.1 -p 5432 -c "SELECT 1"' + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - bash + - -ec + - | + exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432 + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] + resources: + limits: + cpu: 375m + ephemeral-storage: 2Gi + memory: 384Mi + requests: + cpu: 250m + ephemeral-storage: 50Mi + memory: 256Mi + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/postgresql/conf + subPath: app-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/postgresql/tmp + subPath: app-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/repmgr/conf + subPath: repmgr-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/repmgr/tmp + subPath: repmgr-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/repmgr/logs + subPath: repmgr-logs-dir + - name: data + mountPath: /bitnami/postgresql + - name: hooks-scripts + mountPath: /pre-stop.sh + subPath: pre-stop.sh + - name: hooks-scripts + mountPath: /readiness-probe.sh + subPath: readiness-probe.sh + volumes: + - name: empty-dir + emptyDir: {} + - name: hooks-scripts + configMap: + name: release-name-postgresql-ha-postgresql-hooks-scripts + defaultMode: 0755 + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: "8Gi" +--- +# Source: gitea/charts/redis-cluster/templates/redis-statefulset.yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: release-name-redis-cluster + namespace: "gitea" + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: redis-cluster + app.kubernetes.io/version: 7.2.5 +spec: + updateStrategy: + rollingUpdate: + partition: 0 + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: redis-cluster + replicas: 3 + serviceName: release-name-redis-cluster-headless + podManagementPolicy: Parallel + template: + metadata: + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: redis-cluster + app.kubernetes.io/version: 7.2.5 + annotations: + checksum/scripts: f4443ed238f1b19ab40555e6ba2aea56daba79e8270549f884b9b31cf8e0e2ee + checksum/secret: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + checksum/config: 958b865b26062946819f240fe4e5fd268b7c3203b944549981f1bd7fdc7947eb + spec: + hostNetwork: false + enableServiceLinks: false + + securityContext: + fsGroup: 1001 + fsGroupChangePolicy: Always + supplementalGroups: [] + sysctls: [] + serviceAccountName: release-name-redis-cluster + automountServiceAccountToken: false + affinity: + podAffinity: + + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: redis-cluster + topologyKey: kubernetes.io/hostname + weight: 1 + nodeAffinity: + + containers: + - name: release-name-redis-cluster + image: docker.io/bitnami/redis-cluster:7.2.5-debian-12-r2 + imagePullPolicy: "IfNotPresent" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1001 + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + command: ['/bin/bash', '-c'] + args: + - | + # Backwards compatibility change + if ! [[ -f /opt/bitnami/redis/etc/redis.conf ]]; then + echo COPYING FILE + cp /opt/bitnami/redis/etc/redis-default.conf /opt/bitnami/redis/etc/redis.conf + fi + pod_index=($(echo "$POD_NAME" | tr "-" "\n")) + pod_index="${pod_index[-1]}" + if [[ "$pod_index" == "0" ]]; then + export REDIS_CLUSTER_CREATOR="yes" + export REDIS_CLUSTER_REPLICAS="0" + fi + /opt/bitnami/scripts/redis-cluster/entrypoint.sh /opt/bitnami/scripts/redis-cluster/run.sh + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: REDIS_NODES + value: "release-name-redis-cluster-0.release-name-redis-cluster-headless release-name-redis-cluster-1.release-name-redis-cluster-headless release-name-redis-cluster-2.release-name-redis-cluster-headless " + - name: ALLOW_EMPTY_PASSWORD + value: "yes" + - name: REDIS_AOF_ENABLED + value: "yes" + - name: REDIS_TLS_ENABLED + value: "no" + - name: REDIS_PORT_NUMBER + value: "6379" + ports: + - name: tcp-redis + containerPort: 6379 + - name: tcp-redis-bus + containerPort: 16379 + livenessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + # One second longer than command timeout should prevent generation of zombie processes. + timeoutSeconds: 6 + successThreshold: 1 + failureThreshold: 5 + exec: + command: + - sh + - -c + - /scripts/ping_liveness_local.sh 5 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + # One second longer than command timeout should prevent generation of zombie processes. + timeoutSeconds: 2 + successThreshold: 1 + failureThreshold: 5 + exec: + command: + - sh + - -c + - /scripts/ping_readiness_local.sh 1 + resources: + limits: + cpu: 150m + ephemeral-storage: 2Gi + memory: 192Mi + requests: + cpu: 100m + ephemeral-storage: 50Mi + memory: 128Mi + volumeMounts: + - name: scripts + mountPath: /scripts + - name: redis-data + mountPath: /bitnami/redis/data + subPath: + - name: default-config + mountPath: /opt/bitnami/redis/etc/redis-default.conf + subPath: redis-default.conf + - name: empty-dir + mountPath: /opt/bitnami/redis/etc/ + subPath: app-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/redis/tmp + subPath: app-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/redis/logs + subPath: app-logs-dir + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + volumes: + - name: scripts + configMap: + name: release-name-redis-cluster-scripts + defaultMode: 0755 + - name: default-config + configMap: + name: release-name-redis-cluster-default + - name: empty-dir + emptyDir: {} + volumeClaimTemplates: + - metadata: + name: redis-data + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: redis-cluster + spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: "8Gi" diff --git a/on-premise/cicd/gitea/3_apply/deploy.yaml b/on-premise/cicd/gitea/3_apply/deploy.yaml index 38958fb..f2520a9 100644 --- a/on-premise/cicd/gitea/3_apply/deploy.yaml +++ b/on-premise/cicd/gitea/3_apply/deploy.yaml @@ -49,7 +49,7 @@ spec: # Auxiliary vars to populate environment variables containers: - name: pgpool - image: docker.io/bitnami/pgpool:4.5.2-debian-12-r2 + image: reg.inje-private.com/nnd002/bitnami/pgpool:4.5.2-debian-12-r2 imagePullPolicy: "IfNotPresent" securityContext: allowPrivilegeEscalation: false @@ -207,7 +207,7 @@ spec: fsGroup: 1000 initContainers: - name: init-directories - image: "gitea/gitea:1.22.1-rootless" + image: "reg.inje-private.com/nnd002/gitea/gitea:1.22.1-rootless" imagePullPolicy: IfNotPresent command: ["/usr/sbin/init_directory_structure.sh"] env: @@ -235,7 +235,7 @@ spec: cpu: 100m memory: 128Mi - name: init-app-ini - image: "gitea/gitea:1.22.1-rootless" + image: "reg.inje-private.com/nnd002/gitea/gitea:1.22.1-rootless" imagePullPolicy: IfNotPresent command: ["/usr/sbin/config_environment.sh"] env: @@ -265,7 +265,7 @@ spec: cpu: 100m memory: 128Mi - name: configure-gitea - image: "gitea/gitea:1.22.1-rootless" + image: "reg.inje-private.com/nnd002/gitea/gitea:1.22.1-rootless" command: ["/usr/sbin/configure_gitea.sh"] imagePullPolicy: IfNotPresent securityContext: @@ -303,7 +303,7 @@ spec: terminationGracePeriodSeconds: 60 containers: - name: gitea - image: "gitea/gitea:1.22.1-rootless" + image: "reg.inje-private.com/nnd002/gitea/gitea:1.22.1-rootless" imagePullPolicy: IfNotPresent env: # SSH Port values have to be set here as well for openssh configuration @@ -432,7 +432,7 @@ spec: hostIPC: false containers: - name: postgresql - image: docker.io/bitnami/postgresql-repmgr:16.3.0-debian-12-r15 + image: reg.inje-private.com/nnd002/bitnami/postgresql-repmgr:16.3.0-debian-12-r15 imagePullPolicy: "IfNotPresent" securityContext: allowPrivilegeEscalation: false @@ -629,7 +629,7 @@ spec: requests: storage: "8Gi" --- -# Source: gitea/charts/redis-cluster/templates/redis-statefulset.yaml +# Source: cdgitea/charts/redis-cluster/templates/redis-statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: @@ -688,7 +688,7 @@ spec: containers: - name: release-name-redis-cluster - image: docker.io/bitnami/redis-cluster:7.2.5-debian-12-r2 + image: reg.inje-private.com/nnd002/bitnami/redis-cluster:7.2.5-debian-12-r2 imagePullPolicy: "IfNotPresent" securityContext: allowPrivilegeEscalation: false diff --git a/on-premise/cicd/gitea/3_apply/ing.yaml b/on-premise/cicd/gitea/3_apply/ing.yaml index cb7790a..f0504a2 100644 --- a/on-premise/cicd/gitea/3_apply/ing.yaml +++ b/on-premise/cicd/gitea/3_apply/ing.yaml @@ -9,7 +9,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: gitea.nativedeck.com + - host: gitea.inje-private.com http: paths: - path: / @@ -21,6 +21,6 @@ spec: number: 3000 tls: - hosts: - - "gitea.nativedeck.com" - secretName: secret-gitea-ssl + - "gitea.inje-private.com" + secretName: gitea-ssl diff --git a/on-premise/logging/fluentbit_v3.1.7/1_configure/init.yaml b/on-premise/logging/fluentbit_v3.1.7/1_configure/init.yaml index 39813e2..1a93b50 100644 --- a/on-premise/logging/fluentbit_v3.1.7/1_configure/init.yaml +++ b/on-premise/logging/fluentbit_v3.1.7/1_configure/init.yaml @@ -1,3 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: logging + --- # Source: fluent-bit/templates/serviceaccount.yaml apiVersion: v1 @@ -52,4 +57,4 @@ roleRef: subjects: - kind: ServiceAccount name: fluent-bit - namespace: logging \ No newline at end of file + namespace: logging diff --git a/on-premise/logging/fluentbit_v3.1.7/2_config/custom.yaml b/on-premise/logging/fluentbit_v3.1.7/2_config/custom.yaml new file mode 100644 index 0000000..eddda2e --- /dev/null +++ b/on-premise/logging/fluentbit_v3.1.7/2_config/custom.yaml @@ -0,0 +1,69 @@ +# Source: fluent-bit/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluent-bit + namespace: logging + labels: + helm.sh/chart: fluent-bit-0.47.9 + app.kubernetes.io/name: fluent-bit + app.kubernetes.io/instance: fluent-bit + app.kubernetes.io/version: "3.1.7" + app.kubernetes.io/managed-by: Helm +data: + custom_parsers.conf: | + [PARSER] + Name docker_no_time + Format json + Time_Keep Off + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + fluent-bit.conf: | + [SERVICE] + Daemon Off + Flush 1 + Log_Level info + Parsers_File /fluent-bit/etc/parsers.conf + Parsers_File /fluent-bit/etc/conf/custom_parsers.conf + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_Port 2020 + Health_Check On + + [INPUT] + Name tail + Path /var/log/containers/*.log + multiline.parser docker, cri + # DB /var/fluent-bit/state/flb_log.db + Tag kube.* + Mem_Buf_Limit 5MB + Skip_Long_Lines On + + + [FILTER] + Name kubernetes + Match kube.* + Merge_Log On + Keep_Log Off + K8S-Logging.Parser On + K8S-Logging.Exclude On + + # [FILTER] + # Name record_modifier + # Match kube.* + # Record namespace ${_score} + + [OUTPUT] + Name es + Match kube.* + Host 172.17.128.246 + HTTP_User admin + HTTP_Passwd admin + Index fluent-bit10--%Y.%m.%d + Logstash_Format On + Logstash_Prefix_Key $kubernetes['namespace_name'] + Suppress_Type_Name On + tls On + tls.Verify Off + Retry_Limit False + diff --git a/on-premise/logging/fluentbit_v3.1.7/3_apply/debug.yaml b/on-premise/logging/fluentbit_v3.1.7/3_apply/debug.yaml index 7ac0ac9..2372e5e 100644 --- a/on-premise/logging/fluentbit_v3.1.7/3_apply/debug.yaml +++ b/on-premise/logging/fluentbit_v3.1.7/3_apply/debug.yaml @@ -134,4 +134,4 @@ spec: - name: file-save # 있음 hostPath: path: /home/ubuntu - \ No newline at end of file + diff --git a/on-premise/logging/fluentbit_v3.1.7/3_apply/default.yaml b/on-premise/logging/fluentbit_v3.1.7/3_apply/default.yaml index 9409aec..c929aca 100644 --- a/on-premise/logging/fluentbit_v3.1.7/3_apply/default.yaml +++ b/on-premise/logging/fluentbit_v3.1.7/3_apply/default.yaml @@ -51,7 +51,7 @@ spec: dnsPolicy: ClusterFirst containers: - name: fluent-bit - image: "cr.fluentbit.io/fluent/fluent-bit:3.1.7" + image: "reg.inje-private.com/nnd002/fluent/fluent-bit:3.1.7" imagePullPolicy: IfNotPresent command: - /fluent-bit/bin/fluent-bit @@ -129,4 +129,4 @@ spec: - name: mnt # 있음 hostPath: path: /mnt - \ No newline at end of file + diff --git a/on-premise/logging/fluentbit_v3.1.7/3_apply/test.yaml b/on-premise/logging/fluentbit_v3.1.7/3_apply/test.yaml index 094b73e..7b1eb99 100644 --- a/on-premise/logging/fluentbit_v3.1.7/3_apply/test.yaml +++ b/on-premise/logging/fluentbit_v3.1.7/3_apply/test.yaml @@ -14,8 +14,8 @@ metadata: spec: containers: - name: wget - image: "busybox:latest" + image: "reg.inje-private.com/nnd002/busybox:latest" imagePullPolicy: Always command: ["sh"] args: ["-c", "wget -O- fluent-bit:2020"] - restartPolicy: Never \ No newline at end of file + restartPolicy: Never diff --git a/on-premise/logging/openSearch/ing-opensearch-dashboard.yaml b/on-premise/logging/openSearch/ing-opensearch-dashboard.yaml index 04eebe5..a956011 100644 --- a/on-premise/logging/openSearch/ing-opensearch-dashboard.yaml +++ b/on-premise/logging/openSearch/ing-opensearch-dashboard.yaml @@ -6,7 +6,7 @@ metadata: spec: ingressClassName: nginx rules: - - host: os-dash.nativedeck.com + - host: os-dash.inje-private.com http: paths: - backend: @@ -18,5 +18,5 @@ spec: pathType: Prefix tls: - hosts: - - os-dash.nativedeck.com - secretName: secret-logging-ssl + - os-dash.inje-private.com + secretName: logging-ssl diff --git a/on-premise/logging/openSearch/openSearch-dashboard_2.11.1.yaml b/on-premise/logging/openSearch/openSearch-dashboard_2.11.1.yaml index 70b5741..0740e69 100644 --- a/on-premise/logging/openSearch/openSearch-dashboard_2.11.1.yaml +++ b/on-premise/logging/openSearch/openSearch-dashboard_2.11.1.yaml @@ -88,11 +88,11 @@ spec: runAsNonRoot: true runAsUser: 1000 #image: "opensearchproject/opensearch-dashboards:2.13.0" - image: "opensearchproject/opensearch-dashboards:2.11.1" + image: "reg.inje-private.com/nnd002/opensearchproject/opensearch-dashboards:2.11.1" imagePullPolicy: "IfNotPresent" readinessProbe: failureThreshold: 10 - initialDelaySeconds: 10 + initialDelaySeconds: 30 periodSeconds: 20 successThreshold: 1 tcpSocket: @@ -100,7 +100,7 @@ spec: timeoutSeconds: 5 livenessProbe: failureThreshold: 10 - initialDelaySeconds: 10 + initialDelaySeconds: 30 periodSeconds: 20 successThreshold: 1 tcpSocket: @@ -108,7 +108,7 @@ spec: timeoutSeconds: 5 startupProbe: failureThreshold: 20 - initialDelaySeconds: 10 + initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 tcpSocket: @@ -116,7 +116,7 @@ spec: timeoutSeconds: 5 env: - name: OPENSEARCH_HOSTS - value: "https://10.163.1.66:9200" + value: "https://172.17.128.246:9200" #value: "https://opensearch-cluster-master:9200" - name: SERVER_HOST value: "0.0.0.0" @@ -137,4 +137,12 @@ spec: requests: cpu: 100m memory: 512M - #volumeMounts: + volumeMounts: + - name: tls-secret + mountPath: /etc/opensearch/certs + readOnly: true + volumes: + - name: tls-secret + secret: + secretName: logging-ssl + diff --git a/on-premise/main/harbor_2.9.1/1.init.yaml b/on-premise/main/harbor_2.9.1/1.init.yaml index 6dde4e9..c28b273 100644 --- a/on-premise/main/harbor_2.9.1/1.init.yaml +++ b/on-premise/main/harbor_2.9.1/1.init.yaml @@ -24,7 +24,7 @@ data: CORE_LOCAL_URL: http://127.0.0.1:8080 CORE_URL: http://harbor-core:80 DATABASE_TYPE: postgresql - EXT_ENDPOINT: https://harbor.icurfer.com + EXT_ENDPOINT: https://harbor.inje-private.com HTTP_PROXY: "" HTTPS_PROXY: "" JOBSERVICE_URL: http://harbor-jobservice diff --git a/on-premise/main/harbor_2.9.1/2.cert.yaml b/on-premise/main/harbor_2.9.1/2.cert.yaml index 54c6cf8..9c8e6ae 100644 --- a/on-premise/main/harbor_2.9.1/2.cert.yaml +++ b/on-premise/main/harbor_2.9.1/2.cert.yaml @@ -4,7 +4,7 @@ metadata: name: harbor-cacerts namespace: harbor data: - cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU5RENDQTl5Z0F3SUJBZ0lTQktsUkF1R24rM2N1R2xKS1o5aVY4Vmx4TUEwR0NTcUdTSWIzRFFFQkN3VUEKTURJeEN6QUpCZ05WQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFNWlhRbmN5QkZibU55ZVhCME1Rc3dDUVlEVlFRRApFd0pTTXpBZUZ3MHlOREF6TURJeE5EQTVOVFZhRncweU5EQTFNekV4TkRBNU5UUmFNQmd4RmpBVUJnTlZCQU1NCkRTb3VhV04xY21abGNpNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3oKQWVxVS9KSkJGWWJpeFQwbTRKTXU3QW5CdTVYRUFVSUhHendsR3ZjdjJXRTBxajNwU1JCeUdJWEo0eHdycnl3eAprYjgrRkxTSjh4U3Q2TXpwZjVxNTBQMm9PYklFdkMwY0drNHZuZThGVm1YckNKckNMaUtld0JBRWhFcC9IUjdYClVFSFRLVFpXTE5oUkIzNjMxZFkrcHhHU1AxeWNMblBXYkJQOUVSa2xzeUhoUnJpWHBxTmZDcGVIM3kxb3VJOUwKV3l5Yks3SUdmSkVzN1g0TE1OZ2RycEZtUzlCdTNZQ0JVMExZMlZtWVFJNVFaNkNhbisrQk51bVN6U0M4ZVRUaApJamY0Uk14R2JIUFNDYjBXb3hxM3M4RmZmQVd1a2JOSmhXSTlidXNucWxNTnRrQnREdFYxdVpaQUlLMno0cnFCCmlJbDlaS0lza3FEQUJaMWFSb0JkQWdNQkFBR2pnZ0ljTUlJQ0dEQU9CZ05WSFE4QkFmOEVCQU1DQmFBd0hRWUQKVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUF3R0ExVWRFd0VCL3dRQ01BQXdIUVlEVlIwTwpCQllFRk51b3p0ZmprQ25FRGFxd01zVlBwdU5CaU5YaU1COEdBMVVkSXdRWU1CYUFGQlF1c3hlM1dGYkxybEFKClFPWWZyNTJMRk1MR01GVUdDQ3NHQVFVRkJ3RUJCRWt3UnpBaEJnZ3JCZ0VGQlFjd0FZWVZhSFIwY0RvdkwzSXoKTG04dWJHVnVZM0l1YjNKbk1DSUdDQ3NHQVFVRkJ6QUNoaFpvZEhSd09pOHZjak11YVM1c1pXNWpjaTV2Y21jdgpNQ1VHQTFVZEVRUWVNQnlDRFNvdWFXTjFjbVpsY2k1amIyMkNDMmxqZFhKbVpYSXVZMjl0TUJNR0ExVWRJQVFNCk1Bb3dDQVlHWjRFTUFRSUJNSUlCQkFZS0t3WUJCQUhXZVFJRUFnU0I5UVNCOGdEd0FIVUFPMU4zZFQ0dHVZQk8KaXpCYkJ2NUFPMmZZVDhQMHg3MEFEUzF5YitINjFCY0FBQUdOLzdidTJ3QUFCQU1BUmpCRUFpQkdEcW5xZytIcwpQUmVmYTc5TXdVZjlmUzFOYWh3SEsrRlJrVlg4REE2QUN3SWdPN2NsOU1IcC9hVVFSbkhZNFlRU01lMG5WbHhUCkpBY0RuY2syUkJQMFhBUUFkd0R1emRCazFkc2F6c1ZjdDUyMHpST2lNb2RHZkx6czNzTlJTRmxHY1IrMW13QUEKQVkzL3R1N0tBQUFFQXdCSU1FWUNJUUNTWTlxczV0ZFY2ejR5c01acG9yOXZXcmhsVXlScFNINVJIVGRQZGdlWQpsd0loQUpvblNHeVJOYmVNcEs3SW5uYVJxOVFuajB3R1hhWnVNMnZXTmlUYWFLTzBNQTBHQ1NxR1NJYjNEUUVCCkN3VUFBNElCQVFCMmlWcEttN0IxZ3p0a01Ud2QrQXBNOWh4SzkwYndWSTZxUnZLNmpsZVFJV0JCZG84Z3I0QlEKTlpPNDBWa21OaFhoY3ljQ1ZsSmlhT3JLd1J0c1VhMzVmc29BVTFCQzlodFRPT3R4TXYvb2lDZlA4aEZQNGttagpOTVFzNVZ2eFR6cmRjbWxhRmJaOWJkNVF2dko3L2hadTBnZ1ZrSUZVRXVZcWtQNFFzSHU1dXhOd01rWUY3RGUxCnVsVGY1YlFQcTJ0TEk5cTk1OUNsM2xMTTJqYklkM2h1bkRrMDFLZ2dSOWNkUmEzZnEzM2VZNkY2eWNWSVBPblMKdGhXck9melc5K2IrSFNDWHkyd3BJR0VTUTVJQU95cUdibnBBR1Z6U294UnVrNW1Wd0FqeDBaMW94eUdPRVprTgpEQUhHa21aNThIOUJpcXJ0VzBuaEMyKzN0cCtmR2kydwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlGRmpDQ0F2NmdBd0lCQWdJUkFKRXJDRXJQREJpblUvYldMaVduWDFvd0RRWUpLb1pJaHZjTkFRRUxCUUF3ClR6RUxNQWtHQTFVRUJoTUNWVk14S1RBbkJnTlZCQW9USUVsdWRHVnlibVYwSUZObFkzVnlhWFI1SUZKbGMyVmgKY21Ob0lFZHliM1Z3TVJVd0V3WURWUVFERXd4SlUxSkhJRkp2YjNRZ1dERXdIaGNOTWpBd09UQTBNREF3TURBdwpXaGNOTWpVd09URTFNVFl3TURBd1dqQXlNUXN3Q1FZRFZRUUdFd0pWVXpFV01CUUdBMVVFQ2hNTlRHVjBKM01nClJXNWpjbmx3ZERFTE1Ba0dBMVVFQXhNQ1VqTXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUsKQW9JQkFRQzdBaFVvelBhZ2xOTVBFdXlOVlpMRCtJTHhtYVo2UW9pblhTYXF0U3U1eFV5eHI0NXIrWFhJbzljUApSNVFVVlRWWGpKNm9vamtaOVlJOFFxbE9idlU3d3k3YmpjQ3dYUE5aT09mdHoybndXZ3NidnNDVUpDV0gramR4CnN4UG5IS3pobSsvYjVEdEZVa1dXcWNGVHpqVElVdTYxcnUyUDNtQnc0cVZVcTdadERwZWxRRFJySzlPOFp1dG0KTkh6NmE0dVBWeW1aK0RBWFhicHliL3VCeGEzU2hsZzlGOGZuQ2J2eEsvZUczTUhhY1YzVVJ1UE1yU1hCaUx4ZwpaM1Ztcy9FWTk2SmM1bFAvT29pMlI2WC9FeGpxbUFsM1A1MVQrYzhCNWZXbWNCY1VyMk9rLzVtems1M2NVNmNHCi9raUZIYUZwcmlWMXV4UE1VZ1AxN1ZHaGk5c1ZBZ01CQUFHamdnRUlNSUlCQkRBT0JnTlZIUThCQWY4RUJBTUMKQVlZd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3SUdDQ3NHQVFVRkJ3TUJNQklHQTFVZEV3RUIvd1FJTUFZQgpBZjhDQVFBd0hRWURWUjBPQkJZRUZCUXVzeGUzV0ZiTHJsQUpRT1lmcjUyTEZNTEdNQjhHQTFVZEl3UVlNQmFBCkZIbTBXZVo3dHVYa0FYT0FDSWpJR2xqMjZadHVNRElHQ0NzR0FRVUZCd0VCQkNZd0pEQWlCZ2dyQmdFRkJRY3cKQW9ZV2FIUjBjRG92TDNneExta3ViR1Z1WTNJdWIzSm5MekFuQmdOVkhSOEVJREFlTUJ5Z0dxQVloaFpvZEhSdwpPaTh2ZURFdVl5NXNaVzVqY2k1dmNtY3ZNQ0lHQTFVZElBUWJNQmt3Q0FZR1o0RU1BUUlCTUEwR0N5c0dBUVFCCmd0OFRBUUVCTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElDQVFDRnlrNUhQcVAzaFVTRnZOVm5lTEtZWTYxMVRSNlcKUFRObGNsUXRnYURxdyszNElMOWZ6TGR3QUxkdU8vWmVsTjdrSUorbTc0dXlBK2VpdFJZOGtjNjA3VGtDNTN3bAppa2ZtWlc0L1J2VFo4TTZVSys1VXpoSzhqQ2RMdU1HWUw2S3Z6WEdSU2dpM3lMZ2pld1F0Q1BrSVZ6NkQyUVF6CkNrY2hlQW1DSjhNcXlKdTV6bHp5Wk1qQXZubkFUNDV0UkF4ZWtyc3U5NHNRNGVnZFJDbmJXU0R0WTdraCtCSW0KbEpOWG9CMWxCTUVLSXE0UURVT1hvUmdmZnVEZ2hqZTFXckc5TUwrSGJpc3EveUZPR3dYRDlSaVg4RjZzdzZXNAphdkF1dkRzenVlNUwzc3o4NUsrRUM0WS93RlZETnZabzRUWVhhbzZaMGYrbFFLYzB0OERRWXprMU9YVnU4cnAyCnlKTUM2YWxMYkJmT0RBTFp2WUg3bjdkbzFBWmxzNEk5ZDFQNGpua0RyUW94QjNVcVE5aFZsM0xFS1E3M3hGMU8KeUs1R2hERFg4b1ZmR0tGNXUrZGVjSXNINFlhVHc3bVAzR0Z4SlNxdjMrMGxVRkpvaTVMYzVkYTE0OXA5MElkcwpoQ0V4cm9MMSs3bXJ5SWtYUGVGTTVUZ085cjBydlphQkZPdlYyejBncDM1WjArTDRXUGxidUVqTi9seFBGaW4rCkhsVWpyOGdSc0kzcWZKT1FGeS85cktJSlIwWS84T213dC84b1RXZ3kxbWRlSG1tams3ajFuWXN2QzlKU1E2WnYKTWxkbFRUS0IzemhUaFYxK1hXWXA2cmpkNUpXMXpiVldFa0xOeEU3R0pUaEVVRzNzemdCVkdQN3BTV1RVVHNxWApuTFJid0hPb3E3aEh3Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURuVENDQW9XZ0F3SUJBZ0lVZG82RjNaejRhT2JjazdreDJwbHdHQVJreHBZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1hqRUxNQWtHQTFVRUJoTUNTMUl4RGpBTUJnTlZCQWdNQlZObGIzVnNNUTB3Q3dZRFZRUUhEQVJIUVZOTwpNUXd3Q2dZRFZRUUtEQU5FUlZZeEVEQU9CZ05WQkFzTUIwcEJXUzVEVDFJeEVEQU9CZ05WQkFNTUIxSlBUMVF0ClEwRXdIaGNOTWpReE1ERXdNRFEwTWpJMldoY05Nall4TURFd01EUTBNakkyV2pCZU1Rc3dDUVlEVlFRR0V3SkwKVWpFT01Bd0dBMVVFQ0F3RlUyVnZkV3d4RFRBTEJnTlZCQWNNQkVkQlUwNHhEREFLQmdOVkJBb01BMFJGVmpFUQpNQTRHQTFVRUN3d0hTa0ZaTGtOUFVqRVFNQTRHQTFVRUF3d0hVazlQVkMxRFFUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMYkZPU2dMOEUveDk3VGVBdENqWDllTnlleXZkcS9GSWV0V2l2bk0KSWtaSWhqakZleG4rQXB0azZodFU2U1JabFdvNncvcExJRmJDUlZKbWdNY0s5WVRQenJHQ1FmUjRtOGhvdnN4dQo0aWNLU2tCR0o3YWd0RWI5MU1tSzk3SjFrelNHbm5EVXhQQVRRVnFtWVhZekdiWWhXRGpROURuQ3IwV3Rrb0xECkxwZU4yVERYcW5FcFY3K0dhaEpxWmhnc1VHUkJtcDR4VWttUFpDRWFSZkNrMHg4bVkvVFUyR1NRaTl1Y0dDQm4KN2RQQ1dXeEtNemFQNFkwMm5TSlgvY3FRTmxVS0FDOGlHZ2xwdllaRno3U29hNmxaak8yZXlVbEtXQnc3RGh0eQpiUHFrdjlicEc5aWRCdTU3Y2NuZ1dML0c5SnBFMTBSMEkxUXJJK0h5aUFTRThhOENBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRkprZ3VDTVBFT1c3YzN4NnBVa3Vwb0F2RkovcU1COEdBMVVkSXdRWU1CYUFGSmtndUNNUEVPVzcKYzN4NnBVa3Vwb0F2RkovcU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRUUzd3hoak5xZzhxUFQ1UC9MNTFKSWlaaWxGbk95cTJjOGg5L0dYVHl2Rmp1ZXB5MkFOeUtMaEJwcjlCNXhYCkVqY3JqWCtyT044OWJIRkFRamlnWTJadGVvRGNyNjhVb1d3cExETC8zU1BPTEcvTnN2TnNUTFJTQkxSK01CdE0KQUJVNzUwM0o4WSszZWY3K0N0MElmVzdWTWNnRnpheWNIaXRkZDZON0x5YTJsVW9vUnNFZmNXSjZqWXlUNEVaTgoxVjc4STEwWHE4aW56ZVFVT3JjaEhQY3Y3VHF6ay9wVG9aMWI0K3hLZFJJTExsYUo1SmQ1R1MrWVU2R3FRb2VmClNlcWlRRmlzODJxdzFFS2xCOFVxNGVFejZENXdjNnF5U0pLd25tY2FOMVNxcld4YnlHSk53TGtyWkZmQXdPNWwKc2N6WjVvdE54TTJUOFgyV2Z4MUtPZW89Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- apiVersion: v1 kind: Secret @@ -22,6 +22,6 @@ data: REGISTRY_CREDENTIAL_PASSWORD: aGFyYm9yX3JlZ2lzdHJ5X3Bhc3N3b3Jk secret: RTRQY0FxZ3RPVmdKWTBRRw== secretKey: bm90LWEtc2VjdXJlLWtleQ== - tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU5RENDQTl5Z0F3SUJBZ0lTQktsUkF1R24rM2N1R2xKS1o5aVY4Vmx4TUEwR0NTcUdTSWIzRFFFQkN3VUEKTURJeEN6QUpCZ05WQkFZVEFsVlRNUll3RkFZRFZRUUtFdzFNWlhRbmN5QkZibU55ZVhCME1Rc3dDUVlEVlFRRApFd0pTTXpBZUZ3MHlOREF6TURJeE5EQTVOVFZhRncweU5EQTFNekV4TkRBNU5UUmFNQmd4RmpBVUJnTlZCQU1NCkRTb3VhV04xY21abGNpNWpiMjB3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3oKQWVxVS9KSkJGWWJpeFQwbTRKTXU3QW5CdTVYRUFVSUhHendsR3ZjdjJXRTBxajNwU1JCeUdJWEo0eHdycnl3eAprYjgrRkxTSjh4U3Q2TXpwZjVxNTBQMm9PYklFdkMwY0drNHZuZThGVm1YckNKckNMaUtld0JBRWhFcC9IUjdYClVFSFRLVFpXTE5oUkIzNjMxZFkrcHhHU1AxeWNMblBXYkJQOUVSa2xzeUhoUnJpWHBxTmZDcGVIM3kxb3VJOUwKV3l5Yks3SUdmSkVzN1g0TE1OZ2RycEZtUzlCdTNZQ0JVMExZMlZtWVFJNVFaNkNhbisrQk51bVN6U0M4ZVRUaApJamY0Uk14R2JIUFNDYjBXb3hxM3M4RmZmQVd1a2JOSmhXSTlidXNucWxNTnRrQnREdFYxdVpaQUlLMno0cnFCCmlJbDlaS0lza3FEQUJaMWFSb0JkQWdNQkFBR2pnZ0ljTUlJQ0dEQU9CZ05WSFE4QkFmOEVCQU1DQmFBd0hRWUQKVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUF3R0ExVWRFd0VCL3dRQ01BQXdIUVlEVlIwTwpCQllFRk51b3p0ZmprQ25FRGFxd01zVlBwdU5CaU5YaU1COEdBMVVkSXdRWU1CYUFGQlF1c3hlM1dGYkxybEFKClFPWWZyNTJMRk1MR01GVUdDQ3NHQVFVRkJ3RUJCRWt3UnpBaEJnZ3JCZ0VGQlFjd0FZWVZhSFIwY0RvdkwzSXoKTG04dWJHVnVZM0l1YjNKbk1DSUdDQ3NHQVFVRkJ6QUNoaFpvZEhSd09pOHZjak11YVM1c1pXNWpjaTV2Y21jdgpNQ1VHQTFVZEVRUWVNQnlDRFNvdWFXTjFjbVpsY2k1amIyMkNDMmxqZFhKbVpYSXVZMjl0TUJNR0ExVWRJQVFNCk1Bb3dDQVlHWjRFTUFRSUJNSUlCQkFZS0t3WUJCQUhXZVFJRUFnU0I5UVNCOGdEd0FIVUFPMU4zZFQ0dHVZQk8KaXpCYkJ2NUFPMmZZVDhQMHg3MEFEUzF5YitINjFCY0FBQUdOLzdidTJ3QUFCQU1BUmpCRUFpQkdEcW5xZytIcwpQUmVmYTc5TXdVZjlmUzFOYWh3SEsrRlJrVlg4REE2QUN3SWdPN2NsOU1IcC9hVVFSbkhZNFlRU01lMG5WbHhUCkpBY0RuY2syUkJQMFhBUUFkd0R1emRCazFkc2F6c1ZjdDUyMHpST2lNb2RHZkx6czNzTlJTRmxHY1IrMW13QUEKQVkzL3R1N0tBQUFFQXdCSU1FWUNJUUNTWTlxczV0ZFY2ejR5c01acG9yOXZXcmhsVXlScFNINVJIVGRQZGdlWQpsd0loQUpvblNHeVJOYmVNcEs3SW5uYVJxOVFuajB3R1hhWnVNMnZXTmlUYWFLTzBNQTBHQ1NxR1NJYjNEUUVCCkN3VUFBNElCQVFCMmlWcEttN0IxZ3p0a01Ud2QrQXBNOWh4SzkwYndWSTZxUnZLNmpsZVFJV0JCZG84Z3I0QlEKTlpPNDBWa21OaFhoY3ljQ1ZsSmlhT3JLd1J0c1VhMzVmc29BVTFCQzlodFRPT3R4TXYvb2lDZlA4aEZQNGttagpOTVFzNVZ2eFR6cmRjbWxhRmJaOWJkNVF2dko3L2hadTBnZ1ZrSUZVRXVZcWtQNFFzSHU1dXhOd01rWUY3RGUxCnVsVGY1YlFQcTJ0TEk5cTk1OUNsM2xMTTJqYklkM2h1bkRrMDFLZ2dSOWNkUmEzZnEzM2VZNkY2eWNWSVBPblMKdGhXck9melc5K2IrSFNDWHkyd3BJR0VTUTVJQU95cUdibnBBR1Z6U294UnVrNW1Wd0FqeDBaMW94eUdPRVprTgpEQUhHa21aNThIOUJpcXJ0VzBuaEMyKzN0cCtmR2kydwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t - tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQ3pBZXFVL0pKQkZZYmkKeFQwbTRKTXU3QW5CdTVYRUFVSUhHendsR3ZjdjJXRTBxajNwU1JCeUdJWEo0eHdycnl3eGtiOCtGTFNKOHhTdAo2TXpwZjVxNTBQMm9PYklFdkMwY0drNHZuZThGVm1YckNKckNMaUtld0JBRWhFcC9IUjdYVUVIVEtUWldMTmhSCkIzNjMxZFkrcHhHU1AxeWNMblBXYkJQOUVSa2xzeUhoUnJpWHBxTmZDcGVIM3kxb3VJOUxXeXliSzdJR2ZKRXMKN1g0TE1OZ2RycEZtUzlCdTNZQ0JVMExZMlZtWVFJNVFaNkNhbisrQk51bVN6U0M4ZVRUaElqZjRSTXhHYkhQUwpDYjBXb3hxM3M4RmZmQVd1a2JOSmhXSTlidXNucWxNTnRrQnREdFYxdVpaQUlLMno0cnFCaUlsOVpLSXNrcURBCkJaMWFSb0JkQWdNQkFBRUNnZ0VBQmdGVTNvOG82VHlManN6VVMvQ0JsNGtpY2FpZjhnTDRkVmNTcEl4YjlGNW0KbmxidUVVY0ZkczBVK0pjaElUa0tSK3ZEcytyZ3ZLRUE2d0w4bEMwVzk5QUhvUmxnWnJ3WkI2WG43MmZYdG9EZwphMEJadXIvRCtHU1Q2bEdLMDBBRmw4TzdsWlhVR3I0bk9wNnEvN0ttM09sZ3ZrY3R1RUtacnhJOG9HM1pWTFJOCmJMTUpLMFhMdGRSZDFIUWg4ZHNycDNldndYSUwzS3dnOEpDV2xEb2FPc0tCbUdxQU5LRTY4MDVNbm5uZWk5RlEKZ01lTFRxdmJzUkRJWFdpdDM4WEZLdmRBSUhnVTB3clh1djhXUXplYitjdnd0MFlRUEpyU0lraFFHUG10TlFQUgpHYWh3cGhlNXBVRUZranlxTXQxcHB2QmZTeFhWaU0zM3hlaEdZOTNtd1FLQmdRQzJWbjJPNWlmdUJUQVVqeDVyCkxoRTdGMWpnZGdZTWJRZUFjNDdUZkdXNjA1VGNlRk5TeDdBYk9tUHduR01xUWRiT0M4dEUzZXR3MURsV1hyRjcKL3NlRmxtVmduNWRWdGQxRWNoVUUvVVlxejIweldjSGpSN1lDbktmdDRIZmM3YWVmWGZZOG50TGVDUENtQVpsVgpycTVjSFUvOENLc3RwNmdHbVdFV0I0S25IUUtCZ1FEN1V2ODBxUzd6TDBsTFNWVTEycDMrUTl6NDU3MHgybmhOCmgvS3pnWnJpZ1FXMHRLdnlpRkdndHZ6V1BGMncvOUdDVDgyRHN2R2FMSURsa2o1VUpGalczUUQzWmxERFk5dEcKYU5zTEdwSkt4UDZwaEFwSUlMSjdYUXI2QXNWVm5yZXNSRGxZMU1LQXhFZGMxUHFNUk1sWEdpdzl3amdLQXA4UQpNZ2RYTlR1NlFRS0JnSDZmQzJ4YnlpalJjM1VqZWlWR0JYTTZvRjZudDBXVHhWemZZclRjc3l5TlY5Zk91MVpHCkU3YWswdGc1VWVmN2RyYjVtN3dFUEViTEtkSWZ5akxvV0JnZHUrTGdrTkJWamdYRkQzRzZqS3FZQnlaYzAzY0kKeW8xL3ltSTN1aVV5NkcrVWFiWHBPVmcxYnlCcEJkbHBoKzJ4OFdSOWhKb2N6bU5leWZ2cFZVTEZBb0dCQU1rZwpSNG4rSnN1SXVSQWQ5S292ZFNiSmFtcHJFaloyVHJaRktJNU5Gd1ZUR1p6ZXhZaEhYWVBQVFJHcHA1VUJkTW5qClVXV202OEJsQXhZMWJkbnFhSW95dlJZLzlEd1ppcDZUUlZCaWlGWjd4ZzBrMVJHWjBSdjJmdFZMS0Y3M3NLZVUKeFl2NFlGdXFPQzNyWjBLZnZiME4vZi9Da1JRNXVzKzhLYkc1c1QzQkFvR0JBSms2VmJvK3BtSE5ab0E2cDY5MApCY2lJRFJ3ZUJXQmZ2dmJ3ek8xbiswcE9IdEF1N1ZCS3ZmSGZ1bkhjMGNkdjdTdks0RjN3NW03blJBR3cxOXFnCjFreG5PZWFlazFGMG1aZWZaNGlqajVUSWtxTnlwQldkMEZYdHk5SUwwSEhMemxQU3VDb2pRVUJ3cG5PMTJ5cTYKMC92RFA0U1p3K2hWb3JORnZzMzhDVmZjCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= ---- \ No newline at end of file + tls.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURuVENDQW9XZ0F3SUJBZ0lVZG82RjNaejRhT2JjazdreDJwbHdHQVJreHBZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1hqRUxNQWtHQTFVRUJoTUNTMUl4RGpBTUJnTlZCQWdNQlZObGIzVnNNUTB3Q3dZRFZRUUhEQVJIUVZOTwpNUXd3Q2dZRFZRUUtEQU5FUlZZeEVEQU9CZ05WQkFzTUIwcEJXUzVEVDFJeEVEQU9CZ05WQkFNTUIxSlBUMVF0ClEwRXdIaGNOTWpReE1ERXdNRFEwTWpJMldoY05Nall4TURFd01EUTBNakkyV2pCZU1Rc3dDUVlEVlFRR0V3SkwKVWpFT01Bd0dBMVVFQ0F3RlUyVnZkV3d4RFRBTEJnTlZCQWNNQkVkQlUwNHhEREFLQmdOVkJBb01BMFJGVmpFUQpNQTRHQTFVRUN3d0hTa0ZaTGtOUFVqRVFNQTRHQTFVRUF3d0hVazlQVkMxRFFUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMYkZPU2dMOEUveDk3VGVBdENqWDllTnlleXZkcS9GSWV0V2l2bk0KSWtaSWhqakZleG4rQXB0azZodFU2U1JabFdvNncvcExJRmJDUlZKbWdNY0s5WVRQenJHQ1FmUjRtOGhvdnN4dQo0aWNLU2tCR0o3YWd0RWI5MU1tSzk3SjFrelNHbm5EVXhQQVRRVnFtWVhZekdiWWhXRGpROURuQ3IwV3Rrb0xECkxwZU4yVERYcW5FcFY3K0dhaEpxWmhnc1VHUkJtcDR4VWttUFpDRWFSZkNrMHg4bVkvVFUyR1NRaTl1Y0dDQm4KN2RQQ1dXeEtNemFQNFkwMm5TSlgvY3FRTmxVS0FDOGlHZ2xwdllaRno3U29hNmxaak8yZXlVbEtXQnc3RGh0eQpiUHFrdjlicEc5aWRCdTU3Y2NuZ1dML0c5SnBFMTBSMEkxUXJJK0h5aUFTRThhOENBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRkprZ3VDTVBFT1c3YzN4NnBVa3Vwb0F2RkovcU1COEdBMVVkSXdRWU1CYUFGSmtndUNNUEVPVzcKYzN4NnBVa3Vwb0F2RkovcU1BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRUUzd3hoak5xZzhxUFQ1UC9MNTFKSWlaaWxGbk95cTJjOGg5L0dYVHl2Rmp1ZXB5MkFOeUtMaEJwcjlCNXhYCkVqY3JqWCtyT044OWJIRkFRamlnWTJadGVvRGNyNjhVb1d3cExETC8zU1BPTEcvTnN2TnNUTFJTQkxSK01CdE0KQUJVNzUwM0o4WSszZWY3K0N0MElmVzdWTWNnRnpheWNIaXRkZDZON0x5YTJsVW9vUnNFZmNXSjZqWXlUNEVaTgoxVjc4STEwWHE4aW56ZVFVT3JjaEhQY3Y3VHF6ay9wVG9aMWI0K3hLZFJJTExsYUo1SmQ1R1MrWVU2R3FRb2VmClNlcWlRRmlzODJxdzFFS2xCOFVxNGVFejZENXdjNnF5U0pLd25tY2FOMVNxcld4YnlHSk53TGtyWkZmQXdPNWwKc2N6WjVvdE54TTJUOFgyV2Z4MUtPZW89Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBNENCZnhHTW8xb3pNWld0cXVKNmJUdndPNHhSRy9MTWFVcEF3WUlRNElJUXZtazloCmJkL24vMW85TmpWdDB2QzRqUmU0TFkxbzNUcWk0YWdCbWFWOW1CWTBjZmlRakluSTdybFFJOVpDN25zNXIyZ0gKdngrRGhzVExPQ0I1Mit1b05UdkdJdDYrRzUzbm53c3YxNmx6Qy9GU2M0ZEwzaURacjlQazJOWk55NUhFRC8yawpVQU43ejZ3bmNDRE4vNlVQdlR3aFdncmNtQmpTMjZhQjBMVzU2bk1FZzhTSHErREd2OVlhYXlySDgrYkV0RlVBCllJU2JPcCs3RTRIZVI5c011dmw3VVg5WW1RbG9DN0oxQnljaExuTGdXWlhBU0p0ODd0eW45RkpiaTI1bGVjeVIKTU9oYmxvQSt0SjgyZWlORTRuZXBxOTdXWTZpY3Jqei9aZTd5OVFJREFRQUJBb0lCQUFPNjdqVWJ6R0p6d2ZRZgpLMDNLei8xcXl3bWkvUUo0TGFRNW82QjdtdDZKckt3bURaSlJVM0JuelZTQlk2UkszdHQwVFZ1dXVwUFNCY041Ck14dWVTajZWZ2daeWsxOVBiTUZ5WXAvU0VWZWNRK3ZFTUxyUTJMVE53aThiTlVRQWdsSnVmZi8zRXBWdGxaMEwKUjk3UVFtcXN0OGxWODJDTlRlb3ovZDlSQThielRHV2o5c3FlOS9wY28rb09FV0xPWXNMeE9lWXBFSjdXejhIWQoxalhtRnpid1Jlcnp3Q3RuMVFLeDRKYU4wVWpSTkY3dEpKV2c1VEo0YTVLSkdNaHhZdE5NQ3UvaVBObjNIMnpDCnBJK2x0SmNMMkIwcXBRdzZCMHZ2d1ZHblNNS05weWlHK0dRQk5XRFZLYVR4TXZZT1g0YXpWWmkzS29nU0lETkcKaVZpaTZYa0NnWUVBNzYwN3pFQmIzSmJMakVlNGR2cUErdkJKMGpQNDNBQlNSWElSM3AyaW45VjRJMlpEbHN6NAowem9aelVpS3NYSVAvRlI0bGJHQXJMYzFwMDdSYmpJWUdRaXFzU2N6UCtqMGhDYVJpOWZoaXRVOUJBSk1lT24rCnRZbmxmZ3VZU2ZRa0t4Qk03ck90WnJNdkV2OW5aUXNDYmFGOTV4cDFNKzV2aFoxRHg5OXZ2VDBDZ1lFQTcyUUYKb1QwUko4eVlCTWs5bEYyQUwzcSsxRjQ3SUZ2VFVpd0NIS2tkL1NYd3BSaW5IQ0xwQnZBRjBFcGU0UVcrVkdiSQpEY3UyV0dVY1E0cFRpZk9TcUc2Um4rQ3RjUzViVTRYUytUR09aLzZobkFmSGYyQTh4OTg3aE9DTCtHWVU5Y2RLClFuR1czcFRxMkxkdEFDTnEzcUV0VXhMSjNOZkNyYlZ4ZVBkaTJCa0NnWUVBbTJGTVRncy9Rby9FSUFwekRUY3oKblB0Z2NGVGZOZ2xEVE9BNXMzK3dhVHhrS1ZibjVJQzNvNENjTDVpaXlZenZ6aDhaR2JxOGQ3eENuVmVjc0hycgpZbmRhNllSSFZseDVBSjljWmpPcmRXenVwSVcwL0FKKzdVUWJzbzVqeVRYc3FMcGxsYTZJY1BjalFvYXZpak1MCi9QVGdBWTRHZzRkRlozTGYrVmppUU9VQ2dZRUFnNlJHTUVlTGtvNUFub2tua3RuajdyZ2FEbUNQTlJrcDJRc1kKVWpoeHBFN2p5WFlJRjBIZlVSQldzaGJqbSt4em9LZ3dwTjE4TlpuTWRCdXlHcTlWMjhlSnp4aFhhR0RzbWI2QwpxTVFtb210MDVYK2xwaGIrOVk1OWhYR1JweFJEdkhCT0ZzR3VERkpwM3FqbmlPYnhFdUloTVlpb2R3Z3pKeUVhCitFRmFHcWtDZ1lCSnhuWU1CNzlTa1M1Z1NvTnJnNjJRV3JBcElvZ2dTTkFCNnA3Q1NJbTFldXcvYlBvYVB1aEcKL0V4c0ZGenZ2ayt2TWFycVU0VFNJYkRHcjRkRXZHRm8yM3NQYVNvcVFVZDVRbmg3RGd6RVh5RjhmUGxBV2RxTQpuTTU0aUFnZ2Fyc1paSk9CSnpvQzQveDdwVEJta3RDYkNPVnNVakpDdWZCa0luOXU0UWJjMmc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ== +--- diff --git a/on-premise/main/harbor_2.9.1/3.harbor.yaml b/on-premise/main/harbor_2.9.1/3.harbor.yaml index 43b09ec..2777627 100644 --- a/on-premise/main/harbor_2.9.1/3.harbor.yaml +++ b/on-premise/main/harbor_2.9.1/3.harbor.yaml @@ -132,6 +132,7 @@ metadata: spec: accessModes: - ReadWriteMany + storageClassName: sc-monitoring resources: requests: storage: 10Gi @@ -146,6 +147,7 @@ metadata: name: harbor-registry namespace: harbor spec: + storageClassName: sc-monitoring accessModes: - ReadWriteMany resources: @@ -194,7 +196,7 @@ spec: name: harbor-core - secretRef: name: harbor-core - image: goharbor/harbor-core:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-core:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 2 @@ -300,7 +302,7 @@ spec: name: harbor-jobservice-env - secretRef: name: harbor-jobservice - image: goharbor/harbor-jobservice:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-jobservice:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -364,7 +366,7 @@ spec: spec: automountServiceAccountToken: false containers: - - image: goharbor/harbor-portal:v2.9.1 + - image: reg.inje-private.com/nnd002/goharbor/harbor-portal:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -430,7 +432,7 @@ spec: envFrom: - secretRef: name: harbor-registry - image: goharbor/registry-photon:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/registry-photon:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -478,7 +480,7 @@ spec: name: harbor-registry - secretRef: name: harbor-registryctl - image: goharbor/harbor-registryctl:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-registryctl:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: @@ -558,7 +560,7 @@ spec: envFrom: - secretRef: name: harbor-database - image: goharbor/harbor-db:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-db:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: exec: @@ -588,7 +590,7 @@ spec: /var/lib/postgresql/data/pgdata/ || true' command: - /bin/sh - image: goharbor/harbor-db:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-db:v2.9.1 imagePullPolicy: IfNotPresent name: data-migrator volumeMounts: @@ -599,7 +601,7 @@ spec: - chmod -R 700 /var/lib/postgresql/data/pgdata || true command: - /bin/sh - image: goharbor/harbor-db:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/harbor-db:v2.9.1 imagePullPolicy: IfNotPresent name: data-permissions-ensurer volumeMounts: @@ -654,7 +656,7 @@ spec: spec: automountServiceAccountToken: false containers: - - image: goharbor/redis-photon:v2.9.1 + - image: reg.inje-private.com/nnd002/goharbor/redis-photon:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: initialDelaySeconds: 300 @@ -767,7 +769,7 @@ spec: secretKeyRef: key: redisURL name: harbor-trivy - image: goharbor/trivy-adapter-photon:v2.9.1 + image: reg.inje-private.com/nnd002/goharbor/trivy-adapter-photon:v2.9.1 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 10 diff --git a/on-premise/main/harbor_2.9.1/4.ing-harbor.yaml b/on-premise/main/harbor_2.9.1/4.ing-harbor.yaml index 324aaca..ef75867 100644 --- a/on-premise/main/harbor_2.9.1/4.ing-harbor.yaml +++ b/on-premise/main/harbor_2.9.1/4.ing-harbor.yaml @@ -4,7 +4,7 @@ metadata: annotations: ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-body-size: "0" - #nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + #nginx.ingress.kubernetes.io/force-ssl-redirect: "true" labels: app: harbor release: harbor @@ -12,12 +12,12 @@ metadata: namespace: harbor spec: ingressClassName: nginx - #tls: - #- hosts: - # - "harbor.icurfer.com" - # secretName: secret-harbor-ssl + tls: + - hosts: + - "harbor.icurfer.com" + secretName: harbor-ssl rules: - - host: harbor.icurfer.com + - host: harbor.inje-private.com http: paths: - backend: diff --git a/on-premise/main/rancher_v2.9.1/rancher/.helmignore b/on-premise/main/rancher_v2.9.1/rancher/.helmignore new file mode 100644 index 0000000..2b29f27 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/.helmignore @@ -0,0 +1 @@ +tests diff --git a/on-premise/main/rancher_v2.9.1/rancher/Chart.yaml b/on-premise/main/rancher_v2.9.1/rancher/Chart.yaml new file mode 100644 index 0000000..da234dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +appVersion: v2.9.1 +description: Install Rancher Server to manage Kubernetes clusters across providers. +home: https://rancher.com +icon: https://github.com/rancher/ui/blob/master/public/assets/images/logos/welcome-cow.svg +keywords: +- rancher +kubeVersion: < 1.32.0-0 +maintainers: +- email: charts@rancher.com + name: Rancher Labs +name: rancher +sources: +- https://github.com/rancher/rancher +- https://github.com/rancher/server-chart +version: 2.9.1 diff --git a/on-premise/main/rancher_v2.9.1/rancher/README.md b/on-premise/main/rancher_v2.9.1/rancher/README.md new file mode 100644 index 0000000..b0394b9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/README.md @@ -0,0 +1,208 @@ +By installing this application, you accept the [End User License Agreement & Terms & Conditions](https://www.suse.com/licensing/eula/). + +# Rancher + +***Rancher*** is open source software that combines everything an organization needs to adopt and run containers in production. Built on Kubernetes, Rancher makes it easy for DevOps teams to test, deploy and manage their applications. + +### Introduction + +This chart bootstraps a [Rancher Server](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster) on a Kubernetes cluster using the [Helm](https://helm.sh/) package manager. For a Rancher Supported Deployment please follow our [HA install instructions](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs). + + +### Prerequisites Details + +*For installations covered under [Rancher Support SLA](https://www.suse.com/suse-rancher/support-matrix/all-supported-versions) the target cluster must be **[RKE1](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke1-for-rancher)**, **[RKE2](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke2-for-rancher)**, **[K3s](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/k3s-for-rancher)**, **[AKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-aks)**, **[EKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-amazon-eks)**, or **[GKE](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-gke)**.* + +Make sure the node(s) for the Rancher server fulfill the following requirements: + +[Operating Systems and Container Runtime Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#operating-systems-and-container-runtime-requirements) +[Hardware Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#hardware-requirements) + +- [CPU and Memory](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#cpu-and-memory) +- [Ingress](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#ingress) +- [Disks](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#disks) + +[Networking Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#networking-requirements) +- [Node IP Addresses](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#node-ip-addresses) +- [Port Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#port-requirements) + +[Install the Required CLI Tools](https://ranchermanager.docs.rancher.com/pages-for-subheaders/cli-with-rancher) + +- [kubectl](https://ranchermanager.docs.rancher.com/reference-guides/cli-with-rancher/kubectl-utility) - Kubernetes command-line tool. +- [helm](https://docs.helm.sh/using_helm/#installing-helm) - Package management for Kubernetes. Refer to the [Helm version requirements](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/resources/helm-version-requirements) to choose a version of Helm to install Rancher. + +For a list of best practices that we recommend for running the Rancher server in production, refer to the [best practices section](https://ranchermanager.docs.rancher.com/pages-for-subheaders/best-practices). + +## Installing Rancher + +For production environments, we recommend installing Rancher in a [high-availability Kubernetes installation](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs) so that your user base can always access Rancher Server. When installed in a Kubernetes cluster, Rancher will integrate with the cluster’s etcd database and take advantage of Kubernetes scheduling for high-availability. + +Optional: Installing Rancher on a [Single-node](https://ranchermanager.docs.rancher.com/pages-for-subheaders/rancher-on-a-single-node-with-docker) Kubernetes Cluster + +#### Add the Helm Chart Repository + +Use [helm repo add](https://helm.sh/docs/helm/helm_repo_add/) command to add the Helm chart repository that contains charts to install Rancher. For more information about the repository choices and which is best for your use case, see Choosing a Version of Rancher. + +```bash +helm repo add rancher-latest https://releases.rancher.com/server-charts/latest +``` + +#### Create a Namespace for Rancher + +We’ll need to define a Kubernetes namespace where the resources created by the Chart should be installed. This should always be cattle-system: + +```bash +kubectl create namespace cattle-system +``` + +#### Choose your SSL Configuration + +The Rancher management server is designed to be secure by default and requires SSL/TLS configuration. + +There are three recommended options for the source of the certificate used for TLS termination at the Rancher server: + +- [Rancher-generated TLS certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Bring your own certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) + +#### Install cert-manager + +This step is only required to use certificates issued by Rancher’s generated CA **`(ingress.tls.source=rancher)`** or to request Let’s Encrypt issued certificates **`(ingress.tls.source=letsEncrypt)`**. + +[These instructions are adapted from the official cert-manager documentation.](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#4-install-cert-manager) + +#### Install Rancher with Helm and Your Chosen Certificate Option + +- [Rancher to generated certificates](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org +``` + +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=letsEncrypt \ + --set letsEncrypt.email=me@example.org +``` + +- [Certificates from Files](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret +``` + +*If you are using a Private CA signed certificate , add **--set privateCA=true** to the command:`* + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret \ + --set privateCA=true +``` + +#### Verify that the Rancher Server is Successfully Deployed + +After adding the secrets, check if Rancher was rolled out successfully: + +```bash +kubectl -n cattle-system rollout status deploy/rancher +Waiting for deployment "rancher" rollout to finish: 0 of 3 updated replicas are available... +deployment "rancher" successfully rolled out +``` + +If you see the following **`error: error: deployment "rancher" exceeded its progress deadline`**, you can check the status of the deployment by running the following command: + +```bash +kubectl -n cattle-system get deploy rancher +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +rancher 3 3 3 3 3m +``` + +It should show the same count for **`DESIRED`** and **`AVAILABLE`**. + +#### Save Your Options + +Make sure you save the **`--set`** options you used. You will need to use the same options when you upgrade Rancher to new versions with Helm. + +#### Finishing Up + +That’s it. You should have a functional Rancher server. + +In a web browser, go to the DNS name that forwards traffic to your load balancer. Then you should be greeted by the colorful login page. + +Doesn’t work? Take a look at the [Troubleshooting Page](https://ranchermanager.docs.rancher.com/troubleshooting/general-troubleshooting) + +***All of these instructions are defined in detailed in the [Rancher Documentation](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#install-the-rancher-helm-chart).*** + +### Helm Chart Options for Kubernetes Installations + +The full [Helm Chart Options](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options) can be found here. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +#### Common Options + +| Parameter | Default Value | Description | +| ------------------------- | ------------- | -------------------------------------------------------------------------------------------- | +| `hostname` | " " | ***string*** - the Fully Qualified Domain Name for your Rancher Server | +| `ingress.tls.source` | "rancher" | ***string*** - Where to get the cert for the ingress. - "***rancher, letsEncrypt, secret***" | +| `letsEncrypt.email` | " " | ***string*** - Your email address | +| `letsEncrypt.environment` | "production" | ***string*** - Valid options: "***staging, production***" | +| `privateCA` | false | ***bool*** - Set to true if your cert is signed by a private CA | + +#### Advanced Options + +| Parameter | Default Value | Description | +| ---------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `additionalTrustedCAs` | false | ***bool*** - [See Additional Trusted CAs Server](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options#additional-trusted-cas) | +| `addLocal` | "true" | ***string*** - As of Rancher v2.5.0 this flag is deprecated and must be set to "true" | +| `antiAffinity` | "preferred" | ***string*** - AntiAffinity rule for Rancher pods - *"preferred, required"* | +| `replicas` | 3 | ***int*** - Number of replicas of Rancher pods | +| `auditLog.destination` | "sidecar" | ***string*** - Stream to sidecar container console or hostPath volume - *"sidecar, hostPath"* | +| `auditLog.hostPath` | "/var/log/rancher/audit" | ***string*** - log file destination on host (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.level` | 0 | ***int*** - set the [API Audit Log level](https://ranchermanager.docs.rancher.com/how-to-guides/advanced-user-guides/enable-api-audit-log#audit-log-levels). 0 is off. [0-3] | +| `auditLog.maxAge` | 1 | ***int*** - maximum number of days to retain old audit log files (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxBackup` | 1 | int - maximum number of audit log files to retain (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxSize` | 100 | ***int*** - maximum size in megabytes of the audit log file before it gets rotated (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.image.repository` | "rancher/mirrored-bci-micro" | ***string*** - Location for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.tag` | "15.4.14.3" | ***string*** - Tag for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.pullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for auditLog images - *"Always", "Never", "IfNotPresent"* *Note: Available as of v2.7.0* | +| `busyboxImage` | "" | ***string*** - *Deprecated `auditlog.image.repository` should be used to control auditing sidecar image.* Image location for busybox image used to collect audit logs *Note: Available as of v2.2.0, and Deprecated as of v2.7.0* | +| `busyboxImagePullPolicy` | "IfNotPresent" | ***string*** - - *Deprecated `auditlog.image.pullPolicy` should be used to control auditing sidecar image.* Override imagePullPolicy for busybox images - *"Always", "Never", "IfNotPresent"* *Deprecated as of v2.7.0* | +| `debug` | false | ***bool*** - set debug flag on rancher server | +| `certmanager.version` | " " | ***string*** - set cert-manager compatibility | +| `extraEnv` | [] | ***list*** - set additional environment variables for Rancher Note: *Available as of v2.2.0* | +| `imagePullSecrets` | [] | ***list*** - list of names of Secret resource containing private registry credentials | +| `ingress.enabled` | true | ***bool*** - install ingress resource | +| `ingress.ingressClassName` | " " | ***string*** - class name of ingress if not set manually or by the ingress controller's defaults | +| `ingress.includeDefaultExtraAnnotations` | true | ***bool*** - Add default nginx annotations | +| `ingress.extraAnnotations` | {} | ***map*** - additional annotations to customize the ingress | +| `ingress.configurationSnippet` | " " | ***string*** - Add additional Nginx configuration. Can be used for proxy configuration. Note: *Available as of v2.0.15, v2.1.10 and v2.2.4* | +| `service.annotations` | {} | ***map*** - annotations to customize the service | +| `service.type` | " " | ***string*** - Override the type used for the service - *"NodePort", "LoadBalancer", "ClusterIP"* | +| `letsEncrypt.ingress.class` | " " | ***string*** - optional ingress class for the cert-manager acmesolver ingress that responds to the Let’s *Encrypt ACME challenges* | +| `proxy` | " " | ***string** - HTTP[S] proxy server for Rancher | +| `noProxy` | "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local" | ***string*** - comma separated list of hostnames or ip address not to use the proxy | +| `resources` | {} | ***map*** - rancher pod resource requests & limits | +| `rancherImage` | "rancher/rancher" | ***string*** - rancher image source | +| `rancherImageTag` | same as chart version | ***string*** - rancher/rancher image tag | +| `rancherImagePullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for rancher server images - *"Always", "Never", "IfNotPresent"* | +| `tls` | "ingress" | ***string*** - See External TLS Termination for details. - *"ingress, external"* | +| `systemDefaultRegistry` | "" | ***string*** - private registry to be used for all system Docker images, e.g., [http://registry.example.com/] *Available as of v2.3.0* | +| `useBundledSystemChart` | false | ***bool*** - select to use the system-charts packaged with Rancher server. This option is used for air gapped installations. *Available as of v2.3.0* | +| `customLogos.enabled` | false | ***bool*** - Enabled [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) and [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence volume | +| `customLogos.volumeSubpaths.emberUi` | "ember" | ***string*** - Volume subpath for [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) persistence | +| `customLogos.volumeSubpaths.vueUi` | "vue" | ***string*** - Volume subpath for [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence | +| `customLogos.volumeName` | "" | ***string*** - Use an existing volume. Custom logos should be copied to the proper `volume/subpath` folder by the user. Optional for persistentVolumeClaim, required for configMap | +| `customLogos.storageClass` | "" | ***string*** - Set custom logos persistentVolumeClaim storage class. Required for dynamic pv | +| `customLogos.accessMode` | "ReadWriteOnce" | ***string*** - Set custom persistentVolumeClaim access mode | +| `customLogos.size` | "1Gi" | ***string*** - Set custom persistentVolumeClaim size | diff --git a/on-premise/main/rancher_v2.9.1/rancher/cattle-system.json b/on-premise/main/rancher_v2.9.1/rancher/cattle-system.json new file mode 100644 index 0000000..dd9a48e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/cattle-system.json @@ -0,0 +1,64 @@ +{ + "apiVersion": "v1", + "kind": "Namespace", + "metadata": { + "annotations": { + "cattle.io/status": "{\"Conditions\":[{\"Type\":\"ResourceQuotaInit\",\"Status\":\"True\",\"Message\":\"\",\"LastUpdateTime\":\"2024-10-14T01:51:04Z\"},{\"Type\":\"InitialRolesPopulated\",\"Status\":\"True\",\"Message\":\"\",\"LastUpdateTime\":\"2024-10-14T01:51:09Z\"}]}", + "field.cattle.io/projectId": "local:p-2mvh7", + "lifecycle.cattle.io/create.namespace-auth": "true", + "management.cattle.io/no-default-sa-token": "true" + }, + "creationTimestamp": "2024-10-14T01:46:51Z", + "deletionTimestamp": "2024-10-14T01:54:44Z", + "finalizers": [ + ], + "labels": { + "field.cattle.io/projectId": "p-2mvh7", + "kubernetes.io/metadata.name": "cattle-system" + }, + "name": "cattle-system", + "resourceVersion": "4398991", + "uid": "bc99e08c-67a1-40ed-8106-9cc109e2f6a1" + }, + "spec": {}, + "status": { + "conditions": [ + { + "lastTransitionTime": "2024-10-14T01:54:50Z", + "message": "All resources successfully discovered", + "reason": "ResourcesDiscovered", + "status": "False", + "type": "NamespaceDeletionDiscoveryFailure" + }, + { + "lastTransitionTime": "2024-10-14T01:54:50Z", + "message": "All legacy kube types successfully parsed", + "reason": "ParsedGroupVersions", + "status": "False", + "type": "NamespaceDeletionGroupVersionParsingFailure" + }, + { + "lastTransitionTime": "2024-10-14T01:54:50Z", + "message": "All content successfully deleted, may be waiting on finalization", + "reason": "ContentDeleted", + "status": "False", + "type": "NamespaceDeletionContentFailure" + }, + { + "lastTransitionTime": "2024-10-14T01:54:50Z", + "message": "All content successfully removed", + "reason": "ContentRemoved", + "status": "False", + "type": "NamespaceContentRemaining" + }, + { + "lastTransitionTime": "2024-10-14T01:54:50Z", + "message": "All content-preserving finalizers finished", + "reason": "ContentHasNoFinalizers", + "status": "False", + "type": "NamespaceFinalizersRemaining" + } + ], + "phase": "Terminating" + } +} diff --git a/on-premise/main/rancher_v2.9.1/rancher/ing.yaml b/on-premise/main/rancher_v2.9.1/rancher/ing.yaml new file mode 100644 index 0000000..b5a9027 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/ing.yaml @@ -0,0 +1,31 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ing-rancher + namespace: cattle-system + labels: + app: release-name-rancher + release: release-name + annotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +spec: + ingressClassName: nginx + rules: + - host: rancher.inje-private.com # hostname to access rancher server + http: + paths: + - backend: + service: + name: rancher + port: + number: 80 + pathType: ImplementationSpecific + path: / + tls: + - hosts: + - rancher.inje-private.com + secretName: cattle-ssl + + diff --git a/on-premise/main/rancher_v2.9.1/rancher/rancher-2.9.1.tgz b/on-premise/main/rancher_v2.9.1/rancher/rancher-2.9.1.tgz new file mode 100644 index 0000000..a0aab75 Binary files /dev/null and b/on-premise/main/rancher_v2.9.1/rancher/rancher-2.9.1.tgz differ diff --git a/on-premise/main/rancher_v2.9.1/rancher/scripts/post-delete-hook.sh b/on-premise/main/rancher_v2.9.1/rancher/scripts/post-delete-hook.sh new file mode 100644 index 0000000..ad8d7a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/scripts/post-delete-hook.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -e + +namespaces="${NAMESPACES}" +rancher_namespace="${RANCHER_NAMESPACE}" +timeout="${TIMEOUT}" +ignoreTimeoutError="${IGNORETIMEOUTERROR}" + +if [[ -z ${namespaces} ]]; then + echo "No namespace is provided." + exit 1 +fi + +if [[ -z ${rancher_namespace} ]]; then + echo "No rancher namespace is provided." + exit 1 +fi + +if [[ -z ${timeout} ]]; then + echo "No timeout value is provided." + exit 1 +fi + +if [[ -z ${ignoreTimeoutError} ]]; then + echo "No ignoreTimeoutError value is provided." + exit 1 +fi + +succeeded=() +failed=() + +get_pod_count() { + kubectl get pods --selector app="${1}" -n "${2}" -o json | jq '.items | length' +} + +echo "Uninstalling Rancher resources in the following namespaces: ${namespaces}" + +for namespace in ${namespaces}; do + for app in $(helm list -n "${namespace}" -q); do + if [[ ${app} =~ .crd$ ]]; then + echo "--- Skip the app [${app}] in the namespace [${namespace}]" + continue + fi + echo "--- Deleting the app [${app}] in the namespace [${namespace}]" + if [[ ! $(helm uninstall "${app}" -n "${namespace}") ]]; then + failed=("${failed[@]}" "${app}") + continue + fi + + t=0 + while true; do + if [[ $(get_pod_count "${app}" "${namespace}") -eq 0 ]]; then + echo "successfully uninstalled [${app}] in the namespace [${namespace}]" + succeeded=("${succeeded[@]}" "${app}") + break + fi + if [[ ${t} -ge ${timeout} ]]; then + echo "timeout uninstalling [${app}] in the namespace [${namespace}]" + failed=("${failed[@]}" "${app}") + break + fi + # by default, wait 120 seconds in total for an app to be uninstalled + echo "waiting 5 seconds for pods of [${app}] to be terminated ..." + sleep 5 + t=$((t + 5)) + done + done + + # delete the helm operator pods + for pod in $(kubectl get pods -n "${namespace}" -o name); do + if [[ ${pod} =~ ^pod\/helm-operation-* ]]; then + echo "--- Deleting the pod [${pod}] in the namespace [${namespace}]" + kubectl delete "${pod}" -n "${namespace}" + fi + done +done + +echo "Removing Rancher bootstrap secret in the following namespace: ${rancher_namespace}" +kubectl --ignore-not-found=true delete secret bootstrap-secret -n "${rancher_namespace}" + +echo "------ Summary ------" +if [[ ${#succeeded[@]} -ne 0 ]]; then + echo "Succeeded to uninstall the following apps:" "${succeeded[@]}" +fi + +if [[ ${#failed[@]} -ne 0 ]]; then + echo "Failed to uninstall the following apps:" "${failed[@]}" + if [[ "${ignoreTimeoutError}" == "false" ]]; then + exit 2 + fi +else + echo "Cleanup finished successfully." +fi diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/NOTES.txt b/on-premise/main/rancher_v2.9.1/rancher/templates/NOTES.txt new file mode 100644 index 0000000..5d9d1e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/NOTES.txt @@ -0,0 +1,22 @@ +Rancher Server has been installed. + +NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued, Containers are started and the Ingress rule comes up. + +Check out our docs at https://rancher.com/docs/ + +If you provided your own bootstrap password during installation, browse to https://{{ .Values.hostname }} to get started. + +If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates: + +``` +echo https://{{ .Values.hostname }}/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}') +``` + +To get just the bootstrap password on its own, run: + +``` +kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}{{ "{{" }} "\n" {{ "}}" }}' +``` + + +Happy Containering! diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/_helpers.tpl b/on-premise/main/rancher_v2.9.1/rancher/templates/_helpers.tpl new file mode 100644 index 0000000..1b5ad55 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/_helpers.tpl @@ -0,0 +1,76 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "rancher.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.fullname" -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified chart name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.chartname" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +# Render Values in configurationSnippet +{{- define "configurationSnippet" -}} + {{- tpl (.Values.ingress.configurationSnippet) . | nindent 6 -}} +{{- end -}} + +{{/* +Generate the labels. +*/}} +{{- define "rancher.labels" -}} +app: {{ template "rancher.fullname" . }} +chart: {{ template "rancher.chartname" . }} +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector-terms" -}} +{{- $key := "kubernetes.io/os" -}} +- matchExpressions: + - key: {{ $key }} + operator: NotIn + values: + - windows +{{- end -}} + +{{- define "system_default_registry" -}} +{{- if .Values.systemDefaultRegistry -}} + {{- if hasSuffix "/" .Values.systemDefaultRegistry -}} + {{- printf "%s" .Values.systemDefaultRegistry -}} + {{- else -}} + {{- printf "%s/" .Values.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/clusterRoleBinding.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/clusterRoleBinding.yaml new file mode 100644 index 0000000..aeb155d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/clusterRoleBinding.yaml @@ -0,0 +1,14 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +subjects: +- kind: ServiceAccount + name: {{ template "rancher.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/configMap.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/configMap.yaml new file mode 100644 index 0000000..76e3460 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/configMap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rancher-config + labels: {{ include "rancher.labels" . | nindent 4 }} + app.kubernetes.io/part-of: "rancher" +data: + priorityClassName: {{ .Values.priorityClassName }} + {{- if and .Values.webhook (kindIs "string" .Values.webhook) }} + rancher-webhook: {{ .Values.webhook | quote }} + {{- else if .Values.webhook }} + rancher-webhook: {{ toYaml .Values.webhook | quote }} + {{- end }} + {{- if and .Values.fleet (kindIs "string" .Values.fleet) }} + fleet: {{ .Values.fleet | quote }} + {{- else if .Values.fleet }} + fleet: {{ toYaml .Values.fleet | quote }} + {{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/deployment.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/deployment.yaml new file mode 100644 index 0000000..06f9401 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/deployment.yaml @@ -0,0 +1,264 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ template "rancher.fullname" . }} + annotations: +{{- if (lt (int .Values.replicas) 0) }} + management.cattle.io/scale-available: "{{ sub 0 (int .Values.replicas)}}" +{{- end }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: +{{- if (gt (int .Values.replicas) 0) }} + replicas: {{ .Values.replicas }} +{{- end }} + selector: + matchLabels: + app: {{ template "rancher.fullname" . }} + strategy: + rollingUpdate: + maxSurge: 1 +{{- if (eq (int .Values.replicas) 1) }} + maxUnavailable: 0 +{{- else }} + maxUnavailable: 1 +{{- end }} + type: RollingUpdate + template: + metadata: + labels: + app: {{ template "rancher.fullname" . }} + release: {{ .Release.Name }} + spec: + priorityClassName: {{ .Values.priorityClassName }} + serviceAccountName: {{ template "rancher.fullname" . }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 6 }} +{{- end }} + affinity: + podAntiAffinity: +{{- if eq .Values.antiAffinity "required" }} + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- else }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- end }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: {{ include "linux-node-selector-terms" . | nindent 14 }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + containers: + - image: {{ .Values.rancherImage }}:{{ default .Chart.AppVersion .Values.rancherImageTag }} + imagePullPolicy: {{ default "IfNotPresent" .Values.rancherImagePullPolicy }} + name: {{ template "rancher.name" . }} + ports: + - containerPort: 80 + protocol: TCP +{{- if (and .Values.hostPort (gt (int .Values.hostPort) 0)) }} + - containerPort: 444 + hostPort: {{ int .Values.hostPort }} + protocol: TCP +{{- end}} + args: +{{- if .Values.debug }} + - "--debug" +{{- end }} +{{- if .Values.privateCA }} + # Private CA - don't clear ca certs +{{- else if and (eq .Values.tls "ingress") (eq .Values.ingress.tls.source "rancher") }} + # Rancher self-signed - don't clear ca certs +{{- else }} + # Public trusted CA - clear ca certs + - "--no-cacerts" +{{- end }} + - "--http-listen-port=80" + - "--https-listen-port=443" + - "--add-local={{ .Values.addLocal }}" + env: + - name: CATTLE_NAMESPACE + value: {{ .Release.Namespace }} + - name: CATTLE_PEER_SERVICE + value: {{ template "rancher.fullname" . }} +{{- if .Values.features }} + - name: CATTLE_FEATURES + value: "{{ .Values.features }}" +{{- end}} +{{- if .Values.noDefaultAdmin }} + - name: CATTLE_NO_DEFAULT_ADMIN + value: "{{ .Values.noDefaultAdmin }}" +{{- end}} +{{- if gt (int .Values.auditLog.level) 0 }} + - name: AUDIT_LEVEL + value: {{ .Values.auditLog.level | quote }} + - name: AUDIT_LOG_MAXAGE + value: {{ .Values.auditLog.maxAge | quote }} + - name: AUDIT_LOG_MAXBACKUP + value: {{ .Values.auditLog.maxBackup | quote }} + - name: AUDIT_LOG_MAXSIZE + value: {{ .Values.auditLog.maxSize | quote }} +{{- end }} +{{- if .Values.proxy }} + - name: HTTP_PROXY + value: {{ .Values.proxy }} + - name: HTTPS_PROXY + value: {{ .Values.proxy }} + - name: NO_PROXY + value: {{ .Values.noProxy }} +{{- end }} +{{- if .Values.systemDefaultRegistry }} + - name: CATTLE_SYSTEM_DEFAULT_REGISTRY + value: {{ .Values.systemDefaultRegistry }} +{{- end }} +{{- if .Values.useBundledSystemChart }} + - name: CATTLE_SYSTEM_CATALOG + value: bundled +{{- end }} +{{- if .Values.restrictedAdmin }} + - name: CATTLE_RESTRICTED_DEFAULT_ADMIN + value: "true" +{{- end}} +{{- if .Values.bootstrapPassword }} + - name: CATTLE_BOOTSTRAP_PASSWORD + valueFrom: + secretKeyRef: + name: "bootstrap-secret" + key: "bootstrapPassword" +{{- end }} +{{- if .Values.agentTLSMode }} + - name: CATTLE_AGENT_TLS_MODE + value: "{{ .Values.agentTLSMode }}" +{{- end }} +{{- if .Values.extraEnv }} +{{ toYaml .Values.extraEnv | indent 8}} +{{- end }} + startupProbe: + httpGet: + path: /healthz + port: 80 + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + livenessProbe: + httpGet: + path: /healthz + port: 80 + {{- with .Values.livenessProbe.initialDelaySeconds}} + initialDelaySeconds: {{ . }} + {{- end }} + timeoutSeconds: {{.Values.livenessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + failureThreshold: {{.Values.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: 80 + {{- with .Values.readinessProbe.initialDelaySeconds}} + initialDelaySeconds: {{ . }} + {{- end }} + timeoutSeconds: {{.Values.readinessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{.Values.readinessProbe.failureThreshold }} + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: +{{- if .Values.additionalTrustedCAs }} + - mountPath: /etc/pki/trust/anchors/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true + - mountPath: /etc/rancher/ssl/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true +{{- end }} +{{- if .Values.privateCA }} + # Pass CA cert into rancher for private CA + - mountPath: /etc/rancher/ssl/cacerts.pem + name: tls-ca-volume + subPath: cacerts.pem + readOnly: true +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + # Mount rancher custom-logos volume + - mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.emberUi | default "ember" | quote }} + - mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.vueUi | default "vue" | quote }} +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + - mountPath: /var/log/auditlog + name: audit-log +{{- end }} +{{- if eq .Values.auditLog.destination "sidecar" }} + {{- if gt (int .Values.auditLog.level) 0 }} + # Make audit logs available for Rancher log collector tools. + {{- if .Values.busyboxImage }} + - image: {{ .Values.busyboxImage}} + {{- else }} + - image: {{ .Values.auditLog.image.repository }}:{{.Values.auditLog.image.tag}} + {{- end }} + {{- if .Values.busyboxImagePullPolicy }} + imagePullPolicy: {{ .Values.busyboxImagePullPolicy }} + {{- else }} + imagePullPolicy: {{ .Values.auditLog.image.pullPolicy }} + {{- end }} + name: {{ template "rancher.name" . }}-audit-log + command: ["tail"] + args: ["-F", "/var/log/auditlog/rancher-api-audit.log"] + volumeMounts: + - mountPath: /var/log/auditlog + name: audit-log + {{- end }} +{{- end }} + volumes: +{{- if .Values.additionalTrustedCAs }} + - name: tls-ca-additional-volume + secret: + defaultMode: 0400 + secretName: tls-ca-additional +{{- end }} +{{- if .Values.privateCA }} + - name: tls-ca-volume + secret: + defaultMode: 0400 + secretName: tls-ca +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + {{- if eq .Values.auditLog.destination "hostPath" }} + - name: audit-log + hostPath: + path: {{ .Values.auditLog.hostPath }} + type: DirectoryOrCreate + {{- else }} + - name: audit-log + emptyDir: {} + {{- end }} +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + - name: custom-logos + {{- if (eq .Values.customLogos.volumeKind "persistentVolumeClaim") }} + persistentVolumeClaim: + claimName: {{ .Values.customLogos.volumeName | default (printf "%s-custom-logos" (include "rancher.fullname" .)) }} + {{- else if (eq .Values.customLogos.volumeKind "configMap") }} + configMap: + name: {{ .Values.customLogos.volumeName }} + {{- end }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/ingress.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/ingress.yaml new file mode 100644 index 0000000..16eb292 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/ingress.yaml @@ -0,0 +1,66 @@ +{{- if .Values.ingress.enabled }} +{{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} +apiVersion: networking.k8s.io/v1 +{{- else }} +apiVersion: networking.k8s.io/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} + annotations: +{{- if .Values.ingress.configurationSnippet }} + nginx.ingress.kubernetes.io/configuration-snippet: | + {{- template "configurationSnippet" . }} +{{- end }} +{{- if eq .Values.tls "external" }} + nginx.ingress.kubernetes.io/ssl-redirect: "false" # turn off ssl redirect for external. +{{- else }} + {{- if ne .Values.ingress.tls.source "secret" }} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + certmanager.k8s.io/issuer: {{ template "rancher.fullname" . }} + {{- else }} + cert-manager.io/issuer: {{ template "rancher.fullname" . }} + cert-manager.io/issuer-kind: Issuer + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.ingress.includeDefaultExtraAnnotations }} + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +{{- end }} +{{- if .Values.ingress.extraAnnotations }} +{{ toYaml .Values.ingress.extraAnnotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} + rules: + - host: {{ .Values.hostname }} # hostname to access rancher server + http: + paths: + - backend: + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + service: + name: {{ template "rancher.fullname" . }} + port: + number: {{ .Values.ingress.servicePort }} + {{- else }} + serviceName: {{ template "rancher.fullname" . }} + servicePort: {{ .Values.ingress.servicePort }} + {{- end }} + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + pathType: {{ .Values.ingress.pathType }} + path: {{ .Values.ingress.path }} + {{- end }} +{{- if eq .Values.tls "ingress" }} + tls: + - hosts: + - {{ .Values.hostname }} + secretName: {{ .Values.ingress.tls.secretName }} +{{- end }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-letsEncrypt.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-letsEncrypt.yaml new file mode 100644 index 0000000..ee0a7b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-letsEncrypt.yaml @@ -0,0 +1,37 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "letsEncrypt" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + acme: + {{- if eq .Values.letsEncrypt.environment "production" }} + server: https://acme-v02.api.letsencrypt.org/directory + {{- else }} + server: https://acme-staging-v02.api.letsencrypt.org/directory + {{- end }} + email: {{ .Values.letsEncrypt.email }} + privateKeySecretRef: + name: letsencrypt-{{ .Values.letsEncrypt.environment }} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + http01: {} + {{- else }} + solvers: + - http01: + ingress: + class: {{ .Values.letsEncrypt.ingress.class }} + {{- end }} + {{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-rancher.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-rancher.yaml new file mode 100644 index 0000000..9e24b38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/issuer-rancher.yaml @@ -0,0 +1,22 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "rancher" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + ca: + secretName: tls-rancher + {{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role-binding.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role-binding.yaml new file mode 100644 index 0000000..476957b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role-binding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "rancher.fullname" . }}-post-delete +subjects: + - kind: ServiceAccount + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role.yaml new file mode 100644 index 0000000..4e6b7d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-cluster-role.yaml @@ -0,0 +1,39 @@ +{{- if .Values.postDelete.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +rules: + - apiGroups: [ "extensions","apps" ] + resources: [ "deployments" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "batch" ] + resources: [ "jobs" ] + verbs: [ "get", "list", "watch", "delete", "create" ] + - apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles", "clusterrolebindings", "roles", "rolebindings" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "" ] + resources: [ "pods", "secrets", "services", "configmaps" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "networking.k8s.io" ] + resources: [ "networkpolicies" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "admissionregistration.k8s.io" ] + resources: [ "validatingwebhookconfigurations", "mutatingwebhookconfigurations" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "networking.k8s.io" ] + resources: [ "ingresses" ] + verbs: [ "delete" ] + - apiGroups: [ "cert-manager.io" ] + resources: [ "issuers" ] + verbs: [ "delete" ] +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-config-map.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-config-map.yaml new file mode 100644 index 0000000..eb7b9e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-config-map.yaml @@ -0,0 +1,15 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +data: + post-delete-hook.sh: |- +{{ $.Files.Get "scripts/post-delete-hook.sh" | indent 4 }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-job.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-job.yaml new file mode 100644 index 0000000..d90ca80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-job.yaml @@ -0,0 +1,46 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 3 + template: + metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 8 }} + spec: + serviceAccountName: {{ template "rancher.fullname" . }}-post-delete + restartPolicy: OnFailure + containers: + - name: {{ template "rancher.name" . }}-post-delete + image: "{{ include "system_default_registry" . }}{{ .Values.postDelete.image.repository }}:{{ .Values.postDelete.image.tag }}" + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: 0 + command: + - /scripts/post-delete-hook.sh + volumeMounts: + - mountPath: /scripts + name: config-volume + env: + - name: NAMESPACES + value: {{ .Values.postDelete.namespaceList | join " " | quote }} + - name: RANCHER_NAMESPACE + value: {{ .Release.Namespace }} + - name: TIMEOUT + value: {{ .Values.postDelete.timeout | quote }} + - name: IGNORETIMEOUTERROR + value: {{ .Values.postDelete.ignoreTimeoutError | quote }} + volumes: + - name: config-volume + configMap: + name: {{ template "rancher.fullname" . }}-post-delete + defaultMode: 0777 +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-service-account.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-service-account.yaml new file mode 100644 index 0000000..923687d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/post-delete-hook-service-account.yaml @@ -0,0 +1,12 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/priorityClass.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/priorityClass.yaml new file mode 100644 index 0000000..5ef748a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/priorityClass.yaml @@ -0,0 +1,8 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: rancher-critical + labels: {{ include "rancher.labels" . | nindent 4 }} +value: 1000000000 +globalDefault: false +description: "Priority class used by pods critical to rancher's functionality." diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/pvc.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/pvc.yaml new file mode 100644 index 0000000..45e644f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/pvc.yaml @@ -0,0 +1,19 @@ +{{- if and (.Values.customLogos.enabled) (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (not .Values.customLogos.volumeName) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }}-custom-logos +spec: + accessModes: + - {{ .Values.customLogos.accessMode | quote }} + resources: + requests: + storage: {{ .Values.customLogos.size | quote }} + storageClassName: {{ if .Values.customLogos.storageClass }} + {{- if (eq "-" .Values.customLogos.storageClass) -}} + "" + {{- else }} + {{- .Values.customLogos.storageClass }} + {{- end -}} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/secret.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/secret.yaml new file mode 100644 index 0000000..fd476bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/secret.yaml @@ -0,0 +1,25 @@ +{{/* Use the bootstrap password from values.yaml if an existing secret is not found */}} +{{- $bootstrapPassword := .Values.bootstrapPassword -}} +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace "bootstrap-secret" -}} +{{- if $existingSecret -}} + {{- if $existingSecret.data -}} + {{- if $existingSecret.data.bootstrapPassword -}} + {{- $bootstrapPassword = $existingSecret.data.bootstrapPassword | b64dec -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{/* If a bootstrap password was found in the values or an existing password was found create the secret */}} +{{- if $bootstrapPassword }} +apiVersion: v1 +kind: Secret +metadata: + name: "bootstrap-secret" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-5" + "helm.sh/resource-policy": keep +type: Opaque +data: + bootstrapPassword: {{ $bootstrapPassword | b64enc | quote }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/service.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/service.yaml new file mode 100644 index 0000000..2b2967b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + {{- /* + If service.type is not provided this attribute is ommitted and k8s default of ClusterIP is used. + */}} + {{- if .Values.service.type }} + type: {{ .Values.service.type }} + {{- end }} + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + targetPort: 444 + protocol: TCP + name: https-internal + selector: + app: {{ template "rancher.fullname" . }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/templates/serviceAccount.yaml b/on-premise/main/rancher_v2.9.1/rancher/templates/serviceAccount.yaml new file mode 100644 index 0000000..84c0d29 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/templates/serviceAccount.yaml @@ -0,0 +1,6 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} diff --git a/on-premise/main/rancher_v2.9.1/rancher/values.schema.json b/on-premise/main/rancher_v2.9.1/rancher/values.schema.json new file mode 100644 index 0000000..d72b73f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/values.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "agentTLSMode": { + "type": ["string", "null"], + "enum": ["strict", "system-store", "", null], + "description": "agentTLSMode must be 'strict' or 'system-store' or null (defaults to system-store)" + } + }, + "required": [], + "title": "Rancher Chart Values", + "type": "object" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/rancher/values.yaml b/on-premise/main/rancher_v2.9.1/rancher/values.yaml new file mode 100644 index 0000000..0867a82 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/rancher/values.yaml @@ -0,0 +1,198 @@ +# Additional Trusted CAs. +# Enable this flag and add your CA certs as a secret named tls-ca-additional in the namespace. +# See README.md for details. +additionalTrustedCAs: false + +antiAffinity: preferred +topologyKey: kubernetes.io/hostname + +# Audit Logs https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# The audit log is piped to the console of the rancher-audit-log container in the rancher pod. +# https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# destination stream to sidecar container console or hostPath volume +# level: Verbosity of logs, 0 to 3. 0 is off 3 is a lot. +auditLog: + destination: sidecar + hostPath: /var/log/rancher/audit/ + level: 0 + maxAge: 1 + maxBackup: 1 + maxSize: 100 + + # Image for collecting rancher audit logs. + # Important: update pkg/image/export/resolve.go when this default image is changed, so that it's reflected accordingly in rancher-images.txt generated for air-gapped setups. + image: + repository: "rancher/mirrored-bci-micro" + tag: 15.4.14.3 + # Override imagePullPolicy image + # options: Always, Never, IfNotPresent + pullPolicy: "IfNotPresent" + +# As of Rancher v2.5.0 this flag is deprecated and must be set to 'true' in order for Rancher to start +addLocal: "true" + +# Add debug flag to Rancher server +debug: false + +# When starting Rancher for the first time, bootstrap the admin as restricted-admin +restrictedAdmin: false + +# Control how the Rancher agents validate TLS connections +# Valid options: strict, or system-store +# Note, for new installations empty will default to strict on 2.9+, or system-store on 2.8 or older +agentTLSMode: "" + +# Extra environment variables passed to the rancher pods. +# extraEnv: +# - name: CATTLE_TLS_MIN_VERSION +# value: "1.0" + +# Fully qualified name to reach your Rancher server +hostname: rancher.inje-private.com + +## Optional array of imagePullSecrets containing private registry credentials +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: secretName + +### ingress ### +# Readme for details and instruction on adding tls secrets. +ingress: + # If set to false, ingress will not be created + # Defaults to true + # options: true, false + enabled: false # by ljh true -> false + includeDefaultExtraAnnotations: true + extraAnnotations: {} + ingressClassName: "" + # Certain ingress controllers will require the pathType or path to be set to a different value. + pathType: ImplementationSpecific + path: "/" + # backend port number + servicePort: 80 + + # configurationSnippet - Add additional Nginx configuration. This example statically sets a header on the ingress. + # configurationSnippet: | + # more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + + tls: + # options: rancher, letsEncrypt, secret + source: rancher + secretName: tls-rancher-ingress + +### service ### +# Override to use NodePort or LoadBalancer service type - default is ClusterIP +service: + type: "" + annotations: {} + +### LetsEncrypt config ### +# ProTip: The production environment only allows you to register a name 5 times a week. +# Use staging until you have your config right. +letsEncrypt: + # email: none@example.com + environment: production + ingress: + # options: traefik, nginx + class: "" +# If you are using certs signed by a private CA set to 'true' and set the 'tls-ca' +# in the 'rancher-system' namespace. See the README.md for details +privateCA: false + +# http[s] proxy server passed into rancher server. +# proxy: http://@:: + +# comma separated list of domains or ip addresses that will not use the proxy +noProxy: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local + +# Override rancher image location for Air Gap installs +rancherImage: reg.inje-private.com/nnd002/rancher/rancher #by ljh +# rancher/rancher image tag. https://hub.docker.com/r/rancher/rancher/tags/ +# Defaults to .Chart.appVersion +# rancherImageTag: v2.0.7 + +# Override imagePullPolicy for rancher server images +# options: Always, Never, IfNotPresent +# Defaults to IfNotPresent +# rancherImagePullPolicy: + +# Number of Rancher server replicas. Setting to negative number will dynamically between 0 and the abs(replicas) based on available nodes. +# of available nodes in the cluster +replicas: 3 + +# Set priorityClassName to avoid eviction +priorityClassName: rancher-critical + +# Set pod resource requests/limits for Rancher. +resources: {} + +# +# tls +# Where to offload the TLS/SSL encryption +# - ingress (default) +# - external +tls: external # by ljh + +systemDefaultRegistry: "" +# Set to use the packaged system charts +useBundledSystemChart: false + +# Certmanager version compatibility +certmanager: + version: "" + +# Rancher custom logos persistence +customLogos: + enabled: true # by ljh + volumeSubpaths: + emberUi: "ember" + vueUi: "vue" + ## Volume kind to use for persistence: persistentVolumeClaim, configMap + volumeKind: persistentVolumeClaim + ## Use an existing volume. Custom logos should be copied to the volume by the user + # volumeName: custom-logos + ## Just for volumeKind: persistentVolumeClaim + ## To disables dynamic provisioning, set storageClass: "" or storageClass: "-" + storageClass: "sc-monitoring" # by ljh + accessMode: ReadWriteOnce + size: 10Gi + +# Rancher post-delete hook +postDelete: + enabled: false #by ljh + image: + repository: reg.inje-private.com/nnd002/rancher/shell # by ljh add registry + tag: v0.2.1 + namespaceList: + - cattle-fleet-system + - cattle-system + - rancher-operator-system + # Number of seconds to wait for an app to be uninstalled + timeout: 120 + # by default, the job will fail if it fail to uninstall any of the apps + ignoreTimeoutError: false + +# Set a bootstrap password. If leave empty, a random password will be generated. +bootstrapPassword: "" + +startupProbe: + ## should be ready within 2 minutes + timeoutSeconds: 5 + periodSeconds: 10 + failureThreshold: 12 +livenessProbe: + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 5 +readinessProbe: + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 5 + +# helm values to use when installing the rancher-webhook chart. +# helm values set here will override all other global values used when installing the webhook such as priorityClassName and systemRegistry settings. +webhook: "" + +# helm values to use when installing the fleet chart. +# helm values set here will override all other global values used when installing the fleet chart. +fleet: "" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.dockerignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.dockerignore new file mode 100644 index 0000000..e80835d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.dockerignore @@ -0,0 +1,16 @@ +./bin +./.dapper +./build +./dist +./.idea +./default.etcd +./package/rancher +./package/agent +./tests/MANIFEST +./tests/.idea +./tests/.cache +./tests/.tox +./tests/.venv +**/*.pyc +**/__pycache__ +./management-state/ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitattributes b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitattributes new file mode 100644 index 0000000..c2bca6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitattributes @@ -0,0 +1,6 @@ +# Treat all Go files in this repo as binary, with no git magic updating +# line endings. Windows users contributing to Go will need to use a +# modern version of git and editors capable of LF line endings. + +*.go -text diff=golang +* text eol=lf diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/bug_report.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a625e77 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,48 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: kind/bug +assignees: '' + +--- + +**Rancher Server Setup** +- Rancher version: +- Installation option (Docker install/Helm Chart): + - If Helm Chart, Kubernetes Cluster and version (RKE1, RKE2, k3s, EKS, etc): +- Proxy/Cert Details: + +**Information about the Cluster** +- Kubernetes version: +- Cluster Type (Local/Downstream): + - If downstream, what type of cluster? (Custom/Imported or specify provider for Hosted/Infrastructure Provider): + + +**User Information** +- What is the role of the user logged in? (Admin/Cluster Owner/Cluster Member/Project Owner/Project Member/Custom) + - If custom, define the set of permissions: + + + +**Describe the bug** + + +**To Reproduce** + + +**Result** + +**Expected Result** + + +**Screenshots** + + +**Additional context** + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/feature_request.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..5d1acce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[RFE] " +labels: kind/enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/flaky-tests.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/flaky-tests.md new file mode 100644 index 0000000..0142c73 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/ISSUE_TEMPLATE/flaky-tests.md @@ -0,0 +1,25 @@ +--- +name: Flaky Tests +about: File a report of a flaky test from drone or automation runs +title: "[flaky-test]" +labels: kind/flaky-test +assignees: '' + +--- + +**Flaky Test** + +``` + +``` + +**Release Branch** + +source branch of PR: `release/vXXX` + + +**Drone Build (if applicable)** + +pipeline stage URL: + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/k3s-images/action.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/k3s-images/action.yml new file mode 100644 index 0000000..41c4607 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/k3s-images/action.yml @@ -0,0 +1,18 @@ +name: "Download K3S images" +description: "Download k3s images txt file and save airgap images" +inputs: + k3s_version: + description: "k3s version" + required: true +runs: + using: "composite" + steps: + - name: Download images txt file + shell: bash + run: curl -sLf https://github.com/rancher/k3s/releases/download/${{ inputs.k3s_version }}/k3s-images.txt -o /tmp/k3s-images.txt + - name: Create k3s images file + shell: bash + run: | + images=$(grep -e 'docker.io/rancher/mirrored-pause' -e 'docker.io/rancher/mirrored-coredns-coredns' /tmp/k3s-images.txt) + xargs -n1 docker pull <<< "${images}" + docker save -o ./k3s-airgap-images.tar ${images} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-build-env/action.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-build-env/action.yml new file mode 100644 index 0000000..4197780 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-build-env/action.yml @@ -0,0 +1,97 @@ +name: "Setup Dependencies Variables" +description: "Setup Dependencies Variables from other files" +outputs: + CATTLE_KDM_BRANCH: + description: "CATTLE_KDM_BRANCH from package/Dockerfile" + value: ${{ steps.vars.outputs.CATTLE_KDM_BRANCH }} + CATTLE_K3S_VERSION: + description: "CATTLE_K3S_VERSION from package/Dockerfile" + value: ${{ steps.vars.outputs.CATTLE_K3S_VERSION }} + CATTLE_HELM_VERSION: + description: "CATTLE_HELM_VERSION from package/Dockerfile" + value: ${{ steps.vars.outputs.CATTLE_HELM_VERSION }} + HELM_VERSION: + description: "HELM_VERSION from package/Dockerfile" + value: ${{ steps.vars.outputs.HELM_VERSION }} + HELM_UNITTEST_VERSION: + description: "HELM_UNITTEST_VERSION from Dockerfile.dapper" + value: ${{ steps.vars.outputs.HELM_UNITTEST_VERSION }} + RKE_VERSION: + description: "RKE_VERSION from go.mod" + value: ${{ steps.vars.outputs.RKE_VERSION }} + CATTLE_RANCHER_WEBHOOK_VERSION: + description: "CATTLE_RANCHER_WEBHOOK_VERSION from scripts/export-config" + value: ${{ steps.vars.outputs.CATTLE_RANCHER_WEBHOOK_VERSION }} + CATTLE_CSP_ADAPTER_MIN_VERSION: + description: "CATTLE_CSP_ADAPTER_MIN_VERSION from scripts/export-config" + value: ${{ steps.vars.outputs.CATTLE_CSP_ADAPTER_MIN_VERSION }} + CATTLE_FLEET_VERSION: + description: "CATTLE_FLEET_VERSION from scripts/export-config" + value: ${{ steps.vars.outputs.CATTLE_FLEET_VERSION }} +runs: + using: "composite" + steps: + - id: vars + shell: bash + run: | + source scripts/export-config + CATTLE_KDM_BRANCH=$(grep -m1 'ARG CATTLE_KDM_BRANCH=' package/Dockerfile | cut -d '=' -f2) + CATTLE_K3S_VERSION=$(grep -m1 'ENV CATTLE_K3S_VERSION' package/Dockerfile | awk '{print $3}') + HELM_VERSION=$(grep -m1 'ENV HELM_VERSION' package/Dockerfile | awk '{print $3}') + CATTLE_HELM_VERSION=$(grep -m1 'ENV CATTLE_HELM_VERSION' package/Dockerfile | awk '{print $3}') + HELM_UNITTEST_VERSION=$(grep -m1 'ENV HELM_UNITTEST_VERSION' Dockerfile.dapper | awk '{print $3}') + RKE_VERSION=$(grep -m1 'github.com/rancher/rke' go.mod | awk '{print $2}') + if [[ -z "$RKE_VERSION" ]]; then + RKE_VERSION=$(grep -m1 'github.com/rancher/rke' go.mod | awk '{print $4}') + fi + RKE_VERSION=$RKE_VERSION + CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION + CATTLE_CSP_ADAPTER_MIN_VERSION=$CATTLE_CSP_ADAPTER_MIN_VERSION + CATTLE_FLEET_VERSION=$CATTLE_FLEET_VERSION + + if [[ -z "$CATTLE_KDM_BRANCH" ]]; then + echo "CATTLE_KDM_BRANCH not found" + exit 1 + fi + if [[ -z "$CATTLE_K3S_VERSION" ]]; then + echo "CATTLE_K3S_VERSION not found" + exit 1 + fi + if [[ -z "$HELM_VERSION" ]]; then + echo "HELM_VERSION not found" + exit 1 + fi + if [[ -z "$CATTLE_HELM_VERSION" ]]; then + echo "CATTLE_HELM_VERSION not found" + exit 1 + fi + if [[ -z "$HELM_UNITTEST_VERSION" ]]; then + echo "HELM_UNITTEST_VERSION not found" + exit 1 + fi + if [[ -z "$RKE_VERSION" ]]; then + echo "RKE_VERSION not found" + exit 1 + fi + if [[ -z "$CATTLE_RANCHER_WEBHOOK_VERSION" ]]; then + echo "CATTLE_RANCHER_WEBHOOK_VERSION not found" + exit 1 + fi + if [[ -z "$CATTLE_CSP_ADAPTER_MIN_VERSION" ]]; then + echo "CATTLE_CSP_ADAPTER_MIN_VERSION not found" + exit 1 + fi + if [[ -z "$CATTLE_FLEET_VERSION" ]]; then + echo "CATTLE_FLEET_VERSION not found" + exit 1 + fi + echo "CATTLE_KDM_BRANCH=$CATTLE_KDM_BRANCH" >> $GITHUB_OUTPUT + echo "CATTLE_K3S_VERSION=$CATTLE_K3S_VERSION" >> $GITHUB_OUTPUT + echo "HELM_VERSION=$HELM_VERSION" >> $GITHUB_OUTPUT + echo "CATTLE_HELM_VERSION=$CATTLE_HELM_VERSION" >> $GITHUB_OUTPUT + echo "HELM_UNITTEST_VERSION=$HELM_UNITTEST_VERSION" >> $GITHUB_OUTPUT + echo "RKE_VERSION=$RKE_VERSION" >> $GITHUB_OUTPUT + echo "CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION" >> $GITHUB_OUTPUT + echo "CATTLE_CSP_ADAPTER_MIN_VERSION=$CATTLE_CSP_ADAPTER_MIN_VERSION" >> $GITHUB_OUTPUT + echo "CATTLE_FLEET_VERSION=$CATTLE_FLEET_VERSION" >> $GITHUB_OUTPUT + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-tag-env/action.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-tag-env/action.yml new file mode 100644 index 0000000..a0310d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/actions/setup-tag-env/action.yml @@ -0,0 +1,20 @@ +name: "Setup TAG and HEAD_TAG env variables" +description: "Setup TAG and HEAD_TAG env variables" +runs: + using: "composite" + steps: + - shell: bash + run: | + ref_name="${{ github.ref_name }}" + TAG="${{ github.sha }}" + prefix="release/" + if [[ "$ref_name" == release/v* ]]; then + TAG=${ref_name#$prefix}-${{ github.sha }}-head + HEAD_TAG=${ref_name#$prefix}-head + echo "HEAD_TAG=$HEAD_TAG" >> "$GITHUB_ENV" + fi + if [[ "${{ github.ref }}" == refs/tags/* ]]; then + TAG="$ref_name" + fi + echo "TAG=$TAG" >> "$GITHUB_ENV" + echo "GIT_TAG=$TAG" >> "$GITHUB_ENV" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/pull_request_template.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/pull_request_template.md new file mode 100644 index 0000000..129126e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/pull_request_template.md @@ -0,0 +1,49 @@ +## Issue: + + +## Problem + + +## Solution + + +## Testing + + +## Engineering Testing +### Manual Testing + + +### Automated Testing + +* Test types added/modified: + * Unit + * Integration (Go Framework) + * Integration (v2prov Framework) + * Validation (Go Framework) + * Other - Explain: _EXPLAIN_ + * None + * _REMOVE NOT APPLICABLE BULLET POINTS ABOVE_ +* If "None" - Reason: _EXPLAIN THE REASON_ + +* If "None" - GH Issue/PR: _LINK TO GH ISSUE/PR TO ADD TESTS_ + +Summary: _TODO_ + +## QA Testing Considerations + + +### Regressions Considerations + +_TODO_ + +Existing / newly added automated tests that provide evidence there are no regressions: +* _TODO_ \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/renovate.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/renovate.json new file mode 100644 index 0000000..7a0a1c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/renovate.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "github>rancher/renovate-config#release" + ], + "baseBranches": [ + "release/v2.9" + ], + "prHourlyLimit": 2, + "prConcurrentLimit": 4, + "prCreation": "status-success" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/runs-on.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/runs-on.yml new file mode 100644 index 0000000..b1bfde5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/runs-on.yml @@ -0,0 +1 @@ +_extends: .github-private diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-auto-generated-changes.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-auto-generated-changes.sh new file mode 100755 index 0000000..749158c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-auto-generated-changes.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -ue + +go generate ./... + +if [ -n "$(git status --porcelain)" ]; then + echo "Generated files have either been changed manually or were not updated." + echo + echo "The following generated files did differ after regeneration:" + git status --porcelain + exit 1 +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-go-mod-changes.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-go-mod-changes.sh new file mode 100755 index 0000000..61a00d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/scripts/check-for-go-mod-changes.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -ue + +for DIRECTORY in . ./pkg/apis ./pkg/client; do + cd "$DIRECTORY" + go mod tidy + go mod verify + cd "$OLDPWD" +done + +if [ -n "$(git status --porcelain)" ]; then + echo "go.mod is not up to date. Please 'run go mod tidy' and commit the changes." + echo + echo "The following go files did differ after tidying them:" + git status --porcelain + exit 1 +fi + +# Check diff between ./go.mod and ./pkg/apis/go.mod +badmodule="false" +while read -r module tag; do + # Get tag from module in ./go.mod + roottag=$(sed '1,/^require/d' go.mod | grep "${module} " | awk '{ print $2 }') + echo "${module}:" + echo "${tag} (./pkg/apis/go.mod)" + echo "${roottag} (./go.mod)" + # Compare with tag from module in ./pkg/apis/go.mod + if [ "${tag}" != "${roottag}" ]; then + echo "${module} is different ('${tag}' vs '${roottag}')" + badmodule="true" + fi +done << EOF +$(sed '1,/require/d' pkg/apis/go.mod | head -n -1 | grep -v indirect | grep rancher | awk '{ print $1,$2 }') +EOF + +if [ "${badmodule}" = "true" ]; then + echo "Diff found between ./go.mod and ./pkg/apis/go.mod" + exit 1 +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/README.md new file mode 100644 index 0000000..a2202df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/README.md @@ -0,0 +1,13 @@ +# Description of GitHub Actions in this repository + +## Go Get (`go-get.yml`) + +Go Get can be used to automate updating Go modules in this repository. It will run `make go-get` which is a helper script for running `go get -d $GOGET_MODULE@$GOGET_VERSION` in all needed places, commit and create a pull request. + +If `Username of the source for this workflow run` is set, the username will be mentioned in the pull request and configured as assignee. This was added for automated workflows, where the user and URL can be used to link back to the source of the trigger. + +If `URL of the source for this workflow run` is set, the URL will be mentioned in the pull request. This was added for automated workflows, where the user and URL can be used to link back to the source of the trigger. + +## Replace environment variable in file (`replace-env-value.yml`) + +Replace environment variable in file can be used to replace an environment variable in any file. It will run `./scripts/replace-env-value-in-file.sh`, commit and create a pull request with the changes. This is mostly used for bumping versions. This workflow should work for `KEY=VALUE` (equal sign separated) values and `KEY VALUE` (space separated) values. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/go-get.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/go-get.yml new file mode 100644 index 0000000..af700ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/go-get.yml @@ -0,0 +1,99 @@ +name: Go get +on: + workflow_dispatch: + inputs: + goget_module: + type: string + description: "What Go module to get" + goget_version: + type: string + description: "What Go module version to get" + source_url: + type: string + description: "URL of the source for this workflow run" + source_author: + type: string + description: "Username of the source for this workflow run" + +env: + GOGET_MODULE: ${{ github.event.inputs.goget_module }} + GOGET_VERSION: ${{ github.event.inputs.goget_version }} + INPUT_SOURCE_URL: ${{ github.event.inputs.source_url }} + INPUT_SOURCE_AUTHOR: ${{ github.event.inputs.source_author }} + +permissions: + contents: write + pull-requests: write +jobs: + go-get: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v2 + - name: Run go get to get Go module + run: make go-get + - name: Check for repository changes + run: | + if git diff --name-only --exit-code; then + echo "No changes found in repository after 'go get'" + echo "changes_exist=false" >> $GITHUB_ENV + else + echo "Changes found in repository after 'go get':" + git diff --name-only + echo "changes_exist=true" >> $GITHUB_ENV + fi + - name: Create branch, commit and push + if: ${{ env.changes_exist == 'true' }} + id: branch + run: | + BRANCH="githubaction-go-get-$(date +%Y-%m-%d-%H-%M-%S)" + echo "::set-output name=branch::$BRANCH" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git checkout -b "$BRANCH" + git commit -a -m "go get ${GOGET_MODULE} ${GOGET_VERSION}" + git push origin "$BRANCH" + - name: Create Pull Request + if: ${{ env.changes_exist == 'true' }} + id: cpr + uses: actions/github-script@v5.0.0 + env: + SOURCE_BRANCH: ${{ steps.branch.outputs.branch }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { GOGET_MODULE, GOGET_VERSION} = process.env + let body = 'Auto-generated by GitHub Actions\n\n' + if ( `${ process.env.INPUT_SOURCE_URL }` ) { + body += `\nSource URL: ${ process.env.INPUT_SOURCE_URL }` + } + if ( `${ process.env.INPUT_SOURCE_AUTHOR }` ) { + body += `\nSource AUTHOR: @${ process.env.INPUT_SOURCE_AUTHOR}` + } + + const { data: pr } = await github.rest.pulls.create({ + title: `[${{ github.ref_name }}] go get ${GOGET_MODULE} ${GOGET_VERSION}`, + body: body, + owner: context.repo.owner, + repo: context.repo.repo, + base: "${{ github.ref_name }}", + head: `${ process.env.SOURCE_BRANCH }` + }); + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pr.number, + labels: ["status/auto-created"], + }); + if ( `${ process.env.INPUT_SOURCE_AUTHOR }` ) { + await github.rest.issues.addAssignees({ + ...context.repo, + issue_number: pr.number, + assignees: [`${ process.env.INPUT_SOURCE_AUTHOR}`], + }); + } + console.log('Created new pull request'); + return pr.html_url; + - name: Check outputs + if: ${{ env.changes_exist == 'true' }} + run: | + echo "Pull Request URL - ${{ steps.cpr.outputs.result }}" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/integration-tests.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/integration-tests.yml new file mode 100644 index 0000000..d36bc58 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/integration-tests.yml @@ -0,0 +1,160 @@ +name: Integration Tests +on: + workflow_call: + inputs: + parent_run_id: + type: string + description: "parent run_id to download images from" + required: true +permissions: {} +env: + HOST_ARCH: amd64 + ARCH: amd64 + PYTHON_VERSION: '3.11' + GOLANG_VERSION: '1.22' + IMAGE: ${{ github.repository_owner }}/rancher + IMAGE_AGENT: ${{ github.repository_owner }}/rancher-agent +jobs: + test: + runs-on: runs-on,runner=8cpu-linux-x64,image=legacy-cgroups-for-x64,run-id=${{ github.run_id }} + timeout-minutes: 60 + env: + K3D_VERSION: v5.7.1 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Clean up Docker + run: | + docker system prune -af + docker volume prune -f + # Cleaning the runner is important to free enough space to build rancher, otherwise the build will fail + - name: Clean runner + run: | + # removes dotnet + sudo rm -rf /usr/share/dotnet + # removes haskell + sudo rm -rf /opt/ghc + # removes android sdk + sudo rm -rf /usr/local/lib/android + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Download Docker images artifact + uses: actions/download-artifact@v4 + with: + run-id: ${{ inputs.parent_run_id }} + github-token: ${{ github.token }} + path: "/tmp" + merge-multiple: true + - name: Load server image + run: | + image_server_id=$(docker load --input /tmp/rancher-linux-amd64.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_server_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + + AMD_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "rancher/rancher:.*amd64.*$" | head -n 1) + echo "the image created is $AMD_IMAGE" + docker tag "$image_server_id" ${{ env.IMAGE }}:${{ env.TAG }} + docker image ls + docker rmi "$AMD_IMAGE" + docker image ls + - name: Load agent image + run: | + image_agent_id=$(docker load --input /tmp/rancher-agent-linux-amd64.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_agent_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + + AMD_IMAGE_AGENT=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "rancher/rancher-agent:.*amd64.*$" | head -n 1) + docker tag "$image_agent_id" ${{ env.IMAGE_AGENT }}:${{ env.TAG }} + echo "the image created is $AMD_IMAGE_AGENT" + docker image ls + docker rmi "$AMD_IMAGE_AGENT" + docker image ls + - name: Install k3d + run: curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=${{ env.K3D_VERSION }} bash + - name: Uninstall existing Python versions + run: | + sudo apt-get remove -y python3 + sudo apt-get autoremove -y + sudo apt-get purge -y python3 + sudo apt-get clean + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "${{ env.PYTHON_VERSION }}" + - name: Check Python version + run: | + sudo rm -rf /usr/bin/python3 + sudo cp $(which python3) /usr/bin/python3 + python3 --version + python3 -m ensurepip --upgrade + - name: Install Python and dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3-pip python3-dev libffi-dev libssl-dev + sudo pip3 install --upgrade pip + sudo pip3 install tox flake8 + + ## Helm Setup start + - name: Uninstall Helm + run: | + sudo rm -rf /usr/local/bin/helm /usr/bin/rancher-helm /usr/bin/rancher-tiller ~/.helm /usr/local/bin/helm_v3 /usr/local/bin/tiller + + - name: Set Helm 2 URL + run: echo "HELM_URL_V2=https://github.com/rancher/helm/releases/download/${{ steps.env.outputs.CATTLE_HELM_VERSION }}/rancher-helm" >> $GITHUB_ENV + + - name: Set Tiller URL + run: echo "TILLER_URL=https://github.com/rancher/helm/releases/download/${{ steps.env.outputs.CATTLE_HELM_VERSION }}/rancher-tiller" >> $GITHUB_ENV + + - name: Download Rancher Helm + run: sudo curl -sLf ${{ env.HELM_URL_V2 }} -o /usr/bin/rancher-helm-v2 + + - name: Download Rancher Tiller + run: sudo curl -sLf ${{ env.TILLER_URL }} -o /usr/bin/rancher-tiller + + - name: Set permissions for Helm and Tiller + run: sudo chmod +x /usr/bin/rancher-helm-v2 /usr/bin/rancher-tiller + + - name: Create symlink for Helm + run: sudo ln -s /usr/bin/rancher-helm-v2 /usr/bin/helm + + - name: Create symlink for Tiller + run: sudo ln -s /usr/bin/rancher-tiller /usr/bin/tiller + + - name: Initialize Helm + run: helm init -c --stable-repo-url https://charts.helm.sh/stable/ + + - name: Set Helm 3 URL + run: echo "HELM_URL_V3=https://get.helm.sh/helm-${{ steps.env.outputs.HELM_VERSION }}-linux-${{ env.HOST_ARCH }}.tar.gz" >> $GITHUB_ENV + + - name: Create temporary directory for Helm 3 + run: sudo mkdir /usr/tmp + + - name: Download and extract Helm 3 + run: curl ${{ env.HELM_URL_V3 }} | sudo tar xvzf - --strip-components=1 -C /usr/tmp/ + + - name: Move Helm 3 binary + run: sudo mv /usr/tmp/helm /usr/bin/helm_v3 + + - name: KDM data + run: | + mkdir -p bin + curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${{ steps.env.outputs.CATTLE_KDM_BRANCH }}/data.json > bin/data.json + ## Helm Setup end + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "${{ env.GOLANG_VERSION }}" + - name: Build Integration Setup + shell: bash + run: | + ./tests/v2/integration/scripts/build-integration-setup + - name: Run Tests + shell: bash + run: sudo --preserve-env GOBIN=$(which go) ./scripts/gha/tests diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/manual.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/manual.yml new file mode 100644 index 0000000..cf4e50b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/manual.yml @@ -0,0 +1,102 @@ +# This is a basic workflow that is manually triggered + +name: Port issue +run-name: "Port issue ${{ github.event.issue.number }}: ${{ github.event.issue.title }}" + +on: + issue_comment: + types: + - created + +jobs: + port-issue: + runs-on: ubuntu-latest + if: contains(github.event.comment.body, '/backport') || contains(github.event.comment.body, '/forwardport') + steps: + - name: Check org membership + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: | + if gh api orgs/${GITHUB_REPOSITORY_OWNER}/members --paginate | jq -e --arg GITHUB_ACTOR "$GITHUB_ACTOR" '.[] | select(.login == $GITHUB_ACTOR)' > /dev/null; then + echo "${GITHUB_ACTOR} is a member" + echo "is_member=true" >> $GITHUB_ENV + else + echo "${GITHUB_ACTOR} is not a member of ${GITHUB_REPOSITORY_OWNER}" >> $GITHUB_STEP_SUMMARY + echo "is_member=false" >> $GITHUB_ENV + fi + - name: Check milestone + if: env.is_member == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + ORIGINAL_ISSUE_NUMBER: ${{ github.event.issue.number }} + COMMENT_BODY: ${{ github.event.comment.body }} + run: | + BODY_MILESTONE=$(echo "${COMMENT_BODY}" | awk '{ print $2 }') + # Sanitize input + MILESTONE=${BODY_MILESTONE//[^a-zA-Z0-9\-\.]/} + if gh api repos/${GITHUB_REPOSITORY}/milestones --paginate | jq -e --arg MILESTONE "$MILESTONE" '.[] | select(.title == $MILESTONE)' > /dev/null; then + echo "Milestone exists" + echo "milestone_exists=true" >> $GITHUB_ENV + else + echo "Milestone ${MILESTONE} does not exist" >> $GITHUB_STEP_SUMMARY + gh issue comment -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --body "Not creating port issue, milestone ${MILESTONE} does not exist or is not an open milestone" + echo "milestone_exists=false" >> $GITHUB_ENV + fi + - name: Port issue + if: | + env.is_member == 'true' && + env.milestone_exists == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + ORIGINAL_ISSUE_NUMBER: ${{ github.event.issue.number }} + COMMENT_BODY: ${{ github.event.comment.body }} + run: | + declare -a additional_cmd + BODY=$(mktemp) + ORIGINAL_ISSUE=$(gh issue view -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --json title,body,assignees) + ORIGINAL_TITLE=$(echo "${ORIGINAL_ISSUE}" | jq -r .title) + TYPE=$(echo "${COMMENT_BODY}" | awk '{ print $1 }' | sed -e 's_/__') + MILESTONE=$(echo "${COMMENT_BODY}" | awk '{ print $2 }') + NEW_TITLE="[${TYPE}] ${ORIGINAL_TITLE}" + # rancher/rancher title + if [[ $MILESTONE =~ (v[0-9]\.[0-9]+) ]]; then + NEW_TITLE="[${TYPE} ${BASH_REMATCH[1]}] ${ORIGINAL_TITLE}" + fi + # rancher/rke2 title + # MAJOR_MINOR_MILESTONE=$(echo $MILESTONE | cut -d. -f1,2) + # NEW_TITLE="[${TYPE} release-${MAJOR_MINOR_MILESTONE}] ${ORIGINAL_TITLE}" + ORIGINAL_LABELS=$(gh issue view -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --json labels --jq '.labels[].name' | grep -v '^\[zube\]:' | paste -sd "," -) + if [ -n "$ORIGINAL_LABELS" ]; then + additional_cmd+=("--label") + additional_cmd+=("${ORIGINAL_LABELS}") + fi + ORIGINAL_PROJECT=$(gh issue view -R ${GITHUB_REPOSITORY} ${ORIGINAL_ISSUE_NUMBER} --json projectItems --jq '.projectItems[].title') + if [ -n "$ORIGINAL_PROJECT" ]; then + additional_cmd+=("--project") + additional_cmd+=("${ORIGINAL_PROJECT}") + fi + ASSIGNEES=$(echo "${ORIGINAL_ISSUE}" | jq -r .assignees[].login) + if [ -n "$ASSIGNEES" ]; then + echo "Checking if assignee is member before assigning" + DELIMITER="" + NEW_ASSIGNEES="" + for ASSIGNEE in $ASSIGNEES; do + if gh api orgs/${GITHUB_REPOSITORY_OWNER}/members --paginate | jq -e --arg GITHUB_ACTOR "$GITHUB_ACTOR" '.[] | select(.login == $GITHUB_ACTOR)' > /dev/null; then + echo "${ASSIGNEE} is a member, adding to assignees" + NEW_ASSIGNEES="${NEW_ASSIGNEES}${DELIMITER}${ASSIGNEE}" + DELIMITER="," + fi + done + if [ -n "$NEW_ASSIGNEES" ]; then + echo "Assignees for new issue: ${NEW_ASSIGNEES}" + additional_cmd+=("--assignee") + additional_cmd+=("${NEW_ASSIGNEES}") + fi + fi + if [ -n "$MILESTONE" ]; then + echo -e "This is a ${TYPE} issue for #${ORIGINAL_ISSUE_NUMBER}, automatically created via [GitHub Actions workflow]($GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID) initiated by @${GITHUB_ACTOR}\n" > $BODY + echo -e "\nOriginal issue body:\n" >> $BODY + echo "${ORIGINAL_ISSUE}" | jq -r '.body[0:65536]' >> $BODY + NEW_ISSUE=$(gh issue create -R "${GITHUB_REPOSITORY}" --title "${NEW_TITLE}" --body-file "${BODY}" -m "${MILESTONE}" "${additional_cmd[@]}") + echo "Port issue created: ${NEW_ISSUE}" >> $GITHUB_STEP_SUMMARY + fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/promote-docker-image.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/promote-docker-image.yml new file mode 100644 index 0000000..93f6153 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/promote-docker-image.yml @@ -0,0 +1,39 @@ +name: Promote docker image to latest or stable +on: + workflow_dispatch: + inputs: + tag: + type: string + description: "e.g: v2.8.4" + required: true + promote-to: + type: choice + description: "Promote to latest or stable" + options: + - "latest" + - "stable" + required: true +env: + REGISTRY: "docker.io" + IMAGE: ${{ github.repository }} + TAG: ${{ github.event.inputs.tag }} + NEW_TAG: ${{ github.event.inputs.promote-to }} +jobs: + promote: + runs-on: ubuntu-latest + container: + image: quay.io/skopeo/stable:v1.15 + permissions: + contents: read + id-token: write + steps: + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Skopeo login + run: echo ${{ env.DOCKER_PASSWORD }} | skopeo login ${{ env.REGISTRY }} --username ${{ env.DOCKER_USERNAME }} --password-stdin + - name: Copy image to new tag + run: skopeo copy docker://${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.TAG }} docker://${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.NEW_TAG }} --all diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/provisioning-tests.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/provisioning-tests.yml new file mode 100644 index 0000000..af7b556 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/provisioning-tests.yml @@ -0,0 +1,38 @@ +name: Provisioning tests +on: + pull_request: + branches: + - release/v* +jobs: + provisioning_tests: + strategy: + fail-fast: false + matrix: + include: + - V2PROV_TEST_DIST: "k3s" + V2PROV_TEST_RUN_REGEX: "^Test_(General|Provisioning)_.*$" + - V2PROV_TEST_DIST: "rke2" + V2PROV_TEST_RUN_REGEX: "^Test_(General|Provisioning)_.*$" + - V2PROV_TEST_DIST: "k3s" + V2PROV_TEST_RUN_REGEX: "^Test_Operation_.*$" + - V2PROV_TEST_DIST: "rke2" + V2PROV_TEST_RUN_REGEX: "^Test_Operation_SetA_.*$" + - V2PROV_TEST_DIST: "rke2" + V2PROV_TEST_RUN_REGEX: "^Test_Operation_SetB_.*$" + name: Provisioning tests + runs-on: runs-on,runner=8cpu-linux-x64,image=legacy-cgroups-for-x64,run-id=${{ github.run_id }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: testdata + run: mkdir -p build/testdata + - name: Install Dapper + run: | + curl -sL https://releases.rancher.com/dapper/latest/dapper-$(uname -s)-$(uname -m) > ./.dapper + chmod +x ./.dapper + - name: Run tests + run: ./.dapper provisioning-tests + env: + DRONE_BUILD_EVENT: "${{ github.event_name }}" + V2PROV_TEST_RUN_REGEX: "${{ matrix.V2PROV_TEST_RUN_REGEX }}" + V2PROV_TEST_DIST: "${{ matrix.V2PROV_TEST_DIST }}" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/pull-request.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/pull-request.yml new file mode 100644 index 0000000..9a783a4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/pull-request.yml @@ -0,0 +1,202 @@ +name: Build Pull Request +on: + - pull_request +env: + ARCH: amd64 + TAG: v2.9-${{ github.sha }} + GIT_TAG: v2.9-${{ github.sha }} + HEAD_TAG: v2.9-${{ github.sha }} + COMMIT: ${{ github.sha }} + REPOSITORY_OWNER: ${{ github.repository_owner }} + IMAGE: ${{ github.repository_owner }}/rancher + IMAGE_AGENT: ${{ github.repository_owner }}/rancher-agent + IMAGE_INSTALLER: ${{ github.repository_owner }}/system-agent-installer-rancher +jobs: + unit-tests: + uses: ./.github/workflows/unit-test.yml + build-chart: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Install dependencies + env: + HELM_URL: https://get.helm.sh/helm-${{ steps.env.outputs.HELM_VERSION }}-linux-amd64.tar.gz + run: | + sudo snap install yq + curl ${{ env.HELM_URL }} | tar xvzf - --strip-components=1 -C /tmp/ && \ + sudo mv /tmp/helm /usr/bin/helm_v3 && \ + sudo chmod +x /usr/bin/helm_v3 + helm_v3 plugin install https://github.com/helm-unittest/helm-unittest.git --version ${{ steps.env.outputs.HELM_UNITTEST_VERSION }}; \ + - name: Build + run: ./scripts/chart/build chart + - name: Validate + run: ./scripts/chart/validate + - name: Test + run: ./scripts/chart/test + - name: Package + run: ./scripts/chart/package + build-server: + runs-on: ubuntu-latest + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + steps: + - name: Checkout code + uses: actions/checkout@v4 + # Cleaning the runner is important to free enough space to build rancher, otherwise the build will fail + - name: Clean runner + run: | + # removes dotnet + sudo rm -rf /usr/share/dotnet + # removes haskell + sudo rm -rf /opt/ghc + # removes android sdk + sudo rm -rf /usr/local/lib/android + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + flavor: | + latest=false + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Create k3s images file + uses: ./.github/actions/k3s-images + with: + k3s_version: ${{ steps.env.outputs.CATTLE_K3S_VERSION }} + - name: Download data.json + run: curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${{ steps.env.outputs.CATTLE_KDM_BRANCH }}/data.json > ./data.json + - name: Build and export server + id: build + uses: docker/build-push-action@v5 + with: + push: false + build-args: | + "VERSION=${{ env.TAG }}" + "COMMIT=${{ github.SHA }}" + "RKE_VERSION=${{ steps.env.outputs.RKE_VERSION }}" + "ARCH=${{ matrix.arch }}" + "CATTLE_RANCHER_WEBHOOK_VERSION=${{ steps.env.outputs.CATTLE_RANCHER_WEBHOOK_VERSION }}" + "CATTLE_CSP_ADAPTER_MIN_VERSION=${{ steps.env.outputs.CATTLE_CSP_ADAPTER_MIN_VERSION }}" + "CATTLE_FLEET_VERSION=${{ steps.env.outputs.CATTLE_FLEET_VERSION }}" + tags: ${{ env.IMAGE }}:${{ env.TAG }}-${{ matrix.arch }} + context: . + platforms: "${{ matrix.os }}/${{ matrix.arch }}" + file: ./package/Dockerfile + labels: "${{ steps.meta.outputs.labels }}" + outputs: type=docker,dest=/tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar + - name: Upload image + uses: actions/upload-artifact@v4 + with: + name: "rancher-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar + if-no-files-found: error + retention-days: 1 + overwrite: false + build-agent: + needs: [build-server] + runs-on: ubuntu-latest + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: + - name: Checkout code + uses: actions/checkout@v4 + # Cleaning the runner is important to free enough space to build rancher, otherwise the build will fail + - name: Clean runner + run: | + # removes dotnet + sudo rm -rf /usr/share/dotnet + # removes haskell + sudo rm -rf /opt/ghc + # removes android sdk + sudo rm -rf /usr/local/lib/android + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + flavor: | + latest=false + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host + - name: Download rancher image + uses: actions/download-artifact@v4 + with: + name: "rancher-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp + - name: Load image + run: | + image_id=$(docker load --input /tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + docker tag "$image_id" localhost:5000/${{ env.IMAGE }}:${{ env.TAG }} + docker push localhost:5000/${{ env.IMAGE }}:${{ env.TAG }} + - name: Build agent + id: build + uses: docker/build-push-action@v5 + with: + push: ${{ github.event_name != 'pull_request' }} + build-args: | + "VERSION=${{ env.TAG }}" + "ARCH=${{ matrix.arch }}" + "RANCHER_TAG=${{ env.TAG }}" + "RANCHER_REPO=${{ env.REPOSITORY_OWNER }}" + "REGISTRY=localhost:5000" + "CATTLE_RANCHER_WEBHOOK_VERSION=${{ steps.env.outputs.CATTLE_RANCHER_WEBHOOK_VERSION }}" + tags: ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-${{ matrix.arch }} + context: . + platforms: "${{ matrix.os }}/${{ matrix.arch }}" + file: ./package/Dockerfile.agent + labels: "${{ steps.meta.outputs.labels }}" + outputs: type=docker,dest=/tmp/rancher-agent-${{ matrix.os }}-${{ matrix.arch }}.tar + - name: Upload image + uses: actions/upload-artifact@v4 + with: + name: "rancher-agent-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp/rancher-agent-${{ matrix.os }}-${{ matrix.arch }}.tar + if-no-files-found: error + retention-days: 1 + overwrite: false + integration-tests: + needs: [build-agent] + uses: ./.github/workflows/integration-tests.yml + with: + parent_run_id: ${{ github.run_id }} + build-agent-windows: + strategy: + matrix: + os: [windows] + version: [2019, 2022] + runs-on: ${{ matrix.os }}-${{ matrix.version }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Build Windows Agent Image + run: docker build -t ${{ env.IMAGE_AGENT }}:${{ env.TAG }} --build-arg VERSION=${{ env.COMMIT }} --build-arg SERVERCORE_VERSION=ltsc${{ matrix.version }} -f package/windows/Dockerfile.agent . diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/push-release.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/push-release.yml new file mode 100644 index 0000000..bdaec9c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/push-release.yml @@ -0,0 +1,593 @@ +name: build-docker-images +on: + push: + branches: + - "master" + - "release/v*" + tags: + - "v*" +env: + COMMIT: ${{ github.sha }} + REPOSITORY_OWNER: ${{ github.repository_owner }} + IMAGE: ${{ github.repository_owner }}/rancher + IMAGE_AGENT: ${{ github.repository_owner }}/rancher-agent + IMAGE_INSTALLER: ${{ github.repository_owner }}/system-agent-installer-rancher +jobs: + unit-tests: + uses: ./.github/workflows/unit-test.yml + build-chart: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Tag Env Variables + uses: ./.github/actions/setup-tag-env + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Install dependencies + env: + HELM_URL: https://get.helm.sh/helm-${{ steps.env.outputs.HELM_VERSION }}-linux-amd64.tar.gz + HELM_UNITTEST_VERSION: ${{ steps.env.outputs.HELM_UNITTEST_VERSION }} + run: | + sudo snap install yq + curl ${{ env.HELM_URL }} | tar xvzf - --strip-components=1 -C /tmp/ && \ + sudo mv /tmp/helm /usr/bin/helm_v3 && \ + sudo chmod +x /usr/bin/helm_v3 + helm_v3 plugin install https://github.com/helm-unittest/helm-unittest.git --version ${{ env.HELM_UNITTEST_VERSION }}; \ + - name: Build + run: ./scripts/chart/build chart + - name: Validate + run: ./scripts/chart/validate + - name: Test + run: ./scripts/chart/test + - name: Package + run: ./scripts/chart/package + - name: Upload chart + uses: actions/upload-artifact@v4 + with: + name: chart + path: ./bin/chart/* + if-no-files-found: error + retention-days: 1 + overwrite: true + publish-chart: + runs-on: ubuntu-latest + needs: [build-chart, push-images] + if: github.event_name == 'push' && contains(github.ref, 'tags/') # Only run on push + permissions: + contents: read + id-token: write + steps: + - name: Download chart + uses: actions/download-artifact@v4 + with: + name: chart + path: ${{ runner.temp }}/charts + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/google-auth/rancher/credentials token | GOOGLE_AUTH ; + - name: Authenticate with Google Cloud + uses: google-github-actions/auth@v2 + with: + credentials_json: ${{ env.GOOGLE_AUTH }} + - name: Upload + uses: google-github-actions/upload-cloud-storage@v2 + with: + destination: releases.rancher.com/server-charts + path: ${{ runner.temp }}/charts + parent: false + process_gcloudignore: false + predefinedAcl: publicRead + headers: |- + cache-control: public,no-cache,proxy-revalidate + build-server: + runs-on: ubuntu-latest + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + steps: + - name: Checkout code + uses: actions/checkout@v4 + # Cleaning the runner is important to free enough space to build rancher, otherwise the build will fail + - name: Clean runner + run: | + # removes dotnet + sudo rm -rf /usr/share/dotnet + # removes haskell + sudo rm -rf /opt/ghc + # removes android sdk + sudo rm -rf /usr/local/lib/android + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + flavor: | + latest=false + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Create k3s images file + uses: ./.github/actions/k3s-images + with: + k3s_version: ${{ steps.env.outputs.CATTLE_K3S_VERSION }} + - name: Download data.json + run: curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${{ steps.env.outputs.CATTLE_KDM_BRANCH }}/data.json > ./data.json + - name: Build and export server + id: build + uses: docker/build-push-action@v5 + with: + push: false + build-args: | + "VERSION=${{ env.TAG }}" + "COMMIT=${{ env.COMMIT }}" + "RKE_VERSION=${{ steps.env.outputs.RKE_VERSION }}" + "ARCH=${{ matrix.arch }}" + "CATTLE_RANCHER_WEBHOOK_VERSION=${{ steps.env.outputs.CATTLE_RANCHER_WEBHOOK_VERSION }}" + "CATTLE_CSP_ADAPTER_MIN_VERSION=${{ steps.env.outputs.CATTLE_CSP_ADAPTER_MIN_VERSION }}" + "CATTLE_FLEET_VERSION=${{ steps.env.outputs.CATTLE_FLEET_VERSION }}" + tags: ${{ env.IMAGE }}:${{ env.TAG }}-${{ matrix.arch }} + context: . + platforms: "${{ matrix.os }}/${{ matrix.arch }}" + file: ./package/Dockerfile + labels: "${{ steps.meta.outputs.labels }}" + outputs: type=docker,dest=/tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar + - name: Upload image + uses: actions/upload-artifact@v4 + with: + name: "rancher-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar + if-no-files-found: error + retention-days: 1 + overwrite: false + build-agent: + needs: [build-server] + runs-on: ubuntu-latest + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + services: + registry: + image: registry:2 + ports: + - 5000:5000 + env: + REGISTRY: "127.0.0.1:5000" + steps: + # Cleaning the runner is important to free enough space to build rancher, otherwise the build will fail + - name: Clean runner + run: | + # removes dotnet + sudo rm -rf /usr/share/dotnet + # removes haskell + sudo rm -rf /opt/ghc + # removes android sdk + sudo rm -rf /usr/local/lib/android + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + run: | + echo "ARCH=${{ matrix.arch }}" >> "$GITHUB_ENV" + source scripts/export-config + echo "CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION" >> "$GITHUB_ENV" + - name: Setup TAG Variables + uses: ./.github/actions/setup-tag-env + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + flavor: | + latest=false + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host + - name: Download rancher image + uses: actions/download-artifact@v4 + with: + name: "rancher-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp + - name: Load image + run: | + image_id=$(docker load --input /tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + docker tag "$image_id" ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.TAG }} + docker push ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.TAG }} + - name: Build agent + id: build + uses: docker/build-push-action@v5 + with: + push: false + build-args: | + "VERSION=${{ env.TAG }}" + "ARCH=${{ matrix.arch }}" + "RANCHER_TAG=${{ env.TAG }}" + "RANCHER_REPO=${{ env.REPOSITORY_OWNER }}" + "REGISTRY=${{ env.REGISTRY }}" + "CATTLE_RANCHER_WEBHOOK_VERSION=${{ env.CATTLE_RANCHER_WEBHOOK_VERSION }}" + tags: ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-${{ matrix.arch }} + context: . + platforms: "${{ matrix.os }}/${{ matrix.arch }}" + file: ./package/Dockerfile.agent + labels: "${{ steps.meta.outputs.labels }}" + outputs: type=docker,dest=/tmp/rancher-agent-${{ matrix.os }}-${{ matrix.arch }}.tar + - name: Upload image + uses: actions/upload-artifact@v4 + with: + name: "rancher-agent-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp/rancher-agent-${{ matrix.os }}-${{ matrix.arch }}.tar + if-no-files-found: error + retention-days: 1 + overwrite: false + integration-tests: + needs: [build-agent] + uses: ./.github/workflows/integration-tests.yml + with: + parent_run_id: ${{ github.run_id }} + build-agent-windows: + needs: [integration-tests] + strategy: + matrix: + os: [windows] + version: [2019, 2022] + runs-on: ${{ matrix.os }}-${{ matrix.version }} + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Build Windows Server Image + run: | + docker build -t ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-${{ matrix.version }} --build-arg VERSION=${{ env.TAG }} --build-arg SERVERCORE_VERSION=ltsc${{ matrix.version }} -f package/windows/Dockerfile.agent . + docker push ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-${{ matrix.version }} + shell: bash + push-images: + runs-on: ubuntu-latest + needs: [unit-tests, integration-tests] + permissions: + contents: read + id-token: write + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Download rancher image + uses: actions/download-artifact@v4 + with: + pattern: "*-${{ matrix.os }}-${{ matrix.arch }}" + path: /tmp + merge-multiple: true + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Docker Registry Login + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Push server image + run: | + image_id=$(docker load --input /tmp/rancher-${{ matrix.os }}-${{ matrix.arch }}.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + docker tag "$image_id" docker.io/${{ env.IMAGE }}:${{ env.TAG }}-${{ matrix.arch }} + docker push docker.io/${{ env.IMAGE }}:${{ env.TAG }}-${{ matrix.arch }} + - name: Push agent image + run: | + image_agent_id=$(docker load --input /tmp/rancher-agent-${{ matrix.os }}-${{ matrix.arch }}.tar 2>&1 | grep "Loaded image" | awk '{print $NF}') + if [ -z "$image_agent_id" ]; then + echo "Error: Failed to load image from tarball!" + exit 1 + fi + docker tag "$image_agent_id" docker.io/${{ env.IMAGE_AGENT }}:${{ env.TAG }}-${{ matrix.arch }} + docker push docker.io/${{ env.IMAGE_AGENT }}:${{ env.TAG }}-${{ matrix.arch }} + merge-server-manifest: + runs-on: ubuntu-latest + needs: [push-images] + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Create manifest list and push + run: | + docker buildx imagetools create -t ${{ env.IMAGE }}:${{ env.TAG }} ${{ env.IMAGE }}:${{ env.TAG }}-amd64 ${{ env.IMAGE }}:${{ env.TAG }}-arm64 + - name: Create head manifest list and push + run: | + if [[ "${{ github.ref_name }}" == release/v* ]]; then + docker buildx imagetools create -t ${{ env.IMAGE }}:${{ env.HEAD_TAG }} ${{ env.IMAGE }}:${{ env.TAG }}-amd64 ${{ env.IMAGE }}:${{ env.TAG }}-arm64 + fi + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.IMAGE }}:${{ env.TAG }} + merge-agent-manifest: + runs-on: ubuntu-latest + needs: [push-images, build-agent-windows] + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Create manifest list and push + run: | + # docker manifest is used with windows images to maintain os.version in the manifest + docker manifest create ${{ env.IMAGE_AGENT }}:${{ env.TAG }} \ + ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-2019 \ + ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-2022 + + docker manifest push ${{ env.IMAGE_AGENT }}:${{ env.TAG }} + + docker buildx imagetools create -t ${{ env.IMAGE_AGENT }}:${{ env.TAG }} \ + --append ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-amd64 \ + --append ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-arm64 + + if [[ "${{ github.ref_name }}" == release/v* ]]; then + docker manifest create ${{ env.IMAGE_AGENT }}:${{ env.HEAD_TAG }} \ + ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-2019 \ + ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-windows-2022 + docker manifest push ${{ env.IMAGE_AGENT }}:${{ env.HEAD_TAG }} + + docker buildx imagetools create -t ${{ env.IMAGE_AGENT }}:${{ env.HEAD_TAG }} \ + --append ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-amd64 \ + --append ${{ env.IMAGE_AGENT }}:${{ env.TAG }}-arm64 + fi + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.IMAGE_AGENT }}:${{ env.TAG }} + build-installer: + needs: + - merge-server-manifest + - build-chart + runs-on: ubuntu-latest + strategy: + matrix: + os: [linux] + arch: [amd64, arm64] + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Setup New Environment Variables + run: | + echo "ARCH=${{ matrix.arch }}" >> "$GITHUB_ENV" + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE }} + flavor: | + latest=false + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Docker Registry Login + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Download chart + uses: actions/download-artifact@v4 + with: + name: chart + path: ./chart + - name: Build and export agent + id: build + uses: docker/build-push-action@v5 + with: + push: true + build-args: | + "VERSION=${{ env.TAG }}" + "ARCH=${{ matrix.arch }}" + "RANCHER_TAG=${{ env.TAG }}" + "RANCHER_REPO=${{ env.REPOSITORY_OWNER }}" + tags: ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }}-${{ matrix.arch }} + context: . + platforms: "${{ matrix.os }}/${{ matrix.arch }}" + file: ./package/Dockerfile.installer + labels: "${{ steps.meta.outputs.labels }}" + merge-installer-manifest: + runs-on: ubuntu-latest + needs: [build-installer] + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_INSTALLER }} + flavor: | + latest=false + - name: Load Secrets from Vault + uses: rancher-eio/read-vault-secrets@main + with: + secrets: | + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials username | DOCKER_USERNAME ; + secret/data/github/repo/${{ github.repository }}/dockerhub/rancher/credentials password | DOCKER_PASSWORD + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ env.DOCKER_PASSWORD }} + - name: Create manifest list and push + run: | + docker buildx imagetools create -t ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }} ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }}-amd64 ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }}-arm64 + if [[ "${{ github.ref_name }}" == release/v* ]]; then + docker buildx imagetools create -t ${{ env.IMAGE_INSTALLER }}:${{ env.HEAD_TAG }} ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }}-amd64 ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }}-arm64 + fi + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.IMAGE_INSTALLER }}:${{ env.TAG }} + create-images-files: + if: github.event_name == 'push' && contains(github.ref, 'tags/') # Only run on push + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - id: env + name: Setup Dependencies Env Variables + uses: ./.github/actions/setup-build-env + - name: Download data.json + run: | + mkdir -p bin + curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${{ steps.env.outputs.CATTLE_KDM_BRANCH }}/data.json > ./bin/data.json + - name: Create files + run: | + mkdir -p $HOME/bin + touch $HOME/bin/rancher-rke-k8s-versions.txt + - name: Create components and images files + shell: bash + run: ./scripts/create-components-images-files.sh + - name: Move files + run: | + mv $HOME/bin/* ./dist + mv ./bin/*.txt ./dist + mv ./bin/*.sh ./dist + mv ./bin/*.ps1 ./dist + - name: Create sha256sum.txt file + run: bash ./scripts/artifacts-hashes.sh + - name: Upload artifacts + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload -R ${{ env.REPOSITORY_OWNER }}/rancher ${{ env.TAG }} ./dist/* --clobber + - name: Add release notes + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + NOTES=$(cat ./dist/rancher-components.txt) + gh release edit -R ${{ github.repository }} ${{ env.TAG }} --notes "$NOTES" + docker-image-digests: + if: github.event_name == 'push' && contains(github.ref, 'tags/') # Only run on tag + runs-on: ubuntu-latest + needs: [create-images-files] + env: + DOCKER_REGISTRY: "docker.io" + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Environment Variables + uses: ./.github/actions/setup-tag-env + - name: Create dist folder + run: mkdir -p dist + - name: Setup ecm-distro-tools + uses: rancher/ecm-distro-tools@v0.38.1 + with: + version: v0.38.1 + - name: Create ECM Config + run: | + mkdir -p ~/.ecm-distro-tools + release config gen + mkdir -p /tmp/digests + - name: Generate Linux Digests + run: | + export LINUX_IMAGES_URL=https://github.com/${{ github.repository }}/releases/download/${{ env.TAG}}/rancher-images.txt + release generate rancher docker-images-digests \ + --images-url "$LINUX_IMAGES_URL" \ + --output-file /tmp/digests/rancher-images-digests-linux-amd64.txt \ + --registry ${{ env.DOCKER_REGISTRY }} + cp /tmp/digests/rancher-images-digests-linux-amd64.txt /tmp/digests/rancher-images-digests-linux-arm64.txt + - name: Generate Windows Digests + run: | + export WINDOWS_IMAGES_URL=https://github.com/${{ github.repository }}/releases/download/${{ env.TAG}}/rancher-windows-images.txt + release generate rancher docker-images-digests \ + --images-url "$WINDOWS_IMAGES_URL" \ + --output-file /tmp/digests/rancher-images-digests-windows-ltsc2019.txt \ + --registry ${{ env.DOCKER_REGISTRY }} + cp /tmp/digests/rancher-images-digests-windows-ltsc2019.txt /tmp/digests/rancher-images-digests-windows-ltsc2022.txt + - name: Upload digests + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload -R ${{ env.REPOSITORY_OWNER }}/rancher ${{ env.TAG }} /tmp/digests/* --clobber diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/renovate.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/renovate.yml new file mode 100644 index 0000000..abade6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/renovate.yml @@ -0,0 +1,25 @@ +name: Renovate +on: + workflow_dispatch: + inputs: + logLevel: + description: "Override default log level" + required: false + default: "info" + type: string + overrideSchedule: + description: "Override all schedules" + required: false + default: "false" + type: string + # Run twice in the early morning (UTC) for initial and follow up steps (create pull request and merge) + schedule: + - cron: '30 4,6 * * *' + +jobs: + call-workflow: + uses: rancher/renovate-config/.github/workflows/renovate.yml@release + with: + logLevel: ${{ inputs.logLevel || 'info' }} + overrideSchedule: ${{ github.event.inputs.overrideSchedule == 'true' && '{''schedule'':null}' || '' }} + secrets: inherit diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/replace-env-value.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/replace-env-value.yml new file mode 100644 index 0000000..0495067 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/replace-env-value.yml @@ -0,0 +1,84 @@ +name: Replace environment variable in file +on: + workflow_dispatch: + inputs: + filepath: + type: string + description: "What file needs to be edited?" + envvar: + type: string + description: "What environment variable needs to be edited?" + envvalue: + type: string + description: "What environment variable value needs to be used?" +permissions: + contents: write + pull-requests: write + +env: + INPUT_FILEPATH: ${{ github.event.inputs.filepath }} + INPUT_ENVVAR: ${{ github.event.inputs.envvar }} + INPUT_ENVVALUE: ${{ github.event.inputs.envvalue }} + +jobs: + tag: + name: Replace environment variable in file + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v2 + - name: Replace tags + run: | + bash ./scripts/replace-env-value-in-file.sh ${INPUT_FILEPATH} ${INPUT_ENVVAR} ${INPUT_ENVVALUE} + - name: Check for repository changes + run: | + if git diff --name-only --exit-code; then + echo "No changes found in repository" + echo "changes_exist=false" >> $GITHUB_ENV + else + echo "Changes found in repository" + git diff --name-only + echo "changes_exist=true" >> $GITHUB_ENV + fi + - name: Create branch, commit and push + if: ${{ env.changes_exist == 'true' }} + id: branch + run: | + BRANCH="githubaction-replace-envvar-$(date +%Y-%m-%d-%H-%M-%S)" + echo "::set-output name=branch::$BRANCH" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git checkout -b "$BRANCH" + git commit -a -m "change env var ${INPUT_ENVVAR} to ${INPUT_ENVVALUE} [CI SKIP]" + git push origin "$BRANCH" + - name: Create Pull Request + if: ${{ env.changes_exist == 'true' }} + id: cpr + uses: actions/github-script@v5.0.0 + env: + SOURCE_BRANCH: ${{ steps.branch.outputs.branch }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { INPUT_ENVVAR, INPUT_ENVVALUE } = process.env + + const { data: pr } = await github.rest.pulls.create({ + title: `[${{ github.ref_name }}] change env var ${INPUT_ENVVAR} to ${INPUT_ENVVALUE}`, + body: 'Auto-generated by GitHub Actions', + owner: context.repo.owner, + repo: context.repo.repo, + base: "${{ github.ref_name }}", + head: `${ process.env.SOURCE_BRANCH }` + }); + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pr.number, + labels: ["status/auto-created"], + }); + console.log('Created new pull request'); + return pr.html_url; + - name: Check outputs + if: ${{ env.changes_exist == 'true' }} + run: | + echo "Pull Request URL - ${{ steps.cpr.outputs.result }}" + echo "::notice file=.github,line=1,col=1::Pull Request URL - ${{ steps.cpr.outputs.result }}" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/stale.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/stale.yml new file mode 100644 index 0000000..a9cdbc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '30 1 * * *' + +permissions: + issues: write + pull-requests: write + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v4 + with: + stale-issue-message: 'This repository uses an automated workflow to automatically label issues which have not had any activity (commit/comment/label) for 60 days. This helps us manage the community issues better. If the issue is still relevant, please add a comment to the issue so the workflow can remove the label and we know it is still valid. If it is no longer relevant (or possibly fixed in the latest release), the workflow will automatically close the issue in 14 days. Thank you for your contributions.' + stale-pr-message: 'This repository uses an automated workflow to automatically label pull requests which have not had any activity (commit/comment/label) for 60 days. This helps us manage the community pull requests better. If the pull request is still relevant, please add a comment to the pull request so the workflow can remove the label and we know it is still valid. If it is no longer relevant (or possibly fixed in the latest release), the workflow will automatically close the pull request in 14 days. Thank you for your contributions.' + stale-issue-label: 'status/stale' + stale-pr-label: 'status/stale' + days-before-stale: 60 + days-before-close: 14 + exempt-issue-labels: 'internal,kind/bug,kind/bug-qa,kind/task,kind/feature,kind/design,kind/ci-improvements,kind/performance,kind/flaky-test,kind/tech-debt' + exempt-pr-labels: 'internal,kind/bug,kind/bug-qa,kind/task,kind/feature,kind/design,kind/ci-improvements,kind/performance,kind/flaky-test,kind/tech-debt' + exempt-all-milestones: true + exempt-all-assignees: true + operations-per-run: 2500 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/unit-test.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/unit-test.yml new file mode 100644 index 0000000..a1949da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/unit-test.yml @@ -0,0 +1,13 @@ +name: Unit Tests +on: [workflow_dispatch, workflow_call] +jobs: + unit-test: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run unit tests + run: go test -cover -tags=test ./pkg/... + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/update-readme.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/update-readme.yml new file mode 100644 index 0000000..017833d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/update-readme.yml @@ -0,0 +1,96 @@ +name: Update README +on: workflow_dispatch + +permissions: + contents: write + pull-requests: write + +jobs: + update-readme: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get chart index.yaml files + run: | + wget https://github.com/mikefarah/yq/releases/download/v4.25.1/yq_linux_amd64 -O /usr/bin/yq && chmod +x /usr/bin/yq + wget -O latest.index.yaml https://releases.rancher.com/server-charts/latest/index.yaml + wget -O stable.index.yaml https://releases.rancher.com/server-charts/stable/index.yaml + - name: Update README file + run: | + tmpfile=$(mktemp) + unset latest + unset stable + for rancher_major_minor in 2.8 2.7 2.6; do + latest2x=$(yq ".entries.rancher[].appVersion | select(test(\"^v${rancher_major_minor}\") and select(. != \"*-rc*\"))" 'latest.index.yaml' | head -1) + stable2x=$(yq ".entries.rancher[].appVersion | select(test(\"^v${rancher_major_minor}\") and select(. != \"*-rc*\"))" 'stable.index.yaml' | head -1) + [[ -z ${latest2x} ]] && [[ -z ${stable2x} ]] && continue + echo "* v${rancher_major_minor}" >> $tmpfile + if [[ -n ${latest2x} ]]; then + if [[ -n ${latest} ]]; then + echo " * Latest - ${latest2x} - \`rancher/rancher:${latest2x}\` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/${latest2x})." >> $tmpfile + else + echo " * Latest - ${latest2x} - \`rancher/rancher:${latest2x}\` / \`rancher/rancher:latest\` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/${latest2x})." >> $tmpfile + fi + fi + if [[ -n ${stable2x} ]]; then + if [[ -n ${stable} ]]; then + echo " * Stable - ${stable2x} - \`rancher/rancher:${stable2x}\` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/${stable2x})." >> $tmpfile + else + echo " * Stable - ${stable2x} - \`rancher/rancher:${stable2x}\` / \`rancher/rancher:stable\` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/${stable2x})." >> $tmpfile + fi + fi + latest=${latest2x} + stable=${stable2x} + done + sed -e '/## Latest Release/r '"$tmpfile"'' -e 's/CURRENTYEAR/'"$(date +%Y)"'/g' README-template.md > README.md + - name: Check for repository changes + run: | + if git diff --name-only --exit-code; then + echo "No changes found in repository after updating README" + echo "changes_exist=false" >> $GITHUB_ENV + else + echo "Changes found in repository after updating README:" + git diff --name-only + echo "changes_exist=true" >> $GITHUB_ENV + fi + - name: Create branch, commit and push + if: ${{ env.changes_exist == 'true' }} + id: branch + run: | + BRANCH="githubaction-update-readme-$(date +%Y-%m-%d-%H-%M-%S)" + echo "::set-output name=branch::$BRANCH" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --global user.name "github-actions[bot]" + git checkout -b "$BRANCH" + git commit -a -m "update README with latest/stable" + git push origin "$BRANCH" + - name: Create Pull Request + if: ${{ env.changes_exist == 'true' }} + id: cpr + env: + SOURCE_BRANCH: ${{ steps.branch.outputs.branch }} + uses: actions/github-script@v5.0.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + let body = 'Auto-generated by GitHub Actions' + + const { data: pr } = await github.rest.pulls.create({ + title: `[${{ github.ref_name }}] update README with latest/stable`, + body: body, + owner: context.repo.owner, + repo: context.repo.repo, + base: "${{ github.ref_name }}", + head: `${ process.env.SOURCE_BRANCH }` + }); + await github.rest.issues.addLabels({ + ...context.repo, + issue_number: pr.number, + labels: ["status/auto-created"], + }); + console.log('Created new pull request'); + return pr.html_url; + - name: Check outputs + if: ${{ env.changes_exist == 'true' }} + run: | + echo "Pull Request URL - ${{ steps.cpr.outputs.result }}" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/validate.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/validate.yml new file mode 100644 index 0000000..2bf957b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/validate.yml @@ -0,0 +1,40 @@ +name: Validate +on: [pull_request, push] +jobs: + validate: + runs-on: ubuntu-latest + env: + GOLANG_CI_LINT_VERSION: v1.54.2 + PYTHON_VERSION: '3.11' + GOLANG_VERSION: '1.22' + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Uninstall existing Python versions + run: | + sudo apt-get remove -y python3 + sudo apt-get autoremove -y + sudo apt-get purge -y python3 + sudo apt-get clean + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "${{ env.PYTHON_VERSION }}" + - name: Check Python version + run: | + sudo rm -rf /usr/bin/python3 + sudo cp $(which python3) /usr/bin/python3 + python3 --version + python3 -m ensurepip --upgrade + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "${{ env.GOLANG_VERSION }}" + - name: Install Python and dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3-pip python3-dev libffi-dev libssl-dev + sudo pip3 install --upgrade pip + sudo pip3 install tox flake8 + - name: Validate + run: ./scripts/validate diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/verify-generated-code-changes.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/verify-generated-code-changes.yml new file mode 100644 index 0000000..45d7afb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.github/workflows/verify-generated-code-changes.yml @@ -0,0 +1,46 @@ +name: Verify generated code changes + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'release/*' + +env: + MAIN_BRANCH: origin/master + GOARCH: amd64 + CGO_ENABLED: 0 + SETUP_GO_VERSION: '1.22.*' + +jobs: + check-changes: + runs-on: ubuntu-latest + + steps: + - + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - + uses: actions/setup-go@v4 + with: + go-version: ${{ env.SETUP_GO_VERSION }} + - + uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - + name: Verify go.mod status + run: ./.github/scripts/check-for-go-mod-changes.sh + - + name: Install controller-gen + run: go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 + - + name: Verify auto-generated changes + run: ./.github/scripts/check-for-auto-generated-changes.sh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitignore new file mode 100644 index 0000000..ef7ad72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.gitignore @@ -0,0 +1,39 @@ +vendor +/.dapper +/bin +/dist +/build +*.swp +/.idea +/cmd/agent/agent +/package/data.json +/package/k3s-airgap-images.tar +/package/rancher +/package/rancher-namespace.yaml +/package/rancher.yaml +/package/agent +/tests/MANIFEST +/tests/integration/MANIFEST +tests/integration/MANIFEST +tests/integration/.idea/ +/tests/.cache +/tests/.tox +/tests/integration/.tox/ +/tests/.venv +/tests/.idea +/default.etcd +*.pyc +__pycache__ +/management-state +/rancher +*.pytest_cache +.kube/ +.vscode/ +.DS_Store +tests/validation/.idea +all.yaml +kustomization.yaml +kontainer-engine +k3s-images.txt +k3s-airgap-images.tar +data.json diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.golangci.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.golangci.json new file mode 100644 index 0000000..27ebd5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/.golangci.json @@ -0,0 +1,83 @@ +{ + "linters": { + "disable-all": true, + "enable": [ + "govet", + "revive", + "goimports", + "misspell", + "ineffassign", + "gofmt" + ] + }, + "linters-settings": { + "govet": { + "check-shadowing": false + }, + "gofmt": { + "simplify": false + } + }, + "run": { + "skip-dirs": [ + "vendor", + "pkg/client", + "pkg/generated", + "tests/framework/clients/rancher/generated" + ], + "tests": false, + "timeout": "10m" + }, + "issues": { + "exclude-rules": [ + { + "linters": "govet", + "text": "^(nilness|structtag)" + }, + { + "path":"pkg/apis/management.cattle.io/v3/globaldns_types.go", + "text":".*lobalDns.*" + }, + { + "path": "pkg/apis/management.cattle.io/v3/zz_generated_register.go", + "text":".*lobalDns.*" + }, + { + "path":"pkg/apis/management.cattle.io/v3/zz_generated_list_types.go", + "text":".*lobalDns.*" + }, + { + "linters": "revive", + "text": "should have comment" + }, + { + "linters": "revive", + "text": "should be of the form" + }, + { + "linters": "typecheck", + "text": "imported but not used as apierrors" + }, + { + "linters": "revive", + "text": "unused-parameter" + }, + { + "linters": "revive", + "text": "redefines-builtin-id" + }, + { + "linters": "revive", + "text": "superfluous-else" + }, + { + "linters": "revive", + "text": "empty-block" + }, + { + "linters": "revive", + "text": "if-return: redundant if" + } + ] + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/CONTRIBUTING.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/CONTRIBUTING.md new file mode 100644 index 0000000..178d1b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing to Rancher + +Thanks for the interest to contribute to Rancher. Please see [Contributing to Rancher](https://ranchermanager.docs.rancher.com/contribute-to-rancher) to get started. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile-windows.dapper b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile-windows.dapper new file mode 100644 index 0000000..452c166 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile-windows.dapper @@ -0,0 +1,58 @@ +FROM library/golang:1.22 +SHELL ["powershell", "-NoLogo", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +ARG DAPPER_HOST_ARCH +ENV HOST_ARCH=${DAPPER_HOST_ARCH} ARCH=${DAPPER_HOST_ARCH} + +RUN pushd c:\; \ + $URL = 'https://github.com/StefanScherer/docker-cli-builder/releases/download/20.10.5/docker.exe'; \ + \ + Write-Host ('Downloading docker from {0} ...' -f $URL); \ + curl.exe -sfL $URL -o c:\Windows\docker.exe; \ + \ + Write-Host 'Complete.'; \ + popd; + +RUN pushd c:\; \ + $URL = 'https://github.com/golangci/golangci-lint/releases/download/v1.59.0/golangci-lint-1.59.0-windows-amd64.zip'; \ + \ + Write-Host ('Downloading golangci from {0} ...' -f $URL); \ + curl.exe -sfL $URL -o c:\golangci-lint.zip; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive -Path c:\golangci-lint.zip -DestinationPath c:\; \ + \ + Write-Host 'Cleaning ...'; \ + Remove-Item -Force -Recurse -Path c:\golangci-lint.zip; \ + \ + Write-Host 'Updating PATH ...'; \ + [Environment]::SetEnvironmentVariable('PATH', ('c:\golangci-lint-1.56.0-windows-amd64\;{0}' -f $env:PATH), [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Complete.'; \ + popd; + +# upgrade git +RUN pushd c:\; \ + $URL = 'https://github.com/git-for-windows/git/releases/download/v2.33.1.windows.1/MinGit-2.33.1-64-bit.zip'; \ + \ + Write-Host ('Downloading git from {0} ...' -f $URL); \ + curl.exe -sfL $URL -o c:\git.zip; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive -Force -Path c:\git.zip -DestinationPath c:\git\.; \ + \ + Write-Host 'Cleaning ...'; \ + Remove-Item -Force -Recurse -Path c:\git.zip; \ + \ + Write-Host 'Complete.'; \ + popd; + +ENV DAPPER_ENV REPO TAG DRONE_TAG FOSSA_API_KEY +ENV DAPPER_SOURCE /gopath/src/github.com/rancher/rancher +ENV DAPPER_OUTPUT ./bin +ENV DAPPER_DOCKER_SOCKET true +ENV HOME ${DAPPER_SOURCE} + +WORKDIR ${DAPPER_SOURCE} +ENTRYPOINT ["powershell", "-NoLogo", "-NonInteractive", "-File", "./scripts/windows/entry.ps1"] +CMD ["ci"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile.dapper b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile.dapper new file mode 100644 index 0000000..4887d18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Dockerfile.dapper @@ -0,0 +1,143 @@ +FROM registry.suse.com/bci/golang:1.22 + +ARG DAPPER_HOST_ARCH +ENV HOST_ARCH=${DAPPER_HOST_ARCH} ARCH=${DAPPER_HOST_ARCH} +ENV CATTLE_HELM_VERSION v2.16.8-rancher2 +ENV CATTLE_MACHINE_VERSION v0.15.0-rancher116 +ENV CATTLE_K3S_VERSION v1.30.2+k3s2 +# helm 3 version +ENV HELM_VERSION v3.15.2 +ENV KUSTOMIZE_VERSION v5.4.2 +ENV HELM_UNITTEST_VERSION 0.3.2 +# k3d ci version +ENV K3D_VERSION v5.7.1 + +# kontainer-driver-metadata branch to be set for specific branch other than dev/master, logic at rancher/rancher/pkg/settings/setting.go +ENV CATTLE_KDM_BRANCH=release-v2.9 + +RUN zypper -n install gcc binutils glibc-devel-static ca-certificates git-core wget curl unzip tar vim less file xz gzip sed gawk iproute2 iptables jq skopeo +# use containerd from k3s image, not from bci +RUN zypper install -y -f docker && rpm -e --nodeps --noscripts containerd + +# prevents `detected dubious ownership in repository` git error due to uid/gid not matching when using bind mounts +RUN git config -f /etc/gitconfig --add safe.directory /go/src/github.com/rancher/rancher + +RUN curl -sLf https://github.com/rancher/machine/releases/download/${CATTLE_MACHINE_VERSION}/rancher-machine-${ARCH}.tar.gz | tar xvzf - -C /usr/bin +RUN if [ "${ARCH}" != "s390x" ]; then \ + curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=${K3D_VERSION} bash; \ + fi + +ENV GOLANGCI_LINT v1.59.0 +RUN if [ "${ARCH}" == "amd64" ]; then \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s "${GOLANGCI_LINT}"; \ + curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/spectrometer/master/install.sh | sh; \ + fi + +# Tool for CRD generation. +ENV CONTROLLER_GEN_VERSION v0.14.0 +RUN go install sigs.k8s.io/controller-tools/cmd/controller-gen@${CONTROLLER_GEN_VERSION} + +# YAML processor for release configuration. +ENV YQ_VERSION v4.44.2 +RUN wget -q https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_${ARCH}.tar.gz -O - | tar xz && mv yq_linux_${ARCH} /usr/bin/yq + +ENV HELM_URL_V2_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm \ + HELM_URL_V2_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-arm64 \ + HELM_URL_V2_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-s390x \ + HELM_URL_V2=HELM_URL_V2_${ARCH} \ + HELM_URL_V3=https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz \ + TILLER_URL_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller \ + TILLER_URL_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-arm64 \ + TILLER_URL_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-s390x \ + TILLER_URL=TILLER_URL_${ARCH} \ + KUSTOMIZE_URL=https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz + +RUN curl -sLf ${KUSTOMIZE_URL} | tar -xzf - -C /usr/bin + +# set up helm 2 +RUN curl -sLf ${!HELM_URL_V2} -o /usr/bin/rancher-helm && \ + curl -sLf ${!TILLER_URL} -o /usr/bin/rancher-tiller && \ + chmod +x /usr/bin/rancher-helm /usr/bin/rancher-tiller && \ + ln -s /usr/bin/rancher-helm /usr/bin/helm && \ + ln -s /usr/bin/rancher-tiller /usr/bin/tiller && \ + helm init -c --stable-repo-url https://charts.helm.sh/stable/ + +# set up helm 3 +RUN mkdir /usr/tmp && \ + curl ${HELM_URL_V3} | tar xvzf - --strip-components=1 -C /usr/tmp/ && \ + mv /usr/tmp/helm /usr/bin/helm_v3 && \ + chmod +x /usr/bin/kustomize + +# Set up K3s: copy the necessary binaries from the K3s image. +COPY --from=rancher/k3s:v1.30.2-k3s2 \ + /bin/blkid \ + /bin/bandwidth \ + /bin/cni \ + /bin/conntrack \ + /bin/containerd \ + /bin/containerd-shim-runc-v2 \ + /bin/ethtool \ + /bin/firewall \ + /bin/ip \ + /bin/ipset \ + /bin/k3s \ + /bin/losetup \ + /bin/pigz \ + /bin/runc \ + /bin/which \ + /bin/aux/xtables-legacy-multi \ +/usr/bin/ + +RUN mkdir -p /go/src/github.com/rancher/rancher/.kube + +RUN ln -s /usr/bin/cni /usr/bin/bridge && \ + ln -s /usr/bin/cni /usr/bin/flannel && \ + ln -s /usr/bin/cni /usr/bin/host-local && \ + ln -s /usr/bin/cni /usr/bin/loopback && \ + ln -s /usr/bin/cni /usr/bin/portmap && \ + ln -s /usr/bin/k3s /usr/bin/crictl && \ + ln -s /usr/bin/k3s /usr/bin/ctr && \ + ln -s /usr/bin/k3s /usr/bin/k3s-agent && \ + ln -s /usr/bin/k3s /usr/bin/k3s-etcd-snapshot && \ + ln -s /usr/bin/k3s /usr/bin/k3s-server && \ + ln -s /usr/bin/k3s /usr/bin/kubectl && \ + ln -s /usr/bin/pigz /usr/bin/unpigz && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-translate && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-translate && \ + ln -s /etc/rancher/k3s/k3s.yaml /go/src/github.com/rancher/rancher/.kube/k3s.yaml + + +RUN curl -sLf https://github.com/rancher/k3s/releases/download/${CATTLE_K3S_VERSION}/k3s-images.txt -o /usr/tmp/k3s-images.txt + +# Python related dependencies for the Integration/Validation tests. +RUN zypper -n install python311-pip python311-base python311 python311-devel python311-tox libffi-devel libopenssl-devel + +ENV HELM_HOME /root/.helm +ENV DAPPER_ENV REPO TAG CI DRONE_BUILD_NUMBER DRONE_TAG DRONE_COMMIT DRONE_BRANCH DRONE_BUILD_EVENT SYSTEM_CHART_DEFAULT_BRANCH FOSSA_API_KEY GOGET_MODULE GOGET_VERSION RELEASE_ACTION RELEASE_TYPE POSTRELEASE_RANCHER_VERSION POSTRELEASE_RANCHER_STABLE DEBUG SOME_K8S_VERSION V2PROV_TEST_DIST V2PROV_TEST_RUN_REGEX V2PROV_DISTRO_DATA_DIR V2PROV_PROVISIONING_DATA_DIR V2PROV_SYSTEM_AGENT_DATA_DIR +ENV DAPPER_SOURCE /go/src/github.com/rancher/rancher/ +ENV DAPPER_OUTPUT ./bin ./dist ./go.mod ./go.sum ./pkg/apis/go.mod ./pkg/apis/go.sum ./pkg/client/go.mod ./pkg/client/go.sum ./scripts/package ./pkg/settings/setting.go ./package/Dockerfile ./Dockerfile.dapper ./pkg/crds/yaml/generated +ENV DAPPER_DOCKER_SOCKET true +ARG CI +ARG DRONE_BUILD_NUMBER +ENV DAPPER_RUN_ARGS "-v rancher2-go16-pkg-1:/go/pkg -v rancher2-go16-cache-1:/root/.cache/go-build --privileged --label CI=${CI} --label DRONE_BUILD_NUMBER=${DRONE_BUILD_NUMBER}" +ENV GOCACHE /root/.cache/go-build +ENV HOME ${DAPPER_SOURCE} + +# set up helm unittest - only needs to run on one arch. Needs to run after $HOME has been changed so we can find it later +RUN if [ "${ARCH}" == "amd64" ]; then \ + helm_v3 plugin install https://github.com/helm-unittest/helm-unittest.git --version ${HELM_UNITTEST_VERSION}; \ + fi + + +VOLUME /var/lib/rancher +VOLUME /var/lib/kubelet +WORKDIR ${DAPPER_SOURCE} + +ENTRYPOINT ["./scripts/entry"] +CMD ["ci"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/LICENSE b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/LICENSE new file mode 100644 index 0000000..e454a52 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/LICENSE @@ -0,0 +1,178 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Makefile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Makefile new file mode 100644 index 0000000..0286179 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/Makefile @@ -0,0 +1,23 @@ +TARGETS := $(shell ls scripts) +DEV_TARGETS := $(shell ls dev-scripts) + +.dapper: + @echo Downloading dapper + @curl -sL https://releases.rancher.com/dapper/latest/dapper-`uname -s`-`uname -m` > .dapper.tmp + @@chmod +x .dapper.tmp + @./.dapper.tmp -v + @mv .dapper.tmp .dapper + +$(TARGETS): .dapper + @if [ "$@" = "check-chart-kdm-source-values" ]; then \ + ./.dapper -q --no-out $@; \ + else \ + ./.dapper $@; \ + fi + +.DEFAULT_GOAL := ci + +$(DEV_TARGETS): + ./dev-scripts/$@ + +.PHONY: $(TARGETS) $(DEV_TARGETS) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README-template.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README-template.md new file mode 100644 index 0000000..7482f10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README-template.md @@ -0,0 +1,67 @@ +# Rancher + +*This file is auto-generated from README-template.md, please make any changes there.* + +[![Build Status](https://drone-publish.rancher.io/api/badges/rancher/rancher/status.svg?branch=release/v2.8)](https://drone-publish.rancher.io/rancher/rancher) +[![Docker Pulls](https://img.shields.io/docker/pulls/rancher/rancher.svg)](https://store.docker.com/community/images/rancher/rancher) +[![Go Report Card](https://goreportcard.com/badge/github.com/rancher/rancher)](https://goreportcard.com/report/github.com/rancher/rancher) + +Rancher is an open source container management platform built for organizations that deploy containers in production. Rancher makes it easy to run Kubernetes everywhere, meet IT requirements, and empower DevOps teams. + +## Latest Release + +To get automated notifications of our latest release, you can watch the announcements category in our [forums](http://forums.rancher.com/c/announcements), or subscribe to the RSS feed `https://forums.rancher.com/c/announcements.rss`. + +## Quick Start + + sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher + +Open your browser to https://localhost + +## Installation + +See [Installing/Upgrading Rancher](https://ranchermanager.docs.rancher.com/v2.8/pages-for-subheaders/installation-and-upgrade) for all installation options. + +### Minimum Requirements + +* Operating Systems + * Please see [Support Matrix](https://rancher.com/support-matrix/) for specific OS versions for each Rancher version. Note that the link will default to the support matrix for the latest version of Rancher. Use the left navigation menu to select a different Rancher version. +* Hardware & Software + * Please see [Installation Requirements](https://ranchermanager.docs.rancher.com/v2.8/pages-for-subheaders/installation-requirements) for hardware and software requirements. + +### Using Rancher + +To learn more about using Rancher, please refer to our [Rancher Documentation](https://ranchermanager.docs.rancher.com/v2.8). + +## Source Code + +This repo is a meta-repo used for packaging and contains the majority of Rancher codebase. For other Rancher projects and modules, [see go.mod](https://github.com/rancher/rancher/blob/release/v2.8/go.mod) for the full list. + +Rancher also includes other open source libraries and projects, [see go.mod](https://github.com/rancher/rancher/blob/release/v2.8/go.mod) for the full list. + +## Build configuration + +Refer to the [build docs](docs/build.md) on how to customize the building and packaging of Rancher. + +## Support, Discussion, and Community +If you need any help with Rancher, please join us at either our [Rancher forums](http://forums.rancher.com/) or [Slack](https://slack.rancher.io/) where most of our team hangs out at. + +Please submit any Rancher bugs, issues, and feature requests to [rancher/rancher](https://github.com/rancher/rancher/issues). + +For security issues, please first check our [security policy](SECURITY.md) and email security-rancher@suse.com instead of posting a public issue in GitHub. You may (but are not required to) use the GPG key located on [Keybase](https://keybase.io/rancher). + +# License + +Copyright (c) 2014-CURRENTYEAR [Rancher Labs, Inc.](http://rancher.com) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README.md new file mode 100644 index 0000000..bbaf7f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/README.md @@ -0,0 +1,76 @@ +# Rancher + +*This file is auto-generated from README-template.md, please make any changes there.* + +[![Build Status](https://drone-publish.rancher.io/api/badges/rancher/rancher/status.svg?branch=release/v2.8)](https://drone-publish.rancher.io/rancher/rancher) +[![Docker Pulls](https://img.shields.io/docker/pulls/rancher/rancher.svg)](https://store.docker.com/community/images/rancher/rancher) +[![Go Report Card](https://goreportcard.com/badge/github.com/rancher/rancher)](https://goreportcard.com/report/github.com/rancher/rancher) + +Rancher is an open source container management platform built for organizations that deploy containers in production. Rancher makes it easy to run Kubernetes everywhere, meet IT requirements, and empower DevOps teams. + +## Latest Release +* v2.8 + * Latest - v2.8.5 - `rancher/rancher:v2.8.5` / `rancher/rancher:latest` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.8.5). + * Stable - v2.8.5 - `rancher/rancher:v2.8.5` / `rancher/rancher:stable` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.8.5). +* v2.7 + * Latest - v2.7.10 - `rancher/rancher:v2.7.10` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.7.10). + * Stable - v2.7.10 - `rancher/rancher:v2.7.10` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.7.10). +* v2.6 + * Latest - v2.6.14 - `rancher/rancher:v2.6.14` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.6.14). + * Stable - v2.6.14 - `rancher/rancher:v2.6.14` - Read the full release [notes](https://github.com/rancher/rancher/releases/tag/v2.6.14). + +To get automated notifications of our latest release, you can watch the announcements category in our [forums](http://forums.rancher.com/c/announcements), or subscribe to the RSS feed `https://forums.rancher.com/c/announcements.rss`. + +## Quick Start + + sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher + +Open your browser to https://localhost + +## Installation + +See [Installing/Upgrading Rancher](https://ranchermanager.docs.rancher.com/v2.8/pages-for-subheaders/installation-and-upgrade) for all installation options. + +### Minimum Requirements + +* Operating Systems + * Please see [Support Matrix](https://rancher.com/support-matrix/) for specific OS versions for each Rancher version. Note that the link will default to the support matrix for the latest version of Rancher. Use the left navigation menu to select a different Rancher version. +* Hardware & Software + * Please see [Installation Requirements](https://ranchermanager.docs.rancher.com/v2.8/pages-for-subheaders/installation-requirements) for hardware and software requirements. + +### Using Rancher + +To learn more about using Rancher, please refer to our [Rancher Documentation](https://ranchermanager.docs.rancher.com/v2.8). + +## Source Code + +This repo is a meta-repo used for packaging and contains the majority of Rancher codebase. For other Rancher projects and modules, [see go.mod](https://github.com/rancher/rancher/blob/release/v2.8/go.mod) for the full list. + +Rancher also includes other open source libraries and projects, [see go.mod](https://github.com/rancher/rancher/blob/release/v2.8/go.mod) for the full list. + +## Build configuration + +Refer to the [build docs](docs/build.md) on how to customize the building and packaging of Rancher. + +## Support, Discussion, and Community +If you need any help with Rancher, please join us at either our [Rancher forums](http://forums.rancher.com/) or [Slack](https://slack.rancher.io/) where most of our team hangs out at. + +Please submit any Rancher bugs, issues, and feature requests to [rancher/rancher](https://github.com/rancher/rancher/issues). + +For security issues, please first check our [security policy](SECURITY.md) and email security-rancher@suse.com instead of posting a public issue in GitHub. You may (but are not required to) use the GPG key located on [Keybase](https://keybase.io/rancher). + +# License + +Copyright (c) 2014-2024 [Rancher Labs, Inc.](http://rancher.com) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/build.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/build.yaml new file mode 100644 index 0000000..a02b4fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/build.yaml @@ -0,0 +1,5 @@ +webhookVersion: 104.0.1+up0.5.1 +provisioningCAPIVersion: 104.0.0+up0.3.0 +cspAdapterMinVersion: 104.0.0+up4.0.0 +defaultShellVersion: rancher/shell:v0.2.1 +fleetVersion: 104.0.1+up0.10.1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/channels.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/channels.yaml new file mode 100644 index 0000000..67b9718 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/channels.yaml @@ -0,0 +1,10 @@ +channels: +- name: latest + latestRegexp: .* + excludeRegexp: ^[^+]+- +- name: testing + latestRegexp: .* +github: + owner: rancher + repo: rancher +redirectBase: https://github.com/rancher/rancher/releases/tag/ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/.helmignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/.helmignore new file mode 100644 index 0000000..2b29f27 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/.helmignore @@ -0,0 +1 @@ +tests diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/Chart.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/Chart.yaml new file mode 100644 index 0000000..67679f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: rancher +description: Install Rancher Server to manage Kubernetes clusters across providers. +version: %VERSION% +appVersion: %APP_VERSION% +kubeVersion: < 1.31.0-0 +home: https://rancher.com +icon: https://github.com/rancher/ui/blob/master/public/assets/images/logos/welcome-cow.svg +keywords: + - rancher +sources: + - https://github.com/rancher/rancher + - https://github.com/rancher/server-chart +maintainers: + - name: Rancher Labs + email: charts@rancher.com diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/README.md new file mode 100644 index 0000000..b0394b9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/README.md @@ -0,0 +1,208 @@ +By installing this application, you accept the [End User License Agreement & Terms & Conditions](https://www.suse.com/licensing/eula/). + +# Rancher + +***Rancher*** is open source software that combines everything an organization needs to adopt and run containers in production. Built on Kubernetes, Rancher makes it easy for DevOps teams to test, deploy and manage their applications. + +### Introduction + +This chart bootstraps a [Rancher Server](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster) on a Kubernetes cluster using the [Helm](https://helm.sh/) package manager. For a Rancher Supported Deployment please follow our [HA install instructions](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs). + + +### Prerequisites Details + +*For installations covered under [Rancher Support SLA](https://www.suse.com/suse-rancher/support-matrix/all-supported-versions) the target cluster must be **[RKE1](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke1-for-rancher)**, **[RKE2](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke2-for-rancher)**, **[K3s](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/k3s-for-rancher)**, **[AKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-aks)**, **[EKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-amazon-eks)**, or **[GKE](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-gke)**.* + +Make sure the node(s) for the Rancher server fulfill the following requirements: + +[Operating Systems and Container Runtime Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#operating-systems-and-container-runtime-requirements) +[Hardware Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#hardware-requirements) + +- [CPU and Memory](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#cpu-and-memory) +- [Ingress](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#ingress) +- [Disks](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#disks) + +[Networking Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#networking-requirements) +- [Node IP Addresses](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#node-ip-addresses) +- [Port Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#port-requirements) + +[Install the Required CLI Tools](https://ranchermanager.docs.rancher.com/pages-for-subheaders/cli-with-rancher) + +- [kubectl](https://ranchermanager.docs.rancher.com/reference-guides/cli-with-rancher/kubectl-utility) - Kubernetes command-line tool. +- [helm](https://docs.helm.sh/using_helm/#installing-helm) - Package management for Kubernetes. Refer to the [Helm version requirements](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/resources/helm-version-requirements) to choose a version of Helm to install Rancher. + +For a list of best practices that we recommend for running the Rancher server in production, refer to the [best practices section](https://ranchermanager.docs.rancher.com/pages-for-subheaders/best-practices). + +## Installing Rancher + +For production environments, we recommend installing Rancher in a [high-availability Kubernetes installation](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs) so that your user base can always access Rancher Server. When installed in a Kubernetes cluster, Rancher will integrate with the cluster’s etcd database and take advantage of Kubernetes scheduling for high-availability. + +Optional: Installing Rancher on a [Single-node](https://ranchermanager.docs.rancher.com/pages-for-subheaders/rancher-on-a-single-node-with-docker) Kubernetes Cluster + +#### Add the Helm Chart Repository + +Use [helm repo add](https://helm.sh/docs/helm/helm_repo_add/) command to add the Helm chart repository that contains charts to install Rancher. For more information about the repository choices and which is best for your use case, see Choosing a Version of Rancher. + +```bash +helm repo add rancher-latest https://releases.rancher.com/server-charts/latest +``` + +#### Create a Namespace for Rancher + +We’ll need to define a Kubernetes namespace where the resources created by the Chart should be installed. This should always be cattle-system: + +```bash +kubectl create namespace cattle-system +``` + +#### Choose your SSL Configuration + +The Rancher management server is designed to be secure by default and requires SSL/TLS configuration. + +There are three recommended options for the source of the certificate used for TLS termination at the Rancher server: + +- [Rancher-generated TLS certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Bring your own certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) + +#### Install cert-manager + +This step is only required to use certificates issued by Rancher’s generated CA **`(ingress.tls.source=rancher)`** or to request Let’s Encrypt issued certificates **`(ingress.tls.source=letsEncrypt)`**. + +[These instructions are adapted from the official cert-manager documentation.](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#4-install-cert-manager) + +#### Install Rancher with Helm and Your Chosen Certificate Option + +- [Rancher to generated certificates](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org +``` + +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=letsEncrypt \ + --set letsEncrypt.email=me@example.org +``` + +- [Certificates from Files](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret +``` + +*If you are using a Private CA signed certificate , add **--set privateCA=true** to the command:`* + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret \ + --set privateCA=true +``` + +#### Verify that the Rancher Server is Successfully Deployed + +After adding the secrets, check if Rancher was rolled out successfully: + +```bash +kubectl -n cattle-system rollout status deploy/rancher +Waiting for deployment "rancher" rollout to finish: 0 of 3 updated replicas are available... +deployment "rancher" successfully rolled out +``` + +If you see the following **`error: error: deployment "rancher" exceeded its progress deadline`**, you can check the status of the deployment by running the following command: + +```bash +kubectl -n cattle-system get deploy rancher +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +rancher 3 3 3 3 3m +``` + +It should show the same count for **`DESIRED`** and **`AVAILABLE`**. + +#### Save Your Options + +Make sure you save the **`--set`** options you used. You will need to use the same options when you upgrade Rancher to new versions with Helm. + +#### Finishing Up + +That’s it. You should have a functional Rancher server. + +In a web browser, go to the DNS name that forwards traffic to your load balancer. Then you should be greeted by the colorful login page. + +Doesn’t work? Take a look at the [Troubleshooting Page](https://ranchermanager.docs.rancher.com/troubleshooting/general-troubleshooting) + +***All of these instructions are defined in detailed in the [Rancher Documentation](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#install-the-rancher-helm-chart).*** + +### Helm Chart Options for Kubernetes Installations + +The full [Helm Chart Options](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options) can be found here. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +#### Common Options + +| Parameter | Default Value | Description | +| ------------------------- | ------------- | -------------------------------------------------------------------------------------------- | +| `hostname` | " " | ***string*** - the Fully Qualified Domain Name for your Rancher Server | +| `ingress.tls.source` | "rancher" | ***string*** - Where to get the cert for the ingress. - "***rancher, letsEncrypt, secret***" | +| `letsEncrypt.email` | " " | ***string*** - Your email address | +| `letsEncrypt.environment` | "production" | ***string*** - Valid options: "***staging, production***" | +| `privateCA` | false | ***bool*** - Set to true if your cert is signed by a private CA | + +#### Advanced Options + +| Parameter | Default Value | Description | +| ---------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `additionalTrustedCAs` | false | ***bool*** - [See Additional Trusted CAs Server](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options#additional-trusted-cas) | +| `addLocal` | "true" | ***string*** - As of Rancher v2.5.0 this flag is deprecated and must be set to "true" | +| `antiAffinity` | "preferred" | ***string*** - AntiAffinity rule for Rancher pods - *"preferred, required"* | +| `replicas` | 3 | ***int*** - Number of replicas of Rancher pods | +| `auditLog.destination` | "sidecar" | ***string*** - Stream to sidecar container console or hostPath volume - *"sidecar, hostPath"* | +| `auditLog.hostPath` | "/var/log/rancher/audit" | ***string*** - log file destination on host (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.level` | 0 | ***int*** - set the [API Audit Log level](https://ranchermanager.docs.rancher.com/how-to-guides/advanced-user-guides/enable-api-audit-log#audit-log-levels). 0 is off. [0-3] | +| `auditLog.maxAge` | 1 | ***int*** - maximum number of days to retain old audit log files (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxBackup` | 1 | int - maximum number of audit log files to retain (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxSize` | 100 | ***int*** - maximum size in megabytes of the audit log file before it gets rotated (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.image.repository` | "rancher/mirrored-bci-micro" | ***string*** - Location for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.tag` | "15.4.14.3" | ***string*** - Tag for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.pullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for auditLog images - *"Always", "Never", "IfNotPresent"* *Note: Available as of v2.7.0* | +| `busyboxImage` | "" | ***string*** - *Deprecated `auditlog.image.repository` should be used to control auditing sidecar image.* Image location for busybox image used to collect audit logs *Note: Available as of v2.2.0, and Deprecated as of v2.7.0* | +| `busyboxImagePullPolicy` | "IfNotPresent" | ***string*** - - *Deprecated `auditlog.image.pullPolicy` should be used to control auditing sidecar image.* Override imagePullPolicy for busybox images - *"Always", "Never", "IfNotPresent"* *Deprecated as of v2.7.0* | +| `debug` | false | ***bool*** - set debug flag on rancher server | +| `certmanager.version` | " " | ***string*** - set cert-manager compatibility | +| `extraEnv` | [] | ***list*** - set additional environment variables for Rancher Note: *Available as of v2.2.0* | +| `imagePullSecrets` | [] | ***list*** - list of names of Secret resource containing private registry credentials | +| `ingress.enabled` | true | ***bool*** - install ingress resource | +| `ingress.ingressClassName` | " " | ***string*** - class name of ingress if not set manually or by the ingress controller's defaults | +| `ingress.includeDefaultExtraAnnotations` | true | ***bool*** - Add default nginx annotations | +| `ingress.extraAnnotations` | {} | ***map*** - additional annotations to customize the ingress | +| `ingress.configurationSnippet` | " " | ***string*** - Add additional Nginx configuration. Can be used for proxy configuration. Note: *Available as of v2.0.15, v2.1.10 and v2.2.4* | +| `service.annotations` | {} | ***map*** - annotations to customize the service | +| `service.type` | " " | ***string*** - Override the type used for the service - *"NodePort", "LoadBalancer", "ClusterIP"* | +| `letsEncrypt.ingress.class` | " " | ***string*** - optional ingress class for the cert-manager acmesolver ingress that responds to the Let’s *Encrypt ACME challenges* | +| `proxy` | " " | ***string** - HTTP[S] proxy server for Rancher | +| `noProxy` | "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local" | ***string*** - comma separated list of hostnames or ip address not to use the proxy | +| `resources` | {} | ***map*** - rancher pod resource requests & limits | +| `rancherImage` | "rancher/rancher" | ***string*** - rancher image source | +| `rancherImageTag` | same as chart version | ***string*** - rancher/rancher image tag | +| `rancherImagePullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for rancher server images - *"Always", "Never", "IfNotPresent"* | +| `tls` | "ingress" | ***string*** - See External TLS Termination for details. - *"ingress, external"* | +| `systemDefaultRegistry` | "" | ***string*** - private registry to be used for all system Docker images, e.g., [http://registry.example.com/] *Available as of v2.3.0* | +| `useBundledSystemChart` | false | ***bool*** - select to use the system-charts packaged with Rancher server. This option is used for air gapped installations. *Available as of v2.3.0* | +| `customLogos.enabled` | false | ***bool*** - Enabled [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) and [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence volume | +| `customLogos.volumeSubpaths.emberUi` | "ember" | ***string*** - Volume subpath for [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) persistence | +| `customLogos.volumeSubpaths.vueUi` | "vue" | ***string*** - Volume subpath for [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence | +| `customLogos.volumeName` | "" | ***string*** - Use an existing volume. Custom logos should be copied to the proper `volume/subpath` folder by the user. Optional for persistentVolumeClaim, required for configMap | +| `customLogos.storageClass` | "" | ***string*** - Set custom logos persistentVolumeClaim storage class. Required for dynamic pv | +| `customLogos.accessMode` | "ReadWriteOnce" | ***string*** - Set custom persistentVolumeClaim access mode | +| `customLogos.size` | "1Gi" | ***string*** - Set custom persistentVolumeClaim size | diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/scripts/post-delete-hook.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/scripts/post-delete-hook.sh new file mode 100755 index 0000000..ad8d7a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/scripts/post-delete-hook.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -e + +namespaces="${NAMESPACES}" +rancher_namespace="${RANCHER_NAMESPACE}" +timeout="${TIMEOUT}" +ignoreTimeoutError="${IGNORETIMEOUTERROR}" + +if [[ -z ${namespaces} ]]; then + echo "No namespace is provided." + exit 1 +fi + +if [[ -z ${rancher_namespace} ]]; then + echo "No rancher namespace is provided." + exit 1 +fi + +if [[ -z ${timeout} ]]; then + echo "No timeout value is provided." + exit 1 +fi + +if [[ -z ${ignoreTimeoutError} ]]; then + echo "No ignoreTimeoutError value is provided." + exit 1 +fi + +succeeded=() +failed=() + +get_pod_count() { + kubectl get pods --selector app="${1}" -n "${2}" -o json | jq '.items | length' +} + +echo "Uninstalling Rancher resources in the following namespaces: ${namespaces}" + +for namespace in ${namespaces}; do + for app in $(helm list -n "${namespace}" -q); do + if [[ ${app} =~ .crd$ ]]; then + echo "--- Skip the app [${app}] in the namespace [${namespace}]" + continue + fi + echo "--- Deleting the app [${app}] in the namespace [${namespace}]" + if [[ ! $(helm uninstall "${app}" -n "${namespace}") ]]; then + failed=("${failed[@]}" "${app}") + continue + fi + + t=0 + while true; do + if [[ $(get_pod_count "${app}" "${namespace}") -eq 0 ]]; then + echo "successfully uninstalled [${app}] in the namespace [${namespace}]" + succeeded=("${succeeded[@]}" "${app}") + break + fi + if [[ ${t} -ge ${timeout} ]]; then + echo "timeout uninstalling [${app}] in the namespace [${namespace}]" + failed=("${failed[@]}" "${app}") + break + fi + # by default, wait 120 seconds in total for an app to be uninstalled + echo "waiting 5 seconds for pods of [${app}] to be terminated ..." + sleep 5 + t=$((t + 5)) + done + done + + # delete the helm operator pods + for pod in $(kubectl get pods -n "${namespace}" -o name); do + if [[ ${pod} =~ ^pod\/helm-operation-* ]]; then + echo "--- Deleting the pod [${pod}] in the namespace [${namespace}]" + kubectl delete "${pod}" -n "${namespace}" + fi + done +done + +echo "Removing Rancher bootstrap secret in the following namespace: ${rancher_namespace}" +kubectl --ignore-not-found=true delete secret bootstrap-secret -n "${rancher_namespace}" + +echo "------ Summary ------" +if [[ ${#succeeded[@]} -ne 0 ]]; then + echo "Succeeded to uninstall the following apps:" "${succeeded[@]}" +fi + +if [[ ${#failed[@]} -ne 0 ]]; then + echo "Failed to uninstall the following apps:" "${failed[@]}" + if [[ "${ignoreTimeoutError}" == "false" ]]; then + exit 2 + fi +else + echo "Cleanup finished successfully." +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/sdjo-test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/sdjo-test.yaml new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/NOTES.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/NOTES.txt new file mode 100644 index 0000000..5d9d1e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/NOTES.txt @@ -0,0 +1,22 @@ +Rancher Server has been installed. + +NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued, Containers are started and the Ingress rule comes up. + +Check out our docs at https://rancher.com/docs/ + +If you provided your own bootstrap password during installation, browse to https://{{ .Values.hostname }} to get started. + +If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates: + +``` +echo https://{{ .Values.hostname }}/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}') +``` + +To get just the bootstrap password on its own, run: + +``` +kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}{{ "{{" }} "\n" {{ "}}" }}' +``` + + +Happy Containering! diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/_helpers.tpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/_helpers.tpl new file mode 100644 index 0000000..1b5ad55 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/_helpers.tpl @@ -0,0 +1,76 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "rancher.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.fullname" -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified chart name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.chartname" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +# Render Values in configurationSnippet +{{- define "configurationSnippet" -}} + {{- tpl (.Values.ingress.configurationSnippet) . | nindent 6 -}} +{{- end -}} + +{{/* +Generate the labels. +*/}} +{{- define "rancher.labels" -}} +app: {{ template "rancher.fullname" . }} +chart: {{ template "rancher.chartname" . }} +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector-terms" -}} +{{- $key := "kubernetes.io/os" -}} +- matchExpressions: + - key: {{ $key }} + operator: NotIn + values: + - windows +{{- end -}} + +{{- define "system_default_registry" -}} +{{- if .Values.systemDefaultRegistry -}} + {{- if hasSuffix "/" .Values.systemDefaultRegistry -}} + {{- printf "%s" .Values.systemDefaultRegistry -}} + {{- else -}} + {{- printf "%s/" .Values.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/clusterRoleBinding.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/clusterRoleBinding.yaml new file mode 100644 index 0000000..aeb155d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/clusterRoleBinding.yaml @@ -0,0 +1,14 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +subjects: +- kind: ServiceAccount + name: {{ template "rancher.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/configMap.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/configMap.yaml new file mode 100644 index 0000000..76e3460 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/configMap.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rancher-config + labels: {{ include "rancher.labels" . | nindent 4 }} + app.kubernetes.io/part-of: "rancher" +data: + priorityClassName: {{ .Values.priorityClassName }} + {{- if and .Values.webhook (kindIs "string" .Values.webhook) }} + rancher-webhook: {{ .Values.webhook | quote }} + {{- else if .Values.webhook }} + rancher-webhook: {{ toYaml .Values.webhook | quote }} + {{- end }} + {{- if and .Values.fleet (kindIs "string" .Values.fleet) }} + fleet: {{ .Values.fleet | quote }} + {{- else if .Values.fleet }} + fleet: {{ toYaml .Values.fleet | quote }} + {{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/deployment.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/deployment.yaml new file mode 100644 index 0000000..06f9401 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/deployment.yaml @@ -0,0 +1,264 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ template "rancher.fullname" . }} + annotations: +{{- if (lt (int .Values.replicas) 0) }} + management.cattle.io/scale-available: "{{ sub 0 (int .Values.replicas)}}" +{{- end }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: +{{- if (gt (int .Values.replicas) 0) }} + replicas: {{ .Values.replicas }} +{{- end }} + selector: + matchLabels: + app: {{ template "rancher.fullname" . }} + strategy: + rollingUpdate: + maxSurge: 1 +{{- if (eq (int .Values.replicas) 1) }} + maxUnavailable: 0 +{{- else }} + maxUnavailable: 1 +{{- end }} + type: RollingUpdate + template: + metadata: + labels: + app: {{ template "rancher.fullname" . }} + release: {{ .Release.Name }} + spec: + priorityClassName: {{ .Values.priorityClassName }} + serviceAccountName: {{ template "rancher.fullname" . }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 6 }} +{{- end }} + affinity: + podAntiAffinity: +{{- if eq .Values.antiAffinity "required" }} + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- else }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- end }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: {{ include "linux-node-selector-terms" . | nindent 14 }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + containers: + - image: {{ .Values.rancherImage }}:{{ default .Chart.AppVersion .Values.rancherImageTag }} + imagePullPolicy: {{ default "IfNotPresent" .Values.rancherImagePullPolicy }} + name: {{ template "rancher.name" . }} + ports: + - containerPort: 80 + protocol: TCP +{{- if (and .Values.hostPort (gt (int .Values.hostPort) 0)) }} + - containerPort: 444 + hostPort: {{ int .Values.hostPort }} + protocol: TCP +{{- end}} + args: +{{- if .Values.debug }} + - "--debug" +{{- end }} +{{- if .Values.privateCA }} + # Private CA - don't clear ca certs +{{- else if and (eq .Values.tls "ingress") (eq .Values.ingress.tls.source "rancher") }} + # Rancher self-signed - don't clear ca certs +{{- else }} + # Public trusted CA - clear ca certs + - "--no-cacerts" +{{- end }} + - "--http-listen-port=80" + - "--https-listen-port=443" + - "--add-local={{ .Values.addLocal }}" + env: + - name: CATTLE_NAMESPACE + value: {{ .Release.Namespace }} + - name: CATTLE_PEER_SERVICE + value: {{ template "rancher.fullname" . }} +{{- if .Values.features }} + - name: CATTLE_FEATURES + value: "{{ .Values.features }}" +{{- end}} +{{- if .Values.noDefaultAdmin }} + - name: CATTLE_NO_DEFAULT_ADMIN + value: "{{ .Values.noDefaultAdmin }}" +{{- end}} +{{- if gt (int .Values.auditLog.level) 0 }} + - name: AUDIT_LEVEL + value: {{ .Values.auditLog.level | quote }} + - name: AUDIT_LOG_MAXAGE + value: {{ .Values.auditLog.maxAge | quote }} + - name: AUDIT_LOG_MAXBACKUP + value: {{ .Values.auditLog.maxBackup | quote }} + - name: AUDIT_LOG_MAXSIZE + value: {{ .Values.auditLog.maxSize | quote }} +{{- end }} +{{- if .Values.proxy }} + - name: HTTP_PROXY + value: {{ .Values.proxy }} + - name: HTTPS_PROXY + value: {{ .Values.proxy }} + - name: NO_PROXY + value: {{ .Values.noProxy }} +{{- end }} +{{- if .Values.systemDefaultRegistry }} + - name: CATTLE_SYSTEM_DEFAULT_REGISTRY + value: {{ .Values.systemDefaultRegistry }} +{{- end }} +{{- if .Values.useBundledSystemChart }} + - name: CATTLE_SYSTEM_CATALOG + value: bundled +{{- end }} +{{- if .Values.restrictedAdmin }} + - name: CATTLE_RESTRICTED_DEFAULT_ADMIN + value: "true" +{{- end}} +{{- if .Values.bootstrapPassword }} + - name: CATTLE_BOOTSTRAP_PASSWORD + valueFrom: + secretKeyRef: + name: "bootstrap-secret" + key: "bootstrapPassword" +{{- end }} +{{- if .Values.agentTLSMode }} + - name: CATTLE_AGENT_TLS_MODE + value: "{{ .Values.agentTLSMode }}" +{{- end }} +{{- if .Values.extraEnv }} +{{ toYaml .Values.extraEnv | indent 8}} +{{- end }} + startupProbe: + httpGet: + path: /healthz + port: 80 + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + livenessProbe: + httpGet: + path: /healthz + port: 80 + {{- with .Values.livenessProbe.initialDelaySeconds}} + initialDelaySeconds: {{ . }} + {{- end }} + timeoutSeconds: {{.Values.livenessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + failureThreshold: {{.Values.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: 80 + {{- with .Values.readinessProbe.initialDelaySeconds}} + initialDelaySeconds: {{ . }} + {{- end }} + timeoutSeconds: {{.Values.readinessProbe.timeoutSeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{.Values.readinessProbe.failureThreshold }} + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: +{{- if .Values.additionalTrustedCAs }} + - mountPath: /etc/pki/trust/anchors/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true + - mountPath: /etc/rancher/ssl/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true +{{- end }} +{{- if .Values.privateCA }} + # Pass CA cert into rancher for private CA + - mountPath: /etc/rancher/ssl/cacerts.pem + name: tls-ca-volume + subPath: cacerts.pem + readOnly: true +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + # Mount rancher custom-logos volume + - mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.emberUi | default "ember" | quote }} + - mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.vueUi | default "vue" | quote }} +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + - mountPath: /var/log/auditlog + name: audit-log +{{- end }} +{{- if eq .Values.auditLog.destination "sidecar" }} + {{- if gt (int .Values.auditLog.level) 0 }} + # Make audit logs available for Rancher log collector tools. + {{- if .Values.busyboxImage }} + - image: {{ .Values.busyboxImage}} + {{- else }} + - image: {{ .Values.auditLog.image.repository }}:{{.Values.auditLog.image.tag}} + {{- end }} + {{- if .Values.busyboxImagePullPolicy }} + imagePullPolicy: {{ .Values.busyboxImagePullPolicy }} + {{- else }} + imagePullPolicy: {{ .Values.auditLog.image.pullPolicy }} + {{- end }} + name: {{ template "rancher.name" . }}-audit-log + command: ["tail"] + args: ["-F", "/var/log/auditlog/rancher-api-audit.log"] + volumeMounts: + - mountPath: /var/log/auditlog + name: audit-log + {{- end }} +{{- end }} + volumes: +{{- if .Values.additionalTrustedCAs }} + - name: tls-ca-additional-volume + secret: + defaultMode: 0400 + secretName: tls-ca-additional +{{- end }} +{{- if .Values.privateCA }} + - name: tls-ca-volume + secret: + defaultMode: 0400 + secretName: tls-ca +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + {{- if eq .Values.auditLog.destination "hostPath" }} + - name: audit-log + hostPath: + path: {{ .Values.auditLog.hostPath }} + type: DirectoryOrCreate + {{- else }} + - name: audit-log + emptyDir: {} + {{- end }} +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + - name: custom-logos + {{- if (eq .Values.customLogos.volumeKind "persistentVolumeClaim") }} + persistentVolumeClaim: + claimName: {{ .Values.customLogos.volumeName | default (printf "%s-custom-logos" (include "rancher.fullname" .)) }} + {{- else if (eq .Values.customLogos.volumeKind "configMap") }} + configMap: + name: {{ .Values.customLogos.volumeName }} + {{- end }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/ingress.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/ingress.yaml new file mode 100644 index 0000000..16eb292 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/ingress.yaml @@ -0,0 +1,66 @@ +{{- if .Values.ingress.enabled }} +{{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} +apiVersion: networking.k8s.io/v1 +{{- else }} +apiVersion: networking.k8s.io/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} + annotations: +{{- if .Values.ingress.configurationSnippet }} + nginx.ingress.kubernetes.io/configuration-snippet: | + {{- template "configurationSnippet" . }} +{{- end }} +{{- if eq .Values.tls "external" }} + nginx.ingress.kubernetes.io/ssl-redirect: "false" # turn off ssl redirect for external. +{{- else }} + {{- if ne .Values.ingress.tls.source "secret" }} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + certmanager.k8s.io/issuer: {{ template "rancher.fullname" . }} + {{- else }} + cert-manager.io/issuer: {{ template "rancher.fullname" . }} + cert-manager.io/issuer-kind: Issuer + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.ingress.includeDefaultExtraAnnotations }} + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +{{- end }} +{{- if .Values.ingress.extraAnnotations }} +{{ toYaml .Values.ingress.extraAnnotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} + rules: + - host: {{ .Values.hostname }} # hostname to access rancher server + http: + paths: + - backend: + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + service: + name: {{ template "rancher.fullname" . }} + port: + number: {{ .Values.ingress.servicePort }} + {{- else }} + serviceName: {{ template "rancher.fullname" . }} + servicePort: {{ .Values.ingress.servicePort }} + {{- end }} + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + pathType: {{ .Values.ingress.pathType }} + path: {{ .Values.ingress.path }} + {{- end }} +{{- if eq .Values.tls "ingress" }} + tls: + - hosts: + - {{ .Values.hostname }} + secretName: {{ .Values.ingress.tls.secretName }} +{{- end }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-letsEncrypt.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-letsEncrypt.yaml new file mode 100644 index 0000000..ee0a7b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-letsEncrypt.yaml @@ -0,0 +1,37 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "letsEncrypt" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + acme: + {{- if eq .Values.letsEncrypt.environment "production" }} + server: https://acme-v02.api.letsencrypt.org/directory + {{- else }} + server: https://acme-staging-v02.api.letsencrypt.org/directory + {{- end }} + email: {{ .Values.letsEncrypt.email }} + privateKeySecretRef: + name: letsencrypt-{{ .Values.letsEncrypt.environment }} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + http01: {} + {{- else }} + solvers: + - http01: + ingress: + class: {{ .Values.letsEncrypt.ingress.class }} + {{- end }} + {{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-rancher.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-rancher.yaml new file mode 100644 index 0000000..9e24b38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/issuer-rancher.yaml @@ -0,0 +1,22 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "rancher" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + ca: + secretName: tls-rancher + {{- end -}} +{{- end -}} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role-binding.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role-binding.yaml new file mode 100644 index 0000000..476957b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role-binding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "rancher.fullname" . }}-post-delete +subjects: + - kind: ServiceAccount + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role.yaml new file mode 100644 index 0000000..4e6b7d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-cluster-role.yaml @@ -0,0 +1,39 @@ +{{- if .Values.postDelete.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +rules: + - apiGroups: [ "extensions","apps" ] + resources: [ "deployments" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "batch" ] + resources: [ "jobs" ] + verbs: [ "get", "list", "watch", "delete", "create" ] + - apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles", "clusterrolebindings", "roles", "rolebindings" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "" ] + resources: [ "pods", "secrets", "services", "configmaps" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "networking.k8s.io" ] + resources: [ "networkpolicies" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "admissionregistration.k8s.io" ] + resources: [ "validatingwebhookconfigurations", "mutatingwebhookconfigurations" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "networking.k8s.io" ] + resources: [ "ingresses" ] + verbs: [ "delete" ] + - apiGroups: [ "cert-manager.io" ] + resources: [ "issuers" ] + verbs: [ "delete" ] +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-config-map.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-config-map.yaml new file mode 100644 index 0000000..eb7b9e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-config-map.yaml @@ -0,0 +1,15 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +data: + post-delete-hook.sh: |- +{{ $.Files.Get "scripts/post-delete-hook.sh" | indent 4 }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-job.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-job.yaml new file mode 100644 index 0000000..d90ca80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-job.yaml @@ -0,0 +1,46 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 3 + template: + metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 8 }} + spec: + serviceAccountName: {{ template "rancher.fullname" . }}-post-delete + restartPolicy: OnFailure + containers: + - name: {{ template "rancher.name" . }}-post-delete + image: "{{ include "system_default_registry" . }}{{ .Values.postDelete.image.repository }}:{{ .Values.postDelete.image.tag }}" + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: 0 + command: + - /scripts/post-delete-hook.sh + volumeMounts: + - mountPath: /scripts + name: config-volume + env: + - name: NAMESPACES + value: {{ .Values.postDelete.namespaceList | join " " | quote }} + - name: RANCHER_NAMESPACE + value: {{ .Release.Namespace }} + - name: TIMEOUT + value: {{ .Values.postDelete.timeout | quote }} + - name: IGNORETIMEOUTERROR + value: {{ .Values.postDelete.ignoreTimeoutError | quote }} + volumes: + - name: config-volume + configMap: + name: {{ template "rancher.fullname" . }}-post-delete + defaultMode: 0777 +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-service-account.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-service-account.yaml new file mode 100644 index 0000000..923687d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/post-delete-hook-service-account.yaml @@ -0,0 +1,12 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/priorityClass.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/priorityClass.yaml new file mode 100644 index 0000000..5ef748a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/priorityClass.yaml @@ -0,0 +1,8 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: rancher-critical + labels: {{ include "rancher.labels" . | nindent 4 }} +value: 1000000000 +globalDefault: false +description: "Priority class used by pods critical to rancher's functionality." diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/pvc.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/pvc.yaml new file mode 100644 index 0000000..45e644f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/pvc.yaml @@ -0,0 +1,19 @@ +{{- if and (.Values.customLogos.enabled) (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (not .Values.customLogos.volumeName) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }}-custom-logos +spec: + accessModes: + - {{ .Values.customLogos.accessMode | quote }} + resources: + requests: + storage: {{ .Values.customLogos.size | quote }} + storageClassName: {{ if .Values.customLogos.storageClass }} + {{- if (eq "-" .Values.customLogos.storageClass) -}} + "" + {{- else }} + {{- .Values.customLogos.storageClass }} + {{- end -}} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/secret.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/secret.yaml new file mode 100644 index 0000000..fd476bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/secret.yaml @@ -0,0 +1,25 @@ +{{/* Use the bootstrap password from values.yaml if an existing secret is not found */}} +{{- $bootstrapPassword := .Values.bootstrapPassword -}} +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace "bootstrap-secret" -}} +{{- if $existingSecret -}} + {{- if $existingSecret.data -}} + {{- if $existingSecret.data.bootstrapPassword -}} + {{- $bootstrapPassword = $existingSecret.data.bootstrapPassword | b64dec -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{/* If a bootstrap password was found in the values or an existing password was found create the secret */}} +{{- if $bootstrapPassword }} +apiVersion: v1 +kind: Secret +metadata: + name: "bootstrap-secret" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-5" + "helm.sh/resource-policy": keep +type: Opaque +data: + bootstrapPassword: {{ $bootstrapPassword | b64enc | quote }} +{{- end }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/service.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/service.yaml new file mode 100644 index 0000000..2b2967b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + {{- /* + If service.type is not provided this attribute is ommitted and k8s default of ClusterIP is used. + */}} + {{- if .Values.service.type }} + type: {{ .Values.service.type }} + {{- end }} + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + targetPort: 444 + protocol: TCP + name: https-internal + selector: + app: {{ template "rancher.fullname" . }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/serviceAccount.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/serviceAccount.yaml new file mode 100644 index 0000000..84c0d29 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/templates/serviceAccount.yaml @@ -0,0 +1,6 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/README.md new file mode 100644 index 0000000..6d3059a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/README.md @@ -0,0 +1,16 @@ + +## local dev testing instructions + +Option 1: Full chart CI run with a live cluster + +```bash +./scripts/charts/ci +``` + +Option 2: Test runs against the chart only + +```bash +# install the helm plugin first - helm plugin install https://github.com/helm-unittest/helm-unittest.git +bash dev-scripts/helm-unittest.sh +``` + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/configmap_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/configmap_test.yaml new file mode 100644 index 0000000..953c941 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/configmap_test.yaml @@ -0,0 +1,116 @@ +suite: Test ConfigMap +templates: + - configMap.yaml + +tests: + - it: should set webhook value from string + set: + webhook: |- + hostNetwork: true + newKey: newValue + newlist: + - list1 + - list2 + - list3 + newMap: + entry1: 1 + entry2: 2 + entry3: + sub3: "sub" + asserts: + - equal: + path: data.rancher-webhook + value: |- + hostNetwork: true + newKey: newValue + newlist: + - list1 + - list2 + - list3 + newMap: + entry1: 1 + entry2: 2 + entry3: + sub3: "sub" + + - it: should set webhook value from map + set: + webhook.hostNetwork: true + webhook.newKey: 2 + webhook.innerMap: + foo: bar + asserts: + - equal: + path: data.rancher-webhook + value: |- + hostNetwork: true + innerMap: + foo: bar + newKey: 2 + + - it: should not set webhook values + asserts: + - notExists: + path: data.rancher-webhook + + - it: should set fleet values from string + set: + fleet: |- + newKey: newValue + newlist: + - list1 + - list2 + - list3 + newMap: + entry1: 1 + entry2: 2 + entry3: + sub3: "sub" + asserts: + - equal: + path: data.fleet + value: |- + newKey: newValue + newlist: + - list1 + - list2 + - list3 + newMap: + entry1: 1 + entry2: 2 + entry3: + sub3: "sub" + + - it: should set fleet values from map + set: + fleet.debug: true + fleet.newKey: 2 + fleet.innerMap: + foo: bar + asserts: + - equal: + path: data.fleet + value: |- + debug: true + innerMap: + foo: bar + newKey: 2 + + - it: should not set fleet values + asserts: + - notExists: + path: data.fleet + + - it: should set priorityClassName + set: + priorityClassName: "super" + asserts: + - equal: + path: data.priorityClassName + value: "super" + + - it: should set default priorityClassName + asserts: + - equal: + path: data.priorityClassName + value: "rancher-critical" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/deployment_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/deployment_test.yaml new file mode 100644 index 0000000..2c5e5cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/deployment_test.yaml @@ -0,0 +1,547 @@ +suite: Test Deployment +templates: +- deployment.yaml +tests: +- it: should set --add-local=false + set: + addLocal: "false" + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--add-local=false" +- it: should default to --add-local=true + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--add-local=true" +- it: should add CATTLE_SYSTEM_DEFAULT_REGISTRY to env and maintain default vars + set: + systemDefaultRegistry: "registry.example.com" + extraEnv: + - name: CATTLE_TLS_MIN_VERSION + value: "1.0" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_SYSTEM_DEFAULT_REGISTRY + value: "registry.example.com" + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_TLS_MIN_VERSION + value: "1.0" + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_NAMESPACE + value: NAMESPACE +- it: should Just have default env vars + asserts: + - equal: + path: spec.template.spec.containers[0].env + value: + - name: CATTLE_NAMESPACE + value: NAMESPACE + - name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher +- it: should default imagePullPolicy to IfNotPresent + asserts: + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: IfNotPresent +- it: should override imagePullPolicy to Always + set: + rancherImagePullPolicy: Always + asserts: + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always +- it: should set sidecar image as auditLog.image when auditLog.destination is sidecar and auditLog.level > 0 + set: + auditLog: + destination: sidecar + level: 1 + asserts: + - equal: + path: spec.template.spec.containers[1].image + value: rancher/mirrored-bci-micro:15.4.14.3 +- it: should override auditLog.image.repository value when auditLog.destination is sidecar and auditLog.level > 0 and both auditLog.image.repository and auditLog.image.tag are set + set: + auditLog: + destination: sidecar + level: 1 + image: + repository: my.private.repo:5000/rancher/busybox + tag: 1.0.1 + asserts: + - equal: + path: spec.template.spec.containers[1].image + value: my.private.repo:5000/rancher/busybox:1.0.1 +- it: deprecated busyboxImage should override auditLog.image.repository image when auditLog.destination is sidecar and auditLog.level > 0 and auditLog.image.repository and busyboxImage are set + set: + auditLog: + destination: sidecar + level: 1 + image: + repository: my.private.repo:5000/rancher/busybox + tag : 1.0.1 + busyboxImage: busybox + asserts: + - equal: + path: spec.template.spec.containers[1].image + value: busybox +- it: should override sidecar audit log imagePullPolicy when auditLog.destination is sidecar and auditLog.level > 0 and auditLog.imagePullPolicy is set + set: + auditLog: + destination: sidecar + level: 1 + image: + pullPolicy: Never + asserts: + - equal: + path: spec.template.spec.containers[1].imagePullPolicy + value: Never +- it: deprecated busyboxImagePullPolicy should override sidecar audit log imagePullPolicy when auditLog.destination is sidecar, auditLog.level > 0, and busyboxImagePullPolicy and auditLog.imagePullPolicy are set + set: + auditLog: + destination: sidecar + level: 1 + image: + pullPolicy: Never + busyboxImagePullPolicy: Always + asserts: + - equal: + path: spec.template.spec.containers[1].imagePullPolicy + value: Always +- it: should not have command arg "--no-cacerts" when using private CA + set: + privateCA: "true" + asserts: + - notContains: + path: spec.template.spec.containers[0].args + content: "--no-cacerts" +- it: should not have command arg "--no-cacerts" when using default (rancher) ingress TLS + set: + tls: "ingress" + asserts: + - notContains: + path: spec.template.spec.containers[0].args + content: "--no-cacerts" +- it: should have command arg "--no-cacerts" when using letsEncrypt ingress TLS + set: + tls: "ingress" + ingress.tls.source: "letsEncrypt" + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--no-cacerts" +- it: should have command arg "--no-cacerts" when using external TLS + set: + tls: "external" + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--no-cacerts" +- it: should add CATTLE_SYSTEM_CATALOG to env + set: + useBundledSystemChart: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_SYSTEM_CATALOG + value: "bundled" +- it: should create custom-logos volume if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim using default volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: custom-logos + persistentVolumeClaim: + claimName: RELEASE-NAME-rancher-custom-logos +- it: should create custom-logos volume customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim using customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + customLogos.volumeName: existing-pvc + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: custom-logos + persistentVolumeClaim: + claimName: existing-pvc +- it: should create custom-logos volume customLogos.enabled and customLogos.volumeKind=configMap using customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + customLogos.volumeName: existing-configMap + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: custom-logos + configMap: + name: existing-configMap +- it: should not create custom-logos volume if customLogos.enabled and customLogos.volumeKind=configMap but no customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + asserts: + - isNullOrEmpty: + path: spec.template.spec.volumes +- it: should not create custom-logos volume if not customLogos.enabled + set: + customLogos.enabled: false + asserts: + - isNullOrEmpty: + path: spec.template.spec.volumes +- it: should mount custom-logos volume with default subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: vue +- it: should mount custom-logos volume with default subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim and customLogos.volumeSubpaths.* blank + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + customLogos.volumeSubpaths.emberUi: "" + customLogos.volumeSubpaths.vueUi: "" + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: vue +- it: should mount custom-logos volume with specified subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + customLogos.volumeSubpaths.emberUi: test_ember + customLogos.volumeSubpaths.vueUi: test_vue + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: test_ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: test_vue +- it: should mount custom-logos volume with default subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim and customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + customLogos.volumeName: existing-configMap + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: vue +- it: should mount custom-logos volume with default subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim and customLogos.volumeName and customLogos.volumeSubpaths.* blank + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + customLogos.volumeName: existing-configMap + customLogos.volumeSubpaths.emberUi: "" + customLogos.volumeSubpaths.vueUi: "" + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: vue +- it: should mount custom-logos volume with specified subpaths if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim and customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + customLogos.volumeName: existing-configMap + customLogos.volumeSubpaths.emberUi: test_ember + customLogos.volumeSubpaths.vueUi: test_vue + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: test_ember + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: test_vue +- it: should not mount custom-logos volume if customLogos.enabled and customLogos.volumeKind=configMap but no customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + asserts: + - isNullOrEmpty: + path: spec.template.spec.containers[0].volumeMounts +- it: should not mount custom-logos volume if not customLogos.enabled + set: + customLogos.enabled: false + asserts: + - isNullOrEmpty: + path: spec.template.spec.containers[0].volumeMounts +- it: should set priorityClassName=system-node-critical + set: + priorityClassName: "system-node-critical" + asserts: + - equal: + path: spec.template.spec.priorityClassName + value: "system-node-critical" +- it: should not set priorityClassName=system-node-critical + set: + priorityClassName: "" + asserts: + - isNullOrEmpty: + path: spec.template.spec.priorityClassName +- it: should default priorityClassName="rancher-critical" + asserts: + - equal: + path: spec.template.spec.priorityClassName + value: "rancher-critical" +- it: should not set a livenessProbe initialDelaySeconds by default + asserts: + - notExists: + path: spec.template.spec.containers[0].livenessProbe.initialDelaySeconds +- it: should set livenessProbe periodSeconds defaults + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe.periodSeconds + value: 30 + - equal: + path: spec.template.spec.containers[0].livenessProbe.timeoutSeconds + value: 5 + - equal: + path: spec.template.spec.containers[0].livenessProbe.failureThreshold + value: 5 +- it: should not set readinessProbe initialDelaySeconds by default + asserts: + - notExists: + path: spec.template.spec.containers[0].readinessProbe.initialDelaySeconds +- it: should set readinessProbe periodSeconds defaults + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe.periodSeconds + value: 30 + - equal: + path: spec.template.spec.containers[0].readinessProbe.timeoutSeconds + value: 5 + - equal: + path: spec.template.spec.containers[0].readinessProbe.failureThreshold + value: 5 +- it: should set livenessProbe initialDelaySeconds to 90 + set: + livenessProbe.initialDelaySeconds: 90 + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe.initialDelaySeconds + value: 90 +- it: should set livenessProbe periodSeconds to 60 + set: + livenessProbe.periodSeconds: 60 + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe.periodSeconds + value: 60 +- it: should set readinessProbe initialDelaySeconds to 20 + set: + readinessProbe.initialDelaySeconds: 20 + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe.initialDelaySeconds + value: 20 +- it: should set readinessProbe periodSeconds to 60 + set: + readinessProbe.periodSeconds: 60 + asserts: + - equal: + path: spec.template.spec.containers[0].readinessProbe.periodSeconds + value: 60 +- it: should always have a startupProbe + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.port + value: 80 + - equal: + path: spec.template.spec.containers[0].startupProbe.httpGet.path + value: /healthz + - equal: + path: spec.template.spec.containers[0].startupProbe.timeoutSeconds + value: 5 + - equal: + path: spec.template.spec.containers[0].startupProbe.failureThreshold + value: 12 + - equal: + path: spec.template.spec.containers[0].startupProbe.periodSeconds + value: 10 +- it: allows configuring startupProbe values + set: + startupProbe.timeoutSeconds: 2 + startupProbe.failureThreshold: 10 + startupProbe.periodSeconds: 15 + asserts: + - equal: + path: spec.template.spec.containers[0].startupProbe.timeoutSeconds + value: 2 + - equal: + path: spec.template.spec.containers[0].startupProbe.failureThreshold + value: 10 + - equal: + path: spec.template.spec.containers[0].startupProbe.periodSeconds + value: 15 +- it: should add CATTLE_AGENT_TLS_MODE=strict to env and maintain default vars + set: + agentTLSMode: "strict" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "strict" + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_NAMESPACE + value: NAMESPACE +- it: should add CATTLE_AGENT_TLS_MODE=system-store to env and maintain default vars + set: + agentTLSMode: "system-store" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "system-store" + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_NAMESPACE + value: NAMESPACE +- it: should not add (null) CATTLE_AGENT_TLS_MODE to env and maintain default vars + set: + agentTLSMode: null + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "strict" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "system-store" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: null + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_NAMESPACE + value: NAMESPACE +- it: should not add ("") CATTLE_AGENT_TLS_MODE to env and maintain default vars + set: + agentTLSMode: "" + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "strict" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "system-store" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: "" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_AGENT_TLS_MODE + value: null + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_PEER_SERVICE + value: RELEASE-NAME-rancher + - contains: + path: spec.template.spec.containers[0].env + content: + name: CATTLE_NAMESPACE + value: NAMESPACE diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/ingress_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/ingress_test.yaml new file mode 100644 index 0000000..fef4824 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/ingress_test.yaml @@ -0,0 +1,240 @@ +suite: Test Ingress +templates: +- ingress.yaml +tests: +- it: should set external options + set: + tls: external + asserts: + - equal: + path: metadata.annotations["nginx.ingress.kubernetes.io/ssl-redirect"] + value: "false" + - isNull: + path: metadata.annotations["certmanager.k8s.io/issuer"] + - isNull: + path: spec.tls +- it: should set default annotations with default cert-manager + asserts: + - equal: + path: metadata.annotations + value: + cert-manager.io/issuer: RELEASE-NAME-rancher + cert-manager.io/issuer-kind: Issuer + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +- it: should set default annotations with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +- it: should set default annotations with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +- it: should disable the default nginx annotations + set: + ingress.includeDefaultExtraAnnotations: false + asserts: + - equal: + path: metadata.annotations + value: + cert-manager.io/issuer: RELEASE-NAME-rancher + cert-manager.io/issuer-kind: Issuer +- it: should over write proxy-connect-timeout with default cert-manager + set: + ingress: + includeDefaultExtraAnnotations: false + extraAnnotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" + asserts: + - equal: + path: metadata.annotations + value: + cert-manager.io/issuer: RELEASE-NAME-rancher + cert-manager.io/issuer-kind: Issuer + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" +- it: should over write proxy-connect-timeout with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress: + includeDefaultExtraAnnotations: false + extraAnnotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" +- it: should over write proxy-connect-timeout with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress: + includeDefaultExtraAnnotations: false + extraAnnotations: + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "15" +- it: should set source secret + set: + hostname: test + ingress.tls.source: secret + asserts: + - isNull: + path: certmanager\.k8s\.io/issuer + - contains: + path: spec.tls + content: + hosts: + - test + secretName: tls-rancher-ingress +- it: should set static X-Forwarded-Host header with default cert-manager + set: + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + asserts: + - equal: + path: metadata.annotations + value: + cert-manager.io/issuer: RELEASE-NAME-rancher + cert-manager.io/issuer-kind: Issuer + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; +- it: should set static X-Forwarded-Host header with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; +- it: should set static X-Forwarded-Host header with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; +- it: should be able to set multiple lines using configurationSnippet with default cert-manager + set: + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + more_set_input_headers "foo: bar"; + asserts: + - equal: + path: metadata.annotations + value: + cert-manager.io/issuer: RELEASE-NAME-rancher + cert-manager.io/issuer-kind: Issuer + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; + more_set_input_headers "foo: bar"; +- it: should be able to set multiple lines using configurationSnippet with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + more_set_input_headers "foo: bar"; + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; + more_set_input_headers "foo: bar"; +- it: should be able to set multiple lines using configurationSnippet with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + hostname: host.example.com + ingress: + configurationSnippet: | + more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + more_set_input_headers "foo: bar"; + asserts: + - equal: + path: metadata.annotations + value: + certmanager.k8s.io/issuer: RELEASE-NAME-rancher + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_input_headers "X-Forwarded-Host: host.example.com"; + more_set_input_headers "foo: bar"; +- it: should create a http rule with path + set: + hostname: host.example.com + asserts: + - equal: + path: spec.rules + value: + - host: host.example.com + http: + paths: + - backend: + service: + name: RELEASE-NAME-rancher + port: + number: 80 + pathType: ImplementationSpecific + path: / \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/issuer_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/issuer_test.yaml new file mode 100644 index 0000000..0c4ca44 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/issuer_test.yaml @@ -0,0 +1,322 @@ +suite: Test Issuers +templates: +- issuer-letsEncrypt.yaml +- issuer-rancher.yaml +tests: +- it: should not render issuers - tls=external + set: + tls: external + asserts: + - hasDocuments: + count: 0 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 0 + template: issuer-rancher.yaml +- it: should not render issuers - ingress.tls.source=secret + set: + ingress.tls.source: secret + asserts: + - hasDocuments: + count: 0 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 0 + template: issuer-rancher.yaml +- it: should render letsEncrypt but not rancher with default cert-manager + set: + ingress.tls.source: letsEncrypt + asserts: + - hasDocuments: + count: 1 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 0 + template: issuer-rancher.yaml +- it: should render letsEncrypt but not rancher with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: letsEncrypt + asserts: + - hasDocuments: + count: 1 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 0 + template: issuer-rancher.yaml +- it: should render letsEncrypt but not rancher with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: letsEncrypt + asserts: + - hasDocuments: + count: 1 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 0 + template: issuer-rancher.yaml +- it: should render rancher but not letsEncrypt with default cert-manager + set: + ingress.tls.source: rancher + asserts: + - hasDocuments: + count: 0 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 1 + template: issuer-rancher.yaml +- it: should render rancher but not letsEncrypt with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: rancher + asserts: + - hasDocuments: + count: 0 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 1 + template: issuer-rancher.yaml +- it: should render rancher but not letsEncrypt with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: rancher + asserts: + - hasDocuments: + count: 0 + template: issuer-letsEncrypt.yaml + - hasDocuments: + count: 1 + template: issuer-rancher.yaml +- it: should set letsEncrypt apiVersion with default cert-manager + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager >= 0.16.0 using capabilities + capabilities: + apiVersions: + - cert-manager.io/v1beta1 + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1beta1 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager >= 0.11.0 using capabilities + capabilities: + apiVersions: + - cert-manager.io/v1alpha2 + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1alpha2 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: certmanager.k8s.io/v1alpha1 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager >= 0.16.0 using parameter + set: + certmanager.version: 0.16.0 + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1beta1 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager >= 0.11.0 using parameter + set: + certmanager.version: 0.11.0 + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1alpha2 + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt apiVersion with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: apiVersion + value: certmanager.k8s.io/v1alpha1 + template: issuer-letsEncrypt.yaml +- it: should set rancher apiVersion with default cert-manager + set: + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager >= 0.16.0 using capabilities + capabilities: + apiVersions: + - cert-manager.io/v1beta1 + set: + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1beta1 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager >= 0.11.0 using capabilities + capabilities: + apiVersions: + - cert-manager.io/v1alpha2 + set: + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1alpha2 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: certmanager.k8s.io/v1alpha1 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager >= 0.16.0 using parameter + set: + certmanager.version: 0.16.0 + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1beta1 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager >= 0.11.0 using parameter + set: + certmanager.version: 0.11.0 + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: cert-manager.io/v1alpha2 + template: issuer-rancher.yaml +- it: should set rancher apiVersion with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: rancher + asserts: + - equal: + path: apiVersion + value: certmanager.k8s.io/v1alpha1 + template: issuer-rancher.yaml +- it: should set letsEncrypt production by default with default cert-manager + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: spec.acme.server + value: https://acme-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt production by default with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: spec.acme.server + value: https://acme-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt production by default with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: letsEncrypt + asserts: + - equal: + path: spec.acme.server + value: https://acme-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt staging with default cert-manager + capabilities: + apiVersions: + - cert-manager.io/v1alpha2 + set: + ingress.tls.source: letsEncrypt + letsEncrypt.environment: staging + asserts: + - equal: + path: spec.acme.server + value: https://acme-staging-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt staging with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: letsEncrypt + letsEncrypt.environment: staging + asserts: + - equal: + path: spec.acme.server + value: https://acme-staging-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt staging with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: letsEncrypt + letsEncrypt.environment: staging + asserts: + - equal: + path: spec.acme.server + value: https://acme-staging-v02.api.letsencrypt.org/directory + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt email address with default cert-manager + set: + ingress.tls.source: letsEncrypt + letsEncrypt.email: test@test.org + asserts: + - equal: + path: spec.acme.email + value: test@test.org + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt email address with cert-manager < 0.11.0 using capabilities + capabilities: + apiVersions: + - certmanager.k8s.io/v1alpha1 + set: + ingress.tls.source: letsEncrypt + letsEncrypt.email: test@test.org + asserts: + - equal: + path: spec.acme.email + value: test@test.org + template: issuer-letsEncrypt.yaml +- it: should set letsEncrypt email address with cert-manager < 0.11.0 using parameter + set: + certmanager.version: 0.9.0 + ingress.tls.source: letsEncrypt + letsEncrypt.email: test@test.org + asserts: + - equal: + path: spec.acme.email + value: test@test.org + template: issuer-letsEncrypt.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/pvc_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/pvc_test.yaml new file mode 100644 index 0000000..0cb9e69 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/pvc_test.yaml @@ -0,0 +1,36 @@ +suite: Test persistentVolumeClaim +templates: +- pvc.yaml +tests: +- it: should create custom-logos pvc if customLogos.enabled and customLogos.volumeKind persistentVolumeClaim + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + asserts: + - equal: + path: metadata.name + value: RELEASE-NAME-rancher-custom-logos +- it: should not create custom-logos pvc if customLogos.enabled and customLogos.volumeKind=persistentVolumeClaim and customLogos.volumeName + set: + customLogos.enabled: true + customLogos.volumeKind: persistentVolumeClaim + customLogos.volumeName: existing-pvc + asserts: + - hasDocuments: + count: 0 + template: pvc.yaml +- it: should not create custom-logos pvc if not customLogos.enabled and customLogos.volumeKind=configMap + set: + customLogos.enabled: true + customLogos.volumeKind: configMap + asserts: + - hasDocuments: + count: 0 + template: pvc.yaml +- it: should not create custom-logos pvc if not customLogos.enabled + set: + customLogos.enabled: false + asserts: + - hasDocuments: + count: 0 + template: pvc.yaml \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/service_test.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/service_test.yaml new file mode 100644 index 0000000..37c47df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/tests/service_test.yaml @@ -0,0 +1,46 @@ +suite: Test Service +templates: +- service.yaml +tests: +- it: should set NodePort service type + set: + service.type: NodePort + asserts: + - equal: + path: spec.type + value: NodePort +- it: should set LoadBalancer service type + set: + service.type: LoadBalancer + asserts: + - equal: + path: spec.type + value: LoadBalancer +- it: should default to ClusterIP service type + asserts: + - isNull: + path: spec.type +- it: should set provided service annotation correctly + set: + service.annotations: + beta.cloud.google.com/backend-config: '{"default": "rancher-config"}' + asserts: + - equal: + path: metadata.annotations + value: + beta.cloud.google.com/backend-config: '{"default": "rancher-config"}' +- it: should set multiple provided service annotations correctly + set: + service.annotations: + beta.cloud.google.com/backend-config: '{"default": "rancher-config"}' + cloud.google.com/neg: '{"ingress": true}' + asserts: + - equal: + path: metadata.annotations + value: + beta.cloud.google.com/backend-config: '{"default": "rancher-config"}' + cloud.google.com/neg: '{"ingress": true}' +- it: should not include service annotations if none are provided + asserts: + - isNull: + path: metadata.annotations diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.schema.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.schema.json new file mode 100644 index 0000000..d72b73f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "properties": { + "agentTLSMode": { + "type": ["string", "null"], + "enum": ["strict", "system-store", "", null], + "description": "agentTLSMode must be 'strict' or 'system-store' or null (defaults to system-store)" + } + }, + "required": [], + "title": "Rancher Chart Values", + "type": "object" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.yaml new file mode 100644 index 0000000..d96a30c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/chart/values.yaml @@ -0,0 +1,199 @@ +# Additional Trusted CAs. +# Enable this flag and add your CA certs as a secret named tls-ca-additional in the namespace. +# See README.md for details. +additionalTrustedCAs: false + +antiAffinity: preferred +topologyKey: kubernetes.io/hostname + +# Audit Logs https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# The audit log is piped to the console of the rancher-audit-log container in the rancher pod. +# https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# destination stream to sidecar container console or hostPath volume +# level: Verbosity of logs, 0 to 3. 0 is off 3 is a lot. +auditLog: + destination: sidecar + hostPath: /var/log/rancher/audit/ + level: 0 + maxAge: 1 + maxBackup: 1 + maxSize: 100 + + # Image for collecting rancher audit logs. + # Important: update pkg/image/export/resolve.go when this default image is changed, so that it's reflected accordingly in rancher-images.txt generated for air-gapped setups. + image: + repository: "rancher/mirrored-bci-micro" + tag: 15.4.14.3 + # Override imagePullPolicy image + # options: Always, Never, IfNotPresent + pullPolicy: "IfNotPresent" + +# As of Rancher v2.5.0 this flag is deprecated and must be set to 'true' in order for Rancher to start +addLocal: "true" + +# Add debug flag to Rancher server +debug: false + +# When starting Rancher for the first time, bootstrap the admin as restricted-admin +restrictedAdmin: false + +# Control how the Rancher agents validate TLS connections +# Valid options: strict, or system-store +# Note, for new installations empty will default to strict on 2.9+, or system-store on 2.8 or older +agentTLSMode: "" + +# Extra environment variables passed to the rancher pods. +# extraEnv: +# - name: CATTLE_TLS_MIN_VERSION +# value: "1.0" + +# Fully qualified name to reach your Rancher server +# hostname: rancher.my.org + +## Optional array of imagePullSecrets containing private registry credentials +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: secretName + +### ingress ### +# Readme for details and instruction on adding tls secrets. +ingress: + # If set to false, ingress will not be created + # Defaults to true + # options: true, false + enabled: true + includeDefaultExtraAnnotations: true + extraAnnotations: {} + ingressClassName: "" + # Certain ingress controllers will require the pathType or path to be set to a different value. + pathType: ImplementationSpecific + path: "/" + # backend port number + servicePort: 80 + + # configurationSnippet - Add additional Nginx configuration. This example statically sets a header on the ingress. + # configurationSnippet: | + # more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + + tls: + # options: rancher, letsEncrypt, secret + source: rancher + secretName: tls-rancher-ingress + +### service ### +# Override to use NodePort or LoadBalancer service type - default is ClusterIP +service: + type: "" + annotations: {} + +### LetsEncrypt config ### +# ProTip: The production environment only allows you to register a name 5 times a week. +# Use staging until you have your config right. +letsEncrypt: + # email: none@example.com + environment: production + ingress: + # options: traefik, nginx + class: "" +# If you are using certs signed by a private CA set to 'true' and set the 'tls-ca' +# in the 'rancher-system' namespace. See the README.md for details +privateCA: false + +# http[s] proxy server passed into rancher server. +# proxy: http://@:: + +# comma separated list of domains or ip addresses that will not use the proxy +noProxy: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local + +# Override rancher image location for Air Gap installs +rancherImage: rancher/rancher +# rancher/rancher image tag. https://hub.docker.com/r/rancher/rancher/tags/ +# Defaults to .Chart.appVersion +# rancherImageTag: v2.0.7 + +# Override imagePullPolicy for rancher server images +# options: Always, Never, IfNotPresent +# Defaults to IfNotPresent +# rancherImagePullPolicy: + +# Number of Rancher server replicas. Setting to negative number will dynamically between 0 and the abs(replicas) based on available nodes. +# of available nodes in the cluster +replicas: 3 + +# Set priorityClassName to avoid eviction +priorityClassName: rancher-critical + +# Set pod resource requests/limits for Rancher. +resources: {} + +# +# tls +# Where to offload the TLS/SSL encryption +# - ingress (default) +# - external +tls: ingress + +systemDefaultRegistry: "" + +# Set to use the packaged system charts +useBundledSystemChart: false + +# Certmanager version compatibility +certmanager: + version: "" + +# Rancher custom logos persistence +customLogos: + enabled: false + volumeSubpaths: + emberUi: "ember" + vueUi: "vue" + ## Volume kind to use for persistence: persistentVolumeClaim, configMap + volumeKind: persistentVolumeClaim + ## Use an existing volume. Custom logos should be copied to the volume by the user + # volumeName: custom-logos + ## Just for volumeKind: persistentVolumeClaim + ## To disables dynamic provisioning, set storageClass: "" or storageClass: "-" + # storageClass: "-" + accessMode: ReadWriteOnce + size: 1Gi + +# Rancher post-delete hook +postDelete: + enabled: true + image: + repository: %POST_DELETE_IMAGE_NAME% + tag: %POST_DELETE_IMAGE_TAG% + namespaceList: + - cattle-fleet-system + - cattle-system + - rancher-operator-system + # Number of seconds to wait for an app to be uninstalled + timeout: 120 + # by default, the job will fail if it fail to uninstall any of the apps + ignoreTimeoutError: false + +# Set a bootstrap password. If leave empty, a random password will be generated. +bootstrapPassword: "" + +startupProbe: + ## should be ready within 2 minutes + timeoutSeconds: 5 + periodSeconds: 10 + failureThreshold: 12 +livenessProbe: + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 5 +readinessProbe: + timeoutSeconds: 5 + periodSeconds: 30 + failureThreshold: 5 + +# helm values to use when installing the rancher-webhook chart. +# helm values set here will override all other global values used when installing the webhook such as priorityClassName and systemRegistry settings. +webhook: "" + +# helm values to use when installing the fleet chart. +# helm values set here will override all other global values used when installing the fleet chart. +fleet: "" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-README.md new file mode 100644 index 0000000..d04ede9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-README.md @@ -0,0 +1,65 @@ +# Active Directory GUID -> DN reverse migration utility + +**It is recommended to take a snapshot of Rancher before performing this in the event that a restore is required.** + + +## Critical Notes +* This script will delete and recreate CRTBs/PRTBs/GRBs, which may cause issues with tools (like terraform) which maintain external state. The original object names are stored in an annotation on the new objects. +* It is recommended to use this script on Rancher v2.7.6 - running this on v2.7.5 may produce performance issues +* This script requires that the Active Directory service account has permissions to read all users known to Rancher. + + +## Purpose + +In order to reverse the effects of migrating Active Directory principalIDs to be based on GUID rather than DN this +utility is required. It can be run manually via Rancher Agent, or it will automatically run inside Rancher at startup +time if no previous run is detected. +This utility will: +* Remove any users that were duplicated during the original migration toward GUID-based principalIDs in Rancher 2.7.5 +* Update objects that referenced a GUID-based principalID to reference the correct distinguished name based principalID + + +## Detailed description + +This utility will go through all Rancher users and perform an Active Directory lookup using the configured service account to +get the user's distinguished name. Next, it will perform lookups inside Rancher for all the user's Tokens, +ClusterRoleTemplateBindings, ProjectRoleTemplateBindings, and GlobalRoleBindings. If any of those objects, including the user object +itself are referencing a principalID based on the GUID of that user, those objects will be updated to reference +the distinguished name-based principalID (unless the utility is run with -dry-run, in that case the only results +are log messages indicating the changes that would be made by a run without that flag). + +This utility will also detect and correct the case where a single ActiveDirectory GUID is mapped to multiple Rancher +users. That condition was likely caused by a race in the original migration to use GUIDs and resulted in a second +Rancher user being created. This caused Rancher logins to fail for the duplicated user. The utility remedies +that situation by mapping any tokens and bindings to the original user before removing the newer user, which was +created in error. + + +## Requirements + +A Rancher environment that has Active Directory set up as the authentication provider. For any environment where +Active Directory is not the authentication provider, this utility will take no action and will exit immediately. + + +## Usage via Rancher Agent + +```bash +./ad-guid-unmigration.sh [--dry-run] [--delete-missing] +``` +* The Agent image can be found at: docker.io/rancher/rancher-agent:v2.7.6 +* The --dry-run flag will run the migration utility, but no changes to Rancher data will take place. The potential changes will be indicated in the log file. +* The --delete-missing flag will delete Rancher users that can not be found by looking them up in Active Directory. If --dry-run is set, that will prevent users from being deleted regardless of this flag. + + +## Additional notes +* The utility will create a configmap named `ad-guid-migration` in the `cattle-system` namespace. This configmap contains + a data entry with a key named "ad-guid-migration-status". If the utility is currently active, that status will be + set to "Running". After the utility has completed, the status will be set to "Finished". If a run is interrupted + prior to completion, that configmap will retain the status of "Running" and subsequent attempts to run the script will + immediately exit. In order to allow it to run again, you can either edit the configmap to remove that key or you can + delete the configmap entirely. + +* When migrating ClusterRoleTemplateBindings, ProjectRoleTemplateBindings, and GlobalRoleBindings it is necessary to perform the action + as a delete/create rather than an update. **This may cause issues if you use tooling that relies on the names of the objects**. + When a ClusterRoleTemplateBinding or a ProjectRoleTemplateBinding is migrated to a new name, the newly created object + will contain a label, "ad-guid-previous-name", that will have a value of the name of the object that was deleted. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-unmigration.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-unmigration.sh new file mode 100755 index 0000000..6da62b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/ad-guid-unmigration.sh @@ -0,0 +1,280 @@ +#!/bin/bash +# set -x +set -e + +# Text to display in the banner +banner_text="This utility will go through all Rancher users and perform an Active Directory lookup using +the configured service account to get the user's distinguished name. Next, it will perform lookups inside Rancher +for all the user's Tokens, ClusterRoleTemplateBindings, and ProjectRoleTemplateBindings. If any of those objects, +including the user object itself are referencing a principalID based on the GUID of that user, those objects will be +updated to reference the distinguished name-based principalID (unless the utility is run with -dry-run, in that case +the only results are log messages indicating the changes that would be made by a run without that flag). + +This utility will also detect and correct the case where a single ActiveDirectory GUID is mapped to multiple Rancher +users. That condition was likely caused by a race in the original migration to use GUIDs and resulted in a second +Rancher user being created. This caused Rancher logins to fail for the duplicated user. The utility remedies +that situation by mapping any tokens and bindings to the original user before removing the newer user, which was +created in error. + +It is also important to note that migration of ClusterRoleTemplateBindings and ProjectRoleTemplateBindings require +a delete/create operation rather than an update. This will result in new object names for the migrated bindings. +A label with the former object name will be included in the migrated bindings. + +The Rancher Agent image to be used with this utility can be found at rancher/rancher-agent:v2.7.6 + +It is recommended that you perform a Rancher backup prior to running this utility." + +CLEAR='\033[0m' +RED='\033[0;31m' + +# cluster resources, including the service account used to run the script +cluster_resources_yaml=$(cat << 'EOF' +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cattle-cleanup-sa + namespace: cattle-system + labels: + rancher-cleanup: "true" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cattle-cleanup-binding + labels: + rancher-cleanup: "true" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cattle-cleanup-role +subjects: + - kind: ServiceAccount + name: cattle-cleanup-sa + namespace: cattle-system +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: cattle-cleanup-job + namespace: cattle-system + labels: + rancher-cleanup: "true" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + selector: + template: + metadata: + creationTimestamp: null + spec: + containers: + - env: + - name: AD_GUID_CLEANUP + value: "true" + #dryrun - name: DRY_RUN + #dryrun value: "true" + #deletemissing - name: AD_DELETE_MISSING_GUID_USERS + #deletemissing value: "true" + #debug - name: RANCHER_DEBUG + #debug value: "true" + image: agent_image + imagePullPolicy: Always + command: ["agent"] + name: cleanup-agent + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccountName: cattle-cleanup-sa + terminationGracePeriodSeconds: 30 +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cattle-cleanup-role + labels: + rancher-cleanup: "true" +rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' +EOF +) + +# Agent image to use in the yaml file +agent_image="$1" + +show_usage() { + if [ -n "$1" ]; then + echo -e "${RED}👉 $1${CLEAR}\n"; + fi + echo "Usage: $0 AGENT_IMAGE [OPTIONS]" + echo "" + echo "Options:" + echo -e "\t-h, --help Display this help message" + echo -e "\t-n, --dry-run Display the resources that would be updated without making changes" + echo -e "\t-d, --delete-missing Permanently remove user objects whose GUID cannot be found in Active Directory" + echo -e "\t-v, --debug Run with extra debug verbosity" +} + +display_banner() { + local text="$1" + local border_char="=" + local text_width=$(($(tput cols))) + local border=$(printf "%${text_width}s" | tr " " "$border_char") + + echo "$border" + printf "%-${text_width}s \n" "$text" + echo "$border" + echo "Dry run: $dry_run" + echo "Delete missing: $delete_missing" + echo "Agent image: $agent_image" + echo "Debug: $debug_mode" + if [[ "$dry_run" = true ]] && [[ "$delete_missing" = true ]] + then + echo "Setting the dry-run option to true overrides the delete-missing option. NO CHANGES WILL BE MADE." + fi + echo "$border" +} + +OPTS=$(getopt -o hndv -l help,dry-run,delete-missing,debug -- "$@") +if [ $? != 0 ]; then + show_usage "Invalid option" + exit 1 +fi + +eval set -- "$OPTS" + +dry_run=false +delete_missing=false +debug_mode=false + +while true; do + case "$1" in + -h | --help) + show_usage + exit 0 + ;; + -n | --dry-run) + dry_run=true + shift + ;; + -d | --delete-missing) + delete_missing=true + shift + ;; + -v | --debug) + debug_mode=true + shift + ;; + --) + shift + break + ;; + *) + show_usage "Invalid option" + exit 1 + ;; + esac +done + +shift "$((OPTIND - 1))" +# Ensure AGENT_IMAGE is provided +if [ $# -lt 1 ]; then + show_usage "AGENT_IMAGE is a required argument" + exit 1 +fi + +display_banner "${banner_text}" + +if [ "$dry_run" != true ] +then + # Check the Rancher version before doing anything. + # If it is v2.7.5, make it clear that configuration is not the recommended way to run this utility. + rancher_version=$(kubectl get settings server-version --template='{{.value}}') + if [ "$rancher_version" = "v2.7.5" ]; then + echo -e "${RED}IT IS NOT RECOMMENDED TO RUN THIS UTILITY AGAINST RANCHER VERSION v2.7.5${CLEAR}" + echo -e "${RED}IF RANCHER v.2.7.5 RESTARTS AFTER RUNNING THIS UTILITY, IT WILL UNDO THE EFFECTS OF THIS UTILITY.${CLEAR}" + echo -e "${RED}IF YOU DO WANT TO RUN THIS UTILITY, IT IS RECOMMENDED THAT YOU MAKE A BACKUP PRIOR TO CONTINUING.${CLEAR}" + read -p "Do you want to continue? (y/n): " choice + if [[ ! $choice =~ ^[Yy]$ ]]; then + echo "Exiting..." + exit 0 + fi + fi +fi + + +read -p "Do you want to continue? (y/n): " choice +if [[ ! $choice =~ ^[Yy]$ ]]; then + echo "Exiting..." + exit 0 +fi + +# apply the provided rancher agent +yaml=$(sed -e 's=agent_image='"$agent_image"'=' <<< $cluster_resources_yaml) + +if [ "$dry_run" = true ] +then + # Uncomment the env var for dry-run mode + yaml=$(sed -e 's/#dryrun // ' <<< "$yaml") +elif [ "$delete_missing" = true ] +then + # Uncomment the env var for missing user cleanup + yaml=$(sed -e 's/#deletemissing // ' <<< "$yaml") +fi + +if [ "$debug_mode" = true ] +then + # Uncomment the env var for debug logging + yaml=$(sed -e 's/#debug // ' <<< "$yaml") +fi + +echo "$yaml" | kubectl apply -f - + +# Get the pod ID to tail the logs +retry_interval=1 +max_retries=10 +retry_count=0 +pod_id="" +while [ $retry_count -lt $max_retries ]; do + pod_id=$(kubectl --namespace=cattle-system get pod -l job-name=cattle-cleanup-job -o jsonpath="{.items[0].metadata.name}") + if [ -n "$pod_id" ]; then + break + else + sleep $retry_interval + ((retry_count++)) + fi +done + +# 600 is equal to 5 minutes, because the sleep interval is 0.5 seconds +job_start_timeout=600 + +declare -i count=0 +until kubectl --namespace=cattle-system logs $pod_id -f +do + if [ $count -gt $job_start_timeout ] + then + echo "Timeout reached, check the job by running kubectl --namespace=cattle-system get jobs" + echo "To cleanup manually, you can run:" + echo " kubectl --namespace=cattle-system delete serviceaccount,job -l rancher-cleanup=true" + echo " kubectl delete clusterrole,clusterrolebinding -l rancher-cleanup=true" + exit 1 + fi + sleep 0.5 + count+=1 +done + +# Cleanup after it completes successfully +echo "$yaml" | kubectl delete -f - diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.sh new file mode 100755 index 0000000..8fd15d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# set -x +set -e + +CLEAR='\033[0m' +RED='\033[0;31m' + +# Location of the yaml to use to deploy the cleanup job +yaml_url=https://raw.githubusercontent.com/rancher/rancher/master/cleanup/binding-clean.yaml + +# 120 is equal to a minute as the sleep is half a second +timeout=120 + +# Agent image to use in the yaml file +agent_image="$1" + +show_usage() { + if [ -n "$1" ]; then + echo -e "${RED}👉 $1${CLEAR}\n"; + fi + echo -e "Usage: $0 [AGENT_IMAGE] [FLAGS]" + echo "AGENT_IMAGE is a required argument" + echo "" + echo "Flags:" + echo -e "\t-dry-run Display the resources that would will be updated without making changes" +} + +if [ $# -lt 1 ] +then + show_usage "AGENT_IMAGE is a required argument" + exit 1 +fi + +if [[ $1 == "-h" ||$1 == "--help" ]] +then + show_usage + exit 0 +fi + +# Pull the yaml and replace the agent_image holder with the passed in image +yaml=$(curl --insecure -sfL $yaml_url | sed -e 's=agent_image='"$agent_image"'=') + +if [ "$2" = "-dry-run" ] +then + # Uncomment the env var for dry-run mode + yaml=$(sed -e 's/# // ' <<< "$yaml") +fi + +echo "$yaml" | kubectl apply -f - + +# Get the pod ID to tail the logs +pod_id=$(kubectl get pod -l job-name=cattle-cleanup-job -o jsonpath="{.items[0].metadata.name}") + +declare -i count=0 +until kubectl logs $pod_id -f +do + if [ $count -gt $timeout ] + then + echo "Timout reached, check the job by running kubectl get jobs" + exit 1 + fi + sleep 0.5 + count+=1 +done + +# Cleanup after it completes successfully +echo "$yaml" | kubectl delete -f - diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.yaml new file mode 100644 index 0000000..892e820 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/binding-clean.yaml @@ -0,0 +1,88 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cattle-cleanup-sa + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cattle-cleanup-binding + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cattle-cleanup-role +subjects: + - kind: ServiceAccount + name: cattle-cleanup-sa + namespace: default +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: cattle-cleanup-job + namespace: default + labels: + rancher-cleanup: "true" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + selector: + template: + metadata: + creationTimestamp: null + spec: + containers: + - env: + - name: BINDING_CLEANUP + value: "true" + # - name: DRY_RUN + # value: "true" + image: agent_image + imagePullPolicy: Always + command: ["agent"] + name: cleanup-agent + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccountName: cattle-cleanup-sa + terminationGracePeriodSeconds: 30 +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cattle-cleanup-role + namespace: default +rules: + - apiGroups: + - management.cattle.io + resources: + - clusterroletemplatebindings + - projectroletemplatebindings + verbs: + - list + - get + - apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + - clusterrolebindings + - roles + verbs: + - list + - get + - delete + - apiGroups: + - batch + resources: + - jobs + verbs: + - list + - get + - delete diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.sh new file mode 100755 index 0000000..0992c51 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# set -x +set -e + +# Location of the yaml to use to deploy the cleanup job +yaml_url=https://raw.githubusercontent.com/rancher/rancher/master/cleanup/user-cluster.yml + +# 120 is equal to a minute as the sleep is half a second +timeout=120 + +# Agent image to use in the yaml file +agent_image="$1" + +show_usage() { + echo -e "Usage: $0 [AGENT_IMAGE] [FLAGS]" + echo "AGENT_IMAGE is a required argument" + echo "" + echo "Flags:" + echo -e "\t-dry-run Display the resources that would will be updated without making changes" +} + +if [ $# -lt 1 ] +then + show_usage + exit 1 +fi + +if [[ $1 == "-h" ||$1 == "--help" ]] +then + show_usage + exit 0 +fi + +# Pull the yaml and replace the agent_image holder with the passed in image +yaml=$(curl --insecure -sfL $yaml_url | sed -e 's=agent_image='"$agent_image"'=') + +if [ "$2" = "-dry-run" ] +then + # Uncomment the env var for dry-run mode + yaml=$(sed -e 's/# // ' <<< "$yaml") +fi + +echo "$yaml" | kubectl apply -f - + +# Get the pod ID to tail the logs +pod_id=$(kubectl get pod -l job-name=cattle-cleanup-job -o jsonpath="{.items[0].metadata.name}") + +declare -i count=0 +until kubectl logs $pod_id -f +do + if [ $count -gt $timeout ] + then + echo "Timout reached, check the job by running kubectl get jobs" + exit 1 + fi + sleep 0.5 + count+=1 +done + +# Cleanup after it completes successfully +echo "$yaml" | kubectl delete -f - diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.yml new file mode 100644 index 0000000..184c7a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cleanup/user-cluster.yml @@ -0,0 +1,95 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cattle-cleanup-sa + namespace: default + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cattle-cleanup-binding + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cattle-cleanup-role +subjects: +- kind: ServiceAccount + name: cattle-cleanup-sa + namespace: default + +--- + +apiVersion: batch/v1 +kind: Job +metadata: + name: cattle-cleanup-job + namespace: default + labels: + rancher-cleanup: "true" +spec: + backoffLimit: 6 + completions: 1 + parallelism: 1 + selector: + template: + metadata: + creationTimestamp: null + spec: + containers: + - env: + - name: CLUSTER_CLEANUP + value: "true" + # - name: DRY_RUN + # value: "true" + image: agent_image + imagePullPolicy: Always + name: cleanup-agent + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: OnFailure + schedulerName: default-scheduler + securityContext: {} + serviceAccountName: cattle-cleanup-sa + terminationGracePeriodSeconds: 30 + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cattle-cleanup-role + namespace: default +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - get + - update + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + - clusterroles + - clusterrolebindings + verbs: + - list + - get + - delete +- apiGroups: + - batch + resources: + - jobs + verbs: + - list + - get + - delete \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cmd/agent/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cmd/agent/main.go new file mode 100644 index 0000000..2a5606b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/cmd/agent/main.go @@ -0,0 +1,546 @@ +package main + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io/ioutil" + "log" + "net/http" + _ "net/http/pprof" + "net/url" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" + "github.com/mattn/go-colorable" + "github.com/rancher/rancher/pkg/agent/clean" + "github.com/rancher/rancher/pkg/agent/clean/adunmigration" + "github.com/rancher/rancher/pkg/agent/cluster" + "github.com/rancher/rancher/pkg/agent/node" + "github.com/rancher/rancher/pkg/agent/rancher" + "github.com/rancher/rancher/pkg/controllers/managementuser/cavalidator" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/logserver" + "github.com/rancher/rancher/pkg/rkenodeconfigclient" + "github.com/rancher/remotedialer" + "github.com/rancher/wrangler/v3/pkg/signals" + "github.com/sirupsen/logrus" +) + +var ( + VERSION = "dev" +) + +const ( + Token = "X-API-Tunnel-Token" + caFileLocation = "/etc/kubernetes/ssl/certs/serverca" +) + +func main() { + var err error + ctx := context.Background() + + if len(os.Args) > 1 { + err = runArgs(ctx) + } else { + if _, err = reconcileKubelet(ctx); err != nil { + logrus.Warnf("failed to reconcile kubelet, error: %v", err) + } + + configureLogrus() + + logserver.StartServerWithDefaults() + + initFeatures() + + if os.Getenv("CLUSTER_CLEANUP") == "true" { + err = clean.Cluster() + } else if os.Getenv("BINDING_CLEANUP") == "true" { + err = errors.Join( + clean.DuplicateBindings(nil), + clean.OrphanBindings(nil), + clean.OrphanCatalogBindings(nil), + ) + } else if os.Getenv("AD_GUID_CLEANUP") == "true" { + dryrun := os.Getenv("DRY_RUN") == "true" + deleteMissingUsers := os.Getenv("AD_DELETE_MISSING_GUID_USERS") == "true" + err = adunmigration.UnmigrateAdGUIDUsers(nil, dryrun, deleteMissingUsers) + } else { + err = run(ctx) + } + } + + if err != nil { + logrus.Fatal(err) + } +} + +func runArgs(ctx context.Context) error { + switch os.Args[1] { + case "clean": + return clean.Run(ctx, os.Args) + default: + return run(ctx) + } +} + +func initFeatures() { + features.InitializeFeatures(nil, os.Getenv("CATTLE_FEATURES")) +} + +func isCluster() bool { + return os.Getenv("CATTLE_CLUSTER") == "true" +} + +func getParams() (map[string]interface{}, error) { + if isCluster() { + return cluster.Params() + } + return node.Params(), nil +} + +func getTokenAndURL() (string, string, error) { + token, url, err := node.TokenAndURL() + if err != nil { + return "", "", err + } + if token == "" { + return cluster.TokenAndURL() + } + return token, url, nil +} + +func isConnect() bool { + if os.Getenv("CATTLE_AGENT_CONNECT") == "true" { + return true + } + _, err := os.Stat("connected") + return err == nil +} + +func connected() { + f, err := os.Create("connected") + if err != nil { + f.Close() + } +} + +func cleanup(ctx context.Context) error { + if os.Getenv("CATTLE_K8S_MANAGED") != "true" { + return nil + } + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + args := filters.NewArgs() + args.Add("label", "io.cattle.agent=true") + + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + return err + } + + for _, container := range containers { + if _, ok := container.Labels["io.kubernetes.pod.namespace"]; ok { + continue + } + + if strings.Contains(container.Names[0], "share-mnt") { + continue + } + + container := container + go func() { + time.Sleep(15 * time.Second) + logrus.Infof("Removing unmanaged agent %s(%s)", container.Names[0], container.ID) + c.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{ + Force: true, + }) + }() + } + + return nil +} + +func run(ctx context.Context) error { + topContext := signals.SetupSignalContext() + + logrus.Infof("Rancher agent version %s is starting", VERSION) + params, err := getParams() + if err != nil { + return err + } + writeCertsOnly := os.Getenv("CATTLE_WRITE_CERT_ONLY") == "true" + bytes, err := json.Marshal(params) + if err != nil { + return err + } + + token, server, err := getTokenAndURL() + if err != nil { + return err + } + + headers := http.Header{ + Token: {token}, + rkenodeconfigclient.Params: {base64.StdEncoding.EncodeToString(bytes)}, + } + + serverURL, err := url.Parse(server) + if err != nil { + return err + } + + topContext = context.WithValue(topContext, cavalidator.CacertsValid, false) + + // Perform root CA verification + var transport *http.Transport + systemStoreConnectionCheckRequired := true + transport = rootCATransport() + if transport != nil { + logrus.Infof("Testing connection to %s using trusted certificate authorities within: %s", server, caFileLocation) + var httpClient = &http.Client{ + Timeout: time.Second * 5, + Transport: transport, + } + if _, err = httpClient.Get(server); err != nil { + if cluster.CAStrictVerify() { + logrus.Errorf("Could not securely connect to %s: %v", server, err) + os.Exit(1) + } + // onConnect will use the transport later on, so discard it as it doesn't work and fallback to the system store. + transport = nil + } else { + topContext = context.WithValue(topContext, cavalidator.CacertsValid, true) + systemStoreConnectionCheckRequired = false + } + } else if cluster.CAStrictVerify() { + logrus.Errorf("Strict CA verification is enabled but encountered error finding root CA") + os.Exit(1) + } + + if systemStoreConnectionCheckRequired { + // Check if secure connection can be made successfully + var httpClient = &http.Client{ + Timeout: time.Second * 5, + } + _, err = httpClient.Get(server) + if err != nil { + if strings.Contains(err.Error(), "x509:") { + certErr := err + if strings.Contains(err.Error(), "certificate signed by unknown authority") { + certErr = fmt.Errorf("Certificate chain is not complete, please check if all needed intermediate certificates are included in the server certificate (in the correct order) and if the cacerts setting in Rancher either contains the correct CA certificate (in the case of using self signed certificates) or is empty (in the case of using a certificate signed by a recognized CA). Certificate information is displayed above. error: %s", err) + } + if strings.Contains(err.Error(), "certificate has expired or is not yet valid") { + certErr = fmt.Errorf("Server certificate is not valid, please check if the host has the correct time configured and if the server certificate has a notAfter date and time in the future. Certificate information is displayed above. error: %s", err) + } + if strings.Contains(err.Error(), "because it doesn't contain any IP SANs") || strings.Contains(err.Error(), "certificate is not valid for any names, but wanted to match") || strings.Contains(err.Error(), "cannot validate certificate for") { + certErr = fmt.Errorf("Server certificate does not contain correct DNS and/or IP address entries in the Subject Alternative Names (SAN). Certificate information is displayed above. error: %s", err) + } + insecureClient := &http.Client{ + Timeout: time.Second * 5, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } + res, err := insecureClient.Get(server) + if err != nil { + logrus.Errorf("Could not connect to %s: %v", server, err) + os.Exit(1) + } + var lastFoundIssuer string + if res.TLS != nil && len(res.TLS.PeerCertificates) > 0 { + logrus.Infof("Certificate details from %s", serverURL) + var previouscert *x509.Certificate + for i := range res.TLS.PeerCertificates { + cert := res.TLS.PeerCertificates[i] + logrus.Infof("Certificate #%d (%s)", i, serverURL) + certinfo(cert) + if i > 0 { + if previouscert.Issuer.String() != cert.Subject.String() { + logrus.Errorf("Certficate's Subject (%s) does not match with previous certificate Issuer (%s). Please check if the configured server certificate contains all needed intermediate certificates and make sure they are in the correct order (server certificate first, intermediates after)", cert.Subject.String(), previouscert.Issuer.String()) + } + } + previouscert = cert + lastFoundIssuer = cert.Issuer.String() + } + } + if _, err := os.Stat(caFileLocation); err == nil { + caFile, err := ioutil.ReadFile(caFileLocation) + if err != nil { + return err + } + var blocks [][]byte + for { + var certDERBlock *pem.Block + certDERBlock, caFile = pem.Decode(caFile) + if certDERBlock == nil { + break + } + + if certDERBlock.Type == "CERTIFICATE" { + blocks = append(blocks, certDERBlock.Bytes) + } + } + if len(blocks) > 1 { + logrus.Warnf("Found %d certificates at %s, should be 1", len(blocks), caFileLocation) + } + logrus.Infof("Certificate details for %s", caFileLocation) + + blockcount := 0 + var lastCACert *x509.Certificate + for _, block := range blocks { + cert, err := x509.ParseCertificate(block) + if err != nil { + logrus.Println(err) + continue + } + + logrus.Infof("Certificate #%d (%s)", blockcount, caFileLocation) + certinfo(cert) + + blockcount = blockcount + 1 + lastCACert = cert + } + if lastFoundIssuer != lastCACert.Issuer.String() { + logrus.Errorf("Issuer of last certificate found in chain (%s) does not match with CA certificate Issuer (%s). Please check if the configured server certificate contains all needed intermediate certificates and make sure they are in the correct order (server certificate first, intermediates after)", lastFoundIssuer, lastCACert.Issuer.String()) + } + } + return certErr + } + } + } + + onConnect := func(ctx context.Context, _ *remotedialer.Session) error { + connected() + connectConfig := fmt.Sprintf("https://%s/v3/connect/config", serverURL.Host) + httpClient := http.Client{ + Timeout: 300 * time.Second, + } + if transport != nil { + httpClient.Transport = transport + } + interval, err := rkenodeconfigclient.ConfigClient(ctx, &httpClient, connectConfig, headers, writeCertsOnly) + if err != nil { + return err + } + + if writeCertsOnly { + exitCertWriter(ctx) + } + + if isCluster() { + err = rancher.Run(topContext) + if err != nil { + logrus.Fatal(err) + } + return nil + } + + if err := cleanup(context.Background()); err != nil { + logrus.Warnf("Unable to perform docker cleanup: %v", err) + } + + go func() { + logrus.Infof("Starting plan monitor, checking every %v seconds", interval) + tt := time.Duration(interval) * time.Second + for { + select { + case <-time.After(tt): + receivedInterval, err := rkenodeconfigclient.ConfigClient(ctx, &httpClient, connectConfig, headers, writeCertsOnly) + if err != nil { + logrus.Errorf("failed to check plan: %v", err) + } else if receivedInterval != 0 && receivedInterval != interval { + tt = time.Duration(receivedInterval) * time.Second + logrus.Infof("Plan monitor checking %v seconds", receivedInterval) + } + case <-ctx.Done(): + return + } + } + }() + + return nil + } + + if isCluster() { + go func() { + log.Println(http.ListenAndServe("localhost:6060", nil)) + }() + } + + for { + wsURL := fmt.Sprintf("wss://%s/v3/connect", serverURL.Host) + if !isConnect() { + wsURL += "/register" + } + + logrus.Infof("Connecting to %s with token starting with %s", wsURL, token[:len(token)/2]) + logrus.Tracef("Connecting to %s with token %s", wsURL, token) + remotedialer.ClientConnect(ctx, wsURL, headers, nil, func(proto, address string) bool { + switch proto { + case "tcp": + return true + case "unix": + return address == "/var/run/docker.sock" + case "npipe": + return address == "//./pipe/docker_engine" + } + return false + }, onConnect) + time.Sleep(5 * time.Second) + } +} + +func exitCertWriter(ctx context.Context) { + // share-mnt process needs an always restart policy and to be killed so it can restart on startup + // this functionality is really only needed for OSes with ephemeral /etc like RancherOS + // everything here will just exit(0) with errors as we need to bail out completely. + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGTERM) + // trap SIGTERM here so that container can exit with 0 + go func() { + <-sigs + os.Exit(0) + }() + + logrus.Info("attempting to stop the share-mnt container so it can reboot on startup") + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + logrus.Error(err) + os.Exit(0) + } + + args := filters.NewArgs() + args.Add("label", "io.rancher.rke.container.name=share-mnt") + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + logrus.Error(err) + os.Exit(0) + } + + for _, container := range containers { + if len(container.Names) > 0 && strings.Contains(container.Names[0], "share-mnt") { + err := c.ContainerKill(ctx, container.ID, "SIGTERM") + if err != nil { + logrus.Error(err) + os.Exit(0) // only need to write certs so exit cleanly + } + } + } + // wait for itself to be kill with SIGTERM so it can return exit 0 + select {} +} + +func certinfo(cert *x509.Certificate) { + logrus.Infof("Subject: %+v", cert.Subject) + logrus.Infof("Issuer: %+v", cert.Issuer) + logrus.Infof("IsCA: %+v", cert.IsCA) + if len(cert.DNSNames) > 0 { + logrus.Infof("DNS Names: %+v", cert.DNSNames) + } else { + logrus.Infof("DNS Names: ") + } + if len(cert.IPAddresses) > 0 { + logrus.Infof("IPAddresses: %+v", cert.IPAddresses) + } else { + logrus.Info("IPAddresses: ") + } + logrus.Infof("NotBefore: %+v", cert.NotBefore) + logrus.Infof("NotAfter: %+v", cert.NotAfter) + logrus.Infof("SignatureAlgorithm: %+v", cert.SignatureAlgorithm) + logrus.Infof("PublicKeyAlgorithm: %+v", cert.PublicKeyAlgorithm) +} + +// reconcileKubelet restarts kubelet in unmanaged agents +func reconcileKubelet(ctx context.Context) (bool, error) { + if os.Getenv("CATTLE_K8S_MANAGED") == "true" { + return true, nil + } + + writeCertsOnly := os.Getenv("CATTLE_WRITE_CERT_ONLY") == "true" + if writeCertsOnly { + return true, nil + } + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return false, err + } + defer c.Close() + + args := filters.NewArgs() + args.Add("label", "io.rancher.rke.container.name=kubelet") + + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + return false, err + } + + for _, container := range containers { + if len(container.Names) > 0 && strings.Contains(container.Names[0], "kubelet") { + nodeName := os.Getenv("CATTLE_NODE_NAME") + logrus.Infof("node %v is not registered, restarting kubelet now", nodeName) + if err := c.ContainerRestart(ctx, container.ID, nil); err != nil { + return false, err + } + break + } + } + return false, nil +} + +func configureLogrus() { + logrus.SetOutput(colorable.NewColorableStdout()) + + if os.Getenv("CATTLE_TRACE") == "true" || os.Getenv("RANCHER_TRACE") == "true" { + logrus.SetLevel(logrus.TraceLevel) + } else if os.Getenv("CATTLE_DEBUG") == "true" || os.Getenv("RANCHER_DEBUG") == "true" { + logrus.SetLevel(logrus.DebugLevel) + } +} + +// rootCATransport generates a http.Transport that contains the contents of the CA file as the Root CA for strict validation. +func rootCATransport() *http.Transport { + caFile, err := os.ReadFile(caFileLocation) + if err != nil { + logrus.Errorf("unable to read CA file from %s: %v", caFileLocation, err) + return nil + } + certPool := x509.NewCertPool() + if ok := certPool.AppendCertsFromPEM(caFile); !ok { + logrus.Errorf("unable to parse CA file %s", caFileLocation) + return nil + } + return &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certPool, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/code-of-conduct.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/code-of-conduct.md new file mode 100644 index 0000000..6aaa7e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/code-of-conduct.md @@ -0,0 +1,35 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering +an open and welcoming community, we pledge to respect all people who contribute +through reporting issues, posting feature requests, updating documentation, +submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for +everyone, regardless of level of experience, gender, gender identity and expression, +sexual orientation, disability, personal appearance, body size, race, ethnicity, age, +religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, + without explicit permission + * Other unethical or unprofessional conduct. + + Project maintainers have the right and responsibility to remove, edit, or reject + comments, commits, code, wiki edits, issues, and other contributions that are not + aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers + commit themselves to fairly and consistently applying these principles to every aspect + of managing this project. + + This code of conduct applies both within project spaces and in public spaces + when an individual is representing the project or its community. + + Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by + contacting a Rancher administrator on [Slack](https://slack.rancher.io), or . + + This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org). diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/helm-unittest.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/helm-unittest.sh new file mode 100755 index 0000000..ce29b5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/helm-unittest.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# note: requires helm-unittest (https://github.com/helm-unittest/helm-unittest) to be installed beforehand +# run in root of rancher - i.e. bash dev-scripts/helm-unittest.sh +# change automated parts of templates +test_image="rancher/rancher" +test_image_tag="v2.7.0" +sed -i -e "s/%VERSION%/${test_image_tag}/g" ./chart/Chart.yaml +sed -i -e "s/%APP_VERSION%/${test_image_tag}/g" ./chart/Chart.yaml +sed -i -e "s@%POST_DELETE_IMAGE_NAME%@${test_image}@g" ./chart/values.yaml +sed -i -e "s/%POST_DELETE_IMAGE_TAG%/${test_image_tag}/g" ./chart/values.yaml + +# test - need to be in the chart directory during the test so it can find Chart.yaml +cd chart +helm lint ./ +helm unittest ./ +cd .. + +# clean +git checkout chart/Chart.yaml chart/values.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/quick b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/quick new file mode 100755 index 0000000..c2ac686 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/dev-scripts/quick @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +## This script builds the Rancher server image exclusively, sans Dapper + +set -eo pipefail +set -x + +# variables +COMMIT=$(git rev-parse --short HEAD) +TAG="${TAG:-$(yq '.env.TAG | sub("-.*", "")' < .github/workflows/pull-request.yml)-${COMMIT}}" +OS="${OS:-linux}" +ARCH="${ARCH:-amd64}" +CATTLE_K3S_VERSION=$(grep -m1 'ENV CATTLE_K3S_VERSION' package/Dockerfile | awk '{print $3}') +CATTLE_KDM_BRANCH=$(grep -m1 'ARG CATTLE_KDM_BRANCH=' package/Dockerfile | cut -d '=' -f2) +RKE_VERSION=$(grep -m1 'github.com/rancher/rke' go.mod | awk '{print $2}') +if [[ -z "$RKE_VERSION" ]]; then + RKE_VERSION=$(grep -m1 'github.com/rancher/rke' go.mod | awk '{print $4}') +fi +CATTLE_RANCHER_WEBHOOK_VERSION=$(yq '.webhookVersion' < build.yaml) +CATTLE_CSP_ADAPTER_MIN_VERSION=$(yq '.cspAdapterMinVersion' < build.yaml) +CATTLE_FLEET_VERSION=$(yq '.fleetVersion' < build.yaml) + +# download airgap images and export it to a tarball +curl -Lf https://github.com/rancher/k3s/releases/download/${CATTLE_K3S_VERSION}/k3s-images.txt -o ./k3s-images.txt +AIRGAP_IMAGES=$(grep -e 'docker.io/rancher/mirrored-pause' -e 'docker.io/rancher/mirrored-coredns-coredns' ./k3s-images.txt) +xargs -n1 docker pull <<< "${AIRGAP_IMAGES}" +xargs -n2 docker save -o ./k3s-airgap-images.tar <<< "${AIRGAP_IMAGES}" + +# download kontainer driver metadata +curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${CATTLE_KDM_BRANCH}/data.json > ./data.json + +# start the builds +docker buildx build \ + --build-arg VERSION="${TAG}" \ + --build-arg ARCH=${ARCH} \ + --build-arg COMMIT="${COMMIT}" \ + --build-arg RKE_VERSION=${RKE_VERSION} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION=${CATTLE_RANCHER_WEBHOOK_VERSION} \ + --build-arg CATTLE_CSP_ADAPTER_MIN_VERSION=${CATTLE_CSP_ADAPTER_MIN_VERSION} \ + --build-arg CATTLE_FLEET_VERSION=${CATTLE_FLEET_VERSION} \ + --tag rancher/rancher:${TAG} \ + --platform="${OS}/${ARCH}" \ + --file ./package/Dockerfile . + +docker buildx build \ + --build-arg VERSION="${TAG}" \ + --build-arg ARCH=${ARCH} \ + --build-arg RANCHER_TAG=${TAG} \ + --build-arg RANCHER_IMAGE=rancher/rancher:${TAG} \ + --build-arg COMMIT="${COMMIT}" \ + --build-arg RKE_VERSION=${RKE_VERSION} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION=${CATTLE_RANCHER_WEBHOOK_VERSION} \ + --tag rancher/rancher-agent:${TAG} \ + --platform="${OS}/${ARCH}" \ + --file ./package/Dockerfile.agent . diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/build.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/build.md new file mode 100644 index 0000000..1558859 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/build.md @@ -0,0 +1,69 @@ +## Build and package configuration + +Build variables should be defined in a single file, +so that anyone who wants to build Rancher needs to only edit this file to change configuration and dependency versions. + +Rancher relies on various subcomponents, such as the webhook. +These typically need to have set versions for Rancher to build and run properly. +Build variables can be used in different places and supplied to the applications in a variety of ways, +including as environment variables in Dockerfiles, constants in Go code, and so on. + +The [build.yaml](../build.yaml) file is the single source of truth. It lists all values by name and value. +Changes to it should be committed to source control. + +### Update an existing value + +Edit the [build.yaml](../build.yaml) file and update the desired value. Run `go generate`. Commit any changes to source +control. To test locally, re-build Rancher with `make build` or re-package it with `make package`. + +### Add a new value + +To add a new value, do the following once. + +Add it to [build.yaml](../build.yaml). For example: + +``` +webhookVersion: 2.0.6+up0.3.6-rc1 +``` + +Then update the [export-config](../scripts/export-config) script. + +``` +CATTLE_RANCHER_WEBHOOK_VERSION=$(yq -e '.webhookVersion' "$file") +export CATTLE_RANCHER_WEBHOOK_VERSION +``` + +Run `go generate` from the root of the repo. + +Now you can refer to the value wherever you need it. + +#### Refer to the new value + +If a new configuration value is an environment variable for a Dockerfile, capture it as an `ARG` and `ENV`. For example: + +``` +ARG CATTLE_FLEET_VERSION +ENV CATTLE_FLEET_VERSION=$CATTLE_FLEET_VERSION +``` + +Then pass it as via `docker build --build-arg MYVAR="$MYVAR" ...` + +If a new configuration value is a regular string outside Dockerfiles, refer to the corresponding constant found in the +generated Go [file](../pkg/buildconfig/constants.go). For example: + +```NewSetting("shell-image", buildconfig.DefaultShellVersion)``` + +The following are examples of files that often refer to newly added configuration values: + +- [build-server](../scripts/build-server) +- [build-agent](../scripts/build-agent) +- [quick](../dev-scripts/quick) +- [Dockerfile](../package/Dockerfile) +- [Dockerfile.agent](../package/Dockerfile.agent) +- [pkg/settings/setting.go](../pkg/settings/setting.go) + +### The build.yaml file + +It's better to follow the standard Kubernetes convention of preferring camelCase keys in the YAML file. + +The exported resulting environment variables should be like standard ENV_VARS. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/development.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/development.md new file mode 100644 index 0000000..53bb964 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/docs/development.md @@ -0,0 +1,31 @@ +# Developing Rancher + +## Generate a local container image + +If you need to test some changes in a container image before they make it to a +pull request, you can use the handy `make quick` script. + +This script uses `docker buildx` in order to enable cross-building of different +architecture images. To build an image for your current OS and architecture, run +from the Rancher project root: +```shell +TAG="localhost:5000/my-test-repo/image:tag" make quick +``` + +If you wish to cross-build for a different architecture, set the variable `ARCH`: +```shell +TAG="localhost:5000/my-test-repo/image:tag" \ + ARCH="amd64" \ + make quick +``` + +## Deploy your custom image via Helm + +To deploy a custom image via Helm, set the variables `rancherImage` and `rancherImageTag`: +```shell +helm upgrade --install rancher/rancher \ + --namespace cattle-system \ + --create-namespace \ + --set rancherImage="my-test-repo/image" \ + --set rancherImageTag="dev-tag" +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/generate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/generate.go new file mode 100644 index 0000000..6e986ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/generate.go @@ -0,0 +1,5 @@ +//go:generate go run pkg/codegen/buildconfig/writer.go pkg/codegen/buildconfig/main.go +//go:generate go run pkg/codegen/generator/cleanup/main.go +//go:generate go run pkg/codegen/main.go +//go:generate scripts/build-crds +package main diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.mod b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.mod new file mode 100644 index 0000000..2d84002 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.mod @@ -0,0 +1,436 @@ +module github.com/rancher/rancher + +go 1.22.0 + +toolchain go1.22.3 + +replace ( + github.com/containerd/containerd => github.com/containerd/containerd v1.6.27 // for compatibilty with docker 20.10.x + github.com/docker/distribution => github.com/docker/distribution v2.8.2+incompatible // rancher-machine requires a replace is set + github.com/docker/docker => github.com/docker/docker v20.10.27+incompatible // rancher-machine requires a repalce is set + + github.com/knative/pkg => github.com/rancher/pkg v0.0.0-20190514055449-b30ab9de040e + github.com/matryer/moq => github.com/rancher/moq v0.0.0-20200712062324-13d1f37d2d77 + + github.com/rancher/rancher/pkg/apis => ./pkg/apis + github.com/rancher/rancher/pkg/client => ./pkg/client + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 + go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.19.0 + go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v1.19.0 + go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v1.19.0 + go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.19.0 + go.opentelemetry.io/proto/otlp => go.opentelemetry.io/proto/otlp v1.0.0 + go.qase.io/client => github.com/rancher/qase-go/client v0.0.0-20231114201952-65195ec001fa + + helm.sh/helm/v3 => github.com/rancher/helm/v3 v3.15.1-rancher2 + k8s.io/api => k8s.io/api v0.30.1 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.1 + k8s.io/apimachinery => k8s.io/apimachinery v0.30.1 + k8s.io/apiserver => k8s.io/apiserver v0.30.1 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.1 + k8s.io/client-go => k8s.io/client-go v0.30.1 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.1 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.30.1 + k8s.io/code-generator => k8s.io/code-generator v0.30.1 + k8s.io/component-base => k8s.io/component-base v0.30.1 + k8s.io/component-helpers => k8s.io/component-helpers v0.30.1 + k8s.io/controller-manager => k8s.io/controller-manager v0.30.1 + k8s.io/cri-api => k8s.io/cri-api v0.30.1 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.1 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.30.1 + k8s.io/endpointslice => k8s.io/endpointslice v0.30.1 + k8s.io/kms => k8s.io/kms v0.30.1 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.30.1 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.30.1 + k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.30.1 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.30.1 + k8s.io/kubectl => k8s.io/kubectl v0.30.1 + k8s.io/kubelet => k8s.io/kubelet v0.30.1 + k8s.io/kubernetes => k8s.io/kubernetes v1.30.1 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.30.1 + k8s.io/metrics => k8s.io/metrics v0.30.1 + k8s.io/mount-utils => k8s.io/mount-utils v0.30.1 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.30.1 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.30.1 + oras.land/oras-go => oras.land/oras-go v1.2.2 // for docker 20.10.x compatibility + sigs.k8s.io/cluster-api => sigs.k8s.io/cluster-api v1.7.3 +) + +require ( + github.com/antihax/optional v1.0.0 + github.com/rancher/rancher/pkg/apis v0.0.0-20240719121207-baeda6b89fe3 + github.com/rancher/shepherd v0.0.0-20240802211915-de6445cd2559 + go.qase.io/client v0.0.0-20231114201952-65195ec001fa +) + +require ( + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.1.1 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 + github.com/Azure/go-autorest/autorest v0.11.29 + github.com/Azure/go-autorest/autorest/adal v0.9.23 + github.com/Azure/go-autorest/autorest/to v0.4.1-0.20240104002855-4c0e21ca2bbb + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 + github.com/Masterminds/semver/v3 v3.2.1 + github.com/Masterminds/sprig/v3 v3.2.3 + github.com/aws/aws-sdk-go v1.50.38 + github.com/aws/aws-sdk-go-v2 v1.30.3 + github.com/aws/aws-sdk-go-v2/service/eks v1.47.0 + github.com/bep/debounce v1.2.1 + github.com/blang/semver v3.5.1+incompatible + github.com/coreos/go-iptables v0.6.0 + github.com/coreos/go-oidc/v3 v3.9.0 + github.com/coreos/go-semver v0.3.1 + github.com/creasty/defaults v1.5.2 + github.com/crewjam/saml v0.4.14 + github.com/docker/distribution v2.8.3+incompatible + github.com/docker/docker v25.0.3+incompatible + github.com/docker/go-connections v0.5.0 + github.com/ehazlett/simplelog v0.0.0-20200226020431-d374894e92a4 + github.com/evanphx/json-patch v5.7.0+incompatible + github.com/ghodss/yaml v1.0.0 + github.com/go-git/go-git/v5 v5.12.0 + github.com/go-ldap/ldap/v3 v3.4.1 + github.com/golang-jwt/jwt v3.2.1+incompatible + github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/golang/mock v1.6.0 + github.com/golang/protobuf v1.5.4 + github.com/google/gnostic-models v0.6.8 + github.com/google/go-containerregistry v0.19.0 + github.com/gorilla/mux v1.8.1 + github.com/gorilla/websocket v1.5.1 + github.com/hashicorp/golang-lru v1.0.2 + github.com/heptio/authenticator v0.0.0-20180409043135-d282f87a1972 + github.com/mattn/go-colorable v0.1.13 + github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 + github.com/microsoft/kiota-abstractions-go v1.0.0 + github.com/microsoftgraph/msgraph-sdk-go v1.0.0 + github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0 + github.com/minio/minio-go/v7 v7.0.10 + github.com/mitchellh/mapstructure v1.5.0 + github.com/moby/locker v1.0.1 + github.com/opencontainers/go-digest v1.0.0 + github.com/opencontainers/image-spec v1.1.0 + github.com/oracle/oci-go-sdk v18.0.0+incompatible + github.com/pborman/uuid v1.2.1 + github.com/pkg/errors v0.9.1 + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.52.0 + github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_model v0.5.0 + github.com/prometheus/common v0.45.0 + github.com/rancher/aks-operator v1.9.1 + github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146 + github.com/rancher/channelserver v0.7.0 + github.com/rancher/dynamiclistener v0.6.0 + github.com/rancher/eks-operator v1.9.1 + github.com/rancher/fleet/pkg/apis v0.10.0 + github.com/rancher/gke-operator v1.9.1 + github.com/rancher/kubernetes-provider-detector v0.1.5 + github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 + github.com/rancher/machine v0.15.0-rancher116 + github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 + github.com/rancher/rancher/pkg/client v0.0.0 + github.com/rancher/remotedialer v0.4.0 + github.com/rancher/rke v1.6.1 + github.com/rancher/steve v0.0.0-20240806133920-61be17faa3d2 + github.com/rancher/system-upgrade-controller/pkg/apis v0.0.0-20210727200656-10b094e30007 + github.com/rancher/wrangler/v3 v3.0.0 + github.com/robfig/cron v1.2.0 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.9.0 + github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 + github.com/urfave/cli v1.22.14 + github.com/vishvananda/netlink v1.2.1-beta.2 + github.com/vmware/govmomi v0.30.6 + go.uber.org/mock v0.4.0 + golang.org/x/crypto v0.25.0 + golang.org/x/mod v0.19.0 + golang.org/x/net v0.27.0 + golang.org/x/oauth2 v0.22.0 + golang.org/x/sync v0.7.0 + golang.org/x/text v0.16.0 + google.golang.org/api v0.153.0 + google.golang.org/grpc v1.59.0 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/natefinch/lumberjack.v2 v2.2.1 + gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 + helm.sh/helm/v3 v3.15.1 + k8s.io/api v0.30.2 + k8s.io/apiextensions-apiserver v0.30.1 + k8s.io/apimachinery v0.30.2 + k8s.io/apiserver v0.30.1 + k8s.io/cli-runtime v0.30.1 + k8s.io/client-go v12.0.0+incompatible + k8s.io/helm v2.16.9+incompatible + k8s.io/kube-aggregator v0.30.1 + k8s.io/kubectl v0.30.1 + k8s.io/kubernetes v1.30.1 + k8s.io/utils v0.0.0-20240102154912-e7106e64919e + oras.land/oras-go/v2 v2.4.0 + sigs.k8s.io/aws-iam-authenticator v0.6.17 + sigs.k8s.io/cluster-api v1.7.3 + sigs.k8s.io/controller-runtime v0.18.4 + sigs.k8s.io/yaml v1.4.0 +) + +require ( + cloud.google.com/go/compute/metadata v0.3.0 // indirect + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights v1.2.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/aws/aws-sdk-go-v2/config v1.27.27 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.27 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect + github.com/aws/aws-sdk-go-v2/service/cloudformation v1.53.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ec2 v1.173.0 // indirect + github.com/aws/aws-sdk-go-v2/service/iam v1.34.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect + github.com/aws/smithy-go v1.20.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cjlapao/common-go v0.0.39 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/cgroups/v3 v3.0.2 // indirect + github.com/containerd/errdefs v0.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/distribution/reference v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect + github.com/google/cel-go v0.17.8 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/kr/fs v0.1.0 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/microsoft/kiota-authentication-azure-go v1.0.0 // indirect + github.com/microsoft/kiota-http-go v1.0.0 // indirect + github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect + github.com/microsoft/kiota-serialization-json-go v1.0.0 // indirect + github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/rancher/wrangler v1.1.2 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 // indirect + go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4 // indirect + k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect + k8s.io/pod-security-admission v0.30.1 // indirect + modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect + modernc.org/libc v1.49.3 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/sqlite v1.29.10 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect +) + +require ( + github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect + github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/autorest/validation v0.3.2-0.20210111195520-9fc88b15294e // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/squirrel v1.5.4 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/Microsoft/hcsshim v0.12.0-rc.3 // indirect + github.com/adrg/xdg v0.4.0 // indirect + github.com/apparentlymart/go-cidr v1.1.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/beevik/etree v1.1.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/containerd/containerd v1.7.12 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/cyphar/filepath-securejoin v0.2.5 + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dimchansky/utfbom v1.1.1 // indirect + github.com/docker/cli v25.0.3+incompatible // indirect + github.com/docker/docker-credential-helpers v0.8.1 // indirect + github.com/docker/go-metrics v0.0.1 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect + github.com/fatih/camelcase v1.0.0 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fvbommel/sortorder v1.1.0 // indirect + github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect + github.com/go-errors/errors v1.4.2 // indirect + github.com/go-gorp/gorp/v3 v3.1.0 // indirect + github.com/go-ini/ini v1.67.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.10 // indirect + github.com/gobuffalo/flect v1.0.2 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-github/v29 v29.0.3 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gosuri/uitable v0.0.4 // indirect + github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-version v1.6.0 + github.com/huandu/xstrings v1.4.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.7 // indirect + github.com/klauspost/cpuid v1.3.1 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matryer/moq v0.3.4 // indirect + github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/minio/md5-simd v1.1.0 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/mount v0.3.3 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/onsi/gomega v1.34.1 // indirect + github.com/opencontainers/runc v1.1.12 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/sftp v1.13.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rancher/cis-operator v1.0.11 + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rs/xid v1.2.1 // indirect + github.com/rubenv/sql-migrate v1.5.2 // indirect + github.com/russellhaering/goxmldsig v1.3.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/vishvananda/netns v0.0.4 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect + github.com/xlab/treeprint v1.2.0 // indirect + github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 // indirect + github.com/yvasiyarov/gorelic v0.0.7 // indirect + github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 // indirect + go.etcd.io/etcd/api/v3 v3.5.13 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.13 // indirect + go.etcd.io/etcd/client/v2 v2.305.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.13 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.0 // indirect + go.opentelemetry.io/otel v1.20.0 // indirect + go.opentelemetry.io/otel/metric v1.20.0 // indirect + go.opentelemetry.io/otel/sdk v1.20.0 // indirect + go.opentelemetry.io/otel/trace v1.20.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.23.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + k8s.io/cluster-bootstrap v0.29.3 // indirect + k8s.io/code-generator v0.30.1 // indirect + k8s.io/component-base v0.30.1 // indirect + k8s.io/component-helpers v0.30.1 // indirect + k8s.io/klog v1.0.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 // indirect + oras.land/oras-go v1.2.4 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 // indirect + sigs.k8s.io/cli-utils v0.35.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.sum b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.sum new file mode 100644 index 0000000..0481a17 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/go.sum @@ -0,0 +1,3040 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= +cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= +cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= +cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM= +cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= +cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= +cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= +cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= +cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= +cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 h1:GJHeeA2N7xrG3q30L2UXDyuWRzDM900/65j70wcM4Ww= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0 h1:ui3YNbxfW7J3tTFIZMH6LIGRjCngp+J+nIFlnizfNTE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.6.0/go.mod h1:gZmgV+qBqygoznvqo2J9oKZAFziqhLZ2xE/WVUmzkHA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 h1:0nGmzwBv5ougvzfGPCO2ljFRHvun57KpNrVCMrlk0ns= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0/go.mod h1:gYq8wyDgv6JLhGbAU6gg8amCPgQWRE+aCvrV2gyzdfs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0/go.mod h1:HcZY0PHPo/7d75p99lB6lK0qYOP4vLRJUBpiehYXtLQ= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.1.1 h1:QZY6o3E/KX0QhgQpvat4UxAsXuBIb4efrFtZcqCUTbs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.1.1/go.mod h1:8gv2PVzO0a+f4aWpe940Ouz0r4ifLj8H+/jxRXgwPxg= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights v1.2.0 h1:4FlNvfcPu7tTvOgOzXxIbZLvwvmZq1OdhQUdIa9g2N4= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights v1.2.0/go.mod h1:A4nzEXwVd5pAyneR6KOvUAo72svUc5rmCzRHhAbP6lA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= +github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/autorest/to v0.4.1-0.20240104002855-4c0e21ca2bbb h1:QvqY5WysgpoF6Jeve74w7OX5gaKMvd5s2TKhsZwWHV4= +github.com/Azure/go-autorest/autorest/to v0.4.1-0.20240104002855-4c0e21ca2bbb/go.mod h1:DSh3VxN6gfEglfL5RXwMuwLQrHEayq9JF/NUe+DkxCI= +github.com/Azure/go-autorest/autorest/validation v0.3.2-0.20210111195520-9fc88b15294e h1:HoowCmmnS+grm3frwGZE+1tXa4ssmy1lgSac+BfteTg= +github.com/Azure/go-autorest/autorest/validation v0.3.2-0.20210111195520-9fc88b15294e/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= +github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= +github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.12.0-rc.3 h1:5GNGrobGs/sN/0nFO21W9k4lFn+iXXZAE8fCZbmdRak= +github.com/Microsoft/hcsshim v0.12.0-rc.3/go.mod h1:WuNfcaYNaw+KpCEsZCIM6HCEmu0c5HfXpi+dDSmveP0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= +github.com/alecthomas/kingpin/v2 v2.3.2/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= +github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.50.38 h1:h8wxaLin7sFGK4sKassc1VpNcDbgAAEQJ5PHjqLAvXQ= +github.com/aws/aws-sdk-go v1.50.38/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= +github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= +github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= +github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/service/cloudformation v1.53.3 h1:mIpL+FXa+2U6oc85b/15JwJhNUU+c/LHwxM3hpQIxXQ= +github.com/aws/aws-sdk-go-v2/service/cloudformation v1.53.3/go.mod h1:lcQ7+K0Q9x0ozhjBwDfBkuY8qexSP/QXLgp0jj+/NZg= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.173.0 h1:ta62lid9JkIpKZtZZXSj6rP2AqY5x1qYGq53ffxqD9Q= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.173.0/go.mod h1:o6QDjdVKpP5EF0dp/VlvqckzuSDATr1rLdHt3A5m0YY= +github.com/aws/aws-sdk-go-v2/service/eks v1.47.0 h1:u0VeIQ02COfhmp37ub8zv29bdRtosCYzXoWd+QRebbY= +github.com/aws/aws-sdk-go-v2/service/eks v1.47.0/go.mod h1:awleuSoavuUt32hemzWdSrI47zq7slFtIj8St07EXpE= +github.com/aws/aws-sdk-go-v2/service/iam v1.34.3 h1:p4L/tixJ3JUIxCteMGT6oMlqCbEv/EzSZoVwdiib8sU= +github.com/aws/aws-sdk-go-v2/service/iam v1.34.3/go.mod h1:rfOWxxwdecWvSC9C2/8K/foW3Blf+aKnIIPP9kQ2DPE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= +github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= +github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= +github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bugsnag/bugsnag-go v2.1.2+incompatible h1:E7dor84qzwUO8KdCM68CZwq9QOSR7HXlLx3Wj5vui2s= +github.com/bugsnag/bugsnag-go v2.1.2+incompatible/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20160118154447-aceac81c6e2f h1:7+HZb3PwI0cCUETyMDgPCvSta1y3idwBL8PHwSgelJk= +github.com/bugsnag/panicwrap v0.0.0-20160118154447-aceac81c6e2f/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cjlapao/common-go v0.0.39 h1:bAAUrj2B9v0kMzbAOhzjSmiyDy+rd56r2sy7oEiQLlA= +github.com/cjlapao/common-go v0.0.39/go.mod h1:M3dzazLjTjEtZJbbxoA5ZDiGCiHmpwqW9l4UWaddwOA= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= +github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= +github.com/containerd/containerd v1.6.27 h1:xGPieCivG5JfO6Sm4XYml/aruv0ru39gN4Wtl7tqeIA= +github.com/containerd/containerd v1.6.27/go.mod h1:uWjQMLorvbCqqDRTte+n8HnW82DIaT7mhvAiB1rOez4= +github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= +github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= +github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= +github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo= +github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creasty/defaults v1.5.2 h1:/VfB6uxpyp6h0fr7SPp7n8WJBoV8jfxQXPCnkVSjyls= +github.com/creasty/defaults v1.5.2/go.mod h1:FPZ+Y0WNrbqOVw+c6av63eyHUAl6pMHZwqLPvXUZGfY= +github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= +github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2 h1:aBfCb7iqHmDEIp6fBvC/hQUddQfg+3qdYjwzaiP9Hnc= +github.com/distribution/distribution/v3 v3.0.0-20221208165359-362910506bc2/go.mod h1:WHNsWjnIn2V1LYOrME7e8KxSeKunYHsxEm4am0BUtcI= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/cli v25.0.3+incompatible h1:KLeNs7zws74oFuVhgZQ5ONGZiXUUdgsdy6/EsX/6284= +github.com/docker/cli v25.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.27+incompatible h1:Id/ZooynV4ZlD6xX20RCd3SR0Ikn7r4QZDa2ECK2TgA= +github.com/docker/docker v20.10.27+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= +github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ehazlett/simplelog v0.0.0-20200226020431-d374894e92a4 h1:v9kqlO59x6QpNXctFc+yiWy6dUb+x5x8e9uPUAu1Taw= +github.com/ehazlett/simplelog v0.0.0-20200226020431-d374894e92a4/go.mod h1:m8BGliBtT1XxrkLygibAe1L4gWruiNqNUmukTUwGlcY= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI= +github.com/foxcpp/go-mockdns v1.0.0/go.mod h1:lgRN6+KxQBawyIghpnl5CezHFGS9VLzvtVlwxvzXTQ4= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= +github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= +github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag= +github.com/go-asn1-ber/asn1-ber v1.5.3/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= +github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= +github.com/go-ldap/ldap/v3 v3.4.1 h1:fU/0xli6HY02ocbMuozHAYsaHLcnkLjvho2r5a34BUU= +github.com/go-ldap/ldap/v3 v3.4.1/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.10 h1:4y86NVn7Z2yYd6pfS4Z+Nyh3aAUL3Nul+LMbhFKy0gA= +github.com/go-openapi/swag v0.22.10/go.mod h1:Cnn8BYtRlx6BNE3DPN86f/xkapGIcLWzh3CLEb4C1jI= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= +github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU= +github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs= +github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0= +github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= +github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= +github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= +github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= +github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic= +github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= +github.com/google/go-github/v29 v29.0.3 h1:IktKCTwU//aFHnpA+2SLIi7Oo9uhAzgsdZNbcAqhgdc= +github.com/google/go-github/v29 v29.0.3/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= +github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/heptio/authenticator v0.0.0-20180409043135-d282f87a1972 h1:Bah0yCXJwqJ7v2QLGdwkQoI/PBXYIBSkyTfirp6nbRk= +github.com/heptio/authenticator v0.0.0-20180409043135-d282f87a1972/go.mod h1:Q86X8hc61JXhE5XxYLKmrSRWby/Oe8IIYZIBgmGVkTA= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= +github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s= +github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= +github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= +github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= +github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= +github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg= +github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= +github.com/microsoft/kiota-abstractions-go v1.0.0 h1:teQS3yOmcTyps+O48AD17LI8TR1B3wCEwGFcwC6K75c= +github.com/microsoft/kiota-abstractions-go v1.0.0/go.mod h1:2yaRQnx2KU7UaenYSApiTT4pf7fFkPV0B71Rm2uYynQ= +github.com/microsoft/kiota-authentication-azure-go v1.0.0 h1:29FNZZ/4nnCOwFcGWlB/sxPvWz487HA2bXH8jR5k2Rk= +github.com/microsoft/kiota-authentication-azure-go v1.0.0/go.mod h1:rnx3PRlkGdXDcA/0lZQTbBwyYGmc+3POt7HpE/e4jGw= +github.com/microsoft/kiota-http-go v1.0.0 h1:F1hd6gMlLeEgH2CkRB7z13ow7LxMKMWEmms/t0VfS+k= +github.com/microsoft/kiota-http-go v1.0.0/go.mod h1:eujxJliqodotsYepIc6ihhK+vXMMt5Q8YiSNL7+7M7U= +github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= +github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= +github.com/microsoft/kiota-serialization-json-go v1.0.0 h1:snT+SwS/R4CMjkmj7mjCHrmib2nKWqGvUWaedgliMbI= +github.com/microsoft/kiota-serialization-json-go v1.0.0/go.mod h1:psfgIfqWm/9P1JAdl2cxHHIg9SdEtYHOetfDLIQ5/dw= +github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA= +github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M= +github.com/microsoftgraph/msgraph-sdk-go v1.0.0 h1:dGh406Loi5CoQ1VsoBkbi+mlozu58eT65YzoYsWX3Sk= +github.com/microsoftgraph/msgraph-sdk-go v1.0.0/go.mod h1:GvurB1XYl22Ralx3wlQZUTOwPnZ55RoTfbRNIStgj94= +github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0 h1:7NWTfyXvOjoizW7PmxNp3+8wCKPgpODs/D1cUZ3fkAY= +github.com/microsoftgraph/msgraph-sdk-go-core v1.0.0/go.mod h1:tQb4q3YMIj2dWhhXhQSJ4ELpol931ANKzHSYK5kX1qE= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= +github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= +github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4= +github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= +github.com/minio/minio-go/v7 v7.0.10 h1:1oUKe4EOPUEhw2qnPQaPsJ0lmVTYLFu03SiItauXs94= +github.com/minio/minio-go/v7 v7.0.10/go.mod h1:td4gW1ldOsj1PbSNS+WYK43j+P1XVhX/8W8awaYlBFo= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs= +github.com/moby/sys/mount v0.3.3/go.mod h1:PBaEorSNTLG5t/+4EgukEQVlAvVEc6ZjTySwKdqp5K0= +github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= +github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= +github.com/onsi/ginkgo/v2 v2.9.0/go.mod h1:4xkjoL/tZv4SMWeww56BU5kAt19mVB47gTWxmrTcxyk= +github.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw= +github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= +github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.27.7/go.mod h1:1p8OOlwo2iUUDsHnOrjE5UKYJ+e3W8eQ3qSlRahPmr4= +github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/oracle/oci-go-sdk v18.0.0+incompatible h1:FLV4KixsVfF3rwyVTMI6Ryp/Q+OSb9sR5TawbfjFLN4= +github.com/oracle/oci-go-sdk v18.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= +github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pkg/sftp v1.13.5 h1:a3RLUqkyjYRtBTZJZ1VRrKbN3zhuPLlUc3sphVz81go= +github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= +github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= +github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.52.0 h1:ANs+jxSJz7Xylkw9GGrN7IFaVrEjhDyeRqikccPXbW8= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.52.0/go.mod h1:f7HML3SGY4Bf10YMdSWKUf2BdIIzQqlAvYh84px05BQ= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rancher/aks-operator v1.9.1 h1:ARxafxU3c51V91BeCB1w94n3yjrKjjzQrqd/tWrd1go= +github.com/rancher/aks-operator v1.9.1/go.mod h1:RbGSV11kCpSjmSiX+WDiExBRQxnF/oRUdlmeAg9PqNA= +github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146 h1:6I4Z7PAGmned9+EYxbMS7kvajId3r8+ZwAR5wB7X3kg= +github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146/go.mod h1:ZNk+LcRGwQYHqgbsJijRrI49KFbX31/QzoUBq4rAeV0= +github.com/rancher/channelserver v0.7.0 h1:ZN5o8aD4mD31uhjEEW2e9yQXa3eOb+4Cp6DcWm7W/Lc= +github.com/rancher/channelserver v0.7.0/go.mod h1:Mwd7hlMSu9X4FnZKj+0mA5ak8nTyJZtZsVX33G62Gzc= +github.com/rancher/cis-operator v1.0.11 h1:3fOkwk45no0S9NaGFYgIINqxjBChqvvGhXWY/ZPGGDM= +github.com/rancher/cis-operator v1.0.11/go.mod h1:tSfpBeEcxYizMRT+rPtvQebJ5CcSJCKL9LW16Zdm7Zc= +github.com/rancher/dynamiclistener v0.6.0 h1:M7x8Nq+GY0UORULANuW/AH1ocnyZaqlmTuviMQAHL1Q= +github.com/rancher/dynamiclistener v0.6.0/go.mod h1:7VNEQhAwzbYJ08S1MYb6B4vili6K7CcrG4cNZXq1j+s= +github.com/rancher/eks-operator v1.9.1 h1:o0K2jcEdlrERRuIyC/CVZkRW++EcCa6GbVidBEfFh0w= +github.com/rancher/eks-operator v1.9.1/go.mod h1:vMQSu6MQqLkuilXcv+KKlL15sFBg24TZQUifVgoDmIc= +github.com/rancher/fleet/pkg/apis v0.10.0 h1:0f8OEghEDJNzvUAR2fpg2dw8EnAgfWvkhnwsYFS9G+w= +github.com/rancher/fleet/pkg/apis v0.10.0/go.mod h1:mjirthAmgpz0xo+qywUiaJDFpjnmX3xrc2E0/qmk3yc= +github.com/rancher/gke-operator v1.9.1 h1:COsXcgo10QEXMzju9zuGFBA+muvHfIiaTXpRz9dwQ2I= +github.com/rancher/gke-operator v1.9.1/go.mod h1:D/U7p7NpQtZcdHFWM+uBOmtk9/tVdlZv7BgR+TIiMAI= +github.com/rancher/helm/v3 v3.15.1-rancher2 h1:yrMhOjghReT3O+xt/Yb6hhmZgQrgWgBWJ2kOm8j6RNA= +github.com/rancher/helm/v3 v3.15.1-rancher2/go.mod h1:fvfoRcB8UKRUV5jrIfOTaN/pG1TPhuqSb56fjYdTKXg= +github.com/rancher/kubernetes-provider-detector v0.1.5 h1:hWRAsWuJOemzGjz/XrbTlM7QmfO4OedvFE3QwXiH60I= +github.com/rancher/kubernetes-provider-detector v0.1.5/go.mod h1:ypuJS7kP7rUiAn330xG46mj+Nhvym05GM8NqMVekpH0= +github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 h1:vv1jDlYbd4KhGbPNxmjs8CYgEHUrQm2bMtmULfXJ6iw= +github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1/go.mod h1:A/y3BLQkxZXYD60MNDRwAG9WGxXfvd6Z6gWR/a8wPw8= +github.com/rancher/machine v0.15.0-rancher116 h1:h8wHlVZYlNqHvD+FLH9ShpoB1V0WxQysfxym4QmSd3g= +github.com/rancher/machine v0.15.0-rancher116/go.mod h1:k/WZ5Pl9xDlo8ihRymBuxlsGLAQ3FHqm4d3+zBe2HJE= +github.com/rancher/moq v0.0.0-20200712062324-13d1f37d2d77 h1:k+vzmkZQsH06rZnDr+phskSixG9ByNj9gVdzHcc8nxw= +github.com/rancher/moq v0.0.0-20200712062324-13d1f37d2d77/go.mod h1:wpITyDPTi/Na5h73XkbuEf2AP9fbgrIGqqxVzFhYD6U= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 h1:AlRMRs5mHJcdiK83KKJyFVeybPMZ7dOUzC0l3k9aUa8= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9/go.mod h1:dyjfXBsNiroPWOdUZe7diUOUSLf6HQ/r2kEpwH/8zas= +github.com/rancher/qase-go/client v0.0.0-20231114201952-65195ec001fa h1:/qeYlQVfyvsO5yY0dZmm7mRTAsDm54jACiRDx3LAwsA= +github.com/rancher/qase-go/client v0.0.0-20231114201952-65195ec001fa/go.mod h1:NP3xboG+t2p+XMnrcrJ/L384Ki0Cp3Pww/X+vm5Jcy0= +github.com/rancher/remotedialer v0.4.0 h1:T9yC5bFMsZFVQ6rK0dNrRg6rRb6Zr/4vsig8S0IJ7ak= +github.com/rancher/remotedialer v0.4.0/go.mod h1:Ys004RpJuTLSm+k4aYUCoFiOOad37ubYev3TkOFg/5w= +github.com/rancher/rke v1.6.1 h1:ipktVDW1Xcs2SIR4vB9vCxH09kVrfD+1RmcUtWIPUV8= +github.com/rancher/rke v1.6.1/go.mod h1:5xRbf3L8PxqJRhABjYRfaBqbpVqAnqyH3maUNQEuwvk= +github.com/rancher/shepherd v0.0.0-20240802211915-de6445cd2559 h1:spcv+Px56tSR/hcx1QbL0NDZWQGHqlLi+F+VdiOfChM= +github.com/rancher/shepherd v0.0.0-20240802211915-de6445cd2559/go.mod h1:7qf+6wlqrQ2Bver/WPCFrT6ZnC0V3KLllOmd1pr8Was= +github.com/rancher/steve v0.0.0-20240806133920-61be17faa3d2 h1:mmm2uQ1NsNCrr6jxq9eAdGxvaf+6061gV4BMvuhcT6I= +github.com/rancher/steve v0.0.0-20240806133920-61be17faa3d2/go.mod h1:Za4nSt0V6kIHRfUo6jTXKkv6ABMMCHINA8EzhzygCfk= +github.com/rancher/system-upgrade-controller/pkg/apis v0.0.0-20210727200656-10b094e30007 h1:ru+mqGnxMmKeU0Q3XIDxkARvInDIqT1hH2amTcsjxI4= +github.com/rancher/system-upgrade-controller/pkg/apis v0.0.0-20210727200656-10b094e30007/go.mod h1:Ja346o44aTPWADc/5Jm93+KgctT6KtftuOosgz0F2AM= +github.com/rancher/wrangler v0.6.1/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4= +github.com/rancher/wrangler v1.1.2 h1:oXbXo9k7y/H4drUpb4RM1c++vT9O3rpoNEfyusGykiU= +github.com/rancher/wrangler v1.1.2/go.mod h1:2k9MyhlBdjcutcBGoOJSUAz0HgDAXnMjv81d3n/AaQc= +github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA= +github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= +github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= +github.com/russellhaering/goxmldsig v1.3.0 h1:DllIWUgMy0cRUMfGiASiYEa35nsieyD3cigIwLonTPM= +github.com/russellhaering/goxmldsig v1.3.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= +github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= +github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= +github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= +github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= +github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vmware/govmomi v0.30.6 h1:O3tjSwQBy0XwI5uK1/yVIfQ1LP9bAECEDUfifnyGs9U= +github.com/vmware/govmomi v0.30.6/go.mod h1:epgoslm97rLECMV4D+08ORzUBEU7boFSepKjt7AYVGg= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= +github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 h1:p7OofyZ509h8DmPLh8Hn+EIIZm/xYhdZHJ9GnXHdr6U= +github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.7 h1:4DTF1WOM2ZZS/xMOkTFBOcb6XiHu/PKn3rVo6dbewQE= +github.com/yvasiyarov/gorelic v0.0.7/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 h1:AsFN8kXcCVkUFHyuzp1FtYbzp1nCO/H6+1uPSGEyPzM= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI= +go.etcd.io/etcd/api/v3 v3.5.13 h1:8WXU2/NBge6AUF1K1gOexB6e07NgsN1hXK0rSTtgSp4= +go.etcd.io/etcd/api/v3 v3.5.13/go.mod h1:gBqlqkcMMZMVTMm4NDZloEVJzxQOQIls8splbqBDa0c= +go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U= +go.etcd.io/etcd/client/pkg/v3 v3.5.13 h1:RVZSAnWWWiI5IrYAXjQorajncORbS0zI48LQlE2kQWg= +go.etcd.io/etcd/client/pkg/v3 v3.5.13/go.mod h1:XxHT4u1qU12E2+po+UVPrEeL94Um6zL58ppuJWXSAB8= +go.etcd.io/etcd/client/v2 v2.305.10 h1:MrmRktzv/XF8CvtQt+P6wLUlURaNpSDJHFZhe//2QE4= +go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA= +go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc= +go.etcd.io/etcd/client/v3 v3.5.13 h1:o0fHTNJLeO0MyVbc7I3fsCf6nrOqn5d+diSarKnB2js= +go.etcd.io/etcd/client/v3 v3.5.13/go.mod h1:cqiAeY8b5DEEcpxvgWKsbLIWNM/8Wy2xJSDMtioMcoI= +go.etcd.io/etcd/pkg/v3 v3.5.10/go.mod h1:TKTuCKKcF1zxmfKWDkfz5qqYaE3JncKKZPFf8c1nFUs= +go.etcd.io/etcd/raft/v3 v3.5.10/go.mod h1:odD6kr8XQXTy9oQnyMPBOr0TVe+gT0neQhElQ6jbGRc= +go.etcd.io/etcd/server/v3 v3.5.10/go.mod h1:gBplPHfs6YI0L+RpGkTQO7buDbHv5HJGG/Bst0/zIPo= +go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= +go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= +google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= +google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= +k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/apiserver v0.30.1 h1:BEWEe8bzS12nMtDKXzCF5Q5ovp6LjjYkSp8qOPk8LZ8= +k8s.io/apiserver v0.30.1/go.mod h1:i87ZnQ+/PGAmSbD/iEKM68bm1D5reX8fO4Ito4B01mo= +k8s.io/cli-runtime v0.30.1 h1:kSBBpfrJGS6lllc24KeniI9JN7ckOOJKnmFYH1RpTOw= +k8s.io/cli-runtime v0.30.1/go.mod h1:zhHgbqI4J00pxb6gM3gJPVf2ysDjhQmQtnTxnMScab8= +k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= +k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= +k8s.io/cluster-bootstrap v0.30.1 h1:WHh04Oh0YAWMsJ5TXXEF+LGu3g/2ymQOYsH8IopUHlQ= +k8s.io/cluster-bootstrap v0.30.1/go.mod h1:GcLD4Z4GFY+CsNYcaqlSAmxFIHgSMGZHNT4SjA0A6ao= +k8s.io/code-generator v0.30.1 h1:ZsG++q5Vt0ScmKCeLhynUuWgcwFGg1Hl1AGfatqPJBI= +k8s.io/code-generator v0.30.1/go.mod h1:hFgxRsvOUg79mbpbVKfjJvRhVz1qLoe40yZDJ/hwRH4= +k8s.io/component-base v0.30.1 h1:bvAtlPh1UrdaZL20D9+sWxsJljMi0QZ3Lmw+kmZAaxQ= +k8s.io/component-base v0.30.1/go.mod h1:e/X9kDiOebwlI41AvBHuWdqFriSRrX50CdwA9TFaHLI= +k8s.io/component-helpers v0.30.1 h1:/UcxSLzZ0owluTE2WMDrFfZl2L+WVXKdYYYm68qnH7U= +k8s.io/component-helpers v0.30.1/go.mod h1:b1Xk27UJ3p/AmPqDx7khrnSxrdwQy9gTP7O1y6MZ6rg= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4 h1:v8TcVKY4HxDaiNH8xnHEEGfx80twQJL9cOQuhd55fcY= +k8s.io/gengo v0.0.0-20240310015720-9cff6334dab4/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo= +k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8= +k8s.io/helm v2.16.9+incompatible h1:yFz+WVaV9SA/DwOjTU8h7vGRs1EzKHF18OSF6dQ5w3o= +k8s.io/helm v2.16.9+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kms v0.30.1/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= +k8s.io/kube-aggregator v0.30.1 h1:ymR2BsxDacTKwzKTuNhGZttuk009c+oZbSeD+IPX5q4= +k8s.io/kube-aggregator v0.30.1/go.mod h1:SFbqWsM6ea8dHd3mPLsZFzJHbjBOS5ykIgJh4znZ5iQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/kubectl v0.30.1 h1:sHFIRI3oP0FFZmBAVEE8ErjnTyXDPkBcvO88mH9RjuY= +k8s.io/kubectl v0.30.1/go.mod h1:7j+L0Cc38RYEcx+WH3y44jRBe1Q1jxdGPKkX0h4iDq0= +k8s.io/kubernetes v1.30.1 h1:XlqS6KslLEA5mQzLK2AJrhr4Z1m8oJfkhHiWJ5lue+I= +k8s.io/kubernetes v1.30.1/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= +k8s.io/pod-security-admission v0.30.1 h1:r2NQSNXfnZDnm6KvLv1sYgai1ZXuO+m0qn11/Xymkf8= +k8s.io/pod-security-admission v0.30.1/go.mod h1:O5iry5U8N0CvtfI5kfe0CZ0Ct/KYj057j6Pa+QIwp24= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= +modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= +modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= +modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= +modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= +modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= +modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= +modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg= +modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= +modernc.org/sqlite v1.29.10 h1:3u93dz83myFnMilBGCOLbr+HjklS6+5rJLx4q86RDAg= +modernc.org/sqlite v1.29.10/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +oras.land/oras-go v1.2.2 h1:0E9tOHUfrNH7TCDk5KU0jVBEzCqbfdyuVfGmJ7ZeRPE= +oras.land/oras-go v1.2.2/go.mod h1:Apa81sKoZPpP7CDciE006tSZ0x3Q3+dOoBcMZ/aNxvw= +oras.land/oras-go/v2 v2.4.0 h1:i+Wt5oCaMHu99guBD0yuBjdLvX7Lz8ukPbwXdR7uBMs= +oras.land/oras-go/v2 v2.4.0/go.mod h1:osvtg0/ClRq1KkydMAEu/IxFieyjItcsQ4ut4PPF+f8= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0 h1:/U5vjBbQn3RChhv7P11uhYvCSm5G2GaIi5AIGBS6r4c= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.29.0/go.mod h1:z7+wmGM2dfIiLRfrC6jb5kV2Mq/sK1ZP303cxzkV5Y4= +sigs.k8s.io/aws-iam-authenticator v0.6.17 h1:YV/4D1XRzstuKTK2f3XD2nPA9rIKyi3YVdHwM9Iwd/I= +sigs.k8s.io/aws-iam-authenticator v0.6.17/go.mod h1:CnvFyzR/xeLHmUY/BD0qW6q0wp6KIwXmFp4eTfrHdP8= +sigs.k8s.io/cli-utils v0.35.0 h1:dfSJaF1W0frW74PtjwiyoB4cwdRygbHnC7qe7HF0g/Y= +sigs.k8s.io/cli-utils v0.35.0/go.mod h1:ITitykCJxP1vaj1Cew/FZEaVJ2YsTN9Q71m02jebkoE= +sigs.k8s.io/cluster-api v1.7.3 h1:DsSRxsA+18jxLqPAo29abZ9kOPK1/xwhSuQb/MROzSs= +sigs.k8s.io/cluster-api v1.7.3/go.mod h1:V9ZhKLvQtsDODwjXOKgbitjyCmC71yMBwDcMyNNIov0= +sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= +sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0= +sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U= +sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/keybase.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/keybase.md new file mode 100644 index 0000000..931cd3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/keybase.md @@ -0,0 +1,84 @@ +### Keybase proof + +I hereby claim: + + * I am rancher on github. + * I am rancher (https://keybase.io/rancher) on keybase. + * I have a public key whose fingerprint is 7ACE 6FB6 0DC4 E26C 4C6F 344D C9DF 50BD AC35 1DA9 + +To claim this, I am signing this object: + +```json +{ + "body": { + "key": { + "eldest_kid": "01208358649f8a0961727af7cad37b772f01d0158cabe5475be08226a2bc00d2176d0a", + "fingerprint": "7ace6fb60dc4e26c4c6f344dc9df50bdac351da9", + "host": "keybase.io", + "key_id": "c9df50bdac351da9", + "kid": "010195274cdf339669e41a38d3439a161ebf7d5dc4d7cb3cedaefcef3515c85c8b2f0a", + "uid": "01b937b34ac988003e7eccf9d986f719", + "username": "rancher" + }, + "service": { + "name": "github", + "username": "rancher" + }, + "type": "web_service_binding", + "version": 1 + }, + "ctime": 1644337278, + "expire_in": 157680000, + "prev": "c1ca2429497f33d213cd9ea8322a1469a975d862eebdf71f9211614dc9bcb08f", + "seqno": 27, + "tag": "signature" +} +``` + +with the key [7ACE 6FB6 0DC4 E26C 4C6F 344D C9DF 50BD AC35 1DA9](https://keybase.io/rancher), yielding the signature: + +``` +-----BEGIN PGP MESSAGE----- + +owF1UmlMVFcUHraGETWUqAQSZsKzKMoE3r6MmpaKWElJKa3LQO30vXfvG17RmWFm +oCAiaJcoxDI0maY1IFWWFNBaQFZZWlkMS0UsqbVUGWiB0KRpS7C2QKVvDPxrk5vc +3HPP953vfOc4N/io/L0GJpI6r1BhNV5Dc4JK8P7ElYsIFpCD6HORdPj0gscAtDuM +6TJA9AiK4ShLUCxNchLLoxyNMTjDS4zIA4IRGAaXUAygGMWKvAApkqEEiLI4TvO4 +IKIowDGGBiiP6BBJNpugzWqTzQ6FluFFSEsCjQKRhDgtkiItESQJRA5IFCoAXiQo +DPCcAkyz2D0IRZzA22G0bFFiysP4VN5/5K/pRjGOwhlSBBJBcDTNQRLjCRYQJMHx +GI1BQWIApZQHjCgQIgQ8lEQoKTSUyCpHUDrz6M5cpRM4pV+C5EWOZVGUgAwURYkD +HEtLDOapm2mHNjN/HCrZNt4spkEbkqdDlGCWLEKPr6ufJtmRlin8L8CRY/VE3oGC +cRVrFGQzUNxTIFnQZpctZkSPKZmiQ/aAMZokCUKZCqtDYLZVtkGj7MmgGFoRiqI6 +xGqDWR6vMJHHSZwjOUaxRBnNK4QIOMizBI7zGElzPMdQgKVxCAWgNCVxOKYY5RmK +IAooKyGedjLMFkSPM4pQ3qSQ2mWTmXdk2iCSt+6cN+Gr8vJXhW0J9z1x29K8oXfq +2MsWMnFt5fy8PfumWqcOXIvUvhCouhZbl536ZPpRmxrOf9+w6Urz/rr6q/6VOQnd +Ps4R49S9rVlzr1pmbizHpTi/EBa6djZRZX91wqZLB8ceT5bvC7h5vTdn+PTR8Y5P +vWq3Du/588Zvk85iS0xYVdSC1ZYfGYqtLAS65lfeSPhHuqiO0bRGudyWggf7CkMi +tpfoqOC8HXuyU0pDtI9fe3C97+j+oqGv0wp8Y21Nh5wlF17v6f22uDe8Oimuiml1 +zj/075AGDZofBy5pnDONhkF6FLhvZt+/0CFN3GvKjQx2nR1oK2pYH3J2h2mWWYi6 +nJSffr9rWPhAI5VOTs9pv2k5fCRuelveuPbibkOeX+iovn+71Wjs6Tz15pMgi7zp +w8bPE6KiNnZPFHTFHkn8XT7x1kefLT06k3dXay46YfcK6h92T4zNFweHu063Rxam +tA97N9XW+PVFHOgZveXTqFUHjAwZ9lY30GfuvkQmtWiWy+LVXdWjX9YZzif/0fdL +gLVkLjp0Ub/x1HcHNYlLz28Oqlxyt7l/+nmzdfZWa8VI5qLpztz67uVt5Zj3Q0N9 +GQgpPbnlQMvMucvP1Ub4a+Mz+iOPX0stuh36LD+I/fD2M1d3TdlD3w1068iKBM18 +WKWmskvIn104uXK48NDf6OKd6J2FH2vQ+L0UaPvKpd79a31yzGJq54v9VRnLNRXN +74+HJbf2jY2Wt7+3618= +=TVo6 +-----END PGP MESSAGE----- + +``` + +And finally, I am proving ownership of the github account by posting this as a gist. + +### My publicly-auditable identity: + +https://keybase.io/rancher + +### From the command line: + +Consider the [keybase command line program](https://keybase.io/download). + +```bash +# look me up +keybase id rancher +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/main.go new file mode 100644 index 0000000..5809140 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/main.go @@ -0,0 +1,228 @@ +package main + +import ( + "fmt" + "log" + "net/http" + _ "net/http/pprof" + "os" + "path/filepath" + + "github.com/docker/docker/pkg/reexec" + "github.com/ehazlett/simplelog" + _ "github.com/rancher/norman/controller" + "github.com/rancher/norman/pkg/kwrapper/k8s" + "github.com/rancher/rancher/pkg/data/management" + "github.com/rancher/rancher/pkg/logserver" + "github.com/rancher/rancher/pkg/rancher" + "github.com/rancher/rancher/pkg/version" + "github.com/rancher/wrangler/v3/pkg/signals" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var ( + profileAddress = "localhost:6060" + kubeConfig string +) + +func main() { + management.RegisterPasswordResetCommand() + management.RegisterEnsureDefaultAdminCommand() + if reexec.Init() { + return + } + + os.Unsetenv("SSH_AUTH_SOCK") + os.Unsetenv("SSH_AGENT_PID") + + if dm := os.Getenv("CATTLE_DEV_MODE"); dm != "" { + if dir, err := os.Getwd(); err == nil { + dmPath := filepath.Join(dir, "management-state", "bin") + os.MkdirAll(dmPath, 0700) + newPath := fmt.Sprintf("%s%s%s", dmPath, string(os.PathListSeparator), os.Getenv("PATH")) + + os.Setenv("PATH", newPath) + } + } else { + newPath := fmt.Sprintf("%s%s%s", "/opt/drivers/management-state/bin", string(os.PathListSeparator), os.Getenv("PATH")) + os.Setenv("PATH", newPath) + } + + var config rancher.Options + + app := cli.NewApp() + app.Version = version.FriendlyVersion() + app.Usage = "Complete container management platform" + app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "kubeconfig", + Usage: "Kube config for accessing k8s cluster", + EnvVar: "KUBECONFIG", + Destination: &kubeConfig, + }, + cli.BoolFlag{ + Name: "debug", + Usage: "Enable debug logs", + Destination: &config.Debug, + }, + cli.BoolFlag{ + Name: "trace", + Usage: "Enable trace logs", + Destination: &config.Trace, + }, + cli.StringFlag{ + Name: "add-local", + Usage: "Add local cluster (true, false)", + Value: "true", + Destination: &config.AddLocal, + Hidden: true, + }, + cli.IntFlag{ + Name: "http-listen-port", + Usage: "HTTP listen port", + Value: 8080, + Destination: &config.HTTPListenPort, + }, + cli.IntFlag{ + Name: "https-listen-port", + Usage: "HTTPS listen port", + Value: 8443, + Destination: &config.HTTPSListenPort, + }, + cli.StringFlag{ + Name: "k8s-mode", + Usage: "Mode to run or access k8s API server for management API (embedded, external, auto)", + Value: "auto", + Destination: &config.K8sMode, + }, + cli.StringFlag{ + Name: "log-format", + Usage: "Log formatter used (json, text, simple)", + Value: "simple", + }, + cli.StringSliceFlag{ + Name: "acme-domain", + EnvVar: "ACME_DOMAIN", + Usage: "Domain to register with LetsEncrypt", + Value: &config.ACMEDomains, + }, + cli.BoolFlag{ + Name: "no-cacerts", + Usage: "Skip CA certs population in settings when set to true", + Destination: &config.NoCACerts, + }, + cli.StringFlag{ + Name: "audit-log-path", + EnvVar: "AUDIT_LOG_PATH", + Value: "/var/log/auditlog/rancher-api-audit.log", + Usage: "Log path for Rancher Server API. Default path is /var/log/auditlog/rancher-api-audit.log", + Destination: &config.AuditLogPath, + }, + cli.IntFlag{ + Name: "audit-log-maxage", + Value: 10, + EnvVar: "AUDIT_LOG_MAXAGE", + Usage: "Defined the maximum number of days to retain old audit log files", + Destination: &config.AuditLogMaxage, + }, + cli.IntFlag{ + Name: "audit-log-maxbackup", + Value: 10, + EnvVar: "AUDIT_LOG_MAXBACKUP", + Usage: "Defines the maximum number of audit log files to retain", + Destination: &config.AuditLogMaxbackup, + }, + cli.IntFlag{ + Name: "audit-log-maxsize", + Value: 100, + EnvVar: "AUDIT_LOG_MAXSIZE", + Usage: "Defines the maximum size in megabytes of the audit log file before it gets rotated, default size is 100M", + Destination: &config.AuditLogMaxsize, + }, + cli.IntFlag{ + Name: "audit-level", + Value: 0, + EnvVar: "AUDIT_LEVEL", + Usage: "Audit log level: 0 - disable audit log, 1 - log event metadata, 2 - log event metadata and request body, 3 - log event metadata, request body and response body", + Destination: &config.AuditLevel, + }, + cli.StringFlag{ + Name: "profile-listen-address", + Value: "127.0.0.1:6060", + Usage: "Address to listen on for profiling", + Destination: &profileAddress, + }, + cli.StringFlag{ + Name: "features", + EnvVar: "CATTLE_FEATURES", + Value: "", + Usage: "Declare specific feature values on start up. Example: \"kontainer-driver=true\" - kontainer driver feature will be enabled despite false default value", + Destination: &config.Features, + }, + } + + app.Action = func(c *cli.Context) error { + // enable profiler + if profileAddress != "" { + go func() { + log.Println(http.ListenAndServe(profileAddress, nil)) + }() + } + initLogs(c, config) + return run(c, config) + } + + app.ExitErrHandler = func(c *cli.Context, err error) { + logrus.Fatal(err) + } + + app.Run(os.Args) +} + +func initLogs(c *cli.Context, cfg rancher.Options) { + switch c.String("log-format") { + case "simple": + logrus.SetFormatter(&simplelog.StandardFormatter{}) + case "text": + logrus.SetFormatter(&logrus.TextFormatter{}) + case "json": + logrus.SetFormatter(&logrus.JSONFormatter{}) + } + logrus.SetOutput(os.Stdout) + if cfg.Debug { + logrus.SetLevel(logrus.DebugLevel) + logrus.Debugf("Loglevel set to [%v]", logrus.DebugLevel) + } + if cfg.Trace { + logrus.SetLevel(logrus.TraceLevel) + logrus.Tracef("Loglevel set to [%v]", logrus.TraceLevel) + } + + logserver.StartServerWithDefaults() +} + +func run(cli *cli.Context, cfg rancher.Options) error { + logrus.Infof("Rancher version %s is starting", version.FriendlyVersion()) + logrus.Infof("Rancher arguments %+v", cfg) + ctx := signals.SetupSignalContext() + + if cfg.AddLocal != "true" && cfg.AddLocal != "auto" { + logrus.Fatal("add-local flag must be set to 'true', see Rancher 2.5.0 release notes for more information") + } + + embedded, clientConfig, err := k8s.GetConfig(ctx, cfg.K8sMode, kubeConfig) + if err != nil { + return err + } + cfg.Embedded = embedded + + os.Unsetenv("KUBECONFIG") + + server, err := rancher.New(ctx, clientConfig, &cfg) + if err != nil { + return err + } + + return server.ListenAndServe(ctx) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/make.bat b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/make.bat new file mode 100644 index 0000000..aeb11a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/make.bat @@ -0,0 +1,20 @@ +@echo off +if "%1%"=="deps" ( + call :deps + goto :eof +) +if "%1%"=="" ( + set cmd=ci +) else ( + set cmd=%1% +) +call :.dapper +.dapper.exe -f Dockerfile-windows.dapper %cmd% +goto :eof + +:.dapper +if not exist .dapper.exe ( + bitsadmin /rawreturn /transfer dappwer-download https://releases.rancher.com/dapper/latest/dapper-Windows-x86_64.exe %~dp0\.dapper.exe + .dapper.exe -v +) +goto :eof diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent-head.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent-head.tmpl new file mode 100644 index 0000000..68664e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent-head.tmpl @@ -0,0 +1,29 @@ +image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-head{{/if}} +manifests: + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-windows-1809 + platform: + architecture: amd64 + os: windows + version: 1809 + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-windows-ltsc2022 + platform: + architecture: amd64 + os: windows + version: ltsc2022 + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent.tmpl new file mode 100644 index 0000000..485079b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-agent.tmpl @@ -0,0 +1,29 @@ +image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}-head{{/if}} +manifests: + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-windows-1809 + platform: + architecture: amd64 + os: windows + version: 1809 + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-windows-ltsc2022 + platform: + architecture: amd64 + os: windows + version: ltsc2022 + - + image: rancher/rancher-agent:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-head.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-head.tmpl new file mode 100644 index 0000000..ca22eb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-head.tmpl @@ -0,0 +1,17 @@ +image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}-head{{/if}} +manifests: + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer-head.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer-head.tmpl new file mode 100644 index 0000000..0211fb4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer-head.tmpl @@ -0,0 +1,17 @@ +image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-head{{/if}} +manifests: + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer.tmpl new file mode 100644 index 0000000..44d6387 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest-installer.tmpl @@ -0,0 +1,17 @@ +image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}-head{{/if}} +manifests: + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/system-agent-installer-rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest.tmpl new file mode 100644 index 0000000..4ee6484 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/manifest.tmpl @@ -0,0 +1,17 @@ +image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-head{{/if}} +manifests: + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-amd64 + platform: + architecture: amd64 + os: linux + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-arm64 + platform: + architecture: arm64 + os: linux + - + image: rancher/rancher:{{#if build.tag}}{{build.tag}}{{else}}{{replace "release/" "" build.branch }}-{{build.commit}}{{/if}}-linux-s390x + platform: + architecture: s390x + os: linux diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile new file mode 100644 index 0000000..e7c9fec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile @@ -0,0 +1,302 @@ +FROM --platform=$BUILDPLATFORM registry.suse.com/bci/golang:1.22 as build +ARG VERSION +ARG COMMIT +ARG RKE_VERSION +ARG CGO_ENABLED=0 +ARG TAGS="k8s" +ARG LINKFLAGS="-extldflags -static" +ARG DEFAULT_VALUES="{\"rke-version\":\"${RKE_VERSION}\"}" +ARG LDFLAGS="-X github.com/rancher/rancher/pkg/version.Version=${VERSION} -X github.com/rancher/rancher/pkg/version.GitCommit=${COMMIT} -X github.com/rancher/rancher/pkg/settings.InjectDefaults=${DEFAULT_VALUES} ${LINKFLAGS}" +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /app +COPY . . +RUN go mod download +RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -tags "${TAGS}" -ldflags "${LDFLAGS}" -o rancher + +FROM registry.suse.com/bci/bci-micro:15.6 AS final + +# Temporary build stage image +FROM registry.suse.com/bci/bci-base:15.6 AS builder + +# Install system packages using builder image that has zypper +COPY --from=final / /chroot/ + +# Install some packages with zypper in the chroot of the final micro image +RUN zypper refresh && \ + zypper --installroot /chroot -n in --no-recommends \ + git-core curl util-linux ca-certificates ca-certificates-mozilla unzip xz gzip sed tar shadow gawk vim-small \ + netcat-openbsd mkisofs openssh-clients openssl patterns-base-fips && \ + zypper --installroot /chroot clean -a && \ + rm -rf /chroot/var/cache/zypp/* /chroot/var/log/zypp/* /chroot/tmp/* /chroot/var/tmp/* /chroot/usr/share/doc/packages/* + +# Main stage using bci-micro as the base image +FROM final + +# Copy binaries and configuration files from builder to micro +COPY --from=builder /chroot/ / + +# Test that some of the dependency binaries were copied +# and are working on the target image. +RUN /usr/bin/unshare --version && \ + /usr/bin/mount --version && \ + /usr/bin/umount --version && \ + /usr/bin/nsenter --version + +RUN useradd rancher && \ + mkdir -p /var/lib/rancher /var/lib/cattle /opt/jail /opt/drivers/management-state/bin && \ + chown -R rancher /var/lib/rancher /var/lib/cattle /usr/local/bin + +RUN mkdir /root/.kube && \ + ln -s /etc/rancher/k3s/k3s.yaml /root/.kube/k3s.yaml && \ + ln -s /etc/rancher/k3s/k3s.yaml /root/.kube/config && \ + ln -s /usr/bin/rancher /usr/bin/reset-password && \ + ln -s /usr/bin/rancher /usr/bin/ensure-default-admin +WORKDIR /var/lib/rancher + +ARG ARCH=amd64 +ARG ETCD_UNSUPPORTED_ARCH +ARG IMAGE_REPO=rancher +ARG SYSTEM_CHART_DEFAULT_BRANCH=release-v2.9 +ARG CHART_DEFAULT_BRANCH=release-v2.9 +ARG PARTNER_CHART_DEFAULT_BRANCH=main +ARG RKE2_CHART_DEFAULT_BRANCH=main +# kontainer-driver-metadata branch to be set for specific branch other than dev/master, logic at rancher/rancher/pkg/settings/setting.go +ARG CATTLE_KDM_BRANCH=release-v2.9 +ARG VERSION=${VERSION} + +ENV CATTLE_SYSTEM_CHART_DEFAULT_BRANCH=$SYSTEM_CHART_DEFAULT_BRANCH +ENV CATTLE_CHART_DEFAULT_BRANCH=$CHART_DEFAULT_BRANCH +ENV CATTLE_PARTNER_CHART_DEFAULT_BRANCH=$PARTNER_CHART_DEFAULT_BRANCH +ENV CATTLE_RKE2_CHART_DEFAULT_BRANCH=$RKE2_CHART_DEFAULT_BRANCH +ENV CATTLE_HELM_VERSION v2.16.8-rancher2 +ENV CATTLE_MACHINE_VERSION v0.15.0-rancher116 +ENV CATTLE_K3S_VERSION v1.30.2+k3s2 +ENV CATTLE_MACHINE_PROVISION_IMAGE rancher/machine:${CATTLE_MACHINE_VERSION} +ENV CATTLE_ETCD_VERSION v3.5.14 +ENV LOGLEVEL_VERSION v0.1.6 +ENV TINI_VERSION v0.18.0 +ENV TELEMETRY_VERSION v0.6.2 +ENV DOCKER_MACHINE_LINODE_VERSION v0.1.12 +ENV LINODE_UI_DRIVER_VERSION v0.7.0 +# make sure the version number is consistent with the one at Line 100 of pkg/data/management/machinedriver_data.go +ENV DOCKER_MACHINE_HARVESTER_VERSION v0.6.7 +ENV CATTLE_KDM_BRANCH ${CATTLE_KDM_BRANCH} +ENV HELM_VERSION v3.15.2 +ENV KUSTOMIZE_VERSION v5.4.2 +ENV CATTLE_WINS_AGENT_VERSION v0.4.17 +ENV CATTLE_WINS_AGENT_INSTALL_SCRIPT https://raw.githubusercontent.com/rancher/wins/${CATTLE_WINS_AGENT_VERSION}/install.ps1 +ENV CATTLE_WINS_AGENT_UNINSTALL_SCRIPT https://raw.githubusercontent.com/rancher/wins/${CATTLE_WINS_AGENT_VERSION}/uninstall.ps1 +ENV CATTLE_WINS_AGENT_UPGRADE_IMAGE rancher/wins:${CATTLE_WINS_AGENT_VERSION} +ENV CATTLE_CSI_PROXY_AGENT_VERSION v1.1.3 +# make sure the CATTLE_SYSTEM_AGENT_VERSION is consistent with tests/v2/codecoverage/package/Dockerfile +ENV CATTLE_SYSTEM_AGENT_VERSION v0.3.8 +ENV CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX https://github.com/rancher/system-agent/releases/download +ENV CATTLE_SYSTEM_AGENT_UPGRADE_IMAGE rancher/system-agent:${CATTLE_SYSTEM_AGENT_VERSION}-suc +ENV CATTLE_SYSTEM_AGENT_INSTALLER_IMAGE rancher/system-agent-installer- +# make sure the ENV CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT is consistent with pkg/settings/setting.go to utlize the local version of install script downloaded during build/package +ENV CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/install.sh +ENV CATTLE_SYSTEM_AGENT_UNINSTALL_SCRIPT ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh +ENV CATTLE_SYSTEM_UPGRADE_CONTROLLER_CHART_VERSION 104.0.0+up0.7.0 + +# AKS,EKS,GKE Operator charts versions +ARG CATTLE_AKS_OPERATOR_VERSION +ENV CATTLE_AKS_OPERATOR_VERSION=$CATTLE_AKS_OPERATOR_VERSION +ARG CATTLE_EKS_OPERATOR_VERSION +ENV CATTLE_EKS_OPERATOR_VERSION=$CATTLE_EKS_OPERATOR_VERSION +ARG CATTLE_GKE_OPERATOR_VERSION +ENV CATTLE_GKE_OPERATOR_VERSION=$CATTLE_GKE_OPERATOR_VERSION + +# System charts minimal version +# Deprecated in favor of CATTLE_FLEET_VERSION. +ENV CATTLE_FLEET_MIN_VERSION="" +ARG CATTLE_FLEET_VERSION +ENV CATTLE_FLEET_VERSION=$CATTLE_FLEET_VERSION +ARG CATTLE_RANCHER_WEBHOOK_VERSION +ENV CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION +ARG CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ENV CATTLE_RANCHER_PROVISIONING_CAPI_VERSION=$CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ARG CATTLE_CSP_ADAPTER_MIN_VERSION +ENV CATTLE_CSP_ADAPTER_MIN_VERSION=$CATTLE_CSP_ADAPTER_MIN_VERSION + +RUN mkdir -p /var/lib/rancher-data/local-catalogs/system-library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/helm3-library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/v2 && \ + git clone -b $CATTLE_SYSTEM_CHART_DEFAULT_BRANCH --depth 1 https://github.com/rancher/system-charts /var/lib/rancher-data/local-catalogs/system-library && \ + # Temporarily clone from our GitHub's main repo, to avoid unnecessary load + # in git.rancher.io + git config --global url."https://github.com/rancher/".insteadOf https://git.rancher.io/ && \ + # Charts need to be copied into the sha256 value of git url computed in https://github.com/rancher/rancher/blob/5ebda9ac23c06e9647b586ec38aa51cc9ff9b031/pkg/catalogv2/git/download.go#L102 to create a unique folder per url + git clone -b $CATTLE_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/charts /var/lib/rancher-data/local-catalogs/v2/rancher-charts/4b40cac650031b74776e87c1a726b0484d0877c3ec137da0872547ff9b73a721/ && \ + git clone -b $CATTLE_PARTNER_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/partner-charts /var/lib/rancher-data/local-catalogs/v2/rancher-partner-charts/8f17acdce9bffd6e05a58a3798840e408c4ea71783381ecd2e9af30baad65974 && \ + git clone -b $CATTLE_RKE2_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/rke2-charts /var/lib/rancher-data/local-catalogs/v2/rancher-rke2-charts/675f1b63a0a83905972dcab2794479ed599a6f41b86cd6193d69472d0fa889c9 && \ + # Revert the previous change in git.rancher.io from .gitconfig + rm "${HOME}/.gitconfig" && \ + git clone -b master --depth 1 https://github.com/rancher/charts /var/lib/rancher-data/local-catalogs/library && \ + git clone -b master --depth 1 https://github.com/rancher/helm3-charts /var/lib/rancher-data/local-catalogs/helm3-library + +RUN curl -sLf https://github.com/rancher/machine/releases/download/${CATTLE_MACHINE_VERSION}/rancher-machine-${ARCH}.tar.gz | tar xvzf - -C /usr/bin && \ + curl -sLf https://github.com/rancher/loglevel/releases/download/${LOGLEVEL_VERSION}/loglevel-${ARCH}-${LOGLEVEL_VERSION}.tar.gz | tar xvzf - -C /usr/bin && \ + curl -LO https://github.com/linode/docker-machine-driver-linode/releases/download/${DOCKER_MACHINE_LINODE_VERSION}/docker-machine-driver-linode_linux-amd64.zip && \ + unzip docker-machine-driver-linode_linux-amd64.zip -d /opt/drivers/management-state/bin && \ + mkdir -p /usr/share/rancher/ui/assets/ && \ + ln -s /opt/drivers/management-state/bin/docker-machine-driver-linode /usr/share/rancher/ui/assets/ && \ + rm docker-machine-driver-linode_linux-amd64.zip + +RUN curl -LO https://releases.rancher.com/harvester-node-driver/${DOCKER_MACHINE_HARVESTER_VERSION}/docker-machine-driver-harvester-amd64.tar.gz && \ + tar -xf docker-machine-driver-harvester-amd64.tar.gz -C /opt/drivers/management-state/bin && \ + ln -s /opt/drivers/management-state/bin/docker-machine-driver-harvester /usr/share/rancher/ui/assets/ && \ + rm docker-machine-driver-harvester-amd64.tar.gz + +ENV TINI_URL_amd64=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini \ + TINI_URL_arm64=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-arm64 \ + TINI_URL_s390x=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-s390x \ + TINI_URL=TINI_URL_${ARCH} + +ENV HELM_URL_V2_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm \ + HELM_URL_V2_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-arm64 \ + HELM_URL_V2_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-s390x \ + HELM_URL_V2=HELM_URL_V2_${ARCH} \ + HELM_URL_V3=https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz \ + TILLER_URL_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller \ + TILLER_URL_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-arm64 \ + TILLER_URL_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-s390x \ + TILLER_URL=TILLER_URL_${ARCH} \ + ETCD_URL=https://github.com/etcd-io/etcd/releases/download/${CATTLE_ETCD_VERSION}/etcd-${CATTLE_ETCD_VERSION}-linux-${ARCH}.tar.gz \ + KUSTOMIZE_URL=https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz + +RUN curl -sLf ${KUSTOMIZE_URL} | tar -xzf - -C /usr/bin + +# set up helm 2 +RUN curl -sLf ${!HELM_URL_V2} > /usr/bin/rancher-helm && \ + curl -sLf ${!TILLER_URL} > /usr/bin/rancher-tiller && \ + ln -s /usr/bin/rancher-helm /usr/bin/helm && \ + ln -s /usr/bin/rancher-tiller /usr/bin/tiller && \ + chmod +x /usr/bin/rancher-helm /usr/bin/rancher-tiller + +# set up helm 3 +RUN curl ${HELM_URL_V3} | tar xvzf - --strip-components=1 -C /usr/bin && \ + mv /usr/bin/helm /usr/bin/helm_v3 && \ + chmod +x /usr/bin/kustomize + +# Set up K3s: copy the necessary binaries from the K3s image. +COPY --from=rancher/k3s:v1.30.2-k3s2 \ + /bin/blkid \ + /bin/bandwidth \ + /bin/cni \ + /bin/conntrack \ + /bin/containerd \ + /bin/containerd-shim-runc-v2 \ + /bin/ethtool \ + /bin/firewall \ + /bin/ip \ + /bin/ipset \ + /bin/k3s \ + /bin/losetup \ + /bin/pigz \ + /bin/runc \ + /bin/which \ + /bin/aux/xtables-legacy-multi \ + /usr/bin/ + +RUN ln -s /usr/bin/cni /usr/bin/bridge && \ + ln -s /usr/bin/cni /usr/bin/flannel && \ + ln -s /usr/bin/cni /usr/bin/host-local && \ + ln -s /usr/bin/cni /usr/bin/loopback && \ + ln -s /usr/bin/cni /usr/bin/portmap && \ + ln -s /usr/bin/k3s /usr/bin/crictl && \ + ln -s /usr/bin/k3s /usr/bin/ctr && \ + ln -s /usr/bin/k3s /usr/bin/k3s-agent && \ + ln -s /usr/bin/k3s /usr/bin/k3s-etcd-snapshot && \ + ln -s /usr/bin/k3s /usr/bin/k3s-server && \ + ln -s /usr/bin/k3s /usr/bin/kubectl && \ + ln -s /usr/bin/pigz /usr/bin/unpigz && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-translate && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-translate + +RUN curl -sLf ${!TINI_URL} > /usr/bin/tini && \ + mkdir -p /var/lib/rancher/k3s/agent/images/ && \ + curl -sfL ${ETCD_URL} | tar xvzf - --strip-components=1 --no-same-owner -C /usr/bin/ etcd-${CATTLE_ETCD_VERSION}-linux-${ARCH}/etcdctl && \ + curl -sLf https://github.com/rancher/telemetry/releases/download/${TELEMETRY_VERSION}/telemetry-${ARCH} > /usr/bin/telemetry && \ + chmod +x /usr/bin/tini /usr/bin/telemetry && \ + mkdir -p /var/lib/rancher-data/driver-metadata + +ENV CATTLE_UI_VERSION 2.9.1 +ENV CATTLE_DASHBOARD_UI_VERSION v2.9.1 +ENV CATTLE_CLI_VERSION v2.9.0 + +# Base UI brand used as a fallback env setting (not user facing) to indicate this is a non-prime install +ENV CATTLE_BASE_UI_BRAND= + +# Please update the api-ui-version in pkg/settings/settings.go when updating the version here. +ENV CATTLE_API_UI_VERSION 1.1.11 + +RUN mkdir -p /var/log/auditlog +ENV AUDIT_LOG_PATH /var/log/auditlog/rancher-api-audit.log +ENV AUDIT_LOG_MAXAGE 10 +ENV AUDIT_LOG_MAXBACKUP 10 +ENV AUDIT_LOG_MAXSIZE 100 +ENV AUDIT_LEVEL 0 + +RUN mkdir -p /usr/share/rancher/ui && \ + cd /usr/share/rancher/ui && \ + curl -sL https://releases.rancher.com/ui/${CATTLE_UI_VERSION}.tar.gz | tar xvzf - --strip-components=1 && \ + mkdir -p assets/rancher-ui-driver-linode && \ + cd assets/rancher-ui-driver-linode && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/component.js && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/component.css && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/linode.svg && \ + mkdir -p /usr/share/rancher/ui/api-ui && \ + cd /usr/share/rancher/ui/api-ui && \ + curl -sL https://releases.rancher.com/api-ui/${CATTLE_API_UI_VERSION}.tar.gz | tar xvzf - --strip-components=1 && \ + mkdir -p /usr/share/rancher/ui-dashboard/dashboard && \ + cd /usr/share/rancher/ui-dashboard/dashboard && \ + curl -sL https://releases.rancher.com/dashboard/${CATTLE_DASHBOARD_UI_VERSION}.tar.gz | tar xvzf - --strip-components=2 && \ + ln -s dashboard/index.html ../index.html && \ + cd ../../ui/assets && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-arm64 -O && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -O && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT} -o system-agent-install.sh && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_UNINSTALL_SCRIPT} -o system-agent-uninstall.sh && \ + curl -sfL https://github.com/rancher/wins/releases/download/${CATTLE_WINS_AGENT_VERSION}/wins.exe -O && \ + curl -sfL https://acs-mirror.azureedge.net/csi-proxy/${CATTLE_CSI_PROXY_AGENT_VERSION}/binaries/csi-proxy-${CATTLE_CSI_PROXY_AGENT_VERSION}.tar.gz -O && \ + curl -sfL ${CATTLE_WINS_AGENT_INSTALL_SCRIPT} -o wins-agent-install.ps1 \ + curl -sfL ${CATTLE_WINS_AGENT_UNINSTALL_SCRIPT} -o wins-agent-uninstall.ps1 + +ENV CATTLE_CLI_URL_DARWIN https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-darwin-amd64-${CATTLE_CLI_VERSION}.tar.gz +ENV CATTLE_CLI_URL_LINUX https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-linux-amd64-${CATTLE_CLI_VERSION}.tar.gz +ENV CATTLE_CLI_URL_WINDOWS https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-windows-386-${CATTLE_CLI_VERSION}.zip + +ENV CATTLE_SERVER_VERSION ${VERSION} + +COPY --from=build /app/rancher /usr/bin/ +COPY --from=build /app/package/entrypoint.sh /usr/bin/ +COPY --from=build /app/package/kustomize.sh /usr/bin/ +COPY --from=build app/package/jailer.sh /usr/bin/ +COPY --from=build /app/k3s-airgap-images.tar /var/lib/rancher/k3s/agent/images/ +RUN chmod +x /usr/bin/entrypoint.sh +RUN chmod +x /usr/bin/kustomize.sh + +COPY --from=build /app/data.json /var/lib/rancher-data/driver-metadata/ + +ENV CATTLE_AGENT_IMAGE ${IMAGE_REPO}/rancher-agent:${VERSION} +ENV CATTLE_SERVER_IMAGE ${IMAGE_REPO}/rancher +ENV ETCDCTL_API=3 + +ENV SSL_CERT_DIR /etc/rancher/ssl +VOLUME /var/lib/rancher +VOLUME /var/lib/kubelet +VOLUME /var/lib/cni +VOLUME /var/log + +ENV ETCD_UNSUPPORTED_ARCH ${ETCD_UNSUPPORTED_ARCH} + +ENTRYPOINT ["entrypoint.sh"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.agent b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.agent new file mode 100644 index 0000000..0996047 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.agent @@ -0,0 +1,79 @@ +ARG RANCHER_TAG=dev +ARG RANCHER_REPO=rancher +ARG REGISTRY=docker.io +ARG RANCHER_IMAGE=${REGISTRY}/${RANCHER_REPO}/rancher:${RANCHER_TAG} +ARG ARCH +ARG VERSION=dev + +FROM --platform=$BUILDPLATFORM registry.suse.com/bci/golang:1.22 AS build +ARG VERSION=${VERSION} +ARG CGO_ENABLED=0 +ARG TAGS="k8s" +ARG LINKFLAGS="-extldflags -static" +ARG LDFLAGS="-X main.VERSION=${VERSION} $LINKFLAGS" +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /app + +COPY . . + +RUN go mod download + +RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build -tags "${TAGS}" -ldflags "${LDFLAGS}" -o agent ./cmd/agent + +FROM ${RANCHER_IMAGE} AS rancher + +FROM registry.suse.com/bci/bci-micro:15.6 AS final + +# Temporary build stage image +FROM registry.suse.com/bci/bci-base:15.6 AS builder + +# Install system packages using builder image that has zypper +COPY --from=final / /chroot/ + +# Install some packages with zypper in the chroot of the final micro image +RUN zypper refresh && \ + zypper --installroot /chroot -n in --no-recommends \ + curl util-linux ca-certificates ca-certificates-mozilla jq git-core hostname iproute2 vim-small less \ + bash-completion bind-utils acl openssh-clients tar gzip xz gawk sysstat openssl patterns-base-fips && \ + zypper --installroot /chroot clean -a && \ + rm -rf /chroot/var/cache/zypp/* /chroot/var/log/zypp/* /chroot/tmp/* /chroot/var/tmp/* /chroot/usr/share/doc/packages/* + +# Main stage using bci-micro as the base image +FROM final + +# Copy binaries and configuration files from builder to micro +COPY --from=builder /chroot/ / + +# Test that some of the dependency binaries were copied +# and are working on the target image. +RUN /usr/bin/unshare --version && \ + /usr/bin/mount --version && \ + /usr/bin/umount --version && \ + /usr/bin/nsenter --version + +ARG ARCH=amd64 +ENV KUBECTL_VERSION v1.27.10 +ARG VERSION=${VERSION} + +RUN curl -sLf https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl > /usr/bin/kubectl && \ + chmod +x /usr/bin/kubectl + +ENV LOGLEVEL_VERSION v0.1.6 + +RUN curl -sLf https://github.com/rancher/loglevel/releases/download/${LOGLEVEL_VERSION}/loglevel-${ARCH}-${LOGLEVEL_VERSION}.tar.gz | tar xvzf - -C /usr/bin + +LABEL io.cattle.agent true +ENV AGENT_IMAGE rancher/rancher-agent:${VERSION} +# For now, this value needs to be manually synced with the one in the main Dockerfile. This pins downstream webhook's version. +ARG CATTLE_RANCHER_WEBHOOK_VERSION +ENV CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION +ARG CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ENV CATTLE_RANCHER_PROVISIONING_CAPI_VERSION=$CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ENV SSL_CERT_DIR /etc/kubernetes/ssl/certs +COPY --from=rancher /var/lib/rancher-data /var/lib/rancher-data +COPY --from=rancher /usr/bin/tini /usr/bin/ +COPY --from=build /app/agent /app/package/run.sh /app/package/kubectl-shell.sh /app/package/shell-setup.sh /usr/bin/ +WORKDIR /var/lib/rancher +ENTRYPOINT ["run.sh"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.installer b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.installer new file mode 100644 index 0000000..0731ff3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/Dockerfile.installer @@ -0,0 +1,8 @@ +ARG RANCHER_TAG=dev +ARG RANCHER_REPO=rancher +FROM ${RANCHER_REPO}/rancher:${RANCHER_TAG} as rancher + +FROM scratch +COPY --from=rancher /usr/bin/helm_v3 /helm +COPY chart/*/*.tgz / +COPY package/installer-run.sh /run.sh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/entrypoint.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/entrypoint.sh new file mode 100644 index 0000000..563b5a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/entrypoint.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e + +if [ ! -e /run/secrets/kubernetes.io/serviceaccount ] && [ ! -e /dev/kmsg ]; then + echo "ERROR: Rancher must be ran with the --privileged flag when running outside of Kubernetes" + exit 1 +fi + +######################################################################################################################################### +# DISCLAIMER # +# Copied from https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/hack/dind#L28-L37 # +# Permission granted by Akihiro Suda (https://github.com/rancher/k3d/issues/493#issuecomment-827405962) # +# Moby License Apache 2.0: https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/LICENSE # +######################################################################################################################################### +# only run this if rancher is not running in kubernetes cluster +if [ ! -e /run/secrets/kubernetes.io/serviceaccount ] && [ -f /sys/fs/cgroup/cgroup.controllers ]; then + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + mkdir -p /sys/fs/cgroup/init + xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' <"/sys/fs/cgroup/cgroup.controllers" >"/sys/fs/cgroup/cgroup.subtree_control" +fi + +rm -f /var/lib/rancher/k3s/server/cred/node-passwd +if [ -e /var/lib/rancher/management-state/etcd ] && [ ! -e /var/lib/rancher/k3s/server/db/etcd ]; then + mkdir -p /var/lib/rancher/k3s/server/db + ln -sf /var/lib/rancher/management-state/etcd /var/lib/rancher/k3s/server/db/etcd + echo -n 'default' > /var/lib/rancher/k3s/server/db/etcd/name +fi +if [ -e /var/lib/rancher/k3s/server/db/etcd ]; then + echo "INFO: Running k3s server --cluster-init --cluster-reset" + set +e + k3s server --cluster-init --cluster-reset &> ./k3s-cluster-reset.log + K3S_CR_CODE=$? + if [ "${K3S_CR_CODE}" -ne 0 ]; then + echo "ERROR:" && cat ./k3s-cluster-reset.log + rm -f /var/lib/rancher/k3s/server/db/reset-flag + exit ${K3S_CR_CODE} + fi + set -e +fi +if [ -x "$(command -v update-ca-certificates)" ]; then + update-ca-certificates +fi +if [ -x "$(command -v c_rehash)" ]; then + c_rehash +fi +exec tini -- rancher --http-listen-port=80 --https-listen-port=443 --audit-log-path=${AUDIT_LOG_PATH} --audit-level=${AUDIT_LEVEL} --audit-log-maxage=${AUDIT_LOG_MAXAGE} --audit-log-maxbackup=${AUDIT_LOG_MAXBACKUP} --audit-log-maxsize=${AUDIT_LOG_MAXSIZE} "${@}" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/installer-run.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/installer-run.sh new file mode 100755 index 0000000..8d0eee1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/installer-run.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env sh +./helm upgrade --create-namespace --install --values "$RANCHER_VALUES" --namespace cattle-system --wait rancher ./*.tgz diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/jailer.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/jailer.sh new file mode 100755 index 0000000..e2c9a6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/jailer.sh @@ -0,0 +1,100 @@ +#!/bin/bash +set -e + +NAME=$1 + +if [[ -z "$1" ]] + then + echo "No name supplied" + exit 1 +fi + +# Build the jail directory structure +mkdir -p /opt/jail/$NAME/dev +mkdir -p /opt/jail/$NAME/etc/ssl +mkdir -p /opt/jail/$NAME/usr/bin +mkdir -p /opt/jail/$NAME/management-state/node/nodes +mkdir -p /opt/jail/$NAME/var/lib/rancher/management-state/bin +mkdir -p /opt/jail/$NAME/management-state/bin +mkdir -p /opt/jail/$NAME/tmp +mkdir -p /opt/jail/$NAME/bin + +# Copy over required files to the jail +if [[ -d /lib64 ]]; then + cp -r /lib64 /opt/jail/$NAME + cp -r /usr/lib64 /opt/jail/$NAME/usr +fi + +cp -r /lib /opt/jail/$NAME +cp -r /usr/lib /opt/jail/$NAME/usr +cp /var/lib/ca-certificates/ca-bundle.pem /opt/jail/$NAME/etc/ssl +cp /etc/resolv.conf /opt/jail/$NAME/etc/ +cp /etc/passwd /opt/jail/$NAME/etc/ +cp /etc/hosts /opt/jail/$NAME/etc/ +cp /etc/nsswitch.conf /opt/jail/$NAME/etc/ + +if [ -d /var/lib/rancher/management-state/bin ] && [ "$(ls -A /var/lib/rancher/management-state/bin)" ]; then + ( cd /var/lib/rancher/management-state/bin + for f in *; do + if [ ! -f "/opt/drivers/management-state/bin/$f" ]; then + cp "$f" "/opt/drivers/management-state/bin/$f" + fi + done + ) +fi + +if [[ -f /etc/ssl/certs/ca-additional.pem ]]; then + cp /etc/ssl/certs/ca-additional.pem /opt/jail/$NAME/etc/ssl +fi + +if [[ -f /etc/rancher/ssl/cacerts.pem ]]; then + cp /etc/rancher/ssl/cacerts.pem /opt/jail/$NAME/etc/ssl +fi + +# Hard link driver binaries +cp -r -l /opt/drivers/management-state/bin /opt/jail/$NAME/var/lib/rancher/management-state + +# Hard link rancher-machine into the jail +cp -l /usr/bin/rancher-machine /opt/jail/$NAME/usr/bin + +# Hard link helm_2 into the jail +cp -l /usr/bin/rancher-helm /opt/jail/$NAME/usr/bin + +# Hard link helm_3 into the jail +cp -l /usr/bin/helm_v3 /opt/jail/$NAME/usr/bin + +# Hard link tiller into the jail +cp -l /usr/bin/rancher-tiller /opt/jail/$NAME/usr/bin + +# Hard link kustomize into the jail +cp -l /usr/bin/kustomize /opt/jail/$NAME/usr/bin + +# Hard link custom kustomize script into jail +cp -l /usr/bin/kustomize.sh /opt/jail/$NAME + +# Hard link ssh into the jail +cp -l /usr/bin/ssh /opt/jail/$NAME/usr/bin + +# Hard link nc into the jail +cp -l /usr/bin/nc /opt/jail/$NAME/usr/bin + +# Hard link cat into the jail +cp -l /bin/cat /opt/jail/$NAME/bin/ + +# Hard link bash into the jail +cp -l /bin/bash /opt/jail/$NAME/bin/ + +# Hard link sh into the jail +cp -l /bin/sh /opt/jail/$NAME/bin/ + +# Hard link rm into the jail +cp -l /bin/rm /opt/jail/$NAME/bin/ + +# Hard link mkisofs into the jail +cp -l /usr/bin/mkisofs /opt/jail/$NAME/usr/bin + +cd /dev +# tar copy /dev excluding mqueue and shm +tar cf - --exclude=mqueue --exclude=shm --exclude=pts . | (cd /opt/jail/${NAME}/dev; tar xfp -) + +touch /opt/jail/$NAME/done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kubectl-shell.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kubectl-shell.sh new file mode 100755 index 0000000..558e485 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kubectl-shell.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +token=$1 +cluster=$2 +cacerts=$3 + +if [ -z "${token}" ]; then + echo No token provided + exit 1 +fi + +if [ -z "${cluster}" ]; then + echo No cluster provided + exit 1 +fi + +echo "# Run kubectl commands inside here" +echo "# e.g. kubectl get all" +export TERM=screen-256color +export TOKEN=${token} +export CLUSTER=${cluster} +export CACERTS=${cacerts} +unshare --fork --pid --mount-proc --mount shell-setup.sh || true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kustomize.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kustomize.sh new file mode 100755 index 0000000..88541c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/kustomize.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cat <&0 > "$CATTLE_KUSTOMIZE_YAML"/all.yaml + +kustomize build "$CATTLE_KUSTOMIZE_YAML" && rm "$CATTLE_KUSTOMIZE_YAML"/all.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/run.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/run.sh new file mode 100755 index 0000000..0a8a56e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/run.sh @@ -0,0 +1,260 @@ +#!/bin/bash +set -e + +# Logging helper functions +info() +{ + echo "INFO:" "$@" 1>&2 +} + +error() +{ + echo "ERROR:" "$@" 1>&2 +} +warn() +{ + echo "WARN:" "$@" 1>&2 +} + +# Print all given arguments +if [ $# -ne 0 ]; then + info "Arguments: $(echo $@ | sed -e 's/\(token\s\)\w*/\1REDACTED/')" +fi + +if [ "$1" = "--" ]; then + shift 1 + exec "$@" +fi + +if [ "$CLUSTER_CLEANUP" = true ]; then + exec agent +fi + +get_address() +{ + local address=$1 + # If nothing is given, return empty (it will be automatically determined later if empty) + if [ -z $address ]; then + echo "" + # If given address is a network interface on the system, retrieve configured IP on that interface (only the first configured IP is taken) + elif [ -n "$(find /sys/devices -name $address)" ]; then + echo $(ip addr show dev $address | grep -w inet | awk '{print $2}' | cut -f1 -d/ | head -1) + # Loop through cloud provider options to get IP from metadata, if not found return given value + else + case $address in + awslocal) + echo $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) + ;; + awspublic) + echo $(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) + ;; + doprivate) + echo $(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address) + ;; + dopublic) + echo $(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address) + ;; + azprivate) + echo $(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text") + ;; + azpublic) + echo $(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text") + ;; + gceinternal) + echo $(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) + ;; + gceexternal) + echo $(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip) + ;; + packetlocal) + echo $(curl -s https://metadata.packet.net/2009-04-04/meta-data/local-ipv4) + ;; + packetpublic) + echo $(curl -s https://metadata.packet.net/2009-04-04/meta-data/public-ipv4) + ;; + ipify) + echo $(curl -s https://api.ipify.org) + ;; + *) + echo $address + ;; + esac + fi +} + +check_url() +{ + local url=$1 + local err + err=$(curl --insecure -sS -fL -o /dev/null --stderr - $url | head -n1 ; exit ${PIPESTATUS[0]}) + if [ $? -eq 0 ] + then + echo "" + else + echo ${err} | sed -e 's/^curl: ([0-9]\+) //' + fi +} + +check_x509_cert() +{ + local cert=$1 + local err + err=$(openssl x509 -in $cert -noout 2>&1) + if [ $? -eq 0 ] + then + echo "" + else + echo ${err} + fi +} + +export CATTLE_ADDRESS +export CATTLE_AGENT_CONNECT +export CATTLE_INTERNAL_ADDRESS +export CATTLE_NODE_NAME +export CATTLE_ROLE +export CATTLE_SERVER +export CATTLE_TOKEN +export CATTLE_NODE_LABEL +export CATTLE_WRITE_CERT_ONLY +export CATTLE_NODE_TAINTS + +while true; do + case "$1" in + -d | --debug) DEBUG=true ;; + -s | --server) shift; CATTLE_SERVER=$1 ;; + -t | --token) shift; CATTLE_TOKEN=$1 ;; + -c | --ca-checksum) shift; CATTLE_CA_CHECKSUM=$1 ;; + -a | --all-roles) ALL=true ;; + -e | --etcd) ETCD=true ;; + -w | --worker) WORKER=true ;; + -p | --controlplane) CONTROL=true ;; + -n | --node-name) shift; CATTLE_NODE_NAME=$1 ;; + -r | --no-register) CATTLE_AGENT_CONNECT=true ;; + -a | --address) shift; CATTLE_ADDRESS=$1 ;; + -i | --internal-address) shift; CATTLE_INTERNAL_ADDRESS=$1 ;; + -l | --label) shift; CATTLE_NODE_LABEL+=",$1" ;; + -o | --only-write-certs) CATTLE_WRITE_CERT_ONLY=true ;; + --taints) shift; CATTLE_NODE_TAINTS+=",$1" ;; + *) break; + esac + shift +done + +if [ "$DEBUG" = true ]; then + set -x +fi + +if [ "$CATTLE_CLUSTER" != "true" ]; then + if [ ! -w /var/run/docker.sock ] || [ ! -S /var/run/docker.sock ]; then + warn "Docker socket is not available!" + warn "Please bind mount in the docker socket to /var/run/docker.sock if docker errors occur" + warn "example: docker run -v /var/run/docker.sock:/var/run/docker.sock ..." + fi +fi + +if [ -z "$CATTLE_NODE_NAME" ]; then + CATTLE_NODE_NAME=$(hostname -s) +fi + +export CATTLE_ADDRESS=$(get_address $CATTLE_ADDRESS) +export CATTLE_INTERNAL_ADDRESS=$(get_address $CATTLE_INTERNAL_ADDRESS) + +if [ -z "$CATTLE_ADDRESS" ]; then + # Example output: '8.8.8.8 via 10.128.0.1 dev ens4 src 10.128.0.34 uid 0' + CATTLE_ADDRESS=$(ip -o route get 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p') +fi + +if [ "$CATTLE_K8S_MANAGED" != "true" ]; then + if [ -z "$CATTLE_TOKEN" ]; then + error -- --token is a required option + exit 1 + fi + + if [ -z "$CATTLE_ADDRESS" ]; then + error -- --address is a required option + exit 1 + fi +fi + +if [ "$ALL" = true ]; then + CATTLE_ROLE="etcd,worker,controlplane" +else + if [ "$ETCD" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},etcd" + fi + if [ "$WORKER" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},worker" + fi + if [ "$CONTROL" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},controlplane" + fi +fi + +if [ -z "$CATTLE_SERVER" ]; then + error -- --server is a required option + exit 1 +fi + +info "Environment: $(echo $(printenv | grep CATTLE | sort | sed -e 's/\(CATTLE_TOKEN=\).*/\1REDACTED/'))" +info "Using resolv.conf: $(echo $(cat /etc/resolv.conf | grep -v ^#))" +if grep -E -q '^nameserver 127.*.*.*|^nameserver localhost|^nameserver ::1' /etc/resolv.conf; then + warn "Loopback address found in /etc/resolv.conf, please refer to the documentation how to configure your cluster to resolve DNS properly" +fi + +CATTLE_SERVER_PING="${CATTLE_SERVER}/ping" +err=$(check_url $CATTLE_SERVER_PING) +if [[ $err ]]; then + error "${CATTLE_SERVER_PING} is not accessible (${err})" + exit 1 +else + info "${CATTLE_SERVER_PING} is accessible" +fi + +# Extract hostname from URL +CATTLE_SERVER_HOSTNAME=$(echo $CATTLE_SERVER | sed -e 's/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/') +CATTLE_SERVER_HOSTNAME_WITH_PORT=$(echo $CATTLE_SERVER | sed -e 's/[^/]*\/\/\([^@]*@\)\?\(.*\).*/\2/') +# Resolve IPv4 address(es) from hostname +RESOLVED_ADDR=$(getent ahostsv4 $CATTLE_SERVER_HOSTNAME | sed -n 's/ *STREAM.*//p') + +# If CATTLE_SERVER_HOSTNAME equals RESOLVED_ADDR, its an IP address and there is nothing to resolve +if [ "${CATTLE_SERVER_HOSTNAME}" != "${RESOLVED_ADDR}" ]; then + info "${CATTLE_SERVER_HOSTNAME} resolves to $(echo $RESOLVED_ADDR)" +fi + +if [ -n "$CATTLE_CA_CHECKSUM" ]; then + temp=$(mktemp) + curl --insecure -s -fL $CATTLE_SERVER/v3/settings/cacerts | jq -r '.value | select(length > 0)' > $temp + if [ ! -s $temp ]; then + error "The environment variable CATTLE_CA_CHECKSUM is set but there is no CA certificate configured at $CATTLE_SERVER/v3/settings/cacerts" + exit 1 + fi + err=$(check_x509_cert $temp) + if [[ $err ]]; then + error "Value from $CATTLE_SERVER/v3/settings/cacerts does not look like an x509 certificate (${err})" + error "Retrieved cacerts:" + cat $temp + exit 1 + else + info "Value from $CATTLE_SERVER/v3/settings/cacerts is an x509 certificate" + fi + CATTLE_SERVER_CHECKSUM=$(sha256sum $temp | awk '{print $1}') + if [ $CATTLE_SERVER_CHECKSUM != $CATTLE_CA_CHECKSUM ]; then + rm -f $temp + error "Configured cacerts checksum ($CATTLE_SERVER_CHECKSUM) does not match given --ca-checksum ($CATTLE_CA_CHECKSUM)" + error "Please check if the correct certificate is configured at $CATTLE_SERVER/v3/settings/cacerts" + exit 1 + else + mkdir -p /etc/kubernetes/ssl/certs + mv $temp /etc/kubernetes/ssl/certs/serverca + chmod 755 /etc/kubernetes/ssl + chmod 700 /etc/kubernetes/ssl/certs + chmod 600 /etc/kubernetes/ssl/certs/serverca + mkdir -p /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT + cp /etc/kubernetes/ssl/certs/serverca /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT/ca.crt + + fi +fi + +exec tini -- agent + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/shell-setup.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/shell-setup.sh new file mode 100755 index 0000000..be95d4e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/shell-setup.sh @@ -0,0 +1,67 @@ +#!/bin/bash +set -e + +mkdir -p /nonexistent +mount -t tmpfs tmpfs /nonexistent +cd /nonexistent + +mkdir -p .kube/certs + +SERVER="${CATTLE_SERVER}/k8s/clusters/${CLUSTER}" + +if [ -f /etc/kubernetes/ssl/certs/serverca ]; then + cp /etc/kubernetes/ssl/certs/serverca .kube/certs/ca.crt + chmod 666 .kube/certs/ca.crt + +elif [ -n "${CACERTS}" ]; then + echo "${CACERTS}" | base64 -d > .kube/certs/ca.crt + chmod 666 .kube/certs/ca.crt +fi + +if [ -f /nonexistent/.kube/certs/ca.crt ] && ! curl -s $SERVER > /dev/null; then + CERT=" certificate-authority: /nonexistent/.kube/certs/ca.crt" +fi + +for i in /run /var/run /etc/kubernetes; do + mount -t tmpfs tmpfs $i +done + +cat < .kube/config +apiVersion: v1 +kind: Config +clusters: +- cluster: + api-version: v1 + server: "${CATTLE_SERVER}/k8s/clusters/${CLUSTER}" +${CERT} + name: "Default" +contexts: +- context: + cluster: "Default" + user: "Default" + name: "Default" +current-context: "Default" +users: +- name: "Default" + user: + token: "${TOKEN}" +EOF + +cp /etc/skel/.bashrc . +cat >> .bashrc < + +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" +$CATTLE_PREFIX_PATH = Get-Env -Key "CATTLE_PREFIX_PATH" + +# parse arguments +$vals = $null +for ($i = $args.Length; $i -ge 0; $i--) +{ + $arg = $args[$i] + switch -regex ($arg) + { + '^(--prefix-path)$' { + $CATTLE_PREFIX_PATH = ($vals | Select-Object -First 1) + $vals = $null + } + default { + if ($vals) { + $vals = ,$arg + $vals + } else { + $vals = @($arg) + } + } + } +} + +if ([string]::IsNullOrEmpty($CATTLE_PREFIX_PATH)) { + $CATTLE_PREFIX_PATH = "c:\" +} + +if ($CATTLE_PREFIX_PATH.Chars($CATTLE_PREFIX_PATH.Length - 1) -ne '\') { + # confirm trailing slash for path building below + $CATTLE_PREFIX_PATH = ($CATTLE_PREFIX_PATH + '\') +} + +$hostPrefixPath = $CATTLE_PREFIX_PATH -Replace "c:\\", "c:\host\" + + +# create directories on the host +# windows docker can only mount an existing path into containers +try +{ + New-Item -Force -ItemType Directory -Path @( + "$($hostPrefixPath)opt" + "$($hostPrefixPath)opt\bin" + "$($hostPrefixPath)opt\cni" + "$($hostPrefixPath)opt\cni\bin" + "$($hostPrefixPath)etc" + "$($hostPrefixPath)etc\rancher" + "$($hostPrefixPath)etc\rancher\wins" + "$($hostPrefixPath)etc\kubernetes" + "$($hostPrefixPath)etc\kubernetes\bin" + "$($hostPrefixPath)etc\cni" + "$($hostPrefixPath)etc\cni\net.d" + "$($hostPrefixPath)etc\nginx" + "$($hostPrefixPath)etc\nginx\logs" + "$($hostPrefixPath)etc\nginx\temp" + "$($hostPrefixPath)etc\nginx\conf" + "$($hostPrefixPath)etc\kube-flannel" + "$($hostPrefixPath)var" + "$($hostPrefixPath)var\run" + "$($hostPrefixPath)var\log" + "$($hostPrefixPath)var\log\pods" + "$($hostPrefixPath)var\log\containers" + "$($hostPrefixPath)var\lib" + "$($hostPrefixPath)var\lib\cni" + "$($hostPrefixPath)var\lib\rancher" + "$($hostPrefixPath)var\lib\rancher\rke" + "$($hostPrefixPath)var\lib\rancher\rke\log" + "$($hostPrefixPath)var\lib\kubelet" + "$($hostPrefixPath)var\lib\kubelet\volumeplugins" + "$($hostPrefixPath)run" + "c:\host\ProgramData\docker\certs.d" + ) | Out-Null +} catch { } + +# copy cleanup.ps1 & wins.exe to the host +# wins needs to run as a service on the host to accept requests from container +try +{ + Copy-Item -Force -Destination "$($hostPrefixPath)etc\rancher" -Path @( + "c:\etc\rancher\utils.psm1" + "c:\Windows\wins.exe" + ) +} catch { } + +$verification = @" +Log-Info "Detecting running permission ..." +if (-not (Is-Administrator)) +{ + Log-Fatal "You need elevated Administrator privileges in order to run this script, start Windows PowerShell by using the Run as Administrator option" +} + +Log-Info "Detecting host CPU reservation ..." +try +{ + `$cpuLogicalProccessors = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty NumberOfLogicalProcessors + if (`$cpuLogicalProccessors -le 1) { + Log-Fatal "The CPU resource could not satisfy the default reservation for both Windows system and Kuberentes components, please increase the CPU resource to more than 2 logic processors" + } elseif (`$cpuLogicalProccessors -lt 2) { + Log-Warn "The CPU resource only satisfies the lowest limit for running Kubernetes components" + Log-Warn "Please increase the CPU resource to more than 2 logic processors if you are unable to schedule Pods on this Node" + } +} +catch +{ + Log-Warn "Could not detect the CPU resource: `$(`$_.Exception.Message)" +} + +Log-Info "Detecting host RAM reservation ..." +try +{ + `$lowestLimitGB = 2.5 + `$systemType = Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty PCSystemType + if (`$systemType -eq 1) { + # system with GUI + `$lowestLimitGB = 4.5 + } + + `$ramTotalGB = `$(Get-WmiObject -Class Win32_ComputerSystem | Select-Object -ExpandProperty TotalPhysicalMemory)/1GB + if (`$ramTotalGB -lt `$lowestLimitGB) { + Log-Fatal "The RAM resource could not satisfy the default reservation for both Windows system and Kubernetes components, please increase the RAM resource to more than `$lowestLimitGB GB" + } + + `$ramAvailableMB = `$(Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_Memory | Measure-Object -Sum -Property AvailableBytes | Select-Object -ExpandProperty Sum)/1MB + if (`$ramAvailableMB -le 500) { + Log-Fatal "The RAM resource could not satisfy the default reservation for Kuberentes components, please increase the RAM resource to more than `$lowestLimitGB GB" + } elseif (`$ramAvailableMB -le 600) { + Log-Warn "The RAM resource only satisfies the lowest limit for running Kubernetes components" + Log-Warn "Please increase the RAM resource to more than `$lowestLimitGB GB if you are unable to schedule Pods on this Node" + } +} +catch +{ + Log-Warn "Could not detect the RAM resource: `$(`$_.Exception.Message)" +} + +Log-Info "Detecting host DISK reservation ..." +try +{ + `$diskAvaliableGB = `$(Get-WmiObject -Class Win32_LogicalDisk | Where-Object {`$_.DeviceID -eq "C:"} | Select-Object -ExpandProperty Size)/1GB + if (`$diskAvaliableGB -lt 29.5) { + Log-Fatal "The DISK resource could not satisfy the default reservation for both Windows system and Kubernetes components, please increase the DISK resource to more than 30 GB" + } elseif (`$diskAvaliableGB -lt 49.5) { + Log-Warn "The DISK resource only satisfies the lowest limit for running Kubernetes components" + Log-Warn "Please increase the DISK resource to more than 50 GB if you are unable to schedule Pods on this Node" + } +} +catch +{ + Log-Warn "Could not detect the DISK resource: `$(`$_.Exception.Message)" +} + +Log-Info "Detecting host Docker named pipe existing ..." +`$dockerNPipe = Get-ChildItem //./pipe/ -ErrorAction Ignore | ? Name -eq "docker_engine" +if (-not `$dockerNPipe) +{ + Log-Warn "Default Docker named pipe is not available" + Log-Warn "Please create '//./pipe/docker_engine' named pipe to access docker daemon if docker errors occur" +} + +Log-Info "Detecting host Docker platform name..." +try +{ + `$dockerPlatform = docker.exe version -f "{{.Server.Platform.Name}}" + if (-not (`$dockerPlatform -like '*Enterprise*') -AND -not (`$dockerPlatform -eq 'Mirantis Container Runtime')) + { + Log-Fatal "Only Docker EE or Mirantis Container Runtime supported" + } +} +catch +{ + Log-Fatal "Could not find Docker service: `$(`$_.Exception.Message)" +} + +Log-Info "Detecting host network interface ..." +`$vNetAdapters = Get-HnsNetwork | Select-Object -ExpandProperty "Subnets" | Select-Object -ExpandProperty "GatewayAddress" +`$allNetAdapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=True" | Sort-Object Index | ForEach-Object { `$_.IPAddress[0] } | Where-Object { -not (`$vNetAdapters -contains `$_) } +`$networkCount = `$allNetAdapters | Measure-Object | Select-Object -ExpandProperty "Count" +if (`$networkCount -gt 1) +{ + Log-Warn "More than 1 network interface was found: `$(`$allNetAdapters -join ", ")" + Log-Warn "Please indicate --internal-address when adding failed" +} + +Log-Info "Configuring host Docker Service to start automatically..." +try +{ + Get-Service -Name "docker" -ErrorAction Ignore | Where-Object {`$_.StartType -ne "Automatic"} | Set-Service -StartupType Automatic +} +catch +{ + Log-Warn "Could not configure the Docker service to start automatically: `$(`$_.Exception.Message)" + Log-Warn "Please change the Docker service 'StartupType' to 'Automatic'" +} + +Log-Info "Enabling host msiscsi service to support iscsi storage ..." +`$svcMsiscsi = Get-Service -Name "msiscsi" -ErrorAction Ignore +if (`$svcMsiscsi -and (`$svcMsiscsi.Status -ne "Running")) +{ + Set-Service -Name "msiscsi" -StartupType Automatic -WarningAction Ignore + Start-Service -Name "msiscsi" -ErrorAction Ignore -WarningAction Ignore + if (-not `$?) { + Log-Warn "Failed to start msiscsi service, you may not be able to use the iSCSI flexvolume properly" + } +} +"@ + +# allow user to disable the verification +if ($env:WITHOUT_VERIFICATION -eq "true") { + $verification = "" +} + +Out-File -Encoding ascii -FilePath "$($hostPrefixPath)etc\rancher\bootstrap.ps1" -InputObject @" +`$ErrorActionPreference = 'Stop' +`$WarningPreference = 'SilentlyContinue' +`$VerbosePreference = 'SilentlyContinue' +`$DebugPreference = 'SilentlyContinue' +`$InformationPreference = 'SilentlyContinue' + +# import modules +Import-Module -WarningAction Ignore -Name "`$PSScriptRoot\utils.psm1" + +# remove script +Remove-Item -Force -Path "`$PSScriptRoot\bootstrap.ps1" -ErrorAction Ignore + +$verification + +# repair Get-GcePdName method +# this is a stopgap, we could drop this after https://github.com/kubernetes/kubernetes/issues/74674 fixed +# related: rke-tools container +`$getGcePodNameCommand = Get-Command -Name "Get-GcePdName" -ErrorAction Ignore +if (-not `$getGcePodNameCommand) +{ + `$profilePath = "`$PsHome\profile.ps1" + if (-not (Test-Path `$profilePath)) { + New-Item -ItemType File -Path `$profilePath -ErrorAction Ignore | Out-Null + } + `$appendProfile = @' +Unblock-File -Path DLLPATH -ErrorAction Ignore +Import-Module -Name DLLPATH -ErrorAction Ignore +'@ + Add-Content -Path `$profilePath -Value `$appendProfile.replace('DLLPATH', "$($CATTLE_PREFIX_PATH)run\GetGcePdName.dll") -ErrorAction Ignore +} + +# clean up the stale HNS network if required +try +{ + # warm up HNS network + 1..5 | ForEach-Object { Invoke-HNSRequest -Method "GET" -Type "networks" | Out-Null } + + # remove the HNS networks + Invoke-HNSRequest -Method "GET" -Type "networks" | Where-Object {@('cbr0', 'vxlan0') -contains `$_.Name} | ForEach-Object { + Log-Info "Cleaning up stale HNSNetwork `$(`$_.Name) ..." + Invoke-HNSRequest -Method "DELETE" -Type "networks" -Id `$_.Id + } + + # remove the HNS policies + Invoke-HNSRequest -Method "GET" -Type "policylists" | Where-Object {-not [string]::IsNullOrEmpty(`$_.Id)} | ForEach-Object { + Log-Info "Cleaning up HNSPolicyList `$(`$_.Id) ..." + Invoke-HNSRequest -Method "DELETE" -Type "policylists" -Id `$_.Id + } +} +catch +{ + Log-Warn "Could not clean: `$(`$_.Exception.Message)" +} + +# make a powershell copy for wins to use +Copy-Item $($(Get-Command powershell).Source) $($CATTLE_PREFIX_PATH)etc\rancher\powershell.exe + +# output wins config +@{ + whiteList = @{ + processPaths = @( + "$($CATTLE_PREFIX_PATH)etc\wmi-exporter\wmi-exporter.exe" + "$($CATTLE_PREFIX_PATH)etc\kubernetes\bin\kube-proxy.exe" + "$($CATTLE_PREFIX_PATH)etc\kubernetes\bin\kubelet.exe" + "$($CATTLE_PREFIX_PATH)etc\nginx\nginx.exe" + "$($CATTLE_PREFIX_PATH)opt\bin\flanneld.exe" + "$($CATTLE_PREFIX_PATH)etc\rancher\wins\wins-upgrade.exe" + "$($CATTLE_PREFIX_PATH)etc\rancher\powershell.exe" + "$($CATTLE_PREFIX_PATH)etc\windows-exporter\windows-exporter.exe" + ) + proxyPorts = @( + 9796 + ) + } +} | ConvertTo-Json -Compress -Depth 32 | Out-File -NoNewline -Encoding utf8 -Force -FilePath "$($CATTLE_PREFIX_PATH)etc\rancher\wins\config" + +# register wins +Start-Process -NoNewWindow -Wait `` + -FilePath "$($CATTLE_PREFIX_PATH)etc\rancher\wins.exe" `` + -ArgumentList "srv app run --register" + +# start wins +Start-Service -Name "rancher-wins" -ErrorAction Ignore + +# run agent +Start-Process -NoNewWindow -Wait `` + -FilePath "docker.exe" `` + -ArgumentList "run -d --restart=unless-stopped -e CATTLE_PREFIX_PATH=$CATTLE_PREFIX_PATH -v \\.\pipe\docker_engine:\\.\pipe\docker_engine -v c:\ProgramData\docker\certs.d:c:\etc\docker\certs.d -v $($CATTLE_PREFIX_PATH)etc\kubernetes:c:\etc\kubernetes -v \\.\pipe\rancher_wins:\\.\pipe\rancher_wins -v $($CATTLE_PREFIX_PATH)etc\rancher\wins:c:\etc\rancher\wins $($env:AGENT_IMAGE) execute $($args -join " ")" +"@ + + +Write-Output -InputObject "$($CATTLE_PREFIX_PATH)etc\rancher\bootstrap.ps1" + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/entrypoint.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/entrypoint.ps1 new file mode 100644 index 0000000..ad42413 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/entrypoint.ps1 @@ -0,0 +1,64 @@ +<# + entry.ps1 detects the first argument as command, and then + select the corresponding execution logic + #> + +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +# to support functionality in linux agent to bypass run.sh using -- +if ($args[0] -eq "--") { + $args = $args[1..($args.Length-1)] +} + +function Run-PowerShell +{ + param ( + [parameter(Mandatory = $false)] [string[]]$ArgumentList + ) + + try { + if ($ArgumentList) { + Start-Process -NoNewWindow -Wait -FilePath "powershell" -ArgumentList $ArgumentList + } else { + Start-Process -NoNewWindow -Wait -FilePath "powershell" + } + } catch { + $errMsg = $_.Exception.Message + if ($errMsg -like "*This command cannot be run due to the error: *") { + if ($ArgumentList) { + Start-Process -NoNewWindow -Wait -FilePath "pwsh" -ArgumentList $ArgumentList + } else { + Start-Process -NoNewWindow -Wait -FilePath "pwsh" + } + } else { + throw $_ + } + } +} + +$psArgs = $null +$componentScript = "$PSScriptRoot\$($args[0]).ps1" +if (-not (Test-Path -ErrorAction Ignore -Path $componentScript)) +{ + if ($env:CATTLE_AGENT_CONNECT -eq "true") + { + $psArgs = @("-NoLogo", "-NonInteractive", "-File", "$PSScriptRoot\execute.ps1") + $args[0..$args.Length] + } +} +else +{ + $psArgs = @("-NoLogo", "-NonInteractive", "-File", "$PSScriptRoot\$($args[0]).ps1") + $args[1..$args.Length] +} + + +if ($psArgs) +{ + Run-PowerShell -ArgumentList $psArgs + exit 0 +} + +Run-PowerShell diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/execute.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/execute.ps1 new file mode 100644 index 0000000..ceb7742 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/execute.ps1 @@ -0,0 +1,350 @@ +<# + run.ps1 executes the agent + #> + +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +function Get-Address +{ + param( + [parameter(Mandatory = $false)] [string]$Addr + ) + + if (-not $Addr) { + return "" + } + + # If given address is a network interface on the system, retrieve configured IP on that interface (only the first configured IP is taken) + try { + $getAdapterJson = wins.exe cli net get --name $Addr + if ($?) { + $namedNetwork = $getAdapterJson | ConvertTo-JsonObj + if ($namedNetwork) { + return $namedNetwork.AddressCIDR -replace "/32","" + } + } + } catch {} + + # Repair the container route for `169.254.169.254` before cloud provider query + $actualGateway = $(route.exe print 0.0.0.0 | Where-Object {$_ -match '0\.0\.0\.0.*[a-z]'} | Select-Object -First 1 | ForEach-Object {($_ -replace '0\.0\.0\.0|[a-z]|\s+',' ').Trim() -split ' '} | Select-Object -First 1) + $expectedGateway = $(route.exe print 169.254.169.254 | Where-Object {$_ -match '169\.254\.169\.254'} | Select-Object -First 1 | ForEach-Object {($_ -replace '169\.254\.169\.254|255\.255\.255\.255|[a-z]|\s+',' ').Trim() -split ' '} | Select-Object -First 1) + if ($actualGateway -ne $expectedGateway) { + $errMsg = $(route.exe add 169.254.169.254 MASK 255.255.255.255 $actualGateway METRIC 1) + if (-not $?) { + Log-Error "Could not repair contain route for using cloud provider" + } + } + + # Loop through cloud provider options to get IP from metadata, if not found return given value + switch ($Addr) + { + "awslocal" { + return $(curl.exe -s "http://169.254.169.254/latest/meta-data/local-ipv4") + } + "awspublic" { + return $(curl.exe -s "http://169.254.169.254/latest/meta-data/public-ipv4") + } + "doprivate" { + return $(curl.exe -s "http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address") + } + "dopublic" { + return $(curl.exe -s "http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address") + } + "azprivate" { + return $(curl.exe -s -H "Metadata:true" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text") + } + "azpublic" { + return $(curl.exe -s -H "Metadata:true" "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text") + } + "gceinternal" { + return $(curl.exe -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip?alt=json") + } + "gceexternal" { + return $(curl.exe -s -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip?alt=json") + } + "packetlocal" { + return $(curl.exe -s "https://metadata.packet.net/2009-04-04/meta-data/local-ipv4") + } + "packetpublic" { + return $(curl.exe -s "https://metadata.packet.net/2009-04-04/meta-data/public-ipv4") + } + "ipify" { + return $(curl.exe -s "https://api.ipify.org") + } + } + + return $Addr +} + +# required envs +Set-Env -Key "DOCKER_HOST" -Value "npipe:////./pipe/docker_engine" +Set-Env -Key "CATTLE_ROLE" -Value "worker" + +# clean up +$CLUSTER_CLEANUP = Get-Env -Key "CLUSTER_CLEANUP" +if ($CLUSTER_CLEANUP -eq "true") +{ + Start-Process -NoNewWindow -Wait -FilePath "c:\etc\rancher\agent.exe" + exit 0 +} + +# init parameters +$CATTLE_SERVER = Get-Env -Key "CATTLE_SERVER" +$CATTLE_TOKEN = Get-Env -Key "CATTLE_TOKEN" +$CATTLE_NODE_NAME = Get-Env -Key "CATTLE_NODE_NAME" +$CATTLE_ADDRESS = Get-Env -Key "CATTLE_ADDRESS" +$CATTLE_INTERNAL_ADDRESS = Get-Env -Key "CATTLE_INTERNAL_ADDRESS" +$CATTLE_CA_CHECKSUM = Get-Env -Key "CATTLE_CA_CHECKSUM" +$CATTLE_NODE_LABEL = @() +$CATTLE_NODE_TAINTS = @() + +# parse arguments +$vals = $null +for ($i = $args.Length; $i -ge 0; $i--) +{ + $arg = $args[$i] + switch -regex ($arg) + { + '^(-d|--debug)$' { + Set-Env -Key "CATTLE_DEBUG" -Value "true" + $vals = $null + } + '^(-s|--server)$' { + $CATTLE_SERVER = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-t|--token)$' { + $CATTLE_TOKEN = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-c|--ca-checksum)$' { + $CATTLE_CA_CHECKSUM = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-all|--all-roles)$' { + $vals = $null + } + '^(-e|--etcd)$' { + $vals = $null + } + '^(-w|--worker)$' { + $vals = $null + } + '^(-p|--controlplane)$' { + $vals = $null + } + '^(-r|--node-name)$' { + $CATTLE_NODE_NAME = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-n|--no-register)$' { + Set-Env -Key "CATTLE_AGENT_CONNECT" -Value "true" + $vals = $null + } + '^(-a|--address)$' { + $CATTLE_ADDRESS = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-i|--internal-address)$' { + $CATTLE_INTERNAL_ADDRESS = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-l|--label)$' { + if ($vals) { + $CATTLE_NODE_LABEL += $vals + } + $vals = $null + } + '^(-o|--only-write-certs)$' { + Set-Env -Key "CATTLE_WRITE_CERT_ONLY" -Value "true" + $vals = $null + } + '^--taints$' { + if ($vals) { + $CATTLE_NODE_TAINTS += $vals + } + $vals = $null + } + default { + if ($vals) { + $vals = ,$arg + $vals + } else { + $vals = @($arg) + } + } + } +} + +# use the register token to request wins server +if (Test-Path -PathType Leaf -Path "c:\cattle-credentials\token") +{ + $token = Get-Content -Path "c:\cattle-credentials\token" -Raw -ErrorAction Ignore + Set-Env -Key "WINS_AUTH_TOKEN" -Value $token +} + +# check docker npipe +$CATTLE_CLUSTER = Get-Env -Key "CATTLE_CLUSTER" +if ($CATTLE_CLUSTER -ne "true") +{ + $dockerNPipe = Get-ChildItem //./pipe/ -ErrorAction Ignore | ? Name -eq "docker_engine" + if (-not $dockerNPipe) { + Log-Warn "Default docker named pipe is not found" + Log-Warn "Please bind mount in the docker named pipe to //./pipe/docker_engine if docker errors occur" + Log-Warn "example: docker run -v //./pipe/custom_docker_named_pipe://./pipe/docker_engine ..." + } +} + +# get address +$CATTLE_ADDRESS = Get-Address -Addr $CATTLE_ADDRESS +$CATTLE_INTERNAL_ADDRESS = Get-Address -Addr $CATTLE_INTERNAL_ADDRESS + +# get default network metadata when nodeName or address is blank +if ((-not $CATTLE_NODE_NAME) -or (-not $CATTLE_ADDRESS)) +{ + $getAdapterJson = wins.exe cli net get + if ($?) { + $defaultNetwork = $getAdapterJson | ConvertTo-JsonObj + if ($defaultNetwork) { + if (-not $CATTLE_NODE_NAME) { + $CATTLE_NODE_NAME = $defaultNetwork.HostName + $CATTLE_NODE_NAME = $CATTLE_NODE_NAME.ToLower() + } + + if (-not $CATTLE_ADDRESS) { + $CATTLE_ADDRESS = $defaultNetwork.AddressCIDR -replace "/32","" + } + } else { + Log-Warn "Could not convert '$getAdapterJson' to json object" + } + } else { + Log-Warn "Could not get host network metadata: $getAdapterJson" + } +} + +# check token and address +$CATTLE_K8S_MANAGED = Get-Env -Key "CATTLE_K8S_MANAGED" +if ($CATTLE_K8S_MANAGED -ne "true") +{ + if (-not $CATTLE_TOKEN) { + Log-Fatal "--token is a required option" + } + if (-not $CATTLE_ADDRESS) { + Log-Fatal "--address is a required option" + } +} + +# check rancher server address +if (-not $CATTLE_SERVER) +{ + Log-Fatal "--server is a required option" +} + +# check rancher server +try +{ + curl.exe --insecure -s -fL "$CATTLE_SERVER/ping" | Out-Null + if ($?) { + Log-Info "$CATTLE_SERVER is accessible" + } else { + Log-Fatal "$CATTLE_SERVER is not accessible" + } +} +catch +{ + Log-Fatal "$CATTLE_SERVER is not accessible: $($_.Exception.Message)" +} + +# download cattle server CA +if ($CATTLE_CA_CHECKSUM) +{ + $sslCertDir = Get-Env -Key "SSL_CERT_DIR" + $server = $CATTLE_SERVER + $caChecksum = $CATTLE_CA_CHECKSUM + $temp = New-TemporaryFile + $cacerts = $null + try { + $cacerts = $(curl.exe --insecure -s -fL "$server/v3/settings/cacerts" | ConvertTo-JsonObj).value + } catch {} + if (-not $cacerts) { + Log-Fatal "Could not get cattle server CA from $server" + } + + $cacerts + "`n" | Out-File -NoNewline -Encoding ascii -FilePath $temp.FullName + $tempHasher = Get-FileHash -LiteralPath $temp.FullName -Algorithm SHA256 + if ($tempHasher.Hash.ToLower() -ne $caChecksum.ToLower()) { + $temp.Delete() + Log-Fatal "Actual cattle server CA checksum is $($tempHasher.Hash.ToLower()), $server/v3/settings/cacerts does not match $($caChecksum.ToLower())" + } + Remove-Item -Force -Recurse -Path "$sslCertDir\serverca" -ErrorAction Ignore + New-Item -Force -ItemType Directory -Path $sslCertDir -ErrorAction Ignore | Out-Null + $temp.MoveTo("$sslCertDir\serverca") + + # import the self-signed certificate + $caBytes = $null + Get-Content "$sslCertDir\serverca" | % { + if ($_ -match '-+BEGIN CERTIFICATE-+') { + $caBytes = @() + } elseif ($_ -match '-+END CERTIFICATE-+') { + $caTemp = New-TemporaryFile + $caString = [Convert]::ToBase64String($caBytes) + Set-Content -Value $caString -Path $caTemp.FullName + certoc.exe -addstore root $caTemp.FullName | Out-Null + if (-not $?) { + $caTemp.Delete() + Log-Fatal "Failed to import rancher server certificates to Root" + } + $caTemp.Delete() + } else { + $caBytes += [Convert]::FromBase64String($_) + } + } + + $CATTLE_SERVER_HOSTNAME = ([System.Uri]"$server").Host + $CATTLE_SERVER_HOSTNAME_WITH_PORT = ([System.Uri]"$server").Authority + + # windows path could not allow colons + $CATTLE_SERVER_HOSTNAME_WITH_PORT = $CATTLE_SERVER_HOSTNAME_WITH_PORT -replace ":", "" + + $dockerCertsPath = "c:\etc\docker\certs.d\$CATTLE_SERVER_HOSTNAME_WITH_PORT" + New-Item -Force -ItemType Directory -Path $dockerCertsPath -ErrorAction Ignore | Out-Null + Copy-Item -Force -Path "$sslCertDir\serverca" -Destination "$dockerCertsPath\ca.crt" -ErrorAction Ignore +} + +# add labels +$getVersionJson = wins.exe cli host get-version +if ($?) { + $windowsCurrentVersion = $getVersionJson | ConvertTo-JsonObj + if ($windowsCurrentVersion) { + $versionTag = "$($windowsCurrentVersion.CurrentMajorVersionNumber).$($windowsCurrentVersion.CurrentMinorVersionNumber).$($windowsCurrentVersion.CurrentBuildNumber).$($windowsCurrentVersion.UBR)" + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-version=$versionTag") + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-release-id=$($windowsCurrentVersion.ReleaseId)") + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-major-version=$($windowsCurrentVersion.CurrentMajorVersionNumber)") + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-minor-version=$($windowsCurrentVersion.CurrentMinorVersionNumber)") + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-kernel-version=$($windowsCurrentVersion.BuildLabEx)") + $CATTLE_NODE_LABEL += @("rke.cattle.io/windows-build=$($windowsCurrentVersion.CurrentBuild)") + } else { + Log-Warn "Could not convert Windows Current Version JSON '$getVersionJson' to object" + } +} else { + Log-Warn "Could not get host version: $getVersionJson" +} + +# set environment variables +Set-Env -Key "CATTLE_SERVER" -Value $CATTLE_SERVER +Set-Env -Key "CATTLE_TOKEN" -Value $CATTLE_TOKEN +Set-Env -Key "CATTLE_ADDRESS" -Val $CATTLE_ADDRESS +Set-Env -Key "CATTLE_INTERNAL_ADDRESS" -Val $CATTLE_INTERNAL_ADDRESS +Set-Env -Key "CATTLE_NODE_NAME" -Value $CATTLE_NODE_NAME +Set-Env -Key "CATTLE_NODE_LABEL" -Value $($CATTLE_NODE_LABEL -join ",") +Set-Env -Key "CATTLE_NODE_TAINTS" -Value $($CATTLE_NODE_TAINTS -join ",") + +# upgrade wins.exe +Transfer-File -Src c:\Windows\wins.exe -Dst c:\etc\rancher\wins\wins.exe + +Start-Process -NoNewWindow -Wait -FilePath "c:\etc\rancher\agent.exe" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/utils.psm1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/utils.psm1 new file mode 100644 index 0000000..71498fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/package/windows/utils.psm1 @@ -0,0 +1,191 @@ +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +function Log-Info +{ + Write-Host -NoNewline -ForegroundColor Blue "INFO: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Warn +{ + Write-Host -NoNewline -ForegroundColor DarkYellow "WARN: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Error +{ + Write-Host -NoNewline -ForegroundColor DarkRed "ERRO: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Fatal +{ + Write-Host -NoNewline -ForegroundColor DarkRed "FATA: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) + + exit 255 +} + +function Is-Administrator +{ + $p = New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent()) + return $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) +} + +function ConvertTo-JsonObj +{ + param ( + [parameter(Mandatory = $false, ValueFromPipeline = $true)] [string]$JSON + ) + + if (-not $JSON) { + return $null + } + + try { + $ret = $JSON | ConvertFrom-Json -ErrorAction Ignore -WarningAction Ignore + return $ret + } catch { + return $null + } +} + +function Set-Env +{ + param( + [parameter(Mandatory = $true)] [string]$Key, + [parameter(Mandatory = $false)] [string]$Value = "" + ) + + try { + [Environment]::SetEnvironmentVariable($Key, $Value, [EnvironmentVariableTarget]::Process) + } catch { + Log-Error "Could not set $Key = $Value in Process target: $($_.Exception.Message)" + } + + try { + [Environment]::SetEnvironmentVariable($Key, $Value, [EnvironmentVariableTarget]::Machine) + } catch { + Log-Error "Could not set $Key = $Value in Machine target: $($_.Exception.Message)" + } +} + +function Get-Env +{ + param( + [parameter(Mandatory = $true)] [string]$Key + ) + + try { + $val = [Environment]::GetEnvironmentVariable($Key, [EnvironmentVariableTarget]::Process) + if ($val) { + return $val + } + } catch { + Log-Error "Could not get $Key in Process target: $($_.Exception.Message)" + } + + try { + $val = [Environment]::GetEnvironmentVariable($Key, [EnvironmentVariableTarget]::Machine) + if ($val) { + return $val + } + } catch { + Log-Error "Could not get $Key in Machine target: $($_.Exception.Message)" + } + + return "" +} + +function Get-VmComputeNativeMethods() +{ + $ret = 'VmCompute.PrivatePInvoke.NativeMethods' -as [type] + if (-not $ret) { + $signature = @' +[DllImport("vmcompute.dll")] +public static extern void HNSCall([MarshalAs(UnmanagedType.LPWStr)] string method, [MarshalAs(UnmanagedType.LPWStr)] string path, [MarshalAs(UnmanagedType.LPWStr)] string request, [MarshalAs(UnmanagedType.LPWStr)] out string response); +'@ + $ret = Add-Type -MemberDefinition $signature -Namespace VmCompute.PrivatePInvoke -Name "NativeMethods" -PassThru + } + return $ret +} + +function Invoke-HNSRequest +{ + param + ( + [ValidateSet('GET', 'POST', 'DELETE')] + [parameter(Mandatory = $true)] [string] $Method, + [ValidateSet('networks', 'endpoints', 'activities', 'policylists', 'endpointstats', 'plugins')] + [parameter(Mandatory = $true)] [string] $Type, + [parameter(Mandatory = $false)] [string] $Action, + [parameter(Mandatory = $false)] [string] $Data = "", + [parameter(Mandatory = $false)] [Guid] $Id = [Guid]::Empty + ) + + $hnsPath = "/$Type" + if ($id -ne [Guid]::Empty) { + $hnsPath += "/$id" + } + if ($Action) { + $hnsPath += "/$Action" + } + + $response = "" + $hnsApi = Get-VmComputeNativeMethods + $hnsApi::HNSCall($Method, $hnsPath, "$Data", [ref]$response) + + $output = @() + if ($response) { + try { + $output = ($response | ConvertFrom-Json) + if ($output.Error) { + Log-Error $output; + } else { + $output = $output.Output; + } + } catch { + Log-Error $_.Exception.Message + } + } + + return $output; +} + +function Transfer-File +{ + param ( + [parameter(Mandatory = $true)] [string]$Src, + [parameter(Mandatory = $true)] [string]$Dst + ) + + if (Test-Path -PathType leaf -Path $Dst) { + $dstHasher = Get-FileHash -Path $Dst + $srcHasher = Get-FileHash -Path $Src + if ($dstHasher.Hash -eq $srcHasher.Hash) { + return + } + } + + try { + $null = Copy-Item -Force -Path $Src -Destination $Dst + } catch { + Log-Fatal "Could not transfer file $Src to $Dst : $($_.Exception.Message)" + } +} + +Export-ModuleMember -Function Log-Info +Export-ModuleMember -Function Log-Warn +Export-ModuleMember -Function Log-Error +Export-ModuleMember -Function Log-Fatal +Export-ModuleMember -Function Is-Administrator +Export-ModuleMember -Function ConvertTo-JsonObj +Export-ModuleMember -Function Set-Env +Export-ModuleMember -Function Get-Env +Export-ModuleMember -Function Get-VmComputeNativeMethods +Export-ModuleMember -Function Invoke-HNSRequest +Export-ModuleMember -Function Transfer-File diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap.go new file mode 100644 index 0000000..1169c6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap.go @@ -0,0 +1,433 @@ +package adunmigration + +import ( + "bytes" + "crypto/x509" + "fmt" + "os" + "regexp" + "strings" + "time" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +// Rancher 2.7.5 serialized binary GUIDs from LDAP using this pattern, so this +// is what we should match. Notably this differs from Active Directory GUID +// strings, which have dashes and braces as delimiters. +var validRancherGUIDPattern = regexp.MustCompile("^[0-9a-f]+$") + +type LdapErrorNotFound struct{} + +// Error provides a string representation of an LdapErrorNotFound +func (e LdapErrorNotFound) Error() string { + return "ldap query returned no results" +} + +// LdapFoundDuplicateGUID indicates either a configuration error or +// a corruption on the Active Directory side. In theory it should never +// be possible when talking to a real Active Directory server, but just +// in case we detect and handle it anyway. +type LdapFoundDuplicateGUID struct{} + +// Error provides a string representation of an LdapErrorNotFound +func (e LdapFoundDuplicateGUID) Error() string { + return "ldap query returned multiple users for the same GUID" +} + +type LdapConnectionPermanentlyFailed struct{} + +// Error provides a string representation of an LdapConnectionPermanentlyFailed +func (e LdapConnectionPermanentlyFailed) Error() string { + return "ldap search failed to connect after exhausting maximum retry attempts" +} + +type sharedLdapConnection struct { + lConn *ldapv3.Conn + isOpen bool + adConfig *v3.ActiveDirectoryConfig +} + +type retryableLdapConnection interface { + findLdapUserWithRetries(guid string) (string, *v3.Principal, error) +} + +func (sLConn sharedLdapConnection) findLdapUserWithRetries(guid string) (string, *v3.Principal, error) { + // These settings range from 2 seconds for minor blips to around a full minute for repeated failures + backoff := wait.Backoff{ + Duration: 2 * time.Second, + Factor: 1.5, // duration multiplied by this for each retry + Jitter: 0.1, // random variance, just in case other parts of rancher are using LDAP while we work + Steps: 10, // number of retries before we consider this failure to be permanent + } + + var distinguishedName string + var principal *v3.Principal + err := wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + if !sLConn.isOpen { + sLConn.lConn, err = ldapConnection(sLConn.adConfig) + if err != nil { + logrus.Warnf("[%v] LDAP connection failed: '%v', retrying...", migrateAdUserOperation, err) + return false, err + } + sLConn.isOpen = true + } + + distinguishedName, principal, err = findLdapUser(guid, sLConn.lConn, sLConn.adConfig) + if err == nil || errors.Is(err, LdapErrorNotFound{}) || errors.Is(err, LdapFoundDuplicateGUID{}) { + return true, err + } + + // any other error type almost certainly indicates a connection failure. Close and re-open the connection + // before retrying + logrus.Warnf("[%v] LDAP connection failed: '%v', retrying...", migrateAdUserOperation, err) + sLConn.lConn.Close() + sLConn.isOpen = false + + return false, err + }) + + return distinguishedName, principal, err +} + +func ldapConnection(config *v3.ActiveDirectoryConfig) (*ldapv3.Conn, error) { + caPool, err := newCAPool(config.Certificate) + if err != nil { + return nil, fmt.Errorf("unable to create caPool: %v", err) + } + + servers := config.Servers + TLS := config.TLS + port := config.Port + connectionTimeout := config.ConnectionTimeout + startTLS := config.StartTLS + + ldapConn, err := ldap.NewLDAPConn(servers, TLS, startTLS, port, connectionTimeout, caPool) + if err != nil { + return nil, err + } + + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountUsername, config.DefaultLoginDomain) + err = ldapConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + if err != nil { + return nil, err + } + return ldapConn, nil +} + +// EscapeUUID will take a UUID string in string form and will add backslashes to every 2nd character. +// The returned result is the string that needs to be added to the LDAP filter to properly filter +// by objectGUID, which is stored as binary data. +func escapeUUID(s string) string { + var buffer bytes.Buffer + var n1 = 1 + var l1 = len(s) - 1 + buffer.WriteRune('\\') + for i, r := range s { + buffer.WriteRune(r) + if i%2 == n1 && i != l1 { + buffer.WriteRune('\\') + } + } + return buffer.String() +} + +func findLdapUser(guid string, lConn *ldapv3.Conn, adConfig *v3.ActiveDirectoryConfig) (string, *v3.Principal, error) { + query := fmt.Sprintf( + "(&(%v=%v)(%v=%v))", + AttributeObjectClass, adConfig.UserObjectClass, + AttributeObjectGUID, escapeUUID(guid), + ) + + search := ldap.NewWholeSubtreeSearchRequest( + adConfig.UserSearchBase, + query, + adConfig.GetUserSearchAttributes("memberOf", "objectClass"), + ) + + result, err := lConn.Search(search) + if err != nil { + return "", nil, err + } + + if len(result.Entries) < 1 { + return "", nil, LdapErrorNotFound{} + } else if len(result.Entries) > 1 { + return "", nil, LdapFoundDuplicateGUID{} + } + + entry := result.Entries[0] + distinguishedName := entry.DN + principal, err := ldap.AttributesToPrincipal(entry.Attributes, distinguishedName, activeDirectoryScope, activeDirecotryName, + adConfig.UserObjectClass, adConfig.UserNameAttribute, adConfig.UserLoginAttribute, adConfig.GroupObjectClass, adConfig.GroupNameAttribute) + if err != nil { + return "", nil, fmt.Errorf("failed to generate principal from ldap attributes") + } + + return entry.DN, principal, nil +} + +func adConfiguration(sc *config.ScaledContext) (*v3.ActiveDirectoryConfig, error) { + authConfigs := sc.Management.AuthConfigs("") + secrets := sc.Core.Secrets("") + + authConfigObj, err := authConfigs.ObjectClient().UnstructuredClient().Get("activedirectory", metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[%v] failed to obtain activedirectory authConfigObj: %v", migrateAdUserOperation, err) + return nil, err + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + logrus.Errorf("[%v] failed to retrieve ActiveDirectoryConfig, cannot read k8s Unstructured data %v", migrateAdUserOperation, err) + return nil, err + } + storedADConfigMap := u.UnstructuredContent() + + storedADConfig := &v3.ActiveDirectoryConfig{} + err = common.Decode(storedADConfigMap, storedADConfig) + if err != nil { + logrus.Errorf("[%v] errors while decoding stored AD config: %v", migrateAdUserOperation, err) + return nil, err + } + + metadataMap, ok := storedADConfigMap["metadata"].(map[string]interface{}) + if !ok { + logrus.Errorf("[%v] failed to retrieve ActiveDirectoryConfig, (second step), cannot read k8s Unstructured data %v", migrateAdUserOperation, err) + return nil, err + } + + typemeta := &metav1.ObjectMeta{} + err = common.Decode(metadataMap, typemeta) + if err != nil { + logrus.Errorf("[%v] errors while decoding typemeta: %v", migrateAdUserOperation, err) + return nil, err + } + + storedADConfig.ObjectMeta = *typemeta + + if storedADConfig.ServiceAccountPassword != "" { + value, err := common.ReadFromSecret(secrets, storedADConfig.ServiceAccountPassword, + strings.ToLower(v3client.ActiveDirectoryConfigFieldServiceAccountPassword)) + if err != nil { + return nil, err + } + storedADConfig.ServiceAccountPassword = value + } + + return storedADConfig, nil +} + +func newCAPool(cert string) (*x509.CertPool, error) { + pool, err := x509.SystemCertPool() + if err != nil { + return nil, err + } + pool.AppendCertsFromPEM([]byte(cert)) + return pool, nil +} + +// prepareClientContexts sets up a scaled context with the ability to read users and AD configuration data +func prepareClientContexts(clientConfig *restclient.Config) (*config.ScaledContext, *v3.ActiveDirectoryConfig, error) { + var restConfig *restclient.Config + var err error + if clientConfig != nil { + restConfig = clientConfig + } else { + restConfig, err = clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG")) + if err != nil { + logrus.Errorf("[%v] failed to build the cluster config: %v", migrateAdUserOperation, err) + return nil, nil, err + } + } + + sc, err := scaledContext(restConfig) + if err != nil { + logrus.Errorf("[%v] failed to create scaled context: %v", migrateAdUserOperation, err) + return nil, nil, err + } + adConfig, err := adConfiguration(sc) + if err != nil { + logrus.Errorf("[%v] failed to acquire ad configuration: %v", migrateAdUserOperation, err) + return nil, nil, err + } + + return sc, adConfig, nil +} + +func isGUID(principalID string) bool { + parts := strings.Split(principalID, "://") + if len(parts) != 2 { + logrus.Errorf("[%v] failed to parse invalid PrincipalID: %v", identifyAdUserOperation, principalID) + return false + } + return validRancherGUIDPattern.MatchString(parts[1]) +} + +func updateADConfigMigrationStatus(status map[string]string, sc *config.ScaledContext) error { + authConfigObj, err := sc.Management.AuthConfigs("").ObjectClient().UnstructuredClient().Get("activedirectory", metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[%v] failed to obtain activedirecotry authConfigObj: %v", migrateAdUserOperation, err) + return err + } + + storedADConfig, ok := authConfigObj.(*unstructured.Unstructured) + if !ok { + return fmt.Errorf("[%v] expected unstructured authconfig, got %T", migrateAdUserOperation, authConfigObj) + } + + // Update annotations with migration status + annotations := storedADConfig.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for annotation, value := range status { + // We do not mirror the actual user lists to the AuthConfig + if annotation != migrateStatusSkipped && annotation != migrateStatusMissing { + annotations[adGUIDMigrationPrefix+annotation] = value + } + } + storedADConfig.SetAnnotations(annotations) + + // Update the AuthConfig object using the unstructured client + _, err = sc.Management.AuthConfigs("").ObjectClient().UnstructuredClient().Update(storedADConfig.GetName(), storedADConfig) + if err != nil { + return fmt.Errorf("failed to update authConfig object: %v", err) + } + + return nil +} + +func migrateAllowedUserPrincipals(workunits *[]migrateUserWorkUnit, missingUsers *[]missingUserWorkUnit, sc *config.ScaledContext, dryRun bool, deleteMissingUsers bool) error { + // this needs its own copy of the ad config, decoded with the ldap credentials fetched, so do that here + originalAdConfig, err := adConfiguration(sc) + if err != nil { + return fmt.Errorf("[%v] failed to obtain activedirectory config: %v", migrateAdUserOperation, err) + } + + authConfigObj, err := sc.Management.AuthConfigs("").ObjectClient().UnstructuredClient().Get("activedirectory", metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("[%v] failed to obtain activedirectory authConfigObj: %v", migrateAdUserOperation, err) + } + + // Create an empty unstructured object to hold the decoded JSON + storedADConfig, ok := authConfigObj.(*unstructured.Unstructured) + if !ok { + return fmt.Errorf("[%v] expected unstructured authconfig, got %T", migrateAdUserOperation, authConfigObj) + } + + unstructuredMap := storedADConfig.UnstructuredContent() + unstructuredMaybeList := unstructuredMap["allowedPrincipalIds"] + listOfMaybeStrings, ok := unstructuredMaybeList.([]interface{}) + if !ok { + return fmt.Errorf("[%v] expected list for allowed principal ids, got %T", migrateAdUserOperation, unstructuredMaybeList) + } + + adWorkUnitsByPrincipal := map[string]int{} + for i, workunit := range *workunits { + adWorkUnitsByPrincipal[activeDirectoryPrefix+workunit.guid] = i + } + missingWorkUnitsByPrincipal := map[string]int{} + for i, workunit := range *missingUsers { + adWorkUnitsByPrincipal[activeDirectoryPrefix+workunit.guid] = i + } + + // we can deduplicate this list while we're at it, so we don't accidentally end up with twice the DNs + var newPrincipalIDs []string + var knownDnIDs = map[string]string{} + + // because we might process users in this list that have never logged in, we may need to perform LDAP + // lookups on the spot to see what their associated DN should be + sharedLConn := sharedLdapConnection{adConfig: originalAdConfig} + + for _, item := range listOfMaybeStrings { + principalID, ok := item.(string) + if !ok { + // ... what? we got a non-string? + // this is weird enough that we should consider it a hard failure for investigation + return fmt.Errorf("[%v] expected string for allowed principal id, found instead %T", migrateAdUserOperation, item) + } + + scope, err := getScope(principalID) + if err != nil { + logrus.Errorf("[%v] found invalid principal ID in allowed user list, refusing to process: %v", migrateAdUserOperation, err) + newPrincipalIDs = append(newPrincipalIDs, principalID) + } + if scope != activeDirectoryScope { + newPrincipalIDs = append(newPrincipalIDs, principalID) + } else { + if !isGUID(principalID) { + // This must be a DN-based principal; add it to the new list + knownDnIDs[principalID] = principalID + } else { + if j, exists := adWorkUnitsByPrincipal[principalID]; exists { + // This user is known and was just migrated to DN, so add their DN-based principal to the list + newPrincipalID := activeDirectoryPrefix + (*workunits)[j].distinguishedName + knownDnIDs[newPrincipalID] = newPrincipalID + } else if _, exists := missingWorkUnitsByPrincipal[principalID]; exists { + // This user is known to be missing, so we don't need to perform an LDAP lookup, we can just + // action accordingly + if !deleteMissingUsers { + newPrincipalIDs = append(newPrincipalIDs, principalID) + } + } else { + // We didn't process a user object for this GUID-based user. We need to perform an ldap + // lookup on the spot and figure out if they have an associated DN + guid, err := getExternalID(principalID) + if err != nil { + // this shouldn't be reachable, as getScope will fail first, but just for consistency... + logrus.Errorf("[%v] found invalid principal ID in allowed user list, refusing to process: %v", migrateAdUserOperation, err) + newPrincipalIDs = append(newPrincipalIDs, principalID) + } else { + dn, _, err := sharedLConn.findLdapUserWithRetries(guid) + if errors.Is(err, LdapErrorNotFound{}) { + if !deleteMissingUsers { + newPrincipalIDs = append(newPrincipalIDs, principalID) + } + } else if err != nil { + // Whelp; keep this one as-is and yell about it + logrus.Errorf("[%v] ldap error when checking distinguished name for guid-based principal %v, skipping: %v", migrateAdUserOperation, principalID, err) + newPrincipalIDs = append(newPrincipalIDs, principalID) + } else { + newPrincipalID := activeDirectoryPrefix + dn + knownDnIDs[newPrincipalID] = newPrincipalID + } + } + } + } + } + } + + // Now that we're through processing the list and dealing with any duplicates, append the new DN-based principals + // to the end of the list + for _, principalID := range knownDnIDs { + newPrincipalIDs = append(newPrincipalIDs, principalID) + } + + if !dryRun { + unstructuredMap["allowedPrincipalIds"] = newPrincipalIDs + storedADConfig.SetUnstructuredContent(unstructuredMap) + + _, err = sc.Management.AuthConfigs("").ObjectClient().UnstructuredClient().Update("activedirectory", storedADConfig) + } else { + logrus.Infof("[%v] DRY RUN: new allowed user list will contain these principal IDs:", migrateAdUserOperation) + for _, principalID := range newPrincipalIDs { + logrus.Infof("[%v] DRY RUN: '%v'", migrateAdUserOperation, principalID) + } + } + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap_test.go new file mode 100644 index 0000000..408bf90 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/ldap_test.go @@ -0,0 +1,80 @@ +package adunmigration + +import ( + "testing" + + "github.com/sirupsen/logrus" + logrusTest "github.com/sirupsen/logrus/hooks/test" + "github.com/stretchr/testify/assert" +) + +func TestEscapeUUID(t *testing.T) { + t.Parallel() + // Note: Because Rancher wrote these strings, the input format we care about is somewhat + // constrained, and we're not spending too much effort dealing with edge cases. + guidString := "953d82a03d47a5498330293e386dfce1" + wantEscapedString := "\\95\\3d\\82\\a0\\3d\\47\\a5\\49\\83\\30\\29\\3e\\38\\6d\\fc\\e1" + result := escapeUUID(guidString) + assert.Equal(t, wantEscapedString, result) +} + +func TestIsGUID(t *testing.T) { + // Note: because logrus state is global, we cannot use t.Parallel here + hook := logrusTest.NewGlobal() + + tests := []struct { + name string + principalId string + wantResult bool + wantLoggedError bool + }{ + { + name: "Local User", + principalId: "local://u-fydcaomakf", + wantResult: false, + wantLoggedError: false, + }, + { + name: "AD user, DN based", + principalId: "activedirectory_user://CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space", + wantResult: false, + wantLoggedError: false, + }, + { + name: "AD user, GUID based", + principalId: "activedirectory_user://953d82a03d47a5498330293e386dfce1", + wantResult: true, + wantLoggedError: false, + }, + { + name: "Invalid principal", + principalId: "fail-on-purpose", + wantResult: false, + wantLoggedError: true, + }, + { + name: "Empty String", + principalId: "", + wantResult: false, + wantLoggedError: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + result := isGUID(test.principalId) + if result != test.wantResult { + t.Errorf("expected isGUID to be %v, but got %v", test.wantResult, result) + } + // This particular function treats invalid principal IDs as a soft error: an invalid ID is by + // definition not a valid GUID. We generate a log if this happens, so let's make sure we got + // that log: + if test.wantLoggedError { + assert.GreaterOrEqual(t, len(hook.Entries), 1) + assert.Equal(t, hook.LastEntry().Level, logrus.ErrorLevel) + } + hook.Reset() + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate.go new file mode 100644 index 0000000..69d753c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate.go @@ -0,0 +1,522 @@ +/* +Look for any active directory users with a GUID type principal. +Convert these users to a distinguished name instead. +*/ + +package adunmigration + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + restclient "k8s.io/client-go/rest" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/activedirectory" + "github.com/rancher/rancher/pkg/types/config" +) + +const ( + migrateAdUserOperation = "migrate-ad-user" + identifyAdUserOperation = "identify-ad-users" + migrateTokensOperation = "migrate-ad-tokens" + migrateCrtbsOperation = "migrate-ad-crtbs" + migratePrtbsOperation = "migrate-ad-prtbs" + migrateGrbsOperation = "migrate-ad-grbs" + activeDirecotryName = "activedirectory" + activeDirectoryScope = "activedirectory_user" + activeDirectoryPrefix = "activedirectory_user://" + localPrefix = "local://" + adGUIDMigrationLabel = "ad-guid-migration" + adGUIDMigrationAnnotation = "ad-guid-migration-data" + adGUIDMigrationPrefix = "migration-" + migratedLabelValue = "migrated" + migrationPreviousName = "ad-guid-previous-name" + AttributeObjectClass = "objectClass" + AttributeObjectGUID = "objectGUID" + migrateStatusSkipped = "skippedUsers" + migrateStatusMissing = "missingUsers" + migrateStatusCountSuffix = "Count" + migrationStatusPercentage = "percentDone" + migrationStatusLastUpdate = "statusLastUpdated" +) + +type migrateUserWorkUnit struct { + distinguishedName string + guid string + originalUser *v3.User + duplicateUsers []*v3.User + principal *v3.Principal + + activeDirectoryCRTBs []v3.ClusterRoleTemplateBinding + duplicateLocalCRTBs []v3.ClusterRoleTemplateBinding + + activeDirectoryPRTBs []v3.ProjectRoleTemplateBinding + duplicateLocalPRTBs []v3.ProjectRoleTemplateBinding + + duplicateLocalGRBs []v3.GlobalRoleBinding + + activeDirectoryTokens []v3.Token + duplicateLocalTokens []v3.Token +} + +type missingUserWorkUnit struct { + guid string + originalUser *v3.User + duplicateUsers []*v3.User +} + +type skippedUserWorkUnit struct { + guid string + originalUser *v3.User +} + +func scaledContext(restConfig *restclient.Config) (*config.ScaledContext, error) { + sc, err := config.NewScaledContext(*restConfig, nil) + if err != nil { + logrus.Errorf("[%v] failed to create scaledContext: %v", migrateAdUserOperation, err) + return nil, err + } + + ctx := context.Background() + err = sc.Start(ctx) + if err != nil { + logrus.Errorf("[%v] failed to start scaled context: %v", migrateAdUserOperation, err) + return nil, err + } + + return sc, nil +} + +// UnmigrateAdGUIDUsersOnce will ensure that the migration script will run only once. cycle through all users, ctrb, ptrb, tokens and migrate them to an +// appropriate DN-based PrincipalID. +func UnmigrateAdGUIDUsersOnce(sc *config.ScaledContext) error { + migrationConfigMap, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).GetNamespaced(activedirectory.StatusConfigMapNamespace, activedirectory.StatusConfigMapName, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Errorf("[%v] unable to check unmigration configmap: %v", migrateAdUserOperation, err) + logrus.Errorf("[%v] cannot determine if it is safe to proceed. refusing to run", migrateAdUserOperation) + return nil + } + if migrationConfigMap != nil { + migrationStatus := migrationConfigMap.Data[activedirectory.StatusMigrationField] + switch migrationStatus { + case activedirectory.StatusMigrationFinished: + logrus.Debugf("[%v] ad-guid migration has already been completed, refusing to run again at startup", migrateAdUserOperation) + return nil + case activedirectory.StatusMigrationFinishedWithMissing: + logrus.Infof("[%v] ad-guid migration has already been completed. To clean-up missing users, you can run the utility manually", migrateAdUserOperation) + return nil + case activedirectory.StatusMigrationFinishedWithSkipped: + logrus.Infof("[%v] ad-guid migration has already been completed. To try and resolve skipped users, you can run the utility manually", migrateAdUserOperation) + return nil + } + + } + return UnmigrateAdGUIDUsers(&sc.RESTConfig, false, false) +} + +// UnmigrateAdGUIDUsers will cycle through all users, ctrb, ptrb, tokens and migrate them to an +// appropriate DN-based PrincipalID. +func UnmigrateAdGUIDUsers(clientConfig *restclient.Config, dryRun bool, deleteMissingUsers bool) error { + if dryRun { + logrus.Infof("[%v] dryRun is true, no objects will be deleted/modified", migrateAdUserOperation) + deleteMissingUsers = false + } else if deleteMissingUsers { + logrus.Infof("[%v] deleteMissingUsers is true, GUID-based users not present in Active Directory will be deleted", migrateAdUserOperation) + } + + sc, adConfig, err := prepareClientContexts(clientConfig) + if err != nil { + return err + } + + migrationConfigMap, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).GetNamespaced(activedirectory.StatusConfigMapNamespace, activedirectory.StatusConfigMapName, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Errorf("[%v] unable to check unmigration configmap: %v", migrateAdUserOperation, err) + logrus.Errorf("[%v] cannot determine if it is safe to proceed. refusing to run", migrateAdUserOperation) + return nil + } + if migrationConfigMap != nil { + migrationStatus := migrationConfigMap.Data[activedirectory.StatusMigrationField] + switch migrationStatus { + case activedirectory.StatusMigrationRunning: + logrus.Infof("[%v] ad-guid migration is currently running, refusing to run again concurrently", migrateAdUserOperation) + return nil + } + } + + finalStatus := activedirectory.StatusMigrationFinished + + // set the status to running and reset the unmigrated fields + if !dryRun { + err = updateMigrationStatus(sc, activedirectory.StatusMigrationField, activedirectory.StatusMigrationRunning) + if err != nil { + logrus.Errorf("[%v] unable to update migration status configmap: %v", migrateAdUserOperation, err) + return err + } + updateUnmigratedUsers("", migrateStatusSkipped, true, sc) + updateUnmigratedUsers("", migrateStatusMissing, true, sc) + // If we return past this point, no matter how we got there, make sure we update the configmap to clear the + // status away from "running." If we fail to do this, we block AD-based logins indefinitely. + defer func(sc *config.ScaledContext, status string) { + err := updateMigrationStatus(sc, status, finalStatus) + if err != nil { + logrus.Errorf("[%v] unable to update migration status configmap: %v", migrateAdUserOperation, err) + } + }(sc, activedirectory.StatusMigrationField) + + // Early bail: if the AD configuration is disabled, then we're done! Update the configmap right now and exit. + if !adConfig.Enabled { + logrus.Infof("[%v] during unmigration, found that Active Directory is not enabled. nothing to do", migrateAdUserOperation) + finalStatus = activedirectory.StatusMigrationFinished + return nil + } + } + + logrus.Infof("[%v] beginning ad-guid unmigration", migrateAdUserOperation) + + users, err := sc.Management.Users("").List(metav1.ListOptions{}) + if err != nil { + logrus.Errorf("[%v] unable to fetch user list: %v", migrateAdUserOperation, err) + return err + } + + lConn := sharedLdapConnection{adConfig: adConfig} + usersToMigrate, missingUsers, skippedUsers := identifyMigrationWorkUnits(users, lConn) + // If any of the below functions fail, there is either a permissions problem or a more serious issue with the + // Rancher API. We should bail in this case and not attempt to process users. + + tokenInterface := sc.Management.Tokens("") + tokenList, err := tokenInterface.List(metav1.ListOptions{}) + if err != nil { + finalStatus = activedirectory.StatusMigrationFailed + logrus.Errorf("[%v] unable to fetch token objects: %v", migrateAdUserOperation, err) + return err + } + identifyTokens(&usersToMigrate, tokenList) + + crtbInterface := sc.Management.ClusterRoleTemplateBindings("") + crtbList, err := crtbInterface.List(metav1.ListOptions{}) + if err != nil { + finalStatus = activedirectory.StatusMigrationFailed + logrus.Errorf("[%v] unable to fetch CRTB objects: %v", migrateAdUserOperation, err) + return err + } + identifyCRTBs(&usersToMigrate, crtbList) + + prtbInterface := sc.Management.ProjectRoleTemplateBindings("") + prtbList, err := prtbInterface.List(metav1.ListOptions{}) + if err != nil { + finalStatus = activedirectory.StatusMigrationFailed + logrus.Errorf("[%v] unable to fetch PRTB objects: %v", migrateAdUserOperation, err) + return err + } + identifyPRTBs(&usersToMigrate, prtbList) + + grbInterface := sc.Management.GlobalRoleBindings("") + grbList, err := grbInterface.List(metav1.ListOptions{}) + if err != nil { + finalStatus = activedirectory.StatusMigrationFailed + logrus.Errorf("[%v] unable to fetch GRB objects: %v", migrateAdUserOperation, err) + return err + } + identifyGRBs(&usersToMigrate, grbList) + + if len(missingUsers) > 0 { + finalStatus = activedirectory.StatusMigrationFinishedWithMissing + } + if len(skippedUsers) > 0 { + finalStatus = activedirectory.StatusMigrationFinishedWithSkipped + } + + for _, user := range skippedUsers { + logrus.Errorf("[%v] unable to migrate user '%v' due to a connection failure; this user will be skipped", + migrateAdUserOperation, user.originalUser.Name) + if !dryRun { + updateUnmigratedUsers(user.originalUser.Name, migrateStatusSkipped, false, sc) + } + } + for _, missingUser := range missingUsers { + if deleteMissingUsers && !dryRun { + logrus.Infof("[%v] user '%v' with GUID '%v' does not seem to exist in Active Directory. deleteMissingUsers is true, proceeding to delete this user permanently", migrateAdUserOperation, missingUser.originalUser.Name, missingUser.guid) + updateUnmigratedUsers(missingUser.originalUser.Name, migrateStatusMissing, false, sc) + err = sc.Management.Users("").Delete(missingUser.originalUser.Name, &metav1.DeleteOptions{}) + if err != nil { + logrus.Errorf("[%v] failed to delete missing user '%v' with: %v", migrateAdUserOperation, missingUser.originalUser.Name, err) + } + } else { + logrus.Infof("[%v] User '%v' with GUID '%v' does not seem to exist in Active Directory. this user will be skipped", migrateAdUserOperation, missingUser.originalUser.Name, missingUser.guid) + if !dryRun { + updateUnmigratedUsers(missingUser.originalUser.Name, migrateStatusMissing, false, sc) + } + } + } + + for i, userToMigrate := range usersToMigrate { + // Note: some resources may fail to migrate due to webhook constraints; this applies especially to bindings + // that refer to disabled templates, as rancher won't allow us to create the replacements. We'll log these + // errors, but do not consider them to be serious enough to stop processing the remainder of each user's work. + migrateCRTBs(&userToMigrate, sc, dryRun) + migratePRTBs(&userToMigrate, sc, dryRun) + migrateGRBs(&userToMigrate, sc, dryRun) + migrateTokens(&userToMigrate, sc, dryRun) + replaceGUIDPrincipalWithDn(userToMigrate.originalUser, userToMigrate.distinguishedName, userToMigrate.guid, dryRun) + + if dryRun { + describePlannedChanges(userToMigrate) + } else { + err = deleteDuplicateUsers(userToMigrate, sc) + if err == nil { + updateModifiedUser(userToMigrate, sc) + } + percentDone := float64(i+1) / float64(len(usersToMigrate)) * 100 + progress := fmt.Sprintf("%.0f%%", percentDone) + err = updateMigrationStatus(sc, migrationStatusPercentage, progress) + if err != nil { + logrus.Errorf("[%v] unable to update migration status: %v", migrateAdUserOperation, err) + } + } + } + + err = migrateAllowedUserPrincipals(&usersToMigrate, &missingUsers, sc, dryRun, deleteMissingUsers) + if err != nil { + logrus.Errorf("[%v] unable to migrate allowed users: %v", migrateAdUserOperation, err) + finalStatus = activedirectory.StatusMigrationFailed + return err + } + + if dryRun { + logrus.Infof("[%v] end of ad-guid unmigration", migrateAdUserOperation) + } else { + logrus.Infof("[%v] end of ad-guid unmigration, results saved to configmap '%v'", migrateAdUserOperation, activedirectory.StatusConfigMapName) + } + + return nil +} + +// identifyMigrationWorkUnits locates ActiveDirectory users with GUID and DN based principal IDs and sorts them +// into work units based on whether those users can be located in the upstream Active Directory provider. Specifically: +// +// usersToMigrate contains GUID-based original users and any duplicates (GUID or DN based) that we wish to merge +// missingUsers contains GUID-based users who could not be found in Active Directory +// skippedUsers contains GUID-based users that could not be processed, usually due to an LDAP connection failure +func identifyMigrationWorkUnits(users *v3.UserList, lConn retryableLdapConnection) ( + []migrateUserWorkUnit, []missingUserWorkUnit, []skippedUserWorkUnit) { + // Note: we *could* make the ldap connection on the spot here, but we're accepting it as a parameter specifically + // so that this function is easier to test. This setup allows us to mock the ldap connection and thus more easily + // test unusual Active Directory responses to our searches. + + var usersToMigrate []migrateUserWorkUnit + var missingUsers []missingUserWorkUnit + var skippedUsers []skippedUserWorkUnit + + // These assist with quickly identifying duplicates, so we don't have to scan the whole structure each time. + // We key on guid/dn, and the value is the index of that work unit in the associated table + knownGUIDWorkUnits := map[string]int{} + knownGUIDMissingUnits := map[string]int{} + knownDnWorkUnits := map[string]int{} + + // Now we'll make two passes over the list of all users. First we need to identify any GUID based users, and + // sort them into "found" and "not found" lists. At this stage we might have GUID-based duplicates, and we'll + // detect and sort those accordingly + ldapPermanentlyFailed := false + logrus.Debugf("[%v] locating GUID-based Active Directory users", identifyAdUserOperation) + for _, user := range users.Items { + if !isAdUser(&user) { + logrus.Debugf("[%v] user '%v' has no AD principals, skipping", identifyAdUserOperation, user.Name) + continue + } + principalID := adPrincipalID(&user) + logrus.Debugf("[%v] processing AD User '%v' with principal ID: '%v'", identifyAdUserOperation, user.Name, principalID) + if !isGUID(principalID) { + logrus.Debugf("[%v] '%v' does not appear to be a GUID-based principal ID, taking no action", identifyAdUserOperation, principalID) + continue + } + guid, err := getExternalID(principalID) + + if err != nil { + // This really shouldn't be possible to hit, since isGuid will fail to parse anything that would + // cause getExternalID to choke on the input, but for maximum safety we'll handle it anyway. + logrus.Errorf("[%v] failed to extract GUID from principal '%v', cannot process user: '%v'", identifyAdUserOperation, err, user.Name) + continue + } + // If our LDAP connection has gone sour, we still need to log this user for reporting + userCopy := user.DeepCopy() + if ldapPermanentlyFailed { + skippedUsers = append(skippedUsers, skippedUserWorkUnit{guid: guid, originalUser: userCopy}) + } else { + // Check for guid-based duplicates here. If we find one, we don't need to perform an other LDAP lookup. + if i, exists := knownGUIDWorkUnits[guid]; exists { + logrus.Debugf("[%v] user %v is GUID-based (%v) and a duplicate of %v", + identifyAdUserOperation, user.Name, guid, usersToMigrate[i].originalUser.Name) + // Make sure the oldest duplicate user is selected as the original + if usersToMigrate[i].originalUser.CreationTimestamp.Time.After(user.CreationTimestamp.Time) { + usersToMigrate[i].duplicateUsers = append(usersToMigrate[i].duplicateUsers, usersToMigrate[i].originalUser) + usersToMigrate[i].originalUser = userCopy + } else { + usersToMigrate[i].duplicateUsers = append(usersToMigrate[i].duplicateUsers, userCopy) + } + continue + } + if i, exists := knownGUIDMissingUnits[guid]; exists { + logrus.Debugf("[%v] user %v is GUID-based (%v) and a duplicate of %v which is known to be missing", + identifyAdUserOperation, user.Name, guid, missingUsers[i].originalUser.Name) + // We're less picky about the age of the oldest user here, because we aren't going to deduplicate these + missingUsers[i].duplicateUsers = append(missingUsers[i].duplicateUsers, userCopy) + continue + } + dn, principal, err := lConn.findLdapUserWithRetries(guid) + if errors.Is(err, LdapFoundDuplicateGUID{}) { + logrus.Errorf("[%v] LDAP returned multiple users with GUID '%v'. this should not be possible, and may indicate a configuration error! this user will be skipped", identifyAdUserOperation, guid) + skippedUsers = append(skippedUsers, skippedUserWorkUnit{guid: guid, originalUser: userCopy}) + } else if errors.Is(err, LdapErrorNotFound{}) { + logrus.Debugf("[%v] user %v is GUID-based (%v) and the Active Directory server doesn't know about it. marking it as missing", identifyAdUserOperation, user.Name, guid) + knownGUIDMissingUnits[guid] = len(missingUsers) + missingUsers = append(missingUsers, missingUserWorkUnit{guid: guid, originalUser: userCopy}) + } else if err != nil { + logrus.Warnf("[%v] LDAP connection has permanently failed! will continue to migrate previously identified users", identifyAdUserOperation) + skippedUsers = append(skippedUsers, skippedUserWorkUnit{guid: guid, originalUser: userCopy}) + ldapPermanentlyFailed = true + } else { + logrus.Debugf("[%v] user %v is GUID-based (%v) and the Active Directory server knows it by the Distinguished Name '%v'", identifyAdUserOperation, user.Name, guid, dn) + knownGUIDWorkUnits[guid] = len(usersToMigrate) + knownDnWorkUnits[dn] = len(usersToMigrate) + var emptyDuplicateList []*v3.User + usersToMigrate = append(usersToMigrate, migrateUserWorkUnit{guid: guid, distinguishedName: dn, principal: principal, originalUser: userCopy, duplicateUsers: emptyDuplicateList}) + } + } + } + + if len(usersToMigrate) == 0 { + logrus.Debugf("[%v] found 0 users in need of migration, exiting without checking for DN-based duplicates", identifyAdUserOperation) + return usersToMigrate, missingUsers, skippedUsers + } + + // Now for the second pass, we need to identify DN-based users, and see if they are duplicates of any of the GUID + // users that we found in the first pass. We'll prefer the oldest user as the originalUser object, this will be + // the one we keep when we resolve duplicates later. + logrus.Debugf("[%v] locating any DN-based Active Directory users", identifyAdUserOperation) + for _, user := range users.Items { + if !isAdUser(&user) { + logrus.Debugf("[%v] user '%v' has no AD principals, skipping", identifyAdUserOperation, user.Name) + continue + } + principalID := adPrincipalID(&user) + logrus.Debugf("[%v] processing AD User '%v' with principal ID: '%v'", identifyAdUserOperation, user.Name, principalID) + if isGUID(principalID) { + logrus.Debugf("[%v] '%v' does not appear to be a DN-based principal ID, taking no action", identifyAdUserOperation, principalID) + continue + } + dn, err := getExternalID(principalID) + if err != nil { + logrus.Errorf("[%v] failed to extract DN from principal '%v', cannot process user: '%v'", identifyAdUserOperation, err, user.Name) + continue + } + if i, exists := knownDnWorkUnits[dn]; exists { + logrus.Debugf("[%v] user %v is DN-based (%v), and a duplicate of %v", + identifyAdUserOperation, user.Name, dn, usersToMigrate[i].originalUser.Name) + // Make sure the oldest duplicate user is selected as the original + userCopy := user.DeepCopy() + if usersToMigrate[i].originalUser.CreationTimestamp.Time.After(user.CreationTimestamp.Time) { + usersToMigrate[i].duplicateUsers = append(usersToMigrate[i].duplicateUsers, usersToMigrate[i].originalUser) + usersToMigrate[i].originalUser = userCopy + } else { + usersToMigrate[i].duplicateUsers = append(usersToMigrate[i].duplicateUsers, userCopy) + } + } + } + + return usersToMigrate, missingUsers, skippedUsers +} + +func workUnitContainsName(workunit *migrateUserWorkUnit, name string) bool { + if workunit.originalUser.Name == name { + return true + } + for _, duplicateLocalUser := range workunit.duplicateUsers { + if duplicateLocalUser.Name == name { + return true + } + } + return false +} + +func updateMigrationStatus(sc *config.ScaledContext, status string, value string) error { + cm, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).Get(activedirectory.StatusConfigMapName, metav1.GetOptions{}) + if err != nil { + // Create a new ConfigMap if it doesn't exist + if !apierrors.IsNotFound(err) { + return err + } + cm = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: activedirectory.StatusConfigMapName, + Namespace: activedirectory.StatusConfigMapNamespace, + }, + } + } + if cm.Data == nil { + cm.Data = map[string]string{} + } + cm.Data[status] = value + cm.Data[migrationStatusLastUpdate] = metav1.Now().Format(time.RFC3339) + + if _, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).Update(cm); err != nil { + // If the ConfigMap does not exist, create it + if apierrors.IsNotFound(err) { + _, err = sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).Create(cm) + if err != nil { + return fmt.Errorf("[%v] unable to create migration status configmap: %v", migrateAdUserOperation, err) + } + } + } + err = updateADConfigMigrationStatus(cm.Data, sc) + if err != nil { + return fmt.Errorf("unable to update AuthConfig status: %v", err) + } + return nil +} + +// updateUnmigratedUsers will add a user to the list for the specified migration status in the migration status configmap. +// If reset is set to true, it will empty the list. +func updateUnmigratedUsers(user string, status string, reset bool, sc *config.ScaledContext) { + cm, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).Get(activedirectory.StatusConfigMapName, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[%v] unable to fetch configmap to update %v users: %v", migrateAdUserOperation, status, err) + } + var currentList string + if reset { + delete(cm.Data, status) + delete(cm.Data, status+migrateStatusCountSuffix) + } else { + currentList = cm.Data[status] + if currentList == "" { + currentList = currentList + user + } else { + currentList = currentList + "," + user + } + count := strconv.Itoa(len(strings.Split(currentList, ","))) + cm.Data[status+migrateStatusCountSuffix] = count + cm.Data[status] = currentList + } + + cm.Data[migrationStatusLastUpdate] = metav1.Now().Format(time.RFC3339) + if _, err := sc.Core.ConfigMaps(activedirectory.StatusConfigMapNamespace).Update(cm); err != nil { + if err != nil { + logrus.Errorf("[%v] unable to update migration status configmap: %v", migrateAdUserOperation, err) + } + } + err = updateADConfigMigrationStatus(cm.Data, sc) + if err != nil { + logrus.Errorf("[%v] unable to update AuthConfig status: %v", migrateAdUserOperation, err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate_test.go new file mode 100644 index 0000000..cdb12b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/migrate_test.go @@ -0,0 +1,379 @@ +package adunmigration + +import ( + "testing" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestWorkUnitContainsName(t *testing.T) { + t.Parallel() + + originalUserName := "u-fydcaomakf" + duplicateUserName := "u-quuknbiweg" + + workunit := migrateUserWorkUnit{ + originalUser: &v3.User{ObjectMeta: metav1.ObjectMeta{Name: originalUserName}}, + duplicateUsers: []*v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: duplicateUserName}}, + }, + } + + tests := []struct { + name string + query string + wantResult bool + }{ + { + name: "No match returns false", + query: "u-nonexistent", + wantResult: false, + }, + { + name: "Original user match returns true", + query: originalUserName, + wantResult: true, + }, + { + name: "Duplicate user match returns true", + query: duplicateUserName, + wantResult: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result := workUnitContainsName(&workunit, test.query) + assert.Equal(t, test.wantResult, result) + }) + } +} + +type mockLdapAlwaysSucceed struct { +} + +func (sLConn mockLdapAlwaysSucceed) findLdapUserWithRetries(guid string) (string, *v3.Principal, error) { + return testDn, &v3.Principal{}, nil +} + +func TestWorkUnitIdentification(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + users []v3.User + wantUsersToMigrate int + wantDuplicateUsers int + }{ + { + name: "Guid-based user, which exists in AD, is identified", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}}, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 0, + }, + { + name: "Guid-based duplicate users are recognized", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}}, + {ObjectMeta: metav1.ObjectMeta{Name: testDuplicateGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testDuplicateGuidLocalPrincipal}}, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + }, + { + name: "Dn-based duplicate users are recognized", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}}, + {ObjectMeta: metav1.ObjectMeta{Name: testDnLocalName}, PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}}, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + }, + { + name: "Dn-based users without GUID-based duplicates are ignored", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testDnLocalName}, PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}}, + }, + wantUsersToMigrate: 0, + wantDuplicateUsers: 0, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ldapConnection := mockLdapAlwaysSucceed{} + userList := v3.UserList{Items: test.users} + usersToMigrate, missingUsers, skippedUsers := identifyMigrationWorkUnits(&userList, ldapConnection) + assert.Equal(t, test.wantUsersToMigrate, len(usersToMigrate), "unexpected count for users to migrate") + assert.Equal(t, 0, len(missingUsers), "unexpected count for missing users") + assert.Equal(t, 0, len(skippedUsers), "unexpected count for skipped users") + if len(usersToMigrate) > 0 { + assert.Equal(t, test.wantDuplicateUsers, len(usersToMigrate[0].duplicateUsers), "unexpected duplicate users for first workunit") + } + }) + } +} + +func TestWorkUnitDuplicateAgeResolution(t *testing.T) { + t.Parallel() + + olderTime, err := time.Parse("2006-Jan-02", "2000-Jan-01") + assert.NoError(t, err, "time itself cannot be trusted, all hope is lost") + newerTime, err := time.Parse("2006-Jan-02", "2001-Jan-01") + assert.NoError(t, err, "time itself cannot be trusted, all hope is lost") + + tests := []struct { + name string + users []v3.User + wantUsersToMigrate int + wantDuplicateUsers int + wantOriginalName string + wantDuplicateName string + }{ + { + name: "Guid-based duplicate selects oldest user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDuplicateGuidLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testDuplicateGuidLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testGuidLocalName, + wantDuplicateName: testDuplicateGuidLocalName, + }, + { + name: "Guid-based duplicate, order reversed, still selects oldest user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDuplicateGuidLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testDuplicateGuidLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testGuidLocalName, + wantDuplicateName: testDuplicateGuidLocalName, + }, + { + name: "Newer Dn-based duplicate of older GUID-based user selects GUID-based user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDnLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testGuidLocalName, + wantDuplicateName: testDnLocalName, + }, + { + name: "Newer Dn-based duplicate of older GUID-based user, order reversed, still selects GUID-based user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDnLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testGuidLocalName, + wantDuplicateName: testDnLocalName, + }, + { + name: "Newer GUID-based duplicate of older Dn-based user selects Dn-based user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDnLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testDnLocalName, + wantDuplicateName: testGuidLocalName, + }, + { + name: "Newer GUID-based duplicate of older Dn-based user, order reversed, still selects Dn-based user as original", + users: []v3.User{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: testGuidLocalName, + CreationTimestamp: metav1.Time{Time: newerTime}, + }, + PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: testDnLocalName, + CreationTimestamp: metav1.Time{Time: olderTime}, + }, + PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}, + }, + }, + wantUsersToMigrate: 1, + wantDuplicateUsers: 1, + wantOriginalName: testDnLocalName, + wantDuplicateName: testGuidLocalName, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ldapConnection := mockLdapAlwaysSucceed{} + userList := v3.UserList{Items: test.users} + usersToMigrate, _, _ := identifyMigrationWorkUnits(&userList, ldapConnection) + assert.Equal(t, test.wantUsersToMigrate, len(usersToMigrate), "unexpected count for users to migrate") + if len(usersToMigrate) > 0 { + assert.Equal(t, test.wantDuplicateUsers, len(usersToMigrate[0].duplicateUsers), "unexpected duplicate users for first workunit") + if len(usersToMigrate[0].duplicateUsers) > 0 { + assert.Equal(t, test.wantOriginalName, usersToMigrate[0].originalUser.Name, "wrong user identified as original") + assert.Equal(t, test.wantDuplicateName, usersToMigrate[0].duplicateUsers[0].Name, "wrong user identified as duplicate") + } + } + }) + } +} + +type mockLdapNeverSucceed struct { +} + +func (sLConn mockLdapNeverSucceed) findLdapUserWithRetries(guid string) (string, *v3.Principal, error) { + return "", nil, LdapErrorNotFound{} +} + +type mockLdapConnectionFailure struct { +} + +func (sLConn mockLdapConnectionFailure) findLdapUserWithRetries(guid string) (string, *v3.Principal, error) { + return "", nil, LdapConnectionPermanentlyFailed{} +} + +func TestWorkUnitConnectionFailures(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + users []v3.User + ldapConn retryableLdapConnection + wantUsersToMigrate int + wantMissingUsers int + wantSkippedUsers int + }{ + { + name: "GUID-based users not found in Active Directory are counted as missing", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}}, + }, + ldapConn: mockLdapNeverSucceed{}, + wantUsersToMigrate: 0, + wantMissingUsers: 1, + wantSkippedUsers: 0, + }, + { + name: "GUID-based users are counted as skipped during LDAP connection failures", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, PrincipalIDs: []string{testGuidPrincipal, testGuidLocalPrincipal}}, + }, + ldapConn: mockLdapConnectionFailure{}, + wantUsersToMigrate: 0, + wantMissingUsers: 0, + wantSkippedUsers: 1, + }, + { + name: "Dn-based users are not counted as missing, even if they don't exist in Active Directory", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testDnLocalName}, PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}}, + }, + ldapConn: mockLdapNeverSucceed{}, + wantUsersToMigrate: 0, + wantMissingUsers: 0, + wantSkippedUsers: 0, + }, + { + name: "Dn-based users are not counted as skipped, even during LDAP connection failures", + users: []v3.User{ + {ObjectMeta: metav1.ObjectMeta{Name: testDnLocalName}, PrincipalIDs: []string{testDnPrincipal, testDnLocalPrincipal}}, + }, + ldapConn: mockLdapConnectionFailure{}, + wantUsersToMigrate: 0, + wantMissingUsers: 0, + wantSkippedUsers: 0, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + userList := v3.UserList{Items: test.users} + usersToMigrate, missingUsers, skippedUsers := identifyMigrationWorkUnits(&userList, test.ldapConn) + assert.Equal(t, test.wantUsersToMigrate, len(usersToMigrate), "unexpected count for users to migrate") + assert.Equal(t, test.wantMissingUsers, len(missingUsers), "unexpected count for missing users") + assert.Equal(t, test.wantSkippedUsers, len(skippedUsers), "unexpected count for skipped users") + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs.go new file mode 100644 index 0000000..19bd003 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs.go @@ -0,0 +1,476 @@ +package adunmigration + +import ( + "fmt" + "time" + + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3norman "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +// principalsToMigrate collects workunits whose resources we wish to migrate into two groups: +// +// adWorkUnitsByPrincipal - resources should be migrated to an ActiveDirectory principal with a Distinguished Name +// duplicateLocalWorkUnitsByPrincipal - resources should be migrated to the local ID of the original (kept) user +func principalsToMigrate(workunits *[]migrateUserWorkUnit) (adWorkUnitsByPrincipal map[string]int, duplicateLocalWorkUnitsByPrincipal map[string]int) { + // first build a map of guid-principalid -> work unit, which will make the following logic more efficient + adWorkUnitsByPrincipal = map[string]int{} + duplicateLocalWorkUnitsByPrincipal = map[string]int{} + + for i, workunit := range *workunits { + adWorkUnitsByPrincipal[activeDirectoryPrefix+workunit.guid] = i + for j := range workunit.duplicateUsers { + duplicateLocalWorkUnitsByPrincipal[activeDirectoryPrefix+workunit.guid] = i + duplicateLocalWorkUnitsByPrincipal[activeDirectoryPrefix+workunit.distinguishedName] = i + duplicateLocalWorkUnitsByPrincipal[localPrefix+workunit.duplicateUsers[j].Name] = i + } + } + + return adWorkUnitsByPrincipal, duplicateLocalWorkUnitsByPrincipal +} + +func identifyCRTBs(workunits *[]migrateUserWorkUnit, crtbList *v3.ClusterRoleTemplateBindingList) { + adWorkUnitsByPrincipal, duplicateLocalWorkUnitsByPrincipal := principalsToMigrate(workunits) + + for _, crtb := range crtbList.Items { + if index, exists := adWorkUnitsByPrincipal[crtb.UserPrincipalName]; exists { + if workUnitContainsName(&(*workunits)[index], crtb.UserName) { + (*workunits)[index].activeDirectoryCRTBs = append((*workunits)[index].activeDirectoryCRTBs, crtb) + } else { + logrus.Warnf("[%v] found CRTB for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, crtb.UserPrincipalName, crtb.UserName) + } + } else if index, exists = duplicateLocalWorkUnitsByPrincipal[crtb.UserPrincipalName]; exists { + if workUnitContainsName(&(*workunits)[index], crtb.UserName) { + (*workunits)[index].duplicateLocalCRTBs = append((*workunits)[index].duplicateLocalCRTBs, crtb) + } else { + logrus.Warnf("[%v] found CRTB for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, crtb.UserPrincipalName, crtb.UserName) + } + } + } +} + +func identifyPRTBs(workunits *[]migrateUserWorkUnit, prtbList *v3.ProjectRoleTemplateBindingList) { + adWorkUnitsByPrincipal, duplicateLocalWorkUnitsByPrincipal := principalsToMigrate(workunits) + + for _, prtb := range prtbList.Items { + if index, exists := adWorkUnitsByPrincipal[prtb.UserPrincipalName]; exists { + if workUnitContainsName(&(*workunits)[index], prtb.UserName) { + (*workunits)[index].activeDirectoryPRTBs = append((*workunits)[index].activeDirectoryPRTBs, prtb) + } else { + logrus.Warnf("[%v] found PRTB for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, prtb.UserPrincipalName, prtb.UserName) + } + } else if index, exists = duplicateLocalWorkUnitsByPrincipal[prtb.UserPrincipalName]; exists { + if workUnitContainsName(&(*workunits)[index], prtb.UserName) { + (*workunits)[index].duplicateLocalPRTBs = append((*workunits)[index].duplicateLocalPRTBs, prtb) + } else { + logrus.Warnf("[%v] found PRTB for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, prtb.UserPrincipalName, prtb.UserName) + } + } + } +} + +func identifyGRBs(workunits *[]migrateUserWorkUnit, grbList *v3.GlobalRoleBindingList) { + duplicateLocalWorkUnitsByName := map[string]int{} + + for _, workunit := range *workunits { + for j := range workunit.duplicateUsers { + duplicateLocalWorkUnitsByName[workunit.duplicateUsers[j].Name] = j + } + } + + for _, grb := range grbList.Items { + if index, exists := duplicateLocalWorkUnitsByName[grb.UserName]; exists { + (*workunits)[index].duplicateLocalGRBs = append((*workunits)[index].duplicateLocalGRBs, grb) + } + } +} + +func updateCRTB(crtbInterface v3norman.ClusterRoleTemplateBindingInterface, oldCrtb *v3.ClusterRoleTemplateBinding, userName string, principalID string) error { + newAnnotations := oldCrtb.Annotations + if newAnnotations == nil { + newAnnotations = make(map[string]string) + } + + newLabels := oldCrtb.Labels + if newLabels == nil { + newLabels = make(map[string]string) + } + newLabels[migrationPreviousName] = oldCrtb.Name + newLabels[adGUIDMigrationLabel] = migratedLabelValue + + // For RBAC reasons, we will delay adding annotations until after the resource is created + + newCrtb := &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + Namespace: oldCrtb.ObjectMeta.Namespace, + GenerateName: "crtb-", + Annotations: newAnnotations, + Labels: newLabels, + }, + ClusterName: oldCrtb.ClusterName, + UserName: userName, + RoleTemplateName: oldCrtb.RoleTemplateName, + UserPrincipalName: principalID, + } + + // If we get an internal error during any of these ops, there's a good chance the webhook is overwhelmed. + // We'll take the opportunity to rate limit ourselves and try again a few times. + + backoff := wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 10, + } + + var createdCrtb *v3.ClusterRoleTemplateBinding + err := wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this does NOT trigger an RBAC sync correctly + createdCrtb, err = crtbInterface.Create(newCrtb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while creating CRTB, will backoff and retry: %v", migrateCrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to create new CRTB: %w", migrateCrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when creating CRTB, giving up: %v", migrateCrtbsOperation, err) + } + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this DOES trigger an RBAC sync which removes the binding in downstream clusters + // It does NOT automatically re-queue the newly created binding from above + err = crtbInterface.DeleteNamespaced(oldCrtb.Namespace, oldCrtb.Name, &metav1.DeleteOptions{}) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while deleting CRTB, will backoff and retry: %v", migrateCrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to delete old CRTB: %w", migrateCrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when deleting CRTB, giving up: %v", migrateCrtbsOperation, err) + } + + // Adding the annotation here has the side effect of triggering a downstream RBAC sync for our newly created + // binding, which is why we perform it last + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + updatedCrtb, err := crtbInterface.GetNamespaced(oldCrtb.Namespace, createdCrtb.Name, metav1.GetOptions{}) + if err != nil { + return true, fmt.Errorf("[%v] unable to get newly created CRTB: %w", migrateCrtbsOperation, err) + } + + if updatedCrtb.Annotations == nil { + updatedCrtb.Annotations = make(map[string]string) + } + updatedCrtb.Annotations[adGUIDMigrationAnnotation] = updatedCrtb.UserPrincipalName + + _, err = crtbInterface.Update(updatedCrtb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while updating CRTB, will backoff and retry: %v", migrateCrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to update new CRTB: %w", migrateCrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when updating CRTB, giving up: %v", migrateCrtbsOperation, err) + } + + return nil +} + +func migrateCRTBs(workunit *migrateUserWorkUnit, sc *config.ScaledContext, dryRun bool) { + crtbInterface := sc.Management.ClusterRoleTemplateBindings("") + // First convert all GUID-based CRTBs to their equivalent Distinguished Name variants + dnPrincipalID := activeDirectoryPrefix + workunit.distinguishedName + for _, oldCrtb := range workunit.activeDirectoryCRTBs { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate CRTB '%v' from GUID principal '%v' to DN principal '%v'. "+ + "Annotation, %v, and labels %v and %v would be added, including the name of the previous CRTB instance", + migrateCrtbsOperation, oldCrtb.Name, oldCrtb.UserPrincipalName, dnPrincipalID, adGUIDMigrationAnnotation, migrationPreviousName, adGUIDMigrationLabel) + } else { + err := updateCRTB(crtbInterface, &oldCrtb, workunit.originalUser.Name, dnPrincipalID) + if err != nil { + logrus.Errorf("[%v] error while migrating CRTBs for user '%v': %v", migrateCrtbsOperation, workunit.originalUser.Name, err) + } + } + } + // Now do the same for Local ID bindings on the users we are about to delete, pointing them instead to the merged + // original user that we will be keeping + localPrincipalID := localPrefix + workunit.originalUser.Name + for _, oldCrtb := range workunit.duplicateLocalCRTBs { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate CRTB '%v' from duplicate local user '%v' to original user '%v'"+ + "Annotation, %v, and labels %v and %v would be added, including the name of the previous CRTB instance", + migrateCrtbsOperation, oldCrtb.Name, oldCrtb.UserPrincipalName, localPrincipalID, adGUIDMigrationAnnotation, migrationPreviousName, adGUIDMigrationLabel) + } else { + err := updateCRTB(crtbInterface, &oldCrtb, workunit.originalUser.Name, localPrincipalID) + if err != nil { + logrus.Errorf("[%v] error while migrating crtbs for user '%v': %v", migrateCrtbsOperation, workunit.originalUser.Name, err) + } + } + } +} + +func updatePRTB(prtbInterface v3norman.ProjectRoleTemplateBindingInterface, oldPrtb *v3.ProjectRoleTemplateBinding, userName string, principalID string) error { + newAnnotations := oldPrtb.Annotations + if newAnnotations == nil { + newAnnotations = make(map[string]string) + } + newLabels := oldPrtb.Labels + if newLabels == nil { + newLabels = make(map[string]string) + } + newLabels[migrationPreviousName] = oldPrtb.Name + newLabels[adGUIDMigrationLabel] = migratedLabelValue + + // For RBAC reasons, we will delay adding annotations until after the resource is created + + newPrtb := &v3.ProjectRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + Namespace: oldPrtb.ObjectMeta.Namespace, + GenerateName: "prtb-", + Annotations: newAnnotations, + Labels: newLabels, + }, + ProjectName: oldPrtb.ProjectName, + UserName: userName, + RoleTemplateName: oldPrtb.RoleTemplateName, + UserPrincipalName: principalID, + } + + // If we get an internal error during any of these ops, there's a good chance the webhook is overwhelmed. + // We'll take the opportunity to rate limit ourselves and try again a few times. + + backoff := wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 10, + } + + var createdPrtb *v3.ProjectRoleTemplateBinding + err := wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this does NOT trigger an RBAC sync correctly + createdPrtb, err = prtbInterface.Create(newPrtb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while creating prtb, will backoff and retry: %v", migratePrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to create new PRTB: %w", migratePrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when creating prtb, giving up: %v", migratePrtbsOperation, err) + } + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this DOES trigger an RBAC sync which removes the binding in downstream clusters + // It does NOT automatically re-queue the newly created binding from above + err = prtbInterface.DeleteNamespaced(oldPrtb.Namespace, oldPrtb.Name, &metav1.DeleteOptions{}) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while deleting prtb, will backoff and retry: %v", migratePrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to delete old PRTB: %w", migratePrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when deleting prtb, giving up: %v", migratePrtbsOperation, err) + } + + // Adding the annotation here has the side effect of triggering a downstream RBAC sync for our newly created + // binding, which is why we perform it last + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + updatedPrtb, err := prtbInterface.GetNamespaced(oldPrtb.Namespace, createdPrtb.Name, metav1.GetOptions{}) + if err != nil { + return true, fmt.Errorf("[%v] unable to get newly created PRTB: %w", migratePrtbsOperation, err) + } + + if updatedPrtb.Annotations == nil { + updatedPrtb.Annotations = make(map[string]string) + } + updatedPrtb.Annotations[adGUIDMigrationAnnotation] = updatedPrtb.UserPrincipalName + _, err = prtbInterface.Update(updatedPrtb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while updating PRTB, will backoff and retry: %v", migratePrtbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to update new PRTB: %w", migratePrtbsOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when updating PRTB, giving up: %v", migratePrtbsOperation, err) + } + + return nil +} + +func migratePRTBs(workunit *migrateUserWorkUnit, sc *config.ScaledContext, dryRun bool) { + prtbInterface := sc.Management.ProjectRoleTemplateBindings("") + // First convert all GUID-based PRTBs to their equivalent Distinguished Name variants + dnPrincipalID := activeDirectoryPrefix + workunit.distinguishedName + for _, oldPrtb := range workunit.activeDirectoryPRTBs { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate PRTB '%v' from GUID principal '%v' to DN principal '%v'. "+ + "Annotation, %v, and labels %v and %v would be added, including the name of the previous PRTB instance", + migratePrtbsOperation, oldPrtb.Name, oldPrtb.UserPrincipalName, dnPrincipalID, adGUIDMigrationAnnotation, migrationPreviousName, adGUIDMigrationLabel) + + } else { + err := updatePRTB(prtbInterface, &oldPrtb, workunit.originalUser.Name, dnPrincipalID) + if err != nil { + logrus.Errorf("[%v] error while migrating prtbs for user '%v': %v", migratePrtbsOperation, workunit.originalUser.Name, err) + } + } + } + // Now do the same for Local ID bindings on the users we are about to delete, pointing them instead to the merged + // original user that we will be keeping + localPrincipalID := localPrefix + workunit.originalUser.Name + for _, oldPrtb := range workunit.duplicateLocalPRTBs { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate PRTB '%v' from duplicate local user '%v' to original user '%v'. "+ + "Annotation, %v, and labels %v and %v would be added, including the name of the previous PRTB instance", + migratePrtbsOperation, oldPrtb.Name, oldPrtb.UserPrincipalName, localPrincipalID, adGUIDMigrationAnnotation, migrationPreviousName, adGUIDMigrationLabel) + + } else { + err := updatePRTB(prtbInterface, &oldPrtb, workunit.originalUser.Name, localPrincipalID) + if err != nil { + logrus.Errorf("[%v] error while migrating prtbs for user '%v': %v", migratePrtbsOperation, workunit.originalUser.Name, err) + } + } + } +} + +func migrateGRBs(workunit *migrateUserWorkUnit, sc *config.ScaledContext, dryRun bool) { + grbInterface := sc.Management.GlobalRoleBindings("") + + backoff := wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 10, + } + + for _, oldGrb := range workunit.duplicateLocalGRBs { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate GRB '%v' from duplicate local user '%v' to original user '%v'. "+ + "Labels %v and %v would be added, including the name of the previous GRB instance", + migrateGrbsOperation, oldGrb.Name, oldGrb.UserName, workunit.originalUser.Name, migrationPreviousName, adGUIDMigrationLabel) + } else { + newAnnotations := oldGrb.Annotations + if newAnnotations == nil { + newAnnotations = make(map[string]string) + } + + // For RBAC reasons, we will delay adding annotations until after the resource is created + + newLabels := oldGrb.Labels + if newLabels == nil { + newLabels = make(map[string]string) + } + newLabels[migrationPreviousName] = oldGrb.Name + newLabels[adGUIDMigrationLabel] = migratedLabelValue + + newGrb := &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + GenerateName: "grb-", + Annotations: newAnnotations, + Labels: newLabels, + }, + GlobalRoleName: oldGrb.GlobalRoleName, + GroupPrincipalName: oldGrb.GroupPrincipalName, + UserName: workunit.originalUser.Name, + } + + var createdGrb *v3.GlobalRoleBinding + err := wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this does NOT trigger an RBAC sync correctly + createdGrb, err = grbInterface.Create(newGrb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while creating GRB, will backoff and retry: %v", migrateGrbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to create new GRB: %w", migrateGrbsOperation, err) + } + return true, nil + }) + if err != nil { + logrus.Errorf("[%v] permanent error while creating GRB, giving up: %v", migrateGrbsOperation, err) + continue + } + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + // Note: this DOES trigger an RBAC sync which removes the binding in downstream clusters + // It does NOT automatically re-queue the newly created binding from above + err = sc.Management.GlobalRoleBindings("").Delete(oldGrb.Name, &metav1.DeleteOptions{}) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while deleting GRB, will backoff and retry: %v", migrateGrbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to delete old GRB: %w", migrateGrbsOperation, err) + } + return true, nil + }) + if err != nil { + logrus.Errorf("[%v] permanent error when deleting GRB, giving up: %v", migrateGrbsOperation, err) + continue + } + + // Adding the annotation here has the side effect of triggering a downstream RBAC sync for our newly created + // binding, which is why we perform it last + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + updatedGrb, err := sc.Management.GlobalRoleBindings("").GetNamespaced(oldGrb.Namespace, createdGrb.Name, metav1.GetOptions{}) + if err != nil { + return true, fmt.Errorf("[%v] unable to get newly created GRB: %w", migrateGrbsOperation, err) + } + if updatedGrb.Annotations == nil { + updatedGrb.Annotations = make(map[string]string) + } + updatedGrb.Annotations[adGUIDMigrationAnnotation] = oldGrb.UserName + + _, err = sc.Management.GlobalRoleBindings("").Update(updatedGrb) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while updating GRB, will backoff and retry: %v", migrateGrbsOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to update GRB: %w", migrateGrbsOperation, err) + } + return true, nil + }) + if err != nil { + logrus.Errorf("[%v] permanent error when updating GRB, giving up: %v", migrateGrbsOperation, err) + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs_test.go new file mode 100644 index 0000000..07c4333 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/rtbs_test.go @@ -0,0 +1,247 @@ +package adunmigration + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + testGuid = "953d82a03d47a5498330293e386dfce1" + testDn = "CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space" + testDnLocalName = "user-vhhxd" + testGuidLocalName = "u-fydcaomakf" + testDuplicateGuidLocalName = "u-quuknbiweg" + testGuidPrincipal = "activedirectory_user://" + testGuid + testDnPrincipal = "activedirectory_user://" + testDn + testDnLocalPrincipal = "local://" + testDnLocalName + testGuidLocalPrincipal = "local://" + testGuidLocalName + testDuplicateGuidLocalPrincipal = "local://" + testDuplicateGuidLocalName +) + +func guidOriginalWorkunit() migrateUserWorkUnit { + // The "success" case for the original migration logic: only the GUID is left, with no extra copies + return migrateUserWorkUnit{ + guid: testGuid, + distinguishedName: testDn, + originalUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, + PrincipalIDs: []string{testGuidLocalPrincipal, testGuidPrincipal}}, + } +} + +func guidOriginalGuidDuplicateWorkunit() migrateUserWorkUnit { + // An uncommon case caused by a race condition: the older GUID-based user was migrated, but not + // before a newer GUID-based duplicate was created. After this, the affected user can no longer log in + // due to both users having the same principal ID + return migrateUserWorkUnit{ + guid: testGuid, + distinguishedName: testDn, + originalUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, + PrincipalIDs: []string{testGuidLocalPrincipal, testGuidPrincipal}, + }, + duplicateUsers: []*v3.User{{ + ObjectMeta: metav1.ObjectMeta{Name: testDuplicateGuidLocalName}, + PrincipalIDs: []string{testDuplicateGuidLocalPrincipal, testGuidPrincipal}}}, + } +} + +func dnOriginalGuidDuplicateWorkunit() migrateUserWorkUnit { + // Caused by a failure to migrate the original user. A new GUID-based user is + // then created at the next login with none of the original permissions. + return migrateUserWorkUnit{ + guid: testGuid, + distinguishedName: testDn, + originalUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: testDnLocalName}, + PrincipalIDs: []string{testDnLocalPrincipal, testDnPrincipal}}, + duplicateUsers: []*v3.User{{ + ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalName}, + PrincipalIDs: []string{testGuidLocalPrincipal, testGuidPrincipal}}}, + } +} + +func TestIdentifyCRTBs(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + workunit migrateUserWorkUnit + crtbs []v3.ClusterRoleTemplateBinding + wantAdCrtbs int + wantDuplicateLocalCrtbs int + }{ + { + name: "Guid-based CRTB referencing Original GUID-based user will be migrated", + workunit: guidOriginalWorkunit(), + crtbs: []v3.ClusterRoleTemplateBinding{ + {UserName: testGuidLocalName, UserPrincipalName: testGuidPrincipal}, + }, + wantAdCrtbs: 1, + wantDuplicateLocalCrtbs: 0, + }, + { + name: "Local-based CRTB referencing Original GUID-based user will not be migrated", + workunit: guidOriginalWorkunit(), + crtbs: []v3.ClusterRoleTemplateBinding{ + {UserName: testGuidLocalName, UserPrincipalName: testGuidLocalPrincipal}, + }, + wantAdCrtbs: 0, + wantDuplicateLocalCrtbs: 0, + }, + { + name: "Guid-based CRTB referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + crtbs: []v3.ClusterRoleTemplateBinding{ + {UserName: testDuplicateGuidLocalName, UserPrincipalName: testGuidPrincipal}, + }, + wantAdCrtbs: 1, + wantDuplicateLocalCrtbs: 0, + }, + { + name: "Local-based CRTB referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + crtbs: []v3.ClusterRoleTemplateBinding{ + {UserName: testDuplicateGuidLocalName, UserPrincipalName: testDuplicateGuidLocalPrincipal}, + }, + wantAdCrtbs: 0, + wantDuplicateLocalCrtbs: 1, + }, + { + name: "DN-based CRTB referencing Original DN-based user will not be migrated", + workunit: dnOriginalGuidDuplicateWorkunit(), + crtbs: []v3.ClusterRoleTemplateBinding{ + {UserName: testDnLocalName, UserPrincipalName: testDnLocalPrincipal}, + }, + wantAdCrtbs: 0, + wantDuplicateLocalCrtbs: 0, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + crtbList := v3.ClusterRoleTemplateBindingList{Items: test.crtbs} + workunitList := []migrateUserWorkUnit{test.workunit} + identifyCRTBs(&workunitList, &crtbList) + + assert.Equal(t, test.wantAdCrtbs, len(workunitList[0].activeDirectoryCRTBs), "expected AD-based CRTBs must match") + assert.Equal(t, test.wantDuplicateLocalCrtbs, len(workunitList[0].duplicateLocalCRTBs), "expected duplicate Local-based CRTBs must match") + }) + } +} + +func TestIdentifyPRTBs(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + workunit migrateUserWorkUnit + prtbs []v3.ProjectRoleTemplateBinding + wantAdPrtbs int + wantDuplicateLocalPrtbs int + }{ + { + name: "Guid-based PRTB referencing Original GUID-based user will be migrated", + workunit: guidOriginalWorkunit(), + prtbs: []v3.ProjectRoleTemplateBinding{ + {UserName: testGuidLocalName, UserPrincipalName: testGuidPrincipal}, + }, + wantAdPrtbs: 1, + wantDuplicateLocalPrtbs: 0, + }, + { + name: "Local-based PRTB referencing Original GUID-based user will not be migrated", + workunit: guidOriginalWorkunit(), + prtbs: []v3.ProjectRoleTemplateBinding{ + {UserName: testGuidLocalName, UserPrincipalName: testGuidLocalPrincipal}, + }, + wantAdPrtbs: 0, + wantDuplicateLocalPrtbs: 0, + }, + { + name: "Guid-based PRTB referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + prtbs: []v3.ProjectRoleTemplateBinding{ + {UserName: testDuplicateGuidLocalName, UserPrincipalName: testGuidPrincipal}, + }, + wantAdPrtbs: 1, + wantDuplicateLocalPrtbs: 0, + }, + { + name: "Local-based PRTB referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + prtbs: []v3.ProjectRoleTemplateBinding{ + {UserName: testDuplicateGuidLocalName, UserPrincipalName: testDuplicateGuidLocalPrincipal}, + }, + wantAdPrtbs: 0, + wantDuplicateLocalPrtbs: 1, + }, + { + name: "DN-based PRTB referencing Original DN-based user will not be migrated", + workunit: dnOriginalGuidDuplicateWorkunit(), + prtbs: []v3.ProjectRoleTemplateBinding{ + {UserName: testDnLocalName, UserPrincipalName: testDnLocalPrincipal}, + }, + wantAdPrtbs: 0, + wantDuplicateLocalPrtbs: 0, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + prtbList := v3.ProjectRoleTemplateBindingList{Items: test.prtbs} + workunitList := []migrateUserWorkUnit{test.workunit} + identifyPRTBs(&workunitList, &prtbList) + + assert.Equal(t, test.wantAdPrtbs, len(workunitList[0].activeDirectoryPRTBs), "expected AD-based PRTBs must match") + assert.Equal(t, test.wantDuplicateLocalPrtbs, len(workunitList[0].duplicateLocalPRTBs), "expected duplicate Local-based PRTBs must match") + }) + } +} + +func TestIdentifyGRBs(t *testing.T) { + //t.Parallel() + + tests := []struct { + name string + workunit migrateUserWorkUnit + grbs []v3.GlobalRoleBinding + wantDuplicateLocalGrbs int + }{ + { + name: "GRB referencing Original user will not be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + grbs: []v3.GlobalRoleBinding{ + {UserName: testGuidLocalName}, + }, + wantDuplicateLocalGrbs: 0, + }, + { + name: "GRB referencing Duplicate user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + grbs: []v3.GlobalRoleBinding{ + {UserName: testDuplicateGuidLocalName}, + }, + wantDuplicateLocalGrbs: 1, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grbList := v3.GlobalRoleBindingList{Items: test.grbs} + workunitList := []migrateUserWorkUnit{test.workunit} + identifyGRBs(&workunitList, &grbList) + + assert.Equal(t, test.wantDuplicateLocalGrbs, len(workunitList[0].duplicateLocalGRBs), "expected duplicate GRBs must match") + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens.go new file mode 100644 index 0000000..dc9836c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens.go @@ -0,0 +1,119 @@ +package adunmigration + +import ( + "fmt" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3norman "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/types/config" +) + +func identifyTokens(workunits *[]migrateUserWorkUnit, tokenList *v3.TokenList) { + adWorkUnitsByPrincipal, duplicateLocalWorkUnitsByPrincipal := principalsToMigrate(workunits) + + for _, token := range tokenList.Items { + if index, exists := adWorkUnitsByPrincipal[token.UserPrincipal.Name]; exists { + if workUnitContainsName(&(*workunits)[index], token.UserID) { + (*workunits)[index].activeDirectoryTokens = append((*workunits)[index].activeDirectoryTokens, token) + } else { + logrus.Warnf("[%v] found token for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, token.UserPrincipal.Name, token.UserID) + } + } else if index, exists = duplicateLocalWorkUnitsByPrincipal[token.UserPrincipal.Name]; exists { + if workUnitContainsName(&(*workunits)[index], token.UserID) { + (*workunits)[index].duplicateLocalTokens = append((*workunits)[index].duplicateLocalTokens, token) + } else { + logrus.Warnf("[%v] found token for user with guid-based principal '%v' and name '%v', but no user object with that name matches the GUID or its associated DN. refusing to process", + identifyAdUserOperation, token.UserPrincipal.Name, token.UserID) + } + } + } +} + +func updateToken(tokenInterface v3norman.TokenInterface, userToken v3.Token, newPrincipalID string, guid string, targetUser *v3.User, targetPrincipal *v3.Principal) error { + latestToken, err := tokenInterface.Get(userToken.Name, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[%v] token %s no longer exists: %v", migrateTokensOperation, userToken.Name, err) + return nil + } + if latestToken.Annotations == nil { + latestToken.Annotations = make(map[string]string) + } + latestToken.Annotations[adGUIDMigrationAnnotation] = guid + if latestToken.Labels == nil { + latestToken.Labels = make(map[string]string) + } + latestToken.Labels[tokens.UserIDLabel] = targetUser.Name + latestToken.Labels[adGUIDMigrationLabel] = migratedLabelValue + // use the new dnPrincipalID for the token name + latestToken.UserPrincipal.Name = newPrincipalID + // copy over other relevant fields to match the user we are attaching this token to + latestToken.UserPrincipal.LoginName = targetPrincipal.LoginName + latestToken.UserPrincipal.DisplayName = targetPrincipal.DisplayName + latestToken.UserID = targetUser.Name + + // If we get an internal error during any of these ops, there's a good chance the webhook is overwhelmed. + // We'll take the opportunity to rate limit ourselves and try again a few times. + + backoff := wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 10, + } + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + _, err = tokenInterface.Update(latestToken) + if err != nil { + if apierrors.IsInternalError(err) { + logrus.Errorf("[%v] internal error while updating token, will backoff and retry: %v", migrateTokensOperation, err) + return false, err + } + return true, fmt.Errorf("[%v] unable to update token: %w", migrateTokensOperation, err) + } + return true, nil + }) + if err != nil { + return fmt.Errorf("[%v] permanent error when updating token, giving up: %v", migrateTokensOperation, err) + } + + return nil +} + +func migrateTokens(workunit *migrateUserWorkUnit, sc *config.ScaledContext, dryRun bool) { + tokenInterface := sc.Management.Tokens("") + dnPrincipalID := activeDirectoryPrefix + workunit.distinguishedName + for _, userToken := range workunit.activeDirectoryTokens { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate token '%v' from GUID principal '%v' to DN principal '%v'. "+ + "Would add annotation, %v, and label, %v, to indicate migration status", + migrateTokensOperation, userToken.Name, userToken.UserPrincipal.Name, dnPrincipalID, adGUIDMigrationAnnotation, adGUIDMigrationLabel) + } else { + err := updateToken(tokenInterface, userToken, dnPrincipalID, workunit.guid, workunit.originalUser, workunit.principal) + if err != nil { + logrus.Errorf("[%v] error while migrating tokens for user '%v': %v", migrateTokensOperation, workunit.originalUser.Name, err) + } + } + } + + localPrincipalID := localPrefix + workunit.originalUser.Name + for _, userToken := range workunit.duplicateLocalTokens { + if dryRun { + logrus.Infof("[%v] DRY RUN: would migrate Token '%v' from duplicate local user '%v' to original user '%v'. "+ + "Would add annotation, %v, and label, %v, to indicate migration status", + migrateTokensOperation, userToken.Name, userToken.UserPrincipal.Name, localPrincipalID, adGUIDMigrationAnnotation, adGUIDMigrationLabel) + } else { + err := updateToken(tokenInterface, userToken, localPrincipalID, workunit.guid, workunit.originalUser, workunit.principal) + if err != nil { + logrus.Errorf("[%v] error while migrating tokens for user '%v': %v", migrateTokensOperation, workunit.originalUser.Name, err) + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens_test.go new file mode 100644 index 0000000..5353c35 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/tokens_test.go @@ -0,0 +1,80 @@ +package adunmigration + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestIdentifyTokens(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + workunit migrateUserWorkUnit + tokens []v3.Token + wantAdTokens int + wantDuplicateLocalTokens int + }{ + { + name: "Guid-based token referencing Original GUID-based user will be migrated", + workunit: guidOriginalWorkunit(), + tokens: []v3.Token{ + {UserID: testGuidLocalName, UserPrincipal: v3.Principal{ObjectMeta: metav1.ObjectMeta{Name: testGuidPrincipal}}}, + }, + wantAdTokens: 1, + wantDuplicateLocalTokens: 0, + }, + { + name: "Local-based token referencing Original GUID-based user will not be migrated", + workunit: guidOriginalWorkunit(), + tokens: []v3.Token{ + {UserID: testGuidLocalName, UserPrincipal: v3.Principal{ObjectMeta: metav1.ObjectMeta{Name: testGuidLocalPrincipal}}}, + }, + wantAdTokens: 0, + wantDuplicateLocalTokens: 0, + }, + { + name: "Guid-based token referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + tokens: []v3.Token{ + {UserID: testDuplicateGuidLocalName, UserPrincipal: v3.Principal{ObjectMeta: metav1.ObjectMeta{Name: testGuidPrincipal}}}, + }, + wantAdTokens: 1, + wantDuplicateLocalTokens: 0, + }, + { + name: "Local-based token referencing Duplicate GUID-based user will be migrated", + workunit: guidOriginalGuidDuplicateWorkunit(), + tokens: []v3.Token{ + {UserID: testDuplicateGuidLocalName, UserPrincipal: v3.Principal{ObjectMeta: metav1.ObjectMeta{Name: testDuplicateGuidLocalPrincipal}}}, + }, + wantAdTokens: 0, + wantDuplicateLocalTokens: 1, + }, + { + name: "DN-based token referencing Original DN-based user will not be migrated", + workunit: dnOriginalGuidDuplicateWorkunit(), + tokens: []v3.Token{ + {UserID: testDnLocalName, UserPrincipal: v3.Principal{ObjectMeta: metav1.ObjectMeta{Name: testDnLocalPrincipal}}}, + }, + wantAdTokens: 0, + wantDuplicateLocalTokens: 0, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + tokenList := v3.TokenList{Items: test.tokens} + workunitList := []migrateUserWorkUnit{test.workunit} + identifyTokens(&workunitList, &tokenList) + + assert.Equal(t, test.wantAdTokens, len(workunitList[0].activeDirectoryTokens), "expected AD-based tokens must match") + assert.Equal(t, test.wantDuplicateLocalTokens, len(workunitList[0].duplicateLocalTokens), "expected duplicate Local-based tokens must match") + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users.go new file mode 100644 index 0000000..189b50c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users.go @@ -0,0 +1,112 @@ +package adunmigration + +import ( + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func describePlannedChanges(workunit migrateUserWorkUnit) { + logrus.Debugf("[%v] DRY RUN: changes to user '%v' have NOT been saved.", migrateAdUserOperation, workunit.originalUser.Name) + if len(workunit.duplicateUsers) > 0 { + logrus.Infof("[%v] DRY RUN: duplicate users were identified", migrateAdUserOperation) + for _, duplicateUser := range workunit.duplicateUsers { + logrus.Infof("[%v] DRY RUN: would DELETE user %v", migrateAdUserOperation, duplicateUser.Name) + } + } +} + +func deleteDuplicateUsers(workunit migrateUserWorkUnit, sc *config.ScaledContext) error { + for _, duplicateUser := range workunit.duplicateUsers { + err := sc.Management.Users("").Delete(duplicateUser.Name, &metav1.DeleteOptions{}) + if err != nil { + logrus.Errorf("[%v] failed to delete dupliate user '%v' with: %v", migrateAdUserOperation, workunit.originalUser.Name, err) + // If the duplicate deletion has failed for some reason, it is NOT safe to save the modified user, as + // this may result in a duplicate AD principal ID. Notify and skip. + + logrus.Errorf("[%v] cannot safely save modifications to user %v, skipping", migrateAdUserOperation, workunit.originalUser.Name) + return errors.Errorf("failed to delete duplicate users") + } + logrus.Infof("[%v] deleted duplicate user %v", migrateAdUserOperation, duplicateUser.Name) + } + return nil +} + +func updateModifiedUser(workunit migrateUserWorkUnit, sc *config.ScaledContext) { + workunit.originalUser.Annotations[adGUIDMigrationAnnotation] = workunit.guid + workunit.originalUser.Labels[adGUIDMigrationLabel] = migratedLabelValue + _, err := sc.Management.Users("").Update(workunit.originalUser) + if err != nil { + logrus.Errorf("[%v] failed to save modified user '%v' with: %v", migrateAdUserOperation, workunit.originalUser.Name, err) + } + logrus.Infof("[%v] user %v was successfully migrated", migrateAdUserOperation, workunit.originalUser.Name) +} + +func replaceGUIDPrincipalWithDn(user *v3.User, dn string, guid string, dryRun bool) { + // It's weird for a single user to have more than just an AD and a Local principal ID, but it *can* happen + // if Rancher has used more than one auth provider over its history. Here we'll keep all principal IDs + // that are unrelated to AD + var principalIDs []string + for _, principalID := range user.PrincipalIDs { + if !strings.HasPrefix(principalID, activeDirectoryPrefix) { + principalIDs = append(principalIDs, principalID) + } + } + principalIDs = append(principalIDs, activeDirectoryPrefix+dn) + + if dryRun { + // In dry run mode we will merely print the computed list and leave the original user object alone + logrus.Infof("[%v] DRY RUN: User '%v' with GUID '%v' would have new principals:", migrateAdUserOperation, + user.Name, guid) + for _, principalID := range principalIDs { + logrus.Infof("[%v] DRY RUN: '%v'", migrateAdUserOperation, principalID) + } + } else { + user.PrincipalIDs = principalIDs + logrus.Debugf("[%v] User '%v' with GUID %v will have new principals:", migrateAdUserOperation, + user.Name, guid) + for _, principalID := range user.PrincipalIDs { + logrus.Debugf("[%v] '%v'", migrateAdUserOperation, principalID) + } + } +} + +func isAdUser(user *v3.User) bool { + for _, principalID := range user.PrincipalIDs { + if strings.HasPrefix(principalID, activeDirectoryPrefix) { + return true + } + } + return false +} + +func adPrincipalID(user *v3.User) string { + for _, principalID := range user.PrincipalIDs { + if strings.HasPrefix(principalID, activeDirectoryPrefix) { + return principalID + } + } + return "" +} + +func getExternalID(principalID string) (string, error) { + parts := strings.Split(principalID, "://") + if len(parts) != 2 { + return "", fmt.Errorf("[%v] failed to parse invalid principalID: %v", identifyAdUserOperation, principalID) + } + return parts[1], nil +} + +func getScope(principalID string) (string, error) { + parts := strings.Split(principalID, "://") + if len(parts) != 2 { + return "", fmt.Errorf("[%v] failed to parse invalid principalID: %v", identifyAdUserOperation, principalID) + } + return parts[0], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users_test.go new file mode 100644 index 0000000..2b74507 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/adunmigration/users_test.go @@ -0,0 +1,166 @@ +package adunmigration + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" +) + +func TestIsAdUser(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + user v3.User + wantResult bool + }{ + { + name: "Local user", + user: v3.User{PrincipalIDs: []string{"local://u-fydcaomakf"}}, + wantResult: false, + }, + { + name: "AD user, DN based", + user: v3.User{PrincipalIDs: []string{ + "local://u-fydcaomakf", + "activedirectory_user://CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space"}}, + wantResult: true, + }, + { + name: "AD user, GUID based", + user: v3.User{PrincipalIDs: []string{ + "local://u-fydcaomakf", + "activedirectory_user://953d82a03d47a5498330293e386dfce1"}}, + wantResult: true, + }, + { + name: "Non-local, non-AD user", + user: v3.User{PrincipalIDs: []string{ + "local://u-fydcaomakf", + "okta_user://test.user@example.com"}}, + wantResult: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result := isAdUser(&test.user) + assert.Equal(t, test.wantResult, result) + }) + } +} + +func TestGetExternalId(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + principalId string + wantResult string + wantError bool + }{ + { + name: "Local User", + principalId: "local://u-fydcaomakf", + wantResult: "u-fydcaomakf", + wantError: false, + }, + { + name: "AD user, DN based", + principalId: "activedirectory_user://CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space", + wantResult: "CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space", + wantError: false, + }, + { + name: "AD user, GUID based", + principalId: "activedirectory_user://953d82a03d47a5498330293e386dfce1", + wantResult: "953d82a03d47a5498330293e386dfce1", + wantError: false, + }, + { + name: "Invalid principal", + principalId: "fail-on-purpose", + wantResult: "", + wantError: true, + }, + { + name: "Empty String", + principalId: "", + wantResult: "", + wantError: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result, err := getExternalID(test.principalId) + if test.wantError { + assert.Error(t, err, "expected error") + } else { + assert.NoError(t, err, "unexpected error") + } + assert.Equal(t, test.wantResult, result) + }) + } +} + +func TestGetScope(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + principalId string + wantResult string + wantError bool + }{ + { + name: "Local User", + principalId: "local://u-fydcaomakf", + wantResult: "local", + wantError: false, + }, + { + name: "AD user, DN based", + principalId: "activedirectory_user://CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space", + wantResult: "activedirectory_user", + wantError: false, + }, + { + name: "AD user, GUID based", + principalId: "activedirectory_user://953d82a03d47a5498330293e386dfce1", + wantResult: "activedirectory_user", + wantError: false, + }, + { + name: "Invalid principal", + principalId: "fail-on-purpose", + wantResult: "", + wantError: true, + }, + { + name: "Empty String", + principalId: "", + wantResult: "", + wantError: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result, err := getScope(test.principalId) + if test.wantError { + assert.Error(t, err, "expected error") + } else { + assert.NoError(t, err, "unexpected error") + } + assert.Equal(t, test.wantResult, result) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster.go new file mode 100644 index 0000000..3673d80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster.go @@ -0,0 +1,468 @@ +//go:build !windows +// +build !windows + +/* +The cleanup is designed to get a cluster that was imported to Rancher disconnected +and cleanup some objects + +Remove the cattle-system namespace which houses the agent used to talk +to Rancher + +Remove Rancher labels, finalizers and annotations from all namespaces + +If the cluster was imported to Rancher 2.1 or later cleanup roles, rolebindings, +clusterRoles and clusterRoleBindings +*/ + +package clean + +import ( + "context" + "errors" + "fmt" + "os" + "strings" + "time" + + "github.com/rancher/rancher/pkg/controllers/management/usercontrollers" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm" + "github.com/rancher/rancher/pkg/monitoring" + "github.com/rancher/rancher/pkg/namespace" + "github.com/sirupsen/logrus" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +var ( + // There is a mirror list in pkg/controllers/management/usercontrollers/controller.go. + // If these are getting updated consider if that update needs to apply to the + // local internal cluster as well + + // List of namespace labels that will be removed + nsLabels = []string{ + nslabels.ProjectIDFieldLabel, + } + + // List of namespace annotations that will be removed + nsAnnotations = []string{ + "cattle.io/status", + "field.cattle.io/creatorId", + "field.cattle.io/resourceQuotaTemplateId", + "lifecycle.cattle.io/create.namespace-auth", + nslabels.ProjectIDFieldLabel, + helm.AppIDsLabel, + } + + dryRun bool + + nsToRemove = []string{ + "cattle-system", + "cattle-prometheus", + "cattle-logging", + "cattle-fleet-system", + "cattle-provisioning-capi-system", + "cattle-impersonation-system", + } + + getNSFuncs = []getNSFunc{ + getProjectMonitoringNamespaces, + } +) + +type getNSFunc func(*kubernetes.Clientset) ([]string, error) + +func Cluster() error { + if os.Getenv("DRY_RUN") == "true" { + dryRun = true + } + + if os.Getenv("SLEEP_FIRST") == "true" { + // The sleep allows Rancher server time to finish updating ownerReferences + // and close the connection. + logrus.Info("Starting sleep for 1 min to allow server time to disconnect....") + time.Sleep(time.Duration(1) * time.Minute) + } + + logrus.Info("Starting cluster cleanup") + config, err := rest.InClusterConfig() + if err != nil { + return err + } + + client, err := kubernetes.NewForConfig(config) + if err != nil { + return err + } + + if rancherInstalled, err := isRancherInstalled(client); err != nil { + return fmt.Errorf("checking for %s/rancher service: %w", namespace.System, err) + } else if rancherInstalled { + logrus.Info("Rancher is installed, not performing cleanup") + return deleteJob(client) + } + + var errors []error + var toRemove = make([]string, len(nsToRemove)) + copy(toRemove, nsToRemove) + + for _, f := range getNSFuncs { + list, err := f(client) + if err != nil { + errors = append(errors, err) + } + toRemove = append(toRemove, list...) + } + + for _, ns := range toRemove { + if err := removeNamespace(ns, client); err != nil { + errors = append(errors, err) + } + } + + webhookErr := cleanupWebhookResources(client) + if len(webhookErr) > 0 { + errors = append(errors, webhookErr...) + } + + nsErr := cleanupNamespaces(client) + if len(nsErr) > 0 { + errors = append(errors, nsErr...) + } + + crbErr := cleanupClusterRoleBindings(client) + if len(crbErr) > 0 { + errors = append(errors, crbErr...) + } + + cbErr := cleanupRoleBindings(client) + if len(cbErr) > 0 { + errors = append(errors, cbErr...) + } + + crErr := cleanupClusterRoles(client) + if len(crErr) > 0 { + errors = append(errors, crErr...) + } + + rErr := cleanupRoles(client) + if len(rErr) > 0 { + errors = append(errors, rErr...) + } + + if len(errors) > 0 { + return processErrors(errors) + } + + return deleteJob(client) +} + +func removeNamespace(namespace string, client *kubernetes.Clientset) error { + logrus.Infof("Attempting to remove %s namespace", namespace) + return tryUpdate(func() error { + ns, err := client.CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}) + if err != nil { + if apierror.IsNotFound(err) { + return nil + } + return err + } + if len(ns.Finalizers) > 0 { + ns.Finalizers = []string{} + } + + logrus.Infof("Updating namespace: %v", ns.Name) + if !dryRun { + ns, err = client.CoreV1().Namespaces().Update(context.TODO(), ns, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + + logrus.Infof("Deleting namespace: %v", ns.Name) + if !dryRun { + err = client.CoreV1().Namespaces().Delete(context.TODO(), namespace, metav1.DeleteOptions{}) + if err != nil { + if !apierror.IsNotFound(err) { + return err + } + } + } + + return nil + }) +} + +var listOptions = metav1.ListOptions{ + LabelSelector: "cattle.io/creator=norman", +} + +func cleanupNamespaces(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of namespaces") + namespaces, err := client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return []error{err} + } + + var errs []error + + for _, ns := range namespaces.Items { + err = tryUpdate(func() error { + nameSpace, err := client.CoreV1().Namespaces().Get(context.TODO(), ns.Name, metav1.GetOptions{}) + if err != nil { + if apierror.IsNotFound(err) { + return nil + } + return err + } + + var updated bool + + // Cleanup finalizers + if len(nameSpace.Finalizers) > 0 { + finalizers := []string{} + for _, finalizer := range nameSpace.Finalizers { + if finalizer != "controller.cattle.io/namespace-auth" { + finalizers = append(finalizers, finalizer) + } + } + if len(nameSpace.Finalizers) != len(finalizers) { + updated = true + nameSpace.Finalizers = finalizers + } + } + + // Cleanup labels + for _, label := range nsLabels { + if _, ok := nameSpace.Labels[label]; ok { + updated = ok + delete(nameSpace.Labels, label) + } + } + + // Cleanup annotations + for _, anno := range nsAnnotations { + if _, ok := nameSpace.Annotations[anno]; ok { + updated = ok + delete(nameSpace.Annotations, anno) + } + } + + if updated { + logrus.Infof("Updating namespace: %v", nameSpace.Name) + if !dryRun { + _, err = client.CoreV1().Namespaces().Update(context.TODO(), nameSpace, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + } + + return nil + }) + + if err != nil { + errs = append(errs, err) + } + } + + return errs + +} + +func cleanupClusterRoleBindings(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of clusterRoleBindings") + crbs, err := client.RbacV1().ClusterRoleBindings().List(context.TODO(), listOptions) + if err != nil { + return []error{err} + } + + var errs []error + + for _, crb := range crbs.Items { + logrus.Infof("Deleting clusterRoleBinding: %v", crb.Name) + if !dryRun { + err = client.RbacV1().ClusterRoleBindings().Delete(context.TODO(), crb.Name, metav1.DeleteOptions{}) + if err != nil { + errs = append(errs, err) + } + } + } + return errs +} + +func cleanupRoleBindings(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of roleBindings") + rbs, err := client.RbacV1().RoleBindings("").List(context.TODO(), listOptions) + if err != nil { + return []error{err} + } + + var errs []error + + for _, rb := range rbs.Items { + logrus.Infof("Deleting roleBinding: %v", rb.Name) + if !dryRun { + err = client.RbacV1().RoleBindings(rb.Namespace).Delete(context.TODO(), rb.Name, metav1.DeleteOptions{}) + if err != nil { + errs = append(errs, err) + } + } + } + return errs +} + +func cleanupClusterRoles(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of clusterRoles") + crs, err := client.RbacV1().ClusterRoles().List(context.TODO(), listOptions) + if err != nil { + return []error{err} + } + + var errs []error + + for _, cr := range crs.Items { + logrus.Infof("Deleting clusterRole: %v", cr.Name) + if !dryRun { + err = client.RbacV1().ClusterRoles().Delete(context.TODO(), cr.Name, metav1.DeleteOptions{}) + if err != nil { + errs = append(errs, err) + } + } + } + return errs +} + +func cleanupRoles(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of roles") + rs, err := client.RbacV1().Roles("").List(context.TODO(), listOptions) + if err != nil { + return []error{err} + } + + var errs []error + + for _, r := range rs.Items { + logrus.Infof("Deleting role: %v", r.Name) + if !dryRun { + err = client.RbacV1().Roles(r.Namespace).Delete(context.TODO(), r.Name, metav1.DeleteOptions{}) + if err != nil { + errs = append(errs, err) + } + } + } + return errs +} + +func cleanupWebhookResources(client *kubernetes.Clientset) []error { + logrus.Info("Starting cleanup of webhook-specific resources") + logrus.Infof("Deleting clusterrolebinding %s", usercontrollers.WebhookClusterRoleBindingName) + logrus.Infof("Deleting mutatingwebhookconfiguration %s", usercontrollers.WebhookConfigurationName) + logrus.Infof("Deleting validatingwebhookconfigurations %s", usercontrollers.WebhookConfigurationName) + + var errs []error + + if !dryRun { + err := client.RbacV1().ClusterRoleBindings().Delete(context.TODO(), usercontrollers.WebhookClusterRoleBindingName, metav1.DeleteOptions{}) + if err != nil && !apierror.IsNotFound(err) { + errs = append(errs, err) + } + + err = client.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(context.TODO(), usercontrollers.WebhookConfigurationName, metav1.DeleteOptions{}) + if err != nil && !apierror.IsNotFound(err) { + errs = append(errs, err) + } + + err = client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Delete(context.TODO(), usercontrollers.WebhookConfigurationName, metav1.DeleteOptions{}) + if err != nil && !apierror.IsNotFound(err) { + errs = append(errs, err) + } + } + return errs +} + +func deleteJob(client *kubernetes.Clientset) error { + logrus.Info("Starting cleanup of jobs") + jobs, err := client.BatchV1().Jobs("default").List(context.TODO(), listOptions) + if err != nil { + return err + } + + for _, job := range jobs.Items { + prop := metav1.DeletePropagationBackground + if strings.HasPrefix(job.Name, "cattle-cleanup") { + logrus.Infof("Deleting job: %v", job.Name) + if !dryRun { + err = client.BatchV1().Jobs("default").Delete(context.TODO(), job.Name, metav1.DeleteOptions{ + PropagationPolicy: &prop, + }) + if err != nil { + return err + } + } + } + } + return nil +} + +// tryUpdate runs the input func and if the error returned is a conflict error +// from k8s it will sleep and attempt to run the func again. This is useful +// when attempting to update an object. +func tryUpdate(f func() error) error { + sleepTime := 100 + tries := 0 + var err error + for tries <= 3 { + err = f() + if err != nil { + if apierror.IsConflict(err) { + time.Sleep(time.Duration(sleepTime) * time.Millisecond) + sleepTime *= 2 + tries++ + continue + } + return err + } + break + } + return err +} + +func processErrors(errs []error) error { + errorString := "Errors: " + for _, err := range errs { + errorString += fmt.Sprintf("%s ", err) + } + return errors.New(errorString) +} + +func getProjectMonitoringNamespaces(client *kubernetes.Clientset) ([]string, error) { + var list []string + nsList, err := client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return nil, err + } + for _, ns := range nsList.Items { + value, ok := ns.Labels[nslabels.ProjectIDFieldLabel] + if !ok { + continue + } + if _, nsname := monitoring.ProjectMonitoringInfo(value); ns.Name != nsname { + continue + } + list = append(list, ns.Name) + } + return list, nil +} + +func isRancherInstalled(k8s kubernetes.Interface) (bool, error) { + _, err := k8s.CoreV1().Services(namespace.System).Get(context.Background(), "rancher", metav1.GetOptions{}) + if apierror.IsNotFound(err) { + return false, nil + } else if err != nil { + return false, err + } + return true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster_windows.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster_windows.go new file mode 100644 index 0000000..deedad0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/cluster_windows.go @@ -0,0 +1,5 @@ +package clean + +func Cluster() error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings.go new file mode 100644 index 0000000..cedf250 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings.go @@ -0,0 +1,388 @@ +//go:build !windows +// +build !windows + +/* +Clean duplicates bindings found in a management cluster. This will collect all +PRTBs and CRTBs, create the labels used to identify the k8s resources that correspond +to those and check for duplicates. If they are found delete all but 1. +This is technically safe as rancher will recreate any CRB or RB that is deleted that +should not have been. +*/ + +package clean + +import ( + "context" + "errors" + "fmt" + "os" + "sort" + "strings" + "sync" + + apiv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/ratelimit" + "github.com/rancher/wrangler/v3/pkg/start" + "github.com/sirupsen/logrus" + k8srbacv1 "k8s.io/api/rbac/v1" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +const ( + crtbType = "crtb" + prtbType = "prtb" + dupeBindingsOperation = "clean-dupe-bindings" +) + +type dupeBindingsCleanup struct { + crtbs v3.ClusterRoleTemplateBindingClient + prtbs v3.ProjectRoleTemplateBindingClient + clusterRoleBindings v1.ClusterRoleBindingClient + roleBindings v1.RoleBindingClient +} + +func DuplicateBindings(clientConfig *restclient.Config) error { + logrus.Infof("[%v] starting bindings cleanup", dupeBindingsOperation) + if os.Getenv("DRY_RUN") == "true" { + logrus.Infof("[%v] DRY_RUN is true, no objects will be deleted/modified", dupeBindingsOperation) + dryRun = true + } + var config *restclient.Config + var err error + if clientConfig != nil { + config = clientConfig + } else { + config, err = clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG")) + if err != nil { + logrus.Errorf("[%v] error in building the cluster config %v", dupeBindingsOperation, err) + return err + } + } + // No one wants to be slow + config.RateLimiter = ratelimit.None + + rancherManagement, err := management.NewFactoryFromConfig(config) + if err != nil { + return err + } + + k8srbac, err := rbac.NewFactoryFromConfig(config) + if err != nil { + return err + } + + starters := []start.Starter{rancherManagement, k8srbac} + + ctx := context.Background() + if err := start.All(ctx, 5, starters...); err != nil { + return err + } + + bc := dupeBindingsCleanup{ + crtbs: rancherManagement.Management().V3().ClusterRoleTemplateBinding(), + prtbs: rancherManagement.Management().V3().ProjectRoleTemplateBinding(), + clusterRoleBindings: k8srbac.Rbac().V1().ClusterRoleBinding(), + roleBindings: k8srbac.Rbac().V1().RoleBinding(), + } + + return bc.clean() +} + +func (bc *dupeBindingsCleanup) clean() error { + crtbs, err := bc.crtbs.List("", metav1.ListOptions{}) + if err != nil { + return err + } + + prtbs, err := bc.prtbs.List("", metav1.ListOptions{}) + if err != nil { + return err + } + + // The label's key and value changes depending on the rancher version + var rancher25 bool + + // Check if we have the updated label, this indicates we are running on rancher 2.5+ + if len(crtbs.Items) > 0 { + if _, ok := crtbs.Items[0].Labels[auth.RtbCrbRbLabelsUpdated]; ok { + rancher25 = true + } + } else if len(prtbs.Items) > 0 { + if _, ok := prtbs.Items[0].Labels[auth.RtbCrbRbLabelsUpdated]; ok { + rancher25 = true + } + } else { + logrus.Infof("[%v] no clusterRoleTemplateBindings or projectRoleTemplateBindings found, exiting.", dupeBindingsOperation) + return nil + } + + var waitGroup sync.WaitGroup + + waitGroup.Add(2) + go func() { + if err := bc.cleanCRTB(rancher25, crtbs.Items); err != nil { + logrus.Errorf("[%v] %v", dupeBindingsOperation, err) + } + waitGroup.Done() + }() + + go func() { + if err := bc.cleanPRTB(rancher25, prtbs.Items); err != nil { + logrus.Errorf("[%v] %v", dupeBindingsOperation, err) + } + waitGroup.Done() + }() + waitGroup.Wait() + return nil +} + +func (bc *dupeBindingsCleanup) cleanCRTB(newLabel bool, crtbs []apiv3.ClusterRoleTemplateBinding) error { + logrus.Debugf("[%v] cleaning up duplicates for %v CRTBs", dupeBindingsOperation, len(crtbs)) + var objectMetas []metav1.ObjectMeta + for _, crtb := range crtbs { + objectMetas = append(objectMetas, crtb.ObjectMeta) + } + + return bc.cleanObjectDuplicates(crtbType, newLabel, objectMetas) +} + +func (bc *dupeBindingsCleanup) cleanPRTB(newLabel bool, prtbs []apiv3.ProjectRoleTemplateBinding) error { + logrus.Debugf("[%v] cleaning up duplicates for %v PRTBs", dupeBindingsOperation, len(prtbs)) + var objectMetas []metav1.ObjectMeta + for _, prtb := range prtbs { + objectMetas = append(objectMetas, prtb.ObjectMeta) + } + + return bc.cleanObjectDuplicates(prtbType, newLabel, objectMetas) +} + +func (bc *dupeBindingsCleanup) cleanObjectDuplicates(bindingType string, newLabel bool, objMetas []metav1.ObjectMeta) error { + // Uppercase so the logging looks pretty + bindingUpper := strings.ToUpper(bindingType) + + var returnErr error + var totalCRBDupes, totalRoleDupes int + + for _, meta := range objMetas { + labels := createLabelSelectors(newLabel, meta, bindingType) + for _, label := range labels { + logrus.Debugf("[%v] checking CRB/RB duplicates for: %v %v label: %v", dupeBindingsOperation, bindingUpper, meta.Name, label) + + var CRBduplicates, RBDupes int + + crbs, err := bc.clusterRoleBindings.List(metav1.ListOptions{LabelSelector: label}) + returnErr = errors.Join(returnErr, err) + + if len(crbs.Items) > 1 { + CRBduplicates += len(crbs.Items) - 1 + returnErr = errors.Join(returnErr, bc.dedupeCRB(crbs.Items)) + } + + roleBindings, err := bc.roleBindings.List("", metav1.ListOptions{LabelSelector: label}) + returnErr = errors.Join(returnErr, err) + + if len(roleBindings.Items) > 1 { + roleDuplicates, err := bc.dedupeRB(roleBindings.Items) + returnErr = errors.Join(returnErr, err) + RBDupes += roleDuplicates + } + if CRBduplicates > 0 || RBDupes > 0 { + totalCRBDupes += CRBduplicates + totalRoleDupes += RBDupes + logrus.Infof("[%v] duplicates: CRB=%v, RB=%v for: %v %v label: %v", dupeBindingsOperation, CRBduplicates, RBDupes, bindingUpper, meta.Name, label) + } else { + logrus.Debugf("[%v] no CRB/RB duplicates found for: %v %v label: %v", dupeBindingsOperation, bindingUpper, meta.Name, label) + } + } + } + logrus.Infof("[%v] total %v duplicate clusterRoleBindings %v, roleBindings %v", dupeBindingsOperation, bindingUpper, totalCRBDupes, totalRoleDupes) + return returnErr +} + +func (bc *dupeBindingsCleanup) dedupeCRB(bindings []k8srbacv1.ClusterRoleBinding) error { + //check if CRB with deterministic name exists + deterministicFound, crbName, err := bc.checkIfDeterministicCRBExists(bindings[0]) + if err != nil { + if !k8sErrors.IsNotFound(err) { + logrus.Errorf("[%v] error attempting to lookup deterministic CRB: %v", dupeBindingsOperation, err) + } + logrus.Infof("[%v] binding with deterministic name not found, will delete all except the oldest binding", dupeBindingsOperation) + } + + duplicates := bindings + if !deterministicFound { + // Sort by creation timestamp so we keep the oldest + sort.Sort(crbByCreation(bindings)) + // Leave the first one alone, we only need the duplicates + duplicates = bindings[1:] + } + + for _, binding := range duplicates { + if deterministicFound && strings.EqualFold(binding.Name, crbName) { + logrus.Infof("[%v] found the CRB with the deterministic name %v, will not delete this", dupeBindingsOperation, binding.Name) + continue + } + if !dryRun { + if err := bc.clusterRoleBindings.Delete(binding.Name, &metav1.DeleteOptions{}); err != nil { + logrus.Errorf("[%v] error attempting to delete CRB %v %v", dupeBindingsOperation, binding.Name, err) + } + } else { + logrus.Infof("[%v] dryRun enabled, clusterRoleBinding %v would be deleted", dupeBindingsOperation, binding.Name) + } + } + return nil +} + +func (bc *dupeBindingsCleanup) dedupeRB(roleBindings []k8srbacv1.RoleBinding) (int, error) { + // roleBindings need to be sorted by namespace. The list gets all of the roleBindings + // with the correct label but we do the processing here to limit the amount of API + // calls this has to do. Sorting off namespace here is much faster than doing a + // call per namespace per label (and gentler on the API). + var duplicatesFound int + + bindingMap := make(map[string][]k8srbacv1.RoleBinding) + for _, b := range roleBindings { + bindingMap[b.Namespace] = append(bindingMap[b.Namespace], b) + } + + for _, bindings := range bindingMap { + //check if RB with deterministic name exists + deterministicFound, rbName, err := bc.checkIfDeterministicRBExists(bindings[0]) + if err != nil { + if !k8sErrors.IsNotFound(err) { + logrus.Errorf("[%v] error attempting to lookup deterministic RB: %v", dupeBindingsOperation, err) + } + logrus.Infof("[%v] binding with deterministic name not found, will delete all except the oldest binding", dupeBindingsOperation) + } + duplicates := bindings + if !deterministicFound { + // Sort by creation timestamp so we keep the oldest + sort.Sort(roleBindingByCreation(bindings)) + // Leave the first one alone, we only need the duplicates + duplicates = bindings[1:] + } + for _, binding := range duplicates { + if deterministicFound && strings.EqualFold(binding.Name, rbName) { + logrus.Infof("[%v] found the RB with the deterministic name %v in namespace %v, will not delete this", dupeBindingsOperation, binding.Name, binding.Namespace) + continue + } + duplicatesFound++ + if !dryRun { + if err := bc.roleBindings.Delete(binding.Namespace, binding.Name, &metav1.DeleteOptions{}); err != nil { + logrus.Errorf("[%v] error attempting to delete RB %v %v", dupeBindingsOperation, binding.Name, err) + } + } else { + logrus.Infof("[%v] dryRun enabled, roleBinding %v in namespace %v would be deleted", dupeBindingsOperation, binding.Name, binding.Namespace) + } + } + } + return duplicatesFound, nil +} + +func (bc *dupeBindingsCleanup) checkIfDeterministicCRBExists(sampleBinding k8srbacv1.ClusterRoleBinding) (bool, string, error) { + var deterministicFound bool + crbName, err := getDeterministicBindingName(sampleBinding) + if err != nil { + return deterministicFound, "", err + } + namedBinding, err := bc.clusterRoleBindings.Get(crbName, metav1.GetOptions{}) + if err != nil || namedBinding == nil { + return deterministicFound, crbName, err + } + return true, crbName, nil +} + +func (bc *dupeBindingsCleanup) checkIfDeterministicRBExists(sampleBinding k8srbacv1.RoleBinding) (bool, string, error) { + var deterministicFound bool + rbName, err := getDeterministicBindingName(sampleBinding) + if err != nil { + return deterministicFound, "", err + } + namedBinding, err := bc.roleBindings.Get(sampleBinding.Namespace, rbName, metav1.GetOptions{}) + if err != nil || namedBinding == nil { + return deterministicFound, rbName, err + } + return true, rbName, nil +} + +func getDeterministicBindingName(object interface{}) (string, error) { + if crb, ok := object.(k8srbacv1.ClusterRoleBinding); ok { + if len(crb.Subjects) > 1 { + return "", fmt.Errorf("found more than one subject for this CRB, cannot cleanup %v", crb.Name) + } + subject := crb.Subjects[0] + crbName := pkgrbac.NameForClusterRoleBinding(crb.RoleRef, subject) + logrus.Debugf("[%v] deterministic crb name for %v is %v", dupeBindingsOperation, crb.Name, crbName) + return crbName, nil + } else if rb, ok := object.(k8srbacv1.RoleBinding); ok { + if len(crb.Subjects) > 1 { + return "", fmt.Errorf("found more than one subject for this RB, cannot cleanup %v", rb.Name) + } + subject := rb.Subjects[0] + rbName := pkgrbac.NameForRoleBinding(rb.Namespace, rb.RoleRef, subject) + logrus.Debugf("[%v] deterministic rb name for %v in ns %v is %v", dupeBindingsOperation, rb.Name, rb.Namespace, rbName) + return rbName, nil + } + return "", nil +} + +// createLabelSelectors creates the labels required to list both clusterRoleBindings and +// roleBindings. See https://github.com/rancher/rancher/pull/28423#issue-468992149 for an explanation +// of the labels. +func createLabelSelectors(newLabel bool, obj metav1.ObjectMeta, objType string) []string { + var labelSelectors []string + var key string + + // newLabel determines if we are using the newer rancher 2.5 style labels + if newLabel { + key = pkgrbac.GetRTBLabel(obj) + labelSelectors = append(labelSelectors, key+"="+auth.MembershipBindingOwner) + } else { + key = string(obj.UID) + labelSelectors = append(labelSelectors, key+"="+auth.MembershipBindingOwnerLegacy) + } + + switch objType { + case crtbType: + labelSelectors = append(labelSelectors, key+"="+auth.CrtbInProjectBindingOwner) + case prtbType: + labelSelectors = append(labelSelectors, key+"="+auth.PrtbInClusterBindingOwner) + } + + return labelSelectors +} + +func rbRoleSubjectKey(roleName string, subject k8srbacv1.Subject) string { + return roleName + "." + subject.Kind + "." + subject.Name +} + +type crbByCreation []k8srbacv1.ClusterRoleBinding + +func (n crbByCreation) Len() int { return len(n) } +func (n crbByCreation) Swap(i, j int) { n[i], n[j] = n[j], n[i] } + +func (n crbByCreation) Less(i, j int) bool { + s := n[i].ObjectMeta.CreationTimestamp + t := n[j].ObjectMeta.CreationTimestamp + return s.Before(&t) +} + +type roleBindingByCreation []k8srbacv1.RoleBinding + +func (n roleBindingByCreation) Len() int { return len(n) } +func (n roleBindingByCreation) Swap(i, j int) { n[i], n[j] = n[j], n[i] } + +func (n roleBindingByCreation) Less(i, j int) bool { + s := n[i].ObjectMeta.CreationTimestamp + t := n[j].ObjectMeta.CreationTimestamp + return s.Before(&t) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings_windows.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings_windows.go new file mode 100644 index 0000000..2b55def --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/dupe_bindings_windows.go @@ -0,0 +1,9 @@ +package clean + +import ( + restclient "k8s.io/client-go/rest" +) + +func DuplicateBindings(clientConfig *restclient.Config) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node.go new file mode 100644 index 0000000..7fc961d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node.go @@ -0,0 +1,8 @@ +package clean + +const ( + NodeCleanupContainerName = "cattle-node-cleanup" + AgentImage = "AGENT_IMAGE" + PrefixPath = "PREFIX_PATH" + WindowsPrefixPath = "WINDOWS_PREFIX_PATH" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_notwindows.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_notwindows.go new file mode 100644 index 0000000..8ee9827 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_notwindows.go @@ -0,0 +1,592 @@ +//go:build !windows +// +build !windows + +package clean + +import ( + "context" + "fmt" + "os" + "os/exec" + "path" + "path/filepath" + "strings" + "time" + + "github.com/coreos/go-iptables/iptables" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" + "github.com/rancher/rke/hosts" + "github.com/sirupsen/logrus" + "github.com/vishvananda/netlink" +) + +const ( + DockerPipe = "/var/run/docker.sock" + HostMount = "/host" +) + +func Run(ctx context.Context, args []string) error { + if len(args) > 3 { + fmt.Println(usage()) + return nil + } + + if len(args) == 3 { + switch args[2] { + case "job": + return job(ctx) + case "node": + return Node(ctx) + case "link", "links": + return links() + case "cluster": + return Cluster() + case "path", "paths": + return paths() + case "firewall", "firewalls": + return firewall() + case "script", "scripts": + fmt.Print(script()) + return nil + case "help": + fmt.Println(usage()) + return nil + default: + fmt.Println(usage()) + return nil + } + } + + fmt.Println(usage()) + return nil +} + +func job(ctx context.Context) error { + logrus.Infof("Starting clean container job: %s", NodeCleanupContainerName) + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + containerList, err := c.ContainerList(ctx, types.ContainerListOptions{}) + if err != nil { + return err + } + + for _, c := range containerList { + for _, n := range c.Names { + if n == "/"+NodeCleanupContainerName { + logrus.Infof("container named %s already exists, exiting.", NodeCleanupContainerName) + return nil + } + } + } + + binds := []string{ + fmt.Sprintf("%s:%s", DockerPipe, DockerPipe), + fmt.Sprintf("%s:%s:z", "/", HostMount), + } + + container, err := c.ContainerCreate(ctx, &container.Config{ + Image: getAgentImage(), + Env: []string{ + fmt.Sprintf("%s=%s", AgentImage, getAgentImage()), + fmt.Sprintf("%s=%s", PrefixPath, os.Getenv(PrefixPath)), + fmt.Sprintf("%s=%s", WindowsPrefixPath, os.Getenv(WindowsPrefixPath)), + }, + Cmd: []string{"--", "agent", "clean", "node"}, + }, &container.HostConfig{ + AutoRemove: true, + Binds: binds, + Privileged: true, + NetworkMode: "host", + }, nil, nil, NodeCleanupContainerName) + + if err != nil { + return err + } + + return c.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}) +} + +func Node(ctx context.Context) error { + logrus.Info("Cleaning up node...") + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + p, err := c.Ping(ctx) + if err != nil { + return fmt.Errorf("error pinging docker api: %s", err) + } + c.NegotiateAPIVersionPing(p) + + if err := waitForK8sPods(ctx, c); err != nil { + return fmt.Errorf("error waiting for k8s pods to be removed: %s", err) + } + + if err := containers(ctx, c); err != nil { + return fmt.Errorf("error trying to stop all rancher containers: %s", err) + } + + if err := docker(ctx, c); err != nil { + return fmt.Errorf("error trying to system prune docker: %s", err) + } + + if err := links(); err != nil { + return fmt.Errorf("error trying to clean links from the host: %s", err) + } + + if err := firewall(); err != nil { + return fmt.Errorf("error trying to flush iptables rules: %s", err) + } + + return paths() +} + +func links() error { + for _, l := range []string{"flannel.1", "cni0", "tunl0", "weave", "datapath", "vxlan-6784"} { + logrus.Infof("checking for link %s", l) + existing, err := netlink.LinkByName(l) + if err != nil { + if err.Error() == "Link not found" { + logrus.Infof("link %s not found", l) + continue // not found, nothing to do + } + + return err + } + + logrus.Infof("found link and will remove: %s", l) + if err := netlink.LinkDel(existing); err != nil { + return fmt.Errorf("failed to delete interface: %v", err) + } + logrus.Infof("link deleted: %s", l) + } + + return nil +} + +func paths() error { + logrus.Info("Cleaning up paths...") + + if err := umountTmpfs(); err != nil { + return err + } + + paths := getPaths() + for _, p := range paths { + hostPath := filepath.Join("/host", p) + logrus.Infof("trying to delete path: %s", hostPath) + _, err := os.Stat(hostPath) + if err != nil { + if os.IsNotExist(err) { + logrus.Infof("path does not exist: %s", hostPath) + continue + } + return err + } + + err = os.RemoveAll(hostPath) + if err != nil { + return err + } + } + + return nil +} + +func umountTmpfs() error { + // umount tmpfs kubelet stuffs + tmpfs, err := exec.Command( + "sh", "-c", "mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }'").Output() + if err != nil { + return err + } + + for _, t := range strings.Split(strings.TrimSpace(string(tmpfs)), "\n") { + t = strings.TrimSpace(t) + if t == "" { + continue + } + + logrus.Infof("trying to umount tmpfs: %s", t) + _, err := exec.Command("sh", "-c", fmt.Sprintf("umount %s", t)).Output() + if err != nil { + return fmt.Errorf("error trying to umount tmpfs %s: %s", t, err) + } + logrus.Infof("umount of tmpfs %s successful", t) + } + + return nil +} + +func getAgentImage() string { + agentImage := os.Getenv("AGENT_IMAGE") + if agentImage == "" { + agentImage = "rancher/rancher-agent:master" + } + return agentImage +} + +func docker(ctx context.Context, c *client.Client) error { + blankArgs := filters.NewArgs() + if _, err := c.ContainersPrune(ctx, blankArgs); err != nil { + return err + } + if _, err := c.VolumesPrune(ctx, blankArgs); err != nil { + return err + } + if _, err := c.ImagesPrune(ctx, blankArgs); err != nil { + return err + } + if _, err := c.NetworksPrune(ctx, blankArgs); err != nil { + return err + } + + return nil +} + +func getPrefixPath() string { + return os.Getenv("PREFIX_PATH") +} + +func containers(ctx context.Context, c *client.Client) error { + containers, err := c.ContainerList(ctx, types.ContainerListOptions{}) + if err != nil { + return err + } + + for _, container := range containers { + isCleanup := false + for _, n := range container.Names { + if strings.HasPrefix(n, "/"+NodeCleanupContainerName) { + isCleanup = true + break + } + } + + if isCleanup { + continue // don't stop the cleanup container! + } + + config, err := c.ContainerInspect(ctx, container.ID) + if err != nil { + return err + } + if strings.HasPrefix(config.Config.Image, "rancher/") { + if err := c.ContainerKill(ctx, config.ID, "SIGKILL"); err != nil { + return err + } + } + } + + return nil +} + +func waitForK8sPods(ctx context.Context, c *client.Client) error { + // wait for up to 5min for k8s pods to be dropped + for i := 0; i < 30; i++ { + logrus.Infof("checking for pods %d out of 30 times", i) + containerList, err := c.ContainerList(ctx, types.ContainerListOptions{}) + if err != nil { + return err + } + + hasPods := false + for _, c := range containerList { + for _, n := range c.Names { + if strings.HasPrefix(n, "/k8s_") { + hasPods = true + continue + } + } + if hasPods { + continue //break out if you already found one + } + } + + if hasPods { + logrus.Info("pods found, waiting 10s and trying again") + time.Sleep(10 * time.Second) + continue + } + + logrus.Info("all pods cleaned, continuing on to more rke cleanup") + return nil + } + + return nil +} + +func firewall() error { + // save docker rules + if _, err := exec.Command("sh", "-c", + "iptables-save -t filter | egrep -w \"COMMIT|DOCKER|docker0|\\*filter\" > filter.txt").Output(); err != nil { + return err + } + + if _, err := exec.Command("sh", "-c", + "iptables-save -t nat | egrep -w \"COMMIT|DOCKER|docker0|\\*nat\" > nat.txt").Output(); err != nil { + return err + } + + ipt, err := iptables.New() + if err != nil { + return err + } + + for _, table := range []string{"nat", "mangle"} { + logrus.Infof("clearing and deleting iptables table: %s", table) + if err := ipt.ClearAndDeleteChain(table, ""); err != nil { + return err + } + } + + if err := ipt.ClearAll(); err != nil { + return err + } + if err := ipt.DeleteAll(); err != nil { + return err + } + + if _, err := exec.Command("sh", "-c", + "iptables-restore filter.txt").Output(); err != nil { + return fmt.Errorf("error putting back filter table: %s", err) + } + + if _, err := exec.Command("sh", "-c", + "iptables-restore nat.txt").Output(); err != nil { + return fmt.Errorf("error putting back nat table: %s", err) + } + + return nil +} + +func getPaths() []string { + pathPrefix := getPrefixPath() + + // all paths on the hosts to rm -rf + return []string{ + hosts.ToCleanCNIConf, hosts.ToCleanCNIBin, + "/opt/rke", "/run/secrets/kubernetes.io", + "/run/calico", "/run/flannel", "/var/log/containers", "/var/log/pods", + hosts.ToCleanCalicoRun, + path.Join(pathPrefix, hosts.ToCleanSSLDir), + path.Join(pathPrefix, hosts.ToCleanTempCertPath), + path.Join(pathPrefix, hosts.ToCleanEtcdDir), + path.Join(pathPrefix, hosts.ToCleanCNILib), + path.Join(pathPrefix, "/var/lib/kubelet"), + path.Join(pathPrefix, "/var/lib/calico"), + path.Join(pathPrefix, "/var/lib/weave"), + path.Join(pathPrefix, "/etc/ceph"), + } +} + +func usage() string { + return `agent clean usage for linux: +Using the clean commands can be run directly from the agent with proper flags, to clean everything you can run the following: + +docker run --privileged --network host -v /:/host -v /var/run/docker.sock:/var/run/docker.sock rancher/rancher-agent:master -- agent clean node + +The above mounts and grants access to everything the node cleaner will need to complete +Note: If your cluster was created with a prefixPath use the env param -e PREFIX_PATH=/my/prefix + +Running individual cleanup sub commands +docker run --privileged -v /:/host rancher/rancher-agent:master -- agent clean paths + +commands: + node - cleans the entire node and performs all actions below and is the default command, requires docker socket to clean up dockerd + links - clean the interface links created on the host, requires --privileged and --network host + paths - clean the paths added by the host like /etc/rancher, /var/lib/rancher, etc. requires -v /:/host + firewall - clean the iptables firewall rules, needs --privileged and --network host to work + script - prints a bash script you can run to clean up the node from the cli + help - print this help message + +other commands for automation: + job - used by the k8s batch job to start the ` + NodeCleanupContainerName + ` container to watch kubelet cleanup and wait to clean the node +` +} + +func script() string { + return `#!/bin/bash + +# Directories to cleanup +CLEANUP_DIRS=(/etc/ceph /etc/cni /etc/kubernetes /opt/cni /opt/rke /run/secrets/kubernetes.io /run/calico /run/flannel /var/lib/calico /var/lib/weave /var/lib/etcd /var/lib/cni /var/lib/kubelet/* /var/lib/rancher/rke/log /var/log/containers /var/log/pods /var/run/calico) + +# Interfaces to cleanup +CLEANUP_INTERFACES=(flannel.1 cni0 tunl0 weave datapath vxlan-6784) + +run() { + + CONTAINERS=$(docker ps -qa) + if [[ -n ${CONTAINERS} ]] + then + cleanup-containers + else + techo "No containers exist, skipping container cleanup..." + fi + cleanup-dirs + cleanup-interfaces + VOLUMES=$(docker volume ls -q) + if [[ -n ${VOLUMES} ]] + then + cleanup-volumes + else + techo "No volumes exist, skipping container volume cleanup..." + fi + if [[ ${CLEANUP_IMAGES} -eq 1 ]] + then + IMAGES=$(docker images -q) + if [[ -n ${IMAGES} ]] + then + cleanup-images + else + techo "No images exist, skipping container image cleanup..." + fi + fi + if [[ ${FLUSH_IPTABLES} -eq 1 ]] + then + flush-iptables + fi + techo "Done!" + +} + +cleanup-containers() { + + techo "Removing containers..." + docker rm -f $(docker ps -qa) + +} + +cleanup-dirs() { + + techo "Unmounting filesystems..." + for mount in $(mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }') + do + umount $mount + done + + techo "Removing directories..." + for DIR in "${CLEANUP_DIRS[@]}" + do + techo "Removing $DIR" + rm -rf $DIR + done + +} + +cleanup-images() { + + techo "Removing images..." + docker rmi -f $(docker images -q) + +} + +cleanup-interfaces() { + + techo "Removing interfaces..." + for INTERFACE in "${CLEANUP_INTERFACES[@]}" + do + if $(ip link show ${INTERFACE} > /dev/null 2>&1) + then + techo "Removing $INTERFACE" + ip link delete $INTERFACE + fi + done + +} + +cleanup-volumes() { + + techo "Removing volumes..." + docker volume rm $(docker volume ls -q) + +} + +flush-iptables() { + + techo "Flushing iptables..." + iptables -F -t nat + iptables -X -t nat + iptables -F -t mangle + iptables -X -t mangle + iptables -F + iptables -X + techo "Restarting Docker..." + if systemctl list-units --full -all | grep -q docker.service + then + systemctl restart docker + else + /etc/init.d/docker restart + fi + +} + +help() { + + echo "Rancher 2.x extended cleanup + Usage: bash extended-cleanup-rancher2.sh [ -f -i ] + + All flags are optional + + -f | --flush-iptables Flush all iptables rules (includes a Docker restart) + -i | --flush-images Cleanup all container images + -h This help menu + + !! Warning, this script removes containers and all data specific to Kubernetes and Rancher + !! Backup data as needed before running this script, and use at your own risk." + +} + +timestamp() { + + date "+%Y-%m-%d %H:%M:%S" + +} + +techo() { + + echo "$(timestamp): $*" + +} + +# Check if we're running as root. +if [[ $EUID -ne 0 ]] + then + techo "This script must be run as root" + exit 1 +fi + +while test $# -gt 0 + do + case ${1} in + -f|--flush-iptables) + shift + FLUSH_IPTABLES=1 + ;; + -i|--flush-images) + shift + CLEANUP_IMAGES=1 + ;; + h) + help && exit 0 + ;; + *) + help && exit 0 + esac +done + +# Run the cleanup +run +` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_windows.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_windows.go new file mode 100644 index 0000000..e02c1e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/node_windows.go @@ -0,0 +1,625 @@ +package clean + +import ( + "context" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "github.com/sirupsen/logrus" +) + +const ( + DockerPipe = "\\\\.\\pipe\\docker_engine" + WinsPipe = "\\\\.\\pipe\\rancher_wins" + HostMount = "c:\\host\\" +) + +func Run(ctx context.Context, args []string) error { + if len(args) > 3 { + fmt.Println(usage()) + return nil + } + + if len(args) == 3 { + switch args[2] { + case "job": + return job(ctx) + case "node": + return node(ctx) + case "script", "scripts": + fmt.Print(script()) + return nil + case "help": + fmt.Println(usage()) + return nil + default: + fmt.Println(usage()) + return nil + } + } + + fmt.Println(usage()) + return nil +} + +func job(ctx context.Context) error { + logrus.Infof("Starting clean container job: %s", NodeCleanupContainerName) + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + containerList, err := c.ContainerList(ctx, types.ContainerListOptions{}) + if err != nil { + return err + } + + for _, c := range containerList { + for _, n := range c.Names { + if n == "/"+NodeCleanupContainerName { + logrus.Infof("container named %s already exists, exiting.", NodeCleanupContainerName) + return nil + } + } + } + + binds := []string{ + fmt.Sprintf("%s:%s", DockerPipe, DockerPipe), + fmt.Sprintf("%s:%s", WinsPipe, WinsPipe), + fmt.Sprintf("%s:%s", "c:\\", HostMount), + } + + container, err := c.ContainerCreate(ctx, &container.Config{ + Image: getAgentImage(), + Env: []string{ + fmt.Sprintf("%s=%s", AgentImage, getAgentImage()), + fmt.Sprintf("%s=%s", PrefixPath, os.Getenv(PrefixPath)), + fmt.Sprintf("%s=%s", WindowsPrefixPath, os.Getenv(WindowsPrefixPath)), + }, + Cmd: []string{"--", "agent", "clean", "node"}, + }, &container.HostConfig{ + Binds: binds, + }, nil, nil, NodeCleanupContainerName) + + if err != nil { + return err + } + + return c.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}) +} + +func node(ctx context.Context) error { + logrus.Info("Cleaning up node...") + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + if err := waitForK8sPods(ctx, c); err != nil { + return fmt.Errorf("error waiting for k8s pods to be removed: %s", err) + } + + return spawnCleanup() +} + +func spawnCleanup() error { + if err := writeScript(); err != nil { + return err + } + winsArgs := createWinsArgs("Spawn") + output, err := exec.Command("wins.exe", winsArgs...).Output() + if err != nil { + logrus.Infof(string(output)) + return err + } + return nil +} + +func writeScript() error { + // add a null file to the container for wins to find and make a hash + psPath := getPowershellPath() + if !fileExists(psPath) { + psHostPath := strings.Replace(psPath, "c:\\", HostMount, 1) + + src, err := os.Open(psHostPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.Create(psPath) + if err != nil { + return err + } + defer dst.Close() + + if _, err := io.Copy(dst, src); err != nil { + return err + } + } else { + logrus.Infof("powershell.exe already exists: %s", psPath) + } + + // write one to the host for wins cli to call + scriptBytes := []byte(script()) + hostScriptPath := strings.Replace(getScriptPath(), "c:\\", HostMount, 1) + if !fileExists(hostScriptPath) { + logrus.Infof("writing file to host: %s", hostScriptPath) + if err := ioutil.WriteFile(hostScriptPath, scriptBytes, 0777); err != nil { + return fmt.Errorf("error writing the cleanup script to the host: %s", err) + } + } else { + logrus.Infof("cleanup script already exists on host: %s", hostScriptPath) + } + + return nil +} + +func fileExists(path string) bool { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +func getAgentImage() string { + agentImage := os.Getenv(AgentImage) + if agentImage == "" { + agentImage = "rancher/rancher-agent:master" + } + return agentImage +} + +func waitForK8sPods(ctx context.Context, c *client.Client) error { + // wait for up to 5min for k8s pods to be dropped + for i := 0; i < 30; i++ { + logrus.Infof("checking for pods %d out of 30 times", i) + containerList, err := c.ContainerList(ctx, types.ContainerListOptions{}) + if err != nil { + return err + } + + hasPods := false + for _, c := range containerList { + for _, n := range c.Names { + if strings.HasPrefix(n, "/k8s_") { + hasPods = true + continue + } + } + if hasPods { + continue //break out if you already found one + } + } + + if hasPods { + logrus.Info("pods found, waiting 10s and trying again") + time.Sleep(10 * time.Second) + continue + } + + logrus.Info("all pods cleaned, continuing on to more rke cleanup") + return nil + } + + return nil +} + +func createWinsArgs(tasks ...string) []string { + args := fmt.Sprintf("-File %s", getScriptPath()) + if len(tasks) > 0 { + args = fmt.Sprintf("%s -Tasks %s", args, strings.Join(tasks, ",")) + } + + path := getPowershellPath() + logrus.Infof("path: %s, args: %s", path, args) + + return []string{ + "cli", "prc", "run", + "--path", path, + "--args", args, + } +} + +func getPrefixPath() string { + prefix := os.Getenv(WindowsPrefixPath) + if prefix == "" { + prefix = "c:\\" + } + return prefix +} + +func getScriptPath() string { + return filepath.Join(getPrefixPath(), "etc", "rancher", "cleanup.ps1") +} + +func getPowershellPath() string { + return filepath.Join(getPrefixPath(), "etc", "rancher", "powershell.exe") +} + +func usage() string { + return `agent clean usage for windows: +Windows is hard to cleanup from a container and it is recommended to clean a node that you pull the included PowerShell +script out of the container and run it locally as administrator. Read the top of the file for usage of the -Tasks argument +if you only want to clean pieces of the node. + +You can clean an entire node with this one line command: +docker run rancher/rancher-agent:master -- agent clean script > cleanup.ps1; ./cleanup.ps1 + +Note: If your cluster was created with a prefixPath use the env param -e WINDOWS_PREFIX_PATH=c:\my\prefix + +commands: + script - prints a PowerShell script you can run to clean the node + help - print this help message + +other commands for automation + node - cleans the entire node, requires volume and named pipes mounted and is best run via automation + job - used by the k8s batch job to start the ` + NodeCleanupContainerName + ` container to watch kubelet cleanup and wait to clean the node +` +} + +func script() string { + return `#Requires -RunAsAdministrator +<# +.SYNOPSIS + Cleans Rancher managed Windows Worker Nodes. Backup your data. Use at your own risk. +.DESCRIPTION + Run the script to clean the windows host of all Rancher related data (kubernetes, docker, network) +.NOTES + This script needs to be run with Elevated permissions to allow for the complete collection of information. + Backup your data. + Use at your own risk. +.EXAMPLE + cleanup.ps1 + Clean the windows host of all Rancher related data (kubernetes, docker, network). + + cleanup.ps1 -Tasks Docker + Cleans the windows host of all Rancher docker related data. + + cleanup.ps1 -Tasks Docker,Network + Cleans the windows host of all Rancher docker and network related data. +#> +[CmdletBinding()] +param ( + [Parameter()] + [ValidateSet("Docker", "Kubernetes", "Firewall", "Rancher", "Network", "Paths", "Spawn", "Logs")] + [string[]] + $Tasks = ("Docker", "Kubernetes", "Rancher", "Firewall", , "Network", "Paths") +) + +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +function Test-Command($cmdname) { + return [bool](Get-Command -Name $cmdname -ErrorAction SilentlyContinue) +} + +# Write-EventLog for when run via automation, Write-Host when running by hand. +function Log-Info { + Write-EventLog -LogName "Application" -Source ` + NodeCleanupContainerName + ` -EventID 999 -EntryType Information -Message $($args -join " ") + Write-Host -NoNewline -ForegroundColor Blue "INFO: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Warn { + Write-EventLog -LogName "Application" -Source ` + NodeCleanupContainerName + ` -EventID 999 -EntryType Warning -Message $($args -join " ") + Write-Host -NoNewline -ForegroundColor DarkYellow "WARN: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Error { + Write-EventLog -LogName "Application" -Source ` + NodeCleanupContainerName + ` -EventID 999 -EntryType Error -Message $($args -join " ") + Write-Host -NoNewline -ForegroundColor DarkRed "ERRO: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Fatal { + Write-EventLog -LogName "Application" -Source ` + NodeCleanupContainerName + ` -EventID 999 -EntryType Error -Message $($args -join " ") + Write-Host -NoNewline -ForegroundColor DarkRed "FATA: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) + exit 255 +} + +function Get-VmComputeNativeMethods() { + $ret = 'VmCompute.PrivatePInvoke.NativeMethods' -as [type] + if (-not $ret) { + $signature = @' +[DllImport("vmcompute.dll")] +public static extern void HNSCall([MarshalAs(UnmanagedType.LPWStr)] string method, [MarshalAs(UnmanagedType.LPWStr)] string path, [MarshalAs(UnmanagedType.LPWStr)] string request, [MarshalAs(UnmanagedType.LPWStr)] out string response); +'@ + $ret = Add-Type -MemberDefinition $signature -Namespace VmCompute.PrivatePInvoke -Name "NativeMethods" -PassThru + } + return $ret +} + +function Invoke-HNSRequest { + param + ( + [ValidateSet('GET', 'DELETE')] + [parameter(Mandatory = $true)] [string] $Method, + [ValidateSet('networks', 'endpoints', 'activities', 'policylists', 'endpointstats', 'plugins')] + [parameter(Mandatory = $true)] [string] $Type, + [parameter(Mandatory = $false)] [string] $Action, + [parameter(Mandatory = $false)] [string] $Data = "", + [parameter(Mandatory = $false)] [Guid] $Id = [Guid]::Empty + ) + $hnsPath = "/$Type" + if ($id -ne [Guid]::Empty) { + $hnsPath += "/$id" + } + if ($Action) { + $hnsPath += "/$Action" + } + $response = "" + $hnsApi = Get-VmComputeNativeMethods + $hnsApi::HNSCall($Method, $hnsPath, "$Data", [ref]$response) + $output = @() + if ($response) { + try { + $output = ($response | ConvertFrom-Json) + if ($output.Error) { + Log-Error $output; + } + else { + $output = $output.Output; + } + } + catch { + Log-Error $_.Exception.Message + } + } + return $output; +} + +function Remove-DockerContainers { + $containers = $(docker.exe ps -aq) + if ($containers) { + Log-Info "Cleaning up docker containers ..." + $errMsg = $($containers | ForEach-Object { docker.exe rm -f $_ }) + if (-not $?) { + Log-Warn "Could not remove docker containers: $errMsg" + } + # wait a while for rancher-wins to clean up processes + Start-Sleep -Seconds 10 + } +} + +function Remove-Kubernetes { + Get-Process -ErrorAction Ignore -Name "rancher-wins-*" | ForEach-Object { + Log-Info "Stopping process $($_.Name) ..." + $_ | Stop-Process -ErrorAction Ignore -Force + } +} + +function Remove-FirewallRules { + Get-NetFirewallRule -PolicyStore ActiveStore -Name "rancher-wins-*" -ErrorAction Ignore | ForEach-Object { + Log-Info "Cleaning up firewall rule $($_.Name) ..." + $_ | Remove-NetFirewallRule -ErrorAction Ignore | Out-Null + } +} + +function Remove-RancherWins { + $service = Get-Service -Name "rancher-wins" -ErrorAction Ignore + if ($service.Status -eq "Running") { + Stop-Service $service.Name + } + + Push-Location c:\etc\rancher + $errMsg = $(.\wins.exe srv app run --unregister) + if (-not $?) { + Log-Warn "Could not unregister: $errMsg" + } + Pop-Location +} + +function Remove-Links { + try { + # Removed the NAT as it isn't in the other one. + Get-HnsNetwork | Where-Object { $_.Name -eq 'vxlan0' -or $_.Name -eq 'cbr0'} | Select-Object Name, ID | ForEach-Object { + Log-Info "Cleaning up HnsNetwork $($_.Name) ..." + hnsdiag delete networks ($_.ID) + } + Invoke-HNSRequest -Method "GET" -Type "policylists" | Where-Object { -not [string]::IsNullOrEmpty($_.Id) } | ForEach-Object { + Log-Info "Cleaning up HNSPolicyList $($_.Id) ..." + Invoke-HNSRequest -Method "DELETE" -Type "policylists" -Id $_.Id + } + ## This one doesn't exist in the previous version either. So we may try with NAT added and this removed. + Get-HnsEndpoint | Select-Object Name, ID | ForEach-Object { + Log-Info "Cleaning up HnsEndpoint $($_.Name) ..." + hnsdiag delete endpoints ($_.ID) + } + } + catch { + Log-Warn "Could not clean: $($_.Exception.Message)" + } +} + +function Remove-Paths { + [CmdletBinding()] + param ( + [Parameter(Mandatory, ValueFromPipeline)] + [string] + $HostPathPrefix + ) + PROCESS { + $runPath = Join-Path $HostPathPrefix "run" + $optPath = Join-Path $HostPathPrefix "opt" + $varPath = Join-Path $HostPathPrefix "var" + $etcPath = Join-Path $HostPathPrefix "etc" + + for ($num = 0; $num -lt 5; $num++){ + $sleep = $false + + Get-Item -ErrorAction Ignore -Path @( + "$runPath\*" + "$optPath\*" + "$varPath\*" + "$etcPath\*" + "c:\ProgramData\docker\containers\*" + ) | ForEach-Object { + Log-Info "Cleaning up data $($_.FullName) ..." + try { + $_ | Remove-Item -ErrorAction Ignore -Recurse -Force + } + catch { + Log-Warn "Could not clean: $($_.Exception.Message)" + $sleep = $true + } + } + + try { + Log-Info "Cleaning up $runPath" + Remove-Item -Path $runPath -ErrorAction Ignore -Recurse -Force + } catch { + $sleep = $true + } + + try { + Log-Info "Cleaning up $optPath" + Remove-Item -Path $optPath -ErrorAction Ignore -Recurse -Force + } catch { + $sleep = $true + } + + try { + Log-Info "Cleaning up $varPath" + Remove-Item -Path $varPath -ErrorAction Ignore -Recurse -Force + } catch { + $sleep = $true + } + + try { + Log-Info "Cleaning up $etcPath" + Remove-Item -Path $etcPath -ErrorAction Ignore -Recurse -Force + } catch { + $sleep = $true + } + + if ($sleep -eq $false) { + break # No Remove-Item's were caught, we can move on + } + + Sleep 5 # Sleep and try again + } + + try { + Log-Info "Restarting the Docker service" + Stop-Service docker + Start-Sleep -Seconds 5 + Start-Service docker + } + catch { + Log-Fatal "Could not restart docker: $($_.Exception.Message)" + } + } +} + +function Get-PrefixPath { + $passedPrefixPath = "` + getPrefixPath() + `" + if ([string]::IsNullOrEmpty($passedPrefixPath) -eq $false) { + return $passedPrefixPath # cluster has a path prefix + } + Log-Info "Getting Windows prefix path" + $rkeDefaultPrefix = "c:\" + $dockerStatus = (docker info) | Out-Null + try { + $hostPrefixPath = (docker exec kubelet pwsh -c 'Get-ChildItem env:' 2>&1 | findstr RKE_NODE_PREFIX_PATH).Trim("RKE_NODE_PREFIX_PATH").Trim(" ") + + if ($dockerstatus.ExitCode -ne 0 -and !$hostPrefixPath) { + $hostPrefixPath = $rkeDefaultPrefix + } + elseif ($hostPrefixPath) { + if ($rkeDefaultPrefix -ine $hostPrefixPath) { + $hostPrefixPath = $hostPrefixPath -Replace "/", "\" + if ($hostPrefixPath.Chars($hostPrefixPath.Length - 1) -ne '\') { + $hostPrefixPath = $( $hostPrefixPath + '\' ) + } + } + } + return $hostPrefixPath + } + catch { + Log-Warn "Unable to find the host prefix path, it has been set to the default: 'c:\'" + } + + return $rkeDefaultPrefix +} + +function Spawn { + Log-Info "Spawning script $PSCommandPath with default tasks to clean node" + Start-Process -FilePath "powershell" -NoNewWindow -ArgumentList @("-ExecutionPolicy", "Bypass", "-File", $PSCommandPath) +} + +function Logs { + Get-EventLog -AppName Application -Source ` + NodeCleanupContainerName + ` -Newest 1000 +} + +# cleanup + +if ([System.Diagnostics.EventLog]::SourceExists("` + NodeCleanupContainerName + `") -eq $false) { + New-EventLog -LogName Application -Source ` + NodeCleanupContainerName + ` +} +Log-Info "Start cleaning ..." + +foreach ($task in $Tasks) { + switch ($task) { + "Docker" { + # clean up docker container: docker rm -fv $(docker ps -qa) + Remove-DockerContainers + } + "Kubernetes" { + # clean up kubernetes components processes + Remove-Kubernetes + } + "Firewall" { + # clean up firewall rules + Remove-FirewallRules + } + "Network" { + # clean up links + Remove-Links + } + "Rancher" { + # clean up rancher-wins service + Remove-RancherWins + } + "Paths" { + # clean up data + Get-PrefixPath | Remove-Paths + } + "Spawn" { + # spawn this script with default tasks to clean everything + Spawn + } + "Logs" { + # spawn this script with default tasks to clean everything + Logs + } + } +} + +Log-Info "Finished!" +if ([System.Diagnostics.EventLog]::SourceExists("` + NodeCleanupContainerName + `") -eq $true) { + Remove-EventLog -Source ` + NodeCleanupContainerName + ` +} + +` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings.go new file mode 100644 index 0000000..598fd76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings.go @@ -0,0 +1,232 @@ +//go:build !windows +// +build !windows + +/* +Clean orphaned bindings found in a cluster namespaces. This will look for orphaned RoleBinding resources +in cluster namespaces and subsequently delete any that are found. +*/ + +package clean + +import ( + "context" + "errors" + "os" + + "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/rancher/pkg/controllers/management/auth/globalroles" + mgmt "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + rbaccommon "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" + corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/ratelimit" + "github.com/rancher/wrangler/v3/pkg/start" + "github.com/sirupsen/logrus" + k8srbacv1 "k8s.io/api/rbac/v1" + rbacv1 "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +const ( + orphanBindingsOperation = "clean-orphan-bindings" + orphanCatalogBindingsOperation = "clean-catalog-orphan-bindings" +) + +type orphanBindingsCleanup struct { + namespaces corev1.NamespaceController + crtbs v3.ClusterRoleTemplateBindingClient + prtbs v3.ProjectRoleTemplateBindingClient + prtbHashes map[string]struct{} + prtbUIDs map[string]struct{} + roleBindings v1.RoleBindingClient + roles v1.RoleClient +} + +func OrphanBindings(clientConfig *rest.Config) error { + bc, err := newOrphanBindingsCleanup(clientConfig) + if err != nil { + return err + } + + logrus.Infof("[%v] cleaning up orphaned bindings", orphanBindingsOperation) + return bc.cleanOrphans(dryRun) +} + +func OrphanCatalogBindings(clientConfig *rest.Config) error { + bc, err := newOrphanBindingsCleanup(clientConfig) + if err != nil { + return err + } + logrus.Infof("[%v] cleaning up orphaned catalog bindings", orphanCatalogBindingsOperation) + return bc.cleanOrphanedCatalogRolesAndRolebindings() +} + +func newOrphanBindingsCleanup(restConfig *rest.Config) (*orphanBindingsCleanup, error) { + if os.Getenv("DRY_RUN") == "true" { + logrus.Infof("[%v] DRY_RUN is true, no objects will be deleted/modified", orphanBindingsOperation) + dryRun = true + } + + var config *rest.Config + var err error + if restConfig != nil { + config = restConfig + } else { + config, err = clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG")) + if err != nil { + logrus.Errorf("[%v] Error in building the cluster config %v", orphanBindingsOperation, err) + return nil, err + } + } + config.RateLimiter = ratelimit.None + + k8srbac, err := rbac.NewFactoryFromConfig(config) + if err != nil { + return nil, err + } + + rancherManagement, err := mgmt.NewFactoryFromConfig(config) + if err != nil { + return nil, err + } + + k8score, err := core.NewFactoryFromConfig(config) + if err != nil { + return nil, err + } + + ctx := context.Background() + starters := []start.Starter{rancherManagement, k8srbac, k8score} + if err := start.All(ctx, 5, starters...); err != nil { + return nil, err + } + bc := orphanBindingsCleanup{ + namespaces: k8score.Core().V1().Namespace(), + prtbs: rancherManagement.Management().V3().ProjectRoleTemplateBinding(), + prtbUIDs: make(map[string]struct{}), + prtbHashes: make(map[string]struct{}), + roleBindings: k8srbac.Rbac().V1().RoleBinding(), + roles: k8srbac.Rbac().V1().Role(), + } + return &bc, nil +} + +// cleanOrphans finds and deletes orphaned bindings +func (bc *orphanBindingsCleanup) cleanOrphans(dryRun bool) error { + prtbs, err := bc.prtbs.List("", metav1.ListOptions{}) + if err != nil { + return err + } + for i := range prtbs.Items { + prtb := prtbs.Items[i] + // Build a set of hashed (shortened) PRTB names (that include namespace). + if hash := rbaccommon.GetRTBLabel(prtb.ObjectMeta); hash != "" { + bc.prtbHashes[hash] = struct{}{} + } + // Build a PRTB UID set for checking for existence of role binding owner in legacy label case. + if uid := string(prtb.UID); uid != "" { + bc.prtbUIDs[uid] = struct{}{} + } + } + + logrus.Infof("[%v] checking for orphaned rolebindings", orphanBindingsOperation) + + // check all rolebindings against orphan criteria + rbs, err := bc.roleBindings.List("", metav1.ListOptions{}) + if err != nil { + return err + } + + var returnErr error + for _, rb := range rbs.Items { + if bc.isOrphanBinding(&rb) { + logrus.Infof("[%v] found orphaned binding: %s/%s", orphanBindingsOperation, rb.Namespace, rb.Name) + if dryRun { + logrus.Infof("[%v] dryRun is enabled, skipping deletion for orphaned binding: %s/%s", orphanBindingsOperation, rb.Namespace, rb.Name) + continue + } + logrus.Infof("[%v] deleting orphaned binding: %s/%s", orphanBindingsOperation, rb.Namespace, rb.Name) + err := bc.roleBindings.Delete(rb.Namespace, rb.Name, &metav1.DeleteOptions{}) + if err != nil && !k8serrors.IsNotFound(err) { + returnErr = errors.Join(returnErr, err) + } + } + } + + return returnErr +} + +// isOrphanBinding detects whether a role binding is orphaned. Only bindings with a Group subject may be orphans. +// To detect orphans, we look at labels with value == PrtbInClusterBindingOwner. If the key for this label is a UID, +// then it is considered to be legacy as the format for the key on this label was changed with 2.5. If the label's key is of the +// form _ then label is considered to be new (post 2.5.0). If we find a binding with a legacy label and not a new label, we check if there is an +// existing prtb with that uid. If there is not, then the binding is an orphan. If a new label exists on the binding, then we check if the parent +// prtb exists. If it does not exist, the binding is an orphan. +func (bc *orphanBindingsCleanup) isOrphanBinding(rb *rbacv1.RoleBinding) bool { + if rb == nil { + return false + } + var hasGroupSubject bool + if len(rb.Subjects) == 1 && rb.Subjects[0].Kind == k8srbacv1.GroupKind { + hasGroupSubject = true + } + if !hasGroupSubject { + return false + } + + var isOrphan bool + for k, v := range rb.Labels { + if v != auth.PrtbInClusterBindingOwner { + continue + } + _, isHashLabel := bc.prtbHashes[k] + _, isUIDLabel := bc.prtbUIDs[k] + // If the binding isn't related to a current label by UID or hash, it is orphaned. + isOrphan = !isHashLabel && !isUIDLabel + } + return isOrphan +} + +// Removes a specific role and bindings to that role, which are no longer valid, from the cattle-global-data namespace +func (bc *orphanBindingsCleanup) cleanOrphanedCatalogRolesAndRolebindings() error { + rbs, err := bc.roleBindings.List(namespace.GlobalNamespace, metav1.ListOptions{}) + if err != nil { + return err + } + logrus.Infof("[%v] Processing %d rolebindings", orphanCatalogBindingsOperation, len(rbs.Items)) + for _, rb := range rbs.Items { + if rb.RoleRef.Name != globalroles.GlobalCatalogRole { + continue + } + + if dryRun { + logrus.Infof("[%v] dryRun is enabled, skipping deletion for orphaned binding: %s/%s", orphanCatalogBindingsOperation, rb.Namespace, rb.Name) + continue + } + logrus.Infof("[%v] Deleting orphaned binding %s", orphanCatalogBindingsOperation, rb.Name) + err = bc.roleBindings.Delete(namespace.GlobalNamespace, rb.Name, &metav1.DeleteOptions{}) + if err != nil { + logrus.Warnf("[%v] Error when deleting rolebinding %s, %s", orphanCatalogBindingsOperation, rb.Name, err.Error()) + } + } + + if dryRun { + logrus.Infof("[%v] dryRun is enabled, skipping deletion for orphaned role: %s/%s", orphanCatalogBindingsOperation, namespace.GlobalNamespace, globalroles.GlobalCatalogRole) + } else { + logrus.Infof("[%v] Deleting orphaned role %s", orphanCatalogBindingsOperation, globalroles.GlobalCatalogRole) + err = bc.roles.Delete(namespace.GlobalNamespace, globalroles.GlobalCatalogRole, &metav1.DeleteOptions{}) + if err != nil && !k8serrors.IsNotFound(err) { + logrus.Warnf("[%v] Error when deleting role %s, %s", orphanCatalogBindingsOperation, globalroles.GlobalCatalogRole, err.Error()) + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_test.go new file mode 100644 index 0000000..6123896 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_test.go @@ -0,0 +1,522 @@ +package clean + +import ( + "errors" + "reflect" + "strings" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/wrangler/v3/pkg/generic" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +func TestCleanOrphans(t *testing.T) { + t.Parallel() + groupSubjects := []v1.Subject{ + { + Kind: v1.GroupKind, + Name: "Dogs", + }, + } + orphanBindingWithBadOldLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "orphan binding with nonexistent old-style PRTB label", + Labels: map[string]string{ + "ns1-non-existent-uid": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + orphanBindingWithBadNewLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "orphan binding with nonexistent new-style PRTB label", + Labels: map[string]string{ + "unknown_unknown": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + orphanBindingWithHashedLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "orphan binding with a new-style PRTB label that has a hash", + Labels: map[string]string{ + "aaaaaaaaaa_whalewhalewhalewhalewhalewhalewhalewhalewhalew-4076a": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + orphanBindingWithStrangeLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "orphan binding with a new-style PRTB label that has a long namespace name", + Labels: map[string]string{ + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb-8k9i4": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + nonOrphanBindingUnrelatedToPRTB := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan binding that is unrelated to any project role template bindings", + Labels: map[string]string{ + "default-8k9i4": "hello", + }, + }, + Subjects: groupSubjects, + } + nonOrphanBindingWithStrangeLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan binding with a new-style PRTB label that has a long namespace name", + Labels: map[string]string{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-37a42": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + nonOrphanBindingWithSimpleLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan binding with hashed simple label", + Labels: map[string]string{ + "default_foo": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + nonOrphanBindingWithHashedLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan binding with hashed label", + Labels: map[string]string{ + "p-kmc2v_grouplonglonglonglonglonglonglonglonglonglonglong-a59f5": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + nonOrphanBindingWithUIDLabel := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan binding with UID label", + Labels: map[string]string{ + "c8bcebc8-779d-4fe7-a367-aa80897fc7b1": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + } + nonOrphanUserBinding := v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "non-orphan user binding", + Labels: map[string]string{ + "ns1-non-existent-prtb": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: []v1.Subject{ + { + Kind: v1.UserKind, + Name: "Bob", + }, + }, + } + allBindings := []v1.RoleBinding{ + orphanBindingWithBadOldLabel, + orphanBindingWithBadNewLabel, + orphanBindingWithStrangeLabel, + orphanBindingWithHashedLabel, + nonOrphanBindingUnrelatedToPRTB, + nonOrphanBindingWithStrangeLabel, + nonOrphanBindingWithSimpleLabel, + nonOrphanBindingWithHashedLabel, + nonOrphanBindingWithUIDLabel, + nonOrphanUserBinding, + } + + tests := []struct { + name string + client *orphanBindingsCleanup + remainingRBs []v1.RoleBinding + dryRun bool + wantErr bool + }{ + { + name: "dry run with no bindings deleted", + dryRun: true, + client: newStandardClient(allBindings), + remainingRBs: allBindings, + }, + { + name: "some bindings deleted", + dryRun: false, + client: newStandardClient(allBindings), + remainingRBs: []v1.RoleBinding{ + nonOrphanBindingUnrelatedToPRTB, + nonOrphanBindingWithStrangeLabel, + nonOrphanBindingWithSimpleLabel, + nonOrphanBindingWithHashedLabel, + nonOrphanBindingWithUIDLabel, + nonOrphanUserBinding, + }, + }, + { + name: "failed to list project role template bindings", + wantErr: true, + client: &orphanBindingsCleanup{ + prtbs: &fakePRTBClient{ + bindings: []v3.ProjectRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "bad", + }, + }, + }, + }, + roleBindings: &fakeRoleBindingClient{ + bindings: allBindings, + }, + prtbHashes: make(map[string]struct{}), + prtbUIDs: make(map[string]struct{}), + }, + }, + { + name: "failed to list role bindings", + wantErr: true, + client: &orphanBindingsCleanup{ + prtbs: &fakePRTBClient{ + bindings: []v3.ProjectRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "hello", + }, + }, + }, + }, + roleBindings: &fakeRoleBindingClient{ + bindings: []v1.RoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "bad", + }, + }, + }, + }, + prtbHashes: make(map[string]struct{}), + prtbUIDs: make(map[string]struct{}), + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + err := test.client.cleanOrphans(test.dryRun) + if test.wantErr && err == nil { + t.Error("expected an error, but didn't get it", err) + return + } + if !test.wantErr && err != nil { + t.Errorf("got an unexpected error: %v", err) + return + } + if !test.wantErr { + current, _ := test.client.roleBindings.List("", metav1.ListOptions{}) + if !reflect.DeepEqual(current.Items, test.remainingRBs) { + t.Errorf("\nexpected:\n%s\ngot:\n%s", + strings.Join(getRoleBindingsNames(test.remainingRBs), "\n"), + strings.Join(getRoleBindingsNames(current.Items), "\n")) + } + } + }) + } +} + +func newStandardClient(roleBindings []v1.RoleBinding) *orphanBindingsCleanup { + // Copy the role bindings to avoid unwanted concurrent modification. The slice is shared by multiple fake clients. + rbs := make([]v1.RoleBinding, len(roleBindings)) + for i := range roleBindings { + rbs[i] = roleBindings[i] + } + return &orphanBindingsCleanup{ + prtbs: &fakePRTBClient{bindings: []v3.ProjectRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + UID: "c8bcebc8-779d-4fe7-a367-aa80897fc7b1", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "grouplonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong", + Namespace: "p-kmc2v", + UID: "abc123", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "whale", + Namespace: strings.Repeat("a", 63), + }, + }, + }}, + prtbHashes: make(map[string]struct{}), + prtbUIDs: make(map[string]struct{}), + roleBindings: &fakeRoleBindingClient{ + bindings: rbs, + }, + } +} + +func TestIsOrphanBinding(t *testing.T) { + t.Parallel() + groupSubjects := []v1.Subject{ + { + Kind: v1.GroupKind, + Name: "Dogs", + }, + } + client := orphanBindingsCleanup{ + prtbHashes: map[string]struct{}{ + "p-kmc2v_grouplonglonglonglonglonglonglonglonglonglonglong-a59f5": {}, + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-4c6e1": {}, + "p-kmc2v_c-123xyz": {}, + }, + prtbUIDs: map[string]struct{}{ + "c8bcebc8-779d-4fe7-a367-aa80897fc7b1": {}, + }, + } + + tests := []struct { + name string + binding *v1.RoleBinding + isOrphan bool + }{ + { + name: "nil binding", + binding: nil, + isOrphan: false, + }, + { + name: "no subjects", + binding: &v1.RoleBinding{}, + isOrphan: false, + }, + { + name: "no group subjects", + binding: &v1.RoleBinding{ + Subjects: []v1.Subject{ + { + Kind: v1.UserKind, + Name: "Pug", + }, + }, + }, + isOrphan: false, + }, + { + name: "no matching new label or uid", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "hello": "world", + }, + }, + Subjects: groupSubjects, + }, + isOrphan: false, + }, + { + name: "matching new label", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "p-kmc2v_c-123xyz": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: false, + }, + { + name: "matching new label with hash", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "p-kmc2v_grouplonglonglonglonglonglonglonglonglonglonglong-a59f5": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: false, + }, + { + name: "matching uid", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "c8bcebc8-779d-4fe7-a367-aa80897fc7b1": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: false, + }, + { + name: "matching new label but missing prtb", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "ns1_missing1": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: true, + }, + { + name: "matching uid but it is unknown", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "uid-unknown": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: true, + }, + { + name: "known binding with a very long namespace name", + binding: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-4c6e1": auth.PrtbInClusterBindingOwner, + }, + }, + Subjects: groupSubjects, + }, + isOrphan: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + isOrphan := client.isOrphanBinding(test.binding) + if isOrphan != test.isOrphan { + t.Errorf("expected isOrphan to be %v, but got %v", test.isOrphan, isOrphan) + } + }) + } +} + +type fakeRoleBindingClient struct { + bindings []v1.RoleBinding +} + +func (c *fakeRoleBindingClient) List(_ string, _ metav1.ListOptions) (*v1.RoleBindingList, error) { + var lst v1.RoleBindingList + // Build a new collection to prevent deletion of items during iteration later. + for i := range c.bindings { + if c.bindings[i].Name == "bad" { + return nil, errors.New("failed to list role bindings") + } + lst.Items = append(lst.Items, c.bindings[i]) + } + return &lst, nil +} + +func (c *fakeRoleBindingClient) Delete(_, name string, _ *metav1.DeleteOptions) error { + for i, v := range c.bindings { + if v.Name == name { + c.bindings = append(c.bindings[:i], c.bindings[i+1:]...) + return nil + } + } + return nil +} + +func (c *fakeRoleBindingClient) Create(_ *v1.RoleBinding) (*v1.RoleBinding, error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) Update(_ *v1.RoleBinding) (*v1.RoleBinding, error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) UpdateStatus(_ *v1.RoleBinding) (*v1.RoleBinding, error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) Get(_, _ string, _ metav1.GetOptions) (*v1.RoleBinding, error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) Watch(_ string, _ metav1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) Patch(_, _ string, _ types.PatchType, _ []byte, _ ...string) (result *v1.RoleBinding, err error) { + panic("implement me") +} + +func (c *fakeRoleBindingClient) WithImpersonation(_ rest.ImpersonationConfig) (generic.ClientInterface[*v1.RoleBinding, *v1.RoleBindingList], error) { + panic("implement me") +} + +type fakePRTBClient struct { + bindings []v3.ProjectRoleTemplateBinding +} + +func (c *fakePRTBClient) List(_ string, _ metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { + var lst v3.ProjectRoleTemplateBindingList + for _, b := range c.bindings { + if b.Name == "bad" { + return nil, errors.New("failed to list PRTBs") + } + lst.Items = append(lst.Items, b) + } + return &lst, nil +} + +func (c *fakePRTBClient) Create(_ *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + panic("implement me") +} + +func (c *fakePRTBClient) Update(_ *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + panic("implement me") +} + +func (c *fakePRTBClient) Delete(_, _ string, _ *metav1.DeleteOptions) error { + panic("implement me") +} + +func (c *fakePRTBClient) Get(_, _ string, _ metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { + panic("implement me") +} + +func (c *fakePRTBClient) Watch(_ string, _ metav1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (c *fakePRTBClient) Patch(_, _ string, _ types.PatchType, _ []byte, _ ...string) (result *v3.ProjectRoleTemplateBinding, err error) { + panic("implement me") +} + +func (c *fakePRTBClient) WithImpersonation(_ rest.ImpersonationConfig) (generic.ClientInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList], error) { + panic("implement me") +} + +func (c *fakePRTBClient) UpdateStatus(_ *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + panic("implement me") +} + +func getRoleBindingsNames(bindings []v1.RoleBinding) []string { + names := make([]string, len(bindings)) + for i := range bindings { + names[i] = bindings[i].Name + } + return names +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_windows.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_windows.go new file mode 100644 index 0000000..94ec936 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/clean/orphan_bindings_windows.go @@ -0,0 +1,11 @@ +package clean + +import restclient "k8s.io/client-go/rest" + +func OrphanBindings(clientConfig *restclient.Config) error { + return nil +} + +func OrphanCatalogBindings(clientConfig *restclient.Config) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/cluster/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/cluster/cluster.go new file mode 100644 index 0000000..5d6d4ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/cluster/cluster.go @@ -0,0 +1,126 @@ +package cluster + +import ( + "context" + "encoding/base64" + "fmt" + "io/ioutil" + "os" + "path" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/wrangler/v3/pkg/kubeconfig" + coreV1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +const ( + rancherCredentialsFolder = "/cattle-credentials" + urlFilename = "url" + tokenFilename = "token" + namespaceFilename = "namespace" + + kubernetesServiceHostKey = "KUBERNETES_SERVICE_HOST" + kubernetesServicePortKey = "KUBERNETES_SERVICE_PORT" +) + +func Namespace() (string, error) { + ns, err := readKey(namespaceFilename) + if os.IsNotExist(err) { + return "", nil + } + return ns, err +} + +func TokenAndURL() (string, string, error) { + url, err := readKey(urlFilename) + if err != nil { + return "", "", err + } + token, err := readKey(tokenFilename) + return token, url, err +} + +func CAChecksum() string { + return os.Getenv("CATTLE_CA_CHECKSUM") +} + +func CAStrictVerify() bool { + return strings.ToLower(os.Getenv("STRICT_VERIFY")) == "true" +} + +func getTokenFromAPI() ([]byte, []byte, error) { + cfg, err := kubeconfig.GetNonInteractiveClientConfig("").ClientConfig() + if err != nil { + return nil, nil, err + } + k8s, err := kubernetes.NewForConfig(cfg) + if err != nil { + return nil, nil, err + } + sa, err := k8s.CoreV1().ServiceAccounts(namespace.System).Get(context.Background(), "cattle", metav1.GetOptions{}) + if err != nil { + return nil, nil, fmt.Errorf("failed to find service account %s/%s: %w", namespace.System, "cattle", err) + } + cm, err := k8s.CoreV1().ConfigMaps(namespace.System).Get(context.Background(), "kube-root-ca.crt", metav1.GetOptions{}) + if err != nil { + // kube-root-ca configmap is not created by upstream for k8s <1.20, read from secret as before + if len(sa.Secrets) == 0 { + return nil, nil, fmt.Errorf("no secret exists for service account %s/%s", namespace.System, "cattle") + } + secret, err := k8s.CoreV1().Secrets(namespace.System).Get(context.Background(), sa.Secrets[0].Name, metav1.GetOptions{}) + if err != nil { + return nil, nil, fmt.Errorf("failed to find secret for service account %s/%s: %w", namespace.System, "cattle", err) + } + return secret.Data[coreV1.ServiceAccountRootCAKey], secret.Data[coreV1.ServiceAccountTokenKey], nil + } + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(context.Background(), nil, k8s, sa) + if err != nil { + return nil, nil, fmt.Errorf("failed to ensure secret for service account %s/%s: %w", namespace.System, "cattle", err) + } + return []byte(cm.Data["ca.crt"]), []byte(secret.Data[coreV1.ServiceAccountTokenKey]), nil +} + +func Params() (map[string]interface{}, error) { + caData, token, err := getTokenFromAPI() + if err != nil { + return nil, errors.Wrapf(err, "looking up %s/%s ca/token", namespace.System, "cattle") + } + + kubernetesServiceHost, err := getenv(kubernetesServiceHostKey) + if err != nil { + return nil, err + } + kubernetesServicePort, err := getenv(kubernetesServicePortKey) + if err != nil { + return nil, err + } + + return map[string]interface{}{ + "cluster": map[string]interface{}{ + "address": fmt.Sprintf("%s:%s", kubernetesServiceHost, kubernetesServicePort), + "token": strings.TrimSpace(string(token)), + "caCert": base64.StdEncoding.EncodeToString(caData), + }, + }, nil +} + +func getenv(env string) (string, error) { + value := os.Getenv(env) + if value == "" { + return "", fmt.Errorf("%s is empty", env) + } + return value, nil +} + +func readKey(key string) (string, error) { + bytes, err := ioutil.ReadFile(path.Join(rancherCredentialsFolder, key)) + if err != nil { + return "", err + } + return string(bytes), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/node/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/node/node.go new file mode 100644 index 0000000..4eb307f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/node/node.go @@ -0,0 +1,94 @@ +package node + +import ( + "context" + "os" + "strings" + + "github.com/docker/docker/client" + "github.com/rancher/norman/types/slice" + "github.com/sirupsen/logrus" +) + +func TokenAndURL() (string, string, error) { + return os.Getenv("CATTLE_TOKEN"), os.Getenv("CATTLE_SERVER"), nil +} + +func Params() map[string]interface{} { + labels := parseLabel(os.Getenv("CATTLE_NODE_LABEL")) + taints := split(os.Getenv("CATTLE_NODE_TAINTS")) + roles := split(os.Getenv("CATTLE_ROLE")) + params := map[string]interface{}{ + "customConfig": map[string]interface{}{ + "address": os.Getenv("CATTLE_ADDRESS"), + "internalAddress": os.Getenv("CATTLE_INTERNAL_ADDRESS"), + "roles": split(os.Getenv("CATTLE_ROLE")), + "label": labels, + "taints": taints, + }, + "etcd": slice.ContainsString(roles, "etcd"), + "controlPlane": slice.ContainsString(roles, "controlplane"), + "worker": slice.ContainsString(roles, "worker"), + "requestedHostname": os.Getenv("CATTLE_NODE_NAME"), + } + + dclient, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + logrus.Errorf("Error getting docker client: %v", err) + } else { + defer dclient.Close() + info, err := dclient.Info(context.Background()) + if err != nil { + logrus.Errorf("Error getting docker info: %v", err) + } else { + params["dockerInfo"] = info + } + } + + for k, v := range params { + if m, ok := v.(map[string]string); ok { + for k, v := range m { + logrus.Infof("Option %s=%s", k, v) + } + } else { + logrus.Infof("Option %s=%v", k, v) + } + } + + return map[string]interface{}{ + "node": params, + } +} + +func parseLabel(v string) map[string]string { + labels := map[string]string{} + parts := strings.Split(v, ",") + for _, part := range parts { + if part == "" { + continue + } + kvs := strings.SplitN(part, "=", 2) + if len(kvs) == 2 { + labels[kvs[0]] = kvs[1] + } else if len(kvs) == 1 { + labels[kvs[0]] = "" + } else { + logrus.Warnf("Invalid label format %v.", part) + } + } + return labels +} + +func split(s string) []string { + var result []string + for _, part := range strings.Split(s, ",") { + p := strings.TrimSpace(part) + if p != "" { + result = append(result, p) + } + } + if len(result) == 1 && result[0] == "" { + return nil + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/rancher/rancher.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/rancher/rancher.go new file mode 100644 index 0000000..b36e20f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/agent/rancher/rancher.go @@ -0,0 +1,167 @@ +package rancher + +import ( + "context" + "io/ioutil" + "os" + "sync" + + "github.com/rancher/rancher/pkg/agent/cluster" + "github.com/rancher/rancher/pkg/controllers/managementuser/cavalidator" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/rancher" + "github.com/rancher/wrangler/v3/pkg/apply" + corefactory "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kubeconfig" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" +) + +var ( + started bool +) + +func Run(ctx context.Context) error { + if err := setupSteveAggregation(ctx); err != nil { + return err + } + + if started { + return nil + } + + if !features.MCMAgent.Enabled() { + return nil + } + + cfg, err := kubeconfig.GetNonInteractiveClientConfig("").ClientConfig() + if err != nil { + return err + } + + core, err := corefactory.NewFactoryFromConfig(cfg) + if err != nil { + return err + } + + h := handler{ + ctx: ctx, + serviceCache: core.Core().V1().Service().Cache(), + } + + core.Core().V1().Service().OnChange(ctx, "rancher-installed", h.OnChange) + if err := core.Start(ctx, 1); err != nil { + return err + } + started = true + return nil +} + +type handler struct { + lock sync.Mutex + ctx context.Context + rancherNotFound *bool + serviceCache corecontrollers.ServiceCache +} + +func (h *handler) startRancher() { + clientConfig := kubeconfig.GetNonInteractiveClientConfig("") + server, err := rancher.New(h.ctx, clientConfig, &rancher.Options{ + HTTPListenPort: 80, + HTTPSListenPort: 443, + Features: os.Getenv("CATTLE_FEATURES"), + AddLocal: "true", + ClusterRegistry: os.Getenv("CATTLE_CLUSTER_REGISTRY"), + }) + if err != nil { + logrus.Fatalf("Embedded rancher failed to initialize: %v", err) + } + go func() { + err = server.ListenAndServe(h.ctx) + logrus.Fatalf("Embedded rancher failed to start: %v", err) + }() +} + +func (h *handler) OnChange(key string, service *corev1.Service) (*corev1.Service, error) { + h.lock.Lock() + defer h.lock.Unlock() + if h.rancherNotFound == nil { + _, err := h.serviceCache.Get(namespace.System, "rancher") + if notFound := apierror.IsNotFound(err); notFound { + h.rancherNotFound = ¬Found + h.startRancher() + } else if err != nil { + return nil, err + } else { + h.rancherNotFound = ¬Found + } + } + + if service == nil { + if key == namespace.System+"/rancher" { + logrus.Info("Rancher has been uninstalled, restarting") + os.Exit(0) + } + } else if service.Namespace == namespace.System && service.Name == "rancher" && *h.rancherNotFound { + logrus.Info("Rancher has been installed, restarting") + os.Exit(0) + } + + return service, nil +} + +func setupSteveAggregation(ctx context.Context) error { + c, err := rest.InClusterConfig() + if err != nil { + return err + } + + apply, err := apply.NewForConfig(c) + if err != nil { + return err + } + + token, url, err := cluster.TokenAndURL() + if err != nil { + return err + } + + data := map[string][]byte{ + "CATTLE_SERVER": []byte(url), + "CATTLE_TOKEN": []byte(token), + "CATTLE_CA_CHECKSUM": []byte(cluster.CAChecksum()), + "url": []byte(url + "/v3/connect"), + "token": []byte("stv-cluster-" + token), + } + + ca, err := ioutil.ReadFile("/etc/kubernetes/ssl/certs/serverca") + if os.IsNotExist(err) { + } else if err != nil { + return err + } else { + data["ca.crt"] = ca + } + + if ctx.Value(cavalidator.CacertsValid).(bool) { + data[cavalidator.CacertsValid] = []byte("true") + } else { + data[cavalidator.CacertsValid] = []byte("false") + } + + return apply. + WithDynamicLookup(). + WithSetID("rancher-stv-aggregation"). + WithListerNamespace(namespace.System). + ApplyObjects(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace.System, + Name: "stv-aggregation", + }, + Data: data, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/handler.go new file mode 100644 index 0000000..d51c371 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/handler.go @@ -0,0 +1,388 @@ +package aks + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/gorilla/mux" + "github.com/rancher/aks-operator/pkg/aks" + "github.com/rancher/machine/drivers/azure/azureutil" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/cluster" + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + mgmtSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +const ( + tenantIDAnnotation = "cluster.management.cattle.io/azure-tenant-id" + tenantIDTimestampAnnotation = "cluster.management.cattle.io/azure-tenant-id-created-at" + tenantIDTimeout = time.Hour +) + +type Capabilities struct { + AuthBaseURL string `json:"authBaseUrl"` + BaseURL string `json:"baseUrl"` + TenantID string `json:"tenantId"` + SubscriptionID string `json:"subscriptionId"` + ClientID string `json:"clientId"` + ClientSecret string `json:"clientSecret"` + ResourceLocation string `json:"region"` + Environment string `json:"environment"` + ClusterID string `json:"clusterId"` +} + +// AKS handler lists available resources in Azure API +type handler struct { + schemas *types.Schemas + secretsLister v1.SecretLister + clusterCache mgmtv3.ClusterCache + ac types.AccessControl + secretClient v1.SecretInterface +} + +func NewAKSHandler(scaledContext *config.ScaledContext) http.Handler { + return &handler{ + schemas: scaledContext.Schemas, + secretsLister: scaledContext.Core.Secrets(namespace.GlobalNamespace).Controller().Lister(), + clusterCache: scaledContext.Wrangler.Mgmt.Cluster().Cache(), + ac: scaledContext.AccessControl, + secretClient: scaledContext.Core.Secrets(namespace.GlobalNamespace), + } +} + +func (h *handler) ServeHTTP(writer http.ResponseWriter, req *http.Request) { + writer.Header().Set("Content-Type", "application/json") + + resourceType := mux.Vars(req)["resource"] + + if resourceType == "aksCheckCredentials" { + if req.Method != http.MethodPost { + handleErr(writer, http.StatusMethodNotAllowed, fmt.Errorf("use POST for this endpoint")) + return + } + if errCode, err := h.checkCredentials(req); err != nil { + handleErr(writer, errCode, err) + return + } + return + } + + capa := &Capabilities{} + + if credID := req.URL.Query().Get("cloudCredentialId"); credID != "" { + if errCode, err := h.getCloudCredential(req, capa, credID); err != nil { + handleErr(writer, errCode, err) + return + } + } else if req.Method == http.MethodPost { + if errCode, err := h.getCredentialsFromBody(req, capa); err != nil { + handleErr(writer, errCode, err) + return + } + } else { + handleErr(writer, http.StatusBadRequest, fmt.Errorf("cannot access Azure API without credentials to authenticate")) + return + } + + var serialized []byte + var errCode int + var err error + + switch resourceType { + case "aksUpgrades": + if serialized, errCode, err = listKubernetesUpgradeVersions(req.Context(), h.clusterCache, capa); err != nil { + logrus.Errorf("[aks-handler] error getting kubernetes upgrade versions: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksVersions": + if serialized, errCode, err = listKubernetesVersions(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting kubernetes versions: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksVirtualNetworks": + if serialized, errCode, err = listVirtualNetworks(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting networks: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksClusters": + if serialized, errCode, err = listClusters(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting clusters: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksVMSizes": + if serialized, errCode, err = listVMSizesV1(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting VM sizes: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksVMSizesV2": + if serialized, errCode, err = listVMSizesV2(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting VM sizes (v2): %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "aksLocations": + if serialized, errCode, err = listLocations(req.Context(), capa); err != nil { + logrus.Errorf("[aks-handler] error getting locations: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + default: + handleErr(writer, httperror.NotFound.Status, fmt.Errorf("invalid endpoint %v", resourceType)) + } +} + +func (h *handler) checkCredentials(req *http.Request) (int, error) { + cred := &Capabilities{} + raw, err := ioutil.ReadAll(req.Body) + if err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot read request body: %v", err) + } + + if err = json.Unmarshal(raw, &cred); err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot parse request body: %v", err) + } + + if cred.SubscriptionID == "" { + return http.StatusBadRequest, fmt.Errorf("must provide subscriptionId") + } + if cred.ClientID == "" { + return http.StatusBadRequest, fmt.Errorf("must provide clientId") + } + if cred.ClientSecret == "" { + return http.StatusBadRequest, fmt.Errorf("must provide clientSecret") + } + + clientEnvironment := "" + if cred.Environment != "" { + clientEnvironment = cred.Environment + } + _, azureEnvironment := GetEnvironment(clientEnvironment) + + cred.BaseURL = azureEnvironment.ResourceManagerEndpoint + cred.AuthBaseURL = azureEnvironment.ActiveDirectoryEndpoint + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + if cred.TenantID == "" { + cred.TenantID, err = azureutil.FindTenantID(ctx, azureEnvironment, cred.SubscriptionID) + if err != nil { + return http.StatusBadRequest, fmt.Errorf("could not find tenant ID for Azure environment %s: %w", azureEnvironment.Name, err) + } + } + + client, err := NewSubscriptionServiceClient(cred) + if err != nil { + logrus.Errorf("[AKS] failed to create new subscription client: %v", err) + return http.StatusUnauthorized, fmt.Errorf("invalid credentials: %w", err) + } + _, err = client.Get(ctx, cred.SubscriptionID, nil) + if err != nil { + logrus.Errorf("[AKS] failed to get subscription details: %v", err) + return http.StatusUnauthorized, fmt.Errorf("invalid credentials: %w", err) + } + + return http.StatusOK, nil +} + +func (h *handler) getCloudCredential(req *http.Request, cap *Capabilities, credID string) (int, error) { + ns, name := ref.Parse(credID) + if ns == "" || name == "" { + logrus.Errorf("[AKS] invalid cloud credential ID %s", credID) + return http.StatusBadRequest, fmt.Errorf("invalid cloud credential ID %s", credID) + } + + var accessCred client.CloudCredential //var to check access + if err := access.ByID(h.generateAPIContext(req), &schema.Version, client.CloudCredentialType, credID, &accessCred); err != nil { + apiError, ok := err.(*httperror.APIError) + if !ok { + return httperror.NotFound.Status, err + } + if apiError.Code.Status == httperror.NotFound.Status { + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") + } + if apiError.Code.Status != httperror.PermissionDenied.Status { + return httperror.InvalidBodyContent.Status, err + } + var clusterID string + if clusterID = req.URL.Query().Get("clusterID"); clusterID == "" { + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") + } + if errCode, err := h.clusterCheck(h.generateAPIContext(req), clusterID, credID); err != nil { + return errCode, err + } + } + + cc, err := h.secretsLister.Get(ns, name) + if err != nil { + logrus.Errorf("[AKS] error accessing cloud credential %s", credID) + return httperror.InvalidBodyContent.Status, fmt.Errorf("error accessing cloud credential %s", credID) + } + cap.TenantID = string(cc.Data["azurecredentialConfig-tenantId"]) + cap.SubscriptionID = string(cc.Data["azurecredentialConfig-subscriptionId"]) + cap.ClientID = string(cc.Data["azurecredentialConfig-clientId"]) + cap.ClientSecret = string(cc.Data["azurecredentialConfig-clientSecret"]) + cap.Environment = string(cc.Data["azurecredentialConfig-environment"]) + + clientEnvironment := "" + if cap.Environment != "" { + clientEnvironment = cap.Environment + } + _, azureEnvironment := GetEnvironment(clientEnvironment) + + if cap.TenantID == "" { + cap.TenantID, err = aks.GetCachedTenantID(h.secretClient, cap.SubscriptionID, cc) + if err != nil { + return httperror.ServerError.Status, err + } + } + + cap.BaseURL = req.URL.Query().Get("baseUrl") + if cap.BaseURL == "" { + cap.BaseURL = azureEnvironment.ResourceManagerEndpoint + } + cap.AuthBaseURL = req.URL.Query().Get("authBaseUrl") + if cap.AuthBaseURL == "" { + cap.AuthBaseURL = azureEnvironment.ActiveDirectoryEndpoint + } + + cap.ResourceLocation = req.URL.Query().Get("region") + cap.ClusterID = req.URL.Query().Get("clusterId") + + return http.StatusOK, nil +} + +func (h *handler) clusterCheck(apiContext *types.APIContext, clusterID, cloudCredentialID string) (int, error) { + var ( + clusters []*v3.Cluster + err error + ) + if clusterID == "" { + // If no clusterID is passed, then we check all clusters that the user has access to and are associated to the cloud credential. + clusters, err = h.clusterCache.GetByIndex(cluster.ByCloudCredential, cloudCredentialID) + if err != nil { + return httperror.InvalidBodyContent.Status, err + } + if len(clusters) == 0 { + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") + } + } else { + c, err := h.clusterCache.Get(clusterID) + if err != nil { + return httperror.ServerError.Status, err + } + clusters = []*v3.Cluster{c} + } + + for _, c := range clusters { + if c.Spec.AKSConfig == nil || c.Spec.AKSConfig.AzureCredentialSecret != cloudCredentialID { + continue + } + + clusterSchema := h.schemas.Schema(&mgmtSchema.Version, client.ClusterType) + if err := h.ac.CanDo(v3.ClusterGroupVersionKind.Group, v3.ClusterResource.Name, "update", apiContext, map[string]interface{}{"id": c.Name}, clusterSchema); err == nil { + return http.StatusOK, nil + } + } + + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") +} + +func (h *handler) getCredentialsFromBody(req *http.Request, cap *Capabilities) (int, error) { + raw, err := ioutil.ReadAll(req.Body) + if err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot read request body: %v", err) + } + + if err = json.Unmarshal(raw, &cap); err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot parse request body: %v", err) + } + + if cap.SubscriptionID == "" { + return http.StatusBadRequest, fmt.Errorf("invalid subscriptionId") + } + if cap.TenantID == "" { + return http.StatusBadRequest, fmt.Errorf("invalid tenantId") + } + if cap.ClientID == "" { + return http.StatusBadRequest, fmt.Errorf("invalid clientId") + } + if cap.ClientSecret == "" { + return http.StatusBadRequest, fmt.Errorf("invalid clientSecret") + } + + clientEnvironment := "" + if cap.Environment != "" { + clientEnvironment = cap.Environment + } + _, azureEnvironment := GetEnvironment(clientEnvironment) + + if cap.BaseURL == "" { + cap.BaseURL = azureEnvironment.ResourceManagerEndpoint + } + if cap.AuthBaseURL == "" { + cap.AuthBaseURL = azureEnvironment.ActiveDirectoryEndpoint + } + + return http.StatusOK, nil +} + +func (h *handler) generateAPIContext(req *http.Request) *types.APIContext { + return &types.APIContext{ + Method: req.Method, + Request: req, + Schemas: h.schemas, + Query: map[string][]string{}, + } +} + +func handleErr(writer http.ResponseWriter, errorCode int, originalErr error) { + writer.WriteHeader(errorCode) + + payload := make(map[string]string) + payload["error"] = originalErr.Error() + payloadJSON, err := json.Marshal(payload) + if err != nil { // This should not happen given fixed types on the payload - https://stackoverflow.com/a/33964549 + logrus.Errorf("[AKS] Failed to write payload JSON: %v", err) + return + } + writer.Write(payloadJSON) +} + +func GetEnvironment(env string) (cloud.Configuration, azure.Environment) { + switch env { + case "AzureChinaCloud": + return cloud.AzureChina, azure.ChinaCloud + case "AzureUSGovernmentCloud": + return cloud.AzureGovernment, azure.USGovernmentCloud + default: + return cloud.AzurePublic, azure.PublicCloud + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/listers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/listers.go new file mode 100644 index 0000000..374afe6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/aks/listers.go @@ -0,0 +1,547 @@ +package aks + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "regexp" + "sort" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + azcoreto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription" + "github.com/Azure/go-autorest/autorest/to" + "github.com/mcuadros/go-version" + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +type virtualNetworksResponseBody struct { + Name string `json:"name"` + ResourceGroup string `json:"resourceGroup"` + Subnets []subnet `json:"subnets"` + Location string `json:"location"` +} + +type subnet struct { + Name string `json:"name"` + AddressRange string `json:"addressRange"` +} + +var matchResourceGroup = regexp.MustCompile("/resource[gG]roups/(.+?)/") + +func NewClientSecretCredential(cap *Capabilities) (*azidentity.ClientSecretCredential, error) { + cloud, _ := GetEnvironment(cap.Environment) + + return azidentity.NewClientSecretCredential(cap.TenantID, cap.ClientID, cap.ClientSecret, &azidentity.ClientSecretCredentialOptions{ + ClientOptions: azcore.ClientOptions{ + Cloud: cloud, + }, + }) +} + +func NewVirtualMachineSKUClient(cap *Capabilities) (*armcompute.ResourceSKUsClient, error) { + cloud, _ := GetEnvironment(cap.Environment) + + cred, err := NewClientSecretCredential(cap) + if err != nil { + return nil, err + } + + options := &arm.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Cloud: cloud, + }, + } + + clientFactory, err := armcompute.NewClientFactory(cap.SubscriptionID, cred, options) + if err != nil { + return nil, err + } + + return clientFactory.NewResourceSKUsClient(), nil +} + +func NewVirtualMachineSizesClient(cap *Capabilities) (*armcompute.VirtualMachineSizesClient, error) { + cloud, _ := GetEnvironment(cap.Environment) + + cred, err := NewClientSecretCredential(cap) + if err != nil { + return nil, err + } + + clientFactory, err := armcompute.NewClientFactory(cap.SubscriptionID, cred, &arm.ClientOptions{ + ClientOptions: azcore.ClientOptions{ + Cloud: cloud, + }, + }) + if err != nil { + return nil, err + } + + return clientFactory.NewVirtualMachineSizesClient(), nil +} + +func NewNetworkServiceClient(cap *Capabilities) (*armnetwork.VirtualNetworksClient, error) { + cloud, _ := GetEnvironment(cap.Environment) + + cred, err := NewClientSecretCredential(cap) + if err != nil { + return nil, err + } + + options := &arm.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Cloud: cloud, + }, + } + + clientFactory, err := armnetwork.NewClientFactory(cap.SubscriptionID, cred, options) + if err != nil { + return nil, err + } + + return clientFactory.NewVirtualNetworksClient(), nil +} + +func NewManagedClustersClient(cap *Capabilities) (*armcontainerservice.ManagedClustersClient, error) { + cloud, _ := GetEnvironment(cap.Environment) + + cred, err := NewClientSecretCredential(cap) + if err != nil { + return nil, err + } + + options := &arm.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Cloud: cloud, + }, + } + + clientFactory, err := armcontainerservice.NewClientFactory(cap.SubscriptionID, cred, options) + if err != nil { + return nil, err + } + + return clientFactory.NewManagedClustersClient(), nil +} + +func NewSubscriptionServiceClient(cap *Capabilities) (*armsubscription.SubscriptionsClient, error) { + cloud, _ := GetEnvironment(cap.Environment) + + cred, err := NewClientSecretCredential(cap) + if err != nil { + return nil, err + } + + options := &arm.ClientOptions{ + ClientOptions: policy.ClientOptions{ + Cloud: cloud, + }, + } + + clientFactory, err := armsubscription.NewClientFactory(cred, options) + if err != nil { + return nil, err + } + + return clientFactory.NewSubscriptionsClient(), nil +} + +type sortableVersion []string + +func (s sortableVersion) Len() int { + return len(s) +} + +func (s sortableVersion) Swap(a, b int) { + s[a], s[b] = s[b], s[a] +} + +func (s sortableVersion) Less(a, b int) bool { + return version.Compare(s[a], s[b], "<") +} + +type KubernetesUpgradeVersion struct { + Version string `json:"version"` + Enabled bool `json:"enabled"` +} + +type KubernetesUpgradeVersions []*KubernetesUpgradeVersion + +func (s KubernetesUpgradeVersions) Len() int { + return len(s) +} + +func (s KubernetesUpgradeVersions) Swap(a, b int) { + s[a], s[b] = s[b], s[a] +} + +func (s KubernetesUpgradeVersions) Less(a, b int) bool { + return version.Compare(s[a].Version, s[b].Version, "<") +} + +type UpgradeVersionsResponse struct { + CurrentVersion string `json:"currentVersion"` + Upgrades KubernetesUpgradeVersions `json:"upgrades"` +} + +// listKubernetesUpgradeVersions lists all kubernetes versions listed by AKS Container Service and marks which ones the +// given cluster can be upgraded to. A version's `Enabled` flag is true if the cluster can be upgraded to the version +// in its current state. +func listKubernetesUpgradeVersions(ctx context.Context, clusterLister mgmtv3.ClusterCache, cap *Capabilities) ([]byte, int, error) { + var resp UpgradeVersionsResponse + + // load the target cluster, if the cluster is not found we cannot proceed + cluster, err := clusterLister.Get(cap.ClusterID) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("invalid cluster id") + } + + if cluster.Spec.AKSConfig.KubernetesVersion != nil { + resp.CurrentVersion = *cluster.Spec.AKSConfig.KubernetesVersion + } else { + if cluster.Status.AKSStatus.UpstreamSpec == nil || cluster.Status.AKSStatus.UpstreamSpec.KubernetesVersion == nil { + return nil, http.StatusBadRequest, fmt.Errorf("kubernetes version of the cluster cannot be determined") + } + resp.CurrentVersion = *cluster.Status.AKSStatus.UpstreamSpec.KubernetesVersion + } + + // get the client for aks container service + client, err := NewManagedClustersClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + res, err := client.ListKubernetesVersions(ctx, cap.ResourceLocation, nil) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get Kubernetes versions: %w", err) + } + + if len(res.Values) == 0 { + return nil, http.StatusBadRequest, fmt.Errorf("no versions were returned: %w", err) + } + + var upgradeVersions map[string]bool + for _, v := range res.Values { + if v == nil { + logrus.Warning("unexpected nil version") + continue + } + + for patchVersion, upgrades := range v.PatchVersions { + // exclude any versions older than the current version + if version.Compare(patchVersion, resp.CurrentVersion, "<") { + continue + } + + // generate the upgrade map when the current version is found + if patchVersion == resp.CurrentVersion { + upgradeVersions = upgradeableVersionsMap(upgrades) + continue + } + + // store this kubernetes version + resp.Upgrades = append(resp.Upgrades, &KubernetesUpgradeVersion{Version: patchVersion}) + } + } + + // enable any version listed in the upgrade versions + for _, kubernetesVersion := range resp.Upgrades { + if upgradeVersions[kubernetesVersion.Version] { + kubernetesVersion.Enabled = true + } + } + + // sort versions + sort.Sort(resp.Upgrades) + + return encodeOutput(resp) +} + +func listKubernetesVersions(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ResourceLocation == "" { + return nil, http.StatusBadRequest, fmt.Errorf("region is required") + } + + client, err := NewManagedClustersClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + res, err := client.ListKubernetesVersions(ctx, cap.ResourceLocation, nil) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get Kubernetes versions: %w", err) + } + + if len(res.Values) == 0 { + return nil, http.StatusBadRequest, fmt.Errorf("no versions were returned: %w", err) + } + + var kubernetesVersions []string + for _, v := range res.Values { + for version := range v.PatchVersions { + kubernetesVersions = append(kubernetesVersions, version) + } + } + + sort.Sort(sortableVersion(kubernetesVersions)) + + return encodeOutput(kubernetesVersions) +} + +func listVirtualNetworks(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + client, err := NewNetworkServiceClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + var networks []virtualNetworksResponseBody + pager := client.NewListAllPager(nil) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get networks: %w", err) + } + + var batch []virtualNetworksResponseBody + for _, azureNetwork := range page.Value { + if cap.ResourceLocation != "" && to.String(azureNetwork.Location) != cap.ResourceLocation { + continue + } + var subnets []subnet + + if azureNetwork.Properties.Subnets != nil { + for _, azureSubnet := range azureNetwork.Properties.Subnets { + if azureSubnet.Name != nil { + subnets = append(subnets, subnet{ + Name: to.String(azureSubnet.Name), + AddressRange: to.String(azureSubnet.Properties.AddressPrefix), + }) + } + } + } + + if azureNetwork.ID == nil { + return nil, http.StatusInternalServerError, fmt.Errorf("no ID on virtual network") + } + + match := matchResourceGroup.FindStringSubmatch(*azureNetwork.ID) + + if len(match) < 2 || match[1] == "" { + return nil, http.StatusInternalServerError, fmt.Errorf("could not parse virtual network ID") + } + + if azureNetwork.Name == nil { + return nil, http.StatusInternalServerError, fmt.Errorf("no name on virtual network") + } + + batch = append(batch, virtualNetworksResponseBody{ + Name: to.String(azureNetwork.Name), + ResourceGroup: match[1], + Subnets: subnets, + Location: to.String(azureNetwork.Location), + }) + } + + networks = append(networks, batch...) + } + + return encodeOutput(networks) +} + +type clustersResponseBody struct { + ResourceGroup string `json:"resourceGroup"` + ClusterName string `json:"clusterName"` + RBACEnabled bool `json:"rbacEnabled"` + Location string `json:"location"` +} + +func listClusters(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + client, err := NewManagedClustersClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + var clusters []clustersResponseBody + pager := client.NewListPager(nil) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get cluster list: %w", err) + } + + for _, v := range page.Value { + cluster := clustersResponseBody{ + ClusterName: to.String(v.Name), + RBACEnabled: to.Bool(v.Properties.EnableRBAC), + Location: to.String(v.Location), + } + if v.ID != nil { + match := matchResourceGroup.FindStringSubmatch(to.String(v.ID)) + if len(match) < 2 || match[1] == "" { + return nil, http.StatusInternalServerError, fmt.Errorf("could not parse virtual network ID") + } + cluster.ResourceGroup = match[1] + } + clusters = append(clusters, cluster) + } + } + + return encodeOutput(clusters) +} + +func listVMSizesV1(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ResourceLocation == "" { + return nil, http.StatusBadRequest, fmt.Errorf("region is required") + } + + client, err := NewVirtualMachineSizesClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + vmSizes := make([]string, 0) + pager := client.NewListPager(cap.ResourceLocation, nil) + for pager.More() { + nextResult, err := pager.NextPage(ctx) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get VM sizes: %v", err) + } + for _, rg := range nextResult.Value { + vmSizes = append(vmSizes, to.String(rg.Name)) + } + } + + return encodeOutput(vmSizes) +} + +const ( + AzureSkuResourceTypeVM = "virtualMachines" + AzureAcceleratedNetworkingFeature = "AcceleratedNetworkingEnabled" +) + +func listVMSizesV2(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ResourceLocation == "" { + return nil, http.StatusBadRequest, fmt.Errorf("region is required") + } + + type VMSizeInfo struct { + //Name is synonymous with the size shown in Rancher UI + Name string + AcceleratedNetworkingSupported bool + AvailabilityZones []string + } + + skuClient, err := NewVirtualMachineSKUClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + var vmSkuInfo []VMSizeInfo + // only get resources for the given location. + // https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5#example-ResourceSKUsClient.NewListPager-ListsAllAvailableResourceSkUsForTheSpecifiedRegion + pager := skuClient.NewListPager(&armcompute.ResourceSKUsClientListOptions{ + Filter: azcoreto.Ptr(fmt.Sprintf("location eq '%s'", cap.ResourceLocation)), + }) + + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, http.StatusInternalServerError, err + } + for _, v := range page.Value { + // we currently can't specify a particular SKU type in the API request, + // we have to filter them out here + if to.String(v.ResourceType) != AzureSkuResourceTypeVM { + continue + } + + vm := VMSizeInfo{ + Name: to.String(v.Name), + AvailabilityZones: []string{}, + } + + if v.Capabilities != nil { + for _, skuCapabilities := range v.Capabilities { + if to.String(skuCapabilities.Name) == AzureAcceleratedNetworkingFeature && to.String(skuCapabilities.Value) == "True" { + vm.AcceleratedNetworkingSupported = true + break + } + } + } + + if v.LocationInfo != nil && len(v.LocationInfo) > 0 { + locInfo := v.LocationInfo + // We specified a location in the Azure API request so there is at most one element + for _, z := range locInfo[0].Zones { + vm.AvailabilityZones = append(vm.AvailabilityZones, *z) + } + } + + vmSkuInfo = append(vmSkuInfo, vm) + } + } + + return encodeOutput(vmSkuInfo) +} + +type locationsResponseBody struct { + Name string `json:"name"` + DisplayName string `json:"displayName"` +} + +func listLocations(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + client, err := NewSubscriptionServiceClient(cap) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + var locations []locationsResponseBody + pager := client.NewListLocationsPager(cap.SubscriptionID, nil) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, http.StatusBadRequest, fmt.Errorf("failed to get locations: %w", err) + } + + for _, v := range page.Value { + locations = append(locations, locationsResponseBody{ + Name: to.String(v.Name), + DisplayName: to.String(v.DisplayName), + }) + } + } + + return encodeOutput(locations) +} + +func encodeOutput(result interface{}) ([]byte, int, error) { + data, err := json.Marshal(&result) + if err != nil { + return data, http.StatusInternalServerError, err + } + + return data, http.StatusOK, err +} + +func upgradeableVersionsMap(patchVersion *armcontainerservice.KubernetesPatchVersion) map[string]bool { + rval := make(map[string]bool, 0) + + if patchVersion.Upgrades == nil { + // already on latest version, no upgrades available + return rval + } + for _, upgradeVersion := range patchVersion.Upgrades { + rval[*upgradeVersion] = true + } + + return rval +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/app/app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/app/app.go new file mode 100644 index 0000000..a4e575e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/app/app.go @@ -0,0 +1,308 @@ +package app + +import ( + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalog/manager" + clusterv3 "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + projectv3 "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/clustermanager" + hcommon "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + clusterschema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + projectschema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/user" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Wrapper struct { + Clusters v3.ClusterInterface + ClusterManager *clustermanager.Manager + CatalogManager manager.CatalogManager + TemplateVersionClient v3.CatalogTemplateVersionInterface + TemplateVersionLister v3.CatalogTemplateVersionLister + AppGetter pv3.AppsGetter + UserLister v3.UserLister + UserManager user.Manager +} + +const ( + appLabel = "io.cattle.field/appId" + MCappLabel = "mcapp" + creatorIDAnno = "field.cattle.io/creatorId" +) + +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + mcappLabel := convert.ToString(values.GetValueN(resource.Values, "labels", MCappLabel)) + if mcappLabel == "" { + resource.AddAction(apiContext, "upgrade") + resource.AddAction(apiContext, "rollback") + } else { + delete(resource.Links, "remove") + } + resource.Links["revision"] = apiContext.URLBuilder.Link("revision", resource) + if _, ok := resource.Values["status"]; ok { + if status, ok := resource.Values["status"].(map[string]interface{}); ok { + delete(status, "lastAppliedTemplate") + } + } + delete(resource.Values, "appliedFiles") + delete(resource.Values, "files") +} + +func (w Wrapper) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + projectID := convert.ToString(data["projectId"]) + clusterID := strings.Split(projectID, ":")[0] + targetNamespace := convert.ToString(data["targetNamespace"]) + appID := convert.ToString(data["name"]) + if err := w.ValidateDashboardAppDoesNotExist(clusterID, appID, targetNamespace, request); err != nil { + return err + } + + externalID := convert.ToString(data["externalId"]) + if externalID == "" { + return nil + } + templateVersionID, templateVersionNamespace, err := hcommon.ParseExternalID(externalID) + if err != nil { + return err + } + templateVersion, err := w.TemplateVersionClient.GetNamespaced(templateVersionNamespace, templateVersionID, metav1.GetOptions{}) + if err != nil { + return err + } + if templateVersion.Spec.RequiredNamespace != "" && templateVersion.Spec.RequiredNamespace != targetNamespace { + return httperror.NewAPIError(httperror.InvalidType, "template's requiredNamespace doesn't match catalog app's target namespace") + } + + // in here access.ByID will only find namespace that is assigned to the current project + var ns clusterv3.Namespace + if err := access.ByID(request, &clusterschema.Version, clusterv3.NamespaceType, targetNamespace, &ns); err != nil { + return err + } + if ns.Name == "" { + return httperror.NewAPIError(httperror.InvalidReference, fmt.Sprintf("target namespace %v is not assigned to the current project %v", targetNamespace, data["projectId"])) + } + + return nil +} + +// ValidateDashboardAppDoesNotExist validates that a request is not attempting +// to create an apps.project.cattle.io with an ID that matches an +// apps.catalog.cattle.io in a namespace that matches its targetNamespace. +func (w Wrapper) ValidateDashboardAppDoesNotExist(clusterName, appID, ns string, request *types.APIContext) error { + if request.Method != http.MethodPost { + return nil + } + + couldNotValidateErrFormat := "could not determine whether an apps.catalog.cattle.io with same ID and namespace currently exists: %v" + clusterContext, err := w.ClusterManager.UserContext(clusterName) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf(couldNotValidateErrFormat, err)) + } + + appClient := clusterContext.Catalog.V1().App() + if _, err := appClient.Get(ns, appID, metav1.GetOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf(couldNotValidateErrFormat, err)) + } + } else { + return httperror.NewAPIError(httperror.Conflict, fmt.Sprintf("an apps.catalog.cattle.io already exists with"+ + " ID [%s] in namespace [%s]", appID, ns)) + } + + return nil +} + +func copyAnswers(specAnswers map[string]string, answers interface{}) { + m, ok := answers.(map[string]interface{}) + if ok { + for k, v := range m { + specAnswers[k] = convert.ToString(v) + } + } +} + +func (w Wrapper) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + var app projectv3.App + if err := access.ByID(apiContext, &projectschema.Version, projectv3.AppType, apiContext.ID, &app); err != nil { + return err + } + + var appMap map[string]interface{} + if err := access.ByID(apiContext, &projectschema.Version, projectv3.AppType, apiContext.ID, &appMap); err != nil { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("unable to access app by id: %v", err)) + } + + if err := apiContext.AccessControl.CanDo(pv3.AppGroupVersionKind.Group, pv3.AppResource.Name, "update", apiContext, appMap, apiContext.Schema); err != nil { + return httperror.NewAPIError(httperror.PermissionDenied, fmt.Sprintf("user does not have permission to update for action %s", actionName)) + } + + creatorNotFound := false + if _, err := w.UserLister.Get("", app.CreatorID); err != nil && apierrors.IsNotFound(err) { + creatorNotFound = true + } + + actionInput, err := parse.ReadBody(apiContext.Request) + if err != nil { + return err + } + clusterName, namespace := ref.Parse(app.ProjectID) + obj, err := w.AppGetter.Apps(namespace).Get(app.Name, metav1.GetOptions{}) + if err != nil { + return err + } + switch actionName { + case "upgrade": + externalID := convert.ToString(actionInput["externalId"]) + + _, _, _, _, currentAppVersion, err := hcommon.SplitExternalID(obj.Spec.ExternalID) + if err != nil { + httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("could not parse current externalID [%s]: %s", + obj.Spec.ExternalID, err.Error())) + } + if err := w.validateChartCompatibility(externalID, clusterName, currentAppVersion); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + answers := actionInput["answers"] + answersSetString := actionInput["answersSetString"] + forceUpgrade := actionInput["forceUpgrade"] + files := actionInput["files"] + valuesYaml := actionInput["valuesYaml"] + obj.Spec.Answers = make(map[string]string) + obj.Spec.AnswersSetString = make(map[string]string) + + copyAnswers(obj.Spec.Answers, answers) + copyAnswers(obj.Spec.AnswersSetString, answersSetString) + obj.Spec.ExternalID = externalID + if convert.ToBool(forceUpgrade) { + v32.AppConditionForceUpgrade.Unknown(obj) + } + if creatorNotFound { + obj.Annotations[creatorIDAnno] = w.UserManager.GetUser(apiContext) + } + if files != nil { + inputFiles := convert.ToMapInterface(files) + if len(inputFiles) != 0 { + targetFiles := make(map[string]string) + for k, v := range inputFiles { + targetFiles[k] = convert.ToString(v) + } + + obj.Spec.Files = targetFiles + obj.Spec.ExternalID = "" // ignore externalID + } + } + if valuesYaml != nil { + obj.Spec.ValuesYaml = convert.ToString(valuesYaml) + } else { + obj.Spec.ValuesYaml = "" + } + // indicate this a user driven action + v32.AppConditionUserTriggeredAction.True(obj) + if _, err := w.AppGetter.Apps(namespace).Update(obj); err != nil { + return err + } + apiContext.WriteResponse(http.StatusNoContent, map[string]interface{}{}) + return nil + case "rollback": + forceUpgrade := actionInput["forceUpgrade"] + revisionName := convert.ToString(actionInput["revisionId"]) + if revisionName == "" { + return fmt.Errorf("revision is empty") + } + _, projectID := ref.Parse(app.ProjectID) + revisionID := fmt.Sprintf("%s:%s", projectID, revisionName) + var appRevision projectv3.AppRevision + if err := access.ByID(apiContext, &projectschema.Version, projectv3.AppRevisionType, revisionID, &appRevision); err != nil { + return err + } + + _, _, _, _, currentAppVersion, err := hcommon.SplitExternalID(obj.Spec.ExternalID) + if err != nil { + httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("could not parse current externalID [%s]: %s", + obj.Spec.ExternalID, err.Error())) + } + if err := w.validateChartCompatibility(appRevision.Status.ExternalID, clusterName, currentAppVersion); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + _, namespace := ref.Parse(app.ProjectID) + obj, err := w.AppGetter.Apps(namespace).Get(app.Name, metav1.GetOptions{}) + if err != nil { + return err + } + obj.Spec.Answers = appRevision.Status.Answers + obj.Spec.AnswersSetString = appRevision.Status.AnswersSetString + obj.Spec.ExternalID = appRevision.Status.ExternalID + obj.Spec.ValuesYaml = appRevision.Status.ValuesYaml + if convert.ToBool(forceUpgrade) { + v32.AppConditionForceUpgrade.Unknown(obj) + } + if creatorNotFound { + obj.Annotations[creatorIDAnno] = w.UserManager.GetUser(apiContext) + } + obj.Spec.Files = appRevision.Status.Files + // indicate this a user driven action + v32.AppConditionUserTriggeredAction.True(obj) + if _, err := w.AppGetter.Apps(namespace).Update(obj); err != nil { + return err + } + apiContext.WriteResponse(http.StatusNoContent, map[string]interface{}{}) + return nil + } + return nil +} + +func (w Wrapper) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "revision": + var app projectv3.App + if err := access.ByID(apiContext, &projectschema.Version, projectv3.AppType, apiContext.ID, &app); err != nil { + return err + } + var appRevisions, filtered []map[string]interface{} + if err := access.List(apiContext, &projectschema.Version, projectv3.AppRevisionType, &types.QueryOptions{}, &appRevisions); err != nil { + return err + } + for _, re := range appRevisions { + labels := convert.ToMapInterface(re["labels"]) + if reflect.DeepEqual(labels[appLabel], app.Name) { + filtered = append(filtered, re) + } + } + apiContext.Type = projectv3.AppRevisionType + apiContext.WriteResponse(http.StatusOK, filtered) + return nil + } + return nil +} + +func (w Wrapper) validateChartCompatibility(externalID, clusterName, currentAppVersion string) error { + if externalID == "" { + return nil + } + templateVersionID, namespace, err := hcommon.ParseExternalID(externalID) + if err != nil { + return err + } + template, err := w.TemplateVersionLister.Get(namespace, templateVersionID) + if err != nil { + return err + } + return w.CatalogManager.ValidateChartCompatibility(template, clusterName, currentAppVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/authn/rtb_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/authn/rtb_store.go new file mode 100644 index 0000000..f23e439 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/authn/rtb_store.go @@ -0,0 +1,78 @@ +package authn + +import ( + "context" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/requests" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clusterrouter" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" +) + +func SetRTBStore(ctx context.Context, schema *types.Schema, mgmt *config.ScaledContext) { + providers.Configure(ctx, mgmt) + userLister := mgmt.Management.Users("").Controller().Lister() + + t := &transform.Store{ + Store: schema.Store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + if id, ok := data[client.ClusterRoleTemplateBindingFieldUserID].(string); ok && id != "" { + u, err := userLister.Get("", id) + if err != nil { + if !errors.IsNotFound(err) { + logrus.Errorf("problem retrieving user for CRTB %v from cache during CRTB transformation: %v", data, err) + } + return data, nil + } + + for _, pid := range u.PrincipalIDs { + if strings.HasPrefix(pid, "system://") { + if opt != nil && opt.Options["ByID"] == "true" { + return nil, httperror.NewAPIError(httperror.NotFound, "resource not found") + } + return nil, nil + } + } + } + return data, nil + }, + } + + s := &Store{ + Store: t, + auth: requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, mgmt), + } + + schema.Store = s +} + +type Store struct { + types.Store + auth requests.Authenticator +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if principalID, ok := data[client.ClusterRoleTemplateBindingFieldUserPrincipalID].(string); ok && principalID != "" && !strings.HasPrefix(principalID, "local://") { + token, err := s.auth.TokenFromRequest(apiContext.Request) + if err != nil { + return nil, err + } + princ, err := providers.GetPrincipal(principalID, *token) + if err != nil { + return nil, err + } + if princ.DisplayName != "" { + values.PutValue(data, princ.DisplayName, "annotations", "auth.cattle.io/principal-display-name") + } + } + + return s.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/catalog.go new file mode 100644 index 0000000..a418888 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/catalog.go @@ -0,0 +1,248 @@ +package catalog + +import ( + "bytes" + "encoding/json" + "net/http" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/ghodss/yaml" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/generated/compose" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/settings" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + SystemLibraryURL = "https://git.rancher.io/system-charts" + SystemCatalogName = "system-library" + embededSystemCatalogSetting = "system-catalog" +) + +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + if canUpdateCatalog(apiContext, resource) { + resource.AddAction(apiContext, "refresh") + } + resource.Links["exportYaml"] = apiContext.URLBuilder.Link("exportYaml", resource) + if resource.Values["url"] == SystemLibraryURL && resource.Values["name"] == SystemCatalogName { + delete(resource.Links, "remove") + + if strings.ToLower(settings.SystemCatalog.Get()) == "bundled" { + delete(resource.Links, "update") + } + } +} + +func CollectionFormatter(apiContext *types.APIContext, collection *types.GenericCollection) { + if canUpdateCatalog(apiContext, nil) { + collection.AddAction(apiContext, "refresh") + } +} + +type ActionHandler struct { + CatalogClient v3.CatalogInterface + ProjectCatalogClient v3.ProjectCatalogInterface + ClusterCatalogClient v3.ClusterCatalogInterface +} + +func (a ActionHandler) refreshCatalog(catalog *v3.Catalog) (err error) { + for i := 0; i < 3; i++ { + catalog, err = a.CatalogClient.Get(catalog.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + catalog.Status.LastRefreshTimestamp = time.Now().Format(time.RFC3339) + v32.CatalogConditionRefreshed.Unknown(catalog) + _, err = a.CatalogClient.Update(catalog) + if err == nil { + break + } + } + return err +} + +func (a ActionHandler) RefreshActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + if actionName != "refresh" { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + if !canUpdateCatalog(apiContext, nil) { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + + catalogs := []v3.Catalog{} + if apiContext.ID != "" { + catalog, err := a.CatalogClient.Get(apiContext.ID, metav1.GetOptions{}) + if err != nil { + return err + } + catalogs = append(catalogs, *catalog) + } else { + catalogList, err := a.CatalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, catalog := range catalogList.Items { + catalogs = append(catalogs, catalog) + } + } + var catalogNames []string + for _, catalog := range catalogs { + if err := a.refreshCatalog(&catalog); err != nil { + return err + } + catalogNames = append(catalogNames, catalog.Name) + } + data := map[string]interface{}{ + "catalogs": catalogNames, + "type": "catalogRefresh", + } + apiContext.WriteResponse(http.StatusOK, data) + return nil +} + +func (a ActionHandler) ExportYamlHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "exportyaml": + catalog, err := a.CatalogClient.Get(apiContext.ID, metav1.GetOptions{}) + if err != nil { + return err + } + topkey := compose.Config{} + topkey.Version = "v3" + ca := client.Catalog{} + if err := convert.ToObj(catalog.Spec, &ca); err != nil { + return err + } + topkey.Catalogs = map[string]client.Catalog{} + topkey.Catalogs[catalog.Name] = ca + m, err := convert.EncodeToMap(topkey) + if err != nil { + return err + } + delete(m["catalogs"].(map[string]interface{})[catalog.Name].(map[string]interface{}), "actions") + delete(m["catalogs"].(map[string]interface{})[catalog.Name].(map[string]interface{}), "links") + delete(m["catalogs"].(map[string]interface{})[catalog.Name].(map[string]interface{}), "password") + data, err := json.Marshal(m) + if err != nil { + return err + } + + buf, err := yaml.JSONToYAML(data) + if err != nil { + return err + } + reader := bytes.NewReader(buf) + apiContext.Response.Header().Set("Content-Type", "text/yaml") + http.ServeContent(apiContext.Response, apiContext.Request, "exportYaml", time.Now(), reader) + return nil + } + return nil +} + +func (a ActionHandler) RefreshProjectCatalogActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + if actionName != "refresh" { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + if !canUpdateCatalog(apiContext, nil) { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + + prjCatalogs := []v3.ProjectCatalog{} + if apiContext.ID != "" { + ns, name := ref.Parse(apiContext.ID) + catalog, err := a.ProjectCatalogClient.GetNamespaced(ns, name, metav1.GetOptions{}) + if err != nil { + return err + } + prjCatalogs = append(prjCatalogs, *catalog) + } else { + catalogList, err := a.ProjectCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, catalog := range catalogList.Items { + prjCatalogs = append(prjCatalogs, catalog) + } + } + var catalogNames []string + for _, catalog := range prjCatalogs { + catalog.Status.LastRefreshTimestamp = time.Now().Format(time.RFC3339) + v32.CatalogConditionRefreshed.Unknown(&catalog) + if _, err := a.ProjectCatalogClient.Update(&catalog); err != nil { + return err + } + } + data := map[string]interface{}{ + "catalogs": catalogNames, + "type": "catalogRefresh", + } + apiContext.WriteResponse(http.StatusOK, data) + return nil +} + +func (a ActionHandler) RefreshClusterCatalogActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + if actionName != "refresh" { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + if !canUpdateCatalog(apiContext, nil) { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + + clCatalogs := []v3.ClusterCatalog{} + if apiContext.ID != "" { + ns, name := ref.Parse(apiContext.ID) + catalog, err := a.ClusterCatalogClient.GetNamespaced(ns, name, metav1.GetOptions{}) + if err != nil { + return err + } + clCatalogs = append(clCatalogs, *catalog) + } else { + catalogList, err := a.ClusterCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, catalog := range catalogList.Items { + clCatalogs = append(clCatalogs, catalog) + } + } + var catalogNames []string + for _, catalog := range clCatalogs { + catalog.Status.LastRefreshTimestamp = time.Now().Format(time.RFC3339) + v32.CatalogConditionRefreshed.Unknown(&catalog) + if _, err := a.ClusterCatalogClient.Update(&catalog); err != nil { + return err + } + } + data := map[string]interface{}{ + "catalogs": catalogNames, + "type": "catalogRefresh", + } + apiContext.WriteResponse(http.StatusOK, data) + return nil +} + +func canUpdateCatalog(apiContext *types.APIContext, resource *types.RawResource) bool { + var groupName, resourceName string + switch rbac.TypeFromContext(apiContext, resource) { + case client.CatalogType: + groupName, resourceName = v3.CatalogGroupVersionKind.Group, v3.CatalogResource.Name + case client.ClusterCatalogType: + groupName, resourceName = v3.ClusterCatalogGroupVersionKind.Group, v3.ClusterCatalogResource.Name + case client.ProjectCatalogType: + groupName, resourceName = v3.ProjectCatalogGroupVersionKind.Group, v3.ProjectCatalogResource.Name + default: + return false + } + obj := rbac.ObjFromContext(apiContext, resource) + return apiContext.AccessControl.CanDo(groupName, resourceName, "update", apiContext, obj, apiContext.Schema) == nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store.go new file mode 100644 index 0000000..dfb6896 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store.go @@ -0,0 +1,120 @@ +package catalog + +import ( + "context" + "fmt" + "strconv" + + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/rancher/pkg/catalog/manager" + catUtil "github.com/rancher/rancher/pkg/catalog/utils" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + hcommon "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +type templateStore struct { + types.Store + CatalogTemplateVersionLister v3.CatalogTemplateVersionLister + CatalogManager manager.CatalogManager +} + +func GetTemplateStore(ctx context.Context, managementContext *config.ScaledContext) types.Store { + ts := templateStore{ + CatalogTemplateVersionLister: managementContext.Management.CatalogTemplateVersions("").Controller().Lister(), + CatalogManager: managementContext.CatalogManager, + } + + s := &transform.Store{ + Store: proxy.NewProxyStore(ctx, managementContext.ClientGetter, + config.ManagementStorageContext, + scheme.Scheme, + []string{"apis"}, + "management.cattle.io", + "v3", + "CatalogTemplate", + "catalogtemplates"), + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + data[client.CatalogTemplateFieldVersionLinks] = ts.extractVersionLinks(apiContext, data) + return data, nil + }, + } + + ts.Store = s + + return ts +} + +func (t *templateStore) extractVersionLinks(apiContext *types.APIContext, resource map[string]interface{}) map[string]interface{} { + schema := apiContext.Schemas.Schema(&managementschema.Version, client.TemplateVersionType) + r := map[string]interface{}{} + versionMaps, ok := resource[client.CatalogTemplateFieldVersions].([]interface{}) + if ok { + for _, versionData := range versionMaps { + revision := "" + if v, ok := versionData.(map[string]interface{})["revision"].(int64); ok { + revision = strconv.FormatInt(v, 10) + } + versionString, ok := versionData.(map[string]interface{})["version"].(string) + if !ok { + logrus.Trace("[templateStore] failed type assertion for field \"version\" for CatalogTemplateFieldVersion") + continue + } + versionID := fmt.Sprintf("%v-%v", resource["id"], versionString) + if revision != "" { + versionID = fmt.Sprintf("%v-%v", resource["id"], revision) + } + versionLink := apiContext.URLBuilder.ResourceLinkByID(schema, versionID) + currentVersion := apiContext.Query.Get("currentVersion") + if currentVersion != "" && currentVersion == versionString { + r[versionString] = versionLink + continue + } + if t.isTemplateVersionCompatible(apiContext.Query.Get("clusterName"), versionData.(map[string]interface{})["externalId"].(string)) { + r[versionString] = versionLink + } + } + } + return r +} + +// templateVersionForRancherVersion indicates if a templateVersion works with the rancher server version +// In the error case it will always return true - if a template is actually invalid for that rancher version +// API validation will handle the rejection +func (t *templateStore) isTemplateVersionCompatible(clusterName, externalID string) bool { + rancherVersion := settings.ServerVersion.Get() + + if !catUtil.ReleaseServerVersion(rancherVersion) { + return true + } + + templateVersionID, namespace, err := hcommon.ParseExternalID(externalID) + if err != nil { + return true + } + + template, err := t.CatalogTemplateVersionLister.Get(namespace, templateVersionID) + if err != nil { + return true + } + + err = t.CatalogManager.ValidateRancherVersion(template, "") + if err != nil { + return false + } + + if clusterName != "" { + if err := t.CatalogManager.ValidateKubeVersion(template, clusterName); err != nil { + return false + } + } + + return true +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store_test.go new file mode 100644 index 0000000..bd0c97b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/store_test.go @@ -0,0 +1,122 @@ +package catalog + +import ( + "fmt" + "strings" + "testing" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalog/manager" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/version" +) + +type testCase struct { + externalID string + rancherVersion string + kubernetesVersion string + result bool +} + +func newTestCase(templateName, rancherVersion, kubernetesVersion string, result bool) testCase { + return testCase{ + externalID: generateExternalID(templateName), + rancherVersion: rancherVersion, + kubernetesVersion: kubernetesVersion, + result: result, + } +} +func TestExtractLinks(t *testing.T) { + templateStore := setupTestTemplateStore() + + // Setup test cases + var tests []testCase + tests = append(tests, newTestCase("rancher-testRancherConstraint-0.1", "2.4.0", "", true)) + tests = append(tests, newTestCase("rancher-testRancherConstraint-0.1", "2.5.1", "", false)) + // all test cases without rancher version should result in true, since a dev environment is assumed and checks are bypassed + tests = append(tests, newTestCase("rancher-testRancherConstraint-0.1", "", "", true)) + tests = append(tests, newTestCase("rancher-testKubeVersionConstraint-0.1", "2.4.0", "1.14.0", true)) + tests = append(tests, newTestCase("rancher-testKubeVersionConstraint-0.1", "2.4.0", "1.16.0", false)) + tests = append(tests, newTestCase("rancher-testKubeVersionConstraint-0.1", "2.4.0", "", true)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "2.5.1", "1.14.0", false)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "2.4.9", "1.16.0", false)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "2.5.1", "1.16.0", false)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "2.4.9", "1.14.0", true)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "", "", true)) + tests = append(tests, newTestCase("rancher-testBothConstraints-0.1", "", "1.16.0", true)) + tests = append(tests, newTestCase("rancher-testNeitherConstraints-0.1", "", "", true)) + tests = append(tests, newTestCase("rancher-testNeitherConstraints-0.1", "2.5.1", "1.16.0", true)) + + // The externalID of a testCase will be tested for compatibility with the given rancherVersion and cluster kubernetes + // version. The result field defines whether compatibility is expected. + for _, test := range tests { + settings.ServerVersion.Set(test.rancherVersion) + templateStore.CatalogManager = &manager.Manager{ClusterLister: newClusterListerWithVersion(test.kubernetesVersion)} + clusterName := "test" + if test.kubernetesVersion == "" { + // kubernetesVersion being empty is equivalent to not targeting a cluster + clusterName = "" + } + assert.Equal(t, test.result, templateStore.isTemplateVersionCompatible(clusterName, test.externalID), fmt.Sprintf("kubeVersion [%s] or rancherVersion [%s] unexpected compatibility with template [%s]", test.kubernetesVersion, test.rancherVersion, test.externalID)) + } +} + +// setupTestTemplateStore sets up test templates with different combinations of rancher +// version constraints and kubeVersionConstraints +func setupTestTemplateStore() templateStore { + catalogTemplateVersionLister := &fakes.CatalogTemplateVersionListerMock{ + GetFunc: func(namespace, name string) (*mgmtv3.CatalogTemplateVersion, error) { + switch name { + case "rancher-testRancherConstraint-0.1": + return newCatalogTemplateVersion("2.4.99", ""), nil + case "rancher-testKubeVersionConstraint-0.1": + return newCatalogTemplateVersion("", "<1.15.0"), nil + case "rancher-testBothConstraints-0.1": + return newCatalogTemplateVersion("2.4.99", "<1.15.0"), nil + case "rancher-testNeitherConstraints-0.1": + return newCatalogTemplateVersion("", ""), nil + } + return nil, nil + }, + } + + return templateStore{ + CatalogTemplateVersionLister: catalogTemplateVersionLister, + CatalogManager: &manager.Manager{}, + } +} +func newClusterListerWithVersion(kubernetesVersion string) *fakes.ClusterListerMock { + return &fakes.ClusterListerMock{ + GetFunc: func(namespace, name string) (*mgmtv3.Cluster, error) { + if name == "test" { + cluster := mgmtv3.Cluster{ + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{ + GitVersion: kubernetesVersion, + }, + }, + } + return &cluster, nil + } + return nil, fmt.Errorf("invalid cluster: %s", name) + }, + } +} + +func newCatalogTemplateVersion(maxRancherVersion, kubeVersion string) *apimgmtv3.CatalogTemplateVersion { + catalogTemplateVersion := &apimgmtv3.CatalogTemplateVersion{ + Spec: apimgmtv3.TemplateVersionSpec{ + KubeVersion: kubeVersion, + RancherMaxVersion: maxRancherVersion, + }, + } + return catalogTemplateVersion +} + +func generateExternalID(name string) string { + parts := strings.Split(name, "-") + return fmt.Sprintf("catalog://?catalog=%s&template=%s&version=%s", parts[0], parts[1], parts[2]) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/template.go new file mode 100644 index 0000000..fc4bdd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/template.go @@ -0,0 +1,142 @@ +package catalog + +import ( + "bytes" + "net/http" + "strings" + "time" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" +) + +type TemplateWrapper struct { + CatalogLister v3.CatalogLister + ClusterCatalogLister v3.ClusterCatalogLister + ProjectCatalogLister v3.ProjectCatalogLister + CatalogTemplateVersionLister v3.CatalogTemplateVersionLister + SecretLister v1.SecretLister +} + +func (t TemplateWrapper) TemplateFormatter(apiContext *types.APIContext, resource *types.RawResource) { + var prjCatalogName, clusterCatalogName string + + //icon + ic, ok := resource.Values["icon"] + if ok { + if strings.HasPrefix(ic.(string), "file:") { + delete(resource.Values, "icon") + resource.Links["icon"] = apiContext.URLBuilder.Link("icon", resource) + + } else { + delete(resource.Values, "icon") + resource.Links["icon"] = ic.(string) + } + } else { + delete(resource.Values, "icon") + resource.Links["icon"] = apiContext.URLBuilder.Link("icon", resource) + } + + val := resource.Values + if val[client.CatalogTemplateFieldCatalogID] != nil { + //catalog link + catalogSchema := apiContext.Schemas.Schema(&managementschema.Version, client.CatalogType) + catalogName := strings.Split(resource.ID, "-")[0] + resource.Links["catalog"] = apiContext.URLBuilder.ResourceLinkByID(catalogSchema, catalogName) + } + + if val[client.CatalogTemplateFieldProjectCatalogID] != nil { + prjCatID, ok := val[client.CatalogTemplateFieldProjectCatalogID].(string) + if ok { + prjCatalogName = prjCatID + } + //project catalog link + prjCatalogSchema := apiContext.Schemas.Schema(&managementschema.Version, client.ProjectCatalogType) + resource.Links["projectCatalog"] = apiContext.URLBuilder.ResourceLinkByID(prjCatalogSchema, prjCatalogName) + } + + if val[client.CatalogTemplateFieldClusterCatalogID] != nil { + clusterCatID, ok := val[client.CatalogTemplateFieldClusterCatalogID].(string) + if ok { + clusterCatalogName = clusterCatID + } + //cluster catalog link + clCatalogSchema := apiContext.Schemas.Schema(&managementschema.Version, client.ClusterCatalogType) + resource.Links["clusterCatalog"] = apiContext.URLBuilder.ResourceLinkByID(clCatalogSchema, clusterCatalogName) + } + + // delete category + delete(resource.Values, "category") + + // delete versions + delete(resource.Values, "versions") +} + +func (t TemplateWrapper) TemplateIconHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "icon": + template := &client.Template{} + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, template); err != nil { + return err + } + if template.Icon == "" || strings.HasPrefix(template.Icon, "http:") || strings.HasPrefix(template.Icon, "https:") { + http.Error(apiContext.Response, "", http.StatusNoContent) + return nil + } + + var ( + catalogType string + catalogName string + iconBytes []byte + err error + ) + + if template.CatalogID != "" { + catalogType = client.CatalogType + catalogName = template.CatalogID + } else if template.ClusterCatalogID != "" { + catalogType = client.ClusterCatalogType + catalogName = template.ClusterCatalogID + } else if template.ProjectCatalogID != "" { + catalogType = client.ProjectCatalogType + catalogName = template.ProjectCatalogID + } + + namespace, name := helmlib.SplitNamespaceAndName(catalogName) + catalog, err := helmlib.GetCatalog(catalogType, namespace, name, t.CatalogLister, t.ClusterCatalogLister, t.ProjectCatalogLister) + if err != nil { + return err + } + + helm, err := helmlib.New(catalog, t.SecretLister) + if err != nil { + return err + } + + iconBytes, err = helm.LoadIcon(template.IconFilename, template.Icon) + if err != nil { + return err + } + + t, err := time.Parse(time.RFC3339, template.Created) + if err != nil { + return err + } + + iconReader := bytes.NewReader(iconBytes) + apiContext.Response.Header().Set("Cache-Control", "private, max-age=604800") + // add security headers (similar to raw.githubusercontent) + apiContext.Response.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") + apiContext.Response.Header().Set("X-Content-Type-Options", "nosniff") + http.ServeContent(apiContext.Response, apiContext.Request, template.IconFilename, t, iconReader) + return nil + default: + return httperror.NewAPIError(httperror.NotFound, "not found") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/templateversion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/templateversion.go new file mode 100644 index 0000000..6001af7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/templateversion.go @@ -0,0 +1,182 @@ +package catalog + +import ( + "bytes" + "encoding/base64" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +type TemplateVerionFormatterWrapper struct { + CatalogLister v3.CatalogLister + ClusterCatalogLister v3.ClusterCatalogLister + ProjectCatalogLister v3.ProjectCatalogLister + SecretLister v1.SecretLister +} + +var supportedFiles = []string{"catalog.yml", "catalog.yaml", "questions.yml", "questions.yaml"} + +type catalogYml struct { + Questions []v32.Question `yaml:"questions,omitempty"` +} + +func (t TemplateVerionFormatterWrapper) TemplateVersionFormatter(apiContext *types.APIContext, resource *types.RawResource) { + delete(resource.Values, "files") + delete(resource.Values, "readme") + delete(resource.Values, "appReadme") + + resource.Links["readme"] = apiContext.URLBuilder.Link("readme", resource) + + version := resource.Values["version"].(string) + if revision, ok := resource.Values["revision"]; ok { + version = strconv.FormatInt(revision.(int64), 10) + } + templateID := strings.TrimSuffix(resource.ID, "-"+version) + templateSchema := apiContext.Schemas.Schema(&managementschema.Version, client.TemplateType) + resource.Links["template"] = apiContext.URLBuilder.ResourceLinkByID(templateSchema, templateID) + + upgradeLinks, ok := resource.Values["upgradeVersionLinks"].(map[string]interface{}) + if ok { + linkMap := map[string]string{} + templateVersionSchema := apiContext.Schemas.Schema(&managementschema.Version, client.TemplateVersionType) + for v, versionID := range upgradeLinks { + linkMap[v] = apiContext.URLBuilder.ResourceLinkByID(templateVersionSchema, versionID.(string)) + } + delete(resource.Values, "upgradeVersionLinks") + resource.Values["upgradeVersionLinks"] = linkMap + } + + externalID, ok := resource.Values["externalId"].(string) + if !ok { + logrus.Errorf("TemplateVersion has no external ID: %s", resource.ID) + return + } + versionName, ok := resource.Values["versionName"].(string) + if !ok { + logrus.Errorf("TemplateVersion has no version Name: %s", resource.ID) + return + } + versionDir, _ := resource.Values["versionDir"].(string) + versionURLsInterface, _ := resource.Values["versionUrls"].([]interface{}) + versionURLs := make([]string, len(versionURLsInterface)) + for i, url := range versionURLsInterface { + versionURLs[i], _ = url.(string) + } + + files, err := t.loadChart(&client.CatalogTemplateVersion{ + ExternalID: externalID, + Version: version, + VersionName: versionName, + VersionDir: versionDir, + VersionURLs: versionURLs, + }, nil) + if err != nil { + logrus.Errorf("failed to load chart: %s", err) + return + } + if len(files) == 0 { + logrus.Errorf("no files were found for this chart") + return + } + + for name, content := range files { + if strings.EqualFold(fmt.Sprintf("%s/%s", versionName, "app-readme.md"), name) { + resource.Links["app-readme"] = apiContext.URLBuilder.Link("app-readme", resource) + } + for _, f := range supportedFiles { + if strings.EqualFold(fmt.Sprintf("%s/%s", versionName, f), name) { + var value catalogYml + if err := yaml.Unmarshal([]byte(content), &value); err != nil { + logrus.Errorf("Failed to load file %s : %s", f, err) + } + if len(value.Questions) > 0 { + resource.Values["questions"] = value.Questions + } + } + } + files[name] = base64.StdEncoding.EncodeToString([]byte(content)) + } + resource.Values["files"] = files +} + +func (t TemplateVerionFormatterWrapper) TemplateVersionReadmeHandler(apiContext *types.APIContext, next types.RequestHandler) error { + templateVersion := &client.CatalogTemplateVersion{} + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, templateVersion); err != nil { + return err + } + + var filter []string + switch apiContext.Link { + case "readme": + filter = []string{templateVersion.VersionName + "/readme.md"} + case "app-readme": + filter = []string{templateVersion.VersionName + "/app-readme.md"} + default: + return httperror.NewAPIError(httperror.NotFound, "not found") + } + files, err := t.loadChart(templateVersion, filter) + if err != nil { + return err + } + return sendFile(templateVersion, files, apiContext) +} + +func (t TemplateVerionFormatterWrapper) loadChart(templateVersion *client.CatalogTemplateVersion, filter []string) (map[string]string, error) { + namespace, catalogName, catalogType, _, _, err := common.SplitExternalID(templateVersion.ExternalID) + if err != nil { + return nil, err + } + catalog, err := helmlib.GetCatalog(catalogType, namespace, catalogName, t.CatalogLister, t.ClusterCatalogLister, t.ProjectCatalogLister) + if err != nil { + return nil, err + } + + helm, err := helmlib.New(catalog, t.SecretLister) + if err != nil { + return nil, err + } + + return helm.LoadChart(&v32.TemplateVersionSpec{ + Version: templateVersion.Version, + VersionName: templateVersion.VersionName, + VersionDir: templateVersion.VersionDir, + VersionURLs: templateVersion.VersionURLs, + }, filter) +} + +func sendFile(templateVersion *client.CatalogTemplateVersion, files map[string]string, apiContext *types.APIContext) error { + var ( + fileContents string + err error + ) + for name, content := range files { + if strings.EqualFold(fmt.Sprintf("%s/%s.md", templateVersion.VersionName, apiContext.Link), name) { + fileContents = content + } + } + reader := bytes.NewReader([]byte(fileContents)) + t, err := time.Parse(time.RFC3339, templateVersion.Created) + if err != nil { + return err + } + apiContext.Response.Header().Set("Content-Type", "text/plain") + http.ServeContent(apiContext.Response, apiContext.Request, apiContext.Link, t, reader) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator.go new file mode 100644 index 0000000..bb3753b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator.go @@ -0,0 +1,47 @@ +package catalog + +import ( + "net/http" + "net/url" + "regexp" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" +) + +var ( + controlChars = regexp.MustCompile("[[:cntrl:]]") + controlEncoded = regexp.MustCompile("%[0-1][0-9,a-f,A-F]") +) + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if pathURL, _ := data["url"].(string); pathURL != "" { + if err := validateURL(pathURL); err != nil { + return err + } + if u, err := url.Parse(pathURL); err == nil { + u.Scheme = strings.ToLower(u.Scheme) // git commands are case-sensitive + data["url"] = u.String() + } + } else if request.Method == http.MethodPost { + return httperror.NewAPIError(httperror.MissingRequired, "Catalog URL not specified") + } + // + if helmVersion, ok := data["helmVersion"]; ok { + toLowerHelmVersion := strings.ToLower(helmVersion.(string)) + // determine if user is setting helmVersion to helm 3 and validate to help user set value correctly + if strings.Contains(toLowerHelmVersion, "v3") && !common.IsHelm3(toLowerHelmVersion) { + return httperror.NewAPIError(httperror.InvalidBodyContent, "Invalid helm 3 version") + } + } + return nil +} + +func validateURL(pathURL string) error { + if controlChars.FindStringIndex(pathURL) != nil || controlEncoded.FindStringIndex(pathURL) != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, "Invalid characters in catalog URL") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator_test.go new file mode 100644 index 0000000..240df6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/catalog/validator_test.go @@ -0,0 +1,121 @@ +package catalog + +import ( + "testing" + + "github.com/rancher/norman/types" + "github.com/stretchr/testify/assert" +) + +func TestValidateURL(t *testing.T) { + type args struct { + pathURL string + } + tests := []struct { + name string + pathURL string + wantErr bool + }{ + { + name: "Remove control characters", + pathURL: "http://example.com/1\r2\n345\b67\t", + wantErr: true, + }, + { + name: "Remove urlEncoded control characters", + pathURL: "https://example.com/12%003%1F45%0A%0a6", + wantErr: true, + }, + { + name: "Remove all control characters, allow uppercase scheme", + pathURL: "https://www.example%0D.com/Hello\r\nWorld", + wantErr: true, + }, + { + name: "Allow git protocol", + pathURL: "git://www.example.com", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotErr := validateURL(tt.pathURL) + assert.Equal(t, gotErr != nil, tt.wantErr) + }) + } +} + +func TestValidateHelm3Version(t *testing.T) { + request := testAsAPIContext() + schema := testAsSchema() + testsWithValues := []struct { + name string + helmVersion string + wantErr bool + }{ + { + name: "Empty helm 3 value", + helmVersion: "", + wantErr: false, + }, + { + name: "Non helm 3 value", + helmVersion: "v2", + wantErr: false, + }, + { + name: "Allow full helm 3 value", + helmVersion: "helm_v3", + wantErr: false, + }, + { + name: "Allow shortened helm 3 value", + helmVersion: "v3", + wantErr: false, + }, + { + name: "Invalid helm 3 value", + helmVersion: "sdfasdfasdv3", + wantErr: true, + }, + } + + testWithNoVersion := []struct { + name string + wantErr bool + }{ + { + name: "No helm 3 value in data map", + wantErr: false, + }, + } + + for _, tt := range testsWithValues { + t.Run(tt.name, func(t *testing.T) { + data := make(map[string]interface{}) + data["helmVersion"] = tt.helmVersion + gotErr := Validator(request, schema, data) + assert.Equal(t, gotErr != nil, tt.wantErr) + }) + } + + for _, tt := range testWithNoVersion { + t.Run(tt.name, func(t *testing.T) { + data := make(map[string]interface{}) + gotErr := Validator(request, schema, data) + assert.Equal(t, gotErr != nil, tt.wantErr) + }) + } +} + +// setup api context for validation test +func testAsAPIContext() *types.APIContext { + testAPIContext := &types.APIContext{} + return testAPIContext +} + +// setup schema for validation test +func testAsSchema() *types.Schema { + testSchema := &types.Schema{} + return testSchema +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actionhandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actionhandler.go new file mode 100644 index 0000000..2b70652 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actionhandler.go @@ -0,0 +1,168 @@ +package cluster + +import ( + "fmt" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/catalog/manager" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clustermanager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/user" + v1 "k8s.io/client-go/kubernetes/typed/authorization/v1" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +// ActionHandler used for performing various cluster actions. +type ActionHandler struct { + NodepoolGetter v3.NodePoolsGetter + NodeLister v3.NodeLister + ClusterClient v3.ClusterInterface + CatalogManager manager.CatalogManager + NodeTemplateGetter v3.NodeTemplatesGetter + UserMgr user.Manager + ClusterManager *clustermanager.Manager + CatalogTemplateVersionLister v3.CatalogTemplateVersionLister + BackupClient v3.EtcdBackupInterface + ClusterTemplateClient v3.ClusterTemplateInterface + ClusterTemplateRevisionClient v3.ClusterTemplateRevisionInterface + SubjectAccessReviewClient v1.SubjectAccessReviewInterface + TokenClient v3.TokenInterface + Auth requests.Authenticator +} + +func canUpdateCluster(apiContext *types.APIContext) bool { + if apiContext == nil { + return false + } + cluster := map[string]interface{}{ + "id": apiContext.ID, + } + return canUpdateClusterWithValues(apiContext, cluster) +} + +func canUpdateClusterWithValues(apiContext *types.APIContext, values map[string]interface{}) bool { + return apiContext.AccessControl.CanDo(v3.ClusterGroupVersionKind.Group, v3.ClusterResource.Name, "update", apiContext, values, apiContext.Schema) == nil +} + +func canBackupEtcd(apiContext *types.APIContext, namespace string) bool { + if apiContext == nil { + return false + } + etcdBackupSchema := types.Schema{ID: mgmtclient.EtcdBackupType} + backupMap := map[string]interface{}{ + "namespaceId": namespace, + } + return apiContext.AccessControl.CanDo(v3.EtcdBackupGroupVersionKind.Group, v3.EtcdBackupResource.Name, "create", apiContext, backupMap, &etcdBackupSchema) == nil +} + +func canCreateClusterTemplate(sar v1.SubjectAccessReviewInterface, apiContext *types.APIContext) bool { + if apiContext == nil { + return false + } + callerID := apiContext.Request.Header.Get(gaccess.ImpersonateUserHeader) + canCreateTemplates, _ := CanCreateRKETemplate(callerID, sar) + return canCreateTemplates +} + +// ClusterActionHandler runs the handler for the provided cluster action in the given context. +func (a ActionHandler) ClusterActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + switch actionName { + case v32.ClusterActionGenerateKubeconfig: + return a.GenerateKubeconfigActionHandler(actionName, action, apiContext) + case v32.ClusterActionImportYaml: + return a.ImportYamlHandler(actionName, action, apiContext) + case v32.ClusterActionExportYaml: + return a.ExportYamlHandler(actionName, action, apiContext) + case v32.ClusterActionBackupEtcd: + if !canBackupEtcd(apiContext, apiContext.ID) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not backup etcd") + } + return a.BackupEtcdHandler(actionName, action, apiContext) + case v32.ClusterActionRestoreFromEtcdBackup: + if !canUpdateCluster(apiContext) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not restore etcd backup") + } + return a.RestoreFromEtcdBackupHandler(actionName, action, apiContext) + case v32.ClusterActionRotateCertificates: + if !canUpdateCluster(apiContext) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not rotate certificates") + } + return a.RotateCertificates(actionName, action, apiContext) + case v32.ClusterActionRotateEncryptionKey: + if !canUpdateCluster(apiContext) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not rotate encryption key") + } + return a.RotateEncryptionKey(actionName, action, apiContext) + case v32.ClusterActionSaveAsTemplate: + if !canUpdateCluster(apiContext) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not save the cluster as an RKETemplate") + } + if !canCreateClusterTemplate(a.SubjectAccessReviewClient, apiContext) { + return httperror.NewAPIError(httperror.PermissionDenied, "can not save the cluster as an RKETemplate") + } + return a.saveAsTemplate(actionName, action, apiContext) + } + return httperror.NewAPIError(httperror.NotFound, "not found") +} + +// ensureClusterToken will create a new kubeconfig token for the user in the provided context with the default TTL. +func (a ActionHandler) ensureClusterToken(clusterID string, apiContext *types.APIContext) (string, error) { + input, err := a.createTokenInput(apiContext) + if err != nil { + return "", err + } + + return a.UserMgr.EnsureClusterToken(clusterID, input) +} + +// ensureToken will create a new kubeconfig token for the user in the provided context with the default TTL. +func (a ActionHandler) ensureToken(apiContext *types.APIContext) (string, error) { + input, err := a.createTokenInput(apiContext) + if err != nil { + return "", err + } + + return a.UserMgr.EnsureToken(input) +} + +// createTokenInput will create the input for a new kubeconfig token with the default TTL. +func (a ActionHandler) createTokenInput(apiContext *types.APIContext) (user.TokenInput, error) { + userName := a.UserMgr.GetUser(apiContext) + tokenNamePrefix := fmt.Sprintf("kubeconfig-%s", userName) + + authToken, err := a.Auth.TokenFromRequest(apiContext.Request) + if err != nil { + return user.TokenInput{}, err + } + + defaultTokenTTL, err := tokens.GetKubeconfigDefaultTokenTTLInMilliSeconds() + if err != nil { + return user.TokenInput{}, fmt.Errorf("failed to get default token TTL: %w", err) + } + + return user.TokenInput{ + TokenName: tokenNamePrefix, + Description: "Kubeconfig token", + Kind: "kubeconfig", + UserName: userName, + AuthProvider: authToken.AuthProvider, + TTL: defaultTokenTTL, + Randomize: true, + UserPrincipal: authToken.UserPrincipal, + }, nil +} + +func (a ActionHandler) generateKubeConfig(apiContext *types.APIContext, cluster *mgmtclient.Cluster) (*clientcmdapi.Config, error) { + token, err := a.ensureToken(apiContext) + if err != nil { + return nil, err + } + + return a.ClusterManager.KubeConfig(cluster.ID, token), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_certs.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_certs.go new file mode 100644 index 0000000..ce33635 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_certs.go @@ -0,0 +1,76 @@ +package cluster + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + rketypes "github.com/rancher/rke/types" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a ActionHandler) RotateCertificates(actionName string, action *types.Action, apiContext *types.APIContext) error { + rtn := map[string]interface{}{ + "type": "rotateCertificateOutput", + "message": "rotating certificates for all components", + } + var mgmtCluster mgmtv3.Cluster + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &mgmtCluster); err != nil { + rtn["message"] = "none existent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, rtn) + + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + rtn["message"] = "none existent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, rtn) + + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + data, err := ioutil.ReadAll(apiContext.Request.Body) + if err != nil { + rtn["message"] = "reading request body error" + apiContext.WriteResponse(http.StatusBadRequest, rtn) + + return errors.Wrapf(err, "failed to read request body") + } + + input := client.RotateCertificateInput{} + if err = json.Unmarshal(data, &input); err != nil { + rtn["message"] = "failed to parse request content" + apiContext.WriteResponse(http.StatusBadRequest, rtn) + + return errors.Wrap(err, "unmarshaling input error") + } + + rotateCerts := &rketypes.RotateCertificates{ + CACertificates: input.CACertificates, + Services: []string{input.Services}, + } + cluster.Spec.RancherKubernetesEngineConfig.RotateCertificates = rotateCerts + if _, err := a.ClusterClient.Update(cluster); err != nil { + rtn["message"] = "failed to update cluster object" + apiContext.WriteResponse(http.StatusInternalServerError, rtn) + + return errors.Wrapf(err, "unable to update Cluster %s", cluster.Name) + } + if input.CACertificates { + rtn["message"] = "rotating CA certificates and all components" + } else if len(input.Services) > 0 { + rtn["message"] = fmt.Sprintf("rotating %s certificates", input.Services) + } else { + rtn["message"] = "rotating certificates for all components" + } + + apiContext.WriteResponse(http.StatusOK, rtn) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_etcd.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_etcd.go new file mode 100644 index 0000000..112be8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_etcd.go @@ -0,0 +1,156 @@ +package cluster + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/etcdbackup" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a ActionHandler) BackupEtcdHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + response := map[string]interface{}{ + "message": "starting ETCD backup", + } + // checking access + var mgmtCluster mgmtv3.Cluster + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &mgmtCluster); err != nil { + response["message"] = "none existent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + response["message"] = "none existent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + + newBackup, err := etcdbackup.NewBackupObject(cluster, true) + if err != nil { + response["message"] = "failed to initialize etcdbackup object" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrapf(err, "failed to initialize etcdbackup object") + } + + backup, err := a.BackupClient.Create(newBackup) + if err != nil { + response["message"] = "failed to create etcdbackup object" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrapf(err, "failed to cteate etcdbackup object") + } + backupJSON, err := json.Marshal(backup) + if err != nil { + return err + } + apiContext.Response.Header().Set("Content-Type", "application/json") + http.ServeContent(apiContext.Response, apiContext.Request, "backupEtcd", time.Now(), bytes.NewReader(backupJSON)) + return nil +} + +func (a ActionHandler) RestoreFromEtcdBackupHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + response := map[string]interface{}{ + "message": "restoring etcdbackup for the cluster", + } + + data, err := ioutil.ReadAll(apiContext.Request.Body) + if err != nil { + response["message"] = "reading request body error" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrap(err, "failed to read request body") + } + + input := client.RestoreFromEtcdBackupInput{} + if err = json.Unmarshal(data, &input); err != nil { + response["message"] = "failed to parse request content" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrap(err, "unmarshaling input error") + } + // checking access + var mgmtCluster client.Cluster + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &mgmtCluster); err != nil { + response["message"] = "nonexistent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + response["message"] = "nonexistent Cluster" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get Cluster by ID %s", apiContext.ID) + } + + ns, name := ref.Parse(input.EtcdBackupID) + if ns == "" || name == "" { + return httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("invalid input id %s", input.EtcdBackupID)) + } + + backup, err := a.BackupClient.GetNamespaced(ns, name, v1.GetOptions{}) + if err != nil { + response["message"] = "error getting backup config" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrapf(err, "failed to get backup config by ID %s", input.EtcdBackupID) + } + + clusterBackupConfig := cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig + if clusterBackupConfig != nil && + clusterBackupConfig.S3BackupConfig == nil && + backup.Spec.BackupConfig.S3BackupConfig != nil { + return httperror.NewAPIError(httperror.MethodNotAllowed, + fmt.Sprintf( + "restoring S3 backups with no cluster level S3 configuration is not supported %s", + input.EtcdBackupID)) + } + + if input.RestoreRkeConfig != "" && backup.Status.ClusterObject == "" { + // attempting to restore rke config and the backup does not contain data, probably pre 2.4 backup + return httperror.NewAPIError(httperror.MethodNotAllowed, + fmt.Sprintf("unable to restore RKE config, backup contains no cluster object: %s", input.EtcdBackupID)) + } + + // backup was taken in 2.4+ and has content + switch strings.ToLower(input.RestoreRkeConfig) { + case "kubernetesversion": + // restore from copy stored inline to not have to decompress object + cluster.Spec.RancherKubernetesEngineConfig.Version = backup.Status.KubernetesVersion + case "all": + clusterBackup, err := etcdbackup.DecompressCluster(backup.Status.ClusterObject) + if err != nil { + response["message"] = "error decompressing cluster object" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrap(err, + fmt.Sprintf("error decompressing cluster object for backupid %s: %s", input.EtcdBackupID, err)) + } + cluster.Spec.RancherKubernetesEngineConfig = clusterBackup.Spec.RancherKubernetesEngineConfig + cluster.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName = clusterBackup.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName + + cluster.Spec.ClusterAgentDeploymentCustomization = clusterBackup.Spec.ClusterAgentDeploymentCustomization + cluster.Spec.FleetAgentDeploymentCustomization = clusterBackup.Spec.FleetAgentDeploymentCustomization + } + + // flag cluster for restore + cluster.Spec.RancherKubernetesEngineConfig.Restore.SnapshotName = input.EtcdBackupID + cluster.Spec.RancherKubernetesEngineConfig.Restore.Restore = true + + if _, err = a.ClusterClient.Update(cluster); err != nil { + response["message"] = "failed to update cluster object" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrapf(err, "unable to update Cluster %s", cluster.Name) + } + apiContext.WriteResponse(http.StatusCreated, response) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_key.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_key.go new file mode 100644 index 0000000..061a380 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_key.go @@ -0,0 +1,76 @@ +package cluster + +import ( + "bytes" + "encoding/json" + "net/http" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a ActionHandler) RotateEncryptionKey(actionName string, action *types.Action, apiContext *types.APIContext) error { + response := map[string]interface{}{ + "type": v3client.RotateEncryptionKeyOutputType, + v3client.RotateEncryptionKeyOutputFieldMessage: "starting rotate encryption key", + } + + var mgmtCluster mgmtv3.Cluster + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &mgmtCluster); err != nil { + response[v3client.RotateEncryptionKeyOutputFieldMessage] = "cluster does not exist" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get cluster by ID %s", apiContext.ID) + } + + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + response[v3client.RotateEncryptionKeyOutputFieldMessage] = "cluster does not exist" + apiContext.WriteResponse(http.StatusBadRequest, response) + return errors.Wrapf(err, "failed to get cluster by ID %s", apiContext.ID) + } + + if err := checkEncryptionConfig(cluster); err != nil { + return httperror.NewAPIError(httperror.InvalidAction, err.Error()) + } + + if !v3.ClusterConditionUpdated.IsTrue(cluster) { + return httperror.NewAPIError(httperror.InvalidAction, "cluster is in updating state") + } + + cluster.Spec.RancherKubernetesEngineConfig.RotateEncryptionKey = true + if _, err := a.ClusterClient.Update(cluster); err != nil { + response[v3client.RotateEncryptionKeyOutputFieldMessage] = "failed to update cluster object" + apiContext.WriteResponse(http.StatusInternalServerError, response) + return errors.Wrapf(err, "unable to update cluster %s", cluster.Name) + } + + res, err := json.Marshal(response) + if err != nil { + return err + } + + apiContext.Response.Header().Set("Content-Type", "application/json") + http.ServeContent(apiContext.Response, apiContext.Request, v3.ClusterActionRotateEncryptionKey, time.Now(), bytes.NewReader(res)) + return nil +} + +// checkEncryptionConfig validates that the secrets encryption is both enabled and not custom. +func checkEncryptionConfig(c *v3.Cluster) error { + if c.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig == nil { + return errors.New("secrets encryption configuration is not defined") + } + if !c.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.Enabled { + return errors.New("secrets encryption is disabled") + } + if c.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig != nil { + return errors.New("custom encryption configuration is not supported for key rotation action") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig.go new file mode 100644 index 0000000..140df08 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig.go @@ -0,0 +1,81 @@ +package cluster + +import ( + "net/http" + "net/url" + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kubeconfig" + "github.com/rancher/rancher/pkg/settings" + "k8s.io/apimachinery/pkg/labels" +) + +func (a ActionHandler) GenerateKubeconfigActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + var err error + var cluster mgmtclient.Cluster + var nodes []*mgmtv3.Node + if err = access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &cluster); err != nil { + return err + } + if apiContext.Type == "cluster" { + nodes, err = a.NodeLister.List(cluster.ID, labels.Everything()) + if err != nil { + return err + } + } + + var ( + cfg string + tokenKey string + ) + + endpointEnabled := cluster.LocalClusterAuthEndpoint != nil && cluster.LocalClusterAuthEndpoint.Enabled + + generateToken := strings.EqualFold(settings.KubeconfigGenerateToken.Get(), "true") + if generateToken { + // generate token and place it in kubeconfig, token doesn't expire + if endpointEnabled { + tokenKey, err = a.ensureClusterToken(cluster.ID, apiContext) + } else { + tokenKey, err = a.ensureToken(apiContext) + } + if err != nil { + return err + } + } + + host := settings.ServerURL.Get() + if host == "" { + host = apiContext.Request.Host + } else { + u, err := url.Parse(host) + if err == nil { + host = u.Host + } else { + host = apiContext.Request.Host + } + } + + if endpointEnabled { + cfg, err = kubeconfig.ForClusterTokenBased(&cluster, nodes, apiContext.ID, host, tokenKey) + if err != nil { + return err + } + } else { + cfg, err = kubeconfig.ForTokenBased(cluster.Name, apiContext.ID, host, tokenKey) + if err != nil { + return err + } + } + + data := map[string]interface{}{ + "config": cfg, + "type": "generateKubeconfigOutput", + } + apiContext.WriteResponse(http.StatusOK, data) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig_test.go new file mode 100644 index 0000000..1b2f3fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_kubeconfig_test.go @@ -0,0 +1,272 @@ +package cluster + +import ( + "fmt" + "net/http" + "testing" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/requests" + v3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/user" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + apitypes "k8s.io/apimachinery/pkg/types" +) + +func TestGenerateKubeconfigActionHandler(t *testing.T) { + tests := []struct { + name string + hostname string + generateToken string + clusterAceEnabled bool + + clusterLookupErr error + nodeListerErr error + tokenCreateErr error + + wantErr bool + }{ + { + name: "no token generation", + generateToken: "false", + wantErr: false, + }, + { + name: "token generation", + generateToken: "true", + wantErr: false, + }, + { + name: "token generation with hostname set", + generateToken: "true", + hostname: "https://set-hostname.fake", + wantErr: false, + }, + { + name: "no token generation with hostname set", + generateToken: "false", + hostname: "https://set-hostname.fake", + wantErr: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + const testClusterName = "test-cluster" + const fakeHost = "fake-request-host.fake" + const testUser = "" + testSchemas := types.NewSchemas().AddSchemas(managementSchema.Schemas) + clusterSchema := testSchemas.Schema(&managementSchema.Version, v3.ClusterType) + fakeStore := fakeClusterStore{ + cluster: v3.Cluster{ + Name: testClusterName, + }, + err: test.clusterLookupErr, + } + clusterSchema.Store = &fakeStore + err := settings.KubeconfigGenerateToken.Set(test.generateToken) + assert.NoError(t, err, "got an error when setting up kubeconfig token setting") + err = settings.ServerURL.Set(test.hostname) + assert.NoError(t, err, "got an error when setting up the server url setting") + + recorder := normanRecorder{} + apiContext := &types.APIContext{ + ID: testClusterName, + Version: &managementSchema.Version, + Type: v3.ClusterType, + ResponseWriter: &recorder, + Schemas: testSchemas, + Request: &http.Request{Host: fakeHost}, + } + fakeManager := fakeUserManager{} + fakeManager.addUserForContext(apiContext, testUser) + fakeAuth := fakeAuthenticator{ + token: apimgmtv3.Token{ + AuthProvider: "local", + UserPrincipal: apimgmtv3.Principal{ + Provider: "local", + ObjectMeta: metav1.ObjectMeta{ + Name: testUser, + }, + }, + }, + } + + handler := ActionHandler{ + NodeLister: &fakes.NodeListerMock{ + GetFunc: func(namespace string, name string) (*apimgmtv3.Node, error) { + return nil, nil + }, + ListFunc: func(namespace string, selector labels.Selector) ([]*apimgmtv3.Node, error) { + return nil, test.nodeListerErr + }, + }, + UserMgr: &fakeManager, + Auth: &fakeAuth, + } + err = handler.GenerateKubeconfigActionHandler("not-used", nil, apiContext) + if test.wantErr { + assert.Error(t, err, "expected an error but did not get one") + } else { + assert.NoError(t, err, "got an error when calling generate kubeconfig") + assert.Len(t, recorder.Responses, 1, "expected a single response") + response := recorder.Responses[0] + assert.Equal(t, response.Code, 200, "expected 200 response code") + data, ok := response.Data.(map[string]interface{}) + assert.True(t, ok, "type assertion failed") + kubeconfig, ok := data["config"].(string) + assert.True(t, ok, "no string kubeconfig in response data") + if test.generateToken == "true" { + assert.Contains(t, kubeconfig, fmt.Sprintf("kubeconfig-%s:", testUser), "token expected in kubeconfig but was missing") + } + if test.hostname == "" { + assert.Contains(t, kubeconfig, fakeHost, "expected hostname from request") + } else { + assert.Contains(t, kubeconfig, test.hostname, "expected server hostname in kubeconfig") + } + + } + }) + } +} + +// fakeClusterStore implements types.Store for the purposes of testing +type fakeClusterStore struct { + err error + cluster v3.Cluster +} + +func (f *fakeClusterStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + if f.err != nil { + return nil, f.err + } + return convert.EncodeToMap(f.cluster) +} + +// The rest of these methods have no functionality, and only serve to implement the types.Store interface +func (f *fakeClusterStore) Context() types.StorageContext { return "" } +func (f *fakeClusterStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + return nil, nil +} +func (f *fakeClusterStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + return nil, nil +} +func (f *fakeClusterStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + return nil, nil +} +func (f *fakeClusterStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, nil +} +func (f *fakeClusterStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + return nil, nil +} + +// normanRecorder is like httptest.ResponseRecorder, but for norman's types.ResponseWriter interface +type normanRecorder struct { + Responses []struct { + Code int + Data interface{} + } +} + +func (n *normanRecorder) Write(apiContext *types.APIContext, code int, obj interface{}) { + if n.Responses == nil { + n.Responses = []struct { + Code int + Data interface{} + }{} + } + n.Responses = append(n.Responses, struct { + Code int + Data interface{} + }{ + Code: code, + Data: obj, + }) +} + +const errUserName = "errUser" + +// fakeUserManager implements user.Manager +type fakeUserManager struct { + usersForContext map[string]string +} + +// Utility methods helpful for setting up mocks +func (f *fakeUserManager) addUserForContext(context *types.APIContext, user string) { + if f.usersForContext == nil { + f.usersForContext = map[string]string{} + } + f.usersForContext[context.ID] = user +} + +func (f *fakeUserManager) GetUser(apiContext *types.APIContext) string { + if f.usersForContext == nil { + return errUserName + } + contextUser, ok := f.usersForContext[apiContext.ID] + if !ok { + return errUserName + } + return contextUser +} +func (f *fakeUserManager) EnsureToken(input user.TokenInput) (string, error) { + if input.UserName == errUserName { + return "", fmt.Errorf("can't generate token for err user") + } + return input.TokenName + ":" + "tokenvalue", nil +} +func (f *fakeUserManager) EnsureClusterToken(clusterName string, input user.TokenInput) (string, error) { + if input.UserName == errUserName { + return "", fmt.Errorf("can't generate token for err user") + } + return input.TokenName + ":" + "tokenvalue", nil +} + +// Remaining functions are only implemented to satisfy the interface +func (f *fakeUserManager) SetPrincipalOnCurrentUser(apiContext *types.APIContext, principal apimgmtv3.Principal) (*apimgmtv3.User, error) { + return nil, nil +} +func (f *fakeUserManager) DeleteToken(tokenName string) error { return nil } +func (f *fakeUserManager) EnsureUser(principalName, displayName string) (*apimgmtv3.User, error) { + return nil, nil +} +func (f *fakeUserManager) CheckAccess(accessMode string, allowedPrincipalIDs []string, userPrincipalID string, groups []apimgmtv3.Principal) (bool, error) { + return false, nil +} +func (f *fakeUserManager) SetPrincipalOnCurrentUserByUserID(userID string, principal apimgmtv3.Principal) (*apimgmtv3.User, error) { + return nil, nil +} +func (f *fakeUserManager) CreateNewUserClusterRoleBinding(userName string, userUID apitypes.UID) error { + return nil +} +func (f *fakeUserManager) GetUserByPrincipalID(principalName string) (*apimgmtv3.User, error) { + return nil, nil +} +func (f *fakeUserManager) GetKubeconfigToken(clusterName, tokenName, description, kind, userName string, userPrincipal apimgmtv3.Principal) (*apimgmtv3.Token, string, error) { + return nil, "", nil +} + +// fakeAuthenticator implements requests.Authenticator for the purposes of testing +type fakeAuthenticator struct { + token apimgmtv3.Token + err error +} + +func (f *fakeAuthenticator) TokenFromRequest(req *http.Request) (*apimgmtv3.Token, error) { + if f.err != nil { + return nil, f.err + } + return &f.token, nil +} + +func (f *fakeAuthenticator) Authenticate(req *http.Request) (*requests.AuthenticatorResponse, error) { + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_rketemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_rketemplate.go new file mode 100644 index 0000000..cd5ab9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_rketemplate.go @@ -0,0 +1,219 @@ +package cluster + +import ( + "fmt" + "net/http" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "time" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + numberOfRetries = 3 + retryIntervalInMs = 5 +) + +func (a ActionHandler) saveAsTemplate(actionName string, action *types.Action, apiContext *types.APIContext) error { + + var err error + var clusterTemplate *v3.ClusterTemplate + var clusterTemplateRevision *v3.ClusterTemplateRevision + + defer a.cleanup(err, clusterTemplate) + + clusterTempName, clusterTempRevName, err := a.validateTemplateInput(apiContext) + if err != nil { + return err + } + + cluster, err := a.validateClusterState(apiContext) + if err != nil { + return err + } + + //Copy the cluster rke spec to a template and revision object + clusterTemplate, err = a.createNewClusterTemplate(apiContext, clusterTempName, cluster) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, + fmt.Sprintf("failed to create RKE Template object")) + } + + clusterTemplateRevision, err = a.createNewClusterTemplateRevision(apiContext, clusterTempRevName, clusterTemplate, cluster) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, + fmt.Sprintf("failed to create RKE Template Revision object")) + } + + err = a.updateCluster(apiContext, clusterTemplate, clusterTemplateRevision) + if err != nil { + return err + } + + response := map[string]interface{}{ + "clusterTemplateName": ref.Ref(clusterTemplate), + "clusterTemplateRevisionName": ref.Ref(clusterTemplateRevision), + "type": "saveAsTemplateOutput", + } + + apiContext.WriteResponse(http.StatusOK, response) + return nil +} + +func (a ActionHandler) validateTemplateInput(apiContext *types.APIContext) (string, string, error) { + actionInput, err := parse.ReadBody(apiContext.Request) + if err != nil { + return "", "", err + } + clusterTempName, ok := actionInput["clusterTemplateName"].(string) + if !ok || len(clusterTempName) == 0 { + return "", "", httperror.NewAPIError(httperror.InvalidBodyContent, "must specify a name for the RKE Template") + } + clusterTempRevName, ok := actionInput["clusterTemplateRevisionName"].(string) + if !ok || len(clusterTempRevName) == 0 { + return "", "", httperror.NewAPIError(httperror.InvalidBodyContent, "must specify a name for the RKE Template Revision") + } + return clusterTempName, clusterTempRevName, nil +} + +func (a ActionHandler) validateClusterState(apiContext *types.APIContext) (*v3.Cluster, error) { + var clusterForAccessCheck mgmtclient.Cluster + var err error + + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &clusterForAccessCheck); err != nil { + return nil, httperror.NewAPIError(httperror.NotFound, + fmt.Sprintf("failed to get cluster by id %v", apiContext.ID)) + } + + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.NotFound, + fmt.Sprintf("cluster with id %v doesn't exist", apiContext.ID)) + } + + if cluster.DeletionTimestamp != nil { + return nil, httperror.NewAPIError(httperror.InvalidType, + fmt.Sprintf("cluster with id %v is being deleted", apiContext.ID)) + } + /*if !v3.ClusterConditionReady.IsTrue(cluster) { + return nil, httperror.WrapAPIError(err, httperror.ClusterUnavailable, + fmt.Sprintf("cluster with id %v is not ready", apiContext.ID)) + }*/ + return cluster, nil +} + +func (a ActionHandler) createNewClusterTemplate(apiContext *types.APIContext, clusterTempName string, cluster *v3.Cluster) (*v3.ClusterTemplate, error) { + creatorID := apiContext.Request.Header.Get("Impersonate-User") + newTemplateObj := a.newClusterTemplate(clusterTempName, cluster, creatorID) + return a.ClusterTemplateClient.Create(newTemplateObj) +} + +func (a ActionHandler) newClusterTemplate(clusterTempName string, cluster *v3.Cluster, creatorID string) *v3.ClusterTemplate { + return &v3.ClusterTemplate{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "ct-", + Namespace: namespace.GlobalNamespace, + Labels: map[string]string{ + "cattle.io/creator": "norman", + }, + Annotations: map[string]string{ + rbac.CreatorIDAnn: creatorID, + }, + }, + Spec: v32.ClusterTemplateSpec{ + DisplayName: clusterTempName, + Description: fmt.Sprintf("RKETemplate generated from cluster Id %v", cluster.Name), + }, + } +} + +func (a ActionHandler) createNewClusterTemplateRevision(apiContext *types.APIContext, clusterTempRevName string, clusterTemplate *v3.ClusterTemplate, cluster *v3.Cluster) (*v3.ClusterTemplateRevision, error) { + creatorID := apiContext.Request.Header.Get("Impersonate-User") + newTemplateRevObj := a.newClusterTemplateRevision(clusterTempRevName, cluster, clusterTemplate, creatorID) + return a.ClusterTemplateRevisionClient.Create(newTemplateRevObj) +} + +func (a ActionHandler) newClusterTemplateRevision(clusterTempRevisionName string, cluster *v3.Cluster, clusterTemplate *v3.ClusterTemplate, creatorID string) *v3.ClusterTemplateRevision { + controller := true + clusterConfig := cluster.Status.AppliedSpec.ClusterSpecBase.DeepCopy() + + return &v3.ClusterTemplateRevision{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "ctr-", + Namespace: namespace.GlobalNamespace, + OwnerReferences: []v1.OwnerReference{ + { + Name: clusterTemplate.Name, + UID: clusterTemplate.UID, + APIVersion: "management.cattle.io/v3", + Kind: "ClusterTemplate", + Controller: &controller, + }, + }, + Labels: map[string]string{ + "cattle.io/creator": "norman", + "io.cattle.field/clusterTemplateId": clusterTemplate.Name, + }, + Annotations: map[string]string{ + rbac.CreatorIDAnn: creatorID, + }, + }, + Spec: v32.ClusterTemplateRevisionSpec{ + DisplayName: clusterTempRevisionName, + ClusterTemplateName: ref.Ref(clusterTemplate), + ClusterConfig: clusterConfig, + }, + } +} + +func (a ActionHandler) updateCluster(apiContext *types.APIContext, clusterTemplate *v3.ClusterTemplate, clusterTemplateRevision *v3.ClusterTemplateRevision) error { + // Can't add either too many retries or longer interval as this an API handler + for i := 0; i < numberOfRetries; i++ { + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + logrus.Errorf("error fetching cluster with id %v: %v", apiContext.ID, err) + continue + } + updatedCluster := cluster.DeepCopy() + updatedCluster.Spec.ClusterTemplateRevisionName = ref.Ref(clusterTemplateRevision) + updatedCluster.Spec.ClusterTemplateName = ref.Ref(clusterTemplate) + + _, err = a.ClusterClient.Update(updatedCluster) + if err == nil { + return nil + } + time.Sleep(retryIntervalInMs * time.Millisecond) + } + return httperror.NewAPIError(httperror.Conflict, + fmt.Sprintf("Error while updating cluster %v with RKE Template Id %v and RKE TemplateRevision Id %v", apiContext.ID, clusterTemplate.Name, clusterTemplateRevision.Name)) +} + +func (a ActionHandler) cleanup(err error, clusterTemplate *v3.ClusterTemplate) { + if err == nil { + return + } + if clusterTemplate != nil { + for i := 0; i < numberOfRetries; i++ { + //delete the clusterTemplate created, any revision will be deleted due to owner-ref + deleteErr := a.ClusterTemplateClient.Delete(clusterTemplate.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("Failed to delete the RKE Template %v", clusterTemplate.Name) + continue + } + time.Sleep(retryIntervalInMs * time.Millisecond) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_yaml.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_yaml.go new file mode 100644 index 0000000..c02edce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/actions_yaml.go @@ -0,0 +1,211 @@ +package cluster + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/ghodss/yaml" + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + clusterclient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/generated/compose" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/kubectl" + "github.com/rancher/rancher/pkg/ref" + schema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + kerrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (a ActionHandler) ImportYamlHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + data, err := ioutil.ReadAll(apiContext.Request.Body) + if err != nil { + return errors.Wrap(err, "reading request body error") + } + + input := mgmtclient.ImportClusterYamlInput{} + if err = json.Unmarshal(data, &input); err != nil { + return errors.Wrap(err, "unmarshaling input error") + } + + var cluster mgmtclient.Cluster + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &cluster); err != nil { + return err + } + + cfg, err := a.generateKubeConfig(apiContext, &cluster) + if err != nil { + return err + } + for _, context := range cfg.Contexts { + if input.DefaultNamespace == "" { + context.Namespace = input.Namespace + } else { + context.Namespace = input.DefaultNamespace + } + } + + var msg []byte + if input.ProjectID != "" { + err = a.processYAML(apiContext, cluster.ID, input.ProjectID, input.YAML) + if err == nil { + msg, err = kubectl.Apply([]byte(input.YAML), cfg) + } + } else if input.Namespace == "" { + msg, err = kubectl.Apply([]byte(input.YAML), cfg) + } else { + msg, err = kubectl.ApplyWithNamespace([]byte(input.YAML), input.Namespace, cfg) + } + rtn := map[string]interface{}{ + "message": string(msg), + "type": "importYamlOutput", + } + if err == nil { + apiContext.WriteResponse(http.StatusOK, rtn) + } else { + if rtn["message"] == "" { + rtn["message"] = err.Error() + } + apiContext.WriteResponse(http.StatusBadRequest, rtn) + } + + return nil +} + +func (a ActionHandler) ExportYamlHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + cluster, err := a.ClusterClient.Get(apiContext.ID, v1.GetOptions{}) + if err != nil { + return err + } + + if cluster.Status.Driver != v32.ClusterDriverRKE { + return fmt.Errorf("cluster %v does not support being exported", cluster.Name) + } + + topkey := compose.Config{} + topkey.Version = "v3" + c := mgmtclient.Cluster{} + if err := convert.ToObj(cluster.Spec, &c); err != nil { + return err + } + topkey.Clusters = map[string]mgmtclient.Cluster{} + topkey.Clusters[cluster.Spec.DisplayName] = c + + // if driver is rancherKubernetesEngine, add any nodePool if found + if cluster.Status.Driver == v32.ClusterDriverRKE { + nodepools, err := a.NodepoolGetter.NodePools(cluster.Name).List(v1.ListOptions{}) + if err != nil { + return err + } + topkey.NodePools = map[string]mgmtclient.NodePool{} + for _, nodepool := range nodepools.Items { + n := mgmtclient.NodePool{} + if err := convert.ToObj(nodepool.Spec, &n); err != nil { + return err + } + n.ClusterID = cluster.Spec.DisplayName + namespace, id := ref.Parse(nodepool.Spec.NodeTemplateName) + nodeTemplate, err := a.NodeTemplateGetter.NodeTemplates(namespace).Get(id, v1.GetOptions{}) + if err != nil { + return err + } + n.NodeTemplateID = nodeTemplate.Spec.DisplayName + topkey.NodePools[nodepool.Name] = n + } + } + + m, err := convert.EncodeToMap(topkey) + if err != nil { + return err + } + delete(m["clusters"].(map[string]interface{})[cluster.Spec.DisplayName].(map[string]interface{}), "actions") + delete(m["clusters"].(map[string]interface{})[cluster.Spec.DisplayName].(map[string]interface{}), "links") + for name := range topkey.NodePools { + delete(m["nodePools"].(map[string]interface{})[name].(map[string]interface{}), "actions") + delete(m["nodePools"].(map[string]interface{})[name].(map[string]interface{}), "links") + } + + data, err := json.Marshal(m) + if err != nil { + return err + } + buf, err := yaml.JSONToYAML(data) + if err != nil { + return err + } + if apiContext.ResponseFormat == "yaml" { + reader := bytes.NewReader(buf) + apiContext.Response.Header().Set("Content-Type", "application/yaml") + http.ServeContent(apiContext.Response, apiContext.Request, "exportYaml", time.Now(), reader) + return nil + } + r := v32.ExportOutput{ + YAMLOutput: string(buf), + } + jsonOutput, err := json.Marshal(r) + if err != nil { + return err + } + reader := bytes.NewReader(jsonOutput) + apiContext.Response.Header().Set("Content-Type", "application/json") + http.ServeContent(apiContext.Response, apiContext.Request, "exportYaml", time.Now(), reader) + return nil +} + +func (a ActionHandler) processYAML(apiContext *types.APIContext, clusterName, projectName, inputYAML string) error { + namespaces, err := findNamespaceCreates(inputYAML) + if err != nil { + return err + } + + nsClient, err := a.findOrCreateProjectNamespaces(apiContext, namespaces, clusterName, projectName) + if err != nil { + return err + } + + waitForNS(nsClient, namespaces) + return nil +} + +func (a ActionHandler) findOrCreateProjectNamespaces(apiContext *types.APIContext, namespaces []string, clusterName, projectName string) (corev1.NamespaceInterface, error) { + userCtx, err := a.ClusterManager.UserContextNoControllers(clusterName) + if err != nil { + return nil, err + } + + nsClient := userCtx.Core.Namespaces("") + + for _, ns := range namespaces { + nsObj, err := nsClient.Get(ns, v1.GetOptions{}) + if kerrors.IsNotFound(err) { + apiContext.SubContext = map[string]string{ + "/v3/schemas/cluster": clusterName, + } + err := access.Create(apiContext, &schema.Version, clusterclient.NamespaceType, map[string]interface{}{ + clusterclient.NamespaceFieldName: ns, + clusterclient.NamespaceFieldProjectID: projectName, + }, nil) + if err != nil { + return nil, err + } + } else if err != nil { + return nil, err + } else if nsObj.Annotations[nslabels.ProjectIDFieldLabel] == projectName { + // nothing + } else { + return nil, fmt.Errorf("Namespace [%s] already exists in project [%s]", ns, nsObj.Annotations[nslabels.ProjectIDFieldLabel]) + } + } + + return nsClient, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/formatter.go new file mode 100644 index 0000000..1c67e7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/formatter.go @@ -0,0 +1,198 @@ +package cluster + +import ( + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/client-go/kubernetes/typed/authorization/v1" +) + +type Formatter struct { + KontainerDriverLister v3.KontainerDriverLister + nodeLister v3.NodeLister + clusterLister v3.ClusterLister + clusterSpecPwdFields map[string]interface{} + SubjectAccessReviewClient v1.SubjectAccessReviewInterface +} + +func NewFormatter(schemas *types.Schemas, managementContext *config.ScaledContext) *Formatter { + clusterFormatter := Formatter{ + KontainerDriverLister: managementContext.Management.KontainerDrivers("").Controller().Lister(), + nodeLister: managementContext.Management.Nodes("").Controller().Lister(), + clusterLister: managementContext.Management.Clusters("").Controller().Lister(), + clusterSpecPwdFields: gatherClusterSpecPwdFields(schemas, schemas.Schema(&managementschema.Version, client.ClusterSpecBaseType)), + SubjectAccessReviewClient: managementContext.K8sClient.AuthorizationV1().SubjectAccessReviews(), + } + return &clusterFormatter +} + +func (f *Formatter) Formatter(request *types.APIContext, resource *types.RawResource) { + if convert.ToBool(resource.Values["internal"]) { + delete(resource.Links, "remove") + } + shellLink := request.URLBuilder.Link("shell", resource) + shellLink = strings.Replace(shellLink, "http", "ws", 1) + shellLink = strings.Replace(shellLink, "/shell", "?shell=true", 1) + resource.Links["shell"] = shellLink + resource.AddAction(request, v32.ClusterActionGenerateKubeconfig) + resource.AddAction(request, v32.ClusterActionImportYaml) + + // If this is an RKE1 cluster only + if _, ok := resource.Values["rancherKubernetesEngineConfig"]; ok { + resource.AddAction(request, v32.ClusterActionExportYaml) + + // If a user has the backupetcd role/privilege, add it- In this case, the resource is the cluster, so use + // the ID as the namespace for the ETCD check since that's where the backups live + if _, ok := values.GetValue(resource.Values, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig"); ok && canBackupEtcd(request, resource.ID) { + resource.AddAction(request, v32.ClusterActionBackupEtcd) + } + + // If user has permissions to update the cluster + if canUpdateClusterWithValues(request, resource.Values) { + if _, ok := values.GetValue(resource.Values, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig"); ok { + resource.AddAction(request, v32.ClusterActionRestoreFromEtcdBackup) + } + resource.AddAction(request, v32.ClusterActionRotateCertificates) + if rotateEncryptionKeyEnabled(f.clusterLister, resource.ID) { + resource.AddAction(request, v32.ClusterActionRotateEncryptionKey) + } + + if val, ok := values.GetValue(resource.Values, "clusterTemplateRevisionId"); ok && val == nil { + if err := request.AccessControl.CanDo(v3.ClusterTemplateGroupVersionKind.Group, v3.ClusterTemplateResource.Name, "create", request, resource.Values, request.Schema); err == nil { + resource.AddAction(request, v32.ClusterActionSaveAsTemplate) + } + } + } + + } + + if gkeConfig, ok := resource.Values["googleKubernetesEngineConfig"]; ok && gkeConfig != nil { + configMap, ok := gkeConfig.(map[string]interface{}) + if !ok { + logrus.Errorf("could not convert gke config to map") + return + } + + setTrueIfNil(configMap, "enableStackdriverLogging") + setTrueIfNil(configMap, "enableStackdriverMonitoring") + setTrueIfNil(configMap, "enableHorizontalPodAutoscaling") + setTrueIfNil(configMap, "enableHttpLoadBalancing") + setTrueIfNil(configMap, "enableNetworkPolicyConfig") + } + + if eksConfig, ok := resource.Values["amazonElasticContainerServiceConfig"]; ok && eksConfig != nil { + configMap, ok := eksConfig.(map[string]interface{}) + if !ok { + logrus.Errorf("could not convert eks config to map") + return + } + + setTrueIfNil(configMap, "associateWorkerNodePublicIp") + setIntIfNil(configMap, "nodeVolumeSize", 20) + } + + if clusterTemplateAnswers, ok := resource.Values["answers"]; ok { + answerMap := convert.ToMapInterface(convert.ToMapInterface(clusterTemplateAnswers)["values"]) + hideClusterTemplateAnswers(answerMap, f.clusterSpecPwdFields) + + appliedAnswers := values.GetValueN(resource.Values, "appliedSpec", "answers") + + if appliedAnswers != nil { + appliedAnswerMap := convert.ToMapInterface(convert.ToMapInterface(appliedAnswers)["values"]) + hideClusterTemplateAnswers(appliedAnswerMap, f.clusterSpecPwdFields) + } + + failedAnswers := values.GetValueN(resource.Values, "failedSpec", "answers") + + if failedAnswers != nil { + failedAnswerMap := convert.ToMapInterface(convert.ToMapInterface(failedAnswers)["values"]) + hideClusterTemplateAnswers(failedAnswerMap, f.clusterSpecPwdFields) + } + } + + nodes, err := f.nodeLister.List(resource.ID, labels.Everything()) + if err != nil { + logrus.Warnf("error getting node list for cluster %s: %s", resource.ID, err) + } else { + resource.Values["nodeCount"] = len(nodes) + } +} + +// rotateEncryptionKeyEnabled returns true if the rotateEncryptionKey action should be enabled in the API view, otherwise, it returns false. +func rotateEncryptionKeyEnabled(clusterLister v3.ClusterLister, clusterName string) bool { + cluster, err := clusterLister.Get("", clusterName) + if err != nil { + return false + } + + // check that encryption is enabled on cluster + if cluster.Spec.RancherKubernetesEngineConfig == nil || + cluster.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig == nil || + !cluster.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.Enabled { + return false + } + + // Cluster should not be in updating + return v32.ClusterConditionUpdated.IsTrue(cluster) +} + +func setTrueIfNil(configMap map[string]interface{}, fieldName string) { + if configMap[fieldName] == nil { + configMap[fieldName] = true + } +} + +func setIntIfNil(configMap map[string]interface{}, fieldName string, replaceVal int) { + if configMap[fieldName] == nil { + configMap[fieldName] = replaceVal + } +} + +func hideClusterTemplateAnswers(answerMap map[string]interface{}, clusterSpecPwdFields map[string]interface{}) { + for key := range answerMap { + pwdVal := values.GetValueN(clusterSpecPwdFields, strings.Split(key, ".")...) + if pwdVal != nil { + //hide this answer + delete(answerMap, key) + } + } +} + +func (f *Formatter) CollectionFormatter(request *types.APIContext, collection *types.GenericCollection) { + collection.AddAction(request, "createFromTemplate") +} + +func gatherClusterSpecPwdFields(schemas *types.Schemas, schema *types.Schema) map[string]interface{} { + + data := map[string]interface{}{} + + for name, field := range schema.ResourceFields { + fieldType := field.Type + if strings.HasPrefix(fieldType, "array") { + fieldType = strings.Split(fieldType, "[")[1] + fieldType = fieldType[:len(fieldType)-1] + } + subSchema := schemas.Schema(&managementschema.Version, fieldType) + if subSchema != nil { + value := gatherClusterSpecPwdFields(schemas, subSchema) + if len(value) > 0 { + data[name] = value + } + } else { + if field.Type == "password" { + data[name] = "true" + } + } + } + + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/shell.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/shell.go new file mode 100644 index 0000000..9701516 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/shell.go @@ -0,0 +1,91 @@ +package cluster + +import ( + "encoding/base64" + "fmt" + "net/http" + "net/url" + "strconv" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + localprovider "github.com/rancher/rancher/pkg/auth/providers/local" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/user" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/transport" +) + +type ShellLinkHandler struct { + Proxy http.Handler + ClusterManager *clustermanager.Manager +} + +func (s *ShellLinkHandler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + context, err := s.ClusterManager.UserContextNoControllers(apiContext.ID) + if err != nil { + return err + } + userManager := context.Management.UserManager + + userID := userManager.GetUser(apiContext) + + var shellTTL int64 + if minutes, err := strconv.ParseInt(settings.AuthUserSessionTTLMinutes.Get(), 10, 64); err == nil { + shellTTL = minutes * 60 * 1000 // convert minutes to milliseconds + } + input := user.TokenInput{ + TokenName: "kubectl-shell-" + userID, + Description: "Access to kubectl shell in the browser", + Kind: "kubectl-shell", + UserName: userID, + AuthProvider: localprovider.Name, + TTL: &shellTTL, + Randomize: true, + } + token, err := userManager.EnsureToken(input) + if err != nil { + return err + } + cacerts := base64.StdEncoding.EncodeToString([]byte(settings.CACerts.Get())) + + pods, err := context.K8sClient.CoreV1().Pods("cattle-system").List(apiContext.Request.Context(), v1.ListOptions{ + LabelSelector: "app=cattle-agent", + }) + if err != nil { + return err + } + + for _, pod := range pods.Items { + if condition.Cond(corev1.PodReady).IsTrue(&pod) { + vars := url.Values{} + vars.Add("container", "agent") + vars.Add("stdout", "1") + vars.Add("stdin", "1") + vars.Add("stderr", "1") + vars.Add("tty", "1") + vars.Add("command", "kubectl-shell.sh") + vars.Add("command", token) + vars.Add("command", context.ClusterName) + vars.Add("command", cacerts) + + path := fmt.Sprintf("/k8s/clusters/%s/api/v1/namespaces/%s/pods/%s/exec", context.ClusterName, "cattle-system", pod.Name) + + req := apiContext.Request + req.URL.Path = path + req.URL.RawQuery = vars.Encode() + // we want to run this as a the system user + req.Header.Del(transport.ImpersonateUserHeader) + req.Header.Del(transport.ImpersonateGroupHeader) + req.Header.Del(transport.ImpersonateUserExtraHeaderPrefix) + + s.Proxy.ServeHTTP(apiContext.Response, req) + return nil + } + } + + return httperror.NewAPIError(httperror.NotFound, "failed to find kubectl pod") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/utils.go new file mode 100644 index 0000000..4c10443 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/utils.go @@ -0,0 +1,170 @@ +package cluster + +import ( + "bytes" + "context" + "encoding/json" + "io" + "io/ioutil" + "time" + + yaml2 "github.com/ghodss/yaml" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + authV1 "k8s.io/api/authorization/v1" + "k8s.io/apimachinery/pkg/api/meta" + v12 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/yaml" + clientauthv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/util/retry" +) + +type noopCloser struct { + io.Reader +} + +func (noopCloser) Close() error { + return nil +} + +func findNamespaceCreates(inputYAML string) ([]string, error) { + var namespaces []string + + reader := yaml.NewDocumentDecoder(noopCloser{Reader: bytes.NewBufferString(inputYAML)}) + for { + next, readErr := ioutil.ReadAll(reader) + if readErr != nil && readErr != io.ErrShortBuffer { + return nil, readErr + } + + obj := &unstructured.Unstructured{} + next, err := yaml2.YAMLToJSON(next) + if err != nil { + return nil, err + } + + err = json.Unmarshal(next, &obj.Object) + if err != nil { + return nil, err + } + + if obj.IsList() { + obj.EachListItem(func(obj runtime.Object) error { + metadata, err := meta.Accessor(obj) + if err != nil { + return err + } + if obj.GetObjectKind().GroupVersionKind().Kind == "Namespace" && obj.GetObjectKind().GroupVersionKind().Version == "v1" { + namespaces = append(namespaces, metadata.GetName()) + } + + if metadata.GetNamespace() != "" { + namespaces = append(namespaces, metadata.GetNamespace()) + } + return nil + }) + } else if obj.GetKind() == "Namespace" && obj.GetAPIVersion() == "v1" { + namespaces = append(namespaces, obj.GetName()) + if obj.GetNamespace() != "" { + namespaces = append(namespaces, obj.GetNamespace()) + } + } + + if readErr == nil { + break + } + } + + uniq := map[string]bool{} + var newNamespaces []string + for _, ns := range namespaces { + if !uniq[ns] { + uniq[ns] = true + newNamespaces = append(newNamespaces, ns) + } + } + + return newNamespaces, nil +} + +func waitForNS(nsClient v1.NamespaceInterface, namespaces []string) { + for i := 0; i < 3; i++ { + allGood := true + for _, ns := range namespaces { + ns, err := nsClient.Get(ns, v12.GetOptions{}) + if err != nil { + allGood = false + break + } + status := ns.Annotations["cattle.io/status"] + if status == "" { + allGood = false + break + } + nsMap := map[string]interface{}{} + err = json.Unmarshal([]byte(status), &nsMap) + if err != nil { + allGood = false + break + } + + foundCond := false + conds := convert.ToMapSlice(values.GetValueN(nsMap, "Conditions")) + for _, cond := range conds { + if cond["Type"] == "InitialRolesPopulated" && cond["Status"] == "True" { + foundCond = true + } + } + + if !foundCond { + allGood = false + } + } + + if allGood { + break + } else { + time.Sleep(2 * time.Second) + } + } +} + +func CanCreateRKETemplate(callerID string, subjectAccessReviewClient clientauthv1.SubjectAccessReviewInterface) (bool, error) { + review := authV1.SubjectAccessReview{ + Spec: authV1.SubjectAccessReviewSpec{ + User: callerID, + ResourceAttributes: &authV1.ResourceAttributes{ + Verb: "create", + Resource: "clustertemplates", + Group: "management.cattle.io", + }, + }, + } + + result, err := subjectAccessReviewClient.Create(context.TODO(), &review, v12.CreateOptions{}) + if err != nil { + return false, err + } + logrus.Debugf("CanCreateRKETemplate: %v", result) + return result.Status.Allowed, nil +} + +// updateClusterWithRetryOnConflict attempts to update the cluster with the changes encoded in the updateFunc. It only retries if a conflict error is returned. +func updateClusterWithRetryOnConflict(clusterClient v3.ClusterInterface, cluster *v3.Cluster, updateFunc func(*v3.Cluster) *v3.Cluster) error { + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + currentCluster, err := clusterClient.Get(cluster.Name, v12.GetOptions{}) + if err != nil { + return err + } + cluster = updateFunc(currentCluster) + if _, err = clusterClient.Update(cluster); err != nil { + return err + } + return nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/validator.go new file mode 100644 index 0000000..c7880ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cluster/validator.go @@ -0,0 +1,771 @@ +package cluster + +import ( + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2020-11-01/containerservice" + "github.com/Azure/go-autorest/autorest/to" + "github.com/aws/aws-sdk-go/aws" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/k3sbasedupgrade" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rancher/pkg/namespace" + mgmtSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Validator struct { + ClusterClient v3.ClusterInterface + ClusterLister v3.ClusterLister + ClusterTemplateLister v3.ClusterTemplateLister + ClusterTemplateRevisionLister v3.ClusterTemplateRevisionLister + Users v3.UserInterface + GrbLister v3.GlobalRoleBindingLister + GrLister v3.GlobalRoleLister +} + +func (v *Validator) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + var clusterSpec v32.ClusterSpec + var clientClusterSpec mgmtclient.Cluster + if err := convert.ToObj(data, &clusterSpec); err != nil { + return httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Cluster spec conversion error") + } + + if err := convert.ToObj(data, &clientClusterSpec); err != nil { + return httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Client cluster spec conversion error") + } + + if err := v.validateEnforcement(request, data); err != nil { + return err + } + + if err := v.validateLocalClusterAuthEndpoint(request, &clusterSpec); err != nil { + return err + } + + if err := v.validateK3sBasedVersionUpgrade(request, &clusterSpec); err != nil { + return err + } + + if err := v.validateGenericEngineConfig(request, &clusterSpec); err != nil { + return err + } + + if err := v.validateAKSConfig(request, data, &clusterSpec); err != nil { + return err + } + + if err := v.validateEKSConfig(request, data, &clusterSpec); err != nil { + return err + } + + return v.validateGKEConfig(request, data, &clusterSpec) +} + +func (v *Validator) validateLocalClusterAuthEndpoint(request *types.APIContext, spec *v32.ClusterSpec) error { + if !spec.LocalClusterAuthEndpoint.Enabled { + return nil + } + + var isValidCluster bool + if request.ID == "" { + isValidCluster = spec.RancherKubernetesEngineConfig != nil + } else { + cluster, err := v.ClusterLister.Get("", request.ID) + if err != nil { + return err + } + isValidCluster = cluster.Status.Driver == "" || + cluster.Status.Driver == v32.ClusterDriverRKE || + cluster.Status.Driver == v32.ClusterDriverImported || + cluster.Status.Driver == v32.ClusterDriverK3s || + cluster.Status.Driver == v32.ClusterDriverRke2 + } + if !isValidCluster { + return httperror.NewFieldAPIError(httperror.InvalidState, "LocalClusterAuthEndpoint.Enabled", "Can only enable LocalClusterAuthEndpoint with RKE, RKE2, or K3s") + } + + if spec.LocalClusterAuthEndpoint.CACerts != "" && spec.LocalClusterAuthEndpoint.FQDN == "" { + return httperror.NewFieldAPIError(httperror.MissingRequired, "LocalClusterAuthEndpoint.FQDN", "CACerts defined but FQDN is not defined") + } + + return nil +} + +func (v *Validator) validateEnforcement(request *types.APIContext, data map[string]interface{}) error { + + if !strings.EqualFold(settings.ClusterTemplateEnforcement.Get(), "true") { + return nil + } + + var spec mgmtclient.Cluster + if err := convert.ToObj(data, &spec); err != nil { + return httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Cluster spec conversion error") + } + + if !v.checkClusterForEnforcement(&spec) { + return nil + } + + ma := gaccess.MemberAccess{ + Users: v.Users, + GrLister: v.GrLister, + GrbLister: v.GrbLister, + } + + //if user is admin, no checks needed + callerID := request.Request.Header.Get(gaccess.ImpersonateUserHeader) + + isAdmin, err := ma.IsAdmin(callerID) + if err != nil { + return err + } + if isAdmin { + return nil + } + + //enforcement is true, template is a must + if spec.ClusterTemplateRevisionID == "" { + return httperror.NewFieldAPIError(httperror.MissingRequired, "", "A clusterTemplateRevision to create a cluster") + } + + err = v.accessTemplate(request, &spec) + if err != nil { + if httperror.IsForbidden(err) || httperror.IsNotFound(err) { + return httperror.NewAPIError(httperror.NotFound, "The clusterTemplateRevision is not found") + } + return err + } + + return nil +} + +// TODO: test validator +// prevents downgrades, no-ops, and upgrading before versions have been set +func (v *Validator) validateK3sBasedVersionUpgrade(request *types.APIContext, spec *v32.ClusterSpec) error { + upgradeNotReadyErr := httperror.NewAPIError(httperror.Conflict, "k3s version upgrade is not ready, try again later") + + if request.Method == http.MethodPost { + return nil + } + isK3s := spec.K3sConfig != nil + isrke2 := spec.Rke2Config != nil + if !isK3s && !isrke2 { + // only applies to k3s clusters + return nil + } + + // must wait for original spec version to be set + if (isK3s && spec.K3sConfig.Version == "") || (isrke2 && spec.Rke2Config.Version == "") { + return upgradeNotReadyErr + } + + cluster, err := v.ClusterLister.Get("", request.ID) + if err != nil { + return err + } + + if isK3s && cluster.Spec.K3sConfig == nil { + // prevents embedded cluster from have k3sConfig set. Embedded cluster cannot be upgraded. Non-embedded + // clusters' config will be set my controller. + return httperror.NewAPIError(httperror.InvalidBodyContent, "k3sConfig cannot be changed from nil") + } + + // must wait for original status version to be set + if cluster.Status.Version == nil { + return upgradeNotReadyErr + } + + var updateVersion string + if cluster.Status.Driver == v32.ClusterDriverRke2 { + updateVersion = spec.Rke2Config.Version + } else { + updateVersion = spec.K3sConfig.Version + } + + prevVersion := cluster.Status.Version.GitVersion + if prevVersion == updateVersion { + // no op + return nil + } + + isNewer, err := k3sbasedupgrade.IsNewerVersion(prevVersion, updateVersion) + if err != nil { + errMsg := fmt.Sprintf("unable to compare cluster version [%s]", updateVersion) + return httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + + if !isNewer { + // update version must be higher than previous version, downgrades are not supported + errMsg := fmt.Sprintf("cannot upgrade cluster version from [%s] to [%s]. New version must be higher.", prevVersion, updateVersion) + return httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + + return nil +} + +func (v *Validator) checkClusterForEnforcement(spec *mgmtclient.Cluster) bool { + if spec.RancherKubernetesEngineConfig != nil { + return true + } + + if spec.ClusterTemplateRevisionID != "" { + return true + } + return false +} + +func (v *Validator) accessTemplate(request *types.APIContext, spec *mgmtclient.Cluster) error { + split := strings.SplitN(spec.ClusterTemplateRevisionID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("error in splitting clusterTemplateRevision name %v", spec.ClusterTemplateRevisionID) + } + revName := split[1] + clusterTempRev, err := v.ClusterTemplateRevisionLister.Get(namespace.GlobalNamespace, revName) + if err != nil { + return err + } + + var ctMap map[string]interface{} + return access.ByID(request, &mgmtSchema.Version, mgmtclient.ClusterTemplateType, clusterTempRev.Spec.ClusterTemplateName, &ctMap) +} + +// validateGenericEngineConfig allows for additional validation of clusters that depend on Kontainer Engine or Rancher Machine driver +func (v *Validator) validateGenericEngineConfig(request *types.APIContext, spec *v32.ClusterSpec) error { + + if request.Method == http.MethodPost { + return nil + } + + if spec.AmazonElasticContainerServiceConfig != nil { + // compare with current cluster + clusterName := request.ID + prevCluster, err := v.ClusterLister.Get("", clusterName) + if err != nil { + return err + } + + err = validateEKS(*prevCluster.Spec.GenericEngineConfig, *spec.AmazonElasticContainerServiceConfig) + if err != nil { + return err + } + } + + return nil + +} + +func (v *Validator) validateAKSConfig(request *types.APIContext, cluster map[string]interface{}, clusterSpec *v32.ClusterSpec) error { + aksConfig, ok := cluster["aksConfig"].(map[string]interface{}) + if !ok { + return nil + } + + var prevCluster *v3.Cluster + + if request.Method == http.MethodPut { + var err error + prevCluster, err = v.ClusterLister.Get("", request.ID) + if err != nil { + return err + } + } + + // check user's access to cloud credential + if azureCredential, ok := aksConfig["azureCredentialSecret"].(string); ok && (prevCluster == nil || azureCredential != prevCluster.Spec.AKSConfig.AzureCredentialSecret) { + // Only check that the user has access to the credential if the credential is being changed. + if err := validateCredentialAuth(request, azureCredential); err != nil { + return err + } + } + + if err := v.validateAKSNetworkPolicy(clusterSpec, prevCluster); err != nil { + return err + } + + createFromImport := request.Method == http.MethodPost && aksConfig["imported"] == true + + if !createFromImport { + if err := validateAKSKubernetesVersion(clusterSpec, prevCluster); err != nil { + return err + } + if err := validateAKSNodePools(clusterSpec); err != nil { + return err + } + } + + if request.Method != http.MethodPost { + return nil + } + + // validation for creates only + if err := validateAKSClusterName(v.ClusterClient, clusterSpec); err != nil { + return err + } + + region, regionOk := aksConfig["resourceLocation"] + if !regionOk || region == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must provide region") + } + + return nil +} + +// validateAKSKubernetesVersion checks whether a kubernetes version is provided +func validateAKSKubernetesVersion(spec *v32.ClusterSpec, prevCluster *v3.Cluster) error { + clusterVersion := spec.AKSConfig.KubernetesVersion + if clusterVersion == nil { + return nil + } + + if to.String(clusterVersion) == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "cluster kubernetes version cannot be empty string") + } + + return nil +} + +// validateAKSNodePools checks whether a given NodePool version is empty or not supported. +// More involved validation is performed in the aks-operator. +func validateAKSNodePools(spec *v32.ClusterSpec) error { + nodePools := spec.AKSConfig.NodePools + if nodePools == nil { + return nil + } + if len(nodePools) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must have at least one nodepool") + } + + for _, np := range nodePools { + name := np.Name + if to.String(name) == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "nodePool Name cannot be an empty string") + } + if np.OsType == "Windows" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "windows node pools are not supported") + } + } + + return nil +} + +func validateAKSClusterName(client v3.ClusterInterface, spec *v32.ClusterSpec) error { + // validate cluster does not reference an AKS cluster that is already backed by a Rancher cluster + name := spec.AKSConfig.ClusterName + region := spec.AKSConfig.ResourceLocation + msgSuffix := fmt.Sprintf("in region [%s]", region) + + // cluster client is being used instead of lister to avoid the use of an outdated cache + clusters, err := client.List(metav1.ListOptions{}) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, "failed to confirm clusterName is unique among Rancher AKS clusters "+msgSuffix) + } + + for _, cluster := range clusters.Items { + if cluster.Spec.AKSConfig == nil { + continue + } + if name != cluster.Spec.AKSConfig.ClusterName { + continue + } + if region != "" && region != cluster.Spec.AKSConfig.ResourceLocation { + continue + } + + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("cluster already exists for AKS cluster [%s] "+msgSuffix, name)) + } + return nil +} + +// validateAKSNetworkPolicy performs validation around setting enableNetworkPolicy on AKS clusters which turns on Project Network Isolation +func (v *Validator) validateAKSNetworkPolicy(clusterSpec *v32.ClusterSpec, prevCluster *v3.Cluster) error { + // determine if network policy is enabled on the AKS cluster by checking the cluster spec and then the upstream spec if the field is nil (unmanaged) + var networkPolicy string + if clusterSpec.AKSConfig != nil && clusterSpec.AKSConfig.NetworkPolicy != nil { + networkPolicy = *clusterSpec.AKSConfig.NetworkPolicy + } else if prevCluster != nil && prevCluster.Status.AKSStatus.UpstreamSpec != nil && prevCluster.Status.AKSStatus.UpstreamSpec.NetworkPolicy != nil { + networkPolicy = *prevCluster.Status.AKSStatus.UpstreamSpec.NetworkPolicy + } else { + return nil + } + + // network policy enabled on the AKS cluster is a prerequisite for PNI + if to.Bool(clusterSpec.EnableNetworkPolicy) && networkPolicy != string(containerservice.NetworkPolicyAzure) && networkPolicy != string(containerservice.NetworkPolicyCalico) { + return httperror.NewAPIError( + httperror.InvalidBodyContent, + "Network Policy support must be enabled on AKS cluster in order to enable Project Network Isolation", + ) + } + + return nil +} + +func (v *Validator) validateEKSConfig(request *types.APIContext, cluster map[string]interface{}, clusterSpec *v32.ClusterSpec) error { + eksConfig, ok := cluster["eksConfig"].(map[string]interface{}) + if !ok { + return nil + } + + var prevCluster *v3.Cluster + + if request.Method == http.MethodPut { + var err error + prevCluster, err = v.ClusterLister.Get("", request.ID) + if err != nil { + return err + } + } + + // check user's access to cloud credential + if amazonCredential, ok := eksConfig["amazonCredentialSecret"].(string); ok && (prevCluster == nil || amazonCredential != prevCluster.Spec.EKSConfig.AmazonCredentialSecret) { + // Only check that the user has access to the credential if the credential is being changed. + if err := validateCredentialAuth(request, amazonCredential); err != nil { + return err + } + } + + createFromImport := request.Method == http.MethodPost && eksConfig["imported"] == true + + if !createFromImport { + if err := validateEKSKubernetesVersion(clusterSpec, prevCluster); err != nil { + return err + } + if err := validateEKSNodegroups(clusterSpec); err != nil { + return err + } + if err := validateEKSAccess(request, eksConfig, prevCluster); err != nil { + return err + } + } + + if request.Method != http.MethodPost { + return nil + } + + // validation for creates only + + // validate cluster does not reference an EKS cluster that is already backed by a Rancher cluster + name, _ := eksConfig["displayName"] + region, _ := eksConfig["region"] + + // cluster client is being used instead of lister to avoid the use of an outdated cache + clusters, err := v.ClusterClient.List(metav1.ListOptions{}) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("failed to confirm displayName is unique among Rancher EKS clusters for region %s", region)) + } + + for _, cluster := range clusters.Items { + if cluster.Spec.EKSConfig == nil { + continue + } + if name != cluster.Spec.EKSConfig.DisplayName { + continue + } + if region != cluster.Spec.EKSConfig.Region { + continue + } + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("cluster already exists for EKS cluster [%s] in region [%s]", name, region)) + } + + if !createFromImport { + // If security groups are provided, then subnets must also be provided + securityGroups, _ := eksConfig["securityGroups"].([]interface{}) + subnets, _ := eksConfig["subnets"].([]interface{}) + + if len(securityGroups) != 0 && len(subnets) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, + "subnets must be provided if security groups are provided") + } + } + + return nil +} + +func validateEKSAccess(request *types.APIContext, eksConfig map[string]interface{}, prevCluster *v3.Cluster) error { + publicAccess, _ := eksConfig["publicAccess"] + privateAccess, _ := eksConfig["privateAccess"] + if request.Method != http.MethodPost { + if publicAccess == nil { + publicAccess = prevCluster.Spec.EKSConfig.PublicAccess + } + if privateAccess == nil { + privateAccess = prevCluster.Spec.EKSConfig.PrivateAccess + } + } + + // can only perform comparisons on interfaces, cannot use as bool + if publicAccess == false && privateAccess == false { + return httperror.NewAPIError(httperror.InvalidBodyContent, + "public access, private access, or both must be enabled") + } + return nil +} + +// validateEKSKubernetesVersion checks whether a kubernetes version is provided and if it is supported +func validateEKSKubernetesVersion(spec *v32.ClusterSpec, prevCluster *v3.Cluster) error { + clusterVersion := spec.EKSConfig.KubernetesVersion + if clusterVersion == nil { + return nil + } + + if aws.StringValue(clusterVersion) == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "cluster kubernetes version cannot be empty string") + } + + return nil +} + +// validateCredentialAuth validates that a user has access to the credential they are setting. +func validateCredentialAuth(request *types.APIContext, credential string) error { + var accessCred mgmtclient.CloudCredential + credentialErr := "error accessing cloud credential" + if err := access.ByID(request, &mgmtSchema.Version, mgmtclient.CloudCredentialType, credential, &accessCred); err != nil { + return httperror.NewAPIError(httperror.NotFound, credentialErr) + } + return nil +} + +// validateEKSNodegroups checks whether a given nodegroup version is empty or not supported. +// More involved validation is performed in the EKS-operator. +func validateEKSNodegroups(spec *v32.ClusterSpec) error { + nodegroups := spec.EKSConfig.NodeGroups + if nodegroups == nil { + return nil + } + if len(nodegroups) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("must have at least one nodegroup")) + } + + var errors []string + + for _, ng := range nodegroups { + name := aws.StringValue(ng.NodegroupName) + if name == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("nodegroupName cannot be an empty")) + } + + version := ng.Version + if version == nil { + continue + } + if aws.StringValue(version) == "" { + errors = append(errors, fmt.Sprintf("nodegroup [%s] version cannot be empty string", name)) + continue + } + } + + if len(errors) != 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf(strings.Join(errors, ";"))) + } + return nil +} + +func validateEKS(prevCluster, newCluster map[string]interface{}) error { + // check config is for EKS clusters + if driver, ok := prevCluster["driverName"]; ok { + if driver != service.AmazonElasticContainerServiceDriverName { + return nil + } + } + + // don't allow for updating subnets + prev, _ := prevCluster["subnets"].([]interface{}) + new, _ := newCluster["subnets"].([]interface{}) + if len(prev) == 0 && len(new) == 0 { + // should treat empty and nil as equal + return nil + } + if !reflect.DeepEqual(prev, new) { + return httperror.NewAPIError(httperror.InvalidBodyContent, "cannot modify EKS subnets after creation") + } + return nil +} + +func (v *Validator) validateGKEConfig(request *types.APIContext, cluster map[string]interface{}, clusterSpec *v32.ClusterSpec) error { + gkeConfig, ok := cluster["gkeConfig"].(map[string]interface{}) + if !ok { + return nil + } + + var prevCluster *v3.Cluster + if request.Method == http.MethodPut { + var err error + prevCluster, err = v.ClusterLister.Get("", request.ID) + if err != nil { + return err + } + } + + // check user's access to cloud credential + if googleCredential, ok := gkeConfig["googleCredentialSecret"].(string); ok && (prevCluster == nil || googleCredential != prevCluster.Spec.GKEConfig.GoogleCredentialSecret) { + // Only check that the user has access to the credential if the credential is being changed. + if err := validateCredentialAuth(request, googleCredential); err != nil { + return err + } + } + + if err := v.validateGKENetworkPolicy(clusterSpec, prevCluster); err != nil { + return err + } + + createFromImport := request.Method == http.MethodPost && gkeConfig["imported"] == true + if !createFromImport { + if err := validateGKEKubernetesVersion(clusterSpec, prevCluster); err != nil { + return err + } + if err := validateGKENodePools(clusterSpec); err != nil { + return err + } + } + + if request.Method != http.MethodPost { + return nil + } + + // validation for creates only + + if err := validateGKEClusterName(v.ClusterClient, clusterSpec); err != nil { + return err + } + + if err := validateGKEPrivateClusterConfig(clusterSpec); err != nil { + return err + } + + region, regionOk := gkeConfig["region"] + zone, zoneOk := gkeConfig["zone"] + if (!regionOk || region == "") && (!zoneOk || zone == "") { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must provide region or zone") + } + + return nil +} + +// validateGKENetworkPolicy performs validation around setting enableNetworkPolicy on GKE clusters which turns on Project Network Isolation +func (v *Validator) validateGKENetworkPolicy(clusterSpec *v32.ClusterSpec, prevCluster *v3.Cluster) error { + // determine if network policy is enabled on the GKE cluster by checking the cluster spec and then the upstream spec if the field is nil (unmanaged) + var netPolEnabled bool + if clusterSpec.GKEConfig != nil && clusterSpec.GKEConfig.NetworkPolicyEnabled != nil { + netPolEnabled = *clusterSpec.GKEConfig.NetworkPolicyEnabled + } else if prevCluster != nil && prevCluster.Status.GKEStatus.UpstreamSpec != nil && prevCluster.Status.GKEStatus.UpstreamSpec.NetworkPolicyEnabled != nil { + netPolEnabled = *prevCluster.Status.GKEStatus.UpstreamSpec.NetworkPolicyEnabled + } else { + return nil + } + + // network policy enabled on the GKE cluster is a prerequisite for PNI + if to.Bool(clusterSpec.EnableNetworkPolicy) && !netPolEnabled { + return httperror.NewAPIError( + httperror.InvalidBodyContent, + "Network Policy support must be enabled on GKE cluster in order to enable Project Network Isolation", + ) + } + + return nil +} + +// validateGKEKubernetesVersion checks whether a kubernetes version is provided and if it is supported +func validateGKEKubernetesVersion(spec *v32.ClusterSpec, prevCluster *v3.Cluster) error { + clusterVersion := spec.GKEConfig.KubernetesVersion + if clusterVersion == nil { + return nil + } + + if *clusterVersion == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, "cluster kubernetes version cannot be empty string") + } + + return nil +} + +// validateGKENodePools checks whether a given node pool version is empty or not supported. +func validateGKENodePools(spec *v32.ClusterSpec) error { + nodepools := spec.GKEConfig.NodePools + if nodepools == nil { + return nil + } + if len(nodepools) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("must have at least one node pool")) + } + + var errors []string + hasRequiredLinuxPool := false + + for _, np := range nodepools { + if np.Name == nil || *np.Name == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("node pool name cannot be empty")) + } + + version := np.Version + if version == nil || *version == "" { + errors = append(errors, fmt.Sprintf("node pool [%s] version cannot be empty", *np.Name)) + continue + } + + // Windows images are WINDOWS_LTSC or WINDOWS_SAC. The cluster must have at least one non-Windows node pool. + if !hasRequiredLinuxPool && !strings.Contains(strings.ToLower(np.Config.ImageType), "windows") { + hasRequiredLinuxPool = true + } + } + + if !hasRequiredLinuxPool { + errors = append(errors, fmt.Sprintf("at least 1 Linux node pool is required")) + } + + if len(errors) != 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf(strings.Join(errors, ";"))) + } + return nil +} + +func validateGKEClusterName(client v3.ClusterInterface, spec *v32.ClusterSpec) error { + // validate cluster does not reference an GKE cluster that is already backed by a Rancher cluster + name := spec.GKEConfig.ClusterName + region := spec.GKEConfig.Region + zone := spec.GKEConfig.Zone + msgSuffix := fmt.Sprintf("in region [%s]", region) + if region == "" { + msgSuffix = fmt.Sprintf("in zone [%s]", spec.GKEConfig.Zone) + } + + // cluster client is being used instead of lister to avoid the use of an outdated cache + clusters, err := client.List(metav1.ListOptions{}) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, "failed to confirm clusterName is unique among Rancher GKE clusters "+msgSuffix) + } + + for _, cluster := range clusters.Items { + if cluster.Spec.GKEConfig == nil { + continue + } + if name != cluster.Spec.GKEConfig.ClusterName { + continue + } + if region != "" && region != cluster.Spec.GKEConfig.Region { + continue + } + if zone != "" && zone != cluster.Spec.GKEConfig.Zone { + continue + } + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("cluster already exists for GKE cluster [%s] "+msgSuffix, name)) + } + return nil +} + +func validateGKEPrivateClusterConfig(spec *v32.ClusterSpec) error { + if spec.GKEConfig.PrivateClusterConfig != nil && spec.GKEConfig.PrivateClusterConfig.EnablePrivateEndpoint && !spec.GKEConfig.PrivateClusterConfig.EnablePrivateNodes { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("private endpoint requires private nodes")) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clusterregistrationtokens/import.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clusterregistrationtokens/import.go new file mode 100644 index 0000000..d7660b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clusterregistrationtokens/import.go @@ -0,0 +1,54 @@ +package clusterregistrationtokens + +import ( + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/norman/types" + "github.com/rancher/norman/urlbuilder" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ClusterImport struct { + Clusters v3.ClusterInterface +} + +func (ch *ClusterImport) ClusterImportHandler(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("Content-Type", "text/plain") + token := mux.Vars(req)["token"] + clusterID := mux.Vars(req)["clusterId"] + + urlBuilder, err := urlbuilder.New(req, schema.Version, types.NewSchemas()) + if err != nil { + resp.WriteHeader(500) + resp.Write([]byte(err.Error())) + return + } + url := settings.ServerURL.Get() + if url == "" { + url = urlBuilder.RelativeToRoot("") + } + + authImage := "" + authImages := req.URL.Query()["authImage"] + if len(authImages) > 0 { + authImage = authImages[0] + } + + var cluster *apimgmtv3.Cluster + if clusterID != "" { + cluster, _ = ch.Clusters.Get(clusterID, metav1.GetOptions{}) + } + + if err = systemtemplate.SystemTemplate(resp, image.Resolve(settings.AgentImage.Get()), authImage, "", token, url, + false, cluster, nil, nil, nil); err != nil { + resp.WriteHeader(500) + resp.Write([]byte(err.Error())) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/cluster_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/cluster_template.go new file mode 100644 index 0000000..0f36c3b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/cluster_template.go @@ -0,0 +1,233 @@ +package clustertemplate + +import ( + "net/http" + "sort" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "encoding/json" + "fmt" + + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +const ( + enableRevisionAction = "enable" + disableRevisionAction = "disable" +) + +type Wrapper struct { + ClusterTemplates v3.ClusterTemplateInterface + ClusterTemplateLister v3.ClusterTemplateLister + ClusterTemplateRevisionLister v3.ClusterTemplateRevisionLister + ClusterTemplateRevisions v3.ClusterTemplateRevisionInterface + ClusterTemplateQuestions []v32.Question +} + +func (w Wrapper) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + resource.Links["revisions"] = apiContext.URLBuilder.Link("revisions", resource) +} + +func (w Wrapper) RevisionFormatter(apiContext *types.APIContext, resource *types.RawResource) { + + if err := apiContext.AccessControl.CanDo(v3.ClusterTemplateRevisionGroupVersionKind.Group, v3.ClusterTemplateRevisionResource.Name, "update", apiContext, resource.Values, apiContext.Schema); err == nil { + if convert.ToBool(resource.Values["enabled"]) { + resource.AddAction(apiContext, disableRevisionAction) + } else { + resource.AddAction(apiContext, enableRevisionAction) + } + } +} + +func (w Wrapper) CollectionFormatter(request *types.APIContext, collection *types.GenericCollection) { + collection.AddAction(request, "listquestions") +} + +func (w Wrapper) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "revisions": + var template client.ClusterTemplate + if err := access.ByID(apiContext, &managementschema.Version, client.ClusterTemplateType, apiContext.ID, &template); err != nil { + return err + } + conditions := []*types.QueryCondition{ + types.NewConditionFromString(client.ClusterTemplateRevisionFieldClusterTemplateID, types.ModifierEQ, []string{template.ID}...), + } + var templateVersions []map[string]interface{} + if err := access.List(apiContext, &managementschema.Version, client.ClusterTemplateRevisionType, &types.QueryOptions{Conditions: conditions}, &templateVersions); err != nil { + return err + } + sort.SliceStable(templateVersions, func(i, j int) bool { + val1, err := time.Parse(time.RFC3339, convert.ToString(values.GetValueN(templateVersions[i], "created"))) + if err != nil { + logrus.Infof("error parsing time %v", err) + } + val2, err := time.Parse(time.RFC3339, convert.ToString(values.GetValueN(templateVersions[j], "created"))) + if err != nil { + logrus.Infof("error parsing time %v", err) + } + return val1.After(val2) + }) + apiContext.Type = client.ClusterTemplateRevisionType + apiContext.WriteResponse(http.StatusOK, templateVersions) + return nil + } + return nil +} + +func (w Wrapper) ClusterTemplateRevisionsActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + + canUpdateClusterTemplateRevision := func() bool { + revision := map[string]interface{}{ + "id": apiContext.ID, + } + + return apiContext.AccessControl.CanDo(v3.ClusterTemplateRevisionGroupVersionKind.Group, v3.ClusterTemplateRevisionResource.Name, "update", apiContext, revision, apiContext.Schema) == nil + } + + switch actionName { + case "disable": + if !canUpdateClusterTemplateRevision() { + return httperror.NewAPIError(httperror.PermissionDenied, "can not access clusterTemplateRevision") + } + return w.updateEnabledFlagOnRevision(apiContext, false) + case "enable": + if !canUpdateClusterTemplateRevision() { + return httperror.NewAPIError(httperror.PermissionDenied, "can not access clusterTemplateRevision") + } + return w.updateEnabledFlagOnRevision(apiContext, true) + case "listquestions": + return w.listRevisionQuestions(actionName, action, apiContext) + + } + return httperror.NewAPIError(httperror.NotFound, "not found") +} + +func (w Wrapper) updateEnabledFlagOnRevision(apiContext *types.APIContext, enabledFlag bool) error { + + revision, err := w.loadRevision(apiContext) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "failed to load clusterTemplateRevision") + } + + if revision.Spec.Enabled != nil && enabledFlag == *revision.Spec.Enabled { + apiContext.WriteResponse(http.StatusNoContent, map[string]interface{}{}) + return nil + } + revisionCopy := revision.DeepCopy() + revisionCopy.Spec.Enabled = &enabledFlag + _, err = w.ClusterTemplateRevisions.Update(revisionCopy) + + if err != nil { + //if conflict update, retry by loading from the store + if apierrors.IsConflict(err) { + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + revisionFromStore, err := w.ClusterTemplateRevisions.GetNamespaced(namespace.GlobalNamespace, revision.ObjectMeta.Name, v1.GetOptions{}) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "failed to load clusterTemplateRevision from store") + } + revisionStoreCopy := revisionFromStore.DeepCopy() + revisionStoreCopy.Spec.Enabled = &enabledFlag + + _, err = w.ClusterTemplateRevisions.Update(revisionStoreCopy) + return err + }) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, fmt.Sprintf("failed to set enabled flag to %v on clusterTemplateRevision", enabledFlag)) + } + return nil + } + return httperror.WrapAPIError(err, httperror.ServerError, fmt.Sprintf("failed to set enabled flag to %v on clusterTemplateRevision", enabledFlag)) + } + + apiContext.WriteResponse(http.StatusNoContent, map[string]interface{}{}) + return nil +} + +func (w Wrapper) loadRevision(apiContext *types.APIContext) (*v3.ClusterTemplateRevision, error) { + //load the templaterevision + split := strings.SplitN(apiContext.ID, ":", 2) + if len(split) != 2 { + return nil, httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("error in splitting clusterTemplateRevision name %v", apiContext.ID)) + } + revisionName := split[1] + + revision, err := w.ClusterTemplateRevisionLister.Get(namespace.GlobalNamespace, revisionName) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.NotFound, "clusterTemplateRevision is not found") + } + if revision.DeletionTimestamp != nil { + return nil, httperror.NewAPIError(httperror.InvalidType, "clusterTemplateRevision is marked for deletion") + } + return revision, nil +} + +func (w Wrapper) listRevisionQuestions(actionName string, action *types.Action, apiContext *types.APIContext) error { + questionsOutput := v32.ClusterTemplateQuestionsOutput{} + + if len(w.ClusterTemplateQuestions) == 0 { + w.ClusterTemplateQuestions = w.BuildQuestionsFromSchema(apiContext.Schemas.Schema(&managementschema.Version, client.ClusterSpecBaseType), apiContext.Schemas, "") + } + questionsOutput.Questions = w.ClusterTemplateQuestions + res, err := json.Marshal(questionsOutput) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, fmt.Sprintf("Error marshalling the Cluster Template questions output, %v", err)) + } + apiContext.Response.Write(res) + + return nil +} + +func (w Wrapper) BuildQuestionsFromSchema(schema *types.Schema, schemas *types.Schemas, pathTofield string) []v32.Question { + questions := []v32.Question{} + for name, field := range schema.ResourceFields { + fieldType := field.Type + if strings.HasPrefix(fieldType, "array") { + fieldType = strings.Split(fieldType, "[")[1] + fieldType = fieldType[:len(fieldType)-1] + } + checkSchema := schemas.Schema(&managementschema.Version, fieldType) + if checkSchema != nil { + subPath := name + if pathTofield != "" { + subPath = pathTofield + "." + name + } + subQuestions := w.BuildQuestionsFromSchema(checkSchema, schemas, subPath) + if len(subQuestions) > 0 { + questions = append(questions, subQuestions...) + } + } else { + //add a Question + newQuestion := v32.Question{} + if field.Type == "password" { + newQuestion.Group = "password" + } + newQuestion.Variable = name + if pathTofield != "" { + newQuestion.Variable = pathTofield + "." + name + } + newQuestion.Type = fieldType + newQuestion.Description = field.Description + newQuestion.Default = convert.ToString(field.Default) + newQuestion.Required = field.Required + questions = append(questions, newQuestion) + } + } + return questions +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/utils.go new file mode 100644 index 0000000..f6264ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/clustertemplate/utils.go @@ -0,0 +1,39 @@ +package clustertemplate + +import ( + "fmt" + "strconv" + "strings" + + "github.com/blang/semver" + "github.com/rancher/norman/httperror" +) + +const ( + RKEConfigK8sVersion = "rancherKubernetesEngineConfig.kubernetesVersion" +) + +func CheckKubernetesVersionFormat(k8sVersion string) (bool, error) { + if !strings.Contains(k8sVersion, "-rancher") { + errMsg := fmt.Sprintf("Requested kubernetesVersion %v is not of valid semver [major.minor.patch] format", k8sVersion) + vparts := strings.Split(k8sVersion, ".") + if len(vparts) != 3 { + return false, httperror.NewAPIError(httperror.InvalidFormat, errMsg) + } + for _, part := range vparts[:2] { + //part should be a numeric value + if _, err := strconv.Atoi(part); err != nil { + return false, httperror.NewAPIError(httperror.InvalidFormat, errMsg) + } + } + _, err := semver.ParseRange("=" + k8sVersion) + if err != nil { + return false, httperror.NewAPIError(httperror.InvalidFormat, errMsg) + } + + if vparts[2] == "x" { + return true, nil + } + } + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cred/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cred/store.go new file mode 100644 index 0000000..74b6d68 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/cred/store.go @@ -0,0 +1,109 @@ +package cred + +import ( + "encoding/base64" + "fmt" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/api/norman/customization/namespacedresource" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + provv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "k8s.io/apimachinery/pkg/labels" +) + +func Wrap(store types.Store, ns v1.NamespaceInterface, nodeTemplateLister v3.NodeTemplateLister, provClusterCache provv1.ClusterCache) types.Store { + transformStore := &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + if configExists(data) { + data["type"] = "cloudCredential" + if err := decodeNonPasswordFields(data); err != nil { + return nil, err + } + return data, nil + } + return nil, nil + }, + } + + newStore := &Store{ + Store: transformStore, + NodeTemplateLister: nodeTemplateLister, + ProvClusterCache: provClusterCache, + } + + return namespacedresource.Wrap(newStore, ns, namespace.GlobalNamespace) +} + +func configExists(data map[string]interface{}) bool { + for key, val := range data { + if strings.HasSuffix(key, "Config") { + if convert.ToString(val) != "" { + return true + } + } + } + return false +} + +func decodeNonPasswordFields(data map[string]interface{}) error { + for key, val := range data { + if strings.HasSuffix(key, "Config") { + ans := convert.ToMapInterface(val) + for field, value := range ans { + decoded, err := base64.StdEncoding.DecodeString(convert.ToString(value)) + if err != nil { + return err + } + ans[field] = string(decoded) + } + } + } + return nil +} + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if !configExists(data) { + return httperror.NewAPIError(httperror.MissingRequired, "a Config field must be set") + } + + return nil +} + +type Store struct { + types.Store + NodeTemplateLister v3.NodeTemplateLister + ProvClusterCache provv1.ClusterCache +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + // make sure the credential isn't being used by an active RKE2/K3s cluster + if provClusters, err := s.ProvClusterCache.GetByIndex(cluster.ByCloudCred, id); err != nil { + return nil, httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("An error was encountered while attempting to delete the cloud credential: %s", err)) + } else if len(provClusters) > 0 { + return nil, httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Cloud credential is currently referenced by provisioning cluster %s", provClusters[0].Name)) + } + + // make sure the cloud credential isn't being used by an RKE1 node template + // which may be used by an active cluster + nodeTemplates, err := s.NodeTemplateLister.List("", labels.NewSelector()) + if err != nil { + return nil, err + } + if len(nodeTemplates) > 0 { + for _, template := range nodeTemplates { + if template.Spec.CloudCredentialName != id { + continue + } + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("Cloud credential is currently referenced by node template %s", template.Name)) + } + } + return s.Store.Delete(apiContext, schema, id) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/etcdbackup/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/etcdbackup/formatter.go new file mode 100644 index 0000000..99c557f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/etcdbackup/formatter.go @@ -0,0 +1,21 @@ +package etcdbackup + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + state := convert.ToString(resource.Values["state"]) + if state == "activating" { + for _, cond := range convert.ToMapSlice(values.GetValueN(resource.Values, "status", "conditions")) { + if cond["type"] == "Completed" { + if cond["status"] == "False" && convert.ToString(cond["reason"]) == "Error" { + resource.Values["state"] = "failed" + } + break + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature.go new file mode 100644 index 0000000..96de06b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature.go @@ -0,0 +1,74 @@ +package feature + +import ( + "fmt" + "net/http" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +type Validator struct { + FeatureLister v3.FeatureLister +} + +func (v *Validator) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method == http.MethodPost { + return httperror.NewAPIError(httperror.MethodNotAllowed, "cannot create new features") + } + + id := request.ID + var feature v3client.Feature + + if err := access.ByID(request, request.Version, v3client.FeatureType, id, &feature); err != nil { + if !httperror.IsNotFound(err) { + return err + } + } + + newValue, ok := data["value"] + if !ok { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must contain value") + } + + obj, err := v.FeatureLister.Get("", id) + if err != nil { + return err + } + + if obj.Status.LockedValue != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("feature flag cannot be changed from current value: %v", *obj.Status.LockedValue)) + } + + _, ok = newValue.(bool) + if !ok { + return httperror.NewAPIError(httperror.InvalidBodyContent, "feature value must be a bool") + } + + return nil +} + +func Formatter(request *types.APIContext, resource *types.RawResource) { + if request.Method == http.MethodGet { + resource.Values["value"] = getEffectiveValue(resource) + } +} + +func getEffectiveValue(resource *types.RawResource) bool { + if val := resource.Values["value"]; val != nil { + val, _ := val.(bool) + return val + } + + var val bool + // if value is nil, then this ensure default value will be usedq + status, ok := resource.Values["status"].(map[string]interface{}) + if ok { + val, _ = status["default"].(bool) + } + + return val +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature_test.go new file mode 100644 index 0000000..643255c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/feature/feature_test.go @@ -0,0 +1,30 @@ +package feature + +import ( + "testing" + + "github.com/rancher/norman/types" + "github.com/stretchr/testify/assert" +) + +// the effective value of a feature should be value if one is assigned, otherwise +// it should reflect the default value +func TestFormatter(t *testing.T) { + assert := assert.New(t) + + // ensure value is set to default when it has not been set by user + testResource := &types.RawResource{ + Values: map[string]interface{}{ + "status": map[string]interface{}{ + "default": true, + }, + }, + } + + assert.Equal(true, getEffectiveValue(testResource)) + + // ensure value is not set to default when it has been set by user + testResource.Values["value"] = false + + assert.Equal(false, getEffectiveValue(testResource)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/handler.go new file mode 100644 index 0000000..da5ddef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/handler.go @@ -0,0 +1,261 @@ +package gke + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/cluster" + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + mgmtSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +type Capabilities struct { + Credentials string `json:"credentials,omitempty"` + ProjectID string `json:"projectId,omitempty"` + Zone string `json:"zone,omitempty"` + Region string `json:"region,omitempty"` +} + +// GKE handler lists available resources in Google API +type handler struct { + Action string + schemas *types.Schemas + secretsLister v1.SecretLister + clusterCache mgmtv3.ClusterCache + ac types.AccessControl +} + +func NewGKEHandler(scaledContext *config.ScaledContext) http.Handler { + return &handler{ + schemas: scaledContext.Schemas, + secretsLister: scaledContext.Core.Secrets(namespace.GlobalNamespace).Controller().Lister(), + clusterCache: scaledContext.Wrangler.Mgmt.Cluster().Cache(), + ac: scaledContext.AccessControl, + } +} + +func (h *handler) ServeHTTP(writer http.ResponseWriter, req *http.Request) { + + writer.Header().Set("Content-Type", "application/json") + + capa := &Capabilities{} + + if credID := req.URL.Query().Get("cloudCredentialId"); credID != "" { + if errCode, err := h.getCloudCredential(req, capa, credID); err != nil { + handleErr(writer, errCode, err) + return + } + } else if req.Method == http.MethodPost { + if errCode, err := h.getCredentialsFromBody(writer, req, capa); err != nil { + handleErr(writer, errCode, err) + return + } + } else { + handleErr(writer, http.StatusBadRequest, fmt.Errorf("cannot access Google API without credentials to authenticate")) + return + } + + var serialized []byte + var errCode int + var err error + + resourceType := mux.Vars(req)["resource"] + + switch resourceType { + case "gkeMachineTypes": + if serialized, errCode, err = listMachineTypes(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting machine types: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeNetworks": + if serialized, errCode, err = listNetworks(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting networks: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeServiceAccounts": + if serialized, errCode, err = listServiceAccounts(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting serviceaccounts: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeSubnetworks": + if serialized, errCode, err = listSubnetworks(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting subnetworks: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeVersions": + if serialized, errCode, err = listVersions(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting versions: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeZones": + if serialized, errCode, err = listZones(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting zones: %v", err) + handleErr(writer, errCode, err) + return + + } + writer.Write(serialized) + case "gkeClusters": + if serialized, errCode, err = listClusters(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting clusters: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + case "gkeSharedSubnets": + if serialized, errCode, err = listSharedSubnets(req.Context(), capa); err != nil { + logrus.Errorf("[gke-handler] error getting shared subnets: %v", err) + handleErr(writer, errCode, err) + return + } + writer.Write(serialized) + default: + handleErr(writer, httperror.NotFound.Status, fmt.Errorf("invalid endpoint %v", resourceType)) + } +} + +func (h *handler) getCloudCredential(req *http.Request, cap *Capabilities, credID string) (int, error) { + ns, name := ref.Parse(credID) + if ns == "" || name == "" { + logrus.Errorf("[GKE] invalid cloud credential ID %s", credID) + return http.StatusBadRequest, fmt.Errorf("invalid cloud credential ID %s", credID) + } + + var accessCred client.CloudCredential // var to check access + if err := access.ByID(h.generateAPIContext(req), &schema.Version, client.CloudCredentialType, credID, &accessCred); err != nil { + apiError, ok := err.(*httperror.APIError) + if !ok { + return httperror.NotFound.Status, err + } + if apiError.Code.Status == httperror.NotFound.Status { + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") + } + if apiError.Code.Status != httperror.PermissionDenied.Status { + return httperror.InvalidBodyContent.Status, err + } + if errCode, err := h.clusterCheck(h.generateAPIContext(req), req.URL.Query().Get("clusterID"), credID); err != nil { + return errCode, err + } + } + + cc, err := h.secretsLister.Get(ns, name) + if err != nil { + logrus.Errorf("[GKE] error accessing cloud credential %s", credID) + return httperror.InvalidBodyContent.Status, fmt.Errorf("error accessing cloud credential %s", credID) + } + cap.Credentials = string(cc.Data["googlecredentialConfig-authEncodedJson"]) + + cap.ProjectID = req.URL.Query().Get("projectId") + if cap.ProjectID == "" { + logrus.Errorf("[GKE] error getting projectId") + return http.StatusBadRequest, fmt.Errorf("error getting projectId") + } + + region := req.URL.Query().Get("region") + if region != "" { + cap.Region = region + } + zone := req.URL.Query().Get("zone") + if zone != "" { + cap.Zone = zone + } + + return http.StatusOK, nil +} + +func (h *handler) clusterCheck(apiContext *types.APIContext, clusterID, cloudCredentialID string) (int, error) { + var ( + clusters []*v3.Cluster + err error + ) + if clusterID == "" { + // If no clusterID is passed, then we check all clusters that the user has access to and are associated to the cloud credential. + clusters, err = h.clusterCache.GetByIndex(cluster.ByCloudCredential, cloudCredentialID) + if err != nil { + return httperror.InvalidBodyContent.Status, err + } + if len(clusters) == 0 { + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") + } + } else { + c, err := h.clusterCache.Get(clusterID) + if err != nil { + return httperror.ServerError.Status, err + } + clusters = []*v3.Cluster{c} + } + + for _, c := range clusters { + if c.Spec.GKEConfig == nil || c.Spec.GKEConfig.GoogleCredentialSecret != cloudCredentialID { + continue + } + + clusterSchema := h.schemas.Schema(&mgmtSchema.Version, client.ClusterType) + if err := h.ac.CanDo(v3.ClusterGroupVersionKind.Group, v3.ClusterResource.Name, "update", apiContext, map[string]interface{}{"id": c.Name}, clusterSchema); err == nil { + return http.StatusOK, nil + } + + } + + return httperror.InvalidBodyContent.Status, fmt.Errorf("cloud credential not found") +} + +func (h *handler) getCredentialsFromBody(writer http.ResponseWriter, req *http.Request, cap *Capabilities) (int, error) { + raw, err := ioutil.ReadAll(req.Body) + if err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot read request body: %v", err) + } + + if err = json.Unmarshal(raw, &cap); err != nil { + return http.StatusBadRequest, fmt.Errorf("cannot parse request body: %v", err) + } + + if cap.Credentials == "" { + return http.StatusBadRequest, fmt.Errorf("invalid credentials") + } + if cap.ProjectID == "" { + return http.StatusBadRequest, fmt.Errorf("invalid projectId") + } + + return http.StatusOK, nil +} + +func (h *handler) generateAPIContext(req *http.Request) *types.APIContext { + return &types.APIContext{ + Method: req.Method, + Request: req, + Schemas: h.schemas, + Query: map[string][]string{}, + } +} + +func handleErr(writer http.ResponseWriter, errorCode int, originalErr error) { + asJSON := []byte(fmt.Sprintf(`{"error":"%v"}`, originalErr)) + + writer.WriteHeader(errorCode) + writer.Write(asJSON) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/listers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/listers.go new file mode 100644 index 0000000..208e7a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/gke/listers.go @@ -0,0 +1,257 @@ +package gke + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "google.golang.org/api/compute/v1" + "google.golang.org/api/container/v1" + gkeapi "google.golang.org/api/container/v1" + "google.golang.org/api/iam/v1" + "google.golang.org/api/option" +) + +func getTokenSource(ctx context.Context, credential string) (oauth2.TokenSource, error) { + ts, err := google.CredentialsFromJSON(ctx, []byte(credential), gkeapi.CloudPlatformScope) + if err != nil { + return nil, err + } + return ts.TokenSource, nil +} + +func getComputeServiceClient(ctx context.Context, credentialContent string) (*compute.Service, error) { + ts, err := getTokenSource(ctx, credentialContent) + if err != nil { + return nil, err + } + + service, err := compute.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, ts))) + if err != nil { + return nil, err + } + + return service, nil +} + +func getIamServiceClient(ctx context.Context, credentialContent string) (*iam.Service, error) { + ts, err := getTokenSource(ctx, credentialContent) + if err != nil { + return nil, err + } + + service, err := iam.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, ts))) + if err != nil { + return nil, err + } + + return service, nil +} + +func getContainerServiceClient(ctx context.Context, credentialContent string) (*container.Service, error) { + ts, err := getTokenSource(ctx, credentialContent) + if err != nil { + return nil, err + } + + service, err := container.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, ts))) + if err != nil { + return nil, err + } + + return service, nil +} + +func listMachineTypes(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ProjectID == "" || cap.Zone == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId and zone are required") + } + + client, err := getComputeServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + result, err := client.MachineTypes.List(cap.ProjectID, cap.Zone).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listNetworks(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ProjectID == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId is required") + } + + client, err := getComputeServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + result, err := client.Networks.List(cap.ProjectID).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listSubnetworks(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ProjectID == "" || cap.Region == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId and region are required") + } + + client, err := getComputeServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + result, err := client.Subnetworks.List(cap.ProjectID, cap.Region).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listServiceAccounts(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ProjectID == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId is required") + } + + client, err := getIamServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + name := "projects/" + cap.ProjectID + result, err := client.Projects.ServiceAccounts.List(name).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listVersions(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.Region == "" && cap.Zone == "" { + return nil, http.StatusBadRequest, fmt.Errorf("either region or zone is required") + } + if cap.Region != "" && cap.Zone != "" { + return nil, http.StatusBadRequest, fmt.Errorf("only one of region or zone can be provided") + } + if cap.ProjectID == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId is required") + } + + client, err := getContainerServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + var location string + if cap.Region != "" { + location = cap.Region + } else { + location = cap.Zone + } + parent := "projects/" + cap.ProjectID + "/locations/" + location + result, err := client.Projects.Locations.GetServerConfig(parent).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listZones(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.ProjectID == "" { + return nil, http.StatusBadRequest, fmt.Errorf("projectId is required") + } + + client, err := getComputeServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + result, err := client.Zones.List(cap.ProjectID).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listClusters(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + if cap.Region == "" && cap.Zone == "" { + return nil, http.StatusBadRequest, fmt.Errorf("either region or zone is required") + } + if cap.Region != "" && cap.Zone != "" { + return nil, http.StatusBadRequest, fmt.Errorf("only one of region or zone can be provided") + } + + var location string + if cap.Region != "" { + location = cap.Region + } else { + location = cap.Zone + } + + client, err := getContainerServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + parent := "projects/" + cap.ProjectID + "/locations/" + location + result, err := client.Projects.Locations.Clusters.List(parent).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + return encodeOutput(result) +} + +func listSharedSubnets(ctx context.Context, cap *Capabilities) ([]byte, int, error) { + computeClient, err := getComputeServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + containerClient, err := getContainerServiceClient(ctx, cap.Credentials) + if err != nil { + return nil, http.StatusInternalServerError, err + } + + hostProject, err := computeClient.Projects.GetXpnHost(cap.ProjectID).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + + // If there is no host project for this project, the fields in this returned object will be empty. + // In this case, we will return a null object indicating there are no subnets explicitly shared to this project. + // The caller will need to call /meta/gkeNetworks and /meta/gkeSubnetworks to get the project's own network and subnet list. + var result *container.ListUsableSubnetworksResponse + if hostProject.Name != "" { + parent := "projects/" + cap.ProjectID + filter := "networkProjectId=" + hostProject.Name + result, err = containerClient.Projects.Aggregated.UsableSubnetworks.List(parent).Filter(filter).Do() + if err != nil { + return nil, http.StatusInternalServerError, err + } + } + + return encodeOutput(result) +} + +func encodeOutput(result interface{}) ([]byte, int, error) { + data, err := json.Marshal(&result) + if err != nil { + return data, http.StatusInternalServerError, err + } + + return data, http.StatusOK, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/action_globaldns.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/action_globaldns.go new file mode 100644 index 0000000..6e54e24 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/action_globaldns.go @@ -0,0 +1,185 @@ +package globaldns + +import ( + "fmt" + "net/http" + "strings" + "time" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + addProjectsAction = "addProjects" + removeProjectsAction = "removeProjects" +) + +var backoff = wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 2, + Jitter: 0.5, + Steps: 7, +} + +func (w *Wrapper) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + resource.AddAction(apiContext, addProjectsAction) + resource.AddAction(apiContext, removeProjectsAction) +} + +func (w *Wrapper) ActionHandler(actionName string, action *types.Action, request *types.APIContext) error { + if err := access.ByID(request, &managementschema.Version, client.GlobalDnsType, request.ID, &client.GlobalDns{}); err != nil { + return err + } + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect global DNS ID") + } + gDNS, err := w.GlobalDNSes.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return err + } + callerID := request.Request.Header.Get(gaccess.ImpersonateUserHeader) + metaAccessor, err := meta.Accessor(gDNS) + if err != nil { + return err + } + creatorID, ok := metaAccessor.GetAnnotations()[creatorIDAnn] + if !ok { + return fmt.Errorf("GlobalDNS %v has no creatorId annotation", metaAccessor.GetName()) + } + ma := gaccess.MemberAccess{ + Users: w.Users, + GrbLister: w.GrbLister, + GrLister: w.GrLister, + } + accessType, err := ma.GetAccessTypeOfCaller(callerID, creatorID, gDNS.Name, gDNS.Spec.Members) + if err != nil { + return err + } + if accessType != gaccess.OwnerAccess { + return fmt.Errorf("only owners can modify global DNS target projects") + } + + actionInput, err := parse.ReadBody(request.Request) + if err != nil { + return err + } + inputProjects := convert.ToStringSlice(actionInput[client.UpdateGlobalDNSTargetsInputFieldProjectIDs]) + switch actionName { + case addProjectsAction: + return w.addProjects(request, inputProjects) + case removeProjectsAction: + return w.removeProjects(request, inputProjects) + default: + return fmt.Errorf("bad action for global dns %v", actionName) + } +} + +func (w *Wrapper) addProjects(request *types.APIContext, inputProjects []string) error { + ma := gaccess.MemberAccess{ + Users: w.Users, + GrbLister: w.GrbLister, + GrLister: w.GrLister, + } + if err := ma.CheckCallerAccessToTargets(request, inputProjects, client.ProjectType, &client.Project{}); err != nil { + return err + } + + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect global DNS ID") + } + + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + existingProjects := make(map[string]bool) + gDNS, err := w.GlobalDNSes.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return false, err + } + if gDNS.Spec.MultiClusterAppName != "" { + return false, httperror.NewAPIError(httperror.InvalidOption, + fmt.Sprintf("cannot add projects to globaldns as targets if multiclusterappID is set %s", gDNS.Spec.MultiClusterAppName)) + } + for _, p := range gDNS.Spec.ProjectNames { + existingProjects[p] = true + } + for _, p := range inputProjects { + if existingProjects[p] { + return false, httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("duplicate projects in targets %s", p)) + } + existingProjects[p] = true + } + for _, name := range inputProjects { + gDNS.Spec.ProjectNames = append(gDNS.Spec.ProjectNames, name) + } + _, err = w.GlobalDNSes.Update(gDNS) + if err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + return true, nil + }) + + if err != nil { + return err + } + op := map[string]interface{}{ + "message": "addedProjects", + } + request.WriteResponse(http.StatusOK, op) + return nil +} + +func (w *Wrapper) removeProjects(request *types.APIContext, inputProjects []string) error { + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect global DNS ID") + } + + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + gDNS, err := w.GlobalDNSes.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return false, err + } + toRemoveProjects := make(map[string]bool) + var finalProjects []string + for _, p := range inputProjects { + toRemoveProjects[p] = true + } + for _, p := range gDNS.Spec.ProjectNames { + if !toRemoveProjects[p] { + finalProjects = append(finalProjects, p) + } + } + gDNS.Spec.ProjectNames = finalProjects + _, err = w.GlobalDNSes.Update(gDNS) + if err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return err + } + op := map[string]interface{}{ + "message": "removedProjects", + } + request.WriteResponse(http.StatusOK, op) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/validator_globaldns.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/validator_globaldns.go new file mode 100644 index 0000000..06ab69e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globaldns/validator_globaldns.go @@ -0,0 +1,105 @@ +package globaldns + +import ( + "fmt" + "net/http" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Wrapper struct { + GlobalDNSLister v3.GlobalDnsLister + GlobalDNSes v3.GlobalDnsInterface + PrtbLister v3.ProjectRoleTemplateBindingLister + MultiClusterAppLister v3.MultiClusterAppLister + Users v3.UserInterface + GrbLister v3.GlobalRoleBindingLister + GrLister v3.GlobalRoleLister +} + +const ( + creatorIDAnn = "field.cattle.io/creatorId" +) + +func (w Wrapper) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method != http.MethodPut && request.Method != http.MethodPost { + return nil + } + + var targetProjects []string + ma := gaccess.MemberAccess{ + Users: w.Users, + GrLister: w.GrLister, + GrbLister: w.GrbLister, + } + + callerID := request.Request.Header.Get(gaccess.ImpersonateUserHeader) + if request.Method == http.MethodPost { + // create request, caller is owner/creator + // Request is POST, hence global DNS is being created. + // if multiclusterapp ID is provided check access to its projects + mcappID := convert.ToString(data[client.GlobalDnsFieldMultiClusterAppID]) + if mcappID != "" { + split := strings.SplitN(mcappID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect multiclusterapp id %v provided for global dns %v", mcappID, request.ID) + } + mcapp, err := w.MultiClusterAppLister.Get(split[0], split[1]) + if err != nil { + return err + } + for _, t := range mcapp.Spec.Targets { + targetProjects = append(targetProjects, t.ProjectName) + } + } else { + // if not, check access to all projects provided in the projects list + targetProjects = convert.ToStringSlice(data[client.GlobalDnsFieldProjectIDs]) + } + return ma.CheckCallerAccessToTargets(request, targetProjects, client.ProjectType, &client.Project{}) + } + // edit request, check access type caller has + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect global DNS ID %v", request.ID) + } + + gDNS, err := w.GlobalDNSes.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return err + } + metaAccessor, err := meta.Accessor(gDNS) + if err != nil { + return err + } + creatorID, ok := metaAccessor.GetAnnotations()[creatorIDAnn] + if !ok { + return fmt.Errorf("GlobalDNS %v has no creatorId annotation", metaAccessor.GetName()) + } + accessType, err := ma.GetAccessTypeOfCaller(callerID, creatorID, gDNS.Name, gDNS.Spec.Members) + if err != nil { + return err + } + if accessType != gaccess.OwnerAccess { + return fmt.Errorf("invalid access type %v for globaldns member", accessType) + } + // only members list, FQDN and multiclusterappID can be edited through PUT, for updating projects, we need to use actions only + // that's why projects and multiclusterappID field have been made non updatable in rancher/types + if err := gaccess.CheckAccessToUpdateMembers(gDNS.Spec.Members, data, accessType == gaccess.OwnerAccess); err != nil { + return err + } + + originalMultiClusterApp := gDNS.Spec.MultiClusterAppName + newMultiClusterApp := convert.ToString(data[client.GlobalDnsFieldMultiClusterAppID]) + if newMultiClusterApp != "" && originalMultiClusterApp != newMultiClusterApp { + // check access to new multiclusterapp + return ma.CheckCallerAccessToTargets(request, []string{newMultiClusterApp}, client.MultiClusterAppType, &client.MultiClusterApp{}) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalnamespaceaccess/access_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalnamespaceaccess/access_common.go new file mode 100644 index 0000000..3c02bde --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalnamespaceaccess/access_common.go @@ -0,0 +1,571 @@ +package globalnamespaceaccess + +import ( + "encoding/base32" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/set" + "github.com/rancher/norman/types/slice" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/ref" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +type MemberAccess struct { + Users v3.UserInterface + RoleTemplateLister v3.RoleTemplateLister + PrtbLister v3.ProjectRoleTemplateBindingLister + CrtbLister v3.ClusterRoleTemplateBindingLister + GrbLister v3.GlobalRoleBindingLister + GrLister v3.GlobalRoleLister + Prtbs v3.ProjectRoleTemplateBindingInterface + Crtbs v3.ClusterRoleTemplateBindingInterface + ProjectLister v3.ProjectLister + ClusterLister v3.ClusterLister +} + +const ( + ImpersonateUserHeader = "Impersonate-User" + ImpersonateGroupHeader = "Impersonate-Group" + OwnerAccess = "owner" + ReadonlyAccess = "read-only" + localPrincipalPrefix = "local://" +) + +func (ma *MemberAccess) CheckCallerAccessToTargets(request *types.APIContext, targets []string, resourceType string, into interface{}) error { + for _, targetID := range targets { + if err := access.ByID(request, &managementschema.Version, resourceType, targetID, into); err != nil { + return err + } + } + return nil +} + +func (ma *MemberAccess) IsAdmin(callerID string) (bool, error) { + u, err := ma.Users.Controller().Lister().Get("", callerID) + if err != nil { + return false, err + } + if u == nil { + return false, fmt.Errorf("No user found with ID %v", callerID) + } + // Get globalRoleBinding for this user + grbs, err := ma.GrbLister.List("", labels.NewSelector()) + if err != nil { + return false, err + } + for _, grb := range grbs { + if grb.UserName == callerID { + gr, err := ma.GrLister.Get("", grb.GlobalRoleName) + if apierrors.IsNotFound(err) { + continue + } else if err != nil { + return false, err + } + for _, rule := range gr.Rules { + // admin roles have all resources and all verbs allowed + if slice.ContainsString(rule.Resources, "*") && slice.ContainsString(rule.APIGroups, "*") && slice.ContainsString(rule.Verbs, "*") { + // caller is global admin + return true, nil + } + } + } + } + return false, nil +} + +func (ma *MemberAccess) IsRestrictedAdmin(callerID string) (bool, error) { + u, err := ma.Users.Controller().Lister().Get("", callerID) + if err != nil { + return false, err + } + if u == nil { + return false, fmt.Errorf("No user found with ID %v", callerID) + } + + // Get globalRoleBinding for this user + grbs, err := ma.GrbLister.List("", labels.NewSelector()) + if err != nil { + return false, err + } + for _, grb := range grbs { + if grb.UserName == callerID { + if grb.GlobalRoleName == rbac.GlobalRestrictedAdmin { + return true, nil + } + } + } + return false, nil +} + +func (ma *MemberAccess) EnsureRoleInTargets(targetProjects, roleTemplates []string, callerID string) error { + isAdmin, err := ma.IsAdmin(callerID) + if err != nil { + return err + } + var isRestrictedAdmin, localTargets bool + if !isAdmin { + isRestrictedAdmin, err = ma.IsRestrictedAdmin(callerID) + if err != nil { + return err + } + if isRestrictedAdmin { + localTargets, err = hasLocalTargets(targetProjects) + if err != nil { + return err + } + } + } + + if isAdmin || (isRestrictedAdmin && !localTargets) { + for _, t := range targetProjects { + if err := ma.checkProjectExists(t); err != nil { + return err + } + } + // relax memberAccess check for the global admin + return nil + } + newProjectRoleTemplateMap := make(map[string]*v3.RoleTemplate) + newClusterRoleTemplateMap := make(map[string]*v3.RoleTemplate) + clusters := make(map[string]bool) + for _, r := range roleTemplates { + rt, err := ma.RoleTemplateLister.Get("", r) + if err != nil { + if apierrors.IsNotFound(err) { + return httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Role "+r+" does not exist") + } + return err + } + switch rt.Context { + case "project": + if _, ok := newProjectRoleTemplateMap[r]; !ok { + newProjectRoleTemplateMap[r] = rt + } + case "cluster": + if _, ok := newClusterRoleTemplateMap[r]; !ok { + newClusterRoleTemplateMap[r] = rt + } + } + } + clustersCallerIsOwnerOf := make(map[string]bool) + errMsg := "User does not have " + roleMissing := false + for _, t := range targetProjects { + if err := ma.checkProjectExists(t); err != nil { + return err + } + cname, pname := ref.Parse(t) + if !clusters[cname] { + clusters[cname] = true + } + projectRoleTemplateFoundCount := 0 + projectRoleTemplateFoundMap := make(map[string]bool) + callerIsProjectOwner := false + callerIsProjectMember := false + callerIsClusterOwner := false + prtbs, err := ma.PrtbLister.List(pname, labels.NewSelector()) + if err != nil { + return err + } + for _, prtb := range prtbs { + if prtb.UserName == callerID { + if _, ok := newProjectRoleTemplateMap[prtb.RoleTemplateName]; ok { + projectRoleTemplateFoundMap[prtb.RoleTemplateName] = true + projectRoleTemplateFoundCount++ + } + if callerIsProjectOwner && callerIsProjectMember { + continue + } + rt, err := ma.RoleTemplateLister.Get("", prtb.RoleTemplateName) + if err != nil { + return err + } + if rt.ProjectCreatorDefault && rt.Builtin { + callerIsProjectOwner = true + } + if rt.Name == "project-member" { + callerIsProjectMember = true + } + } + } + if projectRoleTemplateFoundCount != len(newProjectRoleTemplateMap) { + // user does not have prtbs for all input roles in this project, find the roles for which there are no prtbs + customRolesFound := false + inputRolesContainProjectOwnerRole := false + projectRolesToAddMap := make(map[string]bool) + for role := range newProjectRoleTemplateMap { + projectRolesToAddMap[role] = true + } + _, rolesNotFound, _ := set.Diff(projectRoleTemplateFoundMap, projectRolesToAddMap) + // find if any of the roles for which prtbs aren't found are custom + for _, r := range rolesNotFound { + if rt, ok := newProjectRoleTemplateMap[r]; ok { + if !rt.Builtin { + customRolesFound = true + } + if rt.ProjectCreatorDefault && rt.Builtin { + // this is the "project-owner" role + inputRolesContainProjectOwnerRole = true + } + } + } + // check if caller is project-owner, project-member or cluster-owner + if callerIsProjectOwner && !customRolesFound { + // project-owner should be allowed to add any built-in project roles + continue + } + if callerIsProjectMember && !customRolesFound && !inputRolesContainProjectOwnerRole { + // project-member should be allowed to add any built-in project role, EXCEPT the project-owner role + continue + } + + // check if caller is cluster-owner + crtbs, err := ma.CrtbLister.List(cname, labels.NewSelector()) + if err != nil { + return err + } + for _, crtb := range crtbs { + if crtb.UserName == callerID { + rt, err := ma.RoleTemplateLister.Get("", crtb.RoleTemplateName) + if err != nil { + return err + } + if rt.ClusterCreatorDefault && rt.Builtin { + // caller is the owner of the cluster that this project belongs to, no need to check other crtbs + callerIsClusterOwner = true + clustersCallerIsOwnerOf[cname] = true + break + } + } + } + if callerIsClusterOwner && !customRolesFound { + // cluster-owner should be allowed to add any built-in roles + continue + } + // either the user is not one of these: project-owner, project-member or cluster-owner, OR + // the passed in roles have some custom roles which the user does not have prtbs/crtbs for + p, err := ma.ProjectLister.Get(cname, pname) + if err != nil { + return err + } + projectName := pname + if p.Spec.DisplayName != "" { + projectName = p.Spec.DisplayName + } + // get display name of cluster + c, err := ma.ClusterLister.Get("", cname) + if err != nil { + return err + } + clusterName := cname + if c.Spec.DisplayName != "" { + clusterName = c.Spec.DisplayName + } + roleMissing = true + missingRoles := strings.Join(rolesNotFound, ",") + projErr := fmt.Sprintf("roles %v in project %v of cluster %v, ", missingRoles, projectName, clusterName) + errMsg += projErr + } + } + + if len(newClusterRoleTemplateMap) == 0 && !roleMissing { + return nil + } + for cname := range clusters { + clusterRoleTemplateFoundCount := 0 + clusterRoleTemplateFoundMap := make(map[string]bool) + clusterOwner := clustersCallerIsOwnerOf[cname] + crtbs, err := ma.CrtbLister.List(cname, labels.NewSelector()) + if err != nil { + return err + } + for _, crtb := range crtbs { + if crtb.UserName == callerID { + if _, ok := newClusterRoleTemplateMap[crtb.RoleTemplateName]; ok { + clusterRoleTemplateFoundMap[crtb.RoleTemplateName] = true + clusterRoleTemplateFoundCount++ + } + if clusterOwner { + // we already found a crtb with roletemplate cluster-owner for the caller in this cluster + continue + } + rt, err := ma.RoleTemplateLister.Get("", crtb.RoleTemplateName) + if err != nil { + return err + } + if rt.ClusterCreatorDefault && rt.Builtin { + clusterOwner = true + } + } + } + if clusterRoleTemplateFoundCount != len(newClusterRoleTemplateMap) { + customRolesFound := false + clusterRolesToAddMap := make(map[string]bool) + for role := range newClusterRoleTemplateMap { + clusterRolesToAddMap[role] = true + } + _, rolesNotFound, _ := set.Diff(clusterRoleTemplateFoundMap, clusterRolesToAddMap) + // find if any of the roles for which prtbs aren't found are builtin + for _, r := range rolesNotFound { + if rt, ok := newProjectRoleTemplateMap[r]; ok { + if !rt.Builtin { + customRolesFound = true + } + } + } + if clusterOwner && !customRolesFound { + // caller is cluster-owner of current cluster, relax this check + continue + } + + // get cluster's displayName + c, err := ma.ClusterLister.Get("", cname) + if err != nil { + return err + } + clusterName := cname + if c.Spec.DisplayName != "" { + clusterName = c.Spec.DisplayName + } + roleMissing = true + missingRoles := strings.Join(rolesNotFound, ",") + clusErr := fmt.Sprintf("roles %v in cluster %v, ", missingRoles, clusterName) + errMsg += clusErr + } + } + if roleMissing { + errMsg := strings.TrimRight(errMsg, ", ") + return httperror.NewAPIError(httperror.PermissionDenied, errMsg) + } + return nil +} + +func hasLocalTargets(targetProjects []string) (bool, error) { + for _, target := range targetProjects { + split := strings.SplitN(target, ":", 2) + if len(split) != 2 { + errMsg := fmt.Sprintf("Invalid project ID: %v", target) + return false, httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + clusterName := split[0] + if clusterName == "local" { + return true, nil + } + } + return false, nil +} + +// CheckAccessToUpdateMembers checks if the request is updating members list, and if the caller has permission to do so +func CheckAccessToUpdateMembers(members []v32.Member, data map[string]interface{}, ownerAccess bool) error { + var requestUpdatesMembers bool + // Check if members are being updated, if yes, make sure only member with owner permission is making this update request + newMembers := convert.ToMapSlice(data[client.GlobalDnsFieldMembers]) + originalMembers := members + if len(newMembers) != len(originalMembers) && !ownerAccess { + return fmt.Errorf("only members with owner access can update members") + } + + newMemberAccessType := make(map[string]string) + for _, m := range newMembers { + if userPrincipalName, ok := m[client.MemberFieldUserPrincipalID]; ok && userPrincipalName != nil { + newMemberAccessType[convert.ToString(m[client.MemberFieldUserPrincipalID])] = convert.ToString(m[client.MemberFieldAccessType]) + } + if groupPrincipalName, ok := m[client.MemberFieldGroupPrincipalID]; ok && groupPrincipalName != nil { + newMemberAccessType[convert.ToString(m[client.MemberFieldGroupPrincipalID])] = convert.ToString(m[client.MemberFieldAccessType]) + } + } + + originalMemberAccessType := make(map[string]string) + originalMembersFoundInRequest := make(map[string]bool) // map to check whether all existing members are present in the current request, if not then this request is trying to update members list + for _, m := range originalMembers { + if m.UserPrincipalName != "" { + originalMemberAccessType[m.UserPrincipalName] = m.AccessType + } + if m.GroupPrincipalName != "" { + originalMemberAccessType[m.GroupPrincipalName] = m.AccessType + } + } + + // go through all members in the current request, check if each exists in the original global DNS + // if it exists, check that the access type hasn't changed, if it has changed, this means the req is updating members + // if the member from req doesn't exist in original global DNS, this means the new request is adding a new member, hence updating members list + for key, accessType := range newMemberAccessType { + if val, ok := originalMemberAccessType[key]; ok { + if val != accessType { + requestUpdatesMembers = true + break + } + // mark this original member as present in the current request + originalMembersFoundInRequest[key] = true + } else { + requestUpdatesMembers = true + break + } + } + if requestUpdatesMembers && !ownerAccess { + return fmt.Errorf("only members with owner access can add new members") + } + + // at this point, all members in the new request have been found in the original global DNS with the same access type + // but we need to check if all members from the original global DNS are also present in the current request + for member := range originalMemberAccessType { + // if any member is not found, this means the current request is updating members list by deleting this member + if !originalMembersFoundInRequest[member] && !ownerAccess { + return fmt.Errorf("only members with owner access can delete existing members") + } + } + return nil +} + +func (ma *MemberAccess) GetAccessTypeOfCaller(callerID, creatorID, name string, members []v32.Member) (string, error) { + var username string + isAdmin, err := ma.IsAdmin(callerID) + if err != nil { + return "", err + } + if isAdmin { + // global admins should be allowed to update mcapp, irrespective of their accessType if they're added as member, or + // even if they aren't added as member at all + return OwnerAccess, nil + } + if callerID == creatorID { + return OwnerAccess, nil + } + for _, m := range members { + if m.UserName == "" && m.UserPrincipalName != "" { + user, err := ma.getUserFromUserPrincipalID(m.UserPrincipalName) + if err != nil { + return "", err + } + if user == nil { + return "", fmt.Errorf("no user found for principal %v", m.UserPrincipalName) + } + if user.Name == callerID { + username = user.Name + } + } else if m.UserName == callerID { + username = m.UserName + } + if username != "" { // found the caller + return m.AccessType, nil + } + if m.GroupPrincipalName == "*" { + return m.AccessType, nil + } + } + return "", fmt.Errorf("user %v is not in members list", callerID) +} + +func (ma *MemberAccess) getUserFromUserPrincipalID(userPrincipalID string) (*v3.User, error) { + encodedPrincipalID := base32.HexEncoding.WithPadding(base32.NoPadding).EncodeToString([]byte(userPrincipalID)) + if len(encodedPrincipalID) > 63 { + encodedPrincipalID = encodedPrincipalID[:63] + } + set := labels.Set(map[string]string{encodedPrincipalID: "hashed-principal-name"}) + usersList, err := ma.Users.List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return nil, err + } + + if len(usersList.Items) == 0 { + // check for local auth principals + if strings.HasPrefix(userPrincipalID, localPrincipalPrefix) { + userID := strings.TrimPrefix(userPrincipalID, localPrincipalPrefix) + user, err := ma.Users.Controller().Lister().Get("", userID) + return user, err + } + return nil, nil + } + + var match *v3.User + for _, u := range usersList.Items { + if slice.ContainsString(u.PrincipalIDs, userPrincipalID) { + if match != nil { + // error out on duplicates + return nil, fmt.Errorf("can't find unique user for principal %v", userPrincipalID) + } + match = &u + } + } + return match, nil +} + +func (ma *MemberAccess) RemoveRolesFromTargets(targetProjects, rolesToRemove []string, mcappName string, removeAllRoles bool) error { + systemUserPrincipalID := fmt.Sprintf("system://%s", mcappName) + // from given targets, remove prtbs/crtbs created for user with system account's userID + rolesToRemoveMap := make(map[string]bool) + if !removeAllRoles { + for _, role := range rolesToRemove { + rolesToRemoveMap[role] = true + } + } + + for _, target := range targetProjects { + split := strings.SplitN(target, ":", 2) + if len(split) != 2 { + errMsg := fmt.Sprintf("Invalid project ID: %v", target) + return httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + clusterName, projectName := split[0], split[1] + clustersCovered := make(map[string]bool) + prtbs, err := ma.PrtbLister.List(projectName, labels.NewSelector()) + if err != nil { + return err + } + for _, prtb := range prtbs { + if prtb.UserPrincipalName == systemUserPrincipalID { + if removeAllRoles || rolesToRemoveMap[prtb.RoleTemplateName] { + if err = ma.Prtbs.DeleteNamespaced(projectName, prtb.Name, &v1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return err + } + } + } + } + + if !clustersCovered[clusterName] { + crtbs, err := ma.CrtbLister.List(clusterName, labels.NewSelector()) + if err != nil { + return err + } + for _, crtb := range crtbs { + if crtb.UserPrincipalName == systemUserPrincipalID { + if removeAllRoles || rolesToRemoveMap[crtb.RoleTemplateName] { + if err = ma.Crtbs.DeleteNamespaced(clusterName, crtb.Name, &v1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return err + } + } + } + } + clustersCovered[clusterName] = true + } + } + return nil +} + +func (ma *MemberAccess) checkProjectExists(target string) error { + split := strings.SplitN(target, ":", 2) + if len(split) != 2 { + return httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("invalid project ID %s", target)) + } + _, err := ma.ProjectLister.Get(split[0], split[1]) + if err != nil { + if apierrors.IsNotFound(err) { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("project is not found %s", target)) + } + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("error getting project %s: %v", target, err)) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/formatter.go new file mode 100644 index 0000000..b387dc6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/formatter.go @@ -0,0 +1,11 @@ +package globalrole + +import ( + "github.com/rancher/norman/types" +) + +func Formatter(request *types.APIContext, resource *types.RawResource) { + if resource.Values["builtin"] == true { + delete(resource.Links, "remove") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/validator.go new file mode 100644 index 0000000..a7605ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrole/validator.go @@ -0,0 +1,40 @@ +package globalrole + +import ( + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" +) + +type Wrapper struct { + GlobalRoleLister v3.GlobalRoleLister +} + +func (w Wrapper) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method != http.MethodPut { + return nil + } + + gr, err := w.GlobalRoleLister.Get("", request.ID) + if err != nil { + if errors.IsNotFound(err) { + return httperror.NewAPIError(httperror.NotFound, err.Error()) + } + return err + } + + if gr.Builtin == true { + // Drop everything but locked and defaults. If it's builtin nothing else can change. + for k := range data { + if k == "newUserDefault" { + continue + } + delete(data, k) + } + + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrolebinding/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrolebinding/validator.go new file mode 100644 index 0000000..86dab44 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/globalrolebinding/validator.go @@ -0,0 +1,23 @@ +package globalrolebinding + +import ( + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" +) + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method == http.MethodPut { + return nil + } + + hasSingleSubject := (data["groupPrincipalId"] != nil && data["userId"] == nil) || + (data["groupPrincipalId"] == nil && data["userId"] != nil) + + if !hasSingleSubject { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must contain field [groupPrincipalId] "+ + "OR field [userId]") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/actionhandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/actionhandler.go new file mode 100644 index 0000000..5fa1412 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/actionhandler.go @@ -0,0 +1,193 @@ +package kontainerdriver + +import ( + "fmt" + "net/http" + "strconv" + "strings" + + mVersion "github.com/mcuadros/go-version" + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/catalog/utils" + "github.com/rancher/rancher/pkg/channelserver" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + rketypes "github.com/rancher/rke/types" + img "github.com/rancher/rke/types/image" + "github.com/rancher/rke/util" +) + +const ( + linuxImages = "rancher-images" + windowsImages = "rancher-windows-images" + rkeMetadataConfig = "rke-metadata-config" + forceRefreshAnnotation = "field.cattle.io/lastForceRefresh" +) + +type ActionHandler struct { + KontainerDrivers v3.KontainerDriverInterface + KontainerDriverLister v3.KontainerDriverLister + MetadataHandler kd.MetadataController +} + +type ListHandler struct { + SysImageLister v3.RkeK8sSystemImageLister + SysImages v3.RkeK8sSystemImageInterface + CatalogLister v3.CatalogLister + ConfigMapLister v1.ConfigMapLister +} + +func (a ActionHandler) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + // passing nil as the resource only works because just namespace is grabbed from it and nodedriver is not namespaced + if err := apiContext.AccessControl.CanDo(v3.KontainerDriverGroupVersionKind.Group, v3.KontainerDriverResource.Name, "update", apiContext, nil, apiContext.Schema); err != nil { + return err + } + + switch actionName { + case "activate": + return a.activate(apiContext) + case "deactivate": + return a.deactivate(apiContext) + case "refresh": + return a.refresh(apiContext) + } + return httperror.NewAPIError(httperror.NotFound, "not found") +} + +func (a ActionHandler) activate(apiContext *types.APIContext) error { + return a.setDriverActiveStatus(apiContext, true) +} + +func (a ActionHandler) deactivate(apiContext *types.APIContext) error { + return a.setDriverActiveStatus(apiContext, false) +} + +func (a ActionHandler) refresh(apiContext *types.APIContext) error { + response := map[string]interface{}{} + url, err := kd.GetURLSettingValue() + if err != nil { + msg := fmt.Sprintf("failed to get settings %v", err) + return httperror.WrapAPIError(err, httperror.ServerError, msg) + } + if err := a.MetadataHandler.Refresh(url); err != nil { + msg := fmt.Sprintf("failed to refresh %v", err) + return httperror.WrapAPIError(err, httperror.ServerError, msg) + } + + // refresh to sync k3s/rke2 releases + channelserver.Refresh() + apiContext.WriteResponse(http.StatusOK, response) + return nil +} + +func (a ActionHandler) setDriverActiveStatus(apiContext *types.APIContext, status bool) error { + driver, err := a.KontainerDriverLister.Get("", apiContext.ID) + if err != nil { + return err + } + + driver.Spec.Active = status + + _, err = a.KontainerDrivers.Update(driver) + + return err +} + +func (lh ListHandler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) (err error) { + k8sCurr := strings.Split(settings.KubernetesVersionsCurrent.Get(), ",") + rkeSysImages := map[string]rketypes.RKESystemImages{} + if apiContext.ID != linuxImages && apiContext.ID != windowsImages { + return httperror.NewAPIError(httperror.NotFound, "link does not exist") + } + for _, k8sVersion := range k8sCurr { + rkeSysImg, err := kd.GetRKESystemImages(k8sVersion, lh.SysImageLister, lh.SysImages) + if err != nil { + return err + } + rkeSysImgCopy := rkeSysImg.DeepCopy() + switch apiContext.ID { + case linuxImages: + rkeSysImgCopy.WindowsPodInfraContainer = "" + // removing weave images since it's not supported + rkeSysImgCopy.WeaveNode = "" + rkeSysImgCopy.WeaveCNI = "" + // removing noiro (Cisco ACI) since it's not supported + rkeSysImgCopy.AciCniDeployContainer = "" + rkeSysImgCopy.AciHostContainer = "" + rkeSysImgCopy.AciOpflexContainer = "" + rkeSysImgCopy.AciMcastContainer = "" + rkeSysImgCopy.AciOpenvSwitchContainer = "" + rkeSysImgCopy.AciControllerContainer = "" + rkeSysImgCopy.AciOpflexServerContainer = "" + rkeSysImgCopy.AciGbpServerContainer = "" + case windowsImages: + majorVersion := util.GetTagMajorVersion(k8sVersion) + if mVersion.Compare(majorVersion, "v1.13", "<=") { + continue + } + windowsSysImages := rketypes.RKESystemImages{ + Kubernetes: rkeSysImg.Kubernetes, + WindowsPodInfraContainer: rkeSysImg.WindowsPodInfraContainer, + NginxProxy: rkeSysImg.NginxProxy, + KubernetesServicesSidecar: rkeSysImg.KubernetesServicesSidecar, + CertDownloader: rkeSysImg.CertDownloader, + } + rkeSysImgCopy = &windowsSysImages + } + rkeSysImages[k8sVersion] = *rkeSysImgCopy + } + + var catalogImageList *v1.ConfigMap + catalogImageList, err = lh.ConfigMapLister.Get(namespace.System, utils.GetCatalogImageCacheName(utils.SystemLibraryName)) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "failed to get image list for system catalog") + } + + _, targetSysCatalogImages := image.ParseCatalogImageListConfigMap(catalogImageList) + + var targetRkeSysImages []string + exportConfig := image.ExportConfig{OsType: image.Linux} + switch apiContext.ID { + case linuxImages: + targetRkeSysImages, _, err = image.GetImages(exportConfig, nil, []string{}, rkeSysImages) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "error getting image list for linux platform") + } + case windowsImages: + exportConfig.OsType = image.Windows + targetRkeSysImages, _, err = image.GetImages(exportConfig, nil, []string{}, rkeSysImages) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "error getting image list for windows platform") + } + } + + var targetImages []string + agentImage := settings.AgentImage.Get() + targetImages = append(targetImages, img.Mirror(agentImage)) + targetImages = append(targetImages, targetRkeSysImages...) + targetImages = append(targetImages, targetSysCatalogImages...) + + b := []byte(strings.Join(targetImages, "\n")) + apiContext.Response.Header().Set("Content-Length", strconv.Itoa(len(b))) + apiContext.Response.Header().Set("Content-Type", "application/octet-stream") + apiContext.Response.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.txt", apiContext.ID)) + apiContext.Response.Header().Set("Cache-Control", "private") + apiContext.Response.Header().Set("Pragma", "private") + apiContext.Response.Header().Set("Expires", "Wed 24 Feb 1982 18:42:00 GMT") + apiContext.Response.WriteHeader(http.StatusOK) + _, err = apiContext.Response.Write(b) + return err +} + +func (lh ListHandler) ListHandler(request *types.APIContext, next types.RequestHandler) error { + if request.ID == linuxImages || request.ID == windowsImages { + return lh.LinkHandler(request, next) + } + return handler.ListHandler(request, next) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/formatter.go new file mode 100644 index 0000000..cf64f1f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/formatter.go @@ -0,0 +1,86 @@ +package kontainerdriver + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + "k8s.io/client-go/tools/cache" +) + +type Format struct { + ClusterIndexer cache.Indexer +} + +func RegisterIndexers(config *wrangler.Context) { + config.Mgmt.Cluster().Cache().AddIndexer(clusterByGenericEngineConfigKey, clusterByKontainerDriver) +} + +func NewFormatter(manangement *config.ScaledContext) types.Formatter { + clusterInformer := manangement.Management.Clusters("").Controller().Informer() + format := Format{ + ClusterIndexer: clusterInformer.GetIndexer(), + } + return format.Formatter +} + +func CollectionFormatter(apiContext *types.APIContext, collection *types.GenericCollection) { + collection.AddAction(apiContext, "refresh") + currContext := apiContext.URLBuilder.Current() + if !strings.HasSuffix(currContext, "/") { + currContext = fmt.Sprintf("%s/", currContext) + } + collection.Links["rancher-images"] = fmt.Sprintf("%srancher-images", currContext) + collection.Links["rancher-windows-images"] = fmt.Sprintf("%srancher-windows-images", currContext) +} + +const clusterByGenericEngineConfigKey = "genericEngineConfig" + +// clusterByKontainerDriver is an indexer function that uses the cluster genericEngineConfig +// driverName field +func clusterByKontainerDriver(cluster *v3.Cluster) ([]string, error) { + engineConfig := cluster.Spec.GenericEngineConfig + if engineConfig == nil { + return []string{}, nil + } + driverName, ok := (*engineConfig)["driverName"].(string) + if !ok { + return []string{}, nil + } + + return []string{driverName}, nil +} + +func (f *Format) Formatter(request *types.APIContext, resource *types.RawResource) { + state, ok := resource.Values["state"].(string) + if ok { + if state == "active" { + resource.AddAction(request, "deactivate") + } + + if state == "inactive" { + resource.AddAction(request, "activate") + } + } + // if cluster driver is a built-in, delete removal link from UI + if builtIn, _ := resource.Values[client.KontainerDriverFieldBuiltIn].(bool); builtIn { + delete(resource.Links, "remove") + return + } + resName := resource.Values["id"] + // resName will be nil when first added + if resName != nil { + clustersWithKontainerDriver, err := f.ClusterIndexer.ByIndex(clusterByGenericEngineConfigKey, resName.(string)) + if err != nil { + logrus.Warnf("failed to determine if kontainer driver %v was in use by a cluster : %v", resName.(string), err) + } else if len(clustersWithKontainerDriver) != 0 { + // if cluster driver in use, delete removal link from UI + delete(resource.Links, "remove") + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/store.go new file mode 100644 index 0000000..b7cdc75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/store.go @@ -0,0 +1,55 @@ +package kontainerdriver + +import ( + "fmt" + + errorsutil "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/client-go/tools/cache" +) + +type store struct { + types.Store + KontainerDriverLister v3.KontainerDriverLister + ClusterIndexer cache.Indexer +} + +func NewStore(management *config.ScaledContext, s types.Store) types.Store { + clusterInformer := management.Management.Clusters("").Controller().Informer() + kd := management.Management.KontainerDrivers("").Controller().Lister() + storeObj := store{ + Store: s, + KontainerDriverLister: kd, + ClusterIndexer: clusterInformer.GetIndexer(), + } + return &storeObj +} + +// Delete removes the KontainerDriver if it is not in use by a cluster +func (s *store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + //need to get the full driver since just the id is not enough see if it is builtin + driver, err := s.KontainerDriverLister.Get("", id) + if err != nil { + if !errors.IsNotFound(err) { + return nil, errorsutil.WithMessage(err, fmt.Sprintf("error getting kontainer driver %s", id)) + } + //if driver is not found, don't return error + return nil, nil + } + if driver.Spec.BuiltIn { + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "builtin cluster drivers may not be removed") + } + clustersWithKontainerDriver, err := s.ClusterIndexer.ByIndex(clusterByGenericEngineConfigKey, id) + if err != nil { + return nil, errorsutil.WithMessage(err, fmt.Sprintf("error determining if kontainer driver [%s] was in use", driver.Status.DisplayName)) + } + + if len(clustersWithKontainerDriver) != 0 { + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "cluster Driver is in use by one or more clusters, delete clusters before deleting this driver") + } + return s.Store.Delete(apiContext, schema, id) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/validator.go new file mode 100644 index 0000000..59cfbd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/kontainerdriver/validator.go @@ -0,0 +1,42 @@ +package kontainerdriver + +import ( + "fmt" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/labels" +) + +type Validator struct { + KontainerDriverLister v3.KontainerDriverLister +} + +func (v *Validator) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + var spec v32.KontainerDriverSpec + + if err := convert.ToObj(data, &spec); err != nil { + return httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Kontainer driver spec conversion error") + } + + return v.validateKontainerDriverURL(request, spec) +} + +func (v *Validator) validateKontainerDriverURL(request *types.APIContext, spec v32.KontainerDriverSpec) error { + kontainerDrivers, err := v.KontainerDriverLister.List("", labels.NewSelector()) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "Failed to list kontainer drivers") + } + + for _, driver := range kontainerDrivers { + if driver.Spec.URL == spec.URL && driver.Name != request.ID { + return httperror.NewAPIError(httperror.Conflict, fmt.Sprintf("Driver URL already in use: %s", spec.URL)) + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/multi_cluster_app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/multi_cluster_app.go new file mode 100644 index 0000000..d232fa3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/multi_cluster_app.go @@ -0,0 +1,315 @@ +package multiclusterapp + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/rbac" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + addProjectsAction = "addProjects" + removeProjectsAction = "removeProjects" +) + +var backoff = wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 2, + Jitter: 0, + Steps: 6, +} + +func (w Wrapper) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + if canUpdateMCA(apiContext, resource) == nil { + resource.AddAction(apiContext, "rollback") + resource.AddAction(apiContext, addProjectsAction) + resource.AddAction(apiContext, removeProjectsAction) + } + resource.Links["revisions"] = apiContext.URLBuilder.Link("revisions", resource) +} + +func (w Wrapper) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + var mcApp client.MultiClusterApp + if err := access.ByID(apiContext, &managementschema.Version, client.MultiClusterAppType, apiContext.ID, &mcApp); err != nil { + return err + } + if canUpdateMCA(apiContext, nil) != nil { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + switch actionName { + case "rollback": + data, err := ioutil.ReadAll(apiContext.Request.Body) + if err != nil { + return errors.Wrap(err, "reading request body error") + } + input := client.MultiClusterAppRollbackInput{} + if err = json.Unmarshal(data, &input); err != nil { + return errors.Wrap(err, "unmarshal input error") + } + id := input.RevisionID + splitID := strings.Split(input.RevisionID, ":") + if len(splitID) == 2 { + id = splitID[1] + } + revision, err := w.MultiClusterAppRevisionLister.Get(namespace.GlobalNamespace, id) + if err != nil { + return err + } + obj, err := w.MultiClusterApps.GetNamespaced(namespace.GlobalNamespace, mcApp.Name, v1.GetOptions{}) + if err != nil { + return err + } + if obj.Status.RevisionName == revision.Name { + return nil + } + + mcappTemplateVersionParts := strings.Split(mcApp.TemplateVersionID, "-") + mcappCurrentTemplateVersion := mcappTemplateVersionParts[len(mcappTemplateVersionParts)-1] + if err := w.validateChartCompatibility(revision.TemplateVersionName, mcappCurrentTemplateVersion, obj.Spec.Targets); err != nil { + return err + } + + toUpdate := obj.DeepCopy() + toUpdate.Spec.TemplateVersionName = revision.TemplateVersionName + toUpdate.Spec.Answers = revision.Answers + _, err = w.MultiClusterApps.Update(toUpdate) + return err + case addProjectsAction: + return w.addProjects(apiContext) + case removeProjectsAction: + return w.removeProjects(apiContext) + default: + return fmt.Errorf("bad action for multiclusterapp %v", actionName) + } +} + +func (w Wrapper) addProjects(request *types.APIContext) error { + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect multi cluster app ID %v", request.ID) + } + inputProjects, inputAnswers, err := w.modifyProjects(request, addProjectsAction) + if err != nil { + return err + } + + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + existingProjects := make(map[string]bool) + mcapp, err := w.MultiClusterApps.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return false, err + } + for _, p := range mcapp.Spec.Targets { + existingProjects[p.ProjectName] = true + } + for _, p := range inputProjects { + if existingProjects[p] { + return false, httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("duplicate projects in targets %s", p)) + } + existingProjects[p] = true + } + for _, name := range inputProjects { + mcapp.Spec.Targets = append(mcapp.Spec.Targets, v32.Target{ProjectName: name}) + } + if len(inputAnswers) > 0 { + mcapp.Spec.Answers = append(mcapp.Spec.Answers, inputAnswers...) + } + _, err = w.MultiClusterApps.Update(mcapp) + if err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return err + } + op := map[string]interface{}{ + "message": "addedProjects", + } + request.WriteResponse(http.StatusOK, op) + return nil +} + +func (w Wrapper) removeProjects(request *types.APIContext) error { + inputProjects, _, err := w.modifyProjects(request, removeProjectsAction) + if err != nil { + return err + } + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect multi cluster app ID %v", request.ID) + } + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + mcapp, err := w.MultiClusterApps.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return false, err + } + toRemoveProjects := make(map[string]bool) + var finalTargets []v32.Target + for _, p := range inputProjects { + toRemoveProjects[p] = true + } + for _, t := range mcapp.Spec.Targets { + if !toRemoveProjects[t.ProjectName] { + finalTargets = append(finalTargets, t) + } + } + // after this finalTargets will contain all mcapp targets, that aren't in inputProjects + mcapp.Spec.Targets = finalTargets + _, err = w.MultiClusterApps.Update(mcapp) + if err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return err + } + op := map[string]interface{}{ + "message": "removedProjects", + } + request.WriteResponse(http.StatusOK, op) + return nil +} + +func (w Wrapper) modifyProjects(request *types.APIContext, actionName string) ([]string, []v32.Answer, error) { + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return []string{}, []v32.Answer{}, fmt.Errorf("incorrect multi cluster app ID %v", request.ID) + } + var inputProjects []string + var inputAnswers []v32.Answer + mcapp, err := w.MultiClusterApps.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return inputProjects, inputAnswers, err + } + // ensure that caller is not a readonly member of multiclusterapp, else abort + callerID := request.Request.Header.Get(gaccess.ImpersonateUserHeader) + metaAccessor, err := meta.Accessor(mcapp) + if err != nil { + return inputProjects, inputAnswers, err + } + creatorID, ok := metaAccessor.GetAnnotations()[creatorIDAnn] + if !ok { + return inputProjects, inputAnswers, fmt.Errorf("multiclusterapp %v has no creatorId annotation", metaAccessor.GetName()) + } + ma := gaccess.MemberAccess{ + Users: w.Users, + PrtbLister: w.PrtbLister, + CrtbLister: w.CrtbLister, + RoleTemplateLister: w.RoleTemplateLister, + GrbLister: w.GrbLister, + GrLister: w.GrLister, + Prtbs: w.Prtbs, + Crtbs: w.Crtbs, + ProjectLister: w.ProjectLister, + ClusterLister: w.ClusterLister, + } + accessType, err := ma.GetAccessTypeOfCaller(callerID, creatorID, mcapp.Name, mcapp.Spec.Members) + if err != nil { + return inputProjects, inputAnswers, err + } + if accessType != gaccess.OwnerAccess { + return inputProjects, inputAnswers, fmt.Errorf("only owners can modify projects of multiclusterapp") + } + var updateMultiClusterAppTargetsInput client.UpdateMultiClusterAppTargetsInput + actionInput, err := parse.ReadBody(request.Request) + if err != nil { + return inputProjects, inputAnswers, err + } + if err = convert.ToObj(actionInput, &updateMultiClusterAppTargetsInput); err != nil { + return inputProjects, inputAnswers, err + } + inputProjects = updateMultiClusterAppTargetsInput.Projects + if actionName == addProjectsAction { + if err = ma.EnsureRoleInTargets(inputProjects, mcapp.Spec.Roles, callerID); err != nil { + return inputProjects, inputAnswers, err + } + } else if actionName == removeProjectsAction { + // we want to remove all roles that the mcapp's sys acc has in these projects being removed + if err = ma.RemoveRolesFromTargets(inputProjects, []string{}, mcapp.Name, true); err != nil { + return inputProjects, inputAnswers, err + } + } + for _, a := range updateMultiClusterAppTargetsInput.Answers { + inputAnswers = append(inputAnswers, v32.Answer{ + ProjectName: a.ProjectID, + ClusterName: a.ClusterID, + Values: a.Values, + ValuesSetString: a.ValuesSetString, + }) + } + // check if the input includes answers, and if they are only for the input projects + if len(inputAnswers) > 0 { + inputProjectsMap := make(map[string]bool) + for _, p := range inputProjects { + if !inputProjectsMap[p] { + inputProjectsMap[p] = true + } + } + for _, a := range inputAnswers { + if a.ProjectName == "" { + return inputProjects, inputAnswers, fmt.Errorf("can only provide project-scoped answers for new projects through add/remove projects action") + } + if !inputProjectsMap[a.ProjectName] { + return inputProjects, inputAnswers, fmt.Errorf("the project %v is not among the ones provided in input", a.ProjectName) + } + } + } + return inputProjects, inputAnswers, nil +} + +func (w Wrapper) validateChartCompatibility(tempVersion, currentAppVersion string, targets []v32.Target) error { + parts := strings.Split(tempVersion, ":") + if len(parts) != 2 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "invalid templateVersionId") + } + + template, err := w.TemplateVersionLister.Get(namespace.GlobalNamespace, parts[1]) + if err != nil { + return err + } + + if err := w.CatalogManager.ValidateRancherVersion(template, currentAppVersion); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + for _, target := range targets { + if err := w.CatalogManager.ValidateKubeVersion(template, target.ObjClusterName()); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + } + return nil +} + +func canUpdateMCA(apiContext *types.APIContext, resource *types.RawResource) error { + return apiContext.AccessControl.CanDo(v3.MultiClusterAppGroupVersionKind.Group, v3.MultiClusterAppResource.Name, + "update", apiContext, rbac.ObjFromContext(apiContext, resource), apiContext.Schema) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/store.go new file mode 100644 index 0000000..65cf6e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/store.go @@ -0,0 +1,237 @@ +package multiclusterapp + +import ( + "context" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/ref" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/catalog/manager" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clusterrouter" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +func SetMemberStore(ctx context.Context, schema *types.Schema, mgmt *config.ScaledContext) { + providers.Configure(ctx, mgmt) + userLister := mgmt.Management.Users("").Controller().Lister() + + t := &transform.Store{ + Store: schema.Store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + membersMapSlice, found := values.GetSlice(data, "members") + if !found { + return data, nil + } + for _, m := range membersMapSlice { + if userID, ok := m["userId"].(string); ok && userID != "" { + u, err := userLister.Get("", userID) + if err != nil { + logrus.Errorf("problem retrieving user for member %v from cache during member transformation: %v", data, err) + return data, nil + } + // filtering and keeping system user accounts out of the members list + for _, pid := range u.PrincipalIDs { + if strings.HasPrefix(pid, "system://") { + if opt != nil && opt.Options["ByID"] == "true" { + return nil, httperror.NewAPIError(httperror.NotFound, "resource not found") + } + return nil, nil + } + } + } + } + return data, nil + }, + } + + s := &Store{ + Store: t, + auth: requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, mgmt), + crtbLister: mgmt.Management.ClusterRoleTemplateBindings("").Controller().Lister(), + prtbLister: mgmt.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + grbLister: mgmt.Management.GlobalRoleBindings("").Controller().Lister(), + grLister: mgmt.Management.GlobalRoles("").Controller().Lister(), + templateVersionLister: mgmt.Management.CatalogTemplateVersions("").Controller().Lister(), + users: mgmt.Management.Users(""), + rtLister: mgmt.Management.RoleTemplates("").Controller().Lister(), + mcappLister: mgmt.Management.MultiClusterApps("").Controller().Lister(), + catalogManager: mgmt.CatalogManager, + } + + schema.Store = s +} + +type Store struct { + types.Store + auth requests.Authenticator + crtbLister v3.ClusterRoleTemplateBindingLister + prtbLister v3.ProjectRoleTemplateBindingLister + grbLister v3.GlobalRoleBindingLister + grLister v3.GlobalRoleLister + templateVersionLister v3.CatalogTemplateVersionLister + users v3.UserInterface + rtLister v3.RoleTemplateLister + mcappLister v3.MultiClusterAppLister + catalogManager manager.CatalogManager +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := s.validateChartCompatibility("", data); err != nil { + return nil, err + } + + if err := checkDuplicateTargets(data); err != nil { + return nil, err + } + data, err := s.setDisplayName(apiContext, schema, data) + if err != nil { + return nil, err + } + if err = s.ensureRolesNotDisabled(apiContext, data); err != nil { + return nil, err + } + return s.Store.Create(apiContext, schema, data) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := s.validateChartCompatibility(id, data); err != nil { + return nil, err + } + + data, err := s.setDisplayName(apiContext, schema, data) + if err != nil { + return nil, err + } + if err = s.ensureRolesNotDisabled(apiContext, data); err != nil { + return nil, err + } + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *Store) setDisplayName(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + membersMapSlice, found := values.GetSlice(data, client.MultiClusterAppFieldMembers) + if !found { + return data, nil + } + token, err := s.auth.TokenFromRequest(apiContext.Request) + if err != nil { + return nil, err + } + if token.AuthProvider == providers.LocalProvider { + // getPrincipal if called, will be called on local auth provider, and will not find a user with external auth principal ID + // hence returning, since the only thing this method does is setting display name by getting it from the external auth provider. + return data, nil + } + for _, m := range membersMapSlice { + if principalID, ok := m[client.MemberFieldUserPrincipalID].(string); ok && principalID != "" && !strings.HasPrefix(principalID, "local://") { + princ, err := providers.GetPrincipal(principalID, *token) + if err != nil { + return nil, err + } + if princ.DisplayName != "" { + values.PutValue(m, princ.DisplayName, "displayName") + } + } + } + return data, nil +} + +func (s *Store) ensureRolesNotDisabled(apiContext *types.APIContext, data map[string]interface{}) error { + roles := convert.ToStringSlice(data[client.MultiClusterAppFieldRoles]) + if len(roles) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "No roles provided") + } + for _, role := range roles { + rt, err := s.rtLister.Get("", role) + if err != nil { + if apierrors.IsNotFound(err) { + errMsg := fmt.Sprintf("Provided role %v does not exist", role) + return httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + return err + } + if rt.Locked { + errMsg := fmt.Sprintf("Cannot assigned locked role %v to multiclusterapp", role) + return httperror.NewAPIError(httperror.InvalidBodyContent, errMsg) + } + } + return nil +} + +func (s *Store) validateChartCompatibility(id string, data map[string]interface{}) error { + rawTempVersion, ok := data["templateVersionId"] + if !ok { + return nil + } + + tempVersion := rawTempVersion.(string) + + parts := strings.Split(tempVersion, ":") + if len(parts) != 2 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "invalid templateVersionId") + } + + template, err := s.templateVersionLister.Get(namespace.GlobalNamespace, parts[1]) + if err != nil { + return err + } + + var mcappCurrentTemplateVersion string + mcappNamespace, mcappID := ref.Parse(id) + if mcappID != "" { + mcapp, err := s.mcappLister.Get(mcappNamespace, mcappID) + if err != nil { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("cannot find multiclusterapp [%s:%s]", mcappNamespace, mcappID)) + } + mcappTemplateVersionParts := strings.Split(mcapp.Spec.TemplateVersionName, "-") + mcappCurrentTemplateVersion = mcappTemplateVersionParts[len(mcappTemplateVersionParts)-1] + } + + if err := s.catalogManager.ValidateRancherVersion(template, mcappCurrentTemplateVersion); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + targets, _ := data["targets"].([]interface{}) + for _, target := range targets { + targetMap, ok := target.(map[string]interface{}) + if !ok { + continue + } + parts := strings.SplitN(targetMap["projectId"].(string), ":", 2) + if len(parts) != 2 { + continue + } + if err := s.catalogManager.ValidateKubeVersion(template, parts[0]); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + } + return nil +} + +func checkDuplicateTargets(data map[string]interface{}) error { + targets, _ := values.GetSlice(data, "targets") + projectIDs := map[string]bool{} + for _, target := range targets { + id := convert.ToString(values.GetValueN(target, "projectId")) + if id != "" { + if _, ok := projectIDs[id]; ok { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("duplicate projects in targets %s", id)) + } + projectIDs[id] = true + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/validator_multiclusterapp.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/validator_multiclusterapp.go new file mode 100644 index 0000000..2ec1672 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/multiclusterapp/validator_multiclusterapp.go @@ -0,0 +1,207 @@ +package multiclusterapp + +import ( + "fmt" + "net/http" + "reflect" + "sort" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/set" + "github.com/rancher/norman/types/values" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + "github.com/rancher/rancher/pkg/catalog/manager" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +type Wrapper struct { + MultiClusterApps v3.MultiClusterAppInterface + MultiClusterAppLister v3.MultiClusterAppLister + MultiClusterAppRevisionLister v3.MultiClusterAppRevisionLister + PrtbLister v3.ProjectRoleTemplateBindingLister + CrtbLister v3.ClusterRoleTemplateBindingLister + RoleTemplateLister v3.RoleTemplateLister + Users v3.UserInterface + GrbLister v3.GlobalRoleBindingLister + GrLister v3.GlobalRoleLister + Prtbs v3.ProjectRoleTemplateBindingInterface + Crtbs v3.ClusterRoleTemplateBindingInterface + ProjectLister v3.ProjectLister + ClusterLister v3.ClusterLister + Apps pv3.AppInterface + TemplateVersionLister v3.CatalogTemplateVersionLister + CatalogManager manager.CatalogManager +} + +const ( + mcAppLabel = "io.cattle.field/multiClusterAppId" + creatorIDAnn = "field.cattle.io/creatorId" +) + +func (w Wrapper) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "revisions": + var app client.MultiClusterApp + if err := access.ByID(apiContext, &managementschema.Version, client.MultiClusterAppType, apiContext.ID, &app); err != nil { + return err + } + var appRevisions, filtered []map[string]interface{} + if err := access.List(apiContext, &managementschema.Version, client.MultiClusterAppRevisionType, &types.QueryOptions{}, &appRevisions); err != nil { + return err + } + for _, revision := range appRevisions { + labels := convert.ToMapInterface(revision["labels"]) + if reflect.DeepEqual(labels[mcAppLabel], app.Name) { + filtered = append(filtered, revision) + } + } + sort.SliceStable(filtered, func(i, j int) bool { + val1, err := time.Parse(time.RFC3339, convert.ToString(values.GetValueN(filtered[i], "created"))) + if err != nil { + logrus.Infof("error parsing time %v", err) + } + val2, err := time.Parse(time.RFC3339, convert.ToString(values.GetValueN(filtered[j], "created"))) + if err != nil { + logrus.Infof("error parsing time %v", err) + } + return val1.After(val2) + }) + apiContext.Type = client.MultiClusterAppRevisionType + apiContext.WriteResponse(http.StatusOK, filtered) + return nil + } + return nil +} + +func (w Wrapper) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method != http.MethodPut && request.Method != http.MethodPost { + return nil + } + ma := gaccess.MemberAccess{ + Users: w.Users, + PrtbLister: w.PrtbLister, + CrtbLister: w.CrtbLister, + RoleTemplateLister: w.RoleTemplateLister, + GrbLister: w.GrbLister, + GrLister: w.GrLister, + Prtbs: w.Prtbs, + Crtbs: w.Crtbs, + ProjectLister: w.ProjectLister, + ClusterLister: w.ClusterLister, + } + var targetProjects []string + callerID := request.Request.Header.Get(gaccess.ImpersonateUserHeader) + if request.Method == http.MethodPost { + // create request, caller is owner/creator + // Request is POST, hence multiclusterapp is being created. + // check if creator has the given roles in all target projects + targets, _ := values.GetSlice(data, client.MultiClusterAppFieldTargets) + for _, t := range targets { + targetProjects = append(targetProjects, convert.ToString(t[client.TargetFieldProjectID])) + } + roleTemplates := convert.ToStringSlice(data[client.MultiClusterAppFieldRoles]) + return ma.EnsureRoleInTargets(targetProjects, roleTemplates, callerID) + } + // edit request, only editing members, roles and answers is allowed through this + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("incorrect multiclusterapp ID %v", request.ID) + } + mcapp, err := w.MultiClusterApps.GetNamespaced(split[0], split[1], v1.GetOptions{}) + if err != nil { + return err + } + metaAccessor, err := meta.Accessor(mcapp) + if err != nil { + return err + } + creatorID, ok := metaAccessor.GetAnnotations()[creatorIDAnn] + if !ok { + return fmt.Errorf("MultiClusterApp %v has no creatorId annotation", metaAccessor.GetName()) + } + accessType, err := ma.GetAccessTypeOfCaller(callerID, creatorID, mcapp.Name, mcapp.Spec.Members) + if err != nil { + return err + } + if accessType == gaccess.ReadonlyAccess { + return fmt.Errorf("read-only members cannot update multiclusterapp") + } + ownerAccess := accessType == gaccess.OwnerAccess + // only members and roles list, and templateversion/answers can be edited through PUT, for updating target projects, we need to use actions only + // that's why target projects field has been made non updatable in rancher/types + if err := gaccess.CheckAccessToUpdateMembers(mcapp.Spec.Members, data, ownerAccess); err != nil { + return err + } + + // check whether roles are being edited, if yes then only owner should be allowed to, and should have this role in all projects + roles := convert.ToStringSlice(data[client.MultiClusterAppFieldRoles]) + newRoles := make(map[string]bool) + for _, r := range roles { + newRoles[r] = true + } + originalRoles := make(map[string]bool) + for _, r := range mcapp.Spec.Roles { + originalRoles[r] = true + } + // get difference between new and original roles + rolesToAdd, rolesToRemove, _ := set.Diff(newRoles, originalRoles) + if len(rolesToAdd) == 0 && len(rolesToRemove) == 0 { + // this UPDATE request is not modifying the multiclusterapp roles. + // So return without calling EnsureRoleInTargets, because this UPDATE could be called by a mcapp member with access type member, + // just to update the templateversion or answers; this member is allowed to not have all roles in all targets + return nil + } + if (len(rolesToAdd) != 0 || len(rolesToRemove) != 0) && !ownerAccess { + return fmt.Errorf("user %v is not an owner of multiclusterapp %v, cannot edit roles", callerID, mcapp.Name) + } + // check if modifier has all roles listed in toAdd in all projects + for _, t := range mcapp.Spec.Targets { + targetProjects = append(targetProjects, t.ProjectName) + } + if err = ma.EnsureRoleInTargets(targetProjects, rolesToAdd, callerID); err != nil { + return err + } + // at this point we know the roles have changed, and that the user has the new roles in targets, + // retry underlying app upgrade + for _, t := range mcapp.Spec.Targets { + _, projectNS := ref.Parse(t.ProjectName) + if t.AppName != "" { + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + app, err := w.Apps.GetNamespaced(projectNS, t.AppName, v1.GetOptions{}) + if err != nil || app == nil { + return false, fmt.Errorf("error %v getting app %s in %s", err, t.AppName, projectNS) + } + if val, ok := app.Labels["mcapp"]; !ok || val != mcapp.Name { + return false, fmt.Errorf("app %s in %s missing multi cluster app label", t.AppName, projectNS) + } + v32.AppConditionUserTriggeredAction.True(app) + if _, err := w.Apps.Update(app); err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return err + } + } + } + return ma.RemoveRolesFromTargets(targetProjects, rolesToRemove, mcapp.Name, false) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/link.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/link.go new file mode 100644 index 0000000..c867289 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/link.go @@ -0,0 +1,124 @@ +package namespace + +import ( + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/resourcelink" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + printers2 "k8s.io/cli-runtime/pkg/printers" + "k8s.io/kubernetes/pkg/printers" +) + +var ExportPrinters = map[string]printers.ResourcePrinter{ + "json": &printers2.JSONPrinter{}, + "yaml": &printers2.YAMLPrinter{}, +} + +func NewLinkHandler(next types.RequestHandler, manager *clustermanager.Manager) types.RequestHandler { + + lh := &yamlLinkHandler{ + next: next, + clusterManagement: manager, + } + + return lh.LinkHandler +} + +type yamlLinkHandler struct { + next types.RequestHandler + clusterManagement *clustermanager.Manager +} + +func (s *yamlLinkHandler) callNext(apiContext *types.APIContext, next types.RequestHandler) error { + if s.next != nil { + return s.next(apiContext, next) + } else if next != nil { + return next(apiContext, nil) + } + + return httperror.NewAPIError(httperror.NotFound, "link not found") +} + +func (s *yamlLinkHandler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + if apiContext.Link != "yaml" { + return s.callNext(apiContext, next) + } + + clusterName := s.clusterManagement.ClusterName(apiContext) + + userContext, err := s.clusterManagement.UserContextNoControllers(clusterName) + if err != nil { + return err + } + + ns := apiContext.ID + result := &unstructured.UnstructuredList{} + result.SetAPIVersion("v1") + result.SetKind("List") + + resources := apiContext.Request.URL.Query()["resource"] + toExportResourceMappings := getResourcePrefixMap(resources) + + for kind, prefix := range toExportResourceMappings { + + req := userContext.UnversionedClient.Get().Prefix(prefix).Namespace(ns).Resource(kind) + for k, v := range apiContext.Request.URL.Query() { + req.Param(k, strings.Join(v, ",")) + } + for k, v := range apiContext.Request.Header { + if k == "Authorization" { + continue + } + req.SetHeader(k, v...) + } + req.SetHeader("Accept", "*/*") + + r, err := req.Do(apiContext.Request.Context()).Get() + if err != nil { + if e, ok := err.(*apierrors.StatusError); ok && e.Status().Code == 403 { + continue + } + return err + } + + if list, ok := r.(*unstructured.UnstructuredList); ok { + for _, item := range list.Items { + if len(item.GetOwnerReferences()) == 0 { + result.Items = append(result.Items, item) + } + } + } + } + + printer := ExportPrinters["json"] + apiContext.Response.Header().Set("content-type", "application/json") + + if apiContext.Request.Header.Get("Accept") == "application/yaml" { + printer = ExportPrinters["yaml"] + apiContext.Response.Header().Set("content-type", "application/yaml") + } + + return printer.PrintObj(result, apiContext.Response) +} + +// getResourcePrefixMap converts resource path like `/api/v1/pods` to kind-prefix mappings +func getResourcePrefixMap(resources []string) map[string]string { + if len(resources) == 0 { + return resourcelink.ExportResourcePrefixMappings + } + m := map[string]string{} + for _, r := range resources { + idx := strings.LastIndex(r, "/") + if idx == -1 { + m[r] = "" + } else { + m[r[idx+1:]] = r[:idx] + } + + } + return m +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/namespace.go new file mode 100644 index 0000000..53aa3b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespace/namespace.go @@ -0,0 +1,136 @@ +package namespace + +import ( + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/ref" + schema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/cache" +) + +var ( + namespaceOwnerMap = cache.NewLRUExpireCache(1000) +) + +func updateNamespaceOwnerMap(apiContext *types.APIContext) error { + var namespaces []client.Namespace + if err := access.List(apiContext, &schema.Version, client.NamespaceType, &types.QueryOptions{}, &namespaces); err != nil { + return err + } + + for _, namespace := range namespaces { + namespaceOwnerMap.Add(namespace.Name, namespace.ProjectID, time.Hour) + } + + return nil +} + +func ProjectMap(apiContext *types.APIContext, refresh bool) (map[string]string, error) { + if refresh { + err := updateNamespaceOwnerMap(apiContext) + if err != nil { + return nil, err + } + } + + data := map[string]string{} + for _, key := range namespaceOwnerMap.Keys() { + if val, ok := namespaceOwnerMap.Get(key); ok { + data[key.(string)] = val.(string) + } + } + + return data, nil +} + +type ActionWrapper struct { + ClusterManager *clustermanager.Manager +} + +func (w ActionWrapper) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + actionInput, err := parse.ReadBody(apiContext.Request) + if err != nil { + return err + } + + if !canUpdateNS(apiContext, nil) { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + + switch actionName { + case "move": + clusterID := w.ClusterManager.ClusterName(apiContext) + _, projectID := ref.Parse(convert.ToString(actionInput["projectId"])) + userContext, err := w.ClusterManager.UserContextNoControllers(clusterID) + if err != nil { + if !kerrors.IsNotFound(err) { + return err + } + return httperror.NewAPIError(httperror.NotFound, err.Error()) + } + if projectID != "" { + project, err := userContext.Management.Management.Projects(clusterID).Get(projectID, metav1.GetOptions{}) + if err != nil { + return err + } + if project.Spec.ResourceQuota != nil { + return errors.Errorf("can't move namespace. Project %s has resource quota set", project.Spec.DisplayName) + } + } + nsClient := userContext.Core.Namespaces("") + ns, err := nsClient.Get(apiContext.ID, metav1.GetOptions{}) + if err != nil { + if !kerrors.IsNotFound(err) { + return err + } + return httperror.NewAPIError(httperror.NotFound, err.Error()) + } + if ns.Annotations[helm.AppIDsLabel] != "" { + return errors.New("namespace is currently being used") + } + if projectID == "" { + delete(ns.Annotations, nslabels.ProjectIDFieldLabel) + delete(ns.Labels, nslabels.ProjectIDFieldLabel) + } else { + ns.Annotations[nslabels.ProjectIDFieldLabel] = convert.ToString(actionInput["projectId"]) + } + if _, err := nsClient.Update(ns); err != nil { + return err + } + default: + return errors.New("invalid action") + } + return nil +} + +func NewFormatter(next types.Formatter) types.Formatter { + return func(request *types.APIContext, resource *types.RawResource) { + if next != nil { + next(request, resource) + } + annotations := convert.ToMapInterface(resource.Values["annotations"]) + canUpdate := canUpdateNS(request, resource) + if canUpdate && convert.ToString(annotations[helm.AppIDsLabel]) == "" { + resource.AddAction(request, "move") + } + } +} + +func canUpdateNS(apiContext *types.APIContext, resource *types.RawResource) bool { + obj := rbac.ObjFromContext(apiContext, resource) + // the user must have * permissions on namespace, the create-ns role alone won't return true here + return apiContext.AccessControl.CanDo("", "namespaces", "update", apiContext, obj, apiContext.Schema) == nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespacedresource/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespacedresource/store.go new file mode 100644 index 0000000..d8dd270 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/namespacedresource/store.go @@ -0,0 +1,39 @@ +package namespacedresource + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" +) + +// NamespacedStore makes sure that the namespaced resources are assigned to a given namespace +type namespacedStore struct { + types.Store + NamespaceInterface v1.NamespaceInterface + Namespace string +} + +func Wrap(store types.Store, nsClient v1.NamespaceInterface, namespace string) types.Store { + return &namespacedStore{ + Store: store, + NamespaceInterface: nsClient, + Namespace: namespace, + } +} + +func (s *namespacedStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + ns, ok := values.GetValue(data, client.PreferenceFieldNamespaceId) + if ok && !strings.EqualFold(convert.ToString(ns), s.Namespace) { + return nil, fmt.Errorf("error creating namespaced resource, cannot assign to %v since already assigned to %v namespace", namespace.GlobalNamespace, ns) + } else if !ok { + data[client.PreferenceFieldNamespaceId] = s.Namespace + } + + return s.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node.go new file mode 100644 index 0000000..3906ea4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node.go @@ -0,0 +1,293 @@ +package node + +import ( + "archive/tar" + "archive/zip" + "bytes" + "compress/gzip" + "encoding/base64" + "fmt" + "io" + "net/http" + "strconv" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/mitchellh/mapstructure" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/encryptedstore" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" +) + +var toIgnoreErrs = []string{"--ignore-daemonsets", "--delete-local-data", "--force", "did not complete within"} +var allowedStates = map[string]bool{"active": true, "cordoned": true, "draining": true, "drained": true} + +// Formatter for Node +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + etcd := convert.ToBool(resource.Values[client.NodeFieldEtcd]) + cp := convert.ToBool(resource.Values[client.NodeFieldControlPlane]) + worker := convert.ToBool(resource.Values[client.NodeFieldWorker]) + if !etcd && !cp && !worker { + resource.Values[client.NodeFieldWorker] = true + } + + // add nodeConfig link + canUpdateNode := false + if err := apiContext.AccessControl.CanDo(v3.NodeGroupVersionKind.Group, v3.NodeResource.Name, "update", apiContext, resource.Values, apiContext.Schema); err == nil { + canUpdateNode = true + resource.Links["nodeConfig"] = apiContext.URLBuilder.Link("nodeConfig", resource) + } + + // remove link + nodeTemplateID := resource.Values["nodeTemplateId"] + customConfig := resource.Values["customConfig"] + if nodeTemplateID == nil { + delete(resource.Links, "nodeConfig") + } else if canUpdateNode { + resource.AddAction(apiContext, "scaledown") + } + + if nodeTemplateID == nil && customConfig == nil { + delete(resource.Links, "remove") + } + if resource.Values[client.NodeFieldWorker] != true { + return + } + state := convert.ToString(resource.Values["state"]) + if _, ok := allowedStates[state]; !ok { + return + } + if state == "draining" { + override := false + for _, cond := range convert.ToMapSlice(resource.Values["conditions"]) { + if cond["type"] == "Drained" && cond["status"] == "False" { + if ignoreErr(convert.ToString(cond["message"])) { + override = true + resource.Values["state"] = "cordoned" + break + } + } + } + if !override { + resource.AddAction(apiContext, "stopDrain") + return + } + } + if state != "drained" { + resource.AddAction(apiContext, "drain") + } + if convert.ToBool(resource.Values["unschedulable"]) { + resource.AddAction(apiContext, "uncordon") + } else { + resource.AddAction(apiContext, "cordon") + } +} + +type ActionWrapper struct{} + +func (a ActionWrapper) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + switch actionName { + case "cordon": + return cordonUncordonNode(actionName, apiContext, true) + case "uncordon": + return cordonUncordonNode(actionName, apiContext, false) + case "drain": + return drainNode(actionName, apiContext, false) + case "stopDrain": + return drainNode(actionName, apiContext, true) + case "scaledown": + return scaledownNode(actionName, apiContext) + } + return nil +} + +func scaledownNode(actionName string, apiContext *types.APIContext) error { + node, schema, err := getNodeAndSchema(apiContext) + if err != nil { + return err + } + + values.PutValue(node, time.Now().Format(time.RFC3339), "scaledownTime") + err = updateNode(apiContext, node, schema, actionName) + if err != nil { + return err + } + apiContext.WriteResponse(http.StatusOK, map[string]interface{}{}) + return nil +} + +func cordonUncordonNode(actionName string, apiContext *types.APIContext, cordon bool) error { + node, schema, err := getNodeAndSchema(apiContext) + if err != nil { + return err + } + unschedulable := convert.ToBool(values.GetValueN(node, "unschedulable")) + if cordon == unschedulable { + return httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Node %s already %sed", apiContext.ID, actionName)) + } + values.PutValue(node, convert.ToString(!unschedulable), "desiredNodeUnschedulable") + err = updateNode(apiContext, node, schema, actionName) + if err != nil { + return err + } + apiContext.WriteResponse(http.StatusOK, map[string]interface{}{}) + return nil +} + +func drainNode(actionName string, apiContext *types.APIContext, stop bool) error { + node, schema, err := getNodeAndSchema(apiContext) + if err != nil { + return err + } + if !stop { + drainInput, err := validateDrainInput(apiContext) + if err != nil { + return err + } + if drainInput != nil && drainInput.IgnoreDaemonSets == nil { + trueVal := true + drainInput.IgnoreDaemonSets = &trueVal + } + values.PutValue(node, drainInput, "nodeDrainInput") + } + values.PutValue(node, actionName, "desiredNodeUnschedulable") + err = updateNode(apiContext, node, schema, actionName) + if err != nil { + return err + } + apiContext.WriteResponse(http.StatusOK, map[string]interface{}{}) + return nil +} + +func validateDrainInput(apiContext *types.APIContext) (*v32.NodeDrainInput, error) { + input, err := handler.ParseAndValidateActionBody(apiContext, apiContext.Schemas.Schema(&managementschema.Version, + client.NodeDrainInputType)) + if err != nil { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse action body: %v", err)) + } + drainInput := &v32.NodeDrainInput{} + if err := mapstructure.Decode(input, drainInput); err != nil { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + return drainInput, nil +} + +func getNodeAndSchema(apiContext *types.APIContext) (map[string]interface{}, *types.Schema, error) { + var node map[string]interface{} + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &node); err != nil { + return nil, nil, httperror.NewAPIError(httperror.InvalidReference, "Error accessing node") + } + schema := apiContext.Schemas.Schema(&managementschema.Version, client.NodeType) + return node, schema, nil +} + +type Handler struct { + SecretStore *encryptedstore.GenericEncryptedStore +} + +func (h Handler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + var node map[string]interface{} + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &node); err != nil { + return err + } + + if err := apiContext.AccessControl.CanDo(v3.NodeGroupVersionKind.Group, v3.NodeResource.Name, "update", apiContext, node, apiContext.Schema); err != nil { + return err + } + + nID, _ := node["id"].(string) + nodeID := strings.Split(nID, ":")[1] + secret, err := h.SecretStore.Get(nodeID) + if err != nil { + return err + } + data, err := base64.StdEncoding.DecodeString(secret[configKey]) + if err != nil { + return err + } + + gzipReader, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return err + } + tarReader := tar.NewReader(gzipReader) + + buf := new(bytes.Buffer) + w := zip.NewWriter(buf) + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + break + } + return fmt.Errorf("error reinitializing config (tarRead.Next): %v", err) + } + parts := strings.Split(header.Name, "/") + if len(parts) != 4 { + continue + } + + if parts[3] == "config.json" { + continue + } + fh := &zip.FileHeader{} + fh.Name = fmt.Sprintf("%s/%s", parts[2], parts[3]) + fh.SetMode(0400) + file, err := w.CreateHeader(fh) + if err != nil { + return err + } + buf := &bytes.Buffer{} + _, err = io.Copy(buf, tarReader) + if err != nil { + return err + } + _, err = file.Write(buf.Bytes()) + if err != nil { + return err + } + } + if err := w.Close(); err != nil { + return err + } + + apiContext.Response.Header().Set("Content-Length", strconv.Itoa(len(buf.Bytes()))) + apiContext.Response.Header().Set("Content-Type", "application/octet-stream") + apiContext.Response.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip", node[client.NodeSpecFieldRequestedHostname])) + apiContext.Response.Header().Set("Cache-Control", "private") + apiContext.Response.Header().Set("Pragma", "private") + apiContext.Response.Header().Set("Expires", "Wed 24 Feb 1982 18:42:00 GMT") + apiContext.Response.WriteHeader(http.StatusOK) + _, err = apiContext.Response.Write(buf.Bytes()) + if err != nil { + return err + } + return nil +} + +func updateNode(apiContext *types.APIContext, node map[string]interface{}, schema *types.Schema, actionName string) error { + if _, err := schema.Store.Update(apiContext, schema, node, apiContext.ID); err != nil { + return err + } + return nil +} + +func ignoreErr(msg string) bool { + for _, val := range toIgnoreErrs { + if strings.Contains(msg, val) { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node_driver.go new file mode 100644 index 0000000..9bfd595 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/node/node_driver.go @@ -0,0 +1,122 @@ +package node + +import ( + "bytes" + "net/http" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "encoding/json" + + "github.com/ghodss/yaml" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/generated/compose" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + configKey = "extractedConfig" +) + +type DriverHandlers struct { + NodeDriverClient v3.NodeDriverInterface +} + +func (h *DriverHandlers) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + m, err := h.NodeDriverClient.GetNamespaced("", apiContext.ID, metav1.GetOptions{}) + if err != nil { + return err + } + + // passing nil as the resource only works because just namespace is grabbed from it and nodedriver is not namespaced + if err := apiContext.AccessControl.CanDo(v3.NodeDriverGroupVersionKind.Group, v3.NodeDriverResource.Name, "update", apiContext, nil, apiContext.Schema); err != nil { + return err + } + + switch actionName { + case "activate": + m.Spec.Active = true + v32.NodeDriverConditionActive.Unknown(m) + case "deactivate": + m.Spec.Active = false + v32.NodeDriverConditionInactive.Unknown(m) + var newConditions []v32.Condition + for _, cond := range m.Status.Conditions { + // remove downloaded and installed conditions if stuck in unknown, + // this allows state to correctly show up as inactive vs downloading/installing + if cond.Type == "Downloaded" && cond.Status == "Unknown" { + continue + } + if cond.Type == "Installed" && cond.Status == "Unknown" { + continue + } + newConditions = append(newConditions, cond) + } + m.Status.Conditions = newConditions + } + + _, err = h.NodeDriverClient.Update(m) + if err != nil { + return err + } + + data := map[string]interface{}{} + if err := access.ByID(apiContext, apiContext.Version, apiContext.Type, apiContext.ID, &data); err != nil { + return err + } + + apiContext.WriteResponse(http.StatusOK, data) + return nil +} + +// Formatter for NodeDriver +func (h *DriverHandlers) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + if err := apiContext.AccessControl.CanDo(v3.NodeDriverGroupVersionKind.Group, v3.NodeDriverResource.Name, "update", apiContext, resource.Values, apiContext.Schema); err == nil { + resource.AddAction(apiContext, "activate") + resource.AddAction(apiContext, "deactivate") + } + resource.Links["exportYaml"] = apiContext.URLBuilder.Link("exportYaml", resource) +} + +func (h DriverHandlers) ExportYamlHandler(apiContext *types.APIContext, next types.RequestHandler) error { + switch apiContext.Link { + case "exportyaml": + nodeDriver, err := h.NodeDriverClient.Get(apiContext.ID, metav1.GetOptions{}) + if err != nil { + return err + } + topkey := compose.Config{} + topkey.Version = "v3" + nd := client.NodeDriver{} + if err := convert.ToObj(nodeDriver.Spec, &nd); err != nil { + return err + } + topkey.NodeDrivers = map[string]client.NodeDriver{} + topkey.NodeDrivers[nodeDriver.Spec.DisplayName] = nd + m, err := convert.EncodeToMap(topkey) + if err != nil { + return err + } + delete(m["nodeDrivers"].(map[string]interface{})[nodeDriver.Spec.DisplayName].(map[string]interface{}), "actions") + delete(m["nodeDrivers"].(map[string]interface{})[nodeDriver.Spec.DisplayName].(map[string]interface{}), "links") + data, err := json.Marshal(m) + if err != nil { + return err + } + + buf, err := yaml.JSONToYAML(data) + if err != nil { + return err + } + reader := bytes.NewReader(buf) + apiContext.Response.Header().Set("Content-Type", "text/yaml") + http.ServeContent(apiContext.Response, apiContext.Request, "exportYaml", time.Now(), reader) + return nil + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/formatter.go new file mode 100644 index 0000000..54f288c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/formatter.go @@ -0,0 +1,35 @@ +package nodepool + +import ( + "strings" + + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +type Formatter struct { + NodeTemplateLister v3.NodeTemplateLister +} + +func (ntf *Formatter) Formatter(request *types.APIContext, resource *types.RawResource) { + nodeTemplateID, _ := resource.Values[client.NodePoolFieldNodeTemplateID].(string) + if nodeTemplateID == "" { + return + } + + // id is namespace:name + parts := strings.Split(nodeTemplateID, ":") + if len(parts) != 2 { + return + } + + template, err := ntf.NodeTemplateLister.Get(parts[0], parts[1]) + if err != nil { + logrus.Warnf("Failed to get nodeTemplate driver for nodePool %v. Error: %v", resource.ID, err) + return + } + + resource.Values["driver"] = template.Spec.Driver +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/validator.go new file mode 100644 index 0000000..bd7127f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodepool/validator.go @@ -0,0 +1,59 @@ +package nodepool + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + mgmtSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" +) + +type Validator struct { + NodePoolLister v3.NodePoolLister +} + +func (v *Validator) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + // validate access to nodetemplate + nodetemplateID, ok := data["nodeTemplateId"].(string) + if !ok { + // nodetemplate not passed, nothing to check + return nil + } + if request.ID == "" { + // creating new pool, confirm access to template + return checkNodetemplateAccess(request, nodetemplateID) + } + + // validate request ID is in the right format + split := strings.SplitN(request.ID, ":", 2) + if len(split) != 2 { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("unable to find nodepool [%s]", request.ID)) + } + cluster, nodepool := split[0], split[1] + np, err := v.NodePoolLister.Get(cluster, nodepool) + if err != nil { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("unable to find nodepool [%s]", request.ID)) + } + + if np.Spec.NodeTemplateName != nodetemplateID { + // pulling from lister failed, or update attempt to the nodetemplate + return checkNodetemplateAccess(request, nodetemplateID) + } + + return nil +} + +func checkNodetemplateAccess(request *types.APIContext, nodetemplateID string) error { + if err := access.ByID(request, &mgmtSchema.Version, mgmtclient.NodeTemplateType, nodetemplateID, nil); err != nil { + if httperror.IsNotFound(err) || httperror.IsForbidden(err) { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("unable to find node template [%s]", nodetemplateID)) + } + return httperror.NewAPIError(httperror.ServerError, err.Error()) + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/formatter.go new file mode 100644 index 0000000..21ec4c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/formatter.go @@ -0,0 +1,63 @@ +package nodetemplate + +import ( + "strings" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" +) + +type Formatter struct { + NodePoolLister v3.NodePoolLister + NodeLister v3.NodeLister + UserLister v3.UserLister +} + +func (ntf *Formatter) Formatter(request *types.APIContext, resource *types.RawResource) { + pools, err := ntf.NodePoolLister.List("", labels.Everything()) + if err != nil { + logrus.Warnf("Failed to determine if Node Template is being used. Error: %v", err) + return + } + + for _, pool := range pools { + if pool.Spec.NodeTemplateName == resource.ID { + delete(resource.Links, "remove") + break + } + } + // Only check node references if remove link is still present + if _, ok := resource.Links["remove"]; ok { + nodes, err := ntf.NodeLister.List("", labels.Everything()) + if err != nil { + logrus.Warnf("Failed to determine if Node Template is being used. Error: %v", err) + return + } + for _, node := range nodes { + if node.Spec.NodeTemplateName == resource.ID { + delete(resource.Links, "remove") + break + } + } + } + + creatorID, _ := resource.Values["creatorId"].(string) + + user, err := ntf.UserLister.Get("", creatorID) + if err != nil { + if !errors.IsNotFound(err) { + logrus.Warnf("[NodeTemplate Formatter] Failed to to get user associated with creatorId [%s]. Error: %v", creatorID, err) + } + return + } + + for _, principalID := range user.PrincipalIDs { + if strings.HasPrefix(principalID, "local://") { + resource.Values["principalId"] = principalID + return + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/validation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/validation.go new file mode 100644 index 0000000..6c3a894 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/nodetemplate/validation.go @@ -0,0 +1,36 @@ +package nodetemplate + +import ( + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" +) + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + driver := GetDriver(data) + if driver == "" { + return httperror.NewAPIError(httperror.MissingRequired, "a Config field must be set") + } + if data != nil { + data["driver"] = driver + } + return nil +} + +func GetDriver(obj interface{}) string { + data, _ := convert.EncodeToMap(obj) + driver := "" + + for k, v := range data { + if !strings.HasSuffix(k, "Config") || convert.IsAPIObjectEmpty(v) { + continue + } + + driver = strings.TrimSuffix(k, "Config") + break + } + + return driver +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/handler.go new file mode 100644 index 0000000..1cf3d09 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/handler.go @@ -0,0 +1,251 @@ +package oci + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/gorilla/mux" + "github.com/oracle/oci-go-sdk/common" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + prov "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/auth/util" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + provcluster "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + provv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +type Credentials struct { + Tenancy string `json:"tenancyOCID"` + User string `json:"userOCID"` + Region string `json:"region"` + FingerPrint string `json:"fingerprint"` + PrivateKey string `json:"privateKey"` + PrivateKeyPassphrase string `json:"privateKeyPassphrase"` + Compartment string `json:"compartmentOCID"` +} + +// Cloud Credential Secret Fields +var requiredDataFields = map[string]string{ + "fingerprint": "ocicredentialConfig-fingerprint", + "tenancyId": "ocicredentialConfig-tenancyId", + "userId": "ocicredentialConfig-userId", + "privateKeyContents": "ocicredentialConfig-privateKeyContents", +} + +type handler struct { + Action string + provClusterCache provv1.ClusterCache + schemas *types.Schemas + secretsLister v1.SecretLister +} + +func NewOCIHandler(scaledContext *config.ScaledContext) http.Handler { + return &handler{ + provClusterCache: scaledContext.Wrangler.Provisioning.Cluster().Cache(), + schemas: scaledContext.Schemas, + secretsLister: scaledContext.Core.Secrets(namespace.GlobalNamespace).Controller().Lister(), + } +} + +func (handler *handler) ServeHTTP(writer http.ResponseWriter, req *http.Request) { + writer.Header().Set("Content-Type", "application/json") + + // New credential every invocation + creds := Credentials{} + errCode, err := handler.extractCreds(req, &creds) + if err != nil { + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + + err = handler.validateCreds(&creds) + if err != nil { + util.ReturnHTTPError(writer, req, httperror.InvalidBodyContent.Status, err.Error()) + return + } + + provider := common.NewRawConfigurationProvider(creds.Tenancy, creds.User, creds.Region, creds.FingerPrint, + creds.PrivateKey, &creds.PrivateKeyPassphrase) + + resourceType := mux.Vars(req)["resource"] + + var serialized []byte + + switch resourceType { + case "vcns": + if serialized, errCode, err = processVcns(provider, creds.Compartment); err != nil { + logrus.Debugf("[oci-handler] error processing VCNs: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "okeVersions": + if serialized, errCode, err = processOkeVersions(provider); err != nil { + logrus.Debugf("[oci-handler] error processing OKE versions: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "availabilityDomains": + if serialized, errCode, err = processAvailabilityDomains(provider, creds.Compartment); err != nil { + logrus.Debugf("[oci-handler] error processing ADs: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "regions": + if serialized, errCode, err = processRegions(provider, creds.Tenancy); err != nil { + logrus.Debugf("[oci-handler] error processing regions: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "nodeShapes": + if serialized, errCode, err = processNodeShapes(provider, creds.Compartment); err != nil { + logrus.Debugf("[oci-handler] error processing node shapes: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "nodeImages": + if serialized, errCode, err = processImages(provider, creds.Compartment); err != nil { + logrus.Debugf("[oci-handler] error processing images: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + case "nodeOkeImages": + if serialized, errCode, err = processNodeOkeImages(provider); err != nil { + logrus.Debugf("[oci-handler] error processing OKE images: %v", err) + util.ReturnHTTPError(writer, req, errCode, err.Error()) + return + } + writer.Write(serialized) + default: + util.ReturnHTTPError(writer, req, httperror.NotFound.Status, "invalid endpoint "+resourceType) + } +} + +// extractCreds attempts to extract the credentials from a given request either from the body or cloud credentials. +func (handler *handler) extractCreds(req *http.Request, creds *Credentials) (int, error) { + if credID := req.URL.Query().Get("cloudCredentialId"); credID != "" { + ns, name := ref.Parse(credID) + if ns == "" || name == "" { + logrus.Debugf("[oci-handler] invalid cloud credential ID %s", credID) + return httperror.InvalidBodyContent.Status, fmt.Errorf("invalid cloud credential ID %s", credID) + } + + apiContext := handler.generateAPIContext(req) + if err := access.ByID(apiContext, &schema.Version, client.CloudCredentialType, credID, &client.CloudCredential{}); err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status || apiError.Code.Status == httperror.NotFound.Status { + // If the user doesn't have direct access to the cloud credential, then we check if the user + // has access to a cluster that uses the cloud credential. + var clusters []*prov.Cluster + clusters, err = handler.provClusterCache.GetByIndex(provcluster.ByCloudCred, credID) + if err != nil || len(clusters) == 0 { + return httperror.NotFound.Status, fmt.Errorf("cloud credential not found") + } + for _, cluster := range clusters { + if err = access.ByID(apiContext, &schema.Version, client.ClusterType, cluster.Status.ClusterName, &client.Cluster{}); err == nil { + break + } + } + } + } + if err != nil { + return httperror.NotFound.Status, err + } + } + + cc, err := handler.secretsLister.Get(namespace.GlobalNamespace, name) + if err != nil { + logrus.Debugf("[oci-handler] error accessing cloud credential %s", credID) + return httperror.InvalidBodyContent.Status, fmt.Errorf("error accessing cloud credential %s", credID) + } + + creds.Tenancy = string(cc.Data[requiredDataFields["tenancyId"]]) + creds.User = string(cc.Data[requiredDataFields["userId"]]) + creds.FingerPrint = string(cc.Data[requiredDataFields["fingerprint"]]) + creds.PrivateKey = string(cc.Data[requiredDataFields["privateKeyContents"]]) + creds.PrivateKeyPassphrase = string(cc.Data[requiredDataFields["privateKeyPassphrase"]]) + region := req.URL.Query().Get("region") + if region != "" { + creds.Region = region + } + compartment := req.URL.Query().Get("compartment") + if compartment != "" { + creds.Compartment = compartment + } + } else if req.Method == http.MethodPost { + // Get credentials from body + raw, err := ioutil.ReadAll(req.Body) + if err != nil { + logrus.Debugf("[oci-handler] cannot read request body: " + err.Error()) + return httperror.InvalidBodyContent.Status, fmt.Errorf("cannot read request body: " + err.Error()) + } + + err = json.Unmarshal(raw, &creds) + if err != nil { + logrus.Debugf("[oci-handler] cannot parse request body: " + err.Error()) + return httperror.InvalidBodyContent.Status, fmt.Errorf("cannot parse request body: " + err.Error()) + } + } else { + return httperror.Unauthorized.Status, fmt.Errorf("cannot access OCI API without credentials to authenticate") + } + + return http.StatusOK, nil +} + +// validateCreds validates that all the required credential fields are populated. Optional values may be defaulted. +func (handler *handler) validateCreds(creds *Credentials) error { + + // We can default these two if missing + if creds.Compartment == "" { + creds.Compartment = creds.Tenancy + } + if creds.Region == "" { + // Default to PHX + creds.Region = "us-phoenix-1" + } + + // The rest are required + if creds.PrivateKey == "" { + logrus.Debugf("[oci-handler] OCI API private key is required") + return fmt.Errorf("OCI API private key is required") + } + if creds.FingerPrint == "" { + logrus.Debugf("[oci-handler] OCI fingerprint is required") + return fmt.Errorf("OCI fingerprint is required") + } + if creds.Tenancy == "" { + logrus.Debugf("[oci-handler] OCI tenancy is required") + return fmt.Errorf("OCI tenancy is required") + } + + if creds.User == "" { + logrus.Debugf("[oci-handler] OCI user is required") + return fmt.Errorf("OCI user is required") + } + + return nil +} + +func (handler *handler) generateAPIContext(req *http.Request) *types.APIContext { + return &types.APIContext{ + Method: req.Method, + Request: req, + Schemas: handler.schemas, + Query: map[string][]string{}, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/listers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/listers.go new file mode 100644 index 0000000..4e90633 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/oci/listers.go @@ -0,0 +1,253 @@ +package oci + +import ( + "context" + "encoding/json" + "net/http" + "strings" + + "github.com/oracle/oci-go-sdk/common" + "github.com/oracle/oci-go-sdk/containerengine" + "github.com/oracle/oci-go-sdk/core" + "github.com/oracle/oci-go-sdk/identity" + "github.com/rancher/norman/httperror" + "github.com/sirupsen/logrus" +) + +func processVcns(provider common.ConfigurationProvider, compartment string) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing VCNs in compartment: %s", compartment) + virtualNetworkClient, err := core.NewVirtualNetworkClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating Virtual Network client: %v", err) + return nil, httperror.ServerError.Status, err + } + vcnRequest := core.ListVcnsRequest{ + CompartmentId: &compartment, + } + vcnResponse, err := virtualNetworkClient.ListVcns(context.Background(), vcnRequest) + if err != nil { + httpErr := httperror.ErrorCode{} + if vcnResponse.RawResponse != nil { + httpErr.Status = vcnResponse.RawResponse.StatusCode + } else { + httpErr.Status = httperror.ServerError.Status + } + logrus.Debugf("[oci-handler] error listing VCNs with Virtual Network client: %v", err) + return nil, httpErr.Status, err + } + + var vcnDisplayNames []string + for _, item := range vcnResponse.Items { + vcnDisplayNames = append(vcnDisplayNames, *(item.DisplayName)) + } + + data, err := json.Marshal(vcnDisplayNames) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processOkeVersions(provider common.ConfigurationProvider) ([]byte, int, error) { + logrus.Debug("[oci-handler] listing OKE versions") + containerClient, err := containerengine.NewContainerEngineClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating ContainerEngine client: %v", err) + return nil, httperror.ServerError.Status, err + } + getClusterOptionsReq := containerengine.GetClusterOptionsRequest{ + ClusterOptionId: common.String("all"), + } + getClusterOptionsResp, err := containerClient.GetClusterOptions(context.Background(), getClusterOptionsReq) + if err != nil { + httpErr := httperror.ErrorCode{} + if getClusterOptionsResp.RawResponse != nil { + httpErr.Status = getClusterOptionsResp.RawResponse.StatusCode + } else { + httpErr.Status = httperror.ServerError.Status + } + logrus.Debugf("[oci-handler] error getting cluster options with ContainerEngine client: %v", err) + return nil, httpErr.Status, err + } + + data, err := json.Marshal(getClusterOptionsResp.KubernetesVersions) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processAvailabilityDomains(provider common.ConfigurationProvider, compartment string) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing ADs in compartment: %s", compartment) + identityClient, err := identity.NewIdentityClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating Identity client: %v", err) + return nil, httperror.ServerError.Status, err + } + request := identity.ListAvailabilityDomainsRequest{ + CompartmentId: &compartment, + } + availabilityDomains, err := identityClient.ListAvailabilityDomains(context.Background(), request) + if err != nil { + logrus.Debugf("[oci-handler] error listing ADs with Identity client: %v", err) + return nil, getErrorCode(availabilityDomains.RawResponse), err + } + + var adNames []string + for _, item := range availabilityDomains.Items { + adNames = append(adNames, *(item.Name)) + } + + data, err := json.Marshal(adNames) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processRegions(provider common.ConfigurationProvider, tenancy string) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing VCNs in tenancy: %s", tenancy) + identityClient, err := identity.NewIdentityClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating Identity client: %v", err) + return nil, httperror.ServerError.Status, err + } + request := identity.ListRegionSubscriptionsRequest{ + TenancyId: &tenancy, + } + allRegions, err := identityClient.ListRegionSubscriptions(context.Background(), request) + if err != nil { + logrus.Debugf("[oci-handler] error listing regions with Identity client: %v", err) + return nil, getErrorCode(allRegions.RawResponse), err + } + + var regionNames []string + for _, item := range allRegions.Items { + regionNames = append(regionNames, *(item.RegionName)) + } + + data, err := json.Marshal(regionNames) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processNodeShapes(provider common.ConfigurationProvider, compartment string) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing shapes in compartment: %s", compartment) + computeClient, err := core.NewComputeClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating compute client: %v", err) + return nil, httperror.ServerError.Status, err + } + shapeRequest := core.ListShapesRequest{ + CompartmentId: &compartment, + } + shapeResponse, err := computeClient.ListShapes(context.Background(), shapeRequest) + if err != nil { + logrus.Debugf("[oci-handler] error listing shapes with Compute client: %v", err) + return nil, getErrorCode(shapeResponse.RawResponse), err + } + + var nodeShapes []string + for _, item := range shapeResponse.Items { + if !listContains(nodeShapes, *(item.Shape)) { + nodeShapes = append(nodeShapes, *(item.Shape)) + } + } + + data, err := json.Marshal(nodeShapes) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processImages(provider common.ConfigurationProvider, compartment string) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing images in compartment: %s", compartment) + computeClient, err := core.NewComputeClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating Compute client: %v", err) + return nil, httperror.ServerError.Status, err + } + imageRequest := core.ListImagesRequest{ + CompartmentId: &compartment, + } + shapeResponse, err := computeClient.ListImages(context.Background(), imageRequest) + if err != nil { + logrus.Debugf("[oci-handler] error listing images with Compute client: %v", err) + return nil, getErrorCode(shapeResponse.RawResponse), err + } + + var nodeImages []string + for _, item := range shapeResponse.Items { + if !strings.Contains(*item.DisplayName, "GPU") && + !strings.Contains(*item.DisplayName, "Oracle-Linux-6") && + strings.Contains(*item.DisplayName, "Oracle-Linux") && + !listContains(nodeImages, *(item.DisplayName)) { + nodeImages = append(nodeImages, *(item.DisplayName)) + } + } + + data, err := json.Marshal(nodeImages) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func processNodeOkeImages(provider common.ConfigurationProvider) ([]byte, int, error) { + logrus.Debugf("[oci-handler] listing node OKE images") + containerClient, err := containerengine.NewContainerEngineClientWithConfigurationProvider(provider) + if err != nil { + logrus.Debugf("[oci-handler] error creating ContainerEngine client: %v", err) + return nil, httperror.ServerError.Status, err + } + nodePoolOptionsReq := containerengine.GetNodePoolOptionsRequest{ + NodePoolOptionId: common.String("all"), + } + nodePoolOptionsResp, err := containerClient.GetNodePoolOptions(context.Background(), nodePoolOptionsReq) + if err != nil { + logrus.Debugf("[oci-handler] error getting node pool options with Compute client: %v", err) + return nil, getErrorCode(nodePoolOptionsResp.RawResponse), err + } + + var nodeSources []string + for _, item := range nodePoolOptionsResp.Sources { + + sourceName := *(item.GetSourceName()) + + if !listContains(nodeSources, sourceName) { + nodeSources = append(nodeSources, sourceName) + } + } + + data, err := json.Marshal(nodeSources) + if err != nil { + return data, httperror.ServerError.Status, err + } + + return data, http.StatusOK, err +} + +func listContains(list []string, entry string) bool { + for _, x := range list { + if x == entry { + return true + } + } + return false +} + +func getErrorCode(response *http.Response) int { + if response == nil { + return httperror.ServerError.Status + } + return response.StatusCode +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/persistentvolumeclaim/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/persistentvolumeclaim/validator.go new file mode 100644 index 0000000..6983004 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/persistentvolumeclaim/validator.go @@ -0,0 +1,47 @@ +package persistentvolumeclaim + +import ( + "fmt" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/norman/store/storageclass" + "github.com/rancher/rancher/pkg/clustermanager" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Validator struct { + ClusterManager *clustermanager.Manager +} + +func (v *Validator) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + clusterName := v.ClusterManager.ClusterName(request) + c, err := v.ClusterManager.UserContextNoControllers(clusterName) + if err != nil { + return err + } + + storageClassID, _ := data["storageClassId"].(string) + if storageClassID == "" { + return nil + } + + storageClass, err := c.Storage.StorageClasses("").Get(storageClassID, v1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + return nil + } + + // if the referenced storage class does not have a storageaccounttype, storage account creation will fail in k8s + if storageClass.Provisioner == storageclass.AzureDisk { + if storageClass.Parameters[storageclass.StorageAccountType] == "" && storageClass.Parameters[storageclass.SkuName] == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("invalid storage class [%s]: must provide "+ + "storageaccounttype or skuName", storageClass.Name)) + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions.go new file mode 100644 index 0000000..2aea286 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions.go @@ -0,0 +1,127 @@ +package project + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/ghodss/yaml" + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/imported" + "github.com/rancher/rancher/pkg/generated/compose" + provisioningcontrollerv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/user" +) + +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + resource.AddAction(apiContext, "exportYaml") +} + +type Handler struct { + Projects v3.ProjectInterface + ProjectLister v3.ProjectLister + ClusterManager *clustermanager.Manager + ClusterLister v3.ClusterLister + ProvisioningClusterCache provisioningcontrollerv1.ClusterCache + UserMgr user.Manager +} + +func (h *Handler) Actions(actionName string, action *types.Action, apiContext *types.APIContext) error { + switch actionName { + case "exportYaml": + return h.ExportYamlHandler(actionName, action, apiContext) + } + + return errors.Errorf("unrecognized action %v", actionName) +} + +func (h *Handler) ExportYamlHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + namespace, id := ref.Parse(apiContext.ID) + project, err := h.ProjectLister.Get(namespace, id) + if err != nil { + return err + } + topkey := compose.Config{} + topkey.Version = "v3" + p := client.Project{} + if err := convert.ToObj(project.Spec, &p); err != nil { + return err + } + topkey.Projects = map[string]client.Project{} + topkey.Projects[project.Spec.DisplayName] = p + m, err := convert.EncodeToMap(topkey) + if err != nil { + return err + } + delete(m["projects"].(map[string]interface{})[project.Spec.DisplayName].(map[string]interface{}), "actions") + delete(m["projects"].(map[string]interface{})[project.Spec.DisplayName].(map[string]interface{}), "links") + data, err := json.Marshal(m) + if err != nil { + return err + } + + buf, err := yaml.JSONToYAML(data) + if err != nil { + return err + } + reader := bytes.NewReader(buf) + apiContext.Response.Header().Set("Content-Type", "text/yaml") + http.ServeContent(apiContext.Response, apiContext.Request, "exportYaml", time.Now(), reader) + return nil +} + +func getID(id interface{}) (string, error) { + s, ok := id.(string) + if !ok { + return "", fmt.Errorf("could not convert %v", id) + } + + split := strings.Split(s, ":") + return split[0] + ":" + split[len(split)-1], nil +} + +// isProvisionedRke2Cluster check to see if this is a rancher provisioned rke2 cluster +func isProvisionedRke2Cluster(cluster *v3.Cluster) bool { + return cluster.Status.Provider == v32.ClusterDriverRke2 && imported.IsAdministratedByProvisioningCluster(cluster) +} + +// parseKubeApiServerArgs parses the "kube-apiserver-arg" available in the +// clusters' MachineGlobalConfig to a map. The arguments are expected to +// follow the "key=value" format. Arguments that don't follow this format +// are ignored. +func parseKubeAPIServerArgs(provisioningCluster *provisioningv1.Cluster) map[string]string { + result := make(map[string]string) + + rawArgs, ok := provisioningCluster.Spec.RKEConfig.MachineGlobalConfig.Data["kube-apiserver-arg"] + if !ok || rawArgs == nil { + return result + } + + args, ok := rawArgs.([]any) + if !ok || args == nil { + return result + } + + for _, arg := range args { + s, ok := arg.(string) + if !ok { + continue + } + key, value, found := strings.Cut(s, "=") + if found { + result[key] = value + } + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions_test.go new file mode 100644 index 0000000..ee2e385 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_actions_test.go @@ -0,0 +1,84 @@ +package project + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" +) + +func TestParseKubeAPIServerArgs(t *testing.T) { + testCases := []struct { + name string + populateMap func(m rkev1.GenericMap) + expected map[string]string + }{ + { + name: "no value", + populateMap: func(m rkev1.GenericMap) {}, + expected: make(map[string]string), + }, + { + name: "nil value", + populateMap: func(m rkev1.GenericMap) { + m.Data["kube-apiserver-arg"] = nil + }, + expected: make(map[string]string), + }, + { + name: "invalid value type", + populateMap: func(m rkev1.GenericMap) { + m.Data["kube-apiserver-arg"] = []int{3, 2, 1} + }, + expected: make(map[string]string), + }, + { + name: "invalid value type within list", + populateMap: func(m rkev1.GenericMap) { + m.Data["kube-apiserver-arg"] = []any{3, 2, 1} + }, + expected: make(map[string]string), + }, + { + name: "invalid value within list", + populateMap: func(m rkev1.GenericMap) { + m.Data["kube-apiserver-arg"] = []any{"hey", "hello=world"} + }, + expected: map[string]string{ + "hello": "world", + }, + }, + { + name: "valid list", + populateMap: func(m rkev1.GenericMap) { + m.Data["kube-apiserver-arg"] = []any{"hey=planet", "hello=world"} + }, + expected: map[string]string{ + "hello": "world", + "hey": "planet", + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cluster := &provisioningv1.Cluster{ + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: make(map[string]any), + }, + }, + }, + }, + } + tc.populateMap(cluster.Spec.RKEConfig.MachineGlobalConfig) + res := parseKubeAPIServerArgs(cluster) + assert.Equal(t, tc.expected, res) + }) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_store.go new file mode 100644 index 0000000..7dfda7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/project/project_store.go @@ -0,0 +1,318 @@ +package project + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/mitchellh/mapstructure" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clustermanager" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/resourcequota" + mgmtschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/utils" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +const roleTemplatesRequired = "authz.management.cattle.io/creator-role-bindings" +const quotaField = "resourceQuota" +const namespaceQuotaField = "namespaceDefaultResourceQuota" + +type projectStore struct { + types.Store + projectLister v3.ProjectLister + roleTemplateLister v3.RoleTemplateLister + scaledContext *config.ScaledContext + clusterLister v3.ClusterLister + secretLister v1.SecretLister +} + +func SetProjectStore(schema *types.Schema, mgmt *config.ScaledContext) { + store := &projectStore{ + Store: schema.Store, + projectLister: mgmt.Management.Projects("").Controller().Lister(), + roleTemplateLister: mgmt.Management.RoleTemplates("").Controller().Lister(), + scaledContext: mgmt, + clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + secretLister: mgmt.Core.Secrets("").Controller().Lister(), + } + schema.Store = store +} + +func (s *projectStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + annotation, err := s.createProjectAnnotation() + if err != nil { + return nil, err + } + + if err := s.validateResourceQuota(apiContext, data, ""); err != nil { + return nil, err + } + + values.PutValue(data, annotation, "annotations", roleTemplatesRequired) + + return s.Store.Create(apiContext, schema, data) +} + +func (s *projectStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := s.validateResourceQuota(apiContext, data, id); err != nil { + return nil, err + } + + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *projectStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + parts := strings.Split(id, ":") + + proj, err := s.projectLister.Get(parts[0], parts[len(parts)-1]) + if err != nil { + return nil, err + } + if proj.Labels["authz.management.cattle.io/system-project"] == "true" { + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "System Project cannot be deleted") + } + return s.Store.Delete(apiContext, schema, id) +} + +func (s *projectStore) createProjectAnnotation() (string, error) { + rt, err := s.roleTemplateLister.List("", labels.NewSelector()) + if err != nil { + return "", err + } + + annoMap := make(map[string][]string) + + for _, role := range rt { + if role.ProjectCreatorDefault && !role.Locked { + annoMap["required"] = append(annoMap["required"], role.Name) + } + } + + d, err := json.Marshal(annoMap) + if err != nil { + return "", err + } + + return string(d), nil +} + +func (s *projectStore) validateResourceQuota(apiContext *types.APIContext, data map[string]interface{}, id string) error { + quotaO, quotaOk := data[quotaField] + if quotaO == nil { + quotaOk = false + } + nsQuotaO, namespaceQuotaOk := data[namespaceQuotaField] + if nsQuotaO == nil { + namespaceQuotaOk = false + } + if quotaOk != namespaceQuotaOk { + if quotaOk { + return httperror.NewFieldAPIError(httperror.MissingRequired, namespaceQuotaField, "") + } + return httperror.NewFieldAPIError(httperror.MissingRequired, quotaField, "") + } else if !quotaOk { + return nil + } + + var nsQuota mgmtclient.NamespaceResourceQuota + if err := convert.ToObj(nsQuotaO, &nsQuota); err != nil { + return err + } + var projectQuota mgmtclient.ProjectResourceQuota + if err := convert.ToObj(quotaO, &projectQuota); err != nil { + return err + } + + projectQuotaLimit, err := limitToLimit(projectQuota.Limit) + if err != nil { + return err + } + nsQuotaLimit, err := limitToLimit(nsQuota.Limit) + if err != nil { + return err + } + + // limits in namespace default quota should include all limits defined in the project quota + projectQuotaLimitMap, err := convert.EncodeToMap(projectQuotaLimit) + if err != nil { + return err + } + + nsQuotaLimitMap, err := convert.EncodeToMap(nsQuotaLimit) + if err != nil { + return err + } + if len(nsQuotaLimitMap) != len(projectQuotaLimitMap) { + return httperror.NewFieldAPIError(httperror.MissingRequired, namespaceQuotaField, fmt.Sprintf("does not have all fields defined on a %s", quotaField)) + } + + for k := range projectQuotaLimitMap { + if _, ok := nsQuotaLimitMap[k]; !ok { + return httperror.NewFieldAPIError(httperror.MissingRequired, namespaceQuotaField, fmt.Sprintf("misses %s defined on a %s", k, quotaField)) + } + } + return s.isQuotaFit(apiContext, nsQuotaLimit, projectQuotaLimit, id) +} + +func (s *projectStore) isQuotaFit(apiContext *types.APIContext, nsQuotaLimit *v32.ResourceQuotaLimit, + projectQuotaLimit *v32.ResourceQuotaLimit, id string) error { + // check that namespace default quota is within project quota + isFit, exceeded, err := resourcequota.IsQuotaFit(nsQuotaLimit, []*v32.ResourceQuotaLimit{}, projectQuotaLimit) + if err != nil { + return err + } + if !isFit { + return httperror.NewFieldAPIError(httperror.MaxLimitExceeded, namespaceQuotaField, fmt.Sprintf("exceeds %s on fields: %s", + quotaField, utils.FormatResourceList(exceeded))) + } + + if id == "" { + return nil + } + + var project mgmtclient.Project + if err := access.ByID(apiContext, &mgmtschema.Version, mgmtclient.ProjectType, id, &project); err != nil { + return err + } + + // check if fields were added or removed + // and update project's namespaces accordingly + defaultQuotaLimitMap, err := convert.EncodeToMap(nsQuotaLimit) + if err != nil { + return err + } + + usedQuotaLimitMap := map[string]interface{}{} + if project.ResourceQuota != nil && project.ResourceQuota.UsedLimit != nil { + usedQuotaLimitMap, err = convert.EncodeToMap(project.ResourceQuota.UsedLimit) + if err != nil { + return err + } + } + + limitToAdd := map[string]interface{}{} + limitToRemove := map[string]interface{}{} + for key, value := range defaultQuotaLimitMap { + if _, ok := usedQuotaLimitMap[key]; !ok { + limitToAdd[key] = value + } + } + + for key, value := range usedQuotaLimitMap { + if _, ok := defaultQuotaLimitMap[key]; !ok { + limitToRemove[key] = value + } + } + + // check that used quota is not bigger than the project quota + for key := range limitToRemove { + delete(usedQuotaLimitMap, key) + } + + var usedLimitToCheck mgmtclient.ResourceQuotaLimit + err = convert.ToObj(usedQuotaLimitMap, &usedLimitToCheck) + if err != nil { + return err + } + + usedQuotaLimit, err := limitToLimit(&usedLimitToCheck) + if err != nil { + return err + } + isFit, exceeded, err = resourcequota.IsQuotaFit(usedQuotaLimit, []*v32.ResourceQuotaLimit{}, projectQuotaLimit) + if err != nil { + return err + } + if !isFit { + return httperror.NewFieldAPIError(httperror.MaxLimitExceeded, quotaField, fmt.Sprintf("is below the used limit on fields: %s", + utils.FormatResourceList(exceeded))) + } + + if len(limitToAdd) == 0 && len(limitToRemove) == 0 { + return nil + } + + // check if default quota is enough to set on namespaces + toAppend := &mgmtclient.ResourceQuotaLimit{} + if err := mapstructure.Decode(limitToAdd, toAppend); err != nil { + return err + } + converted, err := limitToLimit(toAppend) + if err != nil { + return err + } + mu := resourcequota.GetProjectLock(id) + mu.Lock() + defer mu.Unlock() + + namespacesCount, err := s.getNamespacesCount(apiContext, project) + if err != nil { + return err + } + var nsLimits []*v32.ResourceQuotaLimit + for i := 0; i < namespacesCount; i++ { + nsLimits = append(nsLimits, converted) + } + + isFit, exceeded, err = resourcequota.IsQuotaFit(&v32.ResourceQuotaLimit{}, nsLimits, projectQuotaLimit) + if err != nil { + return err + } + if !isFit { + return httperror.NewFieldAPIError(httperror.MaxLimitExceeded, namespaceQuotaField, + fmt.Sprintf("exceeds project limit on fields %s when applied to all namespaces in a project", + utils.FormatResourceList(exceeded))) + } + + return nil +} + +func (s *projectStore) getNamespacesCount(apiContext *types.APIContext, project mgmtclient.Project) (int, error) { + cluster, err := s.clusterLister.Get("", project.ClusterID) + if err != nil { + return 0, err + } + + kubeConfig, err := clustermanager.ToRESTConfig(cluster, s.scaledContext, s.secretLister, true) + if kubeConfig == nil || err != nil { + return 0, err + } + + clusterContext, err := config.NewUserContext(s.scaledContext, *kubeConfig, cluster.Name) + if err != nil { + return 0, err + } + + namespaces, err := clusterContext.Core.Namespaces("").List(metav1.ListOptions{}) + if err != nil { + return 0, err + } + count := 0 + for _, n := range namespaces.Items { + if n.Annotations == nil { + continue + } + if n.Annotations["field.cattle.io/projectId"] == project.ID { + count++ + } + } + + return count, nil +} + +func limitToLimit(from *mgmtclient.ResourceQuotaLimit) (*v32.ResourceQuotaLimit, error) { + var to v32.ResourceQuotaLimit + err := convert.ToObj(from, &to) + return &to, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate.go new file mode 100644 index 0000000..ec1f6ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate.go @@ -0,0 +1,71 @@ +package roletemplate + +import ( + "fmt" + "net/http" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" +) + +type Wrapper struct { + RoleTemplateLister v3.RoleTemplateLister +} + +func (w Wrapper) Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if request.Method != http.MethodPut && request.Method != http.MethodPost { + return nil + } + + // Only cluster roles can be administrative for now. So this validation will prevent users from creating any "project" context + // roleTemplates with administrative bit set to true + if request.Method == http.MethodPost || request.Method == http.MethodPut { + administrative := convert.ToBool(data[client.RoleTemplateFieldAdministrative]) + context := convert.ToString(data[client.RoleTemplateFieldContext]) + if administrative && context != "cluster" { + return fmt.Errorf("Only cluster roles can be administrative") + } + } + + if request.Method != http.MethodPut { + return nil + } + rt, err := w.RoleTemplateLister.Get("", request.ID) + if err != nil { + return err + } + + if rt.Builtin == true { + // Drop everything but locked and defaults. If it's builtin nothing else can change. + for k := range data { + if k == "locked" || k == "clusterCreatorDefault" || k == "projectCreatorDefault" { + continue + } + delete(data, k) + } + + } + return nil +} + +func (w Wrapper) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + roleTemplates, err := w.RoleTemplateLister.List("", labels.Everything()) + if err != nil { + logrus.Warnf("[roletemplate formatter] Failed to list roletemplates. Error: %v", err) + return + } + + for _, rt := range roleTemplates { + for _, parent := range rt.RoleTemplateNames { + if parent == resource.ID { + // if another roletemplate inherits from current roletemplate, disable remove + delete(resource.Links, "remove") + return + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate_test.go new file mode 100644 index 0000000..27ee32b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplate/roletemplate_test.go @@ -0,0 +1,83 @@ +package roletemplate + +import ( + "testing" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// testAsRoleTemplate creates resource with ID set to key and runs roletemplate formatter +func testAsRoletemplate(key string) *types.RawResource { + mockRTLister := &fakes.RoleTemplateListerMock{ + ListFunc: mockList, + } + + testWrapper := Wrapper{ + mockRTLister, + } + + testResource := &types.RawResource{ + ID: key, + Links: map[string]string{ + "update": "/test/link", + "remove": "/test/link2", + }, + } + + testWrapper.Formatter(nil, testResource) + + return testResource +} + +func mockList(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) { + return []*v3.RoleTemplate{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt1", + }, + RoleTemplateNames: []string{"asdf", "asdf", "test123"}, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt2", + }, + RoleTemplateNames: []string{"aasdfsdf", "adsasdff"}, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt3", + }, + RoleTemplateNames: []string{}, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt3", + }, + RoleTemplateNames: []string{"test321"}, + }}, nil +} + +// TestDelete confirms that the remove resource link is filtered when roletemplate is inherited +func TestDelete(t *testing.T) { + assert := assert.New(t) + + // test when roletemplate is not a parent of another roletemplate, should have all links + resource := testAsRoletemplate("somekey") + assert.Equal(resource.Links["remove"], "/test/link2") + assert.Equal(resource.Links["update"], "/test/link") + + // test when roletemplate is a parent of another roletemplate, should not have remove link + resource = testAsRoletemplate("test123") + assert.Equal(resource.Links["remove"], "") + assert.Equal(resource.Links["update"], "/test/link") + + // test when roletemplate is only parent of another roletemplate, should not have remove link + resource = testAsRoletemplate("test321") + assert.Equal(resource.Links["remove"], "") + assert.Equal(resource.Links["update"], "/test/link") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplatebinding/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplatebinding/validator.go new file mode 100644 index 0000000..329ad46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/roletemplatebinding/validator.go @@ -0,0 +1,90 @@ +package roletemplatebinding + +import ( + "fmt" + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func NewPRTBValidator(management *config.ScaledContext) types.Validator { + return newValidator(management, client.ProjectRoleTemplateBindingFieldRoleTemplateID, "project") +} + +func NewCRTBValidator(management *config.ScaledContext) types.Validator { + return newValidator(management, client.ClusterRoleTemplateBindingFieldRoleTemplateID, "cluster") +} + +func newValidator(management *config.ScaledContext, field string, context string) types.Validator { + validator := &validator{ + roleTemplateLister: management.Management.RoleTemplates("").Controller().Lister(), + field: field, + context: context, + } + + return validator.validator +} + +type validator struct { + roleTemplateLister v3.RoleTemplateLister + field string + context string +} + +func (v *validator) validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + roleTemplateName := data[v.field] + if roleTemplateName == nil && request.Method == http.MethodPut { + return nil + } + + roleTemplate, err := v.validateRoleTemplateBinding(roleTemplateName) + if err != nil { + return err + } + + if roleTemplate.Context != v.context { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("Cannot reference context [%s] from [%s] context", + roleTemplate.Context, v.context)) + } + + if request.Method == http.MethodPut { + return nil + } + + userID, _ := data["userId"].(string) + userPrincipalID, _ := data["userPrincipalId"].(string) + groupID, _ := data["groupId"].(string) + groupPrincipalID, _ := data["groupPrincipalId"].(string) + + hasUserTarget := userID != "" || userPrincipalID != "" + hasGroupTarget := groupID != "" || groupPrincipalID != "" + + if (hasUserTarget && hasGroupTarget) || (!hasUserTarget && !hasGroupTarget) { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must target a user [userId]/[userPrincipalId] "+ + "OR a group [groupId]/[groupPrincipalId]") + } + + return nil +} + +func (v *validator) validateRoleTemplateBinding(obj interface{}) (*v3.RoleTemplate, error) { + roleTemplateID, ok := obj.(string) + if !ok { + return nil, httperror.NewAPIError(httperror.MissingRequired, "Request does not have a valid roleTemplateId") + } + + roleTemplate, err := v.roleTemplateLister.Get("", roleTemplateID) + if err != nil { + return nil, httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error getting role template: %v", err)) + } + + if roleTemplate.Locked { + return nil, httperror.NewAPIError(httperror.InvalidState, "Role is locked and cannot be assigned") + } + + return roleTemplate, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/secret/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/secret/validator.go new file mode 100644 index 0000000..8b82fe8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/secret/validator.go @@ -0,0 +1,64 @@ +package secret + +import ( + "fmt" + "net/http" + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" +) + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + unauthedError := httperror.NewAPIError(httperror.PermissionDenied, "unauthorized") + + if request.Method == http.MethodPost { + id := "" + + // extracting project name from data + if projectData, ok := data["projectId"].(string); ok { + if projectParts := strings.Split(projectData, ":"); len(projectParts) == 2 { + id = fmt.Sprintf("%s:%s", projectParts[1], data["name"]) + } + } + + if id == "" { + return unauthedError + } + + // minimum info needed to use CanDo + secretState := map[string]interface{}{ + "name": data["name"], + "id": id, + "namespaceId": data["namespaceId"], + } + + // update is used here to avoid the application of general user permissions for secrets + if err := request.AccessControl.CanDo(v1.SecretGroupVersionKind.Group, v1.SecretResource.Name, "update", request, secretState, schema); err != nil { + return unauthedError + } + } else if request.Method == http.MethodPut { + var secretState map[string]interface{} + + if err := access.ByID(request, request.Version, request.Type, request.ID, &secretState); err != nil { + if httperror.IsNotFound(err) || isUnauthorized(err) { + return httperror.NewAPIError(httperror.NotFound, "not found") + } + return httperror.NewAPIError(httperror.ServerError, err.Error()) + } + // this is unused but will be necessary if readonly users are ever given permission to view secrets + if err := request.AccessControl.CanDo(v1.SecretGroupVersionKind.Group, v1.SecretResource.Name, "update", request, secretState, schema); err != nil { + return unauthedError + } + } + return nil +} + +func isUnauthorized(err interface{}) bool { + if err, ok := err.(*httperror.APIError); ok { + return err.Code.Status == 403 + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/setting/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/setting/setting.go new file mode 100644 index 0000000..9c789b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/setting/setting.go @@ -0,0 +1,77 @@ +package setting + +import ( + "fmt" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +var ReadOnlySettings = []string{ + "cacerts", +} + +func Formatter(apiContext *types.APIContext, resource *types.RawResource) { + if convert.ToString(resource.Values["source"]) == "env" { + delete(resource.Links, "update") + } else if slice.ContainsString(ReadOnlySettings, resource.ID) { + delete(resource.Links, "update") + } else { + setting := map[string]interface{}{ + "id": apiContext.ID, + } + if err := apiContext.AccessControl.CanDo(v3.SettingGroupVersionKind.Group, v3.SettingResource.Name, "update", apiContext, setting, apiContext.Schema); err != nil { + delete(resource.Links, "update") + } + } +} + +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + var setting v3client.Setting + + // request.ID is taken from the request request url, it is possible that the request url does not contain the id + id := request.ID + if name, ok := data["name"].(string); ok && id == "" { + id = name + } + + if err := access.ByID(request, request.Version, v3client.SettingType, id, &setting); err != nil { + if !httperror.IsNotFound(err) { + return err + } + } + if setting.Source == "env" { + return httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("%s is readOnly because its value is from environment variable", id)) + } else if slice.ContainsString(ReadOnlySettings, id) { + return httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("%s is readOnly", id)) + } + + newValue, ok := data["value"] + if !ok { + return fmt.Errorf("value not found") + } + newValueString, ok := newValue.(string) + if !ok { + return fmt.Errorf("value not string") + } + + var err error + switch id { + case "auth-user-info-max-age-seconds": + _, err = providerrefresh.ParseMaxAge(newValueString) + case "auth-user-info-resync-cron": + _, err = providerrefresh.ParseCron(newValueString) + } + + if err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("%v", err)) + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters.go new file mode 100644 index 0000000..deadff7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters.go @@ -0,0 +1,62 @@ +package vsphere + +import ( + "context" + "strings" + + "github.com/rancher/rancher/pkg/capr" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vim25/mo" +) + +// processSoapFinderGetters processes the vmPath that is passed in from the UI +// and contains the inventory path to the VM being cloned +// the format needs to match what machine uses (example below) +// vSphere args: cloneFrom:/datacenter/vm/username/sles15-sp3-template +// vSphere cmd: --vmwarevsphere-clone-from=/datacenter/vm/username/sles15-sp3-template +func processSoapFinderGetters(ctx context.Context, vmPath, fieldName string, cc *v1.Secret, dc string) ([]string, error) { + finder, err := getSoapFinder(ctx, cc, dc) + if err != nil { + return nil, err + } + vm, err := finder.VirtualMachine(ctx, vmPath) + if err != nil { + return nil, err + } + var data []string + var d string + switch fieldName { + case "guest-os": + d, err = getVirtualMachineGuestOS(ctx, vm) + data = append(data, d) + } + return data, err +} + +// getVirtualMachineGuestOS fetches vSphere VM object properties to get the guestId +func getVirtualMachineGuestOS(ctx context.Context, vm *object.VirtualMachine) (string, error) { + var mvm mo.VirtualMachine + + refErr := vm.Properties(ctx, vm.Reference(), []string{"summary.config.guestId"}, &mvm) + if refErr != nil { + return "", refErr + } + guestOS := checkGuestID(mvm.Summary.Config.GuestId) + + return guestOS, nil +} + +// checkGuestID parses a vSphere VM object's guestId properties and +// returns a simplified OS string which will default to linux +// if the guestId is not Windows +func checkGuestID(g string) string { + var machineOS string + switch { + case strings.Contains(strings.ToLower(g), capr.WindowsMachineOS): + machineOS = capr.WindowsMachineOS + default: + machineOS = capr.DefaultMachineOS + } + return machineOS +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters_test.go new file mode 100644 index 0000000..de819f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/getters_test.go @@ -0,0 +1,72 @@ +package vsphere + +import ( + "testing" + + "github.com/rancher/rancher/pkg/capr" + "github.com/stretchr/testify/assert" +) + +func Test_checkGuestId(t *testing.T) { + type args struct { + g string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "guestId-windows", + args: args{ + g: capr.WindowsMachineOS, + }, + want: capr.WindowsMachineOS, + wantErr: false, + }, + { + name: "guestId-linux", + args: args{ + g: capr.DefaultMachineOS, + }, + want: capr.DefaultMachineOS, + wantErr: false, + }, + { + // test that the guestId is defaulted to linux if g is + // anything other than "windows" + name: "guestId-empty", + args: args{ + g: "", + }, + want: capr.DefaultMachineOS, + wantErr: false, + }, + { + name: "guestId-unsupported", + args: args{ + g: "darwin", + }, + want: "darwin", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + + // act + guestId := checkGuestID(tt.args.g) + + // assert + a.NotEmpty(guestId) + if tt.wantErr { + a.NotEqual(tt.want, guestId) + } else { + a.Equal(tt.want, guestId) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/handler.go new file mode 100644 index 0000000..d92c0ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/handler.go @@ -0,0 +1,286 @@ +package vsphere + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + prov "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/auth/util" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + provcluster "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + provv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + corev1 "k8s.io/api/core/v1" +) + +const ( + UnknownFinder = iota + SoapFinder + SoapGetter + ContentLibraryManager + TagsManager + CustomFieldsFinder +) + +var fieldNames = map[string]int{ + "data-centers": SoapFinder, + "hosts": SoapFinder, + "data-stores": SoapFinder, + "data-store-clusters": SoapFinder, + "folders": SoapFinder, + "networks": SoapFinder, + "virtual-machines": SoapFinder, + "templates": SoapFinder, + "clusters": SoapFinder, + "resource-pools": SoapFinder, + "guest-os": SoapGetter, + "content-libraries": ContentLibraryManager, + "library-templates": ContentLibraryManager, + "tags": TagsManager, + "tag-categories": TagsManager, + "custom-attributes": CustomFieldsFinder, +} + +var cloudCredentialDataPrefix = "vmwarevspherecredentialConfig-" +var dataFields = map[string]string{ + "username": "username", + "password": "password", + "host": "vcenter", + "port": "vcenterPort", +} + +type handler struct { + schemas *types.Schemas + secretsLister v1.SecretLister + provClusterCache provv1.ClusterCache + ac types.AccessControl +} + +func NewVsphereHandler(scaledContext *config.ScaledContext) http.Handler { + return &handler{ + schemas: scaledContext.Schemas, + secretsLister: scaledContext.Core.Secrets(namespace.GlobalNamespace).Controller().Lister(), + provClusterCache: scaledContext.Wrangler.Provisioning.Cluster().Cache(), + ac: scaledContext.AccessControl, + } +} + +func (v *handler) ServeHTTP(res http.ResponseWriter, req *http.Request) { + var err error + + fieldName := mux.Vars(req)["field"] + dc := req.FormValue("dataCenter") + + if fieldName == "" || !validFieldName(fieldName) { + util.ReturnHTTPError(res, req, httperror.NotFound.Status, fmt.Sprintf("%s: invalid field name", httperror.NotFound.Code)) + return + } + + var cc *v1.Secret + var errcode httperror.ErrorCode + var vmPath string + + if id := req.FormValue("cloudCredentialId"); id != "" { + cc, errcode, err = v.getCloudCredential(id, req) + if err != nil { + util.ReturnHTTPError(res, req, errcode.Status, fmt.Sprintf("%s: %s", errcode.Code, err.Error())) + return + } + } else if id := req.FormValue("secretId"); id != "" { + cc, errcode, err = v.getSecret(id, req) + if err != nil { + util.ReturnHTTPError(res, req, errcode.Status, fmt.Sprintf("%s: %s", errcode.Code, err.Error())) + return + } + } + + if cc == nil { + util.ReturnHTTPError(res, req, httperror.NotFound.Status, fmt.Sprintf("%s: cloud credential not found", httperror.NotFound.Code)) + return + } + + var js []byte + switch fieldNames[fieldName] { + case SoapGetter: + var data []string + data, err = processSoapFinderGetters(req.Context(), vmPath, fieldName, cc, dc) + if err != nil { + invalidBody(res, req, err) + return + } + js, err = json.Marshal(map[string][]string{"data": data}) + case SoapFinder: + var data []string + if data, err = processSoapFinder(req.Context(), fieldName, cc, dc); err != nil { + invalidBody(res, req, err) + return + } + js, err = json.Marshal(map[string][]string{"data": data}) + case ContentLibraryManager: + l := req.FormValue("library") + var data []string + if data, err = processContentLibraryManager(req.Context(), fieldName, cc, l); err != nil { + invalidBody(res, req, err) + return + } + js, err = json.Marshal(map[string][]string{"data": data}) + case CustomFieldsFinder: + var data []map[string]interface{} + if data, err = processCustomFieldsFinder(req.Context(), cc); err != nil { + invalidBody(res, req, err) + return + } + js, err = json.Marshal(map[string][]map[string]interface{}{"data": data}) + case TagsManager: + c := req.FormValue("category") + var data []map[string]string + if data, err = processTagsManager(req.Context(), fieldName, cc, c); err != nil { + invalidBody(res, req, err) + return + } + js, err = json.Marshal(map[string][]map[string]string{"data": data}) + } + + if err != nil { + util.ReturnHTTPError(res, req, httperror.ServerError.Status, fmt.Sprintf("%s: %s", httperror.ServerError.Code, err.Error())) + return + } + + res.Header().Set("Content-Type", "application/json") + res.Write(js) +} + +func (v *handler) getCloudCredential(id string, req *http.Request) (*corev1.Secret, httperror.ErrorCode, error) { + apiContext := v.generateAPIContext(req) + if err := access.ByID(apiContext, &schema.Version, client.CloudCredentialType, id, &client.CloudCredentialClient{}); err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status || apiError.Code.Status == httperror.NotFound.Status { + // If the user doesn't have direct access to the cloud credential, then we check if the user + // has access to a cluster that uses the cloud credential. + var clusters []*prov.Cluster + clusters, err = v.provClusterCache.GetByIndex(provcluster.ByCloudCred, id) + if err != nil || len(clusters) == 0 { + return nil, httperror.NotFound, fmt.Errorf("cloud credential not found") + } + for _, cluster := range clusters { + if err = access.ByID(apiContext, &schema.Version, client.ClusterType, cluster.Status.ClusterName, &client.Cluster{}); err == nil { + break + } + } + } + } + if err != nil { + return nil, httperror.NotFound, err + } + } + + ns, name := ref.Parse(id) + if ns == "" || name == "" { + return nil, httperror.InvalidBodyContent, fmt.Errorf("invalid cloud credential %s", id) + } + + cc, err := v.secretsLister.Get(namespace.GlobalNamespace, name) + if err != nil || cc == nil { + return nil, httperror.InvalidBodyContent, fmt.Errorf("error getting cloud cred %s: %v", id, err) + } + + if cc.Data == nil || len(cc.Data) == 0 { + return nil, httperror.InvalidBodyContent, fmt.Errorf("empty credential ID data %s", id) + } + if !validCloudCredential(cc) { + return nil, httperror.InvalidBodyContent, fmt.Errorf("not a valid vsphere credential %s", id) + } + + return moveData(cc), httperror.ErrorCode{}, nil +} + +func (v *handler) getSecret(id string, req *http.Request) (*corev1.Secret, httperror.ErrorCode, error) { + defaultNamespace := settings.FleetDefaultWorkspaceName.Get() + + secretState := map[string]interface{}{ + "name": id, + "id": id, + "namespaceId": defaultNamespace, + } + schema := types.Schema{ID: "secrets"} + + if err := v.ac.CanDo(v1.SecretGroupVersionKind.Group, v1.SecretResource.Name, + "get", v.generateAPIContext(req), secretState, &schema); err != nil { + return nil, httperror.InvalidBodyContent, fmt.Errorf("not a valid vsphere credential %s", id) + } + + cc, err := v.secretsLister.Get(defaultNamespace, id) + if err != nil || cc == nil { + return nil, httperror.InvalidBodyContent, fmt.Errorf("error getting cloud cred %s: %v", id, err) + } + + if cc.Data == nil || len(cc.Data) == 0 { + return nil, httperror.InvalidBodyContent, fmt.Errorf("empty secret ID data %s", id) + } + + if !validSecret(cc) { + return nil, httperror.InvalidBodyContent, fmt.Errorf("not a valid vsphere credential %s", id) + } + + return cc, httperror.ErrorCode{}, nil +} + +func (v *handler) generateAPIContext(req *http.Request) *types.APIContext { + return &types.APIContext{ + Method: req.Method, + Request: req, + Schemas: v.schemas, + Query: map[string][]string{}, + } +} + +func invalidBody(res http.ResponseWriter, req *http.Request, err error) { + util.ReturnHTTPError(res, req, httperror.InvalidBodyContent.Status, fmt.Sprintf("%s: %s", httperror.InvalidBodyContent.Code, err.Error())) +} + +func validFieldName(s string) bool { + _, ok := fieldNames[s] + return ok +} + +func validCloudCredential(cc *corev1.Secret) bool { + for _, v := range dataFields { + if _, ok := cc.Data[cloudCredentialDataPrefix+v]; !ok { + return false + } + } + + return true +} + +// takes an old cloud credential and moves the data to the new secret location +func moveData(cc *corev1.Secret) *corev1.Secret { + copy := cc.DeepCopy() + for _, v := range dataFields { + n, ok := cc.Data[cloudCredentialDataPrefix+v] + if !ok { + continue + } + copy.Data[v] = n + } + return copy +} + +func validSecret(cc *corev1.Secret) bool { + for _, v := range dataFields { + if _, ok := cc.Data[v]; !ok { + return false + } + } + return true +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/listers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/listers.go new file mode 100644 index 0000000..cad5ff1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/vsphere/listers.go @@ -0,0 +1,411 @@ +package vsphere + +import ( + "context" + "fmt" + "net/url" + "path" + "sort" + "strings" + + "github.com/vmware/govmomi" + "github.com/vmware/govmomi/find" + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vapi/library" + "github.com/vmware/govmomi/vapi/rest" + "github.com/vmware/govmomi/vapi/tags" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" +) + +func processSoapFinder(ctx context.Context, fieldName string, cc *v1.Secret, dc string) ([]string, error) { + finder, err := getSoapFinder(ctx, cc, dc) + if err != nil { + return nil, err + } + + var data []string + switch fieldName { + case "clusters": + data, err = listClusters(ctx, finder) + case "virtual-machines": + data, err = listVirtualMachines(ctx, finder, "virtual-machines") + case "templates": + data, err = listVirtualMachines(ctx, finder, "templates") + case "data-stores": + data, err = listDataStores(ctx, finder) + case "data-store-clusters": + data, err = listDataStoreClusters(ctx, finder) + case "folders": + data, err = listFolders(ctx, finder, dc) + case "hosts": + data, err = listHosts(ctx, finder) + case "networks": + data, err = listNetworks(ctx, finder) + case "data-centers": + data, err = listDataCenters(ctx, finder) + case "resource-pools": + data, err = listResourcePools(ctx, finder) + } + + return data, err +} + +func processTagsManager(ctx context.Context, fieldName string, cc *v1.Secret, cat string) ([]map[string]string, error) { + tagsManager, err := getTagsManager(ctx, cc) + if err != nil { + return nil, err + } + + var data []map[string]string + switch fieldName { + case "tags": + data, err = listTags(ctx, tagsManager, cat) + case "tag-categories": + data, err = listTagCategories(ctx, tagsManager) + } + + return data, err +} + +func processContentLibraryManager(ctx context.Context, fieldName string, cc *v1.Secret, library string) ([]string, error) { + libraryManager, err := getContentLibraryManager(ctx, cc) + if err != nil { + return nil, err + } + + var data []string + switch fieldName { + case "library-templates": + data, err = listContentLibraryTemplates(ctx, libraryManager, library) + case "content-libraries": + data, err = listContentLibraries(ctx, libraryManager) + } + + return data, err +} + +func listContentLibraries(ctx context.Context, mgr *library.Manager) ([]string, error) { + libs, err := mgr.GetLibraries(ctx) + if err != nil { + return nil, err + } + + data := []string{""} + for _, lib := range libs { + data = append(data, lib.Name) + } + + return data, nil +} + +func listContentLibraryTemplates(ctx context.Context, mgr *library.Manager, library string) ([]string, error) { + lib, err := mgr.GetLibraryByName(ctx, library) + if err != nil { + return nil, err + } + + items, err := mgr.GetLibraryItems(ctx, lib.ID) + if err != nil { + return nil, err + } + + var data []string + for _, item := range items { + if item.Type == "ovf" { + data = append(data, item.Name) + } + } + + sort.Strings(data) + return data, nil +} + +func processCustomFieldsFinder(ctx context.Context, cc *v1.Secret) ([]map[string]interface{}, error) { + mgr, err := getCustomFieldsManager(ctx, cc) + if err != nil { + return nil, err + } + + field, err := mgr.Field(ctx) + if err != nil { + return nil, err + } + + var data []map[string]interface{} + for _, def := range field { + if def.ManagedObjectType != "VirtualMachine" { + continue + } + f := map[string]interface{}{ + "key": def.Key, + "name": def.Name, + } + data = append(data, f) + } + return data, nil +} + +func listTags(ctx context.Context, tagsManager *tags.Manager, cat string) ([]map[string]string, error) { + var lsTags []tags.Tag + var err error + if cat == "" { + lsTags, err = tagsManager.GetTags(ctx) + } else { + lsTags, err = tagsManager.GetTagsForCategory(ctx, cat) + } + + if err != nil { + return nil, err + } + + categories, err := tagsManager.GetCategories(ctx) + if err != nil { + return nil, err + } + + m := make(map[string]tags.Category) + for _, category := range categories { + m[category.ID] = category + } + + var data []map[string]string + for _, tag := range lsTags { + t := map[string]string{ + "id": tag.ID, + "name": tag.Name, + "category": m[tag.CategoryID].Name, + } + data = append(data, t) + } + + return data, nil +} + +func listTagCategories(ctx context.Context, tagsManager *tags.Manager) ([]map[string]string, error) { + categories, err := tagsManager.GetCategories(ctx) + if err != nil { + return nil, err + } + + var data []map[string]string + for _, cat := range categories { + tc := map[string]string{ + "id": cat.ID, + "name": cat.Name, + "multipleCardinality": cat.Cardinality, + } + data = append(data, tc) + } + + return data, nil +} + +func listClusters(ctx context.Context, finder *find.Finder) ([]string, error) { + clusters, err := finder.ClusterComputeResourceList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, cluster := range clusters { + data = append(data, cluster.InventoryPath) + } + + return data, nil +} + +func listDataCenters(ctx context.Context, finder *find.Finder) ([]string, error) { + dcs, err := finder.DatacenterList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, v := range dcs { + data = append(data, v.InventoryPath) + } + + return data, nil +} + +func listResourcePools(ctx context.Context, finder *find.Finder) ([]string, error) { + dcs, err := finder.ResourcePoolList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, v := range dcs { + data = append(data, v.InventoryPath) + } + + return data, nil +} + +func listDataStores(ctx context.Context, finder *find.Finder) ([]string, error) { + dataStores, err := finder.DatastoreList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, ds := range dataStores { + data = append(data, ds.InventoryPath) + } + + return data, nil +} + +func listDataStoreClusters(ctx context.Context, finder *find.Finder) ([]string, error) { + dataStores, err := finder.DatastoreClusterList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, ds := range dataStores { + data = append(data, ds.InventoryPath) + } + + return data, nil +} + +func listFolders(ctx context.Context, finder *find.Finder, dc string) ([]string, error) { + folders, err := finder.FolderList(ctx, "*") + if err != nil { + return nil, err + } + + prefix := path.Join(dc, "vm") + // base case of //vm is covered by "" + data := []string{""} + for _, f := range folders { + if strings.HasPrefix(f.InventoryPath, prefix) { + data = append(data, f.InventoryPath) + } + } + + return data, nil +} + +func listHosts(ctx context.Context, finder *find.Finder) ([]string, error) { + hosts, err := finder.HostSystemList(ctx, "*") + if err != nil { + return nil, err + } + + data := []string{""} //blank default + + for _, h := range hosts { + data = append(data, h.InventoryPath) + } + + return data, nil +} + +func listNetworks(ctx context.Context, finder *find.Finder) ([]string, error) { + networks, err := finder.NetworkList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, net := range networks { + data = append(data, net.GetInventoryPath()) + } + + return data, nil +} + +func listVirtualMachines(ctx context.Context, finder *find.Finder, t string) ([]string, error) { + if t == "" { + t = "both" + } + vms, err := finder.VirtualMachineList(ctx, "*") + if err != nil { + return nil, err + } + + var data []string + for _, vm := range vms { + switch t { + case "both": + data = append(data, vm.InventoryPath) + case "templates": + if isTemplate, err := vm.IsTemplate(ctx); err == nil && isTemplate { + data = append(data, vm.InventoryPath) + } + case "virtual-machines": + if isTemplate, err := vm.IsTemplate(ctx); err == nil && !isTemplate { + data = append(data, vm.InventoryPath) + } + } + } + + sort.Strings(data) + return data, nil +} + +func getSoapFinder(ctx context.Context, cc *corev1.Secret, dc string) (*find.Finder, error) { + c, err := getSoapClient(ctx, cc) + if err != nil { + return nil, err + } + + finder := find.NewFinder(c.Client, true) + + if dc != "" { + dataCenter, err := finder.Datacenter(ctx, dc) + if err != nil { + return nil, err + } + + finder.SetDatacenter(dataCenter) + } + + return finder, nil +} + +func getSoapClient(ctx context.Context, cc *corev1.Secret) (*govmomi.Client, error) { + u, err := url.Parse(fmt.Sprintf("https://%s:%s/sdk", cc.Data[dataFields["host"]], cc.Data[dataFields["port"]])) + if err != nil { + return nil, err + } + + u.User = url.UserPassword(string(cc.Data[dataFields["username"]]), string(cc.Data[dataFields["password"]])) + return govmomi.NewClient(ctx, u, true) +} + +func getContentLibraryManager(ctx context.Context, cc *corev1.Secret) (*library.Manager, error) { + soap, err := getSoapClient(ctx, cc) + if err != nil { + return nil, err + } + + mgr := library.NewManager(rest.NewClient(soap.Client)) + ui := url.UserPassword(string(cc.Data[dataFields["username"]]), string(cc.Data[dataFields["password"]])) + + return mgr, mgr.Login(ctx, ui) +} + +func getTagsManager(ctx context.Context, cc *corev1.Secret) (*tags.Manager, error) { + soap, err := getSoapClient(ctx, cc) + if err != nil { + return nil, err + } + + mgr := tags.NewManager(rest.NewClient(soap.Client)) + ui := url.UserPassword(string(cc.Data[dataFields["username"]]), string(cc.Data[dataFields["password"]])) + + return mgr, mgr.Login(ctx, ui) +} + +func getCustomFieldsManager(ctx context.Context, cc *corev1.Secret) (*object.CustomFieldsManager, error) { + soap, err := getSoapClient(ctx, cc) + if err != nil { + return nil, err + } + + return object.GetCustomFieldsManager(soap.Client) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/validator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/validator.go new file mode 100644 index 0000000..43eb6e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/validator.go @@ -0,0 +1,24 @@ +package workload + +import ( + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +// Validator validates deprecated fields `environment` and `environmentFrom` are not being used. +// These fields were deprecated in favor of the k8s native fields `env` and `envFrom`. See https://github.com/rancher/rancher/issues/16148 +func Validator(request *types.APIContext, schema *types.Schema, data map[string]interface{}) error { + if containers, _ := values.GetSlice(data, "containers"); len(containers) > 0 { + for _, c := range containers { + if !convert.IsAPIObjectEmpty(values.GetValueN(c, "environment")) { + return httperror.NewAPIError(httperror.InvalidBodyContent, "field `environment` is deprecated, please use Kubernetes native field `env` for the container's environment variables") + } + if !convert.IsAPIObjectEmpty(values.GetValueN(c, "environmentFrom")) { + return httperror.NewAPIError(httperror.InvalidBodyContent, "field `environmentFrom` is deprecated, please use Kubernetes native fields `env` and `valueFrom` for the container's environment variables") + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/workload.go new file mode 100644 index 0000000..9c3e5f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/workload/workload.go @@ -0,0 +1,334 @@ +package workload + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/mitchellh/mapstructure" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + projectclient "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/clustermanager" + appsv1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + batchv1 "github.com/rancher/rancher/pkg/generated/norman/batch/v1" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/rbac" + projectschema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + k8sappsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sschema "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + workloadRevisions = "revisions" + DeprecatedRollbackTo = "deprecated.deployment.rollback.to" +) + +var ( + allowRedeployTypes = map[string]bool{"cronJob": true, "deployment": true, "replicationController": true, "statefulSet": true, "daemonSet": true, "replicaSet": true} + errInvalidWorkloadType = errors.New("invalid workload type") +) + +type Config struct { + ClusterManager *clustermanager.Manager + Schemas map[string]*types.Schema +} + +func (a *Config) ActionHandler(actionName string, action *types.Action, apiContext *types.APIContext) error { + var deployment projectclient.Workload + accessError := access.ByID(apiContext, &projectschema.Version, "workload", apiContext.ID, &deployment) + if accessError != nil { + return httperror.NewAPIError(httperror.InvalidReference, "Error accessing workload") + } + workloadType, namespace, name := splitID(deployment.ID) + + // Create a RawResource with a minimal config. This will be used for the eventual "CanDo" method, which parses + // the name and namespace from a RawResource object. + rawResource := &types.RawResource{ + Values: map[string]interface{}{ + "id": name, + "namespaceId": namespace, + }, + } + if err := a.canUpdateWorkload(apiContext, rawResource, workloadType); err != nil { + if err == errInvalidWorkloadType { + return httperror.NewAPIError(httperror.InvalidType, errInvalidWorkloadType.Error()) + } + return httperror.NewAPIError(httperror.NotFound, "not found") + } + switch actionName { + case "rollback": + clusterName := a.ClusterManager.ClusterName(apiContext) + if clusterName == "" { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Cluster name empty %s", deployment.ID)) + } + clusterContext, err := a.ClusterManager.UserContextNoControllers(clusterName) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error getting cluster context %s", deployment.ID)) + } + return a.rollbackDeployment(apiContext, clusterContext, actionName, deployment, namespace, name) + + case "pause": + if deployment.Paused { + return httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Deployment %s already paused", deployment.ID)) + } + return updatePause(apiContext, true, deployment, "pause") + + case "resume": + if !deployment.Paused { + return httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Pause deployment %s before resume", deployment.ID)) + } + return updatePause(apiContext, false, deployment, "resume") + case "redeploy": + return updateTimestamp(apiContext, deployment) + } + return nil +} + +func fetchRevisionFor(apiContext *types.APIContext, rollbackInput *projectclient.DeploymentRollbackInput, namespace string, name string, currRevision string) string { + rollbackTo := rollbackInput.ReplicaSetID + if rollbackTo == "" { + revisionNum, _ := convert.ToNumber(currRevision) + return convert.ToString(revisionNum - 1) + } + data := getRevisions(apiContext, namespace, name, rollbackTo) + if len(data) > 0 { + return convert.ToString(values.GetValueN(data[0], "workloadAnnotations", "deployment.kubernetes.io/revision")) + } + return "" +} + +func getRevisions(apiContext *types.APIContext, namespace string, name string, requestedID string) []map[string]interface{} { + var data, replicaSets []map[string]interface{} + options := map[string]string{"hidden": "true"} + conditions := []*types.QueryCondition{ + types.NewConditionFromString("namespaceId", types.ModifierEQ, []string{namespace}...), + } + if requestedID != "" { + // want a specific replicaSet + conditions = append(conditions, types.NewConditionFromString("id", types.ModifierEQ, []string{requestedID}...)) + } + + if err := access.List(apiContext, &projectschema.Version, projectclient.ReplicaSetType, &types.QueryOptions{Options: options, Conditions: conditions}, &replicaSets); err == nil { + for _, replicaSet := range replicaSets { + ownerReferences := convert.ToMapSlice(replicaSet["ownerReferences"]) + for _, ownerReference := range ownerReferences { + kind := convert.ToString(ownerReference["kind"]) + ownerName := convert.ToString(ownerReference["name"]) + if kind == "Deployment" && name == ownerName { + data = append(data, replicaSet) + continue + } + } + } + } + return data +} + +func updatePause(apiContext *types.APIContext, value bool, deployment projectclient.Workload, actionName string) error { + data, err := convert.EncodeToMap(deployment) + if err == nil { + values.PutValue(data, value, "paused") + err = update(apiContext, data, deployment.ID) + } + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error updating workload %s by %s : %s", deployment.ID, actionName, err.Error())) + } + return nil +} + +func update(apiContext *types.APIContext, data map[string]interface{}, ID string) error { + workloadSchema := apiContext.Schemas.Schema(&schema.Version, "workload") + _, err := workloadSchema.Store.Update(apiContext, workloadSchema, data, ID) + return err +} + +func (a *Config) rollbackDeployment(apiContext *types.APIContext, clusterContext *config.UserContext, + actionName string, deployment projectclient.Workload, namespace string, name string) error { + input, err := handler.ParseAndValidateActionBody(apiContext, apiContext.Schemas.Schema(&projectschema.Version, + projectclient.DeploymentRollbackInputType)) + if err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse action body: %v", err)) + } + rollbackInput := &projectclient.DeploymentRollbackInput{} + if err := mapstructure.Decode(input, rollbackInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + currRevision := deployment.WorkloadAnnotations["deployment.kubernetes.io/revision"] + if currRevision == "1" { + httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("No revision for rolling back %s", deployment.ID)) + } + // if deployment's apiversion is apps/v1, we update the object, so getting it from etcd instead of cache + depl, err := clusterContext.Apps.Deployments(namespace).Get(name, v1.GetOptions{}) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error getting deployment %v: %v", name, err)) + } + deploymentVersion, err := k8sschema.ParseGroupVersion(depl.APIVersion) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error parsing api version for deployment %v: %v", name, err)) + } + if deploymentVersion == k8sappsv1.SchemeGroupVersion { + logrus.Debugf("Deployment apiversion is apps/v1") + // DeploymentRollback & RollbackTo are deprecated in apps/v1 + // only way to rollback is update deployment podSpec with replicaSet podSpec + split := strings.SplitN(rollbackInput.ReplicaSetID, ":", 3) + if len(split) != 3 || split[0] != appsv1.ReplicaSetResource.SingularName { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Invalid ReplicaSet %s", rollbackInput.ReplicaSetID)) + } + replicaNamespace, replicaName := split[1], split[2] + rs, err := clusterContext.Apps.ReplicaSets("").GetNamespaced(replicaNamespace, replicaName, v1.GetOptions{}) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("ReplicaSet %s not found for deployment %s", rollbackInput.ReplicaSetID, deployment.ID)) + } + toUpdateDepl := depl.DeepCopy() + toUpdateDepl.Spec.Template.Spec = rs.Spec.Template.Spec + _, err = clusterContext.Apps.Deployments("").Update(toUpdateDepl) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error updating workload under apps/v1 %s by %s : %s", deployment.ID, actionName, err.Error())) + } + return nil + } + + revision := fetchRevisionFor(apiContext, rollbackInput, namespace, name, currRevision) + logrus.Debugf("rollbackInput %v", revision) + if revision == "" { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("ReplicaSet %s doesn't exist for deployment %s", rollbackInput.ReplicaSetID, deployment.ID)) + } + revisionNum, err := convert.ToNumber(revision) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error getting revision number %s for %s : %s", revision, deployment.ID, err.Error())) + } + data := map[string]interface{}{} + data["kind"] = "DeploymentRollback" + data["apiVersion"] = "extensions/v1beta1" + data["name"] = name + data["rollbackTo"] = map[string]interface{}{"revision": revisionNum} + deploymentRollback, err := json.Marshal(data) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error getting DeploymentRollback for %s %s", rollbackInput.ReplicaSetID, err.Error())) + } + err = clusterContext.UnversionedClient.Post().Prefix("apis/extensions/v1beta1/").Namespace(namespace). + Resource("deployments").Name(name).SubResource("rollback").Body(deploymentRollback).Do(apiContext.Request.Context()).Error() + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error updating workload %s by %s : %s", deployment.ID, actionName, err.Error())) + } + return nil +} +func updateTimestamp(apiContext *types.APIContext, workload projectclient.Workload) error { + timestamp := time.Now().UTC().Format(time.RFC3339) + data, err := convert.EncodeToMap(workload) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "Failed to parse workload") + } + values.PutValue(data, timestamp, "annotations", "cattle.io/timestamp") + err = update(apiContext, data, workload.ID) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Error redeploying workload %s : %s", workload.ID, err.Error())) + } + return nil +} +func (h Handler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + if apiContext.Link == workloadRevisions { + var deployment projectclient.Workload + if err := access.ByID(apiContext, &projectschema.Version, "workload", apiContext.ID, &deployment); err == nil { + _, namespace, deploymentName := splitID(deployment.ID) + data := getRevisions(apiContext, namespace, deploymentName, "") + apiContext.Type = projectclient.ReplicaSetType + apiContext.WriteResponse(http.StatusOK, data) + } + return nil + } + return httperror.NewAPIError(httperror.NotFound, "Link not found") +} + +func (a *Config) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + workloadID := resource.ID + workloadSchema := apiContext.Schemas.Schema(&schema.Version, "workload") + resource.Links["self"] = apiContext.URLBuilder.ResourceLinkByID(workloadSchema, workloadID) + resource.Links["remove"] = apiContext.URLBuilder.ResourceLinkByID(workloadSchema, workloadID) + resource.Links["update"] = apiContext.URLBuilder.ResourceLinkByID(workloadSchema, workloadID) + // Add redeploy action to the workload types that support redeploy. + _, ok := allowRedeployTypes[resource.Type] + workloadType, _, _ := splitID(resource.ID) + if ok && a.canUpdateWorkload(apiContext, resource, workloadType) == nil { + resource.Actions["redeploy"] = apiContext.URLBuilder.ActionLinkByID(workloadSchema, workloadID, "redeploy") + } + + delete(resource.Values, "nodeId") +} + +func (a *Config) DeploymentFormatter(apiContext *types.APIContext, resource *types.RawResource) { + workloadID := resource.ID + workloadSchema := apiContext.Schemas.Schema(&schema.Version, "workload") + a.Formatter(apiContext, resource) + resource.Links["revisions"] = apiContext.URLBuilder.ResourceLinkByID(workloadSchema, workloadID) + "/" + workloadRevisions + workloadType, _, _ := splitID(resource.ID) + if a.canUpdateWorkload(apiContext, resource, workloadType) == nil { + resource.Actions["pause"] = apiContext.URLBuilder.ActionLinkByID(workloadSchema, workloadID, "pause") + resource.Actions["resume"] = apiContext.URLBuilder.ActionLinkByID(workloadSchema, workloadID, "resume") + resource.Actions["rollback"] = apiContext.URLBuilder.ActionLinkByID(workloadSchema, workloadID, "rollback") + } +} + +type Handler struct { +} + +func splitID(id string) (string, string, string) { + workloadType := "" + namespace := "" + parts := strings.SplitN(id, ":", 3) + if len(parts) == 3 { + workloadType = parts[0] + namespace = parts[1] + id = parts[2] + } + return workloadType, namespace, id +} + +func (a *Config) canUpdateWorkload(apiContext *types.APIContext, resource *types.RawResource, workloadType string) error { + var apiGroup string + var pluralName string + + switch workloadType { + case appsv1.DeploymentResource.SingularName: + apiGroup = appsv1.GroupName + pluralName = appsv1.DeploymentResource.Name + case corev1.ReplicationControllerResource.SingularName: + apiGroup = corev1.GroupName + pluralName = corev1.ReplicationControllerResource.Name + case appsv1.ReplicaSetResource.SingularName: + apiGroup = appsv1.GroupName + pluralName = appsv1.ReplicaSetResource.Name + case appsv1.DaemonSetResource.SingularName: + apiGroup = appsv1.GroupName + pluralName = appsv1.DaemonSetResource.Name + case appsv1.StatefulSetResource.SingularName: + apiGroup = appsv1.GroupName + pluralName = appsv1.StatefulSetResource.Name + case batchv1.JobResource.SingularName: + apiGroup = batchv1.GroupName + pluralName = batchv1.JobResource.Name + case batchv1.CronJobResource.SingularName: + apiGroup = batchv1.GroupName + pluralName = batchv1.CronJobResource.Name + default: + logrus.Debugf("Invalid workload type: %s", workloadType) + return errInvalidWorkloadType + } + + return apiContext.AccessControl.CanDo(apiGroup, pluralName, "update", apiContext, + rbac.ObjFromContext(apiContext, resource), a.Schemas[workloadType]) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/formatter.go new file mode 100644 index 0000000..45686f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/formatter.go @@ -0,0 +1,14 @@ +package yaml + +import ( + "github.com/rancher/norman/types" +) + +func NewFormatter(next types.Formatter) types.Formatter { + return func(request *types.APIContext, resource *types.RawResource) { + if next != nil { + next(request, resource) + } + resource.Links["yaml"] = request.URLBuilder.Link("yaml", resource) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/link.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/link.go new file mode 100644 index 0000000..2b8ff36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/customization/yaml/link.go @@ -0,0 +1,68 @@ +package yaml + +import ( + "fmt" + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/clustermanager" +) + +func NewLinkHandler(proxy http.Handler, manager *clustermanager.Manager, next types.RequestHandler) types.RequestHandler { + lh := &yamlLinkHandler{ + Proxy: proxy, + ClusterManager: manager, + next: next, + } + + return lh.LinkHandler +} + +type yamlLinkHandler struct { + Proxy http.Handler + ClusterManager *clustermanager.Manager + next types.RequestHandler +} + +func (s *yamlLinkHandler) callNext(apiContext *types.APIContext, next types.RequestHandler) error { + if s.next != nil { + return s.next(apiContext, next) + } else if next != nil { + return next(apiContext, nil) + } + + return httperror.NewAPIError(httperror.NotFound, "link not found") +} + +func (s *yamlLinkHandler) LinkHandler(apiContext *types.APIContext, next types.RequestHandler) error { + if apiContext.Link != "yaml" { + return s.callNext(apiContext, next) + } + + clusterName := s.ClusterManager.ClusterName(apiContext) + if clusterName == "" { + return httperror.NewAPIError(httperror.NotFound, "cluster not found") + } + + schema := apiContext.Schemas.Schema(apiContext.Version, apiContext.Type) + if schema == nil { + return fmt.Errorf("failed to find schema " + apiContext.Type) + } + + data, err := schema.Store.ByID(apiContext, schema, apiContext.ID) + if err != nil { + return err + } + + link, _ := data[".selfLink"].(string) + + if link == "" { + return httperror.NewAPIError(httperror.NotFound, "self link not found") + } + + apiContext.Request.URL.Path = fmt.Sprintf("/k8s/clusters/%s%s", clusterName, link) + s.Proxy.ServeHTTP(apiContext.Response, apiContext.Request) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server.go new file mode 100644 index 0000000..046f449 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server.go @@ -0,0 +1,44 @@ +package norman + +import ( + normanapi "github.com/rancher/norman/api" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/settings" +) + +func NewServer(schemas *types.Schemas) (*normanapi.Server, error) { + server := normanapi.NewAPIServer() + if err := server.AddSchemas(schemas); err != nil { + return nil, err + } + ConfigureAPIUI(server) + return server, nil +} + +func ConfigureAPIUI(server *normanapi.Server) { + server.CustomAPIUIResponseWriter(cssURL, jsURL, settings.APIUIVersion.Get) +} + +func cssURL() string { + switch settings.UIOfflinePreferred.Get() { + case "dynamic": + if !settings.IsRelease() { + return "" + } + case "false": + return "" + } + return "/api-ui/ui.min.css" +} + +func jsURL() string { + switch settings.UIOfflinePreferred.Get() { + case "dynamic": + if !settings.IsRelease() { + return "" + } + case "false": + return "" + } + return "/api-ui/ui.min.js" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/managementstored/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/managementstored/setup.go new file mode 100644 index 0000000..29065bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/managementstored/setup.go @@ -0,0 +1,724 @@ +package managementstored + +import ( + "context" + "net/http" + + "github.com/rancher/norman/store/crd" + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/store/subtype" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/norman/customization/app" + "github.com/rancher/rancher/pkg/api/norman/customization/authn" + "github.com/rancher/rancher/pkg/api/norman/customization/catalog" + ccluster "github.com/rancher/rancher/pkg/api/norman/customization/cluster" + "github.com/rancher/rancher/pkg/api/norman/customization/clustertemplate" + "github.com/rancher/rancher/pkg/api/norman/customization/cred" + "github.com/rancher/rancher/pkg/api/norman/customization/etcdbackup" + "github.com/rancher/rancher/pkg/api/norman/customization/feature" + "github.com/rancher/rancher/pkg/api/norman/customization/globaldns" + "github.com/rancher/rancher/pkg/api/norman/customization/globalrole" + "github.com/rancher/rancher/pkg/api/norman/customization/globalrolebinding" + "github.com/rancher/rancher/pkg/api/norman/customization/kontainerdriver" + "github.com/rancher/rancher/pkg/api/norman/customization/multiclusterapp" + "github.com/rancher/rancher/pkg/api/norman/customization/namespacedresource" + "github.com/rancher/rancher/pkg/api/norman/customization/node" + "github.com/rancher/rancher/pkg/api/norman/customization/nodepool" + "github.com/rancher/rancher/pkg/api/norman/customization/nodetemplate" + + projectaction "github.com/rancher/rancher/pkg/api/norman/customization/project" + "github.com/rancher/rancher/pkg/api/norman/customization/roletemplate" + "github.com/rancher/rancher/pkg/api/norman/customization/roletemplatebinding" + "github.com/rancher/rancher/pkg/api/norman/customization/secret" + "github.com/rancher/rancher/pkg/api/norman/customization/setting" + appStore "github.com/rancher/rancher/pkg/api/norman/store/app" + catalogStore "github.com/rancher/rancher/pkg/api/norman/store/catalog" + "github.com/rancher/rancher/pkg/api/norman/store/cert" + "github.com/rancher/rancher/pkg/api/norman/store/cluster" + clustertemplatestore "github.com/rancher/rancher/pkg/api/norman/store/clustertemplate" + featStore "github.com/rancher/rancher/pkg/api/norman/store/feature" + globaldnsAPIStore "github.com/rancher/rancher/pkg/api/norman/store/globaldns" + globalRoleStore "github.com/rancher/rancher/pkg/api/norman/store/globalrole" + grbstore "github.com/rancher/rancher/pkg/api/norman/store/globalrolebindings" + nodeStore "github.com/rancher/rancher/pkg/api/norman/store/node" + nodeTemplateStore "github.com/rancher/rancher/pkg/api/norman/store/nodetemplate" + "github.com/rancher/rancher/pkg/api/norman/store/noopwatching" + passwordStore "github.com/rancher/rancher/pkg/api/norman/store/password" + "github.com/rancher/rancher/pkg/api/norman/store/preference" + rtStore "github.com/rancher/rancher/pkg/api/norman/store/roletemplate" + "github.com/rancher/rancher/pkg/api/norman/store/scoped" + settingstore "github.com/rancher/rancher/pkg/api/norman/store/setting" + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/rancher/pkg/auth/api" + authapi "github.com/rancher/rancher/pkg/auth/api" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + projectclient "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/clusterrouter" + md "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/nodeconfig" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + projectschema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Setup(ctx context.Context, apiContext *config.ScaledContext, clusterManager *clustermanager.Manager, + k8sProxy http.Handler, localClusterEnabled bool) error { + // Here we setup all types that will be stored in the Management cluster + schemas := apiContext.Schemas + + factory := &crd.Factory{ClientGetter: apiContext.ClientGetter} + + factory.BatchCreateCRDs(ctx, config.ManagementStorageContext, scheme.Scheme, schemas, &managementschema.Version, + client.AuthConfigType, + client.ClusterRegistrationTokenType, + client.ClusterRoleTemplateBindingType, + client.ClusterType, + client.DynamicSchemaType, + client.EtcdBackupType, + client.FeatureType, + client.FleetWorkspaceType, + client.GlobalRoleBindingType, + client.GlobalRoleType, + client.GroupMemberType, + client.GroupType, + client.KontainerDriverType, + client.NodeDriverType, + client.NodePoolType, + client.NodeTemplateType, + client.NodeType, + client.PodSecurityAdmissionConfigurationTemplateType, + client.PreferenceType, + client.ProjectNetworkPolicyType, + client.ProjectRoleTemplateBindingType, + client.ProjectType, + client.RkeK8sSystemImageType, + client.RkeK8sServiceOptionType, + client.RkeAddonType, + client.RoleTemplateType, + client.SamlTokenType, + client.SettingType, + client.TokenType, + client.UserAttributeType, + client.UserType, + client.ClusterTemplateType, + client.ClusterTemplateRevisionType, + ) + + factory.BatchCreateCRDs(ctx, config.ManagementStorageContext, scheme.Scheme, schemas, &managementschema.Version, + client.CatalogType, + client.CatalogTemplateType, + client.CatalogTemplateVersionType, + client.ClusterCatalogType, + client.ComposeConfigType, + client.MultiClusterAppType, + client.MultiClusterAppRevisionType, + client.ProjectCatalogType, + client.TemplateType, + client.TemplateVersionType, + client.TemplateContentType, + client.GlobalDnsType, + client.GlobalDnsProviderType, + client.RancherUserNotificationType, + ) + + factory.BatchCreateCRDs(ctx, config.ManagementStorageContext, scheme.Scheme, schemas, &projectschema.Version, + projectclient.AppType, + projectclient.AppRevisionType, + ) + + if err := factory.BatchWait(); err != nil { + return err + } + + Clusters(ctx, schemas, apiContext, clusterManager, k8sProxy) + ClusterRoleTemplateBinding(schemas, apiContext) + api.User(ctx, schemas, apiContext) + SecretTypes(ctx, schemas, apiContext) + Setting(schemas) + Feature(schemas, apiContext) + Preference(schemas, apiContext) + ClusterRegistrationTokens(schemas, apiContext) + Tokens(ctx, schemas, apiContext) + NodeTemplates(schemas, apiContext) + Project(schemas, apiContext) + ProjectRoleTemplateBinding(schemas, apiContext) + PodSecurityAdmissionConfigurationTemplate(schemas, apiContext) + GlobalRole(schemas, apiContext) + GlobalRoleBindings(schemas, apiContext) + RoleTemplate(schemas, apiContext) + KontainerDriver(schemas, apiContext) + ClusterTemplates(schemas, apiContext) + SystemImages(schemas, apiContext) + EtcdBackups(schemas, apiContext) + RancherUserNotifications(schemas, apiContext) + + Templates(ctx, schemas, apiContext) + TemplateVersion(ctx, schemas, apiContext) + Catalog(schemas, apiContext) + ProjectCatalog(schemas, apiContext) + ClusterCatalog(schemas, apiContext) + App(schemas, apiContext, clusterManager) + TemplateContent(schemas) + MultiClusterApps(schemas, apiContext) + GlobalDNSs(schemas, apiContext, localClusterEnabled) + GlobalDNSProviders(schemas, apiContext, localClusterEnabled) + + if err := NodeTypes(schemas, apiContext); err != nil { + return err + } + + authapi.Setup(ctx, clusterrouter.GetClusterID, apiContext, schemas) + authn.SetRTBStore(ctx, schemas.Schema(&managementschema.Version, client.ClusterRoleTemplateBindingType), apiContext) + authn.SetRTBStore(ctx, schemas.Schema(&managementschema.Version, client.ProjectRoleTemplateBindingType), apiContext) + nodeStore.SetupStore(schemas.Schema(&managementschema.Version, client.NodeType)) + projectaction.SetProjectStore(schemas.Schema(&managementschema.Version, client.ProjectType), apiContext) + setupScopedTypes(schemas) + setupPasswordTypes(ctx, schemas, apiContext) + + multiclusterapp.SetMemberStore(ctx, schemas.Schema(&managementschema.Version, client.MultiClusterAppType), apiContext) + GlobalDNSProvidersPwdWrap(schemas, apiContext, localClusterEnabled) + + return nil +} + +func setupPasswordTypes(ctx context.Context, schemas *types.Schemas, management *config.ScaledContext) { + secretStore := management.Core.Secrets("") + nsStore := management.Core.Namespaces("") + passwordStore.SetPasswordStore(schemas, secretStore, nsStore) +} + +func setupScopedTypes(schemas *types.Schemas) { + for _, schema := range schemas.Schemas() { + if schema.Scope != types.NamespaceScope || schema.Store == nil || schema.Store.Context() != config.ManagementStorageContext { + continue + } + + for _, key := range []string{"projectId", "clusterId"} { + ns, ok := schema.ResourceFields["namespaceId"] + if !ok { + continue + } + + if _, ok := schema.ResourceFields[key]; !ok { + continue + } + + schema.Store = scoped.NewScopedStore(key, schema.Store) + ns.Required = false + schema.ResourceFields["namespaceId"] = ns + break + } + } +} + +func Clusters(ctx context.Context, schemas *types.Schemas, managementContext *config.ScaledContext, clusterManager *clustermanager.Manager, k8sProxy http.Handler) { + schema := schemas.Schema(&managementschema.Version, client.ClusterType) + clusterFormatter := ccluster.NewFormatter(schemas, managementContext) + schema.Formatter = clusterFormatter.Formatter + schema.CollectionFormatter = clusterFormatter.CollectionFormatter + clusterStore := cluster.GetClusterStore(schema, managementContext, clusterManager, k8sProxy) + schema.Store = clusterStore + + handler := ccluster.ActionHandler{ + NodepoolGetter: managementContext.Management, + NodeLister: managementContext.Management.Nodes("").Controller().Lister(), + ClusterClient: managementContext.Management.Clusters(""), + CatalogManager: managementContext.CatalogManager, + UserMgr: managementContext.UserManager, + ClusterManager: clusterManager, + NodeTemplateGetter: managementContext.Management, + BackupClient: managementContext.Management.EtcdBackups(""), + ClusterTemplateClient: managementContext.Management.ClusterTemplates(""), + ClusterTemplateRevisionClient: managementContext.Management.ClusterTemplateRevisions(""), + SubjectAccessReviewClient: managementContext.K8sClient.AuthorizationV1().SubjectAccessReviews(), + TokenClient: managementContext.Management.Tokens(""), + Auth: requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, managementContext), + } + + clusterValidator := ccluster.Validator{ + ClusterClient: managementContext.Management.Clusters(""), + ClusterLister: managementContext.Management.Clusters("").Controller().Lister(), + ClusterTemplateLister: managementContext.Management.ClusterTemplates("").Controller().Lister(), + ClusterTemplateRevisionLister: managementContext.Management.ClusterTemplateRevisions("").Controller().Lister(), + Users: managementContext.Management.Users(""), + GrbLister: managementContext.Management.GlobalRoleBindings("").Controller().Lister(), + GrLister: managementContext.Management.GlobalRoles("").Controller().Lister(), + } + + handler.CatalogTemplateVersionLister = managementContext.Management.CatalogTemplateVersions("").Controller().Lister() + schema.ActionHandler = handler.ClusterActionHandler + schema.Validator = clusterValidator.Validator +} + +func Templates(ctx context.Context, schemas *types.Schemas, managementContext *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.TemplateType) + schema.Scope = types.NamespaceScope + schema.Store = catalog.GetTemplateStore(ctx, managementContext) + + wrapper := catalog.TemplateWrapper{ + CatalogLister: managementContext.Management.Catalogs("").Controller().Lister(), + ClusterCatalogLister: managementContext.Management.ClusterCatalogs("").Controller().Lister(), + ProjectCatalogLister: managementContext.Management.ProjectCatalogs("").Controller().Lister(), + CatalogTemplateVersionLister: managementContext.Management.CatalogTemplateVersions("").Controller().Lister(), + SecretLister: managementContext.Core.Secrets("").Controller().Lister(), + } + schema.Formatter = wrapper.TemplateFormatter + schema.LinkHandler = wrapper.TemplateIconHandler + + schemaCatalogTemplate := schemas.Schema(&managementschema.Version, client.CatalogTemplateType) + schemaCatalogTemplate.CollectionMethods = []string{} + schemaCatalogTemplate.ResourceMethods = []string{} +} + +func TemplateVersion(ctx context.Context, schemas *types.Schemas, managementContext *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.TemplateVersionType) + schema.Scope = types.NamespaceScope + schema.Store = proxy.NewProxyStore(ctx, managementContext.ClientGetter, + config.ManagementStorageContext, + scheme.Scheme, + []string{"apis"}, + "management.cattle.io", + "v3", + "CatalogTemplateVersion", + "catalogtemplateversions") + t := catalog.TemplateVerionFormatterWrapper{ + CatalogLister: managementContext.Management.Catalogs("").Controller().Lister(), + ClusterCatalogLister: managementContext.Management.ClusterCatalogs("").Controller().Lister(), + ProjectCatalogLister: managementContext.Management.ProjectCatalogs("").Controller().Lister(), + SecretLister: managementContext.Core.Secrets("").Controller().Lister(), + } + schema.Formatter = t.TemplateVersionFormatter + schema.LinkHandler = t.TemplateVersionReadmeHandler + schema.Store = noopwatching.Wrap(schema.Store) + + schemaCatalogTemplateVersion := schemas.Schema(&managementschema.Version, client.CatalogTemplateVersionType) + schemaCatalogTemplateVersion.CollectionMethods = []string{} + schemaCatalogTemplateVersion.ResourceMethods = []string{} +} + +func TemplateContent(schemas *types.Schemas) { + schema := schemas.Schema(&managementschema.Version, client.TemplateContentType) + schema.Store = noopwatching.Wrap(schema.Store) + schema.CollectionMethods = []string{} +} + +func Catalog(schemas *types.Schemas, managementContext *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.CatalogType) + schema.Formatter = catalog.Formatter + handler := catalog.ActionHandler{ + CatalogClient: managementContext.Management.Catalogs(""), + } + schema.ActionHandler = handler.RefreshActionHandler + schema.CollectionFormatter = catalog.CollectionFormatter + schema.LinkHandler = handler.ExportYamlHandler + schema.Validator = catalog.Validator + users := managementContext.Management.Users("") + grbLister := managementContext.Management.GlobalRoleBindings("").Controller().Lister() + grLister := managementContext.Management.GlobalRoles("").Controller().Lister() + secretLister := managementContext.Core.Secrets("").Controller().Lister() + secrets := managementContext.Core.Secrets("") + clusterLister := managementContext.Management.Clusters("").Controller().Lister() + schema.Store = catalogStore.Wrap(schema.Store, managementContext, users, grbLister, grLister, secretLister, secrets, clusterLister) +} + +func ProjectCatalog(schemas *types.Schemas, managementContext *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ProjectCatalogType) + schema.Formatter = catalog.Formatter + handler := catalog.ActionHandler{ + ProjectCatalogClient: managementContext.Management.ProjectCatalogs(""), + } + schema.ActionHandler = handler.RefreshProjectCatalogActionHandler + schema.CollectionFormatter = catalog.CollectionFormatter + schema.Validator = catalog.Validator + users := managementContext.Management.Users("") + grbLister := managementContext.Management.GlobalRoleBindings("").Controller().Lister() + grLister := managementContext.Management.GlobalRoles("").Controller().Lister() + secretLister := managementContext.Core.Secrets("").Controller().Lister() + secrets := managementContext.Core.Secrets("") + clusterLister := managementContext.Management.Clusters("").Controller().Lister() + schema.Store = catalogStore.Wrap(schema.Store, managementContext, users, grbLister, grLister, secretLister, secrets, clusterLister) +} + +func ClusterCatalog(schemas *types.Schemas, managementContext *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ClusterCatalogType) + schema.Formatter = catalog.Formatter + handler := catalog.ActionHandler{ + ClusterCatalogClient: managementContext.Management.ClusterCatalogs(""), + } + schema.ActionHandler = handler.RefreshClusterCatalogActionHandler + schema.CollectionFormatter = catalog.CollectionFormatter + schema.Validator = catalog.Validator + users := managementContext.Management.Users("") + grbLister := managementContext.Management.GlobalRoleBindings("").Controller().Lister() + grLister := managementContext.Management.GlobalRoles("").Controller().Lister() + secretLister := managementContext.Core.Secrets("").Controller().Lister() + secrets := managementContext.Core.Secrets("") + clusterLister := managementContext.Management.Clusters("").Controller().Lister() + schema.Store = catalogStore.Wrap(schema.Store, managementContext, users, grbLister, grLister, secretLister, secrets, clusterLister) +} + +func ClusterRegistrationTokens(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ClusterRegistrationTokenType) + schema.Store = &cluster.RegistrationTokenStore{ + Store: schema.Store, + } +} + +func Tokens(ctx context.Context, schemas *types.Schemas, mgmt *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.TokenType) + manager := tokens.NewManager(ctx, mgmt) + + schema.Store = &transform.Store{ + Store: schema.Store, + StreamTransformer: manager.TokenStreamTransformer, + } +} + +func NodeTemplates(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.NodeTemplateType) + npl := management.Management.NodePools("").Controller().Lister() + nl := management.Management.Nodes("").Controller().Lister() + userLister := management.Management.Users("").Controller().Lister() + f := nodetemplate.Formatter{ + NodePoolLister: npl, + NodeLister: nl, + UserLister: userLister, + } + schema.Formatter = f.Formatter + + nsLister := management.Core.Namespaces("") + nodeTemplateGlobalStore := namespacedresource.Wrap(schema.Store, nsLister, namespace.NodeTemplateGlobalNamespace) + + globalSecretLister := management.Core.Secrets(namespace.GlobalNamespace).Controller().Lister() + nodeTemplateClient := management.Management.NodeTemplates("") + + s := nodeTemplateStore.Wrap(nodeTemplateGlobalStore, npl, nl, globalSecretLister, nodeTemplateClient) + schema.Store = s + schema.Validator = nodetemplate.Validator +} + +func SecretTypes(ctx context.Context, schemas *types.Schemas, management *config.ScaledContext) { + secretSchema := schemas.Schema(&projectschema.Version, projectclient.SecretType) + secretSchema.Store = proxy.NewProxyStore(ctx, management.ClientGetter, + config.ManagementStorageContext, + scheme.Scheme, + []string{"api"}, + "", + "v1", + "Secret", + "secrets") + secretSchema.Validator = secret.Validator + for _, subSchema := range schemas.SchemasForVersion(projectschema.Version) { + if subSchema.BaseType == projectclient.SecretType && subSchema.ID != projectclient.SecretType { + if subSchema.CanList(nil) == nil { + subSchema.Store = subtype.NewSubTypeStore(subSchema.ID, secretSchema.Store) + subSchema.Validator = secret.Validator + } + } + } + + secretSchema = schemas.Schema(&projectschema.Version, projectclient.CertificateType) + secretSchema.Store = cert.Wrap(secretSchema.Store) + + mgmtSecretSchema := schemas.Schema(&managementschema.Version, client.ManagementSecretType) + mgmtSecretSchema.Store = proxy.NewProxyStore(ctx, management.ClientGetter, + config.ManagementStorageContext, + scheme.Scheme, + []string{"api"}, + "", + "v1", + "Secret", + "secrets") + + credSchema := schemas.Schema(&managementschema.Version, client.CloudCredentialType) + credSchema.Store = cred.Wrap(mgmtSecretSchema.Store, + management.Core.Namespaces(""), + management.Management.NodeTemplates("").Controller().Lister(), + management.Wrangler.Provisioning.Cluster().Cache(), + ) + credSchema.Validator = cred.Validator +} + +func Preference(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.PreferenceType) + schema.Store = preference.NewStore(management.Core.Namespaces(""), schema.Store) +} + +func NodeTypes(schemas *types.Schemas, management *config.ScaledContext) error { + secretStore, err := nodeconfig.NewStore(management.Core.Namespaces(""), management.Core) + if err != nil { + return err + } + + schema := schemas.Schema(&managementschema.Version, client.NodeDriverType) + machineDriverHandlers := &node.DriverHandlers{ + NodeDriverClient: management.Management.NodeDrivers(""), + } + schema.Formatter = machineDriverHandlers.Formatter + schema.ActionHandler = machineDriverHandlers.ActionHandler + schema.LinkHandler = machineDriverHandlers.ExportYamlHandler + + machineHandler := &node.Handler{ + SecretStore: secretStore, + } + + schema = schemas.Schema(&managementschema.Version, client.NodeType) + schema.Formatter = node.Formatter + schema.LinkHandler = machineHandler.LinkHandler + actionWrapper := node.ActionWrapper{} + schema.ActionHandler = actionWrapper.ActionHandler + + schema = schemas.Schema(&managementschema.Version, client.NodePoolType) + ntl := management.Management.NodeTemplates("").Controller().Lister() + f := &nodepool.Formatter{ + NodeTemplateLister: ntl, + } + schema.Formatter = f.Formatter + + nodepoolValidator := nodepool.Validator{ + NodePoolLister: management.Management.NodePools("").Controller().Lister(), + } + schema.Validator = nodepoolValidator.Validator + return nil +} + +func App(schemas *types.Schemas, management *config.ScaledContext, clusterManager *clustermanager.Manager) { + schema := schemas.Schema(&projectschema.Version, projectclient.AppType) + store := &appStore.Store{ + Store: schema.Store, + Apps: management.Project.Apps("").Controller().Lister(), + TemplateVersionLister: management.Management.CatalogTemplateVersions("").Controller().Lister(), + CatalogManager: management.CatalogManager, + ClusterLister: management.Management.Clusters("").Controller().Lister(), + } + schema.Store = store + wrapper := app.Wrapper{ + Clusters: management.Management.Clusters(""), + ClusterManager: clusterManager, + CatalogManager: management.CatalogManager, + TemplateVersionClient: management.Management.CatalogTemplateVersions(""), + TemplateVersionLister: management.Management.CatalogTemplateVersions("").Controller().Lister(), + AppGetter: management.Project, + UserLister: management.Management.Users("").Controller().Lister(), + UserManager: management.UserManager, + } + schema.Formatter = app.Formatter + schema.ActionHandler = wrapper.ActionHandler + schema.LinkHandler = wrapper.LinkHandler + schema.Validator = wrapper.Validator +} + +func Setting(schemas *types.Schemas) { + schema := schemas.Schema(&managementschema.Version, client.SettingType) + schema.Formatter = setting.Formatter + schema.Validator = setting.Validator + schema.Store = settingstore.New(schema.Store) +} + +func Feature(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.FeatureType) + validator := feature.Validator{FeatureLister: management.Management.Features("").Controller().Lister()} + schema.Validator = validator.Validator + schema.Formatter = feature.Formatter + schema.Store = featStore.New(schema.Store) +} + +func Project(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ProjectType) + schema.Formatter = projectaction.Formatter + handler := &projectaction.Handler{ + Projects: management.Management.Projects(""), + ProjectLister: management.Management.Projects("").Controller().Lister(), + UserMgr: management.UserManager, + ClusterManager: management.ClientGetter.(*clustermanager.Manager), + ClusterLister: management.Management.Clusters("").Controller().Lister(), + ProvisioningClusterCache: management.Wrangler.Provisioning.Cluster().Cache(), + } + schema.ActionHandler = handler.Actions +} + +func PodSecurityAdmissionConfigurationTemplate(schemas *types.Schemas, management *config.ScaledContext) { + schemas.Schema(&managementschema.Version, client.PodSecurityAdmissionConfigurationTemplateType) +} + +func ClusterRoleTemplateBinding(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ClusterRoleTemplateBindingType) + schema.Validator = roletemplatebinding.NewCRTBValidator(management) +} + +func ProjectRoleTemplateBinding(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.ProjectRoleTemplateBindingType) + schema.Validator = roletemplatebinding.NewPRTBValidator(management) +} + +func GlobalRole(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.GlobalRoleType) + grLister := management.Management.GlobalRoles("").Controller().Lister() + schema.Store = globalRoleStore.Wrap(schema.Store, grLister) + schema.Formatter = globalrole.Formatter + w := globalrole.Wrapper{ + GlobalRoleLister: grLister, + } + schema.Validator = w.Validator +} + +func GlobalRoleBindings(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.GlobalRoleBindingType) + grLister := management.Management.GlobalRoles("").Controller().Lister() + schema.Store = grbstore.Wrap(schema.Store, grLister) + schema.Validator = globalrolebinding.Validator +} + +func RoleTemplate(schemas *types.Schemas, management *config.ScaledContext) { + rt := roletemplate.Wrapper{ + RoleTemplateLister: management.Management.RoleTemplates("").Controller().Lister(), + } + schema := schemas.Schema(&managementschema.Version, client.RoleTemplateType) + schema.Formatter = rt.Formatter + schema.Validator = rt.Validator + schema.Store = rtStore.Wrap(schema.Store, management.Management.RoleTemplates("").Controller().Lister()) +} + +func KontainerDriver(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.KontainerDriverType) + metadataHandler := md.MetadataController{ + SystemImagesLister: management.Management.RkeK8sSystemImages("").Controller().Lister(), + SystemImages: management.Management.RkeK8sSystemImages(""), + ServiceOptionsLister: management.Management.RkeK8sServiceOptions("").Controller().Lister(), + ServiceOptions: management.Management.RkeK8sServiceOptions(""), + AddonsLister: management.Management.RkeAddons("").Controller().Lister(), + Addons: management.Management.RkeAddons(""), + SettingLister: management.Management.Settings("").Controller().Lister(), + Settings: management.Management.Settings(""), + } + + handler := kontainerdriver.ActionHandler{ + KontainerDrivers: management.Management.KontainerDrivers(""), + KontainerDriverLister: management.Management.KontainerDrivers("").Controller().Lister(), + MetadataHandler: metadataHandler, + } + lh := kontainerdriver.ListHandler{ + SysImageLister: management.Management.RkeK8sSystemImages("").Controller().Lister(), + SysImages: management.Management.RkeK8sSystemImages(""), + ConfigMapLister: management.Core.ConfigMaps("").Controller().Lister(), + } + lh.CatalogLister = management.Management.Catalogs("").Controller().Lister() + schema.ActionHandler = handler.ActionHandler + schema.CollectionFormatter = kontainerdriver.CollectionFormatter + schema.Formatter = kontainerdriver.NewFormatter(management) + schema.Store = kontainerdriver.NewStore(management, schema.Store) + schema.ListHandler = lh.ListHandler + kontainerDriverValidator := kontainerdriver.Validator{ + KontainerDriverLister: management.Management.KontainerDrivers("").Controller().Lister(), + } + schema.Validator = kontainerDriverValidator.Validator +} + +func MultiClusterApps(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.MultiClusterAppType) + schema.Store = namespacedresource.Wrap(schema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + revisionSchema := schemas.Schema(&managementschema.Version, client.MultiClusterAppRevisionType) + revisionSchema.Store = namespacedresource.Wrap(revisionSchema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + wrapper := multiclusterapp.Wrapper{ + MultiClusterApps: management.Management.MultiClusterApps(""), + MultiClusterAppLister: management.Management.MultiClusterApps("").Controller().Lister(), + MultiClusterAppRevisionLister: management.Management.MultiClusterAppRevisions("").Controller().Lister(), + PrtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + CrtbLister: management.Management.ClusterRoleTemplateBindings("").Controller().Lister(), + RoleTemplateLister: management.Management.RoleTemplates("").Controller().Lister(), + Users: management.Management.Users(""), + GrbLister: management.Management.GlobalRoleBindings("").Controller().Lister(), + GrLister: management.Management.GlobalRoles("").Controller().Lister(), + Prtbs: management.Management.ProjectRoleTemplateBindings(""), + Crtbs: management.Management.ClusterRoleTemplateBindings(""), + ProjectLister: management.Management.Projects("").Controller().Lister(), + ClusterLister: management.Management.Clusters("").Controller().Lister(), + Apps: management.Project.Apps(""), + TemplateVersionLister: management.Management.CatalogTemplateVersions("").Controller().Lister(), + CatalogManager: management.CatalogManager, + } + schema.Formatter = wrapper.Formatter + schema.ActionHandler = wrapper.ActionHandler + schema.LinkHandler = wrapper.LinkHandler + schema.Validator = wrapper.Validator +} + +func GlobalDNSs(schemas *types.Schemas, management *config.ScaledContext, localClusterEnabled bool) { + gdns := globaldns.Wrapper{ + GlobalDNSes: management.Management.GlobalDnses(""), + GlobalDNSLister: management.Management.GlobalDnses("").Controller().Lister(), + PrtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + MultiClusterAppLister: management.Management.MultiClusterApps("").Controller().Lister(), + Users: management.Management.Users(""), + GrbLister: management.Management.GlobalRoleBindings("").Controller().Lister(), + GrLister: management.Management.GlobalRoles("").Controller().Lister(), + } + schema := schemas.Schema(&managementschema.Version, client.GlobalDnsType) + schema.Store = namespacedresource.Wrap(schema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + schema.Formatter = gdns.Formatter + schema.ActionHandler = gdns.ActionHandler + schema.Validator = gdns.Validator + schema.Store = globaldnsAPIStore.Wrap(schema.Store) + if !localClusterEnabled { + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + } +} + +func GlobalDNSProviders(schemas *types.Schemas, management *config.ScaledContext, localClusterEnabled bool) { + schema := schemas.Schema(&managementschema.Version, client.GlobalDnsProviderType) + schema.Store = namespacedresource.Wrap(schema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + schema.Store = globaldnsAPIStore.ProviderWrap(schema.Store) + if !localClusterEnabled { + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + } +} + +func GlobalDNSProvidersPwdWrap(schemas *types.Schemas, management *config.ScaledContext, localClusterEnabled bool) { + schema := schemas.Schema(&managementschema.Version, client.GlobalDnsProviderType) + schema.Store = globaldnsAPIStore.ProviderPwdWrap(schema.Store) +} + +func ClusterTemplates(schemas *types.Schemas, management *config.ScaledContext) { + wrapper := clustertemplate.Wrapper{ + ClusterTemplates: management.Management.ClusterTemplates(""), + ClusterTemplateLister: management.Management.ClusterTemplates("").Controller().Lister(), + ClusterTemplateRevisionLister: management.Management.ClusterTemplateRevisions("").Controller().Lister(), + ClusterTemplateRevisions: management.Management.ClusterTemplateRevisions(""), + } + wrapper.ClusterTemplateQuestions = wrapper.BuildQuestionsFromSchema(schemas.Schema(&managementschema.Version, client.ClusterSpecBaseType), schemas, "") + + schema := schemas.Schema(&managementschema.Version, client.ClusterTemplateType) + schema.Store = namespacedresource.Wrap(schema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + schema.Store = clustertemplatestore.WrapStore(schema.Store, management) + + schema.Formatter = wrapper.Formatter + schema.LinkHandler = wrapper.LinkHandler + + revisionSchema := schemas.Schema(&managementschema.Version, client.ClusterTemplateRevisionType) + revisionSchema.Store = namespacedresource.Wrap(revisionSchema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) + revisionSchema.Store = clustertemplatestore.WrapStore(revisionSchema.Store, management) + revisionSchema.Formatter = wrapper.RevisionFormatter + revisionSchema.CollectionFormatter = wrapper.CollectionFormatter + revisionSchema.ActionHandler = wrapper.ClusterTemplateRevisionsActionHandler +} + +func SystemImages(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.RkeK8sSystemImageType) + schema.Store = namespacedresource.Wrap(schema.Store, management.Core.Namespaces(""), namespace.GlobalNamespace) +} + +func EtcdBackups(schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.EtcdBackupType) + schema.Formatter = etcdbackup.Formatter +} + +func RancherUserNotifications(schemas *types.Schemas, management *config.ScaledContext) { + schemas.Schema(&managementschema.Version, client.RancherUserNotificationType) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/server.go new file mode 100644 index 0000000..6686e96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/server.go @@ -0,0 +1,48 @@ +package server + +import ( + "context" + "net/http" + + responsewriter "github.com/rancher/apiserver/pkg/middleware" + "github.com/rancher/norman/api/builtin" + "github.com/rancher/norman/pkg/subscribe" + "github.com/rancher/rancher/pkg/api/norman" + "github.com/rancher/rancher/pkg/api/norman/server/managementstored" + "github.com/rancher/rancher/pkg/api/norman/server/userstored" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/managementapi" + clusterSchema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + projectSchema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func New(ctx context.Context, scaledContext *config.ScaledContext, clusterManager *clustermanager.Manager, + k8sProxy http.Handler, localClusterEnabled bool) (http.Handler, error) { + subscribe.Register(&builtin.Version, scaledContext.Schemas) + subscribe.Register(&managementSchema.Version, scaledContext.Schemas) + subscribe.Register(&clusterSchema.Version, scaledContext.Schemas) + subscribe.Register(&projectSchema.Version, scaledContext.Schemas) + + if err := managementstored.Setup(ctx, scaledContext, clusterManager, k8sProxy, localClusterEnabled); err != nil { + return nil, err + } + + if err := userstored.Setup(ctx, scaledContext, clusterManager, k8sProxy); err != nil { + return nil, err + } + + server, err := norman.NewServer(scaledContext.Schemas) + if err != nil { + return nil, err + } + server.AccessControl = scaledContext.AccessControl + + if err := managementapi.Register(ctx, scaledContext, clusterManager, server); err != nil { + return nil, err + } + + chainGzip := responsewriter.Chain{responsewriter.Gzip, responsewriter.ContentType} + return chainGzip.Handler(server), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/proxy_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/proxy_store.go new file mode 100644 index 0000000..9afd037 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/proxy_store.go @@ -0,0 +1,55 @@ +package userstored + +import ( + "context" + "strings" + + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/scheme" + clusterSchema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +type storeWrapperFunc func(types.Store) types.Store + +func addProxyStore(ctx context.Context, schemas *types.Schemas, context *config.ScaledContext, schemaType, apiVersion string, storeWrapper storeWrapperFunc) *types.Schema { + s := schemas.Schema(&schema.Version, schemaType) + if s == nil { + s = schemas.Schema(&clusterSchema.Version, schemaType) + } + + if s == nil { + panic("Failed to find schema " + schemaType) + } + + prefix := []string{"api"} + kind := s.CodeName + plural := strings.ToLower(s.PluralName) + + var version, group string + parts := strings.SplitN(apiVersion, "/", 2) + if len(parts) == 1 { + version = parts[0] + } else { + group = parts[0] + version = parts[1] + prefix = []string{"apis"} + } + + s.Store = proxy.NewProxyStore(ctx, context.ClientGetter, + config.UserStorageContext, + scheme.Scheme, + prefix, + group, + version, + kind, + plural) + + if storeWrapper != nil { + s.Store = storeWrapper(s.Store) + } + + return s +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/setup.go new file mode 100644 index 0000000..dd1a7bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/server/userstored/setup.go @@ -0,0 +1,154 @@ +package userstored + +import ( + "context" + "net/http" + "time" + + "github.com/rancher/norman/store/subtype" + "github.com/rancher/norman/types" + namespacecustom "github.com/rancher/rancher/pkg/api/norman/customization/namespace" + "github.com/rancher/rancher/pkg/api/norman/customization/persistentvolumeclaim" + sec "github.com/rancher/rancher/pkg/api/norman/customization/secret" + "github.com/rancher/rancher/pkg/api/norman/customization/yaml" + "github.com/rancher/rancher/pkg/api/norman/store/apiservice" + "github.com/rancher/rancher/pkg/api/norman/store/cert" + "github.com/rancher/rancher/pkg/api/norman/store/hpa" + "github.com/rancher/rancher/pkg/api/norman/store/ingress" + "github.com/rancher/rancher/pkg/api/norman/store/namespace" + "github.com/rancher/rancher/pkg/api/norman/store/nocondition" + "github.com/rancher/rancher/pkg/api/norman/store/pod" + "github.com/rancher/rancher/pkg/api/norman/store/projectsetter" + "github.com/rancher/rancher/pkg/api/norman/store/secret" + "github.com/rancher/rancher/pkg/api/norman/store/service" + "github.com/rancher/rancher/pkg/api/norman/store/storageclass" + "github.com/rancher/rancher/pkg/api/norman/store/workload" + clusterClient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + client "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/clustermanager" + clusterschema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Setup(ctx context.Context, mgmt *config.ScaledContext, clusterManager *clustermanager.Manager, k8sProxy http.Handler) error { + // Here we setup all types that will be stored in the User cluster + + schemas := mgmt.Schemas + + addProxyStore(ctx, schemas, mgmt, client.ConfigMapType, "v1", nil) + addProxyStore(ctx, schemas, mgmt, client.CronJobType, "batch/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.DaemonSetType, "apps/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.DeploymentType, "apps/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.IngressType, "networking.k8s.io/v1", ingress.Wrap(clusterManager, mgmt)) + addProxyStore(ctx, schemas, mgmt, client.JobType, "batch/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.PersistentVolumeClaimType, "v1", nil) + addProxyStore(ctx, schemas, mgmt, client.PodType, "v1", func(store types.Store) types.Store { + return pod.New(store, clusterManager, mgmt) + }) + addProxyStore(ctx, schemas, mgmt, client.ReplicaSetType, "apps/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.ReplicationControllerType, "v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, client.ServiceType, "v1", service.New) + addProxyStore(ctx, schemas, mgmt, client.StatefulSetType, "apps/v1", workload.NewCustomizeStore) + addProxyStore(ctx, schemas, mgmt, clusterClient.NamespaceType, "v1", namespace.New) + addProxyStore(ctx, schemas, mgmt, clusterClient.PersistentVolumeType, "v1", nil) + addProxyStore(ctx, schemas, mgmt, clusterClient.APIServiceType, "apiregistration.k8s.io/v1", nil) + addProxyStore(ctx, schemas, mgmt, client.HorizontalPodAutoscalerType, "autoscaling/v2", nil) + addProxyStore(ctx, schemas, mgmt, clusterClient.StorageClassType, "storage.k8s.io/v1", nil) + + Secret(ctx, mgmt, schemas) + Service(ctx, schemas, mgmt) + Workload(schemas, clusterManager) + Namespace(schemas, clusterManager) + HPA(schemas, clusterManager) + + SetProjectID(schemas, clusterManager, k8sProxy) + StorageClass(schemas) + PersistentVolumeClaim(clusterManager, schemas) + + return nil +} + +func SetProjectID(schemas *types.Schemas, clusterManager *clustermanager.Manager, k8sProxy http.Handler) { + for _, schema := range schemas.SchemasForVersion(schema.Version) { + if schema.Store == nil || schema.Store.Context() != config.UserStorageContext { + continue + } + + if schema.CanList(nil) != nil { + continue + } + + if _, ok := schema.ResourceFields["namespaceId"]; !ok { + panic(schema.ID + " does not have namespaceId") + } + + if _, ok := schema.ResourceFields["projectId"]; !ok { + panic(schema.ID + " does not have projectId") + } + + schema.Store = projectsetter.New(schema.Store, clusterManager) + schema.Formatter = yaml.NewFormatter(schema.Formatter) + schema.LinkHandler = yaml.NewLinkHandler(k8sProxy, clusterManager, schema.LinkHandler) + } +} + +func StorageClass(schemas *types.Schemas) { + storageClassSchema := schemas.Schema(&clusterschema.Version, "storageClass") + storageClassSchema.Store = storageclass.Wrap(storageClassSchema.Store) +} + +func PersistentVolumeClaim(cmanager *clustermanager.Manager, schemas *types.Schemas) { + pvcSchema := schemas.Schema(&schema.Version, "persistentVolumeClaim") + + v := persistentvolumeclaim.Validator{ + ClusterManager: cmanager, + } + pvcSchema.Validator = v.Validator +} + +func Namespace(schemas *types.Schemas, manager *clustermanager.Manager) { + namespaceSchema := schemas.Schema(&clusterschema.Version, "namespace") + namespaceSchema.LinkHandler = namespacecustom.NewLinkHandler(namespaceSchema.LinkHandler, manager) + namespaceSchema.Formatter = namespacecustom.NewFormatter(yaml.NewFormatter(namespaceSchema.Formatter)) + actionWrapper := namespacecustom.ActionWrapper{ + ClusterManager: manager, + } + namespaceSchema.ActionHandler = actionWrapper.ActionHandler +} + +func Workload(schemas *types.Schemas, clusterManager *clustermanager.Manager) { + workload.NewWorkloadAggregateStore(schemas, clusterManager) +} + +func Service(ctx context.Context, schemas *types.Schemas, mgmt *config.ScaledContext) { + serviceSchema := schemas.Schema(&schema.Version, "service") + dnsSchema := schemas.Schema(&schema.Version, "dnsRecord") + // Move service store to DNSRecord and create new store on service, so they are then + // same store but two different instances + dnsSchema.Store = serviceSchema.Store + addProxyStore(ctx, schemas, mgmt, client.ServiceType, "v1", service.New) +} + +func Secret(ctx context.Context, management *config.ScaledContext, schemas *types.Schemas) { + schema := schemas.Schema(&schema.Version, "namespacedSecret") + schema.Store = secret.NewNamespacedSecretStore(ctx, management.ClientGetter) + schema.Validator = sec.Validator + + for _, subSchema := range schemas.Schemas() { + if subSchema.BaseType == schema.ID && subSchema.ID != schema.ID { + subSchema.Store = subtype.NewSubTypeStore(subSchema.ID, schema.Store) + subSchema.Validator = sec.Validator + } + } + + schema = schemas.Schema(&schema.Version, "namespacedCertificate") + schema.Store = cert.Wrap(schema.Store) +} + +func HPA(schemas *types.Schemas, manager *clustermanager.Manager) { + schema := schemas.Schema(&schema.Version, client.HorizontalPodAutoscalerType) + schema.Store = apiservice.NewAPIServicFilterStoreFunc(manager, "autoscaling/v2")(schema.Store) + schema.Store = nocondition.NewWrapper("initializing", "")(schema.Store) + schema.Store = hpa.NewIgnoreTransitioningErrorStore(schema.Store, 60*time.Second, "initializing") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter.go new file mode 100644 index 0000000..9f85794 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter.go @@ -0,0 +1,64 @@ +package apiservice + +import ( + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/clustermanager" + apiregistrationv1 "github.com/rancher/rancher/pkg/generated/norman/apiregistration.k8s.io/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type noWatchByAPIServiceStore struct { + types.Store + manager *clustermanager.Manager + version string +} + +func NewAPIServicFilterStoreFunc(cm *clustermanager.Manager, apiVersion string) func(types.Store) types.Store { + return func(store types.Store) types.Store { + return &noWatchByAPIServiceStore{ + Store: store, + manager: cm, + version: apiVersion, + } + } +} + +func (s *noWatchByAPIServiceStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + clustername := s.manager.ClusterName(apiContext) + versionName := getAPIVersionName(s.version) + apiServiceClient, err := s.getAPIServiceClient(clustername) + if err != nil { + return nil, errors.Wrapf(err, "failed to get api service client in cluster %s", clustername) + } + if _, err := apiServiceClient.Get(versionName, metav1.GetOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return nil, errors.Wrapf(err, "failed to get apiservice %s from client in cluster %s", versionName, clustername) + } + return nil, nil + } + return s.Store.Watch(apiContext, schema, opt) +} + +func (s *noWatchByAPIServiceStore) getAPIServiceClient(clusterName string) (apiregistrationv1.APIServiceInterface, error) { + userContext, err := s.manager.UserContextNoControllers(clusterName) + if err != nil { + return nil, err + } + return userContext.APIAggregation.APIServices(""), nil +} + +func getAPIVersionName(version string) string { + parts := strings.Split(version, "/") + if len(parts) == 1 { + parts[0] = parts[0] + "." + } + //reverse the splited strings, [autoscaling,v2beta2] become [v2beta2,autoscaling] + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + return strings.Join(parts, ".") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter_test.go new file mode 100644 index 0000000..9d4e99c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/apiservice/filter_test.go @@ -0,0 +1,21 @@ +package apiservice + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_getVersionName(t *testing.T) { + type testcase struct { + version string + expectVersionName string + } + testcases := []testcase{ + testcase{version: "v1", expectVersionName: "v1."}, + testcase{version: "autoscaling/v2", expectVersionName: "v2.autoscaling"}, + } + for _, c := range testcases { + assert.Equalf(t, c.expectVersionName, getAPIVersionName(c.version), "Failed to parse version name from %s", c.version) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/app/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/app/store.go new file mode 100644 index 0000000..7096c22 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/app/store.go @@ -0,0 +1,200 @@ +package app + +import ( + "fmt" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + pv3app "github.com/rancher/rancher/pkg/api/norman/customization/app" + "github.com/rancher/rancher/pkg/catalog/manager" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + hcommon "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + mgmtschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" +) + +type Store struct { + types.Store + Apps pv3.AppLister + TemplateVersionLister v3.CatalogTemplateVersionLister + CatalogManager manager.CatalogManager + ClusterLister v3.ClusterLister +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := s.checkAccessToTemplateVersion(apiContext, data); err != nil { + return nil, err + } + + if err := s.verifyAppExternalIDMatchesProject(data, ""); err != nil { + return nil, err + } + + projectID, _ := data["projectId"].(string) + clusterName, _ := ref.Parse(projectID) + + if err := s.validateChartCompatibility(clusterName, "", data); err != nil { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + return s.Store.Create(apiContext, schema, data) +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + if err := s.validateForMultiClusterApp(id, "delete"); err != nil { + return nil, err + } + return s.Store.Delete(apiContext, schema, id) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := s.checkAccessToTemplateVersion(apiContext, data); err != nil { + return nil, err + } + + if err := s.verifyAppExternalIDMatchesProject(data, id); err != nil { + return nil, err + } + + if err := s.validateForMultiClusterApp(id, "update"); err != nil { + return nil, err + } + + projectID, _ := data["projectId"].(string) + clusterName, _ := ref.Parse(projectID) + + ns, name := ref.Parse(id) + if ns == "" || name == "" { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("invalid app id %s", id)) + } + + app, err := s.Apps.Get(ns, name) + if err != nil { + return nil, httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("could not retrieve app [%s]: %v", id, err)) + } + _, _, _, _, currentAppVersion, err := hcommon.SplitExternalID(app.Spec.ExternalID) + if err != nil { + httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("could not parse current externalID [%s]: %s", + app.Spec.ExternalID, err.Error())) + } + + if err := s.validateChartCompatibility(clusterName, currentAppVersion, data); err != nil { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *Store) validateForMultiClusterApp(id string, msg string) error { + ns, name := ref.Parse(id) + if ns == "" || name == "" { + return fmt.Errorf("invalid app id %s", id) + } + app, err := s.Apps.Get(ns, name) + if err != nil { + if !errors.IsNotFound(err) { + return fmt.Errorf("error getting app %s: %v", id, err) + } + return nil + } + if label, ok := app.Labels[pv3app.MCappLabel]; ok && label != "" { + return fmt.Errorf("app %s is controlled by mcapp %s : cannot be %sd", id, label, msg) + } + return nil +} + +func (s *Store) validateChartCompatibility(clusterName, currentAppVersion string, data map[string]interface{}) error { + externalID := convert.ToString(data["externalId"]) + if externalID == "" { + return nil + } + + templateVersionID, templateNamespace, err := hcommon.ParseExternalID(externalID) + if err != nil { + return err + } + + template, err := s.TemplateVersionLister.Get(templateNamespace, templateVersionID) + if err != nil { + return err + } + + return s.CatalogManager.ValidateChartCompatibility(template, clusterName, currentAppVersion) +} + +func (s *Store) checkAccessToTemplateVersion(apiContext *types.APIContext, data map[string]interface{}) error { + templateVersionID, ns, err := s.parseAppExternalID(data) + if err != nil { + return err + } + if templateVersionID == "" && ns == "" { + // all users can use a local template to create apps + return nil + } + if ns == namespace.GlobalNamespace { + // all users have read access to global catalogs, and can use their template versions to create apps + return nil + } + templateVersionID = ns + ":" + templateVersionID + + var templateVersion client.CatalogTemplateVersion + if err := access.ByID(apiContext, &mgmtschema.Version, client.CatalogTemplateVersionType, templateVersionID, &templateVersion); err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status { + return httperror.NewAPIError(httperror.NotFound, "Cannot find template version") + } + } + return err + } + return nil +} + +func (s *Store) verifyAppExternalIDMatchesProject(data map[string]interface{}, id string) error { + _, catalogNs, err := s.parseAppExternalID(data) + if err != nil { + return err + } + if catalogNs == namespace.GlobalNamespace || catalogNs == "" { + // apps from global catalog or local template can be launched in any cluster + return nil + } + + // check if target project is either same as the catalogNs (project scoped catalog), or belongs in the ns (cluster scoped catalog) + projectID := convert.ToString(data["projectId"]) + if projectID == "" { + // this can happen only during app edit, get projectID from app + ns, name := ref.Parse(id) + if ns == "" || name == "" { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("app id [%s] passed during edit is invalid", id)) + } + app, err := s.Apps.Get(ns, name) + if err != nil { + return fmt.Errorf("error getting app %s: %v", id, err) + } + projectID = app.Spec.ProjectName + } + clusterName, projectName := ref.Parse(projectID) + if catalogNs == clusterName || catalogNs == projectName { + return nil + } + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("Cannot use catalog from %v to launch app in %v", catalogNs, projectID)) +} + +func (s *Store) parseAppExternalID(data map[string]interface{}) (string, string, error) { + externalID := convert.ToString(data["externalId"]) + if externalID == "" { + return "", "", nil + } + + templateVersionID, ns, err := hcommon.ParseExternalID(externalID) + if err != nil { + return "", "", err + } + return templateVersionID, ns, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/catalog/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/catalog/store.go new file mode 100644 index 0000000..957d20f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/catalog/store.go @@ -0,0 +1,290 @@ +package catalog + +import ( + "context" + "fmt" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" + c "github.com/rancher/rancher/pkg/api/norman/customization/catalog" + gaccess "github.com/rancher/rancher/pkg/api/norman/customization/globalnamespaceaccess" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sTypes "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/dynamic" +) + +const ( + catalogSecrets = "catalogSecrets" + catalogSecretKey = "credentialSecret" +) + +type Store struct { + types.Store + Users v3.UserInterface + GrbLister v3.GlobalRoleBindingLister + GrLister v3.GlobalRoleLister + secretMigrator *secretmigrator.Migrator + clusterLister v3.ClusterLister + catalogClient dynamic.ResourceInterface + clusterCatalogClient dynamic.NamespaceableResourceInterface + projectCatalogClient dynamic.NamespaceableResourceInterface +} + +func Wrap(store types.Store, mgmt *config.ScaledContext, users v3.UserInterface, grbLister v3.GlobalRoleBindingLister, grLister v3.GlobalRoleLister, secretLister v1.SecretLister, secrets v1.SecretInterface, clusterLister v3.ClusterLister) types.Store { + var catalogClient dynamic.ResourceInterface + var clusterCatalogClient dynamic.NamespaceableResourceInterface + var projectCatalogClient dynamic.NamespaceableResourceInterface + dynamicClient, err := dynamic.NewForConfig(&mgmt.RESTConfig) + if err != nil { + logrus.Warnf("GetClusterStore error creating K8s dynamic client: %v", err) + } else { + catalogClient = dynamicClient.Resource(v3.CatalogGroupVersionResource) + clusterCatalogClient = dynamicClient.Resource(v3.ClusterCatalogGroupVersionResource) + projectCatalogClient = dynamicClient.Resource(v3.ProjectCatalogGroupVersionResource) + + } + return &Store{ + Store: store, + Users: users, + GrbLister: grbLister, + GrLister: grLister, + secretMigrator: secretmigrator.NewMigrator(secretLister, secrets), + clusterLister: clusterLister, + catalogClient: catalogClient, + clusterCatalogClient: clusterCatalogClient, + projectCatalogClient: projectCatalogClient, + } +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + password, _ := data["password"].(string) + secret, err := s.secretMigrator.CreateOrUpdateCatalogSecret("", password, nil) + if err != nil { + return nil, err + } + if secret != nil { + values.PutValue(data, secret.Name, catalogSecrets, catalogSecretKey) + data["password"] = "" + } + data, err = s.Store.Create(apiContext, schema, data) + if err != nil { + if secret != nil { + if cleanupErr := s.secretMigrator.Cleanup(secret.Name); cleanupErr != nil { + logrus.Errorf("catalog store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + return nil, err + } + if secret == nil { + return data, nil + } + var cluster *v3.Cluster + if clusterID, ok := data["clusterId"]; ok { + cluster, err = s.clusterLister.Get("", clusterID.(string)) + } else if projectID, ok := data["projectId"]; ok { + clusterID, _ := ref.Parse(projectID.(string)) + cluster, err = s.clusterLister.Get("", clusterID) + } + if err != nil { + return nil, err + } + var owner metav1.OwnerReference + if cluster != nil { + owner = metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Cluster", + Name: cluster.Name, + UID: cluster.UID, + } + } else { + owner = metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Catalog", + Name: data["id"].(string), + UID: k8sTypes.UID(data["uuid"].(string)), + } + } + err = s.secretMigrator.UpdateSecretOwnerReference(secret, owner) + if err != nil { + logrus.Errorf("catalog store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + return data, nil +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + isSystemCatalog, err := s.isSystemCatalog(apiContext, schema, id) + if err != nil { + return nil, err + } + if isSystemCatalog { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprint("not allowed to delete system-library catalog")) + } + existing, err := s.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + _, isCluster := existing["clusterId"] + _, isProject := existing["projectId"] + // global catalogs are owners of the secret so it will automatically be cleaned up + if isCluster || isProject { + if secretName, ok := values.GetValue(existing, catalogSecrets, catalogSecretKey); ok { + err := s.secretMigrator.Cleanup(secretName.(string)) + if err != nil { + return nil, err + } + } else if secretName, ok := existing[catalogSecretKey]; ok { + err := s.secretMigrator.Cleanup(secretName.(string)) + if err != nil { + return nil, err + } + } + } + return s.Store.Delete(apiContext, schema, id) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + isSystemCatalog, err := s.isSystemCatalog(apiContext, schema, id) + if err != nil { + return nil, err + } + if isSystemCatalog { + isRestrictedAdmin, err := s.isRestrictedAdmin(apiContext) + if err != nil { + return nil, err + } + if strings.ToLower(settings.SystemCatalog.Get()) == "bundled" || isRestrictedAdmin { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprint("not allowed to edit system-library catalog")) + } + } + existing, err := s.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + currentSecret := "" + if v, ok := values.GetValue(existing, catalogSecrets, catalogSecretKey); ok { + currentSecret = v.(string) + } else if v, ok = values.GetValue(existing, catalogSecretKey); ok { + currentSecret = v.(string) + } + password, _ := data["password"].(string) + secret, err := s.secretMigrator.CreateOrUpdateCatalogSecret(currentSecret, password, nil) + if err != nil { + return nil, err + } + if secret != nil { + values.PutValue(data, secret.Name, catalogSecrets, catalogSecretKey) + data["password"] = "" + } + data, err = s.Store.Update(apiContext, schema, data, id) + if err != nil { + if secret != nil && currentSecret == "" { + if cleanupErr := s.secretMigrator.Cleanup(secret.Name); cleanupErr != nil { + logrus.Errorf("catalog store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + } + if _, ok := existing[catalogSecretKey]; ok { + if s.catalogClient == nil { + return nil, fmt.Errorf("Error updating the catalog: k8s client is nil") + } + if clusterID, ok := data["clusterId"]; ok { + _, id = ref.Parse(id) + catalog, err := s.clusterCatalogClient.Namespace(clusterID.(string)).Get(context.Background(), id, metav1.GetOptions{}) + if err != nil { + return nil, err + } + values.RemoveValue(catalog.Object, "status", catalogSecretKey) + _, err = s.clusterCatalogClient.Namespace(clusterID.(string)).Update(context.Background(), catalog, metav1.UpdateOptions{}) + if err != nil { + return nil, err + } + } else if projectID, ok := data["projectId"]; ok { + _, prj := ref.Parse(projectID.(string)) + _, id = ref.Parse(id) + catalog, err := s.projectCatalogClient.Namespace(prj).Get(context.Background(), id, metav1.GetOptions{}) + if err != nil { + return nil, err + } + values.RemoveValue(catalog.Object, "status", catalogSecretKey) + _, err = s.projectCatalogClient.Namespace(prj).Update(context.Background(), catalog, metav1.UpdateOptions{}) + if err != nil { + return nil, err + } + } else { + catalog, err := s.catalogClient.Get(apiContext.Request.Context(), id, metav1.GetOptions{}) + if err != nil { + return nil, err + } + values.RemoveValue(catalog.Object, "status", catalogSecretKey) + _, err = s.catalogClient.Update(apiContext.Request.Context(), catalog, metav1.UpdateOptions{}) + if err != nil { + return nil, err + } + } + } + var cluster *v3.Cluster + if clusterID, ok := data["clusterId"]; ok { + cluster, err = s.clusterLister.Get("", clusterID.(string)) + } else if projectID, ok := data["projectId"]; ok { + clusterID, _ := ref.Parse(projectID.(string)) + cluster, err = s.clusterLister.Get("", clusterID) + } + if err != nil { + return nil, err + } + var owner metav1.OwnerReference + if cluster != nil { + owner = metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Cluster", + Name: cluster.Name, + UID: cluster.UID, + } + } else { + owner = metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Catalog", + Name: data["id"].(string), + UID: k8sTypes.UID(data["uuid"].(string)), + } + } + if secret != nil { + err = s.secretMigrator.UpdateSecretOwnerReference(secret, owner) + if err != nil { + logrus.Errorf("catalog store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + return data, err +} + +func (s *Store) isRestrictedAdmin(apiContext *types.APIContext) (bool, error) { + ma := gaccess.MemberAccess{ + Users: s.Users, + GrLister: s.GrLister, + GrbLister: s.GrbLister, + } + callerID := apiContext.Request.Header.Get(gaccess.ImpersonateUserHeader) + + return ma.IsRestrictedAdmin(callerID) +} + +// isSystemCatalog checks whether the catalog is the the system catalog maintained by rancher +func (s *Store) isSystemCatalog(apiContext *types.APIContext, schema *types.Schema, id string) (bool, error) { + catalog, err := s.ByID(apiContext, schema, id) + if err != nil { + return false, err + } + if catalog["url"] == c.SystemLibraryURL && catalog["name"] == c.SystemCatalogName { + return true, nil + } + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cert/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cert/store.go new file mode 100644 index 0000000..8a32986 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cert/store.go @@ -0,0 +1,66 @@ +package cert + +import ( + "time" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/cert" + client "github.com/rancher/rancher/pkg/client/generated/project/v3" +) + +func Wrap(store types.Store) types.Store { + return &Store{ + Store: store, + } +} + +type Store struct { + types.Store +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := AddCertInfo(data); err != nil { + return nil, err + } + + return s.Store.Create(apiContext, schema, data) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := AddCertInfo(data); err != nil { + return nil, err + } + + return s.Store.Update(apiContext, schema, data, id) +} + +func AddCertInfo(data map[string]interface{}) error { + certs, _ := data[client.CertificateFieldCerts].(string) + key, _ := data[client.CertificateFieldKey].(string) + + if certs == "" || key == "" { + return nil + } + + certInfo, err := cert.Info(certs, key) + if err != nil { + return httperror.NewFieldAPIError(httperror.InvalidBodyContent, "certs", err.Error()) + } + + certData, err := convert.EncodeToMap(certInfo) + if err != nil { + return err + } + + for k, v := range certData { + if t, ok := v.(time.Time); ok { + data[k] = convert.ToString(t) + } else { + data[k] = v + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_registration_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_registration_store.go new file mode 100644 index 0000000..7c9415d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_registration_store.go @@ -0,0 +1,22 @@ +package cluster + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/wrangler/v3/pkg/randomtoken" +) + +type RegistrationTokenStore struct { + types.Store +} + +func (r *RegistrationTokenStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if data != nil { + token, err := randomtoken.Generate() + if err != nil { + return nil, err + } + data["token"] = token + } + + return r.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_store.go new file mode 100644 index 0000000..0100f5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/cluster/cluster_store.go @@ -0,0 +1,1606 @@ +package cluster + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "reflect" + "regexp" + "strconv" + "strings" + "sync" + + "github.com/blang/semver" + mVersion "github.com/mcuadros/go-version" + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse/builder" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/definition" + "github.com/rancher/norman/types/slice" + "github.com/rancher/norman/types/values" + ccluster "github.com/rancher/rancher/pkg/api/norman/customization/cluster" + "github.com/rancher/rancher/pkg/api/norman/customization/clustertemplate" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + "github.com/rancher/rancher/pkg/controllers/management/clusterstatus" + "github.com/rancher/rancher/pkg/controllers/management/etcdbackup" + "github.com/rancher/rancher/pkg/controllers/management/rkeworkerupgrader" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/ref" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" + rkedefaults "github.com/rancher/rke/cluster" + "github.com/rancher/rke/k8s" + rkeservices "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + k8sTypes "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/dynamic" +) + +const ( + DefaultBackupIntervalHours = 12 + DefaultBackupRetention = 6 + s3TransportTimeout = 10 + clusterSecrets = "clusterSecrets" + registrySecretKey = "privateRegistrySecret" + s3SecretKey = "s3CredentialSecret" + weaveSecretKey = "weavePasswordSecret" + vsphereSecretKey = "vsphereSecret" + virtualCenterSecretKey = "virtualCenterSecret" + openStackSecretKey = "openStackSecret" + aadClientSecretKey = "aadClientSecret" + aadClientCertSecretKey = "aadClientCertSecret" + aciAPICUserKeySecretKey = "aciAPICUserKeySecret" + aciTokenSecretKey = "aciTokenSecret" + aciKafkaClientKeySecretKey = "aciKafkaClientKeySecret" + secretsEncryptionProvidersSecretKey = "secretsEncryptionProvidersSecret" + bastionHostSSHKeySecretKey = "bastionHostSSHKeySecret" + kubeletExtraEnvSecretKey = "kubeletExtraEnvSecret" + privateRegistryECRSecretKey = "privateRegistryECRSecret" + clusterCRIDockerdAnn = "io.cattle.cluster.cridockerd.enable" +) + +type Store struct { + types.Store + ShellHandler types.RequestHandler + mu sync.Mutex + KontainerDriverLister v3.KontainerDriverLister + ClusterTemplateLister v3.ClusterTemplateLister + ClusterTemplateRevisionLister v3.ClusterTemplateRevisionLister + NodeLister v3.NodeLister + ClusterLister v3.ClusterLister + DialerFactory dialer.Factory + ClusterClient dynamic.ResourceInterface + SecretClient v1.SecretInterface + SecretLister v1.SecretLister + secretMigrator *secretmigrator.Migrator +} + +type transformer struct { + KontainerDriverLister v3.KontainerDriverLister +} + +func (t *transformer) TransformerFunc(_ *types.APIContext, _ *types.Schema, data map[string]interface{}, _ *types.QueryOptions) (map[string]interface{}, error) { + data = transformSetNilSnapshotFalse(data) + return t.transposeGenericConfigToDynamicField(data) +} + +// transposeGenericConfigToDynamicField converts a genericConfig to one usable by rancher and maps a kontainer id to a kontainer name +func (t *transformer) transposeGenericConfigToDynamicField(data map[string]interface{}) (map[string]interface{}, error) { + if data["genericEngineConfig"] != nil { + drivers, err := t.KontainerDriverLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + + var driver *apimgmtv3.KontainerDriver + driverName := data["genericEngineConfig"].(map[string]interface{})[clusterprovisioner.DriverNameField].(string) + // iterate over kontainer drivers to find the one that maps to the genericEngineConfig DriverName ("kd-**") -> "example" + for _, candidate := range drivers { + if driverName == candidate.Name { + driver = candidate + break + } + } + if driver == nil { + logrus.Warnf("unable to find the kontainer driver %v that maps to %v", driverName, data[clusterprovisioner.DriverNameField]) + return data, nil + } + + var driverTypeName string + if driver.Spec.BuiltIn { + driverTypeName = driver.Status.DisplayName + "Config" + } else { + driverTypeName = driver.Status.DisplayName + "EngineConfig" + } + + data[driverTypeName] = data["genericEngineConfig"] + delete(data, "genericEngineConfig") + } + + return data, nil +} + +func GetClusterStore(schema *types.Schema, mgmt *config.ScaledContext, clusterManager *clustermanager.Manager, k8sProxy http.Handler) *Store { + + transformer := transformer{ + KontainerDriverLister: mgmt.Management.KontainerDrivers("").Controller().Lister(), + } + + t := &transform.Store{ + Store: schema.Store, + Transformer: transformer.TransformerFunc, + } + + linkHandler := &ccluster.ShellLinkHandler{ + Proxy: k8sProxy, + ClusterManager: clusterManager, + } + + s := &Store{ + Store: t, + KontainerDriverLister: mgmt.Management.KontainerDrivers("").Controller().Lister(), + ShellHandler: linkHandler.LinkHandler, + ClusterTemplateLister: mgmt.Management.ClusterTemplates("").Controller().Lister(), + ClusterTemplateRevisionLister: mgmt.Management.ClusterTemplateRevisions("").Controller().Lister(), + ClusterLister: mgmt.Management.Clusters("").Controller().Lister(), + NodeLister: mgmt.Management.Nodes("").Controller().Lister(), + DialerFactory: mgmt.Dialer, + SecretLister: mgmt.Core.Secrets("").Controller().Lister(), + secretMigrator: secretmigrator.NewMigrator( + mgmt.Core.Secrets("").Controller().Lister(), + mgmt.Core.Secrets(""), + ), + } + + dynamicClient, err := dynamic.NewForConfig(&mgmt.RESTConfig) + if err != nil { + logrus.Warnf("GetClusterStore error creating K8s dynamic client: %v", err) + } else { + s.ClusterClient = dynamicClient.Resource(v3.ClusterGroupVersionResource) + } + + schema.Store = s + return s +} + +func transformSetNilSnapshotFalse(data map[string]interface{}) map[string]interface{} { + var ( + etcd interface{} + found bool + ) + + etcd, found = values.GetValue(data, "appliedSpec", "rancherKubernetesEngineConfig", "services", "etcd") + if found { + etcd := convert.ToMapInterface(etcd) + val, found := values.GetValue(etcd, "snapshot") + if !found || val == nil { + values.PutValue(data, false, "appliedSpec", "rancherKubernetesEngineConfig", "services", "etcd", "snapshot") + } + } + + etcd, found = values.GetValue(data, "rancherKubernetesEngineConfig", "services", "etcd") + if found { + etcd := convert.ToMapInterface(etcd) + val, found := values.GetValue(etcd, "snapshot") + if !found || val == nil { + values.PutValue(data, false, "rancherKubernetesEngineConfig", "services", "etcd", "snapshot") + } + } + + return data +} + +func (r *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + // Really we want a link handler but the URL parse makes it impossible to add links to clusters for now. So this + // is basically a hack + if apiContext.Query.Get("shell") == "true" { + return nil, r.ShellHandler(apiContext, nil) + } + + return r.Store.ByID(apiContext, schema, id) +} + +type secrets struct { + regSecret *corev1.Secret + s3Secret *corev1.Secret + weaveSecret *corev1.Secret + vsphereSecret *corev1.Secret + vcenterSecret *corev1.Secret + openStackSecret *corev1.Secret + aadClientSecret *corev1.Secret + aadCertSecret *corev1.Secret + aciAPICUserKeySecret *corev1.Secret + aciTokenSecret *corev1.Secret + aciKafkaClientKeySecret *corev1.Secret + secretsEncryptionProvidersSecret *corev1.Secret + bastionHostSSHKeySecret *corev1.Secret + kubeletExtraEnvSecret *corev1.Secret + privateRegistryECRSecret *corev1.Secret +} + +func (r *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + name := convert.ToString(data["name"]) + if name == "" { + return nil, httperror.NewFieldAPIError(httperror.MissingRequired, "Cluster name", "") + } + + r.mu.Lock() + defer r.mu.Unlock() + + if err := canUseClusterName(apiContext, name); err != nil { + return nil, err + } + + // check if template is passed. if yes, load template data + if hasTemplate(data) { + clusterTemplateRevision, clusterTemplate, err := r.validateTemplateInput(apiContext, data, false) + if err != nil { + return nil, err + } + clusterConfigSchema := apiContext.Schemas.Schema(&managementschema.Version, managementv3.ClusterSpecBaseType) + data, err = loadDataFromTemplate(clusterTemplateRevision, clusterTemplate, data, clusterConfigSchema, nil, r.SecretLister) + if err != nil { + return nil, err + } + data = cleanQuestions(data) + } + + err := setKubernetesVersion(data, true) + if err != nil { + return nil, err + } + enableCRIDockerd(data) + setInstanceMetadataHostname(data) + // enable local backups for rke clusters by default + enableLocalBackup(data) + if err := setNodeUpgradeStrategy(data, nil); err != nil { + return nil, err + } + + data, err = r.transposeDynamicFieldToGenericConfig(data) + if err != nil { + return nil, err + } + + if err := validateNetworkFlag(data, true); err != nil { + return nil, httperror.NewFieldAPIError(httperror.InvalidOption, "enableNetworkPolicy", err.Error()) + } + + if driverName, _ := values.GetValue(data, "genericEngineConfig", "driverName"); driverName == "amazonelasticcontainerservice" { + sessionToken, _ := values.GetValue(data, "genericEngineConfig", "sessionToken") + annotation, _ := values.GetValue(data, managementv3.ClusterFieldAnnotations) + m := toMap(annotation) + m[clusterstatus.TemporaryCredentialsAnnotationKey] = strconv.FormatBool( + sessionToken != "" && sessionToken != nil) + values.PutValue(data, m, managementv3.ClusterFieldAnnotations) + } + + if err = setInitialConditions(data); err != nil { + return nil, err + } + if err = validateS3Credentials(data, nil); err != nil { + return nil, err + } + if err = validateKeyRotation(data); err != nil { + return nil, err + } + cleanPrivateRegistry(data) + + allSecrets, err := r.migrateSecrets(apiContext.Request.Context(), data, nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") + + if err != nil { + return nil, err + } + + data, err = r.Store.Create(apiContext, schema, data) + if err != nil { + cleanup := func(secret *corev1.Secret) { + if secret != nil { + if cleanupErr := r.secretMigrator.Cleanup(secret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + } + + cleanup(allSecrets.regSecret) + cleanup(allSecrets.s3Secret) + cleanup(allSecrets.weaveSecret) + cleanup(allSecrets.vsphereSecret) + cleanup(allSecrets.vcenterSecret) + cleanup(allSecrets.openStackSecret) + cleanup(allSecrets.aadClientSecret) + cleanup(allSecrets.aadCertSecret) + cleanup(allSecrets.aciAPICUserKeySecret) + cleanup(allSecrets.aciTokenSecret) + cleanup(allSecrets.aciKafkaClientKeySecret) + cleanup(allSecrets.secretsEncryptionProvidersSecret) + cleanup(allSecrets.bastionHostSSHKeySecret) + cleanup(allSecrets.kubeletExtraEnvSecret) + cleanup(allSecrets.privateRegistryECRSecret) + + return nil, err + } + owner := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Cluster", + Name: data["id"].(string), + UID: k8sTypes.UID(data["uuid"].(string)), + } + errMsg := fmt.Sprintf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + updateOwner := func(secret *corev1.Secret) { + if secret != nil { + err = r.secretMigrator.UpdateSecretOwnerReference(secret, owner) + if err != nil { + logrus.Errorf(errMsg) + } + } + } + + updateOwner(allSecrets.regSecret) + updateOwner(allSecrets.s3Secret) + updateOwner(allSecrets.weaveSecret) + updateOwner(allSecrets.vsphereSecret) + updateOwner(allSecrets.vcenterSecret) + updateOwner(allSecrets.openStackSecret) + updateOwner(allSecrets.aadClientSecret) + updateOwner(allSecrets.aadCertSecret) + updateOwner(allSecrets.aciAPICUserKeySecret) + updateOwner(allSecrets.aciTokenSecret) + updateOwner(allSecrets.aciKafkaClientKeySecret) + updateOwner(allSecrets.secretsEncryptionProvidersSecret) + updateOwner(allSecrets.bastionHostSSHKeySecret) + updateOwner(allSecrets.kubeletExtraEnvSecret) + updateOwner(allSecrets.privateRegistryECRSecret) + + return data, nil +} + +func transposeNameFields(data map[string]interface{}, clusterConfigSchema *types.Schema) map[string]interface{} { + + if clusterConfigSchema != nil { + for fieldName, field := range clusterConfigSchema.ResourceFields { + + if definition.IsReferenceType(field.Type) && strings.HasSuffix(fieldName, "Id") { + dataKeyName := strings.TrimSuffix(fieldName, "Id") + "Name" + data[fieldName] = data[dataKeyName] + delete(data, dataKeyName) + } + } + } + return data +} + +func loadDataFromTemplate(clusterTemplateRevision *apimgmtv3.ClusterTemplateRevision, clusterTemplate *apimgmtv3.ClusterTemplate, data map[string]interface{}, clusterConfigSchema *types.Schema, existingCluster map[string]interface{}, secretLister v1.SecretLister) (map[string]interface{}, error) { + clusterConfig := *clusterTemplateRevision.Spec.ClusterConfig + clusterConfigSpec, err := assemblers.AssembleRKEConfigTemplateSpec(clusterTemplateRevision, apimgmtv3.ClusterSpec{ClusterSpecBase: clusterConfig}, secretLister) + if err != nil { + return nil, err + } + dataFromTemplate, err := convert.EncodeToMap(clusterConfigSpec) + if err != nil { + return nil, err + } + dataFromTemplate["name"] = convert.ToString(data["name"]) + dataFromTemplate["description"] = convert.ToString(data[managementv3.ClusterSpecFieldDisplayName]) + dataFromTemplate[managementv3.ClusterSpecFieldClusterTemplateID] = ref.Ref(clusterTemplate) + dataFromTemplate[managementv3.ClusterSpecFieldClusterTemplateRevisionID] = convert.ToString(data[managementv3.ClusterSpecFieldClusterTemplateRevisionID]) + + dataFromTemplate = transposeNameFields(dataFromTemplate, clusterConfigSchema) + var revisionQuestions []map[string]interface{} + // Add in any answers to the clusterTemplateRevision's Questions[] + allAnswers := convert.ToMapInterface(convert.ToMapInterface(data[managementv3.ClusterSpecFieldClusterTemplateAnswers])["values"]) + existingAnswers := convert.ToMapInterface(convert.ToMapInterface(existingCluster[managementv3.ClusterSpecFieldClusterTemplateAnswers])["values"]) + + defaultedAnswers := make(map[string]string) + + // The key in the map is used to preserve the order of registries + registryMap := make(map[int]map[string]interface{}) + existingRegistries := convert.ToMapSlice(convert.ToMapInterface(existingCluster[managementv3.ClusterSpecFieldRancherKubernetesEngineConfig])[managementv3.RancherKubernetesEngineConfigFieldPrivateRegistries]) + privateRegistryOverride := false + for i, registry := range existingRegistries { + registryMap[i] = registry + } + processingError := "Error processing clusterTemplate answers" + for _, question := range clusterTemplateRevision.Spec.Questions { + if question.Default == "" { + if secretmigrator.MatchesQuestionPath(question.Variable) { + if strings.HasPrefix(question.Variable, "rancherKubernetesEngineConfig.privateRegistries") { + + registries, ok := values.GetSlice(dataFromTemplate, "rancherKubernetesEngineConfig", "privateRegistries") + if !ok { + return nil, httperror.WrapAPIError(err, httperror.ServerError, processingError) + } + index, err := getIndexFromQuestion(question.Variable) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, processingError) + } + // the key may not exist if the password is not set in the clusterTemplateRevision + password, ok := registries[index]["password"] + if ok { + question.Default = password.(string) + } + } else if strings.HasPrefix(question.Variable, "rancherKubernetesEngineConfig.cloudProvider.vsphereCloudProvider.virtualCenter") { + vcenters, ok := values.GetValue(dataFromTemplate, "rancherKubernetesEngineConfig", "cloudProvider", "vsphereCloudProvider", "virtualCenter") + if !ok { + return nil, httperror.WrapAPIError(err, httperror.ServerError, processingError) + } + key, err := getKeyFromQuestion(question.Variable) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, processingError) + } + question.Default = vcenters.(map[string]interface{})[key].(map[string]interface{})["password"].(string) + + } else { + keyParts := strings.Split(question.Variable, ".") + qDefault, ok := values.GetValue(dataFromTemplate, keyParts...) + if ok { + question.Default = qDefault.(string) + } + } + } + } + answer, ok := allAnswers[question.Variable] + if !ok { + if question.Required && question.Default == "" { + return nil, httperror.WrapAPIError(err, httperror.MissingRequired, fmt.Sprintf("Missing answer for a required clusterTemplate question: %v", question.Variable)) + } + answer = question.Default + defaultedAnswers[question.Variable] = question.Default + } + if existingCluster != nil && strings.EqualFold(question.Variable, "rancherKubernetesEngineConfig.kubernetesVersion") { + if convert.ToString(answer) == convert.ToString(existingAnswers[question.Variable]) { + answer = values.GetValueN(existingCluster, "rancherKubernetesEngineConfig", "kubernetesVersion") + } + } + val, err := builder.ConvertSimple(question.Type, answer, builder.Create) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, processingError) + } + keyParts := strings.Split(question.Variable, ".") + if strings.HasPrefix(question.Variable, "rancherKubernetesEngineConfig.privateRegistries") { + privateRegistryOverride = true + // for example: question.Variable = rancherKubernetesEngineConfig.privateRegistries[0].url + index, err := getIndexFromQuestion(question.Variable) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, "Error processing clusterTemplate answers to private registry") + } + key := keyParts[len(keyParts)-1] + if _, ok := registryMap[index]; ok { + registryMap[index][key] = val + } else { + registryMap[index] = map[string]interface{}{ + key: val, + } + } + } else { + values.PutValue(dataFromTemplate, val, keyParts...) + } + + questionMap, err := convert.EncodeToMap(question) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, "Error reading clusterTemplate questions") + } + revisionQuestions = append(revisionQuestions, questionMap) + } + if len(registryMap) > 0 && privateRegistryOverride { + registries, err := convertRegistryMapToSliceInOrder(registryMap) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.ServerError, "Error processing clusterTemplate answers to private registry") + } + // save privateRegistries back to rancherKubernetesEngineConfig + values.PutValue(dataFromTemplate, registries, managementv3.ClusterSpecFieldRancherKubernetesEngineConfig, managementv3.RancherKubernetesEngineConfigFieldPrivateRegistries) + } + // save defaultAnswers to answer + if allAnswers == nil { + allAnswers = make(map[string]interface{}) + } + for key, val := range defaultedAnswers { + allAnswers[key] = val + } + + finalAnswerMap := make(map[string]interface{}) + finalAnswerMap["values"] = allAnswers + dataFromTemplate[managementv3.ClusterSpecFieldClusterTemplateAnswers] = finalAnswerMap + dataFromTemplate[managementv3.ClusterSpecFieldClusterTemplateQuestions] = revisionQuestions + + dataFromTemplate[managementv3.ClusterSpecFieldDescription] = convert.ToString(data[managementv3.ClusterSpecFieldDescription]) + + annotations, ok := data[managementv3.MetadataUpdateFieldAnnotations] + if ok { + dataFromTemplate[managementv3.MetadataUpdateFieldAnnotations] = convert.ToMapInterface(annotations) + } + + labels, ok := data[managementv3.MetadataUpdateFieldLabels] + if ok { + dataFromTemplate[managementv3.MetadataUpdateFieldLabels] = convert.ToMapInterface(labels) + } + + // make sure fleetworkspace is copied over + fleetworkspace, ok := data[managementv3.ClusterFieldFleetWorkspaceName] + if ok { + dataFromTemplate[managementv3.ClusterFieldFleetWorkspaceName] = fleetworkspace + } + + // validate that the data loaded is valid clusterSpec + var spec apimgmtv3.ClusterSpec + if err := convert.ToObj(dataFromTemplate, &spec); err != nil { + return nil, httperror.WrapAPIError(err, httperror.InvalidBodyContent, "Invalid clusterTemplate, cannot convert to cluster spec") + } + + return dataFromTemplate, nil +} + +func convertRegistryMapToSliceInOrder(registryMap map[int]map[string]interface{}) ([]map[string]interface{}, error) { + size := len(registryMap) + registries := make([]map[string]interface{}, size) + for k, v := range registryMap { + if k >= size { + return nil, fmt.Errorf("the index %d is out of the bound of the registry list (size of %d)", k, size) + } + registries[k] = v + registries[k][managementv3.PrivateRegistryFieldIsDefault] = false + } + // set the first registry in the list as the default registry if it exists + if len(registries) > 0 { + registries[0][managementv3.PrivateRegistryFieldIsDefault] = true + } + return registries, nil +} + +func getIndexFromQuestion(question string) (int, error) { + re, err := regexp.Compile(`\[\d+\]`) + if err != nil { + return 0, err + } + target := re.FindString(question) + if target == "" { + return 0, fmt.Errorf("cannot get index from the question: %s", question) + } + return strconv.Atoi(target[1 : len(target)-1]) +} + +func getKeyFromQuestion(question string) (string, error) { + re, err := regexp.Compile(`\[.+\]`) + if err != nil { + return "", err + } + target := re.FindString(question) + if target == "" { + return "", fmt.Errorf("cannot get key from the question: %s", question) + } + return target[1 : len(target)-1], nil +} + +func hasTemplate(data map[string]interface{}) bool { + templateRevID := convert.ToString(data[managementv3.ClusterSpecFieldClusterTemplateRevisionID]) + if templateRevID != "" { + return true + } + return false +} + +func (r *Store) validateTemplateInput(apiContext *types.APIContext, data map[string]interface{}, isUpdate bool) (*apimgmtv3.ClusterTemplateRevision, *apimgmtv3.ClusterTemplate, error) { + if !isUpdate { + // if data also has rkeconfig, error out on create + rkeConfig, ok := values.GetValue(data, "rancherKubernetesEngineConfig") + if ok && rkeConfig != nil { + return nil, nil, fmt.Errorf("cannot set rancherKubernetesEngineConfig and clusterTemplateRevision both") + } + } + + var templateID, templateRevID string + + templateRevIDStr := convert.ToString(data[managementv3.ClusterSpecFieldClusterTemplateRevisionID]) + var clusterTemplateRev managementv3.ClusterTemplateRevision + + // access check. + if err := access.ByID(apiContext, apiContext.Version, managementv3.ClusterTemplateRevisionType, templateRevIDStr, &clusterTemplateRev); err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status { + return nil, nil, httperror.NewAPIError(httperror.NotFound, "The clusterTemplateRevision is not found") + } + } + return nil, nil, err + } + + splitID := strings.Split(templateRevIDStr, ":") + if len(splitID) == 2 { + templateRevID = splitID[1] + } + + clusterTemplateRevision, err := r.ClusterTemplateRevisionLister.Get(namespace.GlobalNamespace, templateRevID) + if err != nil { + return nil, nil, err + } + + if clusterTemplateRevision.Spec.Enabled != nil && !(*clusterTemplateRevision.Spec.Enabled) { + return nil, nil, fmt.Errorf("cannot create cluster, clusterTemplateRevision is disabled") + } + + templateIDStr := clusterTemplateRevision.Spec.ClusterTemplateName + splitID = strings.Split(templateIDStr, ":") + if len(splitID) == 2 { + templateID = splitID[1] + } + + clusterTemplate, err := r.ClusterTemplateLister.Get(namespace.GlobalNamespace, templateID) + if err != nil { + return nil, nil, err + } + + return clusterTemplateRevision, clusterTemplate, nil + +} + +func setInitialConditions(data map[string]interface{}) error { + if data[managementv3.ClusterStatusFieldConditions] == nil { + data[managementv3.ClusterStatusFieldConditions] = []map[string]interface{}{} + } + + conditions, ok := data[managementv3.ClusterStatusFieldConditions].([]map[string]interface{}) + if !ok { + return fmt.Errorf("unable to parse field \"%v\" type \"%v\" as \"[]map[string]interface{}\"", + managementv3.ClusterStatusFieldConditions, reflect.TypeOf(data[managementv3.ClusterStatusFieldConditions])) + } + for key := range data { + if strings.Index(key, "Config") == len(key)-6 { + data[managementv3.ClusterStatusFieldConditions] = + append( + conditions, + []map[string]interface{}{ + { + "status": "True", + "type": string(apimgmtv3.ClusterConditionPending), + }, + { + "status": "Unknown", + "type": string(apimgmtv3.ClusterConditionProvisioned), + }, + { + "status": "Unknown", + "type": string(apimgmtv3.ClusterConditionWaiting), + }, + }..., + ) + } + } + + return nil +} + +func toMap(rawMap interface{}) map[string]interface{} { + if theMap, ok := rawMap.(map[string]interface{}); ok { + return theMap + } + + return make(map[string]interface{}) +} + +func (r *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + updatedName := convert.ToString(data["name"]) + if updatedName == "" { + return nil, httperror.NewFieldAPIError(httperror.MissingRequired, "Cluster name", "") + } + + existingCluster, err := r.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + + clusterName, ok := existingCluster["name"].(string) + if !ok { + clusterName = "" + } + + if !strings.EqualFold(updatedName, clusterName) { + r.mu.Lock() + defer r.mu.Unlock() + + if err := canUseClusterName(apiContext, updatedName); err != nil { + return nil, err + } + } + + // check if template is passed. if yes, load template data + if hasTemplate(data) { + if existingCluster[managementv3.ClusterSpecFieldClusterTemplateRevisionID] == "" { + return nil, httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("this cluster is not created using a clusterTemplate, cannot update it to use a clusterTemplate now")) + } + + clusterTemplateRevision, clusterTemplate, err := r.validateTemplateInput(apiContext, data, true) + if err != nil { + return nil, err + } + + updatedTemplateID := clusterTemplateRevision.Spec.ClusterTemplateName + templateID := convert.ToString(existingCluster[managementv3.ClusterSpecFieldClusterTemplateID]) + + if !strings.EqualFold(updatedTemplateID, templateID) { + return nil, httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("cannot update cluster, cluster cannot be changed to a new clusterTemplate")) + } + + clusterConfigSchema := apiContext.Schemas.Schema(&managementschema.Version, managementv3.ClusterSpecBaseType) + clusterUpdate, err := loadDataFromTemplate(clusterTemplateRevision, clusterTemplate, data, clusterConfigSchema, existingCluster, r.SecretLister) + if err != nil { + return nil, err + } + clusterUpdate = cleanQuestions(clusterUpdate) + + data = clusterUpdate + + } else if existingCluster[managementv3.ClusterSpecFieldClusterTemplateRevisionID] != nil { + return nil, httperror.NewFieldAPIError(httperror.MissingRequired, "ClusterTemplateRevision", "this cluster is created from a clusterTemplateRevision, please pass the clusterTemplateRevision") + } + + err = setKubernetesVersion(data, false) + if err != nil { + return nil, err + } + enableCRIDockerd(data) + setInstanceMetadataHostname(data) + if err := setNodeUpgradeStrategy(data, existingCluster); err != nil { + return nil, err + } + data, err = r.transposeDynamicFieldToGenericConfig(data) + if err != nil { + return nil, err + } + + if err := validateNetworkFlag(data, false); err != nil { + return nil, httperror.NewFieldAPIError(httperror.InvalidOption, "enableNetworkPolicy", err.Error()) + } + + cleanPrivateRegistry(data) + dialer, err := r.DialerFactory.ClusterDialer(id, true) + if err != nil { + return nil, errors.Wrap(err, "error getting dialer") + } + if err := validateUpdatedS3Credentials(existingCluster, data, dialer); err != nil { + return nil, err + } + if err := validateKeyRotation(data); err != nil { + return nil, err + } + if err := r.validateUnavailableNodes(data, existingCluster, id); err != nil { + return nil, err + } + + // When any rancherKubernetesEngineConfig.cloudProvider.vsphereCloudProvider.virtualCenter has been removed, updating cluster using k8s dynamic client to properly + // replace cluster spec. This is required due to r.Store.Update is merging this data instead of replacing it, https://github.com/rancher/rancher/issues/27306 + if newVCenter, ok := values.GetValue(data, "rancherKubernetesEngineConfig", "cloudProvider", "vsphereCloudProvider", "virtualCenter"); ok && newVCenter != nil { + if oldVCenter, ok := values.GetValue(existingCluster, "rancherKubernetesEngineConfig", "cloudProvider", "vsphereCloudProvider", "virtualCenter"); ok && oldVCenter != nil { + if oldVCenterMap, oldOk := oldVCenter.(map[string]interface{}); oldOk && oldVCenterMap != nil { + if newVCenterMap, newOk := newVCenter.(map[string]interface{}); newOk && newVCenterMap != nil { + for k := range oldVCenterMap { + if _, ok := newVCenterMap[k]; !ok && oldVCenterMap[k] != nil { + return r.updateClusterByK8sclient(apiContext.Request.Context(), id, updatedName, data) + } + } + } + } + } + } + + getSecretByKey := func(key string) string { + if v, ok := values.GetValue(existingCluster, clusterSecrets, key); ok && v.(string) != "" { + return v.(string) + } + if v, ok := values.GetValue(existingCluster, key); ok { + return v.(string) + } + return "" + } + currentRegSecret := getSecretByKey(registrySecretKey) + currentS3Secret := getSecretByKey(s3SecretKey) + currentWeaveSecret := getSecretByKey(weaveSecretKey) + currentVsphereSecret := getSecretByKey(vsphereSecretKey) + currentVcenterSecret := getSecretByKey(virtualCenterSecretKey) + currentOpenStackSecret := getSecretByKey(openStackSecretKey) + currentAADClientSecret := getSecretByKey(aadClientSecretKey) + currentAADCertSecret := getSecretByKey(aadClientCertSecretKey) + currentACIAPICUserKeySecret := getSecretByKey(aciAPICUserKeySecretKey) + currentACITokenSecret := getSecretByKey(aciTokenSecretKey) + currentACIKafkaClientKeySecret := getSecretByKey(aciKafkaClientKeySecretKey) + currentSecretsEncryptionProvidersSecret := getSecretByKey(secretsEncryptionProvidersSecretKey) + currentBastionHostSSHSecret := getSecretByKey(bastionHostSSHKeySecretKey) + currentKubeletExtraEnvSecret := getSecretByKey(kubeletExtraEnvSecretKey) + currentPrivateRegistryECRSecret := getSecretByKey(privateRegistryECRSecretKey) + allSecrets, err := r.migrateSecrets(apiContext.Request.Context(), data, existingCluster, + currentRegSecret, + currentS3Secret, + currentWeaveSecret, + currentVsphereSecret, + currentVcenterSecret, + currentOpenStackSecret, + currentAADClientSecret, + currentAADCertSecret, + currentACIAPICUserKeySecret, + currentACITokenSecret, + currentACIKafkaClientKeySecret, + currentSecretsEncryptionProvidersSecret, + currentBastionHostSSHSecret, + currentKubeletExtraEnvSecret, + currentPrivateRegistryECRSecret) + + if err != nil { + return nil, err + } + data, err = r.Store.Update(apiContext, schema, data, id) + if err != nil { + cleanup := func(secret *corev1.Secret, current string) { + if secret != nil && current == "" { + if cleanupErr := r.secretMigrator.Cleanup(secret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + } + + cleanup(allSecrets.regSecret, currentRegSecret) + cleanup(allSecrets.s3Secret, currentS3Secret) + cleanup(allSecrets.weaveSecret, currentWeaveSecret) + cleanup(allSecrets.vsphereSecret, currentVsphereSecret) + cleanup(allSecrets.vcenterSecret, currentVcenterSecret) + cleanup(allSecrets.openStackSecret, currentOpenStackSecret) + cleanup(allSecrets.aadClientSecret, currentAADClientSecret) + cleanup(allSecrets.aadCertSecret, currentAADCertSecret) + cleanup(allSecrets.aciAPICUserKeySecret, currentACIAPICUserKeySecret) + cleanup(allSecrets.aciTokenSecret, currentACITokenSecret) + cleanup(allSecrets.aciKafkaClientKeySecret, currentACIKafkaClientKeySecret) + cleanup(allSecrets.secretsEncryptionProvidersSecret, currentSecretsEncryptionProvidersSecret) + cleanup(allSecrets.bastionHostSSHKeySecret, currentBastionHostSSHSecret) + cleanup(allSecrets.kubeletExtraEnvSecret, currentKubeletExtraEnvSecret) + cleanup(allSecrets.privateRegistryECRSecret, currentPrivateRegistryECRSecret) + + return nil, err + } + if allSecrets.regSecret != nil || allSecrets.s3Secret != nil || allSecrets.weaveSecret != nil || allSecrets.vsphereSecret != nil || allSecrets.vcenterSecret != nil || allSecrets.openStackSecret != nil || allSecrets.aadClientSecret != nil || allSecrets.aadCertSecret != nil || allSecrets.secretsEncryptionProvidersSecret != nil { + if r.ClusterClient == nil { + return nil, fmt.Errorf("Error updating the cluster: k8s client is nil") + } + cluster, err := r.ClusterClient.Get(apiContext.Request.Context(), existingCluster["id"].(string), metav1.GetOptions{}) + if err != nil { + return nil, err + } + removeFromStatus := func(secret *corev1.Secret, key string) { + if secret != nil { + if _, ok := existingCluster[key]; ok { + values.RemoveValue(cluster.Object, "status", key) + } + } + } + removeFromStatus(allSecrets.regSecret, registrySecretKey) + removeFromStatus(allSecrets.s3Secret, s3SecretKey) + removeFromStatus(allSecrets.weaveSecret, weaveSecretKey) + removeFromStatus(allSecrets.vsphereSecret, vsphereSecretKey) + removeFromStatus(allSecrets.vcenterSecret, virtualCenterSecretKey) + removeFromStatus(allSecrets.openStackSecret, openStackSecretKey) + removeFromStatus(allSecrets.aadClientSecret, aadClientSecretKey) + removeFromStatus(allSecrets.aadCertSecret, aadClientCertSecretKey) + + _, err = r.ClusterClient.Update(apiContext.Request.Context(), cluster, metav1.UpdateOptions{}) + if err != nil { + return nil, err + } + } + owner := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "Cluster", + Name: data["id"].(string), + UID: k8sTypes.UID(data["uuid"].(string)), + } + errMsg := fmt.Sprintf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + updateOwner := func(secret *corev1.Secret) { + if secret != nil { + err = r.secretMigrator.UpdateSecretOwnerReference(secret, owner) + if err != nil { + logrus.Errorf(errMsg) + } + } + } + + updateOwner(allSecrets.regSecret) + updateOwner(allSecrets.s3Secret) + updateOwner(allSecrets.weaveSecret) + updateOwner(allSecrets.vsphereSecret) + updateOwner(allSecrets.vcenterSecret) + updateOwner(allSecrets.openStackSecret) + updateOwner(allSecrets.aadClientSecret) + updateOwner(allSecrets.aadCertSecret) + updateOwner(allSecrets.aciAPICUserKeySecret) + updateOwner(allSecrets.aciTokenSecret) + updateOwner(allSecrets.aciKafkaClientKeySecret) + updateOwner(allSecrets.secretsEncryptionProvidersSecret) + updateOwner(allSecrets.bastionHostSSHKeySecret) + updateOwner(allSecrets.kubeletExtraEnvSecret) + updateOwner(allSecrets.privateRegistryECRSecret) + return data, err +} + +// this method moves the cluster config to and from the genericEngineConfig field so that +// the kontainer drivers behave similarly to the existing machine drivers +func (r *Store) transposeDynamicFieldToGenericConfig(data map[string]interface{}) (map[string]interface{}, error) { + dynamicField, err := r.getDynamicField(data) + if err != nil { + return nil, fmt.Errorf("error getting kontainer drivers: %v", err) + } + + // No dynamic schema field exists on this cluster so return immediately + if dynamicField == "" { + return data, nil + } + + // overwrite generic engine config so it gets saved + data["genericEngineConfig"] = data[dynamicField] + delete(data, dynamicField) + + return data, nil +} + +func (r *Store) getDynamicField(data map[string]interface{}) (string, error) { + drivers, err := r.KontainerDriverLister.List("", labels.Everything()) + if err != nil { + return "", err + } + + for _, driver := range drivers { + var driverName string + if driver.Spec.BuiltIn { + driverName = driver.Status.DisplayName + "Config" + } else { + driverName = driver.Status.DisplayName + "EngineConfig" + } + + if data[driverName] != nil { + if !(driver.Status.DisplayName == "rancherKubernetesEngine" || driver.Status.DisplayName == "import") { + return driverName, nil + } + } + } + + return "", nil +} + +func (r *Store) updateClusterByK8sclient(ctx context.Context, id, name string, data map[string]interface{}) (map[string]interface{}, error) { + logrus.Tracef("Updating cluster [%s] using K8s dynamic client", id) + if r.ClusterClient == nil { + return nil, fmt.Errorf("Error updating the cluster: k8s client is nil") + } + + object, err := r.ClusterClient.Get(ctx, id, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("Error updating the cluster: %v", err) + } + + // Replacing name by displayName to properly update cluster using k8s format + values.PutValue(data, name, "displayName") + values.RemoveValue(data, "name") + + // Setting data as cluster spec before update + object.Object["spec"] = data + object, err = r.ClusterClient.Update(ctx, object, metav1.UpdateOptions{}) + if err != nil || object == nil { + return nil, fmt.Errorf("Error updating the cluster: %v", err) + } + + // Replacing displayName by name to properly return updated data using API format + values.PutValue(object.Object, name, "spec", "name") + values.RemoveValue(object.Object, "spec", "displayName") + + return object.Object["spec"].(map[string]interface{}), nil +} + +func (r *Store) migrateSecrets(ctx context.Context, data, existingCluster map[string]interface{}, currentReg, currentS3, currentWeave, currentVsphere, currentVCenter, currentOpenStack, currentAADClientSecret, currentAADCert, currentACIAPICUserKey, currentACIToken, currentACIKafkaClientKey, currentSecretsEncryptionProviders, currentbastionHostSSHKeySecret, currentKubeletExtraEnvSecret, currentPrivateRegistryECRSecret string) (secrets, error) { + rkeConfig, err := getRkeConfig(data) + if err != nil || rkeConfig == nil { + return secrets{}, err + } + var s secrets + s.regSecret, err = r.secretMigrator.CreateOrUpdatePrivateRegistrySecret(currentReg, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.regSecret != nil { + values.PutValue(data, s.regSecret.Name, clusterSecrets, registrySecretKey) + rkeConfig.PrivateRegistries = secretmigrator.CleanRegistries(rkeConfig.PrivateRegistries) + } + s.s3Secret, err = r.secretMigrator.CreateOrUpdateS3Secret(currentS3, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.s3Secret != nil { + values.PutValue(data, s.s3Secret.Name, clusterSecrets, s3SecretKey) + rkeConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey = "" + } + s.weaveSecret, err = r.secretMigrator.CreateOrUpdateWeaveSecret(currentWeave, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.weaveSecret != nil { + values.PutValue(data, s.weaveSecret.Name, clusterSecrets, weaveSecretKey) + rkeConfig.Network.WeaveNetworkProvider.Password = "" + } + s.vsphereSecret, err = r.secretMigrator.CreateOrUpdateVsphereGlobalSecret(currentVsphere, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.vsphereSecret != nil { + values.PutValue(data, s.vsphereSecret.Name, clusterSecrets, vsphereSecretKey) + rkeConfig.CloudProvider.VsphereCloudProvider.Global.Password = "" + } + s.vcenterSecret, err = r.secretMigrator.CreateOrUpdateVsphereVirtualCenterSecret(currentVCenter, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.vcenterSecret != nil { + values.PutValue(data, s.vcenterSecret.Name, clusterSecrets, virtualCenterSecretKey) + for k, v := range rkeConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + v.Password = "" + rkeConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] = v + } + } + s.openStackSecret, err = r.secretMigrator.CreateOrUpdateOpenStackSecret(currentOpenStack, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.openStackSecret != nil { + values.PutValue(data, s.openStackSecret.Name, clusterSecrets, openStackSecretKey) + rkeConfig.CloudProvider.OpenstackCloudProvider.Global.Password = "" + } + s.aadClientSecret, err = r.secretMigrator.CreateOrUpdateAADClientSecret(currentAADClientSecret, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aadClientSecret != nil { + values.PutValue(data, s.aadClientSecret.Name, clusterSecrets, aadClientSecretKey) + rkeConfig.CloudProvider.AzureCloudProvider.AADClientSecret = "" + } + s.aadCertSecret, err = r.secretMigrator.CreateOrUpdateAADCertSecret(currentAADCert, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aadCertSecret != nil { + values.PutValue(data, s.aadCertSecret.Name, clusterSecrets, aadClientCertSecretKey) + rkeConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword = "" + } + s.aciAPICUserKeySecret, err = r.secretMigrator.CreateOrUpdateACIAPICUserKeySecret(currentACIAPICUserKey, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciAPICUserKeySecret != nil { + values.PutValue(data, s.aciAPICUserKeySecret.Name, clusterSecrets, aciAPICUserKeySecretKey) + rkeConfig.Network.AciNetworkProvider.ApicUserKey = "" + } + s.aciTokenSecret, err = r.secretMigrator.CreateOrUpdateACITokenSecret(currentACIToken, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciTokenSecret != nil { + values.PutValue(data, s.aciTokenSecret.Name, clusterSecrets, aciTokenSecretKey) + rkeConfig.Network.AciNetworkProvider.Token = "" + } + s.aciKafkaClientKeySecret, err = r.secretMigrator.CreateOrUpdateACIKafkaClientKeySecret(currentACIKafkaClientKey, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciKafkaClientKeySecret != nil { + values.PutValue(data, s.aciKafkaClientKeySecret.Name, clusterSecrets, aciKafkaClientKeySecretKey) + rkeConfig.Network.AciNetworkProvider.KafkaClientKey = "" + } + s.secretsEncryptionProvidersSecret, err = r.secretMigrator.CreateOrUpdateSecretsEncryptionProvidersSecret(currentSecretsEncryptionProviders, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.secretsEncryptionProvidersSecret != nil { + values.PutValue(data, s.secretsEncryptionProvidersSecret.Name, clusterSecrets, secretsEncryptionProvidersSecretKey) + rkeConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources = nil + } + s.bastionHostSSHKeySecret, err = r.secretMigrator.CreateOrUpdateBastionHostSSHKeySecret(currentbastionHostSSHKeySecret, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.bastionHostSSHKeySecret != nil { + values.PutValue(data, s.bastionHostSSHKeySecret.Name, clusterSecrets, bastionHostSSHKeySecretKey) + rkeConfig.BastionHost.SSHKey = "" + } + s.kubeletExtraEnvSecret, err = r.secretMigrator.CreateOrUpdateKubeletExtraEnvSecret(currentKubeletExtraEnvSecret, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.kubeletExtraEnvSecret != nil { + values.PutValue(data, s.kubeletExtraEnvSecret.Name, clusterSecrets, kubeletExtraEnvSecretKey) + env := make([]string, 0, len(rkeConfig.Services.Kubelet.ExtraEnv)) + for _, e := range rkeConfig.Services.Kubelet.ExtraEnv { + if !strings.Contains(e, "AWS_SECRET_ACCESS_KEY") { + env = append(env, e) + } + } + rkeConfig.Services.Kubelet.ExtraEnv = env + } + s.privateRegistryECRSecret, err = r.secretMigrator.CreateOrUpdatePrivateRegistryECRSecret(currentPrivateRegistryECRSecret, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.privateRegistryECRSecret != nil { + values.PutValue(data, s.privateRegistryECRSecret.Name, clusterSecrets, privateRegistryECRSecretKey) + for _, reg := range rkeConfig.PrivateRegistries { + if ecr := reg.ECRCredentialPlugin; ecr != nil { + ecr.AwsSecretAccessKey = "" + ecr.AwsSessionToken = "" + } + } + } + + data["rancherKubernetesEngineConfig"], err = convert.EncodeToMap(rkeConfig) + if err != nil { + return secrets{}, err + } + return s, nil +} + +func canUseClusterName(apiContext *types.APIContext, requestedName string) error { + var clusters []managementv3.Cluster + + if err := access.List(apiContext, apiContext.Version, managementv3.ClusterType, &types.QueryOptions{}, &clusters); err != nil { + return err + } + + for _, c := range clusters { + if c.Removed == "" && strings.EqualFold(c.Name, requestedName) { + // cluster exists by this name + return httperror.NewFieldAPIError(httperror.NotUnique, "Cluster name", "") + } + } + + return nil +} + +func setKubernetesVersion(data map[string]interface{}, create bool) error { + rkeConfig, ok := values.GetValue(data, "rancherKubernetesEngineConfig") + if ok && rkeConfig != nil { + k8sVersion := values.GetValueN(data, "rancherKubernetesEngineConfig", "kubernetesVersion") + if k8sVersion == nil || k8sVersion == "" { + // Only set when its a new cluster + if create { + // set k8s version to system default on the spec + defaultVersion := settings.KubernetesVersion.Get() + values.PutValue(data, defaultVersion, "rancherKubernetesEngineConfig", "kubernetesVersion") + } + } else { + // if k8s version is already of rancher version form, noop + // if k8s version is of form 1.14.x, figure out the latest + k8sVersionRequested := convert.ToString(k8sVersion) + if strings.Contains(k8sVersionRequested, "-rancher") { + deprecated, err := isDeprecated(k8sVersionRequested) + if err != nil { + return err + } + if deprecated { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Requested kubernetesVersion %v is deprecated", k8sVersionRequested)) + } + return nil + } + translatedVersion, err := getSupportedK8sVersion(k8sVersionRequested) + if err != nil { + return err + } + if translatedVersion == "" { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Requested kubernetesVersion %v is not supported currently", k8sVersionRequested)) + } + values.PutValue(data, translatedVersion, "rancherKubernetesEngineConfig", "kubernetesVersion") + } + } + return nil +} + +func isDeprecated(version string) (bool, error) { + deprecatedVersions := make(map[string]bool) + deprecatedVersionSetting := settings.KubernetesVersionsDeprecated.Get() + if deprecatedVersionSetting != "" { + if err := json.Unmarshal([]byte(deprecatedVersionSetting), &deprecatedVersions); err != nil { + return false, errors.Wrapf(err, "Error reading the setting %v", settings.KubernetesVersionsDeprecated.Name) + } + } + return convert.ToBool(deprecatedVersions[version]), nil +} + +func getSupportedK8sVersion(k8sVersionRequest string) (string, error) { + _, err := clustertemplate.CheckKubernetesVersionFormat(k8sVersionRequest) + if err != nil { + return "", err + } + + supportedVersions := strings.Split(settings.KubernetesVersionsCurrent.Get(), ",") + range1, err := semver.ParseRange("=" + k8sVersionRequest) + if err != nil { + return "", httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Requested kubernetesVersion %v is not of valid semver [major.minor.patch] format", k8sVersionRequest)) + } + + for _, v := range supportedVersions { + semv, err := semver.ParseTolerant(strings.Split(v, "-rancher")[0]) + if err != nil { + return "", httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Semver translation failed for the current K8bernetes Version %v, err: %v", v, err)) + } + if range1(semv) { + return v, nil + } + } + return "", nil +} + +func validateNetworkFlag(data map[string]interface{}, create bool) error { + enableNetworkPolicy := values.GetValueN(data, "enableNetworkPolicy") + if enableNetworkPolicy == nil && create { + // setting default values for new clusters if value not passed + values.PutValue(data, false, "enableNetworkPolicy") + } else if value := convert.ToBool(enableNetworkPolicy); value { + rke2Config := values.GetValueN(data, "rke2Config") + k3sConfig := values.GetValueN(data, "k3sConfig") + if rke2Config != nil || k3sConfig != nil { + if create { + values.PutValue(data, false, "enableNetworkPolicy") + return nil + } + return fmt.Errorf("enableNetworkPolicy should be false for k3s or rke2 clusters") + } + } + return nil +} + +func setNodeUpgradeStrategy(newData, oldData map[string]interface{}) error { + rkeConfig := values.GetValueN(newData, "rancherKubernetesEngineConfig") + if rkeConfig == nil { + return nil + } + rkeConfigMap := convert.ToMapInterface(rkeConfig) + upgradeStrategy := rkeConfigMap["upgradeStrategy"] + oldUpgradeStrategy := values.GetValueN(oldData, "rancherKubernetesEngineConfig", "upgradeStrategy") + if upgradeStrategy == nil { + if oldUpgradeStrategy != nil { + upgradeStrategy = oldUpgradeStrategy + } else { + upgradeStrategy = &rketypes.NodeUpgradeStrategy{ + MaxUnavailableWorker: rkedefaults.DefaultMaxUnavailableWorker, + MaxUnavailableControlplane: rkedefaults.DefaultMaxUnavailableControlplane, + Drain: func() *bool { b := false; return &b }(), + } + } + values.PutValue(newData, upgradeStrategy, "rancherKubernetesEngineConfig", "upgradeStrategy") + return nil + } + upgradeStrategyMap := convert.ToMapInterface(upgradeStrategy) + if control, ok := upgradeStrategyMap["maxUnavailableControlplane"]; ok && control != "" { + if err := validateUnavailable(convert.ToString(control)); err != nil { + return fmt.Errorf("maxUnavailableControlplane is invalid: %v", err) + } + } else { + values.PutValue(newData, rkedefaults.DefaultMaxUnavailableControlplane, "rancherKubernetesEngineConfig", "upgradeStrategy", "maxUnavailableControlplane") + } + if worker, ok := upgradeStrategyMap["maxUnavailableWorker"]; ok && worker != "" { + if err := validateUnavailable(convert.ToString(worker)); err != nil { + return fmt.Errorf("maxUnavailableWorker is invalid: %v", err) + } + } else { + values.PutValue(newData, rkedefaults.DefaultMaxUnavailableWorker, "rancherKubernetesEngineConfig", "upgradeStrategy", "maxUnavailableWorker") + } + + nodeDrainInput := upgradeStrategyMap["nodeDrainInput"] + if nodeDrainInput == nil { + oldDrainInput := convert.ToMapInterface(oldUpgradeStrategy)["nodeDrainInput"] + if oldDrainInput != nil { + nodeDrainInput = oldDrainInput + } else { + ignoreDaemonSets := true + nodeDrainInput = &apimgmtv3.NodeDrainInput{ + IgnoreDaemonSets: &ignoreDaemonSets, + GracePeriod: -1, + Timeout: 120, + } + } + values.PutValue(newData, nodeDrainInput, "rancherKubernetesEngineConfig", "upgradeStrategy", "nodeDrainInput") + } + return nil +} + +func validateUnavailable(input string) error { + parsed := intstr.Parse(input) + if parsed.Type == intstr.Int && parsed.IntVal < 1 { + return fmt.Errorf("value must be greater than 0: %s", input) + } else if parsed.Type == intstr.String { + if strings.HasPrefix(parsed.StrVal, "-") || strings.HasPrefix(parsed.StrVal, "0") { + return fmt.Errorf("value must be greater than 0: %s", input) + } + s := strings.Replace(parsed.StrVal, "%", "", -1) + if _, err := strconv.Atoi(s); err != nil { + return fmt.Errorf("value must be valid int %s: %v", parsed.StrVal, err) + } + } + return nil +} + +func enableLocalBackup(data map[string]interface{}) { + rkeConfig, ok := values.GetValue(data, "rancherKubernetesEngineConfig") + + if ok && rkeConfig != nil { + legacyConfig := values.GetValueN(data, "rancherKubernetesEngineConfig", "services", "etcd", "snapshot") + if legacyConfig != nil && legacyConfig.(bool) { // don't enable rancher backup if legacy is enabled. + return + } + backupConfig := values.GetValueN(data, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig") + + if backupConfig == nil { + enabled := true + backupConfig = &rketypes.BackupConfig{ + Enabled: &enabled, + IntervalHours: DefaultBackupIntervalHours, + Retention: DefaultBackupRetention, + } + // enable rancher etcd backup + values.PutValue(data, backupConfig, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig") + } + } +} + +func setInstanceMetadataHostname(data map[string]interface{}) { + rkeConfig, ok := values.GetValue(data, "rancherKubernetesEngineConfig") + if ok && rkeConfig != nil { + cloudProviderName := convert.ToString(values.GetValueN(data, "rancherKubernetesEngineConfig", "cloudProvider", "name")) + _, ok := values.GetValue(data, "rancherKubernetesEngineConfig", "cloudProvider", "useInstanceMetadataHostname") + if !ok { + if cloudProviderName == k8s.AWSCloudProvider { + // set default false for in-tree aws cloud provider + values.PutValue(data, false, "rancherKubernetesEngineConfig", "cloudProvider", "useInstanceMetadataHostname") + } else if cloudProviderName == k8s.ExternalAWSCloudProviderName { + // set default true for external-aws cloud provider + values.PutValue(data, true, "rancherKubernetesEngineConfig", "cloudProvider", "useInstanceMetadataHostname") + } + } + } +} + +func enableCRIDockerd(data map[string]interface{}) { + rkeConfig, ok := values.GetValue(data, "rancherKubernetesEngineConfig") + if ok && rkeConfig != nil { + k8sVersion := convert.ToString(values.GetValueN(data, "rancherKubernetesEngineConfig", "kubernetesVersion")) + if mVersion.Compare(k8sVersion, "v1.24.0-rancher1-1", ">=") { + annotation, _ := values.GetValue(data, managementv3.ClusterFieldAnnotations) + m := toMap(annotation) + var enableCRIDockerd124 bool + if enable, ok := m[clusterCRIDockerdAnn]; ok && convert.ToString(enable) == "false" { + values.PutValue(data, enableCRIDockerd124, "rancherKubernetesEngineConfig", "enableCriDockerd") + return + } + enableCRIDockerd124 = true + values.PutValue(data, enableCRIDockerd124, "rancherKubernetesEngineConfig", "enableCriDockerd") + } + } +} + +func validateUpdatedS3Credentials(oldData, newData map[string]interface{}, dialer dialer.Dialer) error { + newConfig := convert.ToMapInterface(values.GetValueN(newData, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig", "s3BackupConfig")) + if newConfig == nil { + return nil + } + + oldConfig := convert.ToMapInterface(values.GetValueN(oldData, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig", "s3BackupConfig")) + if oldConfig == nil { + return validateS3Credentials(newData, dialer) + } + // remove "type" since it's added to the object by API, and it's not present in newConfig yet. + delete(oldConfig, "type") + if !reflect.DeepEqual(newConfig, oldConfig) { + return validateS3Credentials(newData, dialer) + } + return nil +} + +func validateS3Credentials(data map[string]interface{}, dialer dialer.Dialer) error { + s3BackupConfig := values.GetValueN(data, "rancherKubernetesEngineConfig", "services", "etcd", "backupConfig", "s3BackupConfig") + if s3BackupConfig == nil { + return nil + } + configMap := convert.ToMapInterface(s3BackupConfig) + sbc := &rketypes.S3BackupConfig{ + AccessKey: convert.ToString(configMap["accessKey"]), + SecretKey: convert.ToString(configMap["secretKey"]), + Endpoint: convert.ToString(configMap["endpoint"]), + Region: convert.ToString(configMap["region"]), + CustomCA: convert.ToString(configMap["customCa"]), + } + // skip if we don't have credentials defined. + if sbc.AccessKey == "" && sbc.SecretKey == "" { + return nil + } + bucket := convert.ToString(configMap["bucketName"]) + if bucket == "" { + return fmt.Errorf("Empty bucket name") + } + s3Client, err := etcdbackup.GetS3Client(sbc, s3TransportTimeout, dialer) + if err != nil { + return err + } + exists, err := s3Client.BucketExists(context.TODO(), bucket) + if err != nil { + return fmt.Errorf("Unable to validate S3 backup target configuration: %v", err) + } + if !exists { + return fmt.Errorf("Unable to validate S3 backup target configuration: bucket [%v] not found", bucket) + } + return nil +} + +func cleanPrivateRegistry(data map[string]interface{}) { + registries, ok := values.GetSlice(data, "rancherKubernetesEngineConfig", "privateRegistries") + if !ok || registries == nil { + return + } + var updatedRegistries []map[string]interface{} + for _, registry := range registries { + if registry["ecrCredentialPlugin"] != nil { + awsAccessKeyID, _ := values.GetValue(registry, "ecrCredentialPlugin", "awsAccessKeyId") + awsSecretAccessKey, _ := values.GetValue(registry, "ecrCredentialPlugin", "awsSecretAccessKey") + awsAccessToken, _ := values.GetValue(registry, "ecrCredentialPlugin", "awsAccessToken") + if awsAccessKeyID == nil && awsSecretAccessKey == nil && awsAccessToken == nil { + delete(registry, "ecrCredentialPlugin") + } + } + updatedRegistries = append(updatedRegistries, registry) + } + values.PutValue(data, updatedRegistries, "rancherKubernetesEngineConfig", "privateRegistries") +} + +func (r *Store) validateUnavailableNodes(data, existingData map[string]interface{}, id string) error { + cluster, err := r.ClusterLister.Get("", id) + if err != nil { + return fmt.Errorf("error getting cluster, try again %v", err) + } + // no need to validate if cluster's already provisioning or upgrading + if !apimgmtv3.ClusterConditionProvisioned.IsTrue(cluster) || + !apimgmtv3.ClusterConditionUpdated.IsTrue(cluster) || + apimgmtv3.ClusterConditionUpgraded.IsUnknown(cluster) { + return nil + } + spec, err := getRkeConfig(data) + if err != nil || spec == nil { + return err + } + status, err := getRkeConfig(existingData) + if err != nil || status == nil { + return err + } + if reflect.DeepEqual(status, spec) { + return nil + } + nodes, err := r.NodeLister.List(id, labels.Everything()) + if err != nil { + return fmt.Errorf("error fetching nodes, try again %v", err) + } + return canUpgrade(nodes, spec.UpgradeStrategy) +} + +func getRkeConfig(data map[string]interface{}) (*rketypes.RancherKubernetesEngineConfig, error) { + rkeConfig := values.GetValueN(data, "rancherKubernetesEngineConfig") + if rkeConfig == nil { + return nil, nil + } + config, err := json.Marshal(rkeConfig) + if err != nil { + return nil, errors.Wrapf(err, "error marshaling rkeConfig") + } + var spec *rketypes.RancherKubernetesEngineConfig + if err = json.Unmarshal(config, &spec); err != nil { + return nil, errors.Wrapf(err, "error reading rkeConfig") + } + return spec, nil +} + +func canUpgrade(nodes []*apimgmtv3.Node, upgradeStrategy *rketypes.NodeUpgradeStrategy) error { + var ( + controlReady, controlNotReady, workerOnlyReady, workerOnlyNotReady int + ) + for _, node := range nodes { + if node.Status.NodeConfig == nil { + continue + } + if slice.ContainsString(node.Status.NodeConfig.Role, rkeservices.ControlRole) { + // any node having control role + if nodehelper.IsMachineReady(node) { + controlReady++ + } else { + controlNotReady++ + } + continue + } + if slice.ContainsString(node.Status.NodeConfig.Role, rkeservices.ETCDRole) { + continue + } + if nodehelper.IsMachineReady(node) { + workerOnlyReady++ + } else { + workerOnlyNotReady++ + } + } + maxUnavailableControl, err := rkeworkerupgrader.CalculateMaxUnavailable(upgradeStrategy.MaxUnavailableControlplane, controlReady+controlNotReady) + if err != nil { + return err + } + if controlNotReady >= maxUnavailableControl { + return fmt.Errorf("not enough control plane nodes ready to upgrade, maxUnavailable: %v, notReady: %v, ready: %v", + maxUnavailableControl, controlNotReady, controlReady) + } + maxUnavailableWorker, err := rkeworkerupgrader.CalculateMaxUnavailable(upgradeStrategy.MaxUnavailableWorker, workerOnlyReady+workerOnlyNotReady) + if err != nil { + return err + } + if workerOnlyNotReady >= maxUnavailableWorker { + return fmt.Errorf("not enough worker nodes ready to upgrade, maxUnavailable: %v, notReady: %v, ready: %v", + maxUnavailableWorker, workerOnlyNotReady, workerOnlyReady) + } + return nil +} + +func validateKeyRotation(data map[string]interface{}) error { + secretsEncryptionEnabled, _ := values.GetValue(data, "rancherKubernetesEngineConfig", "services", "kubeApi", "secretsEncryptionConfig", "enabled") + rotateEncryptionKeyEnabled, _ := values.GetValue(data, "rancherKubernetesEngineConfig", "rotateEncryptionKey") + if rotateEncryptionKeyEnabled != nil && rotateEncryptionKeyEnabled == true { + if secretsEncryptionEnabled != nil && secretsEncryptionEnabled == false { + return fmt.Errorf("unable to rotate encryption key when encryption configuration is disabled") + } + } + return nil +} + +func cleanQuestions(data map[string]interface{}) map[string]interface{} { + if _, ok := data["questions"]; ok { + questions := data["questions"].([]map[string]interface{}) + for i, q := range questions { + if secretmigrator.MatchesQuestionPath(q["variable"].(string)) { + delete(q, "default") + } + questions[i] = q + } + values.PutValue(data, questions, "questions") + } + if _, ok := values.GetValue(data, "answers", "values"); ok { + values.RemoveValue(data, "answers", "values", secretmigrator.S3BackupAnswersPath) + values.RemoveValue(data, "answers", "values", secretmigrator.WeavePasswordAnswersPath) + values.RemoveValue(data, "answers", "values", secretmigrator.VsphereGlobalAnswersPath) + values.RemoveValue(data, "answers", "values", secretmigrator.OpenStackAnswersPath) + values.RemoveValue(data, "answers", "values", secretmigrator.AADClientAnswersPath) + values.RemoveValue(data, "answers", "values", secretmigrator.AADCertAnswersPath) + for i := 0; ; i++ { + key := fmt.Sprintf(secretmigrator.RegistryPasswordAnswersPath, i) + if _, ok := values.GetValue(data, "answers", "values", key); !ok { + break + } + values.RemoveValue(data, "answers", "values", key) + } + vcenters, ok := values.GetValue(data, "rancherKubernetesEngineConfig", "cloudProvider", "vsphereCloudProvider", "virtualCenter") + if ok { + for k := range vcenters.(map[string]interface{}) { + key := fmt.Sprintf(secretmigrator.VcenterAnswersPath, k) + values.RemoveValue(data, "answers", "values", key) + } + } + } + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/clustertemplate/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/clustertemplate/store.go new file mode 100644 index 0000000..fb82ae0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/clustertemplate/store.go @@ -0,0 +1,813 @@ +package clustertemplate + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/api/norman/customization/clustertemplate" + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + mgmtSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + k8sTypes "k8s.io/apimachinery/pkg/types" +) + +const ( + clusterTemplateLabelName = "io.cattle.field/clusterTemplateId" + registrySecretKey = "privateRegistrySecret" + s3SecretKey = "s3CredentialSecret" + weaveSecretKey = "weavePasswordSecret" + vsphereSecretKey = "vsphereSecret" + virtualCenterSecretKey = "virtualCenterSecret" + openStackSecretKey = "openStackSecret" + aadClientSecretKey = "aadClientSecret" + aadClientCertSecretKey = "aadClientCertSecret" + aciAPICUserKeySecretKey = "aciAPICUserKeySecret" + aciTokenSecretKey = "aciTokenSecret" + aciKafkaClientKeySecretKey = "aciKafkaClientKeySecret" + secretsEncryptionProvidersSecretKey = "secretsEncryptionProvidersSecret" + bastionHostSSHKeySecretKey = "bastionHostSSHKeySecret" + kubeletExtraEnvSecretKey = "kubeletExtraEnvSecret" + privateRegistryECRSecretKey = "privateRegistryECRSecret" +) + +func WrapStore(store types.Store, mgmt *config.ScaledContext) types.Store { + storeWrapped := &Store{ + Store: store, + users: mgmt.Management.Users(""), + grbLister: mgmt.Management.GlobalRoleBindings("").Controller().Lister(), + grLister: mgmt.Management.GlobalRoles("").Controller().Lister(), + ctLister: mgmt.Management.ClusterTemplates("").Controller().Lister(), + clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + secretMigrator: secretmigrator.NewMigrator( + mgmt.Core.Secrets("").Controller().Lister(), + mgmt.Core.Secrets(""), + ), + } + return storeWrapped +} + +type Store struct { + types.Store + users v3.UserInterface + grbLister v3.GlobalRoleBindingLister + grLister v3.GlobalRoleLister + ctLister v3.ClusterTemplateLister + clusterLister v3.ClusterLister + SecretLister v1.SecretLister + secretMigrator *secretmigrator.Migrator +} + +type secrets struct { + regSecret *corev1.Secret + s3Secret *corev1.Secret + weaveSecret *corev1.Secret + vsphereSecret *corev1.Secret + vcenterSecret *corev1.Secret + openStackSecret *corev1.Secret + aadClientSecret *corev1.Secret + aadCertSecret *corev1.Secret + aciAPICUserKeySecret *corev1.Secret + aciTokenSecret *corev1.Secret + aciKafkaClientKeySecret *corev1.Secret + secretsEncryptionProvidersSecret *corev1.Secret + bastionHostSSHKeySecret *corev1.Secret + kubeletExtraEnvSecret *corev1.Secret + privateRegistryECRSecret *corev1.Secret +} + +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateType) { + if err := p.checkMembersAccessType(data); err != nil { + return nil, err + } + } + + var allSecrets secrets + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + if data[managementv3.ClusterTemplateRevisionFieldClusterConfig] == nil { + return nil, httperror.NewAPIError(httperror.MissingRequired, "ClusterTemplateRevision field ClusterConfig is required") + } + err := p.checkPermissionToCreateRevision(apiContext, data) + if err != nil { + return nil, err + } + err = p.checkKubernetesVersionFormat(apiContext, data) + if err != nil { + return nil, err + } + if err := setLabelsAndOwnerRef(apiContext, data); err != nil { + return nil, err + } + allSecrets, err = p.migrateSecrets(data, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") + if err != nil { + return nil, err + } + data = cleanQuestions(data) + } + + result, err := p.Store.Create(apiContext, schema, data) + if err != nil { + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + if allSecrets.regSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.regSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.s3Secret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.s3Secret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.weaveSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.weaveSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.vsphereSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.vsphereSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.vcenterSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.vcenterSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.openStackSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.openStackSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aadClientSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aadClientSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aadCertSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aadCertSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciAPICUserKeySecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciAPICUserKeySecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciTokenSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciTokenSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciKafkaClientKeySecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciKafkaClientKeySecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.secretsEncryptionProvidersSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.secretsEncryptionProvidersSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.bastionHostSSHKeySecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.bastionHostSSHKeySecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.kubeletExtraEnvSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.kubeletExtraEnvSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.privateRegistryECRSecret != nil { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.privateRegistryECRSecret.Name); cleanupErr != nil { + logrus.Errorf("clustertemplate store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + } + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status { + return result, httperror.WrapAPIError(err, httperror.PermissionDenied, "You must have the `Create Cluster Templates` global role in order to create cluster templates or revisions. These permissions can be granted by an administrator.") + } + } + return nil, err + } + + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + _, clusterTemplateName := ref.Parse(result["id"].(string)) + owner := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "ClusterTemplateRevision", + Name: clusterTemplateName, + UID: k8sTypes.UID(result["uuid"].(string)), + } + if allSecrets.regSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.regSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.s3Secret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.s3Secret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.weaveSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.weaveSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.vsphereSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.vsphereSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.vcenterSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.vcenterSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.openStackSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.openStackSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.aadClientSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.aadClientSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.aadCertSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.aadCertSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.aciAPICUserKeySecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.aciAPICUserKeySecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.aciTokenSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.aciTokenSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.aciKafkaClientKeySecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.aciKafkaClientKeySecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.secretsEncryptionProvidersSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.secretsEncryptionProvidersSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.bastionHostSSHKeySecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.bastionHostSSHKeySecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.kubeletExtraEnvSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.kubeletExtraEnvSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + if allSecrets.privateRegistryECRSecret != nil { + err = p.secretMigrator.UpdateSecretOwnerReference(allSecrets.privateRegistryECRSecret, owner) + if err != nil { + logrus.Errorf("cluster store: failed to set %s %s as secret owner", owner.Kind, owner.Name) + } + } + } + return result, err +} + +func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateType) { + if err := p.checkMembersAccessType(data); err != nil { + return nil, err + } + } + + var allSecrets secrets + var currentRegSecret, currentS3Secret, currentWeaveSecret string + var currentVsphereSecret, currentVcenterSecret, currentOpenStackSecret, currentAADClientSecret, currentAADCertSecret string + var currentACIAPICUserKeySecret, currentACITokenSecret, currentACIKafkaClientKeySecret string + var currentSecretsEncryptionProvidersSecret, currentBastionHostSSHKeySecret, currentKubeletExtraEnvSecret, currentPrivateRegistryECRSecret string + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + err := p.checkKubernetesVersionFormat(apiContext, data) + if err != nil { + return nil, err + } + + isUsed, err := p.isTemplateInUse(apiContext, id) + if err != nil { + return nil, err + } + if isUsed { + return nil, httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Cannot update the %v until Clusters are referring it", apiContext.Type)) + } + existingClusterTemplate, err := p.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + currentRegSecret, _ = existingClusterTemplate[registrySecretKey].(string) + currentS3Secret, _ = existingClusterTemplate[s3SecretKey].(string) + currentWeaveSecret, _ = existingClusterTemplate[weaveSecretKey].(string) + currentVsphereSecret, _ = existingClusterTemplate[vsphereSecretKey].(string) + currentVcenterSecret, _ = existingClusterTemplate[virtualCenterSecretKey].(string) + currentOpenStackSecret, _ = existingClusterTemplate[openStackSecretKey].(string) + currentAADClientSecret, _ = existingClusterTemplate[aadClientSecretKey].(string) + currentAADCertSecret, _ = existingClusterTemplate[aadClientCertSecretKey].(string) + currentACIAPICUserKeySecret, _ = existingClusterTemplate[aciAPICUserKeySecretKey].(string) + currentACITokenSecret, _ = existingClusterTemplate[aciTokenSecretKey].(string) + currentACIKafkaClientKeySecret, _ = existingClusterTemplate[aciKafkaClientKeySecretKey].(string) + + currentSecretsEncryptionProvidersSecret, _ = existingClusterTemplate[secretsEncryptionProvidersSecretKey].(string) + currentBastionHostSSHKeySecret, _ = existingClusterTemplate[bastionHostSSHKeySecretKey].(string) + currentKubeletExtraEnvSecret, _ = existingClusterTemplate[kubeletExtraEnvSecretKey].(string) + currentPrivateRegistryECRSecret, _ = existingClusterTemplate[privateRegistryECRSecretKey].(string) + allSecrets, err = p.migrateSecrets(data, currentRegSecret, currentS3Secret, currentWeaveSecret, currentVsphereSecret, currentVcenterSecret, currentOpenStackSecret, currentAADClientSecret, currentAADCertSecret, currentACIAPICUserKeySecret, currentACITokenSecret, currentACIKafkaClientKeySecret, currentSecretsEncryptionProvidersSecret, currentBastionHostSSHKeySecret, currentKubeletExtraEnvSecret, currentPrivateRegistryECRSecret) + if err != nil { + return nil, err + } + data = cleanQuestions(data) + } + + result, err := p.Store.Update(apiContext, schema, data, id) + + if err != nil { + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + if allSecrets.regSecret != nil && currentRegSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.regSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.s3Secret != nil && currentS3Secret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.s3Secret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.weaveSecret != nil && currentWeaveSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.weaveSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.vsphereSecret != nil && currentVsphereSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.vsphereSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.vcenterSecret != nil && currentVcenterSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.vcenterSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.openStackSecret != nil && currentOpenStackSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.openStackSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aadClientSecret != nil && currentAADClientSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aadClientSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aadCertSecret != nil && currentAADCertSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aadCertSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciAPICUserKeySecret != nil && currentACIAPICUserKeySecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciAPICUserKeySecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciTokenSecret != nil && currentACITokenSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciTokenSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.aciKafkaClientKeySecret != nil && currentACIKafkaClientKeySecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.aciKafkaClientKeySecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.secretsEncryptionProvidersSecret != nil && currentSecretsEncryptionProvidersSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.secretsEncryptionProvidersSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.bastionHostSSHKeySecret != nil && currentBastionHostSSHKeySecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.bastionHostSSHKeySecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.kubeletExtraEnvSecret != nil && currentKubeletExtraEnvSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.kubeletExtraEnvSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if allSecrets.privateRegistryECRSecret != nil && currentPrivateRegistryECRSecret == "" { + if cleanupErr := p.secretMigrator.Cleanup(allSecrets.privateRegistryECRSecret.Name); cleanupErr != nil { + logrus.Errorf("cluster store: encountered error while handling migration error: %v, original error: %v", cleanupErr, err) + } + } + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status { + return result, httperror.WrapAPIError(err, httperror.PermissionDenied, "You do not have permissions to create or edit the cluster templates or revisions. These permissions can be granted by an administrator.") + } + } + } + } + + return result, err +} + +func (p *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + + isUsed, err := p.isTemplateInUse(apiContext, id) + if err != nil { + return nil, err + } + if isUsed { + return nil, httperror.NewAPIError(httperror.InvalidAction, fmt.Sprintf("Cannot delete the %v until Clusters referring it are removed", apiContext.Type)) + } + + // check if template.DefaultRevisionId is set, if yes error out if the revision is being deleted. + if strings.EqualFold(apiContext.Type, managementv3.ClusterTemplateRevisionType) { + isDefault, err := isDefaultTemplateRevision(apiContext, id) + if err != nil { + return nil, err + } + if isDefault { + return nil, httperror.NewAPIError(httperror.PermissionDenied, fmt.Sprintf("Cannot delete the %v since this is the default revision of the Template, Please change the default revision first", apiContext.Type)) + } + } + + result, err := p.Store.Delete(apiContext, schema, id) + + if err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status { + return result, httperror.WrapAPIError(err, httperror.PermissionDenied, "You do not have permissions to delete the cluster templates or revisions. These permissions can be granted by an administrator.") + } + } + } + + return result, err +} + +func setLabelsAndOwnerRef(apiContext *types.APIContext, data map[string]interface{}) error { + var template managementv3.ClusterTemplate + + templateID := convert.ToString(data[managementv3.ClusterTemplateRevisionFieldClusterTemplateID]) + if err := access.ByID(apiContext, apiContext.Version, managementv3.ClusterTemplateType, templateID, &template); err != nil { + return err + } + + split := strings.SplitN(template.ID, ":", 2) + if len(split) != 2 { + return fmt.Errorf("error in splitting clusterTemplate ID %v", template.ID) + } + templateName := split[1] + + labels := map[string]string{ + clusterTemplateLabelName: templateName, + } + data["labels"] = labels + + var ownerReferencesSlice []map[string]interface{} + ownerReference := map[string]interface{}{ + managementv3.OwnerReferenceFieldKind: "ClusterTemplate", + managementv3.OwnerReferenceFieldAPIVersion: "management.cattle.io/v3", + managementv3.OwnerReferenceFieldName: templateName, + managementv3.OwnerReferenceFieldUID: template.UUID, + } + ownerReferencesSlice = append(ownerReferencesSlice, ownerReference) + data["ownerReferences"] = ownerReferencesSlice + + return nil +} + +func (p *Store) isTemplateInUse(apiContext *types.APIContext, id string) (bool, error) { + + /*check if there are any clusters referencing this template or templateRevision */ + var clusters []*v3.Cluster + var field string + + clusters, err := p.clusterLister.List("", labels.NewSelector()) + if err != nil { + return false, err + } + + for _, cluster := range clusters { + switch apiContext.Type { + case managementv3.ClusterTemplateType: + field = cluster.Spec.ClusterTemplateName + case managementv3.ClusterTemplateRevisionType: + field = cluster.Spec.ClusterTemplateRevisionName + default: + break + } + if field != id { + continue + } + return true, nil + } + + return false, nil +} + +func isDefaultTemplateRevision(apiContext *types.APIContext, id string) (bool, error) { + + var template managementv3.ClusterTemplate + var templateRevision managementv3.ClusterTemplateRevision + + if err := access.ByID(apiContext, apiContext.Version, managementv3.ClusterTemplateRevisionType, id, &templateRevision); err != nil { + return false, err + } + + if err := access.ByID(apiContext, apiContext.Version, managementv3.ClusterTemplateType, templateRevision.ClusterTemplateID, &template); err != nil { + return false, err + } + + if template.DefaultRevisionID == id { + return true, nil + } + + return false, nil +} + +func (p *Store) checkPermissionToCreateRevision(apiContext *types.APIContext, data map[string]interface{}) error { + value, found := values.GetValue(data, managementv3.ClusterTemplateRevisionFieldClusterTemplateID) + if !found { + return httperror.NewAPIError(httperror.NotFound, "invalid request: clusterTemplateID not found") + } + + clusterTemplateID := convert.ToString(value) + _, clusterTemplateName := ref.Parse(clusterTemplateID) + var ctMap map[string]interface{} + if err := access.ByID(apiContext, &mgmtSchema.Version, managementv3.ClusterTemplateType, clusterTemplateID, &ctMap); err != nil { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("unable to access clusterTemplate by id: %v", err)) + } + if err := apiContext.AccessControl.CanDo(v3.ClusterTemplateGroupVersionKind.Group, v3.ClusterTemplateResource.Name, "update", apiContext, ctMap, apiContext.Schema); err != nil { + return httperror.NewAPIError(httperror.PermissionDenied, fmt.Sprintf("user does not have permission to update clusterTemplate %s by creating a revision for it", clusterTemplateName)) + } + return nil +} + +func (p *Store) checkKubernetesVersionFormat(apiContext *types.APIContext, data map[string]interface{}) error { + clusterConfig, found := values.GetValue(data, managementv3.ClusterTemplateRevisionFieldClusterConfig) + if !found || clusterConfig == nil { + return httperror.NewAPIError(httperror.MissingRequired, "ClusterTemplateRevision field ClusterConfig is required") + } + k8sVersionReq := values.GetValueN(data, managementv3.ClusterTemplateRevisionFieldClusterConfig, "rancherKubernetesEngineConfig", "kubernetesVersion") + if k8sVersionReq == nil { + return nil + } + k8sVersion := convert.ToString(k8sVersionReq) + genericPatch, err := clustertemplate.CheckKubernetesVersionFormat(k8sVersion) + if err != nil { + return err + } + if genericPatch { + // ensure a question is added for "rancherKubernetesEngineConfig.kubernetesVersion" + templateQuestions, ok := data[managementv3.ClusterTemplateRevisionFieldQuestions] + if !ok { + return httperror.NewAPIError(httperror.MissingRequired, fmt.Sprintf("ClusterTemplateRevision must have a Question set for %v", clustertemplate.RKEConfigK8sVersion)) + } + templateQuestionsSlice := convert.ToMapSlice(templateQuestions) + var foundQ bool + for _, question := range templateQuestionsSlice { + if question["variable"] == clustertemplate.RKEConfigK8sVersion { + foundQ = true + break + } + } + if !foundQ { + return httperror.NewAPIError(httperror.MissingRequired, fmt.Sprintf("ClusterTemplateRevision must have a Question set for %v", clustertemplate.RKEConfigK8sVersion)) + } + } + return nil +} + +func (p *Store) checkMembersAccessType(data map[string]interface{}) error { + members := convert.ToMapSlice(data[managementv3.ClusterTemplateFieldMembers]) + for _, m := range members { + accessType := convert.ToString(m[managementv3.MemberFieldAccessType]) + if accessType != rbac.OwnerAccess && accessType != rbac.ReadOnlyAccess { + return httperror.NewAPIError(httperror.InvalidBodyContent, "Invalid accessType provided while sharing cluster template") + } + } + return nil +} + +func (p *Store) migrateSecrets(data map[string]interface{}, currentReg, currentS3, currentWeave, currentVsphere, currentVCenter, currentOpenStack, currentAADClientSecret, currentAADCert, currentACIAPICUserKey, currentACIToken, currentACIKafkaClientKey, currentSecretsEncryptionProviders, currentBastionHostSSHKey, currentKubeletExtraEnv, currentPrivateRegistryECR string) (secrets, error) { + rkeConfig, err := getRkeConfig(data) + if err != nil || rkeConfig == nil { + return secrets{}, err + } + var s secrets + s.regSecret, err = p.secretMigrator.CreateOrUpdatePrivateRegistrySecret(currentReg, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.regSecret != nil { + data[registrySecretKey] = s.regSecret.Name + rkeConfig.PrivateRegistries = secretmigrator.CleanRegistries(rkeConfig.PrivateRegistries) + } + s.s3Secret, err = p.secretMigrator.CreateOrUpdateS3Secret(currentS3, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.s3Secret != nil { + data[s3SecretKey] = s.s3Secret.Name + rkeConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey = "" + } + s.weaveSecret, err = p.secretMigrator.CreateOrUpdateWeaveSecret(currentWeave, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.weaveSecret != nil { + data[weaveSecretKey] = s.weaveSecret.Name + rkeConfig.Network.WeaveNetworkProvider.Password = "" + } + s.vsphereSecret, err = p.secretMigrator.CreateOrUpdateVsphereGlobalSecret(currentVsphere, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.vsphereSecret != nil { + data[vsphereSecretKey] = s.vsphereSecret.Name + rkeConfig.CloudProvider.VsphereCloudProvider.Global.Password = "" + } + s.vcenterSecret, err = p.secretMigrator.CreateOrUpdateVsphereVirtualCenterSecret(currentVCenter, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.vcenterSecret != nil { + data[virtualCenterSecretKey] = s.vcenterSecret.Name + for k, v := range rkeConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + v.Password = "" + rkeConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] = v + } + } + s.openStackSecret, err = p.secretMigrator.CreateOrUpdateOpenStackSecret(currentOpenStack, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.openStackSecret != nil { + data[openStackSecretKey] = s.openStackSecret.Name + rkeConfig.CloudProvider.OpenstackCloudProvider.Global.Password = "" + } + s.aadClientSecret, err = p.secretMigrator.CreateOrUpdateAADClientSecret(currentAADClientSecret, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aadClientSecret != nil { + data[aadClientSecretKey] = s.aadClientSecret.Name + rkeConfig.CloudProvider.AzureCloudProvider.AADClientSecret = "" + } + s.aadCertSecret, err = p.secretMigrator.CreateOrUpdateAADCertSecret(currentAADCert, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aadCertSecret != nil { + data[aadClientCertSecretKey] = s.aadCertSecret.Name + rkeConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword = "" + } + s.aciAPICUserKeySecret, err = p.secretMigrator.CreateOrUpdateACIAPICUserKeySecret(currentACIAPICUserKey, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciAPICUserKeySecret != nil { + data[aciAPICUserKeySecretKey] = s.aciAPICUserKeySecret.Name + rkeConfig.Network.AciNetworkProvider.ApicUserKey = "" + } + s.aciTokenSecret, err = p.secretMigrator.CreateOrUpdateACITokenSecret(currentACIToken, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciTokenSecret != nil { + data[aciTokenSecretKey] = s.aciTokenSecret.Name + rkeConfig.Network.AciNetworkProvider.Token = "" + } + s.aciKafkaClientKeySecret, err = p.secretMigrator.CreateOrUpdateACIKafkaClientKeySecret(currentACIKafkaClientKey, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.aciKafkaClientKeySecret != nil { + data[aciKafkaClientKeySecretKey] = s.aciKafkaClientKeySecret.Name + rkeConfig.Network.AciNetworkProvider.KafkaClientKey = "" + } + s.secretsEncryptionProvidersSecret, err = p.secretMigrator.CreateOrUpdateSecretsEncryptionProvidersSecret(currentSecretsEncryptionProviders, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.secretsEncryptionProvidersSecret != nil { + data[secretsEncryptionProvidersSecretKey] = s.secretsEncryptionProvidersSecret.Name + rkeConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources = nil + } + s.bastionHostSSHKeySecret, err = p.secretMigrator.CreateOrUpdateBastionHostSSHKeySecret(currentBastionHostSSHKey, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.bastionHostSSHKeySecret != nil { + data[bastionHostSSHKeySecretKey] = s.bastionHostSSHKeySecret.Name + rkeConfig.BastionHost.SSHKey = "" + } + s.kubeletExtraEnvSecret, err = p.secretMigrator.CreateOrUpdateKubeletExtraEnvSecret(currentKubeletExtraEnv, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.kubeletExtraEnvSecret != nil { + data[kubeletExtraEnvSecretKey] = s.kubeletExtraEnvSecret.Name + env := make([]string, 0, len(rkeConfig.Services.Kubelet.ExtraEnv)) + for _, e := range rkeConfig.Services.Kubelet.ExtraEnv { + if !strings.Contains(e, "AWS_SECRET_ACCESS_KEY") { + env = append(env, e) + } + } + rkeConfig.Services.Kubelet.ExtraEnv = env + } + s.privateRegistryECRSecret, err = p.secretMigrator.CreateOrUpdatePrivateRegistryECRSecret(currentPrivateRegistryECR, rkeConfig, nil) + if err != nil { + return secrets{}, err + } + if s.privateRegistryECRSecret != nil { + data[privateRegistryECRSecretKey] = s.privateRegistryECRSecret.Name + for _, reg := range rkeConfig.PrivateRegistries { + if ecr := reg.ECRCredentialPlugin; ecr != nil { + ecr.AwsSecretAccessKey = "" + ecr.AwsSessionToken = "" + } + } + } + + encodedRkeConfig, err := convert.EncodeToMap(rkeConfig) + if err != nil { + return secrets{}, err + } + values.PutValue(data, encodedRkeConfig, "clusterConfig", "rancherKubernetesEngineConfig") + return s, nil +} + +func getRkeConfig(data map[string]interface{}) (*rketypes.RancherKubernetesEngineConfig, error) { + rkeConfig := values.GetValueN(data, managementv3.ClusterTemplateRevisionFieldClusterConfig, "rancherKubernetesEngineConfig") + if rkeConfig == nil { + return nil, nil + } + config, err := json.Marshal(rkeConfig) + if err != nil { + return nil, errors.Wrapf(err, "error marshaling rkeConfig") + } + var spec *rketypes.RancherKubernetesEngineConfig + if err := json.Unmarshal([]byte(config), &spec); err != nil { + return nil, errors.Wrapf(err, "error reading rkeConfig") + } + return spec, nil +} + +func cleanQuestions(data map[string]interface{}) map[string]interface{} { + if _, ok := data["questions"]; ok { + questions := data["questions"].([]interface{}) + for i := range questions { + q := questions[i].(map[string]interface{}) + if secretmigrator.MatchesQuestionPath(q["variable"].(string)) { + delete(q, "default") + } + questions[i] = q + } + values.PutValue(data, questions, "questions") + } + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/crd/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/crd/store.go new file mode 100644 index 0000000..4a812d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/crd/store.go @@ -0,0 +1,19 @@ +package crd + +import ( + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" +) + +type ForgetCRDNotFoundStore struct { + types.Store +} + +func (s *ForgetCRDNotFoundStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + c, err := s.Store.Watch(apiContext, schema, opt) + apiError, ok := err.(*httperror.APIError) + if ok && apiError.Code == httperror.NotFound { + return nil, nil + } + return c, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/feature/feature_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/feature/feature_store.go new file mode 100644 index 0000000..7bc8d13 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/feature/feature_store.go @@ -0,0 +1,20 @@ +package feature + +import ( + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" +) + +type Store struct { + types.Store +} + +func New(store types.Store) types.Store { + return &Store{ + store, + } +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "cannot delete features") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldns_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldns_store.go new file mode 100644 index 0000000..613327a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldns_store.go @@ -0,0 +1,78 @@ +package globaldns + +import ( + "strings" + "sync" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" +) + +func Wrap(store types.Store) types.Store { + storeWrapped := &Store{ + Store: store, + } + storeWrapped.mu = sync.Mutex{} + return storeWrapped +} + +type Store struct { + types.Store + mu sync.Mutex +} + +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + fqdn := convert.ToString(data[managementv3.GlobalDnsFieldFQDN]) + + p.mu.Lock() + defer p.mu.Unlock() + + if err := canUseFQDN(apiContext, fqdn); err != nil { + return nil, err + } + + return p.Store.Create(apiContext, schema, data) +} + +func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + updatedFQDN := convert.ToString(data[managementv3.GlobalDnsFieldFQDN]) + + existingGlobalDNS, err := p.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + + fqdn := convert.ToString(existingGlobalDNS[managementv3.GlobalDnsFieldFQDN]) + + if !strings.EqualFold(updatedFQDN, fqdn) { + p.mu.Lock() + defer p.mu.Unlock() + + if err := canUseFQDN(apiContext, updatedFQDN); err != nil { + return nil, err + } + } + + return p.Store.Update(apiContext, schema, data, id) +} + +func canUseFQDN(apiContext *types.APIContext, fqdnRequested string) error { + var globalDNSs []managementv3.GlobalDns + + conditions := []*types.QueryCondition{ + types.NewConditionFromString(managementv3.GlobalDnsFieldFQDN, types.ModifierEQ, []string{fqdnRequested}...), + } + + if err := access.List(apiContext, apiContext.Version, managementv3.GlobalDnsType, &types.QueryOptions{Conditions: conditions}, &globalDNSs); err != nil { + return err + } + + if len(globalDNSs) > 0 { + return httperror.NewFieldAPIError(httperror.NotUnique, managementv3.GlobalDnsFieldFQDN, "") + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldnsprovider_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldnsprovider_store.go new file mode 100644 index 0000000..85b74d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globaldns/globaldnsprovider_store.go @@ -0,0 +1,108 @@ +package globaldns + +import ( + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/namespace" +) + +func ProviderWrap(store types.Store) types.Store { + storeWrapped := &ProviderStore{ + Store: store, + } + return storeWrapped +} + +type ProviderStore struct { + types.Store +} + +func (p *ProviderStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + + if err := canDeleteProvider(apiContext, id); err != nil { + return nil, err + } + + return p.Store.Delete(apiContext, schema, id) +} + +func canDeleteProvider(apiContext *types.APIContext, id string) error { + + //check if there are any globalDNS entries referencing this provider + var globalDNSs []managementv3.GlobalDns + + conditions := []*types.QueryCondition{ + types.NewConditionFromString(managementv3.GlobalDnsFieldProviderID, types.ModifierEQ, []string{id}...), + } + + if err := access.List(apiContext, apiContext.Version, managementv3.GlobalDnsType, &types.QueryOptions{Conditions: conditions}, &globalDNSs); err != nil { + return err + } + + if len(globalDNSs) > 0 { + return httperror.NewAPIError(httperror.PermissionDenied, "Cannot delete the provider until GlobalDNS entries referring it are removed") + } + + return nil +} + +func ProviderPwdWrap(store types.Store) types.Store { + storeWrapped := &ProviderPwdStore{ + Store: store, + } + return storeWrapped +} + +type ProviderPwdStore struct { + types.Store +} + +func (p *ProviderPwdStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + + providerFound, keys := findProviderPasswordKeys(data) + if !providerFound { + return p.Store.Update(apiContext, schema, data, id) + } + + _, passwordFound := values.GetValue(data, keys...) + + if !passwordFound { + existingProvider, err := p.ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + existingPassword, _ := values.GetValue(existingProvider, keys...) + if !strings.HasPrefix(convert.ToString(existingPassword), namespace.GlobalNamespace) { + values.PutValue(data, existingPassword, keys...) + } + } + + return p.Store.Update(apiContext, schema, data, id) +} + +func findProviderPasswordKeys(data map[string]interface{}) (bool, []string) { + var keys []string + + _, route53 := values.GetValue(data, "route53ProviderConfig") + if route53 { + return true, []string{"route53ProviderConfig", "secretKey"} + } + + _, cloudFlare := values.GetValue(data, "cloudflareProviderConfig") + if cloudFlare { + return true, []string{"cloudflareProviderConfig", "apiKey"} + } + + _, aliDNS := values.GetValue(data, "alidnsProviderConfig") + if aliDNS { + return true, []string{"alidnsProviderConfig", "secretKey"} + } + + return false, keys +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrole/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrole/store.go new file mode 100644 index 0000000..cb9ec72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrole/store.go @@ -0,0 +1,32 @@ +package globalrole + +import ( + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +type store struct { + types.Store + + grLister v3.GlobalRoleLister +} + +func Wrap(s types.Store, grLister v3.GlobalRoleLister) types.Store { + return &store{ + Store: s, + grLister: grLister, + } +} + +func (s *store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + globalRole, err := s.grLister.Get("", id) + if err != nil { + return nil, err + } + + if globalRole.Builtin { + return nil, httperror.NewAPIError(httperror.PermissionDenied, "cannot delete builtin global roles") + } + return s.Store.Delete(apiContext, schema, id) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrolebindings/globalrolebinding_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrolebindings/globalrolebinding_store.go new file mode 100644 index 0000000..e1f8661 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/globalrolebindings/globalrolebinding_store.go @@ -0,0 +1,63 @@ +package grbstore + +import ( + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + GrbVersion = "cleanup.cattle.io/grbUpgradeCluster" + OldGrbVersion = "field.cattle.io/grbUpgrade" +) + +func Wrap(store types.Store, grLister v3.GlobalRoleLister) types.Store { + return &grbStore{ + Store: store, + grLister: grLister, + } +} + +type grbStore struct { + types.Store + + grLister v3.GlobalRoleLister +} + +func (s *grbStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + values.PutValue(data, "true", "annotations", GrbVersion) + + err := s.addOwnerReference(data) + if err != nil { + if errors.IsNotFound(err) { + return nil, httperror.NewAPIError(httperror.NotFound, err.Error()) + } + return nil, err + } + + return s.Store.Create(apiContext, schema, data) +} + +// addOwnerReference ensures that a globalRolebinding will be deleted when the role it references +// is deleted +func (s *grbStore) addOwnerReference(data map[string]interface{}) error { + globalRoleName, _ := data["globalRoleId"].(string) + + globalRole, err := s.grLister.Get("", globalRoleName) + if err != nil { + return err + } + + ownerReference := v1.OwnerReference{ + APIVersion: globalRole.APIVersion, + Kind: globalRole.Kind, + Name: globalRole.Name, + UID: globalRole.UID, + } + values.PutValue(data, []v1.OwnerReference{ownerReference}, "ownerReferences") + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/hpa/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/hpa/store.go new file mode 100644 index 0000000..fdf130a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/hpa/store.go @@ -0,0 +1,60 @@ +package hpa + +import ( + "time" + + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +const ( + condition = "ScalingActive" + status = "False" + reason = "FailedGetResourceMetric" +) + +func NewIgnoreTransitioningErrorStore(store types.Store, d time.Duration, expectedState string) types.Store { + return &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + transitioning, _ := values.GetValue(data, "transitioning") + if transitioning != "error" { + return data, nil + } + conditions, ok := values.GetSlice(data, "conditions") + if !ok { + return data, nil + } + var found bool + for _, c := range conditions { + t, _ := values.GetValue(c, "type") + s, _ := values.GetValue(c, "status") + r, _ := values.GetValue(c, "reason") + if t == condition && s == status && r == reason { + found = true + break + } + } + created, ok := values.GetValue(data, "created") + if !ok { + return data, nil + } + t, err := time.Parse(time.RFC3339, created.(string)) + if err != nil { + return data, nil + } + if time.Now().Sub(t).Nanoseconds()-d.Nanoseconds() > 0 { + return data, nil + } + if found { + values.PutValue(data, "yes", "transitioning") + values.PutValue(data, "", "transitioningMessage") + if expectedState != "" { + values.PutValue(data, expectedState, "state") + } + } + return data, nil + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/ingress/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/ingress/store.go new file mode 100644 index 0000000..bf2b2e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/ingress/store.go @@ -0,0 +1,344 @@ +package ingress + +import ( + "context" + "crypto/md5" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "sort" + "strings" + + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/api/norman/store/workload" + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/managementagent/ingress" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +const ( + ingressStateAnnotation = "field.cattle.io/ingressState" +) + +func Wrap(manager *clustermanager.Manager, userContext *config.ScaledContext) func(types.Store) types.Store { + return func(store types.Store) types.Store { + return New(store, manager, userContext) + } +} + +type Store struct { + types.Store + legacyStore types.Store + userContext *config.ScaledContext + ClusterManager *clustermanager.Manager +} + +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + name, _ := data["name"].(string) + namespace, _ := data["namespaceId"].(string) + id := ref.FromStrings(namespace, name) + formatData(id, data, false) + clusterContext, err := p.downstreamClusterContext(apiContext) + if err != nil { + return nil, err + } + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + return p.Store.Create(apiContext, schema, data) + } + // TODO: remove when support for k8s 1.18 is dropped + return p.legacyStore.Create(apiContext, schema, data) +} + +func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + formatData(id, data, false) + clusterContext, err := p.downstreamClusterContext(apiContext) + if err != nil { + return nil, err + } + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + return p.Store.Update(apiContext, schema, data, id) + } + // TODO: remove when support for k8s 1.18 is dropped + return p.legacyStore.Update(apiContext, schema, data, id) +} + +func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + clusterContext, err := p.downstreamClusterContext(apiContext) + if err != nil { + return nil, err + } + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + return p.Store.List(apiContext, schema, opt) + } + // TODO: remove when support for k8s 1.18 is dropped + return p.legacyStore.List(apiContext, schema, opt) +} + +func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + clusterContext, err := p.downstreamClusterContext(apiContext) + if err != nil { + return nil, err + } + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + return p.Store.Watch(apiContext, schema, opt) + } + // TODO: remove when support for k8s 1.18 is dropped + return p.legacyStore.Watch(apiContext, schema, opt) +} + +func (p *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + clusterContext, err := p.downstreamClusterContext(apiContext) + if err != nil { + return nil, err + } + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + return p.Store.ByID(apiContext, schema, id) + } + // TODO: remove when support for k8s 1.18 is dropped + return p.legacyStore.ByID(apiContext, schema, id) +} + +// downstreamClusterContext is a helper for fetching the cluster context from the request. +// TODO: remove when support for k8s 1.18 is dropped +func (p *Store) downstreamClusterContext(apiContext *types.APIContext) (*config.UserContext, error) { + clusterName := p.ClusterManager.ClusterName(apiContext) + return p.ClusterManager.UserContext(clusterName) +} + +func formatData(id string, data map[string]interface{}, forFrontend bool) { + oldState := getState(data) + newState := map[string]string{} + + // transform default backend + if target, ok := values.GetValue(data, "defaultBackend"); ok && target != nil { + updateRule(convert.ToMapInterface(target), id, "", "/", forFrontend, data, oldState, newState) + } + + // transform rules + if paths, ok, flag := getPaths(data); ok { + for hostpath, target := range paths { + updateRule(target, id, hostpath.host, hostpath.path, forFrontend, data, oldState, newState) + } + if flag { + updateDataRules(data) + } + } + + updateCerts(data, forFrontend, oldState, newState) + setState(data, newState) + workload.SetPublicEndpointsFields(data) +} + +func updateDataRules(data map[string]interface{}) { + v, ok := values.GetValue(data, "rules") + if !ok { + return + } + var updated []interface{} + rules := convert.ToInterfaceSlice(v) + for _, rule := range rules { + converted := convert.ToMapInterface(rule) + paths, ok := converted["paths"] + if ok { + pathSlice := convert.ToInterfaceSlice(paths) + for index, target := range pathSlice { + targetMap := convert.ToMapInterface(target) + serviceID := convert.ToString(values.GetValueN(targetMap, "serviceId")) + if serviceID == "" { + pathSlice = append(pathSlice[:index], pathSlice[index+1:]...) + } + } + converted["paths"] = pathSlice + if len(pathSlice) != 0 { + updated = append(updated, rule) + } + } + } + values.PutValue(data, updated, "rules") +} + +func updateRule(target map[string]interface{}, id, host, path string, forFrontend bool, data map[string]interface{}, oldState map[string]string, newState map[string]string) { + targetData := convert.ToMapInterface(target) + port, _ := targetData["targetPort"] + serviceID, _ := targetData["serviceId"].(string) + namespace, name := ref.Parse(id) + stateKey := ingress.GetStateKey(name, namespace, host, path, convert.ToString(port)) + if forFrontend { + isService := true + if serviceValue, ok := oldState[stateKey]; ok && !convert.IsAPIObjectEmpty(serviceValue) { + targetData["workloadIds"] = strings.Split(serviceValue, "/") + isService = false + } + + if isService { + targetData["serviceId"] = fmt.Sprintf("%s:%s", data["namespaceId"].(string), serviceID) + } else { + delete(targetData, "serviceId") + } + } else { + workloadIDs := convert.ToStringSlice(targetData["workloadIds"]) + sort.Strings(workloadIDs) + if serviceID != "" { + splitted := strings.Split(serviceID, ":") + if len(splitted) > 1 { + serviceID = splitted[1] + } + } else { + serviceID = getServiceID(stateKey) + } + newState[stateKey] = strings.Join(workloadIDs, "/") + targetData["serviceId"] = serviceID + values.RemoveValue(targetData, "workloadIds") + } +} + +func getServiceID(stateKey string) string { + bytes, err := base64.URLEncoding.DecodeString(stateKey) + if err != nil { + return "" + } + + sum := md5.Sum(bytes) + hex := "ingress-" + hex.EncodeToString(sum[:]) + + return hex +} + +func getCertKey(key string) string { + return base64.URLEncoding.EncodeToString([]byte(key)) +} + +type hostPath struct { + host string + path string +} + +func getPaths(data map[string]interface{}) (map[hostPath]map[string]interface{}, bool, bool) { + v, ok := values.GetValue(data, "rules") + if !ok { + return nil, false, false + } + flag := false + result := make(map[hostPath]map[string]interface{}) + for _, rule := range convert.ToMapSlice(v) { + converted := convert.ToMapInterface(rule) + paths, ok := converted["paths"] + if ok { + for _, target := range convert.ToMapSlice(paths) { + targetMap := convert.ToMapInterface(target) + path := convert.ToString(targetMap["path"]) + key := hostPath{host: convert.ToString(converted["host"]), path: path} + if existing, ok := result[key]; ok { + flag = true + targetWorkloadIDs := convert.ToStringSlice(values.GetValueN(targetMap, "workloadIds")) + updated := convert.ToStringSlice(values.GetValueN(convert.ToMapInterface(existing), "workloadIds")) + targetWorkloadIDs = append(targetWorkloadIDs, updated...) + values.PutValue(targetMap, targetWorkloadIDs, "workloadIds") + } + result[key] = targetMap + } + } + } + + return result, true, flag +} + +func setState(data map[string]interface{}, stateMap map[string]string) { + content, err := json.Marshal(stateMap) + if err != nil { + logrus.Errorf("failed to save state on ingress: %v", data["id"]) + return + } + + values.PutValue(data, string(content), "annotations", ingressStateAnnotation) +} + +func getState(data map[string]interface{}) map[string]string { + state := map[string]string{} + + v, ok := values.GetValue(data, "annotations", ingressStateAnnotation) + if ok { + json.Unmarshal([]byte(convert.ToString(v)), &state) + } + + return state +} + +func updateCerts(data map[string]interface{}, forFrontend bool, oldState map[string]string, newState map[string]string) { + if forFrontend { + if certs, _ := values.GetSlice(data, "tls"); len(certs) > 0 { + for _, cert := range certs { + certName := convert.ToString(cert["certificateId"]) + certKey := getCertKey(certName) + id := oldState[certKey] + if id == "" { + cert["certificateId"] = fmt.Sprintf("%s:%s", convert.ToString(data["namespaceId"]), certName) + } else { + cert["certificateId"] = id + } + } + } + } else { + if certs, _ := values.GetSlice(data, "tls"); len(certs) > 0 { + for _, cert := range certs { + certificateID := convert.ToString(cert["certificateId"]) + id := strings.Split(certificateID, ":") + if len(id) == 2 { + certName := id[1] + certKey := getCertKey(certName) + newState[certKey] = certificateID + cert["certificateId"] = certName + } + } + } + } +} + +func New(store types.Store, manager *clustermanager.Manager, userContext *config.ScaledContext) types.Store { + // legacyStore is a norman proxy store object for the + // extensions/v1beta1/Ingress API that can be used to sidestep the registered + // networking.k8s.io/v1/Ingress API if the server doesn't support it. + // TODO: remove when support for k8s 1.18 is dropped + legacyStore := proxy.NewProxyStore( + context.Background(), + userContext.ClientGetter, + config.UserStorageContext, + scheme.Scheme, + []string{"apis"}, + "extensions", + "v1beta1", + "Ingress", + "ingresses", + ) + s := &Store{ + store, + legacyStore, + userContext, + manager, + } + return &transform.Store{ + Store: s, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + id, _ := data["id"].(string) + formatData(id, data, true) + setIngressState(data) + return data, nil + }, + } +} + +func setIngressState(data map[string]interface{}) { + lbStatus, ok := values.GetSlice(data, "status", "loadBalancer", "ingress") + if !ok || len(lbStatus) == 0 { + data["state"] = "initializing" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/namespace/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/namespace/store.go new file mode 100644 index 0000000..5da5169 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/namespace/store.go @@ -0,0 +1,182 @@ +package namespace + +import ( + "fmt" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + clusterclient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + mgmtclient "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/resourcequota" + mgmtschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/utils" +) + +const quotaField = "resourceQuota" +const containerResourceLimitField = "containerDefaultResourceLimit" + +func New(store types.Store) types.Store { + t := &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + anns, _ := data["annotations"].(map[string]interface{}) + if anns["management.cattle.io/system-namespace"] == "true" { + return nil, nil + } + return data, nil + }, + } + + return &Store{ + Store: t, + } +} + +type Store struct { + types.Store +} + +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if _, ok := data["resourceQuota"]; ok { + values.PutValue(data, "{\"conditions\": [{\"type\": \"InitialRolesPopulated\", \"status\": \"Unknown\", \"message\": \"Populating initial roles\"},{\"type\": \"ResourceQuotaValidated\", \"status\": \"Unknown\", \"message\": \"Validating resource quota\"}]}", + "annotations", "cattle.io/status") + } else { + values.PutValue(data, "{\"conditions\": [{\"type\": \"InitialRolesPopulated\", \"status\": \"Unknown\", \"message\": \"Populating initial roles\"}]}", + "annotations", "cattle.io/status") + } + + if err := p.validateResourceQuota(apiContext, schema, data, "", false); err != nil { + return nil, err + } + + return p.Store.Create(apiContext, schema, data) +} + +func (p *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := p.validateResourceQuota(apiContext, schema, data, id, true); err != nil { + return nil, err + } + + return p.Store.Update(apiContext, schema, data, id) +} + +func (p *Store) validateResourceQuota(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string, update bool) error { + quota := data[quotaField] + projectID := convert.ToString(data["projectId"]) + if update { + var ns clusterclient.Namespace + if err := access.ByID(apiContext, &schema.Version, clusterclient.NamespaceType, id, &ns); err != nil { + return err + } + projectID = ns.ProjectID + } + if projectID == "" { + return nil + } + var project mgmtclient.Project + if err := access.ByID(apiContext, &mgmtschema.Version, mgmtclient.ProjectType, projectID, &project); err != nil { + return err + } + if project.ResourceQuota == nil { + return nil + } + var nsQuota mgmtclient.NamespaceResourceQuota + if quota == nil { + if project.NamespaceDefaultResourceQuota == nil { + return nil + } + nsQuota = *project.NamespaceDefaultResourceQuota + } else { + if err := convert.ToObj(quota, &nsQuota); err != nil { + return err + } + } + + projectQuotaLimit, err := limitToLimit(project.ResourceQuota.Limit) + if err != nil { + return err + } + nsQuotaLimit, err := limitToLimit(nsQuota.Limit) + if err != nil { + return err + } + + // limits in namespace should include all limits defined on a project + projectQuotaLimitMap, err := convert.EncodeToMap(projectQuotaLimit) + if err != nil { + return err + } + + nsQuotaLimitMap, err := convert.EncodeToMap(nsQuotaLimit) + if err != nil { + return err + } + if len(nsQuotaLimitMap) != len(projectQuotaLimitMap) { + return httperror.NewFieldAPIError(httperror.MissingRequired, quotaField, "does not have all fields defined on a project quota") + } + + for k := range projectQuotaLimitMap { + if _, ok := nsQuotaLimitMap[k]; !ok { + return httperror.NewFieldAPIError(httperror.MissingRequired, quotaField, fmt.Sprintf("misses %s defined on a project quota", k)) + } + } + + // validate resource quota + mu := resourcequota.GetProjectLock(projectID) + mu.Lock() + defer mu.Unlock() + + var nsLimits []*v32.ResourceQuotaLimit + var namespaces []clusterclient.Namespace + options := &types.QueryOptions{ + Conditions: []*types.QueryCondition{ + types.NewConditionFromString("projectId", types.ModifierEQ, projectID), + }, + } + if err := access.List(apiContext, &schema.Version, clusterclient.NamespaceType, options, &namespaces); err != nil { + return err + } + for _, n := range namespaces { + if n.ID == id { + continue + } + if n.ResourceQuota == nil { + continue + } + nsLimit, err := limitToLimitCluster(n.ResourceQuota.Limit) + if err != nil { + return err + } + nsLimits = append(nsLimits, nsLimit) + } + + // set default resource limit + crlMap := convert.ToMapInterface(data[containerResourceLimitField]) + if len(crlMap) <= 0 { + data[containerResourceLimitField] = project.ContainerDefaultResourceLimit + } + + isFit, exceeded, err := resourcequota.IsQuotaFit(nsQuotaLimit, nsLimits, projectQuotaLimit) + if err != nil || isFit { + return err + } + + return httperror.NewFieldAPIError(httperror.MaxLimitExceeded, quotaField, fmt.Sprintf("exceeds projectLimit on fields: %s", utils.FormatResourceList(exceeded))) +} + +func limitToLimit(from *mgmtclient.ResourceQuotaLimit) (*v32.ResourceQuotaLimit, error) { + var to v32.ResourceQuotaLimit + err := convert.ToObj(from, &to) + return &to, err +} + +func limitToLimitCluster(from *clusterclient.ResourceQuotaLimit) (*v32.ResourceQuotaLimit, error) { + var to v32.ResourceQuotaLimit + err := convert.ToObj(from, &to) + return &to, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nocondition/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nocondition/store.go new file mode 100644 index 0000000..1172e48 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nocondition/store.go @@ -0,0 +1,25 @@ +package nocondition + +import ( + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +// NewWrapper returns a wrapper store which sets your object to transitioning state if your object has no conditions. +func NewWrapper(state, message string) func(types.Store) types.Store { + return func(store types.Store) types.Store { + return &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + conditions, ok := values.GetSlice(data, "conditions") + if !ok || len(conditions) == 0 { + values.PutValue(data, state, "state") + values.PutValue(data, "yes", "transitioning") + values.PutValue(data, message, "transitioningMessage") + } + return data, nil + }, + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/node/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/node/store.go new file mode 100644 index 0000000..a103893 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/node/store.go @@ -0,0 +1,203 @@ +package node + +import ( + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/api/norman/store/workload" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "k8s.io/apimachinery/pkg/util/validation" +) + +const apiUpdate = "management.cattle.io/apiUpdate" + +type nodeStore struct { + types.Store +} + +func SetupStore(schema *types.Schema) { + schema.Store = &transform.Store{ + Store: nodeStore{ + Store: schema.Store, + }, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + workload.SetPublicEndpointsFields(data) + setState(data) + return data, nil + }, + } +} + +func (n nodeStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + setName := false + for _, cond := range opt.Conditions { + if cond.Field == "name" && cond.ToCondition().Modifier == types.ModifierEQ { + setName = true + break + } + } + + datas, err := n.Store.List(apiContext, schema, opt) + if err != nil || !setName { + return datas, err + } + + for _, data := range datas { + if !convert.IsAPIObjectEmpty(data["name"]) { + continue + } + + if !convert.IsAPIObjectEmpty(data["nodeName"]) { + data["name"] = data["nodeName"] + continue + } + + if !convert.IsAPIObjectEmpty(data["requestedHostname"]) { + data["name"] = data["requestedHostname"] + continue + } + } + + return datas, err +} + +func (n nodeStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := n.validateDesiredTaints(data); err != nil { + return nil, err + } + format(data) + nodePoolID := n.getNodePoolID(apiContext, schema, data, "") + if nodePoolID != "" { + if err := n.validateHostname(schema, data); err != nil { + return nil, err + } + } + return n.Store.Create(apiContext, schema, data) +} + +func (n nodeStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := n.validateDesiredTaints(data); err != nil { + return nil, err + } + + node := client.Node{} + err := access.ByID(apiContext, apiContext.Version, apiContext.Type, id, &node) + if err != nil { + return nil, err + } + + changed := v32.MetadataUpdate{ + Labels: diff(convert.ToMapInterface(data["labels"]), node.Labels), + Annotations: diff(convert.ToMapInterface(data["annotations"]), node.Annotations), + } + + data["metadataUpdate"] = changed + format(data) + + return n.Store.Update(apiContext, schema, data, id) +} + +func diff(desired map[string]interface{}, actual map[string]string) (result v32.MapDelta) { + if len(desired) == 0 { + return + } + + result.Delete = map[string]bool{} + result.Add = map[string]string{} + + for k, v := range desired { + if actual[k] != v { + result.Add[k] = convert.ToString(v) + } + } + + for k := range actual { + if _, exists := desired[k]; !exists { + result.Delete[k] = true + } + } + + return +} + +func format(data map[string]interface{}) { + data["desiredNodeTaints"] = data["taints"] + trueValue := true + data["updateTaintsFromAPI"] = &trueValue +} + +func setState(data map[string]interface{}) { + if data["state"] == "draining" { + return + } + if convert.ToBool(values.GetValueN(data, "unschedulable")) { + conditions, _ := values.GetSlice(data, "conditions") + for _, condition := range conditions { + condType := values.GetValueN(condition, "type") + if convert.ToString(condType) == "Drained" && + convert.ToString(values.GetValueN(condition, "status")) == "True" { + data["state"] = "drained" + return + } + } + data["state"] = "cordoned" + } +} + +func (n nodeStore) getNodePoolID(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) string { + _, ok := data["nodePoolId"] + if ok { + return data["nodePoolId"].(string) + } + if id != "" { + existingNode, err := n.ByID(apiContext, schema, id) + if err != nil { + return "" + } + _, ok := existingNode["nodePoolId"].(string) + if ok { + return existingNode["nodePoolId"].(string) + } + } + return "" +} + +func (n nodeStore) validateHostname(schema *types.Schema, data map[string]interface{}) error { + hostName := data["name"] + if hostName != nil { + errs := validation.IsDNS1123Label(hostName.(string)) + if len(errs) != 0 { + return httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("invalid value %s: %s", hostName.(string), + strings.Join(errs, ","))) + } + } + + return nil +} + +func (n nodeStore) validateDesiredTaints(data map[string]interface{}) error { + taints, ok := values.GetSlice(data, "taints") + if !ok { + return nil + } + uniqueSet := map[string]struct{}{} + for _, taint := range taints { + // key and effect is required field in API, so we can safely assume that key and effect exist. + key, _ := values.GetValue(taint, "key") + effect, _ := values.GetValue(taint, "effect") + uniqueKey := fmt.Sprintf("%v:%v", key, effect) + if _, ok := uniqueSet[uniqueKey]; ok { + return httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("invalid taints, duplicated key %s and effect %s", key, effect)) + } + uniqueSet[uniqueKey] = struct{}{} + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nodetemplate/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nodetemplate/store.go new file mode 100644 index 0000000..82a9c2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/nodetemplate/store.go @@ -0,0 +1,225 @@ +package nodetemplate + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" +) + +type nodeTemplateStore struct { + types.Store + NodePoolLister v3.NodePoolLister + NodeLister v3.NodeLister + CloudCredentialLister corev1.SecretLister +} + +type transformer struct { + NodeTemplateClient v3.NodeTemplateInterface +} + +type nodeTemplateIDs struct { + fullOriginalID string + originalID string + originalNs string + fullMigratedID string + migratedID string + migratedNs string +} + +func Wrap(store types.Store, npLister v3.NodePoolLister, nodeLister v3.NodeLister, secretLister corev1.SecretLister, ntClient v3.NodeTemplateInterface) types.Store { + t := &transformer{ + NodeTemplateClient: ntClient, + } + s := &transform.Store{ + Store: store, + Transformer: t.filterLegacyTemplates, + } + return &nodeTemplateStore{ + Store: s, + NodePoolLister: npLister, + NodeLister: nodeLister, + CloudCredentialLister: secretLister, + } +} + +func (t *transformer) filterLegacyTemplates(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + ns, _ := data["namespaceId"].(string) + id, _ := data["id"].(string) + if ns != namespace.NodeTemplateGlobalNamespace { + // nodetemplate may not have been migrated yet, enqueue + t.NodeTemplateClient.Controller().Enqueue(ns, strings.TrimPrefix(id, ns+":")) + return nil, nil + } + return data, nil +} + +func (s *nodeTemplateStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + ids := getAllIDs(id) + data, err := s.Store.ByID(apiContext, schema, ids.fullMigratedID) + if err != nil { + return nil, replaceIDInError(err, ids.migratedID, ids.originalID, ids.migratedNs, ids.originalNs) + } + + data["namespaceId"] = ids.originalNs + data["id"] = ids.fullOriginalID + return data, nil +} + +// getAllIDs returns the namespace and trimmed ID of the original ID +// and its corresponding migrated ID +func getAllIDs(id string) nodeTemplateIDs { + originalNs, originalID := ref.Parse(id) + fullMigratedID := getMigratedID(originalNs, originalID) + migratedNs, migratedID := ref.Parse(fullMigratedID) + return nodeTemplateIDs{ + fullOriginalID: id, + originalID: originalID, + originalNs: originalNs, + fullMigratedID: fullMigratedID, + migratedID: migratedID, + migratedNs: migratedNs, + } +} + +func getMigratedID(ns, id string) string { + if ns == namespace.NodeTemplateGlobalNamespace { + return fmt.Sprintf("%s:%s", ns, id) + } + + return fmt.Sprintf("%s:nt-%s-%s", namespace.NodeTemplateGlobalNamespace, ns, id) +} + +func replaceIDInError(err error, id, newID, ns, newNs string) error { + if apiError, ok := err.(*httperror.APIError); ok { + msg := strings.Replace(apiError.Message, id, newID, -1) + msg = strings.Replace(msg, ns, newNs, -1) + err = httperror.NewAPIError(apiError.Code, msg) + } + return err +} + +func (s *nodeTemplateStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + ids := getAllIDs(id) + pools, err := s.NodePoolLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + for _, pool := range pools { + if pool.Spec.NodeTemplateName == ids.fullMigratedID { + logrus.Debugf("nodeTemplateStore: NodeTemplateName [%v] is in use by node pool [%s]", pool.Spec.NodeTemplateName, ids.fullMigratedID) + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "Template is in use by a node pool.") + } + } + nodes, err := s.NodeLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + for _, node := range nodes { + if node.Spec.NodeTemplateName == ids.fullMigratedID { + logrus.Debugf("nodeTemplateStore: NodeTemplateName [%v] is in use by node [%s]", node.Spec.NodeTemplateName, ids.fullMigratedID) + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, "Template is in use by a node.") + } + } + + data, err := s.Store.Delete(apiContext, schema, ids.fullMigratedID) + if err != nil { + return nil, replaceIDInError(err, ids.migratedID, ids.originalID, ids.migratedNs, ids.originalNs) + } + + if data != nil { + data["namespaceId"] = ids.originalNs + data["id"] = ids.fullOriginalID + } + + return data, nil +} + +func (s *nodeTemplateStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := s.replaceCloudCredFields(apiContext, data); err != nil { + return data, err + } + return s.Store.Create(apiContext, schema, data) +} + +func (s *nodeTemplateStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if err := s.replaceCloudCredFields(apiContext, data); err != nil { + return data, err + } + + ids := getAllIDs(id) + data, err := s.Store.Update(apiContext, schema, data, ids.fullMigratedID) + if err != nil { + return nil, replaceIDInError(err, ids.migratedID, ids.originalID, ids.migratedNs, ids.originalNs) + } + + data["namespaceId"] = ids.originalNs + data["id"] = ids.fullOriginalID + return data, nil +} + +func (s *nodeTemplateStore) replaceCloudCredFields(apiContext *types.APIContext, data map[string]interface{}) error { + credID := convert.ToString(values.GetValueN(data, "cloudCredentialId")) + if credID == "" { + return nil + } + var accessCred client.CloudCredential + if err := access.ByID(apiContext, &managementschema.Version, client.CloudCredentialType, credID, &accessCred); err != nil { + if apiError, ok := err.(*httperror.APIError); ok { + if apiError.Code.Status == httperror.PermissionDenied.Status || apiError.Code.Status == httperror.NotFound.Status { + return httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("cloud credential not found")) + } + } + return httperror.WrapAPIError(err, httperror.ServerError, fmt.Sprintf("error accessing cloud credential")) + } + ns, name := ref.Parse(credID) + if ns == "" || name == "" { + return httperror.NewAPIError(httperror.InvalidReference, fmt.Sprintf("invalid cloud credential %s", credID)) + } + cred, err := s.CloudCredentialLister.Get(namespace.GlobalNamespace, name) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, fmt.Sprintf("error getting cloud cred %s: %v", credID, err)) + } + if len(cred.Data) == 0 { + return httperror.WrapAPIError(err, httperror.MissingRequired, fmt.Sprintf("empty credID data %s", credID)) + } + configName, credConfigName := "", "" + for key := range cred.Data { + splitKey := strings.SplitN(key, "-", 2) + if len(splitKey) == 2 && strings.HasSuffix(splitKey[0], "credentialConfig") { + configName = strings.Replace(splitKey[0], "credential", "", 1) + credConfigName = splitKey[0] + break + } + } + if configName == "" { + return httperror.WrapAPIError(err, httperror.MissingRequired, fmt.Sprintf("empty configName for credID %s", configName)) + } + toReplace := convert.ToMapInterface(values.GetValueN(data, configName)) + if len(toReplace) == 0 { + return nil + } + var fields []string + for key := range cred.Data { + splitKey := strings.SplitN(key, "-", 2) + if len(splitKey) == 2 && splitKey[0] == credConfigName { + delete(toReplace, splitKey[1]) + fields = append(fields, splitKey[1]) + } + } + logrus.Debugf("replaceCloudCredFields: %v for credID %s", fields, credID) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/noopwatching/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/noopwatching/store.go new file mode 100644 index 0000000..eb57bac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/noopwatching/store.go @@ -0,0 +1,17 @@ +package noopwatching + +import "github.com/rancher/norman/types" + +func Wrap(store types.Store) types.Store { + return &Store{ + Store: store, + } +} + +type Store struct { + types.Store +} + +func (s *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/password.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/password.go new file mode 100644 index 0000000..2ce6dac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/password.go @@ -0,0 +1,33 @@ +package store + +import ( + "fmt" + "strings" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func GetValueForPasswordField(name string, secrets v1.SecretInterface) (string, error) { + var value string + if name == "" { + return value, fmt.Errorf("empty secret name %s", name) + } + split := strings.SplitN(name, ":", 2) + if len(split) != 2 { + return value, fmt.Errorf("not a secret reference %s", name) + } + if split[0] != namespace.GlobalNamespace { + return value, fmt.Errorf("not rancher referenced secret %s", name) + } + secret, err := secrets.Controller().Lister().Get(namespace.GlobalNamespace, split[1]) + if err != nil && errors.IsNotFound(err) { + secret, err = secrets.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{}) + } + if err != nil { + return value, err + } + return string(secret.Data[split[1]]), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/store.go new file mode 100644 index 0000000..377f803 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/password/store.go @@ -0,0 +1,399 @@ +package store + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + projectschema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + separator = ".." +) + +var ( + arrKeys = map[string]string{"fluentServers": "endpoint"} + ignoreFields = map[string]bool{"appliedSpec": true, "failedSpec": true} +) + +/* +arrKeys = map{arrayFieldName: uniqueKeyName} +When password fields are not passed from api, uniqueKeyName is used to search matching entry in existing array from db +Make sure all nested array fields from pwdTypes are added and validate entries don't have identical uniqueKeyName +*/ + +type PasswordStore struct { + Schemas map[string]*types.Schema + Fields map[string]map[string]interface{} + Stores map[string]types.Store + secretStore v1.SecretInterface + nsStore v1.NamespaceInterface +} + +func SetPasswordStore(schemas *types.Schemas, secretStore v1.SecretInterface, nsStore v1.NamespaceInterface) { + modifyProjectTypes := map[string]bool{ + "githubPipelineConfig": true, + "gitlabPipelineConfig": true, + } + + pwdStore := &PasswordStore{ + Schemas: map[string]*types.Schema{}, + Fields: map[string]map[string]interface{}{}, + Stores: map[string]types.Store{}, + secretStore: secretStore, + nsStore: nsStore, + } + + //add your parent schema name here + pwdTypes := []string{ + "clusterlogging", + "projectlogging", + "globaldnsprovider", + } + + for _, storeType := range pwdTypes { + var schema *types.Schema + if _, ok := modifyProjectTypes[storeType]; ok { + schema = schemas.Schema(&projectschema.Version, storeType) + } else { + schema = schemas.Schema(&managementschema.Version, storeType) + } + if schema != nil && schema.Store != nil { + data := getFields(schema, schemas, map[string]bool{}) + id := schema.ID + pwdStore.Stores[id] = schema.Store + pwdStore.Fields[id] = data + schema.Store = pwdStore + ans, _ := json.Marshal(data) + logrus.Debugf("password fields %s", string(ans)) + } + } +} + +func (p *PasswordStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if err := p.replacePasswords(p.Fields[schema.ID], data, nil); err != nil { + return nil, err + } + return p.Stores[schema.ID].Create(apiContext, schema, data) +} + +func (p *PasswordStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return p.Stores[schema.ID].ByID(apiContext, schema, id) +} + +func (p *PasswordStore) Context() types.StorageContext { + return config.ManagementStorageContext +} + +func (p *PasswordStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + data, err := p.Stores[schema.ID].ByID(apiContext, schema, id) + if err != nil { + return data, err + } + p.deleteSecretData(data, schema.ID) + return p.Stores[schema.ID].Delete(apiContext, schema, id) +} + +func (p *PasswordStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + return p.Stores[schema.ID].List(apiContext, schema, opt) +} + +func (p *PasswordStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + existing, err := p.Stores[schema.ID].ByID(apiContext, schema, id) + if err != nil { + return nil, err + } + if err := p.replacePasswords(p.Fields[schema.ID], data, existing); err != nil { + return nil, err + } + return p.Stores[schema.ID].Update(apiContext, schema, data, id) +} + +func (p *PasswordStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + return p.Stores[schema.ID].Watch(apiContext, schema, opt) +} + +func (p *PasswordStore) replacePasswords(sepData, data, existing map[string]interface{}) error { + /* + sepData: path to all password fields built recursively from schema + data: incoming data from api + existing: data from db by id + + Looping through sepData, + if separator == reached end, check to update/create or replace password fields + else recursive call for map/array + */ + if len(data) == 0 { + // nothing to put in data, delete existing secret for this path + return p.deleteExistingSecrets(sepData, existing) + } + for sepKey, sepVal := range sepData { + if convert.ToString(sepVal) == separator { + if val2, ok := data[sepKey]; ok { + if err := p.putSecretData(data, existing, sepKey, convert.ToString(val2), false); err != nil { + return err + } + } else if _, ok := existing[sepKey]; ok { + if err := p.putSecretData(data, existing, sepKey, "", true); err != nil { + return err + } + } else if data != nil { + logrus.Debugf("[%v] not present in incoming data, secret not stored", sepKey) + } + } else if val2, ok := data[sepKey]; ok { + valArr := convert.ToMapSlice(val2) + existArr := convert.ToMapSlice(existing[sepKey]) + if valArr == nil { + if err := p.replacePasswords(convert.ToMapInterface(sepVal), convert.ToMapInterface(data[sepKey]), convert.ToMapInterface(existing[sepKey])); err != nil { + return err + } + } + // build matching array entries from existing data {uniqueKeyName: index} + existingDataMap := map[string]int{} + searchKey := arrKeys[sepKey] + if searchKey != "" { + for i, each := range existArr { + if name, ok := each[searchKey]; ok { + if strName := convert.ToString(name); strName != "" { + existingDataMap[convert.ToString(name)] = i + } + } + } + } + for _, each := range valArr { + exists := false + if name, ok := each[searchKey]; ok { + if strName := convert.ToString(name); strName != "" { + if ind, ok := existingDataMap[strName]; ok { + if err := p.replacePasswords(convert.ToMapInterface(sepVal), each, existArr[ind]); err != nil { + return err + } + exists = true + delete(existingDataMap, strName) + } + } + } + if !exists { + if err := p.replacePasswords(convert.ToMapInterface(sepVal), each, nil); err != nil { + return err + } + } + } + // delete remaining secrets from existingArr + for _, ind := range existingDataMap { + if err := p.replacePasswords(convert.ToMapInterface(sepVal), nil, existArr[ind]); err != nil { + return err + } + } + } + } + return nil +} + +func (p *PasswordStore) deleteExistingSecrets(sepData, existing map[string]interface{}) error { + /* + Similar to function replacePasswords, except when data is nil, + traverse through existing map to find secrets for deletion + */ + for sepKey, sepVal := range sepData { + if convert.ToString(sepVal) == separator { + if exisVal, ok := existing[sepKey]; ok { + splitKey := strings.SplitN(convert.ToString(exisVal), ":", 2) + if len(splitKey) == 2 { + if err := p.deleteSecret(splitKey[1], splitKey[0]); err != nil { + return err + } + } + } + } else { + existArr := convert.ToMapSlice(existing[sepKey]) + if existArr == nil { + if err := p.deleteExistingSecrets(convert.ToMapInterface(sepData[sepKey]), convert.ToMapInterface(existing[sepKey])); err != nil { + return err + } + continue + } + for _, each := range existArr { + if err := p.deleteExistingSecrets(convert.ToMapInterface(sepData[sepKey]), each); err != nil { + return err + } + } + } + } + return nil +} + +func (p *PasswordStore) putSecretData(data, existing map[string]interface{}, key, val string, replace bool) error { + var ( + name string + err error + ) + if existing != nil { + if exisVal, ok := existing[key]; ok { + splitKey := strings.SplitN(convert.ToString(exisVal), ":", 2) + if len(splitKey) == 2 && splitKey[0] == namespace.GlobalNamespace { + name = splitKey[1] + } + } + } + if replace { + if name == "" { + return fmt.Errorf("replacePasswords: secret name not available in existing data") + } + data[key] = fmt.Sprintf("%s:%s", namespace.GlobalNamespace, name) + return nil + } + if name == "" { + name, err = randomtoken.Generate() + if err != nil { + return fmt.Errorf("replacePasswords: error generating random name %v", err) + } + } + if err := p.createOrUpdateSecrets(val, name, namespace.GlobalNamespace); err != nil { + return fmt.Errorf("replacePasswords: createOrUpdate secrets %v", err) + } + data[key] = fmt.Sprintf("%s:%s", namespace.GlobalNamespace, name) + return nil +} + +func (p *PasswordStore) buildSecretNames(data1 map[string]interface{}, data2 map[string]interface{}, secrets map[string]bool) { + for key1, val1 := range data1 { + if val2, ok := data2[key1]; ok { + if convert.ToString(val1) == separator { + val := convert.ToString(val2) + if val != "" { + secrets[val] = true + } + } else { + valArr := convert.ToMapSlice(val2) + if valArr == nil { + p.buildSecretNames(convert.ToMapInterface(val1), convert.ToMapInterface(val2), secrets) + } else { + for _, each := range valArr { + p.buildSecretNames(convert.ToMapInterface(val1), each, secrets) + } + } + } + } + } +} + +func (p *PasswordStore) createOrUpdateSecrets(data, name, namespace string) error { + _, err := p.nsStore.Get(namespace, metav1.GetOptions{}) + if err != nil && errors.IsNotFound(err) { + if _, err := p.nsStore.Create(&corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }); err != nil && !errors.IsAlreadyExists(err) { + return err + } + } + if err != nil { + return err + } + name = strings.ToLower(name) + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + StringData: map[string]string{name: data}, + Type: corev1.SecretTypeOpaque, + } + existing, err := p.secretStore.GetNamespaced(namespace, name, metav1.GetOptions{}) + if errors.IsNotFound(err) { + _, err = p.secretStore.Create(secret) + return err + } else if err != nil { + return err + } + if !reflect.DeepEqual(existing.StringData, secret.StringData) { + existing.StringData = secret.StringData + _, err = p.secretStore.Update(existing) + } + return err +} + +func (p *PasswordStore) deleteSecretData(data map[string]interface{}, id string) error { + secrets := map[string]bool{} + p.buildSecretNames(p.Fields[id], data, secrets) + logrus.Infof("deleteSecretData: %v", secrets) + for secret := range secrets { + split := strings.SplitN(secret, ":", 2) + if len(split) != 2 || split[0] != namespace.GlobalNamespace { + continue + } + if err := p.deleteSecret(split[1], split[0]); err != nil { + return err + } + } + return nil +} + +func (p *PasswordStore) getSecret(input []string) (string, error) { + returned := "" + secret, err := p.secretStore.GetNamespaced(input[0], input[1], metav1.GetOptions{}) + if err != nil { + return "", err + } + for key, val := range secret.Data { + if key == input[1] { + returned = string(val) + } + } + return returned, nil +} + +func (p *PasswordStore) deleteSecret(name string, namespace string) error { + err := p.secretStore.DeleteNamespaced(namespace, name, &metav1.DeleteOptions{}) + if err != nil && errors.IsNotFound(err) { + return nil + } + return err +} + +func getFields(schema *types.Schema, schemas *types.Schemas, arrFields map[string]bool) map[string]interface{} { + data := map[string]interface{}{} + for name, field := range schema.ResourceFields { + fieldType := field.Type + if strings.HasPrefix(fieldType, "array") { + fieldType = strings.Split(fieldType, "[")[1] + fieldType = fieldType[:len(fieldType)-1] + arrFields[fieldType] = true + } + checkSchema := schemas.Schema(&managementschema.Version, fieldType) + if checkSchema != nil { + if _, ok := ignoreFields[name]; ok { + continue + } + value := getFields(checkSchema, schemas, arrFields) + if len(value) > 0 { + data[name] = value + if _, ok := arrFields[name]; ok { + if _, ok := arrKeys[fmt.Sprintf("%ss", name)]; !ok { + logrus.Warnf("passwordFields: assigned searchKey not present for array[%v], editing might not work as expected for passwords", name) + } + } + } + } else { + if field.Type == "password" { + data[name] = separator + } + } + } + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/owner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/owner.go new file mode 100644 index 0000000..9983785 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/owner.go @@ -0,0 +1,140 @@ +package pod + +import ( + "fmt" + "strings" + + lru "github.com/hashicorp/golang-lru" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + "github.com/rancher/rancher/pkg/ref" + schema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +var ( + ownerCache, _ = lru.New(100000) +) + +type key struct { + SubContext string + Namespace string + Kind string + Name string +} + +type value struct { + Kind string + Name string +} + +func getOwnerWithKind(apiContext *types.APIContext, namespace, ownerKind, name string) (string, string, error) { + subContext := apiContext.SubContext["/v3/schemas/project"] + if subContext == "" { + subContext = apiContext.SubContext["/v3/schemas/cluster"] + } + if subContext == "" { + logrus.Warnf("failed to find subcontext to lookup replicaSet owner") + return "", "", nil + } + + key := key{ + SubContext: subContext, + Namespace: namespace, + Kind: strings.ToLower(ownerKind), + Name: name, + } + + val, ok := ownerCache.Get(key) + if ok { + value, _ := val.(value) + return value.Kind, value.Name, nil + } + + data := map[string]interface{}{} + if err := access.ByID(apiContext, &schema.Version, ownerKind, ref.FromStrings(namespace, name), &data); err != nil { + return "", "", err + } + + kind, name := getOwner(data) + + if !workload.WorkloadKinds[kind] { + kind = "" + name = "" + } + + ownerCache.Add(key, value{ + Kind: kind, + Name: name, + }) + + return kind, name, nil +} + +func getOwner(data map[string]interface{}) (string, string) { + ownerReferences, ok := values.GetSlice(data, "ownerReferences") + if !ok { + return "", "" + } + + for _, ownerReference := range ownerReferences { + controller, _ := ownerReference["controller"].(bool) + if !controller { + continue + } + + kind, _ := ownerReference["kind"].(string) + name, _ := ownerReference["name"].(string) + return kind, name + } + + return "", "" +} + +func SaveOwner(apiContext *types.APIContext, kind, name string, data map[string]interface{}) { + parentKind, parentName := getOwner(data) + namespace, _ := data["namespaceId"].(string) + + subContext := apiContext.SubContext["/v3/schemas/project"] + if subContext == "" { + subContext = apiContext.SubContext["/v3/schemas/cluster"] + } + if subContext == "" { + return + } + + key := key{ + SubContext: subContext, + Namespace: namespace, + Kind: strings.ToLower(kind), + Name: name, + } + + ownerCache.Add(key, value{ + Kind: parentKind, + Name: parentName, + }) +} + +func resolveWorkloadID(apiContext *types.APIContext, data map[string]interface{}) string { + kind, name := getOwner(data) + if kind == "" || !workload.WorkloadKinds[kind] { + return "" + } + + namespace, _ := data["namespaceId"].(string) + + if ownerKind := strings.ToLower(kind); ownerKind == workload.ReplicaSetType || ownerKind == workload.JobType { + k, n, err := getOwnerWithKind(apiContext, namespace, ownerKind, name) + if err != nil { + return "" + } + if k != "" { + kind, name = k, n + } + } + + return strings.ToLower(fmt.Sprintf("%s:%s:%s", kind, namespace, name)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/store.go new file mode 100644 index 0000000..7379d5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/pod/store.go @@ -0,0 +1,70 @@ +package pod + +import ( + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/clustermanager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/client-go/tools/cache" +) + +const ( + nodeNameIdx = "nodeNameId" +) + +func New(store types.Store, clusterManager *clustermanager.Manager, scaledContext *config.ScaledContext) types.Store { + return &transform.Store{ + Store: store, + Transformer: newPT(clusterManager, scaledContext), + } +} + +func newPT(clusterManager *clustermanager.Manager, scaledContext *config.ScaledContext) transform.TransformerFunc { + scaledContext.Management.Nodes("").Controller().Informer().AddIndexers(cache.Indexers{ + nodeNameIdx: func(obj interface{}) ([]string, error) { + node := obj.(*v3.Node) + name := node.Status.NodeName + if name == "" { + return nil, nil + } + return []string{ref.FromStrings(node.Namespace, name)}, nil + }, + }) + + pt := &podTransformer{ + clusterManager: clusterManager, + nodeIndexer: scaledContext.Management.Nodes("").Controller().Informer().GetIndexer(), + } + return pt.transformer +} + +type podTransformer struct { + clusterManager *clustermanager.Manager + nodeIndexer cache.Indexer +} + +func (p *podTransformer) transformer(context *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + if data == nil { + return data, nil + } + owner := resolveWorkloadID(context, data) + if owner != "" { + data["workloadId"] = owner + } + + clusterName := p.clusterManager.ClusterName(context) + nodeName, _ := data["nodeId"].(string) + nodes, err := p.nodeIndexer.ByIndex(nodeNameIdx, ref.FromStrings(clusterName, nodeName)) + if err != nil { + return nil, err + } + + if len(nodes) == 1 { + node := nodes[0].(*v3.Node) + data["nodeId"] = ref.FromStrings(node.Namespace, node.Name) + } + + return data, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/preference/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/preference/store.go new file mode 100644 index 0000000..2fc0d8e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/preference/store.go @@ -0,0 +1,40 @@ +package preference + +import ( + "strings" + + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/api/norman/store/userscope" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" +) + +const ( + NamespaceID = client.PreferenceFieldNamespaceId +) + +func NewStore(nsClient v1.NamespaceInterface, store types.Store) types.Store { + return userscope.NewStore(nsClient, + &transform.Store{ + Store: store, + Transformer: transformer, + }) +} + +func transformer(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opts *types.QueryOptions) (map[string]interface{}, error) { + if data == nil { + return nil, nil + } + + ns := convert.ToString(data[NamespaceID]) + id := convert.ToString(data[types.ResourceFieldID]) + + id = strings.TrimPrefix(id, ns+":") + + data[client.PreferenceFieldName] = id + data[types.ResourceFieldID] = id + + return data, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/project_setter_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/project_setter_test.go new file mode 100644 index 0000000..b432154 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/project_setter_test.go @@ -0,0 +1,74 @@ +package projectsetter + +import ( + "net/http" + "testing" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/project" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Tests that getMatchingNamespaces returns the proper amount namespaces given duplicates, empty slices, and multiple +// matching namespaces. +func TestOptionsCorrectNamespaces(t *testing.T) { + dummyAPIContext := &types.APIContext{ + Method: http.MethodGet, + SubContext: map[string]string{"/v3/schemas/project": "p-test123"}, + } + + namespaceList := []*v1.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + Annotations: map[string]string{project.ProjectIDAnn: "p-test123"}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ns2", + Annotations: map[string]string{project.ProjectIDAnn: "p-test1234"}, + }, + }, + } + + namespaces := getMatchingNamespaces(*dummyAPIContext, namespaceList) + + if len(namespaces) == 0 { + t.Error("Matching namespace was not returned") + } + + namespaceList = []*v1.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + Annotations: map[string]string{project.ProjectIDAnn: "p-test123"}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ns2", + Annotations: map[string]string{project.ProjectIDAnn: "p-test1234"}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ns3", + Annotations: map[string]string{project.ProjectIDAnn: "p-test123"}, + }, + }, + } + + namespaces = getMatchingNamespaces(*dummyAPIContext, namespaceList) + if len(namespaces) != 2 { + t.Error("Should be able to find multiple namespaces") + } + + namespaceList = []*v1.Namespace{} + namespaces = getMatchingNamespaces(*dummyAPIContext, namespaceList) + + if len(namespaces) > 0 { + t.Error("Namespaces should not be returned from empty namespace list") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/store.go new file mode 100644 index 0000000..23507c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/projectsetter/store.go @@ -0,0 +1,187 @@ +package projectsetter + +import ( + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + "github.com/rancher/rancher/pkg/clustermanager" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/project" + k8sv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func New(store types.Store, manager *clustermanager.Manager) types.Store { + t := &transformer{ + ClusterManager: manager, + } + return &transform.Store{ + Store: projectSetter{ + store, + manager, + }, + Transformer: t.object, + ListTransformer: t.list, + StreamTransformer: t.stream, + } +} + +type projectSetter struct { + types.Store + + ClusterManager *clustermanager.Manager +} + +type transformer struct { + ClusterManager *clustermanager.Manager +} + +func (p projectSetter) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + options := *opt + if err := p.setOptionsNamespaces(apiContext, &options); err != nil { + return nil, err + } + + return p.Store.List(apiContext, schema, &options) +} + +func (p projectSetter) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if _, ok := data[client.NamespaceFieldProjectID]; ok { + delete(data, client.NamespaceFieldProjectID) + } + return p.Store.Create(apiContext, schema, data) +} + +func (p projectSetter) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if _, ok := data[client.NamespaceFieldProjectID]; ok { + delete(data, client.NamespaceFieldProjectID) + } + return p.Store.Update(apiContext, schema, data, id) +} + +func (t *transformer) object(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + t.lookupAndSetProjectID(apiContext, schema, data) + return data, nil +} + +func (t *transformer) list(apiContext *types.APIContext, schema *types.Schema, data []map[string]interface{}, opt *types.QueryOptions) ([]map[string]interface{}, error) { + namespaceLister := t.lister(apiContext, schema) + if namespaceLister == nil { + return data, nil + } + + for _, item := range data { + setProjectID(namespaceLister, item) + } + + return data, nil +} + +// Retrieves project from api sub-context, then finds associated namespaces. If found, assigns to options. +func (p projectSetter) setOptionsNamespaces(apiContext *types.APIContext, opt *types.QueryOptions) error { + clusterName := p.ClusterManager.ClusterName(apiContext) + if clusterName == "" { + return nil + } + + clusterContext, err := p.ClusterManager.UserContext(clusterName) + if err != nil { + return err + } + + namespaces, err := clusterContext.Core.Namespaces("").Controller().Lister().List("", labels.NewSelector()) + if err != nil { + return err + } + + matchingNamespaces := getMatchingNamespaces(*apiContext, namespaces) + + if opt == nil { + opt = &types.QueryOptions{} + } + + // It is important this field is set to not nil even if there are no namespaces, so that no namespaces are queried instead of all namespaces + if opt.Namespaces == nil { + opt.Namespaces = make([]string, 0) + } + + // Not using namespaces in opt.Conditions to avoid conflicts + opt.Namespaces = append(opt.Namespaces, matchingNamespaces...) + + return nil +} + +func getMatchingNamespaces(apiContext types.APIContext, namespaces []*k8sv1.Namespace) []string { + var matchingNamespaces []string + + projectID := apiContext.SubContext["/v3/schemas/project"] + if projectID == "" { + return matchingNamespaces + } + + for _, ns := range namespaces { + if ns.Annotations[project.ProjectIDAnn] == projectID { + matchingNamespaces = append(matchingNamespaces, ns.Name) + } + } + return matchingNamespaces +} + +func (t *transformer) stream(apiContext *types.APIContext, schema *types.Schema, data chan map[string]interface{}, opt *types.QueryOptions) (chan map[string]interface{}, error) { + namespaceLister := t.lister(apiContext, schema) + if namespaceLister == nil { + return data, nil + } + + return convert.Chan(data, func(data map[string]interface{}) map[string]interface{} { + setProjectID(namespaceLister, data) + return data + }), nil +} + +func (t *transformer) lister(apiContext *types.APIContext, schema *types.Schema) v1.NamespaceLister { + if _, ok := schema.ResourceFields[client.NamespaceFieldProjectID]; !ok || schema.ID == client.NamespaceType { + return nil + } + + clusterName := t.ClusterManager.ClusterName(apiContext) + if clusterName == "" { + return nil + } + + clusterContext, err := t.ClusterManager.UserContext(clusterName) + if err != nil { + return nil + } + + return clusterContext.Core.Namespaces("").Controller().Lister() +} + +func (t *transformer) lookupAndSetProjectID(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) { + namespaceLister := t.lister(apiContext, schema) + if namespaceLister == nil { + return + } + + setProjectID(namespaceLister, data) +} + +func setProjectID(namespaceLister v1.NamespaceLister, data map[string]interface{}) { + if data == nil { + return + } + + ns, _ := data["namespaceId"].(string) + projectID, _ := data[client.NamespaceFieldProjectID].(string) + if projectID != "" { + return + } + + nsObj, err := namespaceLister.Get("", ns) + if err != nil { + return + } + + data[client.NamespaceFieldProjectID] = nsObj.Annotations["field.cattle.io/projectId"] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store.go new file mode 100644 index 0000000..eb2d6f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store.go @@ -0,0 +1,53 @@ +package roletemplate + +import ( + "fmt" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + RTVersion = "cleanup.cattle.io/rtUpgradeCluster" + OldRTVersion = "field.cattle.io/rtUpgrade" +) + +func Wrap(store types.Store, rtLister v3.RoleTemplateLister) types.Store { + return &rtStore{ + Store: store, + rtLister: rtLister, + } +} + +type rtStore struct { + types.Store + + rtLister v3.RoleTemplateLister +} + +func (s *rtStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + roleTemplates, err := s.rtLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + + // check if roletemplate is referenced as parent by any other roletemplate + for _, rt := range roleTemplates { + for _, parent := range rt.RoleTemplateNames { + if parent == id { + return nil, httperror.NewAPIError(httperror.Conflict, fmt.Sprintf("roletemplate [%s] cannot be deleted because roletemplate [%s] inherits from it", id, rt.Name)) + } + } + } + return s.Store.Delete(apiContext, schema, id) +} + +func (s *rtStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + + values.PutValue(data, "true", "metadata", "annotations", RTVersion) + + return s.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store_test.go new file mode 100644 index 0000000..16d276e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/roletemplate/store_test.go @@ -0,0 +1,93 @@ +package roletemplate + +import ( + "testing" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +type dummyStore struct{} + +// testWithInherited attempt delete given key and inserts the key in the inherited +// list for a roletemplate if insertInLister is true. +func testWithInherited(key string, insertInLister bool) (map[string]interface{}, error) { + insert := "randomstringnotusedkey" + if insertInLister { + insert = key + } + mockRTLister := &fakes.RoleTemplateListerMock{ + ListFunc: mockList(insert), + } + + testStore := Wrap(dummyStore{}, mockRTLister) + + return testStore.Delete(nil, nil, key) +} + +func mockList(insert string) func(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) { + return func(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) { + return []*v3.RoleTemplate{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt1", + }, + RoleTemplateNames: []string{"asdf", "asdf"}, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt2", + }, + RoleTemplateNames: []string{"aasdfsdf", insert, "adsasdff"}, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "rt3", + }, + RoleTemplateNames: []string{}, + }}, nil + } +} + +// TestDelete confirms that the store prevents a roletemplate from being deleted if another roletemplate inherits from it +func TestDelete(t *testing.T) { + assert := assert.New(t) + + // test when roletemplate is not a parent of another roletemplate, should not cause error + _, err := testWithInherited("somekey", false) + assert.Nil(err) + + // test when roletemplate is a parent of another roletemplate, should cause error + _, err = testWithInherited("somekey", true) + assert.Contains(err.Error(), "Conflict 409: roletemplate [somekey] cannot be deleted because roletemplate [rt2] inherits from it") +} + +func (ds dummyStore) Context() types.StorageContext { + return types.StorageContext("test") +} +func (ds dummyStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, nil +} +func (ds dummyStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + return data, nil +} + +func (ds dummyStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/scoped/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/scoped/store.go new file mode 100644 index 0000000..27b09b6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/scoped/store.go @@ -0,0 +1,43 @@ +package scoped + +import ( + "strings" + + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" +) + +type Store struct { + types.Store + key string +} + +func NewScopedStore(key string, store types.Store) *Store { + return &Store{ + Store: &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + if data == nil { + return data, nil + } + v := convert.ToString(data[key]) + if !strings.HasSuffix(v, ":"+convert.ToString(data[client.ProjectFieldNamespaceId])) { + data[key] = data[client.ProjectFieldNamespaceId] + } + data[client.ProjectFieldNamespaceId] = nil + return data, nil + }, + }, + key: key, + } +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if data != nil { + parts := strings.Split(convert.ToString(data[s.key]), ":") + data["namespaceId"] = parts[len(parts)-1] + } + return s.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/secret/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/secret/store.go new file mode 100644 index 0000000..aa06a47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/secret/store.go @@ -0,0 +1,75 @@ +package secret + +import ( + "context" + "strings" + + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/api/norman/store/cert" + "github.com/rancher/rancher/pkg/api/scheme" + client "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +type Store struct { + types.Store +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + t := convert.ToString(data["kind"]) + t = strings.TrimPrefix(t, "namespaced") + t = convert.Uncapitalize(t) + data["kind"] = t + return s.Store.Create(apiContext, schema, data) +} + +func NewNamespacedSecretStore(ctx context.Context, clientGetter proxy.ClientGetter) *Store { + secretsStore := proxy.NewProxyStore(ctx, clientGetter, + config.UserStorageContext, + scheme.Scheme, + []string{"api"}, + "", + "v1", + "Secret", + "secrets") + return &Store{ + Store: &transform.Store{ + Store: secretsStore, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + if data == nil { + return data, nil + } + anns, _ := data["annotations"].(map[string]interface{}) + if anns["secret.user.cattle.io/secret"] == "true" { + return nil, nil + } + if data["projectId"] != nil { + fieldProjectID, _ := data["projectId"].(string) + projectID := strings.Split(fieldProjectID, ":") + id := "" + if len(projectID) == 2 { + id = projectID[1] + } + if id == data["namespaceId"] { + return nil, nil + } + } + parts := strings.Split(convert.ToString(data["type"]), "/") + parts[len(parts)-1] = "namespaced" + convert.Capitalize(parts[len(parts)-1]) + data["type"] = strings.Join(parts, "/") + if data["type"] != client.NamespacedCertificateType { + return data, nil + } + if err := cert.AddCertInfo(data); err != nil { + logrus.Errorf("Error %v parsing cert %v. Will not display correctly in UI", err, data["name"]) + return data, nil + } + return data, nil + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/service/service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/service/service.go new file mode 100644 index 0000000..c7f5792 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/service/service.go @@ -0,0 +1,109 @@ +package service + +import ( + "fmt" + "net" + "strconv" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/intstr" +) + +func New(store types.Store) types.Store { + return &Store{ + store, + } +} + +type Store struct { + types.Store +} + +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if schema.ID == "dnsRecord" { + if convert.IsAPIObjectEmpty(data["hostname"]) { + data["kind"] = "ClusterIP" + data["clusterIp"] = nil + } else { + data["kind"] = "ExternalName" + data["clusterIp"] = "" + } + } + // Check for unset ipFamilyPolicy, for headless services this defaults to dual stack but will not function if the cluster does not have dual stack properly configured (IPv6 CIDRs) + // If its not explicitly configured in the request, we default to SingleStack + if schema.ID == "service" || schema.ID == "dnsRecord" { + logrus.Tracef("Service: Create: data [%v]", data) + if val, ok := data["kind"]; ok { + if val == "ClusterIP" { + if val, ok := data["clusterIp"]; ok { + if val == nil || val == "None" { + if val, ok := data["ipFamilyPolicy"]; !ok || val == nil { + logrus.Debugf("Setting ipFamilyPolicy to SingleStack for service name [%s] service kind [%s]", data["name"], data["kind"]) + data["ipFamilyPolicy"] = "SingleStack" + } + } + } + } + } + } + formatData(schema, data) + err := p.validateNonSpecialIP(schema, data) + if err != nil { + return nil, err + } + return p.Store.Create(apiContext, schema, data) +} + +func formatData(schema *types.Schema, data map[string]interface{}) { + var ports []interface{} + if schema.ID == "service" { + ports = convert.ToInterfaceSlice(data["ports"]) + } + // append default port as sky dns won't work w/o at least one port being set + if len(ports) == 0 { + servicePort := v3.ServicePort{ + Port: 42, + TargetPort: intstr.Parse(strconv.FormatInt(42, 10)), + Protocol: "TCP", + Name: "default", + } + m, err := convert.EncodeToMap(servicePort) + if err != nil { + logrus.Warnf("Failed to transform service port to map: %v", err) + return + } + ports = append(ports, m) + } + data["ports"] = ports +} + +func (p *Store) validateNonSpecialIP(schema *types.Schema, data map[string]interface{}) error { + if schema.ID == "dnsRecord" { + ips := data["ipAddresses"] + if ips != nil { + for _, ip := range ips.([]interface{}) { + IP := net.ParseIP(ip.(string)) + if IP == nil { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("%s must be a valid IP address", IP)) + } + if IP.IsUnspecified() { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("%s may not be unspecified (0.0.0.0)", IP)) + } + if IP.IsLoopback() { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("%s may not be in the loopback range (127.0.0.0/8)", IP)) + } + if IP.IsLinkLocalUnicast() { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("%s may not be in the link-local range (169.254.0.0/16)", IP)) + } + if IP.IsLinkLocalMulticast() { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("%s may not be in the link-local multicast range (224.0.0.0/24)", IP)) + } + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/setting/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/setting/store.go new file mode 100644 index 0000000..0d70340 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/setting/store.go @@ -0,0 +1,107 @@ +package setting + +import ( + "fmt" + "os" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/api/norman/customization/setting" + "github.com/rancher/rancher/pkg/settings" +) + +type Store struct { + types.Store +} + +const ( + UserUpdateLabel = "io.cattle.user.updated" +) + +var MetadataSettings = map[string]bool{ + settings.KubernetesVersion.Name: true, + settings.KubernetesVersionsCurrent.Name: true, + settings.KubernetesVersionsDeprecated.Name: true, +} + +func New(store types.Store) types.Store { + return &Store{ + &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + v, ok := data["value"] + id := convert.ToString(data["id"]) + value, ok2 := os.LookupEnv(settings.GetEnvKey(id)) + switch { + case ok2: + data["value"] = value + data["customized"] = false + data["source"] = "env" + + case !ok || v == "": + data["value"] = data["default"] + data["customized"] = false + data["source"] = "default" + default: + data["customized"] = true + data["source"] = "db" + } + return data, nil + }, + }, + } +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + if slice.ContainsString(setting.ReadOnlySettings, id) { + return nil, httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("Cannot delete readOnly setting %s.", id)) + } + + return s.Store.Delete(apiContext, schema, id) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + if _, ok := MetadataSettings[id]; ok { + labels := map[string]interface{}{} + if val, ok := data["labels"]; ok { + labels = convert.ToMapInterface(val) + } + if val, ok := data["value"]; ok && convert.ToString(val) == "" { + labels[UserUpdateLabel] = "false" + } else { + if id == settings.KubernetesVersion.Name || id == settings.KubernetesVersionsCurrent.Name { + if err := validate(id, convert.ToString(val)); err != nil { + return nil, err + } + } + labels[UserUpdateLabel] = "true" + } + data["labels"] = labels + } + return s.Store.Update(apiContext, schema, data, id) +} + +func validate(id, value string) error { + var k8sVersion string + var k8sCurrVersions []string + + if id == settings.KubernetesVersion.Name { + k8sVersion = value + k8sCurrVersions = strings.Split(settings.KubernetesVersionsCurrent.Get(), ",") + } else { + k8sCurrVersions = strings.Split(value, ",") + k8sVersion = settings.KubernetesVersion.Get() + } + + for _, curr := range k8sCurrVersions { + if curr == k8sVersion { + return nil + } + } + + return httperror.NewAPIError(httperror.MissingRequired, "default k8s-version must be present in k8s-versions-current") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store.go new file mode 100644 index 0000000..858e74e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store.go @@ -0,0 +1,50 @@ +package storageclass + +import ( + "strings" + + "github.com/rancher/norman/types" +) + +const ( + StorageAccountType = "storageaccounttype" + SkuName = "skuName" + storageKind = "kind" + defaultStorageType = "Standard_LRS" + parameters = "parameters" + provisioner = "provisioner" + AzureDisk = "kubernetes.io/azure-disk" +) + +func Wrap(store types.Store) types.Store { + return &storageClassStore{ + store, + } +} + +type storageClassStore struct { + types.Store +} + +func (s *storageClassStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if data[provisioner] == AzureDisk { + params, ok := data[parameters].(map[string]interface{}) + if !ok { + params = make(map[string]interface{}) + data[parameters] = params + } + + kind, _ := params[storageKind].(string) + kind = strings.ToLower(kind) + if kind == "shared" || kind == "" { + saType, _ := params[StorageAccountType].(string) + skuName, _ := params[SkuName].(string) + + if saType == "" && skuName == "" { + params[StorageAccountType] = defaultStorageType + } + } + } + + return s.Store.Create(apiContext, schema, data) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store_test.go new file mode 100644 index 0000000..4a5e6a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/storageclass/store_test.go @@ -0,0 +1,89 @@ +package storageclass + +import ( + "testing" + + "github.com/rancher/norman/types" + "k8s.io/utils/pointer" + + "github.com/stretchr/testify/assert" +) + +type dummyStore struct{} + +func createWithFields(store types.Store, prov string, kind *string, storageaccounttype *string) (map[string]interface{}, error) { + testData := map[string]interface{}{ + "provisioner": prov, + } + + if kind != nil { + testData["parameters"] = map[string]interface{}{"kind": *kind} + + if storageaccounttype != nil { + testData["parameters"].(map[string]interface{})["storageaccounttype"] = *storageaccounttype + } + } + + return store.Create(nil, nil, testData) +} + +func TestCreate(t *testing.T) { + assert := assert.New(t) + testStore := Wrap(dummyStore{}) + + // create with a storageaccounttype of nil should give the storage class a default value for the field + data, err := createWithFields(testStore, AzureDisk, pointer.StringPtr("shared"), nil) + assert.Nil(err) + assert.Equal("Standard_LRS", data["parameters"].(map[string]interface{})["storageaccounttype"]) + + // create with a kind that is not shared should not make a change to the storageaccounttype + data, err = createWithFields(testStore, AzureDisk, pointer.StringPtr("dedicated"), nil) + assert.Nil(err) + assert.Equal(nil, data["parameters"].(map[string]interface{})["storageaccounttype"]) + + // create with a storageaccounttype of empty string should give the storage class a default value for the field + data, err = createWithFields(testStore, AzureDisk, pointer.StringPtr("shared"), pointer.StringPtr("")) + assert.Nil(err) + assert.Equal("Standard_LRS", data["parameters"].(map[string]interface{})["storageaccounttype"]) + + // create with a storageaccounttype of any non-empty string should should not change the storageaccounttype + data, err = createWithFields(testStore, AzureDisk, pointer.StringPtr("shared"), pointer.StringPtr("premium")) + assert.Nil(err) + assert.Equal("premium", data["parameters"].(map[string]interface{})["storageaccounttype"]) + + // create with nil params should create with default value for storageaccounttype + data, err = createWithFields(testStore, AzureDisk, nil, nil) + assert.Nil(err) + assert.Equal("Standard_LRS", data["parameters"].(map[string]interface{})["storageaccounttype"]) + + // creaate with empty strings should create with default value for storageaccounttype + data, err = createWithFields(testStore, AzureDisk, pointer.StringPtr(""), pointer.StringPtr("")) + assert.Nil(err) + assert.Equal("Standard_LRS", data["parameters"].(map[string]interface{})["storageaccounttype"]) +} + +func (ds dummyStore) Context() types.StorageContext { + return types.StorageContext("test") +} +func (ds dummyStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, nil +} +func (ds dummyStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + return data, nil +} + +func (ds dummyStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + return nil, nil +} + +func (ds dummyStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/userscope/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/userscope/store.go new file mode 100644 index 0000000..777c50c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/userscope/store.go @@ -0,0 +1,131 @@ +package userscope + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + NamespaceID = client.PreferenceFieldNamespaceId +) + +type Store struct { + Store types.Store + nsClient v1.NamespaceInterface +} + +func NewStore(nsClient v1.NamespaceInterface, store types.Store) *Store { + return &Store{ + Store: store, + nsClient: nsClient, + } +} + +func (s *Store) Context() types.StorageContext { + return s.Store.Context() +} + +func (s *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil { + return nil, err + } + + return s.Store.ByID(apiContext, schema, addNamespace(user, id)) +} + +func (s *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil { + return nil, err + } + + if opt == nil { + return nil, nil + } + + opt.Conditions = append(opt.Conditions, types.EQ(NamespaceID, getNamespace(user))) + return s.Store.List(apiContext, schema, opt) +} + +func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil || data == nil { + return nil, err + } + + ns := getNamespace(user) + _, err = s.nsClient.Get(ns, metav1.GetOptions{}) + if err != nil { + s.nsClient.Create(&corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "management.cattle.io/system-namespace": "true", + }, + Name: ns, + }, + }) + } + + data[NamespaceID] = getNamespace(user) + return s.Store.Create(apiContext, schema, data) +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil { + return nil, err + } + + return s.Store.Update(apiContext, schema, data, addNamespace(user, id)) +} + +func (s *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil { + return nil, err + } + + return s.Store.Delete(apiContext, schema, addNamespace(user, id)) +} + +func (s *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + user, err := getUser(apiContext) + if err != nil { + return nil, err + } + + if opt == nil { + return nil, nil + } + + opt.Conditions = append(opt.Conditions, types.EQ(NamespaceID, getNamespace(user))) + return s.Store.Watch(apiContext, schema, opt) +} + +func getUser(apiContext *types.APIContext) (string, error) { + user := apiContext.Request.Header.Get("Impersonate-User") + if user == "" { + return "", httperror.NewAPIError(httperror.NotFound, "missing user") + } + return user, nil +} + +func addNamespace(user, id string) string { + parts := strings.SplitN(id, ":", 2) + if len(parts) == 1 { + return fmt.Sprintf("%s:%s", getNamespace(user), parts[0]) + } + return fmt.Sprintf("%s:%s", getNamespace(user), parts[1]) +} + +func getNamespace(user string) string { + return user +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/aggregate_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/aggregate_store.go new file mode 100644 index 0000000..c447104 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/aggregate_store.go @@ -0,0 +1,235 @@ +package workload + +import ( + "encoding/base64" + "errors" + "fmt" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/project/v3" + projectclient "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + corev1 "k8s.io/api/core/v1" +) + +const ( + SelectorLabel = "workload.user.cattle.io/workloadselector" +) + +type AggregateStore struct { + Stores map[string]types.Store + Schemas map[string]*types.Schema + FieldToSchemaID map[string]string +} + +func NewAggregateStore(schemas ...*types.Schema) *AggregateStore { + a := &AggregateStore{ + Stores: map[string]types.Store{}, + Schemas: map[string]*types.Schema{}, + FieldToSchemaID: map[string]string{}, + } + + for _, schema := range schemas { + a.Schemas[strings.ToLower(schema.ID)] = schema + a.Stores[strings.ToLower(schema.ID)] = schema.Store + fieldKey := fmt.Sprintf("%sConfig", schema.ID) + a.FieldToSchemaID[fieldKey] = strings.ToLower(schema.ID) + } + + return a +} + +func (a *AggregateStore) Context() types.StorageContext { + return config.UserStorageContext +} + +func (a *AggregateStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + store, schemaType, err := a.getStore(id) + if err != nil { + return nil, err + } + _, shortID := splitTypeAndID(id) + data, err := store.ByID(apiContext, a.Schemas[schemaType], shortID) + if err != nil { + return nil, err + } + return capabilitiesToUpperCase(data), nil +} + +func (a *AggregateStore) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { + readerGroup, ctx := errgroup.WithContext(apiContext.Request.Context()) + apiContext.Request = apiContext.Request.WithContext(ctx) + + events := make(chan map[string]interface{}) + for _, schema := range a.Schemas { + streamStore(readerGroup, apiContext, schema, opt, events) + } + + go func() { + readerGroup.Wait() + close(events) + }() + return events, nil +} + +func (a *AggregateStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + items := make(chan map[string]interface{}) + g, ctx := errgroup.WithContext(apiContext.Request.Context()) + submit := func(schema *types.Schema, store types.Store) { + g.Go(func() error { + data, err := store.List(apiContext, schema, opt) + if err != nil { + return err + } + for _, item := range data { + select { + case items <- capabilitiesToUpperCase(item): + case <-ctx.Done(): + return ctx.Err() + } + } + return nil + }) + } + + for typeName, store := range a.Stores { + submit(a.Schemas[typeName], store) + } + + go func() { + g.Wait() + close(items) + }() + + var result []map[string]interface{} + for item := range items { + result = append(result, item) + } + + return result, g.Wait() +} + +func (a *AggregateStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + // deployment is default if otherwise is not specified + kind := client.DeploymentType + toSchema := a.Schemas[kind] + toStore := a.Stores[kind] + for field, schemaID := range a.FieldToSchemaID { + if val, ok := data[field]; ok && val != nil { + toSchema = a.Schemas[schemaID] + toStore = a.Stores[schemaID] + break + } + } + + return toStore.Create(apiContext, toSchema, data) +} + +func store(registries map[string]projectclient.RegistryCredential, domainToCreds map[string][]corev1.LocalObjectReference, name string) { + for registry := range registries { + rd, err := GetRegistryDomain(registry) + if err != nil { + logrus.Errorf("unable to get domain for registry=%v err=%v", registry, err) + continue + } + secretRef := corev1.LocalObjectReference{Name: name} + if _, ok := domainToCreds[rd]; ok { + domainToCreds[rd] = append(domainToCreds[rd], secretRef) + } else { + domainToCreds[rd] = []corev1.LocalObjectReference{secretRef} + } + } +} + +func resolveWorkloadID(schemaID string, data map[string]interface{}) string { + return fmt.Sprintf("%s-%s-%s", schemaID, data["namespaceId"], data["name"]) +} + +func (a *AggregateStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + store, schemaType, err := a.getStore(id) + if err != nil { + return nil, err + } + _, shortID := splitTypeAndID(id) + return store.Update(apiContext, a.Schemas[schemaType], data, shortID) +} + +func (a *AggregateStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + store, schemaType, err := a.getStore(id) + if err != nil { + return nil, err + } + _, shortID := splitTypeAndID(id) + return store.Delete(apiContext, a.Schemas[schemaType], shortID) +} + +func (a *AggregateStore) getStore(id string) (types.Store, string, error) { + typeName, _ := splitTypeAndID(id) + store, ok := a.Stores[typeName] + if !ok { + return nil, "", httperror.NewAPIError(httperror.NotFound, "failed to find type "+typeName) + } + return store, typeName, nil +} + +func streamStore(eg *errgroup.Group, apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions, result chan map[string]interface{}) { + eg.Go(func() error { + events, err := schema.Store.Watch(apiContext, schema, opt) + if err != nil || events == nil { + if err != nil { + logrus.Errorf("failed on subscribe %s: %v", schema.ID, err) + } + return err + } + + logrus.Debugf("watching %s", schema.ID) + + for e := range events { + result <- capabilitiesToUpperCase(e) + } + + return errors.New("disconnect") + }) +} + +func splitTypeAndID(id string) (string, string) { + parts := strings.SplitN(id, ":", 2) + if len(parts) < 2 { + // Must conform + return "", "" + } + return parts[0], parts[1] +} + +func getKey(key string) string { + return base64.URLEncoding.EncodeToString([]byte(key)) +} + +// Related issue: #12619 +// In Rancher API schema, Capabilities is defined as enum type and `ALL` is one of the options, which means Rancher API only accepts `ALL`. +// However, Kubernetes accepts both `all` and `ALL“ for capabilities, if user uses kubectl and use `all“ in the yaml, edit will fail in Rancher UI. +// Thus we should convert `all“ to `ALL` so that UI always get `ALL`. +func capabilitiesToUpperCase(data map[string]interface{}) map[string]interface{} { + containers := convert.ToMapSlice(data["containers"]) + elements := []string{"capDrop", "capAdd"} + + for _, c := range containers { + for _, element := range elements { + caps := convert.ToStringSlice(c[element]) + newCaps := []string{} + if caps != nil { + for _, cap := range caps { + newCaps = append(newCaps, strings.ToUpper(cap)) + } + c[element] = newCaps + } + } + } + + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/transform_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/transform_store.go new file mode 100644 index 0000000..eb07c3b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/transform_store.go @@ -0,0 +1,109 @@ +package workload + +import ( + "strings" + + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/definition" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/api/norman/store/pod" + "github.com/sirupsen/logrus" +) + +var ( + hideOwnerReferenceKinds = map[string]bool{"CronJob": true, "Deployment": true} +) + +func NewTransformStore(store types.Store) types.Store { + return &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + var hide bool + if opt != nil && opt.Options["hidden"] == "true" { + hide = false + } else if opt != nil && opt.Options["ByID"] == "true" { + hide = false + } else { + hide = hideByOwner(data) + } + typeName := definition.GetType(data) + name, _ := data["name"].(string) + if hide && data["ownerReferences"] != nil { + pod.SaveOwner(apiContext, typeName, name, data) + return nil, nil + } + id, _ := data["id"].(string) + if typeName != "" && id != "" { + data["id"] = strings.ToLower(typeName) + ":" + id + } + SetPublicEndpointsFields(data) + nodeName := convert.ToString(values.GetValueN(data, "nodeId")) + if nodeName != "" { + state := getState(data) + nodeID := state[getKey(nodeName)] + delete(data, "nodeId") + values.PutValue(data, nodeID, "scheduling", "node", "nodeId") + } + setTransitioning(apiContext, data) + return data, nil + }, + } +} + +func SetPublicEndpointsFields(data map[string]interface{}) { + if val, ok := data["publicEndpoints"]; ok { + eps := convert.ToInterfaceSlice(val) + for _, ep := range eps { + epMap, err := convert.EncodeToMap(ep) + if err != nil { + logrus.Errorf("Failed to convert public endpoint: %v", err) + continue + } + epMap["serviceId"] = epMap["serviceName"] + epMap["nodeId"] = epMap["nodeName"] + epMap["ingressId"] = epMap["ingressName"] + } + } +} + +func setTransitioning(apiContext *types.APIContext, data map[string]interface{}) { + if data["transitioning"] == "yes" || data["transitioning"] == "error" { + return + } + workloadType := convert.ToString(values.GetValueN(data, "type")) + switch workloadType { + case "/v3/project/schemas/deployment": + update(data, "deploymentStatus", "replicas", "readyReplicas") + case "/v3/project/schemas/daemonSet": + update(data, "daemonSetStatus", "desiredNumberScheduled", "numberReady") + case "/v3/project/schemas/statefulSet": + update(data, "statefulSetStatus", "replicas", "readyReplicas") + } +} + +func update(data map[string]interface{}, statusField string, desiredField string, currField string) { + if desiredNum, err := convert.ToNumber(values.GetValueN(data, statusField, desiredField)); err == nil { + if readyNum, err := convert.ToNumber(values.GetValueN(data, statusField, currField)); err == nil { + if desiredNum != readyNum { + data["state"] = "updating" + data["transitioning"] = "yes" + data["transitioningMessage"] = "upgrading workload" + } + } + } +} + +func hideByOwner(data map[string]interface{}) bool { + if data["ownerReferences"] != nil { + owners := convert.ToMapSlice(data["ownerReferences"]) + for _, owner := range owners { + ownerKind := convert.ToString(owner["kind"]) + if _, ok := hideOwnerReferenceKinds[ownerKind]; ok { + return true + } + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils.go new file mode 100644 index 0000000..755e598 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils.go @@ -0,0 +1,18 @@ +package workload + +import ( + "net/url" + "strings" +) + +func GetRegistryDomain(registry string) (string, error) { + if strings.HasPrefix(registry, "http://") || + strings.HasPrefix(registry, "https://") { + domain, err := url.Parse(registry) + if err != nil { + return registry, err + } + return domain.Host, nil + } + return registry, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils_test.go new file mode 100644 index 0000000..89dab26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/utils_test.go @@ -0,0 +1,31 @@ +package workload + +import ( + "testing" + + "github.com/sirupsen/logrus" +) + +func TestGetRegistryDomain(t *testing.T) { + var d string + var err error + + tests := [][]string{ + {"docker.io", "docker.io"}, + {"http://index.docker.io/v1/", "index.docker.io"}, + {"https://index.docker.io/v1/", "index.docker.io"}, + {"http://my.private.registry:5000/v1", "my.private.registry:5000"}, + {"https://my.private.registry/v1", "my.private.registry"}, + } + + for _, test := range tests { + d, err = GetRegistryDomain(test[0]) + if err != nil { + t.Fail() + } + if d != test[1] { + logrus.Infof("d: %v", d) + t.Fail() + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/workload_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/workload_store.go new file mode 100644 index 0000000..5605ff6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/norman/store/workload/workload_store.go @@ -0,0 +1,414 @@ +package workload + +import ( + "encoding/json" + "fmt" + "path" + "strconv" + "strings" + + "github.com/docker/distribution/reference" + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/api/norman/customization/workload" + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + projectclient "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/clustermanager" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + projectschema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +func NewWorkloadAggregateStore(schemas *types.Schemas, manager *clustermanager.Manager) { + workloadSchema := schemas.Schema(&schema.Version, "workload") + store := NewAggregateStore(schemas.Schema(&schema.Version, "deployment"), + schemas.Schema(&schema.Version, "replicaSet"), + schemas.Schema(&schema.Version, "replicationController"), + schemas.Schema(&schema.Version, "daemonSet"), + schemas.Schema(&schema.Version, "statefulSet"), + schemas.Schema(&schema.Version, "job"), + schemas.Schema(&schema.Version, "cronJob")) + + workloadConfig := workload.Config{ + ClusterManager: manager, + Schemas: store.Schemas, + } + + for _, s := range store.Schemas { + if s.ID == "deployment" { + s.Formatter = workloadConfig.DeploymentFormatter + } else { + s.Formatter = workloadConfig.Formatter + } + } + workloadSchema.Store = store + workloadSchema.ActionHandler = workloadConfig.ActionHandler + workloadSchema.LinkHandler = workload.Handler{}.LinkHandler + workloadSchema.Validator = workload.Validator +} + +func NewCustomizeStore(store types.Store) types.Store { + return &CustomizeStore{ + Store: NewTransformStore(store), + } +} + +type CustomizeStore struct { + types.Store +} + +func (s *CustomizeStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + setSelector(schema.ID, data) + setWorkloadSpecificDefaults(schema.ID, data) + setSecrets(apiContext, data, convert.ToString(data["namespaceId"]), true) + if err := setPorts(convert.ToString(data["name"]), data); err != nil { + return nil, err + } + setScheduling(apiContext, data) + setStrategy(data) + + err := s.validateStatefulSetVolume(schema, data) + if err != nil { + return nil, err + } + return s.Store.Create(apiContext, schema, data) +} + +func (s *CustomizeStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + splitted := strings.Split(id, ":") + if err := setPorts(splitted[1], data); err != nil { + return nil, err + } + setScheduling(apiContext, data) + setStrategy(data) + if err := setSecrets(apiContext, data, splitted[0], false); err != nil { + return nil, err + } + + err := s.validateStatefulSetVolume(schema, data) + if err != nil { + return nil, err + } + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *CustomizeStore) validateStatefulSetVolume(schema *types.Schema, data map[string]interface{}) error { + if schema.ID == "statefulSet" { + // retrieve volumeMounts.subPath + containers, _ := values.GetSlice(data, "containers") + for i := range containers { + container := containers[i] + volumeMounts, _ := values.GetSlice(container, "volumeMounts") + for j := range volumeMounts { + vmnt := volumeMounts[j] + subPath := convert.ToString(vmnt["subPath"]) + err := s.validateSubPath(subPath) + if err != nil { + return err + } + } + } + } + return nil +} + +// This validate will make sure subPath: +// 1. is not abs path +// 2. does not have any element which is ".." +func (s *CustomizeStore) validateSubPath(subPath string) error { + if path.IsAbs(subPath) { + return httperror.NewAPIError(httperror.MissingRequired, fmt.Sprintf("Invalid value: Sub Path in Volume %v must be a relative path", subPath)) + } + parts := strings.Split(subPath, "/") + for _, item := range parts { + if item == ".." { + return httperror.NewAPIError(httperror.MissingRequired, fmt.Sprintf("Invalid value: Sub Path in Volume %v must not contain '..'", subPath)) + } + } + return nil +} + +func (s *CustomizeStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + shortID := id + if strings.Count(id, ":") > 1 { + _, shortID = splitTypeAndID(id) + } + return s.Store.ByID(apiContext, schema, shortID) +} + +func setScheduling(apiContext *types.APIContext, data map[string]interface{}) { + if _, ok := values.GetValue(data, "scheduling", "node"); ok { + if nodeID := convert.ToString(values.GetValueN(data, "scheduling", "node", "nodeId")); nodeID != "" { + nodeName := getNodeName(apiContext, nodeID) + values.PutValue(data, nodeName, "scheduling", "node", "nodeId") + state := getState(data) + state[getKey(nodeName)] = nodeID + setState(data, state) + } else { + values.PutValue(data, "", "nodeId") + } + } +} + +func setStrategy(data map[string]interface{}) { + strategy, ok := values.GetValue(data, "deploymentConfig", "strategy") + if ok && convert.ToString(strategy) == "Recreate" { + values.RemoveValue(data, "deploymentConfig", "maxSurge") + values.RemoveValue(data, "deploymentConfig", "maxUnavailable") + } +} + +func setSelector(schemaID string, data map[string]interface{}) { + setSelector := false + isJob := strings.EqualFold(schemaID, "job") || strings.EqualFold(schemaID, "cronJob") + if convert.IsAPIObjectEmpty(data["selector"]) && !isJob { + setSelector = true + } + if setSelector { + workloadID := resolveWorkloadID(schemaID, data) + // set selector + data["selector"] = map[string]interface{}{ + "matchLabels": map[string]interface{}{ + SelectorLabel: workloadID, + }, + } + + // set workload labels + workloadLabels := convert.ToMapInterface(data["workloadLabels"]) + if workloadLabels == nil { + workloadLabels = make(map[string]interface{}) + } + workloadLabels[SelectorLabel] = workloadID + data["workloadLabels"] = workloadLabels + + // set labels + labels := convert.ToMapInterface(data["labels"]) + if labels == nil { + labels = make(map[string]interface{}) + } + labels[SelectorLabel] = workloadID + data["labels"] = labels + } +} + +func getSecrets(apiContext *types.APIContext, data map[string]interface{}, namespaceID string) *[]corev1.LocalObjectReference { + imagePullSecrets, _ := data["imagePullSecrets"].([]corev1.LocalObjectReference) + if containers, _ := values.GetSlice(data, "containers"); len(containers) > 0 { + domainToCreds := getCreds(apiContext, namespaceID) + for _, container := range containers { + if image := convert.ToString(container["image"]); image != "" { + domain := getDomain(image) + if secrets, ok := domainToCreds[domain]; ok { + imagePullSecrets = append(imagePullSecrets, secrets...) + } + } + } + } + return &imagePullSecrets +} + +func setSecrets(apiContext *types.APIContext, data map[string]interface{}, namespaceID string, create bool) error { + imagePullSecrets := getSecrets(apiContext, data, namespaceID) + if imagePullSecrets != nil { + if create { + values.PutValue(data, imagePullSecrets, "imagePullSecrets") + } else if _, ok := data["containers"]; ok { + if updated, err := imageUpdated(apiContext, data); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("error accessing workload : %v", err)) + } else if updated { + values.PutValue(data, imagePullSecrets, "imagePullSecrets") + } + } + } + return nil +} + +func setWorkloadSpecificDefaults(schemaID string, data map[string]interface{}) { + if strings.EqualFold(schemaID, "job") || strings.EqualFold(schemaID, "cronJob") { + // job has different defaults + if _, ok := data["restartPolicy"]; !ok { + data["restartPolicy"] = "OnFailure" + } + } +} + +func setPorts(workloadName string, data map[string]interface{}) error { + containers, ok := values.GetValue(data, "containers") + if !ok { + return nil + } + + for _, c := range convert.ToInterfaceSlice(containers) { + cMap, err := convert.EncodeToMap(c) + if err != nil { + logrus.Warnf("Failed to transform container to map: %v", err) + continue + } + v, ok := values.GetValue(cMap, "ports") + + if ok { + ports := convert.ToInterfaceSlice(v) + usedNames := map[string]bool{} + for _, p := range ports { + port, err := convert.EncodeToMap(p) + if err != nil { + logrus.Warnf("Failed to transform port to map %v", err) + continue + } + + containerPort, err := convert.ToNumber(port["containerPort"]) + if err != nil { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("failed to transform container port [%v] "+ + "to number: %v", port["containerPort"], err)) + } + + containerPortStr := strconv.Itoa(int(containerPort)) + protocol := strings.ToLower(convert.ToString(port["protocol"])) + sourcePort := strings.ToLower(convert.ToString(port["sourcePort"])) + portName := convert.ToString(port["name"]) + if portName == "" || isRancherGeneratedPort(portName, containerPortStr, protocol) { + // port name is of format containerPortProtoSourcePortKind + // len limit is 15, therefore a) no separator b) kind is numerated + numKind := "0" + switch kind := convert.ToString(port["kind"]); kind { + case "NodePort": + numKind = "1" + case "ClusterIP": + numKind = "2" + case "LoadBalancer": + numKind = "3" + } + portName = fmt.Sprintf("%s%s%s%s", + containerPortStr, + protocol, + sourcePort, + numKind) + } + + //validate port name + if _, ok := usedNames[portName]; ok { + return httperror.NewAPIError(httperror.InvalidOption, fmt.Sprintf("Duplicated port kind=%v,"+ + " conainerPort=%v, protcol=%v", port["kind"], port["containerPort"], port["protocol"])) + } + usedNames[portName] = true + port["name"] = portName + + if generateDNSName(workloadName, convert.ToString(port["dnsName"])) { + if port["kind"] == "ClusterIP" { + // use workload name for clusterIP service as it will be used by dns resolution + port["dnsName"] = strings.ToLower(convert.ToString(workloadName)) + } else { + port["dnsName"] = fmt.Sprintf("%s-%s", strings.ToLower(convert.ToString(workloadName)), + strings.ToLower(convert.ToString(port["kind"]))) + } + } + } + } + } + return nil +} + +func isRancherGeneratedPort(portName, containerPort, protocol string) bool { + if strings.HasPrefix(portName, fmt.Sprintf("%s%s", containerPort, protocol)) { + return true + } + return false +} + +func generateDNSName(workloadName, dnsName string) bool { + if dnsName == "" { + return true + } + // regenerate the name in case port type got changed + if strings.EqualFold(dnsName, workloadName) || strings.HasPrefix(dnsName, fmt.Sprintf("%s-", workloadName)) { + return true + } + return false +} + +func getCreds(apiContext *types.APIContext, namespaceID string) map[string][]corev1.LocalObjectReference { + domainToCreds := make(map[string][]corev1.LocalObjectReference) + var namespacedCreds []projectclient.NamespacedDockerCredential + if err := access.List(apiContext, &projectschema.Version, "namespacedDockerCredential", &types.QueryOptions{}, &namespacedCreds); err == nil { + for _, cred := range namespacedCreds { + if cred.NamespaceId == namespaceID { + store(cred.Registries, domainToCreds, cred.Name) + } + } + } + var creds []projectclient.DockerCredential + if err := access.List(apiContext, &projectschema.Version, "dockerCredential", &types.QueryOptions{}, &creds); err == nil { + for _, cred := range creds { + store(cred.Registries, domainToCreds, cred.Name) + } + } + return domainToCreds +} + +func getNodeName(apiContext *types.APIContext, nodeID string) string { + var node managementv3.Node + var nodeName string + if err := access.ByID(apiContext, &managementschema.Version, managementv3.NodeType, nodeID, &node); err == nil { + nodeName = node.NodeName + } + return nodeName +} + +func setState(data map[string]interface{}, stateMap map[string]string) { + content, err := json.Marshal(stateMap) + if err != nil { + logrus.Errorf("failed to save state on workload: %v", data["id"]) + return + } + + values.PutValue(data, string(content), "annotations", "workload.cattle.io/state") +} + +func getState(data map[string]interface{}) map[string]string { + state := map[string]string{} + + v, ok := values.GetValue(data, "annotations", "workload.cattle.io/state") + if ok { + json.Unmarshal([]byte(convert.ToString(v)), &state) + } + + return state +} + +func getDomain(image string) string { + var repo string + named, err := reference.ParseNormalizedNamed(image) + if err != nil { + logrus.Debug(err) + return repo + } + domain := reference.Domain(named) + if domain == "docker.io" { + return "index.docker.io" + } + return domain +} + +func imageUpdated(apiContext *types.APIContext, data map[string]interface{}) (bool, error) { + var workload projectclient.Workload + accessError := access.ByID(apiContext, &projectschema.Version, "workload", apiContext.ID, &workload) + if accessError != nil { + return false, httperror.NewAPIError(httperror.InvalidReference, "Error accessing workload") + } + + containers, _ := values.GetSlice(data, "containers") + if len(containers) != len(workload.Containers) { + return true, nil + } + for i := range containers { + if workload.Containers[i].Image != convert.ToString(containers[i]["image"]) { + return true, nil + } + } + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/scheme/scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/scheme/scheme.go new file mode 100644 index 0000000..adb5b33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/scheme/scheme.go @@ -0,0 +1,114 @@ +package scheme + +import ( + "fmt" + + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + cluster "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + management "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + project "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + provisioning "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rke "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + ui "github.com/rancher/rancher/pkg/apis/ui.cattle.io/v1" + planv1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/apps/v1beta1" + appsv1beta1 "k8s.io/api/apps/v1beta1" + scalingv2 "k8s.io/api/autoscaling/v2" + batchv1 "k8s.io/api/batch/v1" + v1 "k8s.io/api/core/v1" + extv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + knetworkingv1beta1 "k8s.io/api/networking/v1beta1" + policyv1beta1 "k8s.io/api/policy/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + storagev1 "k8s.io/api/storage/v1" + storagev1beta1 "k8s.io/api/storage/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" +) + +type FilteredScheme struct { + *runtime.Scheme + excludedGVKs map[schema.GroupVersionKind]struct{} +} + +func (f *FilteredScheme) New(kind schema.GroupVersionKind) (runtime.Object, error) { + if _, ok := f.excludedGVKs[kind]; ok { + return nil, fmt.Errorf("%s is explicitly excluded from this scheme", kind.String()) + } + + return f.Scheme.New(kind) +} + +func (f *FilteredScheme) ExcludeGVK(kind schema.GroupVersionKind) { + f.excludedGVKs[kind] = struct{}{} +} + +var Scheme *FilteredScheme + +var builders = []runtime.SchemeBuilder{ + ui.SchemeBuilder, + rke.SchemeBuilder, + provisioning.SchemeBuilder, + project.SchemeBuilder, + management.SchemeBuilder, + cluster.SchemeBuilder, + catalog.SchemeBuilder, + fleet.SchemeBuilder, + monitoringv1.SchemeBuilder, + monitoringv1alpha1.SchemeBuilder, + planv1.SchemeBuilder, + appsv1.SchemeBuilder, + appsv1beta1.SchemeBuilder, + scalingv2.SchemeBuilder, + batchv1.SchemeBuilder, + v1.SchemeBuilder, + v1beta1.SchemeBuilder, + extv1beta1.SchemeBuilder, + knetworkingv1.SchemeBuilder, + knetworkingv1beta1.SchemeBuilder, + policyv1beta1.SchemeBuilder, + rbacv1.SchemeBuilder, + rbacv1beta1.SchemeBuilder, + storagev1.SchemeBuilder, + storagev1beta1.SchemeBuilder, + apiregistrationv1.SchemeBuilder, + apiregistrationv1beta1.SchemeBuilder, +} + +func init() { + Scheme = &FilteredScheme{ + Scheme: runtime.NewScheme(), + excludedGVKs: make(map[schema.GroupVersionKind]struct{}), + } + + if err := addKnownTypes(Scheme.Scheme); err != nil { + panic(err) + } + + // Some resources in Norman have values that are not part of go struct associated with their GVK. + // When Norman uses the appropriate go struct it will drop any field not on that go struct. + // Solution: Do not inform Norman about the struct associated with some GVKs so that it will fall back to the + // unstructured object and allow the missing fields to be included. + Scheme.ExcludeGVK(management.SchemeGroupVersion.WithKind("ClusterList")) + Scheme.ExcludeGVK(management.SchemeGroupVersion.WithKind("NodeTemplateList")) + +} + +func addKnownTypes(scheme *runtime.Scheme) error { + for _, builder := range builders { + err := builder.AddToScheme(scheme) + if err != nil { + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/additionalapi.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/additionalapi.go new file mode 100644 index 0000000..27c3027 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/additionalapi.go @@ -0,0 +1,77 @@ +package steve + +import ( + "context" + "net/http" + + gmux "github.com/gorilla/mux" + "github.com/rancher/rancher/pkg/api/steve/aggregation" + "github.com/rancher/rancher/pkg/api/steve/catalog" + "github.com/rancher/rancher/pkg/api/steve/github" + "github.com/rancher/rancher/pkg/api/steve/health" + "github.com/rancher/rancher/pkg/api/steve/projects" + "github.com/rancher/rancher/pkg/api/steve/proxy" + "github.com/rancher/rancher/pkg/capr/configserver" + "github.com/rancher/rancher/pkg/capr/installer" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + steve "github.com/rancher/steve/pkg/server" +) + +func AdditionalAPIsPreMCM(config *wrangler.Context) func(http.Handler) http.Handler { + if features.RKE2.Enabled() { + connectHandler := configserver.New(config) + mux := gmux.NewRouter() + mux.UseEncodedPath() + mux.Handle(configserver.ConnectAgent, connectHandler) + mux.Handle(configserver.ConnectConfigYamlPath, connectHandler) + mux.Handle(configserver.ConnectClusterInfo, connectHandler) + mux.Handle(installer.SystemAgentInstallPath, installer.Handler) + mux.Handle(installer.WindowsRke2InstallPath, installer.Handler) + return func(next http.Handler) http.Handler { + mux.NotFoundHandler = next + return mux + } + } + + return func(next http.Handler) http.Handler { + return next + } +} + +func AdditionalAPIs(ctx context.Context, config *wrangler.Context, steve *steve.Server) (func(http.Handler) http.Handler, error) { + clusterAPI, err := projects.Projects(ctx, config, steve) + if err != nil { + return nil, err + } + + githubHandler, err := github.NewProxy(config.Core.Secret().Cache(), + settings.GithubProxyAPIURL.Get(), + "cattle-system", + "github") + if err != nil { + return nil, err + } + + mux := gmux.NewRouter() + mux.UseEncodedPath() + if features.UIExtension.Enabled() { + catalog.RegisterUIPluginHandlers(mux) + } + mux.Handle("/v1/github{path:.*}", githubHandler) + mux.Handle("/v3/connect", Tunnel(config)) + + health.Register(mux) + + return func(next http.Handler) http.Handler { + mux.NotFoundHandler = clusterAPI(next) + return mux + }, nil +} + +func Tunnel(config *wrangler.Context) http.Handler { + config.TunnelAuthorizer.Add(proxy.NewAuthorizer(config)) + config.TunnelAuthorizer.Add(aggregation.New(config)) + return config.TunnelServer +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/aggregation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/aggregation.go new file mode 100644 index 0000000..d0668d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/aggregation.go @@ -0,0 +1,149 @@ +package aggregation + +import ( + "context" + "net/http" + "regexp" + "sort" + "sync" + "time" + + "github.com/gorilla/mux" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/remotedialer" + "github.com/rancher/steve/pkg/proxy" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/rest" +) + +var ( + clusterPrefixRegexp = regexp.MustCompile(`^/k8s/clusters/[^/]+`) +) + +type aggregationHandler struct { + sync.Mutex + + apiServiceCache mgmtcontrollers.APIServiceCache + mux *mux.Router + remote *remotedialer.Server +} + +type routeEntry struct { + path string + prefix string + uuid string +} + +func NewMiddleware(ctx context.Context, apiServices mgmtcontrollers.APIServiceController, remotedialer *remotedialer.Server) func(http.Handler) http.Handler { + handler := &aggregationHandler{ + apiServiceCache: apiServices.Cache(), + remote: remotedialer, + } + relatedresource.WatchClusterScoped(ctx, "aggregation-router", relatedresource.TriggerAllKey, + apiServices, apiServices) + apiServices.OnChange(ctx, "apiservice-router", handler.OnChange) + return handler.Middleware +} + +func (h *aggregationHandler) Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + h.next(next).ServeHTTP(rw, req) + }) +} + +func (h *aggregationHandler) next(notFound http.Handler) http.Handler { + h.Lock() + defer h.Unlock() + if h.mux == nil { + return notFound + } + h.mux.NotFoundHandler = notFound + return h.mux +} + +func (h *aggregationHandler) setEntries(routes []routeEntry) { + mux := mux.NewRouter() + mux.UseEncodedPath() + for _, entry := range routes { + if entry.prefix != "" { + mux.PathPrefix(entry.prefix).Handler(h.makeHandler(entry.uuid)) + } + if entry.path != "" { + mux.Path(entry.path).Handler(h.makeHandler(entry.uuid)) + } + } + + h.Lock() + defer h.Unlock() + h.mux = mux +} + +func keyFromUUID(uuid string) string { + return "stv-" + uuid +} + +func (h *aggregationHandler) makeHandler(uuid string) http.Handler { + key := keyFromUUID(uuid) + cfg := &rest.Config{ + Host: "http://" + key, + UserAgent: rest.DefaultKubernetesUserAgent() + " " + key, + Transport: &http.Transport{ + DialContext: h.remote.Dialer(key), + }, + } + + next := proxy.ImpersonatingHandler("", cfg) + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + for i := 0; i < 15; i++ { + if !h.remote.HasSession(key) { + time.Sleep(time.Second) + } + } + if !h.remote.HasSession(key) { + http.Error(rw, "Handler disconnected", http.StatusServiceUnavailable) + return + } + + if prefix := clusterPrefixRegexp.FindString(req.URL.Path); prefix != "" { + req.Header.Set("X-API-URL-Prefix", prefix) + } + + next.ServeHTTP(rw, req) + }) +} + +func (h *aggregationHandler) OnChange(key string, obj *v3.APIService) (*v3.APIService, error) { + if key != relatedresource.AllKey { + return obj, nil + } + + apiServices, err := h.apiServiceCache.List(labels.Everything()) + if err != nil { + return nil, err + } + + sort.Slice(apiServices, func(i, j int) bool { + return apiServices[i].Name < apiServices[j].Name + }) + + var entries []routeEntry + for _, apiService := range apiServices { + for _, prefix := range apiService.Spec.PathPrefixes { + entries = append(entries, routeEntry{ + prefix: prefix, + uuid: string(apiService.UID), + }) + } + for _, path := range apiService.Spec.Paths { + entries = append(entries, routeEntry{ + path: path, + uuid: string(apiService.UID), + }) + } + } + + h.setEntries(entries) + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/auth.go new file mode 100644 index 0000000..55fcec3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/aggregation/auth.go @@ -0,0 +1,104 @@ +package aggregation + +import ( + "crypto/sha256" + "encoding/base64" + "net/http" + "strings" + + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/remotedialer" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" +) + +const ( + saTokenHashIndex = "saTokenHashIndex" +) + +func New(wrangler *wrangler.Context) remotedialer.Authorizer { + a := &APIServiceAuthorizer{ + serviceAccount: wrangler.Core.ServiceAccount().Cache(), + apiServices: wrangler.Mgmt.APIService().Cache(), + secrets: wrangler.Core.Secret().Cache(), + } + + wrangler.Core.Secret().Cache().AddIndexer(saTokenHashIndex, func(obj *corev1.Secret) ([]string, error) { + return []string{ + hashSecret(obj), + }, nil + }) + return a.Authorize +} + +type APIServiceAuthorizer struct { + secrets corecontrollers.SecretCache + serviceAccount corecontrollers.ServiceAccountCache + apiServices mgmtcontrollers.APIServiceCache +} + +func hashSecret(sa *corev1.Secret) string { + if sa.Type == corev1.SecretTypeServiceAccountToken { + hash := sha256.Sum256(sa.Data[corev1.ServiceAccountTokenKey]) + return base64.StdEncoding.EncodeToString(hash[:]) + } + return "" +} + +func (a *APIServiceAuthorizer) Authorize(req *http.Request) (clientKey string, authed bool, err error) { + token := strings.TrimSpace(strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")) + if token == "" { + return "", false, nil + } + + secrets, err := a.secrets.GetByIndex(saTokenHashIndex, token) + if apierror.IsNotFound(err) { + return "", false, nil + } else if err != nil { + return "", false, err + } + + for _, secret := range secrets { + if secret.Type != corev1.SecretTypeServiceAccountToken { + continue + } + saName := secret.Annotations[corev1.ServiceAccountNameKey] + saUID := secret.Annotations[corev1.ServiceAccountUIDKey] + if saName == "" || saUID == "" { + continue + } + + sa, err := a.serviceAccount.Get(secret.Namespace, saName) + if apierror.IsNotFound(err) { + continue + } else if err != nil { + return "", false, err + } + + if string(sa.UID) != saUID { + continue + } + + for _, owner := range sa.OwnerReferences { + if owner.Kind != "APIService" { + continue + } + + apiService, err := a.apiServices.Get(owner.Name) + if apierror.IsNotFound(err) { + continue + } else if err != nil { + return "", false, err + } + + if apiService.Status.ServiceAccountNamespace == sa.Namespace && + apiService.Status.ServiceAccountName == sa.Name { + return keyFromUUID(string(apiService.UID)), true, nil + } + } + } + + return "", false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/catalog.go new file mode 100644 index 0000000..3f69073 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/catalog.go @@ -0,0 +1,149 @@ +/* +Package catalog implements API handlers for Rancher's catalog functionality. + +It registers handlers for Helm-related operations and content management. + +It also links the custom resouces with the handlers with the help of Templates in the apiserver package. + +The package is used to facilitate interactions with Helm charts within a Rancher server environment. +*/ +package catalog + +import ( + "context" + "net/http" + + "github.com/rancher/apiserver/pkg/handlers" + responsewriter "github.com/rancher/apiserver/pkg/middleware" + "github.com/rancher/apiserver/pkg/types" + types2 "github.com/rancher/rancher/pkg/api/steve/catalog/types" + "github.com/rancher/rancher/pkg/apis/catalog.cattle.io" + "github.com/rancher/rancher/pkg/catalogv2/content" + "github.com/rancher/rancher/pkg/catalogv2/helmop" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" + schemas3 "github.com/rancher/wrangler/v3/pkg/schemas" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" +) + +// Register is used to register the two handlers with the apiserver +func Register(ctx context.Context, server *steve.Server, + helmop *helmop.Operations, + contentManager *content.Manager) error { + + ops := newOperation(helmop, server.ClusterRegistry) + + // Informer callbacks for Steve server + server.ClusterCache.OnAdd(ctx, ops.OnAdd) + server.ClusterCache.OnChange(ctx, ops.OnChange) + + // App's & marketplace-related data + index := &contentDownload{ + contentManager: contentManager, + } + + addSchemas(server, ops, index) + return nil +} + +// addSchemas adds and customizes API schemas for operations, app, repo, and clusterrepo. +// It adds action handlers and resource actions for install, upgrade, and uninstall operations of Charts. +// It also sets up handlers for byID and link requests. +// +// The function uses predefined structure templates for API schemas, allowing for customization +// of behavior at runtime. It associates specific operations with specific routes, and +// defines how to handle different action requests made on different resources. +// +// The handlers for retrieving resources by their IDs are also customized. +func addSchemas(server *steve.Server, ops *operation, index http.Handler) { + // Imports and generates API schemas to be handled by as requests by the Rancher API server. + server.BaseSchemas.MustImportAndCustomize(types2.ChartUninstallAction{}, nil) + server.BaseSchemas.MustImportAndCustomize(types2.ChartUpgradeAction{}, nil) + server.BaseSchemas.MustImportAndCustomize(types2.ChartUpgrade{}, nil) + server.BaseSchemas.MustImportAndCustomize(types2.ChartInstallAction{}, nil) + server.BaseSchemas.MustImportAndCustomize(types2.ChartInstall{}, nil) + server.BaseSchemas.MustImportAndCustomize(types2.ChartActionOutput{}, nil) + + operationTemplate := schema2.Template{ + Group: catalog.GroupName, + Kind: "Operation", + Customize: func(apiSchema *types.APISchema) { + apiSchema.LinkHandlers = map[string]http.Handler{ + "logs": ops, + } + apiSchema.Formatter = func(request *types.APIRequest, resource *types.RawResource) { + if !resource.APIObject.Data().Bool("status", "podCreated") { + delete(resource.Links, "logs") + } + } + }, + } + appTemplate := schema2.Template{ + Group: catalog.GroupName, + Kind: "App", + Customize: func(apiSchema *types.APISchema) { + apiSchema.ActionHandlers = map[string]http.Handler{ + "uninstall": ops, + } + apiSchema.ResourceActions = map[string]schemas3.Action{ + "uninstall": { + Input: "chartUninstallAction", + Output: "chartActionOutput", + }, + } + }, + } + repoTemplate := schema2.Template{ + Group: catalog.GroupName, + Kind: "Repo", + Customize: func(apiSchema *types.APISchema) { + apiSchema.ActionHandlers = map[string]http.Handler{ + "install": ops, + "upgrade": ops, + } + apiSchema.ResourceActions = map[string]schemas3.Action{ + "install": { + Input: "chartInstallAction", + Output: "chartActionOutput", + }, + "upgrade": { + Input: "chartUpgradeAction", + Output: "chartActionOutput", + }, + } + // Customize the handler for retrieving a Repo resource by its ID. + apiSchema.ByIDHandler = func(request *types.APIRequest) (types.APIObject, error) { + if request.Name == "index.yaml" { + request.Name = request.Namespace + request.Namespace = "" + request.Link = "index" + // Serve the HTTP response using the 'index' handler. + index.ServeHTTP(request.Response, request.Request) + // The request has been fully handled and no further processing is required + return types.APIObject{}, validation.ErrComplete + } + // For all other requests, use default ByIDHandler to retrieve a resource by its ID. + return handlers.ByIDHandler(request) + } + // Define handlers for different links on the Repo resource that can be used to serve additional information. + apiSchema.LinkHandlers = map[string]http.Handler{ + "index": index, + "info": index, + "chart": index, + "icon": responsewriter.ContentType(index), + } + }, + } + chartRepoTemplate := repoTemplate + chartRepoTemplate.Kind = "ClusterRepo" + + server.SchemaFactory.AddTemplate( + operationTemplate, + appTemplate, + repoTemplate, + chartRepoTemplate) +} + +func isClusterRepo(typeName string) bool { + return typeName == "catalog.cattle.io.clusterrepo" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content.go new file mode 100644 index 0000000..a28b20b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content.go @@ -0,0 +1,174 @@ +package catalog + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/rancher/pkg/catalogv2/content" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "helm.sh/helm/v3/pkg/repo" +) + +// contentDownload implements the http handler interface. +type contentDownload struct { + // contentManager struct functions helps in retrieving information + // related to helm repositories such as chart asset,icon,info, helm repo index file + // suitable to the current cluster and logs + contentManager *content.Manager +} + +// ServeHTTP is the main entry point for Apps & MarketPlace content service. +// It parses the request into apicontext to determine the type of content that +// needs to be served. The type of content being served is determined by the +// link field of the API context. It then calls the appropriate function of +// contentManager to serve the information. +func (i *contentDownload) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + // Get the APIContext from the current request's context. This APIContext + // encapsulates the details of the API request, which will be used to + // determine the necessary operation and respond accordingly. + apiContext := types.GetAPIContext(req.Context()) + switch apiContext.Link { + case "index": + if err := i.serveIndex(apiContext, rw, req); err != nil { + apiContext.WriteError(err) + } + case "info": + if err := i.serveInfo(apiContext, rw, req); err != nil { + apiContext.WriteError(err) + } + case "chart": + if err := i.serveChart(apiContext, rw, req); err != nil { + apiContext.WriteError(err) + } + case "icon": + if err := i.serveIcon(apiContext, rw, req); err != nil { + apiContext.WriteError(err) + } + } +} + +// serveIndex retrieves the index file from the Helm repository, translates the URLs based on the current domain name, +// and sends the index file to the client. +func (i *contentDownload) serveIndex(apiContext *types.APIRequest, rw http.ResponseWriter, req *http.Request) error { + index, err := i.getIndex(apiContext) + if err != nil { + return err + } + + u, err := url.Parse(apiContext.URLBuilder.Current()) + if err != nil { + return err + } + + if err := content.TranslateURLs(u, index); err != nil { + return err + } + + rw.Header().Set("Content-Type", "application/json") + return json.NewEncoder(rw).Encode(index) +} + +// serveInfo provides detailed information about a specific chart +func (i *contentDownload) serveInfo(apiContext *types.APIRequest, rw http.ResponseWriter, req *http.Request) error { + query := apiContext.Request.URL.Query() + chartName := query.Get("chartName") + version := query.Get("version") + + if chartName == "" { + return validation.NotFound + } + + namespace, name := nsAndName(apiContext) + info, err := i.contentManager.Info(namespace, name, chartName, version) + if err != nil { + return err + } + + rw.Header().Set("Content-Type", "application/json") + return json.NewEncoder(rw).Encode(info) +} + +// serveIcon retrieves and serves the icon for a specific chart. +func (i *contentDownload) serveIcon(apiContext *types.APIRequest, rw http.ResponseWriter, req *http.Request) error { + query := apiContext.Request.URL.Query() + chartName := query.Get("chartName") + version := query.Get("version") + + if chartName == "" { + return validation.NotFound + } + + namespace, name := nsAndName(apiContext) + chart, suffix, err := i.contentManager.Icon(namespace, name, chartName, version) + if err != nil { + return err + } + if chart != nil { + setIconHeaders(rw, suffix) + _, err = io.Copy(rw, chart) + defer chart.Close() + } + + return err +} + +// setIconHeaders sets headers necessary for the correct display of the icon image in most browsers. +func setIconHeaders(rw http.ResponseWriter, suffix string) { + if suffix == ".svg" { + rw.Header().Set("Content-Type", "image/svg+xml") + } + rw.Header().Set("Cache-Control", "max-age=31536000, public") + rw.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") + rw.Header().Set("X-Content-Type-Options", "nosniff") +} + +// serveChart retrieves and serves a specific chart. +// The chart and its version are determined by the query parameters of the API request. +func (i *contentDownload) serveChart(apiContext *types.APIRequest, rw http.ResponseWriter, req *http.Request) error { + query := apiContext.Request.URL.Query() + chartName := query.Get("chartName") + version := query.Get("version") + + if chartName == "" { + return validation.NotFound + } + + namespace, name := nsAndName(apiContext) + chart, err := i.contentManager.Chart(namespace, name, chartName, version, true) + if err != nil { + return err + } + defer chart.Close() + + rw.Header().Set("Content-Type", "application/gzip") + rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s-%s.tgz\"", chartName, version)) + _, err = io.Copy(rw, chart) + return err +} + +// getIndex retrieves the index file from the Helm repository. +// By default, the index file contains versions filtered by rancher version and the local cluster's k8s version; +// If "skipFilter" is set to "true" in the API request, the index file will contain all versions for all charts; +// if "k8sVersion" is set, the index file will contain versions filtered by rancher version and the k8s version. +func (i *contentDownload) getIndex(apiContext *types.APIRequest) (*repo.IndexFile, error) { + namespace, name := nsAndName(apiContext) + query := apiContext.Request.URL.Query() + rawValue := query.Get("skipFilter") + skipFilter := strings.ToLower(rawValue) == "true" + targetClusterVersion := query.Get("k8sVersion") + return i.contentManager.Index(namespace, name, targetClusterVersion, skipFilter) +} + +// nsAndName returns the namespace and name from the API context. If the +// API context corresponds to the cluster repository, the namespace is an empty string. +func nsAndName(apiContext *types.APIRequest) (string, string) { + if isClusterRepo(apiContext.Type) { + return "", apiContext.Name + } + return apiContext.Namespace, apiContext.Name +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content_test.go new file mode 100644 index 0000000..8b443be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/content_test.go @@ -0,0 +1,43 @@ +package catalog + +import ( + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSetIconHeaders(t *testing.T) { + tests := []struct { + name string + suffix string + }{ + { + name: ".svg suffix", + suffix: ".svg", + }, + { + name: ".png suffix", + suffix: ".png", + }, + { + name: "no suffix", + suffix: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rw := httptest.NewRecorder() + setIconHeaders(rw, tt.suffix) + resp := rw.Result() + assert.Equal(t, []string{"max-age=31536000, public"}, resp.Header["Cache-Control"]) + assert.Equal(t, []string{"default-src 'none'; style-src 'unsafe-inline'; sandbox"}, resp.Header["Content-Security-Policy"]) + assert.Equal(t, []string{"nosniff"}, resp.Header["X-Content-Type-Options"]) + if tt.suffix == ".svg" { + assert.Equal(t, []string{"image/svg+xml"}, resp.Header["Content-Type"]) + } else { + assert.Nil(t, resp.Header["Content-Type"]) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/operation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/operation.go new file mode 100644 index 0000000..22194e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/operation.go @@ -0,0 +1,116 @@ +package catalog + +import ( + "net/http" + + "github.com/rancher/apiserver/pkg/types" + catalogtypes "github.com/rancher/rancher/pkg/api/steve/catalog/types" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/helmop" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "k8s.io/apimachinery/pkg/runtime" + schema2 "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/endpoints/request" +) + +// operation implements the http handler interface. +type operation struct { + // ops is the Operation struct which contains functions + // related to helm such as helm install, helm uninstall etc. + ops *helmop.Operations + // imageOveride is the location of the rancher shell image which is used + // for running helm commands such as install, upgrade and uninstall. + imageOverride string +} + +// newOperation parses and returns an object operation updating the imageOverride field +// based on the clusterRegistry parameter. If clusterRegistry is not an empty string +// the imageOverride value will be prefixed with clusterRegistry value. +func newOperation( + helmop *helmop.Operations, clusterRegistry string) *operation { + var imageOverride string + if clusterRegistry != "" { + imageOverride = clusterRegistry + "/" + settings.ShellImage.Get() + } + return &operation{ + ops: helmop, + imageOverride: imageOverride, + } +} + +// ServeHTTP calls corresponding Operation functions based on the type of the api request. +// It uses the rancher apiserver package to parse the request and know the type of it. +// The types are documented in the rancher apiserver package. After parsing, it then +// checks if the request is authorised by checking the user field in the request. +// +// For example, if the api request is for installing a chart, then it will call the +// install function of the Operation struct. +// +// All chart actions (install, upgrade, and uninstall) are served through this method. +func (o *operation) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + // Get the APIContext from the current request's context. This APIContext + // encapsulates the details of the API request, which will be used to + // determine the necessary operation and respond accordingly. + apiRequest := types.GetAPIContext(req.Context()) + + user, ok := request.UserFrom(req.Context()) + if !ok { + apiRequest.WriteError(validation.Unauthorized) + return + } + + var ( + op *catalog.Operation + err error + ) + + ns, name := nsAndName(apiRequest) + switch apiRequest.Action { + case "install": + op, err = o.ops.Install(apiRequest.Context(), user, ns, name, req.Body, o.imageOverride) + case "upgrade": + op, err = o.ops.Upgrade(apiRequest.Context(), user, ns, name, req.Body, o.imageOverride) + case "uninstall": + op, err = o.ops.Uninstall(apiRequest.Context(), user, ns, name, req.Body, o.imageOverride) + } + + switch apiRequest.Link { + case "logs": + err = o.ops.Log(apiRequest.Response, apiRequest.Request, + apiRequest.Namespace, apiRequest.Name) + } + + if err != nil { + apiRequest.WriteError(err) + return + } + + if op == nil { + return + } + + apiRequest.WriteResponse(http.StatusCreated, types.APIObject{ + Type: "chartActionOutput", + Object: &catalogtypes.ChartActionOutput{ + OperationName: op.Name, + OperationNamespace: op.Namespace, + }, + }) +} + +// OnAdd is registered as a callback of a Kubernetes Informer. +// It is invoked when a new object is added to the Kubernetes cluster. +// It purges old roles related to the object being added. +// These old roles will be purged upon timeout. +func (o *operation) OnAdd(gvk schema2.GroupVersionKind, key string, obj runtime.Object) error { + return o.ops.Impersonator.PurgeOldRoles(gvk, key, obj) +} + +// OnChange is registered as a callback of a Kubernetes Informer. +// It is invoked when an existing object is modified inside the Kubernetes cluster. +// It purges old roles related to the object being modified. +// These old roles will be purged upon timeout. +func (o *operation) OnChange(gvk schema2.GroupVersionKind, key string, obj, oldObj runtime.Object) error { + return o.ops.Impersonator.PurgeOldRoles(gvk, key, obj) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin.go new file mode 100644 index 0000000..e0b0b81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin.go @@ -0,0 +1,122 @@ +package catalog + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "mime" + "net/http" + "net/http/httputil" + neturl "net/url" + "path/filepath" + + "github.com/gorilla/mux" + "github.com/rancher/rancher/pkg/controllers/dashboard/plugin" + "github.com/sirupsen/logrus" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type denyFunc func(host string) bool + +func RegisterUIPluginHandlers(router *mux.Router) { + router.HandleFunc("/v1/uiplugins", indexHandler) + router.HandleFunc("/v1/uiplugins/{name}/{version}/{rest:.*}", pluginHandler) +} + +func indexHandler(w http.ResponseWriter, r *http.Request) { + var in *plugin.SafeIndex + if isAuthenticated(r) { + in = &plugin.Index + } else { + in = &plugin.AnonymousIndex + } + index, err := json.Marshal(in) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + logrus.Error(err) + } + w.Write(index) +} + +func pluginHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + logrus.Debugf("http request vars %s", vars) + authed := isAuthenticated(r) + entry, ok := plugin.Index.Entries[vars["name"]] + // Checks if the requested plugin exists and if the user has authorization to see it + if (!ok || entry.Version != vars["version"]) || (!authed && !entry.NoAuth) { + msg := fmt.Sprintf("plugin [name: %s version: %s] does not exist in index", vars["name"], vars["version"]) + http.Error(w, msg, http.StatusNotFound) + logrus.Debug(msg) + return + } + if entry.NoCache { + logrus.Debugf("[noCache: %v] proxying request to [endpoint: %v]\n", entry.NoCache, entry.Endpoint) + proxyRequest(entry.Endpoint, vars["rest"], w, r, denylist) + } else { + logrus.Debugf("[noCache: %v] serving plugin files from filesystem cache\n", entry.NoCache) + r.URL.Path = fmt.Sprintf("/%s/%s/%s", vars["name"], vars["version"], vars["rest"]) + http.FileServer(http.Dir(plugin.FSCacheRootDir)).ServeHTTP(w, r) + } +} + +func proxyRequest(target, path string, w http.ResponseWriter, r *http.Request, denyListFunc denyFunc) { + url, err := neturl.Parse(target) + if err != nil { + http.Error(w, fmt.Sprintf("failed to parse url [%s]", target), http.StatusInternalServerError) + return + } + if denyListFunc(url.Hostname()) { + http.Error(w, fmt.Sprintf("url [%s] is forbidden", target), http.StatusForbidden) + return + } + proxy := httputil.NewSingleHostReverseProxy(url) + proxy.ModifyResponse = func(response *http.Response) error { + if response.StatusCode == http.StatusOK { + if contentType := mime.TypeByExtension(filepath.Ext(r.URL.Path)); contentType != "" { + w.Header().Set("Content-Type", contentType) + } else { + body, _ := io.ReadAll(response.Body) + response.Body = io.NopCloser(bytes.NewBuffer(body)) + w.Header().Set("Content-Type", http.DetectContentType(body)) + } + + } + return nil + } + r.URL.Host = url.Host + r.URL.Scheme = url.Scheme + r.URL.Path = path + r.Header.Set("X-Forwarded-Host", r.Header.Get("Host")) + r.Host = url.Host + proxy.ServeHTTP(w, r) +} + +func denylist(host string) bool { + denied := map[string]struct{}{ + "localhost": {}, + "127.0.0.1": {}, + "0.0.0.0": {}, + "169.254.169.254": {}, + "::1": {}, + "::": {}, + "": {}, + } + _, isDenied := denied[host] + + return isDenied +} + +func isAuthenticated(r *http.Request) bool { + u, ok := request.UserFrom(r.Context()) + if !ok { + return false + } + for _, g := range u.GetGroups() { + if g == "system:authenticated" { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin_test.go new file mode 100644 index 0000000..a430614 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/plugin_test.go @@ -0,0 +1,40 @@ +package catalog + +import ( + "io" + "net/http" + "net/http/httptest" + "testing" +) + +func TestProxyRequest_content_type(t *testing.T) { + response := "var http = require('http');\n var url = require('url');\n var number = 0;" + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Disposition", "attachment; filename=testing.js") + if _, err := w.Write([]byte(response)); err != nil { + t.Fatal(err) + } + })) + defer ts.Close() + denyFunc := func(string) bool { return false } + req := httptest.NewRequest(http.MethodGet, "http://example.com", nil) + w := httptest.NewRecorder() + + proxyRequest(ts.URL, "/testing.js", w, req, denyFunc) + + resp := w.Result() + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode != http.StatusOK { + t.Errorf("got StatusCode %v, want %v", resp.StatusCode, http.StatusOK) + } + + wantContent := "text/javascript; charset=utf-8" + if ct := resp.Header.Get("Content-Type"); ct != wantContent { + t.Errorf("got Content-Type %s, want %s", ct, wantContent) + + } + if string(body) != response { + t.Errorf("read body: %s", body) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/types/rest.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/types/rest.go new file mode 100644 index 0000000..9856887 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/catalog/types/rest.go @@ -0,0 +1,91 @@ +/* +Package types define several types representing Helm chart operations. + +These types are used by the Steve Catalog API to handle requests and responses +associated with Helm chart actions such as install, upgrade, and uninstall. + +Types in this package include: + + - ChartInstall: Represents a Helm chart installation request. + - ChartInstallAction: Describes the configuration for an installation action. + - ChartInfo: Contains detailed information about a Helm chart. + - ChartUninstallAction: Describes the configuration for an uninstallation action. + - ChartUpgradeAction: Describes the configuration for an upgrade action. + - ChartUpgrade: Represents a Helm chart upgrade request. + - ChartActionOutput: Represents the output after performing a Helm chart action. + +Each type includes fields that map directly to properties of Helm chart operations, +allowing for a structured approach to managing Helm charts through the API. +*/ +package types + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ChartInstall struct { + ChartName string `json:"chartName,omitempty"` + Version string `json:"version,omitempty"` + ReleaseName string `json:"releaseName,omitempty"` + Description string `json:"description,omitempty"` + Values v3.MapStringInterface `json:"values,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` +} + +type ChartInstallAction struct { + Timeout *metav1.Duration `json:"timeout,omitempty"` + Wait bool `json:"wait,omitempty"` + DisableHooks bool `json:"noHooks,omitempty"` + DisableOpenAPIValidation bool `json:"disableOpenAPIValidation,omitempty"` + Namespace string `json:"namespace,omitempty"` + ProjectID string `json:"projectId,omitempty"` + + Charts []ChartInstall `json:"charts,omitempty"` +} + +type ChartInfo struct { + Readme string `json:"readme,omitempty"` + APPReadme string `json:"appReadme,omitempty"` + Values v3.MapStringInterface `json:"values,omitempty"` + Questions v3.MapStringInterface `json:"questions,omitempty"` + Chart v3.MapStringInterface `json:"chart,omitempty"` +} + +type ChartUninstallAction struct { + DisableHooks bool `json:"noHooks,omitempty"` + DryRun bool `json:"dryRun,omitempty"` + KeepHistory bool `json:"keepHistory,omitempty"` + Timeout *metav1.Duration `json:"timeout,omitempty"` + Description string `json:"description,omitempty"` +} + +type ChartUpgradeAction struct { + Timeout *metav1.Duration `json:"timeout,omitempty"` + Wait bool `json:"wait,omitempty"` + DisableHooks bool `json:"noHooks,omitempty"` + DisableOpenAPIValidation bool `json:"disableOpenAPIValidation,omitempty"` + Force bool `json:"force,omitempty"` + TakeOwnership bool `json:"takeOwnership,omitempty"` + MaxHistory int `json:"historyMax,omitempty"` + Install bool `json:"install,omitempty"` + Namespace string `json:"namespace,omitempty"` + CleanupOnFail bool `json:"cleanupOnFail,omitempty"` + Charts []ChartUpgrade `json:"charts,omitempty"` +} + +type ChartUpgrade struct { + ChartName string `json:"chartName,omitempty"` + Version string `json:"version,omitempty"` + ReleaseName string `json:"releaseName,omitempty"` + Force bool `json:"force,omitempty"` + ResetValues bool `json:"resetValues,omitempty"` + Description string `json:"description,omitempty"` + Values v3.MapStringInterface `json:"values,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` +} + +type ChartActionOutput struct { + OperationName string `json:"operationName,omitempty"` + OperationNamespace string `json:"operationNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/clusters.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/clusters.go new file mode 100644 index 0000000..63d4977 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/clusters.go @@ -0,0 +1,114 @@ +package clusters + +import ( + "context" + "net/http" + "time" + + "github.com/rancher/apiserver/pkg/handlers" + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/rancher/pkg/api/steve/norman" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/clusterrouter" + normanv3 "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/steve/pkg/podimpersonation" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" + "github.com/rancher/wrangler/v3/pkg/schemas" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func Register(ctx context.Context, server *steve.Server, wrangler *wrangler.Context) error { + log := &log{ + cg: server.ClientFactory, + } + shell := &shell{ + cg: server.ClientFactory, + namespace: "cattle-system", + impersonator: podimpersonation.New("shell", server.ClientFactory, time.Hour, settings.FullShellImage), + clusterRegistry: server.ClusterRegistry, + } + sc, err := config.NewScaledContext(*wrangler.RESTConfig, nil) + if err != nil { + return err + } + + userManager, err := common.NewUserManagerNoBindings(sc) + if err != nil { + return err + } + kubeconfig := kubeconfigDownload{ + userMgr: userManager, + auth: requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, sc), + } + + server.ClusterCache.OnAdd(ctx, shell.impersonator.PurgeOldRoles) + server.ClusterCache.OnChange(ctx, func(gvk schema.GroupVersionKind, key string, obj, oldObj runtime.Object) error { + return shell.impersonator.PurgeOldRoles(gvk, key, obj) + }) + + server.BaseSchemas.MustImportAndCustomize(GenerateKubeconfigOutput{}, nil) + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "management.cattle.io", + Kind: "Cluster", + Formatter: norman.NewLinksAndActionsFormatter(wrangler.MultiClusterManager, normanv3.Version, "cluster"), + Customize: func(schema *types.APISchema) { + if schema.LinkHandlers == nil { + schema.LinkHandlers = map[string]http.Handler{} + } + schema.LinkHandlers["shell"] = shell + schema.LinkHandlers["log"] = log + if schema.ActionHandlers == nil { + schema.ActionHandlers = map[string]http.Handler{} + } + schema.ActionHandlers["generateKubeconfig"] = kubeconfig + if schema.ResourceActions == nil { + schema.ResourceActions = map[string]schemas.Action{} + } + schema.ResourceActions["generateKubeconfig"] = schemas.Action{ + Output: "generateKubeconfigOutput", + } + schema.ByIDHandler = func(request *types.APIRequest) (types.APIObject, error) { + // By pass authorization for local shell because the user might not have + // GET granted for local cluster + if request.Name == "local" && request.Link == "shell" { + shell.ServeHTTP(request.Response, request.Request) + return types.APIObject{}, validation.ErrComplete + } + return handlers.ByIDHandler(request) + } + // Everybody can list even if they have no list or get privileges. The users + // authorization will still be used to determine what can be seen but just + // may result in an empty list + schema.CollectionMethods = append(schema.CollectionMethods, http.MethodGet) + }, + }) + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "management.cattle.io", + Kind: "Project", + Customize: func(schema *types.APISchema) { + // Everybody can list even if they have no list or get privileges. The users + // authorization will still be used to determine what can be seen but just + // may result in an empty list + schema.CollectionMethods = append(schema.CollectionMethods, http.MethodGet) + }, + }) + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "", + Kind: "Namespace", + Customize: func(schema *types.APISchema) { + // Everybody can list even if they have no list or get privileges. The users + // authorization will still be used to determine what can be seen but just + // may result in an empty list + schema.CollectionMethods = append(schema.CollectionMethods, http.MethodGet) + }, + }) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/kubeconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/kubeconfig.go new file mode 100644 index 0000000..89eaa08 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/kubeconfig.go @@ -0,0 +1,101 @@ +package clusters + +import ( + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/kubeconfig" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/user" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type kubeconfigDownload struct { + userMgr user.Manager + auth requests.Authenticator +} + +func (k kubeconfigDownload) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + apiRequest := types.GetAPIContext(req.Context()) + if err := apiRequest.AccessControl.CanGet(apiRequest, apiRequest.Schema); err != nil { + apiRequest.WriteError(err) + return + } + + if features.MCM.Enabled() { + http.Redirect(rw, req, fmt.Sprintf("/v3/clusters/%s?action=generateKubeconfig", apiRequest.Name), http.StatusFound) + return + } + + userName, ok := request.UserFrom(req.Context()) + if !ok { + apiRequest.WriteError(validation.Unauthorized) + return + } + var tokenKey string + var err error + generateToken := strings.EqualFold(settings.KubeconfigGenerateToken.Get(), "true") + if generateToken { + tokenKey, err = k.ensureToken(userName.GetName(), req) + if err != nil { + apiRequest.WriteError(err) + return + } + } + + host := settings.ServerURL.Get() + if host == "" { + host = apiRequest.Request.Host + } else { + u, err := url.Parse(host) + if err == nil { + host = u.Host + } else { + host = apiRequest.Request.Host + } + } + cfg, err := kubeconfig.ForTokenBased(apiRequest.Name, apiRequest.Name, host, tokenKey) + if err != nil { + apiRequest.WriteError(err) + return + } + apiRequest.WriteResponse(http.StatusOK, types.APIObject{ + Type: "generateKubeconfigOutput", + Object: &GenerateKubeconfigOutput{ + Config: cfg, + }, + }) +} + +func (k kubeconfigDownload) ensureToken(userName string, req *http.Request) (string, error) { + defaultTokenTTL, err := tokens.GetKubeconfigDefaultTokenTTLInMilliSeconds() + if err != nil { + return "", fmt.Errorf("failed to get default token TTL: %w", err) + } + + authToken, err := k.auth.TokenFromRequest(req) + if err != nil { + return "", err + } + + tokenNamePrefix := fmt.Sprintf("kubeconfig-%s", userName) + input := user.TokenInput{ + TokenName: tokenNamePrefix, + Description: "Kubeconfig token", + Kind: "kubeconfig", + UserName: userName, + AuthProvider: authToken.AuthProvider, + TTL: defaultTokenTTL, + Randomize: true, + UserPrincipal: authToken.UserPrincipal, + } + + return k.userMgr.EnsureToken(input) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/log.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/log.go new file mode 100644 index 0000000..5942394 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/log.go @@ -0,0 +1,152 @@ +package clusters + +import ( + "bufio" + "context" + "encoding/base64" + "net/http" + "strings" + "time" + + "github.com/gorilla/websocket" + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/steve/pkg/stores/proxy" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes" +) + +var ( + timeout int64 = 15 * 60 +) + +var upgrader = websocket.Upgrader{ + HandshakeTimeout: 5 * time.Second, + CheckOrigin: func(r *http.Request) bool { return true }, + Error: onError, +} + +func onError(rw http.ResponseWriter, _ *http.Request, code int, err error) { + rw.WriteHeader(code) + rw.Write([]byte(err.Error())) +} + +type log struct { + cg proxy.ClientGetter +} + +func (l *log) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + err := l.printLog(resp, req) + if err != nil { + logrus.Infof("Error while handling cluster log: %v", err) + } +} + +func (l *log) printLog(resp http.ResponseWriter, req *http.Request) error { + conn, err := upgrader.Upgrade(resp, req, nil) + if err != nil { + return err + } + defer conn.Close() + + apiRequest := types.GetAPIContext(req.Context()) + client, err := l.cg.AdminK8sInterface() + if err != nil { + return err + } + + w, err := client.CoreV1().ConfigMaps(apiRequest.Name).Watch(req.Context(), metav1.ListOptions{ + TimeoutSeconds: &timeout, + FieldSelector: "metadata.name=provisioning-log", + }) + if err != nil { + return err + } + + var ( + lastLine = "" + printLine = true + ) + + for event := range w.ResultChan() { + switch event.Type { + case watch.Added: + case watch.Modified: + case watch.Deleted: + return nil + default: + continue + } + cm, ok := event.Object.(*corev1.ConfigMap) + if !ok { + continue + } + + scanner := bufio.NewScanner(strings.NewReader(cm.Data["log"])) + printed := false + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" { + continue + } + + if !printLine && lastLine == line { + printLine = true + continue + } else if printLine { + if err := printMessage(line, conn); err != nil { + return err + } + printed = true + lastLine = line + } + } + if !printed { + scanner := bufio.NewScanner(strings.NewReader(cm.Data["log"])) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" { + continue + } + if err := printMessage(line, conn); err != nil { + return err + } + lastLine = line + } + } + printLine = false + } + + return nil +} + +func printMessage(msg string, conn *websocket.Conn) error { + writer, err := conn.NextWriter(websocket.TextMessage) + if err != nil { + return err + } + if _, err := writer.Write([]byte(base64.StdEncoding.EncodeToString([]byte(msg)))); err != nil { + return err + } + return writer.Close() +} + +func (l *log) contextAndClient(req *http.Request) (context.Context, user.Info, kubernetes.Interface, error) { + ctx := req.Context() + client, err := l.cg.AdminK8sInterface() + if err != nil { + return ctx, nil, nil, err + } + + user, ok := request.UserFrom(ctx) + if !ok { + return ctx, nil, nil, validation.Unauthorized + } + + return ctx, user, client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/shell.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/shell.go new file mode 100644 index 0000000..788e6fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/shell.go @@ -0,0 +1,166 @@ +package clusters + +import ( + "context" + "net/http" + "net/http/httputil" + "strings" + "time" + + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/steve/pkg/podimpersonation" + "github.com/rancher/steve/pkg/stores/proxy" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" +) + +type shell struct { + namespace string + impersonator *podimpersonation.PodImpersonation + cg proxy.ClientGetter + clusterRegistry string +} + +func (s *shell) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + ctx, user, client, err := s.contextAndClient(req) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + var imageOverride string + if s.clusterRegistry != "" { + imageOverride = s.clusterRegistry + "/" + settings.ShellImage.Get() + } + + pod, err := s.impersonator.CreatePod(ctx, user, s.createPod(imageOverride), &podimpersonation.PodOptions{ + Wait: true, + ImageOverride: imageOverride, + }) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + _ = client.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{}) + }() + s.proxyRequest(rw, req, pod, client) +} + +func (s *shell) proxyRequest(rw http.ResponseWriter, req *http.Request, pod *v1.Pod, client kubernetes.Interface) { + attachURL := client.CoreV1().RESTClient(). + Get(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + VersionedParams(&v1.PodExecOptions{ + Stdin: true, + Stdout: true, + Stderr: true, + TTY: true, + Container: "shell", + Command: []string{"welcome"}, + }, scheme.ParameterCodec).URL() + + httpClient := client.CoreV1().RESTClient().(*rest.RESTClient).Client + p := httputil.ReverseProxy{ + Director: func(req *http.Request) { + req.URL = attachURL + req.Host = attachURL.Host + for key := range req.Header { + if strings.HasPrefix(key, "Impersonate-Extra-") { + delete(req.Header, key) + } + } + delete(req.Header, "Impersonate-Group") + delete(req.Header, "Impersonate-User") + delete(req.Header, "Authorization") + delete(req.Header, "Cookie") + }, + Transport: httpClient.Transport, + FlushInterval: time.Millisecond * 100, + } + + p.ServeHTTP(rw, req) +} + +func (s *shell) contextAndClient(req *http.Request) (context.Context, user.Info, kubernetes.Interface, error) { + ctx := req.Context() + client, err := s.cg.AdminK8sInterface() + if err != nil { + return ctx, nil, nil, err + } + + user, ok := request.UserFrom(ctx) + if !ok { + return ctx, nil, nil, validation.Unauthorized + } + + return ctx, user, client, nil +} + +func (s *shell) createPod(imageOverride string) *v1.Pod { + imageName := imageOverride + if imageName == "" { + imageName = settings.FullShellImage() + } + return &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "dashboard-shell-", + Namespace: s.namespace, + }, + Spec: v1.PodSpec{ + TerminationGracePeriodSeconds: new(int64), + RestartPolicy: v1.RestartPolicyNever, + NodeSelector: map[string]string{ + "kubernetes.io/os": "linux", + }, + Tolerations: []v1.Toleration{ + { + Key: "cattle.io/os", + Operator: "Equal", + Value: "linux", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/controlplane", + Operator: "Equal", + Value: "true", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/etcd", + Operator: "Equal", + Value: "true", + Effect: "NoExecute", + }, + }, + Containers: []v1.Container{ + { + Name: "shell", + TTY: true, + Stdin: true, + StdinOnce: true, + Env: []v1.EnvVar{ + { + Name: "KUBECONFIG", + Value: "/home/shell/.kube/config", + }, + }, + Image: imageName, + ImagePullPolicy: v1.PullIfNotPresent, + }, + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/types.go new file mode 100644 index 0000000..d7c6cf0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/clusters/types.go @@ -0,0 +1,5 @@ +package clusters + +type GenerateKubeconfigOutput struct { + Config string `json:"config,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/disallow/disallow.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/disallow/disallow.go new file mode 100644 index 0000000..5eb873c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/disallow/disallow.go @@ -0,0 +1,66 @@ +package disallow + +import ( + "net/http" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/steve/pkg/attributes" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" +) + +// The resource names must be plural. +var ( + // AllowAll is a set of resources for which Rancher doesn't require admin level access to manipulate directly through kubectl. + AllowAll = map[string]bool{ + "clusterproxyconfigs": true, + "clusterroletemplatebindings": true, + "globalrolebindings": true, + "globalroles": true, + "podsecurityadmissionconfigurationtemplates": true, + "projects": true, + "projectroletemplatebindings": true, + } + allowPost = map[string]bool{ + "settings": true, + } + allowPut = map[string]bool{ + "features": true, + "settings": true, + } + disallowGet = map[string]bool{ + "preferences": true, + "sourcecodecredentials": true, + "sourcecodeproviderconfigs": true, + "sourcecoderepositories": true, + "templatecontents": true, + "templates": true, + "templateversions": true, + "tokens": true, + } +) + +func Register(server *steve.Server) { + server.SchemaFactory.AddTemplate(schema2.Template{ + Customize: func(schema *types.APISchema) { + gr := attributes.GR(schema) + if gr.Group == "management.cattle.io" || gr.Group == "project.cattle.io" { + if AllowAll[gr.Resource] { + return + } + attributes.AddDisallowMethods(schema, + http.MethodPatch, + http.MethodDelete) + if !allowPut[gr.Resource] { + attributes.AddDisallowMethods(schema, http.MethodPut) + } + if !allowPost[gr.Resource] { + attributes.AddDisallowMethods(schema, http.MethodPost) + } + if disallowGet[gr.Resource] { + attributes.AddDisallowMethods(schema, http.MethodGet) + } + } + }, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/github/github.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/github/github.go new file mode 100644 index 0000000..973fce6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/github/github.go @@ -0,0 +1,81 @@ +package github + +import ( + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "strings" + + "github.com/gorilla/mux" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type Proxy struct { + proxy *httputil.ReverseProxy + secrets v1.SecretCache + secretNamespace string + key string +} + +func NewProxy(secrets v1.SecretCache, githubURL, namespace, dataKey string) (http.Handler, error) { + gURL, err := url.Parse(githubURL) + if err != nil { + return nil, err + } + + return &Proxy{ + proxy: &httputil.ReverseProxy{ + Director: func(req *http.Request) { + path := mux.Vars(req)["path"] + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + if gURL.Path != "" { + req.URL.Path = gURL.Path + req.URL.Path + } + req.URL.Path = path + req.URL.Scheme = gURL.Scheme + req.URL.Host = gURL.Host + req.Host = gURL.Host + }, + }, + secrets: secrets, + secretNamespace: namespace, + key: dataKey, + }, nil +} + +func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + user, ok := request.UserFrom(req.Context()) + if !ok { + notFound(rw, "user not found") + return + } + + secretName := fmt.Sprintf("%s-secret", user.GetName()) + secret, err := p.secrets.Get(p.secretNamespace, secretName) + if err != nil { + notFound(rw, err.Error()) + return + } + + token := string(secret.Data[p.key]) + if token == "" { + notFound(rw, "token not found") + return + } + + req.Header.Del("Cookie") + req.Header.Del("Authorization") + req.SetBasicAuth(user.GetName(), token) + p.proxy.ServeHTTP(rw, req) +} + +func notFound(rw http.ResponseWriter, msg string) { + rw.WriteHeader(http.StatusNotFound) + if msg != "" { + rw.Write([]byte(msg)) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/health/health.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/health/health.go new file mode 100644 index 0000000..7c77bb1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/health/health.go @@ -0,0 +1,25 @@ +package health + +import ( + "net/http" + + "github.com/gorilla/mux" + "k8s.io/apiserver/pkg/server/healthz" +) + +func Register(router *mux.Router) { + healthz.InstallHandler((*muxWrapper)(router)) + router.Handle("/ping", Pong()) +} + +func Pong() http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + rw.Write([]byte("pong")) + }) +} + +type muxWrapper mux.Router + +func (m *muxWrapper) Handle(path string, handler http.Handler) { + (*mux.Router)(m).Handle(path, handler) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/download.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/download.go new file mode 100644 index 0000000..d781cff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/download.go @@ -0,0 +1,63 @@ +package machine + +import ( + "archive/zip" + "bytes" + "encoding/json" + "fmt" + "net/http" + "strconv" + + "github.com/rancher/apiserver/pkg/types" +) + +func (s *sshClient) download(apiContext *types.APIRequest) error { + machineInfo, err := s.getSSHKey(apiContext.Namespace, apiContext.Name) + if err != nil { + return err + } + + buf := &bytes.Buffer{} + zw := zip.NewWriter(buf) + name := machineInfo.Driver.MachineName + + if err := addFile(zw, name+"/id_rsa", machineInfo.IDRSA); err != nil { + return err + } + if err := addFile(zw, name+"/id_rsa.pub", machineInfo.IDRSAPub); err != nil { + return err + } + machineConfigBytes, err := json.Marshal(machineInfo.Driver) + if err != nil { + return err + } + if err := addFile(zw, name+"/config.json", machineConfigBytes); err != nil { + return err + } + if err := zw.Close(); err != nil { + return err + } + + apiContext.Response.Header().Set("Content-Length", strconv.Itoa(len(buf.Bytes()))) + apiContext.Response.Header().Set("Content-Type", "application/octet-stream") + apiContext.Response.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip", name)) + apiContext.Response.Header().Set("Cache-Control", "private") + apiContext.Response.Header().Set("Pragma", "private") + apiContext.Response.Header().Set("Expires", "Wed 24 Feb 1982 18:42:00 GMT") + apiContext.Response.WriteHeader(http.StatusOK) + _, err = apiContext.Response.Write(buf.Bytes()) + return err +} + +func addFile(zw *zip.Writer, name string, contents []byte) error { + fh := &zip.FileHeader{ + Name: name, + } + fh.SetMode(0400) + w, err := zw.CreateHeader(fh) + if err != nil { + return err + } + _, err = w.Write(contents) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/machine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/machine.go new file mode 100644 index 0000000..47bad3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/machine.go @@ -0,0 +1,37 @@ +package machine + +import ( + "net/http" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/wrangler" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" +) + +func Register(server *steve.Server, clients *wrangler.Context) { + sshClient := &sshClient{ + machines: clients.CAPI.Machine(), + secrets: clients.Core.Secret(), + } + + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "cluster.x-k8s.io", + Kind: "Machine", + Customize: func(schema *types.APISchema) { + if schema.LinkHandlers == nil { + schema.LinkHandlers = map[string]http.Handler{} + } + schema.LinkHandlers["shell"] = sshClient + schema.LinkHandlers["sshkeys"] = sshClient + schema.Formatter = func(request *types.APIRequest, resource *types.RawResource) { + if err := request.AccessControl.CanUpdate(request, types.APIObject{}, request.Schema); err != nil || + resource.APIObject.Data().String("spec", "infrastructureRef", "apiVersion") != capr.RKEMachineAPIVersion { + delete(resource.Links, "shell") + delete(resource.Links, "sshkeys") + } + } + }, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/ssh.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/ssh.go new file mode 100644 index 0000000..9b52285 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/machine/ssh.go @@ -0,0 +1,240 @@ +package machine + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "path/filepath" + "time" + + "github.com/gorilla/websocket" + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "golang.org/x/crypto/ssh" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type sshClient struct { + secrets corecontrollers.SecretClient + machines capicontrollers.MachineClient +} + +var upgrader = websocket.Upgrader{ + HandshakeTimeout: 5 * time.Second, + CheckOrigin: func(r *http.Request) bool { return true }, + Subprotocols: []string{"base64.channel.k8s.io"}, + Error: onError, +} + +func onError(rw http.ResponseWriter, _ *http.Request, code int, err error) { + rw.WriteHeader(code) + rw.Write([]byte(err.Error())) +} + +func (s *sshClient) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + apiRequest := types.GetAPIContext(req.Context()) + if err := apiRequest.AccessControl.CanUpdate(apiRequest, types.APIObject{}, apiRequest.Schema); err != nil { + apiRequest.WriteError(err) + return + } + + switch apiRequest.Link { + case "shell": + if err := s.shell(apiRequest); err != nil { + apiRequest.WriteError(err) + return + } + case "sshkeys": + if err := s.download(apiRequest); err != nil { + apiRequest.WriteError(err) + return + } + } +} + +func (s *sshClient) shell(apiRequest *types.APIRequest) error { + ctx, cancel := context.WithCancel(apiRequest.Context()) + defer cancel() + + req := apiRequest.Request.WithContext(ctx) + conn, err := upgrader.Upgrade(apiRequest.Response, req, nil) + if err != nil { + return err + } + + defer conn.Close() + machineInfo, err := s.getSSHKey(apiRequest.Namespace, apiRequest.Name) + if err != nil { + return err + } + + signer, err := ssh.ParsePrivateKey(machineInfo.IDRSA) + if err != nil { + return err + } + + addr := fmt.Sprintf("%s:%d", machineInfo.Driver.IPAddress, machineInfo.Driver.SSHPort) + client, err := ssh.Dial("tcp", addr, &ssh.ClientConfig{ + User: machineInfo.Driver.SSHUser, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + Timeout: 30 * time.Second, + }) + if err != nil { + return err + } + defer client.Close() + + session, err := client.NewSession() + if err != nil { + return err + } + if err := session.RequestPty("xterm", 20, 80, ssh.TerminalModes{}); err != nil { + return err + } + + stdIn, err := session.StdinPipe() + if err != nil { + return err + } + + stdOut, err := session.StdoutPipe() + if err != nil { + return err + } + + if err := session.Shell(); err != nil { + return err + } + + go func() { + defer cancel() + defer conn.Close() + io.Copy(&writer{conn: conn}, stdOut) + }() + + for { + _, data, err := conn.ReadMessage() + if err != nil { + return err + } + s := string(data) + if len(s) == 0 { + continue + } + if s[0:1] == "0" { + data, err := base64.StdEncoding.DecodeString(s[1:]) + if err != nil { + return err + } + if _, err := stdIn.Write(data); err != nil { + return err + } + } else if s[0:1] == "4" { + data, err := base64.StdEncoding.DecodeString(s[1:]) + if err != nil { + return err + } + resize := &resizeRequest{} + if err := json.Unmarshal(data, resize); err != nil { + return err + } + if err := session.WindowChange(resize.Height, resize.Width); err != nil { + return err + } + } + } +} + +type resizeRequest struct { + Height int + Width int +} + +type machineInfo struct { + IDRSA []byte + IDRSAPub []byte + Driver machineConfig +} + +type machineConfig struct { + IPAddress string + SSHUser string + SSHPort int + MachineName string +} + +func (s *sshClient) getSSHKey(machineNamespace, machineName string) (*machineInfo, error) { + result := &machineInfo{} + machine, err := s.machines.Get(machineNamespace, machineName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + secretName := capr.MachineStateSecretName(machine.Spec.InfrastructureRef.Name) + secret, err := s.secrets.Get(machineNamespace, secretName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + gz, err := gzip.NewReader(bytes.NewReader(secret.Data["extractedConfig"])) + if err != nil { + return nil, err + } + + tar := tar.NewReader(gz) + + for { + header, err := tar.Next() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } + + data, err := ioutil.ReadAll(tar) + if err != nil { + return nil, err + } + switch filepath.Base(header.Name) { + case "id_rsa": + result.IDRSA = data + case "id_rsa.pub": + result.IDRSAPub = data + case "config.json": + err := json.Unmarshal(data, result) + if err != nil { + return nil, err + } + } + } + + return result, nil +} + +type writer struct { + conn *websocket.Conn +} + +func (w *writer) Write(buf []byte) (int, error) { + data := []byte("1" + base64.StdEncoding.EncodeToString(buf)) + m, err := w.conn.NextWriter(websocket.TextMessage) + if err != nil { + return 0, err + } + if _, err := m.Write(data); err != nil { + return 0, err + } + return len(buf), m.Close() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/navlinks.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/navlinks.go new file mode 100644 index 0000000..a7104ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/navlinks.go @@ -0,0 +1,21 @@ +package navlinks + +import ( + "context" + + "github.com/rancher/apiserver/pkg/types" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" +) + +func Register(ctx context.Context, server *steve.Server) { + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "ui.cattle.io", + Kind: "NavLink", + StoreFactory: func(innerStore types.Store) types.Store { + return &store{ + Store: innerStore, + } + }, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/store.go new file mode 100644 index 0000000..a99240b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/navlinks/store.go @@ -0,0 +1,77 @@ +package navlinks + +import ( + "fmt" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" +) + +type store struct { + types.Store +} + +func (e *store) ByID(apiOp *types.APIRequest, schema *types.APISchema, id string) (types.APIObject, error) { + result, err := e.Store.ByID(apiOp, schema, id) + if err != nil { + return result, err + } + if !hasAccess(apiOp, result) { + return types.APIObject{}, validation.NotFound + } + return result, err +} + +func hasAccess(apiOp *types.APIRequest, result types.APIObject) bool { + data := result.Data().Map("spec", "toService") + if len(data) == 0 { + return true + } + + scheme := data.String("scheme") + if scheme == "" { + scheme = "http" + } + port := data.String("port") + if port == "" { + port = "80" + } + + serviceNamespace := data.String("namespace") + serviceName := fmt.Sprintf("%s:%s:%s", scheme, data.String("name"), port) + return apiOp.AccessControl.CanDo(apiOp, "/services/proxy", "get", serviceNamespace, serviceName) == nil +} + +func (e *store) List(apiOp *types.APIRequest, schema *types.APISchema) (types.APIObjectList, error) { + result, err := e.Store.List(apiOp, schema) + if err != nil { + return result, err + } + filtered := result + filtered.Objects = make([]types.APIObject, 0, len(filtered.Objects)) + for _, obj := range result.Objects { + if hasAccess(apiOp, obj) { + filtered.Objects = append(filtered.Objects, obj) + } + } + return filtered, nil +} + +func (e *store) Watch(apiOp *types.APIRequest, schema *types.APISchema, wr types.WatchRequest) (chan types.APIEvent, error) { + result, err := e.Store.Watch(apiOp, schema, wr) + if err != nil { + return result, err + } + + newResult := make(chan types.APIEvent, 1) + go func() { + defer close(newResult) + for event := range result { + if hasAccess(apiOp, event.Object) { + newResult <- event + } + } + }() + + return newResult, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/norman/formatter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/norman/formatter.go new file mode 100644 index 0000000..31a865b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/norman/formatter.go @@ -0,0 +1,131 @@ +package norman + +import ( + "fmt" + "strings" + + "github.com/rancher/apiserver/pkg/types" + types2 "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/urlbuilder" + v3 "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" +) + +type LinksAndActionsFormatter struct { + multiClusterManager wrangler.MultiClusterManager + apiVersion types2.APIVersion + schemaID string +} + +func NewLinksAndActionsFormatter(multiClusterManager wrangler.MultiClusterManager, apiVersion types2.APIVersion, + schemaID string) types.Formatter { + formatter := LinksAndActionsFormatter{ + multiClusterManager: multiClusterManager, + apiVersion: apiVersion, + schemaID: schemaID, + } + return formatter.Formatter +} + +func (a *LinksAndActionsFormatter) Formatter(request *types.APIRequest, resource *types.RawResource) { + schemas := a.multiClusterManager.NormanSchemas() + if schemas == nil { + return + } + + schema := schemas.Schema(&a.apiVersion, a.schemaID) + if schema == nil { + logrus.Errorf("failed to find schema %s in %v", a.schemaID, a.apiVersion) + return + } + + data, err := convert.EncodeToMap(resource.APIObject.Object) + if err != nil { + logrus.Errorf("failed to json encode api object: %v", err) + return + } + schema.Mapper.FromInternal(data) + + normanResource := &types2.RawResource{ + ID: resource.APIObject.ID, + Type: "cluster", + Schema: schema, + Links: map[string]string{}, + Actions: map[string]string{}, + Values: data, + } + normanRequest := types2.NewAPIContext(request.Request, request.Response, schemas) + normanRequest.URLBuilder, err = urlbuilder.New(request.Request, v3.Version, schemas) + normanRequest.AccessControl = accessControlWrapper{ + ac: request.AccessControl, + apiRequest: request, + } + if err != nil { + logrus.Errorf("failed to create url builder: %v", err) + return + } + + schema.Formatter(normanRequest, normanResource) + for k, v := range normanResource.Links { + resource.Links[k] = v + } + for k, v := range normanResource.Actions { + resource.Actions[k] = v + } +} + +type accessControlWrapper struct { + ac types.AccessControl + apiRequest *types.APIRequest +} + +func (a accessControlWrapper) CanDo(apiGroup, resource, verb string, apiContext *types2.APIContext, obj map[string]interface{}, schema *types2.Schema) error { + name, namespace := getNameAndNS(obj) + // The access control used by this function (schema based - provided by rancher/APIserver), expects the resource in + // the below format. We re-format it here since the original format does not match what is expected by the api server + formattedResource := fmt.Sprintf("%s/%s", apiGroup, resource) + return a.ac.CanDo(a.apiRequest, formattedResource, verb, namespace, name) +} + +func getNameAndNS(obj map[string]interface{}) (string, string) { + var id string + var namespace string + + if obj != nil { + id, _ = obj["id"].(string) + namespace, _ = obj["namespaceId"].(string) + if namespace == "" { + pieces := strings.Split(id, ":") + if len(pieces) == 2 { + namespace = pieces[0] + } + } + } + + id = strings.TrimPrefix(id, namespace+":") + return id, namespace +} + +func (a accessControlWrapper) CanCreate(apiContext *types2.APIContext, schema *types2.Schema) error { + panic("not implemented") +} +func (a accessControlWrapper) CanGet(apiContext *types2.APIContext, schema *types2.Schema) error { + panic("not implemented") +} +func (a accessControlWrapper) CanList(apiContext *types2.APIContext, schema *types2.Schema) error { + panic("not implemented") +} +func (a accessControlWrapper) CanUpdate(apiContext *types2.APIContext, obj map[string]interface{}, schema *types2.Schema) error { + panic("not implemented") +} +func (a accessControlWrapper) CanDelete(apiContext *types2.APIContext, obj map[string]interface{}, schema *types2.Schema) error { + panic("not implemented") +} +func (a accessControlWrapper) Filter(apiContext *types2.APIContext, schema *types2.Schema, obj map[string]interface{}, context map[string]string) map[string]interface{} { + panic("not implemented") +} +func (a accessControlWrapper) FilterList(apiContext *types2.APIContext, schema *types2.Schema, obj []map[string]interface{}, context map[string]string) []map[string]interface{} { + panic("not implemented") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/projects.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/projects.go new file mode 100644 index 0000000..24d0c47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/projects.go @@ -0,0 +1,119 @@ +package projects + +import ( + "context" + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/apiserver/pkg/server" + "github.com/rancher/apiserver/pkg/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/steve/pkg/accesscontrol" + "github.com/rancher/steve/pkg/attributes" + "github.com/rancher/steve/pkg/auth" + "github.com/rancher/steve/pkg/client" + "github.com/rancher/steve/pkg/schema" + steveserver "github.com/rancher/steve/pkg/server" + "github.com/rancher/steve/pkg/stores/proxy" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" +) + +type projectServer struct { + ctx context.Context + asl accesscontrol.AccessSetLookup + auth auth.Middleware + cf *client.Factory + clusterLinks []string + namespaceCache corecontrollers.NamespaceCache +} + +func Projects(ctx context.Context, config *wrangler.Context, server *steveserver.Server) (func(http.Handler) http.Handler, error) { + s := projectServer{} + if err := s.Setup(ctx, config, server); err != nil { + return nil, err + } + return s.middleware(), nil +} + +func (s *projectServer) Setup(ctx context.Context, config *wrangler.Context, server *steveserver.Server) error { + s.ctx = ctx + s.asl = server.AccessSetLookup + s.cf = server.ClientFactory + s.namespaceCache = config.Core.Namespace().Cache() + + server.SchemaFactory.AddTemplate(schema.Template{ + ID: "management.cattle.io.cluster", + Formatter: func(request *types.APIRequest, resource *types.RawResource) { + for _, link := range s.clusterLinks { + resource.Links[link] = request.URLBuilder.Link(resource.Schema, resource.ID, link) + } + }, + }) + + return nil +} + +func (s *projectServer) newSchemas() *types.APISchemas { + store := proxy.NewProxyStore(s.cf, nil, s.asl, s.namespaceCache) + schemas := types.EmptyAPISchemas() + + schemas.MustImportAndCustomize(v3.Project{}, func(schema *types.APISchema) { + schema.Store = store + attributes.SetNamespaced(schema, true) + attributes.SetGroup(schema, v3.GroupName) + attributes.SetVersion(schema, "v3") + attributes.SetKind(schema, "Project") + attributes.SetResource(schema, "projects") + attributes.SetVerbs(schema, []string{"create", "list", "get", "delete", "update", "watch", "patch"}) + s.clusterLinks = append(s.clusterLinks, "projects") + }) + + return schemas +} + +func (s *projectServer) newAPIHandler() http.Handler { + server := server.DefaultAPIServer() + for k, v := range server.ResponseWriters { + server.ResponseWriters[k] = stripNS{writer: v} + } + + s.clusterLinks = []string{ + "subscribe", + "schemas", + } + + sf := schema.NewCollection(s.ctx, server.Schemas, s.asl) + sf.Reset(s.newSchemas().Schemas) + + return schema.WrapServer(sf, server) +} + +func (s *projectServer) middleware() func(http.Handler) http.Handler { + server := s.newAPIHandler() + server = prefix(server) + + router := mux.NewRouter() + router.UseEncodedPath() + router.Path("/v1/management.cattle.io.clusters/{namespace}").Queries("link", "{type:projects?}").Handler(server) + router.Path("/v1/management.cattle.io.clusters/{namespace}/{type}").Handler(server) + router.Path("/v1/management.cattle.io.clusters/{namespace}/{type}/{name}").Handler(server) + router.Path("/v1/management.cattle.io.clusters/{clusterID}/{type}/{namespace}/{name}").Handler(server) + + return func(next http.Handler) http.Handler { + router.NotFoundHandler = next + return router + } +} + +func prefix(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + if vars["clusterID"] != "" { + vars["prefix"] = "/v1/management.cattle.io.clusters/" + vars["clusterID"] + } else { + vars["prefix"] = "/v1/management.cattle.io.clusters/" + vars["namespace"] + } + next.ServeHTTP(rw, req) + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/responsewriter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/responsewriter.go new file mode 100644 index 0000000..10631c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/projects/responsewriter.go @@ -0,0 +1,35 @@ +package projects + +import ( + "strings" + + "github.com/gorilla/mux" + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/wrangler/v3/pkg/kv" +) + +type stripNS struct { + writer types.ResponseWriter +} + +func (s stripNS) Write(apiOp *types.APIRequest, code int, obj types.APIObject) { + if mux.Vars(apiOp.Request)["clusterID"] == "" { + prefix := apiOp.Namespace + "/" + if strings.HasPrefix(obj.ID, prefix) { + _, obj.ID = kv.RSplit(obj.ID, "/") + } + } + s.writer.Write(apiOp, code, obj) +} + +func (s stripNS) WriteList(apiOp *types.APIRequest, code int, obj types.APIObjectList) { + if mux.Vars(apiOp.Request)["clusterID"] == "" { + prefix := apiOp.Namespace + "/" + for i := range obj.Objects { + if strings.HasPrefix(obj.Objects[i].ID, prefix) { + _, obj.Objects[i].ID = kv.RSplit(obj.Objects[i].ID, "/") + } + } + } + s.writer.WriteList(apiOp, code, obj) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/auth.go new file mode 100644 index 0000000..e0d3c96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/auth.go @@ -0,0 +1,47 @@ +package proxy + +import ( + "net/http" + "strings" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/remotedialer" + apierror "k8s.io/apimachinery/pkg/api/errors" +) + +const ( + tokenIndex = "clusterToken" + Prefix = "stv-cluster-" +) + +type clusterProxyAuthorizer struct { + tokenCache v3.ClusterRegistrationTokenCache +} + +func NewAuthorizer(wrangler *wrangler.Context) remotedialer.Authorizer { + a := &clusterProxyAuthorizer{ + tokenCache: wrangler.Mgmt.ClusterRegistrationToken().Cache(), + } + a.tokenCache.AddIndexer(tokenIndex, func(obj *apimgmtv3.ClusterRegistrationToken) ([]string, error) { + return []string{obj.Status.Token}, nil + }) + + return a.Authorize +} + +func (a *clusterProxyAuthorizer) Authorize(req *http.Request) (string, bool, error) { + auth := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ") + if !strings.HasPrefix(auth, Prefix) { + return "", false, nil + } + crts, err := a.tokenCache.GetByIndex(tokenIndex, strings.TrimPrefix(auth, Prefix)) + if apierror.IsNotFound(err) || len(crts) == 0 { + return "", false, nil + } else if err != nil { + return "", false, err + } + + return Prefix + crts[0].Namespace, true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy.go new file mode 100644 index 0000000..b768b99 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy.go @@ -0,0 +1,250 @@ +package proxy + +import ( + "context" + "fmt" + "net" + "net/http" + "strings" + "time" + + gmux "github.com/gorilla/mux" + "github.com/rancher/rancher/pkg/api/steve/disallow" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/remotedialer" + "github.com/rancher/steve/pkg/auth" + "github.com/rancher/steve/pkg/proxy" + "github.com/sirupsen/logrus" + authzv1 "k8s.io/api/authorization/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/authorization/authorizerfactory" + "k8s.io/apiserver/pkg/endpoints/request" + v1 "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/rest" +) + +type Handler struct { + authorizer authorizer.Authorizer + dialerFactory ClusterDialerFactory + requestInfoFactory request.RequestInfoFactory +} + +type ClusterDialerFactory func(clusterID string) remotedialer.Dialer + +func RewriteLocalCluster(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if strings.HasPrefix(req.URL.Path, "/k8s/clusters/local") { + req.URL.Path = strings.TrimPrefix(req.URL.Path, "/k8s/clusters/local") + if req.URL.Path == "" { + req.URL.Path = "/" + } + } + next.ServeHTTP(rw, req) + }) +} + +func NewProxyMiddleware(sar v1.AuthorizationV1Interface, + dialerFactory ClusterDialerFactory, + clusters v3.ClusterCache, + localSupport bool, + localCluster http.Handler) (func(http.Handler) http.Handler, error) { + cfg := authorizerfactory.DelegatingAuthorizerConfig{ + SubjectAccessReviewClient: sar, + AllowCacheTTL: time.Second * time.Duration(settings.AuthorizationCacheTTLSeconds.GetInt()), + DenyCacheTTL: time.Second * time.Duration(settings.AuthorizationDenyCacheTTLSeconds.GetInt()), + WebhookRetryBackoff: &auth.WebhookBackoff, + } + + authorizer, err := cfg.New() + if err != nil { + return nil, err + } + + proxyHandler := NewProxyHandler(authorizer, dialerFactory, clusters) + + mux := gmux.NewRouter() + mux.UseEncodedPath() + mux.PathPrefix("/api").MatcherFunc(proxyHandler.matchManagementCRDs()).HandlerFunc(proxyHandler.authLocalCluster(mux)) + mux.Path("/v1/management.cattle.io.clusters/{clusterID}").Queries("link", "shell").HandlerFunc(routeToShellProxy("link", "shell", localSupport, localCluster, mux, proxyHandler)) + mux.Path("/v1/management.cattle.io.clusters/{clusterID}").Queries("action", "apply").HandlerFunc(routeToShellProxy("action", "apply", localSupport, localCluster, mux, proxyHandler)) + mux.Path("/v3/clusters/{clusterID}").Queries("shell", "true").HandlerFunc(routeToShellProxy("link", "shell", localSupport, localCluster, mux, proxyHandler)) + mux.Path("/{prefix:k8s/clusters/[^/]+}{suffix:/v1.*}").MatcherFunc(proxyHandler.MatchNonLegacy("/k8s/clusters/")).Handler(proxyHandler) + + return func(handler http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + mux.NotFoundHandler = handler + mux.ServeHTTP(rw, req) + }) + }, nil +} + +func routeToShellProxy(key, value string, localSupport bool, localCluster http.Handler, mux *gmux.Router, proxyHandler *Handler) func(rw http.ResponseWriter, r *http.Request) { + return func(rw http.ResponseWriter, r *http.Request) { + vars := gmux.Vars(r) + cluster := vars["clusterID"] + if cluster == "local" { + if localSupport { + authed := proxyHandler.userCanAccessCluster(r, cluster) + if !authed { + rw.WriteHeader(http.StatusUnauthorized) + return + } + q := r.URL.Query() + q.Set(key, value) + r.URL.RawQuery = q.Encode() + r.URL.Path = "/v1/management.cattle.io.clusters/local" + localCluster.ServeHTTP(rw, r) + } else { + mux.NotFoundHandler.ServeHTTP(rw, r) + } + return + } + vars["prefix"] = "k8s/clusters/" + cluster + vars["suffix"] = "/v1/management.cattle.io.clusters/local" + q := r.URL.Query() + q.Set(key, value) + r.URL.RawQuery = q.Encode() + r.URL.Path = "/k8s/clusters/" + cluster + "/v1/management.cattle.io.clusters/local" + proxyHandler.ServeHTTP(rw, r) + } +} + +func NewProxyHandler(authorizer authorizer.Authorizer, + dialerFactory ClusterDialerFactory, + clusters v3.ClusterCache) *Handler { + return &Handler{ + authorizer: authorizer, + dialerFactory: dialerFactory, + requestInfoFactory: request.RequestInfoFactory{APIPrefixes: sets.NewString("apis", "api"), GrouplessAPIPrefixes: sets.NewString("api")}, + } +} + +func (h *Handler) MatchNonLegacy(prefix string) gmux.MatcherFunc { + return func(req *http.Request, match *gmux.RouteMatch) bool { + clusterID := strings.TrimPrefix(req.URL.Path, prefix) + clusterID = strings.SplitN(clusterID, "/", 2)[0] + if match.Vars == nil { + match.Vars = map[string]string{} + } + match.Vars["clusterID"] = clusterID + + return true + } +} + +func (h *Handler) authLocalCluster(router *gmux.Router) func(rw http.ResponseWriter, r *http.Request) { + return func(rw http.ResponseWriter, req *http.Request) { + authed := h.userCanAccessCluster(req, "local") + if !authed { + rw.WriteHeader(http.StatusForbidden) + return + } + router.NotFoundHandler.ServeHTTP(rw, req) + } +} + +// matchManagementCRDs matches paths that are for management CRDs that are not in the allow-list of specific management resources. +// To decide what to match, it tries to extract request information from the URL path and examine the group and resource. +func (h *Handler) matchManagementCRDs() gmux.MatcherFunc { + return func(req *http.Request, match *gmux.RouteMatch) bool { + info, err := h.requestInfoFactory.NewRequestInfo(req) + if err != nil { + // This isn't a K8s request, don't match it. + return false + } + return info.APIGroup == managementv3.GroupName && info.Resource != "" && !disallow.AllowAll[info.Resource] + } +} + +func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + clusterID := gmux.Vars(req)["clusterID"] + authed := h.userCanAccessCluster(req, clusterID) + if !authed { + rw.WriteHeader(http.StatusUnauthorized) + return + } + prefix := "/" + gmux.Vars(req)["prefix"] + handler, err := h.next(clusterID, prefix) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte(err.Error())) + return + } + + handler.ServeHTTP(rw, req) +} + +func (h *Handler) userCanAccessCluster(req *http.Request, clusterID string) bool { + requestUser, ok := request.UserFrom(req.Context()) + if ok { + return h.canAccess(req.Context(), requestUser, clusterID) + } + return false +} + +func (h *Handler) dialer(ctx context.Context, network, address string) (net.Conn, error) { + host, _, err := net.SplitHostPort(address) + if err != nil { + return nil, err + } + dialer := h.dialerFactory("stv-cluster-" + host) + var conn net.Conn + for i := 0; i < 15; i++ { + conn, err = dialer(ctx, network, "127.0.0.1:6080") + if err != nil && strings.Contains(err.Error(), "failed to find Session for client") { + if i < 14 { + logrus.Tracef("steve.proxy.dialer: lost connection, retrying") + time.Sleep(time.Second) + } else { + logrus.Tracef("steve.proxy.dialer: lost connection, failed to reconnect after 15 attempts") + } + } else { + break + } + } + if err != nil { + return conn, fmt.Errorf("lost connection to cluster: %w", err) + } + return conn, nil +} + +func (h *Handler) next(clusterID, prefix string) (http.Handler, error) { + cfg := &rest.Config{ + // this is bogus, the dialer will change it to 127.0.0.1:6080, but the clusterID is used to lookup the tunnel + // connect + Host: "http://" + clusterID, + UserAgent: rest.DefaultKubernetesUserAgent() + " cluster " + clusterID, + Transport: &http.Transport{ + DialContext: h.dialer, + }, + } + + next := proxy.ImpersonatingHandler(prefix, cfg) + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + req.Header.Set("X-API-URL-Prefix", prefix) + next.ServeHTTP(rw, req) + }), nil +} + +func (h *Handler) canAccess(ctx context.Context, user user.Info, clusterID string) bool { + extra := map[string]authzv1.ExtraValue{} + for k, v := range user.GetExtra() { + extra[k] = v + } + + resp, _, err := h.authorizer.Authorize(ctx, authorizer.AttributesRecord{ + ResourceRequest: true, + User: user, + Verb: "get", + APIGroup: managementv3.GroupName, + APIVersion: managementv3.Version, + Resource: "clusters", + Name: clusterID, + }) + + return err == nil && resp == authorizer.DecisionAllow +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy_test.go new file mode 100644 index 0000000..686c075 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/proxy/proxy_test.go @@ -0,0 +1,466 @@ +package proxy_test + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + + "github.com/rancher/rancher/pkg/api/steve/proxy" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/remotedialer" + "github.com/stretchr/testify/assert" + authv1 "k8s.io/api/authorization/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + k8sUser "k8s.io/apiserver/pkg/authentication/user" + k8sRequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes/scheme" + typedv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + v1 "k8s.io/client-go/tools/clientcmd/api/v1" +) + +func TestLocalCluster(t *testing.T) { + t.Parallel() + const defaultResponseCode = 210 // so far an unused code, works to not set off any edge cases (is also in 200s) + const defaultResponseMessage = "Default response" + const defaultToken = "01020305081321345589" // token for testing, has shortened, random-like value + const testUserUsername = "test-user" + tests := []struct { + name string + requestPath string + userCanAccessLocal bool + desiredResponseCode int + desiredResponseMessage string + }{ + { + name: "no matching path", + requestPath: "/v1/not/a/path", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd allowed with local cluster access", + requestPath: "/apis/management.cattle.io/v3/test-crd", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd disallowed without local cluster access", + requestPath: "/apis/management.cattle.io/v3/fake-crd", + userCanAccessLocal: false, + desiredResponseCode: http.StatusForbidden, + desiredResponseMessage: "", + }, + { + name: "management crd disallowed with individual resource without local cluster access", + requestPath: "/apis/management.cattle.io/v3/fake-crd/hello", + userCanAccessLocal: false, + desiredResponseCode: http.StatusForbidden, + desiredResponseMessage: "", + }, + { + name: "management crd disallowed with individual resource's status without local cluster access", + requestPath: "/apis/management.cattle.io/v3/fake-crd/hello/status", + userCanAccessLocal: false, + desiredResponseCode: http.StatusForbidden, + desiredResponseMessage: "", + }, + { + name: "management crd allowed without local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd allowed without local cluster access with trailing slash", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates/", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd allowed with local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd allowed with individual resource without local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates/mytemplate", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management crd allowed with individual resource's status without local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates/mytemplate/status", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "core type without local cluster access", + requestPath: "/api/v1/pods", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "core type with local cluster access", + requestPath: "/api/v1/pods", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "non management type without local cluster access", + requestPath: "/apis/provisioning.cattle.io/v1/clusters", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "non management type with local cluster access", + requestPath: "/apis/provisioning.cattle.io/v1/clusters", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "discovery call for management resource without local cluster access", + requestPath: "/apis/management.cattle.io/v3", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "discovery call for management resource with local cluster access", + requestPath: "/apis/management.cattle.io/v3", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "discovery call for core resource without local cluster access", + requestPath: "/api/v1", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "discovery call for core resource with local cluster access", + requestPath: "/api/v1", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management resource of v000 version with local cluster access", + requestPath: "/apis/management.cattle.io/v000/podsecurityadmissionconfigurationtemplates", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "management resource of v000 version without local cluster access", + requestPath: "/apis/management.cattle.io/v000/podsecurityadmissionconfigurationtemplates", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "bad path without local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates/hello/world/foo/bar", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "bad path with local cluster access", + requestPath: "/apis/management.cattle.io/v3/podsecurityadmissionconfigurationtemplates/hello/world/foo/bar/baz", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "special support path without cluster access", + requestPath: "/healthz", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "special support path with cluster access", + requestPath: "/healthz", + userCanAccessLocal: true, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + { + name: "short path", + requestPath: "/apis/hello", + userCanAccessLocal: false, + desiredResponseCode: defaultResponseCode, + desiredResponseMessage: defaultResponseMessage, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + responder := DefaultHandler{ + ResponseCode: defaultResponseCode, + ResponseMessage: defaultResponseMessage, + } + + localHandler := DefaultHandler{ + ResponseCode: http.StatusNotFound, + ResponseMessage: "local cluster routed", + } + + reviewer := testReviewer{} + if test.userCanAccessLocal { + clusterGVR := schema.GroupVersionResource{ + Group: managementv3.GroupName, + Version: managementv3.Version, + Resource: "clusters", + } + reviewer.AddPermissionForUser(testUserUsername, "get", "", "local", clusterGVR) + } + + // Note: Grants must be added before this next call + server, err := NewSARServer(&reviewer, "/webhook") + assert.NoError(t, err, "error when creating sar server") + client, err := RestClientForURL(server.URL, defaultToken) + assert.NoError(t, err, "error when creating rest client") + sarWrapper := Authv1ClientInterface{Client: client} + + proxyMiddleware, err := proxy.NewProxyMiddleware(&sarWrapper, defaultDialer, nil, true, &localHandler) + assert.NoError(t, err, "unable to construct proxy middleware") + // construct the middleware with our default handler + testHandler := proxyMiddleware(&responder) + recorder := httptest.NewRecorder() + request := httptest.NewRequest("get", test.requestPath, bytes.NewReader([]byte{})) + request = addUserToRequest(testUserUsername, request) + testHandler.ServeHTTP(recorder, request) + + assert.Equal(t, test.desiredResponseCode, recorder.Code, "actual response code was different than expected") + assert.Equal(t, test.desiredResponseMessage, recorder.Body.String(), "body was different than expected") + }) + } +} + +func addUserToRequest(username string, request *http.Request) *http.Request { + currentContext := request.Context() + user := &k8sUser.DefaultInfo{ + Name: username, + } + return request.WithContext(k8sRequest.WithUser(currentContext, user)) +} + +type DefaultHandler struct { + ResponseCode int + ResponseMessage string +} + +func (d *DefaultHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(d.ResponseCode) + w.Write([]byte(d.ResponseMessage)) +} + +func defaultDialer(clusterID string) remotedialer.Dialer { + return func(ctx context.Context, network, address string) (net.Conn, error) { + return nil, fmt.Errorf("unable to construct dialer for %s", address) + } +} + +type httpError struct { + StatusCode int + Message string // Generally should be "HTTP Error". Use something else at your own risk +} + +type responseStatus struct { + Allowed bool `json:"allowed"` + Reason string `json:"reason"` + EvaluationError string `json:"evaluationError"` +} + +type response struct { + APIVersion string `json:"apiVersion"` + Status responseStatus `json:"status"` +} + +type grant struct { + username string + verb string + resource schema.GroupVersionResource + namespace string + name string +} + +type testReviewer struct { + grants []grant +} + +func (t *testReviewer) Review(sar *authv1.SubjectAccessReview) (*response, *httpError) { + sarGrant := grant{ + username: sar.Spec.User, + verb: sar.Spec.ResourceAttributes.Verb, + resource: schema.GroupVersionResource{ + Group: sar.Spec.ResourceAttributes.Group, + Version: sar.Spec.ResourceAttributes.Version, + Resource: sar.Spec.ResourceAttributes.Resource, + }, + namespace: sar.Spec.ResourceAttributes.Namespace, + name: sar.Spec.ResourceAttributes.Name, + } + for _, grant := range t.grants { + if grant == sarGrant { + return &response{ + APIVersion: authv1.SchemeGroupVersion.String(), + Status: responseStatus{ + Allowed: true, + Reason: "user has permissions", + EvaluationError: "", + }, + }, nil + } + } + return &response{ + APIVersion: authv1.SchemeGroupVersion.String(), + Status: responseStatus{ + Allowed: false, + // TODO: More detailed reason + Reason: "No grant gives permissions", + EvaluationError: "", + }, + }, nil +} + +func (t *testReviewer) AddPermissionForUser(username, verb, namespace, name string, resource schema.GroupVersionResource) { + if t.grants == nil { + t.grants = []grant{} + } + t.grants = append(t.grants, grant{ + username: username, + verb: verb, + name: name, + namespace: namespace, + resource: resource, + }) +} + +// Adapted version of NewV1TestServer from https://github.com/kubernetes/apiserver/blob/06158e986473ead1397ab8dd7a17339430256999/plugin/pkg/authorizer/webhook/webhook_v1_test.go#L225 +func NewSARServer(reviewer *testReviewer, rootPath string) (*httptest.Server, error) { + serveHTTP := func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, fmt.Sprintf("unexpected method %s", r.Method), http.StatusMethodNotAllowed) + return + } + // if this request isn't for something at root path, return a not found error + if !strings.HasPrefix(r.URL.Path, rootPath) { + http.Error(w, fmt.Sprintf("unexpected path %s", r.URL.Path), http.StatusNotFound) + return + } + var review authv1.SubjectAccessReview + bodyData, _ := io.ReadAll(r.Body) + if err := json.Unmarshal(bodyData, &review); err != nil { + http.Error(w, fmt.Sprintf("failed to decode body %s", err), http.StatusBadRequest) + return + } + + if review.APIVersion != "authorization.k8s.io/v1" { + http.Error(w, fmt.Sprintf("wrong api version %s", string(bodyData)), http.StatusBadRequest) + return + } + resp, err := reviewer.Review(&review) + if err != nil { + http.Error(w, err.Message, err.StatusCode) + return + } + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(*resp) + } + server := httptest.NewUnstartedServer(http.HandlerFunc(serveHTTP)) + server.StartTLS() + + serverURL, _ := url.Parse(server.URL) + serverURL.Path = rootPath + server.URL = serverURL.String() + + return server, nil +} + +// Simple implementation of the authv1.AuthorizationV1Interface which can just return a stored client +type Authv1ClientInterface struct { + Client rest.Interface +} + +func (c *Authv1ClientInterface) RESTClient() rest.Interface { + return c.Client +} + +func (c *Authv1ClientInterface) LocalSubjectAccessReviews(namespace string) typedv1.LocalSubjectAccessReviewInterface { + return nil +} + +func (c *Authv1ClientInterface) SelfSubjectAccessReviews() typedv1.SelfSubjectAccessReviewInterface { + return nil +} + +func (c *Authv1ClientInterface) SelfSubjectRulesReviews() typedv1.SelfSubjectRulesReviewInterface { + return nil +} + +func (c *Authv1ClientInterface) SubjectAccessReviews() typedv1.SubjectAccessReviewInterface { + return nil +} + +// RestClientForURL constructs a k8s rest client which has been configured to communicate with the server at serverURL +// using token as a source of auth +func RestClientForURL(serverURL string, token string) (rest.Interface, error) { + config := v1.Config{ + Clusters: []v1.NamedCluster{ + { + // skip tls here because our server implementation ignores this + Cluster: v1.Cluster{Server: serverURL, InsecureSkipTLSVerify: true}, + }, + }, + AuthInfos: []v1.NamedAuthInfo{ + { + AuthInfo: v1.AuthInfo{Token: token}, + }, + }, + } + tempfile, err := os.CreateTemp("", "") + if err != nil { + return nil, err + } + defer os.Remove(tempfile.Name()) + if err := json.NewEncoder(tempfile).Encode(config); err != nil { + return nil, err + } + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + loadingRules.ExplicitPath = tempfile.Name() + loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) + restConfig, err := loader.ClientConfig() + if err != nil { + return nil, err + } + restConfig.GroupVersion = &v1.SchemeGroupVersion + restConfig.ContentConfig.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + return rest.UnversionedRESTClientFor(restConfig) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/settings/settings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/settings/settings.go new file mode 100644 index 0000000..f4aea0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/settings/settings.go @@ -0,0 +1,20 @@ +package settings + +import ( + "github.com/rancher/apiserver/pkg/types" + schema2 "github.com/rancher/steve/pkg/schema" + steve "github.com/rancher/steve/pkg/server" +) + +func Register(server *steve.Server) { + server.SchemaFactory.AddTemplate(schema2.Template{ + Group: "management.cattle.io", + Kind: "Setting", + Formatter: func(request *types.APIRequest, resource *types.RawResource) { + data := resource.APIObject.Data() + if data.String("value") == "" { + data.Set("value", data.String("default")) + } + }, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/setup.go new file mode 100644 index 0000000..edbaa5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/setup.go @@ -0,0 +1,30 @@ +package steve + +import ( + "context" + + "github.com/rancher/rancher/pkg/api/steve/catalog" + "github.com/rancher/rancher/pkg/api/steve/clusters" + "github.com/rancher/rancher/pkg/api/steve/disallow" + "github.com/rancher/rancher/pkg/api/steve/machine" + "github.com/rancher/rancher/pkg/api/steve/navlinks" + "github.com/rancher/rancher/pkg/api/steve/settings" + "github.com/rancher/rancher/pkg/api/steve/userpreferences" + "github.com/rancher/rancher/pkg/wrangler" + steve "github.com/rancher/steve/pkg/server" +) + +func Setup(ctx context.Context, server *steve.Server, config *wrangler.Context) error { + userpreferences.Register(server.BaseSchemas, server.ClientFactory) + if err := clusters.Register(ctx, server, config); err != nil { + return err + } + machine.Register(server, config) + navlinks.Register(ctx, server) + settings.Register(server) + disallow.Register(server) + return catalog.Register(ctx, + server, + config.HelmOperations, + config.CatalogContentManager) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator.go new file mode 100644 index 0000000..b3acfe6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator.go @@ -0,0 +1,268 @@ +// Package supportconfigs provides a HTTPHandler to serve supportconfigs. This handler should be registered at Endpoint +package supportconfigs + +import ( + "archive/tar" + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + + "github.com/rancher/rancher/pkg/auth/util" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/managedcharts/cspadapter" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/release" + authzv1 "k8s.io/api/authorization/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/endpoints/request" + authv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" +) + +const ( + // Endpoint The endpoint that this URL is accessible at - used for routing and for SARs + Endpoint = "/v1/generateSUSERancherSupportConfig" + // NOTE: the name of the configmap will be the same for both Bring-Your-Own (BOY) and + // Pay-As-You-Go (PAYG) offerings. However, they will be in different namespaces to avoid + // clashing. + cspAdapterConfigmap = "csp-config" + // Metering archive for CSP marketplace Pay-As-You-Go (PAYG + // offerings. Used for auditing purposes. + cspMeteringArchiveConfigmap = "metering-archive" + tarContentType = "application/x-tar" + logPrefix = "support-config-generator" +) + +var errNotFound = errors.New("not implemented") + +type cspAdapterInterface interface { + GetRelease(chartNamespace string, chartName string) (*release.Release, error) +} + +// Handler implements http.Handler - and serves supportconfigs (tar file which contains support relevant information) +type Handler struct { + ConfigMaps v1.ConfigMapInterface + SubjectAccessReviews authv1.SubjectAccessReviewInterface + adapterUtil cspAdapterInterface +} + +// NewHandler creates a handler using the clients defined in scaledContext +func NewHandler(scaledContext *config.ScaledContext) Handler { + return Handler{ + ConfigMaps: scaledContext.Core.ConfigMaps(metav1.NamespaceAll), + SubjectAccessReviews: scaledContext.K8sClient.AuthorizationV1().SubjectAccessReviews(), + adapterUtil: cspadapter.NewChartUtil(scaledContext.Wrangler.RESTClientGetter), + } +} + +// Check to see if user have access to the configmaps needed to create +// the supportconfig tarball. Return false if user is not authorize or error +// in checking authorization, true otherwise. +func (h *Handler) checkAuthorization(cspNamespace string, cspConfigmap string, writer http.ResponseWriter, request *http.Request) bool { + authorized, err := h.authorize(cspNamespace, cspConfigmap, request) + if err != nil { + util.ReturnHTTPError(writer, request, http.StatusForbidden, http.StatusText(http.StatusForbidden)) + logrus.Errorf("[%s] Failed to authorize user with error: %s", logPrefix, err.Error()) + return false + } + if !authorized { + util.ReturnHTTPError(writer, request, http.StatusForbidden, http.StatusText(http.StatusForbidden)) + return false + } + + return true +} + +// ServerHTTP implements http.Handler - attempts to authenticate/authorize the user. Returns a tar of support information +// if the user can get the backing configmap in the adapter namespace +func (h *Handler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { + var cspChartNamespace string + var cspChartName string + + if usePAYG := request.URL.Query()["usePAYG"]; len(usePAYG) > 0 && usePAYG[0] == "true" { + // if usePAYG query parameter exist that means we are using the new Pay-As-You-Go offering CSP billing adapter + cspChartNamespace = cspadapter.PAYGChartNamespace + cspChartName = cspadapter.PAYGChartName + if !h.checkAuthorization(cspChartNamespace, cspMeteringArchiveConfigmap, writer, request) { + return + } + } else { + // if userPAYG query parameter does exist that means we are using the old Managed License offering CSP adapter + cspChartNamespace = cspadapter.MLOChartNamespace + cspChartName = cspadapter.MLOChartName + } + if !h.checkAuthorization(cspChartNamespace, cspAdapterConfigmap, writer, request) { + return + } + _, err := h.adapterUtil.GetRelease(cspChartNamespace, cspChartName) + if err != nil { + if errors.Is(err, cspadapter.ErrNotFound) { + // If neither adapter is installed, return a 501, so the + // user knows to install the adapter + util.ReturnHTTPError(writer, request, http.StatusNotImplemented, cspChartName+" must be installed to generate supportconfigs") + return + } + logrus.Errorf("[%s] Error when attempting to determine if adapter is installed, %s", logPrefix, err) + util.ReturnHTTPError(writer, request, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) + return + } + logrus.Infof("[%s] Generating supportconfig", logPrefix) + archive, err := h.generateSupportConfig(cspChartNamespace) + logrus.Infof("[%s] Done Generating supportconfig", logPrefix) + if err != nil { + if errors.Is(err, errNotFound) { + util.ReturnHTTPError(writer, request, http.StatusServiceUnavailable, "supportconfig not yet generated, try again later") + return + } + logrus.Errorf("[%s] Error when generating supportconfig %v", logPrefix, err) + util.ReturnHTTPError(writer, request, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) + return + } + writer.Header().Set("Content-Type", tarContentType) + writer.Header().Set("Content-Disposition", "attachment; filename=\"supportconfig_rancher.tar\"") + n, err := io.Copy(writer, archive) + if err != nil { + logrus.Warnf("set archive on http response writer: %v", err) + util.ReturnHTTPError(writer, request, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) + return + } + logrus.Debugf("[%s] wrote %v bytes in archive response", logPrefix, n) +} + +// authorize checks to see if the user can get the given csp adapter configmap. Returns a bool (if the user is authorized) +// and optionally an error +func (h *Handler) authorize(cspNamespace string, cspConfigmap string, r *http.Request) (bool, error) { + userInfo, ok := request.UserFrom(r.Context()) + if !ok { + return false, fmt.Errorf("unable to extract user info from context") + } + response, err := h.SubjectAccessReviews.Create(r.Context(), &authzv1.SubjectAccessReview{ + Spec: authzv1.SubjectAccessReviewSpec{ + ResourceAttributes: &authzv1.ResourceAttributes{ + Resource: "configmap", + Verb: "get", + Name: cspConfigmap, + Namespace: cspNamespace, + }, + User: userInfo.GetName(), + Groups: userInfo.GetGroups(), + Extra: convertExtra(userInfo.GetExtra()), + UID: userInfo.GetUID(), + }, + }, metav1.CreateOptions{}) + if err != nil { + return false, fmt.Errorf("failed to create a SubjectAccessReview: %w", err) + } + if !response.Status.Allowed { + return false, nil + } + return true, nil +} + +// getCSPConfig gets the configmap produced by the csp-adapter returns an error if not able to produce the map. Will return +// an errNotFound if the map is not found at all +func (h *Handler) getCSPConfig(cspNamespace string) (map[string]interface{}, error) { + cspConfigMap, err := h.ConfigMaps.GetNamespaced(cspNamespace, cspAdapterConfigmap, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, errNotFound + } + return nil, err + } + retVal := map[string]interface{}{} + err = json.Unmarshal([]byte(cspConfigMap.Data["data"]), &retVal) + if err != nil { + return nil, err + } + + return retVal, nil +} + +// getMeteringArchive gets th metering-archive configmap produced by CSP billing adapter returns an error if not able to produce the map. Will return +// an errNotFound if the map is not found at all +func (h *Handler) getMeteringArchive(cspNamespace string) ([]interface{}, error) { + cspMeteringArchive, err := h.ConfigMaps.GetNamespaced(cspNamespace, cspMeteringArchiveConfigmap, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, errNotFound + } + return nil, err + } + var retVal []interface{} + err = json.Unmarshal([]byte(cspMeteringArchive.Data["archive"]), &retVal) + if err != nil { + return nil, err + } + + return retVal, nil +} + +// generateSupportConfig produces an io.Reader with the supportconfig ready to be returned using a http.ResponseWriter +// Returns an err if it can't get the support config +func (h *Handler) generateSupportConfig(cspNamespace string) (io.Reader, error) { + cspConfig, err := h.getCSPConfig(cspNamespace) + // csp adapter won't always be installed + if err != nil { + return nil, err + } + configData, err := json.MarshalIndent(cspConfig, "", " ") + if err != nil { + return nil, err + } + + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + + files := map[string][]byte{ + "rancher/config.json": configData, + } + + if cspNamespace == cspadapter.PAYGChartNamespace { + // For PAYG we also need to include the metering archive + // for auditing purposes + cspMeteringArchive, err := h.getMeteringArchive(cspNamespace) + + // NOTE: metering archive may not have generated yet so don't include it + // if not found + if err == nil { + meteringArchiveData, err := json.MarshalIndent(cspMeteringArchive, "", " ") + if err != nil { + return nil, err + } + files["rancher/metering_archive.json"] = meteringArchiveData + } else { + if !errors.Is(err, errNotFound) { + return nil, err + } + } + } + + for name, body := range files { + hdr := &tar.Header{ + Name: name, + Mode: 0600, + Size: int64(len(body)), + } + if err := tw.WriteHeader(hdr); err != nil { + return nil, err + } + if _, err := tw.Write(body); err != nil { + return nil, err + } + } + + err = tw.Close() + return &buf, err +} + +func convertExtra(extra map[string][]string) map[string]authzv1.ExtraValue { + result := map[string]authzv1.ExtraValue{} + for k, v := range extra { + result[k] = authzv1.ExtraValue(v) + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator_test.go new file mode 100644 index 0000000..104b7a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/supportconfigs/generator_test.go @@ -0,0 +1,225 @@ +package supportconfigs + +import ( + "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" + + configmapfakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + "github.com/rancher/rancher/pkg/managedcharts/cspadapter" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/release" + authv1 "k8s.io/api/authorization/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes/fake" + k8stesting "k8s.io/client-go/testing" +) + +type FakeChartUtil struct { + generateError bool // return a random error + generateNotFound bool // return cspadapter.ErrNotFound +} + +func NewFakeChartUtil(generateError bool, generateNotFound bool) *FakeChartUtil { + return &FakeChartUtil{ + generateError: generateError, + generateNotFound: generateNotFound, + } +} + +func (c *FakeChartUtil) GetRelease(_ string, _ string) (*release.Release, error) { + if c.generateError { + return nil, fmt.Errorf("random error") + } + // indiscriminately generate a not found error + if c.generateNotFound { + return nil, cspadapter.ErrNotFound + } + // NOTE: we don't actually have to return a helm release as it will be + // ignored by the caller + return &release.Release{}, nil +} + +func TestGenerateSupportConfigScenarios(t *testing.T) { + scenarios := []struct { + name string + usePAYG bool + generateAdapterError bool + generateAdapterNotFound bool + generateAuthorizedError bool + generateMeteringArchiveNotFound bool + authorized bool + marshalledCSPConfig string + expectedHTTPCode int + }{ + { + name: "internal server error due to CSP release lookup", + usePAYG: true, + generateAdapterError: true, + generateAdapterNotFound: false, + generateAuthorizedError: false, + authorized: true, + expectedHTTPCode: http.StatusInternalServerError, + }, + { + name: "denied access due to error while performing authorization", + usePAYG: true, + generateAdapterError: false, + generateAdapterNotFound: false, + generateAuthorizedError: true, + authorized: false, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusForbidden, + }, + { + name: "user requests PAYG, authorized to get PAYG, PAYG not installed (501)", + usePAYG: true, + generateAdapterError: false, + generateAdapterNotFound: true, + generateAuthorizedError: false, + authorized: true, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusNotImplemented, + }, + { + name: "user requests PAYG, not authorized to get PAYG, auth denied (403)", + usePAYG: true, + generateAdapterError: false, + generateAdapterNotFound: true, + generateAuthorizedError: false, + authorized: false, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusForbidden, + }, + { + name: "user requests BYOL, authorized to get BYOL, BYOL not installed (501)", + usePAYG: false, + generateAdapterError: false, + generateAdapterNotFound: true, + generateAuthorizedError: false, + authorized: true, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusNotImplemented, + }, + { + name: "user requests BYOL, not authorized to get BYOL, auth denied (403)", + usePAYG: false, + generateAdapterError: false, + generateAdapterNotFound: false, + generateAuthorizedError: false, + authorized: false, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusForbidden, + }, + { + name: "user requests BYOL, authorized to get BYOL, we return output (200)", + usePAYG: false, + generateAdapterError: false, + generateAdapterNotFound: false, + generateAuthorizedError: false, + authorized: true, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusOK, + }, + { + name: "user requests PAYG, autorized to get PAYG, we return output (200)", + usePAYG: true, + generateAdapterError: false, + generateAdapterNotFound: false, + generateAuthorizedError: false, + authorized: true, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusOK, + }, + { + name: "user requests PAYG, authorized to get PAYG, metering-archive is not available, we return output (200) ", + usePAYG: true, + generateAdapterError: false, + generateAdapterNotFound: false, + generateAuthorizedError: false, + generateMeteringArchiveNotFound: true, + authorized: true, + marshalledCSPConfig: "{}", + expectedHTTPCode: http.StatusOK, + }, + } + for _, scenario := range scenarios { + test := scenario + t.Run(test.name, func(t *testing.T) { + t.Parallel() + var k8sClient *fake.Clientset + objs := []runtime.Object{} + k8sClient = fake.NewSimpleClientset(objs...) + k8sClient.PrependReactor("create", "subjectaccessreviews", + func(action k8stesting.Action) (bool, runtime.Object, error) { + ret := action.(k8stesting.CreateAction).GetObject().(*authv1.SubjectAccessReview) + if test.generateAuthorizedError { + return false, nil, fmt.Errorf("random error") + } + ret.Status.Allowed = test.authorized + return true, ret, nil + }, + ) + h := &Handler{ + ConfigMaps: &configmapfakes.ConfigMapInterfaceMock{ + GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { + // NOTE: we are not testing the configmap itself. Just need to return a valid configmap. + if name == cspAdapterConfigmap { + return &v1.ConfigMap{ + Data: map[string]string{ + "data": "{}", + }, + }, nil + } else { + if test.generateMeteringArchiveNotFound { + return nil, errNotFound + } + return &v1.ConfigMap{ + Data: map[string]string{ + "archive": "[]", + }, + }, nil + } + }, + }, + SubjectAccessReviews: k8sClient.AuthorizationV1().SubjectAccessReviews(), + adapterUtil: NewFakeChartUtil(test.generateAdapterError, test.generateAdapterNotFound), + } + reqPath := "/v1/generateSUSERancherSupportConfig" + if test.usePAYG { + reqPath = reqPath + "?usePAYG=true" + } + req := httptest.NewRequest(http.MethodGet, reqPath, nil) + rr := httptest.NewRecorder() + ctx := req.Context() + ctx = request.WithUser( + ctx, + &user.DefaultInfo{ + Name: "foo", + UID: "18", + Groups: []string{"foogroup"}, + Extra: map[string][]string{"foo": {"bar"}}, + }, + ) + req = req.WithContext(ctx) + h.ServeHTTP(rr, req) + assert.Equal(t, test.expectedHTTPCode, rr.Code) + if test.expectedHTTPCode == http.StatusForbidden { + // if user denied access, config.json should not be returned + body, _ := io.ReadAll(rr.Body) + assert.False(t, strings.Contains(string(body), "rancher/config.json")) + } + if test.generateMeteringArchiveNotFound { + body, _ := io.ReadAll(rr.Body) + assert.False(t, strings.Contains(string(body), "rancher/metering_archive.json")) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/rancherpref.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/rancherpref.go new file mode 100644 index 0000000..c19679f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/rancherpref.go @@ -0,0 +1,176 @@ +package userpreferences + +import ( + "github.com/rancher/apiserver/pkg/store/empty" + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/steve/pkg/attributes" + "github.com/rancher/steve/pkg/stores/proxy" + "github.com/rancher/wrangler/v3/pkg/data/convert" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/dynamic" +) + +var ( + rancherSchema = "management.cattle.io.preference" +) + +type rancherPrefStore struct { + empty.Store + cg proxy.ClientGetter +} + +func (e *rancherPrefStore) getClient(apiOp *types.APIRequest) (dynamic.ResourceInterface, error) { + user, ok := getUser(apiOp) + if !ok { + return nil, validation.Unauthorized + } + u := user.GetName() + cmSchema := apiOp.Schemas.LookupSchema(rancherSchema) + if cmSchema == nil { + return nil, validation.NotFound + } + + return e.cg.AdminClient(apiOp, cmSchema, u, nil) +} + +func (e *rancherPrefStore) ByID(apiOp *types.APIRequest, schema *types.APISchema, id string) (types.APIObject, error) { + u, ok := getUser(apiOp) + if !ok { + return types.APIObject{}, validation.Unauthorized + } + client, err := e.getClient(apiOp) + if err != nil { + return types.APIObject{}, err + } + + pref := &UserPreference{ + Data: map[string]string{}, + } + result := types.APIObject{ + Type: "userpreference", + ID: u.GetName(), + Object: pref, + } + + objs, err := client.List(apiOp.Context(), metav1.ListOptions{}) + if err != nil { + return result, err + } + + for _, obj := range objs.Items { + pref.Data[obj.GetName()] = convert.ToString(obj.Object["value"]) + } + + return result, nil +} + +func (e *rancherPrefStore) List(apiOp *types.APIRequest, schema *types.APISchema) (types.APIObjectList, error) { + obj, err := e.ByID(apiOp, schema, "") + if err != nil { + return types.APIObjectList{}, err + } + return types.APIObjectList{ + Objects: []types.APIObject{ + obj, + }, + }, nil +} + +func (e *rancherPrefStore) createNamespace(apiOp *types.APIRequest, ns string) error { + client, err := e.cg.AdminClient(apiOp, apiOp.Schemas.LookupSchema("namespace"), "", nil) + if err != nil { + return err + } + _, err = client.Get(apiOp.Context(), ns, metav1.GetOptions{}) + if !apierrors.IsNotFound(err) { + return err + } + _, err = client.Create(apiOp.Context(), &unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "name": ns, + }, + }, + }, metav1.CreateOptions{}) + return err +} + +func (e *rancherPrefStore) Update(apiOp *types.APIRequest, schema *types.APISchema, data types.APIObject, id string) (types.APIObject, error) { + client, err := e.getClient(apiOp) + if err != nil { + return types.APIObject{}, err + } + + user, ok := getUser(apiOp) + if !ok { + return types.APIObject{}, validation.Unauthorized + } + + gvk := attributes.GVK(apiOp.Schemas.LookupSchema(rancherSchema)) + + newValues := map[string]string{} + for k, v := range data.Data().Map("data") { + newValues[k] = convert.ToString(v) + } + + prefs, err := client.List(apiOp.Context(), metav1.ListOptions{}) + if err != nil { + return types.APIObject{}, err + } + + for _, pref := range prefs.Items { + key := pref.GetName() + newValue, ok := newValues[key] + delete(newValues, key) + if ok && newValue != pref.Object["value"] { + pref.Object["value"] = newValue + _, err := client.Update(apiOp.Context(), &pref, metav1.UpdateOptions{}) + if err != nil { + return types.APIObject{}, err + } + } else if !ok { + err := client.Delete(apiOp.Context(), key, metav1.DeleteOptions{}) + if err != nil { + return types.APIObject{}, err + } + } + } + + nsExists := false + for k, v := range newValues { + if !nsExists { + if err := e.createNamespace(apiOp, user.GetName()); err != nil { + return types.APIObject{}, err + } + nsExists = true + } + + _, err = client.Create(apiOp.Context(), &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": gvk.GroupVersion().String(), + "kind": gvk.Kind, + "metadata": map[string]interface{}{ + "name": k, + }, + "value": v, + }, + }, metav1.CreateOptions{}) + if err != nil { + return types.APIObject{}, err + } + } + + return e.ByID(apiOp, schema, "") +} + +func (e *rancherPrefStore) Delete(apiOp *types.APIRequest, schema *types.APISchema, id string) (types.APIObject, error) { + client, err := e.getClient(apiOp) + if err != nil { + return types.APIObject{}, err + } + + return types.APIObject{}, client.DeleteCollection(apiOp.Context(), metav1.DeleteOptions{}, metav1.ListOptions{}) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/userpreferences.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/userpreferences.go new file mode 100644 index 0000000..96c4c35 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/api/steve/userpreferences/userpreferences.go @@ -0,0 +1,29 @@ +package userpreferences + +import ( + "net/http" + + "github.com/rancher/apiserver/pkg/types" + "github.com/rancher/steve/pkg/stores/proxy" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type UserPreference struct { + Data map[string]string `json:"data"` +} + +func Register(schemas *types.APISchemas, cg proxy.ClientGetter) { + schemas.InternalSchemas.TypeName("userpreference", UserPreference{}) + schemas.MustImportAndCustomize(UserPreference{}, func(schema *types.APISchema) { + schema.CollectionMethods = []string{http.MethodGet} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut, http.MethodDelete} + schema.Store = &rancherPrefStore{ + cg: cg, + } + }) +} + +func getUser(apiOp *types.APIRequest) (user.Info, bool) { + return request.UserFrom(apiOp.Context()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/doc.go new file mode 100644 index 0000000..7fd6c37 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=catalog.cattle.io +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/helm.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/helm.go new file mode 100644 index 0000000..6d509e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/helm.go @@ -0,0 +1,155 @@ +package v1 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type App struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ReleaseSpec `json:"spec,omitempty"` + Status ReleaseStatus `json:"status,omitempty"` +} + +type ReleaseStatus struct { + Summary Summary `json:"summary,omitempty"` + ObservedGeneration int64 `json:"observedGeneration"` +} + +type Summary struct { + State string `json:"state,omitempty"` + Transitioning bool `json:"transitioning,omitempty"` + Error bool `json:"error,omitempty"` +} + +type ReleaseSpec struct { + // Name is the name of the release + Name string `json:"name,omitempty"` + // Info provides information about a release + Info *Info `json:"info,omitempty"` + // Chart is the chart that was released. + Chart *Chart `json:"chart,omitempty"` + // Config is the set of extra Values added to the chart. + // These values override the default values inside of the chart. + Values v3.MapStringInterface `json:"values,omitempty"` + // Manifest is the string representation of the rendered template. + Resources []ReleaseResource `json:"resources,omitempty"` + // Version is an int which represents the version of the release. + Version int `json:"version,omitempty"` + // Namespace is the kubernetes namespace of the release. + Namespace string `json:"namespace,omitempty"` + + HelmMajorVersion int `json:"helmVersion,omitempty"` +} + +type ReleaseResource struct { + APIVersion string `json:"apiVersion,omitempty"` + Kind string `json:"kind,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` +} + +// Chart is a helm package that contains metadata, a default config, zero or more +// optionally parameterizable templates, and zero or more charts (dependencies). +type Chart struct { + // Metadata is the contents of the Chartfile. + Metadata *Metadata `json:"metadata,omitempty"` + // Values are default config for this chart. + Values v3.MapStringInterface `json:"values,omitempty"` +} + +// Metadata for a Chart file. This models the structure of a Chart.yaml file. +type Metadata struct { + // The name of the chart + Name string `json:"name,omitempty"` + // The URL to a relevant project page, git repo, or contact person + Home string `json:"home,omitempty"` + // Source is the URL to the source code of this chart + Sources []string `json:"sources,omitempty"` + // A SemVer 2 conformant version string of the chart + Version string `json:"version,omitempty"` + // A one-sentence description of the chart + Description string `json:"description,omitempty"` + // A list of string keywords + Keywords []string `json:"keywords,omitempty"` + // A list of name and URL/email address combinations for the maintainer(s) + Maintainers []Maintainer `json:"maintainers,omitempty"` + // The URL to an icon file. + Icon string `json:"icon,omitempty"` + // The API Version of this chart. + APIVersion string `json:"apiVersion,omitempty"` + // The condition to check to enable chart + Condition string `json:"condition,omitempty"` + // The tags to check to enable chart + Tags string `json:"tags,omitempty"` + // The version of the application enclosed inside of this chart. + AppVersion string `json:"appVersion,omitempty"` + // Whether or not this chart is deprecated + Deprecated bool `json:"deprecated,omitempty"` + // Annotations are additional mappings uninterpreted by Helm, + // made available for inspection by other applications. + Annotations map[string]string `json:"annotations,omitempty"` + // KubeVersion is a SemVer constraint specifying the version of Kubernetes required. + KubeVersion string `json:"kubeVersion,omitempty"` + // Specifies the chart type: application or library + Type string `json:"type,omitempty"` +} + +// Maintainer describes a Chart maintainer. +type Maintainer struct { + // Name is a user name or organization name + Name string `json:"name,omitempty"` + // Email is an optional email address to contact the named maintainer + Email string `json:"email,omitempty"` + // URL is an optional URL to an address for the named maintainer + URL string `json:"url,omitempty"` +} + +// Info describes release information. +type Info struct { + // FirstDeployed is when the release was first deployed. + FirstDeployed *metav1.Time `json:"firstDeployed,omitempty"` + // LastDeployed is when the release was last deployed. + LastDeployed *metav1.Time `json:"lastDeployed,omitempty"` + // Deleted tracks when this object was deleted. + Deleted *metav1.Time `json:"deleted,omitempty"` + // Description is human-friendly "log entry" about this release. + Description string `json:"description,omitempty"` + // Status is the current state of the release + Status Status `json:"status,omitempty" wrangler:"options=unknown|deployed|uninstalled|superseded|failed|uninstalling|pending-install|pending-upgrade|pending-rollback"` + // Contains the rendered templates/NOTES.txt if available + Notes string `json:"notes,omitempty"` + Readme string `json:"readme,omitempty"` +} + +type Status string + +// Describe the status of a release +// NOTE: Make sure to update cmd/helm/status.go when adding or modifying any of these statuses. +const ( + // StatusUnknown indicates that a release is in an uncertain state. + StatusUnknown Status = "unknown" + // StatusDeployed indicates that the release has been pushed to Kubernetes. + StatusDeployed Status = "deployed" + // StatusUninstalled indicates that a release has been uninstalled from Kubernetes. + StatusUninstalled Status = "uninstalled" + // StatusSuperseded indicates that this release object is outdated and a newer one exists. + StatusSuperseded Status = "superseded" + // StatusFailed indicates that the release was not successfully deployed. + StatusFailed Status = "failed" + // StatusUninstalling indicates that a uninstall operation is underway. + StatusUninstalling Status = "uninstalling" + // StatusPendingInstall indicates that an install operation is underway. + StatusPendingInstall Status = "pending-install" + // StatusPendingUpgrade indicates that an upgrade operation is underway. + StatusPendingUpgrade Status = "pending-upgrade" + // StatusPendingRollback indicates that an rollback operation is underway. + StatusPendingRollback Status = "pending-rollback" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/plugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/plugin.go new file mode 100644 index 0000000..9f7dc35 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/plugin.go @@ -0,0 +1,53 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:resource:scope=Namespaced +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Plugin Name",type=string,JSONPath=`.spec.plugin.name` +// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.plugin.version` +// +kubebuilder:printcolumn:name="State",type=string,JSONPath=`.status.cacheState` +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type UIPlugin struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + // Spec is the desired state of the ui plugin. + Spec UIPluginSpec `json:"spec"` + // Status is the observed state of the ui plugin. + // +kubebuilder:validation:Optional + Status UIPluginStatus `json:"status"` +} + +type UIPluginSpec struct { + Plugin UIPluginEntry `json:"plugin,omitempty"` +} + +// UIPluginEntry represents an ui plugin. +type UIPluginEntry struct { + // Name of the plugin. + Name string `json:"name,omitempty"` + // Version of the plugin. + Version string `json:"version,omitempty"` + // Endpoint from where to fetch the contents of the plugin. + Endpoint string `json:"endpoint,omitempty"` + // NoCache a flag that tells if the plugin should be cached or not. + // Defaults to false. + // +kubebuilder:default:=false + NoCache bool `json:"noCache,omitempty"` + // NoAuth a flag that tells if the plugin should be accessible without authentication. + // Defaults to false. + // +kubebuilder:default:=false + NoAuth bool `json:"noAuth,omitempty"` + // Metadata of the plugin. + Metadata map[string]string `json:"metadata,omitempty"` +} + +type UIPluginStatus struct { + // CacheState is the cache status of the plugin. + // +nullable + CacheState string `json:"cacheState,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/types.go new file mode 100644 index 0000000..b777eb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/types.go @@ -0,0 +1,151 @@ +package v1 + +import ( + "github.com/rancher/wrangler/v3/pkg/genericcondition" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ClusterRepoNameLabel = "catalog.cattle.io/cluster-repo-name" + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterRepo struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec RepoSpec `json:"spec"` + Status RepoStatus `json:"status"` +} + +// SecretReference a reference to a secret object +type SecretReference struct { + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` +} + +// ExponentialBackOffValues are values in seconds for the ratelimiting func when OCI registry sends 429 http response code. +type ExponentialBackOffValues struct { + MinWait int `json:"minWait,omitempty"` + MaxWait int `json:"maxWait,omitempty"` + MaxRetries int `json:"maxRetries,omitempty"` +} + +type RepoSpec struct { + // URL can be a HTTP URL i.e https://charts.rancher.io or an OCI URL i.e oci://dp.apps.rancher.io/charts/etcd. + URL string `json:"url,omitempty"` + + // InsecurePlainHTTP is only valid for OCI URL's and allows insecure connections to registries without enforcing TLS checks. + InsecurePlainHTTP bool `json:"insecurePlainHttp,omitempty"` + + // GitRepo a git repo to clone and index as the helm repo + GitRepo string `json:"gitRepo,omitempty"` + + // GitBranch The git branch to follow + GitBranch string `json:"gitBranch,omitempty"` + + // ExponentialBackOffValues are values given to the Rancher manager to handle + // 429 TOOMANYREQUESTS response code from the OCI registry. + ExponentialBackOffValues *ExponentialBackOffValues `json:"exponentialBackOffValues,omitempty"` + + // CABundle is a PEM encoded CA bundle which will be used to validate the repo's certificate. + // If unspecified, system trust roots will be used. + CABundle []byte `json:"caBundle,omitempty"` + + // InsecureSkipTLSverify will use insecure HTTPS to download the repo's index. + InsecureSkipTLSverify bool `json:"insecureSkipTLSVerify,omitempty"` + + // ClientSecretName is the client secret to be used to connect to the repo + // It is expected the secret be of type "kubernetes.io/basic-auth" or "kubernetes.io/tls" for Helm repos + // and "kubernetes.io/basic-auth" or "kubernetes.io/ssh-auth" for git repos. + // For a repo the Namespace file will be ignored + ClientSecret *SecretReference `json:"clientSecret,omitempty"` + + // BasicAuthSecretName is the client secret to be used to connect to the repo + BasicAuthSecretName string `json:"basicAuthSecretName,omitempty"` + + // ForceUpdate will cause the repo index to be downloaded if it was last download before the specified time + // If ForceUpdate is greater than time.Now() it will not trigger an update + ForceUpdate *metav1.Time `json:"forceUpdate,omitempty"` + + // ServiceAccount this service account will be used to deploy charts instead of the end users credentials + ServiceAccount string `json:"serviceAccount,omitempty"` + + // ServiceAccountNamespace namespace of the service account to use. This value is used only on + // ClusterRepo and will be ignored on Repo + ServiceAccountNamespace string `json:"serviceAccountNamespace,omitempty"` + + // If disabled the repo clone will not be updated or allowed to be installed from + Enabled *bool `json:"enabled,omitempty"` + + // DisableSameOriginCheck attaches the Basic Auth Header to all helm client API calls, regardless of whether the destination of the API call matches the origin of the repository's URL + // This field is not supported for OCI based URLs + DisableSameOriginCheck bool `json:"disableSameOriginCheck,omitempty"` +} + +type RepoCondition string + +const ( + RepoDownloaded RepoCondition = "Downloaded" + FollowerRepoDownloaded RepoCondition = "FollowerDownloaded" + OCIDownloaded RepoCondition = "OCIDownloaded" +) + +type RepoStatus struct { + ObservedGeneration int64 `json:"observedGeneration"` + + // IndexConfigMapName is the configmap with the store index in it + IndexConfigMapName string `json:"indexConfigMapName,omitempty"` + IndexConfigMapNamespace string `json:"indexConfigMapNamespace,omitempty"` + IndexConfigMapResourceVersion string `json:"indexConfigMapResourceVersion,omitempty"` + + // DownloadTime the time when the index was last downloaded + DownloadTime metav1.Time `json:"downloadTime,omitempty"` + + // The URL used for the last successful index + URL string `json:"url,omitempty"` + + // The branch used for the last successful index + Branch string `json:"branch,omitempty"` + + // The git commit used to generate the index + Commit string `json:"commit,omitempty"` + + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` + + // Number of times the handler will retry if it gets a 429 error + NumberOfRetries int `json:"numberOfRetries,omitempty"` + + // The time the next retry will happen + NextRetryAt metav1.Time `json:"nextRetryAt,omitempty"` + + // If the handler should be skipped or not + ShouldNotSkip bool `json:"shouldNotSkip,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Operation struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Status OperationStatus `json:"status"` +} + +type OperationStatus struct { + ObservedGeneration int64 `json:"observedGeneration"` + Action string `json:"action,omitempty"` + Chart string `json:"chart,omitempty"` + Version string `json:"version,omitempty"` + Release string `json:"releaseName,omitempty"` + Namespace string `json:"namespace,omitempty"` + ProjectID string `json:"projectId,omitempty"` + Token string `json:"token,omitempty"` + Command []string `json:"command,omitempty"` + PodName string `json:"podName,omitempty"` + PodNamespace string `json:"podNamespace,omitempty"` + PodCreated bool `json:"podCreated,omitempty"` + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_deepcopy.go new file mode 100644 index 0000000..1ff7b28 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_deepcopy.go @@ -0,0 +1,632 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + genericcondition "github.com/rancher/wrangler/v3/pkg/genericcondition" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *App) DeepCopyInto(out *App) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new App. +func (in *App) DeepCopy() *App { + if in == nil { + return nil + } + out := new(App) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *App) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppList) DeepCopyInto(out *AppList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]App, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppList. +func (in *AppList) DeepCopy() *AppList { + if in == nil { + return nil + } + out := new(AppList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Chart) DeepCopyInto(out *Chart) { + *out = *in + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = new(Metadata) + (*in).DeepCopyInto(*out) + } + in.Values.DeepCopyInto(&out.Values) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Chart. +func (in *Chart) DeepCopy() *Chart { + if in == nil { + return nil + } + out := new(Chart) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRepo) DeepCopyInto(out *ClusterRepo) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRepo. +func (in *ClusterRepo) DeepCopy() *ClusterRepo { + if in == nil { + return nil + } + out := new(ClusterRepo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRepo) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRepoList) DeepCopyInto(out *ClusterRepoList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterRepo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRepoList. +func (in *ClusterRepoList) DeepCopy() *ClusterRepoList { + if in == nil { + return nil + } + out := new(ClusterRepoList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRepoList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExponentialBackOffValues) DeepCopyInto(out *ExponentialBackOffValues) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExponentialBackOffValues. +func (in *ExponentialBackOffValues) DeepCopy() *ExponentialBackOffValues { + if in == nil { + return nil + } + out := new(ExponentialBackOffValues) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Info) DeepCopyInto(out *Info) { + *out = *in + if in.FirstDeployed != nil { + in, out := &in.FirstDeployed, &out.FirstDeployed + *out = (*in).DeepCopy() + } + if in.LastDeployed != nil { + in, out := &in.LastDeployed, &out.LastDeployed + *out = (*in).DeepCopy() + } + if in.Deleted != nil { + in, out := &in.Deleted, &out.Deleted + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Info. +func (in *Info) DeepCopy() *Info { + if in == nil { + return nil + } + out := new(Info) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Maintainer) DeepCopyInto(out *Maintainer) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Maintainer. +func (in *Maintainer) DeepCopy() *Maintainer { + if in == nil { + return nil + } + out := new(Maintainer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Metadata) DeepCopyInto(out *Metadata) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Keywords != nil { + in, out := &in.Keywords, &out.Keywords + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Maintainers != nil { + in, out := &in.Maintainers, &out.Maintainers + *out = make([]Maintainer, len(*in)) + copy(*out, *in) + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Metadata. +func (in *Metadata) DeepCopy() *Metadata { + if in == nil { + return nil + } + out := new(Metadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Operation) DeepCopyInto(out *Operation) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Operation. +func (in *Operation) DeepCopy() *Operation { + if in == nil { + return nil + } + out := new(Operation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Operation) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperationList) DeepCopyInto(out *OperationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Operation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperationList. +func (in *OperationList) DeepCopy() *OperationList { + if in == nil { + return nil + } + out := new(OperationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OperationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperationStatus) DeepCopyInto(out *OperationStatus) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperationStatus. +func (in *OperationStatus) DeepCopy() *OperationStatus { + if in == nil { + return nil + } + out := new(OperationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReleaseResource) DeepCopyInto(out *ReleaseResource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseResource. +func (in *ReleaseResource) DeepCopy() *ReleaseResource { + if in == nil { + return nil + } + out := new(ReleaseResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReleaseSpec) DeepCopyInto(out *ReleaseSpec) { + *out = *in + if in.Info != nil { + in, out := &in.Info, &out.Info + *out = new(Info) + (*in).DeepCopyInto(*out) + } + if in.Chart != nil { + in, out := &in.Chart, &out.Chart + *out = new(Chart) + (*in).DeepCopyInto(*out) + } + in.Values.DeepCopyInto(&out.Values) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]ReleaseResource, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseSpec. +func (in *ReleaseSpec) DeepCopy() *ReleaseSpec { + if in == nil { + return nil + } + out := new(ReleaseSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReleaseStatus) DeepCopyInto(out *ReleaseStatus) { + *out = *in + out.Summary = in.Summary + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseStatus. +func (in *ReleaseStatus) DeepCopy() *ReleaseStatus { + if in == nil { + return nil + } + out := new(ReleaseStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RepoSpec) DeepCopyInto(out *RepoSpec) { + *out = *in + if in.ExponentialBackOffValues != nil { + in, out := &in.ExponentialBackOffValues, &out.ExponentialBackOffValues + *out = new(ExponentialBackOffValues) + **out = **in + } + if in.CABundle != nil { + in, out := &in.CABundle, &out.CABundle + *out = make([]byte, len(*in)) + copy(*out, *in) + } + if in.ClientSecret != nil { + in, out := &in.ClientSecret, &out.ClientSecret + *out = new(SecretReference) + **out = **in + } + if in.ForceUpdate != nil { + in, out := &in.ForceUpdate, &out.ForceUpdate + *out = (*in).DeepCopy() + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoSpec. +func (in *RepoSpec) DeepCopy() *RepoSpec { + if in == nil { + return nil + } + out := new(RepoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RepoStatus) DeepCopyInto(out *RepoStatus) { + *out = *in + in.DownloadTime.DeepCopyInto(&out.DownloadTime) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + in.NextRetryAt.DeepCopyInto(&out.NextRetryAt) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RepoStatus. +func (in *RepoStatus) DeepCopy() *RepoStatus { + if in == nil { + return nil + } + out := new(RepoStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretReference) DeepCopyInto(out *SecretReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference. +func (in *SecretReference) DeepCopy() *SecretReference { + if in == nil { + return nil + } + out := new(SecretReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Summary) DeepCopyInto(out *Summary) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Summary. +func (in *Summary) DeepCopy() *Summary { + if in == nil { + return nil + } + out := new(Summary) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UIPlugin) DeepCopyInto(out *UIPlugin) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UIPlugin. +func (in *UIPlugin) DeepCopy() *UIPlugin { + if in == nil { + return nil + } + out := new(UIPlugin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *UIPlugin) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UIPluginEntry) DeepCopyInto(out *UIPluginEntry) { + *out = *in + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UIPluginEntry. +func (in *UIPluginEntry) DeepCopy() *UIPluginEntry { + if in == nil { + return nil + } + out := new(UIPluginEntry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UIPluginList) DeepCopyInto(out *UIPluginList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]UIPlugin, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UIPluginList. +func (in *UIPluginList) DeepCopy() *UIPluginList { + if in == nil { + return nil + } + out := new(UIPluginList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *UIPluginList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UIPluginSpec) DeepCopyInto(out *UIPluginSpec) { + *out = *in + in.Plugin.DeepCopyInto(&out.Plugin) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UIPluginSpec. +func (in *UIPluginSpec) DeepCopy() *UIPluginSpec { + if in == nil { + return nil + } + out := new(UIPluginSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UIPluginStatus) DeepCopyInto(out *UIPluginStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UIPluginStatus. +func (in *UIPluginStatus) DeepCopy() *UIPluginStatus { + if in == nil { + return nil + } + out := new(UIPluginStatus) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_list_types.go new file mode 100644 index 0000000..8a26a8b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_list_types.go @@ -0,0 +1,93 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=catalog.cattle.io +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AppList is a list of App resources +type AppList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []App `json:"items"` +} + +func NewApp(namespace, name string, obj App) *App { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("App").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterRepoList is a list of ClusterRepo resources +type ClusterRepoList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterRepo `json:"items"` +} + +func NewClusterRepo(namespace, name string, obj ClusterRepo) *ClusterRepo { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterRepo").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OperationList is a list of Operation resources +type OperationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Operation `json:"items"` +} + +func NewOperation(namespace, name string, obj Operation) *Operation { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Operation").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// UIPluginList is a list of UIPlugin resources +type UIPluginList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []UIPlugin `json:"items"` +} + +func NewUIPlugin(namespace, name string, obj UIPlugin) *UIPlugin { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("UIPlugin").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_register.go new file mode 100644 index 0000000..c6ce982 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/v1/zz_generated_register.go @@ -0,0 +1,69 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=catalog.cattle.io +package v1 + +import ( + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + AppResourceName = "apps" + ClusterRepoResourceName = "clusterrepos" + OperationResourceName = "operations" + UIPluginResourceName = "uiplugins" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: catalog.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &App{}, + &AppList{}, + &ClusterRepo{}, + &ClusterRepoList{}, + &Operation{}, + &OperationList{}, + &UIPlugin{}, + &UIPluginList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..aeac9b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/catalog.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package catalog + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "catalog.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/doc.go new file mode 100644 index 0000000..31a8f9d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=cluster.cattle.io +package v3 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/types.go new file mode 100644 index 0000000..69e4494 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/types.go @@ -0,0 +1,39 @@ +package v3 + +import ( + "github.com/rancher/norman/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterUserAttribute struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Groups []string `json:"groups,omitempty"` + LastRefresh string `json:"lastRefresh,omitempty"` + NeedsRefresh bool `json:"needsRefresh"` + Enabled bool `json:"enabled"` + ExtraByProvider map[string]map[string][]string `json:"extraByProvider,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterAuthToken struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + UserName string `json:"userName"` + ExpiresAt string `json:"expiresAt,omitempty"` + SecretKeyHash string `json:"hash"` + Enabled bool `json:"enabled"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_deepcopy.go new file mode 100644 index 0000000..b519bdc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_deepcopy.go @@ -0,0 +1,176 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterAuthToken) DeepCopyInto(out *ClusterAuthToken) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterAuthToken. +func (in *ClusterAuthToken) DeepCopy() *ClusterAuthToken { + if in == nil { + return nil + } + out := new(ClusterAuthToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterAuthToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterAuthTokenList) DeepCopyInto(out *ClusterAuthTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterAuthToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterAuthTokenList. +func (in *ClusterAuthTokenList) DeepCopy() *ClusterAuthTokenList { + if in == nil { + return nil + } + out := new(ClusterAuthTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterAuthTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterUserAttribute) DeepCopyInto(out *ClusterUserAttribute) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Groups != nil { + in, out := &in.Groups, &out.Groups + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ExtraByProvider != nil { + in, out := &in.ExtraByProvider, &out.ExtraByProvider + *out = make(map[string]map[string][]string, len(*in)) + for key, val := range *in { + var outVal map[string][]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + (*out)[key] = outVal + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterUserAttribute. +func (in *ClusterUserAttribute) DeepCopy() *ClusterUserAttribute { + if in == nil { + return nil + } + out := new(ClusterUserAttribute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterUserAttribute) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterUserAttributeList) DeepCopyInto(out *ClusterUserAttributeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterUserAttribute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterUserAttributeList. +func (in *ClusterUserAttributeList) DeepCopy() *ClusterUserAttributeList { + if in == nil { + return nil + } + out := new(ClusterUserAttributeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterUserAttributeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_list_types.go new file mode 100644 index 0000000..17b96ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_list_types.go @@ -0,0 +1,59 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=cluster.cattle.io +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterAuthTokenList is a list of ClusterAuthToken resources +type ClusterAuthTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterAuthToken `json:"items"` +} + +func NewClusterAuthToken(namespace, name string, obj ClusterAuthToken) *ClusterAuthToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterAuthToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterUserAttributeList is a list of ClusterUserAttribute resources +type ClusterUserAttributeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterUserAttribute `json:"items"` +} + +func NewClusterUserAttribute(namespace, name string, obj ClusterUserAttribute) *ClusterUserAttribute { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterUserAttribute").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_register.go new file mode 100644 index 0000000..5934bba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/v3/zz_generated_register.go @@ -0,0 +1,63 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=cluster.cattle.io +package v3 + +import ( + cluster "github.com/rancher/rancher/pkg/apis/cluster.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + ClusterAuthTokenResourceName = "clusterauthtokens" + ClusterUserAttributeResourceName = "clusteruserattributes" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: cluster.GroupName, Version: "v3"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ClusterAuthToken{}, + &ClusterAuthTokenList{}, + &ClusterUserAttribute{}, + &ClusterUserAttributeList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..5275f36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/cluster.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package cluster + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "cluster.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.mod b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.mod new file mode 100644 index 0000000..7cc061f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.mod @@ -0,0 +1,99 @@ +module github.com/rancher/rancher/pkg/apis + +go 1.22.0 + +toolchain go1.22.3 + +replace ( + k8s.io/api => k8s.io/api v0.30.1 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.30.1 + k8s.io/apimachinery => k8s.io/apimachinery v0.30.1 + k8s.io/apiserver => k8s.io/apiserver v0.30.1 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.30.1 + k8s.io/client-go => k8s.io/client-go v0.30.1 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.30.1 + k8s.io/component-base => k8s.io/component-base v0.30.1 + k8s.io/controller-manager => k8s.io/controller-manager v0.30.1 + k8s.io/cri-api => k8s.io/cri-api v0.30.1 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.30.1 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.30.1 + k8s.io/endpointslice => k8s.io/endpointslice v0.30.1 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.30.1 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.30.1 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.30.1 + k8s.io/kubectl => k8s.io/kubectl v0.30.1 + k8s.io/kubelet => k8s.io/kubelet v0.30.1 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.30.1 + k8s.io/mount-utils => k8s.io/mount-utils v0.30.1 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.30.1 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.30.1 +) + +require ( + github.com/rancher/aks-operator v1.9.1 + github.com/rancher/eks-operator v1.9.1 + github.com/rancher/fleet/pkg/apis v0.10.0 + github.com/rancher/gke-operator v1.9.1 + github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 + github.com/rancher/rke v1.6.1 + github.com/rancher/wrangler/v3 v3.0.0 + github.com/sirupsen/logrus v1.9.3 + k8s.io/api v0.30.2 + k8s.io/apimachinery v0.30.2 + sigs.k8s.io/cluster-api v1.7.3 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/term v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.30.1 // indirect + k8s.io/apiserver v0.30.1 // indirect + k8s.io/client-go v12.0.0+incompatible // indirect + k8s.io/component-base v0.30.1 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/kubernetes v1.30.1 // indirect + k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect + sigs.k8s.io/cli-utils v0.35.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.sum b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.sum new file mode 100644 index 0000000..abc9251 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/go.sum @@ -0,0 +1,205 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= +github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rancher/aks-operator v1.9.1 h1:ARxafxU3c51V91BeCB1w94n3yjrKjjzQrqd/tWrd1go= +github.com/rancher/aks-operator v1.9.1/go.mod h1:RbGSV11kCpSjmSiX+WDiExBRQxnF/oRUdlmeAg9PqNA= +github.com/rancher/eks-operator v1.9.1 h1:o0K2jcEdlrERRuIyC/CVZkRW++EcCa6GbVidBEfFh0w= +github.com/rancher/eks-operator v1.9.1/go.mod h1:vMQSu6MQqLkuilXcv+KKlL15sFBg24TZQUifVgoDmIc= +github.com/rancher/fleet/pkg/apis v0.10.0 h1:0f8OEghEDJNzvUAR2fpg2dw8EnAgfWvkhnwsYFS9G+w= +github.com/rancher/fleet/pkg/apis v0.10.0/go.mod h1:mjirthAmgpz0xo+qywUiaJDFpjnmX3xrc2E0/qmk3yc= +github.com/rancher/gke-operator v1.9.1 h1:COsXcgo10QEXMzju9zuGFBA+muvHfIiaTXpRz9dwQ2I= +github.com/rancher/gke-operator v1.9.1/go.mod h1:D/U7p7NpQtZcdHFWM+uBOmtk9/tVdlZv7BgR+TIiMAI= +github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 h1:vv1jDlYbd4KhGbPNxmjs8CYgEHUrQm2bMtmULfXJ6iw= +github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1/go.mod h1:A/y3BLQkxZXYD60MNDRwAG9WGxXfvd6Z6gWR/a8wPw8= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 h1:AlRMRs5mHJcdiK83KKJyFVeybPMZ7dOUzC0l3k9aUa8= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9/go.mod h1:dyjfXBsNiroPWOdUZe7diUOUSLf6HQ/r2kEpwH/8zas= +github.com/rancher/rke v1.6.1 h1:ipktVDW1Xcs2SIR4vB9vCxH09kVrfD+1RmcUtWIPUV8= +github.com/rancher/rke v1.6.1/go.mod h1:5xRbf3L8PxqJRhABjYRfaBqbpVqAnqyH3maUNQEuwvk= +github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA= +github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= +k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/apiserver v0.30.1 h1:BEWEe8bzS12nMtDKXzCF5Q5ovp6LjjYkSp8qOPk8LZ8= +k8s.io/apiserver v0.30.1/go.mod h1:i87ZnQ+/PGAmSbD/iEKM68bm1D5reX8fO4Ito4B01mo= +k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= +k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= +k8s.io/component-base v0.30.1 h1:bvAtlPh1UrdaZL20D9+sWxsJljMi0QZ3Lmw+kmZAaxQ= +k8s.io/component-base v0.30.1/go.mod h1:e/X9kDiOebwlI41AvBHuWdqFriSRrX50CdwA9TFaHLI= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/kubernetes v1.30.1 h1:XlqS6KslLEA5mQzLK2AJrhr4Z1m8oJfkhHiWJ5lue+I= +k8s.io/kubernetes v1.30.1/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0= +k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= +k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/cli-utils v0.35.0 h1:dfSJaF1W0frW74PtjwiyoB4cwdRygbHnC7qe7HF0g/Y= +sigs.k8s.io/cli-utils v0.35.0/go.mod h1:ITitykCJxP1vaj1Cew/FZEaVJ2YsTN9Q71m02jebkoE= +sigs.k8s.io/cluster-api v1.7.3 h1:DsSRxsA+18jxLqPAo29abZ9kOPK1/xwhSuQb/MROzSs= +sigs.k8s.io/cluster-api v1.7.3/go.mod h1:V9ZhKLvQtsDODwjXOKgbitjyCmC71yMBwDcMyNNIov0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/api_server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/api_server.go new file mode 100644 index 0000000..b64f8d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/api_server.go @@ -0,0 +1,34 @@ +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type APIService struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec APIServiceSpec `json:"spec"` + Status APIServiceStatus `json:"status,omitempty"` +} + +type APIServiceSpec struct { + PathPrefixes []string `json:"pathPrefixes,omitempty"` + Paths []string `json:"paths,omitempty"` + + // SecretName refers to a secret that will be created that can be read by a local aggregation client + SecretName string `json:"secretName,omitempty"` + SecretNamespace string `json:"secretNamespace,omitempty"` +} + +type APIServiceStatus struct { + ServiceAccountName string `json:"serviceAccountName,omitempty"` + ServiceAccountNamespace string `json:"serviceAccountNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/auth_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/auth_list_types.go new file mode 100644 index 0000000..36869fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/auth_list_types.go @@ -0,0 +1,103 @@ +/* +Copyright 2020 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +groupName=management.cattle.io +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ActiveDirectoryConfigList is a list of ActiveDirectoryConfig resources +type ActiveDirectoryConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ActiveDirectoryConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GithubConfigList is a list of GithubConfig resources +type GithubConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GithubConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GoogleOauthConfigList is a list of GoogleOauthConfig resources +type GoogleOauthConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GoogleOauthConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LdapConfigList is a list of LdapConfig resources +type LdapConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []LdapConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalConfigList is a list of LocalConfig resources +type LocalConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []LocalConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SamlConfigList is a list of SamlConfig resources +type SamlConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []SamlConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OIDCConfigList is a list of OIDCConfig resources +type OIDCConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []OIDCConfig `json:"items"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KeyCloakOIDCConfigList is a list of KeyCloakOIDCConfig resources +type KeyCloakOIDCConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []KeyCloakOIDCConfig `json:"items"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types.go new file mode 100644 index 0000000..5cec9d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types.go @@ -0,0 +1,589 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + UserConditionInitialRolesPopulated condition.Cond = "InitialRolesPopulated" + AuthConfigConditionSecretsMigrated condition.Cond = "SecretsMigrated" + // AuthConfigConditionShibbolethSecretFixed is applied to an AuthConfig when the + // incorrect name for the shibboleth OpenLDAP secret has been fixed. + AuthConfigConditionShibbolethSecretFixed condition.Cond = "ShibbolethSecretFixed" + + // AuthConfigOKTAPasswordMigrated is applied when an Okta password has been + // moved to a Secret. + AuthConfigOKTAPasswordMigrated condition.Cond = "OktaPasswordMigrated" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Token struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Token string `json:"token" norman:"writeOnly,noupdate"` + UserPrincipal Principal `json:"userPrincipal" norman:"type=reference[principal]"` + GroupPrincipals []Principal `json:"groupPrincipals,omitempty" norman:"type=array[reference[principal]]"` + ProviderInfo map[string]string `json:"providerInfo,omitempty"` + UserID string `json:"userId" norman:"type=reference[user]"` + AuthProvider string `json:"authProvider"` + TTLMillis int64 `json:"ttl"` + LastUpdateTime string `json:"lastUpdateTime"` + IsDerived bool `json:"isDerived"` + Description string `json:"description"` + Expired bool `json:"expired"` + ExpiresAt string `json:"expiresAt"` + Current bool `json:"current"` + ClusterName string `json:"clusterName,omitempty" norman:"noupdate,type=reference[cluster]"` + Enabled *bool `json:"enabled,omitempty" norman:"default=true"` +} + +func (t *Token) ObjClusterName() string { + return t.ClusterName +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type User struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + DisplayName string `json:"displayName,omitempty"` + Description string `json:"description"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty" norman:"writeOnly,noupdate"` + MustChangePassword bool `json:"mustChangePassword,omitempty"` + PrincipalIDs []string `json:"principalIds,omitempty" norman:"type=array[reference[principal]]"` + Me bool `json:"me,omitempty" norman:"nocreate,noupdate"` + Enabled *bool `json:"enabled,omitempty" norman:"default=true"` + Spec UserSpec `json:"spec,omitempty"` + Status UserStatus `json:"status"` +} + +// IsSystem returns true if the user is a system user. +func (u *User) IsSystem() bool { + for _, principalID := range u.PrincipalIDs { + if strings.HasPrefix(principalID, "system:") { + return true + } + } + + return false +} + +// IsDefaultAdmin returns true if the user is the default admin user. +func (u *User) IsDefaultAdmin() bool { + return u.Username == "admin" +} + +type UserStatus struct { + Conditions []UserCondition `json:"conditions"` +} + +type UserCondition struct { + // Type of user condition. + Type string `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +type UserSpec struct{} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// UserAttribute will have a CRD (and controller) generated for it, but will not be exposed in the API. +type UserAttribute struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + UserName string + GroupPrincipals map[string]Principals // the value is a []Principal, but code generator cannot handle slice as a value + LastRefresh string + NeedsRefresh bool + ExtraByProvider map[string]map[string][]string // extra information for the user to print in audit logs, stored per authProvider. example: map[openldap:map[principalid:[openldap_user://uid=testuser1,ou=dev,dc=us-west-2,dc=compute,dc=internal]]] + LastLogin *metav1.Time `json:"lastLogin,omitempty"` + DisableAfter *metav1.Duration `json:"disableAfter,omitempty"` // Overrides DisableInactiveUserAfter setting. + DeleteAfter *metav1.Duration `json:"deleteAfter,omitempty"` // Overrides DeleteInactiveUserAfter setting. +} + +type Principals struct { + Items []Principal +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Group struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + DisplayName string `json:"displayName,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GroupMember struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + GroupName string `json:"groupName,omitempty" norman:"type=reference[group]"` + PrincipalID string `json:"principalId,omitempty" norman:"type=reference[principal]"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Principal struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + DisplayName string `json:"displayName,omitempty"` + LoginName string `json:"loginName,omitempty"` + ProfilePicture string `json:"profilePicture,omitempty"` + ProfileURL string `json:"profileURL,omitempty"` + PrincipalType string `json:"principalType,omitempty"` + Me bool `json:"me,omitempty"` + MemberOf bool `json:"memberOf,omitempty"` + Provider string `json:"provider,omitempty"` + ExtraInfo map[string]string `json:"extraInfo,omitempty"` +} + +type SearchPrincipalsInput struct { + Name string `json:"name" norman:"type=string,required,notnullable"` + PrincipalType string `json:"principalType,omitempty" norman:"type=enum,options=user|group"` +} + +type ChangePasswordInput struct { + CurrentPassword string `json:"currentPassword" norman:"type=string,required"` + NewPassword string `json:"newPassword" norman:"type=string,required"` +} + +type SetPasswordInput struct { + NewPassword string `json:"newPassword" norman:"type=string,required"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AuthConfig struct { + metav1.TypeMeta `json:",inline" mapstructure:",squash"` + metav1.ObjectMeta `json:"metadata,omitempty" mapstructure:"metadata"` + + Type string `json:"type" norman:"noupdate"` + Enabled bool `json:"enabled,omitempty"` + AccessMode string `json:"accessMode,omitempty" norman:"required,notnullable,type=enum,options=required|restricted|unrestricted"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" norman:"type=array[reference[principal]]"` + Status AuthConfigStatus `json:"status"` +} + +type AuthConfigStatus struct { + Conditions []AuthConfigConditions `json:"conditions"` +} + +type AuthConfigConditions struct { + // Type of condition + Type condition.Cond `json:"type"` + + // Status of condition (one of True, False, Unknown) + Status v1.ConditionStatus `json:"status"` + + // Last time the condition was updated + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + + // Last time the condition transitioned from one status to another + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + + // The reason for the condition's last transition + Reason string `json:"reason,omitempty"` + + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type SamlToken struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Token string `json:"token" norman:"writeOnly,noupdate"` + ExpiresAt string `json:"expiresAt"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type LocalConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GithubConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + Hostname string `json:"hostname,omitempty" norman:"default=github.com" norman:"required"` + TLS bool `json:"tls,omitempty" norman:"notnullable,default=true" norman:"required"` + ClientID string `json:"clientId,omitempty" norman:"required"` + ClientSecret string `json:"clientSecret,omitempty" norman:"required,type=password"` + + // AdditionalClientIDs is a map of clientID to client secrets + AdditionalClientIDs map[string]string `json:"additionalClientIds,omitempty" norman:"nocreate,noupdate"` + HostnameToClientID map[string]string `json:"hostnameToClientId,omitempty" norman:"nocreate,noupdate"` +} + +type GithubConfigTestOutput struct { + RedirectURL string `json:"redirectUrl"` +} + +type GithubConfigApplyInput struct { + GithubConfig GithubConfig `json:"githubConfig,omitempty"` + Code string `json:"code,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GoogleOauthConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + OauthCredential string `json:"oauthCredential,omitempty" norman:"required,type=password,notnullable"` + ServiceAccountCredential string `json:"serviceAccountCredential,omitempty" norman:"required,type=password,notnullable"` + AdminEmail string `json:"adminEmail,omitempty" norman:"required,notnullable"` + Hostname string `json:"hostname,omitempty" norman:"required,notnullable,noupdate"` + UserInfoEndpoint string `json:"userInfoEndpoint" norman:"default=https://openidconnect.googleapis.com/v1/userinfo,required,notnullable"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled" norman:"default=false"` +} + +type GoogleOauthConfigTestOutput struct { + RedirectURL string `json:"redirectUrl"` +} + +type GoogleOauthConfigApplyInput struct { + GoogleOauthConfig GoogleOauthConfig `json:"googleOauthConfig,omitempty"` + Code string `json:"code,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AzureADConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + Endpoint string `json:"endpoint,omitempty" norman:"default=https://login.microsoftonline.com/,required,notnullable"` + GraphEndpoint string `json:"graphEndpoint,omitempty" norman:"required,notnullable"` + TokenEndpoint string `json:"tokenEndpoint,omitempty" norman:"required,notnullable"` + AuthEndpoint string `json:"authEndpoint,omitempty" norman:"required,notnullable"` + DeviceAuthEndpoint string `json:"deviceAuthEndpoint,omitempty"` + TenantID string `json:"tenantId,omitempty" norman:"required,notnullable"` + ApplicationID string `json:"applicationId,omitempty" norman:"required,notnullable"` + ApplicationSecret string `json:"applicationSecret,omitempty" norman:"required,type=password"` + RancherURL string `json:"rancherUrl,omitempty" norman:"required,notnullable"` + GroupMembershipFilter string `json:"groupMembershipFilter,omitempty"` +} + +type AzureADConfigTestOutput struct { + RedirectURL string `json:"redirectUrl"` +} + +type AzureADConfigApplyInput struct { + Config AzureADConfig `json:"config,omitempty"` + Code string `json:"code,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ActiveDirectoryConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + Servers []string `json:"servers,omitempty" norman:"type=array[string],required"` + Port int64 `json:"port,omitempty" norman:"default=389"` + TLS bool `json:"tls,omitempty" norman:"default=false"` + StartTLS bool `json:"starttls,omitempty" norman:"default=false"` + Certificate string `json:"certificate,omitempty"` + DefaultLoginDomain string `json:"defaultLoginDomain,omitempty"` + ServiceAccountUsername string `json:"serviceAccountUsername,omitempty" norman:"required"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" norman:"type=password,required"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" norman:"default=2"` + UserSearchBase string `json:"userSearchBase,omitempty" norman:"required"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" norman:"default=sAMAccountName|sn|givenName,required"` + UserSearchFilter string `json:"userSearchFilter,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" norman:"default=sAMAccountName,required"` + UserObjectClass string `json:"userObjectClass,omitempty" norman:"default=person,required"` + UserNameAttribute string `json:"userNameAttribute,omitempty" norman:"default=name,required"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" norman:"default=userAccountControl,required"` + GroupSearchBase string `json:"groupSearchBase,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" norman:"default=sAMAccountName,required"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" norman:"default=group,required"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" norman:"default=name,required"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" norman:"default=distinguishedName,required"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" norman:"default=distinguishedName,required"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" norman:"default=member,required"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" norman:"default=5000,notnullable,required"` + NestedGroupMembershipEnabled *bool `json:"nestedGroupMembershipEnabled,omitempty" norman:"default=false"` +} + +func (c *ActiveDirectoryConfig) GetUserSearchAttributes(searchAttributes ...string) []string { + userSearchAttributes := []string{ + c.UserObjectClass, + c.UserLoginAttribute, + c.UserNameAttribute, + c.UserEnabledAttribute, + } + return append(userSearchAttributes, searchAttributes...) +} + +func (c *ActiveDirectoryConfig) GetGroupSearchAttributes(searchAttributes ...string) []string { + groupSeachAttributes := []string{ + c.GroupObjectClass, + c.UserLoginAttribute, + c.GroupNameAttribute, + c.GroupSearchAttribute, + } + return append(groupSeachAttributes, searchAttributes...) +} + +type ActiveDirectoryTestAndApplyInput struct { + ActiveDirectoryConfig ActiveDirectoryConfig `json:"activeDirectoryConfig,omitempty"` + Username string `json:"username"` + Password string `json:"password"` + Enabled bool `json:"enabled,omitempty"` +} + +type LdapFields struct { + Servers []string `json:"servers,omitempty" norman:"type=array[string],notnullable,required"` + Port int64 `json:"port,omitempty" norman:"default=389,notnullable,required"` + TLS bool `json:"tls,omitempty" norman:"default=false,notnullable,required"` + StartTLS bool `json:"starttls,omitempty" norman:"default=false"` + Certificate string `json:"certificate,omitempty"` + ServiceAccountDistinguishedName string `json:"serviceAccountDistinguishedName,omitempty" norman:"required"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" norman:"type=password,required"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" norman:"notnullable,required"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" norman:"default=uid|sn|givenName,notnullable,required"` + UserSearchFilter string `json:"userSearchFilter,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" norman:"default=uid,notnullable,required"` + UserObjectClass string `json:"userObjectClass,omitempty" norman:"default=inetOrgPerson,notnullable,required"` + UserNameAttribute string `json:"userNameAttribute,omitempty" norman:"default=cn,notnullable,required"` + UserMemberAttribute string `json:"userMemberAttribute,omitempty" norman:"default=memberOf,notnullable,required"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" norman:"default=cn,notnullable,required"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" norman:"default=groupOfNames,notnullable,required"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" norman:"default=cn,notnullable,required"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" norman:"default=entryDN,notnullable"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" norman:"default=entryDN,notnullable"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" norman:"default=member,notnullable,required"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" norman:"default=5000,notnullable,required"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled" norman:"default=false"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type LdapConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + LdapFields `json:",inline" mapstructure:",squash"` +} + +func (c *LdapConfig) GetUserSearchAttributes(searchAttributes ...string) []string { + userSearchAttributes := []string{ + "dn", + c.UserMemberAttribute, + c.UserObjectClass, + c.UserLoginAttribute, + c.UserNameAttribute, + c.UserEnabledAttribute, + } + return append(userSearchAttributes, searchAttributes...) +} + +func (c *LdapConfig) GetGroupSearchAttributes(searchAttributes ...string) []string { + groupSeachAttributes := []string{ + c.GroupMemberUserAttribute, + c.GroupObjectClass, + c.UserLoginAttribute, + c.GroupNameAttribute, + c.GroupSearchAttribute, + } + return append(groupSeachAttributes, searchAttributes...) +} + +type LdapTestAndApplyInput struct { + LdapConfig `json:"ldapConfig,omitempty"` + Username string `json:"username"` + Password string `json:"password" norman:"type=password,required"` +} + +type OpenLdapConfig struct { + LdapConfig `json:",inline" mapstructure:",squash"` +} + +type OpenLdapTestAndApplyInput struct { + LdapTestAndApplyInput `json:",inline" mapstructure:",squash"` +} + +type FreeIpaConfig struct { + LdapConfig `json:",inline" mapstructure:",squash"` +} + +type FreeIpaTestAndApplyInput struct { + LdapTestAndApplyInput `json:",inline" mapstructure:",squash"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type SamlConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + IDPMetadataContent string `json:"idpMetadataContent" norman:"required"` + SpCert string `json:"spCert" norman:"required"` + SpKey string `json:"spKey" norman:"required,type=password"` + GroupsField string `json:"groupsField" norman:"required"` + DisplayNameField string `json:"displayNameField" norman:"required"` + UserNameField string `json:"userNameField" norman:"required"` + UIDField string `json:"uidField" norman:"required"` + RancherAPIHost string `json:"rancherApiHost" norman:"required"` + EntityID string `json:"entityID"` +} + +type SamlConfigTestInput struct { + FinalRedirectURL string `json:"finalRedirectUrl"` +} + +type SamlConfigTestOutput struct { + IdpRedirectURL string `json:"idpRedirectUrl"` +} + +type PingConfig struct { + SamlConfig `json:",inline" mapstructure:",squash"` +} + +type ADFSConfig struct { + SamlConfig `json:",inline" mapstructure:",squash"` +} + +type KeyCloakConfig struct { + SamlConfig `json:",inline" mapstructure:",squash"` +} + +type OKTAConfig struct { + SamlConfig `json:",inline" mapstructure:",squash"` + OpenLdapConfig LdapFields `json:"openLdapConfig"` +} + +type ShibbolethConfig struct { + SamlConfig `json:",inline" mapstructure:",squash"` + OpenLdapConfig LdapFields `json:"openLdapConfig"` +} + +type AuthSystemImages struct { + KubeAPIAuth string `json:"kubeAPIAuth,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type OIDCConfig struct { + AuthConfig `json:",inline" mapstructure:",squash"` + + ClientID string `json:"clientId" norman:"required"` + ClientSecret string `json:"clientSecret,omitempty" norman:"required,type=password"` + RancherURL string `json:"rancherUrl" norman:"required,notnullable"` + Issuer string `json:"issuer" norman:"required,notnullable"` + AuthEndpoint string `json:"authEndpoint,omitempty"` + TokenEndpoint string `json:"tokenEndpoint,omitempty"` + UserInfoEndpoint string `json:"userInfoEndpoint,omitempty"` + JWKSUrl string `json:"jwksUrl,omitempty"` + Certificate string `json:"certificate,omitempty"` + PrivateKey string `json:"privateKey,omitempty" norman:"type=password"` + GroupSearchEnabled *bool `json:"groupSearchEnabled"` + GroupsClaim string `json:"groupsClaim,omitempty"` + // Scopes is expected to be a space delimited list of scopes + Scopes string `json:"scope,omitempty"` + // AcrValue is expected to be string containing the required ACR value + AcrValue string `json:"acrValue,omitempty"` +} + +type OIDCTestOutput struct { + RedirectURL string `json:"redirectUrl"` +} + +type OIDCApplyInput struct { + OIDCConfig OIDCConfig `json:"oidcConfig,omitempty"` + Code string `json:"code,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +type KeyCloakOIDCConfig struct { + OIDCConfig `json:",inline" mapstructure:",squash"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterProxyConfig determines which downstream requests will be proxied to the downstream cluster for requests that contain service account tokens. +// Objects of this type are created in the namespace of the target cluster. If no object exists, the feature will be disabled by default. +type ClusterProxyConfig struct { + types.Namespaced `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Enabled indicates whether downstream proxy requests for service account tokens is enabled. + Enabled bool `json:"enabled"` +} + +// GenericOIDCConfig is the wrapper for the Generic OIDC provider to hold the OIDC Configuration +type GenericOIDCConfig struct { + OIDCConfig `json:",inline" mapstructure:",squash"` +} + +// GenericOIDCTestOutput is the wrapper for the Generic OIDC provider to hold the OIDC test output object, which +// in turn holds the RedirectURL +type GenericOIDCTestOutput struct { + OIDCTestOutput `json:",inline" mapstructure:",squash"` +} + +// GenericOIDCApplyInput is the wrapper for the input used to enable/activate the Generic OIDC auth provider. It holds +// the configuration for the OIDC provider as well as an auth code. +type GenericOIDCApplyInput struct { + OIDCApplyInput `json:",inline" mapstructure:",squash"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types_test.go new file mode 100644 index 0000000..97d87c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authn_types_test.go @@ -0,0 +1,69 @@ +package v3 + +import ( + "testing" +) + +func TestUserIsSystem(t *testing.T) { + tests := []struct { + user *User + isSystem bool + }{ + { + user: &User{ + PrincipalIDs: []string{"system://local", "local://u-b4qkhsnliz"}, + }, + isSystem: true, + }, + { + user: &User{ + PrincipalIDs: []string{"system://provisioning/fleet-local/local", "local://u-mo773yttt4"}, + }, + isSystem: true, + }, + { + user: &User{ + PrincipalIDs: []string{"local://u-cx7gc"}, + }, + }, + { + user: &User{ + PrincipalIDs: []string{"activedirectory_user://CN=foo,CN=Users,DC=bar,DC=rancher,DC=space", "local://u-ckrl4grxg5"}, + }, + }, + { + user: &User{}, + }, + } + + for _, tt := range tests { + if want, got := tt.isSystem, tt.user.IsSystem(); want != got { + t.Errorf("Expected %t got %t", want, got) + } + } +} + +func TestUserIsAdmin(t *testing.T) { + tests := []struct { + user *User + isAdmin bool + }{ + { + user: &User{ + Username: "admin", + }, + isAdmin: true, + }, + { + user: &User{ + Username: "u-ckrl4grxg5", + }, + }, + } + + for _, tt := range tests { + if want, got := tt.isAdmin, tt.user.IsDefaultAdmin(); want != got { + t.Errorf("Expected %t got %t", want, got) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authz_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authz_types.go new file mode 100644 index 0000000..70438a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/authz_types.go @@ -0,0 +1,401 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + NamespaceBackedResource condition.Cond = "BackingNamespaceCreated" + CreatorMadeOwner condition.Cond = "CreatorMadeOwner" + DefaultNetworkPolicyCreated condition.Cond = "DefaultNetworkPolicyCreated" + ProjectConditionDefaultNamespacesAssigned condition.Cond = "DefaultNamespacesAssigned" + ProjectConditionInitialRolesPopulated condition.Cond = "InitialRolesPopulated" + ProjectConditionSystemNamespacesAssigned condition.Cond = "SystemNamespacesAssigned" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// Project is a group of namespaces. +// Projects are used to create a multi-tenant environment within a Kubernetes cluster by managing namespace operations, +// such as role assignments or quotas, as a group. +type Project struct { + types.Namespaced `json:",inline"` + metav1.TypeMeta `json:",inline"` + + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec is the specification of the desired configuration for the project. + // +optional + Spec ProjectSpec `json:"spec,omitempty"` + + // Status is the most recently observed status of the project. + // +optional + Status ProjectStatus `json:"status,omitempty"` +} + +func (p *Project) ObjClusterName() string { + return p.Spec.ObjClusterName() +} + +// ProjectStatus represents the most recently observed status of the project. +type ProjectStatus struct { + // Conditions are a set of indicators about aspects of the project. + // +optional + Conditions []ProjectCondition `json:"conditions,omitempty"` +} + +// ProjectCondition is the status of an aspect of the project. +type ProjectCondition struct { + // Type of project condition. + // +kubebuilder:validation:Required + Type string `json:"type"` + + // Status of the condition, one of True, False, Unknown. + // +kubebuilder:validation:Required + Status v1.ConditionStatus `json:"status"` + + // The last time this condition was updated. + // +optional + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + + // Last time the condition transitioned from one status to another. + // +optional + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + + // The reason for the condition's last transition. + // +optional + Reason string `json:"reason,omitempty"` + + // Human-readable message indicating details about last transition. + // +optional + Message string `json:"message,omitempty"` +} + +// ProjectSpec is a description of the project. +type ProjectSpec struct { + + // DisplayName is the human-readable name for the project. + // +kubebuilder:validation:Required + DisplayName string `json:"displayName" norman:"required"` + + // Description is a human-readable description of the project. + // +optional + Description string `json:"description,omitempty"` + + // ClusterName is the name of the cluster the project belongs to. Immutable. + // +kubebuilder:validation:Required + ClusterName string `json:"clusterName" norman:"required,type=reference[cluster]"` + + // ResourceQuota is a specification for the total amount of quota for standard resources that will be shared by all namespaces in the project. + // Must provide NamespaceDefaultResourceQuota if ResourceQuota is specified. + // See https://kubernetes.io/docs/concepts/policy/resource-quotas/ for more details. + // +optional + ResourceQuota *ProjectResourceQuota `json:"resourceQuota,omitempty"` + + // NamespaceDefaultResourceQuota is a specification of the default ResourceQuota that a namespace will receive if none is provided. + // Must provide ResourceQuota if NamespaceDefaultResourceQuota is specified. + // See https://kubernetes.io/docs/concepts/policy/resource-quotas/ for more details. + // +optional + NamespaceDefaultResourceQuota *NamespaceResourceQuota `json:"namespaceDefaultResourceQuota,omitempty"` + + // ContainerDefaultResourceLimit is a specification for the default LimitRange for the namespace. + // See https://kubernetes.io/docs/concepts/policy/limit-range/ for more details. + // +optional + ContainerDefaultResourceLimit *ContainerResourceLimit `json:"containerDefaultResourceLimit,omitempty"` +} + +func (p *ProjectSpec) ObjClusterName() string { + return p.ClusterName +} + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="STATUS",type="string",JSONPath=".status.summary" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalRole defines rules that can be applied to the local cluster and or every downstream cluster. +type GlobalRole struct { + metav1.TypeMeta `json:",inline"` + + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // DisplayName is the human-readable name displayed in the UI for this resource. + // +optional + DisplayName string `json:"displayName,omitempty" norman:"required"` + + // Description holds text that describes the resource. + // +optional + Description string `json:"description,omitempty"` + + // Rules holds a list of PolicyRules that are applied to the local cluster only. + // +optional + Rules []rbacv1.PolicyRule `json:"rules,omitempty"` + + // NewUserDefault specifies that all new users created should be bound to this GlobalRole if true. + // +optional + NewUserDefault bool `json:"newUserDefault,omitempty" norman:"required"` + + // Builtin specifies that this GlobalRole was created by Rancher if true. Immutable. + // +optional + Builtin bool `json:"builtin,omitempty" norman:"nocreate,noupdate"` + + // InheritedClusterRoles are the names of RoleTemplates whose permissions are granted by this GlobalRole in every + // cluster besides the local cluster. To grant permissions in the local cluster, use the Rules field. + // +optional + InheritedClusterRoles []string `json:"inheritedClusterRoles,omitempty"` + + // NamespacedRules are the rules that are active in each namespace of this GlobalRole. + // These are applied to the local cluster only. + // * has no special meaning in the keys - these keys are read as raw strings + // and must exactly match with one existing namespace. + // +optional + NamespacedRules map[string][]rbacv1.PolicyRule `json:"namespacedRules,omitempty"` + + // InheritedFleetWorkspacePermissions are the permissions granted by this GlobalRole in every fleet workspace besides + // the local one. + // +optional + InheritedFleetWorkspacePermissions *FleetWorkspacePermission `json:"inheritedFleetWorkspacePermissions,omitempty"` + + // Status is the most recently observed status of the GlobalRole. + // +optional + Status GlobalRoleStatus `json:"status,omitempty"` +} + +// FleetWorkspacePermission defines permissions that will apply to all fleet workspaces except local. +type FleetWorkspacePermission struct { + // ResourceRules rules granted in all backing namespaces for all fleet workspaces besides the local one. + ResourceRules []rbacv1.PolicyRule `json:"resourceRules,omitempty" yaml:"resourceRules,omitempty"` + // WorkspaceVerbs verbs used to grant permissions to the cluster-wide fleetworkspace resources. ResourceNames for + // this rule will contain all fleet workspace names except local. + WorkspaceVerbs []string `json:"workspaceVerbs,omitempty" yaml:"workspaceVerbs,omitempty"` +} + +// GlobalRoleStatus represents the most recently observed status of the GlobalRole. +type GlobalRoleStatus struct { + // ObservedGeneration is the most recent generation (metadata.generation in GlobalRole CR) + // observed by the controller. Populated by the system. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // LastUpdate is a k8s timestamp of the last time the status was updated. + // +optional + LastUpdate string `json:"lastUpdateTime,omitempty"` + + // Summary is a string. One of "Complete", "InProgress" or "Error". + // +optional + Summary string `json:"summary,omitempty"` + + // Conditions is a slice of Condition, indicating the status of specific backing RBAC objects. + // There is one condition per ClusterRole and Role managed by the GlobalRole. + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:resource:scope=Cluster +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalRoleBinding binds a given subject user or group to a GlobalRole. +type GlobalRoleBinding struct { + metav1.TypeMeta `json:",inline"` + + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // UserName is the name of the user subject to be bound. Immutable. + // +optional + UserName string `json:"userName,omitempty" norman:"noupdate,type=reference[user]"` + + // GroupPrincipalName is the name of the group principal subject to be bound. Immutable. + // +optional + GroupPrincipalName string `json:"groupPrincipalName,omitempty" norman:"noupdate,type=reference[principal]"` + + // GlobalRoleName is the name of the Global Role that the subject will be bound to. Immutable. + // +kubebuilder:validation:Required + GlobalRoleName string `json:"globalRoleName" norman:"required,noupdate,type=reference[globalRole]"` +} + +// +genclient +// +genclient:nonNamespaced +// +kubebuilder:resource:scope=Cluster +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RoleTemplate holds configuration for a template that is used to create kubernetes Roles and ClusterRoles +// (in the rbac.authorization.k8s.io group) for a cluster or project. +type RoleTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // DisplayName is the human-readable name displayed in the UI for this resource. + DisplayName string `json:"displayName,omitempty" norman:"required"` + + // Description holds text that describes the resource. + // +optional + Description string `json:"description"` + + // Rules hold all the PolicyRules for this RoleTemplate. + // +optional + Rules []rbacv1.PolicyRule `json:"rules,omitempty"` + + // Builtin if true specifies that this RoleTemplate was created by Rancher and is immutable. + // Default to false. + // +optional + Builtin bool `json:"builtin" norman:"nocreate,noupdate"` + + // External if true specifies that rules for this RoleTemplate should be gathered from a ClusterRole with the matching name. + // If set to true the Rules on the template will not be evaluated. + // External's value is only evaluated if the RoleTemplate's context is set to "cluster" + // Default to false. + // +optional + External bool `json:"external"` + + // ExternalRules hold the external PolicyRules that will be used for authorization. + // This field is required when External=true and no underlying ClusterRole exists in the local cluster. + // This field is just used when the feature flag 'external-rules' is on. + // +optional + ExternalRules []rbacv1.PolicyRule `json:"externalRules,omitempty"` + + // Hidden if true informs the Rancher UI not to display this RoleTemplate. + // Default to false. + // +optional + Hidden bool `json:"hidden"` + + // Locked if true, new bindings will not be able to use this RoleTemplate. + // Default to false. + // +optional + Locked bool `json:"locked,omitempty" norman:"type=boolean"` + + // ClusterCreatorDefault if true, a binding with this RoleTemplate will be created for a users when they create a new cluster. + // ClusterCreatorDefault is only evaluated if the context of the RoleTemplate is set to cluster. + // Default to false. + // +optional + ClusterCreatorDefault bool `json:"clusterCreatorDefault,omitempty" norman:"required"` + + // ProjectCreatorDefault if true, a binding with this RoleTemplate will be created for a user when they create a new project. + // ProjectCreatorDefault is only evaluated if the context of the RoleTemplate is set to project. + // Default to false. + // +optional + ProjectCreatorDefault bool `json:"projectCreatorDefault,omitempty" norman:"required"` + + // Context describes if the roleTemplate applies to clusters or projects. + // Valid values are "project", "cluster" or "". + // +kubebuilder:validation:Enum={"project","cluster",""} + Context string `json:"context,omitempty" norman:"type=string,options=project|cluster"` + + // RoleTemplateNames list of RoleTemplate names that this RoleTemplate will inherit. + // This RoleTemplate will grant all rules defined in an inherited RoleTemplate. + // Inherited RoleTemplates must already exist. + // +optional + RoleTemplateNames []string `json:"roleTemplateNames,omitempty" norman:"type=array[reference[roleTemplate]]"` + + // Administrative if false, and context is set to cluster this RoleTemplate will not grant access to "CatalogTemplates" and "CatalogTemplateVersions" for any project in the cluster. + // Default is false. + // +optional + Administrative bool `json:"administrative,omitempty"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectRoleTemplateBinding is the object representing membership of a subject in a project with permissions +// specified by a given role template. +type ProjectRoleTemplateBinding struct { + types.Namespaced `json:",inline"` + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // UserName is the name of the user subject added to the project. Immutable. + // +optional + UserName string `json:"userName,omitempty" norman:"noupdate,type=reference[user]"` + + // UserPrincipalName is the name of the user principal subject added to the project. Immutable. + // +optional + UserPrincipalName string `json:"userPrincipalName,omitempty" norman:"noupdate,type=reference[principal]"` + + // GroupName is the name of the group subject added to the project. Immutable. + // +optional + GroupName string `json:"groupName,omitempty" norman:"noupdate,type=reference[group]"` + + // GroupPrincipalName is the name of the group principal subject added to the project. Immutable. + // +optional + GroupPrincipalName string `json:"groupPrincipalName,omitempty" norman:"noupdate,type=reference[principal]"` + + // ProjectName is the name of the project to which a subject is added. Immutable. + // +kubebuilder:validation:Required + ProjectName string `json:"projectName" norman:"required,noupdate,type=reference[project]"` + + // RoleTemplateName is the name of the role template that defines permissions to perform actions on resources in the project. Immutable. + // +kubebuilder:validation:Required + RoleTemplateName string `json:"roleTemplateName" norman:"required,noupdate,type=reference[roleTemplate]"` + + // ServiceAccount is the name of the service account bound as a subject. Immutable. + // Deprecated. + // +optional + ServiceAccount string `json:"serviceAccount,omitempty" norman:"nocreate,noupdate"` +} + +func (p *ProjectRoleTemplateBinding) ObjClusterName() string { + if parts := strings.SplitN(p.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterRoleTemplateBinding is the object representing membership of a subject in a cluster with permissions +// specified by a given role template. +type ClusterRoleTemplateBinding struct { + types.Namespaced `json:",inline"` + metav1.TypeMeta `json:",inline"` + + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // UserName is the name of the user subject added to the cluster. Immutable. + // +optional + UserName string `json:"userName,omitempty" norman:"noupdate,type=reference[user]"` + + // UserPrincipalName is the name of the user principal subject added to the cluster. Immutable. + // +optional + UserPrincipalName string `json:"userPrincipalName,omitempty" norman:"noupdate,type=reference[principal]"` + + // GroupName is the name of the group subject added to the cluster. Immutable. + // +optional + GroupName string `json:"groupName,omitempty" norman:"noupdate,type=reference[group]"` + + // GroupPrincipalName is the name of the group principal subject added to the cluster. Immutable. + // +optional + GroupPrincipalName string `json:"groupPrincipalName,omitempty" norman:"noupdate,type=reference[principal]"` + + // ClusterName is the metadata.name of the cluster to which a subject is added. + // Must match the namespace. Immutable. + // +kubebuilder:validation:Required + ClusterName string `json:"clusterName" norman:"required,noupdate,type=reference[cluster]"` + + // RoleTemplateName is the name of the role template that defines permissions to perform actions on resources in the cluster. Immutable. + // +kubebuilder:validation:Required + RoleTemplateName string `json:"roleTemplateName" norman:"required,noupdate,type=reference[roleTemplate]"` +} + +func (c *ClusterRoleTemplateBinding) ObjClusterName() string { + return c.ClusterName +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/catalog_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/catalog_types.go new file mode 100644 index 0000000..3c42dc3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/catalog_types.go @@ -0,0 +1,312 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Catalog struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec CatalogSpec `json:"spec"` + Status CatalogStatus `json:"status"` +} + +type CatalogSpec struct { + Description string `json:"description"` + URL string `json:"url,omitempty" norman:"required"` + Branch string `json:"branch,omitempty"` + CatalogKind string `json:"catalogKind,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty" norman:"type=password"` + HelmVersion string `json:"helmVersion,omitempty" norman:"noupdate"` + CatalogSecrets CatalogSecrets `json:"catalogSecrets" norman:"nocreate,noupdate"` +} + +type CatalogStatus struct { + LastRefreshTimestamp string `json:"lastRefreshTimestamp,omitempty"` + Commit string `json:"commit,omitempty"` + Conditions []CatalogCondition `json:"conditions,omitempty"` + + // Deprecated: should no longer be in use. If a Catalog CR is encountered with this field + // populated, it will be set to nil. + HelmVersionCommits map[string]VersionCommits `json:"helmVersionCommits,omitempty"` + CredentialSecret string `json:"credentialSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use CatalogSpec.CatalogSecrets.CredentialSecret instead +} + +var ( + CatalogConditionRefreshed condition.Cond = "Refreshed" + CatalogConditionUpgraded condition.Cond = "Upgraded" + CatalogConditionDiskCached condition.Cond = "DiskCached" + CatalogConditionProcessed condition.Cond = "Processed" + CatalogConditionSecretsMigrated condition.Cond = "SecretsMigrated" +) + +type CatalogCondition struct { + // Type of cluster condition. + Type ClusterConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +// Deprecated: CatalogStatus.HelmVersionCommits has been deprecated, which is the only consumer of this type. +type VersionCommits struct { + Value map[string]string `json:"Value,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Template struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec TemplateSpec `json:"spec"` + Status TemplateStatus `json:"status"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CatalogTemplate struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec TemplateSpec `json:"spec"` + Status TemplateStatus `json:"status"` +} + +type TemplateSpec struct { + DisplayName string `json:"displayName"` + CatalogID string `json:"catalogId,omitempty" norman:"type=reference[catalog]"` + ProjectCatalogID string `json:"projectCatalogId,omitempty" norman:"type=reference[projectCatalog]"` + ClusterCatalogID string `json:"clusterCatalogId,omitempty" norman:"type=reference[clusterCatalog]"` + DefaultTemplateVersionID string `json:"defaultTemplateVersionId,omitempty" norman:"type=reference[templateVersion]"` + ProjectID string `json:"projectId,omitempty" norman:"required,type=reference[project]"` + ClusterID string `json:"clusterId,omitempty" norman:"required,type=reference[cluster]"` + + Description string `json:"description,omitempty"` + DefaultVersion string `json:"defaultVersion,omitempty" yaml:"default_version,omitempty"` + Path string `json:"path,omitempty"` + Maintainer string `json:"maintainer,omitempty"` + ProjectURL string `json:"projectURL,omitempty" yaml:"project_url,omitempty"` + UpgradeFrom string `json:"upgradeFrom,omitempty"` + FolderName string `json:"folderName,omitempty"` + Icon string `json:"icon,omitempty"` + IconFilename string `json:"iconFilename,omitempty"` + + // Deprecated: Do not use + Readme string `json:"readme,omitempty" norman:"nocreate,noupdate"` + + Categories []string `json:"categories,omitempty"` + Versions []TemplateVersionSpec `json:"versions,omitempty"` + + Category string `json:"category,omitempty"` +} + +type TemplateStatus struct { + HelmVersion string `json:"helmVersion,omitempty" norman:"noupdate,nocreate"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type TemplateVersion struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec TemplateVersionSpec `json:"spec"` + Status TemplateVersionStatus `json:"status"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CatalogTemplateVersion struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec TemplateVersionSpec `json:"spec"` + Status TemplateVersionStatus `json:"status"` +} + +type TemplateVersionSpec struct { + ExternalID string `json:"externalId,omitempty"` + Version string `json:"version,omitempty"` + RancherVersion string `json:"rancherVersion,omitempty"` + RequiredNamespace string `json:"requiredNamespace,omitempty"` + KubeVersion string `json:"kubeVersion,omitempty"` + UpgradeVersionLinks map[string]string `json:"upgradeVersionLinks,omitempty"` + Digest string `json:"digest,omitempty"` + RancherMinVersion string `json:"rancherMinVersion,omitempty"` + RancherMaxVersion string `json:"rancherMaxVersion,omitempty"` + + // Deprecated: Do not use + Files map[string]string `json:"files,omitempty" norman:"nocreate,noupdate"` + // Deprecated: Do not use + Questions []Question `json:"questions,omitempty" norman:"nocreate,noupdate"` + // Deprecated: Do not use + Readme string `json:"readme,omitempty" norman:"nocreate,noupdate"` + // Deprecated: Do not use + AppReadme string `json:"appReadme,omitempty" norman:"nocreate,noupdate"` + + // for local cache rebuilt + VersionName string `json:"versionName,omitempty"` + VersionDir string `json:"versionDir,omitempty"` + VersionURLs []string `json:"versionUrls,omitempty"` +} + +type TemplateVersionStatus struct { + HelmVersion string `json:"helmVersion,omitempty" norman:"noupdate,nocreate"` +} + +type File struct { + Name string `json:"name,omitempty"` + Contents string `json:"contents,omitempty"` +} + +type Question struct { + Variable string `json:"variable,omitempty" yaml:"variable,omitempty"` + Label string `json:"label,omitempty" yaml:"label,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Required bool `json:"required,omitempty" yaml:"required,omitempty"` + Default string `json:"default,omitempty" yaml:"default,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + MinLength int `json:"minLength,omitempty" yaml:"min_length,omitempty"` + MaxLength int `json:"maxLength,omitempty" yaml:"max_length,omitempty"` + Min int `json:"min,omitempty" yaml:"min,omitempty"` + Max int `json:"max,omitempty" yaml:"max,omitempty"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + ValidChars string `json:"validChars,omitempty" yaml:"valid_chars,omitempty"` + InvalidChars string `json:"invalidChars,omitempty" yaml:"invalid_chars,omitempty"` + Subquestions []SubQuestion `json:"subquestions,omitempty" yaml:"subquestions,omitempty"` + ShowIf string `json:"showIf,omitempty" yaml:"show_if,omitempty"` + ShowSubquestionIf string `json:"showSubquestionIf,omitempty" yaml:"show_subquestion_if,omitempty"` + Satisfies string `json:"satisfies,omitempty" yaml:"satisfies,omitempty"` +} + +type SubQuestion struct { + Variable string `json:"variable,omitempty" yaml:"variable,omitempty"` + Label string `json:"label,omitempty" yaml:"label,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Required bool `json:"required,omitempty" yaml:"required,omitempty"` + Default string `json:"default,omitempty" yaml:"default,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + MinLength int `json:"minLength,omitempty" yaml:"min_length,omitempty"` + MaxLength int `json:"maxLength,omitempty" yaml:"max_length,omitempty"` + Min int `json:"min,omitempty" yaml:"min,omitempty"` + Max int `json:"max,omitempty" yaml:"max,omitempty"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + ValidChars string `json:"validChars,omitempty" yaml:"valid_chars,omitempty"` + InvalidChars string `json:"invalidChars,omitempty" yaml:"invalid_chars,omitempty"` + ShowIf string `json:"showIf,omitempty" yaml:"show_if,omitempty"` + Satisfies string `json:"satisfies,omitempty" yaml:"satisfies,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TemplateContent is deprecated +// +// Deprecated: Do not use +type TemplateContent struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Data string `json:"data,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ProjectCatalog struct { + types.Namespaced + + Catalog `json:",inline" mapstructure:",squash"` + ProjectName string `json:"projectName,omitempty" norman:"type=reference[project]"` +} + +func (p *ProjectCatalog) ObjClusterName() string { + if parts := strings.SplitN(p.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterCatalog struct { + types.Namespaced + + Catalog `json:",inline" mapstructure:",squash"` + ClusterName string `json:"clusterName,omitempty" norman:"required,type=reference[cluster]"` +} + +type CatalogRefresh struct { + Catalogs []string `json:"catalogs"` +} + +type CatalogSecrets struct { + CredentialSecret string `json:"credentialSecret,omitempty" norman:"nocreate,noupdate"` +} + +// GetSecret gets a reference to the private catalog secret, either from the CatalogSecrets field or the Status field. +// Spec.CatalogSecrets.CredentialSecret is preferred because Status.CredentialSecret is deprecated. +func (c *Catalog) GetSecret() string { + if c.Spec.CatalogSecrets.CredentialSecret != "" { + return c.Spec.CatalogSecrets.CredentialSecret + } + return c.Status.CredentialSecret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_scan_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_scan_types.go new file mode 100644 index 0000000..43cd824 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_scan_types.go @@ -0,0 +1,8 @@ +package v3 + +type ClusterScanRunType string + +const ( + ClusterScanRunTypeManual ClusterScanRunType = "manual" + ClusterScanRunTypeScheduled ClusterScanRunType = "scheduled" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_template_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_template_types.go new file mode 100644 index 0000000..c7c2e51 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_template_types.go @@ -0,0 +1,103 @@ +package v3 + +import ( + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + ClusterTemplateRevisionConditionSecretsMigrated condition.Cond = "SecretsMigrated" + ClusterTemplateRevisionConditionACISecretsMigrated condition.Cond = "ACISecretsMigrated" + ClusterTemplateRevisionConditionRKESecretsMigrated condition.Cond = "RKESecretsMigrated" +) + +type ClusterTemplateRevisionConditionType string + +type ClusterTemplateRevisionCondition struct { + // Type of cluster template revision condition. + Type ClusterTemplateRevisionConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterTemplate struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterTemplateSpec `json:"spec"` +} + +type ClusterTemplateSpec struct { + DisplayName string `json:"displayName" norman:"required"` + Description string `json:"description"` + DefaultRevisionName string `json:"defaultRevisionName,omitempty" norman:"type=reference[clusterTemplateRevision]"` + + Members []Member `json:"members,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterTemplateRevision struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ClusterTemplateRevisionSpec `json:"spec"` + Status ClusterTemplateRevisionStatus `json:"status"` +} + +type ClusterTemplateRevisionSpec struct { + DisplayName string `json:"displayName" norman:"required"` + Enabled *bool `json:"enabled,omitempty" norman:"default=true"` + ClusterTemplateName string `json:"clusterTemplateName,omitempty" norman:"type=reference[clusterTemplate],required,noupdate"` + + Questions []Question `json:"questions,omitempty"` + ClusterConfig *ClusterSpecBase `json:"clusterConfig" norman:"required"` +} + +type ClusterTemplateRevisionStatus struct { + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" norman:"nocreate,noupdate"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" norman:"nocreate,noupdate"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" norman:"nocreate,noupdate"` + VsphereSecret string `json:"vsphereSecret,omitempty" norman:"nocreate,noupdate"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" norman:"nocreate,noupdate"` + OpenStackSecret string `json:"openStackSecret,omitempty" norman:"nocreate,noupdate"` + AADClientSecret string `json:"aadClientSecret,omitempty" norman:"nocreate,noupdate"` + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" norman:"nocreate,noupdate"` + ACIAPICUserKeySecret string `json:"aciAPICUserKeySecret,omitempty" norman:"nocreate,noupdate"` + ACITokenSecret string `json:"aciTokenSecret,omitempty" norman:"nocreate,noupdate"` + ACIKafkaClientKeySecret string `json:"aciKafkaClientKeySecret,omitempty" norman:"nocreate,noupdate"` + SecretsEncryptionProvidersSecret string `json:"secretsEncryptionProvidersSecret,omitempty" norman:"nocreate,noupdate"` + BastionHostSSHKeySecret string `json:"bastionHostSSHKeySecret,omitempty" norman:"nocreate,noupdate"` + KubeletExtraEnvSecret string `json:"kubeletExtraEnvSecret,omitempty" norman:"nocreate,noupdate"` + PrivateRegistryECRSecret string `json:"privateRegistryECRSecret,omitempty" norman:"nocreate,noupdate"` + Conditions []ClusterTemplateRevisionCondition `json:"conditions,omitempty"` +} + +type ClusterTemplateQuestionsOutput struct { + Questions []Question `json:"questions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_types.go new file mode 100644 index 0000000..29cb5e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/cluster_types.go @@ -0,0 +1,427 @@ +package v3 + +import ( + "bytes" + "encoding/gob" + "reflect" + "strings" + + aksv1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + eksv1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + gkev1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/version" +) + +func init() { + gob.Register(map[string]interface{}{}) + gob.Register([]interface{}{}) +} + +type ClusterConditionType string + +const ( + ClusterActionGenerateKubeconfig = "generateKubeconfig" + ClusterActionImportYaml = "importYaml" + ClusterActionExportYaml = "exportYaml" + ClusterActionBackupEtcd = "backupEtcd" + ClusterActionRestoreFromEtcdBackup = "restoreFromEtcdBackup" + ClusterActionRotateCertificates = "rotateCertificates" + ClusterActionRotateEncryptionKey = "rotateEncryptionKey" + ClusterActionSaveAsTemplate = "saveAsTemplate" + + // ClusterConditionReady Cluster ready to serve API (healthy when true, unhealthy when false) + ClusterConditionReady condition.Cond = "Ready" + ClusterConditionPending condition.Cond = "Pending" + ClusterConditionCertsGenerated condition.Cond = "CertsGenerated" + ClusterConditionEtcd condition.Cond = "etcd" + ClusterConditionProvisioned condition.Cond = "Provisioned" + ClusterConditionUpdated condition.Cond = "Updated" + ClusterConditionUpgraded condition.Cond = "Upgraded" + ClusterConditionWaiting condition.Cond = "Waiting" + ClusterConditionRemoved condition.Cond = "Removed" + // ClusterConditionNoDiskPressure true when all cluster nodes have sufficient disk + ClusterConditionNoDiskPressure condition.Cond = "NoDiskPressure" + // ClusterConditionNoMemoryPressure true when all cluster nodes have sufficient memory + ClusterConditionNoMemoryPressure condition.Cond = "NoMemoryPressure" + // ClusterConditionDefaultProjectCreated true when default project has been created + ClusterConditionDefaultProjectCreated condition.Cond = "DefaultProjectCreated" + // ClusterConditionSystemProjectCreated true when system project has been created + ClusterConditionSystemProjectCreated condition.Cond = "SystemProjectCreated" + // Deprecated: ClusterConditionDefaultNamespaceAssigned true when cluster's default namespace has been initially assigned + ClusterConditionDefaultNamespaceAssigned condition.Cond = "DefaultNamespaceAssigned" + // Deprecated: ClusterConditionSystemNamespacesAssigned true when cluster's system namespaces has been initially assigned to + // a system project + ClusterConditionSystemNamespacesAssigned condition.Cond = "SystemNamespacesAssigned" + ClusterConditionAddonDeploy condition.Cond = "AddonDeploy" + ClusterConditionSystemAccountCreated condition.Cond = "SystemAccountCreated" + ClusterConditionAgentDeployed condition.Cond = "AgentDeployed" + ClusterConditionGlobalAdminsSynced condition.Cond = "GlobalAdminsSynced" + ClusterConditionInitialRolesPopulated condition.Cond = "InitialRolesPopulated" + ClusterConditionServiceAccountMigrated condition.Cond = "ServiceAccountMigrated" + ClusterConditionAlertingEnabled condition.Cond = "AlertingEnabled" + ClusterConditionSecretsMigrated condition.Cond = "SecretsMigrated" + ClusterConditionServiceAccountSecretsMigrated condition.Cond = "ServiceAccountSecretsMigrated" + ClusterConditionHarvesterCloudProviderConfigMigrated condition.Cond = "HarvesterCloudProviderConfigMigrated" + ClusterConditionACISecretsMigrated condition.Cond = "ACISecretsMigrated" + ClusterConditionRKESecretsMigrated condition.Cond = "RKESecretsMigrated" + + ClusterDriverImported = "imported" + ClusterDriverLocal = "local" + ClusterDriverRKE = "rancherKubernetesEngine" + ClusterDriverK3s = "k3s" + ClusterDriverK3os = "k3os" + ClusterDriverRke2 = "rke2" + ClusterDriverAKS = "AKS" + ClusterDriverEKS = "EKS" + ClusterDriverGKE = "GKE" + ClusterDriverRancherD = "rancherd" + + ClusterPrivateRegistrySecret = "PrivateRegistrySecret" + ClusterPrivateRegistryURL = "PrivateRegistryURL" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Cluster struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ClusterSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status ClusterStatus `json:"status"` +} + +type ClusterSpecBase struct { + DesiredAgentImage string `json:"desiredAgentImage"` + DesiredAuthImage string `json:"desiredAuthImage"` + AgentImageOverride string `json:"agentImageOverride"` + AgentEnvVars []v1.EnvVar `json:"agentEnvVars,omitempty"` + RancherKubernetesEngineConfig *rketypes.RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty"` + DefaultPodSecurityAdmissionConfigurationTemplateName string `json:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty"` + DefaultClusterRoleForProjectMembers string `json:"defaultClusterRoleForProjectMembers,omitempty" norman:"type=reference[roleTemplate]"` + DockerRootDir string `json:"dockerRootDir,omitempty" norman:"default=/var/lib/docker"` + EnableNetworkPolicy *bool `json:"enableNetworkPolicy" norman:"default=false"` + WindowsPreferedCluster bool `json:"windowsPreferedCluster" norman:"noupdate"` + LocalClusterAuthEndpoint LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint,omitempty"` + ClusterSecrets ClusterSecrets `json:"clusterSecrets" norman:"nocreate,noupdate"` + ClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"clusterAgentDeploymentCustomization,omitempty"` + FleetAgentDeploymentCustomization *AgentDeploymentCustomization `json:"fleetAgentDeploymentCustomization,omitempty"` +} + +type AgentDeploymentCustomization struct { + AppendTolerations []v1.Toleration `json:"appendTolerations,omitempty"` + OverrideAffinity *v1.Affinity `json:"overrideAffinity,omitempty"` + OverrideResourceRequirements *v1.ResourceRequirements `json:"overrideResourceRequirements,omitempty"` +} + +type ClusterSpec struct { + ClusterSpecBase + DisplayName string `json:"displayName" norman:"required"` + Description string `json:"description"` + Internal bool `json:"internal" norman:"nocreate,noupdate"` + K3sConfig *K3sConfig `json:"k3sConfig,omitempty"` + Rke2Config *Rke2Config `json:"rke2Config,omitempty"` + ImportedConfig *ImportedConfig `json:"importedConfig,omitempty" norman:"nocreate,noupdate"` + GoogleKubernetesEngineConfig *MapStringInterface `json:"googleKubernetesEngineConfig,omitempty"` + AzureKubernetesServiceConfig *MapStringInterface `json:"azureKubernetesServiceConfig,omitempty"` + AmazonElasticContainerServiceConfig *MapStringInterface `json:"amazonElasticContainerServiceConfig,omitempty"` + GenericEngineConfig *MapStringInterface `json:"genericEngineConfig,omitempty"` + AKSConfig *aksv1.AKSClusterConfigSpec `json:"aksConfig,omitempty"` + EKSConfig *eksv1.EKSClusterConfigSpec `json:"eksConfig,omitempty"` + GKEConfig *gkev1.GKEClusterConfigSpec `json:"gkeConfig,omitempty"` + ClusterTemplateName string `json:"clusterTemplateName,omitempty" norman:"type=reference[clusterTemplate],nocreate,noupdate"` + ClusterTemplateRevisionName string `json:"clusterTemplateRevisionName,omitempty" norman:"type=reference[clusterTemplateRevision]"` + ClusterTemplateAnswers Answer `json:"answers,omitempty"` + ClusterTemplateQuestions []Question `json:"questions,omitempty" norman:"nocreate,noupdate"` + FleetWorkspaceName string `json:"fleetWorkspaceName,omitempty"` +} + +type ImportedConfig struct { + KubeConfig string `json:"kubeConfig" norman:"type=password"` +} + +type ClusterStatus struct { + // Conditions represent the latest available observations of an object's current state: + // More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#typical-status-properties + Conditions []ClusterCondition `json:"conditions,omitempty"` + // Component statuses will represent cluster's components (etcd/controller/scheduler) health + // https://kubernetes.io/docs/api-reference/v1.8/#componentstatus-v1-core + Driver string `json:"driver"` + Provider string `json:"provider"` + AgentImage string `json:"agentImage"` + AppliedAgentEnvVars []v1.EnvVar `json:"appliedAgentEnvVars,omitempty"` + AgentFeatures map[string]bool `json:"agentFeatures,omitempty"` + AuthImage string `json:"authImage"` + ComponentStatuses []ClusterComponentStatus `json:"componentStatuses,omitempty"` + APIEndpoint string `json:"apiEndpoint,omitempty"` + ServiceAccountToken string `json:"serviceAccountToken,omitempty"` + ServiceAccountTokenSecret string `json:"serviceAccountTokenSecret,omitempty"` + CACert string `json:"caCert,omitempty"` + Capacity v1.ResourceList `json:"capacity,omitempty"` + Allocatable v1.ResourceList `json:"allocatable,omitempty"` + AppliedSpec ClusterSpec `json:"appliedSpec,omitempty"` + FailedSpec *ClusterSpec `json:"failedSpec,omitempty"` + Requested v1.ResourceList `json:"requested,omitempty"` + Limits v1.ResourceList `json:"limits,omitempty"` + Version *version.Info `json:"version,omitempty"` + AppliedEnableNetworkPolicy bool `json:"appliedEnableNetworkPolicy" norman:"nocreate,noupdate,default=false"` + Capabilities Capabilities `json:"capabilities,omitempty"` + NodeVersion int `json:"nodeVersion,omitempty"` + NodeCount int `json:"nodeCount,omitempty" norman:"nocreate,noupdate"` + LinuxWorkerCount int `json:"linuxWorkerCount,omitempty" norman:"nocreate,noupdate"` + WindowsWorkerCount int `json:"windowsWorkerCount,omitempty" norman:"nocreate,noupdate"` + IstioEnabled bool `json:"istioEnabled,omitempty" norman:"nocreate,noupdate,default=false"` + CertificatesExpiration map[string]CertExpiration `json:"certificatesExpiration,omitempty"` + CurrentCisRunName string `json:"currentCisRunName,omitempty"` + AKSStatus AKSStatus `json:"aksStatus,omitempty" norman:"nocreate,noupdate"` + EKSStatus EKSStatus `json:"eksStatus,omitempty" norman:"nocreate,noupdate"` + GKEStatus GKEStatus `json:"gkeStatus,omitempty" norman:"nocreate,noupdate"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.PrivateRegistrySecret instead + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.S3CredentialSecret instead + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.WeavePasswordSecret instead + VsphereSecret string `json:"vsphereSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.VsphereSecret instead + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.VirtualCenterSecret instead + OpenStackSecret string `json:"openStackSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.OpenStackSecret instead + AADClientSecret string `json:"aadClientSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.AADClientSecret instead + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" norman:"nocreate,noupdate"` // Deprecated: use ClusterSpec.ClusterSecrets.AADClientCertSecret instead + + AppliedClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"appliedClusterAgentDeploymentCustomization,omitempty"` +} + +type ClusterComponentStatus struct { + Name string `json:"name"` + Conditions []v1.ComponentCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,2,rep,name=conditions"` +} + +type ClusterCondition struct { + // Type of cluster condition. + Type ClusterConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +type MapStringInterface map[string]interface{} + +func (m *MapStringInterface) DeepCopy() *MapStringInterface { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + dec := gob.NewDecoder(&buf) + err := enc.Encode(m) + if err != nil { + logrus.Errorf("error while deep copying MapStringInterface %v", err) + return nil + } + + var copy MapStringInterface + err = dec.Decode(©) + if err != nil { + logrus.Errorf("error while deep copying MapStringInterface %v", err) + return nil + } + + return © +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterRegistrationToken struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ClusterRegistrationTokenSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status ClusterRegistrationTokenStatus `json:"status"` +} + +func (c *ClusterRegistrationToken) ObjClusterName() string { + return c.Spec.ObjClusterName() +} + +type ClusterRegistrationTokenSpec struct { + ClusterName string `json:"clusterName" norman:"required,type=reference[cluster]"` +} + +func (c *ClusterRegistrationTokenSpec) ObjClusterName() string { + return c.ClusterName +} + +type ClusterRegistrationTokenStatus struct { + InsecureCommand string `json:"insecureCommand"` + Command string `json:"command"` + WindowsNodeCommand string `json:"windowsNodeCommand"` + InsecureWindowsNodeCommand string `json:"insecureWindowsNodeCommand"` + NodeCommand string `json:"nodeCommand"` + InsecureNodeCommand string `json:"insecureNodeCommand"` + ManifestURL string `json:"manifestUrl"` + Token string `json:"token"` +} + +type GenerateKubeConfigOutput struct { + Config string `json:"config"` +} + +type ExportOutput struct { + YAMLOutput string `json:"yamlOutput"` +} + +type ImportClusterYamlInput struct { + YAML string `json:"yaml,omitempty"` + DefaultNamespace string `json:"defaultNamespace,omitempty"` + Namespace string `json:"namespace,omitempty"` + ProjectName string `json:"projectName,omitempty" norman:"type=reference[project]"` +} + +func (i *ImportClusterYamlInput) ObjClusterName() string { + if parts := strings.SplitN(i.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type ImportYamlOutput struct { + Message string `json:"message,omitempty"` +} + +type Capabilities struct { + LoadBalancerCapabilities LoadBalancerCapabilities `json:"loadBalancerCapabilities,omitempty"` + IngressCapabilities []IngressCapabilities `json:"ingressCapabilities,omitempty"` + NodePoolScalingSupported bool `json:"nodePoolScalingSupported,omitempty"` + NodePortRange string `json:"nodePortRange,omitempty"` + TaintSupport *bool `json:"taintSupport,omitempty"` +} + +type LoadBalancerCapabilities struct { + Enabled *bool `json:"enabled,omitempty"` + Provider string `json:"provider,omitempty"` + ProtocolsSupported []string `json:"protocolsSupported,omitempty"` + HealthCheckSupported bool `json:"healthCheckSupported,omitempty"` +} + +type IngressCapabilities struct { + IngressProvider string `json:"ingressProvider,omitempty"` + CustomDefaultBackend *bool `json:"customDefaultBackend,omitempty"` +} + +type RestoreFromEtcdBackupInput struct { + EtcdBackupName string `json:"etcdBackupName,omitempty" norman:"type=reference[etcdBackup]"` + RestoreRkeConfig string `json:"restoreRkeConfig,omitempty"` +} + +type RotateCertificateInput struct { + CACertificates bool `json:"caCertificates,omitempty"` + Services []string `json:"services,omitempty" norman:"type=enum,options=etcd|kubelet|kube-apiserver|kube-proxy|kube-scheduler|kube-controller-manager"` +} + +type RotateCertificateOutput struct { + Message string `json:"message,omitempty"` +} + +type RotateEncryptionKeyOutput struct { + Message string `json:"message,omitempty"` +} + +type LocalClusterAuthEndpoint struct { + Enabled bool `json:"enabled"` + FQDN string `json:"fqdn,omitempty"` + CACerts string `json:"caCerts,omitempty"` +} + +type CertExpiration struct { + ExpirationDate string `json:"expirationDate,omitempty"` +} + +type SaveAsTemplateInput struct { + ClusterTemplateName string `json:"clusterTemplateName,omitempty"` + ClusterTemplateRevisionName string `json:"clusterTemplateRevisionName,omitempty"` +} + +type SaveAsTemplateOutput struct { + ClusterTemplateName string `json:"clusterTemplateName,omitempty"` + ClusterTemplateRevisionName string `json:"clusterTemplateRevisionName,omitempty"` +} + +type AKSStatus struct { + UpstreamSpec *aksv1.AKSClusterConfigSpec `json:"upstreamSpec"` + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel"` + RBACEnabled *bool `json:"rbacEnabled"` +} + +type EKSStatus struct { + UpstreamSpec *eksv1.EKSClusterConfigSpec `json:"upstreamSpec"` + VirtualNetwork string `json:"virtualNetwork"` + Subnets []string `json:"subnets"` + SecurityGroups []string `json:"securityGroups"` + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel"` + ManagedLaunchTemplateID string `json:"managedLaunchTemplateID"` + ManagedLaunchTemplateVersions map[string]string `json:"managedLaunchTemplateVersions"` + GeneratedNodeRole string `json:"generatedNodeRole"` +} + +type GKEStatus struct { + UpstreamSpec *gkev1.GKEClusterConfigSpec `json:"upstreamSpec"` + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel"` +} + +type ClusterSecrets struct { + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" norman:"nocreate,noupdate"` + PrivateRegistryURL string `json:"privateRegistryURL,omitempty" norman:"nocreate,noupdate"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" norman:"nocreate,noupdate"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" norman:"nocreate,noupdate"` + VsphereSecret string `json:"vsphereSecret,omitempty" norman:"nocreate,noupdate"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" norman:"nocreate,noupdate"` + OpenStackSecret string `json:"openStackSecret,omitempty" norman:"nocreate,noupdate"` + AADClientSecret string `json:"aadClientSecret,omitempty" norman:"nocreate,noupdate"` + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" norman:"nocreate,noupdate"` + ACIAPICUserKeySecret string `json:"aciAPICUserKeySecret,omitempty" norman:"nocreate,noupdate"` + ACITokenSecret string `json:"aciTokenSecret,omitempty" norman:"nocreate,noupdate"` + ACIKafkaClientKeySecret string `json:"aciKafkaClientKeySecret,omitempty" norman:"nocreate,noupdate"` + SecretsEncryptionProvidersSecret string `json:"secretsEncryptionProvidersSecret,omitempty" norman:"nocreate,noupdate"` + BastionHostSSHKeySecret string `json:"bastionHostSSHKeySecret,omitempty" norman:"nocreate,noupdate"` + KubeletExtraEnvSecret string `json:"kubeletExtraEnvSecret,omitempty" norman:"nocreate,noupdate"` + PrivateRegistryECRSecret string `json:"privateRegistryECRSecret,omitempty" norman:"nocreate,noupdate"` +} + +// GetSecret gets a reference to a secret by its field name, either from the ClusterSecrets field or the Status field. +// Spec.ClusterSecrets.* is preferred because the secret fields on Status are deprecated. +func (c *Cluster) GetSecret(key string) string { + clusterSecrets := reflect.ValueOf(&c.Spec.ClusterSecrets).Elem() + secret := clusterSecrets.FieldByName(key) + if secret.IsValid() && secret.String() != "" { + return secret.String() + } + status := reflect.ValueOf(&c.Status).Elem() + secret = status.FieldByName(key) + if secret.IsValid() { + return secret.String() + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/compose_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/compose_types.go new file mode 100644 index 0000000..e713fe2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/compose_types.go @@ -0,0 +1,50 @@ +package v3 + +import ( + "github.com/rancher/norman/condition" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ComposeConfig struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ComposeSpec `json:"spec,omitempty"` + Status ComposeStatus `json:"status,omitempty"` +} + +type ComposeSpec struct { + RancherCompose string `json:"rancherCompose,omitempty"` +} + +type ComposeStatus struct { + Conditions []ComposeCondition `json:"conditions,omitempty"` +} + +var ( + ComposeConditionExecuted condition.Cond = "Executed" +) + +type ComposeCondition struct { + // Type of cluster condition. + Type string `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/constants.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/constants.go new file mode 100644 index 0000000..62d4154 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/constants.go @@ -0,0 +1,26 @@ +package v3 + +import ( + cond "github.com/rancher/norman/condition" +) + +const ( + // transition type + + Created cond.Cond = "Created" + RunCompleted cond.Cond = "RunCompleted" + + // done type + + Completed cond.Cond = "Completed" + Ready cond.Cond = "Ready" + + // error type + + Failed cond.Cond = "Failed" + + // generic type + // these will not trigger any state change on the object + + Alerted cond.Cond = "Alerted" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/doc.go new file mode 100644 index 0000000..85f76e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=management.cattle.io +package v3 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/fleet.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/fleet.go new file mode 100644 index 0000000..93be698 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/fleet.go @@ -0,0 +1,18 @@ +package v3 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type FleetWorkspace struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Status FleetWorkspaceStatus `json:"status,omitempty"` +} + +type FleetWorkspaceStatus struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/global_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/global_types.go new file mode 100644 index 0000000..21805d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/global_types.go @@ -0,0 +1,49 @@ +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Setting struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Value string `json:"value" norman:"required"` + Default string `json:"default" norman:"nocreate,noupdate"` + Customized bool `json:"customized" norman:"nocreate,noupdate"` + Source string `json:"source" norman:"nocreate,noupdate,options=db|default|env"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Feature struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec FeatureSpec `json:"spec"` + Status FeatureStatus `json:"status"` +} + +type FeatureSpec struct { + Value *bool `json:"value" norman:"required"` +} + +type FeatureStatus struct { + Dynamic bool `json:"dynamic"` + Default bool `json:"default"` + Description string `json:"description"` + LockedValue *bool `json:"lockedValue"` +} + +const ( + ExperimentalFeatureKey = "feature.cattle.io/experimental" + ExperimentalFeatureValue = "true" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/globaldns_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/globaldns_types.go new file mode 100644 index 0000000..2ca6d81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/globaldns_types.go @@ -0,0 +1,87 @@ +package v3 + +import ( + "github.com/rancher/norman/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GlobalDns struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec GlobalDNSSpec `json:"spec,omitempty"` + Status GlobalDNSStatus `json:"status,omitempty"` +} + +type GlobalDNSSpec struct { + FQDN string `json:"fqdn,omitempty" norman:"type=hostname,required"` + TTL int64 `json:"ttl,omitempty" norman:"default=300"` + ProjectNames []string `json:"projectNames" norman:"type=array[reference[project]],noupdate"` + MultiClusterAppName string `json:"multiClusterAppName,omitempty" norman:"type=reference[multiClusterApp]"` + ProviderName string `json:"providerName,omitempty" norman:"type=reference[globalDnsProvider],required"` + Members []Member `json:"members,omitempty"` +} + +type GlobalDNSStatus struct { + Endpoints []string `json:"endpoints,omitempty"` + ClusterEndpoints map[string][]string `json:"clusterEndpoints,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GlobalDnsProvider struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + //ObjectMeta.Name = GlobalDNSProviderID + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec GlobalDNSProviderSpec `json:"spec,omitempty"` +} + +type GlobalDNSProviderSpec struct { + Route53ProviderConfig *Route53ProviderConfig `json:"route53ProviderConfig,omitempty"` + CloudflareProviderConfig *CloudflareProviderConfig `json:"cloudflareProviderConfig,omitempty"` + AlidnsProviderConfig *AlidnsProviderConfig `json:"alidnsProviderConfig,omitempty"` + Members []Member `json:"members,omitempty"` + RootDomain string `json:"rootDomain"` +} + +type Route53ProviderConfig struct { + AccessKey string `json:"accessKey" norman:"notnullable,required,minLength=1"` + SecretKey string `json:"secretKey" norman:"notnullable,required,minLength=1,type=password"` + CredentialsPath string `json:"credentialsPath" norman:"default=/.aws"` + RoleArn string `json:"roleArn,omitempty"` + Region string `json:"region" norman:"default=us-east-1"` + ZoneType string `json:"zoneType" norman:"default=public"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty"` +} + +type CloudflareProviderConfig struct { + APIKey string `json:"apiKey" norman:"notnullable,required,minLength=1,type=password"` + APIEmail string `json:"apiEmail" norman:"notnullable,required,minLength=1"` + ProxySetting *bool `json:"proxySetting" norman:"default=true"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty"` +} + +type UpdateGlobalDNSTargetsInput struct { + ProjectNames []string `json:"projectNames" norman:"type=array[reference[project]]"` +} + +type AlidnsProviderConfig struct { + AccessKey string `json:"accessKey" norman:"notnullable,required,minLength=1"` + SecretKey string `json:"secretKey" norman:"notnullable,required,minLength=1,type=password"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/k3s_base_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/k3s_base_types.go new file mode 100644 index 0000000..59ee59e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/k3s_base_types.go @@ -0,0 +1,32 @@ +package v3 + +// K3sConfig provides desired configuration for k3s clusters +type K3sConfig struct { + Version string `yaml:"kubernetes_version" json:"kubernetesVersion,omitempty"` + ClusterUpgradeStrategy `yaml:"k3s_upgrade_strategy,omitempty" json:"k3supgradeStrategy,omitempty"` +} +type Rke2Config struct { + Version string `yaml:"kubernetes_version" json:"kubernetesVersion,omitempty"` + ClusterUpgradeStrategy `yaml:"rke2_upgrade_strategy,omitempty" json:"rke2upgradeStrategy,omitempty"` +} + +// ClusterUpgradeStrategy provides configuration to the downstream system-upgrade-controller +type ClusterUpgradeStrategy struct { + // How many controlplane nodes should be upgrade at time, defaults to 1 + ServerConcurrency int `yaml:"server_concurrency" json:"serverConcurrency,omitempty" norman:"min=1"` + // How many workers should be upgraded at a time + WorkerConcurrency int `yaml:"worker_concurrency" json:"workerConcurrency,omitempty" norman:"min=1"` + // Whether controlplane nodes should be drained + DrainServerNodes bool `yaml:"drain_server_nodes" json:"drainServerNodes,omitempty"` + // Whether worker nodes should be drained + DrainWorkerNodes bool `yaml:"drain_worker_nodes" json:"drainWorkerNodes,omitempty"` +} + +func (r *Rke2Config) SetStrategy(serverConcurrency, workerConcurrency int) { + r.ClusterUpgradeStrategy.ServerConcurrency = serverConcurrency + r.ClusterUpgradeStrategy.WorkerConcurrency = workerConcurrency +} +func (k *K3sConfig) SetStrategy(serverConcurrency, workerConcurrency int) { + k.ClusterUpgradeStrategy.ServerConcurrency = serverConcurrency + k.ClusterUpgradeStrategy.WorkerConcurrency = workerConcurrency +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/kontainer_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/kontainer_types.go new file mode 100644 index 0000000..7d7416d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/kontainer_types.go @@ -0,0 +1,47 @@ +package v3 + +import ( + "github.com/rancher/norman/condition" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type KontainerDriver struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec KontainerDriverSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status KontainerDriverStatus `json:"status"` +} + +type KontainerDriverStatus struct { + ActualURL string `json:"actualUrl"` + ExecutablePath string `json:"executablePath"` + Conditions []Condition `json:"conditions"` + DisplayName string `json:"displayName"` +} + +type KontainerDriverSpec struct { + URL string `json:"url" norman:"required"` + Checksum string `json:"checksum"` + BuiltIn bool `json:"builtIn" norman:"noupdate"` + Active bool `json:"active"` + UIURL string `json:"uiUrl"` + WhitelistDomains []string `json:"whitelistDomains,omitempty"` +} + +var ( + KontainerDriverConditionDownloaded condition.Cond = "Downloaded" + KontainerDriverConditionInstalled condition.Cond = "Installed" + KontainerDriverConditionActive condition.Cond = "Active" + KontainerDriverConditionInactive condition.Cond = "Inactive" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/logging_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/logging_types.go new file mode 100644 index 0000000..855b927 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/logging_types.go @@ -0,0 +1,230 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ClusterLogging struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ClusterLoggingSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status ClusterLoggingStatus `json:"status"` +} + +func (c *ClusterLogging) ObjClusterName() string { + return c.Spec.ObjClusterName() +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ProjectLogging struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec ProjectLoggingSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status ProjectLoggingStatus `json:"status"` +} + +func (p *ProjectLogging) ObjClusterName() string { + return p.Spec.ObjClusterName() +} + +type LoggingCommonField struct { + DisplayName string `json:"displayName,omitempty"` + OutputFlushInterval int `json:"outputFlushInterval,omitempty" norman:"default=60"` + OutputTags map[string]string `json:"outputTags,omitempty"` + EnableJSONParsing bool `json:"enableJSONParsing,omitempty"` +} + +type LoggingTargets struct { + ElasticsearchConfig *ElasticsearchConfig `json:"elasticsearchConfig,omitempty"` + SplunkConfig *SplunkConfig `json:"splunkConfig,omitempty"` + KafkaConfig *KafkaConfig `json:"kafkaConfig,omitempty"` + SyslogConfig *SyslogConfig `json:"syslogConfig,omitempty"` + FluentForwarderConfig *FluentForwarderConfig `json:"fluentForwarderConfig,omitempty"` + CustomTargetConfig *CustomTargetConfig `json:"customTargetConfig,omitempty"` +} + +type ClusterLoggingSpec struct { + LoggingTargets + LoggingCommonField + ClusterName string `json:"clusterName" norman:"type=reference[cluster]"` + IncludeSystemComponent *bool `json:"includeSystemComponent,omitempty" norman:"default=true"` +} + +func (c *ClusterLoggingSpec) ObjClusterName() string { + return c.ClusterName +} + +type ProjectLoggingSpec struct { + LoggingTargets + LoggingCommonField + ProjectName string `json:"projectName" norman:"type=reference[project]"` +} + +func (p *ProjectLoggingSpec) ObjClusterName() string { + if parts := strings.SplitN(p.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type ClusterLoggingStatus struct { + Conditions []LoggingCondition `json:"conditions,omitempty"` + AppliedSpec ClusterLoggingSpec `json:"appliedSpec,omitempty"` + FailedSpec *ClusterLoggingSpec `json:"failedSpec,omitempty"` +} + +type ProjectLoggingStatus struct { + Conditions []LoggingCondition `json:"conditions,omitempty"` + AppliedSpec ProjectLoggingSpec `json:"appliedSpec,omitempty"` +} + +var ( + LoggingConditionProvisioned condition.Cond = "Provisioned" + LoggingConditionUpdated condition.Cond = "Updated" +) + +type LoggingCondition struct { + // Type of cluster condition. + Type condition.Cond `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +type ElasticsearchConfig struct { + Endpoint string `json:"endpoint,omitempty" norman:"required"` + IndexPrefix string `json:"indexPrefix,omitempty" norman:"required"` + DateFormat string `json:"dateFormat,omitempty" norman:"required,type=enum,options=YYYY-MM-DD|YYYY-MM|YYYY,default=YYYY-MM-DD"` + AuthUserName string `json:"authUsername,omitempty"` + AuthPassword string `json:"authPassword,omitempty" norman:"type=password"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + ClientKeyPass string `json:"clientKeyPass,omitempty"` + SSLVerify bool `json:"sslVerify,omitempty"` + SSLVersion string `json:"sslVersion,omitempty" norman:"type=enum,options=SSLv23|TLSv1|TLSv1_1|TLSv1_2,default=TLSv1_2"` +} + +type SplunkConfig struct { + Endpoint string `json:"endpoint,omitempty" norman:"required"` + Source string `json:"source,omitempty"` + Token string `json:"token,omitempty" norman:"required,type=password"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + ClientKeyPass string `json:"clientKeyPass,omitempty"` + SSLVerify bool `json:"sslVerify,omitempty"` + Index string `json:"index,omitempty"` +} + +type KafkaConfig struct { + ZookeeperEndpoint string `json:"zookeeperEndpoint,omitempty"` + BrokerEndpoints []string `json:"brokerEndpoints,omitempty"` + Topic string `json:"topic,omitempty" norman:"required"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + SaslUsername string `json:"saslUsername,omitempty"` + SaslPassword string `json:"saslPassword,omitempty" norman:"type=password"` + SaslScramMechanism string `json:"saslScramMechanism,omitempty" norman:"type=enum,options=sha256|sha512"` + SaslType string `json:"saslType,omitempty" norman:"type=enum,options=plain|scram"` +} + +type SyslogConfig struct { + Endpoint string `json:"endpoint,omitempty" norman:"required"` + Severity string `json:"severity,omitempty" norman:"default=notice,type=enum,options=emerg|alert|crit|err|warning|notice|info|debug"` + Program string `json:"program,omitempty"` + Protocol string `json:"protocol,omitempty" norman:"default=udp,type=enum,options=udp|tcp"` + Token string `json:"token,omitempty" norman:"type=password"` + EnableTLS bool `json:"enableTls,omitempty" norman:"default=false"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + SSLVerify bool `json:"sslVerify,omitempty"` +} + +type FluentForwarderConfig struct { + EnableTLS bool `json:"enableTls,omitempty" norman:"default=false"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + ClientKeyPass string `json:"clientKeyPass,omitempty"` + SSLVerify bool `json:"sslVerify,omitempty"` + Compress *bool `json:"compress,omitempty" norman:"default=true"` + FluentServers []FluentServer `json:"fluentServers,omitempty" norman:"required"` +} + +type FluentServer struct { + Endpoint string `json:"endpoint,omitempty" norman:"required"` + Hostname string `json:"hostname,omitempty"` + Weight int `json:"weight,omitempty" norman:"default=100"` + Standby bool `json:"standby,omitempty" norman:"default=false"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty" norman:"type=password"` + SharedKey string `json:"sharedKey,omitempty" norman:"type=password"` +} + +type CustomTargetConfig struct { + Content string `json:"content,omitempty"` + Certificate string `json:"certificate,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` +} + +type ClusterTestInput struct { + ClusterName string `json:"clusterId" norman:"required,type=reference[cluster]"` + LoggingTargets + OutputTags map[string]string `json:"outputTags,omitempty"` +} + +func (c *ClusterTestInput) ObjClusterName() string { + return c.ClusterName +} + +type ProjectTestInput struct { + ProjectName string `json:"projectId" norman:"required,type=reference[project]"` + LoggingTargets + OutputTags map[string]string `json:"outputTags,omitempty"` +} + +func (p *ProjectTestInput) ObjClusterName() string { + if parts := strings.SplitN(p.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/machine_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/machine_types.go new file mode 100644 index 0000000..6208d2e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/machine_types.go @@ -0,0 +1,381 @@ +package v3 + +import ( + "time" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + rketypes "github.com/rancher/rke/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NodeTemplate struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec NodeTemplateSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status NodeTemplateStatus `json:"status"` +} + +type NodeTemplateStatus struct { + Conditions []NodeTemplateCondition `json:"conditions"` +} + +type NodeTemplateCondition struct { + // Type of cluster condition. + Type string `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` +} + +type NodeTemplateSpec struct { + DisplayName string `json:"displayName"` + Description string `json:"description"` + Driver string `json:"driver" norman:"nocreate,noupdate"` + CloudCredentialName string `json:"cloudCredentialName" norman:"type=reference[cloudCredential]"` + NodeTaints []v1.Taint `json:"nodeTaints,omitempty"` + NodeCommonParams `json:",inline"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Node struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec NodeSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status NodeStatus `json:"status"` +} + +func (in *Node) ObjClusterName() string { + return in.Namespace +} + +type MetadataUpdate struct { + Labels MapDelta `json:"labels,omitempty"` + Annotations MapDelta `json:"annotations,omitempty"` +} + +type MapDelta struct { + Add map[string]string `json:"add,omitempty"` + Delete map[string]bool `json:"delete,omitempty"` +} + +type NodeStatus struct { + Conditions []NodeCondition `json:"conditions,omitempty"` + InternalNodeStatus v1.NodeStatus `json:"internalNodeStatus,omitempty"` + NodeName string `json:"nodeName,omitempty"` + Requested v1.ResourceList `json:"requested,omitempty"` + Limits v1.ResourceList `json:"limits,omitempty"` + NodeTemplateSpec *NodeTemplateSpec `json:"nodeTemplateSpec,omitempty"` + NodeConfig *rketypes.RKEConfigNode `json:"rkeNode,omitempty"` + NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty"` + NodeTaints []v1.Taint `json:"nodeTaints,omitempty"` + DockerInfo *DockerInfo `json:"dockerInfo,omitempty"` + NodePlan *NodePlan `json:"nodePlan,omitempty"` + AppliedNodeVersion int `json:"appliedNodeVersion,omitempty"` +} + +type DockerInfo struct { + ID string + Driver string + Debug bool + LoggingDriver string + CgroupDriver string + KernelVersion string + OperatingSystem string + OSType string + Architecture string + IndexServerAddress string + InitBinary string + DockerRootDir string + SecurityOptions []string + HTTPProxy string + HTTPSProxy string + NoProxy string + Name string + Labels []string + ExperimentalBuild bool + ServerVersion string +} + +var ( + NodeConditionInitialized condition.Cond = "Initialized" + NodeConditionProvisioned condition.Cond = "Provisioned" + NodeConditionUpdated condition.Cond = "Updated" + NodeConditionRegistered condition.Cond = "Registered" + NodeConditionRemoved condition.Cond = "Removed" + NodeConditionConfigSaved condition.Cond = "Saved" + NodeConditionReady condition.Cond = "Ready" + NodeConditionDrained condition.Cond = "Drained" + NodeConditionUpgraded condition.Cond = "Upgraded" +) + +type NodeCondition struct { + // Type of cluster condition. + Type condition.Cond `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +var ( + NodePoolConditionUpdated condition.Cond = "Updated" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NodePool struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec NodePoolSpec `json:"spec"` + Status NodePoolStatus `json:"status"` +} + +func (n *NodePool) ObjClusterName() string { + return n.Spec.ObjClusterName() +} + +type NodePoolSpec struct { + Etcd bool `json:"etcd"` + ControlPlane bool `json:"controlPlane"` + Worker bool `json:"worker"` + NodeTemplateName string `json:"nodeTemplateName,omitempty" norman:"type=reference[nodeTemplate],required,notnullable"` + + HostnamePrefix string `json:"hostnamePrefix" norman:"required,notnullable"` + Quantity int `json:"quantity" norman:"required,default=1"` + DrainBeforeDelete bool `json:"drainBeforeDelete" norman:"default=false"` + NodeLabels map[string]string `json:"nodeLabels"` + NodeAnnotations map[string]string `json:"nodeAnnotations"` + NodeTaints []v1.Taint `json:"nodeTaints,omitempty"` + + DisplayName string `json:"displayName"` + ClusterName string `json:"clusterName,omitempty" norman:"type=reference[cluster],noupdate,required"` + + DeleteNotReadyAfterSecs time.Duration `json:"deleteNotReadyAfterSecs" norman:"default=0,max=31540000,min=0"` +} + +func (n *NodePoolSpec) ObjClusterName() string { + return n.ClusterName +} + +type NodePoolStatus struct { + Conditions []Condition `json:"conditions"` +} + +type CustomConfig struct { + // IP or FQDN that is fully resolvable and used for SSH communication + Address string `yaml:"address" json:"address,omitempty"` + // Optional - Internal address that will be used for components communication + InternalAddress string `yaml:"internal_address" json:"internalAddress,omitempty"` + // SSH user that will be used by RKE + User string `yaml:"user" json:"user,omitempty"` + // Optional - Docker socket on the node that will be used in tunneling + DockerSocket string `yaml:"docker_socket" json:"dockerSocket,omitempty"` + // SSH Private Key + SSHKey string `yaml:"ssh_key" json:"sshKey,omitempty" norman:"type=password"` + // SSH Certificate + SSHCert string `yaml:"ssh_cert" json:"sshCert,omitempty"` + Label map[string]string `yaml:"label" json:"label,omitempty"` + Taints []string `yaml:"taints" json:"taints,omitempty"` +} + +type NodeSpec struct { + // Common fields. They aren't in a shared struct because the annotations are different + + Etcd bool `json:"etcd" norman:"noupdate"` + ControlPlane bool `json:"controlPlane" norman:"noupdate"` + Worker bool `json:"worker" norman:"noupdate"` + NodeTemplateName string `json:"nodeTemplateName,omitempty" norman:"type=reference[nodeTemplate],noupdate"` + + NodePoolName string `json:"nodePoolName" norman:"type=reference[nodePool],nocreate,noupdate"` + CustomConfig *CustomConfig `json:"customConfig"` + Imported bool `json:"imported"` + Description string `json:"description,omitempty"` + DisplayName string `json:"displayName"` + RequestedHostname string `json:"requestedHostname,omitempty" norman:"type=hostname,nullable,noupdate,required"` + InternalNodeSpec v1.NodeSpec `json:"internalNodeSpec"` + DesiredNodeTaints []v1.Taint `json:"desiredNodeTaints"` + UpdateTaintsFromAPI *bool `json:"updateTaintsFromAPI,omitempty"` + DesiredNodeUnschedulable string `json:"desiredNodeUnschedulable,omitempty"` + NodeDrainInput *NodeDrainInput `json:"nodeDrainInput,omitempty"` + MetadataUpdate MetadataUpdate `json:"metadataUpdate,omitempty"` + ScaledownTime string `json:"scaledownTime,omitempty"` +} + +type NodePlan struct { + Plan *rketypes.RKEConfigNodePlan `json:"plan,omitempty"` + Version int `json:"version,omitempty"` + // current default in rancher-agent is 2m (120s) + AgentCheckInterval int `json:"agentCheckInterval,omitempty" norman:"min=1,max=1800,default=120"` +} + +type NodeCommonParams struct { + AuthCertificateAuthority string `json:"authCertificateAuthority,omitempty"` + AuthKey string `json:"authKey,omitempty"` + EngineInstallURL string `json:"engineInstallURL,omitempty"` + DockerVersion string `json:"dockerVersion,omitempty"` + EngineOpt map[string]string `json:"engineOpt,omitempty"` + StorageOpt map[string]string `json:"storageOpt,omitempty"` + LogOpt map[string]string `json:"logOpt,omitempty"` + EngineInsecureRegistry []string `json:"engineInsecureRegistry,omitempty"` + EngineRegistryMirror []string `json:"engineRegistryMirror,omitempty"` + EngineLabel map[string]string `json:"engineLabel,omitempty"` + EngineStorageDriver string `json:"engineStorageDriver,omitempty"` + EngineEnv map[string]string `json:"engineEnv,omitempty"` + UseInternalIPAddress *bool `json:"useInternalIpAddress,omitempty" norman:"default=true,noupdate"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NodeDriver struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec NodeDriverSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status NodeDriverStatus `json:"status"` +} + +type NodeDriverStatus struct { + Conditions []Condition `json:"conditions"` + AppliedURL string `json:"appliedURL"` + AppliedChecksum string `json:"appliedChecksum"` + AppliedDockerMachineVersion string `json:"appliedDockerMachineVersion"` +} + +var ( + NodeDriverConditionDownloaded condition.Cond = "Downloaded" + NodeDriverConditionInstalled condition.Cond = "Installed" + NodeDriverConditionActive condition.Cond = "Active" + NodeDriverConditionInactive condition.Cond = "Inactive" +) + +type Condition struct { + // Type of cluster condition. + Type string `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +type NodeDriverSpec struct { + DisplayName string `json:"displayName"` + Description string `json:"description"` + URL string `json:"url" norman:"required"` + ExternalID string `json:"externalId"` + Builtin bool `json:"builtin"` + Active bool `json:"active"` + // If AddCloudCredential is true, then the cloud credential schema is created + // regardless of whether the node driver is active. + AddCloudCredential bool `json:"addCloudCredential"` + Checksum string `json:"checksum"` + UIURL string `json:"uiUrl"` + WhitelistDomains []string `json:"whitelistDomains,omitempty"` +} + +type PublicEndpoint struct { + NodeName string `json:"nodeName,omitempty" norman:"type=reference[/v3/schemas/node],nocreate,noupdate"` + Addresses []string `json:"addresses,omitempty" norman:"nocreate,noupdate"` + Port int32 `json:"port,omitempty" norman:"nocreate,noupdate"` + Protocol string `json:"protocol,omitempty" norman:"nocreate,noupdate"` + // for node port service endpoint + ServiceName string `json:"serviceName,omitempty" norman:"type=reference[service],nocreate,noupdate"` + // for host port endpoint + PodName string `json:"podName,omitempty" norman:"type=reference[pod],nocreate,noupdate"` + // for ingress endpoint. ServiceName, podName, ingressName are mutually exclusive + IngressName string `json:"ingressName,omitempty" norman:"type=reference[ingress],nocreate,noupdate"` + // Hostname/path are set for Ingress endpoints + Hostname string `json:"hostname,omitempty" norman:"nocreate,noupdate"` + Path string `json:"path,omitempty" norman:"nocreate,noupdate"` + // True when endpoint is exposed on every node + AllNodes bool `json:"allNodes" norman:"nocreate,noupdate"` +} + +type NodeDrainInput = rketypes.NodeDrainInput + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CloudCredential struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CloudCredentialSpec `json:"spec"` +} + +type CloudCredentialSpec struct { + DisplayName string `json:"displayName"` + Description string `json:"description,omitempty"` + S3CredentialConfig *S3CredentialConfig `json:"s3credentialConfig,omitempty"` +} + +type S3CredentialConfig struct { + AccessKey string `norman:"required"` + SecretKey string `norman:"required,type=password"` + DefaultRegion string + DefaultEndpoint string + DefaultEndpointCA string + DefaultSkipSSLVerify string + DefaultBucket string + DefaultFolder string +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/managed_chart.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/managed_chart.go new file mode 100644 index 0000000..8bbd89c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/managed_chart.go @@ -0,0 +1,42 @@ +package v3 + +import ( + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ManagedChart struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ManagedChartSpec `json:"spec"` + Status ManagedChartStatus `json:"status"` +} + +type ManagedChartSpec struct { + Paused bool `json:"paused,omitempty"` + Chart string `json:"chart,omitempty"` + RepoName string `json:"repoName,omitempty"` + ReleaseName string `json:"releaseName,omitempty"` + Version string `json:"version,omitempty"` + TimeoutSeconds int `json:"timeoutSeconds,omitempty"` + Values *fleet.GenericMap `json:"values,omitempty"` + Force bool `json:"force,omitempty"` + TakeOwnership bool `json:"takeOwnership,omitempty"` + MaxHistory int `json:"maxHistory,omitempty"` + DefaultNamespace string `json:"defaultNamespace,omitempty"` + TargetNamespace string `json:"namespace,omitempty"` + ServiceAccount string `json:"serviceAccount,omitempty"` + Diff *fleet.DiffOptions `json:"diff,omitempty"` + + RolloutStrategy *fleet.RolloutStrategy `json:"rolloutStrategy,omitempty"` + Targets []fleet.BundleTarget `json:"targets,omitempty"` +} + +type ManagedChartStatus struct { + fleet.BundleStatus +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/multi_cluster_app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/multi_cluster_app.go new file mode 100644 index 0000000..169c975 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/multi_cluster_app.go @@ -0,0 +1,114 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + MultiClusterAppConditionInstalled condition.Cond = "Installed" + MultiClusterAppConditionDeployed condition.Cond = "Deployed" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type MultiClusterApp struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + + Spec MultiClusterAppSpec `json:"spec"` + Status MultiClusterAppStatus `json:"status"` +} + +type MultiClusterAppSpec struct { + TemplateVersionName string `json:"templateVersionName,omitempty" norman:"type=reference[templateVersion],required"` + Answers []Answer `json:"answers,omitempty"` + Wait bool `json:"wait,omitempty"` + Timeout int `json:"timeout,omitempty" norman:"min=1,default=300"` + Targets []Target `json:"targets,omitempty" norman:"required,noupdate"` + Members []Member `json:"members,omitempty"` + Roles []string `json:"roles,omitempty" norman:"type=array[reference[roleTemplate]],required"` + RevisionHistoryLimit int `json:"revisionHistoryLimit,omitempty" norman:"default=10"` + UpgradeStrategy UpgradeStrategy `json:"upgradeStrategy,omitempty"` +} + +type MultiClusterAppStatus struct { + Conditions []v3.AppCondition `json:"conditions,omitempty"` + RevisionName string `json:"revisionName,omitempty" norman:"type=reference[multiClusterAppRevision],required"` + HelmVersion string `json:"helmVersion,omitempty" norman:"nocreate,noupdate"` +} + +type Target struct { + ProjectName string `json:"projectName,omitempty" norman:"type=reference[project],required"` + AppName string `json:"appName,omitempty" norman:"type=reference[v3/projects/schemas/app]"` + State string `json:"state,omitempty"` + Healthstate string `json:"healthState,omitempty"` +} + +func (t *Target) ObjClusterName() string { + if parts := strings.SplitN(t.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type Answer struct { + ProjectName string `json:"projectName,omitempty" norman:"type=reference[project]"` + ClusterName string `json:"clusterName,omitempty" norman:"type=reference[cluster]"` + Values map[string]string `json:"values,omitempty"` + ValuesSetString map[string]string `json:"valuesSetString,omitempty"` +} + +func (a *Answer) ObjClusterName() string { + return a.ClusterName +} + +type Member struct { + UserName string `json:"userName,omitempty" norman:"type=reference[user]"` + UserPrincipalName string `json:"userPrincipalName,omitempty" norman:"type=reference[principal]"` + DisplayName string `json:"displayName,omitempty"` + GroupPrincipalName string `json:"groupPrincipalName,omitempty" norman:"type=reference[principal]"` + AccessType string `json:"accessType,omitempty" norman:"type=enum,options=owner|member|read-only"` +} + +type UpgradeStrategy struct { + RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"` +} + +type RollingUpdate struct { + BatchSize int `json:"batchSize,omitempty"` + Interval int `json:"interval,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type MultiClusterAppRevision struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + TemplateVersionName string `json:"templateVersionName,omitempty" norman:"type=reference[templateVersion]"` + Answers []Answer `json:"answers,omitempty"` +} + +type MultiClusterAppRollbackInput struct { + RevisionName string `json:"revisionName,omitempty" norman:"type=reference[multiClusterAppRevision]"` +} + +type UpdateMultiClusterAppTargetsInput struct { + Projects []string `json:"projects" norman:"type=array[reference[project]],required"` + Answers []Answer `json:"answers"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/network_policy_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/network_policy_types.go new file mode 100644 index 0000000..2020cdd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/network_policy_types.go @@ -0,0 +1,36 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ProjectNetworkPolicySpec struct { + ProjectName string `json:"projectName,omitempty" norman:"required,type=reference[project]"` + Description string `json:"description"` +} + +func (p *ProjectNetworkPolicySpec) ObjClusterName() string { + if parts := strings.SplitN(p.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type ProjectNetworkPolicyStatus struct { +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ProjectNetworkPolicy struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec ProjectNetworkPolicySpec `json:"spec"` + Status *ProjectNetworkPolicyStatus `json:"status"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/notification_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/notification_types.go new file mode 100644 index 0000000..fc58f55 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/notification_types.go @@ -0,0 +1,18 @@ +package v3 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RancherUserNotification struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + + ComponentName string `json:"componentName"` + Message string `json:"message"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/pod_security_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/pod_security_types.go new file mode 100644 index 0000000..fae6d0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/pod_security_types.go @@ -0,0 +1,44 @@ +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type PodSecurityAdmissionConfigurationTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Description string `json:"description"` + Configuration PodSecurityAdmissionConfigurationTemplateSpec `json:"configuration"` +} + +type PodSecurityAdmissionConfigurationTemplateSpec struct { + Defaults PodSecurityAdmissionConfigurationTemplateDefaults `json:"defaults"` + Exemptions PodSecurityAdmissionConfigurationTemplateExemptions `json:"exemptions,omitempty"` +} + +// PodSecurityAdmissionConfigurationTemplateDefaults are applied when a mode label is not set. +// +// The level label values must be one of +// 'privileged' (default), 'baseline', or 'restricted' +// +// The version levels must be either 'latest' (default), or a specific version (e.g. 'v1.25') +type PodSecurityAdmissionConfigurationTemplateDefaults struct { + Enforce string `json:"enforce"` + EnforceVersion string `json:"enforce-version" yaml:"enforce-version"` + Audit string `json:"audit"` + AuditVersion string `json:"audit-version" yaml:"audit-version"` + Warn string `json:"warn"` + WarnVersion string `json:"warn-version" yaml:"warn-version"` +} + +type PodSecurityAdmissionConfigurationTemplateExemptions struct { + Usernames []string `json:"usernames"` + RuntimeClasses []string `json:"runtimeClasses"` + Namespaces []string `json:"namespaces"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/public_authn_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/public_authn_types.go new file mode 100644 index 0000000..6b402c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/public_authn_types.go @@ -0,0 +1,250 @@ +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AuthProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Type string `json:"type"` +} + +func (a *AuthProvider) GetType() string { + return a.Type +} + +// OAuthProvider contains the OAuth configuration of the AuthProvider +type OAuthProvider struct { + ClientID string `json:"clientId"` + Scopes []string `json:"scopes"` + OAuthEndpoint `json:",inline"` +} + +// OAuthEndpoint contains the endpoints needed for an oauth exchange. +// See also https://pkg.go.dev/golang.org/x/oauth2#Endpoint +type OAuthEndpoint struct { + AuthURL string `json:"authUrl,omitempty"` + DeviceAuthURL string `json:"deviceAuthUrl,omitempty"` + TokenURL string `json:"tokenUrl,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AuthToken struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Token string `json:"token"` + ExpiresAt string `json:"expiresAt"` +} + +type GenericLogin struct { + TTLMillis int64 `json:"ttl,omitempty"` + Description string `json:"description,omitempty" norman:"type=string,required"` + ResponseType string `json:"responseType,omitempty" norman:"type=string,required"` //json or cookie +} + +type BasicLogin struct { + GenericLogin `json:",inline"` + Username string `json:"username" norman:"type=string,required"` + Password string `json:"password" norman:"type=string,required"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type LocalProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GithubProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` +} + +type GithubLogin struct { + GenericLogin `json:",inline"` + Code string `json:"code" norman:"type=string,required"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GoogleOAuthProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` +} + +type GoogleOauthLogin struct { + GenericLogin `json:",inline"` + Code string `json:"code" norman:"type=string,required"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ActiveDirectoryProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + DefaultLoginDomain string `json:"defaultLoginDomain,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AzureADProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` + TenantID string `json:"tenantId,omitempty"` + + OAuthProvider `json:",inline"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type SamlProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` +} + +type AzureADLogin struct { + GenericLogin `json:",inline"` + Code string `json:"code" norman:"type=string,required"` + IDToken string `json:"id_token,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type OpenLdapProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type FreeIpaProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` +} + +type PingProvider struct { + SamlProvider `json:",inline"` +} + +type ShibbolethProvider struct { + SamlProvider `json:",inline"` +} + +type ADFSProvider struct { + SamlProvider `json:",inline"` +} + +type KeyCloakProvider struct { + SamlProvider `json:",inline"` +} + +type OKTAProvider struct { + SamlProvider `json:",inline"` +} + +type SamlLoginInput struct { + FinalRedirectURL string `json:"finalRedirectUrl"` + RequestID string `json:"requestId"` + PublicKey string `json:"publicKey"` + ResponseType string `json:"responseType"` +} + +type SamlLoginOutput struct { + IdpRedirectURL string `json:"idpRedirectUrl"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type OIDCProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` +} + +type OIDCLogin struct { + GenericLogin `json:",inline"` + Code string `json:"code" norman:"type=string,required"` +} + +type KeyCloakOIDCProvider struct { + OIDCProvider `json:",inline"` +} + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type GenericOIDCProvider struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + AuthProvider `json:",inline"` + + RedirectURL string `json:"redirectUrl"` + Scopes string `json:"scopes"` +} + +type GenericOIDCLogin struct { + GenericLogin `json:",inline"` + Code string `json:"code" norman:"type=string,required"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/resource_quota_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/resource_quota_types.go new file mode 100644 index 0000000..a72e015 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/resource_quota_types.go @@ -0,0 +1,97 @@ +package v3 + +// ProjectResourceQuota represents the allowed and allocated quotas for all namespaces in a project. +type ProjectResourceQuota struct { + // Limit is the total allowable quota limits shared by all namespaces in the project. + // +optional + Limit ResourceQuotaLimit `json:"limit,omitempty"` + + // UsedLimit is the currently allocated quota for all namespaces in the project. + // +optional + UsedLimit ResourceQuotaLimit `json:"usedLimit,omitempty"` +} + +// NamespaceResourceQuota represents the default quota limits for a namespace. +type NamespaceResourceQuota struct { + // Limit is the default quota limits applied to new namespaces. + // +optional + Limit ResourceQuotaLimit `json:"limit,omitempty"` +} + +// ResourceQuotaLimit holds quota values for different resources. +// These resources are a subset of Kubernetes resources that can be limited. +// See https://kubernetes.io/docs/concepts/policy/resource-quotas/ for more details. +type ResourceQuotaLimit struct { + // Pods is the total number of Pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if .status.phase in (Failed, Succeeded) is true. + // +optional + Pods string `json:"pods,omitempty"` + + // Services is the total number of Services that can exist in the namespace. + // +optional + Services string `json:"services,omitempty"` + + // ReplicationControllers is total number of ReplicationControllers that can exist in the namespace. + // +optional + ReplicationControllers string `json:"replicationControllers,omitempty"` + + // Secrets is the total number of ReplicationControllers that can exist in the namespace. + // +optional + Secrets string `json:"secrets,omitempty"` + + // ConfigMaps is the total number of ReplicationControllers that can exist in the namespace. + // +optional + ConfigMaps string `json:"configMaps,omitempty"` + + // PersistentVolumeClaims is the total number of PersistentVolumeClaims that can exist in the namespace. + // +optional + PersistentVolumeClaims string `json:"persistentVolumeClaims,omitempty"` + + // ServiceNodePorts is the total number of Services of type NodePort that can exist in the namespace. + // +optional + ServicesNodePorts string `json:"servicesNodePorts,omitempty"` + + // ServicesLoadBalancers is the total number of Services of type LoadBalancer that can exist in the namespace. + // +optional + ServicesLoadBalancers string `json:"servicesLoadBalancers,omitempty"` + + // RequestsCPU is the CPU requests limit across all pods in a non-terminal state. + // +optional + RequestsCPU string `json:"requestsCpu,omitempty"` + + // RequestsMemory is the memory requests limit across all pods in a non-terminal state. + // +optional + RequestsMemory string `json:"requestsMemory,omitempty"` + + // RequestsStorage is the storage requests limit across all persistent volume claims. + // +optional + RequestsStorage string `json:"requestsStorage,omitempty"` + + // LimitsCPU is the CPU limits across all pods in a non-terminal state. + // +optional + LimitsCPU string `json:"limitsCpu,omitempty"` + + // LimitsMemory is the memory limits across all pods in a non-terminal state. + // +optional + LimitsMemory string `json:"limitsMemory,omitempty"` +} + +// ContainerResourceLimit holds quotas limits for individual containers. +// These resources are a subset of Kubernetes resources that can be limited. +// See https://kubernetes.io/docs/concepts/policy/limit-range/ for more details. +type ContainerResourceLimit struct { + // RequestsCPU is the CPU requests limit across all pods in a non-terminal state. + // +optional + RequestsCPU string `json:"requestsCpu,omitempty"` + + // RequestsMemory is the memory requests limit across all pods in a non-terminal state. + // +optional + RequestsMemory string `json:"requestsMemory,omitempty"` + + // LimitsCPU is the CPU limits across all pods in a non-terminal state. + // +optional + LimitsCPU string `json:"limitsCpu,omitempty"` + + // LimitsMemory is the memory limits across all pods in a non-terminal state. + // +optional + LimitsMemory string `json:"limitsMemory,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/rke_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/rke_types.go new file mode 100644 index 0000000..837d093 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/rke_types.go @@ -0,0 +1,59 @@ +package v3 + +import ( + "github.com/rancher/norman/types" + rketypes "github.com/rancher/rke/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type EtcdBackup struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // backup spec + Spec rketypes.EtcdBackupSpec `json:"spec"` + // backup status + Status rketypes.EtcdBackupStatus `yaml:"status" json:"status,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RkeK8sSystemImage struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + SystemImages rketypes.RKESystemImages `yaml:"system_images" json:"systemImages,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RkeK8sServiceOption struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + ServiceOptions rketypes.KubernetesServicesOptions `yaml:"service_options" json:"serviceOptions,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RkeAddon struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Template string `yaml:"template" json:"template,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/schema_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/schema_types.go new file mode 100644 index 0000000..b796dc8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/schema_types.go @@ -0,0 +1,82 @@ +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type DynamicSchema struct { + metav1.TypeMeta `json:",inline"` + // Standard object’s metadata. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata,omitempty"` + // Specification of the desired behavior of the the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Spec DynamicSchemaSpec `json:"spec"` + // Most recent observed status of the cluster. More info: + // https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status + Status DynamicSchemaStatus `json:"status"` +} + +type DynamicSchemaSpec struct { + SchemaName string `json:"schemaName,omitempty"` + Embed bool `json:"embed,omitempty"` + EmbedType string `json:"embedType,omitempty"` + PluralName string `json:"pluralName,omitempty"` + ResourceMethods []string `json:"resourceMethods,omitempty"` + ResourceFields map[string]Field `json:"resourceFields,omitempty"` + ResourceActions map[string]Action `json:"resourceActions,omitempty"` + CollectionMethods []string `json:"collectionMethods,omitempty"` + CollectionFields map[string]Field `json:"collectionFields,omitempty"` + CollectionActions map[string]Action `json:"collectionActions,omitempty"` + CollectionFilters map[string]Filter `json:"collectionFilters,omitempty"` + IncludeableLinks []string `json:"includeableLinks,omitempty"` + DynamicSchemaVersion string `json:"dynamicSchemaVersion,omitempty"` +} + +type DynamicSchemaStatus struct { + Fake string `json:"fake,omitempty"` +} + +type Field struct { + Type string `json:"type,omitempty"` + Default Values `json:"default,omitempty"` + Unique bool `json:"unique,omitempty"` + Nullable bool `json:"nullable,omitempty"` + Create bool `json:"create,omitempty"` + Required bool `json:"required,omitempty"` + Update bool `json:"update,omitempty"` + MinLength int64 `json:"minLength,omitempty"` + MaxLength int64 `json:"maxLength,omitempty"` + Min int64 `json:"min,omitempty"` + Max int64 `json:"max,omitempty"` + Options []string `json:"options,omitempty"` + ValidChars string `json:"validChars,omitempty"` + InvalidChars string `json:"invalidChars,omitempty"` + Description string `json:"description,omitempty"` + DynamicField bool `json:"dynamicField,omitempty"` +} + +type Values struct { + StringValue string `json:"stringValue"` + IntValue int `json:"intValue"` + BoolValue bool `json:"boolValue"` + StringSliceValue []string `json:"stringSliceValue"` +} + +type Action struct { + Input string `json:"input,omitempty"` + Output string `json:"output,omitempty"` +} + +type Filter struct { + Modifiers []string `json:"modifiers,omitempty"` +} + +type ListOpts struct { + Filters map[string]string `json:"filters,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/tools_system_images.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/tools_system_images.go new file mode 100644 index 0000000..abee3ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/tools_system_images.go @@ -0,0 +1,11 @@ +package v3 + +var ( + ToolsSystemImages = struct { + AuthSystemImages AuthSystemImages + }{ + AuthSystemImages: AuthSystemImages{ + KubeAPIAuth: "rancher/kube-api-auth:v0.2.2", + }, + } +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/user_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/user_types.go new file mode 100644 index 0000000..8008c29 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/user_types.go @@ -0,0 +1,19 @@ +package v3 + +import ( + "github.com/rancher/norman/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Preference struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Value string `json:"value" norman:"required"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/windows_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/windows_types.go new file mode 100644 index 0000000..2ce5612 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/windows_types.go @@ -0,0 +1,16 @@ +package v3 + +type WindowsSystemImages struct { + // Windows nginx-proxy image + NginxProxy string `yaml:"nginx_proxy" json:"nginxProxy,omitempty"` + // Kubernetes binaries image + KubernetesBinaries string `yaml:"kubernetes_binaries" json:"kubernetesBinaries,omitempty"` + // Kubelet pause image + KubeletPause string `yaml:"kubelet_pause" json:"kubeletPause,omitempty"` + // Flannel CNI binaries image + FlannelCNIBinaries string `yaml:"flannel_cni_binaries" json:"flannelCniBinaries,omitempty"` + // Calico CNI binaries image + CalicoCNIBinaries string `yaml:"calico_cni_binaries" json:"calicoCniBinaries,omitempty"` + // Canal CNI binaries image + CanalCNIBinaries string `yaml:"canal_cni_binaries" json:"canalCniBinaries,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_deepcopy.go new file mode 100644 index 0000000..be7f539 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_deepcopy.go @@ -0,0 +1,8801 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + ekscattleiov1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + gkecattleiov1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + projectcattleiov3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + types "github.com/rancher/rke/types" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + version "k8s.io/apimachinery/pkg/version" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ADFSConfig) DeepCopyInto(out *ADFSConfig) { + *out = *in + in.SamlConfig.DeepCopyInto(&out.SamlConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ADFSConfig. +func (in *ADFSConfig) DeepCopy() *ADFSConfig { + if in == nil { + return nil + } + out := new(ADFSConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ADFSProvider) DeepCopyInto(out *ADFSProvider) { + *out = *in + in.SamlProvider.DeepCopyInto(&out.SamlProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ADFSProvider. +func (in *ADFSProvider) DeepCopy() *ADFSProvider { + if in == nil { + return nil + } + out := new(ADFSProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AKSStatus) DeepCopyInto(out *AKSStatus) { + *out = *in + if in.UpstreamSpec != nil { + in, out := &in.UpstreamSpec, &out.UpstreamSpec + *out = new(v1.AKSClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + if in.PrivateRequiresTunnel != nil { + in, out := &in.PrivateRequiresTunnel, &out.PrivateRequiresTunnel + *out = new(bool) + **out = **in + } + if in.RBACEnabled != nil { + in, out := &in.RBACEnabled, &out.RBACEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AKSStatus. +func (in *AKSStatus) DeepCopy() *AKSStatus { + if in == nil { + return nil + } + out := new(AKSStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIService) DeepCopyInto(out *APIService) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIService. +func (in *APIService) DeepCopy() *APIService { + if in == nil { + return nil + } + out := new(APIService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *APIService) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServiceList) DeepCopyInto(out *APIServiceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]APIService, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceList. +func (in *APIServiceList) DeepCopy() *APIServiceList { + if in == nil { + return nil + } + out := new(APIServiceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *APIServiceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServiceSpec) DeepCopyInto(out *APIServiceSpec) { + *out = *in + if in.PathPrefixes != nil { + in, out := &in.PathPrefixes, &out.PathPrefixes + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Paths != nil { + in, out := &in.Paths, &out.Paths + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceSpec. +func (in *APIServiceSpec) DeepCopy() *APIServiceSpec { + if in == nil { + return nil + } + out := new(APIServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServiceStatus) DeepCopyInto(out *APIServiceStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceStatus. +func (in *APIServiceStatus) DeepCopy() *APIServiceStatus { + if in == nil { + return nil + } + out := new(APIServiceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Action) DeepCopyInto(out *Action) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Action. +func (in *Action) DeepCopy() *Action { + if in == nil { + return nil + } + out := new(Action) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActiveDirectoryConfig) DeepCopyInto(out *ActiveDirectoryConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + if in.Servers != nil { + in, out := &in.Servers, &out.Servers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.NestedGroupMembershipEnabled != nil { + in, out := &in.NestedGroupMembershipEnabled, &out.NestedGroupMembershipEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveDirectoryConfig. +func (in *ActiveDirectoryConfig) DeepCopy() *ActiveDirectoryConfig { + if in == nil { + return nil + } + out := new(ActiveDirectoryConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ActiveDirectoryConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActiveDirectoryConfigList) DeepCopyInto(out *ActiveDirectoryConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ActiveDirectoryConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveDirectoryConfigList. +func (in *ActiveDirectoryConfigList) DeepCopy() *ActiveDirectoryConfigList { + if in == nil { + return nil + } + out := new(ActiveDirectoryConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ActiveDirectoryConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActiveDirectoryProvider) DeepCopyInto(out *ActiveDirectoryProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveDirectoryProvider. +func (in *ActiveDirectoryProvider) DeepCopy() *ActiveDirectoryProvider { + if in == nil { + return nil + } + out := new(ActiveDirectoryProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ActiveDirectoryProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActiveDirectoryProviderList) DeepCopyInto(out *ActiveDirectoryProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ActiveDirectoryProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveDirectoryProviderList. +func (in *ActiveDirectoryProviderList) DeepCopy() *ActiveDirectoryProviderList { + if in == nil { + return nil + } + out := new(ActiveDirectoryProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ActiveDirectoryProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActiveDirectoryTestAndApplyInput) DeepCopyInto(out *ActiveDirectoryTestAndApplyInput) { + *out = *in + in.ActiveDirectoryConfig.DeepCopyInto(&out.ActiveDirectoryConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveDirectoryTestAndApplyInput. +func (in *ActiveDirectoryTestAndApplyInput) DeepCopy() *ActiveDirectoryTestAndApplyInput { + if in == nil { + return nil + } + out := new(ActiveDirectoryTestAndApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AgentDeploymentCustomization) DeepCopyInto(out *AgentDeploymentCustomization) { + *out = *in + if in.AppendTolerations != nil { + in, out := &in.AppendTolerations, &out.AppendTolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OverrideAffinity != nil { + in, out := &in.OverrideAffinity, &out.OverrideAffinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.OverrideResourceRequirements != nil { + in, out := &in.OverrideResourceRequirements, &out.OverrideResourceRequirements + *out = new(corev1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentDeploymentCustomization. +func (in *AgentDeploymentCustomization) DeepCopy() *AgentDeploymentCustomization { + if in == nil { + return nil + } + out := new(AgentDeploymentCustomization) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AlidnsProviderConfig) DeepCopyInto(out *AlidnsProviderConfig) { + *out = *in + if in.AdditionalOptions != nil { + in, out := &in.AdditionalOptions, &out.AdditionalOptions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlidnsProviderConfig. +func (in *AlidnsProviderConfig) DeepCopy() *AlidnsProviderConfig { + if in == nil { + return nil + } + out := new(AlidnsProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Answer) DeepCopyInto(out *Answer) { + *out = *in + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ValuesSetString != nil { + in, out := &in.ValuesSetString, &out.ValuesSetString + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Answer. +func (in *Answer) DeepCopy() *Answer { + if in == nil { + return nil + } + out := new(Answer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfig) DeepCopyInto(out *AuthConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.AllowedPrincipalIDs != nil { + in, out := &in.AllowedPrincipalIDs, &out.AllowedPrincipalIDs + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfig. +func (in *AuthConfig) DeepCopy() *AuthConfig { + if in == nil { + return nil + } + out := new(AuthConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfigConditions) DeepCopyInto(out *AuthConfigConditions) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfigConditions. +func (in *AuthConfigConditions) DeepCopy() *AuthConfigConditions { + if in == nil { + return nil + } + out := new(AuthConfigConditions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfigList) DeepCopyInto(out *AuthConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AuthConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfigList. +func (in *AuthConfigList) DeepCopy() *AuthConfigList { + if in == nil { + return nil + } + out := new(AuthConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfigStatus) DeepCopyInto(out *AuthConfigStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]AuthConfigConditions, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfigStatus. +func (in *AuthConfigStatus) DeepCopy() *AuthConfigStatus { + if in == nil { + return nil + } + out := new(AuthConfigStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthProvider) DeepCopyInto(out *AuthProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthProvider. +func (in *AuthProvider) DeepCopy() *AuthProvider { + if in == nil { + return nil + } + out := new(AuthProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthProviderList) DeepCopyInto(out *AuthProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AuthProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthProviderList. +func (in *AuthProviderList) DeepCopy() *AuthProviderList { + if in == nil { + return nil + } + out := new(AuthProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthSystemImages) DeepCopyInto(out *AuthSystemImages) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthSystemImages. +func (in *AuthSystemImages) DeepCopy() *AuthSystemImages { + if in == nil { + return nil + } + out := new(AuthSystemImages) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthToken) DeepCopyInto(out *AuthToken) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthToken. +func (in *AuthToken) DeepCopy() *AuthToken { + if in == nil { + return nil + } + out := new(AuthToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthTokenList) DeepCopyInto(out *AuthTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AuthToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthTokenList. +func (in *AuthTokenList) DeepCopy() *AuthTokenList { + if in == nil { + return nil + } + out := new(AuthTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADConfig) DeepCopyInto(out *AzureADConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADConfig. +func (in *AzureADConfig) DeepCopy() *AzureADConfig { + if in == nil { + return nil + } + out := new(AzureADConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AzureADConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADConfigApplyInput) DeepCopyInto(out *AzureADConfigApplyInput) { + *out = *in + in.Config.DeepCopyInto(&out.Config) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADConfigApplyInput. +func (in *AzureADConfigApplyInput) DeepCopy() *AzureADConfigApplyInput { + if in == nil { + return nil + } + out := new(AzureADConfigApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADConfigTestOutput) DeepCopyInto(out *AzureADConfigTestOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADConfigTestOutput. +func (in *AzureADConfigTestOutput) DeepCopy() *AzureADConfigTestOutput { + if in == nil { + return nil + } + out := new(AzureADConfigTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADLogin) DeepCopyInto(out *AzureADLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADLogin. +func (in *AzureADLogin) DeepCopy() *AzureADLogin { + if in == nil { + return nil + } + out := new(AzureADLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADProvider) DeepCopyInto(out *AzureADProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + in.OAuthProvider.DeepCopyInto(&out.OAuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADProvider. +func (in *AzureADProvider) DeepCopy() *AzureADProvider { + if in == nil { + return nil + } + out := new(AzureADProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AzureADProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureADProviderList) DeepCopyInto(out *AzureADProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AzureADProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureADProviderList. +func (in *AzureADProviderList) DeepCopy() *AzureADProviderList { + if in == nil { + return nil + } + out := new(AzureADProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AzureADProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BasicLogin) DeepCopyInto(out *BasicLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicLogin. +func (in *BasicLogin) DeepCopy() *BasicLogin { + if in == nil { + return nil + } + out := new(BasicLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Capabilities) DeepCopyInto(out *Capabilities) { + *out = *in + in.LoadBalancerCapabilities.DeepCopyInto(&out.LoadBalancerCapabilities) + if in.IngressCapabilities != nil { + in, out := &in.IngressCapabilities, &out.IngressCapabilities + *out = make([]IngressCapabilities, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.TaintSupport != nil { + in, out := &in.TaintSupport, &out.TaintSupport + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capabilities. +func (in *Capabilities) DeepCopy() *Capabilities { + if in == nil { + return nil + } + out := new(Capabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Catalog) DeepCopyInto(out *Catalog) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Catalog. +func (in *Catalog) DeepCopy() *Catalog { + if in == nil { + return nil + } + out := new(Catalog) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Catalog) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogCondition) DeepCopyInto(out *CatalogCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogCondition. +func (in *CatalogCondition) DeepCopy() *CatalogCondition { + if in == nil { + return nil + } + out := new(CatalogCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogList) DeepCopyInto(out *CatalogList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Catalog, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogList. +func (in *CatalogList) DeepCopy() *CatalogList { + if in == nil { + return nil + } + out := new(CatalogList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CatalogList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogRefresh) DeepCopyInto(out *CatalogRefresh) { + *out = *in + if in.Catalogs != nil { + in, out := &in.Catalogs, &out.Catalogs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogRefresh. +func (in *CatalogRefresh) DeepCopy() *CatalogRefresh { + if in == nil { + return nil + } + out := new(CatalogRefresh) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogSecrets) DeepCopyInto(out *CatalogSecrets) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogSecrets. +func (in *CatalogSecrets) DeepCopy() *CatalogSecrets { + if in == nil { + return nil + } + out := new(CatalogSecrets) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogSpec) DeepCopyInto(out *CatalogSpec) { + *out = *in + out.CatalogSecrets = in.CatalogSecrets + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogSpec. +func (in *CatalogSpec) DeepCopy() *CatalogSpec { + if in == nil { + return nil + } + out := new(CatalogSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogStatus) DeepCopyInto(out *CatalogStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]CatalogCondition, len(*in)) + copy(*out, *in) + } + if in.HelmVersionCommits != nil { + in, out := &in.HelmVersionCommits, &out.HelmVersionCommits + *out = make(map[string]VersionCommits, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogStatus. +func (in *CatalogStatus) DeepCopy() *CatalogStatus { + if in == nil { + return nil + } + out := new(CatalogStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogTemplate) DeepCopyInto(out *CatalogTemplate) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogTemplate. +func (in *CatalogTemplate) DeepCopy() *CatalogTemplate { + if in == nil { + return nil + } + out := new(CatalogTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CatalogTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogTemplateList) DeepCopyInto(out *CatalogTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CatalogTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogTemplateList. +func (in *CatalogTemplateList) DeepCopy() *CatalogTemplateList { + if in == nil { + return nil + } + out := new(CatalogTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CatalogTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogTemplateVersion) DeepCopyInto(out *CatalogTemplateVersion) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogTemplateVersion. +func (in *CatalogTemplateVersion) DeepCopy() *CatalogTemplateVersion { + if in == nil { + return nil + } + out := new(CatalogTemplateVersion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CatalogTemplateVersion) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CatalogTemplateVersionList) DeepCopyInto(out *CatalogTemplateVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CatalogTemplateVersion, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CatalogTemplateVersionList. +func (in *CatalogTemplateVersionList) DeepCopy() *CatalogTemplateVersionList { + if in == nil { + return nil + } + out := new(CatalogTemplateVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CatalogTemplateVersionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CertExpiration) DeepCopyInto(out *CertExpiration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertExpiration. +func (in *CertExpiration) DeepCopy() *CertExpiration { + if in == nil { + return nil + } + out := new(CertExpiration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChangePasswordInput) DeepCopyInto(out *ChangePasswordInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChangePasswordInput. +func (in *ChangePasswordInput) DeepCopy() *ChangePasswordInput { + if in == nil { + return nil + } + out := new(ChangePasswordInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredential) DeepCopyInto(out *CloudCredential) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredential. +func (in *CloudCredential) DeepCopy() *CloudCredential { + if in == nil { + return nil + } + out := new(CloudCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudCredential) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredentialList) DeepCopyInto(out *CloudCredentialList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CloudCredential, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredentialList. +func (in *CloudCredentialList) DeepCopy() *CloudCredentialList { + if in == nil { + return nil + } + out := new(CloudCredentialList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CloudCredentialList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudCredentialSpec) DeepCopyInto(out *CloudCredentialSpec) { + *out = *in + if in.S3CredentialConfig != nil { + in, out := &in.S3CredentialConfig, &out.S3CredentialConfig + *out = new(S3CredentialConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudCredentialSpec. +func (in *CloudCredentialSpec) DeepCopy() *CloudCredentialSpec { + if in == nil { + return nil + } + out := new(CloudCredentialSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CloudflareProviderConfig) DeepCopyInto(out *CloudflareProviderConfig) { + *out = *in + if in.ProxySetting != nil { + in, out := &in.ProxySetting, &out.ProxySetting + *out = new(bool) + **out = **in + } + if in.AdditionalOptions != nil { + in, out := &in.AdditionalOptions, &out.AdditionalOptions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudflareProviderConfig. +func (in *CloudflareProviderConfig) DeepCopy() *CloudflareProviderConfig { + if in == nil { + return nil + } + out := new(CloudflareProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cluster) DeepCopyInto(out *Cluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. +func (in *Cluster) DeepCopy() *Cluster { + if in == nil { + return nil + } + out := new(Cluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCatalog) DeepCopyInto(out *ClusterCatalog) { + *out = *in + out.Namespaced = in.Namespaced + in.Catalog.DeepCopyInto(&out.Catalog) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCatalog. +func (in *ClusterCatalog) DeepCopy() *ClusterCatalog { + if in == nil { + return nil + } + out := new(ClusterCatalog) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCatalog) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCatalogList) DeepCopyInto(out *ClusterCatalogList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterCatalog, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCatalogList. +func (in *ClusterCatalogList) DeepCopy() *ClusterCatalogList { + if in == nil { + return nil + } + out := new(ClusterCatalogList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCatalogList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterComponentStatus) DeepCopyInto(out *ClusterComponentStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]corev1.ComponentCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterComponentStatus. +func (in *ClusterComponentStatus) DeepCopy() *ClusterComponentStatus { + if in == nil { + return nil + } + out := new(ClusterComponentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCondition) DeepCopyInto(out *ClusterCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCondition. +func (in *ClusterCondition) DeepCopy() *ClusterCondition { + if in == nil { + return nil + } + out := new(ClusterCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterList) DeepCopyInto(out *ClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. +func (in *ClusterList) DeepCopy() *ClusterList { + if in == nil { + return nil + } + out := new(ClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterLogging) DeepCopyInto(out *ClusterLogging) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterLogging. +func (in *ClusterLogging) DeepCopy() *ClusterLogging { + if in == nil { + return nil + } + out := new(ClusterLogging) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterLogging) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterLoggingList) DeepCopyInto(out *ClusterLoggingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterLogging, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterLoggingList. +func (in *ClusterLoggingList) DeepCopy() *ClusterLoggingList { + if in == nil { + return nil + } + out := new(ClusterLoggingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterLoggingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterLoggingSpec) DeepCopyInto(out *ClusterLoggingSpec) { + *out = *in + in.LoggingTargets.DeepCopyInto(&out.LoggingTargets) + in.LoggingCommonField.DeepCopyInto(&out.LoggingCommonField) + if in.IncludeSystemComponent != nil { + in, out := &in.IncludeSystemComponent, &out.IncludeSystemComponent + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterLoggingSpec. +func (in *ClusterLoggingSpec) DeepCopy() *ClusterLoggingSpec { + if in == nil { + return nil + } + out := new(ClusterLoggingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterLoggingStatus) DeepCopyInto(out *ClusterLoggingStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]LoggingCondition, len(*in)) + copy(*out, *in) + } + in.AppliedSpec.DeepCopyInto(&out.AppliedSpec) + if in.FailedSpec != nil { + in, out := &in.FailedSpec, &out.FailedSpec + *out = new(ClusterLoggingSpec) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterLoggingStatus. +func (in *ClusterLoggingStatus) DeepCopy() *ClusterLoggingStatus { + if in == nil { + return nil + } + out := new(ClusterLoggingStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterProxyConfig) DeepCopyInto(out *ClusterProxyConfig) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProxyConfig. +func (in *ClusterProxyConfig) DeepCopy() *ClusterProxyConfig { + if in == nil { + return nil + } + out := new(ClusterProxyConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterProxyConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterProxyConfigList) DeepCopyInto(out *ClusterProxyConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterProxyConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProxyConfigList. +func (in *ClusterProxyConfigList) DeepCopy() *ClusterProxyConfigList { + if in == nil { + return nil + } + out := new(ClusterProxyConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterProxyConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRegistrationToken) DeepCopyInto(out *ClusterRegistrationToken) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRegistrationToken. +func (in *ClusterRegistrationToken) DeepCopy() *ClusterRegistrationToken { + if in == nil { + return nil + } + out := new(ClusterRegistrationToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRegistrationToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRegistrationTokenList) DeepCopyInto(out *ClusterRegistrationTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterRegistrationToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRegistrationTokenList. +func (in *ClusterRegistrationTokenList) DeepCopy() *ClusterRegistrationTokenList { + if in == nil { + return nil + } + out := new(ClusterRegistrationTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRegistrationTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRegistrationTokenSpec) DeepCopyInto(out *ClusterRegistrationTokenSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRegistrationTokenSpec. +func (in *ClusterRegistrationTokenSpec) DeepCopy() *ClusterRegistrationTokenSpec { + if in == nil { + return nil + } + out := new(ClusterRegistrationTokenSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRegistrationTokenStatus) DeepCopyInto(out *ClusterRegistrationTokenStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRegistrationTokenStatus. +func (in *ClusterRegistrationTokenStatus) DeepCopy() *ClusterRegistrationTokenStatus { + if in == nil { + return nil + } + out := new(ClusterRegistrationTokenStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRoleTemplateBinding) DeepCopyInto(out *ClusterRoleTemplateBinding) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleTemplateBinding. +func (in *ClusterRoleTemplateBinding) DeepCopy() *ClusterRoleTemplateBinding { + if in == nil { + return nil + } + out := new(ClusterRoleTemplateBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRoleTemplateBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRoleTemplateBindingList) DeepCopyInto(out *ClusterRoleTemplateBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterRoleTemplateBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleTemplateBindingList. +func (in *ClusterRoleTemplateBindingList) DeepCopy() *ClusterRoleTemplateBindingList { + if in == nil { + return nil + } + out := new(ClusterRoleTemplateBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterRoleTemplateBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSecrets) DeepCopyInto(out *ClusterSecrets) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSecrets. +func (in *ClusterSecrets) DeepCopy() *ClusterSecrets { + if in == nil { + return nil + } + out := new(ClusterSecrets) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in + in.ClusterSpecBase.DeepCopyInto(&out.ClusterSpecBase) + if in.K3sConfig != nil { + in, out := &in.K3sConfig, &out.K3sConfig + *out = new(K3sConfig) + **out = **in + } + if in.Rke2Config != nil { + in, out := &in.Rke2Config, &out.Rke2Config + *out = new(Rke2Config) + **out = **in + } + if in.ImportedConfig != nil { + in, out := &in.ImportedConfig, &out.ImportedConfig + *out = new(ImportedConfig) + **out = **in + } + if in.GoogleKubernetesEngineConfig != nil { + in, out := &in.GoogleKubernetesEngineConfig, &out.GoogleKubernetesEngineConfig + *out = (*in).DeepCopy() + } + if in.AzureKubernetesServiceConfig != nil { + in, out := &in.AzureKubernetesServiceConfig, &out.AzureKubernetesServiceConfig + *out = (*in).DeepCopy() + } + if in.AmazonElasticContainerServiceConfig != nil { + in, out := &in.AmazonElasticContainerServiceConfig, &out.AmazonElasticContainerServiceConfig + *out = (*in).DeepCopy() + } + if in.GenericEngineConfig != nil { + in, out := &in.GenericEngineConfig, &out.GenericEngineConfig + *out = (*in).DeepCopy() + } + if in.AKSConfig != nil { + in, out := &in.AKSConfig, &out.AKSConfig + *out = new(v1.AKSClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + if in.EKSConfig != nil { + in, out := &in.EKSConfig, &out.EKSConfig + *out = new(ekscattleiov1.EKSClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + if in.GKEConfig != nil { + in, out := &in.GKEConfig, &out.GKEConfig + *out = new(gkecattleiov1.GKEClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + in.ClusterTemplateAnswers.DeepCopyInto(&out.ClusterTemplateAnswers) + if in.ClusterTemplateQuestions != nil { + in, out := &in.ClusterTemplateQuestions, &out.ClusterTemplateQuestions + *out = make([]Question, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpecBase) DeepCopyInto(out *ClusterSpecBase) { + *out = *in + if in.AgentEnvVars != nil { + in, out := &in.AgentEnvVars, &out.AgentEnvVars + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.RancherKubernetesEngineConfig != nil { + in, out := &in.RancherKubernetesEngineConfig, &out.RancherKubernetesEngineConfig + *out = new(types.RancherKubernetesEngineConfig) + (*in).DeepCopyInto(*out) + } + if in.EnableNetworkPolicy != nil { + in, out := &in.EnableNetworkPolicy, &out.EnableNetworkPolicy + *out = new(bool) + **out = **in + } + out.LocalClusterAuthEndpoint = in.LocalClusterAuthEndpoint + out.ClusterSecrets = in.ClusterSecrets + if in.ClusterAgentDeploymentCustomization != nil { + in, out := &in.ClusterAgentDeploymentCustomization, &out.ClusterAgentDeploymentCustomization + *out = new(AgentDeploymentCustomization) + (*in).DeepCopyInto(*out) + } + if in.FleetAgentDeploymentCustomization != nil { + in, out := &in.FleetAgentDeploymentCustomization, &out.FleetAgentDeploymentCustomization + *out = new(AgentDeploymentCustomization) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpecBase. +func (in *ClusterSpecBase) DeepCopy() *ClusterSpecBase { + if in == nil { + return nil + } + out := new(ClusterSpecBase) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ClusterCondition, len(*in)) + copy(*out, *in) + } + if in.AppliedAgentEnvVars != nil { + in, out := &in.AppliedAgentEnvVars, &out.AppliedAgentEnvVars + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.AgentFeatures != nil { + in, out := &in.AgentFeatures, &out.AgentFeatures + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ComponentStatuses != nil { + in, out := &in.ComponentStatuses, &out.ComponentStatuses + *out = make([]ClusterComponentStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Capacity != nil { + in, out := &in.Capacity, &out.Capacity + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Allocatable != nil { + in, out := &in.Allocatable, &out.Allocatable + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + in.AppliedSpec.DeepCopyInto(&out.AppliedSpec) + if in.FailedSpec != nil { + in, out := &in.FailedSpec, &out.FailedSpec + *out = new(ClusterSpec) + (*in).DeepCopyInto(*out) + } + if in.Requested != nil { + in, out := &in.Requested, &out.Requested + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Limits != nil { + in, out := &in.Limits, &out.Limits + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Version != nil { + in, out := &in.Version, &out.Version + *out = new(version.Info) + **out = **in + } + in.Capabilities.DeepCopyInto(&out.Capabilities) + if in.CertificatesExpiration != nil { + in, out := &in.CertificatesExpiration, &out.CertificatesExpiration + *out = make(map[string]CertExpiration, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.AKSStatus.DeepCopyInto(&out.AKSStatus) + in.EKSStatus.DeepCopyInto(&out.EKSStatus) + in.GKEStatus.DeepCopyInto(&out.GKEStatus) + if in.AppliedClusterAgentDeploymentCustomization != nil { + in, out := &in.AppliedClusterAgentDeploymentCustomization, &out.AppliedClusterAgentDeploymentCustomization + *out = new(AgentDeploymentCustomization) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplate) DeepCopyInto(out *ClusterTemplate) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplate. +func (in *ClusterTemplate) DeepCopy() *ClusterTemplate { + if in == nil { + return nil + } + out := new(ClusterTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateList) DeepCopyInto(out *ClusterTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateList. +func (in *ClusterTemplateList) DeepCopy() *ClusterTemplateList { + if in == nil { + return nil + } + out := new(ClusterTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateQuestionsOutput) DeepCopyInto(out *ClusterTemplateQuestionsOutput) { + *out = *in + if in.Questions != nil { + in, out := &in.Questions, &out.Questions + *out = make([]Question, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateQuestionsOutput. +func (in *ClusterTemplateQuestionsOutput) DeepCopy() *ClusterTemplateQuestionsOutput { + if in == nil { + return nil + } + out := new(ClusterTemplateQuestionsOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateRevision) DeepCopyInto(out *ClusterTemplateRevision) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateRevision. +func (in *ClusterTemplateRevision) DeepCopy() *ClusterTemplateRevision { + if in == nil { + return nil + } + out := new(ClusterTemplateRevision) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTemplateRevision) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateRevisionCondition) DeepCopyInto(out *ClusterTemplateRevisionCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateRevisionCondition. +func (in *ClusterTemplateRevisionCondition) DeepCopy() *ClusterTemplateRevisionCondition { + if in == nil { + return nil + } + out := new(ClusterTemplateRevisionCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateRevisionList) DeepCopyInto(out *ClusterTemplateRevisionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterTemplateRevision, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateRevisionList. +func (in *ClusterTemplateRevisionList) DeepCopy() *ClusterTemplateRevisionList { + if in == nil { + return nil + } + out := new(ClusterTemplateRevisionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTemplateRevisionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateRevisionSpec) DeepCopyInto(out *ClusterTemplateRevisionSpec) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Questions != nil { + in, out := &in.Questions, &out.Questions + *out = make([]Question, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ClusterConfig != nil { + in, out := &in.ClusterConfig, &out.ClusterConfig + *out = new(ClusterSpecBase) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateRevisionSpec. +func (in *ClusterTemplateRevisionSpec) DeepCopy() *ClusterTemplateRevisionSpec { + if in == nil { + return nil + } + out := new(ClusterTemplateRevisionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateRevisionStatus) DeepCopyInto(out *ClusterTemplateRevisionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ClusterTemplateRevisionCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateRevisionStatus. +func (in *ClusterTemplateRevisionStatus) DeepCopy() *ClusterTemplateRevisionStatus { + if in == nil { + return nil + } + out := new(ClusterTemplateRevisionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTemplateSpec) DeepCopyInto(out *ClusterTemplateSpec) { + *out = *in + if in.Members != nil { + in, out := &in.Members, &out.Members + *out = make([]Member, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTemplateSpec. +func (in *ClusterTemplateSpec) DeepCopy() *ClusterTemplateSpec { + if in == nil { + return nil + } + out := new(ClusterTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTestInput) DeepCopyInto(out *ClusterTestInput) { + *out = *in + in.LoggingTargets.DeepCopyInto(&out.LoggingTargets) + if in.OutputTags != nil { + in, out := &in.OutputTags, &out.OutputTags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTestInput. +func (in *ClusterTestInput) DeepCopy() *ClusterTestInput { + if in == nil { + return nil + } + out := new(ClusterTestInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterUpgradeStrategy) DeepCopyInto(out *ClusterUpgradeStrategy) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterUpgradeStrategy. +func (in *ClusterUpgradeStrategy) DeepCopy() *ClusterUpgradeStrategy { + if in == nil { + return nil + } + out := new(ClusterUpgradeStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComposeCondition) DeepCopyInto(out *ComposeCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposeCondition. +func (in *ComposeCondition) DeepCopy() *ComposeCondition { + if in == nil { + return nil + } + out := new(ComposeCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComposeConfig) DeepCopyInto(out *ComposeConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposeConfig. +func (in *ComposeConfig) DeepCopy() *ComposeConfig { + if in == nil { + return nil + } + out := new(ComposeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComposeConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComposeConfigList) DeepCopyInto(out *ComposeConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ComposeConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposeConfigList. +func (in *ComposeConfigList) DeepCopy() *ComposeConfigList { + if in == nil { + return nil + } + out := new(ComposeConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ComposeConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComposeSpec) DeepCopyInto(out *ComposeSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposeSpec. +func (in *ComposeSpec) DeepCopy() *ComposeSpec { + if in == nil { + return nil + } + out := new(ComposeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComposeStatus) DeepCopyInto(out *ComposeStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ComposeCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposeStatus. +func (in *ComposeStatus) DeepCopy() *ComposeStatus { + if in == nil { + return nil + } + out := new(ComposeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ContainerResourceLimit) DeepCopyInto(out *ContainerResourceLimit) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerResourceLimit. +func (in *ContainerResourceLimit) DeepCopy() *ContainerResourceLimit { + if in == nil { + return nil + } + out := new(ContainerResourceLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomConfig) DeepCopyInto(out *CustomConfig) { + *out = *in + if in.Label != nil { + in, out := &in.Label, &out.Label + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Taints != nil { + in, out := &in.Taints, &out.Taints + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomConfig. +func (in *CustomConfig) DeepCopy() *CustomConfig { + if in == nil { + return nil + } + out := new(CustomConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomTargetConfig) DeepCopyInto(out *CustomTargetConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomTargetConfig. +func (in *CustomTargetConfig) DeepCopy() *CustomTargetConfig { + if in == nil { + return nil + } + out := new(CustomTargetConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerInfo) DeepCopyInto(out *DockerInfo) { + *out = *in + if in.SecurityOptions != nil { + in, out := &in.SecurityOptions, &out.SecurityOptions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerInfo. +func (in *DockerInfo) DeepCopy() *DockerInfo { + if in == nil { + return nil + } + out := new(DockerInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DynamicSchema) DeepCopyInto(out *DynamicSchema) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicSchema. +func (in *DynamicSchema) DeepCopy() *DynamicSchema { + if in == nil { + return nil + } + out := new(DynamicSchema) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DynamicSchema) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DynamicSchemaList) DeepCopyInto(out *DynamicSchemaList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DynamicSchema, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicSchemaList. +func (in *DynamicSchemaList) DeepCopy() *DynamicSchemaList { + if in == nil { + return nil + } + out := new(DynamicSchemaList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DynamicSchemaList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DynamicSchemaSpec) DeepCopyInto(out *DynamicSchemaSpec) { + *out = *in + if in.ResourceMethods != nil { + in, out := &in.ResourceMethods, &out.ResourceMethods + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ResourceFields != nil { + in, out := &in.ResourceFields, &out.ResourceFields + *out = make(map[string]Field, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.ResourceActions != nil { + in, out := &in.ResourceActions, &out.ResourceActions + *out = make(map[string]Action, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CollectionMethods != nil { + in, out := &in.CollectionMethods, &out.CollectionMethods + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.CollectionFields != nil { + in, out := &in.CollectionFields, &out.CollectionFields + *out = make(map[string]Field, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.CollectionActions != nil { + in, out := &in.CollectionActions, &out.CollectionActions + *out = make(map[string]Action, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CollectionFilters != nil { + in, out := &in.CollectionFilters, &out.CollectionFilters + *out = make(map[string]Filter, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.IncludeableLinks != nil { + in, out := &in.IncludeableLinks, &out.IncludeableLinks + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicSchemaSpec. +func (in *DynamicSchemaSpec) DeepCopy() *DynamicSchemaSpec { + if in == nil { + return nil + } + out := new(DynamicSchemaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DynamicSchemaStatus) DeepCopyInto(out *DynamicSchemaStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicSchemaStatus. +func (in *DynamicSchemaStatus) DeepCopy() *DynamicSchemaStatus { + if in == nil { + return nil + } + out := new(DynamicSchemaStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EKSStatus) DeepCopyInto(out *EKSStatus) { + *out = *in + if in.UpstreamSpec != nil { + in, out := &in.UpstreamSpec, &out.UpstreamSpec + *out = new(ekscattleiov1.EKSClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + if in.Subnets != nil { + in, out := &in.Subnets, &out.Subnets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SecurityGroups != nil { + in, out := &in.SecurityGroups, &out.SecurityGroups + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PrivateRequiresTunnel != nil { + in, out := &in.PrivateRequiresTunnel, &out.PrivateRequiresTunnel + *out = new(bool) + **out = **in + } + if in.ManagedLaunchTemplateVersions != nil { + in, out := &in.ManagedLaunchTemplateVersions, &out.ManagedLaunchTemplateVersions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EKSStatus. +func (in *EKSStatus) DeepCopy() *EKSStatus { + if in == nil { + return nil + } + out := new(EKSStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ElasticsearchConfig) DeepCopyInto(out *ElasticsearchConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ElasticsearchConfig. +func (in *ElasticsearchConfig) DeepCopy() *ElasticsearchConfig { + if in == nil { + return nil + } + out := new(ElasticsearchConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EtcdBackup) DeepCopyInto(out *EtcdBackup) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdBackup. +func (in *EtcdBackup) DeepCopy() *EtcdBackup { + if in == nil { + return nil + } + out := new(EtcdBackup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EtcdBackup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EtcdBackupList) DeepCopyInto(out *EtcdBackupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]EtcdBackup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EtcdBackupList. +func (in *EtcdBackupList) DeepCopy() *EtcdBackupList { + if in == nil { + return nil + } + out := new(EtcdBackupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EtcdBackupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExportOutput) DeepCopyInto(out *ExportOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportOutput. +func (in *ExportOutput) DeepCopy() *ExportOutput { + if in == nil { + return nil + } + out := new(ExportOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Feature) DeepCopyInto(out *Feature) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Feature. +func (in *Feature) DeepCopy() *Feature { + if in == nil { + return nil + } + out := new(Feature) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Feature) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FeatureList) DeepCopyInto(out *FeatureList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Feature, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureList. +func (in *FeatureList) DeepCopy() *FeatureList { + if in == nil { + return nil + } + out := new(FeatureList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FeatureList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FeatureSpec) DeepCopyInto(out *FeatureSpec) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureSpec. +func (in *FeatureSpec) DeepCopy() *FeatureSpec { + if in == nil { + return nil + } + out := new(FeatureSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FeatureStatus) DeepCopyInto(out *FeatureStatus) { + *out = *in + if in.LockedValue != nil { + in, out := &in.LockedValue, &out.LockedValue + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureStatus. +func (in *FeatureStatus) DeepCopy() *FeatureStatus { + if in == nil { + return nil + } + out := new(FeatureStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Field) DeepCopyInto(out *Field) { + *out = *in + in.Default.DeepCopyInto(&out.Default) + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Field. +func (in *Field) DeepCopy() *Field { + if in == nil { + return nil + } + out := new(Field) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *File) DeepCopyInto(out *File) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new File. +func (in *File) DeepCopy() *File { + if in == nil { + return nil + } + out := new(File) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Filter) DeepCopyInto(out *Filter) { + *out = *in + if in.Modifiers != nil { + in, out := &in.Modifiers, &out.Modifiers + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filter. +func (in *Filter) DeepCopy() *Filter { + if in == nil { + return nil + } + out := new(Filter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FleetWorkspace) DeepCopyInto(out *FleetWorkspace) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetWorkspace. +func (in *FleetWorkspace) DeepCopy() *FleetWorkspace { + if in == nil { + return nil + } + out := new(FleetWorkspace) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FleetWorkspace) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FleetWorkspaceList) DeepCopyInto(out *FleetWorkspaceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FleetWorkspace, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetWorkspaceList. +func (in *FleetWorkspaceList) DeepCopy() *FleetWorkspaceList { + if in == nil { + return nil + } + out := new(FleetWorkspaceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FleetWorkspaceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FleetWorkspacePermission) DeepCopyInto(out *FleetWorkspacePermission) { + *out = *in + if in.ResourceRules != nil { + in, out := &in.ResourceRules, &out.ResourceRules + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.WorkspaceVerbs != nil { + in, out := &in.WorkspaceVerbs, &out.WorkspaceVerbs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetWorkspacePermission. +func (in *FleetWorkspacePermission) DeepCopy() *FleetWorkspacePermission { + if in == nil { + return nil + } + out := new(FleetWorkspacePermission) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FleetWorkspaceStatus) DeepCopyInto(out *FleetWorkspaceStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetWorkspaceStatus. +func (in *FleetWorkspaceStatus) DeepCopy() *FleetWorkspaceStatus { + if in == nil { + return nil + } + out := new(FleetWorkspaceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FluentForwarderConfig) DeepCopyInto(out *FluentForwarderConfig) { + *out = *in + if in.Compress != nil { + in, out := &in.Compress, &out.Compress + *out = new(bool) + **out = **in + } + if in.FluentServers != nil { + in, out := &in.FluentServers, &out.FluentServers + *out = make([]FluentServer, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluentForwarderConfig. +func (in *FluentForwarderConfig) DeepCopy() *FluentForwarderConfig { + if in == nil { + return nil + } + out := new(FluentForwarderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FluentServer) DeepCopyInto(out *FluentServer) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FluentServer. +func (in *FluentServer) DeepCopy() *FluentServer { + if in == nil { + return nil + } + out := new(FluentServer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FreeIpaConfig) DeepCopyInto(out *FreeIpaConfig) { + *out = *in + in.LdapConfig.DeepCopyInto(&out.LdapConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FreeIpaConfig. +func (in *FreeIpaConfig) DeepCopy() *FreeIpaConfig { + if in == nil { + return nil + } + out := new(FreeIpaConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FreeIpaProvider) DeepCopyInto(out *FreeIpaProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FreeIpaProvider. +func (in *FreeIpaProvider) DeepCopy() *FreeIpaProvider { + if in == nil { + return nil + } + out := new(FreeIpaProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FreeIpaProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FreeIpaProviderList) DeepCopyInto(out *FreeIpaProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FreeIpaProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FreeIpaProviderList. +func (in *FreeIpaProviderList) DeepCopy() *FreeIpaProviderList { + if in == nil { + return nil + } + out := new(FreeIpaProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FreeIpaProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FreeIpaTestAndApplyInput) DeepCopyInto(out *FreeIpaTestAndApplyInput) { + *out = *in + in.LdapTestAndApplyInput.DeepCopyInto(&out.LdapTestAndApplyInput) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FreeIpaTestAndApplyInput. +func (in *FreeIpaTestAndApplyInput) DeepCopy() *FreeIpaTestAndApplyInput { + if in == nil { + return nil + } + out := new(FreeIpaTestAndApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GKEStatus) DeepCopyInto(out *GKEStatus) { + *out = *in + if in.UpstreamSpec != nil { + in, out := &in.UpstreamSpec, &out.UpstreamSpec + *out = new(gkecattleiov1.GKEClusterConfigSpec) + (*in).DeepCopyInto(*out) + } + if in.PrivateRequiresTunnel != nil { + in, out := &in.PrivateRequiresTunnel, &out.PrivateRequiresTunnel + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GKEStatus. +func (in *GKEStatus) DeepCopy() *GKEStatus { + if in == nil { + return nil + } + out := new(GKEStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenerateKubeConfigOutput) DeepCopyInto(out *GenerateKubeConfigOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenerateKubeConfigOutput. +func (in *GenerateKubeConfigOutput) DeepCopy() *GenerateKubeConfigOutput { + if in == nil { + return nil + } + out := new(GenerateKubeConfigOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericLogin) DeepCopyInto(out *GenericLogin) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericLogin. +func (in *GenericLogin) DeepCopy() *GenericLogin { + if in == nil { + return nil + } + out := new(GenericLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCApplyInput) DeepCopyInto(out *GenericOIDCApplyInput) { + *out = *in + in.OIDCApplyInput.DeepCopyInto(&out.OIDCApplyInput) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCApplyInput. +func (in *GenericOIDCApplyInput) DeepCopy() *GenericOIDCApplyInput { + if in == nil { + return nil + } + out := new(GenericOIDCApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCConfig) DeepCopyInto(out *GenericOIDCConfig) { + *out = *in + in.OIDCConfig.DeepCopyInto(&out.OIDCConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCConfig. +func (in *GenericOIDCConfig) DeepCopy() *GenericOIDCConfig { + if in == nil { + return nil + } + out := new(GenericOIDCConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCLogin) DeepCopyInto(out *GenericOIDCLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCLogin. +func (in *GenericOIDCLogin) DeepCopy() *GenericOIDCLogin { + if in == nil { + return nil + } + out := new(GenericOIDCLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCProvider) DeepCopyInto(out *GenericOIDCProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCProvider. +func (in *GenericOIDCProvider) DeepCopy() *GenericOIDCProvider { + if in == nil { + return nil + } + out := new(GenericOIDCProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GenericOIDCProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCProviderList) DeepCopyInto(out *GenericOIDCProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GenericOIDCProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCProviderList. +func (in *GenericOIDCProviderList) DeepCopy() *GenericOIDCProviderList { + if in == nil { + return nil + } + out := new(GenericOIDCProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GenericOIDCProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GenericOIDCTestOutput) DeepCopyInto(out *GenericOIDCTestOutput) { + *out = *in + out.OIDCTestOutput = in.OIDCTestOutput + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericOIDCTestOutput. +func (in *GenericOIDCTestOutput) DeepCopy() *GenericOIDCTestOutput { + if in == nil { + return nil + } + out := new(GenericOIDCTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubConfig) DeepCopyInto(out *GithubConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + if in.AdditionalClientIDs != nil { + in, out := &in.AdditionalClientIDs, &out.AdditionalClientIDs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.HostnameToClientID != nil { + in, out := &in.HostnameToClientID, &out.HostnameToClientID + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubConfig. +func (in *GithubConfig) DeepCopy() *GithubConfig { + if in == nil { + return nil + } + out := new(GithubConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GithubConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubConfigApplyInput) DeepCopyInto(out *GithubConfigApplyInput) { + *out = *in + in.GithubConfig.DeepCopyInto(&out.GithubConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubConfigApplyInput. +func (in *GithubConfigApplyInput) DeepCopy() *GithubConfigApplyInput { + if in == nil { + return nil + } + out := new(GithubConfigApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubConfigList) DeepCopyInto(out *GithubConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GithubConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubConfigList. +func (in *GithubConfigList) DeepCopy() *GithubConfigList { + if in == nil { + return nil + } + out := new(GithubConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GithubConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubConfigTestOutput) DeepCopyInto(out *GithubConfigTestOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubConfigTestOutput. +func (in *GithubConfigTestOutput) DeepCopy() *GithubConfigTestOutput { + if in == nil { + return nil + } + out := new(GithubConfigTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubLogin) DeepCopyInto(out *GithubLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubLogin. +func (in *GithubLogin) DeepCopy() *GithubLogin { + if in == nil { + return nil + } + out := new(GithubLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubProvider) DeepCopyInto(out *GithubProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubProvider. +func (in *GithubProvider) DeepCopy() *GithubProvider { + if in == nil { + return nil + } + out := new(GithubProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GithubProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GithubProviderList) DeepCopyInto(out *GithubProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GithubProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubProviderList. +func (in *GithubProviderList) DeepCopy() *GithubProviderList { + if in == nil { + return nil + } + out := new(GithubProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GithubProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDNSProviderSpec) DeepCopyInto(out *GlobalDNSProviderSpec) { + *out = *in + if in.Route53ProviderConfig != nil { + in, out := &in.Route53ProviderConfig, &out.Route53ProviderConfig + *out = new(Route53ProviderConfig) + (*in).DeepCopyInto(*out) + } + if in.CloudflareProviderConfig != nil { + in, out := &in.CloudflareProviderConfig, &out.CloudflareProviderConfig + *out = new(CloudflareProviderConfig) + (*in).DeepCopyInto(*out) + } + if in.AlidnsProviderConfig != nil { + in, out := &in.AlidnsProviderConfig, &out.AlidnsProviderConfig + *out = new(AlidnsProviderConfig) + (*in).DeepCopyInto(*out) + } + if in.Members != nil { + in, out := &in.Members, &out.Members + *out = make([]Member, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDNSProviderSpec. +func (in *GlobalDNSProviderSpec) DeepCopy() *GlobalDNSProviderSpec { + if in == nil { + return nil + } + out := new(GlobalDNSProviderSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDNSSpec) DeepCopyInto(out *GlobalDNSSpec) { + *out = *in + if in.ProjectNames != nil { + in, out := &in.ProjectNames, &out.ProjectNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Members != nil { + in, out := &in.Members, &out.Members + *out = make([]Member, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDNSSpec. +func (in *GlobalDNSSpec) DeepCopy() *GlobalDNSSpec { + if in == nil { + return nil + } + out := new(GlobalDNSSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDNSStatus) DeepCopyInto(out *GlobalDNSStatus) { + *out = *in + if in.Endpoints != nil { + in, out := &in.Endpoints, &out.Endpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ClusterEndpoints != nil { + in, out := &in.ClusterEndpoints, &out.ClusterEndpoints + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDNSStatus. +func (in *GlobalDNSStatus) DeepCopy() *GlobalDNSStatus { + if in == nil { + return nil + } + out := new(GlobalDNSStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDns) DeepCopyInto(out *GlobalDns) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDns. +func (in *GlobalDns) DeepCopy() *GlobalDns { + if in == nil { + return nil + } + out := new(GlobalDns) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalDns) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDnsList) DeepCopyInto(out *GlobalDnsList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GlobalDns, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDnsList. +func (in *GlobalDnsList) DeepCopy() *GlobalDnsList { + if in == nil { + return nil + } + out := new(GlobalDnsList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalDnsList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDnsProvider) DeepCopyInto(out *GlobalDnsProvider) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDnsProvider. +func (in *GlobalDnsProvider) DeepCopy() *GlobalDnsProvider { + if in == nil { + return nil + } + out := new(GlobalDnsProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalDnsProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalDnsProviderList) DeepCopyInto(out *GlobalDnsProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GlobalDnsProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalDnsProviderList. +func (in *GlobalDnsProviderList) DeepCopy() *GlobalDnsProviderList { + if in == nil { + return nil + } + out := new(GlobalDnsProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalDnsProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRole) DeepCopyInto(out *GlobalRole) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.InheritedClusterRoles != nil { + in, out := &in.InheritedClusterRoles, &out.InheritedClusterRoles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.NamespacedRules != nil { + in, out := &in.NamespacedRules, &out.NamespacedRules + *out = make(map[string][]rbacv1.PolicyRule, len(*in)) + for key, val := range *in { + var outVal []rbacv1.PolicyRule + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + (*out)[key] = outVal + } + } + if in.InheritedFleetWorkspacePermissions != nil { + in, out := &in.InheritedFleetWorkspacePermissions, &out.InheritedFleetWorkspacePermissions + *out = new(FleetWorkspacePermission) + (*in).DeepCopyInto(*out) + } + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRole. +func (in *GlobalRole) DeepCopy() *GlobalRole { + if in == nil { + return nil + } + out := new(GlobalRole) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalRole) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRoleBinding) DeepCopyInto(out *GlobalRoleBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleBinding. +func (in *GlobalRoleBinding) DeepCopy() *GlobalRoleBinding { + if in == nil { + return nil + } + out := new(GlobalRoleBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalRoleBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRoleBindingList) DeepCopyInto(out *GlobalRoleBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GlobalRoleBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleBindingList. +func (in *GlobalRoleBindingList) DeepCopy() *GlobalRoleBindingList { + if in == nil { + return nil + } + out := new(GlobalRoleBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalRoleBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRoleList) DeepCopyInto(out *GlobalRoleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GlobalRole, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleList. +func (in *GlobalRoleList) DeepCopy() *GlobalRoleList { + if in == nil { + return nil + } + out := new(GlobalRoleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GlobalRoleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRoleStatus) DeepCopyInto(out *GlobalRoleStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRoleStatus. +func (in *GlobalRoleStatus) DeepCopy() *GlobalRoleStatus { + if in == nil { + return nil + } + out := new(GlobalRoleStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOAuthProvider) DeepCopyInto(out *GoogleOAuthProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOAuthProvider. +func (in *GoogleOAuthProvider) DeepCopy() *GoogleOAuthProvider { + if in == nil { + return nil + } + out := new(GoogleOAuthProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GoogleOAuthProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOAuthProviderList) DeepCopyInto(out *GoogleOAuthProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GoogleOAuthProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOAuthProviderList. +func (in *GoogleOAuthProviderList) DeepCopy() *GoogleOAuthProviderList { + if in == nil { + return nil + } + out := new(GoogleOAuthProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GoogleOAuthProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOauthConfig) DeepCopyInto(out *GoogleOauthConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOauthConfig. +func (in *GoogleOauthConfig) DeepCopy() *GoogleOauthConfig { + if in == nil { + return nil + } + out := new(GoogleOauthConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GoogleOauthConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOauthConfigApplyInput) DeepCopyInto(out *GoogleOauthConfigApplyInput) { + *out = *in + in.GoogleOauthConfig.DeepCopyInto(&out.GoogleOauthConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOauthConfigApplyInput. +func (in *GoogleOauthConfigApplyInput) DeepCopy() *GoogleOauthConfigApplyInput { + if in == nil { + return nil + } + out := new(GoogleOauthConfigApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOauthConfigList) DeepCopyInto(out *GoogleOauthConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GoogleOauthConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOauthConfigList. +func (in *GoogleOauthConfigList) DeepCopy() *GoogleOauthConfigList { + if in == nil { + return nil + } + out := new(GoogleOauthConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GoogleOauthConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOauthConfigTestOutput) DeepCopyInto(out *GoogleOauthConfigTestOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOauthConfigTestOutput. +func (in *GoogleOauthConfigTestOutput) DeepCopy() *GoogleOauthConfigTestOutput { + if in == nil { + return nil + } + out := new(GoogleOauthConfigTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GoogleOauthLogin) DeepCopyInto(out *GoogleOauthLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GoogleOauthLogin. +func (in *GoogleOauthLogin) DeepCopy() *GoogleOauthLogin { + if in == nil { + return nil + } + out := new(GoogleOauthLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Group) DeepCopyInto(out *Group) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Group. +func (in *Group) DeepCopy() *Group { + if in == nil { + return nil + } + out := new(Group) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Group) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupList) DeepCopyInto(out *GroupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Group, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupList. +func (in *GroupList) DeepCopy() *GroupList { + if in == nil { + return nil + } + out := new(GroupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupMember) DeepCopyInto(out *GroupMember) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupMember. +func (in *GroupMember) DeepCopy() *GroupMember { + if in == nil { + return nil + } + out := new(GroupMember) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupMember) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupMemberList) DeepCopyInto(out *GroupMemberList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]GroupMember, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupMemberList. +func (in *GroupMemberList) DeepCopy() *GroupMemberList { + if in == nil { + return nil + } + out := new(GroupMemberList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *GroupMemberList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImportClusterYamlInput) DeepCopyInto(out *ImportClusterYamlInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImportClusterYamlInput. +func (in *ImportClusterYamlInput) DeepCopy() *ImportClusterYamlInput { + if in == nil { + return nil + } + out := new(ImportClusterYamlInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImportYamlOutput) DeepCopyInto(out *ImportYamlOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImportYamlOutput. +func (in *ImportYamlOutput) DeepCopy() *ImportYamlOutput { + if in == nil { + return nil + } + out := new(ImportYamlOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImportedConfig) DeepCopyInto(out *ImportedConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImportedConfig. +func (in *ImportedConfig) DeepCopy() *ImportedConfig { + if in == nil { + return nil + } + out := new(ImportedConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IngressCapabilities) DeepCopyInto(out *IngressCapabilities) { + *out = *in + if in.CustomDefaultBackend != nil { + in, out := &in.CustomDefaultBackend, &out.CustomDefaultBackend + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressCapabilities. +func (in *IngressCapabilities) DeepCopy() *IngressCapabilities { + if in == nil { + return nil + } + out := new(IngressCapabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *K3sConfig) DeepCopyInto(out *K3sConfig) { + *out = *in + out.ClusterUpgradeStrategy = in.ClusterUpgradeStrategy + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K3sConfig. +func (in *K3sConfig) DeepCopy() *K3sConfig { + if in == nil { + return nil + } + out := new(K3sConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KafkaConfig) DeepCopyInto(out *KafkaConfig) { + *out = *in + if in.BrokerEndpoints != nil { + in, out := &in.BrokerEndpoints, &out.BrokerEndpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KafkaConfig. +func (in *KafkaConfig) DeepCopy() *KafkaConfig { + if in == nil { + return nil + } + out := new(KafkaConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyCloakConfig) DeepCopyInto(out *KeyCloakConfig) { + *out = *in + in.SamlConfig.DeepCopyInto(&out.SamlConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyCloakConfig. +func (in *KeyCloakConfig) DeepCopy() *KeyCloakConfig { + if in == nil { + return nil + } + out := new(KeyCloakConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyCloakOIDCConfig) DeepCopyInto(out *KeyCloakOIDCConfig) { + *out = *in + in.OIDCConfig.DeepCopyInto(&out.OIDCConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyCloakOIDCConfig. +func (in *KeyCloakOIDCConfig) DeepCopy() *KeyCloakOIDCConfig { + if in == nil { + return nil + } + out := new(KeyCloakOIDCConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyCloakOIDCConfigList) DeepCopyInto(out *KeyCloakOIDCConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KeyCloakOIDCConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyCloakOIDCConfigList. +func (in *KeyCloakOIDCConfigList) DeepCopy() *KeyCloakOIDCConfigList { + if in == nil { + return nil + } + out := new(KeyCloakOIDCConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KeyCloakOIDCConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyCloakOIDCProvider) DeepCopyInto(out *KeyCloakOIDCProvider) { + *out = *in + in.OIDCProvider.DeepCopyInto(&out.OIDCProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyCloakOIDCProvider. +func (in *KeyCloakOIDCProvider) DeepCopy() *KeyCloakOIDCProvider { + if in == nil { + return nil + } + out := new(KeyCloakOIDCProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyCloakProvider) DeepCopyInto(out *KeyCloakProvider) { + *out = *in + in.SamlProvider.DeepCopyInto(&out.SamlProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyCloakProvider. +func (in *KeyCloakProvider) DeepCopy() *KeyCloakProvider { + if in == nil { + return nil + } + out := new(KeyCloakProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KontainerDriver) DeepCopyInto(out *KontainerDriver) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KontainerDriver. +func (in *KontainerDriver) DeepCopy() *KontainerDriver { + if in == nil { + return nil + } + out := new(KontainerDriver) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KontainerDriver) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KontainerDriverList) DeepCopyInto(out *KontainerDriverList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KontainerDriver, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KontainerDriverList. +func (in *KontainerDriverList) DeepCopy() *KontainerDriverList { + if in == nil { + return nil + } + out := new(KontainerDriverList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KontainerDriverList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KontainerDriverSpec) DeepCopyInto(out *KontainerDriverSpec) { + *out = *in + if in.WhitelistDomains != nil { + in, out := &in.WhitelistDomains, &out.WhitelistDomains + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KontainerDriverSpec. +func (in *KontainerDriverSpec) DeepCopy() *KontainerDriverSpec { + if in == nil { + return nil + } + out := new(KontainerDriverSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KontainerDriverStatus) DeepCopyInto(out *KontainerDriverStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KontainerDriverStatus. +func (in *KontainerDriverStatus) DeepCopy() *KontainerDriverStatus { + if in == nil { + return nil + } + out := new(KontainerDriverStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LdapConfig) DeepCopyInto(out *LdapConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + in.LdapFields.DeepCopyInto(&out.LdapFields) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapConfig. +func (in *LdapConfig) DeepCopy() *LdapConfig { + if in == nil { + return nil + } + out := new(LdapConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LdapConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LdapConfigList) DeepCopyInto(out *LdapConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LdapConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapConfigList. +func (in *LdapConfigList) DeepCopy() *LdapConfigList { + if in == nil { + return nil + } + out := new(LdapConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LdapConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LdapFields) DeepCopyInto(out *LdapFields) { + *out = *in + if in.Servers != nil { + in, out := &in.Servers, &out.Servers + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapFields. +func (in *LdapFields) DeepCopy() *LdapFields { + if in == nil { + return nil + } + out := new(LdapFields) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LdapTestAndApplyInput) DeepCopyInto(out *LdapTestAndApplyInput) { + *out = *in + in.LdapConfig.DeepCopyInto(&out.LdapConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LdapTestAndApplyInput. +func (in *LdapTestAndApplyInput) DeepCopy() *LdapTestAndApplyInput { + if in == nil { + return nil + } + out := new(LdapTestAndApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ListOpts) DeepCopyInto(out *ListOpts) { + *out = *in + if in.Filters != nil { + in, out := &in.Filters, &out.Filters + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListOpts. +func (in *ListOpts) DeepCopy() *ListOpts { + if in == nil { + return nil + } + out := new(ListOpts) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoadBalancerCapabilities) DeepCopyInto(out *LoadBalancerCapabilities) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.ProtocolsSupported != nil { + in, out := &in.ProtocolsSupported, &out.ProtocolsSupported + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerCapabilities. +func (in *LoadBalancerCapabilities) DeepCopy() *LoadBalancerCapabilities { + if in == nil { + return nil + } + out := new(LoadBalancerCapabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalClusterAuthEndpoint) DeepCopyInto(out *LocalClusterAuthEndpoint) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalClusterAuthEndpoint. +func (in *LocalClusterAuthEndpoint) DeepCopy() *LocalClusterAuthEndpoint { + if in == nil { + return nil + } + out := new(LocalClusterAuthEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalConfig) DeepCopyInto(out *LocalConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalConfig. +func (in *LocalConfig) DeepCopy() *LocalConfig { + if in == nil { + return nil + } + out := new(LocalConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalConfigList) DeepCopyInto(out *LocalConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LocalConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalConfigList. +func (in *LocalConfigList) DeepCopy() *LocalConfigList { + if in == nil { + return nil + } + out := new(LocalConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalProvider) DeepCopyInto(out *LocalProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalProvider. +func (in *LocalProvider) DeepCopy() *LocalProvider { + if in == nil { + return nil + } + out := new(LocalProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalProviderList) DeepCopyInto(out *LocalProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LocalProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalProviderList. +func (in *LocalProviderList) DeepCopy() *LocalProviderList { + if in == nil { + return nil + } + out := new(LocalProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LocalProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoggingCommonField) DeepCopyInto(out *LoggingCommonField) { + *out = *in + if in.OutputTags != nil { + in, out := &in.OutputTags, &out.OutputTags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingCommonField. +func (in *LoggingCommonField) DeepCopy() *LoggingCommonField { + if in == nil { + return nil + } + out := new(LoggingCommonField) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoggingCondition) DeepCopyInto(out *LoggingCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingCondition. +func (in *LoggingCondition) DeepCopy() *LoggingCondition { + if in == nil { + return nil + } + out := new(LoggingCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoggingTargets) DeepCopyInto(out *LoggingTargets) { + *out = *in + if in.ElasticsearchConfig != nil { + in, out := &in.ElasticsearchConfig, &out.ElasticsearchConfig + *out = new(ElasticsearchConfig) + **out = **in + } + if in.SplunkConfig != nil { + in, out := &in.SplunkConfig, &out.SplunkConfig + *out = new(SplunkConfig) + **out = **in + } + if in.KafkaConfig != nil { + in, out := &in.KafkaConfig, &out.KafkaConfig + *out = new(KafkaConfig) + (*in).DeepCopyInto(*out) + } + if in.SyslogConfig != nil { + in, out := &in.SyslogConfig, &out.SyslogConfig + *out = new(SyslogConfig) + **out = **in + } + if in.FluentForwarderConfig != nil { + in, out := &in.FluentForwarderConfig, &out.FluentForwarderConfig + *out = new(FluentForwarderConfig) + (*in).DeepCopyInto(*out) + } + if in.CustomTargetConfig != nil { + in, out := &in.CustomTargetConfig, &out.CustomTargetConfig + *out = new(CustomTargetConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingTargets. +func (in *LoggingTargets) DeepCopy() *LoggingTargets { + if in == nil { + return nil + } + out := new(LoggingTargets) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedChart) DeepCopyInto(out *ManagedChart) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedChart. +func (in *ManagedChart) DeepCopy() *ManagedChart { + if in == nil { + return nil + } + out := new(ManagedChart) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedChart) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedChartList) DeepCopyInto(out *ManagedChartList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ManagedChart, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedChartList. +func (in *ManagedChartList) DeepCopy() *ManagedChartList { + if in == nil { + return nil + } + out := new(ManagedChartList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedChartList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedChartSpec) DeepCopyInto(out *ManagedChartSpec) { + *out = *in + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = (*in).DeepCopy() + } + if in.Diff != nil { + in, out := &in.Diff, &out.Diff + *out = new(v1alpha1.DiffOptions) + (*in).DeepCopyInto(*out) + } + if in.RolloutStrategy != nil { + in, out := &in.RolloutStrategy, &out.RolloutStrategy + *out = new(v1alpha1.RolloutStrategy) + (*in).DeepCopyInto(*out) + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]v1alpha1.BundleTarget, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedChartSpec. +func (in *ManagedChartSpec) DeepCopy() *ManagedChartSpec { + if in == nil { + return nil + } + out := new(ManagedChartSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedChartStatus) DeepCopyInto(out *ManagedChartStatus) { + *out = *in + in.BundleStatus.DeepCopyInto(&out.BundleStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedChartStatus. +func (in *ManagedChartStatus) DeepCopy() *ManagedChartStatus { + if in == nil { + return nil + } + out := new(ManagedChartStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MapDelta) DeepCopyInto(out *MapDelta) { + *out = *in + if in.Add != nil { + in, out := &in.Add, &out.Add + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Delete != nil { + in, out := &in.Delete, &out.Delete + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MapDelta. +func (in *MapDelta) DeepCopy() *MapDelta { + if in == nil { + return nil + } + out := new(MapDelta) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in MapStringInterface) DeepCopyInto(out *MapStringInterface) { + { + in := &in + clone := in.DeepCopy() + *out = *clone + return + } +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Member) DeepCopyInto(out *Member) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Member. +func (in *Member) DeepCopy() *Member { + if in == nil { + return nil + } + out := new(Member) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetadataUpdate) DeepCopyInto(out *MetadataUpdate) { + *out = *in + in.Labels.DeepCopyInto(&out.Labels) + in.Annotations.DeepCopyInto(&out.Annotations) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetadataUpdate. +func (in *MetadataUpdate) DeepCopy() *MetadataUpdate { + if in == nil { + return nil + } + out := new(MetadataUpdate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterApp) DeepCopyInto(out *MultiClusterApp) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterApp. +func (in *MultiClusterApp) DeepCopy() *MultiClusterApp { + if in == nil { + return nil + } + out := new(MultiClusterApp) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MultiClusterApp) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppList) DeepCopyInto(out *MultiClusterAppList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MultiClusterApp, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppList. +func (in *MultiClusterAppList) DeepCopy() *MultiClusterAppList { + if in == nil { + return nil + } + out := new(MultiClusterAppList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MultiClusterAppList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppRevision) DeepCopyInto(out *MultiClusterAppRevision) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make([]Answer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppRevision. +func (in *MultiClusterAppRevision) DeepCopy() *MultiClusterAppRevision { + if in == nil { + return nil + } + out := new(MultiClusterAppRevision) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MultiClusterAppRevision) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppRevisionList) DeepCopyInto(out *MultiClusterAppRevisionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MultiClusterAppRevision, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppRevisionList. +func (in *MultiClusterAppRevisionList) DeepCopy() *MultiClusterAppRevisionList { + if in == nil { + return nil + } + out := new(MultiClusterAppRevisionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MultiClusterAppRevisionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppRollbackInput) DeepCopyInto(out *MultiClusterAppRollbackInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppRollbackInput. +func (in *MultiClusterAppRollbackInput) DeepCopy() *MultiClusterAppRollbackInput { + if in == nil { + return nil + } + out := new(MultiClusterAppRollbackInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppSpec) DeepCopyInto(out *MultiClusterAppSpec) { + *out = *in + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make([]Answer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]Target, len(*in)) + copy(*out, *in) + } + if in.Members != nil { + in, out := &in.Members, &out.Members + *out = make([]Member, len(*in)) + copy(*out, *in) + } + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.UpgradeStrategy.DeepCopyInto(&out.UpgradeStrategy) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppSpec. +func (in *MultiClusterAppSpec) DeepCopy() *MultiClusterAppSpec { + if in == nil { + return nil + } + out := new(MultiClusterAppSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterAppStatus) DeepCopyInto(out *MultiClusterAppStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]projectcattleiov3.AppCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterAppStatus. +func (in *MultiClusterAppStatus) DeepCopy() *MultiClusterAppStatus { + if in == nil { + return nil + } + out := new(MultiClusterAppStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespaceResourceQuota) DeepCopyInto(out *NamespaceResourceQuota) { + *out = *in + out.Limit = in.Limit + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceResourceQuota. +func (in *NamespaceResourceQuota) DeepCopy() *NamespaceResourceQuota { + if in == nil { + return nil + } + out := new(NamespaceResourceQuota) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Node) DeepCopyInto(out *Node) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Node. +func (in *Node) DeepCopy() *Node { + if in == nil { + return nil + } + out := new(Node) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Node) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeCommonParams) DeepCopyInto(out *NodeCommonParams) { + *out = *in + if in.EngineOpt != nil { + in, out := &in.EngineOpt, &out.EngineOpt + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.StorageOpt != nil { + in, out := &in.StorageOpt, &out.StorageOpt + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.LogOpt != nil { + in, out := &in.LogOpt, &out.LogOpt + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.EngineInsecureRegistry != nil { + in, out := &in.EngineInsecureRegistry, &out.EngineInsecureRegistry + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.EngineRegistryMirror != nil { + in, out := &in.EngineRegistryMirror, &out.EngineRegistryMirror + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.EngineLabel != nil { + in, out := &in.EngineLabel, &out.EngineLabel + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.EngineEnv != nil { + in, out := &in.EngineEnv, &out.EngineEnv + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.UseInternalIPAddress != nil { + in, out := &in.UseInternalIPAddress, &out.UseInternalIPAddress + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeCommonParams. +func (in *NodeCommonParams) DeepCopy() *NodeCommonParams { + if in == nil { + return nil + } + out := new(NodeCommonParams) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeCondition) DeepCopyInto(out *NodeCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeCondition. +func (in *NodeCondition) DeepCopy() *NodeCondition { + if in == nil { + return nil + } + out := new(NodeCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeDriver) DeepCopyInto(out *NodeDriver) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeDriver. +func (in *NodeDriver) DeepCopy() *NodeDriver { + if in == nil { + return nil + } + out := new(NodeDriver) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeDriver) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeDriverList) DeepCopyInto(out *NodeDriverList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeDriver, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeDriverList. +func (in *NodeDriverList) DeepCopy() *NodeDriverList { + if in == nil { + return nil + } + out := new(NodeDriverList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeDriverList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeDriverSpec) DeepCopyInto(out *NodeDriverSpec) { + *out = *in + if in.WhitelistDomains != nil { + in, out := &in.WhitelistDomains, &out.WhitelistDomains + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeDriverSpec. +func (in *NodeDriverSpec) DeepCopy() *NodeDriverSpec { + if in == nil { + return nil + } + out := new(NodeDriverSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeDriverStatus) DeepCopyInto(out *NodeDriverStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeDriverStatus. +func (in *NodeDriverStatus) DeepCopy() *NodeDriverStatus { + if in == nil { + return nil + } + out := new(NodeDriverStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeList) DeepCopyInto(out *NodeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Node, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeList. +func (in *NodeList) DeepCopy() *NodeList { + if in == nil { + return nil + } + out := new(NodeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodePlan) DeepCopyInto(out *NodePlan) { + *out = *in + if in.Plan != nil { + in, out := &in.Plan, &out.Plan + *out = new(types.RKEConfigNodePlan) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePlan. +func (in *NodePlan) DeepCopy() *NodePlan { + if in == nil { + return nil + } + out := new(NodePlan) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodePool) DeepCopyInto(out *NodePool) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePool. +func (in *NodePool) DeepCopy() *NodePool { + if in == nil { + return nil + } + out := new(NodePool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodePool) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodePoolList) DeepCopyInto(out *NodePoolList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodePool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePoolList. +func (in *NodePoolList) DeepCopy() *NodePoolList { + if in == nil { + return nil + } + out := new(NodePoolList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodePoolList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodePoolSpec) DeepCopyInto(out *NodePoolSpec) { + *out = *in + if in.NodeLabels != nil { + in, out := &in.NodeLabels, &out.NodeLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NodeAnnotations != nil { + in, out := &in.NodeAnnotations, &out.NodeAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NodeTaints != nil { + in, out := &in.NodeTaints, &out.NodeTaints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePoolSpec. +func (in *NodePoolSpec) DeepCopy() *NodePoolSpec { + if in == nil { + return nil + } + out := new(NodePoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodePoolStatus) DeepCopyInto(out *NodePoolStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodePoolStatus. +func (in *NodePoolStatus) DeepCopy() *NodePoolStatus { + if in == nil { + return nil + } + out := new(NodePoolStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeSpec) DeepCopyInto(out *NodeSpec) { + *out = *in + if in.CustomConfig != nil { + in, out := &in.CustomConfig, &out.CustomConfig + *out = new(CustomConfig) + (*in).DeepCopyInto(*out) + } + in.InternalNodeSpec.DeepCopyInto(&out.InternalNodeSpec) + if in.DesiredNodeTaints != nil { + in, out := &in.DesiredNodeTaints, &out.DesiredNodeTaints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.UpdateTaintsFromAPI != nil { + in, out := &in.UpdateTaintsFromAPI, &out.UpdateTaintsFromAPI + *out = new(bool) + **out = **in + } + if in.NodeDrainInput != nil { + in, out := &in.NodeDrainInput, &out.NodeDrainInput + *out = new(types.NodeDrainInput) + (*in).DeepCopyInto(*out) + } + in.MetadataUpdate.DeepCopyInto(&out.MetadataUpdate) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSpec. +func (in *NodeSpec) DeepCopy() *NodeSpec { + if in == nil { + return nil + } + out := new(NodeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]NodeCondition, len(*in)) + copy(*out, *in) + } + in.InternalNodeStatus.DeepCopyInto(&out.InternalNodeStatus) + if in.Requested != nil { + in, out := &in.Requested, &out.Requested + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.Limits != nil { + in, out := &in.Limits, &out.Limits + *out = make(corev1.ResourceList, len(*in)) + for key, val := range *in { + (*out)[key] = val.DeepCopy() + } + } + if in.NodeTemplateSpec != nil { + in, out := &in.NodeTemplateSpec, &out.NodeTemplateSpec + *out = new(NodeTemplateSpec) + (*in).DeepCopyInto(*out) + } + if in.NodeConfig != nil { + in, out := &in.NodeConfig, &out.NodeConfig + *out = new(types.RKEConfigNode) + (*in).DeepCopyInto(*out) + } + if in.NodeAnnotations != nil { + in, out := &in.NodeAnnotations, &out.NodeAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NodeLabels != nil { + in, out := &in.NodeLabels, &out.NodeLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NodeTaints != nil { + in, out := &in.NodeTaints, &out.NodeTaints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DockerInfo != nil { + in, out := &in.DockerInfo, &out.DockerInfo + *out = new(DockerInfo) + (*in).DeepCopyInto(*out) + } + if in.NodePlan != nil { + in, out := &in.NodePlan, &out.NodePlan + *out = new(NodePlan) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeStatus. +func (in *NodeStatus) DeepCopy() *NodeStatus { + if in == nil { + return nil + } + out := new(NodeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeTemplate) DeepCopyInto(out *NodeTemplate) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeTemplate. +func (in *NodeTemplate) DeepCopy() *NodeTemplate { + if in == nil { + return nil + } + out := new(NodeTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeTemplateCondition) DeepCopyInto(out *NodeTemplateCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeTemplateCondition. +func (in *NodeTemplateCondition) DeepCopy() *NodeTemplateCondition { + if in == nil { + return nil + } + out := new(NodeTemplateCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeTemplateList) DeepCopyInto(out *NodeTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NodeTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeTemplateList. +func (in *NodeTemplateList) DeepCopy() *NodeTemplateList { + if in == nil { + return nil + } + out := new(NodeTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NodeTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeTemplateSpec) DeepCopyInto(out *NodeTemplateSpec) { + *out = *in + if in.NodeTaints != nil { + in, out := &in.NodeTaints, &out.NodeTaints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.NodeCommonParams.DeepCopyInto(&out.NodeCommonParams) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeTemplateSpec. +func (in *NodeTemplateSpec) DeepCopy() *NodeTemplateSpec { + if in == nil { + return nil + } + out := new(NodeTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeTemplateStatus) DeepCopyInto(out *NodeTemplateStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]NodeTemplateCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeTemplateStatus. +func (in *NodeTemplateStatus) DeepCopy() *NodeTemplateStatus { + if in == nil { + return nil + } + out := new(NodeTemplateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OAuthEndpoint) DeepCopyInto(out *OAuthEndpoint) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthEndpoint. +func (in *OAuthEndpoint) DeepCopy() *OAuthEndpoint { + if in == nil { + return nil + } + out := new(OAuthEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OAuthProvider) DeepCopyInto(out *OAuthProvider) { + *out = *in + if in.Scopes != nil { + in, out := &in.Scopes, &out.Scopes + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.OAuthEndpoint = in.OAuthEndpoint + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthProvider. +func (in *OAuthProvider) DeepCopy() *OAuthProvider { + if in == nil { + return nil + } + out := new(OAuthProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCApplyInput) DeepCopyInto(out *OIDCApplyInput) { + *out = *in + in.OIDCConfig.DeepCopyInto(&out.OIDCConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCApplyInput. +func (in *OIDCApplyInput) DeepCopy() *OIDCApplyInput { + if in == nil { + return nil + } + out := new(OIDCApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCConfig) DeepCopyInto(out *OIDCConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + if in.GroupSearchEnabled != nil { + in, out := &in.GroupSearchEnabled, &out.GroupSearchEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCConfig. +func (in *OIDCConfig) DeepCopy() *OIDCConfig { + if in == nil { + return nil + } + out := new(OIDCConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OIDCConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCConfigList) DeepCopyInto(out *OIDCConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OIDCConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCConfigList. +func (in *OIDCConfigList) DeepCopy() *OIDCConfigList { + if in == nil { + return nil + } + out := new(OIDCConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OIDCConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCLogin) DeepCopyInto(out *OIDCLogin) { + *out = *in + out.GenericLogin = in.GenericLogin + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCLogin. +func (in *OIDCLogin) DeepCopy() *OIDCLogin { + if in == nil { + return nil + } + out := new(OIDCLogin) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCProvider) DeepCopyInto(out *OIDCProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProvider. +func (in *OIDCProvider) DeepCopy() *OIDCProvider { + if in == nil { + return nil + } + out := new(OIDCProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OIDCProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCProviderList) DeepCopyInto(out *OIDCProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OIDCProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCProviderList. +func (in *OIDCProviderList) DeepCopy() *OIDCProviderList { + if in == nil { + return nil + } + out := new(OIDCProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OIDCProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OIDCTestOutput) DeepCopyInto(out *OIDCTestOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCTestOutput. +func (in *OIDCTestOutput) DeepCopy() *OIDCTestOutput { + if in == nil { + return nil + } + out := new(OIDCTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OKTAConfig) DeepCopyInto(out *OKTAConfig) { + *out = *in + in.SamlConfig.DeepCopyInto(&out.SamlConfig) + in.OpenLdapConfig.DeepCopyInto(&out.OpenLdapConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OKTAConfig. +func (in *OKTAConfig) DeepCopy() *OKTAConfig { + if in == nil { + return nil + } + out := new(OKTAConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OKTAProvider) DeepCopyInto(out *OKTAProvider) { + *out = *in + in.SamlProvider.DeepCopyInto(&out.SamlProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OKTAProvider. +func (in *OKTAProvider) DeepCopy() *OKTAProvider { + if in == nil { + return nil + } + out := new(OKTAProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenLdapConfig) DeepCopyInto(out *OpenLdapConfig) { + *out = *in + in.LdapConfig.DeepCopyInto(&out.LdapConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenLdapConfig. +func (in *OpenLdapConfig) DeepCopy() *OpenLdapConfig { + if in == nil { + return nil + } + out := new(OpenLdapConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenLdapProvider) DeepCopyInto(out *OpenLdapProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenLdapProvider. +func (in *OpenLdapProvider) DeepCopy() *OpenLdapProvider { + if in == nil { + return nil + } + out := new(OpenLdapProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenLdapProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenLdapProviderList) DeepCopyInto(out *OpenLdapProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OpenLdapProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenLdapProviderList. +func (in *OpenLdapProviderList) DeepCopy() *OpenLdapProviderList { + if in == nil { + return nil + } + out := new(OpenLdapProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OpenLdapProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OpenLdapTestAndApplyInput) DeepCopyInto(out *OpenLdapTestAndApplyInput) { + *out = *in + in.LdapTestAndApplyInput.DeepCopyInto(&out.LdapTestAndApplyInput) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenLdapTestAndApplyInput. +func (in *OpenLdapTestAndApplyInput) DeepCopy() *OpenLdapTestAndApplyInput { + if in == nil { + return nil + } + out := new(OpenLdapTestAndApplyInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PingConfig) DeepCopyInto(out *PingConfig) { + *out = *in + in.SamlConfig.DeepCopyInto(&out.SamlConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingConfig. +func (in *PingConfig) DeepCopy() *PingConfig { + if in == nil { + return nil + } + out := new(PingConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PingProvider) DeepCopyInto(out *PingProvider) { + *out = *in + in.SamlProvider.DeepCopyInto(&out.SamlProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PingProvider. +func (in *PingProvider) DeepCopy() *PingProvider { + if in == nil { + return nil + } + out := new(PingProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSecurityAdmissionConfigurationTemplate) DeepCopyInto(out *PodSecurityAdmissionConfigurationTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Configuration.DeepCopyInto(&out.Configuration) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityAdmissionConfigurationTemplate. +func (in *PodSecurityAdmissionConfigurationTemplate) DeepCopy() *PodSecurityAdmissionConfigurationTemplate { + if in == nil { + return nil + } + out := new(PodSecurityAdmissionConfigurationTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodSecurityAdmissionConfigurationTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSecurityAdmissionConfigurationTemplateDefaults) DeepCopyInto(out *PodSecurityAdmissionConfigurationTemplateDefaults) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityAdmissionConfigurationTemplateDefaults. +func (in *PodSecurityAdmissionConfigurationTemplateDefaults) DeepCopy() *PodSecurityAdmissionConfigurationTemplateDefaults { + if in == nil { + return nil + } + out := new(PodSecurityAdmissionConfigurationTemplateDefaults) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSecurityAdmissionConfigurationTemplateExemptions) DeepCopyInto(out *PodSecurityAdmissionConfigurationTemplateExemptions) { + *out = *in + if in.Usernames != nil { + in, out := &in.Usernames, &out.Usernames + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.RuntimeClasses != nil { + in, out := &in.RuntimeClasses, &out.RuntimeClasses + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Namespaces != nil { + in, out := &in.Namespaces, &out.Namespaces + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityAdmissionConfigurationTemplateExemptions. +func (in *PodSecurityAdmissionConfigurationTemplateExemptions) DeepCopy() *PodSecurityAdmissionConfigurationTemplateExemptions { + if in == nil { + return nil + } + out := new(PodSecurityAdmissionConfigurationTemplateExemptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSecurityAdmissionConfigurationTemplateList) DeepCopyInto(out *PodSecurityAdmissionConfigurationTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodSecurityAdmissionConfigurationTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityAdmissionConfigurationTemplateList. +func (in *PodSecurityAdmissionConfigurationTemplateList) DeepCopy() *PodSecurityAdmissionConfigurationTemplateList { + if in == nil { + return nil + } + out := new(PodSecurityAdmissionConfigurationTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodSecurityAdmissionConfigurationTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSecurityAdmissionConfigurationTemplateSpec) DeepCopyInto(out *PodSecurityAdmissionConfigurationTemplateSpec) { + *out = *in + out.Defaults = in.Defaults + in.Exemptions.DeepCopyInto(&out.Exemptions) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSecurityAdmissionConfigurationTemplateSpec. +func (in *PodSecurityAdmissionConfigurationTemplateSpec) DeepCopy() *PodSecurityAdmissionConfigurationTemplateSpec { + if in == nil { + return nil + } + out := new(PodSecurityAdmissionConfigurationTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Preference) DeepCopyInto(out *Preference) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Preference. +func (in *Preference) DeepCopy() *Preference { + if in == nil { + return nil + } + out := new(Preference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Preference) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PreferenceList) DeepCopyInto(out *PreferenceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Preference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreferenceList. +func (in *PreferenceList) DeepCopy() *PreferenceList { + if in == nil { + return nil + } + out := new(PreferenceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PreferenceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Principal) DeepCopyInto(out *Principal) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.ExtraInfo != nil { + in, out := &in.ExtraInfo, &out.ExtraInfo + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal. +func (in *Principal) DeepCopy() *Principal { + if in == nil { + return nil + } + out := new(Principal) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Principal) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PrincipalList) DeepCopyInto(out *PrincipalList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Principal, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrincipalList. +func (in *PrincipalList) DeepCopy() *PrincipalList { + if in == nil { + return nil + } + out := new(PrincipalList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PrincipalList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Principals) DeepCopyInto(out *Principals) { + *out = *in + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Principal, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principals. +func (in *Principals) DeepCopy() *Principals { + if in == nil { + return nil + } + out := new(Principals) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Project) DeepCopyInto(out *Project) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Project. +func (in *Project) DeepCopy() *Project { + if in == nil { + return nil + } + out := new(Project) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Project) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectCatalog) DeepCopyInto(out *ProjectCatalog) { + *out = *in + out.Namespaced = in.Namespaced + in.Catalog.DeepCopyInto(&out.Catalog) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectCatalog. +func (in *ProjectCatalog) DeepCopy() *ProjectCatalog { + if in == nil { + return nil + } + out := new(ProjectCatalog) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectCatalog) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectCatalogList) DeepCopyInto(out *ProjectCatalogList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ProjectCatalog, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectCatalogList. +func (in *ProjectCatalogList) DeepCopy() *ProjectCatalogList { + if in == nil { + return nil + } + out := new(ProjectCatalogList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectCatalogList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectCondition) DeepCopyInto(out *ProjectCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectCondition. +func (in *ProjectCondition) DeepCopy() *ProjectCondition { + if in == nil { + return nil + } + out := new(ProjectCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectList) DeepCopyInto(out *ProjectList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Project, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectList. +func (in *ProjectList) DeepCopy() *ProjectList { + if in == nil { + return nil + } + out := new(ProjectList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectLogging) DeepCopyInto(out *ProjectLogging) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectLogging. +func (in *ProjectLogging) DeepCopy() *ProjectLogging { + if in == nil { + return nil + } + out := new(ProjectLogging) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectLogging) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectLoggingList) DeepCopyInto(out *ProjectLoggingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ProjectLogging, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectLoggingList. +func (in *ProjectLoggingList) DeepCopy() *ProjectLoggingList { + if in == nil { + return nil + } + out := new(ProjectLoggingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectLoggingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectLoggingSpec) DeepCopyInto(out *ProjectLoggingSpec) { + *out = *in + in.LoggingTargets.DeepCopyInto(&out.LoggingTargets) + in.LoggingCommonField.DeepCopyInto(&out.LoggingCommonField) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectLoggingSpec. +func (in *ProjectLoggingSpec) DeepCopy() *ProjectLoggingSpec { + if in == nil { + return nil + } + out := new(ProjectLoggingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectLoggingStatus) DeepCopyInto(out *ProjectLoggingStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]LoggingCondition, len(*in)) + copy(*out, *in) + } + in.AppliedSpec.DeepCopyInto(&out.AppliedSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectLoggingStatus. +func (in *ProjectLoggingStatus) DeepCopy() *ProjectLoggingStatus { + if in == nil { + return nil + } + out := new(ProjectLoggingStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectNetworkPolicy) DeepCopyInto(out *ProjectNetworkPolicy) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + if in.Status != nil { + in, out := &in.Status, &out.Status + *out = new(ProjectNetworkPolicyStatus) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectNetworkPolicy. +func (in *ProjectNetworkPolicy) DeepCopy() *ProjectNetworkPolicy { + if in == nil { + return nil + } + out := new(ProjectNetworkPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectNetworkPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectNetworkPolicyList) DeepCopyInto(out *ProjectNetworkPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ProjectNetworkPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectNetworkPolicyList. +func (in *ProjectNetworkPolicyList) DeepCopy() *ProjectNetworkPolicyList { + if in == nil { + return nil + } + out := new(ProjectNetworkPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectNetworkPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectNetworkPolicySpec) DeepCopyInto(out *ProjectNetworkPolicySpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectNetworkPolicySpec. +func (in *ProjectNetworkPolicySpec) DeepCopy() *ProjectNetworkPolicySpec { + if in == nil { + return nil + } + out := new(ProjectNetworkPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectNetworkPolicyStatus) DeepCopyInto(out *ProjectNetworkPolicyStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectNetworkPolicyStatus. +func (in *ProjectNetworkPolicyStatus) DeepCopy() *ProjectNetworkPolicyStatus { + if in == nil { + return nil + } + out := new(ProjectNetworkPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectResourceQuota) DeepCopyInto(out *ProjectResourceQuota) { + *out = *in + out.Limit = in.Limit + out.UsedLimit = in.UsedLimit + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectResourceQuota. +func (in *ProjectResourceQuota) DeepCopy() *ProjectResourceQuota { + if in == nil { + return nil + } + out := new(ProjectResourceQuota) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectRoleTemplateBinding) DeepCopyInto(out *ProjectRoleTemplateBinding) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectRoleTemplateBinding. +func (in *ProjectRoleTemplateBinding) DeepCopy() *ProjectRoleTemplateBinding { + if in == nil { + return nil + } + out := new(ProjectRoleTemplateBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectRoleTemplateBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectRoleTemplateBindingList) DeepCopyInto(out *ProjectRoleTemplateBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ProjectRoleTemplateBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectRoleTemplateBindingList. +func (in *ProjectRoleTemplateBindingList) DeepCopy() *ProjectRoleTemplateBindingList { + if in == nil { + return nil + } + out := new(ProjectRoleTemplateBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ProjectRoleTemplateBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectSpec) DeepCopyInto(out *ProjectSpec) { + *out = *in + if in.ResourceQuota != nil { + in, out := &in.ResourceQuota, &out.ResourceQuota + *out = new(ProjectResourceQuota) + **out = **in + } + if in.NamespaceDefaultResourceQuota != nil { + in, out := &in.NamespaceDefaultResourceQuota, &out.NamespaceDefaultResourceQuota + *out = new(NamespaceResourceQuota) + **out = **in + } + if in.ContainerDefaultResourceLimit != nil { + in, out := &in.ContainerDefaultResourceLimit, &out.ContainerDefaultResourceLimit + *out = new(ContainerResourceLimit) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectSpec. +func (in *ProjectSpec) DeepCopy() *ProjectSpec { + if in == nil { + return nil + } + out := new(ProjectSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectStatus) DeepCopyInto(out *ProjectStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]ProjectCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectStatus. +func (in *ProjectStatus) DeepCopy() *ProjectStatus { + if in == nil { + return nil + } + out := new(ProjectStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProjectTestInput) DeepCopyInto(out *ProjectTestInput) { + *out = *in + in.LoggingTargets.DeepCopyInto(&out.LoggingTargets) + if in.OutputTags != nil { + in, out := &in.OutputTags, &out.OutputTags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProjectTestInput. +func (in *ProjectTestInput) DeepCopy() *ProjectTestInput { + if in == nil { + return nil + } + out := new(ProjectTestInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PublicEndpoint) DeepCopyInto(out *PublicEndpoint) { + *out = *in + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PublicEndpoint. +func (in *PublicEndpoint) DeepCopy() *PublicEndpoint { + if in == nil { + return nil + } + out := new(PublicEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Question) DeepCopyInto(out *Question) { + *out = *in + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Subquestions != nil { + in, out := &in.Subquestions, &out.Subquestions + *out = make([]SubQuestion, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Question. +func (in *Question) DeepCopy() *Question { + if in == nil { + return nil + } + out := new(Question) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RancherUserNotification) DeepCopyInto(out *RancherUserNotification) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RancherUserNotification. +func (in *RancherUserNotification) DeepCopy() *RancherUserNotification { + if in == nil { + return nil + } + out := new(RancherUserNotification) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RancherUserNotification) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RancherUserNotificationList) DeepCopyInto(out *RancherUserNotificationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RancherUserNotification, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RancherUserNotificationList. +func (in *RancherUserNotificationList) DeepCopy() *RancherUserNotificationList { + if in == nil { + return nil + } + out := new(RancherUserNotificationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RancherUserNotificationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceQuotaLimit) DeepCopyInto(out *ResourceQuotaLimit) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceQuotaLimit. +func (in *ResourceQuotaLimit) DeepCopy() *ResourceQuotaLimit { + if in == nil { + return nil + } + out := new(ResourceQuotaLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RestoreFromEtcdBackupInput) DeepCopyInto(out *RestoreFromEtcdBackupInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreFromEtcdBackupInput. +func (in *RestoreFromEtcdBackupInput) DeepCopy() *RestoreFromEtcdBackupInput { + if in == nil { + return nil + } + out := new(RestoreFromEtcdBackupInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Rke2Config) DeepCopyInto(out *Rke2Config) { + *out = *in + out.ClusterUpgradeStrategy = in.ClusterUpgradeStrategy + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rke2Config. +func (in *Rke2Config) DeepCopy() *Rke2Config { + if in == nil { + return nil + } + out := new(Rke2Config) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeAddon) DeepCopyInto(out *RkeAddon) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeAddon. +func (in *RkeAddon) DeepCopy() *RkeAddon { + if in == nil { + return nil + } + out := new(RkeAddon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeAddon) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeAddonList) DeepCopyInto(out *RkeAddonList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RkeAddon, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeAddonList. +func (in *RkeAddonList) DeepCopy() *RkeAddonList { + if in == nil { + return nil + } + out := new(RkeAddonList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeAddonList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeK8sServiceOption) DeepCopyInto(out *RkeK8sServiceOption) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.ServiceOptions.DeepCopyInto(&out.ServiceOptions) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeK8sServiceOption. +func (in *RkeK8sServiceOption) DeepCopy() *RkeK8sServiceOption { + if in == nil { + return nil + } + out := new(RkeK8sServiceOption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeK8sServiceOption) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeK8sServiceOptionList) DeepCopyInto(out *RkeK8sServiceOptionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RkeK8sServiceOption, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeK8sServiceOptionList. +func (in *RkeK8sServiceOptionList) DeepCopy() *RkeK8sServiceOptionList { + if in == nil { + return nil + } + out := new(RkeK8sServiceOptionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeK8sServiceOptionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeK8sSystemImage) DeepCopyInto(out *RkeK8sSystemImage) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.SystemImages = in.SystemImages + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeK8sSystemImage. +func (in *RkeK8sSystemImage) DeepCopy() *RkeK8sSystemImage { + if in == nil { + return nil + } + out := new(RkeK8sSystemImage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeK8sSystemImage) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RkeK8sSystemImageList) DeepCopyInto(out *RkeK8sSystemImageList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RkeK8sSystemImage, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RkeK8sSystemImageList. +func (in *RkeK8sSystemImageList) DeepCopy() *RkeK8sSystemImageList { + if in == nil { + return nil + } + out := new(RkeK8sSystemImageList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RkeK8sSystemImageList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoleTemplate) DeepCopyInto(out *RoleTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ExternalRules != nil { + in, out := &in.ExternalRules, &out.ExternalRules + *out = make([]rbacv1.PolicyRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.RoleTemplateNames != nil { + in, out := &in.RoleTemplateNames, &out.RoleTemplateNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleTemplate. +func (in *RoleTemplate) DeepCopy() *RoleTemplate { + if in == nil { + return nil + } + out := new(RoleTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RoleTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoleTemplateList) DeepCopyInto(out *RoleTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RoleTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleTemplateList. +func (in *RoleTemplateList) DeepCopy() *RoleTemplateList { + if in == nil { + return nil + } + out := new(RoleTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RoleTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollingUpdate) DeepCopyInto(out *RollingUpdate) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdate. +func (in *RollingUpdate) DeepCopy() *RollingUpdate { + if in == nil { + return nil + } + out := new(RollingUpdate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RotateCertificateInput) DeepCopyInto(out *RotateCertificateInput) { + *out = *in + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RotateCertificateInput. +func (in *RotateCertificateInput) DeepCopy() *RotateCertificateInput { + if in == nil { + return nil + } + out := new(RotateCertificateInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RotateCertificateOutput) DeepCopyInto(out *RotateCertificateOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RotateCertificateOutput. +func (in *RotateCertificateOutput) DeepCopy() *RotateCertificateOutput { + if in == nil { + return nil + } + out := new(RotateCertificateOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RotateEncryptionKeyOutput) DeepCopyInto(out *RotateEncryptionKeyOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RotateEncryptionKeyOutput. +func (in *RotateEncryptionKeyOutput) DeepCopy() *RotateEncryptionKeyOutput { + if in == nil { + return nil + } + out := new(RotateEncryptionKeyOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Route53ProviderConfig) DeepCopyInto(out *Route53ProviderConfig) { + *out = *in + if in.AdditionalOptions != nil { + in, out := &in.AdditionalOptions, &out.AdditionalOptions + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route53ProviderConfig. +func (in *Route53ProviderConfig) DeepCopy() *Route53ProviderConfig { + if in == nil { + return nil + } + out := new(Route53ProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3CredentialConfig) DeepCopyInto(out *S3CredentialConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3CredentialConfig. +func (in *S3CredentialConfig) DeepCopy() *S3CredentialConfig { + if in == nil { + return nil + } + out := new(S3CredentialConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlConfig) DeepCopyInto(out *SamlConfig) { + *out = *in + in.AuthConfig.DeepCopyInto(&out.AuthConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlConfig. +func (in *SamlConfig) DeepCopy() *SamlConfig { + if in == nil { + return nil + } + out := new(SamlConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlConfigList) DeepCopyInto(out *SamlConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SamlConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlConfigList. +func (in *SamlConfigList) DeepCopy() *SamlConfigList { + if in == nil { + return nil + } + out := new(SamlConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlConfigTestInput) DeepCopyInto(out *SamlConfigTestInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlConfigTestInput. +func (in *SamlConfigTestInput) DeepCopy() *SamlConfigTestInput { + if in == nil { + return nil + } + out := new(SamlConfigTestInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlConfigTestOutput) DeepCopyInto(out *SamlConfigTestOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlConfigTestOutput. +func (in *SamlConfigTestOutput) DeepCopy() *SamlConfigTestOutput { + if in == nil { + return nil + } + out := new(SamlConfigTestOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlLoginInput) DeepCopyInto(out *SamlLoginInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlLoginInput. +func (in *SamlLoginInput) DeepCopy() *SamlLoginInput { + if in == nil { + return nil + } + out := new(SamlLoginInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlLoginOutput) DeepCopyInto(out *SamlLoginOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlLoginOutput. +func (in *SamlLoginOutput) DeepCopy() *SamlLoginOutput { + if in == nil { + return nil + } + out := new(SamlLoginOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlProvider) DeepCopyInto(out *SamlProvider) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.AuthProvider.DeepCopyInto(&out.AuthProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlProvider. +func (in *SamlProvider) DeepCopy() *SamlProvider { + if in == nil { + return nil + } + out := new(SamlProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlProvider) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlProviderList) DeepCopyInto(out *SamlProviderList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SamlProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlProviderList. +func (in *SamlProviderList) DeepCopy() *SamlProviderList { + if in == nil { + return nil + } + out := new(SamlProviderList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlProviderList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlToken) DeepCopyInto(out *SamlToken) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlToken. +func (in *SamlToken) DeepCopy() *SamlToken { + if in == nil { + return nil + } + out := new(SamlToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SamlTokenList) DeepCopyInto(out *SamlTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SamlToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SamlTokenList. +func (in *SamlTokenList) DeepCopy() *SamlTokenList { + if in == nil { + return nil + } + out := new(SamlTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SamlTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SaveAsTemplateInput) DeepCopyInto(out *SaveAsTemplateInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SaveAsTemplateInput. +func (in *SaveAsTemplateInput) DeepCopy() *SaveAsTemplateInput { + if in == nil { + return nil + } + out := new(SaveAsTemplateInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SaveAsTemplateOutput) DeepCopyInto(out *SaveAsTemplateOutput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SaveAsTemplateOutput. +func (in *SaveAsTemplateOutput) DeepCopy() *SaveAsTemplateOutput { + if in == nil { + return nil + } + out := new(SaveAsTemplateOutput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SearchPrincipalsInput) DeepCopyInto(out *SearchPrincipalsInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SearchPrincipalsInput. +func (in *SearchPrincipalsInput) DeepCopy() *SearchPrincipalsInput { + if in == nil { + return nil + } + out := new(SearchPrincipalsInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SetPasswordInput) DeepCopyInto(out *SetPasswordInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SetPasswordInput. +func (in *SetPasswordInput) DeepCopy() *SetPasswordInput { + if in == nil { + return nil + } + out := new(SetPasswordInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Setting) DeepCopyInto(out *Setting) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Setting. +func (in *Setting) DeepCopy() *Setting { + if in == nil { + return nil + } + out := new(Setting) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Setting) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SettingList) DeepCopyInto(out *SettingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Setting, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingList. +func (in *SettingList) DeepCopy() *SettingList { + if in == nil { + return nil + } + out := new(SettingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SettingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ShibbolethConfig) DeepCopyInto(out *ShibbolethConfig) { + *out = *in + in.SamlConfig.DeepCopyInto(&out.SamlConfig) + in.OpenLdapConfig.DeepCopyInto(&out.OpenLdapConfig) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShibbolethConfig. +func (in *ShibbolethConfig) DeepCopy() *ShibbolethConfig { + if in == nil { + return nil + } + out := new(ShibbolethConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ShibbolethProvider) DeepCopyInto(out *ShibbolethProvider) { + *out = *in + in.SamlProvider.DeepCopyInto(&out.SamlProvider) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ShibbolethProvider. +func (in *ShibbolethProvider) DeepCopy() *ShibbolethProvider { + if in == nil { + return nil + } + out := new(ShibbolethProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SplunkConfig) DeepCopyInto(out *SplunkConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SplunkConfig. +func (in *SplunkConfig) DeepCopy() *SplunkConfig { + if in == nil { + return nil + } + out := new(SplunkConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubQuestion) DeepCopyInto(out *SubQuestion) { + *out = *in + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubQuestion. +func (in *SubQuestion) DeepCopy() *SubQuestion { + if in == nil { + return nil + } + out := new(SubQuestion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SyslogConfig) DeepCopyInto(out *SyslogConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SyslogConfig. +func (in *SyslogConfig) DeepCopy() *SyslogConfig { + if in == nil { + return nil + } + out := new(SyslogConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Target) DeepCopyInto(out *Target) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Target. +func (in *Target) DeepCopy() *Target { + if in == nil { + return nil + } + out := new(Target) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Template) DeepCopyInto(out *Template) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Template. +func (in *Template) DeepCopy() *Template { + if in == nil { + return nil + } + out := new(Template) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Template) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateContent) DeepCopyInto(out *TemplateContent) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateContent. +func (in *TemplateContent) DeepCopy() *TemplateContent { + if in == nil { + return nil + } + out := new(TemplateContent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TemplateContent) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateContentList) DeepCopyInto(out *TemplateContentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TemplateContent, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateContentList. +func (in *TemplateContentList) DeepCopy() *TemplateContentList { + if in == nil { + return nil + } + out := new(TemplateContentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TemplateContentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateList) DeepCopyInto(out *TemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Template, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateList. +func (in *TemplateList) DeepCopy() *TemplateList { + if in == nil { + return nil + } + out := new(TemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateSpec) DeepCopyInto(out *TemplateSpec) { + *out = *in + if in.Categories != nil { + in, out := &in.Categories, &out.Categories + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Versions != nil { + in, out := &in.Versions, &out.Versions + *out = make([]TemplateVersionSpec, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSpec. +func (in *TemplateSpec) DeepCopy() *TemplateSpec { + if in == nil { + return nil + } + out := new(TemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateStatus) DeepCopyInto(out *TemplateStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateStatus. +func (in *TemplateStatus) DeepCopy() *TemplateStatus { + if in == nil { + return nil + } + out := new(TemplateStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateVersion) DeepCopyInto(out *TemplateVersion) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateVersion. +func (in *TemplateVersion) DeepCopy() *TemplateVersion { + if in == nil { + return nil + } + out := new(TemplateVersion) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TemplateVersion) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateVersionList) DeepCopyInto(out *TemplateVersionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TemplateVersion, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateVersionList. +func (in *TemplateVersionList) DeepCopy() *TemplateVersionList { + if in == nil { + return nil + } + out := new(TemplateVersionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TemplateVersionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateVersionSpec) DeepCopyInto(out *TemplateVersionSpec) { + *out = *in + if in.UpgradeVersionLinks != nil { + in, out := &in.UpgradeVersionLinks, &out.UpgradeVersionLinks + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Questions != nil { + in, out := &in.Questions, &out.Questions + *out = make([]Question, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VersionURLs != nil { + in, out := &in.VersionURLs, &out.VersionURLs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateVersionSpec. +func (in *TemplateVersionSpec) DeepCopy() *TemplateVersionSpec { + if in == nil { + return nil + } + out := new(TemplateVersionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TemplateVersionStatus) DeepCopyInto(out *TemplateVersionStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateVersionStatus. +func (in *TemplateVersionStatus) DeepCopy() *TemplateVersionStatus { + if in == nil { + return nil + } + out := new(TemplateVersionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Token) DeepCopyInto(out *Token) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.UserPrincipal.DeepCopyInto(&out.UserPrincipal) + if in.GroupPrincipals != nil { + in, out := &in.GroupPrincipals, &out.GroupPrincipals + *out = make([]Principal, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ProviderInfo != nil { + in, out := &in.ProviderInfo, &out.ProviderInfo + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Token. +func (in *Token) DeepCopy() *Token { + if in == nil { + return nil + } + out := new(Token) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Token) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TokenList) DeepCopyInto(out *TokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Token, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenList. +func (in *TokenList) DeepCopy() *TokenList { + if in == nil { + return nil + } + out := new(TokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UpdateGlobalDNSTargetsInput) DeepCopyInto(out *UpdateGlobalDNSTargetsInput) { + *out = *in + if in.ProjectNames != nil { + in, out := &in.ProjectNames, &out.ProjectNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateGlobalDNSTargetsInput. +func (in *UpdateGlobalDNSTargetsInput) DeepCopy() *UpdateGlobalDNSTargetsInput { + if in == nil { + return nil + } + out := new(UpdateGlobalDNSTargetsInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UpdateMultiClusterAppTargetsInput) DeepCopyInto(out *UpdateMultiClusterAppTargetsInput) { + *out = *in + if in.Projects != nil { + in, out := &in.Projects, &out.Projects + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make([]Answer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateMultiClusterAppTargetsInput. +func (in *UpdateMultiClusterAppTargetsInput) DeepCopy() *UpdateMultiClusterAppTargetsInput { + if in == nil { + return nil + } + out := new(UpdateMultiClusterAppTargetsInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UpgradeStrategy) DeepCopyInto(out *UpgradeStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RollingUpdate) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpgradeStrategy. +func (in *UpgradeStrategy) DeepCopy() *UpgradeStrategy { + if in == nil { + return nil + } + out := new(UpgradeStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *User) DeepCopyInto(out *User) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.PrincipalIDs != nil { + in, out := &in.PrincipalIDs, &out.PrincipalIDs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User. +func (in *User) DeepCopy() *User { + if in == nil { + return nil + } + out := new(User) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *User) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserAttribute) DeepCopyInto(out *UserAttribute) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.GroupPrincipals != nil { + in, out := &in.GroupPrincipals, &out.GroupPrincipals + *out = make(map[string]Principals, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.ExtraByProvider != nil { + in, out := &in.ExtraByProvider, &out.ExtraByProvider + *out = make(map[string]map[string][]string, len(*in)) + for key, val := range *in { + var outVal map[string][]string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + (*out)[key] = outVal + } + } + if in.LastLogin != nil { + in, out := &in.LastLogin, &out.LastLogin + *out = (*in).DeepCopy() + } + if in.DisableAfter != nil { + in, out := &in.DisableAfter, &out.DisableAfter + *out = new(metav1.Duration) + **out = **in + } + if in.DeleteAfter != nil { + in, out := &in.DeleteAfter, &out.DeleteAfter + *out = new(metav1.Duration) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserAttribute. +func (in *UserAttribute) DeepCopy() *UserAttribute { + if in == nil { + return nil + } + out := new(UserAttribute) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *UserAttribute) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserAttributeList) DeepCopyInto(out *UserAttributeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]UserAttribute, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserAttributeList. +func (in *UserAttributeList) DeepCopy() *UserAttributeList { + if in == nil { + return nil + } + out := new(UserAttributeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *UserAttributeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserCondition) DeepCopyInto(out *UserCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserCondition. +func (in *UserCondition) DeepCopy() *UserCondition { + if in == nil { + return nil + } + out := new(UserCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserList) DeepCopyInto(out *UserList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]User, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserList. +func (in *UserList) DeepCopy() *UserList { + if in == nil { + return nil + } + out := new(UserList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *UserList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserSpec) DeepCopyInto(out *UserSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserSpec. +func (in *UserSpec) DeepCopy() *UserSpec { + if in == nil { + return nil + } + out := new(UserSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UserStatus) DeepCopyInto(out *UserStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]UserCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserStatus. +func (in *UserStatus) DeepCopy() *UserStatus { + if in == nil { + return nil + } + out := new(UserStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Values) DeepCopyInto(out *Values) { + *out = *in + if in.StringSliceValue != nil { + in, out := &in.StringSliceValue, &out.StringSliceValue + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Values. +func (in *Values) DeepCopy() *Values { + if in == nil { + return nil + } + out := new(Values) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VersionCommits) DeepCopyInto(out *VersionCommits) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionCommits. +func (in *VersionCommits) DeepCopy() *VersionCommits { + if in == nil { + return nil + } + out := new(VersionCommits) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WindowsSystemImages) DeepCopyInto(out *WindowsSystemImages) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WindowsSystemImages. +func (in *WindowsSystemImages) DeepCopy() *WindowsSystemImages { + if in == nil { + return nil + } + out := new(WindowsSystemImages) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_list_types.go new file mode 100644 index 0000000..a15888e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_list_types.go @@ -0,0 +1,1147 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=management.cattle.io +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// APIServiceList is a list of APIService resources +type APIServiceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []APIService `json:"items"` +} + +func NewAPIService(namespace, name string, obj APIService) *APIService { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("APIService").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ActiveDirectoryProviderList is a list of ActiveDirectoryProvider resources +type ActiveDirectoryProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ActiveDirectoryProvider `json:"items"` +} + +func NewActiveDirectoryProvider(namespace, name string, obj ActiveDirectoryProvider) *ActiveDirectoryProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ActiveDirectoryProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AuthConfigList is a list of AuthConfig resources +type AuthConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AuthConfig `json:"items"` +} + +func NewAuthConfig(namespace, name string, obj AuthConfig) *AuthConfig { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("AuthConfig").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AuthProviderList is a list of AuthProvider resources +type AuthProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AuthProvider `json:"items"` +} + +func NewAuthProvider(namespace, name string, obj AuthProvider) *AuthProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("AuthProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AuthTokenList is a list of AuthToken resources +type AuthTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AuthToken `json:"items"` +} + +func NewAuthToken(namespace, name string, obj AuthToken) *AuthToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("AuthToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AzureADProviderList is a list of AzureADProvider resources +type AzureADProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AzureADProvider `json:"items"` +} + +func NewAzureADProvider(namespace, name string, obj AzureADProvider) *AzureADProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("AzureADProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CatalogList is a list of Catalog resources +type CatalogList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Catalog `json:"items"` +} + +func NewCatalog(namespace, name string, obj Catalog) *Catalog { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Catalog").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CatalogTemplateList is a list of CatalogTemplate resources +type CatalogTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CatalogTemplate `json:"items"` +} + +func NewCatalogTemplate(namespace, name string, obj CatalogTemplate) *CatalogTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("CatalogTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CatalogTemplateVersionList is a list of CatalogTemplateVersion resources +type CatalogTemplateVersionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CatalogTemplateVersion `json:"items"` +} + +func NewCatalogTemplateVersion(namespace, name string, obj CatalogTemplateVersion) *CatalogTemplateVersion { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("CatalogTemplateVersion").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CloudCredentialList is a list of CloudCredential resources +type CloudCredentialList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CloudCredential `json:"items"` +} + +func NewCloudCredential(namespace, name string, obj CloudCredential) *CloudCredential { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("CloudCredential").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterList is a list of Cluster resources +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Cluster `json:"items"` +} + +func NewCluster(namespace, name string, obj Cluster) *Cluster { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Cluster").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterLoggingList is a list of ClusterLogging resources +type ClusterLoggingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterLogging `json:"items"` +} + +func NewClusterLogging(namespace, name string, obj ClusterLogging) *ClusterLogging { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterLogging").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterProxyConfigList is a list of ClusterProxyConfig resources +type ClusterProxyConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterProxyConfig `json:"items"` +} + +func NewClusterProxyConfig(namespace, name string, obj ClusterProxyConfig) *ClusterProxyConfig { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterProxyConfig").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterRegistrationTokenList is a list of ClusterRegistrationToken resources +type ClusterRegistrationTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterRegistrationToken `json:"items"` +} + +func NewClusterRegistrationToken(namespace, name string, obj ClusterRegistrationToken) *ClusterRegistrationToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterRegistrationToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterRoleTemplateBindingList is a list of ClusterRoleTemplateBinding resources +type ClusterRoleTemplateBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterRoleTemplateBinding `json:"items"` +} + +func NewClusterRoleTemplateBinding(namespace, name string, obj ClusterRoleTemplateBinding) *ClusterRoleTemplateBinding { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterRoleTemplateBinding").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTemplateList is a list of ClusterTemplate resources +type ClusterTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterTemplate `json:"items"` +} + +func NewClusterTemplate(namespace, name string, obj ClusterTemplate) *ClusterTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTemplateRevisionList is a list of ClusterTemplateRevision resources +type ClusterTemplateRevisionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterTemplateRevision `json:"items"` +} + +func NewClusterTemplateRevision(namespace, name string, obj ClusterTemplateRevision) *ClusterTemplateRevision { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterTemplateRevision").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ComposeConfigList is a list of ComposeConfig resources +type ComposeConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ComposeConfig `json:"items"` +} + +func NewComposeConfig(namespace, name string, obj ComposeConfig) *ComposeConfig { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ComposeConfig").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DynamicSchemaList is a list of DynamicSchema resources +type DynamicSchemaList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []DynamicSchema `json:"items"` +} + +func NewDynamicSchema(namespace, name string, obj DynamicSchema) *DynamicSchema { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("DynamicSchema").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// EtcdBackupList is a list of EtcdBackup resources +type EtcdBackupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []EtcdBackup `json:"items"` +} + +func NewEtcdBackup(namespace, name string, obj EtcdBackup) *EtcdBackup { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("EtcdBackup").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// FeatureList is a list of Feature resources +type FeatureList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Feature `json:"items"` +} + +func NewFeature(namespace, name string, obj Feature) *Feature { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Feature").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// FleetWorkspaceList is a list of FleetWorkspace resources +type FleetWorkspaceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []FleetWorkspace `json:"items"` +} + +func NewFleetWorkspace(namespace, name string, obj FleetWorkspace) *FleetWorkspace { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("FleetWorkspace").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// FreeIpaProviderList is a list of FreeIpaProvider resources +type FreeIpaProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []FreeIpaProvider `json:"items"` +} + +func NewFreeIpaProvider(namespace, name string, obj FreeIpaProvider) *FreeIpaProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("FreeIpaProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GenericOIDCProviderList is a list of GenericOIDCProvider resources +type GenericOIDCProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GenericOIDCProvider `json:"items"` +} + +func NewGenericOIDCProvider(namespace, name string, obj GenericOIDCProvider) *GenericOIDCProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GenericOIDCProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GithubProviderList is a list of GithubProvider resources +type GithubProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GithubProvider `json:"items"` +} + +func NewGithubProvider(namespace, name string, obj GithubProvider) *GithubProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GithubProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalDnsList is a list of GlobalDns resources +type GlobalDnsList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GlobalDns `json:"items"` +} + +func NewGlobalDns(namespace, name string, obj GlobalDns) *GlobalDns { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GlobalDns").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalDnsProviderList is a list of GlobalDnsProvider resources +type GlobalDnsProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GlobalDnsProvider `json:"items"` +} + +func NewGlobalDnsProvider(namespace, name string, obj GlobalDnsProvider) *GlobalDnsProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GlobalDnsProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalRoleList is a list of GlobalRole resources +type GlobalRoleList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GlobalRole `json:"items"` +} + +func NewGlobalRole(namespace, name string, obj GlobalRole) *GlobalRole { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GlobalRole").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GlobalRoleBindingList is a list of GlobalRoleBinding resources +type GlobalRoleBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GlobalRoleBinding `json:"items"` +} + +func NewGlobalRoleBinding(namespace, name string, obj GlobalRoleBinding) *GlobalRoleBinding { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GlobalRoleBinding").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GoogleOAuthProviderList is a list of GoogleOAuthProvider resources +type GoogleOAuthProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GoogleOAuthProvider `json:"items"` +} + +func NewGoogleOAuthProvider(namespace, name string, obj GoogleOAuthProvider) *GoogleOAuthProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GoogleOAuthProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GroupList is a list of Group resources +type GroupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Group `json:"items"` +} + +func NewGroup(namespace, name string, obj Group) *Group { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Group").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// GroupMemberList is a list of GroupMember resources +type GroupMemberList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []GroupMember `json:"items"` +} + +func NewGroupMember(namespace, name string, obj GroupMember) *GroupMember { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("GroupMember").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// KontainerDriverList is a list of KontainerDriver resources +type KontainerDriverList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []KontainerDriver `json:"items"` +} + +func NewKontainerDriver(namespace, name string, obj KontainerDriver) *KontainerDriver { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("KontainerDriver").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// LocalProviderList is a list of LocalProvider resources +type LocalProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []LocalProvider `json:"items"` +} + +func NewLocalProvider(namespace, name string, obj LocalProvider) *LocalProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("LocalProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ManagedChartList is a list of ManagedChart resources +type ManagedChartList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ManagedChart `json:"items"` +} + +func NewManagedChart(namespace, name string, obj ManagedChart) *ManagedChart { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ManagedChart").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MultiClusterAppList is a list of MultiClusterApp resources +type MultiClusterAppList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []MultiClusterApp `json:"items"` +} + +func NewMultiClusterApp(namespace, name string, obj MultiClusterApp) *MultiClusterApp { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("MultiClusterApp").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// MultiClusterAppRevisionList is a list of MultiClusterAppRevision resources +type MultiClusterAppRevisionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []MultiClusterAppRevision `json:"items"` +} + +func NewMultiClusterAppRevision(namespace, name string, obj MultiClusterAppRevision) *MultiClusterAppRevision { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("MultiClusterAppRevision").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodeList is a list of Node resources +type NodeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Node `json:"items"` +} + +func NewNode(namespace, name string, obj Node) *Node { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Node").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodeDriverList is a list of NodeDriver resources +type NodeDriverList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NodeDriver `json:"items"` +} + +func NewNodeDriver(namespace, name string, obj NodeDriver) *NodeDriver { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NodeDriver").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodePoolList is a list of NodePool resources +type NodePoolList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NodePool `json:"items"` +} + +func NewNodePool(namespace, name string, obj NodePool) *NodePool { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NodePool").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NodeTemplateList is a list of NodeTemplate resources +type NodeTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NodeTemplate `json:"items"` +} + +func NewNodeTemplate(namespace, name string, obj NodeTemplate) *NodeTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NodeTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OIDCProviderList is a list of OIDCProvider resources +type OIDCProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []OIDCProvider `json:"items"` +} + +func NewOIDCProvider(namespace, name string, obj OIDCProvider) *OIDCProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("OIDCProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OpenLdapProviderList is a list of OpenLdapProvider resources +type OpenLdapProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []OpenLdapProvider `json:"items"` +} + +func NewOpenLdapProvider(namespace, name string, obj OpenLdapProvider) *OpenLdapProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("OpenLdapProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodSecurityAdmissionConfigurationTemplateList is a list of PodSecurityAdmissionConfigurationTemplate resources +type PodSecurityAdmissionConfigurationTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []PodSecurityAdmissionConfigurationTemplate `json:"items"` +} + +func NewPodSecurityAdmissionConfigurationTemplate(namespace, name string, obj PodSecurityAdmissionConfigurationTemplate) *PodSecurityAdmissionConfigurationTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("PodSecurityAdmissionConfigurationTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PreferenceList is a list of Preference resources +type PreferenceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Preference `json:"items"` +} + +func NewPreference(namespace, name string, obj Preference) *Preference { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Preference").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PrincipalList is a list of Principal resources +type PrincipalList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Principal `json:"items"` +} + +func NewPrincipal(namespace, name string, obj Principal) *Principal { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Principal").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectList is a list of Project resources +type ProjectList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Project `json:"items"` +} + +func NewProject(namespace, name string, obj Project) *Project { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Project").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectLoggingList is a list of ProjectLogging resources +type ProjectLoggingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ProjectLogging `json:"items"` +} + +func NewProjectLogging(namespace, name string, obj ProjectLogging) *ProjectLogging { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ProjectLogging").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectNetworkPolicyList is a list of ProjectNetworkPolicy resources +type ProjectNetworkPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ProjectNetworkPolicy `json:"items"` +} + +func NewProjectNetworkPolicy(namespace, name string, obj ProjectNetworkPolicy) *ProjectNetworkPolicy { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ProjectNetworkPolicy").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectRoleTemplateBindingList is a list of ProjectRoleTemplateBinding resources +type ProjectRoleTemplateBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ProjectRoleTemplateBinding `json:"items"` +} + +func NewProjectRoleTemplateBinding(namespace, name string, obj ProjectRoleTemplateBinding) *ProjectRoleTemplateBinding { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ProjectRoleTemplateBinding").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RancherUserNotificationList is a list of RancherUserNotification resources +type RancherUserNotificationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RancherUserNotification `json:"items"` +} + +func NewRancherUserNotification(namespace, name string, obj RancherUserNotification) *RancherUserNotification { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RancherUserNotification").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RkeAddonList is a list of RkeAddon resources +type RkeAddonList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RkeAddon `json:"items"` +} + +func NewRkeAddon(namespace, name string, obj RkeAddon) *RkeAddon { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RkeAddon").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RkeK8sServiceOptionList is a list of RkeK8sServiceOption resources +type RkeK8sServiceOptionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RkeK8sServiceOption `json:"items"` +} + +func NewRkeK8sServiceOption(namespace, name string, obj RkeK8sServiceOption) *RkeK8sServiceOption { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RkeK8sServiceOption").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RkeK8sSystemImageList is a list of RkeK8sSystemImage resources +type RkeK8sSystemImageList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RkeK8sSystemImage `json:"items"` +} + +func NewRkeK8sSystemImage(namespace, name string, obj RkeK8sSystemImage) *RkeK8sSystemImage { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RkeK8sSystemImage").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RoleTemplateList is a list of RoleTemplate resources +type RoleTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RoleTemplate `json:"items"` +} + +func NewRoleTemplate(namespace, name string, obj RoleTemplate) *RoleTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RoleTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SamlProviderList is a list of SamlProvider resources +type SamlProviderList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []SamlProvider `json:"items"` +} + +func NewSamlProvider(namespace, name string, obj SamlProvider) *SamlProvider { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("SamlProvider").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SamlTokenList is a list of SamlToken resources +type SamlTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []SamlToken `json:"items"` +} + +func NewSamlToken(namespace, name string, obj SamlToken) *SamlToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("SamlToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SettingList is a list of Setting resources +type SettingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Setting `json:"items"` +} + +func NewSetting(namespace, name string, obj Setting) *Setting { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Setting").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TemplateList is a list of Template resources +type TemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Template `json:"items"` +} + +func NewTemplate(namespace, name string, obj Template) *Template { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Template").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TemplateContentList is a list of TemplateContent resources +type TemplateContentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []TemplateContent `json:"items"` +} + +func NewTemplateContent(namespace, name string, obj TemplateContent) *TemplateContent { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("TemplateContent").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TemplateVersionList is a list of TemplateVersion resources +type TemplateVersionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []TemplateVersion `json:"items"` +} + +func NewTemplateVersion(namespace, name string, obj TemplateVersion) *TemplateVersion { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("TemplateVersion").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// TokenList is a list of Token resources +type TokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Token `json:"items"` +} + +func NewToken(namespace, name string, obj Token) *Token { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Token").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// UserList is a list of User resources +type UserList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []User `json:"items"` +} + +func NewUser(namespace, name string, obj User) *User { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("User").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// UserAttributeList is a list of UserAttribute resources +type UserAttributeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []UserAttribute `json:"items"` +} + +func NewUserAttribute(namespace, name string, obj UserAttribute) *UserAttribute { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("UserAttribute").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ProjectCatalogList is a list of ProjectCatalog resources +type ProjectCatalogList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ProjectCatalog `json:"items"` +} + +func NewProjectCatalog(namespace, name string, obj ProjectCatalog) *ProjectCatalog { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ProjectCatalog").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterCatalogList is a list of ClusterCatalog resources +type ClusterCatalogList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ClusterCatalog `json:"items"` +} + +func NewClusterCatalog(namespace, name string, obj ClusterCatalog) *ClusterCatalog { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ClusterCatalog").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_register.go new file mode 100644 index 0000000..9e1b168 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/v3/zz_generated_register.go @@ -0,0 +1,255 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=management.cattle.io +package v3 + +import ( + management "github.com/rancher/rancher/pkg/apis/management.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + APIServiceResourceName = "apiservices" + ActiveDirectoryProviderResourceName = "activedirectoryproviders" + AuthConfigResourceName = "authconfigs" + AuthProviderResourceName = "authproviders" + AuthTokenResourceName = "authtokens" + AzureADProviderResourceName = "azureadproviders" + CatalogResourceName = "catalogs" + CatalogTemplateResourceName = "catalogtemplates" + CatalogTemplateVersionResourceName = "catalogtemplateversions" + CloudCredentialResourceName = "cloudcredentials" + ClusterResourceName = "clusters" + ClusterCatalogResourceName = "clustercatalogs" + ClusterLoggingResourceName = "clusterloggings" + ClusterProxyConfigResourceName = "clusterproxyconfigs" + ClusterRegistrationTokenResourceName = "clusterregistrationtokens" + ClusterRoleTemplateBindingResourceName = "clusterroletemplatebindings" + ClusterTemplateResourceName = "clustertemplates" + ClusterTemplateRevisionResourceName = "clustertemplaterevisions" + ComposeConfigResourceName = "composeconfigs" + DynamicSchemaResourceName = "dynamicschemas" + EtcdBackupResourceName = "etcdbackups" + FeatureResourceName = "features" + FleetWorkspaceResourceName = "fleetworkspaces" + FreeIpaProviderResourceName = "freeipaproviders" + GenericOIDCProviderResourceName = "genericoidcproviders" + GithubProviderResourceName = "githubproviders" + GlobalDnsResourceName = "globaldnses" + GlobalDnsProviderResourceName = "globaldnsproviders" + GlobalRoleResourceName = "globalroles" + GlobalRoleBindingResourceName = "globalrolebindings" + GoogleOAuthProviderResourceName = "googleoauthproviders" + GroupResourceName = "groups" + GroupMemberResourceName = "groupmembers" + KontainerDriverResourceName = "kontainerdrivers" + LocalProviderResourceName = "localproviders" + ManagedChartResourceName = "managedcharts" + MultiClusterAppResourceName = "multiclusterapps" + MultiClusterAppRevisionResourceName = "multiclusterapprevisions" + NodeResourceName = "nodes" + NodeDriverResourceName = "nodedrivers" + NodePoolResourceName = "nodepools" + NodeTemplateResourceName = "nodetemplates" + OIDCProviderResourceName = "oidcproviders" + OpenLdapProviderResourceName = "openldapproviders" + PodSecurityAdmissionConfigurationTemplateResourceName = "podsecurityadmissionconfigurationtemplates" + PreferenceResourceName = "preferences" + PrincipalResourceName = "principals" + ProjectResourceName = "projects" + ProjectCatalogResourceName = "projectcatalogs" + ProjectLoggingResourceName = "projectloggings" + ProjectNetworkPolicyResourceName = "projectnetworkpolicies" + ProjectRoleTemplateBindingResourceName = "projectroletemplatebindings" + RancherUserNotificationResourceName = "rancherusernotifications" + RkeAddonResourceName = "rkeaddons" + RkeK8sServiceOptionResourceName = "rkek8sserviceoptions" + RkeK8sSystemImageResourceName = "rkek8ssystemimages" + RoleTemplateResourceName = "roletemplates" + SamlProviderResourceName = "samlproviders" + SamlTokenResourceName = "samltokens" + SettingResourceName = "settings" + TemplateResourceName = "templates" + TemplateContentResourceName = "templatecontents" + TemplateVersionResourceName = "templateversions" + TokenResourceName = "tokens" + UserResourceName = "users" + UserAttributeResourceName = "userattributes" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: management.GroupName, Version: "v3"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &APIService{}, + &APIServiceList{}, + &ActiveDirectoryProvider{}, + &ActiveDirectoryProviderList{}, + &AuthConfig{}, + &AuthConfigList{}, + &AuthProvider{}, + &AuthProviderList{}, + &AuthToken{}, + &AuthTokenList{}, + &AzureADProvider{}, + &AzureADProviderList{}, + &Catalog{}, + &CatalogList{}, + &CatalogTemplate{}, + &CatalogTemplateList{}, + &CatalogTemplateVersion{}, + &CatalogTemplateVersionList{}, + &CloudCredential{}, + &CloudCredentialList{}, + &Cluster{}, + &ClusterList{}, + &ClusterCatalog{}, + &ClusterCatalogList{}, + &ClusterLogging{}, + &ClusterLoggingList{}, + &ClusterProxyConfig{}, + &ClusterProxyConfigList{}, + &ClusterRegistrationToken{}, + &ClusterRegistrationTokenList{}, + &ClusterRoleTemplateBinding{}, + &ClusterRoleTemplateBindingList{}, + &ClusterTemplate{}, + &ClusterTemplateList{}, + &ClusterTemplateRevision{}, + &ClusterTemplateRevisionList{}, + &ComposeConfig{}, + &ComposeConfigList{}, + &DynamicSchema{}, + &DynamicSchemaList{}, + &EtcdBackup{}, + &EtcdBackupList{}, + &Feature{}, + &FeatureList{}, + &FleetWorkspace{}, + &FleetWorkspaceList{}, + &FreeIpaProvider{}, + &FreeIpaProviderList{}, + &GenericOIDCProvider{}, + &GenericOIDCProviderList{}, + &GithubProvider{}, + &GithubProviderList{}, + &GlobalDns{}, + &GlobalDnsList{}, + &GlobalDnsProvider{}, + &GlobalDnsProviderList{}, + &GlobalRole{}, + &GlobalRoleList{}, + &GlobalRoleBinding{}, + &GlobalRoleBindingList{}, + &GoogleOAuthProvider{}, + &GoogleOAuthProviderList{}, + &Group{}, + &GroupList{}, + &GroupMember{}, + &GroupMemberList{}, + &KontainerDriver{}, + &KontainerDriverList{}, + &LocalProvider{}, + &LocalProviderList{}, + &ManagedChart{}, + &ManagedChartList{}, + &MultiClusterApp{}, + &MultiClusterAppList{}, + &MultiClusterAppRevision{}, + &MultiClusterAppRevisionList{}, + &Node{}, + &NodeList{}, + &NodeDriver{}, + &NodeDriverList{}, + &NodePool{}, + &NodePoolList{}, + &NodeTemplate{}, + &NodeTemplateList{}, + &OIDCProvider{}, + &OIDCProviderList{}, + &OpenLdapProvider{}, + &OpenLdapProviderList{}, + &PodSecurityAdmissionConfigurationTemplate{}, + &PodSecurityAdmissionConfigurationTemplateList{}, + &Preference{}, + &PreferenceList{}, + &Principal{}, + &PrincipalList{}, + &Project{}, + &ProjectList{}, + &ProjectCatalog{}, + &ProjectCatalogList{}, + &ProjectLogging{}, + &ProjectLoggingList{}, + &ProjectNetworkPolicy{}, + &ProjectNetworkPolicyList{}, + &ProjectRoleTemplateBinding{}, + &ProjectRoleTemplateBindingList{}, + &RancherUserNotification{}, + &RancherUserNotificationList{}, + &RkeAddon{}, + &RkeAddonList{}, + &RkeK8sServiceOption{}, + &RkeK8sServiceOptionList{}, + &RkeK8sSystemImage{}, + &RkeK8sSystemImageList{}, + &RoleTemplate{}, + &RoleTemplateList{}, + &SamlProvider{}, + &SamlProviderList{}, + &SamlToken{}, + &SamlTokenList{}, + &Setting{}, + &SettingList{}, + &Template{}, + &TemplateList{}, + &TemplateContent{}, + &TemplateContentList{}, + &TemplateVersion{}, + &TemplateVersionList{}, + &Token{}, + &TokenList{}, + &User{}, + &UserList{}, + &UserAttribute{}, + &UserAttributeList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..9e6f891 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/management.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package management + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "management.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/app_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/app_types.go new file mode 100644 index 0000000..c6f8703 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/app_types.go @@ -0,0 +1,137 @@ +package v3 + +import ( + "strings" + + "github.com/rancher/norman/condition" + "github.com/rancher/norman/types" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type App struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AppSpec `json:"spec,omitempty"` + Status AppStatus `json:"status,omitempty"` +} + +func (a *App) ObjClusterName() string { + return a.Spec.ObjClusterName() +} + +type AppSpec struct { + ProjectName string `json:"projectName,omitempty" norman:"type=reference[/v3/schemas/project]"` + Description string `json:"description,omitempty"` + TargetNamespace string `json:"targetNamespace,omitempty"` + ExternalID string `json:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty"` + Answers map[string]string `json:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty"` + Wait bool `json:"wait,omitempty"` + Timeout int `json:"timeout,omitempty" norman:"min=1,default=300"` + AppRevisionName string `json:"appRevisionName,omitempty" norman:"type=reference[/v3/project/schemas/apprevision]"` + Prune bool `json:"prune,omitempty"` + MultiClusterAppName string `json:"multiClusterAppName,omitempty" norman:"type=reference[/v3/schemas/multiclusterapp]"` + ValuesYaml string `json:"valuesYaml,omitempty"` + MaxRevisionCount int `json:"maxRevisionCount,omitempty"` +} + +func (a *AppSpec) ObjClusterName() string { + if parts := strings.SplitN(a.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +var ( + AppConditionInstalled condition.Cond = "Installed" + AppConditionMigrated condition.Cond = "Migrated" + AppConditionDeployed condition.Cond = "Deployed" + AppConditionForceUpgrade condition.Cond = "ForceUpgrade" + AppConditionUserTriggeredAction condition.Cond = "UserTriggeredAction" +) + +type AppStatus struct { + AppliedFiles map[string]string `json:"appliedFiles,omitempty"` + Notes string `json:"notes,omitempty"` + Conditions []AppCondition `json:"conditions,omitempty"` + LastAppliedTemplates string `json:"lastAppliedTemplate,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" norman:"noupdate,nocreate"` +} + +type AppCondition struct { + // Type of cluster condition. + Type condition.Cond `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status v1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime string `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime string `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // Human-readable message indicating details about last transition + Message string `json:"message,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type AppRevision struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AppRevisionSpec `json:"spec,omitempty"` + Status AppRevisionStatus `json:"status,omitempty"` +} + +type AppRevisionSpec struct { + ProjectName string `json:"projectName,omitempty" norman:"type=reference[/v3/schemas/project]"` +} + +func (a *AppRevisionSpec) ObjClusterName() string { + if parts := strings.SplitN(a.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type AppRevisionStatus struct { + ProjectName string `json:"projectName,omitempty" norman:"type=reference[/v3/schemas/project]"` + ExternalID string `json:"externalId"` + Answers map[string]string `json:"answers"` + AnswersSetString map[string]string `json:"answersSetString"` + Digest string `json:"digest"` + ValuesYaml string `json:"valuesYaml,omitempty"` + Files map[string]string `json:"files,omitempty"` +} + +func (a *AppRevisionStatus) ObjClusterName() string { + if parts := strings.SplitN(a.ProjectName, ":", 2); len(parts) == 2 { + return parts[0] + } + return "" +} + +type AppUpgradeConfig struct { + ExternalID string `json:"externalId,omitempty"` + Answers map[string]string `json:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty"` + ForceUpgrade bool `json:"forceUpgrade,omitempty"` + Files map[string]string `json:"files,omitempty"` + ValuesYaml string `json:"valuesYaml,omitempty"` +} + +type RollbackRevision struct { + RevisionName string `json:"revisionName,omitempty" norman:"type=reference[/v3/project/schemas/apprevision]"` + ForceUpgrade bool `json:"forceUpgrade,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/doc.go new file mode 100644 index 0000000..fd1257f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=project.cattle.io +package v3 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/types.go new file mode 100644 index 0000000..5cc518e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/types.go @@ -0,0 +1,169 @@ +package v3 + +import ( + "github.com/rancher/norman/types" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ServiceAccountToken struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + AccountName string `json:"accountName"` + AccountUID string `json:"accountUid"` + Description string `json:"description"` + Token string `json:"token" norman:"writeOnly"` + CACRT string `json:"caCrt"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NamespacedServiceAccountToken ServiceAccountToken + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type DockerCredential struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Description string `json:"description"` + Registries map[string]RegistryCredential `json:"registries"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NamespacedDockerCredential DockerCredential + +type RegistryCredential struct { + Description string `json:"description"` + Username string `json:"username"` + Password string `json:"password" norman:"writeOnly"` + Auth string `json:"auth" norman:"writeOnly"` + Email string `json:"email"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Certificate struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Description string `json:"description"` + Certs string `json:"certs"` + Key string `json:"key" norman:"writeOnly"` + + CertFingerprint string `json:"certFingerprint" norman:"nocreate,noupdate"` + CN string `json:"cn" norman:"nocreate,noupdate"` + Version string `json:"version" norman:"nocreate,noupdate"` + ExpiresAt string `json:"expiresAt" norman:"nocreate,noupdate"` + Issuer string `json:"issuer" norman:"nocreate,noupdate"` + IssuedAt string `json:"issuedAt" norman:"nocreate,noupdate"` + Algorithm string `json:"algorithm" norman:"nocreate,noupdate"` + SerialNumber string `json:"serialNumber" norman:"nocreate,noupdate"` + KeySize string `json:"keySize" norman:"nocreate,noupdate"` + SubjectAlternativeNames []string `json:"subjectAlternativeNames" norman:"nocreate,noupdate"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NamespacedCertificate Certificate + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type BasicAuth struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Description string `json:"description"` + Username string `json:"username"` + Password string `json:"password" norman:"writeOnly"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NamespacedBasicAuth BasicAuth + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type SSHAuth struct { + types.Namespaced + + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Description string `json:"description"` + PrivateKey string `json:"privateKey" norman:"writeOnly"` + Fingerprint string `json:"certFingerprint" norman:"nocreate,noupdate"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NamespacedSSHAuth SSHAuth + +type PublicEndpoint struct { + NodeName string `json:"nodeName,omitempty" norman:"type=reference[/v3/schemas/node],nocreate,noupdate"` + Addresses []string `json:"addresses,omitempty" norman:"nocreate,noupdate"` + Port int32 `json:"port,omitempty" norman:"nocreate,noupdate"` + Protocol string `json:"protocol,omitempty" norman:"nocreate,noupdate"` + // for node port service endpoint + ServiceName string `json:"serviceName,omitempty" norman:"type=reference[service],nocreate,noupdate"` + // for host port endpoint + PodName string `json:"podName,omitempty" norman:"type=reference[pod],nocreate,noupdate"` + // for ingress endpoint. ServiceName, podName, ingressName are mutually exclusive + IngressName string `json:"ingressName,omitempty" norman:"type=reference[ingress],nocreate,noupdate"` + // Hostname/path are set for Ingress endpoints + Hostname string `json:"hostname,omitempty" norman:"nocreate,noupdate"` + Path string `json:"path,omitempty" norman:"nocreate,noupdate"` + // True when endpoint is exposed on every node + AllNodes bool `json:"allNodes" norman:"nocreate,noupdate"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Workload struct { + types.Namespaced + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` +} + +type DeploymentRollbackInput struct { + ReplicaSetID string `json:"replicaSetId" norman:"type=reference[replicaSet]"` +} + +type WorkloadMetric struct { + Port int32 `json:"port,omitempty"` + Path string `json:"path,omitempty"` + Schema string `json:"schema,omitempty" norman:"type=enum,options=HTTP|HTTPS"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_deepcopy.go new file mode 100644 index 0000000..6eed441 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_deepcopy.go @@ -0,0 +1,1090 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *App) DeepCopyInto(out *App) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new App. +func (in *App) DeepCopy() *App { + if in == nil { + return nil + } + out := new(App) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *App) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppCondition) DeepCopyInto(out *AppCondition) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppCondition. +func (in *AppCondition) DeepCopy() *AppCondition { + if in == nil { + return nil + } + out := new(AppCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppList) DeepCopyInto(out *AppList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]App, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppList. +func (in *AppList) DeepCopy() *AppList { + if in == nil { + return nil + } + out := new(AppList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppRevision) DeepCopyInto(out *AppRevision) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRevision. +func (in *AppRevision) DeepCopy() *AppRevision { + if in == nil { + return nil + } + out := new(AppRevision) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppRevision) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppRevisionList) DeepCopyInto(out *AppRevisionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AppRevision, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRevisionList. +func (in *AppRevisionList) DeepCopy() *AppRevisionList { + if in == nil { + return nil + } + out := new(AppRevisionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AppRevisionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppRevisionSpec) DeepCopyInto(out *AppRevisionSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRevisionSpec. +func (in *AppRevisionSpec) DeepCopy() *AppRevisionSpec { + if in == nil { + return nil + } + out := new(AppRevisionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppRevisionStatus) DeepCopyInto(out *AppRevisionStatus) { + *out = *in + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AnswersSetString != nil { + in, out := &in.AnswersSetString, &out.AnswersSetString + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppRevisionStatus. +func (in *AppRevisionStatus) DeepCopy() *AppRevisionStatus { + if in == nil { + return nil + } + out := new(AppRevisionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppSpec) DeepCopyInto(out *AppSpec) { + *out = *in + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AnswersSetString != nil { + in, out := &in.AnswersSetString, &out.AnswersSetString + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppSpec. +func (in *AppSpec) DeepCopy() *AppSpec { + if in == nil { + return nil + } + out := new(AppSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppStatus) DeepCopyInto(out *AppStatus) { + *out = *in + if in.AppliedFiles != nil { + in, out := &in.AppliedFiles, &out.AppliedFiles + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]AppCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppStatus. +func (in *AppStatus) DeepCopy() *AppStatus { + if in == nil { + return nil + } + out := new(AppStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AppUpgradeConfig) DeepCopyInto(out *AppUpgradeConfig) { + *out = *in + if in.Answers != nil { + in, out := &in.Answers, &out.Answers + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AnswersSetString != nil { + in, out := &in.AnswersSetString, &out.AnswersSetString + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppUpgradeConfig. +func (in *AppUpgradeConfig) DeepCopy() *AppUpgradeConfig { + if in == nil { + return nil + } + out := new(AppUpgradeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuth. +func (in *BasicAuth) DeepCopy() *BasicAuth { + if in == nil { + return nil + } + out := new(BasicAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BasicAuth) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BasicAuthList) DeepCopyInto(out *BasicAuthList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]BasicAuth, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BasicAuthList. +func (in *BasicAuthList) DeepCopy() *BasicAuthList { + if in == nil { + return nil + } + out := new(BasicAuthList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BasicAuthList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Certificate) DeepCopyInto(out *Certificate) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.SubjectAlternativeNames != nil { + in, out := &in.SubjectAlternativeNames, &out.SubjectAlternativeNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Certificate. +func (in *Certificate) DeepCopy() *Certificate { + if in == nil { + return nil + } + out := new(Certificate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Certificate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CertificateList) DeepCopyInto(out *CertificateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Certificate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertificateList. +func (in *CertificateList) DeepCopy() *CertificateList { + if in == nil { + return nil + } + out := new(CertificateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CertificateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentRollbackInput) DeepCopyInto(out *DeploymentRollbackInput) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentRollbackInput. +func (in *DeploymentRollbackInput) DeepCopy() *DeploymentRollbackInput { + if in == nil { + return nil + } + out := new(DeploymentRollbackInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerCredential) DeepCopyInto(out *DockerCredential) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Registries != nil { + in, out := &in.Registries, &out.Registries + *out = make(map[string]RegistryCredential, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerCredential. +func (in *DockerCredential) DeepCopy() *DockerCredential { + if in == nil { + return nil + } + out := new(DockerCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerCredential) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerCredentialList) DeepCopyInto(out *DockerCredentialList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerCredential, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerCredentialList. +func (in *DockerCredentialList) DeepCopy() *DockerCredentialList { + if in == nil { + return nil + } + out := new(DockerCredentialList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerCredentialList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedBasicAuth) DeepCopyInto(out *NamespacedBasicAuth) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedBasicAuth. +func (in *NamespacedBasicAuth) DeepCopy() *NamespacedBasicAuth { + if in == nil { + return nil + } + out := new(NamespacedBasicAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedBasicAuth) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedBasicAuthList) DeepCopyInto(out *NamespacedBasicAuthList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NamespacedBasicAuth, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedBasicAuthList. +func (in *NamespacedBasicAuthList) DeepCopy() *NamespacedBasicAuthList { + if in == nil { + return nil + } + out := new(NamespacedBasicAuthList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedBasicAuthList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedCertificate) DeepCopyInto(out *NamespacedCertificate) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.SubjectAlternativeNames != nil { + in, out := &in.SubjectAlternativeNames, &out.SubjectAlternativeNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedCertificate. +func (in *NamespacedCertificate) DeepCopy() *NamespacedCertificate { + if in == nil { + return nil + } + out := new(NamespacedCertificate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedCertificate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedCertificateList) DeepCopyInto(out *NamespacedCertificateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NamespacedCertificate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedCertificateList. +func (in *NamespacedCertificateList) DeepCopy() *NamespacedCertificateList { + if in == nil { + return nil + } + out := new(NamespacedCertificateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedCertificateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedDockerCredential) DeepCopyInto(out *NamespacedDockerCredential) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Registries != nil { + in, out := &in.Registries, &out.Registries + *out = make(map[string]RegistryCredential, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedDockerCredential. +func (in *NamespacedDockerCredential) DeepCopy() *NamespacedDockerCredential { + if in == nil { + return nil + } + out := new(NamespacedDockerCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedDockerCredential) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedDockerCredentialList) DeepCopyInto(out *NamespacedDockerCredentialList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NamespacedDockerCredential, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedDockerCredentialList. +func (in *NamespacedDockerCredentialList) DeepCopy() *NamespacedDockerCredentialList { + if in == nil { + return nil + } + out := new(NamespacedDockerCredentialList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedDockerCredentialList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedSSHAuth) DeepCopyInto(out *NamespacedSSHAuth) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedSSHAuth. +func (in *NamespacedSSHAuth) DeepCopy() *NamespacedSSHAuth { + if in == nil { + return nil + } + out := new(NamespacedSSHAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedSSHAuth) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedSSHAuthList) DeepCopyInto(out *NamespacedSSHAuthList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NamespacedSSHAuth, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedSSHAuthList. +func (in *NamespacedSSHAuthList) DeepCopy() *NamespacedSSHAuthList { + if in == nil { + return nil + } + out := new(NamespacedSSHAuthList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedSSHAuthList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedServiceAccountToken) DeepCopyInto(out *NamespacedServiceAccountToken) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedServiceAccountToken. +func (in *NamespacedServiceAccountToken) DeepCopy() *NamespacedServiceAccountToken { + if in == nil { + return nil + } + out := new(NamespacedServiceAccountToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedServiceAccountToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NamespacedServiceAccountTokenList) DeepCopyInto(out *NamespacedServiceAccountTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NamespacedServiceAccountToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedServiceAccountTokenList. +func (in *NamespacedServiceAccountTokenList) DeepCopy() *NamespacedServiceAccountTokenList { + if in == nil { + return nil + } + out := new(NamespacedServiceAccountTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NamespacedServiceAccountTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PublicEndpoint) DeepCopyInto(out *PublicEndpoint) { + *out = *in + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PublicEndpoint. +func (in *PublicEndpoint) DeepCopy() *PublicEndpoint { + if in == nil { + return nil + } + out := new(PublicEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegistryCredential) DeepCopyInto(out *RegistryCredential) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryCredential. +func (in *RegistryCredential) DeepCopy() *RegistryCredential { + if in == nil { + return nil + } + out := new(RegistryCredential) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollbackRevision) DeepCopyInto(out *RollbackRevision) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollbackRevision. +func (in *RollbackRevision) DeepCopy() *RollbackRevision { + if in == nil { + return nil + } + out := new(RollbackRevision) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSHAuth) DeepCopyInto(out *SSHAuth) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSHAuth. +func (in *SSHAuth) DeepCopy() *SSHAuth { + if in == nil { + return nil + } + out := new(SSHAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SSHAuth) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SSHAuthList) DeepCopyInto(out *SSHAuthList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SSHAuth, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSHAuthList. +func (in *SSHAuthList) DeepCopy() *SSHAuthList { + if in == nil { + return nil + } + out := new(SSHAuthList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SSHAuthList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceAccountToken) DeepCopyInto(out *ServiceAccountToken) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountToken. +func (in *ServiceAccountToken) DeepCopy() *ServiceAccountToken { + if in == nil { + return nil + } + out := new(ServiceAccountToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceAccountToken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceAccountTokenList) DeepCopyInto(out *ServiceAccountTokenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceAccountToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccountTokenList. +func (in *ServiceAccountTokenList) DeepCopy() *ServiceAccountTokenList { + if in == nil { + return nil + } + out := new(ServiceAccountTokenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceAccountTokenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Workload) DeepCopyInto(out *Workload) { + *out = *in + out.Namespaced = in.Namespaced + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workload. +func (in *Workload) DeepCopy() *Workload { + if in == nil { + return nil + } + out := new(Workload) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Workload) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadList) DeepCopyInto(out *WorkloadList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Workload, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadList. +func (in *WorkloadList) DeepCopy() *WorkloadList { + if in == nil { + return nil + } + out := new(WorkloadList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *WorkloadList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadMetric) DeepCopyInto(out *WorkloadMetric) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadMetric. +func (in *WorkloadMetric) DeepCopy() *WorkloadMetric { + if in == nil { + return nil + } + out := new(WorkloadMetric) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_list_types.go new file mode 100644 index 0000000..d88fbaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_list_types.go @@ -0,0 +1,246 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=project.cattle.io +package v3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AppList is a list of App resources +type AppList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []App `json:"items"` +} + +func NewApp(namespace, name string, obj App) *App { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("App").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// AppRevisionList is a list of AppRevision resources +type AppRevisionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []AppRevision `json:"items"` +} + +func NewAppRevision(namespace, name string, obj AppRevision) *AppRevision { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("AppRevision").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// BasicAuthList is a list of BasicAuth resources +type BasicAuthList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []BasicAuth `json:"items"` +} + +func NewBasicAuth(namespace, name string, obj BasicAuth) *BasicAuth { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("BasicAuth").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CertificateList is a list of Certificate resources +type CertificateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Certificate `json:"items"` +} + +func NewCertificate(namespace, name string, obj Certificate) *Certificate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Certificate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// DockerCredentialList is a list of DockerCredential resources +type DockerCredentialList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []DockerCredential `json:"items"` +} + +func NewDockerCredential(namespace, name string, obj DockerCredential) *DockerCredential { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("DockerCredential").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NamespacedBasicAuthList is a list of NamespacedBasicAuth resources +type NamespacedBasicAuthList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NamespacedBasicAuth `json:"items"` +} + +func NewNamespacedBasicAuth(namespace, name string, obj NamespacedBasicAuth) *NamespacedBasicAuth { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NamespacedBasicAuth").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NamespacedCertificateList is a list of NamespacedCertificate resources +type NamespacedCertificateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NamespacedCertificate `json:"items"` +} + +func NewNamespacedCertificate(namespace, name string, obj NamespacedCertificate) *NamespacedCertificate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NamespacedCertificate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NamespacedDockerCredentialList is a list of NamespacedDockerCredential resources +type NamespacedDockerCredentialList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NamespacedDockerCredential `json:"items"` +} + +func NewNamespacedDockerCredential(namespace, name string, obj NamespacedDockerCredential) *NamespacedDockerCredential { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NamespacedDockerCredential").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NamespacedSSHAuthList is a list of NamespacedSSHAuth resources +type NamespacedSSHAuthList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NamespacedSSHAuth `json:"items"` +} + +func NewNamespacedSSHAuth(namespace, name string, obj NamespacedSSHAuth) *NamespacedSSHAuth { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NamespacedSSHAuth").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NamespacedServiceAccountTokenList is a list of NamespacedServiceAccountToken resources +type NamespacedServiceAccountTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NamespacedServiceAccountToken `json:"items"` +} + +func NewNamespacedServiceAccountToken(namespace, name string, obj NamespacedServiceAccountToken) *NamespacedServiceAccountToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NamespacedServiceAccountToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SSHAuthList is a list of SSHAuth resources +type SSHAuthList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []SSHAuth `json:"items"` +} + +func NewSSHAuth(namespace, name string, obj SSHAuth) *SSHAuth { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("SSHAuth").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ServiceAccountTokenList is a list of ServiceAccountToken resources +type ServiceAccountTokenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ServiceAccountToken `json:"items"` +} + +func NewServiceAccountToken(namespace, name string, obj ServiceAccountToken) *ServiceAccountToken { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ServiceAccountToken").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// WorkloadList is a list of Workload resources +type WorkloadList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Workload `json:"items"` +} + +func NewWorkload(namespace, name string, obj Workload) *Workload { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Workload").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_register.go new file mode 100644 index 0000000..f67bffc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/v3/zz_generated_register.go @@ -0,0 +1,96 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=project.cattle.io +package v3 + +import ( + project "github.com/rancher/rancher/pkg/apis/project.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + AppResourceName = "apps" + AppRevisionResourceName = "apprevisions" + BasicAuthResourceName = "basicauths" + CertificateResourceName = "certificates" + DockerCredentialResourceName = "dockercredentials" + NamespacedBasicAuthResourceName = "namespacedbasicauths" + NamespacedCertificateResourceName = "namespacedcertificates" + NamespacedDockerCredentialResourceName = "namespaceddockercredentials" + NamespacedSSHAuthResourceName = "namespacedsshauths" + NamespacedServiceAccountTokenResourceName = "namespacedserviceaccounttokens" + SSHAuthResourceName = "sshauths" + ServiceAccountTokenResourceName = "serviceaccounttokens" + WorkloadResourceName = "workloads" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: project.GroupName, Version: "v3"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &App{}, + &AppList{}, + &AppRevision{}, + &AppRevisionList{}, + &BasicAuth{}, + &BasicAuthList{}, + &Certificate{}, + &CertificateList{}, + &DockerCredential{}, + &DockerCredentialList{}, + &NamespacedBasicAuth{}, + &NamespacedBasicAuthList{}, + &NamespacedCertificate{}, + &NamespacedCertificateList{}, + &NamespacedDockerCredential{}, + &NamespacedDockerCredentialList{}, + &NamespacedSSHAuth{}, + &NamespacedSSHAuthList{}, + &NamespacedServiceAccountToken{}, + &NamespacedServiceAccountTokenList{}, + &SSHAuth{}, + &SSHAuthList{}, + &ServiceAccountToken{}, + &ServiceAccountTokenList{}, + &Workload{}, + &WorkloadList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..c320eca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/project.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package project + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "project.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/cluster.go new file mode 100644 index 0000000..9a6adb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/cluster.go @@ -0,0 +1,61 @@ +package v1 + +import ( + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/genericcondition" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type Cluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec ClusterSpec `json:"spec"` + Status ClusterStatus `json:"status,omitempty"` +} + +type ClusterSpec struct { + CloudCredentialSecretName string `json:"cloudCredentialSecretName,omitempty"` + KubernetesVersion string `json:"kubernetesVersion,omitempty"` + + ClusterAPIConfig *ClusterAPIConfig `json:"clusterAPIConfig,omitempty"` + RKEConfig *RKEConfig `json:"rkeConfig,omitempty"` + LocalClusterAuthEndpoint rkev1.LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint,omitempty"` + + AgentEnvVars []rkev1.EnvVar `json:"agentEnvVars,omitempty"` + ClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"clusterAgentDeploymentCustomization,omitempty"` + DefaultPodSecurityAdmissionConfigurationTemplateName string `json:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty"` + DefaultClusterRoleForProjectMembers string `json:"defaultClusterRoleForProjectMembers,omitempty" norman:"type=reference[roleTemplate]"` + EnableNetworkPolicy *bool `json:"enableNetworkPolicy,omitempty" norman:"default=false"` + FleetAgentDeploymentCustomization *AgentDeploymentCustomization `json:"fleetAgentDeploymentCustomization,omitempty"` + + RedeploySystemAgentGeneration int64 `json:"redeploySystemAgentGeneration,omitempty"` +} + +type AgentDeploymentCustomization struct { + AppendTolerations []v1.Toleration `json:"appendTolerations,omitempty"` + OverrideAffinity *v1.Affinity `json:"overrideAffinity,omitempty"` + OverrideResourceRequirements *v1.ResourceRequirements `json:"overrideResourceRequirements,omitempty"` +} + +type ClusterStatus struct { + Ready bool `json:"ready,omitempty"` + ClusterName string `json:"clusterName,omitempty"` + FleetWorkspaceName string `json:"fleetWorkspaceName,omitempty"` + ClientSecretName string `json:"clientSecretName,omitempty"` + AgentDeployed bool `json:"agentDeployed,omitempty"` + ObservedGeneration int64 `json:"observedGeneration"` + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` +} + +type ImportedConfig struct { + KubeConfigSecretName string `json:"kubeConfigSecretName,omitempty"` +} + +type ClusterAPIConfig struct { + ClusterName string `json:"clusterName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/doc.go new file mode 100644 index 0000000..85ef2f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=provisioning.cattle.io +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/rke.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/rke.go new file mode 100644 index 0000000..f76e95d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/rke.go @@ -0,0 +1,88 @@ +package v1 + +import ( + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +type RKEMachinePool struct { + rkev1.RKECommonNodeConfig + + Paused bool `json:"paused,omitempty"` + EtcdRole bool `json:"etcdRole,omitempty"` + ControlPlaneRole bool `json:"controlPlaneRole,omitempty"` + WorkerRole bool `json:"workerRole,omitempty"` + DrainBeforeDelete bool `json:"drainBeforeDelete,omitempty"` + DrainBeforeDeleteTimeout *metav1.Duration `json:"drainBeforeDeleteTimeout,omitempty"` + NodeConfig *corev1.ObjectReference `json:"machineConfigRef,omitempty" wrangler:"required"` + Name string `json:"name,omitempty" wrangler:"required"` + DisplayName string `json:"displayName,omitempty"` + Quantity *int32 `json:"quantity,omitempty"` + RollingUpdate *RKEMachinePoolRollingUpdate `json:"rollingUpdate,omitempty"` + MachineDeploymentLabels map[string]string `json:"machineDeploymentLabels,omitempty"` + MachineDeploymentAnnotations map[string]string `json:"machineDeploymentAnnotations,omitempty"` + NodeStartupTimeout *metav1.Duration `json:"nodeStartupTimeout,omitempty"` + UnhealthyNodeTimeout *metav1.Duration `json:"unhealthyNodeTimeout,omitempty"` + MaxUnhealthy *string `json:"maxUnhealthy,omitempty"` + UnhealthyRange *string `json:"unhealthyRange,omitempty"` + MachineOS string `json:"machineOS,omitempty"` + DynamicSchemaSpec string `json:"dynamicSchemaSpec,omitempty"` + HostnameLengthLimit int `json:"hostnameLengthLimit,omitempty"` +} + +type RKEMachinePoolRollingUpdate struct { + // The maximum number of machines that can be unavailable during the update. + // Value can be an absolute number (ex: 5) or a percentage of desired + // machines (ex: 10%). + // Absolute number is calculated from percentage by rounding down. + // This can not be 0 if MaxSurge is 0. + // Defaults to 0. + // Example: when this is set to 30%, the old MachineSet can be scaled + // down to 70% of desired machines immediately when the rolling update + // starts. Once new machines are ready, old MachineSet can be scaled + // down further, followed by scaling up the new MachineSet, ensuring + // that the total number of machines available at all times + // during the update is at least 70% of desired machines. + // +optional + MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + + // The maximum number of machines that can be scheduled above the + // desired number of machines. + // Value can be an absolute number (ex: 5) or a percentage of + // desired machines (ex: 10%). + // This can not be 0 if MaxUnavailable is 0. + // Absolute number is calculated from percentage by rounding up. + // Defaults to 1. + // Example: when this is set to 30%, the new MachineSet can be scaled + // up immediately when the rolling update starts, such that the total + // number of old and new machines do not exceed 130% of desired + // machines. Once old machines have been killed, new MachineSet can + // be scaled up further, ensuring that total number of machines running + // at any time during the update is at most 130% of desired machines. + // +optional + MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` +} + +// Note: if you add new fields to the RKEConfig, please ensure that you check +// `pkg/controllers/provisioningv2/rke2/provisioningcluster/template.go` file and +// drop the fields when saving a copy of the cluster spec on etcd snapshots, otherwise, +// operations using the new fields will cause unnecessary plan thrashing. + +type RKEConfig struct { + rkev1.RKEClusterSpecCommon + + ETCDSnapshotCreate *rkev1.ETCDSnapshotCreate `json:"etcdSnapshotCreate,omitempty"` + ETCDSnapshotRestore *rkev1.ETCDSnapshotRestore `json:"etcdSnapshotRestore,omitempty"` + RotateCertificates *rkev1.RotateCertificates `json:"rotateCertificates,omitempty"` + RotateEncryptionKeys *rkev1.RotateEncryptionKeys `json:"rotateEncryptionKeys,omitempty"` + + MachinePools []RKEMachinePool `json:"machinePools,omitempty"` + MachinePoolDefaults RKEMachinePoolDefaults `json:"machinePoolDefaults,omitempty"` + InfrastructureRef *corev1.ObjectReference `json:"infrastructureRef,omitempty"` +} + +type RKEMachinePoolDefaults struct { + HostnameLengthLimit int `json:"hostnameLengthLimit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_deepcopy.go new file mode 100644 index 0000000..235c3e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_deepcopy.go @@ -0,0 +1,388 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + rkecattleiov1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + genericcondition "github.com/rancher/wrangler/v3/pkg/genericcondition" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + intstr "k8s.io/apimachinery/pkg/util/intstr" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AgentDeploymentCustomization) DeepCopyInto(out *AgentDeploymentCustomization) { + *out = *in + if in.AppendTolerations != nil { + in, out := &in.AppendTolerations, &out.AppendTolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OverrideAffinity != nil { + in, out := &in.OverrideAffinity, &out.OverrideAffinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.OverrideResourceRequirements != nil { + in, out := &in.OverrideResourceRequirements, &out.OverrideResourceRequirements + *out = new(corev1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentDeploymentCustomization. +func (in *AgentDeploymentCustomization) DeepCopy() *AgentDeploymentCustomization { + if in == nil { + return nil + } + out := new(AgentDeploymentCustomization) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cluster) DeepCopyInto(out *Cluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. +func (in *Cluster) DeepCopy() *Cluster { + if in == nil { + return nil + } + out := new(Cluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterAPIConfig) DeepCopyInto(out *ClusterAPIConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterAPIConfig. +func (in *ClusterAPIConfig) DeepCopy() *ClusterAPIConfig { + if in == nil { + return nil + } + out := new(ClusterAPIConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterList) DeepCopyInto(out *ClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. +func (in *ClusterList) DeepCopy() *ClusterList { + if in == nil { + return nil + } + out := new(ClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in + if in.ClusterAPIConfig != nil { + in, out := &in.ClusterAPIConfig, &out.ClusterAPIConfig + *out = new(ClusterAPIConfig) + **out = **in + } + if in.RKEConfig != nil { + in, out := &in.RKEConfig, &out.RKEConfig + *out = new(RKEConfig) + (*in).DeepCopyInto(*out) + } + out.LocalClusterAuthEndpoint = in.LocalClusterAuthEndpoint + if in.AgentEnvVars != nil { + in, out := &in.AgentEnvVars, &out.AgentEnvVars + *out = make([]rkecattleiov1.EnvVar, len(*in)) + copy(*out, *in) + } + if in.ClusterAgentDeploymentCustomization != nil { + in, out := &in.ClusterAgentDeploymentCustomization, &out.ClusterAgentDeploymentCustomization + *out = new(AgentDeploymentCustomization) + (*in).DeepCopyInto(*out) + } + if in.EnableNetworkPolicy != nil { + in, out := &in.EnableNetworkPolicy, &out.EnableNetworkPolicy + *out = new(bool) + **out = **in + } + if in.FleetAgentDeploymentCustomization != nil { + in, out := &in.FleetAgentDeploymentCustomization, &out.FleetAgentDeploymentCustomization + *out = new(AgentDeploymentCustomization) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImportedConfig) DeepCopyInto(out *ImportedConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImportedConfig. +func (in *ImportedConfig) DeepCopy() *ImportedConfig { + if in == nil { + return nil + } + out := new(ImportedConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEConfig) DeepCopyInto(out *RKEConfig) { + *out = *in + in.RKEClusterSpecCommon.DeepCopyInto(&out.RKEClusterSpecCommon) + if in.ETCDSnapshotCreate != nil { + in, out := &in.ETCDSnapshotCreate, &out.ETCDSnapshotCreate + *out = new(rkecattleiov1.ETCDSnapshotCreate) + **out = **in + } + if in.ETCDSnapshotRestore != nil { + in, out := &in.ETCDSnapshotRestore, &out.ETCDSnapshotRestore + *out = new(rkecattleiov1.ETCDSnapshotRestore) + **out = **in + } + if in.RotateCertificates != nil { + in, out := &in.RotateCertificates, &out.RotateCertificates + *out = new(rkecattleiov1.RotateCertificates) + (*in).DeepCopyInto(*out) + } + if in.RotateEncryptionKeys != nil { + in, out := &in.RotateEncryptionKeys, &out.RotateEncryptionKeys + *out = new(rkecattleiov1.RotateEncryptionKeys) + **out = **in + } + if in.MachinePools != nil { + in, out := &in.MachinePools, &out.MachinePools + *out = make([]RKEMachinePool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.MachinePoolDefaults = in.MachinePoolDefaults + if in.InfrastructureRef != nil { + in, out := &in.InfrastructureRef, &out.InfrastructureRef + *out = new(corev1.ObjectReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEConfig. +func (in *RKEConfig) DeepCopy() *RKEConfig { + if in == nil { + return nil + } + out := new(RKEConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEMachinePool) DeepCopyInto(out *RKEMachinePool) { + *out = *in + in.RKECommonNodeConfig.DeepCopyInto(&out.RKECommonNodeConfig) + if in.DrainBeforeDeleteTimeout != nil { + in, out := &in.DrainBeforeDeleteTimeout, &out.DrainBeforeDeleteTimeout + *out = new(metav1.Duration) + **out = **in + } + if in.NodeConfig != nil { + in, out := &in.NodeConfig, &out.NodeConfig + *out = new(corev1.ObjectReference) + **out = **in + } + if in.Quantity != nil { + in, out := &in.Quantity, &out.Quantity + *out = new(int32) + **out = **in + } + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RKEMachinePoolRollingUpdate) + (*in).DeepCopyInto(*out) + } + if in.MachineDeploymentLabels != nil { + in, out := &in.MachineDeploymentLabels, &out.MachineDeploymentLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MachineDeploymentAnnotations != nil { + in, out := &in.MachineDeploymentAnnotations, &out.MachineDeploymentAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.NodeStartupTimeout != nil { + in, out := &in.NodeStartupTimeout, &out.NodeStartupTimeout + *out = new(metav1.Duration) + **out = **in + } + if in.UnhealthyNodeTimeout != nil { + in, out := &in.UnhealthyNodeTimeout, &out.UnhealthyNodeTimeout + *out = new(metav1.Duration) + **out = **in + } + if in.MaxUnhealthy != nil { + in, out := &in.MaxUnhealthy, &out.MaxUnhealthy + *out = new(string) + **out = **in + } + if in.UnhealthyRange != nil { + in, out := &in.UnhealthyRange, &out.UnhealthyRange + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEMachinePool. +func (in *RKEMachinePool) DeepCopy() *RKEMachinePool { + if in == nil { + return nil + } + out := new(RKEMachinePool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEMachinePoolDefaults) DeepCopyInto(out *RKEMachinePoolDefaults) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEMachinePoolDefaults. +func (in *RKEMachinePoolDefaults) DeepCopy() *RKEMachinePoolDefaults { + if in == nil { + return nil + } + out := new(RKEMachinePoolDefaults) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEMachinePoolRollingUpdate) DeepCopyInto(out *RKEMachinePoolRollingUpdate) { + *out = *in + if in.MaxUnavailable != nil { + in, out := &in.MaxUnavailable, &out.MaxUnavailable + *out = new(intstr.IntOrString) + **out = **in + } + if in.MaxSurge != nil { + in, out := &in.MaxSurge, &out.MaxSurge + *out = new(intstr.IntOrString) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEMachinePoolRollingUpdate. +func (in *RKEMachinePoolRollingUpdate) DeepCopy() *RKEMachinePoolRollingUpdate { + if in == nil { + return nil + } + out := new(RKEMachinePoolRollingUpdate) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_list_types.go new file mode 100644 index 0000000..bbc8497 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_list_types.go @@ -0,0 +1,42 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=provisioning.cattle.io +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterList is a list of Cluster resources +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Cluster `json:"items"` +} + +func NewCluster(namespace, name string, obj Cluster) *Cluster { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("Cluster").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_register.go new file mode 100644 index 0000000..8a4e09b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/v1/zz_generated_register.go @@ -0,0 +1,60 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=provisioning.cattle.io +package v1 + +import ( + provisioning "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + ClusterResourceName = "clusters" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: provisioning.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Cluster{}, + &ClusterList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..13b532b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/provisioning.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package provisioning + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "provisioning.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/bootstrap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/bootstrap.go new file mode 100644 index 0000000..105e507 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/bootstrap.go @@ -0,0 +1,44 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RKEBootstrap struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec RKEBootstrapSpec `json:"spec"` + Status RKEBootstrapStatus `json:"status,omitempty"` +} + +type RKEBootstrapSpec struct { + ClusterName string `json:"clusterName,omitempty"` +} + +type RKEBootstrapStatus struct { + // Ready indicates the BootstrapData field is ready to be consumed + Ready bool `json:"ready,omitempty"` + + // DataSecretName is the name of the secret that stores the bootstrap data script. + // +optional + DataSecretName *string `json:"dataSecretName,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RKEBootstrapTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec RKEBootstrapTemplateSpec `json:"spec" wrangler:"required"` +} + +type RKEBootstrapTemplateSpec struct { + ClusterName string `json:"clusterName,omitempty"` + Template RKEBootstrap `json:"template,omitempty" wrangler:"required"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/certificaterotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/certificaterotation.go new file mode 100644 index 0000000..0a1f79b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/certificaterotation.go @@ -0,0 +1,6 @@ +package v1 + +type RotateCertificates struct { + Generation int64 `json:"generation,omitempty"` + Services []string `json:"services,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/cluster.go new file mode 100644 index 0000000..237d00f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/cluster.go @@ -0,0 +1,171 @@ +package v1 + +import ( + "github.com/rancher/wrangler/v3/pkg/genericcondition" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RKECluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec RKEClusterSpec `json:"spec"` + Status RKEClusterStatus `json:"status,omitempty"` +} + +type RKEClusterStatus struct { + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` + Ready bool `json:"ready,omitempty"` +} + +type NetworkingStackPreference string + +const ( + // DualStackPreference signifies a dual stack networking strategy, defaulting "localhost" for communication on the + // loopback interface + DualStackPreference = NetworkingStackPreference("dual") + + // SingleStackIPv4Preference signifies a single stack IPv4 networking strategy, defaulting "127.0.0.1" for + // communication on the loopback interface + SingleStackIPv4Preference = NetworkingStackPreference("ipv4") + + // SingleStackIPv6Preference signifies a single stack IPv6 networking strategy, defaulting "::1" for + // communication on the loopback interface + SingleStackIPv6Preference = NetworkingStackPreference("ipv6") + + // DefaultStackPreference is the stack preference used when no preference is defined, or is invalid. Defaults to + // "127.0.0.1" to support existing behavior. + DefaultStackPreference = SingleStackIPv4Preference +) + +// Networking contains information regarding the desired and actual networking stack of the cluster. +type Networking struct { + // Specifies which networking stack to prefer for external cluster communication. In practice, this is used by the + // planner to render the various probes to force IPv4, IPv6, or default to localhost. There is currently no + // sanitization or validation as cluster configuration can be specified with machineGlobalConfig and + // machineSelectorConfig, which although easy to instrument to determine a potential interface, user defined + // configuration can be specified in the `/etc/rancher//config.yaml.d` directory either manually or via + // cloud-init, and there is currently no mechanism to extract the completely rendered configuration via the planner + // nor various engines themselves. + StackPreference NetworkingStackPreference `json:"stackPreference,omitempty"` +} + +type DataDirectories struct { + // Data directory for the system-agent connection info and plans + SystemAgent string `json:"systemAgent,omitempty"` + // Data directory for provisioning related files (idempotency) + Provisioning string `json:"provisioning,omitempty"` + // Data directory for the k8s distro + K8sDistro string `json:"k8sDistro,omitempty"` +} + +type RKEClusterSpecCommon struct { + UpgradeStrategy ClusterUpgradeStrategy `json:"upgradeStrategy,omitempty"` + ChartValues GenericMap `json:"chartValues,omitempty" wrangler:"nullable"` + MachineGlobalConfig GenericMap `json:"machineGlobalConfig,omitempty" wrangler:"nullable"` + MachineSelectorConfig []RKESystemConfig `json:"machineSelectorConfig,omitempty"` + MachineSelectorFiles []RKEProvisioningFiles `json:"machineSelectorFiles,omitempty"` + AdditionalManifest string `json:"additionalManifest,omitempty"` + Registries *Registry `json:"registries,omitempty"` + ETCD *ETCD `json:"etcd,omitempty"` + + // Networking contains information regarding the desired and actual networking stack of the cluster. + Networking *Networking `json:"networking,omitempty"` + + // DataDirectories contains the configuration for the data directories typically stored within /var/lib/rancher. + DataDirectories DataDirectories `json:"dataDirectories,omitempty"` + + // Increment to force all nodes to re-provision + ProvisionGeneration int `json:"provisionGeneration,omitempty"` +} + +type LocalClusterAuthEndpoint struct { + Enabled bool `json:"enabled,omitempty"` + FQDN string `json:"fqdn,omitempty"` + CACerts string `json:"caCerts,omitempty"` +} + +type RKESystemConfig struct { + MachineLabelSelector *metav1.LabelSelector `json:"machineLabelSelector,omitempty"` + Config GenericMap `json:"config,omitempty" wrangler:"nullable"` +} + +type RKEProvisioningFiles struct { + MachineLabelSelector *metav1.LabelSelector `json:"machineLabelSelector,omitempty"` + FileSources []ProvisioningFileSource `json:"fileSources,omitempty"` +} + +type RKEClusterSpec struct { + // Not used in anyway, just here to make cluster-api happy + ControlPlaneEndpoint *capi.APIEndpoint `json:"controlPlaneEndpoint,omitempty"` +} + +type ClusterUpgradeStrategy struct { + // How many controlplane nodes should be upgrade at time, defaults to 1, 0 is infinite. Percentages are + // accepted too. + ControlPlaneConcurrency string `json:"controlPlaneConcurrency,omitempty"` + ControlPlaneDrainOptions DrainOptions `json:"controlPlaneDrainOptions,omitempty"` + + // How many workers should be upgraded at a time + WorkerConcurrency string `json:"workerConcurrency,omitempty"` + WorkerDrainOptions DrainOptions `json:"workerDrainOptions,omitempty"` +} + +type DrainOptions struct { + // Enable will require nodes be drained before upgrade + Enabled bool `json:"enabled"` + // Drain node even if there are pods not managed by a ReplicationController, Job, or DaemonSet + // Drain will not proceed without Force set to true if there are such pods + Force bool `json:"force"` + // If there are DaemonSet-managed pods, drain will not proceed without IgnoreDaemonSets set to true + // (even when set to true, kubectl won't delete pods - so setting default to true) + IgnoreDaemonSets *bool `json:"ignoreDaemonSets"` + // IgnoreErrors Ignore errors occurred between drain nodes in group + IgnoreErrors bool `json:"ignoreErrors"` + // Continue even if there are pods using emptyDir + DeleteEmptyDirData bool `json:"deleteEmptyDirData"` + // DisableEviction forces drain to use delete rather than evict + DisableEviction bool `json:"disableEviction"` + // Period of time in seconds given to each pod to terminate gracefully. + // If negative, the default value specified in the pod will be used + GracePeriod int `json:"gracePeriod"` + // Time to wait (in seconds) before giving up for one try + Timeout int `json:"timeout"` + // SkipWaitForDeleteTimeoutSeconds If pod DeletionTimestamp older than N seconds, skip waiting for the pod. Seconds must be greater than 0 to skip. + SkipWaitForDeleteTimeoutSeconds int `json:"skipWaitForDeleteTimeoutSeconds"` + + // PreDrainHooks A list of hooks to run prior to draining a node + PreDrainHooks []DrainHook `json:"preDrainHooks"` + // PostDrainHook A list of hooks to run after draining AND UPDATING a node + PostDrainHooks []DrainHook `json:"postDrainHooks"` +} + +type DrainHook struct { + // Annotation This annotation will need to be populated on the machine-plan secret with the value from the annotation + // "rke.cattle.io/pre-drain" before the planner will continue with drain the specific node. The annotation + // "rke.cattle.io/pre-drain" is used for pre-drain and "rke.cattle.io/post-drain" is used for post drain. + Annotation string `json:"annotation,omitempty"` +} + +type ProvisioningFileSource struct { + Secret K8sObjectFileSource `json:"secret,omitempty"` + ConfigMap K8sObjectFileSource `json:"configMap,omitempty"` +} + +type K8sObjectFileSource struct { + Name string `json:"name"` + Items []KeyToPath `json:"items,omitempty"` + DefaultPermissions string `json:"defaultPermissions,omitempty"` +} + +type KeyToPath struct { + Key string `json:"key"` + Path string `json:"path"` + Dynamic bool `json:"dynamic,omitempty"` + Permissions string `json:"permissions,omitempty"` + Hash string `json:"hash,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/controlplane.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/controlplane.go new file mode 100644 index 0000000..7748e4c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/controlplane.go @@ -0,0 +1,55 @@ +package v1 + +import ( + "github.com/rancher/wrangler/v3/pkg/genericcondition" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type RKEControlPlane struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec RKEControlPlaneSpec `json:"spec"` + Status RKEControlPlaneStatus `json:"status,omitempty"` +} + +type EnvVar struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` +} + +type RKEControlPlaneSpec struct { + RKEClusterSpecCommon + + AgentEnvVars []EnvVar `json:"agentEnvVars,omitempty"` + LocalClusterAuthEndpoint LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint"` + ETCDSnapshotCreate *ETCDSnapshotCreate `json:"etcdSnapshotCreate,omitempty"` + ETCDSnapshotRestore *ETCDSnapshotRestore `json:"etcdSnapshotRestore,omitempty"` + RotateCertificates *RotateCertificates `json:"rotateCertificates,omitempty"` + RotateEncryptionKeys *RotateEncryptionKeys `json:"rotateEncryptionKeys,omitempty"` + KubernetesVersion string `json:"kubernetesVersion,omitempty"` + ClusterName string `json:"clusterName,omitempty" wrangler:"required"` + ManagementClusterName string `json:"managementClusterName,omitempty" wrangler:"required"` + UnmanagedConfig bool `json:"unmanagedConfig,omitempty"` +} + +type RKEControlPlaneStatus struct { + AppliedSpec *RKEControlPlaneSpec `json:"appliedSpec,omitempty"` + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` + Ready bool `json:"ready,omitempty"` + ObservedGeneration int64 `json:"observedGeneration"` + CertificateRotationGeneration int64 `json:"certificateRotationGeneration"` + RotateEncryptionKeys *RotateEncryptionKeys `json:"rotateEncryptionKeys,omitempty"` + RotateEncryptionKeysPhase RotateEncryptionKeysPhase `json:"rotateEncryptionKeysPhase,omitempty"` + RotateEncryptionKeysLeader string `json:"rotateEncryptionKeysLeader,omitempty"` + ETCDSnapshotRestore *ETCDSnapshotRestore `json:"etcdSnapshotRestore,omitempty"` + ETCDSnapshotRestorePhase ETCDSnapshotPhase `json:"etcdSnapshotRestorePhase,omitempty"` + ETCDSnapshotCreate *ETCDSnapshotCreate `json:"etcdSnapshotCreate,omitempty"` + ETCDSnapshotCreatePhase ETCDSnapshotPhase `json:"etcdSnapshotCreatePhase,omitempty"` + ConfigGeneration int64 `json:"configGeneration,omitempty"` + Initialized bool `json:"initialized,omitempty"` + AgentConnected bool `json:"agentConnected,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/doc.go new file mode 100644 index 0000000..e7bb664 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=rke.cattle.io +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/encryptionkeyrotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/encryptionkeyrotation.go new file mode 100644 index 0000000..d0168af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/encryptionkeyrotation.go @@ -0,0 +1,18 @@ +package v1 + +type RotateEncryptionKeysPhase string + +const ( + RotateEncryptionKeysPhasePrepare RotateEncryptionKeysPhase = "Prepare" + RotateEncryptionKeysPhasePostPrepareRestart RotateEncryptionKeysPhase = "PostPrepareRestart" + RotateEncryptionKeysPhaseRotate RotateEncryptionKeysPhase = "Rotate" + RotateEncryptionKeysPhasePostRotateRestart RotateEncryptionKeysPhase = "PostRotateRestart" + RotateEncryptionKeysPhaseReencrypt RotateEncryptionKeysPhase = "Reencrypt" + RotateEncryptionKeysPhasePostReencryptRestart RotateEncryptionKeysPhase = "PostReencryptRestart" + RotateEncryptionKeysPhaseDone RotateEncryptionKeysPhase = "Done" + RotateEncryptionKeysPhaseFailed RotateEncryptionKeysPhase = "Failed" +) + +type RotateEncryptionKeys struct { + Generation int64 `json:"generation,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/etcd.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/etcd.go new file mode 100644 index 0000000..8b42260 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/etcd.go @@ -0,0 +1,81 @@ +package v1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +type ETCDSnapshotPhase string + +const ( + ETCDSnapshotPhaseStarted ETCDSnapshotPhase = "Started" + ETCDSnapshotPhaseShutdown ETCDSnapshotPhase = "Shutdown" + ETCDSnapshotPhaseRestore ETCDSnapshotPhase = "Restore" + ETCDSnapshotPhasePostRestorePodCleanup ETCDSnapshotPhase = "PostRestorePodCleanup" + ETCDSnapshotPhaseInitialRestartCluster ETCDSnapshotPhase = "InitialRestartCluster" + ETCDSnapshotPhasePostRestoreNodeCleanup ETCDSnapshotPhase = "PostRestoreNodeCleanup" + ETCDSnapshotPhaseRestartCluster ETCDSnapshotPhase = "RestartCluster" + ETCDSnapshotPhaseFinished ETCDSnapshotPhase = "Finished" + ETCDSnapshotPhaseFailed ETCDSnapshotPhase = "Failed" +) + +type ETCDSnapshotS3 struct { + Endpoint string `json:"endpoint,omitempty"` + EndpointCA string `json:"endpointCA,omitempty"` + SkipSSLVerify bool `json:"skipSSLVerify,omitempty"` + Bucket string `json:"bucket,omitempty"` + Region string `json:"region,omitempty"` + CloudCredentialName string `json:"cloudCredentialName,omitempty"` + Folder string `json:"folder,omitempty"` +} + +type ETCDSnapshotCreate struct { + // Changing the Generation is the only thing required to initiate a snapshot creation. + Generation int `json:"generation,omitempty"` +} + +type ETCDSnapshotRestore struct { + // Name refers to the name of the associated etcdsnapshot object + Name string `json:"name,omitempty"` + + // Changing the Generation is the only thing required to initiate a snapshot restore. + Generation int `json:"generation,omitempty"` + // Set to either none (or empty string), all, or kubernetesVersion + RestoreRKEConfig string `json:"restoreRKEConfig,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ETCDSnapshot struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec ETCDSnapshotSpec `json:"spec,omitempty"` + SnapshotFile ETCDSnapshotFile `json:"snapshotFile,omitempty"` + Status ETCDSnapshotStatus `json:"status"` +} + +type ETCDSnapshotSpec struct { + ClusterName string `json:"clusterName,omitempty"` +} + +type ETCDSnapshotFile struct { + Name string `json:"name,omitempty"` + NodeName string `json:"nodeName,omitempty"` + Location string `json:"location,omitempty"` + Metadata string `json:"metadata,omitempty"` + CreatedAt *metav1.Time `json:"createdAt,omitempty"` + Size int64 `json:"size,omitempty"` + S3 *ETCDSnapshotS3 `json:"s3,omitempty"` + Status string `json:"status,omitempty"` + Message string `json:"message,omitempty"` +} + +type ETCDSnapshotStatus struct { + Missing bool `json:"missing"` +} + +type ETCD struct { + DisableSnapshots bool `json:"disableSnapshots,omitempty"` + SnapshotScheduleCron string `json:"snapshotScheduleCron,omitempty"` + SnapshotRetention int `json:"snapshotRetention,omitempty"` + S3 *ETCDSnapshotS3 `json:"s3,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/machine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/machine.go new file mode 100644 index 0000000..839b582 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/machine.go @@ -0,0 +1,48 @@ +package v1 + +import ( + "github.com/rancher/wrangler/v3/pkg/genericcondition" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type RKECommonNodeConfig struct { + Labels map[string]string `json:"labels,omitempty"` + Taints []corev1.Taint `json:"taints,omitempty"` + CloudCredentialSecretName string `json:"cloudCredentialSecretName,omitempty"` +} + +type RKEMachineStatus struct { + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` + JobName string `json:"jobName,omitempty"` + Ready bool `json:"ready,omitempty"` + DriverHash string `json:"driverHash,omitempty"` + DriverURL string `json:"driverUrl,omitempty"` + CloudCredentialSecretName string `json:"cloudCredentialSecretName,omitempty"` + FailureReason string `json:"failureReason,omitempty"` + FailureMessage string `json:"failureMessage,omitempty"` + Addresses []capi.MachineAddress `json:"addresses,omitempty"` +} + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type CustomMachine struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CustomMachineSpec `json:"spec,omitempty"` + Status CustomMachineStatus `json:"status,omitempty"` +} + +type CustomMachineSpec struct { + ProviderID string `json:"providerID,omitempty"` +} + +type CustomMachineStatus struct { + Conditions []genericcondition.GenericCondition `json:"conditions,omitempty"` + Ready bool `json:"ready,omitempty"` + Addresses []capi.MachineAddress `json:"addresses,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/map.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/map.go new file mode 100644 index 0000000..4ada1ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/map.go @@ -0,0 +1,27 @@ +package v1 + +import ( + "encoding/json" + + "github.com/rancher/wrangler/v3/pkg/data/convert" +) + +type GenericMap struct { + Data map[string]interface{} `json:"-"` +} + +func (in GenericMap) MarshalJSON() ([]byte, error) { + return json.Marshal(in.Data) +} + +func (in *GenericMap) UnmarshalJSON(data []byte) error { + in.Data = map[string]interface{}{} + return json.Unmarshal(data, &in.Data) +} + +func (in *GenericMap) DeepCopyInto(out *GenericMap) { + out.Data = map[string]interface{}{} + if err := convert.ToObj(in.Data, &out.Data); err != nil { + panic(err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/plan.go new file mode 100644 index 0000000..068f3a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/plan.go @@ -0,0 +1,82 @@ +package plan + +import capi "sigs.k8s.io/cluster-api/api/v1beta1" + +type Plan struct { + Nodes map[string]*Node `json:"nodes,omitempty"` + Machines map[string]*capi.Machine `json:"machines,omitempty"` + Metadata map[string]*Metadata `json:"metadata,omitempty"` +} + +type Metadata struct { + Labels map[string]string `json:"labels,omitempty"` + Annotations map[string]string `json:"annotations,omitempty"` +} + +type ProbeStatus struct { + Healthy bool `json:"healthy,omitempty"` + SuccessCount int `json:"successCount,omitempty"` + FailureCount int `json:"failureCount,omitempty"` +} + +type Node struct { + Plan NodePlan `json:"plan,omitempty"` + AppliedPlan *NodePlan `json:"appliedPlan,omitempty"` + JoinedTo string `json:"joinedTo,omitempty"` + Output map[string][]byte `json:"-"` + PeriodicOutput map[string]PeriodicInstructionOutput `json:"-"` + Failed bool `json:"failed,omitempty"` + InSync bool `json:"inSync,omitempty"` + Healthy bool `json:"healthy,omitempty"` + PlanDataExists bool `json:"planDataExists,omitempty"` + ProbeStatus map[string]ProbeStatus `json:"probeStatus,omitempty"` + ProbesUsable bool `json:"probesUsable,omitempty"` // ProbesUsable indicates that the probes have passed at least once for the appliedPlan +} + +type PeriodicInstructionOutput struct { + Name string `json:"name"` + Stdout []byte `json:"stdout"` // Stdout is a byte array of the gzip+base64 stdout output + Stderr []byte `json:"stderr"` // Stderr is a byte array of the gzip+base64 stderr output + ExitCode int `json:"exitCode"` // ExitCode is an int representing the exit code of the last run instruction + LastSuccessfulRunTime string `json:"lastSuccessfulRunTime"` // LastSuccessfulRunTime is a time.UnixDate formatted string of the last time the instruction was run +} + +type Secret struct { + ServerToken string `json:"serverToken,omitempty"` + AgentToken string `json:"agentToken,omitempty"` +} + +type OneTimeInstruction struct { + Name string `json:"name,omitempty"` + Image string `json:"image,omitempty"` + Env []string `json:"env,omitempty"` + Args []string `json:"args,omitempty"` + Command string `json:"command,omitempty"` + SaveOutput bool `json:"saveOutput,omitempty"` +} + +type PeriodicInstruction struct { + Name string `json:"name,omitempty"` + Image string `json:"image,omitempty"` + Env []string `json:"env,omitempty"` + Args []string `json:"args,omitempty"` + Command string `json:"command,omitempty"` + PeriodSeconds int `json:"periodSeconds,omitempty"` // default 600, i.e. 10 minutes +} + +type File struct { + Content string `json:"content,omitempty"` + Path string `json:"path,omitempty"` + Permissions string `json:"permissions,omitempty"` + Dynamic bool `json:"dynamic,omitempty"` + Minor bool `json:"minor,omitempty"` // minor signifies that the file can be changed on a node without having to cause a full-blown drain/cordon operation +} + +// NodePlan is the struct used to deliver instructions/files/probes to the system-agent, and retrieve feedback +type NodePlan struct { + Files []File `json:"files,omitempty"` + Instructions []OneTimeInstruction `json:"instructions,omitempty"` + PeriodicInstructions []PeriodicInstruction `json:"periodicInstructions,omitempty"` + Error string `json:"error,omitempty"` + Probes map[string]Probe `json:"probes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/probe.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/probe.go new file mode 100644 index 0000000..5702a98 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/plan/probe.go @@ -0,0 +1,18 @@ +package plan + +type HTTPGetAction struct { + URL string `json:"url,omitempty"` + Insecure bool `json:"insecure,omitempty"` + ClientCert string `json:"clientCert,omitempty"` + ClientKey string `json:"clientKey,omitempty"` + CACert string `json:"caCert,omitempty"` +} + +type Probe struct { + Name string `json:"name,omitempty"` + InitialDelaySeconds int `json:"initialDelaySeconds,omitempty"` // default 0 + TimeoutSeconds int `json:"timeoutSeconds,omitempty"` // default 1 + SuccessThreshold int `json:"successThreshold,omitempty"` // default 1 + FailureThreshold int `json:"failureThreshold,omitempty"` // default 3 + HTTPGetAction HTTPGetAction `json:"httpGet,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/registries.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/registries.go new file mode 100644 index 0000000..2ba4a54 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/registries.go @@ -0,0 +1,59 @@ +package v1 + +// Mirror contains the config related to the registry mirror +type Mirror struct { + // Endpoints are endpoints for a namespace. CRI plugin will try the endpoints + // one by one until a working one is found. The endpoint must be a valid url + // with host specified. + // The scheme, host and path from the endpoint URL will be used. + Endpoints []string `json:"endpoint,omitempty"` + + // Rewrites are repository rewrite rules for a namespace. When fetching image resources + // from an endpoint and a key matches the repository via regular expression matching + // it will be replaced with the corresponding value from the map in the resource request. + Rewrites map[string]string `json:"rewrite,omitempty"` +} + +const ( + AuthConfigSecretType = "rke.cattle.io/auth-config" + + UsernameAuthConfigSecretKey = "username" + PasswordAuthConfigSecretKey = "password" + AuthAuthConfigSecretKey = "auth" + IdentityTokenAuthConfigSecretKey = "identityToken" +) + +// AuthConfig contains the config related to authentication to a specific registry +type AuthConfig struct { + // Username is the username to login the registry. + Username string `json:"username,omitempty"` + // Password is the password to login the registry. + Password string `json:"password,omitempty"` + // Auth is a base64 encoded string from the concatenation of the username, + // a colon, and the password. + Auth string `json:"auth,omitempty"` + // IdentityToken is used to authenticate the user and get + // an access token for the registry. + IdentityToken string `json:"identityToken,omitempty"` +} + +// Registry is registry settings configured +type Registry struct { + // Mirrors are namespace to mirror mapping for all namespaces. + Mirrors map[string]Mirror `json:"mirrors,omitempty"` + // Configs are configs for each registry. + // The key is the FDQN or IP of the registry. + Configs map[string]RegistryConfig `json:"configs,omitempty"` +} + +// RegistryConfig contains configuration used to communicate with the registry. +type RegistryConfig struct { + // Auth contains information to authenticate to the registry. + AuthConfigSecretName string `json:"authConfigSecretName,omitempty"` + // TLS is a pair of Cert/Key which then are used when creating the transport + // that communicates with the registry. + TLSSecretName string `json:"tlsSecretName,omitempty"` + CABundle []byte `json:"caBundle,omitempty"` + + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_deepcopy.go new file mode 100644 index 0000000..26a207f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_deepcopy.go @@ -0,0 +1,1225 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + genericcondition "github.com/rancher/wrangler/v3/pkg/genericcondition" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthConfig) DeepCopyInto(out *AuthConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthConfig. +func (in *AuthConfig) DeepCopy() *AuthConfig { + if in == nil { + return nil + } + out := new(AuthConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterUpgradeStrategy) DeepCopyInto(out *ClusterUpgradeStrategy) { + *out = *in + in.ControlPlaneDrainOptions.DeepCopyInto(&out.ControlPlaneDrainOptions) + in.WorkerDrainOptions.DeepCopyInto(&out.WorkerDrainOptions) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterUpgradeStrategy. +func (in *ClusterUpgradeStrategy) DeepCopy() *ClusterUpgradeStrategy { + if in == nil { + return nil + } + out := new(ClusterUpgradeStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomMachine) DeepCopyInto(out *CustomMachine) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMachine. +func (in *CustomMachine) DeepCopy() *CustomMachine { + if in == nil { + return nil + } + out := new(CustomMachine) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CustomMachine) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomMachineList) DeepCopyInto(out *CustomMachineList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CustomMachine, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMachineList. +func (in *CustomMachineList) DeepCopy() *CustomMachineList { + if in == nil { + return nil + } + out := new(CustomMachineList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CustomMachineList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomMachineSpec) DeepCopyInto(out *CustomMachineSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMachineSpec. +func (in *CustomMachineSpec) DeepCopy() *CustomMachineSpec { + if in == nil { + return nil + } + out := new(CustomMachineSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CustomMachineStatus) DeepCopyInto(out *CustomMachineStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]v1beta1.MachineAddress, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomMachineStatus. +func (in *CustomMachineStatus) DeepCopy() *CustomMachineStatus { + if in == nil { + return nil + } + out := new(CustomMachineStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DataDirectories) DeepCopyInto(out *DataDirectories) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataDirectories. +func (in *DataDirectories) DeepCopy() *DataDirectories { + if in == nil { + return nil + } + out := new(DataDirectories) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DrainHook) DeepCopyInto(out *DrainHook) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DrainHook. +func (in *DrainHook) DeepCopy() *DrainHook { + if in == nil { + return nil + } + out := new(DrainHook) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DrainOptions) DeepCopyInto(out *DrainOptions) { + *out = *in + if in.IgnoreDaemonSets != nil { + in, out := &in.IgnoreDaemonSets, &out.IgnoreDaemonSets + *out = new(bool) + **out = **in + } + if in.PreDrainHooks != nil { + in, out := &in.PreDrainHooks, &out.PreDrainHooks + *out = make([]DrainHook, len(*in)) + copy(*out, *in) + } + if in.PostDrainHooks != nil { + in, out := &in.PostDrainHooks, &out.PostDrainHooks + *out = make([]DrainHook, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DrainOptions. +func (in *DrainOptions) DeepCopy() *DrainOptions { + if in == nil { + return nil + } + out := new(DrainOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCD) DeepCopyInto(out *ETCD) { + *out = *in + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(ETCDSnapshotS3) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCD. +func (in *ETCD) DeepCopy() *ETCD { + if in == nil { + return nil + } + out := new(ETCD) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshot) DeepCopyInto(out *ETCDSnapshot) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.SnapshotFile.DeepCopyInto(&out.SnapshotFile) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshot. +func (in *ETCDSnapshot) DeepCopy() *ETCDSnapshot { + if in == nil { + return nil + } + out := new(ETCDSnapshot) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ETCDSnapshot) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotCreate) DeepCopyInto(out *ETCDSnapshotCreate) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotCreate. +func (in *ETCDSnapshotCreate) DeepCopy() *ETCDSnapshotCreate { + if in == nil { + return nil + } + out := new(ETCDSnapshotCreate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotFile) DeepCopyInto(out *ETCDSnapshotFile) { + *out = *in + if in.CreatedAt != nil { + in, out := &in.CreatedAt, &out.CreatedAt + *out = (*in).DeepCopy() + } + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(ETCDSnapshotS3) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotFile. +func (in *ETCDSnapshotFile) DeepCopy() *ETCDSnapshotFile { + if in == nil { + return nil + } + out := new(ETCDSnapshotFile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotList) DeepCopyInto(out *ETCDSnapshotList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ETCDSnapshot, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotList. +func (in *ETCDSnapshotList) DeepCopy() *ETCDSnapshotList { + if in == nil { + return nil + } + out := new(ETCDSnapshotList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ETCDSnapshotList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotRestore) DeepCopyInto(out *ETCDSnapshotRestore) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotRestore. +func (in *ETCDSnapshotRestore) DeepCopy() *ETCDSnapshotRestore { + if in == nil { + return nil + } + out := new(ETCDSnapshotRestore) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotS3) DeepCopyInto(out *ETCDSnapshotS3) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotS3. +func (in *ETCDSnapshotS3) DeepCopy() *ETCDSnapshotS3 { + if in == nil { + return nil + } + out := new(ETCDSnapshotS3) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotSpec) DeepCopyInto(out *ETCDSnapshotSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotSpec. +func (in *ETCDSnapshotSpec) DeepCopy() *ETCDSnapshotSpec { + if in == nil { + return nil + } + out := new(ETCDSnapshotSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ETCDSnapshotStatus) DeepCopyInto(out *ETCDSnapshotStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ETCDSnapshotStatus. +func (in *ETCDSnapshotStatus) DeepCopy() *ETCDSnapshotStatus { + if in == nil { + return nil + } + out := new(ETCDSnapshotStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvVar) DeepCopyInto(out *EnvVar) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvVar. +func (in *EnvVar) DeepCopy() *EnvVar { + if in == nil { + return nil + } + out := new(EnvVar) + in.DeepCopyInto(out) + return out +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericMap. +func (in *GenericMap) DeepCopy() *GenericMap { + if in == nil { + return nil + } + out := new(GenericMap) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *K8sObjectFileSource) DeepCopyInto(out *K8sObjectFileSource) { + *out = *in + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KeyToPath, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new K8sObjectFileSource. +func (in *K8sObjectFileSource) DeepCopy() *K8sObjectFileSource { + if in == nil { + return nil + } + out := new(K8sObjectFileSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeyToPath) DeepCopyInto(out *KeyToPath) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeyToPath. +func (in *KeyToPath) DeepCopy() *KeyToPath { + if in == nil { + return nil + } + out := new(KeyToPath) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalClusterAuthEndpoint) DeepCopyInto(out *LocalClusterAuthEndpoint) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalClusterAuthEndpoint. +func (in *LocalClusterAuthEndpoint) DeepCopy() *LocalClusterAuthEndpoint { + if in == nil { + return nil + } + out := new(LocalClusterAuthEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Mirror) DeepCopyInto(out *Mirror) { + *out = *in + if in.Endpoints != nil { + in, out := &in.Endpoints, &out.Endpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Rewrites != nil { + in, out := &in.Rewrites, &out.Rewrites + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mirror. +func (in *Mirror) DeepCopy() *Mirror { + if in == nil { + return nil + } + out := new(Mirror) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Networking) DeepCopyInto(out *Networking) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking. +func (in *Networking) DeepCopy() *Networking { + if in == nil { + return nil + } + out := new(Networking) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProvisioningFileSource) DeepCopyInto(out *ProvisioningFileSource) { + *out = *in + in.Secret.DeepCopyInto(&out.Secret) + in.ConfigMap.DeepCopyInto(&out.ConfigMap) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProvisioningFileSource. +func (in *ProvisioningFileSource) DeepCopy() *ProvisioningFileSource { + if in == nil { + return nil + } + out := new(ProvisioningFileSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrap) DeepCopyInto(out *RKEBootstrap) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrap. +func (in *RKEBootstrap) DeepCopy() *RKEBootstrap { + if in == nil { + return nil + } + out := new(RKEBootstrap) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEBootstrap) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapList) DeepCopyInto(out *RKEBootstrapList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RKEBootstrap, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapList. +func (in *RKEBootstrapList) DeepCopy() *RKEBootstrapList { + if in == nil { + return nil + } + out := new(RKEBootstrapList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEBootstrapList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapSpec) DeepCopyInto(out *RKEBootstrapSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapSpec. +func (in *RKEBootstrapSpec) DeepCopy() *RKEBootstrapSpec { + if in == nil { + return nil + } + out := new(RKEBootstrapSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapStatus) DeepCopyInto(out *RKEBootstrapStatus) { + *out = *in + if in.DataSecretName != nil { + in, out := &in.DataSecretName, &out.DataSecretName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapStatus. +func (in *RKEBootstrapStatus) DeepCopy() *RKEBootstrapStatus { + if in == nil { + return nil + } + out := new(RKEBootstrapStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapTemplate) DeepCopyInto(out *RKEBootstrapTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapTemplate. +func (in *RKEBootstrapTemplate) DeepCopy() *RKEBootstrapTemplate { + if in == nil { + return nil + } + out := new(RKEBootstrapTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEBootstrapTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapTemplateList) DeepCopyInto(out *RKEBootstrapTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RKEBootstrapTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapTemplateList. +func (in *RKEBootstrapTemplateList) DeepCopy() *RKEBootstrapTemplateList { + if in == nil { + return nil + } + out := new(RKEBootstrapTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEBootstrapTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEBootstrapTemplateSpec) DeepCopyInto(out *RKEBootstrapTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEBootstrapTemplateSpec. +func (in *RKEBootstrapTemplateSpec) DeepCopy() *RKEBootstrapTemplateSpec { + if in == nil { + return nil + } + out := new(RKEBootstrapTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKECluster) DeepCopyInto(out *RKECluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKECluster. +func (in *RKECluster) DeepCopy() *RKECluster { + if in == nil { + return nil + } + out := new(RKECluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKECluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEClusterList) DeepCopyInto(out *RKEClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RKECluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEClusterList. +func (in *RKEClusterList) DeepCopy() *RKEClusterList { + if in == nil { + return nil + } + out := new(RKEClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEClusterSpec) DeepCopyInto(out *RKEClusterSpec) { + *out = *in + if in.ControlPlaneEndpoint != nil { + in, out := &in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint + *out = new(v1beta1.APIEndpoint) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEClusterSpec. +func (in *RKEClusterSpec) DeepCopy() *RKEClusterSpec { + if in == nil { + return nil + } + out := new(RKEClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEClusterSpecCommon) DeepCopyInto(out *RKEClusterSpecCommon) { + *out = *in + in.UpgradeStrategy.DeepCopyInto(&out.UpgradeStrategy) + in.ChartValues.DeepCopyInto(&out.ChartValues) + in.MachineGlobalConfig.DeepCopyInto(&out.MachineGlobalConfig) + if in.MachineSelectorConfig != nil { + in, out := &in.MachineSelectorConfig, &out.MachineSelectorConfig + *out = make([]RKESystemConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MachineSelectorFiles != nil { + in, out := &in.MachineSelectorFiles, &out.MachineSelectorFiles + *out = make([]RKEProvisioningFiles, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Registries != nil { + in, out := &in.Registries, &out.Registries + *out = new(Registry) + (*in).DeepCopyInto(*out) + } + if in.ETCD != nil { + in, out := &in.ETCD, &out.ETCD + *out = new(ETCD) + (*in).DeepCopyInto(*out) + } + if in.Networking != nil { + in, out := &in.Networking, &out.Networking + *out = new(Networking) + **out = **in + } + out.DataDirectories = in.DataDirectories + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEClusterSpecCommon. +func (in *RKEClusterSpecCommon) DeepCopy() *RKEClusterSpecCommon { + if in == nil { + return nil + } + out := new(RKEClusterSpecCommon) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEClusterStatus) DeepCopyInto(out *RKEClusterStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEClusterStatus. +func (in *RKEClusterStatus) DeepCopy() *RKEClusterStatus { + if in == nil { + return nil + } + out := new(RKEClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKECommonNodeConfig) DeepCopyInto(out *RKECommonNodeConfig) { + *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Taints != nil { + in, out := &in.Taints, &out.Taints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKECommonNodeConfig. +func (in *RKECommonNodeConfig) DeepCopy() *RKECommonNodeConfig { + if in == nil { + return nil + } + out := new(RKECommonNodeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEControlPlane) DeepCopyInto(out *RKEControlPlane) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEControlPlane. +func (in *RKEControlPlane) DeepCopy() *RKEControlPlane { + if in == nil { + return nil + } + out := new(RKEControlPlane) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEControlPlane) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEControlPlaneList) DeepCopyInto(out *RKEControlPlaneList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RKEControlPlane, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEControlPlaneList. +func (in *RKEControlPlaneList) DeepCopy() *RKEControlPlaneList { + if in == nil { + return nil + } + out := new(RKEControlPlaneList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RKEControlPlaneList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEControlPlaneSpec) DeepCopyInto(out *RKEControlPlaneSpec) { + *out = *in + in.RKEClusterSpecCommon.DeepCopyInto(&out.RKEClusterSpecCommon) + if in.AgentEnvVars != nil { + in, out := &in.AgentEnvVars, &out.AgentEnvVars + *out = make([]EnvVar, len(*in)) + copy(*out, *in) + } + out.LocalClusterAuthEndpoint = in.LocalClusterAuthEndpoint + if in.ETCDSnapshotCreate != nil { + in, out := &in.ETCDSnapshotCreate, &out.ETCDSnapshotCreate + *out = new(ETCDSnapshotCreate) + **out = **in + } + if in.ETCDSnapshotRestore != nil { + in, out := &in.ETCDSnapshotRestore, &out.ETCDSnapshotRestore + *out = new(ETCDSnapshotRestore) + **out = **in + } + if in.RotateCertificates != nil { + in, out := &in.RotateCertificates, &out.RotateCertificates + *out = new(RotateCertificates) + (*in).DeepCopyInto(*out) + } + if in.RotateEncryptionKeys != nil { + in, out := &in.RotateEncryptionKeys, &out.RotateEncryptionKeys + *out = new(RotateEncryptionKeys) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEControlPlaneSpec. +func (in *RKEControlPlaneSpec) DeepCopy() *RKEControlPlaneSpec { + if in == nil { + return nil + } + out := new(RKEControlPlaneSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEControlPlaneStatus) DeepCopyInto(out *RKEControlPlaneStatus) { + *out = *in + if in.AppliedSpec != nil { + in, out := &in.AppliedSpec, &out.AppliedSpec + *out = new(RKEControlPlaneSpec) + (*in).DeepCopyInto(*out) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + if in.RotateEncryptionKeys != nil { + in, out := &in.RotateEncryptionKeys, &out.RotateEncryptionKeys + *out = new(RotateEncryptionKeys) + **out = **in + } + if in.ETCDSnapshotRestore != nil { + in, out := &in.ETCDSnapshotRestore, &out.ETCDSnapshotRestore + *out = new(ETCDSnapshotRestore) + **out = **in + } + if in.ETCDSnapshotCreate != nil { + in, out := &in.ETCDSnapshotCreate, &out.ETCDSnapshotCreate + *out = new(ETCDSnapshotCreate) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEControlPlaneStatus. +func (in *RKEControlPlaneStatus) DeepCopy() *RKEControlPlaneStatus { + if in == nil { + return nil + } + out := new(RKEControlPlaneStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEMachineStatus) DeepCopyInto(out *RKEMachineStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]genericcondition.GenericCondition, len(*in)) + copy(*out, *in) + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]v1beta1.MachineAddress, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEMachineStatus. +func (in *RKEMachineStatus) DeepCopy() *RKEMachineStatus { + if in == nil { + return nil + } + out := new(RKEMachineStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKEProvisioningFiles) DeepCopyInto(out *RKEProvisioningFiles) { + *out = *in + if in.MachineLabelSelector != nil { + in, out := &in.MachineLabelSelector, &out.MachineLabelSelector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + if in.FileSources != nil { + in, out := &in.FileSources, &out.FileSources + *out = make([]ProvisioningFileSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKEProvisioningFiles. +func (in *RKEProvisioningFiles) DeepCopy() *RKEProvisioningFiles { + if in == nil { + return nil + } + out := new(RKEProvisioningFiles) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RKESystemConfig) DeepCopyInto(out *RKESystemConfig) { + *out = *in + if in.MachineLabelSelector != nil { + in, out := &in.MachineLabelSelector, &out.MachineLabelSelector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } + in.Config.DeepCopyInto(&out.Config) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RKESystemConfig. +func (in *RKESystemConfig) DeepCopy() *RKESystemConfig { + if in == nil { + return nil + } + out := new(RKESystemConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Registry) DeepCopyInto(out *Registry) { + *out = *in + if in.Mirrors != nil { + in, out := &in.Mirrors, &out.Mirrors + *out = make(map[string]Mirror, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = make(map[string]RegistryConfig, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Registry. +func (in *Registry) DeepCopy() *Registry { + if in == nil { + return nil + } + out := new(Registry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) { + *out = *in + if in.CABundle != nil { + in, out := &in.CABundle, &out.CABundle + *out = make([]byte, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig. +func (in *RegistryConfig) DeepCopy() *RegistryConfig { + if in == nil { + return nil + } + out := new(RegistryConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RotateCertificates) DeepCopyInto(out *RotateCertificates) { + *out = *in + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RotateCertificates. +func (in *RotateCertificates) DeepCopy() *RotateCertificates { + if in == nil { + return nil + } + out := new(RotateCertificates) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RotateEncryptionKeys) DeepCopyInto(out *RotateEncryptionKeys) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RotateEncryptionKeys. +func (in *RotateEncryptionKeys) DeepCopy() *RotateEncryptionKeys { + if in == nil { + return nil + } + out := new(RotateEncryptionKeys) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_list_types.go new file mode 100644 index 0000000..5f76eee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_list_types.go @@ -0,0 +1,127 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=rke.cattle.io +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CustomMachineList is a list of CustomMachine resources +type CustomMachineList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CustomMachine `json:"items"` +} + +func NewCustomMachine(namespace, name string, obj CustomMachine) *CustomMachine { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("CustomMachine").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ETCDSnapshotList is a list of ETCDSnapshot resources +type ETCDSnapshotList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []ETCDSnapshot `json:"items"` +} + +func NewETCDSnapshot(namespace, name string, obj ETCDSnapshot) *ETCDSnapshot { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("ETCDSnapshot").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RKEBootstrapList is a list of RKEBootstrap resources +type RKEBootstrapList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RKEBootstrap `json:"items"` +} + +func NewRKEBootstrap(namespace, name string, obj RKEBootstrap) *RKEBootstrap { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RKEBootstrap").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RKEBootstrapTemplateList is a list of RKEBootstrapTemplate resources +type RKEBootstrapTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RKEBootstrapTemplate `json:"items"` +} + +func NewRKEBootstrapTemplate(namespace, name string, obj RKEBootstrapTemplate) *RKEBootstrapTemplate { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RKEBootstrapTemplate").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RKEClusterList is a list of RKECluster resources +type RKEClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RKECluster `json:"items"` +} + +func NewRKECluster(namespace, name string, obj RKECluster) *RKECluster { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RKECluster").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RKEControlPlaneList is a list of RKEControlPlane resources +type RKEControlPlaneList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RKEControlPlane `json:"items"` +} + +func NewRKEControlPlane(namespace, name string, obj RKEControlPlane) *RKEControlPlane { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("RKEControlPlane").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_register.go new file mode 100644 index 0000000..c374213 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/v1/zz_generated_register.go @@ -0,0 +1,75 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=rke.cattle.io +package v1 + +import ( + rke "github.com/rancher/rancher/pkg/apis/rke.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + CustomMachineResourceName = "custommachines" + ETCDSnapshotResourceName = "etcdsnapshots" + RKEBootstrapResourceName = "rkebootstraps" + RKEBootstrapTemplateResourceName = "rkebootstraptemplates" + RKEClusterResourceName = "rkeclusters" + RKEControlPlaneResourceName = "rkecontrolplanes" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: rke.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CustomMachine{}, + &CustomMachineList{}, + &ETCDSnapshot{}, + &ETCDSnapshotList{}, + &RKEBootstrap{}, + &RKEBootstrapList{}, + &RKEBootstrapTemplate{}, + &RKEBootstrapTemplateList{}, + &RKECluster{}, + &RKEClusterList{}, + &RKEControlPlane{}, + &RKEControlPlaneList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..5ebb97e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/rke.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package rke + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "rke.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/doc.go new file mode 100644 index 0000000..9829861 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=ui.cattle.io +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/types.go new file mode 100644 index 0000000..2a8f285 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/types.go @@ -0,0 +1,35 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// +genclient +// +kubebuilder:skipversion +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type NavLink struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec NavLinkSpec `json:"spec"` +} + +type NavLinkSpec struct { + Label string `json:"label,omitempty"` + Description string `json:"description,omitempty"` + SideLabel string `json:"sideLabel,omitempty"` + IconSrc string `json:"iconSrc,omitempty"` + Group string `json:"group,omitempty"` + Target string `json:"target,omitempty"` + ToURL string `json:"toURL,omitempty"` + ToService *NavLinkTargetService `json:"toService,omitempty"` +} + +type NavLinkTargetService struct { + Namespace string `json:"namespace,omitempty" wrangler:"required"` + Name string `json:"name,omitempty" wrangler:"required"` + Scheme string `json:"scheme,omitempty" wrangler:"default=http,options=http|https,type=enum"` + Port *intstr.IntOrString `json:"port,omitempty"` + Path string `json:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_deepcopy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_deepcopy.go new file mode 100644 index 0000000..004a1de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_deepcopy.go @@ -0,0 +1,129 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" + intstr "k8s.io/apimachinery/pkg/util/intstr" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NavLink) DeepCopyInto(out *NavLink) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NavLink. +func (in *NavLink) DeepCopy() *NavLink { + if in == nil { + return nil + } + out := new(NavLink) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NavLink) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NavLinkList) DeepCopyInto(out *NavLinkList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NavLink, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NavLinkList. +func (in *NavLinkList) DeepCopy() *NavLinkList { + if in == nil { + return nil + } + out := new(NavLinkList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NavLinkList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NavLinkSpec) DeepCopyInto(out *NavLinkSpec) { + *out = *in + if in.ToService != nil { + in, out := &in.ToService, &out.ToService + *out = new(NavLinkTargetService) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NavLinkSpec. +func (in *NavLinkSpec) DeepCopy() *NavLinkSpec { + if in == nil { + return nil + } + out := new(NavLinkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NavLinkTargetService) DeepCopyInto(out *NavLinkTargetService) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(intstr.IntOrString) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NavLinkTargetService. +func (in *NavLinkTargetService) DeepCopy() *NavLinkTargetService { + if in == nil { + return nil + } + out := new(NavLinkTargetService) + in.DeepCopyInto(out) + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_list_types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_list_types.go new file mode 100644 index 0000000..cff652a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_list_types.go @@ -0,0 +1,42 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=ui.cattle.io +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// NavLinkList is a list of NavLink resources +type NavLinkList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []NavLink `json:"items"` +} + +func NewNavLink(namespace, name string, obj NavLink) *NavLink { + obj.APIVersion, obj.Kind = SchemeGroupVersion.WithKind("NavLink").ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_register.go new file mode 100644 index 0000000..c791269 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/v1/zz_generated_register.go @@ -0,0 +1,60 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// +k8s:deepcopy-gen=package +// +groupName=ui.cattle.io +package v1 + +import ( + ui "github.com/rancher/rancher/pkg/apis/ui.cattle.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + NavLinkResourceName = "navlinks" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: ui.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &NavLink{}, + &NavLinkList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/zz_generated_register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/zz_generated_register.go new file mode 100644 index 0000000..8e73252 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/apis/ui.cattle.io/zz_generated_register.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package ui + +const ( + // Package-wide consts from generator "zz_generated_register". + GroupName = "ui.cattle.io" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/app/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/app/utils.go new file mode 100644 index 0000000..983257a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/app/utils.go @@ -0,0 +1,172 @@ +package app + +import ( + "fmt" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/controllers/managementuser/rbac" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + projv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/kubectl/pkg/util/slice" +) + +const ( + creatorIDAnno = "field.cattle.io/creatorId" +) + +func EnsureAppProjectName(userNSClient v1.NamespaceInterface, ownedProjectID, clusterName, appTargetNamespace, creatorID string) (string, error) { + // detect Namespace + deployNamespace, err := userNSClient.Get(appTargetNamespace, metav1.GetOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + return "", errors.Wrapf(err, "failed to find %q Namespace", appTargetNamespace) + } + deployNamespace = deployNamespace.DeepCopy() + + if deployNamespace.Name == appTargetNamespace { + if deployNamespace.DeletionTimestamp != nil { + return "", fmt.Errorf("stale %q Namespace is still on terminating", appTargetNamespace) + } + } else { + deployNamespace = &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: appTargetNamespace, + Annotations: map[string]string{creatorIDAnno: creatorID}, + }, + } + + if deployNamespace, err = userNSClient.Create(deployNamespace); err != nil && !kerrors.IsAlreadyExists(err) { + return "", errors.Wrapf(err, "failed to create %q Namespace", appTargetNamespace) + } + } + + expectedAppProjectName := fmt.Sprintf("%s:%s", clusterName, ownedProjectID) + appProjectID := deployNamespace.Annotations[nslabels.ProjectIDFieldLabel] + if appProjectID != "" && isKnownSystemNamespace(deployNamespace) { + // Don't reassign the system namespaces to another project. + return expectedAppProjectName, nil + } + + // move Namespace into a project + if appProjectID != expectedAppProjectName { + appProjectID = expectedAppProjectName + if deployNamespace.Annotations == nil { + deployNamespace.Annotations = make(map[string]string, 2) + } + + deployNamespace.Annotations[nslabels.ProjectIDFieldLabel] = appProjectID + + _, err := userNSClient.Update(deployNamespace) + if err != nil { + return "", errors.Wrapf(err, "failed to move Namespace %s into a Project", appTargetNamespace) + } + } + + return appProjectID, nil +} + +func GetSystemProjectID(clusterName string, cattleProjectsLister v3.ProjectLister) (string, error) { + // fetch all system Projects + cattleSystemProjects, _ := cattleProjectsLister.List(clusterName, labels.Set(project.SystemProjectLabel).AsSelector()) + + var systemProject *v3.Project + for _, p := range cattleSystemProjects { + if p.Spec.DisplayName == project.System { + systemProject = p + break + } + } + if systemProject == nil { + return "", fmt.Errorf("failed to find any cattle system project") + } + + return systemProject.Name, nil +} + +func DeployApp(mgmtAppClient projv3.AppInterface, projectID string, createOrUpdateApp *projv3.App, forceRedeploy bool) (*projv3.App, error) { + if createOrUpdateApp == nil { + return nil, errors.New("cannot deploy a nil App") + } + var rtn *projv3.App + + appName := createOrUpdateApp.Name + app, err := mgmtAppClient.GetNamespaced(projectID, appName, metav1.GetOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + return nil, errors.Wrapf(err, "failed to query %q App in %s Project", appName, projectID) + } + + if app.DeletionTimestamp != nil { + return nil, fmt.Errorf("stale %q App in %s Project is still on terminating", appName, projectID) + } + + if app.Name == "" { + logrus.Infof("Create app %s/%s", app.Spec.TargetNamespace, app.Name) + if rtn, err = mgmtAppClient.Create(createOrUpdateApp); err != nil { + return nil, errors.Wrapf(err, "failed to create %q App", appName) + } + } else { + app = app.DeepCopy() + app.Spec.Answers = createOrUpdateApp.Spec.Answers + app.Spec.AnswersSetString = createOrUpdateApp.Spec.AnswersSetString + + // clean up status + if forceRedeploy { + if app.Spec.Answers == nil { + app.Spec.Answers = make(map[string]string, 1) + } + app.Spec.Answers["redeployTs"] = fmt.Sprintf("%d", time.Now().Unix()) + } + + if rtn, err = mgmtAppClient.Update(app); err != nil { + return nil, errors.Wrapf(err, "failed to update %q App", appName) + } + } + + return rtn, nil +} + +func DetectAppCatalogExistence(appCatalogID string, cattleTemplateVersionsLister v3.CatalogTemplateVersionLister) error { + templateVersionID, templateVersionNamespace, err := common.ParseExternalID(appCatalogID) + if err != nil { + return errors.Wrapf(err, "failed to parse catalog ID %q", appCatalogID) + } + + _, err = cattleTemplateVersionsLister.Get(templateVersionNamespace, templateVersionID) + if err != nil { + return errors.Wrapf(err, "failed to find catalog by ID %q", appCatalogID) + } + + return nil +} + +func DeleteApp(mgmtAppClient projv3.AppInterface, projectID, appName string) error { + app, err := mgmtAppClient.GetNamespaced(projectID, appName, metav1.GetOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + return errors.Wrapf(err, "failed to find app %s in project %v", appName, projectID) + } + + if app.DeletionTimestamp == nil { + err := mgmtAppClient.DeleteNamespaced(projectID, appName, &metav1.DeleteOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + return errors.Wrapf(err, "failed to delete app %v", appName) + } + } + + return nil +} + +func isKnownSystemNamespace(ns *v1.Namespace) bool { + return slice.ContainsString(strings.Split(settings.SystemNamespaces.Get(), ","), ns.Name, nil) || + rbac.IsFleetNamespace(ns) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup.go new file mode 100644 index 0000000..8ad155a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup.go @@ -0,0 +1,82 @@ +package secrets + +import ( + "errors" + "fmt" + + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/catalog/utils" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// CleanupClientSecrets tries to delete common client secrets for each auth provider. +func CleanupClientSecrets(secretInterface corev1.SecretInterface, config *v3.AuthConfig) error { + if config == nil { + return fmt.Errorf("cannot delete auth provider secrets if its config is nil") + } + + fields, ok := TypeToFields[config.Type] + if !ok { + return fmt.Errorf("cannot delete auth provider %s because it's unknown to Rancher", config.Type) + } + + var result error + for _, field := range fields { + err := common.DeleteSecret(secretInterface, config.Type, field) + if err != nil && !apierrors.IsNotFound(err) { + result = errors.Join(result, err) + } + } + + if utils.Contains(tokens.PerUserCacheProviders, config.Name) { + err := CleanupOAuthTokens(secretInterface, config.Name) + result = errors.Join(result, err) + } + + if fieldsMap, ok := SubTypeToFields[config.Type]; ok { + for _, slice := range fieldsMap { + for _, field := range slice { + err := common.DeleteSecret(secretInterface, config.Type, field) + if err != nil && !apierrors.IsNotFound(err) { + result = errors.Join(result, err) + } + } + } + } + + for _, secretName := range NameToFields[config.Name] { + err := common.DeleteSecret(secretInterface, config.Name, secretName) + if err != nil && !apierrors.IsNotFound(err) { + result = errors.Join(result, err) + } + } + return result +} + +// CleanupOAuthTokens attempts to delete all secrets that contain users' OAuth access tokens. +// It is not possible to filter secrets easily by presence of specific key(s) in the data object. The method fetches all +// Opaque secrets in the relevant namespace and looks at the target key in the data to find a secret that stores a user's +// access token to delete. +func CleanupOAuthTokens(secretInterface corev1.SecretInterface, key string) error { + opaqueSecrets, err := secretInterface.ListNamespaced(tokens.SecretNamespace, metav1.ListOptions{FieldSelector: "type=Opaque"}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to fetch secrets to clean up: %w", err) + } + + var result error + for i := range opaqueSecrets.Items { + secret := &opaqueSecrets.Items[i] + if _, keyPresent := secret.Data[key]; keyPresent { + err := secretInterface.DeleteNamespaced(tokens.SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + result = errors.Join(result, err) + } + } + } + + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup_test.go new file mode 100644 index 0000000..8843644 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/cleanup_test.go @@ -0,0 +1,255 @@ +package secrets + +import ( + "crypto/md5" + "encoding/hex" + "errors" + "fmt" + "strings" + "testing" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestCleanupClientSecretsNilConfig(t *testing.T) { + secrets := getSecretInterfaceMock(map[string]*corev1.Secret{}) + err := CleanupClientSecrets(secrets, nil) + require.Error(t, err) +} + +func TestCleanupClientSecretsUnknownConfig(t *testing.T) { + secrets := getSecretInterfaceMock(map[string]*corev1.Secret{}) + + config := &v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{Name: "unknownConfig"}, + Enabled: true, + } + + err := CleanupClientSecrets(secrets, config) + require.Error(t, err) +} + +func TestCleanupClientSecretsKnownConfig(t *testing.T) { + config := &v3.AuthConfig{ + Type: client.GoogleOauthConfigType, + ObjectMeta: metav1.ObjectMeta{Name: "googleoauth"}, + Enabled: true, + } + + const ( + oauthCredential = "oauthcredential" + serviceAccountToken = "serviceaccountcredential" + ) + secretName1 := fmt.Sprintf("%s-%s", strings.ToLower(config.Type), oauthCredential) + secretName2 := fmt.Sprintf("%s-%s", strings.ToLower(config.Type), serviceAccountToken) + oauthSecretName := "user123-secret" + + initialStore := map[string]*corev1.Secret{} + secrets := getSecretInterfaceMock(initialStore) + + _, err := secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName1, + Namespace: common.SecretsNamespace, + }, + }) + assert.NoError(t, err) + + _, err = secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName2, + Namespace: common.SecretsNamespace, + }, + }) + assert.NoError(t, err) + + _, err = secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: oauthSecretName, + Namespace: tokens.SecretNamespace, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{ + config.Name: []byte("my user token"), + }, + }) + assert.NoError(t, err) + + s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName1) + + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName2) + + s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", oauthSecretName) + + err = CleanupClientSecrets(secrets, config) + assert.NoError(t, err) + + t.Run("Cleanup deletes provider secrets", func(t *testing.T) { + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName1) + assert.Nil(t, s, "expected the secret to be nil") + + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName2) + assert.Nil(t, s, "expected the secret to be nil") + }) + + t.Run("Cleanup deletes OAuth secrets", func(t *testing.T) { + s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", oauthSecretName) + assert.Nil(t, s, "expected the secret to be nil") + }) +} + +func TestCleanupDeprecatedSecretsKnownConfig(t *testing.T) { + config := &v3.AuthConfig{ + Type: client.AzureADConfigType, + ObjectMeta: metav1.ObjectMeta{Name: "azuread"}, + Enabled: true, + } + + secretName := fmt.Sprintf("%s-%s", strings.ToLower(config.Name), "access-token") + initialStore := map[string]*corev1.Secret{} + secrets := getSecretInterfaceMock(initialStore) + + _, err := secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: common.SecretsNamespace, + }, + }) + assert.NoError(t, err) + + s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName) + + err = CleanupClientSecrets(secrets, config) + assert.NoError(t, err) + + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName) + assert.Nil(t, s, "expected the secret to be nil") +} + +func getSecretInterfaceMock(store map[string]*corev1.Secret) v1.SecretInterface { + secretInterfaceMock := &fakes.SecretInterfaceMock{} + + secretInterfaceMock.CreateFunc = func(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.Name == "" { + uniqueIdentifier := md5.Sum([]byte(time.Now().String())) + secret.Name = hex.EncodeToString(uniqueIdentifier[:]) + } + store[fmt.Sprintf("%s:%s", secret.Namespace, secret.Name)] = secret + return secret, nil + } + + secretInterfaceMock.GetNamespacedFunc = func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + secret, ok := store[fmt.Sprintf("%s:%s", namespace, name)] + if ok { + return secret, nil + } + return nil, errors.New("secret not found") + } + + secretInterfaceMock.DeleteNamespacedFunc = func(namespace string, name string, options *metav1.DeleteOptions) error { + key := fmt.Sprintf("%s:%s", namespace, name) + if _, ok := store[key]; !ok { + return apierrors.NewNotFound(schema.GroupResource{ + Group: v1.SecretGroupVersionKind.Group, + Resource: v1.SecretGroupVersionResource.Resource, + }, key) + } + delete(store, key) + return nil + } + + secretInterfaceMock.ListNamespacedFunc = func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { + var secrets []corev1.Secret + for _, s := range store { + secrets = append(secrets, *s) + } + return &corev1.SecretList{Items: secrets}, nil + } + + return secretInterfaceMock +} + +func TestCleanupClientSecretsOKTAConfig(t *testing.T) { + config := &v3.AuthConfig{ + Type: client.OKTAConfigType, + ObjectMeta: metav1.ObjectMeta{Name: "okta"}, + Enabled: true, + } + + secretName1 := fmt.Sprintf("%s-%s", strings.ToLower(config.Type), "spkey") + secretName2 := fmt.Sprintf("%s-%s", strings.ToLower(config.Type), "serviceaccountpassword") + oauthSecretName := "user123-secret" + + initialStore := map[string]*corev1.Secret{} + secrets := getSecretInterfaceMock(initialStore) + + _, err := secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName1, + Namespace: common.SecretsNamespace, + }, + }) + assert.NoError(t, err) + + _, err = secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName2, + Namespace: common.SecretsNamespace, + }, + }) + assert.NoError(t, err) + + _, err = secrets.Create(&v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: oauthSecretName, + Namespace: tokens.SecretNamespace, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{ + config.Name: []byte("my user token"), + }, + }) + assert.NoError(t, err) + + s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName1) + + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName2) + + s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", oauthSecretName) + + err = CleanupClientSecrets(secrets, config) + assert.NoError(t, err) + + t.Run("Cleanup deletes provider secrets", func(t *testing.T) { + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName1) + assert.Nil(t, s, "expected the secret to be nil") + + s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName2) + assert.Nil(t, s, "expected the secret to be nil") + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/fields.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/fields.go new file mode 100644 index 0000000..d7bc863 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/fields.go @@ -0,0 +1,40 @@ +package secrets + +import ( + azuread "github.com/rancher/rancher/pkg/auth/providers/azure/clients" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" +) + +var ( + // TypeToFields associates an Auth Config type with a set of secret names related to the config. + TypeToFields = map[string][]string{ + client.GithubConfigType: {client.GithubConfigFieldClientSecret}, + client.ActiveDirectoryConfigType: {client.ActiveDirectoryConfigFieldServiceAccountPassword}, + client.AzureADConfigType: {client.AzureADConfigFieldApplicationSecret}, + client.OpenLdapConfigType: {client.LdapConfigFieldServiceAccountPassword}, + client.FreeIpaConfigType: {client.LdapConfigFieldServiceAccountPassword}, + client.PingConfigType: {client.PingConfigFieldSpKey}, + client.ADFSConfigType: {client.ADFSConfigFieldSpKey}, + client.KeyCloakConfigType: {client.KeyCloakConfigFieldSpKey}, + client.OKTAConfigType: {client.OKTAConfigFieldSpKey}, + client.ShibbolethConfigType: {client.ShibbolethConfigFieldSpKey}, + client.GoogleOauthConfigType: {client.GoogleOauthConfigFieldOauthCredential, client.GoogleOauthConfigFieldServiceAccountCredential}, + client.OIDCConfigType: {client.OIDCConfigFieldPrivateKey, client.OIDCConfigFieldClientSecret}, + client.KeyCloakOIDCConfigType: {client.KeyCloakOIDCConfigFieldPrivateKey, client.KeyCloakOIDCConfigFieldClientSecret}, + client.GenericOIDCConfigType: {client.GenericOIDCConfigFieldPrivateKey, client.GenericOIDCConfigFieldClientSecret}, + } + // SubTypeToFields associates an Auth Config type with a nested map of secret names related to the config. + SubTypeToFields = map[string]map[string][]string{ + client.ShibbolethConfigType: { + client.ShibbolethConfigFieldOpenLdapConfig: {client.LdapConfigFieldServiceAccountPassword}, + }, + client.OKTAConfigType: { + client.OKTAConfigFieldOpenLdapConfig: {client.LdapConfigFieldServiceAccountPassword}, + }, + } + + // NameToFields keeps track of secrets that Rancher must clean up for the given auth provider specified by name. + NameToFields = map[string][]string{ + azuread.Name: {"access-token"}, + } +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/store.go new file mode 100644 index 0000000..f5519d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/secrets/store.go @@ -0,0 +1,77 @@ +package secrets + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "github.com/rancher/rancher/pkg/auth/providers/common" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" +) + +func Wrap(store types.Store, secrets corev1.SecretInterface) types.Store { + return &Store{ + Store: store, + Secrets: secrets, + } +} + +type Store struct { + types.Store + Secrets corev1.SecretInterface +} + +func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + authType, found := values.GetValue(data, "type") + if !found { + return nil, fmt.Errorf("invalid data for auth store update") + } + + kind := convert.ToString(authType) + fields, ok := TypeToFields[kind] + subFields, subOk := SubTypeToFields[kind] + if !ok && !subOk { + return s.Store.Update(apiContext, schema, data, id) + } + + var err error + for _, field := range fields { + if val, ok := data[field]; ok { + data[field], err = s.CreateOrUpdateSecrets(convert.ToString(val), field, kind) + if err != nil { + return nil, err + } + } + } + + // subfields for embedded configs, see saml group search using openldap + for subField, subFieldList := range subFields { + if subData, ok := data[subField]; ok { + subData, casteOk := subData.(map[string]interface{}) + if !casteOk { + continue + } + for _, field := range subFieldList { + if val, ok := subData[field]; ok { + subData[field], err = s.CreateOrUpdateSecrets(convert.ToString(val), field, kind) + if err != nil { + return nil, err + } + } + } + } + } + + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *Store) CreateOrUpdateSecrets(value, field, kind string) (string, error) { + name, err := common.CreateOrUpdateSecrets(s.Secrets, value, strings.ToLower(field), strings.ToLower(kind)) + if err != nil { + return "", fmt.Errorf("error creating secret %s: %w", name, err) + } + + return name, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/setup.go new file mode 100644 index 0000000..2cfa76b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/setup.go @@ -0,0 +1,73 @@ +package api + +import ( + "context" + "net/http" + + normanapi "github.com/rancher/norman/api" + "github.com/rancher/norman/pkg/subscribe" + "github.com/rancher/norman/store/crd" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/rancher/pkg/auth/api/user" + "github.com/rancher/rancher/pkg/auth/principals" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/requests" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Setup(ctx context.Context, clusterRouter requests.ClusterRouter, scaledContext *config.ScaledContext, schemas *types.Schemas) { + principals.Schema(ctx, clusterRouter, scaledContext, schemas) + providers.SetupAuthConfig(ctx, scaledContext, schemas) + user.SetUserStore(schemas.Schema(&managementschema.Version, client.UserType), scaledContext) + User(ctx, schemas, scaledContext) +} + +func User(ctx context.Context, schemas *types.Schemas, management *config.ScaledContext) { + schema := schemas.Schema(&managementschema.Version, client.UserType) + handler := &user.Handler{ + UserClient: management.Management.Users(""), + GlobalRoleBindingsClient: management.Management.GlobalRoleBindings(""), + UserAuthRefresher: providerrefresh.NewUserAuthRefresher(ctx, management), + } + + schema.Formatter = handler.UserFormatter + schema.CollectionFormatter = handler.CollectionFormatter + schema.ActionHandler = handler.Actions +} + +func NewNormanServer(ctx context.Context, clusterRouter requests.ClusterRouter, scaledContext *config.ScaledContext) (http.Handler, error) { + schemas, err := newSchemas(ctx, scaledContext) + if err != nil { + return nil, err + } + + Setup(ctx, clusterRouter, scaledContext, schemas) + + server := normanapi.NewAPIServer() + if err := server.AddSchemas(schemas); err != nil { + return nil, err + } + return server, nil +} + +func newSchemas(ctx context.Context, apiContext *config.ScaledContext) (*types.Schemas, error) { + schemas := types.NewSchemas() + schemas.AddSchemas(managementschema.AuthSchemas) + subscribe.Register(&managementschema.Version, schemas) + + factory := &crd.Factory{ClientGetter: apiContext.ClientGetter} + factory.BatchCreateCRDs(ctx, config.ManagementStorageContext, scheme.Scheme, schemas, &managementschema.Version, + client.AuthConfigType, + client.GroupMemberType, + client.GroupType, + client.TokenType, + client.UserAttributeType, + client.UserType, + ) + + return schemas, factory.BatchWait() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions.go new file mode 100644 index 0000000..ceef18b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions.go @@ -0,0 +1,206 @@ +package user + +import ( + "net/http" + "strings" + "unicode/utf8" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/parse" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "golang.org/x/crypto/bcrypt" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (h *Handler) UserFormatter(apiContext *types.APIContext, resource *types.RawResource) { + resource.AddAction(apiContext, "setpassword") + + if canRefresh := h.userCanRefresh(apiContext); canRefresh { + resource.AddAction(apiContext, "refreshauthprovideraccess") + } +} + +func (h *Handler) CollectionFormatter(apiContext *types.APIContext, collection *types.GenericCollection) { + collection.AddAction(apiContext, "changepassword") + if canRefresh := h.userCanRefresh(apiContext); canRefresh { + collection.AddAction(apiContext, "refreshauthprovideraccess") + } +} + +type Handler struct { + UserClient v3.UserInterface + GlobalRoleBindingsClient v3.GlobalRoleBindingInterface + UserAuthRefresher providerrefresh.UserAuthRefresher +} + +func (h *Handler) Actions(actionName string, action *types.Action, apiContext *types.APIContext) error { + switch actionName { + case "changepassword": + if err := h.changePassword(apiContext); err != nil { + return err + } + case "setpassword": + if err := h.setPassword(apiContext); err != nil { + return err + } + case "refreshauthprovideraccess": + if err := h.refreshAttributes(apiContext); err != nil { + return err + } + default: + return errors.Errorf("bad action %v", actionName) + } + + if !strings.EqualFold(settings.FirstLogin.Get(), "false") { + if err := settings.FirstLogin.Set("false"); err != nil { + return err + } + } + return nil +} + +func (h *Handler) changePassword(request *types.APIContext) error { + actionInput, err := parse.ReadBody(request.Request) + if err != nil { + return err + } + + store := request.Schema.Store + if store == nil { + return errors.New("no user store available") + } + + userID := request.Request.Header.Get("Impersonate-User") + if userID == "" { + return errors.New("can't find user") + } + + currentPass, ok := actionInput["currentPassword"].(string) + if !ok || len(currentPass) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must specify current password") + } + + newPass, ok := actionInput["newPassword"].(string) + if !ok || len(newPass) == 0 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "invalid new password") + } + + user, err := h.UserClient.Get(userID, v1.GetOptions{}) + if err != nil { + return err + } + + if err := validatePassword(user.Username, currentPass, newPass, settings.PasswordMinLength.GetInt()); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(currentPass)); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, "invalid current password") + } + + newPassHash, err := HashPasswordString(newPass) + if err != nil { + return err + } + + user.Password = newPassHash + user.MustChangePassword = false + user, err = h.UserClient.Update(user) + if err != nil { + return err + } + + return nil +} + +func (h *Handler) setPassword(request *types.APIContext) error { + actionInput, err := parse.ReadBody(request.Request) + if err != nil { + return err + } + + store := request.Schema.Store + if store == nil { + return errors.New("no user store available") + } + + userData, err := store.ByID(request, request.Schema, request.ID) + if err != nil { + return err + } + + newPass, ok := actionInput["newPassword"].(string) + if !ok || len(newPass) == 0 { + return errors.New("Invalid password") + } + + // if the username is not set the user is an external one + usernameInt, found := userData[client.UserFieldUsername] + if !found { + return errors.New("Cannot set password of non-local user") + } + username, _ := usernameInt.(string) + + // passing empty currentPass to validator since, this api call doesn't assume an existing password + if err := validatePassword(username, "", newPass, settings.PasswordMinLength.GetInt()); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + userData[client.UserFieldPassword] = newPass + if err := hashPassword(userData); err != nil { + return err + } + userData[client.UserFieldMustChangePassword] = false + delete(userData, "me") + + userData, err = store.Update(request, request.Schema, userData, request.ID) + if err != nil { + return err + } + + request.WriteResponse(http.StatusOK, userData) + return nil +} + +func (h *Handler) refreshAttributes(request *types.APIContext) error { + canRefresh := h.userCanRefresh(request) + + if !canRefresh { + return errors.New("Not Allowed") + } + + if request.ID != "" { + h.UserAuthRefresher.TriggerUserRefresh(request.ID, true) + } else { + h.UserAuthRefresher.TriggerAllUserRefresh() + } + + request.WriteResponse(http.StatusOK, nil) + return nil +} + +func (h *Handler) userCanRefresh(request *types.APIContext) bool { + return request.AccessControl.CanDo(v3.UserGroupVersionKind.Group, v3.UserResource.Name, "create", request, nil, request.Schema) == nil +} + +// validatePassword will ensure a password is at least the minimum required length in runes, +// that the username and password do not match, and that the new password is not the same as the current password. +func validatePassword(user string, currentPass string, pass string, minPassLen int) error { + if utf8.RuneCountInString(pass) < minPassLen { + return errors.Errorf("Password must be at least %v characters", minPassLen) + } + + if user == pass { + return errors.New("Password cannot be the same as username") + } + if pass == currentPass { + return errors.New("The new password must not be the same as the current password") + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions_test.go new file mode 100644 index 0000000..dac7673 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_actions_test.go @@ -0,0 +1,77 @@ +package user + +import ( + "testing" +) + +func TestValidatePassword(t *testing.T) { + tests := []struct { + name string + username string + currentpass string + password string + expectsErr bool + }{ + { + name: "password too short", + username: "admin", + currentpass: "currentpassword", + password: "tooshort", + expectsErr: true, + }, + { + name: "username equals password min length", + username: "passwordpass", + currentpass: "currentpassword", + password: "passwordpass", + expectsErr: true, + }, + { + name: "username and password almost match", + username: "administrator", + currentpass: "currentpassword", + password: "administrator1", + expectsErr: false, + }, + { + name: "12 byte password, 6 runes", + username: "admin", + currentpass: "currentpassword", + password: "пароль", + expectsErr: true, + }, + { + name: "23 byte password, 12 runes", + username: "admin", + currentpass: "currentpassword", + password: "абвгдеёжзий1", + expectsErr: false, + }, + { + name: "username equals password min length unicode", + username: "абвгдеёжзий1", + currentpass: "currentpassword", + password: "абвгдеёжзий1", + expectsErr: true, + }, + { + name: "new password matches current password", + username: "admin", + currentpass: "myfavoritepassword", + password: "myfavoritepassword", + expectsErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validatePassword(tt.username, tt.currentpass, tt.password, 12) + if err != nil && !tt.expectsErr { + t.Errorf("Received unexpected error: %v", err) + } else if err == nil && tt.expectsErr { + t.Error("Expected error when non received") + } + }) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_store.go new file mode 100644 index 0000000..f11cdb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/api/user/user_store.go @@ -0,0 +1,235 @@ +package user + +import ( + "strings" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/store/transform" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/bcrypt" + "k8s.io/client-go/tools/cache" +) + +const userByUsernameIndex = "auth.management.cattle.io/user-by-username" + +type userStore struct { + types.Store + mu sync.Mutex + userIndexer cache.Indexer + userManager user.Manager +} + +func SetUserStore(schema *types.Schema, mgmt *config.ScaledContext) { + userInformer := mgmt.Management.Users("").Controller().Informer() + userIndexers := map[string]cache.IndexFunc{ + userByUsernameIndex: userByUsername, + } + userInformer.AddIndexers(userIndexers) + + store := &userStore{ + Store: schema.Store, + mu: sync.Mutex{}, + userIndexer: userInformer.GetIndexer(), + userManager: mgmt.UserManager, + } + + t := &transform.Store{ + Store: store, + Transformer: func(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, opt *types.QueryOptions) (map[string]interface{}, error) { + // filter system users out of the api + if princIDs, ok := data[client.UserFieldPrincipalIDs].([]interface{}); ok { + for _, p := range princIDs { + pid, _ := p.(string) + if strings.HasPrefix(pid, "system://") { + if opt != nil && opt.Options["ByID"] == "true" { + return nil, httperror.NewAPIError(httperror.NotFound, "resource not found") + } + return nil, nil + } + } + } + + // set "me" field on user + userID := apiContext.Request.Header.Get("Impersonate-User") + if userID != "" { + id, ok := data[types.ResourceFieldID].(string) + if ok { + if id == userID { + data["me"] = "true" + } + } + } + + return data, nil + }, + } + + schema.Store = t +} + +func userByUsername(obj interface{}) ([]string, error) { + u, ok := obj.(*v3.User) + if !ok { + return []string{}, nil + } + + return []string{u.Username}, nil +} + +func hashPassword(data map[string]interface{}) error { + pass, ok := data[client.UserFieldPassword].(string) + if !ok { + return errors.New("password not a string") + } + hashed, err := HashPasswordString(pass) + if err != nil { + return err + } + data[client.UserFieldPassword] = string(hashed) + + return nil +} + +func HashPasswordString(password string) (string, error) { + hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return "", errors.Wrap(err, "problem encrypting password") + } + return string(hash), nil +} + +func (s *userStore) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + username, ok := data[client.UserFieldUsername].(string) + if !ok { + return nil, errors.New("invalid username") + } + + password, ok := data[client.UserFieldPassword].(string) + if !ok { + return nil, errors.New("invalid password") + } + + if err := validatePassword(username, "", password, settings.PasswordMinLength.GetInt()); err != nil { + return nil, httperror.NewAPIError(httperror.InvalidBodyContent, err.Error()) + } + + if err := hashPassword(data); err != nil { + return nil, err + } + + created, err := s.create(apiContext, schema, data) + if err != nil { + return nil, err + } + +Tries: + for x := 0; x < 3; x++ { + if id, ok := created[types.ResourceFieldID].(string); ok { + time.Sleep(time.Duration((x+1)*100) * time.Millisecond) + + created, err = s.ByID(apiContext, schema, id) + if err != nil { + logrus.Warnf("error while getting user: %v", err) + continue + } + + var principalIDs []interface{} + if pids, ok := created[client.UserFieldPrincipalIDs].([]interface{}); ok { + principalIDs = pids + } + + for _, pid := range principalIDs { + if pidString, ok := pid.(string); ok { + if strings.HasPrefix(pidString, "local://") { + break Tries + } + } + } + + created[client.UserFieldPrincipalIDs] = append(principalIDs, "local://"+id) + created, err = s.Update(apiContext, schema, created, id) + if err != nil { + if httperror.IsConflict(err) { + continue + } + + logrus.Warnf("error while updating user: %v", err) + break + } + break + } + } + + delete(created, client.UserFieldPassword) + + return created, nil +} + +func (s *userStore) create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + username, ok := data[client.UserFieldUsername].(string) + if !ok { + return nil, errors.New("invalid username") + } + + s.mu.Lock() + defer s.mu.Unlock() + + users, err := s.userIndexer.ByIndex(userByUsernameIndex, username) + if err != nil { + return nil, err + } + if len(users) > 0 { + return nil, httperror.NewFieldAPIError(httperror.NotUnique, "username", "Username is already in use.") + } + + return s.Store.Create(apiContext, schema, data) +} + +func (s *userStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + currentUser, err := getUser(apiContext) + if err != nil { + return nil, err + } + + willBeInactive := false + if val, ok := data[client.UserFieldEnabled].(bool); ok { + willBeInactive = !val + } + + if currentUser == id && willBeInactive { + return nil, httperror.NewAPIError(httperror.InvalidAction, "You cannot deactivate yourself") + } + + return s.Store.Update(apiContext, schema, data, id) +} + +func (s *userStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + currentUser, err := getUser(apiContext) + if err != nil { + return nil, err + } + + if currentUser == id { + return nil, httperror.NewAPIError(httperror.InvalidAction, "You cannot delete yourself") + } + + return s.Store.Delete(apiContext, schema, id) +} + +func getUser(apiContext *types.APIContext) (string, error) { + user := apiContext.Request.Header.Get("Impersonate-User") + if user == "" { + return "", httperror.NewAPIError(httperror.ServerError, "There was an error authorizing the user") + } + + return user, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit.go new file mode 100644 index 0000000..8f6dcae --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit.go @@ -0,0 +1,496 @@ +// Package audit is used to preform audit logging. +package audit + +import ( + "bytes" + "compress/gzip" + "compress/zlib" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "regexp" + "strings" + "time" + + "github.com/pborman/uuid" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/sirupsen/logrus" + k8stypes "k8s.io/apimachinery/pkg/types" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/utils/strings/slices" +) + +const ( + contentTypeJSON = "application/json" + contentEncodingGZIP = "gzip" + contentEncodingZLib = "deflate" + redacted = "[redacted]" +) + +// Level represents a desired logging level. +type Level int + +const ( + // LevelNull default value. + LevelNull Level = iota + // LevelMetadata log request header information. + LevelMetadata + // LevelRequest log metadata and request body. + LevelRequest + // LevelRequestResponse log metadata request body and response header and body. + LevelRequestResponse + + generateKubeconfigURI = "action=generateKubeconfig" + + auditLogErrKey = "auditLogError" +) + +var ( + bodyMethods = map[string]bool{ + http.MethodPut: true, + http.MethodPost: true, + } + sensitiveRequestHeader = []string{"Cookie", "Authorization", "X-Api-Tunnel-Params", "X-Api-Tunnel-Token", "X-Api-Auth-Header", "X-Amz-Security-Token"} + sensitiveResponseHeader = []string{"Cookie", "Set-Cookie", "X-Api-Set-Cookie-Header"} + sensitiveBodyFields = []string{"credentials", "applicationSecret", "oauthCredential", "serviceAccountCredential", "spKey", "spCert", "certificate", "privateKey"} + // ErrUnsupportedEncoding is returned when the response encoding is unsupported + ErrUnsupportedEncoding = fmt.Errorf("unsupported encoding") + secretBaseType = regexp.MustCompile(".\"baseType\":\"([A-Za-z]*[S|s]ecret)\".") +) + +type auditLog struct { + log *log + writer *LogWriter + reqBody []byte + keysToRedactRegex *regexp.Regexp +} + +type log struct { + AuditID k8stypes.UID `json:"auditID,omitempty"` + RequestURI string `json:"requestURI,omitempty"` + User *User `json:"user,omitempty"` + Method string `json:"method,omitempty"` + RemoteAddr string `json:"remoteAddr,omitempty"` + RequestTimestamp string `json:"requestTimestamp,omitempty"` + ResponseTimestamp string `json:"responseTimestamp,omitempty"` + ResponseCode int `json:"responseCode,omitempty"` + RequestHeader http.Header `json:"requestHeader,omitempty"` + ResponseHeader http.Header `json:"responseHeader,omitempty"` + RequestBody []byte `json:"requestBody,omitempty"` + ResponseBody []byte `json:"responseBody,omitempty"` + UserLoginName string `json:"userLoginName,omitempty"` +} + +var userKey struct{} + +// User holds information about the user who caused the audit log +type User struct { + Name string `json:"name,omitempty"` + Group []string `json:"group,omitempty"` + Extra map[string][]string `json:"extra,omitempty"` + // RequestUser is the --as user + RequestUser string `json:"requestUser,omitempty"` + // RequestGroups is the --as-group list + RequestGroups []string `json:"requestGroups,omitempty"` +} + +func getUserInfo(req *http.Request) *User { + user, _ := request.UserFrom(req.Context()) + return &User{ + Name: user.GetName(), + Group: user.GetGroups(), + Extra: user.GetExtra(), + } +} + +func getUserNameForBasicLogin(body []byte) string { + input := &v32.BasicLogin{} + err := json.Unmarshal(body, input) + if err != nil { + logrus.Debugf("error unmarshalling input, cannot add login info to audit log: %v", err) + return "" + } + return input.Username +} + +// FromContext gets the user information from the given context. +func FromContext(ctx context.Context) (*User, bool) { + u, ok := ctx.Value(userKey).(*User) + return u, ok +} + +func newAuditLog(writer *LogWriter, req *http.Request, keysToRedactRegex *regexp.Regexp) (*auditLog, error) { + auditLog := &auditLog{ + writer: writer, + log: &log{ + AuditID: k8stypes.UID(uuid.NewRandom().String()), + RequestURI: req.RequestURI, + Method: req.Method, + RemoteAddr: req.RemoteAddr, + RequestTimestamp: time.Now().Format(time.RFC3339), + }, + keysToRedactRegex: keysToRedactRegex, + } + + contentType := req.Header.Get("Content-Type") + loginReq := isLoginRequest(req.RequestURI) + if writer.Level >= LevelRequest || loginReq { + if bodyMethods[req.Method] && strings.HasPrefix(contentType, contentTypeJSON) { + reqBody, err := readBodyWithoutLosingContent(req) + if err != nil { + return nil, err + } + if loginReq { + loginName := getUserNameForBasicLogin(reqBody) + if loginName != "" { + auditLog.log.UserLoginName = loginName + } + } + if writer.Level >= LevelRequest { + auditLog.reqBody = reqBody + } + } + } + return auditLog, nil +} + +func (a *auditLog) write(userInfo *User, reqHeaders, resHeaders http.Header, resCode int, resBody []byte) error { + a.log.User = userInfo + a.log.ResponseTimestamp = time.Now().Format(time.RFC3339) + a.log.RequestHeader = filterOutHeaders(reqHeaders, sensitiveRequestHeader) + a.log.ResponseHeader = filterOutHeaders(resHeaders, sensitiveResponseHeader) + a.log.ResponseCode = resCode + + if a.log.UserLoginName != "" { + if a.log.User.Extra == nil { + a.log.User.Extra = make(map[string][]string) + } + a.log.User.Extra["username"] = []string{a.log.UserLoginName} + logrus.Debugf("Added username for login request to audit log %v", a.log.UserLoginName) + } + + var buffer bytes.Buffer + + alByte, err := json.Marshal(a.log) + if err != nil { + return fmt.Errorf("failed to marshal log message: %w", err) + } + + buffer.Write(bytes.TrimSuffix(alByte, []byte("}"))) + a.writeRequest(&buffer) + + if err = a.writeResponse(&buffer, resHeaders, resBody); err != nil { + return err + } + + buffer.WriteString("}") + + var compactBuffer bytes.Buffer + err = json.Compact(&compactBuffer, buffer.Bytes()) + if err != nil { + return fmt.Errorf("failed to compact audit log: %w", err) + } + + compactBuffer.WriteString("\n") + + _, err = a.writer.Output.Write(compactBuffer.Bytes()) + if err != nil { + return fmt.Errorf("failed to write log to output: %w", err) + } + + return nil +} + +// writeRequest attempts to write the API request to the log message. +func (a *auditLog) writeRequest(buf *bytes.Buffer) { + if a.writer.Level < LevelRequest || len(a.reqBody) == 0 { + return + } + + buf.WriteString(`,"requestBody":`) + buf.Write(bytes.TrimSuffix(a.redactSensitiveData(a.log.RequestURI, a.reqBody), []byte("\n"))) +} + +// writeResponse attempt to write the API response to the log message. +func (a *auditLog) writeResponse(buf *bytes.Buffer, resHeaders http.Header, resBody []byte) (err error) { + if a.writer.Level < LevelRequestResponse || resHeaders.Get("Content-Type") != contentTypeJSON || len(resBody) == 0 { + return nil + } + + switch resHeaders.Get("Content-Encoding") { + case contentEncodingGZIP: + resBody, err = decompressGZIP(resBody) + case contentEncodingZLib: + resBody, err = decompressZLib(resBody) + case "none": + // do nothing message is not encoded + case "": + // do nothing message is not encoded + default: + err = fmt.Errorf("%w '%s' in response header", ErrUnsupportedEncoding, resHeaders.Get("Content-Encoding")) + } + + if err != nil { + return fmt.Errorf("failed to decode response: %w", err) + } + + buf.WriteString(`,"responseBody":`) + buf.Write(bytes.TrimSuffix(a.redactSensitiveData(a.log.RequestURI, resBody), []byte("\n"))) + + return nil +} + +func isLoginRequest(uri string) bool { + return strings.Contains(uri, "?action=login") +} + +func readBodyWithoutLosingContent(req *http.Request) ([]byte, error) { + if !bodyMethods[req.Method] { + return nil, nil + } + + bodyBytes, err := ioutil.ReadAll(req.Body) + if err != nil { + return nil, fmt.Errorf("failed to read request body: %w", err) + } + req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + + return bodyBytes, nil +} + +func filterOutHeaders(headers http.Header, filterKeys []string) map[string][]string { + newHeader := make(map[string][]string) + for k, v := range headers { + if isExist(filterKeys, k) { + continue + } + newHeader[k] = v + } + return newHeader +} + +func isExist(array []string, key string) bool { + for _, v := range array { + if v == key { + return true + } + } + return false +} + +func redactedBodyWithErr(auditErr error) []byte { + m := map[string]string{ + auditLogErrKey: auditErr.Error(), + } + + body, err := json.Marshal(m) + if err != nil { + logrus.Debugf("auditLog: recevied invalid json: %v", err) + return []byte("{}") + } + + return body +} + +func (a *auditLog) redactSensitiveData(requestURI string, body []byte) []byte { + var m map[string]interface{} + if err := json.Unmarshal(body, &m); err != nil { + return redactedBodyWithErr(err) + } + + var changed bool + // Redact values of secret data. + if strings.Contains(requestURI, "secrets") || secretBaseType.Match(body) { + changed = a.redactSecretsData(requestURI, m) + } + + if strings.Contains(requestURI, generateKubeconfigURI) { + // generateKubeconfig cannot rely on regex because it uses config key instead of [kK]ube[cC]onfig + changed = redact(m, "config") + } + + // Redact values for data considered sensitive: passwords, tokens, etc. + if !a.redactMap(m) && !changed { + return body + } + + newBody, err := json.Marshal(m) + if err != nil { + return redactedBodyWithErr(err) + } + + return newBody +} + +func redact(body map[string]interface{}, key string) bool { + if _, ok := body[key]; !ok { + return false + } + body[key] = redacted + return true +} + +func (a *auditLog) redactSecretsData(requestURI string, body map[string]interface{}) bool { + var changed bool + + isK8sProxyList := strings.HasPrefix(requestURI, "/k8s/") && (body["kind"] != nil && body["kind"] == "SecretList") + isRegularList := body["type"] != nil && body["type"] == "collection" + if !(isK8sProxyList || isRegularList) { + return redactSecret(body) + } + + itemsKey := "data" + if isK8sProxyList { + itemsKey = "items" + } + + if _, ok := body[itemsKey]; !ok { + logrus.Debugf("auditLog: Skipping data redaction of secret bodies in secrets list: no key [%s] present, no data to redact.", itemsKey) + return false + } + + secretsList, ok := body[itemsKey].([]interface{}) + if !ok { + body[itemsKey] = redacted + logrus.Debugf("auditLog: Redacting entire value for key [%s] in response to request URI [%s], unable to assert body is of type []interface{}", itemsKey, requestURI) + return true + } + + for index, secret := range secretsList { + m, ok := secret.(map[string]interface{}) + if !ok { + secretsList[index] = redacted + logrus.Debugf("auditLog: Redacting entire value for index [%d] in list in response to request URI [%s]. Failed to assert secret element as map[string]interface", index, requestURI) + continue + } + + changed = redactSecret(m) || changed + secretsList[index] = m + } + + if changed { + body[itemsKey] = secretsList + return changed + } + + return changed +} + +func redactSecret(secret map[string]interface{}) bool { + var changed bool + if secret["data"] != nil { + secret["data"] = redacted + changed = true + } + if secret["stringData"] != nil { + secret["stringData"] = redacted + changed = true + } + if changed { + return changed + } + + for key := range secret { + if key == "id" || key == "baseType" || key == "created" { + // censorAll is used when the secret is formatted in such a way where its + // data fields cannot be distinguished from its other fields. In this case + // most of the data is redacted apart from "id", "baseType", "key" + continue + } + secret[key] = redacted + changed = true + } + return changed +} + +func (a *auditLog) redactMap(m map[string]interface{}) bool { + var changed bool + for key := range m { + switch val := m[key].(type) { + case string: + if a.keysToRedactRegex.MatchString(key) || slices.Contains(sensitiveBodyFields, key) { + changed = true + m[key] = redacted + } + case map[string]interface{}: + if a.redactMap(val) { + changed = true + m[key] = val + } + case []interface{}: + if a.redactSlice(val) { + changed = true + m[key] = val + } + } + } + + return changed +} + +func (a *auditLog) redactSlice(valSlice []interface{}) bool { + var changed bool + for i, v := range valSlice { + switch val := v.(type) { + case map[string]interface{}: + if a.redactMap(val) { + changed = true + valSlice[i] = val + } + case string: + // this attempts to identify slices that represent commands of the format ["--, "], and + // redact value is command indicates it is sensitive. + if i+1 == len(valSlice) { + continue + } + if !strings.HasPrefix(val, "--") || !a.keysToRedactRegex.MatchString(val) { + // not a sensitive option flag + continue + } + valSlice[i+1] = redacted + changed = true + } + } + return changed +} + +func decompressGZIP(data []byte) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("failed to create gzip reader: %w", err) + } + + return decompress(gz) +} + +func decompressZLib(data []byte) ([]byte, error) { + zr, err := zlib.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("failed to create zlib reader: %w", err) + } + + return decompress(zr) +} + +func decompress(readCloser io.ReadCloser) ([]byte, error) { + rawData, err := ioutil.ReadAll(readCloser) + if err != nil { + retErr := fmt.Errorf("failed to read compressed response: %w", err) + closeErr := readCloser.Close() + if closeErr != nil { + // Using %v for close error because you can currently only wrap one error. + // The read error is more important to the caller in this instance. + retErr = fmt.Errorf("%w; failed to close readCloser: %v", retErr, closeErr) + } + return nil, retErr + } + + if err = readCloser.Close(); err != nil { + return rawData, fmt.Errorf("failed to close reader: %w", err) + } + + return rawData, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit_test.go new file mode 100644 index 0000000..a4e91e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/audit_test.go @@ -0,0 +1,569 @@ +package audit + +import ( + "bytes" + "compress/gzip" + "compress/zlib" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "reflect" + "regexp" + "strings" + "testing" + + "github.com/rancher/rancher/pkg/data/management" + "github.com/stretchr/testify/suite" +) + +var errAny = errors.New("any error is allowed") + +type AuditTest struct { + suite.Suite +} + +func TestAuditSuite(t *testing.T) { + suite.Run(t, new(AuditTest)) +} +func (a *AuditTest) TestRedactSensitiveData() { + r, err := constructKeyRedactRegex() + a.Require().NoError(err, "failed compiling sanitizing regex") + logger := auditLog{ + log: nil, + writer: nil, + reqBody: nil, + keysToRedactRegex: r, + } + + machineDataInput, machineDataWant := []byte("{"), []byte("{") + for _, v := range management.DriverData { + for key, value := range v { + if strings.HasPrefix(key, "optional") { + continue + } + public := strings.HasPrefix(key, "public") + for _, item := range value { + machineDataInput = append(machineDataInput, []byte("\""+item+"\" : \"fake_"+item+"\",")...) + if public { + machineDataWant = append(machineDataWant, []byte("\""+item+"\" : \"fake_"+item+"\",")...) + } else { + machineDataWant = append(machineDataWant, []byte("\""+item+"\" : \""+redacted+"\",")...) + } + } + } + } + machineDataInput[len(machineDataInput)-1] = byte('}') + machineDataWant[len(machineDataWant)-1] = byte('}') + + tests := []struct { + name string + uri string + input []byte + want []byte + }{ + { + name: "password entry", + input: []byte(`{"password": "fake_password", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"password":"%s","user":"fake_user"}`, redacted)), + }, + { + name: "Password entry", + input: []byte(`{"Password": "fake_password", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"Password":"%s","user":"fake_user"}`, redacted)), + }, + { + name: "password entry no space", + input: []byte(`{"password":"whatever you want", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"password":"%s", "user": "fake_user"}`, redacted)), + }, + { + name: "Password entry no space", + input: []byte(`{"Password":"A whole bunch of \"\"}{()","user":"fake_user"}`), + want: []byte(fmt.Sprintf(`{"Password":"%s", "user": "fake_user"}`, redacted)), + }, + { + name: "currentPassword entry", + input: []byte(`{"currentPassword": "something super secret", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"currentPassword": "%s", "user": "fake_user"}`, redacted)), + }, + { + name: "newPassword entry", + input: []byte(`{"newPassword": "don't share this", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"newPassword": "%s", "user": "fake_user"}`, redacted)), + }, + { + name: "Multiple password entries", + input: []byte(`{"currentPassword": "fake_password", "newPassword": "new_fake_password", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"currentPassword": "%s", "newPassword": "%[1]s", "user": "fake_user"}`, redacted)), + }, + { + name: "No password entries", + input: []byte(`{"user": "fake_user", "user_info": "some information about the user", "request_info": "some info about the request"}`), + want: []byte(`{"user": "fake_user", "user_info": "some information about the user", "request_info": "some info about the request"}`), + }, + { + name: "Strategic password examples", + input: []byte(`{"anotherPassword":"\"password\"","currentPassword":"password\":","newPassword":"newPassword\\\":","shortPassword":"'","user":"fake_user"}`), + want: []byte(fmt.Sprintf(`{"anotherPassword":"%s","currentPassword":"%[1]s","newPassword":"%[1]s","shortPassword":"%[1]s","user":"fake_user"}`, redacted)), + }, + { + name: "Token entry", + input: []byte(`{"accessToken": "fake_access_token", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"accessToken": "%s", "user": "fake_user"}`, redacted)), + }, + { + name: "Token entry in slice", + input: []byte(`{"data":[{"accessToken": "fake_access_token", "user": "fake_user"}]}`), + want: []byte(fmt.Sprintf(`{"data":[{"accessToken": "%s", "user": "fake_user"}]}`, redacted)), + }, + { + name: "Token entry in args slice", + input: []byte(`{"data":{"commands":["--user","user","--token","sometoken"]}}`), + want: []byte(fmt.Sprintf(`{"data":{"commands":["--user","user","--token","%s"]}}`, redacted)), + }, + { + name: "Token entry in args slice but is last element of slice", + input: []byte(`{"data":{"commands":["--user","user","--token"]}}`), + want: []byte(`{"data":{"commands":["--user","user","--token"]}}`), + }, + { + name: "With public fields", + input: []byte(`{"accessKey": "fake_access_key", "secretKey": "fake_secret_key", "user": "fake_user"}`), + want: []byte(fmt.Sprintf(`{"accessKey": "fake_access_key", "secretKey": "%s", "user": "fake_user"}`, redacted)), + }, + { + name: "With secret data", + input: []byte(`{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}, "accessToken" : "fake_access_token"}`), + want: []byte(fmt.Sprintf(`{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":"%s", "accessToken" : "%[1]s"}`, redacted)), + uri: "/secrets", + }, + { + name: "With secret list data", + input: []byte(`{"type": "collection", "data":[{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}},{"type":"Opaque","metadata":{"namespace":"default","name":"my secret2"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}}]}`), + want: []byte(fmt.Sprintf(`{"type": "collection", "data":[{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":"%s"},{"type":"Opaque","metadata":{"namespace":"default","name":"my secret2"},"_type":"Opaque","data":"%[1]s"}]}`, redacted)), + uri: "/v1/secrets", + }, + { + // norman transforms some secret subtypes to where their data fields cannot be distinguished from non-sensitive fields. + // In this case, all fields aside from id, created, and baseType should be redacted. + name: "With secret list data but no data field for array elements", + input: []byte(`{"type": "collection", "data":[{"id":"p-12345:testsecret","baseType":"secret","type":"Opaque","_type":"Opaque","foo":"something","bar":"something","accessToken":"token"}]}`), + want: []byte(fmt.Sprintf(`{"data":[{"_type":"%s","accessToken":"%[1]s","bar":"%[1]s","baseType":"secret","foo":"%[1]s","id":"p-12345:testsecret","type":"%[1]s"}],"type":"collection"}`, redacted)), + uri: "/secrets", + }, + { + name: "With secret list data from k8s proxy", + input: []byte(`{"kind": "SecretList", "items":[{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}}]}`), + want: []byte(fmt.Sprintf(`{"kind": "SecretList", "items":[{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":"%s"}]}`, redacted)), + uri: "/k8s/clusters/local/api/v1/secrets?limit=500", + }, + { + name: "With secret data and wrong URI", + input: []byte(`{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}, "accessToken" : "fake_access_token"}`), + want: []byte(fmt.Sprintf(`{"type":"Opaque","metadata":{"namespace":"default","name":"my secret"},"_type":"Opaque","data":{"foo":"c3VwZXIgc2VjcmV0IGRhdGE=\\", "bar": "U3VwZXIgU2VjcmV0IERhdGEK"}, "accessToken" : "%s"}`, redacted)), + uri: "/not-secret", + }, + { + name: "With nested sensitive information", + input: []byte(`{"sensitiveData": {"accessToken": "fake_access_token", "user": "fake_user"}}`), + want: []byte(fmt.Sprintf(`{"sensitiveData": {"accessToken": "%s", "user": "fake_user"}}`, redacted)), + }, + { + name: "With all machine driver fields", + input: machineDataInput, + want: machineDataWant, + }, + { + name: "With no secret uri but secret base type slice", + input: []byte(`{"type":"collection","data":[{"baseType":"namespacedSecret","creatorId":null,"data":{"testfield":"somesecretencodeddata"},"id":"cattle-system:test","kind":"Opaque"}]}`), + want: []byte(fmt.Sprintf(`{"type":"collection","data":[{"baseType":"namespacedSecret","creatorId":null,"data":"%s","id":"cattle-system:test","kind":"Opaque"}]}`, redacted)), + uri: `/v3/project/local:p-12345/namespacedcertificates?limit=-1&sort=name`, + }, + { + name: "With kubeconfig from generateKubeconfig action", + input: []byte(`{"baseType":"generateKubeConfigOutput","config":"apiVersion: v1\nkind: Config\nclusters:\n- name: \"somecluster-rke\"\n cluster:\n server: \"https://rancherurl.com/k8s/clusters/c-xxxxx\"\n- name: \"somecluster-rke-somecluster-rke1\"\n cluster:\n server: \"https://34.211.205.110:6443\"\n certificate-authority-data: \"somecadata\"\n\nusers:\n- name: \"somecluster-rke\"\n user:\n token: \"kubeconfig-user-12345:sometoken\"\n\n\ncontexts:\n- name: \"somecluster-rke\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke\"\n- name: \"somecluster-rke-somecluster-rke1\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke-somecluster-rke1\"\n\ncurrent-context: \"somecluster-rke\"\n","type":"generateKubeConfigOutput"}`), + want: []byte(fmt.Sprintf(`{"baseType":"generateKubeConfigOutput","config":"%s","type":"generateKubeConfigOutput"}`, redacted)), + uri: `/v3/clusters/c-xxxxx?action=generateKubeconfig`, + }, + { + name: "With kubeconfig from connect agent", + input: []byte(`{"kubeConfig":"apiVersion: v1\nkind: Config\nclusters:\n- name: \"somecluster-rke\"\n cluster:\n server: \"https://rancherurl.com/k8s/clusters/c-xxxxx\"\n- name: \"somecluster-rke-somecluster-rke1\"\n cluster:\n server: \"https://34.211.205.110:6443\"\n certificate-authority-data: \"somecadata\"\n\nusers:\n- name: \"somecluster-rke\"\n user:\n token: \"kubeconfig-user-12345:sometoken\"\n\n\ncontexts:\n- name: \"somecluster-rke\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke\"\n- name: \"somecluster-rke-somecluster-rke1\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke-somecluster-rke1\"\n\ncurrent-context: \"somecluster-rke\"\n","namespace":"testns","secretName":"secret-name"}`), + want: []byte(fmt.Sprintf(`{"kubeConfig":"%s","namespace":"testns","secretName":"secret-name"}`, redacted)), + uri: `/v3/connect/agent`, + }, + { + name: "With kubeconfig from random request", + input: []byte(`{"kubeConfig":"apiVersion: v1\nkind: Config\nclusters:\n- name: \"somecluster-rke\"\n cluster:\n server: \"https://rancherurl.com/k8s/clusters/c-xxxxx\"\n- name: \"somecluster-rke-somecluster-rke1\"\n cluster:\n server: \"https://34.211.205.110:6443\"\n certificate-authority-data: \"somecadata\"\n\nusers:\n- name: \"somecluster-rke\"\n user:\n token: \"kubeconfig-user-12345:sometoken\"\n\n\ncontexts:\n- name: \"somecluster-rke\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke\"\n- name: \"somecluster-rke-somecluster-rke1\"\n context:\n user: \"somecluster-rke\"\n cluster: \"somecluster-rke-somecluster-rke1\"\n\ncurrent-context: \"somecluster-rke\"\n","namespace":"testns","secretName":"secret-name"}`), + want: []byte(fmt.Sprintf(`{"kubeConfig":"%s","namespace":"testns","secretName":"secret-name"}`, redacted)), + uri: `asdf`, + }, + { + name: "With items from sensitiveBodyFields", + input: []byte(`{"credentials": "{'fakeCredName': 'fakeCred'}", "applicationSecret": "fakeAppSecret", "oauthCredential": "fakeOauth", "serviceAccountCredential": "fakeSACred", "spKey": "fakeSPKey", "spCert": "fakeSPCERT", "certificate": "fakeCert", "privateKey": "fakeKey"}`), + want: []byte(fmt.Sprintf(`{"credentials": "%s", "applicationSecret": "%[1]s", "oauthCredential": "%[1]s", "serviceAccountCredential": "%[1]s", "spKey": "%[1]s", "spCert": "%[1]s", "certificate": "%[1]s", "privateKey": "%[1]s"}`, redacted)), + }, + { + name: "With malformed input", + input: []byte(`{"key": "value", "response":}`), + want: []byte(fmt.Sprintf(`{"%s": "invalid character '}' looking for beginning of value"}`, auditLogErrKey)), + }, + } + for i := range tests { + test := tests[i] + a.Run(test.name, func() { + var want map[string]interface{} + err := json.Unmarshal(test.want, &want) + a.NoError(err, "failed to unmarshal") + got := logger.redactSensitiveData(test.uri, test.input) + var gotMap map[string]interface{} + err = json.Unmarshal(got, &gotMap) + a.NoError(err, "failed to unmarshal") + a.Equal(want, gotMap, "redactSensitiveData() for map = %s, want %s", got, test.want) + }) + } +} +func (a *AuditTest) TestCompression() { + // Create a temp log file + tmpFile, err := os.CreateTemp("", "audit-test") + a.Require().NoError(err, "Failed to create temp directory.") + // close the file so the logger can open it for writing + err = tmpFile.Close() + a.Require().NoError(err, "Failed to close temporary file after creation") + + tmpPath := tmpFile.Name() + defer func() { + err = os.RemoveAll(tmpPath) + a.NoError(err, "Failed to clean up temp directory") + }() + + writer := NewLogWriter(tmpPath, LevelRequestResponse, 30, 30, 100) + a.Require().NotNil(writer, "Failed to create auditWriter.") + + sensitiveRegex, err := regexp.Compile(`[pP]assword|[tT]oken`) + a.Require().NoErrorf(err, "Failed to create valid regex: %v", err) + + req, err := http.NewRequest(http.MethodGet, "/test", nil) + a.Require().NoErrorf(err, "Failed to create request: %v", err) + + auditLog, err := newAuditLog(writer, req, sensitiveRegex) + a.Require().NoErrorf(err, "Failed to create AuditLog: %v", err) + + const testString = "{\"test\":\"response\"}" + const testString2 = "{\"test\":\"request\"}" + + tests := []struct { + name string + respHeader http.Header + respBody []byte + reqBody []byte + returnCode int + expectedRespBody string + expectedReqBody string + level Level + Error error + }{ + { + name: "invalid Encoding", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"bzip2"}}, + respBody: []byte(testString), + Error: ErrUnsupportedEncoding, + level: LevelRequestResponse, + }, + { + name: "none encoding", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + respBody: []byte(testString), + reqBody: []byte(testString2), + expectedRespBody: testString, + expectedReqBody: testString2, + level: LevelRequestResponse, + }, + { + name: "request only", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + respBody: []byte(testString), + reqBody: []byte(testString2), + expectedReqBody: testString2, + level: LevelRequest, + }, + { + name: "meta only", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + respBody: []byte(testString), + reqBody: []byte(testString2), + level: LevelMetadata, + }, + { + name: "gzip encoding", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"gzip"}}, + respBody: a.gzip(testString), + expectedRespBody: testString, + level: LevelRequestResponse, + }, + { + name: "deflate encoding", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"deflate"}}, + respBody: a.deflate(testString), + expectedRespBody: testString, + level: LevelRequestResponse, + }, + { + name: "empty gzip response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"gzip"}}, + respBody: a.gzip("{}"), + expectedRespBody: "{}", + level: LevelRequestResponse, + }, + { + name: "empty deflate response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"deflate"}}, + respBody: a.deflate("{}"), + expectedRespBody: "{}", + level: LevelRequestResponse, + }, + + { + name: "empty response", + respHeader: http.Header{"Content-Type": []string{"application/json"}}, + respBody: []byte(""), + expectedRespBody: "", + level: LevelRequestResponse, + }, + { + name: "invalid gzip response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"gzip"}}, + respBody: []byte(testString), + Error: errAny, + level: LevelRequestResponse, + }, + { + name: "invalid deflate response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"deflate"}}, + respBody: []byte(testString), + Error: errAny, + level: LevelRequestResponse, + }, + { + name: "invalid json gzip response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"gzip"}}, + respBody: a.gzip(""), + expectedRespBody: `{"auditLogError":"unexpected end of JSON input"}`, + level: LevelRequestResponse, + }, + { + name: "invalid json deflate response", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"deflate"}}, + respBody: a.deflate("Bad Data[]}"), + expectedRespBody: `{"auditLogError":"invalid character 'B' looking for beginning of value"}`, + level: LevelRequestResponse, + }, + } + + for i := range tests { + test := tests[i] + a.Run(test.name, func() { + writer.Level = test.level + auditLog.reqBody = []byte(test.reqBody) + // write the test to the audit logger + err := auditLog.write(nil, req.Header, test.respHeader, test.returnCode, test.respBody) + + // if we are expecting an error check the error is not nil and the correct type + if test.Error != nil { + if errors.Is(test.Error, errAny) { + a.Error(err, "Expected an Error") + return + } + a.Truef(errorIsType(err, test.Error), "Received error does not wrap an error of type '%T'", test.Error) + return + } + a.Require().NoErrorf(err, "Failed to write log: %v.", err) + + // validate the json written to the file is as expected\ + + expectedData := a.addMeta(auditLog.log, nil, test.respHeader, test.expectedReqBody, test.expectedRespBody) + + a.JSONEqf(expectedData, a.drain(tmpPath), "Incorrect JSON stored.") + }) + } +} + +func (a *AuditTest) TestFilterSensitiveHeader() { + // Create a temp log file + tmpFile, err := os.CreateTemp("", "audit-test") + a.Require().NoError(err, "Failed to create temp directory.") + // close the file so the logger can open it for writing + err = tmpFile.Close() + a.Require().NoError(err, "Failed to close temporary file after creation") + + tmpPath := tmpFile.Name() + defer func() { + err = os.RemoveAll(tmpPath) + a.NoError(err, "Failed to clean up temp directory") + }() + + writer := NewLogWriter(tmpPath, LevelRequestResponse, 30, 30, 100) + a.Require().NotNil(writer, "Failed to create auditWriter.") + + sensitiveRegex, err := regexp.Compile(`[pP]assword|[tT]oken`) + a.Require().NoErrorf(err, "Failed to create valid regex: %v", err) + + req, err := http.NewRequest(http.MethodGet, "/test", nil) + a.Require().NoErrorf(err, "Failed to create request: %v", err) + + auditLog, err := newAuditLog(writer, req, sensitiveRegex) + a.Require().NoErrorf(err, "Failed to create AuditLog: %v", err) + + tests := []struct { + name string + respHeader http.Header + reqHeader http.Header + expectedRespHeader http.Header + expectedReqHeader http.Header + }{ + { + name: "sensitive request header: \"X-Api-Tunnel-Param\"", + reqHeader: http.Header{"X-Api-Tunnel-Params": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive request header: \"X-Api-Tunnel-Token\"", + reqHeader: http.Header{"X-Api-Tunnel-Token": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive request header: \"Authorization\"", + reqHeader: http.Header{"Authorization": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive request header: \"Cookie\"", + reqHeader: http.Header{"Cookie": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive request header: \"X-Api-Auth-Header\"", + reqHeader: http.Header{"X-Api-Auth-Header": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive request header: \"X-Amz-Security-Token\"", + reqHeader: http.Header{"X-Amz-Security-Token": []string{"abcd"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "non-sensitive request header and sensitive request header: \"Cookie\"", + reqHeader: http.Header{"Cookie": []string{"abcd"}, "User-Agent": []string{"useragent1"}}, + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + expectedReqHeader: http.Header{"User-Agent": []string{"useragent1"}}, + }, + { + name: "sensitive response header: \"Cookie\"", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}, "Cookie": []string{"abcd"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive response header: \"Set-Cookie\"", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}, "Set-Cookie": []string{"abcd"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + { + name: "sensitive response header: \"X-Api-Set-Cookie-Header\"", + respHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}, "X-Api-Set-Cookie-Header": []string{"abcd"}}, + expectedRespHeader: http.Header{"Content-Type": []string{"application/json"}, "Content-Encoding": []string{"none"}}, + }, + } + writer.Level = LevelMetadata + for i := range tests { + test := tests[i] + a.Run(test.name, func() { + writer.Level = 1 + // write the test to the audit logger + auditLog.log.RequestHeader = test.reqHeader + err := auditLog.write(nil, test.reqHeader, test.respHeader, 0, []byte{}) + + a.Require().NoErrorf(err, "Failed to write log: %v.", err) + + // validate the json written to the file is as expected\ + + expectedData := a.addMeta(auditLog.log, test.expectedReqHeader, test.expectedRespHeader, "", "") + + a.JSONEqf(expectedData, a.drain(tmpPath), "Incorrect JSON stored.") + }) + } +} + +// addMeta adds expected log metadata to the expected log message. +func (a *AuditTest) addMeta(log *log, reqHeader, respHeader http.Header, reqBody, respBody string) string { + data := map[string]interface{}{} + if reqBody != "" { + reqBodyData := map[string]interface{}{} + err := json.Unmarshal([]byte(reqBody), &reqBodyData) + a.NoErrorf(err, "Failed to unmarshal test body data: %v", err) + data["requestBody"] = reqBodyData + } + if respBody != "" { + respBodyData := map[string]interface{}{} + err := json.Unmarshal([]byte(respBody), &respBodyData) + a.NoErrorf(err, "Failed to unmarshal test body data: %v", err) + data["responseBody"] = respBodyData + } + + data["method"] = log.Method + data["requestTimestamp"] = log.RequestTimestamp + data["auditID"] = log.AuditID + data["responseHeader"] = respHeader + if reqHeader != nil { + data["requestHeader"] = reqHeader + } + data["responseTimestamp"] = log.ResponseTimestamp + retJSON, err := json.Marshal(data) + a.NoErrorf(err, "Failed to add json metadata for log message check: %v", err) + return string(retJSON) +} + +// read a file's content then truncate +func (a *AuditTest) drain(tmpFile string) string { + data, err := os.ReadFile(tmpFile) + a.NoErrorf(err, "Failed to read the temp file") + err = os.Truncate(tmpFile, 0) + a.NoError(err, "Failed to truncate temp file") + return string(data) +} + +// gzip the given string +func (a *AuditTest) gzip(input string) []byte { + var buf bytes.Buffer + w := gzip.NewWriter(&buf) + w.Write([]byte(input)) + a.Require().NoError(w.Close()) + return buf.Bytes() +} + +// deflate the given string +func (a *AuditTest) deflate(input string) []byte { + var buf bytes.Buffer + w := zlib.NewWriter(&buf) + w.Write([]byte(input)) + a.Require().NoError(w.Close()) + return buf.Bytes() +} + +func errorIsType(err, target error) bool { + targetType := reflect.TypeOf(target) + for err != nil { + if reflect.TypeOf(err) == targetType { + return true + } + err = errors.Unwrap(err) + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/filter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/filter.go new file mode 100644 index 0000000..60cfe56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/filter.go @@ -0,0 +1,141 @@ +package audit + +import ( + "bufio" + "bytes" + "context" + "fmt" + "net" + "net/http" + "reflect" + "regexp" + "strings" + "sync" + "time" + + "github.com/rancher/rancher/pkg/auth/util" + "github.com/rancher/rancher/pkg/data/management" + "github.com/sirupsen/logrus" +) + +var ( + errorDebounceTime = time.Second * 30 +) + +func NewAuditLogMiddleware(auditWriter *LogWriter) (func(http.Handler) http.Handler, error) { + sensitiveRegex, err := constructKeyRedactRegex() + return func(next http.Handler) http.Handler { + return &auditHandler{ + next: next, + auditWriter: auditWriter, + sanitizingRegex: sensitiveRegex, + errMap: make(map[string]time.Time), + errLock: &sync.Mutex{}, + } + }, err +} + +// constructKeyRedactRegex builds a regex for matching non-public fields from management.DriverData as well as fields that end with [pP]assword or [tT]oken. +func constructKeyRedactRegex() (*regexp.Regexp, error) { + s := strings.Builder{} + s.WriteRune('(') + for _, v := range management.DriverData { + for key, value := range v { + if strings.HasPrefix(key, "public") || strings.HasPrefix(key, "optional") { + continue + } + for _, item := range value { + s.WriteString(item + "|") + } + } + } + s.WriteString(`[pP]assword|[tT]oken|[kK]ube[cC]onfig)`) + + return regexp.Compile(s.String()) +} + +type auditHandler struct { + next http.Handler + auditWriter *LogWriter + sanitizingRegex *regexp.Regexp + errMap map[string]time.Time + errLock *sync.Mutex +} + +func (h auditHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if h.auditWriter == nil { + h.next.ServeHTTP(rw, req) + return + } + + user := getUserInfo(req) + + context := context.WithValue(req.Context(), userKey, user) + req = req.WithContext(context) + + auditLog, err := newAuditLog(h.auditWriter, req, h.sanitizingRegex) + if err != nil { + util.ReturnHTTPError(rw, req, http.StatusInternalServerError, err.Error()) + return + } + + wr := &wrapWriter{ResponseWriter: rw, auditWriter: h.auditWriter, statusCode: http.StatusOK} + h.next.ServeHTTP(wr, req) + + err = auditLog.write(user, req.Header, wr.Header(), wr.statusCode, wr.buf.Bytes()) + if err == nil { + return + } + + // Locking after next is called to avoid performance hits on the request. + h.errLock.Lock() + defer h.errLock.Unlock() + + // Only log duplicate error messages at most every errorDebounceTime. + // This is to prevent the rancher logs from being flooded with error messages + // when the log path is invalid or any other error that will always cause a write to fail. + if lastSeen, ok := h.errMap[err.Error()]; !ok || time.Since(lastSeen) > errorDebounceTime { + logrus.Warnf("Failed to write audit log: %s", err) + h.errMap[err.Error()] = time.Now() + } +} + +type wrapWriter struct { + http.ResponseWriter + auditWriter *LogWriter + statusCode int + buf bytes.Buffer +} + +func (aw *wrapWriter) WriteHeader(statusCode int) { + aw.ResponseWriter.WriteHeader(statusCode) + aw.statusCode = statusCode +} + +func (aw *wrapWriter) Write(body []byte) (int, error) { + aw.buf.Write(body) + return aw.ResponseWriter.Write(body) +} + +func (aw *wrapWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hijacker, ok := aw.ResponseWriter.(http.Hijacker); ok { + return hijacker.Hijack() + } + return nil, nil, fmt.Errorf("Upstream ResponseWriter of type %v does not implement http.Hijacker", reflect.TypeOf(aw.ResponseWriter)) +} + +func (aw *wrapWriter) CloseNotify() <-chan bool { + if cn, ok := aw.ResponseWriter.(http.CloseNotifier); ok { + return cn.CloseNotify() + } + logrus.Errorf("Upstream ResponseWriter of type %v does not implement http.CloseNotifier", reflect.TypeOf(aw.ResponseWriter)) + return make(<-chan bool) +} + +func (aw *wrapWriter) Flush() { + if f, ok := aw.ResponseWriter.(http.Flusher); ok { + f.Flush() + return + } + logrus.Errorf("Upstream ResponseWriter of type %v does not implement http.Flusher", reflect.TypeOf(aw.ResponseWriter)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/logwriter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/logwriter.go new file mode 100644 index 0000000..ef117e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/audit/logwriter.go @@ -0,0 +1,38 @@ +package audit + +import ( + "context" + + lumberjack "gopkg.in/natefinch/lumberjack.v2" +) + +type LogWriter struct { + Level Level + Output *lumberjack.Logger +} + +func (l *LogWriter) Start(ctx context.Context) { + if l == nil { + return + } + go func() { + <-ctx.Done() + l.Output.Close() + }() +} + +func NewLogWriter(path string, level Level, maxAge, maxBackup, maxSize int) *LogWriter { + if path == "" || level == LevelNull { + return nil + } + + return &LogWriter{ + Level: level, + Output: &lumberjack.Logger{ + Filename: path, + MaxAge: maxAge, + MaxBackups: maxBackup, + MaxSize: maxSize, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service.go new file mode 100644 index 0000000..b42101f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service.go @@ -0,0 +1,254 @@ +// Package cleanup defines a type that represents a cleanup routine for an auth provider. +package cleanup + +import ( + "errors" + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/api/secrets" + controllers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +var errAuthConfigNil = errors.New("cannot get auth provider if its config is nil") + +// Service performs cleanup of resources associated with an auth provider. +type Service struct { + secretsInterface corev1.SecretInterface + + userCache controllers.UserCache + userClient controllers.UserClient + + clusterRoleTemplateBindingsCache controllers.ClusterRoleTemplateBindingCache + clusterRoleTemplateBindingsClient controllers.ClusterRoleTemplateBindingClient + + globalRoleBindingsCache controllers.GlobalRoleBindingCache + globalRoleBindingsClient controllers.GlobalRoleBindingClient + + projectRoleTemplateBindingsCache controllers.ProjectRoleTemplateBindingCache + projectRoleTemplateBindingsClient controllers.ProjectRoleTemplateBindingClient + + tokensCache controllers.TokenCache + tokensClient controllers.TokenClient +} + +// NewCleanupService creates and returns a new auth provider cleanup service. +func NewCleanupService(secretsInterface corev1.SecretInterface, c controllers.Interface) *Service { + return &Service{ + secretsInterface: secretsInterface, + + userCache: c.User().Cache(), + userClient: c.User(), + + clusterRoleTemplateBindingsCache: c.ClusterRoleTemplateBinding().Cache(), + clusterRoleTemplateBindingsClient: c.ClusterRoleTemplateBinding(), + + projectRoleTemplateBindingsCache: c.ProjectRoleTemplateBinding().Cache(), + projectRoleTemplateBindingsClient: c.ProjectRoleTemplateBinding(), + + globalRoleBindingsCache: c.GlobalRoleBinding().Cache(), + globalRoleBindingsClient: c.GlobalRoleBinding(), + + tokensCache: c.Token().Cache(), + tokensClient: c.Token(), + } +} + +// Run takes an auth config and checks if its auth provider is disabled, and ensures that any resources associated with it, +// such as secrets, CRTBs, PRTBs, GRBs, Users, are deleted. +func (s *Service) Run(config *v3.AuthConfig) error { + if err := secrets.CleanupClientSecrets(s.secretsInterface, config); err != nil { + return fmt.Errorf("error cleaning up resources associated with a disabled auth provider %s: %w", config.Name, err) + } + + if err := s.deleteGlobalRoleBindings(config); err != nil { + return fmt.Errorf("error cleaning up global role bindings associated with a disabled auth provider %s: %w", config.Name, err) + } + + if err := s.deleteClusterRoleTemplateBindings(config); err != nil { + return fmt.Errorf("error cleaning up cluster role template bindings associated with a disabled auth provider %s: %w", config.Name, err) + } + + if err := s.deleteProjectRoleTemplateBindings(config); err != nil { + return fmt.Errorf("error cleaning up project role template bindings associated with a disabled auth provider %s: %w", config.Name, err) + } + + if err := s.deleteUsers(config); err != nil { + return fmt.Errorf("error cleaning up users associated with a disabled auth provider %s: %w", config.Name, err) + } + + if err := s.deleteTokens(config); err != nil { + return fmt.Errorf("error cleaning up tokens associated with a disabled auth provider %s: %w", config.Name, err) + } + + return nil +} + +func (s *Service) deleteClusterRoleTemplateBindings(config *v3.AuthConfig) error { + if config == nil { + return errAuthConfigNil + } + list, err := s.clusterRoleTemplateBindingsCache.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list cluster role template bindings: %w", err) + } + + for _, b := range list { + providerName := getProviderNameFromPrincipalNames(b.UserPrincipalName, b.GroupPrincipalName) + if providerName == config.Name { + err := s.clusterRoleTemplateBindingsClient.Delete(b.Namespace, b.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + } + } + + return nil +} + +func (s *Service) deleteGlobalRoleBindings(config *v3.AuthConfig) error { + if config == nil { + return errAuthConfigNil + } + list, err := s.globalRoleBindingsCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list global role bindings: %w", err) + } + + for _, b := range list { + providerName := getProviderNameFromPrincipalNames(b.GroupPrincipalName) + if providerName == config.Name { + err := s.globalRoleBindingsClient.Delete(b.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + } + } + + return nil +} + +func (s *Service) deleteProjectRoleTemplateBindings(config *v3.AuthConfig) error { + if config == nil { + return errAuthConfigNil + } + prtbs, err := s.projectRoleTemplateBindingsCache.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list project role template bindings: %w", err) + } + + for _, b := range prtbs { + providerName := getProviderNameFromPrincipalNames(b.UserPrincipalName, b.GroupPrincipalName) + if providerName == config.Name { + err := s.projectRoleTemplateBindingsClient.Delete(b.Namespace, b.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + } + } + + return nil +} + +// deleteUsers deletes all external users (for the given provider specified in the config), +// who never were local users. It does not delete external users who were local before the provider had been set up. +// The method only removes the external principal IDs from those users. +// External users are those who have multiple principal IDs associated with them. +// A local admin (not necessarily the default admin) who had set up the provider will have two principal IDs, +// but will also have a password. +// This is how Rancher distinguishes fully external users from those who are external, too, but were once local. +func (s *Service) deleteUsers(config *v3.AuthConfig) error { + if config == nil { + return errAuthConfigNil + } + users, err := s.userCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list users: %w", err) + } + + for _, u := range users { + providerName := getProviderNameFromPrincipalNames(u.PrincipalIDs...) + if providerName == config.Name { + // A fully external user (who was never local) has no password. + if u.Password == "" { + err := s.userClient.Delete(u.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + } else { + if err := s.resetLocalUser(u); err != nil { + return fmt.Errorf("failed to reset local user: %w", err) + } + } + } + } + + return nil +} + +// deleteTokens deletes all the tokens created with the disabled provider +func (s *Service) deleteTokens(config *v3.AuthConfig) error { + if config == nil { + return errAuthConfigNil + } + + tokens, err := s.tokensCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list tokens: %w", err) + } + + for _, t := range tokens { + if t.AuthProvider == config.Name { + err := s.tokensClient.Delete(t.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed deleting token %s while disabling authprovider %s: %w", t.Name, t.AuthProvider, err) + } + } + } + + return nil +} + +// resetLocalUser takes a user and removes all its principal IDs except that of the local user. +// It updates the user so that it is effectively as it was before any auth provider had been enabled. +func (s *Service) resetLocalUser(user *v3.User) error { + if user == nil || len(user.PrincipalIDs) < 2 { + return nil + } + + var localID string + for _, id := range user.PrincipalIDs { + if strings.HasPrefix(id, "local") { + localID = id + break + } + } + + if localID == "" { + return nil + } + + user.PrincipalIDs = []string{localID} + _, err := s.userClient.Update(user) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil +} + +// getProviderNameFromPrincipalNames tries to extract the provider name from any one string that represents +// a user principal or group principal. +func getProviderNameFromPrincipalNames(names ...string) string { + for _, name := range names { + parts := strings.Split(name, "_") + if len(parts) > 0 && parts[0] != "" && !strings.HasPrefix(parts[0], "local") { + return parts[0] + } + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service_test.go new file mode 100644 index 0000000..4645104 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/cleanup/service_test.go @@ -0,0 +1,325 @@ +package cleanup + +import ( + "crypto/md5" + "encoding/hex" + "errors" + "fmt" + "strings" + "testing" + "time" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func TestRunCleanup(t *testing.T) { + var globalRoleBindingStore = map[string]*v3.GlobalRoleBinding{ + "azure": { + ObjectMeta: metav1.ObjectMeta{Name: "azure"}, + GroupPrincipalName: "azuread_group://mygroup", + }, + "ping": { + ObjectMeta: metav1.ObjectMeta{Name: "ping"}, + GroupPrincipalName: "ping_group://mygroup", + }, + } + + var projectRoleTemplateBindingStore = map[string]*v3.ProjectRoleTemplateBinding{ + "local:azure": { + ObjectMeta: metav1.ObjectMeta{Name: "azure", Namespace: "local"}, + GroupPrincipalName: "azuread_group://mygroup", + }, + + "local:ping": { + ObjectMeta: metav1.ObjectMeta{Name: "ping", Namespace: "local"}, + GroupPrincipalName: "ping_group://mygroup", + }, + } + + var clusterRoleTemplateBindingStore = map[string]*v3.ClusterRoleTemplateBinding{ + "local:azure": { + ObjectMeta: metav1.ObjectMeta{Name: "ping", Namespace: "local"}, + GroupPrincipalName: "azuread_group://mygroup", + }, + "local:ping": { + ObjectMeta: metav1.ObjectMeta{Name: "ping", Namespace: "local"}, + GroupPrincipalName: "ping_group://mygroup", + }, + } + + var userStore = map[string]*v3.User{ + "alice": { + ObjectMeta: metav1.ObjectMeta{Name: "alice"}, + PrincipalIDs: []string{"azuread_group://alice"}, + }, + "bob": { + ObjectMeta: metav1.ObjectMeta{Name: "bob"}, + PrincipalIDs: []string{"local://bob"}, + }, + "rick": { + ObjectMeta: metav1.ObjectMeta{Name: "rick"}, + PrincipalIDs: []string{"azuread_group://rick", "local://rick"}, + Password: "secret", + }, + } + + var tokenStore = map[string]*v3.Token{ + "local-123": { + ObjectMeta: metav1.ObjectMeta{Name: "local-123"}, + AuthProvider: "local", + }, + "azure-123": { + ObjectMeta: metav1.ObjectMeta{Name: "azure-123"}, + AuthProvider: "azuread", + }, + "openldap-333": { + ObjectMeta: metav1.ObjectMeta{Name: "openldap-333"}, + AuthProvider: "openldap", + }, + } + + var secretStore = map[string]*v1.Secret{ + "cattle-system:oauthSecretName": { + ObjectMeta: metav1.ObjectMeta{ + Name: "oauthSecretName", + Namespace: tokens.SecretNamespace, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{ + "azuread": []byte("my user token"), + }, + }, + "cattle-global-data:azureadconfig-applicationsecret": { + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s", strings.ToLower(client.AzureADConfigType), client.AzureADConfigFieldApplicationSecret), + Namespace: common.SecretsNamespace, + }, + }, + "cattle-global-data:azuread-access-token": { + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%s", strings.ToLower("azuread"), "access-token"), + Namespace: common.SecretsNamespace, + }, + }, + "foo:regular-secret": { + ObjectMeta: metav1.ObjectMeta{ + Name: "regular secret", + Namespace: "foo", + }, + }, + } + + svc := newMockCleanupService(t, + globalRoleBindingStore, + projectRoleTemplateBindingStore, + clusterRoleTemplateBindingStore, + tokenStore, + userStore, + secretStore, + ) + cfg := v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "azuread", + }, + Type: client.AzureADConfigType, + Enabled: false, + } + + err := svc.Run(&cfg) + + require.NoError(t, err) + assert.Len(t, globalRoleBindingStore, 1) + assert.Len(t, clusterRoleTemplateBindingStore, 1) + assert.Len(t, projectRoleTemplateBindingStore, 1) + assert.Len(t, userStore, 2) + assert.Len(t, secretStore, 1) + assert.Len(t, tokenStore, 2) + assert.Empty(t, tokenStore["azure-123"]) + + for _, user := range userStore { + require.Lenf(t, user.PrincipalIDs, 1, "every user after cleanup must have only one principal ID, got %d", len(user.PrincipalIDs)) + principalID := user.PrincipalIDs[0] + assert.Truef(t, strings.HasPrefix(principalID, "local"), "the only principal ID has 'local' as a prefix, got %s", principalID) + } +} + +func newMockCleanupService(t *testing.T, + grbStore map[string]*v3.GlobalRoleBinding, + prtbStore map[string]*v3.ProjectRoleTemplateBinding, + crtbStore map[string]*v3.ClusterRoleTemplateBinding, + tokenStore map[string]*v3.Token, + userStore map[string]*v3.User, + secretStore map[string]*v1.Secret) Service { + t.Helper() + ctrl := gomock.NewController(t) + + // Setup GlobalRole mock cache + grbCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl) + grbCache.EXPECT().List(gomock.Any()).DoAndReturn(func(_ labels.Selector) ([]*v3.GlobalRoleBinding, error) { + var lst []*v3.GlobalRoleBinding + for _, v := range grbStore { + lst = append(lst, v) + } + return lst, nil + }).AnyTimes() + grbCache.EXPECT().Get(gomock.Any()).DoAndReturn(func(name string) (*v3.GlobalRoleBinding, error) { + return grbStore[name], nil + }).AnyTimes() + + // Setup GlobalRole mock client + grbClient := fake.NewMockNonNamespacedClientInterface[*v3.GlobalRoleBinding, *v3.GlobalRoleBindingList](ctrl) + grbClient.EXPECT().Delete(gomock.Any(), gomock.Any()).DoAndReturn(func(name string, _ *metav1.DeleteOptions) error { + delete(grbStore, name) + return nil + }).AnyTimes() + + // Setup ProjectRoleTemplateBinding mock cache + prtbCache := fake.NewMockCacheInterface[*v3.ProjectRoleTemplateBinding](ctrl) + prtbCache.EXPECT().List(gomock.Any(), gomock.Any()).DoAndReturn(func(_ string, _ labels.Selector) ([]*v3.ProjectRoleTemplateBinding, error) { + var lst []*v3.ProjectRoleTemplateBinding + for _, v := range prtbStore { + lst = append(lst, v) + } + return lst, nil + }).AnyTimes() + prtbCache.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string) (*v3.ProjectRoleTemplateBinding, error) { + return prtbStore[namespace+":"+name], nil + }).AnyTimes() + + // Setup ProjectRoleTemplateBinding mock client + prtbClient := fake.NewMockClientInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList](ctrl) + prtbClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, _ *metav1.DeleteOptions) error { + delete(prtbStore, namespace+":"+name) + return nil + }).AnyTimes() + + // Setup ClusterRoleTemplateBinding mock cache + crtbCache := fake.NewMockCacheInterface[*v3.ClusterRoleTemplateBinding](ctrl) + crtbCache.EXPECT().List(gomock.Any(), gomock.Any()).DoAndReturn(func(_ string, _ labels.Selector) ([]*v3.ClusterRoleTemplateBinding, error) { + var lst []*v3.ClusterRoleTemplateBinding + for _, v := range crtbStore { + lst = append(lst, v) + } + return lst, nil + }).AnyTimes() + crtbCache.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string) (*v3.ClusterRoleTemplateBinding, error) { + return crtbStore[namespace+":"+name], nil + }).AnyTimes() + + // Setup ClusterRoleTemplateBinding mock client + crtbClient := fake.NewMockClientInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList](ctrl) + crtbClient.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, _ *metav1.DeleteOptions) error { + delete(crtbStore, namespace+":"+name) + return nil + }).AnyTimes() + + // Setup Token mock cache + tokenCache := fake.NewMockNonNamespacedCacheInterface[*v3.Token](ctrl) + tokenCache.EXPECT().List(gomock.Any()).DoAndReturn(func(_ labels.Selector) ([]*v3.Token, error) { + var lst []*v3.Token + for _, v := range tokenStore { + lst = append(lst, v) + } + return lst, nil + }).AnyTimes() + tokenCache.EXPECT().Get(gomock.Any()).DoAndReturn(func(name string) (*v3.Token, error) { + return tokenStore[name], nil + }).AnyTimes() + + // Setup Token mock client + tokenClient := fake.NewMockNonNamespacedClientInterface[*v3.Token, *v3.TokenList](ctrl) + tokenClient.EXPECT().Delete(gomock.Any(), gomock.Any()).DoAndReturn(func(name string, _ *metav1.DeleteOptions) error { + delete(tokenStore, name) + return nil + }).AnyTimes() + + // Setup User mock cache + userCache := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + userCache.EXPECT().List(gomock.Any()).DoAndReturn(func(_ labels.Selector) ([]*v3.User, error) { + var lst []*v3.User + for _, v := range userStore { + lst = append(lst, v) + } + return lst, nil + }).AnyTimes() + userCache.EXPECT().Get(gomock.Any()).DoAndReturn(func(name string) (*v3.User, error) { + return userStore[name], nil + }).AnyTimes() + + // Setup User mock client + userClient := fake.NewMockNonNamespacedClientInterface[*v3.User, *v3.UserList](ctrl) + userClient.EXPECT().Delete(gomock.Any(), gomock.Any()).DoAndReturn(func(name string, _ *metav1.DeleteOptions) error { + delete(userStore, name) + return nil + }).AnyTimes() + userClient.EXPECT().Update(gomock.Any()).DoAndReturn(func(user *v3.User) (*v3.User, error) { + userStore[user.Name] = user + return user, nil + }) + + return Service{ + secretsInterface: getSecretInterfaceMock(secretStore), + globalRoleBindingsCache: grbCache, + globalRoleBindingsClient: grbClient, + projectRoleTemplateBindingsCache: prtbCache, + projectRoleTemplateBindingsClient: prtbClient, + clusterRoleTemplateBindingsCache: crtbCache, + clusterRoleTemplateBindingsClient: crtbClient, + tokensCache: tokenCache, + tokensClient: tokenClient, + userCache: userCache, + userClient: userClient, + } +} + +func getSecretInterfaceMock(store map[string]*corev1.Secret) v1.SecretInterface { + secretInterfaceMock := &fakes.SecretInterfaceMock{} + + secretInterfaceMock.CreateFunc = func(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.Name == "" { + uniqueIdentifier := md5.Sum([]byte(time.Now().String())) + secret.Name = hex.EncodeToString(uniqueIdentifier[:]) + } + store[fmt.Sprintf("%s:%s", secret.Namespace, secret.Name)] = secret + return secret, nil + } + + secretInterfaceMock.ListNamespacedFunc = func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { + var secrets []corev1.Secret + for _, secret := range store { + if secret.Namespace == namespace { + secrets = append(secrets, *secret) + } + } + return &corev1.SecretList{ + Items: secrets, + }, nil + } + + secretInterfaceMock.GetNamespacedFunc = func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + secret, ok := store[fmt.Sprintf("%s:%s", namespace, name)] + if ok { + return secret, nil + } + return nil, errors.New("secret not found") + } + + secretInterfaceMock.DeleteNamespacedFunc = func(namespace string, name string, options *metav1.DeleteOptions) error { + delete(store, fmt.Sprintf("%s:%s", namespace, name)) + return nil + } + + return secretInterfaceMock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/context/context.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/context/context.go new file mode 100644 index 0000000..68702e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/context/context.go @@ -0,0 +1,19 @@ +package auth + +import "context" + +// saAuthenticatedContextKey is the context key for the SAAuthenticated flag. +type saAuthenticatedContextKey struct{} + +var saContextKey = saAuthenticatedContextKey{} + +// IsSAAuthenticated returns true if the SAAuthenticated flag is set in the context. +func IsSAAuthenticated(ctx context.Context) bool { + authed, _ := ctx.Value(saContextKey).(bool) + return authed +} + +// SetSAAuthenticated sets the SAAuthenticated flag in the context. +func SetSAAuthenticated(ctx context.Context) context.Context { + return context.WithValue(ctx, saContextKey, true) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/data/authconfig_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/data/authconfig_data.go new file mode 100644 index 0000000..8fd9e75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/data/authconfig_data.go @@ -0,0 +1,102 @@ +package data + +import ( + "github.com/rancher/rancher/pkg/auth/providers/activedirectory" + "github.com/rancher/rancher/pkg/auth/providers/azure" + "github.com/rancher/rancher/pkg/auth/providers/genericoidc" + "github.com/rancher/rancher/pkg/auth/providers/github" + "github.com/rancher/rancher/pkg/auth/providers/googleoauth" + "github.com/rancher/rancher/pkg/auth/providers/keycloakoidc" + "github.com/rancher/rancher/pkg/auth/providers/ldap" + localprovider "github.com/rancher/rancher/pkg/auth/providers/local" + "github.com/rancher/rancher/pkg/auth/providers/oidc" + "github.com/rancher/rancher/pkg/auth/providers/saml" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/auth" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func AuthConfigs(management *config.ManagementContext) error { + if err := addAuthConfig(github.Name, client.GithubConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(activedirectory.Name, client.ActiveDirectoryConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(azure.Name, client.AzureADConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(ldap.OpenLdapName, client.OpenLdapConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(ldap.FreeIpaName, client.FreeIpaConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(saml.PingName, client.PingConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(saml.ADFSName, client.ADFSConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(saml.KeyCloakName, client.KeyCloakConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(saml.OKTAName, client.OKTAConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(saml.ShibbolethName, client.ShibbolethConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(googleoauth.Name, client.GoogleOauthConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(oidc.Name, client.OIDCConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(keycloakoidc.Name, client.KeyCloakOIDCConfigType, false, management); err != nil { + return err + } + + if err := addAuthConfig(genericoidc.Name, client.GenericOIDCConfigType, false, management); err != nil { + return err + } + + return addAuthConfig(localprovider.Name, client.LocalConfigType, true, management) +} + +func addAuthConfig(name, aType string, enabled bool, management *config.ManagementContext) error { + annotations := make(map[string]string) + if name == azure.Name { + annotations[azure.GraphEndpointMigratedAnnotation] = "true" + } + annotations[auth.CleanupAnnotation] = auth.CleanupRancherLocked + + _, err := management.Management.AuthConfigs("").ObjectClient().Create(&v3.AuthConfig{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Annotations: annotations, + }, + Type: aType, + Enabled: enabled, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/handler.go new file mode 100644 index 0000000..5c11731 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/handler.go @@ -0,0 +1,140 @@ +package principals + +import ( + "context" + "encoding/json" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "net/http" + + "fmt" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +type principalsHandler struct { + principalsClient v3.PrincipalInterface + tokensClient v3.TokenInterface + auth requests.Authenticator + tokenMGR *tokens.Manager + ac types.AccessControl +} + +func newPrincipalsHandler(ctx context.Context, clusterRouter requests.ClusterRouter, mgmt *config.ScaledContext) *principalsHandler { + providers.Configure(ctx, mgmt) + return &principalsHandler{ + principalsClient: mgmt.Management.Principals(""), + tokensClient: mgmt.Management.Tokens(""), + auth: requests.NewAuthenticator(ctx, clusterRouter, mgmt), + tokenMGR: tokens.NewManager(ctx, mgmt), + ac: mgmt.AccessControl, + } +} + +func (h *principalsHandler) actions(actionName string, action *types.Action, apiContext *types.APIContext) error { + if actionName != "search" { + return httperror.NewAPIError(httperror.ActionNotAvailable, "") + } + + input := &v32.SearchPrincipalsInput{} + if err := json.NewDecoder(apiContext.Request.Body).Decode(input); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("Failed to parse body: %v", err)) + } + + token, err := h.getToken(apiContext.Request) + if err != nil { + return err + } + + ps, err := providers.SearchPrincipals(input.Name, input.PrincipalType, *token) + if err != nil { + return err + } + + var principals []map[string]interface{} + for _, p := range ps { + x, err := convertPrincipal(apiContext.Schema, p) + if err != nil { + return err + } + principals = append(principals, x) + } + + context := map[string]string{"resource": "principals", "apiGroup": "management.cattle.io"} + principals = h.ac.FilterList(apiContext, apiContext.Schema, principals, context) + + apiContext.WriteResponse(200, principals) + return nil +} + +func (h *principalsHandler) list(apiContext *types.APIContext, next types.RequestHandler) error { + var principals []map[string]interface{} + + token, err := h.getToken(apiContext.Request) + if err != nil { + return err + } + + if apiContext.ID != "" { + princ, err := providers.GetPrincipal(apiContext.ID, *token) + if err != nil { + return err + } + p, err := convertPrincipal(apiContext.Schema, princ) + if err != nil { + return err + } + + context := map[string]string{"resource": "principals", "apiGroup": "management.cattle.io"} + p = h.ac.Filter(apiContext, apiContext.Schema, p, context) + + apiContext.WriteResponse(200, p) + return nil + } + + p, err := convertPrincipal(apiContext.Schema, token.UserPrincipal) + if err != nil { + return err + } + principals = append(principals, p) + + groupPrincipals := h.tokenMGR.GetGroupsForTokenAuthProvider(token) + for _, p := range groupPrincipals { + x, err := convertPrincipal(apiContext.Schema, p) + if err != nil { + return err + } + principals = append(principals, x) + } + + apiContext.WriteResponse(200, principals) + return nil +} + +func convertPrincipal(schema *types.Schema, principal v3.Principal) (map[string]interface{}, error) { + data, err := convert.EncodeToMap(principal) + if err != nil { + return nil, err + } + mapper := schema.Mapper + if mapper == nil { + return nil, errors.New("no schema mapper available") + } + mapper.FromInternal(data) + + return data, nil +} + +func (h *principalsHandler) getToken(request *http.Request) (*v3.Token, error) { + token, err := h.auth.TokenFromRequest(request) + return token, errors.Wrap(err, requests.ErrMustAuthenticate.Error()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/schema.go new file mode 100644 index 0000000..c92a6e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/principals/schema.go @@ -0,0 +1,31 @@ +package principals + +import ( + "context" + "net/url" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/requests" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Schema(ctx context.Context, clusterRouter requests.ClusterRouter, management *config.ScaledContext, schemas *types.Schemas) error { + p := newPrincipalsHandler(ctx, clusterRouter, management) + schema := schemas.Schema(&managementSchema.Version, client.PrincipalType) + schema.ActionHandler = p.actions + schema.ListHandler = p.list + schema.CollectionFormatter = collectionFormatter + schema.Formatter = formatter + return nil +} + +func collectionFormatter(apiContext *types.APIContext, collection *types.GenericCollection) { + collection.AddAction(apiContext, "search") +} + +func formatter(request *types.APIContext, resource *types.RawResource) { + schema := request.Schemas.Schema(&managementSchema.Version, client.PrincipalType) + resource.Links = map[string]string{"self": request.URLBuilder.ResourceLinkByID(schema, url.PathEscape(resource.ID))} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/daemon.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/daemon.go new file mode 100644 index 0000000..48cf2c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/daemon.go @@ -0,0 +1,111 @@ +package providerrefresh + +import ( + "context" + "fmt" + "time" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/robfig/cron" + "github.com/sirupsen/logrus" +) + +var ( + ref *refresher + c = cron.New() +) + +func StartRefreshDaemon(ctx context.Context, scaledContext *config.ScaledContext, mgmtContext *config.ManagementContext) { + refreshCronTime := settings.AuthUserInfoResyncCron.Get() + maxAge := settings.AuthUserInfoMaxAgeSeconds.Get() + ref = &refresher{ + tokenLister: mgmtContext.Management.Tokens("").Controller().Lister(), + tokens: mgmtContext.Management.Tokens(""), + userLister: mgmtContext.Management.Users("").Controller().Lister(), + tokenMGR: tokens.NewManager(ctx, scaledContext), + userAttributes: mgmtContext.Management.UserAttributes(""), + userAttributeLister: mgmtContext.Management.UserAttributes("").Controller().Lister(), + } + + UpdateRefreshMaxAge(maxAge) + UpdateRefreshCronTime(refreshCronTime) + +} + +func UpdateRefreshCronTime(refreshCronTime string) { + if ref == nil || refreshCronTime == "" { + return + } + + parsed, err := ParseCron(refreshCronTime) + if err != nil { + logrus.Errorf("%v", err) + return + } + + c.Stop() + c = cron.New() + + if parsed != nil { + job := cron.FuncJob(RefreshAllForCron) + c.Schedule(parsed, job) + c.Start() + } +} + +func UpdateRefreshMaxAge(maxAge string) { + if ref == nil { + return + } + + ref.ensureMaxAgeUpToDate(maxAge) +} + +func RefreshAllForCron() { + if ref == nil { + return + } + + logrus.Debug("Triggering auth refresh cron") + ref.refreshAll(false) +} + +func RefreshAttributes(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + if ref == nil { + return nil, errors.Errorf("refresh daemon not yet initialized") + } + + logrus.Debugf("Starting refresh process for %v", attribs.Name) + modified, err := ref.refreshAttributes(attribs) + if err != nil { + return nil, err + } + logrus.Debugf("Finished refresh process for %v", attribs.Name) + modified.LastRefresh = time.Now().UTC().Format(time.RFC3339) + modified.NeedsRefresh = false + return modified, nil +} + +func ParseMaxAge(setting string) (time.Duration, error) { + durString := fmt.Sprintf("%vs", setting) + dur, err := time.ParseDuration(durString) + if err != nil { + return 0, fmt.Errorf("Error parsing auth refresh max age: %v", err) + } + return dur, nil +} + +func ParseCron(setting string) (cron.Schedule, error) { + if setting == "" { + return nil, nil + } + schedule, err := cron.ParseStandard(setting) + if err != nil { + return nil, fmt.Errorf("Error parsing auth refresh cron: %v", err) + } + return schedule, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher.go new file mode 100644 index 0000000..088e692 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher.go @@ -0,0 +1,339 @@ +package providerrefresh + +import ( + "context" + "strings" + "sync" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/utils/pointer" +) + +type UserAuthRefresher interface { + TriggerAllUserRefresh() + TriggerUserRefresh(string, bool) +} + +func NewUserAuthRefresher(ctx context.Context, scaledContext *config.ScaledContext) UserAuthRefresher { + return &refresher{ + tokenLister: scaledContext.Management.Tokens("").Controller().Lister(), + tokens: scaledContext.Management.Tokens(""), + userLister: scaledContext.Management.Users("").Controller().Lister(), + tokenMGR: tokens.NewManager(ctx, scaledContext), + userAttributes: scaledContext.Management.UserAttributes(""), + userAttributeLister: scaledContext.Management.UserAttributes("").Controller().Lister(), + } +} + +type refresher struct { + sync.Mutex + tokenLister v3.TokenLister + tokens v3.TokenInterface + tokenMGR *tokens.Manager + userLister v3.UserLister + userAttributes v3.UserAttributeInterface + userAttributeLister v3.UserAttributeLister + intervalInSeconds int64 + unparsedMaxAge string + maxAge time.Duration +} + +func (r *refresher) ensureMaxAgeUpToDate(maxAge string) { + if r.unparsedMaxAge == maxAge || maxAge == "" { + return + } + + parsed, err := ParseMaxAge(maxAge) + if err != nil { + logrus.Errorf("Error parsing max age %v", err) + return + } + r.unparsedMaxAge = maxAge + r.maxAge = parsed +} + +func (r *refresher) TriggerUserRefresh(userName string, force bool) { + if force { + logrus.Debugf("Triggering auth refresh manually on %v", userName) + } else { + logrus.Debugf("Triggering auth refresh on %v", userName) + } + r.Lock() + r.ensureMaxAgeUpToDate(settings.AuthUserInfoMaxAgeSeconds.Get()) + r.Unlock() + if !force && (r.maxAge <= 0) { + logrus.Debugf("Skipping refresh trigger on user %v because max age setting is <= 0", userName) + return + } + + r.triggerUserRefresh(userName, force) +} + +func (r *refresher) TriggerAllUserRefresh() { + logrus.Debug("Triggering auth refresh manually on all users") + r.refreshAll(true) +} + +func (r *refresher) refreshAll(force bool) { + users, err := r.userLister.List("", labels.Everything()) + if err != nil { + logrus.Errorf("Error listing Users during auth provider refresh: %v", err) + } + for _, user := range users { + r.triggerUserRefresh(user.Name, force) + } +} + +func (r *refresher) triggerUserRefresh(userName string, force bool) { + attribs, needCreate, err := r.tokenMGR.EnsureAndGetUserAttribute(userName) + if err != nil { + logrus.Errorf("Error fetching user attribute to trigger refresh: %v", err) + return + } + now := time.Now().UTC() + // in the case there is an invalid (or no) last refresh ignore the error, lastrefresh will be 0 + lastRefresh, _ := time.Parse(time.RFC3339, attribs.LastRefresh) + earliestRefresh := lastRefresh.Add(r.maxAge) + if !force && now.Before(earliestRefresh) { + logrus.Debugf("Skipping refresh for %v due to max-age", userName) + return + } + + user, err := r.userLister.Get("", userName) + if err != nil { + logrus.Errorf("Error finding user before triggering refresh %v", err) + return + } + + for _, principalID := range user.PrincipalIDs { + if strings.HasPrefix(principalID, "system://") { + logrus.Debugf("Skipping refresh for system-user %v ", userName) + return + } + } + + attribs.NeedsRefresh = true + if needCreate { + _, err := r.userAttributes.Create(attribs) + if err != nil { + logrus.Errorf("Error creating user attribute to trigger refresh: %v", err) + } + } else { + _, err = r.userAttributes.Update(attribs) + if err != nil { + if apierrors.IsConflict(err) { + // User attribute has just been updated, triggering the refresh. + logrus.Debugf("Error updating user attribute to trigger refresh: %v", err) + } else { + logrus.Errorf("Error updating user attribute to trigger refresh: %v", err) + } + } + } +} + +func (r *refresher) refreshAttributes(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + var ( + derivedTokenList []*v3.Token + derivedTokens map[string][]*v3.Token + loginTokenList []*v3.Token + loginTokens map[string][]*v3.Token + canLogInAtAll bool + errorConfirmingLogins bool + ) + + attribs = attribs.DeepCopy() + + user, err := r.userLister.Get("", attribs.Name) + if err != nil { + return nil, err + } + + loginTokens = make(map[string][]*v3.Token) + derivedTokens = make(map[string][]*v3.Token) + + allTokens, err := r.tokenLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + + for providerName := range providers.ProviderNames { + loginTokens[providerName] = []*v3.Token{} + derivedTokens[providerName] = []*v3.Token{} + } + + for _, token := range allTokens { + if token.UserID != user.Name { + continue + } + + if token.IsDerived { + derivedTokens[token.AuthProvider] = append(derivedTokens[token.AuthProvider], token) + derivedTokenList = append(derivedTokenList, token) + } else { + loginTokens[token.AuthProvider] = append(loginTokens[token.AuthProvider], token) + loginTokenList = append(loginTokenList, token) + } + } + + for providerName := range providers.ProviderNames { + // We have to find out if the user has a userprincipal for the provider. + principalID := GetPrincipalIDForProvider(providerName, user) + var newGroupPrincipals []v3.Principal + + providerDisabled, err := providers.IsDisabledProvider(providerName) + if err != nil { + logrus.Warnf("Unable to determine if provider %s was disabled, will assume that it isn't with error: %v", providerName, err) + // this is set as false by the return, but it's re-set here to be explicit/safe about the behavior + providerDisabled = false + } + if providerDisabled { + // if this auth provider has been disabled, act as though the user lost access to this provider + principalID = "" + } + + // If there is no principalID for the provider, there is no reason to go through the refetch process + if principalID != "" { + secret := "" + hasPerUserSecrets, err := providers.ProviderHasPerUserSecrets(providerName) + if err != nil { + return nil, err + } + if hasPerUserSecrets { + secret, err = r.tokenMGR.GetSecret(user.Name, providerName, loginTokens[providerName]) + if apierrors.IsNotFound(err) { + // There is no secret so we can't refresh, just continue to the next attribute + return attribs, nil + } + if err != nil { + return nil, err + } + } + + // SAML cannot refresh, so we do restore the existing providers. + if providers.UnrefreshableProviders[providerName] { + existingPrincipals := attribs.GroupPrincipals[providerName].Items + if existingPrincipals != nil { + newGroupPrincipals = existingPrincipals + } + } else { + newGroupPrincipals, err = providers.RefetchGroupPrincipals(principalID, providerName, secret) + if err != nil { + // In the case that we cant access a server, we still want to continue refreshing, but + // we no longer want to disable derived tokens, or remove their login tokens for this provider + if err.Error() != "no access" { + errorConfirmingLogins = true + logrus.Errorf("Error refreshing token principals, skipping: %v", err) + existingPrincipals := attribs.GroupPrincipals[providerName].Items + if existingPrincipals != nil { + newGroupPrincipals = existingPrincipals + } + } else { + // In the case that the user explicitly cannot login at all to this provider + // (e.g. they no longer exist) we pretend they have no principal with this provider + // so that their login tokens get blanked out + principalID = "" + } + } + } + } + + if len(newGroupPrincipals) == 0 { + newGroupPrincipals = nil + } + + attribs.GroupPrincipals[providerName] = v32.Principals{Items: newGroupPrincipals} + + canAccessProvider := false + + if principalID != "" && !errorConfirmingLogins { + // We want to verify that the user still has rancher access + canStillAccess, err := providers.CanAccessWithGroupProviders(providerName, principalID, newGroupPrincipals) + if err != nil { + return nil, err + } + + if canStillAccess { + canAccessProvider = true + canLogInAtAll = true + } + } + + // Update extras if either the user has an active login token, or an API token/kubeconfig token and is still active in the auth provider. + // If the user cannot access the auth provider, the derived tokens are deactivated below and should not be used to determine extra attributes. + if principalID != "" && (len(loginTokens[providerName]) > 0 || (len(derivedTokens[providerName]) > 0 && (canAccessProvider || errorConfirmingLogins))) { + // A user is 1:1 with its principal for a given provider, no need to get principals from tokens beyond the first one + var token v3.Token + if len(loginTokens[providerName]) > 0 { + token = *loginTokens[providerName][0] + } else { + token = *derivedTokens[providerName][0] + } + userPrincipal, err := providers.GetPrincipal(principalID, token) + if err != nil { + return nil, err + } + userExtraInfo := providers.GetUserExtraAttributes(providerName, userPrincipal) + if userExtraInfo != nil { + if attribs.ExtraByProvider == nil { + attribs.ExtraByProvider = make(map[string]map[string][]string) + } + attribs.ExtraByProvider[providerName] = userExtraInfo + } + } + + // If the user doesn't have access through this provider, we want to remove their login tokens for this provider + if !canAccessProvider && !errorConfirmingLogins { + for _, token := range loginTokens[providerName] { + err := r.tokens.Delete(token.Name, &metav1.DeleteOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + continue + } + return nil, err + } + } + } + } + + // if they can still log in, or we failed to validate one of their logins, don't disable derived tokens + if canLogInAtAll || errorConfirmingLogins { + return attribs, nil + } + + // user has been deactivated, disable their tokens + for _, token := range derivedTokenList { + token = token.DeepCopy() + token.Enabled = pointer.Bool(false) + _, err := r.tokenMGR.UpdateToken(token) + if err != nil { + return nil, err + } + } + return attribs, err +} + +func GetPrincipalIDForProvider(providerName string, user *v3.User) string { + prefix := providerName + "_user://" + if providerName == "local" { + prefix = "local://" + } + principalID := "" + for _, id := range user.PrincipalIDs { + if strings.HasPrefix(id, prefix) { + principalID = id + break + } + } + return principalID +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher_test.go new file mode 100644 index 0000000..c983283 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providerrefresh/refresher_test.go @@ -0,0 +1,619 @@ +package providerrefresh + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func Test_refreshAttributes(t *testing.T) { + tests := []struct { + name string + user *v3.User + attribs *v3.UserAttribute + providerDisabled bool + providerDisabledError error + tokens []*v3.Token + enabled bool + deleted bool + want *v3.UserAttribute + }{ + { + name: "local user no tokens", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{}, + enabled: true, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{}, + }, + }, + { + name: "local user with login token", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: false, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + }, + enabled: true, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{ + providers.LocalProvider: map[string][]string{ + common.UserAttributePrincipalID: []string{"local://user-abcde"}, + common.UserAttributeUserName: []string{"admin"}, + }, + }, + }, + }, + { + name: "local user with derived token", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + }, + enabled: true, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{ + providers.LocalProvider: map[string][]string{ + common.UserAttributePrincipalID: []string{"local://user-abcde"}, + common.UserAttributeUserName: []string{"admin"}, + }, + }, + }, + }, + { + name: "user with derived token disabled in provider", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + }, + enabled: false, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{}, + }, + }, + { + name: "user with login and derived tokens", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: false, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-vwxyz", + common.UserAttributeUserName: "nimda", + }, + }, + }, + }, + enabled: true, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{ + providers.LocalProvider: map[string][]string{ + common.UserAttributePrincipalID: []string{"local://user-abcde"}, + common.UserAttributeUserName: []string{"admin"}, + }, + }, + }, + }, + { + name: "shibboleth user", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "shibboleth_user://user1", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: saml.ShibbolethName, + UserPrincipal: v3.Principal{ + Provider: saml.ShibbolethName, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "shibboleth_user://user1", + common.UserAttributeUserName: "user1", + }, + }, + }, + }, + enabled: true, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{ + saml.ShibbolethName: map[string][]string{ + common.UserAttributePrincipalID: []string{"shibboleth_user://user1"}, + common.UserAttributeUserName: []string{"user1"}, + }, + }, + }, + }, + { + name: "disabled provider, disabled/deleted tokens", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: false, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + }, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{}, + }, + providerDisabled: true, + deleted: true, + enabled: false, + }, + { + name: "error in determining if provider is disabled, tokens left unchanged", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, + attribs: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + }, + tokens: []*v3.Token{ + { + UserID: "user-abcde", + IsDerived: false, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + { + UserID: "user-abcde", + IsDerived: true, + AuthProvider: providers.LocalProvider, + UserPrincipal: v3.Principal{ + Provider: providers.LocalProvider, + ExtraInfo: map[string]string{ + common.UserAttributePrincipalID: "local://user-abcde", + common.UserAttributeUserName: "admin", + }, + }, + }, + }, + want: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + GroupPrincipals: map[string]v3.Principals{ + "local": v3.Principals{}, + "shibboleth": v3.Principals{}, + }, + ExtraByProvider: map[string]map[string][]string{ + providers.LocalProvider: map[string][]string{ + common.UserAttributePrincipalID: []string{"local://user-abcde"}, + common.UserAttributeUserName: []string{"admin"}, + }, + }, + }, + providerDisabled: true, + providerDisabledError: fmt.Errorf("unable to determine if provider was disabled"), + deleted: false, + enabled: true, + }, + } + + providers.ProviderNames = map[string]bool{ + providers.LocalProvider: true, + saml.ShibbolethName: true, + } + for _, tt := range tests { + tokenUpdateCalled := false + tokenDeleteCalled := false + t.Run(tt.name, func(t *testing.T) { + providers.Providers = map[string]common.AuthProvider{ + providers.LocalProvider: &mockLocalProvider{ + canAccess: tt.enabled, + disabled: tt.providerDisabled, + disabledErr: tt.providerDisabledError, + }, + saml.ShibbolethName: &mockShibbolethProvider{}, + } + r := &refresher{ + tokenLister: &fakes.TokenListerMock{ + ListFunc: func(_ string, _ labels.Selector) ([]*v3.Token, error) { + return tt.tokens, nil + }, + }, + userLister: &fakes.UserListerMock{ + GetFunc: func(_, _ string) (*v3.User, error) { + return tt.user, nil + }, + }, + tokens: &fakes.TokenInterfaceMock{ + DeleteFunc: func(_ string, _ *metav1.DeleteOptions) error { + tokenDeleteCalled = true + return nil + }, + }, + tokenMGR: tokens.NewMockedManager(&fakes.TokenInterfaceMock{ + UpdateFunc: func(_ *v3.Token) (*v3.Token, error) { + tokenUpdateCalled = true + return nil, nil + }, + }), + } + got, err := r.refreshAttributes(tt.attribs) + assert.Nil(t, err) + assert.Equal(t, tt.want, got) + assert.NotEqual(t, tt.enabled, tokenUpdateCalled) + assert.Equal(t, tt.deleted, tokenDeleteCalled) + }) + } +} + +func TestGetPrincipalIDForProvider(t *testing.T) { + const testUserUsername = "tUser" + tests := []struct { + name string + userPrincipalIds []string + providerName string + desiredPrincipalId string + }{ + { + name: "basic test", + userPrincipalIds: []string{fmt.Sprintf("azure_user://%s", testUserUsername)}, + providerName: "azure", + desiredPrincipalId: fmt.Sprintf("azure_user://%s", testUserUsername), + }, + { + name: "no principal for provider", + userPrincipalIds: []string{fmt.Sprintf("azure_user://%s", testUserUsername)}, + providerName: "not-a-provider", + desiredPrincipalId: "", + }, + { + name: "local provider principal", + userPrincipalIds: []string{fmt.Sprintf("local://%s", testUserUsername)}, + providerName: "local", + desiredPrincipalId: fmt.Sprintf("local://%s", testUserUsername), + }, + { + name: "local provider missing principal", + userPrincipalIds: []string{fmt.Sprintf("local_user://%s", testUserUsername)}, + providerName: "local", + desiredPrincipalId: "", + }, + { + name: "multiple providers, correct one (first) chosen", + userPrincipalIds: []string{ + fmt.Sprintf("ldap_user://%s", testUserUsername), + fmt.Sprintf("azure_user://%s", testUserUsername), + }, + providerName: "ldap", + desiredPrincipalId: fmt.Sprintf("ldap_user://%s", testUserUsername), + }, + { + name: "multiple providers, correct one (last) chosen", + userPrincipalIds: []string{ + fmt.Sprintf("ldap_user://%s", testUserUsername), + fmt.Sprintf("azure_user://%s", testUserUsername), + }, + providerName: "azure", + desiredPrincipalId: fmt.Sprintf("azure_user://%s", testUserUsername), + }, + { + name: "multiple correct providers, first one chosen", + userPrincipalIds: []string{ + fmt.Sprintf("ldap_user://%s", testUserUsername), + fmt.Sprintf("ldap_user://%s", "tUser2"), + }, + providerName: "ldap", + desiredPrincipalId: fmt.Sprintf("ldap_user://%s", testUserUsername), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + user := v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: testUserUsername, + }, + PrincipalIDs: test.userPrincipalIds, + } + outputPrincipalID := GetPrincipalIDForProvider(test.providerName, &user) + assert.Equal(t, test.desiredPrincipalId, outputPrincipalID, "got a different principal id than expected") + }) + } +} + +type mockLocalProvider struct { + canAccess bool + disabled bool + disabledErr error +} + +func (p *mockLocalProvider) IsDisabledProvider() (bool, error) { + return p.disabled, p.disabledErr +} + +func (p *mockLocalProvider) GetName() string { + panic("not implemented") +} + +func (p *mockLocalProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + panic("not implemented") +} + +func (p *mockLocalProvider) SearchPrincipals(name, principalType string, myToken v3.Token) ([]v3.Principal, error) { + panic("not implemented") +} + +func (p *mockLocalProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + return token.UserPrincipal, nil +} + +func (p *mockLocalProvider) CustomizeSchema(schema *types.Schema) { + panic("not implemented") +} + +func (p *mockLocalProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + panic("not implemented") +} + +func (p *mockLocalProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + return []v3.Principal{}, nil +} + +func (p *mockLocalProvider) CanAccessWithGroupProviders(userPrincipalID string, groups []v3.Principal) (bool, error) { + return p.canAccess, nil +} + +func (p *mockLocalProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + return map[string][]string{ + common.UserAttributePrincipalID: []string{userPrincipal.ExtraInfo[common.UserAttributePrincipalID]}, + common.UserAttributeUserName: []string{userPrincipal.ExtraInfo[common.UserAttributeUserName]}, + } +} + +func (p *mockLocalProvider) CleanupResources(*v3.AuthConfig) error { + return nil +} + +type mockShibbolethProvider struct { + enabled bool + enabledErr error +} + +func (p *mockShibbolethProvider) IsDisabledProvider() (bool, error) { + return p.enabled, p.enabledErr +} + +func (p *mockShibbolethProvider) GetName() string { + panic("not implemented") +} + +func (p *mockShibbolethProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + panic("not implemented") +} + +func (p *mockShibbolethProvider) SearchPrincipals(name, principalType string, myToken v3.Token) ([]v3.Principal, error) { + panic("not implemented") +} + +func (p *mockShibbolethProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + return token.UserPrincipal, nil +} + +func (p *mockShibbolethProvider) CustomizeSchema(schema *types.Schema) { + panic("not implemented") +} + +func (p *mockShibbolethProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + panic("not implemented") +} + +func (p *mockShibbolethProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + return []v3.Principal{}, errors.New("Not implemented") +} + +func (p *mockShibbolethProvider) CanAccessWithGroupProviders(userPrincipalID string, groups []v3.Principal) (bool, error) { + return true, nil +} + +func (p *mockShibbolethProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + return map[string][]string{ + common.UserAttributePrincipalID: []string{userPrincipal.ExtraInfo[common.UserAttributePrincipalID]}, + common.UserAttributeUserName: []string{userPrincipal.ExtraInfo[common.UserAttributeUserName]}, + } +} + +func (p *mockShibbolethProvider) CleanupResources(*v3.AuthConfig) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_actions.go new file mode 100644 index 0000000..2d575ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_actions.go @@ -0,0 +1,129 @@ +package activedirectory + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/client-go/util/retry" +) + +func (p *adProvider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "testAndApply") +} + +func (p *adProvider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, Name, p.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "testAndApply" { + return p.testAndApply(request) + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (p *adProvider) testAndApply(request *types.APIContext) error { + input, err := handler.ParseAndValidateActionBody(request, request.Schemas.Schema(&managementschema.Version, + client.ActiveDirectoryTestAndApplyInputType)) + if err != nil { + return err + } + configApplyInput := &v32.ActiveDirectoryTestAndApplyInput{} + if err := common.Decode(input, configApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + + config := &configApplyInput.ActiveDirectoryConfig + + login := &v32.BasicLogin{ + Username: configApplyInput.Username, + Password: configApplyInput.Password, + } + + if config.ServiceAccountPassword != "" { + value, err := common.ReadFromSecret(p.secrets, config.ServiceAccountPassword, + strings.ToLower(client.ActiveDirectoryConfigFieldServiceAccountPassword)) + if err != nil { + return err + } + config.ServiceAccountPassword = value + } + + caPool, err := newCAPool(config.Certificate) + if err != nil { + return err + } + + if len(config.Servers) < 1 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must supply a server") + } + + userPrincipal, groupPrincipals, err := p.loginUser(login, config, caPool, true) + if err != nil { + return err + } + + // if this works, save adConfig CR adding enabled flag + config.Enabled = configApplyInput.Enabled + err = p.saveActiveDirectoryConfig(config) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to save activedirectory config: %v", err)) + } + + user, err := p.userMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + userExtraInfo := p.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return p.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to create or update userAttribute: %v", err)) + } + + return p.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, "", 0, "Token via AD Configuration", request) +} + +func (p *adProvider) saveActiveDirectoryConfig(config *v32.ActiveDirectoryConfig) error { + storedConfig, _, err := p.getActiveDirectoryConfig() + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = client.ActiveDirectoryConfigType + config.ObjectMeta = storedConfig.ObjectMeta + + field := strings.ToLower(client.ActiveDirectoryConfigFieldServiceAccountPassword) + name, err := common.CreateOrUpdateSecrets(p.secrets, config.ServiceAccountPassword, field, strings.ToLower(convert.ToString(config.Type))) + if err != nil { + return err + } + + config.ServiceAccountPassword = name + + logrus.Debugf("updating activeDirectoryConfig") + _, err = p.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + if err != nil { + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_client.go new file mode 100644 index 0000000..75cc9af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_client.go @@ -0,0 +1,519 @@ +package activedirectory + +import ( + "crypto/x509" + "fmt" + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (p *adProvider) loginUser(adCredential *v32.BasicLogin, config *v32.ActiveDirectoryConfig, caPool *x509.CertPool, testServiceAccountBind bool) (v3.Principal, []v3.Principal, error) { + logrus.Debug("Now generating Ldap token") + + username := adCredential.Username + password := adCredential.Password + if password == "" { + return v3.Principal{}, nil, httperror.NewAPIError(httperror.MissingRequired, "password not provided") + } + externalID := ldap.GetUserExternalID(username, config.DefaultLoginDomain) + + lConn, err := p.ldapConnection(config, caPool) + if err != nil { + return v3.Principal{}, nil, err + } + defer lConn.Close() + + serviceAccountPassword := config.ServiceAccountPassword + serviceAccountUserName := config.ServiceAccountUsername + if testServiceAccountBind { + err = ldap.AuthenticateServiceAccountUser(serviceAccountPassword, serviceAccountUserName, config.DefaultLoginDomain, lConn) + if err != nil { + return v3.Principal{}, nil, err + } + } + + logrus.Debug("Binding username password") + err = lConn.Bind(externalID, password) + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") + } + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.ServerError, "server error while authenticating") + } + + samName := username + if strings.Contains(username, `\`) { + samName = strings.SplitN(username, `\`, 2)[1] + } + + query := fmt.Sprintf("(%v=%v)", config.UserLoginAttribute, ldapv3.EscapeFilter(samName)) + logrus.Debugf("LDAP Search query: {%s}", query) + + search := ldap.NewWholeSubtreeSearchRequest( + config.UserSearchBase, + query, + config.GetUserSearchAttributes(MemberOfAttribute, ObjectClass), + ) + + result, err := lConn.Search(search) + if err != nil { + return v3.Principal{}, nil, err + } + + if len(result.Entries) < 1 { + return v3.Principal{}, nil, fmt.Errorf("Cannot locate user information for %s", search.Filter) + } else if len(result.Entries) > 1 { + return v3.Principal{}, nil, fmt.Errorf("ldap user search found more than one result") + } + + userPrincipal, groupPrincipals, err := p.getPrincipalsFromSearchResult(result, config, lConn) + if err != nil { + return v3.Principal{}, nil, err + } + + allowed, err := p.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipal.Name, groupPrincipals) + if err != nil { + return v3.Principal{}, nil, err + } + if !allowed { + return v3.Principal{}, nil, httperror.NewAPIError(httperror.PermissionDenied, "Permission denied") + } + + return userPrincipal, groupPrincipals, err +} + +func (p *adProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + config, caPool, err := p.getActiveDirectoryConfig() + if err != nil { + return nil, err + } + + lConn, err := p.ldapConnection(config, caPool) + if err != nil { + return nil, err + } + defer lConn.Close() + + serviceAccountPassword := config.ServiceAccountPassword + serviceAccountUserName := config.ServiceAccountUsername + + err = ldap.AuthenticateServiceAccountUser(serviceAccountPassword, serviceAccountUserName, config.DefaultLoginDomain, lConn) + if err != nil { + return nil, err + } + + externalID, _, err := p.getDNAndScopeFromPrincipalID(principalID) + if err != nil { + return nil, err + } + + dn := externalID + + logrus.Debugf("LDAP Refetch principals base DN : {%s}", dn) + + search := ldap.NewBaseObjectSearchRequest( + dn, + fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass), + config.GetUserSearchAttributes(MemberOfAttribute, ObjectClass), + ) + + result, err := lConn.Search(search) + if err != nil { + return nil, err + } + + if len(result.Entries) < 1 { + return nil, fmt.Errorf("Cannot locate user information for %s", search.Filter) + } else if len(result.Entries) > 1 { + return nil, fmt.Errorf("ldap user search found more than one result") + } + + _, groupPrincipals, err := p.getPrincipalsFromSearchResult(result, config, lConn) + if err != nil { + return nil, err + } + + return groupPrincipals, err +} + +func (p *adProvider) getPrincipalsFromSearchResult(result *ldapv3.SearchResult, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn) (v3.Principal, []v3.Principal, error) { + var groupPrincipals []v3.Principal + var userPrincipal v3.Principal + + var nonDupGroupPrincipals []v3.Principal + var nestedGroupPrincipals []v3.Principal + + groupMap := make(map[string]bool) + + entry := result.Entries[0] + + if !p.permissionCheck(entry.Attributes, config) { + return v3.Principal{}, nil, fmt.Errorf("Permission denied") + } + + memberOf := entry.GetAttributeValues(MemberOfAttribute) + + logrus.Debugf("ADConstants userMemberAttribute() {%v}", MemberOfAttribute) + logrus.Debugf("SearchResult memberOf attribute {%s}", memberOf) + + isType := false + objectClass := entry.GetAttributeValues(ObjectClass) + for _, obj := range objectClass { + if strings.EqualFold(string(obj), config.UserObjectClass) { + isType = true + } + } + if !isType { + return v3.Principal{}, nil, nil + } + + user, err := ldap.AttributesToPrincipal(entry.Attributes, result.Entries[0].DN, UserScope, Name, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + return userPrincipal, groupPrincipals, err + } + + userPrincipal = *user + userPrincipal.Me = true + + if len(memberOf) != 0 { + for i := 0; i < len(memberOf); i += 50 { + batch := memberOf[i:min(i+50, len(memberOf))] + filter := fmt.Sprintf("(%v=%v)", ObjectClass, config.GroupObjectClass) + query := "(|" + for _, attrib := range batch { + query += fmt.Sprintf("(distinguishedName=%v)", ldapv3.EscapeFilter(attrib)) + } + query += ")" + query = fmt.Sprintf("(&%v%v)", filter, query) + // Pulling user's groups + logrus.Debugf("AD: Query for pulling user's groups: %v", query) + searchDomain := config.UserSearchBase + if config.GroupSearchBase != "" { + searchDomain = config.GroupSearchBase + } + + // Call common method for getting group principals + groupPrincipalListBatch, err := p.getGroupPrincipalsFromSearch(searchDomain, query, config, lConn, batch) + if err != nil { + return userPrincipal, groupPrincipals, err + } + groupPrincipals = append(groupPrincipals, groupPrincipalListBatch...) + } + } + // config.NestedGroupMembershipEnabled nil or false = false + if config.NestedGroupMembershipEnabled != nil { + if *config.NestedGroupMembershipEnabled == true { + searchDomain := config.UserSearchBase + if config.GroupSearchBase != "" { + searchDomain = config.GroupSearchBase + } + // config.GroupMemberMappingAttribute is a required field post 2.0.1, so if an upgraded setup doesn't have its value, we set it to `member` + if config.GroupMemberMappingAttribute == "" { + config.GroupMemberMappingAttribute = "member" + } + + // Handling nestedgroups: tracing from down to top in order to find the parent groups, parent parent groups, and so on... + // When traversing up, we note down all the parent groups and add them to groupPrincipals + commonConfig := ldap.ConfigAttributes{ + GroupMemberMappingAttribute: config.GroupMemberMappingAttribute, + GroupNameAttribute: config.GroupNameAttribute, + GroupObjectClass: config.GroupObjectClass, + GroupSearchAttribute: config.GroupSearchAttribute, + ObjectClass: ObjectClass, + ProviderName: Name, + UserLoginAttribute: config.UserLoginAttribute, + UserNameAttribute: config.UserNameAttribute, + UserObjectClass: config.UserObjectClass, + } + searchAttributes := []string{MemberOfAttribute, ObjectClass, config.GroupObjectClass, config.UserLoginAttribute, config.GroupNameAttribute, + config.GroupSearchAttribute} + for _, groupPrincipal := range groupPrincipals { + err = ldap.GatherParentGroups(groupPrincipal, searchDomain, GroupScope, &commonConfig, lConn, groupMap, &nestedGroupPrincipals, searchAttributes) + if err != nil { + return userPrincipal, groupPrincipals, nil + } + } + nonDupGroupPrincipals = ldap.FindNonDuplicateBetweenGroupPrincipals(nestedGroupPrincipals, groupPrincipals, []v3.Principal{}) + groupPrincipals = append(groupPrincipals, nonDupGroupPrincipals...) + } + return userPrincipal, groupPrincipals, nil + } + + return userPrincipal, groupPrincipals, nil +} + +func (p *adProvider) getGroupPrincipalsFromSearch(searchBase string, filter string, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn, + groupDN []string) ([]v3.Principal, error) { + var groupPrincipals []v3.Principal + var nilPrincipal []v3.Principal + + search := ldap.NewWholeSubtreeSearchRequest( + searchBase, + filter, + config.GetGroupSearchAttributes(ObjectClass), + ) + + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountUsername, config.DefaultLoginDomain) + err := lConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) && config.Enabled { + // If bind fails because service account password has changed, just return identities formed from groups in `memberOf` + groupList := []v3.Principal{} + for _, dn := range groupDN { + grp := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: GroupScope + "://" + dn}, + DisplayName: dn, + LoginName: dn, + PrincipalType: GroupScope, + MemberOf: true, + } + groupList = append(groupList, grp) + } + return groupList, nil + } + return groupPrincipals, err + } + + result, err := lConn.SearchWithPaging(search, 1000) + if err != nil { + return groupPrincipals, httperror.WrapAPIError(errors.Wrapf(err, "server returned error for search %v %v: %v", search.BaseDN, search.Filter, err), httperror.ServerError, err.Error()) + } + + for _, e := range result.Entries { + principal, err := ldap.AttributesToPrincipal(e.Attributes, e.DN, GroupScope, Name, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + logrus.Errorf("AD: Error in getting principal for group entry %v: %v", e, err) + continue + } + if !reflect.DeepEqual(principal, nilPrincipal) { + principal.MemberOf = true + groupPrincipals = append(groupPrincipals, *principal) + } + } + + return groupPrincipals, nil +} + +func (p *adProvider) getPrincipal(distinguishedName string, scope string, config *v32.ActiveDirectoryConfig, caPool *x509.CertPool) (*v3.Principal, error) { + var search *ldapv3.SearchRequest + var filter string + if !slice.ContainsString(scopes, scope) { + return nil, fmt.Errorf("Invalid scope") + } + + var attributes []*ldapv3.AttributeTypeAndValue + var attribs []*ldapv3.EntryAttribute + object, err := ldapv3.ParseDN(distinguishedName) + if err != nil { + return nil, err + } + for _, rdns := range object.RDNs { + for _, attr := range rdns.Attributes { + attributes = append(attributes, attr) + entryAttr := ldapv3.NewEntryAttribute(attr.Type, []string{attr.Value}) + attribs = append(attribs, entryAttr) + } + } + + if !ldap.IsType(attribs, scope) && !p.permissionCheck(attribs, config) { + logrus.Errorf("Failed to get object %s", distinguishedName) + return nil, nil + } + + if strings.EqualFold(UserScope, scope) { + filter = fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass) + } else { + filter = fmt.Sprintf("(%v=%v)", ObjectClass, config.GroupObjectClass) + } + + logrus.Debugf("Query for getPrincipal(%s): %s", distinguishedName, filter) + lConn, err := p.ldapConnection(config, caPool) + if err != nil { + return nil, err + } + defer lConn.Close() + // Bind before query + // If service acc bind fails, and auth is on, return principal formed using DN + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountUsername, config.DefaultLoginDomain) + err = lConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) && config.Enabled { + var kind string + if strings.EqualFold(UserScope, scope) { + kind = "user" + } else if strings.EqualFold(GroupScope, scope) { + kind = "group" + } + principal := &v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: scope + "://" + distinguishedName}, + DisplayName: distinguishedName, + LoginName: distinguishedName, + PrincipalType: kind, + } + + return principal, nil + } + return nil, fmt.Errorf("Error in ldap bind: %v", err) + } + + var attrs []string + if strings.EqualFold(UserScope, scope) { + attrs = config.GetUserSearchAttributes(MemberOfAttribute, ObjectClass) + } else { + attrs = config.GetGroupSearchAttributes(MemberOfAttribute, ObjectClass) + } + + search = ldap.NewBaseObjectSearchRequest( + distinguishedName, + filter, + attrs, + ) + + result, err := lConn.Search(search) + if err != nil { + if ldapErr, ok := err.(*ldapv3.Error); ok && ldapErr.ResultCode == 32 { + return nil, httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("%v not found", distinguishedName)) + } + return nil, httperror.WrapAPIError(errors.Wrapf(err, "server returned error for search %v %v: %v", search.BaseDN, filter, err), httperror.ServerError, "Internal server error") + } + + if len(result.Entries) < 1 { + return nil, fmt.Errorf("No identities can be retrieved") + } else if len(result.Entries) > 1 { + return nil, fmt.Errorf("More than one result found") + } + + entry := result.Entries[0] + entryAttributes := entry.Attributes + if !p.permissionCheck(entry.Attributes, config) { + return nil, fmt.Errorf("Permission denied") + } + + principal, err := ldap.AttributesToPrincipal(entryAttributes, distinguishedName, scope, Name, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + return nil, err + } + return principal, nil +} + +func (p *adProvider) searchPrincipals(name, principalType string, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn) ([]v3.Principal, error) { + name = ldapv3.EscapeFilter(name) + + var principals []v3.Principal + + if principalType == "" || principalType == "user" { + userPrincipals, err := p.searchUser(name, config, lConn) + if err != nil { + return nil, err + } + principals = append(principals, userPrincipals...) + } + + if principalType == "" || principalType == "group" { + groupPrincipals, err := p.searchGroup(name, config, lConn) + if err != nil { + return nil, err + } + principals = append(principals, groupPrincipals...) + } + + return principals, nil +} + +func (p *adProvider) searchUser(name string, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn) ([]v3.Principal, error) { + srchAttributes := strings.Split(config.UserSearchAttribute, "|") + query := fmt.Sprintf("(&(%v=%v)", ObjectClass, config.UserObjectClass) + srchAttrs := "(|" + for _, attr := range srchAttributes { + srchAttrs += fmt.Sprintf("(%v=%v*)", attr, name) + } + // UserSearchFilter should be follow AD search filter syntax, enclosed by parentheses + query += srchAttrs + ")" + config.UserSearchFilter + ")" + logrus.Debugf("LDAPProvider searchUser query: %s", query) + return p.searchLdap(query, UserScope, config, lConn) +} + +func (p *adProvider) searchGroup(name string, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn) ([]v3.Principal, error) { + // GroupSearchFilter should be follow AD search filter syntax, enclosed by parentheses + query := "(&(" + ObjectClass + "=" + config.GroupObjectClass + ")(" + config.GroupSearchAttribute + "=" + name + "*)" + config.GroupSearchFilter + ")" + logrus.Debugf("LDAPProvider searchGroup query: %s", query) + return p.searchLdap(query, GroupScope, config, lConn) +} + +func (p *adProvider) searchLdap(query string, scope string, config *v32.ActiveDirectoryConfig, lConn *ldapv3.Conn) ([]v3.Principal, error) { + var principals []v3.Principal + var search *ldapv3.SearchRequest + + searchDomain := config.UserSearchBase + if strings.EqualFold(UserScope, scope) { + search = ldap.NewWholeSubtreeSearchRequest( + searchDomain, + query, + config.GetUserSearchAttributes(MemberOfAttribute, ObjectClass), + ) + } else { + if config.GroupSearchBase != "" { + searchDomain = config.GroupSearchBase + } + search = ldap.NewWholeSubtreeSearchRequest( + searchDomain, + query, + config.GetGroupSearchAttributes(MemberOfAttribute, ObjectClass), + ) + } + + // Bind before query + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountUsername, config.DefaultLoginDomain) + err := lConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + if err != nil { + return nil, fmt.Errorf("Error %v in ldap bind", err) + } + + results, err := lConn.SearchWithPaging(search, 1000) + if err != nil { + ldapErr, ok := reflect.ValueOf(err).Interface().(*ldapv3.Error) + if ok && ldapErr.ResultCode != ldapv3.LDAPResultNoSuchObject { + return []v3.Principal{}, fmt.Errorf("When searching ldap, Failed to search: %s, error: %#v", query, err) + } + } + + for i := 0; i < len(results.Entries); i++ { + entry := results.Entries[i] + principal, err := ldap.AttributesToPrincipal(entry.Attributes, results.Entries[i].DN, scope, Name, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + logrus.Errorf("Error translating search result: %v", err) + continue + } + principals = append(principals, *principal) + } + + return principals, nil +} + +func (p *adProvider) ldapConnection(config *v32.ActiveDirectoryConfig, caPool *x509.CertPool) (*ldapv3.Conn, error) { + servers := config.Servers + TLS := config.TLS + port := config.Port + connectionTimeout := config.ConnectionTimeout + startTLS := config.StartTLS + return ldap.NewLDAPConn(servers, TLS, startTLS, port, connectionTimeout, caPool) +} +func (p *adProvider) permissionCheck(attributes []*ldapv3.EntryAttribute, config *v32.ActiveDirectoryConfig) bool { + userObjectClass := config.UserObjectClass + userEnabledAttribute := config.UserEnabledAttribute + userDisabledBitMask := config.UserDisabledBitMask + return ldap.HasPermission(attributes, userObjectClass, userEnabledAttribute, userDisabledBitMask) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_provider.go new file mode 100644 index 0000000..315ed46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/activedirectory/activedirectory_provider.go @@ -0,0 +1,269 @@ +package activedirectory + +import ( + "context" + "crypto/x509" + "fmt" + "strings" + + "github.com/rancher/norman/httperror" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + client "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" +) + +const ( + Name = "activedirectory" + UserScope = Name + "_user" + GroupScope = Name + "_group" + ObjectClass = "objectClass" + MemberOfAttribute = "memberOf" + StatusConfigMapName = "ad-guid-migration" + StatusConfigMapNamespace = "cattle-system" + StatusMigrationField = "ad-guid-migration-status" + StatusMigrationFinished = "Finished" + StatusMigrationRunning = "Running" + StatusMigrationFinishedWithSkipped = "FinishedWithSkipped" + StatusMigrationFinishedWithMissing = "FinishedWithMissing" + StatusMigrationFailed = "Failed" + StatusLoginDisabled = "login is disabled while migration is running" + StatusACMigrationRunning = "migration-ad-guid-migration-status" +) + +var scopes = []string{UserScope, GroupScope} + +type adProvider struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + configMaps corev1.ConfigMapLister + secrets corev1.SecretInterface + userMGR user.Manager + certs string + caPool *x509.CertPool + tokenMGR *tokens.Manager +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + return &adProvider{ + ctx: ctx, + authConfigs: mgmtCtx.Management.AuthConfigs(""), + configMaps: mgmtCtx.Core.ConfigMaps("").Controller().Lister(), + secrets: mgmtCtx.Core.Secrets(""), + userMGR: userMGR, + tokenMGR: tokenMGR, + } +} + +func (p *adProvider) GetName() string { + return Name +} + +func (p *adProvider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = p.actionHandler + schema.Formatter = p.formatter +} + +func (p *adProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + ap := common.TransformToAuthProvider(authConfig) + defaultDomain := "" + if dld, ok := authConfig[client.ActiveDirectoryProviderFieldDefaultLoginDomain].(string); ok { + defaultDomain = dld + } + ap[client.ActiveDirectoryProviderFieldDefaultLoginDomain] = defaultDomain + return ap, nil +} + +func (p *adProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, ok := input.(*v32.BasicLogin) + if !ok { + return v3.Principal{}, nil, "", errors.New("unexpected input type") + } + + config, caPool, err := p.getActiveDirectoryConfig() + if err != nil { + return v3.Principal{}, nil, "", errors.New("can't find authprovider") + } + + // If a migration is running, we need to block logins and indicate why we are doing so + if config.Annotations != nil && config.Annotations[StatusACMigrationRunning] == StatusMigrationRunning { + return v3.Principal{}, nil, "", httperror.WrapAPIError(err, httperror.ClusterUnavailable, StatusLoginDisabled) + } + + principal, groupPrincipal, err := p.loginUser(login, config, caPool, false) + if err != nil { + return v3.Principal{}, nil, "", err + } + + return principal, groupPrincipal, "", err +} + +func (p *adProvider) SearchPrincipals(searchKey, principalType string, myToken v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + var err error + + config, caPool, err := p.getActiveDirectoryConfig() + if err != nil { + return principals, nil + } + + lConn, err := p.ldapConnection(config, caPool) + if err != nil { + return principals, nil + } + defer lConn.Close() + + principals, err = p.searchPrincipals(searchKey, principalType, config, lConn) + if err == nil { + for _, principal := range principals { + if principal.PrincipalType == "user" { + if p.isThisUserMe(myToken.UserPrincipal, principal) { + principal.Me = true + } + } else if principal.PrincipalType == "group" { + principal.MemberOf = p.tokenMGR.IsMemberOf(myToken, principal) + } + } + } + + return principals, nil +} + +func (p *adProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + config, caPool, err := p.getActiveDirectoryConfig() + if err != nil { + return v3.Principal{}, nil + } + + externalID, scope, err := p.getDNAndScopeFromPrincipalID(principalID) + if err != nil { + return v3.Principal{}, err + } + + principal, err := p.getPrincipal(externalID, scope, config, caPool) + if err != nil { + return v3.Principal{}, err + } + if p.isThisUserMe(token.UserPrincipal, *principal) { + principal.Me = true + } + return *principal, err +} + +func (p *adProvider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (p *adProvider) getActiveDirectoryConfig() (*v32.ActiveDirectoryConfig, *x509.CertPool, error) { + // TODO See if this can be simplified. also, this makes an api call everytime. find a better way + authConfigObj, err := p.authConfigs.ObjectClient().UnstructuredClient().Get("activedirectory", metav1.GetOptions{}) + if err != nil { + return nil, nil, fmt.Errorf("failed to retrieve ActiveDirectoryConfig, error: %v", err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, nil, fmt.Errorf("failed to retrieve ActiveDirectoryConfig, cannot read k8s Unstructured data") + } + storedADConfigMap := u.UnstructuredContent() + + storedADConfig := &v32.ActiveDirectoryConfig{} + err = common.Decode(storedADConfigMap, storedADConfig) + if err != nil { + return nil, nil, fmt.Errorf("unable to decode Active Directory Config: %w", err) + } + + if p.certs != storedADConfig.Certificate || p.caPool == nil { + pool, err := newCAPool(storedADConfig.Certificate) + if err != nil { + return nil, nil, err + } + p.certs = storedADConfig.Certificate + p.caPool = pool + } + + if storedADConfig.ServiceAccountPassword != "" { + value, err := common.ReadFromSecret(p.secrets, storedADConfig.ServiceAccountPassword, + strings.ToLower(v3client.ActiveDirectoryConfigFieldServiceAccountPassword)) + if err != nil { + return nil, nil, err + } + storedADConfig.ServiceAccountPassword = value + } + + return storedADConfig, p.caPool, nil +} + +func newCAPool(cert string) (*x509.CertPool, error) { + pool, err := x509.SystemCertPool() + if err != nil { + return nil, err + } + pool.AppendCertsFromPEM([]byte(cert)) + return pool, nil +} + +func (p *adProvider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, _, err := p.getActiveDirectoryConfig() + if err != nil { + logrus.Errorf("Error fetching AD config: %v", err) + return false, err + } + allowed, err := p.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func (p *adProvider) getDNAndScopeFromPrincipalID(principalID string) (string, string, error) { + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return "", "", errors.Errorf("invalid id %v", principalID) + } + scope := parts[0] + externalID := strings.TrimPrefix(parts[1], "//") + return externalID, scope, nil +} + +func (p *adProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +type LoginDisabledError struct{} + +// Error provides a string representation of an LdapErrorNotFound +func (e LoginDisabledError) Error() string { + return StatusLoginDisabled +} + +// IsDisabledProvider checks if the Azure Active Directory provider is currently disabled in Rancher. +func (p *adProvider) IsDisabledProvider() (bool, error) { + adConfig, _, err := p.getActiveDirectoryConfig() + if err != nil { + return false, err + } + return !adConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_actions.go new file mode 100644 index 0000000..59ff463 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_actions.go @@ -0,0 +1,150 @@ +package azure + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/azure/clients" + "github.com/rancher/rancher/pkg/auth/providers/common" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +func (ap *Provider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "configureTest") + resource.AddAction(apiContext, "testAndApply") + resource.AddAction(apiContext, "upgrade") +} + +func (ap *Provider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, Name, ap.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "configureTest" { + return ap.ConfigureTest(request) + } else if actionName == "testAndApply" { + return ap.testAndApply(request) + } else if actionName == "upgrade" { + return ap.migrateToMicrosoftGraph() + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (ap *Provider) ConfigureTest(request *types.APIContext) error { + // Verify the body has all required fields + input, err := handler.ParseAndValidateActionBody(request, request.Schemas.Schema(&managementschema.Version, + client.AzureADConfigType)) + if err != nil { + return err + } + + data := map[string]interface{}{ + "redirectUrl": formAzureRedirectURL(input), + "type": "azureADConfigTestOutput", + } + + request.WriteResponse(http.StatusOK, data) + return nil +} + +func (ap *Provider) testAndApply(request *types.APIContext) error { + var err error + // On any error, delete the cached secret containing the access token to the Microsoft Graph, in case it had been + // cached without having sufficient API permissions. Rancher has no precise control over when this secret is cached. + defer func() { + if err != nil { + if err = ap.secrets.DeleteNamespaced(common.SecretsNamespace, clients.AccessTokenSecretName, &metav1.DeleteOptions{}); err != nil { + logrus.Errorf("Failed to delete the Azure AD access token secret from Kubernetes") + } + } + }() + + azureADConfigApplyInput := &v32.AzureADConfigApplyInput{} + if err := json.NewDecoder(request.Request.Body).Decode(azureADConfigApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + + azureADConfig := &azureADConfigApplyInput.Config + + currentConfig, err := ap.GetAzureConfigK8s() + if err != nil { + logrus.Errorf("Failed to fetch Azure AD Config from Kubernetes: %v", err) + return httperror.NewAPIError(httperror.ServerError, "failed to fetch Azure AD Config from Kubernetes") + } + migrateNewFlowAnnotation(currentConfig, azureADConfig) + + azureLogin := &v32.AzureADLogin{ + Code: azureADConfigApplyInput.Code, + } + + if azureADConfig.ApplicationSecret != "" { + value, err := common.ReadFromSecret(ap.secrets, azureADConfig.ApplicationSecret, + strings.ToLower(client.AzureADConfigFieldApplicationSecret)) + if err != nil { + return err + } + azureADConfig.ApplicationSecret = value + } + // Call provider + userPrincipal, groupPrincipals, providerToken, err := ap.loginUser(azureADConfig, azureLogin, true) + if err != nil { + if httperror.IsAPIError(err) { + return err + } + return errors.Wrap(err, "server error while authenticating") + } + + user, err := ap.userMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + err = ap.saveAzureConfigK8s(azureADConfig) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to save azure config: %v", err)) + } + + userExtraInfo := ap.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return ap.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to create or update userAttribute: %v", err)) + } + + return ap.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, providerToken, 0, "Token via Azure Configuration", request) +} + +// Check the current auth config and make sure that the proposed one submitted through the API has up-to-date annotations. +// Rancher relies on GraphEndpointMigratedAnnotation to choose the right authentication flow and Graph API. +func migrateNewFlowAnnotation(current, proposed *v32.AzureADConfig) { + if IsConfigDeprecated(current) { + return + } + // This covers the case where admins upgrade Rancher to v2.6.7+ without having used Azure AD as the auth provider. + // In 2.6.7+, whether Azure AD is later registered or not, Rancher on startup creates the annotation on the template auth config. + // But in the case where the auth config had been created on Rancher startup prior to v2.6.7, the annotation would be missing. + // This ensures the annotation is set on initial attempt to set up Azure AD. + // This also covers the case where admins want to reconfigure a v2.6.7+ new auth flow setup with a new secret or app. + if proposed.ObjectMeta.Annotations == nil { + proposed.ObjectMeta.Annotations = make(map[string]string) + } + proposed.ObjectMeta.Annotations[GraphEndpointMigratedAnnotation] = "true" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider.go new file mode 100644 index 0000000..4ad421b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider.go @@ -0,0 +1,558 @@ +// Package azure provides functions and types to register and use Azure AD as the auth provider in Rancher. +package azure + +import ( + "context" + "fmt" + "net/url" + "strconv" + "strings" + + lru "github.com/hashicorp/golang-lru" + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/azure/clients" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + Name = clients.Name +) + +type unstructuredGetter interface { + Get(string, metav1.GetOptions) (runtime.Object, error) +} + +type Provider struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + Retriever unstructuredGetter + secrets corev1.SecretInterface + userMGR user.Manager + tokenMGR *tokens.Manager +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + var err error + clients.GroupCache, err = lru.New(settings.AzureGroupCacheSize.GetInt()) + if err != nil { + logrus.Warnf("initial azure-group-cache-size was invalid value, setting to 10000 error:%v", err) + clients.GroupCache, _ = lru.New(10000) + } + + return &Provider{ + ctx: ctx, + Retriever: mgmtCtx.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), + authConfigs: mgmtCtx.Management.AuthConfigs(""), + secrets: mgmtCtx.Core.Secrets(""), + userMGR: userMGR, + tokenMGR: tokenMGR, + } +} + +func (ap *Provider) GetName() string { + return Name +} + +func (ap *Provider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, ok := input.(*v32.AzureADLogin) + if !ok { + return v3.Principal{}, nil, "", errors.New("unexpected input type") + } + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return v3.Principal{}, nil, "", err + } + return ap.loginUser(cfg, login, false) +} + +func (ap *Provider) RefetchGroupPrincipals(principalID, secret string) ([]v3.Principal, error) { + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return nil, err + } + var useDeprecatedAzureADClient = IsConfigDeprecated(cfg) + azureClient, err := clients.NewAzureClientFromSecret(cfg, useDeprecatedAzureADClient, secret, ap.secrets) + if err != nil { + return nil, err + } + + logrus.Debug("[AZURE_PROVIDER] Started getting user info from AzureAD") + + parsed, err := clients.ParsePrincipalID(principalID) + if err != nil { + return nil, err + } + userPrincipal, err := azureClient.GetUser(parsed["ID"]) + if err != nil { + return nil, err + } + + logrus.Debug("[AZURE_PROVIDER] Completed getting user info from AzureAD") + + userGroups, err := azureClient.ListGroupMemberships(clients.GetPrincipalID(userPrincipal), cfg.GroupMembershipFilter) + if err != nil { + return nil, err + } + + groupPrincipals, err := clients.UserGroupsToPrincipals(azureClient, userGroups) + if err != nil { + return nil, err + } + + return groupPrincipals, nil +} + +func (ap *Provider) SearchPrincipals(name, principalType string, token v3.Token) ([]v3.Principal, error) { + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return nil, err + } + var principals []v3.Principal + + azureClient, err := ap.newAzureClientFromToken(cfg, &token) + if err != nil { + return nil, err + } + + switch principalType { + case "user": + principals, err = ap.searchUserPrincipalsByName(azureClient, name, token) + if err != nil { + return nil, err + } + case "group": + principals, err = ap.searchGroupPrincipalsByName(azureClient, name, token) + if err != nil { + return nil, err + } + case "": + users, err := ap.searchUserPrincipalsByName(azureClient, name, token) + if err != nil { + return nil, err + } + groups, err := ap.searchGroupPrincipalsByName(azureClient, name, token) + if err != nil { + return nil, err + } + principals = append(principals, users...) + principals = append(principals, groups...) + } + return principals, ap.updateToken(azureClient, &token) +} + +func (ap *Provider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + var principal v3.Principal + var err error + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return v3.Principal{}, err + } + + azureClient, err := ap.newAzureClientFromToken(cfg, &token) + if err != nil { + return principal, err + } + + parsed, err := clients.ParsePrincipalID(principalID) + if err != nil { + return v3.Principal{}, httperror.NewAPIError(httperror.NotFound, "invalid principal") + } + + switch parsed["type"] { + case "user": + principal, err = ap.getUserPrincipal(azureClient, parsed["ID"], token) + case "group": + principal, err = ap.getGroupPrincipal(azureClient, parsed["ID"], token) + } + + if err != nil { + return v3.Principal{}, err + } + + return principal, ap.updateToken(azureClient, &token) +} + +func (ap *Provider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = ap.actionHandler + schema.Formatter = ap.formatter +} + +func (ap *Provider) TransformToAuthProvider( + authConfig map[string]interface{}, +) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + p[publicclient.AzureADProviderFieldRedirectURL] = formAzureRedirectURL(authConfig) + + tenantID, _ := authConfig["tenantId"].(string) + p[publicclient.AzureADProviderFieldTenantID] = tenantID + applicationID, _ := authConfig["applicationId"].(string) + p[publicclient.AzureADProviderFieldClientID] = applicationID + + p[publicclient.AzureADProviderFieldScopes] = []string{"openid", "profile", "email"} + + // this is the default base endpoint, i.e.: https://login.microsoftonline.com/ + baseEndpoint, _ := authConfig["endpoint"].(string) + + // getString will return the string value from the map, or a blank string if the value is not a string + getString := func(data map[string]interface{}, key string) string { + v, ok := data[key] + if !ok { + return "" + } + + s, _ := v.(string) + return s + } + + // Set default authEndpoint, or custom if provided + joined, err := url.JoinPath(baseEndpoint, tenantID, "/oauth2/v2.0/authorize") + if err != nil { + return nil, err + } + p[publicclient.AzureADProviderFieldAuthURL] = joined + + if customEndpoint := getString(authConfig, "authEndpoint"); customEndpoint != "" { + p[publicclient.AzureADProviderFieldAuthURL] = customEndpoint + } + + // Set default tokenEndpoint, or custom if provided + joined, err = url.JoinPath(baseEndpoint, tenantID, "/oauth2/v2.0/token") + if err != nil { + return nil, err + } + p[publicclient.AzureADProviderFieldTokenURL] = joined + + if customEndpoint := getString(authConfig, "tokenEndpoint"); customEndpoint != "" { + p[publicclient.AzureADProviderFieldTokenURL] = customEndpoint + } + + // Set default deviceAuthEndpoint, or custom if provided + joined, err = url.JoinPath(baseEndpoint, tenantID, "/oauth2/v2.0/devicecode") + if err != nil { + return nil, err + } + p[publicclient.AzureADProviderFieldDeviceAuthURL] = joined + + if customEndpoint := getString(authConfig, "deviceAuthEndpoint"); customEndpoint != "" { + p[publicclient.AzureADProviderFieldDeviceAuthURL] = customEndpoint + } + + return p, nil +} + +func (ap *Provider) loginUser(config *v32.AzureADConfig, azureCredential *v32.AzureADLogin, test bool) (v3.Principal, []v3.Principal, string, error) { + var useDeprecatedAzureADClient = IsConfigDeprecated(config) + azureClient, err := clients.NewAzureClientFromCredential(config, useDeprecatedAzureADClient, azureCredential, ap.secrets) + if err != nil { + return v3.Principal{}, nil, "", err + } + userPrincipal, groupPrincipals, providerToken, err := azureClient.LoginUser(config, azureCredential) + if err != nil { + return v3.Principal{}, nil, "", err + } + testAllowedPrincipals := config.AllowedPrincipalIDs + if test && config.AccessMode == "restricted" { + testAllowedPrincipals = append(testAllowedPrincipals, userPrincipal.Name) + } + + allowed, err := ap.userMGR.CheckAccess(config.AccessMode, testAllowedPrincipals, userPrincipal.Name, groupPrincipals) + if err != nil { + return v3.Principal{}, nil, "", err + } + if !allowed { + return v3.Principal{}, nil, "", httperror.NewAPIError(httperror.Unauthorized, "unauthorized") + } + + return userPrincipal, groupPrincipals, providerToken, nil +} + +func (ap *Provider) getUserPrincipal(client clients.AzureClient, principalID string, token v3.Token) (v3.Principal, error) { + principal, err := client.GetUser(principalID) + if err != nil { + return v3.Principal{}, httperror.NewAPIError(httperror.NotFound, err.Error()) + } + principal.Me = samePrincipal(token.UserPrincipal, principal) + return principal, nil +} + +func (ap *Provider) getGroupPrincipal(client clients.AzureClient, id string, token v3.Token) (v3.Principal, error) { + principal, err := client.GetGroup(id) + if err != nil { + return v3.Principal{}, httperror.NewAPIError(httperror.NotFound, err.Error()) + } + principal.MemberOf = ap.tokenMGR.IsMemberOf(token, principal) + return principal, nil +} + +func (ap *Provider) searchUserPrincipalsByName(client clients.AzureClient, name string, token v3.Token) ([]v3.Principal, error) { + filter := fmt.Sprintf("startswith(userPrincipalName,'%[1]s') or startswith(displayName,'%[1]s') or startswith(givenName,'%[1]s') or startswith(surname,'%[1]s')", name) + principals, err := client.ListUsers(filter) + if err != nil { + return nil, err + } + for _, principal := range principals { + principal.Me = samePrincipal(token.UserPrincipal, principal) + } + return principals, nil +} + +func (ap *Provider) searchGroupPrincipalsByName(client clients.AzureClient, name string, token v3.Token) ([]v3.Principal, error) { + filter := fmt.Sprintf("startswith(displayName,'%[1]s') or startswith(mail,'%[1]s') or startswith(mailNickname,'%[1]s')", name) + principals, err := client.ListGroups(filter) + if err != nil { + return nil, err + } + for _, principal := range principals { + principal.MemberOf = ap.tokenMGR.IsMemberOf(token, principal) + } + return principals, nil +} + +func (ap *Provider) newAzureClientFromToken(cfg *v32.AzureADConfig, token *v32.Token) (clients.AzureClient, error) { + var secret string + var deprecated = IsConfigDeprecated(cfg) + if deprecated { + var err error + secret, err = ap.tokenMGR.GetSecret(token.UserID, Name, []*v3.Token{token}) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + } + return clients.NewAzureClientFromSecret(cfg, deprecated, secret, ap.secrets) +} + +func (ap *Provider) saveAzureConfigK8s(config *v32.AzureADConfig) error { + // Copy the annotations. + annotations := config.ObjectMeta.Annotations + storedAzureConfig, err := ap.GetAzureConfigK8s() + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = client.AzureADConfigType + config.ObjectMeta = storedAzureConfig.ObjectMeta + + // Ensure the passed in config's annotations are applied to the object to be persisted. + if config.ObjectMeta.Annotations == nil { + config.ObjectMeta.Annotations = map[string]string{} + } + for k, v := range annotations { + config.ObjectMeta.Annotations[k] = v + } + + field := strings.ToLower(client.AzureADConfigFieldApplicationSecret) + name, err := common.CreateOrUpdateSecrets(ap.secrets, config.ApplicationSecret, field, strings.ToLower(config.Type)) + if err != nil { + return err + } + + config.ApplicationSecret = name + + logrus.Debugf("updating AzureADConfig") + _, err = ap.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + if err != nil { + return err + } + return nil +} + +func (ap *Provider) GetAzureConfigK8s() (*v32.AzureADConfig, error) { + authConfigObj, err := ap.Retriever.Get(Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve AzureADConfig, error: %v", err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to retrieve AzureADConfig, cannot read k8s Unstructured data") + } + storedAzureADConfigMap := u.UnstructuredContent() + + storedAzureADConfig := &v32.AzureADConfig{} + err = common.Decode(storedAzureADConfigMap, storedAzureADConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode Azure Config: %w", err) + } + + if storedAzureADConfig.ApplicationSecret != "" { + value, err := common.ReadFromSecret(ap.secrets, storedAzureADConfig.ApplicationSecret, + strings.ToLower(client.AzureADConfigFieldApplicationSecret)) + if err != nil { + return nil, err + } + storedAzureADConfig.ApplicationSecret = value + } + + return storedAzureADConfig, nil +} + +// updateToken compares the current Azure access token to the one stored in the secret and updates if needed. +// This is relevant only for access tokens to the deprecated Azure AD Graph API. +func (ap *Provider) updateToken(client clients.AzureClient, token *v3.Token) error { + // For the new flow via Microsoft Graph, the caching and updating of the token to the Microsoft Graph API + // is handled separately via the SDK client cache. + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return err + } + if !IsConfigDeprecated(cfg) { + return nil + } + + current, err := client.MarshalTokenJSON() + if err != nil { + return fmt.Errorf("marshaling token to JSON: %w", err) + } + + secret, err := ap.tokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{token}) + if err != nil { + if apierrors.IsNotFound(err) { + // providerToken doesn't exist as a secret, update on token. + if current, ok := token.ProviderInfo["access_token"]; ok && current != current { + token.ProviderInfo["access_token"] = current + } + return nil + } + return err + } + + if current == secret { + return nil + } + + return ap.tokenMGR.UpdateSecret(token.UserID, token.AuthProvider, current) +} + +func formAzureRedirectURL(config map[string]interface{}) string { + var ac v32.AzureADConfig + err := common.Decode(config, &ac) + if err == nil { + // Extract the annotations from the map. This is needed because of the type structure of + // the Azure config and the Auth config it embeds. Full deserialization does not work for + // fields of the embedded Kubernetes types in this case. + ac.ObjectMeta.Annotations = extractAnnotationsFromAuthConfig(config) + if !IsConfigDeprecated(&ac) { + // Return the redirect URL for Microsoft Graph. + return fmt.Sprintf( + "%s?client_id=%s&redirect_uri=%s&response_type=code&scope=openid", + ac.AuthEndpoint, + ac.ApplicationID, + ac.RancherURL, + ) + } + } else { + logrus.Warnf("failed to determine if Graph endpoint is deprecated when generating redirect URL: %v", err) + } + // Return the redirect URL for the deprecated Azure AD Graph. + return fmt.Sprintf( + "%s?client_id=%s&redirect_uri=%s&resource=%s&scope=openid", + config["authEndpoint"], + config["applicationId"], + config["rancherUrl"], + config["graphEndpoint"], + ) +} + +// extractAnnotationsFromAuthConfig tries to extract the annotations from the AuthConfig value. +// The AuthConfig value might come from either the database (on login attempts) or from the UI (on Azure AD setup attempts). +// In these two cases, the structure of the config is different. +// In the former, it's "metadata.annotations.[map of annotations]". +// In the latter, it's "annotations.[map of annotations]". The function tries to find the annotations in either structure. +func extractAnnotationsFromAuthConfig(config map[string]interface{}) map[string]string { + if metadata, ok := config["metadata"].(map[string]interface{}); ok { + return parseAnnotations(metadata) + } + logrus.Info("Failed to decode the 'metadata' field of the AuthConfig. Attempting to decode 'annotations' at the top level.") + return parseAnnotations(config) +} + +func parseAnnotations(metadata map[string]interface{}) map[string]string { + annotations := make(map[string]string) + rawAnnotations, ok := metadata["annotations"].(map[string]interface{}) + if !ok { + logrus.Info("Failed to decode the 'annotations' field of the AuthConfig.") + return annotations + } + for k, v := range rawAnnotations { + if stringValue, ok := v.(string); ok { + annotations[k] = stringValue + } else { + logrus.Infof("Failed to decode the annotation value of the key %q as a string (%v of type %T) on the AuthConfig.", k, v, v) + } + } + return annotations +} + +func (ap *Provider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + logrus.Errorf("Error fetching azure config: %v", err) + return false, err + } + allowed, err := ap.userMGR.CheckAccess(cfg.AccessMode, cfg.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func samePrincipal(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +// UpdateGroupCacheSize attempts to update the size of the group cache defined at the package level. +func UpdateGroupCacheSize(size string) { + if size == "" { + return + } + + i, err := strconv.Atoi(size) + if err != nil { + logrus.Errorf("error parsing azure-group-cache-size, skipping update %v", err) + return + } + if i < 0 { + logrus.Error("azure-group-cache-size must be >= 0, skipping update") + return + } + clients.GroupCache.Resize(i) +} + +func (ap *Provider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the Azure AD auth provider is currently disabled in Rancher. +func (ap *Provider) IsDisabledProvider() (bool, error) { + azureConfig, err := ap.GetAzureConfigK8s() + if err != nil { + return false, err + } + return !azureConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider_test.go new file mode 100644 index 0000000..ec11aef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/azure_provider_test.go @@ -0,0 +1,442 @@ +package azure + +import ( + "bytes" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/rancher/norman/api/writer" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// TestConfigureTest inspects the Redirect URL during Azure AD setup. +func TestConfigureTest(t *testing.T) { + t.Parallel() + tests := []struct { + name string + authConfig map[string]interface{} + expectedRedirectURL string + }{ + { + name: "initial setup of Azure AD with Microsoft Graph", + authConfig: map[string]interface{}{ + "accessMode": "unrestricted", + "annotations": map[string]interface{}{ + "auth.cattle.io/azuread-endpoint-migrated": "true", + }, + "enabled": false, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.microsoft.com", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedRedirectURL: "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + { + name: "attempt to initially setup Azure AD with deprecated Azure AD Graph", + authConfig: map[string]interface{}{ + "accessMode": "unrestricted", + "annotations": map[string]interface{}{}, + "enabled": false, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedRedirectURL: "https://login.microsoftonline.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + { + name: "editing an existing setup of Azure AD", + authConfig: map[string]interface{}{ + "enabled": true, + "accessMode": "unrestricted", + "annotations": map[string]interface{}{ + "auth.cattle.io/azuread-endpoint-migrated": "true", + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.microsoft.com", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedRedirectURL: "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + { + name: "editing an existing setup of Azure AD without annotation", + authConfig: map[string]interface{}{ + "enabled": true, + "accessMode": "unrestricted", + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedRedirectURL: "https://login.microsoftonline.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&resource=https://graph.windows.net/&scope=openid", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + b, err := json.Marshal(test.authConfig) + assert.NoError(t, err) + + req := httptest.NewRequest(http.MethodPost, "/v3/azureADConfigs/azuread?action=configureTest", bytes.NewReader(b)) + + schemas := types.NewSchemas() + schemas.AddSchemas(managementschema.AuthSchemas) + + rw := &writer.EncodingResponseWriter{ + ContentType: "application/json", + Encoder: types.JSONEncoder, + } + rr := httptest.NewRecorder() + r := &types.APIContext{ + Schemas: schemas, + Request: req, + Response: rr, + ResponseWriter: rw, + Version: &managementschema.Version, + } + + provider := Provider{} + err = provider.ConfigureTest(r) + assert.NoError(t, err) + + res := rr.Result() + defer res.Body.Close() + + var output v3.AzureADConfigTestOutput + err = json.NewDecoder(res.Body).Decode(&output) + assert.NoError(t, err) + assert.Equal(t, test.expectedRedirectURL, output.RedirectURL) + }) + } + +} + +func TestTransformToAuthProvider(t *testing.T) { + t.Parallel() + tests := []struct { + name string + authConfig map[string]interface{} + expectedAuthProvider map[string]interface{} + }{ + { + name: "redirect URL for Microsoft Graph", + authConfig: map[string]interface{}{ + "enabled": true, + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{ + "auth.cattle.io/azuread-endpoint-migrated": "true", + }, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.microsoft.com", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tokenUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/token", + "deviceAuthUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + { + name: "redirect URL for Azure AD Graph", + authConfig: map[string]interface{}{ + "enabled": true, + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{}, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tokenUrl": "https://login.microsoftonline.com/tenant123/oauth2/token", + "deviceAuthUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&resource=https://graph.windows.net/&scope=openid", + }, + }, + { + name: "redirect URL for disabled auth provider with annotation", + authConfig: map[string]interface{}{ + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{ + "auth.cattle.io/azuread-endpoint-migrated": "true", + }, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.microsoft.com", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize", + "tokenUrl": "https://login.microsoftonline.com/tenant123/oauth2/token", + "deviceAuthUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + { + name: "redirect URL for disabled auth provider without annotation", + authConfig: map[string]interface{}{ + "enabled": false, // Here, enabled is set to false explicitly. + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{}, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "tokenEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/token", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tokenUrl": "https://login.microsoftonline.com/tenant123/oauth2/token", + "deviceAuthUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + { + name: "oauth URLs from default endpoint", + authConfig: map[string]interface{}{ + "enabled": false, // Here, enabled is set to false explicitly. + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{}, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "authEndpoint": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize", + "tokenUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/token", + "deviceAuthUrl": "https://login.microsoftonline.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://login.microsoftonline.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + { + name: "oauth URLs from custom endpoint and no oauth URLs", + authConfig: map[string]interface{}{ + "enabled": false, // Here, enabled is set to false explicitly. + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{}, + }, + "endpoint": "https://myendpoint.com/", + "graphEndpoint": "https://graph.windows.net/", + "authEndpoint": "https://myendpoint.com/tenant123/oauth2/authorize", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://myendpoint.com/tenant123/oauth2/authorize", + "tokenUrl": "https://myendpoint.com/tenant123/oauth2/v2.0/token", + "deviceAuthUrl": "https://myendpoint.com/tenant123/oauth2/v2.0/devicecode", + "redirectUrl": "https://myendpoint.com/tenant123/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + { + name: "oauth URLs from custom URLs", + authConfig: map[string]interface{}{ + "enabled": false, // Here, enabled is set to false explicitly. + "accessMode": "unrestricted", + "metadata": map[string]interface{}{ + "name": "providerName", + "annotations": map[string]interface{}{}, + }, + "endpoint": "https://login.microsoftonline.com/", + "graphEndpoint": "https://graph.windows.net/", + "tokenEndpoint": "https://custom.com/oauth2/token", + "authEndpoint": "https://custom.com/oauth2/authorize", + "deviceAuthEndpoint": "https://custom.com/oauth2/device", + "tenantId": "tenant123", + "applicationId": "app123", + "applicationSecret": "secret123", + "rancherUrl": "https://myrancher.com", + }, + expectedAuthProvider: map[string]interface{}{ + "id": "providerName", + "clientId": "app123", + "tenantId": "tenant123", + "scopes": []string{"openid", "profile", "email"}, + "authUrl": "https://custom.com/oauth2/authorize", + "tokenUrl": "https://custom.com/oauth2/token", + "deviceAuthUrl": "https://custom.com/oauth2/device", + "redirectUrl": "https://custom.com/oauth2/authorize?client_id=app123&redirect_uri=https://myrancher.com&response_type=code&scope=openid", + }, + }, + } + + var provider Provider + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + authProvider, err := provider.TransformToAuthProvider(test.authConfig) + assert.NoError(t, err) + assert.Equal(t, test.expectedAuthProvider, authProvider) + }) + } +} + +func TestMigrateNewFlowAnnotation(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + current *v3.AzureADConfig + proposed *v3.AzureADConfig + annotationExpected bool + }{ + { + name: "new setup on Rancher v2.6.7+ after an upgrade from previous version", + current: &v3.AzureADConfig{ + AuthConfig: v3.AuthConfig{ + Enabled: false, + }, + GraphEndpoint: "https://graph.microsoft.com", + }, + proposed: &v3.AzureADConfig{}, + annotationExpected: true, + }, + { + name: "new setup on Rancher v2.6.7+", + current: &v3.AzureADConfig{ + AuthConfig: v3.AuthConfig{ + Enabled: false, + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + GraphEndpointMigratedAnnotation: "true", + }, + }, + }, + GraphEndpoint: "https://graph.microsoft.com", + }, + proposed: &v3.AzureADConfig{}, + annotationExpected: true, + }, + { + name: "reconfigure existing deprecated setup", + current: &v3.AzureADConfig{ + AuthConfig: v3.AuthConfig{ + Enabled: true, + }, + GraphEndpoint: "https://graph.windows.net/", + }, + proposed: &v3.AzureADConfig{}, + annotationExpected: false, + }, + { + name: "reconfigure existing new setup", + current: &v3.AzureADConfig{ + AuthConfig: v3.AuthConfig{ + Enabled: true, + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + GraphEndpointMigratedAnnotation: "true", + }, + }, + }, + GraphEndpoint: "https://graph.microsoft.com", + }, + proposed: &v3.AzureADConfig{}, + annotationExpected: true, + }, + } + + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + migrateNewFlowAnnotation(test.current, test.proposed) + _, hasAnnotation := test.proposed.Annotations[GraphEndpointMigratedAnnotation] + if test.annotationExpected && !hasAnnotation { + assert.Fail(t, "expected annotation on the processed config, but did not find one") + } + if !test.annotationExpected && hasAnnotation { + assert.Fail(t, "did not expect the annotation on the processed config, but found one") + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ad_graph_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ad_graph_client.go new file mode 100644 index 0000000..c79e091 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ad_graph_client.go @@ -0,0 +1,237 @@ +package clients + +import ( + "context" + "strings" + + "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type azureADGraphClient struct { + servicePrincipal adal.ServicePrincipalToken + userClient graphrbac.UsersClient + groupClient graphrbac.GroupsClient +} + +// GetUser takes a user ID and fetches the user principal from the Azure AD Graph API. +func (c *azureADGraphClient) GetUser(id string) (v3.Principal, error) { + user, err := c.userClient.Get(context.Background(), id) + if err != nil { + return v3.Principal{}, err + } + return c.userToPrincipal(user) +} + +// ListUsers fetches all user principals in a directory from the Azure AD Graph API. +func (c *azureADGraphClient) ListUsers(filter string) ([]v3.Principal, error) { + users, err := c.userClient.List(context.Background(), filter, "") + if err != nil { + return nil, err + } + + var principals []v3.Principal + for _, u := range users.Values() { + principal, err := c.userToPrincipal(u) + if err != nil { + return nil, err + } + principals = append(principals, principal) + } + return principals, err +} + +// GetGroup takes a group ID and fetches the group principal from the Azure AD Graph API. +func (c *azureADGraphClient) GetGroup(id string) (v3.Principal, error) { + group, err := c.groupClient.Get(context.Background(), id) + if err != nil { + return v3.Principal{}, err + } + return c.groupToPrincipal(group) +} + +// ListGroups fetches all group principals in a directory from the Azure AD Graph API. +func (c *azureADGraphClient) ListGroups(filter string) ([]v3.Principal, error) { + groups, err := c.groupClient.List(context.Background(), filter) + if err != nil { + return nil, err + } + + var principals []v3.Principal + for _, u := range groups.Values() { + principal, err := c.groupToPrincipal(u) + if err != nil { + return nil, err + } + principals = append(principals, principal) + } + return principals, err +} + +// ListGroupMemberships takes a user ID and fetches the user's group principals as strings IDs from the Azure AD Graph API. +func (c *azureADGraphClient) ListGroupMemberships(id string, filter string) ([]string, error) { + securityEnabledOnly := false + params := graphrbac.UserGetMemberGroupsParameters{ + SecurityEnabledOnly: &securityEnabledOnly, + } + groups, err := c.userClient.GetMemberGroups(context.Background(), id, params) + if err != nil { + return nil, err + } + return *groups.Value, nil +} + +// LoginUser fetches the user principal, user's group principals, and provider access token. +func (c *azureADGraphClient) LoginUser(_ *v32.AzureADConfig, _ *v32.AzureADLogin) (v3.Principal, []v3.Principal, string, error) { + oid, err := ExtractFieldFromJWT(c.AccessToken(), "oid") + if err != nil { + return v3.Principal{}, nil, "", err + } + + logrus.Debug("[AZURE_PROVIDER] Started getting user info from AzureAD") + userPrincipal, err := c.GetUser(oid.(string)) + if err != nil { + return v3.Principal{}, nil, "", err + } + userPrincipal.Me = true + logrus.Debug("[AZURE_PROVIDER] Completed getting user info from AzureAD") + + userGroups, err := c.ListGroupMemberships(GetPrincipalID(userPrincipal), "") + if err != nil { + return v3.Principal{}, nil, "", err + } + + groupPrincipals, err := UserGroupsToPrincipals(c, userGroups) + if err != nil { + return v3.Principal{}, nil, "", err + } + + providerToken, err := c.MarshalTokenJSON() + if err != nil { + return v3.Principal{}, nil, "", err + } + + return userPrincipal, groupPrincipals, providerToken, nil +} + +// NewADGraphClientFromCredential configures the SPT, user, and group clients using a credential. +func NewADGraphClientFromCredential(config *v32.AzureADConfig, credential *v32.AzureADLogin) (AzureClient, error) { + var c azureADGraphClient + logrus.Debug("[AZURE_PROVIDER] Started token swap with AzureAD") + oauthConfig, err := adal.NewOAuthConfig(config.Endpoint, config.TenantID) + if err != nil { + return nil, err + } + + // The tenantID should not be in the endpoint, drop /tenantID + tenant := config.TenantID + if strings.Contains(config.GraphEndpoint, tenant) { + i := strings.Index(config.GraphEndpoint, tenant) + config.GraphEndpoint = config.GraphEndpoint[:i-1] + } + + spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode( + *oauthConfig, + config.ApplicationID, + config.ApplicationSecret, + credential.Code, + config.RancherURL, + config.GraphEndpoint, + ) + if err != nil { + return nil, err + } + + if err := spt.Refresh(); err != nil { + return nil, err + } + logrus.Debug("[AZURE_PROVIDER] Completed token swap with AzureAD") + + c.setInternalFields(config, *spt) + return &c, err +} + +// NewAzureADGraphClientFromADALToken returns an Azure AD Graph client. +// It sets up the SPT, user and group client using an access token to Azure AD Graph API. +func NewAzureADGraphClientFromADALToken(config *v32.AzureADConfig, adalTokenSecret string) (AzureClient, error) { + adalToken, err := unmarshalADALToken(adalTokenSecret) + if err != nil { + return nil, err + } + ac := &azureADGraphClient{} + + oauthConfig, err := adal.NewOAuthConfig(config.Endpoint, config.TenantID) + if err != nil { + return nil, err + } + + secret := &adal.ServicePrincipalAuthorizationCodeSecret{ + ClientSecret: config.ApplicationSecret, + } + + spt, err := adal.NewServicePrincipalTokenFromManualTokenSecret( + *oauthConfig, + config.ApplicationID, + config.GraphEndpoint, + adalToken, + secret) + + if err != nil { + return nil, err + } + + ac.setInternalFields(config, *spt) + return ac, nil +} + +func (c *azureADGraphClient) setInternalFields(config *v32.AzureADConfig, spt adal.ServicePrincipalToken) { + c.servicePrincipal = spt + + // Create the required bearer token. + bearer := autorest.NewBearerAuthorizer(&spt) + + // Set up the user client. + userClient := graphrbac.NewUsersClientWithBaseURI(config.GraphEndpoint, config.TenantID) + userClient.Authorizer = bearer + c.userClient = userClient + + // Set up the group client. + groupClient := graphrbac.NewGroupsClientWithBaseURI(config.GraphEndpoint, config.TenantID) + groupClient.Authorizer = bearer + c.groupClient = groupClient +} + +// AccessToken returns the OAuthToken from the underlying SPT. +func (c *azureADGraphClient) AccessToken() string { + return c.servicePrincipal.OAuthToken() +} + +// MarshalTokenJSON returns the JSON representation of the underlying access token. +func (c *azureADGraphClient) MarshalTokenJSON() (string, error) { + b, err := c.servicePrincipal.MarshalTokenJSON() + return string(b), err +} + +func (c *azureADGraphClient) userToPrincipal(user graphrbac.User) (v3.Principal, error) { + return v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: Name + "_user://" + *user.ObjectID}, + DisplayName: *user.DisplayName, + LoginName: *user.UserPrincipalName, + PrincipalType: "user", + Provider: Name, + }, nil +} + +func (c *azureADGraphClient) groupToPrincipal(group graphrbac.ADGroup) (v3.Principal, error) { + return v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: Name + "_group://" + *group.ObjectID}, + DisplayName: *group.DisplayName, + PrincipalType: "group", + Provider: Name, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/client.go new file mode 100644 index 0000000..4ecdf8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/client.go @@ -0,0 +1,42 @@ +package clients + +import ( + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +// Name is the identifier for the Azure AD auth provider. +const Name = "azuread" + +// AzureClient specifies the subset of operations that a real client would delegate to some SDK for accessing +// one of the two APIs to work with Active Directory resources - Azure AD Graph and Microsoft Graph. +type AzureClient interface { + LoginUser(*v32.AzureADConfig, *v32.AzureADLogin) (v3.Principal, []v3.Principal, string, error) + AccessToken() string + MarshalTokenJSON() (string, error) + + GetUser(id string) (v3.Principal, error) + ListUsers(filter string) ([]v3.Principal, error) + GetGroup(id string) (v3.Principal, error) + ListGroups(filter string) ([]v3.Principal, error) + ListGroupMemberships(id string, filter string) ([]string, error) +} + +// NewAzureClientFromCredential returns a new client to be used for first-time authentication. This means it does not need any +// externally stored secrets with tokens, as is the case when a client is created to use an existing access token. +func NewAzureClientFromCredential(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, credential *v32.AzureADLogin, secrets corev1.SecretInterface) (AzureClient, error) { + if useDeprecatedAzureADClient { + return NewADGraphClientFromCredential(config, credential) + } + return NewMSGraphClient(config, secrets) +} + +// NewAzureClientFromSecret returns a new client to be used for search and other activities after initial authentication. +// The client would fetch the access token from either a refresh token or secret contents passed in. +func NewAzureClientFromSecret(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, secret string, secrets corev1.SecretInterface) (AzureClient, error) { + if useDeprecatedAzureADClient { + return NewAzureADGraphClientFromADALToken(config, secret) + } + return NewMSGraphClient(config, secrets) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/extract.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/extract.go new file mode 100644 index 0000000..5e2984f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/extract.go @@ -0,0 +1,76 @@ +package clients + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strings" + + "github.com/Azure/go-autorest/autorest/adal" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +// GetPrincipalID attempts to extract the ID of either a user or group from the principal value. +func GetPrincipalID(principal v3.Principal) string { + name := principal.ObjectMeta.Name + if parts := strings.Split(name, "//"); len(parts) > 1 { + return parts[1] + } + return "" +} + +// ExtractFieldFromJWT attempts to extract a value from a JWT by field name. +// It does not make assumptions about the type of the return value, so the caller is responsible for handling that. +func ExtractFieldFromJWT(tokenString string, fieldID string) (interface{}, error) { + pieces := strings.Split(tokenString, ".") + if len(pieces) != 3 { + return "", fmt.Errorf("invalid token") + } + decoded, err := base64.RawURLEncoding.DecodeString(pieces[1]) + if err != nil { + return "", fmt.Errorf("error decoding token") + } + + var data map[string]interface{} + err = json.Unmarshal(decoded, &data) + if err != nil { + return "", fmt.Errorf("error unmarshaling token") + } + if _, ok := data[fieldID]; !ok { + return "", fmt.Errorf("missing field %s from token", fieldID) + } + return data[fieldID], nil +} + +// ParsePrincipalID accepts a principalID in the format _:// +// and returns a map containing ID, provider, and type. +func ParsePrincipalID(principalID string) (map[string]string, error) { + parsed := make(map[string]string) + + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return parsed, fmt.Errorf("invalid id %v", principalID) + } + externalID := strings.TrimPrefix(parts[1], "//") + + parsed["ID"] = externalID + + pparts := strings.SplitN(parts[0], "_", 2) + if len(pparts) != 2 { + return parsed, fmt.Errorf("invalid id %v", principalID) + } + + parsed["provider"] = pparts[0] + parsed["type"] = pparts[1] + + return parsed, nil +} + +func unmarshalADALToken(secret string) (adal.Token, error) { + var azureToken adal.Token + err := json.Unmarshal([]byte(secret), &azureToken) + if err != nil { + return azureToken, err + } + return azureToken, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/group_cache.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/group_cache.go new file mode 100644 index 0000000..414f0bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/group_cache.go @@ -0,0 +1,65 @@ +package clients + +import ( + "time" + + lru "github.com/hashicorp/golang-lru" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" +) + +// GroupCache is an in-memory cache of group principals. +var GroupCache *lru.Cache + +// UserGroupsToPrincipals attempts to convert a value representing a collection of groups to a slice of principal values. +// It also stores group values in an in-memory cache for faster subsequent access. +func UserGroupsToPrincipals(azureClient AzureClient, groupNames []string) ([]v3.Principal, error) { + var tasksManager errgroup.Group + groupPrincipals := make([]v3.Principal, len(groupNames)) + + start := time.Now() + logrus.Debug("[AZURE_PROVIDER] Started gathering users groups") + + for i, id := range groupNames { + if id == "" { + continue + } + + j := i + groupID := id + + if principal, ok := GroupCache.Get(groupID); ok { + p, ok := principal.(v3.Principal) + if !ok { + logrus.Errorf("failed to convert a cached group to principal") + continue + } + groupPrincipals[j] = p + continue + } + + tasksManager.Go(func() error { + // This is inefficient for a collection of msgraph.Group. This is temporary - until support for Azure AD Graph is removed. + // The SDK for Microsoft Graph returns actual groups when queried for a user's group memberships. + // The SDK for Azure AD Graph returns group names as strings. + // The common interface that abstracts the Graph operations returns group names as strings. + // So Microsoft Graph groups are effectively fetched twice. But this happens only once - before the groups are added to the cache. + groupObj, err := azureClient.GetGroup(groupID) + if err != nil { + logrus.Errorf("[AZURE_PROVIDER] Error getting group: %v", err) + return err + } + groupObj.MemberOf = true + + GroupCache.Add(groupID, groupObj) + groupPrincipals[j] = groupObj + return nil + }) + } + if err := tasksManager.Wait(); err != nil { + return nil, err + } + logrus.Debugf("[AZURE_PROVIDER] Completed gathering users groups, took %v, keys in cache:%v", time.Since(start), GroupCache.Len()) + return groupPrincipals, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client.go new file mode 100644 index 0000000..060b5d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client.go @@ -0,0 +1,460 @@ +package clients + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/url" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential" + "github.com/coreos/go-oidc/v3/oidc" + abstractions "github.com/microsoft/kiota-abstractions-go" + msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go" + msgraphsdkgo "github.com/microsoftgraph/msgraph-sdk-go" + msgraphcore "github.com/microsoftgraph/msgraph-sdk-go-core" + msgraphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups" + "github.com/microsoftgraph/msgraph-sdk-go/models" + msgraphusers "github.com/microsoftgraph/msgraph-sdk-go/users" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + normancorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + // AccessTokenSecretName is the name of the secret that contains an access token for the Microsoft Graph API. + AccessTokenSecretName = "azuread-access-token" + + providerLogPrefix = "AZUREAD_PROVIDER" + cacheLogPrefix = "AZUREAD_PROVIDER_CACHE" +) + +// NewMSGraphClient creates and returns a new client for accessing the Azure +// Graph client. + +// It first tries to fetch the token from the refresh token, if the access token is found in the database. +// If that fails, it tries to acquire it directly from the auth provider with the credential (application secret in Azure). +// It also checks that the access token has the necessary permissions. +func NewMSGraphClient(config *v32.AzureADConfig, secrets normancorev1.SecretInterface) (*AzureMSGraphClient, error) { + cred, err := confidential.NewCredFromSecret(config.ApplicationSecret) + if err != nil { + return nil, fmt.Errorf("could not create a cred from a secret: %w", err) + } + + authorityURL, err := url.JoinPath(config.Endpoint, config.TenantID) + if err != nil { + return nil, fmt.Errorf("could not create token authority url: %w", err) + } + + tokenCache := accessTokenCache{Secrets: secrets} + confidentialClient, err := confidential.New(authorityURL, config.ApplicationID, cred, + confidential.WithCache(tokenCache)) + if err != nil { + return nil, fmt.Errorf("creating MS Graph client: %w", err) + } + + graphEndpoint, err := url.JoinPath(config.GraphEndpoint, ".default") + if err != nil { + return nil, fmt.Errorf("making graph endpoint for %s: %w", config.GraphEndpoint, err) + } + + var ar confidential.AuthResult + ctx := context.Background() + ar, err = confidentialClient.AcquireTokenSilent(ctx, []string{graphEndpoint}) + if err != nil { + logrus.Debugf("[%s] failed to get the access token from cache: %s", providerLogPrefix, err) + logrus.Debugf("[%s] attempting to acquire the access token by credential", providerLogPrefix) + ar, err = confidentialClient.AcquireTokenByCredential(ctx, []string{graphEndpoint}) + if err != nil { + return nil, fmt.Errorf("acquiring token by credential: %w", err) + } + } else { + logrus.Debugf("[%s] acquired token from cache", providerLogPrefix) + } + + authResult := getCustomAuthResult(ar) + + logrus.Debugf("[%s] connecting to graph endpoint: %s", providerLogPrefix, graphEndpoint) + graphClient, err := msgraphsdk.NewGraphServiceClientWithCredentials( + authResult, []string{graphEndpoint}) + if err != nil { + return nil, fmt.Errorf("creating graph service client: %w", err) + } + + return &AzureMSGraphClient{ + Credential: cred, + GraphEndpointURL: graphEndpoint, + GraphClient: graphClient, + ConfidentialClient: confidentialClient, + authResult: authResult, + }, nil +} + +// AzureMSGraphClient queries the Azure graph API to get users and groups. +type AzureMSGraphClient struct { + confidential.Credential + GraphEndpointURL string + authResult *customAuthResult + ConfidentialClient confidential.Client + + GraphClient *msgraphsdkgo.GraphServiceClient +} + +// GetUser takes a user ID and fetches the user principal from the Microsoft Graph API. +func (c AzureMSGraphClient) GetUser(userID string) (v3.Principal, error) { + logrus.Debugf("[%s] GetUser %s", providerLogPrefix, userID) + result, err := c.GraphClient.Users().ByUserId(userID).Get(context.Background(), nil) + if err != nil { + return v3.Principal{}, fmt.Errorf("getting user by ID: %w", err) + } + + return userToPrincipal(result), nil +} + +// ListUsers fetches all user principals in a directory from the Microsoft Graph API. +func (c AzureMSGraphClient) ListUsers(filter string) ([]v3.Principal, error) { + logrus.Debugf("[%s] ListUsers %s", providerLogPrefix, filter) + result, err := c.GraphClient.Users().Get(context.Background(), &msgraphusers.UsersRequestBuilderGetRequestConfiguration{ + QueryParameters: &msgraphusers.UsersRequestBuilderGetQueryParameters{ + Filter: &filter, + }}) + if err != nil { + return nil, fmt.Errorf("listing users: %w", err) + } + + pageIterator, err := msgraphcore.NewPageIterator[models.Userable]( + result, c.GraphClient.GetAdapter(), models.CreateUserCollectionResponseFromDiscriminatorValue) + if err != nil { + return nil, fmt.Errorf("iterating over user list: %w", err) + } + + var users []v3.Principal + err = pageIterator.Iterate(context.Background(), func(user models.Userable) bool { + users = append(users, userToPrincipal(user)) + return true + }) + + return users, err +} + +// GetGroup takes a group ID and fetches the group principal from the Microsoft Graph API. +func (c AzureMSGraphClient) GetGroup(groupID string) (v3.Principal, error) { + logrus.Debugf("[%s] GetGroup %s", providerLogPrefix, groupID) + result, err := c.GraphClient.Groups().ByGroupId(groupID).Get(context.Background(), nil) + if err != nil { + return v3.Principal{}, fmt.Errorf("getting group by ID: %w", err) + } + + return groupToPrincipal(result), nil +} + +// ListGroups fetches all group principals in a directory from the Microsoft Graph API. +func (c AzureMSGraphClient) ListGroups(filter string) ([]v3.Principal, error) { + logrus.Debugf("[%s] ListGroups %s", providerLogPrefix, filter) + result, err := c.GraphClient.Groups().Get(context.Background(), &msgraphgroups.GroupsRequestBuilderGetRequestConfiguration{ + QueryParameters: &msgraphgroups.GroupsRequestBuilderGetQueryParameters{ + Filter: &filter, + }}) + if err != nil { + return nil, fmt.Errorf("listing groups: %w", err) + } + + pageIterator, err := msgraphcore.NewPageIterator[models.Groupable]( + result, c.GraphClient.GetAdapter(), models.CreateGroupCollectionResponseFromDiscriminatorValue) + if err != nil { + return nil, fmt.Errorf("iterating over group list: %w", err) + } + + var groups []v3.Principal + err = pageIterator.Iterate(context.Background(), func(group models.Groupable) bool { + groups = append(groups, groupToPrincipal(group)) + return true + }) + + return groups, err + +} + +// ListGroupMemberships takes a user ID and fetches the user's group principals as string IDs from the Microsoft Graph API. +func (c AzureMSGraphClient) ListGroupMemberships(userID string, filter string) ([]string, error) { + logrus.Debugf("[%s] ListGroupMemberships %s", providerLogPrefix, userID) + var groupIDs []string + + err := c.listGroupMemberships(context.Background(), userID, filter, func(g *models.Group) { + if id := g.GetId(); id != nil { + groupIDs = append(groupIDs, *id) + } + }) + if err != nil { + return nil, err + } + + return groupIDs, nil +} + +func (c AzureMSGraphClient) listGroupMemberships(ctx context.Context, userID string, filter string, f func(*models.Group)) error { + requestCount := true + headers := abstractions.NewRequestHeaders() + headers.Add("ConsistencyLevel", "eventual") + + result, err := c.GraphClient.Users(). + ByUserId(userID). + TransitiveMemberOf(). + Get(ctx, + &msgraphusers.ItemTransitiveMemberOfRequestBuilderGetRequestConfiguration{ + Headers: headers, + QueryParameters: &msgraphusers.ItemTransitiveMemberOfRequestBuilderGetQueryParameters{ + Filter: &filter, + Count: &requestCount, + }}) + if err != nil { + return fmt.Errorf("listing group memberships: %w", err) + } + + pageIterator, err := msgraphcore.NewPageIterator[models.DirectoryObjectable]( + result, c.GraphClient.GetAdapter(), + models.CreateDirectoryObjectCollectionResponseFromDiscriminatorValue) + if err != nil { + return fmt.Errorf("iterating over group membership list: %w", err) + } + + err = pageIterator.Iterate(ctx, func(do models.DirectoryObjectable) bool { + group, ok := do.(*models.Group) + if !ok { + if _, ok := do.(*models.DirectoryRole); !ok { + logrus.Errorf("[%s] Page Iterator received incorrect value of type %T: %#v", providerLogPrefix, do, do) + } + return true + } + f(group) + + return true + }) + + return err +} + +// LoginUser verifies the user and fetches the user principal, user's group principals. It deliberately does not return +// the provider access token because the client itself handles its caching and does not need to return it. +func (c AzureMSGraphClient) LoginUser(config *v32.AzureADConfig, credential *v32.AzureADLogin) (v3.Principal, []v3.Principal, string, error) { + logrus.Debugf("[%s] Started token swap with AzureAD", providerLogPrefix) + + oid, err := c.getOIDFromLogin(config, credential) + if err != nil { + return v3.Principal{}, nil, "", err + } + + logrus.Debugf("[%s] Completed token swap with AzureAD", providerLogPrefix) + + logrus.Debugf("[%s] Started getting user info from AzureAD", providerLogPrefix) + userPrincipal, err := c.GetUser(oid) + if err != nil { + return v3.Principal{}, nil, "", fmt.Errorf("getting UserInfo from Azure: %w", err) + } + userPrincipal.Me = true + logrus.Debugf("[%s] Completed getting user info from AzureAD", providerLogPrefix) + + groupPrincipals, err := c.listGroupPrincipals(context.Background(), userPrincipal, config.GroupMembershipFilter) + if err != nil { + return v3.Principal{}, nil, "", err + } + + return userPrincipal, groupPrincipals, "", nil +} + +func (c AzureMSGraphClient) listGroupPrincipals(ctx context.Context, userPrincipal v3.Principal, filter string) ([]v3.Principal, error) { + var groups []string + err := c.listGroupMemberships(ctx, GetPrincipalID(userPrincipal), filter, func(g *models.Group) { + if id := g.GetId(); id != nil && g.GetDisplayName() != nil && g.GetSecurityEnabled() != nil { + groups = append(groups, *id) + } + }) + if err != nil { + return nil, fmt.Errorf("listing group memberships: %w", err) + } + + groupPrincipals, err := UserGroupsToPrincipals(c, groups) + if err != nil { + return nil, fmt.Errorf("converting groups to principals: %w", err) + } + + return groupPrincipals, nil +} + +func (c AzureMSGraphClient) getOIDFromLogin(config *v32.AzureADConfig, credential *v32.AzureADLogin) (string, error) { + if credential.IDToken != "" { + // Acquire the OID from the IDToken to verify the user + oidFromToken, err := oidFromIDToken(credential.IDToken, config) + if err != nil { + return "", fmt.Errorf("getting OID from IDToken: %w", err) + } + + return oidFromToken, nil + } + + // Acquire the OID exchanging the Code to verify the user + oidFromCode, err := oidFromAuthCode(credential.Code, config, c.GraphEndpointURL, c.ConfidentialClient) + if err != nil { + return "", fmt.Errorf("getting OID from AuthCode: %w", err) + } + + return oidFromCode, nil +} + +// AccessToken returns the client's underlying provider access token. +func (c AzureMSGraphClient) AccessToken() string { + return c.authResult.AccessToken +} + +// MarshalTokenJSON returns the JSON representation of the underlying access token. +func (c AzureMSGraphClient) MarshalTokenJSON() (string, error) { + b, err := json.Marshal(c.authResult.AccessToken) + + return string(b), err +} + +func userToPrincipal(user models.Userable) v3.Principal { + return v3.Principal{ + ObjectMeta: metav1.ObjectMeta{ + Name: Name + "_user://" + *user.GetId(), + }, + DisplayName: *user.GetDisplayName(), + LoginName: *user.GetUserPrincipalName(), + PrincipalType: "user", + Provider: Name, + } +} + +func groupToPrincipal(group models.Groupable) v3.Principal { + return v3.Principal{ + ObjectMeta: metav1.ObjectMeta{ + Name: Name + "_group://" + *group.GetId(), + }, + DisplayName: *group.GetDisplayName(), + PrincipalType: "group", + Provider: Name, + } +} + +// oidFromIDToken verifies the IDToken, returning the user OID +func oidFromIDToken(token string, config *v32.AzureADConfig) (string, error) { + issuer, err := url.JoinPath(config.Endpoint, config.TenantID, "/v2.0") + if err != nil { + return "", fmt.Errorf("joining issuer path: %w", err) + } + + ctx := context.Background() + + provider, err := oidc.NewProvider(ctx, issuer) + if err != nil { + return "", fmt.Errorf("creating OIDC provider: %w", err) + } + + verifier := provider.Verifier(&oidc.Config{ClientID: config.ApplicationID}) + idToken, err := verifier.Verify(ctx, token) + if err != nil { + return "", fmt.Errorf("verifying user ID Token: %w", err) + } + + var claims struct { + OID string `json:"oid"` + } + + if err = idToken.Claims(&claims); err != nil { + return "", fmt.Errorf("extracting claims: %w", err) + } + + if claims.OID == "" { + return "", errors.New("empty user OID") + } + + return claims.OID, nil +} + +// oidFromAuthCode exchanges the AuthCode for a IDToken, returning the user OID +func oidFromAuthCode(code string, config *v32.AzureADConfig, endpointURL string, confidentialClient confidential.Client) (string, error) { + authResult, err := confidentialClient.AcquireTokenByAuthCode(context.Background(), code, config.RancherURL, []string{endpointURL}) + if err != nil { + return "", err + } + + return authResult.IDToken.Oid, nil +} + +// accessTokenCache is responsible for reading (replacing) the access token from some storage (a secret in the database, +// in this case) and writing it (exporting) to the storage. +// The Microsoft Graph SDK is responsible for verifying and calling the cache methods when needed, +// so this type simply implements the interface for the cache that the SDK requires. +// The SDK is also responsible for fetching a refresh token or a new access token, depending on how close expiration is. +// By default, a new access token from Microsoft Graph expires in one hour. +// +// WARNING: The tokens are stored in plain-text in Kubernetes secrets. +type accessTokenCache struct { + Secrets normancorev1.SecretInterface +} + +// Replace fetches the access token from a secret in Kubernetes. +func (c accessTokenCache) Replace(ctx context.Context, cache cache.Unmarshaler, hints cache.ReplaceHints) error { + secretName := fmt.Sprintf("%s:%s", common.SecretsNamespace, AccessTokenSecretName) + secret, err := common.ReadFromSecret(c.Secrets, secretName, "access-token") + if err != nil { + logrus.Errorf("[%s] Failed to read the access token from Kubernetes: %v", cacheLogPrefix, err) + return client.IgnoreNotFound(err) + } + + err = cache.Unmarshal([]byte(secret)) + if err != nil { + logrus.Errorf("[%s] Failed to unmarshal the access token: %v", cacheLogPrefix, err) + return err + } + + return nil +} + +// Export persists the access token to a secret in Kubernetes. +func (c accessTokenCache) Export(ctx context.Context, cache cache.Marshaler, hints cache.ExportHints) error { + marshalled, err := cache.Marshal() + if err != nil { + logrus.Errorf("[%s] Failed to marshal the access token before saving in Kubernetes: %v", cacheLogPrefix, err) + return err + } + + _, err = common.CreateOrUpdateSecrets(c.Secrets, string(marshalled), "access-token", "azuread") + if err != nil { + logrus.Errorf("[%s] Failed to save the access token in Kubernetes: %v", cacheLogPrefix, err) + return err + } + + return nil +} + +func getCustomAuthResult(result confidential.AuthResult) *customAuthResult { + return &customAuthResult{ + AccessToken: result.AccessToken, + ExpiresOn: result.ExpiresOn, + GrantedScopes: result.GrantedScopes, + DeclinedScopes: result.DeclinedScopes, + } +} + +type customAuthResult struct { + AccessToken string `json:"accessToken,omitempty"` + ExpiresOn time.Time `json:"expiresOn,omitempty"` + GrantedScopes []string `json:"grantedScopes,omitempty"` + DeclinedScopes []string `json:"declinedScopes,omitempty"` +} + +func (c *customAuthResult) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) { + return azcore.AccessToken{ + Token: c.AccessToken, + ExpiresOn: c.ExpiresOn, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client_test.go new file mode 100644 index 0000000..1c9338d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/clients/ms_graph_client_test.go @@ -0,0 +1,259 @@ +package clients + +import ( + "os" + "testing" + + apismgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + normancorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/apis/core" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// NOTE: This will require the following environment variables setup +// +// TEST_AZURE_TENANT_ID +// TEST_AZURE_APPLICATION_ID +// TEST_AZURE_APPLICATION_SECRET + +func TestMSGraphClient_GetUser(t *testing.T) { + secrets := newTestSecretsClient() + client := newTestClientWithSecretsClient(t, secrets) + + user, err := client.GetUser("testuser6@ranchertest.onmicrosoft.com") + if err != nil { + t.Fatal(err) + } + + want := mgmtv3.Principal{ + PrincipalType: "user", + Provider: Name, + ObjectMeta: metav1.ObjectMeta{ + Name: "azuread_user://b2511543-7052-431b-a97d-02e1e9cae337", + }, + DisplayName: "testuser6", + LoginName: "testuser6@ranchertest.onmicrosoft.com", + } + assert.Equal(t, want, user) + + client = newTestClientWithSecretsClient(t, secrets) + _, err = client.GetUser("testuser6@ranchertest.onmicrosoft.com") + if err != nil { + t.Fatal(err) + } +} + +func TestMSGraphClient_ListUsers(t *testing.T) { + client := newTestClient(t) + + users, err := client.ListUsers("") + if err != nil { + t.Fatal(err) + } + + var displayNames []string + for _, v := range users { + displayNames = append(displayNames, v.DisplayName) + } + + assert.Len(t, users, 41) +} + +func TestMSGraphClient_ListUsers_with_filter(t *testing.T) { + client := newTestClient(t) + + users, err := client.ListUsers("startswith(userPrincipalName,'fresh')") + if err != nil { + t.Fatal(err) + } + assert.Len(t, users, 2) +} + +func TestMSGraphClient_GetGroup(t *testing.T) { + client := newTestClient(t) + + group, err := client.GetGroup("00d7a0e6-e0b1-44be-8577-0fb76b13e853") + if err != nil { + t.Fatal(err) + } + + want := mgmtv3.Principal{ + PrincipalType: "group", + Provider: Name, + ObjectMeta: metav1.ObjectMeta{ + Name: "azuread_group://00d7a0e6-e0b1-44be-8577-0fb76b13e853", + }, + DisplayName: "lotsofgroups728", + } + assert.Equal(t, want, group) +} + +func TestMSGraphClient_ListGroups(t *testing.T) { + client := newTestClient(t) + + groups, err := client.ListGroups("") + if err != nil { + t.Fatal(err) + } + + assert.Greater(t, len(groups), 1) +} + +func TestMSGraphClient_ListGroups_with_filter(t *testing.T) { + client := newTestClient(t) + + groups, err := client.ListGroups("") + if err != nil { + t.Fatal(err) + } + unfilteredCount := len(groups) + + groups, err = client.ListGroups("startswith(displayName,'test')") + if err != nil { + t.Fatal(err) + } + + assert.Less(t, len(groups), unfilteredCount) +} + +func TestMSGraphClient_ListGroupMemberships(t *testing.T) { + client := newTestClient(t) + + groups, err := client.ListGroupMemberships("testuser1@ranchertest.onmicrosoft.com", "") + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, []string{ + "15f6a947-9d67-4e7f-b1d0-f5f52145fed3", + "748274fd-3ec7-40d1-b08b-775c1a8ec1af", + "bf881716-8d6d-456f-b234-2b143dfd5cf0"}, groups) +} + +func TestMSGraphClient_ListGroupMemberships_nested_groups(t *testing.T) { + client := newTestClient(t) + + groups, err := client.ListGroupMemberships("anunesteduser1@ranchertest.onmicrosoft.com", "") + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, []string{ + "95469c9b-7f7f-48c4-82f2-a4c1eacf454b", + "bf6fa98e-9d06-46ed-bd62-5d8eee196265", + }, groups) +} + +func TestMSGraphClient_ListGroupMemberships_with_filter(t *testing.T) { + client := newTestClient(t) + + groups, err := client.ListGroupMemberships("testuser1@ranchertest.onmicrosoft.com", "") + if err != nil { + t.Fatal(err) + } + unfilteredCount := len(groups) + + groups, err = client.ListGroupMemberships("testuser1@ranchertest.onmicrosoft.com", "startswith(displayName,'test')") + if err != nil { + t.Fatal(err) + } + + assert.Less(t, len(groups), unfilteredCount) +} + +func newTestClient(t *testing.T) *AzureMSGraphClient { + t.Helper() + return newTestClientWithSecretsClient(t, newTestSecretsClient()) +} + +func newTestClientWithSecretsClient(t *testing.T, secrets normancorev1.SecretInterface) *AzureMSGraphClient { + t.Helper() + tenantID, applicationID, applicationSecret := os.Getenv("TEST_AZURE_TENANT_ID"), os.Getenv("TEST_AZURE_APPLICATION_ID"), os.Getenv("TEST_AZURE_APPLICATION_SECRET") + + if tenantID == "" || applicationID == "" || applicationSecret == "" { + t.Skip("Skipping MSGraph Client Tests for Azure because missing environment variables, TEST_AZURE_TENANT_ID, TEST_AZURE_APPLICATION_ID and TEST_AZURE_APPLICATION_SECRET must be set") + } + + client, err := NewMSGraphClient(&apismgmtv3.AzureADConfig{ + Endpoint: "https://login.microsoftonline.com/", + GraphEndpoint: "https://graph.microsoft.com", + TenantID: tenantID, + ApplicationID: applicationID, + ApplicationSecret: applicationSecret, + }, secrets) + + if err != nil { + t.Fatalf("creating MSGraphClient: %s", err) + } + + return client +} + +func newTestSecretsClient() normancorev1.SecretInterface { + secrets := map[types.NamespacedName]*corev1.Secret{} + + sm := &fakes.SecretInterfaceMock{ + GetNamespacedFunc: func(namespace, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + namespacedName := types.NamespacedName{Namespace: namespace, Name: name} + if s, ok := secrets[namespacedName]; ok { + return s, nil + } + + return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) + }, + + CreateFunc: func(in1 *corev1.Secret) (*corev1.Secret, error) { + if in1.StringData != nil { + if in1.Data == nil { + in1.Data = map[string][]byte{} + } + for k, v := range in1.StringData { + in1.Data[k] = []byte(v) + } + in1.StringData = nil + } + secrets[client.ObjectKeyFromObject(in1)] = in1 + return in1, nil + }, + + UpdateFunc: func(in1 *corev1.Secret) (*corev1.Secret, error) { + if in1.StringData != nil { + if in1.Data == nil { + in1.Data = map[string][]byte{} + } + for k, v := range in1.StringData { + in1.Data[k] = []byte(v) + } + in1.StringData = nil + } + secrets[client.ObjectKeyFromObject(in1)] = in1 + return in1, nil + }, + + ControllerFunc: func() normancorev1.SecretController { + return &fakes.SecretControllerMock{ + ListerFunc: func() normancorev1.SecretLister { + return &fakes.SecretListerMock{ + GetFunc: func(namespace, name string) (*corev1.Secret, error) { + namespacedName := types.NamespacedName{Namespace: namespace, Name: name} + if s, ok := secrets[namespacedName]; ok { + return s, nil + } + + return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) + }, + } + }, + } + }, + } + + return sm +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/config.go new file mode 100644 index 0000000..66b3500 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/config.go @@ -0,0 +1,84 @@ +package azure + +import ( + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +const ( + globalAzureADGraphEndpoint = "https://graph.windows.net/" + globalMSGraphEndpoint = "https://graph.microsoft.com" + chinaAzureADGraphEndpoint = "https://graph.chinacloudapi.cn/" + chinaMSGraphEndpoint = "https://microsoftgraph.chinacloudapi.cn" + + chinaAzureADLoginEndpoint = "https://login.chinacloudapi.cn/" + chinaAzureMSLoginEndpoint = "https://login.partner.microsoftonline.cn/" +) + +// GraphEndpointMigratedAnnotation is the main piece of data based on which Rancher decides to use either the +// deprecated authentication flow via Azure AD Graph or the new one via Microsoft Graph. +// If the annotation is missing on the Auth Config object, or is present with a value of anything other than "true", +// then Rancher uses the old, deprecated flow. If the annotation is present and set to "true", Rancher uses the new flow. +const GraphEndpointMigratedAnnotation = "auth.cattle.io/azuread-endpoint-migrated" + +func authProviderEnabled(config *v32.AzureADConfig) bool { + return config.Enabled && config.GraphEndpoint != "" +} + +// IsConfigDeprecated returns true if a given Azure AD auth config specifies the old, +// deprecated authentication flow via the Azure AD Graph. +func IsConfigDeprecated(cfg *v32.AzureADConfig) bool { + return authProviderEnabled(cfg) && !configHasNewFlowAnnotation(cfg) +} + +func configHasNewFlowAnnotation(cfg *v32.AzureADConfig) bool { + if cfg.ObjectMeta.Annotations != nil { + return cfg.ObjectMeta.Annotations[GraphEndpointMigratedAnnotation] == "true" + } + return false +} + +func updateAzureADEndpoints(c *v32.AzureADConfig) { + if isConfigForChina(c) { + updateEndpointsForChina(c) + } else { + updateEndpointsForGlobal(c) + } +} + +func isConfigForChina(c *v32.AzureADConfig) bool { + return strings.HasSuffix(c.GraphEndpoint, ".cn") || strings.HasSuffix(c.GraphEndpoint, ".cn/") +} + +func updateEndpointsForGlobal(c *v32.AzureADConfig) { + if c.GraphEndpoint != globalAzureADGraphEndpoint { + logrus.Infof("Refusing to upgrade because the Graph Endpoint %s is not deprecated.", c.GraphEndpoint) + return + } + // Update the Graph Endpoint. + c.GraphEndpoint = globalMSGraphEndpoint + // Update the Auth Endpoint and Token Endpoint. + c.AuthEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/authorize", c.Endpoint, c.TenantID) + c.TokenEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/token", c.Endpoint, c.TenantID) + c.DeviceAuthEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/devicecode", c.Endpoint, c.TenantID) +} + +func updateEndpointsForChina(c *v32.AzureADConfig) { + if c.GraphEndpoint != chinaAzureADGraphEndpoint { + logrus.Infof("Refusing to upgrade because the Graph Endpoint %s is not deprecated.", c.GraphEndpoint) + return + } + // Update the Graph Endpoint. + c.GraphEndpoint = chinaMSGraphEndpoint + // Update the login endpoint. + if c.Endpoint == chinaAzureADLoginEndpoint { + c.Endpoint = chinaAzureMSLoginEndpoint + } + // Update the Auth Endpoint and Token Endpoint. + c.AuthEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/authorize", c.Endpoint, c.TenantID) + c.TokenEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/token", c.Endpoint, c.TenantID) + c.DeviceAuthEndpoint = fmt.Sprintf("%s%s/oauth2/v2.0/devicecode", c.Endpoint, c.TenantID) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/migrate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/migrate.go new file mode 100644 index 0000000..7e2e317 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/azure/migrate.go @@ -0,0 +1,65 @@ +package azure + +import ( + "github.com/rancher/norman/httperror" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/api/secrets" + "github.com/rancher/rancher/pkg/auth/providers/azure/clients" + "github.com/sirupsen/logrus" +) + +// migrateToMicrosoftGraph performs a migration of the registered Azure AD auth provider +// from the deprecated Azure AD Graph API to the Microsoft Graph API. +// It modifies the existing auth config in the database, so that it has up-to-date endpoints to the new API. +// Most importantly, it sets the annotation that specifies that the auth config has been migrated to use the new auth flow. +// The method receives the current AuthConfig from the database, then updates it in-memory to use the new endpoints. + +// It also creates a new test Azure client to catch any errors before committing the migration. +// If validation and applying work, then migrateToMicrosoftGraph deletes all secrets with access tokens to the +// deprecated Azure AD Graph API. +func (ap *Provider) migrateToMicrosoftGraph() error { + cfg, err := ap.updateConfigAndTest() + if err != nil { + return err + } + if err = ap.applyUpdatedConfig(cfg); err != nil { + return err + } + ap.deleteUserAccessTokens() + clients.GroupCache.Purge() + return nil +} + +func (ap *Provider) updateConfigAndTest() (*v32.AzureADConfig, error) { + cfg, err := ap.GetAzureConfigK8s() + if err != nil { + return nil, err + } + if !authProviderEnabled(cfg) { + return nil, httperror.NewAPIError(httperror.InvalidState, "the Azure AD auth provider is not enabled") + } + + updateAzureADEndpoints(cfg) + + // Try to get a new client, which will fetch a new access token and catch any errors. + _, err = clients.NewMSGraphClient(cfg, ap.secrets) + if err != nil { + return nil, err + } + + return cfg, nil +} + +func (ap *Provider) applyUpdatedConfig(cfg *v32.AzureADConfig) error { + if cfg.ObjectMeta.Annotations == nil { + cfg.ObjectMeta.Annotations = make(map[string]string) + } + cfg.ObjectMeta.Annotations[GraphEndpointMigratedAnnotation] = "true" + return ap.saveAzureConfigK8s(cfg) +} + +func (ap *Provider) deleteUserAccessTokens() { + if err := secrets.CleanupOAuthTokens(ap.secrets, ap.GetName()); err != nil { + logrus.Errorf("error during OAuth secrets clean up on Azure AD endpoint update: %v", err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/actions.go new file mode 100644 index 0000000..b487bc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/actions.go @@ -0,0 +1,36 @@ +package common + +import ( + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func HandleCommonAction(actionName string, action *types.Action, request *types.APIContext, authConfigName string, authConfigs v3.AuthConfigInterface) (bool, error) { + if actionName == "disable" { + request.Response.Header().Add("Content-type", "application/json") + o, err := authConfigs.ObjectClient().UnstructuredClient().Get(authConfigName, v1.GetOptions{}) + if err != nil { + return false, err + } + u, _ := o.(runtime.Unstructured) + config := u.UnstructuredContent() + if e, ok := config[client.AuthConfigFieldEnabled].(bool); ok && e { + config[client.AuthConfigFieldEnabled] = false + logrus.Infof("Disabling auth provider %s from the action.", authConfigName) + _, err = authConfigs.ObjectClient().Update(authConfigName, o) + return true, err + } + } + + return false, nil +} + +func AddCommonActions(apiContext *types.APIContext, resource *types.RawResource) { + if e, ok := resource.Values["enabled"].(bool); ok && e { + resource.AddAction(apiContext, "disable") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/ldap/ldap_util.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/ldap/ldap_util.go new file mode 100644 index 0000000..aea3b6c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/ldap/ldap_util.go @@ -0,0 +1,314 @@ +package ldap + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "strconv" + "strings" + "time" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ConfigAttributes struct { + GroupMemberMappingAttribute string + GroupNameAttribute string + GroupObjectClass string + GroupSearchAttribute string + ObjectClass string + ProviderName string + UserLoginAttribute string + UserNameAttribute string + UserObjectClass string +} + +func Connect(config *v3.LdapConfig, caPool *x509.CertPool) (*ldapv3.Conn, error) { + return NewLDAPConn(config.Servers, config.TLS, config.StartTLS, config.Port, config.ConnectionTimeout, caPool) +} + +func NewLDAPConn(servers []string, TLS, startTLS bool, port int64, connectionTimeout int64, caPool *x509.CertPool) (*ldapv3.Conn, error) { + logrus.Debug("Now creating Ldap connection") + var lConn *ldapv3.Conn + var err error + var tlsConfig *tls.Config + ldapv3.DefaultTimeout = time.Duration(connectionTimeout) * time.Millisecond + if len(servers) < 1 { + return nil, errors.New("invalid server config. at least 1 server needs to be configured") + } + for _, server := range servers { + tlsConfig = &tls.Config{RootCAs: caPool, InsecureSkipVerify: false, ServerName: server} + if TLS { + lConn, err = ldapv3.DialTLS("tcp", fmt.Sprintf("%s:%d", server, port), tlsConfig) + if err != nil { + err = fmt.Errorf("Error creating ssl connection: %v", err) + } + } else if startTLS { + lConn, err = ldapv3.Dial("tcp", fmt.Sprintf("%s:%d", server, port)) + if err != nil { + err = fmt.Errorf("Error creating connection for startTLS: %v", err) + } else if err = lConn.StartTLS(tlsConfig); err != nil { + err = fmt.Errorf("Error upgrading startTLS connection: %v", err) + } + } else { + lConn, err = ldapv3.Dial("tcp", fmt.Sprintf("%s:%d", server, port)) + if err != nil { + err = fmt.Errorf("Error creating connection: %v", err) + } + } + if err == nil { + lConn.SetTimeout(time.Duration(connectionTimeout) * time.Millisecond) + return lConn, nil + } + } + + return nil, err +} + +func GetUserExternalID(username string, loginDomain string) string { + if strings.Contains(username, "\\") { + return username + } else if loginDomain != "" { + return loginDomain + "\\" + username + } + return username +} + +func HasPermission(attributes []*ldapv3.EntryAttribute, userObjectClass string, userEnabledAttribute string, userDisabledBitMask int64) bool { + var permission int64 + if !IsType(attributes, userObjectClass) { + return true + } + + if userEnabledAttribute != "" { + for _, attr := range attributes { + if attr.Name == userEnabledAttribute { + if len(attr.Values) > 0 && attr.Values[0] != "" { + intAttr, err := strconv.ParseInt(attr.Values[0], 10, 64) + if err != nil { + logrus.Errorf("Failed to get USER_ENABLED_ATTRIBUTE, error: %v", err) + return false + } + permission = intAttr + } + } + } + } else { + return true + } + permission = permission & userDisabledBitMask + return permission != userDisabledBitMask +} + +func IsType(search []*ldapv3.EntryAttribute, varType string) bool { + for _, attrib := range search { + if strings.EqualFold(attrib.Name, "objectClass") { + for _, val := range attrib.Values { + if strings.EqualFold(val, varType) { + logrus.Debugf("ldap IsType found object of type %s", varType) + return true + } + } + } + } + logrus.Debugf("ldap IsType failed to determine if object is type: %s", varType) + return false +} + +func GetAttributeValuesByName(search []*ldapv3.EntryAttribute, attributeName string) []string { + for _, attrib := range search { + if attrib.Name == attributeName { + return attrib.Values + } + } + return []string{} +} + +func AuthenticateServiceAccountUser(serviceAccountPassword string, serviceAccountUsername string, defaultLoginDomain string, lConn ldapv3.Client) error { + logrus.Debug("Binding service account username password") + if serviceAccountPassword == "" { + return httperror.NewAPIError(httperror.MissingRequired, "service account password not provided") + } + sausername := GetUserExternalID(serviceAccountUsername, defaultLoginDomain) + err := lConn.Bind(sausername, serviceAccountPassword) + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) { + return httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") + } + return httperror.WrapAPIError(err, httperror.ServerError, "server error while authenticating") + } + + return nil +} + +func AttributesToPrincipal(attribs []*ldapv3.EntryAttribute, dnStr, scope, providerName, userObjectClass, userNameAttribute, userLoginAttribute, groupObjectClass, groupNameAttribute string) (*v3.Principal, error) { + var externalIDType, accountName, externalID, login, kind string + externalID = dnStr + externalIDType = scope + + if IsType(attribs, userObjectClass) { + for _, attr := range attribs { + if attr.Name == userNameAttribute { + if len(attr.Values) != 0 { + accountName = attr.Values[0] + } else { + accountName = externalID + } + } + if attr.Name == userLoginAttribute { + if len(attr.Values) > 0 && attr.Values[0] != "" { + login = attr.Values[0] + } + } + } + if login == "" { + login = accountName + } + kind = "user" + } else if IsType(attribs, groupObjectClass) { + for _, attr := range attribs { + if attr.Name == groupNameAttribute { + if len(attr.Values) != 0 { + accountName = attr.Values[0] + } else { + accountName = externalID + } + } + if attr.Name == userLoginAttribute { + if len(attr.Values) > 0 && attr.Values[0] != "" { + login = attr.Values[0] + } + } + } + if login == "" { + login = accountName + } + kind = "group" + } else { + return nil, fmt.Errorf("Failed to get attributes for %s", dnStr) + } + + principal := &v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: externalIDType + "://" + externalID}, + DisplayName: accountName, + LoginName: login, + PrincipalType: kind, + Me: true, + Provider: providerName, + } + return principal, nil +} + +func GatherParentGroups(groupPrincipal v3.Principal, searchDomain string, groupScope string, config *ConfigAttributes, lConn ldapv3.Client, + groupMap map[string]bool, nestedGroupPrincipals *[]v3.Principal, searchAttributes []string) error { + groupMap[groupPrincipal.ObjectMeta.Name] = true + principals := []v3.Principal{} + //var searchAttributes []string + parts := strings.SplitN(groupPrincipal.ObjectMeta.Name, ":", 2) + if len(parts) != 2 { + return errors.Errorf("invalid id %v", groupPrincipal.ObjectMeta.Name) + } + groupDN := strings.TrimPrefix(parts[1], "//") + + filter := fmt.Sprintf( + "(&(%v=%v)(%v=%v))", + config.GroupMemberMappingAttribute, ldapv3.EscapeFilter(groupDN), + config.ObjectClass, config.GroupObjectClass, + ) + + searchGroup := NewWholeSubtreeSearchRequest( + searchDomain, + filter, + searchAttributes, + ) + + resultGroups, err := lConn.SearchWithPaging(searchGroup, 1000) + if err != nil { + return err + } + + for i := 0; i < len(resultGroups.Entries); i++ { + entry := resultGroups.Entries[i] + principal, err := AttributesToPrincipal(entry.Attributes, entry.DN, groupScope, config.ProviderName, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + logrus.Errorf("Error translating group result: %v", err) + continue + } + principals = append(principals, *principal) + } + + for _, gp := range principals { + if _, ok := groupMap[gp.ObjectMeta.Name]; ok { + continue + } else { + *nestedGroupPrincipals = append(*nestedGroupPrincipals, gp) + err = GatherParentGroups(gp, searchDomain, groupScope, config, lConn, groupMap, nestedGroupPrincipals, searchAttributes) + if err != nil { + return err + } + } + } + return nil +} + +func FindNonDuplicateBetweenGroupPrincipals(newGroupPrincipals []v3.Principal, groupPrincipals []v3.Principal, nonDupGroupPrincipals []v3.Principal) []v3.Principal { + for _, gp := range newGroupPrincipals { + counter := 0 + for _, usermembergp := range groupPrincipals { + // check the groups ObjectMeta.Name and name fields value are the same, then they are the same group + if gp.ObjectMeta.Name == usermembergp.ObjectMeta.Name && gp.DisplayName == usermembergp.DisplayName { + break + } else { + counter++ + } + } + if counter == len(groupPrincipals) { + nonDupGroupPrincipals = append(nonDupGroupPrincipals, gp) + } + } + return nonDupGroupPrincipals +} + +func NewCAPool(cert string) (*x509.CertPool, error) { + pool, err := x509.SystemCertPool() + if err != nil { + return nil, err + } + pool.AppendCertsFromPEM([]byte(cert)) + return pool, nil +} + +// NewWholeSubtreeSearchRequest will return a NewDefaultSearchRequest with a ScopeWholeSubtree scope +func NewWholeSubtreeSearchRequest(baseDN, filter string, attributes []string) *ldapv3.SearchRequest { + return NewDefaultSearchRequest(baseDN, filter, ldapv3.ScopeWholeSubtree, attributes) +} + +// NewBaseObjectSearchRequest will return a NewDefaultSearchRequest with a ScopeBaseObject scope +func NewBaseObjectSearchRequest(baseDN, filter string, attributes []string) *ldapv3.SearchRequest { + return NewDefaultSearchRequest(baseDN, filter, ldapv3.ScopeBaseObject, attributes) +} + +// NewDefaultSearchRequest will return a new *ldapv3.SearchRequest based on some fixed common arguments: +// - DerefAliases (NeverDerefAliases) +// - SizeLimit (0) +// - TimeLimit (0) +// - TypesOnly (false) +// - Controls (nil) +func NewDefaultSearchRequest(baseDN, filter string, scope int, attributes []string) *ldapv3.SearchRequest { + return ldapv3.NewSearchRequest( + baseDN, // BaseDN + scope, // Scope + ldapv3.NeverDerefAliases, // DerefAliases + 0, // SizeLimit + 0, // TimeLimit + false, // TypesOnly + filter, // Filter + attributes, // Attributes + nil, // Controls + ) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password.go new file mode 100644 index 0000000..83aa705 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password.go @@ -0,0 +1,112 @@ +package common + +import ( + "fmt" + "reflect" + "strings" + + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const SecretsNamespace = namespace.GlobalNamespace + +// NameForSecret returns a string with the namespace:name for the provided +// Secret. +func NameForSecret(s *corev1.Secret) string { + return fmt.Sprintf("%s:%s", s.GetNamespace(), s.GetName()) +} + +// CreateOrUpdateSecrets creates a new Secret for a specific authorisation +// mechanism. +// +// The secret is created with field: secretInfo as its .Data and the authType +// and field as the Name. +// +// In the event that the Secret already exists, if the .Data doesn't match the +// desired state it is overwritten. +// +// It returns a string with the namespace:name of the created Secret. +func CreateOrUpdateSecrets(secrets corev1.SecretInterface, secretInfo, field, authType string) (string, error) { + if secretInfo == "" { + return "", nil + } + + name := fmt.Sprintf("%s-%s", authType, field) + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: SecretsNamespace, + }, + StringData: map[string]string{field: secretInfo}, + Type: v1.SecretTypeOpaque, + } + + curr, err := secrets.Controller().Lister().Get(SecretsNamespace, name) + if err != nil && !apierrors.IsNotFound(err) { + return "", fmt.Errorf("error getting secret for %s : %w", name, err) + } + + if err == nil && !reflect.DeepEqual(curr.Data, secret.Data) { + _, err = secrets.Update(secret) + if err != nil { + return "", fmt.Errorf("error updating secret %s: %w", name, err) + } + } else if apierrors.IsNotFound(err) { + _, err = secrets.Create(secret) + if err != nil && !apierrors.IsAlreadyExists(err) { + return "", fmt.Errorf("error creating secret %s %w", name, err) + } + } + + return NameForSecret(secret), nil +} + +func ReadFromSecret(secrets corev1.SecretInterface, secretInfo string, field string) (string, error) { + if strings.HasPrefix(secretInfo, SecretsNamespace) { + data, err := ReadFromSecretData(secrets, secretInfo) + if err != nil { + return "", err + } + for key, val := range data { + if key == field { + return string(val), nil + } + } + } + return secretInfo, nil +} + +func ReadFromSecretData(secrets corev1.SecretInterface, secretInfo string) (map[string][]byte, error) { + if strings.HasPrefix(secretInfo, SecretsNamespace) { + split := strings.SplitN(secretInfo, ":", 2) + if len(split) == 2 { + secret, err := secrets.GetNamespaced(split[0], split[1], metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("error getting secret %s: %w", secretInfo, err) + } + return secret.Data, nil + } + } + return nil, nil +} + +// GetFullSecretName returns a formatted name for a secret associated with an auth provider, +// given a config type and its field. +func GetFullSecretName(configType string, field string) string { + return fmt.Sprintf("%s:%s-%s", SecretsNamespace, strings.ToLower(configType), field) +} + +// DeleteSecret deletes a secret associated with an auth provider. +func DeleteSecret(secrets corev1.SecretInterface, configType string, field string) error { + secretName := fmt.Sprintf("%s-%s", strings.ToLower(configType), strings.ToLower(field)) + return secrets.DeleteNamespaced(SecretsNamespace, secretName, &metav1.DeleteOptions{}) +} + +// SavePasswordSecret creates a secret out of a password, config type, and field name. +func SavePasswordSecret(secrets corev1.SecretInterface, password string, fieldName string, authType string) (string, error) { + return CreateOrUpdateSecrets(secrets, password, strings.ToLower(fieldName), strings.ToLower(authType)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password_test.go new file mode 100644 index 0000000..43a94dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/password_test.go @@ -0,0 +1,121 @@ +package common + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + + clientv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + fake1 "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" +) + +const ( + appSecretKey = "applicationSecret" + appSecretValue = "superSecret" +) + +type testPair struct { + in string + out string +} + +var tests = []testPair{ + {in: "potato", out: "potato"}, + {in: SecretsNamespace + "-foo", out: SecretsNamespace + "-foo"}, + {in: SecretsNamespace + ":bar", out: appSecretValue}, + {in: "bad:thing", out: "bad:thing"}, +} + +func TestReadFromSecret(t *testing.T) { + secretInterface := fake1.SecretInterfaceMock{ + GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + s := corev1.Secret{ + Data: make(map[string][]byte), + } + if name == "bar" { + s.Data[appSecretKey] = []byte(appSecretValue) + return &s, nil + } + return nil, errors.New("secret not found") + }, + } + + for _, pair := range tests { + info, err := ReadFromSecret(&secretInterface, pair.in, appSecretKey) + assert.Nil(t, err) + assert.Equal(t, pair.out, info) + } +} + +func TestNameForSecret(t *testing.T) { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "shibbolethconfig-serviceaccountpassword", + Namespace: "cattle-global-data", + }, + StringData: map[string]string{ + "serviceaccountpassword": "test-password", + }, + Type: corev1.SecretTypeOpaque, + } + + want := "cattle-global-data:shibbolethconfig-serviceaccountpassword" + if n := NameForSecret(secret); n != want { + t.Errorf("NameForSecret() got %s, want t%s", n, want) + } +} + +func TestSavePasswordSecret(t *testing.T) { + secrets := &secretFake{} + secretInterface := newSecretInterfaceMock(secrets) + + name, err := SavePasswordSecret(secretInterface, "test-password", + clientv3.LdapConfigFieldServiceAccountPassword, + "shibbolethConfig") + assert.NoError(t, err) + + wantSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "shibbolethconfig-serviceaccountpassword", + Namespace: "cattle-global-data", + }, + StringData: map[string]string{ + "serviceaccountpassword": "test-password", + }, + Type: corev1.SecretTypeOpaque, + } + assert.Equal(t, []*corev1.Secret{wantSecret}, secrets.Created) + assert.Equal(t, wantSecret.Namespace+":"+wantSecret.Name, name) +} + +type secretFake struct { + Created []*corev1.Secret +} + +func newSecretInterfaceMock(secrets *secretFake) v1.SecretInterface { + controller := &fakes.SecretControllerMock{ + ListerFunc: func() v1.SecretLister { + return &fakes.SecretListerMock{ + GetFunc: func(ns string, name string) (*corev1.Secret, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }, + } + }, + } + return &fakes.SecretInterfaceMock{ + ControllerFunc: func() v1.SecretController { + return controller + }, + CreateFunc: func(in1 *corev1.Secret) (*v1.Secret, error) { + secrets.Created = append(secrets.Created, in1) + return in1, nil + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider.go new file mode 100644 index 0000000..9c4b5e5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider.go @@ -0,0 +1,26 @@ +package common + +import ( + "context" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +const ( + UserAttributePrincipalID = "principalid" + UserAttributeUserName = "username" +) + +type AuthProvider interface { + GetName() string + AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) + SearchPrincipals(name, principalType string, myToken v3.Token) ([]v3.Principal, error) + GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) + CustomizeSchema(schema *types.Schema) + TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) + RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) + CanAccessWithGroupProviders(userPrincipalID string, groups []v3.Principal) (bool, error) + GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string + IsDisabledProvider() (bool, error) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util.go new file mode 100644 index 0000000..b7573d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util.go @@ -0,0 +1,46 @@ +package common + +import ( + "fmt" + "reflect" + "time" + + "github.com/mitchellh/mapstructure" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Decode will decode to the output structure by creating a custom decoder +// that uses the stringToK8sTimeHookFunc to handle the metav1.Time field properly. +func Decode(input, output any) error { + decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + DecodeHook: stringToK8sTimeHookFunc(), + Result: output, + }) + if err != nil { + return fmt.Errorf("unable to create decoder for Config: %w", err) + } + err = decoder.Decode(input) + if err != nil { + return fmt.Errorf("unable to decode Config: %w", err) + } + return nil +} + +// stringToTimeHookFunc returns a DecodeHookFunc that converts strings to metav1.Time. +func stringToK8sTimeHookFunc() mapstructure.DecodeHookFunc { + return func( + f reflect.Type, + t reflect.Type, + data interface{}) (interface{}, error) { + if f.Kind() != reflect.String { + return data, nil + } + if t != reflect.TypeOf(metav1.Time{}) { + return data, nil + } + + // Convert it by parsing + stdTime, err := time.Parse(time.RFC3339, data.(string)) + return metav1.Time{Time: stdTime}, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util_test.go new file mode 100644 index 0000000..70edc2b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/provider_util_test.go @@ -0,0 +1,74 @@ +package common_test + +import ( + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "testing" + "time" +) + +func TestDecode(t *testing.T) { + t.Parallel() + tests := []struct { + name string + input any + output any + wantErr bool + }{ + { + name: "successful decode", + input: getMockAuthConfig(), + output: &apimgmtv3.AuthConfig{}, + wantErr: false, + }, + { + name: "unsuccessful decoder create", + input: getMockAuthConfig(), + output: apimgmtv3.AuthConfig{}, + wantErr: true, + }, + { + name: "unsuccessful decode", + input: "bogus input", + output: &apimgmtv3.AuthConfig{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := common.Decode(tt.input, tt.output) + assert.Equal(t, err != nil, tt.wantErr) + if !tt.wantErr { + inputMap, _ := tt.input.(map[string]interface{}) + inputMeta, _ := inputMap["metadata"].(map[string]interface{}) + outputConfig, _ := tt.output.(*apimgmtv3.AuthConfig) + // Spot check some fields, creationtimestamp is critical though as it's the + // main reason we are using a customized decoder. + assert.Equal(t, inputMap["kind"], outputConfig.Kind) + assert.Equal(t, inputMap["enabled"], outputConfig.Enabled) + assert.Equal(t, inputMeta["creationtimestamp"], outputConfig.ObjectMeta.CreationTimestamp) + } + }) + } +} + +func getMockAuthConfig() map[string]any { + timeStamp, _ := time.Parse(time.RFC3339, "2023-05-15T19:28:22Z") + createdTime := metav1.NewTime(timeStamp) + return map[string]any{ + "metadata": map[string]any{ + "name": saml.ShibbolethName, + "creationtimestamp": createdTime, + }, + "kind": "AuthConfig", + "apiVersion": "management.cattle.io/v3", + "type": "shibbolethConfig", + "enabled": true, + "openLdapConfig": map[string]any{ + "serviceAccountPassword": "testpass1234", + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/transformer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/transformer.go new file mode 100644 index 0000000..19635db --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/transformer.go @@ -0,0 +1,20 @@ +package common + +import "strings" + +func TransformToAuthProvider(authConfig map[string]interface{}) map[string]interface{} { + result := map[string]interface{}{} + + metadata, ok := authConfig["metadata"].(map[string]interface{}) + if ok { + if name, found := metadata["name"]; found { + result["id"] = name + } + } + + if t, _ := authConfig["type"].(string); t != "" { + result["type"] = strings.Replace(t, "Config", "Provider", -1) + } + + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/usermanager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/usermanager.go new file mode 100644 index 0000000..c92fae2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/common/usermanager.go @@ -0,0 +1,822 @@ +package common + +import ( + "crypto/sha256" + "encoding/base32" + "encoding/json" + "fmt" + "reflect" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/auth/tokens" + tokenUtil "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + k8srbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + apitypes "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" +) + +const ( + userAuthHeader = "Impersonate-User" + userByPrincipalIndex = "auth.management.cattle.io/userByPrincipal" + crtbsByPrincipalAndUserIndex = "auth.management.cattle.io/crtbByPrincipalAndUser" + prtbsByPrincipalAndUserIndex = "auth.management.cattle.io/prtbByPrincipalAndUser" + grbByUserIndex = "auth.management.cattle.io/grbByUser" + roleTemplatesRequired = "authz.management.cattle.io/creator-role-bindings" +) + +func NewUserManagerNoBindings(scaledContext *config.ScaledContext) (user.Manager, error) { + userInformer := scaledContext.Management.Users("").Controller().Informer() + userIndexers := map[string]cache.IndexFunc{ + userByPrincipalIndex: userByPrincipal, + } + if err := userInformer.AddIndexers(userIndexers); err != nil { + return nil, err + } + + return &userManager{ + users: scaledContext.Management.Users(""), + userIndexer: userInformer.GetIndexer(), + tokens: scaledContext.Management.Tokens(""), + tokenLister: scaledContext.Management.Tokens("").Controller().Lister(), + rbacClient: scaledContext.RBAC, + }, nil +} + +var backoff = wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 7, +} + +func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { + userInformer := scaledContext.Management.Users("").Controller().Informer() + userIndexers := map[string]cache.IndexFunc{ + userByPrincipalIndex: userByPrincipal, + } + if err := userInformer.AddIndexers(userIndexers); err != nil { + return nil, err + } + + crtbInformer := scaledContext.Management.ClusterRoleTemplateBindings("").Controller().Informer() + crtbIndexers := map[string]cache.IndexFunc{ + crtbsByPrincipalAndUserIndex: crtbsByPrincipalAndUser, + } + if err := crtbInformer.AddIndexers(crtbIndexers); err != nil { + return nil, err + } + + prtbInformer := scaledContext.Management.ProjectRoleTemplateBindings("").Controller().Informer() + prtbIndexers := map[string]cache.IndexFunc{ + prtbsByPrincipalAndUserIndex: prtbsByPrincipalAndUser, + } + if err := prtbInformer.AddIndexers(prtbIndexers); err != nil { + return nil, err + } + + grbInformer := scaledContext.Management.GlobalRoleBindings("").Controller().Informer() + grbIndexers := map[string]cache.IndexFunc{ + grbByUserIndex: grbByUser, + } + if err := grbInformer.AddIndexers(grbIndexers); err != nil { + return nil, err + } + + return &userManager{ + manageBindings: true, + users: scaledContext.Management.Users(""), + userIndexer: userInformer.GetIndexer(), + crtbIndexer: crtbInformer.GetIndexer(), + prtbIndexer: prtbInformer.GetIndexer(), + tokens: scaledContext.Management.Tokens(""), + tokenLister: scaledContext.Management.Tokens("").Controller().Lister(), + globalRoleBindings: scaledContext.Management.GlobalRoleBindings(""), + globalRoleLister: scaledContext.Management.GlobalRoles("").Controller().Lister(), + grbIndexer: grbInformer.GetIndexer(), + clusterRoleLister: scaledContext.RBAC.ClusterRoles("").Controller().Lister(), + clusterRoleBindingLister: scaledContext.RBAC.ClusterRoleBindings("").Controller().Lister(), + rbacClient: scaledContext.RBAC, + }, nil +} + +type userManager struct { + // manageBinding means whether or not we gr, grb, crtb, and prtb exist in the cluster + manageBindings bool + users v3.UserInterface + globalRoleBindings v3.GlobalRoleBindingInterface + globalRoleLister v3.GlobalRoleLister + grbIndexer cache.Indexer + userIndexer cache.Indexer + crtbIndexer cache.Indexer + prtbIndexer cache.Indexer + tokenLister v3.TokenLister + tokens v3.TokenInterface + clusterRoleLister rbacv1.ClusterRoleLister + clusterRoleBindingLister rbacv1.ClusterRoleBindingLister + rbacClient rbacv1.Interface +} + +func (m *userManager) SetPrincipalOnCurrentUser(apiContext *types.APIContext, principal v3.Principal) (*v3.User, error) { + userID := m.GetUser(apiContext) + if userID == "" { + return nil, errors.New("user not provided") + } + + return m.SetPrincipalOnCurrentUserByUserID(userID, principal) +} + +func (m *userManager) SetPrincipalOnCurrentUserByUserID(userID string, principal v3.Principal) (*v3.User, error) { + user, err := m.users.Get(userID, v1.GetOptions{}) + if err != nil { + return nil, err + } + + // ensure this principal is unique to this user + if conflict, err := m.GetUserByPrincipalID(principal.Name); err != nil { + return nil, err + } else if conflict != nil && conflict.UID != user.UID { + logrus.Errorf("refusing to set principal [%s] on user [%s], principal already in use on user [%s]", principal.Name, user.DisplayName, conflict.DisplayName) + return user, errors.New("refusing to set principal on user that is already bound to another user") + } + + if providerExists(user.PrincipalIDs, principal.Provider) { + var principalIDs []string + for _, id := range user.PrincipalIDs { + if !strings.Contains(id, principal.Provider) { + principalIDs = append(principalIDs, id) + } + } + user.PrincipalIDs = principalIDs + } + + if !slice.ContainsString(user.PrincipalIDs, principal.Name) { + user.PrincipalIDs = append(user.PrincipalIDs, principal.Name) + logrus.Infof("Updating user %v. Adding principal", user.Name) + return m.users.Update(user) + } + return user, nil +} + +func (m *userManager) GetUser(apiContext *types.APIContext) string { + return apiContext.Request.Header.Get(userAuthHeader) +} + +// checkis if the supplied principal can login based on the accessMode and allowed principals +func (m *userManager) CheckAccess(accessMode string, allowedPrincipalIDs []string, userPrincipalID string, groups []v3.Principal) (bool, error) { + if accessMode == "unrestricted" || accessMode == "" { + return true, nil + } + + if accessMode == "required" || accessMode == "restricted" { + user, err := m.checkCache(userPrincipalID) + if err != nil { + return false, err + } + + userPrincipals := []string{userPrincipalID} + if user != nil { + for _, p := range user.PrincipalIDs { + if userPrincipalID != p { + userPrincipals = append(userPrincipals, p) + } + } + } + + for _, p := range userPrincipals { + if slice.ContainsString(allowedPrincipalIDs, p) { + return true, nil + } + } + + for _, g := range groups { + if slice.ContainsString(allowedPrincipalIDs, g.Name) { + return true, nil + } + } + + if accessMode == "restricted" { + // check if any of the user's principals are in a project or cluster + var userNameAndPrincipals []string + for _, g := range groups { + userNameAndPrincipals = append(userNameAndPrincipals, g.Name) + } + if user != nil { + userNameAndPrincipals = append(userNameAndPrincipals, user.Name) + userNameAndPrincipals = append(userNameAndPrincipals, userPrincipals...) + } + + return m.userExistsInClusterOrProject(userNameAndPrincipals) + } + return false, nil + } + return false, errors.Errorf("Unsupported accessMode: %v", accessMode) +} + +// creates tokens with 0 ttl and returns token in 'token.Name:token.Token' format +func (m *userManager) EnsureToken(input user.TokenInput) (string, error) { + return m.EnsureClusterToken("", input) +} + +func (m *userManager) EnsureClusterToken(clusterName string, input user.TokenInput) (string, error) { + if strings.HasPrefix(input.TokenName, "token-") { + return "", errors.New("token names can't start with token-") + } + + var err error + var token *v3.Token + if !input.Randomize { + token, err = m.tokenLister.Get("", input.TokenName) + if err != nil && !apierrors.IsNotFound(err) { + return "", err + } + if err == nil { + if err := m.tokens.Delete(token.Name, &v1.DeleteOptions{}); err != nil { + return "", err + } + } + } + + key, err := randomtoken.Generate() + if err != nil { + return "", errors.New("failed to generate token key") + } + + token = &v3.Token{ + ObjectMeta: v1.ObjectMeta{ + Name: input.TokenName, + Labels: map[string]string{ + tokens.UserIDLabel: input.UserName, + tokens.TokenKindLabel: input.Kind, + }, + }, + TTLMillis: 0, + Description: input.Description, + UserID: input.UserName, + AuthProvider: input.AuthProvider, + UserPrincipal: input.UserPrincipal, + IsDerived: true, + Token: key, + ClusterName: clusterName, + } + if input.TTL != nil { + token.TTLMillis = *input.TTL + } + if input.Randomize { + token.ObjectMeta.Name = "" + token.ObjectMeta.GenerateName = input.TokenName + } + err = tokens.ConvertTokenKeyToHash(token) + if err != nil { + return "", err + } + + logrus.Infof("Creating token for user %v", input.UserName) + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + // Backoff was added here because it is possible the token is in the process of deleting. + // This should cause the create to retry until the delete is finished. + newToken, err := m.tokens.Create(token) + if err != nil { + if apierrors.IsAlreadyExists(err) { + return false, nil + } + return false, err + } + token = newToken + return true, nil + }) + if err != nil { + return "", err + } + + return token.Name + ":" + key, nil +} + +// newTokenForKubeconfig creates a new token for a generated kubeconfig. +func (m *userManager) newTokenForKubeconfig(clusterName, tokenName, description, kind, userName string, userPrincipal v3.Principal) (string, error) { + tokenTTL, err := tokens.GetKubeconfigDefaultTokenTTLInMilliSeconds() + if err != nil { + return "", fmt.Errorf("failed to get default token TTL: %w", err) + } + + input := user.TokenInput{ + TokenName: tokenName, + Description: description, + Kind: kind, + UserName: userName, + AuthProvider: userPrincipal.Provider, + TTL: tokenTTL, + Randomize: true, + UserPrincipal: userPrincipal, + } + + return m.EnsureClusterToken(clusterName, input) +} + +// GetKubeconfigToken creates a new token for use in a kubeconfig generated through the CLI. +func (m *userManager) GetKubeconfigToken(clusterName, tokenName, description, kind, userName string, userPrincipal v3.Principal) (*v3.Token, string, error) { + fullCreatedToken, err := m.newTokenForKubeconfig(clusterName, tokenName, description, kind, userName, userPrincipal) + if err != nil { + return nil, "", err + } + + randomizedTokenName, createdTokenValue := tokens.SplitTokenParts(fullCreatedToken) + token, err := m.tokens.Get(randomizedTokenName, v1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return nil, createdTokenValue, err + } + + if token.ExpiresAt != "" { + return token, createdTokenValue, nil + } + + // SetTokenExpiresAt requires creationTS, so can only be set post create + tokenCopy := token.DeepCopy() + tokenUtil.SetTokenExpiresAt(tokenCopy) + + token, err = m.tokens.Update(tokenCopy) + if err != nil { + if !apierrors.IsConflict(err) { + return nil, "", fmt.Errorf("getToken: updating token [%s] failed [%v]", randomizedTokenName, err) + } + + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + token, err = m.tokens.Get(randomizedTokenName, v1.GetOptions{}) + if err != nil { + return false, err + } + + if token.ExpiresAt == "" { + tokenCopy := token.DeepCopy() + tokenUtil.SetTokenExpiresAt(tokenCopy) + + token, err = m.tokens.Update(tokenCopy) + if err != nil { + logrus.Debugf("getToken: updating token [%s] failed [%v]", randomizedTokenName, err) + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + } + return true, nil + }) + + if err != nil { + return nil, "", fmt.Errorf("getToken: retry updating token [%s] failed [%v]", randomizedTokenName, err) + } + } + + logrus.Debugf("getToken: token %s expiresAt %s", token.Name, token.ExpiresAt) + return token, createdTokenValue, nil +} + +func (m *userManager) EnsureUser(principalName, displayName string) (*v3.User, error) { + var user *v3.User + var err error + var labelSet labels.Set + + // First check the local cache + user, err = m.checkCache(principalName) + if err != nil { + return nil, err + } + + if user == nil { + // Not in cache, query API by label + user, labelSet, err = m.checkLabels(principalName) + if err != nil { + return nil, err + } + } + + if user != nil { + if displayName != "" && user.DisplayName == "" { + user.DisplayName = displayName + if _, err := m.users.Update(user); err != nil { + return nil, err + } + } + + // If the user does not have the annotation it indicates the user was created + // through the UI or from a previous rancher version so don't add the + // default bindings. + if _, ok := user.Annotations[roleTemplatesRequired]; !ok { + return user, nil + } + + if v32.UserConditionInitialRolesPopulated.IsTrue(user) { + // The users global role bindings were already created. They can differ + // from what is in the annotation if they were updated manually. + return user, nil + } + } else { + // User doesn't exist, create user + logrus.Infof("Creating user for principal %v", principalName) + + // Create a hash of the principalName to use as the name for the user, + // this lets k8s tell us if there are duplicate users with the same name + // thus avoiding a race. + hasher := sha256.New() + hasher.Write([]byte(principalName)) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + + annotations, err := m.createUsersRoleAnnotation() + if err != nil { + return nil, err + } + + user = &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "u-" + strings.ToLower(sha), + Labels: labelSet, + Annotations: annotations, + }, + DisplayName: displayName, + PrincipalIDs: []string{principalName}, + } + + user, err = m.users.Create(user) + if err != nil { + return nil, err + } + + err = m.CreateNewUserClusterRoleBinding(user.Name, user.UID) + if err != nil { + return nil, err + } + } + + logrus.Infof("Creating globalRoleBindings for %v", user.Name) + err = m.createUsersBindings(user) + if err != nil { + return nil, err + } + + return user, nil +} + +func (m *userManager) CreateNewUserClusterRoleBinding(userName string, userUID apitypes.UID) error { + if !m.manageBindings { + return nil + } + + roleName := userName + "-view" + bindingName := "grb-" + roleName + + ownerReference := v1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "User", + Name: userName, + UID: userUID, + } + + cr, err := m.clusterRoleLister.Get("", roleName) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + // ClusterRole doesn't exist yet, create it. + rule := k8srbacv1.PolicyRule{ + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"users"}, + ResourceNames: []string{userName}, + } + role := &k8srbacv1.ClusterRole{ + ObjectMeta: v1.ObjectMeta{ + Name: roleName, + OwnerReferences: []v1.OwnerReference{ownerReference}, + }, + Rules: []k8srbacv1.PolicyRule{rule}, + } + + cr, err = m.rbacClient.ClusterRoles("").Create(role) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return err + } + } + } + + _, err = m.clusterRoleBindingLister.Get("", bindingName) + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + // ClusterRoleBinding doesn't exit yet, create it. + crb := &k8srbacv1.ClusterRoleBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: bindingName, + OwnerReferences: []v1.OwnerReference{ownerReference}, + }, + Subjects: []k8srbacv1.Subject{ + k8srbacv1.Subject{ + Kind: "User", + Name: userName, + }, + }, + RoleRef: k8srbacv1.RoleRef{ + Kind: "ClusterRole", + Name: cr.Name, + }, + } + _, err = m.rbacClient.ClusterRoleBindings("").Create(crb) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return err + } + } + } + + return nil +} + +func (m *userManager) createUsersBindings(user *v3.User) error { + if !m.manageBindings { + return nil + } + + roleMap := make(map[string][]string) + err := json.Unmarshal([]byte(user.Annotations[roleTemplatesRequired]), &roleMap) + if err != nil { + return err + } + + // Collect the users existing globalRoleBindings + var existingGRB []string + grbs, err := m.grbIndexer.ByIndex(grbByUserIndex, user.Name) + if err != nil { + return err + } + + for _, grb := range grbs { + binding, ok := grb.(*v3.GlobalRoleBinding) + if !ok { + continue + } + existingGRB = append(existingGRB, binding.GlobalRoleName) + } + + var createdRoles []string + for _, role := range roleMap["required"] { + if !slice.ContainsString(existingGRB, role) { + _, err := m.globalRoleBindings.Create(&v3.GlobalRoleBinding{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "grb-", + }, + UserName: user.Name, + GlobalRoleName: role, + }) + + if err != nil { + return err + } + } + createdRoles = append(createdRoles, role) + } + + roleMap["created"] = createdRoles + d, err := json.Marshal(roleMap) + if err != nil { + return err + } + + rtr := string(d) + + sleepTime := 100 + // The user needs updated so keep trying if there is a conflict + for i := 0; i <= 3; i++ { + user, err = m.users.Get(user.Name, v1.GetOptions{}) + if err != nil { + return err + } + + user.Annotations[roleTemplatesRequired] = rtr + + if reflect.DeepEqual(roleMap["required"], createdRoles) { + v32.UserConditionInitialRolesPopulated.True(user) + } + + _, err = m.users.Update(user) + if err != nil { + if apierrors.IsConflict(err) { + // Conflict on the user, sleep and try again + time.Sleep(time.Duration(sleepTime) * time.Millisecond) + sleepTime *= 2 + continue + } + return err + } + break + } + + return nil +} + +func (m *userManager) createUsersRoleAnnotation() (map[string]string, error) { + if !m.manageBindings { + return nil, nil + } + + roleMap := make(map[string][]string) + + roles, err := m.globalRoleLister.List("", labels.NewSelector()) + if err != nil { + return nil, err + } + + for _, gr := range roles { + if gr.NewUserDefault { + roleMap["required"] = append(roleMap["required"], gr.Name) + } + } + + d, err := json.Marshal(roleMap) + if err != nil { + return nil, err + } + + annotations := make(map[string]string) + annotations[roleTemplatesRequired] = string(d) + + return annotations, nil +} + +func (m *userManager) GetUserByPrincipalID(principalName string) (*v3.User, error) { + user, err := m.checkCache(principalName) + if err != nil { + return nil, err + } + if user == nil { + // Not in cache, query API by label + user, _, err = m.checkLabels(principalName) + if err != nil { + return nil, err + } + } + return user, nil +} + +func (m *userManager) DeleteToken(tokenName string) error { + return m.tokens.Delete(tokenName, &v1.DeleteOptions{}) +} + +func (m *userManager) checkCache(principalName string) (*v3.User, error) { + users, err := m.userIndexer.ByIndex(userByPrincipalIndex, principalName) + if err != nil { + return nil, err + } + if len(users) > 1 { + return nil, errors.Errorf("can't find unique user for principal %v", principalName) + } + if len(users) == 1 { + u := users[0].(*v3.User) + return u.DeepCopy(), nil + } + return nil, nil +} + +func (m *userManager) userExistsInClusterOrProject(userNameAndPrincipals []string) (bool, error) { + if !m.manageBindings { + return false, nil + } + + for _, principal := range userNameAndPrincipals { + crtbs, err := m.crtbIndexer.ByIndex(crtbsByPrincipalAndUserIndex, principal) + if err != nil { + return false, err + } + if len(crtbs) > 0 { + return true, nil + } + prtbs, err := m.prtbIndexer.ByIndex(prtbsByPrincipalAndUserIndex, principal) + if err != nil { + return false, err + } + if len(prtbs) > 0 { + return true, nil + } + } + + return false, nil +} + +func (m *userManager) checkLabels(principalName string) (*v3.User, labels.Set, error) { + encodedPrincipalID := base32.HexEncoding.WithPadding(base32.NoPadding).EncodeToString([]byte(principalName)) + if len(encodedPrincipalID) > 63 { + encodedPrincipalID = encodedPrincipalID[:63] + } + set := labels.Set(map[string]string{encodedPrincipalID: "hashed-principal-name"}) + users, err := m.users.List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return nil, nil, err + } + + if len(users.Items) == 0 { + return nil, set, nil + } + + var match *v3.User + for _, u := range users.Items { + if slice.ContainsString(u.PrincipalIDs, principalName) { + if match != nil { + // error out on duplicates + return nil, nil, errors.Errorf("can't find unique user for principal %v", principalName) + } + match = &u + } + } + + return match, set, nil +} + +func userByPrincipal(obj interface{}) ([]string, error) { + u, ok := obj.(*v3.User) + if !ok { + return []string{}, nil + } + + match := false + for _, id := range u.PrincipalIDs { + if strings.HasPrefix(id, "local://") { + match = true + break + } + } + + if match { + return u.PrincipalIDs, nil + } + return append(u.PrincipalIDs, "local://"+u.Name), nil +} + +func crtbsByPrincipalAndUser(obj interface{}) ([]string, error) { + var principals []string + b, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok { + return []string{}, nil + } + if b.GroupPrincipalName != "" { + principals = append(principals, b.GroupPrincipalName) + } + if b.UserPrincipalName != "" { + principals = append(principals, b.UserPrincipalName) + } + if b.UserName != "" { + principals = append(principals, b.UserName) + } + return principals, nil +} + +func prtbsByPrincipalAndUser(obj interface{}) ([]string, error) { + var principals []string + b, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + if b.GroupPrincipalName != "" { + principals = append(principals, b.GroupPrincipalName) + } + if b.UserPrincipalName != "" { + principals = append(principals, b.UserPrincipalName) + } + if b.UserName != "" { + principals = append(principals, b.UserName) + } + return principals, nil +} + +func grbByUser(obj interface{}) ([]string, error) { + grb, ok := obj.(*v3.GlobalRoleBinding) + if !ok { + return []string{}, nil + } + + return []string{grb.UserName}, nil +} + +func providerExists(principalIDs []string, provider string) bool { + for _, id := range principalIDs { + splitID := strings.Split(id, ":")[0] + if strings.Contains(splitID, provider) { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider.go new file mode 100644 index 0000000..d97850b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider.go @@ -0,0 +1,175 @@ +package genericoidc + +import ( + "context" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/auth/providers/common" + baseoidc "github.com/rancher/rancher/pkg/auth/providers/oidc" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type GenOIDCProvider struct { + baseoidc.OpenIDCProvider +} + +const ( + Name = "genericoidc" + UserType = "user" + GroupType = "group" +) + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + return &GenOIDCProvider{ + baseoidc.OpenIDCProvider{ + Name: Name, + Type: client.GenericOIDCConfigType, + CTX: ctx, + AuthConfigs: mgmtCtx.Management.AuthConfigs(""), + Secrets: mgmtCtx.Core.Secrets(""), + UserMGR: userMGR, + TokenMGR: tokenMGR, + }, + } +} + +// GetName returns the name of this provider. +func (g *GenOIDCProvider) GetName() string { + return Name +} + +// SearchPrincipals will return a principal of the requested principalType with a displayName +// that matches the searchValue. If principalType is empty, both a user principal and a group principal will +// be returned. This is done because OIDC does not have a proper lookup mechanism. In order +// to provide some degree of functionality that allows manual entry for users/groups, this is the compromise. +func (g *GenOIDCProvider) SearchPrincipals(searchValue, principalType string, _ v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + + if principalType != GroupType { + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: g.Name + "_" + UserType + "://" + searchValue}, + DisplayName: searchValue, + LoginName: searchValue, + PrincipalType: UserType, + Provider: g.Name, + } + principals = append(principals, p) + } + + if principalType != UserType { + gp := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: g.Name + "_" + GroupType + "://" + searchValue}, + DisplayName: searchValue, + PrincipalType: GroupType, + Provider: g.Name, + } + principals = append(principals, gp) + } + return principals, nil +} + +func (g *GenOIDCProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + var p v3.Principal + + // parsing id to get the external id and type. Example genericoidc_:// + principalScheme, externalID, found := strings.Cut(principalID, "://") + if !found { + return p, fmt.Errorf("invalid principal id: %s", principalID) + } + provider, principalType, found := strings.Cut(principalScheme, "_") + if !found { + return p, fmt.Errorf("invalid principal scheme: %s", principalScheme) + } + + if externalID == "" && principalType == "" { + return p, fmt.Errorf("invalid id %v", principalID) + } + if principalType != UserType && principalType != GroupType { + return p, fmt.Errorf("invalid principal type: %s", principalType) + } + if principalType == UserType { + p = v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: provider + "_" + principalType + "://" + externalID}, + DisplayName: externalID, + LoginName: externalID, + PrincipalType: UserType, + Provider: g.Name, + } + } else { + p = g.groupToPrincipal(externalID) + } + p = g.toPrincipalFromToken(principalType, p, &token) + return p, nil +} + +// TransformToAuthProvider yields information used, typically by the UI, to be able to form URLs used to perform login. +func (g *GenOIDCProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + p[publicclient.GenericOIDCProviderFieldRedirectURL] = g.getRedirectURL(authConfig) + p[publicclient.GenericOIDCProviderFieldScopes] = authConfig["scope"] + return p, nil +} + +// RefetchGroupPrincipals is not implemented for OIDC. +func (g *GenOIDCProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + return nil, errors.New("Not implemented") +} + +// groupToPrincipal takes a bare group name and turns it into a v3.Principal group object by filling-in other fields +// with basic provider information. +func (g *GenOIDCProvider) groupToPrincipal(groupName string) v3.Principal { + return v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: g.Name + "_" + GroupType + "://" + groupName}, + DisplayName: groupName, + Provider: g.Name, + PrincipalType: GroupType, + Me: false, + } +} + +// getRedirectURL uses the AuthConfig map to build-up the redirect URL passed to the OIDC provider at login-time. +func (g *GenOIDCProvider) getRedirectURL(config map[string]interface{}) string { + authURL, _ := baseoidc.FetchAuthURL(config) + + redirectURL := fmt.Sprintf( + "%s?client_id=%s&response_type=code&redirect_uri=%s", + authURL, + config["clientId"], + config["rancherUrl"], + ) + + if config["acrValue"] != nil { + redirectURL += fmt.Sprintf("&acr_values=%s", config["acrValue"]) + } + + return redirectURL +} + +// toPrincipalFromToken uses additional information about the principal found in the token, if available, to provide +// a more detailed, useful Principal object. +func (g *GenOIDCProvider) toPrincipalFromToken(principalType string, princ v3.Principal, token *v3.Token) v3.Principal { + if principalType == UserType { + princ.PrincipalType = UserType + if token != nil { + princ.Me = g.IsThisUserMe(token.UserPrincipal, princ) + if princ.Me { + princ.LoginName = token.UserPrincipal.LoginName + princ.DisplayName = token.UserPrincipal.DisplayName + } + } + } else { + princ.PrincipalType = GroupType + if token != nil { + princ.MemberOf = g.TokenMGR.IsMemberOf(*token, princ) + } + } + return princ +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider_test.go new file mode 100644 index 0000000..b74e79a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/genericoidc/genericoidc_provider_test.go @@ -0,0 +1,263 @@ +package genericoidc + +import ( + "reflect" + "testing" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/oidc" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGenOIDCProvider_GetPrincipal(t *testing.T) { + tests := []struct { + name string + principalID string + token v3.Token + want v3.Principal + wantErr bool + }{ + { + name: "fetch principal for current user", + principalID: "genericoidc_user://1234567", + token: v3.Token{ + UserPrincipal: apimgmtv3.Principal{ + ObjectMeta: metav1.ObjectMeta{ + Name: "genericoidc_user://1234567", + }, + DisplayName: "Test User", + LoginName: "1234567", + PrincipalType: "user", + Me: true, + }, + }, + want: v3.Principal{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: "genericoidc_user://1234567", + }, + DisplayName: "Test User", + LoginName: "1234567", + PrincipalType: "user", + Me: true, + Provider: Name, + }, + wantErr: false, + }, + { + name: "fetch principal for user other than self", + principalID: "genericoidc_user://9876543", + token: v3.Token{ + UserPrincipal: apimgmtv3.Principal{ + ObjectMeta: metav1.ObjectMeta{ + Name: "genericoidc_user://1234567", + }, + DisplayName: "Test User", + LoginName: "1234567", + PrincipalType: "user", + Me: false, + }, + }, + want: v3.Principal{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: "genericoidc_user://9876543", + }, + DisplayName: "9876543", + LoginName: "9876543", + PrincipalType: "user", + Me: false, + Provider: Name, + }, + wantErr: false, + }, + { + name: "fetch principal token is nil", + principalID: "genericoidc_user://9876543", + want: v3.Principal{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: "genericoidc_user://9876543", + }, + DisplayName: "9876543", + LoginName: "9876543", + PrincipalType: "user", + Me: false, + Provider: Name, + }, + wantErr: false, + }, + { + name: "fetch principal called with empty principal", + principalID: "", + want: v3.Principal{}, + wantErr: true, + }, + } + for _, test := range tests { + test := test + g := &GenOIDCProvider{ + oidc.OpenIDCProvider{ + Name: Name, + Type: client.GenericOIDCConfigType, + }, + } + t.Run(test.name, func(t *testing.T) { + t.Parallel() + got, err := g.GetPrincipal(test.principalID, test.token) + if (err != nil) != test.wantErr { + t.Errorf("GetPrincipal() error = %v, wantErr %v", err, test.wantErr) + return + } + if !reflect.DeepEqual(got, test.want) { + t.Errorf("GetPrincipal() got = %v, want %v", got, test.want) + } + }) + } +} + +func TestGenOIDCProvider_SearchPrincipals(t *testing.T) { + tests := []struct { + name string + searchValue string + principalType string + expected []v3.Principal + }{ + { + name: "test search for user principal", + searchValue: "user1", + principalType: UserType, + expected: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_user://user1"}, + DisplayName: "user1", + LoginName: "user1", + PrincipalType: UserType, + Provider: Name, + }, + }, + }, + { + name: "test search for user principal with empty principaltype", + searchValue: "user1", + expected: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_user://user1"}, + DisplayName: "user1", + LoginName: "user1", + PrincipalType: UserType, + Provider: Name, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_group://user1"}, + DisplayName: "user1", + PrincipalType: GroupType, + Provider: Name, + }, + }, + }, + { + name: "test search for user principal with empty principaltype and searchval", + expected: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_user://"}, + PrincipalType: UserType, + Provider: Name, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_group://"}, + PrincipalType: GroupType, + Provider: Name, + }, + }, + }, + { + name: "test search for group principal", + searchValue: "group1", + principalType: GroupType, + expected: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_group://group1"}, + DisplayName: "group1", + PrincipalType: GroupType, + Provider: Name, + }, + }, + }, + { + name: "test search for group principal with empty searchval", + principalType: GroupType, + expected: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "genericoidc_group://"}, + PrincipalType: GroupType, + Provider: Name, + }, + }, + }, + } + + g := &GenOIDCProvider{ + oidc.OpenIDCProvider{ + Name: Name, + Type: client.GenericOIDCConfigType, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result, err := g.SearchPrincipals(test.searchValue, test.principalType, v3.Token{}) + if err != nil { + t.Errorf("SearchPrincipals() returned an error: %v", err) + } + + if !reflect.DeepEqual(result, test.expected) { + t.Errorf("SearchPrincipals() returned %+v, expected %+v", result, test.expected) + } + }) + } +} + +func TestGenOIDCProvider_TransformToAuthProvider(t *testing.T) { + tests := []struct { + name string + authConfig map[string]interface{} + expected map[string]interface{} + }{ + { + name: "Test with valid authConfig", + authConfig: map[string]interface{}{ + "clientId": "client123", + "rancherUrl": "https://example.com/callback", + "scope": "openid profile email", + "issuer": "https://ranchertest.io/issuer", + "authEndpoint": "https://ranchertest.io/auth", + }, + expected: map[string]interface{}{ + "redirectUrl": "https://ranchertest.io/auth?client_id=client123&response_type=code&redirect_uri=https://example.com/callback", + "scopes": "openid profile email", + }, + }, + } + + provider := &GenOIDCProvider{} + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + result, err := provider.TransformToAuthProvider(test.authConfig) + if err != nil { + t.Errorf("TransformToAuthProvider() returned an error: %v", err) + } + + if !reflect.DeepEqual(result, test.expected) { + t.Errorf("TransformToAuthProvider() returned %+v, expected %+v", result, test.expected) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_account.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_account.go new file mode 100644 index 0000000..eedc75a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_account.go @@ -0,0 +1,36 @@ +package github + +import ( + "fmt" +) + +type searchResult struct { + Items []Account `json:"items"` +} + +// Account defines properties an account on github has +type Account struct { + ID int `json:"id,omitempty"` + Login string `json:"login,omitempty"` + Name string `json:"name,omitempty"` + AvatarURL string `json:"avatar_url,omitempty"` + HTMLURL string `json:"html_url,omitempty"` + Type string `json:"type,omitempty"` +} + +// Team defines properties a team on github has +type Team struct { + ID int `json:"id,omitempty"` + Organization map[string]interface{} `json:"organization,omitempty"` + Name string `json:"name,omitempty"` + Slug string `json:"slug,omitempty"` +} + +func (t *Team) toGithubAccount(url string, account *Account) { + account.ID = t.ID + account.Name = t.Name + orgLogin := (t.Organization["login"]).(string) + account.AvatarURL = t.Organization["avatar_url"].(string) + account.HTMLURL = fmt.Sprintf(url, orgLogin, t.Slug) + account.Login = t.Slug +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client.go new file mode 100644 index 0000000..d7b781f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client.go @@ -0,0 +1,428 @@ +package github + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "github.com/tomnomnom/linkheader" +) + +const ( + gheAPI = "/api/v3" + githubAPI = "https://api.github.com" + githubDefaultHostName = "https://github.com" +) + +// GClient implements a httpclient for github +type GClient struct { + httpClient *http.Client +} + +func (g *GClient) getAccessToken(code string, config *v32.GithubConfig) (string, error) { + + form := url.Values{} + form.Add("client_id", config.ClientID) + form.Add("client_secret", config.ClientSecret) + form.Add("code", code) + + url := g.getURL("TOKEN", config) + + b, err := g.postToGithub(url, form) + if err != nil { + return "", fmt.Errorf("github getAccessToken: POST url %v received error from github, err: %v", url, err) + } + + // Decode the response + var respMap map[string]interface{} + + if err := json.Unmarshal(b, &respMap); err != nil { + return "", fmt.Errorf("github getAccessToken: received error unmarshalling response body, err: %v", err) + } + + if respMap["error"] != nil { + desc := respMap["error_description"] + return "", fmt.Errorf("github getAccessToken: received error from github %v, description from github %v", respMap["error"], desc) + } + + acessToken, ok := respMap["access_token"].(string) + if !ok { + return "", fmt.Errorf("github getAccessToken: received error reading accessToken from response %v", respMap) + } + return acessToken, nil +} + +func (g *GClient) getUser(githubAccessToken string, config *v32.GithubConfig) (Account, error) { + + url := g.getURL("USER_INFO", config) + b, _, err := g.getFromGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getGithubUser: GET url %v received error from github, err: %v", url, err) + return Account{}, err + } + var githubAcct Account + + if err := json.Unmarshal(b, &githubAcct); err != nil { + logrus.Errorf("Github getGithubUser: error unmarshalling response, err: %v", err) + return Account{}, err + } + + return githubAcct, nil +} + +func (g *GClient) getOrgs(githubAccessToken string, config *v32.GithubConfig) ([]Account, error) { + var orgs []Account + + url := g.getURL("ORG_INFO", config) + responses, err := g.paginateGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getGithubOrgs: GET url %v received error from github, err: %v", url, err) + return orgs, err + } + + for _, b := range responses { + var orgObjs []Account + if err := json.Unmarshal(b, &orgObjs); err != nil { + logrus.Errorf("Github getGithubOrgs: received error unmarshalling org array, err: %v", err) + return nil, err + } + orgs = append(orgs, orgObjs...) + } + + return orgs, nil +} + +func (g *GClient) getTeams(githubAccessToken string, config *v32.GithubConfig) ([]Account, error) { + var teams []Account + + url := g.getURL("TEAMS", config) + responses, err := g.paginateGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getGithubTeams: GET url %v received error from github, err: %v", url, err) + return teams, err + } + for _, response := range responses { + teamObjs, err := g.getTeamInfo(response, config) + + if err != nil { + logrus.Errorf("Github getGithubTeams: received error unmarshalling teams array, err: %v", err) + return teams, err + } + teams = append(teams, teamObjs...) + + } + return teams, nil +} + +// getOrgTeams returns the teams belonging to an organization. +func (g *GClient) getOrgTeams(githubAccessToken string, config *v32.GithubConfig, org Account) ([]Account, error) { + url := fmt.Sprintf(g.getURL("ORG_TEAMS", config), url.PathEscape(org.Login)) + responses, err := g.paginateGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getGithubTeams: GET url %v received error from github, err: %v", url, err) + return nil, err + } + + var teams, respTeams []Account + for _, response := range responses { + respTeams, err = g.getOrgTeamInfo(response, config, org) + if err != nil { + logrus.Errorf("Github getOrgTeams: received error unmarshalling teams array, err: %v", err) + return teams, err + } + teams = append(teams, respTeams...) + } + + return teams, nil +} + +// getOrgTeamInfo is similar to getTeamInfo but takes an org as an argument. +func (g *GClient) getOrgTeamInfo(b []byte, config *v32.GithubConfig, org Account) ([]Account, error) { + var teams []Account + var teamObjs []Team + if err := json.Unmarshal(b, &teamObjs); err != nil { + logrus.Errorf("Github getTeamInfo: received error unmarshalling team array, err: %v", err) + return teams, err + } + + url := g.getURL("TEAM_PROFILE", config) + for _, team := range teamObjs { + teams = append(teams, Account{ + ID: team.ID, + Name: team.Name, + AvatarURL: org.AvatarURL, + HTMLURL: fmt.Sprintf(url, org.Login, team.Slug), + Login: team.Slug, + }) + } + + return teams, nil +} + +func (g *GClient) getTeamInfo(b []byte, config *v32.GithubConfig) ([]Account, error) { + var teams []Account + var teamObjs []Team + if err := json.Unmarshal(b, &teamObjs); err != nil { + logrus.Errorf("Github getTeamInfo: received error unmarshalling team array, err: %v", err) + return teams, err + } + + url := g.getURL("TEAM_PROFILE", config) + for _, team := range teamObjs { + teamAcct := Account{} + team.toGithubAccount(url, &teamAcct) + teams = append(teams, teamAcct) + } + + return teams, nil +} + +func (g *GClient) getTeamByID(id string, githubAccessToken string, config *v32.GithubConfig) (Account, error) { + var teamAcct Account + + url := g.getURL("TEAM", config) + id + b, _, err := g.getFromGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getTeamByID: GET url %v received error from github, err: %v", url, err) + return teamAcct, err + } + var teamObj Team + if err := json.Unmarshal(b, &teamObj); err != nil { + logrus.Errorf("Github getTeamByID: received error unmarshalling team array, err: %v", err) + return teamAcct, err + } + url = g.getURL("TEAM_PROFILE", config) + teamObj.toGithubAccount(url, &teamAcct) + + return teamAcct, nil +} + +func (g *GClient) paginateGithub(githubAccessToken string, url string) ([][]byte, error) { + var responses [][]byte + var err error + var response []byte + nextURL := url + for nextURL != "" { + response, nextURL, err = g.getFromGithub(githubAccessToken, nextURL) + if err != nil { + return nil, err + } + responses = append(responses, response) + } + + return responses, nil +} + +func (g *GClient) nextGithubPage(response *http.Response) string { + header := response.Header.Get("link") + + if header != "" { + links := linkheader.Parse(header) + for _, link := range links { + if link.Rel == "next" { + return link.URL + } + } + } + + return "" +} + +func (g *GClient) searchUsers(searchTerm, searchType string, githubAccessToken string, config *v32.GithubConfig) ([]Account, error) { + if searchType == "group" { + searchType = orgType + } + + search := searchTerm + if searchType != "" { + search += "+type:" + searchType + } + search = URLEncoded(search) + url := g.getURL("USER_SEARCH", config) + search + + b, _, err := g.getFromGithub(githubAccessToken, url) + if err != nil { + // no match on search returns an error. do not log + return nil, nil + } + + result := &searchResult{} + if err := json.Unmarshal(b, result); err != nil { + return nil, err + } + + return result.Items, nil +} + +// searchTeams searches for teams that match the search term in the organizations the access token has access to. +// At the moment it only does a case-insensitive prefix match on the team's name. +func (g *GClient) searchTeams(searchTerm, githubAccessToken string, config *v32.GithubConfig) ([]Account, error) { + orgs, err := g.getOrgs(githubAccessToken, config) + if err != nil { + return nil, err + } + + lowerSearchTerm := strings.ToLower(searchTerm) + + var matches, teams []Account + for _, org := range orgs { + teams, err = g.getOrgTeams(githubAccessToken, config, org) + if err != nil { + return nil, err + } + + for _, team := range teams { + if !strings.HasPrefix(strings.ToLower(team.Name), lowerSearchTerm) { + continue + } + + matches = append(matches, team) + } + + } + + return matches, nil +} + +func (g *GClient) getUserOrgByID(id string, githubAccessToken string, config *v32.GithubConfig) (Account, error) { + url := g.getURL("USER_INFO", config) + "/" + id + + b, _, err := g.getFromGithub(githubAccessToken, url) + if err != nil { + logrus.Errorf("Github getUserOrgById: GET url %v received error from github, err: %v", url, err) + return Account{}, err + } + var githubAcct Account + + if err := json.Unmarshal(b, &githubAcct); err != nil { + logrus.Errorf("Github getUserOrgById: error unmarshalling response, err: %v", err) + return Account{}, err + } + + return githubAcct, nil +} + +// URLEncoded encodes the string +func URLEncoded(str string) string { + u, err := url.Parse(str) + if err != nil { + logrus.Errorf("Error encoding the url: %s, error: %v", str, err) + return str + } + return u.String() +} + +func (g *GClient) postToGithub(url string, form url.Values) ([]byte, error) { + req, err := http.NewRequest("POST", url, strings.NewReader(form.Encode())) + if err != nil { + logrus.Error(err) + } + req.PostForm = form + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Accept", "application/json") + resp, err := g.httpClient.Do(req) + if err != nil { + logrus.Errorf("Received error from github: %v", err) + return nil, err + } + + defer resp.Body.Close() + // Check the status code + switch resp.StatusCode { + case 200: + case 201: + default: + var body bytes.Buffer + io.Copy(&body, resp.Body) + return nil, fmt.Errorf("request failed, got status code: %d. Response: %s", + resp.StatusCode, body.Bytes()) + } + return io.ReadAll(resp.Body) +} + +func (g *GClient) getFromGithub(githubAccessToken string, url string) ([]byte, string, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, "", err + } + req.Header.Add("Authorization", "token "+githubAccessToken) + req.Header.Add("Accept", "application/json") + req.Header.Add("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36)") + resp, err := g.httpClient.Do(req) + if err != nil { + logrus.Errorf("Received error from github: %v", err) + return nil, "", err + } + defer resp.Body.Close() + // Check the status code + switch resp.StatusCode { + case 200: + case 201: + default: + var body bytes.Buffer + io.Copy(&body, resp.Body) + return nil, "", fmt.Errorf("request failed, got status code: %d. Response: %s", + resp.StatusCode, body.Bytes()) + } + + nextURL := g.nextGithubPage(resp) + b, err := io.ReadAll(resp.Body) + return b, nextURL, err +} + +func (g *GClient) getURL(endpoint string, config *v32.GithubConfig) string { + var hostName, apiEndpoint, toReturn string + + if config.Hostname != "" { + scheme := "http://" + if config.TLS { + scheme = "https://" + } + hostName = scheme + config.Hostname + if hostName == githubDefaultHostName { + apiEndpoint = githubAPI + } else { + apiEndpoint = scheme + config.Hostname + gheAPI + } + } else { + hostName = githubDefaultHostName + apiEndpoint = githubAPI + } + + switch endpoint { + case "API": + toReturn = apiEndpoint + case "TOKEN": + toReturn = hostName + "/login/oauth/access_token" + case "USERS": + toReturn = apiEndpoint + "/users/" + case "ORGS": + toReturn = apiEndpoint + "/orgs/" + case "USER_INFO": + toReturn = apiEndpoint + "/user" + case "ORG_INFO": + toReturn = apiEndpoint + "/user/orgs?per_page=1" + case "USER_PICTURE": + toReturn = "https://avatars.githubusercontent.com/u/" + endpoint + "?v=3&s=72" + case "USER_SEARCH": + toReturn = apiEndpoint + "/search/users?q=" + case "TEAM": + toReturn = apiEndpoint + "/teams/" + case "TEAMS": + toReturn = apiEndpoint + "/user/teams?per_page=100" + case "TEAM_PROFILE": + toReturn = hostName + "/orgs/%s/teams/%s" + case "ORG_TEAMS": + toReturn = apiEndpoint + "/orgs/%s/teams?per_page=100" + default: + toReturn = apiEndpoint + } + + return toReturn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client_test.go new file mode 100644 index 0000000..9cc7011 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_client_test.go @@ -0,0 +1,146 @@ +package github + +import ( + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" +) + +func TestGitHubClientGetOrgTeams(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(` + [{ + "id": 9933605, + "name": "developers", + "slug": "developers" + }]`)) + })) + defer srv.Close() + + srvURL, err := url.Parse(srv.URL) + if err != nil { + t.Fatal(err) + } + + gcClient := &GClient{httpClient: srv.Client()} + + config := &v32.GithubConfig{ + Hostname: srvURL.Host, + } + + org := Account{ + ID: 9343010, + Login: "org", + AvatarURL: srvURL.Host + "/u/9343010/avatar", + } + teams, err := gcClient.getOrgTeams("", config, org) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, len(teams); want != got { + t.Fatalf("Expected teams %d got %d", want, got) + } + + if want, got := 9933605, teams[0].ID; want != got { + t.Errorf("Expected ID %d got %d", want, got) + } + if want, got := "developers", teams[0].Login; want != got { + t.Errorf("Expected login %s got %s", want, got) + } + if want, got := "developers", teams[0].Name; want != got { + t.Errorf("Expected name %s got %s", want, got) + } + if want, got := org.AvatarURL, teams[0].AvatarURL; want != got { + t.Errorf("Expected avatarURL %s got %s", want, got) + } + if !strings.HasSuffix(teams[0].HTMLURL, "/orgs/org/teams/developers") { + t.Errorf("Unexpected htmlURL %s", teams[0].HTMLURL) + } +} + +func TestGetUrlForOrgTeams(t *testing.T) { + var userOrgs, org1Teams, org2Teams []byte + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch path := r.URL.Path; path { + case "/api/v3/user/orgs": + w.Write(userOrgs) + case "/api/v3/orgs/org1/teams": + w.Write(org1Teams) + case "/api/v3/orgs/org2/teams": + w.Write(org2Teams) + default: + t.Errorf("Unexpected client call %s", path) + } + })) + defer srv.Close() + + srvURL, err := url.Parse(srv.URL) + if err != nil { + t.Fatal(err) + } + + userOrgs = []byte(` + [{ + "id": 9343010, + "login": "org1", + "avatar_url": "` + srvURL.Host + `/u/9343010/avatar" + },{ + "id": 9343011, + "login": "org2", + "avatar_url": "` + srvURL.Host + `/u/9343011/avatar" + }]`) + org1Teams = []byte(` + [{ + "id": 9933605, + "name": "developers", + "slug": "developers" + },{ + "id": 9933606, + "name": "security", + "slug": "security" + }]`) + org2Teams = []byte(` + [{ + "id": 9933607, + "name": "dev-ops", + "slug": "dev-ops" + }]`) + + gcClient := &GClient{httpClient: srv.Client()} + + config := &v32.GithubConfig{ + Hostname: srvURL.Host, + } + + teams, err := gcClient.searchTeams("dev", "", config) + if err != nil { + t.Fatal(err) + } + + if want, got := 2, len(teams); want != got { + t.Fatalf("Expected teams %d got %d", want, got) + } + + for _, team := range teams { + switch team.ID { + case 9933605, 9933607: + default: + t.Errorf("Unexpected team %d", team.ID) + } + } + + teams, err = gcClient.searchTeams("foo", "", config) + if err != nil { + t.Fatal(err) + } + + if want, got := 0, len(teams); want != got { + t.Fatalf("Expected teams %d got %d", want, got) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider.go new file mode 100644 index 0000000..6f00d40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider.go @@ -0,0 +1,442 @@ +package github + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + util2 "github.com/rancher/rancher/pkg/auth/util" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + Name = "github" +) + +type tokensManager interface { + GetSecret(userID string, provider string, fallbackTokens []*v3.Token) (string, error) + IsMemberOf(token v3.Token, group v3.Principal) bool + CreateTokenAndSetCookie(userID string, userPrincipal v3.Principal, groupPrincipals []v3.Principal, providerToken string, ttl int, description string, request *types.APIContext) error + UserAttributeCreateOrUpdate(userID, provider string, groupPrincipals []v3.Principal, userExtraInfo map[string][]string, loginTime ...time.Time) error +} + +type ghProvider struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + getConfig func() (*v32.GithubConfig, error) + githubClient *GClient + userMGR user.Manager + tokenMGR tokensManager +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + githubClient := &GClient{ + httpClient: &http.Client{}, + } + + provider := &ghProvider{ + ctx: ctx, + authConfigs: mgmtCtx.Management.AuthConfigs(""), + secrets: mgmtCtx.Core.Secrets(""), + githubClient: githubClient, + userMGR: userMGR, + tokenMGR: tokenMGR, + } + provider.getConfig = provider.getGithubConfigCR + + return provider +} + +func (g *ghProvider) GetName() string { + return Name +} + +func (g *ghProvider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = g.actionHandler + schema.Formatter = g.formatter +} + +func (g *ghProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + p[publicclient.GithubProviderFieldRedirectURL] = formGithubRedirectURLFromMap(authConfig) + return p, nil +} + +func (g *ghProvider) getGithubConfigCR() (*v32.GithubConfig, error) { + authConfigObj, err := g.authConfigs.ObjectClient().UnstructuredClient().Get(Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve GithubConfig, error: %v", err) + } + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to retrieve GithubConfig, cannot read k8s Unstructured data") + } + storedGithubConfigMap := u.UnstructuredContent() + + storedGithubConfig := &v32.GithubConfig{} + err = common.Decode(storedGithubConfigMap, storedGithubConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode Github Config: %w", err) + } + + if storedGithubConfig.ClientSecret != "" { + data, err := common.ReadFromSecretData(g.secrets, storedGithubConfig.ClientSecret) + if err != nil { + return nil, err + } + for k, v := range data { + if strings.EqualFold(k, client.GithubConfigFieldClientSecret) { + storedGithubConfig.ClientSecret = string(v) + } else { + if storedGithubConfig.AdditionalClientIDs == nil { + storedGithubConfig.AdditionalClientIDs = map[string]string{} + } + storedGithubConfig.AdditionalClientIDs[k] = strings.TrimSpace(string(v)) + } + } + } + + return storedGithubConfig, nil +} + +func (g *ghProvider) saveGithubConfig(config *v32.GithubConfig) error { + storedGithubConfig, err := g.getGithubConfigCR() + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = client.GithubConfigType + config.ObjectMeta = storedGithubConfig.ObjectMeta + + secretInfo := convert.ToString(config.ClientSecret) + field := strings.ToLower(client.GithubConfigFieldClientSecret) + name, err := common.CreateOrUpdateSecrets(g.secrets, secretInfo, field, strings.ToLower(config.Type)) + if err != nil { + return err + } + + config.ClientSecret = name + + _, err = g.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + if err != nil { + return err + } + return nil +} + +func (g *ghProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, ok := input.(*v32.GithubLogin) + if !ok { + return v3.Principal{}, nil, "", errors.New("unexpected input type") + } + host := "" + req, ok := ctx.Value(util2.RequestKey).(*http.Request) + if ok { + host = util2.GetHost(req) + } + return g.LoginUser(host, login, nil, false) +} + +func choseClientID(host string, config *v32.GithubConfig) *v32.GithubConfig { + if host == "" { + return config + } + + clientID := config.HostnameToClientID[host] + secretID := config.AdditionalClientIDs[clientID] + if secretID == "" { + return config + } + + copy := *config + copy.ClientID = clientID + copy.ClientSecret = secretID + + return © +} + +func (g *ghProvider) LoginUser(host string, githubCredential *v32.GithubLogin, config *v32.GithubConfig, test bool) (v3.Principal, []v3.Principal, string, error) { + var groupPrincipals []v3.Principal + var userPrincipal v3.Principal + var err error + + if config == nil { + config, err = g.getConfig() + if err != nil { + return v3.Principal{}, nil, "", err + } + } + + config = choseClientID(host, config) + securityCode := githubCredential.Code + + accessToken, err := g.githubClient.getAccessToken(securityCode, config) + if err != nil { + logrus.Infof("Error generating accessToken from github %v", err) + return v3.Principal{}, nil, "", err + } + + user, err := g.githubClient.getUser(accessToken, config) + if err != nil { + return v3.Principal{}, nil, "", err + } + userPrincipal = g.toPrincipal(userType, user, nil) + userPrincipal.Me = true + + orgAccts, err := g.githubClient.getOrgs(accessToken, config) + if err != nil { + return v3.Principal{}, nil, "", err + } + for _, orgAcct := range orgAccts { + groupPrincipal := g.toPrincipal(orgType, orgAcct, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + + teamAccts, err := g.githubClient.getTeams(accessToken, config) + if err != nil { + return v3.Principal{}, nil, "", err + } + for _, teamAcct := range teamAccts { + groupPrincipal := g.toPrincipal(teamType, teamAcct, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + + testAllowedPrincipals := config.AllowedPrincipalIDs + if test && config.AccessMode == "restricted" { + testAllowedPrincipals = append(testAllowedPrincipals, userPrincipal.Name) + } + + allowed, err := g.userMGR.CheckAccess(config.AccessMode, testAllowedPrincipals, userPrincipal.Name, groupPrincipals) + if err != nil { + return v3.Principal{}, nil, "", err + } + if !allowed { + return v3.Principal{}, nil, "", httperror.NewAPIError(httperror.Unauthorized, "unauthorized") + } + + return userPrincipal, groupPrincipals, accessToken, nil +} + +func (g *ghProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + var groupPrincipals []v3.Principal + var err error + var config *v32.GithubConfig + + config, err = g.getConfig() + if err != nil { + return nil, err + } + + orgAccts, err := g.githubClient.getOrgs(secret, config) + if err != nil { + return nil, err + } + for _, orgAcct := range orgAccts { + groupPrincipal := g.toPrincipal(orgType, orgAcct, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + + teamAccts, err := g.githubClient.getTeams(secret, config) + if err != nil { + return nil, err + } + for _, teamAcct := range teamAccts { + groupPrincipal := g.toPrincipal(teamType, teamAcct, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + + return groupPrincipals, nil +} + +func (g *ghProvider) SearchPrincipals(searchKey, principalType string, token v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + var err error + + config, err := g.getConfig() + if err != nil { + return principals, err + } + + accessToken, err := g.tokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{&token}) + if err != nil { + if !apierrors.IsNotFound(err) { + return nil, err + } + accessToken = token.ProviderInfo["access_token"] + } + + accts, err := g.githubClient.searchUsers(searchKey, principalType, accessToken, config) + if err != nil { + logrus.Errorf("problem searching github: %v", err) + } + + for _, acct := range accts { + pType := strings.ToLower(acct.Type) + if pType == "organization" { + pType = orgType + } + p := g.toPrincipal(pType, acct, &token) + principals = append(principals, p) + } + + if principalType == "" || principalType == "group" { + // Additionally see if there are any matching teams since GitHub user search API doesn't cover those. + teamAccts, err := g.githubClient.searchTeams(searchKey, accessToken, config) + if err != nil { + return nil, err + } + + for _, acct := range teamAccts { + p := g.toPrincipal(teamType, acct, &token) + principals = append(principals, p) + } + } + + return principals, nil +} + +const ( + userType = "user" + teamType = "team" + orgType = "org" +) + +func (g *ghProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + config, err := g.getConfig() + if err != nil { + return v3.Principal{}, err + } + + accessToken, err := g.tokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{&token}) + if err != nil { + if !apierrors.IsNotFound(err) { + return v3.Principal{}, err + } + accessToken = token.ProviderInfo["access_token"] + } + // parsing id to get the external id and type. id looks like github_[user|org|team]://12345 + var externalID string + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return v3.Principal{}, errors.Errorf("invalid id %v", principalID) + } + externalID = strings.TrimPrefix(parts[1], "//") + parts = strings.SplitN(parts[0], "_", 2) + if len(parts) != 2 { + return v3.Principal{}, errors.Errorf("invalid id %v", principalID) + } + + principalType := parts[1] + var acct Account + switch principalType { + case userType, orgType: + acct, err = g.githubClient.getUserOrgByID(externalID, accessToken, config) + if err != nil { + return v3.Principal{}, err + } + case teamType: + acct, err = g.githubClient.getTeamByID(externalID, accessToken, config) + if err != nil { + return v3.Principal{}, err + } + default: + return v3.Principal{}, fmt.Errorf("cannot get the github account due to invalid externalIDType %v", principalType) + } + + princ := g.toPrincipal(principalType, acct, &token) + return princ, nil +} + +func (g *ghProvider) toPrincipal(principalType string, acct Account, token *v3.Token) v3.Principal { + displayName := acct.Name + if displayName == "" { + displayName = acct.Login + } + + princ := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: Name + "_" + principalType + "://" + strconv.Itoa(acct.ID)}, + DisplayName: displayName, + LoginName: acct.Login, + Provider: Name, + Me: false, + ProfilePicture: acct.AvatarURL, + } + + if principalType == userType { + princ.PrincipalType = "user" + if token != nil { + princ.Me = g.isThisUserMe(token.UserPrincipal, princ) + } + } else { + princ.PrincipalType = "group" + if token != nil { + princ.MemberOf = g.tokenMGR.IsMemberOf(*token, princ) + } + } + + return princ +} + +func (g *ghProvider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + return me.ObjectMeta.Name == other.ObjectMeta.Name && + me.LoginName == other.LoginName && + me.PrincipalType == other.PrincipalType +} + +func (g *ghProvider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, err := g.getConfig() + if err != nil { + logrus.Errorf("Error fetching github config: %v", err) + return false, err + } + allowed, err := g.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func (g *ghProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the GitHub auth provider is currently disabled in Rancher. +func (g *ghProvider) IsDisabledProvider() (bool, error) { + ghConfig, err := g.getConfig() + if err != nil { + return false, err + } + return !ghConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider_test.go new file mode 100644 index 0000000..5fc8ea5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/github_provider_test.go @@ -0,0 +1,235 @@ +package github + +import ( + "context" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "testing" + "time" + + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type fakeTokensManager struct { + getSecretFunc func(userID string, provider string, fallbackTokens []*v3.Token) (string, error) + isMemberOfFunc func(token v3.Token, group v3.Principal) bool + createTokenAndSetCookieFunc func(userID string, userPrincipal v3.Principal, groupPrincipals []v3.Principal, providerToken string, ttl int, description string, request *types.APIContext) error +} + +func (m *fakeTokensManager) GetSecret(userID string, provider string, fallbackTokens []*v3.Token) (string, error) { + if m.getSecretFunc != nil { + return m.getSecretFunc(userID, provider, fallbackTokens) + } + return "", nil +} + +func (m *fakeTokensManager) IsMemberOf(token v3.Token, group v3.Principal) bool { + if m.isMemberOfFunc != nil { + return m.isMemberOfFunc(token, group) + } + return false +} + +func (m *fakeTokensManager) CreateTokenAndSetCookie(userID string, userPrincipal v3.Principal, groupPrincipals []v3.Principal, providerToken string, ttl int, description string, request *types.APIContext) error { + if m.createTokenAndSetCookieFunc != nil { + return m.createTokenAndSetCookieFunc(userID, userPrincipal, groupPrincipals, providerToken, ttl, description, request) + } + return nil +} + +func (m *fakeTokensManager) UserAttributeCreateOrUpdate(userID, provider string, groupPrincipals []v3.Principal, userExtraInfo map[string][]string, loginTime ...time.Time) error { + return nil +} + +func TestSearchPrincipals(t *testing.T) { + var userOrgs, orgTeams, searchUsersAll, searchUsersGroup, searchUsersUser []byte + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch path := r.URL.Path; path { + case "/api/v3/user/orgs": + w.Write(userOrgs) + case "/api/v3/orgs/devorg/teams": + w.Write(orgTeams) + case "/api/v3/search/users": + q := r.URL.Query().Get("q") + if strings.Contains(q, " type:org") { + w.Write(searchUsersGroup) + } else if strings.Contains(q, " type:user") { + w.Write(searchUsersUser) + } else { + w.Write(searchUsersAll) + } + default: + t.Errorf("Unexpected client call %s", path) + } + })) + defer srv.Close() + + srvURL, err := url.Parse(srv.URL) + if err != nil { + t.Fatal(err) + } + + userOrgs = []byte(` + [{ + "id": 9343010, + "login": "devorg", + "avatar_url": "` + srvURL.Host + `/u/9343010/avatar" + }]`) + orgTeams = []byte(` + [{ + "id": 9933605, + "name": "developers", + "slug": "developers" + },{ + "id": 9933606, + "name": "security", + "slug": "security" + }]`) + searchUsersAll = []byte(`{ + "total_count": 2, + "incomplete_results": false, + "items": [{ + "id": 9253000, + "login": "developer", + "avatar_url": "` + srvURL.Host + `/u/9253000/avatar", + "html_url": "` + srvURL.Host + `/developer", + "type": "User" + },{ + "id": 9343010, + "login": "devorg", + "avatar_url": "` + srvURL.Host + `/u/9343010/avatar", + "html_url": "` + srvURL.Host + `/devorg", + "type": "Organization" + }] + }`) + searchUsersGroup = []byte(`{ + "total_count": 1, + "incomplete_results": false, + "items": [{ + "id": 9343010, + "login": "devorg", + "avatar_url": "` + srvURL.Host + `/u/9343010/avatar", + "html_url": "` + srvURL.Host + `/devorg", + "type": "Organization" + }] + }`) + searchUsersUser = []byte(`{ + "total_count": 1, + "incomplete_results": false, + "items": [{ + "id": 9253000, + "login": "developer", + "avatar_url": "` + srvURL.Host + `/u/9253000/avatar", + "html_url": "` + srvURL.Host + `/developer", + "type": "User" + }] + }`) + + fakeTokensManager := &fakeTokensManager{ + isMemberOfFunc: func(token v3.Token, group v3.Principal) bool { + return true + }, + } + config := &v32.GithubConfig{ + Hostname: srvURL.Host, + } + + provider := ghProvider{ + ctx: context.Background(), + githubClient: &GClient{httpClient: srv.Client()}, + getConfig: func() (*v32.GithubConfig, error) { return config, nil }, + tokenMGR: fakeTokensManager, + } + + token := v32.Token{ + UserPrincipal: v32.Principal{ + ObjectMeta: metav1.ObjectMeta{ + Name: "github_user://9253000", + }, + LoginName: "developer", + PrincipalType: "user", + }, + } + + // Search for groups and users. + found, err := provider.SearchPrincipals("dev", "", token) + if err != nil { + t.Fatal(err) + } + + if want, got := 3, len(found); want != got { + t.Fatalf("Expected principals %d got %d", want, got) + } + + for _, p := range found { + switch p.LoginName { + case "devorg": + if want, got := false, p.Me; want != got { + t.Errorf("[%s] Expected Me %t, got %t", p.LoginName, want, got) + } + if want, got := true, p.MemberOf; want != got { + t.Errorf("[%s] Expected MemberOf %t, got %t", p.LoginName, want, got) + } + if want, got := "group", p.PrincipalType; want != got { + t.Errorf("[%s] Expected PrincipalType %s, got %s", p.LoginName, want, got) + } + case "developer": + if want, got := true, p.Me; want != got { + t.Errorf("[%s] Expected Me %t, got %t", p.LoginName, want, got) + } + if want, got := "user", p.PrincipalType; want != got { + t.Errorf("[%s] Expected PrincipalType %s, got %s", p.LoginName, want, got) + } + case "developers": + if want, got := false, p.Me; want != got { + t.Errorf("[%s] Expected Me %t, got %t", p.LoginName, want, got) + } + if want, got := true, p.MemberOf; want != got { + t.Errorf("[%s] Expected MemberOf %t, got %t", p.LoginName, want, got) + } + if want, got := "group", p.PrincipalType; want != got { + t.Errorf("[%s] Expected PrincipalType %s, got %s", p.LoginName, want, got) + } + default: + t.Errorf("Unexpected principal %s", p.LoginName) + } + } + + // Search for groups only. + found, err = provider.SearchPrincipals("dev", "group", token) + if err != nil { + t.Fatal(err) + } + + if want, got := 2, len(found); want != got { + t.Fatalf("Expected principals %d got %d", want, got) + } + + for _, p := range found { + switch p.LoginName { + case "devorg", "developers": + default: + t.Errorf("Unexpected principal %s", p.LoginName) + } + } + + // Search for users only. + found, err = provider.SearchPrincipals("dev", "user", token) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, len(found); want != got { + t.Fatalf("Expected principals %d got %d", want, got) + } + + if found[0].LoginName != "developer" { + t.Errorf("Unexpected principal %s", found[0].LoginName) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/githubconfig_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/githubconfig_actions.go new file mode 100644 index 0000000..edc721a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/github/githubconfig_actions.go @@ -0,0 +1,143 @@ +package github + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "k8s.io/client-go/util/retry" +) + +func (g *ghProvider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "configureTest") + resource.AddAction(apiContext, "testAndApply") +} + +func (g *ghProvider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, Name, g.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "configureTest" { + return g.configureTest(request) + } else if actionName == "testAndApply" { + return g.testAndApply(request) + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (g *ghProvider) configureTest(request *types.APIContext) error { + githubConfig := &v32.GithubConfig{} + if err := json.NewDecoder(request.Request.Body).Decode(githubConfig); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + redirectURL := formGithubRedirectURL(githubConfig) + + data := map[string]interface{}{ + "redirectUrl": redirectURL, + "type": "githubConfigTestOutput", + } + + request.WriteResponse(http.StatusOK, data) + return nil +} + +func formGithubRedirectURL(githubConfig *v32.GithubConfig) string { + return githubRedirectURL(githubConfig.Hostname, githubConfig.ClientID, githubConfig.TLS) +} + +func formGithubRedirectURLFromMap(config map[string]interface{}) string { + hostname, _ := config[client.GithubConfigFieldHostname].(string) + clientID, _ := config[client.GithubConfigFieldClientID].(string) + tls, _ := config[client.GithubConfigFieldTLS].(bool) + + requestHostname := convert.ToString(config[".host"]) + clientIDs := convert.ToMapInterface(config["hostnameToClientId"]) + if otherID, ok := clientIDs[requestHostname]; ok { + clientID = convert.ToString(otherID) + } + return githubRedirectURL(hostname, clientID, tls) +} + +func githubRedirectURL(hostname, clientID string, tls bool) string { + redirect := "" + if hostname != "" { + scheme := "http://" + if tls { + scheme = "https://" + } + redirect = scheme + hostname + } else { + redirect = githubDefaultHostName + } + redirect = redirect + "/login/oauth/authorize?client_id=" + clientID + return redirect +} + +func (g *ghProvider) testAndApply(request *types.APIContext) error { + var githubConfig v32.GithubConfig + githubConfigApplyInput := &v32.GithubConfigApplyInput{} + + if err := json.NewDecoder(request.Request.Body).Decode(githubConfigApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + githubConfig = githubConfigApplyInput.GithubConfig + githubLogin := &v32.GithubLogin{ + Code: githubConfigApplyInput.Code, + } + + if githubConfig.ClientSecret != "" { + value, err := common.ReadFromSecret(g.secrets, githubConfig.ClientSecret, + strings.ToLower(client.GithubConfigFieldClientSecret)) + if err != nil { + return err + } + githubConfig.ClientSecret = value + } + + // Call provider to testLogin + userPrincipal, groupPrincipals, providerInfo, err := g.LoginUser("", githubLogin, &githubConfig, true) + if err != nil { + if httperror.IsAPIError(err) { + return err + } + return errors.Wrap(err, "server error while authenticating") + } + + // if this works, save githubConfig CR adding enabled flag + user, err := g.userMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + githubConfig.Enabled = githubConfigApplyInput.Enabled + err = g.saveGithubConfig(&githubConfig) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to save github config: %v", err)) + } + + userExtraInfo := g.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return g.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to create or update userAttribute: %v", err)) + } + + return g.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, providerInfo, 0, "Token via Github Configuration", request) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_client.go new file mode 100644 index 0000000..b4dbded --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_client.go @@ -0,0 +1,59 @@ +package googleoauth + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" +) + +// GClient implements a httpclient for google oauth +type GClient struct { + httpClient *http.Client +} + +func (g *GClient) getUser(accessToken string, config *v32.GoogleOauthConfig) (*Account, error) { + // userinfo endpoint doesn't require viewType param, non-admins and admins both can query this endpoint + respBytes, _, err := g.getFromGoogle(accessToken, config.UserInfoEndpoint) + if err != nil { + return nil, err + } + + var goauthAccount Account + if err = json.Unmarshal(respBytes, &goauthAccount); err != nil { + return nil, err + } + return &goauthAccount, nil +} + +func (g *GClient) getFromGoogle(accessToken string, url string) ([]byte, int, error) { + var statusCode int + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, statusCode, err + } + req.Header.Add("Authorization", "Bearer "+accessToken) + req.Header.Add("Accept", "application/json") + resp, err := g.httpClient.Do(req) + if err != nil { + return nil, statusCode, err + } + defer resp.Body.Close() + // Check the status code + switch resp.StatusCode { + case 200: + case 201: + default: + var body bytes.Buffer + io.Copy(&body, resp.Body) + return nil, resp.StatusCode, fmt.Errorf("request failed, got status code: %d. Response: %s", + resp.StatusCode, body.Bytes()) + } + + b, err := ioutil.ReadAll(resp.Body) + return b, statusCode, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_helper.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_helper.go new file mode 100644 index 0000000..0240160 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_helper.go @@ -0,0 +1,295 @@ +package googleoauth + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + admin "google.golang.org/api/admin/directory/v1" + "google.golang.org/api/googleapi" +) + +func (g *googleOauthProvider) getUserInfoAndGroups(adminSvc *admin.Service, gOAuthToken *oauth2.Token, config *v32.GoogleOauthConfig, testAndEnableAction bool) (v3.Principal, []v3.Principal, error) { + var userPrincipal v3.Principal + var groupPrincipals []v3.Principal + // use the access token to make requests, get user info + user, err := g.goauthClient.getUser(gOAuthToken.AccessToken, config) + if err != nil { + return userPrincipal, groupPrincipals, err + } + if testAndEnableAction { + if user.HostedDomain != config.Hostname { + return userPrincipal, groupPrincipals, fmt.Errorf("invalid hostname provided") + } + } + userPrincipal = g.toPrincipal(userType, *user, nil) + userPrincipal.Me = true + logrus.Debugf("[Google OAuth] loginuser: Obtained userinfo using oauth access token") + + groupPrincipals, err = g.getGroupsUserBelongsTo(adminSvc, user.SubjectUniqueID, user.HostedDomain, config) + if err != nil { + // The error for this group request could be 403, because svc acc was not provided, and we're relying on individual + // users' creds to get groups + if config.ServiceAccountCredential == "" { + if gErr, ok := err.(*googleapi.Error); !ok || gErr.Code != http.StatusForbidden { + // if the error is not forbidden, return the error + return userPrincipal, groupPrincipals, err + } + // if the error is forbidden, don't throw any error, just no group principals will be returned + } else { + // getting any error in spite of svc acc creds must be returned + return userPrincipal, groupPrincipals, err + } + } + if config.NestedGroupMembershipEnabled { + groupPrincipals, err = g.fetchParentGroups(config, groupPrincipals, adminSvc, user.HostedDomain) + if err != nil { + return userPrincipal, groupPrincipals, err + } + } + + logrus.Debugf("[Google OAuth] loginuser: Retrieved user's groups using admin directory") + return userPrincipal, groupPrincipals, nil +} + +func (g *googleOauthProvider) fetchParentGroups(config *v32.GoogleOauthConfig, groupPrincipals []v3.Principal, adminSvc *admin.Service, hostedDomain string) ([]v3.Principal, error) { + groupMap := make(map[string]bool) + var nestedGroupPrincipals []v3.Principal + for _, principal := range groupPrincipals { + principals, err := g.gatherParentGroups(principal, adminSvc, config, hostedDomain, groupMap) + if err != nil { + return groupPrincipals, err + } + if len(principals) > 0 { + nestedGroupPrincipals = append(nestedGroupPrincipals, principals...) + } + } + groupPrincipals = append(groupPrincipals, nestedGroupPrincipals...) + return groupPrincipals, nil +} + +func (g *googleOauthProvider) getGroupsUserBelongsTo(adminSvc *admin.Service, userKey string, hostedDomain string, config *v32.GoogleOauthConfig) ([]v3.Principal, error) { + var groupPrincipals []v3.Principal + _, groups, err := g.paginateResults(adminSvc, hostedDomain, userKey, "", "", groupType, false) + if err != nil { + // The error for this group request could be 403, because svc acc was not provided, and we're relying on individual + // users' creds to get groups + if config.ServiceAccountCredential == "" { + // used the client creds, if error is forbidden, don't throw error + if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusForbidden { + return groupPrincipals, nil + } + } + // getting any error in spite of svc acc creds must be returned + return nil, err + } + for _, gr := range groups { + group := Account{Name: gr.Name, Email: gr.Email, SubjectUniqueID: gr.Id} + groupPrincipal := g.toPrincipal(groupType, group, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + return groupPrincipals, nil +} + +func (g *googleOauthProvider) searchPrincipals(adminSvc *admin.Service, searchKey, principalType string, config *v32.GoogleOauthConfig) ([]Account, error) { + var accounts []Account + + if principalType == "" || principalType == "user" { + userAccounts, err := g.searchUsers(adminSvc, searchKey, config, false) + if err != nil { + if config.ServiceAccountCredential == "" { + // used the client creds, must try once with viewType domain_public + if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusForbidden { + userAccounts, err = g.searchUsers(adminSvc, searchKey, config, true) + if err != nil { + return nil, err + } + } else { + return nil, err + } + } else { + // getting any error in spite of svc acc creds must be returned + return nil, err + } + } + accounts = append(accounts, userAccounts...) + } + if principalType == "" || principalType == "group" { + groupAccounts, err := g.searchGroups(adminSvc, searchKey, config) + if err != nil { + if config.ServiceAccountCredential == "" { + // used the client creds, if error is forbidden, don't throw error + if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusForbidden { + return accounts, nil + } + } + // getting any error in spite of svc acc creds must be returned + return nil, err + } + accounts = append(accounts, groupAccounts...) + } + return accounts, nil +} + +func (g *googleOauthProvider) searchUsers(adminSvc *admin.Service, searchKey string, config *v32.GoogleOauthConfig, viewPublic bool) ([]Account, error) { + var users []*admin.User + var accounts []Account + users, _, err := g.paginateResults(adminSvc, config.Hostname, "", searchKey, "", userType, viewPublic) + if err != nil { + return accounts, err + } + for _, u := range users { + a := Account{ + SubjectUniqueID: u.Id, + Email: u.PrimaryEmail, + PictureURL: u.ThumbnailPhotoUrl, + Type: userType, + } + if u.Name != nil { + a.Name = u.Name.FullName + a.GivenName = u.Name.GivenName + a.FamilyName = u.Name.FamilyName + } + accounts = append(accounts, a) + } + return accounts, nil +} + +func (g *googleOauthProvider) searchGroups(adminSvc *admin.Service, searchKey string, config *v32.GoogleOauthConfig) ([]Account, error) { + var accounts []Account + groupsMap := map[string]*admin.Group{} + for _, attr := range []string{"name", "email"} { + _, resGroups, err := g.paginateResults(adminSvc, config.Hostname, "", searchKey, attr, groupType, false) + if err != nil { + return accounts, err + } + //dedup groups + for _, gr := range resGroups { + if _, ok := groupsMap[gr.Id]; !ok { + groupsMap[gr.Id] = gr + } + } + } + + for _, g := range groupsMap { + accounts = append(accounts, Account{SubjectUniqueID: g.Id, Email: g.Email, Name: g.Name, Type: groupType}) + } + return accounts, nil +} + +func (g *googleOauthProvider) paginateResults(adminSvc *admin.Service, hostedDomain, memberKey, searchKey, searchAttr, accountType string, viewPublic bool) ([]*admin.User, []*admin.Group, error) { + var groups []*admin.Group + var users []*admin.User + switch accountType { + case userType: + // in case of list users call, using the searchKey itself as query searches all attributes for the search key + userListCall := adminSvc.Users.List().Domain(hostedDomain).Query(searchKey) + if viewPublic { + userListCall.ViewType(domainPublicViewType) + } + for { + res, err := userListCall.Do() + if err != nil { + return users, nil, err + } + users = append(users, res.Users...) + if res.NextPageToken == "" { + return users, nil, nil + } + userListCall.PageToken(res.NextPageToken) + } + case groupType: + groupListCall := adminSvc.Groups.List().Domain(hostedDomain) + if memberKey != "" { + groupListCall.UserKey(memberKey) + } else if searchKey != "" { + // in case of list groups call, we need to specify search attributes + groupListCall.Query(searchAttr + ":" + searchKey + "*") + } + for { + res, err := groupListCall.Do() + if err != nil { + return nil, groups, err + } + groups = append(groups, res.Groups...) + if res.NextPageToken == "" { + return nil, groups, nil + } + groupListCall.PageToken(res.NextPageToken) + } + default: + return nil, nil, fmt.Errorf("paginateResults: Invalid principal type") + } +} + +func (g *googleOauthProvider) gatherParentGroups(groupPrincipal v3.Principal, adminSvc *admin.Service, config *v32.GoogleOauthConfig, hostedDomain string, groupMap map[string]bool) ([]v3.Principal, error) { + var principals []v3.Principal + if groupMap[groupPrincipal.ObjectMeta.Name] { + return principals, nil + } + groupMap[groupPrincipal.ObjectMeta.Name] = true + parts := strings.SplitN(groupPrincipal.ObjectMeta.Name, ":", 2) + if len(parts) != 2 { + return principals, fmt.Errorf("error while gathering parent groups: invalid id %v", groupPrincipal.ObjectMeta.Name) + } + groupID := strings.TrimPrefix(parts[1], "//") + groups, err := g.getGroupsUserBelongsTo(adminSvc, groupID, hostedDomain, config) + if err != nil { + return principals, err + } + + for _, group := range groups { + if groupMap[group.ObjectMeta.Name] { + continue + } else { + principals = append(principals, group) + nestedGroupPrincipals, err := g.gatherParentGroups(group, adminSvc, config, hostedDomain, groupMap) + if err != nil { + return principals, err + } + if len(nestedGroupPrincipals) > 0 { + principals = append(principals, nestedGroupPrincipals...) + } + } + } + return principals, nil +} + +func (g *googleOauthProvider) getdirectoryServiceFromStoredToken(storedOauthToken string, config *v32.GoogleOauthConfig) (*admin.Service, error) { + var oauthToken oauth2.Token + if err := json.Unmarshal([]byte(storedOauthToken), &oauthToken); err != nil { + return nil, err + } + + oauth2Config, err := google.ConfigFromJSON([]byte(config.OauthCredential), scopes...) + if err != nil { + return nil, err + } + adminSvc, err := g.getDirectoryService(g.ctx, config.AdminEmail, []byte(config.ServiceAccountCredential), oauth2Config.TokenSource(g.ctx, &oauthToken)) + if err != nil { + return nil, err + } + return adminSvc, nil +} + +func getUIDFromPrincipalID(principalID string) (string, string, error) { + var externalID string + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid id %v", principalID) + } + externalID = strings.TrimPrefix(parts[1], "//") + parts = strings.SplitN(parts[0], "_", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid id %v", principalID) + } + return externalID, parts[1], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_provider.go new file mode 100644 index 0000000..e401739 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauth_provider.go @@ -0,0 +1,443 @@ +package googleoauth + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + admin "google.golang.org/api/admin/directory/v1" + "google.golang.org/api/googleapi" + "google.golang.org/api/option" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + Name = "googleoauth" + userType = "user" + groupType = "group" + domainPublicViewType = "domain_public" +) + +var scopes = []string{"openid", "profile", "email", admin.AdminDirectoryUserReadonlyScope, admin.AdminDirectoryGroupReadonlyScope} + +type googleOauthProvider struct { + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + goauthClient *GClient + userMGR user.Manager + tokenMGR *tokens.Manager + ctx context.Context +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + gClient := GClient{ + httpClient: &http.Client{ + Timeout: time.Second * 30, + }, + } + return &googleOauthProvider{ + ctx: ctx, + authConfigs: mgmtCtx.Management.AuthConfigs(""), + secrets: mgmtCtx.Core.Secrets(""), + goauthClient: &gClient, + userMGR: userMGR, + tokenMGR: tokenMGR, + } +} + +func (g *googleOauthProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, ok := input.(*v32.GoogleOauthLogin) + if !ok { + return v3.Principal{}, nil, "", fmt.Errorf("unexpected input type") + } + return g.loginUser(ctx, login, nil, false) +} + +// loginUser takes as input the code; gets access_token and refresh_token in exhange; uses access_token to get user info +// and groups (if allowed); and returns the user and group principals and oauth token +func (g *googleOauthProvider) loginUser(c context.Context, googleOAuthCredential *v32.GoogleOauthLogin, config *v32.GoogleOauthConfig, testAndEnableAction bool) (v3.Principal, []v3.Principal, string, error) { + var groupPrincipals []v3.Principal + var userPrincipal v3.Principal + var err error + + if config == nil { + config, err = g.getGoogleOAuthConfigCR() + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + } + + logrus.Debugf("[Google OAuth] loginuser: Using code to get oauth token") + securityCode := googleOAuthCredential.Code + oauth2Config, err := google.ConfigFromJSON([]byte(config.OauthCredential), scopes...) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + // Exchange the code for oauthToken + gOAuthToken, err := oauth2Config.Exchange(c, securityCode) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + logrus.Debugf("[Google OAuth] loginuser: Exchanged code for oauth token") + + // init the admin directory service + adminSvc, err := g.getDirectoryService(c, config.AdminEmail, []byte(config.ServiceAccountCredential), oauth2Config.TokenSource(c, gOAuthToken)) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + userPrincipal, groupPrincipals, err = g.getUserInfoAndGroups(adminSvc, gOAuthToken, config, testAndEnableAction) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + + logrus.Debugf("[Google OAuth] loginuser: Checking user's access to Rancher") + allowed, err := g.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipal.Name, groupPrincipals) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + if !allowed { + return userPrincipal, groupPrincipals, "", httperror.NewAPIError(httperror.Unauthorized, "unauthorized") + } + + // save entire oauthToken because it contains refresh_token and token expiry time + // oauth2.TokenSource used in getDirectoryService uses all these fields to auto renew the access token (Ref: https://github.com/golang/oauth2/blob/aaccbc9213b0974828f81aaac109d194880e3014/oauth2.go#L235) + oauthToken, err := json.Marshal(gOAuthToken) + if err != nil { + return userPrincipal, groupPrincipals, "", err + } + + logrus.Debugf("[Google OAuth] loginuser: Returning principals and marshaled oauth token") + return userPrincipal, groupPrincipals, string(oauthToken), nil +} + +func (g *googleOauthProvider) SearchPrincipals(searchKey, principalType string, token v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + var err error + + config, err := g.getGoogleOAuthConfigCR() + if err != nil { + return principals, err + } + + storedOauthToken, err := g.tokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{&token}) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + logrus.Debugf("[Google OAuth] SearchPrincipals: Retrieved stored oauth token") + adminSvc, err := g.getdirectoryServiceFromStoredToken(storedOauthToken, config) + if err != nil { + return principals, err + } + + logrus.Debugf("[Google OAuth] SearchPrincipals: Initialized dir svc with stored oauth token") + accounts, err := g.searchPrincipals(adminSvc, searchKey, principalType, config) + if err != nil { + return principals, err + } + for _, acc := range accounts { + principals = append(principals, g.toPrincipal(acc.Type, acc, &token)) + } + logrus.Debugf("[Google OAuth] SearchPrincipals: Returning principals") + return principals, nil +} + +func (g *googleOauthProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + var principal v3.Principal + config, err := g.getGoogleOAuthConfigCR() + if err != nil { + return principal, err + } + storedOauthToken, err := g.tokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{&token}) + if err != nil { + if !apierrors.IsNotFound(err) { + return principal, err + } + } + logrus.Debugf("[Google OAuth] GetPrincipal: Retrieved stored oauth token") + adminSvc, err := g.getdirectoryServiceFromStoredToken(storedOauthToken, config) + if err != nil { + return principal, err + } + + logrus.Debugf("[Google OAuth] GetPrincipal: Initialized dir svc with stored oauth token") + externalID, principalType, err := getUIDFromPrincipalID(principalID) + if err != nil { + return principal, err + } + logrus.Debugf("[Google OAuth] GetPrincipal: Parsed principalID") + switch principalType { + case userType: + user, err := adminSvc.Users.Get(externalID).Do() + if err != nil { + if config.ServiceAccountCredential == "" { + // used client creds, try get again with viewType=domain_public + if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusForbidden { + user, err = adminSvc.Users.Get(externalID).ViewType(domainPublicViewType).Do() + if err != nil { + return principal, err + } + } else { + return principal, err + } + } else { + return principal, err + } + } + acc := Account{ + SubjectUniqueID: user.Id, + Email: user.PrimaryEmail, + PictureURL: user.ThumbnailPhotoUrl, + Type: userType, + } + if user.Name != nil { + acc.Name = user.Name.FullName + acc.GivenName = user.Name.GivenName + acc.FamilyName = user.Name.FamilyName + } + return g.toPrincipal(userType, acc, &token), nil + case groupType: + group, err := adminSvc.Groups.Get(externalID).Do() + if err != nil { + if config.ServiceAccountCredential == "" { + // used client creds, getting group for non-admin might fail with forbidden, if that's the case don't throw + // error + if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == http.StatusForbidden { + return principal, nil + } + } + return principal, err + } + return g.toPrincipal(groupType, Account{SubjectUniqueID: group.Id, Email: group.Email, Name: group.Name}, &token), nil + default: + return principal, fmt.Errorf("cannot get the google account due to invalid externalIDType %v", principalType) + } +} + +func (g *googleOauthProvider) GetName() string { + return Name +} + +func (g *googleOauthProvider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = g.actionHandler + schema.Formatter = g.formatter +} + +func (g *googleOauthProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + val, err := g.formGoogleOAuthRedirectURLFromMap(authConfig) + if err != nil { + return nil, err + } + p[publicclient.GoogleOAuthProviderFieldRedirectURL] = val + return p, nil +} + +func (g *googleOauthProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + var principals []v3.Principal + config, err := g.getGoogleOAuthConfigCR() + if err != nil { + return principals, err + } + adminSvc, err := g.getdirectoryServiceFromStoredToken(secret, config) + if err != nil { + return principals, err + } + logrus.Debugf("[Google OAuth] RefetchGroupPrincipals: Initialized dir svc with stored oauth token") + externalID, _, err := getUIDFromPrincipalID(principalID) + if err != nil { + return principals, err + } + logrus.Debugf("[Google OAuth] GetPrincipal: Parsed principalID") + groupPrincipals, err := g.getGroupsUserBelongsTo(adminSvc, externalID, config.Hostname, config) + if err != nil { + return principals, err + } + if !config.NestedGroupMembershipEnabled { + return groupPrincipals, nil + } + return g.fetchParentGroups(config, groupPrincipals, adminSvc, config.Hostname) +} + +func (g *googleOauthProvider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, err := g.getGoogleOAuthConfigCR() + if err != nil { + logrus.Errorf("Error fetching google OAuth config: %v", err) + return false, err + } + allowed, err := g.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func (g *googleOauthProvider) getGoogleOAuthConfigCR() (*v32.GoogleOauthConfig, error) { + authConfigObj, err := g.authConfigs.ObjectClient().UnstructuredClient().Get(Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve GoogleOAuthConfig, error: %v", err) + } + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to retrieve GoogleOAuthConfig, cannot read k8s Unstructured data") + } + storedGoogleOAuthConfigMap := u.UnstructuredContent() + + storedGoogleOAuthConfig := &v32.GoogleOauthConfig{} + err = common.Decode(storedGoogleOAuthConfigMap, storedGoogleOAuthConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode Google Oauth Config: %w", err) + } + + if storedGoogleOAuthConfig.OauthCredential != "" { + value, err := common.ReadFromSecret(g.secrets, storedGoogleOAuthConfig.OauthCredential, strings.ToLower(client.GoogleOauthConfigFieldOauthCredential)) + if err != nil { + return nil, err + } + storedGoogleOAuthConfig.OauthCredential = value + } + + if storedGoogleOAuthConfig.ServiceAccountCredential != "" { + value, err := common.ReadFromSecret(g.secrets, storedGoogleOAuthConfig.ServiceAccountCredential, strings.ToLower(client.GoogleOauthConfigFieldServiceAccountCredential)) + if err != nil { + return nil, err + } + storedGoogleOAuthConfig.ServiceAccountCredential = value + } + return storedGoogleOAuthConfig, nil +} + +func (g *googleOauthProvider) saveGoogleOAuthConfigCR(config *v32.GoogleOauthConfig) error { + storedGoogleOAuthConfig, err := g.getGoogleOAuthConfigCR() + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = client.GoogleOauthConfigType + config.ObjectMeta = storedGoogleOAuthConfig.ObjectMeta + + secretInfo := convert.ToString(config.OauthCredential) + field := strings.ToLower(client.GoogleOauthConfigFieldOauthCredential) + name, err := common.CreateOrUpdateSecrets(g.secrets, secretInfo, field, strings.ToLower(config.Type)) + if err != nil { + return err + } + config.OauthCredential = name + + if config.ServiceAccountCredential != "" { + secretInfo = convert.ToString(config.ServiceAccountCredential) + field = strings.ToLower(client.GoogleOauthConfigFieldServiceAccountCredential) + name, err := common.CreateOrUpdateSecrets(g.secrets, secretInfo, field, strings.ToLower(config.Type)) + if err != nil { + return err + } + config.ServiceAccountCredential = name + } + + _, err = g.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + if err != nil { + return err + } + return nil +} + +func (g *googleOauthProvider) toPrincipal(principalType string, acct Account, token *v3.Token) v3.Principal { + displayName := acct.Name + if displayName == "" { + displayName = acct.Email + } + + princ := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: Name + "_" + principalType + "://" + acct.SubjectUniqueID}, + DisplayName: displayName, + LoginName: acct.Email, + Provider: Name, + Me: false, + ProfilePicture: acct.PictureURL, + } + + if principalType == userType { + princ.PrincipalType = "user" + if token != nil { + princ.Me = g.isThisUserMe(token.UserPrincipal, princ) + } + } else { + princ.PrincipalType = "group" + if token != nil { + princ.MemberOf = g.tokenMGR.IsMemberOf(*token, princ) + } + } + return princ +} + +func (g *googleOauthProvider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (g *googleOauthProvider) getDirectoryService(ctx context.Context, userEmail string, jsonCredentials []byte, accessTokenSource oauth2.TokenSource) (*admin.Service, error) { + if userEmail != "" && len(jsonCredentials) > 0 { + // oauth golang library performs all these steps: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth + // using JWTConfigFromJSON method + config, err := google.JWTConfigFromJSON(jsonCredentials, admin.AdminDirectoryUserReadonlyScope, admin.AdminDirectoryGroupReadonlyScope) + if err != nil { + logrus.Errorf("[Google OAuth] error unmarshaling service account creds: %v", err) + return nil, fmt.Errorf("invalid Service Account Credentials provided") + } + config.Subject = userEmail + srv, err := admin.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx))) + if err != nil { + logrus.Errorf("[Google OAuth] error generating tokenSource for service account creds: %v", err) + return nil, fmt.Errorf("invalid Service Account Credentials provided") + } + return srv, nil + } + // client oauth creds are used + srv, err := admin.NewService(ctx, option.WithTokenSource(accessTokenSource)) + if err != nil { + return nil, err + } + return srv, nil +} + +func (g *googleOauthProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the Google auth provider is currently disabled in Rancher. +func (g *googleOauthProvider) IsDisabledProvider() (bool, error) { + googleOauthConfig, err := g.getGoogleOAuthConfigCR() + if err != nil { + return false, err + } + return !googleOauthConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauthconfig_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauthconfig_actions.go new file mode 100644 index 0000000..194cb71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/goauthconfig_actions.go @@ -0,0 +1,152 @@ +package googleoauth + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + "k8s.io/client-go/util/retry" +) + +func (g *googleOauthProvider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "configureTest") + resource.AddAction(apiContext, "testAndApply") +} + +func (g *googleOauthProvider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, Name, g.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "configureTest" { + return g.configureTest(request) + } else if actionName == "testAndApply" { + return g.testAndApply(request) + } + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (g *googleOauthProvider) configureTest(request *types.APIContext) error { + goauthConfig := &v32.GoogleOauthConfig{} + if err := json.NewDecoder(request.Request.Body).Decode(goauthConfig); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("[Google OAuth] configureTest: Failed to parse body: %v", err)) + } + + redirectURL, err := g.formGoogleOAuthRedirectURL(goauthConfig) + if err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("[Google OAuth] configureTest: Failed to form redirect URL with error: %v", err)) + } + data := map[string]interface{}{ + "redirectUrl": redirectURL, + "type": "googleOAuthConfigTestOutput", + } + request.WriteResponse(http.StatusOK, data) + return nil +} + +func (g *googleOauthProvider) testAndApply(request *types.APIContext) error { + var googleOAuthConfig v32.GoogleOauthConfig + googleOAuthConfigApplyInput := &v32.GoogleOauthConfigApplyInput{} + if err := json.NewDecoder(request.Request.Body).Decode(googleOAuthConfigApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("[Google OAuth] testAndApply: Failed to parse body: %v", err)) + } + + googleOAuthConfig = googleOAuthConfigApplyInput.GoogleOauthConfig + googleLogin := &v32.GoogleOauthLogin{ + Code: googleOAuthConfigApplyInput.Code, + } + + if googleOAuthConfig.OauthCredential != "" { + value, err := common.ReadFromSecret(g.secrets, googleOAuthConfig.OauthCredential, + strings.ToLower(client.GoogleOauthConfigFieldOauthCredential)) + if err != nil { + return err + } + googleOAuthConfig.OauthCredential = value + } + + if googleOAuthConfig.ServiceAccountCredential != "" { + value, err := common.ReadFromSecret(g.secrets, googleOAuthConfig.ServiceAccountCredential, + strings.ToLower(client.GoogleOauthConfigFieldServiceAccountCredential)) + if err != nil { + return err + } + googleOAuthConfig.ServiceAccountCredential = value + } + + // Call provider to testLogin + userPrincipal, groupPrincipals, providerInfo, err := g.loginUser(request.Request.Context(), googleLogin, &googleOAuthConfig, true) + if err != nil { + if httperror.IsAPIError(err) { + return err + } + return fmt.Errorf("[Google OAuth] testAndApply: server error while authenticating: %v", err) + } + // if this works, save google oauth CR adding enabled flag + user, err := g.userMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + googleOAuthConfig.Enabled = googleOAuthConfigApplyInput.Enabled + err = g.saveGoogleOAuthConfigCR(&googleOAuthConfig) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("testAndApply: Failed to save google oauth config: %v", err)) + } + + userExtraInfo := g.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return g.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to create or update userAttribute: %v", err)) + } + + return g.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, providerInfo, 0, "Token via Google OAuth Configuration", request) + +} + +func (g *googleOauthProvider) formGoogleOAuthRedirectURL(goauthConfig *v32.GoogleOauthConfig) (string, error) { + return g.getRedirectURL([]byte(goauthConfig.OauthCredential)) +} + +func (g *googleOauthProvider) formGoogleOAuthRedirectURLFromMap(config map[string]interface{}) (string, error) { + clientCreds, ok := config[client.GoogleOauthConfigFieldOauthCredential].(string) + if !ok { + return "", fmt.Errorf("[Google OAuth] formGoogleOAuthRedirectURLFromMap: no creds file present") + } + value, err := common.ReadFromSecret(g.secrets, clientCreds, strings.ToLower(client.GoogleOauthConfigFieldOauthCredential)) + if err != nil { + return "", err + } + + return g.getRedirectURL([]byte(value)) +} + +func (g *googleOauthProvider) getRedirectURL(configFile []byte) (string, error) { + oauth2Config, err := google.ConfigFromJSON(configFile) + if err != nil { + return "", err + } + // Removing redirectURL from config because UI will set it + oauth2Config.RedirectURL = "" + // access type=offline and prompt=consent (approval force), return a refresh token + // UI will generate and validate the state + consentPageURL := oauth2Config.AuthCodeURL("", oauth2.AccessTypeOffline, oauth2.ApprovalForce) + return consentPageURL, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/types.go new file mode 100644 index 0000000..605f4f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/googleoauth/types.go @@ -0,0 +1,14 @@ +package googleoauth + +// Account defines properties an account on github has +type Account struct { + Email string `json:"email,omitempty"` + Name string `json:"name,omitempty"` + GivenName string `json:"given_name,omitempty"` + FamilyName string `json:"family_name,omitempty"` + PictureURL string `json:"picture,omitempty"` + SubjectUniqueID string `json:"sub,omitempty"` + EmailVerified bool `json:"email_verified,omitempty"` + HostedDomain string `json:"hd,omitempty"` + Type string +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_client.go new file mode 100644 index 0000000..21cda3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_client.go @@ -0,0 +1,216 @@ +package keycloakoidc + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +// account defines properties an account in keycloak has +type account struct { + ID string `json:"id,omitempty"` + Email string `json:"email,omitempty"` + EmailVerified bool `json:"emailVerified,omitempty"` + Username string `json:"username,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Name string `json:"firstName,omitempty"` + LastName string `json:"lastName,omitempty"` + Type string +} + +// Group defines properties a group in keycloak has +type Group struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Subgroups []Group `json:"subGroups,omitempty"` +} + +// KeyCloakClient implements a httpclient for keycloak +type KeyCloakClient struct { + httpClient *http.Client +} + +func (k *KeyCloakClient) searchPrincipals(searchTerm, principalType string, config *v32.OIDCConfig) ([]account, error) { + var accounts []account + sURL, err := getSearchURL(config.Issuer) + if err != nil { + return accounts, err + } + if principalType == "" || principalType == UserType { + var userAccounts []account + searchURL := fmt.Sprintf("%s/%ss?search=%s", sURL, UserType, searchTerm) + search := URLEncoded(searchURL) + + b, err := k.getFromKeyCloak(search) + if err != nil { + logrus.Errorf("[keycloak oidc] searchPrincipals: GET request failed. url: %s, err: %s", search, err) + return accounts, err + } + if err := json.Unmarshal(b, &userAccounts); err != nil { + logrus.Errorf("[keycloak oidc] searchPrincipals: received error unmarshalling search results, err: %v", err) + return accounts, err + } + for _, u := range userAccounts { + u.Type = UserType + accounts = append(accounts, u) + } + } + //checking the GroupSearchEnabled flag to ensure group principals are not returned if group mappers + //are not enabled. If group mappers are not enabled, it doesn't make sense to return groups as + //principals that could be authorized. + if (principalType == "" || principalType == GroupType) && *config.GroupSearchEnabled == true { + groupAccounts, err := k.groupSearch(searchTerm, sURL) + if err != nil { + return accounts, err + } + accounts = append(accounts, groupAccounts...) + } + return accounts, nil +} + +func (k *KeyCloakClient) groupSearch(searchTerm string, sURL string) ([]account, error) { + var groups []Group + var accounts []account + + searchURL := fmt.Sprintf("%s/%ss?search=%s", sURL, GroupType, searchTerm) + search := URLEncoded(searchURL) + + b, err := k.getFromKeyCloak(search) + if err != nil { + logrus.Errorf("[keycloak oidc] groupSearch: GET request failed. url: %s, err: %s", search, err) + return accounts, err + } + if err = json.Unmarshal(b, &groups); err != nil { + logrus.Errorf("[keycloak oidc] groupSearch: received error unmarshalling search results, err: %v", err) + return accounts, err + } + for _, g := range groups { + accounts = append(accounts, account{ID: g.ID, Name: g.Name, Type: GroupType}) + subGroups := getSubGroups(g) + for _, sg := range subGroups { + accounts = append(accounts, account{ID: sg.ID, Name: sg.Name, Type: GroupType}) + } + } + return accounts, nil +} + +func filterByGroupName(name string, accounts []account) account { + for _, group := range accounts { + if group.Name == name { + return group + } + } + return account{} +} + +func getSubGroups(group Group) []Group { + var groups []Group + if len(group.Subgroups) > 0 { + for i, sub := range group.Subgroups { + // setting an upper limit for how many subgroups we will loop through + // this value was chosen at random so can be changed if needed + if i < 100 { + groups = append(groups, sub) + groups = append(groups, getSubGroups(sub)...) + } + } + } + return groups +} + +func (k *KeyCloakClient) getFromKeyCloakByID(principalID, principalType string, config *v32.OIDCConfig) (account, error) { + var searchResult account + + if principalID == "" { + return searchResult, errors.Errorf("invalid id %v", principalID) + } + sURL, err := getSearchURL(config.Issuer) + if err != nil { + return searchResult, nil + } + // this will use the keycloak search endpoint with an id + if principalType == UserType { + searchURL := fmt.Sprintf("%s/%ss/%s", sURL, principalType, principalID) + search := URLEncoded(searchURL) + b, err := k.getFromKeyCloak(search) + if err != nil { + logrus.Errorf("[keycloak oidc] getFromKeyCloakByID: GET request failed. url: %s, err: %s", search, err) + return searchResult, err + } + if err := json.Unmarshal(b, &searchResult); err != nil { + logrus.Errorf("[keycloak oidc] getFromKeyCloakByID: received error unmarshalling search results, err: %v", err) + return searchResult, err + } + } else { + // when getting a users groups, we are only able to get the group name in some instances but + // you must have a group's id to utilize the keycloak by id search endpoint. + // to search by name, this uses the generic group search endpoint and then filters the result to the + // group name. group names are unique in keycloak. + accounts, err := k.groupSearch(principalID, sURL) + if err != nil { + return searchResult, err + } + searchResult = filterByGroupName(principalID, accounts) + return searchResult, nil + } + return searchResult, nil +} + +func getSearchURL(issuer string) (string, error) { + iss := strings.SplitAfter(issuer, "/auth/") // keycloak < 19 has auth prefix + if len(iss) == 2 { + return fmt.Sprintf("%sadmin/%s", iss[0], iss[1]), nil + } + iss = strings.SplitN(issuer, "/realms/", 2) // keycloak >= 19 doesn't have auth prefix + if len(iss) == 2 { + return fmt.Sprintf("%s/admin/realms/%s", iss[0], iss[1]), nil + } + return "", fmt.Errorf("can't parse issuer url") +} + +// URLEncoded encodes the string +func URLEncoded(str string) string { + u, err := url.Parse(str) + if err != nil { + logrus.Errorf("[keycloak oidc] URLEncoded: Error encoding the url: %s, error: %v", str, err) + return str + } + return u.String() +} + +func (k *KeyCloakClient) getFromKeyCloak(url string) ([]byte, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + req.Header.Add("Accept", "application/json") + resp, err := k.httpClient.Do(req) + if err != nil { + logrus.Errorf("[keycloak oidc] getFromKeyCloak: received error from keycloak: %v", err) + return nil, err + } + defer resp.Body.Close() + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return b, err + } + switch resp.StatusCode { + case 200: + case 201: + case 403: + return b, httperror.NewAPIError(httperror.PermissionDenied, "access denied") + case 401: + return b, httperror.NewAPIError(httperror.Unauthorized, "invalid token") + default: + return b, err + } + return b, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_provider.go new file mode 100644 index 0000000..b906112 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/keycloakoidc/keycloak_provider.go @@ -0,0 +1,185 @@ +package keycloakoidc + +import ( + "context" + "encoding/json" + "reflect" + "strings" + + gooidc "github.com/coreos/go-oidc/v3/oidc" + "github.com/pkg/errors" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/oidc" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "golang.org/x/oauth2" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + Name = "keycloakoidc" + UserType = "user" + GroupType = "group" +) + +type keyCloakOIDCProvider struct { + oidc.OpenIDCProvider +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + return &keyCloakOIDCProvider{ + oidc.OpenIDCProvider{ + Name: Name, + Type: client.KeyCloakOIDCConfigType, + CTX: ctx, + AuthConfigs: mgmtCtx.Management.AuthConfigs(""), + Secrets: mgmtCtx.Core.Secrets(""), + UserMGR: userMGR, + TokenMGR: tokenMGR, + }, + } +} + +func (k *keyCloakOIDCProvider) GetName() string { + return Name +} + +func (k *keyCloakOIDCProvider) newClient(config *v32.OIDCConfig, token v3.Token) (*KeyCloakClient, error) { + // creating context for new client and for refreshing oauth token if needed + ctx, err := oidc.AddCertKeyToContext(context.Background(), config.Certificate, config.PrivateKey) + if err != nil { + return nil, err + } + provider, err := gooidc.NewProvider(ctx, config.Issuer) + if err != nil { + return nil, err + } + oauthConfig := oidc.ConfigToOauthConfig(provider.Endpoint(), config) + // get, refresh and update token + oauthToken, err := k.getRefreshAndUpdateToken(ctx, oauthConfig, token) + if err != nil { + return nil, err + } + keyCloakClient := &KeyCloakClient{ + httpClient: oauthConfig.Client(ctx, oauthToken), + } + + return keyCloakClient, err +} + +func (k *keyCloakOIDCProvider) SearchPrincipals(searchValue, principalType string, token v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + var err error + + config, err := k.GetOIDCConfig() + if err != nil { + return principals, err + } + keyCloakClient, err := k.newClient(config, token) + if err != nil { + logrus.Errorf("[keycloak oidc] SsearchPrincipals: error creating new http client: %v", err) + return principals, err + } + accts, err := keyCloakClient.searchPrincipals(searchValue, principalType, config) + if err != nil { + logrus.Errorf("[keycloak oidc] SearchPrincipals: problem searching keycloak: %v", err) + return principals, err + } + for _, acct := range accts { + p := k.toPrincipal(acct.Type, acct, &token) + principals = append(principals, p) + } + return principals, nil +} + +func (k *keyCloakOIDCProvider) toPrincipal(principalType string, acct account, token *v3.Token) v3.Principal { + displayName := acct.Name + if displayName == "" { + displayName = acct.Username + } + princ := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: k.GetName() + "_" + principalType + "://" + acct.ID}, + DisplayName: displayName, + LoginName: acct.Username, + Provider: k.GetName(), + Me: false, + } + + if principalType == UserType { + princ.PrincipalType = UserType + if token != nil { + princ.Me = k.IsThisUserMe(token.UserPrincipal, princ) + } + } else { + princ.PrincipalType = GroupType + princ.ObjectMeta = metav1.ObjectMeta{Name: k.GetName() + "_" + principalType + "://" + acct.Name} + if token != nil { + princ.MemberOf = k.TokenMGR.IsMemberOf(*token, princ) + } + } + return princ +} + +func (k *keyCloakOIDCProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + config, err := k.GetOIDCConfig() + if err != nil { + return v3.Principal{}, err + } + var externalID string + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return v3.Principal{}, errors.Errorf("invalid id %v", principalID) + } + externalID = strings.TrimPrefix(parts[1], "//") + parts = strings.SplitN(parts[0], "_", 2) + if len(parts) != 2 { + return v3.Principal{}, errors.Errorf("invalid id %v", principalID) + } + principalType := parts[1] + keyCloakClient, err := k.newClient(config, token) + if err != nil { + logrus.Errorf("[keycloak oidc] GetPrincipal: error creating new http client: %v", err) + return v3.Principal{}, err + } + acct, err := keyCloakClient.getFromKeyCloakByID(externalID, principalType, config) + if err != nil { + return v3.Principal{}, err + } + princ := k.toPrincipal(principalType, acct, &token) + return princ, err +} + +func (k *keyCloakOIDCProvider) getRefreshAndUpdateToken(ctx context.Context, oauthConfig oauth2.Config, token v3.Token) (*oauth2.Token, error) { + var oauthToken *oauth2.Token + storedOauthToken, err := k.TokenMGR.GetSecret(token.UserID, token.AuthProvider, []*v3.Token{&token}) + if err := json.Unmarshal([]byte(storedOauthToken), &oauthToken); err != nil { + return oauthToken, err + } + if err != nil { + if !apierrors.IsNotFound(err) { + return oauthToken, err + } + oauthToken.AccessToken = token.ProviderInfo["access_token"] + } + // Valid will return false if access token is expired + if !oauthToken.Valid() { + // since token is not valid, the TokenSource func used in the Client func will attempt to refresh the access token + // if the refresh token has not expired + logrus.Debugf("[generic oidc] RefeshAndUpdateToken: attempting to refresh access token") + } + reusedToken, err := oauth2.ReuseTokenSource(oauthToken, oauthConfig.TokenSource(ctx, oauthToken)).Token() + if err != nil { + return oauthToken, err + } + + if !reflect.DeepEqual(oauthToken, reusedToken) { + k.UpdateToken(reusedToken, token.UserID) + } + return reusedToken, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_actions.go new file mode 100644 index 0000000..faa803d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_actions.go @@ -0,0 +1,146 @@ +package ldap + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/client-go/util/retry" +) + +func (p *ldapProvider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "testAndApply") +} + +func (p *ldapProvider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, p.providerName, p.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "testAndApply" { + return p.testAndApply(request) + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (p *ldapProvider) testAndApply(request *types.APIContext) error { + var input map[string]interface{} + var err error + input, err = handler.ParseAndValidateActionBody(request, request.Schemas.Schema(&managementschema.Version, + p.testAndApplyInputType)) + + if err != nil { + return err + } + + configApplyInput := &v32.LdapTestAndApplyInput{} + + if err := common.Decode(input, configApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("Failed to parse body: %v", err)) + } + + config := &configApplyInput.LdapConfig + + login := &v32.BasicLogin{ + Username: configApplyInput.Username, + Password: configApplyInput.Password, + } + + if config.ServiceAccountPassword != "" { + value, err := common.ReadFromSecret(p.secrets, config.ServiceAccountPassword, + strings.ToLower(client.LdapConfigFieldServiceAccountPassword)) + if err != nil { + return err + } + config.ServiceAccountPassword = value + } + + caPool, err := ldap.NewCAPool(config.Certificate) + if err != nil { + return err + } + + if len(config.Servers) < 1 { + return httperror.NewAPIError(httperror.InvalidBodyContent, "must supply a server") + } + + lConn, err := ldap.Connect(config, caPool) + if err != nil { + return err + } + defer lConn.Close() + + userPrincipal, groupPrincipals, err := p.loginUser(lConn, login, config, caPool) + if err != nil { + return err + } + + //if this works, save LDAPConfig CR adding enabled flag + config.Enabled = configApplyInput.Enabled + err = p.saveLDAPConfig(config) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to save %s config: %v", p.providerName, err)) + } + + user, err := p.userMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + userExtraInfo := p.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return p.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("Failed to create or update userAttribute: %v", err)) + } + + return p.tokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, "", 0, "Token via LDAP Configuration", request) +} + +func (p *ldapProvider) saveLDAPConfig(config *v3.LdapConfig) error { + storedConfig, _, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + if p.providerName == "openldap" { + config.Type = client.OpenLdapConfigType + } else { + config.Type = client.FreeIpaConfigType + } + + config.ObjectMeta = storedConfig.ObjectMeta + + field := strings.ToLower(client.LdapConfigFieldServiceAccountPassword) + name, err := common.CreateOrUpdateSecrets(p.secrets, config.ServiceAccountPassword, + field, strings.ToLower(config.Type)) + if err != nil { + return err + } + + config.ServiceAccountPassword = name + + logrus.Debugf("updating %s config", p.providerName) + _, err = p.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + if err != nil { + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client.go new file mode 100644 index 0000000..8504454 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client.go @@ -0,0 +1,542 @@ +package ldap + +import ( + "crypto/x509" + "fmt" + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var operationalAttrList = []string{"1.1", "+", "*"} + +func (p *ldapProvider) loginUser(lConn ldapv3.Client, credential *v32.BasicLogin, config *v3.LdapConfig, caPool *x509.CertPool) (v3.Principal, []v3.Principal, error) { + logrus.Debug("Now generating Ldap token") + + username := credential.Username + password := credential.Password + + if password == "" { + return v3.Principal{}, nil, httperror.NewAPIError(httperror.MissingRequired, "password not provided") + } + + serviceAccountPassword := config.ServiceAccountPassword + serviceAccountUserName := config.ServiceAccountDistinguishedName + err := ldap.AuthenticateServiceAccountUser(serviceAccountPassword, serviceAccountUserName, "", lConn) + if err != nil { + return v3.Principal{}, nil, err + } + + logrus.Debug("Binding username password") + + filter := fmt.Sprintf( + "(&(%v=%v)(%v=%v))", + ObjectClass, config.UserObjectClass, + config.UserLoginAttribute, ldapv3.EscapeFilter(username), + ) + + searchRequest := ldap.NewWholeSubtreeSearchRequest( + config.UserSearchBase, + filter, + config.GetUserSearchAttributes(ObjectClass), + ) + + result, err := lConn.Search(searchRequest) + if err != nil { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") // need to reload this error + } + + if len(result.Entries) < 1 { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "Cannot locate user information for "+searchRequest.Filter) + } else if len(result.Entries) > 1 { + return v3.Principal{}, nil, fmt.Errorf("ldap user search found more than one result") + } + + userDN := result.Entries[0].DN //userDN is externalID + err = lConn.Bind(userDN, password) + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed: invalid credentials") + } + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.ServerError, "server error while authenticating") + } + + searchOpRequest := ldap.NewWholeSubtreeSearchRequest( + userDN, + fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass), + operationalAttrList, + ) + + opResult, err := lConn.Search(searchOpRequest) + if err != nil { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") // need to reload this error + } + + if len(opResult.Entries) < 1 { + return v3.Principal{}, nil, httperror.WrapAPIError(err, httperror.Unauthorized, "Cannot locate user information for "+searchOpRequest.Filter) + } + + userPrincipal, groupPrincipals, err := p.getPrincipalsFromSearchResult(result, opResult, config, lConn) + if err != nil { + return v3.Principal{}, nil, err + } + + allowed, err := p.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipal.Name, groupPrincipals) + if err != nil { + return v3.Principal{}, nil, err + } + if !allowed { + return v3.Principal{}, nil, httperror.NewAPIError(httperror.PermissionDenied, "Permission denied") + } + + return userPrincipal, groupPrincipals, err +} + +func (p *ldapProvider) getPrincipalsFromSearchResult(result *ldapv3.SearchResult, opResult *ldapv3.SearchResult, config *v3.LdapConfig, lConn ldapv3.Client) (v3.Principal, []v3.Principal, error) { + var groupPrincipals []v3.Principal + var userPrincipal v3.Principal + var nonDupGroupPrincipals []v3.Principal + var userScope, groupScope string + var nestedGroupPrincipals []v3.Principal + var freeipaNonEntrydnApproach bool + + groupMap := make(map[string]bool) + entry := result.Entries[0] + userAttributes := entry.Attributes + + if !p.permissionCheck(userAttributes, config) { + return v3.Principal{}, nil, fmt.Errorf("Permission denied") + } + + logrus.Debugf("getPrincipals: user attributes: %v ", userAttributes) + + userMemberAttribute := entry.GetAttributeValues(config.UserMemberAttribute) + if len(userMemberAttribute) == 0 { + userMemberAttribute = opResult.Entries[0].GetAttributeValues(config.UserMemberAttribute) + } + + logrus.Debugf("SearchResult memberOf attribute {%s}", userMemberAttribute) + + if !ldap.IsType(userAttributes, config.UserObjectClass) { + logrus.Debugf("The objectClass %s was not found in the user attributes", config.UserObjectClass) + return v3.Principal{}, nil, nil + } + + userScope = p.userScope + groupScope = p.groupScope + + user, err := ldap.AttributesToPrincipal(entry.Attributes, result.Entries[0].DN, userScope, p.providerName, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + return v3.Principal{}, groupPrincipals, err + } + + userPrincipal = *user + userDN := result.Entries[0].DN + + if len(userMemberAttribute) > 0 { + for i := 0; i < len(userMemberAttribute); i += 50 { + batchGroupDN := userMemberAttribute[i:min(i+50, len(userMemberAttribute))] + filter := fmt.Sprintf("(%v=%v)", ObjectClass, config.GroupObjectClass) + query := "(|" + for _, gdn := range batchGroupDN { + query += fmt.Sprintf("(%v=%v)", config.GroupDNAttribute, ldapv3.EscapeFilter(gdn)) + } + query += ")" + query = fmt.Sprintf("(&%v%v)", filter, query) + // Pulling user's groups + logrus.Debugf("Ldap: Query for pulling user's groups: %v", query) + userMemberGroupPrincipals, err := p.searchLdap(query, groupScope, config, lConn) + groupPrincipals = append(groupPrincipals, userMemberGroupPrincipals...) + if err != nil { + return userPrincipal, groupPrincipals, err + } + } + } + + opEntry := opResult.Entries[0] + opAttributes := opEntry.Attributes + + groupMemberUserAttribute := entry.GetAttributeValues(config.GroupMemberUserAttribute) + if len(groupMemberUserAttribute) == 0 { + for _, attr := range opAttributes { + if attr.Name == config.GroupMemberUserAttribute { + groupMemberUserAttribute = attr.Values + } + } + } + + if len(groupMemberUserAttribute) > 0 { + query := fmt.Sprintf("(&(%v=%v)(%v=%v))", config.GroupMemberMappingAttribute, ldapv3.EscapeFilter(groupMemberUserAttribute[0]), ObjectClass, config.GroupObjectClass) + newGroupPrincipals, err := p.searchLdap(query, groupScope, config, lConn) + //deduplicate groupprincipals get from userMemberAttribute + nonDupGroupPrincipals = ldap.FindNonDuplicateBetweenGroupPrincipals(newGroupPrincipals, groupPrincipals, nonDupGroupPrincipals) + groupPrincipals = append(groupPrincipals, nonDupGroupPrincipals...) + if err != nil { + return userPrincipal, groupPrincipals, err + } + } + + if len(groupPrincipals) == 0 { + // In case of Freeipa, some servers might not have entrydn attribute, so we can't use it to get details of all groups returned when user logged in. + // So we run a separate query with the filer: (&(member=uid of user logging in)(objectclass=groupofnames)) + // This returns all details of a user's groups that we need to create principals, but doesn't return nested membership, + // so we derive nested membership using the logic we have for openldap + logrus.Debugf("EntryDN attribute not returned, retrieving group membership using the member attribute") + // didn't get the entrydn as expected, so use query with member attribute and manually gather nested group + query := fmt.Sprintf("(&(%v=%v)(%v=%v))", config.GroupMemberMappingAttribute, ldapv3.EscapeFilter(userDN), ObjectClass, config.GroupObjectClass) + groupPrincipals, err = p.searchLdap(query, groupScope, config, lConn) + if err != nil { + return userPrincipal, groupPrincipals, err + } + logrus.Debugf("Retrieved following groups using member attribute: %v", groupPrincipals) + freeipaNonEntrydnApproach = true + } + // Handle nestedgroups for openldap, filter operationalAttrList already handles nestedgroups for freeipa + if (config.NestedGroupMembershipEnabled && groupScope == "openldap_group") || freeipaNonEntrydnApproach { + searchDomain := config.UserSearchBase + if config.GroupSearchBase != "" { + searchDomain = config.GroupSearchBase + } + + // Handling nestedgroups: tracing from down to top in order to find the parent groups, parent parent groups, and so on... + // When traversing up, we note down all the parent groups and add them to groupPrincipals + commonConfig := ldap.ConfigAttributes{ + GroupMemberMappingAttribute: config.GroupMemberMappingAttribute, + GroupNameAttribute: config.GroupNameAttribute, + GroupObjectClass: config.GroupObjectClass, + GroupSearchAttribute: config.GroupSearchAttribute, + ObjectClass: ObjectClass, + ProviderName: OpenLdapName, + UserLoginAttribute: config.UserLoginAttribute, + UserNameAttribute: config.UserNameAttribute, + UserObjectClass: config.UserObjectClass, + } + searchAttributes := []string{config.GroupMemberUserAttribute, config.GroupMemberMappingAttribute, ObjectClass, config.GroupObjectClass, config.UserLoginAttribute, + config.GroupNameAttribute, config.GroupSearchAttribute} + for _, groupPrincipal := range groupPrincipals { + err = ldap.GatherParentGroups(groupPrincipal, searchDomain, groupScope, &commonConfig, lConn, groupMap, &nestedGroupPrincipals, searchAttributes) + if err != nil { + return userPrincipal, groupPrincipals, nil + } + } + nonDupGroupPrincipals = ldap.FindNonDuplicateBetweenGroupPrincipals(nestedGroupPrincipals, groupPrincipals, []v3.Principal{}) + groupPrincipals = append(groupPrincipals, nonDupGroupPrincipals...) + } + + return userPrincipal, groupPrincipals, nil +} + +func (p *ldapProvider) getPrincipal(distinguishedName string, scope string, config *v3.LdapConfig, caPool *x509.CertPool) (*v3.Principal, error) { + var search *ldapv3.SearchRequest + var filter string + if (scope != p.userScope) && (scope != p.groupScope) { + return nil, fmt.Errorf("Invalid scope") + } + + var attributes []*ldapv3.AttributeTypeAndValue + var attribs []*ldapv3.EntryAttribute + object, err := ldapv3.ParseDN(distinguishedName) + if err != nil { + return nil, err + } + + for _, rdns := range object.RDNs { + for _, attr := range rdns.Attributes { + attributes = append(attributes, attr) + entryAttr := ldapv3.NewEntryAttribute(attr.Type, []string{attr.Value}) + attribs = append(attribs, entryAttr) + } + } + + if !ldap.IsType(attribs, scope) && !p.permissionCheck(attribs, config) { + logrus.Errorf("Failed to get object %v", distinguishedName) + return nil, nil + } + + entityType := strings.Split(scope, "_")[1] + if strings.EqualFold("user", entityType) { + filter = fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass) + } else { + filter = fmt.Sprintf("(%v=%v)", ObjectClass, config.GroupObjectClass) + } + + logrus.Debugf("Query for getPrincipal(%v): %v", distinguishedName, filter) + + lConn, err := ldap.Connect(config, caPool) + if err != nil { + return nil, err + } + defer lConn.Close() + // Bind before query + // If service acc bind fails, and auth is on, return principal formed using DN + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountDistinguishedName, "") + err = lConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + + if err != nil { + if ldapv3.IsErrorWithCode(err, ldapv3.LDAPResultInvalidCredentials) && config.Enabled { + var kind string + if strings.EqualFold("user", entityType) { + kind = "user" + } else if strings.EqualFold("group", entityType) { + kind = "group" + } + principal := &v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: scope + "://" + distinguishedName}, + DisplayName: distinguishedName, + LoginName: distinguishedName, + PrincipalType: kind, + } + + return principal, nil + } + return nil, fmt.Errorf("Error in ldap bind: %v", err) + } + + var attrs []string + if strings.EqualFold("user", entityType) { + attrs = config.GetUserSearchAttributes(ObjectClass) + } else { + attrs = config.GetGroupSearchAttributes(ObjectClass) + } + + search = ldap.NewBaseObjectSearchRequest( + distinguishedName, + filter, + attrs, + ) + + result, err := lConn.Search(search) + if err != nil { + if ldapErr, ok := err.(*ldapv3.Error); ok && ldapErr.ResultCode == 32 { + return nil, httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("%v not found", distinguishedName)) + } + return nil, httperror.WrapAPIError(errors.Wrapf(err, "server returned error for search %v %v: %v", search.BaseDN, filter, err), httperror.ServerError, "Internal server error") + } + + if len(result.Entries) < 1 { + return nil, fmt.Errorf("No identities can be retrieved") + } else if len(result.Entries) > 1 { + return nil, fmt.Errorf("More than one result found") + } + + entry := result.Entries[0] + entryAttributes := entry.Attributes + + if !p.permissionCheck(entry.Attributes, config) { + return nil, fmt.Errorf("Permission denied") + } + + principal, err := ldap.AttributesToPrincipal(entryAttributes, distinguishedName, scope, p.providerName, config.UserObjectClass, config.UserNameAttribute, config.UserLoginAttribute, config.GroupObjectClass, config.GroupNameAttribute) + if err != nil { + return nil, err + } + return principal, nil +} + +func (p *ldapProvider) searchPrincipals(name, principalType string, config *v3.LdapConfig, lConn ldapv3.Client) ([]v3.Principal, error) { + name = ldapv3.EscapeFilter(name) + var principals []v3.Principal + + if principalType == "" || principalType == "user" { + userPrincipals, err := p.searchUser(name, config, lConn) + if err != nil { + return nil, err + } + principals = append(principals, userPrincipals...) + } + + if principalType == "" || principalType == "group" { + groupPrincipals, err := p.searchGroup(name, config, lConn) + if err != nil { + return nil, err + } + principals = append(principals, groupPrincipals...) + } + + return principals, nil +} + +func (p *ldapProvider) searchUser(name string, config *v3.LdapConfig, lConn ldapv3.Client) ([]v3.Principal, error) { + srchAttributes := strings.Split(config.UserSearchAttribute, "|") + query := fmt.Sprintf("(&(%v=%v)", ObjectClass, config.UserObjectClass) + srchAttrs := "(|" + for _, attr := range srchAttributes { + if attr == "uidNumber" { + // specific integer match, can't use wildcard + srchAttrs += fmt.Sprintf("(%v=%v)", attr, name) + } else { + srchAttrs += fmt.Sprintf("(%v=%v*)", attr, name) + } + } + // The user search filter will be added as another and clause + // and is expected to follow ldap syntax and enclosed in parenthesis + query += srchAttrs + ")" + config.UserSearchFilter + ")" + logrus.Debugf("%s searchUser query: %s", p.providerName, query) + return p.searchLdap(query, p.userScope, config, lConn) +} + +func (p *ldapProvider) searchGroup(name string, config *v3.LdapConfig, lConn ldapv3.Client) ([]v3.Principal, error) { + searchFmt := config.GroupSearchAttribute + "=*%s*" + if config.GroupSearchAttribute == "gidNumber" { + // specific integer match, can't use wildcard + searchFmt = config.GroupSearchAttribute + "=%s" + } + + query := "(&(" + ObjectClass + "=" + config.GroupObjectClass + ")(" + fmt.Sprintf(searchFmt, name) + ")" + config.GroupSearchFilter + ")" + logrus.Debugf("%s searchGroup query: %s scope: %s", p.providerName, query, p.groupScope) + return p.searchLdap(query, p.groupScope, config, lConn) +} + +func (p *ldapProvider) searchLdap(query string, scope string, config *v3.LdapConfig, lConn ldapv3.Client) ([]v3.Principal, error) { + var principals []v3.Principal + var search *ldapv3.SearchRequest + + entityType := strings.Split(scope, "_")[1] + searchDomain := config.UserSearchBase + if strings.EqualFold("user", entityType) { + search = ldap.NewWholeSubtreeSearchRequest( + searchDomain, + query, + config.GetUserSearchAttributes(ObjectClass), + ) + } else { + if config.GroupSearchBase != "" { + searchDomain = config.GroupSearchBase + } + search = ldap.NewWholeSubtreeSearchRequest( + searchDomain, + query, + config.GetGroupSearchAttributes(ObjectClass), + ) + } + + // Bind before query + serviceAccountUsername := ldap.GetUserExternalID(config.ServiceAccountDistinguishedName, "") + err := lConn.Bind(serviceAccountUsername, config.ServiceAccountPassword) + if err != nil { + return nil, fmt.Errorf("Error %v in ldap bind", err) + } + + results, err := lConn.SearchWithPaging(search, 1000) + if err != nil { + ldapErr, ok := reflect.ValueOf(err).Interface().(*ldapv3.Error) + if ok && ldapErr.ResultCode != ldapv3.LDAPResultNoSuchObject { + return []v3.Principal{}, fmt.Errorf("When searching ldap, Failed to search: %s, error: %#v", query, err) + } + } + + for i := 0; i < len(results.Entries); i++ { + externalID := results.Entries[i].DN + entry := results.Entries[i] + + if p.samlSearchProvider() { + if strings.EqualFold("user", entityType) { + userLoginValues := ldap.GetAttributeValuesByName(entry.Attributes, config.UserLoginAttribute) + if len(userLoginValues) > 0 { + externalID = userLoginValues[0] // only support first + } + } else { + groupDNValues := ldap.GetAttributeValuesByName(entry.Attributes, config.GroupDNAttribute) + if len(groupDNValues) > 0 { + externalID = groupDNValues[0] // only support first + } + } + } + + principal, err := ldap.AttributesToPrincipal( + entry.Attributes, + externalID, + scope, + p.providerName, + config.UserObjectClass, + config.UserNameAttribute, + config.UserLoginAttribute, + config.GroupObjectClass, + config.GroupNameAttribute) + if err != nil { + return []v3.Principal{}, err + } + principals = append(principals, *principal) + } + + return principals, nil +} + +func (p *ldapProvider) permissionCheck(attributes []*ldapv3.EntryAttribute, config *v3.LdapConfig) bool { + userObjectClass := config.UserObjectClass + userEnabledAttribute := config.UserEnabledAttribute + userDisabledBitMask := config.UserDisabledBitMask + return ldap.HasPermission(attributes, userObjectClass, userEnabledAttribute, userDisabledBitMask) +} + +func (p *ldapProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + config, caPool, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + return nil, err + } + lConn, err := ldap.Connect(config, caPool) + if err != nil { + return nil, err + } + defer lConn.Close() + + serviceAccountPassword := config.ServiceAccountPassword + serviceAccountUserName := config.ServiceAccountDistinguishedName + err = ldap.AuthenticateServiceAccountUser(serviceAccountPassword, serviceAccountUserName, "", lConn) + if err != nil { + return nil, err + } + + distinguishedName, _, err := p.getDNAndScopeFromPrincipalID(principalID) + if err != nil { + return nil, err + } + + searchRequest := ldap.NewBaseObjectSearchRequest( + distinguishedName, + fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass), + config.GetUserSearchAttributes(ObjectClass), + ) + + result, err := lConn.Search(searchRequest) + if err != nil { + return nil, errors.New("no access") + } + + if len(result.Entries) < 1 { + return nil, httperror.WrapAPIError(err, httperror.Unauthorized, "Cannot locate user information for "+searchRequest.Filter) + } else if len(result.Entries) > 1 { + return nil, fmt.Errorf("ldap user search found more than one result") + } + + userDN := result.Entries[0].DN //userDN is externalID + + searchOpRequest := ldap.NewBaseObjectSearchRequest( + userDN, + fmt.Sprintf("(%v=%v)", ObjectClass, config.UserObjectClass), + operationalAttrList, + ) + opResult, err := lConn.Search(searchOpRequest) + if err != nil { + return nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") // need to reload this error + } + + if len(opResult.Entries) < 1 { + return nil, httperror.WrapAPIError(err, httperror.Unauthorized, "Cannot locate user information for "+searchOpRequest.Filter) + } + + _, groupPrincipals, err := p.getPrincipalsFromSearchResult(result, opResult, config, lConn) + if err != nil { + return nil, err + } + return groupPrincipals, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client_test.go new file mode 100644 index 0000000..d749c44 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_client_test.go @@ -0,0 +1,323 @@ +package ldap + +import ( + "context" + "crypto/tls" + "crypto/x509" + "reflect" + "testing" + "time" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/pkg/errors" + + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/tokens" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/user" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apitypes "k8s.io/apimachinery/pkg/types" +) + +const ( + DummySAUsername = "satestuser1" + DummySAUPassword = "sapassword123" + UserObjectClassName = "inetOrgPerson" +) + +func Test_ldapProvider_loginUser(t *testing.T) { + type fields struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + userMGR mockUserManager + tokenMGR *tokens.Manager + certs string + caPool *x509.CertPool + providerName string + testAndApplyInputType string + userScope string + groupScope string + } + type args struct { + lConn ldapv3.Client + credential *v32.BasicLogin + config *v3.LdapConfig + caPool *x509.CertPool + } + tests := []struct { + name string + fields fields + args args + wantUserPrincipal v3.Principal + wantGroupPrincipals []v3.Principal + wantErr bool + }{ + { + name: "successful user login", + fields: fields{ + userMGR: mockUserManager{ + hasAccess: true, + }, + tokenMGR: &tokens.Manager{}, + caPool: &x509.CertPool{}, + userScope: "providername_user", + groupScope: "providername_group", + }, + args: args{ + lConn: newMockLdapConnClient(), + credential: &v32.BasicLogin{ + Username: DummyUsername, + Password: DummyPassword, + }, + config: &v3.LdapConfig{ + LdapFields: v32.LdapFields{ + ServiceAccountDistinguishedName: DummySAUsername, + ServiceAccountPassword: DummySAUPassword, + UserObjectClass: UserObjectClassName, + }, + }, + caPool: &x509.CertPool{}, + }, + wantUserPrincipal: v3.Principal{ + ObjectMeta: v1.ObjectMeta{ + Name: "providername_user://ldap.test.domain", + }, + PrincipalType: "user", + Me: true, + }, + wantGroupPrincipals: []v3.Principal{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "providername_group://ldap.test.domain", + }, + PrincipalType: "user", + Me: true, + }, + }, + wantErr: false, + }, + { + name: "user login with invalid credentials", + fields: fields{ + userMGR: mockUserManager{ + hasAccess: false, + }, + tokenMGR: &tokens.Manager{}, + caPool: &x509.CertPool{}, + userScope: "providername_user", + groupScope: "providername_group", + }, + args: args{ + lConn: &mockLdapConn{ + canAuthenticate: false, + }, + credential: &v32.BasicLogin{ + Username: DummyUsername, + Password: DummyPassword, + }, + config: &v3.LdapConfig{ + LdapFields: v32.LdapFields{ + ServiceAccountDistinguishedName: DummySAUsername, + ServiceAccountPassword: DummySAUPassword, + UserObjectClass: UserObjectClassName, + }, + }, + caPool: &x509.CertPool{}, + }, + wantUserPrincipal: v3.Principal{}, + wantGroupPrincipals: nil, + wantErr: true, + }, + { + name: "user login without access permissions", + fields: fields{ + userMGR: mockUserManager{ + hasAccess: false, + }, + tokenMGR: &tokens.Manager{}, + caPool: &x509.CertPool{}, + userScope: "providername_user", + groupScope: "providername_group", + }, + args: args{ + lConn: newMockLdapConnClient(), + credential: &v32.BasicLogin{ + Username: DummyUsername, + Password: DummyPassword, + }, + config: &v3.LdapConfig{ + LdapFields: v32.LdapFields{ + ServiceAccountDistinguishedName: DummySAUsername, + ServiceAccountPassword: DummySAUPassword, + UserObjectClass: UserObjectClassName, + }, + }, + caPool: &x509.CertPool{}, + }, + wantUserPrincipal: v3.Principal{}, + wantGroupPrincipals: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &ldapProvider{ + ctx: tt.fields.ctx, + authConfigs: tt.fields.authConfigs, + secrets: tt.fields.secrets, + userMGR: tt.fields.userMGR, + tokenMGR: tt.fields.tokenMGR, + certs: tt.fields.certs, + caPool: tt.fields.caPool, + providerName: tt.fields.providerName, + testAndApplyInputType: tt.fields.testAndApplyInputType, + userScope: tt.fields.userScope, + groupScope: tt.fields.groupScope, + } + gotUserPrincipal, gotGroupPrincipals, err := p.loginUser(tt.args.lConn, tt.args.credential, tt.args.config, tt.args.caPool) + if (err != nil) != tt.wantErr { + t.Errorf("ldapProvider.loginUser() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotUserPrincipal, tt.wantUserPrincipal) { + t.Errorf("ldapProvider.loginUser() got = %v, want %v", gotUserPrincipal, tt.wantUserPrincipal) + } + if !reflect.DeepEqual(gotGroupPrincipals, tt.wantGroupPrincipals) { + t.Errorf("ldapProvider.loginUser() got1 = %v, want %v", gotGroupPrincipals, tt.wantGroupPrincipals) + } + }) + } +} + +type mockLdapConn struct { + SimpleBindResponse *ldapv3.SimpleBindResult + PasswordModifyResponse *ldapv3.PasswordModifyResult + SearchResponse *ldapv3.SearchResult + canAuthenticate bool +} + +func (m mockLdapConn) Start() { + panic("unimplemented") +} +func (m mockLdapConn) StartTLS(*tls.Config) error { + panic("unimplemented") +} +func (m mockLdapConn) Close() { + panic("unimplemented") +} +func (m mockLdapConn) IsClosing() bool { + panic("unimplemented") +} +func (m mockLdapConn) SetTimeout(time.Duration) { + panic("unimplemented") +} +func (m mockLdapConn) Bind(username, password string) error { + if !m.canAuthenticate { + return ldapv3.NewError(ldapv3.LDAPResultInvalidCredentials, errors.New("ldap: invalid credentials")) + } + return nil +} +func (m mockLdapConn) UnauthenticatedBind(username string) error { + panic("unimplemented") +} +func (m mockLdapConn) SimpleBind(*ldapv3.SimpleBindRequest) (*ldapv3.SimpleBindResult, error) { + panic("unimplemented") +} +func (m mockLdapConn) ExternalBind() error { + panic("unimplemented") +} +func (m mockLdapConn) Add(*ldapv3.AddRequest) error { + panic("unimplemented") +} +func (m mockLdapConn) Del(*ldapv3.DelRequest) error { + panic("unimplemented") +} +func (m mockLdapConn) Modify(*ldapv3.ModifyRequest) error { + panic("unimplemented") +} +func (m mockLdapConn) ModifyDN(*ldapv3.ModifyDNRequest) error { + panic("unimplemented") +} +func (m mockLdapConn) ModifyWithResult(*ldapv3.ModifyRequest) (*ldapv3.ModifyResult, error) { + panic("unimplemented") +} +func (m mockLdapConn) Compare(dn, attribute, value string) (bool, error) { + panic("unimplemented") +} +func (m mockLdapConn) PasswordModify(*ldapv3.PasswordModifyRequest) (*ldapv3.PasswordModifyResult, error) { + panic("unimplemented") +} +func (m mockLdapConn) Search(*ldapv3.SearchRequest) (*ldapv3.SearchResult, error) { + return m.SearchResponse, nil +} +func (m mockLdapConn) SearchWithPaging(searchRequest *ldapv3.SearchRequest, pagingSize uint32) (*ldapv3.SearchResult, error) { + return m.SearchResponse, nil +} + +func newMockLdapConnClient() *mockLdapConn { + return &mockLdapConn{ + SimpleBindResponse: &ldapv3.SimpleBindResult{ + Controls: []ldapv3.Control{}, + }, + PasswordModifyResponse: &ldapv3.PasswordModifyResult{ + GeneratedPassword: "", + }, + SearchResponse: &ldapv3.SearchResult{ + Entries: []*ldapv3.Entry{ + { + DN: "ldap.test.domain", + Attributes: []*ldapv3.EntryAttribute{ + { + Name: "objectclass", + Values: []string{UserObjectClassName}, + }, + }, + }, + }, + Referrals: []string{}, + Controls: []ldapv3.Control{}, + }, + canAuthenticate: true, + } +} + +type mockUserManager struct { + hasAccess bool +} + +func (m mockUserManager) SetPrincipalOnCurrentUser(apiContext *types.APIContext, principal v3.Principal) (*v3.User, error) { + panic("unimplemented") +} +func (m mockUserManager) GetUser(apiContext *types.APIContext) string { + panic("unimplemented") +} +func (m mockUserManager) EnsureToken(input user.TokenInput) (string, error) { + panic("unimplemented") +} +func (m mockUserManager) EnsureClusterToken(clusterName string, input user.TokenInput) (string, error) { + panic("unimplemented") +} +func (m mockUserManager) DeleteToken(tokenName string) error { + panic("unimplemented") +} +func (m mockUserManager) EnsureUser(principalName, displayName string) (*v3.User, error) { + panic("unimplemented") +} +func (m mockUserManager) CheckAccess(accessMode string, allowedPrincipalIDs []string, userPrincipalID string, groups []v3.Principal) (bool, error) { + return m.hasAccess, nil +} +func (m mockUserManager) SetPrincipalOnCurrentUserByUserID(userID string, principal v3.Principal) (*v3.User, error) { + panic("unimplemented") +} +func (m mockUserManager) CreateNewUserClusterRoleBinding(userName string, userUID apitypes.UID) error { + panic("unimplemented") +} +func (m mockUserManager) GetUserByPrincipalID(principalName string) (*v3.User, error) { + panic("unimplemented") +} +func (m mockUserManager) GetKubeconfigToken(clusterName, tokenName, description, kind, userName string, userPrincipal v3.Principal) (*v3.Token, string, error) { + panic("unimplemented") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider.go new file mode 100644 index 0000000..ff74c4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider.go @@ -0,0 +1,425 @@ +package ldap + +import ( + "context" + "crypto/x509" + "errors" + "fmt" + "strings" + + ldapv3 "github.com/go-ldap/ldap/v3" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + OpenLdapName = "openldap" + FreeIpaName = "freeipa" + ShibbolethName = "shibboleth" + ObjectClass = "objectClass" + OKTAName = "okta" +) + +// An ErrorNotConfigured indicates that the requested LDAP operation +// failed due to missing or incomplete configuration. +type ErrorNotConfigured struct{} + +// Error provides a string representation of an ErrorNotConfigured +func (e ErrorNotConfigured) Error() string { + return "not configured" +} + +var ( + testAndApplyInputTypes = map[string]string{ + FreeIpaName: client.FreeIpaTestAndApplyInputType, + OpenLdapName: client.OpenLdapTestAndApplyInputType, + } + + // empty string for inline + ldapConfigKey = map[string]string{ + FreeIpaName: "", + OpenLdapName: "", + ShibbolethName: client.ShibbolethConfigFieldOpenLdapConfig, + OKTAName: client.OKTAConfigFieldOpenLdapConfig, + } +) + +type ldapProvider struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + userMGR user.Manager + tokenMGR *tokens.Manager + certs string + caPool *x509.CertPool + providerName string + testAndApplyInputType string + userScope string + groupScope string +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager, providerName string) common.AuthProvider { + return &ldapProvider{ + ctx: ctx, + authConfigs: mgmtCtx.Management.AuthConfigs(""), + secrets: mgmtCtx.Core.Secrets(""), + userMGR: userMGR, + tokenMGR: tokenMGR, + providerName: providerName, + testAndApplyInputType: testAndApplyInputTypes[providerName], + userScope: providerName + "_user", + groupScope: providerName + "_group", + } +} + +func GetLDAPConfig(authProvider common.AuthProvider) (*v3.LdapConfig, *x509.CertPool, error) { + ldapProvider, ok := authProvider.(*ldapProvider) + if !ok { + return nil, nil, fmt.Errorf("can not get ldap config from type other than ldapProvider") + } + + return ldapProvider.getLDAPConfig(ldapProvider.authConfigs.ObjectClient().UnstructuredClient()) +} + +// IsNotConfigured checks whether this error indicates a missing LDAP configuration. +func IsNotConfigured(err error) bool { + return errors.Is(err, ErrorNotConfigured{}) +} + +func (p *ldapProvider) GetName() string { + return p.providerName +} + +func (p *ldapProvider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = p.actionHandler + schema.Formatter = p.formatter +} + +func (p *ldapProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + ldap := common.TransformToAuthProvider(authConfig) + return ldap, nil +} + +func toBasicLogin(input interface{}) (*v32.BasicLogin, error) { + login, ok := input.(*v32.BasicLogin) + if !ok { + return nil, errors.New("unexpected input type") + } + return login, nil +} + +// AuthenticateUser takes in a context and user credentials, and authenticates the user against an LDAP server. +// Returns principal, slice of group principals, and any errors encountered. +func (p *ldapProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, err := toBasicLogin(input) + if err != nil { + return v3.Principal{}, nil, "", err + } + + config, caPool, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + return v3.Principal{}, nil, "", errors.New("can't find authprovider") + } + + lConn, err := ldap.Connect(config, caPool) + if err != nil { + return v3.Principal{}, nil, "", err + } + defer lConn.Close() + + principal, groupPrincipal, err := p.loginUser(lConn, login, config, caPool) + if err != nil { + return v3.Principal{}, nil, "", err + } + + return principal, groupPrincipal, "", err +} + +// searchKey can be user PrincipalID e.g. shibboleth_user://username with principalType of group for group search by user +func (p *ldapProvider) SearchPrincipals(searchKey, principalType string, myToken v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + var err error + + config, caPool, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + if IsNotConfigured(err) { + return principals, err + } + logrus.Warnf("ldap search principals failed to get ldap config: %s\n", err) + return principals, nil + } + + lConn, err := ldap.Connect(config, caPool) + if err != nil { + logrus.Warnf("ldap search principals failed to connect to ldap: %s\n", err) + return principals, nil + } + defer lConn.Close() + + principals, err = p.searchPrincipals(searchKey, principalType, config, lConn) + if err == nil { + for _, principal := range principals { + if principal.PrincipalType == "user" { + if p.isThisUserMe(myToken.UserPrincipal, principal) { + principal.Me = true + } + } else if principal.PrincipalType == "group" { + if p.isMemberOf(myToken.GroupPrincipals, principal) { + principal.MemberOf = true + } + } + } + } + + return principals, nil +} + +func (p *ldapProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + config, caPool, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + if IsNotConfigured(err) { + return v3.Principal{}, err + } + return v3.Principal{}, nil + } + + externalID, scope, err := p.getDNAndScopeFromPrincipalID(principalID) + if err != nil { + return v3.Principal{}, err + } + + var principal *v3.Principal + if p.samlSearchProvider() { + principal, err = p.samlSearchGetPrincipal(externalID, scope, config, caPool) + } else { + principal, err = p.getPrincipal(externalID, scope, config, caPool) + } + + if err != nil { + return v3.Principal{}, err + } + + if p.isThisUserMe(token.UserPrincipal, *principal) { + principal.Me = true + } + return *principal, err +} + +func (p *ldapProvider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (p *ldapProvider) isMemberOf(myGroups []v3.Principal, other v3.Principal) bool { + for _, mygroup := range myGroups { + if mygroup.ObjectMeta.Name == other.ObjectMeta.Name && mygroup.PrincipalType == other.PrincipalType { + return true + } + } + return false +} + +func (p *ldapProvider) getLDAPConfig(genericClient objectclient.GenericClient) (*v3.LdapConfig, *x509.CertPool, error) { + // TODO See if this can be simplified. also, this makes an api call everytime. find a better way + authConfigObj, err := genericClient.Get(p.providerName, metav1.GetOptions{}) + if err != nil { + return nil, nil, fmt.Errorf("failed to retrieve %s, error: %v", p.providerName, err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, nil, fmt.Errorf("failed to retrieve %s, cannot read k8s Unstructured data", p.providerName) + } + + storedLdapConfigMap := u.UnstructuredContent() + storedLdapConfig := &v3.LdapConfig{} + + if p.samlSearchProvider() && ldapConfigKey[p.providerName] != "" { + subLdapConfig, ok := storedLdapConfigMap[ldapConfigKey[p.providerName]] + if !ok { + return nil, nil, ErrorNotConfigured{} + } + + storedLdapConfigMap = subLdapConfig.(map[string]interface{}) + err = common.Decode(storedLdapConfigMap, storedLdapConfig) + if err != nil { + return nil, nil, fmt.Errorf("unable to decode Ldap Config: %w", err) + } + if len(storedLdapConfig.Servers) < 1 { + return storedLdapConfig, nil, ErrorNotConfigured{} + } + } else { + err = common.Decode(storedLdapConfigMap, storedLdapConfig) + if err != nil { + return nil, nil, fmt.Errorf("unable to decode Ldap Config: %w", err) + } + } + + if p.certs != storedLdapConfig.Certificate || p.caPool == nil { + pool, err := ldap.NewCAPool(storedLdapConfig.Certificate) + if err != nil { + return nil, nil, err + } + p.certs = storedLdapConfig.Certificate + p.caPool = pool + } + + if storedLdapConfig.ServiceAccountPassword != "" { + value, err := common.ReadFromSecret(p.secrets, storedLdapConfig.ServiceAccountPassword, + strings.ToLower(client.LdapConfigFieldServiceAccountPassword)) + if err != nil { + return nil, nil, err + } + storedLdapConfig.ServiceAccountPassword = value + } + + return storedLdapConfig, p.caPool, nil +} + +func (p *ldapProvider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, _, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + logrus.Errorf("Error fetching ldap config: %v", err) + return false, err + } + allowed, err := p.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func (p *ldapProvider) getDNAndScopeFromPrincipalID(principalID string) (string, string, error) { + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return "", "", fmt.Errorf("invalid id %v", principalID) + } + scope := parts[0] + externalID := strings.TrimPrefix(parts[1], "//") + + return externalID, scope, nil +} + +// if provider only enabled for search by a SAML provider +func (p *ldapProvider) samlSearchProvider() bool { + return ShibbolethName == p.providerName || OKTAName == p.providerName +} + +func (p *ldapProvider) samlSearchGetPrincipal( + externalID string, scope string, config *v3.LdapConfig, caPool *x509.CertPool) (*v3.Principal, error) { + + if scope != p.userScope && scope != p.groupScope { + return nil, fmt.Errorf("Invalid scope") + } + + lConn, err := ldap.Connect(config, caPool) + if err != nil { + return nil, err + } + defer lConn.Close() + + err = ldap.AuthenticateServiceAccountUser( + config.ServiceAccountPassword, config.ServiceAccountDistinguishedName, "", lConn) + if err != nil { + return nil, err + } + + var searchRequest *ldapv3.SearchRequest + + if scope == p.userScope { + filter := fmt.Sprintf( + "(&(%v=%v)(%v=%v))", + ObjectClass, config.UserObjectClass, + config.UserLoginAttribute, ldapv3.EscapeFilter(externalID), + ) + + searchRequest = ldap.NewWholeSubtreeSearchRequest( + config.UserSearchBase, + filter, + config.GetUserSearchAttributes(ObjectClass), + ) + } else { + filter := fmt.Sprintf( + "(&(%v=%v)(%v=%v))", + ObjectClass, config.GroupObjectClass, + config.GroupDNAttribute, ldapv3.EscapeFilter(externalID), + ) + + searchRequest = ldap.NewWholeSubtreeSearchRequest( + config.GroupSearchBase, + filter, + config.GetGroupSearchAttributes(ObjectClass), + ) + } + + result, err := lConn.Search(searchRequest) + if err != nil { + return nil, fmt.Errorf("saml search get principals search error: %s", err) + } + + if len(result.Entries) < 1 { + return nil, fmt.Errorf("No identities can be retrieved") + } else if len(result.Entries) > 1 { + return nil, fmt.Errorf("More than one result found") + } + + entry := result.Entries[0] + entryAttributes := entry.Attributes + + if scope == p.userScope { + userLoginValues := ldap.GetAttributeValuesByName(entry.Attributes, config.UserLoginAttribute) + if len(userLoginValues) > 0 { + externalID = userLoginValues[0] // only support first + } + } else { + groupDNValues := ldap.GetAttributeValuesByName(entry.Attributes, config.GroupDNAttribute) + if len(groupDNValues) > 0 { + externalID = groupDNValues[0] // only support first + } + } + + return ldap.AttributesToPrincipal( + entryAttributes, + externalID, + scope, + p.providerName, + config.UserObjectClass, + config.UserNameAttribute, + config.UserLoginAttribute, + config.GroupObjectClass, + config.GroupNameAttribute) +} + +func (p *ldapProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the LDAP auth provider is currently disabled in Rancher. +func (p *ldapProvider) IsDisabledProvider() (bool, error) { + ldapConfig, _, err := p.getLDAPConfig(p.authConfigs.ObjectClient().UnstructuredClient()) + if err != nil { + return false, err + } + return !ldapConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider_test.go new file mode 100644 index 0000000..86f77f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/ldap/ldap_provider_test.go @@ -0,0 +1,199 @@ +package ldap + +import ( + "context" + "crypto/x509" + "reflect" + "testing" + + "github.com/rancher/norman/objectclient" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/tokens" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/user" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +var ( + DummyCerts = "dummycerts" + DummyUsername = "testuser1" + DummyPassword = "testuser1" +) + +func Test_getBasicLogin(t *testing.T) { + type args struct { + input interface{} + } + tests := []struct { + name string + args args + wantLogin *v32.BasicLogin + wantErr bool + }{ + { + name: "good input credentials", + args: args{ + input: &v32.BasicLogin{ + Username: DummyUsername, + Password: DummyPassword, + }, + }, + wantLogin: &v32.BasicLogin{ + Username: DummyUsername, + Password: DummyPassword, + }, + wantErr: false, + }, + { + name: "bad input credentials", + args: args{ + input: "badinput", + }, + wantLogin: &v32.BasicLogin{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotLogin, err := toBasicLogin(tt.args.input) + if err != nil { + if tt.wantErr { + assert.Errorf(t, err, "unexpected input type") + } else { + t.Errorf("toBasicLogin() error = %v, wantErr %v", err, tt.wantErr) + } + return + } + if !reflect.DeepEqual(gotLogin, tt.wantLogin) { + t.Errorf("toBasicLogin() = %v, want %v", gotLogin, tt.wantLogin) + } + }) + } +} + +func Test_ldapProvider_getLDAPConfig(t *testing.T) { + type fields struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + userMGR user.Manager + tokenMGR *tokens.Manager + certs string + caPool *x509.CertPool + providerName string + testAndApplyInputType string + userScope string + groupScope string + mockGenericClient mockGenericClient + } + tests := []struct { + name string + fields fields + wantStoredLdapConfig *v3.LdapConfig + wantCaPool *x509.CertPool + wantErr bool + }{ + { + name: "get LDAP config object", + fields: fields{ + caPool: x509.NewCertPool(), + certs: DummyCerts, + }, + wantStoredLdapConfig: &v3.LdapConfig{ + LdapFields: v32.LdapFields{ + Certificate: DummyCerts, + }, + }, + wantCaPool: x509.NewCertPool(), + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &ldapProvider{ + ctx: tt.fields.ctx, + authConfigs: tt.fields.authConfigs, + secrets: tt.fields.secrets, + userMGR: tt.fields.userMGR, + tokenMGR: tt.fields.tokenMGR, + certs: tt.fields.certs, + caPool: tt.fields.caPool, + providerName: tt.fields.providerName, + testAndApplyInputType: tt.fields.testAndApplyInputType, + userScope: tt.fields.userScope, + groupScope: tt.fields.groupScope, + } + gotStoredLdapConfig, gotCaPool, err := p.getLDAPConfig(tt.fields.mockGenericClient) + if (err != nil) != tt.wantErr { + t.Errorf("ldapProvider.getLDAPConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(gotStoredLdapConfig, tt.wantStoredLdapConfig) { + t.Errorf("ldapProvider.getLDAPConfig() got = %v, want %v", gotStoredLdapConfig, tt.wantStoredLdapConfig) + } + if !reflect.DeepEqual(gotCaPool, tt.wantCaPool) { + t.Errorf("ldapProvider.getLDAPConfig() got1 = %v, want %v", gotCaPool, tt.wantCaPool) + } + }) + } +} + +type mockGenericClient struct{} + +func (m mockGenericClient) UnstructuredClient() objectclient.GenericClient { + panic("unimplemented") +} +func (m mockGenericClient) GroupVersionKind() schema.GroupVersionKind { + panic("unimplemented") +} +func (m mockGenericClient) Create(o runtime.Object) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) Get(name string, opts metav1.GetOptions) (runtime.Object, error) { + u := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "Certificate": DummyCerts, + }, + } + return u, nil +} +func (m mockGenericClient) Update(name string, o runtime.Object) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) UpdateStatus(name string, o runtime.Object) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) DeleteNamespaced(namespace, name string, opts *metav1.DeleteOptions) error { + panic("unimplemented") +} +func (m mockGenericClient) Delete(name string, opts *metav1.DeleteOptions) error { + panic("unimplemented") +} +func (m mockGenericClient) List(opts metav1.ListOptions) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) ListNamespaced(namespace string, opts metav1.ListOptions) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + panic("unimplemented") +} +func (m mockGenericClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error { + panic("unimplemented") +} +func (m mockGenericClient) Patch(name string, o runtime.Object, patchType types.PatchType, data []byte, subresources ...string) (runtime.Object, error) { + panic("unimplemented") +} +func (m mockGenericClient) ObjectFactory() objectclient.ObjectFactory { + panic("unimplemented") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/local/local_auth_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/local/local_auth_provider.go new file mode 100644 index 0000000..3a8a553 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/local/local_auth_provider.go @@ -0,0 +1,471 @@ +package local + +import ( + "context" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/bcrypt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +const ( + Name = "local" + userNameIndex = "authn.management.cattle.io/user-username-index" + gmPrincipalIndex = "authn.management.cattle.io/groupmember-principalid-index" + userSearchIndex = "authn.management.cattle.io/user-search-index" + groupSearchIndex = "authn.management.cattle.io/group-search-index" + searchIndexDefaultLen = 6 +) + +type Provider struct { + userLister v3.UserLister + groupLister v3.GroupLister + userIndexer cache.Indexer + gmIndexer cache.Indexer + groupIndexer cache.Indexer + tokenMGR *tokens.Manager + invalidHash []byte +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, tokenMGR *tokens.Manager) common.AuthProvider { + informer := mgmtCtx.Management.Users("").Controller().Informer() + indexers := map[string]cache.IndexFunc{userNameIndex: userNameIndexer, userSearchIndex: userSearchIndexer} + informer.AddIndexers(indexers) + + gmInformer := mgmtCtx.Management.GroupMembers("").Controller().Informer() + gmIndexers := map[string]cache.IndexFunc{gmPrincipalIndex: gmPIdIndexer} + gmInformer.AddIndexers(gmIndexers) + + gInformer := mgmtCtx.Management.Groups("").Controller().Informer() + gIndexers := map[string]cache.IndexFunc{groupSearchIndex: groupSearchIndexer} + gInformer.AddIndexers(gIndexers) + + invalidHash, _ := bcrypt.GenerateFromPassword([]byte("invalid"), bcrypt.DefaultCost) + + l := &Provider{ + userIndexer: informer.GetIndexer(), + gmIndexer: gmInformer.GetIndexer(), + groupLister: mgmtCtx.Management.Groups("").Controller().Lister(), + groupIndexer: gInformer.GetIndexer(), + userLister: mgmtCtx.Management.Users("").Controller().Lister(), + tokenMGR: tokenMGR, + invalidHash: invalidHash, + } + return l +} + +func (l *Provider) GetName() string { + return Name +} + +func (l *Provider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = l.actionHandler +} + +func (l *Provider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + return common.TransformToAuthProvider(authConfig), nil +} + +func (l *Provider) getUser(username string) (*v3.User, error) { + objs, err := l.userIndexer.ByIndex(userNameIndex, username) + + if err != nil { + return nil, err + } + if len(objs) == 0 { + return nil, httperror.WrapAPIError(err, httperror.Unauthorized, "authentication failed") + } + if len(objs) > 1 { + return nil, fmt.Errorf("found more than one users with username %v", username) + } + + user, ok := objs[0].(*v3.User) + + if !ok { + return nil, fmt.Errorf("fatal error. %v is not a user", objs[0]) + } + return user, nil +} + +func (l *Provider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + localInput, ok := input.(*v32.BasicLogin) + if !ok { + return v3.Principal{}, nil, "", httperror.NewAPIError(httperror.ServerError, "Unexpected input type") + } + + username := localInput.Username + pwd := localInput.Password + + authFailedError := httperror.NewAPIError(httperror.Unauthorized, "authentication failed") + user, err := l.getUser(username) + if err != nil { + // If the user don't exist the password is evaluated + // to avoid user enumeration via timing attack (time based side-channel). + bcrypt.CompareHashAndPassword(l.invalidHash, []byte(pwd)) + logrus.Debugf("Get User [%s] failed during Authentication: %v", username, err) + return v3.Principal{}, nil, "", authFailedError + } + + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(pwd)); err != nil { + logrus.Debugf("Authentication failed for User [%s]: %v", username, err) + return v3.Principal{}, nil, "", authFailedError + } + + principalID := getLocalPrincipalID(user) + userPrincipal := l.toPrincipal("user", user.DisplayName, user.Username, principalID, nil) + userPrincipal.Me = true + + groupPrincipals, err := l.getGroupPrincipals(user) + if err != nil { + return v3.Principal{}, nil, "", errors.Wrapf(err, "failed to get groups for %v", user.Name) + } + + return userPrincipal, groupPrincipals, "", nil +} + +func getLocalPrincipalID(user *v3.User) string { + // TODO error condition handling: no principal, more than one that would match + var principalID string + for _, p := range user.PrincipalIDs { + if strings.HasPrefix(p, Name+"://") { + principalID = p + } + } + if principalID == "" { + return Name + "://" + user.Name + } + return principalID +} + +func (l *Provider) getGroupPrincipals(user *v3.User) ([]v3.Principal, error) { + groupPrincipals := []v3.Principal{} + + for _, pid := range user.PrincipalIDs { + objs, err := l.gmIndexer.ByIndex(gmPrincipalIndex, pid) + if err != nil { + return []v3.Principal{}, err + } + + for _, o := range objs { + gm, ok := o.(*v3.GroupMember) + if !ok { + continue + } + + //find group for this member mapping + localGroup, err := l.groupLister.Get("", gm.GroupName) + if err != nil { + logrus.Errorf("Failed to get Group resource %v: %v", gm.GroupName, err) + continue + } + + groupPrincipal := l.toPrincipal("group", localGroup.DisplayName, "", Name+"://"+localGroup.Name, nil) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + } + + return groupPrincipals, nil +} + +func (l *Provider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + userID := strings.SplitN(principalID, "://", 2)[1] + user, err := l.userLister.Get("", userID) + if err != nil { + return nil, err + } + + return l.getGroupPrincipals(user) +} + +func (l *Provider) SearchPrincipals(searchKey, principalType string, token v3.Token) ([]v3.Principal, error) { + return l.SearchPrincipalsDedupe(searchKey, principalType, token, nil) +} + +// SearchPrincipalsDedupe performs principal search, but deduplicates the results against the supplied list (that should have come from other non-local auth providers) +// This is to avoid getting duplicate search results +func (l *Provider) SearchPrincipalsDedupe(searchKey, principalType string, token v3.Token, principalsFromOtherProviders []v3.Principal) ([]v3.Principal, error) { + fromOtherProviders := map[string]bool{} + for _, p := range principalsFromOtherProviders { + fromOtherProviders[p.Name] = true + } + var principals []v3.Principal + var localUsers []*v3.User + var localGroups []*v3.Group + var err error + + if len(searchKey) > searchIndexDefaultLen { + localUsers, localGroups, err = l.listAllUsersAndGroups(searchKey) + } else { + localUsers, localGroups, err = l.listUsersAndGroupsByIndex(searchKey) + } + + if err != nil { + logrus.Infof("Failed to search User/Group resources for %v: %v", searchKey, err) + return principals, err + } + + if principalType == "" || principalType == "user" { + User: + for _, user := range localUsers { + for _, p := range user.PrincipalIDs { + if fromOtherProviders[p] { + continue User + } + } + principalID := getLocalPrincipalID(user) + userPrincipal := l.toPrincipal("user", user.DisplayName, user.Username, principalID, &token) + principals = append(principals, userPrincipal) + } + } + + if principalType == "" || principalType == "group" { + for _, group := range localGroups { + groupPrincipal := l.toPrincipal("group", group.DisplayName, "", Name+"://"+group.Name, &token) + principals = append(principals, groupPrincipal) + } + } + + return principals, nil +} + +func (l *Provider) toPrincipal(principalType, displayName, loginName, id string, token *v3.Token) v3.Principal { + if displayName == "" { + displayName = loginName + } + + princ := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: id}, + DisplayName: displayName, + LoginName: loginName, + Provider: Name, + Me: false, + } + + if principalType == "user" { + princ.PrincipalType = "user" + if token != nil { + princ.Me = l.isThisUserMe(token.UserPrincipal, princ) + } + } else { + princ.PrincipalType = "group" + if token != nil { + princ.MemberOf = l.tokenMGR.IsMemberOf(*token, princ) + } + } + + return princ +} + +func (l *Provider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + // TODO implement group lookup (local groups currently not implemented, so we can skip) + // parsing id to get the external id and type. id looks like github_[user|org|team]://12345 + var name string + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return v3.Principal{}, errors.Errorf("invalid id %v", principalID) + } + name = strings.TrimPrefix(parts[1], "//") + + user, err := l.userLister.Get("", name) + if err != nil { + return v3.Principal{}, err + } + + princID := getLocalPrincipalID(user) + princ := l.toPrincipal("user", user.DisplayName, user.Username, princID, &token) + return princ, nil +} + +func (l *Provider) listAllUsersAndGroups(searchKey string) ([]*v3.User, []*v3.Group, error) { + var localUsers []*v3.User + var localGroups []*v3.Group + + allUsers, err := l.userLister.List("", labels.NewSelector()) + if err != nil { + logrus.Infof("Failed to search User resources for %v: %v", searchKey, err) + return localUsers, localGroups, err + } + for _, user := range allUsers { + if !(strings.HasPrefix(user.ObjectMeta.Name, searchKey) || strings.HasPrefix(user.Username, searchKey) || strings.HasPrefix(user.DisplayName, searchKey)) { + continue + } + localUsers = append(localUsers, user) + } + + allGroups, err := l.groupLister.List("", labels.NewSelector()) + if err != nil { + logrus.Infof("Failed to search group resources for %v: %v", searchKey, err) + return localUsers, localGroups, err + } + for _, group := range allGroups { + if !(strings.HasPrefix(group.ObjectMeta.Name, searchKey) || strings.HasPrefix(group.DisplayName, searchKey)) { + continue + } + localGroups = append(localGroups, group) + } + return localUsers, localGroups, err +} + +func (l *Provider) listUsersAndGroupsByIndex(searchKey string) ([]*v3.User, []*v3.Group, error) { + var localUsers []*v3.User + var localGroups []*v3.Group + var err error + + objs, err := l.userIndexer.ByIndex(userSearchIndex, searchKey) + if err != nil { + logrus.Infof("Failed to search User resources for %v: %v", searchKey, err) + return localUsers, localGroups, err + } + + for _, obj := range objs { + user, ok := obj.(*v3.User) + if !ok { + logrus.Errorf("User isnt a user %v", obj) + return localUsers, localGroups, err + } + localUsers = append(localUsers, user) + } + + groupObjs, err := l.groupIndexer.ByIndex(groupSearchIndex, searchKey) + if err != nil { + logrus.Infof("Failed to search Group resources for %v: %v", searchKey, err) + return localUsers, localGroups, err + } + + for _, obj := range groupObjs { + group, ok := obj.(*v3.Group) + if !ok { + logrus.Errorf("Object isnt a group %v", obj) + return localUsers, localGroups, err + } + localGroups = append(localGroups, group) + } + return localUsers, localGroups, err + +} + +func (l *Provider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (l *Provider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func userNameIndexer(obj interface{}) ([]string, error) { + user, ok := obj.(*v3.User) + if !ok { + return []string{}, nil + } + return []string{user.Username}, nil +} + +func gmPIdIndexer(obj interface{}) ([]string, error) { + gm, ok := obj.(*v3.GroupMember) + if !ok { + return []string{}, nil + } + return []string{gm.PrincipalID}, nil +} + +func userSearchIndexer(obj interface{}) ([]string, error) { + user, ok := obj.(*v3.User) + if !ok { + return []string{}, nil + } + var fieldIndexes []string + + fieldIndexes = append(fieldIndexes, indexField(user.Username, minOf(len(user.Username), searchIndexDefaultLen))...) + fieldIndexes = append(fieldIndexes, indexField(user.DisplayName, minOf(len(user.DisplayName), searchIndexDefaultLen))...) + fieldIndexes = append(fieldIndexes, indexField(user.ObjectMeta.Name, minOf(len(user.ObjectMeta.Name), searchIndexDefaultLen))...) + + return fieldIndexes, nil +} + +func groupSearchIndexer(obj interface{}) ([]string, error) { + group, ok := obj.(*v3.Group) + if !ok { + return []string{}, nil + } + var fieldIndexes []string + + fieldIndexes = append(fieldIndexes, indexField(group.DisplayName, minOf(len(group.DisplayName), searchIndexDefaultLen))...) + fieldIndexes = append(fieldIndexes, indexField(group.ObjectMeta.Name, minOf(len(group.ObjectMeta.Name), searchIndexDefaultLen))...) + + return fieldIndexes, nil +} + +func minOf(length int, defaultLen int) int { + if length < defaultLen { + return length + } + return defaultLen +} + +func indexField(field string, maxindex int) []string { + var fieldIndexes []string + for i := 2; i <= maxindex; i++ { + fieldIndexes = append(fieldIndexes, field[0:i]) + } + return fieldIndexes +} + +func (l *Provider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + userID := strings.TrimPrefix(userPrincipalID, Name+"://") + user, err := l.userLister.Get("", userID) + if err != nil { + return false, err + } + + if user.Username != "" { + return true, nil + } + + for _, principalID := range user.PrincipalIDs { + if strings.HasPrefix(principalID, "system://") { + return true, nil + } + } + + return false, nil +} + +func (l *Provider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the local auth provider is currently disabled in Rancher. +// As of now, local provider can't be disabled, so this method always returns false and nil for the error. +func (l *Provider) IsDisabledProvider() (bool, error) { + return false, nil +} + +// CleanupResources deletes resources associated with the local auth provider. +func (l *Provider) CleanupResources(*v3.AuthConfig) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions.go new file mode 100644 index 0000000..5ac8c47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions.go @@ -0,0 +1,136 @@ +package oidc + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "slices" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/api/handler" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "k8s.io/client-go/util/retry" +) + +func (o *OpenIDCProvider) Formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "configureTest") + resource.AddAction(apiContext, "testAndApply") +} + +func (o *OpenIDCProvider) ActionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, o.Name, o.AuthConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "configureTest" { + return o.ConfigureTest(request) + } else if actionName == "testAndApply" { + return o.TestAndApply(request) + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (o *OpenIDCProvider) ConfigureTest(request *types.APIContext) error { + //verify body has all required fields + input, err := handler.ParseAndValidateActionBody(request, request.Schemas.Schema(&managementschema.Version, + o.Type)) + if err != nil { + return err + } + + data := map[string]interface{}{ + "redirectUrl": o.getRedirectURL(input), + "type": "OIDCTestOutput", + } + request.WriteResponse(http.StatusOK, data) + return nil +} + +func (o *OpenIDCProvider) TestAndApply(request *types.APIContext) error { + var oidcConfig v32.OIDCConfig + oidcConfigApplyInput := &v32.OIDCApplyInput{} + + if err := json.NewDecoder(request.Request.Body).Decode(oidcConfigApplyInput); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("[generic oidc] testAndApply: failed to parse body: %v", err)) + } + + oidcConfig = oidcConfigApplyInput.OIDCConfig + oidcLogin := &v32.OIDCLogin{ + Code: oidcConfigApplyInput.Code, + } + + if !validateScopes(oidcConfig.Scopes) { + return fmt.Errorf("scopes are invalid: scopes must be space delimited and openid is a required scope. %s", oidcConfig.Scopes) + } + + // encode url to ensure path is escaped properly + // the issuer url is used to get all the other urls for the provider + // so its the only one that needs encoded + issuerURL, err := url.Parse(oidcConfig.Issuer) + if err != nil { + if httperror.IsAPIError(err) { + return err + } + return errors.Wrap(err, "[generic oidc]: server error while authenticating") + } + oidcConfig.Issuer = issuerURL.String() + + // call provider + userPrincipal, groupPrincipals, providerToken, claimInfo, err := o.LoginUser(request.Request.Context(), oidcLogin, &oidcConfig) + if err != nil { + if httperror.IsAPIError(err) { + return err + } + return errors.Wrap(err, "[generic oidc]: server error while authenticating") + } + // setting a bool for group search flag + // this only needs updated when an auth provider is enabled or edited + if claimInfo.Groups == nil && claimInfo.FullGroupPath == nil { + falseBool := false + oidcConfig.GroupSearchEnabled = &falseBool + } else { + trueBool := true + oidcConfig.GroupSearchEnabled = &trueBool + } + user, err := o.UserMGR.SetPrincipalOnCurrentUser(request, userPrincipal) + if err != nil { + return err + } + + err = o.saveOIDCConfig(&oidcConfig) + if err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("[generic oidc]: failed to save oidc config: %v", err)) + } + + userExtraInfo := o.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return o.TokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo) + }); err != nil { + return httperror.NewAPIError(httperror.ServerError, fmt.Sprintf("[generic oidc]: Failed to create or update userAttribute: %v", err)) + } + + return o.TokenMGR.CreateTokenAndSetCookie(user.Name, userPrincipal, groupPrincipals, providerToken, 0, "Token via OIDC Configuration", request) +} + +// validateScopes returns true if there are no commas in the scopes string and openid is included as a scope. +// Otherwise, the scopes are invalid and we return false. +func validateScopes(input string) bool { + if strings.Contains(input, ",") { + return false + } + values := strings.Fields(input) + return slices.Contains(values, "openid") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions_test.go new file mode 100644 index 0000000..74f9a93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_actions_test.go @@ -0,0 +1,44 @@ +package oidc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_validScopes(t *testing.T) { + tests := []struct { + name string + scopes string + want bool + }{ + { + name: "valid single scope", + scopes: "openid", + want: true, + }, + { + name: "valid multiple scopes", + scopes: "profile openid", + want: true, + }, + { + name: "no scopes", + }, + { + name: "scopes lacking openid", + scopes: "profile email", + }, + { + name: "invalid scopes", + scopes: "profile, email, openid", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + tt := tt + assert.Equalf(t, tt.want, validateScopes(tt.scopes), "validateScopes(%v)", tt.scopes) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client.go new file mode 100644 index 0000000..50ddd34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client.go @@ -0,0 +1,105 @@ +package oidc + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/coreos/go-oidc/v3/oidc" +) + +func getClientCertificates(certificate, key string) ([]tls.Certificate, error) { + cert, err := tls.X509KeyPair([]byte(certificate), []byte(key)) + if err != nil { + return nil, fmt.Errorf("could not parse cert/key pair: %w", err) + } + + return []tls.Certificate{cert}, nil +} + +func getHTTPClient(certificate, key string) (*http.Client, error) { + pool, err := x509.SystemCertPool() + if err != nil { + return nil, err + } + + if certificate != "" && key != "" { + certs, err := getClientCertificates(certificate, key) + if err != nil { + return nil, err + } + + pool.AppendCertsFromPEM([]byte(certificate)) + return &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: pool, + Certificates: certs, + }, + }, + }, nil + } + + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig.RootCAs = pool + return &http.Client{ + Transport: transport, + }, nil +} + +func AddCertKeyToContext(ctx context.Context, certificate, key string) (context.Context, error) { + client, err := getHTTPClient(certificate, key) + if err != nil { + return nil, err + } + + return oidc.ClientContext(ctx, client), nil +} + +func FetchAuthURL(config map[string]interface{}) (string, error) { + // If the authEndpoint is already configured, use that + if authURL, ok := config["authEndpoint"].(string); ok { + return authURL, nil + } + + issuerURL, ok := config["issuer"].(string) + if !ok { + return "", fmt.Errorf("both authEndpoint and issuerURL are missing in the authConfig") + } + + discoveryURL, err := url.JoinPath(issuerURL, "/.well-known/openid-configuration") + if err != nil { + return "", fmt.Errorf("could not form discovery URL: %w", err) + } + + client := &http.Client{ + Timeout: 10 * time.Second, + } + discoveryResponse, err := client.Get(discoveryURL) + if err != nil { + return "", fmt.Errorf("unable to fetch discovery information for OIDC provider: %w", err) + } + defer discoveryResponse.Body.Close() + + if discoveryResponse.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to fetch discovery document: %s", discoveryResponse.Status) + } + + var discoveryInfo struct { + AuthorizationEndpoint string `json:"authorization_endpoint"` + } + + if err := json.NewDecoder(discoveryResponse.Body).Decode(&discoveryInfo); err != nil { + return "", fmt.Errorf("unable to decode the OIDC discovery response %w", err) + } + if discoveryInfo.AuthorizationEndpoint == "" { + return "", fmt.Errorf("no authorization endpoint found in discovery response with status %s", discoveryResponse.Status) + } + + return discoveryInfo.AuthorizationEndpoint, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client_test.go new file mode 100644 index 0000000..d729078 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_client_test.go @@ -0,0 +1,269 @@ +package oidc + +import ( + "bytes" + "context" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "net" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/oauth2" +) + +func createCert(isCA bool) (*x509.Certificate, *rsa.PrivateKey, error) { + serialNo, err := rand.Int(rand.Reader, big.NewInt(int64(time.Now().Year()))) + if err != nil { + return nil, nil, err + } + + keyUsage := x509.KeyUsageDigitalSignature + if isCA { + keyUsage = keyUsage | x509.KeyUsageCertSign + } + + cert := &x509.Certificate{ + SerialNumber: serialNo, + Subject: pkix.Name{ + Organization: []string{fmt.Sprintf("Rancher - %d", serialNo)}, + Country: []string{"US"}, + Province: []string{""}, + Locality: []string{"Green Pastures"}, + StreetAddress: []string{"123 Cattle Drive"}, + PostalCode: []string{"94016"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(5 * time.Minute), + KeyUsage: keyUsage, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + IsCA: isCA, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + } + + key, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, nil, err + } + + return cert, key, nil +} + +func getPEMBytes(cert []byte, key *rsa.PrivateKey) ([]byte, []byte) { + certPEM := new(bytes.Buffer) + pem.Encode(certPEM, &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert, + }) + + keyPEM := new(bytes.Buffer) + pem.Encode(keyPEM, &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), + }) + + return certPEM.Bytes(), keyPEM.Bytes() +} + +func createClientCert(ca *x509.Certificate, rootKey *rsa.PrivateKey) ([]byte, []byte, error) { + cert, key, err := createCert(false) + if err != nil { + return nil, nil, err + } + + certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &key.PublicKey, rootKey) + if err != nil { + return nil, nil, err + } + + certPEM, keyPEM := getPEMBytes(certBytes, key) + return certPEM, keyPEM, nil +} + +func TestAddCertKeyToContext(t *testing.T) { + rootCA, rootKey, err := createCert(true) + if err != nil { + t.Fatalf("unable to create test CA Key: %s", err) + } + + rootCABytes, err := x509.CreateCertificate(rand.Reader, rootCA, rootCA, &rootKey.PublicKey, rootKey) + if err != nil { + t.Fatalf("unable to parse generated CA certs") + } + + _, rootKeyPem := getPEMBytes(rootCABytes, rootKey) + + clientCertBytes, clientKeyBytes, err := createClientCert(rootCA, rootKey) + if err != nil { + t.Fatalf("unable to generate test client cert") + } + + pool, _ := x509.SystemCertPool() + poolWithCert, _ := x509.SystemCertPool() + cert, err := tls.X509KeyPair(clientCertBytes, clientKeyBytes) + if err != nil { + t.Fatalf("unable to parse generated certs") + } + poolWithCert.AppendCertsFromPEM(clientCertBytes) + + testCases := []struct { + name string + cert string + key string + shouldFail bool + wantPool *x509.CertPool + wantCerts []tls.Certificate + }{ + { + name: "no cert or key", + cert: "", + key: "", + shouldFail: false, + wantPool: pool, + wantCerts: nil, + }, + { + name: "valid cert and key", + cert: string(clientCertBytes), + key: string(clientKeyBytes), + shouldFail: false, + wantPool: poolWithCert, + wantCerts: []tls.Certificate{cert}, + }, + { + name: "valid cert with no key", + cert: string(clientCertBytes), + key: "", + shouldFail: false, + wantPool: pool, + wantCerts: nil, + }, + { + name: "no cert with valid key", + cert: "", + key: string(clientKeyBytes), + shouldFail: false, + wantPool: pool, + wantCerts: nil, + }, + { + name: "mismatched cert and key", + cert: string(clientCertBytes), + key: string(rootKeyPem), + shouldFail: true, + wantPool: nil, + wantCerts: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx, err := AddCertKeyToContext(context.Background(), tc.cert, tc.key) + assert.Equal(t, err != nil, tc.shouldFail) + if tc.shouldFail && err != nil { + return + } + + got, ok := ctx.Value(oauth2.HTTPClient).(*http.Client) + require.True(t, ok, "expected to find an http client accessible in the context but didn't") + + gotTransport := got.Transport.(*http.Transport) + if !gotTransport.TLSClientConfig.RootCAs.Equal(tc.wantPool) { + t.Fatalf("system cert pool did not match desired") + } + + assert.Equal(t, tc.wantCerts, gotTransport.TLSClientConfig.Certificates, "cert did not match desired") + }) + } +} + +func TestFetchAuthURL(t *testing.T) { + testCases := []struct { + name string + config map[string]interface{} + mockResponse string + mockStatus int + expectedURL string + expectError bool + }{ + { + name: "AuthEndpoint already configured", + config: map[string]interface{}{ + "authEndpoint": "https://ranchertest.io/auth", + }, + expectedURL: "https://ranchertest.io/auth", + expectError: false, + }, + { + name: "Issuer URL provided, valid discovery document", + config: map[string]interface{}{ + "issuer": "https://ranchertest.io", + }, + mockResponse: `{"authorization_endpoint": "https://ranchertest.io/auth"}`, + mockStatus: http.StatusOK, + expectedURL: "https://ranchertest.io/auth", + expectError: false, + }, + { + name: "Issuer URL provided, invalid discovery document", + config: map[string]interface{}{ + "issuer": "https://ranchertest.io", + }, + mockResponse: `{"authorization_endpoi": "https://ranchertest.io/auth"}`, + mockStatus: http.StatusOK, + expectedURL: "", + expectError: true, + }, + { + name: "Issuer URL provided, error fetching discovery document", + config: map[string]interface{}{ + "issuer": "https://ranchertest.io", + }, + mockResponse: `Internal Server Error`, + mockStatus: http.StatusInternalServerError, + expectedURL: "", + expectError: true, + }, + { + name: "Both authEndpoint and issuerURL missing", + config: map[string]interface{}{}, + expectedURL: "", + expectError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(tc.mockStatus) + w.Write([]byte(tc.mockResponse)) + })) + defer server.Close() + + // Adjust the config to use the mock server URL + if _, ok := tc.config["issuer"].(string); ok { + mockURL, _ := url.Parse(server.URL) + tc.config["issuer"] = mockURL.Scheme + "://" + mockURL.Host + } + + authURL, err := FetchAuthURL(tc.config) + if (err != nil) != tc.expectError { + t.Fatalf("expected error: %v, got: %v", tc.expectError, err) + } + if authURL != tc.expectedURL { + t.Fatalf("expected URL: %s, got: %s", tc.expectedURL, authURL) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider.go new file mode 100644 index 0000000..d44ff7b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider.go @@ -0,0 +1,574 @@ +package oidc + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "slices" + "strings" + + "github.com/coreos/go-oidc/v3/oidc" + "github.com/golang-jwt/jwt" + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "golang.org/x/oauth2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + Name = "oidc" + UserType = "user" + GroupType = "group" +) + +type OpenIDCProvider struct { + Name string + Type string + CTX context.Context + AuthConfigs v3.AuthConfigInterface + Secrets corev1.SecretInterface + UserMGR user.Manager + TokenMGR *tokens.Manager +} + +type ClaimInfo struct { + Subject string `json:"sub"` + Name string `json:"name"` + PreferredUsername string `json:"preferred_username"` + GivenName string `json:"given_name"` + FamilyName string `json:"family_name"` + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + Groups []string `json:"groups"` + FullGroupPath []string `json:"full_group_path"` + ACR string `json:"acr"` +} + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager) common.AuthProvider { + return &OpenIDCProvider{ + Name: Name, + Type: client.OIDCConfigType, + CTX: ctx, + AuthConfigs: mgmtCtx.Management.AuthConfigs(""), + Secrets: mgmtCtx.Core.Secrets(""), + UserMGR: userMGR, + TokenMGR: tokenMGR, + } +} + +func (o *OpenIDCProvider) GetName() string { + return Name +} + +func (o *OpenIDCProvider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = o.ActionHandler + schema.Formatter = o.Formatter +} + +func (o *OpenIDCProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + login, ok := input.(*v32.OIDCLogin) + if !ok { + return v3.Principal{}, nil, "", fmt.Errorf("unexpected input type") + } + userPrincipal, groupPrincipals, providerToken, _, err := o.LoginUser(ctx, login, nil) + return userPrincipal, groupPrincipals, providerToken, err +} + +func (o *OpenIDCProvider) LoginUser(ctx context.Context, oauthLoginInfo *v32.OIDCLogin, config *v32.OIDCConfig) (v3.Principal, []v3.Principal, string, ClaimInfo, error) { + var userPrincipal v3.Principal + var groupPrincipals []v3.Principal + var userClaimInfo ClaimInfo + var err error + + if config == nil { + config, err = o.GetOIDCConfig() + if err != nil { + return userPrincipal, nil, "", userClaimInfo, err + } + } + userInfo, oauth2Token, err := o.getUserInfo(&ctx, config, oauthLoginInfo.Code, &userClaimInfo, "") + if err != nil { + return userPrincipal, groupPrincipals, "", userClaimInfo, err + } + userPrincipal = o.userToPrincipal(userInfo, userClaimInfo) + userPrincipal.Me = true + groupPrincipals = o.getGroupsFromClaimInfo(userClaimInfo) + + logrus.Debugf("[generic oidc] loginuser: checking user's access to rancher") + allowed, err := o.UserMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipal.Name, groupPrincipals) + if err != nil { + return userPrincipal, groupPrincipals, "", userClaimInfo, err + } + if !allowed { + return userPrincipal, groupPrincipals, "", userClaimInfo, httperror.NewAPIError(httperror.Unauthorized, "unauthorized") + } + // save entire oauthToken because it contains refresh_token and token expiry time + // will use with oauth2.Client and with TokenSource to ensure auto refresh of tokens occurs for api calls + oauthToken, err := json.Marshal(oauth2Token) + if err != nil { + return userPrincipal, groupPrincipals, "", userClaimInfo, err + } + return userPrincipal, groupPrincipals, string(oauthToken), userClaimInfo, nil +} + +func (o *OpenIDCProvider) SearchPrincipals(searchValue, principalType string, token v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + + if principalType == "" { + principalType = UserType + } + + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: o.Name + "_" + principalType + "://" + searchValue}, + DisplayName: searchValue, + LoginName: searchValue, + PrincipalType: principalType, + Provider: o.Name, + } + + principals = append(principals, p) + return principals, nil +} + +func (o *OpenIDCProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + var p v3.Principal + + // parsing id to get the external id and type. Example oidc_:// + var externalID string + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return p, errors.Errorf("invalid id %v", principalID) + } + externalID = strings.TrimPrefix(parts[1], "//") + parts = strings.SplitN(parts[0], "_", 2) + if len(parts) != 2 { + return p, errors.Errorf("invalid id %v", principalID) + } + + principalType := parts[1] + if externalID == "" && principalType == "" { + return p, fmt.Errorf("invalid id %v", principalID) + } + if principalType != UserType && principalType != GroupType { + return p, fmt.Errorf("invalid principal type") + } + if principalID == UserType { + p = v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: principalType + "://" + externalID}, + DisplayName: externalID, + LoginName: externalID, + PrincipalType: UserType, + Provider: o.Name, + } + } else { + p = o.groupToPrincipal(externalID) + } + p = o.toPrincipalFromToken(principalType, p, &token) + return p, nil +} + +func (o *OpenIDCProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + p[publicclient.OIDCProviderFieldRedirectURL] = o.getRedirectURL(authConfig) + return p, nil +} + +func (o *OpenIDCProvider) getRedirectURL(config map[string]interface{}) string { + authURL, _ := FetchAuthURL(config) + + return fmt.Sprintf( + "%s?client_id=%s&response_type=code&redirect_uri=%s", + authURL, + config["clientId"], + config["rancherUrl"], + ) +} + +func (o *OpenIDCProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + var groupPrincipals []v3.Principal + var claimInfo ClaimInfo + + config, err := o.GetOIDCConfig() + if err != nil { + logrus.Errorf("[generic oidc] refetchGroupPrincipals: error fetching OIDCConfig: %v", err) + return groupPrincipals, err + } + // need to get the user information so that the refreshed token can be saved using the username / userID + user, err := o.UserMGR.GetUserByPrincipalID(principalID) + if err != nil { + logrus.Errorf("[generic oidc] refetchGroupPrincipals: error getting user by principalID: %v", err) + return groupPrincipals, err + } + //do not need userInfo or oauth2Token since we are only processing groups + _, _, err = o.getUserInfo(&o.CTX, config, secret, &claimInfo, user.Name) + if err != nil { + return groupPrincipals, err + } + return o.getGroupsFromClaimInfo(claimInfo), nil +} + +func (o *OpenIDCProvider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, err := o.GetOIDCConfig() + if err != nil { + logrus.Errorf("[generic oidc] canAccessWithGroupProviders: error fetching OIDCConfig: %v", err) + return false, err + } + allowed, err := o.UserMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func (o *OpenIDCProvider) userToPrincipal(userInfo *oidc.UserInfo, claimInfo ClaimInfo) v3.Principal { + displayName := claimInfo.Name + if displayName == "" { + displayName = userInfo.Email + } + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: o.Name + "_" + UserType + "://" + userInfo.Subject}, + DisplayName: displayName, + LoginName: userInfo.Email, + Provider: o.Name, + PrincipalType: UserType, + Me: false, + } + return p +} + +func (o *OpenIDCProvider) groupToPrincipal(groupName string) v3.Principal { + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: o.Name + "_" + GroupType + "://" + groupName}, + DisplayName: groupName, + Provider: o.Name, + PrincipalType: GroupType, + Me: false, + } + return p +} + +func (o *OpenIDCProvider) toPrincipalFromToken(principalType string, princ v3.Principal, token *v3.Token) v3.Principal { + if principalType == UserType { + princ.PrincipalType = UserType + if token != nil { + princ.Me = o.IsThisUserMe(token.UserPrincipal, princ) + if princ.Me { + princ.LoginName = token.UserPrincipal.LoginName + princ.DisplayName = token.UserPrincipal.DisplayName + } + } + } else { + princ.PrincipalType = GroupType + if token != nil { + princ.MemberOf = o.TokenMGR.IsMemberOf(*token, princ) + } + } + return princ +} + +func (o *OpenIDCProvider) saveOIDCConfig(config *v32.OIDCConfig) error { + storedOidcConfig, err := o.GetOIDCConfig() + if err != nil { + return err + } + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = o.Type + config.ObjectMeta = storedOidcConfig.ObjectMeta + + if config.PrivateKey != "" { + privateKeyField := strings.ToLower(client.OIDCConfigFieldPrivateKey) + name, err := common.CreateOrUpdateSecrets(o.Secrets, config.PrivateKey, privateKeyField, strings.ToLower(config.Type)) + if err != nil { + return err + } + config.PrivateKey = name + } + + secretField := strings.ToLower(client.OIDCConfigFieldClientSecret) + name, err := common.CreateOrUpdateSecrets(o.Secrets, convert.ToString(config.ClientSecret), secretField, strings.ToLower(config.Type)) + if err != nil { + return err + } + config.ClientSecret = name + + logrus.Debugf("[generic oidc] saveOIDCConfig: updating config") + _, err = o.AuthConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + return err +} + +func (o *OpenIDCProvider) GetOIDCConfig() (*v32.OIDCConfig, error) { + authConfigObj, err := o.AuthConfigs.ObjectClient().UnstructuredClient().Get(o.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve OIDCConfig, error: %v", err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to retrieve OIDCConfig, cannot read k8s Unstructured data") + } + storedOidcConfigMap := u.UnstructuredContent() + + storedOidcConfig := &v32.OIDCConfig{} + err = common.Decode(storedOidcConfigMap, storedOidcConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode OidcConfig: %w", err) + } + + if storedOidcConfig.PrivateKey != "" { + value, err := common.ReadFromSecret(o.Secrets, storedOidcConfig.PrivateKey, strings.ToLower(client.OIDCConfigFieldPrivateKey)) + if err != nil { + return nil, err + } + storedOidcConfig.PrivateKey = value + } + if storedOidcConfig.ClientSecret != "" { + data, err := common.ReadFromSecretData(o.Secrets, storedOidcConfig.ClientSecret) + if err != nil { + return nil, err + } + for _, v := range data { + storedOidcConfig.ClientSecret = string(v) + } + } + + return storedOidcConfig, nil +} + +func (o *OpenIDCProvider) IsThisUserMe(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.LoginName == other.LoginName && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (o *OpenIDCProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +func (o *OpenIDCProvider) getUserInfo(ctx *context.Context, config *v32.OIDCConfig, authCode string, claimInfo *ClaimInfo, userName string) (*oidc.UserInfo, *oauth2.Token, error) { + var userInfo *oidc.UserInfo + var oauth2Token *oauth2.Token + var err error + + updatedContext, err := AddCertKeyToContext(*ctx, config.Certificate, config.PrivateKey) + if err != nil { + return userInfo, oauth2Token, err + } + + provider, err := o.getOIDCProvider(updatedContext, config) + if err != nil { + return userInfo, oauth2Token, err + } + oauthConfig := ConfigToOauthConfig(provider.Endpoint(), config) + var verifier = provider.Verifier(&oidc.Config{ClientID: config.ClientID}) + + oauth2Token, err = oauthConfig.Exchange(updatedContext, authCode, oauth2.SetAuthURLParam("scope", strings.Join(oauthConfig.Scopes, " "))) + if err != nil { + return userInfo, oauth2Token, err + } + + // Get the ID token. The ID token should be there because we require the openid scope. + rawIDToken, ok := oauth2Token.Extra("id_token").(string) + if !ok { + return userInfo, oauth2Token, fmt.Errorf("no id_token field in oauth2 token") + } + + idToken, err := verifier.Verify(updatedContext, rawIDToken) + if err != nil { + return userInfo, oauth2Token, fmt.Errorf("failed to verify ID token: %w", err) + } + + if err := idToken.Claims(&claimInfo); err != nil { + return userInfo, oauth2Token, fmt.Errorf("failed to parse claims: %w", err) + } + + // Valid will return false if access token is expired + if !oauth2Token.Valid() { + // since token is not valid, the TokenSource func will attempt to refresh the access token + // if the refresh token has not expired + logrus.Debugf("[generic oidc] getUserInfo: attempting to refresh access token") + } + reusedToken, err := oauth2.ReuseTokenSource(oauth2Token, oauthConfig.TokenSource(updatedContext, oauth2Token)).Token() + if err != nil { + return userInfo, oauth2Token, err + } + if !reflect.DeepEqual(oauth2Token, reusedToken) { + o.UpdateToken(reusedToken, userName) + } + + if config.AcrValue != "" { + acrValue, err := parseACRFromAccessToken(oauth2Token.AccessToken) + if err != nil { + return userInfo, oauth2Token, fmt.Errorf("failed to parse ACR from access token: %w", err) + } + if !isValidACR(acrValue, config.AcrValue) { + return userInfo, oauth2Token, errors.New("failed to validate ACR") + } + } + + logrus.Debugf("[generic oidc] getUserInfo: getting user info") + userInfo, err = provider.UserInfo(updatedContext, oauthConfig.TokenSource(updatedContext, reusedToken)) + if err != nil { + return userInfo, oauth2Token, err + } + if err := userInfo.Claims(&claimInfo); err != nil { + return userInfo, oauth2Token, err + } + + return userInfo, oauth2Token, nil +} + +func ConfigToOauthConfig(endpoint oauth2.Endpoint, config *v32.OIDCConfig) oauth2.Config { + var finalScopes []string + hasOIDCScope := strings.Contains(config.Scopes, oidc.ScopeOpenID) + // scopes must be space separated in string when passed into the api + configScopes := strings.Split(config.Scopes, " ") + if !hasOIDCScope { + configScopes = append(configScopes, oidc.ScopeOpenID) + } + for _, scope := range configScopes { + if scope != "" { + finalScopes = append(finalScopes, scope) + } + } + return oauth2.Config{ + ClientID: config.ClientID, + ClientSecret: config.ClientSecret, + Endpoint: endpoint, + RedirectURL: config.RancherURL, + Scopes: finalScopes, + } +} + +func (o *OpenIDCProvider) getGroupsFromClaimInfo(claimInfo ClaimInfo) []v3.Principal { + var groupPrincipals []v3.Principal + + if claimInfo.FullGroupPath != nil { + for _, groupPath := range claimInfo.FullGroupPath { + groupsFromPath := strings.Split(groupPath, "/") + for _, group := range groupsFromPath { + if group != "" { + groupPrincipal := o.groupToPrincipal(group) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + } + } + } else { + for _, group := range claimInfo.Groups { + groupPrincipal := o.groupToPrincipal(group) + groupPrincipal.MemberOf = true + groupPrincipals = append(groupPrincipals, groupPrincipal) + } + } + return groupPrincipals +} + +func (o *OpenIDCProvider) UpdateToken(refreshedToken *oauth2.Token, userID string) error { + var err error + logrus.Debugf("[generic oidc] UpdateToken: access token has been refreshed") + marshalledToken, err := json.Marshal(refreshedToken) + if err != nil { + return err + } + logrus.Debugf("[generic oidc] UpdateToken: saving refreshed access token") + o.TokenMGR.UpdateSecret(userID, o.Name, string(marshalledToken)) + return err +} + +// IsDisabledProvider checks if the OIDC auth provider is currently disabled in Rancher. +func (o *OpenIDCProvider) IsDisabledProvider() (bool, error) { + oidcConfig, err := o.GetOIDCConfig() + if err != nil { + return false, err + } + return !oidcConfig.Enabled, nil +} + +func (o *OpenIDCProvider) getOIDCProvider(ctx context.Context, oidcConfig *v32.OIDCConfig) (*oidc.Provider, error) { + oidcFields := map[string]string{ + client.OIDCConfigFieldIssuer: oidcConfig.Issuer, + client.OIDCConfigFieldAuthEndpoint: oidcConfig.AuthEndpoint, + client.OIDCConfigFieldTokenEndpoint: oidcConfig.TokenEndpoint, + client.OIDCConfigFieldJWKSUrl: oidcConfig.JWKSUrl, + client.OIDCConfigFieldUserInfoEndpoint: oidcConfig.UserInfoEndpoint, + } + var emptyFields []string + for key, value := range oidcFields { + if value == "" { + emptyFields = append(emptyFields, key) + } + } + + // If all the fields are set, we will use them and manually specify each one. + // Otherwise, we will fall back to using just the issuer and the others will be determined by discovery. + if len(emptyFields) > 0 && slices.Contains(emptyFields, oidcFields[client.OIDCConfigFieldIssuer]) { + return nil, fmt.Errorf("unable to create OIDC provider. The following fields are missing: %s", strings.Join(emptyFields, ",")) + } + + if len(emptyFields) == 0 { + pConfig := &oidc.ProviderConfig{ + IssuerURL: oidcConfig.Issuer, + AuthURL: oidcConfig.AuthEndpoint, + TokenURL: oidcConfig.TokenEndpoint, + UserInfoURL: oidcConfig.UserInfoEndpoint, + JWKSURL: oidcConfig.JWKSUrl, + } + return pConfig.NewProvider(ctx), nil + } + // This will perform discovery in the oidc library + return oidc.NewProvider(ctx, oidcConfig.Issuer) +} + +func isValidACR(claimACR string, configuredACR string) bool { + // if we have no ACR configured, all values are accepted + if configuredACR == "" { + return true + } + + if claimACR != configuredACR { + logrus.Infof("acr value in token does not match configured acr value") + return false + } + return true +} + +func parseACRFromAccessToken(accessToken string) (string, error) { + var parser jwt.Parser + // we already validated the incoming token + token, _, err := parser.ParseUnverified(accessToken, jwt.MapClaims{}) + if err != nil { + return "", fmt.Errorf("failed to parse token: %w", err) + } + claims, ok := token.Claims.(jwt.MapClaims) + if !ok { + return "", errors.New("invalid access token jwt.MapClaims format") + } + acrValue, found := claims["acr"].(string) + if !found { + return "", fmt.Errorf("acr claim invalid or not found in token: (acr=%v)", claims["acr"]) + } + return acrValue, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider_test.go new file mode 100644 index 0000000..b1b67a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/oidc/oidc_provider_test.go @@ -0,0 +1,102 @@ +package oidc + +import ( + "encoding/base64" + "fmt" + "testing" + + "github.com/golang-jwt/jwt" + "github.com/stretchr/testify/assert" +) + +func Test_validateACR(t *testing.T) { + tests := []struct { + name string + claimACR string + configuredACR string + want bool + }{ + { + name: "acr set in config and matches token", + configuredACR: "level1", + claimACR: "level1", + want: true, + }, + { + name: "acr set in config and does not match token", + configuredACR: "level1", + claimACR: "", + want: false, + }, + { + name: "acr not set in config", + claimACR: "", + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, isValidACR(tt.claimACR, tt.configuredACR), "isValidACR(%v, %v)", tt.claimACR, tt.configuredACR) + }) + } +} + +func TestParseACRFromAccessToken(t *testing.T) { + header := base64.URLEncoding.EncodeToString([]byte(`{"alg":"none"}`)) + validClaims := base64.URLEncoding.EncodeToString([]byte(`{"acr":"example_acr"}`)) + invalidBase64Claims := "invalid_base64_claims" + noAcrClaims := base64.URLEncoding.EncodeToString([]byte(`{"sub":"1234567890"}`)) + + tests := []struct { + name string + token string + expectedACR string + wantError bool + }{ + { + name: "valid token with ACR", + token: fmt.Sprintf("%s.%s.", header, validClaims), + expectedACR: "example_acr", + }, + { + name: "invalid token format", + token: "invalid.token", + expectedACR: "", + wantError: true, + }, + { + name: "invalid base64 decoding", + token: fmt.Sprintf("%s.%s.", header, invalidBase64Claims), + expectedACR: "", + wantError: true, + }, + { + name: "valid token without ACR claim", + token: fmt.Sprintf("%s.%s.", header, noAcrClaims), + expectedACR: "", + wantError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + acr, err := parseACRFromAccessToken(tt.token) + if acr != tt.expectedACR { + t.Errorf("expected acr to be '%s', got '%s'", tt.expectedACR, acr) + } + if (err != nil) != tt.wantError { + t.Errorf("expected error: %v, got error: %v", tt.wantError, err) + } + }) + } +} + +// generateAccessToken generates an access token with the specified acr. +func generateAccessToken(acr string) string { + claims := jwt.MapClaims{ + "acr": acr, + } + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + tokenString, _ := token.SignedString([]byte("test_secret_key")) + return tokenString +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers.go new file mode 100644 index 0000000..64804a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers.go @@ -0,0 +1,252 @@ +package providers + +import ( + "context" + "fmt" + "strings" + "sync" + + "github.com/rancher/rancher/pkg/auth/providers/activedirectory" + "github.com/rancher/rancher/pkg/auth/providers/azure" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/genericoidc" + "github.com/rancher/rancher/pkg/auth/providers/github" + "github.com/rancher/rancher/pkg/auth/providers/googleoauth" + "github.com/rancher/rancher/pkg/auth/providers/keycloakoidc" + "github.com/rancher/rancher/pkg/auth/providers/ldap" + "github.com/rancher/rancher/pkg/auth/providers/local" + "github.com/rancher/rancher/pkg/auth/providers/oidc" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +var ( + ProviderNames = make(map[string]bool) + providersWithSecrets = make(map[string]bool) + UnrefreshableProviders = make(map[string]bool) + Providers = make(map[string]common.AuthProvider) + LocalProvider = "local" + providersByType = make(map[string]common.AuthProvider) + confMu sync.Mutex + userExtraAttributesMap = map[string]bool{common.UserAttributePrincipalID: true, common.UserAttributeUserName: true} +) + +func GetProvider(providerName string) (common.AuthProvider, error) { + if provider, ok := Providers[providerName]; ok { + if provider != nil { + return provider, nil + } + } + return nil, fmt.Errorf("No such provider '%s'", providerName) +} + +func GetProviderByType(configType string) common.AuthProvider { + return providersByType[configType] +} + +func Configure(ctx context.Context, mgmt *config.ScaledContext) { + confMu.Lock() + defer confMu.Unlock() + userMGR := mgmt.UserManager + tokenMGR := tokens.NewManager(ctx, mgmt) + var p common.AuthProvider + + p = local.Configure(ctx, mgmt, tokenMGR) + ProviderNames[local.Name] = true + Providers[local.Name] = p + providersByType[client.LocalConfigType] = p + providersByType[publicclient.LocalProviderType] = p + + p = github.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[github.Name] = true + providersWithSecrets[github.Name] = true + Providers[github.Name] = p + providersByType[client.GithubConfigType] = p + providersByType[publicclient.GithubProviderType] = p + + p = azure.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[azure.Name] = true + providersWithSecrets[azure.Name] = true + Providers[azure.Name] = p + providersByType[client.AzureADConfigType] = p + providersByType[publicclient.AzureADProviderType] = p + + p = activedirectory.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[activedirectory.Name] = true + Providers[activedirectory.Name] = p + providersByType[client.ActiveDirectoryConfigType] = p + providersByType[publicclient.ActiveDirectoryProviderType] = p + + p = ldap.Configure(ctx, mgmt, userMGR, tokenMGR, ldap.OpenLdapName) + ProviderNames[ldap.OpenLdapName] = true + Providers[ldap.OpenLdapName] = p + providersByType[client.OpenLdapConfigType] = p + providersByType[publicclient.OpenLdapProviderType] = p + + p = ldap.Configure(ctx, mgmt, userMGR, tokenMGR, ldap.FreeIpaName) + ProviderNames[ldap.FreeIpaName] = true + Providers[ldap.FreeIpaName] = p + providersByType[client.FreeIpaConfigType] = p + providersByType[publicclient.FreeIpaProviderType] = p + + p = saml.Configure(ctx, mgmt, userMGR, tokenMGR, saml.PingName) + ProviderNames[saml.PingName] = true + UnrefreshableProviders[saml.PingName] = true + Providers[saml.PingName] = p + providersByType[client.PingConfigType] = p + providersByType[publicclient.PingProviderType] = p + + p = saml.Configure(ctx, mgmt, userMGR, tokenMGR, saml.ADFSName) + ProviderNames[saml.ADFSName] = true + UnrefreshableProviders[saml.ADFSName] = true + Providers[saml.ADFSName] = p + providersByType[client.ADFSConfigType] = p + providersByType[publicclient.ADFSProviderType] = p + + p = saml.Configure(ctx, mgmt, userMGR, tokenMGR, saml.KeyCloakName) + ProviderNames[saml.KeyCloakName] = true + UnrefreshableProviders[saml.KeyCloakName] = true + Providers[saml.KeyCloakName] = p + providersByType[client.KeyCloakConfigType] = p + providersByType[publicclient.KeyCloakProviderType] = p + + p = saml.Configure(ctx, mgmt, userMGR, tokenMGR, saml.OKTAName) + ProviderNames[saml.OKTAName] = true + UnrefreshableProviders[saml.OKTAName] = true + Providers[saml.OKTAName] = p + providersByType[client.OKTAConfigType] = p + providersByType[publicclient.OKTAProviderType] = p + + p = saml.Configure(ctx, mgmt, userMGR, tokenMGR, saml.ShibbolethName) + ProviderNames[saml.ShibbolethName] = true + UnrefreshableProviders[saml.ShibbolethName] = false + Providers[saml.ShibbolethName] = p + providersByType[client.ShibbolethConfigType] = p + providersByType[publicclient.ShibbolethProviderType] = p + + p = googleoauth.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[googleoauth.Name] = true + providersWithSecrets[googleoauth.Name] = true + Providers[googleoauth.Name] = p + providersByType[client.GoogleOauthConfigType] = p + providersByType[publicclient.GoogleOAuthProviderType] = p + + p = oidc.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[oidc.Name] = true + providersWithSecrets[oidc.Name] = true + Providers[oidc.Name] = p + providersByType[client.OIDCConfigType] = p + providersByType[publicclient.OIDCProviderType] = p + + p = keycloakoidc.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[keycloakoidc.Name] = true + providersWithSecrets[keycloakoidc.Name] = true + Providers[keycloakoidc.Name] = p + providersByType[client.KeyCloakOIDCConfigType] = p + providersByType[publicclient.KeyCloakOIDCProviderType] = p + + p = genericoidc.Configure(ctx, mgmt, userMGR, tokenMGR) + ProviderNames[genericoidc.Name] = true + providersWithSecrets[genericoidc.Name] = true + UnrefreshableProviders[genericoidc.Name] = true + Providers[genericoidc.Name] = p + providersByType[client.GenericOIDCConfigType] = p + providersByType[publicclient.GenericOIDCProviderType] = p +} + +func IsValidUserExtraAttribute(key string) bool { + if _, ok := userExtraAttributesMap[strings.ToLower(key)]; ok { + return true + } + return false +} + +func AuthenticateUser(ctx context.Context, input interface{}, providerName string) (v3.Principal, []v3.Principal, string, error) { + return Providers[providerName].AuthenticateUser(ctx, input) +} + +func GetPrincipal(principalID string, myToken v3.Token) (v3.Principal, error) { + principal, err := Providers[myToken.AuthProvider].GetPrincipal(principalID, myToken) + + if err != nil && myToken.AuthProvider != LocalProvider { + p2, e2 := Providers[LocalProvider].GetPrincipal(principalID, myToken) + if e2 == nil { + return p2, nil + } + } + + return principal, err +} + +func SearchPrincipals(name, principalType string, myToken v3.Token) ([]v3.Principal, error) { + if myToken.AuthProvider == "" { + return []v3.Principal{}, fmt.Errorf("[SearchPrincipals] no authProvider specified in token") + } + if Providers[myToken.AuthProvider] == nil { + return []v3.Principal{}, fmt.Errorf("[SearchPrincipals] authProvider %v not initialized", myToken.AuthProvider) + } + principals, err := Providers[myToken.AuthProvider].SearchPrincipals(name, principalType, myToken) + if err != nil { + return principals, err + } + if myToken.AuthProvider != LocalProvider { + lp := Providers[LocalProvider] + if lpDedupe, _ := lp.(*local.Provider); lpDedupe != nil { + localPrincipals, err := lpDedupe.SearchPrincipalsDedupe(name, principalType, myToken, principals) + if err != nil { + return principals, err + } + principals = append(principals, localPrincipals...) + } + } + return principals, err +} + +func CanAccessWithGroupProviders(providerName string, userPrincipalID string, groups []v3.Principal) (bool, error) { + return Providers[providerName].CanAccessWithGroupProviders(userPrincipalID, groups) +} + +func RefetchGroupPrincipals(principalID string, providerName string, secret string) ([]v3.Principal, error) { + return Providers[providerName].RefetchGroupPrincipals(principalID, secret) +} + +func GetUserExtraAttributes(providerName string, userPrincipal v3.Principal) map[string][]string { + return Providers[providerName].GetUserExtraAttributes(userPrincipal) +} + +func IsDisabledProvider(providerName string) (bool, error) { + provider, err := GetProvider(providerName) + if err != nil { + return false, err + } + return provider.IsDisabledProvider() +} + +// ProviderHasPerUserSecrets returns true if a given provider is known to use per-user auth tokens stored in secrets. +func ProviderHasPerUserSecrets(providerName string) (bool, error) { + // For Azure AD, check if it's configured to use the new or old flow. Only the old flow via Azure AD Graph uses per-user secrets. + if providerName == azure.Name { + p, ok := Providers[azure.Name] + if !ok { + return false, fmt.Errorf("error determining if auth provider uses per-user tokens: provider %s is unknown to Rancher", providerName) + } + + azureProvider, ok := p.(*azure.Provider) + if !ok { + return false, fmt.Errorf("error determining if Azure AD auth provider uses per-user tokens: provider's type is invalid") + } + + cfg, err := azureProvider.GetAzureConfigK8s() + if err != nil { + return false, fmt.Errorf("error determining if Azure AD auth provider uses per-user tokens because of an error to fetch its config: %w", err) + } + + return azure.IsConfigDeprecated(cfg), nil + } + + return providersWithSecrets[providerName], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers_test.go new file mode 100644 index 0000000..a5052db --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/providers_test.go @@ -0,0 +1,196 @@ +package providers + +import ( + "context" + "fmt" + "testing" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/azure" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/github" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestNewAzureADProviderDoesNotHavePerUserTokens(t *testing.T) { + t.Cleanup(cleanup) + newFlowCfg := map[string]any{ + "metadata": map[string]any{ + "name": "azure", + "annotations": map[string]any{"auth.cattle.io/azuread-endpoint-migrated": "true"}, + }, + "enabled": true, + "graphEndpoint": "https://graph.microsoft.com/", + } + + getter := newMockUnstructuredGetter() + obj := mockUnstructured{content: newFlowCfg} + getter.objects[azure.Name] = &obj + Providers[azure.Name] = &azure.Provider{Retriever: getter} + + hasPerUserSecrets, err := ProviderHasPerUserSecrets(azure.Name) + + require.NoError(t, err) + assert.False(t, hasPerUserSecrets) +} + +func TestOldAzureADProviderHasPerUserTokens(t *testing.T) { + t.Cleanup(cleanup) + oldFlowCfg := map[string]any{ + "metadata": map[string]any{ + "name": "azure", + }, + "enabled": true, + "graphEndpoint": "https://graph.windows.net/", + } + + getter := newMockUnstructuredGetter() + obj := mockUnstructured{content: oldFlowCfg} + getter.objects[azure.Name] = &obj + Providers[azure.Name] = &azure.Provider{Retriever: getter} + + hasPerUserSecrets, err := ProviderHasPerUserSecrets(azure.Name) + + require.NoError(t, err) + assert.True(t, hasPerUserSecrets) +} + +func TestBadAzureProviderDoesNotHavePerUserTokens(t *testing.T) { + t.Run("Azure Provider is not registered", func(t *testing.T) { + t.Cleanup(cleanup) + hasPerUserSecrets, err := ProviderHasPerUserSecrets(azure.Name) + + require.Error(t, err) + assert.False(t, hasPerUserSecrets) + }) + + t.Run("Azure Provider has the wrong type", func(t *testing.T) { + t.Cleanup(cleanup) + Providers[azure.Name] = fakeProvider{} + hasPerUserSecrets, err := ProviderHasPerUserSecrets(azure.Name) + + require.Error(t, err) + assert.False(t, hasPerUserSecrets) + }) + + t.Run("Config could not be fetch from Kubernetes", func(t *testing.T) { + t.Cleanup(cleanup) + getter := newMockUnstructuredGetter() + getter.errObjects[azure.Name] = errors.New("error getting config") + Providers[azure.Name] = &azure.Provider{Retriever: getter} + hasPerUserSecrets, err := ProviderHasPerUserSecrets(azure.Name) + + require.Error(t, err) + assert.False(t, hasPerUserSecrets) + }) +} + +func TestProviderHasPerUserTokens(t *testing.T) { + t.Cleanup(cleanup) + hasPerUserSecrets, err := ProviderHasPerUserSecrets(github.Name) + + require.NoError(t, err) + assert.False(t, hasPerUserSecrets) + + providersWithSecrets[github.Name] = true + hasPerUserSecrets, err = ProviderHasPerUserSecrets(github.Name) + + require.NoError(t, err) + assert.True(t, hasPerUserSecrets) +} + +func cleanup() { + Providers = make(map[string]common.AuthProvider) + providersWithSecrets = make(map[string]bool) +} + +type mockUnstructuredGetter struct { + objects map[string]runtime.Object + errObjects map[string]error +} + +func newMockUnstructuredGetter() *mockUnstructuredGetter { + return &mockUnstructuredGetter{ + objects: map[string]runtime.Object{}, + errObjects: map[string]error{}, + } +} + +func (m *mockUnstructuredGetter) Get(name string, _ metav1.GetOptions) (runtime.Object, error) { + if obj, ok := m.objects[name]; ok { + return obj, nil + } + if err, ok := m.errObjects[name]; ok { + return nil, err + } + return nil, fmt.Errorf("object %s not found", name) +} + +func (m *mockUnstructuredGetter) addObject(name string, object runtime.Object) { + m.objects[name] = object +} + +func (m *mockUnstructuredGetter) addErr(name string, err error) { + m.errObjects[name] = err +} + +type mockUnstructured struct { + content map[string]interface{} +} + +func (m *mockUnstructured) NewEmptyInstance() runtime.Unstructured { return nil } +func (m *mockUnstructured) UnstructuredContent() map[string]interface{} { return m.content } +func (m *mockUnstructured) SetUnstructuredContent(input map[string]interface{}) { m.content = input } +func (m *mockUnstructured) IsList() bool { return false } +func (m *mockUnstructured) EachListItem(func(runtime.Object) error) error { return nil } +func (m *mockUnstructured) EachListItemWithAlloc(func(runtime.Object) error) error { return nil } +func (m *mockUnstructured) GetObjectKind() schema.ObjectKind { return nil } +func (m *mockUnstructured) DeepCopyObject() runtime.Object { return nil } + +type fakeProvider struct{} + +func (f fakeProvider) GetName() string { + panic("implement me") +} + +func (f fakeProvider) AuthenticateUser(_ context.Context, _ interface{}) (v3.Principal, []v3.Principal, string, error) { + panic("implement me") +} + +func (f fakeProvider) SearchPrincipals(_, _ string, _ v3.Token) ([]v3.Principal, error) { + panic("implement me") +} + +func (f fakeProvider) GetPrincipal(_ string, _ v3.Token) (v3.Principal, error) { + panic("implement me") +} + +func (f fakeProvider) CustomizeSchema(_ *types.Schema) { + panic("implement me") +} + +func (f fakeProvider) TransformToAuthProvider(_ map[string]interface{}) (map[string]interface{}, error) { + panic("implement me") +} + +func (f fakeProvider) RefetchGroupPrincipals(_ string, _ string) ([]v3.Principal, error) { + panic("implement me") +} + +func (f fakeProvider) CanAccessWithGroupProviders(_ string, _ []v3.Principal) (bool, error) { + panic("implement me") +} + +func (f fakeProvider) GetUserExtraAttributes(_ v3.Principal) map[string][]string { + panic("implement me") +} + +func (f fakeProvider) IsDisabledProvider() (bool, error) { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/handler.go new file mode 100644 index 0000000..8d4d1fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/handler.go @@ -0,0 +1,72 @@ +package publicapi + +import ( + "context" + "net/http" + + normanapi "github.com/rancher/norman/api" + "github.com/rancher/norman/store/subtype" + "github.com/rancher/norman/types" + v3public "github.com/rancher/rancher/pkg/client/generated/management/v3public" + publicSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3public" + "github.com/rancher/rancher/pkg/types/config" +) + +type ServerOption func(server *normanapi.Server) + +func NewHandler(ctx context.Context, mgmtCtx *config.ScaledContext, opts ...ServerOption) (http.Handler, error) { + schemas := types.NewSchemas().AddSchemas(publicSchema.PublicSchemas) + if err := authProviderSchemas(ctx, mgmtCtx, schemas); err != nil { + return nil, err + } + + server := normanapi.NewAPIServer() + if err := server.AddSchemas(schemas); err != nil { + return nil, err + } + + for _, opt := range opts { + opt(server) + } + + return server, nil +} + +var authProviderTypes = []string{ + v3public.ActiveDirectoryProviderType, + v3public.AzureADProviderType, + v3public.GithubProviderType, + v3public.LocalProviderType, + v3public.OpenLdapProviderType, + v3public.FreeIpaProviderType, + v3public.PingProviderType, + v3public.ADFSProviderType, + v3public.KeyCloakProviderType, + v3public.OKTAProviderType, + v3public.ShibbolethProviderType, + v3public.GoogleOAuthProviderType, + v3public.OIDCProviderType, + v3public.KeyCloakOIDCProviderType, + v3public.GenericOIDCProviderType, +} + +func authProviderSchemas(ctx context.Context, management *config.ScaledContext, schemas *types.Schemas) error { + schema := schemas.Schema(&publicSchema.PublicVersion, v3public.AuthProviderType) + setAuthProvidersStore(schema, management) + lh := newLoginHandler(ctx, management) + + for _, apSubtype := range authProviderTypes { + subSchema := schemas.Schema(&publicSchema.PublicVersion, apSubtype) + subSchema.Store = subtype.NewSubTypeStore(apSubtype, schema.Store) + subSchema.ActionHandler = lh.login + subSchema.Formatter = loginActionFormatter + } + + schema = schemas.Schema(&publicSchema.PublicVersion, v3public.AuthTokenType) + setAuthTokensStore(schema, management) + return nil +} + +func loginActionFormatter(apiContext *types.APIContext, resource *types.RawResource) { + resource.AddAction(apiContext, "login") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/login.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/login.go new file mode 100644 index 0000000..9a98831 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/login.go @@ -0,0 +1,264 @@ +package publicapi + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "time" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + apiv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/providers/activedirectory" + "github.com/rancher/rancher/pkg/auth/providers/azure" + "github.com/rancher/rancher/pkg/auth/providers/genericoidc" + "github.com/rancher/rancher/pkg/auth/providers/github" + "github.com/rancher/rancher/pkg/auth/providers/googleoauth" + "github.com/rancher/rancher/pkg/auth/providers/keycloakoidc" + "github.com/rancher/rancher/pkg/auth/providers/ldap" + "github.com/rancher/rancher/pkg/auth/providers/local" + "github.com/rancher/rancher/pkg/auth/providers/oidc" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/auth/util" + client "github.com/rancher/rancher/pkg/client/generated/management/v3public" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3public" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/utils/pointer" +) + +const ( + CookieName = "R_SESS" +) + +func newLoginHandler(ctx context.Context, mgmt *config.ScaledContext) *loginHandler { + return &loginHandler{ + scaledContext: mgmt, + userMGR: mgmt.UserManager, + tokenMGR: tokens.NewManager(ctx, mgmt), + clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + secretLister: mgmt.Core.Secrets("").Controller().Lister(), + } +} + +type loginHandler struct { + scaledContext *config.ScaledContext + userMGR user.Manager + tokenMGR *tokens.Manager + clusterLister v3.ClusterLister + secretLister v1.SecretLister +} + +func (h *loginHandler) login(actionName string, action *types.Action, request *types.APIContext) error { + if actionName != "login" { + return httperror.NewAPIError(httperror.ActionNotAvailable, "") + } + + w := request.Response + + token, unhashedTokenKey, responseType, err := h.createLoginToken(request) + if err != nil { + // if user fails to authenticate, hide the details of the exact error. bad credentials will already be APIErrors + // otherwise, return a generic error message + if httperror.IsAPIError(err) { + return err + } + return httperror.WrapAPIError(err, httperror.ServerError, "Server error while authenticating") + } + + if responseType == "cookie" { + tokenCookie := &http.Cookie{ + Name: CookieName, + Value: token.ObjectMeta.Name + ":" + unhashedTokenKey, + Secure: true, + Path: "/", + HttpOnly: true, + } + http.SetCookie(w, tokenCookie) + } else if responseType == "saml" { + return nil + } else { + tokenData, err := tokens.ConvertTokenResource(request.Schemas.Schema(&schema.PublicVersion, client.TokenType), token) + if err != nil { + return httperror.WrapAPIError(err, httperror.ServerError, "Server error while authenticating") + } + tokenData["token"] = token.ObjectMeta.Name + ":" + unhashedTokenKey + request.WriteResponse(http.StatusCreated, tokenData) + } + + return nil +} + +// createLoginToken returns token, unhashed token key (where applicable), responseType and error +func (h *loginHandler) createLoginToken(request *types.APIContext) (v3.Token, string, string, error) { + var userPrincipal v3.Principal + var groupPrincipals []v3.Principal + var providerToken string + logrus.Debugf("Create Token Invoked") + + bytes, err := ioutil.ReadAll(request.Request.Body) + if err != nil { + logrus.Errorf("login failed with error: %v", err) + return v3.Token{}, "", "", httperror.NewAPIError(httperror.InvalidBodyContent, "") + } + + generic := &apiv3.GenericLogin{} + err = json.Unmarshal(bytes, generic) + if err != nil { + logrus.Errorf("unmarshal failed with error: %v", err) + return v3.Token{}, "", "", httperror.NewAPIError(httperror.InvalidBodyContent, "") + } + responseType := generic.ResponseType + description := generic.Description + ttl := generic.TTLMillis + + authTimeout := settings.AuthUserSessionTTLMinutes.Get() + if minutes, err := strconv.ParseInt(authTimeout, 10, 64); err == nil { + ttl = minutes * 60 * 1000 + } + + var input interface{} + var providerName string + switch request.Type { + case client.LocalProviderType: + input = &apiv3.BasicLogin{} + providerName = local.Name + case client.GithubProviderType: + input = &apiv3.GithubLogin{} + providerName = github.Name + case client.ActiveDirectoryProviderType: + input = &apiv3.BasicLogin{} + providerName = activedirectory.Name + case client.AzureADProviderType: + input = &apiv3.AzureADLogin{} + providerName = azure.Name + case client.OpenLdapProviderType: + input = &apiv3.BasicLogin{} + providerName = ldap.OpenLdapName + case client.FreeIpaProviderType: + input = &apiv3.BasicLogin{} + providerName = ldap.FreeIpaName + case client.PingProviderType: + input = &apiv3.SamlLoginInput{} + providerName = saml.PingName + case client.ADFSProviderType: + input = &apiv3.SamlLoginInput{} + providerName = saml.ADFSName + case client.KeyCloakProviderType: + input = &apiv3.SamlLoginInput{} + providerName = saml.KeyCloakName + case client.OKTAProviderType: + input = &apiv3.SamlLoginInput{} + providerName = saml.OKTAName + case client.ShibbolethProviderType: + input = &apiv3.SamlLoginInput{} + providerName = saml.ShibbolethName + case client.GoogleOAuthProviderType: + input = &apiv3.GoogleOauthLogin{} + providerName = googleoauth.Name + case client.OIDCProviderType: + input = &apiv3.OIDCLogin{} + providerName = oidc.Name + case client.KeyCloakOIDCProviderType: + input = &apiv3.OIDCLogin{} + providerName = keycloakoidc.Name + case client.GenericOIDCProviderType: + input = &apiv3.OIDCLogin{} + providerName = genericoidc.Name + default: + return v3.Token{}, "", "", httperror.NewAPIError(httperror.ServerError, "unknown authentication provider") + } + + err = json.Unmarshal(bytes, input) + if err != nil { + logrus.Errorf("unmarshal failed with error: %v", err) + return v3.Token{}, "", "", httperror.NewAPIError(httperror.InvalidBodyContent, "") + } + + // Authenticate User + // SAML's login flow is different from the other providers. Unlike the other providers, it gets the logged in user's data via a POST from + // the identity provider on a separate endpoint specifically for that. + + if providerName == saml.PingName || providerName == saml.ADFSName || providerName == saml.KeyCloakName || + providerName == saml.OKTAName || providerName == saml.ShibbolethName { + err = saml.PerformSamlLogin(providerName, request, input) + return v3.Token{}, "", "saml", err + } + + ctx := context.WithValue(request.Request.Context(), util.RequestKey, request.Request) + userPrincipal, groupPrincipals, providerToken, err = providers.AuthenticateUser(ctx, input, providerName) + if err != nil { + return v3.Token{}, "", "", err + } + + displayName := userPrincipal.DisplayName + if displayName == "" { + displayName = userPrincipal.LoginName + } + + var backoff = wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 2, + Jitter: .2, + Steps: 5, + } + + var ( + enabled bool + currUser *v3.User + ) + + err = wait.ExponentialBackoffWithContext(ctx, backoff, func(_ context.Context) (bool, error) { + var err error + + currUser, err = h.userMGR.EnsureUser(userPrincipal.Name, displayName) + if err != nil { + logrus.Warnf("Error creating or updating user for %s, retrying: %v", currUser.Name, err) + return false, nil + } + + enabled = pointer.BoolDeref(currUser.Enabled, true) + if !enabled { + return true, nil + } + + loginTime := time.Now() + userExtraInfo := providers.GetUserExtraAttributes(providerName, userPrincipal) + err = h.tokenMGR.UserAttributeCreateOrUpdate(currUser.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo, loginTime) + if err != nil { + logrus.Warnf("Error creating or updating userAttribute for %s, retrying: %v", currUser.Name, err) + return false, nil + } + + return true, nil + }) + if err != nil { + return v3.Token{}, "", "", fmt.Errorf("error creating or updating user and/or userAttribute for %s: %w", currUser.Name, err) + } + + if !enabled { + return v3.Token{}, "", "", httperror.NewAPIError(httperror.PermissionDenied, "Permission Denied") + } + + if strings.HasPrefix(responseType, tokens.KubeconfigResponseType) { + token, tokenValue, err := tokens.GetKubeConfigToken(currUser.Name, responseType, h.userMGR, userPrincipal) + if err != nil { + return v3.Token{}, "", "", err + } + return *token, tokenValue, responseType, nil + } + + rToken, unhashedTokenKey, err := h.tokenMGR.NewLoginToken(currUser.Name, userPrincipal, groupPrincipals, providerToken, ttl, description) + return rToken, unhashedTokenKey, responseType, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/store.go new file mode 100644 index 0000000..9fe8bd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/publicapi/store.go @@ -0,0 +1,135 @@ +package publicapi + +import ( + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/store/empty" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/auth/util" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +func setAuthProvidersStore(schema *types.Schema, apiContext *config.ScaledContext) { + schema.Store = &authProvidersStore{ + authConfigsRaw: apiContext.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), + } +} + +type authProvidersStore struct { + empty.Store + authConfigsRaw objectclient.GenericClient +} + +func (s *authProvidersStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + o, err := s.authConfigsRaw.Get(id, v1.GetOptions{}) + if err != nil { + return nil, err + } + u, _ := o.(runtime.Unstructured) + config := u.UnstructuredContent() + if t, ok := config["type"].(string); ok && t != "" { + config[".host"] = util.GetHost(apiContext.Request) + provider, err := providers.GetProviderByType(t).TransformToAuthProvider(config) + if err != nil { + return nil, err + } + return provider, nil + } + + return nil, httperror.NewAPIError(httperror.NotFound, "") +} + +func (s *authProvidersStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + rrr, _ := s.authConfigsRaw.List(v1.ListOptions{}) + var result []map[string]interface{} + list, _ := rrr.(*unstructured.UnstructuredList) + for _, i := range list.Items { + if t, ok := i.Object["type"].(string); ok && t != "" { + if enabled, ok := i.Object["enabled"].(bool); ok && enabled { + i.Object[".host"] = util.GetHost(apiContext.Request) + provider, err := providers.GetProviderByType(t).TransformToAuthProvider(i.Object) + if err != nil { + return result, err + } + result = append(result, provider) + } + } + } + return result, nil +} + +func (s *authProvidersStore) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { + result, err := s.Update(apiContext, schema, data, id) + if err != nil { + return nil, err + } + if strings.EqualFold(settings.FirstLogin.Get(), "true") { + if err := settings.FirstLogin.Set("false"); err != nil { + return nil, err + } + } + return result, nil +} + +func setAuthTokensStore(schema *types.Schema, apiContext *config.ScaledContext) { + schema.Store = &authTokensStore{ + tokens: apiContext.Management.SamlTokens(""), + } +} + +type authTokensStore struct { + empty.Store + tokens v3.SamlTokenInterface +} + +func (t *authTokensStore) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + token, err := t.tokens.GetNamespaced(namespace.GlobalNamespace, id, v1.GetOptions{}) + if err != nil { + return nil, err + } + generated := transformToAuthToken(token) + return generated, err +} + +func (t *authTokensStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { + tokens, err := t.tokens.ListNamespaced(namespace.GlobalNamespace, v1.ListOptions{}) + if err != nil { + return nil, err + } + var result []map[string]interface{} + for _, token := range tokens.Items { + generated := transformToAuthToken(&token) + result = append(result, generated) + } + return result, nil +} + +func (t *authTokensStore) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) { + if err := t.tokens.DeleteNamespaced(namespace.GlobalNamespace, id, &v1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return nil, err + } + return nil, nil +} + +func transformToAuthToken(token *v3.SamlToken) map[string]interface{} { + generated := map[string]interface{}{} + if token == nil { + return generated + } + generated["id"] = token.Name + generated["type"] = "authToken" + generated["name"] = token.Name + generated["token"] = token.Token + generated["expiresAt"] = token.ExpiresAt + return generated +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_actions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_actions.go new file mode 100644 index 0000000..e7b773e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_actions.go @@ -0,0 +1,78 @@ +package saml + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/sirupsen/logrus" +) + +func (s *Provider) formatter(apiContext *types.APIContext, resource *types.RawResource) { + common.AddCommonActions(apiContext, resource) + resource.AddAction(apiContext, "testAndEnable") +} + +func (s *Provider) actionHandler(actionName string, action *types.Action, request *types.APIContext) error { + handled, err := common.HandleCommonAction(actionName, action, request, s.name, s.authConfigs) + if err != nil { + return err + } + if handled { + return nil + } + + if actionName == "testAndEnable" { + return s.testAndEnable(actionName, action, request) + } + + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (s *Provider) testAndEnable(actionName string, action *types.Action, request *types.APIContext) error { + // get Final redirect URL from request body + + samlLogin := &v32.SamlConfigTestInput{} + if err := json.NewDecoder(request.Request.Body).Decode(samlLogin); err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, + fmt.Sprintf("SAML: Failed to parse body: %v", err)) + } + + samlConfig, err := s.getSamlConfig() + if err != nil { + return err + } + + logrus.Debug("SAML [testAndEnable]: Initializing SAML service provider") + err = InitializeSamlServiceProvider(samlConfig, s.name) + if err != nil { + return err + } + + provider, ok := SamlProviders[s.name] + if !ok { + return fmt.Errorf("SAML [testAndEnable]: Provider %v not configured", s.name) + } + + logrus.Debugf("SAML [testAndEnable]: Setting clientState for SAML service provider %v", s.name) + finalRedirectURL := samlLogin.FinalRedirectURL + provider.clientState.SetState(request.Response, request.Request, "Rancher_UserID", provider.userMGR.GetUser(request)) + provider.clientState.SetState(request.Response, request.Request, "Rancher_FinalRedirectURL", finalRedirectURL) + provider.clientState.SetState(request.Response, request.Request, "Rancher_Action", testAndEnableAction) + idpRedirectURL, err := provider.HandleSamlLogin(request.Response, request.Request) + if err != nil { + return err + } + logrus.Debugf("SAML [testAndEnable]: Redirecting to the identity provider login page at %v", idpRedirectURL) + data := map[string]interface{}{ + "idpRedirectUrl": idpRedirectURL, + "type": "samlConfigTestOutput", + } + + request.WriteResponse(http.StatusOK, data) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client.go new file mode 100644 index 0000000..ad9e526 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client.go @@ -0,0 +1,497 @@ +package saml + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "encoding/xml" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/crewjam/saml" + "github.com/gorilla/mux" + responsewriter "github.com/rancher/apiserver/pkg/middleware" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +type IDPMetadata struct { + XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:metadata EntityDescriptor"` + ValidUntil time.Time `xml:"validUntil,attr"` + EntityID string `xml:"entityID,attr"` + IDPSSODescriptors []saml.IDPSSODescriptor `xml:"IDPSSODescriptor"` + SPSSODescriptors []saml.SPSSODescriptor `xml:"SPSSODescriptor"` +} + +var root *mux.Router +var appliedVersion string +var initMu sync.Mutex + +const UITranslationKeyForErrorMessage = "invalidSamlAttrs" + +func InitializeSamlServiceProvider(configToSet *v32.SamlConfig, name string) error { + + initMu.Lock() + defer initMu.Unlock() + + if configToSet.ResourceVersion == appliedVersion { + return nil + } + + var privKey *rsa.PrivateKey + var cert *x509.Certificate + var err error + var ok bool + + log.Debugf("SAML [InitializeSamlServiceProvider]: Validating input for provider %v", name) + + if configToSet.IDPMetadataContent == "" { + return fmt.Errorf("SAML: Cannot initialize saml SP properly, missing IDP URL/metadata in the config %v", configToSet) + } + + if configToSet.SpCert == "" { + return fmt.Errorf("SAML: Cannot initialize saml SP properly, missing SpCert in the config %v", configToSet) + } + + if configToSet.SpKey == "" { + return fmt.Errorf("SAML: Cannot initialize saml SP properly, missing SpKey in the config %v", configToSet) + } + + if configToSet.SpKey != "" { + // used from ssh.ParseRawPrivateKey + + block, _ := pem.Decode([]byte(configToSet.SpKey)) + if block == nil { + return fmt.Errorf("SAML: no key found") + } + + if strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED") { + return fmt.Errorf("SAML: cannot decode encrypted private keys") + } + + switch block.Type { + case "RSA PRIVATE KEY": + privKey, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return fmt.Errorf("SAML: error parsing PKCS1 RSA key: %v", err) + } + case "PRIVATE KEY": + pk, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return fmt.Errorf("SAML: error parsing PKCS8 RSA key: %v", err) + } + privKey, ok = pk.(*rsa.PrivateKey) + if !ok { + return fmt.Errorf("SAML: unable to get rsa key") + } + default: + return fmt.Errorf("SAML: unsupported key type %q", block.Type) + } + } + + if configToSet.SpCert != "" { + block, _ := pem.Decode([]byte(configToSet.SpCert)) + if block == nil { + return fmt.Errorf("SAML: failed to parse PEM block containing the private key") + } + + cert, err = x509.ParseCertificate(block.Bytes) + if err != nil { + return fmt.Errorf("SAML: failed to parse DER encoded public key: " + err.Error()) + } + } + + provider, ok := SamlProviders[name] + if !ok { + return fmt.Errorf("SAML [InitializeSamlServiceProvider]: Provider %v not configured", name) + } + + log.Debugf("SAML [InitializeSamlServiceProvider]: Initializing provider %v", name) + + rancherAPIHost := strings.TrimRight(configToSet.RancherAPIHost, "/") + samlURL := rancherAPIHost + "/v1-saml/" + samlURL += name + actURL, err := url.Parse(samlURL) + if err != nil { + return fmt.Errorf("SAML: error in parsing URL") + } + + metadataURL := *actURL + metadataURL.Path = metadataURL.Path + "/saml/metadata" + acsURL := *actURL + acsURL.Path = acsURL.Path + "/saml/acs" + + sp := saml.ServiceProvider{ + Key: privKey, + Certificate: cert, + MetadataURL: metadataURL, + AcsURL: acsURL, + EntityID: configToSet.EntityID, + } + + // XML unmarshal throws an error for IdP Metadata cacheDuration field, as it's of type xml Duration. Using a separate struct for unmarshaling for now + idm := &IDPMetadata{} + if configToSet.IDPMetadataContent != "" { + sp.IDPMetadata = &saml.EntityDescriptor{} + if err := xml.NewDecoder(strings.NewReader(configToSet.IDPMetadataContent)).Decode(idm); err != nil { + return fmt.Errorf("SAML: cannot initialize saml SP, cannot decode IDP Metadata content from the config %v, error %v", configToSet, err) + } + } + + sp.IDPMetadata.XMLName = idm.XMLName + sp.IDPMetadata.ValidUntil = idm.ValidUntil + sp.IDPMetadata.EntityID = idm.EntityID + sp.IDPMetadata.SPSSODescriptors = idm.SPSSODescriptors + sp.IDPMetadata.IDPSSODescriptors = idm.IDPSSODescriptors + if name == ADFSName || name == OKTAName { + sp.AuthnNameIDFormat = saml.UnspecifiedNameIDFormat + } + + provider.serviceProvider = &sp + + cookieStore := ClientCookies{ + ServiceProvider: &sp, + Name: "token", + Domain: actURL.Host, + } + + provider.clientState = &cookieStore + + root.Use(responsewriter.ContentTypeOptions) + + SamlProviders[name] = provider + + switch name { + case PingName: + root.Get("PingACS").HandlerFunc(provider.ServeHTTP) + root.Get("PingMetadata").HandlerFunc(provider.ServeHTTP) + case ADFSName: + root.Get("AdfsACS").HandlerFunc(provider.ServeHTTP) + root.Get("AdfsMetadata").HandlerFunc(provider.ServeHTTP) + case KeyCloakName: + root.Get("KeyCloakACS").HandlerFunc(provider.ServeHTTP) + root.Get("KeyCloakMetadata").HandlerFunc(provider.ServeHTTP) + case OKTAName: + root.Get("OktaACS").HandlerFunc(provider.ServeHTTP) + root.Get("OktaMetadata").HandlerFunc(provider.ServeHTTP) + case ShibbolethName: + root.Get("ShibbolethACS").HandlerFunc(provider.ServeHTTP) + root.Get("ShibbolethMetadata").HandlerFunc(provider.ServeHTTP) + } + + appliedVersion = configToSet.ResourceVersion + + return nil +} + +func AuthHandler() http.Handler { + root = mux.NewRouter() + + root.Methods("POST").Path("/v1-saml/ping/saml/acs").Name("PingACS") + root.Methods("GET").Path("/v1-saml/ping/saml/metadata").Name("PingMetadata") + + root.Methods("POST").Path("/v1-saml/adfs/saml/acs").Name("AdfsACS") + root.Methods("GET").Path("/v1-saml/adfs/saml/metadata").Name("AdfsMetadata") + + root.Methods("POST").Path("/v1-saml/keycloak/saml/acs").Name("KeyCloakACS") + root.Methods("GET").Path("/v1-saml/keycloak/saml/metadata").Name("KeyCloakMetadata") + + root.Methods("POST").Path("/v1-saml/okta/saml/acs").Name("OktaACS") + root.Methods("GET").Path("/v1-saml/okta/saml/metadata").Name("OktaMetadata") + + root.Methods("POST").Path("/v1-saml/shibboleth/saml/acs").Name("ShibbolethACS") + root.Methods("GET").Path("/v1-saml/shibboleth/saml/metadata").Name("ShibbolethMetadata") + + return root +} + +func (s *Provider) getSamlPrincipals(config *v32.SamlConfig, samlData map[string][]string) (v3.Principal, []v3.Principal, error) { + var userPrincipal v3.Principal + var groupPrincipals []v3.Principal + uid, ok := samlData[config.UIDField] + if !ok { + // UID field provided by user is actually not there in SAMLResponse, without this we cannot differentiate between users and create separate principals + return userPrincipal, groupPrincipals, fmt.Errorf("SAML: Unique ID field is not provided in SAML Response") + } + userPrincipal = v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: s.userType + "://" + uid[0]}, + Provider: s.name, + PrincipalType: "user", + Me: true, + } + + displayName, ok := samlData[config.DisplayNameField] + if ok { + userPrincipal.DisplayName = displayName[0] + } + + userName, ok := samlData[config.UserNameField] + if ok { + userPrincipal.LoginName = userName[0] + } + + groups, ok := samlData[config.GroupsField] + if ok { + for _, group := range groups { + group := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: s.groupType + "://" + group}, + DisplayName: group, + Provider: s.name, + PrincipalType: "group", + MemberOf: true, + } + groupPrincipals = append(groupPrincipals, group) + } + } + + return userPrincipal, groupPrincipals, nil +} + +// HandleSamlAssertion processes/handles the assertion obtained by the POST to /saml/acs from IdP +func (s *Provider) HandleSamlAssertion(w http.ResponseWriter, r *http.Request, assertion *saml.Assertion) { + var groupPrincipals []v3.Principal + var userPrincipal v3.Principal + + if relayState := r.Form.Get("RelayState"); relayState != "" { + // delete the cookie + s.clientState.DeleteState(w, r, relayState) + } + + redirectURL := s.clientState.GetState(r, "Rancher_FinalRedirectURL") + rancherAction := s.clientState.GetState(r, "Rancher_Action") + if rancherAction == loginAction { + redirectURL += "/login?" + } else if rancherAction == testAndEnableAction { + // the first query param is config=saml_provider_name set by UI + redirectURL += "&" + } + + samlData := make(map[string][]string) + + for _, attributeStatement := range assertion.AttributeStatements { + for _, attr := range attributeStatement.Attributes { + attrName := attr.FriendlyName + if attrName == "" { + attrName = attr.Name + } + for _, value := range attr.Values { + samlData[attrName] = append(samlData[attrName], value.Value) + } + } + } + + config, err := s.getSamlConfig() + if err != nil { + log.Errorf("SAML: Error getting saml config %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + + userPrincipal, groupPrincipals, err = s.getSamlPrincipals(config, samlData) + if err != nil { + log.Error(err) + // UI uses this translation key to get the error message + http.Redirect(w, r, redirectURL+"errorCode=422&errorMsg="+UITranslationKeyForErrorMessage, http.StatusFound) + return + } + allowedPrincipals := config.AllowedPrincipalIDs + + allowed, err := s.userMGR.CheckAccess(config.AccessMode, allowedPrincipals, userPrincipal.Name, groupPrincipals) + if err != nil { + log.Errorf("SAML: Error during login while checking access %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + if !allowed { + log.Errorf("SAML: User [%s] is not an authorized user or is not a member of an authorized group", userPrincipal.Name) + http.Redirect(w, r, redirectURL+"errorCode=403", http.StatusFound) + return + } + + userID := s.clientState.GetState(r, "Rancher_UserID") + if userID != "" && rancherAction == testAndEnableAction { + user, err := s.userMGR.SetPrincipalOnCurrentUserByUserID(userID, userPrincipal) + if err != nil && user == nil { + log.Errorf("SAML: Error setting principal on current user %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } else if err != nil && user != nil { + http.Redirect(w, r, redirectURL+"errorCode=422&errorMsg="+err.Error(), http.StatusFound) + return + } + + config.Enabled = true + err = s.saveSamlConfig(config) + if err != nil { + log.Errorf("SAML: Error saving saml config %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + + isSecure := false + if r.URL.Scheme == "https" { + isSecure = true + } + err = s.setRancherToken(w, s.tokenMGR, user.Name, userPrincipal, groupPrincipals, isSecure) + if err != nil { + log.Errorf("SAML: Failed creating token with error: %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + } + // delete the cookies + s.clientState.DeleteState(w, r, "Rancher_UserID") + s.clientState.DeleteState(w, r, "Rancher_Action") + redirectURL := s.clientState.GetState(r, "Rancher_FinalRedirectURL") + s.clientState.DeleteState(w, r, "Rancher_FinalRedirectURL") + if redirectURL != "" { + // delete the cookie + s.clientState.DeleteState(w, r, "Rancher_FinalRedirectURL") + http.Redirect(w, r, redirectURL, http.StatusFound) + } + return + } + + displayName := userPrincipal.DisplayName + if displayName == "" { + displayName = userPrincipal.LoginName + } + user, err := s.userMGR.EnsureUser(userPrincipal.Name, displayName) + if err != nil { + log.Errorf("SAML: Failed getting user with error: %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + + if user.Enabled != nil && !*user.Enabled { + log.Errorf("SAML: User %v permission denied", user.Name) + http.Redirect(w, r, redirectURL+"errorCode=403", http.StatusFound) + return + } + + loginTime := time.Now() + userExtraInfo := s.GetUserExtraAttributes(userPrincipal) + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + return s.tokenMGR.UserAttributeCreateOrUpdate(user.Name, userPrincipal.Provider, groupPrincipals, userExtraInfo, loginTime) + }); err != nil { + log.Errorf("SAML: Failed creating or updating userAttribute with error: %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + + err = s.setRancherToken(w, s.tokenMGR, user.Name, userPrincipal, groupPrincipals, true) + if err != nil { + log.Errorf("SAML: Failed creating token with error: %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + } + redirectURL = s.clientState.GetState(r, "Rancher_FinalRedirectURL") + + if redirectURL != "" { + // delete the cookie + s.clientState.DeleteState(w, r, "Rancher_FinalRedirectURL") + + requestID := s.clientState.GetState(r, "Rancher_RequestID") + log.Debugf("SAML: requestID: %s", requestID) + if requestID != "" { + // generate kubeconfig saml token + responseType := s.clientState.GetState(r, "Rancher_ResponseType") + publicKey := s.clientState.GetState(r, "Rancher_PublicKey") + + token, tokenValue, err := tokens.GetKubeConfigToken(user.Name, responseType, s.userMGR, userPrincipal) + if err != nil { + log.Errorf("SAML: getToken error %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + + keyBytes, err := base64.StdEncoding.DecodeString(publicKey) + if err != nil { + log.Errorf("SAML: base64 DecodeString error %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + pubKey := &rsa.PublicKey{} + err = json.Unmarshal(keyBytes, pubKey) + if err != nil { + log.Errorf("SAML: getPublicKey error %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + encryptedToken, err := rsa.EncryptOAEP( + sha256.New(), + rand.Reader, + pubKey, + []byte(fmt.Sprintf("%s:%s", token.ObjectMeta.Name, tokenValue)), + nil) + if err != nil { + log.Errorf("SAML: getEncryptedToken error %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + return + } + encoded := base64.StdEncoding.EncodeToString(encryptedToken) + + samlToken := &v3.SamlToken{ + Token: encoded, + ExpiresAt: token.ExpiresAt, + ObjectMeta: v1.ObjectMeta{ + Name: requestID, + Namespace: namespace.GlobalNamespace, + }, + } + + _, err = s.samlTokens.Create(samlToken) + if err != nil { + log.Errorf("SAML: createToken err %v", err) + http.Redirect(w, r, redirectURL+"errorCode=500", http.StatusFound) + } + + s.clientState.DeleteState(w, r, "Rancher_ConnToken") + s.clientState.DeleteState(w, r, "Rancher_RequestUUID") + s.clientState.DeleteState(w, r, "Rancher_ResponseType") + s.clientState.DeleteState(w, r, "Rancher_PublicKey") + + } + + http.Redirect(w, r, redirectURL, http.StatusFound) + return + } +} + +func (s *Provider) setRancherToken(w http.ResponseWriter, tokenMGR *tokens.Manager, userID string, userPrincipal v3.Principal, + groupPrincipals []v3.Principal, isSecure bool) error { + authTimeout := settings.AuthUserSessionTTLMinutes.Get() + var ttl int64 + if minutes, err := strconv.ParseInt(authTimeout, 10, 64); err == nil { + ttl = minutes * 60 * 1000 + } + + rToken, unhashedTokenKey, err := tokenMGR.NewLoginToken(userID, userPrincipal, groupPrincipals, "", ttl, "") + if err != nil { + return err + } + + tokenCookie := &http.Cookie{ + Name: "R_SESS", + Value: rToken.ObjectMeta.Name + ":" + unhashedTokenKey, + Secure: isSecure, + Path: "/", + HttpOnly: true, + } + http.SetCookie(w, tokenCookie) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client_cookies.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client_cookies.go new file mode 100644 index 0000000..a1cedfa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_client_cookies.go @@ -0,0 +1,100 @@ +package saml + +import ( + "net/http" + "strings" + "time" + + "github.com/crewjam/saml" +) + +// ClientState implements client side storage for state. +type ClientState interface { + SetState(w http.ResponseWriter, r *http.Request, id string, value string) + GetStates(r *http.Request) map[string]string + GetState(r *http.Request, id string) string + DeleteState(w http.ResponseWriter, r *http.Request, id string) error +} + +// ClientToken implements client side storage for signed authorization tokens. +type ClientToken interface { + GetToken(r *http.Request) string + SetToken(w http.ResponseWriter, r *http.Request, value string, maxAge time.Duration) +} + +const stateCookiePrefix = "saml_" + +type ClientCookies struct { + ServiceProvider *saml.ServiceProvider + Name string + Domain string + Secure bool +} + +// SetState stores the named state value by setting a cookie. +func (c ClientCookies) SetState(w http.ResponseWriter, r *http.Request, id string, value string) { + http.SetCookie(w, &http.Cookie{ + Name: stateCookiePrefix + id, + Value: value, + MaxAge: int(saml.MaxIssueDelay.Seconds()), + HttpOnly: true, + Secure: c.Secure || r.URL.Scheme == "https", + Path: c.ServiceProvider.AcsURL.Path, + }) +} + +// GetStates returns the currently stored states by reading cookies. +func (c ClientCookies) GetStates(r *http.Request) map[string]string { + rv := map[string]string{} + for _, cookie := range r.Cookies() { + if !strings.HasPrefix(cookie.Name, stateCookiePrefix) { + continue + } + name := strings.TrimPrefix(cookie.Name, stateCookiePrefix) + rv[name] = cookie.Value + } + return rv +} + +// GetState returns a single stored state by reading the cookies +func (c ClientCookies) GetState(r *http.Request, id string) string { + stateCookie, err := r.Cookie(stateCookiePrefix + id) + if err != nil { + return "" + } + return stateCookie.Value +} + +// DeleteState removes the named stored state by clearing the corresponding cookie. +func (c ClientCookies) DeleteState(w http.ResponseWriter, r *http.Request, id string) error { + cookie, err := r.Cookie(stateCookiePrefix + id) + if err != nil { + return err + } + cookie.Value = "" + cookie.Expires = time.Unix(1, 0) // past time as close to epoch as possible, but not zero time.Time{} + http.SetCookie(w, cookie) + return nil +} + +// SetToken assigns the specified token by setting a cookie. +func (c ClientCookies) SetToken(w http.ResponseWriter, r *http.Request, value string, maxAge time.Duration) { + http.SetCookie(w, &http.Cookie{ + Name: c.Name, + Domain: c.Domain, + Value: value, + MaxAge: int(maxAge.Seconds()), + HttpOnly: true, + Secure: c.Secure || r.URL.Scheme == "https", + Path: "/", + }) +} + +// GetToken returns the token by reading the cookie. +func (c ClientCookies) GetToken(r *http.Request) string { + cookie, err := r.Cookie(c.Name) + if err != nil { + return "" + } + return cookie.Value +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_handlers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_handlers.go new file mode 100644 index 0000000..7239d20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_handlers.go @@ -0,0 +1,116 @@ +package saml + +import ( + "crypto/x509" + "encoding/base64" + "encoding/xml" + "fmt" + "net/http" + "strings" + + "github.com/crewjam/saml" + "github.com/golang-jwt/jwt" + log "github.com/sirupsen/logrus" +) + +// ServeHTTP is the handler for /saml/metadata and /saml/acs endpoints +func (s *Provider) ServeHTTP(w http.ResponseWriter, r *http.Request) { + serviceProvider := s.serviceProvider + if r.URL.Path == serviceProvider.MetadataURL.Path { + buf, _ := xml.MarshalIndent(serviceProvider.Metadata(), "", " ") + w.Header().Set("Content-Type", "application/samlmetadata+xml") + w.Write(buf) + return + } + + if r.URL.Path == serviceProvider.AcsURL.Path { + r.ParseForm() + assertion, err := serviceProvider.ParseResponse(r, s.getPossibleRequestIDs(r)) + if err != nil { + if parseErr, ok := err.(*saml.InvalidResponseError); ok { + log.Debugf("RESPONSE: ===\n%s\n===\nNOW: %s\nERROR: %s", + parseErr.Response, parseErr.Now, parseErr.PrivateErr) + } + redirectURL := r.URL.Host + "/login?errorCode=403" + http.Redirect(w, r, redirectURL, http.StatusFound) + return + } + s.HandleSamlAssertion(w, r, assertion) + return + } + + http.NotFoundHandler().ServeHTTP(w, r) +} + +func (s *Provider) getPossibleRequestIDs(r *http.Request) []string { + rv := []string{} + serviceProvider := s.serviceProvider + + for name, value := range s.clientState.GetStates(r) { + if strings.HasPrefix(name, "Rancher_") { + continue + } + jwtParser := jwt.Parser{ + ValidMethods: []string{jwt.SigningMethodHS256.Name}, + } + token, err := jwtParser.Parse(value, func(t *jwt.Token) (interface{}, error) { + secretBlock := x509.MarshalPKCS1PrivateKey(serviceProvider.Key) + return secretBlock, nil + }) + if err != nil || !token.Valid { + log.Debugf("... invalid token %s", err) + continue + } + claims := token.Claims.(jwt.MapClaims) + rv = append(rv, claims["id"].(string)) + } + return rv +} + +// HandleSamlLogin is the endpoint for /saml/login endpoint +func (s *Provider) HandleSamlLogin(w http.ResponseWriter, r *http.Request) (string, error) { + serviceProvider := s.serviceProvider + if r.URL.Path == serviceProvider.AcsURL.Path { + return "", fmt.Errorf("don't wrap Middleware with RequireAccount") + } + log.Debugf("SAML [HandleSamlLogin]: Creating authentication request for %v", s.name) + binding := saml.HTTPRedirectBinding + bindingLocation := serviceProvider.GetSSOBindingLocation(binding) + + req, err := serviceProvider.MakeAuthenticationRequest(bindingLocation, binding, saml.HTTPPostBinding) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return "", err + } + // relayState is limited to 80 bytes but also must be integrity protected. + // this means that we cannot use a JWT because it is way too long. Instead + // we set a cookie that corresponds to the state + relayState := base64.URLEncoding.EncodeToString(randomBytes(42)) + + secretBlock := x509.MarshalPKCS1PrivateKey(serviceProvider.Key) + state := jwt.New(jwt.SigningMethodHS256) + claims := state.Claims.(jwt.MapClaims) + claims["id"] = req.ID + claims["uri"] = r.URL.String() + signedState, err := state.SignedString(secretBlock) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return "", err + } + + s.clientState.SetState(w, r, relayState, signedState) + + redirectURL, err := req.Redirect(relayState, serviceProvider) + if err != nil { + return "", err + } + return redirectURL.String(), nil +} + +func randomBytes(n int) []byte { + rv := make([]byte, n) + if _, err := saml.RandReader.Read(rv); err != nil { + panic(err) + } + return rv +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider.go new file mode 100644 index 0000000..65c2007 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider.go @@ -0,0 +1,437 @@ +package saml + +import ( + "context" + "fmt" + "net/http" + "strings" + + "github.com/crewjam/saml" + "github.com/pkg/errors" + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/api/secrets" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/ldap" + "github.com/rancher/rancher/pkg/auth/tokens" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + PingName = "ping" + ADFSName = "adfs" + KeyCloakName = "keycloak" + OKTAName = "okta" + ShibbolethName = "shibboleth" + loginAction = "login" + testAndEnableAction = "testAndEnable" +) + +type Provider struct { + ctx context.Context + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface + samlTokens v3.SamlTokenInterface + userMGR user.Manager + tokenMGR *tokens.Manager + serviceProvider *saml.ServiceProvider + name string + userType string + groupType string + clientState ClientState + ldapProvider common.AuthProvider +} + +var SamlProviders = make(map[string]*Provider) + +func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.Manager, tokenMGR *tokens.Manager, name string) common.AuthProvider { + samlp := &Provider{ + ctx: ctx, + authConfigs: mgmtCtx.Management.AuthConfigs(""), + secrets: mgmtCtx.Core.Secrets(""), + samlTokens: mgmtCtx.Management.SamlTokens(""), + userMGR: userMGR, + tokenMGR: tokenMGR, + name: name, + userType: name + "_user", + groupType: name + "_group", + } + + if samlp.hasLdapGroupSearch() { + samlp.ldapProvider = ldap.Configure(ctx, mgmtCtx, userMGR, tokenMGR, name) + } + + SamlProviders[name] = samlp + return samlp +} + +func (s *Provider) GetName() string { + return s.name +} + +func (s *Provider) CustomizeSchema(schema *types.Schema) { + schema.ActionHandler = s.actionHandler + schema.Formatter = s.formatter +} + +func (s *Provider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + p := common.TransformToAuthProvider(authConfig) + switch s.name { + case PingName: + p[publicclient.PingProviderFieldRedirectURL] = formSamlRedirectURLFromMap(authConfig, s.name) + case ADFSName: + p[publicclient.ADFSProviderFieldRedirectURL] = formSamlRedirectURLFromMap(authConfig, s.name) + case KeyCloakName: + p[publicclient.KeyCloakProviderFieldRedirectURL] = formSamlRedirectURLFromMap(authConfig, s.name) + case OKTAName: + p[publicclient.OKTAProviderFieldRedirectURL] = formSamlRedirectURLFromMap(authConfig, s.name) + case ShibbolethName: + p[publicclient.ShibbolethProviderFieldRedirectURL] = formSamlRedirectURLFromMap(authConfig, s.name) + } + return p, nil +} + +func (s *Provider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + return v3.Principal{}, nil, "", fmt.Errorf("SAML providers do not implement Authenticate User API") +} + +func PerformSamlLogin(name string, apiContext *types.APIContext, input interface{}) error { + //input will contain the FINAL redirect URL + login, ok := input.(*v32.SamlLoginInput) + if !ok { + return errors.New("unexpected input type") + } + finalRedirectURL := login.FinalRedirectURL + + if provider, ok := SamlProviders[name]; ok { + if provider == nil { + logrus.Errorf("SAML: Provider %v not initialized", name) + return fmt.Errorf("SAML: Provider %v not initialized", name) + } + if provider.clientState == nil { + logrus.Errorf("SAML: Provider %v clientState not set", name) + return fmt.Errorf("SAML: Provider %v clientState not set", name) + } + logrus.Debugf("SAML [PerformSamlLogin]: Setting clientState for SAML service provider %v", name) + provider.clientState.SetState(apiContext.Response, apiContext.Request, "Rancher_FinalRedirectURL", finalRedirectURL) + provider.clientState.SetState(apiContext.Response, apiContext.Request, "Rancher_Action", loginAction) + provider.clientState.SetState(apiContext.Response, apiContext.Request, "Rancher_PublicKey", login.PublicKey) + provider.clientState.SetState(apiContext.Response, apiContext.Request, "Rancher_RequestID", login.RequestID) + provider.clientState.SetState(apiContext.Response, apiContext.Request, "Rancher_ResponseType", login.ResponseType) + + idpRedirectURL, err := provider.HandleSamlLogin(apiContext.Response, apiContext.Request) + if err != nil { + return err + } + logrus.Debugf("SAML [PerformSamlLogin]: Redirecting to the identity provider login page at %v", idpRedirectURL) + data := map[string]interface{}{ + "idpRedirectUrl": idpRedirectURL, + "type": "samlLoginOutput", + } + apiContext.WriteResponse(http.StatusOK, data) + + return nil + } + return nil +} + +func (s *Provider) getSamlConfig() (*v32.SamlConfig, error) { + authConfigObj, err := s.authConfigs.ObjectClient().UnstructuredClient().Get(s.name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("SAML: failed to retrieve SamlConfig, error: %v", err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("SAML: failed to retrieve SamlConfig, cannot read k8s Unstructured data") + } + storedSamlConfigMap := u.UnstructuredContent() + + storedSamlConfig := &v32.SamlConfig{} + err = common.Decode(storedSamlConfigMap, storedSamlConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode Saml Config: %w", err) + } + + if enabled, ok := storedSamlConfigMap["enabled"].(bool); ok { + storedSamlConfig.Enabled = enabled + } + + if storedSamlConfig.SpKey != "" { + value, err := common.ReadFromSecret(s.secrets, storedSamlConfig.SpKey, + strings.ToLower(client.PingConfigFieldSpKey)) + if err != nil { + return nil, err + } + storedSamlConfig.SpKey = value + } + + return storedSamlConfig, nil +} + +func (s *Provider) saveSamlConfig(config *v32.SamlConfig) error { + var configType string + + storedSamlConfig, err := s.getSamlConfig() + if err != nil { + return err + } + + switch s.name { + case PingName: + configType = client.PingConfigType + case ADFSName: + configType = client.ADFSConfigType + case KeyCloakName: + configType = client.KeyCloakConfigType + case OKTAName: + configType = client.OKTAConfigType + case ShibbolethName: + configType = client.ShibbolethConfigType + } + + config.APIVersion = "management.cattle.io/v3" + config.Kind = v3.AuthConfigGroupVersionKind.Kind + config.Type = configType + storedSamlConfig.Annotations = config.Annotations + config.ObjectMeta = storedSamlConfig.ObjectMeta + + var field string + // This assumes the provider needs to create only one secret. If there are new entries + // in the secret collection, this code that creates the actual secrets would need to be updated. + if fields, ok := secrets.TypeToFields[configType]; ok && len(fields) > 0 { + field = strings.ToLower(fields[0]) + } + spKey, err := common.CreateOrUpdateSecrets(s.secrets, config.SpKey, + field, strings.ToLower(config.Type)) + if err != nil { + return err + } + + config.SpKey = spKey + + if s.hasLdapGroupSearch() { + combinedConfig, err := s.combineSamlAndLdapConfig(config) + if err != nil { + logrus.Warnf("problem combining saml and ldap config, saving partial configuration %s", err.Error()) + } + _, err = s.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, combinedConfig) + if err != nil { + return fmt.Errorf("unable to update authconfig: %w", err) + } + return nil + } + + _, err = s.authConfigs.ObjectClient().Update(config.ObjectMeta.Name, config) + return err +} + +func (s *Provider) toPrincipal(principalType string, princ v3.Principal, token *v3.Token) v3.Principal { + if principalType == s.userType { + princ.PrincipalType = "user" + if token != nil { + princ.Me = s.isThisUserMe(token.UserPrincipal, princ) + if princ.Me { + princ.LoginName = token.UserPrincipal.LoginName + princ.DisplayName = token.UserPrincipal.DisplayName + } + } + } else { + princ.PrincipalType = "group" + if token != nil { + princ.MemberOf = s.tokenMGR.IsMemberOf(*token, princ) + } + } + + return princ +} + +func (s *Provider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + return nil, errors.New("Not implemented") +} + +func (s *Provider) SearchPrincipals(searchKey, principalType string, token v3.Token) ([]v3.Principal, error) { + if s.hasLdapGroupSearch() { + principals, err := s.ldapProvider.SearchPrincipals(searchKey, principalType, token) + // only give response from ldap if it's configured + if !ldap.IsNotConfigured(err) { + return principals, err + } + } + + var principals []v3.Principal + if principalType == "" { + principalType = "user" + } + + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: s.userType + "://" + searchKey}, + DisplayName: searchKey, + LoginName: searchKey, + PrincipalType: principalType, + Provider: s.name, + } + + principals = append(principals, p) + return principals, nil +} + +func (s *Provider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + externalID, principalType := splitPrincipalID(principalID) + if externalID == "" && principalType == "" { + return v3.Principal{}, fmt.Errorf("SAML: invalid id %v", principalID) + } + if principalType != s.userType && principalType != s.groupType { + return v3.Principal{}, fmt.Errorf("SAML: Invalid principal type") + } + + if s.hasLdapGroupSearch() { + p, err := s.ldapProvider.GetPrincipal(principalID, token) + // only give response from ldap if it's configured + if !ldap.IsNotConfigured(err) { + return p, err + } + } + + p := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: principalType + "://" + externalID}, + DisplayName: externalID, + LoginName: externalID, + Provider: s.name, + } + + p = s.toPrincipal(principalType, p, &token) + return p, nil +} + +func (s *Provider) isThisUserMe(me v3.Principal, other v3.Principal) bool { + if me.ObjectMeta.Name == other.ObjectMeta.Name && me.PrincipalType == other.PrincipalType { + return true + } + return false +} + +func (s *Provider) CanAccessWithGroupProviders(userPrincipalID string, groupPrincipals []v3.Principal) (bool, error) { + config, err := s.getSamlConfig() + if err != nil { + logrus.Errorf("Error fetching saml config: %v", err) + return false, err + } + allowed, err := s.userMGR.CheckAccess(config.AccessMode, config.AllowedPrincipalIDs, userPrincipalID, groupPrincipals) + if err != nil { + return false, err + } + return allowed, nil +} + +func formSamlRedirectURLFromMap(config map[string]interface{}, name string) string { + var hostname string + switch name { + case PingName: + hostname, _ = config[client.PingConfigFieldRancherAPIHost].(string) + case ADFSName: + hostname, _ = config[client.ADFSConfigFieldRancherAPIHost].(string) + case KeyCloakName: + hostname, _ = config[client.KeyCloakConfigFieldRancherAPIHost].(string) + case OKTAName: + hostname, _ = config[client.OKTAConfigFieldRancherAPIHost].(string) + case ShibbolethName: + hostname, _ = config[client.ShibbolethConfigFieldRancherAPIHost].(string) + } + + path := hostname + "/v1-saml/" + name + "/login" + return path +} + +func splitPrincipalID(principalID string) (string, string) { + parts := strings.SplitN(principalID, ":", 2) + if len(parts) != 2 { + return "", "" + } + externalID := strings.TrimPrefix(parts[1], "//") + return externalID, parts[0] +} + +func (s *Provider) combineSamlAndLdapConfig(config *v32.SamlConfig) (runtime.Object, error) { + // if errors we might not want to turn on ldap + ldapConfig, _, err := ldap.GetLDAPConfig(s.ldapProvider) + + // can be misconfigured but still want it saved + if err != nil { + logrus.Warnf("error pulling %s ldap configs: %s\n", s.name, err) + + // if the the config subkey not in the crd + if ldapConfig == nil { + return config, nil + } + + // only return the saml config on other errors + // if not configured it might have data in it we want to keep + if !ldap.IsNotConfigured(err) { + return config, nil + } + } + + var fullConfig runtime.Object + samlConfig := v32.SamlConfig{} + config.DeepCopyInto(&samlConfig) + switch s.name { + case ShibbolethName: + secretName, err := common.SavePasswordSecret( + s.secrets, + ldapConfig.LdapFields.ServiceAccountPassword, + client.LdapConfigFieldServiceAccountPassword, + samlConfig.Type, + ) + if err != nil { + return config, fmt.Errorf("unable to save ldap service account password: %w", err) + } + + ldapConfig.LdapFields.ServiceAccountPassword = secretName + // Set the status for SecretsMigrated to True so it doesn't get re-migrated + v32.AuthConfigConditionSecretsMigrated.SetStatus(&samlConfig, "True") + fullConfig = &v32.ShibbolethConfig{ + SamlConfig: samlConfig, + OpenLdapConfig: ldapConfig.LdapFields, + } + case OKTAName: + fullConfig = &v32.OKTAConfig{ + SamlConfig: samlConfig, + OpenLdapConfig: ldapConfig.LdapFields, + } + } + + return fullConfig, nil +} + +func (s *Provider) hasLdapGroupSearch() bool { + return ShibbolethName == s.name || OKTAName == s.name +} + +func (s *Provider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + extras := make(map[string][]string) + if userPrincipal.Name != "" { + extras[common.UserAttributePrincipalID] = []string{userPrincipal.Name} + } + if userPrincipal.LoginName != "" { + extras[common.UserAttributeUserName] = []string{userPrincipal.LoginName} + } + return extras +} + +// IsDisabledProvider checks if the SAML auth provider is currently disabled in Rancher. +func (s *Provider) IsDisabledProvider() (bool, error) { + samlConfig, err := s.getSamlConfig() + if err != nil { + return false, err + } + return !samlConfig.Enabled, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider_test.go new file mode 100644 index 0000000..3fbb440 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/saml/saml_provider_test.go @@ -0,0 +1,132 @@ +package saml + +import ( + "context" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/providers/ldap" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + "testing" +) + +func createSamlProviderWithMockedLdap(name string, hasLdap bool) *Provider { + provider := &Provider{name: name} + provider.ldapProvider = &mockLdapProvider{isLdapConfigured: hasLdap, providerName: provider.name} + return provider +} + +func TestConfiguredOktaProviderContainsLdapProvider(t *testing.T) { + // saml.Configure runs some ldap specific logic based on the saml provider name, so we provide + // just enough scaffolding to run the Configure function. + ctx := context.Background() + mgmtCtx, err := config.NewScaledContext(rest.Config{}, nil) + require.NoError(t, err, "Failed to create NewScaledContext") + tokenMGR := tokens.NewManager(ctx, mgmtCtx) + provider, ok := Configure(ctx, mgmtCtx, mgmtCtx.UserManager, tokenMGR, "okta").(*Provider) + require.True(t, ok, "Failed to Configure a valid Provider") + + assert.True(t, provider.hasLdapGroupSearch(), "Missing LDAP group search capability for okta provider") + assert.NotNil(t, provider.ldapProvider, "Configured okta provider did not receive child LDAP provider") +} + +func TestSearchPrincipals(t *testing.T) { + var userSearchKey = "al" + // Note: The mocked ldap provider alawys returns a single user named "alice" + testcases := []struct { + name string + providerName string + expectedLoginName string + isLdapConfigured bool + }{ + { + name: "okta with ldap provides ldap user", + providerName: "okta", + expectedLoginName: "alice", + isLdapConfigured: true, + }, + { + name: "okta without ldap uses fallback behavior", + providerName: "okta", + expectedLoginName: "al", + isLdapConfigured: false, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + provider := createSamlProviderWithMockedLdap(tt.providerName, tt.isLdapConfigured) + results, err := provider.SearchPrincipals(userSearchKey, "user", v3.Token{}) + require.NoError(t, err, "Failed to search principals") + require.NotEmpty(t, results, "Got empty principal list") + assert.Equal(t, tt.expectedLoginName, results[0].LoginName) + }) + } +} + +// Bare minimum to provide ldap responses (or error conditions) when performing SearchPrincipals. We're testing +// the SAML provider's logic, not anything the ldap provider is doing, so we merely need enough scaffolding to +// detect that the ldapProvider was used at all. +type mockLdapProvider struct { + providerName string + isLdapConfigured bool +} + +func (p *mockLdapProvider) GetName() string { + return p.providerName +} + +func (p *mockLdapProvider) AuthenticateUser(ctx context.Context, input interface{}) (v3.Principal, []v3.Principal, string, error) { + panic("AuthenticateUser Unimplemented!") +} + +func (p *mockLdapProvider) SearchPrincipals(name, principalType string, myToken v3.Token) ([]v3.Principal, error) { + var principals []v3.Principal + if p.isLdapConfigured { + // The mock provider is pretty sure you meant the user "alice" + alice := v3.Principal{ + ObjectMeta: metav1.ObjectMeta{Name: "inetOrgPerson" + "://" + "alice"}, + DisplayName: "Alice", + LoginName: "alice", + PrincipalType: "user", + Me: true, + Provider: p.providerName, + } + principals = append(principals, alice) + return principals, nil + } else { + return principals, ldap.ErrorNotConfigured{} + } +} + +func (p *mockLdapProvider) CustomizeSchema(schema *types.Schema) { + panic("CustomizeSchema Unimplemented!") +} + +func (p *mockLdapProvider) GetPrincipal(principalID string, token v3.Token) (v3.Principal, error) { + panic("GetPrincipal Unimplemented!") +} + +func (p *mockLdapProvider) TransformToAuthProvider(authConfig map[string]interface{}) (map[string]interface{}, error) { + panic("TransformToAuthProvider Unimplemented!") +} + +func (p *mockLdapProvider) RefetchGroupPrincipals(principalID string, secret string) ([]v3.Principal, error) { + panic("RefetchGroupPrincipals Unimplemented!") +} + +func (p *mockLdapProvider) CanAccessWithGroupProviders(userPrincipalID string, groups []v3.Principal) (bool, error) { + panic("CanAccessWithGroupProviders Unimplemented!") +} + +func (p *mockLdapProvider) GetUserExtraAttributes(userPrincipal v3.Principal) map[string][]string { + panic("GetUserExtraAttributes Unimplemented!") +} + +func (p *mockLdapProvider) IsDisabledProvider() (bool, error) { + panic("IsDisabledProvider Unimplemented!") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/setup.go new file mode 100644 index 0000000..d8785a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/providers/setup.go @@ -0,0 +1,43 @@ +package providers + +import ( + "context" + + "github.com/rancher/norman/store/subtype" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/api/secrets" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/namespace" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +var authConfigTypes = []string{ + client.GithubConfigType, + client.LocalConfigType, + client.ActiveDirectoryConfigType, + client.AzureADConfigType, + client.OpenLdapConfigType, + client.FreeIpaConfigType, + client.PingConfigType, + client.ADFSConfigType, + client.KeyCloakConfigType, + client.OKTAConfigType, + client.ShibbolethConfigType, + client.GoogleOauthConfigType, + client.OIDCConfigType, + client.KeyCloakOIDCConfigType, + client.GenericOIDCConfigType, +} + +func SetupAuthConfig(ctx context.Context, management *config.ScaledContext, schemas *types.Schemas) { + Configure(ctx, management) + + authConfigBaseSchema := schemas.Schema(&managementschema.Version, client.AuthConfigType) + authConfigBaseSchema.Store = secrets.Wrap(authConfigBaseSchema.Store, management.Core.Secrets(namespace.GlobalNamespace)) + for _, authConfigSubtype := range authConfigTypes { + subSchema := schemas.Schema(&managementschema.Version, authConfigSubtype) + GetProviderByType(authConfigSubtype).CustomizeSchema(subSchema) + subSchema.Store = subtype.NewSubTypeStore(authConfigSubtype, authConfigBaseSchema.Store) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/authenticate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/authenticate.go new file mode 100644 index 0000000..c404032 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/authenticate.go @@ -0,0 +1,240 @@ +package requests + +import ( + "context" + "net/http" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/steve/pkg/auth" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/client-go/tools/cache" +) + +var ( + ErrMustAuthenticate = httperror.NewAPIError(httperror.Unauthorized, "must authenticate") +) + +type Authenticator interface { + Authenticate(req *http.Request) (*AuthenticatorResponse, error) + TokenFromRequest(req *http.Request) (*v3.Token, error) +} + +type AuthenticatorResponse struct { + IsAuthed bool + User string + UserPrincipal string + Groups []string + Extras map[string][]string +} + +func ToAuthMiddleware(a Authenticator) auth.Middleware { + f := func(req *http.Request) (user.Info, bool, error) { + authResp, err := a.Authenticate(req) + if err != nil { + return nil, false, err + } + return &user.DefaultInfo{ + Name: authResp.User, + UID: authResp.User, + Groups: authResp.Groups, + Extra: authResp.Extras, + }, authResp.IsAuthed, err + } + return auth.ToMiddleware(auth.AuthenticatorFunc(f)) +} + +type ClusterRouter func(req *http.Request) string + +func NewAuthenticator(ctx context.Context, clusterRouter ClusterRouter, mgmtCtx *config.ScaledContext) Authenticator { + tokenInformer := mgmtCtx.Management.Tokens("").Controller().Informer() + tokenInformer.AddIndexers(map[string]cache.IndexFunc{tokenKeyIndex: tokenKeyIndexer}) + + return &tokenAuthenticator{ + ctx: ctx, + tokenIndexer: tokenInformer.GetIndexer(), + tokenClient: mgmtCtx.Management.Tokens(""), + userAttributeLister: mgmtCtx.Management.UserAttributes("").Controller().Lister(), + userAttributes: mgmtCtx.Management.UserAttributes(""), + userLister: mgmtCtx.Management.Users("").Controller().Lister(), + clusterRouter: clusterRouter, + userAuthRefresher: providerrefresh.NewUserAuthRefresher(ctx, mgmtCtx), + } +} + +type tokenAuthenticator struct { + ctx context.Context + tokenIndexer cache.Indexer + tokenClient v3.TokenInterface + userAttributes v3.UserAttributeInterface + userAttributeLister v3.UserAttributeLister + userLister v3.UserLister + clusterRouter ClusterRouter + userAuthRefresher providerrefresh.UserAuthRefresher +} + +const ( + tokenKeyIndex = "authn.management.cattle.io/token-key-index" +) + +func tokenKeyIndexer(obj interface{}) ([]string, error) { + token, ok := obj.(*v3.Token) + if !ok { + return []string{}, nil + } + + return []string{token.Token}, nil +} + +func (a *tokenAuthenticator) Authenticate(req *http.Request) (*AuthenticatorResponse, error) { + authResp := &AuthenticatorResponse{ + Extras: make(map[string][]string), + } + token, err := a.TokenFromRequest(req) + if err != nil { + return nil, err + } + + if token.Enabled != nil && !*token.Enabled { + return nil, errors.Wrapf(ErrMustAuthenticate, "user's token is not enabled") + } + if token.ClusterName != "" && token.ClusterName != a.clusterRouter(req) { + return nil, errors.Wrapf(ErrMustAuthenticate, "clusterID does not match") + } + + attribs, err := a.userAttributeLister.Get("", token.UserID) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + + u, err := a.userLister.Get("", token.UserID) + if err != nil { + return nil, err + } + + if u.Enabled != nil && !*u.Enabled { + return nil, errors.Wrap(ErrMustAuthenticate, "user is not enabled") + } + + var groups []string + hitProvider := false + if attribs != nil { + for provider, gps := range attribs.GroupPrincipals { + if provider == token.AuthProvider { + hitProvider = true + } + for _, principal := range gps.Items { + name := strings.TrimPrefix(principal.Name, "local://") + groups = append(groups, name) + } + } + } + + // fallback to legacy token.GroupPrincipals + if !hitProvider { + for _, principal := range token.GroupPrincipals { + // TODO This is a short cut for now. Will actually need to lookup groups in future + name := strings.TrimPrefix(principal.Name, "local://") + groups = append(groups, name) + } + } + groups = append(groups, user.AllAuthenticated, "system:cattle:authenticated") + if !strings.HasPrefix(token.UserID, "system:") { + go a.userAuthRefresher.TriggerUserRefresh(token.UserID, false) + } + + authResp.IsAuthed = true + authResp.User = token.UserID + authResp.UserPrincipal = token.UserPrincipal.Name + authResp.Groups = groups + authResp.Extras = getUserExtraInfo(token, u, attribs) + logrus.Debugf("Extras returned %v", authResp.Extras) + + return authResp, nil +} + +func getUserExtraInfo(token *v3.Token, u *v3.User, attribs *v3.UserAttribute) map[string][]string { + extraInfo := make(map[string][]string) + + if attribs != nil && attribs.ExtraByProvider != nil && len(attribs.ExtraByProvider) != 0 { + if token.AuthProvider == "local" || token.AuthProvider == "" { + //gather all extraInfo for all external auth providers present in the userAttributes + for _, extra := range attribs.ExtraByProvider { + for key, value := range extra { + extraInfo[key] = append(extraInfo[key], value...) + } + } + return extraInfo + } + //authProvider is set in token + if extraInfo, ok := attribs.ExtraByProvider[token.AuthProvider]; ok { + return extraInfo + } + } + + extraInfo = providers.GetUserExtraAttributes(token.AuthProvider, token.UserPrincipal) + //if principalid is not set in extra, read from user + if extraInfo != nil { + if len(extraInfo[common.UserAttributePrincipalID]) == 0 { + extraInfo[common.UserAttributePrincipalID] = u.PrincipalIDs + } + if len(extraInfo[common.UserAttributeUserName]) == 0 { + extraInfo[common.UserAttributeUserName] = []string{u.DisplayName} + } + } + + return extraInfo +} + +func (a *tokenAuthenticator) TokenFromRequest(req *http.Request) (*v3.Token, error) { + tokenAuthValue := tokens.GetTokenAuthFromRequest(req) + if tokenAuthValue == "" { + return nil, ErrMustAuthenticate + } + + tokenName, tokenKey := tokens.SplitTokenParts(tokenAuthValue) + if tokenName == "" || tokenKey == "" { + return nil, ErrMustAuthenticate + } + + lookupUsingClient := false + objs, err := a.tokenIndexer.ByIndex(tokenKeyIndex, tokenKey) + if err != nil { + if apierrors.IsNotFound(err) { + lookupUsingClient = true + } else { + return nil, errors.Wrapf(ErrMustAuthenticate, "failed to retrieve auth token from cache, error: %v", err) + } + } else if len(objs) == 0 { + lookupUsingClient = true + } + + var storedToken *v3.Token + if lookupUsingClient { + storedToken, err = a.tokenClient.Get(tokenName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, ErrMustAuthenticate + } + return nil, errors.Wrapf(ErrMustAuthenticate, "failed to retrieve auth token, error: %#v", err) + } + } else { + storedToken = objs[0].(*v3.Token) + } + + if _, err := tokens.VerifyToken(storedToken, tokenName, tokenKey); err != nil { + return nil, errors.Wrapf(ErrMustAuthenticate, "failed to verify token: %v", err) + } + + return storedToken, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/chained.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/chained.go new file mode 100644 index 0000000..79f94e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/chained.go @@ -0,0 +1,41 @@ +package requests + +import ( + "net/http" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +func Chain(auths ...Authenticator) Authenticator { + return &chainedAuth{ + auths: auths, + } +} + +type chainedAuth struct { + auths []Authenticator +} + +func (c *chainedAuth) Authenticate(req *http.Request) (*AuthenticatorResponse, error) { + for _, auth := range c.auths { + authResponse, err := auth.Authenticate(req) + if err != nil || authResponse.IsAuthed { + return authResponse, err + } + } + return &AuthenticatorResponse{ + Extras: make(map[string][]string), + }, nil +} + +func (c *chainedAuth) TokenFromRequest(req *http.Request) (*v3.Token, error) { + var lastErr error + for _, auth := range c.auths { + t, err := auth.TokenFromRequest(req) + if err == nil { + return t, nil + } + lastErr = err + } + return nil, lastErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/filter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/filter.go new file mode 100644 index 0000000..b6885b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/filter.go @@ -0,0 +1,111 @@ +package requests + +import ( + "net/http" + "strings" + + "github.com/rancher/rancher/pkg/auth/audit" + authcontext "github.com/rancher/rancher/pkg/auth/context" + "github.com/rancher/rancher/pkg/auth/providers" + "github.com/rancher/rancher/pkg/auth/util" + "github.com/sirupsen/logrus" + "k8s.io/apiserver/pkg/endpoints/request" +) + +func NewAuthenticatedFilter(next http.Handler) http.Handler { + return &authHeaderHandler{ + next: next, + } +} + +type authHeaderHandler struct { + next http.Handler +} + +func (h authHeaderHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + userInfo, authed := request.UserFrom(req.Context()) + // checking for system:cattle:error user keeps the old behavior of always returning 401 when authentication fails + if !authed || userInfo.GetName() == "system:cattle:error" { + util.ReturnHTTPError(rw, req, 401, ErrMustAuthenticate.Error()) + return + } + + // clean extra that is not part of userInfo + for header := range req.Header { + if strings.HasPrefix(header, "Impersonate-Extra-") { + key := strings.TrimPrefix(header, "Impersonate-Extra-") + if !providers.IsValidUserExtraAttribute(key) { + req.Header.Del(header) + } + } + } + + if !authcontext.IsSAAuthenticated(req.Context()) { + // If the request is not authenticated as a service account, + // we need to set impersonation headers. + req.Header.Set("Impersonate-User", userInfo.GetName()) + req.Header.Del("Impersonate-Group") + for _, group := range userInfo.GetGroups() { + req.Header.Add("Impersonate-Group", group) + } + + for key, extras := range userInfo.GetExtra() { + for _, s := range extras { + if s != "" { + req.Header.Add("Impersonate-Extra-"+key, s) + } + } + } + } + + logrus.Tracef("Rancher Auth Filter ##headers %v: ", req.Header) + + auditUser, ok := audit.FromContext(req.Context()) + if ok { + auditUser.Name = userInfo.GetName() + auditUser.Group = userInfo.GetGroups() + } + + h.next.ServeHTTP(rw, req) +} + +func NewRequireAuthenticatedFilter(pathPrefix string, ignorePrefix ...string) func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return &authedFilter{ + next: next, + pathPrefix: pathPrefix, + ignorePrefix: ignorePrefix, + } + } +} + +type authedFilter struct { + next http.Handler + pathPrefix string + ignorePrefix []string +} + +func (h authedFilter) matches(path string) bool { + if strings.HasPrefix(path, h.pathPrefix) { + for _, prefix := range h.ignorePrefix { + if strings.HasPrefix(path, prefix) { + return false + } + } + return true + } + return false +} + +func (h authedFilter) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if h.matches(req.URL.Path) { + userInfo, authed := request.UserFrom(req.Context()) + // checking for system:cattle:error user keeps the old behavior of always returning 401 when authentication fails + if !authed || userInfo.GetName() == "system:cattle:error" { + util.ReturnHTTPError(rw, req, 401, ErrMustAuthenticate.Error()) + return + } + } + + h.next.ServeHTTP(rw, req) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/impersonate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/impersonate.go new file mode 100644 index 0000000..0c34768 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/impersonate.go @@ -0,0 +1,100 @@ +package requests + +import ( + "errors" + "net/http" + + "github.com/rancher/rancher/pkg/auth/audit" + "github.com/rancher/rancher/pkg/auth/requests/sar" + "github.com/rancher/steve/pkg/auth" + "k8s.io/apimachinery/pkg/util/sets" + k8sUser "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type impersonatingAuth struct { + sar sar.SubjectAccessReview +} + +func NewImpersonatingAuth(sar sar.SubjectAccessReview) auth.Authenticator { + return &impersonatingAuth{ + sar: sar, + } +} + +func (h *impersonatingAuth) Authenticate(req *http.Request) (k8sUser.Info, bool, error) { + userInfo, authed := request.UserFrom(req.Context()) + if !authed { + return nil, false, nil + } + user := userInfo.GetName() + groups := userInfo.GetGroups() + + var impersonateUser bool + var impersonateGroup bool + + reqUser := req.Header.Get("Impersonate-User") + var reqGroup []string + if g, ok := req.Header["Impersonate-Group"]; ok { + reqGroup = g + } + + auditUser, ok := audit.FromContext(req.Context()) + if ok { + auditUser.RequestUser = reqUser + auditUser.RequestGroups = reqGroup + } + + // If there is an impersonate header, the incoming request is attempting to + // impersonate a different user, verify the token user is authz to impersonate + if h.sar != nil { + if reqUser != "" && reqUser != user { + canDo, err := h.sar.UserCanImpersonateUser(req, user, reqUser) + if err != nil { + return nil, false, err + } else if !canDo { + return nil, false, errors.New("not allowed to impersonate") + } + impersonateUser = true + } + + if len(reqGroup) > 0 && !groupsEqual(reqGroup, groups) { + canDo, err := h.sar.UserCanImpersonateGroups(req, user, reqGroup) + if err != nil { + return nil, false, err + } else if !canDo { + return nil, false, errors.New("not allowed to impersonate") + } + impersonateGroup = true + } + } + + if impersonateUser || impersonateGroup { + if impersonateUser { + user = reqUser + } + if impersonateGroup { + groups = reqGroup + } else { + groups = nil + } + groups = append(groups, k8sUser.AllAuthenticated) + } + + extra := userInfo.GetExtra() + + return &k8sUser.DefaultInfo{ + Name: user, + UID: user, + Groups: groups, + Extra: extra, + }, true, nil +} + +func groupsEqual(group1, group2 []string) bool { + if len(group1) != len(group2) { + return false + } + + return sets.NewString(group1...).Equal(sets.NewString(group2...)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/sar/sar.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/sar/sar.go new file mode 100644 index 0000000..5b30100 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/sar/sar.go @@ -0,0 +1,95 @@ +package sar + +import ( + "context" + "net/http" + + "github.com/sirupsen/logrus" + authV1 "k8s.io/api/authorization/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/client-go/kubernetes/typed/authorization/v1" +) + +// SubjectAccessReview checks if a user can impersonate as another user or group +type SubjectAccessReview interface { + // UserCanImpersonateUser checks if user can impersonate as impUser + UserCanImpersonateUser(req *http.Request, user, impUser string) (bool, error) + // UserCanImpersonateGroups checks if user can impersonate as the groups + UserCanImpersonateGroups(req *http.Request, user string, groups []string) (bool, error) +} + +type subjectAccessReview struct { + sarClientGetter SubjectAccessReviewClientGetter +} + +type SubjectAccessReviewClientGetter interface { + SubjectAccessReviewForCluster(request *http.Request) (v1.SubjectAccessReviewInterface, error) +} + +func NewSubjectAccessReview(getter SubjectAccessReviewClientGetter) SubjectAccessReview { + return subjectAccessReview{ + sarClientGetter: getter, + } +} + +func (sar subjectAccessReview) UserCanImpersonateUser(req *http.Request, user, impUser string) (bool, error) { + userContext, err := sar.sarClientGetter.SubjectAccessReviewForCluster(req) + if err != nil { + return false, err + } + return sar.checkUserCanImpersonateUser(userContext, user, impUser) +} + +func (sar subjectAccessReview) UserCanImpersonateGroups(req *http.Request, user string, groups []string) (bool, error) { + userContext, err := sar.sarClientGetter.SubjectAccessReviewForCluster(req) + if err != nil { + return false, err + } + return sar.checkUserCanImpersonateGroup(userContext, user, groups) +} + +func (sar subjectAccessReview) checkUserCanImpersonateUser(sarClient v1.SubjectAccessReviewInterface, user, impUser string) (bool, error) { + review := authV1.SubjectAccessReview{ + Spec: authV1.SubjectAccessReviewSpec{ + User: user, + ResourceAttributes: &authV1.ResourceAttributes{ + Verb: "impersonate", + Resource: "users", + Name: impUser, + }, + }, + } + + result, err := sarClient.Create(context.TODO(), &review, metav1.CreateOptions{}) + if err != nil { + return false, err + } + logrus.Debugf("Impersonate check result: %v", result) + return result.Status.Allowed, nil +} + +func (sar subjectAccessReview) checkUserCanImpersonateGroup(sarClient v1.SubjectAccessReviewInterface, user string, groups []string) (bool, error) { + for _, group := range groups { + review := authV1.SubjectAccessReview{ + Spec: authV1.SubjectAccessReviewSpec{ + User: user, + ResourceAttributes: &authV1.ResourceAttributes{ + Verb: "impersonate", + Resource: "groups", + Name: group, + }, + }, + } + + result, err := sarClient.Create(context.TODO(), &review, metav1.CreateOptions{}) + if err != nil { + return false, err + } + logrus.Debugf("Impersonate check result: %v", result) + if !result.Status.Allowed { + return false, nil + } + } + + return true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account.go new file mode 100644 index 0000000..40b07d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account.go @@ -0,0 +1,160 @@ +package requests + +import ( + "fmt" + "net/http" + "strings" + + jwtv4 "github.com/golang-jwt/jwt/v4" + "github.com/gorilla/mux" + authcontext "github.com/rancher/rancher/pkg/auth/context" + "github.com/rancher/rancher/pkg/auth/tokens" + controllers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/steve/pkg/auth" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +type ( + restConfigGetter func(cluster *mgmtv3.Cluster, context *config.ScaledContext, secretLister corev1.SecretLister, tryReconnecting bool) (*rest.Config, error) + authClientCreator func(clusterID string) (kubernetes.Interface, error) +) + +// ServiceAccountAuth is an authenticator that authenticates requests using the downstream service account's JWT. +type ServiceAccountAuth struct { + scaledContext *config.ScaledContext + clusterLister mgmtv3.ClusterLister + secretLister corev1.SecretLister + restConfigGetter restConfigGetter + authClientCreator authClientCreator + clusterProxyConfigsGetter controllers.ClusterProxyConfigCache +} + +// NewServiceAccountAuth creates a new instance of ServiceAccountAuth. +func NewServiceAccountAuth( + scaledContext *config.ScaledContext, + restConfigGetter restConfigGetter, +) auth.Authenticator { + return &ServiceAccountAuth{ + scaledContext: scaledContext, + clusterLister: scaledContext.Management.Clusters("").Controller().Lister(), + secretLister: scaledContext.Core.Secrets("").Controller().Lister(), + restConfigGetter: restConfigGetter, + authClientCreator: func(clusterID string) (kubernetes.Interface, error) { + return scaledContext.Wrangler.MultiClusterManager.K8sClient(clusterID) + }, + clusterProxyConfigsGetter: scaledContext.Wrangler.Mgmt.ClusterProxyConfig().Cache(), + } +} + +// Authenticate the request using the downstream service account's JWT. +func (t *ServiceAccountAuth) Authenticate(req *http.Request) (user.Info, bool, error) { + // Basic checks to see if we even need to proceed + info, hasAuth := request.UserFrom(req.Context()) + if info.GetName() != "system:cattle:error" { + return info, hasAuth, nil + } + clusterID := mux.Vars(req)["clusterID"] + if clusterID == "" { + return info, hasAuth, fmt.Errorf("no clusterID found in request") + } + // Check the cluster setting value to determine whether we will continue the auth process + settings, err := t.clusterProxyConfigsGetter.List(clusterID, labels.NewSelector()) + if err != nil { + logrus.Debugf("rejecting downstream proxy request for %s, unable to fetch ClusterProxySettings object for cluster. %v", req.URL.Path, err) + return info, false, nil + } + if settings == nil { + logrus.Debugf("rejecting downstream proxy request for %s, no ClusterProxySettings object exists for cluster", req.URL.Path) + return info, false, nil + } + if len(settings) > 1 { + logrus.Errorf("multiple clusterproxyconfigs found for cluster, which is a misconfiguration, feature is disabled") + return info, false, nil + } + + if !settings[0].Enabled { + logrus.Debugf("rejecting downstream proxy request for %s, current setting is enabled: %v", req.URL.Path, settings[0].Enabled) + return info, false, nil + } + + // See if the token is a JWT. + rawToken := tokens.GetTokenAuthFromRequest(req) + + jwtParser := jwtv4.NewParser(jwtv4.WithoutClaimsValidation()) + claims := jwtv4.RegisteredClaims{} + // Using ParseUnverified is deliberate here to look at the basic info in the token. + // Later on, we do a real TokenReview against the downstream cluster to actually verify the JWT. + _, _, err = jwtParser.ParseUnverified(rawToken, &claims) + if err != nil { + logrus.Debug("saauth: error parsing JWT") + return info, false, err + } + + if !strings.HasPrefix(claims.Subject, serviceaccount.ServiceAccountUsernamePrefix) { + logrus.Debugf("saauth: JWT sub is not a service account: %v", err) + return info, false, nil + } + + if isTokenExpired(claims) { + logrus.Debugf("saauth: Service Account JWT is expired. Expiration time was: %v", claims.ExpiresAt) + return info, false, nil + } + + // Get a client for the downstream cluster. + downstreamAuthClient, err := t.authClientCreator(clusterID) + if err != nil { + logrus.Errorf("saauth: failed to fetch downstream kubeconfig: %v", err) + return info, false, nil + } + + tokenReview := &v1.TokenReview{ + Spec: v1.TokenReviewSpec{ + Token: rawToken, + }, + } + + // Make the token review request to the downstream cluster. + tokenReview, err = downstreamAuthClient.AuthenticationV1().TokenReviews().Create(req.Context(), tokenReview, metav1.CreateOptions{}) + if err != nil { + logrus.Debugf("saauth: error creating a tokenreview request: %v", err) + return info, false, nil + } + + // Let others know that this request is authenticated using a service account. + *req = *req.WithContext(authcontext.SetSAAuthenticated(req.Context())) + + extraMap := convertExtra(tokenReview.Status.User.Extra) + + return &user.DefaultInfo{ + Name: tokenReview.Status.User.Username, + UID: tokenReview.Status.User.UID, + Groups: tokenReview.Status.User.Groups, + Extra: extraMap, + }, tokenReview.Status.Authenticated, nil +} + +// isTokenExpired takes RegisteredClaims JWT and returns true if it is expired, otherwise it returns false. +func isTokenExpired(claims jwtv4.RegisteredClaims) bool { + // Token without an expiration time is not expired. + return !claims.VerifyExpiresAt(jwtv4.TimeFunc(), false) +} + +// convertExtra converts the Extra value from a tokenResponse to map[string][]string +func convertExtra(extra map[string]v1.ExtraValue) map[string][]string { + result := make(map[string][]string) + for key, values := range extra { + result[key] = values + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account_test.go new file mode 100644 index 0000000..9cff97c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/service_account_test.go @@ -0,0 +1,353 @@ +package requests + +import ( + "net/http" + "reflect" + "testing" + "time" + + jwtv4 "github.com/golang-jwt/jwt/v4" + "github.com/golang/mock/gomock" + "github.com/gorilla/mux" + v3api "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/rancher/rancher/pkg/types/config" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/authentication/user" + k8sRequest "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/rest" + k8stesting "k8s.io/client-go/testing" +) + +const ( + proxyPrefix = "/k8s/clusters/" + tokenReviewSuffix = "/apis/authentication.k8s.io/v1/tokenreviews" +) + +func TestIsTokenExpired(t *testing.T) { + tests := []struct { + name string + expirationTime *jwtv4.NumericDate + wantExpired bool + }{ + { + name: "empty expiration", + wantExpired: false, + }, + { + name: "expired token", + expirationTime: jwtv4.NewNumericDate(time.Now().Add(-time.Hour)), + wantExpired: true, + }, + { + name: "not expired token", + expirationTime: jwtv4.NewNumericDate(time.Now().Add(time.Hour)), + wantExpired: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testClaim := jwtv4.RegisteredClaims{ + ExpiresAt: tt.expirationTime, + } + if got := isTokenExpired(testClaim); got != tt.wantExpired { + t.Errorf("isTokenExpired() = %v, wantExpired %v", got, tt.wantExpired) + } + }) + } +} + +func TestAuthenticate(t *testing.T) { + t.Parallel() + tests := []struct { + name string + startUser string + expectedUser string + settingEnabled bool + token string + tokenReviewAuthStatus bool + downstreamRequest *http.Request + clusterID string + isAuthenticated bool + expectedError bool + omitProxyConfig bool + }{ + { + name: "everything valid auth succeeds secure mode", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "expected-username", + settingEnabled: true, + tokenReviewAuthStatus: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testclusterid", + isAuthenticated: true, + expectedError: false, + }, + { + name: "everything valid auth succeeds insecure mode", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "expected-username", + settingEnabled: true, + tokenReviewAuthStatus: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testclusterid", + isAuthenticated: true, + expectedError: false, + }, + { + name: "everything valid but tokenreview auth fails", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "", + settingEnabled: true, + tokenReviewAuthStatus: false, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testclusterid", + isAuthenticated: false, + expectedError: false, + }, + { + name: "expired token auth fails", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(-time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + settingEnabled: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testclusterid", + isAuthenticated: false, + expectedError: false, + }, + { + name: "invalid token auth fail", + token: "totallybogusjwttoken", + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + settingEnabled: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testclusterid", + isAuthenticated: false, + expectedError: true, + }, + { + name: "invalid subject in jwt will fail", + token: makeJWT(jwtv4.MapClaims{ + "sub": "not-a-sa:totalfail", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + settingEnabled: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testcluster", + isAuthenticated: false, + expectedError: false, + }, + { + name: "missing clusterid auth fail", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + settingEnabled: true, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "", + isAuthenticated: true, + expectedError: true, + }, + { + name: "everything valid but setting is off auth fails", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + settingEnabled: false, + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testcluster", + isAuthenticated: false, + expectedError: false, + }, + { + name: "everything valid but setting is missing auth fails", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "system:cattle:error", + downstreamRequest: generateDownstreamRequest("POST", "testclusterid"+tokenReviewSuffix), + clusterID: "testcluster", + isAuthenticated: false, + expectedError: false, + omitProxyConfig: true, + }, + { + name: "everything valid auth succeeds for non tokenreview feature enabled", + token: makeJWT(jwtv4.MapClaims{ + "sub": "system:serviceaccount:vault:token-reviewer", + "exp": time.Now().Add(time.Hour).Unix(), + }), + startUser: "system:cattle:error", + expectedUser: "expected-username", + settingEnabled: true, + tokenReviewAuthStatus: true, + downstreamRequest: generateDownstreamRequest("GET", "testclusterid/apis/testgroup.k8s.io/v1/testendpoint"), + clusterID: "testclusterid", + isAuthenticated: true, + expectedError: false, + }, + } + + for _, test := range tests { + test := test + ctrl := gomock.NewController(t) + cpsCache := wranglerfake.NewMockCacheInterface[*v3api.ClusterProxyConfig](ctrl) + cpsCache.EXPECT().List(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace string, _ labels.Selector) ([]*v3api.ClusterProxyConfig, error) { + if test.omitProxyConfig { + return nil, nil + } + return []*v3api.ClusterProxyConfig{ + { + Enabled: test.settingEnabled, + }, + }, nil + }).AnyTimes() + t.Run(test.name, func(t *testing.T) { + mgmtCtx, err := config.NewScaledContext(rest.Config{}, nil) + auth := &ServiceAccountAuth{ + scaledContext: mgmtCtx, + clusterLister: &fakes.ClusterListerMock{ + GetFunc: func(namespace string, name string) (*v3.Cluster, error) { + return &v3.Cluster{}, nil + }, + }, + secretLister: nil, + restConfigGetter: func(cluster *v3.Cluster, context *config.ScaledContext, secretLister corev1.SecretLister, tryReconnecting bool) (*rest.Config, error) { + return &rest.Config{}, nil + }, + authClientCreator: func(clusterID string) (kubernetes.Interface, error) { + authclient := fake.NewSimpleClientset() + // Use PrependReactor because there is a default Reactor for */* that will trump ours if we just use AddReactor + authclient.Fake.PrependReactor("create", "tokenreviews", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + tokenReview := &v1.TokenReview{ + TypeMeta: metav1.TypeMeta{ + Kind: "TokenReview", + APIVersion: "authentication.k8s.io/v1", + }, + Status: v1.TokenReviewStatus{ + Authenticated: test.tokenReviewAuthStatus, + Audiences: []string{}, + User: v1.UserInfo{ + Username: test.expectedUser, + }, + }, + } + return true, tokenReview, nil + }) + return authclient, nil + }, + clusterProxyConfigsGetter: cpsCache, + } + + req := test.downstreamRequest + req.Header.Set("Authorization", "Bearer "+test.token) + startUserInfo := &user.DefaultInfo{ + Name: test.startUser, + } + currentContext := req.Context() + req = req.WithContext(k8sRequest.WithUser(currentContext, startUserInfo)) + req = mux.SetURLVars(req, map[string]string{"clusterID": test.clusterID}) + user, isAuthenticated, err := auth.Authenticate(req.WithContext(req.Context())) + + if test.expectedError { + assert.NotNil(t, err, "Expected error") + } else { + assert.Nil(t, err, "Expected no error") + } + assert.Equal(t, test.isAuthenticated, isAuthenticated, "Unexpected authentication result") + assert.Equal(t, test.expectedUser, user.GetName(), "Expected username in the user info") + }) + } +} + +func generateDownstreamRequest(method string, path string) *http.Request { + req, _ := http.NewRequest("GET", proxyPrefix+path, nil) + return req +} + +func makeJWT(claims jwtv4.Claims) string { + token := jwtv4.NewWithClaims(jwtv4.SigningMethodHS256, claims) + sampleSecretKey := []byte("testingkeyfortestpurposes") + tokenString, _ := token.SignedString(sampleSecretKey) + return tokenString +} + +func TestConvertExtra(t *testing.T) { + tests := []struct { + name string + input map[string]v1.ExtraValue + want map[string][]string + }{ + { + name: "Empty Input", + input: map[string]v1.ExtraValue{}, + want: map[string][]string{}, + }, + { + name: "Single Key-Value", + input: map[string]v1.ExtraValue{ + "key1": {"value1"}, + }, + want: map[string][]string{ + "key1": {"value1"}, + }, + }, + { + name: "Multiple Key-Values", + input: map[string]v1.ExtraValue{ + "key1": {"value1", "value2"}, + "key2": {"value3"}, + }, + want: map[string][]string{ + "key1": {"value1", "value2"}, + "key2": {"value3"}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := convertExtra(tt.input) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("convertExtra() = %v, wantExpired %v", got, tt.want) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/token_review.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/token_review.go new file mode 100644 index 0000000..41b5434 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/requests/token_review.go @@ -0,0 +1,59 @@ +package requests + +import ( + "net/http" + + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/steve/pkg/auth" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + authv1 "k8s.io/client-go/kubernetes/typed/authentication/v1" +) + +type TokenReviewAuth struct { + AuthClient authv1.AuthenticationV1Interface +} + +func NewTokenReviewAuth(authClient authv1.AuthenticationV1Interface) auth.Authenticator { + return &TokenReviewAuth{ + AuthClient: authClient, + } +} + +// Authenticate attempts to authenticate using given function. If authentication +// fails AND the endpoint is in allowedPaths, it will attempt to perform a token +// review to authenticate token and extract user info. +func (t *TokenReviewAuth) Authenticate(req *http.Request) (user.Info, bool, error) { + info, hasAuth := request.UserFrom(req.Context()) + if info.GetName() != "system:cattle:error" { + // auth has succeeded + return info, hasAuth, nil + } + + tokenReview := &v1.TokenReview{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "authentication.k8s.io/v1", + Kind: "TokenReview", + }, + Spec: v1.TokenReviewSpec{ + Token: tokens.GetTokenAuthFromRequest(req), + }, + } + + tokenReview, err := t.AuthClient.TokenReviews().Create(req.Context(), tokenReview, metav1.CreateOptions{}) + if err != nil { + logrus.Debugf("tokenReview failed: %v", err) + return info, false, nil + } + + tokenReviewUserInfo := &user.DefaultInfo{ + Name: tokenReview.Status.User.Username, + UID: tokenReview.Status.User.UID, + Groups: tokenReview.Status.User.Groups, + } + + return tokenReviewUserInfo, true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/server.go new file mode 100644 index 0000000..dc7dcc1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/server.go @@ -0,0 +1,182 @@ +package auth + +import ( + "context" + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/norman/store/proxy" + "github.com/rancher/rancher/pkg/api/norman" + "github.com/rancher/rancher/pkg/auth/api" + "github.com/rancher/rancher/pkg/auth/data" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/publicapi" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/clusterrouter" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/types/config" + steveauth "github.com/rancher/steve/pkg/auth" + "github.com/sirupsen/logrus" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/rest" +) + +type Server struct { + Authenticator steveauth.Middleware + Management func(http.Handler) http.Handler + scaledContext *config.ScaledContext +} + +func NewAlwaysAdmin() (*Server, error) { + return &Server{ + Authenticator: steveauth.ToMiddleware(steveauth.AuthenticatorFunc(steveauth.AlwaysAdmin)), + Management: func(next http.Handler) http.Handler { + return next + }, + }, nil +} + +func NewHeaderAuth() (*Server, error) { + return &Server{ + Authenticator: steveauth.ToMiddleware(steveauth.AuthenticatorFunc(steveauth.Impersonation)), + Management: func(next http.Handler) http.Handler { + return next + }, + }, nil +} + +func NewServer(ctx context.Context, cfg *rest.Config) (*Server, error) { + sc, err := config.NewScaledContext(*cfg, nil) + if err != nil { + return nil, err + } + + sc.UserManager, err = common.NewUserManagerNoBindings(sc) + if err != nil { + return nil, err + } + + sc.ClientGetter, err = proxy.NewClientGetterFromConfig(*cfg) + if err != nil { + return nil, err + } + + authenticator := requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, sc) + authManagement, err := newAPIManagement(ctx, sc) + if err != nil { + return nil, err + } + + return &Server{ + Authenticator: requests.ToAuthMiddleware(authenticator), + Management: authManagement, + scaledContext: sc, + }, nil +} + +func newAPIManagement(ctx context.Context, scaledContext *config.ScaledContext) (steveauth.Middleware, error) { + privateAPI, err := newPrivateAPI(ctx, scaledContext) + if err != nil { + return nil, err + } + + publicAPI, err := publicapi.NewHandler(ctx, scaledContext, norman.ConfigureAPIUI) + if err != nil { + return nil, err + } + + saml := saml.AuthHandler() + + root := mux.NewRouter() + root.UseEncodedPath() + root.PathPrefix("/v3-public").Handler(publicAPI) + root.PathPrefix("/v1-saml").Handler(saml) + root.NotFoundHandler = privateAPI + + return func(next http.Handler) http.Handler { + privateAPI.NotFoundHandler = next + return root + }, nil +} + +func newPrivateAPI(ctx context.Context, scaledContext *config.ScaledContext) (*mux.Router, error) { + tokenAPI, err := tokens.NewAPIHandler(ctx, scaledContext, norman.ConfigureAPIUI) + if err != nil { + return nil, err + } + + otherAPIs, err := api.NewNormanServer(ctx, clusterrouter.GetClusterID, scaledContext) + if err != nil { + return nil, err + } + + root := mux.NewRouter() + root.UseEncodedPath() + root.Use(requests.NewAuthenticatedFilter) + root.PathPrefix("/v3/identit").Handler(tokenAPI) + root.PathPrefix("/v3/token").Handler(tokenAPI) + root.PathPrefix("/v3/authConfig").Handler(otherAPIs) + root.PathPrefix("/v3/principal").Handler(otherAPIs) + root.PathPrefix("/v3/user").Handler(otherAPIs) + root.PathPrefix("/v3/schema").Handler(otherAPIs) + root.PathPrefix("/v3/subscribe").Handler(otherAPIs) + return root, nil +} + +func (s *Server) OnLeader(ctx context.Context) error { + if s.scaledContext == nil { + return nil + } + + management := &config.ManagementContext{ + Management: s.scaledContext.Management, + Core: s.scaledContext.Core, + } + + if err := data.AuthConfigs(management); err != nil { + return fmt.Errorf("failed to add authconfig data: %v", err) + } + + tokens.StartPurgeDaemon(ctx, management) + providerrefresh.StartRefreshDaemon(ctx, s.scaledContext, management) + logrus.Infof("Steve auth startup complete") + return nil +} + +func (s *Server) Start(ctx context.Context, leader bool) error { + if s.scaledContext == nil { + return nil + } + + if err := s.scaledContext.Start(ctx); err != nil { + return err + } + if leader { + return s.OnLeader(ctx) + } + return nil +} + +func SetXAPICattleAuthHeader(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if features.Auth.Enabled() { + user, ok := request.UserFrom(req.Context()) + if ok { + ok = false + for _, group := range user.GetGroups() { + if group == "system:authenticated" { + ok = true + } + } + } + rw.Header().Set("X-API-Cattle-Auth", fmt.Sprint(ok)) + } else { + rw.Header().Set("X-API-Cattle-Auth", "none") + } + next.ServeHTTP(rw, req) + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/settings/settings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/settings/settings.go new file mode 100644 index 0000000..905dde5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/settings/settings.go @@ -0,0 +1,29 @@ +package settings + +var ( + AuthUserInfoResyncCron = newSetting("0 0 * * *") + AuthUserSessionTTLMinutes = newSetting("960") // 16 hours + AuthUserInfoMaxAgeSeconds = newSetting("3600") // 1 hour + FirstLogin = newSetting("true") +) + +type Setting interface { + Get() string + Set(val string) error +} + +func newSetting(val string) Setting { + return &setting{val} +} + +type setting struct { + val string +} + +func (s *setting) Get() string { + return s.val +} + +func (s *setting) Set(val string) error { + panic("not implemented") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/api.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/api.go new file mode 100644 index 0000000..b2526bc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/api.go @@ -0,0 +1,86 @@ +package tokens + +import ( + "context" + "net/http" + + normanapi "github.com/rancher/norman/api" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" +) + +const ( + CookieName = "R_SESS" + AuthHeaderName = "Authorization" + AuthValuePrefix = "Bearer" + BasicAuthPrefix = "Basic" + CSRFCookie = "CSRF" +) + +var crdVersions = []*types.APIVersion{ + &managementSchema.Version, +} + +type ServerOption func(server *normanapi.Server) + +func NewAPIHandler(ctx context.Context, apiContext *config.ScaledContext, opts ...ServerOption) (http.Handler, error) { + api := &tokenAPI{ + mgr: NewManager(ctx, apiContext), + } + + schemas := types.NewSchemas().AddSchemas(managementSchema.TokenSchemas) + schema := schemas.Schema(&managementSchema.Version, client.TokenType) + schema.CollectionActions = map[string]types.Action{ + "logout": {}, + } + + schema.ActionHandler = api.tokenActionHandler + schema.ListHandler = api.tokenListHandler + schema.CreateHandler = api.tokenCreateHandler + schema.DeleteHandler = api.tokenDeleteHandler + + server := normanapi.NewAPIServer() + if err := server.AddSchemas(schemas); err != nil { + return nil, err + } + + for _, opt := range opts { + opt(server) + } + + return server, nil +} + +type tokenAPI struct { + mgr *Manager +} + +func (t *tokenAPI) tokenActionHandler(actionName string, action *types.Action, request *types.APIContext) error { + logrus.Debugf("TokenActionHandler called for action %v", actionName) + if actionName == "logout" { + return t.mgr.logout(actionName, action, request) + } + return httperror.NewAPIError(httperror.ActionNotAvailable, "") +} + +func (t *tokenAPI) tokenCreateHandler(request *types.APIContext, _ types.RequestHandler) error { + logrus.Debugf("TokenCreateHandler called") + return t.mgr.deriveToken(request) +} + +func (t *tokenAPI) tokenListHandler(request *types.APIContext, _ types.RequestHandler) error { + logrus.Debugf("TokenListHandler called") + if request.ID != "" { + return t.mgr.getTokenFromRequest(request) + } + return t.mgr.listTokens(request) +} + +func (t *tokenAPI) tokenDeleteHandler(request *types.APIContext, _ types.RequestHandler) error { + logrus.Debugf("TokenDeleteHandler called") + return t.mgr.removeToken(request) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers.go new file mode 100644 index 0000000..e985ab1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers.go @@ -0,0 +1,61 @@ +// Package hashers provides the various hash methods which can be used to hash tokens +package hashers + +import ( + "fmt" + "strconv" + "strings" +) + +type HashVersion int + +const ( + ScryptVersion HashVersion = iota + 1 + SHA256Version + SHA3Version +) + +// Hasher describes an interface which allows a user to create a hash for a value or verify that a hash is correct. +type Hasher interface { + // CreateHash creates a hash for a secret, returns nil, err if it encounters an error + CreateHash(secretKey string) (string, error) + // VerifyHash verifies that the hash of secretKey == hash + VerifyHash(hash, secretKey string) error +} + +// GetHasherForHash matches a hash with the hasher that produced it by looking at the version in the string. +func GetHasherForHash(hash string) (Hasher, error) { + version, err := GetHashVersion(hash) + if err != nil { + return nil, fmt.Errorf("unable to determine version for hash, %w", err) + } + switch HashVersion(version) { + case ScryptVersion: + return ScryptHasher{}, nil + case SHA256Version: + return Sha256Hasher{}, nil + case SHA3Version: + return Sha3Hasher{}, nil + default: + return nil, fmt.Errorf("invalid version %d, no hasher exists for that version", version) + } +} + +// GetHasher produces the hasher which should be used for new tokens, for verifying existing tokens use GetHasherForHash. +func GetHasher() Hasher { + return Sha3Hasher{} +} + +// GetHashVersion produces the hash version for a given hash. +func GetHashVersion(hash string) (HashVersion, error) { + splitHash := strings.SplitN(strings.TrimPrefix(hash, "$"), ":", 3) + if len(splitHash) != 3 { + return 0, fmt.Errorf("hash format invalid") + } + version, err := strconv.Atoi(splitHash[0]) + // this value could in theory be part of a sensitive value, so we don't include it in the error + if err != nil { + return 0, fmt.Errorf("unable to convert hash version") + } + return HashVersion(version), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers_test.go new file mode 100644 index 0000000..36a1ad3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/hashers_test.go @@ -0,0 +1,112 @@ +package hashers + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetHasherForHash(t *testing.T) { + const testSecret = "testsecret" + scryptHash, err := ScryptHasher{}.CreateHash(testSecret) + assert.NoError(t, err, "error when creating scrypt hash") + sha256Hash, err := Sha256Hasher{}.CreateHash(testSecret) + assert.NoError(t, err, "error when creating sha256 hash") + sha3Hash, err := Sha3Hasher{}.CreateHash(testSecret) + assert.NoError(t, err, "error when creating sha3 hash") + + tests := []struct { + name string + hash string + wantHasher Hasher + wantErr bool + }{ + { + name: "scrypt hash", + hash: scryptHash, + wantHasher: ScryptHasher{}, + wantErr: false, + }, + { + name: "sha256 hash", + hash: sha256Hash, + wantHasher: Sha256Hasher{}, + wantErr: false, + }, + { + name: "sha3 hash", + hash: sha3Hash, + wantHasher: Sha3Hasher{}, + wantErr: false, + }, + { + name: "invalid hash", + hash: "thisisnotahash", + wantHasher: nil, + wantErr: true, + }, + { + name: "invalid hash version", + hash: "$4:some-salt-here:some-secret-here", + wantHasher: nil, + wantErr: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + hasher, err := GetHasherForHash(test.hash) + if test.wantErr { + assert.Error(t, err, "wanted error but did not get one") + } else { + assert.NoError(t, err, "got an error but did not get one") + assert.IsTypef(t, hasher, test.wantHasher, "did not get the expected hasher") + } + }) + } +} + +func TestGetHasher(t *testing.T) { + t.Parallel() + assert.IsTypef(t, Sha3Hasher{}, GetHasher(), "expected SHA3 to be the default hasher") +} + +func TestGetHashVersion(t *testing.T) { + tests := []struct { + name string + hash string + wantHashVersion HashVersion + wantErr bool + }{ + { + name: "test valid hash", + hash: "$1:some-salt-here:some-secret-here", + wantHashVersion: ScryptVersion, + wantErr: false, + }, + { + name: "test bad hash format", + hash: "$1:some-secret-here", + wantErr: true, + }, + { + name: "test bad hash version", + hash: "$not-a-number:some-salt-here:some-secret-here", + wantErr: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + hashVersion, err := GetHashVersion(test.hash) + if test.wantErr { + assert.Error(t, err, "Wanted error but did not get one") + } else { + assert.NoError(t, err, "Wanted error but did not get one") + assert.Equal(t, test.wantHashVersion, hashVersion, "did not get expected hash version") + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/scrypt.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/scrypt.go new file mode 100644 index 0000000..daa3a5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/scrypt.go @@ -0,0 +1,78 @@ +package hashers + +import ( + "crypto/rand" + "crypto/subtle" + "encoding/base64" + "fmt" + + "golang.org/x/crypto/scrypt" +) + +const ( + scryptHashFormat = "$%d:%x:%d:%d:%d:%s" +) + +// ScryptHasher implements the Hasher interface using a backing alogorithm of Scrypt. +type ScryptHasher struct{} + +// CreateHash hahshes secretKey using a salt and scrypt. +func (s ScryptHasher) CreateHash(secretKey string) (string, error) { + const ( + n = 15 + r = 8 + p = 1 + keyLen = 64 + saltLen = 8 + ) + salt := make([]byte, saltLen) + + _, err := rand.Read(salt) + if err != nil { + return "", err + } + + dk, err := scrypt.Key([]byte(secretKey), salt, 1< $1:abc:def +) + +// Sha256Hasher implements the Hasher interface using a backing algorithm of SHA256. +type Sha256Hasher struct{} + +// CreateHash hashes secretKey using a random salt and SHA256. +func (s Sha256Hasher) CreateHash(secretKey string) (string, error) { + salt := make([]byte, 8) + _, err := rand.Read(salt) + if err != nil { + return "", err + } + hash := sha256.Sum256([]byte(fmt.Sprintf("%s%s", salt, secretKey))) + encSalt := base64.RawStdEncoding.EncodeToString(salt) + encKey := base64.RawStdEncoding.EncodeToString(hash[:]) + return fmt.Sprintf(sha256HashFormat, SHA256Version, encSalt, encKey), nil +} + +// VerifyHash compares a key with the hash, and will produce an error if the hash does not match or if the hash is not +// a valid SHA256 hash. +func (s Sha256Hasher) VerifyHash(hash, secretKey string) error { + if !strings.HasPrefix(hash, "$") { + return errors.New("hash format invalid") + } + splitHash := strings.SplitN(strings.TrimPrefix(hash, "$"), ":", 3) + if len(splitHash) != 3 { + return errors.New("hash format invalid") + } + + version, err := strconv.Atoi(splitHash[0]) + if err != nil { + return err + } + if HashVersion(version) != SHA256Version { + return fmt.Errorf("hash version %d does not match package version %d", version, SHA256Version) + } + + salt, enc := splitHash[1], splitHash[2] + // base64 decode stored salt and key + decodedKey, err := base64.RawStdEncoding.DecodeString(enc) + if err != nil { + return err + } + if len(decodedKey) < 1 { + return errors.New("secretKey hash does not match") // Don't allow accidental empty string to succeed + } + decodedSalt, err := base64.RawStdEncoding.DecodeString(salt) + if err != nil { + return err + } + // compare the two + hashedSecretKey := sha256.Sum256([]byte(string(decodedSalt) + secretKey)) + if subtle.ConstantTimeCompare(decodedKey, hashedSecretKey[:]) == 0 { + return errors.New("secretKey hash does not match") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha256_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha256_test.go new file mode 100644 index 0000000..9577e6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha256_test.go @@ -0,0 +1,30 @@ +package hashers + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBasicSha256Hash(t *testing.T) { + secretKey := "hello world" + hasher := Sha256Hasher{} + hash, err := hasher.CreateHash(secretKey) + assert.Nil(t, err) + assert.NotNil(t, hash) + // Now check it + assert.Nil(t, hasher.VerifyHash(hash, secretKey)) + assert.NotNil(t, hasher.VerifyHash(hash, "incorrect")) +} + +func TestSha256LongKey(t *testing.T) { + secretKey := strings.Repeat("A", 720) + hasher := Sha256Hasher{} + hash, err := hasher.CreateHash(secretKey) + assert.Nil(t, err) + assert.NotNil(t, hash) + // Now check it + assert.Nil(t, hasher.VerifyHash(hash, secretKey)) + assert.NotNil(t, hasher.VerifyHash(hash, secretKey+":wrong!")) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3.go new file mode 100644 index 0000000..e4c07af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3.go @@ -0,0 +1,89 @@ +package hashers + +import ( + "crypto/rand" + "crypto/subtle" + "encoding/base64" + "fmt" + "strconv" + "strings" + + "golang.org/x/crypto/sha3" +) + +const ( + sha3HashFormat = "$%d:%d:%s:%s" // $version:sha3_variation:salt:hash -> $1:1:abc:def + // sha512variation is the value that identifies a particular hash as using sha512 as the backing hash + sha512variation = 1 + // saltLength is the length of the salt used in the hash + saltLength = 8 +) + +// Sha3Hasher implements the Hasher interface using a backing algorithm of SHA3 and SHA512. +type Sha3Hasher struct{} + +// CreateHash hashes secretKey using a random salt and SHA3/SHA512. +func (s Sha3Hasher) CreateHash(secretKey string) (string, error) { + secretKeyBytes := []byte(secretKey) + // to save on allocations, we will first read the salt into hashInput, and then append the secretKey + // rand will only read to len(hashInput), so we set the length to saltLength but pre-allocate the + // capacity for the secret key that will be appended later + hashInput := make([]byte, saltLength, saltLength+len(secretKeyBytes)) + _, err := rand.Read(hashInput) + if err != nil { + return "", fmt.Errorf("unable to read random values for salt: %w", err) + } + hashInput = append(hashInput, secretKeyBytes...) + hash := sha3.Sum512(hashInput) + encSalt := base64.RawStdEncoding.EncodeToString(hashInput[:saltLength]) + encKey := base64.RawStdEncoding.EncodeToString(hash[:]) + return fmt.Sprintf(sha3HashFormat, SHA3Version, sha512variation, encSalt, encKey), nil +} + +// VerifyHash compares a key with the hash, and will produce an error if the hash does not match or if the hash is not +// a valid SHA3 hash. +func (s Sha3Hasher) VerifyHash(hash, secretKey string) error { + if !strings.HasPrefix(hash, "$") { + return fmt.Errorf("hash format invalid") + } + splitHash := strings.Split(strings.TrimPrefix(hash, "$"), ":") + if len(splitHash) != 4 { + return fmt.Errorf("hash format invalid") + } + + version, err := strconv.Atoi(splitHash[0]) + if err != nil { + return err + } + if HashVersion(version) != SHA3Version { + return fmt.Errorf("hash version %d does not match package version %d", version, SHA3Version) + } + + variationVersion, err := strconv.Atoi(splitHash[1]) + if err != nil { + return fmt.Errorf("unable to convert hash variation to an int") + } + if variationVersion != sha512variation { + return fmt.Errorf("sha3 variation %d is not a known variation: [%d]", variationVersion, sha512variation) + } + + salt, enc := splitHash[2], splitHash[3] + // base64 decode stored salt and key + decodedKey, err := base64.RawStdEncoding.DecodeString(enc) + if err != nil { + return err + } + if len(decodedKey) < 1 { + return fmt.Errorf("secretKey hash does not match") // Don't allow accidental empty string to succeed + } + decodedSalt, err := base64.RawStdEncoding.DecodeString(salt) + if err != nil { + return err + } + // compare the two + hashedSecretKey := sha3.Sum512([]byte(fmt.Sprintf("%s%s", string(decodedSalt), secretKey))) + if subtle.ConstantTimeCompare(decodedKey, hashedSecretKey[:]) == 0 { + return fmt.Errorf("secretKey hash does not match") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3_test.go new file mode 100644 index 0000000..50516a9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/hashers/sha3_test.go @@ -0,0 +1,114 @@ +package hashers + +import ( + "strconv" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBasicSha3Hash(t *testing.T) { + secretKey := "hello world" + hasher := Sha3Hasher{} + hash, err := hasher.CreateHash(secretKey) + require.Nil(t, err) + require.NotNil(t, hash) + splitHash := strings.Split(hash, ":") + require.Len(t, splitHash, 4) + require.Equal(t, strconv.Itoa(int(SHA3Version)), splitHash[0][1:]) + require.Equal(t, splitHash[1], "1") + // Now check it + require.Nil(t, hasher.VerifyHash(hash, secretKey)) + require.NotNil(t, hasher.VerifyHash(hash, "incorrect")) +} + +func TestSha3LongKey(t *testing.T) { + secretKey := strings.Repeat("A", 720) + hasher := Sha3Hasher{} + hash, err := hasher.CreateHash(secretKey) + require.Nil(t, err) + require.NotNil(t, hash) + splitHash := strings.Split(hash, ":") + require.Len(t, splitHash, 4) + require.Equal(t, strconv.Itoa(int(SHA3Version)), splitHash[0][1:]) + require.Equal(t, splitHash[1], "1") + // Now check it + require.Nil(t, hasher.VerifyHash(hash, secretKey)) + require.NotNil(t, hasher.VerifyHash(hash, "incorrect")) +} + +func TestSHA3VerifyHash(t *testing.T) { + tests := []struct { + name string + hash string + secretKey string + wantError bool + }{ + { + name: "valid hash", + hash: "$3:1:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: false, + }, + { + name: "invalid hash format", + hash: "$3:1:uFrxm43ggfw", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "invalid hash version", + hash: "$2:1:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "invalid sha variation", + hash: "$3:2:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "invalid secret key", + hash: "$3:2:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "wrong", + wantError: true, + }, + { + name: "missing $ prefix", + hash: "3:1:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "non-int hash version", + hash: "$A:1:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "non base64 character in salt", + hash: "$3:B:#Frxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + { + name: "non base64 character in hash", + hash: "$3:B:uFrxm43ggfw:#sN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA", + secretKey: "dddddddddddddddddddddddddddddddddddddddddddddddddddddd", + wantError: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + hasher := Sha3Hasher{} + err := hasher.VerifyHash(test.hash, test.secretKey) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager.go new file mode 100644 index 0000000..aa000be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager.go @@ -0,0 +1,837 @@ +package tokens + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "reflect" + "sort" + "time" + + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/util" + "github.com/rancher/rancher/pkg/catalog/utils" + clientv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + apicorev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// TODO Cleanup error logging. If error is being returned, use errors.wrap to return and dont log here + +const ( + userPrincipalIndex = "authn.management.cattle.io/user-principal-index" + UserIDLabel = "authn.management.cattle.io/token-userId" + TokenKindLabel = "authn.management.cattle.io/kind" + TokenHashed = "authn.management.cattle.io/token-hashed" + tokenKeyIndex = "authn.management.cattle.io/token-key-index" + secretNameEnding = "-secret" + SecretNamespace = "cattle-system" + KubeconfigResponseType = "kubeconfig" +) + +var ( + toDeleteCookies = []string{CookieName, CSRFCookie} +) + +func RegisterIndexer(apiContext *config.ScaledContext) error { + informer := apiContext.Management.Users("").Controller().Informer() + return informer.AddIndexers(map[string]cache.IndexFunc{userPrincipalIndex: userPrincipalIndexer}) +} + +func NewManager(ctx context.Context, apiContext *config.ScaledContext) *Manager { + informer := apiContext.Management.Users("").Controller().Informer() + tokenInformer := apiContext.Management.Tokens("").Controller().Informer() + + return &Manager{ + ctx: ctx, + tokensClient: apiContext.Management.Tokens(""), + userIndexer: informer.GetIndexer(), + tokenIndexer: tokenInformer.GetIndexer(), + userAttributes: apiContext.Management.UserAttributes(""), + userAttributeLister: apiContext.Management.UserAttributes("").Controller().Lister(), + userLister: apiContext.Management.Users("").Controller().Lister(), + secrets: apiContext.Core.Secrets(""), + secretLister: apiContext.Core.Secrets("").Controller().Lister(), + } +} + +type Manager struct { + ctx context.Context + tokensClient v3.TokenInterface + userAttributes v3.UserAttributeInterface + userAttributeLister v3.UserAttributeLister + userIndexer cache.Indexer + tokenIndexer cache.Indexer + userLister v3.UserLister + secrets v1.SecretInterface + secretLister v1.SecretLister +} + +func userPrincipalIndexer(obj interface{}) ([]string, error) { + user, ok := obj.(*v3.User) + if !ok { + return []string{}, nil + } + + return user.PrincipalIDs, nil +} + +// createDerivedToken will create a jwt token for the authenticated user +func (m *Manager) createDerivedToken(jsonInput clientv3.Token, tokenAuthValue string) (v3.Token, string, int, error) { + logrus.Debug("Create Derived Token Invoked") + + token, _, err := m.getToken(tokenAuthValue) + if err != nil { + return v3.Token{}, "", 401, err + } + + tokenTTL, err := ClampToMaxTTL(time.Duration(int64(jsonInput.TTLMillis)) * time.Millisecond) + if err != nil { + return v3.Token{}, "", 500, fmt.Errorf("error validating max-ttl %v", err) + } + + var unhashedTokenKey string + derivedToken := v3.Token{ + UserPrincipal: token.UserPrincipal, + IsDerived: true, + TTLMillis: tokenTTL.Milliseconds(), + UserID: token.UserID, + AuthProvider: token.AuthProvider, + ProviderInfo: token.ProviderInfo, + Description: jsonInput.Description, + ClusterName: jsonInput.ClusterID, + } + derivedToken, unhashedTokenKey, err = m.createToken(&derivedToken) + + return derivedToken, unhashedTokenKey, 0, err + +} + +// createToken returns the token object and it's unhashed token key, which is stored hashed +func (m *Manager) createToken(k8sToken *v3.Token) (v3.Token, string, error) { + key, err := randomtoken.Generate() + if err != nil { + logrus.Errorf("Failed to generate token key: %v", err) + return v3.Token{}, "", errors.New("failed to generate token key") + } + + if k8sToken.ObjectMeta.Labels == nil { + k8sToken.ObjectMeta.Labels = make(map[string]string) + } + k8sToken.APIVersion = "management.cattle.io/v3" + k8sToken.Kind = "Token" + k8sToken.Token = key + k8sToken.ObjectMeta.Labels[UserIDLabel] = k8sToken.UserID + k8sToken.ObjectMeta.GenerateName = "token-" + err = ConvertTokenKeyToHash(k8sToken) + if err != nil { + return v3.Token{}, "", err + } + createdToken, err := m.tokensClient.Create(k8sToken) + + if err != nil { + return v3.Token{}, "", err + } + + return *createdToken, key, nil +} + +func (m *Manager) updateToken(token *v3.Token) (*v3.Token, error) { + return m.tokensClient.Update(token) +} + +func (m *Manager) getToken(tokenAuthValue string) (*v3.Token, int, error) { + tokenName, tokenKey := SplitTokenParts(tokenAuthValue) + + lookupUsingClient := false + + objs, err := m.tokenIndexer.ByIndex(tokenKeyIndex, tokenKey) + if err != nil { + if apierrors.IsNotFound(err) { + lookupUsingClient = true + } else { + return nil, 404, fmt.Errorf("failed to retrieve auth token from cache, error: %v", err) + } + } else if len(objs) == 0 { + lookupUsingClient = true + } + + var storedToken *v3.Token + if lookupUsingClient { + storedToken, err = m.tokensClient.Get(tokenName, metav1.GetOptions{}) + if err != nil { + return nil, 404, fmt.Errorf("failed to retrieve auth token, error: %#v", err) + } + } else { + storedToken = objs[0].(*v3.Token) + } + + if code, err := VerifyToken(storedToken, tokenName, tokenKey); err != nil { + return nil, code, err + } + + return storedToken, 0, nil +} + +// GetTokens will list all(login and derived, and even expired) tokens of the authenticated user +func (m *Manager) getTokens(tokenAuthValue string) ([]v3.Token, int, error) { + logrus.Debug("LIST Tokens Invoked") + tokens := make([]v3.Token, 0) + + storedToken, _, err := m.getToken(tokenAuthValue) + if err != nil { + return tokens, 401, err + } + + userID := storedToken.UserID + set := labels.Set(map[string]string{UserIDLabel: userID}) + tokenList, err := m.tokensClient.List(metav1.ListOptions{LabelSelector: set.AsSelector().String()}) + if err != nil { + return tokens, 0, fmt.Errorf("error getting tokens for user: %v selector: %v err: %v", userID, set.AsSelector().String(), err) + } + + for _, t := range tokenList.Items { + if IsExpired(t) { + t.Expired = true + } + tokens = append(tokens, t) + } + return tokens, 0, nil +} + +func (m *Manager) deleteToken(tokenAuthValue string) (int, error) { + logrus.Debug("DELETE Token Invoked") + + storedToken, status, err := m.getToken(tokenAuthValue) + if err != nil { + if status == 404 { + return 0, nil + } else if status != 410 { + return 401, err + } + } + + return m.deleteTokenByName(storedToken.Name) +} + +func (m *Manager) deleteTokenByName(tokenName string) (int, error) { + err := m.tokensClient.Delete(tokenName, &metav1.DeleteOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return 0, nil + } + return 500, fmt.Errorf("failed to delete token") + } + logrus.Debug("Deleted Token") + return 0, nil +} + +// getToken will get the token by ID +func (m *Manager) getTokenByID(tokenAuthValue string, tokenID string) (v3.Token, int, error) { + logrus.Debug("GET Token Invoked") + token := &v3.Token{} + + storedToken, _, err := m.getToken(tokenAuthValue) + if err != nil { + return *token, 401, err + } + + token, err = m.tokensClient.Get(tokenID, metav1.GetOptions{}) + if err != nil { + return v3.Token{}, 404, err + } + + if token.UserID != storedToken.UserID { + return v3.Token{}, 404, fmt.Errorf("%v not found", tokenID) + } + + if IsExpired(*token) { + token.Expired = true + } + + return *token, 0, nil +} + +func (m *Manager) deriveToken(request *types.APIContext) error { + + r := request.Request + + tokenAuthValue := GetTokenAuthFromRequest(r) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "No valid token cookie or auth header") + } + + bytes, err := ioutil.ReadAll(r.Body) + if err != nil { + return httperror.NewAPIError(httperror.InvalidBodyContent, fmt.Sprintf("%s", err)) + } + + jsonInput := clientv3.Token{} + err = json.Unmarshal(bytes, &jsonInput) + if err != nil { + return httperror.NewAPIError(httperror.InvalidFormat, fmt.Sprintf("%s", err)) + } + + // create derived token + token, unhashedTokenKey, status, err := m.createDerivedToken(jsonInput, tokenAuthValue) + if err != nil { + logrus.Errorf("deriveToken failed with error: %v", err) + if status == 0 { + status = http.StatusInternalServerError + } + return httperror.NewAPIErrorLong(status, util.GetHTTPErrorCode(status), fmt.Sprintf("%v", err)) + } + + tokenData, err := ConvertTokenResource(request.Schema, token) + if err != nil { + return err + } + tokenData["token"] = token.ObjectMeta.Name + ":" + unhashedTokenKey + + request.WriteResponse(http.StatusCreated, tokenData) + + return nil +} + +func (m *Manager) listTokens(request *types.APIContext) error { + r := request.Request + + // TODO switch to X-API-UserId header + tokenAuthValue := GetTokenAuthFromRequest(r) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "No valid token cookie or auth header") + } + //getToken + tokens, status, err := m.getTokens(tokenAuthValue) + if err != nil { + logrus.Errorf("GetToken failed with error: %v", err) + if status == 0 { + status = http.StatusInternalServerError + } + return httperror.NewAPIErrorLong(status, util.GetHTTPErrorCode(status), fmt.Sprintf("%v", err)) + } + + currentAuthToken, _, err := m.getToken(tokenAuthValue) + if err != nil { + return err + } + + tokensFromStore := make([]map[string]interface{}, len(tokens)) + for _, token := range tokens { + token.Current = currentAuthToken.Name == token.Name && !currentAuthToken.IsDerived + tokenData, err := ConvertTokenResource(request.Schema, token) + if err != nil { + return err + } + + tokensFromStore = append(tokensFromStore, tokenData) + } + + request.WriteResponse(http.StatusOK, tokensFromStore) + return nil +} + +func (m *Manager) logout(actionName string, action *types.Action, request *types.APIContext) error { + r := request.Request + w := request.Response + + tokenAuthValue := GetTokenAuthFromRequest(r) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "No valid token cookie or auth header") + } + + isSecure := false + if r.URL.Scheme == "https" { + isSecure = true + } + + for _, cookieName := range toDeleteCookies { + tokenCookie := &http.Cookie{ + Name: cookieName, + Value: "", + Secure: isSecure, + Path: "/", + HttpOnly: true, + MaxAge: -1, + Expires: time.Date(1982, time.February, 10, 23, 0, 0, 0, time.UTC), + } + http.SetCookie(w, tokenCookie) + } + w.Header().Add("Content-type", "application/json") + + //getToken + status, err := m.deleteToken(tokenAuthValue) + if err != nil { + logrus.Errorf("DeleteToken failed with error: %v", err) + if status == 0 { + status = http.StatusInternalServerError + } + return httperror.NewAPIErrorLong(status, util.GetHTTPErrorCode(status), fmt.Sprintf("%v", err)) + } + return nil +} + +func (m *Manager) getTokenFromRequest(request *types.APIContext) error { + // TODO switch to X-API-UserId header + r := request.Request + + tokenAuthValue := GetTokenAuthFromRequest(r) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "No valid token cookie or auth header") + } + + tokenID := request.ID + + currentAuthToken, _, err := m.getToken(tokenAuthValue) + if err != nil { + return err + } + + //getToken + token, status, err := m.getTokenByID(tokenAuthValue, tokenID) + if err != nil { + logrus.Errorf("GetToken failed with error: %v", err) + if status == 0 { + status = http.StatusInternalServerError + } else if status == 410 { + status = http.StatusNotFound + } + return httperror.NewAPIErrorLong(status, util.GetHTTPErrorCode(status), fmt.Sprintf("%v", err)) + } + token.Current = currentAuthToken.Name == token.Name && !currentAuthToken.IsDerived + tokenData, err := ConvertTokenResource(request.Schema, token) + if err != nil { + return err + } + request.WriteResponse(http.StatusOK, tokenData) + return nil +} + +func (m *Manager) removeToken(request *types.APIContext) error { + // TODO switch to X-API-UserId header + r := request.Request + + tokenAuthValue := GetTokenAuthFromRequest(r) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "No valid token cookie or auth header") + } + tokenID := request.ID + + //getToken + t, status, err := m.getTokenByID(tokenAuthValue, tokenID) + if err != nil { + if status != 410 { + logrus.Errorf("DeleteToken Failed to fetch the token to delete with error: %v", err) + if status == 0 { + status = http.StatusInternalServerError + } + return httperror.NewAPIErrorLong(status, util.GetHTTPErrorCode(status), fmt.Sprintf("%v", err)) + } + } + + currentAuthToken, _, err := m.getToken(tokenAuthValue) + if err != nil { + return err + } + + if currentAuthToken.Name == t.Name && !currentAuthToken.IsDerived { + return httperror.NewAPIErrorLong(http.StatusBadRequest, util.GetHTTPErrorCode(http.StatusBadRequest), "Cannot delete token for current session. Use logout instead") + } + + if _, err := m.deleteTokenByName(t.Name); err != nil { + return err + } + + request.WriteResponse(http.StatusNoContent, nil) + return nil +} + +// CreateSecret saves the secret in k8s. Secret is saved under the userID-secret with +// key being the provider and data being the providers secret +func (m *Manager) CreateSecret(userID, provider, secret string) error { + _, err := m.secretLister.Get(SecretNamespace, userID+secretNameEnding) + // An error either means it already exists or something bad happened + if err != nil { + if !apierrors.IsNotFound(err) { + return err + } + // The secret doesn't exist so create it + data := make(map[string]string) + data[provider] = secret + + s := apicorev1.Secret{ + StringData: data, + } + s.ObjectMeta = metav1.ObjectMeta{ + Name: userID + secretNameEnding, + Namespace: SecretNamespace, + } + _, err = m.secrets.Create(&s) + return err + } + + // No error means the secret already exists and needs to be updated + return m.UpdateSecret(userID, provider, secret) +} + +func (m *Manager) GetSecret(userID string, provider string, fallbackTokens []*v3.Token) (string, error) { + cachedSecret, err := m.secretLister.Get(SecretNamespace, userID+secretNameEnding) + if err != nil && !apierrors.IsNotFound(err) { + return "", err + } + + if (err == nil) && cachedSecret != nil && string(cachedSecret.Data[provider]) != "" { + return string(cachedSecret.Data[provider]), nil + } + + for _, token := range fallbackTokens { + secret := token.ProviderInfo["access_token"] + if secret != "" { + return secret, nil + } + } + + return "", err // The not found error from above +} + +func (m *Manager) UpdateSecret(userID, provider, secret string) error { + cachedSecret, err := m.secretLister.Get(SecretNamespace, userID+secretNameEnding) + if err != nil { + return err + } + + cachedSecret = cachedSecret.DeepCopy() + + cachedSecret.Data[provider] = []byte(secret) + + _, err = m.secrets.Update(cachedSecret) + return err +} + +func (m *Manager) EnsureAndGetUserAttribute(userID string) (*v3.UserAttribute, bool, error) { + attribs, err := m.userAttributeLister.Get("", userID) + if err != nil && !apierrors.IsNotFound(err) { + return nil, false, err + } + + if attribs == nil { + attribs, err = m.userAttributes.Get(userID, metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return nil, false, err + } + } + + if attribs != nil && attribs.Name != "" { + return attribs.DeepCopy(), false, nil + } + + user, err := m.userLister.Get("", userID) + if err != nil { + return nil, false, err + } + + attribs = &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: user.APIVersion, + Kind: user.Kind, + UID: user.UID, + Name: user.Name, + }, + }, + }, + GroupPrincipals: map[string]v32.Principals{}, + ExtraByProvider: map[string]map[string][]string{}, + LastRefresh: "", + NeedsRefresh: false, + } + + return attribs, true, nil +} + +func (m *Manager) UserAttributeCreateOrUpdate(userID, provider string, groupPrincipals []v3.Principal, userExtraInfo map[string][]string, loginTime ...time.Time) error { + attribs, needCreate, err := m.EnsureAndGetUserAttribute(userID) + if err != nil { + return err + } + + if attribs.GroupPrincipals == nil { + attribs.GroupPrincipals = make(map[string]v32.Principals) + } + + if attribs.ExtraByProvider == nil { + attribs.ExtraByProvider = make(map[string]map[string][]string) + } + if userExtraInfo == nil { + userExtraInfo = make(map[string][]string) + } + + shouldUpdate := m.userAttributeChanged(attribs, provider, userExtraInfo, groupPrincipals) + if len(loginTime) > 0 && !loginTime[0].IsZero() { + // Login time is truncated to seconds as the corresponding user label is set as epoch time. + lastLogin := metav1.NewTime(loginTime[0].Truncate(time.Second)) + attribs.LastLogin = &lastLogin + shouldUpdate = true + } + + attribs.GroupPrincipals[provider] = v32.Principals{Items: groupPrincipals} + attribs.ExtraByProvider[provider] = userExtraInfo + + if needCreate { + _, err = m.userAttributes.Create(attribs) + if err != nil { + return fmt.Errorf("failed to create UserAttribute: %w", err) + } + + return nil + } + + if shouldUpdate { + _, err = m.userAttributes.Update(attribs) + if err != nil { + return fmt.Errorf("failed to update UserAttribute: %w", err) + } + } + + return nil +} + +func (m *Manager) userAttributeChanged(attribs *v32.UserAttribute, provider string, extraInfo map[string][]string, groupPrincipals []v32.Principal) bool { + oldSet := []string{} + newSet := []string{} + + if len(attribs.GroupPrincipals[provider].Items) != len(groupPrincipals) { + return true + } + + for _, principal := range attribs.GroupPrincipals[provider].Items { + oldSet = append(oldSet, principal.ObjectMeta.Name) + } + for _, principal := range groupPrincipals { + newSet = append(newSet, principal.ObjectMeta.Name) + } + sort.Strings(oldSet) + sort.Strings(newSet) + + for i := range oldSet { + if oldSet[i] != newSet[i] { + return true + } + } + + if attribs.ExtraByProvider == nil && extraInfo != nil { + return true + } + + return !reflect.DeepEqual(attribs.ExtraByProvider[provider], extraInfo) +} + +// PerUserCacheProviders is a set of provider names for which the token manager creates a per-user login token. +var PerUserCacheProviders = []string{"github", "azuread", "googleoauth", "oidc", "keycloakoidc", "genericoidc"} + +func (m *Manager) NewLoginToken(userID string, userPrincipal v3.Principal, groupPrincipals []v3.Principal, providerToken string, ttl int64, description string) (v3.Token, string, error) { + provider := userPrincipal.Provider + // Providers that use oauth need to create a secret for storing the access token. + if utils.Contains(PerUserCacheProviders, provider) && providerToken != "" { + err := m.CreateSecret(userID, provider, providerToken) + if err != nil { + return v3.Token{}, "", fmt.Errorf("unable to create secret: %s", err) + } + } + + token := &v3.Token{ + UserPrincipal: userPrincipal, + IsDerived: false, + TTLMillis: ttl, + UserID: userID, + AuthProvider: provider, + Description: description, + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + TokenKindLabel: "session", + }, + }, + } + + return m.createToken(token) +} + +func (m *Manager) UpdateToken(token *v3.Token) (*v3.Token, error) { + return m.updateToken(token) +} + +func (m *Manager) GetGroupsForTokenAuthProvider(token *v3.Token) []v3.Principal { + var groups []v3.Principal + + attribs, err := m.userAttributeLister.Get("", token.UserID) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Warnf("Problem getting userAttribute while getting groups for %v: %v", token.UserID, err) + // if err is not nil, then attribs will be. So, below code will handle it + } + + hitProvider := false + if attribs != nil { + for provider, y := range attribs.GroupPrincipals { + if provider == token.AuthProvider { + hitProvider = true + groups = append(groups, y.Items...) + } + } + } + + // fallback to legacy token groupPrincipals + if !hitProvider { + groups = append(groups, token.GroupPrincipals...) + } + + return groups +} + +func (m *Manager) IsMemberOf(token v3.Token, group v3.Principal) bool { + attribs, err := m.userAttributeLister.Get("", token.UserID) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Warnf("Problem getting userAttribute while determining group membership for %v in %v (%v): %v", token.UserID, + group.Name, group.DisplayName, err) + // if err not nil, then attribs will be nil. So, below code will handle it + } + + groups := map[string]bool{} + hitProviders := map[string]bool{} + if attribs != nil { + for provider, gps := range attribs.GroupPrincipals { + for _, principal := range gps.Items { + hitProviders[provider] = true + groups[principal.Name] = true + } + } + } + + // fallback to legacy token groupPrincipals + if _, ok := hitProviders[token.AuthProvider]; !ok { + for _, principal := range token.GroupPrincipals { + groups[principal.Name] = true + } + } + + return groups[group.Name] +} + +func (m *Manager) CreateTokenAndSetCookie(userID string, userPrincipal v3.Principal, groupPrincipals []v3.Principal, providerToken string, ttl int, description string, request *types.APIContext) error { + token, unhashedTokenKey, err := m.NewLoginToken(userID, userPrincipal, groupPrincipals, providerToken, 0, description) + if err != nil { + logrus.Errorf("Failed creating token with error: %v", err) + return httperror.NewAPIErrorLong(500, "", fmt.Sprintf("Failed creating token with error: %v", err)) + } + + isSecure := false + if request.Request.URL.Scheme == "https" { + isSecure = true + } + + tokenCookie := &http.Cookie{ + Name: CookieName, + Value: token.ObjectMeta.Name + ":" + unhashedTokenKey, + Secure: isSecure, + Path: "/", + HttpOnly: true, + } + http.SetCookie(request.Response, tokenCookie) + request.WriteResponse(http.StatusOK, nil) + + return nil +} + +// TokenStreamTransformer only filters out data for tokens that do not belong to the user +func (m *Manager) TokenStreamTransformer( + apiContext *types.APIContext, + schema *types.Schema, + data chan map[string]interface{}, + opt *types.QueryOptions) (chan map[string]interface{}, error) { + logrus.Debug("TokenStreamTransformer called") + tokenAuthValue := GetTokenAuthFromRequest(apiContext.Request) + if tokenAuthValue == "" { + // no cookie or auth header, cannot authenticate + return nil, httperror.NewAPIErrorLong(http.StatusUnauthorized, util.GetHTTPErrorCode(http.StatusUnauthorized), "[TokenStreamTransformer] failed: No valid token cookie or auth header") + } + + storedToken, code, err := m.getToken(tokenAuthValue) + if err != nil { + return nil, httperror.NewAPIErrorLong(code, http.StatusText(code), fmt.Sprintf("[TokenStreamTransformer] failed: %s", err.Error())) + } + + userID := storedToken.UserID + + return convert.Chan(data, func(data map[string]interface{}) map[string]interface{} { + labels, _ := data["labels"].(map[string]interface{}) + if labels[UserIDLabel] != userID { + return nil + } + return data + }), nil +} + +// ParseTokenTTL parses an integer representing minutes as a string and returns its duration. +func ParseTokenTTL(ttl string) (time.Duration, error) { + durString := fmt.Sprintf("%vm", ttl) + dur, err := time.ParseDuration(durString) + if err != nil { + return 0, fmt.Errorf("error parsing token ttl: %v", err) + } + return dur, nil +} + +// ClampToMaxTTL will return the duration of the provided TTL or the duration of settings.AuthTokenMaxTTLMinutes whichever is smaller. +func ClampToMaxTTL(ttl time.Duration) (time.Duration, error) { + maxTTL, err := ParseTokenTTL(settings.AuthTokenMaxTTLMinutes.Get()) + if err != nil { + return 0, fmt.Errorf("failed to parse setting '%s': %w", settings.AuthTokenMaxTTLMinutes.Name, err) + } + if maxTTL == 0 { + return ttl, nil + } + if ttl == 0 { + return maxTTL, nil + } + // return min(ttl, maxTTL) + if ttl <= maxTTL { + return ttl, nil + } + return maxTTL, nil +} + +// GetKubeconfigDefaultTokenTTLInMilliSeconds will return the default TTL for kubeconfig tokens +func GetKubeconfigDefaultTokenTTLInMilliSeconds() (*int64, error) { + defaultTokenTTL, err := ParseTokenTTL(settings.KubeconfigDefaultTokenTTLMinutes.Get()) + if err != nil { + return nil, fmt.Errorf("failed to parse setting '%s': %w", settings.KubeconfigDefaultTokenTTLMinutes.Name, err) + } + + tokenTTL, err := ClampToMaxTTL(defaultTokenTTL) + if err != nil { + return nil, fmt.Errorf("failed to validate token ttl: %w", err) + } + ttlMilli := tokenTTL.Milliseconds() + return &ttlMilli, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager_test.go new file mode 100644 index 0000000..484a572 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/manager_test.go @@ -0,0 +1,298 @@ +package tokens + +import ( + "fmt" + "net/http" + "strconv" + "testing" + "time" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/auth/tokens/hashers" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + mgmtFakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" + "k8s.io/utils/pointer" +) + +type DummyIndexer struct { + cache.Store + + hashedEnabled bool +} + +type TestCase struct { + token string + userID string + receive bool + err string +} + +var ( + token string + tokenHashed string +) + +type TestManager struct { + assert *assert.Assertions + tokenManager Manager + apiCtx *types.APIContext + testCases []TestCase +} + +// TestTokenStreamTransformer validates that the function properly filters data in websocket +func TestTokenStreamTransformer(t *testing.T) { + features.TokenHashing.Set(false) + + testManager := TestManager{ + assert: assert.New(t), + tokenManager: Manager{ + tokenIndexer: &DummyIndexer{ + Store: &cache.FakeCustomStore{}, + }, + }, + apiCtx: &types.APIContext{ + Request: &http.Request{}, + }, + } + + var err error + token, err = randomtoken.Generate() + if err != nil { + testManager.assert.FailNow(fmt.Sprintf("unable to generate token for token stream transformer test: %v", err)) + } + sha256Hasher := hashers.Sha256Hasher{} + tokenHashed, err = sha256Hasher.CreateHash(token) + if err != nil { + testManager.assert.FailNow(fmt.Sprintf("unable to hash token for token stream transformer test: %v", err)) + } + + testManager.testCases = []TestCase{ + { + token: "testname:" + token, + userID: "testuser", + receive: true, + err: "", + }, + { + token: "testname:testtoken", + userID: "testuser", + receive: false, + err: "Invalid auth token value", + }, + { + token: "wrongname:testkey", + userID: "testuser", + receive: false, + err: "422: [TokenStreamTransformer] failed: Invalid auth token value", + }, + { + token: "testname:wrongkey", + userID: "testname", + receive: false, + err: "422: [TokenStreamTransformer] failed: Invalid auth token value", + }, + { + token: "testname:" + token, + userID: "diffname", + receive: false, + err: "", + }, + { + token: "", + userID: "testuser", + receive: false, + err: "401: [TokenStreamTransformer] failed: No valid token cookie or auth header", + }, + } + + testManager.runTestCases(false) + testManager.runTestCases(true) +} + +func (t *TestManager) runTestCases(hashingEnabled bool) { + features.TokenHashing.Set(hashingEnabled) + t.tokenManager = Manager{ + tokenIndexer: &DummyIndexer{ + Store: &cache.FakeCustomStore{}, + hashedEnabled: hashingEnabled, + }, + } + for index, testCase := range t.testCases { + failureMessage := fmt.Sprintf("test case #%d failed", index) + + dataStream := make(chan map[string]interface{}, 1) + dataReceived := make(chan bool, 1) + + t.apiCtx.Request.Header = map[string][]string{"Authorization": {fmt.Sprintf("Bearer %s", testCase.token)}} + + df, err := t.tokenManager.TokenStreamTransformer(t.apiCtx, nil, dataStream, nil) + if testCase.err == "" { + t.assert.Nil(err, failureMessage) + } else { + t.assert.NotNil(err, failureMessage) + t.assert.Contains(err.Error(), testCase.err, failureMessage) + } + + ticker := time.NewTicker(1 * time.Second) + go receivedData(df, ticker.C, dataReceived) + + // test data is received when data stream contains matching userID + dataStream <- map[string]interface{}{"labels": map[string]interface{}{UserIDLabel: testCase.userID}} + t.assert.Equal(<-dataReceived, testCase.receive) + close(dataStream) + ticker.Stop() + } +} + +func receivedData(c <-chan map[string]interface{}, t <-chan time.Time, result chan<- bool) { + select { + case <-c: + result <- true + case <-t: + // assume data will not be received after 1 second timeout + result <- false + } +} + +func (d *DummyIndexer) Index(indexName string, obj interface{}) ([]interface{}, error) { + return nil, nil +} + +func (d *DummyIndexer) IndexKeys(indexName, indexKey string) ([]string, error) { + return []string{}, nil +} + +func (d *DummyIndexer) ListIndexFuncValues(indexName string) []string { + return []string{} +} + +func (d *DummyIndexer) ByIndex(indexName, indexKey string) ([]interface{}, error) { + token := &v3.Token{ + Token: token, + ObjectMeta: v1.ObjectMeta{ + Name: "testname", + }, + UserID: "testuser", + } + if d.hashedEnabled { + token.Annotations = map[string]string{TokenHashed: strconv.FormatBool(d.hashedEnabled)} + token.Token = tokenHashed + } + return []interface{}{ + token, + }, nil +} + +func (d *DummyIndexer) GetIndexers() cache.Indexers { + return nil +} + +func (d *DummyIndexer) AddIndexers(newIndexers cache.Indexers) error { + return nil +} + +func (d *DummyIndexer) SetTokenHashed(enabled bool) { + d.hashedEnabled = enabled +} + +func TestUserAttributeCreateOrUpdateSetsLastLoginTime(t *testing.T) { + createdUserAttribute := &v3.UserAttribute{} + + userID := "u-abcdef" + manager := Manager{ + userLister: &mgmtFakes.UserListerMock{ + GetFunc: func(namespace, name string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: userID, + }, + Enabled: pointer.BoolPtr(true), + }, nil + }, + }, + userAttributeLister: &mgmtFakes.UserAttributeListerMock{ + GetFunc: func(namespace, name string) (*v3.UserAttribute, error) { + return &v3.UserAttribute{}, nil + }, + }, + userAttributes: &mgmtFakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return userAttribute.DeepCopy(), nil + }, + CreateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + createdUserAttribute = userAttribute.DeepCopy() + return createdUserAttribute, nil + }, + }, + } + + groupPrincipals := []v3.Principal{} + userExtraInfo := map[string][]string{} + + loginTime := time.Now() + err := manager.UserAttributeCreateOrUpdate(userID, "provider", groupPrincipals, userExtraInfo, loginTime) + assert.NoError(t, err) + + // Make sure login time is set and truncated to seconds. + assert.Equal(t, loginTime.Truncate(time.Second), createdUserAttribute.LastLogin.Time) +} + +func TestUserAttributeCreateOrUpdateUpdatesGroups(t *testing.T) { + updatedUserAttribute := &v3.UserAttribute{} + + userID := "u-abcdef" + manager := Manager{ + userLister: &mgmtFakes.UserListerMock{ + GetFunc: func(namespace, name string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: userID, + }, + Enabled: pointer.BoolPtr(true), + }, nil + }, + }, + userAttributeLister: &mgmtFakes.UserAttributeListerMock{ + GetFunc: func(namespace, name string) (*v3.UserAttribute, error) { + return &v3.UserAttribute{ + ObjectMeta: v1.ObjectMeta{ + Name: userID, + }, + }, nil + }, + }, + userAttributes: &mgmtFakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + updatedUserAttribute = userAttribute.DeepCopy() + return updatedUserAttribute, nil + }, + CreateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return userAttribute.DeepCopy(), nil + }, + }, + } + + groupPrincipals := []v3.Principal{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "group1", + }, + }, + } + userExtraInfo := map[string][]string{} + + err := manager.UserAttributeCreateOrUpdate(userID, "provider", groupPrincipals, userExtraInfo) + assert.NoError(t, err) + + require.Len(t, updatedUserAttribute.GroupPrincipals, 1) + principals := updatedUserAttribute.GroupPrincipals["provider"] + require.NotEmpty(t, principals) + require.Len(t, principals.Items, 1) + assert.Equal(t, principals.Items[0].Name, "group1") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/purge_daemon.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/purge_daemon.go new file mode 100644 index 0000000..235ae05 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/purge_daemon.go @@ -0,0 +1,78 @@ +package tokens + +import ( + "context" + "time" + + "github.com/rancher/norman/clientbase" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" +) + +const intervalSeconds int64 = 3600 + +func StartPurgeDaemon(ctx context.Context, mgmt *config.ManagementContext) { + p := &purger{ + tokenLister: mgmt.Management.Tokens("").Controller().Lister(), + tokens: mgmt.Management.Tokens(""), + samlTokensLister: mgmt.Management.SamlTokens("").Controller().Lister(), + samlTokens: mgmt.Management.SamlTokens(""), + } + go wait.JitterUntil(p.purge, time.Duration(intervalSeconds)*time.Second, .1, true, ctx.Done()) +} + +type purger struct { + tokenLister v3.TokenLister + tokens v3.TokenInterface + samlTokens v3.SamlTokenInterface + samlTokensLister v3.SamlTokenLister +} + +func (p *purger) purge() { + allTokens, err := p.tokenLister.List("", labels.Everything()) + if err != nil { + logrus.Errorf("Error listing tokens during purge: %v", err) + } + + var count int + for _, token := range allTokens { + if IsExpired(*token) { + err = p.tokens.Delete(token.ObjectMeta.Name, &metav1.DeleteOptions{}) + if err != nil && !clientbase.IsNotFound(err) { + logrus.Errorf("Error: while deleting expired token %v: %v", err, token.ObjectMeta.Name) + continue + } + count++ + } + } + if count > 0 { + logrus.Infof("Purged %v expired tokens", count) + } + + // saml tokens store encrypted token for login request from rancher cli + samlTokens, err := p.samlTokensLister.List(namespace.GlobalNamespace, labels.Everything()) + if err != nil { + return + } + + count = 0 + for _, token := range samlTokens { + // avoid delete immediately after creation, login request might be pending + if token.CreationTimestamp.Add(15 * time.Minute).Before(time.Now()) { + err = p.samlTokens.Delete(token.ObjectMeta.Name, &metav1.DeleteOptions{}) + if err != nil && !clientbase.IsNotFound(err) { + logrus.Errorf("Error: while deleting expired token %v: %v", err, token.Name) + continue + } + count++ + } + } + if count > 0 { + logrus.Infof("Purged %v saml tokens", count) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/test_utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/test_utils.go new file mode 100644 index 0000000..04e936c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/test_utils.go @@ -0,0 +1,12 @@ +package tokens + +import ( + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" +) + +// NewMockedManager returns a token manager with mocked clients to be used in other packages' tests. +func NewMockedManager(tokensClient *fakes.TokenInterfaceMock) *Manager { // add other clients, indexers, listers as needed + return &Manager{ + tokensClient: tokensClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util.go new file mode 100644 index 0000000..6e84ada --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util.go @@ -0,0 +1,179 @@ +package tokens + +import ( + "encoding/base64" + "fmt" + "net/http" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/auth/tokens/hashers" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" +) + +func getAuthProviderName(principalID string) string { + parts := strings.Split(principalID, "://") + externalType := parts[0] + + providerParts := strings.Split(externalType, "_") + return providerParts[0] +} + +func getUserID(principalID string) string { + parts := strings.Split(principalID, "://") + return parts[1] +} + +func SplitTokenParts(tokenID string) (string, string) { + parts := strings.Split(tokenID, ":") + if len(parts) != 2 { + return parts[0], "" + } + return parts[0], parts[1] +} + +func SetTokenExpiresAt(token *v3.Token) { + if token.TTLMillis != 0 { + created := token.ObjectMeta.CreationTimestamp.Time + ttlDuration := time.Duration(token.TTLMillis) * time.Millisecond + expiresAtTime := created.Add(ttlDuration) + token.ExpiresAt = expiresAtTime.UTC().Format(time.RFC3339) + } +} + +func IsExpired(token v3.Token) bool { + if token.TTLMillis == 0 { + return false + } + + created := token.ObjectMeta.CreationTimestamp.Time + durationElapsed := time.Since(created) + + ttlDuration := time.Duration(token.TTLMillis) * time.Millisecond + return durationElapsed.Seconds() >= ttlDuration.Seconds() +} + +func GetTokenAuthFromRequest(req *http.Request) string { + var tokenAuthValue string + authHeader := req.Header.Get(AuthHeaderName) + authHeader = strings.TrimSpace(authHeader) + + if authHeader != "" { + parts := strings.SplitN(authHeader, " ", 2) + if strings.EqualFold(parts[0], AuthValuePrefix) { + if len(parts) > 1 { + tokenAuthValue = strings.TrimSpace(parts[1]) + } + } else if strings.EqualFold(parts[0], BasicAuthPrefix) { + if len(parts) > 1 { + base64Value := strings.TrimSpace(parts[1]) + data, err := base64.URLEncoding.DecodeString(base64Value) + if err != nil { + logrus.Errorf("Error %v parsing %v header", err, AuthHeaderName) + } else { + tokenAuthValue = string(data) + } + } + } + } else { + cookie, err := req.Cookie(CookieName) + if err == nil { + tokenAuthValue = cookie.Value + } + } + return tokenAuthValue +} + +func ConvertTokenResource(schema *types.Schema, token v3.Token) (map[string]interface{}, error) { + tokenData, err := convert.EncodeToMap(token) + if err != nil { + return nil, err + } + mapper := schema.Mapper + if mapper == nil { + return nil, errors.New("no schema mapper available") + } + mapper.FromInternal(tokenData) + + return tokenData, nil +} + +func GetKubeConfigToken(userName, responseType string, userMGR user.Manager, userPrincipal v3.Principal) (*v3.Token, string, error) { + // create kubeconfig expiring tokens if responseType=kubeconfig in login action vs login tokens for responseType=json + clusterID := extractClusterIDFromResponseType(responseType) + + logrus.Debugf("getKubeConfigToken: responseType %s", responseType) + name := "kubeconfig-" + userName + if clusterID != "" { + name = fmt.Sprintf("kubeconfig-%s.%s", userName, clusterID) + } + + token, tokenVal, err := userMGR.GetKubeconfigToken(clusterID, name, "Kubeconfig token", "kubeconfig", userName, userPrincipal) + if err != nil { + return nil, "", err + } + + return token, tokenVal, nil +} + +func extractClusterIDFromResponseType(responseType string) string { + responseSplit := strings.SplitN(responseType, "_", 2) + if len(responseSplit) != 2 { + return "" + } + return responseSplit[1] +} + +// Given a stored token with hashed key, check if the provided (unhashed) tokenKey matches and is valid +func VerifyToken(storedToken *v3.Token, tokenName, tokenKey string) (int, error) { + invalidAuthTokenErr := errors.New("Invalid auth token value") + if storedToken == nil || storedToken.Name != tokenName { + return http.StatusUnprocessableEntity, invalidAuthTokenErr + } + if storedToken.Annotations != nil && storedToken.Annotations[TokenHashed] == "true" { + hasher, err := hashers.GetHasherForHash(storedToken.Token) + if err != nil { + logrus.Errorf("unable to get a hasher for token with error %v", err) + return http.StatusInternalServerError, fmt.Errorf("unable to verify hash") + } + if err := hasher.VerifyHash(storedToken.Token, tokenKey); err != nil { + logrus.Errorf("VerifyHash failed with error: %v", err) + return http.StatusUnprocessableEntity, invalidAuthTokenErr + } + } else { + if storedToken.Token != tokenKey { + return http.StatusUnprocessableEntity, invalidAuthTokenErr + } + } + if IsExpired(*storedToken) { + return http.StatusGone, errors.New("must authenticate") + } + return http.StatusOK, nil +} + +// ConvertTokenKeyToHash takes a token with an un-hashed key and converts it to a hashed key +func ConvertTokenKeyToHash(token *v3.Token) error { + if !features.TokenHashing.Enabled() { + return nil + } + if token != nil && len(token.Token) > 0 { + hasher := hashers.GetHasher() + hashedToken, err := hasher.CreateHash(token.Token) + if err != nil { + logrus.Errorf("Failed to generate hash from token: %v", err) + return errors.New("failed to generate hash from token") + } + token.Token = hashedToken + if token.Annotations == nil { + token.Annotations = map[string]string{} + } + token.Annotations[TokenHashed] = "true" + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util_test.go new file mode 100644 index 0000000..8971082 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/tokens/token_util_test.go @@ -0,0 +1,215 @@ +package tokens + +import ( + "testing" + "time" + + "github.com/rancher/rancher/pkg/auth/tokens/hashers" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestVerifyToken(t *testing.T) { + tokenName := "test-token" + hashedTokenName := "hashed-test-token" + + tokenKey := "dddddddddddddddddddddddddddddddddddddddddddddddddddddd" + badTokenKey := "cccccccccccccccccccccccccccccccccccccccccccccccccccccc" + // SHA3 hash of tokenKey + hashedTokenKey := "$3:1:uFrxm43ggfw:zsN1zEFC7SvABTdR58o7yjIqfrI4cQ/HSYz3jBwwVnx5X+/ph4etGDIU9dvIYuy1IvnYUVe6a/Ar95xE+gfjhA" + invalidHashToken := "$-1:111:111" + unhashedToken := v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: tokenName, + }, + Token: tokenKey, + TTLMillis: 0, + } + hashedToken := v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: hashedTokenName, + Annotations: map[string]string{ + TokenHashed: "true", + }, + }, + Token: hashedTokenKey, + TTLMillis: 0, + } + invalidHashedToken := *hashedToken.DeepCopy() + invalidHashedToken.Token = invalidHashToken + + tests := []struct { + name string + token *v3.Token + tokenName string + tokenKey string + + wantResponseCode int + wantErr bool + }{ + { + name: "valid non-hashed token", + token: &unhashedToken, + tokenName: tokenName, + tokenKey: tokenKey, + wantResponseCode: 200, + }, + { + name: "valid hashed token", + token: &hashedToken, + tokenName: hashedTokenName, + tokenKey: tokenKey, + wantResponseCode: 200, + }, + { + name: "valid hashed token, incorrect key", + token: &hashedToken, + tokenName: hashedTokenName, + tokenKey: badTokenKey, + wantResponseCode: 422, + wantErr: true, + }, + { + name: "wrong token", + token: &unhashedToken, + tokenName: hashedTokenName, + tokenKey: tokenKey, + wantResponseCode: 422, + wantErr: true, + }, + { + name: "incorrect token key", + token: &unhashedToken, + tokenName: tokenName, + tokenKey: badTokenKey, + wantResponseCode: 422, + wantErr: true, + }, + { + name: "expired token", + token: expireToken(&unhashedToken), + tokenName: tokenName, + tokenKey: tokenKey, + wantResponseCode: 410, + wantErr: true, + }, + { + name: "expired hashed token", + token: expireToken(&hashedToken), + tokenName: hashedTokenName, + tokenKey: tokenKey, + wantResponseCode: 410, + wantErr: true, + }, + { + name: "nil token", + token: nil, + tokenName: tokenName, + tokenKey: tokenKey, + wantResponseCode: 422, + wantErr: true, + }, + { + name: "unable to retrieve hasher", + token: &invalidHashedToken, + tokenName: hashedTokenName, + tokenKey: tokenKey, + wantResponseCode: 500, + wantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + responseCode, err := VerifyToken(test.token, test.tokenName, test.tokenKey) + if test.wantErr { + require.Error(t, err) + } + require.Equal(t, test.wantResponseCode, responseCode) + }) + } +} + +func TestConvertTokenKeyToHash(t *testing.T) { + plaintextToken := "cccccccccccccccccccccccccccccccccccccccccccccccccccccc" + token := v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-token", + }, + Token: plaintextToken, + TTLMillis: 0, + } + tests := []struct { + name string + tokenHashingEnabled bool + token *v3.Token + + wantError bool + wantHashedAnnotation bool + wantHashedVal bool + }{ + { + name: "token hashing enabled", + tokenHashingEnabled: true, + token: &token, + + wantHashedAnnotation: true, + wantHashedVal: true, + }, + { + name: "token hashing disabled", + tokenHashingEnabled: false, + token: &token, + + wantHashedAnnotation: false, + wantHashedVal: false, + }, + { + name: "nil token", + tokenHashingEnabled: false, + token: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // token will be modified by the consuming function, deep copy to avoid changing the original token + features.TokenHashing.Set(test.tokenHashingEnabled) + var testToken *v3.Token + if test.token != nil { + testToken = test.token.DeepCopy() + } + err := ConvertTokenKeyToHash(testToken) + if test.wantError { + require.Error(t, err) + } + if test.wantHashedAnnotation { + require.Contains(t, testToken.Annotations, TokenHashed) + require.Equal(t, "true", testToken.Annotations[TokenHashed]) + } else { + if test.token != nil { + require.NotContains(t, testToken.Annotations, TokenHashed) + } + } + if test.wantHashedVal { + hasher, err := hashers.GetHasherForHash(testToken.Token) + require.NoError(t, err) + err = hasher.VerifyHash(testToken.Token, plaintextToken) + require.NoError(t, err) + } else { + if test.token != nil { + require.Equal(t, plaintextToken, testToken.Token) + } + } + }) + } +} + +func expireToken(token *v3.Token) *v3.Token { + newToken := token.DeepCopy() + newToken.CreationTimestamp = metav1.NewTime(time.Now().Add(-time.Second * 10)) + newToken.TTLMillis = 1 + return newToken +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label.go new file mode 100644 index 0000000..ca181c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label.go @@ -0,0 +1,227 @@ +package userretention + +import ( + "context" + "fmt" + "strconv" + "time" + + mgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/util/retry" +) + +// UserLabeler sets user retention labels based on user attributes and settings. +type UserLabeler struct { + ctx context.Context + userAttributeCache mgmtcontrollers.UserAttributeCache + userCache mgmtcontrollers.UserCache + users mgmtcontrollers.UserClient + readSettings func() (settings, error) +} + +// NewUserLabeler creates a new instance of UserLabeler. +func NewUserLabeler(ctx context.Context, wContext *wrangler.Context) *UserLabeler { + return &UserLabeler{ + ctx: ctx, + userCache: wContext.Mgmt.User().Cache(), + users: wContext.Mgmt.User(), + userAttributeCache: wContext.Mgmt.UserAttribute().Cache(), + readSettings: readSettings, + } +} + +// EnsureForAll sets retention labels for all users. +func (l *UserLabeler) EnsureForAll() error { + if l.ctx.Err() != nil { + logrus.Info("userretention: labeler: context canceled, quitting") + return nil + } + + settings, err := l.readSettings() + if err != nil { + // We don't want the caller (UserAttribute controller) to spin indefinitely. + // Log the error and return early. + logrus.Errorf("userretention: labeler: error reading settings, retention is disabled: %v", err) + return nil + } + + users, err := l.userCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("userretention: labeler: error listing users: %w", err) + } + + var processed, skipped int + + for _, user := range users { + if l.ctx.Err() != nil { + logrus.Info("userretention: labeler: context canceled, quitting") + break + } + + if user.IsSystem() { + // Note: although the default admin is not subject to retention + // we still want to check/set the last-login label for it. + continue + } + + processed++ + + attribs, err := l.userAttributeCache.Get(user.Name) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Errorf("userretention: labeler: error getting user attributes for %s: %v", user.Name, err) + skipped++ + continue + } + + if attribs == nil { + // This is possible if the user was created but hasn't logged in yet. + logrus.Debugf("userretention: labeler: no user attributes found for %s, skipping", user.Name) + skipped++ + continue + } + + l.setLabelsAndUpdateUser(settings, user, attribs) + } + + return nil +} + +// EnsureForAttributes sets retention labels for a user based on user attributes. +func (l *UserLabeler) EnsureForAttributes(attribs *mgmtv3.UserAttribute) error { + if l.ctx.Err() != nil { + logrus.Info("userretention: labeler: context canceled, quitting") + return nil + } + + settings, err := l.readSettings() + if err != nil { + // We don't want the caller (Setting controller) to spin indefinitely. + // Log the error and return early. + logrus.Errorf("userretention: labeler: error reading settings: %v, retention is disabled", err) + return nil + } + + user, err := l.userCache.Get(attribs.Name) + if err != nil { + // In a highly unlikely event of having userattribute without a corresponding user object + // we don't want the caller to spin indefinitely. There is nothing we can do about it, + // other than to log the error and move on. + if apierrors.IsNotFound(err) { + logrus.Errorf("userretention: labeler: error getting user: user not found for user attributes %s", attribs.Name) + return nil + } + + return fmt.Errorf("userretention: labeler: error getting user %s: %w", user.Name, err) + } + + l.setLabelsAndUpdateUser(settings, user, attribs) + + return nil +} + +// setLabelsAndUpdateUser sets user retention labels and updates the user. +func (l *UserLabeler) setLabelsAndUpdateUser(settings settings, user *mgmtv3.User, attribs *mgmtv3.UserAttribute) { + var userGetTry int + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + defer func() { userGetTry++ }() + + var err error + if userGetTry > 0 { // Refetch only if the first attempt to update failed. + user, err = l.users.Get(user.Name, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { // The user is no longer, move on. + return nil + } + + logrus.Errorf("userretention: labeler: error getting user %s: %v", user.Name, err) + return err + } + } + + updated := setLabels(settings, user, attribs) + if !updated { // If labels haven't changed, return early. + return nil + } + + _, err = l.users.Update(user) + if err != nil { + if apierrors.IsNotFound(err) { + logrus.Errorf("userretention: labeler: error updating user: user not found %s", user.Name) + return nil + } + + return err + } + + return nil + }) + if err != nil { + // Log the error and move on. + logrus.Errorf("userretention: labeler: error updating user %s: %v", user.Name, err) + } +} + +// setLabels sets user labels based on user retention settings and user attributes. +func setLabels(settings settings, user *mgmtv3.User, attribs *mgmtv3.UserAttribute) bool { + if user.Labels == nil { + user.Labels = map[string]string{} + } + + lastLogin := lastLoginTime(settings, attribs) + updated := ensureLabel(lastLogin, LastLoginLabelKey, user) + + var deleteAfterTime, disableAfterTime time.Time + + if settings.ShouldDelete() && !user.IsDefaultAdmin() && !lastLogin.IsZero() { + if attribs.DeleteAfter != nil { + if userDeleteAfter := attribs.DeleteAfter.Duration; userDeleteAfter > 0 { + deleteAfterTime = lastLogin.Add(userDeleteAfter) // User-specific override. + } + } else { + deleteAfterTime = lastLogin.Add(settings.deleteAfter) + } + } + updated = ensureLabel(deleteAfterTime, DeleteAfterLabelKey, user) || updated + + if settings.ShouldDisable() && !user.IsDefaultAdmin() && !lastLogin.IsZero() { + if attribs.DisableAfter != nil { + if userDisableAfter := attribs.DisableAfter.Duration; userDisableAfter > 0 { + disableAfterTime = lastLogin.Add(userDisableAfter) // User-specific override. + } + } else { + disableAfterTime = lastLogin.Add(settings.disableAfter) + } + } + return ensureLabel(disableAfterTime, DisableAfterLabelKey, user) || updated +} + +// toEpochTimeString returns the epoch time as a string. +func toEpochTimeString(t time.Time) string { + return strconv.FormatInt(t.Unix(), 10) +} + +// ensureLabel checks and sets or deletes a user retention label. +// It returns true if the label was changed. +func ensureLabel(value time.Time, labelKey string, user *mgmtv3.User) bool { + if value.IsZero() { + if _, ok := user.Labels[labelKey]; ok { + delete(user.Labels, labelKey) + return true + } + return false + } + + label := toEpochTimeString(value) + if user.Labels[labelKey] != label { + user.Labels[labelKey] = label + return true + } + + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label_test.go new file mode 100644 index 0000000..2eb2132 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/label_test.go @@ -0,0 +1,525 @@ +package userretention + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/golang/mock/gomock" + management "github.com/rancher/rancher/pkg/apis/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestEnsureForAttributes(t *testing.T) { + now := time.Now().Truncate(time.Second) + userID := "u-abcdef" + user := &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: userID}, + } + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: userID}, + LastLogin: &metav1.Time{Time: now}, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(2).DoAndReturn(func(name string) (*v3.User, error) { + return user, nil + }) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(0) + usersClient.EXPECT().Update(gomock.Any()).Times(2) + + disableAfter := time.Duration(time.Hour) + deleteAfter := time.Duration(2 * time.Hour) + labeler := &UserLabeler{ + ctx: context.Background(), + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableAfter, + deleteAfter: deleteAfter, + }, nil + }, + } + + err := labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } + + if want, got := toEpochTimeString(now), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s", want, got) + } + if want, got := toEpochTimeString(now.Add(disableAfter)), user.Labels[DisableAfterLabelKey]; want != got { + t.Errorf("Expected disable-after label %s got %s", want, got) + } + if want, got := toEpochTimeString(now.Add(deleteAfter)), user.Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("Expected delete-after label %s got %s", want, got) + } + + // The default admin should only have last-login label. + user.Username = "admin" + + err = labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, len(user.Labels); want != got { + t.Fatalf("Expected labels %d got %d", want, got) + } + + if want, got := toEpochTimeString(now), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s", want, got) + } +} + +func TestEnsureForAttributesZeroLastLogin(t *testing.T) { + userID := "u-abcdef" + user := &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + } + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(2).DoAndReturn(func(name string) (*v3.User, error) { + return user, nil + }) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(0) + usersClient.EXPECT().Update(gomock.Any()).Times(1) + + disableAfter := time.Duration(time.Hour) + deleteAfter := time.Duration(2 * time.Hour) + labeler := &UserLabeler{ + ctx: context.Background(), + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableAfter, + deleteAfter: deleteAfter, + }, nil + }, + } + + // There should be no retention labels set. + err := labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } + + if want, got := 0, len(user.Labels); want != got { + t.Errorf("Expected labels %d got %d", want, got) + } + + // All existing retention labels should be removed. + user.Labels = map[string]string{ + LastLoginLabelKey: "some-time", + DisableAfterLabelKey: "some-time", + DeleteAfterLabelKey: "some-time", + } + err = labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } + + if want, got := 0, len(user.Labels); want != got { + t.Errorf("Expected labels %d got %d", want, got) + } +} + +func TestEnsureForAttributesConflictOnUpdate(t *testing.T) { + now := time.Now().Truncate(time.Second) + userID := "u-abcdef" + user := &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: userID}, + } + unmodifiedUser := user.DeepCopy() + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{Name: userID}, + LastLogin: &metav1.Time{Time: now}, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(1).DoAndReturn(func(name string) (*v3.User, error) { + return user, nil + }) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(name string, options metav1.GetOptions) (*v3.User, error) { + return unmodifiedUser, nil + }) + var userUpdateTry int + usersClient.EXPECT().Update(gomock.Any()).Times(2).DoAndReturn(func(user *v3.User) (*v3.User, error) { + defer func() { userUpdateTry++ }() + + if userUpdateTry == 0 { + return nil, apierrors.NewConflict(schema.GroupResource{ + Group: management.GroupName, + Resource: v3.UserResourceName, + }, user.Name, fmt.Errorf("some error")) + } + + user = user.DeepCopy() + return user, nil + }) + + disableAfter := time.Duration(time.Hour) + deleteAfter := time.Duration(2 * time.Hour) + labeler := &UserLabeler{ + ctx: context.Background(), + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableAfter, + deleteAfter: deleteAfter, + }, nil + }, + } + + err := labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } + + if want, got := toEpochTimeString(now), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s", want, got) + } + if want, got := toEpochTimeString(now.Add(disableAfter)), user.Labels[DisableAfterLabelKey]; want != got { + t.Errorf("Expected disable-after label %s got %s", want, got) + } + if want, got := toEpochTimeString(now.Add(deleteAfter)), user.Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("Expected delete-after label %s got %s", want, got) + } +} + +func TestEnsureForAttributesErrorReadingSettings(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(0) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(0) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + + labeler := &UserLabeler{ + ctx: context.Background(), + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{}, fmt.Errorf("invalid settings") + }, + } + + // There should be no error returned. + err := labeler.EnsureForAttributes(attribs) + if err != nil { + t.Fatal(err) + } +} + +func TestEnsureForAll(t *testing.T) { + override := 5 * time.Hour + + now := time.Now().Truncate(time.Second) + users := []*v3.User{ + { // Regular user with no overrides. + ObjectMeta: metav1.ObjectMeta{Name: "u-abcdef"}, + }, + { // Regular user with stale labels. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-bcdefa", + Labels: map[string]string{ + LastLoginLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + DisableAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + DeleteAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + }, + }, + }, + { // Regular user with overrides to increase retention period. + ObjectMeta: metav1.ObjectMeta{Name: "u-cdefab"}, + }, + { // Regular user with overrides that disables retention. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-defabc", + Labels: map[string]string{ // Should be removed by the labeler. + DisableAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + DeleteAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + }, + }, + }, + { // Default admin. + ObjectMeta: metav1.ObjectMeta{Name: "user-phs88"}, + Username: "admin", + }, + { // Regular user, no attributes. + ObjectMeta: metav1.ObjectMeta{Name: "u-efabcd"}, + }, + { // System user. + ObjectMeta: metav1.ObjectMeta{Name: "u-ixoqm74x7r"}, + PrincipalIDs: []string{"system://c-xpqsb"}, + }, + { // Regular user, no LastLogin and previously set retention labels. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-fabcde", + Labels: map[string]string{ + LastLoginLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + DisableAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + DeleteAfterLabelKey: toEpochTimeString(now.Add(-24 * time.Hour)), + }, + }, + }, + } + attribs := []*v3.UserAttribute{ + { + ObjectMeta: metav1.ObjectMeta{Name: "u-abcdef"}, + LastLogin: &metav1.Time{Time: now}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "u-bcdefa"}, + LastLogin: &metav1.Time{Time: now}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "u-cdefab"}, + LastLogin: &metav1.Time{Time: now}, + DisableAfter: &metav1.Duration{Duration: override}, + DeleteAfter: &metav1.Duration{Duration: override}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "u-defabc"}, + LastLogin: &metav1.Time{Time: now}, + DisableAfter: &metav1.Duration{Duration: 0}, + DeleteAfter: &metav1.Duration{Duration: 0}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "user-phs88"}, + LastLogin: &metav1.Time{Time: now}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "u-fabcde"}, + }, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(0) + usersCacheClient.EXPECT().List(gomock.Any()).Times(1).DoAndReturn(func(selector labels.Selector) ([]*v3.User, error) { + return users, nil + }) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Update(gomock.Any()).AnyTimes() + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).AnyTimes().DoAndReturn(func(name string) (*v3.UserAttribute, error) { + for _, attr := range attribs { + if attr.Name == name { + return attr.DeepCopy(), nil + } + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + + disableAfter := time.Duration(time.Hour) + deleteAfter := time.Duration(2 * time.Hour) + labeler := &UserLabeler{ + ctx: context.Background(), + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableAfter, + deleteAfter: deleteAfter, + }, nil + }, + } + + err := labeler.EnsureForAll() + if err != nil { + t.Fatal(err) + } + + var i int + + // The first two users should have identical labels. + for i = 0; i < 2; i++ { + if want, got := toEpochTimeString(now), users[i].Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s for user %s", want, got, users[i].Name) + } + if want, got := toEpochTimeString(now.Add(disableAfter)), users[i].Labels[DisableAfterLabelKey]; want != got { + t.Errorf("Expected disable-after label %s got %s for user %s", want, got, users[i].Name) + } + if want, got := toEpochTimeString(now.Add(deleteAfter)), users[i].Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("Expected delete-after label %s got %s for user %s", want, got, users[i].Name) + } + } + + // The third should have increased retention period. + i = 2 + if want, got := toEpochTimeString(now), users[2].Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s for user %s", want, got, users[i].Name) + } + if want, got := toEpochTimeString(now.Add(override)), users[2].Labels[DisableAfterLabelKey]; want != got { + t.Errorf("Expected disable-after label %s got %s for user %s", want, got, users[i].Name) + } + if want, got := toEpochTimeString(now.Add(override)), users[2].Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("Expected delete-after label %s got %s for user %s", want, got, users[i].Name) + } + + // The fourth and fifth should only have last-login label and no retention labels due to overrides. + for i = 3; i < 5; i++ { + if want, got := 1, len(users[i].Labels); want != got { + t.Errorf("Expected labels %d got %d for user %s", want, got, users[i].Name) + } + if want, got := toEpochTimeString(now), users[i].Labels[LastLoginLabelKey]; want != got { + t.Errorf("Expected last-login label %s got %s for user %s", want, got, users[i].Name) + } + } + + // The last three should have no labels. + for i = 5; i < 8; i++ { + if want, got := 0, len(users[i].Labels); want != got { + t.Errorf("Expected labels %d got %d for user %s", want, got, users[i].Name) + } + } +} + +func TestEnsureForAllContextCancelled(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() // Cancel the context right away. + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(0) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).Times(0) + + labeler := &UserLabeler{ + ctx: ctx, + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + } + + err := labeler.EnsureForAll() + if err != nil { + t.Fatal(err) + } +} + +func TestEnsureForAllContextCancelledInFlight(t *testing.T) { + users := []*v3.User{ + { // Regular user with no overrides. + ObjectMeta: metav1.ObjectMeta{Name: "u-abcdef"}, + }, + } + + ctx, cancel := context.WithCancel(context.Background()) + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(0) + usersCacheClient.EXPECT().List(gomock.Any()).AnyTimes().DoAndReturn(func(selector labels.Selector) ([]*v3.User, error) { + cancel() // Cancel the context before processing individual users. + return users, nil + }) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).Times(0) + + disableAfter := time.Duration(time.Hour) + deleteAfter := time.Duration(2 * time.Hour) + labeler := &UserLabeler{ + ctx: ctx, + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableAfter, + deleteAfter: deleteAfter, + }, nil + }, + } + + err := labeler.EnsureForAll() + if err != nil { + t.Fatal(err) + } +} + +func TestEnsureForAllErrorReadingSettings(t *testing.T) { + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().Get(gomock.Any()).Times(0) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).Times(0) + + labeler := &UserLabeler{ + ctx: context.Background(), + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{}, fmt.Errorf("invalid settings") + }, + } + + err := labeler.EnsureForAll() + if err != nil { + t.Fatal(err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention.go new file mode 100644 index 0000000..8870a19 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention.go @@ -0,0 +1,248 @@ +package userretention + +import ( + "context" + "fmt" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/util/retry" + "k8s.io/utils/pointer" +) + +const ( + LastLoginLabelKey = "cattle.io/last-login" + DisableAfterLabelKey = "cattle.io/disable-after" + DeleteAfterLabelKey = "cattle.io/delete-after" +) + +// Retention is the user retention process that disables or deletes inactive users +// based on the last time the user was seen (logged in) that is stored as a user attribute. +// Note: Disabling and deleting are independent of each other and are driven by the +// corresponding settings disableAfter and deleteAfter. +// retention can be configured to either +// - do nothing, which is the default (disableAfter == deleteAfter == 0) +// - only disable users (disableAfter > 0 && deleteAfter == 0) +// - progressively disable and delete users (0 < disableAfter < deleteAfter) +// - only delete users (disableAfter == 0 && deleteAfter > 0 or 0 < deleteAfter < disableAfter) +type Retention struct { + userAttributeCache mgmtcontrollers.UserAttributeCache + userCache mgmtcontrollers.UserCache + users mgmtcontrollers.UserClient + readSettings func() (settings, error) +} + +// New creates a new instance of Retention. +func New(wContext *wrangler.Context) *Retention { + return &Retention{ + userCache: wContext.Mgmt.User().Cache(), + users: wContext.Mgmt.User(), + userAttributeCache: wContext.Mgmt.UserAttribute().Cache(), + readSettings: readSettings, + } +} + +// Run the user retention process. +func (r *Retention) Run(ctx context.Context) error { + if ctx.Err() != nil { + logrus.Info("userretention: context canceled, quitting") + return nil + } + + startedAt := time.Now() + + settings, err := r.readSettings() + if err != nil { + return fmt.Errorf("error reading settings: %w, retention is disabled", err) + } + + if !settings.ShouldDisable() && !settings.ShouldDelete() { + logrus.Info("userretention: nothing to do, neither DisableInactiveUserAfter nor DeleteInactiveUserAfter is set") + return nil + } + + logrus.Infof( + "userretention: started (disable-inactive-user-after %s, delete-inactive-user-after %s, user-last-login-default %s, user-retention-dry-run %t)", + settings.disableAfter, settings.deleteAfter, settings.FormatDefaultLastLogin(), settings.dryRun, + ) + + users, err := r.userCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("error listing users: %w", err) + } + + var processed, skipped, disabled, deleted, errCount int + now := time.Now() + + defer func() { + logrus.Infof( + "userretention: finished in %v seconds (processed %d, skipped %d, disabled %d, deleted %d, errors %d)", + time.Since(startedAt).Seconds(), + processed, skipped, disabled, deleted, errCount, + ) + }() + + for _, user := range users { + if ctx.Err() != nil { + logrus.Info("userretention: context canceled, quitting") + break + } + + if !isSubjectToRetention(user) { + continue + } + + processed++ + + logrus.Debugf("userretention: processing user %s", user.Name) + + attribs, err := r.userAttributeCache.Get(user.Name) + if err != nil && !apierrors.IsNotFound(err) { + logrus.Errorf("userretention: error getting user attributes for %s: %v", user.Name, err) + errCount++ + skipped++ + continue + } + + if attribs == nil { + // This is possible if the user was created but haven't logged in yet. + logrus.Debugf("userretention: no user attributes found for %s, skipping", user.Name) + skipped++ + continue + } + + var ( + userDeleteAfter, userDisableAfter time.Duration + disableUser bool + ) + + lastLogin := lastLoginTime(settings, attribs) + if !lastLogin.IsZero() { + deleteAfterTime := lastLogin.Add(settings.deleteAfter) + if attribs.DeleteAfter != nil { // Apply user-specific override. + if userDeleteAfter = attribs.DeleteAfter.Duration; userDeleteAfter <= 0 { + deleteAfterTime = time.Time{} // The user shouldn't be considered for deletion. + } else { + deleteAfterTime = lastLogin.Add(userDeleteAfter) + } + } + deleteAfterTime = deleteAfterTime.Truncate(time.Second) + + disableAfterTime := lastLogin.Add(settings.disableAfter) + if attribs.DisableAfter != nil { // Apply user-specific override. + if userDisableAfter = attribs.DisableAfter.Duration; userDisableAfter <= 0 { + disableAfterTime = time.Time{} // The user shouldn't be considered for being disabled. + } else { + disableAfterTime = lastLogin.Add(userDisableAfter) + } + } + disableAfterTime = disableAfterTime.Truncate(time.Second) + + if attribs.DeleteAfter != nil && userDeleteAfter == 0 && + attribs.DisableAfter != nil && userDisableAfter == 0 { + skipped++ // This is to keep the counter updated. + } + + if settings.ShouldDelete() && !deleteAfterTime.IsZero() && + now.After(deleteAfterTime) { + logrus.Infof("userretention: deleting user %s", user.Name) + + if !settings.dryRun { + err := r.users.Delete(user.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + logrus.Errorf("userretention: error deleting user %s: %v", user.Name, err) + errCount++ + continue + } + } + + deleted++ + continue + + } + + if settings.ShouldDisable() && !disableAfterTime.IsZero() && + now.After(disableAfterTime) && pointer.BoolDeref(user.Enabled, true) { + logrus.Infof("userretention: disabling user %s", user.Name) + // Flag the needed update but don't apply it as we may need to update retention labels too. + disableUser = true + disabled++ + } + } + + var userGetTry int + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + defer func() { userGetTry++ }() + + var err error + + if userGetTry > 0 { // Refetch only if the first attempt to update failed. + user, err = r.users.Get(user.Name, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { // The user is no longer, move on. + return nil + } + + logrus.Errorf("userretention: error getting user %s: %v", user.Name, err) + return err + } + } + + if settings.dryRun { + return nil + } + + if disableUser { + user.Enabled = pointer.Bool(false) + } + + // Update the retention labels if necessary. + labelsUpdated := setLabels(settings, user, attribs) + + // No user updates; return early. + if !labelsUpdated && !disableUser { + return nil + } + + if _, err = r.users.Update(user); err != nil { + if apierrors.IsNotFound(err) { + logrus.Errorf("userretention: error updating user: user not found %s", user.Name) + return nil + } + + return err + } + + return nil + }) + if err != nil { + // Log the error and move on. + logrus.Errorf("userretention: error updating user %s: %v", user.Name, err) + errCount++ + } + } + + return nil +} + +func isSubjectToRetention(user *v3.User) bool { + return !user.IsDefaultAdmin() && !user.IsSystem() +} + +func lastLoginTime(settings settings, attribs *v3.UserAttribute) time.Time { + if attribs.LastLogin != nil && !attribs.LastLogin.Time.IsZero() { + return attribs.LastLogin.Time + } + + if !settings.defaultLastLogin.IsZero() { + return settings.defaultLastLogin + } + + return time.Time{} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention_test.go new file mode 100644 index 0000000..f1e4ad7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/retention_test.go @@ -0,0 +1,562 @@ +package userretention + +import ( + "context" + "fmt" + "reflect" + "sort" + "strconv" + "strings" + "testing" + "time" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/utils/pointer" +) + +func TestLastLoginTime(t *testing.T) { + now := time.Now() + zeroLastLogin := &metav1.Time{Time: time.Time{}} + + tests := []struct { + desc string + lastLoginDefault time.Time + lastLogin *metav1.Time + want time.Time + }{ + { + desc: "missing last login", + }, + { + desc: "zero last login", + lastLogin: zeroLastLogin, + }, + { + desc: "missing last login with default", + lastLoginDefault: now, + want: now, + }, + { + desc: "zero last login with default", + lastLogin: zeroLastLogin, + lastLoginDefault: now, + want: now, + }, + { + desc: "last login is set with no default", + lastLogin: &metav1.Time{Time: now}, + want: now, + }, + { + desc: "last login is set with default", + lastLogin: &metav1.Time{Time: now}, + lastLoginDefault: now.Add(-time.Hour), + want: now, + }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + settings := settings{defaultLastLogin: test.lastLoginDefault} + attribs := &v3.UserAttribute{LastLogin: test.lastLogin} + if want, got := test.want, lastLoginTime(settings, attribs); want != got { + t.Errorf("Expected last login time %v got %v", want, got) + } + }) + } +} + +func TestRetentionIsDisabledByDefault(t *testing.T) { + defer func() { + if err := recover(); err != nil { + t.Fatal("Unexpected panic") + } + }() + + r := Retention{ + readSettings: readSettings, + } + + err := r.Run(context.Background()) + if err != nil { + t.Fatal(err) + } +} + +func TestRetentionNormalRun(t *testing.T) { + now := time.Now().Truncate(time.Second) + disableInactiveUserAfter := 55 * time.Minute + deleteInactiveUserAfter := 115 * time.Minute + lastLoginDefault := now.Add(-time.Hour) + + userAttributes := map[string]*v3.UserAttribute{ + "u-cx7gc": { + // LastLogin is missing. + }, + "u-ckrl4grxg5": { + LastLogin: &metav1.Time{Time: now.Add(-time.Hour)}, + }, + "u-mo773yttt4": { + LastLogin: &metav1.Time{Time: now.Add(-time.Hour)}, + }, + "u-yypnjwjmkq": { + LastLogin: &metav1.Time{Time: now.Add(-2 * time.Hour)}, + }, + "u-evhs6gb54u": { + LastLogin: &metav1.Time{Time: now.Add(-2 * time.Hour)}, + DisableAfter: &metav1.Duration{Duration: 4 * time.Hour}, + DeleteAfter: &metav1.Duration{Duration: 5 * time.Hour}, + }, + "u-f5ugvctlrk": { + LastLogin: &metav1.Time{Time: now.Add(-10 * time.Hour)}, + DisableAfter: &metav1.Duration{Duration: 0}, + DeleteAfter: &metav1.Duration{Duration: 0}, + }, + } + + users := map[string]*v3.User{ + "user-phs88": { // Default admin. + ObjectMeta: metav1.ObjectMeta{ + Name: "user-phs88", + }, + PrincipalIDs: []string{"local://user-phs88", "activedirectory_user://CN=testuser1,CN=Users,DC=qa,DC=rancher,DC=space"}, + Username: "admin", + Enabled: pointer.Bool(true), + }, + "u-cx7gc": { // Local user. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-cx7gc", + }, + PrincipalIDs: []string{"local://u-cx7gc"}, + Enabled: pointer.Bool(true), + }, + "u-ckrl4grxg5": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-ckrl4grxg5", + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser2,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-ckrl4grxg5"}, + Enabled: pointer.Bool(true), + }, + "u-mo773yttt4": { // Already disabled. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-mo773yttt4", + Labels: map[string]string{ + LastLoginLabelKey: toEpochTimeString(userAttributes["u-mo773yttt4"].LastLogin.Time), + DisableAfterLabelKey: toEpochTimeString(userAttributes["u-mo773yttt4"].LastLogin.Add(disableInactiveUserAfter)), + DeleteAfterLabelKey: toEpochTimeString(userAttributes["u-mo773yttt4"].LastLogin.Add(deleteInactiveUserAfter)), + }, + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser3,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-mo773yttt4"}, + Enabled: pointer.Bool(false), + }, + "u-yypnjwjmkq": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-yypnjwjmkq", + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser4,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-yypnjwjmkq"}, + Enabled: pointer.Bool(true), + }, + "u-evhs6gb54u": { // A user with disable and delete overrides. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-evhs6gb54u", + Labels: map[string]string{ + LastLoginLabelKey: toEpochTimeString(userAttributes["u-evhs6gb54u"].LastLogin.Time), + DisableAfterLabelKey: toEpochTimeString(userAttributes["u-evhs6gb54u"].LastLogin.Add(userAttributes["u-evhs6gb54u"].DisableAfter.Duration)), // Should stay intact after the retention run. + DeleteAfterLabelKey: toEpochTimeString(userAttributes["u-evhs6gb54u"].LastLogin.Add(userAttributes["u-evhs6gb54u"].DeleteAfter.Duration)), // Should stay intact after the retention run. + }, + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser5,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-evhs6gb54u"}, + Enabled: pointer.Bool(true), + }, + "u-f5ugvctlrk": { // A user that should be retained indefinitely. + ObjectMeta: metav1.ObjectMeta{ + Name: "u-f5ugvctlrk", + Labels: map[string]string{ + DisableAfterLabelKey: toEpochTimeString(now), // Should be removed after the retention run. + DeleteAfterLabelKey: toEpochTimeString(now), // Should be removed after the retention run. + }, + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser6,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-f5ugvctlrk"}, + Enabled: pointer.Bool(true), + }, + } + var ( + deleted []string + updated []*v3.User + ) + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().List(gomock.Any()).Times(1).DoAndReturn(func(selector labels.Selector) ([]*v3.User, error) { + result := make([]*v3.User, 0, len(users)) + for _, user := range users { + result = append(result, user.DeepCopy()) + } + return result, nil + }) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.User, error) { + if user, ok := users[name]; ok { + return user.DeepCopy(), nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + usersClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(user *v3.User) (*v3.User, error) { + u := user.DeepCopy() + updated = append(updated, u) + return u, nil + }) + usersClient.EXPECT().Delete(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, options *metav1.DeleteOptions) error { + deleted = append(deleted, name) + return nil + }) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).AnyTimes().DoAndReturn(func(name string) (*v3.UserAttribute, error) { + if attr, ok := userAttributes[name]; ok { + return attr, nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + + retention := Retention{ + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableInactiveUserAfter, + deleteAfter: deleteInactiveUserAfter, + defaultLastLogin: lastLoginDefault, + }, nil + }, + } + + err := retention.Run(context.Background()) + if err != nil { + t.Fatal(err) + } + + sort.Strings(deleted) + if want, got := []string{"u-yypnjwjmkq"}, deleted; !reflect.DeepEqual(want, got) { + t.Errorf("Expected deleted\n%v\ngot\n%v", want, got) + } + + if want, got := 3, len(updated); want != got { + t.Errorf("Expected %d updated users got %d", want, got) + } + + for _, user := range updated { + switch user.Name { + case "u-f5ugvctlrk": + // Make sure retention labels were removed because of the overrides. + if want, got := 1, len(user.Labels); want != got { + t.Errorf("[user %s] Expected %d labels got %d", user.Name, want, got) + } + if want, got := strconv.FormatInt(userAttributes[user.Name].LastLogin.Unix(), 10), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("[user %s] Expected last-login label %s got %s", user.Name, want, got) + } + case "u-cx7gc": + if want, got := false, pointer.BoolDeref(user.Enabled, true); want != got { + t.Errorf("[user %s] Expected enabled %t got %t", user.Name, want, got) + } + if want, got := 3, len(user.Labels); want != got { + t.Fatalf("[user %s] Expected %d labels got %d", user.Name, want, got) + } + if want, got := toEpochTimeString(lastLoginDefault.Add(disableInactiveUserAfter)), user.Labels[DisableAfterLabelKey]; want != got { + t.Errorf("[user %s] Expected disable-after label %s got %s", user.Name, want, got) + } + if want, got := toEpochTimeString(lastLoginDefault.Add(deleteInactiveUserAfter)), user.Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("[user %s] Expected delete-after label %s got %s", user.Name, want, got) + } + if want, got := toEpochTimeString(lastLoginDefault), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("[user %s] Expected last-login label %s got %s", user.Name, want, got) + } + case "u-ckrl4grxg5": + if want, got := false, pointer.BoolDeref(user.Enabled, true); want != got { + t.Errorf("[user %s] Expected enabled %t got %t", user.Name, want, got) + } + if want, got := 3, len(user.Labels); want != got { + t.Fatalf("[user %s] Expected %d labels got %d", user.Name, want, got) + } + if want, got := toEpochTimeString(now.Add(-time.Hour+disableInactiveUserAfter)), user.Labels[DisableAfterLabelKey]; want != got { + t.Errorf("[user %s] Expected disable-after label %s got %s", user.Name, want, got) + } + if want, got := toEpochTimeString(now.Add(-time.Hour+deleteInactiveUserAfter)), user.Labels[DeleteAfterLabelKey]; want != got { + t.Errorf("[user %s] Expected delete-after label %s got %s", user.Name, want, got) + } + if want, got := toEpochTimeString(userAttributes[user.Name].LastLogin.Time), user.Labels[LastLoginLabelKey]; want != got { + t.Errorf("[user %s] Expected last-login label %s got %s", user.Name, want, got) + } + default: + t.Errorf("[user %s] Unexpected update", user.Name) + } + } +} + +func TestRetentionDryRun(t *testing.T) { + users := map[string]*v3.User{ + "u-ckrl4grxg5": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-ckrl4grxg5", + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser2,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-ckrl4grxg5"}, + Enabled: pointer.Bool(true), + }, + "u-mo773yttt4": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-mo773yttt4", + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser3,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-mo773yttt4"}, + Enabled: pointer.Bool(true), + }, + } + userAttributes := map[string]*v3.UserAttribute{ + "u-ckrl4grxg5": { + LastLogin: &metav1.Time{Time: time.Now().Add(-time.Hour)}, + }, + "u-mo773yttt4": { + LastLogin: &metav1.Time{Time: time.Now().Add(-2 * time.Hour)}, + }, + } + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().List(gomock.Any()).Times(1).DoAndReturn(func(selector labels.Selector) ([]*v3.User, error) { + result := make([]*v3.User, 0, len(users)) + for _, user := range users { + result = append(result, user) + } + return result, nil + }) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.User, error) { + if user, ok := users[name]; ok { + return user, nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + usersClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).AnyTimes().DoAndReturn(func(name string) (*v3.UserAttribute, error) { + if attr, ok := userAttributes[name]; ok { + return attr, nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + + retention := Retention{ + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: 55 * time.Minute, + deleteAfter: 115 * time.Minute, + dryRun: true, + }, nil + }, + } + + err := retention.Run(context.Background()) + if err != nil { + t.Fatal(err) + } + + for id, user := range users { + if want, got := true, pointer.BoolDeref(user.Enabled, false); want != got { + t.Errorf("Expected Enabled for user %s %t got %t", id, want, got) + } + if want, got := 0, len(user.Labels); want != got { + t.Errorf("Expected labels for user %s %d got %d", id, want, got) + } + } +} + +func TestRetentionRunNoLastLoginDefault(t *testing.T) { + now := time.Now().Truncate(time.Second) + disableInactiveUserAfter := 55 * time.Minute + deleteInactiveUserAfter := 115 * time.Minute + + userAttributes := map[string]*v3.UserAttribute{ + "u-cx7gc": {}, + "u-ckrl4grxg5": {}, + } + + users := map[string]*v3.User{ + "u-cx7gc": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-cx7gc", + }, + PrincipalIDs: []string{"local://u-cx7gc"}, + }, + "u-ckrl4grxg5": { + ObjectMeta: metav1.ObjectMeta{ + Name: "u-ckrl4grxg5", + Labels: map[string]string{ + LastLoginLabelKey: toEpochTimeString(now), + DisableAfterLabelKey: toEpochTimeString(now.Add(disableInactiveUserAfter)), + DeleteAfterLabelKey: toEpochTimeString(now.Add(deleteInactiveUserAfter)), + }, + }, + PrincipalIDs: []string{"activedirectory_user://CN=testuser2,CN=Users,DC=qa,DC=rancher,DC=space", "local://u-ckrl4grxg5"}, + }, + } + var ( + deleted []string + updated []*v3.User + ) + + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().List(gomock.Any()).Times(1).DoAndReturn(func(selector labels.Selector) ([]*v3.User, error) { + result := make([]*v3.User, 0, len(users)) + for _, user := range users { + result = append(result, user.DeepCopy()) + } + return result, nil + }) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.User, error) { + if user, ok := users[name]; ok { + return user.DeepCopy(), nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + usersClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(user *v3.User) (*v3.User, error) { + u := user.DeepCopy() + updated = append(updated, u) + return u, nil + }) + usersClient.EXPECT().Delete(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, options *metav1.DeleteOptions) error { + deleted = append(deleted, name) + return nil + }) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).AnyTimes().DoAndReturn(func(name string) (*v3.UserAttribute, error) { + if attr, ok := userAttributes[name]; ok { + return attr, nil + } + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + }) + + retention := Retention{ + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: disableInactiveUserAfter, + deleteAfter: deleteInactiveUserAfter, + }, nil + }, + } + + err := retention.Run(context.Background()) + if err != nil { + t.Fatal(err) + } + + if want, got := 0, len(deleted); want != got { + t.Errorf("Expected %d deleted users got %d", want, got) + } + + if want, got := 1, len(updated); want != got { + t.Errorf("Expected %d updated users got %d", want, got) + } + + for _, user := range updated { + switch user.Name { + case "u-cx7gc", "u-ckrl4grxg5": + if want, got := 0, len(user.Labels); want != got { + t.Fatalf("[user %s] Expected %d labels got %d", user.Name, want, got) + } + default: + t.Errorf("[user %s] Unexpected update", user.Name) + } + } +} + +func TestRetentionRunErrorReadingSettings(t *testing.T) { + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(0) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + usersClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).Times(0) + + readSettingsErr := fmt.Errorf("error reading settings") + retention := Retention{ + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{}, readSettingsErr + }, + } + + err := retention.Run(context.Background()) + if err == nil { + t.Fatal("Expected error got nil") + } + + if !strings.Contains(err.Error(), readSettingsErr.Error()) { + t.Error("Unexpected error message") + } +} + +func TestRetentionRunContextCancelled(t *testing.T) { + ctrl := gomock.NewController(t) + + usersCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.User](ctrl) + usersCacheClient.EXPECT().List(gomock.Any()).Times(0) + + usersClient := fake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + usersClient.EXPECT().Get(gomock.Any(), gomock.Any()).Times(0) + usersClient.EXPECT().Update(gomock.Any()).Times(0) + usersClient.EXPECT().Delete(gomock.Any(), gomock.Any()).Times(0) + + userAttributeCacheClient := fake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributeCacheClient.EXPECT().Get(gomock.Any()).Times(0) + + retention := Retention{ + userAttributeCache: userAttributeCacheClient, + userCache: usersCacheClient, + users: usersClient, + readSettings: func() (settings, error) { + return settings{ + disableAfter: 55 * time.Minute, + deleteAfter: 115 * time.Minute, + }, nil + }, + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err := retention.Run(ctx) + if err != nil { + t.Fatal(err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings.go new file mode 100644 index 0000000..072df2e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings.go @@ -0,0 +1,69 @@ +package userretention + +import ( + "fmt" + "strings" + "time" + + appsettings "github.com/rancher/rancher/pkg/settings" +) + +// settings control user retention process. +type settings struct { + disableAfter time.Duration + deleteAfter time.Duration + defaultLastLogin time.Time + dryRun bool +} + +// ShouldDisable returns true if the user retention process should disable users. +func (s *settings) ShouldDisable() bool { + return s.disableAfter != 0 +} + +// ShouldDelete returns true if the user retention process should delete users. +func (s *settings) ShouldDelete() bool { + return s.deleteAfter != 0 +} + +// FormatDefaultLastLogin returns formatted value of the default last login. +func (s *settings) FormatDefaultLastLogin() string { + if s.defaultLastLogin.IsZero() { + return "" + } + + return s.defaultLastLogin.Format(time.RFC3339) +} + +// readSettings reads and parses user retention settings. +func readSettings() (settings, error) { + var ( + err error + parsed settings + ) + + if value := appsettings.DisableInactiveUserAfter.Get(); value != "" { + parsed.disableAfter, err = time.ParseDuration(value) + if err != nil { + return settings{}, fmt.Errorf("%s: %w", appsettings.DisableInactiveUserAfter.Name, err) + } + } + + if value := appsettings.DeleteInactiveUserAfter.Get(); value != "" { + parsed.deleteAfter, err = time.ParseDuration(value) + if err != nil { + return settings{}, fmt.Errorf("%s: %w", appsettings.DeleteInactiveUserAfter.Name, err) + } + } + + if value := appsettings.UserLastLoginDefault.Get(); value != "" { + parsed.defaultLastLogin, err = time.Parse(time.RFC3339, value) + if err != nil { + return settings{}, fmt.Errorf("%s: %w", appsettings.UserLastLoginDefault.Name, err) + } + } + + parsed.dryRun = strings.EqualFold(appsettings.UserRetentionDryRun.Get(), "true") + + return parsed, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings_test.go new file mode 100644 index 0000000..caba52b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/userretention/settings_test.go @@ -0,0 +1,210 @@ +package userretention + +import ( + "reflect" + "testing" + "time" + + appsettings "github.com/rancher/rancher/pkg/settings" +) + +func TestSettingsShouldDisable(t *testing.T) { + tests := []struct { + disableAfter time.Duration + shouldDisable bool + }{ + {}, + { + disableAfter: time.Hour, + shouldDisable: true, + }, + } + + for _, tt := range tests { + t.Run(tt.disableAfter.String(), func(t *testing.T) { + settings := settings{disableAfter: tt.disableAfter} + + if want, got := tt.shouldDisable, settings.ShouldDisable(); want != got { + t.Errorf("Expected %t got %t", want, got) + } + }) + } +} + +func TestSettingsShouldDelete(t *testing.T) { + tests := []struct { + deleteAfter time.Duration + shouldDelete bool + }{ + {}, + { + deleteAfter: time.Hour, + shouldDelete: true, + }, + } + + for _, tt := range tests { + t.Run(tt.deleteAfter.String(), func(t *testing.T) { + settings := settings{deleteAfter: tt.deleteAfter} + + if want, got := tt.shouldDelete, settings.ShouldDelete(); want != got { + t.Errorf("Expected %t got %t", want, got) + } + }) + } +} + +func TestSettingsFormatDefaultLastLogin(t *testing.T) { + now := time.Now() + tests := []struct { + defaultLastLogin time.Time + formatted string + }{ + {}, + { + defaultLastLogin: now, + formatted: now.Format(time.RFC3339), + }, + } + + for _, tt := range tests { + t.Run(tt.defaultLastLogin.String(), func(t *testing.T) { + settings := settings{defaultLastLogin: tt.defaultLastLogin} + + if want, got := tt.formatted, settings.FormatDefaultLastLogin(); want != got { + t.Errorf("Expected %s got %s", want, got) + } + }) + } +} + +func TestReadSettings(t *testing.T) { + tests := []struct { + desc string + disableInactiveUserAfter string + deleteInactiveUserAfter string + userLastLoginDefault string + userRetentionDryRun string + parsed settings + shouldErr bool + }{ + { + desc: "all settings are empty", + }, + { + desc: "disableInactiveUserAfter is 0", + disableInactiveUserAfter: "0", + }, + { + desc: "disableInactiveUserAfter is set", + disableInactiveUserAfter: "1h30m30s", + parsed: settings{ + disableAfter: time.Hour + 30*time.Minute + 30*time.Second, + }, + }, + { + desc: "deleteInactiveUserAfter is 0", + deleteInactiveUserAfter: "0", + }, + { + desc: "deleteInactiveUserAfter is set", + deleteInactiveUserAfter: "1h30m30s", + parsed: settings{ + deleteAfter: time.Hour + 30*time.Minute + 30*time.Second, + }, + }, + { + desc: "userLastLoginDefault is set", + userLastLoginDefault: "2024-03-15T12:00:00Z", + parsed: settings{ + defaultLastLogin: time.Date(2024, 3, 15, 12, 0, 0, 0, time.UTC), + }, + }, + { + desc: "userRetentionDryRun is true", + userRetentionDryRun: "true", + parsed: settings{ + dryRun: true, + }, + }, + { + desc: "userRetentionDryRun is True", + userRetentionDryRun: "true", + parsed: settings{ + dryRun: true, + }, + }, + { + desc: "userRetentionDryRun is false", + userRetentionDryRun: "false", + }, + { + desc: "userRetentionDryRun is neither true nor false", + userRetentionDryRun: "foo", + }, + { + desc: "all settings are set", + disableInactiveUserAfter: "1h30m30s", + deleteInactiveUserAfter: "1h30m30s", + userLastLoginDefault: "2024-03-15T12:00:00Z", + userRetentionDryRun: "true", + parsed: settings{ + disableAfter: time.Hour + 30*time.Minute + 30*time.Second, + deleteAfter: time.Hour + 30*time.Minute + 30*time.Second, + defaultLastLogin: time.Date(2024, 3, 15, 12, 0, 0, 0, time.UTC), + dryRun: true, + }, + }, + { + desc: "disableInactiveUserAfter is invalid", + disableInactiveUserAfter: "foo", + shouldErr: true, + }, + { + desc: "deleteInactiveUserAfter is invalid", + deleteInactiveUserAfter: "foo", + shouldErr: true, + }, + { + desc: "userLastLoginDefault is invalid", + userLastLoginDefault: "foo", + shouldErr: true, + }, + } + + for _, tt := range tests { + // Note: subtests can't be run in parralel because we're modifying global settings. + t.Run(tt.desc, func(t *testing.T) { + // Preserve the original settings. + disableInactiveUserAfter := appsettings.DisableInactiveUserAfter.Get() + deleteInactiveUserAfter := appsettings.DeleteInactiveUserAfter.Get() + userLastLoginDefault := appsettings.UserLastLoginDefault.Get() + userRetentionDryRun := appsettings.UserRetentionDryRun.Get() + defer func() { + // Restore the settings. + appsettings.DisableInactiveUserAfter.Set(disableInactiveUserAfter) + appsettings.DeleteInactiveUserAfter.Set(deleteInactiveUserAfter) + appsettings.UserLastLoginDefault.Set(userLastLoginDefault) + appsettings.UserRetentionDryRun.Set(userRetentionDryRun) + }() + + appsettings.DisableInactiveUserAfter.Set(tt.disableInactiveUserAfter) + appsettings.DeleteInactiveUserAfter.Set(tt.deleteInactiveUserAfter) + appsettings.UserLastLoginDefault.Set(tt.userLastLoginDefault) + appsettings.UserRetentionDryRun.Set(tt.userRetentionDryRun) + + parsed, err := readSettings() + if err != nil { + if !tt.shouldErr { + t.Errorf("Unexpected error: %v", err) + return + } + // In the case of an expected error all the retention settings should have zero values. + } + + if want, got := tt.parsed, parsed; !reflect.DeepEqual(want, got) { + t.Errorf("Expected \n%+v\ngot\n%+v", want, got) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/util/common_util.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/util/common_util.go new file mode 100644 index 0000000..cdd9742 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/util/common_util.go @@ -0,0 +1,61 @@ +package util + +import ( + "encoding/json" + "net/http" + "strconv" +) + +var ( + RequestKey = struct{}{} +) + +// ReturnHTTPError handles sending out Error response +// TODO Use the Norman API error framework instead +func ReturnHTTPError(w http.ResponseWriter, r *http.Request, httpStatus int, errorMessage string) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(httpStatus) + + err := AuthError{ + Status: strconv.Itoa(httpStatus), + Message: errorMessage, + Type: "error", + } + + enc := json.NewEncoder(w) + enc.SetEscapeHTML(false) + enc.Encode(err) +} + +func GetHTTPErrorCode(httpStatus int) string { + switch httpStatus { + case 401: + return "Unauthorized" + case 404: + return "NotFound" + case 403: + return "PermissionDenied" + case 500: + return "ServerError" + } + + return "ServerError" +} + +func GetHost(req *http.Request) string { + host := req.Header.Get("X-API-Host") + if host == "" { + host = req.Header.Get("X-Forwarded-Host") + } + if host == "" { + host = req.Host + } + return host +} + +// AuthError structure contains the error resource definition +type AuthError struct { + Type string `json:"type"` + Status string `json:"status"` + Message string `json:"message"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/webhook/webhook.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/webhook/webhook.go new file mode 100644 index 0000000..21c9598 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/auth/webhook/webhook.go @@ -0,0 +1,82 @@ +package webhook + +import ( + "encoding/json" + "net/http" + + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/endpoints/request" +) + +type TokenReviewer struct { + ExternalIDs bool +} + +func (t *TokenReviewer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + dec := json.NewDecoder(req.Body) + tr := &v1.TokenReview{} + err := dec.Decode(tr) + if err != nil { + handleErr(rw, err) + return + } + + req = &http.Request{ + Header: map[string][]string{}, + } + + userInfo, ok := request.UserFrom(req.Context()) + if !ok { + handleErr(rw, requests.ErrMustAuthenticate) + return + } + + user := v1.UserInfo{ + UID: userInfo.GetUID(), + Username: userInfo.GetName(), + Groups: userInfo.GetGroups(), + } + for k, v := range userInfo.GetExtra() { + if user.Extra == nil { + user.Extra = map[string]v1.ExtraValue{} + } + user.Extra[k] = v + } + + trResp := &v1.TokenReview{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "authentication.k8s.io/v1", + Kind: "TokenReview", + }, + Status: v1.TokenReviewStatus{ + Authenticated: ok, + User: user, + }, + } + + writeResp(rw, trResp) +} + +func writeResp(rw http.ResponseWriter, tr *v1.TokenReview) { + rw.Header().Set("Content-Type", "application/json") + enc := json.NewEncoder(rw) + err := enc.Encode(tr) + if err != nil { + logrus.Infof("Failed to encode token review response") + } +} + +func handleErr(rw http.ResponseWriter, err error) { + writeResp(rw, &v1.TokenReview{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "authentication.k8s.io/v1", + Kind: "TokenReview", + }, + Status: v1.TokenReviewStatus{ + Error: err.Error(), + }, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/buildconfig/constants.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/buildconfig/constants.go new file mode 100644 index 0000000..560b4bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/buildconfig/constants.go @@ -0,0 +1,11 @@ +// Code generated by pkg/codegen/config/main.go. DO NOT EDIT. +// Package buildconfig contains a set of exported constants that represent configuration variables of Rancher at build-time. +package buildconfig + +const ( + CspAdapterMinVersion = "104.0.0+up4.0.0" + DefaultShellVersion = "rancher/shell:v0.2.1" + FleetVersion = "104.0.1+up0.10.1" + ProvisioningCAPIVersion = "104.0.0+up0.3.0" + WebhookVersion = "104.0.1+up0.5.1" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cacerts/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cacerts/handler.go new file mode 100644 index 0000000..fa33da2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cacerts/handler.go @@ -0,0 +1,68 @@ +package cacerts + +import ( + "crypto/hmac" + "crypto/sha256" + "crypto/sha512" + "encoding/base64" + "net/http" + "strings" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/tls" +) + +var ( + tokenHash = "tokenByHash" +) + +func Handler(clusterRegistrationToken v3.ClusterRegistrationTokenCache) http.HandlerFunc { + clusterRegistrationToken.AddIndexer(tokenHash, func(obj *apimgmtv3.ClusterRegistrationToken) ([]string, error) { + if obj.Status.Token == "" { + return nil, nil + } + hash := sha256.Sum256([]byte(obj.Status.Token)) + return []string{base64.StdEncoding.EncodeToString(hash[:])}, nil + }) + return func(rw http.ResponseWriter, req *http.Request) { + handler(clusterRegistrationToken, rw, req) + } +} + +func handler(clusterRegistrationToken v3.ClusterRegistrationTokenCache, rw http.ResponseWriter, req *http.Request) { + ca := settings.CACerts.Get() + if v, ok := req.Context().Value(tls.InternalAPI).(bool); ok && v { + ca = settings.InternalCACerts.Get() + } + + rw.Header().Set("Content-Type", "text/plain") + var bytes []byte + if strings.TrimSpace(ca) != "" { + if !strings.HasSuffix(ca, "\n") { + ca += "\n" + } + bytes = []byte(ca) + } + + nonce := req.Header.Get("X-Cattle-Nonce") + authorization := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ") + + if authorization != "" && nonce != "" { + crt, err := clusterRegistrationToken.GetByIndex(tokenHash, authorization) + if err == nil && len(crt) >= 0 { + digest := hmac.New(sha512.New, []byte(crt[0].Status.Token)) + digest.Write([]byte(nonce)) + digest.Write([]byte{0}) + digest.Write(bytes) + digest.Write([]byte{0}) + hash := digest.Sum(nil) + rw.Header().Set("X-Cattle-Hash", base64.StdEncoding.EncodeToString(hash)) + } + } + + if len(bytes) > 0 { + _, _ = rw.Write([]byte(ca)) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common.go new file mode 100644 index 0000000..6376870 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common.go @@ -0,0 +1,663 @@ +package capr + +import ( + "bytes" + "compress/gzip" + "context" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "path" + "regexp" + "sort" + "strings" + "time" + + "github.com/rancher/channelserver/pkg/model" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/channelserver" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/data" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/name" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + capierrors "sigs.k8s.io/cluster-api/errors" +) + +const ( + AddressAnnotation = "rke.cattle.io/address" + ClusterNameLabel = "rke.cattle.io/cluster-name" + // ClusterSpecAnnotation is used to define the cluster spec used to generate the rkecontrolplane object as an annotation on the object + ClusterSpecAnnotation = "rke.cattle.io/cluster-spec" + ControlPlaneRoleLabel = "rke.cattle.io/control-plane-role" + DrainAnnotation = "rke.cattle.io/drain-options" + DrainDoneAnnotation = "rke.cattle.io/drain-done" + DrainErrorAnnotation = "rke.cattle.io/drain-error" + EtcdRoleLabel = "rke.cattle.io/etcd-role" + ForceRemoveEtcdAnnotation = "rke.cattle.io/etcd-force-remove" + HostnameLengthLimitAnnotation = "rke.cattle.io/hostname-length-limit" + InitNodeLabel = "rke.cattle.io/init-node" + InitNodeMachineIDLabel = "rke.cattle.io/init-node-machine-id" + InternalAddressAnnotation = "rke.cattle.io/internal-address" + JoinURLAutosetDisabled = "rke.cattle.io/join-url-autoset-disabled" + JoinURLAnnotation = "rke.cattle.io/join-url" + JoinedToAnnotation = "rke.cattle.io/joined-to" + LabelsAnnotation = "rke.cattle.io/labels" + MachineIDLabel = "rke.cattle.io/machine-id" + MachineNameLabel = "rke.cattle.io/machine-name" + MachineTemplateHashLabel = "rke.cattle.io/machine-template-hash" + RKEMachinePoolNameLabel = "rke.cattle.io/rke-machine-pool-name" + MachineNamespaceLabel = "rke.cattle.io/machine-namespace" + MachineRequestType = "rke.cattle.io/machine-request" + MachineUIDLabel = "rke.cattle.io/machine" + NodeNameLabel = "rke.cattle.io/node-name" + PlanSecret = "rke.cattle.io/plan-secret-name" + PostDrainAnnotation = "rke.cattle.io/post-drain" + PreDrainAnnotation = "rke.cattle.io/pre-drain" + RoleLabel = "rke.cattle.io/service-account-role" + TaintsAnnotation = "rke.cattle.io/taints" + UnCordonAnnotation = "rke.cattle.io/uncordon" + WorkerRoleLabel = "rke.cattle.io/worker-role" + AuthorizedObjectAnnotation = "rke.cattle.io/object-authorized-for-clusters" + PlanUpdatedTimeAnnotation = "rke.cattle.io/plan-last-updated" + PlanProbesPassedAnnotation = "rke.cattle.io/plan-probes-passed" + DeleteMissingCustomMachinesAfterAnnotation = "rke.cattle.io/delete-missing-custom-machines-after" + + JoinServerImplausible = "implausible" + + SecretTypeMachinePlan = "rke.cattle.io/machine-plan" + SecretTypeClusterState = "rke.cattle.io/cluster-state" + + MachineTemplateClonedFromGroupVersionAnn = "rke.cattle.io/cloned-from-group-version" + MachineTemplateClonedFromKindAnn = "rke.cattle.io/cloned-from-kind" + MachineTemplateClonedFromNameAnn = "rke.cattle.io/cloned-from-name" + + CattleOSLabel = "cattle.io/os" + DefaultMachineOS = "linux" + WindowsMachineOS = "windows" + + DefaultMachineConfigAPIVersion = "rke-machine-config.cattle.io/v1" + RKEMachineAPIVersion = "rke-machine.cattle.io/v1" + RKEAPIVersion = "rke.cattle.io/v1" + + Provisioned = condition.Cond("Provisioned") + Stable = condition.Cond("Stable") // The Stable condition is used to indicate whether we can safely copy the v3 management cluster Ready condition to the v1 object. + Updated = condition.Cond("Updated") + Reconciled = condition.Cond("Reconciled") + Ready = condition.Cond("Ready") + Waiting = condition.Cond("Waiting") + Pending = condition.Cond("Pending") + Removed = condition.Cond("Removed") + PlanApplied = condition.Cond("PlanApplied") + InfrastructureReady = condition.Cond(capi.InfrastructureReadyCondition) + SystemUpgradeControllerReady = condition.Cond("SystemUpgradeControllerReady") + Bootstrapped = condition.Cond("Bootstrapped") + + RuntimeK3S = "k3s" + RuntimeRKE2 = "rke2" + + K3sKubectlPath = "/usr/local/bin/kubectl" + K3sKubeconfigPath = "/etc/rancher/k3s/k3s.yaml" + RKE2RelativeKubectlPath = "bin/kubectl" + RKE2KubeconfigPath = "/etc/rancher/rke2/rke2.yaml" + + RoleBootstrap = "bootstrap" + RolePlan = "plan" + + MaxHelmReleaseNameLength = 53 + + MinimumHostnameLengthLimit = 10 + MaximumHostnameLengthLimit = 63 + + SystemAgentDataDirEnvVar = "CATTLE_AGENT_VAR_DIR" + SystemAgentFallbackPathEnvVar = "CATTLE_AGENT_FALLBACK_PATH" +) + +var ( + ErrNoMachineOwnerRef = errors.New("no machine owner ref") + ErrNoMatchingControllerOwnerRef = errors.New("no matching controller owner ref") + labelAnnotationMatch = regexp.MustCompile(`^((rke\.cattle\.io)|((?:machine\.)?cluster\.x-k8s\.io))/`) + windowsDrivers = map[string]struct{}{ + "vmwarevsphere": {}, + } +) + +// WindowsCheck return a bool based on if the driver is marked as +// supporting Windows +func WindowsCheck(driver string) bool { + _, ok := windowsDrivers[driver] + return ok +} + +func MachineStateSecretName(machineName string) string { + return name.SafeConcatName(machineName, "machine", "state") +} + +func GetMachineByOwner(machineCache capicontrollers.MachineCache, obj metav1.Object) (*capi.Machine, error) { + for _, owner := range obj.GetOwnerReferences() { + if owner.APIVersion == capi.GroupVersion.String() && owner.Kind == "Machine" { + return machineCache.Get(obj.GetNamespace(), owner.Name) + } + } + + return nil, ErrNoMachineOwnerRef +} + +// GetKubectlAndKubeconfigPaths returns the corresponding kubectl/kubeconfig paths for a downstream node for the given +// RKEControlPlane. +func GetKubectlAndKubeconfigPaths(controlPlane *rkev1.RKEControlPlane) (string, string) { + switch GetRuntime(controlPlane.Spec.KubernetesVersion) { + case RuntimeK3S: + return K3sKubectlPath, K3sKubeconfigPath + case RuntimeRKE2: + return path.Join(GetDistroDataDir(controlPlane), RKE2RelativeKubectlPath), RKE2KubeconfigPath + } + return "", "" +} + +func GetRuntimeCommand(kubernetesVersion string) string { + return strings.ToLower(GetRuntime(kubernetesVersion)) +} + +func GetRuntimeServerUnit(kubernetesVersion string) string { + if GetRuntime(kubernetesVersion) == RuntimeK3S { + return RuntimeK3S + } + return RuntimeRKE2 + "-server" +} + +func GetRuntimeAgentUnit(kubernetesVersion string) string { + return GetRuntimeCommand(kubernetesVersion) + "-agent" +} + +func GetRuntimeEnv(kubernetesVersion string) string { + return strings.ToUpper(GetRuntime(kubernetesVersion)) +} + +func GetRuntime(kubernetesVersion string) string { + if strings.Contains(kubernetesVersion, RuntimeK3S) { + return RuntimeK3S + } + return RuntimeRKE2 +} + +func GetKDMReleaseData(ctx context.Context, controlPlane *rkev1.RKEControlPlane) *model.Release { + if controlPlane == nil || controlPlane.Spec.KubernetesVersion == "" { + return nil + } + release := channelserver.GetReleaseConfigByRuntimeAndVersion(ctx, GetRuntime(controlPlane.Spec.KubernetesVersion), controlPlane.Spec.KubernetesVersion) + return &release +} + +// GetFeatureVersion retrieves a feature version (string) for a given controlPlane based on the version/runtime of the project. It will return 0.0.0 (semver) if the KDM data is valid, but the featureVersion isn't defined. +func GetFeatureVersion(ctx context.Context, controlPlane *rkev1.RKEControlPlane, featureKey string) (string, error) { + if controlPlane == nil { + return "", fmt.Errorf("error retrieving feature version as controlPlane was nil") + } + + release := GetKDMReleaseData(ctx, controlPlane) + if release == nil { + return "", fmt.Errorf("KDM release data was nil for controlplane %s/%s", controlPlane.Namespace, controlPlane.Name) + } + + version := release.FeatureVersions[featureKey] + if version == "" { + version = "0.0.0" + } + + return version, nil +} + +func GetRuntimeSupervisorPort(kubernetesVersion string) int { + if GetRuntime(kubernetesVersion) == RuntimeRKE2 { + return 9345 + } + return 6443 +} + +func GetLoopbackAddress(controlPlane *rkev1.RKEControlPlane) string { + stackPreference := rkev1.DefaultStackPreference + if networking := controlPlane.Spec.Networking; networking != nil && networking.StackPreference != "" { + stackPreference = networking.StackPreference + } + if stackPreference == rkev1.SingleStackIPv6Preference { + return "[::1]" + } + if stackPreference == rkev1.DualStackPreference { + return "localhost" + } + return "127.0.0.1" +} + +func GetDistroDataDir(controlPlane *rkev1.RKEControlPlane) string { + if dir := controlPlane.Spec.DataDirectories.K8sDistro; dir != "" { + return dir + } + return fmt.Sprintf("/var/lib/rancher/%s", GetRuntime(controlPlane.Spec.KubernetesVersion)) +} + +func GetProvisioningDataDir(spec *rkev1.RKEClusterSpecCommon) string { + if dir := spec.DataDirectories.Provisioning; dir != "" { + return dir + } + return "/var/lib/rancher/capr" +} + +func GetSystemAgentDataDir(spec *rkev1.RKEClusterSpecCommon) string { + if dir := spec.DataDirectories.SystemAgent; dir != "" { + return dir + } + return "/var/lib/rancher/agent" +} + +func IsOwnedByMachine(bootstrapCache rkecontroller.RKEBootstrapCache, machineName string, sa *corev1.ServiceAccount) (bool, error) { + for _, owner := range sa.OwnerReferences { + if owner.Kind == "RKEBootstrap" { + bootstrap, err := bootstrapCache.Get(sa.Namespace, owner.Name) + if err != nil { + return false, err + } + for _, owner := range bootstrap.OwnerReferences { + if owner.Kind == "Machine" && owner.Name == machineName { + return true, nil + } + } + } + } + return false, nil +} + +// PlanSACheck checks the given plan service account to ensure that it matches the machine that is passed, +// and makes sure that the plan service account is owned by the machine in question. +func PlanSACheck(bootstrapCache rkecontroller.RKEBootstrapCache, machineName string, planSA *corev1.ServiceAccount) error { + if planSA == nil { + return fmt.Errorf("planSA was nil during planSA check for machineName %s", machineName) + } + if machineName == "" { + return fmt.Errorf("planSA %s/%s compared machine name was blank", planSA.Namespace, planSA.Name) + } + if planSA.Labels[MachineNameLabel] != machineName || + planSA.Labels[RoleLabel] != RolePlan || + planSA.Labels[PlanSecret] == "" { + return fmt.Errorf("planSA %s/%s does not have correct labels", planSA.Namespace, planSA.Name) + } + if foundParent, err := IsOwnedByMachine(bootstrapCache, machineName, planSA); err != nil { + return err + } else if !foundParent { + return fmt.Errorf("planSA %s/%s no parent found for planSA, was not owned by machine %s", planSA.Namespace, planSA.Name, machineName) + } + return nil +} + +// GetPlanSecretName will return the plan secret name that is assigned to the plan service account +func GetPlanSecretName(planSA *corev1.ServiceAccount) (string, error) { + if planSA == nil { + return "", fmt.Errorf("planSA was nil") + } + if planSA.Labels[PlanSecret] == "" { + return "", fmt.Errorf("planSA %s/%s plan secret label was not set", planSA.Namespace, planSA.Name) + } + return planSA.Labels[PlanSecret], nil +} + +// GetPlanServiceAccountTokenSecret retrieves the secret that corresponds to the plan service account that is passed in. It will create a secret if one does not +// already exist for the plan service account. +func GetPlanServiceAccountTokenSecret(secretClient corecontrollers.SecretController, k8s kubernetes.Interface, planSA *corev1.ServiceAccount) (*corev1.Secret, bool, error) { + if planSA == nil { + return nil, false, fmt.Errorf("planSA was nil") + } + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(context.Background(), secretClient.Cache(), k8s, planSA) + if err != nil { + return nil, false, fmt.Errorf("error ensuring secret for service account [%s:%s]: %w", planSA.Namespace, planSA.Name, err) + } + return secret, true, nil +} + +func PlanSecretFromBootstrapName(bootstrapName string) string { + return name.SafeConcatName(bootstrapName, "machine", "plan") +} + +func DoRemoveAndUpdateStatus(obj metav1.Object, doRemove func() (string, error), enqueueAfter func(string, string, time.Duration)) error { + if !Provisioned.IsTrue(obj) || !Waiting.IsTrue(obj) || !Pending.IsTrue(obj) || !Updated.IsTrue(obj) { + // Ensure the Removed obj appears in the UI. + Provisioned.SetStatus(obj, "True") + Waiting.SetStatus(obj, "True") + Pending.SetStatus(obj, "True") + Updated.SetStatus(obj, "True") + } + message, err := doRemove() + if errors.Is(err, generic.ErrSkip) { + // If generic.ErrSkip is returned, we don't want to update the status. + return err + } + + if err != nil { + Removed.SetError(obj, "", err) + } else if message == "" { + Removed.SetStatusBool(obj, true) + Removed.Reason(obj, "") + Removed.Message(obj, "") + } else { + Removed.SetStatus(obj, "Unknown") + Removed.Reason(obj, "Waiting") + Removed.Message(obj, message) + enqueueAfter(obj.GetNamespace(), obj.GetName(), 5*time.Second) + // generic.ErrSkip will mark the cluster as reconciled, but not remove the finalizer. + // The finalizer shouldn't be removed until other objects have all been removed. + err = generic.ErrSkip + } + + return err +} + +func GetMachineDeletionStatus(machines []*capi.Machine) (string, error) { + sort.Slice(machines, func(i, j int) bool { + return machines[i].Name < machines[j].Name + }) + for _, machine := range machines { + if machine.Status.FailureReason != nil && *machine.Status.FailureReason == capierrors.DeleteMachineError { + return "", fmt.Errorf("error deleting machine [%s], machine must be deleted manually", machine.Name) + } + return fmt.Sprintf("waiting for machine [%s] to delete", machine.Name), nil + } + + return "", nil +} + +// GetMachineFromNode attempts to find the corresponding machine for an etcd snapshot that is found in the configmap. If the machine list is successful, it will return true on the boolean, otherwise, it can be assumed that a false, nil, and defined error indicate the machine does not exist. +func GetMachineFromNode(machineCache capicontrollers.MachineCache, nodeName string, cluster *provv1.Cluster) (bool, *capi.Machine, error) { + ls, err := labels.Parse(fmt.Sprintf("%s=%s", capi.ClusterNameLabel, cluster.Name)) + if err != nil { + return false, nil, err + } + machines, err := machineCache.List(cluster.Namespace, ls) + if err != nil { + return false, nil, err + } + for _, machine := range machines { + if machine.Status.NodeRef != nil && machine.Status.NodeRef.Name == nodeName { + return true, machine, nil + } + } + return true, nil, fmt.Errorf("unable to find node %s in machines", nodeName) +} + +// GetMachineByID attempts to find the corresponding machine for an etcd snapshot that is found in the configmap. If the machine list is successful, it will return true on the boolean, otherwise, it can be assumed that a false, nil, and defined error indicate the machine does not exist. +func GetMachineByID(machineCache capicontrollers.MachineCache, machineID, clusterNamespace, clusterName string) (bool, *capi.Machine, error) { + machines, err := machineCache.List(clusterNamespace, labels.SelectorFromSet(map[string]string{ + ClusterNameLabel: clusterName, + MachineIDLabel: machineID, + })) + if err != nil || len(machines) > 1 { + return false, nil, err + } + if len(machines) == 1 { + return true, machines[0], nil + } + return true, nil, fmt.Errorf("unable to find machine by ID %s for cluster %s", machineID, clusterName) +} + +func CopyPlanMetadataToSecret(secret *corev1.Secret, metadata *plan.Metadata) { + if metadata == nil { + return + } + if secret.Labels == nil { + secret.Labels = map[string]string{} + } + if secret.Annotations == nil { + secret.Annotations = map[string]string{} + } + + CopyMap(secret.Labels, metadata.Labels) + CopyMap(secret.Annotations, metadata.Annotations) +} + +// CopyMap will copy the items from source to destination. It will only copy items that have keys that start with +// rke.cattle.io/, cluster.x-k8s.io/. or machine.cluster.x-k8s.io/. +func CopyMap(destination map[string]string, source map[string]string) { + CopyMapWithExcludes(destination, source, nil) +} + +// CopyMapWithExcludes will copy the items from source to destination, excluding all items whose keys are in excludes. +// It will only copy items that have keys that start with rke.cattle.io/, cluster.x-k8s.io/. or +// machine.cluster.x-k8s.io/. +func CopyMapWithExcludes(destination map[string]string, source map[string]string, excludes map[string]struct{}) { + for k, v := range source { + if !labelAnnotationMatch.MatchString(k) { + continue + } + if _, ok := excludes[k]; !ok { + destination[k] = v + } + } +} + +func SortedKeys(m map[string]interface{}) []string { + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +var errNilObject = errors.New("cannot get capi cluster for nil object") + +// GetCAPIClusterFromLabel takes a runtime.Object and will attempt to find the label denoting which capi cluster it +// belongs to. +// If the object is nil, it cannot access to object or type metas, or the label is not present, it returns an error. +// If the object has the expected label, it will return the capi cluster object. +func GetCAPIClusterFromLabel(obj runtime.Object, cache capicontrollers.ClusterCache) (*capi.Cluster, error) { + if obj == nil { + return nil, errNilObject + } + data, err := data.Convert(obj) + if err != nil { + return nil, err + } + clusterName := data.String("metadata", "labels", capi.ClusterNameLabel) + if clusterName != "" { + return cache.Get(data.String("metadata", "namespace"), clusterName) + } + return nil, fmt.Errorf("%s label not present on %s: %s/%s", capi.ClusterNameLabel, obj.GetObjectKind().GroupVersionKind().Kind, data.String("metadata", "namespace"), data.String("metadata", "name")) +} + +// GetOwnerCAPICluster takes an obj and will attempt to find the capi cluster owner reference. +// If the object is nil, it cannot access to object or type metas, the owner reference Kind or APIVersion do not match, +// or the object could not be found, it returns an error. +// If the owner reference exists and is valid, it will return the owning capi cluster object. +func GetOwnerCAPICluster(obj runtime.Object, cache capicontrollers.ClusterCache) (*capi.Cluster, error) { + ref, namespace, err := GetOwnerFromGVK(capi.GroupVersion.String(), "Cluster", obj) + if err != nil { + return nil, err + } + return cache.Get(namespace, ref.Name) +} + +// GetOwnerCAPIMachine takes an obj and will attempt to find the capi machine owner reference. +// If the object is nil, it cannot access to object or type metas, the owner reference Kind or APIVersion do not match, +// or the object could not be found, it returns an error. +// If the owner reference exists and is valid, it will return the owning capi machine object. +func GetOwnerCAPIMachine(obj runtime.Object, cache capicontrollers.MachineCache) (*capi.Machine, error) { + ref, namespace, err := GetOwnerFromGVK(capi.GroupVersion.String(), "Machine", obj) + if err != nil { + return nil, err + } + return cache.Get(namespace, ref.Name) +} + +// GetOwnerCAPIMachineSet takes an obj and will attempt to find the capi machine set owner reference. +// If the object is nil, it cannot access to object or type metas, the owner reference Kind or APIVersion do not match, +// or the object could not be found, it returns an error. +// If the owner reference exists and is valid, it will return the owning capi machine object. +func GetOwnerCAPIMachineSet(obj runtime.Object, cache capicontrollers.MachineSetCache) (*capi.MachineSet, error) { + ref, namespace, err := GetOwnerFromGVK(capi.GroupVersion.String(), "MachineSet", obj) + if err != nil { + return nil, err + } + return cache.Get(namespace, ref.Name) +} + +// GetOwnerFromGVK takes a runtime.Object, and will search for a controlling owner reference of kind apiVersion. +// If the object is nil, it cannot access to object or type metas, the owner reference Kind or APIVersion do not match, +// or the object could not be found, it returns an ErrNoMatchingControllerOwnerRef error. +// If the owner reference exists and is valid, it will return the owner reference and the namespace it belongs to. +func GetOwnerFromGVK(groupVersion, kind string, obj runtime.Object) (*metav1.OwnerReference, string, error) { + if obj == nil { + return nil, "", errNilObject + } + objMeta, err := meta.Accessor(obj) + if err != nil { + return nil, "", err + } + ref := metav1.GetControllerOf(objMeta) + if ref == nil || ref.Kind != kind || ref.APIVersion != groupVersion { + return nil, "", ErrNoMatchingControllerOwnerRef + } + return ref, objMeta.GetNamespace(), nil +} + +// SafeConcatName takes a maximum length and set of strings, it returns a string +// representing the concatenation of the given strings which is at most maxLength long. +// If a given set of strings exceeds the maxLength parameter, the concatenated string will be truncated and +// a hash will be prepended so that the result is at most maxLength long. +// If the maxLength parameter is equal to or less than 5, the string will simply be shortened with no additional hash added. +// TODO; move this updated logic into wrangler, where it belongs. +func SafeConcatName(maxLength int, name ...string) string { + + hashLength := 6 + + fullPath := strings.Join(name, "-") + if len(fullPath) <= maxLength { + return fullPath + } + + if maxLength == 0 { + return "" + } + + if maxLength <= 5 { + return fullPath[:maxLength] + } + + digest := sha256.Sum256([]byte(fullPath)) + + // since we trailingCharacterIndex the string in the middle, the last char may not be compatible with what is expected in k8s + // we are checking and if necessary removing the last char + trailingCharacterIndex := maxLength - (hashLength + 1) + if trailingCharacterIndex < 0 { + trailingCharacterIndex = 0 + } + c := fullPath[trailingCharacterIndex] + + if 'a' <= c && c <= 'z' || '0' <= c && c <= '9' { + remainingString := fullPath[0 : maxLength-(hashLength)] + hash := hex.EncodeToString(digest[0:])[0 : hashLength-1] + if remainingString == "" { + // if we've completely converted the input into a hash don't append '-' + return hash + } + return remainingString + "-" + hash + } + + return fullPath[0:maxLength-(hashLength+1)] + "-" + hex.EncodeToString(digest[0:])[0:hashLength] +} + +// CompressInterface is a function that will marshal, gzip, then base64 encode the provided interface. +func CompressInterface(v interface{}) (string, error) { + marshalledCluster, err := json.Marshal(v) + if err != nil { + return "", err + } + var b bytes.Buffer + gz := gzip.NewWriter(&b) + if _, err := gz.Write(marshalledCluster); err != nil { + return "", err + } + if err := gz.Flush(); err != nil { + return "", err + } + if err := gz.Close(); err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(b.Bytes()), nil +} + +// DecompressInterface is a function that will base64 decode, ungzip, and unmarshal a string into the provided interface. +func DecompressInterface(inputb64 string, v any) error { + if inputb64 == "" { + return fmt.Errorf("empty base64 input") + } + + decodedGzip, err := base64.StdEncoding.DecodeString(inputb64) + if err != nil { + return fmt.Errorf("error base64.DecodeString: %v", err) + } + + buffer := bytes.NewBuffer(decodedGzip) + + var gz io.Reader + gz, err = gzip.NewReader(buffer) + if err != nil { + return err + } + + csBytes, err := io.ReadAll(gz) + if err != nil { + return err + } + + err = json.Unmarshal(csBytes, v) + if err != nil { + return err + } + + return nil +} + +// DecompressClusterSpec is a function that will base64 decode, ungzip, and unmarshal a string into a cluster spec. +func DecompressClusterSpec(inputb64 string) (*provv1.ClusterSpec, error) { + c := provv1.ClusterSpec{} + err := DecompressInterface(inputb64, &c) + if err != nil { + return nil, err + } + return &c, nil +} + +// ParseSnapshotClusterSpecOrError returns a provv1 ClusterSpec from the etcd snapshot if it can be found in the CR. If it cannot be found, it returns an error. +func ParseSnapshotClusterSpecOrError(snapshot *rkev1.ETCDSnapshot) (*provv1.ClusterSpec, error) { + if snapshot == nil { + return nil, fmt.Errorf("snapshot was nil") + } + if snapshot.SnapshotFile.Metadata != "" { + var md map[string]string + b, err := base64.StdEncoding.DecodeString(snapshot.SnapshotFile.Metadata) + if err != nil { + return nil, err + } + if err := json.Unmarshal(b, &md); err != nil { + return nil, err + } + if v, ok := md["provisioning-cluster-spec"]; ok { + return DecompressClusterSpec(v) + } + } + return nil, fmt.Errorf("unable to find and decode snapshot ClusterSpec for snapshot") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common_test.go new file mode 100644 index 0000000..9858ebf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/common_test.go @@ -0,0 +1,315 @@ +package capr + +import ( + "reflect" + "testing" + + "github.com/golang/mock/gomock" + "github.com/pkg/errors" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// Implements ClusterCache +type test struct { + name string + expected *capi.Cluster + expectedErr error + obj runtime.Object +} + +func TestFindCAPIClusterFromLabel(t *testing.T) { + tests := []test{ + { + name: "nil", + expected: nil, + expectedErr: errNilObject, + obj: nil, + }, + { + name: "missing label", + expected: nil, + expectedErr: errors.New("cluster.x-k8s.io/cluster-name label not present on testObject: testNamespace/testName"), + obj: &capi.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testName", + Namespace: "testNamespace", + Labels: map[string]string{}, + }, + TypeMeta: metav1.TypeMeta{Kind: "testObject"}, + }, + }, + { + name: "missing cluster", + expected: nil, + obj: &capi.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "cluster.x-k8s.io/cluster-name": "testCluster", + }, + }, + }, + }, + { + name: "success", + expected: &capi.Cluster{}, + expectedErr: nil, + obj: &capi.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "cluster.x-k8s.io/cluster-name": "testCluster", + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + capiCache := fake.NewMockCacheInterface[*capi.Cluster](ctrl) + capiCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(tt.expected, nil).MaxTimes(1) + cluster, err := GetCAPIClusterFromLabel(tt.obj, capiCache) + if err == nil { + assert.Nil(t, tt.expectedErr) + } else if tt.expectedErr != nil { + assert.Equal(t, tt.expectedErr.Error(), err.Error()) + } else { + assert.Fail(t, "expected err to be nil, was actually %s", err) + } + assert.Equal(t, tt.expected, cluster) + }) + } +} + +func TestFindOwnerCAPICluster(t *testing.T) { + tests := []test{ + { + name: "nil", + expected: nil, + expectedErr: errNilObject, + obj: nil, + }, + { + name: "no owner", + expected: nil, + expectedErr: ErrNoMatchingControllerOwnerRef, + obj: &rkev1.RKECluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "RKECluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + Namespace: "testnamespace", + }, + }, + }, + { + name: "no controller", + expected: nil, + expectedErr: ErrNoMatchingControllerOwnerRef, + obj: &rkev1.RKECluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "RKECluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + Namespace: "testnamespace", + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "nil", + }, + }, + }, + }, + }, + { + name: "owner wrong kind", + expected: nil, + expectedErr: ErrNoMatchingControllerOwnerRef, + obj: &rkev1.RKECluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "RKECluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + Namespace: "testnamespace", + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "nil", + APIVersion: "cluster.x-k8s.io/v1beta1", + Controller: &[]bool{true}[0], + }, + }, + }, + }, + }, + { + name: "owner wrong api version", + expected: nil, + expectedErr: ErrNoMatchingControllerOwnerRef, + obj: &rkev1.RKECluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "RKECluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + Namespace: "testnamespace", + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "Cluster", + APIVersion: "nil", + Controller: &[]bool{true}[0], + }, + }, + }, + }, + }, + { + name: "success", + expected: nil, + expectedErr: nil, + obj: &rkev1.RKECluster{ + TypeMeta: metav1.TypeMeta{ + Kind: "RKECluster", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + Namespace: "testnamespace", + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "Cluster", + APIVersion: "cluster.x-k8s.io/v1beta1", + Controller: &[]bool{true}[0], + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + capiCache := fake.NewMockCacheInterface[*capi.Cluster](ctrl) + capiCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(tt.expected, tt.expectedErr).MaxTimes(1) + cluster, err := GetOwnerCAPICluster(tt.obj, capiCache) + if err == nil { + assert.Nil(t, tt.expectedErr) + } else if tt.expectedErr != nil { + assert.Equal(t, tt.expectedErr.Error(), err.Error()) + } else { + assert.Fail(t, "expected err to be nil, was actually %s", err) + } + assert.Equal(t, tt.expected, cluster) + }) + } +} + +func TestSafeConcatName(t *testing.T) { + + testcase := []struct { + name string + input []string + expectedOutput string + maxLength int + }{ + { + name: "max k8s name shortening", + input: []string{"very", "long", "name", "to", "test", "shortening", "behavior", "this", "should", "exceed", "max", "k8s", "name", "length"}, + expectedOutput: "very-long-name-to-test-shortening-behavior-this-should-ex-e8118", + maxLength: 63, + }, + { + name: "max helm release name shortening", + maxLength: 53, + input: []string{"long", "cluster", "name", "testing", "managed", "system-upgrade", "controller", "fleet", "agent"}, + expectedOutput: "long-cluster-name-testing-managed-system-upgrad-0beef", + }, + { + name: "max length smaller than hash size should concat and shorten but not hash", + maxLength: 3, + input: []string{"this", "will", "not", "be", "hashed"}, + expectedOutput: "thi", + }, + { + name: "concat but not shorten", + maxLength: 90, + input: []string{"simple", "concat", "no", "hash", "needed"}, + expectedOutput: "simple-concat-no-hash-needed", + }, + { + name: "no max length, no output", + maxLength: 0, + input: []string{"input"}, + expectedOutput: "", + }, + { + name: "input equal to hash length should return hash without leading '-'", + maxLength: 6, + input: []string{"input", "s"}, + expectedOutput: "deab5", + }, + { + name: "avoid special characters", + maxLength: 8, + input: []string{"a", "&", "b", "=", "c"}, + expectedOutput: "a-359087", + }, + } + + for _, tc := range testcase { + t.Run(tc.name, func(t *testing.T) { + out := SafeConcatName(tc.maxLength, tc.input...) + if len(out) > tc.maxLength || out != tc.expectedOutput { + t.Fail() + t.Logf("expected output %s with length of %d, got %s with length of %d", tc.expectedOutput, len(tc.expectedOutput), out, len(out)) + } + t.Log(out) + }) + } +} + +func TestCompressInterface(t *testing.T) { + tests := []struct { + name string + value any + }{ + { + name: "int", + value: &[]int{1}[0], + }, + { + name: "string", + value: &[]string{"test"}[0], + }, + { + name: "struct", + value: &struct { + TestInt int + TestString string + }{ + TestInt: 1, + TestString: "test", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := CompressInterface(tt.value) + assert.Nil(t, err) + assert.True(t, result != "") + + target := reflect.New(reflect.ValueOf(tt.value).Elem().Type()).Interface() + + err = DecompressInterface(result, target) + assert.Nil(t, err) + assert.Equal(t, tt.value, target) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/custom.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/custom.go new file mode 100644 index 0000000..f3ebfff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/custom.go @@ -0,0 +1,141 @@ +package configserver + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/rancher/rancher/pkg/capr" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + machineIDHeader = "X-Cattle-Id" + headerPrefix = "X-Cattle-" +) + +func (r *RKE2ConfigServer) findMachineByClusterToken(req *http.Request) (string, string, error) { + token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ") + if token == "" { + return "", "", nil + } + + machineID := req.Header.Get(machineIDHeader) + if machineID == "" { + return "", "", nil + } + + tokens, err := r.clusterTokenCache.GetByIndex(tokenIndex, token) + if err != nil { + return "", "", err + } + + data := dataFromHeaders(req) + + if len(tokens) == 0 { + return "", "", nil + } + + secretName := machineRequestSecretName(machineID) + secret, err := r.secretsCache.Get(tokens[0].Namespace, secretName) + if apierror.IsNotFound(err) { + secret, err = r.createSecret(tokens[0].Namespace, secretName, data) + } + if err != nil { + return "", "", err + } + + secret, err = r.waitReady(secret) + if err != nil { + return "", "", err + } + + machineNamespace, machineName := secret.Labels[capr.MachineNamespaceLabel], secret.Labels[capr.MachineNameLabel] + _ = r.secrets.Delete(secret.Namespace, secret.Name, nil) + return machineNamespace, machineName, nil +} + +func (r *RKE2ConfigServer) findMachineByID(machineID, ns string) (*capi.Machine, error) { + machines, err := r.machineCache.List(ns, labels.SelectorFromSet(map[string]string{ + capr.MachineIDLabel: machineID, + })) + if err != nil { + return nil, err + } + + if len(machines) != 1 { + return nil, fmt.Errorf("unable to find machine %s, found %d machine(s)", machineID, len(machines)) + } + + return machines[0], nil +} + +func (r *RKE2ConfigServer) createSecret(namespace, name string, data map[string]interface{}) (*corev1.Secret, error) { + dataBytes, err := json.Marshal(data) + if err != nil { + return nil, err + } + + return r.secrets.Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Immutable: nil, + Data: map[string][]byte{ + "data": dataBytes, + }, + Type: capr.MachineRequestType, + }) +} + +func (r *RKE2ConfigServer) waitReady(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.Labels[capr.MachineNameLabel] != "" { + return secret, nil + } + + resp, err := r.secrets.Watch(secret.Namespace, metav1.ListOptions{ + TimeoutSeconds: &[]int64{120}[0], + FieldSelector: "metadata.name=" + secret.Name, + }) + if err != nil { + return nil, err + } + defer func() { + resp.Stop() + for range resp.ResultChan() { + } + }() + + for obj := range resp.ResultChan() { + secret, ok := obj.Object.(*corev1.Secret) + if ok && secret.Labels[capr.MachineNameLabel] != "" { + return secret, nil + } + } + + return nil, fmt.Errorf("timeout waiting for %s/%s to be ready", secret.Namespace, secret.Name) +} + +func machineRequestSecretName(name string) string { + hash := sha256.Sum256([]byte(name)) + return "custom-" + hex.EncodeToString(hash[:])[:12] +} + +func dataFromHeaders(req *http.Request) map[string]interface{} { + data := make(map[string]interface{}) + for k, v := range req.Header { + if strings.HasPrefix(k, headerPrefix) { + data[strings.ToLower(strings.TrimPrefix(k, headerPrefix))] = v + } + } + + return data +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/managed.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/managed.go new file mode 100644 index 0000000..beacb03 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/managed.go @@ -0,0 +1,32 @@ +package configserver + +import ( + "net/http" + "strings" + + "github.com/rancher/rancher/pkg/capr" + api "k8s.io/api/core/v1" +) + +func (r *RKE2ConfigServer) findMachineByProvisioningSA(req *http.Request) (string, string, error) { + token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ") + secrets, err := r.secretsCache.GetByIndex(tokenIndex, token) + if err != nil || len(secrets) == 0 { + return "", "", err + } + + sa, err := r.serviceAccountsCache.Get(secrets[0].Namespace, secrets[0].Annotations[api.ServiceAccountNameKey]) + if err != nil { + return "", "", err + } + + if sa.Labels[capr.RoleLabel] != capr.RoleBootstrap || string(sa.UID) != secrets[0].Annotations[api.ServiceAccountUIDKey] { + return "", "", err + } + + if foundParent, err := capr.IsOwnedByMachine(r.bootstrapCache, sa.Labels[capr.MachineNameLabel], sa); err != nil || !foundParent { + return "", "", err + } + + return sa.Namespace, sa.Labels[capr.MachineNameLabel], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/server.go new file mode 100644 index 0000000..2c4dfea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/configserver/server.go @@ -0,0 +1,486 @@ +package configserver + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/capr/planner" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + provisioningcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/tls" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + ConnectClusterInfo = "/v3/connect/cluster-info" + ConnectConfigYamlPath = "/v3/connect/config-yaml" + ConnectAgent = "/v3/connect/agent" +) + +var ( + tokenIndex = "tokenIndex" +) + +type RKE2ConfigServer struct { + clusterTokenCache mgmtcontroller.ClusterRegistrationTokenCache + clusterTokens mgmtcontroller.ClusterRegistrationTokenController + serviceAccountsCache corecontrollers.ServiceAccountCache + serviceAccounts corecontrollers.ServiceAccountClient + secretsCache corecontrollers.SecretCache + secrets corecontrollers.SecretController + settings mgmtcontroller.SettingCache + machineCache capicontrollers.MachineCache + machines capicontrollers.MachineClient + bootstrapCache rkecontroller.RKEBootstrapCache + provisioningClusterCache provisioningcontrollers.ClusterCache + k8s kubernetes.Interface +} + +func New(clients *wrangler.Context) *RKE2ConfigServer { + clients.Core.Secret().Cache().AddIndexer(tokenIndex, func(obj *corev1.Secret) ([]string, error) { + if obj.Type == corev1.SecretTypeServiceAccountToken { + hash := sha256.Sum256(obj.Data["token"]) + return []string{base64.URLEncoding.EncodeToString(hash[:])}, nil + } + return nil, nil + }) + + clients.Mgmt.ClusterRegistrationToken().Cache().AddIndexer(tokenIndex, + func(obj *v3.ClusterRegistrationToken) ([]string, error) { + return []string{obj.Status.Token}, nil + }) + + return &RKE2ConfigServer{ + serviceAccountsCache: clients.Core.ServiceAccount().Cache(), + serviceAccounts: clients.Core.ServiceAccount(), + secretsCache: clients.Core.Secret().Cache(), + secrets: clients.Core.Secret(), + clusterTokenCache: clients.Mgmt.ClusterRegistrationToken().Cache(), + clusterTokens: clients.Mgmt.ClusterRegistrationToken(), + machineCache: clients.CAPI.Machine().Cache(), + machines: clients.CAPI.Machine(), + bootstrapCache: clients.RKE.RKEBootstrap().Cache(), + provisioningClusterCache: clients.Provisioning.Cluster().Cache(), + k8s: clients.K8s, + } +} + +func (r *RKE2ConfigServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if !r.secrets.Informer().HasSynced() || !r.clusterTokens.Informer().HasSynced() { + if err := r.secrets.Informer().GetIndexer().Resync(); err != nil { + logrus.Errorf("error re-syncing secrets informer in rke2configserver: %v", err) + } + if err := r.clusterTokens.Informer().GetIndexer().Resync(); err != nil { + logrus.Errorf("error re-syncing clustertokens informer in rke2configserver: %v", err) + } + rw.WriteHeader(http.StatusUnauthorized) + return + } + planSecret, secret, err := r.findSA(req) + if apierrors.IsNotFound(err) { + rw.WriteHeader(http.StatusUnauthorized) + return + } else if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } else if secret == nil || secret.Data[corev1.ServiceAccountTokenKey] == nil { + rw.WriteHeader(http.StatusUnauthorized) + return + } + + switch req.URL.Path { + case ConnectConfigYamlPath: + r.connectConfigYaml(planSecret, secret.Namespace, rw) + case ConnectAgent: + r.connectAgent(planSecret, secret, rw, req) + case ConnectClusterInfo: + r.connectClusterInfo(secret, rw, req) + } +} + +func (r *RKE2ConfigServer) connectAgent(planSecret string, secret *v1.Secret, rw http.ResponseWriter, req *http.Request) { + var ca []byte + url, pem := settings.ServerURL.Get(), settings.CACerts.Get() + if strings.TrimSpace(pem) != "" { + ca = []byte(pem) + } + + if url == "" { + pem = settings.InternalCACerts.Get() + url = fmt.Sprintf("https://%s", req.Host) + if strings.TrimSpace(pem) != "" { + ca = []byte(pem) + } + } else if v, ok := req.Context().Value(tls.InternalAPI).(bool); ok && v { + pem = settings.InternalCACerts.Get() + if strings.TrimSpace(pem) != "" { + ca = []byte(pem) + } + } + + kubeConfig, err := clientcmd.Write(clientcmdapi.Config{ + Clusters: map[string]*clientcmdapi.Cluster{ + "agent": { + Server: url, + CertificateAuthorityData: ca, + }, + }, + AuthInfos: map[string]*clientcmdapi.AuthInfo{ + "agent": { + Token: string(secret.Data["token"]), + }, + }, + Contexts: map[string]*clientcmdapi.Context{ + "agent": { + Cluster: "agent", + AuthInfo: "agent", + }, + }, + CurrentContext: "agent", + }) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + rw.Header().Set("Content-Type", "application/json") + enc := json.NewEncoder(rw) + enc.SetIndent("", " ") + _ = enc.Encode(map[string]string{ + "namespace": secret.Namespace, + "secretName": planSecret, + "kubeConfig": string(kubeConfig), + }) +} + +func (r *RKE2ConfigServer) connectConfigYaml(name, ns string, rw http.ResponseWriter) { + mpSecret, err := r.getMachinePlanSecret(ns, name) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + config := make(map[string]interface{}) + if err := json.Unmarshal(mpSecret.Data[capr.RolePlan], &config); err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + if _, ok := config["files"]; !ok { + http.Error(rw, "no files in the plan", http.StatusInternalServerError) + return + } + + kubernetesVersion, err := r.getClusterKubernetesVersion(mpSecret.Labels[capi.ClusterNameLabel], ns) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + var content string + for _, f := range config["files"].([]interface{}) { + f := f.(map[string]interface{}) + if path, ok := f["path"].(string); ok && path == fmt.Sprintf(planner.ConfigYamlFileName, capr.GetRuntime(kubernetesVersion)) { + if _, ok := f["content"]; ok { + content = f["content"].(string) + } + } + } + + if content == "" { + http.Error(rw, "no config content", http.StatusInternalServerError) + return + } + + jsonContent, err := base64.StdEncoding.DecodeString(content) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + rw.Header().Set("Content-Type", "application/json") + rw.Write(jsonContent) +} + +func (r *RKE2ConfigServer) connectClusterInfo(secret *v1.Secret, rw http.ResponseWriter, req *http.Request) { + headers := dataFromHeaders(req) + + // expecting -H "X-Cattle-Field: kubernetesversion" -H "X-Cattle-Field: name" + fields, ok := headers["field"] + if !ok { + http.Error(rw, "no field headers", http.StatusInternalServerError) + return + } + + castedFields, ok := fields.([]string) + if !ok || len(castedFields) == 0 { + http.Error(rw, "no field headers", http.StatusInternalServerError) + return + } + + var info = make(map[string]string) + for _, f := range castedFields { + switch strings.ToLower(f) { + case "kubernetesversion": + k8sv, err := r.infoKubernetesVersion(req.Header.Get(machineIDHeader), secret.Namespace) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + info[f] = k8sv + } + } + + jsonContent, err := json.Marshal(info) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + + rw.Header().Set("Content-Type", "application/json") + rw.Write(jsonContent) +} + +func (r *RKE2ConfigServer) infoKubernetesVersion(machineID, ns string) (string, error) { + if machineID == "" { + return "", nil + } + machine, err := r.findMachineByID(machineID, ns) + if err != nil { + return "", err + } + + clusterName, ok := machine.Labels[capi.ClusterNameLabel] + if !ok { + return "", fmt.Errorf("unable to find cluster name for machine") + } + + return r.getClusterKubernetesVersion(clusterName, ns) +} + +func (r *RKE2ConfigServer) getClusterKubernetesVersion(clusterName, ns string) (string, error) { + cluster, err := r.provisioningClusterCache.Get(ns, clusterName) + if err != nil { + return "", err + } + + return cluster.Spec.KubernetesVersion, nil +} + +// findSA uses the request machineID to find and deliver the plan secret name and a service account token (or an error). +func (r *RKE2ConfigServer) findSA(req *http.Request) (string, *corev1.Secret, error) { + machineID := req.Header.Get(machineIDHeader) + logrus.Debugf("[rke2configserver] parsed %s as machineID", machineID) + if machineID == "" { + return "", nil, nil + } + + machineNamespace, machineName, err := r.findMachineByProvisioningSA(req) + if err != nil { + return "", nil, err + } + logrus.Debugf("[rke2configserver] Got %s/%s machine from provisioning SA", machineNamespace, machineName) + if machineName == "" { + machineNamespace, machineName, err = r.findMachineByClusterToken(req) + if err != nil { + return "", nil, err + } + logrus.Debugf("[rke2configserver] Got %s/%s machine from cluster token", machineNamespace, machineName) + } + + if machineName == "" || machineNamespace == "" { + return "", nil, fmt.Errorf("machine not found by request") + } + + if err := r.setOrUpdateMachineID(machineNamespace, machineName, machineID); err != nil { + return "", nil, err + } + + planSAs, err := r.serviceAccountsCache.List(machineNamespace, labels.SelectorFromSet(map[string]string{ + capr.MachineNameLabel: machineName, + capr.RoleLabel: capr.RolePlan, + })) + if err != nil { + return "", nil, err + } + + logrus.Debugf("[rke2configserver] %s/%s listed %d planSAs", machineNamespace, machineName, len(planSAs)) + + for _, planSA := range planSAs { + if err := capr.PlanSACheck(r.bootstrapCache, machineName, planSA); err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for checking planSA %s/%s against machine %s: %v", planSA.Namespace, planSA.Name, machineName, err) + continue + } + planSecret, err := capr.GetPlanSecretName(planSA) + if err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for plan secret name for planSA %s/%s: %v", planSA.Namespace, planSA.Name, err) + continue + } + logrus.Debugf("[rke2configserver] %s/%s plan secret was %s", machineNamespace, machineName, planSecret) + if planSecret == "" { + continue + } + tokenSecret, _, err := capr.GetPlanServiceAccountTokenSecret(r.secrets, r.k8s, planSA) + if err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for token secret for planSA %s/%s: %v", planSA.Namespace, planSA.Name, err) + continue + } + if tokenSecret == nil { + logrus.Debugf("[rke2configserver] %s/%s token secret for planSecret %s was nil", machineNamespace, machineName, planSecret) + continue + } + logrus.Infof("[rke2configserver] %s/%s machineID: %s delivering planSecret %s with token secret %s/%s to system-agent", machineNamespace, machineName, machineID, planSecret, tokenSecret.Namespace, tokenSecret.Name) + return planSecret, tokenSecret, err + } + + logrus.Debugf("[rke2configserver] %s/%s watching for plan secret to become ready for consumption", machineNamespace, machineName) + + // The plan service account will likely not exist yet -- the plan service account is created by the bootstrap controller. + respSA, err := r.serviceAccounts.Watch(machineNamespace, metav1.ListOptions{ + LabelSelector: capr.MachineNameLabel + "=" + machineName + "," + capr.RoleLabel + "=" + capr.RolePlan, + }) + if err != nil { + return "", nil, err + } + defer func() { + respSA.Stop() + for range respSA.ResultChan() { + } + }() + + // The following logic will start a watch for plan service accounts -- + // once we see the first valid plan service account come through, we then will open a watch for secrets to look for the corresponding secret for that plan service account. + var planSA *corev1.ServiceAccount + var planSecret string + + for event := range respSA.ResultChan() { + var ok bool + if planSA, ok = event.Object.(*corev1.ServiceAccount); ok { + if err := capr.PlanSACheck(r.bootstrapCache, machineName, planSA); err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for checking planSA %s/%s against machine %s: %v", planSA.Namespace, planSA.Name, machineName, err) + continue + } + planSecret, err = capr.GetPlanSecretName(planSA) + if err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for plan secret name for planSA %s/%s: %v", planSA.Namespace, planSA.Name, err) + continue + } + logrus.Debugf("[rke2configserver] %s/%s plan secret was %s", machineNamespace, machineName, planSecret) + if planSecret == "" { + continue + } + tokenSecret, watchable, err := capr.GetPlanServiceAccountTokenSecret(r.secrets, r.k8s, planSA) + if err != nil || tokenSecret == nil { + logrus.Debugf("[rke2configserver] %s/%s token secret for planSecret %s was nil or error received", machineNamespace, machineName, planSecret) + if err != nil { + logrus.Errorf("[rke2configserver] error encountered when searching for token secret for planSA %s/%s: %v", planSA.Namespace, planSA.Name, err) + } + if watchable { + logrus.Debugf("[rke2configserver] %s/%s token secret for planSecret %s is watchable, starting secret watch to wait for token to populate", machineNamespace, machineName, planSecret) + break + } + continue + } + logrus.Infof("[rke2configserver] %s/%s machineID: %s delivering planSecret %s with token secret %s/%s to system-agent from plan service account watch", machineNamespace, machineName, machineID, planSecret, tokenSecret.Namespace, tokenSecret.Name) + return planSecret, tokenSecret, nil + } + } + + if planSecret == "" || planSA == nil { + return "", nil, fmt.Errorf("could not start secret watch for token secret") + } + + logrus.Debugf("[rke2configserver] %s/%s starting token secret watch for planSA %s/%s", machineNamespace, machineName, planSA.Namespace, planSA.Name) + // start watch for the planSA corresponding secret, using a label selector. + respSecret, err := r.secrets.Watch(machineNamespace, metav1.ListOptions{ + LabelSelector: labels.Set{ + serviceaccounttoken.ServiceAccountSecretLabel: planSA.Name, + }.String(), + }) + if err != nil { + return "", nil, err + } + defer func() { + respSecret.Stop() + for range respSecret.ResultChan() { + } + }() + for event := range respSecret.ResultChan() { + if secret, ok := event.Object.(*corev1.Secret); ok { + logrus.Infof("[rke2configserver] %s/%s machineID: %s delivering planSecret %s with token secret %s/%s to system-agent from secret watch", machineNamespace, machineName, machineID, planSecret, secret.Namespace, secret.Name) + return planSecret, secret, nil + } + } + + return "", nil, fmt.Errorf("timeout waiting for plan") +} + +func (r *RKE2ConfigServer) setOrUpdateMachineID(machineNamespace, machineName, machineID string) error { + machine, err := r.machineCache.Get(machineNamespace, machineName) + if err != nil { + return err + } + + if machine.Labels[capr.MachineIDLabel] == machineID { + return nil + } + + machine = machine.DeepCopy() + if machine.Labels == nil { + machine.Labels = map[string]string{} + } + + machine.Labels[capr.MachineIDLabel] = machineID + _, err = r.machines.Update(machine) + logrus.Debugf("[rke2configserver] %s/%s updated machine ID to %s", machineNamespace, machineName, machineID) + return err +} + +func (r *RKE2ConfigServer) getMachinePlanSecret(ns, name string) (*v1.Secret, error) { + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 2, + Steps: 10, + Cap: 2 * time.Second, + } + var secret *v1.Secret + return secret, wait.ExponentialBackoff(backoff, func() (bool, error) { + var err error + secret, err = r.secretsCache.Get(name, ns) + if err != nil { + if !apierrors.IsNotFound(err) { + return false, err // hard error out if there's a problem + } + return false, nil // retry if secret not found + } + + if len(secret.Data) == 0 || string(secret.Data[capr.RolePlan]) == "" { + return false, nil // retry if no secret Data or plan, backoff and wait for the controller + } + + return true, nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer.go new file mode 100644 index 0000000..aa520f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer.go @@ -0,0 +1,193 @@ +package installer + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "os" + "strings" + + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + "github.com/rancher/rancher/pkg/tls" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +const ( + SystemAgentInstallPath = "/system-agent-install.sh" // corresponding curl -o in package/Dockerfile + WindowsRke2InstallPath = "/wins-agent-install.ps1" // corresponding curl -o in package/Dockerfile +) + +var ( + localAgentInstallScripts = []string{ + settings.UIPath.Get() + "/assets" + SystemAgentInstallPath, + "." + SystemAgentInstallPath, + } + localWindowsRke2InstallScripts = []string{ + settings.UIPath.Get() + "/assets" + WindowsRke2InstallPath, + "." + WindowsRke2InstallPath} +) + +func installScript(setting settings.Setting, files []string) ([]byte, error) { + if setting.Get() == setting.Default { + // no setting override, check for local file first + for _, f := range files { + script, err := ioutil.ReadFile(f) + if err != nil { + if !os.IsNotExist(err) { + logrus.Debugf("error pulling system agent installation script %s: %s", f, err) + } + continue + } + return script, err + } + logrus.Debugf("no local installation script found, moving on to url: %s", setting.Get()) + } + + resp, err := http.Get(setting.Get()) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return ioutil.ReadAll(resp.Body) +} + +func LinuxInstallScript(ctx context.Context, token string, envVars []corev1.EnvVar, defaultHost, _ string) ([]byte, error) { + data, err := installScript( + settings.SystemAgentInstallScript, + localAgentInstallScripts) + if err != nil { + return nil, err + } + binaryURL := "" + if settings.SystemAgentVersion.Get() != "" { + if settings.ServerURL.Get() != "" { + binaryURL = fmt.Sprintf("CATTLE_AGENT_BINARY_BASE_URL=\"%s/assets\"", settings.ServerURL.Get()) + } else if defaultHost != "" { + binaryURL = fmt.Sprintf("CATTLE_AGENT_BINARY_BASE_URL=\"https://%s/assets\"", defaultHost) + } + } + ca := systemtemplate.CAChecksum() + if v, ok := ctx.Value(tls.InternalAPI).(bool); ok && v { + ca = systemtemplate.InternalCAChecksum() + } + if ca != "" { + ca = "CATTLE_CA_CHECKSUM=\"" + ca + "\"" + } + if token != "" { + token = "CATTLE_ROLE_NONE=true\nCATTLE_TOKEN=\"" + token + "\"" + } + + // Merge the env vars with the AgentTLSModeStrict + found := false + for _, ev := range envVars { + if ev.Name == "STRICT_VERIFY" { + found = true // The user has specified `STRICT_VERIFY`, we should not attempt to overwrite it. + } + } + if !found { + if settings.AgentTLSMode.Get() == settings.AgentTLSModeStrict { + envVars = append(envVars, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "true", + }) + } else { + envVars = append(envVars, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "false", + }) + } + } + + envVarBuf := &strings.Builder{} + for _, envVar := range envVars { + if envVar.Value == "" { + continue + } + envVarBuf.WriteString(fmt.Sprintf("%s=\"%s\"\n", envVar.Name, envVar.Value)) + } + server := "" + if settings.ServerURL.Get() != "" { + server = fmt.Sprintf("CATTLE_SERVER=%s", settings.ServerURL.Get()) + } + return []byte(fmt.Sprintf(`#!/usr/bin/env sh +%s +%s +%s +%s +%s + +%s +`, envVarBuf.String(), binaryURL, server, ca, token, data)), nil +} + +func WindowsInstallScript(ctx context.Context, token string, envVars []corev1.EnvVar, defaultHost, dataDir string) ([]byte, error) { + data, err := installScript( + settings.WinsAgentInstallScript, + localWindowsRke2InstallScripts) + if err != nil { + return nil, err + } + + binaryURL := "" + if settings.WinsAgentVersion.Get() != "" { + if settings.ServerURL.Get() != "" { + binaryURL = fmt.Sprintf("$env:CATTLE_AGENT_BINARY_BASE_URL=\"%s/assets\"", settings.ServerURL.Get()) + } else if defaultHost != "" { + binaryURL = fmt.Sprintf("$env:CATTLE_AGENT_BINARY_BASE_URL=\"https://%s/assets\"", defaultHost) + } + } + + csiProxyURL := settings.CSIProxyAgentURL.Get() + csiProxyVersion := "v1.0.0" + if settings.CSIProxyAgentVersion.Get() != "" { + csiProxyVersion = settings.CSIProxyAgentVersion.Get() + if settings.ServerURL.Get() != "" { + csiProxyURL = fmt.Sprintf("%s/assets/csi-proxy-%%[1]s.tar.gz", settings.ServerURL.Get()) + } else if defaultHost != "" { + csiProxyURL = fmt.Sprintf("https://%s/assets/csi-proxy-%%[1]s.tar.gz", defaultHost) + } + } + + ca := systemtemplate.CAChecksum() + if v, ok := ctx.Value(tls.InternalAPI).(bool); ok && v { + ca = systemtemplate.InternalCAChecksum() + } + if ca != "" { + ca = "$env:CATTLE_CA_CHECKSUM=\"" + ca + "\"" + } + if token != "" { + token = "$env:CATTLE_ROLE_NONE=\"true\"\n$env:CATTLE_TOKEN=\"" + token + "\"" + } + envVarBuf := &strings.Builder{} + for _, envVar := range envVars { + if envVar.Value == "" { + continue + } + envVarBuf.WriteString(fmt.Sprintf("$env:%s=\"%s\"\n", envVar.Name, envVar.Value)) + } + server := "" + if settings.ServerURL.Get() != "" { + server = fmt.Sprintf("$env:CATTLE_SERVER=\"%s\"", settings.ServerURL.Get()) + } + + return []byte(fmt.Sprintf(`%s + +%s +%s +%s +%s +%s + +# Enables CSI Proxy +$env:CSI_PROXY_URL = "%s" +$env:CSI_PROXY_VERSION = "%s" +$env:CSI_PROXY_KUBELET_PATH = "C:%s/bin/kubelet.exe" + +Invoke-WinsInstaller @PSBoundParameters +exit 0 +`, data, envVarBuf.String(), binaryURL, server, ca, token, csiProxyURL, csiProxyVersion, dataDir)), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer_test.go new file mode 100644 index 0000000..27f195b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/installer_test.go @@ -0,0 +1,40 @@ +package installer + +import ( + "context" + "fmt" + "testing" + + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +func TestInstaller_WindowsInstallScript(t *testing.T) { + // arrange + CACert := "uibesrwguiobsdrujigbsduigbuidbg" + a := assert.New(t) + + // act + err := settings.ServerURL.Set("localhost") + a.Nil(err) + + err = settings.CACerts.Set(CACert) + a.Nil(err) + + CACertEncoded := systemtemplate.CAChecksum() + + script, err := WindowsInstallScript(context.TODO(), "test", []corev1.EnvVar{}, "localhost", "/var/lib/rancher/rke2") + + // assert + a.Nil(err) + a.NotNil(script) + a.Contains(string(script), "$env:CATTLE_TOKEN=\"test\"") + a.Contains(string(script), "$env:CATTLE_ROLE_NONE=\"true\"") + a.Contains(string(script), "$env:CATTLE_SERVER=\"localhost\"") + a.Contains(string(script), fmt.Sprintf("$env:CATTLE_CA_CHECKSUM=\"%s\"", CACertEncoded)) + a.Contains(string(script), "$env:CSI_PROXY_URL") + a.Contains(string(script), "$env:CSI_PROXY_VERSION") + a.Contains(string(script), "$env:CSI_PROXY_KUBELET_PATH") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server.go new file mode 100644 index 0000000..2dfa9ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server.go @@ -0,0 +1,28 @@ +package installer + +import ( + "net/http" +) + +type handler struct{} + +var Handler *handler + +func (s *handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + var err error + var content []byte + + switch req.URL.Path { + case SystemAgentInstallPath: + content, err = LinuxInstallScript(req.Context(), "", nil, req.Host, "") + case WindowsRke2InstallPath: + content, err = WindowsInstallScript(req.Context(), "", nil, req.Host, "") + } + + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + return + } + rw.Header().Set("Content-Type", "text/plain") + rw.Write(content) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server_test.go new file mode 100644 index 0000000..8b3539d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/installer/server_test.go @@ -0,0 +1,109 @@ +package installer + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" +) + +func TestHandler_ServeHTTP(t *testing.T) { + type scriptArgs struct { + path string + body string + } + tests := []struct { + name string + args scriptArgs + }{ + { + name: "Retrieve Linux script", + args: scriptArgs{ + path: "/system-agent-install.sh", + body: "#!/usr/bin/env sh", + }, + }, + { + name: "Retrieve Windows script", + args: scriptArgs{ + path: "/wins-agent-install.ps1", + body: "Invoke-WinsInstaller @PSBoundParameters", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + req, err := http.NewRequest(http.MethodGet, tt.args.path, nil) + a.Nil(err) + rr := httptest.NewRecorder() + handler := handler{} + + // act + err = settings.SystemAgentInstallScript.Set("https://raw.githubusercontent.com/rancher/system-agent/main/install.sh") + a.Nil(err) + err = settings.SystemAgentInstallerImage.Set("rancher/system-agent-installer-") + a.Nil(err) + + handler.ServeHTTP(rr, req) + + // assert + a.Equal(rr.Code, http.StatusOK) + a.Contains(rr.Body.String(), tt.args.body) + }) + } +} + +func TestHandler_ServeHTTPAirgap(t *testing.T) { + type scriptArgs struct { + path string + body string + } + tests := []struct { + name string + args scriptArgs + }{ + { + name: "Retrieve Linux script in mock airgap", + args: scriptArgs{ + path: "/system-agent-install.sh", + body: "#!/usr/bin/env sh", + }, + }, + { + name: "Retrieve Windows script in mock airgap", + args: scriptArgs{ + path: "/wins-agent-install.ps1", + body: "Invoke-WinsInstaller @PSBoundParameters", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + err := settings.SystemAgentInstallScript.Set("https://raw.githubusercontent.com/rancher/system-agent/main/install.sh") + a.Nil(err) + err = settings.SystemAgentInstallerImage.Set("rancher/system-agent-installer-") + a.Nil(err) + + req, err := http.NewRequest(http.MethodGet, tt.args.path, nil) + a.Nil(err) + rr := httptest.NewRecorder() + handler := handler{} + air := httptest.NewUnstartedServer(&handler) + + // act + air.Config.Handler.ServeHTTP(rr, req) + defer air.Config.Close() + + // assert + a.Equal(rr.Code, http.StatusOK) + a.Contains(rr.Body.String(), tt.args.body) + + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/agent.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/agent.go new file mode 100644 index 0000000..23e1cdf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/agent.go @@ -0,0 +1,41 @@ +package planner + +import ( + "fmt" + "sort" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/systemtemplate" +) + +// generateClusterAgentManifest generates a cluster agent manifest +func (p *Planner) generateClusterAgentManifest(controlPlane *rkev1.RKEControlPlane, entry *planEntry) ([]byte, error) { + if controlPlane.Spec.ManagementClusterName == "local" { + return nil, nil + } + + tokens, err := p.clusterRegistrationTokenCache.GetByIndex(clusterRegToken, controlPlane.Spec.ManagementClusterName) + if err != nil { + return nil, err + } + + if len(tokens) == 0 { + return nil, fmt.Errorf("no cluster registration token found") + } + + sort.Slice(tokens, func(i, j int) bool { + return tokens[i].Name < tokens[j].Name + }) + + mgmtCluster, err := p.managementClusters.Get(controlPlane.Spec.ManagementClusterName) + if err != nil { + return nil, err + } + + taints, err := getTaints(entry, controlPlane) + if err != nil { + return nil, err + } + + return systemtemplate.ForCluster(mgmtCluster, tokens[0].Status.Token, taints, p.secretCache) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation.go new file mode 100644 index 0000000..16b16d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation.go @@ -0,0 +1,282 @@ +package planner + +import ( + "fmt" + "path" + "strconv" + "strings" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/sirupsen/logrus" +) + +// rotateCertificates checks if there is a need to rotate any certificates and updates the plan accordingly. +func (p *Planner) rotateCertificates(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, clusterPlan *plan.Plan) (rkev1.RKEControlPlaneStatus, error) { + if !shouldRotate(controlPlane) { + return status, nil + } + + found, joinServer, _, err := p.findInitNode(controlPlane, clusterPlan) + if err != nil { + logrus.Errorf("[planner] rkecluster %s/%s: error encountered while searching for init node during certificate rotation: %v", controlPlane.Namespace, controlPlane.Name, err) + return status, err + } + if !found || joinServer == "" { + logrus.Warnf("[planner] rkecluster %s/%s: skipping certificate creation as cluster does not have an init node", controlPlane.Namespace, controlPlane.Name) + return status, nil + } + + for _, node := range collect(clusterPlan, anyRole) { + if !shouldRotateEntry(controlPlane.Spec.RotateCertificates, node) { + continue + } + + rotatePlan, joinedServer, err := p.rotateCertificatesPlan(controlPlane, tokensSecret, controlPlane.Spec.RotateCertificates, node, joinServer) + if err != nil { + return status, err + } + + err = assignAndCheckPlan(p.store, fmt.Sprintf("[%s] certificate rotation", node.Machine.Name), node, rotatePlan, joinedServer, 0, 0) + if err != nil { + // Ensure the CAPI cluster is paused if we have assigned and are checking a plan. + if pauseErr := p.pauseCAPICluster(controlPlane, true); pauseErr != nil { + return status, pauseErr + } + return status, err + } + } + + if err := p.pauseCAPICluster(controlPlane, false); err != nil { + return status, errWaiting("unpausing CAPI cluster") + } + + status.CertificateRotationGeneration = controlPlane.Spec.RotateCertificates.Generation + return status, errWaiting("certificate rotation done") +} + +// shouldRotate `true` if the cluster is ready and the generation is stale +func shouldRotate(cp *rkev1.RKEControlPlane) bool { + // if a spec is not defined there is nothing to do + if cp.Spec.RotateCertificates == nil { + return false + } + + // The controlplane must be initialized before we rotate anything + if cp.Status.Initialized != true { + logrus.Warnf("[planner] rkecluster %s/%s: skipping certificate rotation as cluster was not initialized", cp.Namespace, cp.Name) + return false + } + + // if this generation has already been applied there is no work + return cp.Status.CertificateRotationGeneration != cp.Spec.RotateCertificates.Generation +} + +// rotateCertificatesPlan rotates the certificates for the services specified, if any, and restarts the service. If no services are specified +// all certificates are rotated. +func (p *Planner) rotateCertificatesPlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, rotation *rkev1.RotateCertificates, entry *planEntry, joinServer string) (plan.NodePlan, string, error) { + if isOnlyWorker(entry) { + // Don't overwrite the joinURL annotation. + joinServer = "" + } + rotatePlan, config, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, entry, joinServer, true) + if err != nil { + return plan.NodePlan{}, joinedServer, err + } + + if isOnlyWorker(entry) { + rotatePlan.Instructions = append(rotatePlan.Instructions, idempotentRestartInstructions( + controlPlane, + "certificate-rotation/restart", + strconv.FormatInt(rotation.Generation, 10), + capr.GetRuntimeAgentUnit(controlPlane.Spec.KubernetesVersion))...) + return rotatePlan, joinedServer, nil + } + + args := []string{ + "certificate", + "rotate", + } + + if len(rotation.Services) > 0 { + for _, service := range rotation.Services { + args = append(args, "-s", service) + } + } + + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + + rotatePlan.Instructions = append(rotatePlan.Instructions, idempotentInstruction( + controlPlane, + "certificate-rotation/rotate", + strconv.FormatInt(rotation.Generation, 10), + capr.GetRuntime(controlPlane.Spec.KubernetesVersion), + args, + []string{}, + )) + if isControlPlane(entry) { + // The following kube-scheduler and kube-controller-manager certificates are self-signed by the respective services and are used by CAPR for secure healthz probes against the service. + if rotationContainsService(rotation, "controller-manager") { + if kcmCertDir := getArgValue(config[KubeControllerManagerArg], CertDirArgument, "="); kcmCertDir != "" && getArgValue(config[KubeControllerManagerArg], TLSCertFileArgument, "=") == "" { + rotatePlan.Instructions = append(rotatePlan.Instructions, []plan.OneTimeInstruction{ + idempotentInstruction( + controlPlane, + "certificate-rotation/rm-kcm-cert", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + fmt.Sprintf("%s/%s", kcmCertDir, DefaultKubeControllerManagerCert), + }, + []string{}, + ), + idempotentInstruction( + controlPlane, + "certificate-rotation/rm-kcm-key", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + fmt.Sprintf("%s/%s", kcmCertDir, strings.ReplaceAll(DefaultKubeControllerManagerCert, ".crt", ".key")), + }, + []string{}, + ), + }...) + if runtime == capr.RuntimeRKE2 { + rotatePlan.Instructions = append(rotatePlan.Instructions, idempotentInstruction( + controlPlane, + "certificate-rotation/rm-kcm-spm", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + path.Join(capr.GetDistroDataDir(controlPlane), "/agent/pod-manifests/kube-controller-manager.yaml"), + }, + []string{}, + )) + } + } + } + if rotationContainsService(rotation, "scheduler") { + if ksCertDir := getArgValue(config[KubeSchedulerArg], CertDirArgument, "="); ksCertDir != "" && getArgValue(config[KubeSchedulerArg], TLSCertFileArgument, "=") == "" { + rotatePlan.Instructions = append(rotatePlan.Instructions, []plan.OneTimeInstruction{ + idempotentInstruction( + controlPlane, + "certificate-rotation/rm-ks-cert", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + fmt.Sprintf("%s/%s", ksCertDir, DefaultKubeSchedulerCert), + }, + []string{}, + ), + idempotentInstruction( + controlPlane, + "certificate-rotation/rm-ks-key", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + fmt.Sprintf("%s/%s", ksCertDir, strings.ReplaceAll(DefaultKubeSchedulerCert, ".crt", ".key")), + }, + []string{}, + ), + }...) + if runtime == capr.RuntimeRKE2 { + rotatePlan.Instructions = append(rotatePlan.Instructions, idempotentInstruction( + controlPlane, + "certificate-rotation/rm-ks-spm", + strconv.FormatInt(rotation.Generation, 10), + "rm", + []string{ + "-f", + path.Join(capr.GetDistroDataDir(controlPlane), "agent/pod-manifests/kube-scheduler.yaml"), + }, + []string{}, + )) + } + } + } + } + if runtime == capr.RuntimeRKE2 { + if generated, instruction := generateManifestRemovalInstruction(controlPlane, entry); generated { + rotatePlan.Instructions = append(rotatePlan.Instructions, convertToIdempotentInstruction( + controlPlane, + "certificate-rotation/manifest-removal", + strconv.FormatInt(rotation.Generation, 10), + instruction)) + } + } + rotatePlan.Instructions = append(rotatePlan.Instructions, idempotentRestartInstructions( + controlPlane, + "certificate-rotation/restart", + strconv.FormatInt(rotation.Generation, 10), + capr.GetRuntimeServerUnit(controlPlane.Spec.KubernetesVersion))...) + return rotatePlan, joinedServer, nil +} + +// rotationContainsService searches the rotation.Services slice the specified service. If the length of the services slice is 0, it returns true. +func rotationContainsService(rotation *rkev1.RotateCertificates, service string) bool { + if rotation == nil { + return false + } + if len(rotation.Services) == 0 { + return true + } + for _, desiredService := range rotation.Services { + if desiredService == service { + return true + } + } + return false +} + +// shouldRotateEntry returns true if the rotated services are applicable to the entry's roles. +func shouldRotateEntry(rotation *rkev1.RotateCertificates, entry *planEntry) bool { + relevantServices := map[string]struct{}{} + + if len(rotation.Services) == 0 { + return true + } + + if isWorker(entry) { + relevantServices["rke2-server"] = struct{}{} + relevantServices["k3s-server"] = struct{}{} + relevantServices["api-server"] = struct{}{} + relevantServices["kubelet"] = struct{}{} + relevantServices["kube-proxy"] = struct{}{} + relevantServices["auth-proxy"] = struct{}{} + } + + if isControlPlane(entry) { + relevantServices["rke2-server"] = struct{}{} + relevantServices["k3s-server"] = struct{}{} + relevantServices["api-server"] = struct{}{} + relevantServices["kubelet"] = struct{}{} + relevantServices["kube-proxy"] = struct{}{} + relevantServices["auth-proxy"] = struct{}{} + relevantServices["controller-manager"] = struct{}{} + relevantServices["scheduler"] = struct{}{} + relevantServices["rke2-controller"] = struct{}{} + relevantServices["k3s-controller"] = struct{}{} + relevantServices["admin"] = struct{}{} + relevantServices["cloud-controller"] = struct{}{} + } + + if isEtcd(entry) { + relevantServices["etcd"] = struct{}{} + relevantServices["kubelet"] = struct{}{} + relevantServices["k3s-server"] = struct{}{} + relevantServices["rke2-server"] = struct{}{} + } + + for i := range rotation.Services { + if _, ok := relevantServices[rotation.Services[i]]; ok { + return true + } + } + + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation_test.go new file mode 100644 index 0000000..4e90aad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/certificaterotation_test.go @@ -0,0 +1,282 @@ +package planner + +import ( + "strconv" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/stretchr/testify/assert" +) + +func Test_shouldRotateEntry(t *testing.T) { + tests := []struct { + name string + services []string + rotateWorker bool + rotateControlPlane bool + rotateETCD bool + }{ + {name: "rke2-server", services: []string{"rke2-server"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: true}, + {name: "k3s-server", services: []string{"k3s-server"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: true}, + {name: "api-server", services: []string{"api-server"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: false}, + {name: "kubelet", services: []string{"kubelet"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: true}, + {name: "kube-proxy", services: []string{"kube-proxy"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: false}, + {name: "auth-proxy", services: []string{"auth-proxy"}, rotateWorker: true, rotateControlPlane: true, rotateETCD: false}, + {name: "controller-manager", services: []string{"controller-manager"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "scheduler", services: []string{"scheduler"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "rke2-controller", services: []string{"rke2-controller"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "k3s-controller", services: []string{"k3s-controller"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "admin", services: []string{"admin"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "cloud-controller", services: []string{"cloud-controller"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: false}, + {name: "etcd", services: []string{"etcd"}, rotateWorker: false, rotateControlPlane: false, rotateETCD: true}, + {name: "many", services: []string{"etcd", "cloud-controller"}, rotateWorker: false, rotateControlPlane: true, rotateETCD: true}, + {name: "none", services: []string{}, rotateWorker: true, rotateControlPlane: true, rotateETCD: true}, + } + + workerRoleEntry := &planEntry{Metadata: &plan.Metadata{Labels: map[string]string{capr.WorkerRoleLabel: "true"}}} + controlPlaneRoleEntry := &planEntry{Metadata: &plan.Metadata{Labels: map[string]string{capr.ControlPlaneRoleLabel: "true"}}} + etcdRoleEntry := &planEntry{Metadata: &plan.Metadata{Labels: map[string]string{capr.EtcdRoleLabel: "true"}}} + allRoleEntry := &planEntry{Metadata: &plan.Metadata{Labels: map[string]string{capr.WorkerRoleLabel: "true", capr.ControlPlaneRoleLabel: "true", capr.EtcdRoleLabel: "true"}}} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.rotateWorker, shouldRotateEntry(&rkev1.RotateCertificates{Services: tt.services}, workerRoleEntry)) + assert.Equal(t, tt.rotateControlPlane, shouldRotateEntry(&rkev1.RotateCertificates{Services: tt.services}, controlPlaneRoleEntry)) + assert.Equal(t, tt.rotateETCD, shouldRotateEntry(&rkev1.RotateCertificates{Services: tt.services}, etcdRoleEntry)) + assert.True(t, shouldRotateEntry(&rkev1.RotateCertificates{Services: tt.services}, allRoleEntry)) + }) + } +} + +func Test_rotateCertificatesPlan(t *testing.T) { + type expected struct { + otiIndex int + oti *plan.OneTimeInstruction + otiCount int + joinServer string + } + + genericSetup := func(mp *mockPlanner) { + mp.clusterRegistrationTokenCache.EXPECT().GetByIndex(clusterRegToken, "somecluster").Return([]*v3.ClusterRegistrationToken{{Status: v3.ClusterRegistrationTokenStatus{Token: "lol"}}}, nil) + mp.managementClusters.EXPECT().Get("somecluster").Return(&v3.Cluster{}, nil) + } + + tests := []struct { + name string + version string + setup func(mp *mockPlanner) + joinServer string + entryIsControlPlane bool + machineGlobalConfig *rkev1.GenericMap + expected expected + rotateCertificates *rkev1.RotateCertificates + }{ + { + name: "test KCM cert regeneration removal instruction contains K3s", + version: "v1.25.7+k3s1", + entryIsControlPlane: true, + joinServer: "my-magic-joinserver", + setup: genericSetup, + expected: expected{ + otiIndex: 1, + oti: &[]plan.OneTimeInstruction{idempotentInstruction( + createTestControlPlane("v1.25.7+k3s1"), + "certificate-rotation/rm-kcm-cert", + strconv.FormatInt(int64(0), 10), + "rm", + []string{ + "-f", + "/var/lib/rancher/k3s/server/tls/kube-controller-manager/kube-controller-manager.crt", + }, + []string{}, + )}[0], + otiCount: 7, + joinServer: "my-magic-joinserver", + }, + }, + { + name: "test KCM cert regeneration removal instruction contains RKE2", + version: "v1.25.7+rke2r1", + entryIsControlPlane: true, + joinServer: "my-magic-joinserver", + setup: genericSetup, + rotateCertificates: &rkev1.RotateCertificates{ + Generation: 244, + }, + expected: expected{ + otiIndex: 1, + oti: &[]plan.OneTimeInstruction{idempotentInstruction( + createTestControlPlane("v1.25.7+rke2r1"), + "certificate-rotation/rm-kcm-cert", + strconv.FormatInt(int64(244), 10), + "rm", + []string{ + "-f", + "/var/lib/rancher/rke2/server/tls/kube-controller-manager/kube-controller-manager.crt", + }, + []string{}, + )}[0], + otiCount: 10, // the extra removal instructions are for removing the static pod manifests for RKE2 + joinServer: "my-magic-joinserver", + }, + }, + { + name: "test KS cert regeneration removal instruction contains K3s", + version: "v1.25.7+k3s1", + entryIsControlPlane: true, + joinServer: "my-magic-joinserver", + setup: genericSetup, + expected: expected{ + otiIndex: 3, + oti: &[]plan.OneTimeInstruction{idempotentInstruction( + createTestControlPlane("v1.25.7+k3s1"), + "certificate-rotation/rm-ks-cert", + strconv.FormatInt(int64(0), 10), + "rm", + []string{ + "-f", + "/var/lib/rancher/k3s/server/tls/kube-scheduler/kube-scheduler.crt", + }, + []string{}, + )}[0], + otiCount: 7, + joinServer: "my-magic-joinserver", + }, + }, + { + name: "test KS cert regeneration removal instruction contains RKE2", + version: "v1.25.7+rke2r1", + entryIsControlPlane: true, + joinServer: "my-magic-joinserver", + setup: genericSetup, + expected: expected{ + otiIndex: 4, + oti: &[]plan.OneTimeInstruction{idempotentInstruction( + createTestControlPlane("v1.25.7+rke2r1"), + "certificate-rotation/rm-ks-cert", + strconv.FormatInt(int64(0), 10), + "rm", + []string{ + "-f", + "/var/lib/rancher/rke2/server/tls/kube-scheduler/kube-scheduler.crt", + }, + []string{}, + )}[0], + otiCount: 10, // the extra removal instructions are for removing the static pod manifests for RKE2 + joinServer: "my-magic-joinserver", + }, + }, + { + name: "test rke2 worker-only instruction", + version: "v1.25.7+rke2r1", + entryIsControlPlane: false, + joinServer: "my-magic-joinserver", + expected: expected{ + otiIndex: 1, + oti: &[]plan.OneTimeInstruction{idempotentRestartInstructions( + createTestControlPlane("v1.25.7+rke2r1"), + "certificate-rotation/restart", + strconv.FormatInt(int64(0), 10), + capr.GetRuntimeAgentUnit("v1.25.7+rke2r1"))[1]}[0], + otiCount: 2, + joinServer: "", + }, + }, + { + name: "test k3s worker-only instruction", + version: "v1.25.7+k3s1", + entryIsControlPlane: false, + joinServer: "my-magic-joinserver", + expected: expected{ + otiIndex: 1, + oti: &[]plan.OneTimeInstruction{idempotentRestartInstructions( + createTestControlPlane("v1.25.7+k3s1"), + "certificate-rotation/restart", + strconv.FormatInt(int64(0), 10), + capr.GetRuntimeAgentUnit("v1.25.7+k3s1"))[1]}[0], + otiCount: 2, + joinServer: "", + }, + }, + { + name: "test K3s kcm custom kube-controller-manager cert-dir instruction", + version: "v1.25.7+k3s1", + entryIsControlPlane: true, + joinServer: "my-magic-joinserver", + setup: genericSetup, + machineGlobalConfig: &rkev1.GenericMap{ + Data: map[string]interface{}{ + KubeControllerManagerArg: []any{"cert-dir=/mycustomdir"}, + }, + }, + expected: expected{ + otiIndex: 1, + oti: &[]plan.OneTimeInstruction{idempotentInstruction( + createTestControlPlane("v1.25.7+k3s1"), + "certificate-rotation/rm-kcm-cert", + strconv.FormatInt(int64(0), 10), + "rm", + []string{ + "-f", + "/mycustomdir/kube-controller-manager.crt", + }, + []string{}, + )}[0], + otiCount: 7, + joinServer: "my-magic-joinserver", + }, + }, + } + + for _, tt := range tests { + // copy test case for persistence in parallel runs + tt := tt + t.Run(tt.name, func(t *testing.T) { + mockPlanner := newMockPlanner(t, InfoFunctions{ + SystemAgentImage: func() string { return "system-agent" }, + ImageResolver: image.ResolveWithControlPlane, + }) + if tt.setup != nil { + tt.setup(mockPlanner) + } + controlPlane := createTestControlPlane(tt.version) + if tt.machineGlobalConfig != nil { + controlPlane.Spec.MachineGlobalConfig = *tt.machineGlobalConfig + } + controlPlane.Spec.ManagementClusterName = "somecluster" + controlPlane.Spec.RotateCertificates = &rkev1.RotateCertificates{} + if tt.rotateCertificates != nil { + controlPlane.Spec.RotateCertificates = tt.rotateCertificates + } else { + controlPlane.Spec.RotateCertificates = &rkev1.RotateCertificates{} + } + entry := createTestPlanEntry(capr.DefaultMachineOS) + if tt.entryIsControlPlane { + entry.Machine.Labels[capr.ControlPlaneRoleLabel] = "true" + entry.Metadata.Labels[capr.ControlPlaneRoleLabel] = "true" + } else { + // worker nodes ignore passed in join server and rely only on annotation + if entry.Metadata.Annotations == nil { + entry.Metadata.Annotations = map[string]string{} + } + entry.Metadata.Annotations[capr.JoinedToAnnotation] = tt.expected.joinServer + } + + ts := plan.Secret{ + ServerToken: "lol", + } + + np, joined, err := mockPlanner.planner.rotateCertificatesPlan(controlPlane, ts, controlPlane.Spec.RotateCertificates, entry, tt.joinServer) + if tt.expected.oti != nil { + assert.Equal(t, *tt.expected.oti, np.Instructions[tt.expected.otiIndex]) + } + assert.NoError(t, err) + assert.Equal(t, tt.expected.joinServer, joined) + assert.Equal(t, tt.expected.otiCount, len(np.Instructions)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/config.go new file mode 100644 index 0000000..2034aee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/config.go @@ -0,0 +1,662 @@ +package planner + +import ( + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "path" + "sort" + "strconv" + "strings" + + "github.com/rancher/norman/types/values" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/nodeconfig" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kv" + "github.com/rancher/wrangler/v3/pkg/yaml" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +// addEtcd mutates the given config map with etcd-specific configuration elements, and adds S3-related arguments and files if renderS3 is true. +func (p *Planner) addETCD(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane, entry *planEntry, renderS3 bool) (result []plan.File, _ error) { + if !isEtcd(entry) || controlPlane.Spec.ETCD == nil { + return nil, nil + } + + if controlPlane.Spec.ETCD.DisableSnapshots { + config["etcd-disable-snapshots"] = true + } + if controlPlane.Spec.ETCD.SnapshotRetention > 0 { + config["etcd-snapshot-retention"] = controlPlane.Spec.ETCD.SnapshotRetention + } + if controlPlane.Spec.ETCD.SnapshotScheduleCron != "" { + config["etcd-snapshot-schedule-cron"] = controlPlane.Spec.ETCD.SnapshotScheduleCron + } + + if renderS3 { + args, _, files, err := p.etcdS3Args.ToArgs(controlPlane.Spec.ETCD.S3, controlPlane, "etcd-", false) + if err != nil { + return nil, err + } + for _, arg := range args { + k, v := kv.Split(arg, "=") + k = strings.TrimPrefix(k, "--") + if v == "" { + config[k] = true + } else { + config[k] = v + } + } + result = files + } + + return +} + +func addDefaults(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane) { + if capr.GetRuntime(controlPlane.Spec.KubernetesVersion) == capr.RuntimeRKE2 { + config["cni"] = "calico" + } +} + +func addUserConfig(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane, entry *planEntry) error { + for k, v := range controlPlane.Spec.MachineGlobalConfig.Data { + config[k] = v + } + + for _, opts := range controlPlane.Spec.MachineSelectorConfig { + sel, err := metav1.LabelSelectorAsSelector(opts.MachineLabelSelector) + if err != nil { + return err + } + if opts.MachineLabelSelector == nil || sel.Matches(labels.Set(entry.Machine.Labels)) { + for k, v := range opts.Config.Data { + config[k] = v + } + } + } + + filterConfigData(config, controlPlane, entry) + + // "data-dir" is explicitly not added to KDM for filtering because it is mapped to a field in the provisioning cluster + // CRD. While technically possible to add feature gates and update KDM, there is nothing to be gained from such an + // approach as the "data-dir" implementation will likely never change distro-side. + if controlPlane.Spec.DataDirectories.K8sDistro != "" { + config["data-dir"] = controlPlane.Spec.DataDirectories.K8sDistro + } + + return nil +} + +// addRoleConfig adds the role config to the passed in map, and returns the join server that the config was rendered for. +// It will return "-" as the join server if the entry is an init node (the init node should not join a server) +func addRoleConfig(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane, entry *planEntry, joinServer string) string { + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + if isInitNode(entry) { + // If this node is the init node, it should not be joined to anything. Clear the joinServer URL. + if runtime == capr.RuntimeK3S { + config["cluster-init"] = true + } + joinServer = "-" + } else if joinServer == "" { + // If no join server was specified, use the join server annotation for the node. + var ok bool + joinServer, ok = entry.Metadata.Annotations[capr.JoinedToAnnotation] + if !ok { + return capr.JoinServerImplausible + } + } + + if joinServer != "" && joinServer != "-" { + // it's very important that the joinServer param isn't used on the initNode. The init node is special + // because it will be evaluated twice, first with joinServer = "" and then with joinServer == self. + // If we use the joinServer param then we will get different nodePlan and cause issues. + config["server"] = joinServer + } + + if IsOnlyEtcd(entry) { + config["disable-scheduler"] = true + config["disable-apiserver"] = true + config["disable-controller-manager"] = true + } else if isOnlyControlPlane(entry) { + config["disable-etcd"] = true + } + + if pr := image.GetPrivateRepoURLFromControlPlane(controlPlane); pr != "" && !isOnlyWorker(entry) { + config["system-default-registry"] = pr + } + + // If this is a control-plane node, then we need to set arguments/(and for RKE2, volume mounts) to allow probes + // to run. + if isControlPlane(entry) { + logrus.Debug("addRoleConfig rendering arguments and mounts for kube-controller-manager") + certDirArg, certDirMount := renderArgAndMount(config[KubeControllerManagerArg], config[KubeControllerManagerExtraMount], controlPlane, DefaultKubeControllerManagerDefaultSecurePort, DefaultKubeControllerManagerCertDir) + config[KubeControllerManagerArg] = certDirArg + if runtime == capr.RuntimeRKE2 { + config[KubeControllerManagerExtraMount] = certDirMount + } + + logrus.Debug("addRoleConfig rendering arguments and mounts for kube-scheduler") + certDirArg, certDirMount = renderArgAndMount(config[KubeSchedulerArg], config[KubeSchedulerExtraMount], controlPlane, DefaultKubeSchedulerDefaultSecurePort, DefaultKubeSchedulerCertDir) + config[KubeSchedulerArg] = certDirArg + if runtime == capr.RuntimeRKE2 { + config[KubeSchedulerExtraMount] = certDirMount + } + } + + if nodeName := entry.Metadata.Labels[capr.NodeNameLabel]; nodeName != "" { + config["node-name"] = nodeName + } + return joinServer +} + +func addLocalClusterAuthenticationEndpointConfig(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane, entry *planEntry) { + if isOnlyWorker(entry) || !controlPlane.Spec.LocalClusterAuthEndpoint.Enabled { + return + } + + authFile := path.Join(capr.GetDistroDataDir(controlPlane), authnWebhookFileName) + config["kube-apiserver-arg"] = append(convert.ToStringSlice(config["kube-apiserver-arg"]), + fmt.Sprintf("authentication-token-webhook-config-file=%s", authFile)) +} + +func addLocalClusterAuthenticationEndpointFile(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry) plan.NodePlan { + if isOnlyWorker(entry) || !controlPlane.Spec.LocalClusterAuthEndpoint.Enabled { + return nodePlan + } + + loopbackAddress := capr.GetLoopbackAddress(controlPlane) + authFile := path.Join(capr.GetDistroDataDir(controlPlane), authnWebhookFileName) + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf(AuthnWebhook, loopbackAddress))), + Path: authFile, + }) + + return nodePlan +} + +func (p *Planner) addManifests(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry) (plan.NodePlan, error) { + files, err := p.getControlPlaneManifests(controlPlane, entry) + if err != nil { + return nodePlan, err + } + nodePlan.Files = append(nodePlan.Files, files...) + + return nodePlan, nil +} + +func isVSphereProvider(controlPlane *rkev1.RKEControlPlane, entry *planEntry) (bool, error) { + data := map[string]interface{}{} + if err := addUserConfig(data, controlPlane, entry); err != nil { + return false, err + } + return data["cloud-provider-name"] == "rancher-vsphere", nil +} + +func addVSphereCharts(controlPlane *rkev1.RKEControlPlane, entry *planEntry) (map[string]interface{}, error) { + if isVSphere, err := isVSphereProvider(controlPlane, entry); err != nil { + return nil, err + } else if isVSphere && controlPlane.Spec.ChartValues.Data["rancher-vsphere-csi"] == nil { + // ensure we have this chart config so that the global.cattle.clusterId is set + newData := controlPlane.Spec.ChartValues.DeepCopy() + if newData.Data == nil { + newData.Data = map[string]interface{}{} + } + newData.Data["rancher-vsphere-csi"] = map[string]interface{}{} + return newData.Data, nil + } + + return controlPlane.Spec.ChartValues.Data, nil +} + +type helmChartConfig struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec helmChartConfigSpec `json:"spec,omitempty"` +} + +type helmChartConfigSpec struct { + ValuesContent string `json:"valuesContent,omitempty"` +} + +func (h *helmChartConfig) DeepCopyObject() runtime.Object { + panic("unsupported") +} + +func (p *Planner) addChartConfigs(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry) (plan.NodePlan, error) { + if isOnlyWorker(entry) { + return nodePlan, nil + } + + chartValues, err := addVSphereCharts(controlPlane, entry) + if err != nil { + return nodePlan, err + } + + var chartConfigs []runtime.Object + for _, chart := range capr.SortedKeys(chartValues) { + valuesMap := convert.ToMapInterface(chartValues[chart]) + if valuesMap == nil { + valuesMap = map[string]interface{}{} + } + data.PutValue(valuesMap, controlPlane.Spec.ManagementClusterName, "global", "cattle", "clusterId") + + data, err := json.Marshal(valuesMap) + if err != nil { + return plan.NodePlan{}, err + } + + chartConfigs = append(chartConfigs, &helmChartConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "HelmChartConfig", + APIVersion: "helm.cattle.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: chart, + Namespace: "kube-system", + }, + Spec: helmChartConfigSpec{ + ValuesContent: string(data), + }, + }) + } + contents, err := yaml.ToBytes(chartConfigs) + if err != nil { + return plan.NodePlan{}, err + } + + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString(contents), + Path: path.Join(capr.GetDistroDataDir(controlPlane), "server/manifests/rancher/managed-chart-config.yaml"), + Dynamic: true, + }) + + return nodePlan, nil +} + +func addOtherFiles(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry) (plan.NodePlan, error) { + nodePlan = addLocalClusterAuthenticationEndpointFile(nodePlan, controlPlane, entry) + return nodePlan, nil +} + +func restartStamp(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, image string) string { + restartStamp := sha256.New() + restartStamp.Write([]byte(strconv.Itoa(controlPlane.Spec.ProvisionGeneration))) + restartStamp.Write([]byte(image)) + for _, file := range nodePlan.Files { + if file.Dynamic { + continue + } + restartStamp.Write([]byte(file.Path)) + restartStamp.Write([]byte(file.Content)) + } + restartStamp.Write([]byte(strconv.FormatInt(controlPlane.Status.ConfigGeneration, 10))) + return hex.EncodeToString(restartStamp.Sum(nil)) +} + +func addToken(config map[string]interface{}, entry *planEntry, tokensSecret plan.Secret) { + if tokensSecret.ServerToken == "" { + return + } + if isOnlyWorker(entry) { + config["token"] = tokensSecret.AgentToken + } else { + config["token"] = tokensSecret.ServerToken + config["agent-token"] = tokensSecret.AgentToken + } +} + +func addAddresses(secrets corecontrollers.SecretCache, config map[string]interface{}, entry *planEntry) error { + internalIPAddress := entry.Metadata.Annotations[capr.InternalAddressAnnotation] + ipAddress := entry.Metadata.Annotations[capr.AddressAnnotation] + internalAddressProvided, addressProvided := internalIPAddress != "", ipAddress != "" + + // If this is a provisioned node (not a custom node), then get the IP addresses from the machine driver config. + if entry.Machine.Spec.InfrastructureRef.APIVersion == capr.RKEMachineAPIVersion && (!internalAddressProvided || !addressProvided) { + secret, err := secrets.Get(entry.Machine.Spec.InfrastructureRef.Namespace, capr.MachineStateSecretName(entry.Machine.Spec.InfrastructureRef.Name)) + if apierrors.IsNotFound(err) || (secret != nil && len(secret.Data["extractedConfig"]) == 0) { + return errIgnore(fmt.Sprintf("waiting for machine %s/%s driver config to be saved", entry.Machine.Namespace, entry.Machine.Name)) + } else if err != nil { + return fmt.Errorf("error getting machine state secret for machine %s/%s: %w", entry.Machine.Namespace, entry.Machine.Name, err) + } + + driverConfig, err := nodeconfig.ExtractConfigJSON(base64.StdEncoding.EncodeToString(secret.Data["extractedConfig"])) + if err != nil || len(driverConfig) == 0 { + return fmt.Errorf("error getting machine state JSON for machine %s/%s: %w", entry.Machine.Namespace, entry.Machine.Name, err) + } + + if !addressProvided { + ipAddress = convert.ToString(values.GetValueN(driverConfig, "Driver", "IPAddress")) + } + if !internalAddressProvided { + internalIPAddress = convert.ToString(values.GetValueN(driverConfig, "Driver", "PrivateIPAddress")) + } + } + + setNodeExternalIP := ipAddress != "" && internalIPAddress != "" && ipAddress != internalIPAddress + + if setNodeExternalIP && !isOnlyWorker(entry) { + config["advertise-address"] = internalIPAddress + config["tls-san"] = append(convert.ToStringSlice(config["tls-san"]), ipAddress) + } + + if internalIPAddress != "" { + config["node-ip"] = append(convert.ToStringSlice(config["node-ip"]), internalIPAddress) + } + + // Cloud provider, if set, will handle external IP + if convert.ToString(config["cloud-provider-name"]) == "" && (addressProvided || setNodeExternalIP) { + config["node-external-ip"] = append(convert.ToStringSlice(config["node-external-ip"]), ipAddress) + } + + return nil +} + +func addLabels(config map[string]interface{}, entry *planEntry) error { + var labels []string + if data := entry.Metadata.Annotations[capr.LabelsAnnotation]; data != "" { + labelMap := map[string]string{} + if err := json.Unmarshal([]byte(data), &labelMap); err != nil { + return err + } + for k, v := range labelMap { + labels = append(labels, fmt.Sprintf("%s=%s", k, v)) + } + } + + labels = append(labels, capr.MachineUIDLabel+"="+string(entry.Machine.UID)) + sort.Strings(labels) + if len(labels) > 0 { + config["node-label"] = labels + } + return nil +} + +func addTaints(config map[string]interface{}, entry *planEntry, cp *rkev1.RKEControlPlane) error { + var ( + taintString []string + ) + + taints, err := getTaints(entry, cp) + if err != nil { + return err + } + + for _, taint := range taints { + if taint.Key != "" { + taintString = append(taintString, taint.ToString()) + } + } + + sort.Strings(taintString) + config["node-taint"] = taintString + + return nil +} + +// retrieveClusterAuthorizedSecret accepts a secret and a cluster name, and checks if a cluster is authorized to use the secret +// by looking at the 'v2prov-secret-authorized-for-cluster' annotation and determining if it is equal to the cluster name. +// if the cluster is authorized to use the secret, the contents of the 'credential' key are returned as a byte slice +func retrieveClusterAuthorizedSecret(secret *v1.Secret, clusterName string) ([]byte, error) { + authorized, ownerFound := clusterObjectAuthorized(secret, secretmigrator.AuthorizedSecretAnnotation, clusterName) + if !ownerFound || !authorized { + return nil, fmt.Errorf("the secret 'secret://%s:%s' provided within the cloud-provider-config does not belong to cluster '%s'", secret.Namespace, secret.Name, clusterName) + } + + secretContent, configFound := secret.Data["credential"] + if !configFound { + return nil, fmt.Errorf("the cloud-provider-config specified a secret, but no config could be found within the secret 'secret://%s:%s'", secret.Namespace, secret.Name) + } + return secretContent, nil +} + +// clusterObjectAuthorized accepts any object, and inspects the metadata.Annotations of the object for the specified annotation +// and determines if the object has authorized the cluster to access it. It returns two booleans, the first being whether the +// cluster is authorized to access the object and the second being whether the annotation and a corresponding value were found +// on the object +func clusterObjectAuthorized(obj runtime.Object, annotation, clusterName string) (bool, bool) { + annotationValueFound := false + if obj == nil || annotation == "" || clusterName == "" { + return false, annotationValueFound + } + copiedObj := obj.DeepCopyObject() + if objMeta, err := meta.Accessor(copiedObj); err == nil && objMeta != nil { + authorizedClusters := strings.Split(objMeta.GetAnnotations()[annotation], ",") + if len(authorizedClusters) > 0 { + annotationValueFound = true + } + for _, authorizedCluster := range authorizedClusters { + if clusterName == authorizedCluster { + return true, annotationValueFound + } + } + } + return false, annotationValueFound +} + +func checkForSecretFormat(secretFieldName, configValue string) (bool, string, string, error) { + if strings.HasPrefix(configValue, "secret://") { + configValue = strings.ReplaceAll(configValue, "secret://", "") + namespaceAndName := strings.Split(configValue, ":") + if len(namespaceAndName) != 2 || namespaceAndName[0] == "" || namespaceAndName[1] == "" { + return true, "", "", fmt.Errorf("provided value for %s secret is malformed, must be of the format secret://namespace:name", secretFieldName) + } + return true, namespaceAndName[0], namespaceAndName[1], nil + } + return false, "", "", nil +} + +// configFile renders the full path to a config file based on the passed in filename and controlPlane +// If the desired filename does not have a defined path template in the `filePaths` map, the function will fall back +// to rendering a filepath based on `%s/etc/config-files/%s` where the first %s is the data-dir and +// second %s is the filename. +func configFile(controlPlane *rkev1.RKEControlPlane, filename string) string { + if path := filePaths[filename]; path != "" { + if strings.Contains(path, "%s") { + return fmt.Sprintf(path, capr.GetRuntime(controlPlane.Spec.KubernetesVersion)) + } + return path + } + return path.Join(capr.GetDistroDataDir(controlPlane), "etc/config-files", filename) +} + +func (p *Planner) renderFiles(controlPlane *rkev1.RKEControlPlane, entry *planEntry) ([]plan.File, error) { + var files []plan.File + for _, msf := range controlPlane.Spec.MachineSelectorFiles { + sel, err := metav1.LabelSelectorAsSelector(msf.MachineLabelSelector) + if err != nil { + return files, err + } + if msf.MachineLabelSelector != nil && !sel.Matches(labels.Set(entry.Machine.Labels)) { + continue + } + for _, fs := range msf.FileSources { + if fs.Secret.Name != "" && fs.ConfigMap.Name != "" { + return files, fmt.Errorf("secret %s/%s and configmap %s/%s cannot both be defined at the same time for files, use separate entries", controlPlane.Namespace, fs.Secret.Name, controlPlane.Namespace, fs.ConfigMap.Name) + } + if fs.Secret.Name != "" { + // retrieve secret and auth then use contents + secret, err := p.secretCache.Get(controlPlane.Namespace, fs.Secret.Name) + if err != nil { + return files, fmt.Errorf("error retrieving secret %s/%s while rendering files: %v", controlPlane.Namespace, fs.Secret.Name, err) + } + if authorized, found := clusterObjectAuthorized(secret, capr.AuthorizedObjectAnnotation, controlPlane.Name); authorized && found { + for _, v := range fs.Secret.Items { + file := plan.File{ + Path: v.Path, + Content: base64.StdEncoding.EncodeToString(secret.Data[v.Key]), + Dynamic: v.Dynamic, + } + hash := sha256.Sum256(secret.Data[v.Key]) + if v.Hash != "" && v.Hash != base64.StdEncoding.EncodeToString(hash[:]) { + return files, fmt.Errorf("secret %s does not cotain the expected content", secret.Name) + } + if v.Permissions != "" { + file.Permissions = v.Permissions + } else if fs.Secret.DefaultPermissions != "" { + file.Permissions = fs.Secret.DefaultPermissions + } + files = append(files, file) + } + } else { + return files, fmt.Errorf("error rendering files: cluster %s/%s was not authorized to access secret %s/%s", controlPlane.Namespace, controlPlane.Name, controlPlane.Namespace, fs.Secret.Name) + } + } + if fs.ConfigMap.Name != "" { + configmap, err := p.configMapCache.Get(controlPlane.Namespace, fs.ConfigMap.Name) + if err != nil { + return files, fmt.Errorf("error retrieving configmap %s/%s while rendering files: %v", controlPlane.Namespace, fs.ConfigMap.Name, err) + } + // retrieve configmap and use contents + if authorized, found := clusterObjectAuthorized(configmap, capr.AuthorizedObjectAnnotation, controlPlane.Name); authorized && found { + for _, v := range fs.ConfigMap.Items { + file := plan.File{ + Path: v.Path, + Content: base64.StdEncoding.EncodeToString([]byte(configmap.Data[v.Key])), + Dynamic: v.Dynamic, + } + hash := sha256.Sum256([]byte(configmap.Data[v.Key])) + if v.Hash != "" && v.Hash != base64.StdEncoding.EncodeToString(hash[:]) { + return files, fmt.Errorf("configmap %s does not cotain the expected content", configmap.Name) + } + if v.Permissions != "" { + file.Permissions = v.Permissions + } else if fs.ConfigMap.DefaultPermissions != "" { + file.Permissions = fs.ConfigMap.DefaultPermissions + } + files = append(files, file) + } + } else { + return files, fmt.Errorf("error rendering files: cluster %s/%s was not authorized to access configmap %s/%s", controlPlane.Namespace, controlPlane.Name, controlPlane.Namespace, fs.ConfigMap.Name) + } + } + } + } + return files, nil +} + +// addConfigFile will render the distribution configuration file and add it to the nodePlan. It also renders files that +// are referenced in the distribution configuration file (for example, ACE and the cloud-provider). It returns the updated +// NodePlan, the config that was rendered in a map, the joined server, and an error if one exists. +// NOTE: the joined server can be "-" if the config file is being added for the init node. +func (p *Planner) addConfigFile(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry, tokensSecret plan.Secret, + joinServer string, reg registries, renderS3 bool) (plan.NodePlan, map[string]interface{}, string, error) { + config := map[string]interface{}{} + + addDefaults(config, controlPlane) + + // Must call addUserConfig first because it will filter out non-kdm data + if err := addUserConfig(config, controlPlane, entry); err != nil { + return nodePlan, config, "", err + } + + files, err := p.addETCD(config, controlPlane, entry, renderS3) + if err != nil { + return nodePlan, config, "", err + } + nodePlan.Files = append(nodePlan.Files, files...) + + joinedServer := addRoleConfig(config, controlPlane, entry, joinServer) + if joinedServer == capr.JoinServerImplausible { + return nodePlan, config, "", fmt.Errorf("implausible joined server for entry") + } + + addLocalClusterAuthenticationEndpointConfig(config, controlPlane, entry) + addToken(config, entry, tokensSecret) + + if err := addAddresses(p.secretCache, config, entry); err != nil { + return nodePlan, config, joinedServer, err + } + if err := addLabels(config, entry); err != nil { + return nodePlan, config, joinedServer, err + } + if err := addTaints(config, entry, controlPlane); err != nil { + return nodePlan, config, joinedServer, err + } + + for _, fileParam := range fileParams { + var content interface{} + if fileParam == privateRegistryArg { + content = string(reg.registriesFileRaw) + } else { + var ok bool + content, ok = config[fileParam] + if !ok { + continue + } + } + + if fileParam == cloudProviderConfigArg { + isSecretFormat, namespace, name, err := checkForSecretFormat(cloudProviderConfigArg, convert.ToString(content)) + if err != nil { + // provided secret for cloud-provider-config does not follow the format of + // secret://namespace:name + return nodePlan, config, joinedServer, err + } + if isSecretFormat { + secret, err := p.secretCache.Get(namespace, name) + if err != nil { + return nodePlan, config, joinedServer, err + } + + secretContent, err := retrieveClusterAuthorizedSecret(secret, controlPlane.Name) + if err != nil { + return nodePlan, config, joinedServer, err + } + + filePath := configFile(controlPlane, fileParam) + config[fileParam] = filePath + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString(secretContent), + Path: filePath, + }) + continue + } + } + + filePath := configFile(controlPlane, fileParam) + config[fileParam] = filePath + + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(convert.ToString(content))), + Path: filePath, + }) + } + + files, err = p.renderFiles(controlPlane, entry) + if err != nil { + return nodePlan, config, joinedServer, err + } + + nodePlan.Files = append(nodePlan.Files, files...) + + PruneEmpty(config) + + configData, err := json.MarshalIndent(config, "", " ") + if err != nil { + return nodePlan, config, joinedServer, err + } + + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString(configData), + Path: fmt.Sprintf(ConfigYamlFileName, capr.GetRuntime(controlPlane.Spec.KubernetesVersion)), + }) + + return nodePlan, config, joinedServer, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/defaultplan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/defaultplan.go new file mode 100644 index 0000000..541344b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/defaultplan.go @@ -0,0 +1,33 @@ +package planner + +import ( + "encoding/base64" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" +) + +// commonNodePlan returns a "default" node plan with the corresponding registry configuration. +// It will append to the node plan passed in through options. +func (p *Planner) commonNodePlan(controlPlane *rkev1.RKEControlPlane, np plan.NodePlan) (plan.NodePlan, registries, error) { + if controlPlane.Spec.Registries == nil { + return np, registries{}, nil + } + + reg, err := p.renderRegistries(controlPlane) + if err != nil { + return plan.NodePlan{}, registries{}, err + } + + // Render the registries.yaml file for the rancher-system-agent. The registries.yaml file for the respective distribution should be rendered elsewhere + // (at config file rendering) + np.Files = append(np.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString(reg.registriesFileRaw), + Path: "/etc/rancher/agent/registries.yaml", + Dynamic: true, + }) + // Add the corresponding certificate files (if they exist) + np.Files = append(np.Files, reg.certificateFiles...) + + return np, reg, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/drain.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/drain.go new file mode 100644 index 0000000..b7767f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/drain.go @@ -0,0 +1,114 @@ +package planner + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/rancher/norman/types/convert" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/wrangler/v3/pkg/kv" +) + +func getRestartStamp(plan *plan.NodePlan) string { + for _, instr := range plan.Instructions { + for _, env := range instr.Env { + k, v := kv.Split(env, "=") + if k == "RESTART_STAMP" || + k == "$env:RESTART_STAMP" { + return v + } + } + } + return "" +} + +// shouldDrain determines whether the node should be drained based on the plans provided. If the oldPlan doesn't exist, +// then it will not be drained, otherwise, it compares the restart stamps to determine whether the engine will be restarted +func shouldDrain(oldPlan *plan.NodePlan, newPlan plan.NodePlan) bool { + if oldPlan == nil { + return false + } + return getRestartStamp(oldPlan) != getRestartStamp(&newPlan) +} + +func optionsToString(options rkev1.DrainOptions, disable bool) (string, error) { + if disable { + options.Enabled = false + } + // convert to map first for consistent ordering before creating the json string + opts, err := convert.EncodeToMap(options) + if err != nil { + return "", err + } + + data, err := json.Marshal(opts) + if err != nil { + return "", err + } + + return string(data), nil +} + +func (p *Planner) drain(oldPlan *plan.NodePlan, newPlan plan.NodePlan, entry *planEntry, clusterPlan *plan.Plan, options rkev1.DrainOptions) (bool, error) { + if entry == nil || entry.Metadata == nil || entry.Metadata.Annotations == nil || entry.Machine == nil || entry.Machine.Status.NodeRef == nil { + return true, nil + } + + // Short circuit if there is nothing to do, don't set annotations and move on + if (!options.Enabled || len(clusterPlan.Machines) == 1) && + len(options.PreDrainHooks) == 0 && + len(options.PostDrainHooks) == 0 { + return true, nil + } + + if !shouldDrain(oldPlan, newPlan) { + return true, nil + } + + // Don't drain a single node cluster, but still run the hooks + optionString, err := optionsToString(options, len(clusterPlan.Machines) == 1) + if err != nil { + return false, err + } + + if entry.Metadata.Annotations[capr.DrainAnnotation] != optionString { + entry.Metadata.Annotations[capr.DrainAnnotation] = optionString + return false, p.store.updatePlanSecretLabelsAndAnnotations(entry) + } + + if err := checkForDrainError(entry, "draining"); err != nil { + // This is the only place true and an error is returned to indicate that draining is ongoing, but there is an error. + return true, err + } + + return entry.Metadata.Annotations[capr.DrainDoneAnnotation] == optionString, nil +} + +func (p *Planner) undrain(entry *planEntry) (bool, error) { + if entry.Metadata.Annotations[capr.DrainAnnotation] != "" && + entry.Metadata.Annotations[capr.DrainAnnotation] != entry.Metadata.Annotations[capr.UnCordonAnnotation] { + entry.Metadata.Annotations[capr.UnCordonAnnotation] = entry.Metadata.Annotations[capr.DrainAnnotation] + return false, p.store.updatePlanSecretLabelsAndAnnotations(entry) + } + + if err := checkForDrainError(entry, "undraining"); err != nil { + // This is the only place true and an error is returned to indicate that undraining is ongoing, but there is an error. + return true, err + } + + // The annotations will be removed when undrain is done + return entry.Metadata.Annotations[capr.UnCordonAnnotation] == "", nil +} + +// checkForDrainError checks if there is an error in the drain annotations. It ignores errors that contain "error trying to reach service" +// because these indicate that the cluster is not reachable because the node is restarting or the cattle-cluster-agent is getting rescheduled. +// These errors are expected during draining and it is not necessary to alert the user about them. +func checkForDrainError(entry *planEntry, drainStep string) error { + if errStr := entry.Metadata.Annotations[capr.DrainErrorAnnotation]; errStr != "" && !strings.Contains(errStr, "error trying to reach service") { + return fmt.Errorf("error %s machine %s: %s", drainStep, entry.Machine.Name, errStr) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/encryptionkeyrotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/encryptionkeyrotation.go new file mode 100644 index 0000000..544d046 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/encryptionkeyrotation.go @@ -0,0 +1,759 @@ +package planner + +import ( + "encoding/base64" + "fmt" + "path" + "strconv" + "strings" + + "github.com/blang/semver" + "github.com/pkg/errors" + "github.com/rancher/channelserver/pkg/model" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/equality" +) + +const ( + encryptionKeyRotationStageReencryptRequest = "reencrypt_request" + encryptionKeyRotationStageReencryptActive = "reencrypt_active" + encryptionKeyRotationStageReencryptFinished = "reencrypt_finished" + + encryptionKeyRotationCommandPrepare = "prepare" + encryptionKeyRotationCommandRotate = "rotate" + encryptionKeyRotationCommandReencrypt = "reencrypt" + + encryptionKeyRotationSecretsEncryptStatusCommand = "secrets-encrypt-status" + + encryptionKeyRotationBinPrefix = "capr/encryption-key-rotation/bin" + + encryptionKeyRotationWaitForSystemctlStatusPath = "wait_for_systemctl_status.sh" + encryptionKeyRotationWaitForSecretsEncryptStatusPath = "wait_for_secrets_encrypt_status.sh" + encryptionKeyRotationSecretsEncryptStatusPath = "secrets_encrypt_status.sh" + + encryptionKeyRotationWaitForSystemctlStatus = ` +#!/bin/sh + +runtimeServer=$1 +i=0 + +while [ $i -lt 30 ]; do + systemctl is-active $runtimeServer + if [ $? -eq 0 ]; then + exit 0 + fi + sleep 10 + i=$((i + 1)) +done +exit 1 +` + + encryptionKeyRotationWaitForSecretsEncryptStatusScript = ` +#!/bin/sh + +runtime=$1 +i=0 + +while [ $i -lt 10 ]; do + $runtime secrets-encrypt status + if [ $? -eq 0 ]; then + exit 0 + fi + sleep 10 + i=$((i + 1)) +done +exit 1 +` + + encryptionKeyRotationSecretsEncryptStatusScript = ` +#!/bin/sh + +runtime=$1 +i=0 + +while [ $i -lt 10 ]; do + output="$($runtime secrets-encrypt status)" + if [ $? -eq 0 ]; then + if [ -n "$2" ]; then + echo $output | grep -q "$2" + if [ $? -eq 0 ]; then + exit 0 + fi + else + exit 0 + fi + fi + sleep 10 + i=$((i + 1)) +done +exit 1 +` + + encryptionKeyRotationEndpointEnv = "CONTAINER_RUNTIME_ENDPOINT=unix:///var/run/k3s/containerd/containerd.sock" +) + +func (p *Planner) setEncryptionKeyRotateState(status rkev1.RKEControlPlaneStatus, rotate *rkev1.RotateEncryptionKeys, phase rkev1.RotateEncryptionKeysPhase) (rkev1.RKEControlPlaneStatus, error) { + if equality.Semantic.DeepEqual(status.RotateEncryptionKeys, rotate) && equality.Semantic.DeepEqual(status.RotateEncryptionKeysPhase, phase) { + return status, nil + } + status.RotateEncryptionKeys = rotate + status.RotateEncryptionKeysPhase = phase + return status, errWaiting("refreshing encryption key rotation state") +} + +func (p *Planner) resetEncryptionKeyRotateState(status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + if status.RotateEncryptionKeys == nil && status.RotateEncryptionKeysPhase == "" { + return status, nil + } + return p.setEncryptionKeyRotateState(status, nil, "") +} + +// rotateEncryptionKeys first verifies that the control plane is in a state where the next step can be derived. If encryption key rotation is required, the corresponding phase and status fields will be set. +// The function is expected to be called multiple times throughout encryption key rotation, and will set the next corresponding phase based on previous output. +func (p *Planner) rotateEncryptionKeys(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, clusterPlan *plan.Plan, releaseData *model.Release) (rkev1.RKEControlPlaneStatus, error) { + if controlPlane == nil || releaseData == nil || clusterPlan == nil { + return status, fmt.Errorf("cannot pass nil parameters to rotateEncryptionKeys") + } + + if controlPlane.Spec.RotateEncryptionKeys == nil { + return p.resetEncryptionKeyRotateState(status) + } + + if supported, err := encryptionKeyRotationSupported(releaseData); err != nil { + return status, err + } else if !supported { + logrus.Debugf("rkecluster %s/%s: marking encryption key rotation phase as failed as it was not supported by version: %s", controlPlane.Namespace, controlPlane.Name, controlPlane.Spec.KubernetesVersion) + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhaseFailed) + } + + if !canRotateEncryptionKeys(controlPlane) { + return status, nil + } + + if !status.Initialized { + // cluster is not yet initialized, so return nil for now. + logrus.Warnf("[planner] rkecluster %s/%s: skipping encryption key rotation as cluster was not initialized", controlPlane.Namespace, controlPlane.Name) + return status, nil + } + + found, joinServer, initNode, err := p.findInitNode(controlPlane, clusterPlan) + if err != nil { + logrus.Errorf("[planner] rkecluster %s/%s: error encountered while searching for init node during encryption key rotation: %v", controlPlane.Namespace, controlPlane.Name, err) + return status, err + } + if !found || joinServer == "" { + logrus.Warnf("[planner] rkecluster %s/%s: skipping encryption key rotation as cluster does not have an init node", controlPlane.Namespace, controlPlane.Name) + return status, nil + } + + if shouldRestartEncryptionKeyRotation(controlPlane) { + logrus.Debugf("[planner] rkecluster %s/%s: starting/restarting encryption key rotation", controlPlane.Namespace, controlPlane.Name) + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhasePrepare) + } + + leader, err := p.encryptionKeyRotationFindLeader(status, clusterPlan, initNode) + if err != nil { + return status, err + } + + if status.RotateEncryptionKeysLeader != leader.Machine.Name { + status.RotateEncryptionKeysLeader = leader.Machine.Name + return status, errWaitingf("elected %s as control plane leader for encryption key rotation", leader.Machine.Name) + } + + logrus.Debugf("[planner] rkecluster %s/%s: current encryption key rotation phase: [%s]", controlPlane.Namespace, controlPlane.Spec.ClusterName, controlPlane.Status.RotateEncryptionKeysPhase) + + switch controlPlane.Status.RotateEncryptionKeysPhase { + case rkev1.RotateEncryptionKeysPhasePrepare: + if err := p.pauseCAPICluster(controlPlane, true); err != nil { + return status, errWaiting("pausing CAPI cluster") + } + status, err = p.encryptionKeyRotationLeaderPhaseReconcile(controlPlane, status, tokensSecret, joinServer, leader) + if err != nil { + return status, err + } + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhasePostPrepareRestart) + case rkev1.RotateEncryptionKeysPhasePostPrepareRestart: + status, err = p.encryptionKeyRotationRestartNodes(controlPlane, status, tokensSecret, clusterPlan, leader, initNode, joinServer) + if err != nil { + return status, err + } + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhaseRotate) + case rkev1.RotateEncryptionKeysPhaseRotate: + status, err = p.encryptionKeyRotationLeaderPhaseReconcile(controlPlane, status, tokensSecret, joinServer, leader) + if err != nil { + return status, err + } + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhasePostRotateRestart) + case rkev1.RotateEncryptionKeysPhasePostRotateRestart: + status, err = p.encryptionKeyRotationRestartNodes(controlPlane, status, tokensSecret, clusterPlan, leader, initNode, joinServer) + if err != nil { + return status, err + } + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhaseReencrypt) + case rkev1.RotateEncryptionKeysPhaseReencrypt: + status, err = p.encryptionKeyRotationLeaderPhaseReconcile(controlPlane, status, tokensSecret, joinServer, leader) + if err != nil { + return status, err + } + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhasePostReencryptRestart) + case rkev1.RotateEncryptionKeysPhasePostReencryptRestart: + status, err = p.encryptionKeyRotationRestartNodes(controlPlane, status, tokensSecret, clusterPlan, leader, initNode, joinServer) + if err != nil { + return status, err + } + if err = p.pauseCAPICluster(controlPlane, false); err != nil { + return status, errWaiting("unpausing CAPI cluster") + } + status.RotateEncryptionKeysLeader = "" + return p.setEncryptionKeyRotateState(status, controlPlane.Spec.RotateEncryptionKeys, rkev1.RotateEncryptionKeysPhaseDone) + } + + return status, fmt.Errorf("encountered unknown encryption key rotation phase: %s", controlPlane.Status.RotateEncryptionKeysPhase) +} + +// encryptionKeyRotationSupported returns a boolean indicating whether encryption key rotation is supported by the release, +// and an error if one was encountered. +func encryptionKeyRotationSupported(releaseData *model.Release) (bool, error) { + if releaseData == nil { + return false, fmt.Errorf("unable to find KDM release data for encryption key rotation support in release") + } + if featureVersion, ok := releaseData.FeatureVersions["encryption-key-rotation"]; ok { + version, err := semver.Make(featureVersion) + if err != nil { + return false, fmt.Errorf("unable to parse semver version for encryption key rotation: %s", featureVersion) + } + // v2.6.4 - v2.6.6 are looking for 1.x.x, but encryption key rotation does not work in those versions. Rather than + // enable it retroactively, those versions will not be able to rotate encryption keys since some cluster + // configurations can break in such a way that they become unrecoverable. Additionally, we want to be careful + // updating the encryption-key-rotation feature gate in KDM in the future, so as not to break backwards + // compatibility for existing clusters. + if version.Major == 2 { + return true, nil + } + } + return false, nil +} + +// canRotateEncryptionKeys returns false if the controlplane does not have a Ready: True condition and encryption key rotation is not already in progress, if the spec for +// encryption key rotation is nil, or if the spec has been reconciled but the phase is done or failed. +func canRotateEncryptionKeys(controlPlane *rkev1.RKEControlPlane) bool { + if (!capr.Ready.IsTrue(controlPlane) && !rotateEncryptionKeyInProgress(controlPlane)) || + controlPlane.Spec.RotateEncryptionKeys == nil || + (controlPlane.Status.RotateEncryptionKeys != nil && controlPlane.Status.RotateEncryptionKeys.Generation == controlPlane.Spec.RotateEncryptionKeys.Generation && + (controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseDone || controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseFailed)) { + return false + } + + return true +} + +// shouldRestartEncryptionKeyRotation returns `true` if encryption key rotation is necessary and the fields on the status object are not valid for an encryption key rotation procedure. +func shouldRestartEncryptionKeyRotation(controlPlane *rkev1.RKEControlPlane) bool { + if !capr.Ready.IsTrue(controlPlane) { + return false + } + if controlPlane.Spec.RotateEncryptionKeys.Generation > 0 && controlPlane.Status.RotateEncryptionKeys == nil { + return true + } + if (controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseDone || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseFailed || + controlPlane.Status.RotateEncryptionKeysPhase == "") && + controlPlane.Spec.RotateEncryptionKeys.Generation != controlPlane.Status.RotateEncryptionKeys.Generation { + return true + } + if !hasValidNonFailedRotateEncryptionKeyStatus(controlPlane) { + return true + } + return false +} + +// hasValidNonFailedRotateEncryptionKeyStatus verifies that the control plane encryption key status is an expected value and is not failed. +func hasValidNonFailedRotateEncryptionKeyStatus(controlPlane *rkev1.RKEControlPlane) bool { + return rotateEncryptionKeyInProgress(controlPlane) || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseDone +} + +// rotateEncryptionKeyInProgress returns true if the phase of the encryption key rotation indicates that rotation is in progress. +func rotateEncryptionKeyInProgress(controlPlane *rkev1.RKEControlPlane) bool { + return controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhasePrepare || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhasePostPrepareRestart || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseRotate || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhasePostRotateRestart || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseReencrypt || + controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhasePostReencryptRestart +} + +// encryptionKeyRotationFindLeader returns the current encryption rotation leader if it is valid, otherwise, if the +// phase is "prepare", it will re-elect a new leader. It will look for the init node, and if the init node is not valid +// (etcd-only), it will elect the first suitable control plane node. If the phase is not in "prepare" and a re-election +// of the leader is necessary, the phase will be set to failed as this is unexpected. +func (p *Planner) encryptionKeyRotationFindLeader(status rkev1.RKEControlPlaneStatus, clusterPlan *plan.Plan, init *planEntry) (*planEntry, error) { + machineName := status.RotateEncryptionKeysLeader + if machine, ok := clusterPlan.Machines[machineName]; ok { + entry := &planEntry{ + Machine: machine, + Plan: clusterPlan.Nodes[machineName], + Metadata: clusterPlan.Metadata[machineName], + } + if encryptionKeyRotationIsSuitableControlPlane(entry) { + return entry, nil + } + } + + if status.RotateEncryptionKeysPhase != rkev1.RotateEncryptionKeysPhasePrepare { + // if we are electing a leader and are not in the "prepare" phase, something is wrong. + return nil, fmt.Errorf("cannot elect control plane leader in phase %s", status.RotateEncryptionKeysPhase) + } + + leader := init + if !isControlPlane(init) { + machines := collect(clusterPlan, encryptionKeyRotationIsSuitableControlPlane) + if len(machines) == 0 { + return nil, fmt.Errorf("no suitable control plane nodes for encryption key rotation") + } + leader = machines[0] + } + + return leader, nil +} + +// encryptionKeyRotationIsSuitableControlPlane ensures that a control plane node has not been deleted and has a valid +// node associated with it. +func encryptionKeyRotationIsSuitableControlPlane(entry *planEntry) bool { + return isControlPlane(entry) && isNotDeleting(entry) && entry.Machine.Status.NodeRef != nil && capr.Ready.IsTrue(entry.Machine) +} + +// encryptionKeyRotationIsControlPlaneAndNotLeaderAndInit allows us to filter cluster plans to restart healthy follower nodes. +func encryptionKeyRotationIsControlPlaneAndNotLeaderAndInit(controlPlane *rkev1.RKEControlPlane) roleFilter { + return func(entry *planEntry) bool { + return isControlPlaneAndNotInitNode(entry) && + controlPlane.Status.RotateEncryptionKeysLeader != entry.Machine.Name + } +} + +// encryptionKeyRotationIsEtcdAndNotControlPlaneAndNotLeaderAndInit allows us to filter cluster plans to restart healthy follower nodes. +func encryptionKeyRotationIsEtcdAndNotControlPlaneAndNotLeaderAndInit(controlPlane *rkev1.RKEControlPlane) roleFilter { + return func(entry *planEntry) bool { + return isEtcd(entry) && !isControlPlane(entry) && + controlPlane.Status.RotateEncryptionKeysLeader != entry.Machine.Name && + !isInitNode(entry) + } +} + +// encryptionKeyRotationRestartNodes restarts the leader's server service, extracting the current stage afterwards. +// The followers (if any exist) are subsequently restarted. Notably, if the encryption key rotation leader is not the init node, +// it will restart the init node, then restart the encryption key rotation leader, +// then finalize walking through etcd nodes (that are not controlplane), then finally controlplane nodes. +func (p *Planner) encryptionKeyRotationRestartNodes(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, clusterPlan *plan.Plan, leader *planEntry, initNode *planEntry, joinServer string) (rkev1.RKEControlPlaneStatus, error) { + // in certain cases with multi-node setups, we must restart the init node before we can proceed to restarting the leader. + if !isInitNode(leader) { + logrus.Debugf("[planner] rkecluster %s/%s: leader %s was not the init node, finding and restarting etcd nodes", controlPlane.Namespace, controlPlane.Name, leader.Machine.Name) + + _, status, err := p.encryptionKeyRotationRestartService(controlPlane, status, tokensSecret, joinServer, initNode, false, "") + if err != nil { + return status, err + } + logrus.Debugf("[planner] rkecluster %s/%s: collecting etcd and not control plane", controlPlane.Namespace, controlPlane.Name) + for _, entry := range collect(clusterPlan, encryptionKeyRotationIsEtcdAndNotControlPlaneAndNotLeaderAndInit(controlPlane)) { + _, status, err = p.encryptionKeyRotationRestartService(controlPlane, status, tokensSecret, joinServer, entry, false, "") + if err != nil { + return status, err + } + } + } + + leaderStage, status, err := p.encryptionKeyRotationRestartService(controlPlane, status, tokensSecret, joinServer, leader, true, "") + if err != nil { + return status, err + } + + logrus.Debugf("[planner] rkecluster %s/%s: collecting control plane and not leader and init nodes", controlPlane.Namespace, controlPlane.Name) + for _, entry := range collect(clusterPlan, encryptionKeyRotationIsControlPlaneAndNotLeaderAndInit(controlPlane)) { + var stage string + stage, status, err = p.encryptionKeyRotationRestartService(controlPlane, status, tokensSecret, joinServer, entry, true, leaderStage) + if err != nil { + return status, err + } + + if stage != leaderStage { + // secrets-encrypt command was run on another node. this is considered a failure, but might be a bit too sensitive. to be tested. + return p.encryptionKeyRotationFailed(status, fmt.Errorf("leader [%s] with %s stage and follower [%s] with %s stage", leader.Machine.Status.NodeRef.Name, leaderStage, entry.Machine.Status.NodeRef.Name, stage)) + } + } + + return status, nil +} + +// encryptionKeyRotationRestartService restarts the server unit on the downstream node, waits until secrets-encrypt +// status can be successfully queried, and then gets the status. leaderStage is allowed to be empty if entry is the +// leader. +func (p *Planner) encryptionKeyRotationRestartService(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, joinServer string, entry *planEntry, scrapeStage bool, leaderStage string) (string, rkev1.RKEControlPlaneStatus, error) { + nodePlan, config, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, entry, joinServer, true) + if err != nil { + return "", status, err + } + + nodePlan.Files = append(nodePlan.Files, plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(encryptionKeyRotationWaitForSystemctlStatus)), + Path: encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationWaitForSystemctlStatusPath), + }) + + nodePlan.Instructions = []plan.OneTimeInstruction{} + + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + if runtime == capr.RuntimeRKE2 { + if generated, instruction := generateManifestRemovalInstruction(controlPlane, entry); generated { + nodePlan.Instructions = append(nodePlan.Instructions, convertToIdempotentInstruction( + controlPlane, + strings.ToLower(fmt.Sprintf("encryption-key-rotation/manifest-cleanup/%s", controlPlane.Status.RotateEncryptionKeysPhase)), + strconv.FormatInt(controlPlane.Spec.RotateEncryptionKeys.Generation, 10), + instruction)) + } + } + + nodePlan.Instructions = append(nodePlan.Instructions, idempotentRestartInstructions( + controlPlane, + strings.ToLower(fmt.Sprintf("encryption-key-rotation/restart/%s", controlPlane.Status.RotateEncryptionKeysPhase)), + strconv.FormatInt(controlPlane.Spec.RotateEncryptionKeys.Generation, 10), + capr.GetRuntimeServerUnit(controlPlane.Spec.KubernetesVersion))...) + + nodePlan.Instructions = append(nodePlan.Instructions, encryptionKeyRotationWaitForSystemctlStatusInstruction(controlPlane)) + + if isControlPlane(entry) { + nodePlan.Files = append(nodePlan.Files, + plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(encryptionKeyRotationSecretsEncryptStatusScript)), + Path: encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationSecretsEncryptStatusPath), + }, + plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(encryptionKeyRotationWaitForSecretsEncryptStatusScript)), + Path: encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationWaitForSecretsEncryptStatusPath), + }, + ) + nodePlan.Instructions = append(nodePlan.Instructions, + encryptionKeyRotationWaitForSecretsEncryptStatus(controlPlane), + encryptionKeyRotationSecretsEncryptStatusScriptOneTimeInstruction(controlPlane, leaderStage), + encryptionKeyRotationSecretsEncryptStatusOneTimeInstruction(controlPlane), + ) + } + + probes, err := p.generateProbes(controlPlane, entry, config) + if err != nil { + return "", status, err + } + nodePlan.Probes = probes + + // retry is important here because without it, we always seem to run into some sort of issue such as: + // - the follower node reporting the wrong status after a restart + // - the plan failing with the k3s/rke2-server services crashing the first, and resuming subsequent times + // It's not necessarily ideal if encryption key rotation can never complete, especially since we don't have access to + // the downstream k3s/rke2-server service logs, but it has to be done in order for encryption key rotation to succeed + err = assignAndCheckPlan(p.store, fmt.Sprintf("encryption key rotation [%s] for machine [%s]", controlPlane.Status.RotateEncryptionKeysPhase, entry.Machine.Name), entry, nodePlan, joinedServer, 5, 5) + if err != nil { + if IsErrWaiting(err) { + if planAppliedButWaitingForProbes(entry) { + return "", status, errWaitingf("%s: %s", err.Error(), probesMessage(entry.Plan)) + } + return "", status, err + } + status, err = p.encryptionKeyRotationFailed(status, err) + return "", status, err + } + + if !scrapeStage || !isControlPlane(entry) { + return "", status, nil + } + + stage, err := encryptionKeyRotationSecretsEncryptStageFromOneTimeStatus(entry) + if err != nil { + return "", status, err + } + return stage, status, nil +} + +// encryptionKeyRotationLeaderPhaseReconcile will run the secrets-encrypt command that corresponds to the phase, and scrape output to ensure that it was +// successful. If the secrets-encrypt command does not exist on the plan, that means this is the first reconciliation, and +// it must be added, otherwise reenqueue until the plan is in sync. +func (p *Planner) encryptionKeyRotationLeaderPhaseReconcile(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, joinServer string, leader *planEntry) (rkev1.RKEControlPlaneStatus, error) { + nodePlan, _, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, leader, joinServer, true) + if err != nil { + return status, err + } + + apply, err := encryptionKeyRotationSecretsEncryptInstruction(controlPlane) + if err != nil { + return p.encryptionKeyRotationFailed(status, err) + } + + nodePlan.Files = append(nodePlan.Files, []plan.File{ + { + Content: base64.StdEncoding.EncodeToString([]byte(encryptionKeyRotationWaitForSecretsEncryptStatusScript)), + Path: encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationWaitForSecretsEncryptStatusPath), + }, + { + Content: base64.StdEncoding.EncodeToString([]byte(encryptionKeyRotationSecretsEncryptStatusScript)), + Path: encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationSecretsEncryptStatusPath), + }, + }...) + + nodePlan.Instructions = []plan.OneTimeInstruction{ + apply, + encryptionKeyRotationSecretsEncryptStatusScriptOneTimeInstruction(controlPlane, ""), + encryptionKeyRotationSecretsEncryptStatusOneTimeInstruction(controlPlane), + } + nodePlan.PeriodicInstructions = []plan.PeriodicInstruction{ + encryptionKeyRotationSecretsEncryptStatusPeriodicInstruction(controlPlane), + } + err = assignAndCheckPlan(p.store, fmt.Sprintf("encryption key rotation [%s] for machine [%s]", controlPlane.Status.RotateEncryptionKeysPhase, leader.Machine.Name), leader, nodePlan, joinedServer, 1, 1) + if err != nil { + if IsErrWaiting(err) { + if strings.HasPrefix(err.Error(), "starting") { + logrus.Infof("[planner] rkecluster %s/%s: applying encryption key rotation stage command: [%s]", controlPlane.Namespace, controlPlane.Spec.ClusterName, apply.Args[1]) + } + return status, err + } + return p.encryptionKeyRotationFailed(status, err) + } + scrapedStageFromOneTimeInstructions, err := encryptionKeyRotationSecretsEncryptStageFromOneTimeStatus(leader) + if err != nil { + return status, err + } + periodic, err := encryptionKeyRotationSecretsEncryptStageFromPeriodic(leader) + if err != nil { + return status, err + } + err = encryptionKeyRotationIsCurrentStageAllowed(scrapedStageFromOneTimeInstructions, controlPlane.Status.RotateEncryptionKeysPhase) + if err != nil { + return p.encryptionKeyRotationFailed(status, err) + } + if scrapedStageFromOneTimeInstructions == encryptionKeyRotationStageReencryptRequest || scrapedStageFromOneTimeInstructions == encryptionKeyRotationStageReencryptActive { + if periodic != encryptionKeyRotationStageReencryptFinished { + return status, errWaitingf("waiting for encryption key rotation stage to be finished") + } + } + // successful restart, complete same phases for rotate & reencrypt + logrus.Infof("[planner] rkecluster %s/%s: successfully applied encryption key rotation stage command: [%s]", controlPlane.Namespace, controlPlane.Spec.ClusterName, leader.Plan.Plan.Instructions[0].Args[1]) + return status, nil +} + +// encryptionKeyRotationSecretsEncryptStageFromPeriodic will attempt to extract the current stage (secrets-encrypt status) from the +// plan by parsing the periodic output. +func encryptionKeyRotationSecretsEncryptStageFromPeriodic(plan *planEntry) (string, error) { + output, ok := plan.Plan.PeriodicOutput[encryptionKeyRotationSecretsEncryptStatusCommand] + if !ok { + for _, pi := range plan.Plan.Plan.PeriodicInstructions { + if pi.Name == encryptionKeyRotationSecretsEncryptStatusCommand { + return "", errWaitingf("could not extract current status from plan for [%s]: no output for status", plan.Machine.Name) + } + } + return "", fmt.Errorf("could not extract current status from plan for [%s]: status command not present in plan", plan.Machine.Name) + } + periodic, err := encryptionKeyRotationStageFromOutput(plan, string(output.Stdout)) + return periodic, err +} + +// encryptionKeyRotationSecretsEncryptStageFromOneTimeStatus will attempt to extract the current stage (secrets-encrypt status) from the +// plan by parsing the one time output. +func encryptionKeyRotationSecretsEncryptStageFromOneTimeStatus(plan *planEntry) (string, error) { + output, ok := plan.Plan.Output[encryptionKeyRotationSecretsEncryptStatusCommand] + if !ok { + return "", errWaitingf("could not extract current status from plan for [%s]: no output for status", plan.Machine.Name) + } + status, err := encryptionKeyRotationStageFromOutput(plan, string(output)) + return status, err +} + +// encryptionKeyRotationStageFromOutput parses the output of a secrets-encrypt status command. +func encryptionKeyRotationStageFromOutput(plan *planEntry, output string) (string, error) { + a := strings.Split(output, "\n") + if len(a) < 2 { + return "", errWaitingf("could not extract current stage from plan for [%s]: status output is incomplete", plan.Machine.Name) + } + for _, v := range a { + a = strings.Split(v, ": ") + if a[0] != "Current Rotation Stage" { + continue + } + status := a[1] + return status, nil + } + return "", errWaitingf("unable to parse rotation stage from output") +} + +// encryptionKeyRotationSecretsEncryptInstruction generates a secrets-encrypt command to run on the leader node given +// the current secrets-encrypt phase. +func encryptionKeyRotationSecretsEncryptInstruction(controlPlane *rkev1.RKEControlPlane) (plan.OneTimeInstruction, error) { + if controlPlane == nil { + return plan.OneTimeInstruction{}, fmt.Errorf("controlplane cannot be nil") + } + + var command string + switch controlPlane.Status.RotateEncryptionKeysPhase { + case rkev1.RotateEncryptionKeysPhasePrepare: + command = encryptionKeyRotationCommandPrepare + case rkev1.RotateEncryptionKeysPhaseRotate: + command = encryptionKeyRotationCommandRotate + case rkev1.RotateEncryptionKeysPhaseReencrypt: + command = encryptionKeyRotationCommandReencrypt + default: + return plan.OneTimeInstruction{}, fmt.Errorf("cannot determine desired secrets-encrypt command for phase: [%s]", controlPlane.Status.RotateEncryptionKeysPhase) + } + + return idempotentInstruction( + controlPlane, + strings.ToLower(fmt.Sprintf("encryption-key-rotation/%s", controlPlane.Status.RotateEncryptionKeysPhase)), + strconv.FormatInt(controlPlane.Spec.RotateEncryptionKeys.Generation, 10), + capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + []string{ + "secrets-encrypt", + command, + }, + []string{}, + ), nil +} + +// encryptionKeyRotationStatusEnv returns an environment variable in order to force followers to rerun their plans +// following progression of encryption key rotation. In an HA setup with split role etcd & controlplane nodes, the etcd +// nodes would have identical plans, so this variable is used to spoof an update and force the system-agent to run the +// plan. +func encryptionKeyRotationStatusEnv(controlPlane *rkev1.RKEControlPlane) string { + return fmt.Sprintf("ENCRYPTION_KEY_ROTATION_STAGE=%s", controlPlane.Status.RotateEncryptionKeysPhase) +} + +// encryptionKeyRotationGenerationEnv returns an environment variable in order to force followers to rerun their plans +// on subsequent generations, in the event that encryption key rotation is restarting and failed during prepare. +func encryptionKeyRotationGenerationEnv(controlPlane *rkev1.RKEControlPlane) string { + return fmt.Sprintf("ENCRYPTION_KEY_ROTATION_GENERATION=%d", controlPlane.Spec.RotateEncryptionKeys.Generation) +} + +// encryptionKeyRotationSecretsEncryptStatusOneTimeInstruction generates a one time instruction which will scrape the secrets-encrypt +// status. +func encryptionKeyRotationSecretsEncryptStatusScriptOneTimeInstruction(controlPlane *rkev1.RKEControlPlane, expected string) plan.OneTimeInstruction { + i := plan.OneTimeInstruction{ + Name: "secrets-encrypt-status-script", + Command: "sh", + Args: []string{ + "-x", + encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationSecretsEncryptStatusPath), + capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + }, + Env: []string{ + encryptionKeyRotationStatusEnv(controlPlane), + encryptionKeyRotationGenerationEnv(controlPlane), + }, + } + if expected != "" { + i.Args = append(i.Args, expected) + } + return i +} + +// encryptionKeyRotationSecretsEncryptStatusOneTimeInstruction generates a one time instruction which will scrape the secrets-encrypt +// status. +func encryptionKeyRotationSecretsEncryptStatusOneTimeInstruction(controlPlane *rkev1.RKEControlPlane) plan.OneTimeInstruction { + return plan.OneTimeInstruction{ + Name: encryptionKeyRotationSecretsEncryptStatusCommand, + Command: capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + Args: []string{ + "secrets-encrypt", + "status", + }, + Env: []string{ + encryptionKeyRotationStatusEnv(controlPlane), + encryptionKeyRotationGenerationEnv(controlPlane), + }, + SaveOutput: true, + } +} + +// encryptionKeyRotationSecretsEncryptStatusPeriodicInstruction generates a periodic instruction which will scrape the secrets-encrypt +// status from the node every 5 seconds. +func encryptionKeyRotationSecretsEncryptStatusPeriodicInstruction(controlPlane *rkev1.RKEControlPlane) plan.PeriodicInstruction { + return plan.PeriodicInstruction{ + Name: encryptionKeyRotationSecretsEncryptStatusCommand, + Command: capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + Args: []string{ + "secrets-encrypt", + "status", + }, + PeriodSeconds: 5, + } +} + +// encryptionKeyRotationWaitForSystemctlStatusInstruction is intended to run after a node is restart, and wait until the +// node is online and able to provide systemctl status, ensuring that the server service is able to be restarted. If the +// service never comes active, the plan advances anyway in order to restart the service. If restarting the service +// fails, then the plan will fail. +func encryptionKeyRotationWaitForSystemctlStatusInstruction(controlPlane *rkev1.RKEControlPlane) plan.OneTimeInstruction { + return plan.OneTimeInstruction{ + Name: "wait-for-systemctl-status", + Command: "sh", + Args: []string{ + "-x", encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationWaitForSystemctlStatusPath), capr.GetRuntimeServerUnit(controlPlane.Spec.KubernetesVersion), + }, + Env: []string{ + encryptionKeyRotationEndpointEnv, + encryptionKeyRotationStatusEnv(controlPlane), + encryptionKeyRotationGenerationEnv(controlPlane), + }, + SaveOutput: false, + } +} + +// encryptionKeyRotationWaitForSecretsEncryptStatus is intended to run after a node is restart, and wait until the node +// is online and able to provide secrets-encrypt status, ensuring that subsequent status commands from the system-agent +// will be successful. +func encryptionKeyRotationWaitForSecretsEncryptStatus(controlPlane *rkev1.RKEControlPlane) plan.OneTimeInstruction { + return plan.OneTimeInstruction{ + Name: "wait-for-secrets-encrypt-status", + Command: "sh", + Args: []string{ + "-x", encryptionKeyRotationScriptPath(controlPlane, encryptionKeyRotationWaitForSecretsEncryptStatusPath), capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + }, + Env: []string{ + encryptionKeyRotationEndpointEnv, + encryptionKeyRotationStatusEnv(controlPlane), + encryptionKeyRotationGenerationEnv(controlPlane), + }, + SaveOutput: true, + } +} + +// encryptionKeyRotationIsCurrentStageAllowed returns a boolean that indicates whether the scraped stage from the leader is allowed in comparison with the current phase. +// Since reencrypt can be any of three statuses (reencrypt_request, reencrypt_active, and reencrypt_finished), any of these stages are valid, however the first two (request & active) do +// not explicitly indicate that the current command was successful, just that it hasn't failed yet. In certain cases, a +// cluster may never move beyond request and active. +func encryptionKeyRotationIsCurrentStageAllowed(leaderStage string, currentPhase rkev1.RotateEncryptionKeysPhase) error { + switch currentPhase { + case rkev1.RotateEncryptionKeysPhasePrepare: + if leaderStage == encryptionKeyRotationCommandPrepare { + return nil + } + case rkev1.RotateEncryptionKeysPhaseRotate: + if leaderStage == encryptionKeyRotationCommandRotate { + return nil + } + case rkev1.RotateEncryptionKeysPhaseReencrypt: + if leaderStage == encryptionKeyRotationStageReencryptRequest || + leaderStage == encryptionKeyRotationStageReencryptActive || + leaderStage == encryptionKeyRotationStageReencryptFinished { + return nil + } + } + return fmt.Errorf("unexpected encryption key rotation stage [%s] for phase [%s]", leaderStage, currentPhase) +} + +// encryptionKeyRotationFailed updates the various status objects on the control plane, allowing the cluster to +// continue the reconciliation loop. Encryption key rotation will not be restarted again until requested. +func (p *Planner) encryptionKeyRotationFailed(status rkev1.RKEControlPlaneStatus, err error) (rkev1.RKEControlPlaneStatus, error) { + status.RotateEncryptionKeysPhase = rkev1.RotateEncryptionKeysPhaseFailed + return status, errors.Wrap(err, "encryption key rotation failed, please perform an etcd restore") +} + +func encryptionKeyRotationScriptPath(controlPlane *rkev1.RKEControlPlane, file string) string { + return path.Join(capr.GetDistroDataDir(controlPlane), encryptionKeyRotationBinPrefix, file) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/errors.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/errors.go new file mode 100644 index 0000000..25d7cf2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/errors.go @@ -0,0 +1,43 @@ +package planner + +import ( + "errors" + "fmt" +) + +// errWaiting will not cause a re-enqueue of the object being processed and should be used when waiting for other objects/controllers +type errWaiting string + +func (e errWaiting) Error() string { + return string(e) +} + +// errWaitingf renders an error of type errWaiting that will not cause a re-enqueue of the object being processed and should be used when waiting for other objects/controllers +func errWaitingf(format string, a ...interface{}) errWaiting { + return errWaiting(fmt.Sprintf(format, a...)) +} + +func IsErrWaiting(err error) bool { + var errWaiting errWaiting + return errors.As(err, &errWaiting) +} + +// errIgnore is specifically used during plan processing to ignore internal processing errors +type errIgnore string + +func (e errIgnore) Error() string { + return string(e) +} + +// ignoreErrors accepts two errors. If the err is type errIgnore, it will return (err, nil) if firstIgnoreErr is nil or (firstIgnoreErr, nil). +// Otherwise, it will simply return (firstIgnoreErr, err) +func ignoreErrors(firstIgnoreError error, err error) (error, error) { + var errIgnore errIgnore + if errors.As(err, &errIgnore) { + if firstIgnoreError == nil { + return err, nil + } + return firstIgnoreError, nil + } + return firstIgnoreError, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdcreate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdcreate.go new file mode 100644 index 0000000..ff97471 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdcreate.go @@ -0,0 +1,198 @@ +package planner + +import ( + "errors" + "fmt" + + "github.com/Masterminds/semver/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/capr/managesystemagent" + "github.com/rancher/wrangler/v3/pkg/merr" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/equality" +) + +func (p *Planner) setEtcdSnapshotCreateState(status rkev1.RKEControlPlaneStatus, create *rkev1.ETCDSnapshotCreate, phase rkev1.ETCDSnapshotPhase) (rkev1.RKEControlPlaneStatus, error) { + if status.ETCDSnapshotCreatePhase != phase || !equality.Semantic.DeepEqual(status.ETCDSnapshotCreate, create) { + status.ETCDSnapshotCreatePhase = phase + status.ETCDSnapshotCreate = create + return status, errWaiting("refreshing etcd create state") + } + return status, nil +} + +func (p *Planner) resetEtcdSnapshotCreateState(status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + if status.ETCDSnapshotCreate == nil && status.ETCDSnapshotCreatePhase == "" { + return status, nil + } + return p.setEtcdSnapshotCreateState(status, nil, "") +} + +func (p *Planner) startOrRestartEtcdSnapshotCreate(status rkev1.RKEControlPlaneStatus, snapshot *rkev1.ETCDSnapshotCreate) (rkev1.RKEControlPlaneStatus, error) { + if status.ETCDSnapshotCreate == nil || !equality.Semantic.DeepEqual(snapshot, status.ETCDSnapshotCreate) { + return p.setEtcdSnapshotCreateState(status, snapshot, rkev1.ETCDSnapshotPhaseStarted) + } + return status, nil +} + +func (p *Planner) runEtcdSnapshotCreate(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, clusterPlan *plan.Plan, joinServer string) []error { + servers := collect(clusterPlan, isEtcd) + if len(servers) == 0 { + return []error{errors.New("failed to find node to perform etcd snapshot")} + } + + var errs []error + + for _, server := range servers { + createPlan, joinedServer, err := p.generateEtcdSnapshotCreatePlan(controlPlane, tokensSecret, server, joinServer) + if err != nil { + return []error{err} + } + msg := fmt.Sprintf("etcd snapshot on machine %s/%s", server.Machine.Namespace, server.Machine.Name) + if server.Machine.Status.NodeRef != nil && server.Machine.Status.NodeRef.Name != "" { + msg = fmt.Sprintf("etcd snapshot on node %s", server.Machine.Status.NodeRef.Name) + } + if err = assignAndCheckPlan(p.store, msg, server, createPlan, joinedServer, 3, 3); err != nil { + errs = append(errs, err) + } + } + return errs +} + +// runEtcdSnapshotManagementServiceStart walks through the reconciliation process for the controlplane and etcd nodes. +// Notably, this function will blatantly ignore drain and concurrency options, as during an etcd snapshot operation, there is no necessity to drain nodes. +func (p *Planner) runEtcdSnapshotManagementServiceStart(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, clusterPlan *plan.Plan, include roleFilter, operation string) error { + // Generate and deliver desired plan for the bootstrap/init node first. + if err := p.reconcile(controlPlane, tokensSecret, clusterPlan, true, bootstrapTier, isEtcd, isNotInitNodeOrIsDeleting, + "1", "", + controlPlane.Spec.UpgradeStrategy.ControlPlaneDrainOptions); err != nil { + return err + } + + _, joinServer, _, err := p.findInitNode(controlPlane, clusterPlan) + if err != nil { + return err + } + + if joinServer == "" { + return fmt.Errorf("error encountered restarting cluster during %s, joinServer was empty", operation) + } + + for _, entry := range collect(clusterPlan, include) { + if isInitNodeOrDeleting(entry) { + continue + } + plan, joinedServer, err := p.desiredPlan(controlPlane, tokensSecret, entry, joinServer) + if err != nil { + return err + } + if err = assignAndCheckPlan(p.store, fmt.Sprintf("%s management plane restart", operation), entry, plan, joinedServer, 1, -1); err != nil { + return err + } + } + return nil +} + +// generateEtcdSnapshotCreatePlan generates a plan that contains an instruction to create an etcd snapshot. +func (p *Planner) generateEtcdSnapshotCreatePlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, entry *planEntry, joinServer string) (plan.NodePlan, string, error) { + v, err := semver.NewVersion(controlPlane.Spec.KubernetesVersion) + if err != nil { + return plan.NodePlan{}, "", err + } + + args := []string{ + "etcd-snapshot", + } + + // Starting in v1.26, we must specify "save" when creating an etcd snapshot + if v.GreaterThan(managesystemagent.Kubernetes125) { + args = append(args, "save") + } + + createPlan, _, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, entry, joinServer, true) + createPlan.Instructions = append(createPlan.Instructions, p.generateInstallInstructionWithSkipStart(controlPlane, entry), + plan.OneTimeInstruction{ + Name: "create", + Command: capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + Args: args, + }) + return createPlan, joinedServer, err +} + +func (p *Planner) createEtcdSnapshot(controlPlane *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, clusterPlan *plan.Plan) (rkev1.RKEControlPlaneStatus, error) { + var err error + if controlPlane.Spec.ETCDSnapshotCreate == nil { + status, err := p.resetEtcdSnapshotCreateState(status) + return status, err + } + + // Don't create an etcd snapshot if the cluster is not initialized or bootstrapped. + if !status.Initialized || !capr.Bootstrapped.IsTrue(&status) { + logrus.Warnf("[planner] rkecluster %s/%s: skipping etcd snapshot creation as cluster has not yet been initialized or bootstrapped", controlPlane.Namespace, controlPlane.Name) + return status, nil + } + + snapshot := controlPlane.Spec.ETCDSnapshotCreate + + if status, err = p.startOrRestartEtcdSnapshotCreate(status, snapshot); err != nil { + return status, err + } + + switch controlPlane.Status.ETCDSnapshotCreatePhase { + case rkev1.ETCDSnapshotPhaseStarted: + var stateSet bool + var finErrs []error + found, joinServer, _, err := p.findInitNode(controlPlane, clusterPlan) + if err != nil { + logrus.Errorf("[planner] rkecluster %s/%s: error encountered while searching for init node during etcd snapshot creation: %v", controlPlane.Namespace, controlPlane.Name, err) + return status, err + } + if !found || joinServer == "" { + logrus.Warnf("[planner] rkecluster %s/%s: skipping etcd snapshot creation as cluster does not have an init node", controlPlane.Namespace, controlPlane.Name) + return status, nil + } + if errs := p.runEtcdSnapshotCreate(controlPlane, tokensSecret, clusterPlan, joinServer); len(errs) > 0 { + for _, err := range errs { + if err == nil { + continue + } + finErrs = append(finErrs, err) + if !IsErrWaiting(err) { + // we have a failed snapshot from a node. + if !stateSet { + status, err = p.setEtcdSnapshotCreateState(status, snapshot, rkev1.ETCDSnapshotPhaseFailed) + if err != nil { + finErrs = append(finErrs, err) + } else { + stateSet = true + } + } + } + } + return status, errWaiting(merr.NewErrors(finErrs...).Error()) + } + if status, err = p.setEtcdSnapshotCreateState(status, snapshot, rkev1.ETCDSnapshotPhaseRestartCluster); err != nil { + return status, err + } + return status, nil + case rkev1.ETCDSnapshotPhaseRestartCluster: + if err = p.runEtcdSnapshotManagementServiceStart(controlPlane, tokensSecret, clusterPlan, isEtcd, "etcd snapshot creation"); err != nil { + return status, err + } + if status, err = p.setEtcdSnapshotCreateState(status, snapshot, rkev1.ETCDSnapshotPhaseFinished); err != nil { + return status, err + } + return status, nil + case rkev1.ETCDSnapshotPhaseFailed: + fallthrough + case rkev1.ETCDSnapshotPhaseFinished: + return status, nil + default: + if status, err = p.setEtcdSnapshotCreateState(status, snapshot, rkev1.ETCDSnapshotPhaseStarted); err != nil { + return status, err + } + return status, nil + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore.go new file mode 100644 index 0000000..bdf2c5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore.go @@ -0,0 +1,862 @@ +package planner + +import ( + "encoding/base64" + "fmt" + "path" + "strconv" + "strings" + + "github.com/Masterminds/semver/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/capr/managesystemagent" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + etcdRestoreBinPrefix = "capr/etcd-restore/bin" + + etcdRestorePostRestoreWaitForPodListCleanupPath = "wait_for_pod_list.sh" + etcdRestorePostRestoreWaitForPodListCleanupScript = ` +#!/bin/sh + +i=0 + +while [ $i -lt 30 ]; do + if $@ >/dev/null 2>&1; then + exit 0 + fi + sleep 10 + i=$((i + 1)) +done +exit 1 +` + etcdRestoreNodeCleanUpPath = "clean_up_nodes.sh" + etcdRestoreNodeCleanUpScript = ` +#!/bin/sh + +if [ -z "$KUBECTL" ]; then + echo "Must define KUBECTL environment variable" + exit 1 +fi + +if [ -z "$KUBECONFIG" ]; then + echo "Must define KUBECONFIG environment variable" + exit 1 +fi + +MACHINEIDSFILE="$1" +NODENAMESFILE="$2" + +if [ -z "$MACHINEIDSFILE" ] || [ -z "$NODENAMESFILE" ]; then + echo "Must define nodenames file and machineids file" +fi + +TMPALLNODES=$(mktemp) +TMPSAVENODES=$(mktemp) + +cat "$NODENAMESFILE" > "$TMPSAVENODES" + +if ! ${KUBECTL} get nodes --no-headers -o=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' > "$TMPALLNODES"; then + echo "Error listing all nodes" + exit 1 +fi + +while IFS='' read -r IDENTIFIER; do + if NODENAME=$(${KUBECTL} get node --no-headers -o=jsonpath='{.items[0].metadata.name}' -l rke.cattle.io/machine="$IDENTIFIER"); then + echo "$NODENAME" >> "$TMPSAVENODES" + fi +done < "$MACHINEIDSFILE" + +echo "Saving nodes:" +cat "$TMPSAVENODES" + +while IFS='' read -r NODE; do + if [ "${NODE}" = "" ]; then + continue + fi + FOUND=false + while IFS='' read -r KEEP; do + if [ "${NODE}" = "${KEEP}" ]; then + FOUND=true + break + fi + done < "$TMPSAVENODES" + if [ "${FOUND}" != "true" ]; then + echo "Deleting node ${NODE}" + ${KUBECTL} delete node "${NODE}" --wait=false + fi +done < "$TMPALLNODES" +rm "$TMPALLNODES" +rm "$TMPSAVENODES" + +rm "$MACHINEIDSFILE" +rm "$NODENAMESFILE" +` + etcdRestoreNodeWaitForReadyPath = "wait_for_ready.sh" + etcdRestoreNodeWaitForReadyScript = ` +#!/bin/sh + +if [ -z "$KUBECTL" ]; then + echo "Must define KUBECTL environment variable" + exit 1 +fi + +if [ -z "$KUBECONFIG" ]; then + echo "Must define KUBECONFIG environment variable" + exit 1 +fi + +TMPMACHINEIDS=$(mktemp) + +printf '%s\n' "$@" > "$TMPMACHINEIDS" + +DESIREDREADYCOUNT=$(wc -l < "$TMPMACHINEIDS") + +DESIREDNODESREADY=false + +while ! $DESIREDNODESREADY; do + DESIREDNODESREADY=true + while IFS='' read -r MID; do + if [ "$MID" = "" ]; then + exit + fi + if NODEREADY=$(${KUBECTL} get node --no-headers -o=custom-columns=STATUS:status.conditions\[\?\(\@.type==\"Ready\"\)\].status -l rke.cattle.io/machine="$MID"); then + if [ "$NODEREADY" != "True" ]; then + DESIREDNODESREADY=false + sleep 5 + break + fi + fi + done < "$TMPMACHINEIDS" +done + + +DESIREDREADYCOUNT=$(wc -l < "$TMPMACHINEIDS") +rm "$TMPMACHINEIDS" + +TMPALLREADY=$(mktemp) + +ITERCOUNT=0 +while [ "$ITERCOUNT" != 60 ]; do + ACTUALREADYCOUNT=0 + ITERCOUNT=$((ITERCOUNT+1)) + if ! ${KUBECTL} get nodes --no-headers -o=custom-columns=STATUS:status.conditions\[\?\(\@.type==\"Ready\"\)\].status > "$TMPALLREADY"; then + sleep 5 + continue + fi + while IFS='' read -r STATUS; do + if [ "$STATUS" = "True" ]; then + ACTUALREADYCOUNT=$((ACTUALREADYCOUNT+1)) + fi + done < "$TMPALLREADY" + if [ "$DESIREDREADYCOUNT" = "$ACTUALREADYCOUNT" ]; then + break + fi + sleep 5 +done + +rm "$TMPALLREADY" +` +) + +const ETCDRestoreMessage = "etcd restore" + +// setEtcdSnapshotRestoreState sets the restore schema and phase to the given restore and phase and returns an errWaiting if a change was made. Notably this function does not persist the change. +func (p *Planner) setEtcdSnapshotRestoreState(status rkev1.RKEControlPlaneStatus, restore *rkev1.ETCDSnapshotRestore, phase rkev1.ETCDSnapshotPhase) (rkev1.RKEControlPlaneStatus, error) { + if !equality.Semantic.DeepEqual(status.ETCDSnapshotRestore, restore) || status.ETCDSnapshotRestorePhase != phase { + status.ETCDSnapshotRestore = restore + status.ETCDSnapshotRestorePhase = phase + return status, errWaiting("refreshing etcd restore state") + } + return status, nil +} + +// resetEtcdSnapshotRestoreState will unset the restore field and phase +func (p *Planner) resetEtcdSnapshotRestoreState(status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + if status.ETCDSnapshotRestore == nil && status.ETCDSnapshotRestorePhase == "" { + return status, nil + } + return p.setEtcdSnapshotRestoreState(status, nil, "") +} + +// startOrRestartEtcdSnapshotRestore sets the started phase +func (p *Planner) startOrRestartEtcdSnapshotRestore(status rkev1.RKEControlPlaneStatus, restore *rkev1.ETCDSnapshotRestore) (rkev1.RKEControlPlaneStatus, error) { + if status.ETCDSnapshotRestore == nil || !equality.Semantic.DeepEqual(restore, status.ETCDSnapshotRestore) { + return p.setEtcdSnapshotRestoreState(status, restore, rkev1.ETCDSnapshotPhaseStarted) + } + return status, nil +} + +// runEtcdSnapshotRestorePlan runs the snapshot restoration plan by electing an init node (or designating the init node +// that is specified on the snapshot), and renders/delivers the etcd restoration plan to that node. +func (p *Planner) runEtcdSnapshotRestorePlan(controlPlane *rkev1.RKEControlPlane, snapshot *rkev1.ETCDSnapshot, snapshotName string, tokensSecret plan.Secret, clusterPlan *plan.Plan) error { + var joinServer string + var err error + + joinServer, err = p.runEtcdRestoreInitNodeElection(controlPlane, snapshot, clusterPlan) + if err != nil { + return err + } + + servers := collect(clusterPlan, isInitNode) + + if len(servers) != 1 { + return fmt.Errorf("more than one init node existed, cannot run etcd snapshot restore") + } + + if err := p.pauseCAPICluster(controlPlane, true); err != nil { + return err + } + + restorePlan, joinedServer, err := p.generateEtcdSnapshotRestorePlan(controlPlane, snapshot, snapshotName, tokensSecret, servers[0], joinServer) + if err != nil { + return err + } + return assignAndCheckPlan(p.store, ETCDRestoreMessage, servers[0], restorePlan, joinedServer, 1, 1) +} + +func (p *Planner) runEtcdSnapshotPostRestorePodCleanupPlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, clusterPlan *plan.Plan) error { + initNodes := collect(clusterPlan, isInitNode) + if len(initNodes) != 1 { + return fmt.Errorf("multiple init nodes found") + } + initNode := initNodes[0] + + initNodePlan, _, err := p.desiredPlan(controlPlane, tokensSecret, initNode, "") + if err != nil { + return err + } + + // If the init node is a controlplane node, deliver the desired plan + pod cleanup instruction + if isControlPlane(initNode) { + cleanupScriptFiles, cleanupInstructions := p.generateEtcdRestorePodCleanupFilesAndInstruction(controlPlane, []string{string(initNode.Machine.UID)}) + initNodePlan.Files = append(initNodePlan.Files, cleanupScriptFiles...) + initNodePlan.Instructions = append(initNodePlan.Instructions, cleanupInstructions...) + return assignAndCheckPlan(p.store, ETCDRestoreMessage, initNode, initNodePlan, "", 5, 5) + } + + if err := assignAndCheckPlan(p.store, ETCDRestoreMessage, initNode, initNodePlan, "", 5, 5); err != nil { + return err + } + + _, joinServer, _, err := p.findInitNode(controlPlane, clusterPlan) + if joinServer == "" { + return errWaitingf("waiting for join server") + } + if err != nil { + return err + } + + controlPlaneEntries := collect(clusterPlan, roleAnd(isControlPlane, roleNot(isDeleting))) + if len(controlPlaneEntries) == 0 { + return fmt.Errorf("no suitable controlplane entries found for post restore cleanup during etcd restoration") + } + + controlPlaneEntry := controlPlaneEntries[0] + + firstControlPlanePlan, joinedServer, err := p.desiredPlan(controlPlane, tokensSecret, controlPlaneEntry, joinServer) + if err != nil { + return err + } + + cleanupScriptFiles, cleanupInstructions := p.generateEtcdRestorePodCleanupFilesAndInstruction(controlPlane, []string{string(initNode.Machine.UID), string(controlPlaneEntry.Machine.UID)}) + firstControlPlanePlan.Files = append(firstControlPlanePlan.Files, cleanupScriptFiles...) + firstControlPlanePlan.Instructions = append(firstControlPlanePlan.Instructions, cleanupInstructions...) + return assignAndCheckPlan(p.store, ETCDRestoreMessage, controlPlaneEntry, firstControlPlanePlan, joinedServer, 5, 5) +} + +func (p *Planner) runEtcdSnapshotPostRestoreNodeCleanupPlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, clusterPlan *plan.Plan) error { + initNodes := collect(clusterPlan, isInitNode) + if len(initNodes) != 1 { + return fmt.Errorf("multiple init nodes found") + } + initNode := initNodes[0] + + initNodePlan, _, err := p.desiredPlan(controlPlane, tokensSecret, initNode, "") + if err != nil { + return err + } + + var allMachineUIDs, allNodeNames []string + for _, n := range collect(clusterPlan, isNotDeleting) { + if n.Machine != nil && n.Machine.UID != "" { + allMachineUIDs = append(allMachineUIDs, string(n.Machine.UID)) + } + if n.Machine != nil && n.Machine.Status.NodeRef != nil && n.Machine.Status.NodeRef.Name != "" { + allNodeNames = append(allNodeNames, n.Machine.Status.NodeRef.Name) + } + } + + cleanupScriptFiles, cleanupInstructions := p.generateEtcdRestoreNodeCleanupFilesAndInstruction(controlPlane, allMachineUIDs, allNodeNames) + initNodePlan.Files = append(initNodePlan.Files, cleanupScriptFiles...) + initNodePlan.Instructions = append(initNodePlan.Instructions, cleanupInstructions...) + return assignAndCheckPlan(p.store, ETCDRestoreMessage, initNode, initNodePlan, "", 5, 5) +} + +// generateEtcdSnapshotRestorePlan returns a node plan that contains instructions to stop etcd, remove the tombstone file (if one exists), then restore etcd in that order. +func (p *Planner) generateEtcdSnapshotRestorePlan(controlPlane *rkev1.RKEControlPlane, snapshot *rkev1.ETCDSnapshot, snapshotName string, tokensSecret plan.Secret, entry *planEntry, joinServer string) (plan.NodePlan, string, error) { + if controlPlane.Spec.ETCDSnapshotRestore == nil { + return plan.NodePlan{}, "", fmt.Errorf("ETCD Snapshot restore was not defined") + } + + // Notably, if we are generating a restore plan for an S3 snapshot, we will render S3 arguments, environment variables, and files from the snapshot metadata. + nodePlan, _, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, entry, joinServer, false) + if err != nil { + return nodePlan, joinedServer, err + } + + loopbackAddress := capr.GetLoopbackAddress(controlPlane) + + args := []string{ + "server", + "--cluster-reset", + fmt.Sprintf("--etcd-arg=advertise-client-urls=https://%s:2379", loopbackAddress), // this is a workaround for: https://github.com/rancher/rke2/issues/4052 and can likely remain indefinitely (unless IPv6-only becomes a requirement) + "--etcd-disable-snapshots=false", // this is a workaround for https://github.com/k3s-io/k3s/issues/8031 + } + + var env []string + + if snapshot == nil { + // If the snapshot is nil, then we will assume the passed in snapshot name is a local snapshot. + args = append(args, fmt.Sprintf("--cluster-reset-restore-path=db/snapshots/%s", snapshotName), "--etcd-s3=false") + } else if snapshot.SnapshotFile.S3 == nil { + args = append(args, fmt.Sprintf("--cluster-reset-restore-path=db/snapshots/%s", snapshot.SnapshotFile.Name), "--etcd-s3=false") + } else { + args = append(args, fmt.Sprintf("--cluster-reset-restore-path=%s", snapshot.SnapshotFile.Name)) + s3, s3Env, s3Files, err := p.etcdS3Args.ToArgs(snapshot.SnapshotFile.S3, controlPlane, "etcd-", true) + if err != nil { + return plan.NodePlan{}, "", err + } + args = append(args, s3...) + env = s3Env + nodePlan.Files = append(nodePlan.Files, s3Files...) + } + + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + + nodePlan.Instructions = append(nodePlan.Instructions, convertToIdempotentInstruction( + controlPlane, + "etcd-restore/restore-kill-all", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + generateKillAllInstruction(controlPlane))) + + if runtime == capr.RuntimeRKE2 { + if generated, instruction := generateManifestRemovalInstruction(controlPlane, entry); generated { + nodePlan.Instructions = append(nodePlan.Instructions, convertToIdempotentInstruction( + controlPlane, + "etcd-restore/restore-manifest-removal", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + instruction)) + } + } + + // make sure to install the desired version before performing restore + nodePlan.Instructions = append(nodePlan.Instructions, + p.generateInstallInstructionWithSkipStart(controlPlane, entry), + convertToIdempotentInstruction( + controlPlane, + "etcd-restore/clean-etcd-dir", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), plan.OneTimeInstruction{ + Name: "remove-etcd-db-dir", + Command: "rm", + Args: []string{ + "-rf", + path.Join(capr.GetDistroDataDir(controlPlane), "server/db/etcd"), + }}), + idempotentInstruction( + controlPlane, + "etcd-restore/restore", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + capr.GetRuntimeCommand(controlPlane.Spec.KubernetesVersion), + args, + env), + ) + + return nodePlan, joinedServer, nil +} + +func (p *Planner) generateStopServiceAndKillAllPlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, server *planEntry, joinServer string) (plan.NodePlan, string, error) { + nodePlan, _, joinedServer, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, server, joinServer, true) + if err != nil { + return nodePlan, joinedServer, err + } + + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + nodePlan.Instructions = append(nodePlan.Instructions, generateKillAllInstruction(controlPlane)) + + if runtime == capr.RuntimeRKE2 { + if generated, instruction := generateManifestRemovalInstruction(controlPlane, server); generated { + nodePlan.Instructions = append(nodePlan.Instructions, instruction) + } + } + + return nodePlan, joinedServer, nil +} + +func generateKillAllInstruction(controlPlane *rkev1.RKEControlPlane) plan.OneTimeInstruction { + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + killAllScript := runtime + "-killall.sh" + + return plan.OneTimeInstruction{ + Name: "shutdown", + Command: "/bin/sh", + Env: []string{ + fmt.Sprintf("%s_DATA_DIR=%s", strings.ToUpper(runtime), capr.GetDistroDataDir(controlPlane)), + }, + Args: []string{ + "-c", + fmt.Sprintf("if [ -z $(command -v %s) ] && [ -z $(command -v %s) ]; then echo %s does not appear to be installed; exit 0; else %s; fi", runtime, killAllScript, runtime, killAllScript), + }, + } +} + +func generateCreateEtcdTombstoneInstruction(controlPlane *rkev1.RKEControlPlane) plan.OneTimeInstruction { + return plan.OneTimeInstruction{ + Name: "create-etcd-tombstone", + Command: "touch", + Args: []string{ + path.Join(capr.GetDistroDataDir(controlPlane), "server/db/etcd/tombstone"), + }, + } +} + +func etcdRestoreScriptPath(controlPlane *rkev1.RKEControlPlane, file string) string { + return path.Join(capr.GetDistroDataDir(controlPlane), etcdRestoreBinPrefix, file) +} + +// generateEtcdRestorePodCleanupFilesAndInstruction generates a file that contains a script that checks API server health and a slice of instructions that cleans up system pods on etcd restore. +func (p *Planner) generateEtcdRestorePodCleanupFilesAndInstruction(controlPlane *rkev1.RKEControlPlane, cleanupMachineUIDs []string) ([]plan.File, []plan.OneTimeInstruction) { + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + + kubectl, kubeconfig := capr.GetKubectlAndKubeconfigPaths(controlPlane) + if kubectl == "" || kubeconfig == "" { + return nil, nil + } + + instructions := []plan.OneTimeInstruction{ + idempotentInstruction( + controlPlane, + "etcd-restore/pods-wait-for-podlist", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + "/bin/sh", + []string{ + "-x", + etcdRestoreScriptPath(controlPlane, etcdRestorePostRestoreWaitForPodListCleanupPath), + kubectl, + "--kubeconfig", + kubeconfig, + "get", + "pods", + "--all-namespaces", + }, + []string{}), + idempotentInstruction( + controlPlane, + "etcd-restore/wait-for-desired-ready-nodes", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + "/bin/sh", + append([]string{etcdRestoreScriptPath(controlPlane, etcdRestoreNodeWaitForReadyPath)}, cleanupMachineUIDs...), + []string{ + fmt.Sprintf("%s=%s", "KUBECTL", kubectl), + fmt.Sprintf("%s=%s", "KUBECONFIG", kubeconfig), + }), + } + + // These are the pod selectors that are common between K3s/RKE2 (CoreDNS/KubeDNS) + podSelectors := []string{ + "kube-system:k8s-app=kube-dns", + "kube-system:k8s-app=kube-dns-autoscaler", + } + + // RKE2 charts come from: https://github.com/rancher/rke2/blob/253af9ca3115de691f5fdb8ed8dcb284287b1856/Dockerfile#L109-L123 and are deployed into `kube-system` as the Helm {{ .Release.Namespace }} by default + if runtime == capr.RuntimeRKE2 { + podSelectors = append(podSelectors, + "kube-system:app=rke2-metrics-server", // rke2-metrics-server is deployed into `{{ .Release.Namespace }}` which is kube-system in RKE2: https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-metrics-server/rke2-metrics-server/2.11.100/templates/metrics-server-deployment.yaml#L5 + "tigera-operator:k8s-app=tigera-operator", // https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-calico/rke2-calico/v3.25.002/templates/tigera-operator/00-namespace-tigera-operator.yaml#L4 + "calico-system:k8s-app=calico-node", // Managed by tigera-operator https://github.com/tigera/operator/blob/08cdc5df85fda2ebe69ffafded1953744409c554/pkg/common/common.go#L20 + "calico-system:k8s-app=calico-kube-controllers", // Managed by tigera-operator https://github.com/tigera/operator/blob/08cdc5df85fda2ebe69ffafded1953744409c554/pkg/common/common.go#L21 + "calico-system:k8s-app=calico-typha", // Managed by tigera-operator https://github.com/tigera/operator/blob/08cdc5df85fda2ebe69ffafded1953744409c554/pkg/common/common.go#L19 + "kube-system:k8s-app=canal", // Canal is hardcode deployed into `kube-system` https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-canal/rke2-canal/v3.25.0-build2023020902/templates/daemonset.yaml#L10 + "kube-system:k8s-app=cilium", // Cilium agent is deployed into `{{ .Release.Namespace }}` which is kube-system in RKE2: https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-cilium/rke2-cilium/1.13.200/templates/cilium-agent/daemonset.yaml#L26 + "kube-system:app=rke2-multus", // Multus is deployed into `{{ .Release.Namespace }}` which is kube-system in RKE2: https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-multus/rke2-multus/v3.9.3-build2023010902/templates/daemonSet.yaml#L20 + "kube-system:app.kubernetes.io/name=rke2-ingress-nginx", // rke2-ingress-nginx is deployed into `{{ .Release.Namespace }}` which is in kube-system in RKE2: https://github.com/rancher/rke2-charts/blob/237251fccd793df825de0f27804ca7b6ad6e2981/charts/rke2-ingress-nginx/rke2-ingress-nginx/4.5.201/templates/controller-daemonset.yaml#L13 + ) + } + + if p.retrievalFunctions.SystemPodLabelSelectors != nil { + podSelectors = append(podSelectors, p.retrievalFunctions.SystemPodLabelSelectors(controlPlane)...) + } + + for i, podSelector := range podSelectors { + if namespace, labelSelector, usable := strings.Cut(podSelector, ":"); usable { + instructions = append(instructions, idempotentInstruction( + controlPlane, + fmt.Sprintf("etcd-restore/post-restore-cleanup-pods-%d", i), + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + kubectl, + []string{ + "--kubeconfig", + kubeconfig, + "delete", + "pods", + "-n", + namespace, + "-l", + labelSelector, + "--wait=false", + }, + []string{})) + } + } + + return []plan.File{ + { + Content: base64.StdEncoding.EncodeToString([]byte(etcdRestorePostRestoreWaitForPodListCleanupScript)), + Path: etcdRestoreScriptPath(controlPlane, etcdRestorePostRestoreWaitForPodListCleanupPath), + Dynamic: true, + }, + { + Content: base64.StdEncoding.EncodeToString([]byte(etcdRestoreNodeWaitForReadyScript)), + Path: etcdRestoreScriptPath(controlPlane, etcdRestoreNodeWaitForReadyPath), + Dynamic: true, + }, + }, instructions +} + +// generateEtcdRestorePodCleanupFilesAndInstruction generates a file that contains a script that checks API server health and a slice of instructions that cleans up system pods on etcd restore. +func (p *Planner) generateEtcdRestoreNodeCleanupFilesAndInstruction(controlPlane *rkev1.RKEControlPlane, allMachineUIDs []string, allNodeNames []string) ([]plan.File, []plan.OneTimeInstruction) { + kubectl, kubeconfig := capr.GetKubectlAndKubeconfigPaths(controlPlane) + if kubectl == "" || kubeconfig == "" { + return nil, nil + } + + var nodeNames, machineIDs []byte + + for _, mid := range allMachineUIDs { + machineIDs = fmt.Appendf(machineIDs, "%s\n", mid) + } + + for _, nodeName := range allNodeNames { + nodeNames = fmt.Appendf(nodeNames, "%s\n", nodeName) + } + + identifier := name.Hex(controlPlane.Spec.ETCDSnapshotRestore.Name+controlPlane.Spec.ETCDSnapshotRestore.RestoreRKEConfig+strconv.Itoa(controlPlane.Spec.ETCDSnapshotRestore.Generation), 10) + + machineIDsFile := fmt.Sprintf("machine-ids-%s", identifier) + nodeNamesFile := fmt.Sprintf("node-names-%s", identifier) + + instructions := []plan.OneTimeInstruction{ + idempotentInstruction( + controlPlane, + "etcd-restore/cleanup-nodes", + fmt.Sprintf("%v", controlPlane.Status.ETCDSnapshotRestore), + "/bin/sh", + []string{etcdRestoreScriptPath(controlPlane, etcdRestoreNodeCleanUpPath), etcdRestoreScriptPath(controlPlane, machineIDsFile), etcdRestoreScriptPath(controlPlane, nodeNamesFile)}, + []string{ + fmt.Sprintf("%s=%s", "KUBECTL", kubectl), + fmt.Sprintf("%s=%s", "KUBECONFIG", kubeconfig), + }), + } + + return []plan.File{ + { + Content: base64.StdEncoding.EncodeToString([]byte(etcdRestoreNodeCleanUpScript)), + Path: etcdRestoreScriptPath(controlPlane, etcdRestoreNodeCleanUpPath), + Dynamic: true, + }, + { + Content: base64.StdEncoding.EncodeToString(machineIDs), + Path: etcdRestoreScriptPath(controlPlane, machineIDsFile), + Dynamic: true, + }, + { + Content: base64.StdEncoding.EncodeToString(nodeNames), + Path: etcdRestoreScriptPath(controlPlane, nodeNamesFile), + Dynamic: true, + }, + }, instructions +} + +func generateRemoveTLSAndCredDirInstructions(controlPlane *rkev1.RKEControlPlane) []plan.OneTimeInstruction { + return []plan.OneTimeInstruction{ + { + Name: "remove-tls-directory", + Command: "rm", + Args: []string{ + "-rf", + path.Join(capr.GetDistroDataDir(controlPlane), "server/tls"), + }, + }, + { + Name: "remove-cred-directory", + Command: "rm", + Args: []string{ + "-rf", + path.Join(capr.GetDistroDataDir(controlPlane), "server/cred"), + }, + }, + } +} + +// runEtcdRestoreInitNodeElection runs an election for an init node. Notably, it accepts a nil snapshot, and will +func (p *Planner) runEtcdRestoreInitNodeElection(controlPlane *rkev1.RKEControlPlane, snapshot *rkev1.ETCDSnapshot, clusterPlan *plan.Plan) (string, error) { + if snapshot != nil { // If the snapshot CR is not nil, then find an init node. + if snapshot.SnapshotFile.S3 == nil { + // If the snapshot is not an S3 snapshot, then designate the init node by machine ID defined. + if id, ok := snapshot.Labels[capr.MachineIDLabel]; ok { + logrus.Infof("[planner] rkecluster %s/%s: designating init node with machine ID: %s for local snapshot %s/%s restoration", controlPlane.Namespace, controlPlane.Name, id, snapshot.Namespace, snapshot.Name) + return p.designateInitNodeByMachineID(controlPlane, clusterPlan, id) + } + return "", fmt.Errorf("unable to designate machine as label %s on snapshot %s/%s did not exist", capr.MachineIDLabel, snapshot.Namespace, snapshot.Name) + } + logrus.Infof("[planner] rkecluster %s/%s: electing init node for S3 snapshot %s/%s restoration", controlPlane.Namespace, controlPlane.Name, snapshot.Namespace, snapshot.Name) + return p.electInitNode(controlPlane, clusterPlan, true) + } + // make sure that we only have one suitable init node, and elect it. + count := len(collect(clusterPlan, canBeInitNode)) + if count == 0 { + return "", fmt.Errorf("no init node existed and no corresponding etcd snapshot CR found, no assumption can be made for the machine that contains the snapshot") + } else if count > 1 { + return "", fmt.Errorf("more than one init node existed and no corresponding etcd snapshot CR found, no assumption can be made for the machine that contains the snapshot") + } + logrus.Infof("[planner] rkecluster %s/%s: electing init node for local snapshot with no associated CR", controlPlane.Namespace, controlPlane.Name) + return p.electInitNode(controlPlane, clusterPlan, true) +} + +// runEtcdRestoreServiceStop generates service stop plans for every non-windows node in the cluster and +// assigns/checks the plans to ensure they were successful +func (p *Planner) runEtcdRestoreServiceStop(controlPlane *rkev1.RKEControlPlane, snapshot *rkev1.ETCDSnapshot, tokensSecret plan.Secret, clusterPlan *plan.Plan) error { + var joinServer string + var err error + + joinServer, err = p.runEtcdRestoreInitNodeElection(controlPlane, snapshot, clusterPlan) + if err != nil { + return err + } + + deletingEtcdNodes, err := p.forceDeleteAllDeletingEtcdMachines(controlPlane, clusterPlan) + if err != nil { + return err + } else if deletingEtcdNodes != 0 { + return errWaitingf("waiting for %d etcd machines to delete", deletingEtcdNodes) + } + + servers := collect(clusterPlan, anyRoleWithoutWindows) + updated := false + for _, server := range servers { + if server.Plan == nil { + continue + } + stopPlan, joinedServer, err := p.generateStopServiceAndKillAllPlan(controlPlane, tokensSecret, server, joinServer) + if err != nil { + return err + } + // Clean up previous restoration tracking attempts before starting this restoration. + stopPlan.Instructions = append(stopPlan.Instructions, generateIdempotencyCleanupInstruction(controlPlane, "etcd-restore")) + if isEtcd(server) { + stopPlan.Instructions = append(stopPlan.Instructions, generateCreateEtcdTombstoneInstruction(controlPlane)) + } + if roleOr(isEtcd, isControlPlane)(server) { + stopPlan.Instructions = append(stopPlan.Instructions, generateRemoveTLSAndCredDirInstructions(controlPlane)...) + } + if !equality.Semantic.DeepEqual(server.Plan.Plan, stopPlan) { + if err := p.store.UpdatePlan(server, stopPlan, joinedServer, 0, 0); err != nil { + return err + } + updated = true + } + } + + // If any of the node plans were updated, return an errWaiting message for shutting down control plane and etcd + if updated { + return errWaiting("stopping " + capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + " services on control plane and etcd machines/nodes") + } + + for _, server := range servers { + if server.Plan == nil { + continue + } + if !server.Plan.InSync { + if server.Machine.Status.NodeRef == nil { + return errWaiting(fmt.Sprintf("waiting to stop %s services on machine [%s]", capr.GetRuntime(controlPlane.Spec.KubernetesVersion), server.Machine.Name)) + } + return errWaiting(fmt.Sprintf("waiting to stop %s services on node [%s]", capr.GetRuntime(controlPlane.Spec.KubernetesVersion), server.Machine.Status.NodeRef.Name)) + } + } + + if len(collect(clusterPlan, roleAnd(isEtcd, roleNot(isDeleting)))) == 0 { + return errWaiting("waiting for suitable etcd nodes for etcd restore continuation") + } + return nil +} + +// retrieveEtcdSnapshot attempts to retrieve the etcdsnapshot CR that corresponds to the etcd snapshot restore name specified on the controlplane. +func (p *Planner) retrieveEtcdSnapshot(controlPlane *rkev1.RKEControlPlane) (*rkev1.ETCDSnapshot, error) { + if controlPlane == nil { + return nil, fmt.Errorf("controlplane was nil") + } + if controlPlane.Spec.ETCDSnapshotRestore == nil { + return nil, fmt.Errorf("etcdsnapshotrestore spec was nil") + } + if controlPlane.Spec.ClusterName == "" { + return nil, fmt.Errorf("cluster name on rkecontrolplane %s/%s was blank", controlPlane.Namespace, controlPlane.Name) + } + snapshot, err := p.etcdSnapshotCache.Get(controlPlane.Namespace, controlPlane.Spec.ETCDSnapshotRestore.Name) + if apierrors.IsNotFound(err) { + return nil, nil + } + return snapshot, err +} + +// forceDeleteAllDeletingEtcdMachines collects the etcd machines that are deleting for the given plan and force-deletes them. +// This is helpful for the case where an etcd restore operation is happening on a cluster with "stuck" deleting etcd machines (quorum loss). +func (p *Planner) forceDeleteAllDeletingEtcdMachines(cp *rkev1.RKEControlPlane, plan *plan.Plan) (int, error) { + etcdDeleting := collect(plan, roleAnd(isEtcd, isDeleting)) + for _, deletingEtcdNode := range etcdDeleting { + if deletingEtcdNode.Machine == nil { + logrus.Warnf("[planner] rkecluster %s/%s: did not find CAPI machine for entry when deleting etcd nodes", cp.Namespace, cp.Name) + continue + } + if deletingEtcdNode.Machine.Spec.Bootstrap.ConfigRef == nil { + logrus.Warnf("[planner] rkecluster %s/%s: did not find a corresponding CAPI machine for %s/%s", cp.Namespace, cp.Name, deletingEtcdNode.Machine.Namespace, deletingEtcdNode.Machine.Name) + continue + } + if !strings.Contains(deletingEtcdNode.Machine.Spec.Bootstrap.ConfigRef.APIVersion, "rke.cattle.io") { + logrus.Warnf("[planner] rkecluster %s/%s: CAPI machine %s/%s had a bootstrap ref with an unexpected API version: %s", cp.Namespace, cp.Name, deletingEtcdNode.Machine.Namespace, deletingEtcdNode.Machine.Name, deletingEtcdNode.Machine.Spec.Bootstrap.ConfigRef.APIVersion) + continue + } + logrus.Infof("[planner] rkecluster %s/%s: force deleting etcd machine %s/%s as cluster was not sane and machine was deleting", cp.Namespace, cp.Name, deletingEtcdNode.Machine.Namespace, deletingEtcdNode.Machine.Name) + // Update the CAPI machine annotation for exclude node draining and set it to true to get the CAPI controllers to not try to drain this node. + if deletingEtcdNode.Machine.Annotations == nil { + deletingEtcdNode.Machine.Annotations = map[string]string{} + } + deletingEtcdNode.Machine.Annotations[capi.ExcludeNodeDrainingAnnotation] = "true" + var err error + deletingEtcdNode.Machine, err = p.machines.Update(deletingEtcdNode.Machine) + if err != nil { + // If we get an error here, go ahead and return the error as this will re-enqueue and we can try again. + return -1, err + } + rb, err := p.rkeBootstrapCache.Get(deletingEtcdNode.Machine.Spec.Bootstrap.ConfigRef.Namespace, deletingEtcdNode.Machine.Spec.Bootstrap.ConfigRef.Name) + if err != nil { + return -1, err + } + rb = rb.DeepCopy() + // Annotate the rkebootstrap with a "force remove" annotation. This will short-circuit the "safe etcd removal" + // logic because at this point we are completely taking the cluster down. + if rb.Annotations == nil { + rb.Annotations = map[string]string{} + } + rb.Annotations[capr.ForceRemoveEtcdAnnotation] = "true" + _, err = p.rkeBootstrap.Update(rb) + if err != nil { + return -1, err + } + } + return len(etcdDeleting), nil +} + +// restoreEtcdSnapshot is called multiple times during an etcd snapshot restoration. +// restoreEtcdSnapshot utilizes the status of the corresponding control plane object of the cluster to track state +// The phases are in order: +// Started -> When the phase is started, it gets set to shutdown +// Shutdown -> When the phase is shutdown, it attempts to shut down etcd on all nodes (stop etcd) +// Restore -> When the phase is restore, it attempts to restore etcd +// Finished -> When the phase is finished, Restore returns nil. +func (p *Planner) restoreEtcdSnapshot(cp *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, tokensSecret plan.Secret, clusterPlan *plan.Plan, currentVersion *semver.Version) (rkev1.RKEControlPlaneStatus, error) { + if cp.Spec.ETCDSnapshotRestore == nil || cp.Spec.ETCDSnapshotRestore.Name == "" { + return p.resetEtcdSnapshotRestoreState(status) + } + + if status, err := p.startOrRestartEtcdSnapshotRestore(status, cp.Spec.ETCDSnapshotRestore); err != nil { + return status, err + } + + snapshot, err := p.retrieveEtcdSnapshot(cp) + if err != nil { + return status, err + } + + // validate the snapshot can be restored by checking to see if the snapshot version is < 1.25.x and the current version is 1.25 or newer. + if snapshot != nil { + clusterSpec, err := capr.ParseSnapshotClusterSpecOrError(snapshot) + if err != nil || clusterSpec == nil { + logrus.Errorf("[planner] rkecluster %s/%s: error parsing snapshot cluster spec for snapshot %s/%s during etcd restoration: %v", cp.Namespace, cp.Name, snapshot.Namespace, snapshot.Name, err) + } else { + snapshotK8sVersion, err := semver.NewVersion(clusterSpec.KubernetesVersion) + if err != nil { + return status, err + } + if !currentVersion.LessThan(managesystemagent.Kubernetes125) && snapshotK8sVersion.LessThan(managesystemagent.Kubernetes125) { + return status, fmt.Errorf("unable to restore etcd snapshot -- recorded Kubernetes version on snapshot was <= v1.25.0 and current cluster version was v1.25.0 or newer") + } + } + } + + switch cp.Status.ETCDSnapshotRestorePhase { + case rkev1.ETCDSnapshotPhaseStarted: + if status.Initialized || status.Ready { + status.Initialized = false + status.Ready = false + logrus.Debugf("[planner] rkecluster %s/%s: setting controlplane ready/initialized to false during etcd restore", cp.Namespace, cp.Name) + } + status, _ = p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseShutdown) + return status, errWaitingf("shutting down cluster") + case rkev1.ETCDSnapshotPhaseShutdown: + if err = p.runEtcdRestoreServiceStop(cp, snapshot, tokensSecret, clusterPlan); err != nil { + return status, err + } + capr.Bootstrapped.False(&status) + // the error returned from setEtcdSnapshotRestoreState is set based on etcd snapshot restore fields, but we are + // manipulating other fields so we should unconditionally return a waiting error. + status, _ = p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseRestore) + return status, errWaiting("cluster shutdown complete, running etcd restore") + case rkev1.ETCDSnapshotPhaseRestore: + if err = p.runEtcdSnapshotRestorePlan(cp, snapshot, cp.Spec.ETCDSnapshotRestore.Name, tokensSecret, clusterPlan); err != nil { + return status, err + } + status.ConfigGeneration++ // Increment config generation to cause the restart_stamp to change + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhasePostRestorePodCleanup) + case rkev1.ETCDSnapshotPhasePostRestorePodCleanup: + if err = p.runEtcdSnapshotPostRestorePodCleanupPlan(cp, tokensSecret, clusterPlan); err != nil { + return status, err + } + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseInitialRestartCluster) + case rkev1.ETCDSnapshotPhaseInitialRestartCluster: + if err := p.pauseCAPICluster(cp, false); err != nil { + return status, err + } + logrus.Infof("[planner] rkecluster %s/%s: running full reconcile during etcd restore to initially restart cluster", cp.Namespace, cp.Name) + // Run a full reconcile of the cluster at this point, ignoring drain and concurrency. + if status, err := p.fullReconcile(cp, status, tokensSecret, clusterPlan, true); err != nil { + return status, err + } + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhasePostRestoreNodeCleanup) + case rkev1.ETCDSnapshotPhasePostRestoreNodeCleanup: + if err = p.runEtcdSnapshotPostRestoreNodeCleanupPlan(cp, tokensSecret, clusterPlan); err != nil { + return status, err + } + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseRestartCluster) + case rkev1.ETCDSnapshotPhaseRestartCluster: + if err := p.pauseCAPICluster(cp, false); err != nil { + return status, err + } + logrus.Infof("[planner] rkecluster %s/%s: running full reconcile during etcd restore to restart cluster", cp.Namespace, cp.Name) + // Run a full reconcile of the cluster at this point, ignoring drain and concurrency. + if status, err := p.fullReconcile(cp, status, tokensSecret, clusterPlan, true); err != nil { + return status, err + } + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseFinished) + case rkev1.ETCDSnapshotPhaseFinished: + return status, nil + default: + return p.setEtcdSnapshotRestoreState(status, cp.Spec.ETCDSnapshotRestore, rkev1.ETCDSnapshotPhaseStarted) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore_test.go new file mode 100644 index 0000000..b5715b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/etcdrestore_test.go @@ -0,0 +1,281 @@ +package planner + +import ( + "testing" + "time" + + "github.com/golang/mock/gomock" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func TestForceDeleteAllDeletingEtcdMachines(t *testing.T) { + t.Parallel() + + timeNow := metav1.NewTime(time.Now()) + setup := func(t *testing.T, mp *mockPlanner) { + mp.machines.EXPECT().Update(gomock.Any()).DoAndReturn(func(machine *capi.Machine) (*capi.Machine, error) { + assert.Equal(t, machine.Annotations[capi.ExcludeNodeDrainingAnnotation], "true") + return machine, nil + }).AnyTimes() + mp.rkeBootstrapCache.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string) (*rkev1.RKEBootstrap, error) { + return &rkev1.RKEBootstrap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + }, nil + }).AnyTimes() + mp.rkeBootstrap.EXPECT().Update(gomock.Any()).DoAndReturn(func(bootstrap *rkev1.RKEBootstrap) (*rkev1.RKEBootstrap, error) { + assert.Equal(t, bootstrap.Annotations[capr.ForceRemoveEtcdAnnotation], "true") + return bootstrap, nil + }).AnyTimes() + } + + tests := []struct { + name string + controlPlane *rkev1.RKEControlPlane + plan *plan.Plan + expected int + setup func(t *testing.T, mp *mockPlanner) + }{ + { + name: "no machines", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{}, + expected: 0, + setup: nil, + }, + { + name: "no etcd machines", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": {}, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.WorkerRoleLabel: "true", + }, + }, + }, + }, + expected: 0, + setup: nil, + }, + { + name: "non-deleting etcd machine", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": {}, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 0, + setup: nil, + }, + { + name: "nil bootstrap ref", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": { + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: nil, + }, + }, + }, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 0, + setup: nil, + }, + { + name: "non rke.cattle.io APIVersion", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": { + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rancher.testing.io", + }, + }, + }, + }, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 0, + setup: nil, + }, + { + name: "nil annotations", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": { + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &timeNow, + }, + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rke.cattle.io", + }, + }, + }, + }, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 1, + setup: setup, + }, + { + name: "exclude draining false", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": { + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + capi.ExcludeNodeDrainingAnnotation: "false", + }, + DeletionTimestamp: &timeNow, + }, + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rke.cattle.io", + }, + }, + }, + }, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 1, + setup: setup, + }, + { + name: "three deleting etcd", + controlPlane: &rkev1.RKEControlPlane{}, + plan: &plan.Plan{ + Machines: map[string]*capi.Machine{ + "a": { + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &timeNow, + }, + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rke.cattle.io", + }, + }, + }, + }, + "b": { + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &timeNow, + }, + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rke.cattle.io", + }, + }, + }, + }, + "c": { + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &timeNow, + }, + Spec: capi.MachineSpec{ + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + APIVersion: "rke.cattle.io", + }, + }, + }, + }, + }, + Metadata: map[string]*plan.Metadata{ + "a": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + "b": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + "c": { + Labels: map[string]string{ + capr.EtcdRoleLabel: "true", + }, + }, + }, + }, + expected: 3, + setup: setup, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + mp := newMockPlanner(t, InfoFunctions{ + SystemAgentImage: func() string { return "system-agent" }, + ImageResolver: image.ResolveWithControlPlane, + }) + if tt.setup != nil { + tt.setup(t, mp) + } + l, err := mp.planner.forceDeleteAllDeletingEtcdMachines(tt.controlPlane, tt.plan) + assert.NoError(t, err) + assert.Equal(t, tt.expected, l) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/filter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/filter.go new file mode 100644 index 0000000..5605a59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/filter.go @@ -0,0 +1,60 @@ +package planner + +import ( + "context" + + "github.com/rancher/channelserver/pkg/model" + "github.com/rancher/norman/types/convert" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" +) + +func filterConfigData(config map[string]interface{}, controlPlane *rkev1.RKEControlPlane, entry *planEntry) { + var ( + isServer = isControlPlane(entry) || isEtcd(entry) + release = capr.GetKDMReleaseData(context.TODO(), controlPlane) + ) + + if release == nil { + return + } + + for k, v := range config { + if newV, ok := filterField(isServer, k, v, *release); ok { + config[k] = newV + } else { + delete(config, k) + } + } +} + +func filterField(isServer bool, k string, v interface{}, release model.Release) (interface{}, bool) { + if v == nil { + return nil, false + } + + field, fieldFound := release.AgentArgs[k] + if !fieldFound && isServer { + field, fieldFound = release.ServerArgs[k] + } + + // can't find arg + if !fieldFound { + return nil, false + } + + switch v.(type) { + case string: + case bool: + case []interface{}: + default: + // unknown type + return nil, false + } + + if field.Type == "boolean" { + return convert.ToBool(v), true + } + + return v, true +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/idempotent.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/idempotent.go new file mode 100644 index 0000000..bbab447 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/idempotent.go @@ -0,0 +1,115 @@ +package planner + +import ( + "fmt" + "path" + "strings" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" +) + +const idempotentActionScript = ` +#!/bin/sh + +currentHash="" +key=$1 +targetHash=$2 +hashedCmd=$3 +cmd=$4 +caprDir=$5 +shift 5 + +dataRoot="$caprDir/idempotence/$key/$hashedCmd/$targetHash" +attemptFile="$dataRoot/last-attempt" + +currentAttempt=$(cat "$attemptFile" || echo "-1") + +if [ "$currentAttempt" != "$CATTLE_AGENT_ATTEMPT_NUMBER" ]; then + mkdir -p "$dataRoot" + echo "$CATTLE_AGENT_ATTEMPT_NUMBER" > "$attemptFile" + exec "$cmd" "$@" +else + echo "action has already been reconciled to the target hash $targetHash at attempt $currentAttempt" +fi +` + +func idempotentActionScriptPath(controlPlane *rkev1.RKEControlPlane) string { + return path.Join(capr.GetProvisioningDataDir(&controlPlane.Spec.RKEClusterSpecCommon), "idempotence/idempotent.sh") +} + +// generateIdempotencyCleanupInstruction generates a one-time instruction that performs a cleanup of the given key. +func generateIdempotencyCleanupInstruction(controlPlane *rkev1.RKEControlPlane, key string) plan.OneTimeInstruction { + if key == "" { + return plan.OneTimeInstruction{} + } + return plan.OneTimeInstruction{ + Name: "remove idempotency tracking", + Command: "/bin/sh", + Args: []string{ + "-c", + fmt.Sprintf("rm -rf %s/idempotence/%s", capr.GetProvisioningDataDir(&controlPlane.Spec.RKEClusterSpecCommon), key), + }, + } +} + +// idempotentInstruction generates an idempotent action instruction that will execute the given command + args exactly once. +// It works by running a script that writes the given "value" to a file at /var/lib/rancher/capr/idempotence//, +// and checks this file to determine if it needs to run the instruction again. Notably, `identifier` must be a valid relative path. +func idempotentInstruction(controlPlane *rkev1.RKEControlPlane, identifier, value, command string, args []string, env []string) plan.OneTimeInstruction { + hashedCommand := PlanHash([]byte(command)) + hashedValue := PlanHash([]byte(value)) + return plan.OneTimeInstruction{ + Name: fmt.Sprintf("idempotent-%s-%s-%s", identifier, hashedValue, hashedCommand), + Command: "/bin/sh", + Args: append([]string{ + "-x", + idempotentActionScriptPath(controlPlane), + strings.ToLower(identifier), + hashedValue, + hashedCommand, + command, + capr.GetProvisioningDataDir(&controlPlane.Spec.RKEClusterSpecCommon)}, + args...), + Env: env, + } +} + +// convertToIdempotentInstruction converts a OneTimeInstruction to a OneTimeInstruction wrapped with the idempotent script. +// This is useful when an instruction may be used in various phases, without needing idempotency in all cases. +func convertToIdempotentInstruction(controlPlane *rkev1.RKEControlPlane, identifier, value string, instruction plan.OneTimeInstruction) plan.OneTimeInstruction { + newInstruction := idempotentInstruction(controlPlane, identifier, value, instruction.Command, instruction.Args, instruction.Env) + newInstruction.Image = instruction.Image + newInstruction.SaveOutput = instruction.SaveOutput + return newInstruction +} + +// idempotentRestartInstructions generates an idempotent restart instructions for the given runtimeUnit. It checks the +// unit for failure, resets it if necessary, and restarts the unit. +func idempotentRestartInstructions(controlPlane *rkev1.RKEControlPlane, identifier, value, runtimeUnit string) []plan.OneTimeInstruction { + return []plan.OneTimeInstruction{ + idempotentInstruction( + controlPlane, + identifier+"-reset-failed", + value, + "/bin/sh", + []string{ + "-c", + fmt.Sprintf("if [ $(systemctl is-failed %s) = failed ]; then systemctl reset-failed %s; fi", runtimeUnit, runtimeUnit), + }, + []string{}, + ), + idempotentInstruction( + controlPlane, + identifier+"-restart", + value, + "systemctl", + []string{ + "restart", + runtimeUnit, + }, + []string{}, + ), + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/initnode.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/initnode.go new file mode 100644 index 0000000..ad46a39 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/initnode.go @@ -0,0 +1,233 @@ +package planner + +import ( + "errors" + "fmt" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/sirupsen/logrus" +) + +// clearInitNodeMark removes the init node label on the given machine and updates the machine directly against the api +// server, effectively immediately demoting it from being an init node +func (p *Planner) clearInitNodeMark(entry *planEntry) error { + if entry.Metadata.Labels[capr.InitNodeLabel] == "" { + return nil + } + + if err := p.store.removePlanSecretLabel(entry, capr.InitNodeLabel); err != nil { + return err + } + // We've changed state, so let the caches sync up again + return generic.ErrSkip +} + +// setInitNodeMark sets the init node label on the given machine and updates the machine directly against the api +// server. It returns the modified/updated machine object +func (p *Planner) setInitNodeMark(entry *planEntry) error { + if entry.Metadata.Labels[capr.InitNodeLabel] == "true" { + return nil + } + + entry.Metadata.Labels[capr.InitNodeLabel] = "true" + if err := p.store.updatePlanSecretLabelsAndAnnotations(entry); err != nil { + return err + } + + // We've changed state, so let the caches sync up again + return generic.ErrSkip +} + +// findAndDesignateFixedInitNode is used for rancherd where an exact machine (determined by labeling the +// rkecontrolplane object) is desired to be the init node +func (p *Planner) findAndDesignateFixedInitNode(rkeControlPlane *rkev1.RKEControlPlane, plan *plan.Plan) (bool, string, *planEntry, error) { + logrus.Debugf("rkecluster %s/%s: finding and designating fixed init node", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + fixedMachineID := rkeControlPlane.Labels[capr.InitNodeMachineIDLabel] + if fixedMachineID == "" { + return false, "", nil, fmt.Errorf("fixed machine ID label did not exist on rkecontrolplane") + } + entries := collect(plan, func(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Labels[capr.MachineIDLabel] == fixedMachineID + }) + if len(entries) > 1 { + return false, "", nil, fmt.Errorf("multiple machines found with identical machine ID label %s=%s", capr.MachineIDLabel, fixedMachineID) + } else if len(entries) == 0 { + return false, "", nil, fmt.Errorf("fixed machine with ID %s not found", fixedMachineID) + } + if entries[0].Metadata.Labels[capr.InitNodeLabel] != "true" { + logrus.Debugf("rkecluster %s/%s: setting designated init node to fixedMachineID: %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, fixedMachineID) + allInitNodes := collect(plan, isEtcd) + // clear all init node marks and return a generic.ErrSkip if we invalidated caches during clearing + cachesInvalidated := false + for _, entry := range allInitNodes { + if entry.Machine.Labels[capr.MachineIDLabel] == fixedMachineID { + continue + } + err := p.clearInitNodeMark(entry) + if err != nil && !errors.Is(err, generic.ErrSkip) { + // if we received a strange error attempting to clear the init node mark + return false, "", nil, err + } else if errors.Is(err, generic.ErrSkip) { + cachesInvalidated = true + } + } + if cachesInvalidated { + return false, "", nil, generic.ErrSkip + } + + return true, entries[0].Metadata.Annotations[capr.JoinURLAnnotation], entries[0], p.setInitNodeMark(entries[0]) + } + logrus.Debugf("rkecluster %s/%s: designated init node %s found", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, fixedMachineID) + return true, entries[0].Metadata.Annotations[capr.JoinURLAnnotation], entries[0], nil +} + +// findInitNode searches the given cluster for the init node. It returns a bool which is whether an init node was +// found, the init node join URL, and an error for a few conditions, i.e. if multiple init nodes were found or if there +// is a more suitable init node. Notably, if multiple init nodes are found, it will return false as it could not come to +// consensus on a single init node +func (p *Planner) findInitNode(rkeControlPlane *rkev1.RKEControlPlane, plan *plan.Plan) (bool, string, *planEntry, error) { + logrus.Debugf("rkecluster %s/%s searching for init node", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + // if the rkecontrolplane object has an InitNodeMachineID label, we need to find the fixedInitNode. + if rkeControlPlane.Labels[capr.InitNodeMachineIDLabel] != "" { + return p.findAndDesignateFixedInitNode(rkeControlPlane, plan) + } + + currentInitNodes := collect(plan, isInitNode) + + if len(currentInitNodes) > 1 { + // if multiple init nodes are found, we don't know which one to return so return false with an error to hopefully trigger a re-election + return false, "", nil, fmt.Errorf("multiple init nodes found") + } + + initNodeFound := false + var initNode *planEntry + // this loop should never execute more than once + for _, entry := range currentInitNodes { + if canBeInitNode(entry) { + initNodeFound = true + initNode = entry + joinURL := entry.Metadata.Annotations[capr.JoinURLAnnotation] + logrus.Debugf("rkecluster %s/%s found current init node %s with joinURL: %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, entry.Machine.Name, joinURL) + if joinURL != "" { + return true, joinURL, entry, nil + } + } + } + + logrus.Debugf("rkecluster %s/%s: initNodeFound was %t and joinURL is empty", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, initNodeFound) + // If the current init node has an empty joinURL annotation, we can look to see if there are other init nodes that are more suitable + if initNodeFound { + // if the init node was found but doesn't have a joinURL, let's see if there is possible a more suitable init node. + possibleInitNodes := collect(plan, canBeInitNode) + for _, entry := range possibleInitNodes { + if entry.Metadata.Annotations[capr.JoinURLAnnotation] != "" { + // if a non-blank JoinURL was found, return that we found an init node but with an error + return true, "", initNode, fmt.Errorf("non-populated init node found, but more suitable alternative is available") + } + } + // if we got through all possibleInitNodes (or there weren't any other possible init nodes), return true that we found an init node with no error. + logrus.Debugf("rkecluster %s/%s: init node with empty JoinURLAnnotation was found, no suitable alternatives exist", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + return true, "", initNode, nil + } + + return false, "", nil, fmt.Errorf("init node not found") +} + +// electInitNode returns a joinURL and error (if one exists) of an init node. It will first search to see if an init node exists +// (using findInitNode), then will perform a re-election of the most suitable init node (one with a joinURL) and fall back to simply +// electing the first possible init node if no fully populated init node is found. +func (p *Planner) electInitNode(rkeControlPlane *rkev1.RKEControlPlane, plan *plan.Plan, allowReelection bool) (string, error) { + logrus.Debugf("rkecluster %s/%s: determining if election of init node is necessary", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + if initNodeFound, joinURL, _, err := p.findInitNode(rkeControlPlane, plan); (initNodeFound && err == nil) || errors.Is(err, generic.ErrSkip) { + logrus.Debugf("rkecluster %s/%s: init node was already elected and found with joinURL: %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, joinURL) + return joinURL, err + } else if !initNodeFound && rkeControlPlane.Labels[capr.InitNodeMachineIDLabel] != "" { + return "", errWaitingf("unable to find designated init node matching machine ID %s", rkeControlPlane.Labels[capr.InitNodeMachineIDLabel]) + } + // If the joinURL (or an errSkip) was not found, re-elect the init node. + logrus.Debugf("rkecluster %s/%s: performing election of init node", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + + // keep track of whether we invalidate our machine cache when we clear init node marks across nodes. + cachesInvalidated := false + // clear all etcd init node marks because we are re-electing our init node + for _, entry := range collect(plan, isInitNode) { + if !allowReelection { + return "", errWaitingf("rkecluster %s/%s: re-election of init machine %s/%s disallowed", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, entry.Machine.Namespace, entry.Machine.Name) + } + logrus.Debugf("rkecluster %s/%s: clearing init node mark on machine %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, entry.Machine.Name) + if err := p.clearInitNodeMark(entry); errors.Is(err, generic.ErrSkip) { + cachesInvalidated = true + } else if err != nil { + return "", err + } + } + + if cachesInvalidated { + return "", generic.ErrSkip + } + + possibleInitNodes := collect(plan, canBeInitNode) + // Mark the first init node that has a joinURL as our new init node. + for _, entry := range possibleInitNodes { + if joinURL := entry.Metadata.Annotations[capr.JoinURLAnnotation]; joinURL != "" { + logrus.Debugf("rkecluster %s/%s: found %s as fully suitable init node with joinURL: %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, entry.Machine.Name, joinURL) + // it is likely that the error returned by `electInitNode` is going to be `generic.ErrSkip` + return joinURL, p.setInitNodeMark(entry) + } + } + + if len(possibleInitNodes) > 0 { + fallbackInitNode := possibleInitNodes[0] + logrus.Debugf("rkecluster %s/%s: no fully suitable init node was found, marking %s as init node as fallback", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, fallbackInitNode.Machine.Name) + return "", p.setInitNodeMark(fallbackInitNode) + } + + logrus.Debugf("rkecluster %s/%s: failed to elect init node, no suitable init nodes were found", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName) + return "", errWaiting("waiting for viable init node") +} + +// designateInitNodeByID is used to force-designate an init node in the cluster. This is especially useful for things like +// local etcd snapshot restore, where a snapshot may be contained on a specific node and that node needs to be the node that +// the snapshot is restored on. +func (p *Planner) designateInitNodeByMachineID(rkeControlPlane *rkev1.RKEControlPlane, plan *plan.Plan, machineID string) (string, error) { + if machineID == "" { + return "", fmt.Errorf("machineID cannot be empty when designating init node") + } + logrus.Debugf("rkecluster %s/%s: ensuring designated init node for machine ID: %s", rkeControlPlane.Namespace, rkeControlPlane.Spec.ClusterName, machineID) + entries := collect(plan, isEtcd) + cacheInvalidated := false + joinURL := "" + initNodeFound := false + for _, entry := range entries { + if entry.Machine.Labels[capr.MachineIDLabel] == machineID { + // this is our new initNode + initNodeFound = true + if err := p.setInitNodeMark(entry); err != nil { + if errors.Is(err, generic.ErrSkip) { + cacheInvalidated = true + continue + } + return "", err + } + joinURL = entry.Metadata.Annotations[capr.JoinURLAnnotation] + } else { + if err := p.clearInitNodeMark(entry); err != nil { + if errors.Is(err, generic.ErrSkip) { + cacheInvalidated = true + continue + } + return "", err + } + } + } + if !initNodeFound { + return "", fmt.Errorf("rkecluster %s/%s: init node with machine ID %s was not found during designation", rkeControlPlane.Namespace, rkeControlPlane.Name, machineID) + } + if cacheInvalidated { + return joinURL, generic.ErrSkip + } + return joinURL, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions.go new file mode 100644 index 0000000..1b2de99 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions.go @@ -0,0 +1,175 @@ +package planner + +import ( + "fmt" + "path" + "strings" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" +) + +const ( + captureAddressInstructionName = "capture-address" + etcdNameInstructionName = "etcd-name" +) + +// generateInstallInstruction generates the instruction necessary to install the desired tool. +func (p *Planner) generateInstallInstruction(controlPlane *rkev1.RKEControlPlane, entry *planEntry, env []string) plan.OneTimeInstruction { + var instruction plan.OneTimeInstruction + image := p.getInstallerImage(controlPlane) + cattleOS := entry.Metadata.Labels[capr.CattleOSLabel] + for _, arg := range controlPlane.Spec.AgentEnvVars { + if arg.Value == "" { + continue + } + switch cattleOS { + case capr.WindowsMachineOS: + env = append(env, fmt.Sprintf("$env:%s=\"%s\"", arg.Name, arg.Value)) + default: + env = append(env, fmt.Sprintf("%s=%s", arg.Name, arg.Value)) + } + } + switch cattleOS { + case capr.WindowsMachineOS: + env = append(env, fmt.Sprintf("$env:%s_DATA_DIR=\"c:%s\"", strings.ToUpper(capr.GetRuntime(controlPlane.Spec.KubernetesVersion)), capr.GetDistroDataDir(controlPlane))) + default: + env = append(env, fmt.Sprintf("%s_DATA_DIR=%s", strings.ToUpper(capr.GetRuntime(controlPlane.Spec.KubernetesVersion)), capr.GetDistroDataDir(controlPlane))) + } + + switch cattleOS { + case capr.WindowsMachineOS: + instruction = plan.OneTimeInstruction{ + Name: "install", + Image: image, + Command: "powershell.exe", + Args: []string{"-File", "run.ps1"}, + Env: env, + } + default: + instruction = plan.OneTimeInstruction{ + Name: "install", + Image: image, + Command: "sh", + Args: []string{"-c", "run.sh"}, + Env: env, + } + } + + if isOnlyWorker(entry) { + switch cattleOS { + case capr.WindowsMachineOS: + instruction.Env = append(instruction.Env, fmt.Sprintf("$env:INSTALL_%s_EXEC=\"agent\"", capr.GetRuntimeEnv(controlPlane.Spec.KubernetesVersion))) + default: + instruction.Env = append(instruction.Env, fmt.Sprintf("INSTALL_%s_EXEC=agent", capr.GetRuntimeEnv(controlPlane.Spec.KubernetesVersion))) + } + } + + return instruction +} + +// addInstallInstructionWithRestartStamp will generate an instruction and append it to the node plan that executes the `run.sh` or `run.ps1` +// from the installer image based on the control plane configuration. It will generate a restart stamp based on the +// passed in configuration to determine whether it needs to start/restart the service being managed. +func (p *Planner) addInstallInstructionWithRestartStamp(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane, entry *planEntry) (plan.NodePlan, error) { + var restartStampEnv string + stamp := restartStamp(nodePlan, controlPlane, p.getInstallerImage(controlPlane)) + switch entry.Metadata.Labels[capr.CattleOSLabel] { + case capr.WindowsMachineOS: + restartStampEnv = "$env:RESTART_STAMP=\"" + stamp + "\"" + default: + restartStampEnv = "RESTART_STAMP=" + stamp + } + instEnv := []string{restartStampEnv} + nodePlan.Instructions = append(nodePlan.Instructions, p.generateInstallInstruction(controlPlane, entry, instEnv)) + return nodePlan, nil +} + +// generateInstallInstructionWithSkipStart will generate an instruction that executes the `run.sh` or `run.ps1` +// from the installer image based on the control plane configuration. It will add a `SKIP_START` environment variable to prevent +// the service from being started/restarted. +func (p *Planner) generateInstallInstructionWithSkipStart(controlPlane *rkev1.RKEControlPlane, entry *planEntry) plan.OneTimeInstruction { + var skipStartEnv string + switch entry.Metadata.Labels[capr.CattleOSLabel] { + case capr.WindowsMachineOS: + skipStartEnv = fmt.Sprintf("$env:INSTALL_%s_SKIP_START=\"true\"", strings.ToUpper(capr.GetRuntime(controlPlane.Spec.KubernetesVersion))) + default: + skipStartEnv = fmt.Sprintf("INSTALL_%s_SKIP_START=true", strings.ToUpper(capr.GetRuntime(controlPlane.Spec.KubernetesVersion))) + } + instEnv := []string{skipStartEnv} + return p.generateInstallInstruction(controlPlane, entry, instEnv) +} + +func (p *Planner) addInitNodePeriodicInstruction(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane) (plan.NodePlan, error) { + nodePlan.PeriodicInstructions = append(nodePlan.PeriodicInstructions, []plan.PeriodicInstruction{ + { + Name: captureAddressInstructionName, + Command: "sh", + Args: []string{ + "-c", + // the grep here is to make the command fail if we don't get the output we expect, like empty string. + fmt.Sprintf("curl -f --retry 100 --retry-delay 5 --cacert %s https://localhost:%d/db/info | grep 'clientURLs'", + path.Join(capr.GetDistroDataDir(controlPlane), "server/tls/server-ca.crt"), + capr.GetRuntimeSupervisorPort(controlPlane.Spec.KubernetesVersion)), + }, + PeriodSeconds: 600, + }, + { + Name: etcdNameInstructionName, + Command: "sh", + Args: []string{ + "-c", + fmt.Sprintf("cat %s", path.Join(capr.GetDistroDataDir(controlPlane), "server/db/etcd/name")), + }, + PeriodSeconds: 600, + }, + }...) + return nodePlan, nil +} + +func (p *Planner) addEtcdSnapshotListLocalPeriodicInstruction(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane) (plan.NodePlan, error) { + nodePlan.PeriodicInstructions = append(nodePlan.PeriodicInstructions, plan.PeriodicInstruction{ + Name: "etcd-snapshot-list-local", + Command: "sh", + Args: []string{ + "-c", + // the grep here is to make the command fail if we don't get the output we expect, like empty string. + fmt.Sprintf("%s etcd-snapshot list --etcd-s3=false 2>/dev/null", + capr.GetRuntime(controlPlane.Spec.KubernetesVersion)), + }, + PeriodSeconds: 600, + }) + return nodePlan, nil +} + +func (p *Planner) addEtcdSnapshotListS3PeriodicInstruction(nodePlan plan.NodePlan, controlPlane *rkev1.RKEControlPlane) (plan.NodePlan, error) { + nodePlan.PeriodicInstructions = append(nodePlan.PeriodicInstructions, plan.PeriodicInstruction{ + Name: "etcd-snapshot-list-s3", + Command: "sh", + Args: []string{ + "-c", + // the grep here is to make the command fail if we don't get the output we expect, like empty string. + fmt.Sprintf("%s etcd-snapshot list --etcd-s3 2>/dev/null", + capr.GetRuntime(controlPlane.Spec.KubernetesVersion)), + }, + PeriodSeconds: 600, + }) + return nodePlan, nil +} + +// generateManifestRemovalInstruction generates a rm -rf command for the manifests of a server. This was created in response to https://github.com/rancher/rancher/issues/41174 +func generateManifestRemovalInstruction(controlPlane *rkev1.RKEControlPlane, entry *planEntry) (bool, plan.OneTimeInstruction) { + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + if runtime == "" || entry == nil || roleNot(roleOr(isEtcd, isControlPlane))(entry) { + return false, plan.OneTimeInstruction{} + } + return true, plan.OneTimeInstruction{ + Name: "remove server manifests", + Command: "/bin/sh", + Args: []string{ + "-c", + fmt.Sprintf("rm -rf %s/%s-*.yaml", path.Join(capr.GetDistroDataDir(controlPlane), "server/manifests"), runtime), + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions_test.go new file mode 100644 index 0000000..ee1582d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/instructions_test.go @@ -0,0 +1,260 @@ +package planner + +import ( + "testing" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/stretchr/testify/assert" +) + +func TestPlanner_generateInstallInstruction(t *testing.T) { + type args struct { + version string + expectedVersion string + os string + command string + scriptName string + envs []string + expectedEnvsLen int + image string + expectedImage string + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking Empty Linux Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{}, + expectedEnvsLen: 2, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + { + name: "Checking Empty Windows Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "windows", + command: "powershell.exe", + scriptName: "run.ps1", + envs: []string{}, + expectedEnvsLen: 2, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + { + name: "Checking Linux Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{"HTTP_PROXY", "HTTPS_PROXY", "INSTALL_RKE2_EXEC"}, + expectedEnvsLen: 4, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + { + name: "Checking Windows Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "windows", + command: "powershell.exe", + scriptName: "run.ps1", + envs: []string{"$env:HTTP_PROXY", "$env:HTTPS_PROXY", "$env:INSTALL_RKE2_EXEC"}, + expectedEnvsLen: 4, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + controlPlane := createTestControlPlane(tt.args.version) + if len(tt.args.envs) != 0 { + controlPlane.Spec.AgentEnvVars = []v1.EnvVar{{Name: "HTTP_PROXY", Value: "0.0.0.0"}, {Name: "HTTPS_PROXY", Value: "0.0.0.0"}} + } + entry := createTestPlanEntry(tt.args.os) + var planner Planner + planner.retrievalFunctions.SystemAgentImage = func() string { return tt.args.image } + planner.retrievalFunctions.ImageResolver = image.ResolveWithControlPlane + // act + p := planner.generateInstallInstruction(controlPlane, entry, []string{}) + + // assert + a.NotNil(p) + a.Contains(p.Command, tt.args.command) + a.Contains(p.Args, tt.args.scriptName) + a.Equal(p.Image, tt.args.expectedImage) + a.Equal(tt.args.expectedEnvsLen, len(p.Env)) + for _, e := range tt.args.envs { + a.True(findEnv(p.Env, e), "couldn't find %s in environment", e) + } + }) + } +} + +func TestPlanner_addInstallInstructionWithRestartStamp(t *testing.T) { + type args struct { + version string + expectedVersion string + os string + command string + scriptName string + envs []string + image string + expectedImage string + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking Linux Plan restart stamp", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{"RESTART_STAMP"}, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + { + name: "Checking Windows plan restart stamp", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "windows", + command: "powershell.exe", + scriptName: "run.ps1", + envs: []string{"$env:RESTART_STAMP"}, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + var planner Planner + planner.retrievalFunctions.SystemAgentImage = func() string { return tt.args.image } + planner.retrievalFunctions.ImageResolver = image.ResolveWithControlPlane + controlPlane := createTestControlPlane(tt.args.version) + entry := createTestPlanEntry(tt.args.os) + + // act + p, err := planner.addInstallInstructionWithRestartStamp(plan.NodePlan{}, controlPlane, entry) + + // assert + a.Nil(err) + a.NotNil(p) + a.Equal(entry.Metadata.Labels[capr.CattleOSLabel], tt.args.os) + a.NotZero(len(p.Instructions)) + instruction := p.Instructions[0] + a.Contains(instruction.Image, tt.args.expectedVersion) + a.Equal(instruction.Image, tt.args.expectedImage) + a.Contains(instruction.Command, tt.args.command) + a.Contains(instruction.Image, tt.args.expectedVersion) + a.Contains(instruction.Args, tt.args.scriptName) + a.GreaterOrEqual(len(instruction.Env), 1) + for _, e := range tt.args.envs { + a.True(findEnv(instruction.Env, e), "couldn't find %s in environment", e) + } + }) + } +} + +func TestPlanner_generateInstallInstructionWithSkipStart(t *testing.T) { + type args struct { + version string + expectedVersion string + os string + command string + scriptName string + envs []string + image string + expectedImage string + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking Linux Plan skip restart", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{"INSTALL_RKE2_SKIP_START=true"}, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + { + name: "Checking Windows plan skip restart", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "windows", + command: "powershell.exe", + scriptName: "run.ps1", + envs: []string{"$env:INSTALL_RKE2_SKIP_START=\"true\""}, + image: "my/custom-image-", + expectedImage: "my/custom-image-rke2:v1.21.5-rke2r2", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + var planner Planner + planner.retrievalFunctions.SystemAgentImage = func() string { return tt.args.image } + planner.retrievalFunctions.ImageResolver = image.ResolveWithControlPlane + controlPlane := createTestControlPlane(tt.args.version) + entry := createTestPlanEntry(tt.args.os) + + // act + p := planner.generateInstallInstructionWithSkipStart(controlPlane, entry) + + // assert + a.NotNil(p) + a.Equal(entry.Metadata.Labels[capr.CattleOSLabel], tt.args.os) + a.Contains(p.Image, tt.args.expectedVersion) + a.Equal(p.Image, tt.args.expectedImage) + a.Contains(p.Command, tt.args.command) + a.Contains(p.Image, tt.args.expectedVersion) + a.Contains(p.Args, tt.args.scriptName) + a.GreaterOrEqual(len(p.Env), 1) + for _, e := range tt.args.envs { + a.True(findEnv(p.Env, e), "couldn't find %s in environment", e) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/manifests.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/manifests.go new file mode 100644 index 0000000..94f09a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/manifests.go @@ -0,0 +1,92 @@ +package planner + +import ( + "encoding/base64" + "fmt" + "path" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const EtcdSnapshotExtraMetadataConfigMapTemplate = ` +apiVersion: v1 +kind: ConfigMap +metadata: + name: %s-etcd-snapshot-extra-metadata + namespace: %s +data: + %s: %s +` + +// getControlPlaneManifests returns a slice of plan.File objects that are necessary to be placed on a controlplane node. +func (p *Planner) getControlPlaneManifests(controlPlane *rkev1.RKEControlPlane, entry *planEntry) (result []plan.File, _ error) { + // NOTE: The agent does not have a means to delete files. If you add a manifest that + // may not exist in the future then you should create an empty file to "delete" the file + if !isControlPlane(entry) { + return nil, nil + } + + clusterAgent, err := p.getClusterAgentManifestFile(controlPlane, entry) + if err != nil { + return nil, err + } + result = append(result, clusterAgent) + + // if we have a nil snapshotMetadata object, it's probably because the annotation didn't exist on the controlplane object. this is not breaking though so don't block. + snapshotMetadata := getEtcdSnapshotExtraMetadata(controlPlane, capr.GetRuntime(controlPlane.Spec.KubernetesVersion)) + if snapshotMetadata == nil { + logrus.Errorf("Error while generating etcd snapshot extra metadata manifest for cluster %s", controlPlane.Spec.ClusterName) + } else { + result = append(result, *snapshotMetadata) + } + + addons := p.getAddons(controlPlane) + result = append(result, addons) + + return result, nil +} + +// getEtcdSnapshotExtraMetadata returns a plan.File that contains the ConfigMap manifest of the cluster specification, if it exists. +// Otherwise, it will return an empty plan.File and log an error. +func getEtcdSnapshotExtraMetadata(controlPlane *rkev1.RKEControlPlane, runtime string) *plan.File { + if v, ok := controlPlane.Annotations[capr.ClusterSpecAnnotation]; ok { + cm := fmt.Sprintf(EtcdSnapshotExtraMetadataConfigMapTemplate, runtime, metav1.NamespaceSystem, EtcdSnapshotConfigMapKey, v) + return &plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(cm)), + Path: path.Join(capr.GetDistroDataDir(controlPlane), fmt.Sprintf("server/manifests/rancher/%s-etcd-snapshot-extra-metadata.yaml", runtime)), + Dynamic: true, + Minor: true, + } + } + + logrus.Errorf("rkecluster %s/%s: unable to find cluster spec annotation for control plane", controlPlane.Spec.ClusterName, controlPlane.Namespace) + return nil +} + +// getClusterAgentManifestFile returns a plan.File that contains the cluster agent manifest. +func (p *Planner) getClusterAgentManifestFile(controlPlane *rkev1.RKEControlPlane, entry *planEntry) (plan.File, error) { + data, err := p.generateClusterAgentManifest(controlPlane, entry) + if err != nil { + return plan.File{}, err + } + + return plan.File{ + Content: base64.StdEncoding.EncodeToString(data), + Path: path.Join(capr.GetDistroDataDir(controlPlane), "server/manifests/rancher/cluster-agent.yaml"), + Dynamic: true, + Minor: true, + }, nil +} + +// getAddons returns a plan.File that contains the content of the defined additional manifests. +func (p *Planner) getAddons(controlPlane *rkev1.RKEControlPlane) plan.File { + return plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(controlPlane.Spec.AdditionalManifest)), + Path: path.Join(capr.GetDistroDataDir(controlPlane), "server/manifests/rancher/addons.yaml"), + Dynamic: true, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/messages.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/messages.go new file mode 100644 index 0000000..7c84553 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/messages.go @@ -0,0 +1,52 @@ +package planner + +import ( + "fmt" + "sort" + "strings" + + "github.com/rancher/rancher/pkg/capr" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func atMostThree(names []string) string { + sort.Strings(names) + if len(names) > 3 { + return fmt.Sprintf("%s and %d more", strings.Join(names[:3], ","), len(names)-3) + } + return strings.Join(names, ",") +} + +func detailedMessage(machines []string, messages map[string][]string) string { + if len(machines) != 1 { + return "" + } + message := messages[machines[0]] + if len(message) != 0 { + return fmt.Sprintf(": %s", strings.Join(message, ", ")) + } + return "" +} + +// removeReconciledCondition removes the condition "Reconciled" from a CAPI machine object so that messages are not +// duplicated during summarization. +func removeReconciledCondition(machine *capi.Machine) *capi.Machine { + if machine == nil || len(machine.Status.Conditions) == 0 { + return machine + } + + conds := make([]capi.Condition, 0, len(machine.Status.Conditions)) + for _, c := range machine.Status.Conditions { + if string(c.Type) != string(capr.Reconciled) { + conds = append(conds, c) + } + } + + if len(conds) == len(machine.Status.Conditions) { + return machine + } + + machine = machine.DeepCopy() + machine.SetConditions(conds) + return machine +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planentry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planentry.go new file mode 100644 index 0000000..6e5ac2d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planentry.go @@ -0,0 +1,184 @@ +package planner + +import ( + "sort" + + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type planEntry struct { + Machine *capi.Machine + Plan *plan.Node + Metadata *plan.Metadata +} + +type roleFilter func(*planEntry) bool + +func collectAndValidateAnnotationValue(p *plan.Plan, validation roleFilter, annotation, value string) bool { + for machineName, machine := range p.Machines { + entry := &planEntry{ + Machine: machine, + Plan: p.Nodes[machineName], + Metadata: p.Metadata[machineName], + } + if !validation(entry) { + continue + } + if entry.Metadata.Annotations[annotation] == value { + return true + } + } + return false +} + +func collect(p *plan.Plan, include roleFilter) (result []*planEntry) { + for machineName, machine := range p.Machines { + entry := &planEntry{ + Machine: machine, + Plan: p.Nodes[machineName], + Metadata: p.Metadata[machineName], + } + if !include(entry) { + continue + } + result = append(result, entry) + } + + sort.Slice(result, func(i, j int) bool { + return result[i].Machine.Name < result[j].Machine.Name + }) + + return result +} + +func isEtcd(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Labels[capr.EtcdRoleLabel] == "true" +} + +func isInitNode(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Labels[capr.InitNodeLabel] == "true" +} + +func isInitNodeOrDeleting(entry *planEntry) bool { + return isInitNode(entry) || isDeleting(entry) +} + +func IsEtcdOnlyInitNode(entry *planEntry) bool { + return isInitNode(entry) && IsOnlyEtcd(entry) +} + +func isNotInitNodeOrIsDeleting(entry *planEntry) bool { + return !isInitNode(entry) || isDeleting(entry) +} + +func isDeleting(entry *planEntry) bool { + return entry.Machine.DeletionTimestamp != nil +} + +func isNotDeleting(entry *planEntry) bool { + return !isDeleting(entry) +} + +func isNotDeletingAndControlPlaneOrInitNode(entry *planEntry) bool { + return !isDeleting(entry) && (isControlPlane(entry) || isInitNode(entry)) +} + +// isFailed returns true if the provided entry machine.status.phase is failed +func isFailed(entry *planEntry) bool { + return entry.Machine.Status.Phase == string(capi.MachinePhaseFailed) +} + +// canBeInitNode returns true if the provided entry is an etcd node, is not deleting, is not failed, and has its infrastructure ready +// We should wait for the infrastructure condition to be marked as ready because we need the IP address(es) set prior to bootstrapping the node. +func canBeInitNode(entry *planEntry) bool { + return isEtcd(entry) && !isDeleting(entry) && !isFailed(entry) && capr.InfrastructureReady.IsTrue(entry.Machine) +} + +func isControlPlane(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Labels[capr.ControlPlaneRoleLabel] == "true" +} + +func isControlPlaneAndNotInitNode(entry *planEntry) bool { + return isControlPlane(entry) && !isInitNode(entry) +} + +func isControlPlaneEtcd(entry *planEntry) bool { + return isControlPlane(entry) || isEtcd(entry) +} + +func IsOnlyEtcd(entry *planEntry) bool { + return isEtcd(entry) && !isControlPlane(entry) +} + +func isOnlyControlPlane(entry *planEntry) bool { + return !isEtcd(entry) && isControlPlane(entry) +} + +func isWorker(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Labels[capr.WorkerRoleLabel] == "true" +} + +func noRole(entry *planEntry) bool { + return !isEtcd(entry) && !isControlPlane(entry) && !isWorker(entry) +} + +func anyRole(entry *planEntry) bool { + return !noRole(entry) +} + +func anyRoleWithoutWindows(entry *planEntry) bool { + return !noRole(entry) && !windows(entry) +} + +func isOnlyWorker(entry *planEntry) bool { + return !isEtcd(entry) && !isControlPlane(entry) && isWorker(entry) +} + +func windows(entry *planEntry) bool { + if entry == nil || entry.Metadata == nil { + return false + } + if val, ok := entry.Metadata.Labels[capr.CattleOSLabel]; ok { + return val == capr.WindowsMachineOS + } + return false +} + +func anyPlanDataExists(entry *planEntry) bool { + if entry.Plan != nil { + return entry.Plan.PlanDataExists + } + return false +} + +func validJoinURL(plan *plan.Plan, joinURL string) bool { + return collectAndValidateAnnotationValue(plan, isNotDeletingAndControlPlaneOrInitNode, capr.JoinURLAnnotation, joinURL) +} + +func hasJoinURL(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Annotations[capr.JoinURLAnnotation] != "" +} + +func hasJoinedTo(entry *planEntry) bool { + return entry.Metadata != nil && entry.Metadata.Annotations[capr.JoinedToAnnotation] != "" +} + +func roleAnd(r1, r2 roleFilter) roleFilter { + return func(entry *planEntry) bool { + return r1(entry) && r2(entry) + } +} + +func roleOr(r1, r2 roleFilter) roleFilter { + return func(entry *planEntry) bool { + return r1(entry) || r2(entry) + } +} + +func roleNot(r1 roleFilter) roleFilter { + return func(entry *planEntry) bool { + return !r1(entry) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner.go new file mode 100644 index 0000000..16015e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner.go @@ -0,0 +1,1220 @@ +package planner + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "hash/crc32" + "math" + "path" + "path/filepath" + "reflect" + "strconv" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/moby/locker" + "github.com/rancher/channelserver/pkg/model" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + ranchercontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontrollers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/rancher/wrangler/v3/pkg/summary" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierror "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + capiannotations "sigs.k8s.io/cluster-api/util/annotations" + "sigs.k8s.io/cluster-api/util/conditions" +) + +const ( + clusterRegToken = "clusterRegToken" + + EtcdSnapshotConfigMapKey = "provisioning-cluster-spec" + + KubeControllerManagerArg = "kube-controller-manager-arg" + KubeControllerManagerExtraMount = "kube-controller-manager-extra-mount" + DefaultKubeControllerManagerCertDir = "server/tls/kube-controller-manager" + DefaultKubeControllerManagerDefaultSecurePort = "10257" + DefaultKubeControllerManagerCert = "kube-controller-manager.crt" + KubeSchedulerArg = "kube-scheduler-arg" + KubeSchedulerExtraMount = "kube-scheduler-extra-mount" + DefaultKubeSchedulerCertDir = "server/tls/kube-scheduler" + DefaultKubeSchedulerDefaultSecurePort = "10259" + DefaultKubeSchedulerCert = "kube-scheduler.crt" + SecurePortArgument = "secure-port" + CertDirArgument = "cert-dir" + TLSCertFileArgument = "tls-cert-file" + + authnWebhookFileName = "kube-api-authn-webhook.yaml" + ConfigYamlFileName = "/etc/rancher/%s/config.yaml.d/50-rancher.yaml" + + bootstrapTier = "bootstrap" + etcdTier = "etcd" + controlPlaneTier = "control plane" + workerTier = "worker" + + auditPolicyArg = "audit-policy-file" + cloudProviderConfigArg = "cloud-provider-config" + privateRegistryArg = "private-registry" + flannelConfArg = "flannel-conf" + + AuthnWebhook = ` +apiVersion: v1 +kind: Config +clusters: +- name: Default + cluster: + insecure-skip-tls-verify: true + server: http://%s:6440/v1/authenticate +users: +- name: Default + user: + insecure-skip-tls-verify: true +current-context: webhook +contexts: +- name: webhook + context: + user: Default + cluster: Default +` +) + +var ( + fileParams = []string{ + auditPolicyArg, + cloudProviderConfigArg, + privateRegistryArg, + flannelConfArg, + } + filePaths = map[string]string{ + privateRegistryArg: "/etc/rancher/%s/registries.yaml", + } +) + +type Planner struct { + ctx context.Context + store *PlanStore + rkeBootstrap rkecontrollers.RKEBootstrapClient + rkeBootstrapCache rkecontrollers.RKEBootstrapCache + rkeControlPlanes rkecontrollers.RKEControlPlaneController + etcdSnapshotCache rkecontrollers.ETCDSnapshotCache + secretClient corecontrollers.SecretClient + secretCache corecontrollers.SecretCache + configMapCache corecontrollers.ConfigMapCache + machines capicontrollers.MachineClient + machinesCache capicontrollers.MachineCache + clusterRegistrationTokenCache mgmtcontrollers.ClusterRegistrationTokenCache + capiClient capicontrollers.ClusterClient + capiClusters capicontrollers.ClusterCache + managementClusters mgmtcontrollers.ClusterCache + rancherClusterCache ranchercontrollers.ClusterCache + locker locker.Locker + etcdS3Args s3Args + retrievalFunctions InfoFunctions +} + +// InfoFunctions is a struct that contains various dynamic functions that allow for abstracting out Rancher-specific +// logic from the Planner +type InfoFunctions struct { + ImageResolver func(image string, cp *rkev1.RKEControlPlane) string + ReleaseData func(context.Context, *rkev1.RKEControlPlane) *model.Release + SystemAgentImage func() string + SystemPodLabelSelectors func(plane *rkev1.RKEControlPlane) []string +} + +func New(ctx context.Context, clients *wrangler.Context, functions InfoFunctions) *Planner { + clients.Mgmt.ClusterRegistrationToken().Cache().AddIndexer(clusterRegToken, func(obj *v3.ClusterRegistrationToken) ([]string, error) { + return []string{obj.Spec.ClusterName}, nil + }) + store := NewStore(clients.Core.Secret(), + clients.CAPI.Machine().Cache()) + return &Planner{ + ctx: ctx, + store: store, + machines: clients.CAPI.Machine(), + machinesCache: clients.CAPI.Machine().Cache(), + secretClient: clients.Core.Secret(), + secretCache: clients.Core.Secret().Cache(), + configMapCache: clients.Core.ConfigMap().Cache(), + clusterRegistrationTokenCache: clients.Mgmt.ClusterRegistrationToken().Cache(), + capiClient: clients.CAPI.Cluster(), + capiClusters: clients.CAPI.Cluster().Cache(), + managementClusters: clients.Mgmt.Cluster().Cache(), + rancherClusterCache: clients.Provisioning.Cluster().Cache(), + rkeControlPlanes: clients.RKE.RKEControlPlane(), + rkeBootstrap: clients.RKE.RKEBootstrap(), + rkeBootstrapCache: clients.RKE.RKEBootstrap().Cache(), + etcdSnapshotCache: clients.RKE.ETCDSnapshot().Cache(), + etcdS3Args: s3Args{ + secretCache: clients.Core.Secret().Cache(), + }, + retrievalFunctions: functions, + } +} + +func (p *Planner) setMachineConditionStatus(clusterPlan *plan.Plan, machineNames []string, messagePrefix string, messages map[string][]string) error { + var waiting bool + for _, machineName := range machineNames { + machine := clusterPlan.Machines[machineName] + if machine == nil { + return fmt.Errorf("found unexpected machine %s that is not in cluster plan", machineName) + } + + if !capr.InfrastructureReady.IsTrue(machine) { + waiting = true + continue + } + + machine = machine.DeepCopy() + if message := messages[machineName]; len(message) > 0 { + msg := strings.Join(message, ", ") + waiting = true + if capr.Reconciled.GetMessage(machine) == msg { + continue + } + conditions.MarkUnknown(machine, capi.ConditionType(capr.Reconciled), "Waiting", msg) + } else if !capr.Reconciled.IsTrue(machine) { + // Since there is no status message, then the condition should be set to true. + conditions.MarkTrue(machine, capi.ConditionType(capr.Reconciled)) + + // Even though we are technically not waiting for something, an error should be returned so that the planner will retry. + // The machine being updated will cause the planner to re-enqueue with the new data. + waiting = true + } else { + continue + } + + if _, err := p.machines.UpdateStatus(machine); err != nil { + return err + } + } + + if waiting { + return errWaiting(messagePrefix + atMostThree(machineNames) + detailedMessage(machineNames, messages)) + } + return nil +} + +func (p *Planner) Process(cp *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + logrus.Debugf("[planner] rkecluster %s/%s: attempting to lock %s for processing", cp.Namespace, cp.Name, string(cp.UID)) + p.locker.Lock(string(cp.UID)) + defer func(namespace, name, uid string) { + logrus.Debugf("[planner] rkecluster %s/%s: unlocking %s", namespace, name, uid) + _ = p.locker.Unlock(uid) + }(cp.Namespace, cp.Name, string(cp.UID)) + + currentVersion, err := semver.NewVersion(cp.Spec.KubernetesVersion) + if err != nil { + return status, fmt.Errorf("rkecluster %s/%s: error semver parsing kubernetes version %s: %v", cp.Namespace, cp.Name, cp.Spec.KubernetesVersion, err) + } + + releaseData := p.retrievalFunctions.ReleaseData(p.ctx, cp) + if releaseData == nil { + return status, errWaitingf("%s/%s: releaseData nil for version %s", cp.Namespace, cp.Name, cp.Spec.KubernetesVersion) + } + + capiCluster, err := capr.GetOwnerCAPICluster(cp, p.capiClusters) + if err != nil { + if apierrors.IsNotFound(err) { + return status, errWaiting("CAPI cluster does not exist") + } + return status, err + } + + if capiCluster == nil { + return status, errWaiting("CAPI cluster does not exist") + } + + if !capiCluster.DeletionTimestamp.IsZero() { + // because we pause reconciliation during encryption key rotation and cert rotation, unpause it. This is effectively + // a hack since the planner pauses the entire cluster during + if capiannotations.IsPaused(capiCluster, cp) { + err = p.pauseCAPICluster(cp, false) + if err != nil { + logrus.Errorf("error unpausing CAPI cluster during deletion: %s", err) + } + } + logrus.Infof("[planner] %s/%s: reconciliation stopped: CAPI cluster is deleting", cp.Namespace, cp.Name) + return status, nil + } + + if !capiCluster.Status.InfrastructureReady { + return status, errWaiting("waiting for infrastructure ready") + } + + plan, anyPlansDelivered, err := p.store.Load(capiCluster, cp) + if err != nil { + return status, err + } + + // Check for cluster sanity to ensure we can properly deliver plans to this cluster. + if !clusterIsSane(plan) { + // Set the Stable condition on the controlplane to False. This will be used to indicate that the Ready condition + // on the v1 cluster object should be set from the rkecontrolplane Provisioned condition rather than the v3 + // cluster objects Ready condition. + capr.Stable.False(&status) + + // Set the `initialized` and `ready` status fields on the status to false, as the cluster is not sane and cannot + // be considered initialized. This is to also prevent CAPI from setting the ControlPlaneInitialized condition + // using fallback logic from the status field. + if status.Initialized || status.Ready { + status.Initialized = false + status.Ready = false + logrus.Debugf("[planner] rkecluster %s/%s: setting controlplane ready/initialized to false as cluster was not sane", cp.Namespace, cp.Name) + return status, errWaitingf("uninitializing rkecontrolplane %s/%s", cp.Namespace, cp.Name) + } + + // Uninitialize the CAPI ClusterControlPlaneInitialized condition so that CAPI controllers don't get hung up and will take ownership of new RKEBootstraps (amongst other objects) + if err := p.ensureCAPIClusterControlPlaneInitializedFalse(cp); err != nil { + return status, errWaitingf("uninitializing CAPI cluster: %v", err) + } + + // Collect all nodes that are etcd and deleting. At this point, if we have any etcd nodes left in the cluster, + // they will be deleting, so force delete them to prevent quorum loss. + etcdDeleting, err := p.forceDeleteAllDeletingEtcdMachines(cp, plan) + if err != nil { + return status, err + } else if etcdDeleting != 0 { + return status, errWaiting("waiting for all etcd machines to be deleted") + } + return status, errWaiting("waiting for at least one control plane, etcd, and worker node to be registered") + } + + capr.Provisioned.True(&status) + capr.Provisioned.Message(&status, "") + capr.Provisioned.Reason(&status, "") + + _, clusterSecretTokens, err := p.ensureRKEStateSecret(cp, !anyPlansDelivered) + if err != nil { + return status, err + } + + if status, err = p.createEtcdSnapshot(cp, status, clusterSecretTokens, plan); err != nil { + return status, err + } + + if status, err = p.restoreEtcdSnapshot(cp, status, clusterSecretTokens, plan, currentVersion); err != nil { + return status, err + } + + if status, err = p.rotateCertificates(cp, status, clusterSecretTokens, plan); err != nil { + return status, err + } + + if status, err = p.rotateEncryptionKeys(cp, status, clusterSecretTokens, plan, releaseData); err != nil { + return status, err + } + + // pausing the control plane only affects machine reconciliation: etcd snapshot/restore, encryption key & cert + // rotation are not interruptable processes, and therefore must always be completed when requested + if capiannotations.IsPaused(capiCluster, cp) { + return status, errWaitingf("CAPI cluster or RKEControlPlane is paused") + } + + // In the case where the cluster has been bootstrapped and no plans have been + // delivered to any etcd nodes, don't proceed with electing a new init node. + // The only way out of this is to restore an etcd snapshot. + if (capr.Bootstrapped.IsTrue(&status) || len(collect(plan, roleOr(hasJoinURL, hasJoinedTo))) != 0) && len(collect(plan, roleAnd(isEtcd, anyPlanDataExists))) == 0 { + // deliver an etcd snapshot list command to the etcd nodes. + capr.Stable.False(&status) // Set the Stable condition on the controlplane to False. This will be used to hide the v3.Cluster Ready condition from the UI. + return status, errWaiting("rkecontrolplane was already initialized but no etcd machines exist that have plans, indicating the etcd plane has been entirely replaced. Restoration from etcd snapshot is required.") + } + + return p.fullReconcile(cp, status, clusterSecretTokens, plan, false) +} + +func (p *Planner) fullReconcile(cp *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus, clusterSecretTokens plan.Secret, plan *plan.Plan, ignoreDrainAndConcurrency bool) (rkev1.RKEControlPlaneStatus, error) { + // on the first run through, electInitNode will return a `generic.ErrSkip` as it is attempting to wait for the cache to catch up. + joinServer, err := p.electInitNode(cp, plan, true) + if err != nil { + return status, err + } + + var ( + firstIgnoreError error + controlPlaneDrainOptions, workerDrainOptions rkev1.DrainOptions + controlPlaneConcurrency, workerConcurrency string + ) + + if !ignoreDrainAndConcurrency { + controlPlaneDrainOptions = cp.Spec.UpgradeStrategy.ControlPlaneDrainOptions + workerDrainOptions = cp.Spec.UpgradeStrategy.WorkerDrainOptions + controlPlaneConcurrency = cp.Spec.UpgradeStrategy.ControlPlaneConcurrency + workerConcurrency = cp.Spec.UpgradeStrategy.WorkerConcurrency + } + + // select all etcd and then filter to just initNodes so that unavailable count is correct + err = p.reconcile(cp, clusterSecretTokens, plan, true, bootstrapTier, isEtcd, isNotInitNodeOrIsDeleting, + "1", "", + controlPlaneDrainOptions) + capr.Bootstrapped.True(&status) + firstIgnoreError, err = ignoreErrors(firstIgnoreError, err) + if err != nil { + return status, err + } + + if joinServer == "" { + _, joinServer, _, err = p.findInitNode(cp, plan) + if err != nil { + return status, err + } else if joinServer == "" && firstIgnoreError != nil { + return status, errWaiting(firstIgnoreError.Error() + " and join url to be available on bootstrap node") + } else if joinServer == "" { + return status, errWaiting("waiting for join url to be available on bootstrap node") + } + } + + // Process all nodes that have the etcd role and are NOT an init node or deleting. Only process 1 node at a time. + err = p.reconcile(cp, clusterSecretTokens, plan, true, etcdTier, isEtcd, isInitNodeOrDeleting, + "1", joinServer, + controlPlaneDrainOptions) + firstIgnoreError, err = ignoreErrors(firstIgnoreError, err) + if err != nil { + return status, err + } + + // Process all nodes that have the controlplane role and are NOT an init node or deleting. + err = p.reconcile(cp, clusterSecretTokens, plan, true, controlPlaneTier, isControlPlane, isInitNodeOrDeleting, + controlPlaneConcurrency, joinServer, + controlPlaneDrainOptions) + firstIgnoreError, err = ignoreErrors(firstIgnoreError, err) + if err != nil { + return status, err + } + + // If there are any suitable controlplane nodes with join URL annotations + if len(collect(plan, roleAnd(isControlPlane, roleAnd(hasJoinURL, roleNot(isDeleting))))) == 0 { + return status, errWaiting("waiting for control plane to be available") + } + + if status.Initialized != true || status.Ready != true { + status.Initialized = true + status.Ready = true + return status, errWaiting("marking control plane as initialized and ready") + } + + // Process all nodes that are ONLY worker nodes. + err = p.reconcile(cp, clusterSecretTokens, plan, false, workerTier, isOnlyWorker, isInitNodeOrDeleting, + workerConcurrency, "", + workerDrainOptions) + firstIgnoreError, err = ignoreErrors(firstIgnoreError, err) + if err != nil { + return status, err + } + + if firstIgnoreError != nil { + return status, errWaiting(firstIgnoreError.Error()) + } + return status, nil +} + +// getLowestMachineK8sVersion determines the lowest kubelet version in the plan +func getLowestMachineKubeletVersion(plan *plan.Plan) *semver.Version { + var lowestVersion *semver.Version + for _, machine := range plan.Machines { + if machine.Status.NodeInfo != nil { + ver, err := semver.NewVersion(machine.Status.NodeInfo.KubeletVersion) + if err != nil { + logrus.Errorf("error while parsing node kubelet version (%s): %v", machine.Status.NodeInfo.KubeletVersion, err) + continue + } + if lowestVersion == nil { + lowestVersion = ver + } else { + if ver.LessThan(lowestVersion) { + lowestVersion = ver + } + } + } + } + return lowestVersion +} + +// clusterIsSane ensures that there is at least one controlplane, etcd, and worker node that are not deleting for the cluster. +func clusterIsSane(plan *plan.Plan) bool { + if len(collect(plan, roleAnd(isEtcd, roleNot(isDeleting)))) == 0 || len(collect(plan, roleAnd(isControlPlane, roleNot(isDeleting)))) == 0 || len(collect(plan, roleAnd(isWorker, roleNot(isDeleting)))) == 0 { + return false + } + return true +} + +// calculateJoinURL will return a join URL based on calculating the checksum of the given machine UID. This is somewhat deterministic but will change when suitable machine lists change. +func calculateJoinURL(cp *rkev1.RKEControlPlane, entry *planEntry, plan *plan.Plan) string { + if isInitNode(entry) { + return "-" + } + + entries := collect(plan, roleAnd(isControlPlane, roleAnd(hasJoinURL, roleNot(isDeleting)))) + + if len(entries) == 0 { + return "" + } + + ck := crc32.ChecksumIEEE([]byte(entry.Machine.UID)) + if ck == math.MaxUint32 { + ck-- + } + + scaled := int(ck) * len(entries) / math.MaxUint32 + logrus.Debugf("[planner] %s/%s: For machine %s/%s, determined join URL: %s (calculation of index: (%v * %v) / %v = [%v])", cp.Namespace, cp.Name, entry.Machine.Namespace, entry.Machine.Name, entries[scaled].Metadata.Annotations[capr.JoinURLAnnotation], ck, uint32(len(entries)), math.MaxUint32, scaled) + return entries[scaled].Metadata.Annotations[capr.JoinURLAnnotation] +} + +// determineJoinURL determines the join URL for the given entry. It will return different join URLs based on the entry passed in. If the joinURL is specified in the arguments, it will simply return the join URL without validation. +// If the entry is a worker-only node and joinURL is empty, it will validate the existing node the worker is joined to and return if valid. If the existing node is no longer valid, it will calculate a new join URL and return the new join URL. +func determineJoinURL(cp *rkev1.RKEControlPlane, entry *planEntry, plan *plan.Plan, joinURL string) (string, error) { + if cp == nil || entry == nil || plan == nil { + return "", fmt.Errorf("determineJoinURL arguments cannot be nil") + } + if !isOnlyWorker(entry) { + return joinURL, nil + } + if joinURL == "" { + // use the joinServer as specified ONLY if the existing joinServer is not valid for the cluster anymore. This is to prevent plan thrashing when a controlplane host is deleted. + if entry.Plan != nil && entry.Plan.JoinedTo != "" { + if validJoinURL(plan, entry.Plan.JoinedTo) { + joinURL = entry.Plan.JoinedTo + } + } + + if joinURL == "" { + // calculate the next join server for this node + joinURL = calculateJoinURL(cp, entry, plan) + joinedTo := "" + if entry.Plan != nil { + joinedTo = entry.Plan.JoinedTo + } + logrus.Infof("[planner] rkecluster %s/%s - machine %s/%s - previous join server (%s) was not valid, using new join server (%s)", cp.Namespace, cp.Name, entry.Machine.Namespace, entry.Machine.Name, joinedTo, joinURL) + if joinURL == "" { + return "", fmt.Errorf("no suitable join URL found to join machine %s/%s in rkecluster %s/%s to", entry.Machine.Namespace, entry.Machine.Name, cp.Namespace, cp.Name) + } + } + } + return joinURL, nil +} + +// isUnavailable returns a boolean indicating whether the machine/node corresponding to the planEntry is available +// If the plan is not in sync, the machine is being drained, or there are is no new change expected and the probes are failing, it will return true. +func isUnavailable(r *reconcilable) bool { + return !r.entry.Plan.InSync || isInDrain(r.entry) || (!r.change && !r.minorChange && !r.entry.Plan.Healthy) +} + +// isInDrain returns a boolean indicating whether the machine/node corresponding to the planEntry is currently in any +// part of the drain process +func isInDrain(entry *planEntry) bool { + return entry.Metadata.Annotations[capr.PreDrainAnnotation] != "" || + entry.Metadata.Annotations[capr.PostDrainAnnotation] != "" || + entry.Metadata.Annotations[capr.DrainAnnotation] != "" || + entry.Metadata.Annotations[capr.UnCordonAnnotation] != "" +} + +// planAppliedButWaitingForProbes returns a boolean indicating whether a plan was successfully able to be applied, but +// the probes have not been successful. This indicates that while the overall plan hasn't completed yet, it's +// instructions have and can now be overridden if necessary without causing thrashing. +func planAppliedButWaitingForProbes(entry *planEntry) bool { + return entry.Plan.AppliedPlan != nil && reflect.DeepEqual(entry.Plan.Plan, *entry.Plan.AppliedPlan) && !entry.Plan.Healthy +} + +// planAppliedButProbesNeverHealthy returns a boolean indicating whether a plan was successfully able to be applied, but +// the probes have never been successful for the applied plan. This indicates that while the overall plan hasn't completed yet, it's +// instructions have and can now be overridden as there is likely a bad configuration applied. +func planAppliedButProbesNeverHealthy(entry *planEntry) bool { + return entry.Plan.AppliedPlan != nil && reflect.DeepEqual(entry.Plan.Plan, *entry.Plan.AppliedPlan) && !entry.Plan.Healthy && !entry.Plan.ProbesUsable +} + +func calculateConcurrency(maxUnavailable string, reconcilables []*reconcilable, exclude roleFilter) (int, int, error) { + var ( + count, unavailable int + ) + + for _, r := range reconcilables { + if !exclude(r.entry) { + count++ + } + if r.entry.Plan != nil && isUnavailable(r) { + unavailable++ + } + } + + num, err := strconv.Atoi(maxUnavailable) + if err == nil { + return num, unavailable, nil + } + + if maxUnavailable == "" { + return 1, unavailable, nil + } + + percentage, err := strconv.ParseFloat(strings.TrimSuffix(maxUnavailable, "%"), 64) + if err != nil { + return 0, 0, fmt.Errorf("concurrency must be a number or a percentage: %w", err) + } + + max := float64(count) * (percentage / float64(100)) + return int(math.Ceil(max)), unavailable, nil +} + +func minorPlanChangeDetected(old, new plan.NodePlan) bool { + if !equality.Semantic.DeepEqual(old.Instructions, new.Instructions) || + !equality.Semantic.DeepEqual(old.PeriodicInstructions, new.PeriodicInstructions) || + !equality.Semantic.DeepEqual(old.Probes, new.Probes) || + old.Error != new.Error { + return false + } + + if len(old.Files) == 0 && len(new.Files) == 0 { + // if the old plan had no files and no new files were found, there was no plan change detected + return false + } + + newFiles := make(map[string]plan.File) + for _, newFile := range new.Files { + newFiles[newFile.Path] = newFile + } + + for _, oldFile := range old.Files { + if newFile, ok := newFiles[oldFile.Path]; ok { + if oldFile.Content == newFile.Content { + // If the file already exists, we don't care if it is minor + delete(newFiles, oldFile.Path) + } + } else { + // the old file didn't exist in the new file map, + // so check to see if the old file is major and if it is, this is not a minor change. + if !oldFile.Minor { + return false + } + } + } + + if len(newFiles) > 0 { + // If we still have new files in the list, check to see if any of them are major, and if they are, this is not a major change + for _, newFile := range newFiles { + // if we find a new major file, there is not a minor change + if !newFile.Minor { + return false + } + } + // There were new files and all were not major + return true + } + return false +} + +func kubeletVersionUpToDate(controlPlane *rkev1.RKEControlPlane, machine *capi.Machine) bool { + if controlPlane == nil || machine == nil || machine.Status.NodeInfo == nil || !controlPlane.Status.AgentConnected { + // If any of controlPlane, machine, or machine.Status.NodeInfo are nil, then provisioning is still happening. + // If controlPlane.Status.AgentConnected is false, then it cannot be reliably determined if the kubelet is up-to-date. + // Return true so that provisioning is not slowed down. + return true + } + + kubeletVersion, err := semver.NewVersion(strings.TrimPrefix(machine.Status.NodeInfo.KubeletVersion, "v")) + if err != nil { + return false + } + + kubernetesVersion, err := semver.NewVersion(strings.TrimPrefix(controlPlane.Spec.KubernetesVersion, "v")) + if err != nil { + return false + } + + // Compare and ignore pre-release and build metadata + return kubeletVersion.Major() == kubernetesVersion.Major() && kubeletVersion.Minor() == kubernetesVersion.Minor() && kubeletVersion.Patch() == kubernetesVersion.Patch() +} + +// splitArgKeyVal takes a value and returns a pair (key, value) of the argument, or two empty strings if there was not +// a parsed key/val. +func splitArgKeyVal(val string, delim string) (string, string) { + if splitSubArg := strings.SplitN(val, delim, 2); len(splitSubArg) == 2 { + return splitSubArg[0], splitSubArg[1] + } + return "", "" +} + +// getArgValue will search the passed in interface (arg) for a key that matches the searchArg. If a match is found, it +// returns the value of the argument, otherwise it returns an empty string. +func getArgValue(arg interface{}, searchArg string, delim string) string { + logrus.Tracef("getArgValue (searchArg: %s, delim: %s) type of %v is %T", searchArg, delim, arg, arg) + switch arg := arg.(type) { + case []interface{}: + logrus.Tracef("getArgValue (searchArg: %s, delim: %s) encountered interface slice %v", searchArg, delim, arg) + return getArgValue(convertInterfaceSliceToStringSlice(arg), searchArg, delim) + case []string: + logrus.Tracef("getArgValue (searchArg: %s, delim: %s) found string array: %v", searchArg, delim, arg) + for _, v := range arg { + argKey, argVal := splitArgKeyVal(v, delim) + if argKey == searchArg { + return argVal + } + } + case string: + logrus.Tracef("getArgValue (searchArg: %s, delim: %s) found string: %v", searchArg, delim, arg) + argKey, argVal := splitArgKeyVal(arg, delim) + if argKey == searchArg { + return argVal + } + } + logrus.Tracef("getArgValue (searchArg: %s, delim: %s) did not find searchArg in: %v", searchArg, delim, arg) + return "" +} + +// convertInterfaceSliceToStringSlice converts an input interface slice to a string slice by iterating through the +// interface slice and converting each entry to a string using Sprintf. +func convertInterfaceSliceToStringSlice(input []interface{}) []string { + var stringArr []string + for _, v := range input { + stringArr = append(stringArr, fmt.Sprintf("%v", v)) + } + return stringArr +} + +// appendToInterface will return an interface that has the value appended to it. The interface returned will always be +// a slice of strings, and will convert a raw string to a slice of strings. +func appendToInterface(input interface{}, elem string) []string { + switch input := input.(type) { + case []interface{}: + stringArr := convertInterfaceSliceToStringSlice(input) + return appendToInterface(stringArr, elem) + case []string: + return append(input, elem) + case string: + return []string{input, elem} + } + return []string{elem} +} + +// convertInterfaceToStringSlice converts an input interface to a string slice by determining its type and converting +// it accordingly. If it is not a known convertible type, an empty string slice is returned. +func convertInterfaceToStringSlice(input interface{}) []string { + switch input := input.(type) { + case []interface{}: + return convertInterfaceSliceToStringSlice(input) + case []string: + return input + case string: + return []string{input} + } + return []string{} +} + +// renderArgAndMount takes the value of the existing value of the argument and mount and renders an output argument and +// mount based on the value of the input interfaces. It will always return a set of slice of strings. +func renderArgAndMount(existingArg interface{}, existingMount interface{}, controlPlane *rkev1.RKEControlPlane, defaultSecurePort string, defaultCertDir string) ([]string, []string) { + retArg := convertInterfaceToStringSlice(existingArg) + retMount := convertInterfaceToStringSlice(existingMount) + renderedCertDir := path.Join(capr.GetDistroDataDir(controlPlane), defaultCertDir) + // Set a default value for certDirArg and certDirMount (for the case where the user does not set these values) + // If a user sets these values, we will set them to an empty string and check to make sure they are not empty + // strings before adding them to the rendered arg/mount slices. + certDirMount := fmt.Sprintf("%s:%s", renderedCertDir, renderedCertDir) + certDirArg := fmt.Sprintf("%s=%s", CertDirArgument, renderedCertDir) + securePortArg := fmt.Sprintf("%s=%s", SecurePortArgument, defaultSecurePort) + if len(retArg) > 0 { + tlsCF := getArgValue(retArg, TLSCertFileArgument, "=") + if tlsCF == "" { + // If the --tls-cert-file Argument was not set in the config for this component, we can look to see if + // the --cert-dir was set. --tls-cert-file (if set) will take precedence over --tls-cert-file + certDir := getArgValue(retArg, CertDirArgument, "=") + if certDir != "" { + // If --cert-dir was set, we use the --cert-dir that the user provided and should set certDirArg to "" + // so that we don't append it. + certDirArg = "" + // Set certDirMount to an intelligently interpolated value based off of the custom certDir set by the + // user. + certDirMount = fmt.Sprintf("%s:%s", certDir, certDir) + } + } else { + // If the --tls-cert-file argument was set by the user, we don't need to set --cert-dir, but still should + // render a --cert-dir-mount that is based on the --tls-cert-file argument to map the files necessary + // to the static pod (in the RKE2 case) + certDirArg = "" + dir := filepath.Dir(tlsCF) + certDirMount = fmt.Sprintf("%s:%s", dir, dir) + } + sPA := getArgValue(retArg, SecurePortArgument, "=") + if sPA != "" { + // If the user set a custom --secure-port, set --secure-port to an empty string so we don't override + // their custom value + securePortArg = "" + } + } + if certDirArg != "" { + logrus.Debugf("renderArgAndMount adding %s to component arguments", certDirArg) + retArg = appendToInterface(existingArg, certDirArg) + } + if securePortArg != "" { + logrus.Debugf("renderArgAndMount adding %s to component arguments", securePortArg) + retArg = appendToInterface(retArg, securePortArg) + } + if capr.GetRuntime(controlPlane.Spec.KubernetesVersion) == capr.RuntimeRKE2 { + // todo: make sure the certDirMount is not already set by the user to some custom value before we set it for the static pod extraMount + logrus.Debugf("renderArgAndMount adding %s to component mounts", certDirMount) + retMount = appendToInterface(existingMount, certDirMount) + } + return retArg, retMount +} + +func PruneEmpty(config map[string]interface{}) { + for k, v := range config { + if v == nil { + delete(config, k) + } + switch t := v.(type) { + case string: + if t == "" { + delete(config, k) + } + case []interface{}: + if len(t) == 0 { + delete(config, k) + } + case []string: + if len(t) == 0 { + delete(config, k) + } + } + } +} + +// getTaints returns a slice of taints for the machine in question +func getTaints(entry *planEntry, cp *rkev1.RKEControlPlane) (result []corev1.Taint, _ error) { + data := entry.Metadata.Annotations[capr.TaintsAnnotation] + if data != "" { + if err := json.Unmarshal([]byte(data), &result); err != nil { + return result, err + } + } + + if !isWorker(entry) { + // k3s charts do not have correct tolerations when the master node is both controlplane and etcd + if isEtcd(entry) && (capr.GetRuntime(cp.Spec.KubernetesVersion) != capr.RuntimeK3S || !isControlPlane(entry)) { + result = append(result, corev1.Taint{ + Key: "node-role.kubernetes.io/etcd", + Effect: corev1.TaintEffectNoExecute, + }) + } + if isControlPlane(entry) { + result = append(result, corev1.Taint{ + Key: "node-role.kubernetes.io/control-plane", + Effect: corev1.TaintEffectNoSchedule, + }) + } + } + + return +} + +type reconcilable struct { + entry *planEntry + desiredPlan plan.NodePlan + joinedURL string + change bool + minorChange bool +} + +func (p *Planner) reconcile(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, clusterPlan *plan.Plan, required bool, + tierName string, include, exclude roleFilter, maxUnavailable string, forcedJoinURL string, drainOptions rkev1.DrainOptions) error { + var ( + ready, outOfSync, nonReady, errMachines, draining, uncordoned []string + messages = map[string][]string{} + ) + + entries := collect(clusterPlan, include) + + var reconcilables []*reconcilable + + for _, entry := range entries { + if exclude(entry) { + continue + } + + joinURL, err := determineJoinURL(controlPlane, entry, clusterPlan, forcedJoinURL) + if err != nil { + return err + } + + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - rendering desired plan for machine %s/%s with join URL: (%s)", controlPlane.Namespace, controlPlane.Name, tierName, entry.Machine.Namespace, entry.Machine.Name, joinURL) + plan, joinedURL, err := p.desiredPlan(controlPlane, tokensSecret, entry, joinURL) + if err != nil { + return err + } + reconcilables = append(reconcilables, &reconcilable{ + entry: entry, + desiredPlan: plan, + joinedURL: joinedURL, + change: entry.Plan != nil && !equality.Semantic.DeepEqual(entry.Plan.Plan, plan), + minorChange: entry.Plan != nil && minorPlanChangeDetected(entry.Plan.Plan, plan), + }) + } + + concurrency, unavailable, err := calculateConcurrency(maxUnavailable, reconcilables, exclude) + if err != nil { + return err + } + + for _, r := range reconcilables { + logrus.Tracef("[planner] rkecluster %s/%s reconcile tier %s - processing machine entry: %s/%s", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + // we exclude here and not in collect to ensure that include matched at least one node + if exclude(r.entry) { + logrus.Tracef("[planner] rkecluster %s/%s reconcile tier %s - excluding machine entry: %s/%s", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + continue + } + + // The Reconciled condition should be removed when summarizing so that the messages are not duplicated. + summary := summary.Summarize(removeReconciledCondition(r.entry.Machine)) + if summary.Error { + errMachines = append(errMachines, r.entry.Machine.Name) + } + if summary.Transitioning { + nonReady = append(nonReady, r.entry.Machine.Name) + } + + planStatusMessage := getPlanStatusReasonMessage(r.entry) + if planStatusMessage != "" { + summary.Message = append(summary.Message, planStatusMessage) + } + messages[r.entry.Machine.Name] = summary.Message + + if r.entry.Plan == nil { + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - setting initial plan for machine %s/%s", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + logrus.Tracef("[planner] rkecluster %s/%s reconcile tier %s - initial plan for machine %s/%s new: %+v", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name, r.desiredPlan) + outOfSync = append(outOfSync, r.entry.Machine.Name) + if err := p.store.UpdatePlan(r.entry, r.desiredPlan, r.joinedURL, -1, 1); err != nil { + return err + } + } else if r.minorChange { + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - minor plan change detected for machine %s/%s, updating plan immediately", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + logrus.Tracef("[planner] rkecluster %s/%s reconcile tier %s - minor plan change for machine %s/%s old: %+v, new: %+v", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name, r.entry.Plan.Plan, r.desiredPlan) + outOfSync = append(outOfSync, r.entry.Machine.Name) + if err := p.store.UpdatePlan(r.entry, r.desiredPlan, r.joinedURL, -1, 1); err != nil { + return err + } + } else if r.change { + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - plan for machine %s/%s did not match, appending to outOfSync", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + outOfSync = append(outOfSync, r.entry.Machine.Name) + // Conditions + // 1. If the node is already draining then the plan is out of sync. There is no harm in updating it if + // the node is currently drained. + // 2. If the plan has failed to apply. Note that the `Failed` will only be `true` if the max failure count has passed, or (if max-failures is not set) the plan has failed to apply at least once. + // 3. concurrency == 0 which means infinite concurrency. + // 4. unavailable < concurrency meaning we have capacity to make something unavailable + // 5. If the plan was successful in application but the probes never went healthy + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - concurrency: %d, unavailable: %d", controlPlane.Namespace, controlPlane.Name, tierName, concurrency, unavailable) + if isInDrain(r.entry) || r.entry.Plan.Failed || concurrency == 0 || unavailable < concurrency || planAppliedButProbesNeverHealthy(r.entry) { + if !isUnavailable(r) { + unavailable++ + } + if ok, err := p.drain(r.entry.Plan.AppliedPlan, r.desiredPlan, r.entry, clusterPlan, drainOptions); !ok && err != nil { + return err + } else if ok && err == nil { + // Drain is done (or didn't need to be done) and there are no errors, so the plan should be updated to enact the reason the node was drained. + logrus.Debugf("[planner] rkecluster %s/%s reconcile tier %s - major plan change for machine %s/%s", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name) + logrus.Tracef("[planner] rkecluster %s/%s reconcile tier %s - major plan change for machine %s/%s old: %+v, new: %+v", controlPlane.Namespace, controlPlane.Name, tierName, r.entry.Machine.Namespace, r.entry.Machine.Name, r.entry.Plan.Plan, r.desiredPlan) + if err = p.store.UpdatePlan(r.entry, r.desiredPlan, r.joinedURL, -1, 1); err != nil { + return err + } else if r.entry.Metadata.Annotations[capr.DrainDoneAnnotation] != "" { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], "drain completed") + } else if planStatusMessage == "" { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], WaitingPlanStatusMessage) + } + } else { + // In this case, it is true that ((ok == true && err != nil) || (ok == false && err == nil)) + // The first case indicates that there is an error trying to drain the node. + // The second case indicates that the node is draining. + draining = append(draining, r.entry.Machine.Name) + if err != nil { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], err.Error()) + } else { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], "draining node") + } + } + } + } else if planStatusMessage != "" { + outOfSync = append(outOfSync, r.entry.Machine.Name) + } else if ok, err := p.undrain(r.entry); !ok && err != nil { + return err + } else if !ok || err != nil { + // The uncordoning is happening or there was an error. + // Either way, the planner should wait for the result and display the message on the machine. + uncordoned = append(uncordoned, r.entry.Machine.Name) + if err != nil { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], err.Error()) + } else { + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], "waiting for uncordon to finish") + } + } else if !kubeletVersionUpToDate(controlPlane, r.entry.Machine) { + outOfSync = append(outOfSync, r.entry.Machine.Name) + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], "waiting for kubelet to update") + } else if isControlPlane(r.entry) && !controlPlane.Status.AgentConnected { + // If the control plane nodes are currently being provisioned/updated, then it should be ensured that cluster-agent is connected. + // Without the agent connected, the controllers running in Rancher, including CAPI, can't communicate with the downstream cluster. + outOfSync = append(outOfSync, r.entry.Machine.Name) + messages[r.entry.Machine.Name] = append(messages[r.entry.Machine.Name], "waiting for cluster agent to connect") + } else { + ready = append(ready, r.entry.Machine.Name) + } + } + + if required && len(entries) == 0 { + return errWaiting("waiting for at least one " + tierName + " node") + } + + // If multiple machines are changing status, then all of their statuses should be updated to avoid having stale conditions. + // However, only the first one will be returned so that status goes on the control plane and cluster objects. + var firstError error + if err := p.setMachineConditionStatus(clusterPlan, uncordoned, fmt.Sprintf("uncordoning %s node(s) ", tierName), messages); err != nil && firstError == nil { + firstError = err + } + + if err := p.setMachineConditionStatus(clusterPlan, draining, fmt.Sprintf("draining %s node(s) ", tierName), messages); err != nil && firstError == nil { + firstError = err + } + + if err := p.setMachineConditionStatus(clusterPlan, outOfSync, fmt.Sprintf("configuring %s node(s) ", tierName), messages); err != nil && firstError == nil { + firstError = err + } + + // Ensure that the conditions that we control are updated. + if err := p.setMachineConditionStatus(clusterPlan, ready, "", nil); err != nil && firstError == nil { + firstError = err + } + + if firstError != nil { + return firstError + } + + // The messages for these machines come from the machine itself, so nothing needs to be added. + // we want these errors to get reported, but not block the process + if len(errMachines) > 0 { + return errIgnore("failing " + tierName + " machine(s) " + atMostThree(errMachines) + detailedMessage(errMachines, messages)) + } + + if len(nonReady) > 0 { + return errIgnore("non-ready " + tierName + " machine(s) " + atMostThree(nonReady) + detailedMessage(nonReady, messages)) + } + + return nil +} + +// generatePlanWithConfigFiles will generate a node plan with the corresponding config files for the entry in question. +// Notably, it will discard the existing nodePlan in the given entry. It returns the new node plan, the config that was +// rendered, the rendered join server ("-" in the case that the plan is generated for an init node), and an error (if one exists). +func (p *Planner) generatePlanWithConfigFiles(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, entry *planEntry, joinServer string, renderS3 bool) (plan.NodePlan, map[string]interface{}, string, error) { + var ( + reg registries + nodePlan plan.NodePlan + err error + ) + if !controlPlane.Spec.UnmanagedConfig { + nodePlan, reg, err = p.commonNodePlan(controlPlane, plan.NodePlan{}) + if err != nil { + return nodePlan, map[string]interface{}{}, "", err + } + var ( + joinedServer string + config map[string]interface{} + ) + nodePlan, config, joinedServer, err = p.addConfigFile(nodePlan, controlPlane, entry, tokensSecret, joinServer, reg, renderS3) + if err != nil { + return nodePlan, config, joinedServer, err + } + + nodePlan, err = p.addManifests(nodePlan, controlPlane, entry) + if err != nil { + return nodePlan, config, joinedServer, err + } + + nodePlan, err = p.addChartConfigs(nodePlan, controlPlane, entry) + if err != nil { + return nodePlan, config, joinedServer, err + } + + nodePlan, err = addOtherFiles(nodePlan, controlPlane, entry) + + idempotentScriptFile := plan.File{ + Content: base64.StdEncoding.EncodeToString([]byte(idempotentActionScript)), + Path: idempotentActionScriptPath(controlPlane), + Dynamic: true, + Minor: true, + } + + nodePlan.Files = append(nodePlan.Files, idempotentScriptFile) + + return nodePlan, config, joinedServer, err + } + return plan.NodePlan{}, map[string]interface{}{}, "", nil +} + +func (p *Planner) desiredPlan(controlPlane *rkev1.RKEControlPlane, tokensSecret plan.Secret, entry *planEntry, joinServer string) (plan.NodePlan, string, error) { + nodePlan, config, joinedTo, err := p.generatePlanWithConfigFiles(controlPlane, tokensSecret, entry, joinServer, true) + if err != nil { + return nodePlan, joinedTo, err + } + + probes, err := p.generateProbes(controlPlane, entry, config) + if err != nil { + return nodePlan, joinedTo, err + } + nodePlan.Probes = probes + + // Add instruction last because it hashes config content + nodePlan, err = p.addInstallInstructionWithRestartStamp(nodePlan, controlPlane, entry) + if err != nil { + return nodePlan, joinedTo, err + } + + if isInitNode(entry) && IsOnlyEtcd(entry) { + // If the annotation to disable autosetting the join URL is enabled, don't deliver a plan to add the periodic instruction to scrape init node. + if _, autosetDisabled := entry.Metadata.Annotations[capr.JoinURLAutosetDisabled]; !autosetDisabled { + nodePlan, err = p.addInitNodePeriodicInstruction(nodePlan, controlPlane) + if err != nil { + return nodePlan, joinedTo, err + } + } + } + + if isEtcd(entry) { + nodePlan, err = p.addEtcdSnapshotListLocalPeriodicInstruction(nodePlan, controlPlane) + if err != nil { + return nodePlan, joinedTo, err + } + if controlPlane != nil && controlPlane.Spec.ETCD != nil && S3Enabled(controlPlane.Spec.ETCD.S3) && isInitNode(entry) { + nodePlan, err = p.addEtcdSnapshotListS3PeriodicInstruction(nodePlan, controlPlane) + if err != nil { + return nodePlan, joinedTo, err + } + } + } + return nodePlan, joinedTo, nil +} + +// getInstallerImage returns the correct system-agent-installer image for a given controlplane +func (p *Planner) getInstallerImage(controlPlane *rkev1.RKEControlPlane) string { + runtime := capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + installerImage := p.retrievalFunctions.SystemAgentImage() + runtime + ":" + strings.ReplaceAll(controlPlane.Spec.KubernetesVersion, "+", "-") + return p.retrievalFunctions.ImageResolver(installerImage, controlPlane) +} + +// ensureRKEStateSecret ensures that the RKE state secret for the given RKEControlPlane exists. This secret contains the +// serverToken and agentToken used for server/agent registration. +func (p *Planner) ensureRKEStateSecret(controlPlane *rkev1.RKEControlPlane, newCluster bool) (string, plan.Secret, error) { + if controlPlane.Spec.UnmanagedConfig { + return "", plan.Secret{}, nil + } + + name := name.SafeConcatName(controlPlane.Name, "rke", "state") + secret, err := p.secretCache.Get(controlPlane.Namespace, name) + if apierror.IsNotFound(err) { + if !newCluster { + return "", plan.Secret{}, fmt.Errorf("newCluster was false and secret does not exist: %w", err) + } + serverToken, err := randomtoken.Generate() + if err != nil { + return "", plan.Secret{}, err + } + + agentToken, err := randomtoken.Generate() + if err != nil { + return "", plan.Secret{}, err + } + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: controlPlane.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: capr.RKEAPIVersion, + Kind: "RKEControlPlane", + Name: controlPlane.Name, + UID: controlPlane.UID, + }, + }, + }, + Data: map[string][]byte{ + "serverToken": []byte(serverToken), + "agentToken": []byte(agentToken), + }, + Type: capr.SecretTypeClusterState, + } + + _, err = p.secretClient.Create(secret) + return name, plan.Secret{ + ServerToken: serverToken, + AgentToken: agentToken, + }, err + } else if err != nil { + return "", plan.Secret{}, err + } + + if secret.Type != capr.SecretTypeClusterState { + return "", plan.Secret{}, fmt.Errorf("secret %s/%s type %s did not match expected type %s", secret.Namespace, secret.Name, secret.Type, capr.SecretTypeClusterState) + } + + return secret.Name, plan.Secret{ + ServerToken: string(secret.Data["serverToken"]), + AgentToken: string(secret.Data["agentToken"]), + }, nil +} + +// pauseCAPICluster reconciles the given boolean to the owning CAPI cluster. Notably, it retries if there is a conflict +// editing the CAPI cluster as there are many controllers that may be racing to edit the object, but there is only one +// controller that should actively be toggling the paused field on the CAPI cluster object. +func (p *Planner) pauseCAPICluster(cp *rkev1.RKEControlPlane, pause bool) error { + if cp == nil { + return fmt.Errorf("cannot pause CAPI cluster for nil controlplane") + } + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + cluster, err := capr.GetOwnerCAPICluster(cp, p.capiClusters) + if err != nil { + return err + } + if cluster == nil { + return fmt.Errorf("CAPI cluster does not exist for %s/%s", cp.Namespace, cp.Name) + } + cluster = cluster.DeepCopy() + if cluster.Spec.Paused == pause { + return nil + } + cluster.Spec.Paused = pause + _, err = p.capiClient.Update(cluster) + return err + }) +} + +// ensureCAPIClusterControlPlaneInitializedFalse retrieves the CAPI cluster from cache and sets the ControlPlaneInitializedCondition +// to False if it is not already False. +func (p *Planner) ensureCAPIClusterControlPlaneInitializedFalse(cp *rkev1.RKEControlPlane) error { + if cp == nil { + return fmt.Errorf("cannot uninitialize CAPI cluster for nil controlplane") + } + cluster, err := capr.GetOwnerCAPICluster(cp, p.capiClusters) + if err != nil { + return err + } + if cluster == nil { + return fmt.Errorf("CAPI cluster does not exist for %s/%s", cp.Namespace, cp.Name) + } + cluster = cluster.DeepCopy() + if !conditions.IsFalse(cluster, capi.ControlPlaneInitializedCondition) { + conditions.MarkFalse(cluster, capi.ControlPlaneInitializedCondition, capi.WaitingForControlPlaneProviderInitializedReason, capi.ConditionSeverityInfo, "Waiting for control plane provider to indicate the control plane has been initialized") + _, err = p.capiClient.UpdateStatus(cluster) + } + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner_test.go new file mode 100644 index 0000000..f3dcdd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/planner_test.go @@ -0,0 +1,855 @@ +package planner + +import ( + "context" + "fmt" + "math/rand" + "strings" + "testing" + "time" + + "github.com/Masterminds/semver/v3" + "github.com/golang/mock/gomock" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + apisv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type mockPlanner struct { + planner *Planner + rkeBootstrap *fake.MockClientInterface[*rkev1.RKEBootstrap, *rkev1.RKEBootstrapList] + rkeBootstrapCache *fake.MockCacheInterface[*rkev1.RKEBootstrap] + rkeControlPlanes *fake.MockControllerInterface[*rkev1.RKEControlPlane, *rkev1.RKEControlPlaneList] + etcdSnapshotCache *fake.MockCacheInterface[*rkev1.ETCDSnapshot] + secretClient *fake.MockClientInterface[*v1.Secret, *v1.SecretList] + secretCache *fake.MockCacheInterface[*v1.Secret] + configMapCache *fake.MockCacheInterface[*v1.ConfigMap] + machines *fake.MockClientInterface[*capi.Machine, *capi.MachineList] + machinesCache *fake.MockCacheInterface[*capi.Machine] + clusterRegistrationTokenCache *fake.MockCacheInterface[*apisv3.ClusterRegistrationToken] + capiClient *fake.MockClientInterface[*capi.Cluster, *capi.ClusterList] + capiClusters *fake.MockCacheInterface[*capi.Cluster] + managementClusters *fake.MockNonNamespacedCacheInterface[*apisv3.Cluster] + rancherClusterCache *fake.MockCacheInterface[*apisv1.Cluster] +} + +// newMockPlanner creates a new mockPlanner that can be used for simulating a functional Planner. +func newMockPlanner(t *testing.T, functions InfoFunctions) *mockPlanner { + ctrl := gomock.NewController(t) + mp := mockPlanner{ + rkeBootstrap: fake.NewMockClientInterface[*rkev1.RKEBootstrap, *rkev1.RKEBootstrapList](ctrl), + rkeBootstrapCache: fake.NewMockCacheInterface[*rkev1.RKEBootstrap](ctrl), + rkeControlPlanes: fake.NewMockControllerInterface[*rkev1.RKEControlPlane, *rkev1.RKEControlPlaneList](ctrl), + etcdSnapshotCache: fake.NewMockCacheInterface[*rkev1.ETCDSnapshot](ctrl), + secretClient: fake.NewMockClientInterface[*v1.Secret, *v1.SecretList](ctrl), + secretCache: fake.NewMockCacheInterface[*v1.Secret](ctrl), + configMapCache: fake.NewMockCacheInterface[*v1.ConfigMap](ctrl), + machines: fake.NewMockClientInterface[*capi.Machine, *capi.MachineList](ctrl), + machinesCache: fake.NewMockCacheInterface[*capi.Machine](ctrl), + clusterRegistrationTokenCache: fake.NewMockCacheInterface[*apisv3.ClusterRegistrationToken](ctrl), + capiClient: fake.NewMockClientInterface[*capi.Cluster, *capi.ClusterList](ctrl), + capiClusters: fake.NewMockCacheInterface[*capi.Cluster](ctrl), + managementClusters: fake.NewMockNonNamespacedCacheInterface[*apisv3.Cluster](ctrl), + rancherClusterCache: fake.NewMockCacheInterface[*apisv1.Cluster](ctrl), + } + store := PlanStore{ + secrets: mp.secretClient, + secretsCache: mp.secretCache, + machineCache: mp.machinesCache, + } + p := Planner{ + ctx: context.TODO(), + store: &store, + machines: mp.machines, + machinesCache: mp.machinesCache, + secretClient: mp.secretClient, + secretCache: mp.secretCache, + configMapCache: mp.configMapCache, + clusterRegistrationTokenCache: mp.clusterRegistrationTokenCache, + capiClient: mp.capiClient, + capiClusters: mp.capiClusters, + managementClusters: mp.managementClusters, + rancherClusterCache: mp.rancherClusterCache, + rkeControlPlanes: mp.rkeControlPlanes, + rkeBootstrap: mp.rkeBootstrap, + rkeBootstrapCache: mp.rkeBootstrapCache, + etcdSnapshotCache: mp.etcdSnapshotCache, + etcdS3Args: s3Args{ + secretCache: mp.secretCache, + }, + retrievalFunctions: functions, + } + mp.planner = &p + return &mp +} + +func TestPlanner_addInstruction(t *testing.T) { + type args struct { + version string + expectedVersion string + os string + command string + scriptName string + envs []string + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking Linux Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{"INSTALL_RKE2_EXEC"}, + }, + }, + { + name: "Checking Windows Instructions", + args: args{ + version: "v1.21.5+rke2r2", + expectedVersion: "v1.21.5-rke2r2", + os: "windows", + command: "powershell.exe", + scriptName: "run.ps1", + envs: []string{"$env:RESTART_STAMP", "$env:INSTALL_RKE2_EXEC"}, + }, + }, + { + name: "Checking K3s Instructions", + args: args{ + version: "v1.21.5+k3s2", + expectedVersion: "v1.21.5-k3s2", + os: "linux", + command: "sh", + scriptName: "run.sh", + envs: []string{"INSTALL_K3S_EXEC"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + var planner Planner + controlPlane := createTestControlPlane(tt.args.version) + entry := createTestPlanEntry(tt.args.os) + planner.retrievalFunctions.SystemAgentImage = func() string { return "system-agent" } + planner.retrievalFunctions.ImageResolver = image.ResolveWithControlPlane + // act + p, err := planner.addInstallInstructionWithRestartStamp(plan.NodePlan{}, controlPlane, entry) + + // assert + a.Nil(err) + a.NotNil(p) + a.Equal(entry.Metadata.Labels[capr.CattleOSLabel], tt.args.os) + a.NotZero(len(p.Instructions)) + instruction := p.Instructions[0] + a.Contains(instruction.Command, tt.args.command) + a.Contains(instruction.Image, tt.args.expectedVersion) + a.Contains(instruction.Args, tt.args.scriptName) + for _, e := range tt.args.envs { + a.True(findEnv(instruction.Env, e), "couldn't find %s in environment", e) + } + }) + } +} + +func createTestControlPlane(version string) *rkev1.RKEControlPlane { + return &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: version, + }, + } +} + +func createTestPlanEntry(os string) *planEntry { + return &planEntry{ + Machine: &capi.Machine{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + capr.ControlPlaneRoleLabel: "false", + capr.EtcdRoleLabel: "false", + capr.WorkerRoleLabel: "true", + }, + }, + Spec: capi.MachineSpec{}, + Status: capi.MachineStatus{ + NodeInfo: &v1.NodeSystemInfo{ + OperatingSystem: os, + }, + }, + }, + Metadata: &plan.Metadata{ + Labels: map[string]string{ + capr.CattleOSLabel: os, + capr.ControlPlaneRoleLabel: "false", + capr.EtcdRoleLabel: "false", + capr.WorkerRoleLabel: "true", + }, + }, + } +} + +func createTestPlanEntryWithoutRoles(os string) *planEntry { + entry := createTestPlanEntry(os) + entry.Metadata.Labels = map[string]string{ + capr.CattleOSLabel: os, + } + return entry +} + +func findEnv(s []string, v string) bool { + for _, item := range s { + if strings.Contains(item, v) { + return true + } + } + return false +} + +func Test_IsWindows(t *testing.T) { + a := assert.New(t) + data := map[string]bool{ + "windows": true, + "linux": false, + "": false, + } + for k, v := range data { + a.Equal(v, windows(&planEntry{ + Metadata: &plan.Metadata{ + Labels: map[string]string{ + capr.CattleOSLabel: k, + }, + }, + })) + } +} + +func Test_notWindows(t *testing.T) { + type args struct { + entry *planEntry + expected bool + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking that linux isn't windows", + args: args{ + entry: createTestPlanEntry("linux"), + expected: true, + }, + }, + { + name: "Checking that windows is windows", + args: args{ + entry: createTestPlanEntry("windows"), + expected: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + + // act + result := roleNot(windows)(tt.args.entry) + + // assert + a.Equal(result, tt.args.expected) + }) + } +} + +func Test_anyRoleWithoutWindows(t *testing.T) { + type args struct { + entry *planEntry + expected bool + } + + tests := []struct { + name string + args args + }{ + { + name: "Should return linux node with roles", + args: args{ + entry: createTestPlanEntry("linux"), + expected: true, + }, + }, + { + name: "Shouldn't return windows node.", + args: args{ + entry: createTestPlanEntry("windows"), + expected: false, + }, + }, + { + name: "Shouldn't return node without any roles.", + args: args{ + entry: createTestPlanEntryWithoutRoles("linux"), + expected: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + + // act + result := anyRoleWithoutWindows(tt.args.entry) + + // assert + a.Equal(result, tt.args.expected) + }) + } +} + +func TestPlanner_getLowestMachineKubeletVersion(t *testing.T) { + type args struct { + versions []string + expectedLowest string + } + + tests := []struct { + name string + args args + }{ + { + name: "Check lowest RKE2 version within minor release", + args: args{ + versions: []string{ + "v1.25.5+rke2r1", + "v1.25.6+rke2r1", + "v1.25.7+rke2r1", + }, + expectedLowest: "v1.25.5+rke2r1", + }, + }, + { + name: "Check lowest K3s version within minor release", + args: args{ + versions: []string{ + "v1.25.5+k3s1", + "v1.25.6+k3s1", + "v1.25.7+k3s1", + }, + expectedLowest: "v1.25.5+k3s1", + }, + }, + { + name: "Check lowest RKE2 version across any change in release", + args: args{ + versions: []string{ + "v1.25.4+rke2r1", + "v2.21.6+rke2r1", + "v1.26.7+rke2r1", + }, + expectedLowest: "v1.25.4+rke2r1", + }, + }, + { + name: "Check lowest K3s version across any change in release", + args: args{ + versions: []string{ + "v1.25.4+k3s1", + "v2.21.6+k3s1", + "v1.26.7+k3s1", + }, + expectedLowest: "v1.25.4+k3s1", + }, + }, + { + name: "Check lowest version across mixed K3s/RKE2 cluster", + args: args{ + versions: []string{ + "v1.25.4+k3s1", + "v2.21.6+k3s1", + "v1.26.7+k3s1", + "v1.21.5+rke2r1", + }, + expectedLowest: "v1.21.5+rke2r1", + }, + }, + { + name: "Check lowest K3s version with RCs", + args: args{ + versions: []string{ + "v1.21.4+k3s1", + "v1.21.3-rc1+k3s1", + "v1.23.7+k3s1", + }, + expectedLowest: "v1.21.3-rc1+k3s1", + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + a := assert.New(t) + var plan = &plan.Plan{ + Machines: map[string]*capi.Machine{}, + } + rand.Seed(time.Now().UnixNano()) + versions := test.args.versions + // Shuffle the versions to really test the function. + rand.Shuffle(len(versions), func(i, j int) { versions[i], versions[j] = versions[j], versions[i] }) + for i, v := range versions { + plan.Machines[fmt.Sprintf("machine%d", i)] = &capi.Machine{ + Status: capi.MachineStatus{ + NodeInfo: &v1.NodeSystemInfo{ + KubeletVersion: v, + }, + }, + } + } + lowestV := getLowestMachineKubeletVersion(plan) + if len(test.args.versions) > 0 { + a.NotNil(lowestV) + expectedLowest, err := semver.NewVersion(test.args.expectedLowest) + if a.NoError(err) { + a.Equal(lowestV.String(), expectedLowest.String()) + } + } else { + a.Nil(lowestV) + } + }) + } +} + +func Test_getInstallerImage(t *testing.T) { + tests := []struct { + name string + expected string + controlPlane *rkev1.RKEControlPlane + }{ + { + name: "default", + expected: "rancher/system-agent-installer-rke2:v1.25.7-rke2r1", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.25.7+rke2r1", + }, + }, + }, + { + name: "cluster private registry - machine global", + expected: "test.rancher.io/rancher/system-agent-installer-rke2:v1.25.7-rke2r1", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "system-default-registry": "test.rancher.io", + }, + }, + }, + KubernetesVersion: "v1.25.7+rke2r1", + }, + }, + }, + { + name: "cluster private registry - machine selector", + expected: "test.rancher.io/rancher/system-agent-installer-rke2:v1.25.7-rke2r1", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineSelectorConfig: []rkev1.RKESystemConfig{ + { + Config: rkev1.GenericMap{ + Data: map[string]any{ + "system-default-registry": "test.rancher.io", + }, + }, + }, + }, + }, + KubernetesVersion: "v1.25.7+rke2r1", + }, + }, + }, + { + name: "cluster private registry - prefer machine global", + expected: "test.rancher.io/rancher/system-agent-installer-rke2:v1.25.7-rke2r1", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "system-default-registry": "test.rancher.io", + }, + }, + MachineSelectorConfig: []rkev1.RKESystemConfig{ + { + Config: rkev1.GenericMap{ + Data: map[string]any{ + "system-default-registry": "test2.rancher.io", + }, + }, + }, + }, + }, + KubernetesVersion: "v1.25.7+rke2r1", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var planner Planner + planner.retrievalFunctions.ImageResolver = image.ResolveWithControlPlane + planner.retrievalFunctions.SystemAgentImage = func() string { return "rancher/system-agent-installer-" } + + assert.Equal(t, tt.expected, planner.getInstallerImage(tt.controlPlane)) + }) + } +} + +func Test_renderArgAndMount(t *testing.T) { + tests := []struct { + name string + inputArg interface{} + inputMount interface{} + inputSecurePort string + inputCertDir string + controlPlane *rkev1.RKEControlPlane + expectedArgs []string + expectedMount []string + }{ + { + name: "test default K3s KCM rendering", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/k3s", DefaultKubeControllerManagerCertDir), SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s KCM cert-dir", + inputArg: "cert-dir=/tmp", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"cert-dir=/tmp", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s KCM tls-cert-file", + inputArg: "tls-cert-file=/mycustomfile.crt", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"tls-cert-file=/mycustomfile.crt", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s KCM cert-dir with surrounding bogus data in input args", + inputArg: []string{"bogus", "cert-dir=/tmp", "data:"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"bogus", "cert-dir=/tmp", "data:", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s KCM tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test default RKE2 KCM rendering", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir), SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir)}, + }, + { + name: "test custom RKE2 KCM cert-dir", + inputArg: "cert-dir=/tmp", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"cert-dir=/tmp", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{"/tmp:/tmp"}, + }, + { + name: "test custom RKE2 KCM tls-cert-file", + inputArg: "tls-cert-file=/somedir/mycustomfile.crt", + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"tls-cert-file=/somedir/mycustomfile.crt", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{"/somedir:/somedir"}, + }, + { + name: "test custom RKE2 KCM cert-dir with surrounding bogus data in input args", + inputArg: []string{"bogus", "cert-dir=/tmp", "data:"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"bogus", "cert-dir=/tmp", "data:", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{"/tmp:/tmp"}, + }, + { + name: "test custom RKE2 KCM tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data", SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{"/:/"}, // this is notably going to break things but it's still a good demonstration of expected value. If we ever add a validation for this in the future we need to change this test. + }, + { + name: "test custom RKE2 KCM empty tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"tls-cert-file=", "data"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"tls-cert-file=", "data", CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir), SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir)}, + }, + { + name: "test custom RKE2 KCM empty cert-dir with surrounding bogus data in input args", + inputArg: []string{"cert-dir=", "data"}, + inputSecurePort: DefaultKubeControllerManagerDefaultSecurePort, + inputCertDir: DefaultKubeControllerManagerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"cert-dir=", "data", CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir), SecurePortArgument + "=" + DefaultKubeControllerManagerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeControllerManagerCertDir)}, + }, + { + name: "test default K3s kube-scheduler rendering", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/k3s", DefaultKubeSchedulerCertDir), SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s kube-scheduler cert-dir", + inputArg: "cert-dir=/tmp", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"cert-dir=/tmp", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s kube-scheduler tls-cert-file", + inputArg: "tls-cert-file=/mycustomfile.crt", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"tls-cert-file=/mycustomfile.crt", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s kube-scheduler cert-dir with surrounding bogus data in input args", + inputArg: []string{"bogus", "cert-dir=/tmp", "data:"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"bogus", "cert-dir=/tmp", "data:", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test custom K3s kube-scheduler tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+k3s1", + }, + }, + expectedArgs: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{}, + }, + { + name: "test default RKE2 kube-scheduler rendering", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir), SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir)}, + }, + { + name: "test custom RKE2 kube-scheduler cert-dir", + inputArg: "cert-dir=/tmp", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"cert-dir=/tmp", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{"/tmp:/tmp"}, + }, + { + name: "test custom RKE2 kube-scheduler tls-cert-file", + inputArg: "tls-cert-file=/somedir/mycustomfile.crt", + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"tls-cert-file=/somedir/mycustomfile.crt", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{"/somedir:/somedir"}, + }, + { + name: "test custom RKE2 kube-scheduler cert-dir with surrounding bogus data in input args", + inputArg: []string{"bogus", "cert-dir=/tmp", "data:"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"bogus", "cert-dir=/tmp", "data:", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{"/tmp:/tmp"}, + }, + { + name: "test custom RKE2 kube-scheduler tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"bogus=", "tls-cert-file=/mycustomfile.crt", "data", SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{"/:/"}, // this is notably going to break things but it's still a good demonstration of expected value. If we ever add a validation for this in the future we need to change this test. + }, + { + name: "test custom RKE2 kube-scheduler empty tls-cert-file with surrounding bogus data in input args", + inputArg: []string{"tls-cert-file=", "data"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"tls-cert-file=", "data", CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir), SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir)}, + }, + { + name: "test custom RKE2 kube-scheduler empty cert-dir with surrounding bogus data in input args", + inputArg: []string{"cert-dir=", "data"}, + inputSecurePort: DefaultKubeSchedulerDefaultSecurePort, + inputCertDir: DefaultKubeSchedulerCertDir, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expectedArgs: []string{"cert-dir=", "data", CertDirArgument + "=" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir), SecurePortArgument + "=" + DefaultKubeSchedulerDefaultSecurePort}, + expectedMount: []string{fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir) + ":" + fmt.Sprintf("%s/%s", "/var/lib/rancher/rke2", DefaultKubeSchedulerCertDir)}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + args, mounts := renderArgAndMount(tt.inputArg, tt.inputMount, tt.controlPlane, tt.inputSecurePort, tt.inputCertDir) + assert.Equal(t, tt.expectedArgs, args, tt.name) + assert.Equal(t, tt.expectedMount, mounts, tt.name) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe.go new file mode 100644 index 0000000..ad47aa3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe.go @@ -0,0 +1,214 @@ +package planner + +import ( + "fmt" + "path" + "strings" + + "github.com/pkg/errors" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/wrangler/v3/pkg/data/convert" +) + +var ( + allProbes = map[string]plan.Probe{ + "calico": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "http://%s:9099/liveness", + }, + }, + "etcd": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "http://%s:2381/health", + }, + }, + "kube-apiserver": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:6443/readyz", + CACert: "%s/server/tls/server-ca.crt", + ClientCert: "%s/server/tls/client-kube-apiserver.crt", + ClientKey: "%s/server/tls/client-kube-apiserver.key", + }, + }, + "kube-scheduler": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:%s/healthz", + }, + }, + "kube-controller-manager": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:%s/healthz", + }, + }, + "kubelet": { + InitialDelaySeconds: 1, + TimeoutSeconds: 5, + SuccessThreshold: 1, + FailureThreshold: 2, + HTTPGetAction: plan.HTTPGetAction{ + URL: "http://%s:10248/healthz", + }, + }, + } + errEmptyCACert = errors.New("cacert cannot be empty") + errEmptyPort = errors.New("port cannot be empty") + errEmptyAddress = errors.New("address cannot be empty") +) + +// isCalico returns true if the cni is calico or calico+multus, and returns false otherwise. +func isCalico(controlPlane *rkev1.RKEControlPlane, runtime string) bool { + // calico is only supported for rke2 + if runtime != capr.RuntimeRKE2 { + return false + } + + cni := convert.ToString(controlPlane.Spec.MachineGlobalConfig.Data["cni"]) + return cni == "" || + cni == "calico" || + cni == "calico+multus" +} + +// renderSecureProbe takes the existing argument value and renders a secure probe using the argument values and an error +// if one occurred. +func renderSecureProbe(arg any, rawProbe plan.Probe, controlPlane *rkev1.RKEControlPlane, loopbackAddress, defaultSecurePort string, defaultCertDir string, defaultCert string) (plan.Probe, error) { + securePort := getArgValue(arg, SecurePortArgument, "=") + if securePort == "" { + // If the user set a custom --secure-port, set --secure-port to an empty string, so we don't override + // their custom value + securePort = defaultSecurePort + } + TLSCert := getArgValue(arg, TLSCertFileArgument, "=") + if TLSCert == "" { + // If the --tls-cert-file Argument was not set in the config for this component, we can look to see if + // the --cert-dir was set. --tls-cert-file (if set) will take precedence over --cert-dir + certDir := getArgValue(arg, CertDirArgument, "=") + if certDir == "" { + // If --cert-dir was not set, we use defaultCertDir value that was passed in, but must prefix the data-dir + certDir = path.Join(capr.GetDistroDataDir(controlPlane), defaultCertDir) + } + // Our goal here is to generate the tlsCert. If we get to this point, we know we will be using the defaultCert + TLSCert = certDir + "/" + defaultCert + } + return replaceCACertAndPortForProbes(rawProbe, TLSCert, loopbackAddress, securePort) +} + +// generateProbes generates probes for the machine (based on type of machine) to the nodePlan and returns the probes and +// an error if one occurred. +func (p *Planner) generateProbes(controlPlane *rkev1.RKEControlPlane, entry *planEntry, config map[string]any) (map[string]plan.Probe, error) { + var ( + runtime = capr.GetRuntime(controlPlane.Spec.KubernetesVersion) + probeNames []string + probes = map[string]plan.Probe{} + ) + + if runtime != capr.RuntimeK3S && isEtcd(entry) { + probeNames = append(probeNames, "etcd") + } + if isControlPlane(entry) { + probeNames = append(probeNames, "kube-apiserver") + probeNames = append(probeNames, "kube-controller-manager") + probeNames = append(probeNames, "kube-scheduler") + } + if !(IsOnlyEtcd(entry) && runtime == capr.RuntimeK3S) { + // k3s doesn't run the kubelet on etcd only nodes + probeNames = append(probeNames, "kubelet") + } + if !IsOnlyEtcd(entry) && isCalico(controlPlane, runtime) && roleNot(windows)(entry) { + probeNames = append(probeNames, "calico") + } + + for _, probeName := range probeNames { + probes[probeName] = allProbes[probeName] + } + + probes = insertDataDirForProbes(controlPlane, probes) + + loopbackAddress := capr.GetLoopbackAddress(controlPlane) + + if isControlPlane(entry) { + kcmProbe, err := renderSecureProbe(config[KubeControllerManagerArg], probes["kube-controller-manager"], controlPlane, loopbackAddress, DefaultKubeControllerManagerDefaultSecurePort, DefaultKubeControllerManagerCertDir, DefaultKubeControllerManagerCert) + if err != nil { + return probes, err + } + probes["kube-controller-manager"] = kcmProbe + + ksProbe, err := renderSecureProbe(config[KubeSchedulerArg], probes["kube-scheduler"], controlPlane, loopbackAddress, DefaultKubeSchedulerDefaultSecurePort, DefaultKubeSchedulerCertDir, DefaultKubeSchedulerCert) + if err != nil { + return probes, err + } + probes["kube-scheduler"] = ksProbe + } + + probes = replaceURLForProbes(probes, loopbackAddress) + + return probes, nil +} + +// replaceCACertAndPortForProbes adds/replaces the CACert and URL with rendered values based on the values provided. +func replaceCACertAndPortForProbes(probe plan.Probe, cacert, host, port string) (plan.Probe, error) { + if cacert == "" { + return plan.Probe{}, errEmptyCACert + } + if port == "" { + return plan.Probe{}, errEmptyPort + } + if host == "" { + return plan.Probe{}, errEmptyAddress + } + probe.HTTPGetAction.CACert = cacert + probe.HTTPGetAction.URL = fmt.Sprintf(probe.HTTPGetAction.URL, host, port) + return probe, nil +} + +// insertDataDirForProbes will insert the data-dir for all probes based on the controlplane object. +func insertDataDirForProbes(controlPlane *rkev1.RKEControlPlane, probes map[string]plan.Probe) map[string]plan.Probe { + result := make(map[string]plan.Probe, len(probes)) + dataDir := capr.GetDistroDataDir(controlPlane) + for k, v := range probes { + v.HTTPGetAction.CACert = replaceIfFormatSpecifier(v.HTTPGetAction.CACert, dataDir) + v.HTTPGetAction.ClientCert = replaceIfFormatSpecifier(v.HTTPGetAction.ClientCert, dataDir) + v.HTTPGetAction.ClientKey = replaceIfFormatSpecifier(v.HTTPGetAction.ClientKey, dataDir) + result[k] = v + } + return result +} + +// replaceURLForProbes will insert the loopback host for all probes based on stack preference. +func replaceURLForProbes(probes map[string]plan.Probe, loopbackAddress string) map[string]plan.Probe { + result := make(map[string]plan.Probe, len(probes)) + for k, v := range probes { + v.HTTPGetAction.URL = replaceIfFormatSpecifier(v.HTTPGetAction.URL, loopbackAddress) + result[k] = v + } + return result +} + +// replaceIfFormatSpecifier will insert the runtime of the k8s engine if the string str has a string format specifier. +func replaceIfFormatSpecifier(str string, runtime string) string { + if !strings.Contains(str, "%s") { + return str + } + return fmt.Sprintf(str, runtime) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe_test.go new file mode 100644 index 0000000..a84120f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/probe_test.go @@ -0,0 +1,403 @@ +package planner + +import ( + "testing" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + "github.com/stretchr/testify/assert" +) + +func TestIsCalico(t *testing.T) { + tests := []struct { + name string + controlPlane *rkev1.RKEControlPlane + runtime string + expected bool + }{ + { + name: "calico rke2", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "cni": "calico", + }, + }, + }, + }, + }, + runtime: capr.RuntimeRKE2, + expected: true, + }, + { + name: "calico+multus rke2", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "cni": "calico+multus", + }, + }, + }, + }, + }, + runtime: capr.RuntimeRKE2, + expected: true, + }, + { + name: "mispelled calico rke2", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "cni": "calicoo", + }, + }, + }, + }, + }, + runtime: capr.RuntimeRKE2, + expected: false, + }, + { + name: "calico k3s", + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + MachineGlobalConfig: rkev1.GenericMap{ + Data: map[string]any{ + "cni": "calico", + }, + }, + }, + }, + }, + runtime: capr.RuntimeK3S, + expected: false, + }, + { + name: "no cni rke2", + controlPlane: &rkev1.RKEControlPlane{}, + runtime: capr.RuntimeRKE2, + expected: true, + }, + { + name: "no cni k3s", + controlPlane: &rkev1.RKEControlPlane{}, + runtime: capr.RuntimeRKE2, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, isCalico(tt.controlPlane, tt.runtime)) + }) + } +} + +func TestReplaceCACertAndPortForProbes(t *testing.T) { + tests := []struct { + name string + probe plan.Probe + cacert string + address string + port string + expected plan.Probe + expectedErr error + }{ + { + name: "empty cacert", + probe: plan.Probe{}, + cacert: "", + address: "", + port: "", + expected: plan.Probe{}, + expectedErr: errEmptyCACert, + }, + { + name: "empty port", + probe: plan.Probe{}, + cacert: "test", + address: "rancher.com", + port: "", + expected: plan.Probe{}, + expectedErr: errEmptyPort, + }, + { + name: "empty address", + probe: plan.Probe{}, + cacert: "test", + address: "", + port: "1234", + expected: plan.Probe{}, + expectedErr: errEmptyAddress, + }, + { + name: "URL with specifier", + probe: plan.Probe{ + HTTPGetAction: plan.HTTPGetAction{ + CACert: "test", + URL: "https://%s:%s", + }, + }, + cacert: "test", + address: "rancher.com", + port: "1234", + expected: plan.Probe{ + HTTPGetAction: plan.HTTPGetAction{ + CACert: "test", + URL: "https://rancher.com:1234", + }, + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if probe, err := replaceCACertAndPortForProbes(tt.probe, tt.cacert, tt.address, tt.port); err != nil { + assert.ErrorIs(t, err, tt.expectedErr) + } else { + assert.Equal(t, tt.expected, probe) + } + }) + } +} + +func TestRenderProbes(t *testing.T) { + tests := []struct { + name string + input map[string]plan.Probe + controlPlane *rkev1.RKEControlPlane + expected map[string]plan.Probe + }{ + { + name: "nil", + input: nil, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expected: map[string]plan.Probe{}, + }, + { + name: "no probes", + input: map[string]plan.Probe{}, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expected: map[string]plan.Probe{}, + }, + { + name: "simple probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + CACert: "cacert", + ClientCert: "clientcert", + ClientKey: "clientkey", + }, + }, + }, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.8+rke2r1", + }, + }, + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + CACert: "cacert", + ClientCert: "clientcert", + ClientKey: "clientkey", + }, + }, + }, + }, + { + name: "replace probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + CACert: "%s/cacert", + ClientCert: "%s/clientcert", + ClientKey: "%s/clientkey", + }, + }, + }, + controlPlane: &rkev1.RKEControlPlane{ + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: "v1.28.0+rke2r1", + }, + }, + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + CACert: "/var/lib/rancher/rke2/cacert", + ClientCert: "/var/lib/rancher/rke2/clientcert", + ClientKey: "/var/lib/rancher/rke2/clientkey", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, insertDataDirForProbes(tt.controlPlane, tt.input)) + }) + } +} + +func TestReplaceURLForProbes(t *testing.T) { + tests := []struct { + name string + input map[string]plan.Probe + loopbackAddress string + expected map[string]plan.Probe + }{ + { + name: "nil", + input: nil, + loopbackAddress: "", + expected: map[string]plan.Probe{}, + }, + { + name: "no probes", + input: map[string]plan.Probe{}, + loopbackAddress: "", + expected: map[string]plan.Probe{}, + }, + { + name: "simple probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://127.0.0.1:1234/test", + }, + }, + }, + loopbackAddress: "", + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://127.0.0.1:1234/test", + }, + }, + }, + }, + { + name: "replace ipv4 probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:1234/test", + }, + }, + }, + loopbackAddress: "127.0.0.1", + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://127.0.0.1:1234/test", + }, + }, + }, + }, + { + name: "replace ipv6 probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:1234/test", + }, + }, + }, + loopbackAddress: "[::1]", + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://[::1]:1234/test", + }, + }, + }, + }, + { + name: "replace dual probe", + input: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://%s:1234/test", + }, + }, + }, + loopbackAddress: "localhost", + expected: map[string]plan.Probe{ + "a": { + HTTPGetAction: plan.HTTPGetAction{ + URL: "https://localhost:1234/test", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, replaceURLForProbes(tt.input, tt.loopbackAddress)) + }) + } +} + +func TestReplaceIfFormatSpecifier(t *testing.T) { + tests := []struct { + name string + input string + runtime string + expected string + }{ + { + name: "empty string", + input: "", + runtime: "", + expected: "", + }, + { + name: "empty string with runtime", + input: "", + runtime: capr.RuntimeRKE2, + expected: "", + }, + { + name: "no format specifier", + input: "test", + runtime: capr.RuntimeRKE2, + expected: "test", + }, + { + name: "format specifier rke2", + input: "test/%s", + runtime: capr.RuntimeRKE2, + expected: "test/rke2", + }, + { + name: "format specifier k3s", + input: "test/%s", + runtime: capr.RuntimeK3S, + expected: "test/k3s", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, replaceIfFormatSpecifier(tt.input, tt.runtime)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/registry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/registry.go new file mode 100644 index 0000000..e73fe04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/registry.go @@ -0,0 +1,125 @@ +package planner + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "sort" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + corev1 "k8s.io/api/core/v1" +) + +// renderRegistries accepts an RKEControlPlane and generates the data needed to set up registries. +func (p *Planner) renderRegistries(controlPlane *rkev1.RKEControlPlane) (registries, error) { + var ( + files []plan.File + configs = map[string]interface{}{} + data registries + err error + ) + + for registryName, config := range controlPlane.Spec.Registries.Configs { + registryConfig := ®istryConfig{} + if config.InsecureSkipVerify || config.TLSSecretName != "" || len(config.CABundle) > 0 { + registryConfig.TLS = &tlsConfig{ + InsecureSkipVerify: config.InsecureSkipVerify, + } + } + + if config.TLSSecretName != "" { + secret, err := p.secretCache.Get(controlPlane.Namespace, config.TLSSecretName) + if err != nil { + return data, err + } + if secret.Type != corev1.SecretTypeTLS { + return data, fmt.Errorf("secret [%s] must be of type [%s]", config.TLSSecretName, corev1.SecretTypeTLS) + } + + if cert := secret.Data[corev1.TLSCertKey]; len(cert) != 0 { + file := toFile(controlPlane, fmt.Sprintf("tls/registries/%s/tls.crt", registryName), cert) + registryConfig.TLS.CertFile = file.Path + files = append(files, file) + } + + if key := secret.Data[corev1.TLSPrivateKeyKey]; len(key) != 0 { + file := toFile(controlPlane, fmt.Sprintf("tls/registries/%s/tls.key", registryName), key) + registryConfig.TLS.KeyFile = file.Path + files = append(files, file) + } + } + + if len(config.CABundle) > 0 { + file := toFile(controlPlane, fmt.Sprintf("tls/registries/%s/ca.crt", registryName), config.CABundle) + registryConfig.TLS.CAFile = file.Path + files = append(files, file) + } + + if config.AuthConfigSecretName != "" { + secret, err := p.secretCache.Get(controlPlane.Namespace, config.AuthConfigSecretName) + if err != nil { + return data, err + } + if secret.Type != rkev1.AuthConfigSecretType && secret.Type != corev1.SecretTypeBasicAuth { + return data, fmt.Errorf("secret [%s] must be of type [%s] or [%s]", + config.AuthConfigSecretName, rkev1.AuthConfigSecretType, corev1.SecretTypeBasicAuth) + } + registryConfig.Auth = &authConfig{ + Username: string(secret.Data[rkev1.UsernameAuthConfigSecretKey]), + Password: string(secret.Data[rkev1.PasswordAuthConfigSecretKey]), + Auth: string(secret.Data[rkev1.AuthAuthConfigSecretKey]), + IdentityToken: string(secret.Data[rkev1.IdentityTokenAuthConfigSecretKey]), + } + } + + configs[registryName] = registryConfig + } + + data.registriesFileRaw, err = json.Marshal(map[string]interface{}{ + "mirrors": controlPlane.Spec.Registries.Mirrors, + "configs": configs, + }) + if err != nil { + return data, err + } + + // Sort the returned files slice because map iteration is not deterministic. This can lead to unexpected behavior where registry files are out of order. + sort.Slice(files, func(i, j int) bool { return files[i].Path < files[j].Path }) + data.certificateFiles = files + return data, nil +} + +// toFile accepts an RKEControlPlane, path, and a byte slice containing data to be written to a file on host. It returns +// a plan.File. +func toFile(controlPlane *rkev1.RKEControlPlane, path string, content []byte) plan.File { + return plan.File{ + Content: base64.StdEncoding.EncodeToString(content), + Path: fmt.Sprintf("%s/etc/%s", capr.GetDistroDataDir(controlPlane), path), + } +} + +type registries struct { + registriesFileRaw []byte + certificateFiles []plan.File +} + +type registryConfig struct { + Auth *authConfig `json:"auth"` + TLS *tlsConfig `json:"tls"` +} + +type tlsConfig struct { + CAFile string `json:"ca_file"` + CertFile string `json:"cert_file"` + KeyFile string `json:"key_file"` + InsecureSkipVerify bool `json:"insecure_skip_verify"` +} + +type authConfig struct { + Username string `json:"username"` + Password string `json:"password"` + Auth string `json:"auth"` + IdentityToken string `json:"identity_token"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/s3args.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/s3args.go new file mode 100644 index 0000000..7a1af04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/s3args.go @@ -0,0 +1,187 @@ +package planner + +import ( + "encoding/base64" + "fmt" + "strings" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/controllers/capr/machineprovision" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kv" + "github.com/rancher/wrangler/v3/pkg/name" +) + +// s3Args is a struct that contains functions used to generate arguments for etcd snapshots stored in S3 +type s3Args struct { + secretCache corecontrollers.SecretCache +} + +// first returns the first non-blank string from the two passed in arguments (left to right) +func first(one, two string) string { + if one == "" { + return two + } + return one +} + +// S3Enabled returns a boolean indicating whether S3 is enabled for the passed in ETCDSnapshotS3 struct. +func S3Enabled(s3 *rkev1.ETCDSnapshotS3) bool { + if s3 == nil { + return false + } + if s3.Bucket != "" || s3.Endpoint != "" || s3.Folder != "" || s3.CloudCredentialName != "" || s3.Region != "" { + return true + } + return false +} + +// ToArgs renders a slice of arguments and environment variables, as well as files (if S3 endpoints are required). If secretKeyInEnv is set to true, it will set the AWS_SECRET_ACCESS_KEY as an environment variable rather than as an argument. +func (s *s3Args) ToArgs(s3 *rkev1.ETCDSnapshotS3, controlPlane *rkev1.RKEControlPlane, prefix string, secretKeyInEnv bool) (args []string, env []string, files []plan.File, err error) { + if s3 == nil { + return + } + + if !S3Enabled(s3) { + return + } + + var ( + s3Cred s3Credential + ) + + controlPlaneEtcdS3NotNil := controlPlane.Spec.ETCD != nil && controlPlane.Spec.ETCD.S3 != nil + + credName := s3.CloudCredentialName + if credName == "" && controlPlaneEtcdS3NotNil { + credName = controlPlane.Spec.ETCD.S3.CloudCredentialName + } + + s3Cred, err = getS3Credential(s.secretCache, controlPlane.Namespace, credName) + if err != nil { + return + } + + if s3.Bucket != "" || s3Cred.Bucket != "" { + args = append(args, fmt.Sprintf("--%ss3-bucket=%s", prefix, first(s3.Bucket, s3Cred.Bucket))) + } + + if s3Cred.AccessKey != "" { + args = append(args, fmt.Sprintf("--%ss3-access-key=%s", prefix, s3Cred.AccessKey)) + } + if s3Cred.SecretKey != "" { + if secretKeyInEnv { + env = append(env, fmt.Sprintf("AWS_SECRET_ACCESS_KEY=%s", s3Cred.SecretKey)) + } else { + args = append(args, fmt.Sprintf("--%ss3-secret-key=%s", prefix, s3Cred.SecretKey)) + } + } + if v := first(s3.Region, s3Cred.Region); v != "" { + args = append(args, fmt.Sprintf("--%ss3-region=%s", prefix, v)) + } + if v := first(s3.Folder, s3Cred.Folder); v != "" { + args = append(args, fmt.Sprintf("--%ss3-folder=%s", prefix, v)) + } + if v := first(s3.Endpoint, s3Cred.Endpoint); v != "" { + args = append(args, fmt.Sprintf("--%ss3-endpoint=%s", prefix, v)) + } + if s3.SkipSSLVerify || s3Cred.SkipSSLVerify { + args = append(args, fmt.Sprintf("--%ss3-skip-ssl-verify", prefix)) + } + if v := first(s3.EndpointCA, s3Cred.EndpointCA); v != "" { + // An etcd s3 snapshot object may have its endpoint CA be the filepath that was used to create the snapshot. + // If this is the case, search the corresponding cloud credential and controlplane S3 spec for the actual CA data, + // and use if it exists. + // TODO: find a better way to bubble an error to the user that a restore is failing due to a missing endpoint CA file. + if v == s3.EndpointCA && strings.HasSuffix(v, ".crt") { + args = append(args, fmt.Sprintf("--%ss3-endpoint-ca=%s", prefix, v)) + if s3Cred.EndpointCA != "" { + possibleCA := generateEndpointCAFileIfPathMatches(controlPlane, v, s3Cred.EndpointCA) + if possibleCA != nil { + files = append(files, *possibleCA) + } + } else if controlPlaneEtcdS3NotNil && controlPlane.Spec.ETCD.S3.EndpointCA != "" { + possibleCA := generateEndpointCAFileIfPathMatches(controlPlane, v, controlPlane.Spec.ETCD.S3.EndpointCA) + if possibleCA != nil { + files = append(files, *possibleCA) + } + } + } else { + if _, err := base64.StdEncoding.DecodeString(v); err != nil { + // There was an error decoding the endpointCA, indicating that it needs to be encoded. + v = base64.StdEncoding.EncodeToString([]byte(v)) + } + s3CAName := fmt.Sprintf("s3-endpoint-ca-%s.crt", name.Hex(v, 5)) + filePath := configFile(controlPlane, s3CAName) + files = append(files, plan.File{ + Content: v, + Path: filePath, + }) + args = append(args, fmt.Sprintf("--%ss3-endpoint-ca=%s", prefix, filePath)) + } + } + + if len(args) > 0 { + args = append(args, + fmt.Sprintf("--%ss3", prefix)) + } + + return +} + +func generateEndpointCAFileIfPathMatches(controlPlane *rkev1.RKEControlPlane, existingEndpointCAPath, endpointCA string) *plan.File { + s3CAName := fmt.Sprintf("s3-endpoint-ca-%s.crt", name.Hex(endpointCA, 5)) + filePath := configFile(controlPlane, s3CAName) + if existingEndpointCAPath == filePath { + // If the filepath of the s3cred endpointCA matches the endpoint CA that was used for the snapshot, go ahead and include the file for posterity + if _, err := base64.StdEncoding.DecodeString(endpointCA); err != nil { + // There was an error decoding the endpointCA, indicating that it needs to be encoded. + endpointCA = base64.StdEncoding.EncodeToString([]byte(endpointCA)) + } + return &plan.File{ + Content: endpointCA, + Path: filePath, + } + } + return nil +} + +type s3Credential struct { + AccessKey string + SecretKey string + Region string + Endpoint string + EndpointCA string + SkipSSLVerify bool + Bucket string + Folder string +} + +func getS3Credential(secretCache corecontrollers.SecretCache, namespace, name string) (result s3Credential, _ error) { + if name == "" { + return result, nil + } + + secret, err := machineprovision.GetCloudCredentialSecret(secretCache, namespace, name) + if err != nil { + return result, fmt.Errorf("failed to lookup etcdSnapshotCloudCredentialName: %w", err) + } + + data := map[string][]byte{} + for k, v := range secret.Data { + _, k = kv.RSplit(k, "-") + data[k] = v + } + + return s3Credential{ + AccessKey: string(data["accessKey"]), + SecretKey: string(data["secretKey"]), + Region: string(data["defaultRegion"]), + Endpoint: string(data["defaultEndpoint"]), + EndpointCA: string(data["defaultEndpointCA"]), + SkipSSLVerify: string(data["defaultSkipSSLVerify"]) == "true", + Bucket: string(data["defaultBucket"]), + Folder: string(data["defaultFolder"]), + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store.go new file mode 100644 index 0000000..2c371df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store.go @@ -0,0 +1,636 @@ +package planner + +import ( + "bufio" + "bytes" + "compress/gzip" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "net" + "net/url" + "sort" + "strconv" + "strings" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1/plan" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + NoAgentPlanStatusMessage = "waiting for agent to check in and apply initial plan" + WaitingPlanStatusMessage = "waiting for plan to be applied" + FailedPlanStatusMessage = "failure while applying plan" +) + +type PlanStore struct { + secrets corecontrollers.SecretClient + secretsCache corecontrollers.SecretCache + machineCache capicontrollers.MachineCache +} + +func NewStore(secrets corecontrollers.SecretController, machineCache capicontrollers.MachineCache) *PlanStore { + return &PlanStore{ + secrets: secrets, + secretsCache: secrets.Cache(), + machineCache: machineCache, + } +} + +// onlyRKE returns a subset of the passed in slice of CAPI machines that only contains machines that have an RKEBootstrap +func onlyRKE(machines []*capi.Machine) (result []*capi.Machine) { + for _, m := range machines { + if !isRKEBootstrap(m) { + continue + } + result = append(result, m) + } + return +} + +// Load takes a clusters.cluster.x-k8s.io object and the corresponding rkecontrolplanes.rke.cattle.io object and +// generates a new plan.Plan, a bool that indicates whether any plan has been delivered to any of the machines, +// and an error +func (p *PlanStore) Load(cluster *capi.Cluster, rkeControlPlane *rkev1.RKEControlPlane) (*plan.Plan, bool, error) { + result := &plan.Plan{ + Nodes: map[string]*plan.Node{}, + Machines: map[string]*capi.Machine{}, + Metadata: map[string]*plan.Metadata{}, + } + + var anyPlanDelivered bool + + machines, err := p.machineCache.List(cluster.Namespace, labels.SelectorFromSet(map[string]string{ + capi.ClusterNameLabel: cluster.Name, + })) + if err != nil { + return nil, anyPlanDelivered, err + } + + machines = onlyRKE(machines) + + secrets, err := p.getPlanSecrets(machines) + if err != nil { + return nil, anyPlanDelivered, err + } + + // Place a DeepCopy of the machine in the resulting Plan, making mutative operations on the Machine object safe. + for _, machine := range machines { + result.Machines[machine.Name] = machine.DeepCopy() + } + + for machineName, secret := range secrets { + if secret.Labels == nil { + secret.Labels = map[string]string{} + } + if secret.Annotations == nil { + secret.Annotations = map[string]string{} + } + result.Metadata[machineName] = &plan.Metadata{ + Labels: secret.Labels, + Annotations: secret.Annotations, + } + node, err := SecretToNode(secret) + if err != nil { + return nil, anyPlanDelivered, err + } + if node == nil { + continue + } + if node.PlanDataExists { + anyPlanDelivered = true + } + if err := p.setMachineJoinURL(&planEntry{Machine: result.Machines[machineName], Metadata: result.Metadata[machineName], Plan: node}, cluster, rkeControlPlane); err != nil { + return nil, anyPlanDelivered, err + } + result.Nodes[machineName] = node + } + + return result, anyPlanDelivered, nil +} + +func noPlanMessage(entry *planEntry) string { + if isEtcd(entry) { + return "waiting for bootstrap etcd to be available" + } + if isControlPlane(entry) { + return "waiting for etcd to be available" + } + return "waiting for control plane to be available" +} + +func probesMessage(plan *plan.Node) string { + var ( + unhealthy []string + ) + for name, probe := range plan.ProbeStatus { + if !probe.Healthy { + unhealthy = append(unhealthy, name) + } + } + sort.Strings(unhealthy) + return "waiting for probes: " + strings.Join(unhealthy, ", ") +} + +func getPlanStatusReasonMessage(entry *planEntry) string { + switch { + case entry.Plan == nil: + return noPlanMessage(entry) + case len(entry.Plan.Plan.Instructions) == 0: + return noPlanMessage(entry) + case entry.Plan.AppliedPlan == nil: + return NoAgentPlanStatusMessage + case entry.Plan.Plan.Error != "": + return entry.Plan.Plan.Error + case !entry.Plan.Healthy: + return probesMessage(entry.Plan) + case entry.Plan.InSync: + return "" + case entry.Plan.Failed: + return FailedPlanStatusMessage + default: + return WaitingPlanStatusMessage + } +} + +// SecretToNode consumes a secret of type rke.cattle.io/machine-plan and returns a node object and an error if one exists +func SecretToNode(secret *corev1.Secret) (*plan.Node, error) { + if secret == nil { + return nil, fmt.Errorf("unable to convert secret to node plan, secret was nil") + } + if secret.Type != capr.SecretTypeMachinePlan { + return nil, fmt.Errorf("secret %s/%s was not type %s", secret.Namespace, secret.Name, capr.SecretTypeMachinePlan) + } + result := &plan.Node{ + Healthy: true, + } + + planData := secret.Data["plan"] + result.PlanDataExists = len(secret.Data["plan"]) != 0 + appliedPlanData := secret.Data["appliedPlan"] + failedChecksum := string(secret.Data["failed-checksum"]) + output := secret.Data["applied-output"] + appliedPeriodicOutput := secret.Data["applied-periodic-output"] + probes := secret.Data["probe-statuses"] + failureCount := secret.Data["failure-count"] + + if probesPassed, ok := secret.Annotations[capr.PlanProbesPassedAnnotation]; ok && probesPassed != "" { + result.ProbesUsable = true + } + + if len(failureCount) > 0 && PlanHash(planData) == failedChecksum { + failureCount, err := strconv.Atoi(string(failureCount)) + if err != nil { + return nil, err + } + if failureCount > 0 { + result.Failed = true + // failure-threshold is set by Rancher when the plan is updated. If it is not set, then it essentially + // defaults to 1, and any failure causes the plan to be marked as failed + rawFailureThreshold := secret.Data["failure-threshold"] + if len(rawFailureThreshold) > 0 { + failureThreshold, err := strconv.Atoi(string(rawFailureThreshold)) + if err != nil { + return nil, err + } + if failureCount < failureThreshold || failureThreshold == -1 { + // the plan hasn't actually failed to be applied because we haven't passed the failure threshold or failure threshold is set to -1. + result.Failed = false + } + } + } + } + + if len(probes) > 0 { + probeStatuses, healthy, err := ParseProbeStatuses(probes) + if err != nil { + return nil, err + } + result.ProbeStatus = *probeStatuses + result.Healthy = healthy + } + + if len(planData) > 0 { + if err := json.Unmarshal(planData, &result.Plan); err != nil { + return nil, err + } + } else { + return nil, nil + } + + if len(appliedPlanData) > 0 { + newPlan := &plan.NodePlan{} + if err := json.Unmarshal(appliedPlanData, newPlan); err != nil { + return nil, err + } + result.AppliedPlan = newPlan + } + + if joinedTo, ok := secret.Annotations[capr.JoinedToAnnotation]; ok { + result.JoinedTo = joinedTo + } else { + if configFirstHalf, configSecondHalf, found := strings.Cut(ConfigYamlFileName, "%s"); found { + for _, v := range result.Plan.Files { + if strings.Contains(v.Path, configFirstHalf) && strings.Contains(v.Path, configSecondHalf) { + // We found our config file, process it to look for the joined node and then break + cfr, err := base64.StdEncoding.DecodeString(v.Content) + if err != nil { + return nil, err + } + var cf = map[string]interface{}{} + if err := json.Unmarshal(cfr, &cf); err != nil { + return nil, err + } + if server, ok := cf["server"]; ok { + result.JoinedTo = server.(string) + } + break + } + } + } + } + + if len(output) > 0 { + gz, err := gzip.NewReader(bytes.NewBuffer(output)) + if err != nil { + return nil, err + } + output, err = io.ReadAll(gz) + if err != nil { + return nil, err + } + result.Output = map[string][]byte{} + if err := json.Unmarshal(output, &result.Output); err != nil { + return nil, err + } + } + + if len(appliedPeriodicOutput) > 0 { + gz, err := gzip.NewReader(bytes.NewBuffer(appliedPeriodicOutput)) + if err != nil { + return nil, err + } + output, err = io.ReadAll(gz) + if err != nil { + return nil, err + } + result.PeriodicOutput = map[string]plan.PeriodicInstructionOutput{} + if err := json.Unmarshal(output, &result.PeriodicOutput); err != nil { + return nil, err + } + } + + result.InSync = bytes.Equal(planData, appliedPlanData) + return result, nil +} + +func ParseProbeStatuses(probeStatuses []byte) (*map[string]plan.ProbeStatus, bool, error) { + healthy := true + if len(probeStatuses) == 0 { + return nil, false, fmt.Errorf("probe status length was 0") + } + probeStatusMap := map[string]plan.ProbeStatus{} + if err := json.Unmarshal(probeStatuses, &probeStatusMap); err != nil { + return nil, false, err + } + for _, status := range probeStatusMap { + if !status.Healthy { + healthy = false + } + } + return &probeStatusMap, healthy, nil +} + +func PlanHash(plan []byte) string { + result := sha256.Sum256(plan) + return hex.EncodeToString(result[:]) +} + +// getPlanSecrets retrieves the plan secrets for the given list of machines +func (p *PlanStore) getPlanSecrets(machines []*capi.Machine) (map[string]*corev1.Secret, error) { + result := map[string]*corev1.Secret{} + for _, machine := range machines { + secret, err := p.getPlanSecretFromMachine(machine) + if apierror.IsNotFound(err) { + continue + } else if err != nil { + return nil, err + } + if secret != nil { + result[machine.Name] = secret.DeepCopy() + } + } + + return result, nil +} + +func isRKEBootstrap(machine *capi.Machine) bool { + return machine.Spec.Bootstrap.ConfigRef != nil && + machine.Spec.Bootstrap.ConfigRef.Kind == "RKEBootstrap" +} + +// getPlanSecretFromMachine returns the plan secret from the secrets client for the given machine, +// or an error if the plan secret is not available. Notably we do not use the secretsCache to ensure we only operate +// on the latest version of a machine plan secret. +func (p *PlanStore) getPlanSecretFromMachine(machine *capi.Machine) (*corev1.Secret, error) { + if machine == nil { + return nil, fmt.Errorf("machine was nil") + } + + if !isRKEBootstrap(machine) { + return nil, fmt.Errorf("machine %s/%s is not using RKEBootstrap", machine.Namespace, machine.Name) + } + + if machine.Spec.Bootstrap.ConfigRef == nil { + return nil, fmt.Errorf("machine %s/%s bootstrap configref was nil", machine.Namespace, machine.Name) + } + + if machine.Spec.Bootstrap.ConfigRef.Name == "" { + return nil, fmt.Errorf("machine %s/%s bootstrap configref name was empty", machine.Namespace, machine.Name) + } + + secret, err := p.secrets.Get(machine.Namespace, capr.PlanSecretFromBootstrapName(machine.Spec.Bootstrap.ConfigRef.Name), metav1.GetOptions{}) + if err != nil { + return nil, err + } + + if secret.Type != capr.SecretTypeMachinePlan { + return nil, fmt.Errorf("retrieved secret %s/%s type %s did not match expected type %s", secret.Namespace, secret.Name, secret.Type, capr.SecretTypeMachinePlan) + } + + return secret, nil +} + +// UpdatePlan should not be called directly as it will not block further progress if the plan is not in sync +// maxFailures is the number of attempts the system-agent will make to run the plan (in a failed state). failureThreshold is used to determine when the plan has failed. +func (p *PlanStore) UpdatePlan(entry *planEntry, newNodePlan plan.NodePlan, joinedTo string, maxFailures, failureThreshold int) error { + if maxFailures < failureThreshold && failureThreshold != -1 && maxFailures != -1 { + return fmt.Errorf("failureThreshold (%d) cannot be greater than maxFailures (%d)", failureThreshold, maxFailures) + } + secret, err := p.getPlanSecretFromMachine(entry.Machine) + if err != nil { + return err + } + + data, err := json.Marshal(newNodePlan) + if err != nil { + return err + } + + secret = secret.DeepCopy() + if secret.Data == nil { + // Create the map with enough storage for what is needed. + secret.Data = make(map[string][]byte, 6) + } + + // If joinedTo is specified, set the joined-to annotation. If -, then clear the joined-to annotation + if joinedTo != "" { + if joinedTo == "-" || entry.Metadata.Annotations[capr.InitNodeLabel] == "true" { + // clear the joinedTo annotation. + entry.Metadata.Annotations[capr.JoinedToAnnotation] = "" + } else { + entry.Metadata.Annotations[capr.JoinedToAnnotation] = joinedTo + } + } + + // an init node cannot have a joined-to annotation value as it is essentially joined to itself. + if entry.Metadata.Annotations[capr.InitNodeLabel] == "true" { + entry.Metadata.Annotations[capr.JoinedToAnnotation] = "" + } + + entry.Metadata.Annotations[capr.PlanUpdatedTimeAnnotation] = time.Now().UTC().Format(time.RFC3339) + entry.Metadata.Annotations[capr.PlanProbesPassedAnnotation] = "" + + capr.CopyPlanMetadataToSecret(secret, entry.Metadata) + + // If the plan is being updated, then delete the probe-statuses so their healthy status will be reported as healthy only when they pass. + delete(secret.Data, "probe-statuses") + + secret.Data["plan"] = data + if maxFailures > 0 || maxFailures == -1 { + secret.Data["max-failures"] = []byte(strconv.Itoa(maxFailures)) + } else { + delete(secret.Data, "max-failures") + } + + if failureThreshold > 0 || failureThreshold == -1 { + secret.Data["failure-threshold"] = []byte(strconv.Itoa(failureThreshold)) + } else { + delete(secret.Data, "failure-threshold") + } + + updatedSecret, err := p.secrets.Update(secret) + if err != nil { + return err + } + + // Update the node immediately so that future plan processing occurs + newNode, err := SecretToNode(updatedSecret) + if err != nil { + return err + } + + entry.Plan = newNode + return nil +} + +func (p *PlanStore) updatePlanSecretLabelsAndAnnotations(entry *planEntry) error { + secret, err := p.getPlanSecretFromMachine(entry.Machine) + if err != nil { + return err + } + + secret = secret.DeepCopy() + capr.CopyPlanMetadataToSecret(secret, entry.Metadata) + updatedSecret, err := p.secrets.Update(secret) + if err != nil { + return err + } + newNode, err := SecretToNode(updatedSecret) + if err != nil { + return err + } + entry.Plan = newNode + return nil +} + +// removePlanSecretLabel removes a label with the given key from the plan secret that corresponds to the RKEBootstrap +func (p *PlanStore) removePlanSecretLabel(entry *planEntry, key string) error { + secret, err := p.getPlanSecretFromMachine(entry.Machine) + if err != nil { + return err + } + + if _, ok := secret.Labels[key]; !ok { + return nil + } + + secret = secret.DeepCopy() + delete(secret.Labels, key) + updatedSecret, err := p.secrets.Update(secret) + if err != nil { + return err + } + newNode, err := SecretToNode(updatedSecret) + if err != nil { + return err + } + entry.Plan = newNode + entry.Metadata.Labels = secret.Labels + return nil +} + +// assignAndCheckPlan assigns the given newPlan to the designated server in the planEntry, and will return nil if the plan is assigned and in sync. +func assignAndCheckPlan(store *PlanStore, msg string, entry *planEntry, newPlan plan.NodePlan, joinedTo string, failureThreshold, maxRetries int) error { + if entry.Plan == nil || !equality.Semantic.DeepEqual(entry.Plan.Plan, newPlan) { + if err := store.UpdatePlan(entry, newPlan, joinedTo, failureThreshold, maxRetries); err != nil { + return err + } + return errWaiting(fmt.Sprintf("starting %s", msg)) + } + if entry.Plan.Failed { + return fmt.Errorf("operation %s failed", msg) + } + if !entry.Plan.InSync { + return errWaiting(fmt.Sprintf("waiting for %s", msg)) + } + if !entry.Plan.Healthy { + return errWaiting(fmt.Sprintf("waiting for %s probes", msg)) + } + return nil +} + +func (p *PlanStore) setMachineJoinURL(entry *planEntry, capiCluster *capi.Cluster, controlPlane *rkev1.RKEControlPlane) error { + var ( + err error + joinURL string + ) + + // If the annotation to disable autosetting the join URL is enabled, don't process the join URL. + if _, autosetDisabled := entry.Metadata.Annotations[capr.JoinURLAutosetDisabled]; autosetDisabled { + return nil + } + + if IsEtcdOnlyInitNode(entry) { + joinURL, err = getJoinURLFromOutput(entry, capiCluster, controlPlane) + if err != nil || joinURL == "" { + return err + } + } else { + if entry.Machine.Status.NodeInfo == nil { + return nil + } + + address := "" + for _, machineAddress := range entry.Machine.Status.Addresses { + switch machineAddress.Type { + case capi.MachineInternalIP: + address = machineAddress.Address + case capi.MachineExternalIP: + if address == "" { + address = machineAddress.Address + } + } + } + + joinURL = joinURLFromAddress(address, capr.GetRuntimeSupervisorPort(controlPlane.Spec.KubernetesVersion)) + } + + if joinURL != "" && entry.Metadata.Annotations[capr.JoinURLAnnotation] != joinURL { + entry.Metadata.Annotations[capr.JoinURLAnnotation] = joinURL + if err := p.updatePlanSecretLabelsAndAnnotations(entry); err != nil { + return err + } + + return generic.ErrSkip + } + + return nil +} + +func joinURLFromAddress(address string, port int) string { + // ipv6 addresses need to be enclosed in brackets in URLs, and hostnames will fail to be parsed as IPs + if net.ParseIP(address) != nil && strings.Count(address, ":") >= 2 { + if !strings.HasPrefix(address, "[") && !strings.HasSuffix(address, "]") { + address = fmt.Sprintf("[%s]", address) + } + } + return fmt.Sprintf("https://%s:%d", address, port) +} + +func getJoinURLFromOutput(entry *planEntry, capiCluster *capi.Cluster, rkeControlPlane *rkev1.RKEControlPlane) (string, error) { + if entry.Plan == nil || !IsEtcdOnlyInitNode(entry) || capiCluster.Spec.ControlPlaneRef == nil || rkeControlPlane == nil { + return "", nil + } + + var address []byte + var name string + ca := entry.Plan.PeriodicOutput[captureAddressInstructionName] + if ca.ExitCode != 0 || ca.LastSuccessfulRunTime == "" { + return "", nil + } + etcdNameOutput := entry.Plan.PeriodicOutput[etcdNameInstructionName] + if etcdNameOutput.ExitCode != 0 || etcdNameOutput.LastSuccessfulRunTime == "" { + return "", nil + } + address = ca.Stdout + name = string(bytes.TrimSpace(etcdNameOutput.Stdout)) + + var str string + scanner := bufio.NewScanner(bytes.NewBuffer(address)) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "{") { + str = line + break + } + } + + if str == "" { + return "", nil + } + + dbInfo := &dbinfo{} + if err := json.Unmarshal([]byte(str), dbInfo); err != nil { + return "", err + } + + for _, member := range dbInfo.Members { + if member.Name != name { + continue + } + + u, err := url.Parse(member.ClientURLs[0]) + if err != nil { + return "", err + } + + joinURL := joinURLFromAddress(u.Hostname(), capr.GetRuntimeSupervisorPort(rkeControlPlane.Spec.KubernetesVersion)) + return joinURL, nil + } + + // No need to error here because once the plan secret is updated, then this will be retried. + return "", nil +} + +type dbinfo struct { + Members []member `json:"members,omitempty"` +} +type member struct { + Name string `json:"name,omitempty"` + ClientURLs []string `json:"clientURLs,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store_test.go new file mode 100644 index 0000000..1c47d54 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/capr/planner/store_test.go @@ -0,0 +1,41 @@ +package planner + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestJoinURLFromAddress(t *testing.T) { + tests := []struct { + name string + address string + port int + expected string + }{ + { + name: "ipv4", + address: "127.0.0.1", + port: 9345, + expected: "https://127.0.0.1:9345", + }, + { + name: "ipv6", + address: "::ffff:7f00:1", + port: 9345, + expected: "https://[::ffff:7f00:1]:9345", + }, + { + name: "hostname", + address: "testing.rancher.io", + port: 9345, + expected: "https://testing.rancher.io:9345", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, joinURLFromAddress(tt.address, tt.port)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_common.go new file mode 100644 index 0000000..5397eb0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_common.go @@ -0,0 +1,233 @@ +package manager + +import ( + "errors" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func hasAllUpdates(catalog *v3.Catalog) bool { + upgraded := v32.CatalogConditionUpgraded.IsTrue(catalog) + diskCached := v32.CatalogConditionDiskCached.IsTrue(catalog) + return upgraded && diskCached +} + +func isUpToDate(commit string, catalog *v3.Catalog) bool { + commitsEqual := commit == catalog.Status.Commit + updated := hasAllUpdates(catalog) + return commitsEqual && updated +} + +func setRefreshed(catalog *v3.Catalog) bool { + logrus.Debugf("Catalog %s is already up to date", catalog.Name) + if !v32.CatalogConditionRefreshed.IsTrue(catalog) { + v32.CatalogConditionRefreshed.True(catalog) + v32.CatalogConditionRefreshed.Reason(catalog, "") + v32.CatalogConditionRefreshed.Message(catalog, "") + return true + } + return false +} + +func setRefreshedError(catalog *v3.Catalog, err error) { + v32.CatalogConditionRefreshed.False(catalog) + v32.CatalogConditionRefreshed.ReasonAndMessageFromError(catalog, err) +} + +func (m *Manager) deleteTemplates(key string, namespace string) error { + templates, err := m.getTemplateMap(key, namespace) + if err != nil { + return err + } + tvToDelete := map[string]struct{}{} + for _, t := range templates { + tvs, err := m.getTemplateVersion(t.Name, namespace) + if err != nil { + //if template version doesn't exist continue to delete template + if strings.Contains(err.Error(), "invalid label value") { + continue + } + return err + } + for k := range tvs { + tvToDelete[k] = struct{}{} + } + } + go func() { + for { + for k := range templates { + if err := m.templateClient.DeleteNamespaced(namespace, k, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) { + logrus.Warnf("Deleting template %v doesn't succeed. Continue loop", k) + continue + } + } + for k := range tvToDelete { + if err := m.templateVersionClient.DeleteNamespaced(namespace, k, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) { + logrus.Warnf("Deleting templateVersion %v doesn't succeed. Continue loop", k) + continue + } + } + break + } + }() + return nil +} + +func getCatalogType(cmt *CatalogInfo) string { + if cmt.projectCatalog == nil && cmt.clusterCatalog == nil { + return client.CatalogType + } + if cmt.projectCatalog != nil { + return client.ProjectCatalogType + } + return client.ClusterCatalogType +} + +func (m *Manager) updateCatalogInfo(cmt *CatalogInfo, catalogType string, templateName string, condition bool, updateOnly bool) (*CatalogInfo, error) { + var obj runtime.Object + if condition { + switch catalogType { + case client.CatalogType: + obj = runtime.Object(cmt.catalog) + case client.ProjectCatalogType: + obj = runtime.Object(cmt.projectCatalog) + case client.ClusterCatalogType: + obj = runtime.Object(cmt.clusterCatalog) + default: + return cmt, fmt.Errorf("incorrect catalog type") + } + v32.CatalogConditionRefreshed.Unknown(obj) + if templateName != "" { + v32.CatalogConditionRefreshed.Message(obj, fmt.Sprintf("syncing catalog %v", cmt.catalog.Name)) + } else { + v32.CatalogConditionRefreshed.Message(obj, fmt.Sprintf("")) + } + } + + if updateOnly { + switch catalogType { + case client.CatalogType: + if _, err := m.catalogClient.Update(cmt.catalog); err != nil { + return nil, err + } + case client.ProjectCatalogType: + if _, err := m.projectCatalogClient.Update(cmt.projectCatalog); err != nil { + return nil, err + } + case client.ClusterCatalogType: + if _, err := m.clusterCatalogClient.Update(cmt.clusterCatalog); err != nil { + return nil, err + } + default: + return cmt, fmt.Errorf("incorrect catalog type") + } + return cmt, nil + } + + switch catalogType { + case client.CatalogType: + catalog := cmt.catalog + if newCatalog, err := m.catalogClient.Update(cmt.catalog); err == nil { + catalog = newCatalog + } else { + catalog, _ = m.catalogClient.Get(catalog.Name, metav1.GetOptions{}) + } + cmt.catalog = catalog + case client.ProjectCatalogType: + projectCatalog := cmt.projectCatalog + if newCatalog, err := m.projectCatalogClient.Update(projectCatalog); err == nil { + projectCatalog = newCatalog + } else { + projectCatalog, _ = m.projectCatalogClient.Get(projectCatalog.Name, metav1.GetOptions{}) + } + cmt.catalog = &projectCatalog.Catalog + cmt.projectCatalog = projectCatalog + case client.ClusterCatalogType: + clusterCatalog := cmt.clusterCatalog + if newCatalog, err := m.clusterCatalogClient.Update(clusterCatalog); err == nil { + clusterCatalog = newCatalog + } else { + clusterCatalog, _ = m.clusterCatalogClient.Get(clusterCatalog.Name, metav1.GetOptions{}) + } + cmt.catalog = &clusterCatalog.Catalog + cmt.clusterCatalog = clusterCatalog + default: + return cmt, fmt.Errorf("incorrect catalog type") + } + + return cmt, nil +} + +func setCatalogErrorState(cmt *CatalogInfo, catalog *v3.Catalog, projectCatalog *v3.ProjectCatalog, clusterCatalog *v3.ClusterCatalog) { + v32.CatalogConditionRefreshed.False(catalog) + v32.CatalogConditionRefreshed.Message(catalog, fmt.Sprintf("Error syncing catalog %v", catalog.Name)) + v32.CatalogConditionProcessed.True(catalog) + cmt.catalog = catalog + cmt.projectCatalog = projectCatalog + cmt.clusterCatalog = clusterCatalog +} + +func setCatalogIgnoreErrorState(commit string, cmt *CatalogInfo, catalog *v3.Catalog, projectCatalog *v3.ProjectCatalog, clusterCatalog *v3.ClusterCatalog, message string) { + v32.CatalogConditionProcessed.False(catalog) + v32.CatalogConditionProcessed.Message(catalog, message) + v32.CatalogConditionRefreshed.Message(catalog, "") + v32.CatalogConditionProcessed.ReasonAndMessageFromError(catalog, errors.New(message)) + v32.CatalogConditionRefreshed.True(catalog) + catalog.Status.Commit = commit + if projectCatalog != nil { + projectCatalog.Catalog = *catalog + } else if clusterCatalog != nil { + clusterCatalog.Catalog = *catalog + } + cmt.catalog = catalog + cmt.projectCatalog = projectCatalog + cmt.clusterCatalog = clusterCatalog +} + +func setTraverseCompleted(catalog *v3.Catalog) { + v32.CatalogConditionUpgraded.True(catalog) + v32.CatalogConditionDiskCached.True(catalog) + v32.CatalogConditionProcessed.True(catalog) + v32.CatalogConditionProcessed.Message(catalog, "") + v32.CatalogConditionProcessed.Reason(catalog, "") +} + +// getChartName returns the chart name with a given catalogTemplate name and a given catalog name. +// It does not check for correctness, but an empty string will be returned the catalogName input is invalid. +func getChartName(catalogName, templateName string) string { + temp := strings.Split(templateName, catalogName) + if len(temp) < 2 || catalogName == "" { + return "" + } + return strings.TrimPrefix(temp[1], "-") +} + +// Using Helm standards to make a qualified name to be used for template name, see link below +// General Helm Chart conventions should be followed as we will not correct all potential issues +// https://github.com/helm/helm/blob/9b42702a4bced339ff424a78ad68dd6be6e1a80a/cmd/helm/testdata/testcharts/chart-with-template-lib-dep/charts/common/templates/_fullname.tpl +func getValidTemplateName(catalogName, chartName string) string { + templateName := fmt.Sprintf("%s-%s", catalogName, chartName) + templateName = strings.ToLower(templateName) + templateName = strings.TrimSuffix(templateName, "-") + return templateName +} + +// Using Helm standards to make a label to be used for the template version name, see link below +// General Helm Chart conventions should be followed as we will not correct all potential issues +// https://github.com/helm/helm/blob/3582b03a91bb994aa4d33a7bc50de5205f734c7a/pkg/chartutil/create.go +func getValidTemplateNameWithVersion(templateName, version string) string { + label := fmt.Sprintf("%s-%s", templateName, version) + label = strings.ReplaceAll(label, "+", "-") + label = strings.TrimSuffix(label, "-") + label = strings.ToLower(label) + return label +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_preprocess.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_preprocess.go new file mode 100644 index 0000000..d1cd0c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_preprocess.go @@ -0,0 +1,92 @@ +package manager + +import ( + "fmt" + "net/url" + "strings" + + "k8s.io/apimachinery/pkg/util/validation" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/helm" +) + +const invalidURLErrMsg string = "a valid url must consist of an http, https, or git scheme" + +type ChartsWithErrors struct { + Template *helm.ChartVersion + error InvalidChartError +} + +type InvalidChartError struct { + Err string + TemplateName string +} + +func (e *InvalidChartError) Error() string { + return fmt.Sprintf("failed %v %s", e.TemplateName, e.Err) +} + +// Go through each catalog entry and check for errors in values used for template name and labels +// due to restrictions for kubernetes objects. Do not create templates with errored charts. +func (m *Manager) preprocessCatalog(catalog *v3.Catalog, catalogEntries map[string]helm.ChartVersions) ([]ChartsWithErrors, map[string]helm.ChartVersions) { + var invalidEntries []ChartsWithErrors + for chart, metadata := range catalogEntries { + for _, version := range metadata { + var versionErrors []string + // get a chart name that matches helm general conventions + templateName := getValidTemplateName(catalog.Name, chart) + // check that template name could be used as a kubernetes sub domain + errorString := validation.IsDNS1123Subdomain(templateName) + if len(errorString) > 0 { + versionErrors = append(versionErrors, fmt.Sprintf("template name %s: [%s]", templateName, strings.Join(errorString, ";"))) + } + // check that template name can be used as a label + errorString = validation.IsValidLabelValue(templateName) + if len(errorString) > 0 { + versionErrors = append(versionErrors, fmt.Sprintf("template name %s: [%s]", templateName, strings.Join(errorString, ";"))) + } + templateVersionName := getValidTemplateNameWithVersion(templateName, version.Version) + // validate template version name can be used as a kubernetes sub domain + errorString = validation.IsDNS1123Subdomain(templateVersionName) + if len(errorString) > 0 { + versionErrors = append(versionErrors, fmt.Sprintf("template version name %s: [%s]", templateVersionName, strings.Join(errorString, ";"))) + } + if version.URLs != nil { + for _, url := range version.URLs { + // check to see if url is http, https or git scheme + if isInvalidVersionURL(url) { + versionErrors = append(versionErrors, fmt.Sprintf("url %s is invalid. %s", url, invalidURLErrMsg)) + } + } + } + // a chart can have multiple version, so errors are collected per version + // this allows valid chart versions to be processed for use + if len(versionErrors) > 0 { + invalidEntries = append(invalidEntries, ChartsWithErrors{ + Template: version, + error: InvalidChartError{ + Err: strings.Join(versionErrors, ";"), + TemplateName: version.Name, + }, + }) + } + } + } + // remove invalid entry from catalog entries so that they are not processed into templates + for _, version := range invalidEntries { + delete(catalogEntries, version.Template.Name) + } + return invalidEntries, catalogEntries +} + +func isInvalidVersionURL(versionURL string) bool { + url, err := url.Parse(versionURL) + if err != nil { + return false + } + if url.Scheme == "file" || url.Scheme == "local" { + return true + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_sync.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_sync.go new file mode 100644 index 0000000..aa126fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/catalog_sync.go @@ -0,0 +1,136 @@ +package manager + +import ( + "github.com/rancher/rancher/pkg/catalog/utils" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func (m *Manager) updateCatalogError(catalog *v3.Catalog, err error) (runtime.Object, error) { + setRefreshedError(catalog, err) + m.catalogClient.Update(catalog) + return nil, err +} + +func (m *Manager) Sync(key string, obj *v3.Catalog) (runtime.Object, error) { + if obj == nil { + return nil, m.deleteTemplates(key, namespace.GlobalNamespace) + } + + // always get a refresh catalog from etcd + catalog, err := m.catalogClient.Get(key, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + // When setting SystemCatalog is set to bundled, always force our catalogs to keep running that way + if m.bundledMode { + if (catalog.Name == "helm3-library" || catalog.Name == "library" || catalog.Name == "system-library") && catalog.Spec.CatalogKind != helmlib.KindHelmInternal { + catalog.Spec.CatalogKind = helmlib.KindHelmInternal + catalog, err = m.catalogClient.Update(catalog) + if err != nil { + return nil, err + } + } + } + + commit, helm, err := helmlib.NewForceUpdate(catalog, m.SecretLister) + if err != nil { + return m.updateCatalogError(catalog, err) + } + logrus.Debugf("Chart hash comparison for global catalog %v: new -- %v --- current -- %v", catalog.Name, commit, catalog.Status.Commit) + + if isUpToDate(commit, catalog) { + if setRefreshed(catalog) { + m.catalogClient.Update(catalog) + } + return nil, nil + } + + cmt := &CatalogInfo{ + catalog: catalog, + } + + logrus.Infof("Updating global catalog %s", catalog.Name) + err = m.traverseAndUpdate(helm, commit, cmt) + if err != nil { + return nil, err + } + + if catalog.Name == utils.SystemLibraryName { + // ensure the system catalog image cache exists + forceUpdate := !isUpToDate(commit, catalog) + return nil, CreateOrUpdateSystemCatalogImageCache(catalog, m.ConfigMap, m.ConfigMapLister, false, forceUpdate) + } + + return nil, nil +} + +func CreateOrUpdateSystemCatalogImageCache(systemCatalog *v3.Catalog, configMapInterface v1.ConfigMapInterface, configMapLister v1.ConfigMapLister, bundledMode bool, forceUpdate bool) (err error) { + var systemCatalogChartPath string + systemCatalogChartPath, err = utils.GetCatalogChartPath(systemCatalog, bundledMode) + if err != nil { + return err + } + + var systemCatalogImageCache *v1.ConfigMap + var systemCatalogImageCacheCreated bool + + systemCatalogImageCacheName := utils.GetCatalogImageCacheName(systemCatalog.Name) + systemCatalogImageCache, err = configMapLister.Get(namespace.System, systemCatalogImageCacheName) + rancherVersion := settings.GetRancherVersion() + if !image.IsValidSemver(rancherVersion) { + rancherVersion = settings.RancherVersionDev + } + + // if the cache does not exist generate it + if err != nil && errors.IsNotFound(err) { + logrus.Debug("system catalog image cache configmap not found") + + systemCatalogImageCache = &v1.ConfigMap{} + systemCatalogImageCache.Name = systemCatalogImageCacheName + systemCatalogImageCache.Namespace = namespace.System + + err = image.AddImagesToImageListConfigMap(systemCatalogImageCache, rancherVersion, systemCatalogChartPath) + if err != nil { + return + } + + systemCatalogImageCache, err = configMapInterface.Create(systemCatalogImageCache) + if err != nil && !errors.IsAlreadyExists(err) { + return + } + systemCatalogImageCacheCreated = true + logrus.Debug("system catalog image cache configmap created") + + } else if err != nil { + return + } + + // if the cache exists and is out of date update it + if forceUpdate || systemCatalogImageCacheCreated { + if err != nil { + return err + } + err = image.AddImagesToImageListConfigMap(systemCatalogImageCache, rancherVersion, systemCatalogChartPath) + if err != nil { + return + } + + _, err = configMapInterface.Update(systemCatalogImageCache) + if err != nil { + return + } + logrus.Debug("system catalog image cache updated") + } + + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/cluster_catalog_sync.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/cluster_catalog_sync.go new file mode 100644 index 0000000..a9f11eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/cluster_catalog_sync.go @@ -0,0 +1,54 @@ +package manager + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +func (m *Manager) updateClusterCatalogError(clusterCatalog *v3.ClusterCatalog, err error) (runtime.Object, error) { + setRefreshedError(&clusterCatalog.Catalog, err) + m.clusterCatalogClient.Update(clusterCatalog) + return nil, err +} + +func (m *Manager) ClusterCatalogSync(key string, obj *v3.ClusterCatalog) (runtime.Object, error) { + ns, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, err + } + + if obj == nil { + return nil, m.deleteTemplates(name, ns) + } + + // always get a refresh catalog from etcd + clusterCatalog, err := m.clusterCatalogClient.GetNamespaced(ns, name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + commit, helm, err := helmlib.NewForceUpdate(&clusterCatalog.Catalog, m.SecretLister) + if err != nil { + return m.updateClusterCatalogError(clusterCatalog, err) + } + logrus.Debugf("Chart hash comparison for cluster catalog %v: new -- %v --- current -- %v", clusterCatalog.Name, commit, &clusterCatalog.Catalog.Status.Commit) + + if isUpToDate(commit, &clusterCatalog.Catalog) { + if setRefreshed(&clusterCatalog.Catalog) { + m.clusterCatalogClient.Update(clusterCatalog) + } + return nil, nil + } + + cmt := &CatalogInfo{ + catalog: &clusterCatalog.Catalog, + clusterCatalog: clusterCatalog, + } + + logrus.Infof("Updating cluster catalog %s", clusterCatalog.Name) + return nil, m.traverseAndUpdate(helm, commit, cmt) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/config.go new file mode 100644 index 0000000..0755fdb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/config.go @@ -0,0 +1,11 @@ +package manager + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +type CatalogInfo struct { + catalog *v3.Catalog + projectCatalog *v3.ProjectCatalog + clusterCatalog *v3.ClusterCatalog +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/crd.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/crd.go new file mode 100644 index 0000000..78a3512 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/crd.go @@ -0,0 +1,201 @@ +package manager + +import ( + "fmt" + "reflect" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/catalog/utils" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" +) + +const ( + CatalogNameLabel = "catalog.cattle.io/name" + TemplateNameLabel = "catalog.cattle.io/template_name" +) + +func (m *Manager) createTemplate(template v3.CatalogTemplate, catalog *v3.Catalog) error { + template.Labels = labels.Merge(template.Labels, map[string]string{ + CatalogNameLabel: catalog.Name, + }) + versionFiles := make([]v32.TemplateVersionSpec, len(template.Spec.Versions)) + copy(versionFiles, template.Spec.Versions) + for i := range template.Spec.Versions { + template.Spec.Versions[i].Files = nil + template.Spec.Versions[i].Readme = "" + template.Spec.Versions[i].AppReadme = "" + } + logrus.Debugf("Creating template %s", template.Name) + createdTemplate, err := m.templateClient.Create(&template) + if err != nil { + return errors.Wrapf(err, "failed to create template %s", template.Name) + } + return m.createTemplateVersions(catalog.Name, versionFiles, createdTemplate) +} + +func (m *Manager) getTemplateMap(catalogName string, namespace string) (map[string]*v3.CatalogTemplate, error) { + r, _ := labels.NewRequirement(CatalogNameLabel, selection.Equals, []string{catalogName}) + templateList, err := m.templateLister.List(namespace, labels.NewSelector().Add(*r)) + if err != nil { + return nil, errors.Wrapf(err, "failed to list templates for %v", catalogName) + } + templateMap := make(map[string]*v3.CatalogTemplate) + for _, t := range templateList { + templateMap[t.Name] = t + } + return templateMap, nil +} + +func (m *Manager) updateTemplate(template *v3.CatalogTemplate, toUpdate v3.CatalogTemplate) error { + r, err := labels.NewRequirement(TemplateNameLabel, selection.Equals, []string{template.Name}) + if err != nil { + return errors.Wrapf(err, "failed to find template version with label %v for %v", TemplateNameLabel, template.Name) + } + templateVersions, err := m.templateVersionLister.List(template.Namespace, labels.NewSelector().Add(*r)) + if err != nil { + return errors.Wrapf(err, "failed to list templateVersions") + } + tvByVersion := map[string]*v3.CatalogTemplateVersion{} + for _, ver := range templateVersions { + tvByVersion[ver.Spec.Version] = ver + } + /* + For each templateVersion in toUpdate, if spec doesn't match, do update + For version that doesn't exist, create a new one + */ + for _, toUpdateVer := range toUpdate.Spec.Versions { + templateVersion := &v3.CatalogTemplateVersion{} + templateVersion.Spec = toUpdateVer + if tv, ok := tvByVersion[toUpdateVer.Version]; ok { + if !reflect.DeepEqual(tv.Spec, toUpdateVer) { + logrus.Debugf("Updating templateVersion %v", tv.Name) + newObject := tv.DeepCopy() + newObject.Spec = templateVersion.Spec + if _, err := m.templateVersionClient.Update(newObject); err != nil { + return err + } + } + } else { + toCreate := &v3.CatalogTemplateVersion{} + toCreate.Name = fmt.Sprintf("%s-%v", template.Name, toUpdateVer.Version) + toCreate.Namespace = template.Namespace + toCreate.Labels = map[string]string{ + TemplateNameLabel: template.Name, + } + toCreate.Spec = templateVersion.Spec + toCreate.Status = v32.TemplateVersionStatus{HelmVersion: template.Status.HelmVersion} + logrus.Debugf("Creating templateVersion %v", toCreate.Name) + if _, err := m.templateVersionClient.Create(toCreate); err != nil { + return err + } + } + } + + // find existing templateVersion that is not in toUpdate.Versions + toUpdateTvs := map[string]struct{}{} + for _, toUpdateVer := range toUpdate.Spec.Versions { + toUpdateTvs[toUpdateVer.Version] = struct{}{} + } + for v, tv := range tvByVersion { + if _, ok := toUpdateTvs[v]; !ok { + logrus.Infof("Deleting templateVersion %s", tv.Name) + if err := m.templateVersionClient.DeleteNamespaced(template.Namespace, tv.Name, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) { + return err + } + } + } + + for i := range toUpdate.Spec.Versions { + toUpdate.Spec.Versions[i].Files = nil + toUpdate.Spec.Versions[i].Readme = "" + toUpdate.Spec.Versions[i].AppReadme = "" + } + newObj := template.DeepCopy() + newObj.Spec = toUpdate.Spec + newObj.Labels = mergeLabels(template.Labels, toUpdate.Labels) + if _, err := m.templateClient.Update(newObj); err != nil { + return err + } + return nil +} + +// merge any label from set2 into set1 and delete label +func mergeLabels(set1, set2 map[string]string) map[string]string { + if set1 == nil { + set1 = map[string]string{} + } + for k, v := range set2 { + set1[k] = v + } + for k := range set1 { + if set2 != nil { + if _, ok := set2[k]; !ok && k != CatalogNameLabel { + delete(set1, k) + } + } else { + if k != CatalogNameLabel { + delete(set1, k) + } + } + + } + return set1 +} + +func (m *Manager) getTemplateVersion(templateName string, namespace string) (map[string]struct{}, error) { + //because templates is a cluster resource now so we set namespace to "" when listing it. + r, err := labels.NewRequirement(TemplateNameLabel, selection.Equals, []string{templateName}) + if err != nil { + return nil, errors.Wrapf(err, "failed to find template version with label %v for %v", TemplateNameLabel, templateName) + } + templateVersions, err := m.templateVersionLister.List(namespace, labels.NewSelector().Add(*r)) + if err != nil { + return nil, errors.Wrapf(err, "failed to list template version(s) for %v: ", templateName) + } + tVersion := map[string]struct{}{} + for _, ver := range templateVersions { + tVersion[ver.Name] = struct{}{} + } + return tVersion, nil +} + +func (m *Manager) createTemplateVersions(catalogName string, versionsSpec []v32.TemplateVersionSpec, template *v3.CatalogTemplate) error { + for _, spec := range versionsSpec { + templateVersion := &v3.CatalogTemplateVersion{} + templateVersion.Spec = spec + templateVersion.Status = v32.TemplateVersionStatus{HelmVersion: template.Status.HelmVersion} + templateVersion.Name = getValidTemplateNameWithVersion(template.Name, spec.Version) + templateVersion.Namespace = template.Namespace + templateVersion.Labels = map[string]string{ + TemplateNameLabel: template.Name, + } + //help with garbage collection on delete + ownerRef := []metav1.OwnerReference{{ + Name: template.Name, + APIVersion: "management.cattle.io/v3", + UID: template.UID, + Kind: template.Kind, + }} + templateVersion.OwnerReferences = ownerRef + + logrus.Debugf("Creating templateVersion %s", templateVersion.Name) + if _, err := m.templateVersionClient.Create(templateVersion); err != nil && !kerrors.IsAlreadyExists(err) { + return err + } + } + return nil +} + +func showUpgradeLinks(version, upgradeVersion string) bool { + if !utils.VersionGreaterThan(upgradeVersion, version) { + return false + } + return true +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager.go new file mode 100644 index 0000000..2aab5ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager.go @@ -0,0 +1,335 @@ +package manager + +import ( + "fmt" + "sort" + "strings" + "time" + + "github.com/blang/semver" + "github.com/pkg/errors" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalog/utils" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + projectv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// IncompatibleTemplateVersionErr is returned when there's no valid template version for the current Kubernetes cluster +type IncompatibleTemplateVersionErr error + +type Manager struct { + catalogClient v3.CatalogInterface + CatalogLister v3.CatalogLister + ClusterLister v3.ClusterLister + templateClient v3.CatalogTemplateInterface + templateContentClient v3.TemplateContentInterface + templateVersionClient v3.CatalogTemplateVersionInterface + templateLister v3.CatalogTemplateLister + templateVersionLister v3.CatalogTemplateVersionLister + projectCatalogClient v3.ProjectCatalogInterface + ProjectCatalogLister v3.ProjectCatalogLister + clusterCatalogClient v3.ClusterCatalogInterface + ClusterCatalogLister v3.ClusterCatalogLister + appRevisionClient projectv3.AppRevisionInterface + lastUpdateTime time.Time + bundledMode bool + ConfigMap corev1.ConfigMapInterface + ConfigMapLister corev1.ConfigMapLister + SecretLister corev1.SecretLister +} + +type CatalogManager interface { + ValidateChartCompatibility(template *v3.CatalogTemplateVersion, clusterName, currentAppVersion string) error + ValidateKubeVersion(template *v3.CatalogTemplateVersion, clusterName string) error + ValidateRancherVersion(template *v3.CatalogTemplateVersion, currentAppVersion string) error + LatestAvailableTemplateVersion(template *v3.CatalogTemplate, clusterName string) (*v32.TemplateVersionSpec, error) + GetSystemAppCatalogID(templateVersionID, clusterName string) (string, error) +} + +func New(management v3.Interface, project projectv3.Interface, core corev1.Interface) *Manager { + var bundledMode bool + if strings.ToLower(settings.SystemCatalog.Get()) == "bundled" { + bundledMode = true + } + return &Manager{ + catalogClient: management.Catalogs(""), + CatalogLister: management.Catalogs("").Controller().Lister(), + ClusterLister: management.Clusters("").Controller().Lister(), + templateClient: management.CatalogTemplates(""), + templateContentClient: management.TemplateContents(""), + templateVersionClient: management.CatalogTemplateVersions(""), + templateLister: management.CatalogTemplates("").Controller().Lister(), + templateVersionLister: management.CatalogTemplateVersions("").Controller().Lister(), + projectCatalogClient: management.ProjectCatalogs(""), + ProjectCatalogLister: management.ProjectCatalogs("").Controller().Lister(), + clusterCatalogClient: management.ClusterCatalogs(""), + ClusterCatalogLister: management.ClusterCatalogs("").Controller().Lister(), + appRevisionClient: project.AppRevisions(""), + bundledMode: bundledMode, + ConfigMap: core.ConfigMaps(""), + ConfigMapLister: core.ConfigMaps("").Controller().Lister(), + SecretLister: core.Secrets("").Controller().Lister(), + } +} + +func (m *Manager) deleteChart(toDelete string, namespace string) error { + toDeleteTvs, err := m.getTemplateVersion(toDelete, namespace) + if err != nil { + return err + } + for tv := range toDeleteTvs { + if err := m.templateVersionClient.DeleteNamespaced(namespace, tv, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) { + return err + } + } + if err := m.templateClient.DeleteNamespaced(namespace, toDelete, &metav1.DeleteOptions{}); err != nil && !kerrors.IsNotFound(err) { + return err + } + return nil +} + +func getKey(namespace, name string) string { + return fmt.Sprintf("%s/%s", namespace, name) +} + +func (m *Manager) DeleteOldTemplateContent() bool { + // Template content is not used, remove old contents + if err := m.templateContentClient.DeleteCollection(&metav1.DeleteOptions{}, metav1.ListOptions{}); err != nil { + logrus.Warnf("Catalog-manager error deleting old template content: %s", err) + return false + } + return true +} + +func (m *Manager) DeleteBadCatalogTemplates() bool { + // Orphaned catalog templates and template versions may exist, remove anywhere the catalog does not exist + errs := m.deleteBadCatalogTemplates() + if len(errs) == 0 { + return true + } + for _, err := range errs { + logrus.Errorf("Catalog-manager error deleting bad catalog templates: %s", err) + } + return false +} + +func (m *Manager) deleteBadCatalogTemplates() []error { + templates, err := m.templateClient.List(metav1.ListOptions{}) + if err != nil { + return []error{err} + } + + templateVersions, err := m.templateVersionClient.List(metav1.ListOptions{}) + if err != nil { + return []error{err} + } + + var hasCatalog = map[string]bool{} + + catalogs, err := m.catalogClient.List(metav1.ListOptions{}) + if err != nil { + return []error{err} + } + for _, catalog := range catalogs.Items { + hasCatalog[getKey(namespace.GlobalNamespace, catalog.Name)] = true + } + + clusterCatalogs, err := m.clusterCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return []error{err} + } + for _, clusterCatalog := range clusterCatalogs.Items { + hasCatalog[getKey(clusterCatalog.Namespace, clusterCatalog.Name)] = true + } + + projectCatalogs, err := m.projectCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return []error{err} + } + for _, projectCatalog := range projectCatalogs.Items { + hasCatalog[getKey(projectCatalog.Namespace, projectCatalog.Name)] = true + } + + var ( + deleteCount int + errs []error + ) + + for _, template := range templates.Items { + var catalogName string + if template.Spec.CatalogID != "" { + catalogName = template.Spec.CatalogID + } else if template.Spec.ClusterCatalogID != "" { + catalogName = template.Spec.ClusterCatalogID + } else if template.Spec.ProjectCatalogID != "" { + catalogName = template.Spec.ProjectCatalogID + } + + ns, name := helmlib.SplitNamespaceAndName(catalogName) + if ns == "" { + ns = namespace.GlobalNamespace + } + if !hasCatalog[getKey(ns, name)] { + if err := m.templateClient.DeleteNamespaced(template.Namespace, template.Name, &metav1.DeleteOptions{}); err != nil { + errs = append(errs, err) + } + deleteCount++ + } + } + + for _, templateVersion := range templateVersions.Items { + ns, name, _, _, _, err := common.SplitExternalID(templateVersion.Spec.ExternalID) + if err != nil { + logrus.Errorf("Catalog-manager error extracting namespace/name from template version: %s", err) + continue + } + if ns == "" { + ns = namespace.GlobalNamespace + } + if !hasCatalog[getKey(ns, name)] { + if err := m.templateVersionClient.DeleteNamespaced(templateVersion.Namespace, templateVersion.Name, &metav1.DeleteOptions{}); err != nil { + errs = append(errs, err) + } + deleteCount++ + } + } + + if deleteCount > 0 { + logrus.Infof("Catalog-manager deleted %d orphaned catalog template entries", deleteCount) + } + + return errs +} + +func (m *Manager) ValidateChartCompatibility(template *v3.CatalogTemplateVersion, clusterName, currentAppVersion string) error { + if err := m.ValidateRancherVersion(template, currentAppVersion); err != nil { + return err + } + return m.ValidateKubeVersion(template, clusterName) +} + +func (m *Manager) ValidateKubeVersion(template *v3.CatalogTemplateVersion, clusterName string) error { + if template.Spec.KubeVersion == "" { + return nil + } + constraint, err := semver.ParseRange(template.Spec.KubeVersion) + if err != nil { + logrus.Errorf("failed to parse constraint for kubeversion %s: %v", template.Spec.KubeVersion, err) + return nil + } + + cluster, err := m.ClusterLister.Get("", clusterName) + if err != nil { + return err + } + + if cluster.Status.Version == nil { + return fmt.Errorf("cluster [%s] status version is not available yet. Cannot validate kube version for template [%s]", clusterName, template.Name) + } + + k8sVersion, err := semver.Parse(strings.TrimPrefix(cluster.Status.Version.String(), "v")) + if err != nil { + return err + } + if !constraint(k8sVersion) { + return IncompatibleTemplateVersionErr(fmt.Errorf("incompatible kubernetes version [%s] for template [%s]", k8sVersion.String(), template.Name)) + } + return nil +} + +func (m *Manager) ValidateRancherVersion(template *v3.CatalogTemplateVersion, currentAppVersion string) error { + if currentAppVersion != "" && currentAppVersion == template.Spec.Version { + // if current app version is provided and the version in the update is equal to it then the + // version is deemed okay as it is already installed. This ensures the app can continue to + // be edited as long as it is not being upgraded/rollbacked to another incompatible version. + return nil + } + + serverVersion := settings.ServerVersion.Get() + + // don't compare if we are running as dev or in the build env + if !utils.ReleaseServerVersion(serverVersion) { + return nil + } + + serverVersion = strings.TrimPrefix(serverVersion, "v") + + versionRange := "" + if template.Spec.RancherMinVersion != "" { + versionRange += " >=" + strings.TrimPrefix(template.Spec.RancherMinVersion, "v") + } + if template.Spec.RancherMaxVersion != "" { + versionRange += " <=" + strings.TrimPrefix(template.Spec.RancherMaxVersion, "v") + } + if versionRange == "" { + return nil + } + constraint, err := semver.ParseRange(versionRange) + if err != nil { + logrus.Errorf("failed to parse constraint for rancher version %s: %v", versionRange, err) + return nil + } + + rancherVersion, err := semver.Parse(serverVersion) + if err != nil { + return err + } + if !constraint(rancherVersion) { + return IncompatibleTemplateVersionErr(fmt.Errorf("incompatible rancher version [%s] for template [%s]", serverVersion, template.Name)) + } + return nil +} + +func (m *Manager) LatestAvailableTemplateVersion(template *v3.CatalogTemplate, clusterName string) (*v32.TemplateVersionSpec, error) { + versions := template.DeepCopy().Spec.Versions + if len(versions) == 0 { + return nil, errors.New("empty catalog template version list") + } + + sort.Slice(versions, func(i, j int) bool { + val1, err := semver.ParseTolerant(versions[i].Version) + if err != nil { + return false + } + + val2, err := semver.ParseTolerant(versions[j].Version) + if err != nil { + return false + } + + return val2.LT(val1) + }) + + for _, templateVersion := range versions { + catalogTemplateVersion := &v3.CatalogTemplateVersion{ + Spec: templateVersion, + } + + if err := m.ValidateChartCompatibility(catalogTemplateVersion, clusterName, ""); err == nil { + return &templateVersion, nil + } + } + + return nil, IncompatibleTemplateVersionErr(errors.Errorf("template %s incompatible with rancher version or cluster's [%s] kubernetes version", template.Name, clusterName)) +} + +func (m *Manager) GetSystemAppCatalogID(templateVersionID, clusterName string) (string, error) { + template, err := m.templateLister.Get(namespace.GlobalNamespace, templateVersionID) + if err != nil { + return "", errors.Wrapf(err, "failed to find template by ID %s", templateVersionID) + } + + templateVersion, err := m.LatestAvailableTemplateVersion(template, clusterName) + if err != nil { + return "", err + } + return templateVersion.ExternalID, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager_test.go new file mode 100644 index 0000000..dde275a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/manager_test.go @@ -0,0 +1,212 @@ +package manager + +import ( + "testing" + + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" +) + +func TestLatestAvailableTemplateVersion(t *testing.T) { + template := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + RancherMinVersion: "v2.2.0", + RancherMaxVersion: "v2.3.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + RancherMinVersion: "v2.1.0", + RancherMaxVersion: "v2.2.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + RancherMinVersion: "v2.0.0", + RancherMaxVersion: "v2.1.0", + }, + }, + }, + } + + templateWithoutRancherVersion := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + }, + }, + }, + } + + templateWithoutMinRancherVersion := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + RancherMaxVersion: "v2.3.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + RancherMaxVersion: "v2.2.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + RancherMaxVersion: "v2.1.0", + }, + }, + }, + } + + templateWithoutMaxRancherVersion := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + RancherMinVersion: "v2.2.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + RancherMinVersion: "v2.1.0", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + RancherMinVersion: "v2.0.0", + }, + }, + }, + } + + templateWithMinPrerelease := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + RancherMinVersion: "v2.2.1-rc1", + RancherMaxVersion: "v2.2.2", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + RancherMinVersion: "v2.2.0-rc1", + RancherMaxVersion: "v2.2.1", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + }, + }, + }, + } + + templateWith99MaxPatchVersion := &v3.CatalogTemplate{ + Spec: v3.TemplateSpec{ + Versions: []v3.TemplateVersionSpec{ + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.16", + Version: "0.12.16", + RancherMinVersion: "v2.3.0-alpha1", + RancherMaxVersion: "v2.3.99", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.15", + Version: "0.12.15", + RancherMinVersion: "v2.2.0-alpha1", + RancherMaxVersion: "v2.2.99", + }, + { + ExternalID: "catalog://?catalog=library&template=artifactory-ha&version=0.12.14", + Version: "0.12.14", + }, + }, + }, + } + + testLatestAvailableTemplateVersion(t, "v2.0.1", "0.12.14", template) + testLatestAvailableTemplateVersion(t, "v2.0.2-beta", "0.12.14", template) + testLatestAvailableTemplateVersion(t, "v2.1.0-alpha1", "0.12.14", template) + testLatestAvailableTemplateVersion(t, "v2.1.0", "0.12.15", template) + testLatestAvailableTemplateVersion(t, "v2.2.5", "0.12.16", template) + testLatestAvailableTemplateVersion(t, "dev", "0.12.16", template) + testLatestAvailableTemplateVersion(t, "master", "0.12.16", template) + testLatestAvailableTemplateVersion(t, "master-head", "0.12.16", template) + testLatestAvailableTemplateVersion(t, "", "0.12.16", template) + + testLatestAvailableTemplateVersion(t, "v2.0.1", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.0.2-beta", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0-alpha1", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.2.5", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "master", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "master-head", "0.12.16", templateWithoutRancherVersion) + testLatestAvailableTemplateVersion(t, "", "0.12.16", templateWithoutRancherVersion) + + testLatestAvailableTemplateVersion(t, "v2.0.1", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.0.2-beta", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0-alpha1", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.2.5", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "dev", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "master", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "master-head", "0.12.16", templateWithoutMinRancherVersion) + testLatestAvailableTemplateVersion(t, "", "0.12.16", templateWithoutMinRancherVersion) + + testLatestAvailableTemplateVersion(t, "v2.0.1", "0.12.14", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.0.2-beta", "0.12.14", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0-alpha1", "0.12.14", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.1.0", "0.12.15", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "v2.2.5", "0.12.16", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "dev", "0.12.16", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "master", "0.12.16", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "master-head", "0.12.16", templateWithoutMaxRancherVersion) + testLatestAvailableTemplateVersion(t, "", "0.12.16", templateWithoutMaxRancherVersion) + + testLatestAvailableTemplateVersion(t, "v2.2.0-0", "0.12.14", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.0-alpha1", "0.12.14", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.0-rc1", "0.12.15", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.0", "0.12.15", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.1-0", "0.12.15", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.1-alpha1", "0.12.15", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.1-rc1", "0.12.16", templateWithMinPrerelease) + testLatestAvailableTemplateVersion(t, "v2.2.1", "0.12.16", templateWithMinPrerelease) + + testLatestAvailableTemplateVersion(t, "v2.2.0-0", "0.12.14", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.2.0-alpha1", "0.12.15", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.2.0-rc1", "0.12.15", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.2.0", "0.12.15", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.3.0-0", "0.12.14", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.3.0-alpha1", "0.12.16", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.3.0-rc1", "0.12.16", templateWith99MaxPatchVersion) + testLatestAvailableTemplateVersion(t, "v2.3.0", "0.12.16", templateWith99MaxPatchVersion) +} + +func testLatestAvailableTemplateVersion(t *testing.T, serverVersion, expectedCatalogVersion string, template *v3.CatalogTemplate) { + err := settings.ServerVersion.Set(serverVersion) + assert.Nil(t, err) + + catalogManager := Manager{} + templateVersion, err := catalogManager.LatestAvailableTemplateVersion(template, "") + assert.Nil(t, err) + assert.Equal(t, expectedCatalogVersion, templateVersion.Version) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/project_catalog_sync.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/project_catalog_sync.go new file mode 100644 index 0000000..d5ab000 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/project_catalog_sync.go @@ -0,0 +1,54 @@ +package manager + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +func (m *Manager) updateProjectCatalogError(projectCatalog *v3.ProjectCatalog, err error) (runtime.Object, error) { + setRefreshedError(&projectCatalog.Catalog, err) + m.projectCatalogClient.Update(projectCatalog) + return nil, err +} + +func (m *Manager) ProjectCatalogSync(key string, obj *v3.ProjectCatalog) (runtime.Object, error) { + ns, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, err + } + + if obj == nil { + return nil, m.deleteTemplates(name, ns) + } + + // always get a refresh catalog from etcd + projectCatalog, err := m.projectCatalogClient.GetNamespaced(ns, name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + commit, helm, err := helmlib.NewForceUpdate(&projectCatalog.Catalog, m.SecretLister) + if err != nil { + return m.updateProjectCatalogError(projectCatalog, err) + } + logrus.Debugf("Chart hash comparison for project catalog %v: new -- %v --- current -- %v", projectCatalog.Name, commit, &projectCatalog.Catalog.Status.Commit) + + if isUpToDate(commit, &projectCatalog.Catalog) { + if setRefreshed(&projectCatalog.Catalog) { + m.projectCatalogClient.Update(projectCatalog) + } + return nil, nil + } + + cmt := &CatalogInfo{ + catalog: &projectCatalog.Catalog, + projectCatalog: projectCatalog, + } + + logrus.Infof("Updating project catalog %s", projectCatalog.Name) + return nil, m.traverseAndUpdate(helm, commit, cmt) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse.go new file mode 100644 index 0000000..60d87c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse.go @@ -0,0 +1,374 @@ +package manager + +import ( + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/norman/controller" + cutils "github.com/rancher/rancher/pkg/catalog/utils" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/namespace" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func (m *Manager) traverseAndUpdate(helm *helmlib.Helm, commit string, cmt *CatalogInfo) error { + index, err := helm.LoadIndex() + if err != nil { + return err + } + + var catalogName, templateNamespace string + catalog := cmt.catalog + projectCatalog := cmt.projectCatalog + clusterCatalog := cmt.clusterCatalog + catalogType := getCatalogType(cmt) + + switch catalogType { + case client.CatalogType: + templateNamespace = namespace.GlobalNamespace + catalogName = catalog.Name + case client.ClusterCatalogType: + templateNamespace = clusterCatalog.Namespace + catalogName = clusterCatalog.Name + case client.ProjectCatalogType: + templateNamespace = projectCatalog.Namespace + catalogName = projectCatalog.Name + } + + // Remove contents of deprecated field if found. This can greatly reduce Catalog CR size. + if err := m.dropDeprecatedFields(cmt, catalogType); err != nil { + return err + } + + var errs, createErrors, updateErrors []error + var createdTemplates, updatedTemplates, deletedTemplates, failedTemplates int + + if (v32.CatalogConditionRefreshed.IsUnknown(catalog) && !strings.Contains(v32.CatalogConditionRefreshed.GetStatus(catalog), "syncing catalog")) || v32.CatalogConditionRefreshed.IsTrue(catalog) || catalog.Status.Conditions == nil { + cmt, err = m.updateCatalogInfo(cmt, catalogType, "sync", true, false) + if err != nil { + return err + } + } + + catalogTemplateMap, err := m.getTemplateMap(catalogName, templateNamespace) + if err != nil { + return err + } + + var skippedCharts []string + catalogHasAllUpdates := hasAllUpdates(catalog) + entriesWithErrors, entriesToProcess := m.preprocessCatalog(catalog, index.IndexFile.Entries) + for chart, chartVersions := range entriesToProcess { + if chartVersions == nil { + continue + } + if !hasChartChanged(catalogTemplateMap[getValidTemplateName(catalogName, chart)], chartVersions) && catalogHasAllUpdates { + skippedCharts = append(skippedCharts, chart) + continue + } + + template := v3.CatalogTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.ToLower(chart), + }, + } + template.Namespace = templateNamespace + template.Spec.Description = chartVersions[0].Description + template.Spec.DefaultVersion = chartVersions[0].Version + if len(chartVersions[0].Sources) > 0 { + template.Spec.ProjectURL = chartVersions[0].Sources[0] + } + iconFilename, iconURL, err := helm.Icon(chartVersions) + if err != nil { + return err + } + + template.Spec.Icon = iconURL + template.Spec.IconFilename = iconFilename + template.Spec.FolderName = chart + template.Spec.DisplayName = chart + template.Status.HelmVersion = catalog.Spec.HelmVersion + + label := make(map[string]string) + keywords := make(map[string]struct{}) + var versions []v32.TemplateVersionSpec + for _, version := range chartVersions { + v := v32.TemplateVersionSpec{ + Version: strings.ToLower(version.Version), + } + + files, err := helm.FetchLocalFiles(version) + if err != nil { + return err + } + + for _, file := range files { + for _, f := range supportedFiles { + if strings.EqualFold(fmt.Sprintf("%s/%s", chart, f), file.Name) { + var value catalogYml + if err := yaml.Unmarshal([]byte(file.Contents), &value); err != nil { + errs = append(errs, err) + continue + } + v.RancherMinVersion = value.RancherMin + v.RancherMaxVersion = value.RancherMax + v.RequiredNamespace = value.Namespace + label = labels.Merge(label, value.Labels) + for _, category := range value.Categories { + keywords[category] = struct{}{} + } + break + } + } + } + v.KubeVersion = version.KubeVersion + v.Digest = version.Digest + + // for local cache rebuild + v.VersionDir = version.Dir + v.VersionName = version.Name + v.VersionURLs = version.URLs + + for _, versionSpec := range template.Spec.Versions { + // only set UpgradeVersionLinks once and not every loop + if v.UpgradeVersionLinks == nil { + v.UpgradeVersionLinks = map[string]string{} + } + if showUpgradeLinks(v.Version, versionSpec.Version) { + version := versionSpec.Version + v.UpgradeVersionLinks[versionSpec.Version] = fmt.Sprintf("%s-%s", template.Name, version) + } + } + + if catalogType == client.CatalogType { + v.ExternalID = fmt.Sprintf(cutils.CatalogExternalIDFormat, catalog.Name, template.Spec.FolderName, v.Version) + } else { + v.ExternalID = fmt.Sprintf("catalog://?catalog=%s/%s&type=%s&template=%s&version=%s", templateNamespace, catalog.Name, catalogType, template.Spec.FolderName, v.Version) + } + versions = append(versions, v) + } + var categories []string + for k := range keywords { + categories = append(categories, k) + } + // merge all labels from templateVersion to template + template.Labels = label + template.Spec.Categories = categories + template.Spec.Versions = versions + template.Name = getValidTemplateName(catalog.Name, template.Spec.FolderName) + switch catalogType { + case client.CatalogType: + template.Spec.CatalogID = catalog.Name + case client.ClusterCatalogType: + if clusterCatalog == nil || clusterCatalog.Name == "" { + return errors.New("Cluster catalog is no longer available") + } + labelMap := make(map[string]string) + cname := clusterCatalog.Namespace + ":" + clusterCatalog.Name + template.Spec.ClusterCatalogID = cname + template.Spec.ClusterID = clusterCatalog.ClusterName + labelMap[template.Spec.ClusterID+"-"+clusterCatalog.Name] = clusterCatalog.Name + newLabels := labels.Merge(template.Labels, labelMap) + template.Labels = newLabels + case client.ProjectCatalogType: + if projectCatalog == nil || projectCatalog.Name == "" { + return errors.New("Project catalog is no longer available") + } + labelMap := make(map[string]string) + pname := projectCatalog.Namespace + ":" + projectCatalog.Name + template.Spec.ProjectCatalogID = pname + template.Spec.ProjectID = projectCatalog.ProjectName + split := strings.SplitN(template.Spec.ProjectID, ":", 2) + if len(split) != 2 { + return errors.New("Project ID invalid while creating template") + } + labelMap[split[0]+"-"+projectCatalog.Namespace+"-"+projectCatalog.Name] = projectCatalog.Name + newLabels := labels.Merge(template.Labels, labelMap) + template.Labels = newLabels + } + + catalog = cmt.catalog + projectCatalog = cmt.projectCatalog + clusterCatalog = cmt.clusterCatalog + if catalog == nil || catalog.Name == "" { + return errors.New("Catalog is no longer available") + } + if isUpToDate(commit, catalog) { + logrus.Debugf("Stopping catalog [%s] update, catalog already up to date", catalog.Name) + return nil + } + logrus.Debugf("Catalog [%s] found chart template for [%s]", catalog.Name, chart) + + // look for template by name, if not found then create it, otherwise do update + existing, err := m.templateLister.Get(template.Namespace, template.Name) + if apierrors.IsNotFound(err) { + err = m.createTemplate(template, catalog) + if err != nil { + createErrors = append(createErrors, err) + failedTemplates++ + } else { + createdTemplates++ + } + } else if err == nil { + err = m.updateTemplate(existing, template) + if err != nil { + updateErrors = append(updateErrors, err) + failedTemplates++ + } else { + updatedTemplates++ + } + } + } + logrus.Debugf("skipped generating templates for charts that have not been changed: %v", skippedCharts) + + var toDeleteChart []string + for templateName := range catalogTemplateMap { + chart := getChartName(catalog.Name, templateName) + if chart == "" { + continue + } + if _, ok := index.IndexFile.Entries[chart]; !ok { + toDeleteChart = append(toDeleteChart, templateName) + } + } + // delete non-existing templates + for _, toDelete := range toDeleteChart { + logrus.Debugf("Deleting template %s and its associated templateVersion in namespace %s", toDelete, templateNamespace) + if err := m.deleteChart(toDelete, templateNamespace); err != nil { + return err + } + deletedTemplates++ + } + failedTemplates = failedTemplates + len(entriesWithErrors) + logrus.Infof("Catalog sync done. %v templates created, %v templates updated, %v templates deleted, %v templates failed", createdTemplates, updatedTemplates, deletedTemplates, failedTemplates) + + if projectCatalog != nil { + projectCatalog.Catalog = *catalog + } else if clusterCatalog != nil { + clusterCatalog.Catalog = *catalog + } + /*conditions need to be set here to stop templates from updating + each time when they have no changes + */ + setTraverseCompleted(catalog) + var errstrings []string + if len(createErrors) > 0 { + errstrings = append(errstrings, fmt.Sprintf("failed to create templates. Multiple error(s) occurred: %v", createErrors)) + } + if len(updateErrors) > 0 { + errstrings = append(errstrings, fmt.Sprintf("failed to update templates. Multiple error(s) occurred: %v", updateErrors)) + } + if len(entriesWithErrors) > 0 && len(errstrings) == 0 { + invalidChartErrors := processInvalidChartErrors(entriesWithErrors) + setCatalogIgnoreErrorState(commit, cmt, catalog, projectCatalog, clusterCatalog, fmt.Sprintf("Error in chart(s): %s", invalidChartErrors)) + if _, err := m.updateCatalogInfo(cmt, catalogType, "", false, true); err != nil { + return err + } + logrus.Error(fmt.Sprintf("failed to sync templates. Multiple error(s) occurred: %v", invalidChartErrors)) + return &controller.ForgetError{Err: errors.Errorf("failed to sync templates. Multiple error(s) occurred: %v", invalidChartErrors)} + } + if len(errstrings) > 0 { + invalidChartErrors := processInvalidChartErrors(entriesWithErrors) + errstrings = append(errstrings, invalidChartErrors) + setCatalogErrorState(cmt, catalog, projectCatalog, clusterCatalog) + if _, err := m.updateCatalogInfo(cmt, catalogType, "", false, true); err != nil { + return err + } + return errors.Errorf(strings.Join(errstrings, ";")) + } + var finalError error + if len(errs) > 0 { + finalError = errors.Errorf("failed to sync templates. Resetting commit. Multiple error occurred: %v", errs) + commit = "" + } + + catalog.Status.Commit = commit + if projectCatalog != nil { + projectCatalog.Catalog = *catalog + } else if clusterCatalog != nil { + clusterCatalog.Catalog = *catalog + } + cmt.catalog = catalog + cmt.projectCatalog = projectCatalog + cmt.clusterCatalog = clusterCatalog + if _, err := m.updateCatalogInfo(cmt, catalogType, "", true, true); err != nil { + return err + } + + return finalError +} + +func (m *Manager) dropDeprecatedFields(cmt *CatalogInfo, catalogType string) error { + switch catalogType { + case client.CatalogType: + catalog := cmt.catalog + if catalog.Status.HelmVersionCommits == nil { + return nil + } + catalog.Status.HelmVersionCommits = nil + case client.ClusterCatalogType: + clusterCatalog := cmt.clusterCatalog + if clusterCatalog.Status.HelmVersionCommits == nil { + return nil + } + clusterCatalog.Status.HelmVersionCommits = nil + case client.ProjectCatalogType: + projectCatalog := cmt.projectCatalog + if projectCatalog.Status.HelmVersionCommits == nil { + return nil + } + projectCatalog.Status.HelmVersionCommits = nil + } + _, err := m.updateCatalogInfo(cmt, catalogType, "", true, true) + return err +} + +// hasChartChanged checks if a version has been deleted from a template or if an existing template version has changed. +func hasChartChanged(existingTemplate *v3.CatalogTemplate, desiredChartVersions helmlib.ChartVersions) bool { + // If this check does not pass, the existing template has been populated and the lengths of each slice are the same. + if existingTemplate == nil || (len(desiredChartVersions) != len(existingTemplate.Spec.Versions)) { + return true + } + + desiredChartVersionsMap := make(map[string]string) + for _, desiredChartVersion := range desiredChartVersions { + desiredChartVersionsMap[desiredChartVersion.Version] = desiredChartVersion.Digest + } + for _, templateVersion := range existingTemplate.Spec.Versions { + // If the digest is not the same between the actual and desired version, or if the version does not + // exist in the desired versions slice, then we know that the chart has changed. In addition, we do not have to + // check if desired versions exist because the length of each slice is the same at this point. + digest, ok := desiredChartVersionsMap[templateVersion.Version] + if !ok || digest != templateVersion.Digest { + return true + } + } + return false +} + +var supportedFiles = []string{"catalog.yml", "catalog.yaml", "questions.yml", "questions.yaml"} + +type catalogYml struct { + RancherMin string `yaml:"rancher_min_version,omitempty"` + RancherMax string `yaml:"rancher_max_version,omitempty"` + Categories []string `yaml:"categories,omitempty"` + Namespace string `yaml:"namespace,omitempty"` + Labels map[string]string `yaml:"labels,omitempty"` +} + +func processInvalidChartErrors(entriesWithErrors []ChartsWithErrors) string { + var invalidChartErrors strings.Builder + for _, errorInfo := range entriesWithErrors { + fmt.Fprintf(&invalidChartErrors, "%s;", errorInfo.error.Error()) + } + return invalidChartErrors.String() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse_test.go new file mode 100644 index 0000000..5992cd6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/manager/traverse_test.go @@ -0,0 +1,196 @@ +package manager + +import ( + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Set_Catalog_Error_State(t *testing.T) { + type testcase struct { + caseName string + catalogInfo CatalogInfo + catalog v3.Catalog + projectCatalog v3.ProjectCatalog + clusterCatalog v3.ClusterCatalog + } + testcases := []testcase{ + { + caseName: "default", + catalogInfo: CatalogInfo{ + catalog: nil, + projectCatalog: nil, + clusterCatalog: nil, + }, + catalog: v3.Catalog{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCatalog"}, + Status: v32.CatalogStatus{ + LastRefreshTimestamp: "", + Commit: "", + HelmVersionCommits: nil, + Conditions: []v32.CatalogCondition{ + { + Type: "Refreshed", + Status: "True", + Message: "Test Catalog Stuff", + }, + }, + }, + }, + projectCatalog: v3.ProjectCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ProjectName: "", + }, + + clusterCatalog: v3.ClusterCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ClusterName: "", + }, + }, + { + caseName: "catalogcondition nil status & nil message", + catalogInfo: CatalogInfo{ + catalog: nil, + projectCatalog: nil, + clusterCatalog: nil, + }, + catalog: v3.Catalog{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCatalog"}, + Status: v32.CatalogStatus{ + LastRefreshTimestamp: "", + Commit: "", + HelmVersionCommits: nil, + }, + }, + projectCatalog: v3.ProjectCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ProjectName: "", + }, + + clusterCatalog: v3.ClusterCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ClusterName: "", + }, + }, + { + caseName: "default", + catalogInfo: CatalogInfo{ + catalog: nil, + projectCatalog: nil, + clusterCatalog: nil, + }, + catalog: v3.Catalog{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCatalog"}, + Status: v32.CatalogStatus{ + LastRefreshTimestamp: "", + Commit: "", + HelmVersionCommits: nil, + Conditions: []v32.CatalogCondition{ + { + Type: "Refreshed", + }, + }, + }, + }, + projectCatalog: v3.ProjectCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ProjectName: "", + }, + + clusterCatalog: v3.ClusterCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ClusterName: "", + }, + }, + { + caseName: "false status", + catalogInfo: CatalogInfo{ + catalog: nil, + projectCatalog: nil, + clusterCatalog: nil, + }, + catalog: v3.Catalog{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCatalog"}, + Status: v32.CatalogStatus{ + LastRefreshTimestamp: "", + Commit: "", + HelmVersionCommits: nil, + Conditions: []v32.CatalogCondition{ + { + Type: "Refreshed", + Status: "False", + Message: "Test Catalog Stuff", + }, + }, + }, + }, + projectCatalog: v3.ProjectCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ProjectName: "", + }, + + clusterCatalog: v3.ClusterCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ClusterName: "", + }, + }, + { + caseName: "invalid status", + catalogInfo: CatalogInfo{ + catalog: nil, + projectCatalog: nil, + clusterCatalog: nil, + }, + catalog: v3.Catalog{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCatalog"}, + Status: v32.CatalogStatus{ + LastRefreshTimestamp: "", + Commit: "", + HelmVersionCommits: nil, + Conditions: []v32.CatalogCondition{ + { + Type: "Refreshed", + Status: "thisisnotanormalstatus", + Message: "Test Catalog Stuff", + }, + }, + }, + }, + projectCatalog: v3.ProjectCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ProjectName: "", + }, + + clusterCatalog: v3.ClusterCatalog{ + Namespaced: types.Namespaced{}, + Catalog: v3.Catalog{}, + ClusterName: "", + }, + }, + } + + for _, c := range testcases { + setCatalogErrorState(&c.catalogInfo, &c.catalog, &c.projectCatalog, &c.clusterCatalog) + assert.True(t, v32.CatalogConditionRefreshed.IsFalse(&c.catalog)) + assert.Equal(t, "Error syncing catalog testCatalog", v32.CatalogConditionRefreshed.GetMessage(&c.catalog)) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils.go new file mode 100644 index 0000000..758bf97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils.go @@ -0,0 +1,99 @@ +package utils + +import ( + "fmt" + "path/filepath" + + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" +) + +const ( + CatalogExternalIDFormat = "catalog://?catalog=%s&template=%s&version=%s" + SystemLibraryName = "system-library" +) + +// Config holds libcompose top level configuration +type Config struct { + Version string `yaml:"version,omitempty"` + Services RawServiceMap `yaml:"services,omitempty"` + Volumes map[string]interface{} `yaml:"volumes,omitempty"` + Networks map[string]interface{} `yaml:"networks,omitempty"` +} + +// RawService is represent a Service in map form unparsed +type RawService map[string]interface{} + +// RawServiceMap is a collection of RawServices +type RawServiceMap map[string]RawService + +// CreateConfig unmarshals bytes to config and creates config based on version +func CreateConfig(bytes []byte) (*Config, error) { + var config Config + if err := yaml.Unmarshal(bytes, &config); err != nil { + return nil, err + } + + if config.Version != "2" { + var baseRawServices RawServiceMap + if err := yaml.Unmarshal(bytes, &baseRawServices); err != nil { + return nil, err + } + config.Services = baseRawServices + } + + if config.Volumes == nil { + config.Volumes = make(map[string]interface{}) + } + if config.Networks == nil { + config.Networks = make(map[string]interface{}) + } + + return &config, nil +} + +// Convert converts a struct (src) to another one (target) using yaml marshalling/unmarshalling. +// If the structure are not compatible, this will throw an error as the unmarshalling will fail. +func Convert(src, target interface{}) error { + newBytes, err := yaml.Marshal(src) + if err != nil { + return err + } + + err = yaml.Unmarshal(newBytes, target) + if err != nil { + logrus.Errorf("Failed to unmarshall: %v\n%s", err, string(newBytes)) + } + return err +} + +func Contains(collection []string, key string) bool { + for _, value := range collection { + if value == key { + return true + } + } + + return false +} + +func GetCatalogImageCacheName(catalogName string) string { + return fmt.Sprintf("%s-catalog-image-list", catalogName) +} + +func GetCatalogChartPath(catalog *v3.Catalog, bundledMode bool) (string, error) { + if bundledMode { + switch catalog.Name { + case "helm3-library", "library", "system-library": + return filepath.Join(helmlib.InternalCatalog, catalog.Name), nil + case "rancher-charts", "rancher-partner-charts", "rancher-rke2-charts": + return filepath.Join(helmlib.InternalCatalog, "v2", catalog.Name), nil + default: + return "", fmt.Errorf("cannot find bundled catalog chart path for catalog %s", catalog.Name) + } + } + return filepath.Join(helmlib.CatalogCache, helmlib.CatalogSHA256Hash(catalog)), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils_test.go new file mode 100644 index 0000000..3d1cdaa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/utils_test.go @@ -0,0 +1,42 @@ +package utils + +import ( + "github.com/rancher/rancher/pkg/git" + "testing" +) + +func TestValidateURL(t *testing.T) { + tests := []struct { + name string + url string + wantErr bool + }{ + { + name: "works http", + url: "http://example.com/abc?d=ef", + wantErr: false, + }, + { + name: "works git", + url: "git://example.com/abc?d=ef", + wantErr: false, + }, + { + name: "cntrl error", + url: "http://example.com/ abc", + wantErr: true, + }, + { + name: "urlencode error", + url: "git://example.com%0D/abc", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := git.ValidateURL(tt.url); (err != nil) != tt.wantErr { + t.Errorf("ValidateURL() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version.go new file mode 100644 index 0000000..4e354d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version.go @@ -0,0 +1,66 @@ +package utils + +import ( + "strings" + + "github.com/blang/semver" + "github.com/rancher/rancher/pkg/catalog/utils/version" +) + +func VersionBetween(a, b, c string) bool { + if a == "" && c == "" { + return true + } else if a == "" { + return !VersionGreaterThan(b, c) + } else if b == "" { + return true + } else if c == "" { + return !VersionGreaterThan(a, b) + } + return !VersionGreaterThan(a, b) && !VersionGreaterThan(b, c) +} + +func formatVersion(v, rng string) (string, string) { + + v = strings.TrimLeft(v, "v") + + rng = strings.TrimLeft(rng, "v") + rng = strings.Replace(rng, ">v", ">", -1) + rng = strings.Replace(rng, ">=v", ">=", -1) + rng = strings.Replace(rng, " len(aSplit) { + return !GreaterThan(b, a) && a != b + } + + for i := 0; i < len(aSplit); i++ { + if i == len(bSplit) { + if _, err := strconv.Atoi(aSplit[i]); err == nil { + return true + } + return false + } + aWord := wordRe.FindString(aSplit[i]) + bWord := wordRe.FindString(bSplit[i]) + if aWord != "" && bWord != "" { + if strings.Compare(aWord, bWord) > 0 { + return true + } + if strings.Compare(bWord, aWord) > 0 { + return false + } + } + aMatch := numberRe.FindString(aSplit[i]) + bMatch := numberRe.FindString(bSplit[i]) + if aMatch == "" || bMatch == "" { + if strings.Compare(aSplit[i], bSplit[i]) > 0 { + return true + } + if strings.Compare(bSplit[i], aSplit[i]) > 0 { + return false + } + } + aNum, _ := strconv.Atoi(aMatch) + bNum, _ := strconv.Atoi(bMatch) + if aNum > bNum { + return true + } + if bNum > aNum { + return false + } + } + + return false +} + +func stripMetadata(v string) string { + split := strings.Split(v, "+") + if len(split) > 1 { + return split[0] + } + return v +} + +func periodDashSplit(s string) []string { + return strings.FieldsFunc(s, func(r rune) bool { + switch r { + case '.', '-': + return true + } + return false + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version/version_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version/version_test.go new file mode 100644 index 0000000..e21d529 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version/version_test.go @@ -0,0 +1,74 @@ +package version + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func testAscending(t *testing.T, versions []string) { + for i, version := range versions { + for j := i; j < len(versions); j++ { + if j != i { + assert.True(t, GreaterThan(versions[j], version)) + assert.False(t, GreaterThan(version, versions[j])) + } + } + } +} + +func TestGreaterThan(t *testing.T) { + testAscending(t, []string{ + "v1.2.0", + "v1.2.1", + "v1.2.3", + "v1.3.0", + "v1.3.4", + "v2.0.0", + }) + + testAscending(t, []string{ + "v0.1.0-rancher0", + "v0.1.0-rancher1", + "v0.1.0-rancher1.1", + "v1.2.4-rancher6", + "v1.2.4-rancher6.1", + "v1.2.4-rancher7", + "v1.2.4-rancher7.2", + "v1.2.4-rancher7.3", + "v1.2.4-rancher9.0", + "v1.2.4-rancher10.10", + "v1.2.4-rancher12.0", + "v1.2.4-rancher12.5", + "v1.2.4-rancher14", + "v1.2.4-rancher15.10", + "v1.3.0-rancher3", + "v1.3.0-rancher4", + }) + + testAscending(t, []string{ + "0.0.1", + "v0.45.0", + }) + + testAscending(t, []string{ + "0.0.1-a", + "0.0.1-b", + "0.0.1-c", + }) + + testAscending(t, []string{ + "0.0.1-pre1-alpha2", + "0.0.1-pre1-alpha3", + "0.0.1-pre1-beta1", + "0.0.1-pre1-beta2.2", + "0.0.1-pre1-beta11", + "0.0.1-pre1-rc1", + "0.0.1-pre1-rc1-1", + "0.0.1-pre1", + "0.0.1", + }) + + assert.False(t, GreaterThan("v1.0.0+test", "v1.0.0")) + assert.False(t, GreaterThan("v1.0.0", "v1.0.0+test")) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version_test.go new file mode 100644 index 0000000..21d78f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalog/utils/version_test.go @@ -0,0 +1,131 @@ +package utils + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestVersionBetween(t *testing.T) { + assert.True(t, VersionBetween("1", "2", "3")) + assert.True(t, VersionBetween("1", "2", "")) + assert.True(t, VersionBetween("", "2", "3")) + assert.True(t, VersionBetween("", "2", "")) + assert.True(t, VersionBetween("1", "", "")) + assert.True(t, VersionBetween("", "", "3")) + assert.True(t, VersionBetween("1", "", "3")) + + assert.True(t, VersionBetween("2", "2", "2")) + assert.True(t, VersionBetween("2", "2", "")) + assert.True(t, VersionBetween("", "2", "2")) +} + +func testVersionSatifiesRange(t *testing.T, v, rng string) { + satisfiesRange, err := VersionSatisfiesRange(v, rng) + assert.Nil(t, err) + assert.True(t, satisfiesRange) +} + +func testNotVersionSatifiesRange(t *testing.T, v, rng string) { + satisfiesRange, err := VersionSatisfiesRange(v, rng) + assert.Nil(t, err) + assert.False(t, satisfiesRange) +} + +func testInvalidVersion(t *testing.T, v, rng string) { + satisfiesRange, _ := VersionSatisfiesRange(v, rng) + assert.False(t, satisfiesRange) +} + +func TestVersionSatifiesRange(t *testing.T) { + testVersionSatifiesRange(t, "v1.0.0", "=1.0.0") + testVersionSatifiesRange(t, "1.0.0", "!2.0.0") + testVersionSatifiesRange(t, "v1.0.2", ">1.0.1 <1.0.3") + testVersionSatifiesRange(t, "1.0.0", "<1.0.1 || >1.0.3") + testVersionSatifiesRange(t, "v1.0.4", "<1.0.1 || >1.0.3") + testVersionSatifiesRange(t, "v1.0.0", "=v1.0.0") + testVersionSatifiesRange(t, "1.0.0", "!v2.0.0") + testVersionSatifiesRange(t, "v1.0.2", ">v1.0.1 v1.0.3") + testVersionSatifiesRange(t, "v1.0.4", "v1.0.3") + + testVersionSatifiesRange(t, "v1.0.0-rancher11", "=1.0.0-rancher11") + testVersionSatifiesRange(t, "1.0.0-rancher11", "!1.0.0-rancher12") + testVersionSatifiesRange(t, "v1.0.0-rancher2", ">1.0.0-rancher1 <1.0.0-rancher3") + testVersionSatifiesRange(t, "1.0.0-rancher1", "<1.0.0-rancher2 || >1.0.0-rancher4") + testVersionSatifiesRange(t, "v1.0.0-rancher5", "<1.0.0-rancher2 || >1.0.0-rancher4") + testVersionSatifiesRange(t, "v1.0.0-rancher11", "=v1.0.0-rancher11") + testVersionSatifiesRange(t, "1.0.0-rancher11", "!v1.0.0-rancher12") + testVersionSatifiesRange(t, "v1.0.0-rancher2", ">v1.0.0-rancher1 v1.0.0-rancher4") + testVersionSatifiesRange(t, "v1.0.0-rancher5", "v1.0.0-rancher4") + + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher11", "=1.0.0-pre1-rancher11") + testVersionSatifiesRange(t, "1.0.0-pre1-rancher11", "!1.0.0-pre1-rancher12") + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher2", ">1.0.0-pre1-rancher1 <1.0.0-pre1-rancher3") + testVersionSatifiesRange(t, "1.0.0-pre1-rancher1", "<1.0.0-pre1-rancher2 || >1.0.0-pre1-rancher4") + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher5", "<1.0.0-pre1-rancher2 || >1.0.0-pre1-rancher4") + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher11", "=v1.0.0-pre1-rancher11") + testVersionSatifiesRange(t, "1.0.0-pre1-rancher11", "!v1.0.0-pre1-rancher12") + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher2", ">v1.0.0-pre1-rancher1 v1.0.0-pre1-rancher4") + testVersionSatifiesRange(t, "v1.0.0-pre1-rancher5", "v1.0.0-pre1-rancher4") + + testVersionSatifiesRange(t, "v1.0.0-pre11-rancher1", "=1.0.0-pre11-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre11-rancher1", "!1.0.0-pre12-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">1.0.0-pre1-rancher1 <1.0.0-pre3-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre1-rancher1", "<1.0.0-pre2-rancher1 || >1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre5-rancher1", "<1.0.0-pre2-rancher1 || >1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre11-rancher1", "=v1.0.0-pre11-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre11-rancher1", "!v1.0.0-pre12-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">v1.0.0-pre1-rancher1 v1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre5-rancher1", "v1.0.0-pre4-rancher1") + + testVersionSatifiesRange(t, "v1.0.0-pre11-rancher1", "=1.0.0-pre11-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre11-rancher1", "!1.0.0-pre12-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">1.0.0-pre1-rancher1 <1.0.0-pre3-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre1-rancher1", "<1.0.0-pre2-rancher1 || >1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre5-rancher1", "<1.0.0-pre2-rancher1 || >1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre11-rancher1", "=v1.0.0-pre11-rancher1") + testVersionSatifiesRange(t, "1.0.0-pre11-rancher1", "!v1.0.0-pre12-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">v1.0.0-pre1-rancher1 v1.0.0-pre4-rancher1") + testVersionSatifiesRange(t, "v1.0.0-pre5-rancher1", "v1.0.0-pre4-rancher1") + + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">1.0.0-pre1-rancher2") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", "<1.0.0") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", ">v1.0.0-pre1-rancher2") + testVersionSatifiesRange(t, "v1.0.0-pre2-rancher1", "1.0.0-rancher1 <1.0.0-rancher3") + testNotVersionSatifiesRange(t, "1.0.0-rancher3", "<1.0.0-rancher2 || >1.0.0-rancher4") + testNotVersionSatifiesRange(t, "v1.0.0-rancher12", "=v1.0.0-rancher11") + testNotVersionSatifiesRange(t, "1.0.0-rancher12", "!v1.0.0-rancher12") + testNotVersionSatifiesRange(t, "v1.0.0-rancher5", ">v1.0.0-rancher1 v1.0.0-rancher4") + + testInvalidVersion(t, "versionInvalid-1.0", "versionInvalid-1.0") + testInvalidVersion(t, "versionInvalid-1.0", "=versionInvalid-1.0") + testInvalidVersion(t, "versionInvalid-1.0", "versionInvalid-1.0") + testInvalidVersion(t, "versionInvalid-1.0", ">=versionInvalid-1.0") + + testInvalidVersion(t, "v1.0.0-validVersion", "versionInvalid-1.0") + testInvalidVersion(t, "v1.0.0-validVersion", "=versionInvalid-1.0") + testInvalidVersion(t, "v1.0.0-validVersion", ">versionInvalid-1.0") + testInvalidVersion(t, "v1.0.0-validVersion", ">=versionInvalid-1.0") + testInvalidVersion(t, "v1.0.0-validVersion", "v1.0.0-validVersion") + testInvalidVersion(t, "versionInvalid-1.0", ">=v1.0.0-validVersion") + testInvalidVersion(t, "versionInvalid-1.0", "= <`style comparison", + ">= 2.5.0-alpha3 <2.6.0", + "v2.5.0+123", + true, + }, + { + "rancher version in range comparison with `> <`style comparison", + ">2.5.0 <2.6.0", + "v2.5.7", + true, + }, + { + "rancher version in range comparison with `> <=`style comparison", + ">2.5.0-rc1 <=2.6.0-0", + "v2.5.0-rc2", //SemVer comparisons using constraints with prerelease will be evaluated using an ASCII sort order, per the spec + true, + }, + { + "rancher version in range comparison with `>= <=`style comparison", + ">=2.5.0-alpha2 <=2.6.0", + "v2.5.0", //Pre-release versions would be skipped with this comparison + true, + }, + { + "rancher version in range comparison with `~` style comparison", + "~2.5.x", //equivalent to ">= 2.5.0 < 2.6.0" + "v2.5.7", + true, + }, + { + "rancher version in range comparison with `<` style comparison", + "<2.6.001", + "v2.6.000", + true, + }, + { + "rancher version in range comparison with `<=` style comparison", + "<=2.5.8-rc7", + "v2.5.8-rc2+123", //SemVer comparisons using constraints with prerelease will be evaluated using an ASCII sort order, per the spec + true, + }, + { + "rancher version in range comparison with `>=` style comparison", + ">= 2.4.3-r8", + "v2.4.3-r9", + true, + }, + { + "rancher version in range comparison with `>` style comparison", + ">2.4.3", + "v2.4.4", + true, + }, + { + "rancher version in range comparison with `-` style comparison", + "2.5 - 2.6.3", //equivalent to ">= 2.5 <= 2.6.3" + "v2.5.9", + true, + }, + { + "rancher version in range comparison with `^` style comparison", + "^2.7.5", //equivalent to ">= 2.7.5, < 2.8.0" + "v2.7.8", + true, + }, + { + "rancher version out of range comparison with `>= <`style comparison", + ">= 2.5.0-alpha3 <2.6.0-0", + "v2.5.0-alpha2", //SemVer comparisons using constraints with prerelease will be evaluated using an ASCII sort order, per the spec + false, + }, + { + "rancher prerelease version in range comparison with `>= <`style comparison", + ">= 2.5.0-alpha3 <2.6.0-0", + "v2.5.0-alpha4", //SemVer comparisons using constraints with prerelease will be evaluated using an ASCII sort order, per the spec + true, + }, + { + "rancher version out of range comparison with `> <`style comparison", + ">2.5.0 <2.6.0", + "v2.5.3-alpha3", + true, + }, + { + "rancher version out of range comparison with `> <=`style comparison", + "> 2.5.0-alpha <=2.6.0", + "v2.5.1-alpha", + true, + }, + { + "rancher version out of range comparison with `>= <=`style comparison", + ">=2.5.0-rc1 <=2.6.0", + "v2.4.2", //Pre-release versions would be skipped with this comparison + false, + }, + { + "rancher version out of range comparison with `~` style comparison", + "~2.5.040", //equivalent to >= 2.5.0, < 2.6.0 + "v2.5.039", + false, + }, + { + "rancher version out of range comparison with `<` style comparison", + "<2.6.0-alpha", + "v2.7.3", + false, + }, + { + "rancher version out of range comparison with `<=` style comparison", + "<=2.6.0", + "v2.6.1", + false, + }, + { + "rancher version out of range comparison with `>=` style comparison", + ">= 2.4.3", + "v2.4.2-alpha1", + false, + }, + { + "rancher version out of range comparison with `>` style comparison", + ">2.4.3", + "v2.4.3", + false, + }, + { + "rancher version out range comparison with `-` style comparison", + "2.5 - 2.6.3", //equivalent to ">= 2.5 <= 2.6.3" + "v2.4.9", + false, + }, + { + "rancher version out range comparison with `^` style comparison", + "^2.7.x", //equivalent to ">= 2.7.0 < 3.0.0" + "v3.0.0", + false, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + indexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + }, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + filteredIndexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + }, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + contentManager := Manager{} + settings.ServerVersion.Set(tt.rancherVersion) + contentManager.filterReleases(&filteredIndexFile, nil, false) + result := reflect.DeepEqual(indexFile, filteredIndexFile) + assert.Equal(t, tt.expectedPass, result) + if result != tt.expectedPass { + t.Logf("Expected %v, got %v for %s with rancher version %s", tt.expectedPass, result, tt.chartVersionAnnotation, tt.rancherVersion) + } + }) + } +} + +func TestFilteringReleases(t *testing.T) { + tests := []struct { + testName string + chartVersionAnnotation string + rancherVersion string + kubernetesVersionAnnotation string + kubernetesVersion string + skipFiltering bool + expectedPass bool + }{ + { + "Index with chart that has no filters and skips filtering", + "", + "", + "", + "", + true, + true, + }, + { + "Index with chart that has rancher-version annotation filter and skips filtering", + ">= 2.5.0-alpha3 <2.6.0", + "v2.5.0+123", + "", + "v1.21.0", + true, + true, + }, + { + "Index with chart that has kubernetes version filter and skips filtering", + "", + "v2.5.7", + "v1.20.0", + "v1.21.0", + true, + true, + }, + { + "Index with chart that has kubernetes version and rancher-version annotation filter and skips filtering", + ">2.5.0-rc1 <=2.6.0-0", + "v2.5.0-rc2", + "v1.20.0", + "v1.21.0", + true, + true, + }, + { + "Index with chart that has no filters and applies filters", + "", + "", + "", + "", + false, + true, + }, + { + "Index with chart that has rancher-version annotation filter and applies filtering", + ">= 2.5.0-alpha3 <2.6.0", + "v2.5.0+123", + "", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kubernetes version filter and applies filtering", + "", + "v2.5.7", + "v1.20.0", + "v1.21.0", + false, + false, + }, + { + "Index with chart that has kubernetes version and rancher-version annotation filter and applies filtering", + ">2.5.0-rc1 <=2.6.0-0", + "v2.5.0-rc2", + "v1.20.0", + "v1.21.0", + false, + false, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + indexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + }, + KubeVersion: tt.kubernetesVersionAnnotation, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + filteredIndexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + }, + KubeVersion: tt.kubernetesVersionAnnotation, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + contentManager := Manager{} + settings.ServerVersion.Set(tt.rancherVersion) + kubeVersion, _ := semver.NewVersion(tt.kubernetesVersion) + contentManager.filterReleases(&filteredIndexFile, kubeVersion, tt.skipFiltering) + result := reflect.DeepEqual(indexFile, filteredIndexFile) + assert.Equal(t, tt.expectedPass, result) + if result != tt.expectedPass { + t.Logf("Expected %v, got %v for %s with rancher version %s", tt.expectedPass, result, tt.chartVersionAnnotation, tt.rancherVersion) + } + }) + } +} +func TestFilteringReleaseKubeVersionAnnotation(t *testing.T) { + tests := []struct { + testName string + chartVersionAnnotation string + rancherVersion string + ChartKubeVersionAnnotation string + kubernetesVersion string + skipFiltering bool + expectedPass bool + }{ + { + "Index with chart that has no filters and skips filtering", + "", + "", + "", + "", + true, + true, + }, + { + "Index with chart that has kube-version annotation filter and skips filtering", + "", + "v2.5.0+123", + "1.18 - 1.20", + "v1.21.0", + true, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 1", + "", + "v2.5.0+123", + "1.18 - 1.20", + "v1.21.0", + false, + false, + }, + { + "Index with chart that has kube-version annotation filter - case 2", + "", + "v2.5.0+123", + "1.18 - 1.21", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 3", + "", + "v2.5.0+123", + " = 1.20", + "v1.21.0", + false, + false, + }, + { + "Index with chart that has kube-version annotation filter - case 4", + "", + "v2.5.0+123", + " = 1.21.1", + "v1.21.0", + false, + false, + }, + { + "Index with chart that has kube-version annotation filter - case 5", + "", + "v2.5.0+123", + " >= 1.21", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 6", + "", + "v2.5.0+123", + " <= 1.22", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 7", + "", + "v2.5.0+123", + " < 1.22.0-0", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 7", + "", + "v2.5.0+123", + ">= 1.19, <= 1.21", + "v1.21.0", + false, + true, + }, + { + "Index with chart that has kube-version annotation filter - case 8", + "", + "v2.5.0+123", + " >= 1.19, <= 1.20", + "v1.21.0", + false, + false, + }, + { + "Index with chart that has kube-version annotation filter - case 9", + "", + "v2.5.0+123", + " >= 1.19.0-0 < 1.22.0", + "v1.21.0", + false, + true, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + indexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + "catalog.cattle.io/kube-version": tt.ChartKubeVersionAnnotation, + }, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + filteredIndexFile := repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": { + { + Metadata: &chart.Metadata{ + Name: "test-chart", + Version: "1.0.0", + Annotations: map[string]string{ + "catalog.cattle.io/rancher-version": tt.chartVersionAnnotation, + "catalog.cattle.io/kube-version": tt.ChartKubeVersionAnnotation, + }, + }, + URLs: nil, + Created: time.Time{}, + Removed: false, + Digest: "", + }, + }, + }, + } + contentManager := Manager{} + settings.ServerVersion.Set(tt.rancherVersion) + kubeVersion, _ := semver.NewVersion(tt.kubernetesVersion) + contentManager.filterReleases(&filteredIndexFile, kubeVersion, tt.skipFiltering) + result := reflect.DeepEqual(indexFile, filteredIndexFile) + assert.Equal(t, tt.expectedPass, result) + if result != tt.expectedPass { + t.Logf("Expected %v, got %v for %s with chart kubeVersion annotation %s", tt.expectedPass, result, kubeVersion, tt.ChartKubeVersionAnnotation) + } + }) + } +} + +func TestAirgappedAndBundledIcons(t *testing.T) { + // TODO: This test is not complete, it needs to be updated after issue #43958 is resolved + // by adding a check for repo.spec.GitRepo + changeDefaultRepo := func(name, namespace string) *repoDef { + repo := repoDef{ + typedata: &metav1.TypeMeta{ + Kind: "ClusterRepo", + APIVersion: "catalog.cattle.io/v1", + }, + metadata: &metav1.ObjectMeta{ + Name: "rancher-charts", + }, + spec: &v1.RepoSpec{ + GitRepo: "https://git.rancher.io/charts", + GitBranch: "master", + }, + status: &v1.RepoStatus{ + URL: "https://git.rancher.io/charts", + Branch: "main", + IndexConfigMapNamespace: "cattle-system", + Commit: "8ecc234c3b2cf1adfeeb36f33ee4679c8c44fd4c", + }, + } + if name != "" { + repo.metadata.Name = name + } + if namespace != "" { + repo.metadata.Namespace = namespace + } + return &repo + } + + testCases := []struct { + // input + test string + repo *repoDef + settingSystemCatalog string + // output + expectedResult bool + }{ + {test: "#1.0: pass bundled-mode", repo: changeDefaultRepo("", ""), settingSystemCatalog: "bundled", expectedResult: true}, + {test: "#1.1: pass bundled-mode", repo: changeDefaultRepo("rancher-partner-charts", ""), settingSystemCatalog: "bundled", expectedResult: true}, + {test: "#1.2: pass bundled-mode", repo: changeDefaultRepo("rancher-rke2-charts", ""), settingSystemCatalog: "bundled", expectedResult: true}, + {test: "#1.3: block bundled-mode", repo: changeDefaultRepo("", "some-namespace"), settingSystemCatalog: "bundled", expectedResult: false}, + {test: "#1.4: block bundled-mode", repo: changeDefaultRepo("not-any-rancher-charts", ""), settingSystemCatalog: "bundled", expectedResult: false}, + {test: "#2.0: block external-mode", repo: changeDefaultRepo("not-any-rancher-charts", ""), settingSystemCatalog: "external", expectedResult: false}, + {test: "#2.1: block external-mode", repo: changeDefaultRepo("rancher-charts", ""), settingSystemCatalog: "external", expectedResult: false}, + } + + assert := assert.New(t) + for _, tc := range testCases { + settings.SystemCatalog.Set(tc.settingSystemCatalog) + var dir string + // Rancher does not allow to change the name of the official rancher charts(charts, partner, rke2) + if tc.repo.metadata.Name == "rancher-charts" || + tc.repo.metadata.Name == "rancher-partner-charts" || + tc.repo.metadata.Name == "rancher-rke2-charts" { + + dir = fmt.Sprintf("../rancher-data/local-catalogs/v2/%s/%s", tc.repo.metadata.Name, git.Hash(tc.repo.spec.GitRepo)) + err := createDir(dir) + assert.Nil(err, tc.test) + defer deleteDir(dir) + } + result := isRancherAndBundledCatalog(*tc.repo) + assert.Equal(tc.expectedResult, result, tc.test) + } + + deleteDir("../rancher-data") +} + +func createDir(dir string) error { + err := os.MkdirAll(dir, 0755) + if err != nil { + fmt.Println("Error:", err) + return err + } + return nil +} + +func deleteDir(dir string) error { + err := os.RemoveAll(dir) + if err != nil { + fmt.Println("Error:", err) + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/content/translate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/content/translate.go new file mode 100644 index 0000000..7a1e8b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/content/translate.go @@ -0,0 +1,46 @@ +package content + +import ( + "net/url" + + "helm.sh/helm/v3/pkg/repo" +) + +// TranslateURLs - creates URLs that are unique to each version of a chart, +// that contain the chart name, version, and link type as query parameters, making easier to identify +// and download specific version of charts when web browsing. +// +// This is achieved by iterating through each entry of each Helm chart, concatenating, and encoding the information into the URL. +// The base URL will be the one that Rancher is available at. +// +// Parameters: +// - baseURL: The base URL to use as the prefix for all chart and icon URLs in the index file. +// - index: The index file to modify. This should be a parsed JSON object that contains information +// about the charts and their versions. +// +// Returns: +// - An error if there was a problem modifying the URLs in the index file +// - nil if the operation was successful. +func TranslateURLs(baseURL *url.URL, index *repo.IndexFile) error { + u := *baseURL + for chartName, versions := range index.Entries { + for _, version := range versions { + v := url.Values{} + v.Set("chartName", chartName) + v.Set("version", version.Version) + v.Set("link", "chart") + u.RawQuery = v.Encode() + version.URLs = []string{ + u.String(), + } + + v.Set("link", "icon") + if version.Metadata != nil && version.Icon != "" { + u.RawQuery = v.Encode() + version.Icon = u.String() + } + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/content.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/content.go new file mode 100644 index 0000000..a27ad62 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/content.go @@ -0,0 +1,72 @@ +package git + +import ( + "fmt" + "io" + "os" + "path" + "path/filepath" + "strings" + + "github.com/rancher/rancher/pkg/catalogv2/chart" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "helm.sh/helm/v3/pkg/repo" +) + +// Icon will return the icon for a chartName version in a local repository by getting the relative path +func Icon(namespace, name, gitURL string, chartVersion *repo.ChartVersion) (io.ReadCloser, string, error) { + if len(chartVersion.Icon) == 0 { + return nil, "", fmt.Errorf("failed to find chartName %s version %s: %w", chartVersion.Name, chartVersion.Version, validation.NotFound) + } + + dir := RepoDir(namespace, name, gitURL) + icon := chartVersion.Icon + + file, err := relative(dir, gitURL, icon) + if err != nil { + return nil, "", err + } + + f, err := os.Open(file) + return f, path.Ext(file), err +} + +func Chart(namespace, name, gitURL string, chartVersion *repo.ChartVersion) (io.ReadCloser, error) { + dir := RepoDir(namespace, name, gitURL) + + if len(chartVersion.URLs) == 0 { + return nil, fmt.Errorf("failed to find chartName %s version %s: %w", chartVersion.Name, chartVersion.Version, validation.NotFound) + } + + file, err := relative(dir, gitURL, chartVersion.URLs[0]) + if err != nil { + return nil, err + } + + archive, ok, err := chart.LoadArchive(file) + if err != nil { + return nil, err + } else if !ok { + return nil, fmt.Errorf("failed to find chartName %s version %s: %w", chartVersion.Name, chartVersion.Version, validation.NotFound) + } + + return archive.Open() +} + +func relative(base, publicURL, path string) (string, error) { + if strings.HasPrefix(path, publicURL) { + path = path[len(publicURL):] + } + path = strings.TrimPrefix(path, "file://") + + baseAbs, err := filepath.Abs(base) + if err != nil { + return "", err + } + fullAbs, err := filepath.Abs(filepath.Join(base, path)) + if err != nil { + return "", err + } + _, err = filepath.Rel(baseAbs, fullAbs) + return fullAbs, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download.go new file mode 100644 index 0000000..5c84ed1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download.go @@ -0,0 +1,108 @@ +package git + +import ( + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/settings" + corev1 "k8s.io/api/core/v1" +) + +// Ensure runs git clone, clean DIRTY contents and fetch the latest commit +func Ensure(secret *corev1.Secret, namespace, name, gitURL, commit string, insecureSkipTLS bool, caBundle []byte) error { + git, err := gitForRepo(secret, namespace, name, gitURL, insecureSkipTLS, caBundle) + if err != nil { + return fmt.Errorf("ensure failure: %w", err) + } + + // If the repositories are rancher managed and if bundled is set + // don't fetch anything from upstream. + if IsBundled(git.Directory) && settings.SystemCatalog.Get() == "bundled" { + return nil + } + + if err := git.clone(""); err != nil { + return fmt.Errorf("ensure failure: %w", err) + } + + if err := git.reset(commit); err == nil { + return nil + } + + if err := git.fetchAndReset(commit); err != nil { + return fmt.Errorf("ensure failure: %w", err) + } + return nil +} + +// Head runs git clone on directory(if not exist), reset dirty content and return the HEAD commit +func Head(secret *corev1.Secret, namespace, name, gitURL, branch string, insecureSkipTLS bool, caBundle []byte) (string, error) { + git, err := gitForRepo(secret, namespace, name, gitURL, insecureSkipTLS, caBundle) + if err != nil { + return "", fmt.Errorf("head failure: %w", err) + } + + if err := git.clone(branch); err != nil { + return "", fmt.Errorf("head failure: %w", err) + } + + if err := git.reset("HEAD"); err != nil { + return "", fmt.Errorf("head failure: %w", err) + } + + commit, err := git.currentCommit() + if err != nil { + return "", fmt.Errorf("head failure: %w", err) + } + + return commit, nil +} + +// Update updates git repo if remote sha has changed. It also skips the update if in bundled mode and the git dir has a certain prefix stateDir(utils.go). +// If there is an error updating the repo especially stateDir(utils.go) repositories, it ignores the error and returns the current commit in the local pod directory. +// except when the error is `branch not found`. It specifically checks for `couldn't find remote ref` & `Could not find remote branch` in the error message. +func Update(secret *corev1.Secret, namespace, name, gitURL, branch string, insecureSkipTLS bool, caBundle []byte) (string, error) { + git, err := gitForRepo(secret, namespace, name, gitURL, insecureSkipTLS, caBundle) + if err != nil { + return "", fmt.Errorf("update failure: %w", err) + } + if IsBundled(git.Directory) && settings.SystemCatalog.Get() == "bundled" { + return Head(secret, namespace, name, gitURL, branch, insecureSkipTLS, caBundle) + } + + commit, err := git.Update(branch) + if err != nil && IsBundled(git.Directory) { + // We don't report an error unless the branch is invalid + // The reason being it would break airgap environments in downstream + // cluster. A new issue is created to tackle this in the forthcoming. + if strings.Contains(err.Error(), "couldn't find remote ref") || strings.Contains(err.Error(), "Could not find remote branch") { + return "", err + } + return Head(secret, namespace, name, gitURL, branch, insecureSkipTLS, caBundle) + } + return commit, err +} + +func gitForRepo(secret *corev1.Secret, namespace, name, gitURL string, insecureSkipTLS bool, caBundle []byte) (*git, error) { + err := validateURL(gitURL) + if err != nil { + return nil, fmt.Errorf("%w: only http(s) or ssh:// supported", err) + } + + dir := RepoDir(namespace, name, gitURL) + headers := map[string]string{} + if settings.InstallUUID.Get() != "" { + headers["X-Install-Uuid"] = settings.InstallUUID.Get() + } + // convert caBundle to PEM format because git requires correct line breaks, header and footer. + if len(caBundle) > 0 { + caBundle = convertDERToPEM(caBundle) + insecureSkipTLS = false + } + return newGit(dir, gitURL, &Options{ + Credential: secret, + Headers: headers, + InsecureTLSVerify: insecureSkipTLS, + CABundle: caBundle, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download_test.go new file mode 100644 index 0000000..0eb4cd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/download_test.go @@ -0,0 +1,195 @@ +package git + +import ( + "fmt" + "os" + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +const chartsSmallForkURL = "https://github.com/rancher/charts-small-fork" +const mainBranch = "main" +const lastBranch = "test-1" + +func TestMain(m *testing.M) { + // Run all the tests + exitCode := m.Run() + + // Cleanup after tests + cleanup() + + // Exit with the proper code + os.Exit(exitCode) +} + +func cleanup() { + // Delete the management-state directory + os.RemoveAll("management-state") +} + +func Test_Ensure(t *testing.T) { + testCases := []struct { + test string + secret *corev1.Secret + namespace string + name string + gitURL string + commit string + insecureSkipTLS bool + caBundle []byte + branch string + expectedError error + }{ + { + test: "#1 TestCase: Success - Clone, Reset And Exit", + secret: nil, + namespace: "cattle-test", + name: "small-fork-test", + gitURL: chartsSmallForkURL, + commit: "0e2b9da9ddde5c1e502bba6474119856496e5026", + insecureSkipTLS: false, + caBundle: []byte{}, + branch: mainBranch, + expectedError: nil, + }, + { + test: "#2 TestCase: Success - Clone, Reset And Fetch Last Branch", + secret: nil, + namespace: "cattle-test", + name: "small-fork-test", + gitURL: chartsSmallForkURL, + commit: "0e2b9da9ddde5c1e502bba6474119856496e5026", + insecureSkipTLS: false, + caBundle: []byte{}, + branch: lastBranch, + expectedError: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := Ensure(tc.secret, tc.namespace, tc.name, tc.gitURL, tc.commit, tc.insecureSkipTLS, tc.caBundle) + // Check the error + if tc.expectedError == nil && tc.expectedError != err { + t.Errorf("Expected error: %v |But got: %v", tc.expectedError, err) + } + + // Check the error + if tc.expectedError == nil && tc.expectedError != err { + t.Errorf("Expected error: %v |But got: %v", tc.expectedError, err) + } + // Only testing error in some cases + if err != nil { + assert.EqualError(t, tc.expectedError, err.Error()) + } + }) + } +} + +func Test_Head(t *testing.T) { + testCases := []struct { + test string + secret *corev1.Secret + namespace string + name string + gitURL string + insecureSkipTLS bool + caBundle []byte + branch string + expectedCommit string + expectedError error + }{ + { + test: "#1 TestCase: Success - Clone, Reset And Return Commit", + secret: nil, + namespace: "cattle-test", + name: "small-fork-test", + gitURL: chartsSmallForkURL, + insecureSkipTLS: false, + caBundle: []byte{}, + branch: mainBranch, + expectedCommit: "226d544def39de56db210e96d2b0b535badf9bdd", + expectedError: nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + commit, err := Head(tc.secret, tc.namespace, tc.name, tc.gitURL, tc.branch, tc.insecureSkipTLS, tc.caBundle) + // Check the error + if tc.expectedError == nil && tc.expectedError != err { + t.Errorf("Expected error: %v |But got: %v", tc.expectedError, err) + } + // Only testing error in some cases + if err != nil { + assert.EqualError(t, tc.expectedError, err.Error()) + } + + assert.Equal(t, len(commit), len(tc.expectedCommit)) + }) + } +} + +func Test_Update(t *testing.T) { + testCases := []struct { + test string + secret *corev1.Secret + namespace string + name string + gitURL string + insecureSkipTLS bool + caBundle []byte + branch string + systemCatalogMode string + expectedCommit string + expectedError string + dir string + }{ + { + test: "#1 TestCase: Success ", + secret: nil, + namespace: "cattle-test", + name: "small-fork-test", + gitURL: chartsSmallForkURL, + insecureSkipTLS: false, + caBundle: []byte{}, + branch: lastBranch, + systemCatalogMode: "", + expectedCommit: "226d544def39de56db210e96d2b0b535badf9bdd", + expectedError: "", + }, + { + test: "Returns an error if invalid branch is specified", + secret: nil, + namespace: "cattle-test", + name: "small-fork-test", + gitURL: chartsSmallForkURL, + insecureSkipTLS: false, + caBundle: []byte{}, + branch: "invalidbranch", + systemCatalogMode: "", + expectedCommit: "226d544def39de56db210e96d2b0b535badf9bdd", + expectedError: "Could not find remote branch", + dir: fmt.Sprintf("%s/%s", localDir, "cattle-test/small-fork-test/d39a2f6abd49e537e5015bbe1a4cd4f14919ba1c3353208a7ff6be37ffe00c52"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.dir != "" { + err := os.MkdirAll(tc.dir, 0755) + assert.NoError(t, err) + } + + commit, err := Update(tc.secret, tc.namespace, tc.name, tc.gitURL, tc.branch, tc.insecureSkipTLS, tc.caBundle) + if tc.expectedError != "" { + assert.Contains(t, err.Error(), tc.expectedError) + } else { + assert.NoError(t, err) + assert.Equal(t, len(commit), len(tc.expectedCommit)) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/git.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/git.go new file mode 100644 index 0000000..434d3ce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/git.go @@ -0,0 +1,379 @@ +package git + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "net" + "net/http" + "net/url" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" + "golang.org/x/crypto/ssh/agent" + corev1 "k8s.io/api/core/v1" + k8snet "k8s.io/apimachinery/pkg/util/net" +) + +type Options struct { + Credential *corev1.Secret + CABundle []byte + InsecureTLSVerify bool + Headers map[string]string +} + +type git struct { + URL string + Directory string + password string + agent *agent.Agent + caBundle []byte + insecureTLSVerify bool + secret *corev1.Secret + headers map[string]string + knownHosts []byte +} + +func newGit(directory, url string, opts *Options) (*git, error) { + if opts == nil { + opts = &Options{} + } + + g := &git{ + URL: url, + Directory: directory, + caBundle: opts.CABundle, + insecureTLSVerify: opts.InsecureTLSVerify, + secret: opts.Credential, + headers: opts.Headers, + } + return g, g.setCredential(opts.Credential) +} + +func (g *git) setCredential(cred *corev1.Secret) error { + if cred == nil { + return nil + } + + switch cred.Type { + case corev1.SecretTypeBasicAuth: + username, password := cred.Data[corev1.BasicAuthUsernameKey], cred.Data[corev1.BasicAuthPasswordKey] + if len(password) == 0 && len(username) == 0 { + return nil + } + + u, err := url.Parse(g.URL) + if err != nil { + return err + } + u.User = url.User(string(username)) + g.URL = u.String() + g.password = string(password) + case corev1.SecretTypeSSHAuth: + key, err := ssh.ParseRawPrivateKey(cred.Data[corev1.SSHAuthPrivateKey]) + if err != nil { + return err + } + sshAgent := agent.NewKeyring() + err = sshAgent.Add(agent.AddedKey{ + PrivateKey: key, + }) + if err != nil { + return err + } + g.knownHosts = cred.Data["known_hosts"] + g.agent = &sshAgent + } + + return nil +} + +func (g *git) injectAgent(cmd *exec.Cmd) (io.Closer, error) { + r, err := randomtoken.Generate() + if err != nil { + return nil, err + } + + tmpDir, err := os.MkdirTemp("", "ssh-agent") + if err != nil { + return nil, err + } + + addr := &net.UnixAddr{ + Name: filepath.Join(tmpDir, r), + Net: "unix", + } + + l, err := net.ListenUnix(addr.Net, addr) + if err != nil { + return nil, err + } + + cmd.Env = append(cmd.Env, "SSH_AUTH_SOCK="+addr.Name) + + go func() { + defer os.RemoveAll(tmpDir) + defer l.Close() + for { + conn, err := l.Accept() + if err != nil { + if !k8snet.IsProbableEOF(err) { + logrus.Errorf("failed to accept ssh-agent client connection: %v", err) + } + return + } + if err := agent.ServeAgent(*g.agent, conn); err != nil && err != io.EOF { + logrus.Errorf("failed to handle ssh-agent client connection: %v", err) + } + } + }() + + return l, nil +} + +func (g *git) httpClientWithCreds() (*http.Client, error) { + var ( + username string + password string + tlsConfig tls.Config + ) + + if g.secret != nil { + switch g.secret.Type { + case corev1.SecretTypeBasicAuth: + username = string(g.secret.Data[corev1.BasicAuthUsernameKey]) + password = string(g.secret.Data[corev1.BasicAuthPasswordKey]) + case corev1.SecretTypeTLS: + cert, err := tls.X509KeyPair(g.secret.Data[corev1.TLSCertKey], g.secret.Data[corev1.TLSPrivateKeyKey]) + if err != nil { + return nil, err + } + tlsConfig.Certificates = append(tlsConfig.Certificates, cert) + } + } + + if len(g.caBundle) > 0 { + cert, err := x509.ParseCertificate(g.caBundle) + if err != nil { + return nil, err + } + pool, err := x509.SystemCertPool() + if err != nil { + logrus.Debugf("getting system cert pool failed with %s", err) + pool = x509.NewCertPool() + } + pool.AddCert(cert) + tlsConfig.RootCAs = pool + } + + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tlsConfig + transport.TLSClientConfig.InsecureSkipVerify = g.insecureTLSVerify + + client := &http.Client{ + Transport: transport, + Timeout: 30 * time.Second, + } + if username != "" || password != "" { + client.Transport = &basicRoundTripper{ + username: username, + password: password, + next: client.Transport, + } + } + + return client, nil +} + +// Clone runs git clone with depth 1 +func (g *git) Clone(branch string) error { + if branch == "" { + return g.git("clone", "--depth=1", "-n", "--", g.URL, g.Directory) + } + return g.git("clone", "--depth=1", "-n", "--branch="+branch, "--", g.URL, g.Directory) +} + +func (g *git) clone(branch string) error { + gitDir := filepath.Join(g.Directory, ".git") + if dir, err := os.Stat(gitDir); err == nil && dir.IsDir() { + return nil + } + + if err := os.RemoveAll(g.Directory); err != nil { + return fmt.Errorf("failed to remove directory %s: %v", g.Directory, err) + } + + return g.Clone(branch) +} + +// Update updates git repo if remote sha has changed. +func (g *git) Update(branch string) (string, error) { + if err := g.clone(branch); err != nil { + return "", err + } + + if err := g.reset("HEAD"); err != nil { + return "", err + } + + commit, err := g.currentCommit() + if err != nil { + return commit, err + } + + if changed, err := g.remoteSHAChanged(branch, commit); err != nil || !changed { + return commit, err + } + + if err := g.fetchAndReset(branch); err != nil { + return "", err + } + + return g.currentCommit() +} + +func (g *git) fetchAndReset(rev string) error { + if err := g.git("-C", g.Directory, "fetch", "origin", "--", rev); err != nil { + return err + } + return g.reset("FETCH_HEAD") +} + +func (g *git) reset(rev string) error { + return g.git("-C", g.Directory, "reset", "--hard", rev) +} + +func (g *git) currentCommit() (string, error) { + return g.gitOutput("-C", g.Directory, "rev-parse", "HEAD") +} + +func (g *git) remoteSHAChanged(branch, sha string) (bool, error) { + formattedURL := formatGitURL(g.URL, branch) + if formattedURL == "" { + return true, nil + } + + client, err := g.httpClientWithCreds() + if err != nil { + logrus.Warnf("Problem creating http client to check git remote sha of repo [%v]: %v", g.URL, err) + return true, nil + } + defer client.CloseIdleConnections() + + req, err := http.NewRequest("GET", formattedURL, nil) + if err != nil { + logrus.Warnf("Problem creating request to check git remote sha of repo [%v]: %v", g.URL, err) + return true, nil + } + + req.Header.Set("Accept", "application/vnd.github.v3.sha") + req.Header.Set("If-None-Match", fmt.Sprintf("\"%s\"", sha)) + for k, v := range g.headers { + req.Header.Set(k, v) + } + + resp, err := client.Do(req) + if err != nil { + // Return timeout errors so caller can decide whether or not to proceed with updating the repo + uErr := &url.Error{} + if ok := errors.As(err, &uErr); ok && uErr.Timeout() { + return false, errors.Wrapf(uErr, "Repo [%v] is not accessible", g.URL) + } + return true, nil + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusNotModified { + return false, nil + } + + return true, nil +} + +func (g *git) git(args ...string) error { + var output io.Writer + if logrus.IsLevelEnabled(logrus.DebugLevel) { + output = os.Stdout + } + return g.gitCmd(output, args...) +} + +func (g *git) gitOutput(args ...string) (string, error) { + output := &bytes.Buffer{} + err := g.gitCmd(output, args...) + return strings.TrimSpace(output.String()), err +} + +func (g *git) gitCmd(output io.Writer, args ...string) error { + kv := fmt.Sprintf("credential.helper=%s", `/bin/sh -c 'echo "password=$GIT_PASSWORD"'`) + cmd := exec.Command("git", append([]string{"-c", kv}, args...)...) + cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_PASSWORD=%s", g.password)) + stderrBuf := &bytes.Buffer{} + cmd.Stderr = stderrBuf + cmd.Stdout = output + + if g.agent != nil { + c, err := g.injectAgent(cmd) + if err != nil { + return err + } + defer c.Close() + } + + if len(g.knownHosts) != 0 { + f, err := os.CreateTemp("", "known_hosts") + if err != nil { + return err + } + defer os.RemoveAll(f.Name()) + defer f.Close() + + if _, err := f.Write(g.knownHosts); err != nil { + return err + } + if err := f.Close(); err != nil { + return fmt.Errorf("closing knownHosts file %s: %w", f.Name(), err) + } + + cmd.Env = append(cmd.Env, "GIT_SSH_COMMAND="+fmt.Sprintf("ssh -o UserKnownHostsFile=%s", f.Name())) + } else { + cmd.Env = append(cmd.Env, "GIT_SSH_COMMAND="+"ssh -o StrictHostKeyChecking=accept-new") + } + cmd.Env = append(cmd.Env, "GIT_TERMINAL_PROMPT=0") + + if g.insecureTLSVerify { + cmd.Env = append(cmd.Env, "GIT_SSL_NO_VERIFY=false") + } + + if len(g.caBundle) > 0 { + f, err := os.CreateTemp("", "ca-pem-") + if err != nil { + return err + } + defer os.Remove(f.Name()) + defer f.Close() + + if _, err := f.Write(g.caBundle); err != nil { + return fmt.Errorf("writing cabundle to %s: %w", f.Name(), err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("closing cabundle %s: %w", f.Name(), err) + } + cmd.Env = append(cmd.Env, "GIT_SSL_CAINFO="+f.Name()) + } + + err := cmd.Run() + if err != nil { + return fmt.Errorf("git %s error: %w, detail: %v", strings.Join(args, " "), err, stderrBuf.String()) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/index.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/index.go new file mode 100644 index 0000000..1699835 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/index.go @@ -0,0 +1,91 @@ +package git + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/rancher/rancher/pkg/catalogv2/chart" + "helm.sh/helm/v3/pkg/provenance" + "helm.sh/helm/v3/pkg/repo" +) + +func BuildOrGetIndex(namespace, name, gitURL string) (*repo.IndexFile, error) { + dir := RepoDir(namespace, name, gitURL) + return buildOrGetIndex(dir) +} + +func buildOrGetIndex(dir string) (*repo.IndexFile, error) { + if err := ensureNoSymlinks(dir); err != nil { + return nil, err + } + + var ( + existingIndex *repo.IndexFile + indexPath = "" + builtIndex = repo.NewIndexFile() + ) + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if info.Name() == "index.yaml" { + if indexPath == "" || len(path) < len(indexPath) { + if index, err := repo.LoadIndexFile(path); err == nil { + existingIndex = index + indexPath = path + return filepath.SkipDir + } + } + } + + if !info.IsDir() { + return nil + } + + archive, ok, err := chart.LoadArchive(path) + if err != nil { + return err + } + if !ok { + return nil + } + + digest, err := provenance.DigestFile(archive.Path) + archive.Close() + if err != nil { + return err + } + + rel, err := filepath.Rel(dir, path) + if err != nil { + return fmt.Errorf("building path for chart at %s: %w", dir, err) + } + + builtIndex.Add(archive.Metadata, rel, "", digest) + return filepath.SkipDir + }) + if err != nil { + return nil, err + } + + if existingIndex != nil { + return existingIndex, nil + } + + return builtIndex, nil +} + +func ensureNoSymlinks(dir string) error { + return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil || info == nil { + return err + } + if isSymlink(info) { + return fmt.Errorf("symlink found at path %s", path) + } + return nil + }) +} + +func isSymlink(info os.FileInfo) bool { + return info.Mode()&os.ModeSymlink != 0 +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils.go new file mode 100644 index 0000000..f2636dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils.go @@ -0,0 +1,128 @@ +package git + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/pem" + "fmt" + "net/http" + "net/url" + "os" + "path/filepath" + "regexp" + "strings" +) + +const ( + stateDir = "management-state/git-repo" + staticDir = "/var/lib/rancher-data/local-catalogs/v2" + localDir = "../rancher-data/local-catalogs/v2" // identical to helm.InternalCatalog +) + +// RepoDir returns the directory where the git repo is cloned. +func RepoDir(namespace, name, gitURL string) string { + staticDir := filepath.Join(staticDir, namespace, name, Hash(gitURL)) + if s, err := os.Stat(staticDir); err == nil && s.IsDir() { + return staticDir + } + localDir := filepath.Join(localDir, namespace, name, Hash(gitURL)) + if s, err := os.Stat(localDir); err == nil && s.IsDir() { + return localDir + } + return filepath.Join(stateDir, namespace, name, Hash(gitURL)) +} + +// IsBundled checks the directory to see if it is a bundled catalog repository. +func IsBundled(dir string) bool { + return strings.HasPrefix(dir, staticDir) || strings.HasPrefix(dir, localDir) +} + +// isGitSSH checks if the URL is in the SSH URL format using regular expressions. +// [anything]@[anything]:[anything] +// ssh://@:// +func isGitSSH(gitURL string) bool { + pattern1 := `^[^:/]+@[^:]+:[a-zA-Z]+/[^/]+$` + pattern2 := `^ssh://[^@]+@[^:]+:\d+/.+$` + + // Check if the input matches either of the two patterns. + valid, err := regexp.MatchString(pattern1, gitURL) + if err != nil { + return false + } + if valid { + return true + } + valid, err = regexp.MatchString(pattern2, gitURL) + if err != nil { + return false + } + + return valid +} + +// validateURL will validate if the provided URL is in one of the expected patterns +// for the supported protocols http(s) or ssh. +// - if Valid: returns nil +// - if Invalid: returns an error +func validateURL(gitURL string) error { + valid := isGitSSH(gitURL) + if valid { + return nil + } + // not ssh; validate http(s) + u, err := url.Parse(gitURL) + if err != nil || (u.Scheme != "http" && u.Scheme != "https") { + return fmt.Errorf("invalid git URL: %s", gitURL) + } + + return nil +} + +// Hash returns a hash of the git URL. +func Hash(gitURL string) string { + b := sha256.Sum256([]byte(gitURL)) + return hex.EncodeToString(b[:]) +} + +// convertDERToPEM converts a src DER certificate into PEM with line breaks, header, and footer. +func convertDERToPEM(src []byte) []byte { + return pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Headers: map[string]string{}, + Bytes: src, + }) +} + +func formatGitURL(endpoint, branch string) string { + u, err := url.Parse(endpoint) + if err != nil { + return "" + } + + pathParts := strings.Split(u.Path, "/") + switch u.Hostname() { + case "github.com": + if len(pathParts) >= 3 { + org := pathParts[1] + repo := strings.TrimSuffix(pathParts[2], ".git") + return fmt.Sprintf("https://api.github.com/repos/%s/%s/commits/%s", org, repo, branch) + } + case "git.rancher.io": + repo := strings.TrimSuffix(pathParts[1], ".git") + u.Path = fmt.Sprintf("/repos/%s/commits/%s", repo, branch) + return u.String() + } + + return "" +} + +type basicRoundTripper struct { + username string + password string + next http.RoundTripper +} + +func (b *basicRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { + request.SetBasicAuth(b.username, b.password) + return b.next.RoundTrip(request) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils_test.go new file mode 100644 index 0000000..1ff7111 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/git/utils_test.go @@ -0,0 +1,56 @@ +package git + +import ( + "testing" + + assertlib "github.com/stretchr/testify/assert" +) + +func Test_isGitSSH(t *testing.T) { + testCases := []struct { + gitURL string + expected bool + }{ + // True cases + {"customusername@github.com:user/repo.git", true}, + {"customusername@gitlab.com:user/repo.git", true}, + {"customusername@gitlab.com:user/repo", true}, + {"customusername@gitlab.com:user/repo-with-dashes.git", true}, + {"git@github.com:user/repo.git", true}, + {"git@gitlab.com:user/repo-with-dashes.git", true}, + {"git@gitlab.com:user/repo", true}, + {"ssh://git@git.domain.com:443/repo", true}, + // False cases + {"https://github.com/user/repo.git", false}, + {"http://gitlab.com/user/repo.git", false}, + {"http://gitlab.com/user/repo", false}, + {"http://gitlab.com", false}, + {"git@gitlab.com", false}, + {"ftp://git@gitlab.com:22/repo", false}, + } + assert := assertlib.New(t) + for _, tc := range testCases { + actual := isGitSSH(tc.gitURL) + assert.Equalf(tc.expected, actual, "testcase: %v", tc) + } +} + +func Test_gitDir(t *testing.T) { + assert := assertlib.New(t) + testCases := []struct { + namespace string + name string + gitURL string + expected string + }{ + { + "namespace", "name", "https://git.rancher.io/charts", + "management-state/git-repo/namespace/name/4b40cac650031b74776e87c1a726b0484d0877c3ec137da0872547ff9b73a721", + }, + // NOTE(manno): cannot test the other cases without poluting the filesystem + } + for _, tc := range testCases { + actual := RepoDir(tc.namespace, tc.name, tc.gitURL) + assert.Equalf(tc.expected, actual, "testcase: %v", tc) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client.go new file mode 100644 index 0000000..f9273c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client.go @@ -0,0 +1,33 @@ +package helm + +import ( + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/release" + "k8s.io/cli-runtime/pkg/genericclioptions" +) + +type Client struct { + actRun func(*action.List) ([]*release.Release, error) + newList func(*action.Configuration) *action.List + restClientGetter genericclioptions.RESTClientGetter +} + +func NewClient(restClientGetter genericclioptions.RESTClientGetter) *Client { + return &Client{restClientGetter: restClientGetter, actRun: runAction, newList: action.NewList} +} + +func (c *Client) ListReleases(namespace, name string, stateMask action.ListStates) ([]*release.Release, error) { + helmCfg := &action.Configuration{} + if err := helmCfg.Init(c.restClientGetter, namespace, "", logrus.Infof); err != nil { + return nil, err + } + l := c.newList(helmCfg) + l.Filter = "^" + name + "$" + l.StateMask = stateMask + return c.actRun(l) +} + +func runAction(l *action.List) ([]*release.Release, error) { + return l.Run() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client_test.go new file mode 100644 index 0000000..e48842c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/client_test.go @@ -0,0 +1,162 @@ +package helm + +import ( + "bytes" + "encoding/gob" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chartutil" + kubefake "helm.sh/helm/v3/pkg/kube/fake" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v3/pkg/storage" + "helm.sh/helm/v3/pkg/storage/driver" + "io/ioutil" + "k8s.io/cli-runtime/pkg/genericclioptions" + testing2 "k8s.io/kubectl/pkg/cmd/testing" +) + +func TestListReleases(t *testing.T) { + t.Parallel() + asserts := assert.New(t) + type testInput struct { + name string + stateMask action.ListStates + releases []*release.Release + restClientGetter genericclioptions.RESTClientGetter + namespace string + runAction func(l *action.List) ([]*release.Release, error) + } + + type testCase struct { + name string + input testInput + skip bool + fails bool + } + + testRelease := []*release.Release{{Name: "test", Version: 1, Info: &release.Info{Status: release.StatusPendingInstall}}} + + testCases := []testCase{{ + name: "name and stateMask matches", + input: testInput{ + name: "test", + stateMask: action.ListPendingInstall, + releases: testRelease, + restClientGetter: testing2.NewTestFactory(), + namespace: "", + }, + skip: false, + }, { + name: "name does not match", + input: testInput{ + name: "random", + stateMask: action.ListPendingInstall, + restClientGetter: testing2.NewTestFactory(), + namespace: "", + releases: testRelease, + }, + skip: false, + }, { + name: "stateMask does not match", + input: testInput{ + name: "test", + stateMask: action.ListDeployed, + releases: testRelease, + restClientGetter: testing2.NewTestFactory(), + namespace: "test", + }, + skip: false, + }, { + name: "Name and state does not match", + input: testInput{ + name: "random", + stateMask: action.ListPendingUpgrade, + releases: testRelease, + restClientGetter: testing2.NewTestFactory(), + namespace: "test", + }, + skip: false, + }, { + name: "Run action modifies the result of list", + input: testInput{ + name: "test", + stateMask: action.ListPendingInstall, + releases: testRelease, + restClientGetter: testing2.NewTestFactory(), + namespace: "", + runAction: func(l *action.List) ([]*release.Release, error) { + r, e := l.Run() + r[0].Manifest = "random stuff" + return r, e + }, + }, + skip: false, + fails: true, + }} + for _, test := range testCases { + if test.skip { + continue + } + r, _ := registry.NewClient() + + mockCfg := &action.Configuration{ + Releases: storage.Init(driver.NewMemory()), + KubeClient: &kubefake.FailingKubeClient{PrintingKubeClient: kubefake.PrintingKubeClient{Out: ioutil.Discard}}, + Capabilities: chartutil.DefaultCapabilities, + RegistryClient: r, + Log: func(format string, v ...interface{}) { + t.Helper() + }, + } + for _, r := range test.input.releases { + asserts.NoError(mockCfg.Releases.Create(r), test.name) + } + var originalReleases []*release.Release + var originalErr error + client := Client{ + restClientGetter: test.input.restClientGetter, + actRun: func(list *action.List) ([]*release.Release, error) { + //filter and stateMask should be set + asserts.Equal("^"+test.input.name+"$", list.Filter, test.name) + asserts.Equal(test.input.stateMask, list.StateMask, test.name) + + r, e := list.Run() + err := deepCopy(&originalReleases, r) + asserts.NoError(err) + err = deepCopy(&originalErr, &e) + asserts.NoError(err) + if test.input.runAction != nil { + return test.input.runAction(list) + } + return runAction(list) + }, + newList: func(c *action.Configuration) *action.List { + return action.NewList(mockCfg) + }, + } + + resp, err := client.ListReleases(test.input.namespace, test.input.name, test.input.stateMask) + //response should be the same as list.Run() + asserts.True(reflect.DeepEqual(err, originalErr), test.name) + if len(resp) == 0 { + asserts.Equal(len(originalReleases), len(resp), test.name) + } else if !test.fails { + asserts.True(reflect.DeepEqual(resp, originalReleases), test.name) + } else { + asserts.False(reflect.DeepEqual(resp, originalReleases), test.name) + } + } + +} + +func deepCopy(dst, src interface{}) error { + var buf bytes.Buffer + if err := gob.NewEncoder(&buf).Encode(src); err != nil { + return err + } + return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm2.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm2.go new file mode 100644 index 0000000..ec1fdd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm2.go @@ -0,0 +1,178 @@ +package helm + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "io/ioutil" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/timestamp" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + rspb "k8s.io/helm/pkg/proto/hapi/release" + "sigs.k8s.io/yaml" +) + +var ( + // Map containing the accepted name of readme files + readmes = map[string]bool{ + "readme": true, + "readme.txt": true, + "readme.md": true, + } + // Map containing the possible release status + statusMapping = map[string]v1.Status{ + "UNKNOWN": v1.StatusUnknown, + "DEPLOYED": v1.StatusDeployed, + "DELETED": v1.StatusUninstalled, + "SUPERSEDED": v1.StatusSuperseded, + "FAILED": v1.StatusFailed, + "DELETING": v1.StatusUninstalling, + "PENDING_INSTALL": v1.StatusPendingInstall, + "PENDING_UPGRADE": v1.StatusPendingUpgrade, + "PENDING_ROLLBACK": v1.StatusPendingRollback, + } +) + +// isHelm2 checks if the value of the owner key of the received map is equal to TILLER. +// Every helm2 release object contains this label. +func isHelm2(labels map[string]string) bool { + return labels["OWNER"] == "TILLER" +} + +// fromHelm2Data receives a helm2 release data string of an installed helm chart. +// It then converts the string into Helm2 release struct and again to rancher v1.ReleaseSpec struct to return it. +func fromHelm2Data(data string, isNamespaced IsNamespaced) (*v1.ReleaseSpec, error) { + release, err := decodeHelm2(data) + if err != nil { + return nil, err + } + + return fromHelm2ReleaseToRelease(release, isNamespaced) +} + +// toTime receives timestamp in google protobuf format and returns the corresponding metav1.Time struct +func toTime(t *timestamp.Timestamp) *metav1.Time { + if t == nil || (t.Seconds == 0 && t.Nanos == 0) { + return nil + } + return &metav1.Time{ + Time: time.Unix(t.GetSeconds(), int64(t.GetNanos())).UTC(), + } +} + +// fromHelm2ReleaseToRelease receives a k8s release proto struct representing a helm2 release. +// Returns a pointer to a v1.ReleaseSpec struct for the helm2 release +func fromHelm2ReleaseToRelease(release *rspb.Release, isNamespaced IsNamespaced) (*v1.ReleaseSpec, error) { + var ( + err error + ) + + hr := &v1.ReleaseSpec{ + Name: release.Name, + Info: &v1.Info{ + FirstDeployed: toTime(release.GetInfo().GetFirstDeployed()), + LastDeployed: toTime(release.GetInfo().GetLastDeployed()), + Deleted: toTime(release.GetInfo().GetDeleted()), + Description: release.GetInfo().GetDescription(), + Status: statusMapping[release.GetInfo().GetStatus().GetCode().String()], + Notes: release.GetInfo().GetStatus().GetNotes(), + }, + Chart: &v1.Chart{ + Values: toMap(release.Namespace, release.Name, release.GetChart().GetValues().GetRaw()), + Metadata: &v1.Metadata{ + Name: release.GetChart().GetMetadata().GetName(), + Home: release.GetChart().GetMetadata().GetHome(), + Sources: release.GetChart().GetMetadata().GetSources(), + Version: release.GetChart().GetMetadata().GetVersion(), + Description: release.GetChart().GetMetadata().GetDescription(), + Keywords: release.GetChart().GetMetadata().GetKeywords(), + Icon: release.GetChart().GetMetadata().GetIcon(), + Condition: release.GetChart().GetMetadata().GetCondition(), + Tags: release.GetChart().GetMetadata().GetTags(), + AppVersion: release.GetChart().GetMetadata().GetAppVersion(), + Deprecated: release.GetChart().GetMetadata().GetDeprecated(), + Annotations: release.GetChart().GetMetadata().GetAnnotations(), + KubeVersion: release.GetChart().GetMetadata().GetKubeVersion(), + }, + }, + Values: toMap(release.Namespace, release.Name, release.GetConfig().GetRaw()), + Version: int(release.Version), + Namespace: release.Namespace, + HelmMajorVersion: 2, + } + + for _, m := range release.GetChart().GetMetadata().GetMaintainers() { + if m == nil { + continue + } + hr.Chart.Metadata.Maintainers = append(hr.Chart.Metadata.Maintainers, v1.Maintainer{ + Name: m.GetName(), + Email: m.GetEmail(), + URL: m.GetUrl(), + }) + } + + for _, f := range release.GetChart().GetFiles() { + if f == nil { + continue + } + if readmes[strings.ToLower(f.TypeUrl)] { + hr.Info.Readme = string(f.Value) + } + } + + hr.Resources, err = resourcesFromManifest(release.Namespace, release.Manifest, isNamespaced) + return hr, err +} + +// toMap receives the namespace, name and manifest of a release. +// If the manifest is a valid yaml, returns a map representing it, +// otherwise returns an empty map +func toMap(namespace, name string, manifest string) map[string]interface{} { + values := map[string]interface{}{} + + if manifest == "" { + return values + } + + if err := yaml.Unmarshal([]byte(manifest), &values); err != nil { + logrus.Errorf("failed to unmarshal yaml for %s/%s", namespace, name) + } + + return values +} + +// decodeHelm2 receives a helm2 release data and returns the corresponding helm2 release proto struct +func decodeHelm2(data string) (*rspb.Release, error) { + b, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil, err + } + + // For backwards compatibility with releases that were stored before + // compression was introduced we skip decompression if the + // gzip magic header is not found + if bytes.Equal(b[0:3], magicGzip) { + r, err := gzip.NewReader(bytes.NewReader(b)) + if err != nil { + return nil, err + } + b2, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + b = b2 + } + + var rls rspb.Release + // unmarshal protobuf bytes + if err := proto.Unmarshal(b, &rls); err != nil { + return nil, err + } + return &rls, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm3.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm3.go new file mode 100644 index 0000000..eba22cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/helm3.go @@ -0,0 +1,160 @@ +/* +Package helm implements ways of extracting information from helm2 and helm3 data and making a k8s releaseSpec. +It also implements a partition.Partition to handle the resources needed by the release. +*/ +package helm + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "io/ioutil" + "strings" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + + "helm.sh/helm/v3/pkg/release" +) + +// isHelm3 checks if the value of the owner key of the received map is equal to helm. +// Every helm3 release object has this particular label on it. +func isHelm3(labels map[string]string) bool { + return labels["owner"] == "helm" +} + +// fromHelm3Data receives a helm3 release data string of an installed helm chart. +// It then converts the string into Helm3 release struct and again to rancher +// v1.ReleaseSpec struct to return it. +func fromHelm3Data(data string, isNamespaced IsNamespaced) (*v1.ReleaseSpec, error) { + release, err := decodeHelm3(data) + if err != nil { + return nil, err + } + + return fromHelm3ReleaseToRelease(release, isNamespaced) +} + +// fromHelm3ReleaseToRelease receives a helm3 release struct. +// Returns a pointer to a rancher v1.ReleaseSpec struct constructed from the helm3 release struct. +func fromHelm3ReleaseToRelease(release *release.Release, isNamespaced IsNamespaced) (*v1.ReleaseSpec, error) { + var ( + info = &v1.Info{} + chart = &v1.Chart{} + err error + ) + + if release.Info != nil { + info = &v1.Info{ + Description: release.Info.Description, + Status: v1.Status(release.Info.Status), + Notes: release.Info.Notes, + } + if !release.Info.FirstDeployed.IsZero() { + info.FirstDeployed = &metav1.Time{Time: release.Info.FirstDeployed.Time} + } + if !release.Info.LastDeployed.IsZero() { + info.LastDeployed = &metav1.Time{Time: release.Info.LastDeployed.Time} + } + if !release.Info.Deleted.IsZero() { + info.Deleted = &metav1.Time{Time: release.Info.Deleted.Time} + } + } + + if release.Chart != nil { + chart = &v1.Chart{ + Values: release.Chart.Values, + } + if release.Chart.Metadata != nil { + chart.Metadata = &v1.Metadata{ + Name: release.Chart.Metadata.Name, + Home: release.Chart.Metadata.Home, + Sources: release.Chart.Metadata.Sources, + Version: release.Chart.Metadata.Version, + Description: release.Chart.Metadata.Description, + Keywords: release.Chart.Metadata.Keywords, + Icon: release.Chart.Metadata.Icon, + APIVersion: release.Chart.Metadata.APIVersion, + Condition: release.Chart.Metadata.Condition, + Tags: release.Chart.Metadata.Tags, + AppVersion: release.Chart.Metadata.AppVersion, + Deprecated: release.Chart.Metadata.Deprecated, + Annotations: release.Chart.Metadata.Annotations, + KubeVersion: release.Chart.Metadata.KubeVersion, + Type: release.Chart.Metadata.Type, + } + + for _, m := range release.Chart.Metadata.Maintainers { + if m == nil { + continue + } + chart.Metadata.Maintainers = append(chart.Metadata.Maintainers, v1.Maintainer{ + Name: m.Name, + Email: m.Email, + URL: m.URL, + }) + } + } + + for _, f := range release.Chart.Files { + if f == nil { + continue + } + if readmes[strings.ToLower(f.Name)] { + info.Readme = string(f.Data) + } + } + } + + hr := &v1.ReleaseSpec{ + Name: release.Name, + Info: info, + Chart: chart, + Values: release.Config, + Resources: nil, + Version: release.Version, + Namespace: release.Namespace, + HelmMajorVersion: 3, + } + + hr.Resources, err = resourcesFromManifest(release.Namespace, release.Manifest, isNamespaced) + return hr, err +} + +// decodeHelm3 receives a helm3 release data string, decodes the string data using the standard base64 library +// and unmarshals the data into release.Release struct to return it. +func decodeHelm3(data string) (*release.Release, error) { + b, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil, err + } + + // Data is too small to be helm 3 release object + if len(b) <= 3 { + return nil, ErrNotHelmRelease + } + + // For backwards compatibility with releases that were stored before + // compression was introduced we skip decompression if the + // gzip magic header is not found + if bytes.Equal(b[0:3], magicGzip) { + r, err := gzip.NewReader(bytes.NewReader(b)) + if err != nil { + return nil, err + } + b2, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + b = b2 + } + + var rls release.Release + // unmarshal release object bytes + if err := json.Unmarshal(b, &rls); err != nil { + return nil, err + } + return &rls, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/info.go new file mode 100644 index 0000000..3a13d13 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/info.go @@ -0,0 +1,85 @@ +package helm + +import ( + "archive/tar" + "compress/gzip" + "io" + "io/ioutil" + "strings" + + "github.com/rancher/rancher/pkg/api/steve/catalog/types" + + "sigs.k8s.io/yaml" +) + +// decodeYAML reads YAML data from input and decodes it into target +func decodeYAML(input io.Reader, target interface{}) error { + data, err := ioutil.ReadAll(input) + if err != nil { + return err + } + return yaml.Unmarshal(data, target) +} + +// InfoFromTarball receives an input containing a tarball file with chart-data +// Returns a pointer to a types.ChartInfo struct containing the chart-data +func InfoFromTarball(input io.Reader) (*types.ChartInfo, error) { + result := &types.ChartInfo{ + Values: map[string]interface{}{}, + Questions: map[string]interface{}{}, + Chart: map[string]interface{}{}, + } + + gz, err := gzip.NewReader(input) + if err != nil { + return nil, err + } + + tarball := tar.NewReader(gz) + for { + file, err := tarball.Next() + if err == io.EOF { + break + } + + parts := strings.SplitN(file.Name, "/", 2) + if len(parts) == 1 { + continue + } + + switch strings.ToLower(parts[1]) { + case "values.yml": + fallthrough + case "values.yaml": + if err := decodeYAML(tarball, &result.Values); err != nil { + return nil, err + } + case "questions.yml": + fallthrough + case "questions.yaml": + if err := decodeYAML(tarball, &result.Questions); err != nil { + return nil, err + } + case "chart.yml": + fallthrough + case "chart.yaml": + if err := decodeYAML(tarball, &result.Chart); err != nil { + return nil, err + } + case "app-readme.md": + bytes, err := ioutil.ReadAll(tarball) + if err != nil { + return nil, err + } + result.APPReadme = string(bytes) + case "readme.md": + bytes, err := ioutil.ReadAll(tarball) + if err != nil { + return nil, err + } + result.Readme = string(bytes) + } + } + + return result, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/release.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/release.go new file mode 100644 index 0000000..fd2eb35 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helm/release.go @@ -0,0 +1,150 @@ +package helm + +import ( + "bytes" + "encoding/base64" + "errors" + "strconv" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/yaml" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + meta2 "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + ErrNotHelmRelease = errors.New("not helm release") // error for when it's not a helm release + magicGzip = []byte{0x1f, 0x8b, 0x08} // gzip magic header +) + +// IsNamespaced Alias for func(gvk schema.GroupVersionKind) bool +type IsNamespaced func(gvk schema.GroupVersionKind) bool + +// IsLatest checked if the received v1.ReleaseSpec is on the latest version of a helm chart +// by comparing its version to all release helm objects. +func IsLatest(release *v1.ReleaseSpec, others []runtime.Object) bool { + for _, other := range others { + m, err := meta.Accessor(other) + if err != nil { + continue + } + labels := m.GetLabels() + name := labels["name"] + if name == "" { + name = labels["NAME"] + } + if name != release.Name { + continue + } + + version := labels["version"] + if version == "" { + version = labels["VERSION"] + } + + v, err := strconv.Atoi(version) + if err != nil { + continue + } + + if v > release.Version { + return false + } + } + + return true +} + +// ToRelease return a v1.ReleaseSpec for the given runtime.Object received. +// The function populates the releaseSpec with release information related +// to an installed app based on the helm version used to install the app. +func ToRelease(obj runtime.Object, isNamespaced IsNamespaced) (*v1.ReleaseSpec, error) { + releaseData, err := getReleaseDataAndKind(obj) + if err != nil { + return nil, err + } + + meta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + + switch { + case isHelm3(meta.GetLabels()): + return fromHelm3Data(releaseData, isNamespaced) + case isHelm2(meta.GetLabels()): + return fromHelm2Data(releaseData, isNamespaced) + } + + return nil, ErrNotHelmRelease +} + +// getReleaseDataAndKind receives a runtime.Object which can be an +// unstructured.Unstructured, corev1.ConfigMap or a corev1.Secret. +// It extracts the data["release"] based on the object type and returns it. +func getReleaseDataAndKind(obj runtime.Object) (string, error) { + switch t := obj.(type) { + case *unstructured.Unstructured: + if t == nil { + return "", ErrNotHelmRelease + } + releaseData := data.Object(t.Object).String("data", "release") + switch t.GetKind() { + case "ConfigMap": + return releaseData, nil + case "Secret": + data, err := base64.StdEncoding.DecodeString(releaseData) + if err != nil { + return "", err + } + return string(data), nil + } + case *corev1.ConfigMap: + if t == nil { + return "", ErrNotHelmRelease + } + return t.Data["release"], nil + case *corev1.Secret: + if t == nil { + return "", ErrNotHelmRelease + } + return string(t.Data["release"]), nil + } + + return "", ErrNotHelmRelease +} + +// resourcesFromManifest receives the rendered manifest template as a string and +// uses the wrangler yaml functions to convert it to a list of runtime.Objects. +// It then converts each object to a v1.ReleaseResource and returns that list. +func resourcesFromManifest(namespace string, manifest string, isNamespaced IsNamespaced) (result []v1.ReleaseResource, err error) { + objs, err := yaml.ToObjects(bytes.NewReader([]byte(manifest))) + if err != nil { + return nil, err + } + + for _, obj := range objs { + meta, err := meta2.Accessor(obj) + if err != nil { + return nil, err + } + r := v1.ReleaseResource{ + Name: meta.GetName(), + Namespace: meta.GetNamespace(), + } + gvk := obj.GetObjectKind().GroupVersionKind() + if isNamespaced != nil && isNamespaced(gvk) && r.Namespace == "" { + r.Namespace = namespace + } + r.APIVersion, r.Kind = gvk.ToAPIVersionAndKind() + result = append(result, r) + } + + return result, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation.go new file mode 100644 index 0000000..50fc438 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation.go @@ -0,0 +1,1108 @@ +/* +Package helmop implements handlers for managing helm operations. +*/ +package helmop + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/httputil" + "path/filepath" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "github.com/rancher/apiserver/pkg/types" + types2 "github.com/rancher/rancher/pkg/api/steve/catalog/types" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalogv2/content" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + namespaces "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/steve/pkg/podimpersonation" + "github.com/rancher/steve/pkg/stores/proxy" + data2 "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + rbacv1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + v1internal "k8s.io/kubernetes/pkg/apis/core/v1" + "sigs.k8s.io/yaml" +) + +const ( + // helmDataPath contains the files such as values.yaml for a given chart and tar of the chart. + helmDataPath = "/home/shell/helm" + helmRunPath = "/home/shell/helm-run" +) + +var ( + badChars = regexp.MustCompile("[^-.0-9a-zA-Z]") + thirty = int64(30) + chartYAML = map[string]bool{ + "chart.yaml": true, + "Chart.yaml": true, + "chart.yml": true, + "Chart.yml": true, + } +) + +var ( + podOptionsScheme = runtime.NewScheme() + podOptionsCodec = runtime.NewParameterCodec(podOptionsScheme) +) + +var kustomization = `apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +transformers: +- /home/shell/helm-run/transform%s.yaml +resources: +- /home/shell/helm-run/all.yaml` + +var transform = `apiVersion: builtin +kind: LabelTransformer +metadata: + name: common-labels +labels: + io.cattle.field/appId: %s +fieldSpecs: +- path: metadata/labels + create: true +- path: spec/selector + create: true + version: v1 + kind: ReplicationController +- path: spec/template/metadata/labels + create: true + version: v1 + kind: ReplicationController +- path: spec/selector/matchLabels + create: true + kind: Deployment +- path: spec/template/metadata/labels + create: true + kind: Deployment +- path: spec/selector/matchLabels + create: true + kind: ReplicaSet +- path: spec/template/metadata/labels + create: true + kind: ReplicaSet +- path: spec/selector/matchLabels + create: true + kind: DaemonSet +- path: spec/template/metadata/labels + create: true + kind: DaemonSet +- path: spec/selector/matchLabels + create: true + group: apps + kind: StatefulSet +- path: spec/template/metadata/labels + create: true + group: apps + kind: StatefulSet +- path: spec/volumeClaimTemplates[]/metadata/labels + create: true + group: apps + kind: StatefulSet +- path: spec/template/metadata/labels + create: true + group: batch + kind: Job +- path: spec/jobTemplate/metadata/labels + create: true + group: batch + kind: CronJob +- path: spec/jobTemplate/spec/template/metadata/labels + create: true + group: batch + kind: CronJob` + +func init() { + v1internal.AddToScheme(podOptionsScheme) +} + +// Operations describes a helm operation, containing its namespace, roles and such +type Operations struct { + namespace string // namespace the operation is going to be in + contentManager *content.Manager // manager struct to retrieve information about helm repos and its charts + Impersonator *podimpersonation.PodImpersonation // the impersonator used to manage pods created using the service account of the logged in user + clusterRepos catalogcontrollers.ClusterRepoClient // client for cluster repo custom resource + ops catalogcontrollers.OperationClient // client for operation custom resource + pods corev1controllers.PodClient // client for pod kubernetes resource + apps catalogcontrollers.AppClient // client for apps custom resource + roles rbacv1controllers.RoleClient // client for role kubernetes resource + roleBindings rbacv1controllers.RoleBindingClient // client for rolebinding kubernetes resource + cg proxy.ClientGetter // dynamic kubernetes client factory +} + +// NewOperations creates a new Operations struct with all fields initialized +func NewOperations( + cg proxy.ClientGetter, + catalog catalogcontrollers.Interface, + rbac rbacv1controllers.Interface, + contentManager *content.Manager, + pods corev1controllers.PodClient) *Operations { + return &Operations{ + cg: cg, + contentManager: contentManager, + namespace: namespaces.System, + Impersonator: podimpersonation.New("helm-op", cg, time.Hour, settings.FullShellImage), + pods: pods, + clusterRepos: catalog.ClusterRepo(), + ops: catalog.Operation(), + apps: catalog.App(), + roleBindings: rbac.RoleBinding(), + roles: rbac.Role(), + } +} + +// Uninstall gets the uninstall commands using the given namespace, name and options and gets the user information using the isApp flag as true. +// Returns a catalog.Operation that represents the helm operation to be created +func (s *Operations) Uninstall(ctx context.Context, user user.Info, namespace, name string, options io.Reader, imageOverride string) (*catalog.Operation, error) { + status, cmds, err := s.getUninstallArgs(namespace, name, options) + if err != nil { + return nil, err + } + + user, err = s.getUser(user, namespace, name, true) + if err != nil { + return nil, err + } + + return s.createOperation(ctx, user, status, cmds, imageOverride) +} + +// Upgrade gets the upgrade commands using the given namespace, name and options and gets the user using the isApp flag as false. +// Returns a catalog.Operation that represents the helm operation to be created +func (s *Operations) Upgrade(ctx context.Context, user user.Info, namespace, name string, options io.Reader, imageOverride string) (*catalog.Operation, error) { + status, cmds, err := s.getUpgradeCommand(namespace, name, options) + if err != nil { + return nil, err + } + + user, err = s.getUser(user, namespace, name, false) + if err != nil { + return nil, err + } + + return s.createOperation(ctx, user, status, cmds, imageOverride) +} + +// Install gets the install commands using the given namespace, name and options and gets the user using the isApp flag as false. +// Returns a catalog.Operation that represents the helm operation to be created +func (s *Operations) Install(ctx context.Context, user user.Info, namespace, name string, options io.Reader, imageOverride string) (*catalog.Operation, error) { + status, cmds, err := s.getInstallCommand(namespace, name, options) + if err != nil { + return nil, err + } + + user, err = s.getUser(user, namespace, name, false) + if err != nil { + return nil, err + } + + return s.createOperation(ctx, user, status, cmds, imageOverride) +} + +// decodeParams decodes the request using it's url and v1 group version into the target object +func decodeParams(req *http.Request, target runtime.Object) error { + return podOptionsCodec.DecodeParameters(req.URL.Query(), corev1.SchemeGroupVersion, target) +} + +// proxyLogRequest proxies the given http.Request to get the logs of the given k8s pod and write it to the given http.ResponseWriter +func (s *Operations) proxyLogRequest(rw http.ResponseWriter, req *http.Request, pod *v1.Pod, client kubernetes.Interface) error { + logOptions := &v1.PodLogOptions{} + if err := decodeParams(req, logOptions); err != nil { + return err + } + + logOptions.Container = "helm" + logURL := client.CoreV1().RESTClient(). + Get(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("log"). + VersionedParams(logOptions, scheme.ParameterCodec).URL() + + httpClient := client.CoreV1().RESTClient().(*rest.RESTClient).Client + + //Creates a reverse proxy and modifies the request url and headers + p := httputil.ReverseProxy{ + Director: func(req *http.Request) { + req.URL = logURL + req.Host = logURL.Host + for key := range req.Header { + if strings.HasPrefix(key, "Impersonate-Extra-") { + delete(req.Header, key) + } + } + delete(req.Header, "Impersonate-Group") + delete(req.Header, "Impersonate-User") + delete(req.Header, "Authorization") + delete(req.Header, "Cookie") + }, + Transport: httpClient.Transport, + FlushInterval: time.Millisecond * 100, + } + + p.ServeHTTP(rw, req) + return nil +} + +// Log receives a response writer, a http request, the namespace and name of an operation. +// Gets the pod of the operation and proxies the request to get logs of said pod +func (s *Operations) Log(rw http.ResponseWriter, req *http.Request, namespace, name string) error { + op, err := s.ops.Get(namespace, name, metav1.GetOptions{}) + if err != nil { + return err + } + + pod, err := s.pods.Get(op.Status.PodNamespace, op.Status.PodName, metav1.GetOptions{}) + if err != nil { + return err + } + + // check if the pod and op have objects depended by them and that they aren't the same + if len(pod.OwnerReferences) == 0 || len(op.OwnerReferences) == 0 || pod.OwnerReferences[0].UID != op.OwnerReferences[0].UID { + return validation.NotFound + } + + if pod.Labels[podimpersonation.TokenLabel] != op.Status.Token { + return validation.NotFound + } + + client, err := s.cg.AdminK8sInterface() + if err != nil { + return err + } + + return s.proxyLogRequest(rw, req, pod, client) +} + +// getSpec receives the namespace and name of either an app or a repo according to the value of the isApp flag. +// If the isApp flag is true, gets the app and then check the annotations of the chart of the release to see if it's a cluster repo and to get it's name. +// Returns the found catalog.RepoSpec and doesn't return errors if the repo isn't found. +// +// If the isApp flag is false, gets the cluster repo directly using its name. Panics if the namespace isn't empty. +// Returns a catalog.RepoSec struct or an error if it's not found. +func (s *Operations) getSpec(namespace, name string, isApp bool) (*catalog.RepoSpec, error) { + if isApp { + rel, err := s.apps.Get(namespace, name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + if rel.Spec.Chart != nil && rel.Spec.Chart.Metadata != nil { + isClusterRepo := rel.Spec.Chart.Metadata.Annotations["catalog.cattle.io/ui-source-repo-type"] + if isClusterRepo != "cluster" { + return &catalog.RepoSpec{}, nil + } + clusterRepoName := rel.Spec.Chart.Metadata.Annotations["catalog.cattle.io/ui-source-repo"] + clusterRepo, err := s.clusterRepos.Get(clusterRepoName, metav1.GetOptions{}) + if err != nil { + // don't report error if annotation doesn't exist + return &catalog.RepoSpec{}, nil + } + return &clusterRepo.Spec, nil + } + return &catalog.RepoSpec{}, nil + } + if namespace == "" { + clusterRepo, err := s.clusterRepos.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + return &clusterRepo.Spec, nil + } + + panic("namespace should be empty") +} + +// getUser receives the user info, the namespace of the repo and the name of either an app or a repo according to the value of the isApp flag. +// Gets the repoSpec and uses it to build a user.DefaultInfo struct with a default name and groups that will be used to create an operation in either the +// namespace of the repo or the one given. +// Returns a user.Info struct to create an operation. +func (s *Operations) getUser(userInfo user.Info, namespace, name string, isApp bool) (user.Info, error) { + repoSpec, err := s.getSpec(namespace, name, isApp) + if err != nil { + return nil, err + } + + if repoSpec.ServiceAccount == "" { + return userInfo, nil + } + serviceAccountNS := repoSpec.ServiceAccountNamespace + if namespace != "" { + serviceAccountNS = namespace + } + if serviceAccountNS == "" || strings.Contains(repoSpec.ServiceAccountNamespace, ":") { + return userInfo, nil + } + return &user.DefaultInfo{ + Name: fmt.Sprintf("system:serviceaccount:%s:%s", serviceAccountNS, repoSpec.ServiceAccount), + Groups: []string{ + "system:serviceaccounts", + "system:serviceaccounts:" + serviceAccountNS, + }, + }, nil +} + +// getUninstallArgs receives the app namespace, app name and body of the request. +// Returns an uninstall Command according to the input received and also returns the status of the operation that will be created +// to run the command +func (s *Operations) getUninstallArgs(appNamespace, appName string, body io.Reader) (catalog.OperationStatus, Commands, error) { + rel, err := s.apps.Get(appNamespace, appName, metav1.GetOptions{}) + if err != nil { + return catalog.OperationStatus{}, nil, err + } + + uninstallArgs := &types2.ChartUninstallAction{} + if err := json.NewDecoder(body).Decode(uninstallArgs); err != nil { + return catalog.OperationStatus{}, nil, err + } + + cmd := Command{ + Operation: "uninstall", + ArgObjects: []interface{}{ + uninstallArgs, + }, + ReleaseName: rel.Spec.Name, + ReleaseNamespace: rel.Namespace, + } + + status := catalog.OperationStatus{ + Action: cmd.Operation, + Release: rel.Spec.Name, + Namespace: appNamespace, + } + + return status, Commands{cmd}, nil +} + +// getUpgradeCommand receives the repository namespace and name and body of the request. +// Returns the status of the operation that will be created and a list of Command to upgrade the charts received in the request +func (s *Operations) getUpgradeCommand(repoNamespace, repoName string, body io.Reader) (catalog.OperationStatus, Commands, error) { + var ( + upgradeArgs = &types2.ChartUpgradeAction{} + commands Commands + ) + err := json.NewDecoder(body).Decode(upgradeArgs) + if err != nil { + return catalog.OperationStatus{}, nil, err + } + + if upgradeArgs.MaxHistory == 0 { + upgradeArgs.MaxHistory = 5 + } + upgradeArgs.Install = true + + status := catalog.OperationStatus{ + Action: "upgrade", + Namespace: namespace(upgradeArgs.Namespace), + } + + for _, chartUpgrade := range upgradeArgs.Charts { + cmd, err := s.getChartCommand(repoNamespace, repoName, chartUpgrade.ChartName, chartUpgrade.Version, true, chartUpgrade.Annotations, chartUpgrade.Values) + if err != nil { + return status, nil, err + } + cmd.ReleaseName = chartUpgrade.ReleaseName + cmd.Operation = "upgrade" + cmd.ArgObjects = []interface{}{ + chartUpgrade, + upgradeArgs, + } + + // Add the labels to the command arguments to indicate the chart is from a cluster repo + cmd.ArgObjects = append(cmd.ArgObjects, map[string]interface{}{ + "labels": fmt.Sprintf("%s=%s", catalog.ClusterRepoNameLabel, repoName), + }) + + status.Release = chartUpgrade.ReleaseName + commands = append(commands, cmd) + } + + return status, commands, nil +} + +// Command represents a command that will be run inside a helm operation +type Command struct { + Operation string // type of operation, eg upgrade, install, uninstall + ArgObjects []interface{} // the arguments that will be used in the command + ValuesFile string // name of the values.yaml file + Values []byte // content of the values.yaml file + ChartFile string // name of the chart tar file + Chart []byte // content of the chart file + ReleaseName string // name of the release + ReleaseNamespace string // namespace of the release + Kustomize bool // flag to inform if it should use kustomize.sh +} + +type Commands []Command + +// CommandArgs returns a list containing all the commands and their arguments +func (c Commands) CommandArgs() ([]string, error) { + var ( + result []string + ) + for _, c := range c { + args, err := c.renderArgs() + if err != nil { + return nil, err + } + if len(result) > 0 { + result = append(result, ";") + } + result = append(result, "helm") + result = append(result, args...) + } + return result, nil +} + +// Render calls the Command.Render method for each command and appends the +// result in a map and returns it +func (c Commands) Render() (map[string][]byte, error) { + data := map[string][]byte{} + for i, cmd := range c { + cmdData, err := cmd.Render(i) + if err != nil { + return nil, err + } + for k, v := range cmdData { + data[k] = v + } + } + + return data, nil +} + +// Render returns a map containing the arguments and their values for the Command +func (c Command) Render(index int) (map[string][]byte, error) { + args, err := c.renderArgs() + if err != nil { + return nil, err + } + + fileNumID := fmt.Sprintf("%03d", index) + data := map[string][]byte{ + fmt.Sprintf("operation%s", fileNumID): []byte(strings.Join(args, "\x00")), + } + if len(c.ValuesFile) > 0 { + data[c.ValuesFile] = c.Values + } + if len(c.ChartFile) > 0 { + data[c.ChartFile] = c.Chart + } + + if c.Kustomize { + data[fmt.Sprintf("kustomization%s.yaml", fileNumID)] = []byte(fmt.Sprintf(kustomization, fileNumID)) + data[fmt.Sprintf("transform%s.yaml", fileNumID)] = []byte(fmt.Sprintf(transform, c.ReleaseName)) + } + + return data, nil +} + +// renderArgs returns a slice of string representing the Command.Operation and it's arguments. +// It uses the ArgObjects of the command struct to generate arguments for the command +// and removes the fields that aren't necessary in the command +func (c Command) renderArgs() ([]string, error) { + var ( + args []string + ) + + dataMap := map[string]interface{}{} + for _, argObject := range c.ArgObjects { + data, err := convert.EncodeToMap(argObject) + if err != nil { + return nil, err + } + for k, v := range data { + dataMap[k] = v + } + } + + delete(dataMap, "annotations") + delete(dataMap, "values") + delete(dataMap, "charts") + delete(dataMap, "releaseName") + delete(dataMap, "chartName") + delete(dataMap, "projectId") + if v, ok := dataMap["disableOpenAPIValidation"]; ok { + delete(dataMap, "disableOpenAPIValidation") + dataMap["disableOpenapiValidation"] = v + } + + for k, v := range dataMap { + s := convert.ToString(v) + k = convert.ToArgKey(k) + // This is a possibly unneeded check, but we want to ensure the strings have no null bytes so + // running the xargs -0 works. + if !utf8.ValidString(s) || !utf8.ValidString(k) { + return nil, fmt.Errorf("invalid non-utf8 string") + } + args = append(args, fmt.Sprintf("%s=%s", k, s)) + } + + runPath := helmDataPath + if c.Kustomize { + // Run path when using kustomize.sh will be different. Original cannot be used + // because write permissions are necessary and the helmDataPath cannot be + // written to due to it having a SecretVolumeSource. + runPath = helmRunPath + args = append(args, "--post-renderer=/home/shell/kustomize.sh") + } + + if len(c.Values) > 0 { + args = append(args, "--values="+filepath.Join(runPath, c.ValuesFile)) + } + + if c.ReleaseNamespace != "" { + args = append(args, "--namespace="+c.ReleaseNamespace) + } + + sort.Strings(args) + if c.ReleaseName != "" { + args = append(args, c.ReleaseName) + } + if len(c.Chart) > 0 { + args = append(args, filepath.Join(runPath, c.ChartFile)) + } + + return append([]string{c.Operation}, args...), nil +} + +func sanitizeCommandKeyNames(name string) string { + return strings.Replace(name, "/", "-", -1) +} + +func sanitizeVersion(chartVersion string) string { + return badChars.ReplaceAllString(chartVersion, "-") +} + +// injectAnnotation receives the chart data from a tar file and injects the given annotations. +// Returns the modified chart data +func injectAnnotation(data []byte, annotations map[string]string) ([]byte, error) { + if len(annotations) == 0 { + return data, nil + } + + tgz, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, err + } + + var ( + dest = &bytes.Buffer{} + destGz = gzip.NewWriter(dest) + destTar = tar.NewWriter(destGz) + tar = tar.NewReader(tgz) + ) + + for { + header, err := tar.Next() + if err == io.EOF { + break + } + + data, err := ioutil.ReadAll(tar) + if err != nil { + return nil, err + } + + // checks if its chart.yaml + parts := strings.Split(header.Name, "/") + if len(parts) == 2 && chartYAML[parts[1]] { + data, err = addAnnotations(data, annotations) + if err != nil { + return nil, err + } + header.Size = int64(len(data)) + } + + if err := destTar.WriteHeader(header); err != nil { + return nil, err + } + + _, err = destTar.Write(data) + if err != nil { + return nil, err + } + } + + if err = destTar.Close(); err != nil { + return nil, err + } + + if err = destGz.Close(); err != nil { + return nil, err + } + + return dest.Bytes(), nil +} + +// addAnnotations receives that chart.yaml data and injects the given annotations in it +func addAnnotations(data []byte, annotations map[string]string) ([]byte, error) { + chartData := map[string]interface{}{} + if err := yaml.Unmarshal(data, &chartData); err != nil { + return nil, err + } + + chartAnnotations := data2.Object(chartData).Map("annotations") + if chartAnnotations == nil { + chartAnnotations = map[string]interface{}{} + } + for k, v := range annotations { + chartAnnotations[k] = v + } + + chartData["annotations"] = chartAnnotations + return yaml.Marshal(chartData) +} + +// enableKustomize returns whether kustomize should be used. If the helm operation is +// an upgrade and the migrated annotation is present, true will be returned. +func (s *Operations) enableKustomize(annotations map[string]string, upgrade bool) bool { + if !upgrade { + return false + } + + if len(annotations) == 0 { + return false + } + + if val, _ := annotations["apps.cattle.io/migrated"]; val != "true" { + return false + } + + return true +} + +// getChartCommand gets the chart based on the input, inject the annotations into it +// and then creates and return a Command containing the name of the values file, name of the chart file, the chart data +// and if the command should use kustomize.sh +func (s *Operations) getChartCommand(namespace, name, chartName, chartVersion string, upgrade bool, annotations map[string]string, values map[string]interface{}) (Command, error) { + chart, err := s.contentManager.Chart(namespace, name, chartName, chartVersion, true) + if err != nil { + return Command{}, err + } + chartData, err := ioutil.ReadAll(chart) + chart.Close() + if err != nil { + return Command{}, err + } + + chartData, err = injectAnnotation(chartData, annotations) + if err != nil { + return Command{}, err + } + + valuesFileName := sanitizeCommandKeyNames(fmt.Sprintf("values-%s-%s.yaml", chartName, sanitizeVersion(chartVersion))) + chartFileName := sanitizeCommandKeyNames(fmt.Sprintf("%s-%s.tgz", chartName, sanitizeVersion(chartVersion))) + + c := Command{ + ValuesFile: valuesFileName, + ChartFile: chartFileName, + Chart: chartData, + Kustomize: s.enableKustomize(annotations, upgrade), + } + + if len(values) > 0 { + c.Values, err = json.Marshal(values) + if err != nil { + return Command{}, err + } + } + + return c, nil +} + +// getInstallCommand receives the repository namespace, name, and body of the request. +// It decodes the request to get chart information for creating the `helm install` command +// along with args. It returns the catalog.OperationStatus struct and a slice of commands +// to install the charts received in the body of the request. +func (s *Operations) getInstallCommand(repoNamespace, repoName string, body io.Reader) (catalog.OperationStatus, Commands, error) { + installArgs := &types2.ChartInstallAction{} + err := json.NewDecoder(body).Decode(installArgs) + if err != nil { + return catalog.OperationStatus{}, nil, err + } + + var ( + cmds []Command + status = catalog.OperationStatus{ + Action: "install", + } + ) + // Sometimes there are two charts to be installed. First one being the CRD chart + // and then the actual helm chart. So, we need a for loop and the last index of the array + // would be the main chart. + for _, chartInstall := range installArgs.Charts { + cmd, err := s.getChartCommand(repoNamespace, repoName, chartInstall.ChartName, chartInstall.Version, false, chartInstall.Annotations, chartInstall.Values) + if err != nil { + return status, nil, err + } + cmd.Operation = "install" + cmd.ArgObjects = []interface{}{ + chartInstall, + installArgs, + } + cmd.ReleaseName = chartInstall.ReleaseName + + if len(installArgs.Charts) == 1 { + if cmd.ReleaseName == "" { + cmd.ArgObjects = append(cmd.ArgObjects, map[string]interface{}{ + "generateName": "true", + }) + } + } else { + cmd.Operation = "upgrade" + cmd.ArgObjects = append(cmd.ArgObjects, map[string]interface{}{ + "install": "true", + }) + } + // Add the labels to the command arguments to indicate the chart is from a cluster repo + cmd.ArgObjects = append(cmd.ArgObjects, map[string]interface{}{ + "labels": fmt.Sprintf("%s=%s", catalog.ClusterRepoNameLabel, repoName), + }) + + status.Release = chartInstall.ReleaseName + + cmds = append(cmds, cmd) + } + + status.Namespace = namespace(installArgs.Namespace) + status.ProjectID = installArgs.ProjectID + + return status, cmds, err +} + +// namespace func sets the namespace as default if it is empty otherwise returns the same namespace it receives. +func namespace(ns string) string { + if ns == "" { + return "default" + } + return ns +} + +// createOperation creates an operation and its pod, along with its roles and roleBinding. +// Uses the Operations.Impersonator and Operations.ops to do it. +// Returns the created catalog.Operation struct +func (s *Operations) createOperation(ctx context.Context, user user.Info, status catalog.OperationStatus, cmds Commands, imageOverride string) (*catalog.Operation, error) { + if status.Action != "uninstall" { + _, err := s.createNamespace(ctx, status.Namespace, status.ProjectID) + if err != nil { + return nil, err + } + } + + secretData, err := cmds.Render() + if err != nil { + return nil, err + } + + var kustomize bool + for _, cmd := range cmds { + if !cmd.Kustomize { + continue + } + kustomize = true + break + } + pod, podOptions := s.createPod(secretData, kustomize, imageOverride) + pod, err = s.Impersonator.CreatePod(ctx, user, pod, podOptions) + if err != nil { + return nil, err + } + + status.Command, err = cmds.CommandArgs() + if err != nil { + return nil, err + } + + status.Token = pod.Labels[podimpersonation.TokenLabel] + status.PodName = pod.Name + status.PodNamespace = pod.Namespace + + op := &catalog.Operation{ + ObjectMeta: metav1.ObjectMeta{ + Name: pod.Name, + Namespace: status.Namespace, + OwnerReferences: pod.OwnerReferences, + }, + } + op, err = s.ops.Create(op) + if err != nil { + return nil, err + } + + if err := s.createRoleAndRoleBindings(op, user.GetName()); err != nil { + return nil, err + } + + op.Status = status + return s.ops.UpdateStatus(op) +} + +// createRoleAndRoleBindings creates a role that applies to the given catalog.Operation and +// creates a role binding that applies the rule to the given user +func (s *Operations) createRoleAndRoleBindings(op *catalog.Operation, user string) error { + ownerRef := metav1.OwnerReference{ + APIVersion: op.APIVersion, + Kind: op.Kind, + Name: op.Name, + UID: op.UID, + } + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(op.GetName(), user, "role"), + Namespace: op.Namespace, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"get"}, + Resources: []string{"operations"}, + APIGroups: []string{"catalog.cattle.io"}, + ResourceNames: []string{op.Name}, + }, + }, + } + + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(op.GetName(), user, "rolebinding"), + Namespace: op.Namespace, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + }, + Subjects: []rbacv1.Subject{ + { + APIGroup: rbacv1.GroupName, + Kind: rbacv1.UserKind, + Name: user, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: role.Name, + }, + } + + if _, err := s.roles.Create(role); err != nil { + return err + } + + if _, err := s.roleBindings.Create(roleBinding); err != nil { + return err + } + + return nil +} + +// createNamespace creates a new k8s namespace and returns its object. +// It can also set the field.cattle.io/projectId annotation on the namespace if a non-empty projectID is provided. +// It creates a watch on the namespace and waits for the v3.ProjectConditionInitialRolesPopulated condition +// If the condition is not met within 30 seconds, it returns an error +func (s *Operations) createNamespace(ctx context.Context, namespace, projectID string) (*v1.Namespace, error) { + apiContext := types.GetAPIContext(ctx) + client, err := s.cg.K8sInterface(apiContext) + if err != nil { + return nil, err + } + + annotations := map[string]string{} + if projectID != "" { + annotations["field.cattle.io/projectId"] = strings.ReplaceAll(projectID, "/", ":") + } + // We just always try to create an ignore the error. This is because you might have create but not get privileges + _, _ = client.CoreV1().Namespaces().Create(ctx, &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Annotations: annotations, + }, + }, metav1.CreateOptions{}) + + if projectID == "" { + return client.CoreV1().Namespaces().Get(ctx, namespace, metav1.GetOptions{}) + } + + adminClient, err := s.cg.AdminK8sInterface() + if err != nil { + return nil, err + } + + w, err := adminClient.CoreV1().Namespaces().Watch(ctx, metav1.ListOptions{ + FieldSelector: "metadata.name=" + namespace, + TimeoutSeconds: &thirty, + }) + if err != nil { + return nil, err + } + + defer func() { + w.Stop() + // no clue if this needed, but I'm afraid there will be a stuck producer + for range w.ResultChan() { + } + }() + + for event := range w.ResultChan() { + if ns, ok := event.Object.(*v1.Namespace); ok { + if ok, err := namespaces.IsNamespaceConditionSet(ns, string(v3.ProjectConditionInitialRolesPopulated), true); err != nil { + return ns, err + } else if ok { + return ns, nil + } + } + } + + return nil, fmt.Errorf("failed to wait for roles to be populated") +} + +// createPod creates the struct of the pod for the operation to run in. It also mounts a secret with the secretdata provided. +// If imageOverride is provided, it will override the default value of settings.FullShellImage. +// The created pod has default tolerations and node selectors. +// If the kustomize flag is true, the created pod is modified to be able to run the kustomize.sh script. +// Returns a pod object and a pod options object representing the helm operation pod and it's options +func (s *Operations) createPod(secretData map[string][]byte, kustomize bool, imageOverride string) (*v1.Pod, *podimpersonation.PodOptions) { + image := imageOverride + if image == "" { + image = settings.FullShellImage() + } + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "helm-operation-", + Namespace: s.namespace, + }, + Data: secretData, + } + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "helm-operation-", + Namespace: s.namespace, + }, + Spec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: "data", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: "helm-operation-", + }, + }, + }, + }, + TerminationGracePeriodSeconds: new(int64), + RestartPolicy: v1.RestartPolicyNever, + NodeSelector: map[string]string{ + "kubernetes.io/os": "linux", + }, + Tolerations: []v1.Toleration{ + { + Key: "cattle.io/os", + Operator: corev1.TolerationOpEqual, + Value: "linux", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/controlplane", + Operator: corev1.TolerationOpEqual, + Value: "true", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/etcd", + Operator: corev1.TolerationOpEqual, + Value: "true", + Effect: "NoExecute", + }, + { + Key: "node.cloudprovider.kubernetes.io/uninitialized", + Operator: corev1.TolerationOpEqual, + Value: "true", + Effect: "NoSchedule", + }, + }, + Containers: []v1.Container{ + { + Name: "helm", + Env: []v1.EnvVar{ + { + Name: "KUBECONFIG", + Value: "/home/shell/.kube/config", + }, + }, + Stdin: true, + TTY: true, + StdinOnce: true, + Image: image, + ImagePullPolicy: v1.PullIfNotPresent, + Command: []string{"helm-cmd"}, + WorkingDir: helmDataPath, + VolumeMounts: []v1.VolumeMount{ + { + Name: "data", + MountPath: helmDataPath, + ReadOnly: true, + }, + }, + }, + }, + }, + } + + // if kustomize is false then helmDataPath is an acceptable path for helm to run. If it is true, + // files are copied from helmDataPath to helmRunPath. This is because the kustomize.sh script + // needs write permissions but volumes using a SecretVolumeSource are readOnly. This can not be + // changed with the readOnly field or the defaultMode field. + // See: https://github.com/kubernetes/kubernetes/issues/62099. + if kustomize { + pod.Spec.Volumes = append(pod.Spec.Volumes, v1.Volume{ + Name: "helm-run", + VolumeSource: v1.VolumeSource{ + EmptyDir: &v1.EmptyDirVolumeSource{}, + }, + }) + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, v1.VolumeMount{ + Name: "helm-run", + MountPath: helmRunPath, + }) + pod.Spec.Containers[0].Lifecycle = &v1.Lifecycle{ + PostStart: &v1.LifecycleHandler{ + Exec: &v1.ExecAction{ + Command: []string{"/bin/sh", "-c", fmt.Sprintf("cp -r %s/. %s", helmDataPath, helmRunPath)}, + }, + }, + } + pod.Spec.Containers[0].WorkingDir = helmRunPath + } + return pod, &podimpersonation.PodOptions{ + SecretsToCreate: []*v1.Secret{ + secret, + }, + ImageOverride: imageOverride, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation_test.go new file mode 100644 index 0000000..7f85ab7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/helmop/operation_test.go @@ -0,0 +1,112 @@ +package helmop + +import ( + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +type testCase struct { + commands Commands + expected map[string][]byte + failMsg string +} + +func Test_Render(t *testing.T) { + asserts := assert.New(t) + + testCases := []testCase{ + { + commands: Commands{ + Command{ + Operation: "upgrade", + ChartFile: "test-chart-v1.1.0.tgz", + Chart: []byte("test-chart"), + Kustomize: true, + ReleaseName: "test1", + }, + }, + expected: map[string][]byte{ + "operation000": []byte(strings.Join([]string{"upgrade", "--post-renderer=/home/shell/kustomize.sh", "test1", "/home/shell/helm-run/test-chart-v1.1.0.tgz"}, "\x00")), + "kustomization000.yaml": []byte(fmt.Sprintf(kustomization, "000")), + "transform000.yaml": []byte(fmt.Sprintf(transform, "test1")), + "test-chart-v1.1.0.tgz": []byte("test-chart"), + }, + failMsg: "kustomize enabled test case failed", + }, + { + commands: Commands{ + Command{ + Operation: "upgrade", + ValuesFile: "values-test-chart-v1.1.0.yaml", + Values: []byte("{\"a\":\"a\"}"), + ChartFile: "test-chart-v1.1.0.tgz", + Chart: []byte("test-chart"), + Kustomize: false, + ReleaseName: "test2", + }, + }, + expected: map[string][]byte{ + "operation000": []byte(strings.Join([]string{"upgrade", "--values=/home/shell/helm/values-test-chart-v1.1.0.yaml", "test2", "/home/shell/helm/test-chart-v1.1.0.tgz"}, "\x00")), + "test-chart-v1.1.0.tgz": []byte("test-chart"), + "values-test-chart-v1.1.0.yaml": []byte("{\"a\":\"a\"}"), + }, + failMsg: "values yaml test case failed", + }, + { + commands: Commands{ + Command{ + Operation: "upgrade", + ChartFile: "test-chart-v1.1.0.tgz", + Chart: []byte("test-chart"), + Kustomize: false, + ReleaseName: "test3", + }, + }, + expected: map[string][]byte{ + "operation000": []byte(strings.Join([]string{"upgrade", "test3", "/home/shell/helm/test-chart-v1.1.0.tgz"}, "\x00")), + "test-chart-v1.1.0.tgz": []byte("test-chart"), + }, + failMsg: "default test case failed", + }, + { + commands: Commands{ + Command{ + Operation: "install", + ChartFile: "test-chart-v1.1.0.tgz", + Chart: []byte("test-chart"), + Kustomize: false, + ReleaseName: "test4", + }, + }, + expected: map[string][]byte{ + "operation000": []byte(strings.Join([]string{"install", "test4", "/home/shell/helm/test-chart-v1.1.0.tgz"}, "\x00")), + "test-chart-v1.1.0.tgz": []byte("test-chart"), + }, + failMsg: "install test case failed", + }, + { + commands: Commands{ + Command{ + Operation: "uninstall", + ChartFile: "test-chart-v1.1.0.tgz", + Chart: []byte("test-chart"), + Kustomize: false, + ReleaseName: "test5", + }, + }, + expected: map[string][]byte{ + "operation000": []byte(strings.Join([]string{"uninstall", "test5", "/home/shell/helm/test-chart-v1.1.0.tgz"}, "\x00")), + "test-chart-v1.1.0.tgz": []byte("test-chart"), + }, + failMsg: "uninstall test case failed", + }, + } + for _, testCase := range testCases { + actual, err := testCase.commands.Render() + asserts.Nil(err, "error encountered: %v", err) + asserts.Equal(testCase.expected, actual, testCase.failMsg) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client.go new file mode 100644 index 0000000..5d5069d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client.go @@ -0,0 +1,137 @@ +package http + +import ( + "crypto/tls" + "crypto/x509" + "net" + "net/http" + "net/url" + "strings" + "time" + + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +func HelmClient(secret *corev1.Secret, caBundle []byte, insecureSkipTLSVerify bool, disableSameOriginCheck bool, repoURL string) (*http.Client, error) { + var ( + username string + password string + tlsConfig tls.Config + ) + + if secret != nil { + switch secret.Type { + case corev1.SecretTypeBasicAuth: + username = string(secret.Data[corev1.BasicAuthUsernameKey]) + password = string(secret.Data[corev1.BasicAuthPasswordKey]) + case corev1.SecretTypeTLS: + cert, err := tls.X509KeyPair(secret.Data[corev1.TLSCertKey], secret.Data[corev1.TLSPrivateKeyKey]) + if err != nil { + return nil, err + } + tlsConfig.Certificates = append(tlsConfig.Certificates, cert) + } + } + + if len(caBundle) > 0 { + cert, err := x509.ParseCertificate(caBundle) + if err != nil { + return nil, err + } + pool, err := x509.SystemCertPool() + if err != nil { + logrus.Debugf("getting system cert pool failed with %v", err) + pool = x509.NewCertPool() + } + pool.AddCert(cert) + tlsConfig.RootCAs = pool + } + + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tlsConfig + transport.TLSClientConfig.InsecureSkipVerify = insecureSkipTLSVerify + + client := &http.Client{ + Transport: transport, + Timeout: 30 * time.Second, + } + if username != "" || password != "" { + client.Transport = &basicRoundTripper{ + username: username, + password: password, + disableSameOriginCheck: disableSameOriginCheck, + repoURL: repoURL, + next: client.Transport, + } + } + + return client, nil +} + +type basicRoundTripper struct { + username string + password string + disableSameOriginCheck bool + repoURL string + next http.RoundTripper +} + +func (b *basicRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { + attachHeader, err := shouldAttachBasicAuthHeader(b.repoURL, b.disableSameOriginCheck, request) + if err != nil { + return nil, err + } + if attachHeader { + request.SetBasicAuth(b.username, b.password) + } + return b.next.RoundTrip(request) +} + +// Return bool for if the Basic Auth Header should be attached to the request +func shouldAttachBasicAuthHeader(repoURL string, disableSameOriginCheck bool, request *http.Request) (bool, error) { + if disableSameOriginCheck { + return true, nil + } + parsedRepoURL, err := url.Parse(repoURL) + if err != nil { + return false, err + } + // check to see if request is being made to the same domain or subdomain as the repo url + // to determine if it is the same origin, if it is not, then do not attach the auth header + return isDomainOrSubdomain(request.URL, parsedRepoURL), nil +} + +// Using isDomainOrSubdomain from http.client go library +// this is to ensure that we are using as close to the upstream as possible for same origin checks +func isDomainOrSubdomain(reqURL, repoURL *url.URL) bool { + parent := canonicalAddr(repoURL) + sub := canonicalAddr(reqURL) + if sub == parent { + return true + } + // If sub is "foo.example.com" and parent is "example.com", + // that means sub must end in "."+parent. + // Do it without allocating. + if !strings.HasSuffix(sub, parent) { + return false + } + return sub[len(sub)-len(parent)-1] == '.' +} + +// Using canonicalAddr from http.client go library +// canonicalAddr returns url.Host but always with a ":port" suffix +// the idnaASCII checks have been removed +func canonicalAddr(url *url.URL) string { + var portMap = map[string]string{ + "http": "80", + "https": "443", + "socks5": "1080", + } + addr := url.Hostname() + port := url.Port() + if port == "" { + port = portMap[url.Scheme] + } + return net.JoinHostPort(addr, port) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client_test.go new file mode 100644 index 0000000..d44c78a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/client_test.go @@ -0,0 +1,340 @@ +package http + +import ( + "net/http" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAttachBasicAuthHeader(t *testing.T) { + tests := []struct { + testName string + disableSameOriginCheck bool + resourcePath string + repositoryURL string + requestURL string + redirectStatusCode int + redirectURL string + expectedPass bool + }{ + { + "Download index.yaml from repository with disableSameOriginCheck=false", + false, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download index.yaml from repository with disableSameOriginCheck=true", + true, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download index.yaml from repository with redirect to sub domain with disableSameOriginCheck=false", + false, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://storage.charts.rancher.io/repository", + true, + }, + { + "Download index.yaml from repository with redirect to sub domain with disableSameOriginCheck=true", + true, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 308, + "https://storage.charts.rancher.io/repository", + true, + }, + { + "Download index.yaml from different origin url redirect with redirect with disableSameOriginCheck=false", + false, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.io/repository", + false, + }, + { + "Download index.yaml from different origin url redirect with redirect with disableSameOriginCheck=true", + true, + "/index.yaml", + "https://charts.rancher.io", + "https://charts.rancher.io", + 308, + "https://blobstorage.io/repository", + true, + }, + { + "Download chart from repository with disableSameOriginCheck=false", + false, + "/assets/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download chart from repository with disableSameOriginCheck=true", + true, + "/assets/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download chart from repository with redirect to sub domain with disableSameOriginCheck=false", + false, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.charts.rancher.io/repository", + true, + }, + { + "Download chart from repository with redirect to sub domain with disableSameOriginCheck=true", + true, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.charts.rancher.io/repository", + true, + }, + { + "Download chart from different origin url redirect with disableSameOriginCheck=false", + false, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.io/repository", + false, + }, + { + "Download chart from different origin url redirect with disableSameOriginCheck=true", + true, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.io/repository", + true, + }, + { + "Download chart from different origin url with disableSameOriginCheck=false", + false, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://localhost.charts.io/repository", + 200, + "", + false, + }, + { + "Download chart from different origin url with disableSameOriginCheck=true", + true, + "/_blob/nginx-sample-1.1.0.tgz", + "https://charts.rancher.io", + "https://localhost.charts.io/repository", + 200, + "", + true, + }, + { + "Download icon from repository with disableSameOriginCheck=false", + false, + "/assets/logos/fleet.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download icon from repository with disableSameOriginCheck=true", + true, + "/assets/logos/fleet.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 200, + "", + true, + }, + { + "Download icon from repository with redirect to sub domain with disableSameOriginCheck=false", + false, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.charts.rancher.io/repository", + true, + }, + { + "Download icon from repository with redirect to sub domain with disableSameOriginCheck=true", + true, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "https://blobstorage.charts.rancher.io/repository", + true, + }, + { + "Download icon from different origin url redirect with disableSameOriginCheck=false", + false, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "http://blobstorage.io/repository", + false, + }, + { + "Download icon from different origin url redirect with disableSameOriginCheck=true", + true, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://charts.rancher.io", + 307, + "http://blobstorage.io/repository", + true, + }, + { + "Download icon from different origin url with disableSameOriginCheck=false", + false, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://cattle.charts.io", + 200, + "", + false, + }, + { + "Download icon from different origin url with disableSameOriginCheck=true", + true, + "/assets/logos/istio.svg", + "https://charts.rancher.io", + "https://charts.cattle.io", + 200, + "", + true, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + parsedRequestURL, err := url.Parse(tt.requestURL + tt.resourcePath) + if err != nil { + t.Errorf("unexpected error: %v", err) + t.FailNow() + } + repositoryRequest := &http.Request{ + URL: parsedRequestURL, + Response: nil, + } + if tt.redirectURL != "" { + resp := &http.Response{ + StatusCode: tt.redirectStatusCode, + } + redirectRequestURL, err := url.Parse(tt.redirectURL + tt.resourcePath) + if err != nil { + t.Errorf("unexpected error: %v", err) + t.FailNow() + } + repositoryRequest.URL = redirectRequestURL + repositoryRequest.Response = resp + } + attachHeader, _ := shouldAttachBasicAuthHeader(tt.repositoryURL, tt.disableSameOriginCheck, repositoryRequest) + assert.Equal(t, tt.expectedPass, attachHeader) + t.Logf("Expected %v, got %v", tt.expectedPass, attachHeader) + }) + } +} + +func TestIsDomainOrSubdomain(t *testing.T) { + tests := []struct { + testName string + repoURL string + requestURL string + expectedPass bool + }{ + { + "exactly matching urls", + "https://charts.rancher.io", + "https://charts.rancher.io", + true, + }, + { + "exactly matching urls with matching paths", + "https://charts.rancher.io/path/here", + "https://charts.rancher.io/path/here", + true, + }, + { + "matching domains, but mismatch schema", + "https://charts.rancher.io", + "http://charts.rancher.io", + false, + }, + { + "matching domains", + "https://123.123.12.1:8443", + "https://123.123.12.1:8443/path/here", + true, + }, + { + "sub domain does not match, but domains match", + "https://rancher.io", + "https://assets.rancher.io", + true, + }, + { + "mismatch domains", + "https://charts.rancher.io", + "https://other.rancher.io", + false, + }, + { + "no matching urls", + "https://rancher.com", + "https://assets.rancher.io", + false, + }, + } + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + repoURL, err := url.Parse(tt.repoURL) + if err != nil { + t.Errorf("unexpected error: %v", err) + t.FailNow() + } + reqURL, err := url.Parse(tt.requestURL) + if err != nil { + t.Errorf("unexpected error: %v", err) + t.FailNow() + } + isSubDomainOrDomain := isDomainOrSubdomain(reqURL, repoURL) + assert.Equal(t, tt.expectedPass, isSubDomainOrDomain) + t.Logf("Expected %v, got %v", tt.expectedPass, isSubDomainOrDomain) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/download.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/download.go new file mode 100644 index 0000000..ed80950 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/http/download.go @@ -0,0 +1,157 @@ +package http + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "path" + "strings" + "time" + + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + + "sigs.k8s.io/yaml" + + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" +) + +func Icon(secret *corev1.Secret, repoURL string, caBundle []byte, insecureSkipTLSVerify bool, disableSameOriginCheck bool, chart *repo.ChartVersion) (io.ReadCloser, string, error) { + if len(chart.URLs) == 0 { + return nil, "", fmt.Errorf("failed to find chartName %s version %s: %w", chart.Name, chart.Version, validation.NotFound) + } + + client, err := HelmClient(secret, caBundle, insecureSkipTLSVerify, disableSameOriginCheck, repoURL) + client.Timeout = 2 * time.Second + if err != nil { + return nil, "", err + } + defer client.CloseIdleConnections() + + u, err := url.Parse(chart.Icon) + if err != nil { + return nil, "", err + } + if !u.IsAbs() { + base, err := url.Parse(repoURL) + if err != nil { + return nil, "", err + } + base.Path = strings.TrimSuffix(base.Path, "/") + "/" + u = base.ResolveReference(u) + u.RawQuery = base.RawQuery + } + + resp, err := client.Get(u.String()) + if err != nil { + return nil, "", err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + defer ioutil.ReadAll(resp.Body) + return nil, "", validation.ErrorCode{ + Status: resp.StatusCode, + } + } + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, "", err + } + return ioutil.NopCloser(bytes.NewBuffer(data)), path.Ext(u.Path), nil +} + +func Chart(secret *corev1.Secret, repoURL string, caBundle []byte, insecureSkipTLSVerify bool, disableSameOriginCheck bool, chart *repo.ChartVersion) (io.ReadCloser, error) { + if len(chart.URLs) == 0 { + return nil, fmt.Errorf("failed to find chartName %s version %s: %w", chart.Name, chart.Version, validation.NotFound) + } + + client, err := HelmClient(secret, caBundle, insecureSkipTLSVerify, disableSameOriginCheck, repoURL) + if err != nil { + return nil, err + } + defer client.CloseIdleConnections() + + u, err := url.Parse(chart.URLs[0]) + if err != nil { + return nil, err + } + if !u.IsAbs() { + base, err := url.Parse(repoURL) + if err != nil { + return nil, err + } + // Prevent ResolveReference from stripping the last element + // of the path by ensuring it has a trailing slash + base.Path = strings.TrimSuffix(base.Path, "/") + "/" + u = base.ResolveReference(u) + // Retain the query string of the repository URL as it might + // contain an access credential. + u.RawQuery = base.RawQuery + } + + resp, err := client.Get(u.String()) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + data, err := ioutil.ReadAll(resp.Body) + return ioutil.NopCloser(bytes.NewBuffer(data)), err +} + +func DownloadIndex(secret *corev1.Secret, repoURL string, caBundle []byte, insecureSkipTLSVerify bool, disableSameOriginCheck bool) (*repo.IndexFile, error) { + client, err := HelmClient(secret, caBundle, insecureSkipTLSVerify, disableSameOriginCheck, repoURL) + if err != nil { + return nil, err + } + defer client.CloseIdleConnections() + + parsedURL, err := url.Parse(repoURL) + if err != nil { + return nil, err + } + + parsedURL.RawPath = path.Join(parsedURL.RawPath, "index.yaml") + parsedURL.Path = path.Join(parsedURL.Path, "index.yaml") + + url := parsedURL.String() + logrus.Infof("Downloading repo index from %s", url) + + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + req.Header.Set("X-Install-Uuid", settings.InstallUUID.Get()) + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + bytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + // Marshall to file to ensure it matches the schema and this component doesn't just + // become a "fetch any file" service. + index := &repo.IndexFile{} + if err := yaml.Unmarshal(bytes, index); err != nil { + logrus.Errorf("failed to unmarshal %s: %v", url, err) + return nil, fmt.Errorf("failed to parse response from %s", url) + } + + if index.APIVersion == "" { + return nil, repo.ErrNoAPIVersion + } + + return index, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client.go new file mode 100644 index 0000000..60d0b87 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client.go @@ -0,0 +1,99 @@ +package capturewindowclient + +import ( + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/sirupsen/logrus" +) + +const ( + RateLimitRemainingHeader = "RateLimit-Remaining" + RetryAfterHeader = "Retry-After" + TimeWindowPrefix = "w=" +) + +// Transport is an HTTP transport with capturing duration to wait when 429 is returned by the server. +type Transport struct { + // Base is the underlying HTTP transport to use. + // If nil, http.DefaultTransport is used for round trips. + Base http.RoundTripper + + // BackOffDuration is used as a duration to wait for by the + // OCI handler until the next retry to make a call to the OCI registry. + BackOffDuration float64 +} + +// NewTransport creates an HTTP Transport with the ability to store duration to wait when 429 is returned by the server. +func NewTransport(base http.RoundTripper) *Transport { + return &Transport{ + Base: base, + } +} + +// RoundTrip executes a single HTTP transaction, returning a Response for the +// provided Request and it captures the duration to wait until the server unblocks +// the user to make more requests. It checks the headers to capture the duration. +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + resp, respErr := t.Base.RoundTrip(req) + // If we hit 429 status code, try to capture the duration using available headers. + if resp != nil && resp.StatusCode == http.StatusTooManyRequests { + // Case 1: Check if RateLimit-Remaining header is present and get value from it. + if v := resp.Header.Get(RateLimitRemainingHeader); v != "" { + timeWindow, err := decodeTimeFromHeaderValue(v) + if err != nil { + logrus.Error("error:", err) + return resp, respErr + } + t.BackOffDuration = timeWindow + // Case 2: Check if Retry-After header is present and get value from it. + } else if v := resp.Header.Get(RetryAfterHeader); v != "" { + retryAfter, err := strconv.ParseInt(v, 10, 64) + if err != nil { + logrus.Error("error:", err) + return resp, respErr + } + t.BackOffDuration = float64(retryAfter) + } else { + // Case 3: Dockerhub: It sends duration information when a HEAD call is made to the manifest. + URL := fmt.Sprintf("%s://%s%s", req.URL.Scheme, req.Host, req.URL.Path) + headRequest, err := http.NewRequest(http.MethodHead, URL, nil) + if err != nil { + logrus.Errorf("oci: failed to create a head request to %s:%v", URL, err) + return resp, respErr + } + headRequest.Header.Add("Authorization", req.Header.Get("Authorization")) + headResponse, err := t.Base.RoundTrip(headRequest) + if err != nil { + logrus.Errorf("oci: failed to make a head request to %s:%v", URL, err) + return resp, respErr + } + + // Decode the time window + headerValue := headResponse.Header.Get(RateLimitRemainingHeader) + if headerValue != "" { + timeWindow, err := decodeTimeFromHeaderValue(headerValue) + if err != nil { + logrus.Error("error:", err) + return resp, respErr + } + t.BackOffDuration = timeWindow + } + } + } + + return resp, respErr +} + +// decodeTimeFromHeaderValue decodes the time window from the header value. +func decodeTimeFromHeaderValue(value string) (float64, error) { + newValue := strings.Replace(value, TimeWindowPrefix, "", 2) + splitValue := strings.Split(newValue, ";") + if len(splitValue) > 1 { + remainingCount, err := strconv.ParseFloat(splitValue[1], 64) + return remainingCount, err + } + return 0.0, fmt.Errorf("the format of ratelimited header is wrong %s", value) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client_test.go new file mode 100644 index 0000000..7663543 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/capturewindowclient/client_test.go @@ -0,0 +1,161 @@ +package capturewindowclient + +import ( + "bytes" + "net/http" + "net/http/httptest" + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func Test_RoundTrip(t *testing.T) { + type testcase struct { + name string + expectedErr string + headervalue string + backOffDuration float64 + retryHeader bool + } + + testCase1 := testcase{ + name: "sets backoff duration when response status code is 429 with header", + headervalue: "0;w=100", + backOffDuration: 100, + expectedErr: "", + retryHeader: false, + } + testCase2 := testcase{ + name: "doesn't set backoff duration when response status code is 429 with header value empty", + headervalue: "", + backOffDuration: 0.0, + expectedErr: "", + retryHeader: false, + } + testCase3 := testcase{ + name: "return error when invalid header value present", + headervalue: "w=121", + backOffDuration: 0.0, + expectedErr: "the format of ratelimited header is wrong", + retryHeader: false, + } + testCase4 := testcase{ + name: "sets backoff duration when response status code is 429 with retry after header", + headervalue: "123", + backOffDuration: 123, + expectedErr: "", + retryHeader: true, + } + + testCases := []testcase{ + testCase1, + testCase2, + testCase3, + testCase4, + } + + assert := assert.New(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var buf bytes.Buffer + logrus.SetOutput(&buf) + + // Create a test server that returns a 429 response with the RateLimit-Remaining header set to 0 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if tc.retryHeader { + w.Header().Set(RetryAfterHeader, tc.headervalue) + } else { + w.Header().Set(RateLimitRemainingHeader, tc.headervalue) + } + w.WriteHeader(http.StatusTooManyRequests) + })) + defer server.Close() + + transport := NewTransport(server.Client().Transport) + + // Create a request to be sent using the Transport + req, err := http.NewRequest(http.MethodGet, server.URL, nil) + assert.Nil(err) + + // Send the request using the Transport + resp, err := transport.RoundTrip(req) + assert.Equal(http.StatusTooManyRequests, resp.StatusCode) + assert.Equal(tc.backOffDuration, transport.BackOffDuration) + if tc.expectedErr != "" { + assert.Contains(buf.String(), tc.expectedErr) + } else { + assert.Nil(err) + } + }) + } +} + +func Test_RoundTripHeadRequest(t *testing.T) { + type testcase struct { + name string + expectedErr string + headervalue string + backOffDuration float64 + } + + testCase1 := testcase{ + name: "sets backoff duration when response status code is 429 with head request header", + headervalue: "0;w=200", + backOffDuration: 200, + expectedErr: "", + } + testCase2 := testcase{ + name: "return error when invalid header value present", + headervalue: "w=121", + backOffDuration: 0.0, + expectedErr: "the format of ratelimited header is wrong", + } + testCase3 := testcase{ + name: "doesn't set backoff duration when response status code is 429 with header value empty", + headervalue: "", + backOffDuration: 0.0, + expectedErr: "", + } + + testCases := []testcase{ + testCase1, + testCase2, + testCase3, + } + + assert := assert.New(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var buf bytes.Buffer + logrus.SetOutput(&buf) + + // Create a test server that returns a 429 response with the RateLimit-Remaining header set to 0 + server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet { + w.WriteHeader(http.StatusTooManyRequests) + } else if r.Method == http.MethodHead { + w.Header().Set(RateLimitRemainingHeader, tc.headervalue) + w.WriteHeader(http.StatusTooManyRequests) + } + })) + defer server.Close() + + transport := NewTransport(server.Client().Transport) + + // Create a request to be sent using the Transport + req, err := http.NewRequest(http.MethodGet, server.URL, nil) + assert.Nil(err) + + // Make the request using the Transport + resp, err := transport.RoundTrip(req) + assert.Equal(http.StatusTooManyRequests, resp.StatusCode) + assert.Equal(tc.backOffDuration, transport.BackOffDuration) + if tc.expectedErr != "" { + assert.Contains(buf.String(), tc.expectedErr) + } else { + assert.Nil(err) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client.go new file mode 100644 index 0000000..d0f6931 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client.go @@ -0,0 +1,336 @@ +package oci + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/json" + "fmt" + "net/http" + "os" + "strings" + "time" + + ocispecv1 "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" + catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/oci/capturewindowclient" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/chart/loader" + helmregistry "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + v1 "k8s.io/api/core/v1" + "k8s.io/helm/pkg/provenance" + "oras.land/oras-go/v2" + "oras.land/oras-go/v2/content" + "oras.land/oras-go/v2/content/memory" + "oras.land/oras-go/v2/registry" + "oras.land/oras-go/v2/registry/remote" + "oras.land/oras-go/v2/registry/remote/auth" + "oras.land/oras-go/v2/registry/remote/errcode" +) + +// maxHelmChartTar defines what is the max size of helm chart we support. +const maxHelmChartTarSize int64 = 20 * 1024 * 1024 // 20 MiB + +// Client is an OCI client that manages Helm charts in OCI based Helm registries. +type Client struct { + // URL refers to the OCI url provided by the user ie. dp.apps.rancher.io/charts/etcd:1.0.2 + URL string + // registry is the registry part of the URL ie. dp.apps.rancher.io + registry string + // repository is the repository part of the URL ie. charts/etcd + repository string + // tag is the tag part of the URL ie. 1.0.2 + tag string + + HTTPClient http.Client + insecure bool + caBundle []byte + insecurePlainHTTP bool + exponentialBackOffValues *catalogv1.ExponentialBackOffValues + + username string + password string +} + +// NewClient returns a new Client along with parsing +// the URL provided and fetching the credentials. +func NewClient(url string, clusterRepoSpec catalogv1.RepoSpec, credentialSecret *v1.Secret) (*Client, error) { + ociClient := &Client{ + URL: url, + insecure: clusterRepoSpec.InsecureSkipTLSverify, + caBundle: clusterRepoSpec.CABundle, + insecurePlainHTTP: clusterRepoSpec.InsecurePlainHTTP, + exponentialBackOffValues: clusterRepoSpec.ExponentialBackOffValues, + } + + err := ociClient.parseURL() + if err != nil { + return nil, err + } + + if credentialSecret != nil { + if credentialSecret.Type != v1.SecretTypeBasicAuth { + return nil, fmt.Errorf("only basic auth credential is supported") + } + + username, password := string(credentialSecret.Data[v1.BasicAuthUsernameKey]), string(credentialSecret.Data[v1.BasicAuthPasswordKey]) + if len(password) == 0 || len(username) == 0 { + return nil, fmt.Errorf("username or password is empty") + } + ociClient.username = username + ociClient.password = password + } + + err = ociClient.SetAuthClient() + if err != nil { + return nil, err + } + + return ociClient, nil +} + +// parseURL parses the provided OCI URL into sub +// parts such as registry, repository and tag. +func (o *Client) parseURL() error { + // Remove any slash at the end of the URL + url := strings.TrimSuffix(o.URL, "/") + + // Remove the oci scheme from the start of the URL + url = strings.TrimPrefix(url, "oci://") + + // If the URL contains a slash, then it must have a repository and/or tag + if strings.Contains(url, "/") { + var ref registry.Reference + ref, err := registry.ParseReference(url) + if err != nil { + return fmt.Errorf("failed to parse OCI URL '%s' value: %w", o.URL, err) + } + + o.registry = ref.Registry + o.repository = ref.Repository + o.tag = ref.Reference + + // If the URL doesn't contain any slash, then it must have only the registry part of it. + } else { + o.registry = url + } + + return nil +} + +// fetchChart fetchs the chart specified by the oras repository. It first downloads it into the +// oras memory and then saves it into a file and returns the file path. +func (o *Client) fetchChart(orasRepository *remote.Repository) (string, error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ociURL := fmt.Sprintf("%s/%s:%s", o.registry, o.repository, o.tag) + + // Create an oras memory to copy the oci artifact into. + memoryStore := memory.New() + manifest, err := oras.Copy(ctx, orasRepository, o.tag, memoryStore, "", oras.CopyOptions{ + CopyGraphOptions: oras.CopyGraphOptions{ + PreCopy: func(ctx context.Context, desc ocispecv1.Descriptor) error { + // Download only helm chart related descriptors. + if desc.MediaType == ocispecv1.MediaTypeImageManifest || + desc.MediaType == helmregistry.ChartLayerMediaType { + // We cannot load huge amounts of data into the memory + // and so we are defining a limit before fetching. + if desc.Size > maxHelmChartTarSize { + return fmt.Errorf("the oci artifact %s:%s has size more than %d which is not supported", o.repository, o.tag, maxHelmChartTarSize) + } + return nil + } + + return oras.SkipNode + }, + }, + }) + if err != nil { + return "", fmt.Errorf("unable to oras copy the remote oci artifact %s: %w", ociURL, err) + } + + // Helm codebase sets oci artifacts manifest mediatype as ocispecv1.MediaTypeImageManifest + // https://github.com/oras-project/oras-go/blob/v1/pkg/content/manifest.go#L89C22-L89C44 referenced by helm codebase + if manifest.MediaType != ocispecv1.MediaTypeImageManifest { + return "", fmt.Errorf("the oci artifact %s is not a helm chart. The OCI URL must contain only helm charts", ociURL) + } + + // Fetch the manifest blob of the oci artifact + manifestblob, err := content.FetchAll(ctx, memoryStore, manifest) + if err != nil { + return "", fmt.Errorf("unable to fetch the manifest blob of %s: %w", ociURL, err) + } + var manifestJSON ocispecv1.Manifest + err = json.Unmarshal(manifestblob, &manifestJSON) + if err != nil { + return "", fmt.Errorf("unable to unmarshal manifest blob of %s: %w", ociURL, err) + } + + // Create a temp file to store the helm chart tar + tempFile, err := os.CreateTemp("", "helm-") + if err != nil { + return "", fmt.Errorf("unable to create temp file for storing the oci artifact") + } + + // Checking if the OCI artifact is of type helm config ? + if manifestJSON.ArtifactType == helmregistry.ConfigMediaType || manifestJSON.Config.MediaType == helmregistry.ConfigMediaType { + // find the layer of helm chart type and fetch it + for _, layer := range manifestJSON.Layers { + if layer.MediaType == helmregistry.ChartLayerMediaType { + chartTar, err := content.FetchAll(ctx, memoryStore, layer) + if err != nil { + return "", fmt.Errorf("unable to fetch chart blob of %s: %w", ociURL, err) + } + + err = os.WriteFile(tempFile.Name(), chartTar, 0o600) + if err != nil { + return "", fmt.Errorf("unable to write chart %s into file %s: %w", ociURL, tempFile.Name(), err) + } + + return tempFile.Name(), nil + } + } + } + + return tempFile.Name(), fmt.Errorf("the oci artifact %s is not a helm chart. The OCI URL must contain only helm charts", ociURL) +} + +// getAuthClient creates an oras auth client that can be used +// in creating an oras registry client or oras repository client. +func (o *Client) SetAuthClient() error { + config := &tls.Config{ + InsecureSkipVerify: o.insecure, + } + if len(o.caBundle) > 0 { + cert, err := x509.ParseCertificate(o.caBundle) + if err != nil { + return err + } + pool, err := x509.SystemCertPool() + if err != nil { + logrus.Debugf("getting system cert pool failed: %v", err) + pool = x509.NewCertPool() + } + pool.AddCert(cert) + + config.RootCAs = pool + } + baseTransport := http.DefaultTransport.(*http.Transport).Clone() + baseTransport.TLSClientConfig = config + + o.HTTPClient = http.Client{ + Transport: capturewindowclient.NewTransport(baseTransport), + } + + return nil +} + +// GetOrasRegistry returns the oras registry client along with +// setting credentials to authenticate with the registry. +func (o *Client) GetOrasRegistry() (*remote.Registry, error) { + orasRegistry, err := remote.NewRegistry(o.registry) + if err != nil { + return nil, err + } + orasRegistry.PlainHTTP = o.insecurePlainHTTP + + orasRegistry.Client = &auth.Client{ + Credential: func(ctx context.Context, reg string) (auth.Credential, error) { + return auth.Credential{ + Username: o.username, + Password: o.password, + }, nil + }, + Client: &o.HTTPClient, + } + + return orasRegistry, nil +} + +// GetOrasRepository returns the oras repository client along with +// setting credentials to authenticate with the registry/repository. +func (o *Client) GetOrasRepository() (*remote.Repository, error) { + orasRepository, err := remote.NewRepository(fmt.Sprintf("%s/%s", o.registry, o.repository)) + if err != nil { + return nil, err + } + orasRepository.PlainHTTP = o.insecurePlainHTTP + + orasRepository.Client = &auth.Client{ + Credential: func(ctx context.Context, reg string) (auth.Credential, error) { + return auth.Credential{ + Username: o.username, + Password: o.password, + }, nil + }, + Client: &o.HTTPClient, + } + + return orasRepository, nil +} + +// addToIndex adds the given helm chart entry into the helm repo index provided. +func (o *Client) addToIndex(indexFile *repo.IndexFile, chartTarFilePath string) error { + // Load the Chart into chart golang struct. + chart, err := loader.Load(chartTarFilePath) + if err != nil { + return fmt.Errorf("failed to load the chart %s: %w", chartTarFilePath, err) + } + + // Generate the digest of the chart. + digest, err := provenance.DigestFile(chartTarFilePath) + if err != nil { + return fmt.Errorf("failed to generate digest for chart %s: %w", chart.Metadata.Name, err) + } + + // Add the helm chart to the indexfile. + err = indexFile.MustAdd(chart.Metadata, fmt.Sprintf("oci://%s/%s:%s", o.registry, o.repository, o.tag), "", digest) + if err != nil { + return fmt.Errorf("failed to add entry %s to indexfile: %w", chart.Metadata.Name, err) + } + + // For OCI repositories, the created date is not exposed and so Helm library defaults to time.Now() + // This is misleading and so emptying the created date field + indexFile.Entries[chart.Metadata.Name][len(indexFile.Entries[chart.Metadata.Name])-1].Created = time.Time{} + + logrus.Debugf("Added chart %s %s to index", chart.Metadata.Name, chart.Metadata.Version) + return nil +} + +// IsOrasRepository checks if the repository is actually an oci artifact or not. +// The check is done by finding tags and if we find tags then it is valid repo. +func (o *Client) IsOrasRepository() (bool, error) { + count := 0 + ociRepo := fmt.Sprintf("%s/%s", o.registry, o.repository) + + if o.repository != "" { + repository, err := o.GetOrasRepository() + if err != nil { + return false, fmt.Errorf("failed to create an oras repository for %s: %w", ociRepo, err) + } + + // Loop over tags function + tagsFunc := func(tags []string) error { + count = len(tags) + return nil + } + + err = repository.Tags(context.Background(), "", tagsFunc) + if err != nil { + if IsErrorCode(err, errcode.ErrorCodeNameUnknown) { + return false, nil + } + return false, err + } + } + + return count != 0, nil +} + +// IsErrorCode returns true if err is an Error and its Code equals to code. +func IsErrorCode(err error, code string) bool { + var ec errcode.Error + return errors.As(err, &ec) && ec.Code == code +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client_test.go new file mode 100644 index 0000000..48b2c20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/client_test.go @@ -0,0 +1,646 @@ +package oci + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + "time" + + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "oras.land/oras-go/v2/registry/remote/auth" +) + +func spinRegistry(layerSize int, chartMediaType, helmManifest bool, testcaseName string, t *testing.T) *httptest.Server { + testingHelmChartPath := "../../../tests/testdata/testingchart-0.1.0.tgz" + helmChartTar, err := os.ReadFile(testingHelmChartPath) + assert.NoError(t, err) + + layerDesc := ocispec.Descriptor{ + MediaType: registry.ChartLayerMediaType, + Digest: digest.FromBytes(helmChartTar), + Size: int64(len(helmChartTar)), + } + if layerSize > 0 { + layerDesc.Size = int64(layerSize) + } + if !chartMediaType { + layerDesc.MediaType = ocispec.MediaTypeImageLayer + } + + configBlob := []byte("config") + configDesc := ocispec.Descriptor{ + MediaType: registry.ConfigMediaType, + Digest: digest.FromBytes(configBlob), + Size: int64(len(configBlob)), + } + + // Modify test data according to the testcase + switch testcaseName { + case "fetches no chart since chart layer is not Helm Chart type": + layerDesc.MediaType = ocispec.MediaTypeImageLayer + } + + manifest := ocispec.Manifest{ + MediaType: ocispec.MediaTypeImageManifest, + Config: configDesc, + Layers: []ocispec.Descriptor{layerDesc}, + } + manifest.Config.MediaType = registry.ConfigMediaType + manifestJSON, err := json.Marshal(manifest) + assert.NoError(t, err) + + manifestDesc := ocispec.Descriptor{ + MediaType: ocispec.MediaTypeImageManifest, + Digest: digest.FromBytes(manifestJSON), + Size: int64(len(manifestJSON)), + } + if !helmManifest { + manifestDesc.MediaType = ocispec.MediaTypeImageIndex + } + manifestCount := 0 + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + switch r.URL.Path { + case "/v2/_catalog": + t := `{"repositories": ["testingchart"]}` + w.Write([]byte(t)) + + case "/v2/testingchart/tags/list": + t := `{"tags": ["0.1.0","0.0.1","sha256"]}` + w.Write([]byte(t)) + case "/v2/testingchart/blobs/" + configDesc.Digest.String(): + t.FailNow() + case "/v2/testingchart/blobs/" + layerDesc.Digest.String(): + http.ServeFile(w, r, testingHelmChartPath) + case "/v2/testingchart/manifests/0.1.0": + manifestCount++ + if manifestCount > 1 { + w.WriteHeader(http.StatusForbidden) + return + } + if accept := r.Header.Get("Accept"); !strings.Contains(accept, manifestDesc.MediaType) { + assert.NoError(t, err) + w.WriteHeader(http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", manifestDesc.MediaType) + w.Header().Set("Docker-Content-Digest", manifestDesc.Digest.String()) + if _, err := w.Write(manifestJSON); err != nil { + assert.NoError(t, err) + } + } + })) + + return ts +} + +func TestNewClient(t *testing.T) { + testCases := []struct { + name string + url string + repoSpec v1.RepoSpec + secret *corev1.Secret + expectedRegistry string + expectedRepository string + expectedTag string + expectedErr error + }{ + { + name: "works with full OCI URL with tag", + url: "oci://example.com/charts/etcd:0.1.1", + repoSpec: v1.RepoSpec{}, + expectedRegistry: "example.com", + expectedRepository: "charts/etcd", + expectedTag: "0.1.1", + expectedErr: nil, + }, + { + name: "works with OCI URL with no tag and two word namespace", + url: "oci://example.com/charts/etcd", + repoSpec: v1.RepoSpec{}, + expectedRegistry: "example.com", + expectedRepository: "charts/etcd", + expectedTag: "", + expectedErr: nil, + }, + { + name: "works with OCI URL with no tag and only single word namespace", + url: "oci://example.com/charts", + repoSpec: v1.RepoSpec{}, + expectedRegistry: "example.com", + expectedRepository: "charts", + expectedTag: "", + expectedErr: nil, + }, + { + name: "works with OCI URL with only registry", + url: "oci://example.com", + repoSpec: v1.RepoSpec{}, + expectedRegistry: "example.com", + expectedRepository: "", + expectedTag: "", + expectedErr: nil, + }, + { + name: "fails with invalid OCI prefix", + url: "oc://example.com", + repoSpec: v1.RepoSpec{}, + expectedErr: errors.New("invalid reference"), + }, + { + name: "fails with invalid OCI URL with double slashes", + url: "oc://example.com//", + repoSpec: v1.RepoSpec{}, + expectedErr: errors.New("invalid reference"), + }, + { + name: "fails with invalid OCI URL with unknown characters", + url: "oc://example.com*)//", + repoSpec: v1.RepoSpec{}, + expectedErr: errors.New("invalid reference"), + }, + { + name: "works fine with basic auth", + repoSpec: v1.RepoSpec{}, + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secretname", + }, + Data: map[string][]byte{ + corev1.BasicAuthUsernameKey: []byte("test"), + corev1.BasicAuthPasswordKey: []byte("test"), + }, + Type: corev1.SecretTypeBasicAuth, + }, + expectedErr: nil, + }, + { + name: "doesn't work fine with invalid auth", + repoSpec: v1.RepoSpec{}, + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secretname", + }, + Data: map[string][]byte{ + corev1.BasicAuthUsernameKey: []byte("test"), + }, + Type: corev1.SecretTypeBasicAuth, + }, + expectedErr: errors.New("username or password is empty"), + }, + { + name: "doesn't work with invalid secret type", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "secretname", + }, + Data: map[string][]byte{ + corev1.BasicAuthUsernameKey: []byte("test"), + }, + }, + expectedErr: errors.New("only basic auth credential is supported"), + }, + { + name: "sets insecure with insecure mentioned", + repoSpec: v1.RepoSpec{ + InsecureSkipTLSverify: true, + }, + secret: nil, + expectedErr: nil, + }, + { + name: "sets insecurePlainHTTP with insecurePlainHTTP set as true", + secret: nil, + expectedErr: nil, + repoSpec: v1.RepoSpec{ + InsecurePlainHTTP: true, + }, + }, + } + + assert := assert.New(t) + for _, tc := range testCases { + ociClient, err := NewClient(tc.url, tc.repoSpec, tc.secret) + + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + + assert.Equal(tc.expectedRegistry, ociClient.registry) + assert.Equal(tc.expectedRepository, ociClient.repository) + assert.Equal(tc.expectedTag, ociClient.tag) + assert.Equal(tc.repoSpec.InsecureSkipTLSverify, ociClient.insecure) + assert.Equal(tc.repoSpec.InsecurePlainHTTP, ociClient.insecurePlainHTTP) + + if tc.secret != nil { + assert.Equal(ociClient.username, "test") + assert.Equal(ociClient.password, "test") + } + } + } +} + +func TestFetchChart(t *testing.T) { + type testcase struct { + name string + expectedErr string + expectedFound bool + expectedFile bool + size int + spinServer bool + helmManifest bool + chartMediaType bool + } + + testCase1 := testcase{ + name: "fetching a chart works fine with a tag", + expectedErr: "", + expectedFound: true, + expectedFile: true, + size: 0, + spinServer: true, + helmManifest: true, + chartMediaType: true, + } + + testCase2 := testcase{ + name: "fetches no chart that is more than the max size", + expectedErr: "has size more than 20971520", + expectedFound: false, + expectedFile: false, + size: 21 * 1024 * 1024, // 21 MiB + spinServer: true, + helmManifest: true, + chartMediaType: true, + } + + testCase3 := testcase{ + name: "if the server is not responding, oras throws an error", + expectedErr: "unable to oras copy the remote oci artifact", + expectedFound: false, + expectedFile: false, + size: 0, + spinServer: false, + helmManifest: true, + chartMediaType: true, + } + + testCase4 := testcase{ + name: "if the oci artifact is not helm manifest mediatype, we throw an error", + expectedErr: "is not a helm chart", + expectedFound: false, + expectedFile: false, + size: 0, + spinServer: true, + helmManifest: false, + chartMediaType: true, + } + + testCase5 := testcase{ + name: "if the oci artifact has no chart tar, we throw an error", + expectedErr: "is not a helm chart", + expectedFound: false, + expectedFile: false, + size: 0, + spinServer: true, + helmManifest: true, + chartMediaType: false, + } + + testCases := []testcase{ + testCase1, + testCase2, + testCase3, + testCase4, + testCase5, + } + + assert := assert.New(t) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ts := &httptest.Server{ + URL: "http://localhost.com", + } + if tc.spinServer { + ts = spinRegistry(tc.size, tc.chartMediaType, tc.helmManifest, tc.name, t) + defer ts.Close() + } + + expoValues := v1.ExponentialBackOffValues{ + MinWait: 1, + MaxWait: 1, + } + + ociClient, err := NewClient(fmt.Sprintf("%s/testingchart:0.1.0", strings.Replace(ts.URL, "http", "oci", 1)), v1.RepoSpec{ExponentialBackOffValues: &expoValues}, nil) + assert.NoError(err) + + orasReposistory, err := ociClient.GetOrasRepository() + orasReposistory.PlainHTTP = true + orasReposistory.Client.(*auth.Client).Client.Timeout = 5 * time.Second + assert.NoError(err) + + _, err = ociClient.fetchChart(orasReposistory) + if tc.expectedErr == "" { + assert.NoError(err) + } else { + assert.Contains(err.Error(), tc.expectedErr) + } + }) + } +} + +func TestGetOrasRegistry(t *testing.T) { + testCases := []struct { + name string + expectedErr error + insecurePlainHTTP bool + }{ + { + name: "fetching oras registry works fine without auth", + expectedErr: nil, + insecurePlainHTTP: false, + }, + { + name: "fetching oras repository works fine with plainHTTP", + expectedErr: nil, + insecurePlainHTTP: true, + }, + } + + for _, tc := range testCases { + repoSpec := v1.RepoSpec{ + InsecurePlainHTTP: tc.insecurePlainHTTP, + } + + ociClient, err := NewClient("oci://example.com/charts/test:1.2.2", repoSpec, nil) + assert.NoError(t, err) + + orasRegistry, err := ociClient.GetOrasRegistry() + assert.Nil(t, orasRegistry.Client.(*auth.Client).Cache) + assert.Equal(t, orasRegistry.PlainHTTP, tc.insecurePlainHTTP) + + if tc.expectedErr != nil { + assert.ErrorContains(t, err, tc.expectedErr.Error()) + } else { + assert.NoError(t, err) + } + } +} + +func TestGetOrasRepository(t *testing.T) { + testCases := []struct { + name string + expectedErr error + insecurePlainHTTP bool + }{ + { + name: "fetching oras registry works fine without auth", + expectedErr: nil, + insecurePlainHTTP: false, + }, + { + name: "fetching oras repository works fine with plainHTTP", + expectedErr: nil, + insecurePlainHTTP: true, + }, + } + + assert := assert.New(t) + for _, tc := range testCases { + ociClient, err := NewClient("oci://example.com/charts/test:1.2.2", v1.RepoSpec{InsecurePlainHTTP: tc.insecurePlainHTTP}, nil) + assert.NoError(err) + + orasRepo, err := ociClient.GetOrasRepository() + assert.Equal(orasRepo.Client.(*auth.Client).Cache, nil) + assert.Equal(orasRepo.PlainHTTP, tc.insecurePlainHTTP) + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + } + } +} + +func TestAddToIndex(t *testing.T) { + indexFile2 := repo.NewIndexFile() + indexFile2.Entries = nil + + testCases := []struct { + name string + chartName string + fileName string + indexFile *repo.IndexFile + expectedErr error + }{ + { + name: "adding a chart to index works fine", + chartName: "testingchart", + fileName: "../../../tests/testdata/testingchart-0.1.0.tgz", + indexFile: repo.NewIndexFile(), + expectedErr: nil, + }, + { + name: "adding a chart to index doesn't work since file not found", + chartName: "testingchart", + fileName: "", + indexFile: repo.NewIndexFile(), + expectedErr: errors.New("failed to load the chart"), + }, + { + name: "adding a chart to index doesn't work since adding to index fails", + chartName: "testingchart", + fileName: "../../../tests/testdata/testingchart-0.1.0.tgz", + indexFile: indexFile2, + expectedErr: errors.New("failed to add entry"), + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert := assert.New(t) + ociClient, err := NewClient("oci://example.com/testingchart:0.1.0", v1.RepoSpec{}, nil) + assert.NoError(err) + + err = ociClient.addToIndex(tc.indexFile, tc.fileName) + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + } + }) + } +} + +func TestIsOrasRepository(t *testing.T) { + indexFile2 := repo.NewIndexFile() + indexFile2.Entries = nil + + type Tags struct { + Tags []string `json:"tags"` + } + + testTagList := Tags{ + Tags: []string{"tag"}, + } + + testCases := []struct { + name string + URL string + ok bool + tags Tags + expectedErr error + }{ + { + name: "it is a oras repository", + URL: "oci://example.com/testingchart", + ok: true, + tags: testTagList, + expectedErr: nil, + }, + { + name: "it is not a oras repository since no tags are present", + URL: "oci://example.com/testingchart", + ok: false, + tags: Tags{}, + expectedErr: nil, + }, + } + assert := assert.New(t) + for _, tc := range testCases { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := r.URL.Path + m := r.Method + switch { + case p == "/v2/" && m == "GET": + w.WriteHeader(http.StatusOK) + case p == "/v2/testingchart/tags/list" && m == "GET": + if err := json.NewEncoder(w).Encode(tc.tags); err != nil { + http.Error(w, "error encoding", http.StatusBadRequest) + } + } + })) + defer ts.Close() + + ociClient, err := NewClient(fmt.Sprintf("%s/testingchart", strings.Replace(ts.URL, "http", "oci", 1)), v1.RepoSpec{InsecurePlainHTTP: true}, nil) + assert.NoError(err) + + ok, err := ociClient.IsOrasRepository() + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + } + assert.Equal(ok, tc.ok) + } +} + +func TestInsecure(t *testing.T) { + testCases := []struct { + name string + URL string + insecure bool + expectedErr error + }{ + { + name: "fails when insecure is not specified", + URL: "oci://example.com/testingchart", + expectedErr: errors.New("failed to verify certificate"), + }, + { + name: "passes when insecure is specified", + URL: "oci://example.com/testingchart", + insecure: true, + expectedErr: nil, + }, + } + + assert := assert.New(t) + for _, tc := range testCases { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + p := r.URL.Path + m := r.Method + switch { + case p == "/v2/" && m == "GET": + w.WriteHeader(http.StatusOK) + } + })) + defer ts.Close() + + ociClient, err := NewClient(fmt.Sprintf("%s/testingchart", strings.Replace(ts.URL, "https", "oci", 1)), + v1.RepoSpec{ + InsecureSkipTLSverify: tc.insecure, + }, + nil) + assert.NoError(err) + + orasRegistry, err := ociClient.GetOrasRegistry() + assert.NoError(err) + + err = orasRegistry.Ping(context.Background()) + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + } + } +} + +func TestCaBundle(t *testing.T) { + testCases := []struct { + name string + caBundle bool + expectedErr error + }{ + { + name: "fails when caBundle is not specified", + expectedErr: errors.New("failed to verify certificate"), + }, + { + name: "passes when caBundle is specified", + caBundle: true, + expectedErr: nil, + }, + } + + assert := assert.New(t) + for _, tc := range testCases { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) + defer ts.Close() + + var repoSpec v1.RepoSpec + if tc.caBundle { + repoSpec = v1.RepoSpec{ + CABundle: ts.Certificate().Raw, + } + } + + ociClient, err := NewClient(fmt.Sprintf("%s/testingchart", strings.Replace(ts.URL, "https", "oci", 1)), + repoSpec, + nil) + assert.NoError(err) + + orasRegistry, err := ociClient.GetOrasRegistry() + assert.NoError(err) + + err = orasRegistry.Ping(context.Background()) + if tc.expectedErr != nil { + assert.ErrorContains(err, tc.expectedErr.Error()) + } else { + assert.NoError(err) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci.go new file mode 100644 index 0000000..a372379 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci.go @@ -0,0 +1,323 @@ +package oci + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "github.com/hashicorp/go-version" + ocispecv1 "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" + "oras.land/oras-go/v2" + "oras.land/oras-go/v2/content" + "oras.land/oras-go/v2/content/memory" + "oras.land/oras-go/v2/registry/remote" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" +) + +// maxHelmRepoIndexSize defines what is the max size of helm repo index file we support. +var maxHelmRepoIndexSize = 30 * 1024 * 1024 // 30 MiB + +// Chart returns an io.ReadCloser of the chart tar that is requested. +// It uses oras Go library to download the manifest of the OCI artifact +// checks if it is a Helm chart and then return the chart tar layer. +func Chart(credentialSecret *corev1.Secret, chart *repo.ChartVersion, clusterRepoSpec v1.RepoSpec) (io.ReadCloser, error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + chartURL := chart.URLs[0] + + // Create a new OCIClient + ociClient, err := NewClient(chartURL, clusterRepoSpec, credentialSecret) + if err != nil { + return nil, fmt.Errorf("failed to create an OCI client for url %s: %w", chartURL, err) + } + + // Create an oras repository + orasRepository, err := ociClient.GetOrasRepository() + if err != nil { + return nil, fmt.Errorf("failed to create an OCI repository for url %s: %w", chartURL, err) + } + + // Download the oci artifact manifest + memoryStore := memory.New() + manifest, err := oras.Copy(ctx, orasRepository, ociClient.tag, memoryStore, "", oras.CopyOptions{ + CopyGraphOptions: oras.CopyGraphOptions{ + PreCopy: func(ctx context.Context, desc ocispecv1.Descriptor) error { + // Download only helm chart related descriptors. + if desc.MediaType == ocispecv1.MediaTypeImageManifest || + desc.MediaType == registry.ChartLayerMediaType { + // We cannot load huge amounts of data into the memory + // and so we are defining a limit before fetching. + if desc.Size > maxHelmChartTarSize { + return fmt.Errorf("the oci artifact %s has size more than %d which is not supported", chartURL, maxHelmChartTarSize) + } + return nil + } + + return oras.SkipNode + }, + }, + }) + + if err != nil { + return nil, fmt.Errorf("unable to oras copy the remote OCI artifact %s: %w", chartURL, err) + } + // Fetch the manifest blob of the oci artifact + manifestBlob, err := content.FetchAll(ctx, memoryStore, manifest) + if err != nil { + return nil, fmt.Errorf("unable to fetch the manifest blob of %s: %w", chartURL, err) + } + var manifestJSON ocispecv1.Manifest + err = json.Unmarshal(manifestBlob, &manifestJSON) + if err != nil { + return nil, fmt.Errorf("unable to unmarshal manifest blob of %s: %w", chartURL, err) + } + + // Check if the oci artifact is of type helm config ? + if manifest.ArtifactType == registry.ConfigMediaType || manifestJSON.Config.MediaType == registry.ConfigMediaType { + // Find the layer of chart type and fetch it + for _, layer := range manifestJSON.Layers { + if layer.MediaType == registry.ChartLayerMediaType { + chartTar, err := content.FetchAll(ctx, memoryStore, layer) + if err != nil { + return nil, err + } + + return io.NopCloser(bytes.NewBuffer(chartTar)), nil + } + } + } + + return nil, fmt.Errorf("unable to find the required chart tar file for %s", chartURL) +} + +// GenerateIndex creates a Helm repo index from the OCI url provided +// by fetching the repositories and then the tags according to the url. +// Lastly, adds the chart entry to the Helm repo index using the oras library. +func GenerateIndex(ociClient *Client, URL string, credentialSecret *corev1.Secret, + clusterRepoSpec v1.RepoSpec, + clusterRepoStatus v1.RepoStatus, + indexFile *repo.IndexFile) (*repo.IndexFile, error) { + logrus.Debugf("Generating index for oci clusterrepo URL %s", URL) + + // Checking if the URL specified by the user is a oras repository or not ? + IsOrasRepository, err := ociClient.IsOrasRepository() + if err != nil { + return nil, err + } + + var maxTag *version.Version + var chartName string + + // Loop over all the tags and find the latest version + tagsFunc := func(tags []string) error { + existingTags := make(map[string]bool) + for i := len(tags) - 1; i >= 0; i-- { + existingTags[tags[i]] = true + // Check if the tag is a valid semver version or not. If yes, then proceed. + semverTag, err := version.NewVersion(tags[i]) + if err != nil { + // skipping the tag since it is not semver + continue + } + + if maxTag == nil || maxTag.LessThan(semverTag) { + maxTag = semverTag + } + + // Add tags into the helm repo index + if !indexFile.Has(chartName, tags[i]) { + chartVersion := &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: tags[i], + Name: chartName, + }, + URLs: []string{fmt.Sprintf("oci://%s/%s:%s", ociClient.registry, ociClient.repository, tags[i])}, + } + indexFile.Entries[chartName] = append(indexFile.Entries[chartName], chartVersion) + } + } + var updatedChartVersions []*repo.ChartVersion + + // Only keep the versions that are also present in the /tags/list call + for _, chartVersion := range indexFile.Entries[chartName] { + if existingTags[chartVersion.Version] { + updatedChartVersions = append(updatedChartVersions, chartVersion) + } + } + indexFile.Entries[chartName] = updatedChartVersions + return nil + } + + // Loop over all the repositories and fetch the tags + repositoriesFunc := func(repositories []string) error { + existingCharts := make(map[string]bool) + for _, repository := range repositories { + logrus.Debugf("found repository %s for OCI clusterrepo URL %s", repository, URL) + // Storing the user provided repository that can be an oras repository or a sub repository. + userProvidedRepository := ociClient.repository + + // Work on the oci repositories that match with the userProvidedRepository + if _, found := strings.CutPrefix(repository, ociClient.repository); found { + ociClient.repository = repository + orasRepository, err := ociClient.GetOrasRepository() + if err != nil { + return fmt.Errorf("failed to create an oras repository for url %s: %w", URL, err) + } + chartName = ociClient.repository[strings.LastIndex(ociClient.repository, "/")+1:] + existingCharts[chartName] = true + maxTag = nil + + // call tags to get the max tag and update the indexFile + err = orasRepository.Tags(context.Background(), "", tagsFunc) + if err != nil { + return fmt.Errorf("failed to fetch tags for repository %s: %w", URL, err) + } + + if maxTag != nil { + ociClient.tag = maxTag.Original() + + // fetch the chart.yaml for the latest tag and add it to the index. + err = addToHelmRepoIndex(*ociClient, indexFile, orasRepository) + if err != nil { + return fmt.Errorf("failed to add tag %s in OCI repository %s to helm repo index: %w", maxTag.String(), ociClient.repository, err) + } + } + } + ociClient.repository = userProvidedRepository + } + + // Only keep the charts that are also present in the /_catalog call + for chartName := range indexFile.Entries { + if !existingCharts[chartName] { + delete(indexFile.Entries, chartName) + } + } + return nil + } + + // If the user has provided the tag, we simply generate the index with that single oci artifact. + if ociClient.tag != "" { + orasRepository, err := ociClient.GetOrasRepository() + if err != nil { + return nil, fmt.Errorf("failed to create an oras repository for url %s: %w", URL, err) + } + + err = addToHelmRepoIndex(*ociClient, indexFile, orasRepository) + if err != nil { + return nil, fmt.Errorf("failed to add oci artifact %s in OCI URL %s to Helm repo index: %w", ociClient.repository, URL, err) + } + + // If the repository is provided with no tag, then we fetch all tags. + } else if IsOrasRepository { + orasRepository, err := ociClient.GetOrasRepository() + if err != nil { + return nil, fmt.Errorf("failed to create an oras repository for url %s: %w", URL, err) + } + chartName = ociClient.repository[strings.LastIndex(ociClient.repository, "/")+1:] + + // call tags to get the max tag and update the indexFile + err = orasRepository.Tags(context.Background(), "", tagsFunc) + if err != nil { + return nil, fmt.Errorf("failed to fetch tags for repository %s: %w", URL, err) + } + + if maxTag != nil { + ociClient.tag = maxTag.Original() + + // fetch the chart.yaml for the latest tag and add it to the index. + err = addToHelmRepoIndex(*ociClient, indexFile, orasRepository) + if err != nil { + return indexFile, fmt.Errorf("failed to add tag %s in OCI repository %s to helm repo index: %w", maxTag.String(), ociClient.repository, err) + } + } + // If no repository and tag is provided, we fetch + // all repositories and then tags associated. + } else { + orasRegistry, err := ociClient.GetOrasRegistry() + if err != nil { + return nil, fmt.Errorf("failed to create an oras registry for %s: %w", ociClient.registry, err) + } + + // Fetch all repositories + err = orasRegistry.Repositories(context.Background(), "", repositoriesFunc) + if err != nil { + return indexFile, fmt.Errorf("failed to fetch repositories for %s: %w", URL, err) + } + } + + return indexFile, nil +} + +// addToHelmRepoIndex adds the helmchart aka oras repository to the helm repo index +func addToHelmRepoIndex(ociClient Client, indexFile *repo.IndexFile, orasRepository *remote.Repository) (err error) { + ociURL := fmt.Sprintf("%s/%s:%s", ociClient.registry, ociClient.repository, ociClient.tag) + filePath := "" + var indexFileBytes []byte + + // Delete the temporary file created to store the helm chart. + defer func() { + if filePath != "" { + err2 := os.Remove(filePath) + if err == nil { + err = err2 + } + } + }() + // The chartname is always the last part of the repository + // Helm codebase also says the same thing https://github.com/helm/helm/blob/main/pkg/pusher/ocipusher.go#L88 + chartName := ociClient.repository[strings.LastIndex(ociClient.repository, "/")+1:] + + // Check if the repository and tag are not already present in the indexFile + // If it is already present, skip adding it to the indexFile. + for _, entry := range indexFile.Entries[chartName] { + if entry.Metadata.Name == chartName && entry.Version == ociClient.tag && entry.Digest != "" { + logrus.Debugf("skip adding chart %s version %s since it is already present in the index", chartName, ociClient.tag) + return + } + } + + // Fetch the helm chart tar to get the Chart.yaml + filePath, err = ociClient.fetchChart(orasRepository) + if err != nil { + err = fmt.Errorf("failed to fetch the helm chart %s: %w", ociURL, err) + return + } + + // We load index into memory and so we should set a limit + // to the size of the index file that is being created. + indexFileBytes, err = json.Marshal(indexFile) + if err != nil { + return + } + if len(indexFileBytes) > maxHelmRepoIndexSize { + err = fmt.Errorf("there are a lot of charts inside this oci URL %s which is making the index larger than %d", ociURL, maxHelmRepoIndexSize) + return + } + + // Remove the entry from the indexfile since the next function addToIndex + // will add. This is done to avoid duplication. + for index, entry := range indexFile.Entries[chartName] { + if entry.Metadata.Name == chartName && entry.Version == ociClient.tag { + indexFile.Entries[chartName] = append(indexFile.Entries[chartName][:index], indexFile.Entries[chartName][index+1:]...) + } + } + + // Add the chart to the index + err = ociClient.addToIndex(indexFile, filePath) + if err != nil { + err = fmt.Errorf("unable to add helm chart %s to index: %w", ociURL, err) + } + + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci_test.go new file mode 100644 index 0000000..d14d099 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/oci/oci_test.go @@ -0,0 +1,246 @@ +package oci + +import ( + "fmt" + "strings" + "testing" + + corev1 "k8s.io/api/core/v1" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/repo" +) + +func TestAddtoHelmRepoIndex(t *testing.T) { + indexFile := repo.NewIndexFile() + indexFile.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "0.1.0", + }, + Digest: "digest", + }, + } + + indexFile2 := repo.NewIndexFile() + indexFile2.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "0.1.0", + }, + }, + } + + tests := []struct { + name string + indexFile *repo.IndexFile + expectedErrMsg string + maxHelmRepoIndexSize int + }{ + { + "returns an error if indexFile size exceeds max size", + repo.NewIndexFile(), + "there are a lot of charts inside this oci", + 30, + }, + { + "adds the oci artifact to the helm repo index properly without deplication", + indexFile2, + "", + 30 * 1024 * 1024, // 30 MiB + }, + { + "avoids adding the oci artifact to the helm repo index if it already exists", + indexFile, + "", + 30 * 1024 * 1024, // 30 MiB + }, + { + "adds the oci artifact to the helm repo index properly", + repo.NewIndexFile(), + "", + 30 * 1024 * 1024, // 30 MiB + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := spinRegistry(0, true, true, tt.name, t) + defer ts.Close() + ociClient, err := NewClient(fmt.Sprintf("%s/testingchart:0.1.0", strings.Replace(ts.URL, "http", "oci", 1)), v1.RepoSpec{}, nil) + assert.NoError(t, err) + orasRepository, err := ociClient.GetOrasRepository() + orasRepository.PlainHTTP = true + assert.NoError(t, err) + + maxHelmRepoIndexSize = tt.maxHelmRepoIndexSize + err = addToHelmRepoIndex(*ociClient, tt.indexFile, orasRepository) + if tt.expectedErrMsg != "" { + assert.Contains(t, err.Error(), tt.expectedErrMsg) + } else { + assert.NoError(t, err) + if len(tt.indexFile.Entries) > 0 { + assert.Equal(t, len(tt.indexFile.Entries["testingchart"]), 1) + } + } + }) + } +} + +func TestGenerateIndex(t *testing.T) { + indexFile := repo.NewIndexFile() + indexFile.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "0.1.0", + }, + Digest: "digest", + }, + } + + indexFile2 := repo.NewIndexFile() + indexFile2.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "0.1.0", + }, + }, + } + + indexFile3 := repo.NewIndexFile() + indexFile3.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "1.0.0", + }, + Digest: "digest", + }, + } + indexFile4 := repo.NewIndexFile() + indexFile4.Entries["anotherchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "anotherchart", + Version: "1.0.0", + }, + Digest: "digest", + }, + } + indexFile4.Entries["anotherchartagain"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "anotherchartagain", + Version: "1.0.0", + }, + Digest: "digest", + }, + } + one := 1 + two := 2 + + tests := []struct { + name string + indexFile *repo.IndexFile + expectedErrMsg string + numberOfEntries *int + numberOfCharts *int + secret *corev1.Secret + url string + urlPath string + }{ + { + "Can add a specific chart to indexFile if tag is provided", + repo.NewIndexFile(), + "", + &one, + &one, + nil, + "", + "testingchart:0.1.0", + }, + { + "Can add charts to index file if repository is provided", + repo.NewIndexFile(), + "", + &two, + &one, + nil, + "", + "testingchart", + }, + { + "Can add charts to index file if registry is provided", + repo.NewIndexFile(), + "", + &two, + &one, + nil, + "", + "", + }, + { + "Should not duplicate charts on indexFile", + indexFile, + "", + &one, + &one, + nil, + "", + "testingchart:0.1.0", + }, + { + "Index file should not have versions that aren't present in the response of /tags/list", + indexFile3, + "", + &two, + &one, + nil, + "", + "", + }, + { + "Index file should not have repositories that aren't present in the response of /_catalog", + indexFile4, + "", + &two, + &one, + nil, + "", + "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := spinRegistry(0, true, true, tt.name, t) + defer ts.Close() + u := fmt.Sprintf("%s/%s", strings.Replace(ts.URL, "http", "oci", 1), tt.urlPath) + if tt.url != "" { + u = tt.url + } + repoSpec := v1.RepoSpec{InsecurePlainHTTP: true, InsecureSkipTLSverify: true} + ociClient, err := NewClient(u, repoSpec, nil) + assert.Nil(t, err) + i, err := GenerateIndex(ociClient, u, nil, repoSpec, v1.RepoStatus{}, tt.indexFile) + if tt.expectedErrMsg != "" { + assert.Contains(t, err.Error(), tt.expectedErrMsg, "wrong error") + } + if tt.numberOfCharts != nil { + assert.Equal(t, len(i.Entries), *tt.numberOfCharts, "number of charts don't match") + } + if tt.numberOfEntries != nil { + assert.Equal(t, len(i.Entries["testingchart"]), *tt.numberOfEntries, "number of entries don't match") + i.SortEntries() + assert.NotEmpty(t, i.Entries["testingchart"][0].Digest, "wrong digest for the first entry") + if *tt.numberOfEntries > 1 { + assert.Empty(t, i.Entries["testingchart"][1].Digest, "wrong digest for the second entry") + } + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/secret.go new file mode 100644 index 0000000..6b89a65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/secret.go @@ -0,0 +1,20 @@ +package catalogv2 + +import ( + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + corev1 "k8s.io/api/core/v1" +) + +// GetSecret returns the Secret from the cluster repo's clientSecret spec field +func GetSecret(secrets corev1controllers.SecretCache, repoSpec *v1.RepoSpec, repoNamespace string) (*corev1.Secret, error) { + if repoSpec.ClientSecret == nil { + return nil, nil + } + ns := repoSpec.ClientSecret.Namespace + if repoNamespace != "" { + ns = repoNamespace + } + + return secrets.Get(ns, repoSpec.ClientSecret.Name) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/manager_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/manager_test.go new file mode 100644 index 0000000..ecf237f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/manager_test.go @@ -0,0 +1,525 @@ +package system + +// mockgen --build_flags=--mod=mod -package system -destination=./mock_system_test.go github.com/rancher/rancher/pkg/catalogv2/system ContentClient,OperationClient,HelmClient + +import ( + context "context" + "errors" + "testing" + + "github.com/golang/mock/gomock" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v3/pkg/repo" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestManagerRemovesRelease(t *testing.T) { + t.Parallel() + webhook := desiredKey{ + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.1.1", + exactVersion: "1.2.0", + installImageOverride: "some-image", + } + charts := map[desiredKey]map[string]any{ + webhook: {"foo": "bar"}, + } + + manager := Manager{desiredCharts: charts} + manager.Remove("hello", "world") + assert.Equal(t, charts, manager.desiredCharts) + + manager.Remove("cattle-system", "rancher-webhook") + assert.Equal(t, map[desiredKey]map[string]any{}, manager.desiredCharts) + + // Assert that the lookup of key to delete only needs namespace and name. + webhook = desiredKey{ + namespace: "cattle-system", + name: "rancher-webhook", + } + charts[webhook] = map[string]any{} + assert.Equal(t, charts, manager.desiredCharts) + manager.Remove("cattle-system", "rancher-webhook") + assert.Equal(t, map[desiredKey]map[string]any{}, manager.desiredCharts) +} + +func TestStart(t *testing.T) { + t.Parallel() + + ctrl := gomock.NewController(t) + ctx := context.Background() + + mockSettingsController := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](ctrl) + mockSettingsController.EXPECT().OnChange(ctx, "system-feature-chart-refresh", gomock.Any()) + + mockClusterRepos := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockClusterRepos.EXPECT().OnChange(ctx, "catalog-refresh-trigger", gomock.Any()) + + manager := Manager{ + settings: mockSettingsController, + clusterRepos: mockClusterRepos, + } + + manager.Start(ctx) +} + +func TestInstallCharts(t *testing.T) { + var ( + fleetChartV1 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "fleet", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + fleetChartV2 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "fleet", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "2.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + fleetChartV3 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "fleet", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "3.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + rancherChartV1 = release.Release{ + Namespace: "cattle-system", + Name: "rancher-webhook", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + aksOperatorChartV1 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "aks-operator", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + aksOperatorChartV2 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "aks-operator", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "2.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + aksOperatorChartV3 = release.Release{ + Namespace: "cattle-fleet-system", + Name: "aks-operator", + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "3.0.0", + }, + }, + Info: &release.Info{ + Status: release.StatusDeployed, + }, + } + fleetRepoV1 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + URLs: []string{"foo"}, + } + fleetRepoV2 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "2.0.0", + }, + URLs: []string{"foo"}, + } + fleetRepoV3 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "3.0.0", + }, + URLs: []string{"foo"}, + } + aksOperatorRepoV1 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + URLs: []string{"foo"}, + } + aksOperatorRepoV2 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "2.0.0", + }, + URLs: []string{"foo"}, + } + aksOperatorRepoV3 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "3.0.0", + }, + URLs: []string{"foo"}, + } + rancherRepoV1 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + URLs: []string{"foo"}, + } + rancherRepoV2 = repo.ChartVersion{ + Metadata: &chart.Metadata{ + Version: "2.0.0", + }, + URLs: []string{"foo"}, + } + ) + + tests := []struct { + name string + releases []*release.Release + indexedReleases map[string]repo.ChartVersions + desiredCharts map[desiredKey]map[string]any + takeOwnership bool + expectInstalls map[string]bool + expectedErr error + }{ + { + name: "Updates charts to desired version", + releases: []*release.Release{&rancherChartV1, &fleetChartV1, &aksOperatorChartV1}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV2}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV2}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "rancher-webhook": true, + "fleet": true, + "aks-operator": true, + }, + }, + { + name: "Keeps installed release matching desired version", + releases: []*release.Release{&fleetChartV2, &rancherChartV1, &aksOperatorChartV2}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV2}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV2}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "fleet": false, + "rancher-webhook": true, + "aks-operator": true, + }, + }, + { + name: "Keeps installed release, more recent than desired version", + releases: []*release.Release{&rancherChartV1, &fleetChartV3, &aksOperatorChartV3}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV2, &fleetRepoV3}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV2, &aksOperatorRepoV3}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + minVersion: "1.0.0", + exactVersion: "", + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "fleet": false, + "rancher-webhook": true, + "aks-operator": true, + }, + }, + { + // This use case can occur when restoring to an older Rancher version. + name: "Downgrades installed release, more recent than desired version", + releases: []*release.Release{&rancherChartV1, &fleetChartV3, &aksOperatorChartV3}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV2, &fleetRepoV3}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV2, &aksOperatorRepoV3}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "fleet": true, + "rancher-webhook": true, + "aks-operator": true, + }, + }, + { + name: "Installs release if none installed", + releases: []*release.Release{&rancherChartV1}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV2}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV2}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "fleet": true, + "rancher-webhook": true, + "aks-operator": true, + }, + }, + { + name: "Fails to install specified release if not found in catalog", + releases: []*release.Release{&rancherChartV1}, + indexedReleases: map[string]repo.ChartVersions{ + "fleet": {&fleetRepoV1, &fleetRepoV3}, + "rancher-webhook": {&rancherRepoV1, &rancherRepoV2}, + "aks-operator": {&aksOperatorRepoV1, &aksOperatorRepoV3}, + }, + desiredCharts: map[desiredKey]map[string]any{ + { + namespace: "cattle-fleet-system", + name: "fleet", + // major, minor and patch segments match a version from the index, which is + // where Helm could return a matching version based on those segments, but not + // strictly equal to the specified one + minVersion: "3.0.0+up1.2.3", + // no exact version + }: {}, + { + namespace: "cattle-system", + name: "rancher-webhook", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + { + namespace: "cattle-system", + name: "aks-operator", + minVersion: "1.0.0", + exactVersion: "2.0.0", + }: {}, + }, + takeOwnership: false, + expectInstalls: map[string]bool{ + "fleet": false, + "rancher-webhook": true, + "aks-operator": false, + }, + expectedErr: errors.New("specified version 3.0.0+up1.2.3 doesn't exist in the index"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + + ctx := context.Background() + mockContentClient := NewMockContentClient(ctrl) + mockOperationClient := NewMockOperationClient(ctrl) + mockPodClient := fake.NewMockClientInterface[*v1.Pod, *v1.PodList](ctrl) + mockHelmClient := NewMockHelmClient(ctrl) + + for dc := range test.desiredCharts { + var foundRelease *release.Release + for _, r := range test.releases { + if r.Name == dc.name && r.Namespace == dc.namespace { + foundRelease = r + } + } + + var foundReleases []*release.Release + if foundRelease != nil { + foundReleases = []*release.Release{foundRelease} + } + + // Call from installCharts and isInstalled + mockHelmClient.EXPECT().ListReleases(dc.namespace, dc.name, action.ListDeployed). + Return(foundReleases, nil). + MaxTimes(2) + + if test.expectInstalls[dc.name] { + // Call from install -> hasStatus + mockHelmClient.EXPECT().ListReleases( + dc.namespace, + dc.name, + action.ListPendingInstall|action.ListPendingUpgrade|action.ListPendingRollback, + ). + Return(nil, nil) + + upgradeOp := catalog.Operation{ + Status: catalog.OperationStatus{ + PodNamespace: dc.namespace, + }, + } + + mockOperationClient.EXPECT().Upgrade(ctx, installUser, "", "rancher-charts", gomock.Any(), gomock.Any()). + Return(&upgradeOp, nil) + + pod := v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + Name: "helm", + State: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{ + ExitCode: 0, + }, + }, + }, + }, + }, + } + + mockPodClient.EXPECT().Get(dc.namespace, gomock.Any(), metav1.GetOptions{}). + Return(&pod, nil).Times(1) + } + + mockContentClient.EXPECT().Index("", "rancher-charts", "", true). + Return(&repo.IndexFile{Entries: test.indexedReleases}, nil) + } + + manager := Manager{ + ctx: context.Background(), + content: mockContentClient, + pods: mockPodClient, + desiredCharts: test.desiredCharts, + helmClient: mockHelmClient, + operation: mockOperationClient, + } + + err := manager.installCharts(test.desiredCharts, test.takeOwnership) + if test.expectedErr == nil { + assert.NoError(t, err) + } else { + assert.Contains(t, err.Error(), test.expectedErr.Error()) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mock_system_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mock_system_test.go new file mode 100644 index 0000000..1b53f20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mock_system_test.go @@ -0,0 +1,147 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/catalogv2/system (interfaces: ContentClient,OperationClient,HelmClient) + +// Package system is a generated GoMock package. +package system + +import ( + context "context" + io "io" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + action "helm.sh/helm/v3/pkg/action" + release "helm.sh/helm/v3/pkg/release" + repo "helm.sh/helm/v3/pkg/repo" + user "k8s.io/apiserver/pkg/authentication/user" +) + +// MockContentClient is a mock of ContentClient interface. +type MockContentClient struct { + ctrl *gomock.Controller + recorder *MockContentClientMockRecorder +} + +// MockContentClientMockRecorder is the mock recorder for MockContentClient. +type MockContentClientMockRecorder struct { + mock *MockContentClient +} + +// NewMockContentClient creates a new mock instance. +func NewMockContentClient(ctrl *gomock.Controller) *MockContentClient { + mock := &MockContentClient{ctrl: ctrl} + mock.recorder = &MockContentClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockContentClient) EXPECT() *MockContentClientMockRecorder { + return m.recorder +} + +// Index mocks base method. +func (m *MockContentClient) Index(arg0, arg1, arg2 string, arg3 bool) (*repo.IndexFile, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Index", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*repo.IndexFile) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Index indicates an expected call of Index. +func (mr *MockContentClientMockRecorder) Index(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index", reflect.TypeOf((*MockContentClient)(nil).Index), arg0, arg1, arg2, arg3) +} + +// MockOperationClient is a mock of OperationClient interface. +type MockOperationClient struct { + ctrl *gomock.Controller + recorder *MockOperationClientMockRecorder +} + +// MockOperationClientMockRecorder is the mock recorder for MockOperationClient. +type MockOperationClientMockRecorder struct { + mock *MockOperationClient +} + +// NewMockOperationClient creates a new mock instance. +func NewMockOperationClient(ctrl *gomock.Controller) *MockOperationClient { + mock := &MockOperationClient{ctrl: ctrl} + mock.recorder = &MockOperationClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockOperationClient) EXPECT() *MockOperationClientMockRecorder { + return m.recorder +} + +// Uninstall mocks base method. +func (m *MockOperationClient) Uninstall(arg0 context.Context, arg1 user.Info, arg2, arg3 string, arg4 io.Reader, arg5 string) (*v1.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Uninstall", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*v1.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Uninstall indicates an expected call of Uninstall. +func (mr *MockOperationClientMockRecorder) Uninstall(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Uninstall", reflect.TypeOf((*MockOperationClient)(nil).Uninstall), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// Upgrade mocks base method. +func (m *MockOperationClient) Upgrade(arg0 context.Context, arg1 user.Info, arg2, arg3 string, arg4 io.Reader, arg5 string) (*v1.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Upgrade", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*v1.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Upgrade indicates an expected call of Upgrade. +func (mr *MockOperationClientMockRecorder) Upgrade(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upgrade", reflect.TypeOf((*MockOperationClient)(nil).Upgrade), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// MockHelmClient is a mock of HelmClient interface. +type MockHelmClient struct { + ctrl *gomock.Controller + recorder *MockHelmClientMockRecorder +} + +// MockHelmClientMockRecorder is the mock recorder for MockHelmClient. +type MockHelmClientMockRecorder struct { + mock *MockHelmClient +} + +// NewMockHelmClient creates a new mock instance. +func NewMockHelmClient(ctrl *gomock.Controller) *MockHelmClient { + mock := &MockHelmClient{ctrl: ctrl} + mock.recorder = &MockHelmClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHelmClient) EXPECT() *MockHelmClientMockRecorder { + return m.recorder +} + +// ListReleases mocks base method. +func (m *MockHelmClient) ListReleases(arg0, arg1 string, arg2 action.ListStates) ([]*release.Release, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListReleases", arg0, arg1, arg2) + ret0, _ := ret[0].([]*release.Release) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListReleases indicates an expected call of ListReleases. +func (mr *MockHelmClientMockRecorder) ListReleases(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListReleases", reflect.TypeOf((*MockHelmClient)(nil).ListReleases), arg0, arg1, arg2) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ClusterRepoController.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ClusterRepoController.go new file mode 100644 index 0000000..3a38986 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ClusterRepoController.go @@ -0,0 +1,366 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + context "context" + + catalog_cattle_iov1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + cache "k8s.io/client-go/tools/cache" + + generic "github.com/rancher/wrangler/v3/pkg/generic" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mock "github.com/stretchr/testify/mock" + + rest "k8s.io/client-go/rest" + + schema "k8s.io/apimachinery/pkg/runtime/schema" + + time "time" + + types "k8s.io/apimachinery/pkg/types" + + watch "k8s.io/apimachinery/pkg/watch" +) + +// ClusterRepoController is an autogenerated mock type for the ClusterRepoController type +type ClusterRepoController struct { + mock.Mock +} + +// AddGenericHandler provides a mock function with given fields: ctx, name, handler +func (_m *ClusterRepoController) AddGenericHandler(ctx context.Context, name string, handler generic.Handler) { + _m.Called(ctx, name, handler) +} + +// AddGenericRemoveHandler provides a mock function with given fields: ctx, name, handler +func (_m *ClusterRepoController) AddGenericRemoveHandler(ctx context.Context, name string, handler generic.Handler) { + _m.Called(ctx, name, handler) +} + +// Cache provides a mock function with given fields: +func (_m *ClusterRepoController) Cache() generic.NonNamespacedCacheInterface[*catalog_cattle_iov1.ClusterRepo] { + ret := _m.Called() + + var r0 generic.NonNamespacedCacheInterface[*catalog_cattle_iov1.ClusterRepo] + if rf, ok := ret.Get(0).(func() generic.NonNamespacedCacheInterface[*catalog_cattle_iov1.ClusterRepo]); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.NonNamespacedCacheInterface[*catalog_cattle_iov1.ClusterRepo]) + } + } + + return r0 +} + +// Create provides a mock function with given fields: _a0 +func (_m *ClusterRepoController) Create(_a0 *catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error) { + ret := _m.Called(_a0) + + var r0 *catalog_cattle_iov1.ClusterRepo + var r1 error + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) *catalog_cattle_iov1.ClusterRepo); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepo) + } + } + + if rf, ok := ret.Get(1).(func(*catalog_cattle_iov1.ClusterRepo) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: name, options +func (_m *ClusterRepoController) Delete(name string, options *metav1.DeleteOptions) error { + ret := _m.Called(name, options) + + var r0 error + if rf, ok := ret.Get(0).(func(string, *metav1.DeleteOptions) error); ok { + r0 = rf(name, options) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Enqueue provides a mock function with given fields: name +func (_m *ClusterRepoController) Enqueue(name string) { + _m.Called(name) +} + +// EnqueueAfter provides a mock function with given fields: name, duration +func (_m *ClusterRepoController) EnqueueAfter(name string, duration time.Duration) { + _m.Called(name, duration) +} + +// Get provides a mock function with given fields: name, options +func (_m *ClusterRepoController) Get(name string, options metav1.GetOptions) (*catalog_cattle_iov1.ClusterRepo, error) { + ret := _m.Called(name, options) + + var r0 *catalog_cattle_iov1.ClusterRepo + var r1 error + if rf, ok := ret.Get(0).(func(string, metav1.GetOptions) (*catalog_cattle_iov1.ClusterRepo, error)); ok { + return rf(name, options) + } + if rf, ok := ret.Get(0).(func(string, metav1.GetOptions) *catalog_cattle_iov1.ClusterRepo); ok { + r0 = rf(name, options) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepo) + } + } + + if rf, ok := ret.Get(1).(func(string, metav1.GetOptions) error); ok { + r1 = rf(name, options) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GroupVersionKind provides a mock function with given fields: +func (_m *ClusterRepoController) GroupVersionKind() schema.GroupVersionKind { + ret := _m.Called() + + var r0 schema.GroupVersionKind + if rf, ok := ret.Get(0).(func() schema.GroupVersionKind); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(schema.GroupVersionKind) + } + + return r0 +} + +// Informer provides a mock function with given fields: +func (_m *ClusterRepoController) Informer() cache.SharedIndexInformer { + ret := _m.Called() + + var r0 cache.SharedIndexInformer + if rf, ok := ret.Get(0).(func() cache.SharedIndexInformer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.SharedIndexInformer) + } + } + + return r0 +} + +// List provides a mock function with given fields: opts +func (_m *ClusterRepoController) List(opts metav1.ListOptions) (*catalog_cattle_iov1.ClusterRepoList, error) { + ret := _m.Called(opts) + + var r0 *catalog_cattle_iov1.ClusterRepoList + var r1 error + if rf, ok := ret.Get(0).(func(metav1.ListOptions) (*catalog_cattle_iov1.ClusterRepoList, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(metav1.ListOptions) *catalog_cattle_iov1.ClusterRepoList); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepoList) + } + } + + if rf, ok := ret.Get(1).(func(metav1.ListOptions) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnChange provides a mock function with given fields: ctx, name, sync +func (_m *ClusterRepoController) OnChange(ctx context.Context, name string, sync generic.ObjectHandler[*catalog_cattle_iov1.ClusterRepo]) { + _m.Called(ctx, name, sync) +} + +// OnRemove provides a mock function with given fields: ctx, name, sync +func (_m *ClusterRepoController) OnRemove(ctx context.Context, name string, sync generic.ObjectHandler[*catalog_cattle_iov1.ClusterRepo]) { + _m.Called(ctx, name, sync) +} + +// Patch provides a mock function with given fields: name, pt, data, subresources +func (_m *ClusterRepoController) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*catalog_cattle_iov1.ClusterRepo, error) { + _va := make([]interface{}, len(subresources)) + for _i := range subresources { + _va[_i] = subresources[_i] + } + var _ca []interface{} + _ca = append(_ca, name, pt, data) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *catalog_cattle_iov1.ClusterRepo + var r1 error + if rf, ok := ret.Get(0).(func(string, types.PatchType, []byte, ...string) (*catalog_cattle_iov1.ClusterRepo, error)); ok { + return rf(name, pt, data, subresources...) + } + if rf, ok := ret.Get(0).(func(string, types.PatchType, []byte, ...string) *catalog_cattle_iov1.ClusterRepo); ok { + r0 = rf(name, pt, data, subresources...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepo) + } + } + + if rf, ok := ret.Get(1).(func(string, types.PatchType, []byte, ...string) error); ok { + r1 = rf(name, pt, data, subresources...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: _a0 +func (_m *ClusterRepoController) Update(_a0 *catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error) { + ret := _m.Called(_a0) + + var r0 *catalog_cattle_iov1.ClusterRepo + var r1 error + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) *catalog_cattle_iov1.ClusterRepo); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepo) + } + } + + if rf, ok := ret.Get(1).(func(*catalog_cattle_iov1.ClusterRepo) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateStatus provides a mock function with given fields: _a0 +func (_m *ClusterRepoController) UpdateStatus(_a0 *catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error) { + ret := _m.Called(_a0) + + var r0 *catalog_cattle_iov1.ClusterRepo + var r1 error + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) (*catalog_cattle_iov1.ClusterRepo, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*catalog_cattle_iov1.ClusterRepo) *catalog_cattle_iov1.ClusterRepo); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*catalog_cattle_iov1.ClusterRepo) + } + } + + if rf, ok := ret.Get(1).(func(*catalog_cattle_iov1.ClusterRepo) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Updater provides a mock function with given fields: +func (_m *ClusterRepoController) Updater() generic.Updater { + ret := _m.Called() + + var r0 generic.Updater + if rf, ok := ret.Get(0).(func() generic.Updater); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.Updater) + } + } + + return r0 +} + +// Watch provides a mock function with given fields: opts +func (_m *ClusterRepoController) Watch(opts metav1.ListOptions) (watch.Interface, error) { + ret := _m.Called(opts) + + var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(metav1.ListOptions) (watch.Interface, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(metav1.ListOptions) watch.Interface); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(watch.Interface) + } + } + + if rf, ok := ret.Get(1).(func(metav1.ListOptions) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WithImpersonation provides a mock function with given fields: impersonate +func (_m *ClusterRepoController) WithImpersonation(impersonate rest.ImpersonationConfig) (generic.NonNamespacedClientInterface[*catalog_cattle_iov1.ClusterRepo, *catalog_cattle_iov1.ClusterRepoList], error) { + ret := _m.Called(impersonate) + + var r0 generic.NonNamespacedClientInterface[*catalog_cattle_iov1.ClusterRepo, *catalog_cattle_iov1.ClusterRepoList] + var r1 error + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) (generic.NonNamespacedClientInterface[*catalog_cattle_iov1.ClusterRepo, *catalog_cattle_iov1.ClusterRepoList], error)); ok { + return rf(impersonate) + } + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) generic.NonNamespacedClientInterface[*catalog_cattle_iov1.ClusterRepo, *catalog_cattle_iov1.ClusterRepoList]); ok { + r0 = rf(impersonate) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.NonNamespacedClientInterface[*catalog_cattle_iov1.ClusterRepo, *catalog_cattle_iov1.ClusterRepoList]) + } + } + + if rf, ok := ret.Get(1).(func(rest.ImpersonationConfig) error); ok { + r1 = rf(impersonate) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewClusterRepoController creates a new instance of ClusterRepoController. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClusterRepoController(t interface { + mock.TestingT + Cleanup(func()) +}) *ClusterRepoController { + mock := &ClusterRepoController{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ContentClient.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ContentClient.go new file mode 100644 index 0000000..82bb67e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/ContentClient.go @@ -0,0 +1,53 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + repo "helm.sh/helm/v3/pkg/repo" +) + +// ContentClient is an autogenerated mock type for the ContentClient type +type ContentClient struct { + mock.Mock +} + +// Index provides a mock function with given fields: namespace, name, targetK8sVersion, skipFilter +func (_m *ContentClient) Index(namespace string, name string, targetK8sVersion string, skipFilter bool) (*repo.IndexFile, error) { + ret := _m.Called(namespace, name, targetK8sVersion, skipFilter) + + var r0 *repo.IndexFile + var r1 error + if rf, ok := ret.Get(0).(func(string, string, string, bool) (*repo.IndexFile, error)); ok { + return rf(namespace, name, targetK8sVersion, skipFilter) + } + if rf, ok := ret.Get(0).(func(string, string, string, bool) *repo.IndexFile); ok { + r0 = rf(namespace, name, targetK8sVersion, skipFilter) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*repo.IndexFile) + } + } + + if rf, ok := ret.Get(1).(func(string, string, string, bool) error); ok { + r1 = rf(namespace, name, targetK8sVersion, skipFilter) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewContentClient creates a new instance of ContentClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewContentClient(t interface { + mock.TestingT + Cleanup(func()) +}) *ContentClient { + mock := &ContentClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/HelmClient.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/HelmClient.go new file mode 100644 index 0000000..a102b2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/HelmClient.go @@ -0,0 +1,55 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + action "helm.sh/helm/v3/pkg/action" + + release "helm.sh/helm/v3/pkg/release" +) + +// HelmClient is an autogenerated mock type for the HelmClient type +type HelmClient struct { + mock.Mock +} + +// ListReleases provides a mock function with given fields: namespace, name, stateMask +func (_m *HelmClient) ListReleases(namespace string, name string, stateMask action.ListStates) ([]*release.Release, error) { + ret := _m.Called(namespace, name, stateMask) + + var r0 []*release.Release + var r1 error + if rf, ok := ret.Get(0).(func(string, string, action.ListStates) ([]*release.Release, error)); ok { + return rf(namespace, name, stateMask) + } + if rf, ok := ret.Get(0).(func(string, string, action.ListStates) []*release.Release); ok { + r0 = rf(namespace, name, stateMask) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*release.Release) + } + } + + if rf, ok := ret.Get(1).(func(string, string, action.ListStates) error); ok { + r1 = rf(namespace, name, stateMask) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewHelmClient creates a new instance of HelmClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHelmClient(t interface { + mock.TestingT + Cleanup(func()) +}) *HelmClient { + mock := &HelmClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/OperationClient.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/OperationClient.go new file mode 100644 index 0000000..e6b06d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/OperationClient.go @@ -0,0 +1,85 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + context "context" + io "io" + + mock "github.com/stretchr/testify/mock" + + user "k8s.io/apiserver/pkg/authentication/user" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" +) + +// OperationClient is an autogenerated mock type for the OperationClient type +type OperationClient struct { + mock.Mock +} + +// Uninstall provides a mock function with given fields: ctx, _a1, namespace, name, options, imageOverride +func (_m *OperationClient) Uninstall(ctx context.Context, _a1 user.Info, namespace string, name string, options io.Reader, imageOverride string) (*v1.Operation, error) { + ret := _m.Called(ctx, _a1, namespace, name, options, imageOverride) + + var r0 *v1.Operation + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, user.Info, string, string, io.Reader, string) (*v1.Operation, error)); ok { + return rf(ctx, _a1, namespace, name, options, imageOverride) + } + if rf, ok := ret.Get(0).(func(context.Context, user.Info, string, string, io.Reader, string) *v1.Operation); ok { + r0 = rf(ctx, _a1, namespace, name, options, imageOverride) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Operation) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, user.Info, string, string, io.Reader, string) error); ok { + r1 = rf(ctx, _a1, namespace, name, options, imageOverride) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Upgrade provides a mock function with given fields: ctx, _a1, namespace, name, options, imageOverride +func (_m *OperationClient) Upgrade(ctx context.Context, _a1 user.Info, namespace string, name string, options io.Reader, imageOverride string) (*v1.Operation, error) { + ret := _m.Called(ctx, _a1, namespace, name, options, imageOverride) + + var r0 *v1.Operation + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, user.Info, string, string, io.Reader, string) (*v1.Operation, error)); ok { + return rf(ctx, _a1, namespace, name, options, imageOverride) + } + if rf, ok := ret.Get(0).(func(context.Context, user.Info, string, string, io.Reader, string) *v1.Operation); ok { + r0 = rf(ctx, _a1, namespace, name, options, imageOverride) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Operation) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, user.Info, string, string, io.Reader, string) error); ok { + r1 = rf(ctx, _a1, namespace, name, options, imageOverride) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewOperationClient creates a new instance of OperationClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewOperationClient(t interface { + mock.TestingT + Cleanup(func()) +}) *OperationClient { + mock := &OperationClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/PodClient.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/PodClient.go new file mode 100644 index 0000000..77bee71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/PodClient.go @@ -0,0 +1,266 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + generic "github.com/rancher/wrangler/v3/pkg/generic" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + mock "github.com/stretchr/testify/mock" + + rest "k8s.io/client-go/rest" + + types "k8s.io/apimachinery/pkg/types" + + v1 "k8s.io/api/core/v1" + + watch "k8s.io/apimachinery/pkg/watch" +) + +// PodClient is an autogenerated mock type for the PodClient type +type PodClient struct { + mock.Mock +} + +// Create provides a mock function with given fields: _a0 +func (_m *PodClient) Create(_a0 *v1.Pod) (*v1.Pod, error) { + ret := _m.Called(_a0) + + var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(*v1.Pod) (*v1.Pod, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*v1.Pod) *v1.Pod); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Pod) + } + } + + if rf, ok := ret.Get(1).(func(*v1.Pod) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: namespace, name, options +func (_m *PodClient) Delete(namespace string, name string, options *metav1.DeleteOptions) error { + ret := _m.Called(namespace, name, options) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string, *metav1.DeleteOptions) error); ok { + r0 = rf(namespace, name, options) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Get provides a mock function with given fields: namespace, name, options +func (_m *PodClient) Get(namespace string, name string, options metav1.GetOptions) (*v1.Pod, error) { + ret := _m.Called(namespace, name, options) + + var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(string, string, metav1.GetOptions) (*v1.Pod, error)); ok { + return rf(namespace, name, options) + } + if rf, ok := ret.Get(0).(func(string, string, metav1.GetOptions) *v1.Pod); ok { + r0 = rf(namespace, name, options) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Pod) + } + } + + if rf, ok := ret.Get(1).(func(string, string, metav1.GetOptions) error); ok { + r1 = rf(namespace, name, options) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// List provides a mock function with given fields: namespace, opts +func (_m *PodClient) List(namespace string, opts metav1.ListOptions) (*v1.PodList, error) { + ret := _m.Called(namespace, opts) + + var r0 *v1.PodList + var r1 error + if rf, ok := ret.Get(0).(func(string, metav1.ListOptions) (*v1.PodList, error)); ok { + return rf(namespace, opts) + } + if rf, ok := ret.Get(0).(func(string, metav1.ListOptions) *v1.PodList); ok { + r0 = rf(namespace, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.PodList) + } + } + + if rf, ok := ret.Get(1).(func(string, metav1.ListOptions) error); ok { + r1 = rf(namespace, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Patch provides a mock function with given fields: namespace, name, pt, data, subresources +func (_m *PodClient) Patch(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*v1.Pod, error) { + _va := make([]interface{}, len(subresources)) + for _i := range subresources { + _va[_i] = subresources[_i] + } + var _ca []interface{} + _ca = append(_ca, namespace, name, pt, data) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(string, string, types.PatchType, []byte, ...string) (*v1.Pod, error)); ok { + return rf(namespace, name, pt, data, subresources...) + } + if rf, ok := ret.Get(0).(func(string, string, types.PatchType, []byte, ...string) *v1.Pod); ok { + r0 = rf(namespace, name, pt, data, subresources...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Pod) + } + } + + if rf, ok := ret.Get(1).(func(string, string, types.PatchType, []byte, ...string) error); ok { + r1 = rf(namespace, name, pt, data, subresources...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: _a0 +func (_m *PodClient) Update(_a0 *v1.Pod) (*v1.Pod, error) { + ret := _m.Called(_a0) + + var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(*v1.Pod) (*v1.Pod, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*v1.Pod) *v1.Pod); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Pod) + } + } + + if rf, ok := ret.Get(1).(func(*v1.Pod) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateStatus provides a mock function with given fields: _a0 +func (_m *PodClient) UpdateStatus(_a0 *v1.Pod) (*v1.Pod, error) { + ret := _m.Called(_a0) + + var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(*v1.Pod) (*v1.Pod, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*v1.Pod) *v1.Pod); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Pod) + } + } + + if rf, ok := ret.Get(1).(func(*v1.Pod) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Watch provides a mock function with given fields: namespace, opts +func (_m *PodClient) Watch(namespace string, opts metav1.ListOptions) (watch.Interface, error) { + ret := _m.Called(namespace, opts) + + var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(string, metav1.ListOptions) (watch.Interface, error)); ok { + return rf(namespace, opts) + } + if rf, ok := ret.Get(0).(func(string, metav1.ListOptions) watch.Interface); ok { + r0 = rf(namespace, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(watch.Interface) + } + } + + if rf, ok := ret.Get(1).(func(string, metav1.ListOptions) error); ok { + r1 = rf(namespace, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WithImpersonation provides a mock function with given fields: impersonate +func (_m *PodClient) WithImpersonation(impersonate rest.ImpersonationConfig) (generic.ClientInterface[*v1.Pod, *v1.PodList], error) { + ret := _m.Called(impersonate) + + var r0 generic.ClientInterface[*v1.Pod, *v1.PodList] + var r1 error + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) (generic.ClientInterface[*v1.Pod, *v1.PodList], error)); ok { + return rf(impersonate) + } + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) generic.ClientInterface[*v1.Pod, *v1.PodList]); ok { + r0 = rf(impersonate) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.ClientInterface[*v1.Pod, *v1.PodList]) + } + } + + if rf, ok := ret.Get(1).(func(rest.ImpersonationConfig) error); ok { + r1 = rf(impersonate) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewPodClient creates a new instance of PodClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPodClient(t interface { + mock.TestingT + Cleanup(func()) +}) *PodClient { + mock := &PodClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/SettingController.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/SettingController.go new file mode 100644 index 0000000..beb4213 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/mocks/SettingController.go @@ -0,0 +1,367 @@ +// Code generated by mockery v2.30.16. DO NOT EDIT. + +package mocks + +import ( + context "context" + + cache "k8s.io/client-go/tools/cache" + + generic "github.com/rancher/wrangler/v3/pkg/generic" + + management_cattle_iov3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + mock "github.com/stretchr/testify/mock" + + rest "k8s.io/client-go/rest" + + schema "k8s.io/apimachinery/pkg/runtime/schema" + + time "time" + + types "k8s.io/apimachinery/pkg/types" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + watch "k8s.io/apimachinery/pkg/watch" +) + +// SettingController is an autogenerated mock type for the SettingController type +type SettingController struct { + mock.Mock +} + +// AddGenericHandler provides a mock function with given fields: ctx, name, handler +func (_m *SettingController) AddGenericHandler(ctx context.Context, name string, handler generic.Handler) { + _m.Called(ctx, name, handler) +} + +// AddGenericRemoveHandler provides a mock function with given fields: ctx, name, handler +func (_m *SettingController) AddGenericRemoveHandler(ctx context.Context, name string, handler generic.Handler) { + _m.Called(ctx, name, handler) +} + +// Cache provides a mock function with given fields: +func (_m *SettingController) Cache() generic.NonNamespacedCacheInterface[*management_cattle_iov3.Setting] { + ret := _m.Called() + + var r0 generic.NonNamespacedCacheInterface[*management_cattle_iov3.Setting] + if rf, ok := ret.Get(0).(func() generic.NonNamespacedCacheInterface[*management_cattle_iov3.Setting]); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.NonNamespacedCacheInterface[*management_cattle_iov3.Setting]) + } + } + + return r0 +} + +// Create provides a mock function with given fields: _a0 +func (_m *SettingController) Create(_a0 *management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error) { + ret := _m.Called(_a0) + + var r0 *management_cattle_iov3.Setting + var r1 error + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) *management_cattle_iov3.Setting); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.Setting) + } + } + + if rf, ok := ret.Get(1).(func(*management_cattle_iov3.Setting) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Delete provides a mock function with given fields: name, options +func (_m *SettingController) Delete(name string, options *v1.DeleteOptions) error { + ret := _m.Called(name, options) + + var r0 error + if rf, ok := ret.Get(0).(func(string, *v1.DeleteOptions) error); ok { + r0 = rf(name, options) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Enqueue provides a mock function with given fields: name +func (_m *SettingController) Enqueue(name string) { + _m.Called(name) +} + +// EnqueueAfter provides a mock function with given fields: name, duration +func (_m *SettingController) EnqueueAfter(name string, duration time.Duration) { + _m.Called(name, duration) +} + +// Get provides a mock function with given fields: name, options +func (_m *SettingController) Get(name string, options v1.GetOptions) (*management_cattle_iov3.Setting, error) { + ret := _m.Called(name, options) + + var r0 *management_cattle_iov3.Setting + var r1 error + if rf, ok := ret.Get(0).(func(string, v1.GetOptions) (*management_cattle_iov3.Setting, error)); ok { + return rf(name, options) + } + if rf, ok := ret.Get(0).(func(string, v1.GetOptions) *management_cattle_iov3.Setting); ok { + r0 = rf(name, options) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.Setting) + } + } + + if rf, ok := ret.Get(1).(func(string, v1.GetOptions) error); ok { + r1 = rf(name, options) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GroupVersionKind provides a mock function with given fields: +func (_m *SettingController) GroupVersionKind() schema.GroupVersionKind { + ret := _m.Called() + + var r0 schema.GroupVersionKind + if rf, ok := ret.Get(0).(func() schema.GroupVersionKind); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(schema.GroupVersionKind) + } + + return r0 +} + +// Informer provides a mock function with given fields: +func (_m *SettingController) Informer() cache.SharedIndexInformer { + ret := _m.Called() + + var r0 cache.SharedIndexInformer + if rf, ok := ret.Get(0).(func() cache.SharedIndexInformer); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(cache.SharedIndexInformer) + } + } + + return r0 +} + +// List provides a mock function with given fields: opts +func (_m *SettingController) List(opts v1.ListOptions) (*management_cattle_iov3.SettingList, error) { + ret := _m.Called(opts) + + var r0 *management_cattle_iov3.SettingList + var r1 error + if rf, ok := ret.Get(0).(func(v1.ListOptions) (*management_cattle_iov3.SettingList, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(v1.ListOptions) *management_cattle_iov3.SettingList); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.SettingList) + } + } + + if rf, ok := ret.Get(1).(func(v1.ListOptions) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OnChange provides a mock function with given fields: ctx, name, sync +func (_m *SettingController) OnChange(ctx context.Context, name string, sync generic.ObjectHandler[*management_cattle_iov3.Setting]) { + _m.Called(ctx, name, sync) +} + +// OnRemove provides a mock function with given fields: ctx, name, sync +func (_m *SettingController) OnRemove(ctx context.Context, name string, sync generic.ObjectHandler[*management_cattle_iov3.Setting]) { + _m.Called(ctx, name, sync) +} + +// Patch provides a mock function with given fields: name, pt, data, subresources +func (_m *SettingController) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*management_cattle_iov3.Setting, error) { + _va := make([]interface{}, len(subresources)) + for _i := range subresources { + _va[_i] = subresources[_i] + } + var _ca []interface{} + _ca = append(_ca, name, pt, data) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 *management_cattle_iov3.Setting + var r1 error + if rf, ok := ret.Get(0).(func(string, types.PatchType, []byte, ...string) (*management_cattle_iov3.Setting, error)); ok { + return rf(name, pt, data, subresources...) + } + if rf, ok := ret.Get(0).(func(string, types.PatchType, []byte, ...string) *management_cattle_iov3.Setting); ok { + r0 = rf(name, pt, data, subresources...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.Setting) + } + } + + if rf, ok := ret.Get(1).(func(string, types.PatchType, []byte, ...string) error); ok { + r1 = rf(name, pt, data, subresources...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Update provides a mock function with given fields: _a0 +func (_m *SettingController) Update(_a0 *management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error) { + ret := _m.Called(_a0) + + var r0 *management_cattle_iov3.Setting + var r1 error + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) *management_cattle_iov3.Setting); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.Setting) + } + } + + if rf, ok := ret.Get(1).(func(*management_cattle_iov3.Setting) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateStatus provides a mock function with given fields: _a0 +func (_m *SettingController) UpdateStatus(_a0 *management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error) { + ret := _m.Called(_a0) + + var r0 *management_cattle_iov3.Setting + var r1 error + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) (*management_cattle_iov3.Setting, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(*management_cattle_iov3.Setting) *management_cattle_iov3.Setting); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*management_cattle_iov3.Setting) + } + } + + if rf, ok := ret.Get(1).(func(*management_cattle_iov3.Setting) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Updater provides a mock function with given fields: +func (_m *SettingController) Updater() generic.Updater { + ret := _m.Called() + + var r0 generic.Updater + if rf, ok := ret.Get(0).(func() generic.Updater); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.Updater) + } + } + + return r0 +} + +// Watch provides a mock function with given fields: opts +func (_m *SettingController) Watch(opts v1.ListOptions) (watch.Interface, error) { + ret := _m.Called(opts) + + var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(v1.ListOptions) (watch.Interface, error)); ok { + return rf(opts) + } + if rf, ok := ret.Get(0).(func(v1.ListOptions) watch.Interface); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(watch.Interface) + } + } + + if rf, ok := ret.Get(1).(func(v1.ListOptions) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WithImpersonation provides a mock function with given fields: impersonate +func (_m *SettingController) WithImpersonation(impersonate rest.ImpersonationConfig) (generic.NonNamespacedClientInterface[*management_cattle_iov3.Setting, *management_cattle_iov3.SettingList], error) { + ret := _m.Called(impersonate) + + var r0 generic.NonNamespacedClientInterface[*management_cattle_iov3.Setting, *management_cattle_iov3.SettingList] + var r1 error + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) (generic.NonNamespacedClientInterface[*management_cattle_iov3.Setting, *management_cattle_iov3.SettingList], error)); ok { + return rf(impersonate) + } + if rf, ok := ret.Get(0).(func(rest.ImpersonationConfig) generic.NonNamespacedClientInterface[*management_cattle_iov3.Setting, *management_cattle_iov3.SettingList]); ok { + r0 = rf(impersonate) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(generic.NonNamespacedClientInterface[*management_cattle_iov3.Setting, *management_cattle_iov3.SettingList]) + } + } + + if rf, ok := ret.Get(1).(func(rest.ImpersonationConfig) error); ok { + r1 = rf(impersonate) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewSettingController creates a new instance of SettingController. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewSettingController(t interface { + mock.TestingT + Cleanup(func()) +}) *SettingController { + mock := &SettingController{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system.go new file mode 100644 index 0000000..a799ee7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system.go @@ -0,0 +1,515 @@ +package system + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "strconv" + "time" + + "github.com/Masterminds/semver/v3" + jsonpatch "github.com/evanphx/json-patch" + "github.com/rancher/rancher/pkg/api/steve/catalog/types" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/merr" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/release" + "helm.sh/helm/v3/pkg/repo" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" +) + +var ( + installUser = &user.DefaultInfo{ + Name: "helm-installer", + UID: "helm-installer", + Groups: []string{ + "system:masters", + }, + } +) + +type desiredKey struct { + namespace string + name string + minVersion string + exactVersion string + installImageOverride string +} + +type desired struct { + key desiredKey + values map[string]interface{} + takeOwnership bool +} + +type HelmClient interface { + // ListReleases lists all releases in the given namespace that matches the given name and stateMask + ListReleases(namespace, name string, stateMask action.ListStates) ([]*release.Release, error) +} + +type OperationClient interface { + // Upgrade gets the upgrade commands using the given namespace, name and options and gets the user using the isApp flag as false. + // Returns a catalog.Operation that represents the helm operation to be created + Upgrade(ctx context.Context, user user.Info, namespace, name string, options io.Reader, imageOverride string) (*catalog.Operation, error) + // Uninstall gets the uninstallation commands using the given namespace, name and options and gets the user information using the isApp flag as true. + // Returns a catalog.Operation that represents the helm operation to be created + Uninstall(ctx context.Context, user user.Info, namespace, name string, options io.Reader, imageOverride string) (*catalog.Operation, error) +} + +type ContentClient interface { + // Index receives a repository's name and namespace and returns its index file. + Index(namespace, name, targetK8sVersion string, skipFilter bool) (*repo.IndexFile, error) +} + +type Manager struct { + ctx context.Context + operation OperationClient + content ContentClient + pods corecontrollers.PodClient + desiredCharts map[desiredKey]map[string]interface{} + sync chan desired + refreshIntervalChange chan struct{} + settings mgmtcontrollers.SettingController + trigger chan struct{} + clusterRepos catalogcontrollers.ClusterRepoController + helmClient HelmClient +} + +func NewManager(ctx context.Context, + contentManager ContentClient, + ops OperationClient, + pods corecontrollers.PodClient, + settings mgmtcontrollers.SettingController, + clusterRepos catalogcontrollers.ClusterRepoController, + helmClient HelmClient) (*Manager, error) { + + m := &Manager{ + ctx: ctx, + operation: ops, + content: contentManager, + pods: pods, + sync: make(chan desired, 10), + desiredCharts: map[desiredKey]map[string]interface{}{}, + refreshIntervalChange: make(chan struct{}, 1), + settings: settings, + trigger: make(chan struct{}, 1), + clusterRepos: clusterRepos, + helmClient: helmClient, + } + + return m, nil +} + +func (m *Manager) Start(ctx context.Context) { + m.ctx = ctx + go m.runSync() + + m.settings.OnChange(ctx, "system-feature-chart-refresh", m.onSetting) + m.clusterRepos.OnChange(ctx, "catalog-refresh-trigger", m.onTrigger) +} + +func (m *Manager) onSetting(key string, obj *v3.Setting) (*v3.Setting, error) { + if key != settings.SystemFeatureChartRefreshSeconds.Name { + return obj, nil + } + + m.refreshIntervalChange <- struct{}{} + return obj, nil +} + +func (m *Manager) onTrigger(_ string, obj *catalog.ClusterRepo) (*catalog.ClusterRepo, error) { + // We only want to trigger on "rancher-charts" in order to ensure that required charts, such as + // Fleet, are up-to-date upon Rancher startup or upgrade. + if obj == nil || obj.DeletionTimestamp != nil || obj.Name != "rancher-charts" { + return obj, nil + } + + select { + case m.trigger <- struct{}{}: + default: + } + return obj, nil +} + +func (m *Manager) runSync() { + t := time.NewTicker(getIntervalOrDefault(settings.SystemFeatureChartRefreshSeconds.Get())) + defer t.Stop() + + for { + select { + case <-m.refreshIntervalChange: + t = time.NewTicker(getIntervalOrDefault(settings.SystemFeatureChartRefreshSeconds.Get())) + case <-m.ctx.Done(): + return + case <-m.trigger: + _ = m.installCharts(m.desiredCharts, true) + case <-t.C: + _ = m.installCharts(m.desiredCharts, true) + case desired := <-m.sync: + v, exists := m.desiredCharts[desired.key] + // newly requested or changed + if !exists || !equality.Semantic.DeepEqual(v, desired.values) { + err := m.installCharts( + map[desiredKey]map[string]interface{}{ + desired.key: desired.values, + }, + desired.takeOwnership, + ) + if err == nil { + m.desiredCharts[desired.key] = desired.values + } + } + } + } +} + +// getIntervalOrDefault Converts the input to a time.Duration or returns a default value +func getIntervalOrDefault(interval string) time.Duration { + i, err := strconv.Atoi(interval) + if err != nil { + return 21600 * time.Second + } + return time.Duration(i) * time.Second +} + +// installCharts installs charts with takeOwnership. +func (m *Manager) installCharts(charts map[desiredKey]map[string]interface{}, takeOwnership bool) error { + var errs []error + + for key, values := range charts { + for { + if err := m.install(key.namespace, key.name, key.minVersion, key.exactVersion, values, takeOwnership, key.installImageOverride); err == repo.ErrNoChartName || apierrors.IsNotFound(err) { + logrus.Errorf("Failed to find system chart %s will try again in 5 seconds: %v", key.name, err) + time.Sleep(5 * time.Second) + continue + } else if err != nil { + logrus.Errorf("Failed to install system chart %s: %v", key.name, err) + errs = append(errs, err) + } + break + } + } + return merr.NewErrors(errs...) +} + +func (m *Manager) Uninstall(namespace, name string) error { + if ok, err := m.hasStatus(namespace, name, action.ListDeployed|action.ListFailed); err != nil { + return err + } else if !ok { + return nil + } + + uninstall, err := json.Marshal(types.ChartUninstallAction{ + Timeout: &metav1.Duration{Duration: 5 * time.Minute}, + }) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + + op, err := m.operation.Uninstall(m.ctx, installUser, namespace, name, bytes.NewBuffer(uninstall), "") + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + + return m.waitPodDone(op) +} + +func (m *Manager) Ensure(namespace, name, minVersion, exactVersion string, values map[string]interface{}, takeOwnership bool, installImageOverride string) error { + go func() { + m.sync <- desired{ + key: desiredKey{ + namespace: namespace, + name: name, + minVersion: minVersion, + exactVersion: exactVersion, + installImageOverride: installImageOverride, + }, + values: values, + takeOwnership: takeOwnership, + } + }() + return nil +} + +func (m *Manager) Remove(namespace, name string) { + for k := range m.desiredCharts { + if k.namespace == namespace && k.name == name { + delete(m.desiredCharts, k) + } + } +} + +// install tries to install a new version of a chart. +// If the exact version is provided, it will try to install it regardless of whether minVersion is provided. +// If minVersion is provided on its own, it will try to install it only if the current version is earlier than +// minVersion. +// A failure to find a chart for a provided version leads to an error being thrown, without any change in state. +// If no version is provided, it will try to install the latest version available. +// If a release with the version to be installed is already installed, or is pending install, upgrade or rollback, this +// does nothing. +func (m *Manager) install(namespace, name, minVersion, exactVersion string, values map[string]interface{}, takeOwnership bool, installImageOverride string) error { + index, err := m.content.Index("", "rancher-charts", "", true) + if err != nil { + return err + } + + const latestVersionMatcher = ">=0-a" // latest - special syntax to match everything including pre-release builds + + v := latestVersionMatcher + var isExact bool + + if exactVersion != "" { + v = exactVersion + isExact = true + } else if minVersion != "" { + v = minVersion + // not enforcing exact version install, to keep any possibly newer, already installed version. + // This prevents automated downgrades of updates done manually through the web UI, eg. for Fleet. + } + + // This method from the Helm fork doesn't return an error when given a non-existent version, unfortunately. + // It instead returns the latest version in the index. + chart, err := index.Get(name, v) + if err != nil { + // The helm library is using github.com/pkg/errors which is deprecated + return fmt.Errorf(err.Error()) + } + // Because of the behavior of `index.Get`, we need this check. + if v != latestVersionMatcher && chart.Version != v { + return fmt.Errorf("specified version %s doesn't exist in the index", v) + } + + // If the chart version is already installed, we do nothing + installed, desiredVersion, desiredValue, err := m.isInstalled(namespace, name, minVersion, chart.Version, isExact, values) + if err != nil { + return err + } else if installed { + return nil + } + + // If the release is pending install, upgrade or rollback, we do nothing. + // If it's not, we proceed to create an operation + if ok, err := m.hasStatus(namespace, name, action.ListPendingInstall|action.ListPendingUpgrade|action.ListPendingRollback); err != nil { + return err + } else if ok { + return nil + } + + timeout := settings.SystemManagedChartsOperationTimeout.Get() + t, err := time.ParseDuration(timeout) + if err != nil { + t = 5 * time.Minute + } + upgrade, err := json.Marshal(types.ChartUpgradeAction{ + Timeout: &metav1.Duration{Duration: t}, + Wait: true, + Install: true, + MaxHistory: 5, + Namespace: namespace, + TakeOwnership: takeOwnership, + Charts: []types.ChartUpgrade{ + { + ChartName: name, + Version: desiredVersion, + ReleaseName: name, + Values: desiredValue, + ResetValues: true, + }, + }, + }) + if err != nil { + return err + } + + op, err := m.operation.Upgrade(m.ctx, installUser, "", "rancher-charts", bytes.NewBuffer(upgrade), installImageOverride) + if err != nil { + return err + } + + return m.waitPodDone(op) +} + +// waitPodDone receives an operation, get its pod and check if it's done and +// returns nil if it is. If not, creates a watch for the pod with a timeout of 300 seconds +// that will check if the pod is done and return nil. If the watch timeouts, it returns an error. +func (m *Manager) waitPodDone(op *catalog.Operation) error { + pod, err := m.pods.Get(op.Status.PodNamespace, op.Status.PodName, metav1.GetOptions{}) + if err != nil { + return err + } + + if ok, err := podDone(op.Status.Chart, pod); err != nil { + return err + } else if ok { + return nil + } + + sec := int64(60) + resp, err := m.pods.Watch(op.Status.PodNamespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + pod.Name, + ResourceVersion: pod.ResourceVersion, + TimeoutSeconds: &sec, + }) + if err != nil { + return err + } + defer func() { + go func() { + for range resp.ResultChan() { + } + }() + resp.Stop() + }() + + for event := range resp.ResultChan() { + newPod, ok := event.Object.(*v1.Pod) + if !ok { + continue + } + if ok, err := podDone(op.Status.Chart, newPod); err != nil { + return err + } else if ok { + return nil + } + } + + return fmt.Errorf("pod %s/%s failed, watch closed", pod.Namespace, pod.Name) +} + +// podDone receives a chart name and a pod. It will check all containers in that pod and +// get one named helm to check if it terminated and if it did so successfully. +// If there's no helm container or if the container didn't terminate, it returns false. +func podDone(chart string, newPod *v1.Pod) (bool, error) { + for _, container := range newPod.Status.ContainerStatuses { + if container.Name != "helm" { + continue + } + if container.State.Terminated != nil { + if container.State.Terminated.ExitCode == 0 { + return true, nil + } + return false, fmt.Errorf("failed to install %s, pod %s/%s exited %d", chart, + newPod.Namespace, newPod.Name, container.State.Terminated.ExitCode) + } + } + return false, nil +} + +// isInstalled gets all releases for a particular namespace and name that has the status action.ListDeployed. +// It calls the desiredVersionAndValues function with it to return if the chart is installed, the desired version and the desired values for it. +func (m *Manager) isInstalled(namespace, name, minVersion, desiredVersion string, isExact bool, desiredValue map[string]interface{}) (bool, string, map[string]interface{}, error) { + releases, err := m.helmClient.ListReleases(namespace, name, action.ListDeployed) + if err != nil { + return false, "", nil, err + } + + return desiredVersionAndValues(releases, minVersion, desiredVersion, isExact, desiredValue) +} + +// desiredVersionAndValues returns whether the release is installed. If not, it returns the desired version and Helm values. +// Callers must provide the desired version. If isExact is true, then the resulting value is the desiredVersion, which +// may result in a forced upgrade or downgrade. Otherwise, the desiredVersion signifies the latest version, which may +// or may not be installed, depending on the value of the min version. +func desiredVersionAndValues(releases []*release.Release, minVersion, desiredVersion string, isExact bool, desiredValues map[string]any) (bool, string, map[string]interface{}, error) { + for _, r := range releases { + if r.Info.Status != release.StatusDeployed { + continue + } + if desiredValues == nil { + desiredValues = map[string]interface{}{} + } + releaseConfig := r.Config + if releaseConfig == nil { + releaseConfig = map[string]interface{}{} + } + + desiredValuesJSON, err := json.Marshal(desiredValues) + if err != nil { + return false, "", nil, err + } + + actualValueJSON, err := json.Marshal(releaseConfig) + if err != nil { + return false, "", nil, err + } + + patchedJSON, err := jsonpatch.MergePatch(actualValueJSON, desiredValuesJSON) + if err != nil { + return false, "", nil, err + } + + desiredValues = map[string]interface{}{} + if err := json.Unmarshal(patchedJSON, &desiredValues); err != nil { + return false, "", nil, err + } + + current, err := semver.NewVersion(r.Chart.Metadata.Version) + if err != nil { + return false, "", nil, err + } + + desired, err := semver.NewVersion(desiredVersion) + if err != nil { + return false, "", nil, err + } + + if isExact { + if !current.Equal(desired) { + return false, desired.String(), desiredValues, nil + } + } + + if minVersion != "" { + min, err := semver.NewVersion(minVersion) + if err != nil { + return false, "", nil, err + } + if desired.LessThan(min) { + logrus.Errorf("available chart version (%s) for %s is less than the min version (%s) ", desired, r.Chart.Name(), min) + return false, "", nil, repo.ErrNoChartName + } + if min.LessThan(current) || min.Equal(current) { + // If the current deployed version is greater or equal than the min version but configuration has changed, return false and upgrade with the current version + if !bytes.Equal(patchedJSON, actualValueJSON) { + return false, r.Chart.Metadata.Version, desiredValues, nil + } + logrus.Debugf("Skipping installing/upgrading desired version %s for release %s, since current version %s is greater or equal to minimal required version %s", desired.String(), r.Name, current.String(), minVersion) + return true, "", nil, nil + } + } + + if (desired.LessThan(current) || desired.Equal(current)) && bytes.Equal(patchedJSON, actualValueJSON) { + return true, "", nil, nil + } + } + return false, desiredVersion, desiredValues, nil +} + +// hasStatus gets all releases in the given namespace that matches the given name and stateMask and +// returns true if there's any release that matches those conditions. +func (m *Manager) hasStatus(namespace, name string, stateMask action.ListStates) (bool, error) { + releases, err := m.helmClient.ListReleases(namespace, name, stateMask) + if err != nil { + return false, err + } + + return len(releases) != 0, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system_test.go new file mode 100644 index 0000000..2334b59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/catalogv2/system/system_test.go @@ -0,0 +1,602 @@ +package system + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "testing" + "time" + + types2 "github.com/rancher/rancher/pkg/api/steve/catalog/types" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/system/mocks" + "github.com/stretchr/testify/mock" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/repo" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/release" +) + +func TestGetIntervalOrDefault(t *testing.T) { + t.Parallel() + asserts := assert.New(t) + type testCase struct { + name string + input string + expected time.Duration + } + + testCases := []testCase{ + { + name: "Should return the default value of 21600 if input string is empty", + input: "", + expected: 21600 * time.Second, + }, + { + name: "Should return the default value of 21600 if input string is invalid", + input: "foo", + expected: 21600 * time.Second, + }, + { + name: "Should return the time.Duration that corresponds to the given input", + input: "60", + expected: 60 * time.Second, + }, + } + + for _, test := range testCases { + actual := getIntervalOrDefault(test.input) + asserts.Equal(test.expected, actual, test.name) + } +} + +func TestIsInstalled(t *testing.T) { + t.Parallel() + + standardValues := map[string]any{ + "name": "Pablo", + } + newValues := map[string]any{ + "name": "Winston", + } + + tests := []struct { + name string + latestVersion string + minVersion string + desiredValues map[string]any + + expectedInstalled bool + expectedVersion string + expectedValues map[string]any + expectedErr bool + }{ + { + name: "latest and min are the same as current", + latestVersion: "1.0.0", + minVersion: "1.0.0", + desiredValues: standardValues, + + expectedInstalled: true, + expectedVersion: "", + expectedValues: nil, + expectedErr: false, + }, + { + name: "latest and min are the same as current but values changed", + latestVersion: "1.0.0", + minVersion: "1.0.0", + desiredValues: newValues, + + expectedInstalled: false, + expectedVersion: "1.0.0", + expectedValues: newValues, + expectedErr: false, + }, + { + name: "new available latest is ignored", + latestVersion: "1.1.0", + minVersion: "1.0.0", + desiredValues: standardValues, + + expectedInstalled: true, + expectedVersion: "", + expectedValues: nil, + expectedErr: false, + }, + { + name: "new latest is ignored but new values are honored", + latestVersion: "1.1.0", + minVersion: "1.0.0", + desiredValues: newValues, + + expectedInstalled: false, + expectedVersion: "1.0.0", + expectedValues: newValues, + expectedErr: false, + }, + { + name: "higher min and even higher latest", + latestVersion: "1.2.0", + minVersion: "1.1.0", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "1.2.0", + expectedValues: standardValues, + expectedErr: false, + }, + { + name: "higher min and even higher latest with values changed", + latestVersion: "1.2.0", + minVersion: "1.1.0", + desiredValues: newValues, + + expectedInstalled: false, + expectedVersion: "1.2.0", + expectedValues: newValues, + expectedErr: false, + }, + { + name: "both min and latest are higher", + latestVersion: "1.2.0", + minVersion: "1.2.0", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "1.2.0", + expectedValues: standardValues, + expectedErr: false, + }, + { + name: "both min and latest are higher but values changed", + latestVersion: "1.2.0", + minVersion: "1.2.0", + desiredValues: newValues, + + expectedInstalled: false, + expectedVersion: "1.2.0", + expectedValues: newValues, + expectedErr: false, + }, + { + name: "latest is higher but min is lower than current", + latestVersion: "1.1.0", + minVersion: "0.9.0", + desiredValues: standardValues, + + expectedInstalled: true, + expectedVersion: "", + expectedValues: nil, + expectedErr: false, + }, + { + name: "latest is higher but min is lower than current but values changed", + latestVersion: "1.1.0", + minVersion: "0.9.0", + desiredValues: newValues, + + expectedInstalled: false, + expectedVersion: "1.0.0", + expectedValues: newValues, + expectedErr: false, + }, + { + name: "min version is higher but latest is lower than current", + latestVersion: "0.9.0", + minVersion: "2.0.0", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "", + expectedValues: nil, + expectedErr: true, + }, + { + name: "invalid latest version", + latestVersion: "pug", + minVersion: "0.9.0", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "", + expectedValues: nil, + expectedErr: true, + }, + { + name: "invalid min version", + latestVersion: "1.3.0", + minVersion: "pug", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "", + expectedValues: nil, + expectedErr: true, + }, + { + name: "min and latest are both unset", + latestVersion: "", + minVersion: "", + desiredValues: standardValues, + + expectedInstalled: false, + expectedVersion: "", + expectedValues: nil, + expectedErr: true, + }, + { + name: "values are merged", + latestVersion: "1.3.0", + minVersion: "1.2.0", + desiredValues: map[string]any{ + "foo": "bar", + }, + + expectedInstalled: false, + expectedVersion: "1.3.0", + expectedValues: map[string]any{ + "name": "Pablo", + "foo": "bar", + }, + expectedErr: false, + }, + { + name: "new values are empty yet old ones remain in merge", + latestVersion: "1.3.0", + minVersion: "1.2.0", + desiredValues: map[string]any{}, + + expectedInstalled: false, + expectedVersion: "1.3.0", + expectedValues: map[string]any{ + "name": "Pablo", + }, + expectedErr: false, + }, + } + + releases := []*release.Release{ + { + Name: "rancher-webhook", + Info: &release.Info{Status: release.StatusDeployed}, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + }, + Config: standardValues, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + installed, version, values, err := desiredVersionAndValues(releases, test.minVersion, test.latestVersion, false, test.desiredValues) + assert.Equal(t, test.expectedInstalled, installed) + assert.Equal(t, test.expectedVersion, version) + assert.Equal(t, test.expectedValues, values) + assert.Equal(t, test.expectedErr, err != nil) + }) + } +} + +func TestIsInstalledExactVersion(t *testing.T) { + t.Parallel() + + standardValues := map[string]any{ + "name": "Pablo", + } + tests := []struct { + name string + desiredVersion string + desiredValues map[string]any + isExact bool + + expectedInstalled bool + expectedVersion string + expectedValues map[string]any + expectedErr bool + }{ + { + name: "exact is higher than current", + desiredVersion: "2.0.0", + desiredValues: standardValues, + isExact: true, + + expectedInstalled: false, + expectedVersion: "2.0.0", + expectedValues: standardValues, + expectedErr: false, + }, + { + name: "exact is lower than current with no downgrade", + desiredVersion: "0.9.0", + desiredValues: standardValues, + + expectedInstalled: true, + expectedVersion: "", + expectedValues: nil, + expectedErr: false, + }, + { + name: "exact is lower than current with downgrade", + desiredVersion: "0.9.0", + desiredValues: standardValues, + isExact: true, + + expectedInstalled: false, + expectedVersion: "0.9.0", + expectedValues: standardValues, + expectedErr: false, + }, + { + name: "exact matches current", + desiredVersion: "1.0.0", + desiredValues: nil, + isExact: true, + + expectedInstalled: true, + expectedVersion: "", + expectedValues: nil, + expectedErr: false, + }, + { + name: "exact matches current but values changed and got merged", + desiredVersion: "1.0.0", + desiredValues: map[string]any{ + "foo": "bar", + }, + isExact: true, + + expectedInstalled: false, + expectedVersion: "1.0.0", + expectedValues: map[string]any{ + "name": "Pablo", + "foo": "bar", + }, + expectedErr: false, + }, + } + + releases := []*release.Release{ + { + Name: "rancher-webhook", + Info: &release.Info{Status: release.StatusDeployed}, + Chart: &chart.Chart{ + Metadata: &chart.Metadata{ + Version: "1.0.0", + }, + }, + Config: standardValues, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + // Note that the minVersion argument must be an empty string. + installed, version, values, err := desiredVersionAndValues(releases, "", test.desiredVersion, test.isExact, test.desiredValues) + assert.Equal(t, test.expectedInstalled, installed) + assert.Equal(t, test.expectedVersion, version) + assert.Equal(t, test.expectedValues, values) + assert.Equal(t, test.expectedErr, err != nil) + }) + } +} + +func TestInstall(t *testing.T) { + t.Parallel() + asserts := assert.New(t) + type testInput struct { + namespace string + name string + minVersion string + exactVersion string + values map[string]interface{} + takeOwnership bool + installImageOverride string + } + type testMocks struct { + indexOutput *repo.IndexFile + indexError error + isInstalledReleasesOutput []*release.Release + isInstalledReleasesError error + hasStatusOutput []*release.Release + hasStatusError error + upgradeOutput *catalog.Operation + upgradeError error + podGetOutput *v1.Pod + podGetError error + } + type testCase struct { + name string + input testInput + mocks testMocks + expected error + skip bool + } + mockIndex := &repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": []*repo.ChartVersion{{Metadata: &chart.Metadata{Version: "102.0.0+up1.0.0"}}}, + }, + } + + testCases := []testCase{ + { + name: "Should return error if not able to get index file from rancher-charts", + mocks: testMocks{indexError: errors.New("error")}, + expected: errors.New("error"), + }, + { + name: "Should return error if the exact version of the chart does not exists", + input: testInput{ + name: "test-chart", + exactVersion: "100.1.0+up0.6.1", + }, + mocks: testMocks{ + indexOutput: mockIndex, + }, + expected: fmt.Errorf("no chart version found for test-chart-100.1.0+up0.6.1"), + }, + { + name: "Should do nothing if the chart is already installed", + input: testInput{ + namespace: "test", + name: "test-chart", + }, + mocks: testMocks{ + indexOutput: mockIndex, + isInstalledReleasesOutput: []*release.Release{{ + Info: &release.Info{Status: release.StatusDeployed}, + Chart: &chart.Chart{Metadata: &chart.Metadata{Version: "102.0.0+up1.0.0"}}, + }}, + }, + expected: nil, + }, + { + name: "Should return error if not able list helm releases", + input: testInput{ + name: "test-chart", + }, + mocks: testMocks{ + indexOutput: mockIndex, + isInstalledReleasesError: errors.New("error"), + }, + expected: errors.New("error"), + }, + { + name: "Should return error if the available chart version is lower than the min version", + input: testInput{ + namespace: "test", + name: "test-chart", + minVersion: "102.0.0+up1.0.0", + }, + mocks: testMocks{ + indexOutput: &repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": []*repo.ChartVersion{{Metadata: &chart.Metadata{Version: "101.0.0+up1.0.0"}}}, + }, + }, + isInstalledReleasesOutput: []*release.Release{{ + Info: &release.Info{Status: release.StatusDeployed}, + Chart: &chart.Chart{Metadata: &chart.Metadata{Version: "100.0.0+up1.0.0"}}, + }}, + }, + expected: errors.New("no chart version found for test-chart-102.0.0+up1.0.0"), + }, + { + name: "Should do nothing if chart is pending upgrade, pending install or pending rollback", + input: testInput{ + name: "test-chart", + }, + mocks: testMocks{ + indexOutput: mockIndex, + hasStatusOutput: []*release.Release{{ + Chart: &chart.Chart{Metadata: &chart.Metadata{Version: "102.0.0+up1.0.0"}}, + }}, + }, + expected: nil, + }, + { + name: "Should return an error if it fails to create an upgrade operation", + input: testInput{ + name: "test-chart", + }, + mocks: testMocks{ + indexOutput: mockIndex, + upgradeError: errors.New("error"), + }, + expected: errors.New("error"), + }, + { + name: "Should return nil after the operation pod finishes successfully", + input: testInput{ + name: "test-chart", + }, + mocks: testMocks{ + indexOutput: mockIndex, + upgradeOutput: &catalog.Operation{ + Status: catalog.OperationStatus{ + PodName: "install-operation", + PodNamespace: "cattle-system", + }, + }, + podGetOutput: &v1.Pod{Status: v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{ + { + Name: "helm", + State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{ExitCode: 0}}, + }, + }}}, + }, + expected: nil, + }, + { + name: "Should return nil after the operation pod finishes successfully with exact version install", + input: testInput{ + name: "test-chart", + exactVersion: "102.0.0+up1.0.0", + }, + mocks: testMocks{ + indexOutput: &repo.IndexFile{ + Entries: map[string]repo.ChartVersions{ + "test-chart": []*repo.ChartVersion{ + {Metadata: &chart.Metadata{Version: "102.0.0+up1.0.0"}}, + {Metadata: &chart.Metadata{Version: "102.1.0+up1.0.0"}}, + }, + }, + }, + upgradeOutput: &catalog.Operation{ + Status: catalog.OperationStatus{ + PodName: "install-operation", + PodNamespace: "cattle-system", + }, + }, + podGetOutput: &v1.Pod{Status: v1.PodStatus{ContainerStatuses: []v1.ContainerStatus{ + { + Name: "helm", + State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{ExitCode: 0}}, + }, + }}}, + }, + expected: nil, + }, + } + + for _, test := range testCases { + if test.skip { + continue + } + var versionMatcher interface{} + if test.input.exactVersion != "" { + versionMatcher = mock.MatchedBy(func(r io.Reader) bool { + upgradeArgs := &types2.ChartUpgradeAction{} + _ = json.NewDecoder(r).Decode(upgradeArgs) + return upgradeArgs.Charts[0].Version == test.input.exactVersion + }) + } else { + versionMatcher = mock.Anything + } + contentMock, opsMock, podsMock, settingsMock, helmMock, clusterRepoMock := + &mocks.ContentClient{}, &mocks.OperationClient{}, &mocks.PodClient{}, &mocks.SettingController{}, &mocks.HelmClient{}, &mocks.ClusterRepoController{} + + contentMock.On("Index", "", "rancher-charts", "", true).Return(test.mocks.indexOutput, test.mocks.indexError) + helmMock.On("ListReleases", test.input.namespace, test.input.name, action.ListDeployed).Return(test.mocks.isInstalledReleasesOutput, test.mocks.isInstalledReleasesError) + helmMock.On("ListReleases", test.input.namespace, test.input.name, action.ListPendingInstall|action.ListPendingUpgrade|action.ListPendingRollback).Return(test.mocks.hasStatusOutput, test.mocks.hasStatusError) + opsMock.On("Upgrade", context.TODO(), installUser, "", "rancher-charts", versionMatcher, test.input.installImageOverride).Return(test.mocks.upgradeOutput, test.mocks.upgradeError) + if test.mocks.podGetOutput != nil || test.mocks.podGetError != nil { + podsMock.On("Get", test.mocks.upgradeOutput.Status.PodNamespace, test.mocks.upgradeOutput.Status.PodName, metav1.GetOptions{}).Return(test.mocks.podGetOutput, test.mocks.podGetError) + } + manager, _ := NewManager(context.TODO(), contentMock, opsMock, podsMock, settingsMock, clusterRepoMock, helmMock) + err := manager.install(test.input.namespace, test.input.name, test.input.minVersion, test.input.exactVersion, test.input.values, test.input.takeOwnership, test.input.installImageOverride) + asserts.Equal(test.expected, err, test.name) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cert/cert.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cert/cert.go new file mode 100644 index 0000000..aba7a26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cert/cert.go @@ -0,0 +1,133 @@ +package cert + +import ( + "bytes" + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/hex" + "encoding/pem" + "fmt" + "strings" + "time" + + "github.com/pkg/errors" +) + +type CertificateInfo struct { + Algorithm string `json:"algorithm"` + CN string `json:"cn"` + Fingerprint string `json:"certFingerprint"` + ExpiresAt time.Time `json:"expiresAt"` + IssuedAt time.Time `json:"issuedAt"` + Issuer string `json:"issuer"` + KeySize int `json:"keySize"` + SerialNumber string `json:"serialNumber"` + SubjectAlternativeNames []string `json:"subjectAlternativeNames"` + Version int `json:"version"` +} + +func matchAndKeySize(publicKey crypto.PublicKey, privateKey crypto.PrivateKey) (string, int, bool) { + if algo, size, ok := rsaMatchAndKeySize(publicKey, privateKey); ok { + return algo, size, ok + } + + pubKey, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + return "", 0, false + } + + privKey, ok := privateKey.(*ecdsa.PrivateKey) + if !ok { + return "", 0, false + } + + return "ECC", 256, privKey.X.Cmp(pubKey.X) == 0 && privKey.Y.Cmp(privKey.Y) == 0 +} + +func rsaMatchAndKeySize(publicKey crypto.PublicKey, privateKey crypto.PrivateKey) (string, int, bool) { + pubKey, ok := publicKey.(*rsa.PublicKey) + if !ok { + return "", 0, false + } + + privKey, ok := privateKey.(*rsa.PrivateKey) + if !ok { + return "", 0, false + } + + return "RSA", len(privKey.N.Bytes()), pubKey.N.Cmp(privKey.N) == 0 +} + +func Info(pemCerts, pemKey string) (*CertificateInfo, error) { + block, _ := pem.Decode([]byte(pemKey)) + if block == nil { + return nil, errors.New("failed to decode key: not valid pem format") + } + + var key crypto.PrivateKey + var err error + if key, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if key, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + if key, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + return nil, errors.Wrap(err, "failed to parse key: key must be PEM encoded EC, PKCS1, or PKCS8") + } + } + } + + rest := []byte(pemCerts) + for { + block, rest = pem.Decode(rest) + var certInfo CertificateInfo + + if block == nil { + break + } + + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, errors.Wrap(err, "failed to parse certificate") + } + + algo, size, ok := matchAndKeySize(cert.PublicKey, key) + if !ok { + continue + } + + certInfo.Algorithm = algo + certInfo.Fingerprint = fingerprint(block.Bytes) + certInfo.CN = cert.Subject.CommonName + certInfo.ExpiresAt = cert.NotAfter + certInfo.IssuedAt = cert.NotBefore + certInfo.Issuer = cert.Issuer.CommonName + certInfo.KeySize = size + certInfo.SerialNumber = cert.SerialNumber.String() + certInfo.Version = cert.Version + + for _, name := range cert.DNSNames { + certInfo.SubjectAlternativeNames = append(certInfo.SubjectAlternativeNames, name) + } + + for _, ip := range cert.IPAddresses { + certInfo.SubjectAlternativeNames = append(certInfo.SubjectAlternativeNames, ip.String()) + } + + return &certInfo, nil + } + + return nil, fmt.Errorf("failed to find cert that matched private key") +} + +func fingerprint(data []byte) string { + digest := sha1.Sum(data) + buf := &bytes.Buffer{} + for i := 0; i < len(digest); i++ { + if buf.Len() > 0 { + buf.WriteString(":") + } + buf.WriteString(strings.ToUpper(hex.EncodeToString(digest[i : i+1]))) + } + return buf.String() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/channelserver/channelserver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/channelserver/channelserver.go new file mode 100644 index 0000000..14ec9a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/channelserver/channelserver.go @@ -0,0 +1,201 @@ +package channelserver + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strconv" + "sync" + "time" + + "github.com/blang/semver" + "github.com/rancher/channelserver/pkg/config" + "github.com/rancher/channelserver/pkg/model" + "github.com/rancher/channelserver/pkg/server" + "github.com/rancher/rancher/pkg/catalog/utils" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/schemas" + "github.com/sirupsen/logrus" +) + +var ( + configs map[string]*config.Config + configsInit sync.Once + action chan string +) + +func GetURLAndInterval() (string, time.Duration) { + val := map[string]interface{}{} + if err := json.Unmarshal([]byte(settings.RkeMetadataConfig.Get()), &val); err != nil { + logrus.Errorf("failed to parse %s value: %v", settings.RkeMetadataConfig.Name, err) + return "", 0 + } + url := data.Object(val).String("url") + minutes, _ := strconv.Atoi(data.Object(val).String("refresh-interval-minutes")) + if minutes <= 0 { + minutes = 1440 + } + + return url, time.Duration(minutes) * time.Minute +} + +// getChannelServerArg will return with an argument to pass to channel server +// to indicate the server version that is running. If the current version is +// not a proper release version, the argument will be set to the dev version. +func getChannelServerArg() string { + serverVersion := settings.ServerVersion.Get() + if !utils.ReleaseServerVersion(serverVersion) { + return settings.RancherVersionDev + } + return serverVersion +} + +type DynamicInterval struct { + subKey string +} + +func (d *DynamicInterval) Wait(ctx context.Context) bool { + start := time.Now() + for { + select { + case <-time.After(time.Second): + _, duration := GetURLAndInterval() + if start.Add(duration).Before(time.Now()) { + return true + } + continue + case msg := <-action: + if msg == d.subKey { + logrus.Infof("getReleaseConfig: reloading config for %s", d.subKey) + return true + } + action <- msg + case <-ctx.Done(): + return false + } + } +} + +func Refresh() { + action <- "k3s" + action <- "rke2" +} + +type DynamicSource struct{} + +func (d *DynamicSource) URL() string { + url, _ := GetURLAndInterval() + return url +} + +func GetReleaseConfigByRuntimeAndVersion(ctx context.Context, runtime, kubernetesVersion string) model.Release { + fallBack := model.Release{ + AgentArgs: map[string]schemas.Field{}, + ServerArgs: map[string]schemas.Field{}, + } + for _, releaseData := range GetReleaseConfigByRuntime(ctx, runtime).ReleasesConfig().Releases { + if releaseData.Version == kubernetesVersion { + return releaseData + } + for k, v := range releaseData.ServerArgs { + fallBack.ServerArgs[k] = v + } + for k, v := range releaseData.AgentArgs { + fallBack.AgentArgs[k] = v + } + } + return fallBack +} + +func GetReleaseConfigByRuntime(ctx context.Context, runtime string) *config.Config { + configsInit.Do(func() { + urls := []config.Source{ + &DynamicSource{}, + config.StringSource("/var/lib/rancher-data/driver-metadata/data.json"), + } + configs = map[string]*config.Config{ + "k3s": config.NewConfig(ctx, "k3s", &DynamicInterval{"k3s"}, getChannelServerArg(), "rancher", urls), + "rke2": config.NewConfig(ctx, "rke2", &DynamicInterval{"rke2"}, getChannelServerArg(), "rancher", urls), + } + }) + return configs[runtime] +} + +func NewHandler(ctx context.Context) http.Handler { + action = make(chan string, 2) + return server.NewHandler(map[string]*config.Config{ + "v1-k3s-release": GetReleaseConfigByRuntime(ctx, "k3s"), + "v1-rke2-release": GetReleaseConfigByRuntime(ctx, "rke2"), + }) +} + +func GetDefaultByRuntimeAndServerVersion(ctx context.Context, runtime, serverVersion string) string { + version, err := getDefaultFromAppDefaultsByRuntimeAndServerVersion(ctx, runtime, serverVersion) + if err != nil { + logrus.Debugf("[channelserver] fallback to use the default channel due to: %v", err) + version = getDefaultFromChannel(ctx, runtime, "default") + } + return version +} + +func getDefaultFromAppDefaultsByRuntimeAndServerVersion(ctx context.Context, runtime, serverVersion string) (string, error) { + var defaultVersionRange string + serverVersionParsed, err := semver.ParseTolerant(serverVersion) + if err != nil { + return "", fmt.Errorf("fails to parse the server version: %v", err) + } + config := GetReleaseConfigByRuntime(ctx, runtime) + appDefaults := config.AppDefaultsConfig().AppDefaults + if len(appDefaults) == 0 { + return "", fmt.Errorf("no %s appDefaults is found for %s", runtime, serverVersion) + } + // We use the first entry from the list. We do not expect the list contains more than one entry. + for _, appDefault := range appDefaults[0].Defaults { + avrParsed, err := semver.ParseRange(appDefault.AppVersion) + if err != nil { + return "", fmt.Errorf("faild to parse %s appVersionRange for %s: %v", runtime, serverVersion, err) + } + if avrParsed(serverVersionParsed) { + defaultVersionRange = appDefault.DefaultVersion + continue + } + } + if defaultVersionRange == "" { + return "", fmt.Errorf("no matching %s defaultVersionRange is found for %s", runtime, serverVersion) + } + dvrParsed, err := semver.ParseRange(defaultVersionRange) + if err != nil { + return "", fmt.Errorf("faild to parse %s defaultVersionRange for %s: %v", runtime, serverVersion, err) + } + + var candidate []semver.Version + for _, release := range config.ReleasesConfig().Releases { + version, err := semver.ParseTolerant(release.Version) + if err != nil { + logrus.Debugf("fails to parse the release version %s: %v", release.Version, err) + continue + } + if dvrParsed(version) { + candidate = append(candidate, version) + } + } + if len(candidate) == 0 { + return "", fmt.Errorf("no %s version is found for %s", runtime, serverVersion) + } + // the build metadata parts are ignored when sorting versions for now; + // ideally they should be since k3s/RKE2 releases use it to establish order of precedence + semver.Sort(candidate) + return candidate[len(candidate)-1].String(), nil +} + +func getDefaultFromChannel(ctx context.Context, runtime, channelName string) string { + config := GetReleaseConfigByRuntime(ctx, runtime) + for _, c := range config.ChannelsConfig().Channels { + if c.Name == channelName { + return c.Latest + } + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_bootstrap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_bootstrap.go new file mode 100644 index 0000000..c08c35c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_bootstrap.go @@ -0,0 +1,12 @@ +package client + +const ( + BootstrapType = "bootstrap" + BootstrapFieldConfigRef = "configRef" + BootstrapFieldDataSecretName = "dataSecretName" +) + +type Bootstrap struct { + ConfigRef *ObjectReference `json:"configRef,omitempty" yaml:"configRef,omitempty"` + DataSecretName string `json:"dataSecretName,omitempty" yaml:"dataSecretName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_client.go new file mode 100644 index 0000000..5b354b6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_client.go @@ -0,0 +1,26 @@ +package client + +import ( + "github.com/rancher/norman/clientbase" +) + +type Client struct { + clientbase.APIBaseClient + + Machine MachineOperations +} + +func NewClient(opts *clientbase.ClientOpts) (*Client, error) { + baseClient, err := clientbase.NewAPIClient(opts) + if err != nil { + return nil, err + } + + client := &Client{ + APIBaseClient: baseClient, + } + + client.Machine = newMachineClient(client) + + return client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_cluster.x-k8s.io.machine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_cluster.x-k8s.io.machine.go new file mode 100644 index 0000000..d02cffc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_cluster.x-k8s.io.machine.go @@ -0,0 +1,144 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + MachineType = "cluster.x-k8s.io.machine" + MachineFieldAnnotations = "annotations" + MachineFieldBootstrap = "bootstrap" + MachineFieldClusterName = "clusterName" + MachineFieldCreated = "created" + MachineFieldCreatorID = "creatorId" + MachineFieldFailureDomain = "failureDomain" + MachineFieldInfrastructureRef = "infrastructureRef" + MachineFieldLabels = "labels" + MachineFieldName = "name" + MachineFieldNodeDeletionTimeout = "nodeDeletionTimeout" + MachineFieldNodeDrainTimeout = "nodeDrainTimeout" + MachineFieldNodeVolumeDetachTimeout = "nodeVolumeDetachTimeout" + MachineFieldOwnerReferences = "ownerReferences" + MachineFieldProviderID = "providerID" + MachineFieldRemoved = "removed" + MachineFieldState = "state" + MachineFieldStatus = "status" + MachineFieldTransitioning = "transitioning" + MachineFieldTransitioningMessage = "transitioningMessage" + MachineFieldUUID = "uuid" + MachineFieldVersion = "version" +) + +type Machine struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Bootstrap *Bootstrap `json:"bootstrap,omitempty" yaml:"bootstrap,omitempty"` + ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + FailureDomain string `json:"failureDomain,omitempty" yaml:"failureDomain,omitempty"` + InfrastructureRef *ObjectReference `json:"infrastructureRef,omitempty" yaml:"infrastructureRef,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NodeDeletionTimeout *Duration `json:"nodeDeletionTimeout,omitempty" yaml:"nodeDeletionTimeout,omitempty"` + NodeDrainTimeout *Duration `json:"nodeDrainTimeout,omitempty" yaml:"nodeDrainTimeout,omitempty"` + NodeVolumeDetachTimeout *Duration `json:"nodeVolumeDetachTimeout,omitempty" yaml:"nodeVolumeDetachTimeout,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProviderID string `json:"providerID,omitempty" yaml:"providerID,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *MachineStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` +} + +type MachineCollection struct { + types.Collection + Data []Machine `json:"data,omitempty"` + client *MachineClient +} + +type MachineClient struct { + apiClient *Client +} + +type MachineOperations interface { + List(opts *types.ListOpts) (*MachineCollection, error) + ListAll(opts *types.ListOpts) (*MachineCollection, error) + Create(opts *Machine) (*Machine, error) + Update(existing *Machine, updates interface{}) (*Machine, error) + Replace(existing *Machine) (*Machine, error) + ByID(id string) (*Machine, error) + Delete(container *Machine) error +} + +func newMachineClient(apiClient *Client) *MachineClient { + return &MachineClient{ + apiClient: apiClient, + } +} + +func (c *MachineClient) Create(container *Machine) (*Machine, error) { + resp := &Machine{} + err := c.apiClient.Ops.DoCreate(MachineType, container, resp) + return resp, err +} + +func (c *MachineClient) Update(existing *Machine, updates interface{}) (*Machine, error) { + resp := &Machine{} + err := c.apiClient.Ops.DoUpdate(MachineType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *MachineClient) Replace(obj *Machine) (*Machine, error) { + resp := &Machine{} + err := c.apiClient.Ops.DoReplace(MachineType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *MachineClient) List(opts *types.ListOpts) (*MachineCollection, error) { + resp := &MachineCollection{} + err := c.apiClient.Ops.DoList(MachineType, opts, resp) + resp.client = c + return resp, err +} + +func (c *MachineClient) ListAll(opts *types.ListOpts) (*MachineCollection, error) { + resp := &MachineCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *MachineCollection) Next() (*MachineCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &MachineCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *MachineClient) ByID(id string) (*Machine, error) { + resp := &Machine{} + err := c.apiClient.Ops.DoByID(MachineType, id, resp) + return resp, err +} + +func (c *MachineClient) Delete(container *Machine) error { + return c.apiClient.Ops.DoResourceDelete(MachineType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_condition.go new file mode 100644 index 0000000..2ce9df0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ConditionType = "condition" + ConditionFieldLastTransitionTime = "lastTransitionTime" + ConditionFieldMessage = "message" + ConditionFieldReason = "reason" + ConditionFieldSeverity = "severity" + ConditionFieldStatus = "status" + ConditionFieldType = "type" +) + +type Condition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Severity string `json:"severity,omitempty" yaml:"severity,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_duration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_duration.go new file mode 100644 index 0000000..cf0920c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_duration.go @@ -0,0 +1,8 @@ +package client + +const ( + DurationType = "duration" +) + +type Duration struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_address.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_address.go new file mode 100644 index 0000000..6d74288 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_address.go @@ -0,0 +1,12 @@ +package client + +const ( + MachineAddressType = "machineAddress" + MachineAddressFieldAddress = "address" + MachineAddressFieldType = "type" +) + +type MachineAddress struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_spec.go new file mode 100644 index 0000000..e557347 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_spec.go @@ -0,0 +1,26 @@ +package client + +const ( + MachineSpecType = "machineSpec" + MachineSpecFieldBootstrap = "bootstrap" + MachineSpecFieldClusterName = "clusterName" + MachineSpecFieldFailureDomain = "failureDomain" + MachineSpecFieldInfrastructureRef = "infrastructureRef" + MachineSpecFieldNodeDeletionTimeout = "nodeDeletionTimeout" + MachineSpecFieldNodeDrainTimeout = "nodeDrainTimeout" + MachineSpecFieldNodeVolumeDetachTimeout = "nodeVolumeDetachTimeout" + MachineSpecFieldProviderID = "providerID" + MachineSpecFieldVersion = "version" +) + +type MachineSpec struct { + Bootstrap *Bootstrap `json:"bootstrap,omitempty" yaml:"bootstrap,omitempty"` + ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"` + FailureDomain string `json:"failureDomain,omitempty" yaml:"failureDomain,omitempty"` + InfrastructureRef *ObjectReference `json:"infrastructureRef,omitempty" yaml:"infrastructureRef,omitempty"` + NodeDeletionTimeout *Duration `json:"nodeDeletionTimeout,omitempty" yaml:"nodeDeletionTimeout,omitempty"` + NodeDrainTimeout *Duration `json:"nodeDrainTimeout,omitempty" yaml:"nodeDrainTimeout,omitempty"` + NodeVolumeDetachTimeout *Duration `json:"nodeVolumeDetachTimeout,omitempty" yaml:"nodeVolumeDetachTimeout,omitempty"` + ProviderID string `json:"providerID,omitempty" yaml:"providerID,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_status.go new file mode 100644 index 0000000..6ae311d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_machine_status.go @@ -0,0 +1,32 @@ +package client + +const ( + MachineStatusType = "machineStatus" + MachineStatusFieldAddresses = "addresses" + MachineStatusFieldBootstrapReady = "bootstrapReady" + MachineStatusFieldCertificatesExpiryDate = "certificatesExpiryDate" + MachineStatusFieldConditions = "conditions" + MachineStatusFieldFailureMessage = "failureMessage" + MachineStatusFieldFailureReason = "failureReason" + MachineStatusFieldInfrastructureReady = "infrastructureReady" + MachineStatusFieldLastUpdated = "lastUpdated" + MachineStatusFieldNodeInfo = "nodeInfo" + MachineStatusFieldNodeRef = "nodeRef" + MachineStatusFieldObservedGeneration = "observedGeneration" + MachineStatusFieldPhase = "phase" +) + +type MachineStatus struct { + Addresses []MachineAddress `json:"addresses,omitempty" yaml:"addresses,omitempty"` + BootstrapReady bool `json:"bootstrapReady,omitempty" yaml:"bootstrapReady,omitempty"` + CertificatesExpiryDate string `json:"certificatesExpiryDate,omitempty" yaml:"certificatesExpiryDate,omitempty"` + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + FailureMessage string `json:"failureMessage,omitempty" yaml:"failureMessage,omitempty"` + FailureReason string `json:"failureReason,omitempty" yaml:"failureReason,omitempty"` + InfrastructureReady bool `json:"infrastructureReady,omitempty" yaml:"infrastructureReady,omitempty"` + LastUpdated string `json:"lastUpdated,omitempty" yaml:"lastUpdated,omitempty"` + NodeInfo *NodeSystemInfo `json:"nodeInfo,omitempty" yaml:"nodeInfo,omitempty"` + NodeRef *ObjectReference `json:"nodeRef,omitempty" yaml:"nodeRef,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + Phase string `json:"phase,omitempty" yaml:"phase,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_node_system_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_node_system_info.go new file mode 100644 index 0000000..c5632f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_node_system_info.go @@ -0,0 +1,28 @@ +package client + +const ( + NodeSystemInfoType = "nodeSystemInfo" + NodeSystemInfoFieldArchitecture = "architecture" + NodeSystemInfoFieldBootID = "bootID" + NodeSystemInfoFieldContainerRuntimeVersion = "containerRuntimeVersion" + NodeSystemInfoFieldKernelVersion = "kernelVersion" + NodeSystemInfoFieldKubeProxyVersion = "kubeProxyVersion" + NodeSystemInfoFieldKubeletVersion = "kubeletVersion" + NodeSystemInfoFieldMachineID = "machineID" + NodeSystemInfoFieldOSImage = "osImage" + NodeSystemInfoFieldOperatingSystem = "operatingSystem" + NodeSystemInfoFieldSystemUUID = "systemUUID" +) + +type NodeSystemInfo struct { + Architecture string `json:"architecture,omitempty" yaml:"architecture,omitempty"` + BootID string `json:"bootID,omitempty" yaml:"bootID,omitempty"` + ContainerRuntimeVersion string `json:"containerRuntimeVersion,omitempty" yaml:"containerRuntimeVersion,omitempty"` + KernelVersion string `json:"kernelVersion,omitempty" yaml:"kernelVersion,omitempty"` + KubeProxyVersion string `json:"kubeProxyVersion,omitempty" yaml:"kubeProxyVersion,omitempty"` + KubeletVersion string `json:"kubeletVersion,omitempty" yaml:"kubeletVersion,omitempty"` + MachineID string `json:"machineID,omitempty" yaml:"machineID,omitempty"` + OSImage string `json:"osImage,omitempty" yaml:"osImage,omitempty"` + OperatingSystem string `json:"operatingSystem,omitempty" yaml:"operatingSystem,omitempty"` + SystemUUID string `json:"systemUUID,omitempty" yaml:"systemUUID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_meta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_meta.go new file mode 100644 index 0000000..29f7963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_meta.go @@ -0,0 +1,28 @@ +package client + +const ( + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldFinalizers = "finalizers" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldOwnerReferences = "ownerReferences" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldSelfLink = "selfLink" + ObjectMetaFieldUUID = "uuid" +) + +type ObjectMeta struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + Finalizers []string `json:"finalizers,omitempty" yaml:"finalizers,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_reference.go new file mode 100644 index 0000000..2a5f94e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_object_reference.go @@ -0,0 +1,22 @@ +package client + +const ( + ObjectReferenceType = "objectReference" + ObjectReferenceFieldAPIVersion = "apiVersion" + ObjectReferenceFieldFieldPath = "fieldPath" + ObjectReferenceFieldKind = "kind" + ObjectReferenceFieldName = "name" + ObjectReferenceFieldNamespace = "namespace" + ObjectReferenceFieldResourceVersion = "resourceVersion" + ObjectReferenceFieldUID = "uid" +) + +type ObjectReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_owner_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_owner_reference.go new file mode 100644 index 0000000..5f4436b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v1beta1/zz_generated_owner_reference.go @@ -0,0 +1,20 @@ +package client + +const ( + OwnerReferenceType = "ownerReference" + OwnerReferenceFieldAPIVersion = "apiVersion" + OwnerReferenceFieldBlockOwnerDeletion = "blockOwnerDeletion" + OwnerReferenceFieldController = "controller" + OwnerReferenceFieldKind = "kind" + OwnerReferenceFieldName = "name" + OwnerReferenceFieldUID = "uid" +) + +type OwnerReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" yaml:"blockOwnerDeletion,omitempty"` + Controller *bool `json:"controller,omitempty" yaml:"controller,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service.go new file mode 100644 index 0000000..e03898a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service.go @@ -0,0 +1,140 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + APIServiceType = "apiService" + APIServiceFieldAnnotations = "annotations" + APIServiceFieldCABundle = "caBundle" + APIServiceFieldConditions = "conditions" + APIServiceFieldCreated = "created" + APIServiceFieldCreatorID = "creatorId" + APIServiceFieldGroup = "group" + APIServiceFieldGroupPriorityMinimum = "groupPriorityMinimum" + APIServiceFieldInsecureSkipTLSVerify = "insecureSkipTLSVerify" + APIServiceFieldLabels = "labels" + APIServiceFieldName = "name" + APIServiceFieldOwnerReferences = "ownerReferences" + APIServiceFieldRemoved = "removed" + APIServiceFieldService = "service" + APIServiceFieldState = "state" + APIServiceFieldTransitioning = "transitioning" + APIServiceFieldTransitioningMessage = "transitioningMessage" + APIServiceFieldUUID = "uuid" + APIServiceFieldVersion = "version" + APIServiceFieldVersionPriority = "versionPriority" +) + +type APIService struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CABundle string `json:"caBundle,omitempty" yaml:"caBundle,omitempty"` + Conditions []APIServiceCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + GroupPriorityMinimum int64 `json:"groupPriorityMinimum,omitempty" yaml:"groupPriorityMinimum,omitempty"` + InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty" yaml:"insecureSkipTLSVerify,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Service *ServiceReference `json:"service,omitempty" yaml:"service,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + VersionPriority int64 `json:"versionPriority,omitempty" yaml:"versionPriority,omitempty"` +} + +type APIServiceCollection struct { + types.Collection + Data []APIService `json:"data,omitempty"` + client *APIServiceClient +} + +type APIServiceClient struct { + apiClient *Client +} + +type APIServiceOperations interface { + List(opts *types.ListOpts) (*APIServiceCollection, error) + ListAll(opts *types.ListOpts) (*APIServiceCollection, error) + Create(opts *APIService) (*APIService, error) + Update(existing *APIService, updates interface{}) (*APIService, error) + Replace(existing *APIService) (*APIService, error) + ByID(id string) (*APIService, error) + Delete(container *APIService) error +} + +func newAPIServiceClient(apiClient *Client) *APIServiceClient { + return &APIServiceClient{ + apiClient: apiClient, + } +} + +func (c *APIServiceClient) Create(container *APIService) (*APIService, error) { + resp := &APIService{} + err := c.apiClient.Ops.DoCreate(APIServiceType, container, resp) + return resp, err +} + +func (c *APIServiceClient) Update(existing *APIService, updates interface{}) (*APIService, error) { + resp := &APIService{} + err := c.apiClient.Ops.DoUpdate(APIServiceType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *APIServiceClient) Replace(obj *APIService) (*APIService, error) { + resp := &APIService{} + err := c.apiClient.Ops.DoReplace(APIServiceType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *APIServiceClient) List(opts *types.ListOpts) (*APIServiceCollection, error) { + resp := &APIServiceCollection{} + err := c.apiClient.Ops.DoList(APIServiceType, opts, resp) + resp.client = c + return resp, err +} + +func (c *APIServiceClient) ListAll(opts *types.ListOpts) (*APIServiceCollection, error) { + resp := &APIServiceCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *APIServiceCollection) Next() (*APIServiceCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &APIServiceCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *APIServiceClient) ByID(id string) (*APIService, error) { + resp := &APIService{} + err := c.apiClient.Ops.DoByID(APIServiceType, id, resp) + return resp, err +} + +func (c *APIServiceClient) Delete(container *APIService) error { + return c.apiClient.Ops.DoResourceDelete(APIServiceType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_condition.go new file mode 100644 index 0000000..10b7f6c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + APIServiceConditionType = "apiServiceCondition" + APIServiceConditionFieldLastTransitionTime = "lastTransitionTime" + APIServiceConditionFieldMessage = "message" + APIServiceConditionFieldReason = "reason" + APIServiceConditionFieldStatus = "status" + APIServiceConditionFieldType = "type" +) + +type APIServiceCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_spec.go new file mode 100644 index 0000000..b850958 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_spec.go @@ -0,0 +1,22 @@ +package client + +const ( + APIServiceSpecType = "apiServiceSpec" + APIServiceSpecFieldCABundle = "caBundle" + APIServiceSpecFieldGroup = "group" + APIServiceSpecFieldGroupPriorityMinimum = "groupPriorityMinimum" + APIServiceSpecFieldInsecureSkipTLSVerify = "insecureSkipTLSVerify" + APIServiceSpecFieldService = "service" + APIServiceSpecFieldVersion = "version" + APIServiceSpecFieldVersionPriority = "versionPriority" +) + +type APIServiceSpec struct { + CABundle string `json:"caBundle,omitempty" yaml:"caBundle,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + GroupPriorityMinimum int64 `json:"groupPriorityMinimum,omitempty" yaml:"groupPriorityMinimum,omitempty"` + InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty" yaml:"insecureSkipTLSVerify,omitempty"` + Service *ServiceReference `json:"service,omitempty" yaml:"service,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + VersionPriority int64 `json:"versionPriority,omitempty" yaml:"versionPriority,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_status.go new file mode 100644 index 0000000..4e9b11f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_api_service_status.go @@ -0,0 +1,10 @@ +package client + +const ( + APIServiceStatusType = "apiServiceStatus" + APIServiceStatusFieldConditions = "conditions" +) + +type APIServiceStatus struct { + Conditions []APIServiceCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_aws_elastic_block_store_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_aws_elastic_block_store_volume_source.go new file mode 100644 index 0000000..5765e83 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_aws_elastic_block_store_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + AWSElasticBlockStoreVolumeSourceType = "awsElasticBlockStoreVolumeSource" + AWSElasticBlockStoreVolumeSourceFieldFSType = "fsType" + AWSElasticBlockStoreVolumeSourceFieldPartition = "partition" + AWSElasticBlockStoreVolumeSourceFieldReadOnly = "readOnly" + AWSElasticBlockStoreVolumeSourceFieldVolumeID = "volumeID" +) + +type AWSElasticBlockStoreVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_disk_volume_source.go new file mode 100644 index 0000000..28920c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_disk_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + AzureDiskVolumeSourceType = "azureDiskVolumeSource" + AzureDiskVolumeSourceFieldCachingMode = "cachingMode" + AzureDiskVolumeSourceFieldDataDiskURI = "diskURI" + AzureDiskVolumeSourceFieldDiskName = "diskName" + AzureDiskVolumeSourceFieldFSType = "fsType" + AzureDiskVolumeSourceFieldKind = "kind" + AzureDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type AzureDiskVolumeSource struct { + CachingMode string `json:"cachingMode,omitempty" yaml:"cachingMode,omitempty"` + DataDiskURI string `json:"diskURI,omitempty" yaml:"diskURI,omitempty"` + DiskName string `json:"diskName,omitempty" yaml:"diskName,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_file_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_file_persistent_volume_source.go new file mode 100644 index 0000000..4fe943f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_azure_file_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + AzureFilePersistentVolumeSourceType = "azureFilePersistentVolumeSource" + AzureFilePersistentVolumeSourceFieldReadOnly = "readOnly" + AzureFilePersistentVolumeSourceFieldSecretName = "secretName" + AzureFilePersistentVolumeSourceFieldSecretNamespace = "secretNamespace" + AzureFilePersistentVolumeSourceFieldShareName = "shareName" +) + +type AzureFilePersistentVolumeSource struct { + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` + SecretNamespace string `json:"secretNamespace,omitempty" yaml:"secretNamespace,omitempty"` + ShareName string `json:"shareName,omitempty" yaml:"shareName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_ceph_fspersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_ceph_fspersistent_volume_source.go new file mode 100644 index 0000000..cdff275 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_ceph_fspersistent_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + CephFSPersistentVolumeSourceType = "cephFSPersistentVolumeSource" + CephFSPersistentVolumeSourceFieldMonitors = "monitors" + CephFSPersistentVolumeSourceFieldPath = "path" + CephFSPersistentVolumeSourceFieldReadOnly = "readOnly" + CephFSPersistentVolumeSourceFieldSecretFile = "secretFile" + CephFSPersistentVolumeSourceFieldSecretRef = "secretRef" + CephFSPersistentVolumeSourceFieldUser = "user" +) + +type CephFSPersistentVolumeSource struct { + Monitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretFile string `json:"secretFile,omitempty" yaml:"secretFile,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cinder_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cinder_persistent_volume_source.go new file mode 100644 index 0000000..e36020d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cinder_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + CinderPersistentVolumeSourceType = "cinderPersistentVolumeSource" + CinderPersistentVolumeSourceFieldFSType = "fsType" + CinderPersistentVolumeSourceFieldReadOnly = "readOnly" + CinderPersistentVolumeSourceFieldSecretRef = "secretRef" + CinderPersistentVolumeSourceFieldVolumeID = "volumeID" +) + +type CinderPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_client.go new file mode 100644 index 0000000..1f18a9b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_client.go @@ -0,0 +1,32 @@ +package client + +import ( + "github.com/rancher/norman/clientbase" +) + +type Client struct { + clientbase.APIBaseClient + + Namespace NamespaceOperations + PersistentVolume PersistentVolumeOperations + StorageClass StorageClassOperations + APIService APIServiceOperations +} + +func NewClient(opts *clientbase.ClientOpts) (*Client, error) { + baseClient, err := clientbase.NewAPIClient(opts) + if err != nil { + return nil, err + } + + client := &Client{ + APIBaseClient: baseClient, + } + + client.Namespace = newNamespaceClient(client) + client.PersistentVolume = newPersistentVolumeClient(client) + client.StorageClass = newStorageClassClient(client) + client.APIService = newAPIServiceClient(client) + + return client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_auth_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_auth_token.go new file mode 100644 index 0000000..2fe2927 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_auth_token.go @@ -0,0 +1,34 @@ +package client + +const ( + ClusterAuthTokenType = "clusterAuthToken" + ClusterAuthTokenFieldAnnotations = "annotations" + ClusterAuthTokenFieldCreated = "created" + ClusterAuthTokenFieldCreatorID = "creatorId" + ClusterAuthTokenFieldEnabled = "enabled" + ClusterAuthTokenFieldExpiresAt = "expiresAt" + ClusterAuthTokenFieldLabels = "labels" + ClusterAuthTokenFieldName = "name" + ClusterAuthTokenFieldNamespaceId = "namespaceId" + ClusterAuthTokenFieldOwnerReferences = "ownerReferences" + ClusterAuthTokenFieldRemoved = "removed" + ClusterAuthTokenFieldSecretKeyHash = "hash" + ClusterAuthTokenFieldUUID = "uuid" + ClusterAuthTokenFieldUserName = "userName" +) + +type ClusterAuthToken struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SecretKeyHash string `json:"hash,omitempty" yaml:"hash,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserName string `json:"userName,omitempty" yaml:"userName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_user_attribute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_user_attribute.go new file mode 100644 index 0000000..298dec4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_cluster_user_attribute.go @@ -0,0 +1,36 @@ +package client + +const ( + ClusterUserAttributeType = "clusterUserAttribute" + ClusterUserAttributeFieldAnnotations = "annotations" + ClusterUserAttributeFieldCreated = "created" + ClusterUserAttributeFieldCreatorID = "creatorId" + ClusterUserAttributeFieldEnabled = "enabled" + ClusterUserAttributeFieldExtraByProvider = "extraByProvider" + ClusterUserAttributeFieldGroups = "groups" + ClusterUserAttributeFieldLabels = "labels" + ClusterUserAttributeFieldLastRefresh = "lastRefresh" + ClusterUserAttributeFieldName = "name" + ClusterUserAttributeFieldNamespaceId = "namespaceId" + ClusterUserAttributeFieldNeedsRefresh = "needsRefresh" + ClusterUserAttributeFieldOwnerReferences = "ownerReferences" + ClusterUserAttributeFieldRemoved = "removed" + ClusterUserAttributeFieldUUID = "uuid" +) + +type ClusterUserAttribute struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + ExtraByProvider map[string]map[string][]string `json:"extraByProvider,omitempty" yaml:"extraByProvider,omitempty"` + Groups []string `json:"groups,omitempty" yaml:"groups,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastRefresh string `json:"lastRefresh,omitempty" yaml:"lastRefresh,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NeedsRefresh bool `json:"needsRefresh,omitempty" yaml:"needsRefresh,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_container_resource_limit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_container_resource_limit.go new file mode 100644 index 0000000..b36a499 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_container_resource_limit.go @@ -0,0 +1,16 @@ +package client + +const ( + ContainerResourceLimitType = "containerResourceLimit" + ContainerResourceLimitFieldLimitsCPU = "limitsCpu" + ContainerResourceLimitFieldLimitsMemory = "limitsMemory" + ContainerResourceLimitFieldRequestsCPU = "requestsCpu" + ContainerResourceLimitFieldRequestsMemory = "requestsMemory" +) + +type ContainerResourceLimit struct { + LimitsCPU string `json:"limitsCpu,omitempty" yaml:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty" yaml:"limitsMemory,omitempty"` + RequestsCPU string `json:"requestsCpu,omitempty" yaml:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty" yaml:"requestsMemory,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_csi_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_csi_persistent_volume_source.go new file mode 100644 index 0000000..8fadfe0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_csi_persistent_volume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + CSIPersistentVolumeSourceType = "csiPersistentVolumeSource" + CSIPersistentVolumeSourceFieldControllerExpandSecretRef = "controllerExpandSecretRef" + CSIPersistentVolumeSourceFieldControllerPublishSecretRef = "controllerPublishSecretRef" + CSIPersistentVolumeSourceFieldDriver = "driver" + CSIPersistentVolumeSourceFieldFSType = "fsType" + CSIPersistentVolumeSourceFieldNodeExpandSecretRef = "nodeExpandSecretRef" + CSIPersistentVolumeSourceFieldNodePublishSecretRef = "nodePublishSecretRef" + CSIPersistentVolumeSourceFieldNodeStageSecretRef = "nodeStageSecretRef" + CSIPersistentVolumeSourceFieldReadOnly = "readOnly" + CSIPersistentVolumeSourceFieldVolumeAttributes = "volumeAttributes" + CSIPersistentVolumeSourceFieldVolumeHandle = "volumeHandle" +) + +type CSIPersistentVolumeSource struct { + ControllerExpandSecretRef *SecretReference `json:"controllerExpandSecretRef,omitempty" yaml:"controllerExpandSecretRef,omitempty"` + ControllerPublishSecretRef *SecretReference `json:"controllerPublishSecretRef,omitempty" yaml:"controllerPublishSecretRef,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + NodeExpandSecretRef *SecretReference `json:"nodeExpandSecretRef,omitempty" yaml:"nodeExpandSecretRef,omitempty"` + NodePublishSecretRef *SecretReference `json:"nodePublishSecretRef,omitempty" yaml:"nodePublishSecretRef,omitempty"` + NodeStageSecretRef *SecretReference `json:"nodeStageSecretRef,omitempty" yaml:"nodeStageSecretRef,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeAttributes map[string]string `json:"volumeAttributes,omitempty" yaml:"volumeAttributes,omitempty"` + VolumeHandle string `json:"volumeHandle,omitempty" yaml:"volumeHandle,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_fc_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_fc_volume_source.go new file mode 100644 index 0000000..ebc0b63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_fc_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FCVolumeSourceType = "fcVolumeSource" + FCVolumeSourceFieldFSType = "fsType" + FCVolumeSourceFieldLun = "lun" + FCVolumeSourceFieldReadOnly = "readOnly" + FCVolumeSourceFieldTargetWWNs = "targetWWNs" + FCVolumeSourceFieldWWIDs = "wwids" +) + +type FCVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Lun *int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + TargetWWNs []string `json:"targetWWNs,omitempty" yaml:"targetWWNs,omitempty"` + WWIDs []string `json:"wwids,omitempty" yaml:"wwids,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flex_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flex_persistent_volume_source.go new file mode 100644 index 0000000..20de1fd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flex_persistent_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FlexPersistentVolumeSourceType = "flexPersistentVolumeSource" + FlexPersistentVolumeSourceFieldDriver = "driver" + FlexPersistentVolumeSourceFieldFSType = "fsType" + FlexPersistentVolumeSourceFieldOptions = "options" + FlexPersistentVolumeSourceFieldReadOnly = "readOnly" + FlexPersistentVolumeSourceFieldSecretRef = "secretRef" +) + +type FlexPersistentVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flocker_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flocker_volume_source.go new file mode 100644 index 0000000..802b77f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_flocker_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + FlockerVolumeSourceType = "flockerVolumeSource" + FlockerVolumeSourceFieldDatasetName = "datasetName" + FlockerVolumeSourceFieldDatasetUUID = "datasetUUID" +) + +type FlockerVolumeSource struct { + DatasetName string `json:"datasetName,omitempty" yaml:"datasetName,omitempty"` + DatasetUUID string `json:"datasetUUID,omitempty" yaml:"datasetUUID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_gce_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_gce_persistent_disk_volume_source.go new file mode 100644 index 0000000..726a448 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_gce_persistent_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + GCEPersistentDiskVolumeSourceType = "gcePersistentDiskVolumeSource" + GCEPersistentDiskVolumeSourceFieldFSType = "fsType" + GCEPersistentDiskVolumeSourceFieldPDName = "pdName" + GCEPersistentDiskVolumeSourceFieldPartition = "partition" + GCEPersistentDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type GCEPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PDName string `json:"pdName,omitempty" yaml:"pdName,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_glusterfs_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_glusterfs_persistent_volume_source.go new file mode 100644 index 0000000..bb754c3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_glusterfs_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + GlusterfsPersistentVolumeSourceType = "glusterfsPersistentVolumeSource" + GlusterfsPersistentVolumeSourceFieldEndpointsName = "endpoints" + GlusterfsPersistentVolumeSourceFieldEndpointsNamespace = "endpointsNamespace" + GlusterfsPersistentVolumeSourceFieldPath = "path" + GlusterfsPersistentVolumeSourceFieldReadOnly = "readOnly" +) + +type GlusterfsPersistentVolumeSource struct { + EndpointsName string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` + EndpointsNamespace string `json:"endpointsNamespace,omitempty" yaml:"endpointsNamespace,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_host_path_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_host_path_volume_source.go new file mode 100644 index 0000000..a7471bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_host_path_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + HostPathVolumeSourceType = "hostPathVolumeSource" + HostPathVolumeSourceFieldKind = "kind" + HostPathVolumeSourceFieldPath = "path" +) + +type HostPathVolumeSource struct { + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_iscsi_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_iscsi_persistent_volume_source.go new file mode 100644 index 0000000..ba659f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_iscsi_persistent_volume_source.go @@ -0,0 +1,30 @@ +package client + +const ( + ISCSIPersistentVolumeSourceType = "iscsiPersistentVolumeSource" + ISCSIPersistentVolumeSourceFieldDiscoveryCHAPAuth = "chapAuthDiscovery" + ISCSIPersistentVolumeSourceFieldFSType = "fsType" + ISCSIPersistentVolumeSourceFieldIQN = "iqn" + ISCSIPersistentVolumeSourceFieldISCSIInterface = "iscsiInterface" + ISCSIPersistentVolumeSourceFieldInitiatorName = "initiatorName" + ISCSIPersistentVolumeSourceFieldLun = "lun" + ISCSIPersistentVolumeSourceFieldPortals = "portals" + ISCSIPersistentVolumeSourceFieldReadOnly = "readOnly" + ISCSIPersistentVolumeSourceFieldSecretRef = "secretRef" + ISCSIPersistentVolumeSourceFieldSessionCHAPAuth = "chapAuthSession" + ISCSIPersistentVolumeSourceFieldTargetPortal = "targetPortal" +) + +type ISCSIPersistentVolumeSource struct { + DiscoveryCHAPAuth bool `json:"chapAuthDiscovery,omitempty" yaml:"chapAuthDiscovery,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + IQN string `json:"iqn,omitempty" yaml:"iqn,omitempty"` + ISCSIInterface string `json:"iscsiInterface,omitempty" yaml:"iscsiInterface,omitempty"` + InitiatorName string `json:"initiatorName,omitempty" yaml:"initiatorName,omitempty"` + Lun int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + Portals []string `json:"portals,omitempty" yaml:"portals,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + SessionCHAPAuth bool `json:"chapAuthSession,omitempty" yaml:"chapAuthSession,omitempty"` + TargetPortal string `json:"targetPortal,omitempty" yaml:"targetPortal,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_local_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_local_volume_source.go new file mode 100644 index 0000000..6dea350 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_local_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + LocalVolumeSourceType = "localVolumeSource" + LocalVolumeSourceFieldFSType = "fsType" + LocalVolumeSourceFieldPath = "path" +) + +type LocalVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace.go new file mode 100644 index 0000000..41874a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace.go @@ -0,0 +1,139 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespaceType = "namespace" + NamespaceFieldAnnotations = "annotations" + NamespaceFieldContainerDefaultResourceLimit = "containerDefaultResourceLimit" + NamespaceFieldCreated = "created" + NamespaceFieldCreatorID = "creatorId" + NamespaceFieldDescription = "description" + NamespaceFieldLabels = "labels" + NamespaceFieldName = "name" + NamespaceFieldOwnerReferences = "ownerReferences" + NamespaceFieldProjectID = "projectId" + NamespaceFieldRemoved = "removed" + NamespaceFieldResourceQuota = "resourceQuota" + NamespaceFieldState = "state" + NamespaceFieldTransitioning = "transitioning" + NamespaceFieldTransitioningMessage = "transitioningMessage" + NamespaceFieldUUID = "uuid" +) + +type Namespace struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ContainerDefaultResourceLimit *ContainerResourceLimit `json:"containerDefaultResourceLimit,omitempty" yaml:"containerDefaultResourceLimit,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceQuota *NamespaceResourceQuota `json:"resourceQuota,omitempty" yaml:"resourceQuota,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type NamespaceCollection struct { + types.Collection + Data []Namespace `json:"data,omitempty"` + client *NamespaceClient +} + +type NamespaceClient struct { + apiClient *Client +} + +type NamespaceOperations interface { + List(opts *types.ListOpts) (*NamespaceCollection, error) + ListAll(opts *types.ListOpts) (*NamespaceCollection, error) + Create(opts *Namespace) (*Namespace, error) + Update(existing *Namespace, updates interface{}) (*Namespace, error) + Replace(existing *Namespace) (*Namespace, error) + ByID(id string) (*Namespace, error) + Delete(container *Namespace) error + + ActionMove(resource *Namespace, input *NamespaceMove) error +} + +func newNamespaceClient(apiClient *Client) *NamespaceClient { + return &NamespaceClient{ + apiClient: apiClient, + } +} + +func (c *NamespaceClient) Create(container *Namespace) (*Namespace, error) { + resp := &Namespace{} + err := c.apiClient.Ops.DoCreate(NamespaceType, container, resp) + return resp, err +} + +func (c *NamespaceClient) Update(existing *Namespace, updates interface{}) (*Namespace, error) { + resp := &Namespace{} + err := c.apiClient.Ops.DoUpdate(NamespaceType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespaceClient) Replace(obj *Namespace) (*Namespace, error) { + resp := &Namespace{} + err := c.apiClient.Ops.DoReplace(NamespaceType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespaceClient) List(opts *types.ListOpts) (*NamespaceCollection, error) { + resp := &NamespaceCollection{} + err := c.apiClient.Ops.DoList(NamespaceType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespaceClient) ListAll(opts *types.ListOpts) (*NamespaceCollection, error) { + resp := &NamespaceCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespaceCollection) Next() (*NamespaceCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespaceCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespaceClient) ByID(id string) (*Namespace, error) { + resp := &Namespace{} + err := c.apiClient.Ops.DoByID(NamespaceType, id, resp) + return resp, err +} + +func (c *NamespaceClient) Delete(container *Namespace) error { + return c.apiClient.Ops.DoResourceDelete(NamespaceType, &container.Resource) +} + +func (c *NamespaceClient) ActionMove(resource *Namespace, input *NamespaceMove) error { + err := c.apiClient.Ops.DoAction(NamespaceType, "move", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_condition.go new file mode 100644 index 0000000..43e06ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + NamespaceConditionType = "namespaceCondition" + NamespaceConditionFieldLastTransitionTime = "lastTransitionTime" + NamespaceConditionFieldMessage = "message" + NamespaceConditionFieldReason = "reason" + NamespaceConditionFieldStatus = "status" + NamespaceConditionFieldType = "type" +) + +type NamespaceCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_move.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_move.go new file mode 100644 index 0000000..f55a561 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_move.go @@ -0,0 +1,10 @@ +package client + +const ( + NamespaceMoveType = "namespaceMove" + NamespaceMoveFieldProjectID = "projectId" +) + +type NamespaceMove struct { + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_resource_quota.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_resource_quota.go new file mode 100644 index 0000000..b170bf5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_resource_quota.go @@ -0,0 +1,10 @@ +package client + +const ( + NamespaceResourceQuotaType = "namespaceResourceQuota" + NamespaceResourceQuotaFieldLimit = "limit" +) + +type NamespaceResourceQuota struct { + Limit *ResourceQuotaLimit `json:"limit,omitempty" yaml:"limit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_spec.go new file mode 100644 index 0000000..78dcfcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_spec.go @@ -0,0 +1,8 @@ +package client + +const ( + NamespaceSpecType = "namespaceSpec" +) + +type NamespaceSpec struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_status.go new file mode 100644 index 0000000..e94d281 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_namespace_status.go @@ -0,0 +1,12 @@ +package client + +const ( + NamespaceStatusType = "namespaceStatus" + NamespaceStatusFieldConditions = "conditions" + NamespaceStatusFieldPhase = "phase" +) + +type NamespaceStatus struct { + Conditions []NamespaceCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Phase string `json:"phase,omitempty" yaml:"phase,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_nfs_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_nfs_volume_source.go new file mode 100644 index 0000000..bbaeecf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_nfs_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + NFSVolumeSourceType = "nfsVolumeSource" + NFSVolumeSourceFieldPath = "path" + NFSVolumeSourceFieldReadOnly = "readOnly" + NFSVolumeSourceFieldServer = "server" +) + +type NFSVolumeSource struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Server string `json:"server,omitempty" yaml:"server,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector.go new file mode 100644 index 0000000..721a16f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeSelectorType = "nodeSelector" + NodeSelectorFieldNodeSelectorTerms = "nodeSelectorTerms" +) + +type NodeSelector struct { + NodeSelectorTerms []NodeSelectorTerm `json:"nodeSelectorTerms,omitempty" yaml:"nodeSelectorTerms,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_requirement.go new file mode 100644 index 0000000..9338a8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + NodeSelectorRequirementType = "nodeSelectorRequirement" + NodeSelectorRequirementFieldKey = "key" + NodeSelectorRequirementFieldOperator = "operator" + NodeSelectorRequirementFieldValues = "values" +) + +type NodeSelectorRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_term.go new file mode 100644 index 0000000..11bf256 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_node_selector_term.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeSelectorTermType = "nodeSelectorTerm" + NodeSelectorTermFieldMatchExpressions = "matchExpressions" + NodeSelectorTermFieldMatchFields = "matchFields" +) + +type NodeSelectorTerm struct { + MatchExpressions []NodeSelectorRequirement `json:"matchExpressions,omitempty" yaml:"matchExpressions,omitempty"` + MatchFields []NodeSelectorRequirement `json:"matchFields,omitempty" yaml:"matchFields,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_meta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_meta.go new file mode 100644 index 0000000..29f7963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_meta.go @@ -0,0 +1,28 @@ +package client + +const ( + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldFinalizers = "finalizers" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldOwnerReferences = "ownerReferences" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldSelfLink = "selfLink" + ObjectMetaFieldUUID = "uuid" +) + +type ObjectMeta struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + Finalizers []string `json:"finalizers,omitempty" yaml:"finalizers,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_reference.go new file mode 100644 index 0000000..2a5f94e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_object_reference.go @@ -0,0 +1,22 @@ +package client + +const ( + ObjectReferenceType = "objectReference" + ObjectReferenceFieldAPIVersion = "apiVersion" + ObjectReferenceFieldFieldPath = "fieldPath" + ObjectReferenceFieldKind = "kind" + ObjectReferenceFieldName = "name" + ObjectReferenceFieldNamespace = "namespace" + ObjectReferenceFieldResourceVersion = "resourceVersion" + ObjectReferenceFieldUID = "uid" +) + +type ObjectReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_owner_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_owner_reference.go new file mode 100644 index 0000000..5f4436b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_owner_reference.go @@ -0,0 +1,20 @@ +package client + +const ( + OwnerReferenceType = "ownerReference" + OwnerReferenceFieldAPIVersion = "apiVersion" + OwnerReferenceFieldBlockOwnerDeletion = "blockOwnerDeletion" + OwnerReferenceFieldController = "controller" + OwnerReferenceFieldKind = "kind" + OwnerReferenceFieldName = "name" + OwnerReferenceFieldUID = "uid" +) + +type OwnerReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" yaml:"blockOwnerDeletion,omitempty"` + Controller *bool `json:"controller,omitempty" yaml:"controller,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume.go new file mode 100644 index 0000000..d07d88c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume.go @@ -0,0 +1,190 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PersistentVolumeType = "persistentVolume" + PersistentVolumeFieldAWSElasticBlockStore = "awsElasticBlockStore" + PersistentVolumeFieldAccessModes = "accessModes" + PersistentVolumeFieldAnnotations = "annotations" + PersistentVolumeFieldAzureDisk = "azureDisk" + PersistentVolumeFieldAzureFile = "azureFile" + PersistentVolumeFieldCSI = "csi" + PersistentVolumeFieldCapacity = "capacity" + PersistentVolumeFieldCephFS = "cephfs" + PersistentVolumeFieldCinder = "cinder" + PersistentVolumeFieldClaimRef = "claimRef" + PersistentVolumeFieldCreated = "created" + PersistentVolumeFieldCreatorID = "creatorId" + PersistentVolumeFieldDescription = "description" + PersistentVolumeFieldFC = "fc" + PersistentVolumeFieldFlexVolume = "flexVolume" + PersistentVolumeFieldFlocker = "flocker" + PersistentVolumeFieldGCEPersistentDisk = "gcePersistentDisk" + PersistentVolumeFieldGlusterfs = "glusterfs" + PersistentVolumeFieldHostPath = "hostPath" + PersistentVolumeFieldISCSI = "iscsi" + PersistentVolumeFieldLabels = "labels" + PersistentVolumeFieldLocal = "local" + PersistentVolumeFieldMountOptions = "mountOptions" + PersistentVolumeFieldNFS = "nfs" + PersistentVolumeFieldName = "name" + PersistentVolumeFieldNodeAffinity = "nodeAffinity" + PersistentVolumeFieldOwnerReferences = "ownerReferences" + PersistentVolumeFieldPersistentVolumeReclaimPolicy = "persistentVolumeReclaimPolicy" + PersistentVolumeFieldPhotonPersistentDisk = "photonPersistentDisk" + PersistentVolumeFieldPortworxVolume = "portworxVolume" + PersistentVolumeFieldQuobyte = "quobyte" + PersistentVolumeFieldRBD = "rbd" + PersistentVolumeFieldRemoved = "removed" + PersistentVolumeFieldScaleIO = "scaleIO" + PersistentVolumeFieldState = "state" + PersistentVolumeFieldStatus = "status" + PersistentVolumeFieldStorageClassID = "storageClassId" + PersistentVolumeFieldStorageOS = "storageos" + PersistentVolumeFieldTransitioning = "transitioning" + PersistentVolumeFieldTransitioningMessage = "transitioningMessage" + PersistentVolumeFieldUUID = "uuid" + PersistentVolumeFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeFieldVolumeMode = "volumeMode" + PersistentVolumeFieldVsphereVolume = "vsphereVolume" +) + +type PersistentVolume struct { + types.Resource + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" yaml:"awsElasticBlockStore,omitempty"` + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" yaml:"azureDisk,omitempty"` + AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" yaml:"azureFile,omitempty"` + CSI *CSIPersistentVolumeSource `json:"csi,omitempty" yaml:"csi,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + CephFS *CephFSPersistentVolumeSource `json:"cephfs,omitempty" yaml:"cephfs,omitempty"` + Cinder *CinderPersistentVolumeSource `json:"cinder,omitempty" yaml:"cinder,omitempty"` + ClaimRef *ObjectReference `json:"claimRef,omitempty" yaml:"claimRef,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + FC *FCVolumeSource `json:"fc,omitempty" yaml:"fc,omitempty"` + FlexVolume *FlexPersistentVolumeSource `json:"flexVolume,omitempty" yaml:"flexVolume,omitempty"` + Flocker *FlockerVolumeSource `json:"flocker,omitempty" yaml:"flocker,omitempty"` + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" yaml:"gcePersistentDisk,omitempty"` + Glusterfs *GlusterfsPersistentVolumeSource `json:"glusterfs,omitempty" yaml:"glusterfs,omitempty"` + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` + ISCSI *ISCSIPersistentVolumeSource `json:"iscsi,omitempty" yaml:"iscsi,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Local *LocalVolumeSource `json:"local,omitempty" yaml:"local,omitempty"` + MountOptions []string `json:"mountOptions,omitempty" yaml:"mountOptions,omitempty"` + NFS *NFSVolumeSource `json:"nfs,omitempty" yaml:"nfs,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NodeAffinity *VolumeNodeAffinity `json:"nodeAffinity,omitempty" yaml:"nodeAffinity,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PersistentVolumeReclaimPolicy string `json:"persistentVolumeReclaimPolicy,omitempty" yaml:"persistentVolumeReclaimPolicy,omitempty"` + PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" yaml:"photonPersistentDisk,omitempty"` + PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" yaml:"portworxVolume,omitempty"` + Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" yaml:"quobyte,omitempty"` + RBD *RBDPersistentVolumeSource `json:"rbd,omitempty" yaml:"rbd,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ScaleIO *ScaleIOPersistentVolumeSource `json:"scaleIO,omitempty" yaml:"scaleIO,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *PersistentVolumeStatus `json:"status,omitempty" yaml:"status,omitempty"` + StorageClassID string `json:"storageClassId,omitempty" yaml:"storageClassId,omitempty"` + StorageOS *StorageOSPersistentVolumeSource `json:"storageos,omitempty" yaml:"storageos,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" yaml:"vsphereVolume,omitempty"` +} + +type PersistentVolumeCollection struct { + types.Collection + Data []PersistentVolume `json:"data,omitempty"` + client *PersistentVolumeClient +} + +type PersistentVolumeClient struct { + apiClient *Client +} + +type PersistentVolumeOperations interface { + List(opts *types.ListOpts) (*PersistentVolumeCollection, error) + ListAll(opts *types.ListOpts) (*PersistentVolumeCollection, error) + Create(opts *PersistentVolume) (*PersistentVolume, error) + Update(existing *PersistentVolume, updates interface{}) (*PersistentVolume, error) + Replace(existing *PersistentVolume) (*PersistentVolume, error) + ByID(id string) (*PersistentVolume, error) + Delete(container *PersistentVolume) error +} + +func newPersistentVolumeClient(apiClient *Client) *PersistentVolumeClient { + return &PersistentVolumeClient{ + apiClient: apiClient, + } +} + +func (c *PersistentVolumeClient) Create(container *PersistentVolume) (*PersistentVolume, error) { + resp := &PersistentVolume{} + err := c.apiClient.Ops.DoCreate(PersistentVolumeType, container, resp) + return resp, err +} + +func (c *PersistentVolumeClient) Update(existing *PersistentVolume, updates interface{}) (*PersistentVolume, error) { + resp := &PersistentVolume{} + err := c.apiClient.Ops.DoUpdate(PersistentVolumeType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PersistentVolumeClient) Replace(obj *PersistentVolume) (*PersistentVolume, error) { + resp := &PersistentVolume{} + err := c.apiClient.Ops.DoReplace(PersistentVolumeType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PersistentVolumeClient) List(opts *types.ListOpts) (*PersistentVolumeCollection, error) { + resp := &PersistentVolumeCollection{} + err := c.apiClient.Ops.DoList(PersistentVolumeType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PersistentVolumeClient) ListAll(opts *types.ListOpts) (*PersistentVolumeCollection, error) { + resp := &PersistentVolumeCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PersistentVolumeCollection) Next() (*PersistentVolumeCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PersistentVolumeCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PersistentVolumeClient) ByID(id string) (*PersistentVolume, error) { + resp := &PersistentVolume{} + err := c.apiClient.Ops.DoByID(PersistentVolumeType, id, resp) + return resp, err +} + +func (c *PersistentVolumeClient) Delete(container *PersistentVolume) error { + return c.apiClient.Ops.DoResourceDelete(PersistentVolumeType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_spec.go new file mode 100644 index 0000000..07997bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_spec.go @@ -0,0 +1,70 @@ +package client + +const ( + PersistentVolumeSpecType = "persistentVolumeSpec" + PersistentVolumeSpecFieldAWSElasticBlockStore = "awsElasticBlockStore" + PersistentVolumeSpecFieldAccessModes = "accessModes" + PersistentVolumeSpecFieldAzureDisk = "azureDisk" + PersistentVolumeSpecFieldAzureFile = "azureFile" + PersistentVolumeSpecFieldCSI = "csi" + PersistentVolumeSpecFieldCapacity = "capacity" + PersistentVolumeSpecFieldCephFS = "cephfs" + PersistentVolumeSpecFieldCinder = "cinder" + PersistentVolumeSpecFieldClaimRef = "claimRef" + PersistentVolumeSpecFieldFC = "fc" + PersistentVolumeSpecFieldFlexVolume = "flexVolume" + PersistentVolumeSpecFieldFlocker = "flocker" + PersistentVolumeSpecFieldGCEPersistentDisk = "gcePersistentDisk" + PersistentVolumeSpecFieldGlusterfs = "glusterfs" + PersistentVolumeSpecFieldHostPath = "hostPath" + PersistentVolumeSpecFieldISCSI = "iscsi" + PersistentVolumeSpecFieldLocal = "local" + PersistentVolumeSpecFieldMountOptions = "mountOptions" + PersistentVolumeSpecFieldNFS = "nfs" + PersistentVolumeSpecFieldNodeAffinity = "nodeAffinity" + PersistentVolumeSpecFieldPersistentVolumeReclaimPolicy = "persistentVolumeReclaimPolicy" + PersistentVolumeSpecFieldPhotonPersistentDisk = "photonPersistentDisk" + PersistentVolumeSpecFieldPortworxVolume = "portworxVolume" + PersistentVolumeSpecFieldQuobyte = "quobyte" + PersistentVolumeSpecFieldRBD = "rbd" + PersistentVolumeSpecFieldScaleIO = "scaleIO" + PersistentVolumeSpecFieldStorageClassID = "storageClassId" + PersistentVolumeSpecFieldStorageOS = "storageos" + PersistentVolumeSpecFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeSpecFieldVolumeMode = "volumeMode" + PersistentVolumeSpecFieldVsphereVolume = "vsphereVolume" +) + +type PersistentVolumeSpec struct { + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" yaml:"awsElasticBlockStore,omitempty"` + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" yaml:"azureDisk,omitempty"` + AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" yaml:"azureFile,omitempty"` + CSI *CSIPersistentVolumeSource `json:"csi,omitempty" yaml:"csi,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + CephFS *CephFSPersistentVolumeSource `json:"cephfs,omitempty" yaml:"cephfs,omitempty"` + Cinder *CinderPersistentVolumeSource `json:"cinder,omitempty" yaml:"cinder,omitempty"` + ClaimRef *ObjectReference `json:"claimRef,omitempty" yaml:"claimRef,omitempty"` + FC *FCVolumeSource `json:"fc,omitempty" yaml:"fc,omitempty"` + FlexVolume *FlexPersistentVolumeSource `json:"flexVolume,omitempty" yaml:"flexVolume,omitempty"` + Flocker *FlockerVolumeSource `json:"flocker,omitempty" yaml:"flocker,omitempty"` + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" yaml:"gcePersistentDisk,omitempty"` + Glusterfs *GlusterfsPersistentVolumeSource `json:"glusterfs,omitempty" yaml:"glusterfs,omitempty"` + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` + ISCSI *ISCSIPersistentVolumeSource `json:"iscsi,omitempty" yaml:"iscsi,omitempty"` + Local *LocalVolumeSource `json:"local,omitempty" yaml:"local,omitempty"` + MountOptions []string `json:"mountOptions,omitempty" yaml:"mountOptions,omitempty"` + NFS *NFSVolumeSource `json:"nfs,omitempty" yaml:"nfs,omitempty"` + NodeAffinity *VolumeNodeAffinity `json:"nodeAffinity,omitempty" yaml:"nodeAffinity,omitempty"` + PersistentVolumeReclaimPolicy string `json:"persistentVolumeReclaimPolicy,omitempty" yaml:"persistentVolumeReclaimPolicy,omitempty"` + PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" yaml:"photonPersistentDisk,omitempty"` + PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" yaml:"portworxVolume,omitempty"` + Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" yaml:"quobyte,omitempty"` + RBD *RBDPersistentVolumeSource `json:"rbd,omitempty" yaml:"rbd,omitempty"` + ScaleIO *ScaleIOPersistentVolumeSource `json:"scaleIO,omitempty" yaml:"scaleIO,omitempty"` + StorageClassID string `json:"storageClassId,omitempty" yaml:"storageClassId,omitempty"` + StorageOS *StorageOSPersistentVolumeSource `json:"storageos,omitempty" yaml:"storageos,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" yaml:"vsphereVolume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_status.go new file mode 100644 index 0000000..3c00849 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_persistent_volume_status.go @@ -0,0 +1,16 @@ +package client + +const ( + PersistentVolumeStatusType = "persistentVolumeStatus" + PersistentVolumeStatusFieldLastPhaseTransitionTime = "lastPhaseTransitionTime" + PersistentVolumeStatusFieldMessage = "message" + PersistentVolumeStatusFieldPhase = "phase" + PersistentVolumeStatusFieldReason = "reason" +) + +type PersistentVolumeStatus struct { + LastPhaseTransitionTime string `json:"lastPhaseTransitionTime,omitempty" yaml:"lastPhaseTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Phase string `json:"phase,omitempty" yaml:"phase,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_photon_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_photon_persistent_disk_volume_source.go new file mode 100644 index 0000000..d6e8ffd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_photon_persistent_disk_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PhotonPersistentDiskVolumeSourceType = "photonPersistentDiskVolumeSource" + PhotonPersistentDiskVolumeSourceFieldFSType = "fsType" + PhotonPersistentDiskVolumeSourceFieldPdID = "pdID" +) + +type PhotonPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PdID string `json:"pdID,omitempty" yaml:"pdID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_portworx_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_portworx_volume_source.go new file mode 100644 index 0000000..cbe98c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_portworx_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + PortworxVolumeSourceType = "portworxVolumeSource" + PortworxVolumeSourceFieldFSType = "fsType" + PortworxVolumeSourceFieldReadOnly = "readOnly" + PortworxVolumeSourceFieldVolumeID = "volumeID" +) + +type PortworxVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_quobyte_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_quobyte_volume_source.go new file mode 100644 index 0000000..41e308d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_quobyte_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + QuobyteVolumeSourceType = "quobyteVolumeSource" + QuobyteVolumeSourceFieldGroup = "group" + QuobyteVolumeSourceFieldReadOnly = "readOnly" + QuobyteVolumeSourceFieldRegistry = "registry" + QuobyteVolumeSourceFieldTenant = "tenant" + QuobyteVolumeSourceFieldUser = "user" + QuobyteVolumeSourceFieldVolume = "volume" +) + +type QuobyteVolumeSource struct { + Group string `json:"group,omitempty" yaml:"group,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Registry string `json:"registry,omitempty" yaml:"registry,omitempty"` + Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + Volume string `json:"volume,omitempty" yaml:"volume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_rbd_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_rbd_persistent_volume_source.go new file mode 100644 index 0000000..40f5514 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_rbd_persistent_volume_source.go @@ -0,0 +1,24 @@ +package client + +const ( + RBDPersistentVolumeSourceType = "rbdPersistentVolumeSource" + RBDPersistentVolumeSourceFieldCephMonitors = "monitors" + RBDPersistentVolumeSourceFieldFSType = "fsType" + RBDPersistentVolumeSourceFieldKeyring = "keyring" + RBDPersistentVolumeSourceFieldRBDImage = "image" + RBDPersistentVolumeSourceFieldRBDPool = "pool" + RBDPersistentVolumeSourceFieldRadosUser = "user" + RBDPersistentVolumeSourceFieldReadOnly = "readOnly" + RBDPersistentVolumeSourceFieldSecretRef = "secretRef" +) + +type RBDPersistentVolumeSource struct { + CephMonitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Keyring string `json:"keyring,omitempty" yaml:"keyring,omitempty"` + RBDImage string `json:"image,omitempty" yaml:"image,omitempty"` + RBDPool string `json:"pool,omitempty" yaml:"pool,omitempty"` + RadosUser string `json:"user,omitempty" yaml:"user,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_resource_quota_limit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_resource_quota_limit.go new file mode 100644 index 0000000..4bc04ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_resource_quota_limit.go @@ -0,0 +1,34 @@ +package client + +const ( + ResourceQuotaLimitType = "resourceQuotaLimit" + ResourceQuotaLimitFieldConfigMaps = "configMaps" + ResourceQuotaLimitFieldLimitsCPU = "limitsCpu" + ResourceQuotaLimitFieldLimitsMemory = "limitsMemory" + ResourceQuotaLimitFieldPersistentVolumeClaims = "persistentVolumeClaims" + ResourceQuotaLimitFieldPods = "pods" + ResourceQuotaLimitFieldReplicationControllers = "replicationControllers" + ResourceQuotaLimitFieldRequestsCPU = "requestsCpu" + ResourceQuotaLimitFieldRequestsMemory = "requestsMemory" + ResourceQuotaLimitFieldRequestsStorage = "requestsStorage" + ResourceQuotaLimitFieldSecrets = "secrets" + ResourceQuotaLimitFieldServices = "services" + ResourceQuotaLimitFieldServicesLoadBalancers = "servicesLoadBalancers" + ResourceQuotaLimitFieldServicesNodePorts = "servicesNodePorts" +) + +type ResourceQuotaLimit struct { + ConfigMaps string `json:"configMaps,omitempty" yaml:"configMaps,omitempty"` + LimitsCPU string `json:"limitsCpu,omitempty" yaml:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty" yaml:"limitsMemory,omitempty"` + PersistentVolumeClaims string `json:"persistentVolumeClaims,omitempty" yaml:"persistentVolumeClaims,omitempty"` + Pods string `json:"pods,omitempty" yaml:"pods,omitempty"` + ReplicationControllers string `json:"replicationControllers,omitempty" yaml:"replicationControllers,omitempty"` + RequestsCPU string `json:"requestsCpu,omitempty" yaml:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty" yaml:"requestsMemory,omitempty"` + RequestsStorage string `json:"requestsStorage,omitempty" yaml:"requestsStorage,omitempty"` + Secrets string `json:"secrets,omitempty" yaml:"secrets,omitempty"` + Services string `json:"services,omitempty" yaml:"services,omitempty"` + ServicesLoadBalancers string `json:"servicesLoadBalancers,omitempty" yaml:"servicesLoadBalancers,omitempty"` + ServicesNodePorts string `json:"servicesNodePorts,omitempty" yaml:"servicesNodePorts,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_scale_iopersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_scale_iopersistent_volume_source.go new file mode 100644 index 0000000..49871d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_scale_iopersistent_volume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + ScaleIOPersistentVolumeSourceType = "scaleIOPersistentVolumeSource" + ScaleIOPersistentVolumeSourceFieldFSType = "fsType" + ScaleIOPersistentVolumeSourceFieldGateway = "gateway" + ScaleIOPersistentVolumeSourceFieldProtectionDomain = "protectionDomain" + ScaleIOPersistentVolumeSourceFieldReadOnly = "readOnly" + ScaleIOPersistentVolumeSourceFieldSSLEnabled = "sslEnabled" + ScaleIOPersistentVolumeSourceFieldSecretRef = "secretRef" + ScaleIOPersistentVolumeSourceFieldStorageMode = "storageMode" + ScaleIOPersistentVolumeSourceFieldStoragePool = "storagePool" + ScaleIOPersistentVolumeSourceFieldSystem = "system" + ScaleIOPersistentVolumeSourceFieldVolumeName = "volumeName" +) + +type ScaleIOPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Gateway string `json:"gateway,omitempty" yaml:"gateway,omitempty"` + ProtectionDomain string `json:"protectionDomain,omitempty" yaml:"protectionDomain,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SSLEnabled bool `json:"sslEnabled,omitempty" yaml:"sslEnabled,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + StorageMode string `json:"storageMode,omitempty" yaml:"storageMode,omitempty"` + StoragePool string `json:"storagePool,omitempty" yaml:"storagePool,omitempty"` + System string `json:"system,omitempty" yaml:"system,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_secret_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_secret_reference.go new file mode 100644 index 0000000..331f9a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_secret_reference.go @@ -0,0 +1,12 @@ +package client + +const ( + SecretReferenceType = "secretReference" + SecretReferenceFieldName = "name" + SecretReferenceFieldNamespace = "namespace" +) + +type SecretReference struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_service_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_service_reference.go new file mode 100644 index 0000000..1350c93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_service_reference.go @@ -0,0 +1,14 @@ +package client + +const ( + ServiceReferenceType = "serviceReference" + ServiceReferenceFieldName = "name" + ServiceReferenceFieldNamespace = "namespace" + ServiceReferenceFieldPort = "port" +) + +type ServiceReference struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + Port *int64 `json:"port,omitempty" yaml:"port,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_class.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_class.go new file mode 100644 index 0000000..e9408c3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_class.go @@ -0,0 +1,134 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + StorageClassType = "storageClass" + StorageClassFieldAllowVolumeExpansion = "allowVolumeExpansion" + StorageClassFieldAllowedTopologies = "allowedTopologies" + StorageClassFieldAnnotations = "annotations" + StorageClassFieldCreated = "created" + StorageClassFieldCreatorID = "creatorId" + StorageClassFieldDescription = "description" + StorageClassFieldLabels = "labels" + StorageClassFieldMountOptions = "mountOptions" + StorageClassFieldName = "name" + StorageClassFieldOwnerReferences = "ownerReferences" + StorageClassFieldParameters = "parameters" + StorageClassFieldProvisioner = "provisioner" + StorageClassFieldReclaimPolicy = "reclaimPolicy" + StorageClassFieldRemoved = "removed" + StorageClassFieldUUID = "uuid" + StorageClassFieldVolumeBindingMode = "volumeBindingMode" +) + +type StorageClass struct { + types.Resource + AllowVolumeExpansion *bool `json:"allowVolumeExpansion,omitempty" yaml:"allowVolumeExpansion,omitempty"` + AllowedTopologies []TopologySelectorTerm `json:"allowedTopologies,omitempty" yaml:"allowedTopologies,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + MountOptions []string `json:"mountOptions,omitempty" yaml:"mountOptions,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Parameters map[string]string `json:"parameters,omitempty" yaml:"parameters,omitempty"` + Provisioner string `json:"provisioner,omitempty" yaml:"provisioner,omitempty"` + ReclaimPolicy string `json:"reclaimPolicy,omitempty" yaml:"reclaimPolicy,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + VolumeBindingMode string `json:"volumeBindingMode,omitempty" yaml:"volumeBindingMode,omitempty"` +} + +type StorageClassCollection struct { + types.Collection + Data []StorageClass `json:"data,omitempty"` + client *StorageClassClient +} + +type StorageClassClient struct { + apiClient *Client +} + +type StorageClassOperations interface { + List(opts *types.ListOpts) (*StorageClassCollection, error) + ListAll(opts *types.ListOpts) (*StorageClassCollection, error) + Create(opts *StorageClass) (*StorageClass, error) + Update(existing *StorageClass, updates interface{}) (*StorageClass, error) + Replace(existing *StorageClass) (*StorageClass, error) + ByID(id string) (*StorageClass, error) + Delete(container *StorageClass) error +} + +func newStorageClassClient(apiClient *Client) *StorageClassClient { + return &StorageClassClient{ + apiClient: apiClient, + } +} + +func (c *StorageClassClient) Create(container *StorageClass) (*StorageClass, error) { + resp := &StorageClass{} + err := c.apiClient.Ops.DoCreate(StorageClassType, container, resp) + return resp, err +} + +func (c *StorageClassClient) Update(existing *StorageClass, updates interface{}) (*StorageClass, error) { + resp := &StorageClass{} + err := c.apiClient.Ops.DoUpdate(StorageClassType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *StorageClassClient) Replace(obj *StorageClass) (*StorageClass, error) { + resp := &StorageClass{} + err := c.apiClient.Ops.DoReplace(StorageClassType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *StorageClassClient) List(opts *types.ListOpts) (*StorageClassCollection, error) { + resp := &StorageClassCollection{} + err := c.apiClient.Ops.DoList(StorageClassType, opts, resp) + resp.client = c + return resp, err +} + +func (c *StorageClassClient) ListAll(opts *types.ListOpts) (*StorageClassCollection, error) { + resp := &StorageClassCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *StorageClassCollection) Next() (*StorageClassCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &StorageClassCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *StorageClassClient) ByID(id string) (*StorageClass, error) { + resp := &StorageClass{} + err := c.apiClient.Ops.DoByID(StorageClassType, id, resp) + return resp, err +} + +func (c *StorageClassClient) Delete(container *StorageClass) error { + return c.apiClient.Ops.DoResourceDelete(StorageClassType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_ospersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_ospersistent_volume_source.go new file mode 100644 index 0000000..c1f741d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_storage_ospersistent_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + StorageOSPersistentVolumeSourceType = "storageOSPersistentVolumeSource" + StorageOSPersistentVolumeSourceFieldFSType = "fsType" + StorageOSPersistentVolumeSourceFieldReadOnly = "readOnly" + StorageOSPersistentVolumeSourceFieldSecretRef = "secretRef" + StorageOSPersistentVolumeSourceFieldVolumeName = "volumeName" + StorageOSPersistentVolumeSourceFieldVolumeNamespace = "volumeNamespace" +) + +type StorageOSPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *ObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` + VolumeNamespace string `json:"volumeNamespace,omitempty" yaml:"volumeNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_label_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_label_requirement.go new file mode 100644 index 0000000..2d63b43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_label_requirement.go @@ -0,0 +1,12 @@ +package client + +const ( + TopologySelectorLabelRequirementType = "topologySelectorLabelRequirement" + TopologySelectorLabelRequirementFieldKey = "key" + TopologySelectorLabelRequirementFieldValues = "values" +) + +type TopologySelectorLabelRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_term.go new file mode 100644 index 0000000..6a78c4b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_topology_selector_term.go @@ -0,0 +1,10 @@ +package client + +const ( + TopologySelectorTermType = "topologySelectorTerm" + TopologySelectorTermFieldMatchLabelExpressions = "matchLabelExpressions" +) + +type TopologySelectorTerm struct { + MatchLabelExpressions []TopologySelectorLabelRequirement `json:"matchLabelExpressions,omitempty" yaml:"matchLabelExpressions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_volume_node_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_volume_node_affinity.go new file mode 100644 index 0000000..e025eb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_volume_node_affinity.go @@ -0,0 +1,10 @@ +package client + +const ( + VolumeNodeAffinityType = "volumeNodeAffinity" + VolumeNodeAffinityFieldRequired = "required" +) + +type VolumeNodeAffinity struct { + Required *NodeSelector `json:"required,omitempty" yaml:"required,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_vsphere_virtual_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_vsphere_virtual_disk_volume_source.go new file mode 100644 index 0000000..ed671ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/cluster/v3/zz_generated_vsphere_virtual_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + VsphereVirtualDiskVolumeSourceType = "vsphereVirtualDiskVolumeSource" + VsphereVirtualDiskVolumeSourceFieldFSType = "fsType" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyID = "storagePolicyID" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyName = "storagePolicyName" + VsphereVirtualDiskVolumeSourceFieldVolumePath = "volumePath" +) + +type VsphereVirtualDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + StoragePolicyID string `json:"storagePolicyID,omitempty" yaml:"storagePolicyID,omitempty"` + StoragePolicyName string `json:"storagePolicyName,omitempty" yaml:"storagePolicyName,omitempty"` + VolumePath string `json:"volumePath,omitempty" yaml:"volumePath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aci_network_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aci_network_provider.go new file mode 100644 index 0000000..7457b07 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aci_network_provider.go @@ -0,0 +1,238 @@ +package client + +const ( + AciNetworkProviderType = "aciNetworkProvider" + AciNetworkProviderFieldAEP = "aep" + AciNetworkProviderFieldAciContainersControllerMemoryLimit = "aciContainersControllerMemoryLimit" + AciNetworkProviderFieldAciContainersControllerMemoryRequest = "aciContainersControllerMemoryRequest" + AciNetworkProviderFieldAciContainersHostMemoryLimit = "aciContainersHostMemoryLimit" + AciNetworkProviderFieldAciContainersHostMemoryRequest = "aciContainersHostMemoryRequest" + AciNetworkProviderFieldAciContainersMemoryLimit = "aciContainersMemoryLimit" + AciNetworkProviderFieldAciContainersMemoryRequest = "aciContainersMemoryRequest" + AciNetworkProviderFieldAciMultipod = "aciMultipod" + AciNetworkProviderFieldAciMultipodUbuntu = "aciMultipodUbuntu" + AciNetworkProviderFieldAddExternalContractToDefaultEpg = "addExternalContractToDefaultEpg" + AciNetworkProviderFieldAddExternalSubnetsToRdconfig = "addExternalSubnetsToRdconfig" + AciNetworkProviderFieldApicConnectionRetryLimit = "apicConnectionRetryLimit" + AciNetworkProviderFieldApicHosts = "apicHosts" + AciNetworkProviderFieldApicRefreshTickerAdjust = "apicRefreshTickerAdjust" + AciNetworkProviderFieldApicRefreshTime = "apicRefreshTime" + AciNetworkProviderFieldApicSubscriptionDelay = "apicSubscriptionDelay" + AciNetworkProviderFieldApicUserCrt = "apicUserCrt" + AciNetworkProviderFieldApicUserKey = "apicUserKey" + AciNetworkProviderFieldApicUserName = "apicUserName" + AciNetworkProviderFieldCApic = "capic" + AciNetworkProviderFieldControllerLogLevel = "controllerLogLevel" + AciNetworkProviderFieldDhcpDelay = "dhcpDelay" + AciNetworkProviderFieldDhcpRenewMaxRetryCount = "dhcpRenewMaxRetryCount" + AciNetworkProviderFieldDisableHppRendering = "disableHppRendering" + AciNetworkProviderFieldDisablePeriodicSnatGlobalInfoSync = "disablePeriodicSnatGlobalInfoSync" + AciNetworkProviderFieldDisableWaitForNetwork = "disableWaitForNetwork" + AciNetworkProviderFieldDropLogDisableEvents = "dropLogDisableEvents" + AciNetworkProviderFieldDropLogEnable = "dropLogEnable" + AciNetworkProviderFieldDurationWaitForNetwork = "durationWaitForNetwork" + AciNetworkProviderFieldDynamicExternalSubnet = "externDynamic" + AciNetworkProviderFieldEnableEndpointSlice = "enableEndpointSlice" + AciNetworkProviderFieldEnableOpflexAgentReconnect = "enableOpflexAgentReconnect" + AciNetworkProviderFieldEncapType = "encapType" + AciNetworkProviderFieldEpRegistry = "epRegistry" + AciNetworkProviderFieldGbpPodSubnet = "gbpPodSubnet" + AciNetworkProviderFieldHostAgentLogLevel = "hostAgentLogLevel" + AciNetworkProviderFieldHppOptimization = "hppOptimization" + AciNetworkProviderFieldImagePullPolicy = "imagePullPolicy" + AciNetworkProviderFieldImagePullSecret = "imagePullSecret" + AciNetworkProviderFieldInfraVlan = "infraVlan" + AciNetworkProviderFieldInstallIstio = "installIstio" + AciNetworkProviderFieldIstioProfile = "istioProfile" + AciNetworkProviderFieldKafkaBrokers = "kafkaBrokers" + AciNetworkProviderFieldKafkaClientCrt = "kafkaClientCrt" + AciNetworkProviderFieldKafkaClientKey = "kafkaClientKey" + AciNetworkProviderFieldKubeAPIVlan = "kubeApiVlan" + AciNetworkProviderFieldL3Out = "l3out" + AciNetworkProviderFieldL3OutExternalNetworks = "l3outExternalNetworks" + AciNetworkProviderFieldMTUHeadRoom = "mtuHeadRoom" + AciNetworkProviderFieldMaxNodesSvcGraph = "maxNodesSvcGraph" + AciNetworkProviderFieldMcastDaemonMemoryLimit = "mcastDaemonMemoryLimit" + AciNetworkProviderFieldMcastDaemonMemoryRequest = "mcastDaemonMemoryRequest" + AciNetworkProviderFieldMcastRangeEnd = "mcastRangeEnd" + AciNetworkProviderFieldMcastRangeStart = "mcastRangeStart" + AciNetworkProviderFieldMultusDisable = "multusDisable" + AciNetworkProviderFieldNoPriorityClass = "noPriorityClass" + AciNetworkProviderFieldNoWaitForServiceEpReadiness = "noWaitForServiceEpReadiness" + AciNetworkProviderFieldNodePodIfEnable = "nodePodIfEnable" + AciNetworkProviderFieldNodeSnatRedirectExclude = "nodeSnatRedirectExclude" + AciNetworkProviderFieldNodeSubnet = "nodeSubnet" + AciNetworkProviderFieldOVSMemoryLimit = "ovsMemoryLimit" + AciNetworkProviderFieldOVSMemoryRequest = "ovsMemoryRequest" + AciNetworkProviderFieldOpflexAgentLogLevel = "opflexLogLevel" + AciNetworkProviderFieldOpflexAgentMemoryLimit = "opflexAgentMemoryLimit" + AciNetworkProviderFieldOpflexAgentMemoryRequest = "opflexAgentMemoryRequest" + AciNetworkProviderFieldOpflexAgentOpflexAsyncjsonEnabled = "opflexAgentOpflexAsyncjsonEnabled" + AciNetworkProviderFieldOpflexAgentOvsAsyncjsonEnabled = "opflexAgentOvsAsyncjsonEnabled" + AciNetworkProviderFieldOpflexAgentPolicyRetryDelayTimer = "opflexAgentPolicyRetryDelayTimer" + AciNetworkProviderFieldOpflexAgentStatistics = "opflexAgentStatistics" + AciNetworkProviderFieldOpflexClientSSL = "opflexClientSsl" + AciNetworkProviderFieldOpflexDeviceDeleteTimeout = "opflexDeviceDeleteTimeout" + AciNetworkProviderFieldOpflexDeviceReconnectWaitTimeout = "opflexDeviceReconnectWaitTimeout" + AciNetworkProviderFieldOpflexMode = "opflexMode" + AciNetworkProviderFieldOpflexOpensslCompat = "opflexOpensslCompat" + AciNetworkProviderFieldOpflexServerPort = "opflexServerPort" + AciNetworkProviderFieldOpflexStartupEnabled = "opflexStartupEnabled" + AciNetworkProviderFieldOpflexStartupPolicyDuration = "opflexStartupPolicyDuration" + AciNetworkProviderFieldOpflexStartupResolveAftConn = "opflexStartupResolveAftConn" + AciNetworkProviderFieldOpflexSwitchSyncDelay = "opflexSwitchSyncDelay" + AciNetworkProviderFieldOpflexSwitchSyncDynamic = "opflexSwitchSyncDynamic" + AciNetworkProviderFieldOverlayVRFName = "overlayVrfName" + AciNetworkProviderFieldPBRTrackingNonSnat = "pbrTrackingNonSnat" + AciNetworkProviderFieldPodSubnetChunkSize = "podSubnetChunkSize" + AciNetworkProviderFieldRunGbpContainer = "runGbpContainer" + AciNetworkProviderFieldRunOpflexServerContainer = "runOpflexServerContainer" + AciNetworkProviderFieldServiceGraphEndpointAddDelay = "serviceGraphEndpointAddDelay" + AciNetworkProviderFieldServiceGraphEndpointAddServices = "serviceGraphEndpointAddServices" + AciNetworkProviderFieldServiceGraphSubnet = "nodeSvcSubnet" + AciNetworkProviderFieldServiceMonitorInterval = "serviceMonitorInterval" + AciNetworkProviderFieldServiceVlan = "serviceVlan" + AciNetworkProviderFieldSleepTimeSnatGlobalInfoSync = "sleepTimeSnatGlobalInfoSync" + AciNetworkProviderFieldSnatContractScope = "snatContractScope" + AciNetworkProviderFieldSnatNamespace = "snatNamespace" + AciNetworkProviderFieldSnatPortRangeEnd = "snatPortRangeEnd" + AciNetworkProviderFieldSnatPortRangeStart = "snatPortRangeStart" + AciNetworkProviderFieldSnatPortsPerNode = "snatPortsPerNode" + AciNetworkProviderFieldSriovEnable = "sriovEnable" + AciNetworkProviderFieldStaticExternalSubnet = "externStatic" + AciNetworkProviderFieldSubnetDomainName = "subnetDomainName" + AciNetworkProviderFieldSystemIdentifier = "systemId" + AciNetworkProviderFieldTaintNotReadyNode = "taintNotReadyNode" + AciNetworkProviderFieldTenant = "tenant" + AciNetworkProviderFieldToken = "token" + AciNetworkProviderFieldTolerationSeconds = "tolerationSeconds" + AciNetworkProviderFieldUseAciAnywhereCRD = "useAciAnywhereCrd" + AciNetworkProviderFieldUseAciCniPriorityClass = "useAciCniPriorityClass" + AciNetworkProviderFieldUseClusterRole = "useClusterRole" + AciNetworkProviderFieldUseHostNetnsVolume = "useHostNetnsVolume" + AciNetworkProviderFieldUseOpflexServerVolume = "useOpflexServerVolume" + AciNetworkProviderFieldUsePrivilegedContainer = "usePrivilegedContainer" + AciNetworkProviderFieldUseSystemNodePriorityClass = "useSystemNodePriorityClass" + AciNetworkProviderFieldVRFName = "vrfName" + AciNetworkProviderFieldVRFTenant = "vrfTenant" + AciNetworkProviderFieldVmmController = "vmmController" + AciNetworkProviderFieldVmmDomain = "vmmDomain" +) + +type AciNetworkProvider struct { + AEP string `json:"aep,omitempty" yaml:"aep,omitempty"` + AciContainersControllerMemoryLimit string `json:"aciContainersControllerMemoryLimit,omitempty" yaml:"aciContainersControllerMemoryLimit,omitempty"` + AciContainersControllerMemoryRequest string `json:"aciContainersControllerMemoryRequest,omitempty" yaml:"aciContainersControllerMemoryRequest,omitempty"` + AciContainersHostMemoryLimit string `json:"aciContainersHostMemoryLimit,omitempty" yaml:"aciContainersHostMemoryLimit,omitempty"` + AciContainersHostMemoryRequest string `json:"aciContainersHostMemoryRequest,omitempty" yaml:"aciContainersHostMemoryRequest,omitempty"` + AciContainersMemoryLimit string `json:"aciContainersMemoryLimit,omitempty" yaml:"aciContainersMemoryLimit,omitempty"` + AciContainersMemoryRequest string `json:"aciContainersMemoryRequest,omitempty" yaml:"aciContainersMemoryRequest,omitempty"` + AciMultipod string `json:"aciMultipod,omitempty" yaml:"aciMultipod,omitempty"` + AciMultipodUbuntu string `json:"aciMultipodUbuntu,omitempty" yaml:"aciMultipodUbuntu,omitempty"` + AddExternalContractToDefaultEpg string `json:"addExternalContractToDefaultEpg,omitempty" yaml:"addExternalContractToDefaultEpg,omitempty"` + AddExternalSubnetsToRdconfig string `json:"addExternalSubnetsToRdconfig,omitempty" yaml:"addExternalSubnetsToRdconfig,omitempty"` + ApicConnectionRetryLimit string `json:"apicConnectionRetryLimit,omitempty" yaml:"apicConnectionRetryLimit,omitempty"` + ApicHosts []string `json:"apicHosts,omitempty" yaml:"apicHosts,omitempty"` + ApicRefreshTickerAdjust string `json:"apicRefreshTickerAdjust,omitempty" yaml:"apicRefreshTickerAdjust,omitempty"` + ApicRefreshTime string `json:"apicRefreshTime,omitempty" yaml:"apicRefreshTime,omitempty"` + ApicSubscriptionDelay string `json:"apicSubscriptionDelay,omitempty" yaml:"apicSubscriptionDelay,omitempty"` + ApicUserCrt string `json:"apicUserCrt,omitempty" yaml:"apicUserCrt,omitempty"` + ApicUserKey string `json:"apicUserKey,omitempty" yaml:"apicUserKey,omitempty"` + ApicUserName string `json:"apicUserName,omitempty" yaml:"apicUserName,omitempty"` + CApic string `json:"capic,omitempty" yaml:"capic,omitempty"` + ControllerLogLevel string `json:"controllerLogLevel,omitempty" yaml:"controllerLogLevel,omitempty"` + DhcpDelay string `json:"dhcpDelay,omitempty" yaml:"dhcpDelay,omitempty"` + DhcpRenewMaxRetryCount string `json:"dhcpRenewMaxRetryCount,omitempty" yaml:"dhcpRenewMaxRetryCount,omitempty"` + DisableHppRendering string `json:"disableHppRendering,omitempty" yaml:"disableHppRendering,omitempty"` + DisablePeriodicSnatGlobalInfoSync string `json:"disablePeriodicSnatGlobalInfoSync,omitempty" yaml:"disablePeriodicSnatGlobalInfoSync,omitempty"` + DisableWaitForNetwork string `json:"disableWaitForNetwork,omitempty" yaml:"disableWaitForNetwork,omitempty"` + DropLogDisableEvents string `json:"dropLogDisableEvents,omitempty" yaml:"dropLogDisableEvents,omitempty"` + DropLogEnable string `json:"dropLogEnable,omitempty" yaml:"dropLogEnable,omitempty"` + DurationWaitForNetwork string `json:"durationWaitForNetwork,omitempty" yaml:"durationWaitForNetwork,omitempty"` + DynamicExternalSubnet string `json:"externDynamic,omitempty" yaml:"externDynamic,omitempty"` + EnableEndpointSlice string `json:"enableEndpointSlice,omitempty" yaml:"enableEndpointSlice,omitempty"` + EnableOpflexAgentReconnect string `json:"enableOpflexAgentReconnect,omitempty" yaml:"enableOpflexAgentReconnect,omitempty"` + EncapType string `json:"encapType,omitempty" yaml:"encapType,omitempty"` + EpRegistry string `json:"epRegistry,omitempty" yaml:"epRegistry,omitempty"` + GbpPodSubnet string `json:"gbpPodSubnet,omitempty" yaml:"gbpPodSubnet,omitempty"` + HostAgentLogLevel string `json:"hostAgentLogLevel,omitempty" yaml:"hostAgentLogLevel,omitempty"` + HppOptimization string `json:"hppOptimization,omitempty" yaml:"hppOptimization,omitempty"` + ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"` + ImagePullSecret string `json:"imagePullSecret,omitempty" yaml:"imagePullSecret,omitempty"` + InfraVlan string `json:"infraVlan,omitempty" yaml:"infraVlan,omitempty"` + InstallIstio string `json:"installIstio,omitempty" yaml:"installIstio,omitempty"` + IstioProfile string `json:"istioProfile,omitempty" yaml:"istioProfile,omitempty"` + KafkaBrokers []string `json:"kafkaBrokers,omitempty" yaml:"kafkaBrokers,omitempty"` + KafkaClientCrt string `json:"kafkaClientCrt,omitempty" yaml:"kafkaClientCrt,omitempty"` + KafkaClientKey string `json:"kafkaClientKey,omitempty" yaml:"kafkaClientKey,omitempty"` + KubeAPIVlan string `json:"kubeApiVlan,omitempty" yaml:"kubeApiVlan,omitempty"` + L3Out string `json:"l3out,omitempty" yaml:"l3out,omitempty"` + L3OutExternalNetworks []string `json:"l3outExternalNetworks,omitempty" yaml:"l3outExternalNetworks,omitempty"` + MTUHeadRoom string `json:"mtuHeadRoom,omitempty" yaml:"mtuHeadRoom,omitempty"` + MaxNodesSvcGraph string `json:"maxNodesSvcGraph,omitempty" yaml:"maxNodesSvcGraph,omitempty"` + McastDaemonMemoryLimit string `json:"mcastDaemonMemoryLimit,omitempty" yaml:"mcastDaemonMemoryLimit,omitempty"` + McastDaemonMemoryRequest string `json:"mcastDaemonMemoryRequest,omitempty" yaml:"mcastDaemonMemoryRequest,omitempty"` + McastRangeEnd string `json:"mcastRangeEnd,omitempty" yaml:"mcastRangeEnd,omitempty"` + McastRangeStart string `json:"mcastRangeStart,omitempty" yaml:"mcastRangeStart,omitempty"` + MultusDisable string `json:"multusDisable,omitempty" yaml:"multusDisable,omitempty"` + NoPriorityClass string `json:"noPriorityClass,omitempty" yaml:"noPriorityClass,omitempty"` + NoWaitForServiceEpReadiness string `json:"noWaitForServiceEpReadiness,omitempty" yaml:"noWaitForServiceEpReadiness,omitempty"` + NodePodIfEnable string `json:"nodePodIfEnable,omitempty" yaml:"nodePodIfEnable,omitempty"` + NodeSnatRedirectExclude []map[string]string `json:"nodeSnatRedirectExclude,omitempty" yaml:"nodeSnatRedirectExclude,omitempty"` + NodeSubnet string `json:"nodeSubnet,omitempty" yaml:"nodeSubnet,omitempty"` + OVSMemoryLimit string `json:"ovsMemoryLimit,omitempty" yaml:"ovsMemoryLimit,omitempty"` + OVSMemoryRequest string `json:"ovsMemoryRequest,omitempty" yaml:"ovsMemoryRequest,omitempty"` + OpflexAgentLogLevel string `json:"opflexLogLevel,omitempty" yaml:"opflexLogLevel,omitempty"` + OpflexAgentMemoryLimit string `json:"opflexAgentMemoryLimit,omitempty" yaml:"opflexAgentMemoryLimit,omitempty"` + OpflexAgentMemoryRequest string `json:"opflexAgentMemoryRequest,omitempty" yaml:"opflexAgentMemoryRequest,omitempty"` + OpflexAgentOpflexAsyncjsonEnabled string `json:"opflexAgentOpflexAsyncjsonEnabled,omitempty" yaml:"opflexAgentOpflexAsyncjsonEnabled,omitempty"` + OpflexAgentOvsAsyncjsonEnabled string `json:"opflexAgentOvsAsyncjsonEnabled,omitempty" yaml:"opflexAgentOvsAsyncjsonEnabled,omitempty"` + OpflexAgentPolicyRetryDelayTimer string `json:"opflexAgentPolicyRetryDelayTimer,omitempty" yaml:"opflexAgentPolicyRetryDelayTimer,omitempty"` + OpflexAgentStatistics string `json:"opflexAgentStatistics,omitempty" yaml:"opflexAgentStatistics,omitempty"` + OpflexClientSSL string `json:"opflexClientSsl,omitempty" yaml:"opflexClientSsl,omitempty"` + OpflexDeviceDeleteTimeout string `json:"opflexDeviceDeleteTimeout,omitempty" yaml:"opflexDeviceDeleteTimeout,omitempty"` + OpflexDeviceReconnectWaitTimeout string `json:"opflexDeviceReconnectWaitTimeout,omitempty" yaml:"opflexDeviceReconnectWaitTimeout,omitempty"` + OpflexMode string `json:"opflexMode,omitempty" yaml:"opflexMode,omitempty"` + OpflexOpensslCompat string `json:"opflexOpensslCompat,omitempty" yaml:"opflexOpensslCompat,omitempty"` + OpflexServerPort string `json:"opflexServerPort,omitempty" yaml:"opflexServerPort,omitempty"` + OpflexStartupEnabled string `json:"opflexStartupEnabled,omitempty" yaml:"opflexStartupEnabled,omitempty"` + OpflexStartupPolicyDuration string `json:"opflexStartupPolicyDuration,omitempty" yaml:"opflexStartupPolicyDuration,omitempty"` + OpflexStartupResolveAftConn string `json:"opflexStartupResolveAftConn,omitempty" yaml:"opflexStartupResolveAftConn,omitempty"` + OpflexSwitchSyncDelay string `json:"opflexSwitchSyncDelay,omitempty" yaml:"opflexSwitchSyncDelay,omitempty"` + OpflexSwitchSyncDynamic string `json:"opflexSwitchSyncDynamic,omitempty" yaml:"opflexSwitchSyncDynamic,omitempty"` + OverlayVRFName string `json:"overlayVrfName,omitempty" yaml:"overlayVrfName,omitempty"` + PBRTrackingNonSnat string `json:"pbrTrackingNonSnat,omitempty" yaml:"pbrTrackingNonSnat,omitempty"` + PodSubnetChunkSize string `json:"podSubnetChunkSize,omitempty" yaml:"podSubnetChunkSize,omitempty"` + RunGbpContainer string `json:"runGbpContainer,omitempty" yaml:"runGbpContainer,omitempty"` + RunOpflexServerContainer string `json:"runOpflexServerContainer,omitempty" yaml:"runOpflexServerContainer,omitempty"` + ServiceGraphEndpointAddDelay string `json:"serviceGraphEndpointAddDelay,omitempty" yaml:"serviceGraphEndpointAddDelay,omitempty"` + ServiceGraphEndpointAddServices []map[string]string `json:"serviceGraphEndpointAddServices,omitempty" yaml:"serviceGraphEndpointAddServices,omitempty"` + ServiceGraphSubnet string `json:"nodeSvcSubnet,omitempty" yaml:"nodeSvcSubnet,omitempty"` + ServiceMonitorInterval string `json:"serviceMonitorInterval,omitempty" yaml:"serviceMonitorInterval,omitempty"` + ServiceVlan string `json:"serviceVlan,omitempty" yaml:"serviceVlan,omitempty"` + SleepTimeSnatGlobalInfoSync string `json:"sleepTimeSnatGlobalInfoSync,omitempty" yaml:"sleepTimeSnatGlobalInfoSync,omitempty"` + SnatContractScope string `json:"snatContractScope,omitempty" yaml:"snatContractScope,omitempty"` + SnatNamespace string `json:"snatNamespace,omitempty" yaml:"snatNamespace,omitempty"` + SnatPortRangeEnd string `json:"snatPortRangeEnd,omitempty" yaml:"snatPortRangeEnd,omitempty"` + SnatPortRangeStart string `json:"snatPortRangeStart,omitempty" yaml:"snatPortRangeStart,omitempty"` + SnatPortsPerNode string `json:"snatPortsPerNode,omitempty" yaml:"snatPortsPerNode,omitempty"` + SriovEnable string `json:"sriovEnable,omitempty" yaml:"sriovEnable,omitempty"` + StaticExternalSubnet string `json:"externStatic,omitempty" yaml:"externStatic,omitempty"` + SubnetDomainName string `json:"subnetDomainName,omitempty" yaml:"subnetDomainName,omitempty"` + SystemIdentifier string `json:"systemId,omitempty" yaml:"systemId,omitempty"` + TaintNotReadyNode string `json:"taintNotReadyNode,omitempty" yaml:"taintNotReadyNode,omitempty"` + Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + TolerationSeconds string `json:"tolerationSeconds,omitempty" yaml:"tolerationSeconds,omitempty"` + UseAciAnywhereCRD string `json:"useAciAnywhereCrd,omitempty" yaml:"useAciAnywhereCrd,omitempty"` + UseAciCniPriorityClass string `json:"useAciCniPriorityClass,omitempty" yaml:"useAciCniPriorityClass,omitempty"` + UseClusterRole string `json:"useClusterRole,omitempty" yaml:"useClusterRole,omitempty"` + UseHostNetnsVolume string `json:"useHostNetnsVolume,omitempty" yaml:"useHostNetnsVolume,omitempty"` + UseOpflexServerVolume string `json:"useOpflexServerVolume,omitempty" yaml:"useOpflexServerVolume,omitempty"` + UsePrivilegedContainer string `json:"usePrivilegedContainer,omitempty" yaml:"usePrivilegedContainer,omitempty"` + UseSystemNodePriorityClass string `json:"useSystemNodePriorityClass,omitempty" yaml:"useSystemNodePriorityClass,omitempty"` + VRFName string `json:"vrfName,omitempty" yaml:"vrfName,omitempty"` + VRFTenant string `json:"vrfTenant,omitempty" yaml:"vrfTenant,omitempty"` + VmmController string `json:"vmmController,omitempty" yaml:"vmmController,omitempty"` + VmmDomain string `json:"vmmDomain,omitempty" yaml:"vmmDomain,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_action.go new file mode 100644 index 0000000..6e6334b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_action.go @@ -0,0 +1,12 @@ +package client + +const ( + ActionType = "action" + ActionFieldInput = "input" + ActionFieldOutput = "output" +) + +type Action struct { + Input string `json:"input,omitempty" yaml:"input,omitempty"` + Output string `json:"output,omitempty" yaml:"output,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_config.go new file mode 100644 index 0000000..5114618 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_config.go @@ -0,0 +1,86 @@ +package client + +const ( + ActiveDirectoryConfigType = "activeDirectoryConfig" + ActiveDirectoryConfigFieldAccessMode = "accessMode" + ActiveDirectoryConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + ActiveDirectoryConfigFieldAnnotations = "annotations" + ActiveDirectoryConfigFieldCertificate = "certificate" + ActiveDirectoryConfigFieldConnectionTimeout = "connectionTimeout" + ActiveDirectoryConfigFieldCreated = "created" + ActiveDirectoryConfigFieldCreatorID = "creatorId" + ActiveDirectoryConfigFieldDefaultLoginDomain = "defaultLoginDomain" + ActiveDirectoryConfigFieldEnabled = "enabled" + ActiveDirectoryConfigFieldGroupDNAttribute = "groupDNAttribute" + ActiveDirectoryConfigFieldGroupMemberMappingAttribute = "groupMemberMappingAttribute" + ActiveDirectoryConfigFieldGroupMemberUserAttribute = "groupMemberUserAttribute" + ActiveDirectoryConfigFieldGroupNameAttribute = "groupNameAttribute" + ActiveDirectoryConfigFieldGroupObjectClass = "groupObjectClass" + ActiveDirectoryConfigFieldGroupSearchAttribute = "groupSearchAttribute" + ActiveDirectoryConfigFieldGroupSearchBase = "groupSearchBase" + ActiveDirectoryConfigFieldGroupSearchFilter = "groupSearchFilter" + ActiveDirectoryConfigFieldLabels = "labels" + ActiveDirectoryConfigFieldName = "name" + ActiveDirectoryConfigFieldNestedGroupMembershipEnabled = "nestedGroupMembershipEnabled" + ActiveDirectoryConfigFieldOwnerReferences = "ownerReferences" + ActiveDirectoryConfigFieldPort = "port" + ActiveDirectoryConfigFieldRemoved = "removed" + ActiveDirectoryConfigFieldServers = "servers" + ActiveDirectoryConfigFieldServiceAccountPassword = "serviceAccountPassword" + ActiveDirectoryConfigFieldServiceAccountUsername = "serviceAccountUsername" + ActiveDirectoryConfigFieldStartTLS = "starttls" + ActiveDirectoryConfigFieldStatus = "status" + ActiveDirectoryConfigFieldTLS = "tls" + ActiveDirectoryConfigFieldType = "type" + ActiveDirectoryConfigFieldUUID = "uuid" + ActiveDirectoryConfigFieldUserDisabledBitMask = "userDisabledBitMask" + ActiveDirectoryConfigFieldUserEnabledAttribute = "userEnabledAttribute" + ActiveDirectoryConfigFieldUserLoginAttribute = "userLoginAttribute" + ActiveDirectoryConfigFieldUserNameAttribute = "userNameAttribute" + ActiveDirectoryConfigFieldUserObjectClass = "userObjectClass" + ActiveDirectoryConfigFieldUserSearchAttribute = "userSearchAttribute" + ActiveDirectoryConfigFieldUserSearchBase = "userSearchBase" + ActiveDirectoryConfigFieldUserSearchFilter = "userSearchFilter" +) + +type ActiveDirectoryConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" yaml:"connectionTimeout,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultLoginDomain string `json:"defaultLoginDomain,omitempty" yaml:"defaultLoginDomain,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" yaml:"groupDNAttribute,omitempty"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" yaml:"groupMemberMappingAttribute,omitempty"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" yaml:"groupMemberUserAttribute,omitempty"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" yaml:"groupNameAttribute,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" yaml:"groupObjectClass,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" yaml:"groupSearchAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty" yaml:"groupSearchFilter,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NestedGroupMembershipEnabled *bool `json:"nestedGroupMembershipEnabled,omitempty" yaml:"nestedGroupMembershipEnabled,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Servers []string `json:"servers,omitempty" yaml:"servers,omitempty"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" yaml:"serviceAccountPassword,omitempty"` + ServiceAccountUsername string `json:"serviceAccountUsername,omitempty" yaml:"serviceAccountUsername,omitempty"` + StartTLS bool `json:"starttls,omitempty" yaml:"starttls,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" yaml:"userDisabledBitMask,omitempty"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" yaml:"userEnabledAttribute,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" yaml:"userLoginAttribute,omitempty"` + UserNameAttribute string `json:"userNameAttribute,omitempty" yaml:"userNameAttribute,omitempty"` + UserObjectClass string `json:"userObjectClass,omitempty" yaml:"userObjectClass,omitempty"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" yaml:"userSearchAttribute,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"` + UserSearchFilter string `json:"userSearchFilter,omitempty" yaml:"userSearchFilter,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_test_and_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_test_and_apply_input.go new file mode 100644 index 0000000..3055af4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_active_directory_test_and_apply_input.go @@ -0,0 +1,16 @@ +package client + +const ( + ActiveDirectoryTestAndApplyInputType = "activeDirectoryTestAndApplyInput" + ActiveDirectoryTestAndApplyInputFieldActiveDirectoryConfig = "activeDirectoryConfig" + ActiveDirectoryTestAndApplyInputFieldEnabled = "enabled" + ActiveDirectoryTestAndApplyInputFieldPassword = "password" + ActiveDirectoryTestAndApplyInputFieldUsername = "username" +) + +type ActiveDirectoryTestAndApplyInput struct { + ActiveDirectoryConfig *ActiveDirectoryConfig `json:"activeDirectoryConfig,omitempty" yaml:"activeDirectoryConfig,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_adfs_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_adfs_config.go new file mode 100644 index 0000000..5170ec8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_adfs_config.go @@ -0,0 +1,52 @@ +package client + +const ( + ADFSConfigType = "adfsConfig" + ADFSConfigFieldAccessMode = "accessMode" + ADFSConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + ADFSConfigFieldAnnotations = "annotations" + ADFSConfigFieldCreated = "created" + ADFSConfigFieldCreatorID = "creatorId" + ADFSConfigFieldDisplayNameField = "displayNameField" + ADFSConfigFieldEnabled = "enabled" + ADFSConfigFieldEntityID = "entityID" + ADFSConfigFieldGroupsField = "groupsField" + ADFSConfigFieldIDPMetadataContent = "idpMetadataContent" + ADFSConfigFieldLabels = "labels" + ADFSConfigFieldName = "name" + ADFSConfigFieldOwnerReferences = "ownerReferences" + ADFSConfigFieldRancherAPIHost = "rancherApiHost" + ADFSConfigFieldRemoved = "removed" + ADFSConfigFieldSpCert = "spCert" + ADFSConfigFieldSpKey = "spKey" + ADFSConfigFieldStatus = "status" + ADFSConfigFieldType = "type" + ADFSConfigFieldUIDField = "uidField" + ADFSConfigFieldUUID = "uuid" + ADFSConfigFieldUserNameField = "userNameField" +) + +type ADFSConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DisplayNameField string `json:"displayNameField,omitempty" yaml:"displayNameField,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + EntityID string `json:"entityID,omitempty" yaml:"entityID,omitempty"` + GroupsField string `json:"groupsField,omitempty" yaml:"groupsField,omitempty"` + IDPMetadataContent string `json:"idpMetadataContent,omitempty" yaml:"idpMetadataContent,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherAPIHost string `json:"rancherApiHost,omitempty" yaml:"rancherApiHost,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SpCert string `json:"spCert,omitempty" yaml:"spCert,omitempty"` + SpKey string `json:"spKey,omitempty" yaml:"spKey,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UIDField string `json:"uidField,omitempty" yaml:"uidField,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserNameField string `json:"userNameField,omitempty" yaml:"userNameField,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aes_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aes_configuration.go new file mode 100644 index 0000000..21732a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aes_configuration.go @@ -0,0 +1,10 @@ +package client + +const ( + AESConfigurationType = "aesConfiguration" + AESConfigurationFieldKeys = "keys" +) + +type AESConfiguration struct { + Keys []Key `json:"keys,omitempty" yaml:"keys,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_affinity.go new file mode 100644 index 0000000..0489c3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_affinity.go @@ -0,0 +1,14 @@ +package client + +const ( + AffinityType = "affinity" + AffinityFieldNodeAffinity = "nodeAffinity" + AffinityFieldPodAffinity = "podAffinity" + AffinityFieldPodAntiAffinity = "podAntiAffinity" +) + +type Affinity struct { + NodeAffinity *NodeAffinity `json:"nodeAffinity,omitempty" yaml:"nodeAffinity,omitempty"` + PodAffinity *PodAffinity `json:"podAffinity,omitempty" yaml:"podAffinity,omitempty"` + PodAntiAffinity *PodAntiAffinity `json:"podAntiAffinity,omitempty" yaml:"podAntiAffinity,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_agent_deployment_customization.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_agent_deployment_customization.go new file mode 100644 index 0000000..841e6e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_agent_deployment_customization.go @@ -0,0 +1,14 @@ +package client + +const ( + AgentDeploymentCustomizationType = "agentDeploymentCustomization" + AgentDeploymentCustomizationFieldAppendTolerations = "appendTolerations" + AgentDeploymentCustomizationFieldOverrideAffinity = "overrideAffinity" + AgentDeploymentCustomizationFieldOverrideResourceRequirements = "overrideResourceRequirements" +) + +type AgentDeploymentCustomization struct { + AppendTolerations []Toleration `json:"appendTolerations,omitempty" yaml:"appendTolerations,omitempty"` + OverrideAffinity *Affinity `json:"overrideAffinity,omitempty" yaml:"overrideAffinity,omitempty"` + OverrideResourceRequirements *ResourceRequirements `json:"overrideResourceRequirements,omitempty" yaml:"overrideResourceRequirements,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_cluster_config_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_cluster_config_spec.go new file mode 100644 index 0000000..d6caad1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_cluster_config_spec.go @@ -0,0 +1,76 @@ +package client + +const ( + AKSClusterConfigSpecType = "aksClusterConfigSpec" + AKSClusterConfigSpecFieldAuthBaseURL = "authBaseUrl" + AKSClusterConfigSpecFieldAuthorizedIPRanges = "authorizedIpRanges" + AKSClusterConfigSpecFieldAzureCredentialSecret = "azureCredentialSecret" + AKSClusterConfigSpecFieldBaseURL = "baseUrl" + AKSClusterConfigSpecFieldClusterName = "clusterName" + AKSClusterConfigSpecFieldDNSPrefix = "dnsPrefix" + AKSClusterConfigSpecFieldHTTPApplicationRouting = "httpApplicationRouting" + AKSClusterConfigSpecFieldImported = "imported" + AKSClusterConfigSpecFieldKubernetesVersion = "kubernetesVersion" + AKSClusterConfigSpecFieldLinuxAdminUsername = "linuxAdminUsername" + AKSClusterConfigSpecFieldLinuxSSHPublicKey = "sshPublicKey" + AKSClusterConfigSpecFieldLoadBalancerSKU = "loadBalancerSku" + AKSClusterConfigSpecFieldLogAnalyticsWorkspaceGroup = "logAnalyticsWorkspaceGroup" + AKSClusterConfigSpecFieldLogAnalyticsWorkspaceName = "logAnalyticsWorkspaceName" + AKSClusterConfigSpecFieldManagedIdentity = "managedIdentity" + AKSClusterConfigSpecFieldMonitoring = "monitoring" + AKSClusterConfigSpecFieldNetworkDNSServiceIP = "dnsServiceIp" + AKSClusterConfigSpecFieldNetworkDockerBridgeCIDR = "dockerBridgeCidr" + AKSClusterConfigSpecFieldNetworkPlugin = "networkPlugin" + AKSClusterConfigSpecFieldNetworkPodCIDR = "podCidr" + AKSClusterConfigSpecFieldNetworkPolicy = "networkPolicy" + AKSClusterConfigSpecFieldNetworkServiceCIDR = "serviceCidr" + AKSClusterConfigSpecFieldNodePools = "nodePools" + AKSClusterConfigSpecFieldNodeResourceGroup = "nodeResourceGroup" + AKSClusterConfigSpecFieldOutboundType = "outboundType" + AKSClusterConfigSpecFieldPrivateCluster = "privateCluster" + AKSClusterConfigSpecFieldPrivateDNSZone = "privateDnsZone" + AKSClusterConfigSpecFieldResourceGroup = "resourceGroup" + AKSClusterConfigSpecFieldResourceLocation = "resourceLocation" + AKSClusterConfigSpecFieldSubnet = "subnet" + AKSClusterConfigSpecFieldTags = "tags" + AKSClusterConfigSpecFieldUserAssignedIdentity = "userAssignedIdentity" + AKSClusterConfigSpecFieldVirtualNetwork = "virtualNetwork" + AKSClusterConfigSpecFieldVirtualNetworkResourceGroup = "virtualNetworkResourceGroup" +) + +type AKSClusterConfigSpec struct { + AuthBaseURL *string `json:"authBaseUrl,omitempty" yaml:"authBaseUrl,omitempty"` + AuthorizedIPRanges *[]string `json:"authorizedIpRanges,omitempty" yaml:"authorizedIpRanges,omitempty"` + AzureCredentialSecret string `json:"azureCredentialSecret,omitempty" yaml:"azureCredentialSecret,omitempty"` + BaseURL *string `json:"baseUrl,omitempty" yaml:"baseUrl,omitempty"` + ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"` + DNSPrefix *string `json:"dnsPrefix,omitempty" yaml:"dnsPrefix,omitempty"` + HTTPApplicationRouting *bool `json:"httpApplicationRouting,omitempty" yaml:"httpApplicationRouting,omitempty"` + Imported bool `json:"imported,omitempty" yaml:"imported,omitempty"` + KubernetesVersion *string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` + LinuxAdminUsername *string `json:"linuxAdminUsername,omitempty" yaml:"linuxAdminUsername,omitempty"` + LinuxSSHPublicKey *string `json:"sshPublicKey,omitempty" yaml:"sshPublicKey,omitempty"` + LoadBalancerSKU *string `json:"loadBalancerSku,omitempty" yaml:"loadBalancerSku,omitempty"` + LogAnalyticsWorkspaceGroup *string `json:"logAnalyticsWorkspaceGroup,omitempty" yaml:"logAnalyticsWorkspaceGroup,omitempty"` + LogAnalyticsWorkspaceName *string `json:"logAnalyticsWorkspaceName,omitempty" yaml:"logAnalyticsWorkspaceName,omitempty"` + ManagedIdentity **bool `json:"managedIdentity,omitempty" yaml:"managedIdentity,omitempty"` + Monitoring *bool `json:"monitoring,omitempty" yaml:"monitoring,omitempty"` + NetworkDNSServiceIP *string `json:"dnsServiceIp,omitempty" yaml:"dnsServiceIp,omitempty"` + NetworkDockerBridgeCIDR *string `json:"dockerBridgeCidr,omitempty" yaml:"dockerBridgeCidr,omitempty"` + NetworkPlugin *string `json:"networkPlugin,omitempty" yaml:"networkPlugin,omitempty"` + NetworkPodCIDR *string `json:"podCidr,omitempty" yaml:"podCidr,omitempty"` + NetworkPolicy *string `json:"networkPolicy,omitempty" yaml:"networkPolicy,omitempty"` + NetworkServiceCIDR *string `json:"serviceCidr,omitempty" yaml:"serviceCidr,omitempty"` + NodePools []AKSNodePool `json:"nodePools,omitempty" yaml:"nodePools,omitempty"` + NodeResourceGroup *string `json:"nodeResourceGroup,omitempty" yaml:"nodeResourceGroup,omitempty"` + OutboundType *string `json:"outboundType,omitempty" yaml:"outboundType,omitempty"` + PrivateCluster *bool `json:"privateCluster,omitempty" yaml:"privateCluster,omitempty"` + PrivateDNSZone *string `json:"privateDnsZone,omitempty" yaml:"privateDnsZone,omitempty"` + ResourceGroup string `json:"resourceGroup,omitempty" yaml:"resourceGroup,omitempty"` + ResourceLocation string `json:"resourceLocation,omitempty" yaml:"resourceLocation,omitempty"` + Subnet *string `json:"subnet,omitempty" yaml:"subnet,omitempty"` + Tags map[string]string `json:"tags,omitempty" yaml:"tags,omitempty"` + UserAssignedIdentity *string `json:"userAssignedIdentity,omitempty" yaml:"userAssignedIdentity,omitempty"` + VirtualNetwork *string `json:"virtualNetwork,omitempty" yaml:"virtualNetwork,omitempty"` + VirtualNetworkResourceGroup *string `json:"virtualNetworkResourceGroup,omitempty" yaml:"virtualNetworkResourceGroup,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_node_pool.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_node_pool.go new file mode 100644 index 0000000..43e5721 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_node_pool.go @@ -0,0 +1,42 @@ +package client + +const ( + AKSNodePoolType = "aksNodePool" + AKSNodePoolFieldAvailabilityZones = "availabilityZones" + AKSNodePoolFieldCount = "count" + AKSNodePoolFieldEnableAutoScaling = "enableAutoScaling" + AKSNodePoolFieldMaxCount = "maxCount" + AKSNodePoolFieldMaxPods = "maxPods" + AKSNodePoolFieldMaxSurge = "maxSurge" + AKSNodePoolFieldMinCount = "minCount" + AKSNodePoolFieldMode = "mode" + AKSNodePoolFieldName = "name" + AKSNodePoolFieldNodeLabels = "nodeLabels" + AKSNodePoolFieldNodeTaints = "nodeTaints" + AKSNodePoolFieldOrchestratorVersion = "orchestratorVersion" + AKSNodePoolFieldOsDiskSizeGB = "osDiskSizeGB" + AKSNodePoolFieldOsDiskType = "osDiskType" + AKSNodePoolFieldOsType = "osType" + AKSNodePoolFieldVMSize = "vmSize" + AKSNodePoolFieldVnetSubnetID = "vnetSubnetID" +) + +type AKSNodePool struct { + AvailabilityZones *[]string `json:"availabilityZones,omitempty" yaml:"availabilityZones,omitempty"` + Count *int64 `json:"count,omitempty" yaml:"count,omitempty"` + EnableAutoScaling *bool `json:"enableAutoScaling,omitempty" yaml:"enableAutoScaling,omitempty"` + MaxCount *int64 `json:"maxCount,omitempty" yaml:"maxCount,omitempty"` + MaxPods *int64 `json:"maxPods,omitempty" yaml:"maxPods,omitempty"` + MaxSurge string `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MinCount *int64 `json:"minCount,omitempty" yaml:"minCount,omitempty"` + Mode string `json:"mode,omitempty" yaml:"mode,omitempty"` + Name *string `json:"name,omitempty" yaml:"name,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" yaml:"nodeLabels,omitempty"` + NodeTaints []string `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + OrchestratorVersion *string `json:"orchestratorVersion,omitempty" yaml:"orchestratorVersion,omitempty"` + OsDiskSizeGB *int64 `json:"osDiskSizeGB,omitempty" yaml:"osDiskSizeGB,omitempty"` + OsDiskType string `json:"osDiskType,omitempty" yaml:"osDiskType,omitempty"` + OsType string `json:"osType,omitempty" yaml:"osType,omitempty"` + VMSize string `json:"vmSize,omitempty" yaml:"vmSize,omitempty"` + VnetSubnetID *string `json:"vnetSubnetID,omitempty" yaml:"vnetSubnetID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_status.go new file mode 100644 index 0000000..91074c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aks_status.go @@ -0,0 +1,14 @@ +package client + +const ( + AKSStatusType = "aksStatus" + AKSStatusFieldPrivateRequiresTunnel = "privateRequiresTunnel" + AKSStatusFieldRBACEnabled = "rbacEnabled" + AKSStatusFieldUpstreamSpec = "upstreamSpec" +) + +type AKSStatus struct { + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel,omitempty" yaml:"privateRequiresTunnel,omitempty"` + RBACEnabled *bool `json:"rbacEnabled,omitempty" yaml:"rbacEnabled,omitempty"` + UpstreamSpec *AKSClusterConfigSpec `json:"upstreamSpec,omitempty" yaml:"upstreamSpec,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_alidns_provider_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_alidns_provider_config.go new file mode 100644 index 0000000..a58df2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_alidns_provider_config.go @@ -0,0 +1,14 @@ +package client + +const ( + AlidnsProviderConfigType = "alidnsProviderConfig" + AlidnsProviderConfigFieldAccessKey = "accessKey" + AlidnsProviderConfigFieldAdditionalOptions = "additionalOptions" + AlidnsProviderConfigFieldSecretKey = "secretKey" +) + +type AlidnsProviderConfig struct { + AccessKey string `json:"accessKey,omitempty" yaml:"accessKey,omitempty"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty" yaml:"additionalOptions,omitempty"` + SecretKey string `json:"secretKey,omitempty" yaml:"secretKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_answer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_answer.go new file mode 100644 index 0000000..d79e0c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_answer.go @@ -0,0 +1,16 @@ +package client + +const ( + AnswerType = "answer" + AnswerFieldClusterID = "clusterId" + AnswerFieldProjectID = "projectId" + AnswerFieldValues = "values" + AnswerFieldValuesSetString = "valuesSetString" +) + +type Answer struct { + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Values map[string]string `json:"values,omitempty" yaml:"values,omitempty"` + ValuesSetString map[string]string `json:"valuesSetString,omitempty" yaml:"valuesSetString,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_app_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_app_condition.go new file mode 100644 index 0000000..9d633ae --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_app_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + AppConditionType = "appCondition" + AppConditionFieldLastTransitionTime = "lastTransitionTime" + AppConditionFieldLastUpdateTime = "lastUpdateTime" + AppConditionFieldMessage = "message" + AppConditionFieldReason = "reason" + AppConditionFieldStatus = "status" + AppConditionFieldType = "type" +) + +type AppCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_attached_volume.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_attached_volume.go new file mode 100644 index 0000000..c3bbe0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_attached_volume.go @@ -0,0 +1,10 @@ +package client + +const ( + AttachedVolumeType = "attachedVolume" + AttachedVolumeFieldName = "name" +) + +type AttachedVolume struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log.go new file mode 100644 index 0000000..7d605ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log.go @@ -0,0 +1,12 @@ +package client + +const ( + AuditLogType = "auditLog" + AuditLogFieldConfiguration = "configuration" + AuditLogFieldEnabled = "enabled" +) + +type AuditLog struct { + Configuration *AuditLogConfig `json:"configuration,omitempty" yaml:"configuration,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log_config.go new file mode 100644 index 0000000..d1d8289 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_audit_log_config.go @@ -0,0 +1,20 @@ +package client + +const ( + AuditLogConfigType = "auditLogConfig" + AuditLogConfigFieldFormat = "format" + AuditLogConfigFieldMaxAge = "maxAge" + AuditLogConfigFieldMaxBackup = "maxBackup" + AuditLogConfigFieldMaxSize = "maxSize" + AuditLogConfigFieldPath = "path" + AuditLogConfigFieldPolicy = "policy" +) + +type AuditLogConfig struct { + Format string `json:"format,omitempty" yaml:"format,omitempty"` + MaxAge int64 `json:"maxAge,omitempty" yaml:"maxAge,omitempty"` + MaxBackup int64 `json:"maxBackup,omitempty" yaml:"maxBackup,omitempty"` + MaxSize int64 `json:"maxSize,omitempty" yaml:"maxSize,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Policy map[string]interface{} `json:"policy,omitempty" yaml:"policy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config.go new file mode 100644 index 0000000..ac6c47b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + AuthConfigType = "authConfig" + AuthConfigFieldAccessMode = "accessMode" + AuthConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + AuthConfigFieldAnnotations = "annotations" + AuthConfigFieldCreated = "created" + AuthConfigFieldCreatorID = "creatorId" + AuthConfigFieldEnabled = "enabled" + AuthConfigFieldLabels = "labels" + AuthConfigFieldName = "name" + AuthConfigFieldOwnerReferences = "ownerReferences" + AuthConfigFieldRemoved = "removed" + AuthConfigFieldStatus = "status" + AuthConfigFieldType = "type" + AuthConfigFieldUUID = "uuid" +) + +type AuthConfig struct { + types.Resource + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type AuthConfigCollection struct { + types.Collection + Data []AuthConfig `json:"data,omitempty"` + client *AuthConfigClient +} + +type AuthConfigClient struct { + apiClient *Client +} + +type AuthConfigOperations interface { + List(opts *types.ListOpts) (*AuthConfigCollection, error) + ListAll(opts *types.ListOpts) (*AuthConfigCollection, error) + Create(opts *AuthConfig) (*AuthConfig, error) + Update(existing *AuthConfig, updates interface{}) (*AuthConfig, error) + Replace(existing *AuthConfig) (*AuthConfig, error) + ByID(id string) (*AuthConfig, error) + Delete(container *AuthConfig) error +} + +func newAuthConfigClient(apiClient *Client) *AuthConfigClient { + return &AuthConfigClient{ + apiClient: apiClient, + } +} + +func (c *AuthConfigClient) Create(container *AuthConfig) (*AuthConfig, error) { + resp := &AuthConfig{} + err := c.apiClient.Ops.DoCreate(AuthConfigType, container, resp) + return resp, err +} + +func (c *AuthConfigClient) Update(existing *AuthConfig, updates interface{}) (*AuthConfig, error) { + resp := &AuthConfig{} + err := c.apiClient.Ops.DoUpdate(AuthConfigType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *AuthConfigClient) Replace(obj *AuthConfig) (*AuthConfig, error) { + resp := &AuthConfig{} + err := c.apiClient.Ops.DoReplace(AuthConfigType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *AuthConfigClient) List(opts *types.ListOpts) (*AuthConfigCollection, error) { + resp := &AuthConfigCollection{} + err := c.apiClient.Ops.DoList(AuthConfigType, opts, resp) + resp.client = c + return resp, err +} + +func (c *AuthConfigClient) ListAll(opts *types.ListOpts) (*AuthConfigCollection, error) { + resp := &AuthConfigCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *AuthConfigCollection) Next() (*AuthConfigCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &AuthConfigCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *AuthConfigClient) ByID(id string) (*AuthConfig, error) { + resp := &AuthConfig{} + err := c.apiClient.Ops.DoByID(AuthConfigType, id, resp) + return resp, err +} + +func (c *AuthConfigClient) Delete(container *AuthConfig) error { + return c.apiClient.Ops.DoResourceDelete(AuthConfigType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_conditions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_conditions.go new file mode 100644 index 0000000..bf92ef0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_conditions.go @@ -0,0 +1,20 @@ +package client + +const ( + AuthConfigConditionsType = "authConfigConditions" + AuthConfigConditionsFieldLastTransitionTime = "lastTransitionTime" + AuthConfigConditionsFieldLastUpdateTime = "lastUpdateTime" + AuthConfigConditionsFieldMessage = "message" + AuthConfigConditionsFieldReason = "reason" + AuthConfigConditionsFieldStatus = "status" + AuthConfigConditionsFieldType = "type" +) + +type AuthConfigConditions struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_status.go new file mode 100644 index 0000000..e92cbec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_config_status.go @@ -0,0 +1,10 @@ +package client + +const ( + AuthConfigStatusType = "authConfigStatus" + AuthConfigStatusFieldConditions = "conditions" +) + +type AuthConfigStatus struct { + Conditions []AuthConfigConditions `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_webhook_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_webhook_config.go new file mode 100644 index 0000000..b9bbc1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_auth_webhook_config.go @@ -0,0 +1,12 @@ +package client + +const ( + AuthWebhookConfigType = "authWebhookConfig" + AuthWebhookConfigFieldCacheTimeout = "cacheTimeout" + AuthWebhookConfigFieldConfigFile = "configFile" +) + +type AuthWebhookConfig struct { + CacheTimeout string `json:"cacheTimeout,omitempty" yaml:"cacheTimeout,omitempty"` + ConfigFile string `json:"configFile,omitempty" yaml:"configFile,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authn_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authn_config.go new file mode 100644 index 0000000..e740e61 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authn_config.go @@ -0,0 +1,14 @@ +package client + +const ( + AuthnConfigType = "authnConfig" + AuthnConfigFieldSANs = "sans" + AuthnConfigFieldStrategy = "strategy" + AuthnConfigFieldWebhook = "webhook" +) + +type AuthnConfig struct { + SANs []string `json:"sans,omitempty" yaml:"sans,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` + Webhook *AuthWebhookConfig `json:"webhook,omitempty" yaml:"webhook,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authz_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authz_config.go new file mode 100644 index 0000000..ee491dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_authz_config.go @@ -0,0 +1,12 @@ +package client + +const ( + AuthzConfigType = "authzConfig" + AuthzConfigFieldMode = "mode" + AuthzConfigFieldOptions = "options" +) + +type AuthzConfig struct { + Mode string `json:"mode,omitempty" yaml:"mode,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_cloud_provider.go new file mode 100644 index 0000000..bb1ebd0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_cloud_provider.go @@ -0,0 +1,12 @@ +package client + +const ( + AWSCloudProviderType = "awsCloudProvider" + AWSCloudProviderFieldGlobal = "global" + AWSCloudProviderFieldServiceOverride = "serviceOverride" +) + +type AWSCloudProvider struct { + Global *GlobalAwsOpts `json:"global,omitempty" yaml:"global,omitempty"` + ServiceOverride map[string]ServiceOverride `json:"serviceOverride,omitempty" yaml:"serviceOverride,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_elastic_block_store_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_elastic_block_store_volume_source.go new file mode 100644 index 0000000..5765e83 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_aws_elastic_block_store_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + AWSElasticBlockStoreVolumeSourceType = "awsElasticBlockStoreVolumeSource" + AWSElasticBlockStoreVolumeSourceFieldFSType = "fsType" + AWSElasticBlockStoreVolumeSourceFieldPartition = "partition" + AWSElasticBlockStoreVolumeSourceFieldReadOnly = "readOnly" + AWSElasticBlockStoreVolumeSourceFieldVolumeID = "volumeID" +) + +type AWSElasticBlockStoreVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig.go new file mode 100644 index 0000000..4de1b3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig.go @@ -0,0 +1,54 @@ +package client + +const ( + AzureADConfigType = "azureADConfig" + AzureADConfigFieldAccessMode = "accessMode" + AzureADConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + AzureADConfigFieldAnnotations = "annotations" + AzureADConfigFieldApplicationID = "applicationId" + AzureADConfigFieldApplicationSecret = "applicationSecret" + AzureADConfigFieldAuthEndpoint = "authEndpoint" + AzureADConfigFieldCreated = "created" + AzureADConfigFieldCreatorID = "creatorId" + AzureADConfigFieldDeviceAuthEndpoint = "deviceAuthEndpoint" + AzureADConfigFieldEnabled = "enabled" + AzureADConfigFieldEndpoint = "endpoint" + AzureADConfigFieldGraphEndpoint = "graphEndpoint" + AzureADConfigFieldGroupMembershipFilter = "groupMembershipFilter" + AzureADConfigFieldLabels = "labels" + AzureADConfigFieldName = "name" + AzureADConfigFieldOwnerReferences = "ownerReferences" + AzureADConfigFieldRancherURL = "rancherUrl" + AzureADConfigFieldRemoved = "removed" + AzureADConfigFieldStatus = "status" + AzureADConfigFieldTenantID = "tenantId" + AzureADConfigFieldTokenEndpoint = "tokenEndpoint" + AzureADConfigFieldType = "type" + AzureADConfigFieldUUID = "uuid" +) + +type AzureADConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ApplicationID string `json:"applicationId,omitempty" yaml:"applicationId,omitempty"` + ApplicationSecret string `json:"applicationSecret,omitempty" yaml:"applicationSecret,omitempty"` + AuthEndpoint string `json:"authEndpoint,omitempty" yaml:"authEndpoint,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DeviceAuthEndpoint string `json:"deviceAuthEndpoint,omitempty" yaml:"deviceAuthEndpoint,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + GraphEndpoint string `json:"graphEndpoint,omitempty" yaml:"graphEndpoint,omitempty"` + GroupMembershipFilter string `json:"groupMembershipFilter,omitempty" yaml:"groupMembershipFilter,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherURL string `json:"rancherUrl,omitempty" yaml:"rancherUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TenantID string `json:"tenantId,omitempty" yaml:"tenantId,omitempty"` + TokenEndpoint string `json:"tokenEndpoint,omitempty" yaml:"tokenEndpoint,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_apply_input.go new file mode 100644 index 0000000..a1e5b39 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_apply_input.go @@ -0,0 +1,12 @@ +package client + +const ( + AzureADConfigApplyInputType = "azureADConfigApplyInput" + AzureADConfigApplyInputFieldCode = "code" + AzureADConfigApplyInputFieldConfig = "config" +) + +type AzureADConfigApplyInput struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Config *AzureADConfig `json:"config,omitempty" yaml:"config,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_test_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_test_output.go new file mode 100644 index 0000000..4ce9827 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_adconfig_test_output.go @@ -0,0 +1,10 @@ +package client + +const ( + AzureADConfigTestOutputType = "azureADConfigTestOutput" + AzureADConfigTestOutputFieldRedirectURL = "redirectUrl" +) + +type AzureADConfigTestOutput struct { + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_cloud_provider.go new file mode 100644 index 0000000..df355ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_cloud_provider.go @@ -0,0 +1,74 @@ +package client + +const ( + AzureCloudProviderType = "azureCloudProvider" + AzureCloudProviderFieldAADClientCertPassword = "aadClientCertPassword" + AzureCloudProviderFieldAADClientCertPath = "aadClientCertPath" + AzureCloudProviderFieldAADClientID = "aadClientId" + AzureCloudProviderFieldAADClientSecret = "aadClientSecret" + AzureCloudProviderFieldCloud = "cloud" + AzureCloudProviderFieldCloudProviderBackoff = "cloudProviderBackoff" + AzureCloudProviderFieldCloudProviderBackoffDuration = "cloudProviderBackoffDuration" + AzureCloudProviderFieldCloudProviderBackoffExponent = "cloudProviderBackoffExponent" + AzureCloudProviderFieldCloudProviderBackoffJitter = "cloudProviderBackoffJitter" + AzureCloudProviderFieldCloudProviderBackoffRetries = "cloudProviderBackoffRetries" + AzureCloudProviderFieldCloudProviderRateLimit = "cloudProviderRateLimit" + AzureCloudProviderFieldCloudProviderRateLimitBucket = "cloudProviderRateLimitBucket" + AzureCloudProviderFieldCloudProviderRateLimitQPS = "cloudProviderRateLimitQPS" + AzureCloudProviderFieldExcludeMasterFromStandardLB = "excludeMasterFromStandardLB" + AzureCloudProviderFieldLoadBalancerSku = "loadBalancerSku" + AzureCloudProviderFieldLocation = "location" + AzureCloudProviderFieldMaximumLoadBalancerRuleCount = "maximumLoadBalancerRuleCount" + AzureCloudProviderFieldPrimaryAvailabilitySetName = "primaryAvailabilitySetName" + AzureCloudProviderFieldPrimaryScaleSetName = "primaryScaleSetName" + AzureCloudProviderFieldResourceGroup = "resourceGroup" + AzureCloudProviderFieldRouteTableName = "routeTableName" + AzureCloudProviderFieldSecurityGroupName = "securityGroupName" + AzureCloudProviderFieldSecurityGroupResourceGroup = "securityGroupResourceGroup" + AzureCloudProviderFieldSubnetName = "subnetName" + AzureCloudProviderFieldSubscriptionID = "subscriptionId" + AzureCloudProviderFieldTags = "tags" + AzureCloudProviderFieldTenantID = "tenantId" + AzureCloudProviderFieldUseInstanceMetadata = "useInstanceMetadata" + AzureCloudProviderFieldUseManagedIdentityExtension = "useManagedIdentityExtension" + AzureCloudProviderFieldUserAssignedIdentityID = "userAssignedIdentityID" + AzureCloudProviderFieldVMType = "vmType" + AzureCloudProviderFieldVnetName = "vnetName" + AzureCloudProviderFieldVnetResourceGroup = "vnetResourceGroup" +) + +type AzureCloudProvider struct { + AADClientCertPassword string `json:"aadClientCertPassword,omitempty" yaml:"aadClientCertPassword,omitempty"` + AADClientCertPath string `json:"aadClientCertPath,omitempty" yaml:"aadClientCertPath,omitempty"` + AADClientID string `json:"aadClientId,omitempty" yaml:"aadClientId,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + Cloud string `json:"cloud,omitempty" yaml:"cloud,omitempty"` + CloudProviderBackoff bool `json:"cloudProviderBackoff,omitempty" yaml:"cloudProviderBackoff,omitempty"` + CloudProviderBackoffDuration int64 `json:"cloudProviderBackoffDuration,omitempty" yaml:"cloudProviderBackoffDuration,omitempty"` + CloudProviderBackoffExponent int64 `json:"cloudProviderBackoffExponent,omitempty" yaml:"cloudProviderBackoffExponent,omitempty"` + CloudProviderBackoffJitter int64 `json:"cloudProviderBackoffJitter,omitempty" yaml:"cloudProviderBackoffJitter,omitempty"` + CloudProviderBackoffRetries int64 `json:"cloudProviderBackoffRetries,omitempty" yaml:"cloudProviderBackoffRetries,omitempty"` + CloudProviderRateLimit bool `json:"cloudProviderRateLimit,omitempty" yaml:"cloudProviderRateLimit,omitempty"` + CloudProviderRateLimitBucket int64 `json:"cloudProviderRateLimitBucket,omitempty" yaml:"cloudProviderRateLimitBucket,omitempty"` + CloudProviderRateLimitQPS int64 `json:"cloudProviderRateLimitQPS,omitempty" yaml:"cloudProviderRateLimitQPS,omitempty"` + ExcludeMasterFromStandardLB *bool `json:"excludeMasterFromStandardLB,omitempty" yaml:"excludeMasterFromStandardLB,omitempty"` + LoadBalancerSku string `json:"loadBalancerSku,omitempty" yaml:"loadBalancerSku,omitempty"` + Location string `json:"location,omitempty" yaml:"location,omitempty"` + MaximumLoadBalancerRuleCount int64 `json:"maximumLoadBalancerRuleCount,omitempty" yaml:"maximumLoadBalancerRuleCount,omitempty"` + PrimaryAvailabilitySetName string `json:"primaryAvailabilitySetName,omitempty" yaml:"primaryAvailabilitySetName,omitempty"` + PrimaryScaleSetName string `json:"primaryScaleSetName,omitempty" yaml:"primaryScaleSetName,omitempty"` + ResourceGroup string `json:"resourceGroup,omitempty" yaml:"resourceGroup,omitempty"` + RouteTableName string `json:"routeTableName,omitempty" yaml:"routeTableName,omitempty"` + SecurityGroupName string `json:"securityGroupName,omitempty" yaml:"securityGroupName,omitempty"` + SecurityGroupResourceGroup string `json:"securityGroupResourceGroup,omitempty" yaml:"securityGroupResourceGroup,omitempty"` + SubnetName string `json:"subnetName,omitempty" yaml:"subnetName,omitempty"` + SubscriptionID string `json:"subscriptionId,omitempty" yaml:"subscriptionId,omitempty"` + Tags string `json:"tags,omitempty" yaml:"tags,omitempty"` + TenantID string `json:"tenantId,omitempty" yaml:"tenantId,omitempty"` + UseInstanceMetadata bool `json:"useInstanceMetadata,omitempty" yaml:"useInstanceMetadata,omitempty"` + UseManagedIdentityExtension bool `json:"useManagedIdentityExtension,omitempty" yaml:"useManagedIdentityExtension,omitempty"` + UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty" yaml:"userAssignedIdentityID,omitempty"` + VMType string `json:"vmType,omitempty" yaml:"vmType,omitempty"` + VnetName string `json:"vnetName,omitempty" yaml:"vnetName,omitempty"` + VnetResourceGroup string `json:"vnetResourceGroup,omitempty" yaml:"vnetResourceGroup,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_disk_volume_source.go new file mode 100644 index 0000000..28920c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_disk_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + AzureDiskVolumeSourceType = "azureDiskVolumeSource" + AzureDiskVolumeSourceFieldCachingMode = "cachingMode" + AzureDiskVolumeSourceFieldDataDiskURI = "diskURI" + AzureDiskVolumeSourceFieldDiskName = "diskName" + AzureDiskVolumeSourceFieldFSType = "fsType" + AzureDiskVolumeSourceFieldKind = "kind" + AzureDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type AzureDiskVolumeSource struct { + CachingMode string `json:"cachingMode,omitempty" yaml:"cachingMode,omitempty"` + DataDiskURI string `json:"diskURI,omitempty" yaml:"diskURI,omitempty"` + DiskName string `json:"diskName,omitempty" yaml:"diskName,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_file_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_file_volume_source.go new file mode 100644 index 0000000..3be8571 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_azure_file_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + AzureFileVolumeSourceType = "azureFileVolumeSource" + AzureFileVolumeSourceFieldReadOnly = "readOnly" + AzureFileVolumeSourceFieldSecretName = "secretName" + AzureFileVolumeSourceFieldShareName = "shareName" +) + +type AzureFileVolumeSource struct { + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` + ShareName string `json:"shareName,omitempty" yaml:"shareName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_backup_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_backup_config.go new file mode 100644 index 0000000..140cf15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_backup_config.go @@ -0,0 +1,20 @@ +package client + +const ( + BackupConfigType = "backupConfig" + BackupConfigFieldEnabled = "enabled" + BackupConfigFieldIntervalHours = "intervalHours" + BackupConfigFieldRetention = "retention" + BackupConfigFieldS3BackupConfig = "s3BackupConfig" + BackupConfigFieldSafeTimestamp = "safeTimestamp" + BackupConfigFieldTimeout = "timeout" +) + +type BackupConfig struct { + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + IntervalHours int64 `json:"intervalHours,omitempty" yaml:"intervalHours,omitempty"` + Retention int64 `json:"retention,omitempty" yaml:"retention,omitempty"` + S3BackupConfig *S3BackupConfig `json:"s3BackupConfig,omitempty" yaml:"s3BackupConfig,omitempty"` + SafeTimestamp bool `json:"safeTimestamp,omitempty" yaml:"safeTimestamp,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_bastion_host.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_bastion_host.go new file mode 100644 index 0000000..ac24e24 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_bastion_host.go @@ -0,0 +1,26 @@ +package client + +const ( + BastionHostType = "bastionHost" + BastionHostFieldAddress = "address" + BastionHostFieldIgnoreProxyEnvVars = "ignoreProxyEnvVars" + BastionHostFieldPort = "port" + BastionHostFieldSSHAgentAuth = "sshAgentAuth" + BastionHostFieldSSHCert = "sshCert" + BastionHostFieldSSHCertPath = "sshCertPath" + BastionHostFieldSSHKey = "sshKey" + BastionHostFieldSSHKeyPath = "sshKeyPath" + BastionHostFieldUser = "user" +) + +type BastionHost struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + IgnoreProxyEnvVars bool `json:"ignoreProxyEnvVars,omitempty" yaml:"ignoreProxyEnvVars,omitempty"` + Port string `json:"port,omitempty" yaml:"port,omitempty"` + SSHAgentAuth bool `json:"sshAgentAuth,omitempty" yaml:"sshAgentAuth,omitempty"` + SSHCert string `json:"sshCert,omitempty" yaml:"sshCert,omitempty"` + SSHCertPath string `json:"sshCertPath,omitempty" yaml:"sshCertPath,omitempty"` + SSHKey string `json:"sshKey,omitempty" yaml:"sshKey,omitempty"` + SSHKeyPath string `json:"sshKeyPath,omitempty" yaml:"sshKeyPath,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_block_storage_openstack_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_block_storage_openstack_opts.go new file mode 100644 index 0000000..b95bb36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_block_storage_openstack_opts.go @@ -0,0 +1,14 @@ +package client + +const ( + BlockStorageOpenstackOptsType = "blockStorageOpenstackOpts" + BlockStorageOpenstackOptsFieldBSVersion = "bs-version" + BlockStorageOpenstackOptsFieldIgnoreVolumeAZ = "ignore-volume-az" + BlockStorageOpenstackOptsFieldTrustDevicePath = "trust-device-path" +) + +type BlockStorageOpenstackOpts struct { + BSVersion string `json:"bs-version,omitempty" yaml:"bs-version,omitempty"` + IgnoreVolumeAZ bool `json:"ignore-volume-az,omitempty" yaml:"ignore-volume-az,omitempty"` + TrustDevicePath bool `json:"trust-device-path,omitempty" yaml:"trust-device-path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_calico_network_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_calico_network_provider.go new file mode 100644 index 0000000..4bfc50b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_calico_network_provider.go @@ -0,0 +1,10 @@ +package client + +const ( + CalicoNetworkProviderType = "calicoNetworkProvider" + CalicoNetworkProviderFieldCloudProvider = "cloudProvider" +) + +type CalicoNetworkProvider struct { + CloudProvider string `json:"cloudProvider,omitempty" yaml:"cloudProvider,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_canal_network_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_canal_network_provider.go new file mode 100644 index 0000000..e648a18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_canal_network_provider.go @@ -0,0 +1,10 @@ +package client + +const ( + CanalNetworkProviderType = "canalNetworkProvider" + CanalNetworkProviderFieldIface = "iface" +) + +type CanalNetworkProvider struct { + Iface string `json:"iface,omitempty" yaml:"iface,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_capabilities.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_capabilities.go new file mode 100644 index 0000000..887bcbd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_capabilities.go @@ -0,0 +1,18 @@ +package client + +const ( + CapabilitiesType = "capabilities" + CapabilitiesFieldIngressCapabilities = "ingressCapabilities" + CapabilitiesFieldLoadBalancerCapabilities = "loadBalancerCapabilities" + CapabilitiesFieldNodePoolScalingSupported = "nodePoolScalingSupported" + CapabilitiesFieldNodePortRange = "nodePortRange" + CapabilitiesFieldTaintSupport = "taintSupport" +) + +type Capabilities struct { + IngressCapabilities []IngressCapabilities `json:"ingressCapabilities,omitempty" yaml:"ingressCapabilities,omitempty"` + LoadBalancerCapabilities *LoadBalancerCapabilities `json:"loadBalancerCapabilities,omitempty" yaml:"loadBalancerCapabilities,omitempty"` + NodePoolScalingSupported bool `json:"nodePoolScalingSupported,omitempty" yaml:"nodePoolScalingSupported,omitempty"` + NodePortRange string `json:"nodePortRange,omitempty" yaml:"nodePortRange,omitempty"` + TaintSupport *bool `json:"taintSupport,omitempty" yaml:"taintSupport,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog.go new file mode 100644 index 0000000..4d32338 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog.go @@ -0,0 +1,164 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CatalogType = "catalog" + CatalogFieldAnnotations = "annotations" + CatalogFieldBranch = "branch" + CatalogFieldCatalogSecrets = "catalogSecrets" + CatalogFieldCommit = "commit" + CatalogFieldConditions = "conditions" + CatalogFieldCreated = "created" + CatalogFieldCreatorID = "creatorId" + CatalogFieldCredentialSecret = "credentialSecret" + CatalogFieldDescription = "description" + CatalogFieldHelmVersion = "helmVersion" + CatalogFieldKind = "kind" + CatalogFieldLabels = "labels" + CatalogFieldLastRefreshTimestamp = "lastRefreshTimestamp" + CatalogFieldName = "name" + CatalogFieldOwnerReferences = "ownerReferences" + CatalogFieldPassword = "password" + CatalogFieldRemoved = "removed" + CatalogFieldState = "state" + CatalogFieldTransitioning = "transitioning" + CatalogFieldTransitioningMessage = "transitioningMessage" + CatalogFieldURL = "url" + CatalogFieldUUID = "uuid" + CatalogFieldUsername = "username" +) + +type Catalog struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + CatalogSecrets *CatalogSecrets `json:"catalogSecrets,omitempty" yaml:"catalogSecrets,omitempty"` + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` + Conditions []CatalogCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CredentialSecret string `json:"credentialSecret,omitempty" yaml:"credentialSecret,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastRefreshTimestamp string `json:"lastRefreshTimestamp,omitempty" yaml:"lastRefreshTimestamp,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type CatalogCollection struct { + types.Collection + Data []Catalog `json:"data,omitempty"` + client *CatalogClient +} + +type CatalogClient struct { + apiClient *Client +} + +type CatalogOperations interface { + List(opts *types.ListOpts) (*CatalogCollection, error) + ListAll(opts *types.ListOpts) (*CatalogCollection, error) + Create(opts *Catalog) (*Catalog, error) + Update(existing *Catalog, updates interface{}) (*Catalog, error) + Replace(existing *Catalog) (*Catalog, error) + ByID(id string) (*Catalog, error) + Delete(container *Catalog) error + + ActionRefresh(resource *Catalog) (*CatalogRefresh, error) + + CollectionActionRefresh(resource *CatalogCollection) (*CatalogRefresh, error) +} + +func newCatalogClient(apiClient *Client) *CatalogClient { + return &CatalogClient{ + apiClient: apiClient, + } +} + +func (c *CatalogClient) Create(container *Catalog) (*Catalog, error) { + resp := &Catalog{} + err := c.apiClient.Ops.DoCreate(CatalogType, container, resp) + return resp, err +} + +func (c *CatalogClient) Update(existing *Catalog, updates interface{}) (*Catalog, error) { + resp := &Catalog{} + err := c.apiClient.Ops.DoUpdate(CatalogType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CatalogClient) Replace(obj *Catalog) (*Catalog, error) { + resp := &Catalog{} + err := c.apiClient.Ops.DoReplace(CatalogType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CatalogClient) List(opts *types.ListOpts) (*CatalogCollection, error) { + resp := &CatalogCollection{} + err := c.apiClient.Ops.DoList(CatalogType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CatalogClient) ListAll(opts *types.ListOpts) (*CatalogCollection, error) { + resp := &CatalogCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CatalogCollection) Next() (*CatalogCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CatalogCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CatalogClient) ByID(id string) (*Catalog, error) { + resp := &Catalog{} + err := c.apiClient.Ops.DoByID(CatalogType, id, resp) + return resp, err +} + +func (c *CatalogClient) Delete(container *Catalog) error { + return c.apiClient.Ops.DoResourceDelete(CatalogType, &container.Resource) +} + +func (c *CatalogClient) ActionRefresh(resource *Catalog) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoAction(CatalogType, "refresh", &resource.Resource, nil, resp) + return resp, err +} + +func (c *CatalogClient) CollectionActionRefresh(resource *CatalogCollection) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoCollectionAction(CatalogType, "refresh", &resource.Collection, nil, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_condition.go new file mode 100644 index 0000000..0aba7f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + CatalogConditionType = "catalogCondition" + CatalogConditionFieldLastTransitionTime = "lastTransitionTime" + CatalogConditionFieldLastUpdateTime = "lastUpdateTime" + CatalogConditionFieldMessage = "message" + CatalogConditionFieldReason = "reason" + CatalogConditionFieldStatus = "status" + CatalogConditionFieldType = "type" +) + +type CatalogCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_refresh.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_refresh.go new file mode 100644 index 0000000..b2f825f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_refresh.go @@ -0,0 +1,10 @@ +package client + +const ( + CatalogRefreshType = "catalogRefresh" + CatalogRefreshFieldCatalogs = "catalogs" +) + +type CatalogRefresh struct { + Catalogs []string `json:"catalogs,omitempty" yaml:"catalogs,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_secrets.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_secrets.go new file mode 100644 index 0000000..d89c146 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_secrets.go @@ -0,0 +1,10 @@ +package client + +const ( + CatalogSecretsType = "catalogSecrets" + CatalogSecretsFieldCredentialSecret = "credentialSecret" +) + +type CatalogSecrets struct { + CredentialSecret string `json:"credentialSecret,omitempty" yaml:"credentialSecret,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_spec.go new file mode 100644 index 0000000..0eb5c87 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_spec.go @@ -0,0 +1,24 @@ +package client + +const ( + CatalogSpecType = "catalogSpec" + CatalogSpecFieldBranch = "branch" + CatalogSpecFieldCatalogKind = "catalogKind" + CatalogSpecFieldCatalogSecrets = "catalogSecrets" + CatalogSpecFieldDescription = "description" + CatalogSpecFieldHelmVersion = "helmVersion" + CatalogSpecFieldPassword = "password" + CatalogSpecFieldURL = "url" + CatalogSpecFieldUsername = "username" +) + +type CatalogSpec struct { + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + CatalogKind string `json:"catalogKind,omitempty" yaml:"catalogKind,omitempty"` + CatalogSecrets *CatalogSecrets `json:"catalogSecrets,omitempty" yaml:"catalogSecrets,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_status.go new file mode 100644 index 0000000..624f143 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_status.go @@ -0,0 +1,18 @@ +package client + +const ( + CatalogStatusType = "catalogStatus" + CatalogStatusFieldCommit = "commit" + CatalogStatusFieldConditions = "conditions" + CatalogStatusFieldCredentialSecret = "credentialSecret" + CatalogStatusFieldHelmVersionCommits = "helmVersionCommits" + CatalogStatusFieldLastRefreshTimestamp = "lastRefreshTimestamp" +) + +type CatalogStatus struct { + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` + Conditions []CatalogCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CredentialSecret string `json:"credentialSecret,omitempty" yaml:"credentialSecret,omitempty"` + HelmVersionCommits map[string]VersionCommits `json:"helmVersionCommits,omitempty" yaml:"helmVersionCommits,omitempty"` + LastRefreshTimestamp string `json:"lastRefreshTimestamp,omitempty" yaml:"lastRefreshTimestamp,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template.go new file mode 100644 index 0000000..bc609f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template.go @@ -0,0 +1,166 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CatalogTemplateType = "catalogTemplate" + CatalogTemplateFieldAnnotations = "annotations" + CatalogTemplateFieldCatalogID = "catalogId" + CatalogTemplateFieldCategories = "categories" + CatalogTemplateFieldCategory = "category" + CatalogTemplateFieldClusterCatalogID = "clusterCatalogId" + CatalogTemplateFieldClusterID = "clusterId" + CatalogTemplateFieldCreated = "created" + CatalogTemplateFieldCreatorID = "creatorId" + CatalogTemplateFieldDefaultTemplateVersionID = "defaultTemplateVersionId" + CatalogTemplateFieldDefaultVersion = "defaultVersion" + CatalogTemplateFieldDescription = "description" + CatalogTemplateFieldFolderName = "folderName" + CatalogTemplateFieldIcon = "icon" + CatalogTemplateFieldIconFilename = "iconFilename" + CatalogTemplateFieldLabels = "labels" + CatalogTemplateFieldMaintainer = "maintainer" + CatalogTemplateFieldName = "name" + CatalogTemplateFieldOwnerReferences = "ownerReferences" + CatalogTemplateFieldPath = "path" + CatalogTemplateFieldProjectCatalogID = "projectCatalogId" + CatalogTemplateFieldProjectID = "projectId" + CatalogTemplateFieldProjectURL = "projectURL" + CatalogTemplateFieldReadme = "readme" + CatalogTemplateFieldRemoved = "removed" + CatalogTemplateFieldState = "state" + CatalogTemplateFieldStatus = "status" + CatalogTemplateFieldTransitioning = "transitioning" + CatalogTemplateFieldTransitioningMessage = "transitioningMessage" + CatalogTemplateFieldUUID = "uuid" + CatalogTemplateFieldUpgradeFrom = "upgradeFrom" + CatalogTemplateFieldVersionLinks = "versionLinks" + CatalogTemplateFieldVersions = "versions" +) + +type CatalogTemplate struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CatalogID string `json:"catalogId,omitempty" yaml:"catalogId,omitempty"` + Categories []string `json:"categories,omitempty" yaml:"categories,omitempty"` + Category string `json:"category,omitempty" yaml:"category,omitempty"` + ClusterCatalogID string `json:"clusterCatalogId,omitempty" yaml:"clusterCatalogId,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultTemplateVersionID string `json:"defaultTemplateVersionId,omitempty" yaml:"defaultTemplateVersionId,omitempty"` + DefaultVersion string `json:"defaultVersion,omitempty" yaml:"defaultVersion,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + FolderName string `json:"folderName,omitempty" yaml:"folderName,omitempty"` + Icon string `json:"icon,omitempty" yaml:"icon,omitempty"` + IconFilename string `json:"iconFilename,omitempty" yaml:"iconFilename,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Maintainer string `json:"maintainer,omitempty" yaml:"maintainer,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ProjectCatalogID string `json:"projectCatalogId,omitempty" yaml:"projectCatalogId,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + ProjectURL string `json:"projectURL,omitempty" yaml:"projectURL,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *TemplateStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UpgradeFrom string `json:"upgradeFrom,omitempty" yaml:"upgradeFrom,omitempty"` + VersionLinks map[string]string `json:"versionLinks,omitempty" yaml:"versionLinks,omitempty"` + Versions []TemplateVersionSpec `json:"versions,omitempty" yaml:"versions,omitempty"` +} + +type CatalogTemplateCollection struct { + types.Collection + Data []CatalogTemplate `json:"data,omitempty"` + client *CatalogTemplateClient +} + +type CatalogTemplateClient struct { + apiClient *Client +} + +type CatalogTemplateOperations interface { + List(opts *types.ListOpts) (*CatalogTemplateCollection, error) + ListAll(opts *types.ListOpts) (*CatalogTemplateCollection, error) + Create(opts *CatalogTemplate) (*CatalogTemplate, error) + Update(existing *CatalogTemplate, updates interface{}) (*CatalogTemplate, error) + Replace(existing *CatalogTemplate) (*CatalogTemplate, error) + ByID(id string) (*CatalogTemplate, error) + Delete(container *CatalogTemplate) error +} + +func newCatalogTemplateClient(apiClient *Client) *CatalogTemplateClient { + return &CatalogTemplateClient{ + apiClient: apiClient, + } +} + +func (c *CatalogTemplateClient) Create(container *CatalogTemplate) (*CatalogTemplate, error) { + resp := &CatalogTemplate{} + err := c.apiClient.Ops.DoCreate(CatalogTemplateType, container, resp) + return resp, err +} + +func (c *CatalogTemplateClient) Update(existing *CatalogTemplate, updates interface{}) (*CatalogTemplate, error) { + resp := &CatalogTemplate{} + err := c.apiClient.Ops.DoUpdate(CatalogTemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CatalogTemplateClient) Replace(obj *CatalogTemplate) (*CatalogTemplate, error) { + resp := &CatalogTemplate{} + err := c.apiClient.Ops.DoReplace(CatalogTemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CatalogTemplateClient) List(opts *types.ListOpts) (*CatalogTemplateCollection, error) { + resp := &CatalogTemplateCollection{} + err := c.apiClient.Ops.DoList(CatalogTemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CatalogTemplateClient) ListAll(opts *types.ListOpts) (*CatalogTemplateCollection, error) { + resp := &CatalogTemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CatalogTemplateCollection) Next() (*CatalogTemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CatalogTemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CatalogTemplateClient) ByID(id string) (*CatalogTemplate, error) { + resp := &CatalogTemplate{} + err := c.apiClient.Ops.DoByID(CatalogTemplateType, id, resp) + return resp, err +} + +func (c *CatalogTemplateClient) Delete(container *CatalogTemplate) error { + return c.apiClient.Ops.DoResourceDelete(CatalogTemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template_version.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template_version.go new file mode 100644 index 0000000..520ed18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_catalog_template_version.go @@ -0,0 +1,158 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CatalogTemplateVersionType = "catalogTemplateVersion" + CatalogTemplateVersionFieldAnnotations = "annotations" + CatalogTemplateVersionFieldAppReadme = "appReadme" + CatalogTemplateVersionFieldCreated = "created" + CatalogTemplateVersionFieldCreatorID = "creatorId" + CatalogTemplateVersionFieldDigest = "digest" + CatalogTemplateVersionFieldExternalID = "externalId" + CatalogTemplateVersionFieldFiles = "files" + CatalogTemplateVersionFieldKubeVersion = "kubeVersion" + CatalogTemplateVersionFieldLabels = "labels" + CatalogTemplateVersionFieldName = "name" + CatalogTemplateVersionFieldOwnerReferences = "ownerReferences" + CatalogTemplateVersionFieldQuestions = "questions" + CatalogTemplateVersionFieldRancherMaxVersion = "rancherMaxVersion" + CatalogTemplateVersionFieldRancherMinVersion = "rancherMinVersion" + CatalogTemplateVersionFieldRancherVersion = "rancherVersion" + CatalogTemplateVersionFieldReadme = "readme" + CatalogTemplateVersionFieldRemoved = "removed" + CatalogTemplateVersionFieldRequiredNamespace = "requiredNamespace" + CatalogTemplateVersionFieldState = "state" + CatalogTemplateVersionFieldStatus = "status" + CatalogTemplateVersionFieldTransitioning = "transitioning" + CatalogTemplateVersionFieldTransitioningMessage = "transitioningMessage" + CatalogTemplateVersionFieldUUID = "uuid" + CatalogTemplateVersionFieldUpgradeVersionLinks = "upgradeVersionLinks" + CatalogTemplateVersionFieldVersion = "version" + CatalogTemplateVersionFieldVersionDir = "versionDir" + CatalogTemplateVersionFieldVersionName = "versionName" + CatalogTemplateVersionFieldVersionURLs = "versionUrls" +) + +type CatalogTemplateVersion struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppReadme string `json:"appReadme,omitempty" yaml:"appReadme,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + KubeVersion string `json:"kubeVersion,omitempty" yaml:"kubeVersion,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + RancherMaxVersion string `json:"rancherMaxVersion,omitempty" yaml:"rancherMaxVersion,omitempty"` + RancherMinVersion string `json:"rancherMinVersion,omitempty" yaml:"rancherMinVersion,omitempty"` + RancherVersion string `json:"rancherVersion,omitempty" yaml:"rancherVersion,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RequiredNamespace string `json:"requiredNamespace,omitempty" yaml:"requiredNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *TemplateVersionStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UpgradeVersionLinks map[string]string `json:"upgradeVersionLinks,omitempty" yaml:"upgradeVersionLinks,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + VersionDir string `json:"versionDir,omitempty" yaml:"versionDir,omitempty"` + VersionName string `json:"versionName,omitempty" yaml:"versionName,omitempty"` + VersionURLs []string `json:"versionUrls,omitempty" yaml:"versionUrls,omitempty"` +} + +type CatalogTemplateVersionCollection struct { + types.Collection + Data []CatalogTemplateVersion `json:"data,omitempty"` + client *CatalogTemplateVersionClient +} + +type CatalogTemplateVersionClient struct { + apiClient *Client +} + +type CatalogTemplateVersionOperations interface { + List(opts *types.ListOpts) (*CatalogTemplateVersionCollection, error) + ListAll(opts *types.ListOpts) (*CatalogTemplateVersionCollection, error) + Create(opts *CatalogTemplateVersion) (*CatalogTemplateVersion, error) + Update(existing *CatalogTemplateVersion, updates interface{}) (*CatalogTemplateVersion, error) + Replace(existing *CatalogTemplateVersion) (*CatalogTemplateVersion, error) + ByID(id string) (*CatalogTemplateVersion, error) + Delete(container *CatalogTemplateVersion) error +} + +func newCatalogTemplateVersionClient(apiClient *Client) *CatalogTemplateVersionClient { + return &CatalogTemplateVersionClient{ + apiClient: apiClient, + } +} + +func (c *CatalogTemplateVersionClient) Create(container *CatalogTemplateVersion) (*CatalogTemplateVersion, error) { + resp := &CatalogTemplateVersion{} + err := c.apiClient.Ops.DoCreate(CatalogTemplateVersionType, container, resp) + return resp, err +} + +func (c *CatalogTemplateVersionClient) Update(existing *CatalogTemplateVersion, updates interface{}) (*CatalogTemplateVersion, error) { + resp := &CatalogTemplateVersion{} + err := c.apiClient.Ops.DoUpdate(CatalogTemplateVersionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CatalogTemplateVersionClient) Replace(obj *CatalogTemplateVersion) (*CatalogTemplateVersion, error) { + resp := &CatalogTemplateVersion{} + err := c.apiClient.Ops.DoReplace(CatalogTemplateVersionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CatalogTemplateVersionClient) List(opts *types.ListOpts) (*CatalogTemplateVersionCollection, error) { + resp := &CatalogTemplateVersionCollection{} + err := c.apiClient.Ops.DoList(CatalogTemplateVersionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CatalogTemplateVersionClient) ListAll(opts *types.ListOpts) (*CatalogTemplateVersionCollection, error) { + resp := &CatalogTemplateVersionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CatalogTemplateVersionCollection) Next() (*CatalogTemplateVersionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CatalogTemplateVersionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CatalogTemplateVersionClient) ByID(id string) (*CatalogTemplateVersion, error) { + resp := &CatalogTemplateVersion{} + err := c.apiClient.Ops.DoByID(CatalogTemplateVersionType, id, resp) + return resp, err +} + +func (c *CatalogTemplateVersionClient) Delete(container *CatalogTemplateVersion) error { + return c.apiClient.Ops.DoResourceDelete(CatalogTemplateVersionType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ceph_fsvolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ceph_fsvolume_source.go new file mode 100644 index 0000000..363ba5e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ceph_fsvolume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + CephFSVolumeSourceType = "cephFSVolumeSource" + CephFSVolumeSourceFieldMonitors = "monitors" + CephFSVolumeSourceFieldPath = "path" + CephFSVolumeSourceFieldReadOnly = "readOnly" + CephFSVolumeSourceFieldSecretFile = "secretFile" + CephFSVolumeSourceFieldSecretRef = "secretRef" + CephFSVolumeSourceFieldUser = "user" +) + +type CephFSVolumeSource struct { + Monitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretFile string `json:"secretFile,omitempty" yaml:"secretFile,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cert_expiration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cert_expiration.go new file mode 100644 index 0000000..0b05b46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cert_expiration.go @@ -0,0 +1,10 @@ +package client + +const ( + CertExpirationType = "certExpiration" + CertExpirationFieldExpirationDate = "expirationDate" +) + +type CertExpiration struct { + ExpirationDate string `json:"expirationDate,omitempty" yaml:"expirationDate,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_change_password_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_change_password_input.go new file mode 100644 index 0000000..e3a1208 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_change_password_input.go @@ -0,0 +1,12 @@ +package client + +const ( + ChangePasswordInputType = "changePasswordInput" + ChangePasswordInputFieldCurrentPassword = "currentPassword" + ChangePasswordInputFieldNewPassword = "newPassword" +) + +type ChangePasswordInput struct { + CurrentPassword string `json:"currentPassword,omitempty" yaml:"currentPassword,omitempty"` + NewPassword string `json:"newPassword,omitempty" yaml:"newPassword,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cinder_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cinder_volume_source.go new file mode 100644 index 0000000..ac0a621 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cinder_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + CinderVolumeSourceType = "cinderVolumeSource" + CinderVolumeSourceFieldFSType = "fsType" + CinderVolumeSourceFieldReadOnly = "readOnly" + CinderVolumeSourceFieldSecretRef = "secretRef" + CinderVolumeSourceFieldVolumeID = "volumeID" +) + +type CinderVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_client.go new file mode 100644 index 0000000..8ba5dc7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_client.go @@ -0,0 +1,124 @@ +package client + +import ( + "github.com/rancher/norman/clientbase" +) + +type Client struct { + clientbase.APIBaseClient + + NodePool NodePoolOperations + Node NodeOperations + NodeDriver NodeDriverOperations + NodeTemplate NodeTemplateOperations + PodSecurityAdmissionConfigurationTemplate PodSecurityAdmissionConfigurationTemplateOperations + Project ProjectOperations + GlobalRole GlobalRoleOperations + GlobalRoleBinding GlobalRoleBindingOperations + RoleTemplate RoleTemplateOperations + ClusterRoleTemplateBinding ClusterRoleTemplateBindingOperations + ProjectRoleTemplateBinding ProjectRoleTemplateBindingOperations + Cluster ClusterOperations + ClusterRegistrationToken ClusterRegistrationTokenOperations + Catalog CatalogOperations + Template TemplateOperations + CatalogTemplate CatalogTemplateOperations + CatalogTemplateVersion CatalogTemplateVersionOperations + TemplateVersion TemplateVersionOperations + TemplateContent TemplateContentOperations + Group GroupOperations + GroupMember GroupMemberOperations + SamlToken SamlTokenOperations + Principal PrincipalOperations + User UserOperations + AuthConfig AuthConfigOperations + LdapConfig LdapConfigOperations + Token TokenOperations + DynamicSchema DynamicSchemaOperations + Preference PreferenceOperations + ProjectNetworkPolicy ProjectNetworkPolicyOperations + Setting SettingOperations + Feature FeatureOperations + ComposeConfig ComposeConfigOperations + ProjectCatalog ProjectCatalogOperations + ClusterCatalog ClusterCatalogOperations + MultiClusterApp MultiClusterAppOperations + MultiClusterAppRevision MultiClusterAppRevisionOperations + GlobalDns GlobalDnsOperations + GlobalDnsProvider GlobalDnsProviderOperations + KontainerDriver KontainerDriverOperations + EtcdBackup EtcdBackupOperations + CloudCredential CloudCredentialOperations + ManagementSecret ManagementSecretOperations + ClusterTemplate ClusterTemplateOperations + ClusterTemplateRevision ClusterTemplateRevisionOperations + RkeK8sSystemImage RkeK8sSystemImageOperations + RkeK8sServiceOption RkeK8sServiceOptionOperations + RkeAddon RkeAddonOperations + FleetWorkspace FleetWorkspaceOperations + RancherUserNotification RancherUserNotificationOperations +} + +func NewClient(opts *clientbase.ClientOpts) (*Client, error) { + baseClient, err := clientbase.NewAPIClient(opts) + if err != nil { + return nil, err + } + + client := &Client{ + APIBaseClient: baseClient, + } + + client.NodePool = newNodePoolClient(client) + client.Node = newNodeClient(client) + client.NodeDriver = newNodeDriverClient(client) + client.NodeTemplate = newNodeTemplateClient(client) + client.PodSecurityAdmissionConfigurationTemplate = newPodSecurityAdmissionConfigurationTemplateClient(client) + client.Project = newProjectClient(client) + client.GlobalRole = newGlobalRoleClient(client) + client.GlobalRoleBinding = newGlobalRoleBindingClient(client) + client.RoleTemplate = newRoleTemplateClient(client) + client.ClusterRoleTemplateBinding = newClusterRoleTemplateBindingClient(client) + client.ProjectRoleTemplateBinding = newProjectRoleTemplateBindingClient(client) + client.Cluster = newClusterClient(client) + client.ClusterRegistrationToken = newClusterRegistrationTokenClient(client) + client.Catalog = newCatalogClient(client) + client.Template = newTemplateClient(client) + client.CatalogTemplate = newCatalogTemplateClient(client) + client.CatalogTemplateVersion = newCatalogTemplateVersionClient(client) + client.TemplateVersion = newTemplateVersionClient(client) + client.TemplateContent = newTemplateContentClient(client) + client.Group = newGroupClient(client) + client.GroupMember = newGroupMemberClient(client) + client.SamlToken = newSamlTokenClient(client) + client.Principal = newPrincipalClient(client) + client.User = newUserClient(client) + client.AuthConfig = newAuthConfigClient(client) + client.LdapConfig = newLdapConfigClient(client) + client.Token = newTokenClient(client) + client.DynamicSchema = newDynamicSchemaClient(client) + client.Preference = newPreferenceClient(client) + client.ProjectNetworkPolicy = newProjectNetworkPolicyClient(client) + client.Setting = newSettingClient(client) + client.Feature = newFeatureClient(client) + client.ComposeConfig = newComposeConfigClient(client) + client.ProjectCatalog = newProjectCatalogClient(client) + client.ClusterCatalog = newClusterCatalogClient(client) + client.MultiClusterApp = newMultiClusterAppClient(client) + client.MultiClusterAppRevision = newMultiClusterAppRevisionClient(client) + client.GlobalDns = newGlobalDnsClient(client) + client.GlobalDnsProvider = newGlobalDnsProviderClient(client) + client.KontainerDriver = newKontainerDriverClient(client) + client.EtcdBackup = newEtcdBackupClient(client) + client.CloudCredential = newCloudCredentialClient(client) + client.ManagementSecret = newManagementSecretClient(client) + client.ClusterTemplate = newClusterTemplateClient(client) + client.ClusterTemplateRevision = newClusterTemplateRevisionClient(client) + client.RkeK8sSystemImage = newRkeK8sSystemImageClient(client) + client.RkeK8sServiceOption = newRkeK8sServiceOptionClient(client) + client.RkeAddon = newRkeAddonClient(client) + client.FleetWorkspace = newFleetWorkspaceClient(client) + client.RancherUserNotification = newRancherUserNotificationClient(client) + + return client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential.go new file mode 100644 index 0000000..9381da3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CloudCredentialType = "cloudCredential" + CloudCredentialFieldAnnotations = "annotations" + CloudCredentialFieldCreated = "created" + CloudCredentialFieldCreatorID = "creatorId" + CloudCredentialFieldDescription = "description" + CloudCredentialFieldLabels = "labels" + CloudCredentialFieldName = "name" + CloudCredentialFieldOwnerReferences = "ownerReferences" + CloudCredentialFieldRemoved = "removed" + CloudCredentialFieldS3CredentialConfig = "s3credentialConfig" + CloudCredentialFieldUUID = "uuid" +) + +type CloudCredential struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + S3CredentialConfig *S3CredentialConfig `json:"s3credentialConfig,omitempty" yaml:"s3credentialConfig,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type CloudCredentialCollection struct { + types.Collection + Data []CloudCredential `json:"data,omitempty"` + client *CloudCredentialClient +} + +type CloudCredentialClient struct { + apiClient *Client +} + +type CloudCredentialOperations interface { + List(opts *types.ListOpts) (*CloudCredentialCollection, error) + ListAll(opts *types.ListOpts) (*CloudCredentialCollection, error) + Create(opts *CloudCredential) (*CloudCredential, error) + Update(existing *CloudCredential, updates interface{}) (*CloudCredential, error) + Replace(existing *CloudCredential) (*CloudCredential, error) + ByID(id string) (*CloudCredential, error) + Delete(container *CloudCredential) error +} + +func newCloudCredentialClient(apiClient *Client) *CloudCredentialClient { + return &CloudCredentialClient{ + apiClient: apiClient, + } +} + +func (c *CloudCredentialClient) Create(container *CloudCredential) (*CloudCredential, error) { + resp := &CloudCredential{} + err := c.apiClient.Ops.DoCreate(CloudCredentialType, container, resp) + return resp, err +} + +func (c *CloudCredentialClient) Update(existing *CloudCredential, updates interface{}) (*CloudCredential, error) { + resp := &CloudCredential{} + err := c.apiClient.Ops.DoUpdate(CloudCredentialType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CloudCredentialClient) Replace(obj *CloudCredential) (*CloudCredential, error) { + resp := &CloudCredential{} + err := c.apiClient.Ops.DoReplace(CloudCredentialType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CloudCredentialClient) List(opts *types.ListOpts) (*CloudCredentialCollection, error) { + resp := &CloudCredentialCollection{} + err := c.apiClient.Ops.DoList(CloudCredentialType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CloudCredentialClient) ListAll(opts *types.ListOpts) (*CloudCredentialCollection, error) { + resp := &CloudCredentialCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CloudCredentialCollection) Next() (*CloudCredentialCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CloudCredentialCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CloudCredentialClient) ByID(id string) (*CloudCredential, error) { + resp := &CloudCredential{} + err := c.apiClient.Ops.DoByID(CloudCredentialType, id, resp) + return resp, err +} + +func (c *CloudCredentialClient) Delete(container *CloudCredential) error { + return c.apiClient.Ops.DoResourceDelete(CloudCredentialType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential_spec.go new file mode 100644 index 0000000..c726919 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_credential_spec.go @@ -0,0 +1,14 @@ +package client + +const ( + CloudCredentialSpecType = "cloudCredentialSpec" + CloudCredentialSpecFieldDescription = "description" + CloudCredentialSpecFieldDisplayName = "displayName" + CloudCredentialSpecFieldS3CredentialConfig = "s3credentialConfig" +) + +type CloudCredentialSpec struct { + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + S3CredentialConfig *S3CredentialConfig `json:"s3credentialConfig,omitempty" yaml:"s3credentialConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_provider.go new file mode 100644 index 0000000..6300e6f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloud_provider.go @@ -0,0 +1,24 @@ +package client + +const ( + CloudProviderType = "cloudProvider" + CloudProviderFieldAWSCloudProvider = "awsCloudProvider" + CloudProviderFieldAzureCloudProvider = "azureCloudProvider" + CloudProviderFieldCustomCloudProvider = "customCloudProvider" + CloudProviderFieldHarvesterCloudProvider = "harvesterCloudProvider" + CloudProviderFieldName = "name" + CloudProviderFieldOpenstackCloudProvider = "openstackCloudProvider" + CloudProviderFieldUseInstanceMetadataHostname = "useInstanceMetadataHostname" + CloudProviderFieldVsphereCloudProvider = "vsphereCloudProvider" +) + +type CloudProvider struct { + AWSCloudProvider *AWSCloudProvider `json:"awsCloudProvider,omitempty" yaml:"awsCloudProvider,omitempty"` + AzureCloudProvider *AzureCloudProvider `json:"azureCloudProvider,omitempty" yaml:"azureCloudProvider,omitempty"` + CustomCloudProvider string `json:"customCloudProvider,omitempty" yaml:"customCloudProvider,omitempty"` + HarvesterCloudProvider *HarvesterCloudProvider `json:"harvesterCloudProvider,omitempty" yaml:"harvesterCloudProvider,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OpenstackCloudProvider *OpenstackCloudProvider `json:"openstackCloudProvider,omitempty" yaml:"openstackCloudProvider,omitempty"` + UseInstanceMetadataHostname *bool `json:"useInstanceMetadataHostname,omitempty" yaml:"useInstanceMetadataHostname,omitempty"` + VsphereCloudProvider *VsphereCloudProvider `json:"vsphereCloudProvider,omitempty" yaml:"vsphereCloudProvider,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloudflare_provider_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloudflare_provider_config.go new file mode 100644 index 0000000..98ed972 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cloudflare_provider_config.go @@ -0,0 +1,16 @@ +package client + +const ( + CloudflareProviderConfigType = "cloudflareProviderConfig" + CloudflareProviderConfigFieldAPIEmail = "apiEmail" + CloudflareProviderConfigFieldAPIKey = "apiKey" + CloudflareProviderConfigFieldAdditionalOptions = "additionalOptions" + CloudflareProviderConfigFieldProxySetting = "proxySetting" +) + +type CloudflareProviderConfig struct { + APIEmail string `json:"apiEmail,omitempty" yaml:"apiEmail,omitempty"` + APIKey string `json:"apiKey,omitempty" yaml:"apiKey,omitempty"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty" yaml:"additionalOptions,omitempty"` + ProxySetting *bool `json:"proxySetting,omitempty" yaml:"proxySetting,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster.go new file mode 100644 index 0000000..8fd8864 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster.go @@ -0,0 +1,318 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterType = "cluster" + ClusterFieldAADClientCertSecret = "aadClientCertSecret" + ClusterFieldAADClientSecret = "aadClientSecret" + ClusterFieldAKSConfig = "aksConfig" + ClusterFieldAKSStatus = "aksStatus" + ClusterFieldAPIEndpoint = "apiEndpoint" + ClusterFieldAgentEnvVars = "agentEnvVars" + ClusterFieldAgentFeatures = "agentFeatures" + ClusterFieldAgentImage = "agentImage" + ClusterFieldAgentImageOverride = "agentImageOverride" + ClusterFieldAllocatable = "allocatable" + ClusterFieldAnnotations = "annotations" + ClusterFieldAppliedAgentEnvVars = "appliedAgentEnvVars" + ClusterFieldAppliedClusterAgentDeploymentCustomization = "appliedClusterAgentDeploymentCustomization" + ClusterFieldAppliedEnableNetworkPolicy = "appliedEnableNetworkPolicy" + ClusterFieldAppliedSpec = "appliedSpec" + ClusterFieldAuthImage = "authImage" + ClusterFieldCACert = "caCert" + ClusterFieldCapabilities = "capabilities" + ClusterFieldCapacity = "capacity" + ClusterFieldCertificatesExpiration = "certificatesExpiration" + ClusterFieldClusterAgentDeploymentCustomization = "clusterAgentDeploymentCustomization" + ClusterFieldClusterSecrets = "clusterSecrets" + ClusterFieldClusterTemplateAnswers = "answers" + ClusterFieldClusterTemplateID = "clusterTemplateId" + ClusterFieldClusterTemplateQuestions = "questions" + ClusterFieldClusterTemplateRevisionID = "clusterTemplateRevisionId" + ClusterFieldComponentStatuses = "componentStatuses" + ClusterFieldConditions = "conditions" + ClusterFieldCreated = "created" + ClusterFieldCreatorID = "creatorId" + ClusterFieldCurrentCisRunName = "currentCisRunName" + ClusterFieldDefaultClusterRoleForProjectMembers = "defaultClusterRoleForProjectMembers" + ClusterFieldDefaultPodSecurityAdmissionConfigurationTemplateName = "defaultPodSecurityAdmissionConfigurationTemplateName" + ClusterFieldDescription = "description" + ClusterFieldDesiredAgentImage = "desiredAgentImage" + ClusterFieldDesiredAuthImage = "desiredAuthImage" + ClusterFieldDockerRootDir = "dockerRootDir" + ClusterFieldDriver = "driver" + ClusterFieldEKSConfig = "eksConfig" + ClusterFieldEKSStatus = "eksStatus" + ClusterFieldEnableNetworkPolicy = "enableNetworkPolicy" + ClusterFieldFailedSpec = "failedSpec" + ClusterFieldFleetAgentDeploymentCustomization = "fleetAgentDeploymentCustomization" + ClusterFieldFleetWorkspaceName = "fleetWorkspaceName" + ClusterFieldGKEConfig = "gkeConfig" + ClusterFieldGKEStatus = "gkeStatus" + ClusterFieldImportedConfig = "importedConfig" + ClusterFieldInternal = "internal" + ClusterFieldIstioEnabled = "istioEnabled" + ClusterFieldK3sConfig = "k3sConfig" + ClusterFieldLabels = "labels" + ClusterFieldLimits = "limits" + ClusterFieldLinuxWorkerCount = "linuxWorkerCount" + ClusterFieldLocalClusterAuthEndpoint = "localClusterAuthEndpoint" + ClusterFieldName = "name" + ClusterFieldNodeCount = "nodeCount" + ClusterFieldNodeVersion = "nodeVersion" + ClusterFieldOpenStackSecret = "openStackSecret" + ClusterFieldOwnerReferences = "ownerReferences" + ClusterFieldPrivateRegistrySecret = "privateRegistrySecret" + ClusterFieldProvider = "provider" + ClusterFieldRancherKubernetesEngineConfig = "rancherKubernetesEngineConfig" + ClusterFieldRemoved = "removed" + ClusterFieldRequested = "requested" + ClusterFieldRke2Config = "rke2Config" + ClusterFieldS3CredentialSecret = "s3CredentialSecret" + ClusterFieldServiceAccountTokenSecret = "serviceAccountTokenSecret" + ClusterFieldState = "state" + ClusterFieldTransitioning = "transitioning" + ClusterFieldTransitioningMessage = "transitioningMessage" + ClusterFieldUUID = "uuid" + ClusterFieldVersion = "version" + ClusterFieldVirtualCenterSecret = "virtualCenterSecret" + ClusterFieldVsphereSecret = "vsphereSecret" + ClusterFieldWeavePasswordSecret = "weavePasswordSecret" + ClusterFieldWindowsPreferedCluster = "windowsPreferedCluster" + ClusterFieldWindowsWorkerCount = "windowsWorkerCount" +) + +type Cluster struct { + types.Resource + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" yaml:"aadClientCertSecret,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + AKSConfig *AKSClusterConfigSpec `json:"aksConfig,omitempty" yaml:"aksConfig,omitempty"` + AKSStatus *AKSStatus `json:"aksStatus,omitempty" yaml:"aksStatus,omitempty"` + APIEndpoint string `json:"apiEndpoint,omitempty" yaml:"apiEndpoint,omitempty"` + AgentEnvVars []EnvVar `json:"agentEnvVars,omitempty" yaml:"agentEnvVars,omitempty"` + AgentFeatures map[string]bool `json:"agentFeatures,omitempty" yaml:"agentFeatures,omitempty"` + AgentImage string `json:"agentImage,omitempty" yaml:"agentImage,omitempty"` + AgentImageOverride string `json:"agentImageOverride,omitempty" yaml:"agentImageOverride,omitempty"` + Allocatable map[string]string `json:"allocatable,omitempty" yaml:"allocatable,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppliedAgentEnvVars []EnvVar `json:"appliedAgentEnvVars,omitempty" yaml:"appliedAgentEnvVars,omitempty"` + AppliedClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"appliedClusterAgentDeploymentCustomization,omitempty" yaml:"appliedClusterAgentDeploymentCustomization,omitempty"` + AppliedEnableNetworkPolicy bool `json:"appliedEnableNetworkPolicy,omitempty" yaml:"appliedEnableNetworkPolicy,omitempty"` + AppliedSpec *ClusterSpec `json:"appliedSpec,omitempty" yaml:"appliedSpec,omitempty"` + AuthImage string `json:"authImage,omitempty" yaml:"authImage,omitempty"` + CACert string `json:"caCert,omitempty" yaml:"caCert,omitempty"` + Capabilities *Capabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + CertificatesExpiration map[string]CertExpiration `json:"certificatesExpiration,omitempty" yaml:"certificatesExpiration,omitempty"` + ClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"clusterAgentDeploymentCustomization,omitempty" yaml:"clusterAgentDeploymentCustomization,omitempty"` + ClusterSecrets *ClusterSecrets `json:"clusterSecrets,omitempty" yaml:"clusterSecrets,omitempty"` + ClusterTemplateAnswers *Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + ClusterTemplateID string `json:"clusterTemplateId,omitempty" yaml:"clusterTemplateId,omitempty"` + ClusterTemplateQuestions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + ClusterTemplateRevisionID string `json:"clusterTemplateRevisionId,omitempty" yaml:"clusterTemplateRevisionId,omitempty"` + ComponentStatuses []ClusterComponentStatus `json:"componentStatuses,omitempty" yaml:"componentStatuses,omitempty"` + Conditions []ClusterCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CurrentCisRunName string `json:"currentCisRunName,omitempty" yaml:"currentCisRunName,omitempty"` + DefaultClusterRoleForProjectMembers string `json:"defaultClusterRoleForProjectMembers,omitempty" yaml:"defaultClusterRoleForProjectMembers,omitempty"` + DefaultPodSecurityAdmissionConfigurationTemplateName string `json:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty" yaml:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DesiredAgentImage string `json:"desiredAgentImage,omitempty" yaml:"desiredAgentImage,omitempty"` + DesiredAuthImage string `json:"desiredAuthImage,omitempty" yaml:"desiredAuthImage,omitempty"` + DockerRootDir string `json:"dockerRootDir,omitempty" yaml:"dockerRootDir,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + EKSConfig *EKSClusterConfigSpec `json:"eksConfig,omitempty" yaml:"eksConfig,omitempty"` + EKSStatus *EKSStatus `json:"eksStatus,omitempty" yaml:"eksStatus,omitempty"` + EnableNetworkPolicy *bool `json:"enableNetworkPolicy,omitempty" yaml:"enableNetworkPolicy,omitempty"` + FailedSpec *ClusterSpec `json:"failedSpec,omitempty" yaml:"failedSpec,omitempty"` + FleetAgentDeploymentCustomization *AgentDeploymentCustomization `json:"fleetAgentDeploymentCustomization,omitempty" yaml:"fleetAgentDeploymentCustomization,omitempty"` + FleetWorkspaceName string `json:"fleetWorkspaceName,omitempty" yaml:"fleetWorkspaceName,omitempty"` + GKEConfig *GKEClusterConfigSpec `json:"gkeConfig,omitempty" yaml:"gkeConfig,omitempty"` + GKEStatus *GKEStatus `json:"gkeStatus,omitempty" yaml:"gkeStatus,omitempty"` + ImportedConfig *ImportedConfig `json:"importedConfig,omitempty" yaml:"importedConfig,omitempty"` + Internal bool `json:"internal,omitempty" yaml:"internal,omitempty"` + IstioEnabled bool `json:"istioEnabled,omitempty" yaml:"istioEnabled,omitempty"` + K3sConfig *K3sConfig `json:"k3sConfig,omitempty" yaml:"k3sConfig,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + LinuxWorkerCount int64 `json:"linuxWorkerCount,omitempty" yaml:"linuxWorkerCount,omitempty"` + LocalClusterAuthEndpoint *LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint,omitempty" yaml:"localClusterAuthEndpoint,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NodeCount int64 `json:"nodeCount,omitempty" yaml:"nodeCount,omitempty"` + NodeVersion int64 `json:"nodeVersion,omitempty" yaml:"nodeVersion,omitempty"` + OpenStackSecret string `json:"openStackSecret,omitempty" yaml:"openStackSecret,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" yaml:"privateRegistrySecret,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + RancherKubernetesEngineConfig *RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty" yaml:"rancherKubernetesEngineConfig,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Requested map[string]string `json:"requested,omitempty" yaml:"requested,omitempty"` + Rke2Config *Rke2Config `json:"rke2Config,omitempty" yaml:"rke2Config,omitempty"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" yaml:"s3CredentialSecret,omitempty"` + ServiceAccountTokenSecret string `json:"serviceAccountTokenSecret,omitempty" yaml:"serviceAccountTokenSecret,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Version *Info `json:"version,omitempty" yaml:"version,omitempty"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" yaml:"virtualCenterSecret,omitempty"` + VsphereSecret string `json:"vsphereSecret,omitempty" yaml:"vsphereSecret,omitempty"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" yaml:"weavePasswordSecret,omitempty"` + WindowsPreferedCluster bool `json:"windowsPreferedCluster,omitempty" yaml:"windowsPreferedCluster,omitempty"` + WindowsWorkerCount int64 `json:"windowsWorkerCount,omitempty" yaml:"windowsWorkerCount,omitempty"` +} + +type ClusterCollection struct { + types.Collection + Data []Cluster `json:"data,omitempty"` + client *ClusterClient +} + +type ClusterClient struct { + apiClient *Client +} + +type ClusterOperations interface { + List(opts *types.ListOpts) (*ClusterCollection, error) + ListAll(opts *types.ListOpts) (*ClusterCollection, error) + Create(opts *Cluster) (*Cluster, error) + Update(existing *Cluster, updates interface{}) (*Cluster, error) + Replace(existing *Cluster) (*Cluster, error) + ByID(id string) (*Cluster, error) + Delete(container *Cluster) error + + ActionBackupEtcd(resource *Cluster) error + + ActionExportYaml(resource *Cluster) (*ExportOutput, error) + + ActionGenerateKubeconfig(resource *Cluster) (*GenerateKubeConfigOutput, error) + + ActionImportYaml(resource *Cluster, input *ImportClusterYamlInput) (*ImportYamlOutput, error) + + ActionRestoreFromEtcdBackup(resource *Cluster, input *RestoreFromEtcdBackupInput) error + + ActionRotateCertificates(resource *Cluster, input *RotateCertificateInput) (*RotateCertificateOutput, error) + + ActionRotateEncryptionKey(resource *Cluster) (*RotateEncryptionKeyOutput, error) + + ActionSaveAsTemplate(resource *Cluster, input *SaveAsTemplateInput) (*SaveAsTemplateOutput, error) +} + +func newClusterClient(apiClient *Client) *ClusterClient { + return &ClusterClient{ + apiClient: apiClient, + } +} + +func (c *ClusterClient) Create(container *Cluster) (*Cluster, error) { + resp := &Cluster{} + err := c.apiClient.Ops.DoCreate(ClusterType, container, resp) + return resp, err +} + +func (c *ClusterClient) Update(existing *Cluster, updates interface{}) (*Cluster, error) { + resp := &Cluster{} + err := c.apiClient.Ops.DoUpdate(ClusterType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterClient) Replace(obj *Cluster) (*Cluster, error) { + resp := &Cluster{} + err := c.apiClient.Ops.DoReplace(ClusterType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterClient) List(opts *types.ListOpts) (*ClusterCollection, error) { + resp := &ClusterCollection{} + err := c.apiClient.Ops.DoList(ClusterType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterClient) ListAll(opts *types.ListOpts) (*ClusterCollection, error) { + resp := &ClusterCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterCollection) Next() (*ClusterCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterClient) ByID(id string) (*Cluster, error) { + resp := &Cluster{} + err := c.apiClient.Ops.DoByID(ClusterType, id, resp) + return resp, err +} + +func (c *ClusterClient) Delete(container *Cluster) error { + return c.apiClient.Ops.DoResourceDelete(ClusterType, &container.Resource) +} + +func (c *ClusterClient) ActionBackupEtcd(resource *Cluster) error { + err := c.apiClient.Ops.DoAction(ClusterType, "backupEtcd", &resource.Resource, nil, nil) + return err +} + +func (c *ClusterClient) ActionExportYaml(resource *Cluster) (*ExportOutput, error) { + resp := &ExportOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "exportYaml", &resource.Resource, nil, resp) + return resp, err +} + +func (c *ClusterClient) ActionGenerateKubeconfig(resource *Cluster) (*GenerateKubeConfigOutput, error) { + resp := &GenerateKubeConfigOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "generateKubeconfig", &resource.Resource, nil, resp) + return resp, err +} + +func (c *ClusterClient) ActionImportYaml(resource *Cluster, input *ImportClusterYamlInput) (*ImportYamlOutput, error) { + resp := &ImportYamlOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "importYaml", &resource.Resource, input, resp) + return resp, err +} + +func (c *ClusterClient) ActionRestoreFromEtcdBackup(resource *Cluster, input *RestoreFromEtcdBackupInput) error { + err := c.apiClient.Ops.DoAction(ClusterType, "restoreFromEtcdBackup", &resource.Resource, input, nil) + return err +} + +func (c *ClusterClient) ActionRotateCertificates(resource *Cluster, input *RotateCertificateInput) (*RotateCertificateOutput, error) { + resp := &RotateCertificateOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "rotateCertificates", &resource.Resource, input, resp) + return resp, err +} + +func (c *ClusterClient) ActionRotateEncryptionKey(resource *Cluster) (*RotateEncryptionKeyOutput, error) { + resp := &RotateEncryptionKeyOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "rotateEncryptionKey", &resource.Resource, nil, resp) + return resp, err +} + +func (c *ClusterClient) ActionSaveAsTemplate(resource *Cluster, input *SaveAsTemplateInput) (*SaveAsTemplateOutput, error) { + resp := &SaveAsTemplateOutput{} + err := c.apiClient.Ops.DoAction(ClusterType, "saveAsTemplate", &resource.Resource, input, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_catalog.go new file mode 100644 index 0000000..d555f2b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_catalog.go @@ -0,0 +1,168 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterCatalogType = "clusterCatalog" + ClusterCatalogFieldAnnotations = "annotations" + ClusterCatalogFieldBranch = "branch" + ClusterCatalogFieldCatalogSecrets = "catalogSecrets" + ClusterCatalogFieldClusterID = "clusterId" + ClusterCatalogFieldCommit = "commit" + ClusterCatalogFieldConditions = "conditions" + ClusterCatalogFieldCreated = "created" + ClusterCatalogFieldCreatorID = "creatorId" + ClusterCatalogFieldCredentialSecret = "credentialSecret" + ClusterCatalogFieldDescription = "description" + ClusterCatalogFieldHelmVersion = "helmVersion" + ClusterCatalogFieldKind = "kind" + ClusterCatalogFieldLabels = "labels" + ClusterCatalogFieldLastRefreshTimestamp = "lastRefreshTimestamp" + ClusterCatalogFieldName = "name" + ClusterCatalogFieldNamespaceId = "namespaceId" + ClusterCatalogFieldOwnerReferences = "ownerReferences" + ClusterCatalogFieldPassword = "password" + ClusterCatalogFieldRemoved = "removed" + ClusterCatalogFieldState = "state" + ClusterCatalogFieldTransitioning = "transitioning" + ClusterCatalogFieldTransitioningMessage = "transitioningMessage" + ClusterCatalogFieldURL = "url" + ClusterCatalogFieldUUID = "uuid" + ClusterCatalogFieldUsername = "username" +) + +type ClusterCatalog struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + CatalogSecrets *CatalogSecrets `json:"catalogSecrets,omitempty" yaml:"catalogSecrets,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` + Conditions []CatalogCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CredentialSecret string `json:"credentialSecret,omitempty" yaml:"credentialSecret,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastRefreshTimestamp string `json:"lastRefreshTimestamp,omitempty" yaml:"lastRefreshTimestamp,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type ClusterCatalogCollection struct { + types.Collection + Data []ClusterCatalog `json:"data,omitempty"` + client *ClusterCatalogClient +} + +type ClusterCatalogClient struct { + apiClient *Client +} + +type ClusterCatalogOperations interface { + List(opts *types.ListOpts) (*ClusterCatalogCollection, error) + ListAll(opts *types.ListOpts) (*ClusterCatalogCollection, error) + Create(opts *ClusterCatalog) (*ClusterCatalog, error) + Update(existing *ClusterCatalog, updates interface{}) (*ClusterCatalog, error) + Replace(existing *ClusterCatalog) (*ClusterCatalog, error) + ByID(id string) (*ClusterCatalog, error) + Delete(container *ClusterCatalog) error + + ActionRefresh(resource *ClusterCatalog) (*CatalogRefresh, error) + + CollectionActionRefresh(resource *ClusterCatalogCollection) (*CatalogRefresh, error) +} + +func newClusterCatalogClient(apiClient *Client) *ClusterCatalogClient { + return &ClusterCatalogClient{ + apiClient: apiClient, + } +} + +func (c *ClusterCatalogClient) Create(container *ClusterCatalog) (*ClusterCatalog, error) { + resp := &ClusterCatalog{} + err := c.apiClient.Ops.DoCreate(ClusterCatalogType, container, resp) + return resp, err +} + +func (c *ClusterCatalogClient) Update(existing *ClusterCatalog, updates interface{}) (*ClusterCatalog, error) { + resp := &ClusterCatalog{} + err := c.apiClient.Ops.DoUpdate(ClusterCatalogType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterCatalogClient) Replace(obj *ClusterCatalog) (*ClusterCatalog, error) { + resp := &ClusterCatalog{} + err := c.apiClient.Ops.DoReplace(ClusterCatalogType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterCatalogClient) List(opts *types.ListOpts) (*ClusterCatalogCollection, error) { + resp := &ClusterCatalogCollection{} + err := c.apiClient.Ops.DoList(ClusterCatalogType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterCatalogClient) ListAll(opts *types.ListOpts) (*ClusterCatalogCollection, error) { + resp := &ClusterCatalogCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterCatalogCollection) Next() (*ClusterCatalogCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterCatalogCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterCatalogClient) ByID(id string) (*ClusterCatalog, error) { + resp := &ClusterCatalog{} + err := c.apiClient.Ops.DoByID(ClusterCatalogType, id, resp) + return resp, err +} + +func (c *ClusterCatalogClient) Delete(container *ClusterCatalog) error { + return c.apiClient.Ops.DoResourceDelete(ClusterCatalogType, &container.Resource) +} + +func (c *ClusterCatalogClient) ActionRefresh(resource *ClusterCatalog) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoAction(ClusterCatalogType, "refresh", &resource.Resource, nil, resp) + return resp, err +} + +func (c *ClusterCatalogClient) CollectionActionRefresh(resource *ClusterCatalogCollection) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoCollectionAction(ClusterCatalogType, "refresh", &resource.Collection, nil, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_component_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_component_status.go new file mode 100644 index 0000000..9955ee8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_component_status.go @@ -0,0 +1,12 @@ +package client + +const ( + ClusterComponentStatusType = "clusterComponentStatus" + ClusterComponentStatusFieldConditions = "conditions" + ClusterComponentStatusFieldName = "name" +) + +type ClusterComponentStatus struct { + Conditions []ComponentCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_condition.go new file mode 100644 index 0000000..1ecf2ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ClusterConditionType = "clusterCondition" + ClusterConditionFieldLastTransitionTime = "lastTransitionTime" + ClusterConditionFieldLastUpdateTime = "lastUpdateTime" + ClusterConditionFieldMessage = "message" + ClusterConditionFieldReason = "reason" + ClusterConditionFieldStatus = "status" + ClusterConditionFieldType = "type" +) + +type ClusterCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token.go new file mode 100644 index 0000000..2b0e191 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token.go @@ -0,0 +1,144 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterRegistrationTokenType = "clusterRegistrationToken" + ClusterRegistrationTokenFieldAnnotations = "annotations" + ClusterRegistrationTokenFieldClusterID = "clusterId" + ClusterRegistrationTokenFieldCommand = "command" + ClusterRegistrationTokenFieldCreated = "created" + ClusterRegistrationTokenFieldCreatorID = "creatorId" + ClusterRegistrationTokenFieldInsecureCommand = "insecureCommand" + ClusterRegistrationTokenFieldInsecureNodeCommand = "insecureNodeCommand" + ClusterRegistrationTokenFieldInsecureWindowsNodeCommand = "insecureWindowsNodeCommand" + ClusterRegistrationTokenFieldLabels = "labels" + ClusterRegistrationTokenFieldManifestURL = "manifestUrl" + ClusterRegistrationTokenFieldName = "name" + ClusterRegistrationTokenFieldNamespaceId = "namespaceId" + ClusterRegistrationTokenFieldNodeCommand = "nodeCommand" + ClusterRegistrationTokenFieldOwnerReferences = "ownerReferences" + ClusterRegistrationTokenFieldRemoved = "removed" + ClusterRegistrationTokenFieldState = "state" + ClusterRegistrationTokenFieldToken = "token" + ClusterRegistrationTokenFieldTransitioning = "transitioning" + ClusterRegistrationTokenFieldTransitioningMessage = "transitioningMessage" + ClusterRegistrationTokenFieldUUID = "uuid" + ClusterRegistrationTokenFieldWindowsNodeCommand = "windowsNodeCommand" +) + +type ClusterRegistrationToken struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Command string `json:"command,omitempty" yaml:"command,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + InsecureCommand string `json:"insecureCommand,omitempty" yaml:"insecureCommand,omitempty"` + InsecureNodeCommand string `json:"insecureNodeCommand,omitempty" yaml:"insecureNodeCommand,omitempty"` + InsecureWindowsNodeCommand string `json:"insecureWindowsNodeCommand,omitempty" yaml:"insecureWindowsNodeCommand,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + ManifestURL string `json:"manifestUrl,omitempty" yaml:"manifestUrl,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeCommand string `json:"nodeCommand,omitempty" yaml:"nodeCommand,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WindowsNodeCommand string `json:"windowsNodeCommand,omitempty" yaml:"windowsNodeCommand,omitempty"` +} + +type ClusterRegistrationTokenCollection struct { + types.Collection + Data []ClusterRegistrationToken `json:"data,omitempty"` + client *ClusterRegistrationTokenClient +} + +type ClusterRegistrationTokenClient struct { + apiClient *Client +} + +type ClusterRegistrationTokenOperations interface { + List(opts *types.ListOpts) (*ClusterRegistrationTokenCollection, error) + ListAll(opts *types.ListOpts) (*ClusterRegistrationTokenCollection, error) + Create(opts *ClusterRegistrationToken) (*ClusterRegistrationToken, error) + Update(existing *ClusterRegistrationToken, updates interface{}) (*ClusterRegistrationToken, error) + Replace(existing *ClusterRegistrationToken) (*ClusterRegistrationToken, error) + ByID(id string) (*ClusterRegistrationToken, error) + Delete(container *ClusterRegistrationToken) error +} + +func newClusterRegistrationTokenClient(apiClient *Client) *ClusterRegistrationTokenClient { + return &ClusterRegistrationTokenClient{ + apiClient: apiClient, + } +} + +func (c *ClusterRegistrationTokenClient) Create(container *ClusterRegistrationToken) (*ClusterRegistrationToken, error) { + resp := &ClusterRegistrationToken{} + err := c.apiClient.Ops.DoCreate(ClusterRegistrationTokenType, container, resp) + return resp, err +} + +func (c *ClusterRegistrationTokenClient) Update(existing *ClusterRegistrationToken, updates interface{}) (*ClusterRegistrationToken, error) { + resp := &ClusterRegistrationToken{} + err := c.apiClient.Ops.DoUpdate(ClusterRegistrationTokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterRegistrationTokenClient) Replace(obj *ClusterRegistrationToken) (*ClusterRegistrationToken, error) { + resp := &ClusterRegistrationToken{} + err := c.apiClient.Ops.DoReplace(ClusterRegistrationTokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterRegistrationTokenClient) List(opts *types.ListOpts) (*ClusterRegistrationTokenCollection, error) { + resp := &ClusterRegistrationTokenCollection{} + err := c.apiClient.Ops.DoList(ClusterRegistrationTokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterRegistrationTokenClient) ListAll(opts *types.ListOpts) (*ClusterRegistrationTokenCollection, error) { + resp := &ClusterRegistrationTokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterRegistrationTokenCollection) Next() (*ClusterRegistrationTokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterRegistrationTokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterRegistrationTokenClient) ByID(id string) (*ClusterRegistrationToken, error) { + resp := &ClusterRegistrationToken{} + err := c.apiClient.Ops.DoByID(ClusterRegistrationTokenType, id, resp) + return resp, err +} + +func (c *ClusterRegistrationTokenClient) Delete(container *ClusterRegistrationToken) error { + return c.apiClient.Ops.DoResourceDelete(ClusterRegistrationTokenType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_spec.go new file mode 100644 index 0000000..9a0fd3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_spec.go @@ -0,0 +1,10 @@ +package client + +const ( + ClusterRegistrationTokenSpecType = "clusterRegistrationTokenSpec" + ClusterRegistrationTokenSpecFieldClusterID = "clusterId" +) + +type ClusterRegistrationTokenSpec struct { + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_status.go new file mode 100644 index 0000000..1e51b10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_registration_token_status.go @@ -0,0 +1,24 @@ +package client + +const ( + ClusterRegistrationTokenStatusType = "clusterRegistrationTokenStatus" + ClusterRegistrationTokenStatusFieldCommand = "command" + ClusterRegistrationTokenStatusFieldInsecureCommand = "insecureCommand" + ClusterRegistrationTokenStatusFieldInsecureNodeCommand = "insecureNodeCommand" + ClusterRegistrationTokenStatusFieldInsecureWindowsNodeCommand = "insecureWindowsNodeCommand" + ClusterRegistrationTokenStatusFieldManifestURL = "manifestUrl" + ClusterRegistrationTokenStatusFieldNodeCommand = "nodeCommand" + ClusterRegistrationTokenStatusFieldToken = "token" + ClusterRegistrationTokenStatusFieldWindowsNodeCommand = "windowsNodeCommand" +) + +type ClusterRegistrationTokenStatus struct { + Command string `json:"command,omitempty" yaml:"command,omitempty"` + InsecureCommand string `json:"insecureCommand,omitempty" yaml:"insecureCommand,omitempty"` + InsecureNodeCommand string `json:"insecureNodeCommand,omitempty" yaml:"insecureNodeCommand,omitempty"` + InsecureWindowsNodeCommand string `json:"insecureWindowsNodeCommand,omitempty" yaml:"insecureWindowsNodeCommand,omitempty"` + ManifestURL string `json:"manifestUrl,omitempty" yaml:"manifestUrl,omitempty"` + NodeCommand string `json:"nodeCommand,omitempty" yaml:"nodeCommand,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + WindowsNodeCommand string `json:"windowsNodeCommand,omitempty" yaml:"windowsNodeCommand,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_role_template_binding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_role_template_binding.go new file mode 100644 index 0000000..e4301c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_role_template_binding.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterRoleTemplateBindingType = "clusterRoleTemplateBinding" + ClusterRoleTemplateBindingFieldAnnotations = "annotations" + ClusterRoleTemplateBindingFieldClusterID = "clusterId" + ClusterRoleTemplateBindingFieldCreated = "created" + ClusterRoleTemplateBindingFieldCreatorID = "creatorId" + ClusterRoleTemplateBindingFieldGroupID = "groupId" + ClusterRoleTemplateBindingFieldGroupPrincipalID = "groupPrincipalId" + ClusterRoleTemplateBindingFieldLabels = "labels" + ClusterRoleTemplateBindingFieldName = "name" + ClusterRoleTemplateBindingFieldNamespaceId = "namespaceId" + ClusterRoleTemplateBindingFieldOwnerReferences = "ownerReferences" + ClusterRoleTemplateBindingFieldRemoved = "removed" + ClusterRoleTemplateBindingFieldRoleTemplateID = "roleTemplateId" + ClusterRoleTemplateBindingFieldUUID = "uuid" + ClusterRoleTemplateBindingFieldUserID = "userId" + ClusterRoleTemplateBindingFieldUserPrincipalID = "userPrincipalId" +) + +type ClusterRoleTemplateBinding struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + GroupID string `json:"groupId,omitempty" yaml:"groupId,omitempty"` + GroupPrincipalID string `json:"groupPrincipalId,omitempty" yaml:"groupPrincipalId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RoleTemplateID string `json:"roleTemplateId,omitempty" yaml:"roleTemplateId,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserID string `json:"userId,omitempty" yaml:"userId,omitempty"` + UserPrincipalID string `json:"userPrincipalId,omitempty" yaml:"userPrincipalId,omitempty"` +} + +type ClusterRoleTemplateBindingCollection struct { + types.Collection + Data []ClusterRoleTemplateBinding `json:"data,omitempty"` + client *ClusterRoleTemplateBindingClient +} + +type ClusterRoleTemplateBindingClient struct { + apiClient *Client +} + +type ClusterRoleTemplateBindingOperations interface { + List(opts *types.ListOpts) (*ClusterRoleTemplateBindingCollection, error) + ListAll(opts *types.ListOpts) (*ClusterRoleTemplateBindingCollection, error) + Create(opts *ClusterRoleTemplateBinding) (*ClusterRoleTemplateBinding, error) + Update(existing *ClusterRoleTemplateBinding, updates interface{}) (*ClusterRoleTemplateBinding, error) + Replace(existing *ClusterRoleTemplateBinding) (*ClusterRoleTemplateBinding, error) + ByID(id string) (*ClusterRoleTemplateBinding, error) + Delete(container *ClusterRoleTemplateBinding) error +} + +func newClusterRoleTemplateBindingClient(apiClient *Client) *ClusterRoleTemplateBindingClient { + return &ClusterRoleTemplateBindingClient{ + apiClient: apiClient, + } +} + +func (c *ClusterRoleTemplateBindingClient) Create(container *ClusterRoleTemplateBinding) (*ClusterRoleTemplateBinding, error) { + resp := &ClusterRoleTemplateBinding{} + err := c.apiClient.Ops.DoCreate(ClusterRoleTemplateBindingType, container, resp) + return resp, err +} + +func (c *ClusterRoleTemplateBindingClient) Update(existing *ClusterRoleTemplateBinding, updates interface{}) (*ClusterRoleTemplateBinding, error) { + resp := &ClusterRoleTemplateBinding{} + err := c.apiClient.Ops.DoUpdate(ClusterRoleTemplateBindingType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterRoleTemplateBindingClient) Replace(obj *ClusterRoleTemplateBinding) (*ClusterRoleTemplateBinding, error) { + resp := &ClusterRoleTemplateBinding{} + err := c.apiClient.Ops.DoReplace(ClusterRoleTemplateBindingType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterRoleTemplateBindingClient) List(opts *types.ListOpts) (*ClusterRoleTemplateBindingCollection, error) { + resp := &ClusterRoleTemplateBindingCollection{} + err := c.apiClient.Ops.DoList(ClusterRoleTemplateBindingType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterRoleTemplateBindingClient) ListAll(opts *types.ListOpts) (*ClusterRoleTemplateBindingCollection, error) { + resp := &ClusterRoleTemplateBindingCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterRoleTemplateBindingCollection) Next() (*ClusterRoleTemplateBindingCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterRoleTemplateBindingCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterRoleTemplateBindingClient) ByID(id string) (*ClusterRoleTemplateBinding, error) { + resp := &ClusterRoleTemplateBinding{} + err := c.apiClient.Ops.DoByID(ClusterRoleTemplateBindingType, id, resp) + return resp, err +} + +func (c *ClusterRoleTemplateBindingClient) Delete(container *ClusterRoleTemplateBinding) error { + return c.apiClient.Ops.DoResourceDelete(ClusterRoleTemplateBindingType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_secrets.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_secrets.go new file mode 100644 index 0000000..6f5cc76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_secrets.go @@ -0,0 +1,40 @@ +package client + +const ( + ClusterSecretsType = "clusterSecrets" + ClusterSecretsFieldAADClientCertSecret = "aadClientCertSecret" + ClusterSecretsFieldAADClientSecret = "aadClientSecret" + ClusterSecretsFieldACIAPICUserKeySecret = "aciAPICUserKeySecret" + ClusterSecretsFieldACIKafkaClientKeySecret = "aciKafkaClientKeySecret" + ClusterSecretsFieldACITokenSecret = "aciTokenSecret" + ClusterSecretsFieldBastionHostSSHKeySecret = "bastionHostSSHKeySecret" + ClusterSecretsFieldKubeletExtraEnvSecret = "kubeletExtraEnvSecret" + ClusterSecretsFieldOpenStackSecret = "openStackSecret" + ClusterSecretsFieldPrivateRegistryECRSecret = "privateRegistryECRSecret" + ClusterSecretsFieldPrivateRegistrySecret = "privateRegistrySecret" + ClusterSecretsFieldPrivateRegistryURL = "privateRegistryURL" + ClusterSecretsFieldS3CredentialSecret = "s3CredentialSecret" + ClusterSecretsFieldSecretsEncryptionProvidersSecret = "secretsEncryptionProvidersSecret" + ClusterSecretsFieldVirtualCenterSecret = "virtualCenterSecret" + ClusterSecretsFieldVsphereSecret = "vsphereSecret" + ClusterSecretsFieldWeavePasswordSecret = "weavePasswordSecret" +) + +type ClusterSecrets struct { + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" yaml:"aadClientCertSecret,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + ACIAPICUserKeySecret string `json:"aciAPICUserKeySecret,omitempty" yaml:"aciAPICUserKeySecret,omitempty"` + ACIKafkaClientKeySecret string `json:"aciKafkaClientKeySecret,omitempty" yaml:"aciKafkaClientKeySecret,omitempty"` + ACITokenSecret string `json:"aciTokenSecret,omitempty" yaml:"aciTokenSecret,omitempty"` + BastionHostSSHKeySecret string `json:"bastionHostSSHKeySecret,omitempty" yaml:"bastionHostSSHKeySecret,omitempty"` + KubeletExtraEnvSecret string `json:"kubeletExtraEnvSecret,omitempty" yaml:"kubeletExtraEnvSecret,omitempty"` + OpenStackSecret string `json:"openStackSecret,omitempty" yaml:"openStackSecret,omitempty"` + PrivateRegistryECRSecret string `json:"privateRegistryECRSecret,omitempty" yaml:"privateRegistryECRSecret,omitempty"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" yaml:"privateRegistrySecret,omitempty"` + PrivateRegistryURL string `json:"privateRegistryURL,omitempty" yaml:"privateRegistryURL,omitempty"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" yaml:"s3CredentialSecret,omitempty"` + SecretsEncryptionProvidersSecret string `json:"secretsEncryptionProvidersSecret,omitempty" yaml:"secretsEncryptionProvidersSecret,omitempty"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" yaml:"virtualCenterSecret,omitempty"` + VsphereSecret string `json:"vsphereSecret,omitempty" yaml:"vsphereSecret,omitempty"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" yaml:"weavePasswordSecret,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec.go new file mode 100644 index 0000000..9466453 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec.go @@ -0,0 +1,72 @@ +package client + +const ( + ClusterSpecType = "clusterSpec" + ClusterSpecFieldAKSConfig = "aksConfig" + ClusterSpecFieldAgentEnvVars = "agentEnvVars" + ClusterSpecFieldAgentImageOverride = "agentImageOverride" + ClusterSpecFieldAmazonElasticContainerServiceConfig = "amazonElasticContainerServiceConfig" + ClusterSpecFieldAzureKubernetesServiceConfig = "azureKubernetesServiceConfig" + ClusterSpecFieldClusterAgentDeploymentCustomization = "clusterAgentDeploymentCustomization" + ClusterSpecFieldClusterSecrets = "clusterSecrets" + ClusterSpecFieldClusterTemplateAnswers = "answers" + ClusterSpecFieldClusterTemplateID = "clusterTemplateId" + ClusterSpecFieldClusterTemplateQuestions = "questions" + ClusterSpecFieldClusterTemplateRevisionID = "clusterTemplateRevisionId" + ClusterSpecFieldDefaultClusterRoleForProjectMembers = "defaultClusterRoleForProjectMembers" + ClusterSpecFieldDefaultPodSecurityAdmissionConfigurationTemplateName = "defaultPodSecurityAdmissionConfigurationTemplateName" + ClusterSpecFieldDescription = "description" + ClusterSpecFieldDesiredAgentImage = "desiredAgentImage" + ClusterSpecFieldDesiredAuthImage = "desiredAuthImage" + ClusterSpecFieldDisplayName = "displayName" + ClusterSpecFieldDockerRootDir = "dockerRootDir" + ClusterSpecFieldEKSConfig = "eksConfig" + ClusterSpecFieldEnableNetworkPolicy = "enableNetworkPolicy" + ClusterSpecFieldFleetAgentDeploymentCustomization = "fleetAgentDeploymentCustomization" + ClusterSpecFieldFleetWorkspaceName = "fleetWorkspaceName" + ClusterSpecFieldGKEConfig = "gkeConfig" + ClusterSpecFieldGenericEngineConfig = "genericEngineConfig" + ClusterSpecFieldGoogleKubernetesEngineConfig = "googleKubernetesEngineConfig" + ClusterSpecFieldImportedConfig = "importedConfig" + ClusterSpecFieldInternal = "internal" + ClusterSpecFieldK3sConfig = "k3sConfig" + ClusterSpecFieldLocalClusterAuthEndpoint = "localClusterAuthEndpoint" + ClusterSpecFieldRancherKubernetesEngineConfig = "rancherKubernetesEngineConfig" + ClusterSpecFieldRke2Config = "rke2Config" + ClusterSpecFieldWindowsPreferedCluster = "windowsPreferedCluster" +) + +type ClusterSpec struct { + AKSConfig *AKSClusterConfigSpec `json:"aksConfig,omitempty" yaml:"aksConfig,omitempty"` + AgentEnvVars []EnvVar `json:"agentEnvVars,omitempty" yaml:"agentEnvVars,omitempty"` + AgentImageOverride string `json:"agentImageOverride,omitempty" yaml:"agentImageOverride,omitempty"` + AmazonElasticContainerServiceConfig map[string]interface{} `json:"amazonElasticContainerServiceConfig,omitempty" yaml:"amazonElasticContainerServiceConfig,omitempty"` + AzureKubernetesServiceConfig map[string]interface{} `json:"azureKubernetesServiceConfig,omitempty" yaml:"azureKubernetesServiceConfig,omitempty"` + ClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"clusterAgentDeploymentCustomization,omitempty" yaml:"clusterAgentDeploymentCustomization,omitempty"` + ClusterSecrets *ClusterSecrets `json:"clusterSecrets,omitempty" yaml:"clusterSecrets,omitempty"` + ClusterTemplateAnswers *Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + ClusterTemplateID string `json:"clusterTemplateId,omitempty" yaml:"clusterTemplateId,omitempty"` + ClusterTemplateQuestions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + ClusterTemplateRevisionID string `json:"clusterTemplateRevisionId,omitempty" yaml:"clusterTemplateRevisionId,omitempty"` + DefaultClusterRoleForProjectMembers string `json:"defaultClusterRoleForProjectMembers,omitempty" yaml:"defaultClusterRoleForProjectMembers,omitempty"` + DefaultPodSecurityAdmissionConfigurationTemplateName string `json:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty" yaml:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DesiredAgentImage string `json:"desiredAgentImage,omitempty" yaml:"desiredAgentImage,omitempty"` + DesiredAuthImage string `json:"desiredAuthImage,omitempty" yaml:"desiredAuthImage,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + DockerRootDir string `json:"dockerRootDir,omitempty" yaml:"dockerRootDir,omitempty"` + EKSConfig *EKSClusterConfigSpec `json:"eksConfig,omitempty" yaml:"eksConfig,omitempty"` + EnableNetworkPolicy *bool `json:"enableNetworkPolicy,omitempty" yaml:"enableNetworkPolicy,omitempty"` + FleetAgentDeploymentCustomization *AgentDeploymentCustomization `json:"fleetAgentDeploymentCustomization,omitempty" yaml:"fleetAgentDeploymentCustomization,omitempty"` + FleetWorkspaceName string `json:"fleetWorkspaceName,omitempty" yaml:"fleetWorkspaceName,omitempty"` + GKEConfig *GKEClusterConfigSpec `json:"gkeConfig,omitempty" yaml:"gkeConfig,omitempty"` + GenericEngineConfig map[string]interface{} `json:"genericEngineConfig,omitempty" yaml:"genericEngineConfig,omitempty"` + GoogleKubernetesEngineConfig map[string]interface{} `json:"googleKubernetesEngineConfig,omitempty" yaml:"googleKubernetesEngineConfig,omitempty"` + ImportedConfig *ImportedConfig `json:"importedConfig,omitempty" yaml:"importedConfig,omitempty"` + Internal bool `json:"internal,omitempty" yaml:"internal,omitempty"` + K3sConfig *K3sConfig `json:"k3sConfig,omitempty" yaml:"k3sConfig,omitempty"` + LocalClusterAuthEndpoint *LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint,omitempty" yaml:"localClusterAuthEndpoint,omitempty"` + RancherKubernetesEngineConfig *RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty" yaml:"rancherKubernetesEngineConfig,omitempty"` + Rke2Config *Rke2Config `json:"rke2Config,omitempty" yaml:"rke2Config,omitempty"` + WindowsPreferedCluster bool `json:"windowsPreferedCluster,omitempty" yaml:"windowsPreferedCluster,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec_base.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec_base.go new file mode 100644 index 0000000..d458582 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_spec_base.go @@ -0,0 +1,36 @@ +package client + +const ( + ClusterSpecBaseType = "clusterSpecBase" + ClusterSpecBaseFieldAgentEnvVars = "agentEnvVars" + ClusterSpecBaseFieldAgentImageOverride = "agentImageOverride" + ClusterSpecBaseFieldClusterAgentDeploymentCustomization = "clusterAgentDeploymentCustomization" + ClusterSpecBaseFieldClusterSecrets = "clusterSecrets" + ClusterSpecBaseFieldDefaultClusterRoleForProjectMembers = "defaultClusterRoleForProjectMembers" + ClusterSpecBaseFieldDefaultPodSecurityAdmissionConfigurationTemplateName = "defaultPodSecurityAdmissionConfigurationTemplateName" + ClusterSpecBaseFieldDesiredAgentImage = "desiredAgentImage" + ClusterSpecBaseFieldDesiredAuthImage = "desiredAuthImage" + ClusterSpecBaseFieldDockerRootDir = "dockerRootDir" + ClusterSpecBaseFieldEnableNetworkPolicy = "enableNetworkPolicy" + ClusterSpecBaseFieldFleetAgentDeploymentCustomization = "fleetAgentDeploymentCustomization" + ClusterSpecBaseFieldLocalClusterAuthEndpoint = "localClusterAuthEndpoint" + ClusterSpecBaseFieldRancherKubernetesEngineConfig = "rancherKubernetesEngineConfig" + ClusterSpecBaseFieldWindowsPreferedCluster = "windowsPreferedCluster" +) + +type ClusterSpecBase struct { + AgentEnvVars []EnvVar `json:"agentEnvVars,omitempty" yaml:"agentEnvVars,omitempty"` + AgentImageOverride string `json:"agentImageOverride,omitempty" yaml:"agentImageOverride,omitempty"` + ClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"clusterAgentDeploymentCustomization,omitempty" yaml:"clusterAgentDeploymentCustomization,omitempty"` + ClusterSecrets *ClusterSecrets `json:"clusterSecrets,omitempty" yaml:"clusterSecrets,omitempty"` + DefaultClusterRoleForProjectMembers string `json:"defaultClusterRoleForProjectMembers,omitempty" yaml:"defaultClusterRoleForProjectMembers,omitempty"` + DefaultPodSecurityAdmissionConfigurationTemplateName string `json:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty" yaml:"defaultPodSecurityAdmissionConfigurationTemplateName,omitempty"` + DesiredAgentImage string `json:"desiredAgentImage,omitempty" yaml:"desiredAgentImage,omitempty"` + DesiredAuthImage string `json:"desiredAuthImage,omitempty" yaml:"desiredAuthImage,omitempty"` + DockerRootDir string `json:"dockerRootDir,omitempty" yaml:"dockerRootDir,omitempty"` + EnableNetworkPolicy *bool `json:"enableNetworkPolicy,omitempty" yaml:"enableNetworkPolicy,omitempty"` + FleetAgentDeploymentCustomization *AgentDeploymentCustomization `json:"fleetAgentDeploymentCustomization,omitempty" yaml:"fleetAgentDeploymentCustomization,omitempty"` + LocalClusterAuthEndpoint *LocalClusterAuthEndpoint `json:"localClusterAuthEndpoint,omitempty" yaml:"localClusterAuthEndpoint,omitempty"` + RancherKubernetesEngineConfig *RancherKubernetesEngineConfig `json:"rancherKubernetesEngineConfig,omitempty" yaml:"rancherKubernetesEngineConfig,omitempty"` + WindowsPreferedCluster bool `json:"windowsPreferedCluster,omitempty" yaml:"windowsPreferedCluster,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_status.go new file mode 100644 index 0000000..25b838b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_status.go @@ -0,0 +1,86 @@ +package client + +const ( + ClusterStatusType = "clusterStatus" + ClusterStatusFieldAADClientCertSecret = "aadClientCertSecret" + ClusterStatusFieldAADClientSecret = "aadClientSecret" + ClusterStatusFieldAKSStatus = "aksStatus" + ClusterStatusFieldAPIEndpoint = "apiEndpoint" + ClusterStatusFieldAgentFeatures = "agentFeatures" + ClusterStatusFieldAgentImage = "agentImage" + ClusterStatusFieldAllocatable = "allocatable" + ClusterStatusFieldAppliedAgentEnvVars = "appliedAgentEnvVars" + ClusterStatusFieldAppliedClusterAgentDeploymentCustomization = "appliedClusterAgentDeploymentCustomization" + ClusterStatusFieldAppliedEnableNetworkPolicy = "appliedEnableNetworkPolicy" + ClusterStatusFieldAppliedSpec = "appliedSpec" + ClusterStatusFieldAuthImage = "authImage" + ClusterStatusFieldCACert = "caCert" + ClusterStatusFieldCapabilities = "capabilities" + ClusterStatusFieldCapacity = "capacity" + ClusterStatusFieldCertificatesExpiration = "certificatesExpiration" + ClusterStatusFieldComponentStatuses = "componentStatuses" + ClusterStatusFieldConditions = "conditions" + ClusterStatusFieldCurrentCisRunName = "currentCisRunName" + ClusterStatusFieldDriver = "driver" + ClusterStatusFieldEKSStatus = "eksStatus" + ClusterStatusFieldFailedSpec = "failedSpec" + ClusterStatusFieldGKEStatus = "gkeStatus" + ClusterStatusFieldIstioEnabled = "istioEnabled" + ClusterStatusFieldLimits = "limits" + ClusterStatusFieldLinuxWorkerCount = "linuxWorkerCount" + ClusterStatusFieldNodeCount = "nodeCount" + ClusterStatusFieldNodeVersion = "nodeVersion" + ClusterStatusFieldOpenStackSecret = "openStackSecret" + ClusterStatusFieldPrivateRegistrySecret = "privateRegistrySecret" + ClusterStatusFieldProvider = "provider" + ClusterStatusFieldRequested = "requested" + ClusterStatusFieldS3CredentialSecret = "s3CredentialSecret" + ClusterStatusFieldServiceAccountTokenSecret = "serviceAccountTokenSecret" + ClusterStatusFieldVersion = "version" + ClusterStatusFieldVirtualCenterSecret = "virtualCenterSecret" + ClusterStatusFieldVsphereSecret = "vsphereSecret" + ClusterStatusFieldWeavePasswordSecret = "weavePasswordSecret" + ClusterStatusFieldWindowsWorkerCount = "windowsWorkerCount" +) + +type ClusterStatus struct { + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" yaml:"aadClientCertSecret,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + AKSStatus *AKSStatus `json:"aksStatus,omitempty" yaml:"aksStatus,omitempty"` + APIEndpoint string `json:"apiEndpoint,omitempty" yaml:"apiEndpoint,omitempty"` + AgentFeatures map[string]bool `json:"agentFeatures,omitempty" yaml:"agentFeatures,omitempty"` + AgentImage string `json:"agentImage,omitempty" yaml:"agentImage,omitempty"` + Allocatable map[string]string `json:"allocatable,omitempty" yaml:"allocatable,omitempty"` + AppliedAgentEnvVars []EnvVar `json:"appliedAgentEnvVars,omitempty" yaml:"appliedAgentEnvVars,omitempty"` + AppliedClusterAgentDeploymentCustomization *AgentDeploymentCustomization `json:"appliedClusterAgentDeploymentCustomization,omitempty" yaml:"appliedClusterAgentDeploymentCustomization,omitempty"` + AppliedEnableNetworkPolicy bool `json:"appliedEnableNetworkPolicy,omitempty" yaml:"appliedEnableNetworkPolicy,omitempty"` + AppliedSpec *ClusterSpec `json:"appliedSpec,omitempty" yaml:"appliedSpec,omitempty"` + AuthImage string `json:"authImage,omitempty" yaml:"authImage,omitempty"` + CACert string `json:"caCert,omitempty" yaml:"caCert,omitempty"` + Capabilities *Capabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + CertificatesExpiration map[string]CertExpiration `json:"certificatesExpiration,omitempty" yaml:"certificatesExpiration,omitempty"` + ComponentStatuses []ClusterComponentStatus `json:"componentStatuses,omitempty" yaml:"componentStatuses,omitempty"` + Conditions []ClusterCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CurrentCisRunName string `json:"currentCisRunName,omitempty" yaml:"currentCisRunName,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + EKSStatus *EKSStatus `json:"eksStatus,omitempty" yaml:"eksStatus,omitempty"` + FailedSpec *ClusterSpec `json:"failedSpec,omitempty" yaml:"failedSpec,omitempty"` + GKEStatus *GKEStatus `json:"gkeStatus,omitempty" yaml:"gkeStatus,omitempty"` + IstioEnabled bool `json:"istioEnabled,omitempty" yaml:"istioEnabled,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + LinuxWorkerCount int64 `json:"linuxWorkerCount,omitempty" yaml:"linuxWorkerCount,omitempty"` + NodeCount int64 `json:"nodeCount,omitempty" yaml:"nodeCount,omitempty"` + NodeVersion int64 `json:"nodeVersion,omitempty" yaml:"nodeVersion,omitempty"` + OpenStackSecret string `json:"openStackSecret,omitempty" yaml:"openStackSecret,omitempty"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" yaml:"privateRegistrySecret,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + Requested map[string]string `json:"requested,omitempty" yaml:"requested,omitempty"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" yaml:"s3CredentialSecret,omitempty"` + ServiceAccountTokenSecret string `json:"serviceAccountTokenSecret,omitempty" yaml:"serviceAccountTokenSecret,omitempty"` + Version *Info `json:"version,omitempty" yaml:"version,omitempty"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" yaml:"virtualCenterSecret,omitempty"` + VsphereSecret string `json:"vsphereSecret,omitempty" yaml:"vsphereSecret,omitempty"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" yaml:"weavePasswordSecret,omitempty"` + WindowsWorkerCount int64 `json:"windowsWorkerCount,omitempty" yaml:"windowsWorkerCount,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template.go new file mode 100644 index 0000000..63fcdb4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template.go @@ -0,0 +1,124 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterTemplateType = "clusterTemplate" + ClusterTemplateFieldAnnotations = "annotations" + ClusterTemplateFieldCreated = "created" + ClusterTemplateFieldCreatorID = "creatorId" + ClusterTemplateFieldDefaultRevisionID = "defaultRevisionId" + ClusterTemplateFieldDescription = "description" + ClusterTemplateFieldLabels = "labels" + ClusterTemplateFieldMembers = "members" + ClusterTemplateFieldName = "name" + ClusterTemplateFieldOwnerReferences = "ownerReferences" + ClusterTemplateFieldRemoved = "removed" + ClusterTemplateFieldUUID = "uuid" +) + +type ClusterTemplate struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultRevisionID string `json:"defaultRevisionId,omitempty" yaml:"defaultRevisionId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ClusterTemplateCollection struct { + types.Collection + Data []ClusterTemplate `json:"data,omitempty"` + client *ClusterTemplateClient +} + +type ClusterTemplateClient struct { + apiClient *Client +} + +type ClusterTemplateOperations interface { + List(opts *types.ListOpts) (*ClusterTemplateCollection, error) + ListAll(opts *types.ListOpts) (*ClusterTemplateCollection, error) + Create(opts *ClusterTemplate) (*ClusterTemplate, error) + Update(existing *ClusterTemplate, updates interface{}) (*ClusterTemplate, error) + Replace(existing *ClusterTemplate) (*ClusterTemplate, error) + ByID(id string) (*ClusterTemplate, error) + Delete(container *ClusterTemplate) error +} + +func newClusterTemplateClient(apiClient *Client) *ClusterTemplateClient { + return &ClusterTemplateClient{ + apiClient: apiClient, + } +} + +func (c *ClusterTemplateClient) Create(container *ClusterTemplate) (*ClusterTemplate, error) { + resp := &ClusterTemplate{} + err := c.apiClient.Ops.DoCreate(ClusterTemplateType, container, resp) + return resp, err +} + +func (c *ClusterTemplateClient) Update(existing *ClusterTemplate, updates interface{}) (*ClusterTemplate, error) { + resp := &ClusterTemplate{} + err := c.apiClient.Ops.DoUpdate(ClusterTemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterTemplateClient) Replace(obj *ClusterTemplate) (*ClusterTemplate, error) { + resp := &ClusterTemplate{} + err := c.apiClient.Ops.DoReplace(ClusterTemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterTemplateClient) List(opts *types.ListOpts) (*ClusterTemplateCollection, error) { + resp := &ClusterTemplateCollection{} + err := c.apiClient.Ops.DoList(ClusterTemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterTemplateClient) ListAll(opts *types.ListOpts) (*ClusterTemplateCollection, error) { + resp := &ClusterTemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterTemplateCollection) Next() (*ClusterTemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterTemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterTemplateClient) ByID(id string) (*ClusterTemplate, error) { + resp := &ClusterTemplate{} + err := c.apiClient.Ops.DoByID(ClusterTemplateType, id, resp) + return resp, err +} + +func (c *ClusterTemplateClient) Delete(container *ClusterTemplate) error { + return c.apiClient.Ops.DoResourceDelete(ClusterTemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_questions_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_questions_output.go new file mode 100644 index 0000000..2de3399 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_questions_output.go @@ -0,0 +1,10 @@ +package client + +const ( + ClusterTemplateQuestionsOutputType = "clusterTemplateQuestionsOutput" + ClusterTemplateQuestionsOutputFieldQuestions = "questions" +) + +type ClusterTemplateQuestionsOutput struct { + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision.go new file mode 100644 index 0000000..6986d4e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision.go @@ -0,0 +1,186 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ClusterTemplateRevisionType = "clusterTemplateRevision" + ClusterTemplateRevisionFieldAADClientCertSecret = "aadClientCertSecret" + ClusterTemplateRevisionFieldAADClientSecret = "aadClientSecret" + ClusterTemplateRevisionFieldACIAPICUserKeySecret = "aciAPICUserKeySecret" + ClusterTemplateRevisionFieldACIKafkaClientKeySecret = "aciKafkaClientKeySecret" + ClusterTemplateRevisionFieldACITokenSecret = "aciTokenSecret" + ClusterTemplateRevisionFieldAnnotations = "annotations" + ClusterTemplateRevisionFieldBastionHostSSHKeySecret = "bastionHostSSHKeySecret" + ClusterTemplateRevisionFieldClusterConfig = "clusterConfig" + ClusterTemplateRevisionFieldClusterTemplateID = "clusterTemplateId" + ClusterTemplateRevisionFieldConditions = "conditions" + ClusterTemplateRevisionFieldCreated = "created" + ClusterTemplateRevisionFieldCreatorID = "creatorId" + ClusterTemplateRevisionFieldEnabled = "enabled" + ClusterTemplateRevisionFieldKubeletExtraEnvSecret = "kubeletExtraEnvSecret" + ClusterTemplateRevisionFieldLabels = "labels" + ClusterTemplateRevisionFieldName = "name" + ClusterTemplateRevisionFieldOpenStackSecret = "openStackSecret" + ClusterTemplateRevisionFieldOwnerReferences = "ownerReferences" + ClusterTemplateRevisionFieldPrivateRegistryECRSecret = "privateRegistryECRSecret" + ClusterTemplateRevisionFieldPrivateRegistrySecret = "privateRegistrySecret" + ClusterTemplateRevisionFieldQuestions = "questions" + ClusterTemplateRevisionFieldRemoved = "removed" + ClusterTemplateRevisionFieldS3CredentialSecret = "s3CredentialSecret" + ClusterTemplateRevisionFieldSecretsEncryptionProvidersSecret = "secretsEncryptionProvidersSecret" + ClusterTemplateRevisionFieldState = "state" + ClusterTemplateRevisionFieldTransitioning = "transitioning" + ClusterTemplateRevisionFieldTransitioningMessage = "transitioningMessage" + ClusterTemplateRevisionFieldUUID = "uuid" + ClusterTemplateRevisionFieldVirtualCenterSecret = "virtualCenterSecret" + ClusterTemplateRevisionFieldVsphereSecret = "vsphereSecret" + ClusterTemplateRevisionFieldWeavePasswordSecret = "weavePasswordSecret" +) + +type ClusterTemplateRevision struct { + types.Resource + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" yaml:"aadClientCertSecret,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + ACIAPICUserKeySecret string `json:"aciAPICUserKeySecret,omitempty" yaml:"aciAPICUserKeySecret,omitempty"` + ACIKafkaClientKeySecret string `json:"aciKafkaClientKeySecret,omitempty" yaml:"aciKafkaClientKeySecret,omitempty"` + ACITokenSecret string `json:"aciTokenSecret,omitempty" yaml:"aciTokenSecret,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + BastionHostSSHKeySecret string `json:"bastionHostSSHKeySecret,omitempty" yaml:"bastionHostSSHKeySecret,omitempty"` + ClusterConfig *ClusterSpecBase `json:"clusterConfig,omitempty" yaml:"clusterConfig,omitempty"` + ClusterTemplateID string `json:"clusterTemplateId,omitempty" yaml:"clusterTemplateId,omitempty"` + Conditions []ClusterTemplateRevisionCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + KubeletExtraEnvSecret string `json:"kubeletExtraEnvSecret,omitempty" yaml:"kubeletExtraEnvSecret,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OpenStackSecret string `json:"openStackSecret,omitempty" yaml:"openStackSecret,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateRegistryECRSecret string `json:"privateRegistryECRSecret,omitempty" yaml:"privateRegistryECRSecret,omitempty"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" yaml:"privateRegistrySecret,omitempty"` + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" yaml:"s3CredentialSecret,omitempty"` + SecretsEncryptionProvidersSecret string `json:"secretsEncryptionProvidersSecret,omitempty" yaml:"secretsEncryptionProvidersSecret,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" yaml:"virtualCenterSecret,omitempty"` + VsphereSecret string `json:"vsphereSecret,omitempty" yaml:"vsphereSecret,omitempty"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" yaml:"weavePasswordSecret,omitempty"` +} + +type ClusterTemplateRevisionCollection struct { + types.Collection + Data []ClusterTemplateRevision `json:"data,omitempty"` + client *ClusterTemplateRevisionClient +} + +type ClusterTemplateRevisionClient struct { + apiClient *Client +} + +type ClusterTemplateRevisionOperations interface { + List(opts *types.ListOpts) (*ClusterTemplateRevisionCollection, error) + ListAll(opts *types.ListOpts) (*ClusterTemplateRevisionCollection, error) + Create(opts *ClusterTemplateRevision) (*ClusterTemplateRevision, error) + Update(existing *ClusterTemplateRevision, updates interface{}) (*ClusterTemplateRevision, error) + Replace(existing *ClusterTemplateRevision) (*ClusterTemplateRevision, error) + ByID(id string) (*ClusterTemplateRevision, error) + Delete(container *ClusterTemplateRevision) error + + ActionDisable(resource *ClusterTemplateRevision) error + + ActionEnable(resource *ClusterTemplateRevision) error + + CollectionActionListquestions(resource *ClusterTemplateRevisionCollection) (*ClusterTemplateQuestionsOutput, error) +} + +func newClusterTemplateRevisionClient(apiClient *Client) *ClusterTemplateRevisionClient { + return &ClusterTemplateRevisionClient{ + apiClient: apiClient, + } +} + +func (c *ClusterTemplateRevisionClient) Create(container *ClusterTemplateRevision) (*ClusterTemplateRevision, error) { + resp := &ClusterTemplateRevision{} + err := c.apiClient.Ops.DoCreate(ClusterTemplateRevisionType, container, resp) + return resp, err +} + +func (c *ClusterTemplateRevisionClient) Update(existing *ClusterTemplateRevision, updates interface{}) (*ClusterTemplateRevision, error) { + resp := &ClusterTemplateRevision{} + err := c.apiClient.Ops.DoUpdate(ClusterTemplateRevisionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ClusterTemplateRevisionClient) Replace(obj *ClusterTemplateRevision) (*ClusterTemplateRevision, error) { + resp := &ClusterTemplateRevision{} + err := c.apiClient.Ops.DoReplace(ClusterTemplateRevisionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ClusterTemplateRevisionClient) List(opts *types.ListOpts) (*ClusterTemplateRevisionCollection, error) { + resp := &ClusterTemplateRevisionCollection{} + err := c.apiClient.Ops.DoList(ClusterTemplateRevisionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ClusterTemplateRevisionClient) ListAll(opts *types.ListOpts) (*ClusterTemplateRevisionCollection, error) { + resp := &ClusterTemplateRevisionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ClusterTemplateRevisionCollection) Next() (*ClusterTemplateRevisionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ClusterTemplateRevisionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ClusterTemplateRevisionClient) ByID(id string) (*ClusterTemplateRevision, error) { + resp := &ClusterTemplateRevision{} + err := c.apiClient.Ops.DoByID(ClusterTemplateRevisionType, id, resp) + return resp, err +} + +func (c *ClusterTemplateRevisionClient) Delete(container *ClusterTemplateRevision) error { + return c.apiClient.Ops.DoResourceDelete(ClusterTemplateRevisionType, &container.Resource) +} + +func (c *ClusterTemplateRevisionClient) ActionDisable(resource *ClusterTemplateRevision) error { + err := c.apiClient.Ops.DoAction(ClusterTemplateRevisionType, "disable", &resource.Resource, nil, nil) + return err +} + +func (c *ClusterTemplateRevisionClient) ActionEnable(resource *ClusterTemplateRevision) error { + err := c.apiClient.Ops.DoAction(ClusterTemplateRevisionType, "enable", &resource.Resource, nil, nil) + return err +} + +func (c *ClusterTemplateRevisionClient) CollectionActionListquestions(resource *ClusterTemplateRevisionCollection) (*ClusterTemplateQuestionsOutput, error) { + resp := &ClusterTemplateQuestionsOutput{} + err := c.apiClient.Ops.DoCollectionAction(ClusterTemplateRevisionType, "listquestions", &resource.Collection, nil, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_condition.go new file mode 100644 index 0000000..114d52b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ClusterTemplateRevisionConditionType = "clusterTemplateRevisionCondition" + ClusterTemplateRevisionConditionFieldLastTransitionTime = "lastTransitionTime" + ClusterTemplateRevisionConditionFieldLastUpdateTime = "lastUpdateTime" + ClusterTemplateRevisionConditionFieldMessage = "message" + ClusterTemplateRevisionConditionFieldReason = "reason" + ClusterTemplateRevisionConditionFieldStatus = "status" + ClusterTemplateRevisionConditionFieldType = "type" +) + +type ClusterTemplateRevisionCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_spec.go new file mode 100644 index 0000000..72a46d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_spec.go @@ -0,0 +1,18 @@ +package client + +const ( + ClusterTemplateRevisionSpecType = "clusterTemplateRevisionSpec" + ClusterTemplateRevisionSpecFieldClusterConfig = "clusterConfig" + ClusterTemplateRevisionSpecFieldClusterTemplateID = "clusterTemplateId" + ClusterTemplateRevisionSpecFieldDisplayName = "displayName" + ClusterTemplateRevisionSpecFieldEnabled = "enabled" + ClusterTemplateRevisionSpecFieldQuestions = "questions" +) + +type ClusterTemplateRevisionSpec struct { + ClusterConfig *ClusterSpecBase `json:"clusterConfig,omitempty" yaml:"clusterConfig,omitempty"` + ClusterTemplateID string `json:"clusterTemplateId,omitempty" yaml:"clusterTemplateId,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_status.go new file mode 100644 index 0000000..1aa56ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_revision_status.go @@ -0,0 +1,40 @@ +package client + +const ( + ClusterTemplateRevisionStatusType = "clusterTemplateRevisionStatus" + ClusterTemplateRevisionStatusFieldAADClientCertSecret = "aadClientCertSecret" + ClusterTemplateRevisionStatusFieldAADClientSecret = "aadClientSecret" + ClusterTemplateRevisionStatusFieldACIAPICUserKeySecret = "aciAPICUserKeySecret" + ClusterTemplateRevisionStatusFieldACIKafkaClientKeySecret = "aciKafkaClientKeySecret" + ClusterTemplateRevisionStatusFieldACITokenSecret = "aciTokenSecret" + ClusterTemplateRevisionStatusFieldBastionHostSSHKeySecret = "bastionHostSSHKeySecret" + ClusterTemplateRevisionStatusFieldConditions = "conditions" + ClusterTemplateRevisionStatusFieldKubeletExtraEnvSecret = "kubeletExtraEnvSecret" + ClusterTemplateRevisionStatusFieldOpenStackSecret = "openStackSecret" + ClusterTemplateRevisionStatusFieldPrivateRegistryECRSecret = "privateRegistryECRSecret" + ClusterTemplateRevisionStatusFieldPrivateRegistrySecret = "privateRegistrySecret" + ClusterTemplateRevisionStatusFieldS3CredentialSecret = "s3CredentialSecret" + ClusterTemplateRevisionStatusFieldSecretsEncryptionProvidersSecret = "secretsEncryptionProvidersSecret" + ClusterTemplateRevisionStatusFieldVirtualCenterSecret = "virtualCenterSecret" + ClusterTemplateRevisionStatusFieldVsphereSecret = "vsphereSecret" + ClusterTemplateRevisionStatusFieldWeavePasswordSecret = "weavePasswordSecret" +) + +type ClusterTemplateRevisionStatus struct { + AADClientCertSecret string `json:"aadClientCertSecret,omitempty" yaml:"aadClientCertSecret,omitempty"` + AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty"` + ACIAPICUserKeySecret string `json:"aciAPICUserKeySecret,omitempty" yaml:"aciAPICUserKeySecret,omitempty"` + ACIKafkaClientKeySecret string `json:"aciKafkaClientKeySecret,omitempty" yaml:"aciKafkaClientKeySecret,omitempty"` + ACITokenSecret string `json:"aciTokenSecret,omitempty" yaml:"aciTokenSecret,omitempty"` + BastionHostSSHKeySecret string `json:"bastionHostSSHKeySecret,omitempty" yaml:"bastionHostSSHKeySecret,omitempty"` + Conditions []ClusterTemplateRevisionCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + KubeletExtraEnvSecret string `json:"kubeletExtraEnvSecret,omitempty" yaml:"kubeletExtraEnvSecret,omitempty"` + OpenStackSecret string `json:"openStackSecret,omitempty" yaml:"openStackSecret,omitempty"` + PrivateRegistryECRSecret string `json:"privateRegistryECRSecret,omitempty" yaml:"privateRegistryECRSecret,omitempty"` + PrivateRegistrySecret string `json:"privateRegistrySecret,omitempty" yaml:"privateRegistrySecret,omitempty"` + S3CredentialSecret string `json:"s3CredentialSecret,omitempty" yaml:"s3CredentialSecret,omitempty"` + SecretsEncryptionProvidersSecret string `json:"secretsEncryptionProvidersSecret,omitempty" yaml:"secretsEncryptionProvidersSecret,omitempty"` + VirtualCenterSecret string `json:"virtualCenterSecret,omitempty" yaml:"virtualCenterSecret,omitempty"` + VsphereSecret string `json:"vsphereSecret,omitempty" yaml:"vsphereSecret,omitempty"` + WeavePasswordSecret string `json:"weavePasswordSecret,omitempty" yaml:"weavePasswordSecret,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_spec.go new file mode 100644 index 0000000..6d0270f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_template_spec.go @@ -0,0 +1,16 @@ +package client + +const ( + ClusterTemplateSpecType = "clusterTemplateSpec" + ClusterTemplateSpecFieldDefaultRevisionID = "defaultRevisionId" + ClusterTemplateSpecFieldDescription = "description" + ClusterTemplateSpecFieldDisplayName = "displayName" + ClusterTemplateSpecFieldMembers = "members" +) + +type ClusterTemplateSpec struct { + DefaultRevisionID string `json:"defaultRevisionId,omitempty" yaml:"defaultRevisionId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_trust_bundle_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_trust_bundle_projection.go new file mode 100644 index 0000000..61d322d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_trust_bundle_projection.go @@ -0,0 +1,18 @@ +package client + +const ( + ClusterTrustBundleProjectionType = "clusterTrustBundleProjection" + ClusterTrustBundleProjectionFieldLabelSelector = "labelSelector" + ClusterTrustBundleProjectionFieldName = "name" + ClusterTrustBundleProjectionFieldOptional = "optional" + ClusterTrustBundleProjectionFieldPath = "path" + ClusterTrustBundleProjectionFieldSignerName = "signerName" +) + +type ClusterTrustBundleProjection struct { + LabelSelector *LabelSelector `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + SignerName string `json:"signerName,omitempty" yaml:"signerName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_upgrade_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_upgrade_strategy.go new file mode 100644 index 0000000..c508107 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cluster_upgrade_strategy.go @@ -0,0 +1,16 @@ +package client + +const ( + ClusterUpgradeStrategyType = "clusterUpgradeStrategy" + ClusterUpgradeStrategyFieldDrainServerNodes = "drainServerNodes" + ClusterUpgradeStrategyFieldDrainWorkerNodes = "drainWorkerNodes" + ClusterUpgradeStrategyFieldServerConcurrency = "serverConcurrency" + ClusterUpgradeStrategyFieldWorkerConcurrency = "workerConcurrency" +) + +type ClusterUpgradeStrategy struct { + DrainServerNodes bool `json:"drainServerNodes,omitempty" yaml:"drainServerNodes,omitempty"` + DrainWorkerNodes bool `json:"drainWorkerNodes,omitempty" yaml:"drainWorkerNodes,omitempty"` + ServerConcurrency int64 `json:"serverConcurrency,omitempty" yaml:"serverConcurrency,omitempty"` + WorkerConcurrency int64 `json:"workerConcurrency,omitempty" yaml:"workerConcurrency,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cmek_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cmek_config.go new file mode 100644 index 0000000..c30a658 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cmek_config.go @@ -0,0 +1,12 @@ +package client + +const ( + CMEKConfigType = "cmekConfig" + CMEKConfigFieldKeyName = "keyName" + CMEKConfigFieldRingName = "ringName" +) + +type CMEKConfig struct { + KeyName string `json:"keyName,omitempty" yaml:"keyName,omitempty"` + RingName string `json:"ringName,omitempty" yaml:"ringName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_component_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_component_condition.go new file mode 100644 index 0000000..ac23579 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_component_condition.go @@ -0,0 +1,16 @@ +package client + +const ( + ComponentConditionType = "componentCondition" + ComponentConditionFieldError = "error" + ComponentConditionFieldMessage = "message" + ComponentConditionFieldStatus = "status" + ComponentConditionFieldType = "type" +) + +type ComponentCondition struct { + Error string `json:"error,omitempty" yaml:"error,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_condition.go new file mode 100644 index 0000000..e2b5a1e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ComposeConditionType = "composeCondition" + ComposeConditionFieldLastTransitionTime = "lastTransitionTime" + ComposeConditionFieldLastUpdateTime = "lastUpdateTime" + ComposeConditionFieldMessage = "message" + ComposeConditionFieldReason = "reason" + ComposeConditionFieldStatus = "status" + ComposeConditionFieldType = "type" +) + +type ComposeCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_config.go new file mode 100644 index 0000000..7b926c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_config.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ComposeConfigType = "composeConfig" + ComposeConfigFieldAnnotations = "annotations" + ComposeConfigFieldCreated = "created" + ComposeConfigFieldCreatorID = "creatorId" + ComposeConfigFieldLabels = "labels" + ComposeConfigFieldName = "name" + ComposeConfigFieldOwnerReferences = "ownerReferences" + ComposeConfigFieldRancherCompose = "rancherCompose" + ComposeConfigFieldRemoved = "removed" + ComposeConfigFieldState = "state" + ComposeConfigFieldStatus = "status" + ComposeConfigFieldTransitioning = "transitioning" + ComposeConfigFieldTransitioningMessage = "transitioningMessage" + ComposeConfigFieldUUID = "uuid" +) + +type ComposeConfig struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherCompose string `json:"rancherCompose,omitempty" yaml:"rancherCompose,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *ComposeStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ComposeConfigCollection struct { + types.Collection + Data []ComposeConfig `json:"data,omitempty"` + client *ComposeConfigClient +} + +type ComposeConfigClient struct { + apiClient *Client +} + +type ComposeConfigOperations interface { + List(opts *types.ListOpts) (*ComposeConfigCollection, error) + ListAll(opts *types.ListOpts) (*ComposeConfigCollection, error) + Create(opts *ComposeConfig) (*ComposeConfig, error) + Update(existing *ComposeConfig, updates interface{}) (*ComposeConfig, error) + Replace(existing *ComposeConfig) (*ComposeConfig, error) + ByID(id string) (*ComposeConfig, error) + Delete(container *ComposeConfig) error +} + +func newComposeConfigClient(apiClient *Client) *ComposeConfigClient { + return &ComposeConfigClient{ + apiClient: apiClient, + } +} + +func (c *ComposeConfigClient) Create(container *ComposeConfig) (*ComposeConfig, error) { + resp := &ComposeConfig{} + err := c.apiClient.Ops.DoCreate(ComposeConfigType, container, resp) + return resp, err +} + +func (c *ComposeConfigClient) Update(existing *ComposeConfig, updates interface{}) (*ComposeConfig, error) { + resp := &ComposeConfig{} + err := c.apiClient.Ops.DoUpdate(ComposeConfigType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ComposeConfigClient) Replace(obj *ComposeConfig) (*ComposeConfig, error) { + resp := &ComposeConfig{} + err := c.apiClient.Ops.DoReplace(ComposeConfigType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ComposeConfigClient) List(opts *types.ListOpts) (*ComposeConfigCollection, error) { + resp := &ComposeConfigCollection{} + err := c.apiClient.Ops.DoList(ComposeConfigType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ComposeConfigClient) ListAll(opts *types.ListOpts) (*ComposeConfigCollection, error) { + resp := &ComposeConfigCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ComposeConfigCollection) Next() (*ComposeConfigCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ComposeConfigCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ComposeConfigClient) ByID(id string) (*ComposeConfig, error) { + resp := &ComposeConfig{} + err := c.apiClient.Ops.DoByID(ComposeConfigType, id, resp) + return resp, err +} + +func (c *ComposeConfigClient) Delete(container *ComposeConfig) error { + return c.apiClient.Ops.DoResourceDelete(ComposeConfigType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_spec.go new file mode 100644 index 0000000..6477b00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_spec.go @@ -0,0 +1,10 @@ +package client + +const ( + ComposeSpecType = "composeSpec" + ComposeSpecFieldRancherCompose = "rancherCompose" +) + +type ComposeSpec struct { + RancherCompose string `json:"rancherCompose,omitempty" yaml:"rancherCompose,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_status.go new file mode 100644 index 0000000..53138f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_compose_status.go @@ -0,0 +1,10 @@ +package client + +const ( + ComposeStatusType = "composeStatus" + ComposeStatusFieldConditions = "conditions" +) + +type ComposeStatus struct { + Conditions []ComposeCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_condition.go new file mode 100644 index 0000000..7f50204 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ConditionType = "condition" + ConditionFieldLastTransitionTime = "lastTransitionTime" + ConditionFieldLastUpdateTime = "lastUpdateTime" + ConditionFieldMessage = "message" + ConditionFieldReason = "reason" + ConditionFieldStatus = "status" + ConditionFieldType = "type" +) + +type Condition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_key_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_key_selector.go new file mode 100644 index 0000000..e1b5991 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_key_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + ConfigMapKeySelectorType = "configMapKeySelector" + ConfigMapKeySelectorFieldKey = "key" + ConfigMapKeySelectorFieldName = "name" + ConfigMapKeySelectorFieldOptional = "optional" +) + +type ConfigMapKeySelector struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_node_config_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_node_config_source.go new file mode 100644 index 0000000..1f6d090 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_node_config_source.go @@ -0,0 +1,18 @@ +package client + +const ( + ConfigMapNodeConfigSourceType = "configMapNodeConfigSource" + ConfigMapNodeConfigSourceFieldKubeletConfigKey = "kubeletConfigKey" + ConfigMapNodeConfigSourceFieldName = "name" + ConfigMapNodeConfigSourceFieldNamespace = "namespace" + ConfigMapNodeConfigSourceFieldResourceVersion = "resourceVersion" + ConfigMapNodeConfigSourceFieldUID = "uid" +) + +type ConfigMapNodeConfigSource struct { + KubeletConfigKey string `json:"kubeletConfigKey,omitempty" yaml:"kubeletConfigKey,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_projection.go new file mode 100644 index 0000000..94388a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + ConfigMapProjectionType = "configMapProjection" + ConfigMapProjectionFieldItems = "items" + ConfigMapProjectionFieldName = "name" + ConfigMapProjectionFieldOptional = "optional" +) + +type ConfigMapProjection struct { + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_volume_source.go new file mode 100644 index 0000000..4de7b8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_config_map_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + ConfigMapVolumeSourceType = "configMapVolumeSource" + ConfigMapVolumeSourceFieldDefaultMode = "defaultMode" + ConfigMapVolumeSourceFieldItems = "items" + ConfigMapVolumeSourceFieldName = "name" + ConfigMapVolumeSourceFieldOptional = "optional" +) + +type ConfigMapVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_image.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_image.go new file mode 100644 index 0000000..5f14197 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_image.go @@ -0,0 +1,12 @@ +package client + +const ( + ContainerImageType = "containerImage" + ContainerImageFieldNames = "names" + ContainerImageFieldSizeBytes = "sizeBytes" +) + +type ContainerImage struct { + Names []string `json:"names,omitempty" yaml:"names,omitempty"` + SizeBytes int64 `json:"sizeBytes,omitempty" yaml:"sizeBytes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_resource_limit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_resource_limit.go new file mode 100644 index 0000000..b36a499 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_container_resource_limit.go @@ -0,0 +1,16 @@ +package client + +const ( + ContainerResourceLimitType = "containerResourceLimit" + ContainerResourceLimitFieldLimitsCPU = "limitsCpu" + ContainerResourceLimitFieldLimitsMemory = "limitsMemory" + ContainerResourceLimitFieldRequestsCPU = "requestsCpu" + ContainerResourceLimitFieldRequestsMemory = "requestsMemory" +) + +type ContainerResourceLimit struct { + LimitsCPU string `json:"limitsCpu,omitempty" yaml:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty" yaml:"limitsMemory,omitempty"` + RequestsCPU string `json:"requestsCpu,omitempty" yaml:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty" yaml:"requestsMemory,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cpu_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cpu_info.go new file mode 100644 index 0000000..08764a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_cpu_info.go @@ -0,0 +1,10 @@ +package client + +const ( + CPUInfoType = "cpuInfo" + CPUInfoFieldCount = "count" +) + +type CPUInfo struct { + Count int64 `json:"count,omitempty" yaml:"count,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_csi_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_csi_volume_source.go new file mode 100644 index 0000000..f341d53 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_csi_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + CSIVolumeSourceType = "csiVolumeSource" + CSIVolumeSourceFieldDriver = "driver" + CSIVolumeSourceFieldFSType = "fsType" + CSIVolumeSourceFieldNodePublishSecretRef = "nodePublishSecretRef" + CSIVolumeSourceFieldReadOnly = "readOnly" + CSIVolumeSourceFieldVolumeAttributes = "volumeAttributes" +) + +type CSIVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + NodePublishSecretRef *LocalObjectReference `json:"nodePublishSecretRef,omitempty" yaml:"nodePublishSecretRef,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeAttributes map[string]string `json:"volumeAttributes,omitempty" yaml:"volumeAttributes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_custom_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_custom_config.go new file mode 100644 index 0000000..677392b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_custom_config.go @@ -0,0 +1,24 @@ +package client + +const ( + CustomConfigType = "customConfig" + CustomConfigFieldAddress = "address" + CustomConfigFieldDockerSocket = "dockerSocket" + CustomConfigFieldInternalAddress = "internalAddress" + CustomConfigFieldLabel = "label" + CustomConfigFieldSSHCert = "sshCert" + CustomConfigFieldSSHKey = "sshKey" + CustomConfigFieldTaints = "taints" + CustomConfigFieldUser = "user" +) + +type CustomConfig struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + DockerSocket string `json:"dockerSocket,omitempty" yaml:"dockerSocket,omitempty"` + InternalAddress string `json:"internalAddress,omitempty" yaml:"internalAddress,omitempty"` + Label map[string]string `json:"label,omitempty" yaml:"label,omitempty"` + SSHCert string `json:"sshCert,omitempty" yaml:"sshCert,omitempty"` + SSHKey string `json:"sshKey,omitempty" yaml:"sshKey,omitempty"` + Taints []string `json:"taints,omitempty" yaml:"taints,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_endpoint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_endpoint.go new file mode 100644 index 0000000..88cefc7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_endpoint.go @@ -0,0 +1,10 @@ +package client + +const ( + DaemonEndpointType = "daemonEndpoint" + DaemonEndpointFieldPort = "Port" +) + +type DaemonEndpoint struct { + Port int64 `json:"Port,omitempty" yaml:"Port,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_set_update_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_set_update_strategy.go new file mode 100644 index 0000000..775007e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_daemon_set_update_strategy.go @@ -0,0 +1,12 @@ +package client + +const ( + DaemonSetUpdateStrategyType = "daemonSetUpdateStrategy" + DaemonSetUpdateStrategyFieldRollingUpdate = "rollingUpdate" + DaemonSetUpdateStrategyFieldStrategy = "strategy" +) + +type DaemonSetUpdateStrategy struct { + RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty" yaml:"rollingUpdate,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_deployment_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_deployment_strategy.go new file mode 100644 index 0000000..69c4b91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_deployment_strategy.go @@ -0,0 +1,12 @@ +package client + +const ( + DeploymentStrategyType = "deploymentStrategy" + DeploymentStrategyFieldRollingUpdate = "rollingUpdate" + DeploymentStrategyFieldStrategy = "strategy" +) + +type DeploymentStrategy struct { + RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty" yaml:"rollingUpdate,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_disk_vsphere_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_disk_vsphere_opts.go new file mode 100644 index 0000000..d3db88a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_disk_vsphere_opts.go @@ -0,0 +1,10 @@ +package client + +const ( + DiskVsphereOptsType = "diskVsphereOpts" + DiskVsphereOptsFieldSCSIControllerType = "scsicontrollertype" +) + +type DiskVsphereOpts struct { + SCSIControllerType string `json:"scsicontrollertype,omitempty" yaml:"scsicontrollertype,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dns_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dns_config.go new file mode 100644 index 0000000..d7a5630 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dns_config.go @@ -0,0 +1,28 @@ +package client + +const ( + DNSConfigType = "dnsConfig" + DNSConfigFieldLinearAutoscalerParams = "linearAutoscalerParams" + DNSConfigFieldNodeSelector = "nodeSelector" + DNSConfigFieldNodelocal = "nodelocal" + DNSConfigFieldOptions = "options" + DNSConfigFieldProvider = "provider" + DNSConfigFieldReverseCIDRs = "reversecidrs" + DNSConfigFieldStubDomains = "stubdomains" + DNSConfigFieldTolerations = "tolerations" + DNSConfigFieldUpdateStrategy = "updateStrategy" + DNSConfigFieldUpstreamNameservers = "upstreamnameservers" +) + +type DNSConfig struct { + LinearAutoscalerParams *LinearAutoscalerParams `json:"linearAutoscalerParams,omitempty" yaml:"linearAutoscalerParams,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + Nodelocal *Nodelocal `json:"nodelocal,omitempty" yaml:"nodelocal,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + ReverseCIDRs []string `json:"reversecidrs,omitempty" yaml:"reversecidrs,omitempty"` + StubDomains map[string][]string `json:"stubdomains,omitempty" yaml:"stubdomains,omitempty"` + Tolerations []Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` + UpdateStrategy *DeploymentStrategy `json:"updateStrategy,omitempty" yaml:"updateStrategy,omitempty"` + UpstreamNameservers []string `json:"upstreamnameservers,omitempty" yaml:"upstreamnameservers,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_docker_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_docker_info.go new file mode 100644 index 0000000..1b66e62 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_docker_info.go @@ -0,0 +1,48 @@ +package client + +const ( + DockerInfoType = "dockerInfo" + DockerInfoFieldArchitecture = "architecture" + DockerInfoFieldCgroupDriver = "cgroupDriver" + DockerInfoFieldDebug = "debug" + DockerInfoFieldDockerRootDir = "dockerRootDir" + DockerInfoFieldDriver = "driver" + DockerInfoFieldExperimentalBuild = "experimentalBuild" + DockerInfoFieldHTTPProxy = "httpProxy" + DockerInfoFieldHTTPSProxy = "httpsProxy" + DockerInfoFieldID = "id" + DockerInfoFieldIndexServerAddress = "indexServerAddress" + DockerInfoFieldInitBinary = "initBinary" + DockerInfoFieldKernelVersion = "kernelVersion" + DockerInfoFieldLabels = "labels" + DockerInfoFieldLoggingDriver = "loggingDriver" + DockerInfoFieldName = "name" + DockerInfoFieldNoProxy = "noProxy" + DockerInfoFieldOSType = "osType" + DockerInfoFieldOperatingSystem = "operatingSystem" + DockerInfoFieldSecurityOptions = "securityOptions" + DockerInfoFieldServerVersion = "serverVersion" +) + +type DockerInfo struct { + Architecture string `json:"architecture,omitempty" yaml:"architecture,omitempty"` + CgroupDriver string `json:"cgroupDriver,omitempty" yaml:"cgroupDriver,omitempty"` + Debug bool `json:"debug,omitempty" yaml:"debug,omitempty"` + DockerRootDir string `json:"dockerRootDir,omitempty" yaml:"dockerRootDir,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + ExperimentalBuild bool `json:"experimentalBuild,omitempty" yaml:"experimentalBuild,omitempty"` + HTTPProxy string `json:"httpProxy,omitempty" yaml:"httpProxy,omitempty"` + HTTPSProxy string `json:"httpsProxy,omitempty" yaml:"httpsProxy,omitempty"` + ID string `json:"id,omitempty" yaml:"id,omitempty"` + IndexServerAddress string `json:"indexServerAddress,omitempty" yaml:"indexServerAddress,omitempty"` + InitBinary string `json:"initBinary,omitempty" yaml:"initBinary,omitempty"` + KernelVersion string `json:"kernelVersion,omitempty" yaml:"kernelVersion,omitempty"` + Labels []string `json:"labels,omitempty" yaml:"labels,omitempty"` + LoggingDriver string `json:"loggingDriver,omitempty" yaml:"loggingDriver,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NoProxy string `json:"noProxy,omitempty" yaml:"noProxy,omitempty"` + OSType string `json:"osType,omitempty" yaml:"osType,omitempty"` + OperatingSystem string `json:"operatingSystem,omitempty" yaml:"operatingSystem,omitempty"` + SecurityOptions []string `json:"securityOptions,omitempty" yaml:"securityOptions,omitempty"` + ServerVersion string `json:"serverVersion,omitempty" yaml:"serverVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apiprojection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apiprojection.go new file mode 100644 index 0000000..ca02c4d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apiprojection.go @@ -0,0 +1,10 @@ +package client + +const ( + DownwardAPIProjectionType = "downwardAPIProjection" + DownwardAPIProjectionFieldItems = "items" +) + +type DownwardAPIProjection struct { + Items []DownwardAPIVolumeFile `json:"items,omitempty" yaml:"items,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_file.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_file.go new file mode 100644 index 0000000..c8f8bc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_file.go @@ -0,0 +1,16 @@ +package client + +const ( + DownwardAPIVolumeFileType = "downwardAPIVolumeFile" + DownwardAPIVolumeFileFieldFieldRef = "fieldRef" + DownwardAPIVolumeFileFieldMode = "mode" + DownwardAPIVolumeFileFieldPath = "path" + DownwardAPIVolumeFileFieldResourceFieldRef = "resourceFieldRef" +) + +type DownwardAPIVolumeFile struct { + FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" yaml:"fieldRef,omitempty"` + Mode *int64 `json:"mode,omitempty" yaml:"mode,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" yaml:"resourceFieldRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_source.go new file mode 100644 index 0000000..f6be194 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_downward_apivolume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + DownwardAPIVolumeSourceType = "downwardAPIVolumeSource" + DownwardAPIVolumeSourceFieldDefaultMode = "defaultMode" + DownwardAPIVolumeSourceFieldItems = "items" +) + +type DownwardAPIVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []DownwardAPIVolumeFile `json:"items,omitempty" yaml:"items,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_duration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_duration.go new file mode 100644 index 0000000..cf0920c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_duration.go @@ -0,0 +1,8 @@ +package client + +const ( + DurationType = "duration" +) + +type Duration struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema.go new file mode 100644 index 0000000..080dcb4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema.go @@ -0,0 +1,152 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + DynamicSchemaType = "dynamicSchema" + DynamicSchemaFieldAnnotations = "annotations" + DynamicSchemaFieldCollectionActions = "collectionActions" + DynamicSchemaFieldCollectionFields = "collectionFields" + DynamicSchemaFieldCollectionFilters = "collectionFilters" + DynamicSchemaFieldCollectionMethods = "collectionMethods" + DynamicSchemaFieldCreated = "created" + DynamicSchemaFieldCreatorID = "creatorId" + DynamicSchemaFieldDynamicSchemaVersion = "dynamicSchemaVersion" + DynamicSchemaFieldEmbed = "embed" + DynamicSchemaFieldEmbedType = "embedType" + DynamicSchemaFieldIncludeableLinks = "includeableLinks" + DynamicSchemaFieldLabels = "labels" + DynamicSchemaFieldName = "name" + DynamicSchemaFieldOwnerReferences = "ownerReferences" + DynamicSchemaFieldPluralName = "pluralName" + DynamicSchemaFieldRemoved = "removed" + DynamicSchemaFieldResourceActions = "resourceActions" + DynamicSchemaFieldResourceFields = "resourceFields" + DynamicSchemaFieldResourceMethods = "resourceMethods" + DynamicSchemaFieldSchemaName = "schemaName" + DynamicSchemaFieldState = "state" + DynamicSchemaFieldStatus = "status" + DynamicSchemaFieldTransitioning = "transitioning" + DynamicSchemaFieldTransitioningMessage = "transitioningMessage" + DynamicSchemaFieldUUID = "uuid" +) + +type DynamicSchema struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CollectionActions map[string]Action `json:"collectionActions,omitempty" yaml:"collectionActions,omitempty"` + CollectionFields map[string]Field `json:"collectionFields,omitempty" yaml:"collectionFields,omitempty"` + CollectionFilters map[string]Filter `json:"collectionFilters,omitempty" yaml:"collectionFilters,omitempty"` + CollectionMethods []string `json:"collectionMethods,omitempty" yaml:"collectionMethods,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DynamicSchemaVersion string `json:"dynamicSchemaVersion,omitempty" yaml:"dynamicSchemaVersion,omitempty"` + Embed bool `json:"embed,omitempty" yaml:"embed,omitempty"` + EmbedType string `json:"embedType,omitempty" yaml:"embedType,omitempty"` + IncludeableLinks []string `json:"includeableLinks,omitempty" yaml:"includeableLinks,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PluralName string `json:"pluralName,omitempty" yaml:"pluralName,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceActions map[string]Action `json:"resourceActions,omitempty" yaml:"resourceActions,omitempty"` + ResourceFields map[string]Field `json:"resourceFields,omitempty" yaml:"resourceFields,omitempty"` + ResourceMethods []string `json:"resourceMethods,omitempty" yaml:"resourceMethods,omitempty"` + SchemaName string `json:"schemaName,omitempty" yaml:"schemaName,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *DynamicSchemaStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type DynamicSchemaCollection struct { + types.Collection + Data []DynamicSchema `json:"data,omitempty"` + client *DynamicSchemaClient +} + +type DynamicSchemaClient struct { + apiClient *Client +} + +type DynamicSchemaOperations interface { + List(opts *types.ListOpts) (*DynamicSchemaCollection, error) + ListAll(opts *types.ListOpts) (*DynamicSchemaCollection, error) + Create(opts *DynamicSchema) (*DynamicSchema, error) + Update(existing *DynamicSchema, updates interface{}) (*DynamicSchema, error) + Replace(existing *DynamicSchema) (*DynamicSchema, error) + ByID(id string) (*DynamicSchema, error) + Delete(container *DynamicSchema) error +} + +func newDynamicSchemaClient(apiClient *Client) *DynamicSchemaClient { + return &DynamicSchemaClient{ + apiClient: apiClient, + } +} + +func (c *DynamicSchemaClient) Create(container *DynamicSchema) (*DynamicSchema, error) { + resp := &DynamicSchema{} + err := c.apiClient.Ops.DoCreate(DynamicSchemaType, container, resp) + return resp, err +} + +func (c *DynamicSchemaClient) Update(existing *DynamicSchema, updates interface{}) (*DynamicSchema, error) { + resp := &DynamicSchema{} + err := c.apiClient.Ops.DoUpdate(DynamicSchemaType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *DynamicSchemaClient) Replace(obj *DynamicSchema) (*DynamicSchema, error) { + resp := &DynamicSchema{} + err := c.apiClient.Ops.DoReplace(DynamicSchemaType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *DynamicSchemaClient) List(opts *types.ListOpts) (*DynamicSchemaCollection, error) { + resp := &DynamicSchemaCollection{} + err := c.apiClient.Ops.DoList(DynamicSchemaType, opts, resp) + resp.client = c + return resp, err +} + +func (c *DynamicSchemaClient) ListAll(opts *types.ListOpts) (*DynamicSchemaCollection, error) { + resp := &DynamicSchemaCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *DynamicSchemaCollection) Next() (*DynamicSchemaCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &DynamicSchemaCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *DynamicSchemaClient) ByID(id string) (*DynamicSchema, error) { + resp := &DynamicSchema{} + err := c.apiClient.Ops.DoByID(DynamicSchemaType, id, resp) + return resp, err +} + +func (c *DynamicSchemaClient) Delete(container *DynamicSchema) error { + return c.apiClient.Ops.DoResourceDelete(DynamicSchemaType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_spec.go new file mode 100644 index 0000000..db9b544 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_spec.go @@ -0,0 +1,34 @@ +package client + +const ( + DynamicSchemaSpecType = "dynamicSchemaSpec" + DynamicSchemaSpecFieldCollectionActions = "collectionActions" + DynamicSchemaSpecFieldCollectionFields = "collectionFields" + DynamicSchemaSpecFieldCollectionFilters = "collectionFilters" + DynamicSchemaSpecFieldCollectionMethods = "collectionMethods" + DynamicSchemaSpecFieldDynamicSchemaVersion = "dynamicSchemaVersion" + DynamicSchemaSpecFieldEmbed = "embed" + DynamicSchemaSpecFieldEmbedType = "embedType" + DynamicSchemaSpecFieldIncludeableLinks = "includeableLinks" + DynamicSchemaSpecFieldPluralName = "pluralName" + DynamicSchemaSpecFieldResourceActions = "resourceActions" + DynamicSchemaSpecFieldResourceFields = "resourceFields" + DynamicSchemaSpecFieldResourceMethods = "resourceMethods" + DynamicSchemaSpecFieldSchemaName = "schemaName" +) + +type DynamicSchemaSpec struct { + CollectionActions map[string]Action `json:"collectionActions,omitempty" yaml:"collectionActions,omitempty"` + CollectionFields map[string]Field `json:"collectionFields,omitempty" yaml:"collectionFields,omitempty"` + CollectionFilters map[string]Filter `json:"collectionFilters,omitempty" yaml:"collectionFilters,omitempty"` + CollectionMethods []string `json:"collectionMethods,omitempty" yaml:"collectionMethods,omitempty"` + DynamicSchemaVersion string `json:"dynamicSchemaVersion,omitempty" yaml:"dynamicSchemaVersion,omitempty"` + Embed bool `json:"embed,omitempty" yaml:"embed,omitempty"` + EmbedType string `json:"embedType,omitempty" yaml:"embedType,omitempty"` + IncludeableLinks []string `json:"includeableLinks,omitempty" yaml:"includeableLinks,omitempty"` + PluralName string `json:"pluralName,omitempty" yaml:"pluralName,omitempty"` + ResourceActions map[string]Action `json:"resourceActions,omitempty" yaml:"resourceActions,omitempty"` + ResourceFields map[string]Field `json:"resourceFields,omitempty" yaml:"resourceFields,omitempty"` + ResourceMethods []string `json:"resourceMethods,omitempty" yaml:"resourceMethods,omitempty"` + SchemaName string `json:"schemaName,omitempty" yaml:"schemaName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_status.go new file mode 100644 index 0000000..014783e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_dynamic_schema_status.go @@ -0,0 +1,10 @@ +package client + +const ( + DynamicSchemaStatusType = "dynamicSchemaStatus" + DynamicSchemaStatusFieldFake = "fake" +) + +type DynamicSchemaStatus struct { + Fake string `json:"fake,omitempty" yaml:"fake,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ecr_credential_plugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ecr_credential_plugin.go new file mode 100644 index 0000000..f4e0ae4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ecr_credential_plugin.go @@ -0,0 +1,14 @@ +package client + +const ( + ECRCredentialPluginType = "ecrCredentialPlugin" + ECRCredentialPluginFieldAwsAccessKeyID = "awsAccessKeyId" + ECRCredentialPluginFieldAwsSecretAccessKey = "awsSecretAccessKey" + ECRCredentialPluginFieldAwsSessionToken = "awsAccessToken" +) + +type ECRCredentialPlugin struct { + AwsAccessKeyID string `json:"awsAccessKeyId,omitempty" yaml:"awsAccessKeyId,omitempty"` + AwsSecretAccessKey string `json:"awsSecretAccessKey,omitempty" yaml:"awsSecretAccessKey,omitempty"` + AwsSessionToken string `json:"awsAccessToken,omitempty" yaml:"awsAccessToken,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_cluster_config_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_cluster_config_spec.go new file mode 100644 index 0000000..b447110 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_cluster_config_spec.go @@ -0,0 +1,42 @@ +package client + +const ( + EKSClusterConfigSpecType = "eksClusterConfigSpec" + EKSClusterConfigSpecFieldAmazonCredentialSecret = "amazonCredentialSecret" + EKSClusterConfigSpecFieldDisplayName = "displayName" + EKSClusterConfigSpecFieldEBSCSIDriver = "ebsCSIDriver" + EKSClusterConfigSpecFieldImported = "imported" + EKSClusterConfigSpecFieldKmsKey = "kmsKey" + EKSClusterConfigSpecFieldKubernetesVersion = "kubernetesVersion" + EKSClusterConfigSpecFieldLoggingTypes = "loggingTypes" + EKSClusterConfigSpecFieldNodeGroups = "nodeGroups" + EKSClusterConfigSpecFieldPrivateAccess = "privateAccess" + EKSClusterConfigSpecFieldPublicAccess = "publicAccess" + EKSClusterConfigSpecFieldPublicAccessSources = "publicAccessSources" + EKSClusterConfigSpecFieldRegion = "region" + EKSClusterConfigSpecFieldSecretsEncryption = "secretsEncryption" + EKSClusterConfigSpecFieldSecurityGroups = "securityGroups" + EKSClusterConfigSpecFieldServiceRole = "serviceRole" + EKSClusterConfigSpecFieldSubnets = "subnets" + EKSClusterConfigSpecFieldTags = "tags" +) + +type EKSClusterConfigSpec struct { + AmazonCredentialSecret string `json:"amazonCredentialSecret,omitempty" yaml:"amazonCredentialSecret,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + EBSCSIDriver *bool `json:"ebsCSIDriver,omitempty" yaml:"ebsCSIDriver,omitempty"` + Imported bool `json:"imported,omitempty" yaml:"imported,omitempty"` + KmsKey *string `json:"kmsKey,omitempty" yaml:"kmsKey,omitempty"` + KubernetesVersion *string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` + LoggingTypes []string `json:"loggingTypes,omitempty" yaml:"loggingTypes,omitempty"` + NodeGroups []NodeGroup `json:"nodeGroups,omitempty" yaml:"nodeGroups,omitempty"` + PrivateAccess *bool `json:"privateAccess,omitempty" yaml:"privateAccess,omitempty"` + PublicAccess *bool `json:"publicAccess,omitempty" yaml:"publicAccess,omitempty"` + PublicAccessSources []string `json:"publicAccessSources,omitempty" yaml:"publicAccessSources,omitempty"` + Region string `json:"region,omitempty" yaml:"region,omitempty"` + SecretsEncryption *bool `json:"secretsEncryption,omitempty" yaml:"secretsEncryption,omitempty"` + SecurityGroups []string `json:"securityGroups,omitempty" yaml:"securityGroups,omitempty"` + ServiceRole *string `json:"serviceRole,omitempty" yaml:"serviceRole,omitempty"` + Subnets []string `json:"subnets,omitempty" yaml:"subnets,omitempty"` + Tags map[string]string `json:"tags,omitempty" yaml:"tags,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_status.go new file mode 100644 index 0000000..54127aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_eks_status.go @@ -0,0 +1,24 @@ +package client + +const ( + EKSStatusType = "eksStatus" + EKSStatusFieldGeneratedNodeRole = "generatedNodeRole" + EKSStatusFieldManagedLaunchTemplateID = "managedLaunchTemplateID" + EKSStatusFieldManagedLaunchTemplateVersions = "managedLaunchTemplateVersions" + EKSStatusFieldPrivateRequiresTunnel = "privateRequiresTunnel" + EKSStatusFieldSecurityGroups = "securityGroups" + EKSStatusFieldSubnets = "subnets" + EKSStatusFieldUpstreamSpec = "upstreamSpec" + EKSStatusFieldVirtualNetwork = "virtualNetwork" +) + +type EKSStatus struct { + GeneratedNodeRole string `json:"generatedNodeRole,omitempty" yaml:"generatedNodeRole,omitempty"` + ManagedLaunchTemplateID string `json:"managedLaunchTemplateID,omitempty" yaml:"managedLaunchTemplateID,omitempty"` + ManagedLaunchTemplateVersions map[string]string `json:"managedLaunchTemplateVersions,omitempty" yaml:"managedLaunchTemplateVersions,omitempty"` + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel,omitempty" yaml:"privateRequiresTunnel,omitempty"` + SecurityGroups []string `json:"securityGroups,omitempty" yaml:"securityGroups,omitempty"` + Subnets []string `json:"subnets,omitempty" yaml:"subnets,omitempty"` + UpstreamSpec *EKSClusterConfigSpec `json:"upstreamSpec,omitempty" yaml:"upstreamSpec,omitempty"` + VirtualNetwork string `json:"virtualNetwork,omitempty" yaml:"virtualNetwork,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_empty_dir_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_empty_dir_volume_source.go new file mode 100644 index 0000000..c4856f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_empty_dir_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + EmptyDirVolumeSourceType = "emptyDirVolumeSource" + EmptyDirVolumeSourceFieldMedium = "medium" + EmptyDirVolumeSourceFieldSizeLimit = "sizeLimit" +) + +type EmptyDirVolumeSource struct { + Medium string `json:"medium,omitempty" yaml:"medium,omitempty"` + SizeLimit string `json:"sizeLimit,omitempty" yaml:"sizeLimit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_encryption_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_encryption_configuration.go new file mode 100644 index 0000000..8cc644d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_encryption_configuration.go @@ -0,0 +1,14 @@ +package client + +const ( + EncryptionConfigurationType = "encryptionConfiguration" + EncryptionConfigurationFieldAPIVersion = "apiVersion" + EncryptionConfigurationFieldKind = "kind" + EncryptionConfigurationFieldResources = "resources" +) + +type EncryptionConfiguration struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Resources []ResourceConfiguration `json:"resources,omitempty" yaml:"resources,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var.go new file mode 100644 index 0000000..35ccda3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var.go @@ -0,0 +1,14 @@ +package client + +const ( + EnvVarType = "envVar" + EnvVarFieldName = "name" + EnvVarFieldValue = "value" + EnvVarFieldValueFrom = "valueFrom" +) + +type EnvVar struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` + ValueFrom *EnvVarSource `json:"valueFrom,omitempty" yaml:"valueFrom,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var_source.go new file mode 100644 index 0000000..390a033 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_env_var_source.go @@ -0,0 +1,16 @@ +package client + +const ( + EnvVarSourceType = "envVarSource" + EnvVarSourceFieldConfigMapKeyRef = "configMapKeyRef" + EnvVarSourceFieldFieldRef = "fieldRef" + EnvVarSourceFieldResourceFieldRef = "resourceFieldRef" + EnvVarSourceFieldSecretKeyRef = "secretKeyRef" +) + +type EnvVarSource struct { + ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" yaml:"configMapKeyRef,omitempty"` + FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" yaml:"fieldRef,omitempty"` + ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" yaml:"resourceFieldRef,omitempty"` + SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" yaml:"secretKeyRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ephemeral_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ephemeral_volume_source.go new file mode 100644 index 0000000..fc7f09e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ephemeral_volume_source.go @@ -0,0 +1,10 @@ +package client + +const ( + EphemeralVolumeSourceType = "ephemeralVolumeSource" + EphemeralVolumeSourceFieldVolumeClaimTemplate = "volumeClaimTemplate" +) + +type EphemeralVolumeSource struct { + VolumeClaimTemplate *PersistentVolumeClaimTemplate `json:"volumeClaimTemplate,omitempty" yaml:"volumeClaimTemplate,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup.go new file mode 100644 index 0000000..74cdd40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup.go @@ -0,0 +1,136 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + EtcdBackupType = "etcdBackup" + EtcdBackupFieldAnnotations = "annotations" + EtcdBackupFieldBackupConfig = "backupConfig" + EtcdBackupFieldClusterID = "clusterId" + EtcdBackupFieldCreated = "created" + EtcdBackupFieldCreatorID = "creatorId" + EtcdBackupFieldFilename = "filename" + EtcdBackupFieldLabels = "labels" + EtcdBackupFieldManual = "manual" + EtcdBackupFieldName = "name" + EtcdBackupFieldNamespaceId = "namespaceId" + EtcdBackupFieldOwnerReferences = "ownerReferences" + EtcdBackupFieldRemoved = "removed" + EtcdBackupFieldState = "state" + EtcdBackupFieldStatus = "status" + EtcdBackupFieldTransitioning = "transitioning" + EtcdBackupFieldTransitioningMessage = "transitioningMessage" + EtcdBackupFieldUUID = "uuid" +) + +type EtcdBackup struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + BackupConfig *BackupConfig `json:"backupConfig,omitempty" yaml:"backupConfig,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Filename string `json:"filename,omitempty" yaml:"filename,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Manual bool `json:"manual,omitempty" yaml:"manual,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *EtcdBackupStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type EtcdBackupCollection struct { + types.Collection + Data []EtcdBackup `json:"data,omitempty"` + client *EtcdBackupClient +} + +type EtcdBackupClient struct { + apiClient *Client +} + +type EtcdBackupOperations interface { + List(opts *types.ListOpts) (*EtcdBackupCollection, error) + ListAll(opts *types.ListOpts) (*EtcdBackupCollection, error) + Create(opts *EtcdBackup) (*EtcdBackup, error) + Update(existing *EtcdBackup, updates interface{}) (*EtcdBackup, error) + Replace(existing *EtcdBackup) (*EtcdBackup, error) + ByID(id string) (*EtcdBackup, error) + Delete(container *EtcdBackup) error +} + +func newEtcdBackupClient(apiClient *Client) *EtcdBackupClient { + return &EtcdBackupClient{ + apiClient: apiClient, + } +} + +func (c *EtcdBackupClient) Create(container *EtcdBackup) (*EtcdBackup, error) { + resp := &EtcdBackup{} + err := c.apiClient.Ops.DoCreate(EtcdBackupType, container, resp) + return resp, err +} + +func (c *EtcdBackupClient) Update(existing *EtcdBackup, updates interface{}) (*EtcdBackup, error) { + resp := &EtcdBackup{} + err := c.apiClient.Ops.DoUpdate(EtcdBackupType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *EtcdBackupClient) Replace(obj *EtcdBackup) (*EtcdBackup, error) { + resp := &EtcdBackup{} + err := c.apiClient.Ops.DoReplace(EtcdBackupType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *EtcdBackupClient) List(opts *types.ListOpts) (*EtcdBackupCollection, error) { + resp := &EtcdBackupCollection{} + err := c.apiClient.Ops.DoList(EtcdBackupType, opts, resp) + resp.client = c + return resp, err +} + +func (c *EtcdBackupClient) ListAll(opts *types.ListOpts) (*EtcdBackupCollection, error) { + resp := &EtcdBackupCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *EtcdBackupCollection) Next() (*EtcdBackupCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &EtcdBackupCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *EtcdBackupClient) ByID(id string) (*EtcdBackup, error) { + resp := &EtcdBackup{} + err := c.apiClient.Ops.DoByID(EtcdBackupType, id, resp) + return resp, err +} + +func (c *EtcdBackupClient) Delete(container *EtcdBackup) error { + return c.apiClient.Ops.DoResourceDelete(EtcdBackupType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_condition.go new file mode 100644 index 0000000..bfae753 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + EtcdBackupConditionType = "etcdBackupCondition" + EtcdBackupConditionFieldLastTransitionTime = "lastTransitionTime" + EtcdBackupConditionFieldLastUpdateTime = "lastUpdateTime" + EtcdBackupConditionFieldMessage = "message" + EtcdBackupConditionFieldReason = "reason" + EtcdBackupConditionFieldStatus = "status" + EtcdBackupConditionFieldType = "type" +) + +type EtcdBackupCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_spec.go new file mode 100644 index 0000000..f78b227 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_spec.go @@ -0,0 +1,16 @@ +package client + +const ( + EtcdBackupSpecType = "etcdBackupSpec" + EtcdBackupSpecFieldBackupConfig = "backupConfig" + EtcdBackupSpecFieldClusterID = "clusterId" + EtcdBackupSpecFieldFilename = "filename" + EtcdBackupSpecFieldManual = "manual" +) + +type EtcdBackupSpec struct { + BackupConfig *BackupConfig `json:"backupConfig,omitempty" yaml:"backupConfig,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Filename string `json:"filename,omitempty" yaml:"filename,omitempty"` + Manual bool `json:"manual,omitempty" yaml:"manual,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_status.go new file mode 100644 index 0000000..57b48ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_backup_status.go @@ -0,0 +1,14 @@ +package client + +const ( + EtcdBackupStatusType = "etcdBackupStatus" + EtcdBackupStatusFieldClusterObject = "clusterObject" + EtcdBackupStatusFieldConditions = "conditions" + EtcdBackupStatusFieldKubernetesVersion = "kubernetesVersion" +) + +type EtcdBackupStatus struct { + ClusterObject string `json:"clusterObject,omitempty" yaml:"clusterObject,omitempty"` + Conditions []EtcdBackupCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + KubernetesVersion string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_service.go new file mode 100644 index 0000000..6c17499 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_etcd_service.go @@ -0,0 +1,48 @@ +package client + +const ( + ETCDServiceType = "etcdService" + ETCDServiceFieldBackupConfig = "backupConfig" + ETCDServiceFieldCACert = "caCert" + ETCDServiceFieldCert = "cert" + ETCDServiceFieldCreation = "creation" + ETCDServiceFieldExternalURLs = "externalUrls" + ETCDServiceFieldExtraArgs = "extraArgs" + ETCDServiceFieldExtraArgsArray = "extraArgsArray" + ETCDServiceFieldExtraBinds = "extraBinds" + ETCDServiceFieldExtraEnv = "extraEnv" + ETCDServiceFieldGID = "gid" + ETCDServiceFieldImage = "image" + ETCDServiceFieldKey = "key" + ETCDServiceFieldPath = "path" + ETCDServiceFieldRetention = "retention" + ETCDServiceFieldSnapshot = "snapshot" + ETCDServiceFieldUID = "uid" + ETCDServiceFieldWindowsExtraArgs = "winExtraArgs" + ETCDServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + ETCDServiceFieldWindowsExtraBinds = "winExtraBinds" + ETCDServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type ETCDService struct { + BackupConfig *BackupConfig `json:"backupConfig,omitempty" yaml:"backupConfig,omitempty"` + CACert string `json:"caCert,omitempty" yaml:"caCert,omitempty"` + Cert string `json:"cert,omitempty" yaml:"cert,omitempty"` + Creation string `json:"creation,omitempty" yaml:"creation,omitempty"` + ExternalURLs []string `json:"externalUrls,omitempty" yaml:"externalUrls,omitempty"` + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + GID int64 `json:"gid,omitempty" yaml:"gid,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Retention string `json:"retention,omitempty" yaml:"retention,omitempty"` + Snapshot *bool `json:"snapshot,omitempty" yaml:"snapshot,omitempty"` + UID int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_event_rate_limit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_event_rate_limit.go new file mode 100644 index 0000000..6ba3b86 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_event_rate_limit.go @@ -0,0 +1,12 @@ +package client + +const ( + EventRateLimitType = "eventRateLimit" + EventRateLimitFieldConfiguration = "configuration" + EventRateLimitFieldEnabled = "enabled" +) + +type EventRateLimit struct { + Configuration map[string]interface{} `json:"configuration,omitempty" yaml:"configuration,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_export_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_export_output.go new file mode 100644 index 0000000..cf2559b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_export_output.go @@ -0,0 +1,10 @@ +package client + +const ( + ExportOutputType = "exportOutput" + ExportOutputFieldYAMLOutput = "yamlOutput" +) + +type ExportOutput struct { + YAMLOutput string `json:"yamlOutput,omitempty" yaml:"yamlOutput,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_env.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_env.go new file mode 100644 index 0000000..96a3ece --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_env.go @@ -0,0 +1,14 @@ +package client + +const ( + ExtraEnvType = "extraEnv" + ExtraEnvFieldName = "name" + ExtraEnvFieldValue = "value" + ExtraEnvFieldValueFrom = "valueFrom" +) + +type ExtraEnv struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` + ValueFrom *EnvVarSource `json:"valueFrom,omitempty" yaml:"valueFrom,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume.go new file mode 100644 index 0000000..cd629ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume.go @@ -0,0 +1,68 @@ +package client + +const ( + ExtraVolumeType = "extraVolume" + ExtraVolumeFieldAWSElasticBlockStore = "awsElasticBlockStore" + ExtraVolumeFieldAzureDisk = "azureDisk" + ExtraVolumeFieldAzureFile = "azureFile" + ExtraVolumeFieldCSI = "csi" + ExtraVolumeFieldCephFS = "cephfs" + ExtraVolumeFieldCinder = "cinder" + ExtraVolumeFieldConfigMap = "configMap" + ExtraVolumeFieldDownwardAPI = "downwardAPI" + ExtraVolumeFieldEmptyDir = "emptyDir" + ExtraVolumeFieldEphemeral = "ephemeral" + ExtraVolumeFieldFC = "fc" + ExtraVolumeFieldFlexVolume = "flexVolume" + ExtraVolumeFieldFlocker = "flocker" + ExtraVolumeFieldGCEPersistentDisk = "gcePersistentDisk" + ExtraVolumeFieldGitRepo = "gitRepo" + ExtraVolumeFieldGlusterfs = "glusterfs" + ExtraVolumeFieldHostPath = "hostPath" + ExtraVolumeFieldISCSI = "iscsi" + ExtraVolumeFieldNFS = "nfs" + ExtraVolumeFieldName = "name" + ExtraVolumeFieldPersistentVolumeClaim = "persistentVolumeClaim" + ExtraVolumeFieldPhotonPersistentDisk = "photonPersistentDisk" + ExtraVolumeFieldPortworxVolume = "portworxVolume" + ExtraVolumeFieldProjected = "projected" + ExtraVolumeFieldQuobyte = "quobyte" + ExtraVolumeFieldRBD = "rbd" + ExtraVolumeFieldScaleIO = "scaleIO" + ExtraVolumeFieldSecret = "secret" + ExtraVolumeFieldStorageOS = "storageos" + ExtraVolumeFieldVsphereVolume = "vsphereVolume" +) + +type ExtraVolume struct { + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" yaml:"awsElasticBlockStore,omitempty"` + AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" yaml:"azureDisk,omitempty"` + AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" yaml:"azureFile,omitempty"` + CSI *CSIVolumeSource `json:"csi,omitempty" yaml:"csi,omitempty"` + CephFS *CephFSVolumeSource `json:"cephfs,omitempty" yaml:"cephfs,omitempty"` + Cinder *CinderVolumeSource `json:"cinder,omitempty" yaml:"cinder,omitempty"` + ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty" yaml:"configMap,omitempty"` + DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty" yaml:"downwardAPI,omitempty"` + EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" yaml:"emptyDir,omitempty"` + Ephemeral *EphemeralVolumeSource `json:"ephemeral,omitempty" yaml:"ephemeral,omitempty"` + FC *FCVolumeSource `json:"fc,omitempty" yaml:"fc,omitempty"` + FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" yaml:"flexVolume,omitempty"` + Flocker *FlockerVolumeSource `json:"flocker,omitempty" yaml:"flocker,omitempty"` + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" yaml:"gcePersistentDisk,omitempty"` + GitRepo *GitRepoVolumeSource `json:"gitRepo,omitempty" yaml:"gitRepo,omitempty"` + Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" yaml:"glusterfs,omitempty"` + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` + ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" yaml:"iscsi,omitempty"` + NFS *NFSVolumeSource `json:"nfs,omitempty" yaml:"nfs,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty" yaml:"persistentVolumeClaim,omitempty"` + PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" yaml:"photonPersistentDisk,omitempty"` + PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" yaml:"portworxVolume,omitempty"` + Projected *ProjectedVolumeSource `json:"projected,omitempty" yaml:"projected,omitempty"` + Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" yaml:"quobyte,omitempty"` + RBD *RBDVolumeSource `json:"rbd,omitempty" yaml:"rbd,omitempty"` + ScaleIO *ScaleIOVolumeSource `json:"scaleIO,omitempty" yaml:"scaleIO,omitempty"` + Secret *SecretVolumeSource `json:"secret,omitempty" yaml:"secret,omitempty"` + StorageOS *StorageOSVolumeSource `json:"storageos,omitempty" yaml:"storageos,omitempty"` + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" yaml:"vsphereVolume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume_mount.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume_mount.go new file mode 100644 index 0000000..bbfbaea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_extra_volume_mount.go @@ -0,0 +1,22 @@ +package client + +const ( + ExtraVolumeMountType = "extraVolumeMount" + ExtraVolumeMountFieldMountPath = "mountPath" + ExtraVolumeMountFieldMountPropagation = "mountPropagation" + ExtraVolumeMountFieldName = "name" + ExtraVolumeMountFieldReadOnly = "readOnly" + ExtraVolumeMountFieldRecursiveReadOnly = "recursiveReadOnly" + ExtraVolumeMountFieldSubPath = "subPath" + ExtraVolumeMountFieldSubPathExpr = "subPathExpr" +) + +type ExtraVolumeMount struct { + MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"` + MountPropagation string `json:"mountPropagation,omitempty" yaml:"mountPropagation,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + RecursiveReadOnly string `json:"recursiveReadOnly,omitempty" yaml:"recursiveReadOnly,omitempty"` + SubPath string `json:"subPath,omitempty" yaml:"subPath,omitempty"` + SubPathExpr string `json:"subPathExpr,omitempty" yaml:"subPathExpr,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fc_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fc_volume_source.go new file mode 100644 index 0000000..ebc0b63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fc_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FCVolumeSourceType = "fcVolumeSource" + FCVolumeSourceFieldFSType = "fsType" + FCVolumeSourceFieldLun = "lun" + FCVolumeSourceFieldReadOnly = "readOnly" + FCVolumeSourceFieldTargetWWNs = "targetWWNs" + FCVolumeSourceFieldWWIDs = "wwids" +) + +type FCVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Lun *int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + TargetWWNs []string `json:"targetWWNs,omitempty" yaml:"targetWWNs,omitempty"` + WWIDs []string `json:"wwids,omitempty" yaml:"wwids,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature.go new file mode 100644 index 0000000..a8d1786 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + FeatureType = "feature" + FeatureFieldAnnotations = "annotations" + FeatureFieldCreated = "created" + FeatureFieldCreatorID = "creatorId" + FeatureFieldLabels = "labels" + FeatureFieldName = "name" + FeatureFieldOwnerReferences = "ownerReferences" + FeatureFieldRemoved = "removed" + FeatureFieldState = "state" + FeatureFieldStatus = "status" + FeatureFieldTransitioning = "transitioning" + FeatureFieldTransitioningMessage = "transitioningMessage" + FeatureFieldUUID = "uuid" + FeatureFieldValue = "value" +) + +type Feature struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *FeatureStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Value *bool `json:"value,omitempty" yaml:"value,omitempty"` +} + +type FeatureCollection struct { + types.Collection + Data []Feature `json:"data,omitempty"` + client *FeatureClient +} + +type FeatureClient struct { + apiClient *Client +} + +type FeatureOperations interface { + List(opts *types.ListOpts) (*FeatureCollection, error) + ListAll(opts *types.ListOpts) (*FeatureCollection, error) + Create(opts *Feature) (*Feature, error) + Update(existing *Feature, updates interface{}) (*Feature, error) + Replace(existing *Feature) (*Feature, error) + ByID(id string) (*Feature, error) + Delete(container *Feature) error +} + +func newFeatureClient(apiClient *Client) *FeatureClient { + return &FeatureClient{ + apiClient: apiClient, + } +} + +func (c *FeatureClient) Create(container *Feature) (*Feature, error) { + resp := &Feature{} + err := c.apiClient.Ops.DoCreate(FeatureType, container, resp) + return resp, err +} + +func (c *FeatureClient) Update(existing *Feature, updates interface{}) (*Feature, error) { + resp := &Feature{} + err := c.apiClient.Ops.DoUpdate(FeatureType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *FeatureClient) Replace(obj *Feature) (*Feature, error) { + resp := &Feature{} + err := c.apiClient.Ops.DoReplace(FeatureType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *FeatureClient) List(opts *types.ListOpts) (*FeatureCollection, error) { + resp := &FeatureCollection{} + err := c.apiClient.Ops.DoList(FeatureType, opts, resp) + resp.client = c + return resp, err +} + +func (c *FeatureClient) ListAll(opts *types.ListOpts) (*FeatureCollection, error) { + resp := &FeatureCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *FeatureCollection) Next() (*FeatureCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &FeatureCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *FeatureClient) ByID(id string) (*Feature, error) { + resp := &Feature{} + err := c.apiClient.Ops.DoByID(FeatureType, id, resp) + return resp, err +} + +func (c *FeatureClient) Delete(container *Feature) error { + return c.apiClient.Ops.DoResourceDelete(FeatureType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_spec.go new file mode 100644 index 0000000..95c5029 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_spec.go @@ -0,0 +1,10 @@ +package client + +const ( + FeatureSpecType = "featureSpec" + FeatureSpecFieldValue = "value" +) + +type FeatureSpec struct { + Value *bool `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_status.go new file mode 100644 index 0000000..be4799a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_feature_status.go @@ -0,0 +1,16 @@ +package client + +const ( + FeatureStatusType = "featureStatus" + FeatureStatusFieldDefault = "default" + FeatureStatusFieldDescription = "description" + FeatureStatusFieldDynamic = "dynamic" + FeatureStatusFieldLockedValue = "lockedValue" +) + +type FeatureStatus struct { + Default bool `json:"default,omitempty" yaml:"default,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Dynamic bool `json:"dynamic,omitempty" yaml:"dynamic,omitempty"` + LockedValue *bool `json:"lockedValue,omitempty" yaml:"lockedValue,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_field.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_field.go new file mode 100644 index 0000000..9f13a3a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_field.go @@ -0,0 +1,40 @@ +package client + +const ( + FieldType = "field" + FieldFieldCreate = "create" + FieldFieldDefault = "default" + FieldFieldDescription = "description" + FieldFieldDynamicField = "dynamicField" + FieldFieldInvalidChars = "invalidChars" + FieldFieldMax = "max" + FieldFieldMaxLength = "maxLength" + FieldFieldMin = "min" + FieldFieldMinLength = "minLength" + FieldFieldNullable = "nullable" + FieldFieldOptions = "options" + FieldFieldRequired = "required" + FieldFieldType = "type" + FieldFieldUnique = "unique" + FieldFieldUpdate = "update" + FieldFieldValidChars = "validChars" +) + +type Field struct { + Create bool `json:"create,omitempty" yaml:"create,omitempty"` + Default *Values `json:"default,omitempty" yaml:"default,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DynamicField bool `json:"dynamicField,omitempty" yaml:"dynamicField,omitempty"` + InvalidChars string `json:"invalidChars,omitempty" yaml:"invalidChars,omitempty"` + Max int64 `json:"max,omitempty" yaml:"max,omitempty"` + MaxLength int64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"` + Min int64 `json:"min,omitempty" yaml:"min,omitempty"` + MinLength int64 `json:"minLength,omitempty" yaml:"minLength,omitempty"` + Nullable bool `json:"nullable,omitempty" yaml:"nullable,omitempty"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + Required bool `json:"required,omitempty" yaml:"required,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Unique bool `json:"unique,omitempty" yaml:"unique,omitempty"` + Update bool `json:"update,omitempty" yaml:"update,omitempty"` + ValidChars string `json:"validChars,omitempty" yaml:"validChars,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_file.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_file.go new file mode 100644 index 0000000..18d80cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_file.go @@ -0,0 +1,12 @@ +package client + +const ( + FileType = "file" + FileFieldContents = "contents" + FileFieldName = "name" +) + +type File struct { + Contents string `json:"contents,omitempty" yaml:"contents,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_filter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_filter.go new file mode 100644 index 0000000..8bb3f71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_filter.go @@ -0,0 +1,10 @@ +package client + +const ( + FilterType = "filter" + FilterFieldModifiers = "modifiers" +) + +type Filter struct { + Modifiers []string `json:"modifiers,omitempty" yaml:"modifiers,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flannel_network_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flannel_network_provider.go new file mode 100644 index 0000000..088fe6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flannel_network_provider.go @@ -0,0 +1,10 @@ +package client + +const ( + FlannelNetworkProviderType = "flannelNetworkProvider" + FlannelNetworkProviderFieldIface = "iface" +) + +type FlannelNetworkProvider struct { + Iface string `json:"iface,omitempty" yaml:"iface,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace.go new file mode 100644 index 0000000..963b286 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + FleetWorkspaceType = "fleetWorkspace" + FleetWorkspaceFieldAnnotations = "annotations" + FleetWorkspaceFieldCreated = "created" + FleetWorkspaceFieldCreatorID = "creatorId" + FleetWorkspaceFieldLabels = "labels" + FleetWorkspaceFieldName = "name" + FleetWorkspaceFieldOwnerReferences = "ownerReferences" + FleetWorkspaceFieldRemoved = "removed" + FleetWorkspaceFieldStatus = "status" + FleetWorkspaceFieldUUID = "uuid" +) + +type FleetWorkspace struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Status *FleetWorkspaceStatus `json:"status,omitempty" yaml:"status,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type FleetWorkspaceCollection struct { + types.Collection + Data []FleetWorkspace `json:"data,omitempty"` + client *FleetWorkspaceClient +} + +type FleetWorkspaceClient struct { + apiClient *Client +} + +type FleetWorkspaceOperations interface { + List(opts *types.ListOpts) (*FleetWorkspaceCollection, error) + ListAll(opts *types.ListOpts) (*FleetWorkspaceCollection, error) + Create(opts *FleetWorkspace) (*FleetWorkspace, error) + Update(existing *FleetWorkspace, updates interface{}) (*FleetWorkspace, error) + Replace(existing *FleetWorkspace) (*FleetWorkspace, error) + ByID(id string) (*FleetWorkspace, error) + Delete(container *FleetWorkspace) error +} + +func newFleetWorkspaceClient(apiClient *Client) *FleetWorkspaceClient { + return &FleetWorkspaceClient{ + apiClient: apiClient, + } +} + +func (c *FleetWorkspaceClient) Create(container *FleetWorkspace) (*FleetWorkspace, error) { + resp := &FleetWorkspace{} + err := c.apiClient.Ops.DoCreate(FleetWorkspaceType, container, resp) + return resp, err +} + +func (c *FleetWorkspaceClient) Update(existing *FleetWorkspace, updates interface{}) (*FleetWorkspace, error) { + resp := &FleetWorkspace{} + err := c.apiClient.Ops.DoUpdate(FleetWorkspaceType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *FleetWorkspaceClient) Replace(obj *FleetWorkspace) (*FleetWorkspace, error) { + resp := &FleetWorkspace{} + err := c.apiClient.Ops.DoReplace(FleetWorkspaceType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *FleetWorkspaceClient) List(opts *types.ListOpts) (*FleetWorkspaceCollection, error) { + resp := &FleetWorkspaceCollection{} + err := c.apiClient.Ops.DoList(FleetWorkspaceType, opts, resp) + resp.client = c + return resp, err +} + +func (c *FleetWorkspaceClient) ListAll(opts *types.ListOpts) (*FleetWorkspaceCollection, error) { + resp := &FleetWorkspaceCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *FleetWorkspaceCollection) Next() (*FleetWorkspaceCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &FleetWorkspaceCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *FleetWorkspaceClient) ByID(id string) (*FleetWorkspace, error) { + resp := &FleetWorkspace{} + err := c.apiClient.Ops.DoByID(FleetWorkspaceType, id, resp) + return resp, err +} + +func (c *FleetWorkspaceClient) Delete(container *FleetWorkspace) error { + return c.apiClient.Ops.DoResourceDelete(FleetWorkspaceType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_permission.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_permission.go new file mode 100644 index 0000000..209f623 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_permission.go @@ -0,0 +1,12 @@ +package client + +const ( + FleetWorkspacePermissionType = "fleetWorkspacePermission" + FleetWorkspacePermissionFieldResourceRules = "resourceRules" + FleetWorkspacePermissionFieldWorkspaceVerbs = "workspaceVerbs" +) + +type FleetWorkspacePermission struct { + ResourceRules []PolicyRule `json:"resourceRules,omitempty" yaml:"resourceRules,omitempty"` + WorkspaceVerbs []string `json:"workspaceVerbs,omitempty" yaml:"workspaceVerbs,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_status.go new file mode 100644 index 0000000..aa5db18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_fleet_workspace_status.go @@ -0,0 +1,8 @@ +package client + +const ( + FleetWorkspaceStatusType = "fleetWorkspaceStatus" +) + +type FleetWorkspaceStatus struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flex_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flex_volume_source.go new file mode 100644 index 0000000..d2e942b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flex_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FlexVolumeSourceType = "flexVolumeSource" + FlexVolumeSourceFieldDriver = "driver" + FlexVolumeSourceFieldFSType = "fsType" + FlexVolumeSourceFieldOptions = "options" + FlexVolumeSourceFieldReadOnly = "readOnly" + FlexVolumeSourceFieldSecretRef = "secretRef" +) + +type FlexVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flocker_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flocker_volume_source.go new file mode 100644 index 0000000..802b77f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_flocker_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + FlockerVolumeSourceType = "flockerVolumeSource" + FlockerVolumeSourceFieldDatasetName = "datasetName" + FlockerVolumeSourceFieldDatasetUUID = "datasetUUID" +) + +type FlockerVolumeSource struct { + DatasetName string `json:"datasetName,omitempty" yaml:"datasetName,omitempty"` + DatasetUUID string `json:"datasetUUID,omitempty" yaml:"datasetUUID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_config.go new file mode 100644 index 0000000..750de61 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_config.go @@ -0,0 +1,84 @@ +package client + +const ( + FreeIpaConfigType = "freeIpaConfig" + FreeIpaConfigFieldAccessMode = "accessMode" + FreeIpaConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + FreeIpaConfigFieldAnnotations = "annotations" + FreeIpaConfigFieldCertificate = "certificate" + FreeIpaConfigFieldConnectionTimeout = "connectionTimeout" + FreeIpaConfigFieldCreated = "created" + FreeIpaConfigFieldCreatorID = "creatorId" + FreeIpaConfigFieldEnabled = "enabled" + FreeIpaConfigFieldGroupDNAttribute = "groupDNAttribute" + FreeIpaConfigFieldGroupMemberMappingAttribute = "groupMemberMappingAttribute" + FreeIpaConfigFieldGroupMemberUserAttribute = "groupMemberUserAttribute" + FreeIpaConfigFieldGroupNameAttribute = "groupNameAttribute" + FreeIpaConfigFieldGroupObjectClass = "groupObjectClass" + FreeIpaConfigFieldGroupSearchAttribute = "groupSearchAttribute" + FreeIpaConfigFieldGroupSearchBase = "groupSearchBase" + FreeIpaConfigFieldGroupSearchFilter = "groupSearchFilter" + FreeIpaConfigFieldLabels = "labels" + FreeIpaConfigFieldName = "name" + FreeIpaConfigFieldOwnerReferences = "ownerReferences" + FreeIpaConfigFieldPort = "port" + FreeIpaConfigFieldRemoved = "removed" + FreeIpaConfigFieldServers = "servers" + FreeIpaConfigFieldServiceAccountDistinguishedName = "serviceAccountDistinguishedName" + FreeIpaConfigFieldServiceAccountPassword = "serviceAccountPassword" + FreeIpaConfigFieldStartTLS = "starttls" + FreeIpaConfigFieldStatus = "status" + FreeIpaConfigFieldTLS = "tls" + FreeIpaConfigFieldType = "type" + FreeIpaConfigFieldUUID = "uuid" + FreeIpaConfigFieldUserDisabledBitMask = "userDisabledBitMask" + FreeIpaConfigFieldUserEnabledAttribute = "userEnabledAttribute" + FreeIpaConfigFieldUserLoginAttribute = "userLoginAttribute" + FreeIpaConfigFieldUserMemberAttribute = "userMemberAttribute" + FreeIpaConfigFieldUserNameAttribute = "userNameAttribute" + FreeIpaConfigFieldUserObjectClass = "userObjectClass" + FreeIpaConfigFieldUserSearchAttribute = "userSearchAttribute" + FreeIpaConfigFieldUserSearchBase = "userSearchBase" + FreeIpaConfigFieldUserSearchFilter = "userSearchFilter" +) + +type FreeIpaConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" yaml:"connectionTimeout,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" yaml:"groupDNAttribute,omitempty"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" yaml:"groupMemberMappingAttribute,omitempty"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" yaml:"groupMemberUserAttribute,omitempty"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" yaml:"groupNameAttribute,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" yaml:"groupObjectClass,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" yaml:"groupSearchAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty" yaml:"groupSearchFilter,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Servers []string `json:"servers,omitempty" yaml:"servers,omitempty"` + ServiceAccountDistinguishedName string `json:"serviceAccountDistinguishedName,omitempty" yaml:"serviceAccountDistinguishedName,omitempty"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" yaml:"serviceAccountPassword,omitempty"` + StartTLS bool `json:"starttls,omitempty" yaml:"starttls,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" yaml:"userDisabledBitMask,omitempty"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" yaml:"userEnabledAttribute,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" yaml:"userLoginAttribute,omitempty"` + UserMemberAttribute string `json:"userMemberAttribute,omitempty" yaml:"userMemberAttribute,omitempty"` + UserNameAttribute string `json:"userNameAttribute,omitempty" yaml:"userNameAttribute,omitempty"` + UserObjectClass string `json:"userObjectClass,omitempty" yaml:"userObjectClass,omitempty"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" yaml:"userSearchAttribute,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"` + UserSearchFilter string `json:"userSearchFilter,omitempty" yaml:"userSearchFilter,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_test_and_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_test_and_apply_input.go new file mode 100644 index 0000000..ad27c59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_free_ipa_test_and_apply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + FreeIpaTestAndApplyInputType = "freeIpaTestAndApplyInput" + FreeIpaTestAndApplyInputFieldLdapConfig = "ldapConfig" + FreeIpaTestAndApplyInputFieldPassword = "password" + FreeIpaTestAndApplyInputFieldUsername = "username" +) + +type FreeIpaTestAndApplyInput struct { + LdapConfig *LdapConfig `json:"ldapConfig,omitempty" yaml:"ldapConfig,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gce_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gce_persistent_disk_volume_source.go new file mode 100644 index 0000000..726a448 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gce_persistent_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + GCEPersistentDiskVolumeSourceType = "gcePersistentDiskVolumeSource" + GCEPersistentDiskVolumeSourceFieldFSType = "fsType" + GCEPersistentDiskVolumeSourceFieldPDName = "pdName" + GCEPersistentDiskVolumeSourceFieldPartition = "partition" + GCEPersistentDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type GCEPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PDName string `json:"pdName,omitempty" yaml:"pdName,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generate_kube_config_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generate_kube_config_output.go new file mode 100644 index 0000000..2603f41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generate_kube_config_output.go @@ -0,0 +1,10 @@ +package client + +const ( + GenerateKubeConfigOutputType = "generateKubeConfigOutput" + GenerateKubeConfigOutputFieldConfig = "config" +) + +type GenerateKubeConfigOutput struct { + Config string `json:"config,omitempty" yaml:"config,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcapply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcapply_input.go new file mode 100644 index 0000000..5bc8c60 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcapply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + GenericOIDCApplyInputType = "genericOIDCApplyInput" + GenericOIDCApplyInputFieldCode = "code" + GenericOIDCApplyInputFieldEnabled = "enabled" + GenericOIDCApplyInputFieldOIDCConfig = "oidcConfig" +) + +type GenericOIDCApplyInput struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + OIDCConfig *OIDCConfig `json:"oidcConfig,omitempty" yaml:"oidcConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcconfig.go new file mode 100644 index 0000000..4d120bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidcconfig.go @@ -0,0 +1,62 @@ +package client + +const ( + GenericOIDCConfigType = "genericOIDCConfig" + GenericOIDCConfigFieldAccessMode = "accessMode" + GenericOIDCConfigFieldAcrValue = "acrValue" + GenericOIDCConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + GenericOIDCConfigFieldAnnotations = "annotations" + GenericOIDCConfigFieldAuthEndpoint = "authEndpoint" + GenericOIDCConfigFieldCertificate = "certificate" + GenericOIDCConfigFieldClientID = "clientId" + GenericOIDCConfigFieldClientSecret = "clientSecret" + GenericOIDCConfigFieldCreated = "created" + GenericOIDCConfigFieldCreatorID = "creatorId" + GenericOIDCConfigFieldEnabled = "enabled" + GenericOIDCConfigFieldGroupSearchEnabled = "groupSearchEnabled" + GenericOIDCConfigFieldGroupsClaim = "groupsClaim" + GenericOIDCConfigFieldIssuer = "issuer" + GenericOIDCConfigFieldJWKSUrl = "jwksUrl" + GenericOIDCConfigFieldLabels = "labels" + GenericOIDCConfigFieldName = "name" + GenericOIDCConfigFieldOwnerReferences = "ownerReferences" + GenericOIDCConfigFieldPrivateKey = "privateKey" + GenericOIDCConfigFieldRancherURL = "rancherUrl" + GenericOIDCConfigFieldRemoved = "removed" + GenericOIDCConfigFieldScopes = "scope" + GenericOIDCConfigFieldStatus = "status" + GenericOIDCConfigFieldTokenEndpoint = "tokenEndpoint" + GenericOIDCConfigFieldType = "type" + GenericOIDCConfigFieldUUID = "uuid" + GenericOIDCConfigFieldUserInfoEndpoint = "userInfoEndpoint" +) + +type GenericOIDCConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AcrValue string `json:"acrValue,omitempty" yaml:"acrValue,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthEndpoint string `json:"authEndpoint,omitempty" yaml:"authEndpoint,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ClientID string `json:"clientId,omitempty" yaml:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupSearchEnabled *bool `json:"groupSearchEnabled,omitempty" yaml:"groupSearchEnabled,omitempty"` + GroupsClaim string `json:"groupsClaim,omitempty" yaml:"groupsClaim,omitempty"` + Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"` + JWKSUrl string `json:"jwksUrl,omitempty" yaml:"jwksUrl,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + RancherURL string `json:"rancherUrl,omitempty" yaml:"rancherUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Scopes string `json:"scope,omitempty" yaml:"scope,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TokenEndpoint string `json:"tokenEndpoint,omitempty" yaml:"tokenEndpoint,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserInfoEndpoint string `json:"userInfoEndpoint,omitempty" yaml:"userInfoEndpoint,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidctest_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidctest_output.go new file mode 100644 index 0000000..93d2fdc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_generic_oidctest_output.go @@ -0,0 +1,10 @@ +package client + +const ( + GenericOIDCTestOutputType = "genericOIDCTestOutput" + GenericOIDCTestOutputFieldRedirectURL = "redirectUrl" +) + +type GenericOIDCTestOutput struct { + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_git_repo_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_git_repo_volume_source.go new file mode 100644 index 0000000..102d08f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_git_repo_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + GitRepoVolumeSourceType = "gitRepoVolumeSource" + GitRepoVolumeSourceFieldDirectory = "directory" + GitRepoVolumeSourceFieldRepository = "repository" + GitRepoVolumeSourceFieldRevision = "revision" +) + +type GitRepoVolumeSource struct { + Directory string `json:"directory,omitempty" yaml:"directory,omitempty"` + Repository string `json:"repository,omitempty" yaml:"repository,omitempty"` + Revision string `json:"revision,omitempty" yaml:"revision,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config.go new file mode 100644 index 0000000..04dc453 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config.go @@ -0,0 +1,46 @@ +package client + +const ( + GithubConfigType = "githubConfig" + GithubConfigFieldAccessMode = "accessMode" + GithubConfigFieldAdditionalClientIDs = "additionalClientIds" + GithubConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + GithubConfigFieldAnnotations = "annotations" + GithubConfigFieldClientID = "clientId" + GithubConfigFieldClientSecret = "clientSecret" + GithubConfigFieldCreated = "created" + GithubConfigFieldCreatorID = "creatorId" + GithubConfigFieldEnabled = "enabled" + GithubConfigFieldHostname = "hostname" + GithubConfigFieldHostnameToClientID = "hostnameToClientId" + GithubConfigFieldLabels = "labels" + GithubConfigFieldName = "name" + GithubConfigFieldOwnerReferences = "ownerReferences" + GithubConfigFieldRemoved = "removed" + GithubConfigFieldStatus = "status" + GithubConfigFieldTLS = "tls" + GithubConfigFieldType = "type" + GithubConfigFieldUUID = "uuid" +) + +type GithubConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AdditionalClientIDs map[string]string `json:"additionalClientIds,omitempty" yaml:"additionalClientIds,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClientID string `json:"clientId,omitempty" yaml:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + HostnameToClientID map[string]string `json:"hostnameToClientId,omitempty" yaml:"hostnameToClientId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_apply_input.go new file mode 100644 index 0000000..af9cae8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_apply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + GithubConfigApplyInputType = "githubConfigApplyInput" + GithubConfigApplyInputFieldCode = "code" + GithubConfigApplyInputFieldEnabled = "enabled" + GithubConfigApplyInputFieldGithubConfig = "githubConfig" +) + +type GithubConfigApplyInput struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GithubConfig *GithubConfig `json:"githubConfig,omitempty" yaml:"githubConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_test_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_test_output.go new file mode 100644 index 0000000..d7eaf88 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_github_config_test_output.go @@ -0,0 +1,10 @@ +package client + +const ( + GithubConfigTestOutputType = "githubConfigTestOutput" + GithubConfigTestOutputFieldRedirectURL = "redirectUrl" +) + +type GithubConfigTestOutput struct { + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_autopilot_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_autopilot_config.go new file mode 100644 index 0000000..83bf5ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_autopilot_config.go @@ -0,0 +1,10 @@ +package client + +const ( + GKEAutopilotConfigType = "gkeAutopilotConfig" + GKEAutopilotConfigFieldEnabled = "enabled" +) + +type GKEAutopilotConfig struct { + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cidr_block.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cidr_block.go new file mode 100644 index 0000000..d89fa3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cidr_block.go @@ -0,0 +1,12 @@ +package client + +const ( + GKECidrBlockType = "gkeCidrBlock" + GKECidrBlockFieldCidrBlock = "cidrBlock" + GKECidrBlockFieldDisplayName = "displayName" +) + +type GKECidrBlock struct { + CidrBlock string `json:"cidrBlock,omitempty" yaml:"cidrBlock,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_addons.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_addons.go new file mode 100644 index 0000000..8cbf23c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_addons.go @@ -0,0 +1,14 @@ +package client + +const ( + GKEClusterAddonsType = "gkeClusterAddons" + GKEClusterAddonsFieldHTTPLoadBalancing = "httpLoadBalancing" + GKEClusterAddonsFieldHorizontalPodAutoscaling = "horizontalPodAutoscaling" + GKEClusterAddonsFieldNetworkPolicyConfig = "networkPolicyConfig" +) + +type GKEClusterAddons struct { + HTTPLoadBalancing bool `json:"httpLoadBalancing,omitempty" yaml:"httpLoadBalancing,omitempty"` + HorizontalPodAutoscaling bool `json:"horizontalPodAutoscaling,omitempty" yaml:"horizontalPodAutoscaling,omitempty"` + NetworkPolicyConfig bool `json:"networkPolicyConfig,omitempty" yaml:"networkPolicyConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_config_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_config_spec.go new file mode 100644 index 0000000..4973fe6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_cluster_config_spec.go @@ -0,0 +1,58 @@ +package client + +const ( + GKEClusterConfigSpecType = "gkeClusterConfigSpec" + GKEClusterConfigSpecFieldAutopilotConfig = "autopilotConfig" + GKEClusterConfigSpecFieldClusterAddons = "clusterAddons" + GKEClusterConfigSpecFieldClusterIpv4CidrBlock = "clusterIpv4Cidr" + GKEClusterConfigSpecFieldClusterName = "clusterName" + GKEClusterConfigSpecFieldCustomerManagedEncryptionKey = "customerManagedEncryptionKey" + GKEClusterConfigSpecFieldDescription = "description" + GKEClusterConfigSpecFieldEnableKubernetesAlpha = "enableKubernetesAlpha" + GKEClusterConfigSpecFieldGoogleCredentialSecret = "googleCredentialSecret" + GKEClusterConfigSpecFieldIPAllocationPolicy = "ipAllocationPolicy" + GKEClusterConfigSpecFieldImported = "imported" + GKEClusterConfigSpecFieldKubernetesVersion = "kubernetesVersion" + GKEClusterConfigSpecFieldLabels = "labels" + GKEClusterConfigSpecFieldLocations = "locations" + GKEClusterConfigSpecFieldLoggingService = "loggingService" + GKEClusterConfigSpecFieldMaintenanceWindow = "maintenanceWindow" + GKEClusterConfigSpecFieldMasterAuthorizedNetworksConfig = "masterAuthorizedNetworks" + GKEClusterConfigSpecFieldMonitoringService = "monitoringService" + GKEClusterConfigSpecFieldNetwork = "network" + GKEClusterConfigSpecFieldNetworkPolicyEnabled = "networkPolicyEnabled" + GKEClusterConfigSpecFieldNodePools = "nodePools" + GKEClusterConfigSpecFieldPrivateClusterConfig = "privateClusterConfig" + GKEClusterConfigSpecFieldProjectID = "projectID" + GKEClusterConfigSpecFieldRegion = "region" + GKEClusterConfigSpecFieldSubnetwork = "subnetwork" + GKEClusterConfigSpecFieldZone = "zone" +) + +type GKEClusterConfigSpec struct { + AutopilotConfig *GKEAutopilotConfig `json:"autopilotConfig,omitempty" yaml:"autopilotConfig,omitempty"` + ClusterAddons *GKEClusterAddons `json:"clusterAddons,omitempty" yaml:"clusterAddons,omitempty"` + ClusterIpv4CidrBlock *string `json:"clusterIpv4Cidr,omitempty" yaml:"clusterIpv4Cidr,omitempty"` + ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"` + CustomerManagedEncryptionKey *CMEKConfig `json:"customerManagedEncryptionKey,omitempty" yaml:"customerManagedEncryptionKey,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + EnableKubernetesAlpha *bool `json:"enableKubernetesAlpha,omitempty" yaml:"enableKubernetesAlpha,omitempty"` + GoogleCredentialSecret string `json:"googleCredentialSecret,omitempty" yaml:"googleCredentialSecret,omitempty"` + IPAllocationPolicy *GKEIPAllocationPolicy `json:"ipAllocationPolicy,omitempty" yaml:"ipAllocationPolicy,omitempty"` + Imported bool `json:"imported,omitempty" yaml:"imported,omitempty"` + KubernetesVersion *string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Locations []string `json:"locations,omitempty" yaml:"locations,omitempty"` + LoggingService *string `json:"loggingService,omitempty" yaml:"loggingService,omitempty"` + MaintenanceWindow *string `json:"maintenanceWindow,omitempty" yaml:"maintenanceWindow,omitempty"` + MasterAuthorizedNetworksConfig *GKEMasterAuthorizedNetworksConfig `json:"masterAuthorizedNetworks,omitempty" yaml:"masterAuthorizedNetworks,omitempty"` + MonitoringService *string `json:"monitoringService,omitempty" yaml:"monitoringService,omitempty"` + Network *string `json:"network,omitempty" yaml:"network,omitempty"` + NetworkPolicyEnabled *bool `json:"networkPolicyEnabled,omitempty" yaml:"networkPolicyEnabled,omitempty"` + NodePools []GKENodePoolConfig `json:"nodePools,omitempty" yaml:"nodePools,omitempty"` + PrivateClusterConfig *GKEPrivateClusterConfig `json:"privateClusterConfig,omitempty" yaml:"privateClusterConfig,omitempty"` + ProjectID string `json:"projectID,omitempty" yaml:"projectID,omitempty"` + Region string `json:"region,omitempty" yaml:"region,omitempty"` + Subnetwork *string `json:"subnetwork,omitempty" yaml:"subnetwork,omitempty"` + Zone string `json:"zone,omitempty" yaml:"zone,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_master_authorized_networks_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_master_authorized_networks_config.go new file mode 100644 index 0000000..0eb9371 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_master_authorized_networks_config.go @@ -0,0 +1,12 @@ +package client + +const ( + GKEMasterAuthorizedNetworksConfigType = "gkeMasterAuthorizedNetworksConfig" + GKEMasterAuthorizedNetworksConfigFieldCidrBlocks = "cidrBlocks" + GKEMasterAuthorizedNetworksConfigFieldEnabled = "enabled" +) + +type GKEMasterAuthorizedNetworksConfig struct { + CidrBlocks []GKECidrBlock `json:"cidrBlocks,omitempty" yaml:"cidrBlocks,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_config.go new file mode 100644 index 0000000..ee72b72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_config.go @@ -0,0 +1,32 @@ +package client + +const ( + GKENodeConfigType = "gkeNodeConfig" + GKENodeConfigFieldBootDiskKmsKey = "bootDiskKmsKey" + GKENodeConfigFieldDiskSizeGb = "diskSizeGb" + GKENodeConfigFieldDiskType = "diskType" + GKENodeConfigFieldImageType = "imageType" + GKENodeConfigFieldLabels = "labels" + GKENodeConfigFieldLocalSsdCount = "localSsdCount" + GKENodeConfigFieldMachineType = "machineType" + GKENodeConfigFieldOauthScopes = "oauthScopes" + GKENodeConfigFieldPreemptible = "preemptible" + GKENodeConfigFieldServiceAccount = "serviceAccount" + GKENodeConfigFieldTags = "tags" + GKENodeConfigFieldTaints = "taints" +) + +type GKENodeConfig struct { + BootDiskKmsKey string `json:"bootDiskKmsKey,omitempty" yaml:"bootDiskKmsKey,omitempty"` + DiskSizeGb int64 `json:"diskSizeGb,omitempty" yaml:"diskSizeGb,omitempty"` + DiskType string `json:"diskType,omitempty" yaml:"diskType,omitempty"` + ImageType string `json:"imageType,omitempty" yaml:"imageType,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LocalSsdCount int64 `json:"localSsdCount,omitempty" yaml:"localSsdCount,omitempty"` + MachineType string `json:"machineType,omitempty" yaml:"machineType,omitempty"` + OauthScopes []string `json:"oauthScopes,omitempty" yaml:"oauthScopes,omitempty"` + Preemptible bool `json:"preemptible,omitempty" yaml:"preemptible,omitempty"` + ServiceAccount string `json:"serviceAccount,omitempty" yaml:"serviceAccount,omitempty"` + Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"` + Taints []GKENodeTaintConfig `json:"taints,omitempty" yaml:"taints,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_autoscaling.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_autoscaling.go new file mode 100644 index 0000000..7be64fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_autoscaling.go @@ -0,0 +1,14 @@ +package client + +const ( + GKENodePoolAutoscalingType = "gkeNodePoolAutoscaling" + GKENodePoolAutoscalingFieldEnabled = "enabled" + GKENodePoolAutoscalingFieldMaxNodeCount = "maxNodeCount" + GKENodePoolAutoscalingFieldMinNodeCount = "minNodeCount" +) + +type GKENodePoolAutoscaling struct { + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + MaxNodeCount int64 `json:"maxNodeCount,omitempty" yaml:"maxNodeCount,omitempty"` + MinNodeCount int64 `json:"minNodeCount,omitempty" yaml:"minNodeCount,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_config.go new file mode 100644 index 0000000..30bf770 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_config.go @@ -0,0 +1,22 @@ +package client + +const ( + GKENodePoolConfigType = "gkeNodePoolConfig" + GKENodePoolConfigFieldAutoscaling = "autoscaling" + GKENodePoolConfigFieldConfig = "config" + GKENodePoolConfigFieldInitialNodeCount = "initialNodeCount" + GKENodePoolConfigFieldManagement = "management" + GKENodePoolConfigFieldMaxPodsConstraint = "maxPodsConstraint" + GKENodePoolConfigFieldName = "name" + GKENodePoolConfigFieldVersion = "version" +) + +type GKENodePoolConfig struct { + Autoscaling *GKENodePoolAutoscaling `json:"autoscaling,omitempty" yaml:"autoscaling,omitempty"` + Config *GKENodeConfig `json:"config,omitempty" yaml:"config,omitempty"` + InitialNodeCount *int64 `json:"initialNodeCount,omitempty" yaml:"initialNodeCount,omitempty"` + Management *GKENodePoolManagement `json:"management,omitempty" yaml:"management,omitempty"` + MaxPodsConstraint *int64 `json:"maxPodsConstraint,omitempty" yaml:"maxPodsConstraint,omitempty"` + Name *string `json:"name,omitempty" yaml:"name,omitempty"` + Version *string `json:"version,omitempty" yaml:"version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_management.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_management.go new file mode 100644 index 0000000..de37c5a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_pool_management.go @@ -0,0 +1,12 @@ +package client + +const ( + GKENodePoolManagementType = "gkeNodePoolManagement" + GKENodePoolManagementFieldAutoRepair = "autoRepair" + GKENodePoolManagementFieldAutoUpgrade = "autoUpgrade" +) + +type GKENodePoolManagement struct { + AutoRepair bool `json:"autoRepair,omitempty" yaml:"autoRepair,omitempty"` + AutoUpgrade bool `json:"autoUpgrade,omitempty" yaml:"autoUpgrade,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_taint_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_taint_config.go new file mode 100644 index 0000000..f9fd1e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_node_taint_config.go @@ -0,0 +1,14 @@ +package client + +const ( + GKENodeTaintConfigType = "gkeNodeTaintConfig" + GKENodeTaintConfigFieldEffect = "effect" + GKENodeTaintConfigFieldKey = "key" + GKENodeTaintConfigFieldValue = "value" +) + +type GKENodeTaintConfig struct { + Effect string `json:"effect,omitempty" yaml:"effect,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_private_cluster_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_private_cluster_config.go new file mode 100644 index 0000000..7607cbe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_private_cluster_config.go @@ -0,0 +1,14 @@ +package client + +const ( + GKEPrivateClusterConfigType = "gkePrivateClusterConfig" + GKEPrivateClusterConfigFieldEnablePrivateEndpoint = "enablePrivateEndpoint" + GKEPrivateClusterConfigFieldEnablePrivateNodes = "enablePrivateNodes" + GKEPrivateClusterConfigFieldMasterIpv4CidrBlock = "masterIpv4CidrBlock" +) + +type GKEPrivateClusterConfig struct { + EnablePrivateEndpoint bool `json:"enablePrivateEndpoint,omitempty" yaml:"enablePrivateEndpoint,omitempty"` + EnablePrivateNodes bool `json:"enablePrivateNodes,omitempty" yaml:"enablePrivateNodes,omitempty"` + MasterIpv4CidrBlock string `json:"masterIpv4CidrBlock,omitempty" yaml:"masterIpv4CidrBlock,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_status.go new file mode 100644 index 0000000..3c94390 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gke_status.go @@ -0,0 +1,12 @@ +package client + +const ( + GKEStatusType = "gkeStatus" + GKEStatusFieldPrivateRequiresTunnel = "privateRequiresTunnel" + GKEStatusFieldUpstreamSpec = "upstreamSpec" +) + +type GKEStatus struct { + PrivateRequiresTunnel *bool `json:"privateRequiresTunnel,omitempty" yaml:"privateRequiresTunnel,omitempty"` + UpstreamSpec *GKEClusterConfigSpec `json:"upstreamSpec,omitempty" yaml:"upstreamSpec,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gkeip_allocation_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gkeip_allocation_policy.go new file mode 100644 index 0000000..140bd42 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_gkeip_allocation_policy.go @@ -0,0 +1,24 @@ +package client + +const ( + GKEIPAllocationPolicyType = "gkeipAllocationPolicy" + GKEIPAllocationPolicyFieldClusterIpv4CidrBlock = "clusterIpv4CidrBlock" + GKEIPAllocationPolicyFieldClusterSecondaryRangeName = "clusterSecondaryRangeName" + GKEIPAllocationPolicyFieldCreateSubnetwork = "createSubnetwork" + GKEIPAllocationPolicyFieldNodeIpv4CidrBlock = "nodeIpv4CidrBlock" + GKEIPAllocationPolicyFieldServicesIpv4CidrBlock = "servicesIpv4CidrBlock" + GKEIPAllocationPolicyFieldServicesSecondaryRangeName = "servicesSecondaryRangeName" + GKEIPAllocationPolicyFieldSubnetworkName = "subnetworkName" + GKEIPAllocationPolicyFieldUseIPAliases = "useIpAliases" +) + +type GKEIPAllocationPolicy struct { + ClusterIpv4CidrBlock string `json:"clusterIpv4CidrBlock,omitempty" yaml:"clusterIpv4CidrBlock,omitempty"` + ClusterSecondaryRangeName string `json:"clusterSecondaryRangeName,omitempty" yaml:"clusterSecondaryRangeName,omitempty"` + CreateSubnetwork bool `json:"createSubnetwork,omitempty" yaml:"createSubnetwork,omitempty"` + NodeIpv4CidrBlock string `json:"nodeIpv4CidrBlock,omitempty" yaml:"nodeIpv4CidrBlock,omitempty"` + ServicesIpv4CidrBlock string `json:"servicesIpv4CidrBlock,omitempty" yaml:"servicesIpv4CidrBlock,omitempty"` + ServicesSecondaryRangeName string `json:"servicesSecondaryRangeName,omitempty" yaml:"servicesSecondaryRangeName,omitempty"` + SubnetworkName string `json:"subnetworkName,omitempty" yaml:"subnetworkName,omitempty"` + UseIPAliases bool `json:"useIpAliases,omitempty" yaml:"useIpAliases,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_aws_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_aws_opts.go new file mode 100644 index 0000000..61965de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_aws_opts.go @@ -0,0 +1,28 @@ +package client + +const ( + GlobalAwsOptsType = "globalAwsOpts" + GlobalAwsOptsFieldDisableSecurityGroupIngress = "disable-security-group-ingress" + GlobalAwsOptsFieldDisableStrictZoneCheck = "disable-strict-zone-check" + GlobalAwsOptsFieldElbSecurityGroup = "elb-security-group" + GlobalAwsOptsFieldKubernetesClusterID = "kubernetes-cluster-id" + GlobalAwsOptsFieldKubernetesClusterTag = "kubernetes-cluster-tag" + GlobalAwsOptsFieldRoleARN = "role-arn" + GlobalAwsOptsFieldRouteTableID = "routetable-id" + GlobalAwsOptsFieldSubnetID = "subnet-id" + GlobalAwsOptsFieldVPC = "vpc" + GlobalAwsOptsFieldZone = "zone" +) + +type GlobalAwsOpts struct { + DisableSecurityGroupIngress bool `json:"disable-security-group-ingress,omitempty" yaml:"disable-security-group-ingress,omitempty"` + DisableStrictZoneCheck bool `json:"disable-strict-zone-check,omitempty" yaml:"disable-strict-zone-check,omitempty"` + ElbSecurityGroup string `json:"elb-security-group,omitempty" yaml:"elb-security-group,omitempty"` + KubernetesClusterID string `json:"kubernetes-cluster-id,omitempty" yaml:"kubernetes-cluster-id,omitempty"` + KubernetesClusterTag string `json:"kubernetes-cluster-tag,omitempty" yaml:"kubernetes-cluster-tag,omitempty"` + RoleARN string `json:"role-arn,omitempty" yaml:"role-arn,omitempty"` + RouteTableID string `json:"routetable-id,omitempty" yaml:"routetable-id,omitempty"` + SubnetID string `json:"subnet-id,omitempty" yaml:"subnet-id,omitempty"` + VPC string `json:"vpc,omitempty" yaml:"vpc,omitempty"` + Zone string `json:"zone,omitempty" yaml:"zone,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns.go new file mode 100644 index 0000000..2de8450 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns.go @@ -0,0 +1,152 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GlobalDnsType = "globalDns" + GlobalDnsFieldAnnotations = "annotations" + GlobalDnsFieldCreated = "created" + GlobalDnsFieldCreatorID = "creatorId" + GlobalDnsFieldFQDN = "fqdn" + GlobalDnsFieldLabels = "labels" + GlobalDnsFieldMembers = "members" + GlobalDnsFieldMultiClusterAppID = "multiClusterAppId" + GlobalDnsFieldName = "name" + GlobalDnsFieldOwnerReferences = "ownerReferences" + GlobalDnsFieldProjectIDs = "projectIds" + GlobalDnsFieldProviderID = "providerId" + GlobalDnsFieldRemoved = "removed" + GlobalDnsFieldState = "state" + GlobalDnsFieldStatus = "status" + GlobalDnsFieldTTL = "ttl" + GlobalDnsFieldTransitioning = "transitioning" + GlobalDnsFieldTransitioningMessage = "transitioningMessage" + GlobalDnsFieldUUID = "uuid" +) + +type GlobalDns struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + FQDN string `json:"fqdn,omitempty" yaml:"fqdn,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + MultiClusterAppID string `json:"multiClusterAppId,omitempty" yaml:"multiClusterAppId,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectIDs []string `json:"projectIds,omitempty" yaml:"projectIds,omitempty"` + ProviderID string `json:"providerId,omitempty" yaml:"providerId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *GlobalDNSStatus `json:"status,omitempty" yaml:"status,omitempty"` + TTL int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type GlobalDnsCollection struct { + types.Collection + Data []GlobalDns `json:"data,omitempty"` + client *GlobalDnsClient +} + +type GlobalDnsClient struct { + apiClient *Client +} + +type GlobalDnsOperations interface { + List(opts *types.ListOpts) (*GlobalDnsCollection, error) + ListAll(opts *types.ListOpts) (*GlobalDnsCollection, error) + Create(opts *GlobalDns) (*GlobalDns, error) + Update(existing *GlobalDns, updates interface{}) (*GlobalDns, error) + Replace(existing *GlobalDns) (*GlobalDns, error) + ByID(id string) (*GlobalDns, error) + Delete(container *GlobalDns) error + + ActionAddProjects(resource *GlobalDns, input *UpdateGlobalDNSTargetsInput) error + + ActionRemoveProjects(resource *GlobalDns, input *UpdateGlobalDNSTargetsInput) error +} + +func newGlobalDnsClient(apiClient *Client) *GlobalDnsClient { + return &GlobalDnsClient{ + apiClient: apiClient, + } +} + +func (c *GlobalDnsClient) Create(container *GlobalDns) (*GlobalDns, error) { + resp := &GlobalDns{} + err := c.apiClient.Ops.DoCreate(GlobalDnsType, container, resp) + return resp, err +} + +func (c *GlobalDnsClient) Update(existing *GlobalDns, updates interface{}) (*GlobalDns, error) { + resp := &GlobalDns{} + err := c.apiClient.Ops.DoUpdate(GlobalDnsType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GlobalDnsClient) Replace(obj *GlobalDns) (*GlobalDns, error) { + resp := &GlobalDns{} + err := c.apiClient.Ops.DoReplace(GlobalDnsType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GlobalDnsClient) List(opts *types.ListOpts) (*GlobalDnsCollection, error) { + resp := &GlobalDnsCollection{} + err := c.apiClient.Ops.DoList(GlobalDnsType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GlobalDnsClient) ListAll(opts *types.ListOpts) (*GlobalDnsCollection, error) { + resp := &GlobalDnsCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GlobalDnsCollection) Next() (*GlobalDnsCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GlobalDnsCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GlobalDnsClient) ByID(id string) (*GlobalDns, error) { + resp := &GlobalDns{} + err := c.apiClient.Ops.DoByID(GlobalDnsType, id, resp) + return resp, err +} + +func (c *GlobalDnsClient) Delete(container *GlobalDns) error { + return c.apiClient.Ops.DoResourceDelete(GlobalDnsType, &container.Resource) +} + +func (c *GlobalDnsClient) ActionAddProjects(resource *GlobalDns, input *UpdateGlobalDNSTargetsInput) error { + err := c.apiClient.Ops.DoAction(GlobalDnsType, "addProjects", &resource.Resource, input, nil) + return err +} + +func (c *GlobalDnsClient) ActionRemoveProjects(resource *GlobalDns, input *UpdateGlobalDNSTargetsInput) error { + err := c.apiClient.Ops.DoAction(GlobalDnsType, "removeProjects", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider.go new file mode 100644 index 0000000..951b228 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GlobalDnsProviderType = "globalDnsProvider" + GlobalDnsProviderFieldAlidnsProviderConfig = "alidnsProviderConfig" + GlobalDnsProviderFieldAnnotations = "annotations" + GlobalDnsProviderFieldCloudflareProviderConfig = "cloudflareProviderConfig" + GlobalDnsProviderFieldCreated = "created" + GlobalDnsProviderFieldCreatorID = "creatorId" + GlobalDnsProviderFieldLabels = "labels" + GlobalDnsProviderFieldMembers = "members" + GlobalDnsProviderFieldName = "name" + GlobalDnsProviderFieldOwnerReferences = "ownerReferences" + GlobalDnsProviderFieldRemoved = "removed" + GlobalDnsProviderFieldRootDomain = "rootDomain" + GlobalDnsProviderFieldRoute53ProviderConfig = "route53ProviderConfig" + GlobalDnsProviderFieldUUID = "uuid" +) + +type GlobalDnsProvider struct { + types.Resource + AlidnsProviderConfig *AlidnsProviderConfig `json:"alidnsProviderConfig,omitempty" yaml:"alidnsProviderConfig,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CloudflareProviderConfig *CloudflareProviderConfig `json:"cloudflareProviderConfig,omitempty" yaml:"cloudflareProviderConfig,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RootDomain string `json:"rootDomain,omitempty" yaml:"rootDomain,omitempty"` + Route53ProviderConfig *Route53ProviderConfig `json:"route53ProviderConfig,omitempty" yaml:"route53ProviderConfig,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type GlobalDnsProviderCollection struct { + types.Collection + Data []GlobalDnsProvider `json:"data,omitempty"` + client *GlobalDnsProviderClient +} + +type GlobalDnsProviderClient struct { + apiClient *Client +} + +type GlobalDnsProviderOperations interface { + List(opts *types.ListOpts) (*GlobalDnsProviderCollection, error) + ListAll(opts *types.ListOpts) (*GlobalDnsProviderCollection, error) + Create(opts *GlobalDnsProvider) (*GlobalDnsProvider, error) + Update(existing *GlobalDnsProvider, updates interface{}) (*GlobalDnsProvider, error) + Replace(existing *GlobalDnsProvider) (*GlobalDnsProvider, error) + ByID(id string) (*GlobalDnsProvider, error) + Delete(container *GlobalDnsProvider) error +} + +func newGlobalDnsProviderClient(apiClient *Client) *GlobalDnsProviderClient { + return &GlobalDnsProviderClient{ + apiClient: apiClient, + } +} + +func (c *GlobalDnsProviderClient) Create(container *GlobalDnsProvider) (*GlobalDnsProvider, error) { + resp := &GlobalDnsProvider{} + err := c.apiClient.Ops.DoCreate(GlobalDnsProviderType, container, resp) + return resp, err +} + +func (c *GlobalDnsProviderClient) Update(existing *GlobalDnsProvider, updates interface{}) (*GlobalDnsProvider, error) { + resp := &GlobalDnsProvider{} + err := c.apiClient.Ops.DoUpdate(GlobalDnsProviderType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GlobalDnsProviderClient) Replace(obj *GlobalDnsProvider) (*GlobalDnsProvider, error) { + resp := &GlobalDnsProvider{} + err := c.apiClient.Ops.DoReplace(GlobalDnsProviderType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GlobalDnsProviderClient) List(opts *types.ListOpts) (*GlobalDnsProviderCollection, error) { + resp := &GlobalDnsProviderCollection{} + err := c.apiClient.Ops.DoList(GlobalDnsProviderType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GlobalDnsProviderClient) ListAll(opts *types.ListOpts) (*GlobalDnsProviderCollection, error) { + resp := &GlobalDnsProviderCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GlobalDnsProviderCollection) Next() (*GlobalDnsProviderCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GlobalDnsProviderCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GlobalDnsProviderClient) ByID(id string) (*GlobalDnsProvider, error) { + resp := &GlobalDnsProvider{} + err := c.apiClient.Ops.DoByID(GlobalDnsProviderType, id, resp) + return resp, err +} + +func (c *GlobalDnsProviderClient) Delete(container *GlobalDnsProvider) error { + return c.apiClient.Ops.DoResourceDelete(GlobalDnsProviderType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider_spec.go new file mode 100644 index 0000000..b5f1157 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_provider_spec.go @@ -0,0 +1,18 @@ +package client + +const ( + GlobalDNSProviderSpecType = "globalDnsProviderSpec" + GlobalDNSProviderSpecFieldAlidnsProviderConfig = "alidnsProviderConfig" + GlobalDNSProviderSpecFieldCloudflareProviderConfig = "cloudflareProviderConfig" + GlobalDNSProviderSpecFieldMembers = "members" + GlobalDNSProviderSpecFieldRootDomain = "rootDomain" + GlobalDNSProviderSpecFieldRoute53ProviderConfig = "route53ProviderConfig" +) + +type GlobalDNSProviderSpec struct { + AlidnsProviderConfig *AlidnsProviderConfig `json:"alidnsProviderConfig,omitempty" yaml:"alidnsProviderConfig,omitempty"` + CloudflareProviderConfig *CloudflareProviderConfig `json:"cloudflareProviderConfig,omitempty" yaml:"cloudflareProviderConfig,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + RootDomain string `json:"rootDomain,omitempty" yaml:"rootDomain,omitempty"` + Route53ProviderConfig *Route53ProviderConfig `json:"route53ProviderConfig,omitempty" yaml:"route53ProviderConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_spec.go new file mode 100644 index 0000000..3f22ef2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_spec.go @@ -0,0 +1,20 @@ +package client + +const ( + GlobalDNSSpecType = "globalDnsSpec" + GlobalDNSSpecFieldFQDN = "fqdn" + GlobalDNSSpecFieldMembers = "members" + GlobalDNSSpecFieldMultiClusterAppID = "multiClusterAppId" + GlobalDNSSpecFieldProjectIDs = "projectIds" + GlobalDNSSpecFieldProviderID = "providerId" + GlobalDNSSpecFieldTTL = "ttl" +) + +type GlobalDNSSpec struct { + FQDN string `json:"fqdn,omitempty" yaml:"fqdn,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + MultiClusterAppID string `json:"multiClusterAppId,omitempty" yaml:"multiClusterAppId,omitempty"` + ProjectIDs []string `json:"projectIds,omitempty" yaml:"projectIds,omitempty"` + ProviderID string `json:"providerId,omitempty" yaml:"providerId,omitempty"` + TTL int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_status.go new file mode 100644 index 0000000..d37181a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_dns_status.go @@ -0,0 +1,12 @@ +package client + +const ( + GlobalDNSStatusType = "globalDnsStatus" + GlobalDNSStatusFieldClusterEndpoints = "clusterEndpoints" + GlobalDNSStatusFieldEndpoints = "endpoints" +) + +type GlobalDNSStatus struct { + ClusterEndpoints map[string][]string `json:"clusterEndpoints,omitempty" yaml:"clusterEndpoints,omitempty"` + Endpoints []string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_openstack_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_openstack_opts.go new file mode 100644 index 0000000..7db5e17 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_openstack_opts.go @@ -0,0 +1,30 @@ +package client + +const ( + GlobalOpenstackOptsType = "globalOpenstackOpts" + GlobalOpenstackOptsFieldAuthURL = "auth-url" + GlobalOpenstackOptsFieldCAFile = "ca-file" + GlobalOpenstackOptsFieldDomainID = "domain-id" + GlobalOpenstackOptsFieldDomainName = "domain-name" + GlobalOpenstackOptsFieldPassword = "password" + GlobalOpenstackOptsFieldRegion = "region" + GlobalOpenstackOptsFieldTenantID = "tenant-id" + GlobalOpenstackOptsFieldTenantName = "tenant-name" + GlobalOpenstackOptsFieldTrustID = "trust-id" + GlobalOpenstackOptsFieldUserID = "user-id" + GlobalOpenstackOptsFieldUsername = "username" +) + +type GlobalOpenstackOpts struct { + AuthURL string `json:"auth-url,omitempty" yaml:"auth-url,omitempty"` + CAFile string `json:"ca-file,omitempty" yaml:"ca-file,omitempty"` + DomainID string `json:"domain-id,omitempty" yaml:"domain-id,omitempty"` + DomainName string `json:"domain-name,omitempty" yaml:"domain-name,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Region string `json:"region,omitempty" yaml:"region,omitempty"` + TenantID string `json:"tenant-id,omitempty" yaml:"tenant-id,omitempty"` + TenantName string `json:"tenant-name,omitempty" yaml:"tenant-name,omitempty"` + TrustID string `json:"trust-id,omitempty" yaml:"trust-id,omitempty"` + UserID string `json:"user-id,omitempty" yaml:"user-id,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role.go new file mode 100644 index 0000000..f528984 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role.go @@ -0,0 +1,134 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GlobalRoleType = "globalRole" + GlobalRoleFieldAnnotations = "annotations" + GlobalRoleFieldBuiltin = "builtin" + GlobalRoleFieldCreated = "created" + GlobalRoleFieldCreatorID = "creatorId" + GlobalRoleFieldDescription = "description" + GlobalRoleFieldInheritedClusterRoles = "inheritedClusterRoles" + GlobalRoleFieldInheritedFleetWorkspacePermissions = "inheritedFleetWorkspacePermissions" + GlobalRoleFieldLabels = "labels" + GlobalRoleFieldName = "name" + GlobalRoleFieldNamespacedRules = "namespacedRules" + GlobalRoleFieldNewUserDefault = "newUserDefault" + GlobalRoleFieldOwnerReferences = "ownerReferences" + GlobalRoleFieldRemoved = "removed" + GlobalRoleFieldRules = "rules" + GlobalRoleFieldStatus = "status" + GlobalRoleFieldUUID = "uuid" +) + +type GlobalRole struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Builtin bool `json:"builtin,omitempty" yaml:"builtin,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + InheritedClusterRoles []string `json:"inheritedClusterRoles,omitempty" yaml:"inheritedClusterRoles,omitempty"` + InheritedFleetWorkspacePermissions *FleetWorkspacePermission `json:"inheritedFleetWorkspacePermissions,omitempty" yaml:"inheritedFleetWorkspacePermissions,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespacedRules map[string][]PolicyRule `json:"namespacedRules,omitempty" yaml:"namespacedRules,omitempty"` + NewUserDefault bool `json:"newUserDefault,omitempty" yaml:"newUserDefault,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Rules []PolicyRule `json:"rules,omitempty" yaml:"rules,omitempty"` + Status GlobalRoleStatus `json:"status,omitempty" yaml:"status,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type GlobalRoleCollection struct { + types.Collection + Data []GlobalRole `json:"data,omitempty"` + client *GlobalRoleClient +} + +type GlobalRoleClient struct { + apiClient *Client +} + +type GlobalRoleOperations interface { + List(opts *types.ListOpts) (*GlobalRoleCollection, error) + ListAll(opts *types.ListOpts) (*GlobalRoleCollection, error) + Create(opts *GlobalRole) (*GlobalRole, error) + Update(existing *GlobalRole, updates interface{}) (*GlobalRole, error) + Replace(existing *GlobalRole) (*GlobalRole, error) + ByID(id string) (*GlobalRole, error) + Delete(container *GlobalRole) error +} + +func newGlobalRoleClient(apiClient *Client) *GlobalRoleClient { + return &GlobalRoleClient{ + apiClient: apiClient, + } +} + +func (c *GlobalRoleClient) Create(container *GlobalRole) (*GlobalRole, error) { + resp := &GlobalRole{} + err := c.apiClient.Ops.DoCreate(GlobalRoleType, container, resp) + return resp, err +} + +func (c *GlobalRoleClient) Update(existing *GlobalRole, updates interface{}) (*GlobalRole, error) { + resp := &GlobalRole{} + err := c.apiClient.Ops.DoUpdate(GlobalRoleType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GlobalRoleClient) Replace(obj *GlobalRole) (*GlobalRole, error) { + resp := &GlobalRole{} + err := c.apiClient.Ops.DoReplace(GlobalRoleType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GlobalRoleClient) List(opts *types.ListOpts) (*GlobalRoleCollection, error) { + resp := &GlobalRoleCollection{} + err := c.apiClient.Ops.DoList(GlobalRoleType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GlobalRoleClient) ListAll(opts *types.ListOpts) (*GlobalRoleCollection, error) { + resp := &GlobalRoleCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GlobalRoleCollection) Next() (*GlobalRoleCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GlobalRoleCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GlobalRoleClient) ByID(id string) (*GlobalRole, error) { + resp := &GlobalRole{} + err := c.apiClient.Ops.DoByID(GlobalRoleType, id, resp) + return resp, err +} + +func (c *GlobalRoleClient) Delete(container *GlobalRole) error { + return c.apiClient.Ops.DoResourceDelete(GlobalRoleType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_binding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_binding.go new file mode 100644 index 0000000..0d447d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_binding.go @@ -0,0 +1,124 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GlobalRoleBindingType = "globalRoleBinding" + GlobalRoleBindingFieldAnnotations = "annotations" + GlobalRoleBindingFieldCreated = "created" + GlobalRoleBindingFieldCreatorID = "creatorId" + GlobalRoleBindingFieldGlobalRoleID = "globalRoleId" + GlobalRoleBindingFieldGroupPrincipalID = "groupPrincipalId" + GlobalRoleBindingFieldLabels = "labels" + GlobalRoleBindingFieldName = "name" + GlobalRoleBindingFieldOwnerReferences = "ownerReferences" + GlobalRoleBindingFieldRemoved = "removed" + GlobalRoleBindingFieldUUID = "uuid" + GlobalRoleBindingFieldUserID = "userId" +) + +type GlobalRoleBinding struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + GlobalRoleID string `json:"globalRoleId,omitempty" yaml:"globalRoleId,omitempty"` + GroupPrincipalID string `json:"groupPrincipalId,omitempty" yaml:"groupPrincipalId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserID string `json:"userId,omitempty" yaml:"userId,omitempty"` +} + +type GlobalRoleBindingCollection struct { + types.Collection + Data []GlobalRoleBinding `json:"data,omitempty"` + client *GlobalRoleBindingClient +} + +type GlobalRoleBindingClient struct { + apiClient *Client +} + +type GlobalRoleBindingOperations interface { + List(opts *types.ListOpts) (*GlobalRoleBindingCollection, error) + ListAll(opts *types.ListOpts) (*GlobalRoleBindingCollection, error) + Create(opts *GlobalRoleBinding) (*GlobalRoleBinding, error) + Update(existing *GlobalRoleBinding, updates interface{}) (*GlobalRoleBinding, error) + Replace(existing *GlobalRoleBinding) (*GlobalRoleBinding, error) + ByID(id string) (*GlobalRoleBinding, error) + Delete(container *GlobalRoleBinding) error +} + +func newGlobalRoleBindingClient(apiClient *Client) *GlobalRoleBindingClient { + return &GlobalRoleBindingClient{ + apiClient: apiClient, + } +} + +func (c *GlobalRoleBindingClient) Create(container *GlobalRoleBinding) (*GlobalRoleBinding, error) { + resp := &GlobalRoleBinding{} + err := c.apiClient.Ops.DoCreate(GlobalRoleBindingType, container, resp) + return resp, err +} + +func (c *GlobalRoleBindingClient) Update(existing *GlobalRoleBinding, updates interface{}) (*GlobalRoleBinding, error) { + resp := &GlobalRoleBinding{} + err := c.apiClient.Ops.DoUpdate(GlobalRoleBindingType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GlobalRoleBindingClient) Replace(obj *GlobalRoleBinding) (*GlobalRoleBinding, error) { + resp := &GlobalRoleBinding{} + err := c.apiClient.Ops.DoReplace(GlobalRoleBindingType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GlobalRoleBindingClient) List(opts *types.ListOpts) (*GlobalRoleBindingCollection, error) { + resp := &GlobalRoleBindingCollection{} + err := c.apiClient.Ops.DoList(GlobalRoleBindingType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GlobalRoleBindingClient) ListAll(opts *types.ListOpts) (*GlobalRoleBindingCollection, error) { + resp := &GlobalRoleBindingCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GlobalRoleBindingCollection) Next() (*GlobalRoleBindingCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GlobalRoleBindingCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GlobalRoleBindingClient) ByID(id string) (*GlobalRoleBinding, error) { + resp := &GlobalRoleBinding{} + err := c.apiClient.Ops.DoByID(GlobalRoleBindingType, id, resp) + return resp, err +} + +func (c *GlobalRoleBindingClient) Delete(container *GlobalRoleBinding) error { + return c.apiClient.Ops.DoResourceDelete(GlobalRoleBindingType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_status.go new file mode 100644 index 0000000..2e90c1e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_role_status.go @@ -0,0 +1,16 @@ +package client + +const ( + GlobalRoleStatusType = "globalRoleStatus" + GlobalRoleStatusFieldConditions = "conditions" + GlobalRoleStatusFieldLastUpdate = "lastUpdateTime" + GlobalRoleStatusFieldObservedGeneration = "observedGeneration" + GlobalRoleStatusFieldSummary = "summary" +) + +type GlobalRoleStatus struct { + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + LastUpdate string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_vsphere_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_vsphere_opts.go new file mode 100644 index 0000000..3b515a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_global_vsphere_opts.go @@ -0,0 +1,32 @@ +package client + +const ( + GlobalVsphereOptsType = "globalVsphereOpts" + GlobalVsphereOptsFieldDatacenter = "datacenter" + GlobalVsphereOptsFieldDatacenters = "datacenters" + GlobalVsphereOptsFieldDefaultDatastore = "datastore" + GlobalVsphereOptsFieldInsecureFlag = "insecure-flag" + GlobalVsphereOptsFieldPassword = "password" + GlobalVsphereOptsFieldRoundTripperCount = "soap-roundtrip-count" + GlobalVsphereOptsFieldUser = "user" + GlobalVsphereOptsFieldVCenterIP = "server" + GlobalVsphereOptsFieldVCenterPort = "port" + GlobalVsphereOptsFieldVMName = "vm-name" + GlobalVsphereOptsFieldVMUUID = "vm-uuid" + GlobalVsphereOptsFieldWorkingDir = "working-dir" +) + +type GlobalVsphereOpts struct { + Datacenter string `json:"datacenter,omitempty" yaml:"datacenter,omitempty"` + Datacenters string `json:"datacenters,omitempty" yaml:"datacenters,omitempty"` + DefaultDatastore string `json:"datastore,omitempty" yaml:"datastore,omitempty"` + InsecureFlag bool `json:"insecure-flag,omitempty" yaml:"insecure-flag,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + RoundTripperCount int64 `json:"soap-roundtrip-count,omitempty" yaml:"soap-roundtrip-count,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + VCenterIP string `json:"server,omitempty" yaml:"server,omitempty"` + VCenterPort string `json:"port,omitempty" yaml:"port,omitempty"` + VMName string `json:"vm-name,omitempty" yaml:"vm-name,omitempty"` + VMUUID string `json:"vm-uuid,omitempty" yaml:"vm-uuid,omitempty"` + WorkingDir string `json:"working-dir,omitempty" yaml:"working-dir,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_glusterfs_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_glusterfs_volume_source.go new file mode 100644 index 0000000..fa5900b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_glusterfs_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + GlusterfsVolumeSourceType = "glusterfsVolumeSource" + GlusterfsVolumeSourceFieldEndpointsName = "endpoints" + GlusterfsVolumeSourceFieldPath = "path" + GlusterfsVolumeSourceFieldReadOnly = "readOnly" +) + +type GlusterfsVolumeSource struct { + EndpointsName string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config.go new file mode 100644 index 0000000..f441422 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config.go @@ -0,0 +1,46 @@ +package client + +const ( + GoogleOauthConfigType = "googleOauthConfig" + GoogleOauthConfigFieldAccessMode = "accessMode" + GoogleOauthConfigFieldAdminEmail = "adminEmail" + GoogleOauthConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + GoogleOauthConfigFieldAnnotations = "annotations" + GoogleOauthConfigFieldCreated = "created" + GoogleOauthConfigFieldCreatorID = "creatorId" + GoogleOauthConfigFieldEnabled = "enabled" + GoogleOauthConfigFieldHostname = "hostname" + GoogleOauthConfigFieldLabels = "labels" + GoogleOauthConfigFieldName = "name" + GoogleOauthConfigFieldNestedGroupMembershipEnabled = "nestedGroupMembershipEnabled" + GoogleOauthConfigFieldOauthCredential = "oauthCredential" + GoogleOauthConfigFieldOwnerReferences = "ownerReferences" + GoogleOauthConfigFieldRemoved = "removed" + GoogleOauthConfigFieldServiceAccountCredential = "serviceAccountCredential" + GoogleOauthConfigFieldStatus = "status" + GoogleOauthConfigFieldType = "type" + GoogleOauthConfigFieldUUID = "uuid" + GoogleOauthConfigFieldUserInfoEndpoint = "userInfoEndpoint" +) + +type GoogleOauthConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AdminEmail string `json:"adminEmail,omitempty" yaml:"adminEmail,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled,omitempty" yaml:"nestedGroupMembershipEnabled,omitempty"` + OauthCredential string `json:"oauthCredential,omitempty" yaml:"oauthCredential,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ServiceAccountCredential string `json:"serviceAccountCredential,omitempty" yaml:"serviceAccountCredential,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserInfoEndpoint string `json:"userInfoEndpoint,omitempty" yaml:"userInfoEndpoint,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_apply_input.go new file mode 100644 index 0000000..9b5d8c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_apply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + GoogleOauthConfigApplyInputType = "googleOauthConfigApplyInput" + GoogleOauthConfigApplyInputFieldCode = "code" + GoogleOauthConfigApplyInputFieldEnabled = "enabled" + GoogleOauthConfigApplyInputFieldGoogleOauthConfig = "googleOauthConfig" +) + +type GoogleOauthConfigApplyInput struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GoogleOauthConfig *GoogleOauthConfig `json:"googleOauthConfig,omitempty" yaml:"googleOauthConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_test_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_test_output.go new file mode 100644 index 0000000..941108c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_google_oauth_config_test_output.go @@ -0,0 +1,10 @@ +package client + +const ( + GoogleOauthConfigTestOutputType = "googleOauthConfigTestOutput" + GoogleOauthConfigTestOutputFieldRedirectURL = "redirectUrl" +) + +type GoogleOauthConfigTestOutput struct { + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group.go new file mode 100644 index 0000000..f14da72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group.go @@ -0,0 +1,118 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GroupType = "group" + GroupFieldAnnotations = "annotations" + GroupFieldCreated = "created" + GroupFieldCreatorID = "creatorId" + GroupFieldLabels = "labels" + GroupFieldName = "name" + GroupFieldOwnerReferences = "ownerReferences" + GroupFieldRemoved = "removed" + GroupFieldUUID = "uuid" +) + +type Group struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type GroupCollection struct { + types.Collection + Data []Group `json:"data,omitempty"` + client *GroupClient +} + +type GroupClient struct { + apiClient *Client +} + +type GroupOperations interface { + List(opts *types.ListOpts) (*GroupCollection, error) + ListAll(opts *types.ListOpts) (*GroupCollection, error) + Create(opts *Group) (*Group, error) + Update(existing *Group, updates interface{}) (*Group, error) + Replace(existing *Group) (*Group, error) + ByID(id string) (*Group, error) + Delete(container *Group) error +} + +func newGroupClient(apiClient *Client) *GroupClient { + return &GroupClient{ + apiClient: apiClient, + } +} + +func (c *GroupClient) Create(container *Group) (*Group, error) { + resp := &Group{} + err := c.apiClient.Ops.DoCreate(GroupType, container, resp) + return resp, err +} + +func (c *GroupClient) Update(existing *Group, updates interface{}) (*Group, error) { + resp := &Group{} + err := c.apiClient.Ops.DoUpdate(GroupType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GroupClient) Replace(obj *Group) (*Group, error) { + resp := &Group{} + err := c.apiClient.Ops.DoReplace(GroupType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GroupClient) List(opts *types.ListOpts) (*GroupCollection, error) { + resp := &GroupCollection{} + err := c.apiClient.Ops.DoList(GroupType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GroupClient) ListAll(opts *types.ListOpts) (*GroupCollection, error) { + resp := &GroupCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GroupCollection) Next() (*GroupCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GroupCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GroupClient) ByID(id string) (*Group, error) { + resp := &Group{} + err := c.apiClient.Ops.DoByID(GroupType, id, resp) + return resp, err +} + +func (c *GroupClient) Delete(container *Group) error { + return c.apiClient.Ops.DoResourceDelete(GroupType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group_member.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group_member.go new file mode 100644 index 0000000..bbcfe34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_group_member.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + GroupMemberType = "groupMember" + GroupMemberFieldAnnotations = "annotations" + GroupMemberFieldCreated = "created" + GroupMemberFieldCreatorID = "creatorId" + GroupMemberFieldGroupID = "groupId" + GroupMemberFieldLabels = "labels" + GroupMemberFieldName = "name" + GroupMemberFieldOwnerReferences = "ownerReferences" + GroupMemberFieldPrincipalID = "principalId" + GroupMemberFieldRemoved = "removed" + GroupMemberFieldUUID = "uuid" +) + +type GroupMember struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + GroupID string `json:"groupId,omitempty" yaml:"groupId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrincipalID string `json:"principalId,omitempty" yaml:"principalId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type GroupMemberCollection struct { + types.Collection + Data []GroupMember `json:"data,omitempty"` + client *GroupMemberClient +} + +type GroupMemberClient struct { + apiClient *Client +} + +type GroupMemberOperations interface { + List(opts *types.ListOpts) (*GroupMemberCollection, error) + ListAll(opts *types.ListOpts) (*GroupMemberCollection, error) + Create(opts *GroupMember) (*GroupMember, error) + Update(existing *GroupMember, updates interface{}) (*GroupMember, error) + Replace(existing *GroupMember) (*GroupMember, error) + ByID(id string) (*GroupMember, error) + Delete(container *GroupMember) error +} + +func newGroupMemberClient(apiClient *Client) *GroupMemberClient { + return &GroupMemberClient{ + apiClient: apiClient, + } +} + +func (c *GroupMemberClient) Create(container *GroupMember) (*GroupMember, error) { + resp := &GroupMember{} + err := c.apiClient.Ops.DoCreate(GroupMemberType, container, resp) + return resp, err +} + +func (c *GroupMemberClient) Update(existing *GroupMember, updates interface{}) (*GroupMember, error) { + resp := &GroupMember{} + err := c.apiClient.Ops.DoUpdate(GroupMemberType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *GroupMemberClient) Replace(obj *GroupMember) (*GroupMember, error) { + resp := &GroupMember{} + err := c.apiClient.Ops.DoReplace(GroupMemberType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *GroupMemberClient) List(opts *types.ListOpts) (*GroupMemberCollection, error) { + resp := &GroupMemberCollection{} + err := c.apiClient.Ops.DoList(GroupMemberType, opts, resp) + resp.client = c + return resp, err +} + +func (c *GroupMemberClient) ListAll(opts *types.ListOpts) (*GroupMemberCollection, error) { + resp := &GroupMemberCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *GroupMemberCollection) Next() (*GroupMemberCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &GroupMemberCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *GroupMemberClient) ByID(id string) (*GroupMember, error) { + resp := &GroupMember{} + err := c.apiClient.Ops.DoByID(GroupMemberType, id, resp) + return resp, err +} + +func (c *GroupMemberClient) Delete(container *GroupMember) error { + return c.apiClient.Ops.DoResourceDelete(GroupMemberType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_harvester_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_harvester_cloud_provider.go new file mode 100644 index 0000000..4075744 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_harvester_cloud_provider.go @@ -0,0 +1,10 @@ +package client + +const ( + HarvesterCloudProviderType = "harvesterCloudProvider" + HarvesterCloudProviderFieldCloudConfig = "cloudConfig" +) + +type HarvesterCloudProvider struct { + CloudConfig string `json:"cloudConfig,omitempty" yaml:"cloudConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_health_check.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_health_check.go new file mode 100644 index 0000000..b7e8e5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_health_check.go @@ -0,0 +1,10 @@ +package client + +const ( + HealthCheckType = "healthCheck" + HealthCheckFieldURL = "url" +) + +type HealthCheck struct { + URL string `json:"url,omitempty" yaml:"url,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_host_path_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_host_path_volume_source.go new file mode 100644 index 0000000..cbeffd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_host_path_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + HostPathVolumeSourceType = "hostPathVolumeSource" + HostPathVolumeSourceFieldPath = "path" + HostPathVolumeSourceFieldType = "type" +) + +type HostPathVolumeSource struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_identity_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_identity_configuration.go new file mode 100644 index 0000000..1cc371d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_identity_configuration.go @@ -0,0 +1,8 @@ +package client + +const ( + IdentityConfigurationType = "identityConfiguration" +) + +type IdentityConfiguration struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_cluster_yaml_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_cluster_yaml_input.go new file mode 100644 index 0000000..4bc3625 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_cluster_yaml_input.go @@ -0,0 +1,16 @@ +package client + +const ( + ImportClusterYamlInputType = "importClusterYamlInput" + ImportClusterYamlInputFieldDefaultNamespace = "defaultNamespace" + ImportClusterYamlInputFieldNamespace = "namespace" + ImportClusterYamlInputFieldProjectID = "projectId" + ImportClusterYamlInputFieldYAML = "yaml" +) + +type ImportClusterYamlInput struct { + DefaultNamespace string `json:"defaultNamespace,omitempty" yaml:"defaultNamespace,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + YAML string `json:"yaml,omitempty" yaml:"yaml,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_yaml_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_yaml_output.go new file mode 100644 index 0000000..7b4a285 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_import_yaml_output.go @@ -0,0 +1,10 @@ +package client + +const ( + ImportYamlOutputType = "importYamlOutput" + ImportYamlOutputFieldMessage = "message" +) + +type ImportYamlOutput struct { + Message string `json:"message,omitempty" yaml:"message,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_imported_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_imported_config.go new file mode 100644 index 0000000..b3a9699 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_imported_config.go @@ -0,0 +1,10 @@ +package client + +const ( + ImportedConfigType = "importedConfig" + ImportedConfigFieldKubeConfig = "kubeConfig" +) + +type ImportedConfig struct { + KubeConfig string `json:"kubeConfig,omitempty" yaml:"kubeConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_info.go new file mode 100644 index 0000000..1f37151 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_info.go @@ -0,0 +1,26 @@ +package client + +const ( + InfoType = "info" + InfoFieldBuildDate = "buildDate" + InfoFieldCompiler = "compiler" + InfoFieldGitCommit = "gitCommit" + InfoFieldGitTreeState = "gitTreeState" + InfoFieldGitVersion = "gitVersion" + InfoFieldGoVersion = "goVersion" + InfoFieldMajor = "major" + InfoFieldMinor = "minor" + InfoFieldPlatform = "platform" +) + +type Info struct { + BuildDate string `json:"buildDate,omitempty" yaml:"buildDate,omitempty"` + Compiler string `json:"compiler,omitempty" yaml:"compiler,omitempty"` + GitCommit string `json:"gitCommit,omitempty" yaml:"gitCommit,omitempty"` + GitTreeState string `json:"gitTreeState,omitempty" yaml:"gitTreeState,omitempty"` + GitVersion string `json:"gitVersion,omitempty" yaml:"gitVersion,omitempty"` + GoVersion string `json:"goVersion,omitempty" yaml:"goVersion,omitempty"` + Major string `json:"major,omitempty" yaml:"major,omitempty"` + Minor string `json:"minor,omitempty" yaml:"minor,omitempty"` + Platform string `json:"platform,omitempty" yaml:"platform,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_capabilities.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_capabilities.go new file mode 100644 index 0000000..ff678cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_capabilities.go @@ -0,0 +1,12 @@ +package client + +const ( + IngressCapabilitiesType = "ingressCapabilities" + IngressCapabilitiesFieldCustomDefaultBackend = "customDefaultBackend" + IngressCapabilitiesFieldIngressProvider = "ingressProvider" +) + +type IngressCapabilities struct { + CustomDefaultBackend *bool `json:"customDefaultBackend,omitempty" yaml:"customDefaultBackend,omitempty"` + IngressProvider string `json:"ingressProvider,omitempty" yaml:"ingressProvider,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_config.go new file mode 100644 index 0000000..ac10579 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ingress_config.go @@ -0,0 +1,42 @@ +package client + +const ( + IngressConfigType = "ingressConfig" + IngressConfigFieldDNSPolicy = "dnsPolicy" + IngressConfigFieldDefaultBackend = "defaultBackend" + IngressConfigFieldDefaultHTTPBackendPriorityClassName = "defaultHttpBackendPriorityClassName" + IngressConfigFieldDefaultIngressClass = "defaultIngressClass" + IngressConfigFieldExtraArgs = "extraArgs" + IngressConfigFieldExtraEnvs = "extraEnvs" + IngressConfigFieldExtraVolumeMounts = "extraVolumeMounts" + IngressConfigFieldExtraVolumes = "extraVolumes" + IngressConfigFieldHTTPPort = "httpPort" + IngressConfigFieldHTTPSPort = "httpsPort" + IngressConfigFieldNetworkMode = "networkMode" + IngressConfigFieldNginxIngressControllerPriorityClassName = "nginxIngressControllerPriorityClassName" + IngressConfigFieldNodeSelector = "nodeSelector" + IngressConfigFieldOptions = "options" + IngressConfigFieldProvider = "provider" + IngressConfigFieldTolerations = "tolerations" + IngressConfigFieldUpdateStrategy = "updateStrategy" +) + +type IngressConfig struct { + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DefaultBackend *bool `json:"defaultBackend,omitempty" yaml:"defaultBackend,omitempty"` + DefaultHTTPBackendPriorityClassName string `json:"defaultHttpBackendPriorityClassName,omitempty" yaml:"defaultHttpBackendPriorityClassName,omitempty"` + DefaultIngressClass *bool `json:"defaultIngressClass,omitempty" yaml:"defaultIngressClass,omitempty"` + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraEnvs []interface{} `json:"extraEnvs,omitempty" yaml:"extraEnvs,omitempty"` + ExtraVolumeMounts []interface{} `json:"extraVolumeMounts,omitempty" yaml:"extraVolumeMounts,omitempty"` + ExtraVolumes []interface{} `json:"extraVolumes,omitempty" yaml:"extraVolumes,omitempty"` + HTTPPort int64 `json:"httpPort,omitempty" yaml:"httpPort,omitempty"` + HTTPSPort int64 `json:"httpsPort,omitempty" yaml:"httpsPort,omitempty"` + NetworkMode string `json:"networkMode,omitempty" yaml:"networkMode,omitempty"` + NginxIngressControllerPriorityClassName string `json:"nginxIngressControllerPriorityClassName,omitempty" yaml:"nginxIngressControllerPriorityClassName,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + Tolerations []Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` + UpdateStrategy *DaemonSetUpdateStrategy `json:"updateStrategy,omitempty" yaml:"updateStrategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_spec.go new file mode 100644 index 0000000..ced9234 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_spec.go @@ -0,0 +1,18 @@ +package client + +const ( + InternalNodeSpecType = "internalNodeSpec" + InternalNodeSpecFieldPodCidr = "podCidr" + InternalNodeSpecFieldPodCidrs = "podCidrs" + InternalNodeSpecFieldProviderId = "providerId" + InternalNodeSpecFieldTaints = "taints" + InternalNodeSpecFieldUnschedulable = "unschedulable" +) + +type InternalNodeSpec struct { + PodCidr string `json:"podCidr,omitempty" yaml:"podCidr,omitempty"` + PodCidrs []string `json:"podCidrs,omitempty" yaml:"podCidrs,omitempty"` + ProviderId string `json:"providerId,omitempty" yaml:"providerId,omitempty"` + Taints []Taint `json:"taints,omitempty" yaml:"taints,omitempty"` + Unschedulable bool `json:"unschedulable,omitempty" yaml:"unschedulable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_status.go new file mode 100644 index 0000000..7515d50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_internal_node_status.go @@ -0,0 +1,30 @@ +package client + +const ( + InternalNodeStatusType = "internalNodeStatus" + InternalNodeStatusFieldAllocatable = "allocatable" + InternalNodeStatusFieldCapacity = "capacity" + InternalNodeStatusFieldConfig = "config" + InternalNodeStatusFieldExternalIPAddress = "externalIpAddress" + InternalNodeStatusFieldHostname = "hostname" + InternalNodeStatusFieldIPAddress = "ipAddress" + InternalNodeStatusFieldInfo = "info" + InternalNodeStatusFieldNodeConditions = "nodeConditions" + InternalNodeStatusFieldRuntimeHandlers = "runtimeHandlers" + InternalNodeStatusFieldVolumesAttached = "volumesAttached" + InternalNodeStatusFieldVolumesInUse = "volumesInUse" +) + +type InternalNodeStatus struct { + Allocatable map[string]string `json:"allocatable,omitempty" yaml:"allocatable,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + Config *NodeConfigStatus `json:"config,omitempty" yaml:"config,omitempty"` + ExternalIPAddress string `json:"externalIpAddress,omitempty" yaml:"externalIpAddress,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPAddress string `json:"ipAddress,omitempty" yaml:"ipAddress,omitempty"` + Info *NodeInfo `json:"info,omitempty" yaml:"info,omitempty"` + NodeConditions []NodeCondition `json:"nodeConditions,omitempty" yaml:"nodeConditions,omitempty"` + RuntimeHandlers []NodeRuntimeHandler `json:"runtimeHandlers,omitempty" yaml:"runtimeHandlers,omitempty"` + VolumesAttached map[string]AttachedVolume `json:"volumesAttached,omitempty" yaml:"volumesAttached,omitempty"` + VolumesInUse []string `json:"volumesInUse,omitempty" yaml:"volumesInUse,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_iscsi_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_iscsi_volume_source.go new file mode 100644 index 0000000..ef07620 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_iscsi_volume_source.go @@ -0,0 +1,30 @@ +package client + +const ( + ISCSIVolumeSourceType = "iscsiVolumeSource" + ISCSIVolumeSourceFieldDiscoveryCHAPAuth = "chapAuthDiscovery" + ISCSIVolumeSourceFieldFSType = "fsType" + ISCSIVolumeSourceFieldIQN = "iqn" + ISCSIVolumeSourceFieldISCSIInterface = "iscsiInterface" + ISCSIVolumeSourceFieldInitiatorName = "initiatorName" + ISCSIVolumeSourceFieldLun = "lun" + ISCSIVolumeSourceFieldPortals = "portals" + ISCSIVolumeSourceFieldReadOnly = "readOnly" + ISCSIVolumeSourceFieldSecretRef = "secretRef" + ISCSIVolumeSourceFieldSessionCHAPAuth = "chapAuthSession" + ISCSIVolumeSourceFieldTargetPortal = "targetPortal" +) + +type ISCSIVolumeSource struct { + DiscoveryCHAPAuth bool `json:"chapAuthDiscovery,omitempty" yaml:"chapAuthDiscovery,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + IQN string `json:"iqn,omitempty" yaml:"iqn,omitempty"` + ISCSIInterface string `json:"iscsiInterface,omitempty" yaml:"iscsiInterface,omitempty"` + InitiatorName string `json:"initiatorName,omitempty" yaml:"initiatorName,omitempty"` + Lun int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + Portals []string `json:"portals,omitempty" yaml:"portals,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + SessionCHAPAuth bool `json:"chapAuthSession,omitempty" yaml:"chapAuthSession,omitempty"` + TargetPortal string `json:"targetPortal,omitempty" yaml:"targetPortal,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_k3s_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_k3s_config.go new file mode 100644 index 0000000..425cbd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_k3s_config.go @@ -0,0 +1,12 @@ +package client + +const ( + K3sConfigType = "k3sConfig" + K3sConfigFieldClusterUpgradeStrategy = "k3supgradeStrategy" + K3sConfigFieldVersion = "kubernetesVersion" +) + +type K3sConfig struct { + ClusterUpgradeStrategy *ClusterUpgradeStrategy `json:"k3supgradeStrategy,omitempty" yaml:"k3supgradeStrategy,omitempty"` + Version string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key.go new file mode 100644 index 0000000..0aa9ed6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key.go @@ -0,0 +1,12 @@ +package client + +const ( + KeyType = "key" + KeyFieldName = "name" + KeyFieldSecret = "secret" +) + +type Key struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Secret string `json:"secret,omitempty" yaml:"secret,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_config.go new file mode 100644 index 0000000..7a2b392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_config.go @@ -0,0 +1,52 @@ +package client + +const ( + KeyCloakConfigType = "keyCloakConfig" + KeyCloakConfigFieldAccessMode = "accessMode" + KeyCloakConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + KeyCloakConfigFieldAnnotations = "annotations" + KeyCloakConfigFieldCreated = "created" + KeyCloakConfigFieldCreatorID = "creatorId" + KeyCloakConfigFieldDisplayNameField = "displayNameField" + KeyCloakConfigFieldEnabled = "enabled" + KeyCloakConfigFieldEntityID = "entityID" + KeyCloakConfigFieldGroupsField = "groupsField" + KeyCloakConfigFieldIDPMetadataContent = "idpMetadataContent" + KeyCloakConfigFieldLabels = "labels" + KeyCloakConfigFieldName = "name" + KeyCloakConfigFieldOwnerReferences = "ownerReferences" + KeyCloakConfigFieldRancherAPIHost = "rancherApiHost" + KeyCloakConfigFieldRemoved = "removed" + KeyCloakConfigFieldSpCert = "spCert" + KeyCloakConfigFieldSpKey = "spKey" + KeyCloakConfigFieldStatus = "status" + KeyCloakConfigFieldType = "type" + KeyCloakConfigFieldUIDField = "uidField" + KeyCloakConfigFieldUUID = "uuid" + KeyCloakConfigFieldUserNameField = "userNameField" +) + +type KeyCloakConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DisplayNameField string `json:"displayNameField,omitempty" yaml:"displayNameField,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + EntityID string `json:"entityID,omitempty" yaml:"entityID,omitempty"` + GroupsField string `json:"groupsField,omitempty" yaml:"groupsField,omitempty"` + IDPMetadataContent string `json:"idpMetadataContent,omitempty" yaml:"idpMetadataContent,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherAPIHost string `json:"rancherApiHost,omitempty" yaml:"rancherApiHost,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SpCert string `json:"spCert,omitempty" yaml:"spCert,omitempty"` + SpKey string `json:"spKey,omitempty" yaml:"spKey,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UIDField string `json:"uidField,omitempty" yaml:"uidField,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserNameField string `json:"userNameField,omitempty" yaml:"userNameField,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_oidcconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_oidcconfig.go new file mode 100644 index 0000000..522b444 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_cloak_oidcconfig.go @@ -0,0 +1,62 @@ +package client + +const ( + KeyCloakOIDCConfigType = "keyCloakOIDCConfig" + KeyCloakOIDCConfigFieldAccessMode = "accessMode" + KeyCloakOIDCConfigFieldAcrValue = "acrValue" + KeyCloakOIDCConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + KeyCloakOIDCConfigFieldAnnotations = "annotations" + KeyCloakOIDCConfigFieldAuthEndpoint = "authEndpoint" + KeyCloakOIDCConfigFieldCertificate = "certificate" + KeyCloakOIDCConfigFieldClientID = "clientId" + KeyCloakOIDCConfigFieldClientSecret = "clientSecret" + KeyCloakOIDCConfigFieldCreated = "created" + KeyCloakOIDCConfigFieldCreatorID = "creatorId" + KeyCloakOIDCConfigFieldEnabled = "enabled" + KeyCloakOIDCConfigFieldGroupSearchEnabled = "groupSearchEnabled" + KeyCloakOIDCConfigFieldGroupsClaim = "groupsClaim" + KeyCloakOIDCConfigFieldIssuer = "issuer" + KeyCloakOIDCConfigFieldJWKSUrl = "jwksUrl" + KeyCloakOIDCConfigFieldLabels = "labels" + KeyCloakOIDCConfigFieldName = "name" + KeyCloakOIDCConfigFieldOwnerReferences = "ownerReferences" + KeyCloakOIDCConfigFieldPrivateKey = "privateKey" + KeyCloakOIDCConfigFieldRancherURL = "rancherUrl" + KeyCloakOIDCConfigFieldRemoved = "removed" + KeyCloakOIDCConfigFieldScopes = "scope" + KeyCloakOIDCConfigFieldStatus = "status" + KeyCloakOIDCConfigFieldTokenEndpoint = "tokenEndpoint" + KeyCloakOIDCConfigFieldType = "type" + KeyCloakOIDCConfigFieldUUID = "uuid" + KeyCloakOIDCConfigFieldUserInfoEndpoint = "userInfoEndpoint" +) + +type KeyCloakOIDCConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AcrValue string `json:"acrValue,omitempty" yaml:"acrValue,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthEndpoint string `json:"authEndpoint,omitempty" yaml:"authEndpoint,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ClientID string `json:"clientId,omitempty" yaml:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupSearchEnabled *bool `json:"groupSearchEnabled,omitempty" yaml:"groupSearchEnabled,omitempty"` + GroupsClaim string `json:"groupsClaim,omitempty" yaml:"groupsClaim,omitempty"` + Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"` + JWKSUrl string `json:"jwksUrl,omitempty" yaml:"jwksUrl,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + RancherURL string `json:"rancherUrl,omitempty" yaml:"rancherUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Scopes string `json:"scope,omitempty" yaml:"scope,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TokenEndpoint string `json:"tokenEndpoint,omitempty" yaml:"tokenEndpoint,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserInfoEndpoint string `json:"userInfoEndpoint,omitempty" yaml:"userInfoEndpoint,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_to_path.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_to_path.go new file mode 100644 index 0000000..de4ae60 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_key_to_path.go @@ -0,0 +1,14 @@ +package client + +const ( + KeyToPathType = "keyToPath" + KeyToPathFieldKey = "key" + KeyToPathFieldMode = "mode" + KeyToPathFieldPath = "path" +) + +type KeyToPath struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Mode *int64 `json:"mode,omitempty" yaml:"mode,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kms_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kms_configuration.go new file mode 100644 index 0000000..74ea0ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kms_configuration.go @@ -0,0 +1,18 @@ +package client + +const ( + KMSConfigurationType = "kmsConfiguration" + KMSConfigurationFieldAPIVersion = "apiVersion" + KMSConfigurationFieldCacheSize = "cachesize" + KMSConfigurationFieldEndpoint = "endpoint" + KMSConfigurationFieldName = "name" + KMSConfigurationFieldTimeout = "timeout" +) + +type KMSConfiguration struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + CacheSize *int64 `json:"cachesize,omitempty" yaml:"cachesize,omitempty"` + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Timeout *Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver.go new file mode 100644 index 0000000..319d68a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver.go @@ -0,0 +1,163 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + KontainerDriverType = "kontainerDriver" + KontainerDriverFieldActive = "active" + KontainerDriverFieldActualURL = "actualUrl" + KontainerDriverFieldAnnotations = "annotations" + KontainerDriverFieldBuiltIn = "builtIn" + KontainerDriverFieldChecksum = "checksum" + KontainerDriverFieldConditions = "conditions" + KontainerDriverFieldCreated = "created" + KontainerDriverFieldCreatorID = "creatorId" + KontainerDriverFieldExecutablePath = "executablePath" + KontainerDriverFieldLabels = "labels" + KontainerDriverFieldName = "name" + KontainerDriverFieldOwnerReferences = "ownerReferences" + KontainerDriverFieldRemoved = "removed" + KontainerDriverFieldState = "state" + KontainerDriverFieldTransitioning = "transitioning" + KontainerDriverFieldTransitioningMessage = "transitioningMessage" + KontainerDriverFieldUIURL = "uiUrl" + KontainerDriverFieldURL = "url" + KontainerDriverFieldUUID = "uuid" + KontainerDriverFieldWhitelistDomains = "whitelistDomains" +) + +type KontainerDriver struct { + types.Resource + Active bool `json:"active,omitempty" yaml:"active,omitempty"` + ActualURL string `json:"actualUrl,omitempty" yaml:"actualUrl,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + BuiltIn bool `json:"builtIn,omitempty" yaml:"builtIn,omitempty"` + Checksum string `json:"checksum,omitempty" yaml:"checksum,omitempty"` + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + ExecutablePath string `json:"executablePath,omitempty" yaml:"executablePath,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UIURL string `json:"uiUrl,omitempty" yaml:"uiUrl,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WhitelistDomains []string `json:"whitelistDomains,omitempty" yaml:"whitelistDomains,omitempty"` +} + +type KontainerDriverCollection struct { + types.Collection + Data []KontainerDriver `json:"data,omitempty"` + client *KontainerDriverClient +} + +type KontainerDriverClient struct { + apiClient *Client +} + +type KontainerDriverOperations interface { + List(opts *types.ListOpts) (*KontainerDriverCollection, error) + ListAll(opts *types.ListOpts) (*KontainerDriverCollection, error) + Create(opts *KontainerDriver) (*KontainerDriver, error) + Update(existing *KontainerDriver, updates interface{}) (*KontainerDriver, error) + Replace(existing *KontainerDriver) (*KontainerDriver, error) + ByID(id string) (*KontainerDriver, error) + Delete(container *KontainerDriver) error + + ActionActivate(resource *KontainerDriver) error + + ActionDeactivate(resource *KontainerDriver) error + + CollectionActionRefresh(resource *KontainerDriverCollection) error +} + +func newKontainerDriverClient(apiClient *Client) *KontainerDriverClient { + return &KontainerDriverClient{ + apiClient: apiClient, + } +} + +func (c *KontainerDriverClient) Create(container *KontainerDriver) (*KontainerDriver, error) { + resp := &KontainerDriver{} + err := c.apiClient.Ops.DoCreate(KontainerDriverType, container, resp) + return resp, err +} + +func (c *KontainerDriverClient) Update(existing *KontainerDriver, updates interface{}) (*KontainerDriver, error) { + resp := &KontainerDriver{} + err := c.apiClient.Ops.DoUpdate(KontainerDriverType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *KontainerDriverClient) Replace(obj *KontainerDriver) (*KontainerDriver, error) { + resp := &KontainerDriver{} + err := c.apiClient.Ops.DoReplace(KontainerDriverType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *KontainerDriverClient) List(opts *types.ListOpts) (*KontainerDriverCollection, error) { + resp := &KontainerDriverCollection{} + err := c.apiClient.Ops.DoList(KontainerDriverType, opts, resp) + resp.client = c + return resp, err +} + +func (c *KontainerDriverClient) ListAll(opts *types.ListOpts) (*KontainerDriverCollection, error) { + resp := &KontainerDriverCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *KontainerDriverCollection) Next() (*KontainerDriverCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &KontainerDriverCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *KontainerDriverClient) ByID(id string) (*KontainerDriver, error) { + resp := &KontainerDriver{} + err := c.apiClient.Ops.DoByID(KontainerDriverType, id, resp) + return resp, err +} + +func (c *KontainerDriverClient) Delete(container *KontainerDriver) error { + return c.apiClient.Ops.DoResourceDelete(KontainerDriverType, &container.Resource) +} + +func (c *KontainerDriverClient) ActionActivate(resource *KontainerDriver) error { + err := c.apiClient.Ops.DoAction(KontainerDriverType, "activate", &resource.Resource, nil, nil) + return err +} + +func (c *KontainerDriverClient) ActionDeactivate(resource *KontainerDriver) error { + err := c.apiClient.Ops.DoAction(KontainerDriverType, "deactivate", &resource.Resource, nil, nil) + return err +} + +func (c *KontainerDriverClient) CollectionActionRefresh(resource *KontainerDriverCollection) error { + err := c.apiClient.Ops.DoCollectionAction(KontainerDriverType, "refresh", &resource.Collection, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_spec.go new file mode 100644 index 0000000..985f7d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_spec.go @@ -0,0 +1,20 @@ +package client + +const ( + KontainerDriverSpecType = "kontainerDriverSpec" + KontainerDriverSpecFieldActive = "active" + KontainerDriverSpecFieldBuiltIn = "builtIn" + KontainerDriverSpecFieldChecksum = "checksum" + KontainerDriverSpecFieldUIURL = "uiUrl" + KontainerDriverSpecFieldURL = "url" + KontainerDriverSpecFieldWhitelistDomains = "whitelistDomains" +) + +type KontainerDriverSpec struct { + Active bool `json:"active,omitempty" yaml:"active,omitempty"` + BuiltIn bool `json:"builtIn,omitempty" yaml:"builtIn,omitempty"` + Checksum string `json:"checksum,omitempty" yaml:"checksum,omitempty"` + UIURL string `json:"uiUrl,omitempty" yaml:"uiUrl,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + WhitelistDomains []string `json:"whitelistDomains,omitempty" yaml:"whitelistDomains,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_status.go new file mode 100644 index 0000000..9ea025d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kontainer_driver_status.go @@ -0,0 +1,16 @@ +package client + +const ( + KontainerDriverStatusType = "kontainerDriverStatus" + KontainerDriverStatusFieldActualURL = "actualUrl" + KontainerDriverStatusFieldConditions = "conditions" + KontainerDriverStatusFieldDisplayName = "displayName" + KontainerDriverStatusFieldExecutablePath = "executablePath" +) + +type KontainerDriverStatus struct { + ActualURL string `json:"actualUrl,omitempty" yaml:"actualUrl,omitempty"` + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + ExecutablePath string `json:"executablePath,omitempty" yaml:"executablePath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_apiservice.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_apiservice.go new file mode 100644 index 0000000..b55abd8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_apiservice.go @@ -0,0 +1,42 @@ +package client + +const ( + KubeAPIServiceType = "kubeAPIService" + KubeAPIServiceFieldAdmissionConfiguration = "admissionConfiguration" + KubeAPIServiceFieldAlwaysPullImages = "alwaysPullImages" + KubeAPIServiceFieldAuditLog = "auditLog" + KubeAPIServiceFieldEventRateLimit = "eventRateLimit" + KubeAPIServiceFieldExtraArgs = "extraArgs" + KubeAPIServiceFieldExtraArgsArray = "extraArgsArray" + KubeAPIServiceFieldExtraBinds = "extraBinds" + KubeAPIServiceFieldExtraEnv = "extraEnv" + KubeAPIServiceFieldImage = "image" + KubeAPIServiceFieldPodSecurityConfiguration = "podSecurityConfiguration" + KubeAPIServiceFieldSecretsEncryptionConfig = "secretsEncryptionConfig" + KubeAPIServiceFieldServiceClusterIPRange = "serviceClusterIpRange" + KubeAPIServiceFieldServiceNodePortRange = "serviceNodePortRange" + KubeAPIServiceFieldWindowsExtraArgs = "winExtraArgs" + KubeAPIServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + KubeAPIServiceFieldWindowsExtraBinds = "winExtraBinds" + KubeAPIServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type KubeAPIService struct { + AdmissionConfiguration map[string]interface{} `json:"admissionConfiguration,omitempty" yaml:"admissionConfiguration,omitempty"` + AlwaysPullImages bool `json:"alwaysPullImages,omitempty" yaml:"alwaysPullImages,omitempty"` + AuditLog *AuditLog `json:"auditLog,omitempty" yaml:"auditLog,omitempty"` + EventRateLimit *EventRateLimit `json:"eventRateLimit,omitempty" yaml:"eventRateLimit,omitempty"` + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + PodSecurityConfiguration string `json:"podSecurityConfiguration,omitempty" yaml:"podSecurityConfiguration,omitempty"` + SecretsEncryptionConfig *SecretsEncryptionConfig `json:"secretsEncryptionConfig,omitempty" yaml:"secretsEncryptionConfig,omitempty"` + ServiceClusterIPRange string `json:"serviceClusterIpRange,omitempty" yaml:"serviceClusterIpRange,omitempty"` + ServiceNodePortRange string `json:"serviceNodePortRange,omitempty" yaml:"serviceNodePortRange,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_controller_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_controller_service.go new file mode 100644 index 0000000..304cecf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kube_controller_service.go @@ -0,0 +1,30 @@ +package client + +const ( + KubeControllerServiceType = "kubeControllerService" + KubeControllerServiceFieldClusterCIDR = "clusterCidr" + KubeControllerServiceFieldExtraArgs = "extraArgs" + KubeControllerServiceFieldExtraArgsArray = "extraArgsArray" + KubeControllerServiceFieldExtraBinds = "extraBinds" + KubeControllerServiceFieldExtraEnv = "extraEnv" + KubeControllerServiceFieldImage = "image" + KubeControllerServiceFieldServiceClusterIPRange = "serviceClusterIpRange" + KubeControllerServiceFieldWindowsExtraArgs = "winExtraArgs" + KubeControllerServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + KubeControllerServiceFieldWindowsExtraBinds = "winExtraBinds" + KubeControllerServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type KubeControllerService struct { + ClusterCIDR string `json:"clusterCidr,omitempty" yaml:"clusterCidr,omitempty"` + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ServiceClusterIPRange string `json:"serviceClusterIpRange,omitempty" yaml:"serviceClusterIpRange,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubelet_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubelet_service.go new file mode 100644 index 0000000..7474a10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubelet_service.go @@ -0,0 +1,36 @@ +package client + +const ( + KubeletServiceType = "kubeletService" + KubeletServiceFieldClusterDNSServer = "clusterDnsServer" + KubeletServiceFieldClusterDomain = "clusterDomain" + KubeletServiceFieldExtraArgs = "extraArgs" + KubeletServiceFieldExtraArgsArray = "extraArgsArray" + KubeletServiceFieldExtraBinds = "extraBinds" + KubeletServiceFieldExtraEnv = "extraEnv" + KubeletServiceFieldFailSwapOn = "failSwapOn" + KubeletServiceFieldGenerateServingCertificate = "generateServingCertificate" + KubeletServiceFieldImage = "image" + KubeletServiceFieldInfraContainerImage = "infraContainerImage" + KubeletServiceFieldWindowsExtraArgs = "winExtraArgs" + KubeletServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + KubeletServiceFieldWindowsExtraBinds = "winExtraBinds" + KubeletServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type KubeletService struct { + ClusterDNSServer string `json:"clusterDnsServer,omitempty" yaml:"clusterDnsServer,omitempty"` + ClusterDomain string `json:"clusterDomain,omitempty" yaml:"clusterDomain,omitempty"` + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + FailSwapOn bool `json:"failSwapOn,omitempty" yaml:"failSwapOn,omitempty"` + GenerateServingCertificate bool `json:"generateServingCertificate,omitempty" yaml:"generateServingCertificate,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + InfraContainerImage string `json:"infraContainerImage,omitempty" yaml:"infraContainerImage,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubeproxy_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubeproxy_service.go new file mode 100644 index 0000000..9159447 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubeproxy_service.go @@ -0,0 +1,26 @@ +package client + +const ( + KubeproxyServiceType = "kubeproxyService" + KubeproxyServiceFieldExtraArgs = "extraArgs" + KubeproxyServiceFieldExtraArgsArray = "extraArgsArray" + KubeproxyServiceFieldExtraBinds = "extraBinds" + KubeproxyServiceFieldExtraEnv = "extraEnv" + KubeproxyServiceFieldImage = "image" + KubeproxyServiceFieldWindowsExtraArgs = "winExtraArgs" + KubeproxyServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + KubeproxyServiceFieldWindowsExtraBinds = "winExtraBinds" + KubeproxyServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type KubeproxyService struct { + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_info.go new file mode 100644 index 0000000..69aa058 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_info.go @@ -0,0 +1,12 @@ +package client + +const ( + KubernetesInfoType = "kubernetesInfo" + KubernetesInfoFieldKubeProxyVersion = "kubeProxyVersion" + KubernetesInfoFieldKubeletVersion = "kubeletVersion" +) + +type KubernetesInfo struct { + KubeProxyVersion string `json:"kubeProxyVersion,omitempty" yaml:"kubeProxyVersion,omitempty"` + KubeletVersion string `json:"kubeletVersion,omitempty" yaml:"kubeletVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_services_options.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_services_options.go new file mode 100644 index 0000000..b2fe33c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_kubernetes_services_options.go @@ -0,0 +1,20 @@ +package client + +const ( + KubernetesServicesOptionsType = "kubernetesServicesOptions" + KubernetesServicesOptionsFieldEtcd = "etcd" + KubernetesServicesOptionsFieldKubeAPI = "kubeapi" + KubernetesServicesOptionsFieldKubeController = "kubeController" + KubernetesServicesOptionsFieldKubelet = "kubelet" + KubernetesServicesOptionsFieldKubeproxy = "kubeproxy" + KubernetesServicesOptionsFieldScheduler = "scheduler" +) + +type KubernetesServicesOptions struct { + Etcd map[string]string `json:"etcd,omitempty" yaml:"etcd,omitempty"` + KubeAPI map[string]string `json:"kubeapi,omitempty" yaml:"kubeapi,omitempty"` + KubeController map[string]string `json:"kubeController,omitempty" yaml:"kubeController,omitempty"` + Kubelet map[string]string `json:"kubelet,omitempty" yaml:"kubelet,omitempty"` + Kubeproxy map[string]string `json:"kubeproxy,omitempty" yaml:"kubeproxy,omitempty"` + Scheduler map[string]string `json:"scheduler,omitempty" yaml:"scheduler,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector.go new file mode 100644 index 0000000..27162cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector.go @@ -0,0 +1,12 @@ +package client + +const ( + LabelSelectorType = "labelSelector" + LabelSelectorFieldMatchExpressions = "matchExpressions" + LabelSelectorFieldMatchLabels = "matchLabels" +) + +type LabelSelector struct { + MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" yaml:"matchExpressions,omitempty"` + MatchLabels map[string]string `json:"matchLabels,omitempty" yaml:"matchLabels,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector_requirement.go new file mode 100644 index 0000000..3a875ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_label_selector_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + LabelSelectorRequirementType = "labelSelectorRequirement" + LabelSelectorRequirementFieldKey = "key" + LabelSelectorRequirementFieldOperator = "operator" + LabelSelectorRequirementFieldValues = "values" +) + +type LabelSelectorRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_launch_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_launch_template.go new file mode 100644 index 0000000..a5d4c84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_launch_template.go @@ -0,0 +1,14 @@ +package client + +const ( + LaunchTemplateType = "launchTemplate" + LaunchTemplateFieldID = "id" + LaunchTemplateFieldName = "name" + LaunchTemplateFieldVersion = "version" +) + +type LaunchTemplate struct { + ID *string `json:"id,omitempty" yaml:"id,omitempty"` + Name *string `json:"name,omitempty" yaml:"name,omitempty"` + Version *int64 `json:"version,omitempty" yaml:"version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_config.go new file mode 100644 index 0000000..73a21c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_config.go @@ -0,0 +1,180 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + LdapConfigType = "ldapConfig" + LdapConfigFieldAccessMode = "accessMode" + LdapConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + LdapConfigFieldAnnotations = "annotations" + LdapConfigFieldCertificate = "certificate" + LdapConfigFieldConnectionTimeout = "connectionTimeout" + LdapConfigFieldCreated = "created" + LdapConfigFieldCreatorID = "creatorId" + LdapConfigFieldEnabled = "enabled" + LdapConfigFieldGroupDNAttribute = "groupDNAttribute" + LdapConfigFieldGroupMemberMappingAttribute = "groupMemberMappingAttribute" + LdapConfigFieldGroupMemberUserAttribute = "groupMemberUserAttribute" + LdapConfigFieldGroupNameAttribute = "groupNameAttribute" + LdapConfigFieldGroupObjectClass = "groupObjectClass" + LdapConfigFieldGroupSearchAttribute = "groupSearchAttribute" + LdapConfigFieldGroupSearchBase = "groupSearchBase" + LdapConfigFieldGroupSearchFilter = "groupSearchFilter" + LdapConfigFieldLabels = "labels" + LdapConfigFieldName = "name" + LdapConfigFieldNestedGroupMembershipEnabled = "nestedGroupMembershipEnabled" + LdapConfigFieldOwnerReferences = "ownerReferences" + LdapConfigFieldPort = "port" + LdapConfigFieldRemoved = "removed" + LdapConfigFieldServers = "servers" + LdapConfigFieldServiceAccountDistinguishedName = "serviceAccountDistinguishedName" + LdapConfigFieldServiceAccountPassword = "serviceAccountPassword" + LdapConfigFieldStartTLS = "starttls" + LdapConfigFieldStatus = "status" + LdapConfigFieldTLS = "tls" + LdapConfigFieldType = "type" + LdapConfigFieldUUID = "uuid" + LdapConfigFieldUserDisabledBitMask = "userDisabledBitMask" + LdapConfigFieldUserEnabledAttribute = "userEnabledAttribute" + LdapConfigFieldUserLoginAttribute = "userLoginAttribute" + LdapConfigFieldUserMemberAttribute = "userMemberAttribute" + LdapConfigFieldUserNameAttribute = "userNameAttribute" + LdapConfigFieldUserObjectClass = "userObjectClass" + LdapConfigFieldUserSearchAttribute = "userSearchAttribute" + LdapConfigFieldUserSearchBase = "userSearchBase" + LdapConfigFieldUserSearchFilter = "userSearchFilter" +) + +type LdapConfig struct { + types.Resource + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" yaml:"connectionTimeout,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" yaml:"groupDNAttribute,omitempty"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" yaml:"groupMemberMappingAttribute,omitempty"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" yaml:"groupMemberUserAttribute,omitempty"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" yaml:"groupNameAttribute,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" yaml:"groupObjectClass,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" yaml:"groupSearchAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty" yaml:"groupSearchFilter,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled,omitempty" yaml:"nestedGroupMembershipEnabled,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Servers []string `json:"servers,omitempty" yaml:"servers,omitempty"` + ServiceAccountDistinguishedName string `json:"serviceAccountDistinguishedName,omitempty" yaml:"serviceAccountDistinguishedName,omitempty"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" yaml:"serviceAccountPassword,omitempty"` + StartTLS bool `json:"starttls,omitempty" yaml:"starttls,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" yaml:"userDisabledBitMask,omitempty"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" yaml:"userEnabledAttribute,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" yaml:"userLoginAttribute,omitempty"` + UserMemberAttribute string `json:"userMemberAttribute,omitempty" yaml:"userMemberAttribute,omitempty"` + UserNameAttribute string `json:"userNameAttribute,omitempty" yaml:"userNameAttribute,omitempty"` + UserObjectClass string `json:"userObjectClass,omitempty" yaml:"userObjectClass,omitempty"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" yaml:"userSearchAttribute,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"` + UserSearchFilter string `json:"userSearchFilter,omitempty" yaml:"userSearchFilter,omitempty"` +} + +type LdapConfigCollection struct { + types.Collection + Data []LdapConfig `json:"data,omitempty"` + client *LdapConfigClient +} + +type LdapConfigClient struct { + apiClient *Client +} + +type LdapConfigOperations interface { + List(opts *types.ListOpts) (*LdapConfigCollection, error) + ListAll(opts *types.ListOpts) (*LdapConfigCollection, error) + Create(opts *LdapConfig) (*LdapConfig, error) + Update(existing *LdapConfig, updates interface{}) (*LdapConfig, error) + Replace(existing *LdapConfig) (*LdapConfig, error) + ByID(id string) (*LdapConfig, error) + Delete(container *LdapConfig) error +} + +func newLdapConfigClient(apiClient *Client) *LdapConfigClient { + return &LdapConfigClient{ + apiClient: apiClient, + } +} + +func (c *LdapConfigClient) Create(container *LdapConfig) (*LdapConfig, error) { + resp := &LdapConfig{} + err := c.apiClient.Ops.DoCreate(LdapConfigType, container, resp) + return resp, err +} + +func (c *LdapConfigClient) Update(existing *LdapConfig, updates interface{}) (*LdapConfig, error) { + resp := &LdapConfig{} + err := c.apiClient.Ops.DoUpdate(LdapConfigType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *LdapConfigClient) Replace(obj *LdapConfig) (*LdapConfig, error) { + resp := &LdapConfig{} + err := c.apiClient.Ops.DoReplace(LdapConfigType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *LdapConfigClient) List(opts *types.ListOpts) (*LdapConfigCollection, error) { + resp := &LdapConfigCollection{} + err := c.apiClient.Ops.DoList(LdapConfigType, opts, resp) + resp.client = c + return resp, err +} + +func (c *LdapConfigClient) ListAll(opts *types.ListOpts) (*LdapConfigCollection, error) { + resp := &LdapConfigCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *LdapConfigCollection) Next() (*LdapConfigCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &LdapConfigCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *LdapConfigClient) ByID(id string) (*LdapConfig, error) { + resp := &LdapConfig{} + err := c.apiClient.Ops.DoByID(LdapConfigType, id, resp) + return resp, err +} + +func (c *LdapConfigClient) Delete(container *LdapConfig) error { + return c.apiClient.Ops.DoResourceDelete(LdapConfigType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_fields.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_fields.go new file mode 100644 index 0000000..7c342d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ldap_fields.go @@ -0,0 +1,60 @@ +package client + +const ( + LdapFieldsType = "ldapFields" + LdapFieldsFieldCertificate = "certificate" + LdapFieldsFieldConnectionTimeout = "connectionTimeout" + LdapFieldsFieldGroupDNAttribute = "groupDNAttribute" + LdapFieldsFieldGroupMemberMappingAttribute = "groupMemberMappingAttribute" + LdapFieldsFieldGroupMemberUserAttribute = "groupMemberUserAttribute" + LdapFieldsFieldGroupNameAttribute = "groupNameAttribute" + LdapFieldsFieldGroupObjectClass = "groupObjectClass" + LdapFieldsFieldGroupSearchAttribute = "groupSearchAttribute" + LdapFieldsFieldGroupSearchBase = "groupSearchBase" + LdapFieldsFieldGroupSearchFilter = "groupSearchFilter" + LdapFieldsFieldNestedGroupMembershipEnabled = "nestedGroupMembershipEnabled" + LdapFieldsFieldPort = "port" + LdapFieldsFieldServers = "servers" + LdapFieldsFieldServiceAccountDistinguishedName = "serviceAccountDistinguishedName" + LdapFieldsFieldServiceAccountPassword = "serviceAccountPassword" + LdapFieldsFieldStartTLS = "starttls" + LdapFieldsFieldTLS = "tls" + LdapFieldsFieldUserDisabledBitMask = "userDisabledBitMask" + LdapFieldsFieldUserEnabledAttribute = "userEnabledAttribute" + LdapFieldsFieldUserLoginAttribute = "userLoginAttribute" + LdapFieldsFieldUserMemberAttribute = "userMemberAttribute" + LdapFieldsFieldUserNameAttribute = "userNameAttribute" + LdapFieldsFieldUserObjectClass = "userObjectClass" + LdapFieldsFieldUserSearchAttribute = "userSearchAttribute" + LdapFieldsFieldUserSearchBase = "userSearchBase" + LdapFieldsFieldUserSearchFilter = "userSearchFilter" +) + +type LdapFields struct { + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" yaml:"connectionTimeout,omitempty"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" yaml:"groupDNAttribute,omitempty"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" yaml:"groupMemberMappingAttribute,omitempty"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" yaml:"groupMemberUserAttribute,omitempty"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" yaml:"groupNameAttribute,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" yaml:"groupObjectClass,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" yaml:"groupSearchAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty" yaml:"groupSearchFilter,omitempty"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled,omitempty" yaml:"nestedGroupMembershipEnabled,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Servers []string `json:"servers,omitempty" yaml:"servers,omitempty"` + ServiceAccountDistinguishedName string `json:"serviceAccountDistinguishedName,omitempty" yaml:"serviceAccountDistinguishedName,omitempty"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" yaml:"serviceAccountPassword,omitempty"` + StartTLS bool `json:"starttls,omitempty" yaml:"starttls,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" yaml:"userDisabledBitMask,omitempty"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" yaml:"userEnabledAttribute,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" yaml:"userLoginAttribute,omitempty"` + UserMemberAttribute string `json:"userMemberAttribute,omitempty" yaml:"userMemberAttribute,omitempty"` + UserNameAttribute string `json:"userNameAttribute,omitempty" yaml:"userNameAttribute,omitempty"` + UserObjectClass string `json:"userObjectClass,omitempty" yaml:"userObjectClass,omitempty"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" yaml:"userSearchAttribute,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"` + UserSearchFilter string `json:"userSearchFilter,omitempty" yaml:"userSearchFilter,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_linear_autoscaler_params.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_linear_autoscaler_params.go new file mode 100644 index 0000000..f9ed17d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_linear_autoscaler_params.go @@ -0,0 +1,18 @@ +package client + +const ( + LinearAutoscalerParamsType = "linearAutoscalerParams" + LinearAutoscalerParamsFieldCoresPerReplica = "coresPerReplica" + LinearAutoscalerParamsFieldMax = "max" + LinearAutoscalerParamsFieldMin = "min" + LinearAutoscalerParamsFieldNodesPerReplica = "nodesPerReplica" + LinearAutoscalerParamsFieldPreventSinglePointFailure = "preventSinglePointFailure" +) + +type LinearAutoscalerParams struct { + CoresPerReplica float64 `json:"coresPerReplica,omitempty" yaml:"coresPerReplica,omitempty"` + Max int64 `json:"max,omitempty" yaml:"max,omitempty"` + Min int64 `json:"min,omitempty" yaml:"min,omitempty"` + NodesPerReplica float64 `json:"nodesPerReplica,omitempty" yaml:"nodesPerReplica,omitempty"` + PreventSinglePointFailure bool `json:"preventSinglePointFailure,omitempty" yaml:"preventSinglePointFailure,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_capabilities.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_capabilities.go new file mode 100644 index 0000000..6258b57 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_capabilities.go @@ -0,0 +1,16 @@ +package client + +const ( + LoadBalancerCapabilitiesType = "loadBalancerCapabilities" + LoadBalancerCapabilitiesFieldEnabled = "enabled" + LoadBalancerCapabilitiesFieldHealthCheckSupported = "healthCheckSupported" + LoadBalancerCapabilitiesFieldProtocolsSupported = "protocolsSupported" + LoadBalancerCapabilitiesFieldProvider = "provider" +) + +type LoadBalancerCapabilities struct { + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + HealthCheckSupported bool `json:"healthCheckSupported,omitempty" yaml:"healthCheckSupported,omitempty"` + ProtocolsSupported []string `json:"protocolsSupported,omitempty" yaml:"protocolsSupported,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_openstack_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_openstack_opts.go new file mode 100644 index 0000000..bd4f386 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_load_balancer_openstack_opts.go @@ -0,0 +1,30 @@ +package client + +const ( + LoadBalancerOpenstackOptsType = "loadBalancerOpenstackOpts" + LoadBalancerOpenstackOptsFieldCreateMonitor = "create-monitor" + LoadBalancerOpenstackOptsFieldFloatingNetworkID = "floating-network-id" + LoadBalancerOpenstackOptsFieldLBMethod = "lb-method" + LoadBalancerOpenstackOptsFieldLBProvider = "lb-provider" + LoadBalancerOpenstackOptsFieldLBVersion = "lb-version" + LoadBalancerOpenstackOptsFieldManageSecurityGroups = "manage-security-groups" + LoadBalancerOpenstackOptsFieldMonitorDelay = "monitor-delay" + LoadBalancerOpenstackOptsFieldMonitorMaxRetries = "monitor-max-retries" + LoadBalancerOpenstackOptsFieldMonitorTimeout = "monitor-timeout" + LoadBalancerOpenstackOptsFieldSubnetID = "subnet-id" + LoadBalancerOpenstackOptsFieldUseOctavia = "use-octavia" +) + +type LoadBalancerOpenstackOpts struct { + CreateMonitor bool `json:"create-monitor,omitempty" yaml:"create-monitor,omitempty"` + FloatingNetworkID string `json:"floating-network-id,omitempty" yaml:"floating-network-id,omitempty"` + LBMethod string `json:"lb-method,omitempty" yaml:"lb-method,omitempty"` + LBProvider string `json:"lb-provider,omitempty" yaml:"lb-provider,omitempty"` + LBVersion string `json:"lb-version,omitempty" yaml:"lb-version,omitempty"` + ManageSecurityGroups bool `json:"manage-security-groups,omitempty" yaml:"manage-security-groups,omitempty"` + MonitorDelay string `json:"monitor-delay,omitempty" yaml:"monitor-delay,omitempty"` + MonitorMaxRetries int64 `json:"monitor-max-retries,omitempty" yaml:"monitor-max-retries,omitempty"` + MonitorTimeout string `json:"monitor-timeout,omitempty" yaml:"monitor-timeout,omitempty"` + SubnetID string `json:"subnet-id,omitempty" yaml:"subnet-id,omitempty"` + UseOctavia bool `json:"use-octavia,omitempty" yaml:"use-octavia,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_cluster_auth_endpoint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_cluster_auth_endpoint.go new file mode 100644 index 0000000..830583d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_cluster_auth_endpoint.go @@ -0,0 +1,14 @@ +package client + +const ( + LocalClusterAuthEndpointType = "localClusterAuthEndpoint" + LocalClusterAuthEndpointFieldCACerts = "caCerts" + LocalClusterAuthEndpointFieldEnabled = "enabled" + LocalClusterAuthEndpointFieldFQDN = "fqdn" +) + +type LocalClusterAuthEndpoint struct { + CACerts string `json:"caCerts,omitempty" yaml:"caCerts,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + FQDN string `json:"fqdn,omitempty" yaml:"fqdn,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_config.go new file mode 100644 index 0000000..ca4d512 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_config.go @@ -0,0 +1,34 @@ +package client + +const ( + LocalConfigType = "localConfig" + LocalConfigFieldAccessMode = "accessMode" + LocalConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + LocalConfigFieldAnnotations = "annotations" + LocalConfigFieldCreated = "created" + LocalConfigFieldCreatorID = "creatorId" + LocalConfigFieldEnabled = "enabled" + LocalConfigFieldLabels = "labels" + LocalConfigFieldName = "name" + LocalConfigFieldOwnerReferences = "ownerReferences" + LocalConfigFieldRemoved = "removed" + LocalConfigFieldStatus = "status" + LocalConfigFieldType = "type" + LocalConfigFieldUUID = "uuid" +) + +type LocalConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_object_reference.go new file mode 100644 index 0000000..e4d3b50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_local_object_reference.go @@ -0,0 +1,10 @@ +package client + +const ( + LocalObjectReferenceType = "localObjectReference" + LocalObjectReferenceFieldName = "name" +) + +type LocalObjectReference struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_management_secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_management_secret.go new file mode 100644 index 0000000..4814ba4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_management_secret.go @@ -0,0 +1,126 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ManagementSecretType = "managementSecret" + ManagementSecretFieldAnnotations = "annotations" + ManagementSecretFieldCreated = "created" + ManagementSecretFieldCreatorID = "creatorId" + ManagementSecretFieldData = "data" + ManagementSecretFieldImmutable = "immutable" + ManagementSecretFieldLabels = "labels" + ManagementSecretFieldName = "name" + ManagementSecretFieldOwnerReferences = "ownerReferences" + ManagementSecretFieldRemoved = "removed" + ManagementSecretFieldStringData = "stringData" + ManagementSecretFieldType = "type" + ManagementSecretFieldUUID = "uuid" +) + +type ManagementSecret struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"` + Immutable *bool `json:"immutable,omitempty" yaml:"immutable,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + StringData map[string]string `json:"stringData,omitempty" yaml:"stringData,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ManagementSecretCollection struct { + types.Collection + Data []ManagementSecret `json:"data,omitempty"` + client *ManagementSecretClient +} + +type ManagementSecretClient struct { + apiClient *Client +} + +type ManagementSecretOperations interface { + List(opts *types.ListOpts) (*ManagementSecretCollection, error) + ListAll(opts *types.ListOpts) (*ManagementSecretCollection, error) + Create(opts *ManagementSecret) (*ManagementSecret, error) + Update(existing *ManagementSecret, updates interface{}) (*ManagementSecret, error) + Replace(existing *ManagementSecret) (*ManagementSecret, error) + ByID(id string) (*ManagementSecret, error) + Delete(container *ManagementSecret) error +} + +func newManagementSecretClient(apiClient *Client) *ManagementSecretClient { + return &ManagementSecretClient{ + apiClient: apiClient, + } +} + +func (c *ManagementSecretClient) Create(container *ManagementSecret) (*ManagementSecret, error) { + resp := &ManagementSecret{} + err := c.apiClient.Ops.DoCreate(ManagementSecretType, container, resp) + return resp, err +} + +func (c *ManagementSecretClient) Update(existing *ManagementSecret, updates interface{}) (*ManagementSecret, error) { + resp := &ManagementSecret{} + err := c.apiClient.Ops.DoUpdate(ManagementSecretType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ManagementSecretClient) Replace(obj *ManagementSecret) (*ManagementSecret, error) { + resp := &ManagementSecret{} + err := c.apiClient.Ops.DoReplace(ManagementSecretType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ManagementSecretClient) List(opts *types.ListOpts) (*ManagementSecretCollection, error) { + resp := &ManagementSecretCollection{} + err := c.apiClient.Ops.DoList(ManagementSecretType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ManagementSecretClient) ListAll(opts *types.ListOpts) (*ManagementSecretCollection, error) { + resp := &ManagementSecretCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ManagementSecretCollection) Next() (*ManagementSecretCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ManagementSecretCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ManagementSecretClient) ByID(id string) (*ManagementSecret, error) { + resp := &ManagementSecret{} + err := c.apiClient.Ops.DoByID(ManagementSecretType, id, resp) + return resp, err +} + +func (c *ManagementSecretClient) Delete(container *ManagementSecret) error { + return c.apiClient.Ops.DoResourceDelete(ManagementSecretType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_map_delta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_map_delta.go new file mode 100644 index 0000000..b686181 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_map_delta.go @@ -0,0 +1,12 @@ +package client + +const ( + MapDeltaType = "mapDelta" + MapDeltaFieldAdd = "add" + MapDeltaFieldDelete = "delete" +) + +type MapDelta struct { + Add map[string]string `json:"add,omitempty" yaml:"add,omitempty"` + Delete map[string]bool `json:"delete,omitempty" yaml:"delete,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_member.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_member.go new file mode 100644 index 0000000..620e460 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_member.go @@ -0,0 +1,14 @@ +package client + +const ( + MemberType = "member" + MemberFieldAccessType = "accessType" + MemberFieldGroupPrincipalID = "groupPrincipalId" + MemberFieldUserPrincipalID = "userPrincipalId" +) + +type Member struct { + AccessType string `json:"accessType,omitempty" yaml:"accessType,omitempty"` + GroupPrincipalID string `json:"groupPrincipalId,omitempty" yaml:"groupPrincipalId,omitempty"` + UserPrincipalID string `json:"userPrincipalId,omitempty" yaml:"userPrincipalId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_memory_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_memory_info.go new file mode 100644 index 0000000..ecd1a17 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_memory_info.go @@ -0,0 +1,10 @@ +package client + +const ( + MemoryInfoType = "memoryInfo" + MemoryInfoFieldMemTotalKiB = "memTotalKiB" +) + +type MemoryInfo struct { + MemTotalKiB int64 `json:"memTotalKiB,omitempty" yaml:"memTotalKiB,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_openstack_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_openstack_opts.go new file mode 100644 index 0000000..8a38e93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_openstack_opts.go @@ -0,0 +1,12 @@ +package client + +const ( + MetadataOpenstackOptsType = "metadataOpenstackOpts" + MetadataOpenstackOptsFieldRequestTimeout = "request-timeout" + MetadataOpenstackOptsFieldSearchOrder = "search-order" +) + +type MetadataOpenstackOpts struct { + RequestTimeout int64 `json:"request-timeout,omitempty" yaml:"request-timeout,omitempty"` + SearchOrder string `json:"search-order,omitempty" yaml:"search-order,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_update.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_update.go new file mode 100644 index 0000000..1d1f5b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_metadata_update.go @@ -0,0 +1,12 @@ +package client + +const ( + MetadataUpdateType = "metadataUpdate" + MetadataUpdateFieldAnnotations = "annotations" + MetadataUpdateFieldLabels = "labels" +) + +type MetadataUpdate struct { + Annotations *MapDelta `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Labels *MapDelta `json:"labels,omitempty" yaml:"labels,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_monitoring_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_monitoring_config.go new file mode 100644 index 0000000..3cb7049 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_monitoring_config.go @@ -0,0 +1,22 @@ +package client + +const ( + MonitoringConfigType = "monitoringConfig" + MonitoringConfigFieldMetricsServerPriorityClassName = "metricsServerPriorityClassName" + MonitoringConfigFieldNodeSelector = "nodeSelector" + MonitoringConfigFieldOptions = "options" + MonitoringConfigFieldProvider = "provider" + MonitoringConfigFieldReplicas = "replicas" + MonitoringConfigFieldTolerations = "tolerations" + MonitoringConfigFieldUpdateStrategy = "updateStrategy" +) + +type MonitoringConfig struct { + MetricsServerPriorityClassName string `json:"metricsServerPriorityClassName,omitempty" yaml:"metricsServerPriorityClassName,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + Replicas *int64 `json:"replicas,omitempty" yaml:"replicas,omitempty"` + Tolerations []Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` + UpdateStrategy *DeploymentStrategy `json:"updateStrategy,omitempty" yaml:"updateStrategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app.go new file mode 100644 index 0000000..228b842 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app.go @@ -0,0 +1,165 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + MultiClusterAppType = "multiClusterApp" + MultiClusterAppFieldAnnotations = "annotations" + MultiClusterAppFieldAnswers = "answers" + MultiClusterAppFieldCreated = "created" + MultiClusterAppFieldCreatorID = "creatorId" + MultiClusterAppFieldLabels = "labels" + MultiClusterAppFieldMembers = "members" + MultiClusterAppFieldName = "name" + MultiClusterAppFieldOwnerReferences = "ownerReferences" + MultiClusterAppFieldRemoved = "removed" + MultiClusterAppFieldRevisionHistoryLimit = "revisionHistoryLimit" + MultiClusterAppFieldRoles = "roles" + MultiClusterAppFieldState = "state" + MultiClusterAppFieldStatus = "status" + MultiClusterAppFieldTargets = "targets" + MultiClusterAppFieldTemplateVersionID = "templateVersionId" + MultiClusterAppFieldTimeout = "timeout" + MultiClusterAppFieldTransitioning = "transitioning" + MultiClusterAppFieldTransitioningMessage = "transitioningMessage" + MultiClusterAppFieldUUID = "uuid" + MultiClusterAppFieldUpgradeStrategy = "upgradeStrategy" + MultiClusterAppFieldWait = "wait" +) + +type MultiClusterApp struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Answers []Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RevisionHistoryLimit int64 `json:"revisionHistoryLimit,omitempty" yaml:"revisionHistoryLimit,omitempty"` + Roles []string `json:"roles,omitempty" yaml:"roles,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *MultiClusterAppStatus `json:"status,omitempty" yaml:"status,omitempty"` + Targets []Target `json:"targets,omitempty" yaml:"targets,omitempty"` + TemplateVersionID string `json:"templateVersionId,omitempty" yaml:"templateVersionId,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty" yaml:"upgradeStrategy,omitempty"` + Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` +} + +type MultiClusterAppCollection struct { + types.Collection + Data []MultiClusterApp `json:"data,omitempty"` + client *MultiClusterAppClient +} + +type MultiClusterAppClient struct { + apiClient *Client +} + +type MultiClusterAppOperations interface { + List(opts *types.ListOpts) (*MultiClusterAppCollection, error) + ListAll(opts *types.ListOpts) (*MultiClusterAppCollection, error) + Create(opts *MultiClusterApp) (*MultiClusterApp, error) + Update(existing *MultiClusterApp, updates interface{}) (*MultiClusterApp, error) + Replace(existing *MultiClusterApp) (*MultiClusterApp, error) + ByID(id string) (*MultiClusterApp, error) + Delete(container *MultiClusterApp) error + + ActionAddProjects(resource *MultiClusterApp, input *UpdateMultiClusterAppTargetsInput) error + + ActionRemoveProjects(resource *MultiClusterApp, input *UpdateMultiClusterAppTargetsInput) error + + ActionRollback(resource *MultiClusterApp, input *MultiClusterAppRollbackInput) error +} + +func newMultiClusterAppClient(apiClient *Client) *MultiClusterAppClient { + return &MultiClusterAppClient{ + apiClient: apiClient, + } +} + +func (c *MultiClusterAppClient) Create(container *MultiClusterApp) (*MultiClusterApp, error) { + resp := &MultiClusterApp{} + err := c.apiClient.Ops.DoCreate(MultiClusterAppType, container, resp) + return resp, err +} + +func (c *MultiClusterAppClient) Update(existing *MultiClusterApp, updates interface{}) (*MultiClusterApp, error) { + resp := &MultiClusterApp{} + err := c.apiClient.Ops.DoUpdate(MultiClusterAppType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *MultiClusterAppClient) Replace(obj *MultiClusterApp) (*MultiClusterApp, error) { + resp := &MultiClusterApp{} + err := c.apiClient.Ops.DoReplace(MultiClusterAppType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *MultiClusterAppClient) List(opts *types.ListOpts) (*MultiClusterAppCollection, error) { + resp := &MultiClusterAppCollection{} + err := c.apiClient.Ops.DoList(MultiClusterAppType, opts, resp) + resp.client = c + return resp, err +} + +func (c *MultiClusterAppClient) ListAll(opts *types.ListOpts) (*MultiClusterAppCollection, error) { + resp := &MultiClusterAppCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *MultiClusterAppCollection) Next() (*MultiClusterAppCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &MultiClusterAppCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *MultiClusterAppClient) ByID(id string) (*MultiClusterApp, error) { + resp := &MultiClusterApp{} + err := c.apiClient.Ops.DoByID(MultiClusterAppType, id, resp) + return resp, err +} + +func (c *MultiClusterAppClient) Delete(container *MultiClusterApp) error { + return c.apiClient.Ops.DoResourceDelete(MultiClusterAppType, &container.Resource) +} + +func (c *MultiClusterAppClient) ActionAddProjects(resource *MultiClusterApp, input *UpdateMultiClusterAppTargetsInput) error { + err := c.apiClient.Ops.DoAction(MultiClusterAppType, "addProjects", &resource.Resource, input, nil) + return err +} + +func (c *MultiClusterAppClient) ActionRemoveProjects(resource *MultiClusterApp, input *UpdateMultiClusterAppTargetsInput) error { + err := c.apiClient.Ops.DoAction(MultiClusterAppType, "removeProjects", &resource.Resource, input, nil) + return err +} + +func (c *MultiClusterAppClient) ActionRollback(resource *MultiClusterApp, input *MultiClusterAppRollbackInput) error { + err := c.apiClient.Ops.DoAction(MultiClusterAppType, "rollback", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_revision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_revision.go new file mode 100644 index 0000000..a759036 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_revision.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + MultiClusterAppRevisionType = "multiClusterAppRevision" + MultiClusterAppRevisionFieldAnnotations = "annotations" + MultiClusterAppRevisionFieldAnswers = "answers" + MultiClusterAppRevisionFieldCreated = "created" + MultiClusterAppRevisionFieldCreatorID = "creatorId" + MultiClusterAppRevisionFieldLabels = "labels" + MultiClusterAppRevisionFieldName = "name" + MultiClusterAppRevisionFieldOwnerReferences = "ownerReferences" + MultiClusterAppRevisionFieldRemoved = "removed" + MultiClusterAppRevisionFieldTemplateVersionID = "templateVersionId" + MultiClusterAppRevisionFieldUUID = "uuid" +) + +type MultiClusterAppRevision struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Answers []Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + TemplateVersionID string `json:"templateVersionId,omitempty" yaml:"templateVersionId,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type MultiClusterAppRevisionCollection struct { + types.Collection + Data []MultiClusterAppRevision `json:"data,omitempty"` + client *MultiClusterAppRevisionClient +} + +type MultiClusterAppRevisionClient struct { + apiClient *Client +} + +type MultiClusterAppRevisionOperations interface { + List(opts *types.ListOpts) (*MultiClusterAppRevisionCollection, error) + ListAll(opts *types.ListOpts) (*MultiClusterAppRevisionCollection, error) + Create(opts *MultiClusterAppRevision) (*MultiClusterAppRevision, error) + Update(existing *MultiClusterAppRevision, updates interface{}) (*MultiClusterAppRevision, error) + Replace(existing *MultiClusterAppRevision) (*MultiClusterAppRevision, error) + ByID(id string) (*MultiClusterAppRevision, error) + Delete(container *MultiClusterAppRevision) error +} + +func newMultiClusterAppRevisionClient(apiClient *Client) *MultiClusterAppRevisionClient { + return &MultiClusterAppRevisionClient{ + apiClient: apiClient, + } +} + +func (c *MultiClusterAppRevisionClient) Create(container *MultiClusterAppRevision) (*MultiClusterAppRevision, error) { + resp := &MultiClusterAppRevision{} + err := c.apiClient.Ops.DoCreate(MultiClusterAppRevisionType, container, resp) + return resp, err +} + +func (c *MultiClusterAppRevisionClient) Update(existing *MultiClusterAppRevision, updates interface{}) (*MultiClusterAppRevision, error) { + resp := &MultiClusterAppRevision{} + err := c.apiClient.Ops.DoUpdate(MultiClusterAppRevisionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *MultiClusterAppRevisionClient) Replace(obj *MultiClusterAppRevision) (*MultiClusterAppRevision, error) { + resp := &MultiClusterAppRevision{} + err := c.apiClient.Ops.DoReplace(MultiClusterAppRevisionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *MultiClusterAppRevisionClient) List(opts *types.ListOpts) (*MultiClusterAppRevisionCollection, error) { + resp := &MultiClusterAppRevisionCollection{} + err := c.apiClient.Ops.DoList(MultiClusterAppRevisionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *MultiClusterAppRevisionClient) ListAll(opts *types.ListOpts) (*MultiClusterAppRevisionCollection, error) { + resp := &MultiClusterAppRevisionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *MultiClusterAppRevisionCollection) Next() (*MultiClusterAppRevisionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &MultiClusterAppRevisionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *MultiClusterAppRevisionClient) ByID(id string) (*MultiClusterAppRevision, error) { + resp := &MultiClusterAppRevision{} + err := c.apiClient.Ops.DoByID(MultiClusterAppRevisionType, id, resp) + return resp, err +} + +func (c *MultiClusterAppRevisionClient) Delete(container *MultiClusterAppRevision) error { + return c.apiClient.Ops.DoResourceDelete(MultiClusterAppRevisionType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_rollback_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_rollback_input.go new file mode 100644 index 0000000..90a033e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_rollback_input.go @@ -0,0 +1,10 @@ +package client + +const ( + MultiClusterAppRollbackInputType = "multiClusterAppRollbackInput" + MultiClusterAppRollbackInputFieldRevisionID = "revisionId" +) + +type MultiClusterAppRollbackInput struct { + RevisionID string `json:"revisionId,omitempty" yaml:"revisionId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_spec.go new file mode 100644 index 0000000..c9d0b38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_spec.go @@ -0,0 +1,26 @@ +package client + +const ( + MultiClusterAppSpecType = "multiClusterAppSpec" + MultiClusterAppSpecFieldAnswers = "answers" + MultiClusterAppSpecFieldMembers = "members" + MultiClusterAppSpecFieldRevisionHistoryLimit = "revisionHistoryLimit" + MultiClusterAppSpecFieldRoles = "roles" + MultiClusterAppSpecFieldTargets = "targets" + MultiClusterAppSpecFieldTemplateVersionID = "templateVersionId" + MultiClusterAppSpecFieldTimeout = "timeout" + MultiClusterAppSpecFieldUpgradeStrategy = "upgradeStrategy" + MultiClusterAppSpecFieldWait = "wait" +) + +type MultiClusterAppSpec struct { + Answers []Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + Members []Member `json:"members,omitempty" yaml:"members,omitempty"` + RevisionHistoryLimit int64 `json:"revisionHistoryLimit,omitempty" yaml:"revisionHistoryLimit,omitempty"` + Roles []string `json:"roles,omitempty" yaml:"roles,omitempty"` + Targets []Target `json:"targets,omitempty" yaml:"targets,omitempty"` + TemplateVersionID string `json:"templateVersionId,omitempty" yaml:"templateVersionId,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty" yaml:"upgradeStrategy,omitempty"` + Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_status.go new file mode 100644 index 0000000..e84859c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_multi_cluster_app_status.go @@ -0,0 +1,14 @@ +package client + +const ( + MultiClusterAppStatusType = "multiClusterAppStatus" + MultiClusterAppStatusFieldConditions = "conditions" + MultiClusterAppStatusFieldHelmVersion = "helmVersion" + MultiClusterAppStatusFieldRevisionID = "revisionId" +) + +type MultiClusterAppStatus struct { + Conditions []AppCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + RevisionID string `json:"revisionId,omitempty" yaml:"revisionId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_namespace_resource_quota.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_namespace_resource_quota.go new file mode 100644 index 0000000..b170bf5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_namespace_resource_quota.go @@ -0,0 +1,10 @@ +package client + +const ( + NamespaceResourceQuotaType = "namespaceResourceQuota" + NamespaceResourceQuotaFieldLimit = "limit" +) + +type NamespaceResourceQuota struct { + Limit *ResourceQuotaLimit `json:"limit,omitempty" yaml:"limit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_config.go new file mode 100644 index 0000000..4235298 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_config.go @@ -0,0 +1,30 @@ +package client + +const ( + NetworkConfigType = "networkConfig" + NetworkConfigFieldAciNetworkProvider = "aciNetworkProvider" + NetworkConfigFieldCalicoNetworkProvider = "calicoNetworkProvider" + NetworkConfigFieldCanalNetworkProvider = "canalNetworkProvider" + NetworkConfigFieldFlannelNetworkProvider = "flannelNetworkProvider" + NetworkConfigFieldMTU = "mtu" + NetworkConfigFieldNodeSelector = "nodeSelector" + NetworkConfigFieldOptions = "options" + NetworkConfigFieldPlugin = "plugin" + NetworkConfigFieldTolerations = "tolerations" + NetworkConfigFieldUpdateStrategy = "updateStrategy" + NetworkConfigFieldWeaveNetworkProvider = "weaveNetworkProvider" +) + +type NetworkConfig struct { + AciNetworkProvider *AciNetworkProvider `json:"aciNetworkProvider,omitempty" yaml:"aciNetworkProvider,omitempty"` + CalicoNetworkProvider *CalicoNetworkProvider `json:"calicoNetworkProvider,omitempty" yaml:"calicoNetworkProvider,omitempty"` + CanalNetworkProvider *CanalNetworkProvider `json:"canalNetworkProvider,omitempty" yaml:"canalNetworkProvider,omitempty"` + FlannelNetworkProvider *FlannelNetworkProvider `json:"flannelNetworkProvider,omitempty" yaml:"flannelNetworkProvider,omitempty"` + MTU int64 `json:"mtu,omitempty" yaml:"mtu,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + Plugin string `json:"plugin,omitempty" yaml:"plugin,omitempty"` + Tolerations []Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` + UpdateStrategy *DaemonSetUpdateStrategy `json:"updateStrategy,omitempty" yaml:"updateStrategy,omitempty"` + WeaveNetworkProvider *WeaveNetworkProvider `json:"weaveNetworkProvider,omitempty" yaml:"weaveNetworkProvider,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_vshpere_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_vshpere_opts.go new file mode 100644 index 0000000..ad27335 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_network_vshpere_opts.go @@ -0,0 +1,10 @@ +package client + +const ( + NetworkVshpereOptsType = "networkVshpereOpts" + NetworkVshpereOptsFieldPublicNetwork = "public-network" +) + +type NetworkVshpereOpts struct { + PublicNetwork string `json:"public-network,omitempty" yaml:"public-network,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nfs_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nfs_volume_source.go new file mode 100644 index 0000000..bbaeecf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nfs_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + NFSVolumeSourceType = "nfsVolumeSource" + NFSVolumeSourceFieldPath = "path" + NFSVolumeSourceFieldReadOnly = "readOnly" + NFSVolumeSourceFieldServer = "server" +) + +type NFSVolumeSource struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Server string `json:"server,omitempty" yaml:"server,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node.go new file mode 100644 index 0000000..5f3ab57 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node.go @@ -0,0 +1,231 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NodeType = "node" + NodeFieldAllocatable = "allocatable" + NodeFieldAnnotations = "annotations" + NodeFieldAppliedNodeVersion = "appliedNodeVersion" + NodeFieldCapacity = "capacity" + NodeFieldClusterID = "clusterId" + NodeFieldConditions = "conditions" + NodeFieldControlPlane = "controlPlane" + NodeFieldCreated = "created" + NodeFieldCreatorID = "creatorId" + NodeFieldCustomConfig = "customConfig" + NodeFieldDescription = "description" + NodeFieldDockerInfo = "dockerInfo" + NodeFieldEtcd = "etcd" + NodeFieldExternalIPAddress = "externalIpAddress" + NodeFieldHostname = "hostname" + NodeFieldIPAddress = "ipAddress" + NodeFieldImported = "imported" + NodeFieldInfo = "info" + NodeFieldLabels = "labels" + NodeFieldLimits = "limits" + NodeFieldName = "name" + NodeFieldNamespaceId = "namespaceId" + NodeFieldNodeName = "nodeName" + NodeFieldNodePlan = "nodePlan" + NodeFieldNodePoolID = "nodePoolId" + NodeFieldNodeTaints = "nodeTaints" + NodeFieldNodeTemplateID = "nodeTemplateId" + NodeFieldOwnerReferences = "ownerReferences" + NodeFieldPodCidr = "podCidr" + NodeFieldPodCidrs = "podCidrs" + NodeFieldProviderId = "providerId" + NodeFieldPublicEndpoints = "publicEndpoints" + NodeFieldRemoved = "removed" + NodeFieldRequested = "requested" + NodeFieldRequestedHostname = "requestedHostname" + NodeFieldRuntimeHandlers = "runtimeHandlers" + NodeFieldScaledownTime = "scaledownTime" + NodeFieldSshUser = "sshUser" + NodeFieldState = "state" + NodeFieldTaints = "taints" + NodeFieldTransitioning = "transitioning" + NodeFieldTransitioningMessage = "transitioningMessage" + NodeFieldUUID = "uuid" + NodeFieldUnschedulable = "unschedulable" + NodeFieldVolumesAttached = "volumesAttached" + NodeFieldVolumesInUse = "volumesInUse" + NodeFieldWorker = "worker" +) + +type Node struct { + types.Resource + Allocatable map[string]string `json:"allocatable,omitempty" yaml:"allocatable,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppliedNodeVersion int64 `json:"appliedNodeVersion,omitempty" yaml:"appliedNodeVersion,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Conditions []NodeCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + ControlPlane bool `json:"controlPlane,omitempty" yaml:"controlPlane,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CustomConfig *CustomConfig `json:"customConfig,omitempty" yaml:"customConfig,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DockerInfo *DockerInfo `json:"dockerInfo,omitempty" yaml:"dockerInfo,omitempty"` + Etcd bool `json:"etcd,omitempty" yaml:"etcd,omitempty"` + ExternalIPAddress string `json:"externalIpAddress,omitempty" yaml:"externalIpAddress,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPAddress string `json:"ipAddress,omitempty" yaml:"ipAddress,omitempty"` + Imported bool `json:"imported,omitempty" yaml:"imported,omitempty"` + Info *NodeInfo `json:"info,omitempty" yaml:"info,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeName string `json:"nodeName,omitempty" yaml:"nodeName,omitempty"` + NodePlan *NodePlan `json:"nodePlan,omitempty" yaml:"nodePlan,omitempty"` + NodePoolID string `json:"nodePoolId,omitempty" yaml:"nodePoolId,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + NodeTemplateID string `json:"nodeTemplateId,omitempty" yaml:"nodeTemplateId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PodCidr string `json:"podCidr,omitempty" yaml:"podCidr,omitempty"` + PodCidrs []string `json:"podCidrs,omitempty" yaml:"podCidrs,omitempty"` + ProviderId string `json:"providerId,omitempty" yaml:"providerId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Requested map[string]string `json:"requested,omitempty" yaml:"requested,omitempty"` + RequestedHostname string `json:"requestedHostname,omitempty" yaml:"requestedHostname,omitempty"` + RuntimeHandlers []NodeRuntimeHandler `json:"runtimeHandlers,omitempty" yaml:"runtimeHandlers,omitempty"` + ScaledownTime string `json:"scaledownTime,omitempty" yaml:"scaledownTime,omitempty"` + SshUser string `json:"sshUser,omitempty" yaml:"sshUser,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Taints []Taint `json:"taints,omitempty" yaml:"taints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Unschedulable bool `json:"unschedulable,omitempty" yaml:"unschedulable,omitempty"` + VolumesAttached map[string]AttachedVolume `json:"volumesAttached,omitempty" yaml:"volumesAttached,omitempty"` + VolumesInUse []string `json:"volumesInUse,omitempty" yaml:"volumesInUse,omitempty"` + Worker bool `json:"worker,omitempty" yaml:"worker,omitempty"` +} + +type NodeCollection struct { + types.Collection + Data []Node `json:"data,omitempty"` + client *NodeClient +} + +type NodeClient struct { + apiClient *Client +} + +type NodeOperations interface { + List(opts *types.ListOpts) (*NodeCollection, error) + ListAll(opts *types.ListOpts) (*NodeCollection, error) + Create(opts *Node) (*Node, error) + Update(existing *Node, updates interface{}) (*Node, error) + Replace(existing *Node) (*Node, error) + ByID(id string) (*Node, error) + Delete(container *Node) error + + ActionCordon(resource *Node) error + + ActionDrain(resource *Node, input *NodeDrainInput) error + + ActionScaledown(resource *Node) error + + ActionStopDrain(resource *Node) error + + ActionUncordon(resource *Node) error +} + +func newNodeClient(apiClient *Client) *NodeClient { + return &NodeClient{ + apiClient: apiClient, + } +} + +func (c *NodeClient) Create(container *Node) (*Node, error) { + resp := &Node{} + err := c.apiClient.Ops.DoCreate(NodeType, container, resp) + return resp, err +} + +func (c *NodeClient) Update(existing *Node, updates interface{}) (*Node, error) { + resp := &Node{} + err := c.apiClient.Ops.DoUpdate(NodeType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NodeClient) Replace(obj *Node) (*Node, error) { + resp := &Node{} + err := c.apiClient.Ops.DoReplace(NodeType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NodeClient) List(opts *types.ListOpts) (*NodeCollection, error) { + resp := &NodeCollection{} + err := c.apiClient.Ops.DoList(NodeType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NodeClient) ListAll(opts *types.ListOpts) (*NodeCollection, error) { + resp := &NodeCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NodeCollection) Next() (*NodeCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NodeCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NodeClient) ByID(id string) (*Node, error) { + resp := &Node{} + err := c.apiClient.Ops.DoByID(NodeType, id, resp) + return resp, err +} + +func (c *NodeClient) Delete(container *Node) error { + return c.apiClient.Ops.DoResourceDelete(NodeType, &container.Resource) +} + +func (c *NodeClient) ActionCordon(resource *Node) error { + err := c.apiClient.Ops.DoAction(NodeType, "cordon", &resource.Resource, nil, nil) + return err +} + +func (c *NodeClient) ActionDrain(resource *Node, input *NodeDrainInput) error { + err := c.apiClient.Ops.DoAction(NodeType, "drain", &resource.Resource, input, nil) + return err +} + +func (c *NodeClient) ActionScaledown(resource *Node) error { + err := c.apiClient.Ops.DoAction(NodeType, "scaledown", &resource.Resource, nil, nil) + return err +} + +func (c *NodeClient) ActionStopDrain(resource *Node) error { + err := c.apiClient.Ops.DoAction(NodeType, "stopDrain", &resource.Resource, nil, nil) + return err +} + +func (c *NodeClient) ActionUncordon(resource *Node) error { + err := c.apiClient.Ops.DoAction(NodeType, "uncordon", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_address.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_address.go new file mode 100644 index 0000000..972c248 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_address.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeAddressType = "nodeAddress" + NodeAddressFieldAddress = "address" + NodeAddressFieldType = "type" +) + +type NodeAddress struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_affinity.go new file mode 100644 index 0000000..c1563ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeAffinityType = "nodeAffinity" + NodeAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + NodeAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type NodeAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []PreferredSchedulingTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution *NodeSelector `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_condition.go new file mode 100644 index 0000000..a07010a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + NodeConditionType = "nodeCondition" + NodeConditionFieldLastHeartbeatTime = "lastHeartbeatTime" + NodeConditionFieldLastTransitionTime = "lastTransitionTime" + NodeConditionFieldMessage = "message" + NodeConditionFieldReason = "reason" + NodeConditionFieldStatus = "status" + NodeConditionFieldType = "type" +) + +type NodeCondition struct { + LastHeartbeatTime string `json:"lastHeartbeatTime,omitempty" yaml:"lastHeartbeatTime,omitempty"` + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_source.go new file mode 100644 index 0000000..fc84f34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_source.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeConfigSourceType = "nodeConfigSource" + NodeConfigSourceFieldConfigMap = "configMap" +) + +type NodeConfigSource struct { + ConfigMap *ConfigMapNodeConfigSource `json:"configMap,omitempty" yaml:"configMap,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_status.go new file mode 100644 index 0000000..919108f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_config_status.go @@ -0,0 +1,16 @@ +package client + +const ( + NodeConfigStatusType = "nodeConfigStatus" + NodeConfigStatusFieldActive = "active" + NodeConfigStatusFieldAssigned = "assigned" + NodeConfigStatusFieldError = "error" + NodeConfigStatusFieldLastKnownGood = "lastKnownGood" +) + +type NodeConfigStatus struct { + Active *NodeConfigSource `json:"active,omitempty" yaml:"active,omitempty"` + Assigned *NodeConfigSource `json:"assigned,omitempty" yaml:"assigned,omitempty"` + Error string `json:"error,omitempty" yaml:"error,omitempty"` + LastKnownGood *NodeConfigSource `json:"lastKnownGood,omitempty" yaml:"lastKnownGood,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_daemon_endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_daemon_endpoints.go new file mode 100644 index 0000000..57da90d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_daemon_endpoints.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeDaemonEndpointsType = "nodeDaemonEndpoints" + NodeDaemonEndpointsFieldKubeletEndpoint = "kubeletEndpoint" +) + +type NodeDaemonEndpoints struct { + KubeletEndpoint *DaemonEndpoint `json:"kubeletEndpoint,omitempty" yaml:"kubeletEndpoint,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_drain_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_drain_input.go new file mode 100644 index 0000000..974ac7e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_drain_input.go @@ -0,0 +1,18 @@ +package client + +const ( + NodeDrainInputType = "nodeDrainInput" + NodeDrainInputFieldDeleteLocalData = "deleteLocalData" + NodeDrainInputFieldForce = "force" + NodeDrainInputFieldGracePeriod = "gracePeriod" + NodeDrainInputFieldIgnoreDaemonSets = "ignoreDaemonSets" + NodeDrainInputFieldTimeout = "timeout" +) + +type NodeDrainInput struct { + DeleteLocalData bool `json:"deleteLocalData,omitempty" yaml:"deleteLocalData,omitempty"` + Force bool `json:"force,omitempty" yaml:"force,omitempty"` + GracePeriod int64 `json:"gracePeriod,omitempty" yaml:"gracePeriod,omitempty"` + IgnoreDaemonSets *bool `json:"ignoreDaemonSets,omitempty" yaml:"ignoreDaemonSets,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver.go new file mode 100644 index 0000000..4e0cefd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver.go @@ -0,0 +1,160 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NodeDriverType = "nodeDriver" + NodeDriverFieldActive = "active" + NodeDriverFieldAddCloudCredential = "addCloudCredential" + NodeDriverFieldAnnotations = "annotations" + NodeDriverFieldBuiltin = "builtin" + NodeDriverFieldChecksum = "checksum" + NodeDriverFieldCreated = "created" + NodeDriverFieldCreatorID = "creatorId" + NodeDriverFieldDescription = "description" + NodeDriverFieldExternalID = "externalId" + NodeDriverFieldLabels = "labels" + NodeDriverFieldName = "name" + NodeDriverFieldOwnerReferences = "ownerReferences" + NodeDriverFieldRemoved = "removed" + NodeDriverFieldState = "state" + NodeDriverFieldStatus = "status" + NodeDriverFieldTransitioning = "transitioning" + NodeDriverFieldTransitioningMessage = "transitioningMessage" + NodeDriverFieldUIURL = "uiUrl" + NodeDriverFieldURL = "url" + NodeDriverFieldUUID = "uuid" + NodeDriverFieldWhitelistDomains = "whitelistDomains" +) + +type NodeDriver struct { + types.Resource + Active bool `json:"active,omitempty" yaml:"active,omitempty"` + AddCloudCredential bool `json:"addCloudCredential,omitempty" yaml:"addCloudCredential,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Builtin bool `json:"builtin,omitempty" yaml:"builtin,omitempty"` + Checksum string `json:"checksum,omitempty" yaml:"checksum,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *NodeDriverStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UIURL string `json:"uiUrl,omitempty" yaml:"uiUrl,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WhitelistDomains []string `json:"whitelistDomains,omitempty" yaml:"whitelistDomains,omitempty"` +} + +type NodeDriverCollection struct { + types.Collection + Data []NodeDriver `json:"data,omitempty"` + client *NodeDriverClient +} + +type NodeDriverClient struct { + apiClient *Client +} + +type NodeDriverOperations interface { + List(opts *types.ListOpts) (*NodeDriverCollection, error) + ListAll(opts *types.ListOpts) (*NodeDriverCollection, error) + Create(opts *NodeDriver) (*NodeDriver, error) + Update(existing *NodeDriver, updates interface{}) (*NodeDriver, error) + Replace(existing *NodeDriver) (*NodeDriver, error) + ByID(id string) (*NodeDriver, error) + Delete(container *NodeDriver) error + + ActionActivate(resource *NodeDriver) (*NodeDriver, error) + + ActionDeactivate(resource *NodeDriver) (*NodeDriver, error) +} + +func newNodeDriverClient(apiClient *Client) *NodeDriverClient { + return &NodeDriverClient{ + apiClient: apiClient, + } +} + +func (c *NodeDriverClient) Create(container *NodeDriver) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoCreate(NodeDriverType, container, resp) + return resp, err +} + +func (c *NodeDriverClient) Update(existing *NodeDriver, updates interface{}) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoUpdate(NodeDriverType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NodeDriverClient) Replace(obj *NodeDriver) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoReplace(NodeDriverType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NodeDriverClient) List(opts *types.ListOpts) (*NodeDriverCollection, error) { + resp := &NodeDriverCollection{} + err := c.apiClient.Ops.DoList(NodeDriverType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NodeDriverClient) ListAll(opts *types.ListOpts) (*NodeDriverCollection, error) { + resp := &NodeDriverCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NodeDriverCollection) Next() (*NodeDriverCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NodeDriverCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NodeDriverClient) ByID(id string) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoByID(NodeDriverType, id, resp) + return resp, err +} + +func (c *NodeDriverClient) Delete(container *NodeDriver) error { + return c.apiClient.Ops.DoResourceDelete(NodeDriverType, &container.Resource) +} + +func (c *NodeDriverClient) ActionActivate(resource *NodeDriver) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoAction(NodeDriverType, "activate", &resource.Resource, nil, resp) + return resp, err +} + +func (c *NodeDriverClient) ActionDeactivate(resource *NodeDriver) (*NodeDriver, error) { + resp := &NodeDriver{} + err := c.apiClient.Ops.DoAction(NodeDriverType, "deactivate", &resource.Resource, nil, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_spec.go new file mode 100644 index 0000000..d8a64cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_spec.go @@ -0,0 +1,28 @@ +package client + +const ( + NodeDriverSpecType = "nodeDriverSpec" + NodeDriverSpecFieldActive = "active" + NodeDriverSpecFieldAddCloudCredential = "addCloudCredential" + NodeDriverSpecFieldBuiltin = "builtin" + NodeDriverSpecFieldChecksum = "checksum" + NodeDriverSpecFieldDescription = "description" + NodeDriverSpecFieldDisplayName = "displayName" + NodeDriverSpecFieldExternalID = "externalId" + NodeDriverSpecFieldUIURL = "uiUrl" + NodeDriverSpecFieldURL = "url" + NodeDriverSpecFieldWhitelistDomains = "whitelistDomains" +) + +type NodeDriverSpec struct { + Active bool `json:"active,omitempty" yaml:"active,omitempty"` + AddCloudCredential bool `json:"addCloudCredential,omitempty" yaml:"addCloudCredential,omitempty"` + Builtin bool `json:"builtin,omitempty" yaml:"builtin,omitempty"` + Checksum string `json:"checksum,omitempty" yaml:"checksum,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + UIURL string `json:"uiUrl,omitempty" yaml:"uiUrl,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + WhitelistDomains []string `json:"whitelistDomains,omitempty" yaml:"whitelistDomains,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_status.go new file mode 100644 index 0000000..971f6ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_driver_status.go @@ -0,0 +1,16 @@ +package client + +const ( + NodeDriverStatusType = "nodeDriverStatus" + NodeDriverStatusFieldAppliedChecksum = "appliedChecksum" + NodeDriverStatusFieldAppliedDockerMachineVersion = "appliedDockerMachineVersion" + NodeDriverStatusFieldAppliedURL = "appliedURL" + NodeDriverStatusFieldConditions = "conditions" +) + +type NodeDriverStatus struct { + AppliedChecksum string `json:"appliedChecksum,omitempty" yaml:"appliedChecksum,omitempty"` + AppliedDockerMachineVersion string `json:"appliedDockerMachineVersion,omitempty" yaml:"appliedDockerMachineVersion,omitempty"` + AppliedURL string `json:"appliedURL,omitempty" yaml:"appliedURL,omitempty"` + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_group.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_group.go new file mode 100644 index 0000000..733983a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_group.go @@ -0,0 +1,48 @@ +package client + +const ( + NodeGroupType = "nodeGroup" + NodeGroupFieldArm = "arm" + NodeGroupFieldDesiredSize = "desiredSize" + NodeGroupFieldDiskSize = "diskSize" + NodeGroupFieldEc2SshKey = "ec2SshKey" + NodeGroupFieldGpu = "gpu" + NodeGroupFieldImageID = "imageId" + NodeGroupFieldInstanceType = "instanceType" + NodeGroupFieldLabels = "labels" + NodeGroupFieldLaunchTemplate = "launchTemplate" + NodeGroupFieldMaxSize = "maxSize" + NodeGroupFieldMinSize = "minSize" + NodeGroupFieldNodeRole = "nodeRole" + NodeGroupFieldNodegroupName = "nodegroupName" + NodeGroupFieldRequestSpotInstances = "requestSpotInstances" + NodeGroupFieldResourceTags = "resourceTags" + NodeGroupFieldSpotInstanceTypes = "spotInstanceTypes" + NodeGroupFieldSubnets = "subnets" + NodeGroupFieldTags = "tags" + NodeGroupFieldUserData = "userData" + NodeGroupFieldVersion = "version" +) + +type NodeGroup struct { + Arm *bool `json:"arm,omitempty" yaml:"arm,omitempty"` + DesiredSize *int64 `json:"desiredSize,omitempty" yaml:"desiredSize,omitempty"` + DiskSize *int64 `json:"diskSize,omitempty" yaml:"diskSize,omitempty"` + Ec2SshKey *string `json:"ec2SshKey,omitempty" yaml:"ec2SshKey,omitempty"` + Gpu *bool `json:"gpu,omitempty" yaml:"gpu,omitempty"` + ImageID *string `json:"imageId,omitempty" yaml:"imageId,omitempty"` + InstanceType *string `json:"instanceType,omitempty" yaml:"instanceType,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LaunchTemplate *LaunchTemplate `json:"launchTemplate,omitempty" yaml:"launchTemplate,omitempty"` + MaxSize *int64 `json:"maxSize,omitempty" yaml:"maxSize,omitempty"` + MinSize *int64 `json:"minSize,omitempty" yaml:"minSize,omitempty"` + NodeRole *string `json:"nodeRole,omitempty" yaml:"nodeRole,omitempty"` + NodegroupName *string `json:"nodegroupName,omitempty" yaml:"nodegroupName,omitempty"` + RequestSpotInstances *bool `json:"requestSpotInstances,omitempty" yaml:"requestSpotInstances,omitempty"` + ResourceTags map[string]string `json:"resourceTags,omitempty" yaml:"resourceTags,omitempty"` + SpotInstanceTypes []string `json:"spotInstanceTypes,omitempty" yaml:"spotInstanceTypes,omitempty"` + Subnets []string `json:"subnets,omitempty" yaml:"subnets,omitempty"` + Tags map[string]string `json:"tags,omitempty" yaml:"tags,omitempty"` + UserData *string `json:"userData,omitempty" yaml:"userData,omitempty"` + Version *string `json:"version,omitempty" yaml:"version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_info.go new file mode 100644 index 0000000..d3d8ac4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_info.go @@ -0,0 +1,16 @@ +package client + +const ( + NodeInfoType = "nodeInfo" + NodeInfoFieldCPU = "cpu" + NodeInfoFieldKubernetes = "kubernetes" + NodeInfoFieldMemory = "memory" + NodeInfoFieldOS = "os" +) + +type NodeInfo struct { + CPU *CPUInfo `json:"cpu,omitempty" yaml:"cpu,omitempty"` + Kubernetes *KubernetesInfo `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty"` + Memory *MemoryInfo `json:"memory,omitempty" yaml:"memory,omitempty"` + OS *OSInfo `json:"os,omitempty" yaml:"os,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_plan.go new file mode 100644 index 0000000..4bf3c78 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_plan.go @@ -0,0 +1,14 @@ +package client + +const ( + NodePlanType = "nodePlan" + NodePlanFieldAgentCheckInterval = "agentCheckInterval" + NodePlanFieldPlan = "plan" + NodePlanFieldVersion = "version" +) + +type NodePlan struct { + AgentCheckInterval int64 `json:"agentCheckInterval,omitempty" yaml:"agentCheckInterval,omitempty"` + Plan *RKEConfigNodePlan `json:"plan,omitempty" yaml:"plan,omitempty"` + Version int64 `json:"version,omitempty" yaml:"version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool.go new file mode 100644 index 0000000..345acd2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool.go @@ -0,0 +1,156 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NodePoolType = "nodePool" + NodePoolFieldAnnotations = "annotations" + NodePoolFieldClusterID = "clusterId" + NodePoolFieldControlPlane = "controlPlane" + NodePoolFieldCreated = "created" + NodePoolFieldCreatorID = "creatorId" + NodePoolFieldDeleteNotReadyAfterSecs = "deleteNotReadyAfterSecs" + NodePoolFieldDisplayName = "displayName" + NodePoolFieldDrainBeforeDelete = "drainBeforeDelete" + NodePoolFieldDriver = "driver" + NodePoolFieldEtcd = "etcd" + NodePoolFieldHostnamePrefix = "hostnamePrefix" + NodePoolFieldLabels = "labels" + NodePoolFieldName = "name" + NodePoolFieldNamespaceId = "namespaceId" + NodePoolFieldNodeAnnotations = "nodeAnnotations" + NodePoolFieldNodeLabels = "nodeLabels" + NodePoolFieldNodeTaints = "nodeTaints" + NodePoolFieldNodeTemplateID = "nodeTemplateId" + NodePoolFieldOwnerReferences = "ownerReferences" + NodePoolFieldQuantity = "quantity" + NodePoolFieldRemoved = "removed" + NodePoolFieldState = "state" + NodePoolFieldStatus = "status" + NodePoolFieldTransitioning = "transitioning" + NodePoolFieldTransitioningMessage = "transitioningMessage" + NodePoolFieldUUID = "uuid" + NodePoolFieldWorker = "worker" +) + +type NodePool struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + ControlPlane bool `json:"controlPlane,omitempty" yaml:"controlPlane,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DeleteNotReadyAfterSecs int64 `json:"deleteNotReadyAfterSecs,omitempty" yaml:"deleteNotReadyAfterSecs,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + DrainBeforeDelete bool `json:"drainBeforeDelete,omitempty" yaml:"drainBeforeDelete,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + Etcd bool `json:"etcd,omitempty" yaml:"etcd,omitempty"` + HostnamePrefix string `json:"hostnamePrefix,omitempty" yaml:"hostnamePrefix,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty" yaml:"nodeAnnotations,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" yaml:"nodeLabels,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + NodeTemplateID string `json:"nodeTemplateId,omitempty" yaml:"nodeTemplateId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Quantity int64 `json:"quantity,omitempty" yaml:"quantity,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *NodePoolStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Worker bool `json:"worker,omitempty" yaml:"worker,omitempty"` +} + +type NodePoolCollection struct { + types.Collection + Data []NodePool `json:"data,omitempty"` + client *NodePoolClient +} + +type NodePoolClient struct { + apiClient *Client +} + +type NodePoolOperations interface { + List(opts *types.ListOpts) (*NodePoolCollection, error) + ListAll(opts *types.ListOpts) (*NodePoolCollection, error) + Create(opts *NodePool) (*NodePool, error) + Update(existing *NodePool, updates interface{}) (*NodePool, error) + Replace(existing *NodePool) (*NodePool, error) + ByID(id string) (*NodePool, error) + Delete(container *NodePool) error +} + +func newNodePoolClient(apiClient *Client) *NodePoolClient { + return &NodePoolClient{ + apiClient: apiClient, + } +} + +func (c *NodePoolClient) Create(container *NodePool) (*NodePool, error) { + resp := &NodePool{} + err := c.apiClient.Ops.DoCreate(NodePoolType, container, resp) + return resp, err +} + +func (c *NodePoolClient) Update(existing *NodePool, updates interface{}) (*NodePool, error) { + resp := &NodePool{} + err := c.apiClient.Ops.DoUpdate(NodePoolType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NodePoolClient) Replace(obj *NodePool) (*NodePool, error) { + resp := &NodePool{} + err := c.apiClient.Ops.DoReplace(NodePoolType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NodePoolClient) List(opts *types.ListOpts) (*NodePoolCollection, error) { + resp := &NodePoolCollection{} + err := c.apiClient.Ops.DoList(NodePoolType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NodePoolClient) ListAll(opts *types.ListOpts) (*NodePoolCollection, error) { + resp := &NodePoolCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NodePoolCollection) Next() (*NodePoolCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NodePoolCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NodePoolClient) ByID(id string) (*NodePool, error) { + resp := &NodePool{} + err := c.apiClient.Ops.DoByID(NodePoolType, id, resp) + return resp, err +} + +func (c *NodePoolClient) Delete(container *NodePool) error { + return c.apiClient.Ops.DoResourceDelete(NodePoolType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_spec.go new file mode 100644 index 0000000..408463f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_spec.go @@ -0,0 +1,34 @@ +package client + +const ( + NodePoolSpecType = "nodePoolSpec" + NodePoolSpecFieldClusterID = "clusterId" + NodePoolSpecFieldControlPlane = "controlPlane" + NodePoolSpecFieldDeleteNotReadyAfterSecs = "deleteNotReadyAfterSecs" + NodePoolSpecFieldDisplayName = "displayName" + NodePoolSpecFieldDrainBeforeDelete = "drainBeforeDelete" + NodePoolSpecFieldEtcd = "etcd" + NodePoolSpecFieldHostnamePrefix = "hostnamePrefix" + NodePoolSpecFieldNodeAnnotations = "nodeAnnotations" + NodePoolSpecFieldNodeLabels = "nodeLabels" + NodePoolSpecFieldNodeTaints = "nodeTaints" + NodePoolSpecFieldNodeTemplateID = "nodeTemplateId" + NodePoolSpecFieldQuantity = "quantity" + NodePoolSpecFieldWorker = "worker" +) + +type NodePoolSpec struct { + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + ControlPlane bool `json:"controlPlane,omitempty" yaml:"controlPlane,omitempty"` + DeleteNotReadyAfterSecs int64 `json:"deleteNotReadyAfterSecs,omitempty" yaml:"deleteNotReadyAfterSecs,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + DrainBeforeDelete bool `json:"drainBeforeDelete,omitempty" yaml:"drainBeforeDelete,omitempty"` + Etcd bool `json:"etcd,omitempty" yaml:"etcd,omitempty"` + HostnamePrefix string `json:"hostnamePrefix,omitempty" yaml:"hostnamePrefix,omitempty"` + NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty" yaml:"nodeAnnotations,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" yaml:"nodeLabels,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + NodeTemplateID string `json:"nodeTemplateId,omitempty" yaml:"nodeTemplateId,omitempty"` + Quantity int64 `json:"quantity,omitempty" yaml:"quantity,omitempty"` + Worker bool `json:"worker,omitempty" yaml:"worker,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_status.go new file mode 100644 index 0000000..f5c7ed7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_pool_status.go @@ -0,0 +1,10 @@ +package client + +const ( + NodePoolStatusType = "nodePoolStatus" + NodePoolStatusFieldConditions = "conditions" +) + +type NodePoolStatus struct { + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler.go new file mode 100644 index 0000000..500e2c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeRuntimeHandlerType = "nodeRuntimeHandler" + NodeRuntimeHandlerFieldFeatures = "features" + NodeRuntimeHandlerFieldName = "name" +) + +type NodeRuntimeHandler struct { + Features *NodeRuntimeHandlerFeatures `json:"features,omitempty" yaml:"features,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler_features.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler_features.go new file mode 100644 index 0000000..dda38dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_runtime_handler_features.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeRuntimeHandlerFeaturesType = "nodeRuntimeHandlerFeatures" + NodeRuntimeHandlerFeaturesFieldRecursiveReadOnlyMounts = "recursiveReadOnlyMounts" +) + +type NodeRuntimeHandlerFeatures struct { + RecursiveReadOnlyMounts *bool `json:"recursiveReadOnlyMounts,omitempty" yaml:"recursiveReadOnlyMounts,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector.go new file mode 100644 index 0000000..721a16f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeSelectorType = "nodeSelector" + NodeSelectorFieldNodeSelectorTerms = "nodeSelectorTerms" +) + +type NodeSelector struct { + NodeSelectorTerms []NodeSelectorTerm `json:"nodeSelectorTerms,omitempty" yaml:"nodeSelectorTerms,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_requirement.go new file mode 100644 index 0000000..9338a8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + NodeSelectorRequirementType = "nodeSelectorRequirement" + NodeSelectorRequirementFieldKey = "key" + NodeSelectorRequirementFieldOperator = "operator" + NodeSelectorRequirementFieldValues = "values" +) + +type NodeSelectorRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_term.go new file mode 100644 index 0000000..11bf256 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_selector_term.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeSelectorTermType = "nodeSelectorTerm" + NodeSelectorTermFieldMatchExpressions = "matchExpressions" + NodeSelectorTermFieldMatchFields = "matchFields" +) + +type NodeSelectorTerm struct { + MatchExpressions []NodeSelectorRequirement `json:"matchExpressions,omitempty" yaml:"matchExpressions,omitempty"` + MatchFields []NodeSelectorRequirement `json:"matchFields,omitempty" yaml:"matchFields,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_spec.go new file mode 100644 index 0000000..f2f6eef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_spec.go @@ -0,0 +1,50 @@ +package client + +const ( + NodeSpecType = "nodeSpec" + NodeSpecFieldControlPlane = "controlPlane" + NodeSpecFieldCustomConfig = "customConfig" + NodeSpecFieldDescription = "description" + NodeSpecFieldDesiredNodeTaints = "desiredNodeTaints" + NodeSpecFieldDesiredNodeUnschedulable = "desiredNodeUnschedulable" + NodeSpecFieldDisplayName = "displayName" + NodeSpecFieldEtcd = "etcd" + NodeSpecFieldImported = "imported" + NodeSpecFieldMetadataUpdate = "metadataUpdate" + NodeSpecFieldNodeDrainInput = "nodeDrainInput" + NodeSpecFieldNodePoolID = "nodePoolId" + NodeSpecFieldNodeTemplateID = "nodeTemplateId" + NodeSpecFieldPodCidr = "podCidr" + NodeSpecFieldPodCidrs = "podCidrs" + NodeSpecFieldProviderId = "providerId" + NodeSpecFieldRequestedHostname = "requestedHostname" + NodeSpecFieldScaledownTime = "scaledownTime" + NodeSpecFieldTaints = "taints" + NodeSpecFieldUnschedulable = "unschedulable" + NodeSpecFieldUpdateTaintsFromAPI = "updateTaintsFromAPI" + NodeSpecFieldWorker = "worker" +) + +type NodeSpec struct { + ControlPlane bool `json:"controlPlane,omitempty" yaml:"controlPlane,omitempty"` + CustomConfig *CustomConfig `json:"customConfig,omitempty" yaml:"customConfig,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DesiredNodeTaints []Taint `json:"desiredNodeTaints,omitempty" yaml:"desiredNodeTaints,omitempty"` + DesiredNodeUnschedulable string `json:"desiredNodeUnschedulable,omitempty" yaml:"desiredNodeUnschedulable,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + Etcd bool `json:"etcd,omitempty" yaml:"etcd,omitempty"` + Imported bool `json:"imported,omitempty" yaml:"imported,omitempty"` + MetadataUpdate *MetadataUpdate `json:"metadataUpdate,omitempty" yaml:"metadataUpdate,omitempty"` + NodeDrainInput *NodeDrainInput `json:"nodeDrainInput,omitempty" yaml:"nodeDrainInput,omitempty"` + NodePoolID string `json:"nodePoolId,omitempty" yaml:"nodePoolId,omitempty"` + NodeTemplateID string `json:"nodeTemplateId,omitempty" yaml:"nodeTemplateId,omitempty"` + PodCidr string `json:"podCidr,omitempty" yaml:"podCidr,omitempty"` + PodCidrs []string `json:"podCidrs,omitempty" yaml:"podCidrs,omitempty"` + ProviderId string `json:"providerId,omitempty" yaml:"providerId,omitempty"` + RequestedHostname string `json:"requestedHostname,omitempty" yaml:"requestedHostname,omitempty"` + ScaledownTime string `json:"scaledownTime,omitempty" yaml:"scaledownTime,omitempty"` + Taints []Taint `json:"taints,omitempty" yaml:"taints,omitempty"` + Unschedulable bool `json:"unschedulable,omitempty" yaml:"unschedulable,omitempty"` + UpdateTaintsFromAPI *bool `json:"updateTaintsFromAPI,omitempty" yaml:"updateTaintsFromAPI,omitempty"` + Worker bool `json:"worker,omitempty" yaml:"worker,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_status.go new file mode 100644 index 0000000..99a1754 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_status.go @@ -0,0 +1,48 @@ +package client + +const ( + NodeStatusType = "nodeStatus" + NodeStatusFieldAllocatable = "allocatable" + NodeStatusFieldAppliedNodeVersion = "appliedNodeVersion" + NodeStatusFieldCapacity = "capacity" + NodeStatusFieldConditions = "conditions" + NodeStatusFieldDockerInfo = "dockerInfo" + NodeStatusFieldExternalIPAddress = "externalIpAddress" + NodeStatusFieldHostname = "hostname" + NodeStatusFieldIPAddress = "ipAddress" + NodeStatusFieldInfo = "info" + NodeStatusFieldLimits = "limits" + NodeStatusFieldNodeAnnotations = "nodeAnnotations" + NodeStatusFieldNodeConfig = "rkeNode" + NodeStatusFieldNodeLabels = "nodeLabels" + NodeStatusFieldNodeName = "nodeName" + NodeStatusFieldNodePlan = "nodePlan" + NodeStatusFieldNodeTaints = "nodeTaints" + NodeStatusFieldRequested = "requested" + NodeStatusFieldRuntimeHandlers = "runtimeHandlers" + NodeStatusFieldVolumesAttached = "volumesAttached" + NodeStatusFieldVolumesInUse = "volumesInUse" +) + +type NodeStatus struct { + Allocatable map[string]string `json:"allocatable,omitempty" yaml:"allocatable,omitempty"` + AppliedNodeVersion int64 `json:"appliedNodeVersion,omitempty" yaml:"appliedNodeVersion,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + Conditions []NodeCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + DockerInfo *DockerInfo `json:"dockerInfo,omitempty" yaml:"dockerInfo,omitempty"` + ExternalIPAddress string `json:"externalIpAddress,omitempty" yaml:"externalIpAddress,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPAddress string `json:"ipAddress,omitempty" yaml:"ipAddress,omitempty"` + Info *NodeInfo `json:"info,omitempty" yaml:"info,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + NodeAnnotations map[string]string `json:"nodeAnnotations,omitempty" yaml:"nodeAnnotations,omitempty"` + NodeConfig *RKEConfigNode `json:"rkeNode,omitempty" yaml:"rkeNode,omitempty"` + NodeLabels map[string]string `json:"nodeLabels,omitempty" yaml:"nodeLabels,omitempty"` + NodeName string `json:"nodeName,omitempty" yaml:"nodeName,omitempty"` + NodePlan *NodePlan `json:"nodePlan,omitempty" yaml:"nodePlan,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + Requested map[string]string `json:"requested,omitempty" yaml:"requested,omitempty"` + RuntimeHandlers []NodeRuntimeHandler `json:"runtimeHandlers,omitempty" yaml:"runtimeHandlers,omitempty"` + VolumesAttached map[string]AttachedVolume `json:"volumesAttached,omitempty" yaml:"volumesAttached,omitempty"` + VolumesInUse []string `json:"volumesInUse,omitempty" yaml:"volumesInUse,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_system_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_system_info.go new file mode 100644 index 0000000..c5632f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_system_info.go @@ -0,0 +1,28 @@ +package client + +const ( + NodeSystemInfoType = "nodeSystemInfo" + NodeSystemInfoFieldArchitecture = "architecture" + NodeSystemInfoFieldBootID = "bootID" + NodeSystemInfoFieldContainerRuntimeVersion = "containerRuntimeVersion" + NodeSystemInfoFieldKernelVersion = "kernelVersion" + NodeSystemInfoFieldKubeProxyVersion = "kubeProxyVersion" + NodeSystemInfoFieldKubeletVersion = "kubeletVersion" + NodeSystemInfoFieldMachineID = "machineID" + NodeSystemInfoFieldOSImage = "osImage" + NodeSystemInfoFieldOperatingSystem = "operatingSystem" + NodeSystemInfoFieldSystemUUID = "systemUUID" +) + +type NodeSystemInfo struct { + Architecture string `json:"architecture,omitempty" yaml:"architecture,omitempty"` + BootID string `json:"bootID,omitempty" yaml:"bootID,omitempty"` + ContainerRuntimeVersion string `json:"containerRuntimeVersion,omitempty" yaml:"containerRuntimeVersion,omitempty"` + KernelVersion string `json:"kernelVersion,omitempty" yaml:"kernelVersion,omitempty"` + KubeProxyVersion string `json:"kubeProxyVersion,omitempty" yaml:"kubeProxyVersion,omitempty"` + KubeletVersion string `json:"kubeletVersion,omitempty" yaml:"kubeletVersion,omitempty"` + MachineID string `json:"machineID,omitempty" yaml:"machineID,omitempty"` + OSImage string `json:"osImage,omitempty" yaml:"osImage,omitempty"` + OperatingSystem string `json:"operatingSystem,omitempty" yaml:"operatingSystem,omitempty"` + SystemUUID string `json:"systemUUID,omitempty" yaml:"systemUUID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template.go new file mode 100644 index 0000000..bd6ce9c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template.go @@ -0,0 +1,160 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NodeTemplateType = "nodeTemplate" + NodeTemplateFieldAnnotations = "annotations" + NodeTemplateFieldAuthCertificateAuthority = "authCertificateAuthority" + NodeTemplateFieldAuthKey = "authKey" + NodeTemplateFieldCloudCredentialID = "cloudCredentialId" + NodeTemplateFieldCreated = "created" + NodeTemplateFieldCreatorID = "creatorId" + NodeTemplateFieldDescription = "description" + NodeTemplateFieldDockerVersion = "dockerVersion" + NodeTemplateFieldDriver = "driver" + NodeTemplateFieldEngineEnv = "engineEnv" + NodeTemplateFieldEngineInsecureRegistry = "engineInsecureRegistry" + NodeTemplateFieldEngineInstallURL = "engineInstallURL" + NodeTemplateFieldEngineLabel = "engineLabel" + NodeTemplateFieldEngineOpt = "engineOpt" + NodeTemplateFieldEngineRegistryMirror = "engineRegistryMirror" + NodeTemplateFieldEngineStorageDriver = "engineStorageDriver" + NodeTemplateFieldLabels = "labels" + NodeTemplateFieldLogOpt = "logOpt" + NodeTemplateFieldName = "name" + NodeTemplateFieldNodeTaints = "nodeTaints" + NodeTemplateFieldOwnerReferences = "ownerReferences" + NodeTemplateFieldRemoved = "removed" + NodeTemplateFieldState = "state" + NodeTemplateFieldStatus = "status" + NodeTemplateFieldStorageOpt = "storageOpt" + NodeTemplateFieldTransitioning = "transitioning" + NodeTemplateFieldTransitioningMessage = "transitioningMessage" + NodeTemplateFieldUUID = "uuid" + NodeTemplateFieldUseInternalIPAddress = "useInternalIpAddress" +) + +type NodeTemplate struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthCertificateAuthority string `json:"authCertificateAuthority,omitempty" yaml:"authCertificateAuthority,omitempty"` + AuthKey string `json:"authKey,omitempty" yaml:"authKey,omitempty"` + CloudCredentialID string `json:"cloudCredentialId,omitempty" yaml:"cloudCredentialId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DockerVersion string `json:"dockerVersion,omitempty" yaml:"dockerVersion,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + EngineEnv map[string]string `json:"engineEnv,omitempty" yaml:"engineEnv,omitempty"` + EngineInsecureRegistry []string `json:"engineInsecureRegistry,omitempty" yaml:"engineInsecureRegistry,omitempty"` + EngineInstallURL string `json:"engineInstallURL,omitempty" yaml:"engineInstallURL,omitempty"` + EngineLabel map[string]string `json:"engineLabel,omitempty" yaml:"engineLabel,omitempty"` + EngineOpt map[string]string `json:"engineOpt,omitempty" yaml:"engineOpt,omitempty"` + EngineRegistryMirror []string `json:"engineRegistryMirror,omitempty" yaml:"engineRegistryMirror,omitempty"` + EngineStorageDriver string `json:"engineStorageDriver,omitempty" yaml:"engineStorageDriver,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LogOpt map[string]string `json:"logOpt,omitempty" yaml:"logOpt,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *NodeTemplateStatus `json:"status,omitempty" yaml:"status,omitempty"` + StorageOpt map[string]string `json:"storageOpt,omitempty" yaml:"storageOpt,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UseInternalIPAddress *bool `json:"useInternalIpAddress,omitempty" yaml:"useInternalIpAddress,omitempty"` +} + +type NodeTemplateCollection struct { + types.Collection + Data []NodeTemplate `json:"data,omitempty"` + client *NodeTemplateClient +} + +type NodeTemplateClient struct { + apiClient *Client +} + +type NodeTemplateOperations interface { + List(opts *types.ListOpts) (*NodeTemplateCollection, error) + ListAll(opts *types.ListOpts) (*NodeTemplateCollection, error) + Create(opts *NodeTemplate) (*NodeTemplate, error) + Update(existing *NodeTemplate, updates interface{}) (*NodeTemplate, error) + Replace(existing *NodeTemplate) (*NodeTemplate, error) + ByID(id string) (*NodeTemplate, error) + Delete(container *NodeTemplate) error +} + +func newNodeTemplateClient(apiClient *Client) *NodeTemplateClient { + return &NodeTemplateClient{ + apiClient: apiClient, + } +} + +func (c *NodeTemplateClient) Create(container *NodeTemplate) (*NodeTemplate, error) { + resp := &NodeTemplate{} + err := c.apiClient.Ops.DoCreate(NodeTemplateType, container, resp) + return resp, err +} + +func (c *NodeTemplateClient) Update(existing *NodeTemplate, updates interface{}) (*NodeTemplate, error) { + resp := &NodeTemplate{} + err := c.apiClient.Ops.DoUpdate(NodeTemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NodeTemplateClient) Replace(obj *NodeTemplate) (*NodeTemplate, error) { + resp := &NodeTemplate{} + err := c.apiClient.Ops.DoReplace(NodeTemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NodeTemplateClient) List(opts *types.ListOpts) (*NodeTemplateCollection, error) { + resp := &NodeTemplateCollection{} + err := c.apiClient.Ops.DoList(NodeTemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NodeTemplateClient) ListAll(opts *types.ListOpts) (*NodeTemplateCollection, error) { + resp := &NodeTemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NodeTemplateCollection) Next() (*NodeTemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NodeTemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NodeTemplateClient) ByID(id string) (*NodeTemplate, error) { + resp := &NodeTemplate{} + err := c.apiClient.Ops.DoByID(NodeTemplateType, id, resp) + return resp, err +} + +func (c *NodeTemplateClient) Delete(container *NodeTemplate) error { + return c.apiClient.Ops.DoResourceDelete(NodeTemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_condition.go new file mode 100644 index 0000000..c3b3fe9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + NodeTemplateConditionType = "nodeTemplateCondition" + NodeTemplateConditionFieldLastTransitionTime = "lastTransitionTime" + NodeTemplateConditionFieldLastUpdateTime = "lastUpdateTime" + NodeTemplateConditionFieldReason = "reason" + NodeTemplateConditionFieldStatus = "status" + NodeTemplateConditionFieldType = "type" +) + +type NodeTemplateCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_spec.go new file mode 100644 index 0000000..e930722 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_spec.go @@ -0,0 +1,44 @@ +package client + +const ( + NodeTemplateSpecType = "nodeTemplateSpec" + NodeTemplateSpecFieldAuthCertificateAuthority = "authCertificateAuthority" + NodeTemplateSpecFieldAuthKey = "authKey" + NodeTemplateSpecFieldCloudCredentialID = "cloudCredentialId" + NodeTemplateSpecFieldDescription = "description" + NodeTemplateSpecFieldDisplayName = "displayName" + NodeTemplateSpecFieldDockerVersion = "dockerVersion" + NodeTemplateSpecFieldDriver = "driver" + NodeTemplateSpecFieldEngineEnv = "engineEnv" + NodeTemplateSpecFieldEngineInsecureRegistry = "engineInsecureRegistry" + NodeTemplateSpecFieldEngineInstallURL = "engineInstallURL" + NodeTemplateSpecFieldEngineLabel = "engineLabel" + NodeTemplateSpecFieldEngineOpt = "engineOpt" + NodeTemplateSpecFieldEngineRegistryMirror = "engineRegistryMirror" + NodeTemplateSpecFieldEngineStorageDriver = "engineStorageDriver" + NodeTemplateSpecFieldLogOpt = "logOpt" + NodeTemplateSpecFieldNodeTaints = "nodeTaints" + NodeTemplateSpecFieldStorageOpt = "storageOpt" + NodeTemplateSpecFieldUseInternalIPAddress = "useInternalIpAddress" +) + +type NodeTemplateSpec struct { + AuthCertificateAuthority string `json:"authCertificateAuthority,omitempty" yaml:"authCertificateAuthority,omitempty"` + AuthKey string `json:"authKey,omitempty" yaml:"authKey,omitempty"` + CloudCredentialID string `json:"cloudCredentialId,omitempty" yaml:"cloudCredentialId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + DockerVersion string `json:"dockerVersion,omitempty" yaml:"dockerVersion,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + EngineEnv map[string]string `json:"engineEnv,omitempty" yaml:"engineEnv,omitempty"` + EngineInsecureRegistry []string `json:"engineInsecureRegistry,omitempty" yaml:"engineInsecureRegistry,omitempty"` + EngineInstallURL string `json:"engineInstallURL,omitempty" yaml:"engineInstallURL,omitempty"` + EngineLabel map[string]string `json:"engineLabel,omitempty" yaml:"engineLabel,omitempty"` + EngineOpt map[string]string `json:"engineOpt,omitempty" yaml:"engineOpt,omitempty"` + EngineRegistryMirror []string `json:"engineRegistryMirror,omitempty" yaml:"engineRegistryMirror,omitempty"` + EngineStorageDriver string `json:"engineStorageDriver,omitempty" yaml:"engineStorageDriver,omitempty"` + LogOpt map[string]string `json:"logOpt,omitempty" yaml:"logOpt,omitempty"` + NodeTaints []Taint `json:"nodeTaints,omitempty" yaml:"nodeTaints,omitempty"` + StorageOpt map[string]string `json:"storageOpt,omitempty" yaml:"storageOpt,omitempty"` + UseInternalIPAddress *bool `json:"useInternalIpAddress,omitempty" yaml:"useInternalIpAddress,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_status.go new file mode 100644 index 0000000..c8b5d71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_template_status.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeTemplateStatusType = "nodeTemplateStatus" + NodeTemplateStatusFieldConditions = "conditions" +) + +type NodeTemplateStatus struct { + Conditions []NodeTemplateCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_upgrade_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_upgrade_strategy.go new file mode 100644 index 0000000..3e6106c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_node_upgrade_strategy.go @@ -0,0 +1,16 @@ +package client + +const ( + NodeUpgradeStrategyType = "nodeUpgradeStrategy" + NodeUpgradeStrategyFieldDrain = "drain" + NodeUpgradeStrategyFieldDrainInput = "nodeDrainInput" + NodeUpgradeStrategyFieldMaxUnavailableControlplane = "maxUnavailableControlplane" + NodeUpgradeStrategyFieldMaxUnavailableWorker = "maxUnavailableWorker" +) + +type NodeUpgradeStrategy struct { + Drain *bool `json:"drain,omitempty" yaml:"drain,omitempty"` + DrainInput *NodeDrainInput `json:"nodeDrainInput,omitempty" yaml:"nodeDrainInput,omitempty"` + MaxUnavailableControlplane string `json:"maxUnavailableControlplane,omitempty" yaml:"maxUnavailableControlplane,omitempty"` + MaxUnavailableWorker string `json:"maxUnavailableWorker,omitempty" yaml:"maxUnavailableWorker,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nodelocal.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nodelocal.go new file mode 100644 index 0000000..392249c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_nodelocal.go @@ -0,0 +1,16 @@ +package client + +const ( + NodelocalType = "nodelocal" + NodelocalFieldIPAddress = "ipAddress" + NodelocalFieldNodeLocalDNSPriorityClassName = "nodeLocalDnsPriorityClassName" + NodelocalFieldNodeSelector = "nodeSelector" + NodelocalFieldUpdateStrategy = "updateStrategy" +) + +type Nodelocal struct { + IPAddress string `json:"ipAddress,omitempty" yaml:"ipAddress,omitempty"` + NodeLocalDNSPriorityClassName string `json:"nodeLocalDnsPriorityClassName,omitempty" yaml:"nodeLocalDnsPriorityClassName,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + UpdateStrategy *DaemonSetUpdateStrategy `json:"updateStrategy,omitempty" yaml:"updateStrategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_field_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_field_selector.go new file mode 100644 index 0000000..4951d2a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_field_selector.go @@ -0,0 +1,12 @@ +package client + +const ( + ObjectFieldSelectorType = "objectFieldSelector" + ObjectFieldSelectorFieldAPIVersion = "apiVersion" + ObjectFieldSelectorFieldFieldPath = "fieldPath" +) + +type ObjectFieldSelector struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_meta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_meta.go new file mode 100644 index 0000000..29f7963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_object_meta.go @@ -0,0 +1,28 @@ +package client + +const ( + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldFinalizers = "finalizers" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldOwnerReferences = "ownerReferences" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldSelfLink = "selfLink" + ObjectMetaFieldUUID = "uuid" +) + +type ObjectMeta struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + Finalizers []string `json:"finalizers,omitempty" yaml:"finalizers,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_apply_input.go new file mode 100644 index 0000000..cc73a77 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_apply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + OIDCApplyInputType = "oidcApplyInput" + OIDCApplyInputFieldCode = "code" + OIDCApplyInputFieldEnabled = "enabled" + OIDCApplyInputFieldOIDCConfig = "oidcConfig" +) + +type OIDCApplyInput struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + OIDCConfig *OIDCConfig `json:"oidcConfig,omitempty" yaml:"oidcConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_config.go new file mode 100644 index 0000000..c8a5c21 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_config.go @@ -0,0 +1,62 @@ +package client + +const ( + OIDCConfigType = "oidcConfig" + OIDCConfigFieldAccessMode = "accessMode" + OIDCConfigFieldAcrValue = "acrValue" + OIDCConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + OIDCConfigFieldAnnotations = "annotations" + OIDCConfigFieldAuthEndpoint = "authEndpoint" + OIDCConfigFieldCertificate = "certificate" + OIDCConfigFieldClientID = "clientId" + OIDCConfigFieldClientSecret = "clientSecret" + OIDCConfigFieldCreated = "created" + OIDCConfigFieldCreatorID = "creatorId" + OIDCConfigFieldEnabled = "enabled" + OIDCConfigFieldGroupSearchEnabled = "groupSearchEnabled" + OIDCConfigFieldGroupsClaim = "groupsClaim" + OIDCConfigFieldIssuer = "issuer" + OIDCConfigFieldJWKSUrl = "jwksUrl" + OIDCConfigFieldLabels = "labels" + OIDCConfigFieldName = "name" + OIDCConfigFieldOwnerReferences = "ownerReferences" + OIDCConfigFieldPrivateKey = "privateKey" + OIDCConfigFieldRancherURL = "rancherUrl" + OIDCConfigFieldRemoved = "removed" + OIDCConfigFieldScopes = "scope" + OIDCConfigFieldStatus = "status" + OIDCConfigFieldTokenEndpoint = "tokenEndpoint" + OIDCConfigFieldType = "type" + OIDCConfigFieldUUID = "uuid" + OIDCConfigFieldUserInfoEndpoint = "userInfoEndpoint" +) + +type OIDCConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AcrValue string `json:"acrValue,omitempty" yaml:"acrValue,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthEndpoint string `json:"authEndpoint,omitempty" yaml:"authEndpoint,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ClientID string `json:"clientId,omitempty" yaml:"clientId,omitempty"` + ClientSecret string `json:"clientSecret,omitempty" yaml:"clientSecret,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupSearchEnabled *bool `json:"groupSearchEnabled,omitempty" yaml:"groupSearchEnabled,omitempty"` + GroupsClaim string `json:"groupsClaim,omitempty" yaml:"groupsClaim,omitempty"` + Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"` + JWKSUrl string `json:"jwksUrl,omitempty" yaml:"jwksUrl,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + RancherURL string `json:"rancherUrl,omitempty" yaml:"rancherUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Scopes string `json:"scope,omitempty" yaml:"scope,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TokenEndpoint string `json:"tokenEndpoint,omitempty" yaml:"tokenEndpoint,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserInfoEndpoint string `json:"userInfoEndpoint,omitempty" yaml:"userInfoEndpoint,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_test_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_test_output.go new file mode 100644 index 0000000..db930c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_oidc_test_output.go @@ -0,0 +1,10 @@ +package client + +const ( + OIDCTestOutputType = "oidcTestOutput" + OIDCTestOutputFieldRedirectURL = "redirectUrl" +) + +type OIDCTestOutput struct { + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_okta_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_okta_config.go new file mode 100644 index 0000000..4279acb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_okta_config.go @@ -0,0 +1,54 @@ +package client + +const ( + OKTAConfigType = "oktaConfig" + OKTAConfigFieldAccessMode = "accessMode" + OKTAConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + OKTAConfigFieldAnnotations = "annotations" + OKTAConfigFieldCreated = "created" + OKTAConfigFieldCreatorID = "creatorId" + OKTAConfigFieldDisplayNameField = "displayNameField" + OKTAConfigFieldEnabled = "enabled" + OKTAConfigFieldEntityID = "entityID" + OKTAConfigFieldGroupsField = "groupsField" + OKTAConfigFieldIDPMetadataContent = "idpMetadataContent" + OKTAConfigFieldLabels = "labels" + OKTAConfigFieldName = "name" + OKTAConfigFieldOpenLdapConfig = "openLdapConfig" + OKTAConfigFieldOwnerReferences = "ownerReferences" + OKTAConfigFieldRancherAPIHost = "rancherApiHost" + OKTAConfigFieldRemoved = "removed" + OKTAConfigFieldSpCert = "spCert" + OKTAConfigFieldSpKey = "spKey" + OKTAConfigFieldStatus = "status" + OKTAConfigFieldType = "type" + OKTAConfigFieldUIDField = "uidField" + OKTAConfigFieldUUID = "uuid" + OKTAConfigFieldUserNameField = "userNameField" +) + +type OKTAConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DisplayNameField string `json:"displayNameField,omitempty" yaml:"displayNameField,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + EntityID string `json:"entityID,omitempty" yaml:"entityID,omitempty"` + GroupsField string `json:"groupsField,omitempty" yaml:"groupsField,omitempty"` + IDPMetadataContent string `json:"idpMetadataContent,omitempty" yaml:"idpMetadataContent,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OpenLdapConfig *LdapFields `json:"openLdapConfig,omitempty" yaml:"openLdapConfig,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherAPIHost string `json:"rancherApiHost,omitempty" yaml:"rancherApiHost,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SpCert string `json:"spCert,omitempty" yaml:"spCert,omitempty"` + SpKey string `json:"spKey,omitempty" yaml:"spKey,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UIDField string `json:"uidField,omitempty" yaml:"uidField,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserNameField string `json:"userNameField,omitempty" yaml:"userNameField,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_config.go new file mode 100644 index 0000000..36af1a4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_config.go @@ -0,0 +1,86 @@ +package client + +const ( + OpenLdapConfigType = "openLdapConfig" + OpenLdapConfigFieldAccessMode = "accessMode" + OpenLdapConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + OpenLdapConfigFieldAnnotations = "annotations" + OpenLdapConfigFieldCertificate = "certificate" + OpenLdapConfigFieldConnectionTimeout = "connectionTimeout" + OpenLdapConfigFieldCreated = "created" + OpenLdapConfigFieldCreatorID = "creatorId" + OpenLdapConfigFieldEnabled = "enabled" + OpenLdapConfigFieldGroupDNAttribute = "groupDNAttribute" + OpenLdapConfigFieldGroupMemberMappingAttribute = "groupMemberMappingAttribute" + OpenLdapConfigFieldGroupMemberUserAttribute = "groupMemberUserAttribute" + OpenLdapConfigFieldGroupNameAttribute = "groupNameAttribute" + OpenLdapConfigFieldGroupObjectClass = "groupObjectClass" + OpenLdapConfigFieldGroupSearchAttribute = "groupSearchAttribute" + OpenLdapConfigFieldGroupSearchBase = "groupSearchBase" + OpenLdapConfigFieldGroupSearchFilter = "groupSearchFilter" + OpenLdapConfigFieldLabels = "labels" + OpenLdapConfigFieldName = "name" + OpenLdapConfigFieldNestedGroupMembershipEnabled = "nestedGroupMembershipEnabled" + OpenLdapConfigFieldOwnerReferences = "ownerReferences" + OpenLdapConfigFieldPort = "port" + OpenLdapConfigFieldRemoved = "removed" + OpenLdapConfigFieldServers = "servers" + OpenLdapConfigFieldServiceAccountDistinguishedName = "serviceAccountDistinguishedName" + OpenLdapConfigFieldServiceAccountPassword = "serviceAccountPassword" + OpenLdapConfigFieldStartTLS = "starttls" + OpenLdapConfigFieldStatus = "status" + OpenLdapConfigFieldTLS = "tls" + OpenLdapConfigFieldType = "type" + OpenLdapConfigFieldUUID = "uuid" + OpenLdapConfigFieldUserDisabledBitMask = "userDisabledBitMask" + OpenLdapConfigFieldUserEnabledAttribute = "userEnabledAttribute" + OpenLdapConfigFieldUserLoginAttribute = "userLoginAttribute" + OpenLdapConfigFieldUserMemberAttribute = "userMemberAttribute" + OpenLdapConfigFieldUserNameAttribute = "userNameAttribute" + OpenLdapConfigFieldUserObjectClass = "userObjectClass" + OpenLdapConfigFieldUserSearchAttribute = "userSearchAttribute" + OpenLdapConfigFieldUserSearchBase = "userSearchBase" + OpenLdapConfigFieldUserSearchFilter = "userSearchFilter" +) + +type OpenLdapConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Certificate string `json:"certificate,omitempty" yaml:"certificate,omitempty"` + ConnectionTimeout int64 `json:"connectionTimeout,omitempty" yaml:"connectionTimeout,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + GroupDNAttribute string `json:"groupDNAttribute,omitempty" yaml:"groupDNAttribute,omitempty"` + GroupMemberMappingAttribute string `json:"groupMemberMappingAttribute,omitempty" yaml:"groupMemberMappingAttribute,omitempty"` + GroupMemberUserAttribute string `json:"groupMemberUserAttribute,omitempty" yaml:"groupMemberUserAttribute,omitempty"` + GroupNameAttribute string `json:"groupNameAttribute,omitempty" yaml:"groupNameAttribute,omitempty"` + GroupObjectClass string `json:"groupObjectClass,omitempty" yaml:"groupObjectClass,omitempty"` + GroupSearchAttribute string `json:"groupSearchAttribute,omitempty" yaml:"groupSearchAttribute,omitempty"` + GroupSearchBase string `json:"groupSearchBase,omitempty" yaml:"groupSearchBase,omitempty"` + GroupSearchFilter string `json:"groupSearchFilter,omitempty" yaml:"groupSearchFilter,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NestedGroupMembershipEnabled bool `json:"nestedGroupMembershipEnabled,omitempty" yaml:"nestedGroupMembershipEnabled,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Servers []string `json:"servers,omitempty" yaml:"servers,omitempty"` + ServiceAccountDistinguishedName string `json:"serviceAccountDistinguishedName,omitempty" yaml:"serviceAccountDistinguishedName,omitempty"` + ServiceAccountPassword string `json:"serviceAccountPassword,omitempty" yaml:"serviceAccountPassword,omitempty"` + StartTLS bool `json:"starttls,omitempty" yaml:"starttls,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS bool `json:"tls,omitempty" yaml:"tls,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserDisabledBitMask int64 `json:"userDisabledBitMask,omitempty" yaml:"userDisabledBitMask,omitempty"` + UserEnabledAttribute string `json:"userEnabledAttribute,omitempty" yaml:"userEnabledAttribute,omitempty"` + UserLoginAttribute string `json:"userLoginAttribute,omitempty" yaml:"userLoginAttribute,omitempty"` + UserMemberAttribute string `json:"userMemberAttribute,omitempty" yaml:"userMemberAttribute,omitempty"` + UserNameAttribute string `json:"userNameAttribute,omitempty" yaml:"userNameAttribute,omitempty"` + UserObjectClass string `json:"userObjectClass,omitempty" yaml:"userObjectClass,omitempty"` + UserSearchAttribute string `json:"userSearchAttribute,omitempty" yaml:"userSearchAttribute,omitempty"` + UserSearchBase string `json:"userSearchBase,omitempty" yaml:"userSearchBase,omitempty"` + UserSearchFilter string `json:"userSearchFilter,omitempty" yaml:"userSearchFilter,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_test_and_apply_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_test_and_apply_input.go new file mode 100644 index 0000000..29c48f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_open_ldap_test_and_apply_input.go @@ -0,0 +1,14 @@ +package client + +const ( + OpenLdapTestAndApplyInputType = "openLdapTestAndApplyInput" + OpenLdapTestAndApplyInputFieldLdapConfig = "ldapConfig" + OpenLdapTestAndApplyInputFieldPassword = "password" + OpenLdapTestAndApplyInputFieldUsername = "username" +) + +type OpenLdapTestAndApplyInput struct { + LdapConfig *LdapConfig `json:"ldapConfig,omitempty" yaml:"ldapConfig,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_openstack_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_openstack_cloud_provider.go new file mode 100644 index 0000000..6d883ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_openstack_cloud_provider.go @@ -0,0 +1,18 @@ +package client + +const ( + OpenstackCloudProviderType = "openstackCloudProvider" + OpenstackCloudProviderFieldBlockStorage = "blockStorage" + OpenstackCloudProviderFieldGlobal = "global" + OpenstackCloudProviderFieldLoadBalancer = "loadBalancer" + OpenstackCloudProviderFieldMetadata = "metadata" + OpenstackCloudProviderFieldRoute = "route" +) + +type OpenstackCloudProvider struct { + BlockStorage *BlockStorageOpenstackOpts `json:"blockStorage,omitempty" yaml:"blockStorage,omitempty"` + Global *GlobalOpenstackOpts `json:"global,omitempty" yaml:"global,omitempty"` + LoadBalancer *LoadBalancerOpenstackOpts `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` + Metadata *MetadataOpenstackOpts `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Route *RouteOpenstackOpts `json:"route,omitempty" yaml:"route,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_os_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_os_info.go new file mode 100644 index 0000000..c2c503c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_os_info.go @@ -0,0 +1,14 @@ +package client + +const ( + OSInfoType = "osInfo" + OSInfoFieldDockerVersion = "dockerVersion" + OSInfoFieldKernelVersion = "kernelVersion" + OSInfoFieldOperatingSystem = "operatingSystem" +) + +type OSInfo struct { + DockerVersion string `json:"dockerVersion,omitempty" yaml:"dockerVersion,omitempty"` + KernelVersion string `json:"kernelVersion,omitempty" yaml:"kernelVersion,omitempty"` + OperatingSystem string `json:"operatingSystem,omitempty" yaml:"operatingSystem,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_owner_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_owner_reference.go new file mode 100644 index 0000000..5f4436b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_owner_reference.go @@ -0,0 +1,20 @@ +package client + +const ( + OwnerReferenceType = "ownerReference" + OwnerReferenceFieldAPIVersion = "apiVersion" + OwnerReferenceFieldBlockOwnerDeletion = "blockOwnerDeletion" + OwnerReferenceFieldController = "controller" + OwnerReferenceFieldKind = "kind" + OwnerReferenceFieldName = "name" + OwnerReferenceFieldUID = "uid" +) + +type OwnerReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" yaml:"blockOwnerDeletion,omitempty"` + Controller *bool `json:"controller,omitempty" yaml:"controller,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_spec.go new file mode 100644 index 0000000..b3f2c16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_spec.go @@ -0,0 +1,26 @@ +package client + +const ( + PersistentVolumeClaimSpecType = "persistentVolumeClaimSpec" + PersistentVolumeClaimSpecFieldAccessModes = "accessModes" + PersistentVolumeClaimSpecFieldDataSource = "dataSource" + PersistentVolumeClaimSpecFieldDataSourceRef = "dataSourceRef" + PersistentVolumeClaimSpecFieldResources = "resources" + PersistentVolumeClaimSpecFieldSelector = "selector" + PersistentVolumeClaimSpecFieldStorageClassName = "storageClassName" + PersistentVolumeClaimSpecFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeClaimSpecFieldVolumeMode = "volumeMode" + PersistentVolumeClaimSpecFieldVolumeName = "volumeName" +) + +type PersistentVolumeClaimSpec struct { + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" yaml:"dataSource,omitempty"` + DataSourceRef *TypedObjectReference `json:"dataSourceRef,omitempty" yaml:"dataSourceRef,omitempty"` + Resources *VolumeResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + StorageClassName string `json:"storageClassName,omitempty" yaml:"storageClassName,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_template.go new file mode 100644 index 0000000..1eed7b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_template.go @@ -0,0 +1,12 @@ +package client + +const ( + PersistentVolumeClaimTemplateType = "persistentVolumeClaimTemplate" + PersistentVolumeClaimTemplateFieldObjectMeta = "metadata" + PersistentVolumeClaimTemplateFieldSpec = "spec" +) + +type PersistentVolumeClaimTemplate struct { + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Spec *PersistentVolumeClaimSpec `json:"spec,omitempty" yaml:"spec,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_volume_source.go new file mode 100644 index 0000000..1b4ae4b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_persistent_volume_claim_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PersistentVolumeClaimVolumeSourceType = "persistentVolumeClaimVolumeSource" + PersistentVolumeClaimVolumeSourceFieldClaimName = "claimName" + PersistentVolumeClaimVolumeSourceFieldReadOnly = "readOnly" +) + +type PersistentVolumeClaimVolumeSource struct { + ClaimName string `json:"claimName,omitempty" yaml:"claimName,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_photon_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_photon_persistent_disk_volume_source.go new file mode 100644 index 0000000..d6e8ffd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_photon_persistent_disk_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PhotonPersistentDiskVolumeSourceType = "photonPersistentDiskVolumeSource" + PhotonPersistentDiskVolumeSourceFieldFSType = "fsType" + PhotonPersistentDiskVolumeSourceFieldPdID = "pdID" +) + +type PhotonPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PdID string `json:"pdID,omitempty" yaml:"pdID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ping_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ping_config.go new file mode 100644 index 0000000..3905905 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_ping_config.go @@ -0,0 +1,52 @@ +package client + +const ( + PingConfigType = "pingConfig" + PingConfigFieldAccessMode = "accessMode" + PingConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + PingConfigFieldAnnotations = "annotations" + PingConfigFieldCreated = "created" + PingConfigFieldCreatorID = "creatorId" + PingConfigFieldDisplayNameField = "displayNameField" + PingConfigFieldEnabled = "enabled" + PingConfigFieldEntityID = "entityID" + PingConfigFieldGroupsField = "groupsField" + PingConfigFieldIDPMetadataContent = "idpMetadataContent" + PingConfigFieldLabels = "labels" + PingConfigFieldName = "name" + PingConfigFieldOwnerReferences = "ownerReferences" + PingConfigFieldRancherAPIHost = "rancherApiHost" + PingConfigFieldRemoved = "removed" + PingConfigFieldSpCert = "spCert" + PingConfigFieldSpKey = "spKey" + PingConfigFieldStatus = "status" + PingConfigFieldType = "type" + PingConfigFieldUIDField = "uidField" + PingConfigFieldUUID = "uuid" + PingConfigFieldUserNameField = "userNameField" +) + +type PingConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DisplayNameField string `json:"displayNameField,omitempty" yaml:"displayNameField,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + EntityID string `json:"entityID,omitempty" yaml:"entityID,omitempty"` + GroupsField string `json:"groupsField,omitempty" yaml:"groupsField,omitempty"` + IDPMetadataContent string `json:"idpMetadataContent,omitempty" yaml:"idpMetadataContent,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherAPIHost string `json:"rancherApiHost,omitempty" yaml:"rancherApiHost,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SpCert string `json:"spCert,omitempty" yaml:"spCert,omitempty"` + SpKey string `json:"spKey,omitempty" yaml:"spKey,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UIDField string `json:"uidField,omitempty" yaml:"uidField,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserNameField string `json:"userNameField,omitempty" yaml:"userNameField,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity.go new file mode 100644 index 0000000..ebe2958 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + PodAffinityType = "podAffinity" + PodAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + PodAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type PodAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []WeightedPodAffinityTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution []PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity_term.go new file mode 100644 index 0000000..aa1478e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_affinity_term.go @@ -0,0 +1,20 @@ +package client + +const ( + PodAffinityTermType = "podAffinityTerm" + PodAffinityTermFieldLabelSelector = "labelSelector" + PodAffinityTermFieldMatchLabelKeys = "matchLabelKeys" + PodAffinityTermFieldMismatchLabelKeys = "mismatchLabelKeys" + PodAffinityTermFieldNamespaceSelector = "namespaceSelector" + PodAffinityTermFieldNamespaces = "namespaces" + PodAffinityTermFieldTopologyKey = "topologyKey" +) + +type PodAffinityTerm struct { + LabelSelector *LabelSelector `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` + MatchLabelKeys []string `json:"matchLabelKeys,omitempty" yaml:"matchLabelKeys,omitempty"` + MismatchLabelKeys []string `json:"mismatchLabelKeys,omitempty" yaml:"mismatchLabelKeys,omitempty"` + NamespaceSelector *LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"` + Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"` + TopologyKey string `json:"topologyKey,omitempty" yaml:"topologyKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_anti_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_anti_affinity.go new file mode 100644 index 0000000..47fdd69 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_anti_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + PodAntiAffinityType = "podAntiAffinity" + PodAntiAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + PodAntiAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type PodAntiAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []WeightedPodAffinityTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution []PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template.go new file mode 100644 index 0000000..5fc4e6c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PodSecurityAdmissionConfigurationTemplateType = "podSecurityAdmissionConfigurationTemplate" + PodSecurityAdmissionConfigurationTemplateFieldAnnotations = "annotations" + PodSecurityAdmissionConfigurationTemplateFieldConfiguration = "configuration" + PodSecurityAdmissionConfigurationTemplateFieldCreated = "created" + PodSecurityAdmissionConfigurationTemplateFieldCreatorID = "creatorId" + PodSecurityAdmissionConfigurationTemplateFieldDescription = "description" + PodSecurityAdmissionConfigurationTemplateFieldLabels = "labels" + PodSecurityAdmissionConfigurationTemplateFieldName = "name" + PodSecurityAdmissionConfigurationTemplateFieldOwnerReferences = "ownerReferences" + PodSecurityAdmissionConfigurationTemplateFieldRemoved = "removed" + PodSecurityAdmissionConfigurationTemplateFieldUUID = "uuid" +) + +type PodSecurityAdmissionConfigurationTemplate struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Configuration *PodSecurityAdmissionConfigurationTemplateSpec `json:"configuration,omitempty" yaml:"configuration,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type PodSecurityAdmissionConfigurationTemplateCollection struct { + types.Collection + Data []PodSecurityAdmissionConfigurationTemplate `json:"data,omitempty"` + client *PodSecurityAdmissionConfigurationTemplateClient +} + +type PodSecurityAdmissionConfigurationTemplateClient struct { + apiClient *Client +} + +type PodSecurityAdmissionConfigurationTemplateOperations interface { + List(opts *types.ListOpts) (*PodSecurityAdmissionConfigurationTemplateCollection, error) + ListAll(opts *types.ListOpts) (*PodSecurityAdmissionConfigurationTemplateCollection, error) + Create(opts *PodSecurityAdmissionConfigurationTemplate) (*PodSecurityAdmissionConfigurationTemplate, error) + Update(existing *PodSecurityAdmissionConfigurationTemplate, updates interface{}) (*PodSecurityAdmissionConfigurationTemplate, error) + Replace(existing *PodSecurityAdmissionConfigurationTemplate) (*PodSecurityAdmissionConfigurationTemplate, error) + ByID(id string) (*PodSecurityAdmissionConfigurationTemplate, error) + Delete(container *PodSecurityAdmissionConfigurationTemplate) error +} + +func newPodSecurityAdmissionConfigurationTemplateClient(apiClient *Client) *PodSecurityAdmissionConfigurationTemplateClient { + return &PodSecurityAdmissionConfigurationTemplateClient{ + apiClient: apiClient, + } +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) Create(container *PodSecurityAdmissionConfigurationTemplate) (*PodSecurityAdmissionConfigurationTemplate, error) { + resp := &PodSecurityAdmissionConfigurationTemplate{} + err := c.apiClient.Ops.DoCreate(PodSecurityAdmissionConfigurationTemplateType, container, resp) + return resp, err +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) Update(existing *PodSecurityAdmissionConfigurationTemplate, updates interface{}) (*PodSecurityAdmissionConfigurationTemplate, error) { + resp := &PodSecurityAdmissionConfigurationTemplate{} + err := c.apiClient.Ops.DoUpdate(PodSecurityAdmissionConfigurationTemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) Replace(obj *PodSecurityAdmissionConfigurationTemplate) (*PodSecurityAdmissionConfigurationTemplate, error) { + resp := &PodSecurityAdmissionConfigurationTemplate{} + err := c.apiClient.Ops.DoReplace(PodSecurityAdmissionConfigurationTemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) List(opts *types.ListOpts) (*PodSecurityAdmissionConfigurationTemplateCollection, error) { + resp := &PodSecurityAdmissionConfigurationTemplateCollection{} + err := c.apiClient.Ops.DoList(PodSecurityAdmissionConfigurationTemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) ListAll(opts *types.ListOpts) (*PodSecurityAdmissionConfigurationTemplateCollection, error) { + resp := &PodSecurityAdmissionConfigurationTemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PodSecurityAdmissionConfigurationTemplateCollection) Next() (*PodSecurityAdmissionConfigurationTemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PodSecurityAdmissionConfigurationTemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) ByID(id string) (*PodSecurityAdmissionConfigurationTemplate, error) { + resp := &PodSecurityAdmissionConfigurationTemplate{} + err := c.apiClient.Ops.DoByID(PodSecurityAdmissionConfigurationTemplateType, id, resp) + return resp, err +} + +func (c *PodSecurityAdmissionConfigurationTemplateClient) Delete(container *PodSecurityAdmissionConfigurationTemplate) error { + return c.apiClient.Ops.DoResourceDelete(PodSecurityAdmissionConfigurationTemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_defaults.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_defaults.go new file mode 100644 index 0000000..f2fc1d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_defaults.go @@ -0,0 +1,20 @@ +package client + +const ( + PodSecurityAdmissionConfigurationTemplateDefaultsType = "podSecurityAdmissionConfigurationTemplateDefaults" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldAudit = "audit" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldAuditVersion = "audit-version" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldEnforce = "enforce" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldEnforceVersion = "enforce-version" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldWarn = "warn" + PodSecurityAdmissionConfigurationTemplateDefaultsFieldWarnVersion = "warn-version" +) + +type PodSecurityAdmissionConfigurationTemplateDefaults struct { + Audit string `json:"audit,omitempty" yaml:"audit,omitempty"` + AuditVersion string `json:"audit-version,omitempty" yaml:"audit-version,omitempty"` + Enforce string `json:"enforce,omitempty" yaml:"enforce,omitempty"` + EnforceVersion string `json:"enforce-version,omitempty" yaml:"enforce-version,omitempty"` + Warn string `json:"warn,omitempty" yaml:"warn,omitempty"` + WarnVersion string `json:"warn-version,omitempty" yaml:"warn-version,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_exemptions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_exemptions.go new file mode 100644 index 0000000..392c5c4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_exemptions.go @@ -0,0 +1,14 @@ +package client + +const ( + PodSecurityAdmissionConfigurationTemplateExemptionsType = "podSecurityAdmissionConfigurationTemplateExemptions" + PodSecurityAdmissionConfigurationTemplateExemptionsFieldNamespaces = "namespaces" + PodSecurityAdmissionConfigurationTemplateExemptionsFieldRuntimeClasses = "runtimeClasses" + PodSecurityAdmissionConfigurationTemplateExemptionsFieldUsernames = "usernames" +) + +type PodSecurityAdmissionConfigurationTemplateExemptions struct { + Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"` + RuntimeClasses []string `json:"runtimeClasses,omitempty" yaml:"runtimeClasses,omitempty"` + Usernames []string `json:"usernames,omitempty" yaml:"usernames,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_spec.go new file mode 100644 index 0000000..afe2ef0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_pod_security_admission_configuration_template_spec.go @@ -0,0 +1,12 @@ +package client + +const ( + PodSecurityAdmissionConfigurationTemplateSpecType = "podSecurityAdmissionConfigurationTemplateSpec" + PodSecurityAdmissionConfigurationTemplateSpecFieldDefaults = "defaults" + PodSecurityAdmissionConfigurationTemplateSpecFieldExemptions = "exemptions" +) + +type PodSecurityAdmissionConfigurationTemplateSpec struct { + Defaults *PodSecurityAdmissionConfigurationTemplateDefaults `json:"defaults,omitempty" yaml:"defaults,omitempty"` + Exemptions *PodSecurityAdmissionConfigurationTemplateExemptions `json:"exemptions,omitempty" yaml:"exemptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_policy_rule.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_policy_rule.go new file mode 100644 index 0000000..b7a51ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_policy_rule.go @@ -0,0 +1,18 @@ +package client + +const ( + PolicyRuleType = "policyRule" + PolicyRuleFieldAPIGroups = "apiGroups" + PolicyRuleFieldNonResourceURLs = "nonResourceURLs" + PolicyRuleFieldResourceNames = "resourceNames" + PolicyRuleFieldResources = "resources" + PolicyRuleFieldVerbs = "verbs" +) + +type PolicyRule struct { + APIGroups []string `json:"apiGroups,omitempty" yaml:"apiGroups,omitempty"` + NonResourceURLs []string `json:"nonResourceURLs,omitempty" yaml:"nonResourceURLs,omitempty"` + ResourceNames []string `json:"resourceNames,omitempty" yaml:"resourceNames,omitempty"` + Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"` + Verbs []string `json:"verbs,omitempty" yaml:"verbs,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_port_check.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_port_check.go new file mode 100644 index 0000000..2e9c37e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_port_check.go @@ -0,0 +1,14 @@ +package client + +const ( + PortCheckType = "portCheck" + PortCheckFieldAddress = "address" + PortCheckFieldPort = "port" + PortCheckFieldProtocol = "protocol" +) + +type PortCheck struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_portworx_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_portworx_volume_source.go new file mode 100644 index 0000000..cbe98c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_portworx_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + PortworxVolumeSourceType = "portworxVolumeSource" + PortworxVolumeSourceFieldFSType = "fsType" + PortworxVolumeSourceFieldReadOnly = "readOnly" + PortworxVolumeSourceFieldVolumeID = "volumeID" +) + +type PortworxVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preference.go new file mode 100644 index 0000000..5028069 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preference.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PreferenceType = "preference" + PreferenceFieldAnnotations = "annotations" + PreferenceFieldCreated = "created" + PreferenceFieldCreatorID = "creatorId" + PreferenceFieldLabels = "labels" + PreferenceFieldName = "name" + PreferenceFieldNamespaceId = "namespaceId" + PreferenceFieldOwnerReferences = "ownerReferences" + PreferenceFieldRemoved = "removed" + PreferenceFieldUUID = "uuid" + PreferenceFieldValue = "value" +) + +type Preference struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} + +type PreferenceCollection struct { + types.Collection + Data []Preference `json:"data,omitempty"` + client *PreferenceClient +} + +type PreferenceClient struct { + apiClient *Client +} + +type PreferenceOperations interface { + List(opts *types.ListOpts) (*PreferenceCollection, error) + ListAll(opts *types.ListOpts) (*PreferenceCollection, error) + Create(opts *Preference) (*Preference, error) + Update(existing *Preference, updates interface{}) (*Preference, error) + Replace(existing *Preference) (*Preference, error) + ByID(id string) (*Preference, error) + Delete(container *Preference) error +} + +func newPreferenceClient(apiClient *Client) *PreferenceClient { + return &PreferenceClient{ + apiClient: apiClient, + } +} + +func (c *PreferenceClient) Create(container *Preference) (*Preference, error) { + resp := &Preference{} + err := c.apiClient.Ops.DoCreate(PreferenceType, container, resp) + return resp, err +} + +func (c *PreferenceClient) Update(existing *Preference, updates interface{}) (*Preference, error) { + resp := &Preference{} + err := c.apiClient.Ops.DoUpdate(PreferenceType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PreferenceClient) Replace(obj *Preference) (*Preference, error) { + resp := &Preference{} + err := c.apiClient.Ops.DoReplace(PreferenceType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PreferenceClient) List(opts *types.ListOpts) (*PreferenceCollection, error) { + resp := &PreferenceCollection{} + err := c.apiClient.Ops.DoList(PreferenceType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PreferenceClient) ListAll(opts *types.ListOpts) (*PreferenceCollection, error) { + resp := &PreferenceCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PreferenceCollection) Next() (*PreferenceCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PreferenceCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PreferenceClient) ByID(id string) (*Preference, error) { + resp := &Preference{} + err := c.apiClient.Ops.DoByID(PreferenceType, id, resp) + return resp, err +} + +func (c *PreferenceClient) Delete(container *Preference) error { + return c.apiClient.Ops.DoResourceDelete(PreferenceType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preferred_scheduling_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preferred_scheduling_term.go new file mode 100644 index 0000000..b5be217 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_preferred_scheduling_term.go @@ -0,0 +1,12 @@ +package client + +const ( + PreferredSchedulingTermType = "preferredSchedulingTerm" + PreferredSchedulingTermFieldPreference = "preference" + PreferredSchedulingTermFieldWeight = "weight" +) + +type PreferredSchedulingTerm struct { + Preference *NodeSelectorTerm `json:"preference,omitempty" yaml:"preference,omitempty"` + Weight int64 `json:"weight,omitempty" yaml:"weight,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_principal.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_principal.go new file mode 100644 index 0000000..1f51a8b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_principal.go @@ -0,0 +1,142 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PrincipalType = "principal" + PrincipalFieldAnnotations = "annotations" + PrincipalFieldCreated = "created" + PrincipalFieldCreatorID = "creatorId" + PrincipalFieldExtraInfo = "extraInfo" + PrincipalFieldLabels = "labels" + PrincipalFieldLoginName = "loginName" + PrincipalFieldMe = "me" + PrincipalFieldMemberOf = "memberOf" + PrincipalFieldName = "name" + PrincipalFieldOwnerReferences = "ownerReferences" + PrincipalFieldPrincipalType = "principalType" + PrincipalFieldProfilePicture = "profilePicture" + PrincipalFieldProfileURL = "profileURL" + PrincipalFieldProvider = "provider" + PrincipalFieldRemoved = "removed" + PrincipalFieldUUID = "uuid" +) + +type Principal struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + ExtraInfo map[string]string `json:"extraInfo,omitempty" yaml:"extraInfo,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LoginName string `json:"loginName,omitempty" yaml:"loginName,omitempty"` + Me bool `json:"me,omitempty" yaml:"me,omitempty"` + MemberOf bool `json:"memberOf,omitempty" yaml:"memberOf,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrincipalType string `json:"principalType,omitempty" yaml:"principalType,omitempty"` + ProfilePicture string `json:"profilePicture,omitempty" yaml:"profilePicture,omitempty"` + ProfileURL string `json:"profileURL,omitempty" yaml:"profileURL,omitempty"` + Provider string `json:"provider,omitempty" yaml:"provider,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type PrincipalCollection struct { + types.Collection + Data []Principal `json:"data,omitempty"` + client *PrincipalClient +} + +type PrincipalClient struct { + apiClient *Client +} + +type PrincipalOperations interface { + List(opts *types.ListOpts) (*PrincipalCollection, error) + ListAll(opts *types.ListOpts) (*PrincipalCollection, error) + Create(opts *Principal) (*Principal, error) + Update(existing *Principal, updates interface{}) (*Principal, error) + Replace(existing *Principal) (*Principal, error) + ByID(id string) (*Principal, error) + Delete(container *Principal) error + + CollectionActionSearch(resource *PrincipalCollection, input *SearchPrincipalsInput) (*PrincipalCollection, error) +} + +func newPrincipalClient(apiClient *Client) *PrincipalClient { + return &PrincipalClient{ + apiClient: apiClient, + } +} + +func (c *PrincipalClient) Create(container *Principal) (*Principal, error) { + resp := &Principal{} + err := c.apiClient.Ops.DoCreate(PrincipalType, container, resp) + return resp, err +} + +func (c *PrincipalClient) Update(existing *Principal, updates interface{}) (*Principal, error) { + resp := &Principal{} + err := c.apiClient.Ops.DoUpdate(PrincipalType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PrincipalClient) Replace(obj *Principal) (*Principal, error) { + resp := &Principal{} + err := c.apiClient.Ops.DoReplace(PrincipalType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PrincipalClient) List(opts *types.ListOpts) (*PrincipalCollection, error) { + resp := &PrincipalCollection{} + err := c.apiClient.Ops.DoList(PrincipalType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PrincipalClient) ListAll(opts *types.ListOpts) (*PrincipalCollection, error) { + resp := &PrincipalCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PrincipalCollection) Next() (*PrincipalCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PrincipalCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PrincipalClient) ByID(id string) (*Principal, error) { + resp := &Principal{} + err := c.apiClient.Ops.DoByID(PrincipalType, id, resp) + return resp, err +} + +func (c *PrincipalClient) Delete(container *Principal) error { + return c.apiClient.Ops.DoResourceDelete(PrincipalType, &container.Resource) +} + +func (c *PrincipalClient) CollectionActionSearch(resource *PrincipalCollection, input *SearchPrincipalsInput) (*PrincipalCollection, error) { + resp := &PrincipalCollection{} + err := c.apiClient.Ops.DoCollectionAction(PrincipalType, "search", &resource.Collection, input, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_private_registry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_private_registry.go new file mode 100644 index 0000000..1f6f199 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_private_registry.go @@ -0,0 +1,18 @@ +package client + +const ( + PrivateRegistryType = "privateRegistry" + PrivateRegistryFieldECRCredentialPlugin = "ecrCredentialPlugin" + PrivateRegistryFieldIsDefault = "isDefault" + PrivateRegistryFieldPassword = "password" + PrivateRegistryFieldURL = "url" + PrivateRegistryFieldUser = "user" +) + +type PrivateRegistry struct { + ECRCredentialPlugin *ECRCredentialPlugin `json:"ecrCredentialPlugin,omitempty" yaml:"ecrCredentialPlugin,omitempty"` + IsDefault bool `json:"isDefault,omitempty" yaml:"isDefault,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_process.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_process.go new file mode 100644 index 0000000..425fd65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_process.go @@ -0,0 +1,40 @@ +package client + +const ( + ProcessType = "process" + ProcessFieldArgs = "args" + ProcessFieldBinds = "binds" + ProcessFieldCommand = "command" + ProcessFieldEnv = "env" + ProcessFieldHealthCheck = "healthCheck" + ProcessFieldImage = "image" + ProcessFieldImageRegistryAuthConfig = "imageRegistryAuthConfig" + ProcessFieldLabels = "labels" + ProcessFieldName = "name" + ProcessFieldNetworkMode = "networkMode" + ProcessFieldPidMode = "pidMode" + ProcessFieldPrivileged = "privileged" + ProcessFieldPublish = "publish" + ProcessFieldRestartPolicy = "restartPolicy" + ProcessFieldUser = "user" + ProcessFieldVolumesFrom = "volumesFrom" +) + +type Process struct { + Args []string `json:"args,omitempty" yaml:"args,omitempty"` + Binds []string `json:"binds,omitempty" yaml:"binds,omitempty"` + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + Env []string `json:"env,omitempty" yaml:"env,omitempty"` + HealthCheck *HealthCheck `json:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImageRegistryAuthConfig string `json:"imageRegistryAuthConfig,omitempty" yaml:"imageRegistryAuthConfig,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NetworkMode string `json:"networkMode,omitempty" yaml:"networkMode,omitempty"` + PidMode string `json:"pidMode,omitempty" yaml:"pidMode,omitempty"` + Privileged bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` + Publish []string `json:"publish,omitempty" yaml:"publish,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + VolumesFrom []string `json:"volumesFrom,omitempty" yaml:"volumesFrom,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project.go new file mode 100644 index 0000000..63ae424 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project.go @@ -0,0 +1,145 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ProjectType = "project" + ProjectFieldAnnotations = "annotations" + ProjectFieldClusterID = "clusterId" + ProjectFieldConditions = "conditions" + ProjectFieldContainerDefaultResourceLimit = "containerDefaultResourceLimit" + ProjectFieldCreated = "created" + ProjectFieldCreatorID = "creatorId" + ProjectFieldDescription = "description" + ProjectFieldLabels = "labels" + ProjectFieldName = "name" + ProjectFieldNamespaceDefaultResourceQuota = "namespaceDefaultResourceQuota" + ProjectFieldNamespaceId = "namespaceId" + ProjectFieldOwnerReferences = "ownerReferences" + ProjectFieldRemoved = "removed" + ProjectFieldResourceQuota = "resourceQuota" + ProjectFieldState = "state" + ProjectFieldTransitioning = "transitioning" + ProjectFieldTransitioningMessage = "transitioningMessage" + ProjectFieldUUID = "uuid" +) + +type Project struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Conditions []ProjectCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + ContainerDefaultResourceLimit *ContainerResourceLimit `json:"containerDefaultResourceLimit,omitempty" yaml:"containerDefaultResourceLimit,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceDefaultResourceQuota *NamespaceResourceQuota `json:"namespaceDefaultResourceQuota,omitempty" yaml:"namespaceDefaultResourceQuota,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceQuota *ProjectResourceQuota `json:"resourceQuota,omitempty" yaml:"resourceQuota,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ProjectCollection struct { + types.Collection + Data []Project `json:"data,omitempty"` + client *ProjectClient +} + +type ProjectClient struct { + apiClient *Client +} + +type ProjectOperations interface { + List(opts *types.ListOpts) (*ProjectCollection, error) + ListAll(opts *types.ListOpts) (*ProjectCollection, error) + Create(opts *Project) (*Project, error) + Update(existing *Project, updates interface{}) (*Project, error) + Replace(existing *Project) (*Project, error) + ByID(id string) (*Project, error) + Delete(container *Project) error + + ActionExportYaml(resource *Project) error +} + +func newProjectClient(apiClient *Client) *ProjectClient { + return &ProjectClient{ + apiClient: apiClient, + } +} + +func (c *ProjectClient) Create(container *Project) (*Project, error) { + resp := &Project{} + err := c.apiClient.Ops.DoCreate(ProjectType, container, resp) + return resp, err +} + +func (c *ProjectClient) Update(existing *Project, updates interface{}) (*Project, error) { + resp := &Project{} + err := c.apiClient.Ops.DoUpdate(ProjectType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ProjectClient) Replace(obj *Project) (*Project, error) { + resp := &Project{} + err := c.apiClient.Ops.DoReplace(ProjectType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ProjectClient) List(opts *types.ListOpts) (*ProjectCollection, error) { + resp := &ProjectCollection{} + err := c.apiClient.Ops.DoList(ProjectType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ProjectClient) ListAll(opts *types.ListOpts) (*ProjectCollection, error) { + resp := &ProjectCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ProjectCollection) Next() (*ProjectCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ProjectCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ProjectClient) ByID(id string) (*Project, error) { + resp := &Project{} + err := c.apiClient.Ops.DoByID(ProjectType, id, resp) + return resp, err +} + +func (c *ProjectClient) Delete(container *Project) error { + return c.apiClient.Ops.DoResourceDelete(ProjectType, &container.Resource) +} + +func (c *ProjectClient) ActionExportYaml(resource *Project) error { + err := c.apiClient.Ops.DoAction(ProjectType, "exportYaml", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_catalog.go new file mode 100644 index 0000000..2185abe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_catalog.go @@ -0,0 +1,168 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ProjectCatalogType = "projectCatalog" + ProjectCatalogFieldAnnotations = "annotations" + ProjectCatalogFieldBranch = "branch" + ProjectCatalogFieldCatalogSecrets = "catalogSecrets" + ProjectCatalogFieldCommit = "commit" + ProjectCatalogFieldConditions = "conditions" + ProjectCatalogFieldCreated = "created" + ProjectCatalogFieldCreatorID = "creatorId" + ProjectCatalogFieldCredentialSecret = "credentialSecret" + ProjectCatalogFieldDescription = "description" + ProjectCatalogFieldHelmVersion = "helmVersion" + ProjectCatalogFieldKind = "kind" + ProjectCatalogFieldLabels = "labels" + ProjectCatalogFieldLastRefreshTimestamp = "lastRefreshTimestamp" + ProjectCatalogFieldName = "name" + ProjectCatalogFieldNamespaceId = "namespaceId" + ProjectCatalogFieldOwnerReferences = "ownerReferences" + ProjectCatalogFieldPassword = "password" + ProjectCatalogFieldProjectID = "projectId" + ProjectCatalogFieldRemoved = "removed" + ProjectCatalogFieldState = "state" + ProjectCatalogFieldTransitioning = "transitioning" + ProjectCatalogFieldTransitioningMessage = "transitioningMessage" + ProjectCatalogFieldURL = "url" + ProjectCatalogFieldUUID = "uuid" + ProjectCatalogFieldUsername = "username" +) + +type ProjectCatalog struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Branch string `json:"branch,omitempty" yaml:"branch,omitempty"` + CatalogSecrets *CatalogSecrets `json:"catalogSecrets,omitempty" yaml:"catalogSecrets,omitempty"` + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` + Conditions []CatalogCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CredentialSecret string `json:"credentialSecret,omitempty" yaml:"credentialSecret,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastRefreshTimestamp string `json:"lastRefreshTimestamp,omitempty" yaml:"lastRefreshTimestamp,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type ProjectCatalogCollection struct { + types.Collection + Data []ProjectCatalog `json:"data,omitempty"` + client *ProjectCatalogClient +} + +type ProjectCatalogClient struct { + apiClient *Client +} + +type ProjectCatalogOperations interface { + List(opts *types.ListOpts) (*ProjectCatalogCollection, error) + ListAll(opts *types.ListOpts) (*ProjectCatalogCollection, error) + Create(opts *ProjectCatalog) (*ProjectCatalog, error) + Update(existing *ProjectCatalog, updates interface{}) (*ProjectCatalog, error) + Replace(existing *ProjectCatalog) (*ProjectCatalog, error) + ByID(id string) (*ProjectCatalog, error) + Delete(container *ProjectCatalog) error + + ActionRefresh(resource *ProjectCatalog) (*CatalogRefresh, error) + + CollectionActionRefresh(resource *ProjectCatalogCollection) (*CatalogRefresh, error) +} + +func newProjectCatalogClient(apiClient *Client) *ProjectCatalogClient { + return &ProjectCatalogClient{ + apiClient: apiClient, + } +} + +func (c *ProjectCatalogClient) Create(container *ProjectCatalog) (*ProjectCatalog, error) { + resp := &ProjectCatalog{} + err := c.apiClient.Ops.DoCreate(ProjectCatalogType, container, resp) + return resp, err +} + +func (c *ProjectCatalogClient) Update(existing *ProjectCatalog, updates interface{}) (*ProjectCatalog, error) { + resp := &ProjectCatalog{} + err := c.apiClient.Ops.DoUpdate(ProjectCatalogType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ProjectCatalogClient) Replace(obj *ProjectCatalog) (*ProjectCatalog, error) { + resp := &ProjectCatalog{} + err := c.apiClient.Ops.DoReplace(ProjectCatalogType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ProjectCatalogClient) List(opts *types.ListOpts) (*ProjectCatalogCollection, error) { + resp := &ProjectCatalogCollection{} + err := c.apiClient.Ops.DoList(ProjectCatalogType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ProjectCatalogClient) ListAll(opts *types.ListOpts) (*ProjectCatalogCollection, error) { + resp := &ProjectCatalogCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ProjectCatalogCollection) Next() (*ProjectCatalogCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ProjectCatalogCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ProjectCatalogClient) ByID(id string) (*ProjectCatalog, error) { + resp := &ProjectCatalog{} + err := c.apiClient.Ops.DoByID(ProjectCatalogType, id, resp) + return resp, err +} + +func (c *ProjectCatalogClient) Delete(container *ProjectCatalog) error { + return c.apiClient.Ops.DoResourceDelete(ProjectCatalogType, &container.Resource) +} + +func (c *ProjectCatalogClient) ActionRefresh(resource *ProjectCatalog) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoAction(ProjectCatalogType, "refresh", &resource.Resource, nil, resp) + return resp, err +} + +func (c *ProjectCatalogClient) CollectionActionRefresh(resource *ProjectCatalogCollection) (*CatalogRefresh, error) { + resp := &CatalogRefresh{} + err := c.apiClient.Ops.DoCollectionAction(ProjectCatalogType, "refresh", &resource.Collection, nil, resp) + return resp, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_condition.go new file mode 100644 index 0000000..b0907cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ProjectConditionType = "projectCondition" + ProjectConditionFieldLastTransitionTime = "lastTransitionTime" + ProjectConditionFieldLastUpdateTime = "lastUpdateTime" + ProjectConditionFieldMessage = "message" + ProjectConditionFieldReason = "reason" + ProjectConditionFieldStatus = "status" + ProjectConditionFieldType = "type" +) + +type ProjectCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy.go new file mode 100644 index 0000000..0df489f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ProjectNetworkPolicyType = "projectNetworkPolicy" + ProjectNetworkPolicyFieldAnnotations = "annotations" + ProjectNetworkPolicyFieldCreated = "created" + ProjectNetworkPolicyFieldCreatorID = "creatorId" + ProjectNetworkPolicyFieldDescription = "description" + ProjectNetworkPolicyFieldLabels = "labels" + ProjectNetworkPolicyFieldName = "name" + ProjectNetworkPolicyFieldNamespaceId = "namespaceId" + ProjectNetworkPolicyFieldOwnerReferences = "ownerReferences" + ProjectNetworkPolicyFieldProjectID = "projectId" + ProjectNetworkPolicyFieldRemoved = "removed" + ProjectNetworkPolicyFieldState = "state" + ProjectNetworkPolicyFieldStatus = "status" + ProjectNetworkPolicyFieldTransitioning = "transitioning" + ProjectNetworkPolicyFieldTransitioningMessage = "transitioningMessage" + ProjectNetworkPolicyFieldUUID = "uuid" +) + +type ProjectNetworkPolicy struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *ProjectNetworkPolicyStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ProjectNetworkPolicyCollection struct { + types.Collection + Data []ProjectNetworkPolicy `json:"data,omitempty"` + client *ProjectNetworkPolicyClient +} + +type ProjectNetworkPolicyClient struct { + apiClient *Client +} + +type ProjectNetworkPolicyOperations interface { + List(opts *types.ListOpts) (*ProjectNetworkPolicyCollection, error) + ListAll(opts *types.ListOpts) (*ProjectNetworkPolicyCollection, error) + Create(opts *ProjectNetworkPolicy) (*ProjectNetworkPolicy, error) + Update(existing *ProjectNetworkPolicy, updates interface{}) (*ProjectNetworkPolicy, error) + Replace(existing *ProjectNetworkPolicy) (*ProjectNetworkPolicy, error) + ByID(id string) (*ProjectNetworkPolicy, error) + Delete(container *ProjectNetworkPolicy) error +} + +func newProjectNetworkPolicyClient(apiClient *Client) *ProjectNetworkPolicyClient { + return &ProjectNetworkPolicyClient{ + apiClient: apiClient, + } +} + +func (c *ProjectNetworkPolicyClient) Create(container *ProjectNetworkPolicy) (*ProjectNetworkPolicy, error) { + resp := &ProjectNetworkPolicy{} + err := c.apiClient.Ops.DoCreate(ProjectNetworkPolicyType, container, resp) + return resp, err +} + +func (c *ProjectNetworkPolicyClient) Update(existing *ProjectNetworkPolicy, updates interface{}) (*ProjectNetworkPolicy, error) { + resp := &ProjectNetworkPolicy{} + err := c.apiClient.Ops.DoUpdate(ProjectNetworkPolicyType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ProjectNetworkPolicyClient) Replace(obj *ProjectNetworkPolicy) (*ProjectNetworkPolicy, error) { + resp := &ProjectNetworkPolicy{} + err := c.apiClient.Ops.DoReplace(ProjectNetworkPolicyType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ProjectNetworkPolicyClient) List(opts *types.ListOpts) (*ProjectNetworkPolicyCollection, error) { + resp := &ProjectNetworkPolicyCollection{} + err := c.apiClient.Ops.DoList(ProjectNetworkPolicyType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ProjectNetworkPolicyClient) ListAll(opts *types.ListOpts) (*ProjectNetworkPolicyCollection, error) { + resp := &ProjectNetworkPolicyCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ProjectNetworkPolicyCollection) Next() (*ProjectNetworkPolicyCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ProjectNetworkPolicyCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ProjectNetworkPolicyClient) ByID(id string) (*ProjectNetworkPolicy, error) { + resp := &ProjectNetworkPolicy{} + err := c.apiClient.Ops.DoByID(ProjectNetworkPolicyType, id, resp) + return resp, err +} + +func (c *ProjectNetworkPolicyClient) Delete(container *ProjectNetworkPolicy) error { + return c.apiClient.Ops.DoResourceDelete(ProjectNetworkPolicyType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_spec.go new file mode 100644 index 0000000..6875efb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_spec.go @@ -0,0 +1,12 @@ +package client + +const ( + ProjectNetworkPolicySpecType = "projectNetworkPolicySpec" + ProjectNetworkPolicySpecFieldDescription = "description" + ProjectNetworkPolicySpecFieldProjectID = "projectId" +) + +type ProjectNetworkPolicySpec struct { + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_status.go new file mode 100644 index 0000000..cef3c16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_network_policy_status.go @@ -0,0 +1,8 @@ +package client + +const ( + ProjectNetworkPolicyStatusType = "projectNetworkPolicyStatus" +) + +type ProjectNetworkPolicyStatus struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_resource_quota.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_resource_quota.go new file mode 100644 index 0000000..05f7366 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_resource_quota.go @@ -0,0 +1,12 @@ +package client + +const ( + ProjectResourceQuotaType = "projectResourceQuota" + ProjectResourceQuotaFieldLimit = "limit" + ProjectResourceQuotaFieldUsedLimit = "usedLimit" +) + +type ProjectResourceQuota struct { + Limit *ResourceQuotaLimit `json:"limit,omitempty" yaml:"limit,omitempty"` + UsedLimit *ResourceQuotaLimit `json:"usedLimit,omitempty" yaml:"usedLimit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_role_template_binding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_role_template_binding.go new file mode 100644 index 0000000..4723756 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_role_template_binding.go @@ -0,0 +1,134 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ProjectRoleTemplateBindingType = "projectRoleTemplateBinding" + ProjectRoleTemplateBindingFieldAnnotations = "annotations" + ProjectRoleTemplateBindingFieldCreated = "created" + ProjectRoleTemplateBindingFieldCreatorID = "creatorId" + ProjectRoleTemplateBindingFieldGroupID = "groupId" + ProjectRoleTemplateBindingFieldGroupPrincipalID = "groupPrincipalId" + ProjectRoleTemplateBindingFieldLabels = "labels" + ProjectRoleTemplateBindingFieldName = "name" + ProjectRoleTemplateBindingFieldNamespaceId = "namespaceId" + ProjectRoleTemplateBindingFieldOwnerReferences = "ownerReferences" + ProjectRoleTemplateBindingFieldProjectID = "projectId" + ProjectRoleTemplateBindingFieldRemoved = "removed" + ProjectRoleTemplateBindingFieldRoleTemplateID = "roleTemplateId" + ProjectRoleTemplateBindingFieldServiceAccount = "serviceAccount" + ProjectRoleTemplateBindingFieldUUID = "uuid" + ProjectRoleTemplateBindingFieldUserID = "userId" + ProjectRoleTemplateBindingFieldUserPrincipalID = "userPrincipalId" +) + +type ProjectRoleTemplateBinding struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + GroupID string `json:"groupId,omitempty" yaml:"groupId,omitempty"` + GroupPrincipalID string `json:"groupPrincipalId,omitempty" yaml:"groupPrincipalId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RoleTemplateID string `json:"roleTemplateId,omitempty" yaml:"roleTemplateId,omitempty"` + ServiceAccount string `json:"serviceAccount,omitempty" yaml:"serviceAccount,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserID string `json:"userId,omitempty" yaml:"userId,omitempty"` + UserPrincipalID string `json:"userPrincipalId,omitempty" yaml:"userPrincipalId,omitempty"` +} + +type ProjectRoleTemplateBindingCollection struct { + types.Collection + Data []ProjectRoleTemplateBinding `json:"data,omitempty"` + client *ProjectRoleTemplateBindingClient +} + +type ProjectRoleTemplateBindingClient struct { + apiClient *Client +} + +type ProjectRoleTemplateBindingOperations interface { + List(opts *types.ListOpts) (*ProjectRoleTemplateBindingCollection, error) + ListAll(opts *types.ListOpts) (*ProjectRoleTemplateBindingCollection, error) + Create(opts *ProjectRoleTemplateBinding) (*ProjectRoleTemplateBinding, error) + Update(existing *ProjectRoleTemplateBinding, updates interface{}) (*ProjectRoleTemplateBinding, error) + Replace(existing *ProjectRoleTemplateBinding) (*ProjectRoleTemplateBinding, error) + ByID(id string) (*ProjectRoleTemplateBinding, error) + Delete(container *ProjectRoleTemplateBinding) error +} + +func newProjectRoleTemplateBindingClient(apiClient *Client) *ProjectRoleTemplateBindingClient { + return &ProjectRoleTemplateBindingClient{ + apiClient: apiClient, + } +} + +func (c *ProjectRoleTemplateBindingClient) Create(container *ProjectRoleTemplateBinding) (*ProjectRoleTemplateBinding, error) { + resp := &ProjectRoleTemplateBinding{} + err := c.apiClient.Ops.DoCreate(ProjectRoleTemplateBindingType, container, resp) + return resp, err +} + +func (c *ProjectRoleTemplateBindingClient) Update(existing *ProjectRoleTemplateBinding, updates interface{}) (*ProjectRoleTemplateBinding, error) { + resp := &ProjectRoleTemplateBinding{} + err := c.apiClient.Ops.DoUpdate(ProjectRoleTemplateBindingType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ProjectRoleTemplateBindingClient) Replace(obj *ProjectRoleTemplateBinding) (*ProjectRoleTemplateBinding, error) { + resp := &ProjectRoleTemplateBinding{} + err := c.apiClient.Ops.DoReplace(ProjectRoleTemplateBindingType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ProjectRoleTemplateBindingClient) List(opts *types.ListOpts) (*ProjectRoleTemplateBindingCollection, error) { + resp := &ProjectRoleTemplateBindingCollection{} + err := c.apiClient.Ops.DoList(ProjectRoleTemplateBindingType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ProjectRoleTemplateBindingClient) ListAll(opts *types.ListOpts) (*ProjectRoleTemplateBindingCollection, error) { + resp := &ProjectRoleTemplateBindingCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ProjectRoleTemplateBindingCollection) Next() (*ProjectRoleTemplateBindingCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ProjectRoleTemplateBindingCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ProjectRoleTemplateBindingClient) ByID(id string) (*ProjectRoleTemplateBinding, error) { + resp := &ProjectRoleTemplateBinding{} + err := c.apiClient.Ops.DoByID(ProjectRoleTemplateBindingType, id, resp) + return resp, err +} + +func (c *ProjectRoleTemplateBindingClient) Delete(container *ProjectRoleTemplateBinding) error { + return c.apiClient.Ops.DoResourceDelete(ProjectRoleTemplateBindingType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_spec.go new file mode 100644 index 0000000..e1e940b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_spec.go @@ -0,0 +1,20 @@ +package client + +const ( + ProjectSpecType = "projectSpec" + ProjectSpecFieldClusterID = "clusterId" + ProjectSpecFieldContainerDefaultResourceLimit = "containerDefaultResourceLimit" + ProjectSpecFieldDescription = "description" + ProjectSpecFieldDisplayName = "displayName" + ProjectSpecFieldNamespaceDefaultResourceQuota = "namespaceDefaultResourceQuota" + ProjectSpecFieldResourceQuota = "resourceQuota" +) + +type ProjectSpec struct { + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + ContainerDefaultResourceLimit *ContainerResourceLimit `json:"containerDefaultResourceLimit,omitempty" yaml:"containerDefaultResourceLimit,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + NamespaceDefaultResourceQuota *NamespaceResourceQuota `json:"namespaceDefaultResourceQuota,omitempty" yaml:"namespaceDefaultResourceQuota,omitempty"` + ResourceQuota *ProjectResourceQuota `json:"resourceQuota,omitempty" yaml:"resourceQuota,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_status.go new file mode 100644 index 0000000..7806c91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_project_status.go @@ -0,0 +1,10 @@ +package client + +const ( + ProjectStatusType = "projectStatus" + ProjectStatusFieldConditions = "conditions" +) + +type ProjectStatus struct { + Conditions []ProjectCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_projected_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_projected_volume_source.go new file mode 100644 index 0000000..f90539e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_projected_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ProjectedVolumeSourceType = "projectedVolumeSource" + ProjectedVolumeSourceFieldDefaultMode = "defaultMode" + ProjectedVolumeSourceFieldSources = "sources" +) + +type ProjectedVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Sources []VolumeProjection `json:"sources,omitempty" yaml:"sources,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_provider_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_provider_configuration.go new file mode 100644 index 0000000..4a29cfd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_provider_configuration.go @@ -0,0 +1,18 @@ +package client + +const ( + ProviderConfigurationType = "providerConfiguration" + ProviderConfigurationFieldAESCBC = "aescbc" + ProviderConfigurationFieldAESGCM = "aesgcm" + ProviderConfigurationFieldIdentity = "identity" + ProviderConfigurationFieldKMS = "kms" + ProviderConfigurationFieldSecretbox = "secretbox" +) + +type ProviderConfiguration struct { + AESCBC *AESConfiguration `json:"aescbc,omitempty" yaml:"aescbc,omitempty"` + AESGCM *AESConfiguration `json:"aesgcm,omitempty" yaml:"aesgcm,omitempty"` + Identity *IdentityConfiguration `json:"identity,omitempty" yaml:"identity,omitempty"` + KMS *KMSConfiguration `json:"kms,omitempty" yaml:"kms,omitempty"` + Secretbox *SecretboxConfiguration `json:"secretbox,omitempty" yaml:"secretbox,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_public_endpoint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_public_endpoint.go new file mode 100644 index 0000000..85844aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_public_endpoint.go @@ -0,0 +1,28 @@ +package client + +const ( + PublicEndpointType = "publicEndpoint" + PublicEndpointFieldAddresses = "addresses" + PublicEndpointFieldAllNodes = "allNodes" + PublicEndpointFieldHostname = "hostname" + PublicEndpointFieldIngressID = "ingressId" + PublicEndpointFieldNodeID = "nodeId" + PublicEndpointFieldPath = "path" + PublicEndpointFieldPodID = "podId" + PublicEndpointFieldPort = "port" + PublicEndpointFieldProtocol = "protocol" + PublicEndpointFieldServiceID = "serviceId" +) + +type PublicEndpoint struct { + Addresses []string `json:"addresses,omitempty" yaml:"addresses,omitempty"` + AllNodes bool `json:"allNodes,omitempty" yaml:"allNodes,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IngressID string `json:"ingressId,omitempty" yaml:"ingressId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + PodID string `json:"podId,omitempty" yaml:"podId,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + ServiceID string `json:"serviceId,omitempty" yaml:"serviceId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_question.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_question.go new file mode 100644 index 0000000..6042683 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_question.go @@ -0,0 +1,44 @@ +package client + +const ( + QuestionType = "question" + QuestionFieldDefault = "default" + QuestionFieldDescription = "description" + QuestionFieldGroup = "group" + QuestionFieldInvalidChars = "invalidChars" + QuestionFieldLabel = "label" + QuestionFieldMax = "max" + QuestionFieldMaxLength = "maxLength" + QuestionFieldMin = "min" + QuestionFieldMinLength = "minLength" + QuestionFieldOptions = "options" + QuestionFieldRequired = "required" + QuestionFieldSatisfies = "satisfies" + QuestionFieldShowIf = "showIf" + QuestionFieldShowSubquestionIf = "showSubquestionIf" + QuestionFieldSubquestions = "subquestions" + QuestionFieldType = "type" + QuestionFieldValidChars = "validChars" + QuestionFieldVariable = "variable" +) + +type Question struct { + Default string `json:"default,omitempty" yaml:"default,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + InvalidChars string `json:"invalidChars,omitempty" yaml:"invalidChars,omitempty"` + Label string `json:"label,omitempty" yaml:"label,omitempty"` + Max int64 `json:"max,omitempty" yaml:"max,omitempty"` + MaxLength int64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"` + Min int64 `json:"min,omitempty" yaml:"min,omitempty"` + MinLength int64 `json:"minLength,omitempty" yaml:"minLength,omitempty"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + Required bool `json:"required,omitempty" yaml:"required,omitempty"` + Satisfies string `json:"satisfies,omitempty" yaml:"satisfies,omitempty"` + ShowIf string `json:"showIf,omitempty" yaml:"showIf,omitempty"` + ShowSubquestionIf string `json:"showSubquestionIf,omitempty" yaml:"showSubquestionIf,omitempty"` + Subquestions []SubQuestion `json:"subquestions,omitempty" yaml:"subquestions,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + ValidChars string `json:"validChars,omitempty" yaml:"validChars,omitempty"` + Variable string `json:"variable,omitempty" yaml:"variable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_quobyte_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_quobyte_volume_source.go new file mode 100644 index 0000000..41e308d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_quobyte_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + QuobyteVolumeSourceType = "quobyteVolumeSource" + QuobyteVolumeSourceFieldGroup = "group" + QuobyteVolumeSourceFieldReadOnly = "readOnly" + QuobyteVolumeSourceFieldRegistry = "registry" + QuobyteVolumeSourceFieldTenant = "tenant" + QuobyteVolumeSourceFieldUser = "user" + QuobyteVolumeSourceFieldVolume = "volume" +) + +type QuobyteVolumeSource struct { + Group string `json:"group,omitempty" yaml:"group,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Registry string `json:"registry,omitempty" yaml:"registry,omitempty"` + Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + Volume string `json:"volume,omitempty" yaml:"volume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_kubernetes_engine_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_kubernetes_engine_config.go new file mode 100644 index 0000000..19d3369 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_kubernetes_engine_config.go @@ -0,0 +1,62 @@ +package client + +const ( + RancherKubernetesEngineConfigType = "rancherKubernetesEngineConfig" + RancherKubernetesEngineConfigFieldAddonJobTimeout = "addonJobTimeout" + RancherKubernetesEngineConfigFieldAddons = "addons" + RancherKubernetesEngineConfigFieldAddonsInclude = "addonsInclude" + RancherKubernetesEngineConfigFieldAuthentication = "authentication" + RancherKubernetesEngineConfigFieldAuthorization = "authorization" + RancherKubernetesEngineConfigFieldBastionHost = "bastionHost" + RancherKubernetesEngineConfigFieldCloudProvider = "cloudProvider" + RancherKubernetesEngineConfigFieldClusterName = "clusterName" + RancherKubernetesEngineConfigFieldDNS = "dns" + RancherKubernetesEngineConfigFieldEnableCRIDockerd = "enableCriDockerd" + RancherKubernetesEngineConfigFieldIgnoreDockerVersion = "ignoreDockerVersion" + RancherKubernetesEngineConfigFieldIngress = "ingress" + RancherKubernetesEngineConfigFieldMonitoring = "monitoring" + RancherKubernetesEngineConfigFieldNetwork = "network" + RancherKubernetesEngineConfigFieldNodes = "nodes" + RancherKubernetesEngineConfigFieldPrefixPath = "prefixPath" + RancherKubernetesEngineConfigFieldPrivateRegistries = "privateRegistries" + RancherKubernetesEngineConfigFieldRestore = "restore" + RancherKubernetesEngineConfigFieldRotateCertificates = "rotateCertificates" + RancherKubernetesEngineConfigFieldRotateEncryptionKey = "rotateEncryptionKey" + RancherKubernetesEngineConfigFieldSSHAgentAuth = "sshAgentAuth" + RancherKubernetesEngineConfigFieldSSHCertPath = "sshCertPath" + RancherKubernetesEngineConfigFieldSSHKeyPath = "sshKeyPath" + RancherKubernetesEngineConfigFieldServices = "services" + RancherKubernetesEngineConfigFieldUpgradeStrategy = "upgradeStrategy" + RancherKubernetesEngineConfigFieldVersion = "kubernetesVersion" + RancherKubernetesEngineConfigFieldWindowsPrefixPath = "winPrefixPath" +) + +type RancherKubernetesEngineConfig struct { + AddonJobTimeout int64 `json:"addonJobTimeout,omitempty" yaml:"addonJobTimeout,omitempty"` + Addons string `json:"addons,omitempty" yaml:"addons,omitempty"` + AddonsInclude []string `json:"addonsInclude,omitempty" yaml:"addonsInclude,omitempty"` + Authentication *AuthnConfig `json:"authentication,omitempty" yaml:"authentication,omitempty"` + Authorization *AuthzConfig `json:"authorization,omitempty" yaml:"authorization,omitempty"` + BastionHost *BastionHost `json:"bastionHost,omitempty" yaml:"bastionHost,omitempty"` + CloudProvider *CloudProvider `json:"cloudProvider,omitempty" yaml:"cloudProvider,omitempty"` + ClusterName string `json:"clusterName,omitempty" yaml:"clusterName,omitempty"` + DNS *DNSConfig `json:"dns,omitempty" yaml:"dns,omitempty"` + EnableCRIDockerd *bool `json:"enableCriDockerd,omitempty" yaml:"enableCriDockerd,omitempty"` + IgnoreDockerVersion *bool `json:"ignoreDockerVersion,omitempty" yaml:"ignoreDockerVersion,omitempty"` + Ingress *IngressConfig `json:"ingress,omitempty" yaml:"ingress,omitempty"` + Monitoring *MonitoringConfig `json:"monitoring,omitempty" yaml:"monitoring,omitempty"` + Network *NetworkConfig `json:"network,omitempty" yaml:"network,omitempty"` + Nodes []RKEConfigNode `json:"nodes,omitempty" yaml:"nodes,omitempty"` + PrefixPath string `json:"prefixPath,omitempty" yaml:"prefixPath,omitempty"` + PrivateRegistries []PrivateRegistry `json:"privateRegistries,omitempty" yaml:"privateRegistries,omitempty"` + Restore *RestoreConfig `json:"restore,omitempty" yaml:"restore,omitempty"` + RotateCertificates *RotateCertificates `json:"rotateCertificates,omitempty" yaml:"rotateCertificates,omitempty"` + RotateEncryptionKey bool `json:"rotateEncryptionKey,omitempty" yaml:"rotateEncryptionKey,omitempty"` + SSHAgentAuth bool `json:"sshAgentAuth,omitempty" yaml:"sshAgentAuth,omitempty"` + SSHCertPath string `json:"sshCertPath,omitempty" yaml:"sshCertPath,omitempty"` + SSHKeyPath string `json:"sshKeyPath,omitempty" yaml:"sshKeyPath,omitempty"` + Services *RKEConfigServices `json:"services,omitempty" yaml:"services,omitempty"` + UpgradeStrategy *NodeUpgradeStrategy `json:"upgradeStrategy,omitempty" yaml:"upgradeStrategy,omitempty"` + Version string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` + WindowsPrefixPath string `json:"winPrefixPath,omitempty" yaml:"winPrefixPath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_user_notification.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_user_notification.go new file mode 100644 index 0000000..8fa289e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rancher_user_notification.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + RancherUserNotificationType = "rancherUserNotification" + RancherUserNotificationFieldAnnotations = "annotations" + RancherUserNotificationFieldComponentName = "componentName" + RancherUserNotificationFieldCreated = "created" + RancherUserNotificationFieldCreatorID = "creatorId" + RancherUserNotificationFieldLabels = "labels" + RancherUserNotificationFieldMessage = "message" + RancherUserNotificationFieldName = "name" + RancherUserNotificationFieldOwnerReferences = "ownerReferences" + RancherUserNotificationFieldRemoved = "removed" + RancherUserNotificationFieldUUID = "uuid" +) + +type RancherUserNotification struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ComponentName string `json:"componentName,omitempty" yaml:"componentName,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type RancherUserNotificationCollection struct { + types.Collection + Data []RancherUserNotification `json:"data,omitempty"` + client *RancherUserNotificationClient +} + +type RancherUserNotificationClient struct { + apiClient *Client +} + +type RancherUserNotificationOperations interface { + List(opts *types.ListOpts) (*RancherUserNotificationCollection, error) + ListAll(opts *types.ListOpts) (*RancherUserNotificationCollection, error) + Create(opts *RancherUserNotification) (*RancherUserNotification, error) + Update(existing *RancherUserNotification, updates interface{}) (*RancherUserNotification, error) + Replace(existing *RancherUserNotification) (*RancherUserNotification, error) + ByID(id string) (*RancherUserNotification, error) + Delete(container *RancherUserNotification) error +} + +func newRancherUserNotificationClient(apiClient *Client) *RancherUserNotificationClient { + return &RancherUserNotificationClient{ + apiClient: apiClient, + } +} + +func (c *RancherUserNotificationClient) Create(container *RancherUserNotification) (*RancherUserNotification, error) { + resp := &RancherUserNotification{} + err := c.apiClient.Ops.DoCreate(RancherUserNotificationType, container, resp) + return resp, err +} + +func (c *RancherUserNotificationClient) Update(existing *RancherUserNotification, updates interface{}) (*RancherUserNotification, error) { + resp := &RancherUserNotification{} + err := c.apiClient.Ops.DoUpdate(RancherUserNotificationType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *RancherUserNotificationClient) Replace(obj *RancherUserNotification) (*RancherUserNotification, error) { + resp := &RancherUserNotification{} + err := c.apiClient.Ops.DoReplace(RancherUserNotificationType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *RancherUserNotificationClient) List(opts *types.ListOpts) (*RancherUserNotificationCollection, error) { + resp := &RancherUserNotificationCollection{} + err := c.apiClient.Ops.DoList(RancherUserNotificationType, opts, resp) + resp.client = c + return resp, err +} + +func (c *RancherUserNotificationClient) ListAll(opts *types.ListOpts) (*RancherUserNotificationCollection, error) { + resp := &RancherUserNotificationCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *RancherUserNotificationCollection) Next() (*RancherUserNotificationCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &RancherUserNotificationCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *RancherUserNotificationClient) ByID(id string) (*RancherUserNotification, error) { + resp := &RancherUserNotification{} + err := c.apiClient.Ops.DoByID(RancherUserNotificationType, id, resp) + return resp, err +} + +func (c *RancherUserNotificationClient) Delete(container *RancherUserNotification) error { + return c.apiClient.Ops.DoResourceDelete(RancherUserNotificationType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rbd_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rbd_volume_source.go new file mode 100644 index 0000000..436a8b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rbd_volume_source.go @@ -0,0 +1,24 @@ +package client + +const ( + RBDVolumeSourceType = "rbdVolumeSource" + RBDVolumeSourceFieldCephMonitors = "monitors" + RBDVolumeSourceFieldFSType = "fsType" + RBDVolumeSourceFieldKeyring = "keyring" + RBDVolumeSourceFieldRBDImage = "image" + RBDVolumeSourceFieldRBDPool = "pool" + RBDVolumeSourceFieldRadosUser = "user" + RBDVolumeSourceFieldReadOnly = "readOnly" + RBDVolumeSourceFieldSecretRef = "secretRef" +) + +type RBDVolumeSource struct { + CephMonitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Keyring string `json:"keyring,omitempty" yaml:"keyring,omitempty"` + RBDImage string `json:"image,omitempty" yaml:"image,omitempty"` + RBDPool string `json:"pool,omitempty" yaml:"pool,omitempty"` + RadosUser string `json:"user,omitempty" yaml:"user,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_claim.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_claim.go new file mode 100644 index 0000000..1ef8e0a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_claim.go @@ -0,0 +1,10 @@ +package client + +const ( + ResourceClaimType = "resourceClaim" + ResourceClaimFieldName = "name" +) + +type ResourceClaim struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_configuration.go new file mode 100644 index 0000000..3c09f76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_configuration.go @@ -0,0 +1,12 @@ +package client + +const ( + ResourceConfigurationType = "resourceConfiguration" + ResourceConfigurationFieldProviders = "providers" + ResourceConfigurationFieldResources = "resources" +) + +type ResourceConfiguration struct { + Providers []ProviderConfiguration `json:"providers,omitempty" yaml:"providers,omitempty"` + Resources []string `json:"resources,omitempty" yaml:"resources,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_field_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_field_selector.go new file mode 100644 index 0000000..d9c0c92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_field_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + ResourceFieldSelectorType = "resourceFieldSelector" + ResourceFieldSelectorFieldContainerName = "containerName" + ResourceFieldSelectorFieldDivisor = "divisor" + ResourceFieldSelectorFieldResource = "resource" +) + +type ResourceFieldSelector struct { + ContainerName string `json:"containerName,omitempty" yaml:"containerName,omitempty"` + Divisor string `json:"divisor,omitempty" yaml:"divisor,omitempty"` + Resource string `json:"resource,omitempty" yaml:"resource,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_quota_limit.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_quota_limit.go new file mode 100644 index 0000000..4bc04ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_quota_limit.go @@ -0,0 +1,34 @@ +package client + +const ( + ResourceQuotaLimitType = "resourceQuotaLimit" + ResourceQuotaLimitFieldConfigMaps = "configMaps" + ResourceQuotaLimitFieldLimitsCPU = "limitsCpu" + ResourceQuotaLimitFieldLimitsMemory = "limitsMemory" + ResourceQuotaLimitFieldPersistentVolumeClaims = "persistentVolumeClaims" + ResourceQuotaLimitFieldPods = "pods" + ResourceQuotaLimitFieldReplicationControllers = "replicationControllers" + ResourceQuotaLimitFieldRequestsCPU = "requestsCpu" + ResourceQuotaLimitFieldRequestsMemory = "requestsMemory" + ResourceQuotaLimitFieldRequestsStorage = "requestsStorage" + ResourceQuotaLimitFieldSecrets = "secrets" + ResourceQuotaLimitFieldServices = "services" + ResourceQuotaLimitFieldServicesLoadBalancers = "servicesLoadBalancers" + ResourceQuotaLimitFieldServicesNodePorts = "servicesNodePorts" +) + +type ResourceQuotaLimit struct { + ConfigMaps string `json:"configMaps,omitempty" yaml:"configMaps,omitempty"` + LimitsCPU string `json:"limitsCpu,omitempty" yaml:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty" yaml:"limitsMemory,omitempty"` + PersistentVolumeClaims string `json:"persistentVolumeClaims,omitempty" yaml:"persistentVolumeClaims,omitempty"` + Pods string `json:"pods,omitempty" yaml:"pods,omitempty"` + ReplicationControllers string `json:"replicationControllers,omitempty" yaml:"replicationControllers,omitempty"` + RequestsCPU string `json:"requestsCpu,omitempty" yaml:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty" yaml:"requestsMemory,omitempty"` + RequestsStorage string `json:"requestsStorage,omitempty" yaml:"requestsStorage,omitempty"` + Secrets string `json:"secrets,omitempty" yaml:"secrets,omitempty"` + Services string `json:"services,omitempty" yaml:"services,omitempty"` + ServicesLoadBalancers string `json:"servicesLoadBalancers,omitempty" yaml:"servicesLoadBalancers,omitempty"` + ServicesNodePorts string `json:"servicesNodePorts,omitempty" yaml:"servicesNodePorts,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_requirements.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_requirements.go new file mode 100644 index 0000000..5fe765a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_resource_requirements.go @@ -0,0 +1,14 @@ +package client + +const ( + ResourceRequirementsType = "resourceRequirements" + ResourceRequirementsFieldClaims = "claims" + ResourceRequirementsFieldLimits = "limits" + ResourceRequirementsFieldRequests = "requests" +) + +type ResourceRequirements struct { + Claims []ResourceClaim `json:"claims,omitempty" yaml:"claims,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + Requests map[string]string `json:"requests,omitempty" yaml:"requests,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_config.go new file mode 100644 index 0000000..8370f96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_config.go @@ -0,0 +1,12 @@ +package client + +const ( + RestoreConfigType = "restoreConfig" + RestoreConfigFieldRestore = "restore" + RestoreConfigFieldSnapshotName = "snapshotName" +) + +type RestoreConfig struct { + Restore bool `json:"restore,omitempty" yaml:"restore,omitempty"` + SnapshotName string `json:"snapshotName,omitempty" yaml:"snapshotName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_from_etcd_backup_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_from_etcd_backup_input.go new file mode 100644 index 0000000..7bd5f59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_restore_from_etcd_backup_input.go @@ -0,0 +1,12 @@ +package client + +const ( + RestoreFromEtcdBackupInputType = "restoreFromEtcdBackupInput" + RestoreFromEtcdBackupInputFieldEtcdBackupID = "etcdBackupId" + RestoreFromEtcdBackupInputFieldRestoreRkeConfig = "restoreRkeConfig" +) + +type RestoreFromEtcdBackupInput struct { + EtcdBackupID string `json:"etcdBackupId,omitempty" yaml:"etcdBackupId,omitempty"` + RestoreRkeConfig string `json:"restoreRkeConfig,omitempty" yaml:"restoreRkeConfig,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke2config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke2config.go new file mode 100644 index 0000000..3e355a9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke2config.go @@ -0,0 +1,12 @@ +package client + +const ( + Rke2ConfigType = "rke2Config" + Rke2ConfigFieldClusterUpgradeStrategy = "rke2upgradeStrategy" + Rke2ConfigFieldVersion = "kubernetesVersion" +) + +type Rke2Config struct { + ClusterUpgradeStrategy *ClusterUpgradeStrategy `json:"rke2upgradeStrategy,omitempty" yaml:"rke2upgradeStrategy,omitempty"` + Version string `json:"kubernetesVersion,omitempty" yaml:"kubernetesVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_addon.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_addon.go new file mode 100644 index 0000000..67719ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_addon.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + RkeAddonType = "rkeAddon" + RkeAddonFieldAnnotations = "annotations" + RkeAddonFieldCreated = "created" + RkeAddonFieldCreatorID = "creatorId" + RkeAddonFieldLabels = "labels" + RkeAddonFieldName = "name" + RkeAddonFieldOwnerReferences = "ownerReferences" + RkeAddonFieldRemoved = "removed" + RkeAddonFieldTemplate = "template" + RkeAddonFieldUUID = "uuid" +) + +type RkeAddon struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Template string `json:"template,omitempty" yaml:"template,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type RkeAddonCollection struct { + types.Collection + Data []RkeAddon `json:"data,omitempty"` + client *RkeAddonClient +} + +type RkeAddonClient struct { + apiClient *Client +} + +type RkeAddonOperations interface { + List(opts *types.ListOpts) (*RkeAddonCollection, error) + ListAll(opts *types.ListOpts) (*RkeAddonCollection, error) + Create(opts *RkeAddon) (*RkeAddon, error) + Update(existing *RkeAddon, updates interface{}) (*RkeAddon, error) + Replace(existing *RkeAddon) (*RkeAddon, error) + ByID(id string) (*RkeAddon, error) + Delete(container *RkeAddon) error +} + +func newRkeAddonClient(apiClient *Client) *RkeAddonClient { + return &RkeAddonClient{ + apiClient: apiClient, + } +} + +func (c *RkeAddonClient) Create(container *RkeAddon) (*RkeAddon, error) { + resp := &RkeAddon{} + err := c.apiClient.Ops.DoCreate(RkeAddonType, container, resp) + return resp, err +} + +func (c *RkeAddonClient) Update(existing *RkeAddon, updates interface{}) (*RkeAddon, error) { + resp := &RkeAddon{} + err := c.apiClient.Ops.DoUpdate(RkeAddonType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *RkeAddonClient) Replace(obj *RkeAddon) (*RkeAddon, error) { + resp := &RkeAddon{} + err := c.apiClient.Ops.DoReplace(RkeAddonType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *RkeAddonClient) List(opts *types.ListOpts) (*RkeAddonCollection, error) { + resp := &RkeAddonCollection{} + err := c.apiClient.Ops.DoList(RkeAddonType, opts, resp) + resp.client = c + return resp, err +} + +func (c *RkeAddonClient) ListAll(opts *types.ListOpts) (*RkeAddonCollection, error) { + resp := &RkeAddonCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *RkeAddonCollection) Next() (*RkeAddonCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &RkeAddonCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *RkeAddonClient) ByID(id string) (*RkeAddon, error) { + resp := &RkeAddon{} + err := c.apiClient.Ops.DoByID(RkeAddonType, id, resp) + return resp, err +} + +func (c *RkeAddonClient) Delete(container *RkeAddon) error { + return c.apiClient.Ops.DoResourceDelete(RkeAddonType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node.go new file mode 100644 index 0000000..a8a2c20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node.go @@ -0,0 +1,38 @@ +package client + +const ( + RKEConfigNodeType = "rkeConfigNode" + RKEConfigNodeFieldAddress = "address" + RKEConfigNodeFieldDockerSocket = "dockerSocket" + RKEConfigNodeFieldHostnameOverride = "hostnameOverride" + RKEConfigNodeFieldInternalAddress = "internalAddress" + RKEConfigNodeFieldLabels = "labels" + RKEConfigNodeFieldNodeID = "nodeId" + RKEConfigNodeFieldPort = "port" + RKEConfigNodeFieldRole = "role" + RKEConfigNodeFieldSSHAgentAuth = "sshAgentAuth" + RKEConfigNodeFieldSSHCert = "sshCert" + RKEConfigNodeFieldSSHCertPath = "sshCertPath" + RKEConfigNodeFieldSSHKey = "sshKey" + RKEConfigNodeFieldSSHKeyPath = "sshKeyPath" + RKEConfigNodeFieldTaints = "taints" + RKEConfigNodeFieldUser = "user" +) + +type RKEConfigNode struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + DockerSocket string `json:"dockerSocket,omitempty" yaml:"dockerSocket,omitempty"` + HostnameOverride string `json:"hostnameOverride,omitempty" yaml:"hostnameOverride,omitempty"` + InternalAddress string `json:"internalAddress,omitempty" yaml:"internalAddress,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + Port string `json:"port,omitempty" yaml:"port,omitempty"` + Role []string `json:"role,omitempty" yaml:"role,omitempty"` + SSHAgentAuth bool `json:"sshAgentAuth,omitempty" yaml:"sshAgentAuth,omitempty"` + SSHCert string `json:"sshCert,omitempty" yaml:"sshCert,omitempty"` + SSHCertPath string `json:"sshCertPath,omitempty" yaml:"sshCertPath,omitempty"` + SSHKey string `json:"sshKey,omitempty" yaml:"sshKey,omitempty"` + SSHKeyPath string `json:"sshKeyPath,omitempty" yaml:"sshKeyPath,omitempty"` + Taints []RKETaint `json:"taints,omitempty" yaml:"taints,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node_plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node_plan.go new file mode 100644 index 0000000..fd9224f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_node_plan.go @@ -0,0 +1,22 @@ +package client + +const ( + RKEConfigNodePlanType = "rkeConfigNodePlan" + RKEConfigNodePlanFieldAddress = "address" + RKEConfigNodePlanFieldAnnotations = "annotations" + RKEConfigNodePlanFieldFiles = "files" + RKEConfigNodePlanFieldLabels = "labels" + RKEConfigNodePlanFieldPortChecks = "portChecks" + RKEConfigNodePlanFieldProcesses = "processes" + RKEConfigNodePlanFieldTaints = "taints" +) + +type RKEConfigNodePlan struct { + Address string `json:"address,omitempty" yaml:"address,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Files []File `json:"files,omitempty" yaml:"files,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + PortChecks []PortCheck `json:"portChecks,omitempty" yaml:"portChecks,omitempty"` + Processes map[string]Process `json:"processes,omitempty" yaml:"processes,omitempty"` + Taints []RKETaint `json:"taints,omitempty" yaml:"taints,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_services.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_services.go new file mode 100644 index 0000000..16086f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_config_services.go @@ -0,0 +1,20 @@ +package client + +const ( + RKEConfigServicesType = "rkeConfigServices" + RKEConfigServicesFieldEtcd = "etcd" + RKEConfigServicesFieldKubeAPI = "kubeApi" + RKEConfigServicesFieldKubeController = "kubeController" + RKEConfigServicesFieldKubelet = "kubelet" + RKEConfigServicesFieldKubeproxy = "kubeproxy" + RKEConfigServicesFieldScheduler = "scheduler" +) + +type RKEConfigServices struct { + Etcd *ETCDService `json:"etcd,omitempty" yaml:"etcd,omitempty"` + KubeAPI *KubeAPIService `json:"kubeApi,omitempty" yaml:"kubeApi,omitempty"` + KubeController *KubeControllerService `json:"kubeController,omitempty" yaml:"kubeController,omitempty"` + Kubelet *KubeletService `json:"kubelet,omitempty" yaml:"kubelet,omitempty"` + Kubeproxy *KubeproxyService `json:"kubeproxy,omitempty" yaml:"kubeproxy,omitempty"` + Scheduler *SchedulerService `json:"scheduler,omitempty" yaml:"scheduler,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_service_option.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_service_option.go new file mode 100644 index 0000000..6c5173f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_service_option.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + RkeK8sServiceOptionType = "rkeK8sServiceOption" + RkeK8sServiceOptionFieldAnnotations = "annotations" + RkeK8sServiceOptionFieldCreated = "created" + RkeK8sServiceOptionFieldCreatorID = "creatorId" + RkeK8sServiceOptionFieldLabels = "labels" + RkeK8sServiceOptionFieldName = "name" + RkeK8sServiceOptionFieldOwnerReferences = "ownerReferences" + RkeK8sServiceOptionFieldRemoved = "removed" + RkeK8sServiceOptionFieldServiceOptions = "serviceOptions" + RkeK8sServiceOptionFieldUUID = "uuid" +) + +type RkeK8sServiceOption struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ServiceOptions *KubernetesServicesOptions `json:"serviceOptions,omitempty" yaml:"serviceOptions,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type RkeK8sServiceOptionCollection struct { + types.Collection + Data []RkeK8sServiceOption `json:"data,omitempty"` + client *RkeK8sServiceOptionClient +} + +type RkeK8sServiceOptionClient struct { + apiClient *Client +} + +type RkeK8sServiceOptionOperations interface { + List(opts *types.ListOpts) (*RkeK8sServiceOptionCollection, error) + ListAll(opts *types.ListOpts) (*RkeK8sServiceOptionCollection, error) + Create(opts *RkeK8sServiceOption) (*RkeK8sServiceOption, error) + Update(existing *RkeK8sServiceOption, updates interface{}) (*RkeK8sServiceOption, error) + Replace(existing *RkeK8sServiceOption) (*RkeK8sServiceOption, error) + ByID(id string) (*RkeK8sServiceOption, error) + Delete(container *RkeK8sServiceOption) error +} + +func newRkeK8sServiceOptionClient(apiClient *Client) *RkeK8sServiceOptionClient { + return &RkeK8sServiceOptionClient{ + apiClient: apiClient, + } +} + +func (c *RkeK8sServiceOptionClient) Create(container *RkeK8sServiceOption) (*RkeK8sServiceOption, error) { + resp := &RkeK8sServiceOption{} + err := c.apiClient.Ops.DoCreate(RkeK8sServiceOptionType, container, resp) + return resp, err +} + +func (c *RkeK8sServiceOptionClient) Update(existing *RkeK8sServiceOption, updates interface{}) (*RkeK8sServiceOption, error) { + resp := &RkeK8sServiceOption{} + err := c.apiClient.Ops.DoUpdate(RkeK8sServiceOptionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *RkeK8sServiceOptionClient) Replace(obj *RkeK8sServiceOption) (*RkeK8sServiceOption, error) { + resp := &RkeK8sServiceOption{} + err := c.apiClient.Ops.DoReplace(RkeK8sServiceOptionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *RkeK8sServiceOptionClient) List(opts *types.ListOpts) (*RkeK8sServiceOptionCollection, error) { + resp := &RkeK8sServiceOptionCollection{} + err := c.apiClient.Ops.DoList(RkeK8sServiceOptionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *RkeK8sServiceOptionClient) ListAll(opts *types.ListOpts) (*RkeK8sServiceOptionCollection, error) { + resp := &RkeK8sServiceOptionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *RkeK8sServiceOptionCollection) Next() (*RkeK8sServiceOptionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &RkeK8sServiceOptionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *RkeK8sServiceOptionClient) ByID(id string) (*RkeK8sServiceOption, error) { + resp := &RkeK8sServiceOption{} + err := c.apiClient.Ops.DoByID(RkeK8sServiceOptionType, id, resp) + return resp, err +} + +func (c *RkeK8sServiceOptionClient) Delete(container *RkeK8sServiceOption) error { + return c.apiClient.Ops.DoResourceDelete(RkeK8sServiceOptionType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_system_image.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_system_image.go new file mode 100644 index 0000000..3fb0e15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_k8s_system_image.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + RkeK8sSystemImageType = "rkeK8sSystemImage" + RkeK8sSystemImageFieldAnnotations = "annotations" + RkeK8sSystemImageFieldCreated = "created" + RkeK8sSystemImageFieldCreatorID = "creatorId" + RkeK8sSystemImageFieldLabels = "labels" + RkeK8sSystemImageFieldName = "name" + RkeK8sSystemImageFieldOwnerReferences = "ownerReferences" + RkeK8sSystemImageFieldRemoved = "removed" + RkeK8sSystemImageFieldSystemImages = "systemImages" + RkeK8sSystemImageFieldUUID = "uuid" +) + +type RkeK8sSystemImage struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SystemImages *RKESystemImages `json:"systemImages,omitempty" yaml:"systemImages,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type RkeK8sSystemImageCollection struct { + types.Collection + Data []RkeK8sSystemImage `json:"data,omitempty"` + client *RkeK8sSystemImageClient +} + +type RkeK8sSystemImageClient struct { + apiClient *Client +} + +type RkeK8sSystemImageOperations interface { + List(opts *types.ListOpts) (*RkeK8sSystemImageCollection, error) + ListAll(opts *types.ListOpts) (*RkeK8sSystemImageCollection, error) + Create(opts *RkeK8sSystemImage) (*RkeK8sSystemImage, error) + Update(existing *RkeK8sSystemImage, updates interface{}) (*RkeK8sSystemImage, error) + Replace(existing *RkeK8sSystemImage) (*RkeK8sSystemImage, error) + ByID(id string) (*RkeK8sSystemImage, error) + Delete(container *RkeK8sSystemImage) error +} + +func newRkeK8sSystemImageClient(apiClient *Client) *RkeK8sSystemImageClient { + return &RkeK8sSystemImageClient{ + apiClient: apiClient, + } +} + +func (c *RkeK8sSystemImageClient) Create(container *RkeK8sSystemImage) (*RkeK8sSystemImage, error) { + resp := &RkeK8sSystemImage{} + err := c.apiClient.Ops.DoCreate(RkeK8sSystemImageType, container, resp) + return resp, err +} + +func (c *RkeK8sSystemImageClient) Update(existing *RkeK8sSystemImage, updates interface{}) (*RkeK8sSystemImage, error) { + resp := &RkeK8sSystemImage{} + err := c.apiClient.Ops.DoUpdate(RkeK8sSystemImageType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *RkeK8sSystemImageClient) Replace(obj *RkeK8sSystemImage) (*RkeK8sSystemImage, error) { + resp := &RkeK8sSystemImage{} + err := c.apiClient.Ops.DoReplace(RkeK8sSystemImageType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *RkeK8sSystemImageClient) List(opts *types.ListOpts) (*RkeK8sSystemImageCollection, error) { + resp := &RkeK8sSystemImageCollection{} + err := c.apiClient.Ops.DoList(RkeK8sSystemImageType, opts, resp) + resp.client = c + return resp, err +} + +func (c *RkeK8sSystemImageClient) ListAll(opts *types.ListOpts) (*RkeK8sSystemImageCollection, error) { + resp := &RkeK8sSystemImageCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *RkeK8sSystemImageCollection) Next() (*RkeK8sSystemImageCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &RkeK8sSystemImageCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *RkeK8sSystemImageClient) ByID(id string) (*RkeK8sSystemImage, error) { + resp := &RkeK8sSystemImage{} + err := c.apiClient.Ops.DoByID(RkeK8sSystemImageType, id, resp) + return resp, err +} + +func (c *RkeK8sSystemImageClient) Delete(container *RkeK8sSystemImage) error { + return c.apiClient.Ops.DoResourceDelete(RkeK8sSystemImageType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_system_images.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_system_images.go new file mode 100644 index 0000000..185a3f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_system_images.go @@ -0,0 +1,90 @@ +package client + +const ( + RKESystemImagesType = "rkeSystemImages" + RKESystemImagesFieldAciCniDeployContainer = "aciCniDeployContainer" + RKESystemImagesFieldAciControllerContainer = "aciControllerContainer" + RKESystemImagesFieldAciGbpServerContainer = "aciGbpServerContainer" + RKESystemImagesFieldAciHostContainer = "aciHostContainer" + RKESystemImagesFieldAciMcastContainer = "aciMcastContainer" + RKESystemImagesFieldAciOpenvSwitchContainer = "aciOvsContainer" + RKESystemImagesFieldAciOpflexContainer = "aciOpflexContainer" + RKESystemImagesFieldAciOpflexServerContainer = "aciOpflexServerContainer" + RKESystemImagesFieldAlpine = "alpine" + RKESystemImagesFieldCalicoCNI = "calicoCni" + RKESystemImagesFieldCalicoControllers = "calicoControllers" + RKESystemImagesFieldCalicoCtl = "calicoCtl" + RKESystemImagesFieldCalicoFlexVol = "calicoFlexVol" + RKESystemImagesFieldCalicoNode = "calicoNode" + RKESystemImagesFieldCanalCNI = "canalCni" + RKESystemImagesFieldCanalControllers = "canalControllers" + RKESystemImagesFieldCanalFlannel = "canalFlannel" + RKESystemImagesFieldCanalFlexVol = "canalFlexVol" + RKESystemImagesFieldCanalNode = "canalNode" + RKESystemImagesFieldCertDownloader = "certDownloader" + RKESystemImagesFieldCoreDNS = "coredns" + RKESystemImagesFieldCoreDNSAutoscaler = "corednsAutoscaler" + RKESystemImagesFieldDNSmasq = "dnsmasq" + RKESystemImagesFieldEtcd = "etcd" + RKESystemImagesFieldFlannel = "flannel" + RKESystemImagesFieldFlannelCNI = "flannelCni" + RKESystemImagesFieldIngress = "ingress" + RKESystemImagesFieldIngressBackend = "ingressBackend" + RKESystemImagesFieldIngressWebhook = "ingressWebhook" + RKESystemImagesFieldKubeDNS = "kubedns" + RKESystemImagesFieldKubeDNSAutoscaler = "kubednsAutoscaler" + RKESystemImagesFieldKubeDNSSidecar = "kubednsSidecar" + RKESystemImagesFieldKubernetes = "kubernetes" + RKESystemImagesFieldKubernetesServicesSidecar = "kubernetesServicesSidecar" + RKESystemImagesFieldMetricsServer = "metricsServer" + RKESystemImagesFieldNginxProxy = "nginxProxy" + RKESystemImagesFieldNodelocal = "nodelocal" + RKESystemImagesFieldPodInfraContainer = "podInfraContainer" + RKESystemImagesFieldWeaveCNI = "weaveCni" + RKESystemImagesFieldWeaveNode = "weaveNode" + RKESystemImagesFieldWindowsPodInfraContainer = "windowsPodInfraContainer" +) + +type RKESystemImages struct { + AciCniDeployContainer string `json:"aciCniDeployContainer,omitempty" yaml:"aciCniDeployContainer,omitempty"` + AciControllerContainer string `json:"aciControllerContainer,omitempty" yaml:"aciControllerContainer,omitempty"` + AciGbpServerContainer string `json:"aciGbpServerContainer,omitempty" yaml:"aciGbpServerContainer,omitempty"` + AciHostContainer string `json:"aciHostContainer,omitempty" yaml:"aciHostContainer,omitempty"` + AciMcastContainer string `json:"aciMcastContainer,omitempty" yaml:"aciMcastContainer,omitempty"` + AciOpenvSwitchContainer string `json:"aciOvsContainer,omitempty" yaml:"aciOvsContainer,omitempty"` + AciOpflexContainer string `json:"aciOpflexContainer,omitempty" yaml:"aciOpflexContainer,omitempty"` + AciOpflexServerContainer string `json:"aciOpflexServerContainer,omitempty" yaml:"aciOpflexServerContainer,omitempty"` + Alpine string `json:"alpine,omitempty" yaml:"alpine,omitempty"` + CalicoCNI string `json:"calicoCni,omitempty" yaml:"calicoCni,omitempty"` + CalicoControllers string `json:"calicoControllers,omitempty" yaml:"calicoControllers,omitempty"` + CalicoCtl string `json:"calicoCtl,omitempty" yaml:"calicoCtl,omitempty"` + CalicoFlexVol string `json:"calicoFlexVol,omitempty" yaml:"calicoFlexVol,omitempty"` + CalicoNode string `json:"calicoNode,omitempty" yaml:"calicoNode,omitempty"` + CanalCNI string `json:"canalCni,omitempty" yaml:"canalCni,omitempty"` + CanalControllers string `json:"canalControllers,omitempty" yaml:"canalControllers,omitempty"` + CanalFlannel string `json:"canalFlannel,omitempty" yaml:"canalFlannel,omitempty"` + CanalFlexVol string `json:"canalFlexVol,omitempty" yaml:"canalFlexVol,omitempty"` + CanalNode string `json:"canalNode,omitempty" yaml:"canalNode,omitempty"` + CertDownloader string `json:"certDownloader,omitempty" yaml:"certDownloader,omitempty"` + CoreDNS string `json:"coredns,omitempty" yaml:"coredns,omitempty"` + CoreDNSAutoscaler string `json:"corednsAutoscaler,omitempty" yaml:"corednsAutoscaler,omitempty"` + DNSmasq string `json:"dnsmasq,omitempty" yaml:"dnsmasq,omitempty"` + Etcd string `json:"etcd,omitempty" yaml:"etcd,omitempty"` + Flannel string `json:"flannel,omitempty" yaml:"flannel,omitempty"` + FlannelCNI string `json:"flannelCni,omitempty" yaml:"flannelCni,omitempty"` + Ingress string `json:"ingress,omitempty" yaml:"ingress,omitempty"` + IngressBackend string `json:"ingressBackend,omitempty" yaml:"ingressBackend,omitempty"` + IngressWebhook string `json:"ingressWebhook,omitempty" yaml:"ingressWebhook,omitempty"` + KubeDNS string `json:"kubedns,omitempty" yaml:"kubedns,omitempty"` + KubeDNSAutoscaler string `json:"kubednsAutoscaler,omitempty" yaml:"kubednsAutoscaler,omitempty"` + KubeDNSSidecar string `json:"kubednsSidecar,omitempty" yaml:"kubednsSidecar,omitempty"` + Kubernetes string `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty"` + KubernetesServicesSidecar string `json:"kubernetesServicesSidecar,omitempty" yaml:"kubernetesServicesSidecar,omitempty"` + MetricsServer string `json:"metricsServer,omitempty" yaml:"metricsServer,omitempty"` + NginxProxy string `json:"nginxProxy,omitempty" yaml:"nginxProxy,omitempty"` + Nodelocal string `json:"nodelocal,omitempty" yaml:"nodelocal,omitempty"` + PodInfraContainer string `json:"podInfraContainer,omitempty" yaml:"podInfraContainer,omitempty"` + WeaveCNI string `json:"weaveCni,omitempty" yaml:"weaveCni,omitempty"` + WeaveNode string `json:"weaveNode,omitempty" yaml:"weaveNode,omitempty"` + WindowsPodInfraContainer string `json:"windowsPodInfraContainer,omitempty" yaml:"windowsPodInfraContainer,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_taint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_taint.go new file mode 100644 index 0000000..8cd196f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rke_taint.go @@ -0,0 +1,16 @@ +package client + +const ( + RKETaintType = "rkeTaint" + RKETaintFieldEffect = "effect" + RKETaintFieldKey = "key" + RKETaintFieldTimeAdded = "timeAdded" + RKETaintFieldValue = "value" +) + +type RKETaint struct { + Effect string `json:"effect,omitempty" yaml:"effect,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + TimeAdded string `json:"timeAdded,omitempty" yaml:"timeAdded,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_role_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_role_template.go new file mode 100644 index 0000000..ed74608 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_role_template.go @@ -0,0 +1,142 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + RoleTemplateType = "roleTemplate" + RoleTemplateFieldAdministrative = "administrative" + RoleTemplateFieldAnnotations = "annotations" + RoleTemplateFieldBuiltin = "builtin" + RoleTemplateFieldClusterCreatorDefault = "clusterCreatorDefault" + RoleTemplateFieldContext = "context" + RoleTemplateFieldCreated = "created" + RoleTemplateFieldCreatorID = "creatorId" + RoleTemplateFieldDescription = "description" + RoleTemplateFieldExternal = "external" + RoleTemplateFieldExternalRules = "externalRules" + RoleTemplateFieldHidden = "hidden" + RoleTemplateFieldLabels = "labels" + RoleTemplateFieldLocked = "locked" + RoleTemplateFieldName = "name" + RoleTemplateFieldOwnerReferences = "ownerReferences" + RoleTemplateFieldProjectCreatorDefault = "projectCreatorDefault" + RoleTemplateFieldRemoved = "removed" + RoleTemplateFieldRoleTemplateIDs = "roleTemplateIds" + RoleTemplateFieldRules = "rules" + RoleTemplateFieldUUID = "uuid" +) + +type RoleTemplate struct { + types.Resource + Administrative bool `json:"administrative,omitempty" yaml:"administrative,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Builtin bool `json:"builtin,omitempty" yaml:"builtin,omitempty"` + ClusterCreatorDefault bool `json:"clusterCreatorDefault,omitempty" yaml:"clusterCreatorDefault,omitempty"` + Context string `json:"context,omitempty" yaml:"context,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + External bool `json:"external,omitempty" yaml:"external,omitempty"` + ExternalRules []PolicyRule `json:"externalRules,omitempty" yaml:"externalRules,omitempty"` + Hidden bool `json:"hidden,omitempty" yaml:"hidden,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Locked bool `json:"locked,omitempty" yaml:"locked,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectCreatorDefault bool `json:"projectCreatorDefault,omitempty" yaml:"projectCreatorDefault,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RoleTemplateIDs []string `json:"roleTemplateIds,omitempty" yaml:"roleTemplateIds,omitempty"` + Rules []PolicyRule `json:"rules,omitempty" yaml:"rules,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type RoleTemplateCollection struct { + types.Collection + Data []RoleTemplate `json:"data,omitempty"` + client *RoleTemplateClient +} + +type RoleTemplateClient struct { + apiClient *Client +} + +type RoleTemplateOperations interface { + List(opts *types.ListOpts) (*RoleTemplateCollection, error) + ListAll(opts *types.ListOpts) (*RoleTemplateCollection, error) + Create(opts *RoleTemplate) (*RoleTemplate, error) + Update(existing *RoleTemplate, updates interface{}) (*RoleTemplate, error) + Replace(existing *RoleTemplate) (*RoleTemplate, error) + ByID(id string) (*RoleTemplate, error) + Delete(container *RoleTemplate) error +} + +func newRoleTemplateClient(apiClient *Client) *RoleTemplateClient { + return &RoleTemplateClient{ + apiClient: apiClient, + } +} + +func (c *RoleTemplateClient) Create(container *RoleTemplate) (*RoleTemplate, error) { + resp := &RoleTemplate{} + err := c.apiClient.Ops.DoCreate(RoleTemplateType, container, resp) + return resp, err +} + +func (c *RoleTemplateClient) Update(existing *RoleTemplate, updates interface{}) (*RoleTemplate, error) { + resp := &RoleTemplate{} + err := c.apiClient.Ops.DoUpdate(RoleTemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *RoleTemplateClient) Replace(obj *RoleTemplate) (*RoleTemplate, error) { + resp := &RoleTemplate{} + err := c.apiClient.Ops.DoReplace(RoleTemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *RoleTemplateClient) List(opts *types.ListOpts) (*RoleTemplateCollection, error) { + resp := &RoleTemplateCollection{} + err := c.apiClient.Ops.DoList(RoleTemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *RoleTemplateClient) ListAll(opts *types.ListOpts) (*RoleTemplateCollection, error) { + resp := &RoleTemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *RoleTemplateCollection) Next() (*RoleTemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &RoleTemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *RoleTemplateClient) ByID(id string) (*RoleTemplate, error) { + resp := &RoleTemplate{} + err := c.apiClient.Ops.DoByID(RoleTemplateType, id, resp) + return resp, err +} + +func (c *RoleTemplateClient) Delete(container *RoleTemplate) error { + return c.apiClient.Ops.DoResourceDelete(RoleTemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update.go new file mode 100644 index 0000000..180f638 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update.go @@ -0,0 +1,12 @@ +package client + +const ( + RollingUpdateType = "rollingUpdate" + RollingUpdateFieldBatchSize = "batchSize" + RollingUpdateFieldInterval = "interval" +) + +type RollingUpdate struct { + BatchSize int64 `json:"batchSize,omitempty" yaml:"batchSize,omitempty"` + Interval int64 `json:"interval,omitempty" yaml:"interval,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_daemon_set.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_daemon_set.go new file mode 100644 index 0000000..f6c2e12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_daemon_set.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + RollingUpdateDaemonSetType = "rollingUpdateDaemonSet" + RollingUpdateDaemonSetFieldMaxSurge = "maxSurge" + RollingUpdateDaemonSetFieldMaxUnavailable = "maxUnavailable" +) + +type RollingUpdateDaemonSet struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_deployment.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_deployment.go new file mode 100644 index 0000000..535fb36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rolling_update_deployment.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + RollingUpdateDeploymentType = "rollingUpdateDeployment" + RollingUpdateDeploymentFieldMaxSurge = "maxSurge" + RollingUpdateDeploymentFieldMaxUnavailable = "maxUnavailable" +) + +type RollingUpdateDeployment struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_input.go new file mode 100644 index 0000000..e827476 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_input.go @@ -0,0 +1,12 @@ +package client + +const ( + RotateCertificateInputType = "rotateCertificateInput" + RotateCertificateInputFieldCACertificates = "caCertificates" + RotateCertificateInputFieldServices = "services" +) + +type RotateCertificateInput struct { + CACertificates bool `json:"caCertificates,omitempty" yaml:"caCertificates,omitempty"` + Services string `json:"services,omitempty" yaml:"services,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_output.go new file mode 100644 index 0000000..47c50ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificate_output.go @@ -0,0 +1,10 @@ +package client + +const ( + RotateCertificateOutputType = "rotateCertificateOutput" + RotateCertificateOutputFieldMessage = "message" +) + +type RotateCertificateOutput struct { + Message string `json:"message,omitempty" yaml:"message,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificates.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificates.go new file mode 100644 index 0000000..219450f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_certificates.go @@ -0,0 +1,12 @@ +package client + +const ( + RotateCertificatesType = "rotateCertificates" + RotateCertificatesFieldCACertificates = "caCertificates" + RotateCertificatesFieldServices = "services" +) + +type RotateCertificates struct { + CACertificates bool `json:"caCertificates,omitempty" yaml:"caCertificates,omitempty"` + Services string `json:"services,omitempty" yaml:"services,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_encryption_key_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_encryption_key_output.go new file mode 100644 index 0000000..23360d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_rotate_encryption_key_output.go @@ -0,0 +1,10 @@ +package client + +const ( + RotateEncryptionKeyOutputType = "rotateEncryptionKeyOutput" + RotateEncryptionKeyOutputFieldMessage = "message" +) + +type RotateEncryptionKeyOutput struct { + Message string `json:"message,omitempty" yaml:"message,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route53provider_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route53provider_config.go new file mode 100644 index 0000000..0932c3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route53provider_config.go @@ -0,0 +1,22 @@ +package client + +const ( + Route53ProviderConfigType = "route53ProviderConfig" + Route53ProviderConfigFieldAccessKey = "accessKey" + Route53ProviderConfigFieldAdditionalOptions = "additionalOptions" + Route53ProviderConfigFieldCredentialsPath = "credentialsPath" + Route53ProviderConfigFieldRegion = "region" + Route53ProviderConfigFieldRoleArn = "roleArn" + Route53ProviderConfigFieldSecretKey = "secretKey" + Route53ProviderConfigFieldZoneType = "zoneType" +) + +type Route53ProviderConfig struct { + AccessKey string `json:"accessKey,omitempty" yaml:"accessKey,omitempty"` + AdditionalOptions map[string]string `json:"additionalOptions,omitempty" yaml:"additionalOptions,omitempty"` + CredentialsPath string `json:"credentialsPath,omitempty" yaml:"credentialsPath,omitempty"` + Region string `json:"region,omitempty" yaml:"region,omitempty"` + RoleArn string `json:"roleArn,omitempty" yaml:"roleArn,omitempty"` + SecretKey string `json:"secretKey,omitempty" yaml:"secretKey,omitempty"` + ZoneType string `json:"zoneType,omitempty" yaml:"zoneType,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route_openstack_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route_openstack_opts.go new file mode 100644 index 0000000..ad6f988 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_route_openstack_opts.go @@ -0,0 +1,10 @@ +package client + +const ( + RouteOpenstackOptsType = "routeOpenstackOpts" + RouteOpenstackOptsFieldRouterID = "router-id" +) + +type RouteOpenstackOpts struct { + RouterID string `json:"router-id,omitempty" yaml:"router-id,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3backup_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3backup_config.go new file mode 100644 index 0000000..14ea587 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3backup_config.go @@ -0,0 +1,22 @@ +package client + +const ( + S3BackupConfigType = "s3BackupConfig" + S3BackupConfigFieldAccessKey = "accessKey" + S3BackupConfigFieldBucketName = "bucketName" + S3BackupConfigFieldCustomCA = "customCa" + S3BackupConfigFieldEndpoint = "endpoint" + S3BackupConfigFieldFolder = "folder" + S3BackupConfigFieldRegion = "region" + S3BackupConfigFieldSecretKey = "secretKey" +) + +type S3BackupConfig struct { + AccessKey string `json:"accessKey,omitempty" yaml:"accessKey,omitempty"` + BucketName string `json:"bucketName,omitempty" yaml:"bucketName,omitempty"` + CustomCA string `json:"customCa,omitempty" yaml:"customCa,omitempty"` + Endpoint string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Folder string `json:"folder,omitempty" yaml:"folder,omitempty"` + Region string `json:"region,omitempty" yaml:"region,omitempty"` + SecretKey string `json:"secretKey,omitempty" yaml:"secretKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3credential_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3credential_config.go new file mode 100644 index 0000000..f351e8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_s3credential_config.go @@ -0,0 +1,24 @@ +package client + +const ( + S3CredentialConfigType = "s3CredentialConfig" + S3CredentialConfigFieldAccessKey = "accessKey" + S3CredentialConfigFieldDefaultBucket = "defaultBucket" + S3CredentialConfigFieldDefaultEndpoint = "defaultEndpoint" + S3CredentialConfigFieldDefaultEndpointCA = "defaultEndpointCA" + S3CredentialConfigFieldDefaultFolder = "defaultFolder" + S3CredentialConfigFieldDefaultRegion = "defaultRegion" + S3CredentialConfigFieldDefaultSkipSSLVerify = "defaultSkipSSLVerify" + S3CredentialConfigFieldSecretKey = "secretKey" +) + +type S3CredentialConfig struct { + AccessKey string `json:"accessKey,omitempty" yaml:"accessKey,omitempty"` + DefaultBucket string `json:"defaultBucket,omitempty" yaml:"defaultBucket,omitempty"` + DefaultEndpoint string `json:"defaultEndpoint,omitempty" yaml:"defaultEndpoint,omitempty"` + DefaultEndpointCA string `json:"defaultEndpointCA,omitempty" yaml:"defaultEndpointCA,omitempty"` + DefaultFolder string `json:"defaultFolder,omitempty" yaml:"defaultFolder,omitempty"` + DefaultRegion string `json:"defaultRegion,omitempty" yaml:"defaultRegion,omitempty"` + DefaultSkipSSLVerify string `json:"defaultSkipSSLVerify,omitempty" yaml:"defaultSkipSSLVerify,omitempty"` + SecretKey string `json:"secretKey,omitempty" yaml:"secretKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_input.go new file mode 100644 index 0000000..a7d31f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_input.go @@ -0,0 +1,10 @@ +package client + +const ( + SamlConfigTestInputType = "samlConfigTestInput" + SamlConfigTestInputFieldFinalRedirectURL = "finalRedirectUrl" +) + +type SamlConfigTestInput struct { + FinalRedirectURL string `json:"finalRedirectUrl,omitempty" yaml:"finalRedirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_output.go new file mode 100644 index 0000000..e9e5b95 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_config_test_output.go @@ -0,0 +1,10 @@ +package client + +const ( + SamlConfigTestOutputType = "samlConfigTestOutput" + SamlConfigTestOutputFieldIdpRedirectURL = "idpRedirectUrl" +) + +type SamlConfigTestOutput struct { + IdpRedirectURL string `json:"idpRedirectUrl,omitempty" yaml:"idpRedirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_token.go new file mode 100644 index 0000000..91f0fb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_saml_token.go @@ -0,0 +1,124 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + SamlTokenType = "samlToken" + SamlTokenFieldAnnotations = "annotations" + SamlTokenFieldCreated = "created" + SamlTokenFieldCreatorID = "creatorId" + SamlTokenFieldExpiresAt = "expiresAt" + SamlTokenFieldLabels = "labels" + SamlTokenFieldName = "name" + SamlTokenFieldNamespaceId = "namespaceId" + SamlTokenFieldOwnerReferences = "ownerReferences" + SamlTokenFieldRemoved = "removed" + SamlTokenFieldToken = "token" + SamlTokenFieldUUID = "uuid" +) + +type SamlToken struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type SamlTokenCollection struct { + types.Collection + Data []SamlToken `json:"data,omitempty"` + client *SamlTokenClient +} + +type SamlTokenClient struct { + apiClient *Client +} + +type SamlTokenOperations interface { + List(opts *types.ListOpts) (*SamlTokenCollection, error) + ListAll(opts *types.ListOpts) (*SamlTokenCollection, error) + Create(opts *SamlToken) (*SamlToken, error) + Update(existing *SamlToken, updates interface{}) (*SamlToken, error) + Replace(existing *SamlToken) (*SamlToken, error) + ByID(id string) (*SamlToken, error) + Delete(container *SamlToken) error +} + +func newSamlTokenClient(apiClient *Client) *SamlTokenClient { + return &SamlTokenClient{ + apiClient: apiClient, + } +} + +func (c *SamlTokenClient) Create(container *SamlToken) (*SamlToken, error) { + resp := &SamlToken{} + err := c.apiClient.Ops.DoCreate(SamlTokenType, container, resp) + return resp, err +} + +func (c *SamlTokenClient) Update(existing *SamlToken, updates interface{}) (*SamlToken, error) { + resp := &SamlToken{} + err := c.apiClient.Ops.DoUpdate(SamlTokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *SamlTokenClient) Replace(obj *SamlToken) (*SamlToken, error) { + resp := &SamlToken{} + err := c.apiClient.Ops.DoReplace(SamlTokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *SamlTokenClient) List(opts *types.ListOpts) (*SamlTokenCollection, error) { + resp := &SamlTokenCollection{} + err := c.apiClient.Ops.DoList(SamlTokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *SamlTokenClient) ListAll(opts *types.ListOpts) (*SamlTokenCollection, error) { + resp := &SamlTokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *SamlTokenCollection) Next() (*SamlTokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &SamlTokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *SamlTokenClient) ByID(id string) (*SamlToken, error) { + resp := &SamlToken{} + err := c.apiClient.Ops.DoByID(SamlTokenType, id, resp) + return resp, err +} + +func (c *SamlTokenClient) Delete(container *SamlToken) error { + return c.apiClient.Ops.DoResourceDelete(SamlTokenType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_input.go new file mode 100644 index 0000000..b756e4f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_input.go @@ -0,0 +1,12 @@ +package client + +const ( + SaveAsTemplateInputType = "saveAsTemplateInput" + SaveAsTemplateInputFieldClusterTemplateName = "clusterTemplateName" + SaveAsTemplateInputFieldClusterTemplateRevisionName = "clusterTemplateRevisionName" +) + +type SaveAsTemplateInput struct { + ClusterTemplateName string `json:"clusterTemplateName,omitempty" yaml:"clusterTemplateName,omitempty"` + ClusterTemplateRevisionName string `json:"clusterTemplateRevisionName,omitempty" yaml:"clusterTemplateRevisionName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_output.go new file mode 100644 index 0000000..e509010 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_save_as_template_output.go @@ -0,0 +1,12 @@ +package client + +const ( + SaveAsTemplateOutputType = "saveAsTemplateOutput" + SaveAsTemplateOutputFieldClusterTemplateName = "clusterTemplateName" + SaveAsTemplateOutputFieldClusterTemplateRevisionName = "clusterTemplateRevisionName" +) + +type SaveAsTemplateOutput struct { + ClusterTemplateName string `json:"clusterTemplateName,omitempty" yaml:"clusterTemplateName,omitempty"` + ClusterTemplateRevisionName string `json:"clusterTemplateRevisionName,omitempty" yaml:"clusterTemplateRevisionName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scale_iovolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scale_iovolume_source.go new file mode 100644 index 0000000..58e0009 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scale_iovolume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + ScaleIOVolumeSourceType = "scaleIOVolumeSource" + ScaleIOVolumeSourceFieldFSType = "fsType" + ScaleIOVolumeSourceFieldGateway = "gateway" + ScaleIOVolumeSourceFieldProtectionDomain = "protectionDomain" + ScaleIOVolumeSourceFieldReadOnly = "readOnly" + ScaleIOVolumeSourceFieldSSLEnabled = "sslEnabled" + ScaleIOVolumeSourceFieldSecretRef = "secretRef" + ScaleIOVolumeSourceFieldStorageMode = "storageMode" + ScaleIOVolumeSourceFieldStoragePool = "storagePool" + ScaleIOVolumeSourceFieldSystem = "system" + ScaleIOVolumeSourceFieldVolumeName = "volumeName" +) + +type ScaleIOVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Gateway string `json:"gateway,omitempty" yaml:"gateway,omitempty"` + ProtectionDomain string `json:"protectionDomain,omitempty" yaml:"protectionDomain,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SSLEnabled bool `json:"sslEnabled,omitempty" yaml:"sslEnabled,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + StorageMode string `json:"storageMode,omitempty" yaml:"storageMode,omitempty"` + StoragePool string `json:"storagePool,omitempty" yaml:"storagePool,omitempty"` + System string `json:"system,omitempty" yaml:"system,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scheduler_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scheduler_service.go new file mode 100644 index 0000000..1af88de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_scheduler_service.go @@ -0,0 +1,26 @@ +package client + +const ( + SchedulerServiceType = "schedulerService" + SchedulerServiceFieldExtraArgs = "extraArgs" + SchedulerServiceFieldExtraArgsArray = "extraArgsArray" + SchedulerServiceFieldExtraBinds = "extraBinds" + SchedulerServiceFieldExtraEnv = "extraEnv" + SchedulerServiceFieldImage = "image" + SchedulerServiceFieldWindowsExtraArgs = "winExtraArgs" + SchedulerServiceFieldWindowsExtraArgsArray = "winExtraArgsArray" + SchedulerServiceFieldWindowsExtraBinds = "winExtraBinds" + SchedulerServiceFieldWindowsExtraEnv = "winExtraEnv" +) + +type SchedulerService struct { + ExtraArgs map[string]string `json:"extraArgs,omitempty" yaml:"extraArgs,omitempty"` + ExtraArgsArray map[string][]string `json:"extraArgsArray,omitempty" yaml:"extraArgsArray,omitempty"` + ExtraBinds []string `json:"extraBinds,omitempty" yaml:"extraBinds,omitempty"` + ExtraEnv []string `json:"extraEnv,omitempty" yaml:"extraEnv,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + WindowsExtraArgs map[string]string `json:"winExtraArgs,omitempty" yaml:"winExtraArgs,omitempty"` + WindowsExtraArgsArray map[string][]string `json:"winExtraArgsArray,omitempty" yaml:"winExtraArgsArray,omitempty"` + WindowsExtraBinds []string `json:"winExtraBinds,omitempty" yaml:"winExtraBinds,omitempty"` + WindowsExtraEnv []string `json:"winExtraEnv,omitempty" yaml:"winExtraEnv,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_search_principals_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_search_principals_input.go new file mode 100644 index 0000000..c486b4c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_search_principals_input.go @@ -0,0 +1,12 @@ +package client + +const ( + SearchPrincipalsInputType = "searchPrincipalsInput" + SearchPrincipalsInputFieldName = "name" + SearchPrincipalsInputFieldPrincipalType = "principalType" +) + +type SearchPrincipalsInput struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + PrincipalType string `json:"principalType,omitempty" yaml:"principalType,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_key_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_key_selector.go new file mode 100644 index 0000000..9a23641 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_key_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + SecretKeySelectorType = "secretKeySelector" + SecretKeySelectorFieldKey = "key" + SecretKeySelectorFieldName = "name" + SecretKeySelectorFieldOptional = "optional" +) + +type SecretKeySelector struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_projection.go new file mode 100644 index 0000000..684b025 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + SecretProjectionType = "secretProjection" + SecretProjectionFieldItems = "items" + SecretProjectionFieldName = "name" + SecretProjectionFieldOptional = "optional" +) + +type SecretProjection struct { + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_volume_source.go new file mode 100644 index 0000000..bdb5109 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secret_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + SecretVolumeSourceType = "secretVolumeSource" + SecretVolumeSourceFieldDefaultMode = "defaultMode" + SecretVolumeSourceFieldItems = "items" + SecretVolumeSourceFieldOptional = "optional" + SecretVolumeSourceFieldSecretName = "secretName" +) + +type SecretVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secretbox_configuration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secretbox_configuration.go new file mode 100644 index 0000000..c913985 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secretbox_configuration.go @@ -0,0 +1,10 @@ +package client + +const ( + SecretboxConfigurationType = "secretboxConfiguration" + SecretboxConfigurationFieldKeys = "keys" +) + +type SecretboxConfiguration struct { + Keys []Key `json:"keys,omitempty" yaml:"keys,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secrets_encryption_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secrets_encryption_config.go new file mode 100644 index 0000000..658ff6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_secrets_encryption_config.go @@ -0,0 +1,12 @@ +package client + +const ( + SecretsEncryptionConfigType = "secretsEncryptionConfig" + SecretsEncryptionConfigFieldCustomConfig = "customConfig" + SecretsEncryptionConfigFieldEnabled = "enabled" +) + +type SecretsEncryptionConfig struct { + CustomConfig *EncryptionConfiguration `json:"customConfig,omitempty" yaml:"customConfig,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_account_token_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_account_token_projection.go new file mode 100644 index 0000000..7d2e880 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_account_token_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + ServiceAccountTokenProjectionType = "serviceAccountTokenProjection" + ServiceAccountTokenProjectionFieldAudience = "audience" + ServiceAccountTokenProjectionFieldExpirationSeconds = "expirationSeconds" + ServiceAccountTokenProjectionFieldPath = "path" +) + +type ServiceAccountTokenProjection struct { + Audience string `json:"audience,omitempty" yaml:"audience,omitempty"` + ExpirationSeconds *int64 `json:"expirationSeconds,omitempty" yaml:"expirationSeconds,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_override.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_override.go new file mode 100644 index 0000000..96ed63c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_service_override.go @@ -0,0 +1,20 @@ +package client + +const ( + ServiceOverrideType = "serviceOverride" + ServiceOverrideFieldRegion = "region" + ServiceOverrideFieldService = "service" + ServiceOverrideFieldSigningMethod = "signing-method" + ServiceOverrideFieldSigningName = "signing-name" + ServiceOverrideFieldSigningRegion = "signing-region" + ServiceOverrideFieldURL = "url" +) + +type ServiceOverride struct { + Region string `json:"region,omitempty" yaml:"region,omitempty"` + Service string `json:"service,omitempty" yaml:"service,omitempty"` + SigningMethod string `json:"signing-method,omitempty" yaml:"signing-method,omitempty"` + SigningName string `json:"signing-name,omitempty" yaml:"signing-name,omitempty"` + SigningRegion string `json:"signing-region,omitempty" yaml:"signing-region,omitempty"` + URL string `json:"url,omitempty" yaml:"url,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_set_password_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_set_password_input.go new file mode 100644 index 0000000..4dc32d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_set_password_input.go @@ -0,0 +1,10 @@ +package client + +const ( + SetPasswordInputType = "setPasswordInput" + SetPasswordInputFieldNewPassword = "newPassword" +) + +type SetPasswordInput struct { + NewPassword string `json:"newPassword,omitempty" yaml:"newPassword,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_setting.go new file mode 100644 index 0000000..6ea352b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_setting.go @@ -0,0 +1,126 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + SettingType = "setting" + SettingFieldAnnotations = "annotations" + SettingFieldCreated = "created" + SettingFieldCreatorID = "creatorId" + SettingFieldCustomized = "customized" + SettingFieldDefault = "default" + SettingFieldLabels = "labels" + SettingFieldName = "name" + SettingFieldOwnerReferences = "ownerReferences" + SettingFieldRemoved = "removed" + SettingFieldSource = "source" + SettingFieldUUID = "uuid" + SettingFieldValue = "value" +) + +type Setting struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Customized bool `json:"customized,omitempty" yaml:"customized,omitempty"` + Default string `json:"default,omitempty" yaml:"default,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Source string `json:"source,omitempty" yaml:"source,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} + +type SettingCollection struct { + types.Collection + Data []Setting `json:"data,omitempty"` + client *SettingClient +} + +type SettingClient struct { + apiClient *Client +} + +type SettingOperations interface { + List(opts *types.ListOpts) (*SettingCollection, error) + ListAll(opts *types.ListOpts) (*SettingCollection, error) + Create(opts *Setting) (*Setting, error) + Update(existing *Setting, updates interface{}) (*Setting, error) + Replace(existing *Setting) (*Setting, error) + ByID(id string) (*Setting, error) + Delete(container *Setting) error +} + +func newSettingClient(apiClient *Client) *SettingClient { + return &SettingClient{ + apiClient: apiClient, + } +} + +func (c *SettingClient) Create(container *Setting) (*Setting, error) { + resp := &Setting{} + err := c.apiClient.Ops.DoCreate(SettingType, container, resp) + return resp, err +} + +func (c *SettingClient) Update(existing *Setting, updates interface{}) (*Setting, error) { + resp := &Setting{} + err := c.apiClient.Ops.DoUpdate(SettingType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *SettingClient) Replace(obj *Setting) (*Setting, error) { + resp := &Setting{} + err := c.apiClient.Ops.DoReplace(SettingType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *SettingClient) List(opts *types.ListOpts) (*SettingCollection, error) { + resp := &SettingCollection{} + err := c.apiClient.Ops.DoList(SettingType, opts, resp) + resp.client = c + return resp, err +} + +func (c *SettingClient) ListAll(opts *types.ListOpts) (*SettingCollection, error) { + resp := &SettingCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *SettingCollection) Next() (*SettingCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &SettingCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *SettingClient) ByID(id string) (*Setting, error) { + resp := &Setting{} + err := c.apiClient.Ops.DoByID(SettingType, id, resp) + return resp, err +} + +func (c *SettingClient) Delete(container *Setting) error { + return c.apiClient.Ops.DoResourceDelete(SettingType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_shibboleth_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_shibboleth_config.go new file mode 100644 index 0000000..8ab4b89 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_shibboleth_config.go @@ -0,0 +1,54 @@ +package client + +const ( + ShibbolethConfigType = "shibbolethConfig" + ShibbolethConfigFieldAccessMode = "accessMode" + ShibbolethConfigFieldAllowedPrincipalIDs = "allowedPrincipalIds" + ShibbolethConfigFieldAnnotations = "annotations" + ShibbolethConfigFieldCreated = "created" + ShibbolethConfigFieldCreatorID = "creatorId" + ShibbolethConfigFieldDisplayNameField = "displayNameField" + ShibbolethConfigFieldEnabled = "enabled" + ShibbolethConfigFieldEntityID = "entityID" + ShibbolethConfigFieldGroupsField = "groupsField" + ShibbolethConfigFieldIDPMetadataContent = "idpMetadataContent" + ShibbolethConfigFieldLabels = "labels" + ShibbolethConfigFieldName = "name" + ShibbolethConfigFieldOpenLdapConfig = "openLdapConfig" + ShibbolethConfigFieldOwnerReferences = "ownerReferences" + ShibbolethConfigFieldRancherAPIHost = "rancherApiHost" + ShibbolethConfigFieldRemoved = "removed" + ShibbolethConfigFieldSpCert = "spCert" + ShibbolethConfigFieldSpKey = "spKey" + ShibbolethConfigFieldStatus = "status" + ShibbolethConfigFieldType = "type" + ShibbolethConfigFieldUIDField = "uidField" + ShibbolethConfigFieldUUID = "uuid" + ShibbolethConfigFieldUserNameField = "userNameField" +) + +type ShibbolethConfig struct { + AccessMode string `json:"accessMode,omitempty" yaml:"accessMode,omitempty"` + AllowedPrincipalIDs []string `json:"allowedPrincipalIds,omitempty" yaml:"allowedPrincipalIds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DisplayNameField string `json:"displayNameField,omitempty" yaml:"displayNameField,omitempty"` + Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + EntityID string `json:"entityID,omitempty" yaml:"entityID,omitempty"` + GroupsField string `json:"groupsField,omitempty" yaml:"groupsField,omitempty"` + IDPMetadataContent string `json:"idpMetadataContent,omitempty" yaml:"idpMetadataContent,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OpenLdapConfig *LdapFields `json:"openLdapConfig,omitempty" yaml:"openLdapConfig,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RancherAPIHost string `json:"rancherApiHost,omitempty" yaml:"rancherApiHost,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SpCert string `json:"spCert,omitempty" yaml:"spCert,omitempty"` + SpKey string `json:"spKey,omitempty" yaml:"spKey,omitempty"` + Status *AuthConfigStatus `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UIDField string `json:"uidField,omitempty" yaml:"uidField,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserNameField string `json:"userNameField,omitempty" yaml:"userNameField,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_storage_osvolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_storage_osvolume_source.go new file mode 100644 index 0000000..46dc40f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_storage_osvolume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + StorageOSVolumeSourceType = "storageOSVolumeSource" + StorageOSVolumeSourceFieldFSType = "fsType" + StorageOSVolumeSourceFieldReadOnly = "readOnly" + StorageOSVolumeSourceFieldSecretRef = "secretRef" + StorageOSVolumeSourceFieldVolumeName = "volumeName" + StorageOSVolumeSourceFieldVolumeNamespace = "volumeNamespace" +) + +type StorageOSVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` + VolumeNamespace string `json:"volumeNamespace,omitempty" yaml:"volumeNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_sub_question.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_sub_question.go new file mode 100644 index 0000000..f0a47e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_sub_question.go @@ -0,0 +1,40 @@ +package client + +const ( + SubQuestionType = "subQuestion" + SubQuestionFieldDefault = "default" + SubQuestionFieldDescription = "description" + SubQuestionFieldGroup = "group" + SubQuestionFieldInvalidChars = "invalidChars" + SubQuestionFieldLabel = "label" + SubQuestionFieldMax = "max" + SubQuestionFieldMaxLength = "maxLength" + SubQuestionFieldMin = "min" + SubQuestionFieldMinLength = "minLength" + SubQuestionFieldOptions = "options" + SubQuestionFieldRequired = "required" + SubQuestionFieldSatisfies = "satisfies" + SubQuestionFieldShowIf = "showIf" + SubQuestionFieldType = "type" + SubQuestionFieldValidChars = "validChars" + SubQuestionFieldVariable = "variable" +) + +type SubQuestion struct { + Default string `json:"default,omitempty" yaml:"default,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Group string `json:"group,omitempty" yaml:"group,omitempty"` + InvalidChars string `json:"invalidChars,omitempty" yaml:"invalidChars,omitempty"` + Label string `json:"label,omitempty" yaml:"label,omitempty"` + Max int64 `json:"max,omitempty" yaml:"max,omitempty"` + MaxLength int64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"` + Min int64 `json:"min,omitempty" yaml:"min,omitempty"` + MinLength int64 `json:"minLength,omitempty" yaml:"minLength,omitempty"` + Options []string `json:"options,omitempty" yaml:"options,omitempty"` + Required bool `json:"required,omitempty" yaml:"required,omitempty"` + Satisfies string `json:"satisfies,omitempty" yaml:"satisfies,omitempty"` + ShowIf string `json:"showIf,omitempty" yaml:"showIf,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + ValidChars string `json:"validChars,omitempty" yaml:"validChars,omitempty"` + Variable string `json:"variable,omitempty" yaml:"variable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_taint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_taint.go new file mode 100644 index 0000000..cec2b5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_taint.go @@ -0,0 +1,16 @@ +package client + +const ( + TaintType = "taint" + TaintFieldEffect = "effect" + TaintFieldKey = "key" + TaintFieldTimeAdded = "timeAdded" + TaintFieldValue = "value" +) + +type Taint struct { + Effect string `json:"effect,omitempty" yaml:"effect,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + TimeAdded string `json:"timeAdded,omitempty" yaml:"timeAdded,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_target.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_target.go new file mode 100644 index 0000000..cd8d728 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_target.go @@ -0,0 +1,16 @@ +package client + +const ( + TargetType = "target" + TargetFieldAppID = "appId" + TargetFieldHealthstate = "healthState" + TargetFieldProjectID = "projectId" + TargetFieldState = "state" +) + +type Target struct { + AppID string `json:"appId,omitempty" yaml:"appId,omitempty"` + Healthstate string `json:"healthState,omitempty" yaml:"healthState,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template.go new file mode 100644 index 0000000..9b15563 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template.go @@ -0,0 +1,166 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + TemplateType = "template" + TemplateFieldAnnotations = "annotations" + TemplateFieldCatalogID = "catalogId" + TemplateFieldCategories = "categories" + TemplateFieldCategory = "category" + TemplateFieldClusterCatalogID = "clusterCatalogId" + TemplateFieldClusterID = "clusterId" + TemplateFieldCreated = "created" + TemplateFieldCreatorID = "creatorId" + TemplateFieldDefaultTemplateVersionID = "defaultTemplateVersionId" + TemplateFieldDefaultVersion = "defaultVersion" + TemplateFieldDescription = "description" + TemplateFieldFolderName = "folderName" + TemplateFieldIcon = "icon" + TemplateFieldIconFilename = "iconFilename" + TemplateFieldLabels = "labels" + TemplateFieldMaintainer = "maintainer" + TemplateFieldName = "name" + TemplateFieldOwnerReferences = "ownerReferences" + TemplateFieldPath = "path" + TemplateFieldProjectCatalogID = "projectCatalogId" + TemplateFieldProjectID = "projectId" + TemplateFieldProjectURL = "projectURL" + TemplateFieldReadme = "readme" + TemplateFieldRemoved = "removed" + TemplateFieldState = "state" + TemplateFieldStatus = "status" + TemplateFieldTransitioning = "transitioning" + TemplateFieldTransitioningMessage = "transitioningMessage" + TemplateFieldUUID = "uuid" + TemplateFieldUpgradeFrom = "upgradeFrom" + TemplateFieldVersionLinks = "versionLinks" + TemplateFieldVersions = "versions" +) + +type Template struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CatalogID string `json:"catalogId,omitempty" yaml:"catalogId,omitempty"` + Categories []string `json:"categories,omitempty" yaml:"categories,omitempty"` + Category string `json:"category,omitempty" yaml:"category,omitempty"` + ClusterCatalogID string `json:"clusterCatalogId,omitempty" yaml:"clusterCatalogId,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultTemplateVersionID string `json:"defaultTemplateVersionId,omitempty" yaml:"defaultTemplateVersionId,omitempty"` + DefaultVersion string `json:"defaultVersion,omitempty" yaml:"defaultVersion,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + FolderName string `json:"folderName,omitempty" yaml:"folderName,omitempty"` + Icon string `json:"icon,omitempty" yaml:"icon,omitempty"` + IconFilename string `json:"iconFilename,omitempty" yaml:"iconFilename,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Maintainer string `json:"maintainer,omitempty" yaml:"maintainer,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ProjectCatalogID string `json:"projectCatalogId,omitempty" yaml:"projectCatalogId,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + ProjectURL string `json:"projectURL,omitempty" yaml:"projectURL,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *TemplateStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UpgradeFrom string `json:"upgradeFrom,omitempty" yaml:"upgradeFrom,omitempty"` + VersionLinks map[string]string `json:"versionLinks,omitempty" yaml:"versionLinks,omitempty"` + Versions []TemplateVersionSpec `json:"versions,omitempty" yaml:"versions,omitempty"` +} + +type TemplateCollection struct { + types.Collection + Data []Template `json:"data,omitempty"` + client *TemplateClient +} + +type TemplateClient struct { + apiClient *Client +} + +type TemplateOperations interface { + List(opts *types.ListOpts) (*TemplateCollection, error) + ListAll(opts *types.ListOpts) (*TemplateCollection, error) + Create(opts *Template) (*Template, error) + Update(existing *Template, updates interface{}) (*Template, error) + Replace(existing *Template) (*Template, error) + ByID(id string) (*Template, error) + Delete(container *Template) error +} + +func newTemplateClient(apiClient *Client) *TemplateClient { + return &TemplateClient{ + apiClient: apiClient, + } +} + +func (c *TemplateClient) Create(container *Template) (*Template, error) { + resp := &Template{} + err := c.apiClient.Ops.DoCreate(TemplateType, container, resp) + return resp, err +} + +func (c *TemplateClient) Update(existing *Template, updates interface{}) (*Template, error) { + resp := &Template{} + err := c.apiClient.Ops.DoUpdate(TemplateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *TemplateClient) Replace(obj *Template) (*Template, error) { + resp := &Template{} + err := c.apiClient.Ops.DoReplace(TemplateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *TemplateClient) List(opts *types.ListOpts) (*TemplateCollection, error) { + resp := &TemplateCollection{} + err := c.apiClient.Ops.DoList(TemplateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *TemplateClient) ListAll(opts *types.ListOpts) (*TemplateCollection, error) { + resp := &TemplateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *TemplateCollection) Next() (*TemplateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &TemplateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *TemplateClient) ByID(id string) (*Template, error) { + resp := &Template{} + err := c.apiClient.Ops.DoByID(TemplateType, id, resp) + return resp, err +} + +func (c *TemplateClient) Delete(container *Template) error { + return c.apiClient.Ops.DoResourceDelete(TemplateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_content.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_content.go new file mode 100644 index 0000000..14061ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_content.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + TemplateContentType = "templateContent" + TemplateContentFieldAnnotations = "annotations" + TemplateContentFieldCreated = "created" + TemplateContentFieldCreatorID = "creatorId" + TemplateContentFieldData = "data" + TemplateContentFieldLabels = "labels" + TemplateContentFieldName = "name" + TemplateContentFieldOwnerReferences = "ownerReferences" + TemplateContentFieldRemoved = "removed" + TemplateContentFieldUUID = "uuid" +) + +type TemplateContent struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Data string `json:"data,omitempty" yaml:"data,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type TemplateContentCollection struct { + types.Collection + Data []TemplateContent `json:"data,omitempty"` + client *TemplateContentClient +} + +type TemplateContentClient struct { + apiClient *Client +} + +type TemplateContentOperations interface { + List(opts *types.ListOpts) (*TemplateContentCollection, error) + ListAll(opts *types.ListOpts) (*TemplateContentCollection, error) + Create(opts *TemplateContent) (*TemplateContent, error) + Update(existing *TemplateContent, updates interface{}) (*TemplateContent, error) + Replace(existing *TemplateContent) (*TemplateContent, error) + ByID(id string) (*TemplateContent, error) + Delete(container *TemplateContent) error +} + +func newTemplateContentClient(apiClient *Client) *TemplateContentClient { + return &TemplateContentClient{ + apiClient: apiClient, + } +} + +func (c *TemplateContentClient) Create(container *TemplateContent) (*TemplateContent, error) { + resp := &TemplateContent{} + err := c.apiClient.Ops.DoCreate(TemplateContentType, container, resp) + return resp, err +} + +func (c *TemplateContentClient) Update(existing *TemplateContent, updates interface{}) (*TemplateContent, error) { + resp := &TemplateContent{} + err := c.apiClient.Ops.DoUpdate(TemplateContentType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *TemplateContentClient) Replace(obj *TemplateContent) (*TemplateContent, error) { + resp := &TemplateContent{} + err := c.apiClient.Ops.DoReplace(TemplateContentType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *TemplateContentClient) List(opts *types.ListOpts) (*TemplateContentCollection, error) { + resp := &TemplateContentCollection{} + err := c.apiClient.Ops.DoList(TemplateContentType, opts, resp) + resp.client = c + return resp, err +} + +func (c *TemplateContentClient) ListAll(opts *types.ListOpts) (*TemplateContentCollection, error) { + resp := &TemplateContentCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *TemplateContentCollection) Next() (*TemplateContentCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &TemplateContentCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *TemplateContentClient) ByID(id string) (*TemplateContent, error) { + resp := &TemplateContent{} + err := c.apiClient.Ops.DoByID(TemplateContentType, id, resp) + return resp, err +} + +func (c *TemplateContentClient) Delete(container *TemplateContent) error { + return c.apiClient.Ops.DoResourceDelete(TemplateContentType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_spec.go new file mode 100644 index 0000000..dbce148 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_spec.go @@ -0,0 +1,48 @@ +package client + +const ( + TemplateSpecType = "templateSpec" + TemplateSpecFieldCatalogID = "catalogId" + TemplateSpecFieldCategories = "categories" + TemplateSpecFieldCategory = "category" + TemplateSpecFieldClusterCatalogID = "clusterCatalogId" + TemplateSpecFieldClusterID = "clusterId" + TemplateSpecFieldDefaultTemplateVersionID = "defaultTemplateVersionId" + TemplateSpecFieldDefaultVersion = "defaultVersion" + TemplateSpecFieldDescription = "description" + TemplateSpecFieldDisplayName = "displayName" + TemplateSpecFieldFolderName = "folderName" + TemplateSpecFieldIcon = "icon" + TemplateSpecFieldIconFilename = "iconFilename" + TemplateSpecFieldMaintainer = "maintainer" + TemplateSpecFieldPath = "path" + TemplateSpecFieldProjectCatalogID = "projectCatalogId" + TemplateSpecFieldProjectID = "projectId" + TemplateSpecFieldProjectURL = "projectURL" + TemplateSpecFieldReadme = "readme" + TemplateSpecFieldUpgradeFrom = "upgradeFrom" + TemplateSpecFieldVersions = "versions" +) + +type TemplateSpec struct { + CatalogID string `json:"catalogId,omitempty" yaml:"catalogId,omitempty"` + Categories []string `json:"categories,omitempty" yaml:"categories,omitempty"` + Category string `json:"category,omitempty" yaml:"category,omitempty"` + ClusterCatalogID string `json:"clusterCatalogId,omitempty" yaml:"clusterCatalogId,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + DefaultTemplateVersionID string `json:"defaultTemplateVersionId,omitempty" yaml:"defaultTemplateVersionId,omitempty"` + DefaultVersion string `json:"defaultVersion,omitempty" yaml:"defaultVersion,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"` + FolderName string `json:"folderName,omitempty" yaml:"folderName,omitempty"` + Icon string `json:"icon,omitempty" yaml:"icon,omitempty"` + IconFilename string `json:"iconFilename,omitempty" yaml:"iconFilename,omitempty"` + Maintainer string `json:"maintainer,omitempty" yaml:"maintainer,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ProjectCatalogID string `json:"projectCatalogId,omitempty" yaml:"projectCatalogId,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + ProjectURL string `json:"projectURL,omitempty" yaml:"projectURL,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + UpgradeFrom string `json:"upgradeFrom,omitempty" yaml:"upgradeFrom,omitempty"` + Versions []TemplateVersionSpec `json:"versions,omitempty" yaml:"versions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_status.go new file mode 100644 index 0000000..573947c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_status.go @@ -0,0 +1,10 @@ +package client + +const ( + TemplateStatusType = "templateStatus" + TemplateStatusFieldHelmVersion = "helmVersion" +) + +type TemplateStatus struct { + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version.go new file mode 100644 index 0000000..f981e2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version.go @@ -0,0 +1,158 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + TemplateVersionType = "templateVersion" + TemplateVersionFieldAnnotations = "annotations" + TemplateVersionFieldAppReadme = "appReadme" + TemplateVersionFieldCreated = "created" + TemplateVersionFieldCreatorID = "creatorId" + TemplateVersionFieldDigest = "digest" + TemplateVersionFieldExternalID = "externalId" + TemplateVersionFieldFiles = "files" + TemplateVersionFieldKubeVersion = "kubeVersion" + TemplateVersionFieldLabels = "labels" + TemplateVersionFieldName = "name" + TemplateVersionFieldOwnerReferences = "ownerReferences" + TemplateVersionFieldQuestions = "questions" + TemplateVersionFieldRancherMaxVersion = "rancherMaxVersion" + TemplateVersionFieldRancherMinVersion = "rancherMinVersion" + TemplateVersionFieldRancherVersion = "rancherVersion" + TemplateVersionFieldReadme = "readme" + TemplateVersionFieldRemoved = "removed" + TemplateVersionFieldRequiredNamespace = "requiredNamespace" + TemplateVersionFieldState = "state" + TemplateVersionFieldStatus = "status" + TemplateVersionFieldTransitioning = "transitioning" + TemplateVersionFieldTransitioningMessage = "transitioningMessage" + TemplateVersionFieldUUID = "uuid" + TemplateVersionFieldUpgradeVersionLinks = "upgradeVersionLinks" + TemplateVersionFieldVersion = "version" + TemplateVersionFieldVersionDir = "versionDir" + TemplateVersionFieldVersionName = "versionName" + TemplateVersionFieldVersionURLs = "versionUrls" +) + +type TemplateVersion struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppReadme string `json:"appReadme,omitempty" yaml:"appReadme,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + KubeVersion string `json:"kubeVersion,omitempty" yaml:"kubeVersion,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + RancherMaxVersion string `json:"rancherMaxVersion,omitempty" yaml:"rancherMaxVersion,omitempty"` + RancherMinVersion string `json:"rancherMinVersion,omitempty" yaml:"rancherMinVersion,omitempty"` + RancherVersion string `json:"rancherVersion,omitempty" yaml:"rancherVersion,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + RequiredNamespace string `json:"requiredNamespace,omitempty" yaml:"requiredNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *TemplateVersionStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UpgradeVersionLinks map[string]string `json:"upgradeVersionLinks,omitempty" yaml:"upgradeVersionLinks,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + VersionDir string `json:"versionDir,omitempty" yaml:"versionDir,omitempty"` + VersionName string `json:"versionName,omitempty" yaml:"versionName,omitempty"` + VersionURLs []string `json:"versionUrls,omitempty" yaml:"versionUrls,omitempty"` +} + +type TemplateVersionCollection struct { + types.Collection + Data []TemplateVersion `json:"data,omitempty"` + client *TemplateVersionClient +} + +type TemplateVersionClient struct { + apiClient *Client +} + +type TemplateVersionOperations interface { + List(opts *types.ListOpts) (*TemplateVersionCollection, error) + ListAll(opts *types.ListOpts) (*TemplateVersionCollection, error) + Create(opts *TemplateVersion) (*TemplateVersion, error) + Update(existing *TemplateVersion, updates interface{}) (*TemplateVersion, error) + Replace(existing *TemplateVersion) (*TemplateVersion, error) + ByID(id string) (*TemplateVersion, error) + Delete(container *TemplateVersion) error +} + +func newTemplateVersionClient(apiClient *Client) *TemplateVersionClient { + return &TemplateVersionClient{ + apiClient: apiClient, + } +} + +func (c *TemplateVersionClient) Create(container *TemplateVersion) (*TemplateVersion, error) { + resp := &TemplateVersion{} + err := c.apiClient.Ops.DoCreate(TemplateVersionType, container, resp) + return resp, err +} + +func (c *TemplateVersionClient) Update(existing *TemplateVersion, updates interface{}) (*TemplateVersion, error) { + resp := &TemplateVersion{} + err := c.apiClient.Ops.DoUpdate(TemplateVersionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *TemplateVersionClient) Replace(obj *TemplateVersion) (*TemplateVersion, error) { + resp := &TemplateVersion{} + err := c.apiClient.Ops.DoReplace(TemplateVersionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *TemplateVersionClient) List(opts *types.ListOpts) (*TemplateVersionCollection, error) { + resp := &TemplateVersionCollection{} + err := c.apiClient.Ops.DoList(TemplateVersionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *TemplateVersionClient) ListAll(opts *types.ListOpts) (*TemplateVersionCollection, error) { + resp := &TemplateVersionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *TemplateVersionCollection) Next() (*TemplateVersionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &TemplateVersionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *TemplateVersionClient) ByID(id string) (*TemplateVersion, error) { + resp := &TemplateVersion{} + err := c.apiClient.Ops.DoByID(TemplateVersionType, id, resp) + return resp, err +} + +func (c *TemplateVersionClient) Delete(container *TemplateVersion) error { + return c.apiClient.Ops.DoResourceDelete(TemplateVersionType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_spec.go new file mode 100644 index 0000000..ba9dd9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_spec.go @@ -0,0 +1,40 @@ +package client + +const ( + TemplateVersionSpecType = "templateVersionSpec" + TemplateVersionSpecFieldAppReadme = "appReadme" + TemplateVersionSpecFieldDigest = "digest" + TemplateVersionSpecFieldExternalID = "externalId" + TemplateVersionSpecFieldFiles = "files" + TemplateVersionSpecFieldKubeVersion = "kubeVersion" + TemplateVersionSpecFieldQuestions = "questions" + TemplateVersionSpecFieldRancherMaxVersion = "rancherMaxVersion" + TemplateVersionSpecFieldRancherMinVersion = "rancherMinVersion" + TemplateVersionSpecFieldRancherVersion = "rancherVersion" + TemplateVersionSpecFieldReadme = "readme" + TemplateVersionSpecFieldRequiredNamespace = "requiredNamespace" + TemplateVersionSpecFieldUpgradeVersionLinks = "upgradeVersionLinks" + TemplateVersionSpecFieldVersion = "version" + TemplateVersionSpecFieldVersionDir = "versionDir" + TemplateVersionSpecFieldVersionName = "versionName" + TemplateVersionSpecFieldVersionURLs = "versionUrls" +) + +type TemplateVersionSpec struct { + AppReadme string `json:"appReadme,omitempty" yaml:"appReadme,omitempty"` + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + KubeVersion string `json:"kubeVersion,omitempty" yaml:"kubeVersion,omitempty"` + Questions []Question `json:"questions,omitempty" yaml:"questions,omitempty"` + RancherMaxVersion string `json:"rancherMaxVersion,omitempty" yaml:"rancherMaxVersion,omitempty"` + RancherMinVersion string `json:"rancherMinVersion,omitempty" yaml:"rancherMinVersion,omitempty"` + RancherVersion string `json:"rancherVersion,omitempty" yaml:"rancherVersion,omitempty"` + Readme string `json:"readme,omitempty" yaml:"readme,omitempty"` + RequiredNamespace string `json:"requiredNamespace,omitempty" yaml:"requiredNamespace,omitempty"` + UpgradeVersionLinks map[string]string `json:"upgradeVersionLinks,omitempty" yaml:"upgradeVersionLinks,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + VersionDir string `json:"versionDir,omitempty" yaml:"versionDir,omitempty"` + VersionName string `json:"versionName,omitempty" yaml:"versionName,omitempty"` + VersionURLs []string `json:"versionUrls,omitempty" yaml:"versionUrls,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_status.go new file mode 100644 index 0000000..ea736ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_template_version_status.go @@ -0,0 +1,10 @@ +package client + +const ( + TemplateVersionStatusType = "templateVersionStatus" + TemplateVersionStatusFieldHelmVersion = "helmVersion" +) + +type TemplateVersionStatus struct { + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_token.go new file mode 100644 index 0000000..40c591d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_token.go @@ -0,0 +1,155 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + TokenType = "token" + TokenFieldAnnotations = "annotations" + TokenFieldAuthProvider = "authProvider" + TokenFieldClusterID = "clusterId" + TokenFieldCreated = "created" + TokenFieldCreatorID = "creatorId" + TokenFieldCurrent = "current" + TokenFieldDescription = "description" + TokenFieldEnabled = "enabled" + TokenFieldExpired = "expired" + TokenFieldExpiresAt = "expiresAt" + TokenFieldGroupPrincipals = "groupPrincipals" + TokenFieldIsDerived = "isDerived" + TokenFieldLabels = "labels" + TokenFieldLastUpdateTime = "lastUpdateTime" + TokenFieldName = "name" + TokenFieldOwnerReferences = "ownerReferences" + TokenFieldProviderInfo = "providerInfo" + TokenFieldRemoved = "removed" + TokenFieldTTLMillis = "ttl" + TokenFieldToken = "token" + TokenFieldUUID = "uuid" + TokenFieldUserID = "userId" + TokenFieldUserPrincipal = "userPrincipal" +) + +type Token struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthProvider string `json:"authProvider,omitempty" yaml:"authProvider,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Current bool `json:"current,omitempty" yaml:"current,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Expired bool `json:"expired,omitempty" yaml:"expired,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + GroupPrincipals []string `json:"groupPrincipals,omitempty" yaml:"groupPrincipals,omitempty"` + IsDerived bool `json:"isDerived,omitempty" yaml:"isDerived,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProviderInfo map[string]string `json:"providerInfo,omitempty" yaml:"providerInfo,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserID string `json:"userId,omitempty" yaml:"userId,omitempty"` + UserPrincipal string `json:"userPrincipal,omitempty" yaml:"userPrincipal,omitempty"` +} + +type TokenCollection struct { + types.Collection + Data []Token `json:"data,omitempty"` + client *TokenClient +} + +type TokenClient struct { + apiClient *Client +} + +type TokenOperations interface { + List(opts *types.ListOpts) (*TokenCollection, error) + ListAll(opts *types.ListOpts) (*TokenCollection, error) + Create(opts *Token) (*Token, error) + Update(existing *Token, updates interface{}) (*Token, error) + Replace(existing *Token) (*Token, error) + ByID(id string) (*Token, error) + Delete(container *Token) error + + CollectionActionLogout(resource *TokenCollection) error +} + +func newTokenClient(apiClient *Client) *TokenClient { + return &TokenClient{ + apiClient: apiClient, + } +} + +func (c *TokenClient) Create(container *Token) (*Token, error) { + resp := &Token{} + err := c.apiClient.Ops.DoCreate(TokenType, container, resp) + return resp, err +} + +func (c *TokenClient) Update(existing *Token, updates interface{}) (*Token, error) { + resp := &Token{} + err := c.apiClient.Ops.DoUpdate(TokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *TokenClient) Replace(obj *Token) (*Token, error) { + resp := &Token{} + err := c.apiClient.Ops.DoReplace(TokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *TokenClient) List(opts *types.ListOpts) (*TokenCollection, error) { + resp := &TokenCollection{} + err := c.apiClient.Ops.DoList(TokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *TokenClient) ListAll(opts *types.ListOpts) (*TokenCollection, error) { + resp := &TokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *TokenCollection) Next() (*TokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &TokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *TokenClient) ByID(id string) (*Token, error) { + resp := &Token{} + err := c.apiClient.Ops.DoByID(TokenType, id, resp) + return resp, err +} + +func (c *TokenClient) Delete(container *Token) error { + return c.apiClient.Ops.DoResourceDelete(TokenType, &container.Resource) +} + +func (c *TokenClient) CollectionActionLogout(resource *TokenCollection) error { + err := c.apiClient.Ops.DoCollectionAction(TokenType, "logout", &resource.Collection, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_toleration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_toleration.go new file mode 100644 index 0000000..eabdd9d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_toleration.go @@ -0,0 +1,18 @@ +package client + +const ( + TolerationType = "toleration" + TolerationFieldEffect = "effect" + TolerationFieldKey = "key" + TolerationFieldOperator = "operator" + TolerationFieldTolerationSeconds = "tolerationSeconds" + TolerationFieldValue = "value" +) + +type Toleration struct { + Effect string `json:"effect,omitempty" yaml:"effect,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + TolerationSeconds *int64 `json:"tolerationSeconds,omitempty" yaml:"tolerationSeconds,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_local_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_local_object_reference.go new file mode 100644 index 0000000..0de2ebe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_local_object_reference.go @@ -0,0 +1,14 @@ +package client + +const ( + TypedLocalObjectReferenceType = "typedLocalObjectReference" + TypedLocalObjectReferenceFieldAPIGroup = "apiGroup" + TypedLocalObjectReferenceFieldKind = "kind" + TypedLocalObjectReferenceFieldName = "name" +) + +type TypedLocalObjectReference struct { + APIGroup string `json:"apiGroup,omitempty" yaml:"apiGroup,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_object_reference.go new file mode 100644 index 0000000..d60df80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_typed_object_reference.go @@ -0,0 +1,16 @@ +package client + +const ( + TypedObjectReferenceType = "typedObjectReference" + TypedObjectReferenceFieldAPIGroup = "apiGroup" + TypedObjectReferenceFieldKind = "kind" + TypedObjectReferenceFieldName = "name" + TypedObjectReferenceFieldNamespace = "namespace" +) + +type TypedObjectReference struct { + APIGroup string `json:"apiGroup,omitempty" yaml:"apiGroup,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_global_dnstargets_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_global_dnstargets_input.go new file mode 100644 index 0000000..5aec4f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_global_dnstargets_input.go @@ -0,0 +1,10 @@ +package client + +const ( + UpdateGlobalDNSTargetsInputType = "updateGlobalDNSTargetsInput" + UpdateGlobalDNSTargetsInputFieldProjectIDs = "projectIds" +) + +type UpdateGlobalDNSTargetsInput struct { + ProjectIDs []string `json:"projectIds,omitempty" yaml:"projectIds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_multi_cluster_app_targets_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_multi_cluster_app_targets_input.go new file mode 100644 index 0000000..8ccaf6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_update_multi_cluster_app_targets_input.go @@ -0,0 +1,12 @@ +package client + +const ( + UpdateMultiClusterAppTargetsInputType = "updateMultiClusterAppTargetsInput" + UpdateMultiClusterAppTargetsInputFieldAnswers = "answers" + UpdateMultiClusterAppTargetsInputFieldProjects = "projects" +) + +type UpdateMultiClusterAppTargetsInput struct { + Answers []Answer `json:"answers,omitempty" yaml:"answers,omitempty"` + Projects []string `json:"projects,omitempty" yaml:"projects,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_upgrade_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_upgrade_strategy.go new file mode 100644 index 0000000..1bd375c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_upgrade_strategy.go @@ -0,0 +1,10 @@ +package client + +const ( + UpgradeStrategyType = "upgradeStrategy" + UpgradeStrategyFieldRollingUpdate = "rollingUpdate" +) + +type UpgradeStrategy struct { + RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty" yaml:"rollingUpdate,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user.go new file mode 100644 index 0000000..454a296 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user.go @@ -0,0 +1,169 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + UserType = "user" + UserFieldAnnotations = "annotations" + UserFieldConditions = "conditions" + UserFieldCreated = "created" + UserFieldCreatorID = "creatorId" + UserFieldDescription = "description" + UserFieldEnabled = "enabled" + UserFieldLabels = "labels" + UserFieldMe = "me" + UserFieldMustChangePassword = "mustChangePassword" + UserFieldName = "name" + UserFieldOwnerReferences = "ownerReferences" + UserFieldPassword = "password" + UserFieldPrincipalIDs = "principalIds" + UserFieldRemoved = "removed" + UserFieldState = "state" + UserFieldTransitioning = "transitioning" + UserFieldTransitioningMessage = "transitioningMessage" + UserFieldUUID = "uuid" + UserFieldUsername = "username" +) + +type User struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Conditions []UserCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Me bool `json:"me,omitempty" yaml:"me,omitempty"` + MustChangePassword bool `json:"mustChangePassword,omitempty" yaml:"mustChangePassword,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + PrincipalIDs []string `json:"principalIds,omitempty" yaml:"principalIds,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type UserCollection struct { + types.Collection + Data []User `json:"data,omitempty"` + client *UserClient +} + +type UserClient struct { + apiClient *Client +} + +type UserOperations interface { + List(opts *types.ListOpts) (*UserCollection, error) + ListAll(opts *types.ListOpts) (*UserCollection, error) + Create(opts *User) (*User, error) + Update(existing *User, updates interface{}) (*User, error) + Replace(existing *User) (*User, error) + ByID(id string) (*User, error) + Delete(container *User) error + + ActionRefreshauthprovideraccess(resource *User) error + + ActionSetpassword(resource *User, input *SetPasswordInput) (*User, error) + + CollectionActionChangepassword(resource *UserCollection, input *ChangePasswordInput) error + + CollectionActionRefreshauthprovideraccess(resource *UserCollection) error +} + +func newUserClient(apiClient *Client) *UserClient { + return &UserClient{ + apiClient: apiClient, + } +} + +func (c *UserClient) Create(container *User) (*User, error) { + resp := &User{} + err := c.apiClient.Ops.DoCreate(UserType, container, resp) + return resp, err +} + +func (c *UserClient) Update(existing *User, updates interface{}) (*User, error) { + resp := &User{} + err := c.apiClient.Ops.DoUpdate(UserType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *UserClient) Replace(obj *User) (*User, error) { + resp := &User{} + err := c.apiClient.Ops.DoReplace(UserType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *UserClient) List(opts *types.ListOpts) (*UserCollection, error) { + resp := &UserCollection{} + err := c.apiClient.Ops.DoList(UserType, opts, resp) + resp.client = c + return resp, err +} + +func (c *UserClient) ListAll(opts *types.ListOpts) (*UserCollection, error) { + resp := &UserCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *UserCollection) Next() (*UserCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &UserCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *UserClient) ByID(id string) (*User, error) { + resp := &User{} + err := c.apiClient.Ops.DoByID(UserType, id, resp) + return resp, err +} + +func (c *UserClient) Delete(container *User) error { + return c.apiClient.Ops.DoResourceDelete(UserType, &container.Resource) +} + +func (c *UserClient) ActionRefreshauthprovideraccess(resource *User) error { + err := c.apiClient.Ops.DoAction(UserType, "refreshauthprovideraccess", &resource.Resource, nil, nil) + return err +} + +func (c *UserClient) ActionSetpassword(resource *User, input *SetPasswordInput) (*User, error) { + resp := &User{} + err := c.apiClient.Ops.DoAction(UserType, "setpassword", &resource.Resource, input, resp) + return resp, err +} + +func (c *UserClient) CollectionActionChangepassword(resource *UserCollection, input *ChangePasswordInput) error { + err := c.apiClient.Ops.DoCollectionAction(UserType, "changepassword", &resource.Collection, input, nil) + return err +} + +func (c *UserClient) CollectionActionRefreshauthprovideraccess(resource *UserCollection) error { + err := c.apiClient.Ops.DoCollectionAction(UserType, "refreshauthprovideraccess", &resource.Collection, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_attribute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_attribute.go new file mode 100644 index 0000000..16ce8aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_attribute.go @@ -0,0 +1,40 @@ +package client + +const ( + UserAttributeType = "userAttribute" + UserAttributeFieldAnnotations = "annotations" + UserAttributeFieldCreated = "created" + UserAttributeFieldCreatorID = "creatorId" + UserAttributeFieldDeleteAfter = "deleteAfter" + UserAttributeFieldDisableAfter = "disableAfter" + UserAttributeFieldExtraByProvider = "extraByProvider" + UserAttributeFieldGroupPrincipals = "groupPrincipals" + UserAttributeFieldLabels = "labels" + UserAttributeFieldLastLogin = "lastLogin" + UserAttributeFieldLastRefresh = "lastRefresh" + UserAttributeFieldName = "name" + UserAttributeFieldNeedsRefresh = "needsRefresh" + UserAttributeFieldOwnerReferences = "ownerReferences" + UserAttributeFieldRemoved = "removed" + UserAttributeFieldUUID = "uuid" + UserAttributeFieldUserName = "userName" +) + +type UserAttribute struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DeleteAfter string `json:"deleteAfter,omitempty" yaml:"deleteAfter,omitempty"` + DisableAfter string `json:"disableAfter,omitempty" yaml:"disableAfter,omitempty"` + ExtraByProvider map[string]map[string][]string `json:"extraByProvider,omitempty" yaml:"extraByProvider,omitempty"` + GroupPrincipals map[string]Principal `json:"groupPrincipals,omitempty" yaml:"groupPrincipals,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastLogin string `json:"lastLogin,omitempty" yaml:"lastLogin,omitempty"` + LastRefresh string `json:"lastRefresh,omitempty" yaml:"lastRefresh,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NeedsRefresh bool `json:"needsRefresh,omitempty" yaml:"needsRefresh,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserName string `json:"userName,omitempty" yaml:"userName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_condition.go new file mode 100644 index 0000000..7d19141 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + UserConditionType = "userCondition" + UserConditionFieldLastTransitionTime = "lastTransitionTime" + UserConditionFieldLastUpdateTime = "lastUpdateTime" + UserConditionFieldMessage = "message" + UserConditionFieldReason = "reason" + UserConditionFieldStatus = "status" + UserConditionFieldType = "type" +) + +type UserCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_spec.go new file mode 100644 index 0000000..a3b927d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_spec.go @@ -0,0 +1,8 @@ +package client + +const ( + UserSpecType = "userSpec" +) + +type UserSpec struct { +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_status.go new file mode 100644 index 0000000..a42c797 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_user_status.go @@ -0,0 +1,10 @@ +package client + +const ( + UserStatusType = "userStatus" + UserStatusFieldConditions = "conditions" +) + +type UserStatus struct { + Conditions []UserCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_values.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_values.go new file mode 100644 index 0000000..f8b87dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_values.go @@ -0,0 +1,16 @@ +package client + +const ( + ValuesType = "values" + ValuesFieldBoolValue = "boolValue" + ValuesFieldIntValue = "intValue" + ValuesFieldStringSliceValue = "stringSliceValue" + ValuesFieldStringValue = "stringValue" +) + +type Values struct { + BoolValue bool `json:"boolValue,omitempty" yaml:"boolValue,omitempty"` + IntValue int64 `json:"intValue,omitempty" yaml:"intValue,omitempty"` + StringSliceValue []string `json:"stringSliceValue,omitempty" yaml:"stringSliceValue,omitempty"` + StringValue string `json:"stringValue,omitempty" yaml:"stringValue,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_version_commits.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_version_commits.go new file mode 100644 index 0000000..493b1e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_version_commits.go @@ -0,0 +1,10 @@ +package client + +const ( + VersionCommitsType = "versionCommits" + VersionCommitsFieldValue = "Value" +) + +type VersionCommits struct { + Value map[string]string `json:"Value,omitempty" yaml:"Value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_virtual_center_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_virtual_center_config.go new file mode 100644 index 0000000..b29d74d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_virtual_center_config.go @@ -0,0 +1,18 @@ +package client + +const ( + VirtualCenterConfigType = "virtualCenterConfig" + VirtualCenterConfigFieldDatacenters = "datacenters" + VirtualCenterConfigFieldPassword = "password" + VirtualCenterConfigFieldRoundTripperCount = "soap-roundtrip-count" + VirtualCenterConfigFieldUser = "user" + VirtualCenterConfigFieldVCenterPort = "port" +) + +type VirtualCenterConfig struct { + Datacenters string `json:"datacenters,omitempty" yaml:"datacenters,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + RoundTripperCount int64 `json:"soap-roundtrip-count,omitempty" yaml:"soap-roundtrip-count,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + VCenterPort string `json:"port,omitempty" yaml:"port,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_projection.go new file mode 100644 index 0000000..d67ed14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_projection.go @@ -0,0 +1,18 @@ +package client + +const ( + VolumeProjectionType = "volumeProjection" + VolumeProjectionFieldClusterTrustBundle = "clusterTrustBundle" + VolumeProjectionFieldConfigMap = "configMap" + VolumeProjectionFieldDownwardAPI = "downwardAPI" + VolumeProjectionFieldSecret = "secret" + VolumeProjectionFieldServiceAccountToken = "serviceAccountToken" +) + +type VolumeProjection struct { + ClusterTrustBundle *ClusterTrustBundleProjection `json:"clusterTrustBundle,omitempty" yaml:"clusterTrustBundle,omitempty"` + ConfigMap *ConfigMapProjection `json:"configMap,omitempty" yaml:"configMap,omitempty"` + DownwardAPI *DownwardAPIProjection `json:"downwardAPI,omitempty" yaml:"downwardAPI,omitempty"` + Secret *SecretProjection `json:"secret,omitempty" yaml:"secret,omitempty"` + ServiceAccountToken *ServiceAccountTokenProjection `json:"serviceAccountToken,omitempty" yaml:"serviceAccountToken,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_resource_requirements.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_resource_requirements.go new file mode 100644 index 0000000..780368b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_volume_resource_requirements.go @@ -0,0 +1,12 @@ +package client + +const ( + VolumeResourceRequirementsType = "volumeResourceRequirements" + VolumeResourceRequirementsFieldLimits = "limits" + VolumeResourceRequirementsFieldRequests = "requests" +) + +type VolumeResourceRequirements struct { + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + Requests map[string]string `json:"requests,omitempty" yaml:"requests,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_cloud_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_cloud_provider.go new file mode 100644 index 0000000..63bbae2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_cloud_provider.go @@ -0,0 +1,18 @@ +package client + +const ( + VsphereCloudProviderType = "vsphereCloudProvider" + VsphereCloudProviderFieldDisk = "disk" + VsphereCloudProviderFieldGlobal = "global" + VsphereCloudProviderFieldNetwork = "network" + VsphereCloudProviderFieldVirtualCenter = "virtualCenter" + VsphereCloudProviderFieldWorkspace = "workspace" +) + +type VsphereCloudProvider struct { + Disk *DiskVsphereOpts `json:"disk,omitempty" yaml:"disk,omitempty"` + Global *GlobalVsphereOpts `json:"global,omitempty" yaml:"global,omitempty"` + Network *NetworkVshpereOpts `json:"network,omitempty" yaml:"network,omitempty"` + VirtualCenter map[string]VirtualCenterConfig `json:"virtualCenter,omitempty" yaml:"virtualCenter,omitempty"` + Workspace *WorkspaceVsphereOpts `json:"workspace,omitempty" yaml:"workspace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_virtual_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_virtual_disk_volume_source.go new file mode 100644 index 0000000..ed671ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_vsphere_virtual_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + VsphereVirtualDiskVolumeSourceType = "vsphereVirtualDiskVolumeSource" + VsphereVirtualDiskVolumeSourceFieldFSType = "fsType" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyID = "storagePolicyID" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyName = "storagePolicyName" + VsphereVirtualDiskVolumeSourceFieldVolumePath = "volumePath" +) + +type VsphereVirtualDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + StoragePolicyID string `json:"storagePolicyID,omitempty" yaml:"storagePolicyID,omitempty"` + StoragePolicyName string `json:"storagePolicyName,omitempty" yaml:"storagePolicyName,omitempty"` + VolumePath string `json:"volumePath,omitempty" yaml:"volumePath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weave_network_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weave_network_provider.go new file mode 100644 index 0000000..2cd7b6f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weave_network_provider.go @@ -0,0 +1,10 @@ +package client + +const ( + WeaveNetworkProviderType = "weaveNetworkProvider" + WeaveNetworkProviderFieldPassword = "password" +) + +type WeaveNetworkProvider struct { + Password string `json:"password,omitempty" yaml:"password,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weighted_pod_affinity_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weighted_pod_affinity_term.go new file mode 100644 index 0000000..a046f5a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_weighted_pod_affinity_term.go @@ -0,0 +1,12 @@ +package client + +const ( + WeightedPodAffinityTermType = "weightedPodAffinityTerm" + WeightedPodAffinityTermFieldPodAffinityTerm = "podAffinityTerm" + WeightedPodAffinityTermFieldWeight = "weight" +) + +type WeightedPodAffinityTerm struct { + PodAffinityTerm *PodAffinityTerm `json:"podAffinityTerm,omitempty" yaml:"podAffinityTerm,omitempty"` + Weight int64 `json:"weight,omitempty" yaml:"weight,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_workspace_vsphere_opts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_workspace_vsphere_opts.go new file mode 100644 index 0000000..3f13897 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3/zz_generated_workspace_vsphere_opts.go @@ -0,0 +1,18 @@ +package client + +const ( + WorkspaceVsphereOptsType = "workspaceVsphereOpts" + WorkspaceVsphereOptsFieldDatacenter = "datacenter" + WorkspaceVsphereOptsFieldDefaultDatastore = "default-datastore" + WorkspaceVsphereOptsFieldFolder = "folder" + WorkspaceVsphereOptsFieldResourcePoolPath = "resourcepool-path" + WorkspaceVsphereOptsFieldVCenterIP = "server" +) + +type WorkspaceVsphereOpts struct { + Datacenter string `json:"datacenter,omitempty" yaml:"datacenter,omitempty"` + DefaultDatastore string `json:"default-datastore,omitempty" yaml:"default-datastore,omitempty"` + Folder string `json:"folder,omitempty" yaml:"folder,omitempty"` + ResourcePoolPath string `json:"resourcepool-path,omitempty" yaml:"resourcepool-path,omitempty"` + VCenterIP string `json:"server,omitempty" yaml:"server,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_active_directory_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_active_directory_provider.go new file mode 100644 index 0000000..51ef43c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_active_directory_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + ActiveDirectoryProviderType = "activeDirectoryProvider" + ActiveDirectoryProviderFieldAnnotations = "annotations" + ActiveDirectoryProviderFieldCreated = "created" + ActiveDirectoryProviderFieldCreatorID = "creatorId" + ActiveDirectoryProviderFieldDefaultLoginDomain = "defaultLoginDomain" + ActiveDirectoryProviderFieldLabels = "labels" + ActiveDirectoryProviderFieldName = "name" + ActiveDirectoryProviderFieldOwnerReferences = "ownerReferences" + ActiveDirectoryProviderFieldRemoved = "removed" + ActiveDirectoryProviderFieldType = "type" + ActiveDirectoryProviderFieldUUID = "uuid" +) + +type ActiveDirectoryProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultLoginDomain string `json:"defaultLoginDomain,omitempty" yaml:"defaultLoginDomain,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_adfs_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_adfs_provider.go new file mode 100644 index 0000000..552a93d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_adfs_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + ADFSProviderType = "adfsProvider" + ADFSProviderFieldAnnotations = "annotations" + ADFSProviderFieldCreated = "created" + ADFSProviderFieldCreatorID = "creatorId" + ADFSProviderFieldLabels = "labels" + ADFSProviderFieldName = "name" + ADFSProviderFieldOwnerReferences = "ownerReferences" + ADFSProviderFieldRedirectURL = "redirectUrl" + ADFSProviderFieldRemoved = "removed" + ADFSProviderFieldType = "type" + ADFSProviderFieldUUID = "uuid" +) + +type ADFSProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_provider.go new file mode 100644 index 0000000..4c49b3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_provider.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + AuthProviderType = "authProvider" + AuthProviderFieldAnnotations = "annotations" + AuthProviderFieldCreated = "created" + AuthProviderFieldCreatorID = "creatorId" + AuthProviderFieldLabels = "labels" + AuthProviderFieldName = "name" + AuthProviderFieldOwnerReferences = "ownerReferences" + AuthProviderFieldRemoved = "removed" + AuthProviderFieldType = "type" + AuthProviderFieldUUID = "uuid" +) + +type AuthProvider struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type AuthProviderCollection struct { + types.Collection + Data []AuthProvider `json:"data,omitempty"` + client *AuthProviderClient +} + +type AuthProviderClient struct { + apiClient *Client +} + +type AuthProviderOperations interface { + List(opts *types.ListOpts) (*AuthProviderCollection, error) + ListAll(opts *types.ListOpts) (*AuthProviderCollection, error) + Create(opts *AuthProvider) (*AuthProvider, error) + Update(existing *AuthProvider, updates interface{}) (*AuthProvider, error) + Replace(existing *AuthProvider) (*AuthProvider, error) + ByID(id string) (*AuthProvider, error) + Delete(container *AuthProvider) error +} + +func newAuthProviderClient(apiClient *Client) *AuthProviderClient { + return &AuthProviderClient{ + apiClient: apiClient, + } +} + +func (c *AuthProviderClient) Create(container *AuthProvider) (*AuthProvider, error) { + resp := &AuthProvider{} + err := c.apiClient.Ops.DoCreate(AuthProviderType, container, resp) + return resp, err +} + +func (c *AuthProviderClient) Update(existing *AuthProvider, updates interface{}) (*AuthProvider, error) { + resp := &AuthProvider{} + err := c.apiClient.Ops.DoUpdate(AuthProviderType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *AuthProviderClient) Replace(obj *AuthProvider) (*AuthProvider, error) { + resp := &AuthProvider{} + err := c.apiClient.Ops.DoReplace(AuthProviderType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *AuthProviderClient) List(opts *types.ListOpts) (*AuthProviderCollection, error) { + resp := &AuthProviderCollection{} + err := c.apiClient.Ops.DoList(AuthProviderType, opts, resp) + resp.client = c + return resp, err +} + +func (c *AuthProviderClient) ListAll(opts *types.ListOpts) (*AuthProviderCollection, error) { + resp := &AuthProviderCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *AuthProviderCollection) Next() (*AuthProviderCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &AuthProviderCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *AuthProviderClient) ByID(id string) (*AuthProvider, error) { + resp := &AuthProvider{} + err := c.apiClient.Ops.DoByID(AuthProviderType, id, resp) + return resp, err +} + +func (c *AuthProviderClient) Delete(container *AuthProvider) error { + return c.apiClient.Ops.DoResourceDelete(AuthProviderType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_token.go new file mode 100644 index 0000000..d406dc7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_auth_token.go @@ -0,0 +1,122 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + AuthTokenType = "authToken" + AuthTokenFieldAnnotations = "annotations" + AuthTokenFieldCreated = "created" + AuthTokenFieldCreatorID = "creatorId" + AuthTokenFieldExpiresAt = "expiresAt" + AuthTokenFieldLabels = "labels" + AuthTokenFieldName = "name" + AuthTokenFieldOwnerReferences = "ownerReferences" + AuthTokenFieldRemoved = "removed" + AuthTokenFieldToken = "token" + AuthTokenFieldUUID = "uuid" +) + +type AuthToken struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type AuthTokenCollection struct { + types.Collection + Data []AuthToken `json:"data,omitempty"` + client *AuthTokenClient +} + +type AuthTokenClient struct { + apiClient *Client +} + +type AuthTokenOperations interface { + List(opts *types.ListOpts) (*AuthTokenCollection, error) + ListAll(opts *types.ListOpts) (*AuthTokenCollection, error) + Create(opts *AuthToken) (*AuthToken, error) + Update(existing *AuthToken, updates interface{}) (*AuthToken, error) + Replace(existing *AuthToken) (*AuthToken, error) + ByID(id string) (*AuthToken, error) + Delete(container *AuthToken) error +} + +func newAuthTokenClient(apiClient *Client) *AuthTokenClient { + return &AuthTokenClient{ + apiClient: apiClient, + } +} + +func (c *AuthTokenClient) Create(container *AuthToken) (*AuthToken, error) { + resp := &AuthToken{} + err := c.apiClient.Ops.DoCreate(AuthTokenType, container, resp) + return resp, err +} + +func (c *AuthTokenClient) Update(existing *AuthToken, updates interface{}) (*AuthToken, error) { + resp := &AuthToken{} + err := c.apiClient.Ops.DoUpdate(AuthTokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *AuthTokenClient) Replace(obj *AuthToken) (*AuthToken, error) { + resp := &AuthToken{} + err := c.apiClient.Ops.DoReplace(AuthTokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *AuthTokenClient) List(opts *types.ListOpts) (*AuthTokenCollection, error) { + resp := &AuthTokenCollection{} + err := c.apiClient.Ops.DoList(AuthTokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *AuthTokenClient) ListAll(opts *types.ListOpts) (*AuthTokenCollection, error) { + resp := &AuthTokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *AuthTokenCollection) Next() (*AuthTokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &AuthTokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *AuthTokenClient) ByID(id string) (*AuthToken, error) { + resp := &AuthToken{} + err := c.apiClient.Ops.DoByID(AuthTokenType, id, resp) + return resp, err +} + +func (c *AuthTokenClient) Delete(container *AuthToken) error { + return c.apiClient.Ops.DoResourceDelete(AuthTokenType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adlogin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adlogin.go new file mode 100644 index 0000000..1bcdd47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adlogin.go @@ -0,0 +1,18 @@ +package client + +const ( + AzureADLoginType = "azureADLogin" + AzureADLoginFieldCode = "code" + AzureADLoginFieldDescription = "description" + AzureADLoginFieldIDToken = "id_token" + AzureADLoginFieldResponseType = "responseType" + AzureADLoginFieldTTLMillis = "ttl" +) + +type AzureADLogin struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + IDToken string `json:"id_token,omitempty" yaml:"id_token,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adprovider.go new file mode 100644 index 0000000..b8d5e44 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_azure_adprovider.go @@ -0,0 +1,40 @@ +package client + +const ( + AzureADProviderType = "azureADProvider" + AzureADProviderFieldAnnotations = "annotations" + AzureADProviderFieldAuthURL = "authUrl" + AzureADProviderFieldClientID = "clientId" + AzureADProviderFieldCreated = "created" + AzureADProviderFieldCreatorID = "creatorId" + AzureADProviderFieldDeviceAuthURL = "deviceAuthUrl" + AzureADProviderFieldLabels = "labels" + AzureADProviderFieldName = "name" + AzureADProviderFieldOwnerReferences = "ownerReferences" + AzureADProviderFieldRedirectURL = "redirectUrl" + AzureADProviderFieldRemoved = "removed" + AzureADProviderFieldScopes = "scopes" + AzureADProviderFieldTenantID = "tenantId" + AzureADProviderFieldTokenURL = "tokenUrl" + AzureADProviderFieldType = "type" + AzureADProviderFieldUUID = "uuid" +) + +type AzureADProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthURL string `json:"authUrl,omitempty" yaml:"authUrl,omitempty"` + ClientID string `json:"clientId,omitempty" yaml:"clientId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DeviceAuthURL string `json:"deviceAuthUrl,omitempty" yaml:"deviceAuthUrl,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Scopes []string `json:"scopes,omitempty" yaml:"scopes,omitempty"` + TenantID string `json:"tenantId,omitempty" yaml:"tenantId,omitempty"` + TokenURL string `json:"tokenUrl,omitempty" yaml:"tokenUrl,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_basic_login.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_basic_login.go new file mode 100644 index 0000000..0ebad76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_basic_login.go @@ -0,0 +1,18 @@ +package client + +const ( + BasicLoginType = "basicLogin" + BasicLoginFieldDescription = "description" + BasicLoginFieldPassword = "password" + BasicLoginFieldResponseType = "responseType" + BasicLoginFieldTTLMillis = "ttl" + BasicLoginFieldUsername = "username" +) + +type BasicLogin struct { + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_client.go new file mode 100644 index 0000000..9771473 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_client.go @@ -0,0 +1,28 @@ +package client + +import ( + "github.com/rancher/norman/clientbase" +) + +type Client struct { + clientbase.APIBaseClient + + AuthToken AuthTokenOperations + AuthProvider AuthProviderOperations +} + +func NewClient(opts *clientbase.ClientOpts) (*Client, error) { + baseClient, err := clientbase.NewAPIClient(opts) + if err != nil { + return nil, err + } + + client := &Client{ + APIBaseClient: baseClient, + } + + client.AuthToken = newAuthTokenClient(client) + client.AuthProvider = newAuthProviderClient(client) + + return client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_free_ipa_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_free_ipa_provider.go new file mode 100644 index 0000000..0cc8931 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_free_ipa_provider.go @@ -0,0 +1,26 @@ +package client + +const ( + FreeIpaProviderType = "freeIpaProvider" + FreeIpaProviderFieldAnnotations = "annotations" + FreeIpaProviderFieldCreated = "created" + FreeIpaProviderFieldCreatorID = "creatorId" + FreeIpaProviderFieldLabels = "labels" + FreeIpaProviderFieldName = "name" + FreeIpaProviderFieldOwnerReferences = "ownerReferences" + FreeIpaProviderFieldRemoved = "removed" + FreeIpaProviderFieldType = "type" + FreeIpaProviderFieldUUID = "uuid" +) + +type FreeIpaProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_generic_oidcprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_generic_oidcprovider.go new file mode 100644 index 0000000..a4d51a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_generic_oidcprovider.go @@ -0,0 +1,30 @@ +package client + +const ( + GenericOIDCProviderType = "genericOIDCProvider" + GenericOIDCProviderFieldAnnotations = "annotations" + GenericOIDCProviderFieldCreated = "created" + GenericOIDCProviderFieldCreatorID = "creatorId" + GenericOIDCProviderFieldLabels = "labels" + GenericOIDCProviderFieldName = "name" + GenericOIDCProviderFieldOwnerReferences = "ownerReferences" + GenericOIDCProviderFieldRedirectURL = "redirectUrl" + GenericOIDCProviderFieldRemoved = "removed" + GenericOIDCProviderFieldScopes = "scopes" + GenericOIDCProviderFieldType = "type" + GenericOIDCProviderFieldUUID = "uuid" +) + +type GenericOIDCProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Scopes string `json:"scopes,omitempty" yaml:"scopes,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_login.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_login.go new file mode 100644 index 0000000..c2bad5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_login.go @@ -0,0 +1,16 @@ +package client + +const ( + GithubLoginType = "githubLogin" + GithubLoginFieldCode = "code" + GithubLoginFieldDescription = "description" + GithubLoginFieldResponseType = "responseType" + GithubLoginFieldTTLMillis = "ttl" +) + +type GithubLogin struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_provider.go new file mode 100644 index 0000000..95c9e6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_github_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + GithubProviderType = "githubProvider" + GithubProviderFieldAnnotations = "annotations" + GithubProviderFieldCreated = "created" + GithubProviderFieldCreatorID = "creatorId" + GithubProviderFieldLabels = "labels" + GithubProviderFieldName = "name" + GithubProviderFieldOwnerReferences = "ownerReferences" + GithubProviderFieldRedirectURL = "redirectUrl" + GithubProviderFieldRemoved = "removed" + GithubProviderFieldType = "type" + GithubProviderFieldUUID = "uuid" +) + +type GithubProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_login.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_login.go new file mode 100644 index 0000000..ccbad51 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_login.go @@ -0,0 +1,16 @@ +package client + +const ( + GoogleOauthLoginType = "googleOauthLogin" + GoogleOauthLoginFieldCode = "code" + GoogleOauthLoginFieldDescription = "description" + GoogleOauthLoginFieldResponseType = "responseType" + GoogleOauthLoginFieldTTLMillis = "ttl" +) + +type GoogleOauthLogin struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_provider.go new file mode 100644 index 0000000..916caec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_google_oauth_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + GoogleOAuthProviderType = "googleOAuthProvider" + GoogleOAuthProviderFieldAnnotations = "annotations" + GoogleOAuthProviderFieldCreated = "created" + GoogleOAuthProviderFieldCreatorID = "creatorId" + GoogleOAuthProviderFieldLabels = "labels" + GoogleOAuthProviderFieldName = "name" + GoogleOAuthProviderFieldOwnerReferences = "ownerReferences" + GoogleOAuthProviderFieldRedirectURL = "redirectUrl" + GoogleOAuthProviderFieldRemoved = "removed" + GoogleOAuthProviderFieldType = "type" + GoogleOAuthProviderFieldUUID = "uuid" +) + +type GoogleOAuthProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_oidcprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_oidcprovider.go new file mode 100644 index 0000000..9f43ef3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_oidcprovider.go @@ -0,0 +1,28 @@ +package client + +const ( + KeyCloakOIDCProviderType = "keyCloakOIDCProvider" + KeyCloakOIDCProviderFieldAnnotations = "annotations" + KeyCloakOIDCProviderFieldCreated = "created" + KeyCloakOIDCProviderFieldCreatorID = "creatorId" + KeyCloakOIDCProviderFieldLabels = "labels" + KeyCloakOIDCProviderFieldName = "name" + KeyCloakOIDCProviderFieldOwnerReferences = "ownerReferences" + KeyCloakOIDCProviderFieldRedirectURL = "redirectUrl" + KeyCloakOIDCProviderFieldRemoved = "removed" + KeyCloakOIDCProviderFieldType = "type" + KeyCloakOIDCProviderFieldUUID = "uuid" +) + +type KeyCloakOIDCProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_provider.go new file mode 100644 index 0000000..e9bd448 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_key_cloak_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + KeyCloakProviderType = "keyCloakProvider" + KeyCloakProviderFieldAnnotations = "annotations" + KeyCloakProviderFieldCreated = "created" + KeyCloakProviderFieldCreatorID = "creatorId" + KeyCloakProviderFieldLabels = "labels" + KeyCloakProviderFieldName = "name" + KeyCloakProviderFieldOwnerReferences = "ownerReferences" + KeyCloakProviderFieldRedirectURL = "redirectUrl" + KeyCloakProviderFieldRemoved = "removed" + KeyCloakProviderFieldType = "type" + KeyCloakProviderFieldUUID = "uuid" +) + +type KeyCloakProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_local_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_local_provider.go new file mode 100644 index 0000000..c1f755f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_local_provider.go @@ -0,0 +1,26 @@ +package client + +const ( + LocalProviderType = "localProvider" + LocalProviderFieldAnnotations = "annotations" + LocalProviderFieldCreated = "created" + LocalProviderFieldCreatorID = "creatorId" + LocalProviderFieldLabels = "labels" + LocalProviderFieldName = "name" + LocalProviderFieldOwnerReferences = "ownerReferences" + LocalProviderFieldRemoved = "removed" + LocalProviderFieldType = "type" + LocalProviderFieldUUID = "uuid" +) + +type LocalProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_object_meta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_object_meta.go new file mode 100644 index 0000000..29f7963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_object_meta.go @@ -0,0 +1,28 @@ +package client + +const ( + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldFinalizers = "finalizers" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldOwnerReferences = "ownerReferences" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldSelfLink = "selfLink" + ObjectMetaFieldUUID = "uuid" +) + +type ObjectMeta struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + Finalizers []string `json:"finalizers,omitempty" yaml:"finalizers,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_login.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_login.go new file mode 100644 index 0000000..f55d1c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_login.go @@ -0,0 +1,16 @@ +package client + +const ( + OIDCLoginType = "oidcLogin" + OIDCLoginFieldCode = "code" + OIDCLoginFieldDescription = "description" + OIDCLoginFieldResponseType = "responseType" + OIDCLoginFieldTTLMillis = "ttl" +) + +type OIDCLogin struct { + Code string `json:"code,omitempty" yaml:"code,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_provider.go new file mode 100644 index 0000000..4995660 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_oidc_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + OIDCProviderType = "oidcProvider" + OIDCProviderFieldAnnotations = "annotations" + OIDCProviderFieldCreated = "created" + OIDCProviderFieldCreatorID = "creatorId" + OIDCProviderFieldLabels = "labels" + OIDCProviderFieldName = "name" + OIDCProviderFieldOwnerReferences = "ownerReferences" + OIDCProviderFieldRedirectURL = "redirectUrl" + OIDCProviderFieldRemoved = "removed" + OIDCProviderFieldType = "type" + OIDCProviderFieldUUID = "uuid" +) + +type OIDCProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_okta_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_okta_provider.go new file mode 100644 index 0000000..81487c4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_okta_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + OKTAProviderType = "oktaProvider" + OKTAProviderFieldAnnotations = "annotations" + OKTAProviderFieldCreated = "created" + OKTAProviderFieldCreatorID = "creatorId" + OKTAProviderFieldLabels = "labels" + OKTAProviderFieldName = "name" + OKTAProviderFieldOwnerReferences = "ownerReferences" + OKTAProviderFieldRedirectURL = "redirectUrl" + OKTAProviderFieldRemoved = "removed" + OKTAProviderFieldType = "type" + OKTAProviderFieldUUID = "uuid" +) + +type OKTAProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_open_ldap_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_open_ldap_provider.go new file mode 100644 index 0000000..68d5067 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_open_ldap_provider.go @@ -0,0 +1,26 @@ +package client + +const ( + OpenLdapProviderType = "openLdapProvider" + OpenLdapProviderFieldAnnotations = "annotations" + OpenLdapProviderFieldCreated = "created" + OpenLdapProviderFieldCreatorID = "creatorId" + OpenLdapProviderFieldLabels = "labels" + OpenLdapProviderFieldName = "name" + OpenLdapProviderFieldOwnerReferences = "ownerReferences" + OpenLdapProviderFieldRemoved = "removed" + OpenLdapProviderFieldType = "type" + OpenLdapProviderFieldUUID = "uuid" +) + +type OpenLdapProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_owner_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_owner_reference.go new file mode 100644 index 0000000..5f4436b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_owner_reference.go @@ -0,0 +1,20 @@ +package client + +const ( + OwnerReferenceType = "ownerReference" + OwnerReferenceFieldAPIVersion = "apiVersion" + OwnerReferenceFieldBlockOwnerDeletion = "blockOwnerDeletion" + OwnerReferenceFieldController = "controller" + OwnerReferenceFieldKind = "kind" + OwnerReferenceFieldName = "name" + OwnerReferenceFieldUID = "uid" +) + +type OwnerReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" yaml:"blockOwnerDeletion,omitempty"` + Controller *bool `json:"controller,omitempty" yaml:"controller,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_ping_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_ping_provider.go new file mode 100644 index 0000000..d5ed895 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_ping_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + PingProviderType = "pingProvider" + PingProviderFieldAnnotations = "annotations" + PingProviderFieldCreated = "created" + PingProviderFieldCreatorID = "creatorId" + PingProviderFieldLabels = "labels" + PingProviderFieldName = "name" + PingProviderFieldOwnerReferences = "ownerReferences" + PingProviderFieldRedirectURL = "redirectUrl" + PingProviderFieldRemoved = "removed" + PingProviderFieldType = "type" + PingProviderFieldUUID = "uuid" +) + +type PingProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_input.go new file mode 100644 index 0000000..a6fb24a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_input.go @@ -0,0 +1,16 @@ +package client + +const ( + SamlLoginInputType = "samlLoginInput" + SamlLoginInputFieldFinalRedirectURL = "finalRedirectUrl" + SamlLoginInputFieldPublicKey = "publicKey" + SamlLoginInputFieldRequestID = "requestId" + SamlLoginInputFieldResponseType = "responseType" +) + +type SamlLoginInput struct { + FinalRedirectURL string `json:"finalRedirectUrl,omitempty" yaml:"finalRedirectUrl,omitempty"` + PublicKey string `json:"publicKey,omitempty" yaml:"publicKey,omitempty"` + RequestID string `json:"requestId,omitempty" yaml:"requestId,omitempty"` + ResponseType string `json:"responseType,omitempty" yaml:"responseType,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_output.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_output.go new file mode 100644 index 0000000..c360ed7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_saml_login_output.go @@ -0,0 +1,10 @@ +package client + +const ( + SamlLoginOutputType = "samlLoginOutput" + SamlLoginOutputFieldIdpRedirectURL = "idpRedirectUrl" +) + +type SamlLoginOutput struct { + IdpRedirectURL string `json:"idpRedirectUrl,omitempty" yaml:"idpRedirectUrl,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_shibboleth_provider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_shibboleth_provider.go new file mode 100644 index 0000000..230dc16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_shibboleth_provider.go @@ -0,0 +1,28 @@ +package client + +const ( + ShibbolethProviderType = "shibbolethProvider" + ShibbolethProviderFieldAnnotations = "annotations" + ShibbolethProviderFieldCreated = "created" + ShibbolethProviderFieldCreatorID = "creatorId" + ShibbolethProviderFieldLabels = "labels" + ShibbolethProviderFieldName = "name" + ShibbolethProviderFieldOwnerReferences = "ownerReferences" + ShibbolethProviderFieldRedirectURL = "redirectUrl" + ShibbolethProviderFieldRemoved = "removed" + ShibbolethProviderFieldType = "type" + ShibbolethProviderFieldUUID = "uuid" +) + +type ShibbolethProvider struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + RedirectURL string `json:"redirectUrl,omitempty" yaml:"redirectUrl,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_token.go new file mode 100644 index 0000000..97c9349 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/management/v3public/zz_generated_token.go @@ -0,0 +1,54 @@ +package client + +const ( + TokenType = "token" + TokenFieldAnnotations = "annotations" + TokenFieldAuthProvider = "authProvider" + TokenFieldClusterID = "clusterId" + TokenFieldCreated = "created" + TokenFieldCreatorID = "creatorId" + TokenFieldCurrent = "current" + TokenFieldDescription = "description" + TokenFieldEnabled = "enabled" + TokenFieldExpired = "expired" + TokenFieldExpiresAt = "expiresAt" + TokenFieldGroupPrincipals = "groupPrincipals" + TokenFieldIsDerived = "isDerived" + TokenFieldLabels = "labels" + TokenFieldLastUpdateTime = "lastUpdateTime" + TokenFieldName = "name" + TokenFieldOwnerReferences = "ownerReferences" + TokenFieldProviderInfo = "providerInfo" + TokenFieldRemoved = "removed" + TokenFieldTTLMillis = "ttl" + TokenFieldToken = "token" + TokenFieldUUID = "uuid" + TokenFieldUserID = "userId" + TokenFieldUserPrincipal = "userPrincipal" +) + +type Token struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AuthProvider string `json:"authProvider,omitempty" yaml:"authProvider,omitempty"` + ClusterID string `json:"clusterId,omitempty" yaml:"clusterId,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Current bool `json:"current,omitempty" yaml:"current,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"` + Expired bool `json:"expired,omitempty" yaml:"expired,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + GroupPrincipals []string `json:"groupPrincipals,omitempty" yaml:"groupPrincipals,omitempty"` + IsDerived bool `json:"isDerived,omitempty" yaml:"isDerived,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProviderInfo map[string]string `json:"providerInfo,omitempty" yaml:"providerInfo,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + TTLMillis int64 `json:"ttl,omitempty" yaml:"ttl,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + UserID string `json:"userId,omitempty" yaml:"userId,omitempty"` + UserPrincipal string `json:"userPrincipal,omitempty" yaml:"userPrincipal,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_affinity.go new file mode 100644 index 0000000..0489c3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_affinity.go @@ -0,0 +1,14 @@ +package client + +const ( + AffinityType = "affinity" + AffinityFieldNodeAffinity = "nodeAffinity" + AffinityFieldPodAffinity = "podAffinity" + AffinityFieldPodAntiAffinity = "podAntiAffinity" +) + +type Affinity struct { + NodeAffinity *NodeAffinity `json:"nodeAffinity,omitempty" yaml:"nodeAffinity,omitempty"` + PodAffinity *PodAffinity `json:"podAffinity,omitempty" yaml:"podAffinity,omitempty"` + PodAntiAffinity *PodAntiAffinity `json:"podAntiAffinity,omitempty" yaml:"podAntiAffinity,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app.go new file mode 100644 index 0000000..4c0b2bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app.go @@ -0,0 +1,178 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + AppType = "app" + AppFieldAnnotations = "annotations" + AppFieldAnswers = "answers" + AppFieldAnswersSetString = "answersSetString" + AppFieldAppRevisionID = "appRevisionId" + AppFieldAppliedFiles = "appliedFiles" + AppFieldConditions = "conditions" + AppFieldCreated = "created" + AppFieldCreatorID = "creatorId" + AppFieldDescription = "description" + AppFieldExternalID = "externalId" + AppFieldFiles = "files" + AppFieldHelmVersion = "helmVersion" + AppFieldLabels = "labels" + AppFieldLastAppliedTemplates = "lastAppliedTemplate" + AppFieldMaxRevisionCount = "maxRevisionCount" + AppFieldMultiClusterAppID = "multiClusterAppId" + AppFieldName = "name" + AppFieldNamespaceId = "namespaceId" + AppFieldNotes = "notes" + AppFieldOwnerReferences = "ownerReferences" + AppFieldProjectID = "projectId" + AppFieldPrune = "prune" + AppFieldRemoved = "removed" + AppFieldState = "state" + AppFieldTargetNamespace = "targetNamespace" + AppFieldTimeout = "timeout" + AppFieldTransitioning = "transitioning" + AppFieldTransitioningMessage = "transitioningMessage" + AppFieldUUID = "uuid" + AppFieldValuesYaml = "valuesYaml" + AppFieldWait = "wait" +) + +type App struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Answers map[string]string `json:"answers,omitempty" yaml:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty" yaml:"answersSetString,omitempty"` + AppRevisionID string `json:"appRevisionId,omitempty" yaml:"appRevisionId,omitempty"` + AppliedFiles map[string]string `json:"appliedFiles,omitempty" yaml:"appliedFiles,omitempty"` + Conditions []AppCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastAppliedTemplates string `json:"lastAppliedTemplate,omitempty" yaml:"lastAppliedTemplate,omitempty"` + MaxRevisionCount int64 `json:"maxRevisionCount,omitempty" yaml:"maxRevisionCount,omitempty"` + MultiClusterAppID string `json:"multiClusterAppId,omitempty" yaml:"multiClusterAppId,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + Notes string `json:"notes,omitempty" yaml:"notes,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Prune bool `json:"prune,omitempty" yaml:"prune,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + TargetNamespace string `json:"targetNamespace,omitempty" yaml:"targetNamespace,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + ValuesYaml string `json:"valuesYaml,omitempty" yaml:"valuesYaml,omitempty"` + Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` +} + +type AppCollection struct { + types.Collection + Data []App `json:"data,omitempty"` + client *AppClient +} + +type AppClient struct { + apiClient *Client +} + +type AppOperations interface { + List(opts *types.ListOpts) (*AppCollection, error) + ListAll(opts *types.ListOpts) (*AppCollection, error) + Create(opts *App) (*App, error) + Update(existing *App, updates interface{}) (*App, error) + Replace(existing *App) (*App, error) + ByID(id string) (*App, error) + Delete(container *App) error + + ActionRollback(resource *App, input *RollbackRevision) error + + ActionUpgrade(resource *App, input *AppUpgradeConfig) error +} + +func newAppClient(apiClient *Client) *AppClient { + return &AppClient{ + apiClient: apiClient, + } +} + +func (c *AppClient) Create(container *App) (*App, error) { + resp := &App{} + err := c.apiClient.Ops.DoCreate(AppType, container, resp) + return resp, err +} + +func (c *AppClient) Update(existing *App, updates interface{}) (*App, error) { + resp := &App{} + err := c.apiClient.Ops.DoUpdate(AppType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *AppClient) Replace(obj *App) (*App, error) { + resp := &App{} + err := c.apiClient.Ops.DoReplace(AppType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *AppClient) List(opts *types.ListOpts) (*AppCollection, error) { + resp := &AppCollection{} + err := c.apiClient.Ops.DoList(AppType, opts, resp) + resp.client = c + return resp, err +} + +func (c *AppClient) ListAll(opts *types.ListOpts) (*AppCollection, error) { + resp := &AppCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *AppCollection) Next() (*AppCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &AppCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *AppClient) ByID(id string) (*App, error) { + resp := &App{} + err := c.apiClient.Ops.DoByID(AppType, id, resp) + return resp, err +} + +func (c *AppClient) Delete(container *App) error { + return c.apiClient.Ops.DoResourceDelete(AppType, &container.Resource) +} + +func (c *AppClient) ActionRollback(resource *App, input *RollbackRevision) error { + err := c.apiClient.Ops.DoAction(AppType, "rollback", &resource.Resource, input, nil) + return err +} + +func (c *AppClient) ActionUpgrade(resource *App, input *AppUpgradeConfig) error { + err := c.apiClient.Ops.DoAction(AppType, "upgrade", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_armor_profile.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_armor_profile.go new file mode 100644 index 0000000..e943a3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_armor_profile.go @@ -0,0 +1,12 @@ +package client + +const ( + AppArmorProfileType = "appArmorProfile" + AppArmorProfileFieldLocalhostProfile = "localhostProfile" + AppArmorProfileFieldType = "type" +) + +type AppArmorProfile struct { + LocalhostProfile string `json:"localhostProfile,omitempty" yaml:"localhostProfile,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_condition.go new file mode 100644 index 0000000..9d633ae --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + AppConditionType = "appCondition" + AppConditionFieldLastTransitionTime = "lastTransitionTime" + AppConditionFieldLastUpdateTime = "lastUpdateTime" + AppConditionFieldMessage = "message" + AppConditionFieldReason = "reason" + AppConditionFieldStatus = "status" + AppConditionFieldType = "type" +) + +type AppCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision.go new file mode 100644 index 0000000..86df374 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision.go @@ -0,0 +1,130 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + AppRevisionType = "appRevision" + AppRevisionFieldAnnotations = "annotations" + AppRevisionFieldCreated = "created" + AppRevisionFieldCreatorID = "creatorId" + AppRevisionFieldLabels = "labels" + AppRevisionFieldName = "name" + AppRevisionFieldNamespaceId = "namespaceId" + AppRevisionFieldOwnerReferences = "ownerReferences" + AppRevisionFieldProjectID = "projectId" + AppRevisionFieldRemoved = "removed" + AppRevisionFieldState = "state" + AppRevisionFieldStatus = "status" + AppRevisionFieldTransitioning = "transitioning" + AppRevisionFieldTransitioningMessage = "transitioningMessage" + AppRevisionFieldUUID = "uuid" +) + +type AppRevision struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *AppRevisionStatus `json:"status,omitempty" yaml:"status,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type AppRevisionCollection struct { + types.Collection + Data []AppRevision `json:"data,omitempty"` + client *AppRevisionClient +} + +type AppRevisionClient struct { + apiClient *Client +} + +type AppRevisionOperations interface { + List(opts *types.ListOpts) (*AppRevisionCollection, error) + ListAll(opts *types.ListOpts) (*AppRevisionCollection, error) + Create(opts *AppRevision) (*AppRevision, error) + Update(existing *AppRevision, updates interface{}) (*AppRevision, error) + Replace(existing *AppRevision) (*AppRevision, error) + ByID(id string) (*AppRevision, error) + Delete(container *AppRevision) error +} + +func newAppRevisionClient(apiClient *Client) *AppRevisionClient { + return &AppRevisionClient{ + apiClient: apiClient, + } +} + +func (c *AppRevisionClient) Create(container *AppRevision) (*AppRevision, error) { + resp := &AppRevision{} + err := c.apiClient.Ops.DoCreate(AppRevisionType, container, resp) + return resp, err +} + +func (c *AppRevisionClient) Update(existing *AppRevision, updates interface{}) (*AppRevision, error) { + resp := &AppRevision{} + err := c.apiClient.Ops.DoUpdate(AppRevisionType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *AppRevisionClient) Replace(obj *AppRevision) (*AppRevision, error) { + resp := &AppRevision{} + err := c.apiClient.Ops.DoReplace(AppRevisionType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *AppRevisionClient) List(opts *types.ListOpts) (*AppRevisionCollection, error) { + resp := &AppRevisionCollection{} + err := c.apiClient.Ops.DoList(AppRevisionType, opts, resp) + resp.client = c + return resp, err +} + +func (c *AppRevisionClient) ListAll(opts *types.ListOpts) (*AppRevisionCollection, error) { + resp := &AppRevisionCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *AppRevisionCollection) Next() (*AppRevisionCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &AppRevisionCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *AppRevisionClient) ByID(id string) (*AppRevision, error) { + resp := &AppRevision{} + err := c.apiClient.Ops.DoByID(AppRevisionType, id, resp) + return resp, err +} + +func (c *AppRevisionClient) Delete(container *AppRevision) error { + return c.apiClient.Ops.DoResourceDelete(AppRevisionType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_spec.go new file mode 100644 index 0000000..3975f26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_spec.go @@ -0,0 +1,10 @@ +package client + +const ( + AppRevisionSpecType = "appRevisionSpec" + AppRevisionSpecFieldProjectID = "projectId" +) + +type AppRevisionSpec struct { + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_status.go new file mode 100644 index 0000000..5c0e42d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_revision_status.go @@ -0,0 +1,22 @@ +package client + +const ( + AppRevisionStatusType = "appRevisionStatus" + AppRevisionStatusFieldAnswers = "answers" + AppRevisionStatusFieldAnswersSetString = "answersSetString" + AppRevisionStatusFieldDigest = "digest" + AppRevisionStatusFieldExternalID = "externalId" + AppRevisionStatusFieldFiles = "files" + AppRevisionStatusFieldProjectID = "projectId" + AppRevisionStatusFieldValuesYaml = "valuesYaml" +) + +type AppRevisionStatus struct { + Answers map[string]string `json:"answers,omitempty" yaml:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty" yaml:"answersSetString,omitempty"` + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + ValuesYaml string `json:"valuesYaml,omitempty" yaml:"valuesYaml,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_spec.go new file mode 100644 index 0000000..f43cc74 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_spec.go @@ -0,0 +1,36 @@ +package client + +const ( + AppSpecType = "appSpec" + AppSpecFieldAnswers = "answers" + AppSpecFieldAnswersSetString = "answersSetString" + AppSpecFieldAppRevisionID = "appRevisionId" + AppSpecFieldDescription = "description" + AppSpecFieldExternalID = "externalId" + AppSpecFieldFiles = "files" + AppSpecFieldMaxRevisionCount = "maxRevisionCount" + AppSpecFieldMultiClusterAppID = "multiClusterAppId" + AppSpecFieldProjectID = "projectId" + AppSpecFieldPrune = "prune" + AppSpecFieldTargetNamespace = "targetNamespace" + AppSpecFieldTimeout = "timeout" + AppSpecFieldValuesYaml = "valuesYaml" + AppSpecFieldWait = "wait" +) + +type AppSpec struct { + Answers map[string]string `json:"answers,omitempty" yaml:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty" yaml:"answersSetString,omitempty"` + AppRevisionID string `json:"appRevisionId,omitempty" yaml:"appRevisionId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + MaxRevisionCount int64 `json:"maxRevisionCount,omitempty" yaml:"maxRevisionCount,omitempty"` + MultiClusterAppID string `json:"multiClusterAppId,omitempty" yaml:"multiClusterAppId,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Prune bool `json:"prune,omitempty" yaml:"prune,omitempty"` + TargetNamespace string `json:"targetNamespace,omitempty" yaml:"targetNamespace,omitempty"` + Timeout int64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + ValuesYaml string `json:"valuesYaml,omitempty" yaml:"valuesYaml,omitempty"` + Wait bool `json:"wait,omitempty" yaml:"wait,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_status.go new file mode 100644 index 0000000..d5337a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_status.go @@ -0,0 +1,18 @@ +package client + +const ( + AppStatusType = "appStatus" + AppStatusFieldAppliedFiles = "appliedFiles" + AppStatusFieldConditions = "conditions" + AppStatusFieldHelmVersion = "helmVersion" + AppStatusFieldLastAppliedTemplates = "lastAppliedTemplate" + AppStatusFieldNotes = "notes" +) + +type AppStatus struct { + AppliedFiles map[string]string `json:"appliedFiles,omitempty" yaml:"appliedFiles,omitempty"` + Conditions []AppCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + HelmVersion string `json:"helmVersion,omitempty" yaml:"helmVersion,omitempty"` + LastAppliedTemplates string `json:"lastAppliedTemplate,omitempty" yaml:"lastAppliedTemplate,omitempty"` + Notes string `json:"notes,omitempty" yaml:"notes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_upgrade_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_upgrade_config.go new file mode 100644 index 0000000..82fbe5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_app_upgrade_config.go @@ -0,0 +1,20 @@ +package client + +const ( + AppUpgradeConfigType = "appUpgradeConfig" + AppUpgradeConfigFieldAnswers = "answers" + AppUpgradeConfigFieldAnswersSetString = "answersSetString" + AppUpgradeConfigFieldExternalID = "externalId" + AppUpgradeConfigFieldFiles = "files" + AppUpgradeConfigFieldForceUpgrade = "forceUpgrade" + AppUpgradeConfigFieldValuesYaml = "valuesYaml" +) + +type AppUpgradeConfig struct { + Answers map[string]string `json:"answers,omitempty" yaml:"answers,omitempty"` + AnswersSetString map[string]string `json:"answersSetString,omitempty" yaml:"answersSetString,omitempty"` + ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"` + Files map[string]string `json:"files,omitempty" yaml:"files,omitempty"` + ForceUpgrade bool `json:"forceUpgrade,omitempty" yaml:"forceUpgrade,omitempty"` + ValuesYaml string `json:"valuesYaml,omitempty" yaml:"valuesYaml,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_aws_elastic_block_store_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_aws_elastic_block_store_volume_source.go new file mode 100644 index 0000000..5765e83 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_aws_elastic_block_store_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + AWSElasticBlockStoreVolumeSourceType = "awsElasticBlockStoreVolumeSource" + AWSElasticBlockStoreVolumeSourceFieldFSType = "fsType" + AWSElasticBlockStoreVolumeSourceFieldPartition = "partition" + AWSElasticBlockStoreVolumeSourceFieldReadOnly = "readOnly" + AWSElasticBlockStoreVolumeSourceFieldVolumeID = "volumeID" +) + +type AWSElasticBlockStoreVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_disk_volume_source.go new file mode 100644 index 0000000..28920c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_disk_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + AzureDiskVolumeSourceType = "azureDiskVolumeSource" + AzureDiskVolumeSourceFieldCachingMode = "cachingMode" + AzureDiskVolumeSourceFieldDataDiskURI = "diskURI" + AzureDiskVolumeSourceFieldDiskName = "diskName" + AzureDiskVolumeSourceFieldFSType = "fsType" + AzureDiskVolumeSourceFieldKind = "kind" + AzureDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type AzureDiskVolumeSource struct { + CachingMode string `json:"cachingMode,omitempty" yaml:"cachingMode,omitempty"` + DataDiskURI string `json:"diskURI,omitempty" yaml:"diskURI,omitempty"` + DiskName string `json:"diskName,omitempty" yaml:"diskName,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_persistent_volume_source.go new file mode 100644 index 0000000..4fe943f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + AzureFilePersistentVolumeSourceType = "azureFilePersistentVolumeSource" + AzureFilePersistentVolumeSourceFieldReadOnly = "readOnly" + AzureFilePersistentVolumeSourceFieldSecretName = "secretName" + AzureFilePersistentVolumeSourceFieldSecretNamespace = "secretNamespace" + AzureFilePersistentVolumeSourceFieldShareName = "shareName" +) + +type AzureFilePersistentVolumeSource struct { + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` + SecretNamespace string `json:"secretNamespace,omitempty" yaml:"secretNamespace,omitempty"` + ShareName string `json:"shareName,omitempty" yaml:"shareName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_volume_source.go new file mode 100644 index 0000000..3be8571 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_azure_file_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + AzureFileVolumeSourceType = "azureFileVolumeSource" + AzureFileVolumeSourceFieldReadOnly = "readOnly" + AzureFileVolumeSourceFieldSecretName = "secretName" + AzureFileVolumeSourceFieldShareName = "shareName" +) + +type AzureFileVolumeSource struct { + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` + ShareName string `json:"shareName,omitempty" yaml:"shareName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_basic_auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_basic_auth.go new file mode 100644 index 0000000..d2c9fdb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_basic_auth.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + BasicAuthType = "basicAuth" + BasicAuthFieldAnnotations = "annotations" + BasicAuthFieldCreated = "created" + BasicAuthFieldCreatorID = "creatorId" + BasicAuthFieldDescription = "description" + BasicAuthFieldLabels = "labels" + BasicAuthFieldName = "name" + BasicAuthFieldNamespaceId = "namespaceId" + BasicAuthFieldOwnerReferences = "ownerReferences" + BasicAuthFieldPassword = "password" + BasicAuthFieldProjectID = "projectId" + BasicAuthFieldRemoved = "removed" + BasicAuthFieldUUID = "uuid" + BasicAuthFieldUsername = "username" +) + +type BasicAuth struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type BasicAuthCollection struct { + types.Collection + Data []BasicAuth `json:"data,omitempty"` + client *BasicAuthClient +} + +type BasicAuthClient struct { + apiClient *Client +} + +type BasicAuthOperations interface { + List(opts *types.ListOpts) (*BasicAuthCollection, error) + ListAll(opts *types.ListOpts) (*BasicAuthCollection, error) + Create(opts *BasicAuth) (*BasicAuth, error) + Update(existing *BasicAuth, updates interface{}) (*BasicAuth, error) + Replace(existing *BasicAuth) (*BasicAuth, error) + ByID(id string) (*BasicAuth, error) + Delete(container *BasicAuth) error +} + +func newBasicAuthClient(apiClient *Client) *BasicAuthClient { + return &BasicAuthClient{ + apiClient: apiClient, + } +} + +func (c *BasicAuthClient) Create(container *BasicAuth) (*BasicAuth, error) { + resp := &BasicAuth{} + err := c.apiClient.Ops.DoCreate(BasicAuthType, container, resp) + return resp, err +} + +func (c *BasicAuthClient) Update(existing *BasicAuth, updates interface{}) (*BasicAuth, error) { + resp := &BasicAuth{} + err := c.apiClient.Ops.DoUpdate(BasicAuthType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *BasicAuthClient) Replace(obj *BasicAuth) (*BasicAuth, error) { + resp := &BasicAuth{} + err := c.apiClient.Ops.DoReplace(BasicAuthType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *BasicAuthClient) List(opts *types.ListOpts) (*BasicAuthCollection, error) { + resp := &BasicAuthCollection{} + err := c.apiClient.Ops.DoList(BasicAuthType, opts, resp) + resp.client = c + return resp, err +} + +func (c *BasicAuthClient) ListAll(opts *types.ListOpts) (*BasicAuthCollection, error) { + resp := &BasicAuthCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *BasicAuthCollection) Next() (*BasicAuthCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &BasicAuthCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *BasicAuthClient) ByID(id string) (*BasicAuth, error) { + resp := &BasicAuth{} + err := c.apiClient.Ops.DoByID(BasicAuthType, id, resp) + return resp, err +} + +func (c *BasicAuthClient) Delete(container *BasicAuth) error { + return c.apiClient.Ops.DoResourceDelete(BasicAuthType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_capabilities.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_capabilities.go new file mode 100644 index 0000000..e19c533 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_capabilities.go @@ -0,0 +1,12 @@ +package client + +const ( + CapabilitiesType = "capabilities" + CapabilitiesFieldCapAdd = "capAdd" + CapabilitiesFieldCapDrop = "capDrop" +) + +type Capabilities struct { + CapAdd []string `json:"capAdd,omitempty" yaml:"capAdd,omitempty"` + CapDrop []string `json:"capDrop,omitempty" yaml:"capDrop,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fspersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fspersistent_volume_source.go new file mode 100644 index 0000000..cdff275 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fspersistent_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + CephFSPersistentVolumeSourceType = "cephFSPersistentVolumeSource" + CephFSPersistentVolumeSourceFieldMonitors = "monitors" + CephFSPersistentVolumeSourceFieldPath = "path" + CephFSPersistentVolumeSourceFieldReadOnly = "readOnly" + CephFSPersistentVolumeSourceFieldSecretFile = "secretFile" + CephFSPersistentVolumeSourceFieldSecretRef = "secretRef" + CephFSPersistentVolumeSourceFieldUser = "user" +) + +type CephFSPersistentVolumeSource struct { + Monitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretFile string `json:"secretFile,omitempty" yaml:"secretFile,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fsvolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fsvolume_source.go new file mode 100644 index 0000000..363ba5e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ceph_fsvolume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + CephFSVolumeSourceType = "cephFSVolumeSource" + CephFSVolumeSourceFieldMonitors = "monitors" + CephFSVolumeSourceFieldPath = "path" + CephFSVolumeSourceFieldReadOnly = "readOnly" + CephFSVolumeSourceFieldSecretFile = "secretFile" + CephFSVolumeSourceFieldSecretRef = "secretRef" + CephFSVolumeSourceFieldUser = "user" +) + +type CephFSVolumeSource struct { + Monitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretFile string `json:"secretFile,omitempty" yaml:"secretFile,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_certificate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_certificate.go new file mode 100644 index 0000000..8ca953f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_certificate.go @@ -0,0 +1,148 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CertificateType = "certificate" + CertificateFieldAlgorithm = "algorithm" + CertificateFieldAnnotations = "annotations" + CertificateFieldCN = "cn" + CertificateFieldCertFingerprint = "certFingerprint" + CertificateFieldCerts = "certs" + CertificateFieldCreated = "created" + CertificateFieldCreatorID = "creatorId" + CertificateFieldDescription = "description" + CertificateFieldExpiresAt = "expiresAt" + CertificateFieldIssuedAt = "issuedAt" + CertificateFieldIssuer = "issuer" + CertificateFieldKey = "key" + CertificateFieldKeySize = "keySize" + CertificateFieldLabels = "labels" + CertificateFieldName = "name" + CertificateFieldNamespaceId = "namespaceId" + CertificateFieldOwnerReferences = "ownerReferences" + CertificateFieldProjectID = "projectId" + CertificateFieldRemoved = "removed" + CertificateFieldSerialNumber = "serialNumber" + CertificateFieldSubjectAlternativeNames = "subjectAlternativeNames" + CertificateFieldUUID = "uuid" + CertificateFieldVersion = "version" +) + +type Certificate struct { + types.Resource + Algorithm string `json:"algorithm,omitempty" yaml:"algorithm,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CN string `json:"cn,omitempty" yaml:"cn,omitempty"` + CertFingerprint string `json:"certFingerprint,omitempty" yaml:"certFingerprint,omitempty"` + Certs string `json:"certs,omitempty" yaml:"certs,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + IssuedAt string `json:"issuedAt,omitempty" yaml:"issuedAt,omitempty"` + Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + KeySize string `json:"keySize,omitempty" yaml:"keySize,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SerialNumber string `json:"serialNumber,omitempty" yaml:"serialNumber,omitempty"` + SubjectAlternativeNames []string `json:"subjectAlternativeNames,omitempty" yaml:"subjectAlternativeNames,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` +} + +type CertificateCollection struct { + types.Collection + Data []Certificate `json:"data,omitempty"` + client *CertificateClient +} + +type CertificateClient struct { + apiClient *Client +} + +type CertificateOperations interface { + List(opts *types.ListOpts) (*CertificateCollection, error) + ListAll(opts *types.ListOpts) (*CertificateCollection, error) + Create(opts *Certificate) (*Certificate, error) + Update(existing *Certificate, updates interface{}) (*Certificate, error) + Replace(existing *Certificate) (*Certificate, error) + ByID(id string) (*Certificate, error) + Delete(container *Certificate) error +} + +func newCertificateClient(apiClient *Client) *CertificateClient { + return &CertificateClient{ + apiClient: apiClient, + } +} + +func (c *CertificateClient) Create(container *Certificate) (*Certificate, error) { + resp := &Certificate{} + err := c.apiClient.Ops.DoCreate(CertificateType, container, resp) + return resp, err +} + +func (c *CertificateClient) Update(existing *Certificate, updates interface{}) (*Certificate, error) { + resp := &Certificate{} + err := c.apiClient.Ops.DoUpdate(CertificateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CertificateClient) Replace(obj *Certificate) (*Certificate, error) { + resp := &Certificate{} + err := c.apiClient.Ops.DoReplace(CertificateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CertificateClient) List(opts *types.ListOpts) (*CertificateCollection, error) { + resp := &CertificateCollection{} + err := c.apiClient.Ops.DoList(CertificateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CertificateClient) ListAll(opts *types.ListOpts) (*CertificateCollection, error) { + resp := &CertificateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CertificateCollection) Next() (*CertificateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CertificateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CertificateClient) ByID(id string) (*Certificate, error) { + resp := &Certificate{} + err := c.apiClient.Ops.DoByID(CertificateType, id, resp) + return resp, err +} + +func (c *CertificateClient) Delete(container *Certificate) error { + return c.apiClient.Ops.DoResourceDelete(CertificateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_persistent_volume_source.go new file mode 100644 index 0000000..e36020d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + CinderPersistentVolumeSourceType = "cinderPersistentVolumeSource" + CinderPersistentVolumeSourceFieldFSType = "fsType" + CinderPersistentVolumeSourceFieldReadOnly = "readOnly" + CinderPersistentVolumeSourceFieldSecretRef = "secretRef" + CinderPersistentVolumeSourceFieldVolumeID = "volumeID" +) + +type CinderPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_volume_source.go new file mode 100644 index 0000000..ac0a621 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cinder_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + CinderVolumeSourceType = "cinderVolumeSource" + CinderVolumeSourceFieldFSType = "fsType" + CinderVolumeSourceFieldReadOnly = "readOnly" + CinderVolumeSourceFieldSecretRef = "secretRef" + CinderVolumeSourceFieldVolumeID = "volumeID" +) + +type CinderVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_claim_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_claim_source.go new file mode 100644 index 0000000..ee403e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_claim_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ClaimSourceType = "claimSource" + ClaimSourceFieldResourceClaimName = "resourceClaimName" + ClaimSourceFieldResourceClaimTemplateName = "resourceClaimTemplateName" +) + +type ClaimSource struct { + ResourceClaimName string `json:"resourceClaimName,omitempty" yaml:"resourceClaimName,omitempty"` + ResourceClaimTemplateName string `json:"resourceClaimTemplateName,omitempty" yaml:"resourceClaimTemplateName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client.go new file mode 100644 index 0000000..d2d79f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client.go @@ -0,0 +1,82 @@ +package client + +import ( + "github.com/rancher/norman/clientbase" +) + +type Client struct { + clientbase.APIBaseClient + + PersistentVolumeClaim PersistentVolumeClaimOperations + ConfigMap ConfigMapOperations + Ingress IngressOperations + Secret SecretOperations + ServiceAccountToken ServiceAccountTokenOperations + DockerCredential DockerCredentialOperations + Certificate CertificateOperations + BasicAuth BasicAuthOperations + SSHAuth SSHAuthOperations + NamespacedSecret NamespacedSecretOperations + NamespacedServiceAccountToken NamespacedServiceAccountTokenOperations + NamespacedDockerCredential NamespacedDockerCredentialOperations + NamespacedCertificate NamespacedCertificateOperations + NamespacedBasicAuth NamespacedBasicAuthOperations + NamespacedSSHAuth NamespacedSSHAuthOperations + Service ServiceOperations + DNSRecord DNSRecordOperations + Pod PodOperations + Deployment DeploymentOperations + ReplicationController ReplicationControllerOperations + ReplicaSet ReplicaSetOperations + StatefulSet StatefulSetOperations + DaemonSet DaemonSetOperations + Job JobOperations + CronJob CronJobOperations + Workload WorkloadOperations + App AppOperations + AppRevision AppRevisionOperations + HorizontalPodAutoscaler HorizontalPodAutoscalerOperations +} + +func NewClient(opts *clientbase.ClientOpts) (*Client, error) { + baseClient, err := clientbase.NewAPIClient(opts) + if err != nil { + return nil, err + } + + client := &Client{ + APIBaseClient: baseClient, + } + + client.PersistentVolumeClaim = newPersistentVolumeClaimClient(client) + client.ConfigMap = newConfigMapClient(client) + client.Ingress = newIngressClient(client) + client.Secret = newSecretClient(client) + client.ServiceAccountToken = newServiceAccountTokenClient(client) + client.DockerCredential = newDockerCredentialClient(client) + client.Certificate = newCertificateClient(client) + client.BasicAuth = newBasicAuthClient(client) + client.SSHAuth = newSSHAuthClient(client) + client.NamespacedSecret = newNamespacedSecretClient(client) + client.NamespacedServiceAccountToken = newNamespacedServiceAccountTokenClient(client) + client.NamespacedDockerCredential = newNamespacedDockerCredentialClient(client) + client.NamespacedCertificate = newNamespacedCertificateClient(client) + client.NamespacedBasicAuth = newNamespacedBasicAuthClient(client) + client.NamespacedSSHAuth = newNamespacedSSHAuthClient(client) + client.Service = newServiceClient(client) + client.DNSRecord = newDNSRecordClient(client) + client.Pod = newPodClient(client) + client.Deployment = newDeploymentClient(client) + client.ReplicationController = newReplicationControllerClient(client) + client.ReplicaSet = newReplicaSetClient(client) + client.StatefulSet = newStatefulSetClient(client) + client.DaemonSet = newDaemonSetClient(client) + client.Job = newJobClient(client) + client.CronJob = newCronJobClient(client) + client.Workload = newWorkloadClient(client) + client.App = newAppClient(client) + client.AppRevision = newAppRevisionClient(client) + client.HorizontalPodAutoscaler = newHorizontalPodAutoscalerClient(client) + + return client, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client_ipconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client_ipconfig.go new file mode 100644 index 0000000..377baa7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_client_ipconfig.go @@ -0,0 +1,10 @@ +package client + +const ( + ClientIPConfigType = "clientIPConfig" + ClientIPConfigFieldTimeoutSeconds = "timeoutSeconds" +) + +type ClientIPConfig struct { + TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty" yaml:"timeoutSeconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cluster_trust_bundle_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cluster_trust_bundle_projection.go new file mode 100644 index 0000000..61d322d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cluster_trust_bundle_projection.go @@ -0,0 +1,18 @@ +package client + +const ( + ClusterTrustBundleProjectionType = "clusterTrustBundleProjection" + ClusterTrustBundleProjectionFieldLabelSelector = "labelSelector" + ClusterTrustBundleProjectionFieldName = "name" + ClusterTrustBundleProjectionFieldOptional = "optional" + ClusterTrustBundleProjectionFieldPath = "path" + ClusterTrustBundleProjectionFieldSignerName = "signerName" +) + +type ClusterTrustBundleProjection struct { + LabelSelector *LabelSelector `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + SignerName string `json:"signerName,omitempty" yaml:"signerName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_condition.go new file mode 100644 index 0000000..3718c4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + ConditionType = "condition" + ConditionFieldLastTransitionTime = "lastTransitionTime" + ConditionFieldMessage = "message" + ConditionFieldObservedGeneration = "observedGeneration" + ConditionFieldReason = "reason" + ConditionFieldStatus = "status" + ConditionFieldType = "type" +) + +type Condition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map.go new file mode 100644 index 0000000..a5549ae --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ConfigMapType = "configMap" + ConfigMapFieldAnnotations = "annotations" + ConfigMapFieldBinaryData = "binaryData" + ConfigMapFieldCreated = "created" + ConfigMapFieldCreatorID = "creatorId" + ConfigMapFieldData = "data" + ConfigMapFieldImmutable = "immutable" + ConfigMapFieldLabels = "labels" + ConfigMapFieldName = "name" + ConfigMapFieldNamespaceId = "namespaceId" + ConfigMapFieldOwnerReferences = "ownerReferences" + ConfigMapFieldProjectID = "projectId" + ConfigMapFieldRemoved = "removed" + ConfigMapFieldUUID = "uuid" +) + +type ConfigMap struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + BinaryData map[string]string `json:"binaryData,omitempty" yaml:"binaryData,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"` + Immutable *bool `json:"immutable,omitempty" yaml:"immutable,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ConfigMapCollection struct { + types.Collection + Data []ConfigMap `json:"data,omitempty"` + client *ConfigMapClient +} + +type ConfigMapClient struct { + apiClient *Client +} + +type ConfigMapOperations interface { + List(opts *types.ListOpts) (*ConfigMapCollection, error) + ListAll(opts *types.ListOpts) (*ConfigMapCollection, error) + Create(opts *ConfigMap) (*ConfigMap, error) + Update(existing *ConfigMap, updates interface{}) (*ConfigMap, error) + Replace(existing *ConfigMap) (*ConfigMap, error) + ByID(id string) (*ConfigMap, error) + Delete(container *ConfigMap) error +} + +func newConfigMapClient(apiClient *Client) *ConfigMapClient { + return &ConfigMapClient{ + apiClient: apiClient, + } +} + +func (c *ConfigMapClient) Create(container *ConfigMap) (*ConfigMap, error) { + resp := &ConfigMap{} + err := c.apiClient.Ops.DoCreate(ConfigMapType, container, resp) + return resp, err +} + +func (c *ConfigMapClient) Update(existing *ConfigMap, updates interface{}) (*ConfigMap, error) { + resp := &ConfigMap{} + err := c.apiClient.Ops.DoUpdate(ConfigMapType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ConfigMapClient) Replace(obj *ConfigMap) (*ConfigMap, error) { + resp := &ConfigMap{} + err := c.apiClient.Ops.DoReplace(ConfigMapType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ConfigMapClient) List(opts *types.ListOpts) (*ConfigMapCollection, error) { + resp := &ConfigMapCollection{} + err := c.apiClient.Ops.DoList(ConfigMapType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ConfigMapClient) ListAll(opts *types.ListOpts) (*ConfigMapCollection, error) { + resp := &ConfigMapCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ConfigMapCollection) Next() (*ConfigMapCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ConfigMapCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ConfigMapClient) ByID(id string) (*ConfigMap, error) { + resp := &ConfigMap{} + err := c.apiClient.Ops.DoByID(ConfigMapType, id, resp) + return resp, err +} + +func (c *ConfigMapClient) Delete(container *ConfigMap) error { + return c.apiClient.Ops.DoResourceDelete(ConfigMapType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_env_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_env_source.go new file mode 100644 index 0000000..881e144 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_env_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ConfigMapEnvSourceType = "configMapEnvSource" + ConfigMapEnvSourceFieldName = "name" + ConfigMapEnvSourceFieldOptional = "optional" +) + +type ConfigMapEnvSource struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_key_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_key_selector.go new file mode 100644 index 0000000..e1b5991 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_key_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + ConfigMapKeySelectorType = "configMapKeySelector" + ConfigMapKeySelectorFieldKey = "key" + ConfigMapKeySelectorFieldName = "name" + ConfigMapKeySelectorFieldOptional = "optional" +) + +type ConfigMapKeySelector struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_projection.go new file mode 100644 index 0000000..94388a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + ConfigMapProjectionType = "configMapProjection" + ConfigMapProjectionFieldItems = "items" + ConfigMapProjectionFieldName = "name" + ConfigMapProjectionFieldOptional = "optional" +) + +type ConfigMapProjection struct { + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_volume_source.go new file mode 100644 index 0000000..4de7b8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_config_map_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + ConfigMapVolumeSourceType = "configMapVolumeSource" + ConfigMapVolumeSourceFieldDefaultMode = "defaultMode" + ConfigMapVolumeSourceFieldItems = "items" + ConfigMapVolumeSourceFieldName = "name" + ConfigMapVolumeSourceFieldOptional = "optional" +) + +type ConfigMapVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container.go new file mode 100644 index 0000000..445fb8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container.go @@ -0,0 +1,96 @@ +package client + +const ( + ContainerType = "container" + ContainerFieldAllowPrivilegeEscalation = "allowPrivilegeEscalation" + ContainerFieldAppArmorProfile = "appArmorProfile" + ContainerFieldCapAdd = "capAdd" + ContainerFieldCapDrop = "capDrop" + ContainerFieldCommand = "command" + ContainerFieldEntrypoint = "entrypoint" + ContainerFieldEnv = "env" + ContainerFieldEnvFrom = "envFrom" + ContainerFieldEnvironment = "environment" + ContainerFieldEnvironmentFrom = "environmentFrom" + ContainerFieldExitCode = "exitCode" + ContainerFieldImage = "image" + ContainerFieldImagePullPolicy = "imagePullPolicy" + ContainerFieldInitContainer = "initContainer" + ContainerFieldLivenessProbe = "livenessProbe" + ContainerFieldName = "name" + ContainerFieldPorts = "ports" + ContainerFieldPostStart = "postStart" + ContainerFieldPreStop = "preStop" + ContainerFieldPrivileged = "privileged" + ContainerFieldProcMount = "procMount" + ContainerFieldReadOnly = "readOnly" + ContainerFieldReadinessProbe = "readinessProbe" + ContainerFieldResizePolicy = "resizePolicy" + ContainerFieldResources = "resources" + ContainerFieldRestartCount = "restartCount" + ContainerFieldRestartPolicy = "restartPolicy" + ContainerFieldRunAsGroup = "runAsGroup" + ContainerFieldRunAsNonRoot = "runAsNonRoot" + ContainerFieldSeccompProfile = "seccompProfile" + ContainerFieldStartupProbe = "startupProbe" + ContainerFieldState = "state" + ContainerFieldStdin = "stdin" + ContainerFieldStdinOnce = "stdinOnce" + ContainerFieldTTY = "tty" + ContainerFieldTerminationMessagePath = "terminationMessagePath" + ContainerFieldTerminationMessagePolicy = "terminationMessagePolicy" + ContainerFieldTransitioning = "transitioning" + ContainerFieldTransitioningMessage = "transitioningMessage" + ContainerFieldUid = "uid" + ContainerFieldVolumeDevices = "volumeDevices" + ContainerFieldVolumeMounts = "volumeMounts" + ContainerFieldWindowsOptions = "windowsOptions" + ContainerFieldWorkingDir = "workingDir" +) + +type Container struct { + AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty" yaml:"allowPrivilegeEscalation,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + CapAdd []string `json:"capAdd,omitempty" yaml:"capAdd,omitempty"` + CapDrop []string `json:"capDrop,omitempty" yaml:"capDrop,omitempty"` + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + Entrypoint []string `json:"entrypoint,omitempty" yaml:"entrypoint,omitempty"` + Env []EnvVar `json:"env,omitempty" yaml:"env,omitempty"` + EnvFrom []EnvFromSource `json:"envFrom,omitempty" yaml:"envFrom,omitempty"` + Environment map[string]string `json:"environment,omitempty" yaml:"environment,omitempty"` + EnvironmentFrom []EnvironmentFrom `json:"environmentFrom,omitempty" yaml:"environmentFrom,omitempty"` + ExitCode *int64 `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"` + InitContainer bool `json:"initContainer,omitempty" yaml:"initContainer,omitempty"` + LivenessProbe *Probe `json:"livenessProbe,omitempty" yaml:"livenessProbe,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Ports []ContainerPort `json:"ports,omitempty" yaml:"ports,omitempty"` + PostStart *LifecycleHandler `json:"postStart,omitempty" yaml:"postStart,omitempty"` + PreStop *LifecycleHandler `json:"preStop,omitempty" yaml:"preStop,omitempty"` + Privileged *bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` + ProcMount string `json:"procMount,omitempty" yaml:"procMount,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + ReadinessProbe *Probe `json:"readinessProbe,omitempty" yaml:"readinessProbe,omitempty"` + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" yaml:"resizePolicy,omitempty"` + Resources *ResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + RestartCount int64 `json:"restartCount,omitempty" yaml:"restartCount,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + StartupProbe *Probe `json:"startupProbe,omitempty" yaml:"startupProbe,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Stdin bool `json:"stdin,omitempty" yaml:"stdin,omitempty"` + StdinOnce bool `json:"stdinOnce,omitempty" yaml:"stdinOnce,omitempty"` + TTY bool `json:"tty,omitempty" yaml:"tty,omitempty"` + TerminationMessagePath string `json:"terminationMessagePath,omitempty" yaml:"terminationMessagePath,omitempty"` + TerminationMessagePolicy string `json:"terminationMessagePolicy,omitempty" yaml:"terminationMessagePolicy,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + VolumeDevices []VolumeDevice `json:"volumeDevices,omitempty" yaml:"volumeDevices,omitempty"` + VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" yaml:"volumeMounts,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_port.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_port.go new file mode 100644 index 0000000..f981498 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_port.go @@ -0,0 +1,24 @@ +package client + +const ( + ContainerPortType = "containerPort" + ContainerPortFieldContainerPort = "containerPort" + ContainerPortFieldDNSName = "dnsName" + ContainerPortFieldHostIp = "hostIp" + ContainerPortFieldHostPort = "hostPort" + ContainerPortFieldKind = "kind" + ContainerPortFieldName = "name" + ContainerPortFieldProtocol = "protocol" + ContainerPortFieldSourcePort = "sourcePort" +) + +type ContainerPort struct { + ContainerPort int64 `json:"containerPort,omitempty" yaml:"containerPort,omitempty"` + DNSName string `json:"dnsName,omitempty" yaml:"dnsName,omitempty"` + HostIp string `json:"hostIp,omitempty" yaml:"hostIp,omitempty"` + HostPort int64 `json:"hostPort,omitempty" yaml:"hostPort,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + SourcePort int64 `json:"sourcePort,omitempty" yaml:"sourcePort,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resize_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resize_policy.go new file mode 100644 index 0000000..ad3dfed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resize_policy.go @@ -0,0 +1,12 @@ +package client + +const ( + ContainerResizePolicyType = "containerResizePolicy" + ContainerResizePolicyFieldResourceName = "resourceName" + ContainerResizePolicyFieldRestartPolicy = "restartPolicy" +) + +type ContainerResizePolicy struct { + ResourceName string `json:"resourceName,omitempty" yaml:"resourceName,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_source.go new file mode 100644 index 0000000..481b0ce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_source.go @@ -0,0 +1,14 @@ +package client + +const ( + ContainerResourceMetricSourceType = "containerResourceMetricSource" + ContainerResourceMetricSourceFieldContainer = "container" + ContainerResourceMetricSourceFieldName = "name" + ContainerResourceMetricSourceFieldTarget = "target" +) + +type ContainerResourceMetricSource struct { + Container string `json:"container,omitempty" yaml:"container,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_status.go new file mode 100644 index 0000000..2f5c33b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_resource_metric_status.go @@ -0,0 +1,14 @@ +package client + +const ( + ContainerResourceMetricStatusType = "containerResourceMetricStatus" + ContainerResourceMetricStatusFieldContainer = "container" + ContainerResourceMetricStatusFieldCurrent = "current" + ContainerResourceMetricStatusFieldName = "name" +) + +type ContainerResourceMetricStatus struct { + Container string `json:"container,omitempty" yaml:"container,omitempty"` + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state.go new file mode 100644 index 0000000..a648e7c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state.go @@ -0,0 +1,14 @@ +package client + +const ( + ContainerStateType = "containerState" + ContainerStateFieldRunning = "running" + ContainerStateFieldTerminated = "terminated" + ContainerStateFieldWaiting = "waiting" +) + +type ContainerState struct { + Running *ContainerStateRunning `json:"running,omitempty" yaml:"running,omitempty"` + Terminated *ContainerStateTerminated `json:"terminated,omitempty" yaml:"terminated,omitempty"` + Waiting *ContainerStateWaiting `json:"waiting,omitempty" yaml:"waiting,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_running.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_running.go new file mode 100644 index 0000000..d0ae392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_running.go @@ -0,0 +1,10 @@ +package client + +const ( + ContainerStateRunningType = "containerStateRunning" + ContainerStateRunningFieldStartedAt = "startedAt" +) + +type ContainerStateRunning struct { + StartedAt string `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_terminated.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_terminated.go new file mode 100644 index 0000000..409b3bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_terminated.go @@ -0,0 +1,22 @@ +package client + +const ( + ContainerStateTerminatedType = "containerStateTerminated" + ContainerStateTerminatedFieldContainerID = "containerID" + ContainerStateTerminatedFieldExitCode = "exitCode" + ContainerStateTerminatedFieldFinishedAt = "finishedAt" + ContainerStateTerminatedFieldMessage = "message" + ContainerStateTerminatedFieldReason = "reason" + ContainerStateTerminatedFieldSignal = "signal" + ContainerStateTerminatedFieldStartedAt = "startedAt" +) + +type ContainerStateTerminated struct { + ContainerID string `json:"containerID,omitempty" yaml:"containerID,omitempty"` + ExitCode int64 `json:"exitCode,omitempty" yaml:"exitCode,omitempty"` + FinishedAt string `json:"finishedAt,omitempty" yaml:"finishedAt,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Signal int64 `json:"signal,omitempty" yaml:"signal,omitempty"` + StartedAt string `json:"startedAt,omitempty" yaml:"startedAt,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_waiting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_waiting.go new file mode 100644 index 0000000..c420f93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_state_waiting.go @@ -0,0 +1,12 @@ +package client + +const ( + ContainerStateWaitingType = "containerStateWaiting" + ContainerStateWaitingFieldMessage = "message" + ContainerStateWaitingFieldReason = "reason" +) + +type ContainerStateWaiting struct { + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_status.go new file mode 100644 index 0000000..49b6c3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_container_status.go @@ -0,0 +1,32 @@ +package client + +const ( + ContainerStatusType = "containerStatus" + ContainerStatusFieldAllocatedResources = "allocatedResources" + ContainerStatusFieldContainerID = "containerID" + ContainerStatusFieldImage = "image" + ContainerStatusFieldImageID = "imageID" + ContainerStatusFieldLastTerminationState = "lastState" + ContainerStatusFieldName = "name" + ContainerStatusFieldReady = "ready" + ContainerStatusFieldResources = "resources" + ContainerStatusFieldRestartCount = "restartCount" + ContainerStatusFieldStarted = "started" + ContainerStatusFieldState = "state" + ContainerStatusFieldVolumeMounts = "volumeMounts" +) + +type ContainerStatus struct { + AllocatedResources map[string]string `json:"allocatedResources,omitempty" yaml:"allocatedResources,omitempty"` + ContainerID string `json:"containerID,omitempty" yaml:"containerID,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImageID string `json:"imageID,omitempty" yaml:"imageID,omitempty"` + LastTerminationState *ContainerState `json:"lastState,omitempty" yaml:"lastState,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Ready bool `json:"ready,omitempty" yaml:"ready,omitempty"` + Resources *ResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + RestartCount int64 `json:"restartCount,omitempty" yaml:"restartCount,omitempty"` + Started *bool `json:"started,omitempty" yaml:"started,omitempty"` + State *ContainerState `json:"state,omitempty" yaml:"state,omitempty"` + VolumeMounts []VolumeMountStatus `json:"volumeMounts,omitempty" yaml:"volumeMounts,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job.go new file mode 100644 index 0000000..be444f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job.go @@ -0,0 +1,249 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + CronJobType = "cronJob" + CronJobFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + CronJobFieldAnnotations = "annotations" + CronJobFieldAppArmorProfile = "appArmorProfile" + CronJobFieldAutomountServiceAccountToken = "automountServiceAccountToken" + CronJobFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + CronJobFieldCompletionMode = "completionMode" + CronJobFieldContainers = "containers" + CronJobFieldCreated = "created" + CronJobFieldCreatorID = "creatorId" + CronJobFieldCronJobConfig = "cronJobConfig" + CronJobFieldCronJobStatus = "cronJobStatus" + CronJobFieldDNSConfig = "dnsConfig" + CronJobFieldDNSPolicy = "dnsPolicy" + CronJobFieldEnableServiceLinks = "enableServiceLinks" + CronJobFieldEphemeralContainers = "ephemeralContainers" + CronJobFieldFSGroupChangePolicy = "fsGroupChangePolicy" + CronJobFieldFsgid = "fsgid" + CronJobFieldGids = "gids" + CronJobFieldHostAliases = "hostAliases" + CronJobFieldHostIPC = "hostIPC" + CronJobFieldHostNetwork = "hostNetwork" + CronJobFieldHostPID = "hostPID" + CronJobFieldHostUsers = "hostUsers" + CronJobFieldHostname = "hostname" + CronJobFieldImagePullSecrets = "imagePullSecrets" + CronJobFieldLabels = "labels" + CronJobFieldManagedBy = "managedBy" + CronJobFieldMaxFailedIndexes = "maxFailedIndexes" + CronJobFieldName = "name" + CronJobFieldNamespaceId = "namespaceId" + CronJobFieldNodeID = "nodeId" + CronJobFieldOS = "os" + CronJobFieldOverhead = "overhead" + CronJobFieldOwnerReferences = "ownerReferences" + CronJobFieldPodFailurePolicy = "podFailurePolicy" + CronJobFieldPodReplacementPolicy = "podReplacementPolicy" + CronJobFieldPreemptionPolicy = "preemptionPolicy" + CronJobFieldProjectID = "projectId" + CronJobFieldPublicEndpoints = "publicEndpoints" + CronJobFieldReadinessGates = "readinessGates" + CronJobFieldRemoved = "removed" + CronJobFieldResourceClaims = "resourceClaims" + CronJobFieldRestartPolicy = "restartPolicy" + CronJobFieldRunAsGroup = "runAsGroup" + CronJobFieldRunAsNonRoot = "runAsNonRoot" + CronJobFieldRuntimeClassName = "runtimeClassName" + CronJobFieldScheduling = "scheduling" + CronJobFieldSchedulingGates = "schedulingGates" + CronJobFieldSeccompProfile = "seccompProfile" + CronJobFieldSelector = "selector" + CronJobFieldServiceAccountName = "serviceAccountName" + CronJobFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + CronJobFieldShareProcessNamespace = "shareProcessNamespace" + CronJobFieldState = "state" + CronJobFieldSubdomain = "subdomain" + CronJobFieldSuccessPolicy = "successPolicy" + CronJobFieldSysctls = "sysctls" + CronJobFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + CronJobFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + CronJobFieldTimeZone = "timeZone" + CronJobFieldTopologySpreadConstraints = "topologySpreadConstraints" + CronJobFieldTransitioning = "transitioning" + CronJobFieldTransitioningMessage = "transitioningMessage" + CronJobFieldUUID = "uuid" + CronJobFieldUid = "uid" + CronJobFieldVolumes = "volumes" + CronJobFieldWindowsOptions = "windowsOptions" + CronJobFieldWorkloadAnnotations = "workloadAnnotations" + CronJobFieldWorkloadLabels = "workloadLabels" + CronJobFieldWorkloadMetrics = "workloadMetrics" +) + +type CronJob struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CronJobConfig *CronJobConfig `json:"cronJobConfig,omitempty" yaml:"cronJobConfig,omitempty"` + CronJobStatus *CronJobStatus `json:"cronJobStatus,omitempty" yaml:"cronJobStatus,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TimeZone string `json:"timeZone,omitempty" yaml:"timeZone,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type CronJobCollection struct { + types.Collection + Data []CronJob `json:"data,omitempty"` + client *CronJobClient +} + +type CronJobClient struct { + apiClient *Client +} + +type CronJobOperations interface { + List(opts *types.ListOpts) (*CronJobCollection, error) + ListAll(opts *types.ListOpts) (*CronJobCollection, error) + Create(opts *CronJob) (*CronJob, error) + Update(existing *CronJob, updates interface{}) (*CronJob, error) + Replace(existing *CronJob) (*CronJob, error) + ByID(id string) (*CronJob, error) + Delete(container *CronJob) error + + ActionRedeploy(resource *CronJob) error +} + +func newCronJobClient(apiClient *Client) *CronJobClient { + return &CronJobClient{ + apiClient: apiClient, + } +} + +func (c *CronJobClient) Create(container *CronJob) (*CronJob, error) { + resp := &CronJob{} + err := c.apiClient.Ops.DoCreate(CronJobType, container, resp) + return resp, err +} + +func (c *CronJobClient) Update(existing *CronJob, updates interface{}) (*CronJob, error) { + resp := &CronJob{} + err := c.apiClient.Ops.DoUpdate(CronJobType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *CronJobClient) Replace(obj *CronJob) (*CronJob, error) { + resp := &CronJob{} + err := c.apiClient.Ops.DoReplace(CronJobType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *CronJobClient) List(opts *types.ListOpts) (*CronJobCollection, error) { + resp := &CronJobCollection{} + err := c.apiClient.Ops.DoList(CronJobType, opts, resp) + resp.client = c + return resp, err +} + +func (c *CronJobClient) ListAll(opts *types.ListOpts) (*CronJobCollection, error) { + resp := &CronJobCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *CronJobCollection) Next() (*CronJobCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &CronJobCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *CronJobClient) ByID(id string) (*CronJob, error) { + resp := &CronJob{} + err := c.apiClient.Ops.DoByID(CronJobType, id, resp) + return resp, err +} + +func (c *CronJobClient) Delete(container *CronJob) error { + return c.apiClient.Ops.DoResourceDelete(CronJobType, &container.Resource) +} + +func (c *CronJobClient) ActionRedeploy(resource *CronJob) error { + err := c.apiClient.Ops.DoAction(CronJobType, "redeploy", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_config.go new file mode 100644 index 0000000..f378c41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_config.go @@ -0,0 +1,26 @@ +package client + +const ( + CronJobConfigType = "cronJobConfig" + CronJobConfigFieldConcurrencyPolicy = "concurrencyPolicy" + CronJobConfigFieldFailedJobsHistoryLimit = "failedJobsHistoryLimit" + CronJobConfigFieldJobAnnotations = "jobAnnotations" + CronJobConfigFieldJobConfig = "jobConfig" + CronJobConfigFieldJobLabels = "jobLabels" + CronJobConfigFieldSchedule = "schedule" + CronJobConfigFieldStartingDeadlineSeconds = "startingDeadlineSeconds" + CronJobConfigFieldSuccessfulJobsHistoryLimit = "successfulJobsHistoryLimit" + CronJobConfigFieldSuspend = "suspend" +) + +type CronJobConfig struct { + ConcurrencyPolicy string `json:"concurrencyPolicy,omitempty" yaml:"concurrencyPolicy,omitempty"` + FailedJobsHistoryLimit *int64 `json:"failedJobsHistoryLimit,omitempty" yaml:"failedJobsHistoryLimit,omitempty"` + JobAnnotations map[string]string `json:"jobAnnotations,omitempty" yaml:"jobAnnotations,omitempty"` + JobConfig *JobConfig `json:"jobConfig,omitempty" yaml:"jobConfig,omitempty"` + JobLabels map[string]string `json:"jobLabels,omitempty" yaml:"jobLabels,omitempty"` + Schedule string `json:"schedule,omitempty" yaml:"schedule,omitempty"` + StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty" yaml:"startingDeadlineSeconds,omitempty"` + SuccessfulJobsHistoryLimit *int64 `json:"successfulJobsHistoryLimit,omitempty" yaml:"successfulJobsHistoryLimit,omitempty"` + Suspend *bool `json:"suspend,omitempty" yaml:"suspend,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_spec.go new file mode 100644 index 0000000..659ef66 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_spec.go @@ -0,0 +1,114 @@ +package client + +const ( + CronJobSpecType = "cronJobSpec" + CronJobSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + CronJobSpecFieldAppArmorProfile = "appArmorProfile" + CronJobSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + CronJobSpecFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + CronJobSpecFieldCompletionMode = "completionMode" + CronJobSpecFieldContainers = "containers" + CronJobSpecFieldCronJobConfig = "cronJobConfig" + CronJobSpecFieldDNSConfig = "dnsConfig" + CronJobSpecFieldDNSPolicy = "dnsPolicy" + CronJobSpecFieldEnableServiceLinks = "enableServiceLinks" + CronJobSpecFieldEphemeralContainers = "ephemeralContainers" + CronJobSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + CronJobSpecFieldFsgid = "fsgid" + CronJobSpecFieldGids = "gids" + CronJobSpecFieldHostAliases = "hostAliases" + CronJobSpecFieldHostIPC = "hostIPC" + CronJobSpecFieldHostNetwork = "hostNetwork" + CronJobSpecFieldHostPID = "hostPID" + CronJobSpecFieldHostUsers = "hostUsers" + CronJobSpecFieldHostname = "hostname" + CronJobSpecFieldImagePullSecrets = "imagePullSecrets" + CronJobSpecFieldManagedBy = "managedBy" + CronJobSpecFieldMaxFailedIndexes = "maxFailedIndexes" + CronJobSpecFieldNodeID = "nodeId" + CronJobSpecFieldOS = "os" + CronJobSpecFieldObjectMeta = "metadata" + CronJobSpecFieldOverhead = "overhead" + CronJobSpecFieldPodFailurePolicy = "podFailurePolicy" + CronJobSpecFieldPodReplacementPolicy = "podReplacementPolicy" + CronJobSpecFieldPreemptionPolicy = "preemptionPolicy" + CronJobSpecFieldReadinessGates = "readinessGates" + CronJobSpecFieldResourceClaims = "resourceClaims" + CronJobSpecFieldRestartPolicy = "restartPolicy" + CronJobSpecFieldRunAsGroup = "runAsGroup" + CronJobSpecFieldRunAsNonRoot = "runAsNonRoot" + CronJobSpecFieldRuntimeClassName = "runtimeClassName" + CronJobSpecFieldScheduling = "scheduling" + CronJobSpecFieldSchedulingGates = "schedulingGates" + CronJobSpecFieldSeccompProfile = "seccompProfile" + CronJobSpecFieldSelector = "selector" + CronJobSpecFieldServiceAccountName = "serviceAccountName" + CronJobSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + CronJobSpecFieldShareProcessNamespace = "shareProcessNamespace" + CronJobSpecFieldSubdomain = "subdomain" + CronJobSpecFieldSuccessPolicy = "successPolicy" + CronJobSpecFieldSysctls = "sysctls" + CronJobSpecFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + CronJobSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + CronJobSpecFieldTimeZone = "timeZone" + CronJobSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + CronJobSpecFieldUid = "uid" + CronJobSpecFieldVolumes = "volumes" + CronJobSpecFieldWindowsOptions = "windowsOptions" +) + +type CronJobSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + CronJobConfig *CronJobConfig `json:"cronJobConfig,omitempty" yaml:"cronJobConfig,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TimeZone string `json:"timeZone,omitempty" yaml:"timeZone,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_status.go new file mode 100644 index 0000000..64eba04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cron_job_status.go @@ -0,0 +1,14 @@ +package client + +const ( + CronJobStatusType = "cronJobStatus" + CronJobStatusFieldActive = "active" + CronJobStatusFieldLastScheduleTime = "lastScheduleTime" + CronJobStatusFieldLastSuccessfulTime = "lastSuccessfulTime" +) + +type CronJobStatus struct { + Active []ObjectReference `json:"active,omitempty" yaml:"active,omitempty"` + LastScheduleTime string `json:"lastScheduleTime,omitempty" yaml:"lastScheduleTime,omitempty"` + LastSuccessfulTime string `json:"lastSuccessfulTime,omitempty" yaml:"lastSuccessfulTime,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cross_version_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cross_version_object_reference.go new file mode 100644 index 0000000..9e9699e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_cross_version_object_reference.go @@ -0,0 +1,14 @@ +package client + +const ( + CrossVersionObjectReferenceType = "crossVersionObjectReference" + CrossVersionObjectReferenceFieldAPIVersion = "apiVersion" + CrossVersionObjectReferenceFieldKind = "kind" + CrossVersionObjectReferenceFieldName = "name" +) + +type CrossVersionObjectReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_persistent_volume_source.go new file mode 100644 index 0000000..8fadfe0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_persistent_volume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + CSIPersistentVolumeSourceType = "csiPersistentVolumeSource" + CSIPersistentVolumeSourceFieldControllerExpandSecretRef = "controllerExpandSecretRef" + CSIPersistentVolumeSourceFieldControllerPublishSecretRef = "controllerPublishSecretRef" + CSIPersistentVolumeSourceFieldDriver = "driver" + CSIPersistentVolumeSourceFieldFSType = "fsType" + CSIPersistentVolumeSourceFieldNodeExpandSecretRef = "nodeExpandSecretRef" + CSIPersistentVolumeSourceFieldNodePublishSecretRef = "nodePublishSecretRef" + CSIPersistentVolumeSourceFieldNodeStageSecretRef = "nodeStageSecretRef" + CSIPersistentVolumeSourceFieldReadOnly = "readOnly" + CSIPersistentVolumeSourceFieldVolumeAttributes = "volumeAttributes" + CSIPersistentVolumeSourceFieldVolumeHandle = "volumeHandle" +) + +type CSIPersistentVolumeSource struct { + ControllerExpandSecretRef *SecretReference `json:"controllerExpandSecretRef,omitempty" yaml:"controllerExpandSecretRef,omitempty"` + ControllerPublishSecretRef *SecretReference `json:"controllerPublishSecretRef,omitempty" yaml:"controllerPublishSecretRef,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + NodeExpandSecretRef *SecretReference `json:"nodeExpandSecretRef,omitempty" yaml:"nodeExpandSecretRef,omitempty"` + NodePublishSecretRef *SecretReference `json:"nodePublishSecretRef,omitempty" yaml:"nodePublishSecretRef,omitempty"` + NodeStageSecretRef *SecretReference `json:"nodeStageSecretRef,omitempty" yaml:"nodeStageSecretRef,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeAttributes map[string]string `json:"volumeAttributes,omitempty" yaml:"volumeAttributes,omitempty"` + VolumeHandle string `json:"volumeHandle,omitempty" yaml:"volumeHandle,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_volume_source.go new file mode 100644 index 0000000..f341d53 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_csi_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + CSIVolumeSourceType = "csiVolumeSource" + CSIVolumeSourceFieldDriver = "driver" + CSIVolumeSourceFieldFSType = "fsType" + CSIVolumeSourceFieldNodePublishSecretRef = "nodePublishSecretRef" + CSIVolumeSourceFieldReadOnly = "readOnly" + CSIVolumeSourceFieldVolumeAttributes = "volumeAttributes" +) + +type CSIVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + NodePublishSecretRef *LocalObjectReference `json:"nodePublishSecretRef,omitempty" yaml:"nodePublishSecretRef,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeAttributes map[string]string `json:"volumeAttributes,omitempty" yaml:"volumeAttributes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set.go new file mode 100644 index 0000000..1bf9e02 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set.go @@ -0,0 +1,235 @@ +package client + +import ( + "github.com/rancher/norman/types" + + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DaemonSetType = "daemonSet" + DaemonSetFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + DaemonSetFieldAnnotations = "annotations" + DaemonSetFieldAppArmorProfile = "appArmorProfile" + DaemonSetFieldAutomountServiceAccountToken = "automountServiceAccountToken" + DaemonSetFieldContainers = "containers" + DaemonSetFieldCreated = "created" + DaemonSetFieldCreatorID = "creatorId" + DaemonSetFieldDNSConfig = "dnsConfig" + DaemonSetFieldDNSPolicy = "dnsPolicy" + DaemonSetFieldDaemonSetConfig = "daemonSetConfig" + DaemonSetFieldDaemonSetStatus = "daemonSetStatus" + DaemonSetFieldEnableServiceLinks = "enableServiceLinks" + DaemonSetFieldEphemeralContainers = "ephemeralContainers" + DaemonSetFieldFSGroupChangePolicy = "fsGroupChangePolicy" + DaemonSetFieldFsgid = "fsgid" + DaemonSetFieldGids = "gids" + DaemonSetFieldHostAliases = "hostAliases" + DaemonSetFieldHostIPC = "hostIPC" + DaemonSetFieldHostNetwork = "hostNetwork" + DaemonSetFieldHostPID = "hostPID" + DaemonSetFieldHostUsers = "hostUsers" + DaemonSetFieldHostname = "hostname" + DaemonSetFieldImagePullSecrets = "imagePullSecrets" + DaemonSetFieldLabels = "labels" + DaemonSetFieldMaxSurge = "maxSurge" + DaemonSetFieldName = "name" + DaemonSetFieldNamespaceId = "namespaceId" + DaemonSetFieldNodeID = "nodeId" + DaemonSetFieldOS = "os" + DaemonSetFieldOverhead = "overhead" + DaemonSetFieldOwnerReferences = "ownerReferences" + DaemonSetFieldPreemptionPolicy = "preemptionPolicy" + DaemonSetFieldProjectID = "projectId" + DaemonSetFieldPublicEndpoints = "publicEndpoints" + DaemonSetFieldReadinessGates = "readinessGates" + DaemonSetFieldRemoved = "removed" + DaemonSetFieldResourceClaims = "resourceClaims" + DaemonSetFieldRestartPolicy = "restartPolicy" + DaemonSetFieldRunAsGroup = "runAsGroup" + DaemonSetFieldRunAsNonRoot = "runAsNonRoot" + DaemonSetFieldRuntimeClassName = "runtimeClassName" + DaemonSetFieldScheduling = "scheduling" + DaemonSetFieldSchedulingGates = "schedulingGates" + DaemonSetFieldSeccompProfile = "seccompProfile" + DaemonSetFieldSelector = "selector" + DaemonSetFieldServiceAccountName = "serviceAccountName" + DaemonSetFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + DaemonSetFieldShareProcessNamespace = "shareProcessNamespace" + DaemonSetFieldState = "state" + DaemonSetFieldSubdomain = "subdomain" + DaemonSetFieldSysctls = "sysctls" + DaemonSetFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + DaemonSetFieldTopologySpreadConstraints = "topologySpreadConstraints" + DaemonSetFieldTransitioning = "transitioning" + DaemonSetFieldTransitioningMessage = "transitioningMessage" + DaemonSetFieldUUID = "uuid" + DaemonSetFieldUid = "uid" + DaemonSetFieldVolumes = "volumes" + DaemonSetFieldWindowsOptions = "windowsOptions" + DaemonSetFieldWorkloadAnnotations = "workloadAnnotations" + DaemonSetFieldWorkloadLabels = "workloadLabels" + DaemonSetFieldWorkloadMetrics = "workloadMetrics" +) + +type DaemonSet struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DaemonSetConfig *DaemonSetConfig `json:"daemonSetConfig,omitempty" yaml:"daemonSetConfig,omitempty"` + DaemonSetStatus *DaemonSetStatus `json:"daemonSetStatus,omitempty" yaml:"daemonSetStatus,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type DaemonSetCollection struct { + types.Collection + Data []DaemonSet `json:"data,omitempty"` + client *DaemonSetClient +} + +type DaemonSetClient struct { + apiClient *Client +} + +type DaemonSetOperations interface { + List(opts *types.ListOpts) (*DaemonSetCollection, error) + ListAll(opts *types.ListOpts) (*DaemonSetCollection, error) + Create(opts *DaemonSet) (*DaemonSet, error) + Update(existing *DaemonSet, updates interface{}) (*DaemonSet, error) + Replace(existing *DaemonSet) (*DaemonSet, error) + ByID(id string) (*DaemonSet, error) + Delete(container *DaemonSet) error + + ActionRedeploy(resource *DaemonSet) error +} + +func newDaemonSetClient(apiClient *Client) *DaemonSetClient { + return &DaemonSetClient{ + apiClient: apiClient, + } +} + +func (c *DaemonSetClient) Create(container *DaemonSet) (*DaemonSet, error) { + resp := &DaemonSet{} + err := c.apiClient.Ops.DoCreate(DaemonSetType, container, resp) + return resp, err +} + +func (c *DaemonSetClient) Update(existing *DaemonSet, updates interface{}) (*DaemonSet, error) { + resp := &DaemonSet{} + err := c.apiClient.Ops.DoUpdate(DaemonSetType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *DaemonSetClient) Replace(obj *DaemonSet) (*DaemonSet, error) { + resp := &DaemonSet{} + err := c.apiClient.Ops.DoReplace(DaemonSetType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *DaemonSetClient) List(opts *types.ListOpts) (*DaemonSetCollection, error) { + resp := &DaemonSetCollection{} + err := c.apiClient.Ops.DoList(DaemonSetType, opts, resp) + resp.client = c + return resp, err +} + +func (c *DaemonSetClient) ListAll(opts *types.ListOpts) (*DaemonSetCollection, error) { + resp := &DaemonSetCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *DaemonSetCollection) Next() (*DaemonSetCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &DaemonSetCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *DaemonSetClient) ByID(id string) (*DaemonSet, error) { + resp := &DaemonSet{} + err := c.apiClient.Ops.DoByID(DaemonSetType, id, resp) + return resp, err +} + +func (c *DaemonSetClient) Delete(container *DaemonSet) error { + return c.apiClient.Ops.DoResourceDelete(DaemonSetType, &container.Resource) +} + +func (c *DaemonSetClient) ActionRedeploy(resource *DaemonSet) error { + err := c.apiClient.Ops.DoAction(DaemonSetType, "redeploy", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_condition.go new file mode 100644 index 0000000..3941903 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + DaemonSetConditionType = "daemonSetCondition" + DaemonSetConditionFieldLastTransitionTime = "lastTransitionTime" + DaemonSetConditionFieldMessage = "message" + DaemonSetConditionFieldReason = "reason" + DaemonSetConditionFieldStatus = "status" + DaemonSetConditionFieldType = "type" +) + +type DaemonSetCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_config.go new file mode 100644 index 0000000..0670035 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_config.go @@ -0,0 +1,20 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DaemonSetConfigType = "daemonSetConfig" + DaemonSetConfigFieldMaxUnavailable = "maxUnavailable" + DaemonSetConfigFieldMinReadySeconds = "minReadySeconds" + DaemonSetConfigFieldRevisionHistoryLimit = "revisionHistoryLimit" + DaemonSetConfigFieldStrategy = "strategy" +) + +type DaemonSetConfig struct { + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` + RevisionHistoryLimit *int64 `json:"revisionHistoryLimit,omitempty" yaml:"revisionHistoryLimit,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_spec.go new file mode 100644 index 0000000..ac7074a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_spec.go @@ -0,0 +1,102 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DaemonSetSpecType = "daemonSetSpec" + DaemonSetSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + DaemonSetSpecFieldAppArmorProfile = "appArmorProfile" + DaemonSetSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + DaemonSetSpecFieldContainers = "containers" + DaemonSetSpecFieldDNSConfig = "dnsConfig" + DaemonSetSpecFieldDNSPolicy = "dnsPolicy" + DaemonSetSpecFieldDaemonSetConfig = "daemonSetConfig" + DaemonSetSpecFieldEnableServiceLinks = "enableServiceLinks" + DaemonSetSpecFieldEphemeralContainers = "ephemeralContainers" + DaemonSetSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + DaemonSetSpecFieldFsgid = "fsgid" + DaemonSetSpecFieldGids = "gids" + DaemonSetSpecFieldHostAliases = "hostAliases" + DaemonSetSpecFieldHostIPC = "hostIPC" + DaemonSetSpecFieldHostNetwork = "hostNetwork" + DaemonSetSpecFieldHostPID = "hostPID" + DaemonSetSpecFieldHostUsers = "hostUsers" + DaemonSetSpecFieldHostname = "hostname" + DaemonSetSpecFieldImagePullSecrets = "imagePullSecrets" + DaemonSetSpecFieldMaxSurge = "maxSurge" + DaemonSetSpecFieldNodeID = "nodeId" + DaemonSetSpecFieldOS = "os" + DaemonSetSpecFieldObjectMeta = "metadata" + DaemonSetSpecFieldOverhead = "overhead" + DaemonSetSpecFieldPreemptionPolicy = "preemptionPolicy" + DaemonSetSpecFieldReadinessGates = "readinessGates" + DaemonSetSpecFieldResourceClaims = "resourceClaims" + DaemonSetSpecFieldRestartPolicy = "restartPolicy" + DaemonSetSpecFieldRunAsGroup = "runAsGroup" + DaemonSetSpecFieldRunAsNonRoot = "runAsNonRoot" + DaemonSetSpecFieldRuntimeClassName = "runtimeClassName" + DaemonSetSpecFieldScheduling = "scheduling" + DaemonSetSpecFieldSchedulingGates = "schedulingGates" + DaemonSetSpecFieldSeccompProfile = "seccompProfile" + DaemonSetSpecFieldSelector = "selector" + DaemonSetSpecFieldServiceAccountName = "serviceAccountName" + DaemonSetSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + DaemonSetSpecFieldShareProcessNamespace = "shareProcessNamespace" + DaemonSetSpecFieldSubdomain = "subdomain" + DaemonSetSpecFieldSysctls = "sysctls" + DaemonSetSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + DaemonSetSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + DaemonSetSpecFieldUid = "uid" + DaemonSetSpecFieldVolumes = "volumes" + DaemonSetSpecFieldWindowsOptions = "windowsOptions" +) + +type DaemonSetSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DaemonSetConfig *DaemonSetConfig `json:"daemonSetConfig,omitempty" yaml:"daemonSetConfig,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_status.go new file mode 100644 index 0000000..6777a41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_status.go @@ -0,0 +1,28 @@ +package client + +const ( + DaemonSetStatusType = "daemonSetStatus" + DaemonSetStatusFieldCollisionCount = "collisionCount" + DaemonSetStatusFieldConditions = "conditions" + DaemonSetStatusFieldCurrentNumberScheduled = "currentNumberScheduled" + DaemonSetStatusFieldDesiredNumberScheduled = "desiredNumberScheduled" + DaemonSetStatusFieldNumberAvailable = "numberAvailable" + DaemonSetStatusFieldNumberMisscheduled = "numberMisscheduled" + DaemonSetStatusFieldNumberReady = "numberReady" + DaemonSetStatusFieldNumberUnavailable = "numberUnavailable" + DaemonSetStatusFieldObservedGeneration = "observedGeneration" + DaemonSetStatusFieldUpdatedNumberScheduled = "updatedNumberScheduled" +) + +type DaemonSetStatus struct { + CollisionCount *int64 `json:"collisionCount,omitempty" yaml:"collisionCount,omitempty"` + Conditions []DaemonSetCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CurrentNumberScheduled int64 `json:"currentNumberScheduled,omitempty" yaml:"currentNumberScheduled,omitempty"` + DesiredNumberScheduled int64 `json:"desiredNumberScheduled,omitempty" yaml:"desiredNumberScheduled,omitempty"` + NumberAvailable int64 `json:"numberAvailable,omitempty" yaml:"numberAvailable,omitempty"` + NumberMisscheduled int64 `json:"numberMisscheduled,omitempty" yaml:"numberMisscheduled,omitempty"` + NumberReady int64 `json:"numberReady,omitempty" yaml:"numberReady,omitempty"` + NumberUnavailable int64 `json:"numberUnavailable,omitempty" yaml:"numberUnavailable,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + UpdatedNumberScheduled int64 `json:"updatedNumberScheduled,omitempty" yaml:"updatedNumberScheduled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_update_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_update_strategy.go new file mode 100644 index 0000000..98a0882 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_daemon_set_update_strategy.go @@ -0,0 +1,18 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DaemonSetUpdateStrategyType = "daemonSetUpdateStrategy" + DaemonSetUpdateStrategyFieldMaxSurge = "maxSurge" + DaemonSetUpdateStrategyFieldMaxUnavailable = "maxUnavailable" + DaemonSetUpdateStrategyFieldStrategy = "strategy" +) + +type DaemonSetUpdateStrategy struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment.go new file mode 100644 index 0000000..1be8d2e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment.go @@ -0,0 +1,256 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + DeploymentType = "deployment" + DeploymentFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + DeploymentFieldAnnotations = "annotations" + DeploymentFieldAppArmorProfile = "appArmorProfile" + DeploymentFieldAutomountServiceAccountToken = "automountServiceAccountToken" + DeploymentFieldContainers = "containers" + DeploymentFieldCreated = "created" + DeploymentFieldCreatorID = "creatorId" + DeploymentFieldDNSConfig = "dnsConfig" + DeploymentFieldDNSPolicy = "dnsPolicy" + DeploymentFieldDeploymentConfig = "deploymentConfig" + DeploymentFieldDeploymentStatus = "deploymentStatus" + DeploymentFieldEnableServiceLinks = "enableServiceLinks" + DeploymentFieldEphemeralContainers = "ephemeralContainers" + DeploymentFieldFSGroupChangePolicy = "fsGroupChangePolicy" + DeploymentFieldFsgid = "fsgid" + DeploymentFieldGids = "gids" + DeploymentFieldHostAliases = "hostAliases" + DeploymentFieldHostIPC = "hostIPC" + DeploymentFieldHostNetwork = "hostNetwork" + DeploymentFieldHostPID = "hostPID" + DeploymentFieldHostUsers = "hostUsers" + DeploymentFieldHostname = "hostname" + DeploymentFieldImagePullSecrets = "imagePullSecrets" + DeploymentFieldLabels = "labels" + DeploymentFieldName = "name" + DeploymentFieldNamespaceId = "namespaceId" + DeploymentFieldNodeID = "nodeId" + DeploymentFieldOS = "os" + DeploymentFieldOverhead = "overhead" + DeploymentFieldOwnerReferences = "ownerReferences" + DeploymentFieldPaused = "paused" + DeploymentFieldPreemptionPolicy = "preemptionPolicy" + DeploymentFieldProjectID = "projectId" + DeploymentFieldPublicEndpoints = "publicEndpoints" + DeploymentFieldReadinessGates = "readinessGates" + DeploymentFieldRemoved = "removed" + DeploymentFieldResourceClaims = "resourceClaims" + DeploymentFieldRestartPolicy = "restartPolicy" + DeploymentFieldRunAsGroup = "runAsGroup" + DeploymentFieldRunAsNonRoot = "runAsNonRoot" + DeploymentFieldRuntimeClassName = "runtimeClassName" + DeploymentFieldScale = "scale" + DeploymentFieldScheduling = "scheduling" + DeploymentFieldSchedulingGates = "schedulingGates" + DeploymentFieldSeccompProfile = "seccompProfile" + DeploymentFieldSelector = "selector" + DeploymentFieldServiceAccountName = "serviceAccountName" + DeploymentFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + DeploymentFieldShareProcessNamespace = "shareProcessNamespace" + DeploymentFieldState = "state" + DeploymentFieldSubdomain = "subdomain" + DeploymentFieldSysctls = "sysctls" + DeploymentFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + DeploymentFieldTopologySpreadConstraints = "topologySpreadConstraints" + DeploymentFieldTransitioning = "transitioning" + DeploymentFieldTransitioningMessage = "transitioningMessage" + DeploymentFieldUUID = "uuid" + DeploymentFieldUid = "uid" + DeploymentFieldVolumes = "volumes" + DeploymentFieldWindowsOptions = "windowsOptions" + DeploymentFieldWorkloadAnnotations = "workloadAnnotations" + DeploymentFieldWorkloadLabels = "workloadLabels" + DeploymentFieldWorkloadMetrics = "workloadMetrics" +) + +type Deployment struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DeploymentConfig *DeploymentConfig `json:"deploymentConfig,omitempty" yaml:"deploymentConfig,omitempty"` + DeploymentStatus *DeploymentStatus `json:"deploymentStatus,omitempty" yaml:"deploymentStatus,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Paused bool `json:"paused,omitempty" yaml:"paused,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type DeploymentCollection struct { + types.Collection + Data []Deployment `json:"data,omitempty"` + client *DeploymentClient +} + +type DeploymentClient struct { + apiClient *Client +} + +type DeploymentOperations interface { + List(opts *types.ListOpts) (*DeploymentCollection, error) + ListAll(opts *types.ListOpts) (*DeploymentCollection, error) + Create(opts *Deployment) (*Deployment, error) + Update(existing *Deployment, updates interface{}) (*Deployment, error) + Replace(existing *Deployment) (*Deployment, error) + ByID(id string) (*Deployment, error) + Delete(container *Deployment) error + + ActionPause(resource *Deployment) error + + ActionRedeploy(resource *Deployment) error + + ActionResume(resource *Deployment) error + + ActionRollback(resource *Deployment, input *DeploymentRollbackInput) error +} + +func newDeploymentClient(apiClient *Client) *DeploymentClient { + return &DeploymentClient{ + apiClient: apiClient, + } +} + +func (c *DeploymentClient) Create(container *Deployment) (*Deployment, error) { + resp := &Deployment{} + err := c.apiClient.Ops.DoCreate(DeploymentType, container, resp) + return resp, err +} + +func (c *DeploymentClient) Update(existing *Deployment, updates interface{}) (*Deployment, error) { + resp := &Deployment{} + err := c.apiClient.Ops.DoUpdate(DeploymentType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *DeploymentClient) Replace(obj *Deployment) (*Deployment, error) { + resp := &Deployment{} + err := c.apiClient.Ops.DoReplace(DeploymentType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *DeploymentClient) List(opts *types.ListOpts) (*DeploymentCollection, error) { + resp := &DeploymentCollection{} + err := c.apiClient.Ops.DoList(DeploymentType, opts, resp) + resp.client = c + return resp, err +} + +func (c *DeploymentClient) ListAll(opts *types.ListOpts) (*DeploymentCollection, error) { + resp := &DeploymentCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *DeploymentCollection) Next() (*DeploymentCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &DeploymentCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *DeploymentClient) ByID(id string) (*Deployment, error) { + resp := &Deployment{} + err := c.apiClient.Ops.DoByID(DeploymentType, id, resp) + return resp, err +} + +func (c *DeploymentClient) Delete(container *Deployment) error { + return c.apiClient.Ops.DoResourceDelete(DeploymentType, &container.Resource) +} + +func (c *DeploymentClient) ActionPause(resource *Deployment) error { + err := c.apiClient.Ops.DoAction(DeploymentType, "pause", &resource.Resource, nil, nil) + return err +} + +func (c *DeploymentClient) ActionRedeploy(resource *Deployment) error { + err := c.apiClient.Ops.DoAction(DeploymentType, "redeploy", &resource.Resource, nil, nil) + return err +} + +func (c *DeploymentClient) ActionResume(resource *Deployment) error { + err := c.apiClient.Ops.DoAction(DeploymentType, "resume", &resource.Resource, nil, nil) + return err +} + +func (c *DeploymentClient) ActionRollback(resource *Deployment, input *DeploymentRollbackInput) error { + err := c.apiClient.Ops.DoAction(DeploymentType, "rollback", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_condition.go new file mode 100644 index 0000000..ed546d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + DeploymentConditionType = "deploymentCondition" + DeploymentConditionFieldLastTransitionTime = "lastTransitionTime" + DeploymentConditionFieldLastUpdateTime = "lastUpdateTime" + DeploymentConditionFieldMessage = "message" + DeploymentConditionFieldReason = "reason" + DeploymentConditionFieldStatus = "status" + DeploymentConditionFieldType = "type" +) + +type DeploymentCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + LastUpdateTime string `json:"lastUpdateTime,omitempty" yaml:"lastUpdateTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_config.go new file mode 100644 index 0000000..1204973 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_config.go @@ -0,0 +1,24 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DeploymentConfigType = "deploymentConfig" + DeploymentConfigFieldMaxSurge = "maxSurge" + DeploymentConfigFieldMaxUnavailable = "maxUnavailable" + DeploymentConfigFieldMinReadySeconds = "minReadySeconds" + DeploymentConfigFieldProgressDeadlineSeconds = "progressDeadlineSeconds" + DeploymentConfigFieldRevisionHistoryLimit = "revisionHistoryLimit" + DeploymentConfigFieldStrategy = "strategy" +) + +type DeploymentConfig struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` + ProgressDeadlineSeconds *int64 `json:"progressDeadlineSeconds,omitempty" yaml:"progressDeadlineSeconds,omitempty"` + RevisionHistoryLimit *int64 `json:"revisionHistoryLimit,omitempty" yaml:"revisionHistoryLimit,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_rollback_input.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_rollback_input.go new file mode 100644 index 0000000..74ec908 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_rollback_input.go @@ -0,0 +1,10 @@ +package client + +const ( + DeploymentRollbackInputType = "deploymentRollbackInput" + DeploymentRollbackInputFieldReplicaSetID = "replicaSetId" +) + +type DeploymentRollbackInput struct { + ReplicaSetID string `json:"replicaSetId,omitempty" yaml:"replicaSetId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_spec.go new file mode 100644 index 0000000..b62aaa4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_spec.go @@ -0,0 +1,100 @@ +package client + +const ( + DeploymentSpecType = "deploymentSpec" + DeploymentSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + DeploymentSpecFieldAppArmorProfile = "appArmorProfile" + DeploymentSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + DeploymentSpecFieldContainers = "containers" + DeploymentSpecFieldDNSConfig = "dnsConfig" + DeploymentSpecFieldDNSPolicy = "dnsPolicy" + DeploymentSpecFieldDeploymentConfig = "deploymentConfig" + DeploymentSpecFieldEnableServiceLinks = "enableServiceLinks" + DeploymentSpecFieldEphemeralContainers = "ephemeralContainers" + DeploymentSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + DeploymentSpecFieldFsgid = "fsgid" + DeploymentSpecFieldGids = "gids" + DeploymentSpecFieldHostAliases = "hostAliases" + DeploymentSpecFieldHostIPC = "hostIPC" + DeploymentSpecFieldHostNetwork = "hostNetwork" + DeploymentSpecFieldHostPID = "hostPID" + DeploymentSpecFieldHostUsers = "hostUsers" + DeploymentSpecFieldHostname = "hostname" + DeploymentSpecFieldImagePullSecrets = "imagePullSecrets" + DeploymentSpecFieldNodeID = "nodeId" + DeploymentSpecFieldOS = "os" + DeploymentSpecFieldObjectMeta = "metadata" + DeploymentSpecFieldOverhead = "overhead" + DeploymentSpecFieldPaused = "paused" + DeploymentSpecFieldPreemptionPolicy = "preemptionPolicy" + DeploymentSpecFieldReadinessGates = "readinessGates" + DeploymentSpecFieldResourceClaims = "resourceClaims" + DeploymentSpecFieldRestartPolicy = "restartPolicy" + DeploymentSpecFieldRunAsGroup = "runAsGroup" + DeploymentSpecFieldRunAsNonRoot = "runAsNonRoot" + DeploymentSpecFieldRuntimeClassName = "runtimeClassName" + DeploymentSpecFieldScale = "scale" + DeploymentSpecFieldScheduling = "scheduling" + DeploymentSpecFieldSchedulingGates = "schedulingGates" + DeploymentSpecFieldSeccompProfile = "seccompProfile" + DeploymentSpecFieldSelector = "selector" + DeploymentSpecFieldServiceAccountName = "serviceAccountName" + DeploymentSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + DeploymentSpecFieldShareProcessNamespace = "shareProcessNamespace" + DeploymentSpecFieldSubdomain = "subdomain" + DeploymentSpecFieldSysctls = "sysctls" + DeploymentSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + DeploymentSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + DeploymentSpecFieldUid = "uid" + DeploymentSpecFieldVolumes = "volumes" + DeploymentSpecFieldWindowsOptions = "windowsOptions" +) + +type DeploymentSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DeploymentConfig *DeploymentConfig `json:"deploymentConfig,omitempty" yaml:"deploymentConfig,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + Paused bool `json:"paused,omitempty" yaml:"paused,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_status.go new file mode 100644 index 0000000..bee1413 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_status.go @@ -0,0 +1,24 @@ +package client + +const ( + DeploymentStatusType = "deploymentStatus" + DeploymentStatusFieldAvailableReplicas = "availableReplicas" + DeploymentStatusFieldCollisionCount = "collisionCount" + DeploymentStatusFieldConditions = "conditions" + DeploymentStatusFieldObservedGeneration = "observedGeneration" + DeploymentStatusFieldReadyReplicas = "readyReplicas" + DeploymentStatusFieldReplicas = "replicas" + DeploymentStatusFieldUnavailableReplicas = "unavailableReplicas" + DeploymentStatusFieldUpdatedReplicas = "updatedReplicas" +) + +type DeploymentStatus struct { + AvailableReplicas int64 `json:"availableReplicas,omitempty" yaml:"availableReplicas,omitempty"` + CollisionCount *int64 `json:"collisionCount,omitempty" yaml:"collisionCount,omitempty"` + Conditions []DeploymentCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + ReadyReplicas int64 `json:"readyReplicas,omitempty" yaml:"readyReplicas,omitempty"` + Replicas int64 `json:"replicas,omitempty" yaml:"replicas,omitempty"` + UnavailableReplicas int64 `json:"unavailableReplicas,omitempty" yaml:"unavailableReplicas,omitempty"` + UpdatedReplicas int64 `json:"updatedReplicas,omitempty" yaml:"updatedReplicas,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_strategy.go new file mode 100644 index 0000000..ae8cdce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_deployment_strategy.go @@ -0,0 +1,18 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + DeploymentStrategyType = "deploymentStrategy" + DeploymentStrategyFieldMaxSurge = "maxSurge" + DeploymentStrategyFieldMaxUnavailable = "maxUnavailable" + DeploymentStrategyFieldStrategy = "strategy" +) + +type DeploymentStrategy struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_dns_record.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_dns_record.go new file mode 100644 index 0000000..de270fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_dns_record.go @@ -0,0 +1,158 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + DNSRecordType = "dnsRecord" + DNSRecordFieldAllocateLoadBalancerNodePorts = "allocateLoadBalancerNodePorts" + DNSRecordFieldAnnotations = "annotations" + DNSRecordFieldClusterIPs = "clusterIPs" + DNSRecordFieldClusterIp = "clusterIp" + DNSRecordFieldCreated = "created" + DNSRecordFieldCreatorID = "creatorId" + DNSRecordFieldDescription = "description" + DNSRecordFieldHostname = "hostname" + DNSRecordFieldIPAddresses = "ipAddresses" + DNSRecordFieldIPFamilies = "ipFamilies" + DNSRecordFieldIPFamilyPolicy = "ipFamilyPolicy" + DNSRecordFieldLabels = "labels" + DNSRecordFieldName = "name" + DNSRecordFieldNamespaceId = "namespaceId" + DNSRecordFieldOwnerReferences = "ownerReferences" + DNSRecordFieldPorts = "ports" + DNSRecordFieldProjectID = "projectId" + DNSRecordFieldPublicEndpoints = "publicEndpoints" + DNSRecordFieldRemoved = "removed" + DNSRecordFieldSelector = "selector" + DNSRecordFieldState = "state" + DNSRecordFieldTargetDNSRecordIDs = "targetDnsRecordIds" + DNSRecordFieldTargetWorkloadIDs = "targetWorkloadIds" + DNSRecordFieldTrafficDistribution = "trafficDistribution" + DNSRecordFieldTransitioning = "transitioning" + DNSRecordFieldTransitioningMessage = "transitioningMessage" + DNSRecordFieldUUID = "uuid" + DNSRecordFieldWorkloadID = "workloadId" +) + +type DNSRecord struct { + types.Resource + AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty" yaml:"allocateLoadBalancerNodePorts,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterIPs []string `json:"clusterIPs,omitempty" yaml:"clusterIPs,omitempty"` + ClusterIp string `json:"clusterIp,omitempty" yaml:"clusterIp,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPAddresses []string `json:"ipAddresses,omitempty" yaml:"ipAddresses,omitempty"` + IPFamilies []string `json:"ipFamilies,omitempty" yaml:"ipFamilies,omitempty"` + IPFamilyPolicy string `json:"ipFamilyPolicy,omitempty" yaml:"ipFamilyPolicy,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Ports []ServicePort `json:"ports,omitempty" yaml:"ports,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + TargetDNSRecordIDs []string `json:"targetDnsRecordIds,omitempty" yaml:"targetDnsRecordIds,omitempty"` + TargetWorkloadIDs []string `json:"targetWorkloadIds,omitempty" yaml:"targetWorkloadIds,omitempty"` + TrafficDistribution string `json:"trafficDistribution,omitempty" yaml:"trafficDistribution,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WorkloadID string `json:"workloadId,omitempty" yaml:"workloadId,omitempty"` +} + +type DNSRecordCollection struct { + types.Collection + Data []DNSRecord `json:"data,omitempty"` + client *DNSRecordClient +} + +type DNSRecordClient struct { + apiClient *Client +} + +type DNSRecordOperations interface { + List(opts *types.ListOpts) (*DNSRecordCollection, error) + ListAll(opts *types.ListOpts) (*DNSRecordCollection, error) + Create(opts *DNSRecord) (*DNSRecord, error) + Update(existing *DNSRecord, updates interface{}) (*DNSRecord, error) + Replace(existing *DNSRecord) (*DNSRecord, error) + ByID(id string) (*DNSRecord, error) + Delete(container *DNSRecord) error +} + +func newDNSRecordClient(apiClient *Client) *DNSRecordClient { + return &DNSRecordClient{ + apiClient: apiClient, + } +} + +func (c *DNSRecordClient) Create(container *DNSRecord) (*DNSRecord, error) { + resp := &DNSRecord{} + err := c.apiClient.Ops.DoCreate(DNSRecordType, container, resp) + return resp, err +} + +func (c *DNSRecordClient) Update(existing *DNSRecord, updates interface{}) (*DNSRecord, error) { + resp := &DNSRecord{} + err := c.apiClient.Ops.DoUpdate(DNSRecordType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *DNSRecordClient) Replace(obj *DNSRecord) (*DNSRecord, error) { + resp := &DNSRecord{} + err := c.apiClient.Ops.DoReplace(DNSRecordType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *DNSRecordClient) List(opts *types.ListOpts) (*DNSRecordCollection, error) { + resp := &DNSRecordCollection{} + err := c.apiClient.Ops.DoList(DNSRecordType, opts, resp) + resp.client = c + return resp, err +} + +func (c *DNSRecordClient) ListAll(opts *types.ListOpts) (*DNSRecordCollection, error) { + resp := &DNSRecordCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *DNSRecordCollection) Next() (*DNSRecordCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &DNSRecordCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *DNSRecordClient) ByID(id string) (*DNSRecord, error) { + resp := &DNSRecord{} + err := c.apiClient.Ops.DoByID(DNSRecordType, id, resp) + return resp, err +} + +func (c *DNSRecordClient) Delete(container *DNSRecord) error { + return c.apiClient.Ops.DoResourceDelete(DNSRecordType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_docker_credential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_docker_credential.go new file mode 100644 index 0000000..0aec28e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_docker_credential.go @@ -0,0 +1,126 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + DockerCredentialType = "dockerCredential" + DockerCredentialFieldAnnotations = "annotations" + DockerCredentialFieldCreated = "created" + DockerCredentialFieldCreatorID = "creatorId" + DockerCredentialFieldDescription = "description" + DockerCredentialFieldLabels = "labels" + DockerCredentialFieldName = "name" + DockerCredentialFieldNamespaceId = "namespaceId" + DockerCredentialFieldOwnerReferences = "ownerReferences" + DockerCredentialFieldProjectID = "projectId" + DockerCredentialFieldRegistries = "registries" + DockerCredentialFieldRemoved = "removed" + DockerCredentialFieldUUID = "uuid" +) + +type DockerCredential struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Registries map[string]RegistryCredential `json:"registries,omitempty" yaml:"registries,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type DockerCredentialCollection struct { + types.Collection + Data []DockerCredential `json:"data,omitempty"` + client *DockerCredentialClient +} + +type DockerCredentialClient struct { + apiClient *Client +} + +type DockerCredentialOperations interface { + List(opts *types.ListOpts) (*DockerCredentialCollection, error) + ListAll(opts *types.ListOpts) (*DockerCredentialCollection, error) + Create(opts *DockerCredential) (*DockerCredential, error) + Update(existing *DockerCredential, updates interface{}) (*DockerCredential, error) + Replace(existing *DockerCredential) (*DockerCredential, error) + ByID(id string) (*DockerCredential, error) + Delete(container *DockerCredential) error +} + +func newDockerCredentialClient(apiClient *Client) *DockerCredentialClient { + return &DockerCredentialClient{ + apiClient: apiClient, + } +} + +func (c *DockerCredentialClient) Create(container *DockerCredential) (*DockerCredential, error) { + resp := &DockerCredential{} + err := c.apiClient.Ops.DoCreate(DockerCredentialType, container, resp) + return resp, err +} + +func (c *DockerCredentialClient) Update(existing *DockerCredential, updates interface{}) (*DockerCredential, error) { + resp := &DockerCredential{} + err := c.apiClient.Ops.DoUpdate(DockerCredentialType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *DockerCredentialClient) Replace(obj *DockerCredential) (*DockerCredential, error) { + resp := &DockerCredential{} + err := c.apiClient.Ops.DoReplace(DockerCredentialType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *DockerCredentialClient) List(opts *types.ListOpts) (*DockerCredentialCollection, error) { + resp := &DockerCredentialCollection{} + err := c.apiClient.Ops.DoList(DockerCredentialType, opts, resp) + resp.client = c + return resp, err +} + +func (c *DockerCredentialClient) ListAll(opts *types.ListOpts) (*DockerCredentialCollection, error) { + resp := &DockerCredentialCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *DockerCredentialCollection) Next() (*DockerCredentialCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &DockerCredentialCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *DockerCredentialClient) ByID(id string) (*DockerCredential, error) { + resp := &DockerCredential{} + err := c.apiClient.Ops.DoByID(DockerCredentialType, id, resp) + return resp, err +} + +func (c *DockerCredentialClient) Delete(container *DockerCredential) error { + return c.apiClient.Ops.DoResourceDelete(DockerCredentialType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apiprojection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apiprojection.go new file mode 100644 index 0000000..ca02c4d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apiprojection.go @@ -0,0 +1,10 @@ +package client + +const ( + DownwardAPIProjectionType = "downwardAPIProjection" + DownwardAPIProjectionFieldItems = "items" +) + +type DownwardAPIProjection struct { + Items []DownwardAPIVolumeFile `json:"items,omitempty" yaml:"items,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_file.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_file.go new file mode 100644 index 0000000..c8f8bc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_file.go @@ -0,0 +1,16 @@ +package client + +const ( + DownwardAPIVolumeFileType = "downwardAPIVolumeFile" + DownwardAPIVolumeFileFieldFieldRef = "fieldRef" + DownwardAPIVolumeFileFieldMode = "mode" + DownwardAPIVolumeFileFieldPath = "path" + DownwardAPIVolumeFileFieldResourceFieldRef = "resourceFieldRef" +) + +type DownwardAPIVolumeFile struct { + FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" yaml:"fieldRef,omitempty"` + Mode *int64 `json:"mode,omitempty" yaml:"mode,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" yaml:"resourceFieldRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_source.go new file mode 100644 index 0000000..f6be194 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_downward_apivolume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + DownwardAPIVolumeSourceType = "downwardAPIVolumeSource" + DownwardAPIVolumeSourceFieldDefaultMode = "defaultMode" + DownwardAPIVolumeSourceFieldItems = "items" +) + +type DownwardAPIVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []DownwardAPIVolumeFile `json:"items,omitempty" yaml:"items,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_empty_dir_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_empty_dir_volume_source.go new file mode 100644 index 0000000..c4856f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_empty_dir_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + EmptyDirVolumeSourceType = "emptyDirVolumeSource" + EmptyDirVolumeSourceFieldMedium = "medium" + EmptyDirVolumeSourceFieldSizeLimit = "sizeLimit" +) + +type EmptyDirVolumeSource struct { + Medium string `json:"medium,omitempty" yaml:"medium,omitempty"` + SizeLimit string `json:"sizeLimit,omitempty" yaml:"sizeLimit,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_from_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_from_source.go new file mode 100644 index 0000000..3514206 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_from_source.go @@ -0,0 +1,14 @@ +package client + +const ( + EnvFromSourceType = "envFromSource" + EnvFromSourceFieldConfigMapRef = "configMapRef" + EnvFromSourceFieldPrefix = "prefix" + EnvFromSourceFieldSecretRef = "secretRef" +) + +type EnvFromSource struct { + ConfigMapRef *ConfigMapEnvSource `json:"configMapRef,omitempty" yaml:"configMapRef,omitempty"` + Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` + SecretRef *SecretEnvSource `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var.go new file mode 100644 index 0000000..35ccda3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var.go @@ -0,0 +1,14 @@ +package client + +const ( + EnvVarType = "envVar" + EnvVarFieldName = "name" + EnvVarFieldValue = "value" + EnvVarFieldValueFrom = "valueFrom" +) + +type EnvVar struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` + ValueFrom *EnvVarSource `json:"valueFrom,omitempty" yaml:"valueFrom,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var_source.go new file mode 100644 index 0000000..390a033 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_env_var_source.go @@ -0,0 +1,16 @@ +package client + +const ( + EnvVarSourceType = "envVarSource" + EnvVarSourceFieldConfigMapKeyRef = "configMapKeyRef" + EnvVarSourceFieldFieldRef = "fieldRef" + EnvVarSourceFieldResourceFieldRef = "resourceFieldRef" + EnvVarSourceFieldSecretKeyRef = "secretKeyRef" +) + +type EnvVarSource struct { + ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" yaml:"configMapKeyRef,omitempty"` + FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" yaml:"fieldRef,omitempty"` + ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" yaml:"resourceFieldRef,omitempty"` + SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" yaml:"secretKeyRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_environment_from.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_environment_from.go new file mode 100644 index 0000000..40244ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_environment_from.go @@ -0,0 +1,20 @@ +package client + +const ( + EnvironmentFromType = "environmentFrom" + EnvironmentFromFieldOptional = "optional" + EnvironmentFromFieldPrefix = "prefix" + EnvironmentFromFieldSource = "source" + EnvironmentFromFieldSourceKey = "sourceKey" + EnvironmentFromFieldSourceName = "sourceName" + EnvironmentFromFieldTargetKey = "targetKey" +) + +type EnvironmentFrom struct { + Optional bool `json:"optional,omitempty" yaml:"optional,omitempty"` + Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` + Source string `json:"source,omitempty" yaml:"source,omitempty"` + SourceKey string `json:"sourceKey,omitempty" yaml:"sourceKey,omitempty"` + SourceName string `json:"sourceName,omitempty" yaml:"sourceName,omitempty"` + TargetKey string `json:"targetKey,omitempty" yaml:"targetKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_container.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_container.go new file mode 100644 index 0000000..5e371cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_container.go @@ -0,0 +1,58 @@ +package client + +const ( + EphemeralContainerType = "ephemeralContainer" + EphemeralContainerFieldArgs = "args" + EphemeralContainerFieldCommand = "command" + EphemeralContainerFieldEnv = "env" + EphemeralContainerFieldEnvFrom = "envFrom" + EphemeralContainerFieldImage = "image" + EphemeralContainerFieldImagePullPolicy = "imagePullPolicy" + EphemeralContainerFieldLifecycle = "lifecycle" + EphemeralContainerFieldLivenessProbe = "livenessProbe" + EphemeralContainerFieldName = "name" + EphemeralContainerFieldPorts = "ports" + EphemeralContainerFieldReadinessProbe = "readinessProbe" + EphemeralContainerFieldResizePolicy = "resizePolicy" + EphemeralContainerFieldResources = "resources" + EphemeralContainerFieldRestartPolicy = "restartPolicy" + EphemeralContainerFieldSecurityContext = "securityContext" + EphemeralContainerFieldStartupProbe = "startupProbe" + EphemeralContainerFieldStdin = "stdin" + EphemeralContainerFieldStdinOnce = "stdinOnce" + EphemeralContainerFieldTTY = "tty" + EphemeralContainerFieldTargetContainerName = "targetContainerName" + EphemeralContainerFieldTerminationMessagePath = "terminationMessagePath" + EphemeralContainerFieldTerminationMessagePolicy = "terminationMessagePolicy" + EphemeralContainerFieldVolumeDevices = "volumeDevices" + EphemeralContainerFieldVolumeMounts = "volumeMounts" + EphemeralContainerFieldWorkingDir = "workingDir" +) + +type EphemeralContainer struct { + Args []string `json:"args,omitempty" yaml:"args,omitempty"` + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + Env []EnvVar `json:"env,omitempty" yaml:"env,omitempty"` + EnvFrom []EnvFromSource `json:"envFrom,omitempty" yaml:"envFrom,omitempty"` + Image string `json:"image,omitempty" yaml:"image,omitempty"` + ImagePullPolicy string `json:"imagePullPolicy,omitempty" yaml:"imagePullPolicy,omitempty"` + Lifecycle *Lifecycle `json:"lifecycle,omitempty" yaml:"lifecycle,omitempty"` + LivenessProbe *Probe `json:"livenessProbe,omitempty" yaml:"livenessProbe,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Ports []ContainerPort `json:"ports,omitempty" yaml:"ports,omitempty"` + ReadinessProbe *Probe `json:"readinessProbe,omitempty" yaml:"readinessProbe,omitempty"` + ResizePolicy []ContainerResizePolicy `json:"resizePolicy,omitempty" yaml:"resizePolicy,omitempty"` + Resources *ResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + SecurityContext *SecurityContext `json:"securityContext,omitempty" yaml:"securityContext,omitempty"` + StartupProbe *Probe `json:"startupProbe,omitempty" yaml:"startupProbe,omitempty"` + Stdin bool `json:"stdin,omitempty" yaml:"stdin,omitempty"` + StdinOnce bool `json:"stdinOnce,omitempty" yaml:"stdinOnce,omitempty"` + TTY bool `json:"tty,omitempty" yaml:"tty,omitempty"` + TargetContainerName string `json:"targetContainerName,omitempty" yaml:"targetContainerName,omitempty"` + TerminationMessagePath string `json:"terminationMessagePath,omitempty" yaml:"terminationMessagePath,omitempty"` + TerminationMessagePolicy string `json:"terminationMessagePolicy,omitempty" yaml:"terminationMessagePolicy,omitempty"` + VolumeDevices []VolumeDevice `json:"volumeDevices,omitempty" yaml:"volumeDevices,omitempty"` + VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" yaml:"volumeMounts,omitempty"` + WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_volume_source.go new file mode 100644 index 0000000..fc7f09e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ephemeral_volume_source.go @@ -0,0 +1,10 @@ +package client + +const ( + EphemeralVolumeSourceType = "ephemeralVolumeSource" + EphemeralVolumeSourceFieldVolumeClaimTemplate = "volumeClaimTemplate" +) + +type EphemeralVolumeSource struct { + VolumeClaimTemplate *PersistentVolumeClaimTemplate `json:"volumeClaimTemplate,omitempty" yaml:"volumeClaimTemplate,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_exec_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_exec_action.go new file mode 100644 index 0000000..a10423d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_exec_action.go @@ -0,0 +1,10 @@ +package client + +const ( + ExecActionType = "execAction" + ExecActionFieldCommand = "command" +) + +type ExecAction struct { + Command []string `json:"command,omitempty" yaml:"command,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_source.go new file mode 100644 index 0000000..fd086d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ExternalMetricSourceType = "externalMetricSource" + ExternalMetricSourceFieldMetric = "metric" + ExternalMetricSourceFieldTarget = "target" +) + +type ExternalMetricSource struct { + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_status.go new file mode 100644 index 0000000..b8b411f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_external_metric_status.go @@ -0,0 +1,12 @@ +package client + +const ( + ExternalMetricStatusType = "externalMetricStatus" + ExternalMetricStatusFieldCurrent = "current" + ExternalMetricStatusFieldMetric = "metric" +) + +type ExternalMetricStatus struct { + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_fc_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_fc_volume_source.go new file mode 100644 index 0000000..ebc0b63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_fc_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FCVolumeSourceType = "fcVolumeSource" + FCVolumeSourceFieldFSType = "fsType" + FCVolumeSourceFieldLun = "lun" + FCVolumeSourceFieldReadOnly = "readOnly" + FCVolumeSourceFieldTargetWWNs = "targetWWNs" + FCVolumeSourceFieldWWIDs = "wwids" +) + +type FCVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Lun *int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + TargetWWNs []string `json:"targetWWNs,omitempty" yaml:"targetWWNs,omitempty"` + WWIDs []string `json:"wwids,omitempty" yaml:"wwids,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_persistent_volume_source.go new file mode 100644 index 0000000..20de1fd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_persistent_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FlexPersistentVolumeSourceType = "flexPersistentVolumeSource" + FlexPersistentVolumeSourceFieldDriver = "driver" + FlexPersistentVolumeSourceFieldFSType = "fsType" + FlexPersistentVolumeSourceFieldOptions = "options" + FlexPersistentVolumeSourceFieldReadOnly = "readOnly" + FlexPersistentVolumeSourceFieldSecretRef = "secretRef" +) + +type FlexPersistentVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_volume_source.go new file mode 100644 index 0000000..d2e942b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flex_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + FlexVolumeSourceType = "flexVolumeSource" + FlexVolumeSourceFieldDriver = "driver" + FlexVolumeSourceFieldFSType = "fsType" + FlexVolumeSourceFieldOptions = "options" + FlexVolumeSourceFieldReadOnly = "readOnly" + FlexVolumeSourceFieldSecretRef = "secretRef" +) + +type FlexVolumeSource struct { + Driver string `json:"driver,omitempty" yaml:"driver,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Options map[string]string `json:"options,omitempty" yaml:"options,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flocker_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flocker_volume_source.go new file mode 100644 index 0000000..802b77f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_flocker_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + FlockerVolumeSourceType = "flockerVolumeSource" + FlockerVolumeSourceFieldDatasetName = "datasetName" + FlockerVolumeSourceFieldDatasetUUID = "datasetUUID" +) + +type FlockerVolumeSource struct { + DatasetName string `json:"datasetName,omitempty" yaml:"datasetName,omitempty"` + DatasetUUID string `json:"datasetUUID,omitempty" yaml:"datasetUUID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_gce_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_gce_persistent_disk_volume_source.go new file mode 100644 index 0000000..726a448 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_gce_persistent_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + GCEPersistentDiskVolumeSourceType = "gcePersistentDiskVolumeSource" + GCEPersistentDiskVolumeSourceFieldFSType = "fsType" + GCEPersistentDiskVolumeSourceFieldPDName = "pdName" + GCEPersistentDiskVolumeSourceFieldPartition = "partition" + GCEPersistentDiskVolumeSourceFieldReadOnly = "readOnly" +) + +type GCEPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PDName string `json:"pdName,omitempty" yaml:"pdName,omitempty"` + Partition int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_git_repo_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_git_repo_volume_source.go new file mode 100644 index 0000000..102d08f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_git_repo_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + GitRepoVolumeSourceType = "gitRepoVolumeSource" + GitRepoVolumeSourceFieldDirectory = "directory" + GitRepoVolumeSourceFieldRepository = "repository" + GitRepoVolumeSourceFieldRevision = "revision" +) + +type GitRepoVolumeSource struct { + Directory string `json:"directory,omitempty" yaml:"directory,omitempty"` + Repository string `json:"repository,omitempty" yaml:"repository,omitempty"` + Revision string `json:"revision,omitempty" yaml:"revision,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_persistent_volume_source.go new file mode 100644 index 0000000..bb754c3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_persistent_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + GlusterfsPersistentVolumeSourceType = "glusterfsPersistentVolumeSource" + GlusterfsPersistentVolumeSourceFieldEndpointsName = "endpoints" + GlusterfsPersistentVolumeSourceFieldEndpointsNamespace = "endpointsNamespace" + GlusterfsPersistentVolumeSourceFieldPath = "path" + GlusterfsPersistentVolumeSourceFieldReadOnly = "readOnly" +) + +type GlusterfsPersistentVolumeSource struct { + EndpointsName string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` + EndpointsNamespace string `json:"endpointsNamespace,omitempty" yaml:"endpointsNamespace,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_volume_source.go new file mode 100644 index 0000000..fa5900b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_glusterfs_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + GlusterfsVolumeSourceType = "glusterfsVolumeSource" + GlusterfsVolumeSourceFieldEndpointsName = "endpoints" + GlusterfsVolumeSourceFieldPath = "path" + GlusterfsVolumeSourceFieldReadOnly = "readOnly" +) + +type GlusterfsVolumeSource struct { + EndpointsName string `json:"endpoints,omitempty" yaml:"endpoints,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_grpc_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_grpc_action.go new file mode 100644 index 0000000..5aa2b8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_grpc_action.go @@ -0,0 +1,12 @@ +package client + +const ( + GRPCActionType = "grpcAction" + GRPCActionFieldPort = "port" + GRPCActionFieldService = "service" +) + +type GRPCAction struct { + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Service string `json:"service,omitempty" yaml:"service,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler.go new file mode 100644 index 0000000..01078ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler.go @@ -0,0 +1,150 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + HorizontalPodAutoscalerType = "horizontalPodAutoscaler" + HorizontalPodAutoscalerFieldAnnotations = "annotations" + HorizontalPodAutoscalerFieldBehavior = "behavior" + HorizontalPodAutoscalerFieldConditions = "conditions" + HorizontalPodAutoscalerFieldCreated = "created" + HorizontalPodAutoscalerFieldCreatorID = "creatorId" + HorizontalPodAutoscalerFieldCurrentReplicas = "currentReplicas" + HorizontalPodAutoscalerFieldDescription = "description" + HorizontalPodAutoscalerFieldDesiredReplicas = "desiredReplicas" + HorizontalPodAutoscalerFieldLabels = "labels" + HorizontalPodAutoscalerFieldLastScaleTime = "lastScaleTime" + HorizontalPodAutoscalerFieldMaxReplicas = "maxReplicas" + HorizontalPodAutoscalerFieldMetrics = "metrics" + HorizontalPodAutoscalerFieldMinReplicas = "minReplicas" + HorizontalPodAutoscalerFieldName = "name" + HorizontalPodAutoscalerFieldNamespaceId = "namespaceId" + HorizontalPodAutoscalerFieldObservedGeneration = "observedGeneration" + HorizontalPodAutoscalerFieldOwnerReferences = "ownerReferences" + HorizontalPodAutoscalerFieldProjectID = "projectId" + HorizontalPodAutoscalerFieldRemoved = "removed" + HorizontalPodAutoscalerFieldState = "state" + HorizontalPodAutoscalerFieldTransitioning = "transitioning" + HorizontalPodAutoscalerFieldTransitioningMessage = "transitioningMessage" + HorizontalPodAutoscalerFieldUUID = "uuid" + HorizontalPodAutoscalerFieldWorkloadId = "workloadId" +) + +type HorizontalPodAutoscaler struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Behavior *HorizontalPodAutoscalerBehavior `json:"behavior,omitempty" yaml:"behavior,omitempty"` + Conditions []HorizontalPodAutoscalerCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CurrentReplicas int64 `json:"currentReplicas,omitempty" yaml:"currentReplicas,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + DesiredReplicas int64 `json:"desiredReplicas,omitempty" yaml:"desiredReplicas,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LastScaleTime string `json:"lastScaleTime,omitempty" yaml:"lastScaleTime,omitempty"` + MaxReplicas int64 `json:"maxReplicas,omitempty" yaml:"maxReplicas,omitempty"` + Metrics []Metric `json:"metrics,omitempty" yaml:"metrics,omitempty"` + MinReplicas *int64 `json:"minReplicas,omitempty" yaml:"minReplicas,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + ObservedGeneration *int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WorkloadId string `json:"workloadId,omitempty" yaml:"workloadId,omitempty"` +} + +type HorizontalPodAutoscalerCollection struct { + types.Collection + Data []HorizontalPodAutoscaler `json:"data,omitempty"` + client *HorizontalPodAutoscalerClient +} + +type HorizontalPodAutoscalerClient struct { + apiClient *Client +} + +type HorizontalPodAutoscalerOperations interface { + List(opts *types.ListOpts) (*HorizontalPodAutoscalerCollection, error) + ListAll(opts *types.ListOpts) (*HorizontalPodAutoscalerCollection, error) + Create(opts *HorizontalPodAutoscaler) (*HorizontalPodAutoscaler, error) + Update(existing *HorizontalPodAutoscaler, updates interface{}) (*HorizontalPodAutoscaler, error) + Replace(existing *HorizontalPodAutoscaler) (*HorizontalPodAutoscaler, error) + ByID(id string) (*HorizontalPodAutoscaler, error) + Delete(container *HorizontalPodAutoscaler) error +} + +func newHorizontalPodAutoscalerClient(apiClient *Client) *HorizontalPodAutoscalerClient { + return &HorizontalPodAutoscalerClient{ + apiClient: apiClient, + } +} + +func (c *HorizontalPodAutoscalerClient) Create(container *HorizontalPodAutoscaler) (*HorizontalPodAutoscaler, error) { + resp := &HorizontalPodAutoscaler{} + err := c.apiClient.Ops.DoCreate(HorizontalPodAutoscalerType, container, resp) + return resp, err +} + +func (c *HorizontalPodAutoscalerClient) Update(existing *HorizontalPodAutoscaler, updates interface{}) (*HorizontalPodAutoscaler, error) { + resp := &HorizontalPodAutoscaler{} + err := c.apiClient.Ops.DoUpdate(HorizontalPodAutoscalerType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *HorizontalPodAutoscalerClient) Replace(obj *HorizontalPodAutoscaler) (*HorizontalPodAutoscaler, error) { + resp := &HorizontalPodAutoscaler{} + err := c.apiClient.Ops.DoReplace(HorizontalPodAutoscalerType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *HorizontalPodAutoscalerClient) List(opts *types.ListOpts) (*HorizontalPodAutoscalerCollection, error) { + resp := &HorizontalPodAutoscalerCollection{} + err := c.apiClient.Ops.DoList(HorizontalPodAutoscalerType, opts, resp) + resp.client = c + return resp, err +} + +func (c *HorizontalPodAutoscalerClient) ListAll(opts *types.ListOpts) (*HorizontalPodAutoscalerCollection, error) { + resp := &HorizontalPodAutoscalerCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *HorizontalPodAutoscalerCollection) Next() (*HorizontalPodAutoscalerCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &HorizontalPodAutoscalerCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *HorizontalPodAutoscalerClient) ByID(id string) (*HorizontalPodAutoscaler, error) { + resp := &HorizontalPodAutoscaler{} + err := c.apiClient.Ops.DoByID(HorizontalPodAutoscalerType, id, resp) + return resp, err +} + +func (c *HorizontalPodAutoscalerClient) Delete(container *HorizontalPodAutoscaler) error { + return c.apiClient.Ops.DoResourceDelete(HorizontalPodAutoscalerType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_behavior.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_behavior.go new file mode 100644 index 0000000..c6d173a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_behavior.go @@ -0,0 +1,12 @@ +package client + +const ( + HorizontalPodAutoscalerBehaviorType = "horizontalPodAutoscalerBehavior" + HorizontalPodAutoscalerBehaviorFieldScaleDown = "scaleDown" + HorizontalPodAutoscalerBehaviorFieldScaleUp = "scaleUp" +) + +type HorizontalPodAutoscalerBehavior struct { + ScaleDown *HPAScalingRules `json:"scaleDown,omitempty" yaml:"scaleDown,omitempty"` + ScaleUp *HPAScalingRules `json:"scaleUp,omitempty" yaml:"scaleUp,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_condition.go new file mode 100644 index 0000000..15fdfc4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + HorizontalPodAutoscalerConditionType = "horizontalPodAutoscalerCondition" + HorizontalPodAutoscalerConditionFieldLastTransitionTime = "lastTransitionTime" + HorizontalPodAutoscalerConditionFieldMessage = "message" + HorizontalPodAutoscalerConditionFieldReason = "reason" + HorizontalPodAutoscalerConditionFieldStatus = "status" + HorizontalPodAutoscalerConditionFieldType = "type" +) + +type HorizontalPodAutoscalerCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_spec.go new file mode 100644 index 0000000..072407a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_spec.go @@ -0,0 +1,18 @@ +package client + +const ( + HorizontalPodAutoscalerSpecType = "horizontalPodAutoscalerSpec" + HorizontalPodAutoscalerSpecFieldBehavior = "behavior" + HorizontalPodAutoscalerSpecFieldMaxReplicas = "maxReplicas" + HorizontalPodAutoscalerSpecFieldMetrics = "metrics" + HorizontalPodAutoscalerSpecFieldMinReplicas = "minReplicas" + HorizontalPodAutoscalerSpecFieldScaleTargetRef = "scaleTargetRef" +) + +type HorizontalPodAutoscalerSpec struct { + Behavior *HorizontalPodAutoscalerBehavior `json:"behavior,omitempty" yaml:"behavior,omitempty"` + MaxReplicas int64 `json:"maxReplicas,omitempty" yaml:"maxReplicas,omitempty"` + Metrics []Metric `json:"metrics,omitempty" yaml:"metrics,omitempty"` + MinReplicas *int64 `json:"minReplicas,omitempty" yaml:"minReplicas,omitempty"` + ScaleTargetRef *CrossVersionObjectReference `json:"scaleTargetRef,omitempty" yaml:"scaleTargetRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_status.go new file mode 100644 index 0000000..216f688 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_horizontal_pod_autoscaler_status.go @@ -0,0 +1,20 @@ +package client + +const ( + HorizontalPodAutoscalerStatusType = "horizontalPodAutoscalerStatus" + HorizontalPodAutoscalerStatusFieldConditions = "conditions" + HorizontalPodAutoscalerStatusFieldCurrentMetrics = "currentMetrics" + HorizontalPodAutoscalerStatusFieldCurrentReplicas = "currentReplicas" + HorizontalPodAutoscalerStatusFieldDesiredReplicas = "desiredReplicas" + HorizontalPodAutoscalerStatusFieldLastScaleTime = "lastScaleTime" + HorizontalPodAutoscalerStatusFieldObservedGeneration = "observedGeneration" +) + +type HorizontalPodAutoscalerStatus struct { + Conditions []HorizontalPodAutoscalerCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CurrentMetrics []MetricStatus `json:"currentMetrics,omitempty" yaml:"currentMetrics,omitempty"` + CurrentReplicas int64 `json:"currentReplicas,omitempty" yaml:"currentReplicas,omitempty"` + DesiredReplicas int64 `json:"desiredReplicas,omitempty" yaml:"desiredReplicas,omitempty"` + LastScaleTime string `json:"lastScaleTime,omitempty" yaml:"lastScaleTime,omitempty"` + ObservedGeneration *int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_alias.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_alias.go new file mode 100644 index 0000000..021aa52 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_alias.go @@ -0,0 +1,12 @@ +package client + +const ( + HostAliasType = "hostAlias" + HostAliasFieldHostnames = "hostnames" + HostAliasFieldIP = "ip" +) + +type HostAlias struct { + Hostnames []string `json:"hostnames,omitempty" yaml:"hostnames,omitempty"` + IP string `json:"ip,omitempty" yaml:"ip,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_ip.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_ip.go new file mode 100644 index 0000000..97da06c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_ip.go @@ -0,0 +1,10 @@ +package client + +const ( + HostIPType = "hostIP" + HostIPFieldIP = "ip" +) + +type HostIP struct { + IP string `json:"ip,omitempty" yaml:"ip,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_path_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_path_volume_source.go new file mode 100644 index 0000000..a7471bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_host_path_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + HostPathVolumeSourceType = "hostPathVolumeSource" + HostPathVolumeSourceFieldKind = "kind" + HostPathVolumeSourceFieldPath = "path" +) + +type HostPathVolumeSource struct { + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_policy.go new file mode 100644 index 0000000..0014a5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_policy.go @@ -0,0 +1,14 @@ +package client + +const ( + HPAScalingPolicyType = "hpaScalingPolicy" + HPAScalingPolicyFieldPeriodSeconds = "periodSeconds" + HPAScalingPolicyFieldType = "type" + HPAScalingPolicyFieldValue = "value" +) + +type HPAScalingPolicy struct { + PeriodSeconds int64 `json:"periodSeconds,omitempty" yaml:"periodSeconds,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Value int64 `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_rules.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_rules.go new file mode 100644 index 0000000..228f258 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_hpa_scaling_rules.go @@ -0,0 +1,14 @@ +package client + +const ( + HPAScalingRulesType = "hpaScalingRules" + HPAScalingRulesFieldPolicies = "policies" + HPAScalingRulesFieldSelectPolicy = "selectPolicy" + HPAScalingRulesFieldStabilizationWindowSeconds = "stabilizationWindowSeconds" +) + +type HPAScalingRules struct { + Policies []HPAScalingPolicy `json:"policies,omitempty" yaml:"policies,omitempty"` + SelectPolicy string `json:"selectPolicy,omitempty" yaml:"selectPolicy,omitempty"` + StabilizationWindowSeconds *int64 `json:"stabilizationWindowSeconds,omitempty" yaml:"stabilizationWindowSeconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_get_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_get_action.go new file mode 100644 index 0000000..b1fb241 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_get_action.go @@ -0,0 +1,22 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + HTTPGetActionType = "httpGetAction" + HTTPGetActionFieldHTTPHeaders = "httpHeaders" + HTTPGetActionFieldHost = "host" + HTTPGetActionFieldPath = "path" + HTTPGetActionFieldPort = "port" + HTTPGetActionFieldScheme = "scheme" +) + +type HTTPGetAction struct { + HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty" yaml:"httpHeaders,omitempty"` + Host string `json:"host,omitempty" yaml:"host,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Port intstr.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` + Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_header.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_header.go new file mode 100644 index 0000000..7c0d532 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_header.go @@ -0,0 +1,12 @@ +package client + +const ( + HTTPHeaderType = "httpHeader" + HTTPHeaderFieldName = "name" + HTTPHeaderFieldValue = "value" +) + +type HTTPHeader struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_path.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_path.go new file mode 100644 index 0000000..e436fa5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_path.go @@ -0,0 +1,26 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + HTTPIngressPathType = "httpIngressPath" + HTTPIngressPathFieldPath = "path" + HTTPIngressPathFieldPathType = "pathType" + HTTPIngressPathFieldResource = "resource" + HTTPIngressPathFieldService = "service" + HTTPIngressPathFieldServiceId = "serviceId" + HTTPIngressPathFieldTargetPort = "targetPort" + HTTPIngressPathFieldWorkloadIDs = "workloadIds" +) + +type HTTPIngressPath struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + PathType string `json:"pathType,omitempty" yaml:"pathType,omitempty"` + Resource *TypedLocalObjectReference `json:"resource,omitempty" yaml:"resource,omitempty"` + Service *IngressServiceBackend `json:"service,omitempty" yaml:"service,omitempty"` + ServiceId string `json:"serviceId,omitempty" yaml:"serviceId,omitempty"` + TargetPort intstr.IntOrString `json:"targetPort,omitempty" yaml:"targetPort,omitempty"` + WorkloadIDs []string `json:"workloadIds,omitempty" yaml:"workloadIds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_rule_value.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_rule_value.go new file mode 100644 index 0000000..9625462 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_http_ingress_rule_value.go @@ -0,0 +1,10 @@ +package client + +const ( + HTTPIngressRuleValueType = "httpIngressRuleValue" + HTTPIngressRuleValueFieldPaths = "paths" +) + +type HTTPIngressRuleValue struct { + Paths []HTTPIngressPath `json:"paths,omitempty" yaml:"paths,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress.go new file mode 100644 index 0000000..dc7d540 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress.go @@ -0,0 +1,144 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + IngressType = "ingress" + IngressFieldAnnotations = "annotations" + IngressFieldBackend = "backend" + IngressFieldCreated = "created" + IngressFieldCreatorID = "creatorId" + IngressFieldDefaultBackend = "defaultBackend" + IngressFieldDescription = "description" + IngressFieldIngressClassName = "ingressClassName" + IngressFieldLabels = "labels" + IngressFieldName = "name" + IngressFieldNamespaceId = "namespaceId" + IngressFieldOwnerReferences = "ownerReferences" + IngressFieldProjectID = "projectId" + IngressFieldPublicEndpoints = "publicEndpoints" + IngressFieldRemoved = "removed" + IngressFieldRules = "rules" + IngressFieldState = "state" + IngressFieldStatus = "status" + IngressFieldTLS = "tls" + IngressFieldTransitioning = "transitioning" + IngressFieldTransitioningMessage = "transitioningMessage" + IngressFieldUUID = "uuid" +) + +type Ingress struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Backend *IngressBackend `json:"backend,omitempty" yaml:"backend,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DefaultBackend *IngressBackend `json:"defaultBackend,omitempty" yaml:"defaultBackend,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + IngressClassName string `json:"ingressClassName,omitempty" yaml:"ingressClassName,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Rules []IngressRule `json:"rules,omitempty" yaml:"rules,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *IngressStatus `json:"status,omitempty" yaml:"status,omitempty"` + TLS []IngressTLS `json:"tls,omitempty" yaml:"tls,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type IngressCollection struct { + types.Collection + Data []Ingress `json:"data,omitempty"` + client *IngressClient +} + +type IngressClient struct { + apiClient *Client +} + +type IngressOperations interface { + List(opts *types.ListOpts) (*IngressCollection, error) + ListAll(opts *types.ListOpts) (*IngressCollection, error) + Create(opts *Ingress) (*Ingress, error) + Update(existing *Ingress, updates interface{}) (*Ingress, error) + Replace(existing *Ingress) (*Ingress, error) + ByID(id string) (*Ingress, error) + Delete(container *Ingress) error +} + +func newIngressClient(apiClient *Client) *IngressClient { + return &IngressClient{ + apiClient: apiClient, + } +} + +func (c *IngressClient) Create(container *Ingress) (*Ingress, error) { + resp := &Ingress{} + err := c.apiClient.Ops.DoCreate(IngressType, container, resp) + return resp, err +} + +func (c *IngressClient) Update(existing *Ingress, updates interface{}) (*Ingress, error) { + resp := &Ingress{} + err := c.apiClient.Ops.DoUpdate(IngressType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *IngressClient) Replace(obj *Ingress) (*Ingress, error) { + resp := &Ingress{} + err := c.apiClient.Ops.DoReplace(IngressType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *IngressClient) List(opts *types.ListOpts) (*IngressCollection, error) { + resp := &IngressCollection{} + err := c.apiClient.Ops.DoList(IngressType, opts, resp) + resp.client = c + return resp, err +} + +func (c *IngressClient) ListAll(opts *types.ListOpts) (*IngressCollection, error) { + resp := &IngressCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *IngressCollection) Next() (*IngressCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &IngressCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *IngressClient) ByID(id string) (*Ingress, error) { + resp := &Ingress{} + err := c.apiClient.Ops.DoByID(IngressType, id, resp) + return resp, err +} + +func (c *IngressClient) Delete(container *Ingress) error { + return c.apiClient.Ops.DoResourceDelete(IngressType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_backend.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_backend.go new file mode 100644 index 0000000..4731749 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_backend.go @@ -0,0 +1,22 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + IngressBackendType = "ingressBackend" + IngressBackendFieldResource = "resource" + IngressBackendFieldService = "service" + IngressBackendFieldServiceId = "serviceId" + IngressBackendFieldTargetPort = "targetPort" + IngressBackendFieldWorkloadIDs = "workloadIds" +) + +type IngressBackend struct { + Resource *TypedLocalObjectReference `json:"resource,omitempty" yaml:"resource,omitempty"` + Service *IngressServiceBackend `json:"service,omitempty" yaml:"service,omitempty"` + ServiceId string `json:"serviceId,omitempty" yaml:"serviceId,omitempty"` + TargetPort intstr.IntOrString `json:"targetPort,omitempty" yaml:"targetPort,omitempty"` + WorkloadIDs []string `json:"workloadIds,omitempty" yaml:"workloadIds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_ingress.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_ingress.go new file mode 100644 index 0000000..999d80f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_ingress.go @@ -0,0 +1,14 @@ +package client + +const ( + IngressLoadBalancerIngressType = "ingressLoadBalancerIngress" + IngressLoadBalancerIngressFieldHostname = "hostname" + IngressLoadBalancerIngressFieldIP = "ip" + IngressLoadBalancerIngressFieldPorts = "ports" +) + +type IngressLoadBalancerIngress struct { + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IP string `json:"ip,omitempty" yaml:"ip,omitempty"` + Ports []IngressPortStatus `json:"ports,omitempty" yaml:"ports,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_status.go new file mode 100644 index 0000000..9d43e1d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_load_balancer_status.go @@ -0,0 +1,10 @@ +package client + +const ( + IngressLoadBalancerStatusType = "ingressLoadBalancerStatus" + IngressLoadBalancerStatusFieldIngress = "ingress" +) + +type IngressLoadBalancerStatus struct { + Ingress []IngressLoadBalancerIngress `json:"ingress,omitempty" yaml:"ingress,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_port_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_port_status.go new file mode 100644 index 0000000..bc0ab71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_port_status.go @@ -0,0 +1,14 @@ +package client + +const ( + IngressPortStatusType = "ingressPortStatus" + IngressPortStatusFieldError = "error" + IngressPortStatusFieldPort = "port" + IngressPortStatusFieldProtocol = "protocol" +) + +type IngressPortStatus struct { + Error string `json:"error,omitempty" yaml:"error,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_rule.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_rule.go new file mode 100644 index 0000000..f6b787c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_rule.go @@ -0,0 +1,12 @@ +package client + +const ( + IngressRuleType = "ingressRule" + IngressRuleFieldHost = "host" + IngressRuleFieldPaths = "paths" +) + +type IngressRule struct { + Host string `json:"host,omitempty" yaml:"host,omitempty"` + Paths []HTTPIngressPath `json:"paths,omitempty" yaml:"paths,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_service_backend.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_service_backend.go new file mode 100644 index 0000000..0706db4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_service_backend.go @@ -0,0 +1,12 @@ +package client + +const ( + IngressServiceBackendType = "ingressServiceBackend" + IngressServiceBackendFieldName = "name" + IngressServiceBackendFieldPort = "port" +) + +type IngressServiceBackend struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Port *ServiceBackendPort `json:"port,omitempty" yaml:"port,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_spec.go new file mode 100644 index 0000000..b1590a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_spec.go @@ -0,0 +1,18 @@ +package client + +const ( + IngressSpecType = "ingressSpec" + IngressSpecFieldBackend = "backend" + IngressSpecFieldDefaultBackend = "defaultBackend" + IngressSpecFieldIngressClassName = "ingressClassName" + IngressSpecFieldRules = "rules" + IngressSpecFieldTLS = "tls" +) + +type IngressSpec struct { + Backend *IngressBackend `json:"backend,omitempty" yaml:"backend,omitempty"` + DefaultBackend *IngressBackend `json:"defaultBackend,omitempty" yaml:"defaultBackend,omitempty"` + IngressClassName string `json:"ingressClassName,omitempty" yaml:"ingressClassName,omitempty"` + Rules []IngressRule `json:"rules,omitempty" yaml:"rules,omitempty"` + TLS []IngressTLS `json:"tls,omitempty" yaml:"tls,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_status.go new file mode 100644 index 0000000..c42036a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_status.go @@ -0,0 +1,10 @@ +package client + +const ( + IngressStatusType = "ingressStatus" + IngressStatusFieldLoadBalancer = "loadBalancer" +) + +type IngressStatus struct { + LoadBalancer *IngressLoadBalancerStatus `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_tls.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_tls.go new file mode 100644 index 0000000..2506f7e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ingress_tls.go @@ -0,0 +1,12 @@ +package client + +const ( + IngressTLSType = "ingressTLS" + IngressTLSFieldCertificateID = "certificateId" + IngressTLSFieldHosts = "hosts" +) + +type IngressTLS struct { + CertificateID string `json:"certificateId,omitempty" yaml:"certificateId,omitempty"` + Hosts []string `json:"hosts,omitempty" yaml:"hosts,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_persistent_volume_source.go new file mode 100644 index 0000000..ba659f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_persistent_volume_source.go @@ -0,0 +1,30 @@ +package client + +const ( + ISCSIPersistentVolumeSourceType = "iscsiPersistentVolumeSource" + ISCSIPersistentVolumeSourceFieldDiscoveryCHAPAuth = "chapAuthDiscovery" + ISCSIPersistentVolumeSourceFieldFSType = "fsType" + ISCSIPersistentVolumeSourceFieldIQN = "iqn" + ISCSIPersistentVolumeSourceFieldISCSIInterface = "iscsiInterface" + ISCSIPersistentVolumeSourceFieldInitiatorName = "initiatorName" + ISCSIPersistentVolumeSourceFieldLun = "lun" + ISCSIPersistentVolumeSourceFieldPortals = "portals" + ISCSIPersistentVolumeSourceFieldReadOnly = "readOnly" + ISCSIPersistentVolumeSourceFieldSecretRef = "secretRef" + ISCSIPersistentVolumeSourceFieldSessionCHAPAuth = "chapAuthSession" + ISCSIPersistentVolumeSourceFieldTargetPortal = "targetPortal" +) + +type ISCSIPersistentVolumeSource struct { + DiscoveryCHAPAuth bool `json:"chapAuthDiscovery,omitempty" yaml:"chapAuthDiscovery,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + IQN string `json:"iqn,omitempty" yaml:"iqn,omitempty"` + ISCSIInterface string `json:"iscsiInterface,omitempty" yaml:"iscsiInterface,omitempty"` + InitiatorName string `json:"initiatorName,omitempty" yaml:"initiatorName,omitempty"` + Lun int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + Portals []string `json:"portals,omitempty" yaml:"portals,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + SessionCHAPAuth bool `json:"chapAuthSession,omitempty" yaml:"chapAuthSession,omitempty"` + TargetPortal string `json:"targetPortal,omitempty" yaml:"targetPortal,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_volume_source.go new file mode 100644 index 0000000..ef07620 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_iscsi_volume_source.go @@ -0,0 +1,30 @@ +package client + +const ( + ISCSIVolumeSourceType = "iscsiVolumeSource" + ISCSIVolumeSourceFieldDiscoveryCHAPAuth = "chapAuthDiscovery" + ISCSIVolumeSourceFieldFSType = "fsType" + ISCSIVolumeSourceFieldIQN = "iqn" + ISCSIVolumeSourceFieldISCSIInterface = "iscsiInterface" + ISCSIVolumeSourceFieldInitiatorName = "initiatorName" + ISCSIVolumeSourceFieldLun = "lun" + ISCSIVolumeSourceFieldPortals = "portals" + ISCSIVolumeSourceFieldReadOnly = "readOnly" + ISCSIVolumeSourceFieldSecretRef = "secretRef" + ISCSIVolumeSourceFieldSessionCHAPAuth = "chapAuthSession" + ISCSIVolumeSourceFieldTargetPortal = "targetPortal" +) + +type ISCSIVolumeSource struct { + DiscoveryCHAPAuth bool `json:"chapAuthDiscovery,omitempty" yaml:"chapAuthDiscovery,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + IQN string `json:"iqn,omitempty" yaml:"iqn,omitempty"` + ISCSIInterface string `json:"iscsiInterface,omitempty" yaml:"iscsiInterface,omitempty"` + InitiatorName string `json:"initiatorName,omitempty" yaml:"initiatorName,omitempty"` + Lun int64 `json:"lun,omitempty" yaml:"lun,omitempty"` + Portals []string `json:"portals,omitempty" yaml:"portals,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + SessionCHAPAuth bool `json:"chapAuthSession,omitempty" yaml:"chapAuthSession,omitempty"` + TargetPortal string `json:"targetPortal,omitempty" yaml:"targetPortal,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job.go new file mode 100644 index 0000000..f80e8a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job.go @@ -0,0 +1,242 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + JobType = "job" + JobFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + JobFieldAnnotations = "annotations" + JobFieldAppArmorProfile = "appArmorProfile" + JobFieldAutomountServiceAccountToken = "automountServiceAccountToken" + JobFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + JobFieldCompletionMode = "completionMode" + JobFieldContainers = "containers" + JobFieldCreated = "created" + JobFieldCreatorID = "creatorId" + JobFieldDNSConfig = "dnsConfig" + JobFieldDNSPolicy = "dnsPolicy" + JobFieldEnableServiceLinks = "enableServiceLinks" + JobFieldEphemeralContainers = "ephemeralContainers" + JobFieldFSGroupChangePolicy = "fsGroupChangePolicy" + JobFieldFsgid = "fsgid" + JobFieldGids = "gids" + JobFieldHostAliases = "hostAliases" + JobFieldHostIPC = "hostIPC" + JobFieldHostNetwork = "hostNetwork" + JobFieldHostPID = "hostPID" + JobFieldHostUsers = "hostUsers" + JobFieldHostname = "hostname" + JobFieldImagePullSecrets = "imagePullSecrets" + JobFieldJobConfig = "jobConfig" + JobFieldJobStatus = "jobStatus" + JobFieldLabels = "labels" + JobFieldManagedBy = "managedBy" + JobFieldMaxFailedIndexes = "maxFailedIndexes" + JobFieldName = "name" + JobFieldNamespaceId = "namespaceId" + JobFieldNodeID = "nodeId" + JobFieldOS = "os" + JobFieldOverhead = "overhead" + JobFieldOwnerReferences = "ownerReferences" + JobFieldPodFailurePolicy = "podFailurePolicy" + JobFieldPodReplacementPolicy = "podReplacementPolicy" + JobFieldPreemptionPolicy = "preemptionPolicy" + JobFieldProjectID = "projectId" + JobFieldPublicEndpoints = "publicEndpoints" + JobFieldReadinessGates = "readinessGates" + JobFieldRemoved = "removed" + JobFieldResourceClaims = "resourceClaims" + JobFieldRestartPolicy = "restartPolicy" + JobFieldRunAsGroup = "runAsGroup" + JobFieldRunAsNonRoot = "runAsNonRoot" + JobFieldRuntimeClassName = "runtimeClassName" + JobFieldScheduling = "scheduling" + JobFieldSchedulingGates = "schedulingGates" + JobFieldSeccompProfile = "seccompProfile" + JobFieldSelector = "selector" + JobFieldServiceAccountName = "serviceAccountName" + JobFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + JobFieldShareProcessNamespace = "shareProcessNamespace" + JobFieldState = "state" + JobFieldSubdomain = "subdomain" + JobFieldSuccessPolicy = "successPolicy" + JobFieldSuspend = "suspend" + JobFieldSysctls = "sysctls" + JobFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + JobFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + JobFieldTopologySpreadConstraints = "topologySpreadConstraints" + JobFieldTransitioning = "transitioning" + JobFieldTransitioningMessage = "transitioningMessage" + JobFieldUUID = "uuid" + JobFieldUid = "uid" + JobFieldVolumes = "volumes" + JobFieldWindowsOptions = "windowsOptions" + JobFieldWorkloadAnnotations = "workloadAnnotations" + JobFieldWorkloadLabels = "workloadLabels" + JobFieldWorkloadMetrics = "workloadMetrics" +) + +type Job struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + JobConfig *JobConfig `json:"jobConfig,omitempty" yaml:"jobConfig,omitempty"` + JobStatus *JobStatus `json:"jobStatus,omitempty" yaml:"jobStatus,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Suspend *bool `json:"suspend,omitempty" yaml:"suspend,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type JobCollection struct { + types.Collection + Data []Job `json:"data,omitempty"` + client *JobClient +} + +type JobClient struct { + apiClient *Client +} + +type JobOperations interface { + List(opts *types.ListOpts) (*JobCollection, error) + ListAll(opts *types.ListOpts) (*JobCollection, error) + Create(opts *Job) (*Job, error) + Update(existing *Job, updates interface{}) (*Job, error) + Replace(existing *Job) (*Job, error) + ByID(id string) (*Job, error) + Delete(container *Job) error +} + +func newJobClient(apiClient *Client) *JobClient { + return &JobClient{ + apiClient: apiClient, + } +} + +func (c *JobClient) Create(container *Job) (*Job, error) { + resp := &Job{} + err := c.apiClient.Ops.DoCreate(JobType, container, resp) + return resp, err +} + +func (c *JobClient) Update(existing *Job, updates interface{}) (*Job, error) { + resp := &Job{} + err := c.apiClient.Ops.DoUpdate(JobType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *JobClient) Replace(obj *Job) (*Job, error) { + resp := &Job{} + err := c.apiClient.Ops.DoReplace(JobType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *JobClient) List(opts *types.ListOpts) (*JobCollection, error) { + resp := &JobCollection{} + err := c.apiClient.Ops.DoList(JobType, opts, resp) + resp.client = c + return resp, err +} + +func (c *JobClient) ListAll(opts *types.ListOpts) (*JobCollection, error) { + resp := &JobCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *JobCollection) Next() (*JobCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &JobCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *JobClient) ByID(id string) (*Job, error) { + resp := &Job{} + err := c.apiClient.Ops.DoByID(JobType, id, resp) + return resp, err +} + +func (c *JobClient) Delete(container *Job) error { + return c.apiClient.Ops.DoResourceDelete(JobType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_condition.go new file mode 100644 index 0000000..6a63d07 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + JobConditionType = "jobCondition" + JobConditionFieldLastProbeTime = "lastProbeTime" + JobConditionFieldLastTransitionTime = "lastTransitionTime" + JobConditionFieldMessage = "message" + JobConditionFieldReason = "reason" + JobConditionFieldStatus = "status" + JobConditionFieldType = "type" +) + +type JobCondition struct { + LastProbeTime string `json:"lastProbeTime,omitempty" yaml:"lastProbeTime,omitempty"` + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_config.go new file mode 100644 index 0000000..ff99426 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_config.go @@ -0,0 +1,18 @@ +package client + +const ( + JobConfigType = "jobConfig" + JobConfigFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + JobConfigFieldBackoffLimit = "backoffLimit" + JobConfigFieldCompletions = "completions" + JobConfigFieldManualSelector = "manualSelector" + JobConfigFieldParallelism = "parallelism" +) + +type JobConfig struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + BackoffLimit *int64 `json:"backoffLimit,omitempty" yaml:"backoffLimit,omitempty"` + Completions *int64 `json:"completions,omitempty" yaml:"completions,omitempty"` + ManualSelector *bool `json:"manualSelector,omitempty" yaml:"manualSelector,omitempty"` + Parallelism *int64 `json:"parallelism,omitempty" yaml:"parallelism,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_spec.go new file mode 100644 index 0000000..0512387 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_spec.go @@ -0,0 +1,114 @@ +package client + +const ( + JobSpecType = "jobSpec" + JobSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + JobSpecFieldAppArmorProfile = "appArmorProfile" + JobSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + JobSpecFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + JobSpecFieldCompletionMode = "completionMode" + JobSpecFieldContainers = "containers" + JobSpecFieldDNSConfig = "dnsConfig" + JobSpecFieldDNSPolicy = "dnsPolicy" + JobSpecFieldEnableServiceLinks = "enableServiceLinks" + JobSpecFieldEphemeralContainers = "ephemeralContainers" + JobSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + JobSpecFieldFsgid = "fsgid" + JobSpecFieldGids = "gids" + JobSpecFieldHostAliases = "hostAliases" + JobSpecFieldHostIPC = "hostIPC" + JobSpecFieldHostNetwork = "hostNetwork" + JobSpecFieldHostPID = "hostPID" + JobSpecFieldHostUsers = "hostUsers" + JobSpecFieldHostname = "hostname" + JobSpecFieldImagePullSecrets = "imagePullSecrets" + JobSpecFieldJobConfig = "jobConfig" + JobSpecFieldManagedBy = "managedBy" + JobSpecFieldMaxFailedIndexes = "maxFailedIndexes" + JobSpecFieldNodeID = "nodeId" + JobSpecFieldOS = "os" + JobSpecFieldObjectMeta = "metadata" + JobSpecFieldOverhead = "overhead" + JobSpecFieldPodFailurePolicy = "podFailurePolicy" + JobSpecFieldPodReplacementPolicy = "podReplacementPolicy" + JobSpecFieldPreemptionPolicy = "preemptionPolicy" + JobSpecFieldReadinessGates = "readinessGates" + JobSpecFieldResourceClaims = "resourceClaims" + JobSpecFieldRestartPolicy = "restartPolicy" + JobSpecFieldRunAsGroup = "runAsGroup" + JobSpecFieldRunAsNonRoot = "runAsNonRoot" + JobSpecFieldRuntimeClassName = "runtimeClassName" + JobSpecFieldScheduling = "scheduling" + JobSpecFieldSchedulingGates = "schedulingGates" + JobSpecFieldSeccompProfile = "seccompProfile" + JobSpecFieldSelector = "selector" + JobSpecFieldServiceAccountName = "serviceAccountName" + JobSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + JobSpecFieldShareProcessNamespace = "shareProcessNamespace" + JobSpecFieldSubdomain = "subdomain" + JobSpecFieldSuccessPolicy = "successPolicy" + JobSpecFieldSuspend = "suspend" + JobSpecFieldSysctls = "sysctls" + JobSpecFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + JobSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + JobSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + JobSpecFieldUid = "uid" + JobSpecFieldVolumes = "volumes" + JobSpecFieldWindowsOptions = "windowsOptions" +) + +type JobSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + JobConfig *JobConfig `json:"jobConfig,omitempty" yaml:"jobConfig,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Suspend *bool `json:"suspend,omitempty" yaml:"suspend,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_status.go new file mode 100644 index 0000000..9df238a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_status.go @@ -0,0 +1,30 @@ +package client + +const ( + JobStatusType = "jobStatus" + JobStatusFieldActive = "active" + JobStatusFieldCompletedIndexes = "completedIndexes" + JobStatusFieldCompletionTime = "completionTime" + JobStatusFieldConditions = "conditions" + JobStatusFieldFailed = "failed" + JobStatusFieldFailedIndexes = "failedIndexes" + JobStatusFieldReady = "ready" + JobStatusFieldStartTime = "startTime" + JobStatusFieldSucceeded = "succeeded" + JobStatusFieldTerminating = "terminating" + JobStatusFieldUncountedTerminatedPods = "uncountedTerminatedPods" +) + +type JobStatus struct { + Active int64 `json:"active,omitempty" yaml:"active,omitempty"` + CompletedIndexes string `json:"completedIndexes,omitempty" yaml:"completedIndexes,omitempty"` + CompletionTime string `json:"completionTime,omitempty" yaml:"completionTime,omitempty"` + Conditions []JobCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + Failed int64 `json:"failed,omitempty" yaml:"failed,omitempty"` + FailedIndexes string `json:"failedIndexes,omitempty" yaml:"failedIndexes,omitempty"` + Ready *int64 `json:"ready,omitempty" yaml:"ready,omitempty"` + StartTime string `json:"startTime,omitempty" yaml:"startTime,omitempty"` + Succeeded int64 `json:"succeeded,omitempty" yaml:"succeeded,omitempty"` + Terminating *int64 `json:"terminating,omitempty" yaml:"terminating,omitempty"` + UncountedTerminatedPods *UncountedTerminatedPods `json:"uncountedTerminatedPods,omitempty" yaml:"uncountedTerminatedPods,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_template_spec.go new file mode 100644 index 0000000..4d34b40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_job_template_spec.go @@ -0,0 +1,116 @@ +package client + +const ( + JobTemplateSpecType = "jobTemplateSpec" + JobTemplateSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + JobTemplateSpecFieldAppArmorProfile = "appArmorProfile" + JobTemplateSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + JobTemplateSpecFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + JobTemplateSpecFieldCompletionMode = "completionMode" + JobTemplateSpecFieldContainers = "containers" + JobTemplateSpecFieldDNSConfig = "dnsConfig" + JobTemplateSpecFieldDNSPolicy = "dnsPolicy" + JobTemplateSpecFieldEnableServiceLinks = "enableServiceLinks" + JobTemplateSpecFieldEphemeralContainers = "ephemeralContainers" + JobTemplateSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + JobTemplateSpecFieldFsgid = "fsgid" + JobTemplateSpecFieldGids = "gids" + JobTemplateSpecFieldHostAliases = "hostAliases" + JobTemplateSpecFieldHostIPC = "hostIPC" + JobTemplateSpecFieldHostNetwork = "hostNetwork" + JobTemplateSpecFieldHostPID = "hostPID" + JobTemplateSpecFieldHostUsers = "hostUsers" + JobTemplateSpecFieldHostname = "hostname" + JobTemplateSpecFieldImagePullSecrets = "imagePullSecrets" + JobTemplateSpecFieldJobConfig = "jobConfig" + JobTemplateSpecFieldJobMetadata = "jobMetadata" + JobTemplateSpecFieldManagedBy = "managedBy" + JobTemplateSpecFieldMaxFailedIndexes = "maxFailedIndexes" + JobTemplateSpecFieldNodeID = "nodeId" + JobTemplateSpecFieldOS = "os" + JobTemplateSpecFieldObjectMeta = "metadata" + JobTemplateSpecFieldOverhead = "overhead" + JobTemplateSpecFieldPodFailurePolicy = "podFailurePolicy" + JobTemplateSpecFieldPodReplacementPolicy = "podReplacementPolicy" + JobTemplateSpecFieldPreemptionPolicy = "preemptionPolicy" + JobTemplateSpecFieldReadinessGates = "readinessGates" + JobTemplateSpecFieldResourceClaims = "resourceClaims" + JobTemplateSpecFieldRestartPolicy = "restartPolicy" + JobTemplateSpecFieldRunAsGroup = "runAsGroup" + JobTemplateSpecFieldRunAsNonRoot = "runAsNonRoot" + JobTemplateSpecFieldRuntimeClassName = "runtimeClassName" + JobTemplateSpecFieldScheduling = "scheduling" + JobTemplateSpecFieldSchedulingGates = "schedulingGates" + JobTemplateSpecFieldSeccompProfile = "seccompProfile" + JobTemplateSpecFieldSelector = "selector" + JobTemplateSpecFieldServiceAccountName = "serviceAccountName" + JobTemplateSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + JobTemplateSpecFieldShareProcessNamespace = "shareProcessNamespace" + JobTemplateSpecFieldSubdomain = "subdomain" + JobTemplateSpecFieldSuccessPolicy = "successPolicy" + JobTemplateSpecFieldSuspend = "suspend" + JobTemplateSpecFieldSysctls = "sysctls" + JobTemplateSpecFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + JobTemplateSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + JobTemplateSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + JobTemplateSpecFieldUid = "uid" + JobTemplateSpecFieldVolumes = "volumes" + JobTemplateSpecFieldWindowsOptions = "windowsOptions" +) + +type JobTemplateSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + JobConfig *JobConfig `json:"jobConfig,omitempty" yaml:"jobConfig,omitempty"` + JobMetadata *ObjectMeta `json:"jobMetadata,omitempty" yaml:"jobMetadata,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Suspend *bool `json:"suspend,omitempty" yaml:"suspend,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_key_to_path.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_key_to_path.go new file mode 100644 index 0000000..de4ae60 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_key_to_path.go @@ -0,0 +1,14 @@ +package client + +const ( + KeyToPathType = "keyToPath" + KeyToPathFieldKey = "key" + KeyToPathFieldMode = "mode" + KeyToPathFieldPath = "path" +) + +type KeyToPath struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Mode *int64 `json:"mode,omitempty" yaml:"mode,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector.go new file mode 100644 index 0000000..27162cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector.go @@ -0,0 +1,12 @@ +package client + +const ( + LabelSelectorType = "labelSelector" + LabelSelectorFieldMatchExpressions = "matchExpressions" + LabelSelectorFieldMatchLabels = "matchLabels" +) + +type LabelSelector struct { + MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" yaml:"matchExpressions,omitempty"` + MatchLabels map[string]string `json:"matchLabels,omitempty" yaml:"matchLabels,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector_requirement.go new file mode 100644 index 0000000..3a875ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_label_selector_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + LabelSelectorRequirementType = "labelSelectorRequirement" + LabelSelectorRequirementFieldKey = "key" + LabelSelectorRequirementFieldOperator = "operator" + LabelSelectorRequirementFieldValues = "values" +) + +type LabelSelectorRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle.go new file mode 100644 index 0000000..376d104 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle.go @@ -0,0 +1,12 @@ +package client + +const ( + LifecycleType = "lifecycle" + LifecycleFieldPostStart = "postStart" + LifecycleFieldPreStop = "preStop" +) + +type Lifecycle struct { + PostStart *LifecycleHandler `json:"postStart,omitempty" yaml:"postStart,omitempty"` + PreStop *LifecycleHandler `json:"preStop,omitempty" yaml:"preStop,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle_handler.go new file mode 100644 index 0000000..7cd3240 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_lifecycle_handler.go @@ -0,0 +1,28 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + LifecycleHandlerType = "lifecycleHandler" + LifecycleHandlerFieldCommand = "command" + LifecycleHandlerFieldHTTPHeaders = "httpHeaders" + LifecycleHandlerFieldHost = "host" + LifecycleHandlerFieldPath = "path" + LifecycleHandlerFieldPort = "port" + LifecycleHandlerFieldScheme = "scheme" + LifecycleHandlerFieldSleep = "sleep" + LifecycleHandlerFieldTCP = "tcp" +) + +type LifecycleHandler struct { + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty" yaml:"httpHeaders,omitempty"` + Host string `json:"host,omitempty" yaml:"host,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Port intstr.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` + Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"` + Sleep *SleepAction `json:"sleep,omitempty" yaml:"sleep,omitempty"` + TCP bool `json:"tcp,omitempty" yaml:"tcp,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_ingress.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_ingress.go new file mode 100644 index 0000000..cc04685 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_ingress.go @@ -0,0 +1,16 @@ +package client + +const ( + LoadBalancerIngressType = "loadBalancerIngress" + LoadBalancerIngressFieldHostname = "hostname" + LoadBalancerIngressFieldIP = "ip" + LoadBalancerIngressFieldIPMode = "ipMode" + LoadBalancerIngressFieldPorts = "ports" +) + +type LoadBalancerIngress struct { + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IP string `json:"ip,omitempty" yaml:"ip,omitempty"` + IPMode string `json:"ipMode,omitempty" yaml:"ipMode,omitempty"` + Ports []PortStatus `json:"ports,omitempty" yaml:"ports,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_status.go new file mode 100644 index 0000000..453a337 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_load_balancer_status.go @@ -0,0 +1,10 @@ +package client + +const ( + LoadBalancerStatusType = "loadBalancerStatus" + LoadBalancerStatusFieldIngress = "ingress" +) + +type LoadBalancerStatus struct { + Ingress []LoadBalancerIngress `json:"ingress,omitempty" yaml:"ingress,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_object_reference.go new file mode 100644 index 0000000..e4d3b50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_object_reference.go @@ -0,0 +1,10 @@ +package client + +const ( + LocalObjectReferenceType = "localObjectReference" + LocalObjectReferenceFieldName = "name" +) + +type LocalObjectReference struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_volume_source.go new file mode 100644 index 0000000..6dea350 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_local_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + LocalVolumeSourceType = "localVolumeSource" + LocalVolumeSourceFieldFSType = "fsType" + LocalVolumeSourceFieldPath = "path" +) + +type LocalVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric.go new file mode 100644 index 0000000..d5bdc15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric.go @@ -0,0 +1,22 @@ +package client + +const ( + MetricType = "metric" + MetricFieldContainerResource = "containerResource" + MetricFieldCurrent = "current" + MetricFieldDescribedObject = "describedObject" + MetricFieldName = "name" + MetricFieldSelector = "selector" + MetricFieldTarget = "target" + MetricFieldType = "type" +) + +type Metric struct { + ContainerResource *ContainerResourceMetricSource `json:"containerResource,omitempty" yaml:"containerResource,omitempty"` + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + DescribedObject *CrossVersionObjectReference `json:"describedObject,omitempty" yaml:"describedObject,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_identifier.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_identifier.go new file mode 100644 index 0000000..0d86b90 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_identifier.go @@ -0,0 +1,12 @@ +package client + +const ( + MetricIdentifierType = "metricIdentifier" + MetricIdentifierFieldName = "name" + MetricIdentifierFieldSelector = "selector" +) + +type MetricIdentifier struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_status.go new file mode 100644 index 0000000..aec92a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_status.go @@ -0,0 +1,22 @@ +package client + +const ( + MetricStatusType = "metricStatus" + MetricStatusFieldContainerResource = "containerResource" + MetricStatusFieldCurrent = "current" + MetricStatusFieldExternal = "external" + MetricStatusFieldObject = "object" + MetricStatusFieldPods = "pods" + MetricStatusFieldResource = "resource" + MetricStatusFieldType = "type" +) + +type MetricStatus struct { + ContainerResource *ContainerResourceMetricStatus `json:"containerResource,omitempty" yaml:"containerResource,omitempty"` + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + External *ExternalMetricStatus `json:"external,omitempty" yaml:"external,omitempty"` + Object *ObjectMetricStatus `json:"object,omitempty" yaml:"object,omitempty"` + Pods *PodsMetricStatus `json:"pods,omitempty" yaml:"pods,omitempty"` + Resource *ResourceMetricStatus `json:"resource,omitempty" yaml:"resource,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_target.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_target.go new file mode 100644 index 0000000..ca3b7f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_target.go @@ -0,0 +1,16 @@ +package client + +const ( + MetricTargetType = "metricTarget" + MetricTargetFieldAverageValue = "averageValue" + MetricTargetFieldType = "type" + MetricTargetFieldUtilization = "utilization" + MetricTargetFieldValue = "value" +) + +type MetricTarget struct { + AverageValue string `json:"averageValue,omitempty" yaml:"averageValue,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + Utilization *int64 `json:"utilization,omitempty" yaml:"utilization,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_value_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_value_status.go new file mode 100644 index 0000000..1dd7089 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_metric_value_status.go @@ -0,0 +1,14 @@ +package client + +const ( + MetricValueStatusType = "metricValueStatus" + MetricValueStatusFieldAverageValue = "averageValue" + MetricValueStatusFieldUtilization = "utilization" + MetricValueStatusFieldValue = "value" +) + +type MetricValueStatus struct { + AverageValue string `json:"averageValue,omitempty" yaml:"averageValue,omitempty"` + Utilization *int64 `json:"utilization,omitempty" yaml:"utilization,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_modify_volume_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_modify_volume_status.go new file mode 100644 index 0000000..bef0f99 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_modify_volume_status.go @@ -0,0 +1,12 @@ +package client + +const ( + ModifyVolumeStatusType = "modifyVolumeStatus" + ModifyVolumeStatusFieldStatus = "status" + ModifyVolumeStatusFieldTargetVolumeAttributesClassName = "targetVolumeAttributesClassName" +) + +type ModifyVolumeStatus struct { + Status string `json:"status,omitempty" yaml:"status,omitempty"` + TargetVolumeAttributesClassName string `json:"targetVolumeAttributesClassName,omitempty" yaml:"targetVolumeAttributesClassName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_basic_auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_basic_auth.go new file mode 100644 index 0000000..e83b912 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_basic_auth.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedBasicAuthType = "namespacedBasicAuth" + NamespacedBasicAuthFieldAnnotations = "annotations" + NamespacedBasicAuthFieldCreated = "created" + NamespacedBasicAuthFieldCreatorID = "creatorId" + NamespacedBasicAuthFieldDescription = "description" + NamespacedBasicAuthFieldLabels = "labels" + NamespacedBasicAuthFieldName = "name" + NamespacedBasicAuthFieldNamespaceId = "namespaceId" + NamespacedBasicAuthFieldOwnerReferences = "ownerReferences" + NamespacedBasicAuthFieldPassword = "password" + NamespacedBasicAuthFieldProjectID = "projectId" + NamespacedBasicAuthFieldRemoved = "removed" + NamespacedBasicAuthFieldUUID = "uuid" + NamespacedBasicAuthFieldUsername = "username" +) + +type NamespacedBasicAuth struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} + +type NamespacedBasicAuthCollection struct { + types.Collection + Data []NamespacedBasicAuth `json:"data,omitempty"` + client *NamespacedBasicAuthClient +} + +type NamespacedBasicAuthClient struct { + apiClient *Client +} + +type NamespacedBasicAuthOperations interface { + List(opts *types.ListOpts) (*NamespacedBasicAuthCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedBasicAuthCollection, error) + Create(opts *NamespacedBasicAuth) (*NamespacedBasicAuth, error) + Update(existing *NamespacedBasicAuth, updates interface{}) (*NamespacedBasicAuth, error) + Replace(existing *NamespacedBasicAuth) (*NamespacedBasicAuth, error) + ByID(id string) (*NamespacedBasicAuth, error) + Delete(container *NamespacedBasicAuth) error +} + +func newNamespacedBasicAuthClient(apiClient *Client) *NamespacedBasicAuthClient { + return &NamespacedBasicAuthClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedBasicAuthClient) Create(container *NamespacedBasicAuth) (*NamespacedBasicAuth, error) { + resp := &NamespacedBasicAuth{} + err := c.apiClient.Ops.DoCreate(NamespacedBasicAuthType, container, resp) + return resp, err +} + +func (c *NamespacedBasicAuthClient) Update(existing *NamespacedBasicAuth, updates interface{}) (*NamespacedBasicAuth, error) { + resp := &NamespacedBasicAuth{} + err := c.apiClient.Ops.DoUpdate(NamespacedBasicAuthType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedBasicAuthClient) Replace(obj *NamespacedBasicAuth) (*NamespacedBasicAuth, error) { + resp := &NamespacedBasicAuth{} + err := c.apiClient.Ops.DoReplace(NamespacedBasicAuthType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedBasicAuthClient) List(opts *types.ListOpts) (*NamespacedBasicAuthCollection, error) { + resp := &NamespacedBasicAuthCollection{} + err := c.apiClient.Ops.DoList(NamespacedBasicAuthType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedBasicAuthClient) ListAll(opts *types.ListOpts) (*NamespacedBasicAuthCollection, error) { + resp := &NamespacedBasicAuthCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedBasicAuthCollection) Next() (*NamespacedBasicAuthCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedBasicAuthCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedBasicAuthClient) ByID(id string) (*NamespacedBasicAuth, error) { + resp := &NamespacedBasicAuth{} + err := c.apiClient.Ops.DoByID(NamespacedBasicAuthType, id, resp) + return resp, err +} + +func (c *NamespacedBasicAuthClient) Delete(container *NamespacedBasicAuth) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedBasicAuthType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_certificate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_certificate.go new file mode 100644 index 0000000..c6e1c1e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_certificate.go @@ -0,0 +1,148 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedCertificateType = "namespacedCertificate" + NamespacedCertificateFieldAlgorithm = "algorithm" + NamespacedCertificateFieldAnnotations = "annotations" + NamespacedCertificateFieldCN = "cn" + NamespacedCertificateFieldCertFingerprint = "certFingerprint" + NamespacedCertificateFieldCerts = "certs" + NamespacedCertificateFieldCreated = "created" + NamespacedCertificateFieldCreatorID = "creatorId" + NamespacedCertificateFieldDescription = "description" + NamespacedCertificateFieldExpiresAt = "expiresAt" + NamespacedCertificateFieldIssuedAt = "issuedAt" + NamespacedCertificateFieldIssuer = "issuer" + NamespacedCertificateFieldKey = "key" + NamespacedCertificateFieldKeySize = "keySize" + NamespacedCertificateFieldLabels = "labels" + NamespacedCertificateFieldName = "name" + NamespacedCertificateFieldNamespaceId = "namespaceId" + NamespacedCertificateFieldOwnerReferences = "ownerReferences" + NamespacedCertificateFieldProjectID = "projectId" + NamespacedCertificateFieldRemoved = "removed" + NamespacedCertificateFieldSerialNumber = "serialNumber" + NamespacedCertificateFieldSubjectAlternativeNames = "subjectAlternativeNames" + NamespacedCertificateFieldUUID = "uuid" + NamespacedCertificateFieldVersion = "version" +) + +type NamespacedCertificate struct { + types.Resource + Algorithm string `json:"algorithm,omitempty" yaml:"algorithm,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CN string `json:"cn,omitempty" yaml:"cn,omitempty"` + CertFingerprint string `json:"certFingerprint,omitempty" yaml:"certFingerprint,omitempty"` + Certs string `json:"certs,omitempty" yaml:"certs,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExpiresAt string `json:"expiresAt,omitempty" yaml:"expiresAt,omitempty"` + IssuedAt string `json:"issuedAt,omitempty" yaml:"issuedAt,omitempty"` + Issuer string `json:"issuer,omitempty" yaml:"issuer,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + KeySize string `json:"keySize,omitempty" yaml:"keySize,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SerialNumber string `json:"serialNumber,omitempty" yaml:"serialNumber,omitempty"` + SubjectAlternativeNames []string `json:"subjectAlternativeNames,omitempty" yaml:"subjectAlternativeNames,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` +} + +type NamespacedCertificateCollection struct { + types.Collection + Data []NamespacedCertificate `json:"data,omitempty"` + client *NamespacedCertificateClient +} + +type NamespacedCertificateClient struct { + apiClient *Client +} + +type NamespacedCertificateOperations interface { + List(opts *types.ListOpts) (*NamespacedCertificateCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedCertificateCollection, error) + Create(opts *NamespacedCertificate) (*NamespacedCertificate, error) + Update(existing *NamespacedCertificate, updates interface{}) (*NamespacedCertificate, error) + Replace(existing *NamespacedCertificate) (*NamespacedCertificate, error) + ByID(id string) (*NamespacedCertificate, error) + Delete(container *NamespacedCertificate) error +} + +func newNamespacedCertificateClient(apiClient *Client) *NamespacedCertificateClient { + return &NamespacedCertificateClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedCertificateClient) Create(container *NamespacedCertificate) (*NamespacedCertificate, error) { + resp := &NamespacedCertificate{} + err := c.apiClient.Ops.DoCreate(NamespacedCertificateType, container, resp) + return resp, err +} + +func (c *NamespacedCertificateClient) Update(existing *NamespacedCertificate, updates interface{}) (*NamespacedCertificate, error) { + resp := &NamespacedCertificate{} + err := c.apiClient.Ops.DoUpdate(NamespacedCertificateType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedCertificateClient) Replace(obj *NamespacedCertificate) (*NamespacedCertificate, error) { + resp := &NamespacedCertificate{} + err := c.apiClient.Ops.DoReplace(NamespacedCertificateType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedCertificateClient) List(opts *types.ListOpts) (*NamespacedCertificateCollection, error) { + resp := &NamespacedCertificateCollection{} + err := c.apiClient.Ops.DoList(NamespacedCertificateType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedCertificateClient) ListAll(opts *types.ListOpts) (*NamespacedCertificateCollection, error) { + resp := &NamespacedCertificateCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedCertificateCollection) Next() (*NamespacedCertificateCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedCertificateCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedCertificateClient) ByID(id string) (*NamespacedCertificate, error) { + resp := &NamespacedCertificate{} + err := c.apiClient.Ops.DoByID(NamespacedCertificateType, id, resp) + return resp, err +} + +func (c *NamespacedCertificateClient) Delete(container *NamespacedCertificate) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedCertificateType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_docker_credential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_docker_credential.go new file mode 100644 index 0000000..1f8fabd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_docker_credential.go @@ -0,0 +1,126 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedDockerCredentialType = "namespacedDockerCredential" + NamespacedDockerCredentialFieldAnnotations = "annotations" + NamespacedDockerCredentialFieldCreated = "created" + NamespacedDockerCredentialFieldCreatorID = "creatorId" + NamespacedDockerCredentialFieldDescription = "description" + NamespacedDockerCredentialFieldLabels = "labels" + NamespacedDockerCredentialFieldName = "name" + NamespacedDockerCredentialFieldNamespaceId = "namespaceId" + NamespacedDockerCredentialFieldOwnerReferences = "ownerReferences" + NamespacedDockerCredentialFieldProjectID = "projectId" + NamespacedDockerCredentialFieldRegistries = "registries" + NamespacedDockerCredentialFieldRemoved = "removed" + NamespacedDockerCredentialFieldUUID = "uuid" +) + +type NamespacedDockerCredential struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Registries map[string]RegistryCredential `json:"registries,omitempty" yaml:"registries,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type NamespacedDockerCredentialCollection struct { + types.Collection + Data []NamespacedDockerCredential `json:"data,omitempty"` + client *NamespacedDockerCredentialClient +} + +type NamespacedDockerCredentialClient struct { + apiClient *Client +} + +type NamespacedDockerCredentialOperations interface { + List(opts *types.ListOpts) (*NamespacedDockerCredentialCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedDockerCredentialCollection, error) + Create(opts *NamespacedDockerCredential) (*NamespacedDockerCredential, error) + Update(existing *NamespacedDockerCredential, updates interface{}) (*NamespacedDockerCredential, error) + Replace(existing *NamespacedDockerCredential) (*NamespacedDockerCredential, error) + ByID(id string) (*NamespacedDockerCredential, error) + Delete(container *NamespacedDockerCredential) error +} + +func newNamespacedDockerCredentialClient(apiClient *Client) *NamespacedDockerCredentialClient { + return &NamespacedDockerCredentialClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedDockerCredentialClient) Create(container *NamespacedDockerCredential) (*NamespacedDockerCredential, error) { + resp := &NamespacedDockerCredential{} + err := c.apiClient.Ops.DoCreate(NamespacedDockerCredentialType, container, resp) + return resp, err +} + +func (c *NamespacedDockerCredentialClient) Update(existing *NamespacedDockerCredential, updates interface{}) (*NamespacedDockerCredential, error) { + resp := &NamespacedDockerCredential{} + err := c.apiClient.Ops.DoUpdate(NamespacedDockerCredentialType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedDockerCredentialClient) Replace(obj *NamespacedDockerCredential) (*NamespacedDockerCredential, error) { + resp := &NamespacedDockerCredential{} + err := c.apiClient.Ops.DoReplace(NamespacedDockerCredentialType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedDockerCredentialClient) List(opts *types.ListOpts) (*NamespacedDockerCredentialCollection, error) { + resp := &NamespacedDockerCredentialCollection{} + err := c.apiClient.Ops.DoList(NamespacedDockerCredentialType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedDockerCredentialClient) ListAll(opts *types.ListOpts) (*NamespacedDockerCredentialCollection, error) { + resp := &NamespacedDockerCredentialCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedDockerCredentialCollection) Next() (*NamespacedDockerCredentialCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedDockerCredentialCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedDockerCredentialClient) ByID(id string) (*NamespacedDockerCredential, error) { + resp := &NamespacedDockerCredential{} + err := c.apiClient.Ops.DoByID(NamespacedDockerCredentialType, id, resp) + return resp, err +} + +func (c *NamespacedDockerCredentialClient) Delete(container *NamespacedDockerCredential) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedDockerCredentialType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_secret.go new file mode 100644 index 0000000..2b243cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_secret.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedSecretType = "namespacedSecret" + NamespacedSecretFieldAnnotations = "annotations" + NamespacedSecretFieldCreated = "created" + NamespacedSecretFieldCreatorID = "creatorId" + NamespacedSecretFieldData = "data" + NamespacedSecretFieldDescription = "description" + NamespacedSecretFieldImmutable = "immutable" + NamespacedSecretFieldKind = "kind" + NamespacedSecretFieldLabels = "labels" + NamespacedSecretFieldName = "name" + NamespacedSecretFieldNamespaceId = "namespaceId" + NamespacedSecretFieldOwnerReferences = "ownerReferences" + NamespacedSecretFieldProjectID = "projectId" + NamespacedSecretFieldRemoved = "removed" + NamespacedSecretFieldStringData = "stringData" + NamespacedSecretFieldUUID = "uuid" +) + +type NamespacedSecret struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Immutable *bool `json:"immutable,omitempty" yaml:"immutable,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + StringData map[string]string `json:"stringData,omitempty" yaml:"stringData,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type NamespacedSecretCollection struct { + types.Collection + Data []NamespacedSecret `json:"data,omitempty"` + client *NamespacedSecretClient +} + +type NamespacedSecretClient struct { + apiClient *Client +} + +type NamespacedSecretOperations interface { + List(opts *types.ListOpts) (*NamespacedSecretCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedSecretCollection, error) + Create(opts *NamespacedSecret) (*NamespacedSecret, error) + Update(existing *NamespacedSecret, updates interface{}) (*NamespacedSecret, error) + Replace(existing *NamespacedSecret) (*NamespacedSecret, error) + ByID(id string) (*NamespacedSecret, error) + Delete(container *NamespacedSecret) error +} + +func newNamespacedSecretClient(apiClient *Client) *NamespacedSecretClient { + return &NamespacedSecretClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedSecretClient) Create(container *NamespacedSecret) (*NamespacedSecret, error) { + resp := &NamespacedSecret{} + err := c.apiClient.Ops.DoCreate(NamespacedSecretType, container, resp) + return resp, err +} + +func (c *NamespacedSecretClient) Update(existing *NamespacedSecret, updates interface{}) (*NamespacedSecret, error) { + resp := &NamespacedSecret{} + err := c.apiClient.Ops.DoUpdate(NamespacedSecretType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedSecretClient) Replace(obj *NamespacedSecret) (*NamespacedSecret, error) { + resp := &NamespacedSecret{} + err := c.apiClient.Ops.DoReplace(NamespacedSecretType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedSecretClient) List(opts *types.ListOpts) (*NamespacedSecretCollection, error) { + resp := &NamespacedSecretCollection{} + err := c.apiClient.Ops.DoList(NamespacedSecretType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedSecretClient) ListAll(opts *types.ListOpts) (*NamespacedSecretCollection, error) { + resp := &NamespacedSecretCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedSecretCollection) Next() (*NamespacedSecretCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedSecretCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedSecretClient) ByID(id string) (*NamespacedSecret, error) { + resp := &NamespacedSecret{} + err := c.apiClient.Ops.DoByID(NamespacedSecretType, id, resp) + return resp, err +} + +func (c *NamespacedSecretClient) Delete(container *NamespacedSecret) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedSecretType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_service_account_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_service_account_token.go new file mode 100644 index 0000000..9d682b6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_service_account_token.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedServiceAccountTokenType = "namespacedServiceAccountToken" + NamespacedServiceAccountTokenFieldAccountName = "accountName" + NamespacedServiceAccountTokenFieldAccountUID = "accountUid" + NamespacedServiceAccountTokenFieldAnnotations = "annotations" + NamespacedServiceAccountTokenFieldCACRT = "caCrt" + NamespacedServiceAccountTokenFieldCreated = "created" + NamespacedServiceAccountTokenFieldCreatorID = "creatorId" + NamespacedServiceAccountTokenFieldDescription = "description" + NamespacedServiceAccountTokenFieldLabels = "labels" + NamespacedServiceAccountTokenFieldName = "name" + NamespacedServiceAccountTokenFieldNamespaceId = "namespaceId" + NamespacedServiceAccountTokenFieldOwnerReferences = "ownerReferences" + NamespacedServiceAccountTokenFieldProjectID = "projectId" + NamespacedServiceAccountTokenFieldRemoved = "removed" + NamespacedServiceAccountTokenFieldToken = "token" + NamespacedServiceAccountTokenFieldUUID = "uuid" +) + +type NamespacedServiceAccountToken struct { + types.Resource + AccountName string `json:"accountName,omitempty" yaml:"accountName,omitempty"` + AccountUID string `json:"accountUid,omitempty" yaml:"accountUid,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CACRT string `json:"caCrt,omitempty" yaml:"caCrt,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type NamespacedServiceAccountTokenCollection struct { + types.Collection + Data []NamespacedServiceAccountToken `json:"data,omitempty"` + client *NamespacedServiceAccountTokenClient +} + +type NamespacedServiceAccountTokenClient struct { + apiClient *Client +} + +type NamespacedServiceAccountTokenOperations interface { + List(opts *types.ListOpts) (*NamespacedServiceAccountTokenCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedServiceAccountTokenCollection, error) + Create(opts *NamespacedServiceAccountToken) (*NamespacedServiceAccountToken, error) + Update(existing *NamespacedServiceAccountToken, updates interface{}) (*NamespacedServiceAccountToken, error) + Replace(existing *NamespacedServiceAccountToken) (*NamespacedServiceAccountToken, error) + ByID(id string) (*NamespacedServiceAccountToken, error) + Delete(container *NamespacedServiceAccountToken) error +} + +func newNamespacedServiceAccountTokenClient(apiClient *Client) *NamespacedServiceAccountTokenClient { + return &NamespacedServiceAccountTokenClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedServiceAccountTokenClient) Create(container *NamespacedServiceAccountToken) (*NamespacedServiceAccountToken, error) { + resp := &NamespacedServiceAccountToken{} + err := c.apiClient.Ops.DoCreate(NamespacedServiceAccountTokenType, container, resp) + return resp, err +} + +func (c *NamespacedServiceAccountTokenClient) Update(existing *NamespacedServiceAccountToken, updates interface{}) (*NamespacedServiceAccountToken, error) { + resp := &NamespacedServiceAccountToken{} + err := c.apiClient.Ops.DoUpdate(NamespacedServiceAccountTokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedServiceAccountTokenClient) Replace(obj *NamespacedServiceAccountToken) (*NamespacedServiceAccountToken, error) { + resp := &NamespacedServiceAccountToken{} + err := c.apiClient.Ops.DoReplace(NamespacedServiceAccountTokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedServiceAccountTokenClient) List(opts *types.ListOpts) (*NamespacedServiceAccountTokenCollection, error) { + resp := &NamespacedServiceAccountTokenCollection{} + err := c.apiClient.Ops.DoList(NamespacedServiceAccountTokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedServiceAccountTokenClient) ListAll(opts *types.ListOpts) (*NamespacedServiceAccountTokenCollection, error) { + resp := &NamespacedServiceAccountTokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedServiceAccountTokenCollection) Next() (*NamespacedServiceAccountTokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedServiceAccountTokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedServiceAccountTokenClient) ByID(id string) (*NamespacedServiceAccountToken, error) { + resp := &NamespacedServiceAccountToken{} + err := c.apiClient.Ops.DoByID(NamespacedServiceAccountTokenType, id, resp) + return resp, err +} + +func (c *NamespacedServiceAccountTokenClient) Delete(container *NamespacedServiceAccountToken) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedServiceAccountTokenType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_ssh_auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_ssh_auth.go new file mode 100644 index 0000000..87f5e96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_namespaced_ssh_auth.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + NamespacedSSHAuthType = "namespacedSshAuth" + NamespacedSSHAuthFieldAnnotations = "annotations" + NamespacedSSHAuthFieldCreated = "created" + NamespacedSSHAuthFieldCreatorID = "creatorId" + NamespacedSSHAuthFieldDescription = "description" + NamespacedSSHAuthFieldFingerprint = "certFingerprint" + NamespacedSSHAuthFieldLabels = "labels" + NamespacedSSHAuthFieldName = "name" + NamespacedSSHAuthFieldNamespaceId = "namespaceId" + NamespacedSSHAuthFieldOwnerReferences = "ownerReferences" + NamespacedSSHAuthFieldPrivateKey = "privateKey" + NamespacedSSHAuthFieldProjectID = "projectId" + NamespacedSSHAuthFieldRemoved = "removed" + NamespacedSSHAuthFieldUUID = "uuid" +) + +type NamespacedSSHAuth struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Fingerprint string `json:"certFingerprint,omitempty" yaml:"certFingerprint,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type NamespacedSSHAuthCollection struct { + types.Collection + Data []NamespacedSSHAuth `json:"data,omitempty"` + client *NamespacedSSHAuthClient +} + +type NamespacedSSHAuthClient struct { + apiClient *Client +} + +type NamespacedSSHAuthOperations interface { + List(opts *types.ListOpts) (*NamespacedSSHAuthCollection, error) + ListAll(opts *types.ListOpts) (*NamespacedSSHAuthCollection, error) + Create(opts *NamespacedSSHAuth) (*NamespacedSSHAuth, error) + Update(existing *NamespacedSSHAuth, updates interface{}) (*NamespacedSSHAuth, error) + Replace(existing *NamespacedSSHAuth) (*NamespacedSSHAuth, error) + ByID(id string) (*NamespacedSSHAuth, error) + Delete(container *NamespacedSSHAuth) error +} + +func newNamespacedSSHAuthClient(apiClient *Client) *NamespacedSSHAuthClient { + return &NamespacedSSHAuthClient{ + apiClient: apiClient, + } +} + +func (c *NamespacedSSHAuthClient) Create(container *NamespacedSSHAuth) (*NamespacedSSHAuth, error) { + resp := &NamespacedSSHAuth{} + err := c.apiClient.Ops.DoCreate(NamespacedSSHAuthType, container, resp) + return resp, err +} + +func (c *NamespacedSSHAuthClient) Update(existing *NamespacedSSHAuth, updates interface{}) (*NamespacedSSHAuth, error) { + resp := &NamespacedSSHAuth{} + err := c.apiClient.Ops.DoUpdate(NamespacedSSHAuthType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *NamespacedSSHAuthClient) Replace(obj *NamespacedSSHAuth) (*NamespacedSSHAuth, error) { + resp := &NamespacedSSHAuth{} + err := c.apiClient.Ops.DoReplace(NamespacedSSHAuthType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *NamespacedSSHAuthClient) List(opts *types.ListOpts) (*NamespacedSSHAuthCollection, error) { + resp := &NamespacedSSHAuthCollection{} + err := c.apiClient.Ops.DoList(NamespacedSSHAuthType, opts, resp) + resp.client = c + return resp, err +} + +func (c *NamespacedSSHAuthClient) ListAll(opts *types.ListOpts) (*NamespacedSSHAuthCollection, error) { + resp := &NamespacedSSHAuthCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *NamespacedSSHAuthCollection) Next() (*NamespacedSSHAuthCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &NamespacedSSHAuthCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *NamespacedSSHAuthClient) ByID(id string) (*NamespacedSSHAuth, error) { + resp := &NamespacedSSHAuth{} + err := c.apiClient.Ops.DoByID(NamespacedSSHAuthType, id, resp) + return resp, err +} + +func (c *NamespacedSSHAuthClient) Delete(container *NamespacedSSHAuth) error { + return c.apiClient.Ops.DoResourceDelete(NamespacedSSHAuthType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_nfs_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_nfs_volume_source.go new file mode 100644 index 0000000..bbaeecf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_nfs_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + NFSVolumeSourceType = "nfsVolumeSource" + NFSVolumeSourceFieldPath = "path" + NFSVolumeSourceFieldReadOnly = "readOnly" + NFSVolumeSourceFieldServer = "server" +) + +type NFSVolumeSource struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Server string `json:"server,omitempty" yaml:"server,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_affinity.go new file mode 100644 index 0000000..c1563ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeAffinityType = "nodeAffinity" + NodeAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + NodeAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type NodeAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []PreferredSchedulingTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution *NodeSelector `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_scheduling.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_scheduling.go new file mode 100644 index 0000000..9e577da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_scheduling.go @@ -0,0 +1,16 @@ +package client + +const ( + NodeSchedulingType = "nodeScheduling" + NodeSchedulingFieldNodeID = "nodeId" + NodeSchedulingFieldPreferred = "preferred" + NodeSchedulingFieldRequireAll = "requireAll" + NodeSchedulingFieldRequireAny = "requireAny" +) + +type NodeScheduling struct { + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + Preferred []string `json:"preferred,omitempty" yaml:"preferred,omitempty"` + RequireAll []string `json:"requireAll,omitempty" yaml:"requireAll,omitempty"` + RequireAny []string `json:"requireAny,omitempty" yaml:"requireAny,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector.go new file mode 100644 index 0000000..721a16f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector.go @@ -0,0 +1,10 @@ +package client + +const ( + NodeSelectorType = "nodeSelector" + NodeSelectorFieldNodeSelectorTerms = "nodeSelectorTerms" +) + +type NodeSelector struct { + NodeSelectorTerms []NodeSelectorTerm `json:"nodeSelectorTerms,omitempty" yaml:"nodeSelectorTerms,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_requirement.go new file mode 100644 index 0000000..9338a8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + NodeSelectorRequirementType = "nodeSelectorRequirement" + NodeSelectorRequirementFieldKey = "key" + NodeSelectorRequirementFieldOperator = "operator" + NodeSelectorRequirementFieldValues = "values" +) + +type NodeSelectorRequirement struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []string `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_term.go new file mode 100644 index 0000000..11bf256 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_node_selector_term.go @@ -0,0 +1,12 @@ +package client + +const ( + NodeSelectorTermType = "nodeSelectorTerm" + NodeSelectorTermFieldMatchExpressions = "matchExpressions" + NodeSelectorTermFieldMatchFields = "matchFields" +) + +type NodeSelectorTerm struct { + MatchExpressions []NodeSelectorRequirement `json:"matchExpressions,omitempty" yaml:"matchExpressions,omitempty"` + MatchFields []NodeSelectorRequirement `json:"matchFields,omitempty" yaml:"matchFields,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_field_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_field_selector.go new file mode 100644 index 0000000..4951d2a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_field_selector.go @@ -0,0 +1,12 @@ +package client + +const ( + ObjectFieldSelectorType = "objectFieldSelector" + ObjectFieldSelectorFieldAPIVersion = "apiVersion" + ObjectFieldSelectorFieldFieldPath = "fieldPath" +) + +type ObjectFieldSelector struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_meta.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_meta.go new file mode 100644 index 0000000..29f7963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_meta.go @@ -0,0 +1,28 @@ +package client + +const ( + ObjectMetaType = "objectMeta" + ObjectMetaFieldAnnotations = "annotations" + ObjectMetaFieldCreated = "created" + ObjectMetaFieldFinalizers = "finalizers" + ObjectMetaFieldLabels = "labels" + ObjectMetaFieldName = "name" + ObjectMetaFieldNamespace = "namespace" + ObjectMetaFieldOwnerReferences = "ownerReferences" + ObjectMetaFieldRemoved = "removed" + ObjectMetaFieldSelfLink = "selfLink" + ObjectMetaFieldUUID = "uuid" +) + +type ObjectMeta struct { + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + Finalizers []string `json:"finalizers,omitempty" yaml:"finalizers,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_source.go new file mode 100644 index 0000000..58bb11d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_source.go @@ -0,0 +1,14 @@ +package client + +const ( + ObjectMetricSourceType = "objectMetricSource" + ObjectMetricSourceFieldDescribedObject = "describedObject" + ObjectMetricSourceFieldMetric = "metric" + ObjectMetricSourceFieldTarget = "target" +) + +type ObjectMetricSource struct { + DescribedObject *CrossVersionObjectReference `json:"describedObject,omitempty" yaml:"describedObject,omitempty"` + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_status.go new file mode 100644 index 0000000..5734405 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_metric_status.go @@ -0,0 +1,14 @@ +package client + +const ( + ObjectMetricStatusType = "objectMetricStatus" + ObjectMetricStatusFieldCurrent = "current" + ObjectMetricStatusFieldDescribedObject = "describedObject" + ObjectMetricStatusFieldMetric = "metric" +) + +type ObjectMetricStatus struct { + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + DescribedObject *CrossVersionObjectReference `json:"describedObject,omitempty" yaml:"describedObject,omitempty"` + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_reference.go new file mode 100644 index 0000000..2a5f94e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_object_reference.go @@ -0,0 +1,22 @@ +package client + +const ( + ObjectReferenceType = "objectReference" + ObjectReferenceFieldAPIVersion = "apiVersion" + ObjectReferenceFieldFieldPath = "fieldPath" + ObjectReferenceFieldKind = "kind" + ObjectReferenceFieldName = "name" + ObjectReferenceFieldNamespace = "namespace" + ObjectReferenceFieldResourceVersion = "resourceVersion" + ObjectReferenceFieldUID = "uid" +) + +type ObjectReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_owner_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_owner_reference.go new file mode 100644 index 0000000..5f4436b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_owner_reference.go @@ -0,0 +1,20 @@ +package client + +const ( + OwnerReferenceType = "ownerReference" + OwnerReferenceFieldAPIVersion = "apiVersion" + OwnerReferenceFieldBlockOwnerDeletion = "blockOwnerDeletion" + OwnerReferenceFieldController = "controller" + OwnerReferenceFieldKind = "kind" + OwnerReferenceFieldName = "name" + OwnerReferenceFieldUID = "uid" +) + +type OwnerReference struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" yaml:"blockOwnerDeletion,omitempty"` + Controller *bool `json:"controller,omitempty" yaml:"controller,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim.go new file mode 100644 index 0000000..f983fb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim.go @@ -0,0 +1,148 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PersistentVolumeClaimType = "persistentVolumeClaim" + PersistentVolumeClaimFieldAccessModes = "accessModes" + PersistentVolumeClaimFieldAnnotations = "annotations" + PersistentVolumeClaimFieldCreated = "created" + PersistentVolumeClaimFieldCreatorID = "creatorId" + PersistentVolumeClaimFieldDataSource = "dataSource" + PersistentVolumeClaimFieldDataSourceRef = "dataSourceRef" + PersistentVolumeClaimFieldLabels = "labels" + PersistentVolumeClaimFieldName = "name" + PersistentVolumeClaimFieldNamespaceId = "namespaceId" + PersistentVolumeClaimFieldOwnerReferences = "ownerReferences" + PersistentVolumeClaimFieldProjectID = "projectId" + PersistentVolumeClaimFieldRemoved = "removed" + PersistentVolumeClaimFieldResources = "resources" + PersistentVolumeClaimFieldSelector = "selector" + PersistentVolumeClaimFieldState = "state" + PersistentVolumeClaimFieldStatus = "status" + PersistentVolumeClaimFieldStorageClassID = "storageClassId" + PersistentVolumeClaimFieldTransitioning = "transitioning" + PersistentVolumeClaimFieldTransitioningMessage = "transitioningMessage" + PersistentVolumeClaimFieldUUID = "uuid" + PersistentVolumeClaimFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeClaimFieldVolumeID = "volumeId" + PersistentVolumeClaimFieldVolumeMode = "volumeMode" +) + +type PersistentVolumeClaim struct { + types.Resource + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" yaml:"dataSource,omitempty"` + DataSourceRef *TypedObjectReference `json:"dataSourceRef,omitempty" yaml:"dataSourceRef,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Resources *VolumeResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *PersistentVolumeClaimStatus `json:"status,omitempty" yaml:"status,omitempty"` + StorageClassID string `json:"storageClassId,omitempty" yaml:"storageClassId,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeID string `json:"volumeId,omitempty" yaml:"volumeId,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` +} + +type PersistentVolumeClaimCollection struct { + types.Collection + Data []PersistentVolumeClaim `json:"data,omitempty"` + client *PersistentVolumeClaimClient +} + +type PersistentVolumeClaimClient struct { + apiClient *Client +} + +type PersistentVolumeClaimOperations interface { + List(opts *types.ListOpts) (*PersistentVolumeClaimCollection, error) + ListAll(opts *types.ListOpts) (*PersistentVolumeClaimCollection, error) + Create(opts *PersistentVolumeClaim) (*PersistentVolumeClaim, error) + Update(existing *PersistentVolumeClaim, updates interface{}) (*PersistentVolumeClaim, error) + Replace(existing *PersistentVolumeClaim) (*PersistentVolumeClaim, error) + ByID(id string) (*PersistentVolumeClaim, error) + Delete(container *PersistentVolumeClaim) error +} + +func newPersistentVolumeClaimClient(apiClient *Client) *PersistentVolumeClaimClient { + return &PersistentVolumeClaimClient{ + apiClient: apiClient, + } +} + +func (c *PersistentVolumeClaimClient) Create(container *PersistentVolumeClaim) (*PersistentVolumeClaim, error) { + resp := &PersistentVolumeClaim{} + err := c.apiClient.Ops.DoCreate(PersistentVolumeClaimType, container, resp) + return resp, err +} + +func (c *PersistentVolumeClaimClient) Update(existing *PersistentVolumeClaim, updates interface{}) (*PersistentVolumeClaim, error) { + resp := &PersistentVolumeClaim{} + err := c.apiClient.Ops.DoUpdate(PersistentVolumeClaimType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PersistentVolumeClaimClient) Replace(obj *PersistentVolumeClaim) (*PersistentVolumeClaim, error) { + resp := &PersistentVolumeClaim{} + err := c.apiClient.Ops.DoReplace(PersistentVolumeClaimType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PersistentVolumeClaimClient) List(opts *types.ListOpts) (*PersistentVolumeClaimCollection, error) { + resp := &PersistentVolumeClaimCollection{} + err := c.apiClient.Ops.DoList(PersistentVolumeClaimType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PersistentVolumeClaimClient) ListAll(opts *types.ListOpts) (*PersistentVolumeClaimCollection, error) { + resp := &PersistentVolumeClaimCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PersistentVolumeClaimCollection) Next() (*PersistentVolumeClaimCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PersistentVolumeClaimCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PersistentVolumeClaimClient) ByID(id string) (*PersistentVolumeClaim, error) { + resp := &PersistentVolumeClaim{} + err := c.apiClient.Ops.DoByID(PersistentVolumeClaimType, id, resp) + return resp, err +} + +func (c *PersistentVolumeClaimClient) Delete(container *PersistentVolumeClaim) error { + return c.apiClient.Ops.DoResourceDelete(PersistentVolumeClaimType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_condition.go new file mode 100644 index 0000000..0e9bbda --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + PersistentVolumeClaimConditionType = "persistentVolumeClaimCondition" + PersistentVolumeClaimConditionFieldLastProbeTime = "lastProbeTime" + PersistentVolumeClaimConditionFieldLastTransitionTime = "lastTransitionTime" + PersistentVolumeClaimConditionFieldMessage = "message" + PersistentVolumeClaimConditionFieldReason = "reason" + PersistentVolumeClaimConditionFieldStatus = "status" + PersistentVolumeClaimConditionFieldType = "type" +) + +type PersistentVolumeClaimCondition struct { + LastProbeTime string `json:"lastProbeTime,omitempty" yaml:"lastProbeTime,omitempty"` + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_spec.go new file mode 100644 index 0000000..6331328 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_spec.go @@ -0,0 +1,26 @@ +package client + +const ( + PersistentVolumeClaimSpecType = "persistentVolumeClaimSpec" + PersistentVolumeClaimSpecFieldAccessModes = "accessModes" + PersistentVolumeClaimSpecFieldDataSource = "dataSource" + PersistentVolumeClaimSpecFieldDataSourceRef = "dataSourceRef" + PersistentVolumeClaimSpecFieldResources = "resources" + PersistentVolumeClaimSpecFieldSelector = "selector" + PersistentVolumeClaimSpecFieldStorageClassID = "storageClassId" + PersistentVolumeClaimSpecFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeClaimSpecFieldVolumeID = "volumeId" + PersistentVolumeClaimSpecFieldVolumeMode = "volumeMode" +) + +type PersistentVolumeClaimSpec struct { + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + DataSource *TypedLocalObjectReference `json:"dataSource,omitempty" yaml:"dataSource,omitempty"` + DataSourceRef *TypedObjectReference `json:"dataSourceRef,omitempty" yaml:"dataSourceRef,omitempty"` + Resources *VolumeResourceRequirements `json:"resources,omitempty" yaml:"resources,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + StorageClassID string `json:"storageClassId,omitempty" yaml:"storageClassId,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeID string `json:"volumeId,omitempty" yaml:"volumeId,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_status.go new file mode 100644 index 0000000..8f10db6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_status.go @@ -0,0 +1,24 @@ +package client + +const ( + PersistentVolumeClaimStatusType = "persistentVolumeClaimStatus" + PersistentVolumeClaimStatusFieldAccessModes = "accessModes" + PersistentVolumeClaimStatusFieldAllocatedResourceStatuses = "allocatedResourceStatuses" + PersistentVolumeClaimStatusFieldAllocatedResources = "allocatedResources" + PersistentVolumeClaimStatusFieldCapacity = "capacity" + PersistentVolumeClaimStatusFieldConditions = "conditions" + PersistentVolumeClaimStatusFieldCurrentVolumeAttributesClassName = "currentVolumeAttributesClassName" + PersistentVolumeClaimStatusFieldModifyVolumeStatus = "modifyVolumeStatus" + PersistentVolumeClaimStatusFieldPhase = "phase" +) + +type PersistentVolumeClaimStatus struct { + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + AllocatedResourceStatuses map[string]string `json:"allocatedResourceStatuses,omitempty" yaml:"allocatedResourceStatuses,omitempty"` + AllocatedResources map[string]string `json:"allocatedResources,omitempty" yaml:"allocatedResources,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + Conditions []PersistentVolumeClaimCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CurrentVolumeAttributesClassName string `json:"currentVolumeAttributesClassName,omitempty" yaml:"currentVolumeAttributesClassName,omitempty"` + ModifyVolumeStatus *ModifyVolumeStatus `json:"modifyVolumeStatus,omitempty" yaml:"modifyVolumeStatus,omitempty"` + Phase string `json:"phase,omitempty" yaml:"phase,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_template.go new file mode 100644 index 0000000..1eed7b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_template.go @@ -0,0 +1,12 @@ +package client + +const ( + PersistentVolumeClaimTemplateType = "persistentVolumeClaimTemplate" + PersistentVolumeClaimTemplateFieldObjectMeta = "metadata" + PersistentVolumeClaimTemplateFieldSpec = "spec" +) + +type PersistentVolumeClaimTemplate struct { + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Spec *PersistentVolumeClaimSpec `json:"spec,omitempty" yaml:"spec,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_volume_source.go new file mode 100644 index 0000000..45e600c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_claim_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PersistentVolumeClaimVolumeSourceType = "persistentVolumeClaimVolumeSource" + PersistentVolumeClaimVolumeSourceFieldPersistentVolumeClaimID = "persistentVolumeClaimId" + PersistentVolumeClaimVolumeSourceFieldReadOnly = "readOnly" +) + +type PersistentVolumeClaimVolumeSource struct { + PersistentVolumeClaimID string `json:"persistentVolumeClaimId,omitempty" yaml:"persistentVolumeClaimId,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_spec.go new file mode 100644 index 0000000..07997bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_persistent_volume_spec.go @@ -0,0 +1,70 @@ +package client + +const ( + PersistentVolumeSpecType = "persistentVolumeSpec" + PersistentVolumeSpecFieldAWSElasticBlockStore = "awsElasticBlockStore" + PersistentVolumeSpecFieldAccessModes = "accessModes" + PersistentVolumeSpecFieldAzureDisk = "azureDisk" + PersistentVolumeSpecFieldAzureFile = "azureFile" + PersistentVolumeSpecFieldCSI = "csi" + PersistentVolumeSpecFieldCapacity = "capacity" + PersistentVolumeSpecFieldCephFS = "cephfs" + PersistentVolumeSpecFieldCinder = "cinder" + PersistentVolumeSpecFieldClaimRef = "claimRef" + PersistentVolumeSpecFieldFC = "fc" + PersistentVolumeSpecFieldFlexVolume = "flexVolume" + PersistentVolumeSpecFieldFlocker = "flocker" + PersistentVolumeSpecFieldGCEPersistentDisk = "gcePersistentDisk" + PersistentVolumeSpecFieldGlusterfs = "glusterfs" + PersistentVolumeSpecFieldHostPath = "hostPath" + PersistentVolumeSpecFieldISCSI = "iscsi" + PersistentVolumeSpecFieldLocal = "local" + PersistentVolumeSpecFieldMountOptions = "mountOptions" + PersistentVolumeSpecFieldNFS = "nfs" + PersistentVolumeSpecFieldNodeAffinity = "nodeAffinity" + PersistentVolumeSpecFieldPersistentVolumeReclaimPolicy = "persistentVolumeReclaimPolicy" + PersistentVolumeSpecFieldPhotonPersistentDisk = "photonPersistentDisk" + PersistentVolumeSpecFieldPortworxVolume = "portworxVolume" + PersistentVolumeSpecFieldQuobyte = "quobyte" + PersistentVolumeSpecFieldRBD = "rbd" + PersistentVolumeSpecFieldScaleIO = "scaleIO" + PersistentVolumeSpecFieldStorageClassID = "storageClassId" + PersistentVolumeSpecFieldStorageOS = "storageos" + PersistentVolumeSpecFieldVolumeAttributesClassName = "volumeAttributesClassName" + PersistentVolumeSpecFieldVolumeMode = "volumeMode" + PersistentVolumeSpecFieldVsphereVolume = "vsphereVolume" +) + +type PersistentVolumeSpec struct { + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" yaml:"awsElasticBlockStore,omitempty"` + AccessModes []string `json:"accessModes,omitempty" yaml:"accessModes,omitempty"` + AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" yaml:"azureDisk,omitempty"` + AzureFile *AzureFilePersistentVolumeSource `json:"azureFile,omitempty" yaml:"azureFile,omitempty"` + CSI *CSIPersistentVolumeSource `json:"csi,omitempty" yaml:"csi,omitempty"` + Capacity map[string]string `json:"capacity,omitempty" yaml:"capacity,omitempty"` + CephFS *CephFSPersistentVolumeSource `json:"cephfs,omitempty" yaml:"cephfs,omitempty"` + Cinder *CinderPersistentVolumeSource `json:"cinder,omitempty" yaml:"cinder,omitempty"` + ClaimRef *ObjectReference `json:"claimRef,omitempty" yaml:"claimRef,omitempty"` + FC *FCVolumeSource `json:"fc,omitempty" yaml:"fc,omitempty"` + FlexVolume *FlexPersistentVolumeSource `json:"flexVolume,omitempty" yaml:"flexVolume,omitempty"` + Flocker *FlockerVolumeSource `json:"flocker,omitempty" yaml:"flocker,omitempty"` + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" yaml:"gcePersistentDisk,omitempty"` + Glusterfs *GlusterfsPersistentVolumeSource `json:"glusterfs,omitempty" yaml:"glusterfs,omitempty"` + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` + ISCSI *ISCSIPersistentVolumeSource `json:"iscsi,omitempty" yaml:"iscsi,omitempty"` + Local *LocalVolumeSource `json:"local,omitempty" yaml:"local,omitempty"` + MountOptions []string `json:"mountOptions,omitempty" yaml:"mountOptions,omitempty"` + NFS *NFSVolumeSource `json:"nfs,omitempty" yaml:"nfs,omitempty"` + NodeAffinity *VolumeNodeAffinity `json:"nodeAffinity,omitempty" yaml:"nodeAffinity,omitempty"` + PersistentVolumeReclaimPolicy string `json:"persistentVolumeReclaimPolicy,omitempty" yaml:"persistentVolumeReclaimPolicy,omitempty"` + PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" yaml:"photonPersistentDisk,omitempty"` + PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" yaml:"portworxVolume,omitempty"` + Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" yaml:"quobyte,omitempty"` + RBD *RBDPersistentVolumeSource `json:"rbd,omitempty" yaml:"rbd,omitempty"` + ScaleIO *ScaleIOPersistentVolumeSource `json:"scaleIO,omitempty" yaml:"scaleIO,omitempty"` + StorageClassID string `json:"storageClassId,omitempty" yaml:"storageClassId,omitempty"` + StorageOS *StorageOSPersistentVolumeSource `json:"storageos,omitempty" yaml:"storageos,omitempty"` + VolumeAttributesClassName string `json:"volumeAttributesClassName,omitempty" yaml:"volumeAttributesClassName,omitempty"` + VolumeMode string `json:"volumeMode,omitempty" yaml:"volumeMode,omitempty"` + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" yaml:"vsphereVolume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_photon_persistent_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_photon_persistent_disk_volume_source.go new file mode 100644 index 0000000..d6e8ffd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_photon_persistent_disk_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PhotonPersistentDiskVolumeSourceType = "photonPersistentDiskVolumeSource" + PhotonPersistentDiskVolumeSourceFieldFSType = "fsType" + PhotonPersistentDiskVolumeSourceFieldPdID = "pdID" +) + +type PhotonPersistentDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + PdID string `json:"pdID,omitempty" yaml:"pdID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod.go new file mode 100644 index 0000000..33abeb5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod.go @@ -0,0 +1,220 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + PodType = "pod" + PodFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + PodFieldAnnotations = "annotations" + PodFieldAppArmorProfile = "appArmorProfile" + PodFieldAutomountServiceAccountToken = "automountServiceAccountToken" + PodFieldContainers = "containers" + PodFieldCreated = "created" + PodFieldCreatorID = "creatorId" + PodFieldDNSConfig = "dnsConfig" + PodFieldDNSPolicy = "dnsPolicy" + PodFieldDescription = "description" + PodFieldEnableServiceLinks = "enableServiceLinks" + PodFieldEphemeralContainers = "ephemeralContainers" + PodFieldFSGroupChangePolicy = "fsGroupChangePolicy" + PodFieldFsgid = "fsgid" + PodFieldGids = "gids" + PodFieldHostAliases = "hostAliases" + PodFieldHostIPC = "hostIPC" + PodFieldHostNetwork = "hostNetwork" + PodFieldHostPID = "hostPID" + PodFieldHostUsers = "hostUsers" + PodFieldHostname = "hostname" + PodFieldImagePullSecrets = "imagePullSecrets" + PodFieldLabels = "labels" + PodFieldName = "name" + PodFieldNamespaceId = "namespaceId" + PodFieldNodeID = "nodeId" + PodFieldOS = "os" + PodFieldOverhead = "overhead" + PodFieldOwnerReferences = "ownerReferences" + PodFieldPreemptionPolicy = "preemptionPolicy" + PodFieldProjectID = "projectId" + PodFieldPublicEndpoints = "publicEndpoints" + PodFieldReadinessGates = "readinessGates" + PodFieldRemoved = "removed" + PodFieldResourceClaims = "resourceClaims" + PodFieldRestartPolicy = "restartPolicy" + PodFieldRunAsGroup = "runAsGroup" + PodFieldRunAsNonRoot = "runAsNonRoot" + PodFieldRuntimeClassName = "runtimeClassName" + PodFieldScheduling = "scheduling" + PodFieldSchedulingGates = "schedulingGates" + PodFieldSeccompProfile = "seccompProfile" + PodFieldServiceAccountName = "serviceAccountName" + PodFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + PodFieldShareProcessNamespace = "shareProcessNamespace" + PodFieldState = "state" + PodFieldStatus = "status" + PodFieldSubdomain = "subdomain" + PodFieldSysctls = "sysctls" + PodFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + PodFieldTopologySpreadConstraints = "topologySpreadConstraints" + PodFieldTransitioning = "transitioning" + PodFieldTransitioningMessage = "transitioningMessage" + PodFieldUUID = "uuid" + PodFieldUid = "uid" + PodFieldVolumes = "volumes" + PodFieldWindowsOptions = "windowsOptions" + PodFieldWorkloadID = "workloadId" + PodFieldWorkloadMetrics = "workloadMetrics" +) + +type Pod struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Status *PodStatus `json:"status,omitempty" yaml:"status,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadID string `json:"workloadId,omitempty" yaml:"workloadId,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type PodCollection struct { + types.Collection + Data []Pod `json:"data,omitempty"` + client *PodClient +} + +type PodClient struct { + apiClient *Client +} + +type PodOperations interface { + List(opts *types.ListOpts) (*PodCollection, error) + ListAll(opts *types.ListOpts) (*PodCollection, error) + Create(opts *Pod) (*Pod, error) + Update(existing *Pod, updates interface{}) (*Pod, error) + Replace(existing *Pod) (*Pod, error) + ByID(id string) (*Pod, error) + Delete(container *Pod) error +} + +func newPodClient(apiClient *Client) *PodClient { + return &PodClient{ + apiClient: apiClient, + } +} + +func (c *PodClient) Create(container *Pod) (*Pod, error) { + resp := &Pod{} + err := c.apiClient.Ops.DoCreate(PodType, container, resp) + return resp, err +} + +func (c *PodClient) Update(existing *Pod, updates interface{}) (*Pod, error) { + resp := &Pod{} + err := c.apiClient.Ops.DoUpdate(PodType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *PodClient) Replace(obj *Pod) (*Pod, error) { + resp := &Pod{} + err := c.apiClient.Ops.DoReplace(PodType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *PodClient) List(opts *types.ListOpts) (*PodCollection, error) { + resp := &PodCollection{} + err := c.apiClient.Ops.DoList(PodType, opts, resp) + resp.client = c + return resp, err +} + +func (c *PodClient) ListAll(opts *types.ListOpts) (*PodCollection, error) { + resp := &PodCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *PodCollection) Next() (*PodCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &PodCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *PodClient) ByID(id string) (*Pod, error) { + resp := &Pod{} + err := c.apiClient.Ops.DoByID(PodType, id, resp) + return resp, err +} + +func (c *PodClient) Delete(container *Pod) error { + return c.apiClient.Ops.DoResourceDelete(PodType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity.go new file mode 100644 index 0000000..ebe2958 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + PodAffinityType = "podAffinity" + PodAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + PodAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type PodAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []WeightedPodAffinityTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution []PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity_term.go new file mode 100644 index 0000000..aa1478e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_affinity_term.go @@ -0,0 +1,20 @@ +package client + +const ( + PodAffinityTermType = "podAffinityTerm" + PodAffinityTermFieldLabelSelector = "labelSelector" + PodAffinityTermFieldMatchLabelKeys = "matchLabelKeys" + PodAffinityTermFieldMismatchLabelKeys = "mismatchLabelKeys" + PodAffinityTermFieldNamespaceSelector = "namespaceSelector" + PodAffinityTermFieldNamespaces = "namespaces" + PodAffinityTermFieldTopologyKey = "topologyKey" +) + +type PodAffinityTerm struct { + LabelSelector *LabelSelector `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` + MatchLabelKeys []string `json:"matchLabelKeys,omitempty" yaml:"matchLabelKeys,omitempty"` + MismatchLabelKeys []string `json:"mismatchLabelKeys,omitempty" yaml:"mismatchLabelKeys,omitempty"` + NamespaceSelector *LabelSelector `json:"namespaceSelector,omitempty" yaml:"namespaceSelector,omitempty"` + Namespaces []string `json:"namespaces,omitempty" yaml:"namespaces,omitempty"` + TopologyKey string `json:"topologyKey,omitempty" yaml:"topologyKey,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_anti_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_anti_affinity.go new file mode 100644 index 0000000..47fdd69 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_anti_affinity.go @@ -0,0 +1,12 @@ +package client + +const ( + PodAntiAffinityType = "podAntiAffinity" + PodAntiAffinityFieldPreferredDuringSchedulingIgnoredDuringExecution = "preferredDuringSchedulingIgnoredDuringExecution" + PodAntiAffinityFieldRequiredDuringSchedulingIgnoredDuringExecution = "requiredDuringSchedulingIgnoredDuringExecution" +) + +type PodAntiAffinity struct { + PreferredDuringSchedulingIgnoredDuringExecution []WeightedPodAffinityTerm `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` + RequiredDuringSchedulingIgnoredDuringExecution []PodAffinityTerm `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty" yaml:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_condition.go new file mode 100644 index 0000000..2e9538d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_condition.go @@ -0,0 +1,20 @@ +package client + +const ( + PodConditionType = "podCondition" + PodConditionFieldLastProbeTime = "lastProbeTime" + PodConditionFieldLastTransitionTime = "lastTransitionTime" + PodConditionFieldMessage = "message" + PodConditionFieldReason = "reason" + PodConditionFieldStatus = "status" + PodConditionFieldType = "type" +) + +type PodCondition struct { + LastProbeTime string `json:"lastProbeTime,omitempty" yaml:"lastProbeTime,omitempty"` + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig.go new file mode 100644 index 0000000..e61ebd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig.go @@ -0,0 +1,14 @@ +package client + +const ( + PodDNSConfigType = "podDNSConfig" + PodDNSConfigFieldNameservers = "nameservers" + PodDNSConfigFieldOptions = "options" + PodDNSConfigFieldSearches = "searches" +) + +type PodDNSConfig struct { + Nameservers []string `json:"nameservers,omitempty" yaml:"nameservers,omitempty"` + Options []PodDNSConfigOption `json:"options,omitempty" yaml:"options,omitempty"` + Searches []string `json:"searches,omitempty" yaml:"searches,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig_option.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig_option.go new file mode 100644 index 0000000..7afd4e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_dnsconfig_option.go @@ -0,0 +1,12 @@ +package client + +const ( + PodDNSConfigOptionType = "podDNSConfigOption" + PodDNSConfigOptionFieldName = "name" + PodDNSConfigOptionFieldValue = "value" +) + +type PodDNSConfigOption struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy.go new file mode 100644 index 0000000..d8e9ffb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy.go @@ -0,0 +1,10 @@ +package client + +const ( + PodFailurePolicyType = "podFailurePolicy" + PodFailurePolicyFieldRules = "rules" +) + +type PodFailurePolicy struct { + Rules []PodFailurePolicyRule `json:"rules,omitempty" yaml:"rules,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_exit_codes_requirement.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_exit_codes_requirement.go new file mode 100644 index 0000000..efdbbb4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_exit_codes_requirement.go @@ -0,0 +1,14 @@ +package client + +const ( + PodFailurePolicyOnExitCodesRequirementType = "podFailurePolicyOnExitCodesRequirement" + PodFailurePolicyOnExitCodesRequirementFieldContainerName = "containerName" + PodFailurePolicyOnExitCodesRequirementFieldOperator = "operator" + PodFailurePolicyOnExitCodesRequirementFieldValues = "values" +) + +type PodFailurePolicyOnExitCodesRequirement struct { + ContainerName string `json:"containerName,omitempty" yaml:"containerName,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + Values []int64 `json:"values,omitempty" yaml:"values,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_pod_conditions_pattern.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_pod_conditions_pattern.go new file mode 100644 index 0000000..1277203 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_on_pod_conditions_pattern.go @@ -0,0 +1,12 @@ +package client + +const ( + PodFailurePolicyOnPodConditionsPatternType = "podFailurePolicyOnPodConditionsPattern" + PodFailurePolicyOnPodConditionsPatternFieldStatus = "status" + PodFailurePolicyOnPodConditionsPatternFieldType = "type" +) + +type PodFailurePolicyOnPodConditionsPattern struct { + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_rule.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_rule.go new file mode 100644 index 0000000..0f173b9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_failure_policy_rule.go @@ -0,0 +1,14 @@ +package client + +const ( + PodFailurePolicyRuleType = "podFailurePolicyRule" + PodFailurePolicyRuleFieldAction = "action" + PodFailurePolicyRuleFieldOnExitCodes = "onExitCodes" + PodFailurePolicyRuleFieldOnPodConditions = "onPodConditions" +) + +type PodFailurePolicyRule struct { + Action string `json:"action,omitempty" yaml:"action,omitempty"` + OnExitCodes *PodFailurePolicyOnExitCodesRequirement `json:"onExitCodes,omitempty" yaml:"onExitCodes,omitempty"` + OnPodConditions []PodFailurePolicyOnPodConditionsPattern `json:"onPodConditions,omitempty" yaml:"onPodConditions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_ip.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_ip.go new file mode 100644 index 0000000..ccd571e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_ip.go @@ -0,0 +1,10 @@ +package client + +const ( + PodIPType = "podIP" + PodIPFieldIP = "ip" +) + +type PodIP struct { + IP string `json:"ip,omitempty" yaml:"ip,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_os.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_os.go new file mode 100644 index 0000000..0ea7306 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_os.go @@ -0,0 +1,10 @@ +package client + +const ( + PodOSType = "podOS" + PodOSFieldName = "name" +) + +type PodOS struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_readiness_gate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_readiness_gate.go new file mode 100644 index 0000000..5909a4d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_readiness_gate.go @@ -0,0 +1,10 @@ +package client + +const ( + PodReadinessGateType = "podReadinessGate" + PodReadinessGateFieldConditionType = "conditionType" +) + +type PodReadinessGate struct { + ConditionType string `json:"conditionType,omitempty" yaml:"conditionType,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim.go new file mode 100644 index 0000000..9e1bb94 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim.go @@ -0,0 +1,12 @@ +package client + +const ( + PodResourceClaimType = "podResourceClaim" + PodResourceClaimFieldName = "name" + PodResourceClaimFieldSource = "source" +) + +type PodResourceClaim struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Source *ClaimSource `json:"source,omitempty" yaml:"source,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim_status.go new file mode 100644 index 0000000..c019942 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_resource_claim_status.go @@ -0,0 +1,12 @@ +package client + +const ( + PodResourceClaimStatusType = "podResourceClaimStatus" + PodResourceClaimStatusFieldName = "name" + PodResourceClaimStatusFieldResourceClaimName = "resourceClaimName" +) + +type PodResourceClaimStatus struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + ResourceClaimName string `json:"resourceClaimName,omitempty" yaml:"resourceClaimName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_scheduling_gate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_scheduling_gate.go new file mode 100644 index 0000000..9387959 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_scheduling_gate.go @@ -0,0 +1,10 @@ +package client + +const ( + PodSchedulingGateType = "podSchedulingGate" + PodSchedulingGateFieldName = "name" +) + +type PodSchedulingGate struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_security_context.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_security_context.go new file mode 100644 index 0000000..85e7d33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_security_context.go @@ -0,0 +1,28 @@ +package client + +const ( + PodSecurityContextType = "podSecurityContext" + PodSecurityContextFieldAppArmorProfile = "appArmorProfile" + PodSecurityContextFieldFSGroupChangePolicy = "fsGroupChangePolicy" + PodSecurityContextFieldFsgid = "fsgid" + PodSecurityContextFieldGids = "gids" + PodSecurityContextFieldRunAsGroup = "runAsGroup" + PodSecurityContextFieldRunAsNonRoot = "runAsNonRoot" + PodSecurityContextFieldSeccompProfile = "seccompProfile" + PodSecurityContextFieldSysctls = "sysctls" + PodSecurityContextFieldUid = "uid" + PodSecurityContextFieldWindowsOptions = "windowsOptions" +) + +type PodSecurityContext struct { + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_spec.go new file mode 100644 index 0000000..1e96be6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_spec.go @@ -0,0 +1,90 @@ +package client + +const ( + PodSpecType = "podSpec" + PodSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + PodSpecFieldAppArmorProfile = "appArmorProfile" + PodSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + PodSpecFieldContainers = "containers" + PodSpecFieldDNSConfig = "dnsConfig" + PodSpecFieldDNSPolicy = "dnsPolicy" + PodSpecFieldEnableServiceLinks = "enableServiceLinks" + PodSpecFieldEphemeralContainers = "ephemeralContainers" + PodSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + PodSpecFieldFsgid = "fsgid" + PodSpecFieldGids = "gids" + PodSpecFieldHostAliases = "hostAliases" + PodSpecFieldHostIPC = "hostIPC" + PodSpecFieldHostNetwork = "hostNetwork" + PodSpecFieldHostPID = "hostPID" + PodSpecFieldHostUsers = "hostUsers" + PodSpecFieldHostname = "hostname" + PodSpecFieldImagePullSecrets = "imagePullSecrets" + PodSpecFieldNodeID = "nodeId" + PodSpecFieldOS = "os" + PodSpecFieldOverhead = "overhead" + PodSpecFieldPreemptionPolicy = "preemptionPolicy" + PodSpecFieldReadinessGates = "readinessGates" + PodSpecFieldResourceClaims = "resourceClaims" + PodSpecFieldRestartPolicy = "restartPolicy" + PodSpecFieldRunAsGroup = "runAsGroup" + PodSpecFieldRunAsNonRoot = "runAsNonRoot" + PodSpecFieldRuntimeClassName = "runtimeClassName" + PodSpecFieldScheduling = "scheduling" + PodSpecFieldSchedulingGates = "schedulingGates" + PodSpecFieldSeccompProfile = "seccompProfile" + PodSpecFieldServiceAccountName = "serviceAccountName" + PodSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + PodSpecFieldShareProcessNamespace = "shareProcessNamespace" + PodSpecFieldSubdomain = "subdomain" + PodSpecFieldSysctls = "sysctls" + PodSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + PodSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + PodSpecFieldUid = "uid" + PodSpecFieldVolumes = "volumes" + PodSpecFieldWindowsOptions = "windowsOptions" +) + +type PodSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_status.go new file mode 100644 index 0000000..ab25394 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_status.go @@ -0,0 +1,40 @@ +package client + +const ( + PodStatusType = "podStatus" + PodStatusFieldConditions = "conditions" + PodStatusFieldContainerStatuses = "containerStatuses" + PodStatusFieldEphemeralContainerStatuses = "ephemeralContainerStatuses" + PodStatusFieldHostIPs = "hostIPs" + PodStatusFieldInitContainerStatuses = "initContainerStatuses" + PodStatusFieldMessage = "message" + PodStatusFieldNodeIp = "nodeIp" + PodStatusFieldNominatedNodeName = "nominatedNodeName" + PodStatusFieldPhase = "phase" + PodStatusFieldPodIPs = "podIPs" + PodStatusFieldPodIp = "podIp" + PodStatusFieldQOSClass = "qosClass" + PodStatusFieldReason = "reason" + PodStatusFieldResize = "resize" + PodStatusFieldResourceClaimStatuses = "resourceClaimStatuses" + PodStatusFieldStartTime = "startTime" +) + +type PodStatus struct { + Conditions []PodCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + ContainerStatuses []ContainerStatus `json:"containerStatuses,omitempty" yaml:"containerStatuses,omitempty"` + EphemeralContainerStatuses []ContainerStatus `json:"ephemeralContainerStatuses,omitempty" yaml:"ephemeralContainerStatuses,omitempty"` + HostIPs []HostIP `json:"hostIPs,omitempty" yaml:"hostIPs,omitempty"` + InitContainerStatuses []ContainerStatus `json:"initContainerStatuses,omitempty" yaml:"initContainerStatuses,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + NodeIp string `json:"nodeIp,omitempty" yaml:"nodeIp,omitempty"` + NominatedNodeName string `json:"nominatedNodeName,omitempty" yaml:"nominatedNodeName,omitempty"` + Phase string `json:"phase,omitempty" yaml:"phase,omitempty"` + PodIPs []PodIP `json:"podIPs,omitempty" yaml:"podIPs,omitempty"` + PodIp string `json:"podIp,omitempty" yaml:"podIp,omitempty"` + QOSClass string `json:"qosClass,omitempty" yaml:"qosClass,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Resize string `json:"resize,omitempty" yaml:"resize,omitempty"` + ResourceClaimStatuses []PodResourceClaimStatus `json:"resourceClaimStatuses,omitempty" yaml:"resourceClaimStatuses,omitempty"` + StartTime string `json:"startTime,omitempty" yaml:"startTime,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_template_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_template_spec.go new file mode 100644 index 0000000..21d17e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pod_template_spec.go @@ -0,0 +1,92 @@ +package client + +const ( + PodTemplateSpecType = "podTemplateSpec" + PodTemplateSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + PodTemplateSpecFieldAppArmorProfile = "appArmorProfile" + PodTemplateSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + PodTemplateSpecFieldContainers = "containers" + PodTemplateSpecFieldDNSConfig = "dnsConfig" + PodTemplateSpecFieldDNSPolicy = "dnsPolicy" + PodTemplateSpecFieldEnableServiceLinks = "enableServiceLinks" + PodTemplateSpecFieldEphemeralContainers = "ephemeralContainers" + PodTemplateSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + PodTemplateSpecFieldFsgid = "fsgid" + PodTemplateSpecFieldGids = "gids" + PodTemplateSpecFieldHostAliases = "hostAliases" + PodTemplateSpecFieldHostIPC = "hostIPC" + PodTemplateSpecFieldHostNetwork = "hostNetwork" + PodTemplateSpecFieldHostPID = "hostPID" + PodTemplateSpecFieldHostUsers = "hostUsers" + PodTemplateSpecFieldHostname = "hostname" + PodTemplateSpecFieldImagePullSecrets = "imagePullSecrets" + PodTemplateSpecFieldNodeID = "nodeId" + PodTemplateSpecFieldOS = "os" + PodTemplateSpecFieldObjectMeta = "metadata" + PodTemplateSpecFieldOverhead = "overhead" + PodTemplateSpecFieldPreemptionPolicy = "preemptionPolicy" + PodTemplateSpecFieldReadinessGates = "readinessGates" + PodTemplateSpecFieldResourceClaims = "resourceClaims" + PodTemplateSpecFieldRestartPolicy = "restartPolicy" + PodTemplateSpecFieldRunAsGroup = "runAsGroup" + PodTemplateSpecFieldRunAsNonRoot = "runAsNonRoot" + PodTemplateSpecFieldRuntimeClassName = "runtimeClassName" + PodTemplateSpecFieldScheduling = "scheduling" + PodTemplateSpecFieldSchedulingGates = "schedulingGates" + PodTemplateSpecFieldSeccompProfile = "seccompProfile" + PodTemplateSpecFieldServiceAccountName = "serviceAccountName" + PodTemplateSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + PodTemplateSpecFieldShareProcessNamespace = "shareProcessNamespace" + PodTemplateSpecFieldSubdomain = "subdomain" + PodTemplateSpecFieldSysctls = "sysctls" + PodTemplateSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + PodTemplateSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + PodTemplateSpecFieldUid = "uid" + PodTemplateSpecFieldVolumes = "volumes" + PodTemplateSpecFieldWindowsOptions = "windowsOptions" +) + +type PodTemplateSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_source.go new file mode 100644 index 0000000..d6ff266 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_source.go @@ -0,0 +1,12 @@ +package client + +const ( + PodsMetricSourceType = "podsMetricSource" + PodsMetricSourceFieldMetric = "metric" + PodsMetricSourceFieldTarget = "target" +) + +type PodsMetricSource struct { + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_status.go new file mode 100644 index 0000000..307375c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_pods_metric_status.go @@ -0,0 +1,12 @@ +package client + +const ( + PodsMetricStatusType = "podsMetricStatus" + PodsMetricStatusFieldCurrent = "current" + PodsMetricStatusFieldMetric = "metric" +) + +type PodsMetricStatus struct { + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + Metric *MetricIdentifier `json:"metric,omitempty" yaml:"metric,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_port_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_port_status.go new file mode 100644 index 0000000..2a85510 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_port_status.go @@ -0,0 +1,14 @@ +package client + +const ( + PortStatusType = "portStatus" + PortStatusFieldError = "error" + PortStatusFieldPort = "port" + PortStatusFieldProtocol = "protocol" +) + +type PortStatus struct { + Error string `json:"error,omitempty" yaml:"error,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_portworx_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_portworx_volume_source.go new file mode 100644 index 0000000..cbe98c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_portworx_volume_source.go @@ -0,0 +1,14 @@ +package client + +const ( + PortworxVolumeSourceType = "portworxVolumeSource" + PortworxVolumeSourceFieldFSType = "fsType" + PortworxVolumeSourceFieldReadOnly = "readOnly" + PortworxVolumeSourceFieldVolumeID = "volumeID" +) + +type PortworxVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + VolumeID string `json:"volumeID,omitempty" yaml:"volumeID,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_preferred_scheduling_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_preferred_scheduling_term.go new file mode 100644 index 0000000..b5be217 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_preferred_scheduling_term.go @@ -0,0 +1,12 @@ +package client + +const ( + PreferredSchedulingTermType = "preferredSchedulingTerm" + PreferredSchedulingTermFieldPreference = "preference" + PreferredSchedulingTermFieldWeight = "weight" +) + +type PreferredSchedulingTerm struct { + Preference *NodeSelectorTerm `json:"preference,omitempty" yaml:"preference,omitempty"` + Weight int64 `json:"weight,omitempty" yaml:"weight,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_probe.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_probe.go new file mode 100644 index 0000000..c2ae064 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_probe.go @@ -0,0 +1,40 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + ProbeType = "probe" + ProbeFieldCommand = "command" + ProbeFieldFailureThreshold = "failureThreshold" + ProbeFieldGRPC = "grpc" + ProbeFieldHTTPHeaders = "httpHeaders" + ProbeFieldHost = "host" + ProbeFieldInitialDelaySeconds = "initialDelaySeconds" + ProbeFieldPath = "path" + ProbeFieldPeriodSeconds = "periodSeconds" + ProbeFieldPort = "port" + ProbeFieldScheme = "scheme" + ProbeFieldSuccessThreshold = "successThreshold" + ProbeFieldTCP = "tcp" + ProbeFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + ProbeFieldTimeoutSeconds = "timeoutSeconds" +) + +type Probe struct { + Command []string `json:"command,omitempty" yaml:"command,omitempty"` + FailureThreshold int64 `json:"failureThreshold,omitempty" yaml:"failureThreshold,omitempty"` + GRPC *GRPCAction `json:"grpc,omitempty" yaml:"grpc,omitempty"` + HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty" yaml:"httpHeaders,omitempty"` + Host string `json:"host,omitempty" yaml:"host,omitempty"` + InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty" yaml:"initialDelaySeconds,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + PeriodSeconds int64 `json:"periodSeconds,omitempty" yaml:"periodSeconds,omitempty"` + Port intstr.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` + Scheme string `json:"scheme,omitempty" yaml:"scheme,omitempty"` + SuccessThreshold int64 `json:"successThreshold,omitempty" yaml:"successThreshold,omitempty"` + TCP bool `json:"tcp,omitempty" yaml:"tcp,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TimeoutSeconds int64 `json:"timeoutSeconds,omitempty" yaml:"timeoutSeconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_projected_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_projected_volume_source.go new file mode 100644 index 0000000..f90539e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_projected_volume_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ProjectedVolumeSourceType = "projectedVolumeSource" + ProjectedVolumeSourceFieldDefaultMode = "defaultMode" + ProjectedVolumeSourceFieldSources = "sources" +) + +type ProjectedVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Sources []VolumeProjection `json:"sources,omitempty" yaml:"sources,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_public_endpoint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_public_endpoint.go new file mode 100644 index 0000000..85844aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_public_endpoint.go @@ -0,0 +1,28 @@ +package client + +const ( + PublicEndpointType = "publicEndpoint" + PublicEndpointFieldAddresses = "addresses" + PublicEndpointFieldAllNodes = "allNodes" + PublicEndpointFieldHostname = "hostname" + PublicEndpointFieldIngressID = "ingressId" + PublicEndpointFieldNodeID = "nodeId" + PublicEndpointFieldPath = "path" + PublicEndpointFieldPodID = "podId" + PublicEndpointFieldPort = "port" + PublicEndpointFieldProtocol = "protocol" + PublicEndpointFieldServiceID = "serviceId" +) + +type PublicEndpoint struct { + Addresses []string `json:"addresses,omitempty" yaml:"addresses,omitempty"` + AllNodes bool `json:"allNodes,omitempty" yaml:"allNodes,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IngressID string `json:"ingressId,omitempty" yaml:"ingressId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` + PodID string `json:"podId,omitempty" yaml:"podId,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + ServiceID string `json:"serviceId,omitempty" yaml:"serviceId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_quobyte_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_quobyte_volume_source.go new file mode 100644 index 0000000..41e308d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_quobyte_volume_source.go @@ -0,0 +1,20 @@ +package client + +const ( + QuobyteVolumeSourceType = "quobyteVolumeSource" + QuobyteVolumeSourceFieldGroup = "group" + QuobyteVolumeSourceFieldReadOnly = "readOnly" + QuobyteVolumeSourceFieldRegistry = "registry" + QuobyteVolumeSourceFieldTenant = "tenant" + QuobyteVolumeSourceFieldUser = "user" + QuobyteVolumeSourceFieldVolume = "volume" +) + +type QuobyteVolumeSource struct { + Group string `json:"group,omitempty" yaml:"group,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + Registry string `json:"registry,omitempty" yaml:"registry,omitempty"` + Tenant string `json:"tenant,omitempty" yaml:"tenant,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` + Volume string `json:"volume,omitempty" yaml:"volume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_persistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_persistent_volume_source.go new file mode 100644 index 0000000..40f5514 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_persistent_volume_source.go @@ -0,0 +1,24 @@ +package client + +const ( + RBDPersistentVolumeSourceType = "rbdPersistentVolumeSource" + RBDPersistentVolumeSourceFieldCephMonitors = "monitors" + RBDPersistentVolumeSourceFieldFSType = "fsType" + RBDPersistentVolumeSourceFieldKeyring = "keyring" + RBDPersistentVolumeSourceFieldRBDImage = "image" + RBDPersistentVolumeSourceFieldRBDPool = "pool" + RBDPersistentVolumeSourceFieldRadosUser = "user" + RBDPersistentVolumeSourceFieldReadOnly = "readOnly" + RBDPersistentVolumeSourceFieldSecretRef = "secretRef" +) + +type RBDPersistentVolumeSource struct { + CephMonitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Keyring string `json:"keyring,omitempty" yaml:"keyring,omitempty"` + RBDImage string `json:"image,omitempty" yaml:"image,omitempty"` + RBDPool string `json:"pool,omitempty" yaml:"pool,omitempty"` + RadosUser string `json:"user,omitempty" yaml:"user,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_volume_source.go new file mode 100644 index 0000000..436a8b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rbd_volume_source.go @@ -0,0 +1,24 @@ +package client + +const ( + RBDVolumeSourceType = "rbdVolumeSource" + RBDVolumeSourceFieldCephMonitors = "monitors" + RBDVolumeSourceFieldFSType = "fsType" + RBDVolumeSourceFieldKeyring = "keyring" + RBDVolumeSourceFieldRBDImage = "image" + RBDVolumeSourceFieldRBDPool = "pool" + RBDVolumeSourceFieldRadosUser = "user" + RBDVolumeSourceFieldReadOnly = "readOnly" + RBDVolumeSourceFieldSecretRef = "secretRef" +) + +type RBDVolumeSource struct { + CephMonitors []string `json:"monitors,omitempty" yaml:"monitors,omitempty"` + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Keyring string `json:"keyring,omitempty" yaml:"keyring,omitempty"` + RBDImage string `json:"image,omitempty" yaml:"image,omitempty"` + RBDPool string `json:"pool,omitempty" yaml:"pool,omitempty"` + RadosUser string `json:"user,omitempty" yaml:"user,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_registry_credential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_registry_credential.go new file mode 100644 index 0000000..8462475 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_registry_credential.go @@ -0,0 +1,18 @@ +package client + +const ( + RegistryCredentialType = "registryCredential" + RegistryCredentialFieldAuth = "auth" + RegistryCredentialFieldDescription = "description" + RegistryCredentialFieldEmail = "email" + RegistryCredentialFieldPassword = "password" + RegistryCredentialFieldUsername = "username" +) + +type RegistryCredential struct { + Auth string `json:"auth,omitempty" yaml:"auth,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Email string `json:"email,omitempty" yaml:"email,omitempty"` + Password string `json:"password,omitempty" yaml:"password,omitempty"` + Username string `json:"username,omitempty" yaml:"username,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set.go new file mode 100644 index 0000000..f063253 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set.go @@ -0,0 +1,233 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ReplicaSetType = "replicaSet" + ReplicaSetFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + ReplicaSetFieldAnnotations = "annotations" + ReplicaSetFieldAppArmorProfile = "appArmorProfile" + ReplicaSetFieldAutomountServiceAccountToken = "automountServiceAccountToken" + ReplicaSetFieldContainers = "containers" + ReplicaSetFieldCreated = "created" + ReplicaSetFieldCreatorID = "creatorId" + ReplicaSetFieldDNSConfig = "dnsConfig" + ReplicaSetFieldDNSPolicy = "dnsPolicy" + ReplicaSetFieldEnableServiceLinks = "enableServiceLinks" + ReplicaSetFieldEphemeralContainers = "ephemeralContainers" + ReplicaSetFieldFSGroupChangePolicy = "fsGroupChangePolicy" + ReplicaSetFieldFsgid = "fsgid" + ReplicaSetFieldGids = "gids" + ReplicaSetFieldHostAliases = "hostAliases" + ReplicaSetFieldHostIPC = "hostIPC" + ReplicaSetFieldHostNetwork = "hostNetwork" + ReplicaSetFieldHostPID = "hostPID" + ReplicaSetFieldHostUsers = "hostUsers" + ReplicaSetFieldHostname = "hostname" + ReplicaSetFieldImagePullSecrets = "imagePullSecrets" + ReplicaSetFieldLabels = "labels" + ReplicaSetFieldName = "name" + ReplicaSetFieldNamespaceId = "namespaceId" + ReplicaSetFieldNodeID = "nodeId" + ReplicaSetFieldOS = "os" + ReplicaSetFieldOverhead = "overhead" + ReplicaSetFieldOwnerReferences = "ownerReferences" + ReplicaSetFieldPreemptionPolicy = "preemptionPolicy" + ReplicaSetFieldProjectID = "projectId" + ReplicaSetFieldPublicEndpoints = "publicEndpoints" + ReplicaSetFieldReadinessGates = "readinessGates" + ReplicaSetFieldRemoved = "removed" + ReplicaSetFieldReplicaSetConfig = "replicaSetConfig" + ReplicaSetFieldReplicaSetStatus = "replicaSetStatus" + ReplicaSetFieldResourceClaims = "resourceClaims" + ReplicaSetFieldRestartPolicy = "restartPolicy" + ReplicaSetFieldRunAsGroup = "runAsGroup" + ReplicaSetFieldRunAsNonRoot = "runAsNonRoot" + ReplicaSetFieldRuntimeClassName = "runtimeClassName" + ReplicaSetFieldScale = "scale" + ReplicaSetFieldScheduling = "scheduling" + ReplicaSetFieldSchedulingGates = "schedulingGates" + ReplicaSetFieldSeccompProfile = "seccompProfile" + ReplicaSetFieldSelector = "selector" + ReplicaSetFieldServiceAccountName = "serviceAccountName" + ReplicaSetFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + ReplicaSetFieldShareProcessNamespace = "shareProcessNamespace" + ReplicaSetFieldState = "state" + ReplicaSetFieldSubdomain = "subdomain" + ReplicaSetFieldSysctls = "sysctls" + ReplicaSetFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + ReplicaSetFieldTopologySpreadConstraints = "topologySpreadConstraints" + ReplicaSetFieldTransitioning = "transitioning" + ReplicaSetFieldTransitioningMessage = "transitioningMessage" + ReplicaSetFieldUUID = "uuid" + ReplicaSetFieldUid = "uid" + ReplicaSetFieldVolumes = "volumes" + ReplicaSetFieldWindowsOptions = "windowsOptions" + ReplicaSetFieldWorkloadAnnotations = "workloadAnnotations" + ReplicaSetFieldWorkloadLabels = "workloadLabels" + ReplicaSetFieldWorkloadMetrics = "workloadMetrics" +) + +type ReplicaSet struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ReplicaSetConfig *ReplicaSetConfig `json:"replicaSetConfig,omitempty" yaml:"replicaSetConfig,omitempty"` + ReplicaSetStatus *ReplicaSetStatus `json:"replicaSetStatus,omitempty" yaml:"replicaSetStatus,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type ReplicaSetCollection struct { + types.Collection + Data []ReplicaSet `json:"data,omitempty"` + client *ReplicaSetClient +} + +type ReplicaSetClient struct { + apiClient *Client +} + +type ReplicaSetOperations interface { + List(opts *types.ListOpts) (*ReplicaSetCollection, error) + ListAll(opts *types.ListOpts) (*ReplicaSetCollection, error) + Create(opts *ReplicaSet) (*ReplicaSet, error) + Update(existing *ReplicaSet, updates interface{}) (*ReplicaSet, error) + Replace(existing *ReplicaSet) (*ReplicaSet, error) + ByID(id string) (*ReplicaSet, error) + Delete(container *ReplicaSet) error + + ActionRedeploy(resource *ReplicaSet) error +} + +func newReplicaSetClient(apiClient *Client) *ReplicaSetClient { + return &ReplicaSetClient{ + apiClient: apiClient, + } +} + +func (c *ReplicaSetClient) Create(container *ReplicaSet) (*ReplicaSet, error) { + resp := &ReplicaSet{} + err := c.apiClient.Ops.DoCreate(ReplicaSetType, container, resp) + return resp, err +} + +func (c *ReplicaSetClient) Update(existing *ReplicaSet, updates interface{}) (*ReplicaSet, error) { + resp := &ReplicaSet{} + err := c.apiClient.Ops.DoUpdate(ReplicaSetType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ReplicaSetClient) Replace(obj *ReplicaSet) (*ReplicaSet, error) { + resp := &ReplicaSet{} + err := c.apiClient.Ops.DoReplace(ReplicaSetType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ReplicaSetClient) List(opts *types.ListOpts) (*ReplicaSetCollection, error) { + resp := &ReplicaSetCollection{} + err := c.apiClient.Ops.DoList(ReplicaSetType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ReplicaSetClient) ListAll(opts *types.ListOpts) (*ReplicaSetCollection, error) { + resp := &ReplicaSetCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ReplicaSetCollection) Next() (*ReplicaSetCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ReplicaSetCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ReplicaSetClient) ByID(id string) (*ReplicaSet, error) { + resp := &ReplicaSet{} + err := c.apiClient.Ops.DoByID(ReplicaSetType, id, resp) + return resp, err +} + +func (c *ReplicaSetClient) Delete(container *ReplicaSet) error { + return c.apiClient.Ops.DoResourceDelete(ReplicaSetType, &container.Resource) +} + +func (c *ReplicaSetClient) ActionRedeploy(resource *ReplicaSet) error { + err := c.apiClient.Ops.DoAction(ReplicaSetType, "redeploy", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_condition.go new file mode 100644 index 0000000..24e01eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + ReplicaSetConditionType = "replicaSetCondition" + ReplicaSetConditionFieldLastTransitionTime = "lastTransitionTime" + ReplicaSetConditionFieldMessage = "message" + ReplicaSetConditionFieldReason = "reason" + ReplicaSetConditionFieldStatus = "status" + ReplicaSetConditionFieldType = "type" +) + +type ReplicaSetCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_config.go new file mode 100644 index 0000000..7d9acd9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_config.go @@ -0,0 +1,10 @@ +package client + +const ( + ReplicaSetConfigType = "replicaSetConfig" + ReplicaSetConfigFieldMinReadySeconds = "minReadySeconds" +) + +type ReplicaSetConfig struct { + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_spec.go new file mode 100644 index 0000000..63f2dbf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_spec.go @@ -0,0 +1,16 @@ +package client + +const ( + ReplicaSetSpecType = "replicaSetSpec" + ReplicaSetSpecFieldReplicaSetConfig = "replicaSetConfig" + ReplicaSetSpecFieldScale = "scale" + ReplicaSetSpecFieldSelector = "selector" + ReplicaSetSpecFieldTemplate = "template" +) + +type ReplicaSetSpec struct { + ReplicaSetConfig *ReplicaSetConfig `json:"replicaSetConfig,omitempty" yaml:"replicaSetConfig,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + Template *PodTemplateSpec `json:"template,omitempty" yaml:"template,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_status.go new file mode 100644 index 0000000..a0cad24 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replica_set_status.go @@ -0,0 +1,20 @@ +package client + +const ( + ReplicaSetStatusType = "replicaSetStatus" + ReplicaSetStatusFieldAvailableReplicas = "availableReplicas" + ReplicaSetStatusFieldConditions = "conditions" + ReplicaSetStatusFieldFullyLabeledReplicas = "fullyLabeledReplicas" + ReplicaSetStatusFieldObservedGeneration = "observedGeneration" + ReplicaSetStatusFieldReadyReplicas = "readyReplicas" + ReplicaSetStatusFieldReplicas = "replicas" +) + +type ReplicaSetStatus struct { + AvailableReplicas int64 `json:"availableReplicas,omitempty" yaml:"availableReplicas,omitempty"` + Conditions []ReplicaSetCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + FullyLabeledReplicas int64 `json:"fullyLabeledReplicas,omitempty" yaml:"fullyLabeledReplicas,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + ReadyReplicas int64 `json:"readyReplicas,omitempty" yaml:"readyReplicas,omitempty"` + Replicas int64 `json:"replicas,omitempty" yaml:"replicas,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller.go new file mode 100644 index 0000000..2fd2bcb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller.go @@ -0,0 +1,233 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ReplicationControllerType = "replicationController" + ReplicationControllerFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + ReplicationControllerFieldAnnotations = "annotations" + ReplicationControllerFieldAppArmorProfile = "appArmorProfile" + ReplicationControllerFieldAutomountServiceAccountToken = "automountServiceAccountToken" + ReplicationControllerFieldContainers = "containers" + ReplicationControllerFieldCreated = "created" + ReplicationControllerFieldCreatorID = "creatorId" + ReplicationControllerFieldDNSConfig = "dnsConfig" + ReplicationControllerFieldDNSPolicy = "dnsPolicy" + ReplicationControllerFieldEnableServiceLinks = "enableServiceLinks" + ReplicationControllerFieldEphemeralContainers = "ephemeralContainers" + ReplicationControllerFieldFSGroupChangePolicy = "fsGroupChangePolicy" + ReplicationControllerFieldFsgid = "fsgid" + ReplicationControllerFieldGids = "gids" + ReplicationControllerFieldHostAliases = "hostAliases" + ReplicationControllerFieldHostIPC = "hostIPC" + ReplicationControllerFieldHostNetwork = "hostNetwork" + ReplicationControllerFieldHostPID = "hostPID" + ReplicationControllerFieldHostUsers = "hostUsers" + ReplicationControllerFieldHostname = "hostname" + ReplicationControllerFieldImagePullSecrets = "imagePullSecrets" + ReplicationControllerFieldLabels = "labels" + ReplicationControllerFieldName = "name" + ReplicationControllerFieldNamespaceId = "namespaceId" + ReplicationControllerFieldNodeID = "nodeId" + ReplicationControllerFieldOS = "os" + ReplicationControllerFieldOverhead = "overhead" + ReplicationControllerFieldOwnerReferences = "ownerReferences" + ReplicationControllerFieldPreemptionPolicy = "preemptionPolicy" + ReplicationControllerFieldProjectID = "projectId" + ReplicationControllerFieldPublicEndpoints = "publicEndpoints" + ReplicationControllerFieldReadinessGates = "readinessGates" + ReplicationControllerFieldRemoved = "removed" + ReplicationControllerFieldReplicationControllerConfig = "replicationControllerConfig" + ReplicationControllerFieldReplicationControllerStatus = "replicationControllerStatus" + ReplicationControllerFieldResourceClaims = "resourceClaims" + ReplicationControllerFieldRestartPolicy = "restartPolicy" + ReplicationControllerFieldRunAsGroup = "runAsGroup" + ReplicationControllerFieldRunAsNonRoot = "runAsNonRoot" + ReplicationControllerFieldRuntimeClassName = "runtimeClassName" + ReplicationControllerFieldScale = "scale" + ReplicationControllerFieldScheduling = "scheduling" + ReplicationControllerFieldSchedulingGates = "schedulingGates" + ReplicationControllerFieldSeccompProfile = "seccompProfile" + ReplicationControllerFieldSelector = "selector" + ReplicationControllerFieldServiceAccountName = "serviceAccountName" + ReplicationControllerFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + ReplicationControllerFieldShareProcessNamespace = "shareProcessNamespace" + ReplicationControllerFieldState = "state" + ReplicationControllerFieldSubdomain = "subdomain" + ReplicationControllerFieldSysctls = "sysctls" + ReplicationControllerFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + ReplicationControllerFieldTopologySpreadConstraints = "topologySpreadConstraints" + ReplicationControllerFieldTransitioning = "transitioning" + ReplicationControllerFieldTransitioningMessage = "transitioningMessage" + ReplicationControllerFieldUUID = "uuid" + ReplicationControllerFieldUid = "uid" + ReplicationControllerFieldVolumes = "volumes" + ReplicationControllerFieldWindowsOptions = "windowsOptions" + ReplicationControllerFieldWorkloadAnnotations = "workloadAnnotations" + ReplicationControllerFieldWorkloadLabels = "workloadLabels" + ReplicationControllerFieldWorkloadMetrics = "workloadMetrics" +) + +type ReplicationController struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ReplicationControllerConfig *ReplicationControllerConfig `json:"replicationControllerConfig,omitempty" yaml:"replicationControllerConfig,omitempty"` + ReplicationControllerStatus *ReplicationControllerStatus `json:"replicationControllerStatus,omitempty" yaml:"replicationControllerStatus,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type ReplicationControllerCollection struct { + types.Collection + Data []ReplicationController `json:"data,omitempty"` + client *ReplicationControllerClient +} + +type ReplicationControllerClient struct { + apiClient *Client +} + +type ReplicationControllerOperations interface { + List(opts *types.ListOpts) (*ReplicationControllerCollection, error) + ListAll(opts *types.ListOpts) (*ReplicationControllerCollection, error) + Create(opts *ReplicationController) (*ReplicationController, error) + Update(existing *ReplicationController, updates interface{}) (*ReplicationController, error) + Replace(existing *ReplicationController) (*ReplicationController, error) + ByID(id string) (*ReplicationController, error) + Delete(container *ReplicationController) error + + ActionRedeploy(resource *ReplicationController) error +} + +func newReplicationControllerClient(apiClient *Client) *ReplicationControllerClient { + return &ReplicationControllerClient{ + apiClient: apiClient, + } +} + +func (c *ReplicationControllerClient) Create(container *ReplicationController) (*ReplicationController, error) { + resp := &ReplicationController{} + err := c.apiClient.Ops.DoCreate(ReplicationControllerType, container, resp) + return resp, err +} + +func (c *ReplicationControllerClient) Update(existing *ReplicationController, updates interface{}) (*ReplicationController, error) { + resp := &ReplicationController{} + err := c.apiClient.Ops.DoUpdate(ReplicationControllerType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ReplicationControllerClient) Replace(obj *ReplicationController) (*ReplicationController, error) { + resp := &ReplicationController{} + err := c.apiClient.Ops.DoReplace(ReplicationControllerType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ReplicationControllerClient) List(opts *types.ListOpts) (*ReplicationControllerCollection, error) { + resp := &ReplicationControllerCollection{} + err := c.apiClient.Ops.DoList(ReplicationControllerType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ReplicationControllerClient) ListAll(opts *types.ListOpts) (*ReplicationControllerCollection, error) { + resp := &ReplicationControllerCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ReplicationControllerCollection) Next() (*ReplicationControllerCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ReplicationControllerCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ReplicationControllerClient) ByID(id string) (*ReplicationController, error) { + resp := &ReplicationController{} + err := c.apiClient.Ops.DoByID(ReplicationControllerType, id, resp) + return resp, err +} + +func (c *ReplicationControllerClient) Delete(container *ReplicationController) error { + return c.apiClient.Ops.DoResourceDelete(ReplicationControllerType, &container.Resource) +} + +func (c *ReplicationControllerClient) ActionRedeploy(resource *ReplicationController) error { + err := c.apiClient.Ops.DoAction(ReplicationControllerType, "redeploy", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_condition.go new file mode 100644 index 0000000..b6f2db1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + ReplicationControllerConditionType = "replicationControllerCondition" + ReplicationControllerConditionFieldLastTransitionTime = "lastTransitionTime" + ReplicationControllerConditionFieldMessage = "message" + ReplicationControllerConditionFieldReason = "reason" + ReplicationControllerConditionFieldStatus = "status" + ReplicationControllerConditionFieldType = "type" +) + +type ReplicationControllerCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_config.go new file mode 100644 index 0000000..5c26fe6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_config.go @@ -0,0 +1,10 @@ +package client + +const ( + ReplicationControllerConfigType = "replicationControllerConfig" + ReplicationControllerConfigFieldMinReadySeconds = "minReadySeconds" +) + +type ReplicationControllerConfig struct { + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_spec.go new file mode 100644 index 0000000..00816ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_spec.go @@ -0,0 +1,98 @@ +package client + +const ( + ReplicationControllerSpecType = "replicationControllerSpec" + ReplicationControllerSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + ReplicationControllerSpecFieldAppArmorProfile = "appArmorProfile" + ReplicationControllerSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + ReplicationControllerSpecFieldContainers = "containers" + ReplicationControllerSpecFieldDNSConfig = "dnsConfig" + ReplicationControllerSpecFieldDNSPolicy = "dnsPolicy" + ReplicationControllerSpecFieldEnableServiceLinks = "enableServiceLinks" + ReplicationControllerSpecFieldEphemeralContainers = "ephemeralContainers" + ReplicationControllerSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + ReplicationControllerSpecFieldFsgid = "fsgid" + ReplicationControllerSpecFieldGids = "gids" + ReplicationControllerSpecFieldHostAliases = "hostAliases" + ReplicationControllerSpecFieldHostIPC = "hostIPC" + ReplicationControllerSpecFieldHostNetwork = "hostNetwork" + ReplicationControllerSpecFieldHostPID = "hostPID" + ReplicationControllerSpecFieldHostUsers = "hostUsers" + ReplicationControllerSpecFieldHostname = "hostname" + ReplicationControllerSpecFieldImagePullSecrets = "imagePullSecrets" + ReplicationControllerSpecFieldNodeID = "nodeId" + ReplicationControllerSpecFieldOS = "os" + ReplicationControllerSpecFieldObjectMeta = "metadata" + ReplicationControllerSpecFieldOverhead = "overhead" + ReplicationControllerSpecFieldPreemptionPolicy = "preemptionPolicy" + ReplicationControllerSpecFieldReadinessGates = "readinessGates" + ReplicationControllerSpecFieldReplicationControllerConfig = "replicationControllerConfig" + ReplicationControllerSpecFieldResourceClaims = "resourceClaims" + ReplicationControllerSpecFieldRestartPolicy = "restartPolicy" + ReplicationControllerSpecFieldRunAsGroup = "runAsGroup" + ReplicationControllerSpecFieldRunAsNonRoot = "runAsNonRoot" + ReplicationControllerSpecFieldRuntimeClassName = "runtimeClassName" + ReplicationControllerSpecFieldScale = "scale" + ReplicationControllerSpecFieldScheduling = "scheduling" + ReplicationControllerSpecFieldSchedulingGates = "schedulingGates" + ReplicationControllerSpecFieldSeccompProfile = "seccompProfile" + ReplicationControllerSpecFieldSelector = "selector" + ReplicationControllerSpecFieldServiceAccountName = "serviceAccountName" + ReplicationControllerSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + ReplicationControllerSpecFieldShareProcessNamespace = "shareProcessNamespace" + ReplicationControllerSpecFieldSubdomain = "subdomain" + ReplicationControllerSpecFieldSysctls = "sysctls" + ReplicationControllerSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + ReplicationControllerSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + ReplicationControllerSpecFieldUid = "uid" + ReplicationControllerSpecFieldVolumes = "volumes" + ReplicationControllerSpecFieldWindowsOptions = "windowsOptions" +) + +type ReplicationControllerSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ReplicationControllerConfig *ReplicationControllerConfig `json:"replicationControllerConfig,omitempty" yaml:"replicationControllerConfig,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_status.go new file mode 100644 index 0000000..6ebadf0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_replication_controller_status.go @@ -0,0 +1,20 @@ +package client + +const ( + ReplicationControllerStatusType = "replicationControllerStatus" + ReplicationControllerStatusFieldAvailableReplicas = "availableReplicas" + ReplicationControllerStatusFieldConditions = "conditions" + ReplicationControllerStatusFieldFullyLabeledReplicas = "fullyLabeledReplicas" + ReplicationControllerStatusFieldObservedGeneration = "observedGeneration" + ReplicationControllerStatusFieldReadyReplicas = "readyReplicas" + ReplicationControllerStatusFieldReplicas = "replicas" +) + +type ReplicationControllerStatus struct { + AvailableReplicas int64 `json:"availableReplicas,omitempty" yaml:"availableReplicas,omitempty"` + Conditions []ReplicationControllerCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + FullyLabeledReplicas int64 `json:"fullyLabeledReplicas,omitempty" yaml:"fullyLabeledReplicas,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + ReadyReplicas int64 `json:"readyReplicas,omitempty" yaml:"readyReplicas,omitempty"` + Replicas int64 `json:"replicas,omitempty" yaml:"replicas,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_claim.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_claim.go new file mode 100644 index 0000000..1ef8e0a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_claim.go @@ -0,0 +1,10 @@ +package client + +const ( + ResourceClaimType = "resourceClaim" + ResourceClaimFieldName = "name" +) + +type ResourceClaim struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_field_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_field_selector.go new file mode 100644 index 0000000..d9c0c92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_field_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + ResourceFieldSelectorType = "resourceFieldSelector" + ResourceFieldSelectorFieldContainerName = "containerName" + ResourceFieldSelectorFieldDivisor = "divisor" + ResourceFieldSelectorFieldResource = "resource" +) + +type ResourceFieldSelector struct { + ContainerName string `json:"containerName,omitempty" yaml:"containerName,omitempty"` + Divisor string `json:"divisor,omitempty" yaml:"divisor,omitempty"` + Resource string `json:"resource,omitempty" yaml:"resource,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_source.go new file mode 100644 index 0000000..4b1683b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_source.go @@ -0,0 +1,12 @@ +package client + +const ( + ResourceMetricSourceType = "resourceMetricSource" + ResourceMetricSourceFieldName = "name" + ResourceMetricSourceFieldTarget = "target" +) + +type ResourceMetricSource struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Target *MetricTarget `json:"target,omitempty" yaml:"target,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_status.go new file mode 100644 index 0000000..24168ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_metric_status.go @@ -0,0 +1,12 @@ +package client + +const ( + ResourceMetricStatusType = "resourceMetricStatus" + ResourceMetricStatusFieldCurrent = "current" + ResourceMetricStatusFieldName = "name" +) + +type ResourceMetricStatus struct { + Current *MetricValueStatus `json:"current,omitempty" yaml:"current,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_requirements.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_requirements.go new file mode 100644 index 0000000..5fe765a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_resource_requirements.go @@ -0,0 +1,14 @@ +package client + +const ( + ResourceRequirementsType = "resourceRequirements" + ResourceRequirementsFieldClaims = "claims" + ResourceRequirementsFieldLimits = "limits" + ResourceRequirementsFieldRequests = "requests" +) + +type ResourceRequirements struct { + Claims []ResourceClaim `json:"claims,omitempty" yaml:"claims,omitempty"` + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + Requests map[string]string `json:"requests,omitempty" yaml:"requests,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rollback_revision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rollback_revision.go new file mode 100644 index 0000000..5db78d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rollback_revision.go @@ -0,0 +1,12 @@ +package client + +const ( + RollbackRevisionType = "rollbackRevision" + RollbackRevisionFieldForceUpgrade = "forceUpgrade" + RollbackRevisionFieldRevisionID = "revisionId" +) + +type RollbackRevision struct { + ForceUpgrade bool `json:"forceUpgrade,omitempty" yaml:"forceUpgrade,omitempty"` + RevisionID string `json:"revisionId,omitempty" yaml:"revisionId,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_daemon_set.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_daemon_set.go new file mode 100644 index 0000000..f6c2e12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_daemon_set.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + RollingUpdateDaemonSetType = "rollingUpdateDaemonSet" + RollingUpdateDaemonSetFieldMaxSurge = "maxSurge" + RollingUpdateDaemonSetFieldMaxUnavailable = "maxUnavailable" +) + +type RollingUpdateDaemonSet struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_deployment.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_deployment.go new file mode 100644 index 0000000..535fb36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_deployment.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + RollingUpdateDeploymentType = "rollingUpdateDeployment" + RollingUpdateDeploymentFieldMaxSurge = "maxSurge" + RollingUpdateDeploymentFieldMaxUnavailable = "maxUnavailable" +) + +type RollingUpdateDeployment struct { + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_stateful_set_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_stateful_set_strategy.go new file mode 100644 index 0000000..d9e0213 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_rolling_update_stateful_set_strategy.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + RollingUpdateStatefulSetStrategyType = "rollingUpdateStatefulSetStrategy" + RollingUpdateStatefulSetStrategyFieldMaxUnavailable = "maxUnavailable" + RollingUpdateStatefulSetStrategyFieldPartition = "partition" +) + +type RollingUpdateStatefulSetStrategy struct { + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + Partition *int64 `json:"partition,omitempty" yaml:"partition,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iopersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iopersistent_volume_source.go new file mode 100644 index 0000000..49871d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iopersistent_volume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + ScaleIOPersistentVolumeSourceType = "scaleIOPersistentVolumeSource" + ScaleIOPersistentVolumeSourceFieldFSType = "fsType" + ScaleIOPersistentVolumeSourceFieldGateway = "gateway" + ScaleIOPersistentVolumeSourceFieldProtectionDomain = "protectionDomain" + ScaleIOPersistentVolumeSourceFieldReadOnly = "readOnly" + ScaleIOPersistentVolumeSourceFieldSSLEnabled = "sslEnabled" + ScaleIOPersistentVolumeSourceFieldSecretRef = "secretRef" + ScaleIOPersistentVolumeSourceFieldStorageMode = "storageMode" + ScaleIOPersistentVolumeSourceFieldStoragePool = "storagePool" + ScaleIOPersistentVolumeSourceFieldSystem = "system" + ScaleIOPersistentVolumeSourceFieldVolumeName = "volumeName" +) + +type ScaleIOPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Gateway string `json:"gateway,omitempty" yaml:"gateway,omitempty"` + ProtectionDomain string `json:"protectionDomain,omitempty" yaml:"protectionDomain,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SSLEnabled bool `json:"sslEnabled,omitempty" yaml:"sslEnabled,omitempty"` + SecretRef *SecretReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + StorageMode string `json:"storageMode,omitempty" yaml:"storageMode,omitempty"` + StoragePool string `json:"storagePool,omitempty" yaml:"storagePool,omitempty"` + System string `json:"system,omitempty" yaml:"system,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iovolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iovolume_source.go new file mode 100644 index 0000000..58e0009 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scale_iovolume_source.go @@ -0,0 +1,28 @@ +package client + +const ( + ScaleIOVolumeSourceType = "scaleIOVolumeSource" + ScaleIOVolumeSourceFieldFSType = "fsType" + ScaleIOVolumeSourceFieldGateway = "gateway" + ScaleIOVolumeSourceFieldProtectionDomain = "protectionDomain" + ScaleIOVolumeSourceFieldReadOnly = "readOnly" + ScaleIOVolumeSourceFieldSSLEnabled = "sslEnabled" + ScaleIOVolumeSourceFieldSecretRef = "secretRef" + ScaleIOVolumeSourceFieldStorageMode = "storageMode" + ScaleIOVolumeSourceFieldStoragePool = "storagePool" + ScaleIOVolumeSourceFieldSystem = "system" + ScaleIOVolumeSourceFieldVolumeName = "volumeName" +) + +type ScaleIOVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + Gateway string `json:"gateway,omitempty" yaml:"gateway,omitempty"` + ProtectionDomain string `json:"protectionDomain,omitempty" yaml:"protectionDomain,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SSLEnabled bool `json:"sslEnabled,omitempty" yaml:"sslEnabled,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + StorageMode string `json:"storageMode,omitempty" yaml:"storageMode,omitempty"` + StoragePool string `json:"storagePool,omitempty" yaml:"storagePool,omitempty"` + System string `json:"system,omitempty" yaml:"system,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scheduling.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scheduling.go new file mode 100644 index 0000000..2abbb5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_scheduling.go @@ -0,0 +1,18 @@ +package client + +const ( + SchedulingType = "scheduling" + SchedulingFieldNode = "node" + SchedulingFieldPriority = "priority" + SchedulingFieldPriorityClassName = "priorityClassName" + SchedulingFieldScheduler = "scheduler" + SchedulingFieldTolerate = "tolerate" +) + +type Scheduling struct { + Node *NodeScheduling `json:"node,omitempty" yaml:"node,omitempty"` + Priority *int64 `json:"priority,omitempty" yaml:"priority,omitempty"` + PriorityClassName string `json:"priorityClassName,omitempty" yaml:"priorityClassName,omitempty"` + Scheduler string `json:"scheduler,omitempty" yaml:"scheduler,omitempty"` + Tolerate []Toleration `json:"tolerate,omitempty" yaml:"tolerate,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_se_linux_options.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_se_linux_options.go new file mode 100644 index 0000000..5e109c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_se_linux_options.go @@ -0,0 +1,16 @@ +package client + +const ( + SELinuxOptionsType = "seLinuxOptions" + SELinuxOptionsFieldLevel = "level" + SELinuxOptionsFieldRole = "role" + SELinuxOptionsFieldType = "type" + SELinuxOptionsFieldUser = "user" +) + +type SELinuxOptions struct { + Level string `json:"level,omitempty" yaml:"level,omitempty"` + Role string `json:"role,omitempty" yaml:"role,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_seccomp_profile.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_seccomp_profile.go new file mode 100644 index 0000000..77154f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_seccomp_profile.go @@ -0,0 +1,12 @@ +package client + +const ( + SeccompProfileType = "seccompProfile" + SeccompProfileFieldLocalhostProfile = "localhostProfile" + SeccompProfileFieldType = "type" +) + +type SeccompProfile struct { + LocalhostProfile string `json:"localhostProfile,omitempty" yaml:"localhostProfile,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret.go new file mode 100644 index 0000000..3c1385c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + SecretType = "secret" + SecretFieldAnnotations = "annotations" + SecretFieldCreated = "created" + SecretFieldCreatorID = "creatorId" + SecretFieldData = "data" + SecretFieldDescription = "description" + SecretFieldImmutable = "immutable" + SecretFieldKind = "kind" + SecretFieldLabels = "labels" + SecretFieldName = "name" + SecretFieldNamespaceId = "namespaceId" + SecretFieldOwnerReferences = "ownerReferences" + SecretFieldProjectID = "projectId" + SecretFieldRemoved = "removed" + SecretFieldStringData = "stringData" + SecretFieldUUID = "uuid" +) + +type Secret struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Data map[string]string `json:"data,omitempty" yaml:"data,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Immutable *bool `json:"immutable,omitempty" yaml:"immutable,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + StringData map[string]string `json:"stringData,omitempty" yaml:"stringData,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type SecretCollection struct { + types.Collection + Data []Secret `json:"data,omitempty"` + client *SecretClient +} + +type SecretClient struct { + apiClient *Client +} + +type SecretOperations interface { + List(opts *types.ListOpts) (*SecretCollection, error) + ListAll(opts *types.ListOpts) (*SecretCollection, error) + Create(opts *Secret) (*Secret, error) + Update(existing *Secret, updates interface{}) (*Secret, error) + Replace(existing *Secret) (*Secret, error) + ByID(id string) (*Secret, error) + Delete(container *Secret) error +} + +func newSecretClient(apiClient *Client) *SecretClient { + return &SecretClient{ + apiClient: apiClient, + } +} + +func (c *SecretClient) Create(container *Secret) (*Secret, error) { + resp := &Secret{} + err := c.apiClient.Ops.DoCreate(SecretType, container, resp) + return resp, err +} + +func (c *SecretClient) Update(existing *Secret, updates interface{}) (*Secret, error) { + resp := &Secret{} + err := c.apiClient.Ops.DoUpdate(SecretType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *SecretClient) Replace(obj *Secret) (*Secret, error) { + resp := &Secret{} + err := c.apiClient.Ops.DoReplace(SecretType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *SecretClient) List(opts *types.ListOpts) (*SecretCollection, error) { + resp := &SecretCollection{} + err := c.apiClient.Ops.DoList(SecretType, opts, resp) + resp.client = c + return resp, err +} + +func (c *SecretClient) ListAll(opts *types.ListOpts) (*SecretCollection, error) { + resp := &SecretCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *SecretCollection) Next() (*SecretCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &SecretCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *SecretClient) ByID(id string) (*Secret, error) { + resp := &Secret{} + err := c.apiClient.Ops.DoByID(SecretType, id, resp) + return resp, err +} + +func (c *SecretClient) Delete(container *Secret) error { + return c.apiClient.Ops.DoResourceDelete(SecretType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_env_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_env_source.go new file mode 100644 index 0000000..103c7b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_env_source.go @@ -0,0 +1,12 @@ +package client + +const ( + SecretEnvSourceType = "secretEnvSource" + SecretEnvSourceFieldName = "name" + SecretEnvSourceFieldOptional = "optional" +) + +type SecretEnvSource struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_key_selector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_key_selector.go new file mode 100644 index 0000000..9a23641 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_key_selector.go @@ -0,0 +1,14 @@ +package client + +const ( + SecretKeySelectorType = "secretKeySelector" + SecretKeySelectorFieldKey = "key" + SecretKeySelectorFieldName = "name" + SecretKeySelectorFieldOptional = "optional" +) + +type SecretKeySelector struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_projection.go new file mode 100644 index 0000000..684b025 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + SecretProjectionType = "secretProjection" + SecretProjectionFieldItems = "items" + SecretProjectionFieldName = "name" + SecretProjectionFieldOptional = "optional" +) + +type SecretProjection struct { + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_reference.go new file mode 100644 index 0000000..331f9a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_reference.go @@ -0,0 +1,12 @@ +package client + +const ( + SecretReferenceType = "secretReference" + SecretReferenceFieldName = "name" + SecretReferenceFieldNamespace = "namespace" +) + +type SecretReference struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_volume_source.go new file mode 100644 index 0000000..bdb5109 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_secret_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + SecretVolumeSourceType = "secretVolumeSource" + SecretVolumeSourceFieldDefaultMode = "defaultMode" + SecretVolumeSourceFieldItems = "items" + SecretVolumeSourceFieldOptional = "optional" + SecretVolumeSourceFieldSecretName = "secretName" +) + +type SecretVolumeSource struct { + DefaultMode *int64 `json:"defaultMode,omitempty" yaml:"defaultMode,omitempty"` + Items []KeyToPath `json:"items,omitempty" yaml:"items,omitempty"` + Optional *bool `json:"optional,omitempty" yaml:"optional,omitempty"` + SecretName string `json:"secretName,omitempty" yaml:"secretName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_security_context.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_security_context.go new file mode 100644 index 0000000..1def599 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_security_context.go @@ -0,0 +1,32 @@ +package client + +const ( + SecurityContextType = "securityContext" + SecurityContextFieldAllowPrivilegeEscalation = "allowPrivilegeEscalation" + SecurityContextFieldAppArmorProfile = "appArmorProfile" + SecurityContextFieldCapAdd = "capAdd" + SecurityContextFieldCapDrop = "capDrop" + SecurityContextFieldPrivileged = "privileged" + SecurityContextFieldProcMount = "procMount" + SecurityContextFieldReadOnly = "readOnly" + SecurityContextFieldRunAsGroup = "runAsGroup" + SecurityContextFieldRunAsNonRoot = "runAsNonRoot" + SecurityContextFieldSeccompProfile = "seccompProfile" + SecurityContextFieldUid = "uid" + SecurityContextFieldWindowsOptions = "windowsOptions" +) + +type SecurityContext struct { + AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty" yaml:"allowPrivilegeEscalation,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + CapAdd []string `json:"capAdd,omitempty" yaml:"capAdd,omitempty"` + CapDrop []string `json:"capDrop,omitempty" yaml:"capDrop,omitempty"` + Privileged *bool `json:"privileged,omitempty" yaml:"privileged,omitempty"` + ProcMount string `json:"procMount,omitempty" yaml:"procMount,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service.go new file mode 100644 index 0000000..1b9af8f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service.go @@ -0,0 +1,180 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ServiceType = "service" + ServiceFieldAllocateLoadBalancerNodePorts = "allocateLoadBalancerNodePorts" + ServiceFieldAnnotations = "annotations" + ServiceFieldClusterIPs = "clusterIPs" + ServiceFieldClusterIp = "clusterIp" + ServiceFieldCreated = "created" + ServiceFieldCreatorID = "creatorId" + ServiceFieldDescription = "description" + ServiceFieldExternalIPs = "externalIPs" + ServiceFieldExternalTrafficPolicy = "externalTrafficPolicy" + ServiceFieldHealthCheckNodePort = "healthCheckNodePort" + ServiceFieldHostname = "hostname" + ServiceFieldIPAddresses = "ipAddresses" + ServiceFieldIPFamilies = "ipFamilies" + ServiceFieldIPFamilyPolicy = "ipFamilyPolicy" + ServiceFieldInternalTrafficPolicy = "internalTrafficPolicy" + ServiceFieldKind = "kind" + ServiceFieldLabels = "labels" + ServiceFieldLoadBalancerClass = "loadBalancerClass" + ServiceFieldLoadBalancerIP = "loadBalancerIP" + ServiceFieldLoadBalancerSourceRanges = "loadBalancerSourceRanges" + ServiceFieldName = "name" + ServiceFieldNamespaceId = "namespaceId" + ServiceFieldOwnerReferences = "ownerReferences" + ServiceFieldPorts = "ports" + ServiceFieldProjectID = "projectId" + ServiceFieldPublicEndpoints = "publicEndpoints" + ServiceFieldPublishNotReadyAddresses = "publishNotReadyAddresses" + ServiceFieldRemoved = "removed" + ServiceFieldSelector = "selector" + ServiceFieldSessionAffinity = "sessionAffinity" + ServiceFieldSessionAffinityConfig = "sessionAffinityConfig" + ServiceFieldState = "state" + ServiceFieldTargetDNSRecordIDs = "targetDnsRecordIds" + ServiceFieldTargetWorkloadIDs = "targetWorkloadIds" + ServiceFieldTrafficDistribution = "trafficDistribution" + ServiceFieldTransitioning = "transitioning" + ServiceFieldTransitioningMessage = "transitioningMessage" + ServiceFieldUUID = "uuid" + ServiceFieldWorkloadID = "workloadId" +) + +type Service struct { + types.Resource + AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty" yaml:"allocateLoadBalancerNodePorts,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + ClusterIPs []string `json:"clusterIPs,omitempty" yaml:"clusterIPs,omitempty"` + ClusterIp string `json:"clusterIp,omitempty" yaml:"clusterIp,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ExternalIPs []string `json:"externalIPs,omitempty" yaml:"externalIPs,omitempty"` + ExternalTrafficPolicy string `json:"externalTrafficPolicy,omitempty" yaml:"externalTrafficPolicy,omitempty"` + HealthCheckNodePort int64 `json:"healthCheckNodePort,omitempty" yaml:"healthCheckNodePort,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPAddresses []string `json:"ipAddresses,omitempty" yaml:"ipAddresses,omitempty"` + IPFamilies []string `json:"ipFamilies,omitempty" yaml:"ipFamilies,omitempty"` + IPFamilyPolicy string `json:"ipFamilyPolicy,omitempty" yaml:"ipFamilyPolicy,omitempty"` + InternalTrafficPolicy string `json:"internalTrafficPolicy,omitempty" yaml:"internalTrafficPolicy,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + LoadBalancerClass string `json:"loadBalancerClass,omitempty" yaml:"loadBalancerClass,omitempty"` + LoadBalancerIP string `json:"loadBalancerIP,omitempty" yaml:"loadBalancerIP,omitempty"` + LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty" yaml:"loadBalancerSourceRanges,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Ports []ServicePort `json:"ports,omitempty" yaml:"ports,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + PublishNotReadyAddresses bool `json:"publishNotReadyAddresses,omitempty" yaml:"publishNotReadyAddresses,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` + SessionAffinity string `json:"sessionAffinity,omitempty" yaml:"sessionAffinity,omitempty"` + SessionAffinityConfig *SessionAffinityConfig `json:"sessionAffinityConfig,omitempty" yaml:"sessionAffinityConfig,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + TargetDNSRecordIDs []string `json:"targetDnsRecordIds,omitempty" yaml:"targetDnsRecordIds,omitempty"` + TargetWorkloadIDs []string `json:"targetWorkloadIds,omitempty" yaml:"targetWorkloadIds,omitempty"` + TrafficDistribution string `json:"trafficDistribution,omitempty" yaml:"trafficDistribution,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + WorkloadID string `json:"workloadId,omitempty" yaml:"workloadId,omitempty"` +} + +type ServiceCollection struct { + types.Collection + Data []Service `json:"data,omitempty"` + client *ServiceClient +} + +type ServiceClient struct { + apiClient *Client +} + +type ServiceOperations interface { + List(opts *types.ListOpts) (*ServiceCollection, error) + ListAll(opts *types.ListOpts) (*ServiceCollection, error) + Create(opts *Service) (*Service, error) + Update(existing *Service, updates interface{}) (*Service, error) + Replace(existing *Service) (*Service, error) + ByID(id string) (*Service, error) + Delete(container *Service) error +} + +func newServiceClient(apiClient *Client) *ServiceClient { + return &ServiceClient{ + apiClient: apiClient, + } +} + +func (c *ServiceClient) Create(container *Service) (*Service, error) { + resp := &Service{} + err := c.apiClient.Ops.DoCreate(ServiceType, container, resp) + return resp, err +} + +func (c *ServiceClient) Update(existing *Service, updates interface{}) (*Service, error) { + resp := &Service{} + err := c.apiClient.Ops.DoUpdate(ServiceType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ServiceClient) Replace(obj *Service) (*Service, error) { + resp := &Service{} + err := c.apiClient.Ops.DoReplace(ServiceType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ServiceClient) List(opts *types.ListOpts) (*ServiceCollection, error) { + resp := &ServiceCollection{} + err := c.apiClient.Ops.DoList(ServiceType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ServiceClient) ListAll(opts *types.ListOpts) (*ServiceCollection, error) { + resp := &ServiceCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ServiceCollection) Next() (*ServiceCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ServiceCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ServiceClient) ByID(id string) (*Service, error) { + resp := &Service{} + err := c.apiClient.Ops.DoByID(ServiceType, id, resp) + return resp, err +} + +func (c *ServiceClient) Delete(container *Service) error { + return c.apiClient.Ops.DoResourceDelete(ServiceType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token.go new file mode 100644 index 0000000..a851b80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token.go @@ -0,0 +1,132 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + ServiceAccountTokenType = "serviceAccountToken" + ServiceAccountTokenFieldAccountName = "accountName" + ServiceAccountTokenFieldAccountUID = "accountUid" + ServiceAccountTokenFieldAnnotations = "annotations" + ServiceAccountTokenFieldCACRT = "caCrt" + ServiceAccountTokenFieldCreated = "created" + ServiceAccountTokenFieldCreatorID = "creatorId" + ServiceAccountTokenFieldDescription = "description" + ServiceAccountTokenFieldLabels = "labels" + ServiceAccountTokenFieldName = "name" + ServiceAccountTokenFieldNamespaceId = "namespaceId" + ServiceAccountTokenFieldOwnerReferences = "ownerReferences" + ServiceAccountTokenFieldProjectID = "projectId" + ServiceAccountTokenFieldRemoved = "removed" + ServiceAccountTokenFieldToken = "token" + ServiceAccountTokenFieldUUID = "uuid" +) + +type ServiceAccountToken struct { + types.Resource + AccountName string `json:"accountName,omitempty" yaml:"accountName,omitempty"` + AccountUID string `json:"accountUid,omitempty" yaml:"accountUid,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + CACRT string `json:"caCrt,omitempty" yaml:"caCrt,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + Token string `json:"token,omitempty" yaml:"token,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type ServiceAccountTokenCollection struct { + types.Collection + Data []ServiceAccountToken `json:"data,omitempty"` + client *ServiceAccountTokenClient +} + +type ServiceAccountTokenClient struct { + apiClient *Client +} + +type ServiceAccountTokenOperations interface { + List(opts *types.ListOpts) (*ServiceAccountTokenCollection, error) + ListAll(opts *types.ListOpts) (*ServiceAccountTokenCollection, error) + Create(opts *ServiceAccountToken) (*ServiceAccountToken, error) + Update(existing *ServiceAccountToken, updates interface{}) (*ServiceAccountToken, error) + Replace(existing *ServiceAccountToken) (*ServiceAccountToken, error) + ByID(id string) (*ServiceAccountToken, error) + Delete(container *ServiceAccountToken) error +} + +func newServiceAccountTokenClient(apiClient *Client) *ServiceAccountTokenClient { + return &ServiceAccountTokenClient{ + apiClient: apiClient, + } +} + +func (c *ServiceAccountTokenClient) Create(container *ServiceAccountToken) (*ServiceAccountToken, error) { + resp := &ServiceAccountToken{} + err := c.apiClient.Ops.DoCreate(ServiceAccountTokenType, container, resp) + return resp, err +} + +func (c *ServiceAccountTokenClient) Update(existing *ServiceAccountToken, updates interface{}) (*ServiceAccountToken, error) { + resp := &ServiceAccountToken{} + err := c.apiClient.Ops.DoUpdate(ServiceAccountTokenType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *ServiceAccountTokenClient) Replace(obj *ServiceAccountToken) (*ServiceAccountToken, error) { + resp := &ServiceAccountToken{} + err := c.apiClient.Ops.DoReplace(ServiceAccountTokenType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *ServiceAccountTokenClient) List(opts *types.ListOpts) (*ServiceAccountTokenCollection, error) { + resp := &ServiceAccountTokenCollection{} + err := c.apiClient.Ops.DoList(ServiceAccountTokenType, opts, resp) + resp.client = c + return resp, err +} + +func (c *ServiceAccountTokenClient) ListAll(opts *types.ListOpts) (*ServiceAccountTokenCollection, error) { + resp := &ServiceAccountTokenCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *ServiceAccountTokenCollection) Next() (*ServiceAccountTokenCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &ServiceAccountTokenCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *ServiceAccountTokenClient) ByID(id string) (*ServiceAccountToken, error) { + resp := &ServiceAccountToken{} + err := c.apiClient.Ops.DoByID(ServiceAccountTokenType, id, resp) + return resp, err +} + +func (c *ServiceAccountTokenClient) Delete(container *ServiceAccountToken) error { + return c.apiClient.Ops.DoResourceDelete(ServiceAccountTokenType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token_projection.go new file mode 100644 index 0000000..7d2e880 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_account_token_projection.go @@ -0,0 +1,14 @@ +package client + +const ( + ServiceAccountTokenProjectionType = "serviceAccountTokenProjection" + ServiceAccountTokenProjectionFieldAudience = "audience" + ServiceAccountTokenProjectionFieldExpirationSeconds = "expirationSeconds" + ServiceAccountTokenProjectionFieldPath = "path" +) + +type ServiceAccountTokenProjection struct { + Audience string `json:"audience,omitempty" yaml:"audience,omitempty"` + ExpirationSeconds *int64 `json:"expirationSeconds,omitempty" yaml:"expirationSeconds,omitempty"` + Path string `json:"path,omitempty" yaml:"path,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_backend_port.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_backend_port.go new file mode 100644 index 0000000..d016dea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_backend_port.go @@ -0,0 +1,12 @@ +package client + +const ( + ServiceBackendPortType = "serviceBackendPort" + ServiceBackendPortFieldName = "name" + ServiceBackendPortFieldNumber = "number" +) + +type ServiceBackendPort struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Number int64 `json:"number,omitempty" yaml:"number,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_port.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_port.go new file mode 100644 index 0000000..2a31ca0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_port.go @@ -0,0 +1,24 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + ServicePortType = "servicePort" + ServicePortFieldAppProtocol = "appProtocol" + ServicePortFieldName = "name" + ServicePortFieldNodePort = "nodePort" + ServicePortFieldPort = "port" + ServicePortFieldProtocol = "protocol" + ServicePortFieldTargetPort = "targetPort" +) + +type ServicePort struct { + AppProtocol string `json:"appProtocol,omitempty" yaml:"appProtocol,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NodePort int64 `json:"nodePort,omitempty" yaml:"nodePort,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"` + TargetPort intstr.IntOrString `json:"targetPort,omitempty" yaml:"targetPort,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_spec.go new file mode 100644 index 0000000..da96fea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_spec.go @@ -0,0 +1,48 @@ +package client + +const ( + ServiceSpecType = "serviceSpec" + ServiceSpecFieldAllocateLoadBalancerNodePorts = "allocateLoadBalancerNodePorts" + ServiceSpecFieldClusterIPs = "clusterIPs" + ServiceSpecFieldClusterIp = "clusterIp" + ServiceSpecFieldExternalIPs = "externalIPs" + ServiceSpecFieldExternalTrafficPolicy = "externalTrafficPolicy" + ServiceSpecFieldHealthCheckNodePort = "healthCheckNodePort" + ServiceSpecFieldHostname = "hostname" + ServiceSpecFieldIPFamilies = "ipFamilies" + ServiceSpecFieldIPFamilyPolicy = "ipFamilyPolicy" + ServiceSpecFieldInternalTrafficPolicy = "internalTrafficPolicy" + ServiceSpecFieldLoadBalancerClass = "loadBalancerClass" + ServiceSpecFieldLoadBalancerIP = "loadBalancerIP" + ServiceSpecFieldLoadBalancerSourceRanges = "loadBalancerSourceRanges" + ServiceSpecFieldPorts = "ports" + ServiceSpecFieldPublishNotReadyAddresses = "publishNotReadyAddresses" + ServiceSpecFieldSelector = "selector" + ServiceSpecFieldServiceKind = "serviceKind" + ServiceSpecFieldSessionAffinity = "sessionAffinity" + ServiceSpecFieldSessionAffinityConfig = "sessionAffinityConfig" + ServiceSpecFieldTrafficDistribution = "trafficDistribution" +) + +type ServiceSpec struct { + AllocateLoadBalancerNodePorts *bool `json:"allocateLoadBalancerNodePorts,omitempty" yaml:"allocateLoadBalancerNodePorts,omitempty"` + ClusterIPs []string `json:"clusterIPs,omitempty" yaml:"clusterIPs,omitempty"` + ClusterIp string `json:"clusterIp,omitempty" yaml:"clusterIp,omitempty"` + ExternalIPs []string `json:"externalIPs,omitempty" yaml:"externalIPs,omitempty"` + ExternalTrafficPolicy string `json:"externalTrafficPolicy,omitempty" yaml:"externalTrafficPolicy,omitempty"` + HealthCheckNodePort int64 `json:"healthCheckNodePort,omitempty" yaml:"healthCheckNodePort,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + IPFamilies []string `json:"ipFamilies,omitempty" yaml:"ipFamilies,omitempty"` + IPFamilyPolicy string `json:"ipFamilyPolicy,omitempty" yaml:"ipFamilyPolicy,omitempty"` + InternalTrafficPolicy string `json:"internalTrafficPolicy,omitempty" yaml:"internalTrafficPolicy,omitempty"` + LoadBalancerClass string `json:"loadBalancerClass,omitempty" yaml:"loadBalancerClass,omitempty"` + LoadBalancerIP string `json:"loadBalancerIP,omitempty" yaml:"loadBalancerIP,omitempty"` + LoadBalancerSourceRanges []string `json:"loadBalancerSourceRanges,omitempty" yaml:"loadBalancerSourceRanges,omitempty"` + Ports []ServicePort `json:"ports,omitempty" yaml:"ports,omitempty"` + PublishNotReadyAddresses bool `json:"publishNotReadyAddresses,omitempty" yaml:"publishNotReadyAddresses,omitempty"` + Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceKind string `json:"serviceKind,omitempty" yaml:"serviceKind,omitempty"` + SessionAffinity string `json:"sessionAffinity,omitempty" yaml:"sessionAffinity,omitempty"` + SessionAffinityConfig *SessionAffinityConfig `json:"sessionAffinityConfig,omitempty" yaml:"sessionAffinityConfig,omitempty"` + TrafficDistribution string `json:"trafficDistribution,omitempty" yaml:"trafficDistribution,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_status.go new file mode 100644 index 0000000..9d00b84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_service_status.go @@ -0,0 +1,12 @@ +package client + +const ( + ServiceStatusType = "serviceStatus" + ServiceStatusFieldConditions = "conditions" + ServiceStatusFieldLoadBalancer = "loadBalancer" +) + +type ServiceStatus struct { + Conditions []Condition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + LoadBalancer *LoadBalancerStatus `json:"loadBalancer,omitempty" yaml:"loadBalancer,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_session_affinity_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_session_affinity_config.go new file mode 100644 index 0000000..0ae641b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_session_affinity_config.go @@ -0,0 +1,10 @@ +package client + +const ( + SessionAffinityConfigType = "sessionAffinityConfig" + SessionAffinityConfigFieldClientIP = "clientIP" +) + +type SessionAffinityConfig struct { + ClientIP *ClientIPConfig `json:"clientIP,omitempty" yaml:"clientIP,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sleep_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sleep_action.go new file mode 100644 index 0000000..74d46c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sleep_action.go @@ -0,0 +1,10 @@ +package client + +const ( + SleepActionType = "sleepAction" + SleepActionFieldSeconds = "seconds" +) + +type SleepAction struct { + Seconds int64 `json:"seconds,omitempty" yaml:"seconds,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ssh_auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ssh_auth.go new file mode 100644 index 0000000..e7ad07a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_ssh_auth.go @@ -0,0 +1,128 @@ +package client + +import ( + "github.com/rancher/norman/types" +) + +const ( + SSHAuthType = "sshAuth" + SSHAuthFieldAnnotations = "annotations" + SSHAuthFieldCreated = "created" + SSHAuthFieldCreatorID = "creatorId" + SSHAuthFieldDescription = "description" + SSHAuthFieldFingerprint = "certFingerprint" + SSHAuthFieldLabels = "labels" + SSHAuthFieldName = "name" + SSHAuthFieldNamespaceId = "namespaceId" + SSHAuthFieldOwnerReferences = "ownerReferences" + SSHAuthFieldPrivateKey = "privateKey" + SSHAuthFieldProjectID = "projectId" + SSHAuthFieldRemoved = "removed" + SSHAuthFieldUUID = "uuid" +) + +type SSHAuth struct { + types.Resource + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Fingerprint string `json:"certFingerprint,omitempty" yaml:"certFingerprint,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PrivateKey string `json:"privateKey,omitempty" yaml:"privateKey,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` +} + +type SSHAuthCollection struct { + types.Collection + Data []SSHAuth `json:"data,omitempty"` + client *SSHAuthClient +} + +type SSHAuthClient struct { + apiClient *Client +} + +type SSHAuthOperations interface { + List(opts *types.ListOpts) (*SSHAuthCollection, error) + ListAll(opts *types.ListOpts) (*SSHAuthCollection, error) + Create(opts *SSHAuth) (*SSHAuth, error) + Update(existing *SSHAuth, updates interface{}) (*SSHAuth, error) + Replace(existing *SSHAuth) (*SSHAuth, error) + ByID(id string) (*SSHAuth, error) + Delete(container *SSHAuth) error +} + +func newSSHAuthClient(apiClient *Client) *SSHAuthClient { + return &SSHAuthClient{ + apiClient: apiClient, + } +} + +func (c *SSHAuthClient) Create(container *SSHAuth) (*SSHAuth, error) { + resp := &SSHAuth{} + err := c.apiClient.Ops.DoCreate(SSHAuthType, container, resp) + return resp, err +} + +func (c *SSHAuthClient) Update(existing *SSHAuth, updates interface{}) (*SSHAuth, error) { + resp := &SSHAuth{} + err := c.apiClient.Ops.DoUpdate(SSHAuthType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *SSHAuthClient) Replace(obj *SSHAuth) (*SSHAuth, error) { + resp := &SSHAuth{} + err := c.apiClient.Ops.DoReplace(SSHAuthType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *SSHAuthClient) List(opts *types.ListOpts) (*SSHAuthCollection, error) { + resp := &SSHAuthCollection{} + err := c.apiClient.Ops.DoList(SSHAuthType, opts, resp) + resp.client = c + return resp, err +} + +func (c *SSHAuthClient) ListAll(opts *types.ListOpts) (*SSHAuthCollection, error) { + resp := &SSHAuthCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *SSHAuthCollection) Next() (*SSHAuthCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &SSHAuthCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *SSHAuthClient) ByID(id string) (*SSHAuth, error) { + resp := &SSHAuth{} + err := c.apiClient.Ops.DoByID(SSHAuthType, id, resp) + return resp, err +} + +func (c *SSHAuthClient) Delete(container *SSHAuth) error { + return c.apiClient.Ops.DoResourceDelete(SSHAuthType, &container.Resource) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set.go new file mode 100644 index 0000000..fb588ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set.go @@ -0,0 +1,243 @@ +package client + +import ( + "github.com/rancher/norman/types" + + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + StatefulSetType = "statefulSet" + StatefulSetFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + StatefulSetFieldAnnotations = "annotations" + StatefulSetFieldAppArmorProfile = "appArmorProfile" + StatefulSetFieldAutomountServiceAccountToken = "automountServiceAccountToken" + StatefulSetFieldContainers = "containers" + StatefulSetFieldCreated = "created" + StatefulSetFieldCreatorID = "creatorId" + StatefulSetFieldDNSConfig = "dnsConfig" + StatefulSetFieldDNSPolicy = "dnsPolicy" + StatefulSetFieldEnableServiceLinks = "enableServiceLinks" + StatefulSetFieldEphemeralContainers = "ephemeralContainers" + StatefulSetFieldFSGroupChangePolicy = "fsGroupChangePolicy" + StatefulSetFieldFsgid = "fsgid" + StatefulSetFieldGids = "gids" + StatefulSetFieldHostAliases = "hostAliases" + StatefulSetFieldHostIPC = "hostIPC" + StatefulSetFieldHostNetwork = "hostNetwork" + StatefulSetFieldHostPID = "hostPID" + StatefulSetFieldHostUsers = "hostUsers" + StatefulSetFieldHostname = "hostname" + StatefulSetFieldImagePullSecrets = "imagePullSecrets" + StatefulSetFieldLabels = "labels" + StatefulSetFieldMaxUnavailable = "maxUnavailable" + StatefulSetFieldMinReadySeconds = "minReadySeconds" + StatefulSetFieldName = "name" + StatefulSetFieldNamespaceId = "namespaceId" + StatefulSetFieldNodeID = "nodeId" + StatefulSetFieldOS = "os" + StatefulSetFieldOrdinals = "ordinals" + StatefulSetFieldOverhead = "overhead" + StatefulSetFieldOwnerReferences = "ownerReferences" + StatefulSetFieldPersistentVolumeClaimRetentionPolicy = "persistentVolumeClaimRetentionPolicy" + StatefulSetFieldPreemptionPolicy = "preemptionPolicy" + StatefulSetFieldProjectID = "projectId" + StatefulSetFieldPublicEndpoints = "publicEndpoints" + StatefulSetFieldReadinessGates = "readinessGates" + StatefulSetFieldRemoved = "removed" + StatefulSetFieldResourceClaims = "resourceClaims" + StatefulSetFieldRestartPolicy = "restartPolicy" + StatefulSetFieldRunAsGroup = "runAsGroup" + StatefulSetFieldRunAsNonRoot = "runAsNonRoot" + StatefulSetFieldRuntimeClassName = "runtimeClassName" + StatefulSetFieldScale = "scale" + StatefulSetFieldScheduling = "scheduling" + StatefulSetFieldSchedulingGates = "schedulingGates" + StatefulSetFieldSeccompProfile = "seccompProfile" + StatefulSetFieldSelector = "selector" + StatefulSetFieldServiceAccountName = "serviceAccountName" + StatefulSetFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + StatefulSetFieldShareProcessNamespace = "shareProcessNamespace" + StatefulSetFieldState = "state" + StatefulSetFieldStatefulSetConfig = "statefulSetConfig" + StatefulSetFieldStatefulSetStatus = "statefulSetStatus" + StatefulSetFieldSubdomain = "subdomain" + StatefulSetFieldSysctls = "sysctls" + StatefulSetFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + StatefulSetFieldTopologySpreadConstraints = "topologySpreadConstraints" + StatefulSetFieldTransitioning = "transitioning" + StatefulSetFieldTransitioningMessage = "transitioningMessage" + StatefulSetFieldUUID = "uuid" + StatefulSetFieldUid = "uid" + StatefulSetFieldVolumes = "volumes" + StatefulSetFieldWindowsOptions = "windowsOptions" + StatefulSetFieldWorkloadAnnotations = "workloadAnnotations" + StatefulSetFieldWorkloadLabels = "workloadLabels" + StatefulSetFieldWorkloadMetrics = "workloadMetrics" +) + +type StatefulSet struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" yaml:"ordinals,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" yaml:"persistentVolumeClaimRetentionPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + StatefulSetConfig *StatefulSetConfig `json:"statefulSetConfig,omitempty" yaml:"statefulSetConfig,omitempty"` + StatefulSetStatus *StatefulSetStatus `json:"statefulSetStatus,omitempty" yaml:"statefulSetStatus,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type StatefulSetCollection struct { + types.Collection + Data []StatefulSet `json:"data,omitempty"` + client *StatefulSetClient +} + +type StatefulSetClient struct { + apiClient *Client +} + +type StatefulSetOperations interface { + List(opts *types.ListOpts) (*StatefulSetCollection, error) + ListAll(opts *types.ListOpts) (*StatefulSetCollection, error) + Create(opts *StatefulSet) (*StatefulSet, error) + Update(existing *StatefulSet, updates interface{}) (*StatefulSet, error) + Replace(existing *StatefulSet) (*StatefulSet, error) + ByID(id string) (*StatefulSet, error) + Delete(container *StatefulSet) error + + ActionRedeploy(resource *StatefulSet) error +} + +func newStatefulSetClient(apiClient *Client) *StatefulSetClient { + return &StatefulSetClient{ + apiClient: apiClient, + } +} + +func (c *StatefulSetClient) Create(container *StatefulSet) (*StatefulSet, error) { + resp := &StatefulSet{} + err := c.apiClient.Ops.DoCreate(StatefulSetType, container, resp) + return resp, err +} + +func (c *StatefulSetClient) Update(existing *StatefulSet, updates interface{}) (*StatefulSet, error) { + resp := &StatefulSet{} + err := c.apiClient.Ops.DoUpdate(StatefulSetType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *StatefulSetClient) Replace(obj *StatefulSet) (*StatefulSet, error) { + resp := &StatefulSet{} + err := c.apiClient.Ops.DoReplace(StatefulSetType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *StatefulSetClient) List(opts *types.ListOpts) (*StatefulSetCollection, error) { + resp := &StatefulSetCollection{} + err := c.apiClient.Ops.DoList(StatefulSetType, opts, resp) + resp.client = c + return resp, err +} + +func (c *StatefulSetClient) ListAll(opts *types.ListOpts) (*StatefulSetCollection, error) { + resp := &StatefulSetCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *StatefulSetCollection) Next() (*StatefulSetCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &StatefulSetCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *StatefulSetClient) ByID(id string) (*StatefulSet, error) { + resp := &StatefulSet{} + err := c.apiClient.Ops.DoByID(StatefulSetType, id, resp) + return resp, err +} + +func (c *StatefulSetClient) Delete(container *StatefulSet) error { + return c.apiClient.Ops.DoResourceDelete(StatefulSetType, &container.Resource) +} + +func (c *StatefulSetClient) ActionRedeploy(resource *StatefulSet) error { + err := c.apiClient.Ops.DoAction(StatefulSetType, "redeploy", &resource.Resource, nil, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_condition.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_condition.go new file mode 100644 index 0000000..6ff9b5e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_condition.go @@ -0,0 +1,18 @@ +package client + +const ( + StatefulSetConditionType = "statefulSetCondition" + StatefulSetConditionFieldLastTransitionTime = "lastTransitionTime" + StatefulSetConditionFieldMessage = "message" + StatefulSetConditionFieldReason = "reason" + StatefulSetConditionFieldStatus = "status" + StatefulSetConditionFieldType = "type" +) + +type StatefulSetCondition struct { + LastTransitionTime string `json:"lastTransitionTime,omitempty" yaml:"lastTransitionTime,omitempty"` + Message string `json:"message,omitempty" yaml:"message,omitempty"` + Reason string `json:"reason,omitempty" yaml:"reason,omitempty"` + Status string `json:"status,omitempty" yaml:"status,omitempty"` + Type string `json:"type,omitempty" yaml:"type,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_config.go new file mode 100644 index 0000000..0a46f97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_config.go @@ -0,0 +1,20 @@ +package client + +const ( + StatefulSetConfigType = "statefulSetConfig" + StatefulSetConfigFieldPartition = "partition" + StatefulSetConfigFieldPodManagementPolicy = "podManagementPolicy" + StatefulSetConfigFieldRevisionHistoryLimit = "revisionHistoryLimit" + StatefulSetConfigFieldServiceName = "serviceName" + StatefulSetConfigFieldStrategy = "strategy" + StatefulSetConfigFieldVolumeClaimTemplates = "volumeClaimTemplates" +) + +type StatefulSetConfig struct { + Partition *int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + PodManagementPolicy string `json:"podManagementPolicy,omitempty" yaml:"podManagementPolicy,omitempty"` + RevisionHistoryLimit *int64 `json:"revisionHistoryLimit,omitempty" yaml:"revisionHistoryLimit,omitempty"` + ServiceName string `json:"serviceName,omitempty" yaml:"serviceName,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` + VolumeClaimTemplates []PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty" yaml:"volumeClaimTemplates,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_ordinals.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_ordinals.go new file mode 100644 index 0000000..bb54d93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_ordinals.go @@ -0,0 +1,10 @@ +package client + +const ( + StatefulSetOrdinalsType = "statefulSetOrdinals" + StatefulSetOrdinalsFieldStart = "start" +) + +type StatefulSetOrdinals struct { + Start int64 `json:"start,omitempty" yaml:"start,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_persistent_volume_claim_retention_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_persistent_volume_claim_retention_policy.go new file mode 100644 index 0000000..79a76b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_persistent_volume_claim_retention_policy.go @@ -0,0 +1,12 @@ +package client + +const ( + StatefulSetPersistentVolumeClaimRetentionPolicyType = "statefulSetPersistentVolumeClaimRetentionPolicy" + StatefulSetPersistentVolumeClaimRetentionPolicyFieldWhenDeleted = "whenDeleted" + StatefulSetPersistentVolumeClaimRetentionPolicyFieldWhenScaled = "whenScaled" +) + +type StatefulSetPersistentVolumeClaimRetentionPolicy struct { + WhenDeleted string `json:"whenDeleted,omitempty" yaml:"whenDeleted,omitempty"` + WhenScaled string `json:"whenScaled,omitempty" yaml:"whenScaled,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_spec.go new file mode 100644 index 0000000..8dfe0ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_spec.go @@ -0,0 +1,110 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + StatefulSetSpecType = "statefulSetSpec" + StatefulSetSpecFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + StatefulSetSpecFieldAppArmorProfile = "appArmorProfile" + StatefulSetSpecFieldAutomountServiceAccountToken = "automountServiceAccountToken" + StatefulSetSpecFieldContainers = "containers" + StatefulSetSpecFieldDNSConfig = "dnsConfig" + StatefulSetSpecFieldDNSPolicy = "dnsPolicy" + StatefulSetSpecFieldEnableServiceLinks = "enableServiceLinks" + StatefulSetSpecFieldEphemeralContainers = "ephemeralContainers" + StatefulSetSpecFieldFSGroupChangePolicy = "fsGroupChangePolicy" + StatefulSetSpecFieldFsgid = "fsgid" + StatefulSetSpecFieldGids = "gids" + StatefulSetSpecFieldHostAliases = "hostAliases" + StatefulSetSpecFieldHostIPC = "hostIPC" + StatefulSetSpecFieldHostNetwork = "hostNetwork" + StatefulSetSpecFieldHostPID = "hostPID" + StatefulSetSpecFieldHostUsers = "hostUsers" + StatefulSetSpecFieldHostname = "hostname" + StatefulSetSpecFieldImagePullSecrets = "imagePullSecrets" + StatefulSetSpecFieldMaxUnavailable = "maxUnavailable" + StatefulSetSpecFieldMinReadySeconds = "minReadySeconds" + StatefulSetSpecFieldNodeID = "nodeId" + StatefulSetSpecFieldOS = "os" + StatefulSetSpecFieldObjectMeta = "metadata" + StatefulSetSpecFieldOrdinals = "ordinals" + StatefulSetSpecFieldOverhead = "overhead" + StatefulSetSpecFieldPersistentVolumeClaimRetentionPolicy = "persistentVolumeClaimRetentionPolicy" + StatefulSetSpecFieldPreemptionPolicy = "preemptionPolicy" + StatefulSetSpecFieldReadinessGates = "readinessGates" + StatefulSetSpecFieldResourceClaims = "resourceClaims" + StatefulSetSpecFieldRestartPolicy = "restartPolicy" + StatefulSetSpecFieldRunAsGroup = "runAsGroup" + StatefulSetSpecFieldRunAsNonRoot = "runAsNonRoot" + StatefulSetSpecFieldRuntimeClassName = "runtimeClassName" + StatefulSetSpecFieldScale = "scale" + StatefulSetSpecFieldScheduling = "scheduling" + StatefulSetSpecFieldSchedulingGates = "schedulingGates" + StatefulSetSpecFieldSeccompProfile = "seccompProfile" + StatefulSetSpecFieldSelector = "selector" + StatefulSetSpecFieldServiceAccountName = "serviceAccountName" + StatefulSetSpecFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + StatefulSetSpecFieldShareProcessNamespace = "shareProcessNamespace" + StatefulSetSpecFieldStatefulSetConfig = "statefulSetConfig" + StatefulSetSpecFieldSubdomain = "subdomain" + StatefulSetSpecFieldSysctls = "sysctls" + StatefulSetSpecFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + StatefulSetSpecFieldTopologySpreadConstraints = "topologySpreadConstraints" + StatefulSetSpecFieldUid = "uid" + StatefulSetSpecFieldVolumes = "volumes" + StatefulSetSpecFieldWindowsOptions = "windowsOptions" +) + +type StatefulSetSpec struct { + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + ObjectMeta *ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" yaml:"ordinals,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" yaml:"persistentVolumeClaimRetentionPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + StatefulSetConfig *StatefulSetConfig `json:"statefulSetConfig,omitempty" yaml:"statefulSetConfig,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_status.go new file mode 100644 index 0000000..e9779c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_status.go @@ -0,0 +1,28 @@ +package client + +const ( + StatefulSetStatusType = "statefulSetStatus" + StatefulSetStatusFieldAvailableReplicas = "availableReplicas" + StatefulSetStatusFieldCollisionCount = "collisionCount" + StatefulSetStatusFieldConditions = "conditions" + StatefulSetStatusFieldCurrentReplicas = "currentReplicas" + StatefulSetStatusFieldCurrentRevision = "currentRevision" + StatefulSetStatusFieldObservedGeneration = "observedGeneration" + StatefulSetStatusFieldReadyReplicas = "readyReplicas" + StatefulSetStatusFieldReplicas = "replicas" + StatefulSetStatusFieldUpdateRevision = "updateRevision" + StatefulSetStatusFieldUpdatedReplicas = "updatedReplicas" +) + +type StatefulSetStatus struct { + AvailableReplicas int64 `json:"availableReplicas,omitempty" yaml:"availableReplicas,omitempty"` + CollisionCount *int64 `json:"collisionCount,omitempty" yaml:"collisionCount,omitempty"` + Conditions []StatefulSetCondition `json:"conditions,omitempty" yaml:"conditions,omitempty"` + CurrentReplicas int64 `json:"currentReplicas,omitempty" yaml:"currentReplicas,omitempty"` + CurrentRevision string `json:"currentRevision,omitempty" yaml:"currentRevision,omitempty"` + ObservedGeneration int64 `json:"observedGeneration,omitempty" yaml:"observedGeneration,omitempty"` + ReadyReplicas int64 `json:"readyReplicas,omitempty" yaml:"readyReplicas,omitempty"` + Replicas int64 `json:"replicas,omitempty" yaml:"replicas,omitempty"` + UpdateRevision string `json:"updateRevision,omitempty" yaml:"updateRevision,omitempty"` + UpdatedReplicas int64 `json:"updatedReplicas,omitempty" yaml:"updatedReplicas,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_update_strategy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_update_strategy.go new file mode 100644 index 0000000..23cd99d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_stateful_set_update_strategy.go @@ -0,0 +1,18 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + StatefulSetUpdateStrategyType = "statefulSetUpdateStrategy" + StatefulSetUpdateStrategyFieldMaxUnavailable = "maxUnavailable" + StatefulSetUpdateStrategyFieldPartition = "partition" + StatefulSetUpdateStrategyFieldStrategy = "strategy" +) + +type StatefulSetUpdateStrategy struct { + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + Partition *int64 `json:"partition,omitempty" yaml:"partition,omitempty"` + Strategy string `json:"strategy,omitempty" yaml:"strategy,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_ospersistent_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_ospersistent_volume_source.go new file mode 100644 index 0000000..c1f741d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_ospersistent_volume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + StorageOSPersistentVolumeSourceType = "storageOSPersistentVolumeSource" + StorageOSPersistentVolumeSourceFieldFSType = "fsType" + StorageOSPersistentVolumeSourceFieldReadOnly = "readOnly" + StorageOSPersistentVolumeSourceFieldSecretRef = "secretRef" + StorageOSPersistentVolumeSourceFieldVolumeName = "volumeName" + StorageOSPersistentVolumeSourceFieldVolumeNamespace = "volumeNamespace" +) + +type StorageOSPersistentVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *ObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` + VolumeNamespace string `json:"volumeNamespace,omitempty" yaml:"volumeNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_osvolume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_osvolume_source.go new file mode 100644 index 0000000..46dc40f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_storage_osvolume_source.go @@ -0,0 +1,18 @@ +package client + +const ( + StorageOSVolumeSourceType = "storageOSVolumeSource" + StorageOSVolumeSourceFieldFSType = "fsType" + StorageOSVolumeSourceFieldReadOnly = "readOnly" + StorageOSVolumeSourceFieldSecretRef = "secretRef" + StorageOSVolumeSourceFieldVolumeName = "volumeName" + StorageOSVolumeSourceFieldVolumeNamespace = "volumeNamespace" +) + +type StorageOSVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + SecretRef *LocalObjectReference `json:"secretRef,omitempty" yaml:"secretRef,omitempty"` + VolumeName string `json:"volumeName,omitempty" yaml:"volumeName,omitempty"` + VolumeNamespace string `json:"volumeNamespace,omitempty" yaml:"volumeNamespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy.go new file mode 100644 index 0000000..5367576 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy.go @@ -0,0 +1,10 @@ +package client + +const ( + SuccessPolicyType = "successPolicy" + SuccessPolicyFieldRules = "rules" +) + +type SuccessPolicy struct { + Rules []SuccessPolicyRule `json:"rules,omitempty" yaml:"rules,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy_rule.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy_rule.go new file mode 100644 index 0000000..e5f0b16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_success_policy_rule.go @@ -0,0 +1,12 @@ +package client + +const ( + SuccessPolicyRuleType = "successPolicyRule" + SuccessPolicyRuleFieldSucceededCount = "succeededCount" + SuccessPolicyRuleFieldSucceededIndexes = "succeededIndexes" +) + +type SuccessPolicyRule struct { + SucceededCount *int64 `json:"succeededCount,omitempty" yaml:"succeededCount,omitempty"` + SucceededIndexes string `json:"succeededIndexes,omitempty" yaml:"succeededIndexes,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sysctl.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sysctl.go new file mode 100644 index 0000000..ff629d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_sysctl.go @@ -0,0 +1,12 @@ +package client + +const ( + SysctlType = "sysctl" + SysctlFieldName = "name" + SysctlFieldValue = "value" +) + +type Sysctl struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_tcp_socket_action.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_tcp_socket_action.go new file mode 100644 index 0000000..160c1f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_tcp_socket_action.go @@ -0,0 +1,16 @@ +package client + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + TCPSocketActionType = "tcpSocketAction" + TCPSocketActionFieldHost = "host" + TCPSocketActionFieldPort = "port" +) + +type TCPSocketAction struct { + Host string `json:"host,omitempty" yaml:"host,omitempty"` + Port intstr.IntOrString `json:"port,omitempty" yaml:"port,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_toleration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_toleration.go new file mode 100644 index 0000000..eabdd9d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_toleration.go @@ -0,0 +1,18 @@ +package client + +const ( + TolerationType = "toleration" + TolerationFieldEffect = "effect" + TolerationFieldKey = "key" + TolerationFieldOperator = "operator" + TolerationFieldTolerationSeconds = "tolerationSeconds" + TolerationFieldValue = "value" +) + +type Toleration struct { + Effect string `json:"effect,omitempty" yaml:"effect,omitempty"` + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Operator string `json:"operator,omitempty" yaml:"operator,omitempty"` + TolerationSeconds *int64 `json:"tolerationSeconds,omitempty" yaml:"tolerationSeconds,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_topology_spread_constraint.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_topology_spread_constraint.go new file mode 100644 index 0000000..94757ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_topology_spread_constraint.go @@ -0,0 +1,24 @@ +package client + +const ( + TopologySpreadConstraintType = "topologySpreadConstraint" + TopologySpreadConstraintFieldLabelSelector = "labelSelector" + TopologySpreadConstraintFieldMatchLabelKeys = "matchLabelKeys" + TopologySpreadConstraintFieldMaxSkew = "maxSkew" + TopologySpreadConstraintFieldMinDomains = "minDomains" + TopologySpreadConstraintFieldNodeAffinityPolicy = "nodeAffinityPolicy" + TopologySpreadConstraintFieldNodeTaintsPolicy = "nodeTaintsPolicy" + TopologySpreadConstraintFieldTopologyKey = "topologyKey" + TopologySpreadConstraintFieldWhenUnsatisfiable = "whenUnsatisfiable" +) + +type TopologySpreadConstraint struct { + LabelSelector *LabelSelector `json:"labelSelector,omitempty" yaml:"labelSelector,omitempty"` + MatchLabelKeys []string `json:"matchLabelKeys,omitempty" yaml:"matchLabelKeys,omitempty"` + MaxSkew int64 `json:"maxSkew,omitempty" yaml:"maxSkew,omitempty"` + MinDomains *int64 `json:"minDomains,omitempty" yaml:"minDomains,omitempty"` + NodeAffinityPolicy string `json:"nodeAffinityPolicy,omitempty" yaml:"nodeAffinityPolicy,omitempty"` + NodeTaintsPolicy string `json:"nodeTaintsPolicy,omitempty" yaml:"nodeTaintsPolicy,omitempty"` + TopologyKey string `json:"topologyKey,omitempty" yaml:"topologyKey,omitempty"` + WhenUnsatisfiable string `json:"whenUnsatisfiable,omitempty" yaml:"whenUnsatisfiable,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_local_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_local_object_reference.go new file mode 100644 index 0000000..0de2ebe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_local_object_reference.go @@ -0,0 +1,14 @@ +package client + +const ( + TypedLocalObjectReferenceType = "typedLocalObjectReference" + TypedLocalObjectReferenceFieldAPIGroup = "apiGroup" + TypedLocalObjectReferenceFieldKind = "kind" + TypedLocalObjectReferenceFieldName = "name" +) + +type TypedLocalObjectReference struct { + APIGroup string `json:"apiGroup,omitempty" yaml:"apiGroup,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_object_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_object_reference.go new file mode 100644 index 0000000..d60df80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_typed_object_reference.go @@ -0,0 +1,16 @@ +package client + +const ( + TypedObjectReferenceType = "typedObjectReference" + TypedObjectReferenceFieldAPIGroup = "apiGroup" + TypedObjectReferenceFieldKind = "kind" + TypedObjectReferenceFieldName = "name" + TypedObjectReferenceFieldNamespace = "namespace" +) + +type TypedObjectReference struct { + APIGroup string `json:"apiGroup,omitempty" yaml:"apiGroup,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_uncounted_terminated_pods.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_uncounted_terminated_pods.go new file mode 100644 index 0000000..b9d8ec8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_uncounted_terminated_pods.go @@ -0,0 +1,12 @@ +package client + +const ( + UncountedTerminatedPodsType = "uncountedTerminatedPods" + UncountedTerminatedPodsFieldFailed = "failed" + UncountedTerminatedPodsFieldSucceeded = "succeeded" +) + +type UncountedTerminatedPods struct { + Failed []string `json:"failed,omitempty" yaml:"failed,omitempty"` + Succeeded []string `json:"succeeded,omitempty" yaml:"succeeded,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume.go new file mode 100644 index 0000000..9f6c094 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume.go @@ -0,0 +1,68 @@ +package client + +const ( + VolumeType = "volume" + VolumeFieldAWSElasticBlockStore = "awsElasticBlockStore" + VolumeFieldAzureDisk = "azureDisk" + VolumeFieldAzureFile = "azureFile" + VolumeFieldCSI = "csi" + VolumeFieldCephFS = "cephfs" + VolumeFieldCinder = "cinder" + VolumeFieldConfigMap = "configMap" + VolumeFieldDownwardAPI = "downwardAPI" + VolumeFieldEmptyDir = "emptyDir" + VolumeFieldEphemeral = "ephemeral" + VolumeFieldFC = "fc" + VolumeFieldFlexVolume = "flexVolume" + VolumeFieldFlocker = "flocker" + VolumeFieldGCEPersistentDisk = "gcePersistentDisk" + VolumeFieldGitRepo = "gitRepo" + VolumeFieldGlusterfs = "glusterfs" + VolumeFieldHostPath = "hostPath" + VolumeFieldISCSI = "iscsi" + VolumeFieldNFS = "nfs" + VolumeFieldName = "name" + VolumeFieldPersistentVolumeClaim = "persistentVolumeClaim" + VolumeFieldPhotonPersistentDisk = "photonPersistentDisk" + VolumeFieldPortworxVolume = "portworxVolume" + VolumeFieldProjected = "projected" + VolumeFieldQuobyte = "quobyte" + VolumeFieldRBD = "rbd" + VolumeFieldScaleIO = "scaleIO" + VolumeFieldSecret = "secret" + VolumeFieldStorageOS = "storageos" + VolumeFieldVsphereVolume = "vsphereVolume" +) + +type Volume struct { + AWSElasticBlockStore *AWSElasticBlockStoreVolumeSource `json:"awsElasticBlockStore,omitempty" yaml:"awsElasticBlockStore,omitempty"` + AzureDisk *AzureDiskVolumeSource `json:"azureDisk,omitempty" yaml:"azureDisk,omitempty"` + AzureFile *AzureFileVolumeSource `json:"azureFile,omitempty" yaml:"azureFile,omitempty"` + CSI *CSIVolumeSource `json:"csi,omitempty" yaml:"csi,omitempty"` + CephFS *CephFSVolumeSource `json:"cephfs,omitempty" yaml:"cephfs,omitempty"` + Cinder *CinderVolumeSource `json:"cinder,omitempty" yaml:"cinder,omitempty"` + ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty" yaml:"configMap,omitempty"` + DownwardAPI *DownwardAPIVolumeSource `json:"downwardAPI,omitempty" yaml:"downwardAPI,omitempty"` + EmptyDir *EmptyDirVolumeSource `json:"emptyDir,omitempty" yaml:"emptyDir,omitempty"` + Ephemeral *EphemeralVolumeSource `json:"ephemeral,omitempty" yaml:"ephemeral,omitempty"` + FC *FCVolumeSource `json:"fc,omitempty" yaml:"fc,omitempty"` + FlexVolume *FlexVolumeSource `json:"flexVolume,omitempty" yaml:"flexVolume,omitempty"` + Flocker *FlockerVolumeSource `json:"flocker,omitempty" yaml:"flocker,omitempty"` + GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"gcePersistentDisk,omitempty" yaml:"gcePersistentDisk,omitempty"` + GitRepo *GitRepoVolumeSource `json:"gitRepo,omitempty" yaml:"gitRepo,omitempty"` + Glusterfs *GlusterfsVolumeSource `json:"glusterfs,omitempty" yaml:"glusterfs,omitempty"` + HostPath *HostPathVolumeSource `json:"hostPath,omitempty" yaml:"hostPath,omitempty"` + ISCSI *ISCSIVolumeSource `json:"iscsi,omitempty" yaml:"iscsi,omitempty"` + NFS *NFSVolumeSource `json:"nfs,omitempty" yaml:"nfs,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + PersistentVolumeClaim *PersistentVolumeClaimVolumeSource `json:"persistentVolumeClaim,omitempty" yaml:"persistentVolumeClaim,omitempty"` + PhotonPersistentDisk *PhotonPersistentDiskVolumeSource `json:"photonPersistentDisk,omitempty" yaml:"photonPersistentDisk,omitempty"` + PortworxVolume *PortworxVolumeSource `json:"portworxVolume,omitempty" yaml:"portworxVolume,omitempty"` + Projected *ProjectedVolumeSource `json:"projected,omitempty" yaml:"projected,omitempty"` + Quobyte *QuobyteVolumeSource `json:"quobyte,omitempty" yaml:"quobyte,omitempty"` + RBD *RBDVolumeSource `json:"rbd,omitempty" yaml:"rbd,omitempty"` + ScaleIO *ScaleIOVolumeSource `json:"scaleIO,omitempty" yaml:"scaleIO,omitempty"` + Secret *SecretVolumeSource `json:"secret,omitempty" yaml:"secret,omitempty"` + StorageOS *StorageOSVolumeSource `json:"storageos,omitempty" yaml:"storageos,omitempty"` + VsphereVolume *VsphereVirtualDiskVolumeSource `json:"vsphereVolume,omitempty" yaml:"vsphereVolume,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_device.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_device.go new file mode 100644 index 0000000..4fe2310 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_device.go @@ -0,0 +1,12 @@ +package client + +const ( + VolumeDeviceType = "volumeDevice" + VolumeDeviceFieldDevicePath = "devicePath" + VolumeDeviceFieldName = "name" +) + +type VolumeDevice struct { + DevicePath string `json:"devicePath,omitempty" yaml:"devicePath,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount.go new file mode 100644 index 0000000..1c24eb9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount.go @@ -0,0 +1,22 @@ +package client + +const ( + VolumeMountType = "volumeMount" + VolumeMountFieldMountPath = "mountPath" + VolumeMountFieldMountPropagation = "mountPropagation" + VolumeMountFieldName = "name" + VolumeMountFieldReadOnly = "readOnly" + VolumeMountFieldRecursiveReadOnly = "recursiveReadOnly" + VolumeMountFieldSubPath = "subPath" + VolumeMountFieldSubPathExpr = "subPathExpr" +) + +type VolumeMount struct { + MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"` + MountPropagation string `json:"mountPropagation,omitempty" yaml:"mountPropagation,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + RecursiveReadOnly string `json:"recursiveReadOnly,omitempty" yaml:"recursiveReadOnly,omitempty"` + SubPath string `json:"subPath,omitempty" yaml:"subPath,omitempty"` + SubPathExpr string `json:"subPathExpr,omitempty" yaml:"subPathExpr,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount_status.go new file mode 100644 index 0000000..f3ec3e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_mount_status.go @@ -0,0 +1,16 @@ +package client + +const ( + VolumeMountStatusType = "volumeMountStatus" + VolumeMountStatusFieldMountPath = "mountPath" + VolumeMountStatusFieldName = "name" + VolumeMountStatusFieldReadOnly = "readOnly" + VolumeMountStatusFieldRecursiveReadOnly = "recursiveReadOnly" +) + +type VolumeMountStatus struct { + MountPath string `json:"mountPath,omitempty" yaml:"mountPath,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + ReadOnly bool `json:"readOnly,omitempty" yaml:"readOnly,omitempty"` + RecursiveReadOnly string `json:"recursiveReadOnly,omitempty" yaml:"recursiveReadOnly,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_node_affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_node_affinity.go new file mode 100644 index 0000000..e025eb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_node_affinity.go @@ -0,0 +1,10 @@ +package client + +const ( + VolumeNodeAffinityType = "volumeNodeAffinity" + VolumeNodeAffinityFieldRequired = "required" +) + +type VolumeNodeAffinity struct { + Required *NodeSelector `json:"required,omitempty" yaml:"required,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_projection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_projection.go new file mode 100644 index 0000000..d67ed14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_projection.go @@ -0,0 +1,18 @@ +package client + +const ( + VolumeProjectionType = "volumeProjection" + VolumeProjectionFieldClusterTrustBundle = "clusterTrustBundle" + VolumeProjectionFieldConfigMap = "configMap" + VolumeProjectionFieldDownwardAPI = "downwardAPI" + VolumeProjectionFieldSecret = "secret" + VolumeProjectionFieldServiceAccountToken = "serviceAccountToken" +) + +type VolumeProjection struct { + ClusterTrustBundle *ClusterTrustBundleProjection `json:"clusterTrustBundle,omitempty" yaml:"clusterTrustBundle,omitempty"` + ConfigMap *ConfigMapProjection `json:"configMap,omitempty" yaml:"configMap,omitempty"` + DownwardAPI *DownwardAPIProjection `json:"downwardAPI,omitempty" yaml:"downwardAPI,omitempty"` + Secret *SecretProjection `json:"secret,omitempty" yaml:"secret,omitempty"` + ServiceAccountToken *ServiceAccountTokenProjection `json:"serviceAccountToken,omitempty" yaml:"serviceAccountToken,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_resource_requirements.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_resource_requirements.go new file mode 100644 index 0000000..780368b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_volume_resource_requirements.go @@ -0,0 +1,12 @@ +package client + +const ( + VolumeResourceRequirementsType = "volumeResourceRequirements" + VolumeResourceRequirementsFieldLimits = "limits" + VolumeResourceRequirementsFieldRequests = "requests" +) + +type VolumeResourceRequirements struct { + Limits map[string]string `json:"limits,omitempty" yaml:"limits,omitempty"` + Requests map[string]string `json:"requests,omitempty" yaml:"requests,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_vsphere_virtual_disk_volume_source.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_vsphere_virtual_disk_volume_source.go new file mode 100644 index 0000000..ed671ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_vsphere_virtual_disk_volume_source.go @@ -0,0 +1,16 @@ +package client + +const ( + VsphereVirtualDiskVolumeSourceType = "vsphereVirtualDiskVolumeSource" + VsphereVirtualDiskVolumeSourceFieldFSType = "fsType" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyID = "storagePolicyID" + VsphereVirtualDiskVolumeSourceFieldStoragePolicyName = "storagePolicyName" + VsphereVirtualDiskVolumeSourceFieldVolumePath = "volumePath" +) + +type VsphereVirtualDiskVolumeSource struct { + FSType string `json:"fsType,omitempty" yaml:"fsType,omitempty"` + StoragePolicyID string `json:"storagePolicyID,omitempty" yaml:"storagePolicyID,omitempty"` + StoragePolicyName string `json:"storagePolicyName,omitempty" yaml:"storagePolicyName,omitempty"` + VolumePath string `json:"volumePath,omitempty" yaml:"volumePath,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_weighted_pod_affinity_term.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_weighted_pod_affinity_term.go new file mode 100644 index 0000000..a046f5a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_weighted_pod_affinity_term.go @@ -0,0 +1,12 @@ +package client + +const ( + WeightedPodAffinityTermType = "weightedPodAffinityTerm" + WeightedPodAffinityTermFieldPodAffinityTerm = "podAffinityTerm" + WeightedPodAffinityTermFieldWeight = "weight" +) + +type WeightedPodAffinityTerm struct { + PodAffinityTerm *PodAffinityTerm `json:"podAffinityTerm,omitempty" yaml:"podAffinityTerm,omitempty"` + Weight int64 `json:"weight,omitempty" yaml:"weight,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_windows_security_context_options.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_windows_security_context_options.go new file mode 100644 index 0000000..5056e9c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_windows_security_context_options.go @@ -0,0 +1,16 @@ +package client + +const ( + WindowsSecurityContextOptionsType = "windowsSecurityContextOptions" + WindowsSecurityContextOptionsFieldGMSACredentialSpec = "gmsaCredentialSpec" + WindowsSecurityContextOptionsFieldGMSACredentialSpecName = "gmsaCredentialSpecName" + WindowsSecurityContextOptionsFieldHostProcess = "hostProcess" + WindowsSecurityContextOptionsFieldRunAsUserName = "runAsUserName" +) + +type WindowsSecurityContextOptions struct { + GMSACredentialSpec string `json:"gmsaCredentialSpec,omitempty" yaml:"gmsaCredentialSpec,omitempty"` + GMSACredentialSpecName string `json:"gmsaCredentialSpecName,omitempty" yaml:"gmsaCredentialSpecName,omitempty"` + HostProcess *bool `json:"hostProcess,omitempty" yaml:"hostProcess,omitempty"` + RunAsUserName string `json:"runAsUserName,omitempty" yaml:"runAsUserName,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload.go new file mode 100644 index 0000000..07b7423 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload.go @@ -0,0 +1,312 @@ +package client + +import ( + "github.com/rancher/norman/types" + + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + WorkloadType = "workload" + WorkloadFieldActiveDeadlineSeconds = "activeDeadlineSeconds" + WorkloadFieldAnnotations = "annotations" + WorkloadFieldAppArmorProfile = "appArmorProfile" + WorkloadFieldAutomountServiceAccountToken = "automountServiceAccountToken" + WorkloadFieldBackoffLimitPerIndex = "backoffLimitPerIndex" + WorkloadFieldCompletionMode = "completionMode" + WorkloadFieldContainers = "containers" + WorkloadFieldCreated = "created" + WorkloadFieldCreatorID = "creatorId" + WorkloadFieldCronJobConfig = "cronJobConfig" + WorkloadFieldCronJobStatus = "cronJobStatus" + WorkloadFieldDNSConfig = "dnsConfig" + WorkloadFieldDNSPolicy = "dnsPolicy" + WorkloadFieldDaemonSetConfig = "daemonSetConfig" + WorkloadFieldDaemonSetStatus = "daemonSetStatus" + WorkloadFieldDeploymentConfig = "deploymentConfig" + WorkloadFieldDeploymentStatus = "deploymentStatus" + WorkloadFieldEnableServiceLinks = "enableServiceLinks" + WorkloadFieldEphemeralContainers = "ephemeralContainers" + WorkloadFieldFSGroupChangePolicy = "fsGroupChangePolicy" + WorkloadFieldFsgid = "fsgid" + WorkloadFieldGids = "gids" + WorkloadFieldHostAliases = "hostAliases" + WorkloadFieldHostIPC = "hostIPC" + WorkloadFieldHostNetwork = "hostNetwork" + WorkloadFieldHostPID = "hostPID" + WorkloadFieldHostUsers = "hostUsers" + WorkloadFieldHostname = "hostname" + WorkloadFieldImagePullSecrets = "imagePullSecrets" + WorkloadFieldJobConfig = "jobConfig" + WorkloadFieldJobStatus = "jobStatus" + WorkloadFieldLabels = "labels" + WorkloadFieldManagedBy = "managedBy" + WorkloadFieldMaxFailedIndexes = "maxFailedIndexes" + WorkloadFieldMaxSurge = "maxSurge" + WorkloadFieldMaxUnavailable = "maxUnavailable" + WorkloadFieldMinReadySeconds = "minReadySeconds" + WorkloadFieldName = "name" + WorkloadFieldNamespaceId = "namespaceId" + WorkloadFieldNodeID = "nodeId" + WorkloadFieldOS = "os" + WorkloadFieldOrdinals = "ordinals" + WorkloadFieldOverhead = "overhead" + WorkloadFieldOwnerReferences = "ownerReferences" + WorkloadFieldPaused = "paused" + WorkloadFieldPersistentVolumeClaimRetentionPolicy = "persistentVolumeClaimRetentionPolicy" + WorkloadFieldPodFailurePolicy = "podFailurePolicy" + WorkloadFieldPodReplacementPolicy = "podReplacementPolicy" + WorkloadFieldPreemptionPolicy = "preemptionPolicy" + WorkloadFieldProjectID = "projectId" + WorkloadFieldPublicEndpoints = "publicEndpoints" + WorkloadFieldReadinessGates = "readinessGates" + WorkloadFieldRemoved = "removed" + WorkloadFieldReplicaSetConfig = "replicaSetConfig" + WorkloadFieldReplicaSetStatus = "replicaSetStatus" + WorkloadFieldReplicationControllerConfig = "replicationControllerConfig" + WorkloadFieldReplicationControllerStatus = "replicationControllerStatus" + WorkloadFieldResourceClaims = "resourceClaims" + WorkloadFieldRestartPolicy = "restartPolicy" + WorkloadFieldRunAsGroup = "runAsGroup" + WorkloadFieldRunAsNonRoot = "runAsNonRoot" + WorkloadFieldRuntimeClassName = "runtimeClassName" + WorkloadFieldScale = "scale" + WorkloadFieldScheduling = "scheduling" + WorkloadFieldSchedulingGates = "schedulingGates" + WorkloadFieldSeccompProfile = "seccompProfile" + WorkloadFieldSelector = "selector" + WorkloadFieldServiceAccountName = "serviceAccountName" + WorkloadFieldSetHostnameAsFQDN = "setHostnameAsFQDN" + WorkloadFieldShareProcessNamespace = "shareProcessNamespace" + WorkloadFieldState = "state" + WorkloadFieldStatefulSetConfig = "statefulSetConfig" + WorkloadFieldStatefulSetStatus = "statefulSetStatus" + WorkloadFieldSubdomain = "subdomain" + WorkloadFieldSuccessPolicy = "successPolicy" + WorkloadFieldSuspend = "suspend" + WorkloadFieldSysctls = "sysctls" + WorkloadFieldTTLSecondsAfterFinished = "ttlSecondsAfterFinished" + WorkloadFieldTerminationGracePeriodSeconds = "terminationGracePeriodSeconds" + WorkloadFieldTimeZone = "timeZone" + WorkloadFieldTopologySpreadConstraints = "topologySpreadConstraints" + WorkloadFieldTransitioning = "transitioning" + WorkloadFieldTransitioningMessage = "transitioningMessage" + WorkloadFieldUUID = "uuid" + WorkloadFieldUid = "uid" + WorkloadFieldVolumes = "volumes" + WorkloadFieldWindowsOptions = "windowsOptions" + WorkloadFieldWorkloadAnnotations = "workloadAnnotations" + WorkloadFieldWorkloadLabels = "workloadLabels" + WorkloadFieldWorkloadMetrics = "workloadMetrics" +) + +type Workload struct { + types.Resource + ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty" yaml:"activeDeadlineSeconds,omitempty"` + Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` + AppArmorProfile *AppArmorProfile `json:"appArmorProfile,omitempty" yaml:"appArmorProfile,omitempty"` + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty" yaml:"automountServiceAccountToken,omitempty"` + BackoffLimitPerIndex *int64 `json:"backoffLimitPerIndex,omitempty" yaml:"backoffLimitPerIndex,omitempty"` + CompletionMode string `json:"completionMode,omitempty" yaml:"completionMode,omitempty"` + Containers []Container `json:"containers,omitempty" yaml:"containers,omitempty"` + Created string `json:"created,omitempty" yaml:"created,omitempty"` + CreatorID string `json:"creatorId,omitempty" yaml:"creatorId,omitempty"` + CronJobConfig *CronJobConfig `json:"cronJobConfig,omitempty" yaml:"cronJobConfig,omitempty"` + CronJobStatus *CronJobStatus `json:"cronJobStatus,omitempty" yaml:"cronJobStatus,omitempty"` + DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty" yaml:"dnsConfig,omitempty"` + DNSPolicy string `json:"dnsPolicy,omitempty" yaml:"dnsPolicy,omitempty"` + DaemonSetConfig *DaemonSetConfig `json:"daemonSetConfig,omitempty" yaml:"daemonSetConfig,omitempty"` + DaemonSetStatus *DaemonSetStatus `json:"daemonSetStatus,omitempty" yaml:"daemonSetStatus,omitempty"` + DeploymentConfig *DeploymentConfig `json:"deploymentConfig,omitempty" yaml:"deploymentConfig,omitempty"` + DeploymentStatus *DeploymentStatus `json:"deploymentStatus,omitempty" yaml:"deploymentStatus,omitempty"` + EnableServiceLinks *bool `json:"enableServiceLinks,omitempty" yaml:"enableServiceLinks,omitempty"` + EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty" yaml:"ephemeralContainers,omitempty"` + FSGroupChangePolicy string `json:"fsGroupChangePolicy,omitempty" yaml:"fsGroupChangePolicy,omitempty"` + Fsgid *int64 `json:"fsgid,omitempty" yaml:"fsgid,omitempty"` + Gids []int64 `json:"gids,omitempty" yaml:"gids,omitempty"` + HostAliases []HostAlias `json:"hostAliases,omitempty" yaml:"hostAliases,omitempty"` + HostIPC bool `json:"hostIPC,omitempty" yaml:"hostIPC,omitempty"` + HostNetwork bool `json:"hostNetwork,omitempty" yaml:"hostNetwork,omitempty"` + HostPID bool `json:"hostPID,omitempty" yaml:"hostPID,omitempty"` + HostUsers *bool `json:"hostUsers,omitempty" yaml:"hostUsers,omitempty"` + Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"` + ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"` + JobConfig *JobConfig `json:"jobConfig,omitempty" yaml:"jobConfig,omitempty"` + JobStatus *JobStatus `json:"jobStatus,omitempty" yaml:"jobStatus,omitempty"` + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` + ManagedBy string `json:"managedBy,omitempty" yaml:"managedBy,omitempty"` + MaxFailedIndexes *int64 `json:"maxFailedIndexes,omitempty" yaml:"maxFailedIndexes,omitempty"` + MaxSurge intstr.IntOrString `json:"maxSurge,omitempty" yaml:"maxSurge,omitempty"` + MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty" yaml:"maxUnavailable,omitempty"` + MinReadySeconds int64 `json:"minReadySeconds,omitempty" yaml:"minReadySeconds,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + NamespaceId string `json:"namespaceId,omitempty" yaml:"namespaceId,omitempty"` + NodeID string `json:"nodeId,omitempty" yaml:"nodeId,omitempty"` + OS *PodOS `json:"os,omitempty" yaml:"os,omitempty"` + Ordinals *StatefulSetOrdinals `json:"ordinals,omitempty" yaml:"ordinals,omitempty"` + Overhead map[string]string `json:"overhead,omitempty" yaml:"overhead,omitempty"` + OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" yaml:"ownerReferences,omitempty"` + Paused bool `json:"paused,omitempty" yaml:"paused,omitempty"` + PersistentVolumeClaimRetentionPolicy *StatefulSetPersistentVolumeClaimRetentionPolicy `json:"persistentVolumeClaimRetentionPolicy,omitempty" yaml:"persistentVolumeClaimRetentionPolicy,omitempty"` + PodFailurePolicy *PodFailurePolicy `json:"podFailurePolicy,omitempty" yaml:"podFailurePolicy,omitempty"` + PodReplacementPolicy string `json:"podReplacementPolicy,omitempty" yaml:"podReplacementPolicy,omitempty"` + PreemptionPolicy string `json:"preemptionPolicy,omitempty" yaml:"preemptionPolicy,omitempty"` + ProjectID string `json:"projectId,omitempty" yaml:"projectId,omitempty"` + PublicEndpoints []PublicEndpoint `json:"publicEndpoints,omitempty" yaml:"publicEndpoints,omitempty"` + ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty" yaml:"readinessGates,omitempty"` + Removed string `json:"removed,omitempty" yaml:"removed,omitempty"` + ReplicaSetConfig *ReplicaSetConfig `json:"replicaSetConfig,omitempty" yaml:"replicaSetConfig,omitempty"` + ReplicaSetStatus *ReplicaSetStatus `json:"replicaSetStatus,omitempty" yaml:"replicaSetStatus,omitempty"` + ReplicationControllerConfig *ReplicationControllerConfig `json:"replicationControllerConfig,omitempty" yaml:"replicationControllerConfig,omitempty"` + ReplicationControllerStatus *ReplicationControllerStatus `json:"replicationControllerStatus,omitempty" yaml:"replicationControllerStatus,omitempty"` + ResourceClaims []PodResourceClaim `json:"resourceClaims,omitempty" yaml:"resourceClaims,omitempty"` + RestartPolicy string `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"` + RunAsGroup *int64 `json:"runAsGroup,omitempty" yaml:"runAsGroup,omitempty"` + RunAsNonRoot *bool `json:"runAsNonRoot,omitempty" yaml:"runAsNonRoot,omitempty"` + RuntimeClassName string `json:"runtimeClassName,omitempty" yaml:"runtimeClassName,omitempty"` + Scale *int64 `json:"scale,omitempty" yaml:"scale,omitempty"` + Scheduling *Scheduling `json:"scheduling,omitempty" yaml:"scheduling,omitempty"` + SchedulingGates []PodSchedulingGate `json:"schedulingGates,omitempty" yaml:"schedulingGates,omitempty"` + SeccompProfile *SeccompProfile `json:"seccompProfile,omitempty" yaml:"seccompProfile,omitempty"` + Selector *LabelSelector `json:"selector,omitempty" yaml:"selector,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty" yaml:"serviceAccountName,omitempty"` + SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty" yaml:"setHostnameAsFQDN,omitempty"` + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" yaml:"shareProcessNamespace,omitempty"` + State string `json:"state,omitempty" yaml:"state,omitempty"` + StatefulSetConfig *StatefulSetConfig `json:"statefulSetConfig,omitempty" yaml:"statefulSetConfig,omitempty"` + StatefulSetStatus *StatefulSetStatus `json:"statefulSetStatus,omitempty" yaml:"statefulSetStatus,omitempty"` + Subdomain string `json:"subdomain,omitempty" yaml:"subdomain,omitempty"` + SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" yaml:"successPolicy,omitempty"` + Suspend *bool `json:"suspend,omitempty" yaml:"suspend,omitempty"` + Sysctls []Sysctl `json:"sysctls,omitempty" yaml:"sysctls,omitempty"` + TTLSecondsAfterFinished *int64 `json:"ttlSecondsAfterFinished,omitempty" yaml:"ttlSecondsAfterFinished,omitempty"` + TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" yaml:"terminationGracePeriodSeconds,omitempty"` + TimeZone string `json:"timeZone,omitempty" yaml:"timeZone,omitempty"` + TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" yaml:"topologySpreadConstraints,omitempty"` + Transitioning string `json:"transitioning,omitempty" yaml:"transitioning,omitempty"` + TransitioningMessage string `json:"transitioningMessage,omitempty" yaml:"transitioningMessage,omitempty"` + UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"` + Uid *int64 `json:"uid,omitempty" yaml:"uid,omitempty"` + Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"` + WindowsOptions *WindowsSecurityContextOptions `json:"windowsOptions,omitempty" yaml:"windowsOptions,omitempty"` + WorkloadAnnotations map[string]string `json:"workloadAnnotations,omitempty" yaml:"workloadAnnotations,omitempty"` + WorkloadLabels map[string]string `json:"workloadLabels,omitempty" yaml:"workloadLabels,omitempty"` + WorkloadMetrics []WorkloadMetric `json:"workloadMetrics,omitempty" yaml:"workloadMetrics,omitempty"` +} + +type WorkloadCollection struct { + types.Collection + Data []Workload `json:"data,omitempty"` + client *WorkloadClient +} + +type WorkloadClient struct { + apiClient *Client +} + +type WorkloadOperations interface { + List(opts *types.ListOpts) (*WorkloadCollection, error) + ListAll(opts *types.ListOpts) (*WorkloadCollection, error) + Create(opts *Workload) (*Workload, error) + Update(existing *Workload, updates interface{}) (*Workload, error) + Replace(existing *Workload) (*Workload, error) + ByID(id string) (*Workload, error) + Delete(container *Workload) error + + ActionPause(resource *Workload) error + + ActionRedeploy(resource *Workload) error + + ActionResume(resource *Workload) error + + ActionRollback(resource *Workload, input *RollbackRevision) error +} + +func newWorkloadClient(apiClient *Client) *WorkloadClient { + return &WorkloadClient{ + apiClient: apiClient, + } +} + +func (c *WorkloadClient) Create(container *Workload) (*Workload, error) { + resp := &Workload{} + err := c.apiClient.Ops.DoCreate(WorkloadType, container, resp) + return resp, err +} + +func (c *WorkloadClient) Update(existing *Workload, updates interface{}) (*Workload, error) { + resp := &Workload{} + err := c.apiClient.Ops.DoUpdate(WorkloadType, &existing.Resource, updates, resp) + return resp, err +} + +func (c *WorkloadClient) Replace(obj *Workload) (*Workload, error) { + resp := &Workload{} + err := c.apiClient.Ops.DoReplace(WorkloadType, &obj.Resource, obj, resp) + return resp, err +} + +func (c *WorkloadClient) List(opts *types.ListOpts) (*WorkloadCollection, error) { + resp := &WorkloadCollection{} + err := c.apiClient.Ops.DoList(WorkloadType, opts, resp) + resp.client = c + return resp, err +} + +func (c *WorkloadClient) ListAll(opts *types.ListOpts) (*WorkloadCollection, error) { + resp := &WorkloadCollection{} + resp, err := c.List(opts) + if err != nil { + return resp, err + } + data := resp.Data + for next, err := resp.Next(); next != nil && err == nil; next, err = next.Next() { + data = append(data, next.Data...) + resp = next + resp.Data = data + } + if err != nil { + return resp, err + } + return resp, err +} + +func (cc *WorkloadCollection) Next() (*WorkloadCollection, error) { + if cc != nil && cc.Pagination != nil && cc.Pagination.Next != "" { + resp := &WorkloadCollection{} + err := cc.client.apiClient.Ops.DoNext(cc.Pagination.Next, resp) + resp.client = cc.client + return resp, err + } + return nil, nil +} + +func (c *WorkloadClient) ByID(id string) (*Workload, error) { + resp := &Workload{} + err := c.apiClient.Ops.DoByID(WorkloadType, id, resp) + return resp, err +} + +func (c *WorkloadClient) Delete(container *Workload) error { + return c.apiClient.Ops.DoResourceDelete(WorkloadType, &container.Resource) +} + +func (c *WorkloadClient) ActionPause(resource *Workload) error { + err := c.apiClient.Ops.DoAction(WorkloadType, "pause", &resource.Resource, nil, nil) + return err +} + +func (c *WorkloadClient) ActionRedeploy(resource *Workload) error { + err := c.apiClient.Ops.DoAction(WorkloadType, "redeploy", &resource.Resource, nil, nil) + return err +} + +func (c *WorkloadClient) ActionResume(resource *Workload) error { + err := c.apiClient.Ops.DoAction(WorkloadType, "resume", &resource.Resource, nil, nil) + return err +} + +func (c *WorkloadClient) ActionRollback(resource *Workload, input *RollbackRevision) error { + err := c.apiClient.Ops.DoAction(WorkloadType, "rollback", &resource.Resource, input, nil) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload_metric.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload_metric.go new file mode 100644 index 0000000..7388864 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/generated/project/v3/zz_generated_workload_metric.go @@ -0,0 +1,14 @@ +package client + +const ( + WorkloadMetricType = "workloadMetric" + WorkloadMetricFieldPath = "path" + WorkloadMetricFieldPort = "port" + WorkloadMetricFieldSchema = "schema" +) + +type WorkloadMetric struct { + Path string `json:"path,omitempty" yaml:"path,omitempty"` + Port int64 `json:"port,omitempty" yaml:"port,omitempty"` + Schema string `json:"schema,omitempty" yaml:"schema,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.mod b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.mod new file mode 100644 index 0000000..30fada4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.mod @@ -0,0 +1,26 @@ +module github.com/rancher/rancher/pkg/client + +go 1.22.0 + +toolchain go1.22.3 + +require ( + github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 + k8s.io/apimachinery v0.30.1 +) + +require ( + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rancher/wrangler/v3 v3.0.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.sum b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.sum new file mode 100644 index 0000000..41ddd5a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/client/go.sum @@ -0,0 +1,76 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 h1:AlRMRs5mHJcdiK83KKJyFVeybPMZ7dOUzC0l3k9aUa8= +github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9/go.mod h1:dyjfXBsNiroPWOdUZe7diUOUSLf6HQ/r2kEpwH/8zas= +github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA= +github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization.go new file mode 100644 index 0000000..f9b9ef1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization.go @@ -0,0 +1,88 @@ +package cluster + +import ( + "encoding/json" + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + corev1 "k8s.io/api/core/v1" +) + +// GetClusterAgentTolerations returns additional tolerations for the cluster agent if they have been user defined. If +// not, nil is returned. +func GetClusterAgentTolerations(cluster *v3.Cluster) []corev1.Toleration { + if cluster.Spec.ClusterAgentDeploymentCustomization != nil && + cluster.Spec.ClusterAgentDeploymentCustomization.AppendTolerations != nil { + return cluster.Spec.ClusterAgentDeploymentCustomization.AppendTolerations + } + + return nil +} + +// GetClusterAgentAffinity returns node affinity for the cluster agent if it has been user defined. If not, then the +// default affinity is returned. +func GetClusterAgentAffinity(cluster *v3.Cluster) (*corev1.Affinity, error) { + if cluster.Spec.ClusterAgentDeploymentCustomization != nil && + cluster.Spec.ClusterAgentDeploymentCustomization.OverrideAffinity != nil { + return cluster.Spec.ClusterAgentDeploymentCustomization.OverrideAffinity, nil + } + + return unmarshalAffinity(settings.ClusterAgentDefaultAffinity.Get()) +} + +// GetClusterAgentResourceRequirements returns resource requirements (cpu, memory) for the cluster agent if it has been +// user defined. If not, nil is returned. +func GetClusterAgentResourceRequirements(cluster *v3.Cluster) *corev1.ResourceRequirements { + if cluster.Spec.ClusterAgentDeploymentCustomization != nil && + cluster.Spec.ClusterAgentDeploymentCustomization.OverrideResourceRequirements != nil { + return cluster.Spec.ClusterAgentDeploymentCustomization.OverrideResourceRequirements + } + + return nil +} + +// GetFleetAgentTolerations returns additional tolerations for the fleet agent if it has been user defined. If not, +// then nil is returned. +func GetFleetAgentTolerations(cluster *v3.Cluster) []corev1.Toleration { + if cluster.Spec.FleetAgentDeploymentCustomization != nil && + cluster.Spec.FleetAgentDeploymentCustomization.AppendTolerations != nil { + return cluster.Spec.FleetAgentDeploymentCustomization.AppendTolerations + } + + return nil +} + +// GetFleetAgentAffinity returns node affinity for the fleet agent if it has been user defined. If not, then the +// default affinity is returned. +func GetFleetAgentAffinity(cluster *v3.Cluster) (*corev1.Affinity, error) { + if cluster.Spec.FleetAgentDeploymentCustomization != nil && + cluster.Spec.FleetAgentDeploymentCustomization.OverrideAffinity != nil { + return cluster.Spec.FleetAgentDeploymentCustomization.OverrideAffinity, nil + } + + return unmarshalAffinity(settings.FleetAgentDefaultAffinity.Get()) +} + +// GetFleetAgentResourceRequirements returns resource requirements (cpu, memory) for the fleet agent if it has been +// user defined. If not, nil is returned. +func GetFleetAgentResourceRequirements(cluster *v3.Cluster) *corev1.ResourceRequirements { + if cluster.Spec.FleetAgentDeploymentCustomization != nil && + cluster.Spec.FleetAgentDeploymentCustomization.OverrideResourceRequirements != nil { + return cluster.Spec.FleetAgentDeploymentCustomization.OverrideResourceRequirements + } + + return nil +} + +// unmarshalAffinity returns an unmarshalled object of the v1 node affinity. If unable to be unmarshalled, it returns +// nil and an error. +func unmarshalAffinity(affinity string) (*corev1.Affinity, error) { + var affinityObj corev1.Affinity + err := json.Unmarshal([]byte(affinity), &affinityObj) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal node affinity: %w", err) + } + + return &affinityObj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization_test.go new file mode 100644 index 0000000..49d5386 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/agent_customization_test.go @@ -0,0 +1,201 @@ +package cluster + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestAgentCustomization_getAgentCustomization(t *testing.T) { + testClusterAgentToleration := []corev1.Toleration{{ + Effect: "NoSchedule", + Key: "node-role.kubernetes.io/controlplane-test", + Value: "true", + }, + } + testClusterAgentAffinity := &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "cattle.io/cluster-agent-test", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } + testClusterAgentResourceReq := &corev1.ResourceRequirements{ + Limits: map[corev1.ResourceName]resource.Quantity{ + "cpu": *resource.NewQuantity(500, resource.DecimalSI), + "memory": *resource.NewQuantity(250, resource.DecimalSI), + }, + Requests: map[corev1.ResourceName]resource.Quantity{ + "cpu": *resource.NewQuantity(500, resource.DecimalSI), + "memory": *resource.NewQuantity(250, resource.DecimalSI), + }, + } + + testFleetAgentToleration := []corev1.Toleration{ + { + Key: "key", + Operator: corev1.TolerationOpEqual, + Value: "value", + }, + } + testFleetAgentAffinity := &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "fleet.cattle.io/agent", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } + testFleetAgentResourceReq := &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + } + + tests := []struct { + name string + cluster *v3.Cluster + }{ + { + name: "test-default", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-default", + }, + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{}, + }, + }, + }, + { + name: "test-agent-customization", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-agent-customization", + }, + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + ClusterAgentDeploymentCustomization: &v3.AgentDeploymentCustomization{ + AppendTolerations: testClusterAgentToleration, + OverrideAffinity: testClusterAgentAffinity, + OverrideResourceRequirements: testClusterAgentResourceReq, + }, + FleetAgentDeploymentCustomization: &v3.AgentDeploymentCustomization{ + AppendTolerations: testFleetAgentToleration, + OverrideAffinity: testFleetAgentAffinity, + OverrideResourceRequirements: testFleetAgentResourceReq, + }, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clusterAgentToleration := GetClusterAgentTolerations(tt.cluster) + clusterAgentAffinity, clusterErr := GetClusterAgentAffinity(tt.cluster) + clusterAgentResourceRequirements := GetClusterAgentResourceRequirements(tt.cluster) + + fleetAgentToleration := GetFleetAgentTolerations(tt.cluster) + fleetAgentAffinity, fleetErr := GetFleetAgentAffinity(tt.cluster) + fleetAgentResourceRequirements := GetFleetAgentResourceRequirements(tt.cluster) + + switch tt.name { + case "test-default": + // cluster agent + assert.Nil(t, clusterAgentToleration) + defaultClusterAgentAffinity, err := unmarshalAffinity(settings.ClusterAgentDefaultAffinity.Get()) + if err != nil { + assert.FailNow(t, "failed to unmarshal node affinity: %w", err) + } + assert.Equal(t, defaultClusterAgentAffinity, clusterAgentAffinity) + assert.Nil(t, clusterErr) + assert.Nil(t, clusterAgentResourceRequirements) + + // fleet agent + assert.Nil(t, fleetAgentToleration) + defaultFleetAgentAffinity, err := unmarshalAffinity(settings.FleetAgentDefaultAffinity.Get()) + if err != nil { + assert.FailNow(t, "failed to unmarshal node affinity: %w", err) + } + assert.Equal(t, defaultFleetAgentAffinity, fleetAgentAffinity) + assert.Nil(t, fleetErr) + assert.Nil(t, fleetAgentResourceRequirements) + case "test-agent-customization": + // cluster agent + assert.Equal(t, testClusterAgentToleration, clusterAgentToleration) + assert.Equal(t, testClusterAgentAffinity, clusterAgentAffinity) + assert.Nil(t, clusterErr) + assert.Equal(t, testClusterAgentResourceReq, clusterAgentResourceRequirements) + + // fleet agent + assert.Equal(t, testFleetAgentToleration, fleetAgentToleration) + assert.Equal(t, testFleetAgentAffinity, fleetAgentAffinity) + assert.Nil(t, fleetErr) + assert.Equal(t, testFleetAgentResourceReq, fleetAgentResourceRequirements) + } + }) + } + + // Simulate a user setting default affinity as an invalid str + settings.ClusterAgentDefaultAffinity.Set("test-invalid-affinity") + settings.FleetAgentDefaultAffinity.Set("test-invalid-affinity") + + // Run tests again and verify that when the cluster agent or fleet agent default affinity is pulled it returns + // nil and an error. + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clusterAgentAffinity, clusterErr := GetClusterAgentAffinity(tt.cluster) + fleetAgentAffinity, fleetErr := GetFleetAgentAffinity(tt.cluster) + + switch tt.name { + case "test-default": + // cluster agent + assert.Nil(t, clusterAgentAffinity) + assert.ErrorContains(t, clusterErr, "failed to unmarshal node affinity") + + // fleet agent + assert.Nil(t, fleetAgentAffinity) + assert.ErrorContains(t, fleetErr, "failed to unmarshal node affinity") + case "test-agent-customization": + // cluster agent + assert.Equal(t, testClusterAgentAffinity, clusterAgentAffinity) + assert.Nil(t, clusterErr) + + // fleet agent + assert.Equal(t, testFleetAgentAffinity, fleetAgentAffinity) + assert.Nil(t, fleetErr) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry.go new file mode 100644 index 0000000..eefdddc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry.go @@ -0,0 +1,166 @@ +package cluster + +import ( + "encoding/base64" + "encoding/json" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/rke/util" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/kubernetes/pkg/credentialprovider" +) + +// GetPrivateRegistryURL returns the URL of the private registry specified. It will return the cluster level registry if +// one is found, or the system default registry if no cluster level registry is found. If either is not found, it will +// return an empty string. +func GetPrivateRegistryURL(cluster *v3.Cluster) string { + registry := GetPrivateRegistry(cluster) + if registry == nil { + return "" + } + return registry.URL +} + +// GetPrivateRegistry returns a PrivateRegistry entry (or nil if one is not found) for the given +// clusters.management.cattle.io/v3 object. If a cluster-level registry is not defined, it will return the system +// default registry if one exists. +func GetPrivateRegistry(cluster *v3.Cluster) *rketypes.PrivateRegistry { + privateClusterLevelRegistry := GetPrivateClusterLevelRegistry(cluster) + if privateClusterLevelRegistry != nil { + return privateClusterLevelRegistry + } + if settings.SystemDefaultRegistry.Get() != "" { + return &rketypes.PrivateRegistry{ + URL: settings.SystemDefaultRegistry.Get(), + } + } + return nil +} + +// GetPrivateClusterLevelRegistry returns the cluster-level registry for the given clusters.management.cattle.io/v3 +// object (or nil if one is not found). +func GetPrivateClusterLevelRegistry(cluster *v3.Cluster) *rketypes.PrivateRegistry { + if cluster != nil && cluster.Spec.RancherKubernetesEngineConfig != nil && len(cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries) > 0 { + config := cluster.Spec.RancherKubernetesEngineConfig + return &config.PrivateRegistries[0] + } + return nil +} + +// GeneratePrivateRegistryEncodedDockerConfig generates a base64 encoded docker config JSON blob for the provided +// registry, and returns the registry url, the json credentials, and an error if one was encountered. If the cluster is +// nil or no registry is configured for an RKE1 or v2prov cluster, no registry url or json blob are returned, but there +// is no error returned, since not having a registry is not an error. If a registry is configured for the cluster such +// that we know what the URL is, but we do not have enough information to generate the auth config, we return the url, +// an empty string for the auth config, and no error, as we have determined where the private registry is, but the lack +// of secrets indicate to us that the registry does not need authentication to communicate. For RKE1, we attempt to +// utilize the ECR credential plugin if the corresponding secret exists, otherwise the RKE1 private registry secret is +// stored in the docker config JSON format, so no transformation is required. Otherwise, for v2prov clusters, we extract +// the username and password from the secret, and transform it into the expected docker config JSON format. This +// function should not be called with unmigrated clusters, although it is benign to call this function with assembler +// clusters, as the function will reassemble them anyway. +func GeneratePrivateRegistryEncodedDockerConfig(cluster *v3.Cluster, secretLister v1.SecretLister) (string, string, error) { + var err error + // Declare here so we don't need to check if the rkeClusterRegistryOrGlobalSystemDefault exists while working with v2prov + var rkeClusterURLOrGlobalSystemDefault string + + if cluster == nil { + return "", "", nil + } + + cluster = cluster.DeepCopy() + // Only assemble ECR credential, for RKE1 private registries, the credential is stored in the correct format, and + // v2prov secrets won't be assembled because they are in the fleet workspace namespace of the cluster (currently this + // is always the "fleet-default" namespace) + cluster.Spec, err = assemblers.AssemblePrivateRegistryECRCredential(cluster.Spec.ClusterSecrets.PrivateRegistryECRSecret, assemblers.ClusterType, cluster.Name, cluster.Spec, secretLister) + if err != nil { + return "", "", err + } + + // The PrivateRegistrySecret have the same name both for v1 or v2 provisioning clusters despite having different structures + registrySecretName := cluster.GetSecret(v3.ClusterPrivateRegistrySecret) + + // Private registry will only be defined on the cluster if it is an RKE1 cluster, mgmt clusters generated from + // provisioning clusters do not have a populated `RancherKubernetesEngineConfig`. + if rkeClusterRegistryOrGlobalSystemDefault := GetPrivateRegistry(cluster); rkeClusterRegistryOrGlobalSystemDefault != nil { + rkeClusterURLOrGlobalSystemDefault = rkeClusterRegistryOrGlobalSystemDefault.URL + // check for RKE1 ECR credentials first + if rkeClusterRegistryOrGlobalSystemDefault.ECRCredentialPlugin != nil { + // generate ecr authConfig + authConfig, err := util.ECRCredentialPlugin(rkeClusterRegistryOrGlobalSystemDefault.ECRCredentialPlugin, rkeClusterRegistryOrGlobalSystemDefault.URL) + if err != nil { + return rkeClusterRegistryOrGlobalSystemDefault.URL, "", err + } + encodedJSON, err := json.Marshal(authConfig) + if err != nil { + return rkeClusterRegistryOrGlobalSystemDefault.URL, "", err + } + return rkeClusterRegistryOrGlobalSystemDefault.URL, base64.StdEncoding.EncodeToString(encodedJSON), nil + } + + // If we have a Secret we try to check the rke1 provisioning, otherwise we go directly to the v2prov check. + // This is done this way to always check if there is a downstream registry. + if registrySecretName != "" { + // check for the RKE1 registry secret, returning it if it exists. + registrySecret, err := secretLister.Get(namespace.GlobalNamespace, registrySecretName) + if err == nil { + return rkeClusterRegistryOrGlobalSystemDefault.URL, base64.StdEncoding.EncodeToString(registrySecret.Data[corev1.DockerConfigJsonKey]), nil + } + // If it doesn't exist (secret not found error) we need to check for a v2prov cluster. + if err != nil && !apierrors.IsNotFound(err) { + return rkeClusterRegistryOrGlobalSystemDefault.URL, "", err + } + } + } + + // cluster.GetSecret("PrivateRegistryURL") will be empty if the cluster is + // RKE1, imported, or RKE2 with no cluster level registry configured. + // For RKE2 with a cluster level registry configured, this is the + // only reference to the registry URL available on the v3.Cluster. + // Without it, we cannot generate the registry credentials (.dockerconfigjson) + v2ProvRegistryURL := cluster.GetSecret(v3.ClusterPrivateRegistryURL) + // At this point we know that we don't have a RKE1 registry with authentication + // if we don't get a v2ProvRegistryURL we can just return the image set on v1 Prov or the global system default one. + if v2ProvRegistryURL == "" { + return rkeClusterURLOrGlobalSystemDefault, "", nil + } + + // If we reach this point we know that we have a registry URL set on the v2prov downstream cluster. + // If it is a rke1 cluster that requires an authorization, a rke1 cluster without authorization or a v2prov cluster + // without a registry URL the function would have already returned. + // This last check is to see if the registry requires an authorization, if it doesn't we just return the v2ProvRegistryURL. + if registrySecretName == "" { + return v2ProvRegistryURL, "", nil + } + + // If we have a registrySecretName (registry requires authentication) and this function reached this point + // it is a v2 prov cluster. We need to decode that information to return it. + registrySecret, err := secretLister.Get(cluster.Spec.FleetWorkspaceName, registrySecretName) + if err != nil { + return v2ProvRegistryURL, "", err + } + + username := string(registrySecret.Data["username"]) + password := string(registrySecret.Data["password"]) + authConfig := credentialprovider.DockerConfigJSON{ + Auths: credentialprovider.DockerConfig{ + v2ProvRegistryURL: credentialprovider.DockerConfigEntry{ + Username: username, + Password: password, + }, + }, + } + + registryJSON, err := json.Marshal(authConfig) + if err != nil { + return v2ProvRegistryURL, "", err + } + + return v2ProvRegistryURL, base64.StdEncoding.EncodeToString(registryJSON), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry_test.go new file mode 100644 index 0000000..d4cb5ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cluster/private_registry_test.go @@ -0,0 +1,204 @@ +package cluster + +import ( + "encoding/base64" + "fmt" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + corefakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// It is not currently possible to test ECR credentials, because they require valid credentials and communicate with +// the ecr service to generate an auth config. +func TestGeneratePrivateRegistryDockerConfig(t *testing.T) { + mockSecrets := map[string]*corev1.Secret{} + + secretLister := &corefakes.SecretListerMock{ + GetFunc: func(namespace string, name string) (*corev1.Secret, error) { + id := fmt.Sprintf("%s:%s", namespace, name) + secret, ok := mockSecrets[fmt.Sprintf("%s:%s", namespace, name)] + if !ok { + return nil, apierror.NewNotFound(schema.GroupResource{}, id) + } + return secret.DeepCopy(), nil + }, + } + + tests := []struct { + name string + expectedUrl string + expectedConfig string + expectedError string + cluster *v3.Cluster + secrets []*corev1.Secret + }{ + { + name: "nil", + expectedUrl: "", + expectedConfig: "", + expectedError: "", + cluster: nil, + }, + { + name: "rke1 private registry", + expectedUrl: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + expectedConfig: base64.StdEncoding.EncodeToString([]byte("testConfig")), // should be directly copied from RKE1 secret + expectedError: "", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + ClusterSecrets: v3.ClusterSecrets{ + PrivateRegistrySecret: "test-secret", + }, + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{ + { + URL: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + User: "testuser", + }, + }, + }, + }, + }, + }, + secrets: []*corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: assemblers.SecretNamespace, + Name: "test-secret", + }, + Data: map[string][]byte{ + corev1.DockerConfigJsonKey: []byte("testConfig"), + }, + }, + }, + }, + { + name: "v2prov private registry", + expectedUrl: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + expectedConfig: base64.StdEncoding.EncodeToString([]byte(`{"auths":{"0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com":{"username":"testuser","password":"password","auth":"dGVzdHVzZXI6cGFzc3dvcmQ="}}}`)), + expectedError: "", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + ClusterSecrets: v3.ClusterSecrets{ + PrivateRegistrySecret: "test-secret", + PrivateRegistryURL: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + }, + }, + FleetWorkspaceName: "fleet-default", + }, + }, + secrets: []*corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fleet-default", + Name: "test-secret", + }, + Data: map[string][]byte{ + "username": []byte("testuser"), + "password": []byte("password"), + }, + }, + }, + }, + { + name: "global system default registry and no cluster default registry with secret", + expectedUrl: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + expectedConfig: base64.StdEncoding.EncodeToString([]byte(`{"auths":{"0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com":{"username":"testuser","password":"password","auth":"dGVzdHVzZXI6cGFzc3dvcmQ="}}}`)), + expectedError: "", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{{ + URL: "upstream-registry.com", + }}, + }, + ClusterSecrets: v3.ClusterSecrets{ + PrivateRegistrySecret: "test-secret", + PrivateRegistryURL: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + }, + }, + FleetWorkspaceName: "fleet-default", + }, + }, + secrets: []*corev1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fleet-default", + Name: "test-secret", + }, + Data: map[string][]byte{ + "username": []byte("testuser"), + "password": []byte("password"), + }, + }, + }, + }, + { + name: "global system default registry and cluster default registry without secret", + expectedUrl: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + expectedConfig: "", + expectedError: "", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{{ + URL: "upstream-registry.com", + }}, + }, + ClusterSecrets: v3.ClusterSecrets{ + PrivateRegistryURL: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + }, + }, + FleetWorkspaceName: "fleet-default", + }, + }, + }, + { + name: "global system default registry and no cluster default registry", + expectedUrl: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + expectedConfig: "", + expectedError: "", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{{ + URL: "0123456789abcdef.dkr.ecr.us-east-1.amazonaws.com", + }}, + }, + }, + FleetWorkspaceName: "fleet-default", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockSecrets = make(map[string]*corev1.Secret) + for _, s := range tt.secrets { + mockSecrets[fmt.Sprintf("%s:%s", s.Namespace, s.Name)] = s + } + url, cfg, err := GeneratePrivateRegistryEncodedDockerConfig(tt.cluster, secretLister) + assert.Equal(t, tt.expectedUrl, url) + assert.Equal(t, tt.expectedConfig, cfg) + if tt.expectedError == "" { + assert.Nil(t, err) + } else { + assert.EqualError(t, err, tt.expectedError) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors.go new file mode 100644 index 0000000..aedcb7c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors.go @@ -0,0 +1,11 @@ +package clustermanager + +import "github.com/rancher/norman/httperror" + +// IsClusterUnavailableErr checks if a given error indicates that the requested cluster was not available +func IsClusterUnavailableErr(err error) bool { + if apiError, ok := err.(*httperror.APIError); ok { + return apiError.Code == httperror.ClusterUnavailable + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors_test.go new file mode 100644 index 0000000..a09bfd4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/errors_test.go @@ -0,0 +1,48 @@ +package clustermanager_test + +import ( + "fmt" + "testing" + + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/stretchr/testify/require" +) + +func TestIsClusterUnavailableErr(t *testing.T) { + t.Parallel() + tests := []struct { + name string + err error + want bool + }{ + { + name: "basic error", + err: fmt.Errorf("standard error"), + want: false, + }, + { + name: "api error bad error code", + err: &httperror.APIError{ + Code: httperror.ActionNotAvailable, + }, + want: false, + }, + { + name: "api error cluster unavailable code", + err: &httperror.APIError{ + Code: httperror.ClusterUnavailable, + }, + want: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + got := clustermanager.IsClusterUnavailableErr(test.err) + require.Equal(t, got, test.want) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/manager.go new file mode 100644 index 0000000..f16e9a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/manager.go @@ -0,0 +1,621 @@ +package clustermanager + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "fmt" + "net" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/clusterrouter" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + clusterController "github.com/rancher/rancher/pkg/controllers/managementuser" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/drivers/gke" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rke/pki/cert" + "github.com/rancher/steve/pkg/accesscontrol" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/ratelimit" + "github.com/sirupsen/logrus" + "golang.org/x/sync/semaphore" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + authv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" + "k8s.io/client-go/rest" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +type Manager struct { + httpsPort int + ScaledContext *config.ScaledContext + clusterLister v3.ClusterLister + clusters v3.ClusterInterface + secretLister v1.SecretLister + controllers sync.Map + accessControl types.AccessControl + rbac rbacv1.Interface + dialer dialer.Factory + startSem *semaphore.Weighted +} + +type record struct { + sync.Mutex + clusterRec *apimgmtv3.Cluster + cluster *config.UserContext + accessControl types.AccessControl + started bool + owner bool + ctx context.Context + cancel context.CancelFunc +} + +func NewManager(httpsPort int, context *config.ScaledContext, asl accesscontrol.AccessSetLookup) *Manager { + return &Manager{ + httpsPort: httpsPort, + ScaledContext: context, + accessControl: rbac.NewAccessControlWithASL("", asl), + clusterLister: context.Management.Clusters("").Controller().Lister(), + clusters: context.Management.Clusters(""), + secretLister: context.Core.Secrets("").Controller().Lister(), + startSem: semaphore.NewWeighted(int64(settings.ClusterControllerStartCount.GetInt())), + } +} + +func (m *Manager) Stop(cluster *apimgmtv3.Cluster) { + obj, ok := m.controllers.Load(cluster.UID) + if !ok { + return + } + logrus.Infof("Stopping cluster agent for %s", obj.(*record).cluster.ClusterName) + obj.(*record).cancel() + m.controllers.Delete(cluster.UID) +} + +func (m *Manager) Start(ctx context.Context, cluster *apimgmtv3.Cluster, clusterOwner bool) error { + if cluster.DeletionTimestamp != nil { + return nil + } + // reload cluster, always use the cached one + cluster, err := m.clusterLister.Get("", cluster.Name) + if err != nil { + return err + } + _, err = m.start(ctx, cluster, true, clusterOwner) + return err +} + +func (m *Manager) RESTConfig(cluster *apimgmtv3.Cluster) (rest.Config, error) { + obj, ok := m.controllers.Load(cluster.UID) + if !ok { + return rest.Config{}, fmt.Errorf("cluster record not found %s %s", cluster.Name, cluster.UID) + } + + record := obj.(*record) + return record.cluster.RESTConfig, nil +} + +func (m *Manager) markUnavailable(clusterName string) { + if cluster, err := m.clusters.Get(clusterName, metav1.GetOptions{}); err == nil { + if !apimgmtv3.ClusterConditionReady.IsFalse(cluster) { + apimgmtv3.ClusterConditionReady.False(cluster) + m.clusters.Update(cluster) + } + m.Stop(cluster) + } +} + +func (m *Manager) start(ctx context.Context, cluster *apimgmtv3.Cluster, controllers, clusterOwner bool) (*record, error) { + if cluster.DeletionTimestamp != nil { + return nil, nil + } + obj, ok := m.controllers.Load(cluster.UID) + if ok { + if !m.changed(obj.(*record), cluster, controllers, clusterOwner) { + return obj.(*record), m.startController(obj.(*record), controllers, clusterOwner) + } + m.Stop(obj.(*record).clusterRec) + } + + clusterRecord, err := m.toRecord(ctx, cluster) + if err != nil { + m.markUnavailable(cluster.Name) + return nil, err + } + if clusterRecord == nil { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, "cluster not found") + } + + obj, _ = m.controllers.LoadOrStore(cluster.UID, clusterRecord) + if err := m.startController(obj.(*record), controllers, clusterOwner); err != nil { + m.markUnavailable(cluster.Name) + return nil, err + } + + return obj.(*record), nil +} + +func (m *Manager) startController(r *record, controllers, clusterOwner bool) error { + if !controllers { + return nil + } + + r.Lock() + defer r.Unlock() + if !r.started { + go func() { + if err := m.doStart(r, clusterOwner); err != nil { + logrus.Errorf("failed to start cluster controllers %s: %v", r.cluster.ClusterName, err) + m.markUnavailable(r.clusterRec.Name) + m.Stop(r.clusterRec) + } + }() + r.started = true + r.owner = clusterOwner + } + return nil +} + +func (m *Manager) changed(r *record, cluster *apimgmtv3.Cluster, controllers, clusterOwner bool) bool { + existing := r.clusterRec + if existing.Status.APIEndpoint != cluster.Status.APIEndpoint || + existing.Status.ServiceAccountTokenSecret != cluster.Status.ServiceAccountTokenSecret || + existing.Status.CACert != cluster.Status.CACert || + existing.Status.AppliedSpec.LocalClusterAuthEndpoint.Enabled != cluster.Status.AppliedSpec.LocalClusterAuthEndpoint.Enabled { + return true + } + + if controllers && r.started && clusterOwner != r.owner { + return true + } + + return false +} + +func (m *Manager) doStart(rec *record, clusterOwner bool) (exit error) { + defer func() { + if exit == nil { + logrus.Infof("Starting cluster agent for %s [owner=%v]", rec.cluster.ClusterName, clusterOwner) + } + }() + + for i := 0; ; i++ { + // Prior to k8s v1.14, we simply did a DiscoveryClient.Version() check to see if the user cluster is alive + // As of k8s v1.14, kubeapi returns a successful version response even if etcd is not available. + // To work around this, now we try to get a namespace from the API, even if not found, it means the API is up. + if _, err := rec.cluster.K8sClient.CoreV1().Namespaces().Get(rec.ctx, "kube-system", metav1.GetOptions{}); err != nil && !apierrors.IsNotFound(err) { + if i == 2 { + m.markUnavailable(rec.cluster.ClusterName) + } + select { + case <-rec.ctx.Done(): + return rec.ctx.Err() + case <-time.After(5 * time.Second): + continue + } + } + + break + } + + if err := m.startSem.Acquire(rec.ctx, 1); err != nil { + return err + } + defer m.startSem.Release(1) + + transaction := controller.NewHandlerTransaction(rec.ctx) + if clusterOwner { + if err := clusterController.Register(transaction, m.ScaledContext, rec.cluster, rec.clusterRec, m); err != nil { + transaction.Rollback() + return err + } + } else { + if err := clusterController.RegisterFollower(rec.cluster); err != nil { + transaction.Rollback() + return err + } + } + + done := make(chan error, 1) + go func() { + defer close(done) + + logrus.Debugf("[clustermanager] creating AccessControl for cluster %v", rec.cluster.ClusterName) + rec.accessControl = rbac.NewAccessControl(transaction, rec.cluster.ClusterName, rec.cluster.RBACw) + + err := rec.cluster.Start(rec.ctx) + if err == nil { + transaction.Commit() + } else { + transaction.Rollback() + } + done <- err + }() + + select { + case <-time.After(10 * time.Minute): + rec.cancel() + return fmt.Errorf("timeout syncing controllers") + case err := <-done: + return err + } +} + +// ToRESTConfig generates a rest.Config for a given cluster. +// If reconnect is true, the dialer used for connecting this rest.Config will block +// and retry connecting to the cluster for ~30s if the connection is not available, +// otherwise return immediately +func ToRESTConfig(cluster *apimgmtv3.Cluster, context *config.ScaledContext, secretLister v1.SecretLister, reconnect bool) (*rest.Config, error) { + if cluster == nil { + return nil, nil + } + + if cluster.Spec.Internal { + return &context.RESTConfig, nil + } + + if cluster.Status.APIEndpoint == "" || cluster.Status.CACert == "" { + return nil, nil + } + + if !apimgmtv3.ClusterConditionProvisioned.IsTrue(cluster) { + return nil, nil + } + + // clusters that don't have a service account token secret can't interact with downstream yet + if !apimgmtv3.ClusterConditionServiceAccountSecretsMigrated.IsTrue(cluster) { + return nil, fmt.Errorf("waiting for service account token secret to be populated for cluster [%s]", cluster.Name) + } + + u, err := url.Parse(cluster.Status.APIEndpoint) + if err != nil { + return nil, err + } + + caBytes, err := base64.StdEncoding.DecodeString(cluster.Status.CACert) + if err != nil { + return nil, err + } + + clusterDialer, err := context.Dialer.ClusterDialer(cluster.Name, reconnect) + if err != nil { + return nil, err + } + + var tlsDialer func(string, string) (net.Conn, error) + if cluster.Status.Driver == apimgmtv3.ClusterDriverRKE { + tlsDialer, err = nameIgnoringTLSDialer(clusterDialer, caBytes) + if err != nil { + return nil, err + } + } + + secret, err := secretLister.Get(secretmigrator.SecretNamespace, cluster.Status.ServiceAccountTokenSecret) + if err != nil { + return nil, err + } + + // adding suffix to make tlsConfig hashkey unique + suffix := []byte("\n" + cluster.Name) + rc := &rest.Config{ + Host: u.String(), + BearerToken: string(secret.Data[secretmigrator.SecretKey]), + TLSClientConfig: rest.TLSClientConfig{ + CAData: append(caBytes, suffix...), + NextProtos: []string{"http/1.1"}, + }, + Timeout: 45 * time.Second, + RateLimiter: ratelimit.None, + UserAgent: rest.DefaultKubernetesUserAgent() + " cluster " + cluster.Name, + WrapTransport: func(rt http.RoundTripper) http.RoundTripper { + if ht, ok := rt.(*http.Transport); ok { + if tlsDialer == nil { + ht.DialContext = clusterDialer + } else { + ht.DialContext = nil + ht.DialTLS = tlsDialer + } + } + if cluster.Status.Driver == "googleKubernetesEngine" && cluster.Spec.GenericEngineConfig != nil { + cred, _ := (*cluster.Spec.GenericEngineConfig)["credential"].(string) + rt, err = gke.Oauth2Transport(context.RunContext, rt, cred) + if err != nil { + logrus.Errorf("unable to retrieve token source for GKE oauth2: %v", err) + } + } + return rt + }, + } + + return rc, nil +} + +func nameIgnoringTLSDialer(dialer dialer.Dialer, caBytes []byte) (func(string, string) (net.Conn, error), error) { + rkeVerify, err := VerifyIgnoreDNSName(caBytes) + if err != nil { + return nil, err + } + + tlsConfig := &tls.Config{ + // Use custom TLS validate that validates the cert chain, but not the server. This should be secure because + // we use a private per cluster CA always for RKE + InsecureSkipVerify: true, + VerifyPeerCertificate: rkeVerify, + } + + return func(network, address string) (net.Conn, error) { + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second)) + defer cancel() + rawConn, err := dialer(ctx, network, address) + if err != nil { + return nil, err + } + tlsConn := tls.Client(rawConn, tlsConfig) + if err := tlsConn.Handshake(); err != nil { + rawConn.Close() + return nil, err + } + return tlsConn, err + }, nil +} + +func VerifyIgnoreDNSName(caCertsPEM []byte) (func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error, error) { + rootCAs := x509.NewCertPool() + if len(caCertsPEM) > 0 { + caCerts, err := cert.ParseCertsPEM(caCertsPEM) + if err != nil { + return nil, err + } + for _, cert := range caCerts { + rootCAs.AddCert(cert) + } + } + + return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + certs := make([]*x509.Certificate, len(rawCerts)) + for i, asn1Data := range rawCerts { + cert, err := x509.ParseCertificate(asn1Data) + if err != nil { + return fmt.Errorf("failed to parse cert") + } + certs[i] = cert + } + + opts := x509.VerifyOptions{ + Roots: rootCAs, + CurrentTime: time.Now(), + DNSName: "", + Intermediates: x509.NewCertPool(), + } + + for i, cert := range certs { + if i == 0 { + continue + } + opts.Intermediates.AddCert(cert) + } + _, err := certs[0].Verify(opts) + return err + }, nil +} + +func (m *Manager) toRecord(ctx context.Context, cluster *apimgmtv3.Cluster) (*record, error) { + kubeConfig, err := ToRESTConfig(cluster, m.ScaledContext, m.secretLister, true) + if kubeConfig == nil || err != nil { + return nil, err + } + + clusterContext, err := config.NewUserContext(m.ScaledContext, *kubeConfig, cluster.Name) + if err != nil { + return nil, err + } + + s := &record{ + cluster: clusterContext, + clusterRec: cluster, + } + s.ctx, s.cancel = context.WithCancel(ctx) + + return s, nil +} + +func (m *Manager) AccessControl(apiContext *types.APIContext, storageContext types.StorageContext) (types.AccessControl, error) { + record, err := m.record(apiContext, storageContext) + if err != nil { + return nil, err + } + if record == nil { + return m.accessControl, nil + } + + if record.accessControl == nil { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, "cannot determine access, cluster is unavailable") + } + + return record.accessControl, nil +} + +func (m *Manager) UnversionedClient(apiContext *types.APIContext, storageContext types.StorageContext) (rest.Interface, error) { + record, err := m.record(apiContext, storageContext) + if err != nil { + return nil, err + } + if record == nil { + return m.ScaledContext.UnversionedClient, nil + } + return record.cluster.UnversionedClient, nil +} + +func (m *Manager) APIExtClient(_ *types.APIContext, _ types.StorageContext) (clientset.Interface, error) { + return m.ScaledContext.APIExtClient, nil +} + +// UserContextNoControllers accepts a cluster name and returns a client for that cluster, +// no controllers are started for that cluster in the process. +// Note it will block retrying to connect to the cluster for ~30 seconds before returning +// in case the cluster connection fails. +func (m *Manager) UserContextNoControllers(clusterName string) (*config.UserContext, error) { + return m.UserContextNoControllersReconnecting(clusterName, true) +} + +// UserContextNoControllersReconnecting works like UserContextNoControllers if reconnect is true. +// Otherwise, it will return an error immediately if the cluster connection fails. +func (m *Manager) UserContextNoControllersReconnecting(clusterName string, reconnect bool) (*config.UserContext, error) { + cluster, err := m.clusterLister.Get("", clusterName) + if err != nil { + return nil, err + } + ctx, err := m.UserContextFromClusterReconnecting(cluster, reconnect) + if ctx == nil && err == nil { + return nil, fmt.Errorf("cluster context %s is unavailable", clusterName) + } + return ctx, err +} + +// UserContext accepts a cluster name and returns a client for that cluster, +// starting all controllers for that cluster in the process. +func (m *Manager) UserContext(clusterName string) (*config.UserContext, error) { + cluster, err := m.clusterLister.Get("", clusterName) + if err != nil { + return nil, err + } + + record, err := m.start(context.Background(), cluster, false, false) + if err != nil { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, err.Error()) + } + + if record == nil { + return nil, httperror.NewAPIError(httperror.NotFound, "failed to find cluster") + } + + return record.cluster, nil +} + +// UserContextFromCluster accepts a pointer to a Cluster and returns a client +// for that cluster. It does not start any controllers. +// Note it will block retrying to connect to the cluster for ~30 seconds before returning +// in case the cluster connection fails. +func (m *Manager) UserContextFromCluster(cluster *apimgmtv3.Cluster) (*config.UserContext, error) { + return m.UserContextFromClusterReconnecting(cluster, true) +} + +// UserContextFromClusterReconnecting works like UserContextFromCluster if reconnect is true. +// Otherwise, it will return an error immediately if the cluster connection fails. +func (m *Manager) UserContextFromClusterReconnecting(cluster *apimgmtv3.Cluster, reconnect bool) (*config.UserContext, error) { + kubeConfig, err := ToRESTConfig(cluster, m.ScaledContext, m.secretLister, reconnect) + if err != nil { + return nil, err + } + if kubeConfig == nil { + logrus.Debugf("could not get kubeconfig for cluster %s", cluster.Name) + return nil, nil + } + return config.NewUserContext(m.ScaledContext, *kubeConfig, cluster.Name) +} + +func (m *Manager) record(apiContext *types.APIContext, storageContext types.StorageContext) (*record, error) { + if apiContext == nil { + return nil, nil + } + cluster, err := m.cluster(apiContext, storageContext) + if err != nil { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, err.Error()) + } + if cluster == nil { + return nil, nil + } + record, err := m.start(context.Background(), cluster, false, false) + if err != nil { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, err.Error()) + } + + return record, nil +} + +func (m *Manager) ClusterName(apiContext *types.APIContext) string { + clusterID := apiContext.SubContext["/v3/schemas/cluster"] + if clusterID == "" { + projectID, ok := apiContext.SubContext["/v3/schemas/project"] + if ok { + parts := strings.SplitN(projectID, ":", 2) + if len(parts) == 2 { + clusterID = parts[0] + } + } + } + return clusterID +} + +func (m *Manager) cluster(apiContext *types.APIContext, context types.StorageContext) (*apimgmtv3.Cluster, error) { + switch context { + case types.DefaultStorageContext: + return nil, nil + case config.ManagementStorageContext: + return nil, nil + case config.UserStorageContext: + default: + return nil, fmt.Errorf("illegal context: %s", context) + + } + + clusterID := m.ClusterName(apiContext) + if clusterID == "" { + return nil, nil + } + + return m.clusterLister.Get("", clusterID) +} + +func (m *Manager) KubeConfig(clusterName, token string) *clientcmdapi.Config { + return &clientcmdapi.Config{ + CurrentContext: "default", + APIVersion: "v1", + Kind: "Config", + Clusters: map[string]*clientcmdapi.Cluster{ + "default": { + Server: fmt.Sprintf("https://localhost:%d/k8s/clusters/%s", m.httpsPort, clusterName), + InsecureSkipTLSVerify: true, + }, + }, + Contexts: map[string]*clientcmdapi.Context{ + "default": { + AuthInfo: "user", + Cluster: "default", + }, + }, + AuthInfos: map[string]*clientcmdapi.AuthInfo{ + "user": { + Token: token, + }, + }, + } +} + +func (m *Manager) GetHTTPSPort() int { + return m.httpsPort +} + +func (m *Manager) SubjectAccessReviewForCluster(req *http.Request) (authv1.SubjectAccessReviewInterface, error) { + clusterID := clusterrouter.GetClusterID(req) + userContext, err := m.UserContextNoControllers(clusterID) + if err != nil { + return nil, err + } + return userContext.K8sClient.AuthorizationV1().SubjectAccessReviews(), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/rbac.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/rbac.go new file mode 100644 index 0000000..bc11b81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clustermanager/rbac.go @@ -0,0 +1,94 @@ +package clustermanager + +import ( + "github.com/rancher/norman/types" + "github.com/sirupsen/logrus" +) + +func (m *Manager) Expire(apiContext *types.APIContext, schema *types.Schema) { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return + } + if e, ok := ac.(types.Expire); ok { + e.Expire(apiContext, schema) + } +} + +func (m *Manager) CanCreate(apiContext *types.APIContext, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanCreate(apiContext, schema) +} + +func (m *Manager) CanList(apiContext *types.APIContext, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanList(apiContext, schema) +} + +func (m *Manager) CanGet(apiContext *types.APIContext, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanGet(apiContext, schema) +} + +func (m *Manager) CanUpdate(apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanUpdate(apiContext, obj, schema) +} + +func (m *Manager) CanDelete(apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanDelete(apiContext, obj, schema) +} + +func (m *Manager) CanDo(apiGroup, resource, verb string, apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + return err + } + return ac.CanDo(apiGroup, resource, verb, apiContext, obj, schema) +} + +func (m *Manager) Filter(apiContext *types.APIContext, schema *types.Schema, obj map[string]interface{}, context map[string]string) map[string]interface{} { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + logrus.Warnf("failed to find access control: %v", err) + return nil + } + + return ac.Filter(apiContext, schema, obj, context) +} + +func (m *Manager) FilterList(apiContext *types.APIContext, schema *types.Schema, obj []map[string]interface{}, context map[string]string) []map[string]interface{} { + ac, err := m.getAccessControl(apiContext, schema) + if err != nil { + logrus.Warnf("failed to find access control: %v", err) + return nil + } + return ac.FilterList(apiContext, schema, obj, context) +} + +func (m *Manager) getAccessControl(apiContext *types.APIContext, schema *types.Schema) (types.AccessControl, error) { + return m.AccessControl(apiContext, getContext(schema)) +} + +func getContext(schema *types.Schema) types.StorageContext { + if schema == nil || schema.Store == nil { + return types.DefaultStorageContext + } + return schema.Store.Context() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterprovisioninglogger/log.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterprovisioninglogger/log.go new file mode 100644 index 0000000..780bd21 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterprovisioninglogger/log.go @@ -0,0 +1,143 @@ +package clusterprovisioninglogger + +import ( + "bytes" + "context" + "io" + "sync" + "time" + + "github.com/rancher/norman/condition" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/logstream" + "github.com/sirupsen/logrus" + "google.golang.org/grpc/metadata" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v12 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + configMapName = "provisioning-log" +) + +type logger struct { + Cluster *v3.Cluster + Clusters v3.ClusterInterface + ConfigMaps v1.ConfigMapInterface + done chan struct{} + buffer bytes.Buffer + bufferLock sync.Mutex +} + +func NewLogger(clusters v3.ClusterInterface, configMaps v1.ConfigMapInterface, cluster *v3.Cluster, cond condition.Cond) (context.Context, io.Closer) { + l := &logger{ + Cluster: cluster, + Clusters: clusters, + ConfigMaps: configMaps, + done: make(chan struct{}), + } + + _, ctx, logger := l.getCtx(cluster, cond) + go l.saveInterval() + return ctx, logger +} + +func (p *logger) saveMessage() { + p.bufferLock.Lock() + defer p.bufferLock.Unlock() + + log := p.buffer.String() + if log == "" { + return + } + cm, err := p.ConfigMaps.GetNamespaced(p.Cluster.Name, configMapName, v12.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err := p.ConfigMaps.Create(&corev1.ConfigMap{ + ObjectMeta: v12.ObjectMeta{ + Name: configMapName, + Namespace: p.Cluster.Name, + }, + Data: map[string]string{ + "log": log, + }, + }) + logrus.Errorf("Failed to save provisioning log for %s: %v", configMapName, err) + } else if err != nil { + logrus.Errorf("Failed to get provisioning log for %s: %v", configMapName, err) + } else if log != cm.Data["log"] { + if cm.Data == nil { + cm.Data = map[string]string{} + } + cm.Data["log"] = log + _, err := p.ConfigMaps.Update(cm) + if err != nil { + logrus.Errorf("Failed to update provisioning log for %s: %v", configMapName, err) + } + } +} + +func (p *logger) saveInterval() { + timer := time.NewTicker(2 * time.Second) + defer timer.Stop() + + for { + select { + case <-timer.C: + p.saveMessage() + case <-p.done: + p.saveMessage() + return + } + } +} + +func (p *logger) logEvent(cluster *v3.Cluster, event logstream.LogEvent, cond condition.Cond) *v3.Cluster { + p.bufferLock.Lock() + defer p.bufferLock.Unlock() + + if event.Error { + logrus.Errorf("cluster [%s] provisioning: %s", cluster.Name, event.Message) + } else { + logrus.Infof("cluster [%s] provisioning: %s", cluster.Name, event.Message) + } + p.buffer.WriteString(time.Now().Format(time.RFC3339)) + p.buffer.WriteString(" ") + if event.Error { + p.buffer.WriteString("[ERROR] ") + } else { + p.buffer.WriteString("[INFO ] ") + } + p.buffer.WriteString(event.Message) + p.buffer.WriteString("\n") + return cluster +} + +func (p *logger) getCtx(cluster *v3.Cluster, cond condition.Cond) (string, context.Context, io.Closer) { + logger := logstream.NewLogStream() + logID := logger.ID() + ctx := metadata.NewOutgoingContext(context.Background(), metadata.New(map[string]string{ + "log-id": logID, + })) + wg := sync.WaitGroup{} + wg.Add(1) + + go func() { + defer wg.Done() + for event := range logger.Stream() { + cluster = p.logEvent(cluster, event, cond) + } + }() + + return logID, ctx, closerFunc(func() error { + logger.Close() + wg.Wait() + close(p.done) + return nil + }) +} + +type closerFunc func() error + +func (f closerFunc) Close() error { return f() } diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/factory.go new file mode 100644 index 0000000..af8c7ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/factory.go @@ -0,0 +1,79 @@ +package clusterrouter + +import ( + "net/http" + "sync" + + "github.com/moby/locker" + "github.com/rancher/rancher/pkg/clusterrouter/proxy" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config/dialer" + "k8s.io/client-go/rest" +) + +type factory struct { + dialerFactory dialer.Factory + clusterLookup ClusterLookup + clusterLister v3.ClusterLister + clusters sync.Map + serverLock *locker.Locker + servers sync.Map + localConfig *rest.Config + clusterContextGetter proxy.ClusterContextGetter +} + +func newFactory(localConfig *rest.Config, dialer dialer.Factory, lookup ClusterLookup, clusterLister v3.ClusterLister, clusterContextGetter proxy.ClusterContextGetter) *factory { + return &factory{ + dialerFactory: dialer, + serverLock: locker.New(), + clusterLookup: lookup, + clusterLister: clusterLister, + localConfig: localConfig, + clusterContextGetter: clusterContextGetter, + } +} + +func (s *factory) lookupCluster(clusterID string) (*v3.Cluster, http.Handler) { + srv, ok := s.servers.Load(clusterID) + if ok { + if cluster, ok := s.clusters.Load(clusterID); ok { + return cluster.(*v3.Cluster), srv.(server).Handler() + } + } + + return nil, nil +} + +func (s *factory) get(req *http.Request) (*v3.Cluster, http.Handler, error) { + cluster, err := s.clusterLookup.Lookup(req) + if err != nil || cluster == nil { + return nil, nil, err + } + clusterID := cluster.Name + + if newCluster, handler := s.lookupCluster(clusterID); newCluster != nil { + return newCluster, handler, nil + } + + s.serverLock.Lock("cluster." + clusterID) + defer s.serverLock.Unlock("cluster." + clusterID) + + if newCluster, handler := s.lookupCluster(clusterID); newCluster != nil { + return newCluster, handler, nil + } + + var srv interface{} + srv, err = s.newServer(cluster) + if err != nil || srv == nil { + return nil, nil, err + } + + srv, _ = s.servers.LoadOrStore(cluster.Name, srv) + s.clusters.LoadOrStore(cluster.Name, cluster) + + return cluster, srv.(server).Handler(), nil +} + +func (s *factory) newServer(c *v3.Cluster) (server, error) { + return proxy.New(s.localConfig, c, s.clusterLister, s.dialerFactory, s.clusterContextGetter) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/lookup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/lookup.go new file mode 100644 index 0000000..2a7018a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/lookup.go @@ -0,0 +1,24 @@ +package clusterrouter + +import ( + "net/http" + "strings" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +type ClusterLookup interface { + Lookup(req *http.Request) (*v3.Cluster, error) +} + +func GetClusterID(req *http.Request) string { + parts := strings.Split(req.URL.Path, "/") + if len(parts) > 3 && + parts[0] == "" && + (parts[1] == "k8s" || parts[1] == "v3") && + (parts[2] == "clusters" || parts[2] == "cluster") { + return parts[3] + } + + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/proxy/proxy_server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/proxy/proxy_server.go new file mode 100644 index 0000000..8ec858b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/proxy/proxy_server.go @@ -0,0 +1,315 @@ +package proxy + +import ( + "crypto/tls" + "crypto/x509" + "encoding/base64" + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "strings" + "sync" + + "github.com/rancher/norman/httperror" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + authcontext "github.com/rancher/rancher/pkg/auth/context" + dialer2 "github.com/rancher/rancher/pkg/dialer" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/impersonation" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/wrangler/v3/pkg/schemas/validation" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/httpstream" + utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/proxy" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/client-go/rest" +) + +type ClusterContextGetter interface { + UserContext(string) (*config.UserContext, error) +} + +type RemoteService struct { + sync.Mutex + + cluster *v3.Cluster + transport transportGetter + url urlGetter + + factory dialer.Factory + clusterLister v3.ClusterLister + caCert string + localAuth string + httpTransport *http.Transport + clusterContextGetter ClusterContextGetter +} + +var ( + er = &errorResponder{} +) + +type urlGetter func() (url.URL, error) + +type authGetter func() (string, error) + +type transportGetter func() (http.RoundTripper, error) + +type errorResponder struct { +} + +func (e *errorResponder) Error(w http.ResponseWriter, req *http.Request, err error) { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) +} + +func prefix(cluster *v3.Cluster) string { + return "/k8s/clusters/" + cluster.Name +} + +func New(localConfig *rest.Config, cluster *v3.Cluster, clusterLister v3.ClusterLister, factory dialer.Factory, clusterContextGetter ClusterContextGetter) (*RemoteService, error) { + if cluster.Spec.Internal { + return NewLocal(localConfig, cluster) + } + return NewRemote(cluster, clusterLister, factory, clusterContextGetter) +} + +func NewLocal(localConfig *rest.Config, cluster *v3.Cluster) (*RemoteService, error) { + // the gvk is ignored by us, so just pass in any gvk + hostURL, _, err := rest.DefaultServerURL(localConfig.Host, localConfig.APIPath, schema.GroupVersion{}, true) + if err != nil { + return nil, err + } + + transport, err := rest.TransportFor(localConfig) + if err != nil { + return nil, err + } + + transportGetter := func() (http.RoundTripper, error) { + return transport, nil + } + + rs := &RemoteService{ + cluster: cluster, + url: func() (url.URL, error) { + return *hostURL, nil + }, + transport: transportGetter, + } + if localConfig.BearerToken != "" { + rs.localAuth = "Bearer " + localConfig.BearerToken + } else if localConfig.Password != "" { + rs.localAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", localConfig.Username, localConfig.Password))) + } + + return rs, nil +} + +func NewRemote(cluster *v3.Cluster, clusterLister v3.ClusterLister, factory dialer.Factory, clusterContextGetter ClusterContextGetter) (*RemoteService, error) { + if !v32.ClusterConditionProvisioned.IsTrue(cluster) { + return nil, httperror.NewAPIError(httperror.ClusterUnavailable, "cluster not provisioned") + } + + urlGetter := func() (url.URL, error) { + newCluster, err := clusterLister.Get("", cluster.Name) + if err != nil { + return url.URL{}, err + } + + u, err := url.Parse(newCluster.Status.APIEndpoint) + if err != nil { + return url.URL{}, err + } + return *u, nil + } + + return &RemoteService{ + cluster: cluster, + url: urlGetter, + clusterLister: clusterLister, + factory: factory, + clusterContextGetter: clusterContextGetter, + }, nil +} + +func (r *RemoteService) getTransport() (http.RoundTripper, error) { + if r.transport != nil { + return r.transport() + } + + newCluster, err := r.clusterLister.Get("", r.cluster.Name) + if err != nil { + return nil, err + } + + r.Lock() + defer r.Unlock() + + if r.httpTransport != nil && !r.cacertChanged(newCluster) { + return r.httpTransport, nil + } + + transport := &http.Transport{} + if newCluster.Status.CACert != "" { + certBytes, err := base64.StdEncoding.DecodeString(newCluster.Status.CACert) + if err != nil { + return nil, err + } + certs := x509.NewCertPool() + certs.AppendCertsFromPEM(certBytes) + transport.TLSClientConfig = &tls.Config{ + RootCAs: certs, + } + } + + if r.factory != nil { + d, err := r.factory.ClusterDialer(newCluster.Name, true) + if err != nil { + return nil, err + } + transport.DialContext = d + if dialer2.IsPublicCloudDriver(newCluster) { + transport.Proxy = http.ProxyFromEnvironment + } + } + + r.caCert = newCluster.Status.CACert + if r.httpTransport != nil { + r.httpTransport.CloseIdleConnections() + } + r.httpTransport = transport + + return transport, nil +} + +func (r *RemoteService) cacertChanged(cluster *v3.Cluster) bool { + return r.caCert != cluster.Status.CACert +} + +func (r *RemoteService) Close() { + if r.httpTransport != nil { + r.httpTransport.CloseIdleConnections() + } +} + +func (r *RemoteService) Handler() http.Handler { + return r +} + +func (r *RemoteService) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + u, err := r.url() + if err != nil { + er.Error(rw, req, err) + return + } + + u.Path = strings.TrimPrefix(req.URL.Path, prefix(r.cluster)) + u.RawQuery = req.URL.RawQuery + + proto := req.Header.Get("X-Forwarded-Proto") + if proto != "" { + req.URL.Scheme = proto + } else if req.TLS == nil { + req.URL.Scheme = "http" + } else { + req.URL.Scheme = "https" + } + + req.URL.Host = req.Host + transport, err := r.getTransport() + if err != nil { + er.Error(rw, req, err) + return + } + + if r.cluster.Spec.Internal && r.localAuth == "" { + req.Header.Del("Authorization") + } else { + userInfo, authed := request.UserFrom(req.Context()) + if !authed { + er.Error(rw, req, validation.Unauthorized) + return + } + + if !authcontext.IsSAAuthenticated(req.Context()) { + // If the request is not authenticated as a service account, + // we need to use an impersonation token. + // This is because the impersonator service account does exist on the downstream cluster, and + // it has sufficient permissions to perform the TokenReview. + token, err := r.getImpersonatorAccountToken(userInfo) + if err != nil && !strings.Contains(err.Error(), dialer2.ErrAgentDisconnected.Error()) { + er.Error(rw, req, fmt.Errorf("unable to create impersonator account: %w", err)) + return + } + + req.Header.Set("Authorization", "Bearer "+token) + } + } + + if httpstream.IsUpgradeRequest(req) { + upgradeProxy := NewUpgradeProxy(&u, transport) + upgradeProxy.ServeHTTP(rw, req) + return + } + + httpProxy := proxy.NewUpgradeAwareHandler(&u, transport, true, false, er) + httpProxy.ServeHTTP(rw, req) +} + +func (r *RemoteService) Cluster() *v3.Cluster { + return r.cluster +} + +type UpgradeProxy struct { + Location *url.URL + Transport http.RoundTripper +} + +func NewUpgradeProxy(location *url.URL, transport http.RoundTripper) *UpgradeProxy { + return &UpgradeProxy{ + Location: location, + Transport: transport, + } +} + +func (p *UpgradeProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + loc := *p.Location + loc.RawQuery = req.URL.RawQuery + + newReq := req.WithContext(req.Context()) + newReq.Header = utilnet.CloneHeader(req.Header) + newReq.URL = &loc + + httpProxy := httputil.NewSingleHostReverseProxy(&url.URL{Scheme: p.Location.Scheme, Host: p.Location.Host}) + httpProxy.Transport = p.Transport + httpProxy.ServeHTTP(rw, newReq) +} + +// getImpersonatorAccountToken creates, if not already present, a service account and role bindings +// whose only permission is to impersonate the given user, and returns the bearer token for the account. +func (r *RemoteService) getImpersonatorAccountToken(user user.Info) (string, error) { + clusterContext, err := r.clusterContextGetter.UserContext(r.cluster.Name) + if err != nil { + return "", err + } + + i, err := impersonation.New(user, clusterContext) + if err != nil { + return "", fmt.Errorf("error creating impersonation for user %s: %w", user.GetUID(), err) + } + + sa, err := i.SetUpImpersonation() + if err != nil { + return "", fmt.Errorf("error setting up impersonation for user %s: %w", user.GetUID(), err) + } + saToken, err := i.GetToken(sa) + if err != nil { + return "", fmt.Errorf("error getting service account token: %w", err) + } + + return saToken, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/router.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/router.go new file mode 100644 index 0000000..2e2af43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/router.go @@ -0,0 +1,49 @@ +package clusterrouter + +import ( + "encoding/json" + "net/http" + + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/clusterrouter/proxy" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config/dialer" + "k8s.io/client-go/rest" +) + +type Router struct { + serverFactory *factory +} + +func New(localConfig *rest.Config, lookup ClusterLookup, dialer dialer.Factory, clusterLister v3.ClusterLister, clusterContextGetter proxy.ClusterContextGetter) http.Handler { + serverFactory := newFactory(localConfig, dialer, lookup, clusterLister, clusterContextGetter) + return &Router{ + serverFactory: serverFactory, + } +} + +func (r *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + c, handler, err := r.serverFactory.get(req) + if err != nil { + e, ok := err.(*httperror.APIError) + if ok { + response(rw, e.Code, e.Message) + } else { + response(rw, httperror.ServerError, err.Error()) + } + return + } + + if c == nil { + response(rw, httperror.NotFound, "No cluster available") + return + } + + handler.ServeHTTP(rw, req) +} + +func response(rw http.ResponseWriter, code httperror.ErrorCode, message string) { + rw.WriteHeader(code.Status) + rw.Header().Set("content-type", "application/json") + json.NewEncoder(rw).Encode(httperror.NewAPIError(code, message)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/server.go new file mode 100644 index 0000000..9609a28 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/clusterrouter/server.go @@ -0,0 +1,13 @@ +package clusterrouter + +import ( + "net/http" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +type server interface { + Close() + Handler() http.Handler + Cluster() *v3.Cluster +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/main.go new file mode 100644 index 0000000..4a4b3e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/main.go @@ -0,0 +1,44 @@ +// This program generates a Go file containing a set of exported constants that represent +// configuration variables of Rancher at build-time. +package main + +import ( + "fmt" + "os" + "text/template" +) + +func main() { + if err := generateGoConstantsFile(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func generateGoConstantsFile() error { + in, err := os.OpenFile("build.yaml", os.O_RDONLY, 0644) + if err != nil { + return err + } + out, err := os.OpenFile("pkg/buildconfig/constants.go", os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return err + } + const raw = `// Code generated by pkg/codegen/config/main.go. DO NOT EDIT. +// Package buildconfig contains a set of exported constants that represent configuration variables of Rancher at build-time. +package buildconfig + +const ( +{{ . }}) +` + tmpl, err := template.New("").Parse(raw) + if err != nil { + return err + } + writer := GoConstantsWriter{ + Tmpl: tmpl, + Input: in, + Output: out, + } + return writer.Run() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer.go new file mode 100644 index 0000000..517f58b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer.go @@ -0,0 +1,97 @@ +package main + +import ( + "bytes" + "errors" + "fmt" + "go/format" + "io" + "sort" + "strings" + "text/template" + + "golang.org/x/text/cases" + "golang.org/x/text/language" + "gopkg.in/yaml.v3" +) + +type GoConstantsWriter struct { + Input io.Reader + Output io.Writer + Tmpl *template.Template + buf []byte + cfg map[string]string +} + +// Run loads YAML data from the pre-configured Input source, processes it, and outputs a template with formatted +// Go constants in the pre-configured Output source. This method can only be run once, since the Input source gets fully read. +func (f *GoConstantsWriter) Run() error { + if err := f.load(); err != nil { + return err + } + if err := f.process(); err != nil { + return err + } + if err := f.write(); err != nil { + return err + } + return nil +} + +func (f *GoConstantsWriter) load() error { + if f.Input == nil { + return errors.New("nil input") + } + b, err := io.ReadAll(f.Input) + if err != nil { + return fmt.Errorf("failed to read input: %w", err) + } + if len(b) == 0 { + return errors.New("nothing was read") + } + if err := yaml.Unmarshal(b, &f.cfg); err != nil { + return fmt.Errorf("failed to unmarshal raw YAML from input: %w", err) + } + return nil +} + +func (f *GoConstantsWriter) process() error { + if f.Tmpl == nil { + return errors.New("nil template") + } + // This sorts the keys alphabetically to process the map in a fixed order. + keys := make([]string, 0, len(f.cfg)) + for k := range f.cfg { + keys = append(keys, k) + } + sort.Strings(keys) + + capitalize := cases.Title(language.English, cases.NoLower) + var builder strings.Builder + for _, k := range keys { + v := f.cfg[k] + // Capitalize the key to make the constant exported in the generated Go file. + k = capitalize.String(k) + s := fmt.Sprintf("\t%s = %q\n", k, v) + builder.WriteString(s) + } + + buf := new(bytes.Buffer) + if err := f.Tmpl.Execute(buf, builder.String()); err != nil { + return err + } + f.buf = buf.Bytes() + return nil +} + +func (f *GoConstantsWriter) write() error { + if f.Output == nil { + return errors.New("nil output") + } + formatted, err := format.Source(f.buf) + if err != nil { + return err + } + _, err = f.Output.Write(formatted) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer_test.go new file mode 100644 index 0000000..f7c842c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/buildconfig/writer_test.go @@ -0,0 +1,117 @@ +package main_test + +import ( + "bytes" + "io" + "testing" + "text/template" + + "github.com/rancher/rancher/pkg/codegen/buildconfig" + "github.com/stretchr/testify/require" +) + +func TestGoConstantsWriterRun(t *testing.T) { + t.Parallel() + const contents = `b: 3 +a: foo +c: 3.14` + in := bytes.NewBufferString(contents) + out := new(bytes.Buffer) + + const rawTemplate = ` + package buildconfig + + const ( + {{ . }}) + ` + tmpl, err := template.New("").Parse(rawTemplate) + require.NoError(t, err) + w := &main.GoConstantsWriter{ + Tmpl: tmpl, + Input: in, + Output: out, + } + require.NoError(t, w.Run()) + + want := + `package buildconfig + +const ( + A = "foo" + B = "3" + C = "3.14" +) +` + got := out.String() + require.Equal(t, want, got) + + // Running a second time with the same Input source must fail. + require.Error(t, w.Run()) +} + +func TestGoConstantsWriterFailsWithBadConfiguration(t *testing.T) { + t.Parallel() + const rawTemplate = ` + package buildconfig + + const ( + {{ . }}) + ` + tmpl, err := template.New("").Parse(rawTemplate) + require.NoError(t, err) + const contents = `a: foo +b: 3 +c: 3.14` + output := new(bytes.Buffer) + + tests := []struct { + name string + tmpl *template.Template + input io.Reader + output io.Writer + }{ + { + name: "nil template", + tmpl: nil, + input: bytes.NewBufferString(contents), + output: output, + }, + { + name: "empty template", + tmpl: template.New(""), + input: bytes.NewBufferString(contents), + output: output, + }, + { + name: "nil input", + tmpl: tmpl, + input: nil, + output: output, + }, + { + name: "empty input", + tmpl: tmpl, + input: bytes.NewBufferString(""), + output: output, + }, + { + name: "nil output", + tmpl: tmpl, + input: bytes.NewBufferString(contents), + output: nil, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + w := main.GoConstantsWriter{ + Input: test.input, + Output: test.output, + Tmpl: test.tmpl, + } + require.Error(t, w.Run()) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/cleanup/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/cleanup/main.go new file mode 100644 index 0000000..304dfba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/cleanup/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +func main() { + if err := run(); err != nil { + panic(err) + } +} + +func run() error { + if err := os.RemoveAll("./pkg/client/generated"); err != nil { + return err + } + if err := os.RemoveAll("./pkg/generated"); err != nil { + return err + } + if err := os.RemoveAll("./pkg/crds/yamls/generated"); err != nil { + return err + } + return filepath.Walk("./pkg/apis", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if strings.Contains(path, "vendor") { + return filepath.SkipDir + } + + if strings.HasPrefix(info.Name(), "zz_generated") { + fmt.Println("Removing", path) + if err := os.Remove(path); err != nil { + return err + } + } + + return nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/compose_template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/compose_template.go new file mode 100644 index 0000000..75c6b8e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/compose_template.go @@ -0,0 +1,27 @@ +package generator + +var composeTemplate = `package compose + +import ( + clusterClient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3" + projectClient "github.com/rancher/rancher/pkg/client/generated/project/v3" +) + +type Config struct { + Version string %BACK%yaml:"version,omitempty"%BACK% + + // Management Client + {{range .managementSchemas}} + {{- if . | hasPost }}{{.CodeName}}s map[string]managementClient.{{.CodeName}} %BACK%json:"{{.PluralName}},omitempty" yaml:"{{.PluralName}},omitempty"%BACK% +{{end}}{{end}} + + // Cluster Client + {{range .clusterSchemas}} + {{- if . | hasGet }}{{.CodeName}}s map[string]clusterClient.{{.CodeName}} %BACK%json:"{{.PluralName}},omitempty" yaml:"{{.PluralName}},omitempty"%BACK% +{{end}}{{end}} + + // Project Client + {{range .projectSchemas}} + {{- if . | hasGet }}{{.CodeName}}s map[string]projectClient.{{.CodeName}} %BACK%json:"{{.PluralName}},omitempty" yaml:"{{.PluralName}},omitempty"%BACK% +{{end}}{{end}}}` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/generator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/generator.go new file mode 100644 index 0000000..3fd4004 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/generator/generator.go @@ -0,0 +1,162 @@ +package generator + +import ( + "fmt" + "path" + "strings" + + "net/http" + "os" + "path/filepath" + "text/template" + + "github.com/rancher/norman/generator" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + outputDir = "./pkg/generated" + basePackage = "github.com/rancher/rancher/pkg/apis" + baseCattle = "../client/generated" + baseK8s = "norman" + baseCompose = "compose" +) + +func funcs() template.FuncMap { + return template.FuncMap{ + "capitalize": convert.Capitalize, + "unCapitalize": convert.Uncapitalize, + "upper": strings.ToUpper, + "toLower": strings.ToLower, + "hasGet": hasGet, + "hasPost": hasPost, + } +} + +func hasGet(schema *types.Schema) bool { + return contains(schema.CollectionMethods, http.MethodGet) +} + +func hasPost(schema *types.Schema) bool { + return contains(schema.CollectionMethods, http.MethodPost) +} + +func contains(list []string, needle string) bool { + for _, i := range list { + if i == needle { + return true + } + } + return false +} + +func Generate(schemas *types.Schemas, backendTypes map[string]bool) { + version := getVersion(schemas) + group := strings.Split(version.Group, ".")[0] + + cattleOutputPackage := path.Join(baseCattle, group, version.Version) + k8sOutputPackage := path.Join(baseK8s, version.Group, version.Version) + + if err := generator.Generate(schemas, backendTypes, basePackage, outputDir, cattleOutputPackage, k8sOutputPackage); err != nil { + panic(err) + } +} + +func GenerateClient(schemas *types.Schemas, backendTypes map[string]bool) { + version := getVersion(schemas) + group := strings.Split(version.Group, ".")[0] + + cattleOutputPackage := path.Join(baseCattle, group, version.Version) + + if err := generator.GenerateClient(schemas, backendTypes, outputDir, cattleOutputPackage); err != nil { + panic(err) + } +} + +func GenerateComposeType(projectSchemas *types.Schemas, managementSchemas *types.Schemas, clusterSchemas *types.Schemas) { + if err := generateComposeType(filepath.Join(outputDir, baseCompose), projectSchemas, managementSchemas, clusterSchemas); err != nil { + panic(err) + } +} + +func generateComposeType(baseCompose string, projectSchemas *types.Schemas, managementSchemas *types.Schemas, clusterSchemas *types.Schemas) error { + outputDir := filepath.Join(defaultSourceTree(), baseCompose) + if err := os.MkdirAll(outputDir, 0755); err != nil { + return err + } + filePath := "zz_generated_compose.go" + output, err := os.Create(path.Join(outputDir, filePath)) + if err != nil { + return err + } + defer output.Close() + + typeTemplate, err := template.New("compose.template"). + Funcs(funcs()). + Parse(strings.Replace(composeTemplate, "%BACK%", "`", -1)) + if err != nil { + return err + } + + if err := typeTemplate.Execute(output, map[string]interface{}{ + "managementSchemas": managementSchemas.Schemas(), + "projectSchemas": projectSchemas.Schemas(), + "clusterSchemas": clusterSchemas.Schemas(), + }); err != nil { + return err + } + if err := output.Close(); err != nil { + return err + } + + return generator.Gofmt(defaultSourceTree(), baseCompose) +} + +func GenerateNativeTypes(gv schema.GroupVersion, nsObjs []interface{}, objs []interface{}) { + version := gv.Version + group := gv.Group + groupPath := group + + if groupPath == "" { + groupPath = "core" + } + + k8sOutputPackage := path.Join(outputDir, baseK8s, groupPath, version) + + if err := generator.GenerateControllerForTypes(&types.APIVersion{ + Version: version, + Group: group, + Path: fmt.Sprintf("/k8s/%s-%s", groupPath, version), + }, k8sOutputPackage, nsObjs, objs); err != nil { + panic(err) + } +} + +func getVersion(schemas *types.Schemas) *types.APIVersion { + var version types.APIVersion + for _, schema := range schemas.Schemas() { + if version.Group == "" { + version = schema.Version + continue + } + if version.Group != schema.Version.Group || + version.Version != schema.Version.Version { + panic("schema set contains two APIVersions") + } + } + + return &version +} + +// From gengo/args, v1: +// defaultSourceTree returns the /src directory of the first entry in $GOPATH. +// If $GOPATH is empty, it returns "./". Useful as a default output location. +func defaultSourceTree() string { + paths := strings.Split(os.Getenv("GOPATH"), string(filepath.ListSeparator)) + if len(paths) > 0 && len(paths[0]) > 0 { + return filepath.Join(paths[0], "src") + } + return "./" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/main.go new file mode 100644 index 0000000..a354d0a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/codegen/main.go @@ -0,0 +1,198 @@ +package main + +import ( + "os" + + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/codegen/generator" + clusterSchema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + "github.com/rancher/rancher/pkg/schemas/factory" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + publicSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3public" + projectSchema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + planv1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + controllergen "github.com/rancher/wrangler/v3/pkg/controller-gen" + "github.com/rancher/wrangler/v3/pkg/controller-gen/args" + appsv1 "k8s.io/api/apps/v1" + scalingv2 "k8s.io/api/autoscaling/v2" + batchv1 "k8s.io/api/batch/v1" + v1 "k8s.io/api/core/v1" + extv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + rbacv1 "k8s.io/api/rbac/v1" + storagev1 "k8s.io/api/storage/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func main() { + os.Unsetenv("GOPATH") + + controllergen.Run(args.Options{ + OutputPackage: "github.com/rancher/rancher/pkg/generated", + Boilerplate: "scripts/boilerplate.go.txt", + Groups: map[string]args.Group{ + "management.cattle.io": { + PackageName: "management.cattle.io", + Types: []interface{}{ + // All structs with an embedded ObjectMeta field will be picked up + "./pkg/apis/management.cattle.io/v3", + v3.ProjectCatalog{}, + v3.ClusterCatalog{}, + }, + GenerateTypes: true, + }, + "ui.cattle.io": { + PackageName: "ui.cattle.io", + Types: []interface{}{ + "./pkg/apis/ui.cattle.io/v1", + }, + GenerateTypes: true, + }, + "cluster.cattle.io": { + PackageName: "cluster.cattle.io", + Types: []interface{}{ + // All structs with an embedded ObjectMeta field will be picked up + "./pkg/apis/cluster.cattle.io/v3", + }, + GenerateTypes: true, + }, + "project.cattle.io": { + PackageName: "project.cattle.io", + Types: []interface{}{ + // All structs with an embedded ObjectMeta field will be picked up + "./pkg/apis/project.cattle.io/v3", + }, + GenerateTypes: true, + }, + "catalog.cattle.io": { + PackageName: "catalog.cattle.io", + Types: []interface{}{ + // All structs with an embedded ObjectMeta field will be picked up + "./pkg/apis/catalog.cattle.io/v1", + }, + GenerateTypes: true, + GenerateClients: true, + }, + "upgrade.cattle.io": { + PackageName: "upgrade.cattle.io", + Types: []interface{}{ + planv1.Plan{}, + }, + GenerateClients: true, + }, + "provisioning.cattle.io": { + Types: []interface{}{ + "./pkg/apis/provisioning.cattle.io/v1", + }, + GenerateTypes: true, + GenerateClients: true, + }, + "fleet.cattle.io": { + Types: []interface{}{ + fleet.Bundle{}, + fleet.Cluster{}, + fleet.ClusterGroup{}, + }, + }, + "rke.cattle.io": { + Types: []interface{}{ + "./pkg/apis/rke.cattle.io/v1", + }, + GenerateTypes: true, + GenerateClients: true, + }, + "cluster.x-k8s.io": { + Types: []interface{}{ + capi.Machine{}, + capi.MachineSet{}, + capi.MachineDeployment{}, + capi.MachineHealthCheck{}, + capi.Cluster{}, + }, + }, + }, + }) + + clusterAPIVersion := &types.APIVersion{Group: capi.GroupVersion.Group, Version: capi.GroupVersion.Version, Path: "/v1"} + generator.GenerateClient(factory.Schemas(clusterAPIVersion).Init(func(schemas *types.Schemas) *types.Schemas { + return schemas.MustImportAndCustomize(clusterAPIVersion, capi.Machine{}, func(schema *types.Schema) { + schema.ID = "cluster.x-k8s.io.machine" + }) + }), nil) + + generator.GenerateComposeType(projectSchema.Schemas, managementSchema.Schemas, clusterSchema.Schemas) + generator.Generate(managementSchema.Schemas, map[string]bool{ + "userAttribute": true, + }) + generator.GenerateClient(publicSchema.PublicSchemas, nil) + generator.Generate(clusterSchema.Schemas, map[string]bool{ + "clusterUserAttribute": true, + "clusterAuthToken": true, + }) + generator.Generate(projectSchema.Schemas, nil) + generator.GenerateNativeTypes(v1.SchemeGroupVersion, []interface{}{ + v1.Endpoints{}, + v1.PersistentVolumeClaim{}, + v1.Pod{}, + v1.Service{}, + v1.Secret{}, + v1.ConfigMap{}, + v1.ServiceAccount{}, + v1.ReplicationController{}, + v1.ResourceQuota{}, + v1.LimitRange{}, + }, []interface{}{ + v1.Node{}, + v1.ComponentStatus{}, + v1.Namespace{}, + v1.Event{}, + }) + generator.GenerateNativeTypes(appsv1.SchemeGroupVersion, []interface{}{ + appsv1.Deployment{}, + appsv1.DaemonSet{}, + appsv1.StatefulSet{}, + appsv1.ReplicaSet{}, + }, nil) + generator.GenerateNativeTypes(rbacv1.SchemeGroupVersion, []interface{}{ + rbacv1.RoleBinding{}, + rbacv1.Role{}, + }, []interface{}{ + rbacv1.ClusterRoleBinding{}, + rbacv1.ClusterRole{}, + }) + generator.GenerateNativeTypes(knetworkingv1.SchemeGroupVersion, []interface{}{ + knetworkingv1.NetworkPolicy{}, + knetworkingv1.Ingress{}, + }, nil) + generator.GenerateNativeTypes(batchv1.SchemeGroupVersion, []interface{}{ + batchv1.Job{}, + batchv1.CronJob{}, + }, nil) + generator.GenerateNativeTypes(extv1beta1.SchemeGroupVersion, + []interface{}{ + extv1beta1.Ingress{}, + }, + nil, + ) + generator.GenerateNativeTypes(storagev1.SchemeGroupVersion, + nil, + []interface{}{ + storagev1.StorageClass{}, + }, + ) + generator.GenerateNativeTypes(scalingv2.SchemeGroupVersion, + []interface{}{ + scalingv2.HorizontalPodAutoscaler{}, + }, + nil, + ) + generator.GenerateNativeTypes(apiregistrationv1.SchemeGroupVersion, + nil, + []interface{}{ + apiregistrationv1.APIService{}, + }, + ) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller.go new file mode 100644 index 0000000..53a42b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller.go @@ -0,0 +1,573 @@ +package bootstrap + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "strings" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/capr/installer" + "github.com/rancher/rancher/pkg/controllers/capr/etcdmgmt" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/rancher/pkg/tls" + "github.com/rancher/rancher/pkg/wrangler" + appcontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + capiannotations "sigs.k8s.io/cluster-api/util/annotations" + "sigs.k8s.io/cluster-api/util/secret" +) + +const ( + rkeBootstrapName = "rke.cattle.io/rkebootstrap-name" + capiMachinePreTerminateAnnotation = "pre-terminate.delete.hook.machine.cluster.x-k8s.io/rke-bootstrap-cleanup" + capiMachinePreTerminateAnnotationOwner = "rke-bootstrap-controller" +) + +type handler struct { + serviceAccountCache corecontrollers.ServiceAccountCache + secretCache corecontrollers.SecretCache + secretClient corecontrollers.SecretClient + machineCache capicontrollers.MachineCache + machineClient capicontrollers.MachineClient + capiClusterCache capicontrollers.ClusterCache + deploymentCache appcontrollers.DeploymentCache + rkeControlPlanes rkecontroller.RKEControlPlaneCache + rkeBootstrap rkecontroller.RKEBootstrapController + k8s kubernetes.Interface +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + serviceAccountCache: clients.Core.ServiceAccount().Cache(), + secretCache: clients.Core.Secret().Cache(), + secretClient: clients.Core.Secret(), + machineCache: clients.CAPI.Machine().Cache(), + machineClient: clients.CAPI.Machine(), + capiClusterCache: clients.CAPI.Cluster().Cache(), + deploymentCache: clients.Apps.Deployment().Cache(), + rkeControlPlanes: clients.RKE.RKEControlPlane().Cache(), + rkeBootstrap: clients.RKE.RKEBootstrap(), + k8s: clients.K8s, + } + + clients.RKE.RKEBootstrap().OnChange(ctx, "rke-bootstrap-cluster-name", h.OnChange) + clients.RKE.RKEBootstrap().OnRemove(ctx, "rke-bootstrap-etcd-removal", h.OnRemove) + rkecontroller.RegisterRKEBootstrapGeneratingHandler(ctx, + clients.RKE.RKEBootstrap(), + clients.Apply. + WithCacheTypes( + clients.RBAC.Role(), + clients.RBAC.RoleBinding(), + clients.CAPI.Machine(), + clients.Core.ServiceAccount(), + clients.Core.Secret()). + WithSetOwnerReference(true, true), + "", + "rke-bootstrap", + h.GeneratingHandler, + nil) + + relatedresource.Watch(ctx, "rke-bootstrap-trigger", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if sa, ok := obj.(*corev1.ServiceAccount); ok { + if name, ok := sa.Labels[rkeBootstrapName]; ok { + return []relatedresource.Key{ + { + Namespace: sa.Namespace, + Name: name, + }, + }, nil + } + } + if machine, ok := obj.(*capi.Machine); ok { + if machine.Spec.Bootstrap.ConfigRef != nil && machine.Spec.Bootstrap.ConfigRef.Kind == "RKEBootstrap" { + return []relatedresource.Key{{ + Namespace: machine.Namespace, + Name: machine.Spec.Bootstrap.ConfigRef.Name, + }}, nil + } + } + return nil, nil + }, clients.RKE.RKEBootstrap(), clients.Core.ServiceAccount(), clients.CAPI.Machine()) +} + +func (h *handler) getBootstrapSecret(namespace, name string, envVars []corev1.EnvVar, machine *capi.Machine, dataDir string) (*corev1.Secret, error) { + sa, err := h.serviceAccountCache.Get(namespace, name) + if apierrors.IsNotFound(err) { + return nil, nil + } + + if err != nil { + return nil, err + } + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(context.Background(), h.secretCache, h.k8s, sa) + if err != nil { + return nil, err + } + hash := sha256.Sum256(secret.Data["token"]) + + hasHostPort, err := h.rancherDeploymentHasHostPort() + if err != nil { + return nil, err + } + + is := installer.LinuxInstallScript + if os := machine.GetLabels()[capr.CattleOSLabel]; os == capr.WindowsMachineOS { + is = installer.WindowsInstallScript + } + + data, err := is(context.WithValue(context.Background(), tls.InternalAPI, hasHostPort), base64.URLEncoding.EncodeToString(hash[:]), envVars, "", dataDir) + if err != nil { + return nil, err + } + + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{ + "value": data, + }, + Type: "rke.cattle.io/bootstrap", + }, nil +} + +func (h *handler) assignPlanSecret(machine *capi.Machine, bootstrap *rkev1.RKEBootstrap) []runtime.Object { + planSecretName := capr.PlanSecretFromBootstrapName(bootstrap.Name) + labels, annotations := getLabelsAndAnnotationsForPlanSecret(bootstrap, machine) + + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: planSecretName, + Namespace: bootstrap.Namespace, + Labels: map[string]string{ + capr.MachineNameLabel: machine.Name, + rkeBootstrapName: bootstrap.Name, + capr.RoleLabel: capr.RolePlan, + capr.PlanSecret: planSecretName, + }, + }, + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: planSecretName, + Namespace: bootstrap.Namespace, + Labels: labels, + Annotations: annotations, + }, + Type: capr.SecretTypeMachinePlan, + } + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: planSecretName, + Namespace: bootstrap.Namespace, + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"watch", "get", "update", "list"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{planSecretName}, + }, + }, + } + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: planSecretName, + Namespace: bootstrap.Namespace, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: sa.Name, + Namespace: sa.Namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: planSecretName, + }, + } + + return []runtime.Object{sa, secret, role, roleBinding} +} + +func (h *handler) getEnvVars(controlPlane *rkev1.RKEControlPlane) ([]corev1.EnvVar, error) { + var result []corev1.EnvVar + for _, env := range controlPlane.Spec.AgentEnvVars { + // Disallow user supplied system agent var dir env var in favor of spec.systemAgent + if env.Name == capr.SystemAgentDataDirEnvVar { + continue + } + result = append(result, corev1.EnvVar{ + Name: env.Name, + Value: env.Value, + }) + } + if dir := controlPlane.Spec.DataDirectories.SystemAgent; dir != "" { + result = append(result, corev1.EnvVar{ + Name: capr.SystemAgentDataDirEnvVar, + Value: dir, + }) + } + switch capr.GetRuntime(controlPlane.Spec.KubernetesVersion) { + case capr.RuntimeRKE2: + result = append(result, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/rke2/bin", + }) + default: + result = append(result, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/bin", + }) + } + + return result, nil +} + +// shouldCreateBootstrapSecret returns true if the generated handler should create/ensure the bootstrap secret's +// existence, otherwise it wil be cleaned up. The bootstrap secret is created immediately in the Pending phase and +// should be present until machine deletion. +func shouldCreateBootstrapSecret(phase capi.MachinePhase) bool { + return phase != capi.MachinePhaseDeleting && phase != capi.MachinePhaseDeleted && phase != capi.MachinePhaseFailed +} + +// assignBootStrapSecret is utilized by the bootstrap controller's GeneratingHandler method to designate the lifecycle +// of both the bootstrap secret and related service account. The bootstrap secret and service account must be valid +// until the corresponding CAPI Machine object's Machine Phase is at least "Running", which indicates that the machine +// "has become a Kubernetes Node in a Ready state". +func (h *handler) assignBootStrapSecret(machine *capi.Machine, bootstrap *rkev1.RKEBootstrap, capiCluster *capi.Cluster) (*corev1.Secret, []runtime.Object, error) { + if !shouldCreateBootstrapSecret(capi.MachinePhase(machine.Status.Phase)) { + return nil, nil, nil + } + + if capiCluster.Spec.ControlPlaneRef == nil || capiCluster.Spec.ControlPlaneRef.Kind != "RKEControlPlane" { + return nil, nil, nil + } + controlPlane, err := h.rkeControlPlanes.Get(bootstrap.Namespace, capiCluster.Spec.ControlPlaneRef.Name) + if err != nil { + return nil, nil, err + } + + envVars, err := h.getEnvVars(controlPlane) + if err != nil { + return nil, nil, err + } + + dataDir := capr.GetDistroDataDir(controlPlane) + + secretName := name.SafeConcatName(bootstrap.Name, "machine", "bootstrap") + + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: bootstrap.Namespace, + Labels: map[string]string{ + capr.MachineNameLabel: machine.Name, + rkeBootstrapName: bootstrap.Name, + capr.RoleLabel: capr.RoleBootstrap, + }, + }, + } + + bootstrapSecret, err := h.getBootstrapSecret(sa.Namespace, sa.Name, envVars, machine, dataDir) + if err != nil { + return nil, nil, err + } + + return bootstrapSecret, []runtime.Object{sa}, nil +} + +func (h *handler) OnChange(_ string, bootstrap *rkev1.RKEBootstrap) (*rkev1.RKEBootstrap, error) { + if bootstrap == nil || !bootstrap.DeletionTimestamp.IsZero() { + return bootstrap, nil + } + + // If the bootstrap spec cluster name is blank, we need to update the bootstrap spec to the correct value + // This is to handle old rkebootstrap objects for unmanaged clusters that did not have the spec properly set + if v, ok := bootstrap.Labels[capi.ClusterNameLabel]; ok && v != "" && bootstrap.Spec.ClusterName != v { + logrus.Debugf("[rkebootstrap] %s/%s: setting cluster name", bootstrap.Namespace, bootstrap.Name) + bootstrap = bootstrap.DeepCopy() + bootstrap.Spec.ClusterName = v + return h.rkeBootstrap.Update(bootstrap) + } + + return h.reconcileMachinePreTerminateAnnotation(bootstrap) +} + +func (h *handler) GeneratingHandler(bootstrap *rkev1.RKEBootstrap, status rkev1.RKEBootstrapStatus) ([]runtime.Object, rkev1.RKEBootstrapStatus, error) { + var ( + result []runtime.Object + ) + + machine, err := capr.GetOwnerCAPIMachine(bootstrap, h.machineCache) + if apierrors.IsNotFound(err) { + logrus.Debugf("[rkebootstrap] %s/%s: waiting: machine to be set as owner reference", bootstrap.Namespace, bootstrap.Name) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 10*time.Second) + return result, status, generic.ErrSkip + } + if err != nil { + logrus.Errorf("[rkebootstrap] %s/%s: error getting machine by owner reference %v", bootstrap.Namespace, bootstrap.Name, err) + return nil, status, err + } + + capiCluster, err := h.capiClusterCache.Get(machine.Namespace, machine.Spec.ClusterName) + if apierrors.IsNotFound(err) { + logrus.Debugf("[rkebootstrap] %s/%s: waiting: CAPI cluster does not exist", bootstrap.Namespace, bootstrap.Name) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 10*time.Second) + return result, status, generic.ErrSkip + } + if err != nil { + logrus.Errorf("[rkebootstrap] %s/%s: error getting CAPI cluster %v", bootstrap.Namespace, bootstrap.Name, err) + return result, status, err + } + + if capiannotations.IsPaused(capiCluster, bootstrap) { + logrus.Debugf("[rkebootstrap] %s/%s: waiting: CAPI cluster or RKEBootstrap is paused", bootstrap.Namespace, bootstrap.Name) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 10*time.Second) + return result, status, generic.ErrSkip + } + + if !capiCluster.Status.InfrastructureReady { + logrus.Debugf("[rkebootstrap] %s/%s: waiting: CAPI cluster infrastructure is not ready", bootstrap.Namespace, bootstrap.Name) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 10*time.Second) + return result, status, generic.ErrSkip + } + + // The plan secret is used by the planner to deliver plans to the system-agent (and receive feedback) + result = append(result, h.assignPlanSecret(machine, bootstrap)...) + + // The bootstrap secret contains the system-agent install script with corresponding information to bootstrap the node + bootstrapSecret, objs, err := h.assignBootStrapSecret(machine, bootstrap, capiCluster) + if err != nil { + return nil, status, err + } + + if bootstrapSecret != nil { + if status.DataSecretName == nil { + status.DataSecretName = &bootstrapSecret.Name + status.Ready = true + logrus.Debugf("[rkebootstrap] %s/%s: setting dataSecretName: %s", bootstrap.Namespace, bootstrap.Name, *status.DataSecretName) + } + result = append(result, bootstrapSecret) + } + + result = append(result, objs...) + return result, status, nil +} + +func (h *handler) rancherDeploymentHasHostPort() (bool, error) { + deployment, err := h.deploymentCache.Get(namespace.System, "rancher") + if err != nil { + if apierrors.IsNotFound(err) { + return false, nil + } + return false, err + } + + for _, container := range deployment.Spec.Template.Spec.Containers { + for _, port := range container.Ports { + if container.Name == "rancher" && port.HostPort != 0 { + return true, nil + } + } + } + + return false, nil +} + +func getLabelsAndAnnotationsForPlanSecret(bootstrap *rkev1.RKEBootstrap, machine *capi.Machine) (map[string]string, map[string]string) { + labels := make(map[string]string, len(bootstrap.Labels)+2) + labels[capr.MachineNameLabel] = machine.Name + labels[capr.ClusterNameLabel] = bootstrap.Spec.ClusterName + for k, v := range bootstrap.Labels { + labels[k] = v + } + + annotations := make(map[string]string, len(bootstrap.Annotations)) + for k, v := range bootstrap.Annotations { + annotations[k] = v + } + + return labels, annotations +} + +// OnRemove adds finalizer handling to the RKEBootstrap object, and is used to prevent deletion of the RKE Bootstrap +// when it is deleting and bootstrap is for an etcd node. +func (h *handler) OnRemove(_ string, bootstrap *rkev1.RKEBootstrap) (*rkev1.RKEBootstrap, error) { + logrus.Debugf("[rkebootstrap] %s/%s: OnRemove invoked", bootstrap.Namespace, bootstrap.Name) + return h.reconcileMachinePreTerminateAnnotation(bootstrap) +} + +// reconcileMachinePreTerminateAnnotation reconciles the machine object that owns the bootstrap. It only reconciles the machine if it is an +// etcd machine. Its primary purpose is to manage the pre-terminate.delete.hook.machine.x-k8s.io annotation on the machine +// object, which is used to prevent premature tear down of infrastructure before it is ready to be teared down, i.e. +// allowing removal of an etcd member without causing quorum loss. +// The pre-terminate hook will be set on the machine object if the machine and bootstrap are not deleting, the corresponding +// CAPI cluster and RKEControlPlane are not deleting, and the force remove annotation is not set on the bootstrap. +// The annotation will be removed from the machine to allow infrastructure cleanup in the following cases: +// * The machine is deleting and the "safe remove" logic has fired and removed the etcd member from the etcd cluster +// * The bootstrap is missing the CAPI cluster label || the CAPI cluster controlPlaneRef is nil || the machine noderef is nil +// * Any of the following: CAPI kubeconfig secret, CAPI cluster object, RKEControlPlane object are not found +// +// Notably, CAPI controllers do not trigger a deletion of the RKEBootstrap object if a pre-terminate annotation exists on the corresponding machine object. +// This means we rely on the OnChange handler to perform node safe removal, when it sees that the corresponding machine is deleting. +func (h *handler) reconcileMachinePreTerminateAnnotation(bootstrap *rkev1.RKEBootstrap) (*rkev1.RKEBootstrap, error) { + machine, err := capr.GetMachineByOwner(h.machineCache, bootstrap) + if err != nil { + if errors.Is(err, capr.ErrNoMachineOwnerRef) || apierrors.IsNotFound(err) { + // If we did not find the machine by owner ref or the cache returned a not found, then noop. + return bootstrap, nil + } + return bootstrap, err + } + + _, isEtcd := machine.Labels[capr.EtcdRoleLabel] + + forceRemove, ok := bootstrap.Annotations[capr.ForceRemoveEtcdAnnotation] + if (ok && strings.ToLower(forceRemove) == "true") || !isEtcd { + // If the force remove annotation is "true" or the node is not an etcd node, then ensure the machine pre terminate annotation is removed. + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + + // Only add the pre-terminate hook annotation if the corresponding machine and bootstrap are NOT deleting + if machine.DeletionTimestamp.IsZero() && bootstrap.DeletionTimestamp.IsZero() { + // annotate the CAPI machine with the pre-terminate.delete.hook.machine.cluster.x-k8s.io annotation if it is an etcd machine + if val, ok := machine.GetAnnotations()[capiMachinePreTerminateAnnotation]; !ok || val != capiMachinePreTerminateAnnotationOwner { + machine = machine.DeepCopy() + if machine.Annotations == nil { + machine.Annotations = make(map[string]string) + } + machine.Annotations[capiMachinePreTerminateAnnotation] = capiMachinePreTerminateAnnotationOwner + machine, err = h.machineClient.Update(machine) + if err != nil { + return bootstrap, err + } + } + return bootstrap, nil + } + + if bootstrap.Spec.ClusterName == "" { + logrus.Warnf("[rkebootstrap] %s/%s: CAPI cluster label %s was not found in bootstrap labels, ensuring machine pre-terminate annotation is removed", bootstrap.Namespace, bootstrap.Name, capi.ClusterNameLabel) + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + + capiCluster, err := h.capiClusterCache.Get(bootstrap.Namespace, bootstrap.Spec.ClusterName) + if err != nil { + if apierrors.IsNotFound(err) { + logrus.Warnf("[rkebootstrap] %s/%s: CAPI cluster %s/%s was not found, ensuring machine pre-terminate annotation is removed", bootstrap.Namespace, bootstrap.Name, bootstrap.Namespace, bootstrap.Spec.ClusterName) + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + return bootstrap, err + } + + if capiCluster.Spec.ControlPlaneRef == nil { + logrus.Warnf("[rkebootstrap] %s/%s: CAPI cluster %s/%s controlplane object reference was nil, ensuring machine pre-terminate annotation is removed", bootstrap.Namespace, bootstrap.Name, capiCluster.Namespace, capiCluster.Name) + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + + cp, err := h.rkeControlPlanes.Get(capiCluster.Spec.ControlPlaneRef.Namespace, capiCluster.Spec.ControlPlaneRef.Name) + if err != nil { + if apierrors.IsNotFound(err) { + logrus.Warnf("[rkebootstrap] %s/%s: RKEControlPlane %s/%s was not found, ensuring machine pre-terminate annotation is removed", bootstrap.Namespace, bootstrap.Name, capiCluster.Spec.ControlPlaneRef.Namespace, capiCluster.Spec.ControlPlaneRef.Name) + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + return bootstrap, err + } + + if !cp.DeletionTimestamp.IsZero() || !capiCluster.DeletionTimestamp.IsZero() { + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + + if machine.Status.NodeRef == nil { + logrus.Infof("[rkebootstrap] No associated node found for machine %s/%s in cluster %s, ensuring machine pre-terminate annotation is removed", machine.Namespace, machine.Name, bootstrap.Spec.ClusterName) + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + + // If the RKEControlPlane is not deleting, then make sure this node is not being used as an init node. + if cp.DeletionTimestamp.IsZero() { + planSecret, err := h.secretCache.Get(bootstrap.Namespace, capr.PlanSecretFromBootstrapName(bootstrap.Name)) + if err != nil && !apierrors.IsNotFound(err) { + return bootstrap, fmt.Errorf("error retrieving plan secret to validate it was not an init node: %v", err) + } + + if planSecret != nil { + // validate that no other nodes are joined to this node, otherwise removing it will cause a bunch of nodes to start crashing. + joinURL := planSecret.Annotations[capr.JoinURLAnnotation] + planSecrets, err := h.secretCache.List(bootstrap.Namespace, labels.SelectorFromSet(map[string]string{ + capi.ClusterNameLabel: bootstrap.Spec.ClusterName, + })) + if err != nil { + return bootstrap, fmt.Errorf("error encountered list plansecrets to ensure node was not joined: %v", err) + } + for _, ps := range planSecrets { + if ps.GetAnnotations()[capr.JoinedToAnnotation] == joinURL { + logrus.Errorf("[rkebootstrap] %s/%s: cluster %s/%s machine %s/%s was still joined to deleting etcd machine %s/%s", bootstrap.Namespace, bootstrap.Name, capiCluster.Namespace, capiCluster.Name, bootstrap.Namespace, ps.GetLabels()[capr.MachineNameLabel], machine.Namespace, machine.Name) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 5*time.Second) + return bootstrap, generic.ErrSkip + } + } + } + } + + kcSecret, err := h.secretCache.Get(bootstrap.Namespace, secret.Name(bootstrap.Spec.ClusterName, secret.Kubeconfig)) + if err != nil { + if apierrors.IsNotFound(err) { + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) + } + return bootstrap, err + } + + restConfig, err := clientcmd.RESTConfigFromKubeConfig(kcSecret.Data["value"]) + if err != nil { + return bootstrap, err + } + + removed, err := etcdmgmt.SafelyRemoved(restConfig, capr.GetRuntimeCommand(cp.Spec.KubernetesVersion), machine.Status.NodeRef.Name) + if err != nil { + return bootstrap, err + } + if !removed { + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, 5*time.Second) + return bootstrap, generic.ErrSkip + } + return h.ensureMachinePreTerminateAnnotationRemoved(bootstrap, machine) +} + +// ensureMachinePreTerminateAnnotationRemoved removes the pre-terminate annotation from a CAPI machine when we removing the rkebootstrap, indicating the infrastructure can be deleted. +func (h *handler) ensureMachinePreTerminateAnnotationRemoved(bootstrap *rkev1.RKEBootstrap, machine *capi.Machine) (*rkev1.RKEBootstrap, error) { + if machine == nil || machine.Annotations == nil { + return bootstrap, nil + } + + var err error + if _, ok := machine.GetAnnotations()[capiMachinePreTerminateAnnotation]; ok { + machine = machine.DeepCopy() + delete(machine.Annotations, capiMachinePreTerminateAnnotation) + _, err = h.machineClient.Update(machine) + } + return bootstrap, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller_test.go new file mode 100644 index 0000000..cff5e0d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/bootstrap/controller_test.go @@ -0,0 +1,288 @@ +package bootstrap + +import ( + "crypto/sha256" + "encoding/base64" + "fmt" + "testing" + + "github.com/golang/mock/gomock" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + ctrlfake "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1apps "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes/fake" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func Test_getBootstrapSecret(t *testing.T) { + type args struct { + secretName string + os string + namespaceName string + path string + command string + body string + } + + tests := []struct { + name string + args args + }{ + { + name: "Checking Linux Install Script", + args: args{ + os: capr.DefaultMachineOS, + secretName: "mybestlinuxsecret", + command: "sh", + namespaceName: "myfavoritelinuxnamespace", + path: "/system-agent-install.sh", + body: "#!/usr/bin/env sh", + }, + }, + { + name: "Checking Windows Install Script", + args: args{ + os: capr.WindowsMachineOS, + secretName: "mybestwindowssecret", + command: "powershell", + namespaceName: "myfavoritewindowsnamespace", + path: "/wins-agent-install.ps1", + body: "Invoke-WinsInstaller @PSBoundParameters", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + expectHash := sha256.Sum256([]byte("thisismytokenandiwillprotectit")) + expectEncodedHash := base64.URLEncoding.EncodeToString(expectHash[:]) + a := assert.New(t) + ctrl := gomock.NewController(t) + handler := handler{ + serviceAccountCache: getServiceAccountCacheMock(ctrl, tt.args.namespaceName, tt.args.secretName), + secretCache: getSecretCacheMock(ctrl, tt.args.namespaceName, tt.args.secretName), + deploymentCache: getDeploymentCacheMock(ctrl), + machineCache: getMachineCacheMock(ctrl, tt.args.namespaceName, tt.args.os), + k8s: fake.NewSimpleClientset(), + } + + //act + err := settings.ServerURL.Set("localhost") + a.Nil(err) + err = settings.SystemAgentInstallScript.Set("https://raw.githubusercontent.com/rancher/system-agent/main/install.sh") + a.Nil(err) + err = settings.SystemAgentInstallerImage.Set("rancher/system-agent-installer-") + a.Nil(err) + + serviceAccount, err := handler.serviceAccountCache.Get(tt.args.namespaceName, tt.args.secretName) + a.Nil(err) + machine, err := handler.machineCache.Get(tt.args.namespaceName, tt.args.os) + a.Nil(err) + secret, err := handler.getBootstrapSecret(tt.args.namespaceName, tt.args.secretName, []v1.EnvVar{}, machine, "") + a.Nil(err) + + // assert + a.NotNil(secret) + a.NotNil(serviceAccount) + a.NotNil(machine) + a.NotNil(expectHash) + a.NotEmpty(expectEncodedHash) + + a.Equal(tt.args.secretName, secret.Name) + a.Equal(tt.args.namespaceName, secret.Namespace) + a.Equal(tt.args.secretName, serviceAccount.Name) + a.Equal(tt.args.namespaceName, serviceAccount.Namespace) + a.Equal(tt.args.os, machine.Name) + a.Equal(tt.args.namespaceName, machine.Namespace) + + a.Equal("rke.cattle.io/bootstrap", string(secret.Type)) + data := string(secret.Data["value"]) + a.Contains(data, fmt.Sprintf("CATTLE_TOKEN=\"%s\"", expectEncodedHash)) + + switch tt.args.os { + + case capr.DefaultMachineOS: + a.Equal(tt.args.os, capr.DefaultMachineOS) + a.Contains(data, "#!/usr/bin") + a.True(machine.GetLabels()[capr.CattleOSLabel] == capr.DefaultMachineOS) + a.True(machine.GetLabels()[capr.ControlPlaneRoleLabel] == "true") + a.True(machine.GetLabels()[capr.EtcdRoleLabel] == "true") + a.True(machine.GetLabels()[capr.WorkerRoleLabel] == "true") + a.Contains(data, "CATTLE_SERVER=localhost") + a.Contains(data, "CATTLE_ROLE_NONE=true") + + case capr.WindowsMachineOS: + a.Equal(tt.args.os, capr.WindowsMachineOS) + a.Contains(data, "Invoke-WinsInstaller") + a.True(machine.GetLabels()[capr.CattleOSLabel] == capr.WindowsMachineOS) + a.True(machine.GetLabels()[capr.ControlPlaneRoleLabel] == "false") + a.True(machine.GetLabels()[capr.EtcdRoleLabel] == "false") + a.True(machine.GetLabels()[capr.WorkerRoleLabel] == "true") + a.Contains(data, "$env:CATTLE_SERVER=\"localhost\"") + a.Contains(data, "CATTLE_ROLE_NONE=\"true\"") + a.Contains(data, "$env:CSI_PROXY_URL") + a.Contains(data, "$env:CSI_PROXY_VERSION") + a.Contains(data, "$env:CSI_PROXY_KUBELET_PATH") + } + }) + } +} + +func getMachineCacheMock(ctrl *gomock.Controller, namespace, os string) *ctrlfake.MockCacheInterface[*capi.Machine] { + mockMachineCache := ctrlfake.NewMockCacheInterface[*capi.Machine](ctrl) + mockMachineCache.EXPECT().Get(namespace, capr.DefaultMachineOS).DoAndReturn(func(namespace, name string) (*capi.Machine, error) { + return &capi.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: os, + Namespace: namespace, + Labels: map[string]string{ + capr.ControlPlaneRoleLabel: "true", + capr.EtcdRoleLabel: "true", + capr.WorkerRoleLabel: "true", + capr.CattleOSLabel: os, + }, + }, + }, nil + }).AnyTimes() + + mockMachineCache.EXPECT().Get(namespace, capr.WindowsMachineOS).DoAndReturn(func(namespace, name string) (*capi.Machine, error) { + return &capi.Machine{ + ObjectMeta: metav1.ObjectMeta{ + Name: os, + Namespace: namespace, + Labels: map[string]string{ + capr.ControlPlaneRoleLabel: "false", + capr.EtcdRoleLabel: "false", + capr.WorkerRoleLabel: "true", + capr.CattleOSLabel: os, + }, + }, + }, nil + }).AnyTimes() + return mockMachineCache +} + +func getDeploymentCacheMock(ctrl *gomock.Controller) *ctrlfake.MockCacheInterface[*v1apps.Deployment] { + mockDeploymentCache := ctrlfake.NewMockCacheInterface[*v1apps.Deployment](ctrl) + mockDeploymentCache.EXPECT().Get(namespace.System, "rancher").DoAndReturn(func(namespace, name string) (*v1apps.Deployment, error) { + return &v1apps.Deployment{ + Spec: v1apps.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "rancher", + Ports: []v1.ContainerPort{ + { + HostPort: 8080, + }, + }, + }, + }, + }, + }, + }, + }, nil + }).AnyTimes() + return mockDeploymentCache +} + +func getSecretCacheMock(ctrl *gomock.Controller, namespace, saName string) *ctrlfake.MockCacheInterface[*v1.Secret] { + mockSecretCache := ctrlfake.NewMockCacheInterface[*v1.Secret](ctrl) + selector := labels.Set{"cattle.io/service-account.name": saName}.AsSelector() + mockSecretCache.EXPECT().List(namespace, selector).DoAndReturn(func(namespace string, selector labels.Selector) ([]*v1.Secret, error) { + return []*v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: saName + "-secret", + Annotations: map[string]string{ + "kubernetes.io/service-account.name": saName, + }, + Labels: map[string]string{ + "cattle.io/service-account.name": saName, + }, + }, + Immutable: nil, + Data: map[string][]byte{ + "token": []byte("thisismytokenandiwillprotectit"), + }, + StringData: nil, + Type: "kubernetes.io/service-account-token", + }, + }, nil + }).AnyTimes() + return mockSecretCache +} + +func getServiceAccountCacheMock(ctrl *gomock.Controller, namespace, name string) *ctrlfake.MockCacheInterface[*v1.ServiceAccount] { + mockServiceAccountCache := ctrlfake.NewMockCacheInterface[*v1.ServiceAccount](ctrl) + mockServiceAccountCache.EXPECT().Get(namespace, name).DoAndReturn(func(namespace, name string) (*v1.ServiceAccount, error) { + return &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Secrets: []v1.ObjectReference{ + { + Namespace: namespace, + Name: name, + }, + }, + }, nil + }).AnyTimes() + return mockServiceAccountCache +} + +func TestShouldCreateBootstrapSecret(t *testing.T) { + tests := []struct { + phase capi.MachinePhase + expected bool + }{ + { + phase: capi.MachinePhasePending, + expected: true, + }, + { + phase: capi.MachinePhaseProvisioning, + expected: true, + }, + { + phase: capi.MachinePhaseProvisioned, + expected: true, + }, + { + phase: capi.MachinePhaseRunning, + expected: true, + }, + { + phase: capi.MachinePhaseDeleting, + expected: false, + }, + { + phase: capi.MachinePhaseDeleted, + expected: false, + }, + { + phase: capi.MachinePhaseFailed, + expected: false, + }, + { + phase: capi.MachinePhaseUnknown, + expected: true, + }, + } + + for _, tt := range tests { + t.Run(string(tt.phase), func(t *testing.T) { + actual := shouldCreateBootstrapSecret(tt.phase) + assert.Equal(t, tt.expected, actual) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/controllers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/controllers.go new file mode 100644 index 0000000..daabbf1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/controllers.go @@ -0,0 +1,47 @@ +package capr + +import ( + "context" + + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/capr/planner" + "github.com/rancher/rancher/pkg/controllers/capr/bootstrap" + "github.com/rancher/rancher/pkg/controllers/capr/dynamicschema" + "github.com/rancher/rancher/pkg/controllers/capr/machinedrain" + "github.com/rancher/rancher/pkg/controllers/capr/machinenodelookup" + "github.com/rancher/rancher/pkg/controllers/capr/machineprovision" + "github.com/rancher/rancher/pkg/controllers/capr/managesystemagent" + plannercontroller "github.com/rancher/rancher/pkg/controllers/capr/planner" + "github.com/rancher/rancher/pkg/controllers/capr/plansecret" + "github.com/rancher/rancher/pkg/controllers/capr/rkecluster" + "github.com/rancher/rancher/pkg/controllers/capr/rkecontrolplane" + "github.com/rancher/rancher/pkg/controllers/capr/unmanaged" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/provisioningv2/systeminfo" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + rkePlanner := planner.New(ctx, clients, planner.InfoFunctions{ + ImageResolver: image.ResolveWithControlPlane, + ReleaseData: capr.GetKDMReleaseData, + SystemAgentImage: settings.SystemAgentInstallerImage.Get, + SystemPodLabelSelectors: systeminfo.NewRetriever(clients).GetSystemPodLabelSelectors, + }) + if features.MCM.Enabled() { + dynamicschema.Register(ctx, clients) + machineprovision.Register(ctx, clients, kubeconfigManager) + } + rkecluster.Register(ctx, clients) + bootstrap.Register(ctx, clients) + machinenodelookup.Register(ctx, clients, kubeconfigManager) + plannercontroller.Register(ctx, clients, rkePlanner) + plansecret.Register(ctx, clients) + unmanaged.Register(ctx, clients, kubeconfigManager) + rkecontrolplane.Register(ctx, clients) + managesystemagent.Register(ctx, clients) + machinedrain.Register(ctx, clients) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/dynamicschema/dynamicschema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/dynamicschema/dynamicschema.go new file mode 100644 index 0000000..999a748 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/dynamicschema/dynamicschema.go @@ -0,0 +1,367 @@ +package dynamicschema + +import ( + "context" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/rancher/wrangler/v3/pkg/data/convert" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemas" + "github.com/rancher/wrangler/v3/pkg/schemas/openapi" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + machineAPIGroup = "rke-machine.cattle.io" + MachineConfigAPIGroup = "rke-machine-config.cattle.io" +) + +type handler struct { + schemaCache mgmtcontrollers.DynamicSchemaCache + schemasController mgmtcontrollers.DynamicSchemaController +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := handler{ + schemaCache: clients.Mgmt.DynamicSchema().Cache(), + schemasController: clients.Mgmt.DynamicSchema(), + } + mgmtcontrollers.RegisterDynamicSchemaGeneratingHandler(ctx, + clients.Mgmt.DynamicSchema(), + clients.Apply.WithCacheTypes(clients.CRD.CustomResourceDefinition()), + "", + "dynamic-driver-crd", + h.OnChange, + &generic.GeneratingHandlerOptions{ + AllowClusterScoped: true, + }) +} + +func getStatusSchema(allSchemas *schemas.Schemas) (*schemas.Schema, error) { + return allSchemas.Import(rkev1.RKEMachineStatus{}) +} + +func addConfigSchema(name string, specSchema *schemas.Schema, allSchemas *schemas.Schemas) (string, error) { + nodeConfigFields := removeKey(specSchema.ResourceFields, "common") + nodeConfigFields = removeKey(nodeConfigFields, "providerID") + + // check if the infra provider supports Windows + // and add the OS field to an infra provider node's config + if capr.WindowsCheck(name) { + nodeConfigFields = addField(specSchema.ResourceFields, name, "os") + } + + id := name + "Config" + return id, allSchemas.AddSchema(schemas.Schema{ + ID: id, + ResourceFields: nodeConfigFields, + }) +} + +func addMachineSchema(name string, specSchema, statusSchema *schemas.Schema, allSchemas *schemas.Schemas) (string, error) { + id := name + "Machine" + return id, allSchemas.AddSchema(schemas.Schema{ + ID: id, + ResourceFields: map[string]schemas.Field{ + "spec": { + Type: specSchema.ID, + }, + "status": { + Type: statusSchema.ID, + }, + }, + }) +} + +func addMachineTemplateSchema(name string, specSchema *schemas.Schema, allSchemas *schemas.Schemas) (string, error) { + templateTemplateSpecSchemaID := name + "MachineTemplateTemplateSpec" + err := allSchemas.AddSchema(schemas.Schema{ + ID: templateTemplateSpecSchemaID, + ResourceFields: map[string]schemas.Field{ + "spec": { + Type: specSchema.ID, + }, + }, + }) + if err != nil { + return "", err + } + + templateSpecSchemaID := name + "MachineTemplateTemplate" + err = allSchemas.AddSchema(schemas.Schema{ + ID: templateSpecSchemaID, + ResourceFields: map[string]schemas.Field{ + "template": { + Type: templateTemplateSpecSchemaID, + }, + "clusterName": { + Type: "string", + }, + }, + }) + if err != nil { + return "", err + } + + id := name + "MachineTemplate" + return id, allSchemas.AddSchema(schemas.Schema{ + ID: id, + ResourceFields: map[string]schemas.Field{ + "spec": { + Type: templateSpecSchemaID, + }, + }, + }) +} + +func getSchemas(name string, spec *v3.DynamicSchemaSpec) (string, string, string, *schemas.Schemas, error) { + allSchemas, err := schemas.NewSchemas() + if err != nil { + return "", "", "", nil, err + } + + configSpecSchema, err := getConfigSchemas(name, allSchemas, spec) + if err != nil { + return "", "", "", nil, err + } + + specSchema, err := getSpecSchemas(name, allSchemas, spec) + if err != nil { + return "", "", "", nil, err + } + + statusSchema, err := getStatusSchema(allSchemas) + if err != nil { + return "", "", "", nil, err + } + + nodeConfigID, err := addConfigSchema(name, configSpecSchema, allSchemas) + if err != nil { + return "", "", "", nil, err + } + + templateID, err := addMachineTemplateSchema(name, specSchema, allSchemas) + if err != nil { + return "", "", "", nil, err + } + + machineID, err := addMachineSchema(name, specSchema, statusSchema, allSchemas) + if err != nil { + return "", "", "", nil, err + } + + return nodeConfigID, templateID, machineID, allSchemas, nil +} + +func removeKey(fields map[string]schemas.Field, key string) map[string]schemas.Field { + result := map[string]schemas.Field{} + for k, v := range fields { + if k != key { + result[k] = v + } + } + return result +} + +func addField(rFields map[string]schemas.Field, name, newField string) map[string]schemas.Field { + newf := rFields + if _, ok := newf[newField]; !ok { + newf[newField] = schemas.Field{ + Type: "string", + Create: true, + Update: true, + } + } + return newf +} + +func getConfigSchemas(name string, allSchemas *schemas.Schemas, spec *v3.DynamicSchemaSpec) (*schemas.Schema, error) { + specSchema := schemas.Schema{} + if err := convert.ToObj(spec, &specSchema); err != nil { + return nil, err + } + specSchema.ID = name + "ConfigSpec" + + commonField, err := allSchemas.Import(rkev1.RKECommonNodeConfig{}) + if err != nil { + return nil, err + } + + if specSchema.ResourceFields == nil { + specSchema.ResourceFields = map[string]schemas.Field{} + } + + specSchema.ResourceFields["common"] = schemas.Field{ + Type: commonField.ID, + } + + specSchema.ResourceFields["providerID"] = schemas.Field{ + Type: "string", + } + + for name, field := range specSchema.ResourceFields { + defMap, ok := field.Default.(map[string]interface{}) + if !ok { + continue + } + + // set to nil because if map is len() == 0 + field.Default = nil + + // Only add defaults for config objects, defaults will be handled for machines and machine templates based on config + switch field.Type { + case "string", "password": + field.Default = defMap["stringValue"] + case "int": + field.Default = defMap["intValue"] + case "boolean": + field.Default = defMap["boolValue"] + case "array[string]": + field.Default = defMap["stringSliceValue"] + } + + specSchema.ResourceFields[name] = field + } + + if err := allSchemas.AddSchema(specSchema); err != nil { + return nil, err + } + + return allSchemas.Schema(specSchema.ID), nil +} + +func getSpecSchemas(name string, allSchemas *schemas.Schemas, spec *v3.DynamicSchemaSpec) (*schemas.Schema, error) { + specSchema := schemas.Schema{} + if err := convert.ToObj(spec, &specSchema); err != nil { + return nil, err + } + specSchema.ID = name + "Spec" + + commonField, err := allSchemas.Import(rkev1.RKECommonNodeConfig{}) + if err != nil { + return nil, err + } + + if specSchema.ResourceFields == nil { + specSchema.ResourceFields = map[string]schemas.Field{} + } + + specSchema.ResourceFields["common"] = schemas.Field{ + Type: commonField.ID, + } + + specSchema.ResourceFields["providerID"] = schemas.Field{ + Type: "string", + } + + for name, field := range specSchema.ResourceFields { + // Clear all defaults, defaults will be handled for machines and machine templates based on config objects + field.Default = nil + specSchema.ResourceFields[name] = field + } + + if err := allSchemas.AddSchema(specSchema); err != nil { + return nil, err + } + + return allSchemas.Schema(specSchema.ID), nil +} + +func (h *handler) OnChange(obj *v3.DynamicSchema, status v3.DynamicSchemaStatus) ([]runtime.Object, v3.DynamicSchemaStatus, error) { + if obj.Name == "nodetemplateconfig" { + all, err := h.schemaCache.List(labels.Everything()) + if err != nil { + return nil, status, err + } + for _, schema := range all { + if schema.Name == "nodetemplateconfig" { + continue + } + h.schemasController.Enqueue(schema.Name) + } + } + + name, node, _, err := h.getStyle(obj.Name) + if err != nil { + return nil, status, err + } + + if !node { // only support nodes right now && !cluster { + return nil, status, nil + } + + nodeConfigID, templateID, machineID, schemas, err := getSchemas(name, &obj.Spec) + if err != nil { + return nil, status, err + } + + var result []runtime.Object + + for _, id := range []string{nodeConfigID, templateID, machineID} { + props, err := openapi.ToOpenAPI(id, schemas) + if err != nil { + return nil, status, err + } + + _, ok := props.Properties["status"] + crd := crd.CRD{ + GVK: schema.GroupVersionKind{ + Group: machineAPIGroup, + Version: rkev1.SchemeGroupVersion.Version, + Kind: convert.Capitalize(id), + }, + Schema: props, + Labels: map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + "auth.cattle.io/cluster-indexed": "true", + }, + Status: ok, + } + + if nodeConfigID == id { + crd.GVK.Group = MachineConfigAPIGroup + } + + crdObj, err := crd.ToCustomResourceDefinition() + if err != nil { + return nil, status, err + } + result = append(result, crdObj) + } + + return result, status, nil +} + +func (h *handler) getStyle(name string) (string, bool, bool, error) { + if !strings.HasSuffix(name, "config") { + return "", false, false, nil + } + + for _, typeName := range []string{"nodetemplateconfig", "cluster"} { + schema, err := h.schemaCache.Get(typeName) + if apierror.IsNotFound(err) { + continue + } else if err != nil { + return "", false, false, err + } + for key := range schema.Spec.ResourceFields { + if strings.EqualFold(key, name) { + return strings.TrimSuffix(key, "Config"), + typeName == "nodetemplateconfig", + typeName == "cluster", + nil + } + } + } + + return "", false, false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/etcdmgmt/saferemoval.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/etcdmgmt/saferemoval.go new file mode 100644 index 0000000..efc4820 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/etcdmgmt/saferemoval.go @@ -0,0 +1,51 @@ +package etcdmgmt + +import ( + "context" + + "github.com/sirupsen/logrus" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/retry" +) + +func SafelyRemoved(restConfig *rest.Config, runtime, nodeName string) (bool, error) { + removeAnnotation := "etcd." + runtime + ".cattle.io/remove" + removedNodeNameAnnotation := "etcd." + runtime + ".cattle.io/removed-node-name" + + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return false, err + } + + logrus.Debugf("Retrieving node %s from K8s", nodeName) + + node, err := clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + if err != nil { + if apierror.IsNotFound(err) { + logrus.Debugf("Node %s was not found. proceeding with deletion", nodeName) + return true, nil + } + return false, err + } + + if node.Annotations[removeAnnotation] == "true" { + // check val to see if it's true, if not, continue + // check the status of the removal + logrus.Debugf("etcd member removal is currently in progress per the annotation %s", removeAnnotation) + return node.Annotations[removedNodeNameAnnotation] != "", nil + } + // The remove annotation has not been set to true, so we'll go ahead and set it on the node. + return false, retry.RetryOnConflict(retry.DefaultRetry, + func() error { + node, err = clientset.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}) + if err != nil { + return err + } + node.Annotations[removeAnnotation] = "true" + _, err = clientset.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{}) + return err + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinedrain/machinedrain.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinedrain/machinedrain.go new file mode 100644 index 0000000..4751c3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinedrain/machinedrain.go @@ -0,0 +1,286 @@ +package machinedrain + +import ( + "context" + "encoding/json" + "fmt" + "os" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/retry" + "k8s.io/kubectl/pkg/drain" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type handler struct { + ctx context.Context + machineCache capicontrollers.MachineCache + secrets corecontrollers.SecretClient + secretCache corecontrollers.SecretCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + ctx: ctx, + machineCache: clients.CAPI.Machine().Cache(), + secrets: clients.Core.Secret(), + secretCache: clients.Core.Secret().Cache(), + } + + clients.Core.Secret().OnChange(ctx, "machine-drain", h.OnChange) +} + +func (h *handler) OnChange(_ string, secret *corev1.Secret) (*corev1.Secret, error) { + if secret == nil || secret.DeletionTimestamp != nil || secret.Labels[capr.MachineNameLabel] == "" || secret.Type != capr.SecretTypeMachinePlan { + return secret, nil + } + + machine, err := h.machineCache.Get(secret.Namespace, secret.Labels[capr.MachineNameLabel]) + if err != nil { + return secret, err + } + + oldSecret := secret.DeepCopy() + defer func() { + if secret == nil || secret.Annotations == nil { + secret = oldSecret + } + drainErrorValue, ok := secret.Annotations[capr.DrainErrorAnnotation] + if err == nil && !ok || err != nil && drainErrorValue == err.Error() { + // No need to update the machine if the annotation is already set to the correct value + return + } + + secret = secret.DeepCopy() + if err != nil { + secret.Annotations[capr.DrainErrorAnnotation] = err.Error() + } else { + delete(secret.Annotations, capr.DrainErrorAnnotation) + } + + var updateErr error + if secret, updateErr = h.secrets.Update(secret); updateErr != nil && err == nil { + err = updateErr + } else if updateErr != nil { + err = fmt.Errorf("failed to update secret (%v) after drain error: %v", updateErr, err) + } + }() + + drain := secret.Annotations[capr.DrainAnnotation] + if drain != "" && secret.Annotations[capr.DrainDoneAnnotation] != drain { + secret, err = h.drain(secret, machine, drain) + } else if secret.Annotations[capr.UnCordonAnnotation] != "" { + // Only check that it's non-blank. There is no correlation between the drain and unDrain options, meaning + // that the option values do not need to match. For drain we track the status by doing the drain annotation + // and then adding a drain-done annotation with the same value when it's done. Uncordon is different in that + // we want the final state to have no annotations. So when UnCordonAnnotation is set we run and then when + // it's done we delete it. So there is no knowledge of what the value should be except that it's set. + secret, err = h.unDrain(secret, machine, drain) + } + + return secret, err +} + +func (h *handler) k8sClient(machine *capi.Machine) (kubernetes.Interface, error) { + secret, err := h.secretCache.Get(machine.Namespace, name.SafeConcatName(machine.Spec.ClusterName, "kubeconfig")) + if err != nil { + return nil, err + } + + restConfig, err := clientcmd.RESTConfigFromKubeConfig(secret.Data["value"]) + if err != nil { + return nil, err + } + + return kubernetes.NewForConfig(restConfig) +} + +func (h *handler) unDrain(secret *corev1.Secret, machine *capi.Machine, drainData string) (*corev1.Secret, error) { + if machine.Status.NodeRef == nil || machine.Status.NodeRef.Name == "" { + logrus.Debugf("unable to drain machine %s as there is no noderef", machine.Name) + return secret, nil + } + + var drainOpts rkev1.DrainOptions + if err := json.Unmarshal([]byte(drainData), &drainOpts); err != nil { + return secret, err + } + + checkPostDrainHooks := checkHookAnnotations(drainData, drainOpts.PostDrainHooks) + if len(drainOpts.PostDrainHooks) > 0 { + postDrainAnnDoesNotHaveValue := secretAnnotationDoesNotHaveValue(capr.PostDrainAnnotation, drainData) + if postDrainAnnDoesNotHaveValue(secret) { + return h.updateSecretAnnotationIfCheckTrue(secret, capr.PostDrainAnnotation, drainData, postDrainAnnDoesNotHaveValue) + } else if !checkPostDrainHooks(secret) { + return secret, nil + } + } + + helper, node, err := h.getHelper(machine, drainOpts) + if err != nil { + return nil, err + } + + if err := drain.RunCordonOrUncordon(helper, node, false); err != nil { + return nil, err + } + + // Drain/Undrain operations are done so clear all annotations involved + return h.cleanSecretAnnotationsIfCheckTrue(secret, drainOpts, checkPostDrainHooks) +} + +func (h *handler) drain(secret *corev1.Secret, machine *capi.Machine, drainData string) (*corev1.Secret, error) { + drainOpts := &rkev1.DrainOptions{} + if err := json.Unmarshal([]byte(drainData), drainOpts); err != nil { + return nil, err + } + + if err := h.cordon(machine, drainOpts); err != nil { + return secret, err + } + + checkPreDrainHooks := checkHookAnnotations(drainData, drainOpts.PreDrainHooks) + if len(drainOpts.PreDrainHooks) > 0 { + preDrainAnnDoesNotHaveValue := secretAnnotationDoesNotHaveValue(capr.PreDrainAnnotation, drainData) + if preDrainAnnDoesNotHaveValue(secret) { + return h.updateSecretAnnotationIfCheckTrue(secret, capr.PreDrainAnnotation, drainData, preDrainAnnDoesNotHaveValue) + } else if !checkPreDrainHooks(secret) { + return secret, nil + } + } + + if drainOpts.Enabled { + if err := h.performDrain(machine, drainOpts); err != nil { + return nil, err + } + } + + return h.updateSecretAnnotationIfCheckTrue(secret, capr.DrainDoneAnnotation, drainData, checkPreDrainHooks) +} + +func (h *handler) cordon(machine *capi.Machine, drainOpts *rkev1.DrainOptions) error { + if machine.Status.NodeRef == nil || machine.Status.NodeRef.Name == "" { + return nil + } + + helper, node, err := h.getHelper(machine, *drainOpts) + if err != nil { + return err + } + + return drain.RunCordonOrUncordon(helper, node, true) +} + +func (h *handler) getHelper(machine *capi.Machine, drainOpts rkev1.DrainOptions) (*drain.Helper, *corev1.Node, error) { + k8s, err := h.k8sClient(machine) + if err != nil { + return nil, nil, err + } + + timeout := drainOpts.Timeout + if timeout == 0 { + timeout = 600 + } + + helper := &drain.Helper{ + Ctx: h.ctx, + Client: k8s, + Force: drainOpts.Force, + GracePeriodSeconds: drainOpts.GracePeriod, + IgnoreAllDaemonSets: drainOpts.IgnoreDaemonSets == nil || *drainOpts.IgnoreDaemonSets, + Timeout: time.Duration(timeout) * time.Second, + DeleteEmptyDirData: drainOpts.DeleteEmptyDirData, + DisableEviction: drainOpts.DisableEviction, + SkipWaitForDeleteTimeoutSeconds: drainOpts.SkipWaitForDeleteTimeoutSeconds, + Out: os.Stdout, + ErrOut: os.Stderr, + } + + node, err := k8s.CoreV1().Nodes().Get(h.ctx, machine.Status.NodeRef.Name, metav1.GetOptions{}) + if err != nil { + return nil, nil, err + } + + return helper, node, err +} + +func (h *handler) performDrain(machine *capi.Machine, drainOpts *rkev1.DrainOptions) error { + if machine.Status.NodeRef == nil || machine.Status.NodeRef.Name == "" { + return nil + } + + helper, node, err := h.getHelper(machine, *drainOpts) + if err != nil { + return err + } + + return drain.RunNodeDrain(helper, node.Name) +} + +func (h *handler) updateSecretAnnotationIfCheckTrue(secret *corev1.Secret, annotation, value string, check func(*corev1.Secret) bool) (*corev1.Secret, error) { + var err error + return secret, retry.RetryOnConflict(retry.DefaultRetry, func() error { + secret, err = h.secrets.Get(secret.Namespace, secret.Name, metav1.GetOptions{}) + // If there is an error, the check function passes, or the annotation is already set, then return. + if err != nil || !check(secret) || secret.Annotations[annotation] == value { + return err + } + secret = secret.DeepCopy() + secret.Annotations[annotation] = value + _, err = h.secrets.Update(secret) + return err + }) +} + +func (h *handler) cleanSecretAnnotationsIfCheckTrue(secret *corev1.Secret, drainOpts rkev1.DrainOptions, check func(*corev1.Secret) bool) (*corev1.Secret, error) { + var err error + return secret, retry.RetryOnConflict(retry.DefaultRetry, func() error { + secret, err = h.secrets.Get(secret.Namespace, secret.Name, metav1.GetOptions{}) + // If there is an error, the check function passes, or the annotation is already set, then return. + if err != nil || !check(secret) { + return err + } + secret = secret.DeepCopy() + delete(secret.Annotations, capr.PreDrainAnnotation) + delete(secret.Annotations, capr.PostDrainAnnotation) + delete(secret.Annotations, capr.DrainAnnotation) + delete(secret.Annotations, capr.DrainDoneAnnotation) + delete(secret.Annotations, capr.UnCordonAnnotation) + for _, hook := range drainOpts.PreDrainHooks { + delete(secret.Annotations, hook.Annotation) + } + for _, hook := range drainOpts.PostDrainHooks { + delete(secret.Annotations, hook.Annotation) + } + _, err = h.secrets.Update(secret) + return err + }) +} + +func secretAnnotationDoesNotHaveValue(annotation, value string) func(*corev1.Secret) bool { + return func(secret *corev1.Secret) bool { + return secret.Annotations[annotation] != value + } +} + +func checkHookAnnotations(drainData string, hooks []rkev1.DrainHook) func(secret *corev1.Secret) bool { + return func(secret *corev1.Secret) bool { + for _, hook := range hooks { + if hook.Annotation != "" && secret.Annotations[hook.Annotation] != drainData { + return false + } + } + return true + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinenodelookup/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinenodelookup/controller.go new file mode 100644 index 0000000..3849378 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machinenodelookup/controller.go @@ -0,0 +1,168 @@ +package machinenodelookup + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/rancher/lasso/pkg/dynamic" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + ranchercontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/summary" + "github.com/sirupsen/logrus" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" +) + +const ( + nodeErrorEnqueueTime = 15 * time.Second +) + +var ( + bootstrapAPIVersion = fmt.Sprintf("%s/%s", rkev1.SchemeGroupVersion.Group, rkev1.SchemeGroupVersion.Version) +) + +type handler struct { + rancherClusterCache ranchercontrollers.ClusterCache + machineCache capicontrollers.MachineCache + machines capicontrollers.MachineController + rkeBootstrap rkecontroller.RKEBootstrapController + kubeconfigManager *kubeconfig.Manager + dynamic *dynamic.Controller +} + +func Register(ctx context.Context, clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + h := &handler{ + rancherClusterCache: clients.Provisioning.Cluster().Cache(), + machines: clients.CAPI.Machine(), + machineCache: clients.CAPI.Machine().Cache(), + rkeBootstrap: clients.RKE.RKEBootstrap(), + kubeconfigManager: kubeconfigManager, + dynamic: clients.Dynamic, + } + + clients.RKE.RKEBootstrap().OnChange(ctx, "machine-node-lookup", h.associateMachineWithNode) +} + +// associateMachineWithNode back-populates the provider ID and addresses from the K8s v1 Node object onto the +// corresponding infrastructure machine object that is referenced by the bootstrap. +func (h *handler) associateMachineWithNode(_ string, bootstrap *rkev1.RKEBootstrap) (*rkev1.RKEBootstrap, error) { + if bootstrap == nil || bootstrap.DeletionTimestamp != nil { + return bootstrap, nil + } + + if !bootstrap.Status.Ready || bootstrap.Status.DataSecretName == nil || *bootstrap.Status.DataSecretName == "" { + return bootstrap, nil + } + + machine, err := capr.GetMachineByOwner(h.machineCache, bootstrap) + if err != nil { + if errors.Is(err, capr.ErrNoMachineOwnerRef) { + return bootstrap, generic.ErrSkip + } + return bootstrap, err + } + + if machine.Spec.ProviderID != nil && *machine.Spec.ProviderID != "" { + // If the machine already has its provider ID set, then we do not need to continue + return bootstrap, nil + } + + gvk := schema.FromAPIVersionAndKind(machine.Spec.InfrastructureRef.APIVersion, machine.Spec.InfrastructureRef.Kind) + infra, err := h.dynamic.Get(gvk, machine.Namespace, machine.Spec.InfrastructureRef.Name) + if apierror.IsNotFound(err) { + return bootstrap, nil + } else if err != nil { + return bootstrap, err + } + + d, err := data.Convert(infra) + if err != nil { + return bootstrap, err + } + + // Do not mutate the infrastructure machine object if it is not marked as Ready, otherwise it will cause the + // controller to potentially re-run the provision job + if c := getCondition(d, "Ready"); c == nil || (c != nil && strings.ToLower(c.Status()) != "true") { + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, nodeErrorEnqueueTime) + return bootstrap, nil + } + + rancherCluster, err := h.rancherClusterCache.Get(machine.Namespace, machine.Spec.ClusterName) + if err != nil { + return bootstrap, err + } + + config, err := h.kubeconfigManager.GetRESTConfig(rancherCluster, rancherCluster.Status) + if err != nil { + return bootstrap, err + } + + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + return bootstrap, err + } + + nodeLabelSelector := metav1.LabelSelector{MatchLabels: map[string]string{capr.MachineUIDLabel: string(machine.GetUID())}} + nodes, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: labels.Set(nodeLabelSelector.MatchLabels).String()}) + if err != nil || len(nodes.Items) == 0 || nodes.Items[0].Spec.ProviderID == "" || !condition.Cond("Ready").IsTrue(nodes.Items[0]) { + logrus.Debugf("Searching for providerID for selector %s in cluster %s/%s, machine %s: %v", + labels.Set(nodeLabelSelector.MatchLabels), rancherCluster.Namespace, rancherCluster.Name, machine.Name, err) + h.rkeBootstrap.EnqueueAfter(bootstrap.Namespace, bootstrap.Name, nodeErrorEnqueueTime) + return bootstrap, nil + } + + node := &nodes.Items[0] + + if d.String("spec", "providerID") != node.Spec.ProviderID { + obj, err := data.Convert(infra.DeepCopyObject()) + if err != nil { + return bootstrap, err + } + + obj.SetNested(node.Status.Addresses, "status", "addresses") + newObj, err := h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: obj, + }) + if err != nil { + return bootstrap, err + } + + obj, err = data.Convert(newObj) + if err != nil { + return bootstrap, err + } + + obj.SetNested(node.Spec.ProviderID, "spec", "providerID") + _, err = h.dynamic.Update(&unstructured.Unstructured{ + Object: obj, + }) + return bootstrap, err + } + + return bootstrap, nil +} + +func getCondition(d data.Object, conditionType string) *summary.Condition { + for _, cond := range summary.GetUnstructuredConditions(d) { + if cond.Type() == conditionType { + return &cond + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args.go new file mode 100644 index 0000000..38d6f96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args.go @@ -0,0 +1,420 @@ +package machineprovision + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "os" + "path/filepath" + "regexp" + "sort" + "strconv" + "strings" + + mgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/management/drivers" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + wranglername "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + awsClusterTagPrefix = "kubernetes.io/cluster/" +) + +var ( + regExHyphen = regexp.MustCompile("([a-z])([A-Z])") + envNameOverride = map[string]string{ + "amazonec2": "AWS", + "rackspace": "OS", + "openstack": "OS", + "vmwarevsphere": "VSPHERE", + "vmwarefusion": "FUSION", + "vmwarevcloudair": "VCLOUDAIR", + } +) + +type driverArgs struct { + rkev1.RKEMachineStatus + + DriverName string + ImageName string + CapiMachineName string + MachineName string + MachineNamespace string + MachineGVK schema.GroupVersionKind + ImagePullPolicy corev1.PullPolicy + EnvSecret *corev1.Secret + FilesSecret *corev1.Secret + CertsSecret *corev1.Secret + StateSecretName string + BootstrapSecretName string + BootstrapRequired bool + Args []string + BackoffLimit int32 +} + +func (h *handler) getArgsEnvAndStatus(infra *infraObject, args map[string]any, driver string, create bool) (driverArgs, error) { + var ( + url, hash, cloudCredentialSecretName string + jobBackoffLimit int32 + filesSecret *corev1.Secret + ) + + nd, err := h.nodeDriverCache.Get(driver) + if !create && apierrors.IsNotFound(err) { + url = infra.data.String("status", "driverURL") + hash = infra.data.String("status", "driverHash") + } else if err != nil { + return driverArgs{}, err + } else if !strings.HasPrefix(nd.Spec.URL, "local://") { + url, hash, err = getDriverDownloadURL(nd) + if err != nil { + return driverArgs{}, err + } + } + + envSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: wranglername.SafeConcatName(infra.meta.GetName(), "machine", "driver", "secret"), + Namespace: infra.meta.GetNamespace(), + }, + Data: getWhitelistedEnvVars(), + } + // the owner reference may be deleted if the machine is cleaned up forcefully + machineName := infra.meta.GetLabels()[CapiMachineName] + machine, err := h.machineCache.Get(infra.meta.GetNamespace(), machineName) + if err != nil { + return driverArgs{}, err + } + + bootstrapName, cloudCredentialSecretName, secrets, err := h.getSecretData(machine, infra.data, create) + if err != nil { + return driverArgs{}, err + } + + for k, v := range secrets { + _, k = kv.RSplit(k, "-") + envName := envNameOverride[driver] + if envName == "" { + envName = driver + } + k := strings.ToUpper(envName + "_" + regExHyphen.ReplaceAllString(k, "${1}_${2}")) + envSecret.Data[k] = []byte(v) + } + secretName := capr.MachineStateSecretName(infra.meta.GetName()) + + cmd := []string{ + fmt.Sprintf("--driver-download-url=%s", url), + fmt.Sprintf("--driver-hash=%s", hash), + fmt.Sprintf("--secret-namespace=%s", infra.meta.GetNamespace()), + fmt.Sprintf("--secret-name=%s", secretName), + } + + instanceName := getInstanceName(*infra) + + // The files secret must be constructed before toArgs is called because + // constructFilesSecret replaces file contents and creates a secret to be passed as a volume. + filesSecret = constructFilesSecret(driver, args) + if create { + cmd = append(cmd, "create", + fmt.Sprintf("--driver=%s", driver), + fmt.Sprintf("--custom-install-script=/run/secrets/machine/value")) + + hostname := getHostname(*infra) + if hostname != instanceName { + cmd = append(cmd, fmt.Sprintf("--hostname-override=%s", hostname)) + } + + rancherCluster, err := h.rancherClusterCache.Get(infra.meta.GetNamespace(), infra.meta.GetLabels()[capi.ClusterNameLabel]) + if err != nil { + return driverArgs{}, err + } + cmd = append(cmd, toArgs(driver, args, rancherCluster.Status.ClusterName)...) + } else { + // We're passing the `--update-config` flag here along with driver-specific flags to tell Rancher Machine + // to reload the driver-specific flags we pass via envvars. They need to be reloaded to account for cases + // were configuration used by Rancher machine (namely cloud credentials) change while the machine is still running. + // If we didn't do this, a user could create a machine and change the cloud credential it uses, leaving Rancher + // unable to remove the machine afterward because Rancher machine will always use the old credential it stored on + // machine creation. + cmd = append(cmd, "rm", "-y", "--update-config") + jobBackoffLimit = 3 + } + + certsSecret, err := h.constructCertsSecret(infra.meta.GetName(), infra.meta.GetNamespace()) + if err != nil { + return driverArgs{}, err + } + + cmd = append(cmd, instanceName) + + return driverArgs{ + DriverName: driver, + CapiMachineName: machineName, + MachineName: infra.meta.GetName(), + MachineNamespace: infra.meta.GetNamespace(), + MachineGVK: infra.obj.GetObjectKind().GroupVersionKind(), + ImageName: settings.PrefixPrivateRegistry(settings.MachineProvisionImage.Get()), + ImagePullPolicy: settings.GetMachineProvisionImagePullPolicy(), + EnvSecret: envSecret, + FilesSecret: filesSecret, + CertsSecret: certsSecret, + StateSecretName: secretName, + BootstrapSecretName: bootstrapName, + BootstrapRequired: create, + Args: cmd, + BackoffLimit: jobBackoffLimit, + RKEMachineStatus: rkev1.RKEMachineStatus{ + Ready: infra.data.String("spec", "providerID") != "", + DriverHash: hash, + DriverURL: url, + CloudCredentialSecretName: cloudCredentialSecretName, + }, + }, nil +} + +func (h *handler) getBootstrapSecret(machine *capi.Machine) (string, error) { + if machine == nil || machine.Spec.Bootstrap.ConfigRef == nil { + return "", nil + } + + gvk := schema.FromAPIVersionAndKind(machine.Spec.Bootstrap.ConfigRef.APIVersion, + machine.Spec.Bootstrap.ConfigRef.Kind) + bootstrap, err := h.dynamic.Get(gvk, machine.Namespace, machine.Spec.Bootstrap.ConfigRef.Name) + if apierrors.IsNotFound(err) { + return "", nil + } else if err != nil { + return "", err + } + + d, err := data.Convert(bootstrap) + if err != nil { + return "", err + } + return d.String("status", "dataSecretName"), nil +} + +func (h *handler) getSecretData(machine *capi.Machine, obj data.Object, create bool) (string, string, map[string]string, error) { + var ( + err error + result = map[string]string{} + ) + + oldCredential := obj.String("status", "cloudCredentialSecretName") + cloudCredentialSecretName := obj.String("spec", "common", "cloudCredentialSecretName") + + if machine == nil && create { + return "", "", nil, generic.ErrSkip + } + + if cloudCredentialSecretName == "" { + cloudCredentialSecretName = oldCredential + } + + if cloudCredentialSecretName != "" && machine != nil { + secret, err := GetCloudCredentialSecret(h.secrets, machine.GetNamespace(), cloudCredentialSecretName) + if err != nil { + return "", "", nil, err + } + + for k, v := range secret.Data { + result[k] = string(v) + } + } + + bootstrapName, err := h.getBootstrapSecret(machine) + if err != nil { + return "", "", nil, err + } + + return bootstrapName, cloudCredentialSecretName, result, nil +} + +func GetCloudCredentialSecret(secrets corecontrollers.SecretCache, ns, name string) (*corev1.Secret, error) { + globalNS, globalName := kv.Split(name, ":") + if globalName != "" && globalNS == namespace.GlobalNamespace { + return secrets.Get(globalNS, globalName) + } + return secrets.Get(ns, name) +} + +// addAwsClusterOwnedTag will add a tag to the machine arguments of an AWS machine of the form +// "kubernetes.io/cluster/c-m-xxxxxxx,owned" if an owned or shared tag is not already present, which is required for +// cloud provider integration. +// If a user supplies their own tag it is assumed that the default behavior is not needed +// as it is impossible to have an "owned" tag on a resource with another "owned" or "shared tag. +// If args is empty, the value is always added, otherwise it is only added if there is no conflict. +// args is always updated in place. +func addAwsClusterOwnedTag(args map[string]any, clusterID string) { + tagValue := fmt.Sprintf("%s%s,owned", awsClusterTagPrefix, clusterID) + if tags, ok := args["tags"]; !ok || convert.ToString(tags) == "" { + args["tags"] = tagValue + logrus.Tracef("Adding cluster id tag [%s] to machine args", tagValue) + } else { + tagString := convert.ToString(tags) + if !strings.Contains(tagString, awsClusterTagPrefix) { + logrus.Tracef("Appending cluster id tag [%s] to machine args", tagValue) + args["tags"] = tagString + "," + tagValue + } + } +} + +func toArgs(driverName string, args map[string]any, clusterID string) (cmd []string) { + if driverName == "amazonec2" { + addAwsClusterOwnedTag(args, clusterID) + } + + for k, v := range args { + // Don't render providerID into the arguments, as this is only a cluster-api required field. + if k == "providerID" { + continue + } + + dmField := "--" + driverName + "-" + strings.ToLower(regExHyphen.ReplaceAllString(k, "${1}-${2}")) + if v == nil { + continue + } + + switch v.(type) { + case float64: + cmd = append(cmd, fmt.Sprintf("%s=%v", dmField, v)) + case string: + if v.(string) != "" { + cmd = append(cmd, fmt.Sprintf("%s=%s", dmField, v.(string))) + } + case bool: + if v.(bool) { + cmd = append(cmd, dmField) + } + case []interface{}: + for _, s := range v.([]interface{}) { + if _, ok := s.(string); ok { + cmd = append(cmd, fmt.Sprintf("%s=%s", dmField, s.(string))) + } + } + } + } + + if driverName == "amazonec2" && + convert.ToString(args["securityGroup"]) != "rancher-nodes" && + args["securityGroupReadonly"] == nil { + cmd = append(cmd, "--amazonec2-security-group-readonly") + } + + sort.Strings(cmd) + return +} + +func getNodeDriverName(typeMeta meta.Type) string { + return strings.ToLower(strings.TrimSuffix(typeMeta.GetKind(), "Machine")) +} + +// getDriverDownloadURL checks for a local version of the driver to download for air-gapped installs. +// If no local version is found or CATTLE_DEV_MODE is set, then the URL from the node driver is returned. +func getDriverDownloadURL(nd *mgmtv3.NodeDriver) (string, string, error) { + if os.Getenv("CATTLE_DEV_MODE") != "" { + return nd.Spec.URL, nd.Spec.Checksum, nil + } + + driverName := nd.Name + if !strings.HasPrefix(driverName, drivers.DockerMachineDriverPrefix) { + driverName = drivers.DockerMachineDriverPrefix + driverName + } + + path := filepath.Join(settings.UIPath.Get(), "assets", driverName) + if _, err := os.Stat(path); err != nil { + return nd.Spec.URL, nd.Spec.Checksum, nil + } + + hash, err := hashFile(path) + if err != nil { + return "", "", err + } + + return fmt.Sprintf("%s/assets/%s", settings.ServerURL.Get(), driverName), hash, nil +} + +func hashName(name string) string { + b := sha256.Sum256([]byte(name)) + return hex.EncodeToString(b[:16]) +} + +func hashFile(path string) (string, error) { + hasher := sha256.New() + f, err := os.Open(path) + if err != nil { + return "", err + } + defer f.Close() + + if _, err := io.Copy(hasher, f); err != nil { + return "", err + } + + return hex.EncodeToString(hasher.Sum(nil)), nil +} + +func getWhitelistedEnvVars() map[string][]byte { + result := make(map[string][]byte) + settings.IterateWhitelistedEnvVars(func(name, value string) { + result[name] = []byte(value) + }) + return result +} + +// getHostname will get the hostname for an object, and truncate it if it greater than 63 or if the specified limit +// between 10 and 63, whichever is lower. This truncation uses the wrangler SafeConcatName mechanism to ensure that the +// generated name is both less than or equal to the limit, and distinct by replacing the last six characters of the name +// with a `-`, followed by a 5 character hash of the entire input. +func getHostname(infra infraObject) string { + limit := capr.MaximumHostnameLengthLimit + limitAnno := infra.meta.GetAnnotations()[capr.HostnameLengthLimitAnnotation] + if limitAnno != "" { + l, err := strconv.Atoi(limitAnno) + if err != nil { + logrus.Errorf("[machineprovision] failed to parse annotation %s=%s as int for %s %s/%s: %v", capr.HostnameLengthLimitAnnotation, limitAnno, infra.obj.GetObjectKind(), infra.meta.GetNamespace(), infra.meta.GetName(), err) + } else if l < capr.MinimumHostnameLengthLimit { + logrus.Debugf("[machineprovision] parsed annotation %s was %d, which is less than the minimum of %d", capr.HostnameLengthLimitAnnotation, l, capr.MinimumHostnameLengthLimit) + } else if l > capr.MaximumHostnameLengthLimit { + logrus.Debugf("[machineprovision] parsed annotation %s was %d, which is greater than the maximum of %d", capr.HostnameLengthLimitAnnotation, l, capr.MaximumHostnameLengthLimit) + } else { + limit = l + } + } + + // cloud-init will split the hostname on '.' and set the hostname to the first chunk. This causes an issue where all + // nodes in a machine pool may have the same node name in Kubernetes. Converting the '.' to '-' here prevents this. + hostname := strings.ReplaceAll(infra.meta.GetName(), ".", "-") + hostname = capr.SafeConcatName(limit, hostname) + + return hostname +} + +// getInstanceName will get the instance name for use in rancher/machine's create/delete functions. This name will use +// the wrangler SafeConcatName mechanism to ensure that the generated name is both less than or equal to the limit of 63 +// characters, and distinct by replacing the last six characters of the name with a `-`, followed by a 5 character hash +// of the entire input. +func getInstanceName(infra infraObject) string { + // cloud-init will split the hostname on '.' and set the hostname to the first chunk. This causes an issue where all + // nodes in a machine pool may have the same node name in Kubernetes. Converting the '.' to '-' here prevents this. + instanceName := strings.ReplaceAll(infra.meta.GetName(), ".", "-") + instanceName = wranglername.SafeConcatName(instanceName) + + return instanceName +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args_test.go new file mode 100644 index 0000000..f98361f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/args_test.go @@ -0,0 +1,240 @@ +package machineprovision + +import ( + "fmt" + "testing" + + "github.com/rancher/rancher/pkg/capr" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type TestData struct { + metav1.ObjectMeta +} + +func TestGetInstanceName(t *testing.T) { + + tests := []struct { + name string + data TestData + expected string + }{ + { + name: "Single character name", + data: TestData{ + metav1.ObjectMeta{ + Name: "a", + }, + }, + expected: "a", + }, + { + name: "Period replacement", + data: TestData{ + metav1.ObjectMeta{ + Name: "a.", + }, + }, + expected: "a-", + }, + { + name: "Max length name - 63 characters", + data: TestData{ + metav1.ObjectMeta{ + Name: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678", + }, + }, + expected: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345678", + }, + { + name: "> Max length name - 64 characters", + data: TestData{ + metav1.ObjectMeta{ + Name: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef012-aa23e", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + instanceName := getInstanceName(infraObject{meta: &tt.data}) + assert.Equal(t, tt.expected, instanceName) + }) + } +} + +func TestGetHostname(t *testing.T) { + + tests := []struct { + name string + data TestData + expected string + }{ + { + name: "Single character name - no truncation", + data: TestData{ + metav1.ObjectMeta{ + Name: "a", + }, + }, + expected: "a", + }, + { + name: "Period replacement - no truncation", + data: TestData{ + metav1.ObjectMeta{ + Name: "a.", + }, + }, + expected: "a-", + }, + { + name: "Max length name - 63 characters", + data: TestData{ + metav1.ObjectMeta{ + Name: "abcdef0123456789abcdef0123456789abcdef0123456789abcde0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789abcdef0123456789abcde0123456789", + }, + { + name: "> Max length name - 64 characters", + data: TestData{ + metav1.ObjectMeta{ + Name: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef012-aa23e", + }, + { + name: "32 character name - limit < 32", + data: TestData{ + metav1.ObjectMeta{ + Annotations: map[string]string{ + capr.HostnameLengthLimitAnnotation: "24", + }, + Name: "abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789ab-bc373", + }, + { + name: "32 character name - limit < minimum", + data: TestData{ + metav1.ObjectMeta{ + Annotations: map[string]string{ + capr.HostnameLengthLimitAnnotation: "9", + }, + Name: "abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789", + }, + { + name: "32 character name - limit > maximum", + data: TestData{ + metav1.ObjectMeta{ + Annotations: map[string]string{ + capr.HostnameLengthLimitAnnotation: "64", + }, + Name: "abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789", + }, + { + name: "64 character name - limit > maximum", + data: TestData{ + metav1.ObjectMeta{ + Annotations: map[string]string{ + capr.HostnameLengthLimitAnnotation: "64", + }, + Name: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789", + }, + }, + expected: "abcdef0123456789abcdef0123456789abcdef0123456789abcdef012-aa23e", + }, + { + name: "10 character name - limit < minimum", + data: TestData{ + metav1.ObjectMeta{ + Annotations: map[string]string{ + capr.HostnameLengthLimitAnnotation: "9", + }, + Name: "abcdef0123", + }, + }, + expected: "abcdef0123", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hostname := getHostname(infraObject{meta: &tt.data}) + assert.Equal(t, tt.expected, hostname) + }) + } +} + +func TestAddAwsClusterOwnedTag(t *testing.T) { + testClusterId := "c-m-1234567" + tests := []struct { + name string + args map[string]any + expected map[string]any + }{ + { + name: "no tags", + args: map[string]any{}, + expected: map[string]any{ + "tags": fmt.Sprintf("kubernetes.io/cluster/%s,owned", testClusterId), + }, + }, + { + name: "existing owned tag", + args: map[string]any{ + "tags": "kubernetes.io/cluster/testing,owned", + }, + expected: map[string]any{ + "tags": "kubernetes.io/cluster/testing,owned", + }, + }, + { + name: "existing shared tag", + args: map[string]any{ + "tags": "kubernetes.io/cluster/testing,shared", + }, + expected: map[string]any{ + "tags": "kubernetes.io/cluster/testing,shared", + }, + }, + { + name: "unrelated tags", + args: map[string]any{ + "tags": "rancher.cattle.io/testing,true", + }, + expected: map[string]any{ + "tags": fmt.Sprintf("rancher.cattle.io/testing,true,kubernetes.io/cluster/%s,owned", testClusterId), + }, + }, + { + name: "unrelated and owned tags", + args: map[string]any{ + "tags": "kubernetes.io/cluster/testing,owned,rancher.cattle.io/testing,true", + }, + expected: map[string]any{ + "tags": "kubernetes.io/cluster/testing,owned,rancher.cattle.io/testing,true", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + addAwsClusterOwnedTag(tt.args, testClusterId) + assert.Equal(t, tt.expected, tt.args) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller.go new file mode 100644 index 0000000..6ed118f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller.go @@ -0,0 +1,922 @@ +package machineprovision + +import ( + "context" + "errors" + "fmt" + "path" + "strings" + "time" + + "github.com/rancher/lasso/pkg/dynamic" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/management/drivers/nodedriver" + "github.com/rancher/rancher/pkg/controllers/management/node" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + ranchercontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + batchcontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/batch/v1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/genericcondition" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/summary" + "github.com/sirupsen/logrus" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + capierrors "sigs.k8s.io/cluster-api/errors" + capiannotations "sigs.k8s.io/cluster-api/util/annotations" +) + +const ( + createJobConditionType = "CreateJob" + deleteJobConditionType = "DeleteJob" + + forceRemoveMachineAnn = "provisioning.cattle.io/force-machine-remove" +) + +type infraObject struct { + data data.Object + obj runtime.Object + meta metav1.Object + typeMeta metav1.Type +} + +func newInfraObject(obj runtime.Object) (*infraObject, error) { + copiedObj := obj.DeepCopyObject() + objMeta, err := meta.Accessor(copiedObj) + if err != nil { + return nil, err + } + + data, err := data.Convert(copiedObj) + if err != nil { + return nil, err + } + + typeMeta, err := meta.TypeAccessor(copiedObj) + if err != nil { + return nil, err + } + + return &infraObject{ + data: data, + obj: copiedObj, + meta: objMeta, + typeMeta: typeMeta, + }, nil +} + +type handler struct { + ctx context.Context + apply apply.Apply + jobController batchcontrollers.JobController + jobs batchcontrollers.JobCache + pods corecontrollers.PodCache + secrets corecontrollers.SecretCache + capiClusterCache capicontrollers.ClusterCache + machineCache capicontrollers.MachineCache + machineClient capicontrollers.MachineClient + machineSetCache capicontrollers.MachineSetCache + namespaces corecontrollers.NamespaceCache + nodeDriverCache mgmtcontrollers.NodeDriverCache + dynamic *dynamic.Controller + rancherClusterCache ranchercontrollers.ClusterCache + kubeconfigManager *kubeconfig.Manager +} + +func Register(ctx context.Context, clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + h := &handler{ + ctx: ctx, + apply: clients.Apply.WithCacheTypes(clients.Core.Secret(), + clients.Core.ServiceAccount(), + clients.RBAC.RoleBinding(), + clients.RBAC.Role(), + clients.Batch.Job()), + pods: clients.Core.Pod().Cache(), + jobController: clients.Batch.Job(), + jobs: clients.Batch.Job().Cache(), + secrets: clients.Core.Secret().Cache(), + machineCache: clients.CAPI.Machine().Cache(), + machineClient: clients.CAPI.Machine(), + machineSetCache: clients.CAPI.MachineSet().Cache(), + capiClusterCache: clients.CAPI.Cluster().Cache(), + nodeDriverCache: clients.Mgmt.NodeDriver().Cache(), + namespaces: clients.Core.Namespace().Cache(), + dynamic: clients.Dynamic, + rancherClusterCache: clients.Provisioning.Cluster().Cache(), + kubeconfigManager: kubeconfigManager, + } + + removeHandler := generic.NewRemoveHandler("machine-provision-remove", clients.Dynamic.Update, h.OnRemove) + + clients.Dynamic.OnChange(ctx, "machine-provision-remove", validGVK, dynamic.FromKeyHandler(removeHandler)) + clients.Dynamic.OnChange(ctx, "machine-provision", validGVK, h.OnChange) + clients.Batch.Job().OnChange(ctx, "machine-provision-pod", h.OnJobChange) +} + +func validGVK(gvk schema.GroupVersionKind) bool { + return gvk.Group == "rke-machine.cattle.io" && + gvk.Version == "v1" && + strings.HasSuffix(gvk.Kind, "Machine") && + gvk.Kind != "CustomMachine" +} + +func (h *handler) OnJobChange(_ string, job *batchv1.Job) (*batchv1.Job, error) { + if job == nil { + return nil, nil + } + + name := job.Spec.Template.Labels[InfraMachineName] + group := job.Spec.Template.Labels[InfraMachineGroup] + version := job.Spec.Template.Labels[InfraMachineVersion] + kind := job.Spec.Template.Labels[InfraMachineKind] + + if name == "" || kind == "" { + return job, nil + } + + infraMachine, err := h.dynamic.Get(schema.GroupVersionKind{ + Group: group, + Version: version, + Kind: kind, + }, job.Namespace, name) + if apierrors.IsNotFound(err) { + // ignore err + return job, nil + } else if err != nil { + return job, err + } + + infra, err := newInfraObject(infraMachine) + if err != nil { + return job, err + } + + if infra.data.String("status", "jobName") == "" { + infra.data.SetNested(job.Name, "status", "jobName") + _, err = h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }) + return job, err + } + + // Re-evaluate the infra-machine after this + if err = h.dynamic.Enqueue(infraMachine.GetObjectKind().GroupVersionKind(), + infra.meta.GetNamespace(), infra.meta.GetName()); err != nil { + return job, err + } + + return job, nil +} + +func (h *handler) getMachineStatus(job *batchv1.Job) (rkev1.RKEMachineStatus, error) { + condType := createJobConditionType + if job.Spec.Template.Labels[InfraJobRemove] == "true" { + condType = deleteJobConditionType + } + + if condition.Cond("Complete").IsTrue(job) { + return rkev1.RKEMachineStatus{ + Conditions: []genericcondition.GenericCondition{ + { + Type: condType, + Status: corev1.ConditionTrue, + }, + { + Type: "Ready", + Status: corev1.ConditionTrue, + }, + }, + }, nil + } else if condition.Cond("Failed").IsTrue(job) { + sel, err := metav1.LabelSelectorAsSelector(job.Spec.Selector) + if err != nil { + return rkev1.RKEMachineStatus{}, err + } + + pods, err := h.pods.List(job.Namespace, sel) + if err != nil { + return rkev1.RKEMachineStatus{}, err + } + + var lastPod *corev1.Pod + for _, pod := range pods { + if lastPod == nil { + lastPod = pod + continue + } else if pod.CreationTimestamp.After(lastPod.CreationTimestamp.Time) { + lastPod = pod + } + } + + if lastPod != nil { + return getMachineStatusFromPod(lastPod, condType), nil + } + } + + return rkev1.RKEMachineStatus{Conditions: []genericcondition.GenericCondition{ + { + Type: "Ready", + Status: corev1.ConditionFalse, + Message: ExecutingMachineMessage(job.Spec.Template.Labels, job.Namespace), + }, + }}, nil +} + +func getMachineStatusFromPod(pod *corev1.Pod, condType string) rkev1.RKEMachineStatus { + reason := string(capierrors.CreateMachineError) + if condType == deleteJobConditionType { + reason = string(capierrors.DeleteMachineError) + } + + if pod.Status.Phase == corev1.PodSucceeded { + return rkev1.RKEMachineStatus{ + Conditions: []genericcondition.GenericCondition{ + { + Type: condType, + Status: corev1.ConditionTrue, + }, + { + Type: "Ready", + Status: corev1.ConditionTrue, + }, + }, + } + } + + for _, containerStatus := range pod.Status.ContainerStatuses { + if containerStatus.State.Terminated != nil && containerStatus.State.Terminated.ExitCode != 0 { + failureMessage := strings.TrimSpace(containerStatus.State.Terminated.Message) + message := FailedMachineMessage(pod.Labels, pod.Namespace, reason, failureMessage) + return rkev1.RKEMachineStatus{ + Conditions: []genericcondition.GenericCondition{ + { + Type: condType, + Status: corev1.ConditionFalse, + Reason: reason, + Message: message, + }, + { + Type: "Ready", + Status: corev1.ConditionFalse, + Reason: reason, + Message: message, + }, + }, + FailureReason: reason, + FailureMessage: failureMessage, + } + } + } + + return rkev1.RKEMachineStatus{} +} + +func (h *handler) namespaceIsRemoved(obj runtime.Object) (bool, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return false, err + } + + ns, err := h.namespaces.Get(meta.GetNamespace()) + if err != nil { + return false, err + } + + return ns.DeletionTimestamp != nil, nil +} + +func (h *handler) OnRemove(key string, obj runtime.Object) (runtime.Object, error) { + if removed, err := h.namespaceIsRemoved(obj); err != nil || removed { + return obj, err + } + + infra, err := newInfraObject(obj) + if err != nil { + return obj, err + } + + // When infra machines are initially created, the machine set controller sets itself as the owner reference + // Later, the CAPI machine will adopt the node, setting itself as the owner reference + // If the machine set is still present as the owner reference, just delete the machine since no provisioning will have taken place yet + if machineSet, _ := capr.GetOwnerCAPIMachineSet(infra.obj, h.machineSetCache); machineSet != nil { + return obj, nil + } + + // Initial provisioning not finished + if cond := getCondition(infra.data, createJobConditionType); cond != nil && cond.Status() == "Unknown" { + job, err := h.getJobFromInfraMachine(infra) + if apierrors.IsNotFound(err) { + // If the job is not found, go ahead and proceed with machine deletion + return obj, h.apply.WithOwner(obj).ApplyObjects() + } else if err != nil { + return obj, err + } + logrus.Debugf("[machineprovision] create job for %s not finished, job was found and the error was not nil and was not an isnotfound", key) + // OnChange handler will not run when the infra machine is being deleted, we have to reconcile here in order to + // finish the create job, since it has to have completed successfully or never ran for the delete job to run + state, _, err := h.run(infra, true) + if err != nil { + return obj, err + } + if err = reconcileStatus(infra.data, state); err != nil { + return obj, err + } + if job != nil { + newStatus, err := h.getMachineStatus(job) + if err != nil { + return obj, err + } + newStatus.JobName = job.Name + + err = reconcileStatus(infra.data, newStatus) + if err != nil { + return obj, err + } + } + if obj, err = h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }); err != nil { + return obj, err + } + return obj, fmt.Errorf("cannot delete machine %s because create job has not finished", infra.meta.GetName()) + } else if cond == nil { + // If the createJobCondition is not set on this infra object, that means we never actually tried to run a create job + // so there should be no infrastructure, proceed with delete + return obj, nil + } + + // infrastructure deletion finished + if cond := getCondition(infra.data, deleteJobConditionType); cond != nil && cond.Status() != "Unknown" { + job, err := h.getJobFromInfraMachine(infra) + if apierrors.IsNotFound(err) { + // If the deletion job condition has been set on the infrastructure object and the deletion job has been removed, + // then we don't want to create another deletion job. + logrus.Infof("[machineprovision] Machine %s %s has already been deleted", infra.obj.GetObjectKind().GroupVersionKind(), infra.meta.GetName()) + return obj, h.apply.WithOwner(obj).ApplyObjects() + } else if err != nil { + return obj, err + } + + if shouldCleanupObjects(job, infra.data) { + // Calling WithOwner(obj).ApplyObjects with no objects here will look for all objects with types passed to + // WithCacheTypes above that have an owner label (not owner reference) to the given obj. It will compare the existing + // objects it finds to the ones that are passed to ApplyObjects (which there are none in this case). The apply + // controller will delete all existing objects it finds that are not passed to ApplyObjects. Since no objects are + // passed here, it will delete all objects it finds. + return obj, h.apply.WithOwner(obj).ApplyObjects() + } + if cond.Status() == "True" { + return obj, generic.ErrSkip + } + } + + clusterName := infra.meta.GetLabels()[capi.ClusterNameLabel] + if clusterName == "" { + return obj, fmt.Errorf("error retrieving the clustername for machine, label key %s does not appear to exist for dynamic machine %s", capi.ClusterNameLabel, key) + } + + machine, err := capr.GetOwnerCAPIMachine(obj, h.machineCache) + if err != nil && !errors.Is(err, capr.ErrNoMatchingControllerOwnerRef) && !apierrors.IsNotFound(err) { + logrus.Errorf("[machineprovision] %s/%s: error getting machine by owner reference: %v", infra.meta.GetNamespace(), infra.meta.GetName(), err) + return obj, err + } + + // If the controller owner reference is not properly configured, or the CAPI machine does not exist, there is no way + // to recover from this situation, so we should proceed with deletion + if machine == nil || machine.Status.NodeRef == nil { + // Machine noderef is nil, we should just allow deletion. + logrus.Debugf("[machineprovision] There was no associated K8s node with this machine %s. Proceeding with deletion", key) + return h.doRemove(infra) + } + + cluster, err := h.rancherClusterCache.Get(infra.meta.GetNamespace(), clusterName) + if err != nil && !apierrors.IsNotFound(err) { + return obj, err + } + if apierrors.IsNotFound(err) || !cluster.DeletionTimestamp.IsZero() { + return h.doRemove(infra) + } + + return h.doRemove(infra) +} + +func (h *handler) doRemove(infra *infraObject) (runtime.Object, error) { + state, _, err := h.run(infra, false) + if err != nil { + return infra.obj, err + } + + if err = reconcileStatus(infra.data, state); err != nil { + return infra.obj, err + } + + if cond := getCondition(infra.data, deleteJobConditionType); cond == nil { + if err = reconcileStatus(infra.data, rkev1.RKEMachineStatus{ + Conditions: []genericcondition.GenericCondition{ + { + Type: deleteJobConditionType, + Status: corev1.ConditionUnknown, + Message: "creating machine deletion job", + }, + }}); err != nil { + return infra.obj, err + } + if infra.obj, err = h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }); err != nil { + return infra.obj, err + } + return infra.obj, generic.ErrSkip + } + + jobName := infra.data.String("status", "jobName") + if jobName == "" { + return infra.obj, generic.ErrSkip + } + + job, err := h.jobs.Get(infra.meta.GetNamespace(), jobName) + if apierrors.IsNotFound(err) { + if infra.obj, err = h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }); err != nil { + return infra.obj, err + } + return infra.obj, generic.ErrSkip + } else if err != nil { + return infra.obj, err + } + + newStatus, err := h.getMachineStatus(job) + if err != nil { + return infra.obj, err + } + newStatus.JobName = job.Name + + err = reconcileStatus(infra.data, newStatus) + if err != nil { + return infra.obj, err + } + + // We need to reset failureReason & failureMessage, otherwise the deletion status will not be shown + if infra.data.String("status", "failureReason") == string(capierrors.CreateMachineError) { + infra.data.SetNested("", "status", "failureReason") + infra.data.SetNested("", "status", "failureMessage") + } + + if infra.obj, err = h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }); err != nil { + return infra.obj, err + } + + return infra.obj, generic.ErrSkip +} + +func (h *handler) EnqueueAfter(infra *infraObject, duration time.Duration) { + err := h.dynamic.EnqueueAfter(infra.obj.GetObjectKind().GroupVersionKind(), infra.meta.GetNamespace(), infra.meta.GetName(), duration) + if err != nil { + logrus.Errorf("[machineprovision] error enqueuing %s %s/%s: %v", infra.obj.GetObjectKind().GroupVersionKind(), infra.meta.GetNamespace(), infra.meta.GetName(), err) + } +} + +// OnChange is called whenever the infrastructure machine is updated, including when the object is being deleted. +func (h *handler) OnChange(obj runtime.Object) (runtime.Object, error) { + infra, err := newInfraObject(obj) + if err != nil { + return obj, err + } + + if !infra.meta.GetDeletionTimestamp().IsZero() { + return obj, nil + } + + machine, err := capr.GetOwnerCAPIMachine(obj, h.machineCache) + if apierrors.IsNotFound(err) { + logrus.Debugf("[machineprovision] %s/%s: waiting: machine to be set as owner reference", infra.meta.GetNamespace(), infra.meta.GetName()) + h.EnqueueAfter(infra, 10*time.Second) + return obj, generic.ErrSkip + } + + if err != nil { + logrus.Errorf("[machineprovision] %s/%s: error getting machine by owner reference: %v", infra.meta.GetNamespace(), infra.meta.GetName(), err) + return obj, err + } + + // If the CAPI machine is deleted forcefully, the owner reference will not be usable, so the label allows us to create + // the delete job with the same name + if infra.meta.GetLabels()[CapiMachineName] == "" { + infra.data.SetNested(machine.Name, "metadata", "labels", CapiMachineName) + // Return prematurely, we want the caches to be as up-to-date as possible, so that we don't lose changes when + // reconciling in the event of other errors + return h.dynamic.Update(&unstructured.Unstructured{ + Object: infra.data, + }) + } + + capiCluster, err := capr.GetCAPIClusterFromLabel(machine, h.capiClusterCache) + if apierrors.IsNotFound(err) { + logrus.Debugf("[machineprovision] %s/%s: waiting: CAPI cluster does not exist", infra.meta.GetNamespace(), infra.meta.GetName()) + h.EnqueueAfter(infra, 10*time.Second) + return obj, generic.ErrSkip + } + if err != nil { + logrus.Errorf("[machineprovision] %s/%s: error getting CAPI cluster %v", infra.meta.GetNamespace(), infra.meta.GetName(), err) + return obj, err + } + + if capiannotations.IsPaused(capiCluster, infra.meta) { + logrus.Debugf("[machineprovision] %s/%s: waiting: CAPI cluster or RKEMachine is paused", infra.meta.GetNamespace(), infra.meta.GetName()) + h.EnqueueAfter(infra, 10*time.Second) + return obj, generic.ErrSkip + } + + if !capiCluster.Status.InfrastructureReady { + logrus.Debugf("[machineprovision] %s/%s: waiting: CAPI cluster infrastructure is not ready", infra.meta.GetNamespace(), infra.meta.GetName()) + h.EnqueueAfter(infra, 10*time.Second) + return obj, generic.ErrSkip + } + + if machine.Spec.Bootstrap.DataSecretName == nil { + logrus.Debugf("[machineprovision] %s/%s: waiting: dataSecretName is not populated on machine spec", infra.meta.GetNamespace(), infra.meta.GetName()) + h.EnqueueAfter(infra, 10*time.Second) + return obj, generic.ErrSkip + } + + state, failure, err := h.run(infra, true) + if err != nil { + return obj, err + } + + if failure { + logrus.Infof("[machineprovision] %s/%s: Failed to create infrastructure for machine %s, deleting and recreating...", infra.meta.GetNamespace(), infra.meta.GetName(), machine.Name) + if err = h.machineClient.Delete(machine.Namespace, machine.Name, &metav1.DeleteOptions{}); err != nil { + return obj, err + } + } + + if err = reconcileStatus(infra.data, state); err != nil { + return obj, err + } + + if cond := getCondition(infra.data, createJobConditionType); cond == nil { + if err = reconcileStatus(infra.data, rkev1.RKEMachineStatus{ + Conditions: []genericcondition.GenericCondition{ + { + Type: createJobConditionType, + Status: corev1.ConditionUnknown, + Message: "creating machine provision job", + }, + }}); err != nil { + return obj, err + } + return h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }) + } + + jobName := infra.data.String("status", "jobName") + if jobName == "" { + return obj, nil + } + + job, err := h.jobs.Get(infra.meta.GetNamespace(), jobName) + if apierrors.IsNotFound(err) { + return h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }) + } else if err != nil { + return obj, err + } + + newStatus, err := h.getMachineStatus(job) + if err != nil { + return obj, err + } + newStatus.JobName = job.Name + + err = reconcileStatus(infra.data, newStatus) + if err != nil { + return obj, err + } + + return h.dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: infra.data, + }) +} + +func (h *handler) run(infra *infraObject, create bool) (rkev1.RKEMachineStatus, bool, error) { + logrus.Infof("[machineprovision] %s/%s: reconciling machine job", infra.meta.GetNamespace(), infra.meta.GetName()) + + args := infra.data.Map("spec") + driver := getNodeDriverName(infra.typeMeta) + + dArgs, err := h.getArgsEnvAndStatus(infra, args, driver, create) + if err != nil { + return rkev1.RKEMachineStatus{}, false, err + } + + if dArgs.BootstrapSecretName == "" && dArgs.BootstrapRequired { + return rkev1.RKEMachineStatus{}, false, + h.dynamic.EnqueueAfter(infra.obj.GetObjectKind().GroupVersionKind(), infra.meta.GetNamespace(), infra.meta.GetName(), 2*time.Second) + } + + failureReasonType := capierrors.CreateMachineError + if !create { + failureReasonType = capierrors.DeleteMachineError + } + + // Check to see if we have a failure reason. + failure := infra.data.String("status", "failureReason") == string(failureReasonType) + ready := false + + cond := getCondition(infra.data, "Ready") + if cond != nil { + // We are only "ready" if both the condition "Ready" is "True" and the provider ID has been set on the machine. + ready = cond.Status() == "True" && args.String("providerID") != "" + } + + if err := h.apply.WithOwner(infra.obj).ApplyObjects(objects((ready || failure) && create, dArgs)...); err != nil { + return rkev1.RKEMachineStatus{}, failure, err + } + + return dArgs.RKEMachineStatus, failure, err +} + +// reconcileStatus will update the infra machine's status by updating each field based on the value of status. +func reconcileStatus(d data.Object, state rkev1.RKEMachineStatus) error { + statusData, err := convert.EncodeToMap(state) + if err != nil { + return err + } + + changed := false + for k, v := range statusData { + if k != "conditions" { + if d.String("status", k) != convert.ToString(v) { + changed = true + } + } else if len(state.Conditions) > 0 { + for _, c := range state.Conditions { + if thisChanged, err := insertOrUpdateCondition(d, summary.NewCondition(c.Type, string(c.Status), c.Reason, c.Message)); err != nil { + return err + } else if thisChanged { + changed = true + } + } + } + } + + if !changed { + return nil + } + + status := d.Map("status") + if status == nil { + status = map[string]interface{}{} + d.Set("status", status) + } + for k, v := range statusData { + if k != "conditions" { + status[k] = v + } + } + return nil +} + +func (h *handler) getJobFromInfraMachine(infra *infraObject) (*batchv1.Job, error) { + gvk := infra.obj.GetObjectKind().GroupVersionKind() + jobs, err := h.jobs.List(infra.meta.GetNamespace(), labels.Set{ + InfraMachineGroup: gvk.Group, + InfraMachineVersion: gvk.Version, + InfraMachineKind: gvk.Kind, + InfraMachineName: infra.meta.GetName()}.AsSelector(), + ) + if err != nil { + return nil, err + } else if len(jobs) == 0 { + // This is likely the name of the job, expect if the infra machine object has a very long name. + return nil, apierrors.NewNotFound(batchv1.Resource("jobs"), GetJobName(infra.meta.GetName())) + } + + // There can be at most one job returned here because there can be at most one infra machine object with the given GVK and name. + return jobs[0], nil +} + +func setCondition(dynamic *dynamic.Controller, obj runtime.Object, conditionType string, err error) (runtime.Object, error) { + if errors.Is(generic.ErrSkip, err) { + return obj, nil + } + + var ( + reason = "" + status = "True" + message = "" + ) + + if err != nil { + reason = "Error" + status = "False" + message = err.Error() + } + + desiredCondition := summary.NewCondition(conditionType, status, reason, message) + + d, mapErr := data.Convert(obj.DeepCopyObject()) + if mapErr != nil { + return obj, mapErr + } + + if updated, err := insertOrUpdateCondition(d, desiredCondition); !updated || err != nil { + return obj, err + } + + obj, updateErr := dynamic.UpdateStatus(&unstructured.Unstructured{ + Object: d, + }) + if updateErr != nil { + return obj, updateErr + } + return obj, err +} + +func insertOrUpdateCondition(d data.Object, desiredCondition summary.Condition) (bool, error) { + for _, cond := range summary.GetUnstructuredConditions(d) { + if desiredCondition.Equals(cond) { + return false, nil + } + } + + // The conditions must be converted to a map so that DeepCopyJSONValue will + // recognize it as a map instead of a data.Object. + newCond, err := convert.EncodeToMap(desiredCondition.Object) + if err != nil { + return false, err + } + + dConditions := d.Slice("status", "conditions") + conditions := make([]interface{}, len(dConditions)) + found := false + for i, cond := range dConditions { + if cond.String("type") == desiredCondition.Type() { + conditions[i] = newCond + found = true + } else { + conditions[i], err = convert.EncodeToMap(cond) + if err != nil { + return false, err + } + } + } + + if !found { + conditions = append(conditions, newCond) + } + d.SetNested(conditions, "status", "conditions") + + return true, nil +} + +func getCondition(d data.Object, conditionType string) *summary.Condition { + for _, cond := range summary.GetUnstructuredConditions(d) { + if cond.Type() == conditionType { + return &cond + } + } + + return nil +} + +func constructFilesSecret(driver string, config map[string]interface{}) *corev1.Secret { + secretData := make(map[string][]byte) + // Check if the required driver has aliased fields + if fields, ok := node.SchemaToDriverFields[driver]; ok { + for schemaField, driverField := range fields { + if fileContents, ok := config[schemaField].(string); ok { + // Delete our aliased fields + delete(config, schemaField) + if fileContents == "" { + continue + } + + fileName := driverField + if ok := nodedriver.SSHKeyFields[schemaField]; ok { + fileName = "id_rsa" + } + + // The ending newline gets stripped, add em back + if !strings.HasSuffix(fileContents, "\n") { + fileContents = fileContents + "\n" + } + + // Add the file to the secret + secretData[fileName] = []byte(fileContents) + // Add the field and path + config[driverField] = path.Join(pathToMachineFiles, fileName) + } + } + return &corev1.Secret{Data: secretData} + } + return nil +} + +func (h *handler) constructCertsSecret(machineName, machineNamespace string) (*corev1.Secret, error) { + certSecretData := make(map[string][]byte) + + cert := settings.CACerts.Get() + if cert != "" { + certSecretData["tls.crt"] = []byte(cert) + } + + cert = settings.InternalCACerts.Get() + if cert != "" { + certSecretData["internal-tls.crt"] = []byte(cert) + } + + if secret, err := h.secrets.Get(namespace.System, "tls-additional"); err == nil { + for key, val := range secret.Data { + certSecretData[key] = val + } + } else if !apierrors.IsNotFound(err) { + return nil, err + } + + if len(certSecretData) > 0 { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName("machine", "certs", hashName(machineName)), + Namespace: machineNamespace, + }, + Data: certSecretData, + }, nil + } + + return nil, nil +} + +func shouldCleanupObjects(job *batchv1.Job, d data.Object) bool { + if !job.Status.CompletionTime.IsZero() { + return true + } + + createJobCondition := getCondition(d, createJobConditionType) + if createJobCondition == nil { + return false + } + + forceRemoveAnnValue, _ := d.Map("metadata", "annotations")[forceRemoveMachineAnn].(string) + + if createJobCondition.Reason() == string(capierrors.CreateMachineError) || strings.ToLower(forceRemoveAnnValue) == "true" { + return strings.ToLower(job.Spec.Template.Labels[InfraJobRemove]) == "true" && condition.Cond("Failed").IsTrue(job) + } + + return false +} + +func FailedMachineMessage(podLabels map[string]string, namespace, failureReason, failureMessage string) string { + verb := "creating" + if podLabels[InfraJobRemove] == "true" { + verb = "deleting" + } + return fmt.Sprintf("failed %s server [%s/%s] of kind (%s) for machine %s in infrastructure provider: %s: %s", + verb, + namespace, + podLabels[InfraMachineName], + podLabels[InfraMachineKind], + podLabels[CapiMachineName], + failureReason, + failureMessage, + ) +} + +func ExecutingMachineMessage(podLabels map[string]string, namespace string) string { + verb := "creating" + if podLabels[InfraJobRemove] == "true" { + verb = "deleting" + } + return fmt.Sprintf("%s server [%s/%s] of kind (%s) for machine %s in infrastructure provider", + verb, + namespace, + podLabels[InfraMachineName], + podLabels[InfraMachineKind], + podLabels[CapiMachineName], + ) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller_test.go new file mode 100644 index 0000000..5d7bbb5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/controller_test.go @@ -0,0 +1,165 @@ +package machineprovision + +import ( + "testing" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/stretchr/testify/assert" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func MustStatus(status rkev1.RKEMachineStatus, err error) rkev1.RKEMachineStatus { + if err != nil { + panic(err) + } + return status +} + +func TestReconcileStatus(t *testing.T) { + h := handler{} + + tests := []struct { + name string + expected map[string]interface{} + input map[string]interface{} + state rkev1.RKEMachineStatus + }{ + { + name: "create complete", + expected: map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": []interface{}{ + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "CreateJob", + }, + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "Ready", + }, + }, + }, + }, + input: map[string]interface{}{}, + state: MustStatus(h.getMachineStatus(&batchv1.Job{ + Status: batchv1.JobStatus{ + Conditions: []batchv1.JobCondition{ + { + Type: "Complete", + Status: "True", + }, + }, + }, + })), + }, + { + name: "create in progress", + expected: map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": []interface{}{ + map[string]interface{}{ + "message": "creating server [test-namespace/infraMachineName] of kind (infraMachineKind) for machine capiMachineName in infrastructure provider", + "reason": "", + "status": "False", + "type": "Ready", + }, + }, + }, + }, + input: map[string]interface{}{}, + state: MustStatus(h.getMachineStatus(&batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test-namespace", + }, + Spec: batchv1.JobSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + InfraMachineName: "infraMachineName", + InfraMachineKind: "infraMachineKind", + CapiMachineName: "capiMachineName", + }, + }, + }, + }, + })), + }, + { + name: "create complete delete complete", + expected: map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": []interface{}{ + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "CreateJob", + }, + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "Ready", + }, + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "DeleteJob", + }, + }, + }, + }, + input: map[string]interface{}{ + "status": map[string]interface{}{ + "conditions": []interface{}{ + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "CreateJob", + }, + map[string]interface{}{ + "message": "", + "reason": "", + "status": "True", + "type": "Ready", + }, + }, + }, + }, + state: MustStatus(h.getMachineStatus(&batchv1.Job{ + Spec: batchv1.JobSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + InfraJobRemove: "true", + }, + }, + }, + }, + Status: batchv1.JobStatus{ + Conditions: []batchv1.JobCondition{ + { + Type: "Complete", + Status: "True", + }, + }, + }, + })), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := reconcileStatus(tt.input, tt.state) + assert.Nil(t, err) + assert.Equal(t, tt.expected, tt.input) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/template.go new file mode 100644 index 0000000..ce09ede --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/machineprovision/template.go @@ -0,0 +1,251 @@ +package machineprovision + +import ( + "sort" + "strconv" + + name2 "github.com/rancher/wrangler/v3/pkg/name" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + InfraMachineGroup = "rke.cattle.io/infra-machine-group" + InfraMachineVersion = "rke.cattle.io/infra-machine-version" + InfraMachineKind = "rke.cattle.io/infra-machine-kind" + InfraMachineName = "rke.cattle.io/infra-machine-name" + InfraJobRemove = "rke.cattle.io/infra-remove" + CapiMachineName = "rke.cattle.io/capi-machine-name" + + pathToMachineFiles = "/path/to/machine/files" + sslCertDir = "/etc/rancher/ssl" +) + +var ( + oneThousand int64 = 1000 +) + +func GetJobName(name string) string { + return name2.SafeConcatName(name, "machine", "provision") +} + +func objects(ready bool, args driverArgs) []runtime.Object { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: args.StateSecretName, + Namespace: args.MachineNamespace, + }, + Type: "rke.cattle.io/machine-state", + } + + if ready { + // If the machine is ready, then we only need the secret. + return []runtime.Object{secret} + } + + volumes := make([]corev1.Volume, 0) + volumeMounts := make([]corev1.VolumeMount, 0) + saName := GetJobName(args.MachineName) + + if args.BootstrapRequired { + volumes = append(volumes, corev1.Volume{ + Name: "bootstrap", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: args.BootstrapSecretName, + DefaultMode: &[]int32{0777}[0], + }, + }, + }) + + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "bootstrap", + MountPath: "/run/secrets/machine", + ReadOnly: true, + }) + } + + if args.FilesSecret != nil { + if args.FilesSecret.Name == "" { + args.FilesSecret.Name = saName + args.FilesSecret.Namespace = args.MachineNamespace + } + + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "machine-files", + ReadOnly: true, + MountPath: pathToMachineFiles, + }) + + keysToPaths := make([]corev1.KeyToPath, 0, len(args.FilesSecret.Data)) + for file := range args.FilesSecret.Data { + keysToPaths = append(keysToPaths, corev1.KeyToPath{Key: file, Path: file}) + } + + // Because of the way apply works, it must be ensured that the keysToPaths slice is always in the same order. + sort.Slice(keysToPaths, func(i, j int) bool { + return keysToPaths[i].Key < keysToPaths[j].Key + }) + + volumes = append(volumes, corev1.Volume{ + Name: "machine-files", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: args.FilesSecret.Name, + Items: keysToPaths, + DefaultMode: &[]int32{0644}[0], + }, + }, + }) + } + + if args.CertsSecret != nil { + volumes = append(volumes, corev1.Volume{ + Name: "machine-certs", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: args.CertsSecret.Name, + DefaultMode: &[]int32{0644}[0], + }, + }, + }) + for key := range args.CertsSecret.Data { + // Setting one volume mount for each cert ensures that the directory remains writable in the container. + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "machine-certs", + ReadOnly: true, + MountPath: sslCertDir + "/" + key, + SubPath: key, + }) + } + } + + // Because of the way apply works, it must be ensured that the volumeMounts always appear in the same order. + sort.Slice(volumeMounts, func(i, j int) bool { + return volumeMounts[i].MountPath < volumeMounts[j].MountPath + }) + + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: saName, + Namespace: args.MachineNamespace, + }, + } + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: saName, + Namespace: args.MachineNamespace, + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "update"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{secret.Name}, + }, + }, + } + rb := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: saName, + Namespace: args.MachineNamespace, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: saName, + Namespace: args.MachineNamespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: saName, + }, + } + rb2 := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name2.SafeConcatName(saName, "extension"), + Namespace: args.MachineNamespace, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: saName, + Namespace: args.MachineNamespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: "rke2-machine-provisioner", + }, + } + + labels := map[string]string{ + InfraMachineGroup: args.MachineGVK.Group, + InfraMachineVersion: args.MachineGVK.Version, + InfraMachineKind: args.MachineGVK.Kind, + InfraMachineName: args.MachineName, + InfraJobRemove: strconv.FormatBool(!args.BootstrapRequired), + CapiMachineName: args.CapiMachineName, + } + + job := &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: saName, + Namespace: args.MachineNamespace, + Labels: labels, + }, + Spec: batchv1.JobSpec{ + BackoffLimit: &args.BackoffLimit, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + }, + Spec: corev1.PodSpec{ + Volumes: volumes, + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{ + { + Name: "machine", + SecurityContext: &corev1.SecurityContext{ + RunAsUser: &oneThousand, + RunAsGroup: &oneThousand, + }, + Image: args.ImageName, + ImagePullPolicy: args.ImagePullPolicy, + Args: args.Args, + EnvFrom: []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: args.EnvSecret.Name, + }, + }, + }, + }, + VolumeMounts: volumeMounts, + }, + }, + ServiceAccountName: saName, + }, + }, + }, + } + + return []runtime.Object{ + args.EnvSecret, + secret, + sa, + role, + rb, + args.FilesSecret, + args.CertsSecret, + rb2, + job, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagent.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagent.go new file mode 100644 index 0000000..c8372cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagent.go @@ -0,0 +1,407 @@ +package managesystemagent + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + rancherv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + fleetconst "github.com/rancher/rancher/pkg/fleet" + fleetcontrollers "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rocontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + namespaces "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + "github.com/rancher/rancher/pkg/wrangler" + upgradev1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/gvk" + "github.com/rancher/wrangler/v3/pkg/name" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + generationSecretName = "system-agent-upgrade-generation" +) + +var Kubernetes125 = semver.MustParse("v1.25.0") + +type handler struct { + clusterRegistrationTokens v3.ClusterRegistrationTokenCache + bundles fleetcontrollers.BundleClient + provClusters rocontrollers.ClusterCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + clusterRegistrationTokens: clients.Mgmt.ClusterRegistrationToken().Cache(), + bundles: clients.Fleet.Bundle(), + provClusters: clients.Provisioning.Cluster().Cache(), + } + + v1.RegisterRKEControlPlaneStatusHandler(ctx, clients.RKE.RKEControlPlane(), + "", "monitor-system-upgrade-controller-readiness", h.syncSystemUpgradeControllerStatus) + + rocontrollers.RegisterClusterGeneratingHandler(ctx, clients.Provisioning.Cluster(), + clients.Apply. + WithSetOwnerReference(false, false). + WithCacheTypes(clients.Fleet.Bundle(), + clients.Provisioning.Cluster(), + clients.Core.Secret(), + clients.RBAC.RoleBinding(), + clients.RBAC.Role()), + "", "manage-system-agent", h.OnChange, &generic.GeneratingHandlerOptions{ + AllowCrossNamespace: true, + }) + + rocontrollers.RegisterClusterGeneratingHandler(ctx, clients.Provisioning.Cluster(), + clients.Apply. + WithSetOwnerReference(false, false). + WithCacheTypes(clients.Mgmt.ManagedChart(), + clients.Provisioning.Cluster()), + "", "manage-system-upgrade-controller", h.OnChangeInstallSUC, nil) +} + +func (h *handler) OnChange(cluster *rancherv1.Cluster, status rancherv1.ClusterStatus) ([]runtime.Object, rancherv1.ClusterStatus, error) { + if cluster.Spec.RKEConfig == nil || settings.SystemAgentUpgradeImage.Get() == "" { + return nil, status, nil + } + + // Intentionally return an ErrSkip to prevent unnecessarily thrashing the corresponding bundle + // if the status field for fleetworkspacename has not yet been updated + if cluster.Status.FleetWorkspaceName == "" { + return nil, status, generic.ErrSkip + } + + var ( + secretName = "stv-aggregation" + result []runtime.Object + ) + + if cluster.Status.ClusterName == "local" && cluster.Namespace == fleetconst.ClustersLocalNamespace { + secretName += "-local-" + + token, err := h.clusterRegistrationTokens.Get(cluster.Status.ClusterName, "default-token") + if err != nil { + return nil, status, err + } + if token.Status.Token == "" { + return nil, status, fmt.Errorf("token not yet generated for %s/%s", token.Namespace, token.Name) + } + + digest := sha256.New() + digest.Write([]byte(settings.InternalServerURL.Get())) + digest.Write([]byte(token.Status.Token)) + digest.Write([]byte(systemtemplate.InternalCAChecksum())) + d := digest.Sum(nil) + secretName += hex.EncodeToString(d[:])[:12] + + result = append(result, &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: namespaces.System, + }, + Data: map[string][]byte{ + "CATTLE_SERVER": []byte(settings.InternalServerURL.Get()), + "CATTLE_TOKEN": []byte(token.Status.Token), + "CATTLE_CA_CHECKSUM": []byte(systemtemplate.InternalCAChecksum()), + }, + }) + } + + resources, err := ToResources(installer(cluster, secretName)) + if err != nil { + return nil, status, err + } + + result = append(result, &v1alpha1.Bundle{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Status.FleetWorkspaceName, + Name: capr.SafeConcatName(capr.MaxHelmReleaseNameLength, cluster.Name, "managed", "system", "agent"), + }, + Spec: v1alpha1.BundleSpec{ + BundleDeploymentOptions: v1alpha1.BundleDeploymentOptions{ + DefaultNamespace: namespaces.System, + }, + Resources: resources, + Targets: []v1alpha1.BundleTarget{ + { + ClusterName: cluster.Name, + ClusterSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "provisioning.cattle.io/unmanaged-system-agent", + Operator: metav1.LabelSelectorOpDoesNotExist, + }, + }, + }, + }, + }, + }, + }) + + return result, status, nil +} + +func installer(cluster *rancherv1.Cluster, secretName string) []runtime.Object { + upgradeImage := strings.SplitN(settings.SystemAgentUpgradeImage.Get(), ":", 2) + version := "latest" + if len(upgradeImage) == 2 { + version = upgradeImage[1] + } + + winsUpgradeImage := strings.SplitN(settings.WinsAgentUpgradeImage.Get(), ":", 2) + winsVersion := "latest" + if len(winsUpgradeImage) == 2 { + winsVersion = winsUpgradeImage[1] + } + + var env []corev1.EnvVar + for _, e := range cluster.Spec.AgentEnvVars { + env = append(env, corev1.EnvVar{ + Name: e.Name, + Value: e.Value, + }) + } + + // Merge the env vars with the AgentTLSModeStrict + found := false + for _, ev := range env { + if ev.Name == "STRICT_VERIFY" { + found = true // The user has specified `STRICT_VERIFY`, we should not attempt to overwrite it. + } + } + if !found { + if settings.AgentTLSMode.Get() == settings.AgentTLSModeStrict { + env = append(env, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "true", + }) + } else { + env = append(env, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "false", + }) + } + } + + if len(cluster.Spec.RKEConfig.MachineSelectorConfig) == 0 { + env = append(env, corev1.EnvVar{ + Name: "CATTLE_ROLE_WORKER", + Value: "true", + }) + } + + if cluster.Spec.RKEConfig.DataDirectories.SystemAgent != "" { + env = append(env, corev1.EnvVar{ + Name: capr.SystemAgentDataDirEnvVar, + Value: capr.GetSystemAgentDataDir(&cluster.Spec.RKEConfig.RKEClusterSpecCommon), + }) + } + + switch capr.GetRuntime(cluster.Spec.KubernetesVersion) { + case capr.RuntimeRKE2: + env = append(env, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/rke2/bin", + }) + default: + env = append(env, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/bin", + }) + } + + plan := &upgradev1.Plan{ + TypeMeta: metav1.TypeMeta{ + Kind: "Plan", + APIVersion: "upgrade.cattle.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "system-agent-upgrader", + Namespace: namespaces.System, + Annotations: map[string]string{ + "upgrade.cattle.io/digest": "spec.upgrade.envs,spec.upgrade.envFrom", + }, + }, + Spec: upgradev1.PlanSpec{ + Concurrency: 10, + Version: version, + Tolerations: []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }, + }, + NodeSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: corev1.LabelOSStable, + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "linux", + }, + }, + }, + }, + ServiceAccountName: "system-agent-upgrader", + Upgrade: &upgradev1.ContainerSpec{ + Image: image.ResolveWithCluster(upgradeImage[0], cluster), + Env: env, + EnvFrom: []corev1.EnvFromSource{{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + }, + }}, + }, + }, + } + + windowsPlan := &upgradev1.Plan{ + TypeMeta: metav1.TypeMeta{ + Kind: "Plan", + APIVersion: "upgrade.cattle.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "system-agent-upgrader-windows", + Namespace: namespaces.System, + Annotations: map[string]string{ + "upgrade.cattle.io/digest": "spec.upgrade.envs,spec.upgrade.envFrom", + }, + }, + Spec: upgradev1.PlanSpec{ + Concurrency: 10, + Version: winsVersion, + Tolerations: []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }, + }, + NodeSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: corev1.LabelOSStable, + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "windows", + }, + }, + }, + }, + ServiceAccountName: "system-agent-upgrader", + Upgrade: &upgradev1.ContainerSpec{ + Image: image.ResolveWithCluster(winsUpgradeImage[0], cluster), + Env: env, + EnvFrom: []corev1.EnvFromSource{{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: secretName, + }, + }, + }}, + }, + }, + } + + objs := []runtime.Object{ + &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "system-agent-upgrader", + Namespace: namespaces.System, + }, + }, + &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "system-agent-upgrader", + }, + Rules: []rbacv1.PolicyRule{{ + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"nodes"}, + }}, + }, + &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "system-agent-upgrader", + }, + Subjects: []rbacv1.Subject{{ + Kind: "ServiceAccount", + Name: "system-agent-upgrader", + Namespace: namespaces.System, + }}, + RoleRef: rbacv1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "system-agent-upgrader", + }, + }, + } + + if cluster.Spec.RedeploySystemAgentGeneration != 0 { + plan.Spec.Secrets = append(plan.Spec.Secrets, upgradev1.SecretSpec{ + Name: generationSecretName, + }) + + windowsPlan.Spec.Secrets = append(windowsPlan.Spec.Secrets, upgradev1.SecretSpec{ + Name: generationSecretName, + }) + + objs = append(objs, &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: generationSecretName, + Namespace: namespaces.System, + }, + StringData: map[string]string{ + "cluster-uid": string(cluster.UID), + "generation": strconv.Itoa(int(cluster.Spec.RedeploySystemAgentGeneration)), + }, + }) + } + + return append([]runtime.Object{plan, windowsPlan}, objs...) +} + +func ToResources(objs []runtime.Object) (result []v1alpha1.BundleResource, err error) { + for _, obj := range objs { + obj = obj.DeepCopyObject() + if err := gvk.Set(obj); err != nil { + return nil, fmt.Errorf("failed to set gvk: %w", err) + } + + typeMeta, err := meta.TypeAccessor(obj) + if err != nil { + return nil, err + } + + meta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + + data, err := json.Marshal(obj) + if err != nil { + return nil, err + } + + digest := sha256.Sum256(data) + filename := name.SafeConcatName(typeMeta.GetKind(), meta.GetNamespace(), meta.GetName(), hex.EncodeToString(digest[:])[:12]) + ".yaml" + result = append(result, v1alpha1.BundleResource{ + Name: filename, + Content: string(data), + }) + } + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan.go new file mode 100644 index 0000000..d76cc3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan.go @@ -0,0 +1,117 @@ +package managesystemagent + +import ( + "fmt" + + "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rancherv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + namespaces "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func (h *handler) OnChangeInstallSUC(cluster *rancherv1.Cluster, status rancherv1.ClusterStatus) ([]runtime.Object, rancherv1.ClusterStatus, error) { + if cluster.Spec.RKEConfig == nil { + return nil, status, nil + } + + if cluster.Status.FleetWorkspaceName == "" { + return nil, status, nil + } + + // we must limit the output of name.SafeConcatName to at most 48 characters because + // a) the chart release name cannot exceed 53 characters, and + // b) upon creation of this resource the prefix 'mcc-' will be added to the release name, hence the limiting to 48 characters + mcc := &v3.ManagedChart{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Status.FleetWorkspaceName, + Name: capr.SafeConcatName(48, cluster.Name, "managed", "system-upgrade-controller"), + }, + Spec: v3.ManagedChartSpec{ + DefaultNamespace: namespaces.System, + RepoName: "rancher-charts", + Chart: "system-upgrade-controller", + Version: settings.SystemUpgradeControllerChartVersion.Get(), + Values: &v1alpha1.GenericMap{ + Data: map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": image.GetPrivateRepoURLFromCluster(cluster), + }, + }, + }, + }, + Targets: []v1alpha1.BundleTarget{ + { + ClusterName: cluster.Name, + ClusterSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "provisioning.cattle.io/unmanaged-system-agent", + Operator: metav1.LabelSelectorOpDoesNotExist, + }, + }, + }, + }, + }, + }, + } + + return []runtime.Object{ + mcc, + }, status, nil +} + +// syncSystemUpgradeControllerStatus queries the managed system-upgrade-controller chart and determines if it is properly configured for a given +// version of Kubernetes. It applies a condition onto the control-plane object to be used by the planner when handling Kubernetes upgrades. +func (h *handler) syncSystemUpgradeControllerStatus(obj *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + // perform the same name limiting as in the OnChangeInstallSUC and the managedchart controller + cluster, err := h.provClusters.Get(obj.Namespace, obj.Name) + if err != nil { + return status, err + } + if cluster.Status.FleetWorkspaceName == "" { + return status, fmt.Errorf("unable to sync system upgrade controller status for [%s] [%s/%s], status.FleetWorkspaceName was blank", cluster.TypeMeta.String(), cluster.Namespace, cluster.Name) + } + + bundleName := capr.SafeConcatName(capr.MaxHelmReleaseNameLength, "mcc", capr.SafeConcatName(48, obj.Name, "managed", "system-upgrade-controller")) + sucBundle, err := h.bundles.Get(cluster.Status.FleetWorkspaceName, bundleName, metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + // if we couldn't find the bundle then we know it's not ready + capr.SystemUpgradeControllerReady.Reason(&status, fmt.Sprintf("unable to find bundle %s: %v", bundleName, err)) + capr.SystemUpgradeControllerReady.Message(&status, "") + capr.SystemUpgradeControllerReady.False(&status) + // don't return the error, otherwise the status won't be set to 'false' + return status, nil + } + logrus.Errorf("[managesystemagentplan] rkecluster %s/%s: error encountered while retrieving bundle %s: %v", obj.Namespace, obj.Name, bundleName, err) + return status, err + } + // determine if the SUC deployment has been rolled out fully, and if there were any errors encountered + if sucBundle.Status.Summary.Ready != sucBundle.Status.Summary.DesiredReady || sucBundle.Status.Summary.DesiredReady == 0 { + if sucBundle.Status.Summary.ErrApplied != 0 && len(sucBundle.Status.Summary.NonReadyResources) > 0 { + nonReady := sucBundle.Status.Summary.NonReadyResources + capr.SystemUpgradeControllerReady.Reason(&status, fmt.Sprintf("error encountered waiting for system-upgrade-controller bundle roll out: %s", nonReady[0].Message)) + capr.SystemUpgradeControllerReady.Message(&status, "") + capr.SystemUpgradeControllerReady.Unknown(&status) + return status, nil + } + capr.SystemUpgradeControllerReady.Reason(&status, "waiting for system-upgrade-controller bundle roll out") + capr.SystemUpgradeControllerReady.Message(&status, "") + capr.SystemUpgradeControllerReady.Unknown(&status) + return status, nil + } + + capr.SystemUpgradeControllerReady.Message(&status, "") + capr.SystemUpgradeControllerReady.Reason(&status, "") + capr.SystemUpgradeControllerReady.True(&status) + return status, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan_test.go new file mode 100644 index 0000000..55476d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/managesystemagent/managesystemagentplan_test.go @@ -0,0 +1,127 @@ +package managesystemagent + +import ( + "testing" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + + "github.com/golang/mock/gomock" + "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + fleetv1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestManageSystemAgent_syncSystemUpgradeControllerStatusConditionManipulation(t *testing.T) { + type args struct { + controlPlaneName string + controlPlaneNamespace string + kubernetesVersion string + changeExpected bool + bs fleetv1alpha1.BundleSummary + } + + tests := []struct { + name string + args args + }{ + { + name: "basic bundle ready test case", + args: args{ + controlPlaneName: "lol", + controlPlaneNamespace: "lol", + kubernetesVersion: "v1.25.5+k3s1", + bs: fleetv1alpha1.BundleSummary{ + DesiredReady: 1, + Ready: 1, + }, + }, + }, + { + name: "test for super long controlplane name", + args: args{ + controlPlaneName: "ayyhxrojzehfiqampacgkqbqyewdjxwvhjowpikqqtxbkjqpegqaovgfehehkfg", + controlPlaneNamespace: "lol", + kubernetesVersion: "v1.26.5+k3s1", + bs: fleetv1alpha1.BundleSummary{ + DesiredReady: 1, + Ready: 1, + }, + changeExpected: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + bc := fake.NewMockControllerInterface[*v1alpha1.Bundle, *v1alpha1.BundleList](ctrl) + pc := fake.NewMockCacheInterface[*v1.Cluster](ctrl) + h := &handler{ + bundles: bc, + provClusters: pc, + } + a := assert.New(t) + + mockControlPlane := &rkev1.RKEControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: tt.args.controlPlaneName, + Namespace: tt.args.controlPlaneNamespace, + }, + Spec: rkev1.RKEControlPlaneSpec{ + KubernetesVersion: tt.args.kubernetesVersion, + }, + } + + capr.SystemUpgradeControllerReady.True(&mockControlPlane.Status) + capr.SystemUpgradeControllerReady.Message(&mockControlPlane.Status, "") + // Set the "last updated time" to the start of time, because RFC3339 only provides granularity at seconds and the test can run in less than a second (thus ensuring the timestamp is mutated when we expect it to be mutated) + capr.SystemUpgradeControllerReady.LastUpdated(&mockControlPlane.Status, time.Time{}.UTC().Format(time.RFC3339)) + lu := capr.SystemUpgradeControllerReady.GetLastUpdated(&mockControlPlane.Status) + + pc.EXPECT().Get(tt.args.controlPlaneNamespace, tt.args.controlPlaneName).Return(&v1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: tt.args.controlPlaneName, + Namespace: tt.args.controlPlaneNamespace, + }, + Status: v1.ClusterStatus{ + FleetWorkspaceName: tt.args.controlPlaneNamespace, + }, + }, nil) + expectedBundleName := capr.SafeConcatName(capr.MaxHelmReleaseNameLength, "mcc", capr.SafeConcatName(48, tt.args.controlPlaneName, "managed", "system-upgrade-controller")) + bc.EXPECT().Get(tt.args.controlPlaneNamespace, expectedBundleName, metav1.GetOptions{}).Return(&fleetv1alpha1.Bundle{ + ObjectMeta: metav1.ObjectMeta{ + Name: expectedBundleName, + Namespace: tt.args.controlPlaneNamespace, + }, + Spec: fleetv1alpha1.BundleSpec{ + BundleDeploymentOptions: fleetv1alpha1.BundleDeploymentOptions{ + Helm: &fleetv1alpha1.HelmOptions{ + Values: &fleetv1alpha1.GenericMap{ + Data: map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{}, + }, + }, + }, + }, + }, + }, + Status: fleetv1alpha1.BundleStatus{ + Summary: tt.args.bs, + }, + }, nil) + + resultingStatus, err := h.syncSystemUpgradeControllerStatus(mockControlPlane, mockControlPlane.Status) + a.NoError(err) + if tt.args.changeExpected { + a.NotEqual(lu, capr.SystemUpgradeControllerReady.GetLastUpdated(&resultingStatus)) + } else { + a.Equal(lu, capr.SystemUpgradeControllerReady.GetLastUpdated(&resultingStatus)) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/planner/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/planner/controller.go new file mode 100644 index 0000000..f2404b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/planner/controller.go @@ -0,0 +1,136 @@ +package planner + +import ( + "context" + "errors" + "strings" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + caprplanner "github.com/rancher/rancher/pkg/capr/planner" + v1 "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type handler struct { + planner *caprplanner.Planner + controlPlanes v1.RKEControlPlaneController +} + +func Register(ctx context.Context, clients *wrangler.Context, planner *caprplanner.Planner) { + h := handler{ + planner: planner, + controlPlanes: clients.RKE.RKEControlPlane(), + } + v1.RegisterRKEControlPlaneStatusHandler(ctx, clients.RKE.RKEControlPlane(), "", "planner", h.OnChange) + relatedresource.Watch(ctx, "planner", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if secret, ok := obj.(*corev1.Secret); ok { + var relatedResources []relatedresource.Key + clusterName := secret.Labels[capr.ClusterNameLabel] + if clusterName != "" { + logrus.Tracef("[planner] rkecluster %s/%s enqueue triggered by secret %s/%s", secret.Namespace, clusterName, secret.Namespace, secret.Name) + relatedResources = append(relatedResources, relatedresource.Key{ + Namespace: secret.Namespace, + Name: clusterName, + }) + } + authorizedObjects := secret.Annotations[capr.AuthorizedObjectAnnotation] + if authorizedObjects != "" { + for _, clusterName = range strings.Split(authorizedObjects, ",") { + logrus.Tracef("[planner] rkecluster %s/%s enqueue triggered by authorized secret %s/%s", secret.Namespace, clusterName, secret.Namespace, secret.Name) + relatedResources = append(relatedResources, relatedresource.Key{ + Namespace: secret.Namespace, + Name: clusterName, + }) + } + } + return relatedResources, nil + } else if machine, ok := obj.(*capi.Machine); ok { + clusterName := machine.Labels[capi.ClusterNameLabel] + if clusterName != "" { + logrus.Tracef("[planner] rkecluster %s/%s enqueue triggered by machine %s/%s", machine.Namespace, clusterName, machine.Namespace, machine.Name) + return []relatedresource.Key{{ + Namespace: machine.Namespace, + Name: clusterName, + }}, nil + } + } else if configmap, ok := obj.(*corev1.ConfigMap); ok { + var relatedResources []relatedresource.Key + authorizedObjects := configmap.Annotations[capr.AuthorizedObjectAnnotation] + if authorizedObjects != "" { + for _, clusterName := range strings.Split(authorizedObjects, ",") { + logrus.Tracef("[planner] rkecluster %s/%s enqueue triggered by authorized configmap %s/%s", configmap.Namespace, clusterName, configmap.Namespace, configmap.Name) + relatedResources = append(relatedResources, relatedresource.Key{ + Namespace: configmap.Namespace, + Name: clusterName, + }) + } + } + return relatedResources, nil + } + return nil, nil + }, clients.RKE.RKEControlPlane(), clients.Core.Secret(), clients.CAPI.Machine(), clients.Core.ConfigMap()) +} + +func (h *handler) OnChange(cp *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + logrus.Debugf("[planner] rkecluster %s/%s: handler OnChange called", cp.Namespace, cp.Name) + if !cp.DeletionTimestamp.IsZero() { + return status, nil + } + + status.ObservedGeneration = cp.Generation + + logrus.Debugf("[planner] rkecluster %s/%s: calling planner process", cp.Namespace, cp.Name) + status, err := h.planner.Process(cp, status) + if err != nil { + // planner.Process can encounter 3 types of errors: + // * planner.errWaiting - This is an error that indicates we are waiting for something, and will not re-enqueue the object + // * generic.ErrSkip - These will cause the object to be re-enqueued after 5 seconds. + // * error - All other errors. This should be an actual error during planner processing. + if caprplanner.IsErrWaiting(err) { + logrus.Infof("[planner] rkecluster %s/%s: %v", cp.Namespace, cp.Name, err) + capr.Ready.SetStatus(&status, "Unknown") + capr.Ready.Message(&status, err.Error()) + capr.Ready.Reason(&status, "Waiting") + // Set err to nil so planner doesn't automatically re-enqueue the object, as we're waiting. + // If the Reconciled condition is already true and the error was NOT an errIgnore/ErrSkip/ErrWaiting and the status.AppliedSpec (from planner.Process) does not match the controlplane spec, set reconciled to unknown. + if !equality.Semantic.DeepEqual(cp.Spec, status.AppliedSpec) { + capr.Reconciled.SetStatus(&status, "Unknown") + capr.Reconciled.Message(&status, "RKEControlPlane has not been fully reconciled yet") + capr.Reconciled.Reason(&status, "Waiting") + } + return status, nil + } + if errors.Is(err, generic.ErrSkip) { + logrus.Debugf("[planner] rkecluster %s/%s: ErrSkip: %v", cp.Namespace, cp.Name, err) + h.controlPlanes.EnqueueAfter(cp.Namespace, cp.Name, 5*time.Second) + return status, err + } + // An actual error occurred, so set the Ready and Reconciled conditions to this error and return + logrus.Errorf("[planner] rkecluster %s/%s: error during plan processing: %v", cp.Namespace, cp.Name, err) + capr.Ready.SetError(&status, "", err) + capr.Reconciled.SetError(&status, "", err) + return status, err + } + // No error encountered during planner.Process + logrus.Debugf("[planner] rkecluster %s/%s: reconciliation complete", cp.Namespace, cp.Name) + capr.Ready.True(&status) + capr.Ready.Message(&status, "") + capr.Ready.Reason(&status, "") + capr.Stable.True(&status) + capr.Stable.Message(&status, "") + capr.Stable.Reason(&status, "") + status.AppliedSpec = &cp.Spec + capr.Reconciled.True(&status) + capr.Reconciled.Message(&status, "") + capr.Reconciled.Reason(&status, "") + return status, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/plansecret/plansecret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/plansecret/plansecret.go new file mode 100644 index 0000000..4e86fca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/plansecret/plansecret.go @@ -0,0 +1,331 @@ +package plansecret + +import ( + "bufio" + "bytes" + "context" + "fmt" + "strings" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/capr/planner" + sb "github.com/rancher/rancher/pkg/controllers/managementuser/snapshotbackpopulate" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + rkev1controllers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/util/conditions" +) + +type handler struct { + secrets corecontrollers.SecretClient + machinesCache capicontrollers.MachineCache + machinesClient capicontrollers.MachineClient + etcdSnapshotsClient rkev1controllers.ETCDSnapshotClient + etcdSnapshotsCache rkev1controllers.ETCDSnapshotCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := handler{ + secrets: clients.Core.Secret(), + machinesCache: clients.CAPI.Machine().Cache(), + machinesClient: clients.CAPI.Machine(), + etcdSnapshotsClient: clients.RKE.ETCDSnapshot(), + etcdSnapshotsCache: clients.RKE.ETCDSnapshot().Cache(), + } + clients.Core.Secret().OnChange(ctx, "plan-secret", h.OnChange) +} + +func (h *handler) OnChange(key string, secret *corev1.Secret) (*corev1.Secret, error) { + if secret == nil || secret.Type != capr.SecretTypeMachinePlan || len(secret.Data) == 0 { + return secret, nil + } + + logrus.Debugf("[plansecret] reconciling secret %s/%s", secret.Namespace, secret.Name) + + node, err := planner.SecretToNode(secret) + if err != nil { + return secret, err + } + + if v, ok := node.PeriodicOutput["etcd-snapshot-list-local"]; ok && v.ExitCode == 0 && len(v.Stdout) > 0 { + if err := h.reconcileEtcdSnapshotList(secret, false, v.Stdout); err != nil { + logrus.Errorf("[plansecret] error reconciling local snapshot list for secret %s/%s: %v", secret.Namespace, secret.Name, err) + } + } + + if v, ok := node.PeriodicOutput["etcd-snapshot-list-s3"]; ok && v.ExitCode == 0 && len(v.Stdout) > 0 && secret.Labels[capr.InitNodeLabel] == "true" { + if err := h.reconcileEtcdSnapshotList(secret, true, v.Stdout); err != nil { + logrus.Errorf("[plansecret] error reconciling S3 snapshot list for secret %s/%s: %v", secret.Namespace, secret.Name, err) + } + } + + appliedChecksum := string(secret.Data["applied-checksum"]) + failedChecksum := string(secret.Data["failed-checksum"]) + plan := secret.Data["plan"] + + secretChanged := false + secret = secret.DeepCopy() + + if appliedChecksum == planner.PlanHash(plan) && !bytes.Equal(plan, secret.Data["appliedPlan"]) { + secret.Data["appliedPlan"] = plan + secretChanged = true + } + + if len(secret.Data["probe-statuses"]) > 0 { + _, healthy, err := planner.ParseProbeStatuses(secret.Data["probe-statuses"]) + if err != nil { + return nil, err + } + if healthy && secret.Annotations[capr.PlanProbesPassedAnnotation] == "" { + // a non-zero value for this annotation indicates the probes for this specific plan have passed at least once + secret.Annotations[capr.PlanProbesPassedAnnotation] = time.Now().UTC().Format(time.RFC3339) + secretChanged = true + } + } + + if secretChanged { + // don't return the secret at this point, we want to attempt to update the machine status later on + secret, err = h.secrets.Update(secret) + if err != nil { + return secret, err + } + } + + if failedChecksum == planner.PlanHash(plan) { + logrus.Debugf("[plansecret] %s/%s: rv: %s: Detected failed plan application, reconciling machine PlanApplied condition to error", secret.Namespace, secret.Name, secret.ResourceVersion) + err = h.reconcileMachinePlanAppliedCondition(secret, fmt.Errorf("error applying plan -- check rancher-system-agent.service logs on node for more information")) + return secret, err + } + + logrus.Debugf("[plansecret] %s/%s: rv: %s: Reconciling machine PlanApplied condition to nil", secret.Namespace, secret.Name, secret.ResourceVersion) + err = h.reconcileMachinePlanAppliedCondition(secret, nil) + return secret, err +} + +func (h *handler) reconcileMachinePlanAppliedCondition(secret *corev1.Secret, planAppliedErr error) error { + if secret == nil { + logrus.Debug("[plansecret] secret was nil when reconciling machine status") + return nil + } + + condition := capi.ConditionType(capr.PlanApplied) + + machineName, ok := secret.Labels[capr.MachineNameLabel] + if !ok { + return fmt.Errorf("did not find machine label on secret %s/%s", secret.Namespace, secret.Name) + } + + machine, err := h.machinesCache.Get(secret.Namespace, machineName) + if err != nil { + return err + } + + machine = machine.DeepCopy() + + var needsUpdate bool + if planAppliedErr != nil && + (conditions.GetMessage(machine, condition) != planAppliedErr.Error() || + *conditions.GetSeverity(machine, condition) != capi.ConditionSeverityError || + !conditions.IsFalse(machine, condition) || + conditions.GetReason(machine, condition) != "Error") { + logrus.Debugf("[plansecret] machine %s/%s: marking PlanApplied as false", machine.Namespace, machine.Name) + conditions.MarkFalse(machine, condition, "Error", capi.ConditionSeverityError, planAppliedErr.Error()) + needsUpdate = true + } else if planAppliedErr == nil && !conditions.IsTrue(machine, condition) { + logrus.Debugf("[plansecret] machine %s/%s: marking PlanApplied as true", machine.Namespace, machine.Name) + conditions.MarkTrue(machine, condition) + needsUpdate = true + } + + if needsUpdate { + logrus.Debugf("[plansecret] machine %s/%s: updating status of machine to reconcile for condition with error: %+v", machine.Namespace, machine.Name, planAppliedErr) + _, err = h.machinesClient.UpdateStatus(machine) + } + + return err +} + +func machineOwnerRef(machine capi.Machine) metav1.OwnerReference { + return metav1.OwnerReference{ + APIVersion: machine.APIVersion, + Kind: machine.Kind, + Name: machine.Name, + UID: machine.UID, + Controller: &[]bool{true}[0], + BlockOwnerDeletion: &[]bool{true}[0], + } +} + +func (h *handler) reconcileEtcdSnapshotList(secret *corev1.Secret, s3 bool, listStdout []byte) error { + cnl := secret.Labels[capr.ClusterNameLabel] + if len(cnl) == 0 { + return fmt.Errorf("node secret did not have label %s", capr.ClusterNameLabel) + } + + machineName, ok := secret.Labels[capr.MachineNameLabel] + if !ok { + return fmt.Errorf("did not find machine label on secret %s/%s", secret.Namespace, secret.Name) + } + + ls := labels.SelectorFromSet(map[string]string{ + capr.ClusterNameLabel: cnl, + capr.NodeNameLabel: "s3", + }) + + var machine *capi.Machine + var machineID string + var err error + + if !s3 { + machine, err = h.machinesCache.Get(secret.Namespace, machineName) + if err != nil { + return err + } + if machine.Labels[capr.MachineIDLabel] != "" { + machineID = machine.Labels[capr.MachineIDLabel] + ls = labels.SelectorFromSet(map[string]string{ + capr.ClusterNameLabel: cnl, + capr.MachineIDLabel: machine.Labels[capr.MachineIDLabel], + }) + } else { + return fmt.Errorf("error finding machine ID for machine %s/%s", machine.Namespace, machine.Name) + } + } + + etcdSnapshotsOnNode := outputToEtcdSnapshots(cnl, listStdout) + + etcdSnapshots, err := h.etcdSnapshotsCache.List(secret.Namespace, ls) + if err != nil { + return err + } + + // indexedEtcdSnapshots is a map of etcd snapshots that already exist in the management cluster + indexedEtcdSnapshots := map[string]*v1.ETCDSnapshot{} + + for _, v := range etcdSnapshots { + if _, ok := etcdSnapshotsOnNode[v.Name]; !ok && v.Status.Missing { + // delete the etcd snapshot as it is missing + logrus.Infof("[plansecret] Deleting etcd snapshot %s/%s", v.Namespace, v.Name) + if err := h.etcdSnapshotsClient.Delete(v.Namespace, v.Name, &metav1.DeleteOptions{}); err != nil { + return err + } + } + indexedEtcdSnapshots[v.Name] = v + } + + if !s3 && machine.Status.NodeRef != nil { + for k, v := range etcdSnapshotsOnNode { + if _, ok := indexedEtcdSnapshots[k]; !ok { + // create the etcdsnapshot object as it was not in the list of etcdsnapshots and not an S3 snapshot + snapshot := v1.ETCDSnapshot{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: secret.Namespace, + Labels: map[string]string{ + capr.ClusterNameLabel: cnl, + capr.MachineIDLabel: machineID, + }, + Annotations: map[string]string{ + sb.SnapshotNameKey: v.Name, + sb.StorageAnnotationKey: sb.StorageLocal, + }, + OwnerReferences: []metav1.OwnerReference{ + machineOwnerRef(*machine), + }, + }, + Spec: v1.ETCDSnapshotSpec{ + ClusterName: cnl, + }, + SnapshotFile: v1.ETCDSnapshotFile{ + Name: v.Name, + Location: v.Location, + NodeName: machine.Status.NodeRef.Name, + }, + } + snapshot.Name = name.SafeConcatName(cnl, snapshot.SnapshotFile.Name, sb.StorageLocal) + logrus.Debugf("[plansecret] machine %s/%s: creating etcd snapshot %s for cluster %s", machine.Namespace, machine.Name, snapshot.Name, cnl) + _, err = h.etcdSnapshotsClient.Create(&snapshot) + if err != nil && !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("error while creating etcd snapshot: %w", err) + } + } + } + } + + return nil +} + +type snapshot struct { + Name string + Location string + Size string + Created string + S3 bool +} + +func outputToEtcdSnapshots(clusterName string, collectedOutput []byte) map[string]*snapshot { + scanner := bufio.NewScanner(bytes.NewBuffer(collectedOutput)) + snapshots := make(map[string]*snapshot) + for scanner.Scan() { + line := scanner.Text() + if s := strings.Fields(line); len(s) == 3 || len(s) == 4 { + switch len(s) { + case 3: + if strings.ToLower(s[0]) == "name" && + strings.ToLower(s[1]) == "size" && + strings.ToLower(s[2]) == "created" { + continue + } + case 4: + if strings.ToLower(s[0]) == "name" && + strings.ToLower(s[1]) == "location" && + strings.ToLower(s[2]) == "size" && + strings.ToLower(s[3]) == "created" { + continue + } + } + ss, err := generateEtcdSnapshotFromListOutput(line) + if err != nil { + logrus.Errorf("error parsing etcd snapshot output (%s) to etcd snapshot: %v", line, err) + continue + } + suffix := "local" + if ss.S3 { + suffix = "s3" + } + snapshots[fmt.Sprintf("%s-%s-%s", clusterName, ss.Name, suffix)] = ss + } + } + return snapshots +} + +func generateEtcdSnapshotFromListOutput(input string) (*snapshot, error) { + snapshotData := strings.Fields(input) + switch len(snapshotData) { + case 3: + return &snapshot{ + Name: strings.ToLower(sb.InvalidKeyChars.ReplaceAllString(snapshotData[0], "-")), + Size: snapshotData[1], + Created: snapshotData[2], + S3: true, + }, nil + case 4: + return &snapshot{ + Name: strings.ToLower(sb.InvalidKeyChars.ReplaceAllString(snapshotData[0], "-")), + Location: snapshotData[1], + Size: snapshotData[2], + Created: snapshotData[3], + S3: false, + }, nil + } + return nil, fmt.Errorf("input (%s) did not have 3 or 4 fields", input) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecluster/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecluster/controller.go new file mode 100644 index 0000000..60da040 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecluster/controller.go @@ -0,0 +1,86 @@ +package rkecluster + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + capiannotations "sigs.k8s.io/cluster-api/util/annotations" +) + +type handler struct { + rkeCluster rkecontroller.RKEClusterController + capiClusterCache capicontrollers.ClusterCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := handler{ + rkeCluster: clients.RKE.RKECluster(), + capiClusterCache: clients.CAPI.Cluster().Cache(), + } + + clients.RKE.RKECluster().OnChange(ctx, "rke-cluster", h.OnChange) + relatedresource.Watch(ctx, "rke-cluster-trigger", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if capiCluster, ok := obj.(*capi.Cluster); ok && !capiCluster.Spec.Paused { + return []relatedresource.Key{{ + Namespace: namespace, + Name: name, + }}, nil + } + return nil, nil + }, clients.RKE.RKECluster(), clients.CAPI.Cluster()) +} + +func (h *handler) OnChange(_ string, cluster *v1.RKECluster) (*v1.RKECluster, error) { + if cluster == nil { + return nil, nil + } + + capiCluster, err := capr.GetOwnerCAPICluster(cluster, h.capiClusterCache) + if apierrors.IsNotFound(err) { + logrus.Debugf("[rkecluster] %s/%s: waiting: CAPI cluster does not exist", cluster.Namespace, cluster.Name) + h.rkeCluster.EnqueueAfter(cluster.Namespace, cluster.Name, 10*time.Second) + return cluster, generic.ErrSkip + } + if err != nil { + logrus.Errorf("[rkecluster] %s/%s: error getting CAPI cluster %v", cluster.Namespace, cluster.Name, err) + return cluster, err + } + + if capiannotations.IsPaused(capiCluster, cluster) { + logrus.Infof("[rkecluster] %s/%s: waiting: CAPI cluster or RKECluster is paused", cluster.Namespace, cluster.Name) + return cluster, generic.ErrSkip + } + + if cluster.Spec.ControlPlaneEndpoint == nil || !cluster.Spec.ControlPlaneEndpoint.IsValid() { + cluster := cluster.DeepCopy() + cluster.Spec.ControlPlaneEndpoint = &capi.APIEndpoint{ + Host: "localhost", + Port: 6443, + } + logrus.Debugf("[rkecluster] %s/%s: setting controlplane endpoint", cluster.Namespace, cluster.Name) + return h.rkeCluster.Update(cluster) + } + + if len(cluster.Status.Conditions) > 0 || cluster.Status.Ready != true { + cluster := cluster.DeepCopy() + // the rke2.Ready and rke2.Removed conditions may still be present on the object, remove them if present + cluster.Status.Conditions = nil + cluster.Status.Ready = true + logrus.Tracef("[rkecluster] %s/%s: removing stale conditions", cluster.Namespace, cluster.Name) + logrus.Debugf("[rkecluster] %s/%s: marking cluster ready", cluster.Namespace, cluster.Name) + return h.rkeCluster.UpdateStatus(cluster) + } + + return cluster, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecontrolplane/controlplane.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecontrolplane/controlplane.go new file mode 100644 index 0000000..be0a93e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/rkecontrolplane/controlplane.go @@ -0,0 +1,137 @@ +package rkecontrolplane + +import ( + "context" + "fmt" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/management/clusterconnected" + provcluster "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + provcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontrollers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/equality" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + clusterCache: clients.Mgmt.Cluster().Cache(), + provClusterCache: clients.Provisioning.Cluster().Cache(), + rkeControlPlaneController: clients.RKE.RKEControlPlane(), + machineDeploymentClient: clients.CAPI.MachineDeployment(), + machineDeploymentCache: clients.CAPI.MachineDeployment().Cache(), + machineCache: clients.CAPI.Machine().Cache(), + machineClient: clients.CAPI.Machine(), + } + + rkecontrollers.RegisterRKEControlPlaneStatusHandler(ctx, clients.RKE.RKEControlPlane(), + "", "rke-control-plane", h.OnChange) + relatedresource.Watch(ctx, "rke-control-plane-trigger", h.clusterWatch, clients.RKE.RKEControlPlane(), clients.Mgmt.Cluster()) + + clients.RKE.RKEControlPlane().OnRemove(ctx, "rke-control-plane-remove", h.OnRemove) +} + +type handler struct { + clusterCache mgmtcontrollers.ClusterCache + provClusterCache provcontrollers.ClusterCache + rkeControlPlaneController rkecontrollers.RKEControlPlaneController + machineDeploymentClient capicontrollers.MachineDeploymentClient + machineDeploymentCache capicontrollers.MachineDeploymentCache + machineCache capicontrollers.MachineCache + machineClient capicontrollers.MachineClient +} + +func (h *handler) clusterWatch(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + cluster, ok := obj.(*v3.Cluster) + if !ok { + return nil, nil + } + + provClusters, err := h.provClusterCache.GetByIndex(provcluster.ByCluster, cluster.Name) + if err != nil || len(provClusters) == 0 { + return nil, err + } + return []relatedresource.Key{ + { + Namespace: provClusters[0].Namespace, + Name: provClusters[0].Name, + }, + }, nil +} + +func (h *handler) OnChange(obj *rkev1.RKEControlPlane, status rkev1.RKEControlPlaneStatus) (rkev1.RKEControlPlaneStatus, error) { + status.ObservedGeneration = obj.Generation + cluster, err := h.clusterCache.Get(obj.Spec.ManagementClusterName) + if err != nil { + h.rkeControlPlaneController.EnqueueAfter(obj.Namespace, obj.Name, 2*time.Second) + return status, nil + } + + status.AgentConnected = clusterconnected.Connected.IsTrue(cluster) + return status, nil +} + +func (h *handler) OnRemove(_ string, cp *rkev1.RKEControlPlane) (*rkev1.RKEControlPlane, error) { + status := cp.Status + cp = cp.DeepCopy() + + err := capr.DoRemoveAndUpdateStatus(cp, h.doRemove(cp), h.rkeControlPlaneController.EnqueueAfter) + + if equality.Semantic.DeepEqual(status, cp.Status) { + return cp, err + } + cp, updateErr := h.rkeControlPlaneController.UpdateStatus(cp) + if updateErr != nil { + return cp, updateErr + } + + return cp, err +} + +func (h *handler) doRemove(cp *rkev1.RKEControlPlane) func() (string, error) { + return func() (string, error) { + logrus.Debugf("[rkecontrolplane] (%s/%s) Peforming removal of rkecontrolplane", cp.Namespace, cp.Name) + // Control plane nodes are managed by the control plane object. Therefore, the control plane object shouldn't be cleaned up before the control plane nodes are removed. + machines, err := h.machineCache.List(cp.Namespace, labels.SelectorFromSet(labels.Set{capi.ClusterNameLabel: cp.Name, capr.ControlPlaneRoleLabel: "true"})) + if err != nil { + return "", err + } + + // Some machines may not have gotten the CAPI cluster-name label in previous versions in Rancher. + // Because of update issues with the conversion webhook in rancher-webhook, we can't use a "migration" to add the label (it will fail because the conversion webhook is not available). + // In addition, there is no way to "or" label selectors in the API, so we need to do this manually. + otherMachines, err := h.machineCache.List(cp.Namespace, labels.SelectorFromSet(labels.Set{capr.ClusterNameLabel: cp.Name, capr.ControlPlaneRoleLabel: "true"})) + if err != nil { + return "", err + } + + logrus.Debugf("[rkecontrolplane] (%s/%s) listed %d machines during removal", cp.Namespace, cp.Name, len(machines)) + logrus.Tracef("[rkecontrolplane] (%s/%s) machine list: %+v", cp.Namespace, cp.Name, machines) + allMachines := append(machines, otherMachines...) + + for _, machine := range allMachines { + // Only delete custom machines. Custom machines can be added outside the UI, so it is important to check each machine. + if machine.Spec.InfrastructureRef.APIVersion != "rke.cattle.io/v1" || machine.Spec.InfrastructureRef.Kind != "CustomMachine" { + continue + } + if machine.DeletionTimestamp == nil { + if err = h.machineClient.Delete(machine.Namespace, machine.Name, &metav1.DeleteOptions{}); err != nil { + return "", fmt.Errorf("error deleting machine %s/%s: %v", machine.Namespace, machine.Name, err) + } + } + } + + return capr.GetMachineDeletionStatus(allMachines) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/unmanaged/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/unmanaged/controller.go new file mode 100644 index 0000000..d6d223b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/capr/unmanaged/controller.go @@ -0,0 +1,403 @@ +package unmanaged + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterindex" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rocontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/taints" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/data" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kv" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + capi "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/util/conditions" +) + +const UnmanagedMachineKind = "CustomMachine" + +func Register(ctx context.Context, clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + h := handler{ + kubeconfigManager: kubeconfigManager, + unmanagedMachine: clients.RKE.CustomMachine(), + rkeClusterCache: clients.RKE.RKECluster().Cache(), + mgmtClusterCache: clients.Mgmt.Cluster().Cache(), + clusterCache: clients.Provisioning.Cluster().Cache(), + capiClusterCache: clients.CAPI.Cluster().Cache(), + machineCache: clients.CAPI.Machine().Cache(), + machineClient: clients.CAPI.Machine(), + secrets: clients.Core.Secret(), + apply: clients.Apply.WithSetID("unmanaged-machine"). + WithCacheTypes( + clients.Mgmt.Cluster(), + clients.Provisioning.Cluster(), + clients.RKE.CustomMachine(), + clients.CAPI.Machine(), + clients.RKE.RKEBootstrap()), + } + clients.RKE.CustomMachine().OnRemove(ctx, "unmanaged-machine", h.onUnmanagedMachineOnRemove) + clients.RKE.CustomMachine().OnChange(ctx, "unmanaged-health", h.onUnmanagedMachineChange) + clients.Core.Secret().OnChange(ctx, "unmanaged-machine-secret", h.onSecretChange) + + relatedresource.Watch(ctx, "unmanaged-machine", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if rkeCluster, ok := obj.(*rkev1.RKECluster); ok { + var relatedResources []relatedresource.Key + if rkeCluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation] != "" { + logrus.Tracef("[unmanaged] handling related resource for RKECluster %s/%s", rkeCluster.Namespace, rkeCluster.Name) + machines, err := clients.CAPI.Machine().List(rkeCluster.Namespace, metav1.ListOptions{LabelSelector: capi.ClusterNameLabel + "=" + rkeCluster.Annotations[capi.ClusterNameLabel]}) + if err != nil { + return nil, err + } + for _, m := range machines.Items { + if m.Spec.InfrastructureRef.Kind == UnmanagedMachineKind && m.Spec.InfrastructureRef.APIVersion == capr.RKEAPIVersion && machineHasNodeNotFoundCondition(&m) { + relatedResources = append(relatedResources, relatedresource.Key{ + Namespace: m.Spec.InfrastructureRef.Namespace, + Name: m.Spec.InfrastructureRef.Name, + }) + } + } + } + return relatedResources, nil + } else if m, ok := obj.(*capi.Machine); ok { + if m.Spec.InfrastructureRef.Kind == UnmanagedMachineKind && m.Spec.InfrastructureRef.APIVersion == capr.RKEAPIVersion { + logrus.Tracef("[unmanaged] handling related resource for CAPI machine %s/%s", m.Namespace, m.Name) + rkeCluster, err := clients.RKE.RKECluster().Get(m.Namespace, m.Spec.ClusterName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + if rkeCluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation] != "" && machineHasNodeNotFoundCondition(m) { + logrus.Tracef("[unmanaged] machine %s/%s has node not found condition", m.Namespace, m.Name) + return []relatedresource.Key{{ + Namespace: m.Spec.InfrastructureRef.Namespace, + Name: m.Spec.InfrastructureRef.Name, + }}, nil + } + } + } + return nil, nil + }, clients.RKE.CustomMachine(), clients.RKE.RKECluster(), clients.CAPI.Machine()) +} + +type handler struct { + kubeconfigManager *kubeconfig.Manager + unmanagedMachine rkecontroller.CustomMachineController + rkeClusterCache rkecontroller.RKEClusterCache + mgmtClusterCache mgmtcontroller.ClusterCache + capiClusterCache capicontrollers.ClusterCache + machineCache capicontrollers.MachineCache + machineClient capicontrollers.MachineClient + clusterCache rocontrollers.ClusterCache + secrets corecontrollers.SecretClient + apply apply.Apply +} + +func (h *handler) findMachine(cluster *capi.Cluster, machineName, machineID string) (string, error) { + _, err := h.machineCache.Get(cluster.Namespace, machineName) + if apierror.IsNotFound(err) { + machines, err := h.machineCache.List(cluster.Namespace, labels.SelectorFromSet(map[string]string{ + capr.MachineIDLabel: machineID, + })) + if len(machines) != 1 || err != nil || machines[0].Spec.ClusterName != cluster.Name { + return "", err + } + return machines[0].Name, nil + } else if err != nil { + return "", err + } + + return machineName, nil +} + +func (h *handler) onSecretChange(_ string, secret *corev1.Secret) (*corev1.Secret, error) { + if secret == nil || secret.Type != capr.MachineRequestType { + return secret, nil + } + + go func() { + // Only keep requests for 1 minute + time.Sleep(time.Minute) + _ = h.secrets.Delete(secret.Namespace, secret.Name, nil) + }() + + data := data.Object{} + if err := json.Unmarshal(secret.Data["data"], &data); err != nil { + // ignore invalid json, wait until it's valid + return secret, nil + } + + capiCluster, err := h.getCAPICluster(secret) + if err != nil { + return secret, err + } else if capiCluster == nil { + return secret, nil + } + + machineName, err := h.findMachine(capiCluster, secret.Name, data.String("id")) + if err != nil { + return nil, err + } else if machineName == "" { + machineName = secret.Name + if err = h.createMachine(capiCluster, secret, data); err != nil { + return nil, err + } + } + + if secret.Labels[capr.MachineNamespaceLabel] != capiCluster.Namespace || + secret.Labels[capr.MachineNameLabel] != machineName { + secret = secret.DeepCopy() + if secret.Labels == nil { + secret.Labels = map[string]string{} + } + secret.Labels[capr.MachineNamespaceLabel] = capiCluster.Namespace + secret.Labels[capr.MachineNameLabel] = machineName + + return h.secrets.Update(secret) + } + + return secret, nil +} + +func (h *handler) createMachine(capiCluster *capi.Cluster, secret *corev1.Secret, data data.Object) error { + objs, err := h.createMachineObjects(capiCluster, secret.Name, data) + if err != nil { + return err + } + return h.apply.WithOwner(secret).ApplyObjects(objs...) +} + +func (h *handler) createMachineObjects(capiCluster *capi.Cluster, machineName string, data data.Object) ([]runtime.Object, error) { + labels := map[string]string{} + annotations := map[string]string{} + + if data.Bool("role-control-plane") { + labels[capr.ControlPlaneRoleLabel] = "true" + labels[capi.MachineControlPlaneLabel] = "true" + } + if data.Bool("role-etcd") { + labels[capr.EtcdRoleLabel] = "true" + } + if data.Bool("role-worker") { + labels[capr.WorkerRoleLabel] = "true" + } + if val := data.String("node-name"); val != "" { + labels[capr.NodeNameLabel] = val + } + if address := data.String("address"); address != "" { + annotations[capr.AddressAnnotation] = address + } + if internalAddress := data.String("internal-address"); internalAddress != "" { + annotations[capr.InternalAddressAnnotation] = internalAddress + } + + labels[capr.MachineIDLabel] = data.String("id") + labels[capr.ClusterNameLabel] = capiCluster.Name + labels[capi.ClusterNameLabel] = capiCluster.Name + + labelsMap := map[string]string{} + for _, str := range strings.Split(data.String("labels"), ",") { + k, v := kv.Split(str, "=") + if k == "" { + continue + } + labelsMap[k] = v + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + + if len(labelsMap) > 0 { + data, err := json.Marshal(labelsMap) + if err != nil { + return nil, err + } + annotations[capr.LabelsAnnotation] = string(data) + } + + var coreTaints []corev1.Taint + for _, taint := range data.StringSlice("taints") { + coreTaints = append(coreTaints, taints.GetTaintsFromStrings(strings.Split(taint, ","))...) + } + + if len(coreTaints) > 0 { + data, err := json.Marshal(coreTaints) + if err != nil { + return nil, err + } + annotations[capr.TaintsAnnotation] = string(data) + } + + return []runtime.Object{ + &rkev1.RKEBootstrap{ + ObjectMeta: metav1.ObjectMeta{ + Name: machineName, + Namespace: capiCluster.Namespace, + Labels: labels, + Annotations: annotations, + }, + Spec: rkev1.RKEBootstrapSpec{ + ClusterName: capiCluster.Name, + }, + }, + &rkev1.CustomMachine{ + ObjectMeta: metav1.ObjectMeta{ + Name: machineName, + Namespace: capiCluster.Namespace, + Labels: labels, + }, + }, + &capi.Machine{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: machineName, + Namespace: capiCluster.Namespace, + Labels: labels, + }, + Spec: capi.MachineSpec{ + ClusterName: capiCluster.Name, + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + Kind: "RKEBootstrap", + Namespace: capiCluster.Namespace, + Name: machineName, + APIVersion: capr.RKEAPIVersion, + }, + }, + InfrastructureRef: corev1.ObjectReference{ + Kind: UnmanagedMachineKind, + Namespace: capiCluster.Namespace, + Name: machineName, + APIVersion: capr.RKEAPIVersion, + }, + }, + }, + }, nil +} + +func (h *handler) getCAPICluster(secret *corev1.Secret) (*capi.Cluster, error) { + cluster, err := h.mgmtClusterCache.Get(secret.Namespace) + if apierror.IsNotFound(err) { + return nil, nil + } else if err != nil { + return nil, err + } + + rClusters, err := h.clusterCache.GetByIndex(clusterindex.ClusterV1ByClusterV3Reference, cluster.Name) + if err != nil || len(rClusters) == 0 { + return nil, err + } + + return h.capiClusterCache.Get(rClusters[0].Namespace, rClusters[0].Name) +} + +func (h *handler) onUnmanagedMachineOnRemove(_ string, customMachine *rkev1.CustomMachine) (*rkev1.CustomMachine, error) { + // We may want to look at using a migration to remove this finalizer. + return customMachine, nil +} + +func (h *handler) onUnmanagedMachineChange(_ string, customMachine *rkev1.CustomMachine) (*rkev1.CustomMachine, error) { + if customMachine == nil { + return customMachine, nil + } + if !capr.Ready.IsTrue(customMachine) { + // CustomMachines are provisioned already, so their Ready condition should be true. + customMachine = customMachine.DeepCopy() + capr.Ready.SetStatus(customMachine, "True") + capr.Ready.Message(customMachine, "") + return h.unmanagedMachine.UpdateStatus(customMachine) + } + if !customMachine.Status.Ready && customMachine.Spec.ProviderID != "" { + customMachine = customMachine.DeepCopy() + customMachine.Status.Ready = true + return h.unmanagedMachine.UpdateStatus(customMachine) + } + + clusterName := customMachine.Labels[capi.ClusterNameLabel] + rkeCluster, err := h.rkeClusterCache.Get(customMachine.Namespace, clusterName) + if err != nil { + return customMachine, err + } + + if rkeCluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation] != "" { + if customMachine.Spec.ProviderID == "" || !customMachine.Status.Ready { + return customMachine, nil + } + + capiMachine, err := capr.GetMachineByOwner(h.machineCache, customMachine) + if err != nil { + if errors.Is(err, capr.ErrNoMachineOwnerRef) { + return customMachine, nil + } + return customMachine, err + } + + if machineHasNodeNotFoundCondition(capiMachine) { + if capiMachine.Status.NodeRef == nil { + return customMachine, nil + } + logrus.Tracef("[unmanaged] RKECluster %s/%s related to CustomMachine %s/%s specifies deletion after duration (%s), and machine was not found per CAPI, evaluating machine for potential deletion", rkeCluster.Namespace, rkeCluster.Name, customMachine.Namespace, customMachine.Name, rkeCluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation]) + d, err := time.ParseDuration(rkeCluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation]) + if err != nil { + return customMachine, err + } + lastTransition := conditions.GetLastTransitionTime(capiMachine, capi.MachineNodeHealthyCondition) + if lastTransition == nil { + return customMachine, fmt.Errorf("error retrieving last transition time for condition %s of Machine %s/%s related to CustomMachine %s/%s", capi.MachineNodeHealthyCondition, capiMachine.Namespace, capiMachine.Name, customMachine.Namespace, customMachine.Name) + } + now := time.Now() + if now.After(lastTransition.Time.Add(d)) { + cluster, err := h.clusterCache.Get(capiMachine.Namespace, capiMachine.Spec.ClusterName) + if err != nil { + return customMachine, err + } + + restConfig, err := h.kubeconfigManager.GetRESTConfig(cluster, cluster.Status) + if err != nil { + return customMachine, err + } + + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return customMachine, err + } + + _, err = clientset.CoreV1().Nodes().Get(context.Background(), capiMachine.Status.NodeRef.Name, metav1.GetOptions{}) + if apierror.IsNotFound(err) { + logrus.Infof("[unmanaged] CustomMachine %s/%s NodeNotFound condition transition time (%s) was past specified deletion duration (%s), proceeding with delete", customMachine.Namespace, customMachine.Name, lastTransition.String(), d.String()) + if err := h.machineClient.Delete(capiMachine.Namespace, capiMachine.Name, nil); err != nil { + return customMachine, err + } + } + logrus.Errorf("[unmanaged] CustomMachine %s/%s NodeNotFound condition transition time (%s) was past specified deletion duration (%s), but unable to validate node (%s) was actually missing in downstream cluster: %v", customMachine.Namespace, customMachine.Name, lastTransition.String(), d.String(), capiMachine.Status.NodeRef.Name, err) + return customMachine, err + } + nextEnqueueDuration := lastTransition.Time.Add(d).Sub(now) + logrus.Debugf("[unmanaged] CustomMachine %s/%s NodeNotFound condition last transition time (%s) was not past specified deletion duration (%s), enqueuing after %s", customMachine.Namespace, customMachine.Name, lastTransition.String(), d.String(), nextEnqueueDuration) + h.unmanagedMachine.EnqueueAfter(customMachine.Namespace, customMachine.Name, nextEnqueueDuration) + } + } + return customMachine, nil +} + +func machineHasNodeNotFoundCondition(capiMachine *capi.Machine) bool { + return conditions.IsFalse(capiMachine, capi.MachineNodeHealthyCondition) && (conditions.GetReason(capiMachine, capi.MachineNodeHealthyCondition) == capi.NodeNotFoundReason) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/apiservice.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/apiservice.go new file mode 100644 index 0000000..aa3fe2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/apiservice.go @@ -0,0 +1,159 @@ +package apiservice + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + appscontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" +) + +type handler struct { + serviceAccounts corev1controllers.ServiceAccountCache + deploymentCache appscontrollers.DeploymentCache + daemonSetCache appscontrollers.DaemonSetCache + secretsCache corev1controllers.SecretCache + secretsClient corev1controllers.SecretClient + settings mgmtcontrollers.SettingClient + apiServices mgmtcontrollers.APIServiceCache + services corev1controllers.ServiceCache + embedded bool + k8s kubernetes.Interface + ctx context.Context +} + +func Register(ctx context.Context, context *wrangler.Context, embedded bool) { + h := &handler{ + serviceAccounts: context.Core.ServiceAccount().Cache(), + deploymentCache: context.Apps.Deployment().Cache(), + daemonSetCache: context.Apps.DaemonSet().Cache(), + secretsCache: context.Core.Secret().Cache(), + secretsClient: context.Core.Secret(), + settings: context.Mgmt.Setting(), + apiServices: context.Mgmt.APIService().Cache(), + services: context.Core.Service().Cache(), + embedded: embedded, + k8s: context.K8s, + ctx: ctx, + } + + relatedresource.WatchClusterScoped(ctx, "apiservice-watch-owner", + relatedresource.OwnerResolver(false, v3.SchemeGroupVersion.String(), "APIService"), + context.Mgmt.APIService(), context.Core.ServiceAccount()) + + relatedresource.WatchClusterScoped(ctx, "apiservice-watch-settings", h.resolveSettingToAPIServices, + context.Mgmt.APIService(), context.Mgmt.Setting()) + + context.Mgmt.Setting().OnChange(ctx, "apiservice-settings", h.SetupInternalServerURL) + mgmtcontrollers.RegisterAPIServiceGeneratingHandler(ctx, context.Mgmt.APIService(), + context.Apply. + WithSetOwnerReference(true, false). + WithCacheTypes(context.Core.ServiceAccount(), + context.Core.Secret()), + "", "apiservice", h.OnChange, nil) +} + +func (h *handler) resolveSettingToAPIServices(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if name != settings.ServerURL.Name { + return nil, nil + } + services, err := h.apiServices.List(labels.Everything()) + if err != nil { + return nil, err + } + var result []relatedresource.Key + for _, service := range services { + result = append(result, relatedresource.Key{ + Name: service.Name, + }) + } + return result, nil +} + +func (h *handler) OnChange(obj *v3.APIService, status v3.APIServiceStatus) ([]runtime.Object, v3.APIServiceStatus, error) { + sa := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(obj.Name, "api-service"), + Namespace: namespace.System, + }, + } + + objs := []runtime.Object{ + sa, + } + + status.ServiceAccountName = sa.Name + status.ServiceAccountNamespace = sa.Namespace + + if obj.Spec.SecretNamespace == "" || + obj.Spec.SecretName == "" { + return objs, status, nil + } + + token, err := h.getToken(sa) + if err != nil || len(token) == 0 { + return objs, status, err + } + + if len(token) == 0 { + return objs, status, nil + } + + internalServer := settings.InternalServerURL.Get() + if internalServer == "" { + return objs, status, nil + } + internalCA := settings.InternalCACerts.Get() + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: obj.Spec.SecretName, + Namespace: obj.Spec.SecretNamespace, + }, + Data: map[string][]byte{ + "token": []byte(token), + "url": []byte(internalServer + "/v3/connect"), + }, + } + if len(internalCA) > 0 { + secret.Data["ca.crt"] = []byte(internalCA) + } + + return append(objs, secret), status, nil +} + +func (h *handler) getToken(sa *corev1.ServiceAccount) (string, error) { + sa, err := h.serviceAccounts.Get(sa.Namespace, sa.Name) + if apierror.IsNotFound(err) { + return "", nil + } else if err != nil { + return "", err + } + + // create a secret-based token for the service account if one does not exist + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(h.ctx, h.secretsCache, h.k8s, sa) + if err != nil { + return "", fmt.Errorf("error ensuring secret for service account [%s:%s]: %w", sa.Namespace, sa.Name, err) + } + token := secret.Data[v1.ServiceAccountTokenKey] + + hash := sha256.Sum256(token) + return base64.StdEncoding.EncodeToString(hash[:]), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/setting.go new file mode 100644 index 0000000..761b119 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/apiservice/setting.go @@ -0,0 +1,89 @@ +package apiservice + +import ( + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + corev1 "k8s.io/api/core/v1" +) + +const RancherServiceName = "rancher" + +func (h *handler) SetupInternalServerURL(key string, setting *v3.Setting) (*v3.Setting, error) { + if key != settings.ServerURL.Name { + return setting, nil + } + + internalURL, internalCA, err := h.getInternalServerAndURL() + if err != nil { + return nil, err + } + + // purposely update CA before URL, because we only wait for internalURL != "" when checking if it's initialized + if settings.InternalCACerts.Get() != internalCA { + if err := settings.InternalCACerts.Set(internalCA); err != nil { + return setting, err + } + } + + if settings.InternalServerURL.Get() != internalURL { + if err := settings.InternalServerURL.Set(internalURL); err != nil { + return setting, err + } + } + + return setting, nil +} + +func (h *handler) getClusterIP() (string, error) { + serviceName := RancherServiceName + if features.MCMAgent.Enabled() { + serviceName = "cattle-cluster-agent" + } + service, err := h.services.Get(namespace.System, serviceName) + if err != nil { + return "", err + } + if service.Spec.ClusterIP == "" { + return "", fmt.Errorf("waiting on service %s/%s to be assigned a ClusterIP", namespace.System, serviceName) + } + return service.Spec.ClusterIP, nil +} + +func (h *handler) getInternalServerAndURL() (string, string, error) { + serverURL := settings.ServerURL.Get() + ca := settings.CACerts.Get() + + tlsSecret, err := h.secretsCache.Get(namespace.System, "tls-rancher-internal-ca") + if err != nil { + return "", "", err + } + internalCA := string(tlsSecret.Data[corev1.TLSCertKey]) + + clusterIPService := false + if features.MCMAgent.Enabled() { + if _, err := h.deploymentCache.Get(namespace.System, "cattle-cluster-agent"); err == nil { + clusterIPService = true + } + } else { + if dp, err := h.deploymentCache.Get(namespace.System, RancherServiceName); err == nil && dp.Spec.Replicas != nil && *dp.Spec.Replicas != 0 { + clusterIPService = true + } else if _, err := h.daemonSetCache.Get(namespace.System, RancherServiceName); err == nil { + clusterIPService = true + } + } + + if h.embedded { + clusterIPService = true + } + + if clusterIPService { + clusterIP, err := h.getClusterIP() + return fmt.Sprintf("https://%s", clusterIP), internalCA, err + } + + return serverURL, ca, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart.go new file mode 100644 index 0000000..2fcc2bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart.go @@ -0,0 +1,101 @@ +// Package chart is used for defining helm chart information. +package chart + +import ( + "errors" + "fmt" + + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/yaml" +) + +const ( + // PriorityClassKey is the name of the helm value used for setting the name of the priority class on pods deployed by rancher and feature charts. + PriorityClassKey = "priorityClassName" + + // CustomValueMapName is the name of the configMap that hold custom values for charts managed by Rancher. + CustomValueMapName = "rancher-config" + + // WebhookChartName name of the chart for rancher-webhook. + WebhookChartName = "rancher-webhook" + + // ProvisioningCAPIChartName name of the chart for rancher-provisioning-capi. + ProvisioningCAPIChartName = "rancher-provisioning-capi" +) + +var errKeyNotFound = errors.New("key not found") + +// Manager is an interface used by the handler to install and uninstall charts. +// If the interface is changed, regenerate the mock with the below command (run from project root): +// mockgen --build_flags=--mod=mod -destination=pkg/controllers/dashboard/chart/fake/manager.go -package=fake github.com/rancher/rancher/pkg/controllers/dashboard/chart Manager +type Manager interface { + // Ensure ensures that the chart is installed into the given namespace with the given version configuration and values. + Ensure(namespace, name, minVersion, exactVersion string, values map[string]interface{}, takeOwnership bool, installImageOverride string) error + + // Uninstall uninstalls the given chart in the given namespace. + Uninstall(namespace, name string) error + + // Remove removes the chart from the desired state. + Remove(namespace, name string) +} + +// Definition defines a helm chart. +type Definition struct { + ReleaseNamespace string + ChartName string + MinVersionSetting settings.Setting + ExactVersionSetting settings.Setting + Values func() map[string]interface{} + Enabled func() bool + Uninstall bool + RemoveNamespace bool +} + +// RancherConfigGetter is used to get Rancher chart configuration information from the rancher config map. +type RancherConfigGetter struct { + ConfigCache corev1.ConfigMapCache +} + +// GetPriorityClassName attempts to retrieve the priority class for rancher pods and feature charts as set via helm values. +func (r *RancherConfigGetter) GetGlobalValue(key string) (string, error) { + return r.getKey(key, settings.ConfigMapName.Get()) +} + +// GetChartValues attempts to retrieve charts values for the specified chart from the rancher-config configMap. +func (r *RancherConfigGetter) GetChartValues(chartName string) (map[string]any, error) { + strVal, err := r.getKey(chartName, CustomValueMapName) + if err != nil { + return nil, err + } + retValues := map[string]any{} + err = yaml.Unmarshal([]byte(strVal), &retValues) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal '%s' value: %w", chartName, err) + } + return retValues, nil +} + +// getKey attempts to retrieve the provided key for rancher config map. +func (r *RancherConfigGetter) getKey(key, configName string) (string, error) { + configMap, err := r.ConfigCache.Get(namespace.System, configName) + if err != nil { + return "", fmt.Errorf("failed to get ConfigMap '%s': %w", configName, err) + } + notFoundErr := fmt.Errorf("'%s' %w in ConfigMap '%s'", key, errKeyNotFound, configMap.Name) + if configMap.Data == nil { + return "", notFoundErr + } + keyValue, ok := configMap.Data[key] + if !ok { + return "", notFoundErr + } + return keyValue, nil +} + +// IsNotFoundError returns true if the error was caused by either the desired key or ConfigMap not being found. +func IsNotFoundError(err error) bool { + return apierror.IsNotFound(err) || errors.Is(err, errKeyNotFound) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart_test.go new file mode 100644 index 0000000..156b6fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/chart_test.go @@ -0,0 +1,189 @@ +package chart_test + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var errTest = fmt.Errorf("test error") + +const ( + priorityClassName = "rancher-critical" + testKey = "testKey" + testValue = "newValue" +) + +func TestGetPriorityClassNameFromRancherConfigMap(t *testing.T) { + ctrl := gomock.NewController(t) + configCache := fake.NewMockCacheInterface[*v1.ConfigMap](ctrl) + configCache.EXPECT().Get(namespace.System, "set-config").Return(&v1.ConfigMap{Data: map[string]string{"priorityClassName": priorityClassName, testKey: testValue}}, nil).AnyTimes() + configCache.EXPECT().Get(namespace.System, "empty-config").Return(&v1.ConfigMap{}, nil).AnyTimes() + configCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("not found")).AnyTimes() + + tests := []*struct { + name string + want string + key string + wantErr bool + setup func() + }{ + // base case config map set. + { + name: "correctly set priority class name", + key: chart.PriorityClassKey, + want: priorityClassName, + wantErr: false, + setup: func() { settings.ConfigMapName.Set("set-config") }, + }, + // base case config map set. + { + name: "correctly get test key name", + key: testKey, + want: testValue, + wantErr: false, + setup: func() { settings.ConfigMapName.Set("set-config") }, + }, + // config map name is empty. + { + name: "empty configMap name", + key: chart.PriorityClassKey, + want: "", + wantErr: true, + setup: func() { settings.ConfigMapName.Set("") }, + }, + // config map doesn't exist. + { + name: "unknown config map name", + key: chart.PriorityClassKey, + want: "", + wantErr: true, + setup: func() { settings.ConfigMapName.Set("unknown-config-name") }, + }, + // config map exist doesn't have priority class. + { + name: "empty config map", + key: chart.PriorityClassKey, + want: "", + wantErr: true, + setup: func() { settings.ConfigMapName.Set("empty-config") }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.setup() + getter := chart.RancherConfigGetter{configCache} + got, err := getter.GetGlobalValue(tt.key) + if tt.wantErr { + assert.Error(t, err, "Expected test to error.") + return + } + assert.NoError(t, err, "failed to get priority class.") + assert.Equal(t, tt.want, got, "Unexpected priorityClassName returned") + }) + } +} + +func TestGetChartValue(t *testing.T) { + const yamlInfo = "yamlKey: yamlValue" + const invalidYaml = "%{'foo':'bar " + + tests := []*struct { + name string + want map[string]any + chartName string + wantErr bool + notFound bool + setup func(*fake.MockCacheInterface[*v1.ConfigMap]) + }{ + { + name: "correctly get webhook values", + want: map[string]any{"yamlKey": "yamlValue"}, + chartName: chart.WebhookChartName, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(&v1.ConfigMap{Data: map[string]string{chart.WebhookChartName: yamlInfo}}, nil) + }, + }, + + { + name: "webhook values are invalid yaml", + chartName: chart.WebhookChartName, + wantErr: true, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(&v1.ConfigMap{Data: map[string]string{chart.WebhookChartName: invalidYaml}}, nil) + }, + }, + { + name: "value not in map", + chartName: chart.WebhookChartName, + wantErr: true, + notFound: true, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(&v1.ConfigMap{Data: map[string]string{}}, nil) + }, + }, + { + name: "map is nil", + chartName: chart.WebhookChartName, + wantErr: true, + notFound: true, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(&v1.ConfigMap{Data: nil}, nil) + }, + }, + { + name: "rancher config does not exist", + chartName: chart.WebhookChartName, + wantErr: true, + notFound: true, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(nil, apierror.NewNotFound(schema.GroupResource{}, chart.CustomValueMapName)) + }, + }, + { + name: "rancher config get failed", + chartName: chart.WebhookChartName, + wantErr: true, + notFound: false, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(nil, errTest) + }, + }, + { + name: "webhook value does not used deprecated configMap setting", + chartName: chart.WebhookChartName, + want: map[string]any{"yamlKey": "yamlValue"}, + setup: func(configCache *fake.MockCacheInterface[*v1.ConfigMap]) { + settings.ConfigMapName.Set("unknown-config-name") + configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(&v1.ConfigMap{Data: map[string]string{chart.WebhookChartName: yamlInfo}}, nil) + }, + }, + } + for _, tt := range tests { + test := tt + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + configCache := fake.NewMockCacheInterface[*v1.ConfigMap](ctrl) + test.setup(configCache) + getter := chart.RancherConfigGetter{configCache} + got, err := getter.GetChartValues(test.chartName) + if test.wantErr { + assert.Equal(t, test.notFound, chart.IsNotFoundError(err)) + assert.Error(t, err, "Expected test to error.") + return + } + assert.NoError(t, err, "failed to get priority class.") + assert.Equal(t, test.want, got, "Unexpected priorityClassName returned") + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/fake/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/fake/manager.go new file mode 100644 index 0000000..d26b3cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/chart/fake/manager.go @@ -0,0 +1,74 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/controllers/dashboard/chart (interfaces: Manager) + +// Package fake is a generated GoMock package. +package fake + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockManager is a mock of Manager interface. +type MockManager struct { + ctrl *gomock.Controller + recorder *MockManagerMockRecorder +} + +// MockManagerMockRecorder is the mock recorder for MockManager. +type MockManagerMockRecorder struct { + mock *MockManager +} + +// NewMockManager creates a new mock instance. +func NewMockManager(ctrl *gomock.Controller) *MockManager { + mock := &MockManager{ctrl: ctrl} + mock.recorder = &MockManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockManager) EXPECT() *MockManagerMockRecorder { + return m.recorder +} + +// Ensure mocks base method. +func (m *MockManager) Ensure(arg0, arg1, arg2, arg3 string, arg4 map[string]interface{}, arg5 bool, arg6 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Ensure", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret0, _ := ret[0].(error) + return ret0 +} + +// Ensure indicates an expected call of Ensure. +func (mr *MockManagerMockRecorder) Ensure(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ensure", reflect.TypeOf((*MockManager)(nil).Ensure), arg0, arg1, arg2, arg3, arg4, arg5, arg6) +} + +// Remove mocks base method. +func (m *MockManager) Remove(arg0, arg1 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Remove", arg0, arg1) +} + +// Remove indicates an expected call of Remove. +func (mr *MockManagerMockRecorder) Remove(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockManager)(nil).Remove), arg0, arg1) +} + +// Uninstall mocks base method. +func (m *MockManager) Uninstall(arg0, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Uninstall", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Uninstall indicates an expected call of Uninstall. +func (mr *MockManagerMockRecorder) Uninstall(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Uninstall", reflect.TypeOf((*MockManager)(nil).Uninstall), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterindex/clusterindex.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterindex/clusterindex.go new file mode 100644 index 0000000..7b06fc0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterindex/clusterindex.go @@ -0,0 +1,36 @@ +package clusterindex + +import ( + "context" + + rancherv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + ClusterV1ByClusterV3Reference = "clusterByClusterReference" +) + +func Register(ctx context.Context, clients *wrangler.Context) { + clusterCache := clients.Provisioning.Cluster().Cache() + + clusterCache.AddIndexer(ClusterV1ByClusterV3Reference, func(obj *rancherv1.Cluster) ([]string, error) { + return []string{obj.Status.ClusterName}, nil + }) + + relatedresource.Watch(ctx, "cluster-v1-trigger", func(namespace, name string, obj runtime.Object) (result []relatedresource.Key, _ error) { + clusters, err := clusterCache.GetByIndex(ClusterV1ByClusterV3Reference, name) + if err != nil { + return nil, err + } + for _, cluster := range clusters { + result = append(result, relatedresource.Key{ + Namespace: cluster.Namespace, + Name: cluster.Name, + }) + } + return result, nil + }, clients.Provisioning.Cluster(), clients.Mgmt.Cluster()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars.go new file mode 100644 index 0000000..24addec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars.go @@ -0,0 +1,37 @@ +package clusterregistrationtoken + +import ( + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" +) + +type EnvType int + +const ( + Linux EnvType = iota + PowerShell + Docker +) + +func AgentEnvVars(cluster *v3.Cluster, envType EnvType) string { + var agentEnvVars []string + if cluster == nil { + return "" + } + for _, envVar := range cluster.Spec.AgentEnvVars { + if envVar.Value == "" { + continue + } + switch envType { + case Docker: + agentEnvVars = append(agentEnvVars, fmt.Sprintf("-e \"%s=%s\"", envVar.Name, envVar.Value)) + case PowerShell: + agentEnvVars = append(agentEnvVars, fmt.Sprintf("$env:%s=\"%s\";", envVar.Name, envVar.Value)) + default: + agentEnvVars = append(agentEnvVars, fmt.Sprintf("%s=\"%s\"", envVar.Name, envVar.Value)) + } + } + return strings.Join(agentEnvVars, " ") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars_test.go new file mode 100644 index 0000000..d02c11c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/agentvars_test.go @@ -0,0 +1,77 @@ +package clusterregistrationtoken + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" +) + +func TestAgentEnvVars(t *testing.T) { + c := &v3.Cluster{ + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + AgentEnvVars: []corev1.EnvVar{ + { + Name: "HTTPS_PROXY", + Value: "https://0.0.0.0", + }, + { + Name: "HTTP_PROXY", + Value: "http://0.0.0.0", + }, + }, + }, + }, + } + tests := []struct { + name string + cluster *v3.Cluster + envType EnvType + expected string + }{ + { + name: "Envvars should be an empty string with a nil cluster", + cluster: nil, + envType: Linux, + expected: "", + }, + { + name: "Envvars should be an empty string with no vars set on cluster", + cluster: &v3.Cluster{}, + envType: Linux, + expected: "", + }, + { + name: "Envvars should be formatted correctly for Linux", + cluster: c, + envType: Linux, + expected: "HTTPS_PROXY=\"https://0.0.0.0\" HTTP_PROXY=\"http://0.0.0.0\"", + }, + { + name: "Envvars should be formatted correctly for Docker", + cluster: c, + envType: Docker, + expected: "-e \"HTTPS_PROXY=https://0.0.0.0\" -e \"HTTP_PROXY=http://0.0.0.0\"", + }, + { + name: "Envvars should be formatted correctly for PowerShell", + cluster: c, + envType: PowerShell, + expected: "$env:HTTPS_PROXY=\"https://0.0.0.0\"; $env:HTTP_PROXY=\"http://0.0.0.0\";", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // arrange + a := assert.New(t) + + // act + evars := AgentEnvVars(tt.cluster, tt.envType) + + // assert + a.Equal(tt.expected, evars) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/clusterregistrationtoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/clusterregistrationtoken.go new file mode 100644 index 0000000..79b3eb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/clusterregistrationtoken.go @@ -0,0 +1,73 @@ +package clusterregistrationtoken + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v32 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/labels" +) + +type handler struct { + clusterRegistrationTokenCache v32.ClusterRegistrationTokenCache + clusterRegistrationTokenController v32.ClusterRegistrationTokenController + clusters v32.ClusterCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + clusterRegistrationTokenController: clients.Mgmt.ClusterRegistrationToken(), + clusterRegistrationTokenCache: clients.Mgmt.ClusterRegistrationToken().Cache(), + clusters: clients.Mgmt.Cluster().Cache(), + } + clients.Mgmt.ClusterRegistrationToken().OnChange(ctx, "cluster-registration-token", h.onChange) + clients.Mgmt.Cluster().OnChange(ctx, "cluster-registration-token-trigger", h.onClusterChange) + +} + +func (h *handler) onClusterChange(key string, obj *v3.Cluster) (*v3.Cluster, error) { + if obj == nil { + return obj, nil + } + + crts, err := h.clusterRegistrationTokenCache.List(obj.Name, labels.Everything()) + if err != nil { + return obj, nil + } + + for _, crt := range crts { + h.clusterRegistrationTokenController.Enqueue(crt.Namespace, crt.Name) + } + + return obj, nil +} + +func (h *handler) onChange(key string, obj *v3.ClusterRegistrationToken) (_ *v3.ClusterRegistrationToken, err error) { + if obj == nil { + return obj, nil + } + + if obj.Status.Token != "" { + newStatus, err := h.assignStatus(obj) + if err != nil { + return nil, err + } + if !equality.Semantic.DeepEqual(obj.Status, newStatus) { + obj = obj.DeepCopy() + obj.Status = newStatus + return h.clusterRegistrationTokenController.Update(obj) + } + return obj, nil + } + + obj = obj.DeepCopy() + obj.Status.Token, err = randomtoken.Generate() + if err != nil { + return nil, err + } + + return h.clusterRegistrationTokenController.Update(obj) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/status.go new file mode 100644 index 0000000..70ac118 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/clusterregistrationtoken/status.go @@ -0,0 +1,243 @@ +package clusterregistrationtoken + +import ( + "fmt" + "net/url" + + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/capr/installer" + util "github.com/rancher/rancher/pkg/cluster" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + rketypes "github.com/rancher/rke/types" +) + +const ( + commandFormat = "kubectl apply -f %s" + insecureCommandFormat = "curl --insecure -sfL %s | kubectl apply -f -" + nodeCommandFormat = "sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run %s %s --server %s --token %s%s" + rke2NodeCommandFormat = "%s curl -fL %s | sudo %s sh -s - --server %s --label 'cattle.io/os=linux' --token %s%s" + rke2WindowsNodeCommandFormat = `%s curl.exe -fL %s -o install.ps1; Set-ExecutionPolicy Bypass -Scope Process -Force; ./install.ps1 -Server %s -Label 'cattle.io/os=windows' -Token %s -Worker%s` + rke2InsecureNodeCommandFormat = "%s curl --insecure -fL %s | sudo %s sh -s - --server %s --label 'cattle.io/os=linux' --token %s%s" + rke2InsecureWindowsNodeCommandFormat = `%s curl.exe --insecure -fL %s -o install.ps1; Set-ExecutionPolicy Bypass -Scope Process -Force; ./install.ps1 -Server %s -Label 'cattle.io/os=windows' -Token %s -Worker%s` + loginCommandFormat = "echo \"%s\" | sudo docker login --username %s --password-stdin %s" + windowsNodeCommandFormat = `PowerShell -NoLogo -NonInteractive -Command "& {docker run -v c:\:c:\host %s%s bootstrap --server %s --token %s%s%s | iex}"` +) + +func (h *handler) isRKE2(clusterID string) bool { + cluster, err := h.clusters.Get(clusterID) + if err != nil { + return false + } + return cluster.Annotations["objectset.rio.cattle.io/owner-gvk"] == "provisioning.cattle.io/v1, Kind=Cluster" +} + +func (h *handler) assignStatus(crt *v32.ClusterRegistrationToken) (v32.ClusterRegistrationTokenStatus, error) { + checksum := systemtemplate.CAChecksum() + ca := "" + caWindows := "" + if checksum != "" { + ca = " --ca-checksum " + checksum + caWindows = " -CaChecksum " + checksum + } + + token := crt.Status.Token + clusterID := convert.ToString(crt.Spec.ClusterName) + if token == "" { + return crt.Status, nil + } + + crtStatus := crt.Status.DeepCopy() + crtStatus.Token = token + + url, err := getURL(token, clusterID) + if err != nil { + return crt.Status, err + } + + if url == "" { + return *crtStatus, nil + } + + crtStatus.InsecureCommand = fmt.Sprintf(insecureCommandFormat, url) + crtStatus.Command = fmt.Sprintf(commandFormat, url) + crtStatus.ManifestURL = url + + rootURL, err := getRootURL() + if err != nil { + return crt.Status, err + } + + cluster, err := h.clusters.Get(clusterID) + if err != nil { + return crt.Status, err + } + + agentImage := image.ResolveWithCluster(settings.AgentImage.Get(), cluster) + if h.isRKE2(clusterID) { + // for linux + crtStatus.NodeCommand = fmt.Sprintf(rke2NodeCommandFormat, + AgentEnvVars(cluster, Linux), + rootURL+installer.SystemAgentInstallPath, + AgentEnvVars(cluster, Linux), + rootURL, + token, + ca) + crtStatus.InsecureNodeCommand = fmt.Sprintf(rke2InsecureNodeCommandFormat, + AgentEnvVars(cluster, Linux), + rootURL+installer.SystemAgentInstallPath, + AgentEnvVars(cluster, Linux), + rootURL, + token, + ca) + } else { + // for linux + crtStatus.NodeCommand = fmt.Sprintf(nodeCommandFormat, + AgentEnvVars(cluster, Docker), + agentImage, + rootURL, + token, + ca) + } + // for windows + if h.isRKE2(clusterID) { + crtStatus.WindowsNodeCommand = fmt.Sprintf(rke2WindowsNodeCommandFormat, + AgentEnvVars(cluster, PowerShell), + rootURL+installer.WindowsRke2InstallPath, + rootURL, + token, + caWindows) + crtStatus.InsecureWindowsNodeCommand = fmt.Sprintf(rke2InsecureWindowsNodeCommandFormat, + AgentEnvVars(cluster, PowerShell), + rootURL+installer.WindowsRke2InstallPath, + rootURL, + token, + caWindows) + } else { + var agentImageDockerEnv string + if util.GetPrivateRegistryURL(cluster) != "" { + // patch the AGENT_IMAGE env + agentImageDockerEnv = fmt.Sprintf("-e AGENT_IMAGE=%s ", agentImage) + } + crtStatus.WindowsNodeCommand = fmt.Sprintf(windowsNodeCommandFormat, + agentImageDockerEnv, + agentImage, + rootURL, + token, + ca, + getWindowsPrefixPathArg(cluster.Spec.RancherKubernetesEngineConfig)) + } + return *crtStatus, nil +} + +func getWindowsPrefixPathArg(rkeConfig *rketypes.RancherKubernetesEngineConfig) string { + if rkeConfig == nil { + return "" + } + // default to prefix path + prefixPath := rkeConfig.PrefixPath + + // if windows prefix path set, override + if rkeConfig.WindowsPrefixPath != "" { + prefixPath = rkeConfig.WindowsPrefixPath + } + + if prefixPath != "" { + return fmt.Sprintf(" --prefix-path %s", prefixPath) + } + + return "" +} + +func NodeCommand(token string, cluster *v3.Cluster) (string, error) { + ca := systemtemplate.CAChecksum() + if ca != "" { + ca = " --ca-checksum " + ca + } + + rootURL, err := getRootURL() + if err != nil { + return "", err + } + return fmt.Sprintf(nodeCommandFormat, + AgentEnvVars(cluster, Docker), + image.ResolveWithCluster(settings.AgentImage.Get(), cluster), + rootURL, + token, + ca), nil +} + +func ShareMntCommand(nodeName, token string, cluster *v3.Cluster) ([]string, error) { + rootURL, err := getRootURL() + if err != nil { + return []string{""}, err + } + + cmd := []string{ + "--no-register", "--only-write-certs", + "--node-name", nodeName, + "--server", rootURL, + "--token", token, + } + + ca := systemtemplate.CAChecksum() + if ca != "" { + cmd = append(cmd, fmt.Sprintf("--ca-checksum %s", ca)) + } + + return cmd, nil +} + +func LoginCommand(reg rketypes.PrivateRegistry) string { + return fmt.Sprintf( + loginCommandFormat, + // escape password special characters so it is interpreted correctly when command is executed + escapeSpecialChars(reg.Password), + reg.User, + reg.URL, + ) +} + +// escapeSpecialChars escapes ", `, $, \ from a string s +func escapeSpecialChars(s string) string { + var escaped []rune + for _, r := range s { + switch r { + case '"', '`', '$', '\\': // escape + escaped = append(escaped, '\\', r) + default: // no escape + escaped = append(escaped, r) + } + } + return string(escaped) +} + +func getRootURL() (string, error) { + serverURL := settings.ServerURL.Get() + u, err := url.Parse(serverURL) + if err != nil { + return "", err + } + + u.Path = "" + return u.String(), nil +} + +func getURL(token, clusterID string) (string, error) { + serverURL := settings.ServerURL.Get() + if serverURL == "" { + return "", nil + } + path := "/v3/import/" + token + "_" + clusterID + ".yaml" + u, err := url.Parse(serverURL) + if err != nil { + return "", err + } + + u.Path = path + serverURL = u.String() + return serverURL, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/controller.go new file mode 100644 index 0000000..fc73835 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/controller.go @@ -0,0 +1,81 @@ +package dashboard + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/capr" + "github.com/rancher/rancher/pkg/controllers/dashboard/apiservice" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterindex" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterregistrationtoken" + "github.com/rancher/rancher/pkg/controllers/dashboard/cspadaptercharts" + "github.com/rancher/rancher/pkg/controllers/dashboard/fleetcharts" + "github.com/rancher/rancher/pkg/controllers/dashboard/helm" + "github.com/rancher/rancher/pkg/controllers/dashboard/hostedcluster" + "github.com/rancher/rancher/pkg/controllers/dashboard/kubernetesprovider" + "github.com/rancher/rancher/pkg/controllers/dashboard/mcmagent" + "github.com/rancher/rancher/pkg/controllers/dashboard/scaleavailable" + "github.com/rancher/rancher/pkg/controllers/dashboard/systemcharts" + "github.com/rancher/rancher/pkg/controllers/management/clusterconnected" + "github.com/rancher/rancher/pkg/controllers/provisioningv2" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/needacert" +) + +func Register(ctx context.Context, wrangler *wrangler.Context, embedded bool, registryOverride string) error { + helm.Register(ctx, wrangler) + kubernetesprovider.Register(ctx, + wrangler.Mgmt.Cluster(), + wrangler.K8s, + wrangler.MultiClusterManager) + apiservice.Register(ctx, wrangler, embedded) + needacert.Register(ctx, + wrangler.Core.Secret(), + wrangler.Core.Service(), + wrangler.Admission.MutatingWebhookConfiguration(), + wrangler.Admission.ValidatingWebhookConfiguration(), + wrangler.CRD.CustomResourceDefinition()) + scaleavailable.Register(ctx, wrangler) + if err := systemcharts.Register(ctx, wrangler, registryOverride); err != nil { + return err + } + + if err := cspadaptercharts.Register(ctx, wrangler); err != nil { + return err + } + + clusterconnected.Register(ctx, wrangler) + + if features.MCM.Enabled() { + hostedcluster.Register(ctx, wrangler) + } + + if features.Fleet.Enabled() { + if err := fleetcharts.Register(ctx, wrangler); err != nil { + return err + } + } + + if features.ProvisioningV2.Enabled() || features.MCM.Enabled() { + clusterregistrationtoken.Register(ctx, wrangler) + } + + if features.ProvisioningV2.Enabled() { + kubeconfigManager := kubeconfig.New(wrangler) + clusterindex.Register(ctx, wrangler) + provisioningv2.Register(ctx, wrangler, kubeconfigManager) + if features.RKE2.Enabled() { + capr.Register(ctx, wrangler, kubeconfigManager) + } + } + + if features.MCMAgent.Enabled() || features.MCM.Enabled() { + err := mcmagent.Register(ctx, wrangler) + if err != nil { + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/cspadaptercharts/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/cspadaptercharts/controller.go new file mode 100644 index 0000000..26078ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/cspadaptercharts/controller.go @@ -0,0 +1,51 @@ +// Package cspadaptercharts creates the controllers necessary for automatically upgrading the csp adapter chart +package cspadaptercharts + +import ( + "context" + "errors" + "fmt" + "sync" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalogv2/system" + "github.com/rancher/rancher/pkg/managedcharts/cspadapter" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" +) + +// Register registers a setting controller which watches the CSPAdapterMinVersion setting for changes so an installed CSP +// Adapter can be upgraded +func Register(ctx context.Context, wContext *wrangler.Context) error { + h := &handler{ + manager: wContext.SystemChartsManager, + adapterUtil: cspadapter.NewChartUtil(wContext.RESTClientGetter), + } + wContext.Mgmt.Setting().OnChange(ctx, "csp-adapter-upgrade", h.onSetting) + + return nil +} + +type handler struct { + sync.Mutex + manager *system.Manager + adapterUtil *cspadapter.ChartUtil +} + +func (h *handler) onSetting(key string, setting *v3.Setting) (*v3.Setting, error) { + if setting == nil || setting.Name != settings.CSPAdapterMinVersion.Name { + // we only need to check for changes to the CSPAdapterMinVersion setting, ignore any others + return setting, nil + } + adapterRelease, err := h.adapterUtil.GetRelease(cspadapter.MLOChartNamespace, cspadapter.MLOChartName) + if err != nil { + if errors.Is(err, cspadapter.ErrNotFound) { + // If the adapter isn't installed, don't attempt an upgrade + return setting, nil + } + // if we can't determine the status of the adapter, stop here and attempt to re-evaluate later + return setting, fmt.Errorf("unable to validate if the csp adater was installed: %w", err) + } + err = h.manager.Ensure(cspadapter.MLOChartNamespace, adapterRelease.Chart.Name(), settings.CSPAdapterMinVersion.Get(), "", nil, true, "") + return setting, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller.go new file mode 100644 index 0000000..3f946ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller.go @@ -0,0 +1,166 @@ +package fleetcharts + +import ( + "context" + "os" + "sync" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +const priorityClassKey = "priorityClassName" + +var ( + fleetCRDChart = chart.Definition{ + ReleaseNamespace: fleetconst.ReleaseNamespace, + ChartName: fleetconst.CRDChartName, + } + fleetChart = chart.Definition{ + ReleaseNamespace: fleetconst.ReleaseNamespace, + ChartName: fleetconst.ChartName, + } + fleetUninstallChart = chart.Definition{ + ReleaseNamespace: fleetconst.ReleaseLegacyNamespace, + ChartName: fleetconst.ChartName, + } + + watchedSettings = map[string]struct{}{ + settings.ServerURL.Name: {}, + settings.CACerts.Name: {}, + settings.SystemDefaultRegistry.Name: {}, + settings.FleetMinVersion.Name: {}, + settings.FleetVersion.Name: {}, + settings.AgentTLSMode.Name: {}, + } +) + +func Register(ctx context.Context, wContext *wrangler.Context) error { + h := &handler{ + manager: wContext.SystemChartsManager, + chartsConfig: chart.RancherConfigGetter{ConfigCache: wContext.Core.ConfigMap().Cache()}, + } + + wContext.Mgmt.Setting().OnChange(ctx, "fleet-install", h.onSetting) + // watch cluster repo `rancher-charts` and enqueue the setting to make sure the latest fleet is installed after catalog refresh + relatedresource.WatchClusterScoped(ctx, "bootstrap-fleet-charts", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if name == "rancher-charts" { + return []relatedresource.Key{{ + Name: settings.ServerURL.Name, + }}, nil + } + return nil, nil + }, wContext.Mgmt.Setting(), wContext.Catalog.ClusterRepo()) + return nil +} + +type handler struct { + sync.Mutex + manager chart.Manager + chartsConfig chart.RancherConfigGetter +} + +func (h *handler) onSetting(key string, setting *v3.Setting) (*v3.Setting, error) { + if setting == nil { + return nil, nil + } + + if _, isWatched := watchedSettings[setting.Name]; !isWatched { + return setting, nil + } + + h.Lock() + if err := h.manager.Uninstall(fleetUninstallChart.ReleaseNamespace, fleetUninstallChart.ChartName); err != nil { + h.Unlock() + return nil, err + } + h.Unlock() + + fleetVersion := settings.FleetVersion.Get() + // Keep Fleet min version precedence for backward compatibility. + if fleetMinVersion := settings.FleetMinVersion.Get(); fleetMinVersion != "" { + fleetVersion = fleetMinVersion + } + + err := h.manager.Ensure( + fleetCRDChart.ReleaseNamespace, + fleetCRDChart.ChartName, + fleetVersion, + "", + nil, + true, + "") + if err != nil { + return setting, err + } + + systemGlobalRegistry := map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + } + + fleetChartValues := map[string]interface{}{ + "agentTLSMode": settings.AgentTLSMode.Get(), + "apiServerURL": settings.ServerURL.Get(), + "apiServerCA": settings.CACerts.Get(), + "global": systemGlobalRegistry, + "bootstrap": map[string]interface{}{ + "enabled": false, + "agentNamespace": fleetconst.ReleaseLocalNamespace, + }, + "gitops": map[string]interface{}{ + "enabled": features.Gitops.Enabled(), + }, + } + + gitjobChartValues := make(map[string]interface{}) + + if envVal, ok := os.LookupEnv("HTTP_PROXY"); ok { + fleetChartValues["proxy"] = envVal + gitjobChartValues["proxy"] = envVal + } + if envVal, ok := os.LookupEnv("NO_PROXY"); ok { + fleetChartValues["noProxy"] = envVal + gitjobChartValues["noProxy"] = envVal + } + + // add priority class value + if priorityClassName, err := h.chartsConfig.GetGlobalValue(chart.PriorityClassKey); err != nil { + if !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher priorityClassName for '%s': %v", fleetChart.ChartName, err) + } + } else { + fleetChartValues[priorityClassKey] = priorityClassName + gitjobChartValues[priorityClassKey] = priorityClassName + } + + if len(gitjobChartValues) > 0 { + fleetChartValues["gitjob"] = gitjobChartValues + } + + extraValues, err := h.chartsConfig.GetChartValues(fleetconst.ChartName) + if err != nil && !chart.IsNotFoundError(err) { + // Missing extra config is okay, return the error otherwise + return nil, err + } + fleetChartValues = data.MergeMaps(fleetChartValues, extraValues) + + return setting, + h.manager.Ensure( + fleetChart.ReleaseNamespace, + fleetChart.ChartName, + fleetVersion, + "", + fleetChartValues, + true, + "") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller_test.go new file mode 100644 index 0000000..e726dc4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/fleetcharts/controller_test.go @@ -0,0 +1,310 @@ +package fleetcharts + +import ( + "fmt" + "os" + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart/fake" + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/rancher/pkg/settings" + ctrlfake "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + errUnimplemented = fmt.Errorf("unimplemented") + errNotFound = fmt.Errorf("not found") + priorityClassName = "rancher-critical" +) + +// Test_ChartInstallation test that all expected charts are installed or uninstalled with expected configuration +func Test_ChartInstallation(t *testing.T) { + if oldVal, ok := os.LookupEnv("HTTP_PROXY"); ok { + os.Unsetenv("HTTP_PROXY") + defer os.Setenv("HTTP_PROXY", oldVal) + } + if oldVal, ok := os.LookupEnv("NO_PROXY"); ok { + os.Unsetenv("NO_PROXY") + defer os.Setenv("NO_PROXY", oldVal) + } + stgs := []string{ + settings.ServerURL.Name, + settings.CACerts.Name, + settings.SystemDefaultRegistry.Name, + settings.FleetMinVersion.Name, + settings.FleetVersion.Name, + } + tests := []struct { + name string + newManager func(*gomock.Controller) chart.Manager + rancherConfig map[string]string + wantErr bool + }{ + { + name: "normal installation", + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("pass") + settings.FleetMinVersion.Set("") + + manager := fake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "agentTLSMode": settings.AgentTLSMode.Get(), + "apiServerURL": settings.ServerURL.Get(), + "apiServerCA": settings.CACerts.Get(), + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "bootstrap": map[string]interface{}{ + "enabled": false, + "agentNamespace": fleetconst.ReleaseLocalNamespace, + }, + "gitops": map[string]interface{}{ + "enabled": features.Gitops.Enabled(), + }, + "gitjob": map[string]interface{}{ + "priorityClassName": priorityClassName, + }, + "priorityClassName": priorityClassName, + } + + exactVersion := "0.7.0" + settings.FleetVersion.Set(exactVersion) + + var b bool + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.CRDChartName, + exactVersion, + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.ChartName, + exactVersion, + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + + manager.EXPECT().Uninstall(fleetconst.ReleaseLegacyNamespace, fleetconst.ChartName).Return(nil).Times(len(stgs)) + return manager + }, + }, + { + name: "normal installation with min version precedence", + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("pass") + manager := fake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "agentTLSMode": settings.AgentTLSMode.Get(), + "apiServerURL": settings.ServerURL.Get(), + "apiServerCA": settings.CACerts.Get(), + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "bootstrap": map[string]interface{}{ + "enabled": false, + "agentNamespace": fleetconst.ReleaseLocalNamespace, + }, + "gitops": map[string]interface{}{ + "enabled": features.Gitops.Enabled(), + }, + "gitjob": map[string]interface{}{ + "priorityClassName": priorityClassName, + }, + "priorityClassName": priorityClassName, + } + + minVersion := "0.7.0" + exactVersion := "0.7.1" + settings.FleetVersion.Set(exactVersion) + settings.FleetMinVersion.Set(minVersion) + + var b bool + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.CRDChartName, + minVersion, + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.ChartName, + minVersion, + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + + manager.EXPECT().Uninstall(fleetconst.ReleaseLegacyNamespace, fleetconst.ChartName).Return(nil).Times(len(stgs)) + return manager + }, + }, + { + name: "installation without priority class", + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("fail") + settings.FleetMinVersion.Set("") + + manager := fake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "agentTLSMode": settings.AgentTLSMode.Get(), + "apiServerURL": settings.ServerURL.Get(), + "apiServerCA": settings.CACerts.Get(), + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "bootstrap": map[string]interface{}{ + "enabled": false, + "agentNamespace": fleetconst.ReleaseLocalNamespace, + }, + "gitops": map[string]interface{}{ + "enabled": features.Gitops.Enabled(), + }, + } + var b bool + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.CRDChartName, + settings.FleetVersion.Get(), + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.ChartName, + settings.FleetVersion.Get(), + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + + manager.EXPECT().Uninstall(fleetconst.ReleaseLegacyNamespace, fleetconst.ChartName).Return(nil).Times(len(stgs)) + return manager + }, + }, + { + name: "installation with additional values", + rancherConfig: map[string]string{ + "fleet": ` +leaderElection: + leaseDuration: 2s +bootstrap: + enabled: true +gitjob: + debug: true +`}, + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("pass") + settings.FleetMinVersion.Set("") + + manager := fake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "agentTLSMode": settings.AgentTLSMode.Get(), + "apiServerURL": settings.ServerURL.Get(), + "apiServerCA": settings.CACerts.Get(), + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "bootstrap": map[string]interface{}{ + "enabled": true, + "agentNamespace": fleetconst.ReleaseLocalNamespace, + }, + "gitops": map[string]interface{}{ + "enabled": features.Gitops.Enabled(), + }, + "gitjob": map[string]interface{}{ + "priorityClassName": priorityClassName, + "debug": true, + }, + "priorityClassName": priorityClassName, + "leaderElection": map[string]interface{}{ + "leaseDuration": "2s", + }, + } + + exactVersion := "0.7.0" + settings.FleetVersion.Set(exactVersion) + + var b bool + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.CRDChartName, + exactVersion, + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + manager.EXPECT().Ensure( + fleetconst.ReleaseNamespace, + fleetconst.ChartName, + exactVersion, + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil).Times(len(stgs)) + + manager.EXPECT().Uninstall(fleetconst.ReleaseLegacyNamespace, fleetconst.ChartName).Return(nil).Times(len(stgs)) + return manager + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + configCache := ctrlfake.NewMockCacheInterface[*v1.ConfigMap](ctrl) + configCache.EXPECT(). + Get(gomock.Any(), gomock.Any()). + DoAndReturn(func(ns, name string) (*v1.ConfigMap, error) { + if name == "pass" { + return &v1.ConfigMap{Data: map[string]string{"priorityClassName": priorityClassName}}, nil + } + if name == "rancher-config" && tt.rancherConfig != nil { + return &v1.ConfigMap{Data: tt.rancherConfig}, nil + } + return nil, apierrors.NewNotFound(v1.Resource("Configmap"), name) + }).AnyTimes() + h := &handler{ + chartsConfig: chart.RancherConfigGetter{ConfigCache: configCache}, + } + h.manager = tt.newManager(ctrl) + for _, setting := range stgs { + _, err := h.onSetting("", &v3.Setting{ObjectMeta: metav1.ObjectMeta{Name: setting}}) + if tt.wantErr { + assert.Error(t, err, "handler.onRepo() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.NoError(t, err, "unexpected error") + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/apps.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/apps.go new file mode 100644 index 0000000..542c30a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/apps.go @@ -0,0 +1,226 @@ +package helm + +import ( + "context" + + "github.com/moby/locker" + "github.com/rancher/lasso/pkg/client" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/helm" + catalogv1 "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type appHandler struct { + apply apply.Apply + sharedClientFactory client.SharedClientFactory + configMapCache corecontrollers.ConfigMapCache + secretCache corecontrollers.SecretCache + locker locker.Locker +} + +func RegisterApps(ctx context.Context, + apply apply.Apply, + shareClientFactory client.SharedClientFactory, + configMap corecontrollers.ConfigMapController, + secrets corecontrollers.SecretController, + apps catalogv1.AppController, +) { + r := appHandler{ + apply: apply. + WithCacheTypes(apps). + WithSetID("helm-app"). + WithSetOwnerReference(true, false), + sharedClientFactory: shareClientFactory, + secretCache: secrets.Cache(), + configMapCache: configMap.Cache(), + } + configMap.OnChange(ctx, "helm-app-configmap", r.OnConfigMapChange) + secrets.OnChange(ctx, "helm-app-secret", r.OnSecretChange) + catalogv1.RegisterAppStatusHandler(ctx, apps, "", "helm-app-status", r.appStatus) + relatedresource.Watch(ctx, "helm-app", + relatedresource.OwnerResolver(true, "v1", "ConfigMap"), + configMap, + apps) + relatedresource.Watch(ctx, "helm-app", + relatedresource.OwnerResolver(true, "v1", "Secrets"), + secrets, + apps) +} + +func (a *appHandler) appStatus(app *v1.App, status v1.ReleaseStatus) (v1.ReleaseStatus, error) { + summary := v1.Summary{} + if app.Spec.Info != nil && app.Spec.Info.Status != v1.StatusUnknown { + summary.State = string(app.Spec.Info.Status) + switch app.Spec.Info.Status { + case v1.StatusDeployed: + case v1.StatusUninstalled: + case v1.StatusSuperseded: + case v1.StatusFailed: + summary.Error = true + case v1.StatusUninstalling: + summary.Transitioning = true + case v1.StatusPendingInstall: + summary.Transitioning = true + case v1.StatusPendingUpgrade: + summary.Transitioning = true + case v1.StatusPendingRollback: + summary.Transitioning = true + } + } + + status.Summary = summary + status.ObservedGeneration = app.Generation + + return status, nil +} + +func (a *appHandler) isLatestSecret(ns string, spec *v1.ReleaseSpec) (bool, error) { + others, err := a.secretCache.List(ns, labels.SelectorFromSet(labels.Set{ + "owner": "helm", + })) + if err != nil { + return false, err + } + + // TODO: If we find nothing here we didn't even find the original. That's bad and can + // indicate that this is a helm v2 release using secrets which we currently + // aren't expecting. + // https://github.com/rancher/rancher/issues/31297 + if len(others) == 0 { + return false, nil + } + + othersRuntime := make([]runtime.Object, 0, len(others)) + for _, other := range others { + othersRuntime = append(othersRuntime, other) + } + + return helm.IsLatest(spec, othersRuntime), nil +} + +func (a *appHandler) isLatestConfigMap(ns string, spec *v1.ReleaseSpec) (bool, error) { + others, err := a.configMapCache.List(ns, labels.SelectorFromSet(labels.Set{ + "OWNER": "TILLER", + })) + if err != nil { + return false, err + } + + // TODO: If we find nothing here we didn't even find the original. That's bad and can + // indicate that this is a helm v2 release using configMaps which we currently + // aren't expecting. + // https://github.com/rancher/rancher/issues/31297 + if len(others) == 0 { + return false, nil + } + + othersRuntime := make([]runtime.Object, 0, len(others)) + for _, other := range others { + othersRuntime = append(othersRuntime, other) + } + + return helm.IsLatest(spec, othersRuntime), nil +} + +func (a *appHandler) OnConfigMapChange(key string, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) { + spec, err := helm.ToRelease(configMap, a.isNamespaced) + if err == helm.ErrNotHelmRelease { + return configMap, nil + } else if err != nil { + logrus.Errorf("Failed to process configmap %s for helm data: %v", key, err) + // ignore error + return configMap, nil + } + + a.locker.Lock(spec.Name) + defer a.locker.Unlock(spec.Name) + + if latest, err := a.isLatestConfigMap(configMap.Namespace, spec); err != nil { + return nil, err + } else if !latest { + // Don't delete if we create an App before as it's probably owned by something else now + return nil, generic.ErrSkip + } + + if spec.HelmMajorVersion == 2 { + // no longer support helm 2 + return configMap, a.apply.WithOwner(configMap).ApplyObjects() + } + + // Copy the cluster-repo-name label from the configmap to the App + // so that the App can be associated with a cluster repo. + var labels map[string]string + value, ok := configMap.Labels[v1.ClusterRepoNameLabel] + if ok { + labels = map[string]string{ + v1.ClusterRepoNameLabel: value, + } + } + + return configMap, a.apply.WithOwner(configMap).ApplyObjects(&v1.App{ + ObjectMeta: metav1.ObjectMeta{ + Name: spec.Name, + Namespace: configMap.Namespace, + Labels: labels, + }, + Spec: *spec, + }) +} + +func (a *appHandler) OnSecretChange(key string, secret *corev1.Secret) (*corev1.Secret, error) { + spec, err := helm.ToRelease(secret, a.isNamespaced) + if err == helm.ErrNotHelmRelease { + return secret, nil + } else if err != nil { + logrus.Errorf("Failed to process secret %s for helm data: %v", key, err) + // ignore error + return secret, nil + } + + a.locker.Lock(spec.Name) + defer a.locker.Unlock(spec.Name) + + if latest, err := a.isLatestSecret(secret.Namespace, spec); err != nil { + return nil, err + } else if !latest { + // Don't delete if we create an App before as it's probably owned by something else now + return nil, generic.ErrSkip + } + + // Copy the cluster-repo-name label from the secret to the App + // so that the App can be associated with a cluster repo. + var labels map[string]string + value, ok := secret.Labels[v1.ClusterRepoNameLabel] + if ok { + labels = map[string]string{ + v1.ClusterRepoNameLabel: value, + } + } + + return secret, a.apply.WithOwner(secret).ApplyObjects(&v1.App{ + ObjectMeta: metav1.ObjectMeta{ + Name: spec.Name, + Namespace: secret.Namespace, + Labels: labels, + }, + Spec: *spec, + }) +} + +func (a *appHandler) isNamespaced(gvk schema.GroupVersionKind) bool { + _, nsed, err := a.sharedClientFactory.ResourceForGVK(gvk) + if err != nil { + return false + } + return nsed +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/operations.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/operations.go new file mode 100644 index 0000000..4b54d1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/operations.go @@ -0,0 +1,139 @@ +package helm + +import ( + "context" + "fmt" + + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kstatus" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" +) + +const ( + podIndex = "byPod" +) + +type operationHandler struct { + ctx context.Context + pods corecontrollers.PodCache + k8s kubernetes.Interface + operationsCache catalogcontrollers.OperationCache +} + +func RegisterOperations(ctx context.Context, + k8s kubernetes.Interface, + pods corecontrollers.PodController, + operations catalogcontrollers.OperationController) { + + o := operationHandler{ + ctx: ctx, + k8s: k8s, + pods: pods.Cache(), + operationsCache: operations.Cache(), + } + + operations.Cache().AddIndexer(podIndex, indexOperationsByPod) + relatedresource.Watch(ctx, "helm-operation", o.findOperationsFromPod, operations, pods) + catalogcontrollers.RegisterOperationStatusHandler(ctx, operations, "", "helm-operation", o.onOperationChange) +} + +func indexOperationsByPod(obj *catalog.Operation) ([]string, error) { + return []string{ + obj.Status.PodNamespace + "/" + obj.Status.PodName, + }, nil +} + +func (o *operationHandler) findOperationsFromPod(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + ops, err := o.operationsCache.GetByIndex(podIndex, namespace+"/"+name) + if err != nil { + return nil, err + } + var result []relatedresource.Key + for _, op := range ops { + result = append(result, relatedresource.NewKey(op.Namespace, op.Name)) + } + return result, nil +} + +func (o *operationHandler) onOperationChange(operation *catalog.Operation, status catalog.OperationStatus) (catalog.OperationStatus, error) { + if status.PodName == "" || status.PodNamespace == "" { + return status, nil + } + + pod, err := o.pods.Get(status.PodNamespace, status.PodName) + if apierrors.IsNotFound(err) { + kstatus.SetActive(&status) + return status, nil + } + + for _, container := range pod.Status.ContainerStatuses { + if container.Name != "helm" { + continue + } + status.ObservedGeneration = operation.Generation + if container.State.Running != nil { + status.PodCreated = true + kstatus.SetTransitioning(&status, "running operation") + } else if container.State.Terminated != nil { + status.PodCreated = true + if container.State.Terminated.ExitCode == 0 { + kstatus.SetActive(&status) + } else { + kstatus.SetError(&status, + fmt.Sprintf("%s exit code: %d", + container.State.Terminated.Message, + container.State.Terminated.ExitCode)) + } + if err := o.cleanup(pod); err != nil { + return status, err + } + } else if container.State.Waiting != nil { + kstatus.SetTransitioning(&status, "waiting to run operation") + } else { + kstatus.SetTransitioning(&status, "unknown state operation") + } + } + + return status, nil +} + +func (o *operationHandler) cleanup(pod *corev1.Pod) error { + running := false + success := false + for _, container := range pod.Status.ContainerStatuses { + if container.Name == "proxy" && container.State.Terminated == nil { + running = true + } else if container.Name == "helm" && container.State.Terminated != nil && container.State.Terminated.ExitCode == 0 { + success = true + } + } + + if !running || !success { + return nil + } + + result := o.k8s.CoreV1().RESTClient(). + Get(). + Namespace(pod.Namespace). + Resource("pods"). + Name(pod.Name). + SubResource("exec"). + SetHeader("Upgrade", "websocket"). + SetHeader("Sec-Websocket-Key", "websocket"). + SetHeader("Sec-Websocket-Version", "13"). + SetHeader("Connection", "Upgrade"). + VersionedParams(&corev1.PodExecOptions{ + Stdout: true, + Stderr: true, + Container: "proxy", + Command: []string{"pkill", "-x", "kubectl"}, + }, scheme.ParameterCodec).Do(o.ctx) + return result.Error() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/register.go new file mode 100644 index 0000000..a5ba643 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/register.go @@ -0,0 +1,31 @@ +package helm + +import ( + "context" + + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, wrangler *wrangler.Context) { + RegisterRepos(ctx, + wrangler.Apply, + wrangler.Core.Secret().Cache(), + wrangler.Catalog.ClusterRepo(), + wrangler.Core.ConfigMap(), + wrangler.Core.ConfigMap().Cache()) + RegisterOCIRepo(ctx, + wrangler.Apply, + wrangler.Catalog.ClusterRepo(), + wrangler.Core.ConfigMap(), + wrangler.Core.Secret().Cache()) + RegisterApps(ctx, + wrangler.Apply, + wrangler.ControllerFactory.SharedCacheFactory().SharedClientFactory(), + wrangler.Core.ConfigMap(), + wrangler.Core.Secret(), + wrangler.Catalog.App()) + RegisterOperations(ctx, + wrangler.K8s, + wrangler.Core.Pod(), + wrangler.Catalog.Operation()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo.go new file mode 100644 index 0000000..4d5ad0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo.go @@ -0,0 +1,322 @@ +package helm + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "time" + + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2" + "github.com/rancher/rancher/pkg/catalogv2/git" + helmhttp "github.com/rancher/rancher/pkg/catalogv2/http" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + namespaces "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + name2 "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +const ( + maxSize = 100_000 +) + +var ( + interval = 6 * time.Hour +) + +type repoHandler struct { + secrets corev1controllers.SecretCache + clusterRepos catalogcontrollers.ClusterRepoController + configMaps corev1controllers.ConfigMapClient + configMapCache corev1controllers.ConfigMapCache + apply apply.Apply +} + +func RegisterRepos(ctx context.Context, + apply apply.Apply, + secrets corev1controllers.SecretCache, + clusterRepos catalogcontrollers.ClusterRepoController, + configMap corev1controllers.ConfigMapController, + configMapCache corev1controllers.ConfigMapCache) { + h := &repoHandler{ + secrets: secrets, + clusterRepos: clusterRepos, + configMaps: configMap, + configMapCache: configMapCache, + apply: apply.WithCacheTypes(configMap).WithStrictCaching().WithSetOwnerReference(false, false), + } + + catalogcontrollers.RegisterClusterRepoStatusHandler(ctx, clusterRepos, + condition.Cond(catalog.RepoDownloaded), "helm-clusterrepo-download", h.ClusterRepoDownloadStatusHandler) + +} + +func RegisterReposForFollowers(ctx context.Context, + secrets corev1controllers.SecretCache, + clusterRepos catalogcontrollers.ClusterRepoController) { + h := &repoHandler{ + secrets: secrets, + clusterRepos: clusterRepos, + } + + catalogcontrollers.RegisterClusterRepoStatusHandler(ctx, clusterRepos, + condition.Cond(catalog.FollowerRepoDownloaded), "helm-clusterrepo-ensure", h.ClusterRepoDownloadEnsureStatusHandler) + +} + +func (r *repoHandler) ClusterRepoDownloadEnsureStatusHandler(repo *catalog.ClusterRepo, status catalog.RepoStatus) (catalog.RepoStatus, error) { + if registry.IsOCI(repo.Spec.URL) { + return status, nil + } + r.clusterRepos.EnqueueAfter(repo.Name, interval) + return r.ensure(&repo.Spec, status, &repo.ObjectMeta) +} + +func (r *repoHandler) ClusterRepoDownloadStatusHandler(repo *catalog.ClusterRepo, status catalog.RepoStatus) (catalog.RepoStatus, error) { + // Ignore OCI Based Helm Repositories + if registry.IsOCI(repo.Spec.URL) { + return status, nil + } + + err := ensureIndexConfigMap(repo, &status, r.configMaps) + if err != nil { + return status, err + } + if !shouldRefresh(&repo.Spec, &status) { + r.clusterRepos.EnqueueAfter(repo.Name, interval) + return status, nil + } + + return r.download(&repo.Spec, status, &repo.ObjectMeta, metav1.OwnerReference{ + APIVersion: catalog.SchemeGroupVersion.Group + "/" + catalog.SchemeGroupVersion.Version, + Kind: "ClusterRepo", + Name: repo.Name, + UID: repo.UID, + }) +} + +func toOwnerObject(namespace string, owner metav1.OwnerReference) runtime.Object { + return &metav1.PartialObjectMetadata{ + TypeMeta: metav1.TypeMeta{ + Kind: owner.Kind, + APIVersion: owner.APIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: owner.Name, + Namespace: namespace, + UID: owner.UID, + }, + } +} + +func createOrUpdateMap(namespace string, index *repo.IndexFile, owner metav1.OwnerReference, apply apply.Apply) (*corev1.ConfigMap, error) { + // do this before we normalize the namespace + ownerObject := toOwnerObject(namespace, owner) + + buf := &bytes.Buffer{} + gz := gzip.NewWriter(buf) + if err := json.NewEncoder(gz).Encode(index); err != nil { + logrus.Errorf("error while encoding index: %v", err) + return nil, err + } + if err := gz.Close(); err != nil { + logrus.Errorf("error while closing reader: %v", err) + return nil, err + } + + namespace = GetConfigMapNamespace(namespace) + + var ( + objs []runtime.Object + bytes = buf.Bytes() + left []byte + i = 0 + size = len(bytes) + ) + + for { + if len(bytes) > maxSize { + left = bytes[maxSize:] + bytes = bytes[:maxSize] + } + + next := "" + if len(left) > 0 { + next = GenerateConfigMapName(owner.Name, i+1, owner.UID) + } + + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: GenerateConfigMapName(owner.Name, i, owner.UID), + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{owner}, + Annotations: map[string]string{ + "catalog.cattle.io/next": next, + // Size ensure the resource version should update even if this is the head of a multipart chunk + "catalog.cattle.io/size": fmt.Sprint(size), + }, + }, + BinaryData: map[string][]byte{ + "content": bytes, + }, + } + + objs = append(objs, cm) + if len(left) == 0 { + break + } + + i++ + bytes = left + left = nil + } + err := apply.WithOwner(ownerObject).ApplyObjects(objs...) + if err != nil { + logrus.Errorf("error while applying configmap %s: %v", GenerateConfigMapName(owner.Name, i, owner.UID), err) + } + return objs[0].(*corev1.ConfigMap), err +} + +func (r *repoHandler) ensure(repoSpec *catalog.RepoSpec, status catalog.RepoStatus, metadata *metav1.ObjectMeta) (catalog.RepoStatus, error) { + if status.Commit == "" { + return status, nil + } + + status.ObservedGeneration = metadata.Generation + secret, err := catalogv2.GetSecret(r.secrets, repoSpec, metadata.Namespace) + if err != nil { + return status, err + } + + return status, git.Ensure(secret, metadata.Namespace, metadata.Name, status.URL, status.Commit, repoSpec.InsecureSkipTLSverify, repoSpec.CABundle) +} + +func (r *repoHandler) download(repoSpec *catalog.RepoSpec, status catalog.RepoStatus, metadata *metav1.ObjectMeta, owner metav1.OwnerReference) (catalog.RepoStatus, error) { + var ( + index *repo.IndexFile + commit string + err error + ) + + status.ObservedGeneration = metadata.Generation + + secret, err := catalogv2.GetSecret(r.secrets, repoSpec, metadata.Namespace) + if err != nil { + return status, err + } + + downloadTime := metav1.Now() + if repoSpec.GitRepo != "" && status.IndexConfigMapName == "" { + commit, err = git.Head(secret, metadata.Namespace, metadata.Name, repoSpec.GitRepo, repoSpec.GitBranch, repoSpec.InsecureSkipTLSverify, repoSpec.CABundle) + if err != nil { + return status, err + } + status.URL = repoSpec.GitRepo + status.Branch = repoSpec.GitBranch + index, err = git.BuildOrGetIndex(metadata.Namespace, metadata.Name, repoSpec.GitRepo) + } else if repoSpec.GitRepo != "" { + commit, err = git.Update(secret, metadata.Namespace, metadata.Name, repoSpec.GitRepo, repoSpec.GitBranch, repoSpec.InsecureSkipTLSverify, repoSpec.CABundle) + if err != nil { + return status, err + } + status.URL = repoSpec.GitRepo + status.Branch = repoSpec.GitBranch + if status.Commit == commit { + status.DownloadTime = downloadTime + return status, nil + } + index, err = git.BuildOrGetIndex(metadata.Namespace, metadata.Name, repoSpec.GitRepo) + } else if repoSpec.URL != "" { + index, err = helmhttp.DownloadIndex(secret, repoSpec.URL, repoSpec.CABundle, repoSpec.InsecureSkipTLSverify, repoSpec.DisableSameOriginCheck) + + status.URL = repoSpec.URL + status.Branch = "" + } else { + return status, nil + } + if err != nil || index == nil { + return status, err + } + + index.SortEntries() + + cm, err := createOrUpdateMap(metadata.Namespace, index, owner, r.apply) + if err != nil { + return status, err + } + + status.IndexConfigMapName = cm.Name + status.IndexConfigMapNamespace = cm.Namespace + status.IndexConfigMapResourceVersion = cm.ResourceVersion + status.DownloadTime = downloadTime + status.Commit = commit + return status, nil +} + +func ensureIndexConfigMap(repo *catalog.ClusterRepo, status *catalog.RepoStatus, configMap corev1controllers.ConfigMapClient) error { + // Charts from the clusterRepo will be unavailable if the IndexConfigMap recorded in the status does not exist. + // By resetting the value of IndexConfigMapName, IndexConfigMapNamespace, IndexConfigMapResourceVersion to "", + // the method shouldRefresh will return true and trigger the rebuild of the IndexConfigMap and accordingly update the status. + if repo.Spec.GitRepo != "" && status.IndexConfigMapName != "" { + _, err := configMap.Get(status.IndexConfigMapNamespace, status.IndexConfigMapName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + status.IndexConfigMapName = "" + status.IndexConfigMapNamespace = "" + status.IndexConfigMapResourceVersion = "" + return nil + } + logrus.Errorf("Error while fetching index config map %s : %v", status.IndexConfigMapName, err) + reason := apierrors.ReasonForError(err) + if reason == metav1.StatusReasonUnknown { + return err + } + return fmt.Errorf("failed to fetch index config map for cluster repo: %s", reason) + } + } + return nil +} + +func shouldRefresh(spec *catalog.RepoSpec, status *catalog.RepoStatus) bool { + if spec.GitRepo != "" && status.Branch != spec.GitBranch { + return true + } + if spec.URL != "" && spec.URL != status.URL { + return true + } + if spec.GitRepo != "" && spec.GitRepo != status.URL { + return true + } + if status.IndexConfigMapName == "" { + return true + } + if spec.ForceUpdate != nil && spec.ForceUpdate.After(status.DownloadTime.Time) && spec.ForceUpdate.Time.Before(time.Now()) { + return true + } + refreshTime := time.Now().Add(-interval) + return refreshTime.After(status.DownloadTime.Time) +} + +func GenerateConfigMapName(ownerName string, index int, UID types.UID) string { + return name2.SafeConcatName(ownerName, fmt.Sprint(index), string(UID)) +} + +func GetConfigMapNamespace(namespace string) string { + if namespace == "" { + return namespaces.System + } + + return namespace +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci.go new file mode 100644 index 0000000..38c77cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci.go @@ -0,0 +1,464 @@ +package helm + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "errors" + "fmt" + "hash/maphash" + "io" + "math" + "math/rand" + "net/http" + "time" + + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2" + "github.com/rancher/rancher/pkg/catalogv2/oci" + "github.com/rancher/rancher/pkg/catalogv2/oci/capturewindowclient" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "oras.land/oras-go/v2/registry/remote/errcode" +) + +var ( + timeNow = time.Now + ociInterval = 24 * time.Hour +) + +type OCIRepohandler struct { + clusterRepoController catalogcontrollers.ClusterRepoController + configMapController corev1controllers.ConfigMapController + secretCacheController corev1controllers.SecretCache + apply apply.Apply +} + +type retryPolicy struct { + // MinWait is the minimum duration to wait before retrying. + MinWait time.Duration + + // MaxWait is the maximum duration to wait before retrying. + MaxWait time.Duration + + // MaxRetry is the maximum number of retries. + MaxRetry int +} + +func RegisterOCIRepo(ctx context.Context, + apply apply.Apply, + clusterRepoController catalogcontrollers.ClusterRepoController, + configMapController corev1controllers.ConfigMapController, + secretsController corev1controllers.SecretCache) { + + ociRepoHandler := &OCIRepohandler{ + clusterRepoController: clusterRepoController, + configMapController: configMapController, + secretCacheController: secretsController, + apply: apply.WithCacheTypes(configMapController).WithStrictCaching().WithSetOwnerReference(false, false), + } + + clusterRepoController.OnChange(ctx, "oci-clusterrepo-helm", ociRepoHandler.onClusterRepoChange) +} + +// This handler is triggered in the following cases +// * When the spec of the ClusterRepo is changed. +// * When there is no error from the handler, at a regular interval of 24 hours. +// * When there is an error from the handler, at the wrangler's default error interval. +// * When the response from OCI registry is anything 4xx HTTP status code, at an interval of 24 hours or the duration time to wait which is calculated by the backoff function. +func (o *OCIRepohandler) onClusterRepoChange(key string, clusterRepo *catalog.ClusterRepo) (*catalog.ClusterRepo, error) { + if clusterRepo == nil { + return nil, nil + } + // Ignore non OCI ClusterRepos + if !registry.IsOCI(clusterRepo.Spec.URL) { + return clusterRepo, nil + } + newStatus := clusterRepo.Status.DeepCopy() + retryPolicy, err := getRetryPolicy(clusterRepo) + if err != nil { + err = fmt.Errorf("failed to get retry policy: %w", err) + return o.setErrorCondition(clusterRepo, err, newStatus) + } + if o.shouldSkip(clusterRepo, retryPolicy, key) { + return clusterRepo, nil + } + newStatus.ShouldNotSkip = false + + logrus.Debugf("OCIRepoHandler triggered for clusterrepo %s", clusterRepo.Name) + var index *repo.IndexFile + + err = ensureIndexConfigMap(clusterRepo, newStatus, o.configMapController) + if err != nil { + err = fmt.Errorf("failed to ensure index configmap: %w", err) + return o.setErrorCondition(clusterRepo, err, newStatus) + } + + secret, err := catalogv2.GetSecret(o.secretCacheController, &clusterRepo.Spec, clusterRepo.Namespace) + if err != nil { + logrus.Errorf("Error while fetching secret for cluster repo %s: %v", clusterRepo.Name, err) + reason := apierrors.ReasonForError(err) + if reason != metav1.StatusReasonUnknown { + err = fmt.Errorf("failed to fetch secret: %s", reason) + } + return o.setErrorCondition(clusterRepo, err, newStatus) + } + + owner := metav1.OwnerReference{ + APIVersion: catalog.SchemeGroupVersion.Group + "/" + catalog.SchemeGroupVersion.Version, + Kind: "ClusterRepo", + Name: clusterRepo.Name, + UID: clusterRepo.UID, + } + + downloadTime := metav1.Now() + index, err = getIndexfile(clusterRepo.Status, clusterRepo.Spec, o.configMapController, owner, clusterRepo.Namespace) + if err != nil { + return o.setErrorCondition(clusterRepo, fmt.Errorf("error while getting indexfile: %w", err), newStatus) + } + originalIndexBytes, err := json.Marshal(index) + if err != nil { + logrus.Errorf("Error while marshalling indexfile for cluster repo %s: %v", clusterRepo.Name, err) + return o.setErrorCondition(clusterRepo, fmt.Errorf("error while reading indexfile"), newStatus) + } + // Create a new oci client + ociClient, err := oci.NewClient(clusterRepo.Spec.URL, clusterRepo.Spec, secret) + if err != nil { + return nil, fmt.Errorf("failed to create an OCI client for url %s: %w", clusterRepo.Spec.URL, err) + } + + index, err = oci.GenerateIndex(ociClient, clusterRepo.Spec.URL, secret, clusterRepo.Spec, *newStatus, index) + // If there is 401 or 403 error code, then we don't reconcile further and wait for 24 hours interval + var errResp *errcode.ErrorResponse + // If there is 429 error code and max retry is reached, then we don't reconcile further and wait for 24 hours interval, + // but we also create the configmap for future usecases. + if errors.As(err, &errResp) && errResp.StatusCode == http.StatusTooManyRequests { + if index != nil && len(index.Entries) > 0 { + newStatus.URL = clusterRepo.Spec.URL + + index.SortEntries() + _, err := createOrUpdateMap(clusterRepo.Namespace, index, owner, o.apply) + if err != nil { + logrus.Debugf("failed to create/udpate the configmap incase of 4xx statuscode for %s", clusterRepo.Name) + } + } + + // If OCIRegistryBackOffDuration is already defined by the registry, + // we ignore the exponentialBackOffValues set by the user. + var backoff time.Duration + ociRegistryBackOffDuration := ociClient.HTTPClient.Transport.(*capturewindowclient.Transport).BackOffDuration + if ociRegistryBackOffDuration > 0.0 { + backoff = time.Duration(ociRegistryBackOffDuration) * time.Second + ociClient.HTTPClient.Transport.(*capturewindowclient.Transport).BackOffDuration = 0.0 + newStatus.ShouldNotSkip = true + } else { + backoff = calculateBackoff(clusterRepo, retryPolicy) + + newStatus.NumberOfRetries++ + if newStatus.NumberOfRetries > retryPolicy.MaxRetry { + newStatus.NumberOfRetries = 0 + newStatus.NextRetryAt = metav1.Time{} + return o.setConditionWithInterval(clusterRepo, errResp, newStatus, nil) + } + } + + newStatus.NextRetryAt = metav1.Time{Time: timeNow().UTC().Add(backoff)} + return o.setConditionWithInterval(clusterRepo, errResp, newStatus, &backoff) + + } + // If there is an error, we wait for the next interval to happen. + if err != nil { + return o.setConditionWithInterval(clusterRepo, err, newStatus, nil) + } + if index == nil || len(index.Entries) <= 0 { + err = errors.New("there are no helm charts in the repository specified") + return o.setErrorCondition(clusterRepo, err, newStatus) + } + + newIndexBytes, err := json.Marshal(index) + if err != nil { + logrus.Errorf("Error while marshalling indexfile for cluster repo %s: %v", clusterRepo.Name, err) + return o.setErrorCondition(clusterRepo, fmt.Errorf("error while reading indexfile"), newStatus) + } + // Only update, if the index got updated + if !bytes.Equal(originalIndexBytes, newIndexBytes) { + index.SortEntries() + cm, err := createOrUpdateMap(clusterRepo.Namespace, index, owner, o.apply) + if err != nil { + return o.setErrorCondition(clusterRepo, fmt.Errorf("error while creating or updating confimap"), newStatus) + } + + newStatus.URL = clusterRepo.Spec.URL + newStatus.IndexConfigMapName = cm.Name + newStatus.IndexConfigMapNamespace = cm.Namespace + newStatus.IndexConfigMapResourceVersion = cm.ResourceVersion + newStatus.DownloadTime = downloadTime + } + + return o.setErrorCondition(clusterRepo, nil, newStatus) +} + +// setErrorCondition is only called when error happens in the handler, and +// we need to depend on wrangler to requeue the handler +func (o *OCIRepohandler) setErrorCondition(clusterRepo *catalog.ClusterRepo, err error, newStatus *catalog.RepoStatus) (*catalog.ClusterRepo, error) { + var statusErr error + newStatus.NumberOfRetries = 0 + newStatus.NextRetryAt = metav1.Time{} + if err != nil { + newStatus.ShouldNotSkip = true + } + ociDownloaded := condition.Cond(catalog.OCIDownloaded) + if apierrors.IsConflict(err) { + ociDownloaded.SetError(newStatus, "", nil) + } else { + ociDownloaded.SetError(newStatus, "", err) + } + newStatus.ObservedGeneration = clusterRepo.Generation + + if !equality.Semantic.DeepEqual(newStatus, &clusterRepo.Status) { + ociDownloaded.LastUpdated(newStatus, timeNow().UTC().Format(time.RFC3339)) + + clusterRepo.Status = *newStatus + clusterRepo, statusErr = o.clusterRepoController.UpdateStatus(clusterRepo) + if statusErr != nil { + err = statusErr + } + if err == nil { + o.clusterRepoController.EnqueueAfter(clusterRepo.Name, ociInterval) + } + return clusterRepo, err + } + + if err == nil { + o.clusterRepoController.EnqueueAfter(clusterRepo.Name, ociInterval) + } + return clusterRepo, err +} + +// setConditionWithInterval is called to reenqueue the object +// after the interval of 24 hours. +func (o *OCIRepohandler) setConditionWithInterval(clusterRepo *catalog.ClusterRepo, err error, newStatus *catalog.RepoStatus, backoff *time.Duration) (*catalog.ClusterRepo, error) { + var errResp *errcode.ErrorResponse + var newErr error + if errors.As(err, &errResp) { + errorMsg := fmt.Sprintf("error %d: %s", errResp.StatusCode, http.StatusText(errResp.StatusCode)) + if backoff != nil { + errorMsg = fmt.Sprintf("%s. %s", errorMsg, fmt.Sprintf("Will retry after %s", backoff.Round(time.Second))) + } else { + errorMsg = fmt.Sprintf("%s. %s", errorMsg, fmt.Sprintf("Will retry after %s", ociInterval.Round(time.Second))) + } + newErr = fmt.Errorf(errorMsg) + } else { + newErr = err + } + ociDownloaded := condition.Cond(catalog.OCIDownloaded) + if apierrors.IsConflict(err) { + ociDownloaded.SetError(newStatus, "", nil) + } else { + ociDownloaded.SetError(newStatus, "", newErr) + } + newStatus.ObservedGeneration = clusterRepo.Generation + + if !equality.Semantic.DeepEqual(newStatus, &clusterRepo.Status) { + // Since status has changed, update the lastUpdatedTime + ociDownloaded.LastUpdated(newStatus, timeNow().UTC().Format(time.RFC3339)) + + clusterRepo.Status = *newStatus + + _, statusErr := o.clusterRepoController.UpdateStatus(clusterRepo) + if statusErr != nil { + return clusterRepo, statusErr + } + } + + if backoff != nil { + o.clusterRepoController.EnqueueAfter(clusterRepo.Name, *backoff) + } else { + o.clusterRepoController.EnqueueAfter(clusterRepo.Name, ociInterval) + } + return clusterRepo, nil +} + +// getIndexfile fetches the indexfile if it already exits for the clusterRepo +// if not, it creates a new indexfile and returns it. +func getIndexfile(clusterRepoStatus catalog.RepoStatus, + clusterRepoSpec catalog.RepoSpec, + configMapClient corev1controllers.ConfigMapClient, + owner metav1.OwnerReference, + namespace string) (*repo.IndexFile, error) { + + indexFile := repo.NewIndexFile() + var configMap *corev1.ConfigMap + var err error + if clusterRepoSpec.URL != clusterRepoStatus.URL { + return indexFile, nil + } + + // If the status has the configmap defined, fetch it. + if clusterRepoStatus.IndexConfigMapName != "" { + configMap, err = configMapClient.Get(clusterRepoStatus.IndexConfigMapNamespace, clusterRepoStatus.IndexConfigMapName, metav1.GetOptions{}) + if err != nil { + return indexFile, fmt.Errorf("failed to fetch the index configmap for clusterRepo %s", owner.Name) + } + } else { + // otherwise if the configmap is already created, fetch it using the name of the configmap and the namespace. + configMapName := GenerateConfigMapName(owner.Name, 0, owner.UID) + configMapNamespace := GetConfigMapNamespace(namespace) + + configMap, err = configMapClient.Get(configMapNamespace, configMapName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return indexFile, nil + } + return indexFile, fmt.Errorf("failed to fetch the index configmap for clusterRepo %s", owner.Name) + } + } + + data, err := readBytes(configMapClient, configMap) + if err != nil { + return indexFile, fmt.Errorf("failed to read bytes of existing configmap for URL %s", clusterRepoSpec.URL) + } + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + logrus.Errorf("failed to create reader for index file for URL %s: %v", clusterRepoSpec.URL, err) + return indexFile, fmt.Errorf("failed to read indexfile for cluster repo") + } + defer gz.Close() + data, err = io.ReadAll(gz) + if err != nil { + logrus.Errorf("failed to read index file for URL %s: %v", clusterRepoSpec.URL, err) + return indexFile, fmt.Errorf("failed to read indexfile for cluster repo") + } + if err := json.Unmarshal(data, indexFile); err != nil { + logrus.Errorf("failed to unmarshal index file for URL %s: %v", clusterRepoSpec.URL, err) + return indexFile, fmt.Errorf("failed to unmarshal indexfile for cluster repo") + } + + return indexFile, nil +} + +// readBytes reads data from the chain of helm repo index configmaps. +func readBytes(configMapCache corev1controllers.ConfigMapClient, cm *corev1.ConfigMap) ([]byte, error) { + var ( + bytes = cm.BinaryData["content"] + err error + ) + + for { + next := cm.Annotations["catalog.cattle.io/next"] + if next == "" { + break + } + cm, err = configMapCache.Get(cm.Namespace, next, metav1.GetOptions{}) + if err != nil { + return nil, err + } + bytes = append(bytes, cm.BinaryData["content"]...) + } + + return bytes, nil +} + +// calculateBackoff gets the amount of time to wait for the next call. +// Reference: https://github.com/oras-project/oras-go/blob/main/registry/remote/retry/policy.go#L95 +func calculateBackoff(clusterRepo *catalog.ClusterRepo, policy retryPolicy) time.Duration { + var h maphash.Hash + h.SetSeed(maphash.MakeSeed()) + rand := rand.New(rand.NewSource(int64(h.Sum64()))) + temp := float64(policy.MinWait) * math.Pow(2, float64(clusterRepo.Status.NumberOfRetries)) + backoff := time.Duration(temp*(1-0.2)) + time.Duration(rand.Int63n(int64(2*0.2*temp))) + if backoff < policy.MinWait { + return policy.MinWait + } + if backoff > policy.MaxWait { + return policy.MaxWait + } + return backoff +} + +// getRetryPolicy returns the retry policy for the repository using the values present in the spec +// or, if they aren't present, the default values +func getRetryPolicy(clusterRepo *catalog.ClusterRepo) (retryPolicy, error) { + // Default Values for exponentialBackOff function which is used + // to retry an HTTP call when 429 response code is hit. + defaultRetryPolicy := retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 5 * time.Second, + MaxRetry: 5, + } + + if clusterRepo.Spec.ExponentialBackOffValues != nil { + // Set MaxRetry if specified and valid + if clusterRepo.Spec.ExponentialBackOffValues.MaxRetries > 0 { + defaultRetryPolicy.MaxRetry = clusterRepo.Spec.ExponentialBackOffValues.MaxRetries + } + + // Set MinWait if specified and valid + if clusterRepo.Spec.ExponentialBackOffValues.MinWait >= 1 { + defaultRetryPolicy.MinWait = time.Duration(clusterRepo.Spec.ExponentialBackOffValues.MinWait) * time.Second + } else if clusterRepo.Spec.ExponentialBackOffValues.MinWait != 0 { + return defaultRetryPolicy, errors.New("minWait must be at least 1 second") + } + + // Set MaxWait if specified and valid + if clusterRepo.Spec.ExponentialBackOffValues.MaxWait > 0 { + defaultRetryPolicy.MaxWait = time.Duration(clusterRepo.Spec.ExponentialBackOffValues.MaxWait) * time.Second + } + } + + // Ensure MaxWait is not less than MinWait + if defaultRetryPolicy.MaxWait < defaultRetryPolicy.MinWait { + return defaultRetryPolicy, errors.New("maxWait must be greater than or equal to minWait") + } + + return defaultRetryPolicy, nil +} + +// shouldSkip checks certain conditions to see if the handler should be skipped. +// For information regarding the conditions, check the comments in the implementation. +func (o *OCIRepohandler) shouldSkip(clusterRepo *catalog.ClusterRepo, policy retryPolicy, key string) bool { + // this is to prevent the handler from making calls when the crd is outdated. + updatedRepo, err := o.clusterRepoController.Get(key, metav1.GetOptions{}) + if err == nil && updatedRepo.ResourceVersion != clusterRepo.ResourceVersion { + return true + } + + if clusterRepo.Status.ObservedGeneration < clusterRepo.Generation { + clusterRepo.Status.NumberOfRetries = 0 + clusterRepo.Status.NextRetryAt = metav1.Time{} + return false + } + + // The handler is triggered immediately after any changes, including when updating the number of retries done. + // This check is to prevent the handler from executing before the backoff time has passed + if !clusterRepo.Status.NextRetryAt.IsZero() && clusterRepo.Status.NextRetryAt.Time.After(timeNow().UTC()) { + return true + } + + if clusterRepo.Status.ShouldNotSkip { //checks if we should skip running the handler or not + return false + } + + ociDownloaded := condition.Cond(catalog.OCIDownloaded) + ociDownloadedUpdateTime, _ := time.Parse(time.RFC3339, ociDownloaded.GetLastUpdated(clusterRepo)) + + if (clusterRepo.Status.NumberOfRetries > policy.MaxRetry || clusterRepo.Status.NumberOfRetries == 0) && // checks if it's not retrying + clusterRepo.Generation == clusterRepo.Status.ObservedGeneration && // checks if the generation has not changed + ociDownloadedUpdateTime.Add(ociInterval).After(timeNow().UTC()) { // checks if the interval has not passed + + o.clusterRepoController.EnqueueAfter(clusterRepo.Name, ociInterval) + return true + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci_test.go new file mode 100644 index 0000000..6209d9d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_oci_test.go @@ -0,0 +1,526 @@ +package helm + +import ( + "bytes" + "compress/gzip" + "encoding/json" + "errors" + "testing" + "time" + + "github.com/golang/mock/gomock" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/rancher/wrangler/v3/pkg/genericcondition" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestGetIndexFile(t *testing.T) { + indexFile := repo.NewIndexFile() + indexFile.Entries["testingchart"] = repo.ChartVersions{ + &repo.ChartVersion{ + Metadata: &chart.Metadata{ + Name: "testingchart", + Version: "0.1.0", + }, + }, + } + + buf := &bytes.Buffer{} + gz := gzip.NewWriter(buf) + err := json.NewEncoder(gz).Encode(indexFile) + assert.NoError(t, err) + + err = gz.Close() + assert.NoError(t, err) + + configMap := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName-0-unique", + Namespace: "cattle-system", + }, + BinaryData: map[string][]byte{ + "content": buf.Bytes(), + }, + } + + tests := []struct { + name string + clusterRepo *catalog.ClusterRepo + newConfigController func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] + expectedResult bool + namespace string + indexFile *repo.IndexFile + expectedErrMsg string + }{ + { + "no error is returned if configfile is not found when fetched through configmap name generation", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.example.com", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + // Set the configMapController Expectations + + configMapControllerFake.EXPECT().Get("cattle-system", "repoName-0-unique", metav1.GetOptions{}).Return(nil, apierrors.NewNotFound(schema.GroupResource{ + Group: corev1.GroupName, + Resource: corev1.ResourceConfigMaps.String(), + }, "repoName-0-unique")) + + return configMapControllerFake + }, + false, + "", + repo.NewIndexFile(), + "", + }, + { + "no error is returned if configfile is not found when fetched through configmap name generation", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.example.com", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + // Set the configMapController Expectations + + configMapControllerFake.EXPECT().Get("cattle-system", "repoName-0-unique", metav1.GetOptions{}).Return(nil, apierrors.NewInternalError(errors.New("internal"))) + + return configMapControllerFake + }, + false, + "", + repo.NewIndexFile(), + "failed to fetch the index configmap", + }, + { + "index File is fetched through the configmap name generation", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.example.com", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + // Set the configMapController Expectations + + configMapControllerFake.EXPECT().Get("cattle-system", "repoName-0-unique", metav1.GetOptions{}).Return(&configMap, nil) + + return configMapControllerFake + }, + false, + "", + indexFile, + "", + }, + { + "error is returned if configmap from status field is failed to fetch", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.example.com", + IndexConfigMapName: "repoName-0-unique", + IndexConfigMapNamespace: "cattle-system", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + // Set the configMapController Expectations + + configMapControllerFake.EXPECT().Get("cattle-system", "repoName-0-unique", metav1.GetOptions{}).Return(nil, errors.New("kube api server not working")) + + return configMapControllerFake + }, + false, + "", + repo.NewIndexFile(), + "failed to fetch the index configmap", + }, + { + "index File is fetched through the status field values", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.example.com", + IndexConfigMapName: "repoName-0-unique", + IndexConfigMapNamespace: "cattle-system", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + // Set the configMapController Expectations + + configMapControllerFake.EXPECT().Get("cattle-system", "repoName-0-unique", metav1.GetOptions{}).Return(&configMap, nil) + + return configMapControllerFake + }, + false, + "", + indexFile, + "", + }, + { + "when spec URL and status URL differ, empty indexFile is returned", + &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: "repoName", + UID: "unique", + }, + Spec: catalog.RepoSpec{ + URL: "www.example.com", + }, + Status: catalog.RepoStatus{ + URL: "www.different.com", + }, + }, + func(ctrl *gomock.Controller) *fake.MockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList] { + configMapControllerFake := fake.NewMockControllerInterface[*corev1.ConfigMap, *corev1.ConfigMapList](ctrl) + return configMapControllerFake + }, + false, + "", + repo.NewIndexFile(), + "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + owner := metav1.OwnerReference{ + APIVersion: catalog.SchemeGroupVersion.Group + "/" + catalog.SchemeGroupVersion.Version, + Kind: "ClusterRepo", + Name: tt.clusterRepo.Name, + UID: tt.clusterRepo.UID, + } + + ctrl := gomock.NewController(t) + configMapController := tt.newConfigController(ctrl) + + indexFile, err := getIndexfile(tt.clusterRepo.Status, tt.clusterRepo.Spec, configMapController, owner, tt.namespace) + assert.Equal(t, indexFile.Entries, tt.indexFile.Entries) + if tt.expectedErrMsg != "" { + assert.Equal(t, tt.expectedErrMsg, "failed to fetch the index configmap") + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestGetRetryPolicy(t *testing.T) { + testCases := []struct { + name string + backOffValues *catalog.ExponentialBackOffValues + expectedRetryPolicy retryPolicy + expectedErr string + }{ + { + name: "Should return default values if exponentailBackOffValues is empty", + backOffValues: &catalog.ExponentialBackOffValues{}, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 5 * time.Second, + MaxRetry: 5, + }, + expectedErr: "", + }, + { + name: "Should return default values if values are not present", + backOffValues: nil, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 5 * time.Second, + MaxRetry: 5, + }, + expectedErr: "", + }, + { + name: "Should get max retries values from clusterRepo", + backOffValues: &catalog.ExponentialBackOffValues{ + MinWait: 1, + MaxWait: 5, + MaxRetries: 10, + }, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 5 * time.Second, + MaxRetry: 10, + }, + expectedErr: "", + }, + { + name: "Should get max wait from clusterRepo", + backOffValues: &catalog.ExponentialBackOffValues{ + MinWait: 1, + MaxWait: 3600, + }, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 1 * time.Hour, + MaxRetry: 5, + }, + expectedErr: "", + }, + { + name: "Should get min wait from clusterRepo", + backOffValues: &catalog.ExponentialBackOffValues{ + MinWait: 60, + MaxWait: 120, + }, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Minute, + MaxWait: 2 * time.Minute, + MaxRetry: 5, + }, + expectedErr: "", + }, + { + name: "minWait should be atleast 1 second", + backOffValues: &catalog.ExponentialBackOffValues{ + MinWait: -1, + MaxWait: 5, + }, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Second, + MaxWait: 5 * time.Second, + MaxRetry: 5, + }, + expectedErr: "minWait must be at least 1 second", + }, + { + name: "maxWait cant be less than minWait", + backOffValues: &catalog.ExponentialBackOffValues{ + MinWait: 60, + MaxWait: 20, + }, + expectedRetryPolicy: retryPolicy{ + MinWait: 1 * time.Minute, + MaxWait: 20 * time.Second, + MaxRetry: 5, + }, + expectedErr: "maxWait must be greater than or equal to minWait", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + clusterRepo := &catalog.ClusterRepo{ + Spec: catalog.RepoSpec{ + ExponentialBackOffValues: testCase.backOffValues, + }, + } + retryPolicy, err := getRetryPolicy(clusterRepo) + if testCase.expectedErr != "" { + assert.Contains(t, err.Error(), testCase.expectedErr) + } else { + assert.Nil(t, err) + } + assert.Equal(t, testCase.expectedRetryPolicy, retryPolicy) + }) + } +} + +func TestShouldSkip(t *testing.T) { + ociInterval = 1 * time.Hour + testCases := []struct { + name string + ociDownloadedTime time.Time + timeNow func() time.Time + nextRetryAt metav1.Time + newClusterRepoController func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] + generation int64 + observedGeneration int64 + maxRetries int + numberOfRetries int + shouldNotSkip bool + expected bool + }{ + { + name: "Should skip if resourceVersion don't match", + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "2"}}, nil) + return mockController + }, + expected: true, + }, + { + name: "Should skip if nextRetryAt is after time.now()", + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 1, 0, 0, time.UTC) + }, + nextRetryAt: metav1.NewTime(time.Date(2024, 04, 23, 10, 2, 0, 0, time.UTC)), + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + expected: true, + }, + { + name: "Should NOT skip if status.ShouldNotSkip is true", + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 1, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + shouldNotSkip: true, + expected: false, + }, + { + name: "Should NOT skip if the handler is retrying", + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 1, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + maxRetries: 5, + numberOfRetries: 1, + expected: false, + }, + { + name: "Should NOT skip if generation has changed", + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 1, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + generation: 1, + observedGeneration: 0, + maxRetries: 5, + numberOfRetries: 0, + expected: false, + }, + { + name: "Should NOT skip if interval has not passed", + ociDownloadedTime: time.Date(2024, 04, 23, 10, 0, 0, 0, time.UTC), + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 1, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + generation: 1, + observedGeneration: 0, + maxRetries: 5, + numberOfRetries: 0, + expected: false, + }, + { + name: "Should skip if handler is done retrying, generation didn't change and interval has not passed", + ociDownloadedTime: time.Date(2024, 04, 23, 10, 0, 0, 0, time.UTC), + timeNow: func() time.Time { + return time.Date(2024, 04, 23, 10, 5, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + mockController.EXPECT().EnqueueAfter("", ociInterval).Return() + return mockController + }, + generation: 1, + observedGeneration: 1, + maxRetries: 5, + numberOfRetries: 6, + expected: true, + }, + { + name: "Should NOT skip if handler is done retrying, generation didn't change but interval has passed", + ociDownloadedTime: time.Date(2024, 04, 23, 10, 0, 0, 0, time.UTC), + timeNow: func() time.Time { + return time.Date(2024, 04, 24, 11, 0, 0, 0, time.UTC) + }, + newClusterRepoController: func(ctrl *gomock.Controller) *fake.MockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList] { + mockController := fake.NewMockNonNamespacedControllerInterface[*catalog.ClusterRepo, *catalog.ClusterRepoList](ctrl) + mockController.EXPECT().Get("clusterRepo", metav1.GetOptions{}).Return(&catalog.ClusterRepo{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "1"}}, nil) + return mockController + }, + generation: 1, + observedGeneration: 1, + maxRetries: 5, + numberOfRetries: 5, + expected: false, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + policy := retryPolicy{MaxRetry: testCase.maxRetries} + ctrl := gomock.NewController(t) + mockController := testCase.newClusterRepoController(ctrl) + handler := OCIRepohandler{clusterRepoController: mockController} + timeNow = testCase.timeNow + clusterRepo := &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Generation: testCase.generation, + ResourceVersion: "1", + }, + Status: catalog.RepoStatus{ + ObservedGeneration: testCase.observedGeneration, + NumberOfRetries: testCase.numberOfRetries, + NextRetryAt: testCase.nextRetryAt, + ShouldNotSkip: testCase.shouldNotSkip, + Conditions: []genericcondition.GenericCondition{ + { + Type: string(catalog.OCIDownloaded), + LastUpdateTime: testCase.ociDownloadedTime.Format(time.RFC3339), + }, + }}, + } + assert.Equal(t, testCase.expected, handler.shouldSkip(clusterRepo, policy, "clusterRepo")) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_test.go new file mode 100644 index 0000000..105c095 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/helm/repo_test.go @@ -0,0 +1,211 @@ +package helm + +import ( + "testing" + "time" + + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestShouldRefresh(t *testing.T) { + tests := []struct { + name string + spec *catalog.RepoSpec + status *catalog.RepoStatus + expectedResult bool + }{ + { + "http repo - spec equals status", + &catalog.RepoSpec{ + URL: "https://example.com", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + false, + }, + { + "http repo - url changed", + &catalog.RepoSpec{ + URL: "https://changed-url.com", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + true, + }, + { + "http repo - missing indexConfigMap", + &catalog.RepoSpec{ + URL: "https://example.com", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + true, + }, + { + "http repo - download not so long ago", + &catalog.RepoSpec{ + URL: "https://example.com", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now().Add(-1 * time.Minute), + }, + }, + false, + }, + { + "http repo - download to long ago", + &catalog.RepoSpec{ + URL: "https://example.com", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now().Add(-7 * time.Hour), + }, + }, + true, + }, + { + "http repo - force update", + &catalog.RepoSpec{ + URL: "https://example.com", + ForceUpdate: &metav1.Time{ + Time: time.Now(), + }, + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now().Add(-1 * time.Minute), + }, + }, + true, + }, + { + "http repo - force update older than download time", + &catalog.RepoSpec{ + URL: "https://example.com", + ForceUpdate: &metav1.Time{ + Time: time.Now().Add(-2 * time.Minute), + }, + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now().Add(-1 * time.Minute), + }, + }, + false, + }, + { + "http repo - force update in the future", + &catalog.RepoSpec{ + URL: "https://example.com", + ForceUpdate: &metav1.Time{ + Time: time.Now().Add(2 * time.Minute), + }, + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + false, + }, + { + "git repo - spec equals status", + &catalog.RepoSpec{ + GitBranch: "master", + GitRepo: "git.example.com", + }, + &catalog.RepoStatus{ + Branch: "master", + URL: "git.example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + false, + }, + { + "git repo - branch changed", + &catalog.RepoSpec{ + GitBranch: "main", + GitRepo: "git.example.com", + }, + &catalog.RepoStatus{ + Branch: "master", + URL: "git.example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + true, + }, + { + "git repo - repo changed", + &catalog.RepoSpec{ + GitBranch: "master", + GitRepo: "newgit.example.com", + }, + &catalog.RepoStatus{ + Branch: "master", + URL: "git.example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + true, + }, + { + "http repo - spec equals status, but unnecessary git branch in spec", + &catalog.RepoSpec{ + URL: "https://example.com", + GitBranch: "master", + }, + &catalog.RepoStatus{ + URL: "https://example.com", + IndexConfigMapName: "configmap", + DownloadTime: metav1.Time{ + Time: time.Now(), + }, + }, + false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := shouldRefresh(tt.spec, tt.status) + assert.Equal(t, tt.expectedResult, result) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller.go new file mode 100644 index 0000000..4ef3c65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller.go @@ -0,0 +1,245 @@ +package hostedcluster + +import ( + "context" + "fmt" + "os" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + controllerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + controllerprojectv3 "github.com/rancher/rancher/pkg/generated/controllers/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/kv" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const priorityClassKey = "priorityClassName" + +var ( + AksCrdChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-aks-operator-crd", + } + AksChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-aks-operator", + } + EksCrdChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-eks-operator-crd", + } + EksChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-eks-operator", + } + GkeCrdChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-gke-operator-crd", + } + GkeChart = chart.Definition{ + ReleaseNamespace: "cattle-system", + ChartName: "rancher-gke-operator", + } +) + +var ( + localCluster = "local" + + legacyOperatorAppNameFormat = "rancher-%s-operator" +) + +type handler struct { + manager chart.Manager + appCache controllerprojectv3.AppCache + apps controllerprojectv3.AppController + projectCache controllerv3.ProjectCache + secretsCache v1.SecretCache + chartsConfig chart.RancherConfigGetter +} + +func Register(ctx context.Context, wContext *wrangler.Context) { + h := &handler{ + manager: wContext.SystemChartsManager, + apps: wContext.Project.App(), + projectCache: wContext.Mgmt.Project().Cache(), + secretsCache: wContext.Core.Secret().Cache(), + appCache: wContext.Project.App().Cache(), + chartsConfig: chart.RancherConfigGetter{ConfigCache: wContext.Core.ConfigMap().Cache()}, + } + + wContext.Mgmt.Cluster().OnChange(ctx, "cluster-provisioning-operator", h.onClusterChange) + wContext.Core.Secret().OnChange(ctx, "watch-helm-release", h.onSecretChange) +} + +func (h handler) onClusterChange(key string, cluster *v3.Cluster) (*v3.Cluster, error) { + if cluster == nil { + return cluster, nil + } + + skipChartInstallation := strings.EqualFold(settings.SkipHostedClusterChartInstallation.Get(), "true") + if skipChartInstallation { + logrus.Warn("Skipping installation of hosted cluster charts, 'skip-hosted-cluster-chart-installation' is set to true") + return cluster, nil + } + + var toInstallCrdChart, toInstallChart *chart.Definition + var provider, toInstallCrdChartVersion, toInstallChartVersion string + toInstallCrdChartVersion = "" + toInstallChartVersion = "" + if cluster.Spec.AKSConfig != nil { + toInstallCrdChart = &AksCrdChart + toInstallChart = &AksChart + if aksOperatorVersion := settings.AksOperatorVersion.Get(); aksOperatorVersion != "" { + toInstallCrdChartVersion = aksOperatorVersion + toInstallChartVersion = aksOperatorVersion + } + provider = "aks" + } else if cluster.Spec.EKSConfig != nil { + toInstallCrdChart = &EksCrdChart + toInstallChart = &EksChart + if eksOperatorVersion := settings.EksOperatorVersion.Get(); eksOperatorVersion != "" { + toInstallCrdChartVersion = eksOperatorVersion + toInstallChartVersion = eksOperatorVersion + } + provider = "eks" + } else if cluster.Spec.GKEConfig != nil { + toInstallCrdChart = &GkeCrdChart + toInstallChart = &GkeChart + if gkeOperatorVersion := settings.GkeOperatorVersion.Get(); gkeOperatorVersion != "" { + toInstallCrdChartVersion = gkeOperatorVersion + toInstallChartVersion = gkeOperatorVersion + } + provider = "gke" + } + + if toInstallCrdChart == nil || toInstallChart == nil { + return cluster, nil + } + + if err := h.removeLegacyOperatorIfExists(provider); err != nil { + return cluster, err + } + + if err := h.manager.Ensure( + toInstallCrdChart.ReleaseNamespace, + toInstallCrdChart.ChartName, + toInstallCrdChartVersion, + "", + nil, + true, + ""); err != nil { + return cluster, err + } + + systemGlobalRegistry := map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + } + + additionalCA, err := getAdditionalCA(h.secretsCache) + if err != nil { + return cluster, err + } + + chartValues := map[string]interface{}{ + "global": systemGlobalRegistry, + "httpProxy": os.Getenv("HTTP_PROXY"), + "httpsProxy": os.Getenv("HTTPS_PROXY"), + "noProxy": os.Getenv("NO_PROXY"), + "additionalTrustedCAs": additionalCA != nil, + } + // add priority class value + if priorityClassName, err := h.chartsConfig.GetGlobalValue(chart.PriorityClassKey); err != nil { + if !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher priorityClassName for 'rancher-webhook': %s", err.Error()) + } + } else { + chartValues[priorityClassKey] = priorityClassName + } + + if err := h.manager.Ensure( + toInstallChart.ReleaseNamespace, + toInstallChart.ChartName, + toInstallChartVersion, + "", + chartValues, + true, + ""); err != nil { + return cluster, err + } + + return cluster, nil +} + +// check helm release secrets for aks/eks/gke operator chart, if it has been uninstalled, then remove it in m.manager.desiredChart +// so that we don't automatically redeploy it unless there is an AKS/EKS/GKE cluster triggering it +func (h handler) onSecretChange(key string, obj *corev1.Secret) (*corev1.Secret, error) { + if obj == nil { + ns, name := kv.Split(key, "/") + if ns == namespace.System { + // the name will follow the format sh.helm.release.v1.rancher-eks-operator-crd.v1 + parts := strings.Split(name, ".") + if len(parts) == 6 { + releaseName := parts[4] + if isOperatorChartRelease(releaseName) { + h.manager.Remove(ns, releaseName) + } + } + } + } + return obj, nil +} + +func isOperatorChartRelease(name string) bool { + switch name { + case AksCrdChart.ChartName, AksChart.ChartName, EksCrdChart.ChartName, EksChart.ChartName, GkeChart.ChartName, GkeCrdChart.ChartName: + return true + } + return false +} + +func (h handler) removeLegacyOperatorIfExists(provider string) error { + systemProject, err := project.GetSystemProject(localCluster, h.projectCache) + if err != nil { + return err + } + + systemProjectID := ref.Ref(systemProject) + _, systemProjectName := ref.Parse(systemProjectID) + + legacyOperatorAppName := fmt.Sprintf(legacyOperatorAppNameFormat, provider) + _, err = h.appCache.Get(systemProjectName, legacyOperatorAppName) + if err != nil { + if errors.IsNotFound(err) { + // legacy app doesn't exist, no-op + return nil + } + return err + } + + return h.apps.Delete(systemProjectName, legacyOperatorAppName, &metav1.DeleteOptions{}) +} + +func getAdditionalCA(secretsCache v1.SecretCache) ([]byte, error) { + secret, err := secretsCache.Get(namespace.System, "tls-ca-additional") + if err != nil && !errors.IsNotFound(err) { + return nil, err + } + + if secret == nil { + return nil, nil + } + + return secret.Data["ca-additional.pem"], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller_test.go new file mode 100644 index 0000000..f70c30e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/hostedcluster/controller_test.go @@ -0,0 +1,212 @@ +package hostedcluster + +import ( + "fmt" + "os" + "reflect" + "testing" + + "github.com/golang/mock/gomock" + aksv1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + projectv3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + chartsfake "github.com/rancher/rancher/pkg/controllers/dashboard/chart/fake" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var priorityClassName = "rancher-critical" + +func Test_handler_onClusterChange(t *testing.T) { + + tests := []struct { + name string + cluster *v3.Cluster + newManager func(ctrl *gomock.Controller) chart.Manager + wantErr bool + }{ + { + name: "normal installation", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + AKSConfig: &aksv1.AKSClusterConfigSpec{}, + }, + }, + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("pass") + settings.AksOperatorVersion.Set("") + + manager := chartsfake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "httpProxy": os.Getenv("HTTP_PROXY"), + "httpsProxy": os.Getenv("HTTPS_PROXY"), + "noProxy": os.Getenv("NO_PROXY"), + "additionalTrustedCAs": false, + "priorityClassName": priorityClassName, + } + var b bool + manager.EXPECT().Ensure( + AksCrdChart.ReleaseNamespace, + AksCrdChart.ChartName, + settings.AksOperatorVersion.Get(), + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + manager.EXPECT().Ensure( + AksChart.ReleaseNamespace, + AksChart.ChartName, + settings.AksOperatorVersion.Get(), + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + + return manager + }, + }, + { + name: "no priority class installation", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + AKSConfig: &aksv1.AKSClusterConfigSpec{}, + }, + }, + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("error") + settings.AksOperatorVersion.Set("") + manager := chartsfake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "httpProxy": os.Getenv("HTTP_PROXY"), + "httpsProxy": os.Getenv("HTTPS_PROXY"), + "noProxy": os.Getenv("NO_PROXY"), + "additionalTrustedCAs": false, + } + var b bool + manager.EXPECT().Ensure( + AksCrdChart.ReleaseNamespace, + AksCrdChart.ChartName, + settings.AksOperatorVersion.Get(), + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + manager.EXPECT().Ensure( + AksChart.ReleaseNamespace, + AksChart.ChartName, + settings.AksOperatorVersion.Get(), + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + + return manager + }, + }, + { + name: "normal installation with chart version precedence", + cluster: &v3.Cluster{ + Spec: v3.ClusterSpec{ + AKSConfig: &aksv1.AKSClusterConfigSpec{}, + }, + }, + newManager: func(ctrl *gomock.Controller) chart.Manager { + settings.ConfigMapName.Set("pass") + manager := chartsfake.NewMockManager(ctrl) + expectedValues := map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + "httpProxy": os.Getenv("HTTP_PROXY"), + "httpsProxy": os.Getenv("HTTPS_PROXY"), + "noProxy": os.Getenv("NO_PROXY"), + "additionalTrustedCAs": false, + "priorityClassName": priorityClassName, + } + + exactVersion := "1.4.0" + settings.AksOperatorVersion.Set(exactVersion) + + var b bool + manager.EXPECT().Ensure( + AksCrdChart.ReleaseNamespace, + AksCrdChart.ChartName, + exactVersion, + "", + nil, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + manager.EXPECT().Ensure( + AksChart.ReleaseNamespace, + AksChart.ChartName, + exactVersion, + "", + expectedValues, + gomock.AssignableToTypeOf(b), + "", + ).Return(nil) + + return manager + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + h := newHandler(ctrl) + h.manager = tt.newManager(ctrl) + got, err := h.onClusterChange("", tt.cluster) + if tt.wantErr { + assert.Error(t, err, "handler.onRepo() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.NoError(t, err, "unexpected error") + if !reflect.DeepEqual(got, tt.cluster) { + t.Errorf("handler.onClusterChange() = %v, want %v", got, tt.cluster) + } + }) + } +} + +func newHandler(ctrl *gomock.Controller) *handler { + appCache := fake.NewMockCacheInterface[*projectv3.App](ctrl) + // appCache := NewMockAppCache(ctrl) + appCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, nil) + apps := fake.NewMockControllerInterface[*projectv3.App, *projectv3.AppList](ctrl) + apps.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + projectCache := fake.NewMockCacheInterface[*v3.Project](ctrl) + projectCache.EXPECT().List(gomock.Any(), gomock.Any()).Return([]*v3.Project{{ObjectMeta: metav1.ObjectMeta{Name: "test"}}}, nil) + secretsCache := fake.NewMockCacheInterface[*v1.Secret](ctrl) + secretsCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, nil) + configCache := fake.NewMockCacheInterface[*v1.ConfigMap](ctrl) + configCache.EXPECT().Get(gomock.Any(), "pass").Return(&v1.ConfigMap{Data: map[string]string{"priorityClassName": priorityClassName}}, nil).AnyTimes() + configCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("not found")).AnyTimes() + return &handler{ + appCache: appCache, + apps: apps, + projectCache: projectCache, + secretsCache: secretsCache, + chartsConfig: chart.RancherConfigGetter{ConfigCache: configCache}, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/kubernetesprovider/kubernetesprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/kubernetesprovider/kubernetesprovider.go new file mode 100644 index 0000000..9577212 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/kubernetesprovider/kubernetesprovider.go @@ -0,0 +1,78 @@ +package kubernetesprovider + +import ( + "context" + + detector "github.com/rancher/kubernetes-provider-detector" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v32 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "k8s.io/client-go/kubernetes" +) + +const ( + providerKey = "provider.cattle.io" +) + +type handler struct { + ctx context.Context + clusters v32.ClusterClient + localClusterClient kubernetes.Interface + mcm wrangler.MultiClusterManager +} + +func Register(ctx context.Context, + clusters v32.ClusterController, + localClusterClient kubernetes.Interface, + mcm wrangler.MultiClusterManager, +) { + h := &handler{ + ctx: ctx, + clusters: clusters, + localClusterClient: localClusterClient, + mcm: mcm, + } + clusters.OnChange(ctx, "kubernetes-provider", h.OnChange) +} + +func (h *handler) OnChange(key string, cluster *v3.Cluster) (*v3.Cluster, error) { + if cluster == nil || (cluster.Status.Provider != "" && cluster.Labels[providerKey] != "") { + // if cluster has windows enabled and provider is not rke.windows, continue to detect if it has windows nodes + if cluster == nil || !cluster.Spec.WindowsPreferedCluster || cluster.Status.Provider == "rke.windows" { + return cluster, nil + } + } + + if !v3.ClusterConditionReady.IsTrue(cluster) { + return cluster, nil + } + + var client kubernetes.Interface + if cluster.Spec.Internal { + client = h.localClusterClient + } else if k8s, err := h.mcm.K8sClient(cluster.Name); err != nil { + // ignore error. If we can't get a client just ignore it. The cluster probably isn't happy + // yet and we will get an update later when it is. + return nil, nil + } else if k8s != nil { + client = k8s + } + + if client == nil { + return cluster, nil + } + + provider, err := detector.DetectProvider(h.ctx, client) + if err == detector.ErrUnknownProvider { + return cluster, nil + } else if err != nil { + return cluster, err + } + cluster = cluster.DeepCopy() + if cluster.Labels == nil { + cluster.Labels = map[string]string{} + } + cluster.Labels[providerKey] = provider + cluster.Status.Provider = provider + return h.clusters.Update(cluster) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/mcmagent/mcmagent.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/mcmagent/mcmagent.go new file mode 100644 index 0000000..1406d66 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/mcmagent/mcmagent.go @@ -0,0 +1,17 @@ +package mcmagent + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/managementagent" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, wrangler *wrangler.Context) error { + userContext, err := config.NewUserOnlyContext(wrangler) + if err != nil { + return err + } + return managementagent.Register(ctx, userContext) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/controller.go new file mode 100644 index 0000000..caa7d32 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/controller.go @@ -0,0 +1,98 @@ +package plugin + +import ( + "context" + "fmt" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + plugincontroller "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func Register( + ctx context.Context, + wContext *wrangler.Context, +) { + h := &handler{ + systemNamespace: namespace.UIPluginNamespace, + plugin: wContext.Catalog.UIPlugin(), + pluginCache: wContext.Catalog.UIPlugin().Cache(), + } + wContext.Catalog.UIPlugin().OnChange(ctx, "on-ui-plugin-change", h.OnPluginChange) +} + +type handler struct { + systemNamespace string + plugin plugincontroller.UIPluginController + pluginCache plugincontroller.UIPluginCache +} + +func (h *handler) OnPluginChange(key string, plugin *v1.UIPlugin) (*v1.UIPlugin, error) { + cachedPlugins, err := h.pluginCache.List(h.systemNamespace, labels.Everything()) + if err != nil { + return plugin, fmt.Errorf("failed to list plugins from cache: %w", err) + } + err = Index.Generate(cachedPlugins) + if err != nil { + return plugin, fmt.Errorf("failed to generate index with cached plugins: %w", err) + } + var anonymousCachedPlugins []*v1.UIPlugin + for _, cachedPlugin := range cachedPlugins { + if cachedPlugin.Spec.Plugin.NoAuth { + anonymousCachedPlugins = append(anonymousCachedPlugins, cachedPlugin) + } + } + err = AnonymousIndex.Generate(anonymousCachedPlugins) + if err != nil { + return plugin, fmt.Errorf("failed to generate anonymous index with cached plugins: %w", err) + } + pattern := FSCacheRootDir + "/*/*" + fsCacheFiles, err := fsCacheFilepathGlob(pattern) + if err != nil { + return plugin, fmt.Errorf("failed to get files from filesystem cache: %w", err) + } + FsCache.SyncWithIndex(&Index, fsCacheFiles) + if plugin == nil { + return plugin, nil + } + defer h.plugin.UpdateStatus(plugin) + if plugin.Spec.Plugin.NoCache { + plugin.Status.CacheState = Disabled + } else { + plugin.Status.CacheState = Pending + } + for _, p := range cachedPlugins { + err2 := FsCache.SyncWithControllersCache(p) + if errors.Is(err2, errMaxFileSizeError) { + // update CRD to remove cache + p.Spec.Plugin.NoCache = true + _, err2 := h.plugin.Update(p) + if err2 != nil { + logrus.Errorf("failed to update plugin [%s] noCache flag: %s", p.Spec.Plugin.Name, err2.Error()) + continue + } + // delete files that were written + err2 = FsCache.Delete(p.Spec.Plugin.Name, p.Spec.Plugin.Version) + if err2 != nil { + logrus.Error(err2) + continue + } + p.Status.CacheState = Disabled + } else { + err = err2 + } + } + if err != nil { + return plugin, fmt.Errorf("failed to sync filesystem cache with controller cache: %w", err) + } + if !plugin.Spec.Plugin.NoCache { + plugin.Status.CacheState = Cached + } + + return plugin, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache.go new file mode 100644 index 0000000..9ffc07f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache.go @@ -0,0 +1,303 @@ +package plugin + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + "regexp" + "strconv" + "strings" + "syscall" + + "github.com/Masterminds/semver/v3" + filepathsecure "github.com/cyphar/filepath-securejoin" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" +) + +const ( + FilesTxtFilename = "files.txt" + PackageJSONFilename = "plugin/package.json" + + // Cache states used by custom resources + Cached = "cached" + Disabled = "disabled" + Pending = "pending" +) + +var ( + FsCache = FSCache{} + errMaxFileSizeError = fmt.Errorf("file size limit of %s bytes reached", settings.MaxUIPluginFileByteSize.Get()) + FSCacheRootDir = filepath.Join("management-state", "uiplugin") + osRemoveAll = os.RemoveAll + osStat = os.Stat + isDirEmpty = isDirectoryEmpty + fileNameRegex = regexp.MustCompile(`(^[/\\.])|\.\.`) +) + +type FSCache struct { +} + +type PackageJSON struct { + Version string `json:"version,omitempty"` +} + +// SyncWithControllersCache takes in a UI Plugin object and syncs the filesystem cache with it +func (c FSCache) SyncWithControllersCache(p *v1.UIPlugin) error { + plugin := p.Spec.Plugin + if plugin.NoCache { + logrus.Debugf("skipped caching plugin [Name: %s Version: %s] cache is disabled [noCache: %v]", plugin.Name, plugin.Version, plugin.NoCache) + return nil + } + if isCached, err := c.isCached(plugin.Name, plugin.Version); err != nil { + return err + } else if isCached { + logrus.Debugf("skipped caching plugin [Name: %s Version: %s] is already cached", plugin.Name, plugin.Version) + return nil + } + version, err := getVersionFromPackageJSON(fmt.Sprintf("%s/%s", plugin.Endpoint, PackageJSONFilename)) + if err != nil { + return err + } + cachedVersion, err := semver.NewVersion(plugin.Version) + if err != nil { + return err + } + if !cachedVersion.Equal(version) { + return fmt.Errorf("plugin [%s] version [%s] does not match version in controller's cache [%s]", plugin.Name, version.String(), cachedVersion.String()) + } + files, err := fetchFilesTxt(fmt.Sprintf("%s/%s", plugin.Endpoint, FilesTxtFilename)) + if err != nil { + return err + } + for _, file := range files { + if file == "" { + continue + } + data, err := fetchFile(plugin.Endpoint + "/" + file) + if err != nil { + return err + } + path, err := filepathsecure.SecureJoin(FSCacheRootDir, filepath.Join(plugin.Name, plugin.Version, file)) + if err != nil { + return err + } + if err := c.Save(data, path); err != nil { + logrus.Debugf("failed to cache plugin [Name: %s Version: %s] in filesystem [path: %s]", plugin.Name, plugin.Version, path) + } + } + + return nil +} + +// SyncWithIndex syncs up entries in the filesystem cache with the index's entries. +// Entries that aren't in the index, but present in the filesystem cache are deleted +func (c FSCache) SyncWithIndex(index *SafeIndex, fsCacheFiles []string) error { + for _, file := range fsCacheFiles { + logrus.Debugf("syncing index with filesystem cache") + chartName, chartVersion, err := getChartNameAndVersion(file) + if err != nil { + return err + } + _, ok := index.Entries[chartName] + if !ok || index.Entries[chartName].Version != chartVersion { + err := c.Delete(chartName, chartVersion) + if err != nil { + return err + } + } + } + + return nil +} + +// Save takes in data and a path to save it in the filesystem cache +func (c FSCache) Save(data []byte, path string) error { + logrus.Debugf("creating file [%s]", path) + if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { + return err + } + out, err := os.OpenFile(path, syscall.O_RDWR|syscall.O_CREAT|syscall.O_TRUNC, 0600) + if err != nil { + return err + } + defer out.Close() + out.Write(data) + + return nil +} + +// Delete takes in a plugin's name and version, and deletes its entry in the filesystem cache +func (c FSCache) Delete(name, version string) error { + p, err := filepathsecure.SecureJoin(FSCacheRootDir, name) + if err != nil { + return err + } + err = osRemoveAll(p) + if err != nil { + err = fmt.Errorf("failed to delete entry [Name: %s Version: %s] from filesystem cache: %w", name, version, err) + return err + } + logrus.Debugf("deleted plugin entry from cache [Name: %s Version: %s]", name, version) + + return nil +} + +// isCached takes in the name and version of a plugin and returns true if +// it is cached (entry exists and files were fetched), returns false otherwise +func (c FSCache) isCached(name, version string) (bool, error) { + path, err := filepathsecure.SecureJoin(FSCacheRootDir, filepath.Join(name, version)) + if err != nil { + return false, err + } + _, err = osStat(path) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return false, nil + } + return false, err + } + isEmpty, err := isDirEmpty(path) + if err != nil { + return false, err + } + if !isEmpty { + return true, nil + } + return false, nil +} + +// getChartNameAndVersion receives a filepath and returns the chart name and chart version. +// The path has to follow /{root}/{chartName}/{chartVersion}/* +func getChartNameAndVersion(file string) (string, string, error) { + root, err := filepath.Abs(FSCacheRootDir) + if err != nil { + return "", "", fmt.Errorf("unable to get absolute root path: %w", err) + } + filePath, err := filepath.Abs(file) + if err != nil { + return "", "", fmt.Errorf("unable to get absolute file path: %w", err) + } + + // file has to be rooted at FSCacheRootDir + if strings.HasPrefix(filePath, root) { + p, _ := strings.CutPrefix(filePath, root) + s := strings.Split(p, string(os.PathSeparator)) + if len(s) < 3 { + return "", "", fmt.Errorf("file path is not valid. Path provided: %s", file) + } + chartName := s[1] + chartVersion := s[2] + if _, err := semver.NewVersion(chartVersion); err != nil { + return "", "", fmt.Errorf("invalid chart version: %w", err) + } + return chartName, chartVersion, nil + } + return "", "", fmt.Errorf("path root is not the root cache path. Path provided: %s", file) + +} + +func fsCacheFilepathGlob(pattern string) ([]string, error) { + files, err := filepath.Glob(pattern) + if err != nil { + return nil, err + } + logrus.Debugf("files matching glob pattern [%s] found in filesystem cache: %+v", pattern, files) + + return files, nil +} + +// getVersionFromPackageJSON takes in a URL for a plugin's package.json, reads it, and returns a Semver object of the version contained in the file +func getVersionFromPackageJSON(packageJSONURL string) (*semver.Version, error) { + data, err := fetchFile(packageJSONURL) + if err != nil { + return nil, err + } + var packageJSON PackageJSON + err = json.Unmarshal(data, &packageJSON) + if err != nil { + return nil, err + } + version, err := semver.NewVersion(packageJSON.Version) + if err != nil { + return nil, err + } + + return version, nil +} + +// fetchFilesTxt takes in a URL for a plugin's files.txt, reads it, and returns a slice of the file paths contained in the file +func fetchFilesTxt(filesTxtURL string) ([]string, error) { + data, err := fetchFile(filesTxtURL) + if err != nil { + return nil, err + } + files := strings.Split(string(data), "\n") + + err = validateFilesTxtEntries(files) + if err != nil { + return nil, err + } + + return files, nil +} + +// fetchFile reads the file from the given URL and returns the data +func fetchFile(URL string) ([]byte, error) { + logrus.Debugf("fetching file [%s]", URL) + resp, err := http.Get(URL) + if err != nil { + return nil, err + } + defer resp.Body.Close() + maxFileSize, err := strconv.ParseInt(settings.MaxUIPluginFileByteSize.Get(), 10, 64) + if err != nil { + logrus.Errorf("failed to convert setting MaxUIPluginFileByteSize to int64, using fallback. err: %s", err.Error()) + maxFileSize = settings.DefaultMaxUIPluginFileSizeInBytes + } + if resp.ContentLength > maxFileSize { + return nil, errMaxFileSizeError + } + reader := &io.LimitedReader{R: resp.Body, N: maxFileSize + 1} + data, err := io.ReadAll(reader) + if err != nil { + return nil, err + } + if reader.N == 0 { + return nil, errMaxFileSizeError + } + return data, nil +} + +func isDirectoryEmpty(path string) (bool, error) { + f, err := os.Open(path) + if err != nil { + return false, err + } + defer f.Close() + _, err = f.Readdirnames(1) + if err == io.EOF { + return true, nil + } + + return false, err +} + +func validateFilesTxtEntries(entries []string) error { + for _, entry := range entries { + file, err := url.QueryUnescape(entry) + if err != nil { + return fmt.Errorf("failed to decode entry: %s", entry) + } + if fileNameRegex.MatchString(file) { + return fmt.Errorf("invalid file entry: %s", file) + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache_test.go new file mode 100644 index 0000000..4a14a0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/fscache_test.go @@ -0,0 +1,302 @@ +package plugin + +import ( + "fmt" + "io/fs" + "os" + "testing" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/stretchr/testify/assert" +) + +func TestSyncWithIndex(t *testing.T) { + testCases := []struct { + Name string + CurrentEntries map[string]*v1.UIPluginEntry + ExpectedEntries map[string]*v1.UIPluginEntry + FsCacheFiles []string + ShouldDelete bool + }{ + { + Name: "Sync index with FS cache no new entries", + CurrentEntries: map[string]*v1.UIPluginEntry{ + "test-plugin": { + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + }, + ExpectedEntries: map[string]*v1.UIPluginEntry{ + "test-plugin": { + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + }, + FsCacheFiles: []string{ + FSCacheRootDir + "/test-plugin/0.1.0", + }, + }, + { + Name: "Sync index with FS cache delete old test-plugin-2 entry", + CurrentEntries: map[string]*v1.UIPluginEntry{ + "test-plugin": { + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + }, + ExpectedEntries: map[string]*v1.UIPluginEntry{ + "test-plugin": { + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + }, + FsCacheFiles: []string{ + FSCacheRootDir + "/test-plugin/0.1.0", + FSCacheRootDir + "/test-plugin-2/0.1.0", + }, + ShouldDelete: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + var ( + osRemoveAllCalled bool + actualPluginDeleted string + ) + if tc.ShouldDelete { + osRemoveAll = func(path string) error { + osRemoveAllCalled = true + actualPluginDeleted = path + return nil + } + } + fsCache := FSCache{} + index := SafeIndex{ + Entries: tc.CurrentEntries, + } + err := fsCache.SyncWithIndex(&index, tc.FsCacheFiles) + if err != nil { + t.Error(err) + } + assert.Equal(t, index.Entries, tc.CurrentEntries) + if tc.ShouldDelete { + assert.Equal(t, tc.ShouldDelete, osRemoveAllCalled) + expectedPluginDeleted := FSCacheRootDir + "/test-plugin-2" + assert.Equal(t, expectedPluginDeleted, actualPluginDeleted) + } + }) + } +} + +func Test_isCached(t *testing.T) { + testCases := []struct { + Name string + PluginName string + PluginVersion string + Expected bool + OsStatErr error + IsDirEmptyVal bool + }{ + { + Name: "Test cached plugin", + PluginName: "test-plugin", + PluginVersion: "0.0.1", + Expected: true, + OsStatErr: nil, + IsDirEmptyVal: false, + }, + { + Name: "Test non cached plugin", + PluginName: "test-plugin", + PluginVersion: "0.0.1", + Expected: false, + OsStatErr: os.ErrNotExist, + IsDirEmptyVal: true, + }, + { + Name: "Test cached plugin but dir is empty", + PluginName: "test-plugin", + PluginVersion: "0.0.1", + Expected: false, + OsStatErr: nil, + IsDirEmptyVal: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + osStat = func(name string) (fs.FileInfo, error) { + return nil, tc.OsStatErr + } + isDirEmpty = func(path string) (bool, error) { + return tc.IsDirEmptyVal, nil + } + fsCache := FSCache{} + actual, err := fsCache.isCached(tc.PluginName, tc.PluginVersion) + if err != nil { + t.Error(err) + } + assert.Equal(t, tc.Expected, actual) + }) + } +} + +func Test_getChartNameAndVersion(t *testing.T) { + testCases := []struct { + name string + input string + expectedChartName string + expectedChartVersion string + expectedError error + }{ + { + name: "chart rooted at FSCacheRootDir", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "istio/v2.1.0"), + expectedChartName: "istio", + expectedChartVersion: "v2.1.0", + expectedError: nil, + }, + { + name: "chart rooted at FSCacheRootDir with rc version", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "istio/v2.1.0-rc1"), + expectedChartName: "istio", + expectedChartVersion: "v2.1.0-rc1", + expectedError: nil, + }, + { + name: "file rooted at FSCacheRootDir", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "istio/2.1.0/Chart.yaml"), + expectedChartName: "istio", + expectedChartVersion: "2.1.0", + expectedError: nil, + }, + { + name: "chart rooted at FSCacheRootDir without version", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "istio"), + expectedChartName: "", + expectedChartVersion: "", + expectedError: fmt.Errorf("file path is not valid"), + }, + { + name: "chart rooted at FSCacheRootDir with invalid version", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "istio/invalid-version"), + expectedChartName: "", + expectedChartVersion: "", + expectedError: fmt.Errorf("invalid chart version"), + }, + { + name: "chart not rooted at FSCacheRootDir", + input: "/home/wrong-path/bad-chart/v1.0.0", + expectedChartName: "", + expectedChartVersion: "", + expectedError: fmt.Errorf("path root is not the root cache path"), + }, + { + name: "chart not rooted at FSCacheRootDir with ../", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "../bad-chart/v2.1.0"), + expectedChartName: "", + expectedChartVersion: "", + expectedError: fmt.Errorf("path root is not the root cache path"), + }, + { + name: "chart not rooted at FSCacheRootDir 2", + input: fmt.Sprintf("%s/%s", FSCacheRootDir, "/istio/../../bad-chart/v2.1.0"), + expectedChartName: "", + expectedChartVersion: "", + expectedError: fmt.Errorf("path root is not the root cache path"), + }, + } + + for _, testCase := range testCases { + + chartName, chartVersion, err := getChartNameAndVersion(testCase.input) + assert.Equal(t, testCase.expectedChartName, chartName, testCase.name) + assert.Equal(t, testCase.expectedChartVersion, chartVersion, testCase.name) + if testCase.expectedError != nil { + assert.ErrorContains(t, err, testCase.expectedError.Error(), testCase.name) + } else { + assert.NoError(t, err, testCase.name) + } + } +} + +func Test_validateFilesTxtEntries(t *testing.T) { + testCases := []struct { + Name string + Files []string + ShouldErr bool + }{ + { + Name: "valid files", + Files: []string{"plugin/file.js", "plugin/folder/file.min.js"}, + ShouldErr: false, + }, + { + Name: "valid encoded files", + Files: []string{"plugins%2Ffile.js", "plugin%2Ffolder%2Ffile.min.js"}, + ShouldErr: false, + }, + { + Name: "invalid file starting with /", + Files: []string{"/plugin/file.js", "plugin/folder/file.js"}, + ShouldErr: true, + }, + { + Name: "invalid encoded file starting with /", + Files: []string{"%2Fplugin%2Ffile.js", "plugin/folder/file.js"}, + ShouldErr: true, + }, + { + Name: "invalid file starting with \\", + Files: []string{"\\plugin/file.js", "plugin/folder/file.js"}, + ShouldErr: true, + }, + { + Name: "invalid file starting with ..", + Files: []string{"plugin/file.js", "../plugin/folder/file.js"}, + ShouldErr: true, + }, + { + Name: "invalid file starting with .", + Files: []string{"plugin/file.js", ".plugin/folder/file.js"}, + ShouldErr: true, + }, + { + Name: "invalid file containing ..", + Files: []string{"plugin/file.js", "plugin/folder/../file.js"}, + ShouldErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + err := validateFilesTxtEntries(tc.Files) + if tc.ShouldErr { + assert.ErrorContains(t, err, "invalid file entry") + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index.go new file mode 100644 index 0000000..f7d4254 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index.go @@ -0,0 +1,33 @@ +package plugin + +import ( + "sync" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/sirupsen/logrus" +) + +var ( + Index = SafeIndex{} + AnonymousIndex = SafeIndex{} +) + +type SafeIndex struct { + mu sync.RWMutex + Entries map[string]*v1.UIPluginEntry `json:"entries,omitempty"` +} + +// Generate generates a new index from a UIPluginCache object +func (s *SafeIndex) Generate(cachedPlugins []*v1.UIPlugin) error { + logrus.Debug("generating index from plugin controller's cache") + s.mu.Lock() + defer s.mu.Unlock() + s.Entries = make(map[string]*v1.UIPluginEntry, len(cachedPlugins)) + for _, plugin := range cachedPlugins { + entry := &plugin.Spec.Plugin + logrus.Debugf("adding plugin to index: %+v", *entry) + s.Entries[entry.Name] = entry + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index_test.go new file mode 100644 index 0000000..d561fff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/plugin/index_test.go @@ -0,0 +1,75 @@ +package plugin + +import ( + "testing" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/stretchr/testify/assert" +) + +func TestGenerate(t *testing.T) { + testCases := []struct { + Name string + CachedPlugins []*v1.UIPlugin + ExpectedEntries map[string]*v1.UIPluginEntry + }{ + { + Name: "Generate valid index from controllers cached plugins", + CachedPlugins: []*v1.UIPlugin{ + { + Spec: v1.UIPluginSpec{ + Plugin: v1.UIPluginEntry{ + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + }, + }, + { + Spec: v1.UIPluginSpec{ + Plugin: v1.UIPluginEntry{ + Name: "test-plugin-2", + Version: "0.1.1", + Endpoint: "https://test-2.endpoint.svc", + NoCache: true, + Metadata: map[string]string{}, + }, + }, + }, + }, + ExpectedEntries: map[string]*v1.UIPluginEntry{ + "test-plugin": { + Name: "test-plugin", + Version: "0.1.0", + Endpoint: "https://test.endpoint.svc", + NoCache: false, + Metadata: map[string]string{ + "test": "data", + }, + }, + "test-plugin-2": { + Name: "test-plugin-2", + Version: "0.1.1", + Endpoint: "https://test-2.endpoint.svc", + NoCache: true, + Metadata: map[string]string{}, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + index := SafeIndex{} + err := index.Generate(tc.CachedPlugins) + if err != nil { + t.Error(err) + } + assert.Equal(t, tc.ExpectedEntries, index.Entries) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/scaleavailable/scale.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/scaleavailable/scale.go new file mode 100644 index 0000000..773d1af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/scaleavailable/scale.go @@ -0,0 +1,103 @@ +package scaleavailable + +import ( + "context" + "strconv" + + "github.com/rancher/rancher/pkg/wrangler" + appscontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" +) + +const ( + availableAnnotation = "management.cattle.io/scale-available" +) + +type handler struct { + node corecontrollers.NodeCache + deployments appscontrollers.DeploymentClient +} + +func Register(ctx context.Context, wrangler *wrangler.Context) { + h := &handler{ + node: wrangler.Core.Node().Cache(), + deployments: wrangler.Apps.Deployment(), + } + deploymentCache := wrangler.Apps.Deployment().Cache() + wrangler.Apps.Deployment().OnChange(ctx, "scale-available", h.OnChange) + deploymentCache.AddIndexer(availableAnnotation, func(obj *appsv1.Deployment) ([]string, error) { + if val := obj.Annotations[availableAnnotation]; val != "" { + return []string{availableAnnotation}, nil + } + return nil, nil + }) + relatedresource.Watch(ctx, "scale-available-trigger", func(namespace, name string, obj runtime.Object) (result []relatedresource.Key, _ error) { + deps, err := deploymentCache.GetByIndex(availableAnnotation, availableAnnotation) + if err != nil { + return nil, err + } + for _, obj := range deps { + result = append(result, relatedresource.Key{ + Namespace: obj.Namespace, + Name: obj.Name, + }) + } + return result, nil + }, wrangler.Apps.Deployment(), wrangler.Core.Node()) +} + +func (h *handler) OnChange(key string, deployment *appsv1.Deployment) (*appsv1.Deployment, error) { + if deployment == nil { + return nil, nil + } + numStr := deployment.Annotations[availableAnnotation] + if numStr == "" { + return deployment, nil + } + + num, err := strconv.Atoi(numStr) + if err != nil { + // ignore errors + return deployment, nil + } + + selector := labels.SelectorFromSet(deployment.Spec.Template.Spec.NodeSelector) + if deployment.Spec.Template.Spec.Affinity != nil && deployment.Spec.Template.Spec.Affinity.NodeAffinity != nil && + deployment.Spec.Template.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil { + for _, term := range deployment.Spec.Template.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms { + for _, term := range term.MatchExpressions { + req, err := labels.NewRequirement(term.Key, selection.Operator(term.Operator), term.Values) + if err == nil { + selector.Add(*req) + } + } + } + } + + nodes, err := h.node.List(labels.SelectorFromSet(deployment.Spec.Template.Spec.NodeSelector)) + if err != nil { + return deployment, nil + } + + if len(nodes) < num { + num = len(nodes) + } + + if num == 0 { + num = 1 + } + + if deployment.Spec.Replicas == nil || *deployment.Spec.Replicas != int32(num) { + replicas := int32(num) + deployment := deployment.DeepCopy() + deployment.Spec.Replicas = &replicas + return h.deployments.Update(deployment) + } + + return deployment, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller.go new file mode 100644 index 0000000..edf3cd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller.go @@ -0,0 +1,232 @@ +// Package systemcharts handles the reconciliation of systemcharts installed by rancher in the rancher-charts repo. +package systemcharts + +import ( + "context" + + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + "github.com/rancher/rancher/pkg/features" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/data" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + repoName = "rancher-charts" + priorityClassKey = "priorityClassName" +) + +var ( + primaryImages = map[string]string{ + chart.WebhookChartName: "rancher/rancher-webhook", + chart.ProvisioningCAPIChartName: "rancher/mirrored-cluster-api-controller", + } + watchedSettings = map[string]struct{}{ + settings.RancherWebhookVersion.Name: {}, + settings.RancherProvisioningCAPIVersion.Name: {}, + settings.SystemDefaultRegistry.Name: {}, + settings.ShellImage.Name: {}, + } +) + +// Register is called to create a new handler and subscribe to change events. +func Register(ctx context.Context, wContext *wrangler.Context, registryOverride string) error { + h := &handler{ + manager: wContext.SystemChartsManager, + namespaces: wContext.Core.Namespace(), + chartsConfig: chart.RancherConfigGetter{ConfigCache: wContext.Core.ConfigMap().Cache()}, + registryOverride: registryOverride, + } + + wContext.Catalog.ClusterRepo().OnChange(ctx, "bootstrap-charts", h.onRepo) + relatedresource.WatchClusterScoped(ctx, "bootstrap-charts", relatedFeatures, wContext.Catalog.ClusterRepo(), wContext.Mgmt.Feature()) + + relatedresource.WatchClusterScoped(ctx, "bootstrap-settings-charts", relatedSettings, wContext.Catalog.ClusterRepo(), wContext.Mgmt.Setting()) + + // ensure the system charts are installed with the correct values when there are changes to the rancher config map + relatedresource.WatchClusterScoped(ctx, "bootstrap-configmap-charts", relatedConfigMaps, wContext.Catalog.ClusterRepo(), wContext.Core.ConfigMap()) + return nil +} + +type handler struct { + manager chart.Manager + namespaces corecontrollers.NamespaceController + chartsConfig chart.RancherConfigGetter + registryOverride string +} + +func (h *handler) onRepo(key string, repo *catalog.ClusterRepo) (*catalog.ClusterRepo, error) { + if repo == nil || repo.Name != repoName { + return repo, nil + } + + systemGlobalRegistry := map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + } + if h.registryOverride != "" { + // if we have a specific image override, don't set the system default registry + // don't need to check for type assert since we just created this above + registryMap := systemGlobalRegistry["cattle"].(map[string]interface{}) + registryMap["systemDefaultRegistry"] = "" + systemGlobalRegistry["cattle"] = registryMap + } + for _, chartDef := range h.getChartsToInstall() { + if chartDef.Enabled != nil && !chartDef.Enabled() { + continue + } + + if chartDef.Uninstall { + if err := h.manager.Uninstall(chartDef.ReleaseNamespace, chartDef.ChartName); err != nil { + return repo, err + } + if chartDef.RemoveNamespace { + if err := h.namespaces.Delete(chartDef.ReleaseNamespace, nil); err != nil && !errors.IsNotFound(err) { + return repo, err + } + } + continue + } + + values := map[string]interface{}{ + "global": systemGlobalRegistry, + } + var installImageOverride string + if h.registryOverride != "" { + imageSettings, ok := values["image"].(map[string]interface{}) + if !ok { + imageSettings = map[string]interface{}{} + } + if image, ok := primaryImages[chartDef.ChartName]; ok { + imageSettings["repository"] = h.registryOverride + "/" + image + } + values["image"] = imageSettings + installImageOverride = h.registryOverride + "/" + settings.ShellImage.Get() + } + if chartDef.Values != nil { + for k, v := range chartDef.Values() { + values[k] = v + } + } + // webhook needs to be able to adopt the MutatingWebhookConfiguration which originally wasn't a part of the + // chart definition, but is now part of the chart definition + minVersion := chartDef.MinVersionSetting.Get() + exactVersion := chartDef.ExactVersionSetting.Get() + takeOwnership := chartDef.ChartName == chart.WebhookChartName || chartDef.ChartName == chart.ProvisioningCAPIChartName + if err := h.manager.Ensure(chartDef.ReleaseNamespace, chartDef.ChartName, minVersion, exactVersion, values, takeOwnership, installImageOverride); err != nil { + return repo, err + } + } + + return repo, nil +} + +func (h *handler) getChartsToInstall() []*chart.Definition { + return []*chart.Definition{ + { + ReleaseNamespace: namespace.System, + ChartName: chart.WebhookChartName, + ExactVersionSetting: settings.RancherWebhookVersion, + Values: func() map[string]interface{} { + values := map[string]interface{}{ + // This is no longer used in the webhook chart but previous values can still be found + // with `helm get values -n cattle-system rancher-webhook` which can be confusing. We + // completely remove the previous capi values by setting it to nil here. + "capi": nil, + "mcm": map[string]interface{}{ + "enabled": features.MCM.Enabled(), + }, + } + // add priority class value + if priorityClassName, err := h.chartsConfig.GetGlobalValue(chart.PriorityClassKey); err != nil { + if !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher %s for 'rancher-webhook': %s", chart.PriorityClassKey, err.Error()) + } + } else { + values[priorityClassKey] = priorityClassName + } + + // get custom values for the rancher-webhook + configMapValues, err := h.chartsConfig.GetChartValues(chart.WebhookChartName) + if err != nil && !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher rancherWebhookValues %s", err.Error()) + } + + return data.MergeMaps(values, configMapValues) + }, + Enabled: func() bool { return true }, + }, + { + ReleaseNamespace: "rancher-operator-system", + ChartName: "rancher-operator", + Uninstall: true, + RemoveNamespace: true, + }, + { + ReleaseNamespace: namespace.ProvisioningCAPINamespace, + ChartName: chart.ProvisioningCAPIChartName, + ExactVersionSetting: settings.RancherProvisioningCAPIVersion, + Values: func() map[string]interface{} { + values := map[string]interface{}{} + // add priority class value + if priorityClassName, err := h.chartsConfig.GetGlobalValue(chart.PriorityClassKey); err != nil { + if !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher %s for 'rancher-provisioning-capi': %s", chart.PriorityClassKey, err.Error()) + } + } else { + values[priorityClassKey] = priorityClassName + } + + // get custom values for the rancher-provisioning-capi + configMapValues, err := h.chartsConfig.GetChartValues(chart.ProvisioningCAPIChartName) + if err != nil && !chart.IsNotFoundError(err) { + logrus.Warnf("Failed to get rancher-provisioning-capi %s", err.Error()) + } + + return data.MergeMaps(values, configMapValues) + }, + Enabled: func() bool { return true }, + Uninstall: !features.EmbeddedClusterAPI.Enabled(), + RemoveNamespace: !features.EmbeddedClusterAPI.Enabled(), + }, + } +} + +func relatedFeatures(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if _, ok := obj.(*v3.Feature); ok { + return []relatedresource.Key{{ + Name: repoName, + }}, nil + } + return nil, nil +} + +func relatedSettings(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if f, ok := obj.(*v3.Setting); ok { + if _, ok := watchedSettings[f.Name]; ok { + return []relatedresource.Key{{ + Name: repoName, + }}, nil + } + } + return nil, nil +} + +func relatedConfigMaps(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if configMap, ok := obj.(*v1.ConfigMap); ok && configMap.Namespace == namespace.System && (configMap.Name == chart.CustomValueMapName || configMap.Name == settings.ConfigMapName.Get()) { + return []relatedresource.Key{{ + Name: repoName, + }}, nil + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller_test.go new file mode 100644 index 0000000..89a962a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboard/systemcharts/controller_test.go @@ -0,0 +1,453 @@ +package systemcharts + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + catalog "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/chart" + chartfake "github.com/rancher/rancher/pkg/controllers/dashboard/chart/fake" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + errTest = fmt.Errorf("test error") + priorityClassName = "rancher-critical" + operatorNamespace = "rancher-operator-system" + priorityConfig = &v1.ConfigMap{ + Data: map[string]string{ + "priorityClassName": priorityClassName, + }, + } + fullConfig = &v1.ConfigMap{ + Data: map[string]string{ + "priorityClassName": priorityClassName, + chart.WebhookChartName: testYAML, + }, + } + emptyConfig = &v1.ConfigMap{} + originalVersion = settings.RancherWebhookVersion.Get() + originalMCM = features.MCM.Enabled() +) + +const testYAML = `--- +newKey: newValue +mcm: + enabled: false +global: "" +priorityClassName: newClass +` + +type testMocks struct { + manager *chartfake.MockManager + namespaceCtrl *fake.MockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList] + configCache *fake.MockCacheInterface[*v1.ConfigMap] +} + +func (t *testMocks) Handler() *handler { + return &handler{ + manager: t.manager, + namespaces: t.namespaceCtrl, + chartsConfig: chart.RancherConfigGetter{ConfigCache: t.configCache}, + } +} + +// Test_ChartInstallation test that all expected charts are installed or uninstalled with expected configuration. +func Test_ChartInstallation(t *testing.T) { + repo := &catalog.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: repoName, + }, + } + tests := []struct { + name string + setup func(testMocks) + registryOverride string + wantErr bool + }{ + { + name: "normal installation", + setup: func(mocks testMocks) { + mocks.namespaceCtrl.EXPECT().Delete(operatorNamespace, nil).Return(nil) + mocks.configCache.EXPECT().Get(namespace.System, chart.CustomValueMapName).Return(priorityConfig, nil).Times(4) + settings.RancherWebhookVersion.Set("2.0.0") + settings.RancherProvisioningCAPIVersion.Set("2.0.0") + expectedValues := map[string]interface{}{ + "priorityClassName": priorityClassName, + "capi": nil, + "mcm": map[string]interface{}{ + "enabled": features.MCM.Enabled(), + }, + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + } + mocks.manager.EXPECT().Ensure( + namespace.System, + "rancher-webhook", + "", + "2.0.0", + expectedValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + expectedProvCAPIValues := map[string]interface{}{ + "priorityClassName": priorityClassName, + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + } + + mocks.manager.EXPECT().Ensure( + namespace.ProvisioningCAPINamespace, + "rancher-provisioning-capi", + "", + "2.0.0", + expectedProvCAPIValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + mocks.manager.EXPECT().Uninstall(operatorNamespace, "rancher-operator").Return(nil) + }, + }, + { + name: "installation with config cache errors", + setup: func(mocks testMocks) { + mocks.namespaceCtrl.EXPECT().Delete(operatorNamespace, nil).Return(nil) + mocks.configCache.EXPECT().Get(gomock.Any(), chart.CustomValueMapName).Return(nil, errTest).Times(4) + settings.RancherWebhookVersion.Set("2.0.0") + settings.RancherProvisioningCAPIVersion.Set("2.0.0") + expectedValues := map[string]interface{}{ + "capi": nil, + "mcm": map[string]interface{}{ + "enabled": features.MCM.Enabled(), + }, + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + } + mocks.manager.EXPECT().Ensure( + namespace.System, + "rancher-webhook", + "", + "2.0.0", + expectedValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + expectedProvCAPIValues := map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": settings.SystemDefaultRegistry.Get(), + }, + }, + } + mocks.manager.EXPECT().Ensure( + namespace.ProvisioningCAPINamespace, + "rancher-provisioning-capi", + "", + "2.0.0", + expectedProvCAPIValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + mocks.manager.EXPECT().Uninstall(operatorNamespace, "rancher-operator").Return(nil) + }, + }, + { + name: "installation with image override", + setup: func(mocks testMocks) { + mocks.namespaceCtrl.EXPECT().Delete(operatorNamespace, nil).Return(nil) + mocks.configCache.EXPECT().Get(gomock.Any(), chart.CustomValueMapName).Return(emptyConfig, nil).Times(4) + settings.RancherWebhookVersion.Set("2.0.1") + settings.RancherProvisioningCAPIVersion.Set("2.0.1") + expectedValues := map[string]interface{}{ + "capi": nil, + "mcm": map[string]interface{}{ + "enabled": features.MCM.Enabled(), + }, + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": "", + }, + }, + "image": map[string]interface{}{ + "repository": "rancher-test.io/rancher/rancher-webhook", + }, + } + mocks.manager.EXPECT().Ensure( + namespace.System, + "rancher-webhook", + "", + "2.0.1", + expectedValues, + gomock.AssignableToTypeOf(false), + "rancher-test.io/"+settings.ShellImage.Get(), + ).Return(nil) + + expectedProvCAPIValues := map[string]interface{}{ + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": "", + }, + }, + "image": map[string]interface{}{ + "repository": "rancher-test.io/rancher/mirrored-cluster-api-controller", + }, + } + + mocks.manager.EXPECT().Ensure( + namespace.ProvisioningCAPINamespace, + "rancher-provisioning-capi", + "", + "2.0.1", + expectedProvCAPIValues, + gomock.AssignableToTypeOf(false), + "rancher-test.io/"+settings.ShellImage.Get(), + ).Return(nil) + + mocks.manager.EXPECT().Uninstall(operatorNamespace, "rancher-operator").Return(nil) + }, + registryOverride: "rancher-test.io", + }, + { + name: "installation with webhook values", + setup: func(mocks testMocks) { + mocks.namespaceCtrl.EXPECT().Delete(operatorNamespace, nil).Return(nil) + mocks.configCache.EXPECT().Get(gomock.Any(), chart.CustomValueMapName).Return(fullConfig, nil).Times(4) + settings.RancherWebhookVersion.Set("2.0.0") + settings.RancherProvisioningCAPIVersion.Set("2.0.0") + features.MCM.Set(true) + expectedValues := map[string]interface{}{ + "priorityClassName": "newClass", + "capi": nil, + "mcm": map[string]interface{}{ + "enabled": false, + }, + "global": "", + "newKey": "newValue", + } + mocks.manager.EXPECT().Ensure( + namespace.System, + "rancher-webhook", + "", + "2.0.0", + expectedValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + expectedProvCAPIValues := map[string]interface{}{ + "priorityClassName": priorityClassName, + "global": map[string]interface{}{ + "cattle": map[string]interface{}{ + "systemDefaultRegistry": "", + }, + }, + } + mocks.manager.EXPECT().Ensure( + namespace.ProvisioningCAPINamespace, + "rancher-provisioning-capi", + "", + "2.0.0", + expectedProvCAPIValues, + gomock.AssignableToTypeOf(false), + "", + ).Return(nil) + + mocks.manager.EXPECT().Uninstall(operatorNamespace, "rancher-operator").Return(nil) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // reset setting to default values before each test + settings.RancherWebhookVersion.Set(originalVersion) + settings.RancherProvisioningCAPIVersion.Set(originalVersion) + features.MCM.Set(originalMCM) + + ctrl := gomock.NewController(t) + + // create mocks for each test + mocks := testMocks{ + manager: chartfake.NewMockManager(ctrl), + namespaceCtrl: fake.NewMockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList](ctrl), + configCache: fake.NewMockCacheInterface[*v1.ConfigMap](ctrl), + } + + // allow test to add expected calls to mocks and run any additional setup + tt.setup(mocks) + h := mocks.Handler() + + // add any registryOverrides + h.registryOverride = tt.registryOverride + _, err := h.onRepo("", repo) + if (err != nil) != tt.wantErr { + require.FailNow(t, "handler.onRepo() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} + +func Test_relatedConfigMaps(t *testing.T) { + const fooMap = "foo" + orig := settings.ConfigMapName.Get() + defer func() { settings.ConfigMapName.Set(orig) }() + settings.ConfigMapName.Set(fooMap) + tests := []struct { + changedObj runtime.Object + name string + want []relatedresource.Key + }{ + { + name: "rancher-config change", + changedObj: &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + Name: chart.CustomValueMapName, + Namespace: namespace.System, + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "configMap from settings change", + changedObj: &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + Name: fooMap, + Namespace: namespace.System, + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "rancher-config changed wrong namespace", + changedObj: &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + Name: chart.CustomValueMapName, + Namespace: "", + }}, + want: nil, + }, + { + name: "configMap from settings change wrong namespace", + changedObj: &v1.ConfigMap{ObjectMeta: metav1.ObjectMeta{ + Name: fooMap, + Namespace: fooMap, + }}, + want: nil, + }, + { + name: "incorrect type", + changedObj: &v3.Setting{ObjectMeta: metav1.ObjectMeta{ + Name: chart.CustomValueMapName, + Namespace: namespace.System, + }}, + want: nil, + }, + } + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + got, err := relatedConfigMaps("", "", test.changedObj) + require.NoError(t, err, "unexpected error") + require.Equal(t, test.want, got) + + }) + } +} + +func Test_relatedFeature(t *testing.T) { + tests := []struct { + changedObj runtime.Object + name string + want []relatedresource.Key + }{ + { + name: "feature changed", + changedObj: &v3.Feature{ObjectMeta: metav1.ObjectMeta{ + Name: features.MCM.Name(), + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "incorrect type", + changedObj: &v3.Setting{ObjectMeta: metav1.ObjectMeta{ + Name: chart.CustomValueMapName, + Namespace: namespace.System, + }}, + want: nil, + }, + } + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + got, err := relatedFeatures("", "", test.changedObj) + require.NoError(t, err, "unexpected error") + require.Equal(t, test.want, got) + + }) + } +} + +func Test_relatedSettings(t *testing.T) { + tests := []struct { + changedObj runtime.Object + name string + want []relatedresource.Key + }{ + { + name: "rancher version", + changedObj: &v3.Setting{ObjectMeta: metav1.ObjectMeta{ + Name: settings.RancherWebhookVersion.Name, + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "system default registry", + changedObj: &v3.Setting{ObjectMeta: metav1.ObjectMeta{ + Name: settings.SystemDefaultRegistry.Name, + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "shell image", + changedObj: &v3.Setting{ObjectMeta: metav1.ObjectMeta{ + Name: settings.ShellImage.Name, + }}, + want: []relatedresource.Key{{Name: repoName, Namespace: ""}}, + }, + { + name: "incorrect type", + changedObj: &v3.Feature{ObjectMeta: metav1.ObjectMeta{ + Name: chart.CustomValueMapName, + Namespace: namespace.System, + }}, + want: nil, + }, + } + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + got, err := relatedSettings("", "", test.changedObj) + require.NoError(t, err, "unexpected error") + require.Equal(t, test.want, got) + + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/controller.go new file mode 100644 index 0000000..3ca0802 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/controller.go @@ -0,0 +1,16 @@ +package dashboardapi + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/dashboard/helm" + "github.com/rancher/rancher/pkg/controllers/dashboardapi/feature" + "github.com/rancher/rancher/pkg/controllers/dashboardapi/settings" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, wrangler *wrangler.Context) error { + feature.Register(ctx, wrangler.Mgmt.Feature()) + helm.RegisterReposForFollowers(ctx, wrangler.Core.Secret().Cache(), wrangler.Catalog.ClusterRepo()) + return settings.Register(wrangler.Mgmt.Setting()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler.go new file mode 100644 index 0000000..a2cfba0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler.go @@ -0,0 +1,68 @@ +package feature + +import ( + "context" + "fmt" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/sirupsen/logrus" +) + +func Register(ctx context.Context, features managementv3.FeatureController) { + features.OnChange(ctx, "features-restart-handler", sync) +} + +func sync(_ string, obj *v3.Feature) (*v3.Feature, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + val := getEffectiveValue(obj) + if err := ReconcileFeatures(obj, val); err != nil { + time.Sleep(3 * time.Second) + logrus.Fatalf("%v", err) + } + + return obj, nil +} + +// getEffectiveValue considers a feature's default, value, and locked value to determine +// its effective value. +func getEffectiveValue(obj *v3.Feature) bool { + val := obj.Status.Default + if obj.Spec.Value != nil { + val = *obj.Spec.Value + } + if obj.Status.LockedValue != nil { + val = *obj.Status.LockedValue + } + return val +} + +// ReconcileFeatures returns an error if the feature value in memory does +// not match the feature value in etcd AND the feature is non-dynamic. +// Otherwise, the feature value in memory is reconciled and no error is +// returned. +func ReconcileFeatures(obj *v3.Feature, newVal bool) error { + feature := features.GetFeatureByName(obj.Name) + + // possible feature watch renamed, or no longer used by rancher + if feature == nil { + return nil + } + + if newVal == feature.Enabled() { + return nil + } + + if !feature.Dynamic() { + return fmt.Errorf("feature flag [%s] value has changed, rancher must be restarted", obj.Name) + } + + feature.Set(newVal) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler_test.go new file mode 100644 index 0000000..801fdec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/feature/feature_handler_test.go @@ -0,0 +1,50 @@ +package feature + +import ( + "testing" + + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestReconcileFeatures(t *testing.T) { + assert := assert.New(t) + + // testing a non-dynamic feature + mockFeature := v3.Feature{ + ObjectMeta: v1.ObjectMeta{ + Name: "multi-cluster-management-agent", + }, + } + + feature := features.GetFeatureByName(mockFeature.Name) + assert.Equal(false, feature.Enabled()) + + err := ReconcileFeatures(&mockFeature, false) + assert.Nil(err) + assert.Equal(false, feature.Enabled()) + + err = ReconcileFeatures(&mockFeature, true) + assert.Error(err) + assert.Equal(false, feature.Enabled()) + + // testing a dynamic feature + mockFeature = v3.Feature{ + ObjectMeta: v1.ObjectMeta{ + Name: "istio-virtual-service-ui", + }, + } + + feature = features.GetFeatureByName(mockFeature.Name) + assert.Equal(true, feature.Enabled()) + + err = ReconcileFeatures(&mockFeature, true) + assert.Nil(err) + assert.Equal(true, feature.Enabled()) + + err = ReconcileFeatures(&mockFeature, false) + assert.Nil(err) + assert.Equal(false, feature.Enabled()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings.go new file mode 100644 index 0000000..21a7757 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings.go @@ -0,0 +1,207 @@ +// Package settings registers the settings provider which acts as a client for setting and provides functions for +// maintaining settings in k8s on startup. This maintenance includes configuring setting to match any corresponding +// env variables that are set or updating their default values. +package settings + +import ( + "fmt" + "os" + + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" +) + +func Register(settingController managementcontrollers.SettingController) error { + sp := &settingsProvider{ + settings: settingController, + settingCache: settingController.Cache(), + } + + return settings.SetProvider(sp) +} + +type settingsProvider struct { + settings managementcontrollers.SettingClient + settingCache managementcontrollers.SettingCache + fallback map[string]string +} + +func (s *settingsProvider) Get(name string) string { + value := os.Getenv(settings.GetEnvKey(name)) + if value != "" { + return value + } + + obj, err := s.settingCache.Get(name) + if err != nil { + val, err := s.settings.Get(name, metav1.GetOptions{}) + if err != nil { + return s.fallback[name] + } + obj = val + } + + if obj.Value == "" { + return obj.Default + } + + return obj.Value +} + +func (s *settingsProvider) Set(name, value string) error { + envValue := os.Getenv(settings.GetEnvKey(name)) + if envValue != "" { + return fmt.Errorf("setting %s can not be set because it is from environment variable", name) + } + obj, err := s.settings.Get(name, metav1.GetOptions{}) + if err != nil { + return err + } + + obj.Value = value + _, err = s.settings.Update(obj) + return err +} + +func (s *settingsProvider) SetIfUnset(name, value string) error { + obj, err := s.settings.Get(name, metav1.GetOptions{}) + if err != nil { + return err + } + + if obj.Value != "" { + return nil + } + + obj.Value = value + _, err = s.settings.Update(obj) + return err +} + +// SetAll iterates through a map of settings.Setting and updates corresponding settings in k8s +// to match any values set for them via their respective CATTLE_ env var, their +// source to "env" if configured by an env var, and their default to match the setting in the map. +// NOTE: All settings not provided in settingsMap will be marked as unknown, and may be removed in the future. +func (s *settingsProvider) SetAll(settingsMap map[string]settings.Setting) error { + anyInstalled, err := s.anySettingsInstalled() + if err != nil { + return fmt.Errorf("failed to check if any settings are installed: %w", err) + } + fallback := map[string]string{} + + for name, setting := range settingsMap { + key := settings.GetEnvKey(name) + envValue, envOk := os.LookupEnv(key) + + obj, err := s.settings.Get(setting.Name, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + newSetting := &v3.Setting{ + ObjectMeta: metav1.ObjectMeta{ + Name: setting.Name, + }, + Default: setting.Default, + } + if anyInstalled && setting.DefaultOnUpgrade != "" { + newSetting.Default = setting.DefaultOnUpgrade + } + if envOk { + newSetting.Source = "env" + newSetting.Value = envValue + } + if newSetting.Value == "" { + fallback[newSetting.Name] = newSetting.Default + } else { + fallback[newSetting.Name] = newSetting.Value + } + _, err := s.settings.Create(newSetting) + // Rancher will race in an HA setup to try and create the settings + // so if it exists just move on. + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else if err != nil { + return err + } else { + update := false + if obj.Default != setting.Default { + if setting.DefaultOnUpgrade != "" { + obj.Default = setting.DefaultOnUpgrade + } else { + obj.Default = setting.Default + } + update = true + } + if envOk && obj.Source != "env" { + obj.Source = "env" + update = true + } + if !envOk && obj.Source == "env" { + obj.Source = "" + update = true + } + if envOk && obj.Value != envValue { + obj.Value = envValue + update = true + } + if obj.Value == "" { + fallback[obj.Name] = obj.Default + } else { + fallback[obj.Name] = obj.Value + } + if update { + _, err := s.settings.Update(obj) + if err != nil { + return err + } + } + } + } + + s.fallback = fallback + + if err := s.cleanupUnknownSettings(settingsMap); err != nil { + logrus.Errorf("Error cleaning up unknown settings: %v", err) + } + + return nil +} + +// cleanupUnknownSettings lists all settings in the cluster and deletes all unknown (e.g. deprecated) settings. +func (s *settingsProvider) cleanupUnknownSettings(settingsMap map[string]settings.Setting) error { + // The settings cache is not yet available at this point, thus using the client directly. + list, err := s.settings.List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, setting := range list.Items { + if _, ok := settingsMap[setting.Name]; ok { + continue + } + + err = s.settings.Delete(setting.Name, &metav1.DeleteOptions{}) + if err != nil { + logrus.Errorf("Error deleting unknown setting %s: %v", setting.Name, err) + continue + } + + logrus.Warnf("Deleted unknown setting %s", setting.Name) + } + + return nil +} + +// anySettingsInstalled tries to find out if at least one setting is installed as a resource in the cluster. +// It is used as a way to know if Rancher has been started for the first time. +func (s *settingsProvider) anySettingsInstalled() (bool, error) { + list, err := s.settings.List(metav1.ListOptions{}) + if err != nil { + return false, err + } + return len(list.Items) > 0, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings_test.go new file mode 100644 index 0000000..1ef8d8a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/dashboardapi/settings/settings_test.go @@ -0,0 +1,460 @@ +package settings + +import ( + "errors" + "fmt" + "os" + "testing" + + "github.com/golang/mock/gomock" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/utils/pointer" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" +) + +type testCase struct { + description string + envVar *string + newDefVal string + newSetting settings.Setting + existingSetting *v3.Setting +} + +func TestSetAll(t *testing.T) { + t.Skip() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + + store := make(map[string]v3.Setting) + get := func(name string, options metav1.GetOptions) (*v3.Setting, error) { + val, ok := store[name] + if !ok { + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + } + + return &val, nil + } + set := func(setting *v3.Setting) (*v3.Setting, error) { + store[setting.Name] = *setting + return setting, nil + } + + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Create(gomock.Any()).DoAndReturn(set).AnyTimes() + client.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + client.EXPECT().List(gomock.Any()).DoAndReturn(func(opts metav1.ListOptions) (*v3.SettingList, error) { + var items []v3.Setting + for _, setting := range store { + items = append(items, setting) + } + + return &v3.SettingList{Items: items}, nil + }).AnyTimes() + client.EXPECT().Delete(gomock.Any(), gomock.Any()).DoAndReturn(func(name string, opts *metav1.DeleteOptions) error { + delete(store, name) + return nil + }).Times(1) + + settingMap := make(map[string]settings.Setting) + testCases := populateTestCases() + for _, test := range testCases { + settingMap[test.newSetting.Name] = test.newSetting + if test.envVar != nil { + envKey := settings.GetEnvKey(test.newSetting.Name) + os.Setenv(envKey, *test.envVar) + defer os.Unsetenv(envKey) + } + + if test.existingSetting != nil { + store[test.newSetting.Name] = *test.existingSetting + } + } + + store["unknown"] = v3.Setting{ + ObjectMeta: metav1.ObjectMeta{ + Name: "unknown", + }, + Value: "unknown", + Default: "unknown", + } + + err := provider.SetAll(settingMap) + assert.Nil(t, err, "set all should not return an error") + + for _, test := range testCases { + finalSetting, err := provider.settings.Get(test.newSetting.Name, metav1.GetOptions{}) + assert.Nil(t, err) + fallbackValue := provider.fallback[test.newSetting.Name] + failMsg := fmt.Sprintf("test case failed [%s]: %s", test.newSetting.Name, test.description) + fallbackFailMsg := fmt.Sprintf("test case failed [%s]: fallback value not properly set", test.newSetting.Name) + + // Updating setting in kubernetes should have the default from newSetting. + assert.Equal(t, finalSetting.Default, test.newSetting.Default, failMsg) + + // If the value is configured by an environment variable, then the source should be "env", otherwise it should be empty. + assert.True(t, finalSetting.Source == "env" == (test.envVar != nil), failMsg) + + var expectedFallbackVal string + if test.envVar != nil { + // Environment variable takes precedence of everything. Setting's value should match as long as it was set. + assert.Equal(t, *test.envVar, finalSetting.Value, failMsg) + expectedFallbackVal = *test.envVar + } else if test.existingSetting != nil { + expectedFallbackVal = test.existingSetting.Value + assert.Equal(t, test.existingSetting.Value, finalSetting.Value, failMsg) + } else { + assert.Equal(t, "", finalSetting.Value, failMsg) + } + + if expectedFallbackVal == "" { + // Fallback value should be equal to default if value is empty. This is how clients of the settings provider + // evaluate the effective value of the setting. + expectedFallbackVal = test.newSetting.Default + } + + assert.Equal(t, expectedFallbackVal, fallbackValue, fallbackFailMsg) + } + + assert.NotContains(t, store, "unknown") + + // Make sure the store doesn't contain any settings with the unknown label. + const unknownSettingLabelKey = "cattle.io/unknown" + for _, setting := range store { + assert.NotContains(t, setting.Labels, unknownSettingLabelKey) + } + + // Test when setting client's Create method fails. + cannotCreateClient := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider = settingsProvider{ + settings: cannotCreateClient, + } + cannotCreateClient.EXPECT().List(gomock.Any()).Return(new(v3.SettingList), nil).AnyTimes() + cannotCreateClient.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + cannotCreateClient.EXPECT().Create(gomock.Any()).DoAndReturn(func(setting *v3.Setting) (*v3.Setting, error) { + return nil, apierrors.NewServiceUnavailable("some error") + }).AnyTimes() + cannotCreateClient.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + + store = make(map[string]v3.Setting) + err = provider.SetAll(settingMap) + assert.NotNilf(t, err, "SetAll should return an error if setting client's Create returns an error that is IsAlreadyExists.") + + cannotUpdateClient := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider = settingsProvider{ + settings: cannotCreateClient, + } + + // Test when setting client's Update method fails. + cannotUpdateClient.EXPECT().List(gomock.Any()).Return(new(v3.SettingList), nil).AnyTimes() + cannotUpdateClient.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + cannotUpdateClient.EXPECT().Create(gomock.Any()).DoAndReturn(set).AnyTimes() + cannotUpdateClient.EXPECT().Update(gomock.Any()).DoAndReturn(func(s *v3.Setting) (*v3.Setting, error) { + return nil, apierrors.NewServiceUnavailable("some error") + }).AnyTimes() + + store = make(map[string]v3.Setting) + + err = provider.SetAll(settingMap) + assert.NotNilf(t, err, "SetAll should return an error if setting client's Update returns an error.") + + // Test when client's List method fails. + cannotListClient := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider = settingsProvider{ + settings: cannotListClient, + } + cannotListClient.EXPECT().List(gomock.Any()).DoAndReturn(func(opts metav1.ListOptions) (*v3.SettingList, error) { + return nil, apierrors.NewInternalError(errors.New("some error")) + }).Times(1) + + err = provider.SetAll(settingMap) + assert.Error(t, err, "SetAll should return an error if setting client's List returns an error.") + + // Test when setting client's Update method fails with AlreadyExists error. + alreadyExistsCreateClient := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider = settingsProvider{ + settings: alreadyExistsCreateClient, + } + + alreadyExistsCreateClient.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + alreadyExistsCreateClient.EXPECT().Create(gomock.Any()).DoAndReturn(func(setting *v3.Setting) (*v3.Setting, error) { + return nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "some error") + }).AnyTimes() + alreadyExistsCreateClient.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + alreadyExistsCreateClient.EXPECT().List(gomock.Any()).DoAndReturn(func(opts metav1.ListOptions) (*v3.SettingList, error) { + return &v3.SettingList{}, nil + }).AnyTimes() + + store = make(map[string]v3.Setting) + + err = provider.SetAll(settingMap) + assert.Nilf(t, err, "SetAll should not return an error if setting client's Create returns an AlreadyExists error."+ + " This is because it is assumed that if AlreadyExists is returned, than a different node in the setup created it.") +} + +func populateTestCases() []*testCase { + testCases := []*testCase{ + { + description: "test an existing setting with val and empty source being reconfigured with env var uses the value from env var", + envVar: pointer.String("notempty"), + newDefVal: "abc", + existingSetting: &v3.Setting{ + Value: "somethingelse", + Default: "abc", + }, + }, + { + description: "test creating a setting that doesn't exist yet creates the setting in kubernetes", + newDefVal: "abc", + }, + { + description: "test changing default of existing setting with a value properly updates the default but doesn't change value", + newDefVal: "newDef", + existingSetting: &v3.Setting{ + Value: "somethingelse", + Default: "oldDef", + }, + }, + { + description: "test changing default of existing setting without a value properly update the default and nothing else", + newDefVal: "newDef", + existingSetting: &v3.Setting{ + Default: "oldDef", + }, + }, + { + description: "test an existing setting with val and \"env\" source being reconfigured with env var updates value to the new env var value", + newDefVal: "abc", + envVar: pointer.String("notempty"), + existingSetting: &v3.Setting{ + Value: "somethingelse", + Default: "abc", + Source: "env", + }, + }, + { + description: "test a setting that doesn't exist with val and \"env\" source being configured with env var creates setting with" + + " env var value and \"env\" source", + newDefVal: "abc", + envVar: pointer.String("notempty"), + }, + { + description: "test that setting an empty string value using an environment variable works when the env var was not used prior", + newDefVal: "abc", + envVar: pointer.String(""), + existingSetting: &v3.Setting{ + Value: "somethingelse", + Default: "abc", + }, + }, + { + description: "test that setting an empty string value using an environment variable works when the env var was used prior.", + newDefVal: "abc", + envVar: pointer.String(""), + existingSetting: &v3.Setting{ + Value: "somethingelse", + Default: "abc", + Source: "env", + }, + }, + } + + for index, test := range testCases { + settingName := fmt.Sprintf("test%d", index) + newSetting := settings.NewSetting(settingName, test.newDefVal) + test.newSetting = newSetting + if test.existingSetting == nil { + continue + } + test.existingSetting.Name = settingName + } + + return testCases +} + +func TestSetAllWithDefaultOnUpgrade(t *testing.T) { + t.Skip() + t.Parallel() + t.Run("setting gets regular default on fresh install", func(t *testing.T) { + t.Parallel() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + store := make(map[string]v3.Setting) + get, set, list := storeOperations(store) + + client.EXPECT().List(gomock.Any()).DoAndReturn(list).AnyTimes() + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Create(gomock.Any()).DoAndReturn(set).AnyTimes() + + values := map[string]settings.Setting{ + "tls-agent-mode": { + Name: "tls-agent-mode", + Default: "strict", + DefaultOnUpgrade: "system-store", + }, + } + err := provider.SetAll(values) + require.NoError(t, err) + s, err := get("tls-agent-mode", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "strict", s.Default) + }) + + t.Run("setting exists and keeps its default on upgrade having the special upgrade default", func(t *testing.T) { + t.Parallel() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + store := map[string]v3.Setting{ + "tls-agent-mode": { + ObjectMeta: metav1.ObjectMeta{ + Name: "tls-agent-mode", + }, + Value: "", + Default: "system-store", + }, + } + get, set, list := storeOperations(store) + + client.EXPECT().List(gomock.Any()).DoAndReturn(list).AnyTimes() + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + + values := map[string]settings.Setting{ + "tls-agent-mode": settings.NewSetting("tls-agent-mode", "strict").WithDefaultOnUpgrade("system-store"), + } + err := provider.SetAll(values) + require.NoError(t, err) + s, err := get("tls-agent-mode", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "system-store", s.Default) + }) + + t.Run("setting exists and keeps its default on upgrade in absence of an upgrade default value", func(t *testing.T) { + t.Parallel() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + store := map[string]v3.Setting{ + "some-setting": { + ObjectMeta: metav1.ObjectMeta{ + Name: "some-setting", + }, + Default: "some-default", + }, + } + get, set, list := storeOperations(store) + + client.EXPECT().List(gomock.Any()).DoAndReturn(list).AnyTimes() + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + + values := map[string]settings.Setting{ + "some-setting": settings.NewSetting("some-setting", "some-default"), + } + err := provider.SetAll(values) + require.NoError(t, err) + s, err := get("some-setting", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "some-default", s.Default) + }) + + t.Run("setting exists and gets its new default on upgrade in absence of an upgrade default value", func(t *testing.T) { + t.Parallel() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + store := map[string]v3.Setting{ + "some-setting": { + ObjectMeta: metav1.ObjectMeta{ + Name: "some-setting", + }, + Default: "some-default", + }, + } + get, set, list := storeOperations(store) + + client.EXPECT().List(gomock.Any()).DoAndReturn(list).AnyTimes() + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Update(gomock.Any()).DoAndReturn(set).AnyTimes() + + values := map[string]settings.Setting{ + "some-setting": settings.NewSetting("some-setting", "some-new-default"), + } + err := provider.SetAll(values) + require.NoError(t, err) + s, err := get("some-setting", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "some-new-default", s.Default) + }) + + t.Run("setting does not exist and gets a special default on upgrade value on non fresh install", func(t *testing.T) { + t.Parallel() + client := fake.NewMockNonNamespacedControllerInterface[*v3.Setting, *v3.SettingList](gomock.NewController(t)) + provider := settingsProvider{ + settings: client, + } + store := map[string]v3.Setting{ + "some-setting": { + ObjectMeta: metav1.ObjectMeta{ + Name: "some-setting", + }, + Default: "some-default", + }, + } + get, set, list := storeOperations(store) + + client.EXPECT().List(gomock.Any()).DoAndReturn(list).AnyTimes() + client.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(get).AnyTimes() + client.EXPECT().Create(gomock.Any()).DoAndReturn(set).AnyTimes() + + values := map[string]settings.Setting{ + "some-setting": settings.NewSetting("some-setting", "some-default"), + "tls-agent-mode": settings.NewSetting("tls-agent-mode", "strict").WithDefaultOnUpgrade("system-store"), + } + err := provider.SetAll(values) + require.NoError(t, err) + s, err := get("tls-agent-mode", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, "system-store", s.Default) + }) +} + +func storeOperations(store map[string]v3.Setting) (get, set, list) { + get := func(name string, opts metav1.GetOptions) (*v3.Setting, error) { + val, ok := store[name] + if !ok { + return nil, apierrors.NewNotFound(schema.GroupResource{}, name) + } + return &val, nil + } + set := func(setting *v3.Setting) (*v3.Setting, error) { + store[setting.Name] = *setting + return setting, nil + } + list := func(opts metav1.ListOptions) (*v3.SettingList, error) { + items := make([]v3.Setting, 0, len(store)) + for _, setting := range store { + items = append(items, setting) + } + return &v3.SettingList{Items: items}, nil + } + return get, set, list +} + +type get func(name string, opts metav1.GetOptions) (*v3.Setting, error) +type set func(setting *v3.Setting) (*v3.Setting, error) +type list func(opts metav1.ListOptions) (*v3.SettingList, error) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/agentupgrade/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/agentupgrade/controller.go new file mode 100644 index 0000000..abe03d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/agentupgrade/controller.go @@ -0,0 +1,83 @@ +package agentupgrade + +import ( + "context" + "regexp" + + v1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + namespace = "cattle-system" +) + +var ( + names = map[string]bool{ + "cattle-cluster-agent": true, + "cattle-node-agent": true, + } + imageRegexp = regexp.MustCompile("v2\\.[0-4]\\.") +) + +type handler struct { + deployments v1.DeploymentInterface + daemonsetClient v1.DaemonSetInterface +} + +func Register(ctx context.Context, context *config.ManagementContext) { + h := &handler{ + deployments: context.Apps.Deployments(""), + daemonsetClient: context.Apps.DaemonSets(""), + } + + context.Apps.Deployments("").Controller().AddHandler(ctx, "agent-upgrade", h.OnDeploymentChange) + context.Apps.DaemonSets("").Controller().AddHandler(ctx, "agent-upgrade", h.OnDaemonSetChange) +} + +func (h *handler) OnDeploymentChange(key string, deploy *appsv1.Deployment) (runtime.Object, error) { + if deploy == nil || !shouldDelete(&deploy.ObjectMeta, &deploy.Spec.Template) { + return deploy, nil + } + return deploy, h.deployments.DeleteNamespaced(deploy.Namespace, deploy.Name, nil) +} + +func (h *handler) OnDaemonSetChange(key string, ds *appsv1.DaemonSet) (runtime.Object, error) { + if ds == nil || !shouldDelete(&ds.ObjectMeta, &ds.Spec.Template) { + return ds, nil + } + return ds, h.daemonsetClient.DeleteNamespaced(ds.Namespace, ds.Name, nil) +} + +func shouldDelete(meta *metav1.ObjectMeta, pod *corev1.PodTemplateSpec) bool { + if meta.Namespace != namespace { + return false + } + + if !names[meta.Name] { + return false + } + + if len(pod.Spec.Containers) == 0 { + return false + } + + if !imageRegexp.MatchString(pod.Spec.Containers[0].Image) { + return false + } + + for _, container := range pod.Spec.Containers { + for _, env := range container.Env { + if env.Name == "CATTLE_SERVER" && env.Value == settings.ServerURL.Get() { + return true + } + } + } + + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler.go new file mode 100644 index 0000000..91ec586 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler.go @@ -0,0 +1,462 @@ +package aks + +import ( + "context" + "encoding/base64" + stderrors "errors" + "fmt" + "net" + "net/url" + "reflect" + "time" + + "github.com/Azure/go-autorest/autorest/to" + "github.com/rancher/aks-operator/controller" + aksv1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + "github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/dialer" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" +) + +const ( + aksAPIGroup = "aks.cattle.io" + aksV1 = "aks.cattle.io/v1" + enqueueTime = time.Second * 5 +) + +type aksOperatorController struct { + clusteroperator.OperatorController + secretClient corecontrollers.SecretClient +} + +func Register(ctx context.Context, wContext *wrangler.Context, mgmtCtx *config.ManagementContext) { + aksClusterConfigResource := schema.GroupVersionResource{ + Group: aksAPIGroup, + Version: "v1", + Resource: "aksclusterconfigs", + } + + aksCCDynamicClient := mgmtCtx.DynamicClient.Resource(aksClusterConfigResource) + e := &aksOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: wContext.Mgmt.Cluster().EnqueueAfter, + SecretsCache: wContext.Core.Secret().Cache(), + Secrets: mgmtCtx.Core.Secrets(""), + TemplateCache: wContext.Mgmt.CatalogTemplate().Cache(), + ProjectCache: wContext.Mgmt.Project().Cache(), + AppLister: mgmtCtx.Project.Apps("").Controller().Lister(), + AppClient: mgmtCtx.Project.Apps(""), + NsClient: mgmtCtx.Core.Namespaces(""), + ClusterClient: wContext.Mgmt.Cluster(), + CatalogManager: mgmtCtx.CatalogManager, + SystemAccountManager: systemaccount.NewManager(mgmtCtx), + DynamicClient: aksCCDynamicClient, + ClientDialer: mgmtCtx.Dialer, + Discovery: wContext.K8s.Discovery(), + }, + secretClient: wContext.Core.Secret(), + } + + wContext.Mgmt.Cluster().OnChange(ctx, "aks-operator-controller", e.onClusterChange) +} + +func (e *aksOperatorController) onClusterChange(_ string, cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil || cluster.Spec.AKSConfig == nil { + return cluster, nil + } + + // set driver name + if cluster.Status.Driver == "" { + cluster = cluster.DeepCopy() + cluster.Status.Driver = apimgmtv3.ClusterDriverAKS + return e.ClusterClient.Update(cluster) + } + + cluster, err := e.CheckCrdReady(cluster, "aks") + if err != nil { + return cluster, err + } + + // get aks Cluster Config, if it does not exist, create it + aksClusterConfigDynamic, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Get(context.TODO(), cluster.Name, v1.GetOptions{}) + + if err != nil { + if !errors.IsNotFound(err) { + return cluster, err + } + + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "Waiting for API to be available") + if err != nil { + return cluster, err + } + + aksClusterConfigDynamic, err = buildAKSCCCreateObject(cluster) + if err != nil { + return cluster, err + } + + aksClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Create(context.TODO(), aksClusterConfigDynamic, v1.CreateOptions{}) + if err != nil { + return cluster, err + } + } + + aksClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&cluster.Spec.AKSConfig) + if err != nil { + return cluster, err + } + + // check for changes between aks spec on cluster and the aks spec on the aksClusterConfig object + if !reflect.DeepEqual(aksClusterConfigMap, aksClusterConfigDynamic.Object["spec"]) { + logrus.Infof("change detected for cluster [%s], updating AKSClusterConfig", cluster.Name) + return e.updateAKSClusterConfig(cluster, aksClusterConfigDynamic, aksClusterConfigMap) + } + + // get aks Cluster Config's phase + status, _ := aksClusterConfigDynamic.Object["status"].(map[string]interface{}) + phase, _ := status["phase"] + failureMessage, _ := status["failureMessage"].(string) + + switch phase { + case "creating": + if cluster.Status.AKSStatus.UpstreamSpec == nil { + return e.setInitialUpstreamSpec(cluster) + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster AKS [%s] to finish creating", cluster.Name) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster AKS [%s] create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + case "active": + if cluster.Status.AKSStatus.UpstreamSpec == nil { + // non imported clusters will have already had upstream spec set, unless rancher missed the "creating" phase + return e.setInitialUpstreamSpec(cluster) + } + + if cluster.Spec.AKSConfig.Imported && apimgmtv3.ClusterConditionPending.IsUnknown(cluster) { + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionPending.True(cluster) + return e.ClusterClient.Update(cluster) + } + + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + if cluster.Status.AKSStatus.RBACEnabled == nil { + enabled, ok := status["rbacEnabled"].(bool) + if ok { + cluster = cluster.DeepCopy() + cluster.Status.AKSStatus.RBACEnabled = &enabled + return e.ClusterClient.Update(cluster) + } + } + + if cluster.Status.APIEndpoint == "" { + return e.RecordCAAndAPIEndpoint(cluster) + } + + if cluster.Status.AKSStatus.PrivateRequiresTunnel == nil && + to.Bool(cluster.Status.AKSStatus.UpstreamSpec.PrivateCluster) { + // In this case, the API endpoint is private, and it has not been determined if Rancher must tunnel to communicate with it. + // Check to see if we can still use the control plane endpoint even though + // the cluster has private-only access + serviceToken, mustTunnel, err := e.generateSATokenWithPublicAPI(cluster) + if err != nil { + return cluster, err + } + if mustTunnel != nil { + cluster = cluster.DeepCopy() + cluster.Status.AKSStatus.PrivateRequiresTunnel = mustTunnel + if serviceToken != "" { + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, serviceToken, cluster) + if err != nil { + return cluster, err + } + if secret == nil { + logrus.Debugf("Empty service account token secret returned for cluster [%s]", cluster.Name) + return cluster, fmt.Errorf("failed to create or update service account token secret, secret can't be empty") + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + } + return e.ClusterClient.Update(cluster) + } + } + + if cluster.Status.ServiceAccountTokenSecret == "" { + cluster, err = e.generateAndSetServiceAccount(cluster) + if err != nil { + var statusErr error + if err == dialer.ErrAgentDisconnected { + // In this case, the API endpoint is private and rancher is waiting for the import cluster command to be run. + cluster, statusErr = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "waiting for cluster agent to be deployed") + if statusErr == nil { + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + } + return cluster, statusErr + } + cluster, statusErr = e.SetFalse(cluster, apimgmtv3.ClusterConditionWaiting, + fmt.Sprintf("failed to communicate with cluster: %v", err)) + if statusErr != nil { + return cluster, statusErr + } + return cluster, err + } + } + + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + return e.SetTrue(cluster, apimgmtv3.ClusterConditionUpdated, "") + case "updating": + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster AKS [%s] to update", cluster.Name) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + } + logrus.Infof("waiting for cluster AKS [%s] update failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionUpdated, failureMessage) + default: + if cluster.Spec.AKSConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + if cluster.Spec.AKSConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster AKS [%s] pre-create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + } +} + +func (e *aksOperatorController) setInitialUpstreamSpec(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + upstreamSpec, err := clusterupstreamrefresher.BuildAKSUpstreamSpec(e.SecretsCache, e.secretClient, cluster) + if err != nil { + return cluster, err + } + cluster = cluster.DeepCopy() + cluster.Status.AKSStatus.UpstreamSpec = upstreamSpec + return e.ClusterClient.Update(cluster) +} + +// updateAKSClusterConfig updates the AKSClusterConfig object's spec with the cluster's AKSConfig if they are not equal.. +func (e *aksOperatorController) updateAKSClusterConfig(cluster *apimgmtv3.Cluster, aksClusterConfigDynamic *unstructured.Unstructured, spec map[string]interface{}) (*apimgmtv3.Cluster, error) { + list, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).List(context.TODO(), v1.ListOptions{}) + if err != nil { + return cluster, err + } + selector := fields.OneTermEqualSelector("metadata.name", cluster.Name) + w, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Watch(context.TODO(), v1.ListOptions{ResourceVersion: list.GetResourceVersion(), FieldSelector: selector.String()}) + if err != nil { + return cluster, err + } + aksClusterConfigDynamic.Object["spec"] = spec + aksClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Update(context.TODO(), aksClusterConfigDynamic, v1.UpdateOptions{}) + if err != nil { + return cluster, err + } + + // AKS cluster and node pool statuses are not always immediately updated. This cause the AKSConfig to + // stay in "active" for a few seconds, causing the cluster to go back to "active". + timeout := time.NewTimer(10 * time.Second) + for { + select { + case event := <-w.ResultChan(): + var ok bool + if aksClusterConfigDynamic, ok = event.Object.(*unstructured.Unstructured); !ok { + return cluster, fmt.Errorf("unexpected nil cluster config") + } + status, _ := aksClusterConfigDynamic.Object["status"].(map[string]interface{}) + if status["phase"] == "active" { + continue + } + + // this enqueue is necessary to ensure that the controller is reentered with the updating phase + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + case <-timeout.C: + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + return cluster, nil + } + } +} + +// generateAndSetServiceAccount uses the API endpoint and CA cert to generate a service account token. The token is then copied to the cluster status. +func (e *aksOperatorController) generateAndSetServiceAccount(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + restConfig, err := e.getRestConfig(cluster) + if err != nil { + return cluster, fmt.Errorf("error getting kube config: %v", err) + } + + clusterDialer, err := e.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + restConfig.Dial = clusterDialer + saToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + return cluster, fmt.Errorf("error generating service account token: %v", err) + } + + cluster = cluster.DeepCopy() + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, saToken, cluster) + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return e.ClusterClient.Update(cluster) +} + +// buildAKSCCCreateObject returns an object that can be used with the kubernetes dynamic client to +// create an AKSClusterConfig that matches the spec contained in the cluster's AKSConfig. +func buildAKSCCCreateObject(cluster *apimgmtv3.Cluster) (*unstructured.Unstructured, error) { + aksClusterConfig := aksv1.AKSClusterConfig{ + TypeMeta: v1.TypeMeta{ + Kind: "AKSClusterConfig", + APIVersion: aksV1, + }, + ObjectMeta: v1.ObjectMeta{ + Name: cluster.Name, + OwnerReferences: []v1.OwnerReference{ + { + Kind: cluster.Kind, + APIVersion: rbac.RancherManagementAPIVersion, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + Spec: *cluster.Spec.AKSConfig, + } + + // convert AKS cluster config into unstructured object so it can be used with dynamic client + aksClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&aksClusterConfig) + if err != nil { + return nil, err + } + + return &unstructured.Unstructured{ + Object: aksClusterConfigMap, + }, nil +} + +// recordAppliedSpec sets the cluster's current spec as its appliedSpec +func (e *aksOperatorController) recordAppliedSpec(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if reflect.DeepEqual(cluster.Status.AppliedSpec.AKSConfig, cluster.Spec.AKSConfig) { + return cluster, nil + } + + cluster = cluster.DeepCopy() + cluster.Status.AppliedSpec.AKSConfig = cluster.Spec.AKSConfig + return e.ClusterClient.Update(cluster) +} + +// generateSATokenWithPublicAPI tries to get a service account token from the cluster using the public API endpoint. +// This function is called if the cluster has only privateEndpoint enabled and is not publicly available. +// If Rancher is able to communicate with the cluster through its API endpoint even though it is private, then this function will retrieve +// a service account token and the *bool returned will refer to a false value (doesn't have to tunnel). +// +// If the Rancher server cannot connect to the cluster's API endpoint, then one of the two errors below will happen. +// In this case, we know that Rancher must use the cluster agent tunnel for communication. This function will return an empty service account token, +// and the *bool return value will refer to a true value (must tunnel). +// +// If an error different from the two below occur, then the *bool return value will be nil, indicating that Rancher was not able to determine if +// tunneling is required to communicate with the cluster. +func (e *aksOperatorController) generateSATokenWithPublicAPI(cluster *apimgmtv3.Cluster) (string, *bool, error) { + restConfig, err := e.getRestConfig(cluster) + if err != nil { + return "", nil, err + } + + requiresTunnel := new(bool) + restConfig.Dial = (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext + serviceToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + *requiresTunnel = true + var dnsError *net.DNSError + if stderrors.As(err, &dnsError) && !dnsError.IsTemporary { + return "", requiresTunnel, nil + } + + // In the existence of a proxy, it may be the case that the following error occurs, + // in which case rancher should use the tunnel connection to communicate with the cluster. + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + + // Not able to determine if tunneling is required. + requiresTunnel = nil + } + + return serviceToken, requiresTunnel, err +} + +func (e *aksOperatorController) getRestConfig(cluster *apimgmtv3.Cluster) (*rest.Config, error) { + ctx := context.Background() + restConfig, err := controller.GetClusterKubeConfig(ctx, e.SecretsCache, e.secretClient, cluster.Spec.AKSConfig) + if err != nil { + return nil, err + } + + // Get the CACert from the cluster because it will have any additional CAs added to Rancher. + certFromCluster, err := base64.StdEncoding.DecodeString(cluster.Status.CACert) + if err != nil { + return nil, err + } + + restConfig.CAData = certFromCluster + return restConfig, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_interface_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_interface_test.go new file mode 100644 index 0000000..0233d33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_interface_test.go @@ -0,0 +1,613 @@ +package aks + +import ( + "context" + "net" + + openapi2 "github.com/google/gnostic-models/openapiv2" + "github.com/rancher/rancher/pkg/types/config/dialer" + meta1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/version" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/openapi" + "k8s.io/client-go/rest" +) + +const ( + MockDefaultAKSClusterConfigFilename = "test/onclusterchange_akscc_default.json" + MockCreateAKSClusterConfigFilename = "test/onclusterchange_akscc_create.json" + MockActiveAKSClusterConfigFilename = "test/onclusterchange_akscc_active.json" + MockUpdateAKSClusterConfigFilename = "test/onclusterchange_akscc_update.json" + MockAKSClusterConfigUpdatedFilename = "test/updateaksclusterconfig_updated.json" +) + +// mock interfaces + +// mock dynamic client (to return a mock AKSClusterConfig) + +// Test 1 - cluster in default/unknown state. Get will return an AKSClusterConfig with an unknown provisioning phase. +// The rest of the method signatures have to be implemented to mock the interface. There will be one mock of this +// interface for each test. + +type MockNamespaceableResourceInterfaceDefault struct{} + +func (m MockNamespaceableResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceDefault{} +} + +func (m MockNamespaceableResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceDefault struct{} + +func (m MockResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockDefaultAKSClusterConfigFilename) +} + +func (m MockResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 2 - cluster in creating state + +type MockNamespaceableResourceInterfaceCreate struct{} + +func (m MockNamespaceableResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceCreate{} +} + +func (m MockNamespaceableResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceCreate struct{} + +func (m MockResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockCreateAKSClusterConfigFilename) +} + +func (m MockResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 3 - cluster in active state + +type MockNamespaceableResourceInterfaceActive struct{} + +func (m MockNamespaceableResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceActive{} +} + +func (m MockNamespaceableResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceActive struct{} + +func (m MockResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockActiveAKSClusterConfigFilename) +} + +func (m MockResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 4 - cluster in update node pool state + +type MockNamespaceableResourceInterfaceUpdate struct{} + +func (m MockNamespaceableResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceUpdate{} +} + +func (m MockNamespaceableResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceUpdate struct{} + +func (m MockResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockUpdateAKSClusterConfigFilename) +} + +func (m MockResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test UpdateAKSClusterConfig + +type MockNamespaceableResourceInterfaceAKSCC struct{} + +func (m MockNamespaceableResourceInterfaceAKSCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceAKSCC{} +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceAKSCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceAKSCC struct{} + +func (m MockResourceInterfaceAKSCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + // TODO implement m + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockAKSClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceAKSCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceAKSCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockAksClusterConfig(MockAKSClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceAKSCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return &unstructured.UnstructuredList{ + Object: map[string]interface{}{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfigList", + "metadata": map[string]interface{}{"resourceVersion": "142650"}, + }, + Items: nil, + }, nil +} + +// mock interface that returns a watch event (for updateAKSClusterConfig test) + +type MockInterface struct{} + +func (m MockInterface) Stop() {} + +func (m MockInterface) ResultChan() <-chan watch.Event { + return make(chan watch.Event) +} + +func (m MockResourceInterfaceAKSCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return MockInterface{}, nil +} + +func (m MockResourceInterfaceAKSCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// mock cluster dialer + +type MockFactory struct{} + +func (m MockFactory) ClusterDialer(clusterName string, retryOnError bool) (dialer.Dialer, error) { + // pass a dialer func to the client + dialer := func(ctx context.Context, network, address string) (net.Conn, error) { + return nil, nil + } + return dialer, nil +} + +func (m MockFactory) DockerDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +func (m MockFactory) NodeDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +type Dialer func(ctx context.Context, network, address string) (net.Conn, error) + +// mock discovery + +type MockDiscovery struct{} + +func (m MockDiscovery) RESTClient() rest.Interface { + panic("implement me") +} + +func (m MockDiscovery) ServerGroups() (*meta1.APIGroupList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*meta1.APIResourceList, error) { + + return &meta1.APIResourceList{ + TypeMeta: meta1.TypeMeta{}, + GroupVersion: "", + APIResources: []meta1.APIResource{ + {Name: "AKSClusterConfig"}, + {Name: "status"}}, + }, nil +} + +func (m MockDiscovery) ServerGroupsAndResources() ([]*meta1.APIGroup, []*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredNamespacedResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerVersion() (*version.Info, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPISchema() (*openapi2.Document, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPIV3() openapi.Client { + panic("implement me") +} + +func (m MockDiscovery) WithLegacy() discovery.DiscoveryInterface { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_test.go new file mode 100644 index 0000000..18a799a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_mockc_test.go @@ -0,0 +1,222 @@ +//nolint:all // this file was originally generated by github.com/kelveny/mockcompose +package aks + +import ( + "embed" + "encoding/json" + stderrors "errors" + "fmt" + "net" + "net/url" + "testing" + "time" + + "github.com/ghodss/yaml" + "github.com/golang/mock/gomock" + v1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + secretv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +//go:embed test/* +var testFs embed.FS + +type mockAksOperatorController struct { + aksOperatorController + mock.Mock +} + +func getMockAksOperatorController(t *testing.T, clusterState string) mockAksOperatorController { + t.Helper() + ctrl := gomock.NewController(t) + clusterMock := fake.NewMockNonNamespacedClientInterface[*apisv3.Cluster, *apisv3.ClusterList](ctrl) + clusterMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(c *apisv3.Cluster) (*apisv3.Cluster, error) { + return c, nil + }, + ).AnyTimes() + var dynamicClient dynamic.NamespaceableResourceInterface + + switch clusterState { + case "default": + dynamicClient = MockNamespaceableResourceInterfaceDefault{} + case "create": + dynamicClient = MockNamespaceableResourceInterfaceCreate{} + case "active": + dynamicClient = MockNamespaceableResourceInterfaceActive{} + case "update": + dynamicClient = MockNamespaceableResourceInterfaceUpdate{} + case "akscc": + dynamicClient = MockNamespaceableResourceInterfaceAKSCC{} + default: + dynamicClient = nil + } + + return mockAksOperatorController{ + aksOperatorController: aksOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: func(name string, duration time.Duration) {}, + SecretsCache: nil, + Secrets: nil, + TemplateCache: nil, + ProjectCache: nil, + AppLister: nil, + AppClient: nil, + NsClient: nil, + ClusterClient: clusterMock, + CatalogManager: nil, + SystemAccountManager: nil, + DynamicClient: dynamicClient, + ClientDialer: MockFactory{}, + Discovery: MockDiscovery{}, + }, + secretClient: nil, + }, + Mock: mock.Mock{}, + } +} + +// test setInitialUpstreamSpec + +func (m *mockAksOperatorController) setInitialUpstreamSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + + // mock + upstreamSpec := &v1.AKSClusterConfigSpec{} + + cluster = cluster.DeepCopy() + cluster.Status.AKSStatus.UpstreamSpec = upstreamSpec + return m.ClusterClient.Update(cluster) +} + +// test generateAndSetServiceAccount with mock sibling func (getRestConfig) + +func (m *mockAksOperatorController) generateAndSetServiceAccount(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + restConfig, err := m.getRestConfig(cluster) + if err != nil { + return cluster, fmt.Errorf("error getting kube config: %v", err) + } + + clusterDialer, err := m.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + restConfig.Dial = clusterDialer + cluster = cluster.DeepCopy() + + // mock + secret := secretv1.Secret{} + secret.Name = "cluster-serviceaccounttoken-sl7wm" + + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return m.ClusterClient.Update(cluster) +} + +// test generateSATokenWithPublicAPI with mock sibling func (getRestConfig) + +func (m *mockAksOperatorController) generateSATokenWithPublicAPI(cluster *mgmtv3.Cluster) (string, *bool, error) { + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + restConfig, err := m.getRestConfig(cluster) + if err != nil { + return "", nil, err + } + requiresTunnel := new(bool) + restConfig.Dial = (&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext + + // mock serviceToken + serviceToken, err := "testtoken12345", nil + + if err != nil { + *requiresTunnel = true + var dnsError *net.DNSError + if stderrors.As(err, &dnsError) && !dnsError.IsTemporary { + return "", requiresTunnel, nil + } + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + requiresTunnel = nil + } + return serviceToken, requiresTunnel, err +} + +func (m *mockAksOperatorController) getRestConfig(cluster *mgmtv3.Cluster) (*rest.Config, error) { + + _mc_ret := m.Called(cluster) + + var _r0 *rest.Config + + if _rfn, ok := _mc_ret.Get(0).(func(*mgmtv3.Cluster) *rest.Config); ok { + _r0 = _rfn(cluster) + } else { + if _mc_ret.Get(0) != nil { + _r0 = _mc_ret.Get(0).(*rest.Config) + } + } + + var _r1 error + + if _rfn, ok := _mc_ret.Get(1).(func(*mgmtv3.Cluster) error); ok { + _r1 = _rfn(cluster) + } else { + _r1 = _mc_ret.Error(1) + } + + return _r0, _r1 + +} + +// utility + +func getMockV3Cluster(filename string) (mgmtv3.Cluster, error) { + var mockCluster mgmtv3.Cluster + + // Read the embedded file + cluster, err := testFs.ReadFile(filename) + if err != nil { + return mockCluster, err + } + // Unmarshal cluster yaml into a management v3 cluster object + err = yaml.Unmarshal(cluster, &mockCluster) + if err != nil { + return mockCluster, err + } + + return mockCluster, nil +} + +func getMockAksClusterConfig(filename string) (*unstructured.Unstructured, error) { + var aksClusterConfig *unstructured.Unstructured + + // Read the embedded file + bytes, err := testFs.ReadFile(filename) + if err != nil { + return aksClusterConfig, err + } + // Unmarshal json into an unstructured cluster config object + err = json.Unmarshal(bytes, &aksClusterConfig) + if err != nil { + return aksClusterConfig, err + } + + return aksClusterConfig, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_test.go new file mode 100644 index 0000000..516b50a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/aks_cluster_handler_test.go @@ -0,0 +1,288 @@ +package aks + +import ( + "reflect" + "testing" + + "github.com/Azure/go-autorest/autorest/to" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/capr" +) + +const ( + MockDefaultClusterFilename = "test/onclusterchange_default.yaml" + MockCreateClusterFilename = "test/onclusterchange_create.yaml" + MockActiveClusterFilename = "test/onclusterchange_active.yaml" + MockUpdateClusterFilename = "test/onclusterchange_update.yaml" + MockAksClusterConfigFilename = "test/updateaksclusterconfig.json" + MockAksClusterConfigClusterFilename = "test/updateaksclusterconfig.yaml" + MockBuildAksCCCreateObjectFilename = "test/buildakscccreateobject.json" +) + +var mockOperatorController mockAksOperatorController // Operator controller with mock interfaces & sibling funcs + +/* +* Test_onClusterChange +- cluster == nil. Return (nil nil) +- cluster.DeletionTimestamp or cluster.AKSConfig == nil, return (nil nil) +- default phase +- create phase +- active phase +- update node pool phase +*/ +func Test_onClusterChange_ClusterIsNil(t *testing.T) { + cluster, _ := mockOperatorController.onClusterChange("", nil) + if cluster != nil { + t.Errorf("cluster should have returned nil") + } +} + +func Test_onClusterChange_AKSConfigIsNil(t *testing.T) { + mockCluster := &v3.Cluster{ + Spec: v3.ClusterSpec{ + AKSConfig: nil, + }, + } + + cluster, _ := mockOperatorController.onClusterChange("", mockCluster) + if !reflect.DeepEqual(cluster, mockCluster) { + t.Errorf("cluster should have returned with no update") + } +} + +func Test_onClusterChange_Default(t *testing.T) { + + // setup + // create an instance of the operator controller with mock data to simulate the onChangeCluster function reacting + // to a real cluster! + mockOperatorController = getMockAksOperatorController(t, "default") + + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + // run test + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // validate results + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Create(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Active(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsTrue(cluster) { + t.Errorf("provisioned and updated status should be True and cluster returned successfully") + } +} + +func Test_onClusterChange_UpdateNodePool(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "update") + mockCluster, err := getMockV3Cluster(MockUpdateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // check that cluster is updating node pool + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsUnknown(cluster) { + t.Errorf("provisioned status should be True, updated status should be Unknown and cluster returned successfully") + } +} + +/* +* Test_setInitialUpstreamSpec +- success: buildUpstreamClusterState returns a valid upstream spec +*/ +func Test_setInitialUpstreamSpec(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.setInitialUpstreamSpec(&mockCluster) + + if err != nil { + t.Errorf("error running setInitialUpstreamSpec: %s", err) + } + if cluster.Status.AKSStatus.UpstreamSpec == nil { + t.Errorf("upstreamSpec should have been set and cluster returned successfully") + } +} + +/* +* Test_updateAksClusterConfig + - success: AKS cluster tags are removed. AKS cluster is not immediately updated. Cluster sits in active for a few + seconds, return (cluster nil) +*/ +func Test_updateAKSClusterConfig(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "akscc") + mockCluster, err := getMockV3Cluster(MockAksClusterConfigClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + mockAksClusterConfig, err := getMockAksClusterConfig(MockAksClusterConfigFilename) + + // test remove tags from the cluster + _, err = mockOperatorController.updateAKSClusterConfig(&mockCluster, mockAksClusterConfig, nil) + + if err != nil { + t.Errorf("error running updateAKSClusterConfig: %s", err) + } +} + +/* +* Test_generateAndSetServiceAccount +- success: service account token generated, cluster updated! Return updated cluster.Status +- error generating service account token. Return (cluster, err) +*/ +func Test_generateAndSetServiceAccount(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.generateAndSetServiceAccount(&mockCluster) + + // check that serviceAccountToken name and token are set + if err != nil { + t.Errorf("error running generateAndSetServiceAccount: %s", err) + } + if cluster.Status.ServiceAccountTokenSecret == "" { + t.Errorf("service account token secret should have been set on Status and cluster returned successfully") + } +} + +/* +* Test_buildAKSCCCreateObject +- success: AKSClusterConfig object created, return (AKSClusterConfig nil) +*/ +func Test_buildAKSCCCreateObject(t *testing.T) { + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + expected, err := getMockAksClusterConfig(MockBuildAksCCCreateObjectFilename) + + akscc, err := buildAKSCCCreateObject(&mockCluster) + + if err != nil { + t.Errorf("error running buildAKSCCCreateObject: %s", err) + } + if !reflect.DeepEqual(akscc, expected) { + t.Errorf("AKSClusterConfig object was not built as expected") + } +} + +/* +* Test_recordAppliedSpec +- success: set current spec as applied spec. Return (updated cluster err) +- success: AKSConfig and Applied Spec AKSConfig are equal. Return (cluster nil) +*/ +func Test_recordAppliedSpec_Updated(t *testing.T) { + // We use a mock cluster that is still provisioning and in an Unknown state, because that is when the applied spec + // needs to be updated. + mockOperatorController = getMockAksOperatorController(t, "default") + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if cluster.Status.AppliedSpec.AKSConfig == nil { + t.Errorf("cluster Status.AppliedSpec should have been updated with AKSConfig") + } +} + +func Test_recordAppliedSpec_NoUpdate(t *testing.T) { + // A mock active cluster already has the AKSConfig set on the applied spec, so no update is required. + mockOperatorController = getMockAksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if !reflect.DeepEqual(cluster.Status.AppliedSpec, mockCluster.Status.AppliedSpec) { + t.Errorf("cluster Status.AppliedSpec should have no update and cluster returned successfully") + } +} + +/* + - Test_generateSATokenWithPublicAPI + PRIVATE CLUSTER ONLY + - success in getting a service account token from the public API endpoint. Return (token mustTunnel=false nil) + - failure to get service account token. Return ("" mustTunnel=true err) + - unknown error. Return ("" mustTunnel=nil err) +*/ +func Test_generateSATokenWithPublicAPI(t *testing.T) { + mockOperatorController = getMockAksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + input := mockCluster.DeepCopy() + isPrivate := true + input.Status.AKSStatus.UpstreamSpec.PrivateCluster = &isPrivate + + token, requiresTunnel, err := mockOperatorController.generateSATokenWithPublicAPI(input) + + if err != nil { + t.Errorf("error running generateSATokenWithPublicAPI: %s", err) + } + if token == "" || to.Bool(requiresTunnel) != false { + t.Errorf("values (token, requiresTunnel=false, nil) should have been returned successfully") + } +} + +/** Test_getRestConfig + */ +func Test_getRestConfig(t *testing.T) { + t.Skip("not implemented: requires AKS controller") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/buildakscccreateobject.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/buildakscccreateobject.json new file mode 100644 index 0000000..34e1aa2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/buildakscccreateobject.json @@ -0,0 +1,73 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "metadata": { + "creationTimestamp": null, + "name": "c-k4mnv", + "ownerReferences": [ + { + "apiVersion": "management.cattle.io/v3", + "kind": "Cluster", + "name": "c-k4mnv", + "uid": "75f1abf6-dab3-40d4-a0a5-bf9df4e42271" + } + ] + }, + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-26b5h", + "baseUrl": null, + "clusterName": "aks-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "enableAutoScaling": false, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": {}, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "", + "rbacEnabled": null + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_active.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_active.yaml new file mode 100644 index 0000000..8fe45cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_active.yaml @@ -0,0 +1,139 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-26b5h + baseUrl: null + clusterName: aks-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + enableAutoScaling: false + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: {} + virtualNetwork: null + virtualNetworkResourceGroup: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: aks-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + aksStatus: + upstreamSpec: + privateCluster: false + appliedSpec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-26b5h + baseUrl: null + clusterName: aks-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + enableAutoScaling: false + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: {} + virtualNetwork: null + virtualNetworkResourceGroup: null + outboundType: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + conditions: + - lastUpdateTime: "2022-08-08T10:54:05-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-08T10:54:16-04:00" + status: "True" + type: Updated + driver: AKS diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_active.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_active.json new file mode 100644 index 0000000..2d9ac0b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_active.json @@ -0,0 +1,61 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-26b5h", + "baseUrl": null, + "clusterName": "aks-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "enableAutoScaling": false, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": {}, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "active", + "rbacEnabled": true + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_create.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_create.json new file mode 100644 index 0000000..7248b97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_create.json @@ -0,0 +1,61 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-26b5h", + "baseUrl": null, + "clusterName": "aks-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "enableAutoScaling": false, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": {}, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "creating", + "rbacEnabled": null + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_default.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_default.json new file mode 100644 index 0000000..ae2c728 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_default.json @@ -0,0 +1,56 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-26b5h", + "baseUrl": null, + "clusterName": "aks-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "enableAutoScaling": false, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": {}, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_update.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_update.json new file mode 100644 index 0000000..b79996f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_akscc_update.json @@ -0,0 +1,86 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-26b5h", + "baseUrl": null, + "clusterName": "aks-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + }, + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "enableAutoScaling": false, + "maxPods": 110, + "mode": "User", + "name": "agentpool2", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": { + "Cost Center": "000000000", + "Department": "test", + "Environment": "test", + "Finance Business Partner": "financebusinesspartner@suse.com", + "General Ledger Code": "000000000", + "Group": "test", + "Owner": "owner@suse.com", + "Stakeholder": "stakeholder@suse.com" + }, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "updating", + "rbacEnabled": true + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_create.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_create.yaml new file mode 100644 index 0000000..87a8f55 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_create.yaml @@ -0,0 +1,75 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-26b5h + baseUrl: null + clusterName: aks-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + enableAutoScaling: false + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: {} + virtualNetwork: null + virtualNetworkResourceGroup: null + outboundType: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: aks-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + aksStatus: + upstreamSpec: + testfield: "upstream spec is already set" + conditions: + - lastUpdateTime: "2022-08-08T10:42:00-04:00" + status: Unknown + type: Provisioned + driver: AKS diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_default.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_default.yaml new file mode 100644 index 0000000..ad70828 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_default.yaml @@ -0,0 +1,95 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +metadata: + annotations: + authz.management.cattle.io/creator-role-bindings: '{"created":["cluster-owner"],"required":["cluster-owner"]}' + field.cattle.io/creatorId: user-lgw7g + lifecycle.cattle.io/create.cluster-agent-controller-cleanup: "true" + lifecycle.cattle.io/create.cluster-provisioner-controller: "true" + lifecycle.cattle.io/create.cluster-scoped-gc: "true" + lifecycle.cattle.io/create.mgmt-cluster-rbac-remove: "true" + creationTimestamp: "2022-08-08T14:26:21Z" + finalizers: + - wrangler.cattle.io/mgmt-cluster-remove + - controller.cattle.io/cluster-agent-controller-cleanup + - controller.cattle.io/cluster-scoped-gc + - controller.cattle.io/cluster-provisioner-controller + - controller.cattle.io/mgmt-cluster-rbac-remove + generateName: c- + generation: 13 + labels: + cattle.io/creator: norman + name: c-k4mnv + resourceVersion: "9822" + uid: 75f1abf6-dab3-40d4-a0a5-bf9df4e42271 +spec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-26b5h + baseUrl: null + clusterName: aks-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + enableAutoScaling: false + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: {} + virtualNetwork: null + virtualNetworkResourceGroup: null + outboundType: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: aks-monday + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-08T10:26:25-04:00" + message: Waiting on aks crd to be initialized + status: Unknown + type: Provisioned + driver: AKS diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_update.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_update.yaml new file mode 100644 index 0000000..0ac7a34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/onclusterchange_update.yaml @@ -0,0 +1,96 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-26b5h + baseUrl: null + clusterName: aks-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + enableAutoScaling: false + maxPods: 110 + mode: User + name: agentpool2 + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: + Cost Center: "000000000" + Department: test + Environment: test + Finance Business Partner: financebusinesspartner@suse.com + General Ledger Code: "000000000" + Group: test + Owner: owner@suse.com + Stakeholder: stakeholder@suse.com + virtualNetwork: null + virtualNetworkResourceGroup: null + outboundType: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: aks-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-08T10:54:05-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-08T11:05:13-04:00" + status: Unknown + type: Updated + driver: AKS diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.json new file mode 100644 index 0000000..361cb7d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.json @@ -0,0 +1,69 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-swhf7", + "baseUrl": null, + "clusterName": "aks-clusterconfig-test", + "dnsPrefix": "aks-dns-prefix", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": { + "Cost Center": "000000000", + "Department": "test", + "Environment": "test", + "Finance Business Partner": "financebusinesspartner@suse.com", + "General Ledger Code": "000000000", + "Group": "test", + "Owner": "owner@suse.com", + "Stakeholder": "stakeholder@suse.com" + }, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "active", + "rbacEnabled": true + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.yaml new file mode 100644 index 0000000..4b60233 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig.yaml @@ -0,0 +1,297 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-swhf7 + baseUrl: null + clusterName: aks-clusterconfig-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: null + virtualNetwork: null + virtualNetworkResourceGroup: null + outboundType: null + managedIdentity: null + userAssignedIdentity: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: aks-clusterconfig-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + agentFeatures: + embedded-cluster-api: false + fleet: false + monitoringv1: false + multi-cluster-management: false + multi-cluster-management-agent: true + provisioningv2: false + rke2: false + agentImage: rancher/rancher-agent:v2.6-head + aksStatus: + privateRequiresTunnel: null + rbacEnabled: true + upstreamSpec: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-swhf7 + baseUrl: null + clusterName: aks-clusterconfig-test + dnsPrefix: aks-dns-prefix + dnsServiceIp: 10.0.0.10 + dockerBridgeCidr: 172.17.0.1/16 + httpApplicationRouting: false + imported: false + kubernetesVersion: 1.23.8 + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: "" + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: 10.244.0.0/16 + privateCluster: false + privateDnsZone: null + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: 10.0.0.0/16 + subnet: null + tags: + Cost Center: "000000000" + Department: test + Environment: test + Finance Business Partner: financebusinesspartner@suse.com + General Ledger Code: "000000000" + Group: test + Owner: owner@suse.com + Stakeholder: stakeholder@suse.com + virtualNetwork: null + virtualNetworkResourceGroup: null + managedIdentity: null + userAssignedIdentity: null + allocatable: + cpu: 1900m + memory: 4670932Ki + pods: "110" + apiEndpoint: https://aks-dns-88999-dc3103d7.hcp.eastus.azmk8s.io:443 + appliedAgentEnvVars: + - name: CATTLE_SERVER_VERSION + value: dev + - name: CATTLE_INSTALL_UUID + value: 3573e14c-efce-425e-ae8a-7ddc80578c5e + - name: CATTLE_INGRESS_IP_DOMAIN + value: sslip.io + appliedEnableNetworkPolicy: false + appliedPodSecurityPolicyTemplateId: "" + appliedSpec: + agentImageOverride: "" + aksConfig: + authBaseUrl: null + authorizedIpRanges: null + azureCredentialSecret: cattle-global-data:cc-swhf7 + baseUrl: null + clusterName: aks-clusterconfig-test + dnsPrefix: aks-dns-88999 + dnsServiceIp: null + dockerBridgeCidr: null + httpApplicationRouting: null + imported: false + kubernetesVersion: 1.23.8 + linuxAdminUsername: azureuser + loadBalancerSku: Standard + logAnalyticsWorkspaceGroup: null + logAnalyticsWorkspaceName: null + monitoring: null + networkPlugin: kubenet + networkPolicy: null + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + count: 1 + maxPods: 110 + mode: System + name: agentpool + orchestratorVersion: 1.23.8 + osDiskSizeGB: 128 + osDiskType: Managed + osType: Linux + vmSize: Standard_DS2_v2 + podCidr: null + privateCluster: false + resourceGroup: aks-resource-group + resourceLocation: eastus + serviceCidr: null + subnet: null + tags: + Cost Center: "211699999" + Department: ecm + Environment: test + Finance Business Partner: geoff.guest@suse.com + General Ledger Code: "200000119" + Group: container-platform + Owner: denise.schannon@suse.com + Stakeholder: jeff.hobbs@suse.com + virtualNetwork: null + virtualNetworkResourceGroup: null + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + authImage: "" + caCert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU2VENDQXRHZ0F3SUJBZ0lSQUxxam1hblFSOUJXWmpxWlhsMDhDOHN3RFFZSktvWklodmNOQVFFTEJRQXcKRFRFTE1Ba0dBMVVFQXhNQ1kyRXdJQmNOTWpJd09EQTVNVEl6T1RBM1doZ1BNakExTWpBNE1Ea3hNalE1TURkYQpNQTB4Q3pBSkJnTlZCQU1UQW1OaE1JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBCnZmeEFzNCtqZzYwOFJTSzhqUlJ4R1NiM0U5eWU2UU9QNmFiUGdGcTcxUFZuUUtFZEwzR1hZS2xyWHJkU0dET2YKc0FWRElMNHB6ZzF0Yml3bGlOWjM2WHBPVllRR1lYTDgvZUcxOXQwd0lkTDRXTFZ5bHZBalFkcVQvOTFPRG9SQQo3T1NESTNsbm1GakF6VFpWMVVOcFZIa0FmQjJBeks0T2RiQ1MvSm1VSlE0ZWFlR1pKaG1sRHFENlkzdXMrcGg3CkkxMnVYd3ZEdUpkSE05Z09pL2NDb0VVUWNlNlpQVEx2UmVNZkpCNWJiejJiSmx2cHdURWVhWFIxQWYvT0pobHIKNlZaazg5cG1xQlIrM1phaHJNTTFjU3ZnOURwUFlxN0lKUVVEc3JXV2RJTGdzajJiR21iUzhOeXZjOUtsQ0crVgpib0pKaW9kdjY4Rk4yZUpHVlNSWFpRRS83elBsWjZDTlBmdTVrTk9wL05KcFJNRGlNMTRrNFkya2FjYk0weGtyCmxSSGRyaXY1QUYyNFlDcU53N082cmtEVVJDcVYwcVROMWpJNXYvK1J4M2pkaXduOGthN2wvVDdoS09lTGxQT2oKdlFzMU9XdHRzcXlQZ1o3emE1Yjg0RWc5dHdjYnd5TTVWMHd5OTRiWjBPMklhazl1eDhRbVhvaTNsbi9sS0JkaApHajhtQVRpcmJnVHBEVUdXTnB6SzlndUlNS1llYVlxR3V6NnRuS3NXOUYrZE42QTJFTjZlOXExTDRQNHVBSmxDCllPbi9BUUxaMUpZRjVaZ3Zvc2xIclNKVmhvaWxEMXk2U0F1WjlVanpyemVISjI3MWxXZ0JOay9Tb2d1NzVjbWgKN0JXNFVIQzVxOHYzUDBKOVZnc1ZRK0lGQldGbmxkcXU2Qm0wRzMrR3VuOENBd0VBQWFOQ01FQXdEZ1lEVlIwUApBUUgvQkFRREFnS2tNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdIUVlEVlIwT0JCWUVGRUg3OTI5SGtlbVdCM3F2ClFTazdEV2RUcnFUYk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQ0ljTy9sbWVra2E5S3RHTGZTK0xvVmNtTC8KelFqRnNnNTZZN3UxV0VzMXhjK3ZQTjlrMnJoTHFkSE1QT2h2ZU1na0gvUC9DL2c3WUpsc0hHTkRiYUI2N0htbwpXOGcwdEpQYzFmRlh3UDQwQzBCSnp4TVN0N0NsV3IvMWVsZktVck1kblZNMG42L3p5alpKdTZpV24yYWkxUjdnCkFHL1BkWUJ1OXRPZlhEZ1Q4QStnalhJd1lQVW8raFFqRUlMQWJxaEo1RFcvaXMzVDNrYUpuWUMydFI5OWJqdVUKZ3dFbytqdFB5WElxUmZiOUJTQVRldmpnREhvc3FvVUIyNlcvUmMxTzYxR0YyWmJ1RWcxdC9Nc3orT2MzTWdkMQpWdUEzcnVPamsrNXArNmtxVnZHQWFERUpld3A1dUFUbGJlZUQwNCtWUE5qcjNuZUtjcG1tT25EMCtCVXZmRFh0ClNxYVFocmVnc0RyUXpQMGhaWFZ2NkNnTFA5TmR3TC93UFMyMnd1MHVWVTlhelVQT3dCenpPN3pOTEw0NVpnQ1kKVmlkQUZlVFBpajZoRWNiN2V2UG1TR1A1ellNNnYxcHJWV0R6bmZGcHo3dUltV1ZQZWk3TW1ZRU9rTHRQaUl5ZApnRDBaOWRqUmVRc0szUnpBaGJuZ0xNRW45Mm9GNUp1U2lUdmMyeFJFREN1QWcwT0x4YVBkNG9XUlAvQnUzb0o3CjJGVEw2M1VLN0tDSVQrY1FPSGVUMVZta1FPM3dpVVUzUzZBNkFIc09PSVpUZkJnUWNvNC9uWTdTOXlyZnp1aisKUEhJUzlHdXczaVJTY2FNdXFLdlJESGEycVNDZkJlOWMzRWUrSGJDTTRQVHVSYnh4eDNOU0JXVmJXSzhNMnl4Swp4dFNEaS9JbUtOVVpKOWlYbkE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + capabilities: + loadBalancerCapabilities: {} + capacity: + cpu: "2" + memory: 7116244Ki + pods: "110" + conditions: + - status: "True" + type: Pending + - lastUpdateTime: "2022-08-09T08:52:47-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-09T08:48:00-04:00" + message: Waiting for API to be available + status: Unknown + type: Waiting + - lastUpdateTime: "2022-08-09T08:47:52-04:00" + status: "True" + type: BackingNamespaceCreated + - lastUpdateTime: "2022-08-09T08:47:52-04:00" + status: "True" + type: DefaultProjectCreated + - lastUpdateTime: "2022-08-09T08:47:53-04:00" + status: "True" + type: SystemProjectCreated + - lastUpdateTime: "2022-08-09T08:47:53-04:00" + status: "True" + type: InitialRolesPopulated + - lastUpdateTime: "2022-08-09T08:47:56-04:00" + status: "True" + type: CreatorMadeOwner + - lastUpdateTime: "2022-08-09T08:47:57-04:00" + status: "True" + type: NoDiskPressure + - lastUpdateTime: "2022-08-09T08:47:57-04:00" + status: "True" + type: NoMemoryPressure + - lastUpdateTime: "2022-08-09T08:47:57-04:00" + status: "True" + type: SecretsMigrated + - lastUpdateTime: "2022-08-09T08:47:57-04:00" + status: "True" + type: ServiceAccountSecretsMigrated + - lastUpdateTime: "2022-08-09T12:48:04Z" + status: "False" + type: Connected + - lastUpdateTime: "2022-08-09T08:52:48-04:00" + message: Cluster agent is not connected + reason: Disconnected + status: "False" + type: Ready + - lastUpdateTime: "2022-08-09T08:52:52-04:00" + status: "True" + type: Updated + - lastUpdateTime: "2022-08-09T08:53:04-04:00" + status: "True" + type: GlobalAdminsSynced + - lastUpdateTime: "2022-08-09T08:53:04-04:00" + status: "True" + type: SystemAccountCreated + - lastUpdateTime: "2022-08-09T08:53:09-04:00" + status: "True" + type: AgentDeployed + driver: AKS + limits: + cpu: "0" + memory: "0" + pods: "0" + linuxWorkerCount: 1 + nodeCount: 1 + provider: "" + requested: + cpu: "0" + memory: "0" + pods: "0" + serviceAccountTokenSecret: cluster-serviceaccounttoken-cjgqx + version: + buildDate: "2022-06-21T17:15:16Z" + compiler: gc + gitCommit: bd30c9fbc8dc9668d7ab4b0bd4fdab5c929c1ad7 + gitTreeState: clean + gitVersion: v1.23.8 + goVersion: go1.17.11 + major: "1" + minor: "23" + platform: linux/amd64 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig_updated.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig_updated.json new file mode 100644 index 0000000..594e885 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/aks/test/updateaksclusterconfig_updated.json @@ -0,0 +1,62 @@ +{ + "apiVersion": "aks.cattle.io/v1", + "kind": "AKSClusterConfig", + "spec": { + "authBaseUrl": null, + "authorizedIpRanges": null, + "azureCredentialSecret": "cattle-global-data:cc-swhf7", + "baseUrl": null, + "clusterName": "aks-clusterconfig-test", + "dnsPrefix": "aks-dns-88999", + "dnsServiceIp": null, + "dockerBridgeCidr": null, + "httpApplicationRouting": null, + "imported": false, + "kubernetesVersion": "1.23.8", + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "logAnalyticsWorkspaceGroup": null, + "logAnalyticsWorkspaceName": null, + "monitoring": null, + "networkPlugin": "kubenet", + "networkPolicy": null, + "nodePools": [ + { + "availabilityZones": [ + "1", + "2", + "3" + ], + "count": 1, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": "1.23.8", + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "vmSize": "Standard_DS2_v2" + } + ], + "podCidr": null, + "privateCluster": false, + "privateDnsZone": null, + "resourceGroup": "aks-resource-group", + "resourceLocation": "eastus", + "serviceCidr": null, + "subnet": null, + "tags": { + }, + "virtualNetwork": null, + "virtualNetworkResourceGroup": null, + "outboundType": null, + "managedIdentity": null, + "userAssignedIdentity": null + }, + "status": { + "failureMessage": "", + "phase": "active", + "rbacEnabled": true + } +} + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config.go new file mode 100644 index 0000000..39f4a1d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config.go @@ -0,0 +1,203 @@ +package auth + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/rancher/norman/objectclient" + "github.com/rancher/rancher/pkg/auth/cleanup" + "github.com/rancher/rancher/pkg/auth/providerrefresh" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + authConfigControllerName = "mgmt-auth-config-controller" + + // CleanupAnnotation exists to prevent admins from running the cleanup routine in two scenarios: + // 1. When the provider has not been enabled or deliberately disabled, and thus does not need cleanup. + // 2. When the value of the annotation is 'user-locked', set manually by admins in advance. + // Rancher will run cleanup only if the provider becomes disabled, + // and the annotation's value is 'unlocked'. + CleanupAnnotation = "management.cattle.io/auth-provider-cleanup" + + CleanupUnlocked = "unlocked" + CleanupUserLocked = "user-locked" + CleanupRancherLocked = "rancher-locked" +) + +// CleanupService performs a cleanup of auxiliary resources belonging to a particular auth provider type. +type CleanupService interface { + Run(config *v3.AuthConfig) error +} + +type authConfigController struct { + users v3.UserLister + authRefresher providerrefresh.UserAuthRefresher + cleanup CleanupService + // Note the use of the GenericClient here. AuthConfigs contain internal-only fields that deal with + // various auth providers. Those fields are not present everywhere, nor are they defined in the CRD. Given + // that, the regular client will "eat" those internal-only fields, so in this case, we use + // the unstructured client, losing some validation, but gaining the flexibility we require. + authConfigsUnstructured objectclient.GenericClient +} + +func newAuthConfigController(context context.Context, mgmt *config.ManagementContext, scaledContext *config.ScaledContext) *authConfigController { + controller := &authConfigController{ + users: mgmt.Management.Users("").Controller().Lister(), + authRefresher: providerrefresh.NewUserAuthRefresher(context, scaledContext), + cleanup: cleanup.NewCleanupService(mgmt.Core.Secrets(""), mgmt.Wrangler.Mgmt), + authConfigsUnstructured: scaledContext.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), + } + return controller +} + +func (ac *authConfigController) getUnstructured(obj *v3.AuthConfig) (*unstructured.Unstructured, error) { + if obj == nil { + return nil, fmt.Errorf("cannot get a nil auth config") + } + runtimeObj, err := ac.authConfigsUnstructured.Get(obj.Name, v1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get auth config %s from Kubernetes: %w", obj.Name, err) + } + unstructuredObj, ok := runtimeObj.(*unstructured.Unstructured) + if !ok { + return nil, fmt.Errorf("auth config %s is not an unstructured value", obj.Name) + } + return unstructuredObj, nil +} + +func (ac *authConfigController) setCleanupAnnotation(unstructuredObj *unstructured.Unstructured, value string) { + annotations := unstructuredObj.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + annotations[CleanupAnnotation] = value + unstructuredObj.SetAnnotations(annotations) +} + +func (ac *authConfigController) sync(key string, obj *v3.AuthConfig) (runtime.Object, error) { + // If obj is nil, the auth config has been deleted. Rancher currently does not handle deletions gracefully, + // meaning it does not perform resource cleanup. Admins should disable an auth provider instead of deleting its auth config. + if obj == nil { + return nil, nil + } + err := ac.refreshUsers(obj) + if err != nil { + return obj, err + } + + unstructuredObj, err := ac.getUnstructured(obj) + if err != nil { + return nil, err + } + + value := obj.Annotations[CleanupAnnotation] + if value == "" { + if obj.Enabled { + value = CleanupUnlocked + } else { + value = CleanupRancherLocked + } + ac.setCleanupAnnotation(unstructuredObj, value) + return ac.updateAuthConfig(unstructuredObj, obj) + } + + if obj.Enabled && value == CleanupRancherLocked { + ac.setCleanupAnnotation(unstructuredObj, CleanupUnlocked) + return ac.updateAuthConfig(unstructuredObj, obj) + } + + if !obj.Enabled { + refusalFmt := "Refusing to reset the config and clean up resources of the auth provider %s because its auth config annotation %s is set to %s." + + switch value { + case CleanupUnlocked: + // First, reset the auth config by removing all but essential metadata fields. + cfg := unstructuredObj.UnstructuredContent() + resetAuthConfig(cfg) + unstructuredObj.SetUnstructuredContent(cfg) + + // Second, run resource cleanup. + err = ac.cleanup.Run(obj) + if err != nil { + return obj, err + } + + // Third, lock the config after cleanup and commit any updates to it. + logrus.Infof("The resources of the auth provider %s have been cleaned up successfully, and the auth config fields have been reset. Locking down the cleanup operation.", obj.Name) + ac.setCleanupAnnotation(unstructuredObj, CleanupRancherLocked) + return ac.updateAuthConfig(unstructuredObj, obj) + case CleanupRancherLocked: + logrus.Infof(refusalFmt, obj.Name, CleanupAnnotation, CleanupRancherLocked) + return obj, nil + case CleanupUserLocked: + logrus.Infof(refusalFmt, obj.Name, CleanupAnnotation, CleanupUserLocked) + return obj, nil + default: + logrus.Infof("Refusing to clean up auth provider %s because its auth config annotation %s is invalid", obj.Name, CleanupAnnotation) + return obj, nil + } + } + + return obj, nil +} + +func (ac *authConfigController) updateAuthConfig(unstructuredObj *unstructured.Unstructured, obj *v3.AuthConfig) (*v3.AuthConfig, error) { + uobj, err := ac.authConfigsUnstructured.Update(obj.Name, unstructuredObj) + if err != nil { + return nil, fmt.Errorf("failed to update AuthConfig object: %w", err) + } + // We need to return an AuthConfig, but Update deals in terms of unstructured objects. + // Given that, we need to convert the unstructured object to an AuthConfig. + // Normally, we'd like to use mapstructure.Decode, but its handling of embedded structs + // does not give us the desired result in this instance, hence the use of json. + unObject, ok := uobj.(*unstructured.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to read to unstructured data") + } + data, err := json.Marshal(unObject.UnstructuredContent()) + if err != nil { + return nil, fmt.Errorf("unable to marshal unstructured object: %w", err) + } + result := &v3.AuthConfig{} + if err := json.Unmarshal(data, result); err != nil { + return nil, fmt.Errorf("uanble to unmarshal to AuthConfig object: %w", err) + } + return result, nil +} + +func (ac *authConfigController) refreshUsers(obj *v3.AuthConfig) error { + // if we have changed an auth config, refresh all users belonging to the auth config. This addresses: + // Disabling an auth provider - now we disable user access + // Removing a user from auth provider access - now we will immediately revoke access + users, err := ac.users.List("", labels.Everything()) + if err != nil { + return err + } + for _, user := range users { + principalID := providerrefresh.GetPrincipalIDForProvider(obj.Name, user) + if principalID != "" { + // if we have a principal on this provider, then we need to be refreshed to potentially invalidate + // access derived from this provider + ac.authRefresher.TriggerUserRefresh(user.Name, true) + } + } + return nil +} + +// resetAuthConfig takes an Auth Config as a map and deletes all entries except those with basic metadata fields. +func resetAuthConfig(cfg map[string]any) { + retainFields := map[string]bool{"apiVersion": true, "kind": true, "metadata": true, "type": true} + for field := range cfg { + if !retainFields[field] { + delete(cfg, field) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config_test.go new file mode 100644 index 0000000..6c88d2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/auth_config_test.go @@ -0,0 +1,514 @@ +package auth + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + azuread "github.com/rancher/rancher/pkg/auth/providers/azure/clients" + "github.com/rancher/rancher/pkg/auth/providers/github" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +func TestCleanupRuns(t *testing.T) { + t.Parallel() + tests := []struct { + name string + configEnabled bool + annotationValue string + expectCleanup bool + newAnnotationValue string + }{ + { + name: "cleanup runs in disabled unlocked auth config", + configEnabled: false, + annotationValue: CleanupUnlocked, + expectCleanup: true, + newAnnotationValue: CleanupRancherLocked, + }, + { + name: "no cleanup in disabled auth config without annotation", + configEnabled: false, + annotationValue: "", + expectCleanup: false, + newAnnotationValue: CleanupRancherLocked, + }, + { + name: "no cleanup in enabled auth config without annotation", + configEnabled: true, + annotationValue: "", + expectCleanup: false, + newAnnotationValue: CleanupUnlocked, + }, + { + name: "no cleanup in disabled rancher_locked auth config", + configEnabled: false, + annotationValue: CleanupRancherLocked, + expectCleanup: false, + newAnnotationValue: CleanupRancherLocked, + }, + { + name: "no cleanup in disabled user_locked auth config", + configEnabled: false, + annotationValue: CleanupUserLocked, + expectCleanup: false, + newAnnotationValue: CleanupUserLocked, + }, + { + name: "no cleanup in enabled unlocked auth config", + configEnabled: true, + annotationValue: CleanupUnlocked, + expectCleanup: false, + newAnnotationValue: CleanupUnlocked, + }, + { + name: "no cleanup in enabled rancher_locked auth config", + configEnabled: true, + annotationValue: CleanupRancherLocked, + expectCleanup: false, + newAnnotationValue: CleanupUnlocked, + }, + { + name: "no cleanup in enabled user_locked auth config", + configEnabled: true, + annotationValue: CleanupUserLocked, + expectCleanup: false, + newAnnotationValue: CleanupUserLocked, + }, + { + name: "no cleanup in disabled auth config with invalid annotation", + configEnabled: false, + annotationValue: "bad", + expectCleanup: false, + newAnnotationValue: "bad", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + mockUsers := newMockUserLister() + config := &v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: azuread.Name, + Annotations: map[string]string{CleanupAnnotation: test.annotationValue}, + }, + Enabled: test.configEnabled, + } + var service cleanupService + controller := authConfigController{ + cleanup: &service, + authConfigsUnstructured: newMockAuthConfigClient(config), + users: &mockUsers, + } + + authConfig, err := controller.sync("test", config) + acObject := authConfig.(*v3.AuthConfig) + require.NoError(t, err) + assert.Equal(t, test.newAnnotationValue, acObject.Annotations[CleanupAnnotation]) + assert.Equal(t, test.expectCleanup, service.cleanupCalled) + }) + } +} + +func TestAuthConfigReset(t *testing.T) { + t.Parallel() + + allFields := []string{"accessMode", "allowedPrincipalIds", "apiVersion", "kind", "metadata", "type", "status"} + postResetFields := []string{"apiVersion", "kind", "metadata", "type", "status"} + + tests := []struct { + annotationValue string + retainedFields []string + }{ + {CleanupRancherLocked, allFields}, + {CleanupUserLocked, allFields}, + {CleanupUnlocked, postResetFields}, + } + + for _, test := range tests { + test := test + t.Run(test.annotationValue, func(t *testing.T) { + t.Parallel() + config := v3.AuthConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "Auth Config", + APIVersion: "management.cattle.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: github.Name, + Annotations: map[string]string{CleanupAnnotation: test.annotationValue}, + }, + Type: "githubConfig", + Enabled: false, + AccessMode: "unrestricted", + AllowedPrincipalIDs: []string{"user1", "user2"}, + } + + mockUsers := newMockUserLister() + controller := authConfigController{ + cleanup: new(cleanupService), + authConfigsUnstructured: newMockAuthConfigClient(&config), + users: &mockUsers, + } + + _, err := controller.sync("test", &config) + require.NoError(t, err) + u, err := controller.getUnstructured(&config) + require.NoError(t, err) + + cfg := u.UnstructuredContent() + assert.Equal(t, len(test.retainedFields), len(cfg)) + for _, field := range test.retainedFields { + assert.Contains(t, cfg, field) + } + }) + } +} + +func TestAuthConfigSync(t *testing.T) { + config := v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: github.Name, + }, + } + tests := []struct { + name string + usernamesForTestConfig []string + usernamesForOtherConfig []string + listUsersErr error + errExpected bool + }{ + { + name: "basic test case - refresh single user", + usernamesForTestConfig: []string{"tUser"}, + usernamesForOtherConfig: []string{}, + listUsersErr: nil, + errExpected: false, + }, + { + name: "refresh user belonging to one auth provider but not another", + usernamesForTestConfig: []string{"tUser"}, + usernamesForOtherConfig: []string{"oUser"}, + listUsersErr: nil, + errExpected: false, + }, + { + name: "refresh multiple users, some in the auth config, others not", + usernamesForTestConfig: []string{"tUser", "sUser", "newUser"}, + usernamesForOtherConfig: []string{"oUser", "configUser", "otherConfigUser"}, + listUsersErr: nil, + errExpected: false, + }, + { + name: "error when listing users - expect an error", + usernamesForTestConfig: []string{"tUser", "sUser", "newUser"}, + usernamesForOtherConfig: []string{"oUser", "configUser", "otherConfigUser"}, + listUsersErr: fmt.Errorf("error when listing users"), + errExpected: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + const testConfigName = "testConfig" + const otherConfigName = "otherConfig" + + mockUsers := newMockUserLister() + for _, username := range test.usernamesForTestConfig { + mockUsers.AddUser(username, testConfigName) + } + + for _, username := range test.usernamesForOtherConfig { + mockUsers.AddUser(username, otherConfigName) + } + + if test.listUsersErr != nil { + mockUsers.AddListUserError(test.listUsersErr) + } + + mockRefresher := newMockAuthProvider() + controller := authConfigController{ + users: &mockUsers, + authRefresher: &mockRefresher, + cleanup: &fakeCleanupService{}, + authConfigsUnstructured: newMockAuthConfigClient(&config), + } + config := v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: testConfigName, + Annotations: map[string]string{ + CleanupAnnotation: CleanupUnlocked, + }, + }, + Enabled: true, + } + _, err := controller.sync("test", &config) + if test.errExpected { + assert.Error(t, err, "Expected error but none was provided") + } else { + assert.NoError(t, err, "Expected no error") + for _, username := range test.usernamesForTestConfig { + assert.Contains(t, mockRefresher.refreshedUsers, username, "Expected user to be refreshed") + } + for _, username := range test.usernamesForOtherConfig { + assert.NotContains(t, mockRefresher.refreshedUsers, username, "Did not expect user to be refreshed") + } + } + }) + } +} + +type mockUserLister struct { + users []*v3.User + listUsersErr error +} + +func newMockUserLister() mockUserLister { + return mockUserLister{ + users: []*v3.User{}, + } +} + +func (m *mockUserLister) List(_ string, _ labels.Selector) (ret []*v3.User, err error) { + if m.listUsersErr != nil { + return nil, m.listUsersErr + } + return m.users, nil +} +func (m *mockUserLister) Get(_, name string) (*v3.User, error) { + for _, user := range m.users { + if user.Name == name { + return user, nil + } + } + return nil, apierror.NewNotFound(schema.GroupResource{Group: "management.cattle.io", Resource: "user"}, name) +} + +func (m *mockUserLister) AddUser(username string, provider string) { + principalIds := []string{ + fmt.Sprintf("local://%s", username), + fmt.Sprintf("%s_user://%s", provider, username), + } + newUser := v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: username}, + PrincipalIDs: principalIds, + } + found := false + for idx, user := range m.users { + if user.Name == newUser.Name { + m.users[idx] = &newUser + found = true + } + } + if !found { + m.users = append(m.users, &newUser) + } +} + +func (m *mockUserLister) AddListUserError(err error) { + m.listUsersErr = err +} + +type cleanupService struct { + cleanupCalled bool +} + +func (s *cleanupService) Run(_ *v3.AuthConfig) error { + s.cleanupCalled = true + return nil +} + +type mockUnstructuredAuthConfig struct { + config *v3.AuthConfig +} + +func (m mockUnstructuredAuthConfig) GetObjectKind() schema.ObjectKind { + return nil +} + +func (m mockUnstructuredAuthConfig) DeepCopyObject() runtime.Object { + //TODO implement me + panic("implement me") +} + +func (m mockUnstructuredAuthConfig) NewEmptyInstance() runtime.Unstructured { + //TODO implement me + panic("implement me") +} + +func (m mockUnstructuredAuthConfig) UnstructuredContent() map[string]interface{} { + var out map[string]any + b, err := json.Marshal(m.config) + if err != nil { + return nil + } + err = json.Unmarshal(b, &out) + if err != nil { + return nil + } + return out +} + +func (m mockUnstructuredAuthConfig) SetUnstructuredContent(content map[string]interface{}) { + b, err := json.Marshal(content) + if err != nil { + return + } + err = json.Unmarshal(b, m.config) + if err != nil { + return + } +} + +func (m mockUnstructuredAuthConfig) IsList() bool { + //TODO implement me + panic("implement me") +} + +func (m mockUnstructuredAuthConfig) EachListItem(_ func(runtime.Object) error) error { + //TODO implement me + panic("implement me") +} + +type mockAuthConfigClient struct { + config mockUnstructuredAuthConfig +} + +func newMockAuthConfigClient(authConfig *v3.AuthConfig) objectclient.GenericClient { + return &mockAuthConfigClient{config: mockUnstructuredAuthConfig{authConfig}} +} + +func (m *mockAuthConfigClient) Get(_ string, _ metav1.GetOptions) (runtime.Object, error) { + o := unstructured.Unstructured{} + js, err := json.Marshal(m.config.config) + if err != nil { + return nil, err + } + var aMap map[string]any + if err = json.Unmarshal(js, &aMap); err != nil { + return nil, err + } + o.SetUnstructuredContent(aMap) + return &o, nil +} + +func (m *mockAuthConfigClient) Update(_ string, o runtime.Object) (runtime.Object, error) { + b, err := json.Marshal(o) + if err != nil { + return nil, err + } + var cfg v3.AuthConfig + if err = json.Unmarshal(b, &cfg); err != nil { + return nil, err + } + m.config.config = &cfg + return o, nil +} + +func (m *mockAuthConfigClient) UnstructuredClient() objectclient.GenericClient { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) GroupVersionKind() schema.GroupVersionKind { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) Create(_ runtime.Object) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) GetNamespaced(_, _ string, _ metav1.GetOptions) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) UpdateStatus(_ string, _ runtime.Object) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) DeleteNamespaced(_, _ string, _ *metav1.DeleteOptions) error { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) Delete(_ string, _ *metav1.DeleteOptions) error { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) List(_ metav1.ListOptions) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) ListNamespaced(_ string, _ metav1.ListOptions) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) Watch(_ metav1.ListOptions) (watch.Interface, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) DeleteCollection(_ *metav1.DeleteOptions, _ metav1.ListOptions) error { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) Patch(_ string, _ runtime.Object, _ types.PatchType, _ []byte, _ ...string) (runtime.Object, error) { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) ObjectFactory() objectclient.ObjectFactory { + //TODO implement me + panic("implement me") +} + +func (m *mockAuthConfigClient) ObjectClient() *objectclient.ObjectClient { + //TODO implement me + panic("implement me") +} + +type fakeCleanupService struct{} + +func (f *fakeCleanupService) Run(_ *v3.AuthConfig) error { + return nil +} + +type mockAuthProvider struct { + allUsersRefreshed bool + refreshedUsers map[string]bool +} + +func newMockAuthProvider() mockAuthProvider { + return mockAuthProvider{ + allUsersRefreshed: false, + refreshedUsers: map[string]bool{}, + } +} + +func (m *mockAuthProvider) TriggerAllUserRefresh() { + m.allUsersRefreshed = true +} + +func (m *mockAuthProvider) TriggerUserRefresh(username string, force bool) { + m.refreshedUsers[username] = force +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler.go new file mode 100644 index 0000000..9520209 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler.go @@ -0,0 +1,298 @@ +package auth + +import ( + "errors" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/controllers/management/authprovisioningv2" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/util/retry" +) + +const ( + /* Prior to 2.5, the label "memberhsip-binding-owner" was set on the CRB/RBs for a roleTemplateBinding with the key being the roleTemplateBinding's UID. + 2.5 onwards, instead of the roleTemplateBinding's UID, a combination of its namespace and name will be used in this label. + CRB/RBs on clusters upgraded from 2.4.x to 2.5 will continue to carry the original label with UID. To ensure permissions are managed properly on upgrade, + we need to change the label value as well. + So the older label value, MembershipBindingOwnerLegacy (<=2.4.x) will continue to be "memberhsip-binding-owner" (notice the spelling mistake), + and the new label, MembershipBindingOwner will be "membership-binding-owner" (a different label value with the right spelling)*/ + MembershipBindingOwnerLegacy = "memberhsip-binding-owner" + MembershipBindingOwner = "membership-binding-owner" + clusterResource = "clusters" + membershipBindingOwnerIndex = "auth.management.cattle.io/membership-binding-owner" + CrtbInProjectBindingOwner = "crtb-in-project-binding-owner" + PrtbInClusterBindingOwner = "prtb-in-cluster-binding-owner" + rbByOwnerIndex = "auth.management.cattle.io/rb-by-owner" + rbByRoleAndSubjectIndex = "auth.management.cattle.io/crb-by-role-and-subject" + ctrbMGMTController = "mgmt-auth-crtb-controller" + rtbLabelUpdated = "auth.management.cattle.io/rtb-label-updated" + RtbCrbRbLabelsUpdated = "auth.management.cattle.io/crb-rb-labels-updated" +) + +var clusterManagementPlaneResources = map[string]string{ + "clusterscans": "management.cattle.io", + "catalogtemplates": "management.cattle.io", + "catalogtemplateversions": "management.cattle.io", + "clusteralertrules": "management.cattle.io", + "clusteralertgroups": "management.cattle.io", + "clustercatalogs": "management.cattle.io", + "clusterloggings": "management.cattle.io", + "clustermonitorgraphs": "management.cattle.io", + "clusterregistrationtokens": "management.cattle.io", + "clusterroletemplatebindings": "management.cattle.io", + "etcdbackups": "management.cattle.io", + "nodes": "management.cattle.io", + "nodepools": "management.cattle.io", + "notifiers": "management.cattle.io", + "projects": "management.cattle.io", + "etcdsnapshots": "rke.cattle.io", +} + +type crtbLifecycle struct { + mgr managerInterface + clusterLister v3.ClusterLister + userMGR user.Manager + userLister v3.UserLister + projectLister v3.ProjectLister + rbLister typesrbacv1.RoleBindingLister + rbClient typesrbacv1.RoleBindingInterface + crbLister typesrbacv1.ClusterRoleBindingLister + crbClient typesrbacv1.ClusterRoleBindingInterface + crtbClient v3.ClusterRoleTemplateBindingInterface +} + +func (c *crtbLifecycle) Create(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + obj, err := c.reconcileSubject(obj) + if err != nil { + return nil, err + } + err = c.reconcileBindings(obj) + + return obj, err +} + +func (c *crtbLifecycle) Updated(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + obj, err := c.reconcileSubject(obj) + if err != nil { + return nil, err + } + if err := c.reconcileLabels(obj); err != nil { + return nil, err + } + err = c.reconcileBindings(obj) + return obj, err +} + +func (c *crtbLifecycle) Remove(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + if err := c.mgr.reconcileClusterMembershipBindingForDelete("", pkgrbac.GetRTBLabel(obj.ObjectMeta)); err != nil { + return nil, err + } + if err := c.removeMGMTClusterScopedPrivilegesInProjectNamespace(obj); err != nil { + return nil, err + } + + err := c.mgr.removeAuthV2Permissions(authprovisioningv2.CRTBRoleBindingID, obj) + return nil, err +} + +func (c *crtbLifecycle) reconcileSubject(binding *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + if binding.GroupName != "" || binding.GroupPrincipalName != "" || (binding.UserPrincipalName != "" && binding.UserName != "") { + return binding, nil + } + + if binding.UserPrincipalName != "" && binding.UserName == "" { + displayName := binding.Annotations["auth.cattle.io/principal-display-name"] + user, err := c.userMGR.EnsureUser(binding.UserPrincipalName, displayName) + if err != nil { + return binding, err + } + + binding.UserName = user.Name + return binding, nil + } + + if binding.UserPrincipalName == "" && binding.UserName != "" { + u, err := c.userLister.Get("", binding.UserName) + if err != nil { + return binding, err + } + for _, p := range u.PrincipalIDs { + if strings.HasSuffix(p, binding.UserName) { + binding.UserPrincipalName = p + break + } + } + return binding, nil + } + + return nil, fmt.Errorf("ClusterRoleTemplateBinding %v has no subject", binding.Name) +} + +// When a CRTB is created or updated, translate it into several k8s roles and bindings to actually enforce the RBAC +// Specifically: +// - ensure the subject can see the cluster in the mgmt API +// - if the subject was granted owner permissions for the clsuter, ensure they can create/update/delete the cluster +// - if the subject was granted privileges to mgmt plane resources that are scoped to the cluster, enforce those rules in the cluster's mgmt plane namespace +func (c *crtbLifecycle) reconcileBindings(binding *v3.ClusterRoleTemplateBinding) error { + if binding.UserName == "" && binding.GroupPrincipalName == "" && binding.GroupName == "" { + return nil + } + + clusterName := binding.ClusterName + cluster, err := c.clusterLister.Get("", clusterName) + if err != nil { + return err + } + if cluster == nil { + return fmt.Errorf("cannot create binding because cluster %v was not found", clusterName) + } + // if roletemplate is not builtin, check if it's inherited/cloned + isOwnerRole, err := c.mgr.checkReferencedRoles(binding.RoleTemplateName, clusterContext, 0) + if err != nil { + return err + } + var clusterRoleName string + if isOwnerRole { + clusterRoleName = strings.ToLower(fmt.Sprintf("%v-clusterowner", clusterName)) + } else { + clusterRoleName = strings.ToLower(fmt.Sprintf("%v-clustermember", clusterName)) + } + + subject, err := pkgrbac.BuildSubjectFromRTB(binding) + if err != nil { + return err + } + if err := c.mgr.ensureClusterMembershipBinding(clusterRoleName, pkgrbac.GetRTBLabel(binding.ObjectMeta), cluster, isOwnerRole, subject); err != nil { + return err + } + + err = c.mgr.grantManagementPlanePrivileges(binding.RoleTemplateName, clusterManagementPlaneResources, subject, binding) + if err != nil { + return err + } + + projects, err := c.projectLister.List(binding.Namespace, labels.Everything()) + if err != nil { + return err + } + for _, p := range projects { + if p.DeletionTimestamp != nil { + logrus.Warnf("Project %v is being deleted, not creating membership bindings", p.Name) + continue + } + if err := c.mgr.grantManagementClusterScopedPrivilegesInProjectNamespace(binding.RoleTemplateName, p.Name, projectManagementPlaneResources, subject, binding); err != nil { + return err + } + } + return nil +} + +func (c *crtbLifecycle) removeMGMTClusterScopedPrivilegesInProjectNamespace(binding *v3.ClusterRoleTemplateBinding) error { + projects, err := c.projectLister.List(binding.Namespace, labels.Everything()) + if err != nil { + return err + } + bindingKey := pkgrbac.GetRTBLabel(binding.ObjectMeta) + for _, p := range projects { + set := labels.Set(map[string]string{bindingKey: CrtbInProjectBindingOwner}) + rbs, err := c.rbLister.List(p.Name, set.AsSelector()) + if err != nil { + return err + } + for _, rb := range rbs { + logrus.Infof("[%v] Deleting rolebinding %v in namespace %v for crtb %v", ctrbMGMTController, rb.Name, p.Name, binding.Name) + if err := c.rbClient.DeleteNamespaced(p.Name, rb.Name, &v1.DeleteOptions{}); err != nil { + return err + } + } + } + return nil +} + +func (c *crtbLifecycle) reconcileLabels(binding *v3.ClusterRoleTemplateBinding) error { + /* Prior to 2.5, for every CRTB, following CRBs and RBs are created in the management clusters + 1. CRTB.UID is the label key for a CRB, CRTB.UID=memberhsip-binding-owner + 2. CRTB.UID is label key for the RB, CRTB.UID=crtb-in-project-binding-owner (in the namespace of each project in the cluster that the user has access to) + Using above labels, list the CRB and RB and update them to add a label with ns+name of CRTB + */ + if binding.Labels[RtbCrbRbLabelsUpdated] == "true" { + return nil + } + + var returnErr error + requirements, err := getLabelRequirements(binding.ObjectMeta) + if err != nil { + return err + } + + set := labels.Set(map[string]string{string(binding.UID): MembershipBindingOwnerLegacy}) + crbs, err := c.crbLister.List(v1.NamespaceAll, set.AsSelector().Add(requirements...)) + if err != nil { + return err + } + bindingKey := pkgrbac.GetRTBLabel(binding.ObjectMeta) + for _, crb := range crbs { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crbToUpdate, updateErr := c.crbClient.Get(crb.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crbToUpdate.Labels == nil { + crbToUpdate.Labels = make(map[string]string) + } + crbToUpdate.Labels[bindingKey] = MembershipBindingOwner + crbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := c.crbClient.Update(crbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + + set = map[string]string{string(binding.UID): CrtbInProjectBindingOwner} + rbs, err := c.rbLister.List(v1.NamespaceAll, set.AsSelector().Add(requirements...)) + if err != nil { + return err + } + + for _, rb := range rbs { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + rbToUpdate, updateErr := c.rbClient.GetNamespaced(rb.Namespace, rb.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if rbToUpdate.Labels == nil { + rbToUpdate.Labels = make(map[string]string) + } + rbToUpdate.Labels[bindingKey] = CrtbInProjectBindingOwner + rbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := c.rbClient.Update(rbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + if returnErr != nil { + return returnErr + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crtbToUpdate, updateErr := c.crtbClient.GetNamespaced(binding.Namespace, binding.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crtbToUpdate.Labels == nil { + crtbToUpdate.Labels = make(map[string]string) + } + crtbToUpdate.Labels[RtbCrbRbLabelsUpdated] = "true" + _, err := c.crtbClient.Update(crtbToUpdate) + return err + }) + return retryErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler_test.go new file mode 100644 index 0000000..5e653e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/crtb_handler_test.go @@ -0,0 +1,304 @@ +package auth + +import ( + "fmt" + "testing" + "time" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +var ( + e = fmt.Errorf("error") + defaultCRTB = v3.ClusterRoleTemplateBinding{ + UserName: "test", + GroupName: "", + GroupPrincipalName: "", + ClusterName: "clusterName", + RoleTemplateName: "roleTemplate", + } + noUserCRTB = v3.ClusterRoleTemplateBinding{ + UserName: "", + GroupName: "", + GroupPrincipalName: "", + } + defaultCluster = v3.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: "test-cluster", + }, + } + defaultProject = v3.Project{ + ObjectMeta: v1.ObjectMeta{ + Name: "test-project", + }, + } + deletingProject = v3.Project{ + ObjectMeta: v1.ObjectMeta{ + Name: "deleting-project", + DeletionTimestamp: &v1.Time{Time: time.Now()}, + }, + } +) + +type crtbTestState struct { + clusterListerMock *fakes.ClusterListerMock + projectListerMock *fakes.ProjectListerMock + managerMock *MockmanagerInterface +} + +func TestReconcileBindings(t *testing.T) { + tests := []struct { + name string + stateSetup func(crtbTestState) + wantError bool + crtb *v3.ClusterRoleTemplateBinding + }{ + { + name: "reconcile crtb with no subject", + crtb: noUserCRTB.DeepCopy(), + }, + { + name: "error getting cluster", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + return nil, e + } + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "cluster not found", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + return nil, nil + } + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "error in checkReferencedRoles", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, e) + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "error in ensureClusterMembershipBinding", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clusterowner", gomock.Any(), gomock.Any(), true, gomock.Any()). + Return(e) + + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "error in grantManagementPlanePrivileges", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clusterowner", gomock.Any(), gomock.Any(), true, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(e) + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "error listing projects", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clusterowner", gomock.Any(), gomock.Any(), true, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.projectListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Project, error) { + return nil, e + } + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "error listing projects", + stateSetup: func(cts crtbTestState) { + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clusterowner", gomock.Any(), gomock.Any(), true, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.projectListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Project, error) { + p := defaultProject.DeepCopy() + return []*v3.Project{p}, nil + } + cts.managerMock.EXPECT(). + grantManagementClusterScopedPrivilegesInProjectNamespace("roleTemplate", "test-project", gomock.Any(), gomock.Any(), gomock.Any()). + Return(e) + + }, + wantError: true, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "successfully reconcile clusterowner", + stateSetup: func(cts crtbTestState) { + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(true, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clusterowner", gomock.Any(), gomock.Any(), true, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementClusterScopedPrivilegesInProjectNamespace("roleTemplate", "test-project", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.projectListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Project, error) { + p := defaultProject.DeepCopy() + return []*v3.Project{p}, nil + } + }, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "successfully reconcile clustermember", + stateSetup: func(cts crtbTestState) { + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(false, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clustermember", gomock.Any(), gomock.Any(), false, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementClusterScopedPrivilegesInProjectNamespace("roleTemplate", "test-project", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.projectListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Project, error) { + p := defaultProject.DeepCopy() + return []*v3.Project{p}, nil + } + }, + crtb: defaultCRTB.DeepCopy(), + }, + { + name: "skip projects that are deleting", + stateSetup: func(cts crtbTestState) { + cts.managerMock.EXPECT(). + checkReferencedRoles("roleTemplate", "cluster", gomock.Any()). + Return(false, nil) + cts.managerMock.EXPECT(). + ensureClusterMembershipBinding("clustername-clustermember", gomock.Any(), gomock.Any(), false, gomock.Any()). + Return(nil) + cts.managerMock.EXPECT(). + grantManagementPlanePrivileges("roleTemplate", gomock.Any(), gomock.Any(), gomock.Any()). + Return(nil) + // This should not be called + cts.managerMock.EXPECT(). + grantManagementClusterScopedPrivilegesInProjectNamespace("roleTemplate", "deleting-project", gomock.Any(), gomock.Any(), gomock.Any()). + Return(e).AnyTimes() + cts.clusterListerMock.GetFunc = func(namespace, name string) (*v3.Cluster, error) { + c := defaultCluster.DeepCopy() + return c, nil + } + cts.projectListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Project, error) { + p := deletingProject.DeepCopy() + return []*v3.Project{p}, nil + } + }, + crtb: defaultCRTB.DeepCopy(), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + crtbLifecycle := crtbLifecycle{} + state := setupTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + crtbLifecycle.clusterLister = state.clusterListerMock + crtbLifecycle.projectLister = state.projectListerMock + crtbLifecycle.mgr = state.managerMock + + err := crtbLifecycle.reconcileBindings(test.crtb) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func setupTest(t *testing.T) crtbTestState { + ctrl := gomock.NewController(t) + fakeManager := NewMockmanagerInterface(ctrl) + projectListerMock := fakes.ProjectListerMock{} + clusterListerMock := fakes.ClusterListerMock{} + + state := crtbTestState{ + managerMock: fakeManager, + clusterListerMock: &clusterListerMock, + projectListerMock: &projectListerMock, + } + return state +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/fakes/zz_usermanager_fakes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/fakes/zz_usermanager_fakes.go new file mode 100644 index 0000000..634dd57 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/fakes/zz_usermanager_fakes.go @@ -0,0 +1,201 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/user (interfaces: Manager) + +// Package auth is a generated GoMock package. +package auth + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" + types "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + user "github.com/rancher/rancher/pkg/user" + types0 "k8s.io/apimachinery/pkg/types" +) + +// MockManager is a mock of Manager interface. +type MockManager struct { + ctrl *gomock.Controller + recorder *MockManagerMockRecorder +} + +// MockManagerMockRecorder is the mock recorder for MockManager. +type MockManagerMockRecorder struct { + mock *MockManager +} + +// NewMockManager creates a new mock instance. +func NewMockManager(ctrl *gomock.Controller) *MockManager { + mock := &MockManager{ctrl: ctrl} + mock.recorder = &MockManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockManager) EXPECT() *MockManagerMockRecorder { + return m.recorder +} + +// CheckAccess mocks base method. +func (m *MockManager) CheckAccess(arg0 string, arg1 []string, arg2 string, arg3 []v3.Principal) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckAccess", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CheckAccess indicates an expected call of CheckAccess. +func (mr *MockManagerMockRecorder) CheckAccess(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckAccess", reflect.TypeOf((*MockManager)(nil).CheckAccess), arg0, arg1, arg2, arg3) +} + +// CreateNewUserClusterRoleBinding mocks base method. +func (m *MockManager) CreateNewUserClusterRoleBinding(arg0 string, arg1 types0.UID) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateNewUserClusterRoleBinding", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateNewUserClusterRoleBinding indicates an expected call of CreateNewUserClusterRoleBinding. +func (mr *MockManagerMockRecorder) CreateNewUserClusterRoleBinding(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateNewUserClusterRoleBinding", reflect.TypeOf((*MockManager)(nil).CreateNewUserClusterRoleBinding), arg0, arg1) +} + +// DeleteToken mocks base method. +func (m *MockManager) DeleteToken(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteToken", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteToken indicates an expected call of DeleteToken. +func (mr *MockManagerMockRecorder) DeleteToken(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteToken", reflect.TypeOf((*MockManager)(nil).DeleteToken), arg0) +} + +// EnsureClusterToken mocks base method. +func (m *MockManager) EnsureClusterToken(arg0 string, arg1 user.TokenInput) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureClusterToken", arg0, arg1) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EnsureClusterToken indicates an expected call of EnsureClusterToken. +func (mr *MockManagerMockRecorder) EnsureClusterToken(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureClusterToken", reflect.TypeOf((*MockManager)(nil).EnsureClusterToken), arg0, arg1) +} + +// EnsureToken mocks base method. +func (m *MockManager) EnsureToken(arg0 user.TokenInput) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureToken", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EnsureToken indicates an expected call of EnsureToken. +func (mr *MockManagerMockRecorder) EnsureToken(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureToken", reflect.TypeOf((*MockManager)(nil).EnsureToken), arg0) +} + +// EnsureUser mocks base method. +func (m *MockManager) EnsureUser(arg0, arg1 string) (*v3.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EnsureUser", arg0, arg1) + ret0, _ := ret[0].(*v3.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EnsureUser indicates an expected call of EnsureUser. +func (mr *MockManagerMockRecorder) EnsureUser(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureUser", reflect.TypeOf((*MockManager)(nil).EnsureUser), arg0, arg1) +} + +// GetKubeconfigToken mocks base method. +func (m *MockManager) GetKubeconfigToken(arg0, arg1, arg2, arg3, arg4 string, arg5 v3.Principal) (*v3.Token, string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetKubeconfigToken", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*v3.Token) + ret1, _ := ret[1].(string) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetKubeconfigToken indicates an expected call of GetKubeconfigToken. +func (mr *MockManagerMockRecorder) GetKubeconfigToken(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetKubeconfigToken", reflect.TypeOf((*MockManager)(nil).GetKubeconfigToken), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// GetUser mocks base method. +func (m *MockManager) GetUser(arg0 *types.APIContext) string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUser", arg0) + ret0, _ := ret[0].(string) + return ret0 +} + +// GetUser indicates an expected call of GetUser. +func (mr *MockManagerMockRecorder) GetUser(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockManager)(nil).GetUser), arg0) +} + +// GetUserByPrincipalID mocks base method. +func (m *MockManager) GetUserByPrincipalID(arg0 string) (*v3.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUserByPrincipalID", arg0) + ret0, _ := ret[0].(*v3.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUserByPrincipalID indicates an expected call of GetUserByPrincipalID. +func (mr *MockManagerMockRecorder) GetUserByPrincipalID(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserByPrincipalID", reflect.TypeOf((*MockManager)(nil).GetUserByPrincipalID), arg0) +} + +// SetPrincipalOnCurrentUser mocks base method. +func (m *MockManager) SetPrincipalOnCurrentUser(arg0 *types.APIContext, arg1 v3.Principal) (*v3.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPrincipalOnCurrentUser", arg0, arg1) + ret0, _ := ret[0].(*v3.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetPrincipalOnCurrentUser indicates an expected call of SetPrincipalOnCurrentUser. +func (mr *MockManagerMockRecorder) SetPrincipalOnCurrentUser(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrincipalOnCurrentUser", reflect.TypeOf((*MockManager)(nil).SetPrincipalOnCurrentUser), arg0, arg1) +} + +// SetPrincipalOnCurrentUserByUserID mocks base method. +func (m *MockManager) SetPrincipalOnCurrentUserByUserID(arg0 string, arg1 v3.Principal) (*v3.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPrincipalOnCurrentUserByUserID", arg0, arg1) + ret0, _ := ret[0].(*v3.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SetPrincipalOnCurrentUserByUserID indicates an expected call of SetPrincipalOnCurrentUserByUserID. +func (mr *MockManagerMockRecorder) SetPrincipalOnCurrentUserByUserID(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrincipalOnCurrentUserByUserID", reflect.TypeOf((*MockManager)(nil).SetPrincipalOnCurrentUserByUserID), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue.go new file mode 100644 index 0000000..2e2be65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue.go @@ -0,0 +1,324 @@ +package globalroles + +import ( + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + wrangler "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + grbGrIndex = "mgmt-auth-grb-gr-idex" + grNsIndex = "mgmt-auth-gr-ns-index" + grSafeConcatIndex = "mgmt-auth-gr-concat-index" + grbSafeConcatIndex = "mgmt-auth-grb-concat-index" + grbEnqueuer = "mgmt-auth-gr-enqueue" + clusterGrEnqueuer = "mgmt-auth-cluster-gr" + crtbGRBEnqueuer = "mgmt-auth-crtb-grb" + roleEnqueuer = "mgmt-auth-role-gr" + roleBindingEnqueuer = "mgmt-auth-rb-grb" + namespaceGrEnqueuer = "mgmt-auth-ns-gr" + fleetWorkspaceGrbEnqueuer = "mgmt-auth-fw-grb" + clusterRoleEnqueuer = "mgmt-auth-cr-gr" + clusterRoleBindingEnqueuer = "mgmt-auth-crb-grb" +) + +type globalRBACEnqueuer struct { + grbCache mgmtv3.GlobalRoleBindingCache + grCache mgmtv3.GlobalRoleCache + clusterClient mgmtv3.ClusterClient +} + +// grNsIndexer indexes GlobalRoles by the namespaces in NamespacedRules +func grNsIndexer(gr *v3.GlobalRole) ([]string, error) { + result := []string{} + for ns := range gr.NamespacedRules { + result = append(result, ns) + } + return result, nil +} + +// grbGrIndexer indexes a globalRoleBinding by the globalRole it assigns to users +func grbGrIndexer(grb *v3.GlobalRoleBinding) ([]string, error) { + return []string{grb.GlobalRoleName}, nil +} + +// grSafeConcatIndexer indexes a GlobalRole by the SafeConcat version of it's name +func grSafeConcatIndexer(gr *v3.GlobalRole) ([]string, error) { + return []string{wrangler.SafeConcatName(gr.Name)}, nil +} + +// grbSafeConcatIndexer indexes a GlobalRoleBinding by the SafeConcat version of it's name +func grbSafeConcatIndexer(grb *v3.GlobalRoleBinding) ([]string, error) { + return []string{wrangler.SafeConcatName(grb.Name)}, nil +} + +// enqueueGRBs enqueues GlobalRoleBinding for a given changed GlobalRole, allowing per-cluster permissions to sync +func (g *globalRBACEnqueuer) enqueueGRBs(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + globalRole, ok := obj.(*v3.GlobalRole) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a global role", obj) + return nil, nil + } + bindings, err := g.grbCache.GetByIndex(grbGrIndex, globalRole.Name) + if err != nil { + return nil, fmt.Errorf("unable to get grbs for gr %s from indexer: %w", globalRole.Name, err) + } + bindingNames := make([]relatedresource.Key, 0, len(bindings)) + for _, binding := range bindings { + bindingNames = append(bindingNames, relatedresource.Key{Name: binding.Name}) + } + return bindingNames, nil +} + +// clusterEnqueueGRs enqueues GlobalRoles which provide cluster RBAC. Does not enqueue any GRs if this cluster has already had +// the initial RBAC sync done +func (g *globalRBACEnqueuer) clusterEnqueueGRs(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + cluster, ok := obj.(*v3.Cluster) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type %[1]T to a cluster", obj) + return nil, nil + } + // we only want to perform the initial sync once. Future changes will be picked up by other handlers + if _, ok := cluster.Annotations[initialSyncAnnotation]; ok { + return nil, nil + } + globalRoles, err := g.grCache.List(labels.Everything()) + if err != nil { + return nil, fmt.Errorf("unable to list current GlobalRoles when syncing roles for cluster %s: %w", cluster.Name, err) + } + var rolesToSync []relatedresource.Key + for _, globalRole := range globalRoles { + if len(globalRole.InheritedClusterRoles) == 0 { + continue + } + // Set the status as InProgress since we have to reconcile the global role + globalRole.Status.Summary = SummaryInProgress + rolesToSync = append(rolesToSync, relatedresource.Key{Name: globalRole.Name}) + } + // attempt to update the cluster with a sync annotation - this is costly since it will re-enqueue all grs + // which inherit cluster permissions, so we try to avoid it. If we can't record the annotation, we still + // want to try and sync the permissions. + newCluster, err := g.clusterClient.Get(cluster.Name, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("unable to get cluster %s to add sync annotation, grs will re-enqueue on change: %s", cluster.Name, err.Error()) + return rolesToSync, nil + } + if newCluster.Annotations == nil { + newCluster.Annotations = map[string]string{} + } + newCluster.Annotations[initialSyncAnnotation] = "true" + _, err = g.clusterClient.Update(newCluster) + if err != nil { + logrus.Errorf("unable to update cluster %s with sync annotation, grs will re-enqueue on change: %s", cluster.Name, err.Error()) + } + return rolesToSync, nil +} + +// crtbEnqueueGRB enqueues GlobalRoleBindings which own a given CRTB when that CRTB is changed. Uses the label +// which is protected by the webhook rather than the ownerReference +func (g *globalRBACEnqueuer) crtbEnqueueGRB(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + crtb, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a crtb", obj) + return nil, nil + } + grbOwner, ok := crtb.Labels[grbOwnerLabel] + if !ok { + // this crtb isn't owned by a GRB, no need to enqueue a GRB + return nil, nil + } + _, err := g.grbCache.Get(grbOwner) + if err != nil { + // if the crtb was orphaned during deletion, the label may still exist but the owning grb won't + // in these cases, nothing should be re-enqueued + if apierrors.IsNotFound(err) { + return nil, nil + } + return nil, fmt.Errorf("unable to confirm if grb %s exists for crtb %s", grbOwner, crtb.Name) + } + return []relatedresource.Key{ + {Name: grbOwner}, + }, nil +} + +// roleEnqueueGR enqueues GlobalRoles that own a given Role when that Role is changed. Uses grOwnerLabel +// which is protected by the webhook rather than the ownerReference. +func (g *globalRBACEnqueuer) roleEnqueueGR(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + role, ok := obj.(*v1.Role) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a Role", obj) + return nil, nil + } + grOwner, ok := role.Labels[grOwnerLabel] + if !ok { + // this Role isn't owned by a GR, no need to enqueue a GR + return nil, nil + } + grs, err := g.grCache.GetByIndex(grSafeConcatIndex, grOwner) + if err != nil { + return nil, fmt.Errorf("unable to get GlobalRole %s for Role %s", grOwner, role.Name) + } + + grNames := make([]relatedresource.Key, 0, len(grs)) + for _, gr := range grs { + // Set the status as InProgress since we have to reconcile the global role + gr.Status.Summary = SummaryInProgress + grNames = append(grNames, relatedresource.Key{Name: gr.Name}) + } + return grNames, nil +} + +// roleEnqueueGRB enqueues GlobalRoleBindings that own a given RoleBinding when that RoleBinding is changed. +// Uses grbOwnerLabel which is protected by the webhook rather than the ownerReference +func (g *globalRBACEnqueuer) roleBindingEnqueueGRB(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + roleBinding, ok := obj.(*v1.RoleBinding) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a RoleBinding", obj) + return nil, nil + } + grbOwner, ok := roleBinding.Labels[grbOwnerLabel] + if !ok { + // this RoleBinding isn't owned by a GRB, no need to enqueue a GRB + return nil, nil + } + grbs, err := g.grbCache.GetByIndex(grbSafeConcatIndex, grbOwner) + if err != nil { + return nil, fmt.Errorf("unable to get GlobalRoleBinding %s for RoleBinding %s", grbOwner, roleBinding.Name) + } + grbNames := make([]relatedresource.Key, 0, len(grbs)) + for _, grb := range grbs { + grbNames = append(grbNames, relatedresource.Key{Name: grb.Name}) + } + return grbNames, nil + +} + +// namespaceEnqueueGR enqueues GlobalRoles that have Roles in the changed namespace based on +// the NamespacedRules field +func (g *globalRBACEnqueuer) namespaceEnqueueGR(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + namespace, ok := obj.(*corev1.Namespace) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a Namespace", obj) + return nil, nil + } + + grs, err := g.grCache.GetByIndex(grNsIndex, namespace.Name) + if err != nil { + return nil, fmt.Errorf("unable to get grs for namespace %s from indexer: %w", namespace.Name, err) + } + grNames := make([]relatedresource.Key, 0, len(grs)) + for _, gr := range grs { + // Set the status as InProgress since we have to reconcile the global role + gr.Status.Summary = SummaryInProgress + grNames = append(grNames, relatedresource.Key{Name: gr.Name}) + } + return grNames, nil +} + +// fleetWorkspaceEnqueueGRB enqueues GlobalRole that have set InheritedFleetWorkspacePermissions +// when a FleetWorkspace has changed. +func (g *globalRBACEnqueuer) fleetWorkspaceEnqueueGR(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + + grs, err := g.grCache.List(labels.Everything()) + if err != nil { + return nil, fmt.Errorf("unable to list current GlobalRoles: %w", err) + } + var grToSync []relatedresource.Key + for _, gr := range grs { + if gr.InheritedFleetWorkspacePermissions != nil && (gr.InheritedFleetWorkspacePermissions.WorkspaceVerbs != nil || + gr.InheritedFleetWorkspacePermissions.ResourceRules != nil) { + // Set the status as InProgress since we have to reconcile the global role + gr.Status.Summary = SummaryInProgress + grToSync = append(grToSync, relatedresource.Key{Name: gr.Name}) + } + } + + return grToSync, nil +} + +// clusterRoleEnqueueGRB enqueues GlobalRole when a generated ClusterRole changes. +func (g *globalRBACEnqueuer) clusterRoleEnqueueGR(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + clusterRole, ok := obj.(*v1.ClusterRole) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a ClusterRole", obj) + return nil, nil + } + grOwner, ok := clusterRole.Labels[grOwnerLabel] + if !ok { + // this RoleBinding isn't owned by a GRB, no need to enqueue a GRB + return nil, nil + } + grs, err := g.grCache.GetByIndex(grSafeConcatIndex, grOwner) + if err != nil { + return nil, fmt.Errorf("unable to get GlobalRole %s for RoleBinding %s: %w", grOwner, clusterRole.Name, err) + } + grNames := make([]relatedresource.Key, 0, len(grs)) + for _, gr := range grs { + // Set the status as InProgress since we have to reconcile the global role + gr.Status.Summary = SummaryInProgress + grNames = append(grNames, relatedresource.Key{Name: gr.Name}) + } + + return grNames, nil +} + +// clusterRoleBindingEnqueueGRB enqueues GlobalRoleBinding when a generated ClusterRoleBinding changes. +func (g *globalRBACEnqueuer) clusterRoleBindingEnqueueGRB(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if obj == nil { + return nil, nil + } + clusterRoleBinding, ok := obj.(*v1.ClusterRoleBinding) + if !ok { + logrus.Errorf("unable to convert object: %[1]v, type: %[1]T to a ClusterRole", obj) + return nil, nil + } + grbOwner, ok := clusterRoleBinding.Labels[grbOwnerLabel] + if !ok { + // this RoleBinding isn't owned by a GRB, no need to enqueue a GRB + return nil, nil + } + grbs, err := g.grbCache.GetByIndex(grbSafeConcatIndex, grbOwner) + if err != nil { + return nil, fmt.Errorf("unable to get GlobalRoleBinding %s for ClusterRoleBinding %s: %w", grbOwner, clusterRoleBinding.Name, err) + } + grbNames := make([]relatedresource.Key, 0, len(grbs)) + for _, grb := range grbs { + grbNames = append(grbNames, relatedresource.Key{Name: grb.Name}) + } + + return grbNames, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue_test.go new file mode 100644 index 0000000..d79b432 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/enqueue_test.go @@ -0,0 +1,1155 @@ +package globalroles + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + longName = "long-name--------------------------------------------------------" + safeConcatLongName = "long-name------------------------------------------------cc9244" +) + +func Test_grNsIndexer(t *testing.T) { + t.Parallel() + gr := &v3.GlobalRole{ + NamespacedRules: map[string][]v1.PolicyRule{ + "ns1": nil, + "ns2": nil, + }, + } + res, resErr := grNsIndexer(gr) + require.NoError(t, resErr) + require.Len(t, res, 2) + require.Contains(t, res, "ns1") + require.Contains(t, res, "ns2") + + gr.NamespacedRules = map[string][]v1.PolicyRule{} + res, resErr = grNsIndexer(gr) + require.NoError(t, resErr) + require.Len(t, res, 0) + + gr.NamespacedRules = nil + res, resErr = grNsIndexer(gr) + require.NoError(t, resErr) + require.Len(t, res, 0) +} + +func Test_grbGrIndexer(t *testing.T) { + t.Parallel() + grb := &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + }, + GlobalRoleName: "test-gr", + } + res, resErr := grbGrIndexer(grb) + require.NoError(t, resErr) + require.Equal(t, []string{"test-gr"}, res) +} + +func Test_grSafeConcatIndexer(t *testing.T) { + t.Parallel() + gr := &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "gr1", + }, + } + res, resErr := grSafeConcatIndexer(gr) + require.NoError(t, resErr) + require.Equal(t, []string{"gr1"}, res) + + // Make sure it returns the concatenated name + gr.SetName(longName) + res, resErr = grSafeConcatIndexer(gr) + require.NoError(t, resErr) + require.Equal(t, []string{safeConcatLongName}, res) +} + +func Test_grbSafeConcatIndexer(t *testing.T) { + t.Parallel() + grb := &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "grb1", + }, + } + res, resErr := grbSafeConcatIndexer(grb) + require.NoError(t, resErr) + require.Equal(t, []string{"grb1"}, res) + + // Make sure it returns the concatenated name + grb.SetName(longName) + res, resErr = grbSafeConcatIndexer(grb) + require.NoError(t, resErr) + require.Equal(t, []string{safeConcatLongName}, res) +} + +func Test_enqueueGRBs(t *testing.T) { + t.Parallel() + type testState struct { + grbCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRoleBinding] + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "no inherited roles", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + }, + stateSetup: func(state testState) { + grbs := []*v3.GlobalRoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb-1", + }, + GlobalRoleName: "test-gr", + UserName: "u-123xyz", + }, + } + state.grbCacheMock.EXPECT().GetByIndex(grbGrIndex, "test-gr").Return(grbs, nil) + + }, + wantKeys: []relatedresource.Key{{Name: "test-grb-1"}}, + }, + { + name: "empty inherited roles", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{}, + }, + stateSetup: func(state testState) { + grbs := []*v3.GlobalRoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb-1", + }, + GlobalRoleName: "test-gr", + UserName: "u-123xyz", + }, + } + state.grbCacheMock.EXPECT().GetByIndex(grbGrIndex, "test-gr").Return(grbs, nil) + + }, + wantKeys: []relatedresource.Key{{Name: "test-grb-1"}}, + }, + + { + name: "inherited roles", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{"test-role"}, + }, + stateSetup: func(state testState) { + grbs := []*v3.GlobalRoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb-1", + }, + GlobalRoleName: "test-gr", + UserName: "u-123xyz", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb-2", + }, + GlobalRoleName: "test-gr", + UserName: "u-123abc", + }, + } + state.grbCacheMock.EXPECT().GetByIndex(grbGrIndex, "test-gr").Return(grbs, nil) + }, + wantKeys: []relatedresource.Key{{Name: "test-grb-1"}, {Name: "test-grb-2"}}, + }, + { + name: "inherited roles, indexer error", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{"test-role"}, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().GetByIndex(grbGrIndex, "test-gr").Return(nil, fmt.Errorf("server not available")) + }, + wantError: true, + }, + { + name: "inherited roles, no grbs", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{"test-role"}, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().GetByIndex(grbGrIndex, "test-gr").Return([]*v3.GlobalRoleBinding{}, nil) + }, + wantKeys: nil, + }, + { + name: "input not a global role", + inputObject: &v3.ClusterRoleTemplateBinding{}, + wantError: false, + wantKeys: nil, + }, + { + name: "nil input", + inputObject: nil, + wantKeys: nil, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grbCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl) + state := testState{ + grbCacheMock: grbCache, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grbCache: grbCache, + } + res, resErr := enqueuer.enqueueGRBs("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} + +func Test_clusterEnqueueGRs(t *testing.T) { + t.Parallel() + type testState struct { + grCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + clusterClientMock *fake.MockNonNamespacedClientInterface[*v3.Cluster, *v3.ClusterList] + } + inheritedGR := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{"test-role"}, + } + noInheritedGR := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-no-gr", + }, + } + emptyInheritedGR := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-no-gr", + }, + InheritedClusterRoles: []string{}, + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "cluster already synced", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + initialSyncAnnotation: "true", + }, + }, + }, + stateSetup: func(state testState) { + // current implementation doesn't call this, but we want to setup the state in case + // call order changes slightly + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{&inheritedGR}, nil).AnyTimes() + }, + wantKeys: nil, + }, + { + name: "cluster not synced", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{&inheritedGR, &noInheritedGR, &emptyInheritedGR}, nil) + state.clusterClientMock.EXPECT().Get("test-cluster", gomock.Any()).Return( + &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + "some-annotation": "here", + }, + }, + }, nil) + updCluster := v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + "some-annotation": "here", + initialSyncAnnotation: "true", + }, + }, + } + state.clusterClientMock.EXPECT().Update(&updCluster).Return(&updCluster, nil) + }, + wantKeys: []relatedresource.Key{{Name: inheritedGR.Name}}, + }, + { + name: "cluster not synced - no annotations", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{&inheritedGR, &noInheritedGR, &emptyInheritedGR}, nil) + state.clusterClientMock.EXPECT().Get("test-cluster", gomock.Any()).Return( + &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, nil) + updCluster := v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + initialSyncAnnotation: "true", + }, + }, + } + state.clusterClientMock.EXPECT().Update(&updCluster).Return(&updCluster, nil) + }, + wantKeys: []relatedresource.Key{{Name: inheritedGR.Name}}, + }, + { + name: "input not a cluster", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + }, + InheritedClusterRoles: []string{"test-role"}, + }, + wantError: false, + wantKeys: nil, + }, + { + name: "nil input", + inputObject: nil, + wantKeys: nil, + }, + { + name: "cluster not synced, gr list error", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return(nil, fmt.Errorf("server unavailable")) + }, + wantKeys: nil, + wantError: true, + }, + { + name: "cluster not synced, get cluster error", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{&inheritedGR}, nil) + state.clusterClientMock.EXPECT().Get("test-cluster", gomock.Any()).Return(nil, fmt.Errorf("server unavailable")) + }, + wantKeys: []relatedresource.Key{{Name: inheritedGR.Name}}, + }, + { + name: "cluster not synced, update cluster error", + inputObject: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{&inheritedGR}, nil) + state.clusterClientMock.EXPECT().Get("test-cluster", gomock.Any()).Return(&v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + "some-annotation": "here", + }, + }, + }, nil) + state.clusterClientMock.EXPECT().Update(&v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Annotations: map[string]string{ + "some-annotation": "here", + initialSyncAnnotation: "true", + }, + }, + }).Return(nil, fmt.Errorf("server unavailable")) + }, + wantKeys: []relatedresource.Key{{Name: inheritedGR.Name}}, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl) + clusterClient := fake.NewMockNonNamespacedClientInterface[*v3.Cluster, *v3.ClusterList](ctrl) + state := testState{ + grCacheMock: grCache, + clusterClientMock: clusterClient, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grCache: grCache, + clusterClient: clusterClient, + } + res, resErr := enqueuer.clusterEnqueueGRs("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} + +func Test_crtbEnqueueGRB(t *testing.T) { + t.Parallel() + type testState struct { + grbCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRoleBinding] + } + testGrb := v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + }, + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "crtb not owned by grb", + inputObject: &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-crtb", + }, + }, + wantKeys: nil, + }, + { + name: "crtb owned by existing grb", + inputObject: &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-crtb", + Labels: map[string]string{ + grbOwnerLabel: testGrb.Name, + }, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().Get(testGrb.Name).Return(&testGrb, nil) + }, + wantKeys: []relatedresource.Key{{Name: testGrb.Name}}, + }, + { + name: "crtb owned by non-existent grb", + inputObject: &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-crtb", + Labels: map[string]string{ + grbOwnerLabel: testGrb.Name, + }, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().Get(testGrb.Name).Return(nil, apierrors.NewNotFound(schema.GroupResource{ + Group: v3.SchemeGroupVersion.Group, + Resource: v3.GlobalRoleResourceName, + }, testGrb.Name)) + }, + wantKeys: nil, + }, + { + name: "crtb owned by grb, error when confirming grb existence", + inputObject: &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-crtb", + Labels: map[string]string{ + grbOwnerLabel: testGrb.Name, + }, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().Get(testGrb.Name).Return(nil, fmt.Errorf("server unavailable")) + }, + wantError: true, + }, + { + name: "invalid input object type", + inputObject: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + }, + }, + wantKeys: nil, + wantError: false, + }, + { + name: "nil input object", + inputObject: nil, + wantKeys: nil, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grbCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl) + state := testState{ + grbCacheMock: grbCache, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grbCache: grbCache, + } + res, resErr := enqueuer.crtbEnqueueGRB("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} + +func Test_roleEnqueueGR(t *testing.T) { + t.Parallel() + type testState struct { + grCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "object is nil", + inputObject: nil, + wantError: false, + }, + { + name: "object is not a role", + inputObject: &v3.GlobalRole{}, + wantError: false, + }, + { + name: "role does not have owning GR", + inputObject: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + }, + }, + wantError: false, + }, + { + name: "GR get fails", + inputObject: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + Labels: map[string]string{grOwnerLabel: "test-GR"}, + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().GetByIndex(grSafeConcatIndex, "test-GR").Return(nil, fmt.Errorf("error")) + }, + wantError: true, + }, + { + name: "GR gets enqueued", + inputObject: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + Labels: map[string]string{grOwnerLabel: "test-GR"}, + }, + }, + stateSetup: func(state testState) { + gr := &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-GR", + }, + } + state.grCacheMock.EXPECT().GetByIndex(grSafeConcatIndex, "test-GR").Return([]*v3.GlobalRole{gr}, nil) + }, + wantKeys: []relatedresource.Key{{Name: "test-GR"}}, + wantError: false, + }, + { + name: "GR with long name gets enqueued", + inputObject: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + Labels: map[string]string{grOwnerLabel: safeConcatLongName}, + }, + }, + stateSetup: func(state testState) { + gr := &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: longName, + }, + } + state.grCacheMock.EXPECT().GetByIndex(grSafeConcatIndex, safeConcatLongName).Return([]*v3.GlobalRole{gr}, nil) + }, + wantKeys: []relatedresource.Key{{Name: longName}}, + wantError: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl) + state := testState{ + grCacheMock: grCache, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grCache: grCache, + } + res, resErr := enqueuer.roleEnqueueGR("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} + +func Test_roleBindingEnqueueGRB(t *testing.T) { + t.Parallel() + type testState struct { + grbCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRoleBinding] + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "object is nil", + inputObject: nil, + wantError: false, + }, + { + name: "object is not a roleBinding", + inputObject: &v3.GlobalRole{}, + wantError: false, + }, + { + name: "roleBinding does not have owning GR", + inputObject: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-roleBinding", + }, + }, + wantError: false, + }, + { + name: "GRB get fails", + inputObject: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-roleBinding", + Labels: map[string]string{grbOwnerLabel: "test-GRB"}, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().GetByIndex(grbSafeConcatIndex, "test-GRB").Return(nil, fmt.Errorf("error")) + }, + wantError: true, + }, + { + name: "GRB gets enqueued", + inputObject: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-roleBinding", + Labels: map[string]string{grbOwnerLabel: "test-GRB"}, + }, + }, + stateSetup: func(state testState) { + grb := &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-GRB", + }, + } + state.grbCacheMock.EXPECT().GetByIndex(grbSafeConcatIndex, "test-GRB").Return([]*v3.GlobalRoleBinding{grb}, nil) + }, + wantKeys: []relatedresource.Key{{Name: "test-GRB"}}, + wantError: false, + }, + { + name: "GRB with long name gets enqueued", + inputObject: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-roleBinding", + Labels: map[string]string{grbOwnerLabel: safeConcatLongName}, + }, + }, + stateSetup: func(state testState) { + grb := &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: longName, + }, + } + state.grbCacheMock.EXPECT().GetByIndex(grbSafeConcatIndex, safeConcatLongName).Return([]*v3.GlobalRoleBinding{grb}, nil) + }, + wantKeys: []relatedresource.Key{{Name: longName}}, + wantError: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grbCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl) + state := testState{ + grbCacheMock: grbCache, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grbCache: grbCache, + } + res, resErr := enqueuer.roleBindingEnqueueGRB("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} + +func Test_namespaceEnqueueGR(t *testing.T) { + t.Parallel() + type testState struct { + grCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + } + tests := []struct { + name string + stateSetup func(state testState) + inputObject runtime.Object + wantKeys []relatedresource.Key + wantError bool + }{ + { + name: "object is nil", + inputObject: nil, + wantError: false, + }, + { + name: "object is not a namespace", + inputObject: &v3.GlobalRole{}, + wantError: false, + }, + { + name: "namespace not in a NamespacedRule", + inputObject: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().GetByIndex(grNsIndex, "ns1").Return([]*v3.GlobalRole{}, nil) + }, + wantError: false, + }, + { + name: "get namespace fails", + inputObject: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().GetByIndex(grNsIndex, "ns1").Return(nil, fmt.Errorf("error")) + }, + wantError: true, + }, + { + name: "multiple grs are returned", + inputObject: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns1", + }, + }, + stateSetup: func(state testState) { + grs := []*v3.GlobalRole{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "gr1", + }, + NamespacedRules: map[string][]v1.PolicyRule{ + "ns1": nil, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "gr2", + }, + NamespacedRules: map[string][]v1.PolicyRule{ + "ns1": nil, + }, + }, + } + state.grCacheMock.EXPECT().GetByIndex(grNsIndex, "ns1").Return(grs, nil) + }, + wantKeys: []relatedresource.Key{ + {Name: "gr1"}, + {Name: "gr2"}, + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + grCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl) + state := testState{ + grCacheMock: grCache, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + enqueuer := globalRBACEnqueuer{ + grCache: grCache, + } + res, resErr := enqueuer.namespaceEnqueueGR("", "", test.inputObject) + require.Len(t, res, len(test.wantKeys)) + for _, key := range test.wantKeys { + require.Contains(t, res, key) + } + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + }) + } +} +func TestClusterRoleEnqueueGR(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + grCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + } + + tests := map[string]struct { + obj runtime.Object + stateSetup func(state testState) + wantKeys []relatedresource.Key + wantErrorMessage string + }{ + "enqueue grb if cr contains the label authz.management.cattle.io/grb-owner": { + obj: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + grOwnerLabel: "gr", + }, + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().GetByIndex(grSafeConcatIndex, "gr").Return([]*v3.GlobalRole{{ + ObjectMeta: metav1.ObjectMeta{Name: "gr"}, + }}, nil) + }, + wantKeys: []relatedresource.Key{ + { + Name: "gr", + }, + }, + }, + "don't enqueue grb if cr doesn't contain the label authz.management.cattle.io/grb-owner": { + obj: &v1.ClusterRole{}, + wantKeys: nil, + }, + "nil obj": { + obj: nil, + wantKeys: nil, + }, + "can't cast obj to ClusterRole": { + obj: &v1.Role{}, + wantKeys: nil, + }, + "can't get GlobalRole from cache": { + obj: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + grOwnerLabel: "gr", + }, + }, + }, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().GetByIndex(grSafeConcatIndex, "gr").Return(nil, errors.New("unexpected error")) + }, + wantKeys: nil, + wantErrorMessage: "unable to get GlobalRole gr for RoleBinding : unexpected error", + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + state := testState{ + grCacheMock: fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + g := globalRBACEnqueuer{ + grCache: state.grCacheMock, + } + keys, err := g.clusterRoleEnqueueGR("", "", test.obj) + if test.wantErrorMessage == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.wantErrorMessage) + } + assert.Equal(t, test.wantKeys, keys) + }) + } +} + +func TestClusterRoleBindingEnqueueGRB(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + grbCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRoleBinding] + } + + tests := map[string]struct { + obj runtime.Object + stateSetup func(state testState) + wantKeys []relatedresource.Key + wantErrorMessage string + }{ + "enqueue grb if cr contains the label authz.management.cattle.io/grb-fw-owner": { + obj: &v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + grbOwnerLabel: "grb", + }, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().GetByIndex(grbSafeConcatIndex, "grb").Return([]*v3.GlobalRoleBinding{{ + ObjectMeta: metav1.ObjectMeta{Name: "grb"}, + }}, nil) + }, + wantKeys: []relatedresource.Key{ + { + Name: "grb", + }, + }, + }, + "don't enqueue grb if cr doesn't contain the label authz.management.cattle.io/grb-fw-owner": { + obj: &v1.ClusterRoleBinding{}, + wantKeys: nil, + }, + "nil obj": { + obj: nil, + wantKeys: nil, + }, + "can't cast obj to ClusterRoleBinding": { + obj: &v1.Role{}, + wantKeys: nil, + }, + "can't get GlobalRoleBinding from cache": { + obj: &v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + grbOwnerLabel: "grb", + }, + }, + }, + stateSetup: func(state testState) { + state.grbCacheMock.EXPECT().GetByIndex(grbSafeConcatIndex, "grb").Return(nil, errors.New("unexpected error")) + }, + wantKeys: nil, + wantErrorMessage: "unable to get GlobalRoleBinding grb for ClusterRoleBinding : unexpected error", + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + state := testState{ + grbCacheMock: fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + g := globalRBACEnqueuer{ + grbCache: state.grbCacheMock, + } + keys, err := g.clusterRoleBindingEnqueueGRB("", "", test.obj) + if test.wantErrorMessage == "" { + assert.NoError(t, err) + } else { + assert.EqualError(t, err, test.wantErrorMessage) + } + assert.Equal(t, test.wantKeys, keys) + }) + } +} + +func TestFleetWorkspaceEnqueueGRB(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + grCacheMock *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + } + + tests := map[string]struct { + obj runtime.Object + stateSetup func(state testState) + wantKeys []relatedresource.Key + wantErrMessage string + }{ + "enqueue just the GlobalRoles with InheritedFleetWorkspacePermissions": { + obj: &v3.FleetWorkspace{}, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return([]*v3.GlobalRole{ + { + ObjectMeta: metav1.ObjectMeta{Name: "gr1"}, + InheritedFleetWorkspacePermissions: &v3.FleetWorkspacePermission{ + ResourceRules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"fleet.cattle.io"}, + Resources: []string{"*"}, + }, + }, + WorkspaceVerbs: []string{"get"}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "gr2"}, + }, + }, nil) + }, + wantKeys: []relatedresource.Key{ + { + Name: "gr1", + }, + }, + }, + "error listing GlobalRoles": { + obj: &v3.FleetWorkspace{}, + stateSetup: func(state testState) { + state.grCacheMock.EXPECT().List(labels.Everything()).Return(nil, errors.New("unexpected error")) + }, + wantErrMessage: "unable to list current GlobalRoles: unexpected error", + }, + "nil obj": { + obj: nil, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + state := testState{ + grCacheMock: fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + g := globalRBACEnqueuer{ + grCache: state.grCacheMock, + } + keys, err := g.fleetWorkspaceEnqueueGR("", "", test.obj) + if test.wantErrMessage != "" { + assert.EqualError(t, err, test.wantErrMessage) + } + assert.Equal(t, test.wantKeys, keys) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler.go new file mode 100644 index 0000000..38aac2c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler.go @@ -0,0 +1,225 @@ +package globalroles + +import ( + "errors" + "fmt" + "reflect" + + wrangler "github.com/rancher/wrangler/v3/pkg/name" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +var ( + errReconcileResourceRulesBinding = fmt.Errorf("reconciling fleet role bindings failed") + errReconcileWorkspaceVerbsBinding = fmt.Errorf("reconciling fleet workspace verbs cluster role binding failed") +) + +// fleetWorkspaceBindingHandler manages Bindings created for the InheritedFleetWorkspacePermissions field. +type fleetWorkspaceBindingHandler struct { + crbClient rbacv1.ClusterRoleBindingController + crbCache rbacv1.ClusterRoleBindingCache + crCache rbacv1.ClusterRoleCache + grCache mgmtcontroller.GlobalRoleCache + rbClient rbacv1.RoleBindingController + rbCache rbacv1.RoleBindingCache + fwCache mgmtcontroller.FleetWorkspaceCache +} + +func newFleetWorkspaceBindingHandler(management *config.ManagementContext) *fleetWorkspaceBindingHandler { + return &fleetWorkspaceBindingHandler{ + crbClient: management.Wrangler.RBAC.ClusterRoleBinding(), + crbCache: management.Wrangler.RBAC.ClusterRoleBinding().Cache(), + grCache: management.Wrangler.Mgmt.GlobalRole().Cache(), + rbClient: management.Wrangler.RBAC.RoleBinding(), + rbCache: management.Wrangler.RBAC.RoleBinding().Cache(), + fwCache: management.Wrangler.Mgmt.FleetWorkspace().Cache(), + crCache: management.Wrangler.RBAC.ClusterRole().Cache(), + } +} + +// ReconcileFleetWorkspacePermissionsBindings reconciles backing RoleBindings and ClusterRoleBindings created for granting permission +// to fleet workspaces. +func (h *fleetWorkspaceBindingHandler) reconcileFleetWorkspacePermissionsBindings(globalRoleBinding *v3.GlobalRoleBinding) error { + globalRole, err := h.grCache.Get(globalRoleBinding.GlobalRoleName) + if err != nil { + return fmt.Errorf("couldn't get globalRole: %w", err) + } + var returnErr error + if err = h.reconcileResourceRulesBindings(globalRoleBinding, globalRole); err != nil { + returnErr = errors.Join(returnErr, errReconcileResourceRulesBinding, err) + } + if err = h.reconcileWorkspaceVerbsBindings(globalRoleBinding, globalRole); err != nil { + returnErr = errors.Join(returnErr, errReconcileWorkspaceVerbsBinding, err) + } + + return returnErr +} + +func (h *fleetWorkspaceBindingHandler) reconcileResourceRulesBindings(grb *v3.GlobalRoleBinding, gr *v3.GlobalRole) error { + fleetWorkspaces, err := h.fwCache.List(labels.Everything()) + if err != nil { + return fmt.Errorf("couldn't list fleetWorkspaces: %w", err) + } + + var returnError error + for _, fleetWorkspace := range fleetWorkspaces { + if fleetWorkspace.Name == localFleetWorkspace { + continue + } + desiredRB := backingRoleBinding(grb, gr, fleetWorkspace.Name) + rb, err := h.rbCache.Get(fleetWorkspace.Name, wrangler.SafeConcatName(grb.Name)) + if err != nil { + if !apierrors.IsNotFound(err) { + returnError = errors.Join(returnError, fmt.Errorf("couldn't get RoleBinding %s : %w", wrangler.SafeConcatName(grb.Name), err)) + continue + } + if gr.InheritedFleetWorkspacePermissions != nil && gr.InheritedFleetWorkspacePermissions.ResourceRules != nil { + _, err = h.crCache.Get(desiredRB.RoleRef.Name) + if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't get ClusterRole: %w", err)) + continue + } + _, err = h.rbClient.Create(desiredRB) + if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't create RoleBinding: %w", err)) + } + } + continue + } + + if gr.InheritedFleetWorkspacePermissions == nil || gr.InheritedFleetWorkspacePermissions.ResourceRules == nil { + err := h.rbClient.Delete(rb.Namespace, rb.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + returnError = errors.Join(returnError, fmt.Errorf("couldn't clean up RoleBinding: %w", err)) + } + continue + } + if !reflect.DeepEqual(rb.Subjects, desiredRB.Subjects) || + !reflect.DeepEqual(rb.RoleRef, desiredRB.RoleRef) { + // undo modifications if rb has changed. + err := h.rbClient.Delete(rb.Namespace, rb.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + returnError = errors.Join(returnError, fmt.Errorf("couldn't delete RoleBinding: %w", err)) + continue + } + _, err = h.rbClient.Create(desiredRB) + if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't create RoleBinding: %w", err)) + } + } + } + + return returnError +} + +func (h *fleetWorkspaceBindingHandler) reconcileWorkspaceVerbsBindings(grb *v3.GlobalRoleBinding, gr *apimgmtv3.GlobalRole) error { + crbName := wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName) + desiredCRB := backingClusterRoleBinding(grb, gr, crbName) + + crb, err := h.crbCache.Get(crbName) + if err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't get ClusterRoleBinding: %w", err) + } + if gr.InheritedFleetWorkspacePermissions != nil && gr.InheritedFleetWorkspacePermissions.ResourceRules != nil { + _, err = h.crCache.Get(desiredCRB.RoleRef.Name) + if err != nil { + return fmt.Errorf("couldn't get ClusterRole: %w", err) + } + _, err = h.crbClient.Create(desiredCRB) + if err != nil { + return fmt.Errorf("couldn't create ClusterRoleBinding: %w", err) + } + } + return nil + } + + if gr.InheritedFleetWorkspacePermissions == nil || gr.InheritedFleetWorkspacePermissions.ResourceRules == nil { + err := h.crbClient.Delete(crbName, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't clean up ClusterRoleBinding: %w", err) + } + return nil + } + if !reflect.DeepEqual(crb.Subjects, desiredCRB.Subjects) || + !reflect.DeepEqual(crb.RoleRef, desiredCRB.RoleRef) { + // undo modifications if crb has changed. + err := h.crbClient.Delete(crb.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't delete ClusterRoleBinding: %w", err) + } + _, err = h.crbClient.Create(desiredCRB) + + return err + } + + return nil +} + +func backingClusterRoleBinding(grb *v3.GlobalRoleBinding, gr *v3.GlobalRole, crbName string) *v1.ClusterRoleBinding { + return &v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: v3.GlobalRoleBindingGroupVersionKind.Kind, + Name: grb.Name, + UID: grb.UID, + }, + }, + Labels: map[string]string{ + grbOwnerLabel: wrangler.SafeConcatName(grb.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + RoleRef: v1.RoleRef{ + APIGroup: v1.GroupName, + Kind: "ClusterRole", + Name: wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), + }, + Subjects: []v1.Subject{rbac.GetGRBSubject(grb)}, + } +} + +func backingRoleBinding(grb *v3.GlobalRoleBinding, gb *v3.GlobalRole, fwName string) *v1.RoleBinding { + return &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grb.Name), + Namespace: fwName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: v3.GlobalRoleBindingGroupVersionKind.Kind, + Name: grb.Name, + UID: grb.UID, + }, + }, + Labels: map[string]string{ + grbOwnerLabel: wrangler.SafeConcatName(grb.Name), + fleetWorkspacePermissionLabel: "true", + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + RoleRef: v1.RoleRef{ + APIGroup: v1.GroupName, + Kind: "ClusterRole", + Name: wrangler.SafeConcatName(gb.Name, fleetWorkspaceClusterRulesName), + }, + Subjects: []v1.Subject{ + rbac.GetGRBSubject(grb), + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler_test.go new file mode 100644 index 0000000..2db4b08 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_binding_handler_test.go @@ -0,0 +1,519 @@ +package globalroles + +import ( + "testing" + + wrangler "github.com/rancher/wrangler/v3/pkg/name" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + genv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rancherbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + rbac "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + grName = "gr" + grUID = "9cf141b8-54ab-4711-8e43-eb1fc0a189a8" + grbName = "grb" + grbUID = "3267582b-96eb-4752-81de-cb33e7d8f3e7" + user = "user" +) + +var ( + grVerbs = &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + InheritedFleetWorkspacePermissions: &v3.FleetWorkspacePermission{ + ResourceRules: []rbac.PolicyRule{ + { + Verbs: []string{"get", "list"}, + APIGroups: []string{"fleet.cattle.io"}, + Resources: []string{"gitrepos", "bundles"}, + }, + }, + WorkspaceVerbs: []string{"get", "list"}, + }, + } + grVerbsNoFleetPermissions = &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + } + grb = &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + UID: grbUID, + }, + UserName: user, + GlobalRoleName: grName, + } +) + +func TestReconcileFleetWorkspacePermissionsBindings(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + crbClient *fake.MockNonNamespacedControllerInterface[*rbac.ClusterRoleBinding, *rbac.ClusterRoleBindingList] + crbCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRoleBinding] + crCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRole] + grCache *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + rbClient *fake.MockControllerInterface[*rbac.RoleBinding, *rbac.RoleBindingList] + rbCache *fake.MockCacheInterface[*rbac.RoleBinding] + fwCache *fake.MockNonNamespacedCacheInterface[*v3.FleetWorkspace] + } + + tests := map[string]struct { + stateSetup func(state testState) + grb *v3.GlobalRoleBinding + }{ + "backing RoleBindings and ClusterRoleBindings are created for a new GlobalRoleBinding": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + + grb: grb, + }, + "backing RoleBindings and ClusterRoleBindings are updated with new content": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + rb := mockRoleBinding(grb, grVerbs, "fleet-default") + rb.Subjects = []rbac.Subject{ + { + Name: "modified", + }, + } + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(mockRoleBinding(grb, grVerbs, "fleet-default"), nil) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName)), nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + grb: grb, + }, + "no RoleBindings and ClusterRoleBindings are created or updated if inheritedFleetWorkspaceRoles not provided": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbsNoFleetPermissions, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + + grb: grb, + }, + "RoleBindings and ClusterRoleBinding are deleted if inheritedFleetWorkspaceRoles is set to nil": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbsNoFleetPermissions, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(&rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + Namespace: "fleet-default", + }, + }, nil) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), + }, + }, nil) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}) + }, + + grb: grb, + }, + "RoleBindings and ClusterRoleBinding when inheritedFleetWorkspaceRoles is set to nil, and roles were previously deleted": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbsNoFleetPermissions, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(&rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + Namespace: "fleet-default", + }, + }, nil) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), + }, + }, nil) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}).Return(errors.NewNotFound(schema.GroupResource{}, "")) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(errors.NewNotFound(schema.GroupResource{}, "")) + }, + + grb: grb, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + state := testState{ + crbClient: fake.NewMockNonNamespacedControllerInterface[*rbac.ClusterRoleBinding, *rbac.ClusterRoleBindingList](ctrl), + crbCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRoleBinding](ctrl), + crCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRole](ctrl), + grCache: fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl), + rbClient: fake.NewMockControllerInterface[*rbac.RoleBinding, *rbac.RoleBindingList](ctrl), + rbCache: fake.NewMockCacheInterface[*rbac.RoleBinding](ctrl), + fwCache: fake.NewMockNonNamespacedCacheInterface[*v3.FleetWorkspace](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + h := fleetWorkspaceBindingHandler{ + crbClient: state.crbClient, + crbCache: state.crbCache, + crCache: state.crCache, + grCache: state.grCache, + rbClient: state.rbClient, + rbCache: state.rbCache, + fwCache: state.fwCache, + } + + err := h.reconcileFleetWorkspacePermissionsBindings(test.grb) + + assert.Equal(t, err, nil) + }) + } +} + +func TestReconcileFleetWorkspacePermissionsBindings_errors(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + grNotFoundErr := errors.NewNotFound(schema.GroupResource{ + Group: "management.cattle.io", + Resource: "GlobalRole", + }, grName) + unexpectedErr := errors.NewServiceUnavailable("unexpected error") + type testState struct { + crbClient *fake.MockNonNamespacedControllerInterface[*rbac.ClusterRoleBinding, *rbac.ClusterRoleBindingList] + crbCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRoleBinding] + crCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRole] + grCache *fake.MockNonNamespacedCacheInterface[*v3.GlobalRole] + rbClient *fake.MockControllerInterface[*rbac.RoleBinding, *rbac.RoleBindingList] + rbCache *fake.MockCacheInterface[*rbac.RoleBinding] + fwCache *fake.MockNonNamespacedCacheInterface[*v3.FleetWorkspace] + } + tests := map[string]struct { + stateSetup func(state testState) + wantErrs []error + }{ + "GlobalRole not found": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(nil, grNotFoundErr) + }, + wantErrs: []error{grNotFoundErr}, + }, + "Error retrieving fleetworkspaces": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(nil, unexpectedErr) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileResourceRulesBinding, unexpectedErr}, + }, + "Error creating backing RoleBindings for permission rules": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")).Return(nil, unexpectedErr) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileResourceRulesBinding, unexpectedErr}, + }, + "Error deleting backing RoleBindings for permission rules when it has changed": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(&rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fleet-default", + Name: grbName, + }, + }, nil) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}).Return(unexpectedErr) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileResourceRulesBinding, unexpectedErr}, + }, + "Error re-creating backing RoleBindings for permission rules when it has changed": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(&rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "fleet-default", + Name: grbName, + }, + }, nil) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")).Return(nil, unexpectedErr) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileResourceRulesBinding, unexpectedErr}, + }, + "Error creating backing ClusterRoleBinding for workspace verbs": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error deleting backing ClusterRoleBinding for workspace verbs when it has changed": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName)}, + }, nil) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(unexpectedErr) + state.rbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error re-creating backing ClusterRoleBinding for workspace verbs when it has changed": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName)}, + }, nil) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error creating backing ClusterRoleBinding for workspace verbs when it has changed": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, nil) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName)}, + }, nil) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(nil) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error getting RoleBinding": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, unexpectedErr) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{Name: wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName)}, + }, nil) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error getting ClusterRoleBinding": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error getting ClusterRole for resource rules": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crbClient.EXPECT().Create(mockClusterRoleBinding(grb, grVerbs, wrangler.SafeConcatName(grb.Name, fleetWorkspaceVerbsName))).Return(nil, unexpectedErr) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error getting ClusterRole for workspace verbs": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbs, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.rbClient.EXPECT().Create(mockRoleBinding(grb, grVerbs, "fleet-default")) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName)).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, unexpectedErr}, + }, + "Error deleting RoleBindings and ClusterRoleBinding inheritedFleetWorkspaceRoles is set to nil": { + stateSetup: func(state testState) { + state.grCache.EXPECT().Get(grName).Return(grVerbsNoFleetPermissions, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.rbCache.EXPECT().Get("fleet-default", grbName).Return(&rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + Namespace: "fleet-default", + }, + }, nil) + state.crbCache.EXPECT().Get(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), + }, + }, nil) + state.rbClient.EXPECT().Delete("fleet-default", grbName, &metav1.DeleteOptions{}).Return(unexpectedErr) + state.crbClient.EXPECT().Delete(wrangler.SafeConcatName(grbName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(unexpectedErr) + }, + wantErrs: []error{errReconcileWorkspaceVerbsBinding, errReconcileResourceRulesBinding, unexpectedErr}, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + state := testState{ + crbClient: fake.NewMockNonNamespacedControllerInterface[*rbac.ClusterRoleBinding, *rbac.ClusterRoleBindingList](ctrl), + crbCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRoleBinding](ctrl), + crCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRole](ctrl), + grCache: fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRole](ctrl), + rbClient: fake.NewMockControllerInterface[*rbac.RoleBinding, *rbac.RoleBindingList](ctrl), + rbCache: fake.NewMockCacheInterface[*rbac.RoleBinding](ctrl), + fwCache: fake.NewMockNonNamespacedCacheInterface[*v3.FleetWorkspace](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + h := fleetWorkspaceBindingHandler{ + crbClient: state.crbClient, + crbCache: state.crbCache, + grCache: state.grCache, + crCache: state.crCache, + rbClient: state.rbClient, + rbCache: state.rbCache, + fwCache: state.fwCache, + } + + err := h.reconcileFleetWorkspacePermissionsBindings(&v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + UID: grbUID, + }, + UserName: user, + GlobalRoleName: grName, + }) + + for _, wantErr := range test.wantErrs { + assert.ErrorIs(t, err, wantErr) + } + }) + } +} + +func mockClusterRoleBinding(grb *v3.GlobalRoleBinding, gr *v3.GlobalRole, crbName string) *rbac.ClusterRoleBinding { + return &rbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: genv3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: genv3.GlobalRoleBindingGroupVersionKind.Kind, + Name: grb.Name, + UID: grb.UID, + }, + }, + Labels: map[string]string{ + grbOwnerLabel: wrangler.SafeConcatName(grb.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + RoleRef: rbac.RoleRef{ + APIGroup: rbac.GroupName, + Kind: "ClusterRole", + Name: wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), + }, + Subjects: []rbac.Subject{rancherbac.GetGRBSubject(grb)}, + } +} + +func mockRoleBinding(grb *v3.GlobalRoleBinding, gb *v3.GlobalRole, fwName string) *rbac.RoleBinding { + return &rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grb.Name), + Namespace: fwName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: genv3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: genv3.GlobalRoleBindingGroupVersionKind.Kind, + Name: grb.Name, + UID: grb.UID, + }, + }, + Labels: map[string]string{ + grbOwnerLabel: wrangler.SafeConcatName(grb.Name), + fleetWorkspacePermissionLabel: "true", + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + RoleRef: rbac.RoleRef{ + APIGroup: rbac.GroupName, + Kind: "ClusterRole", + Name: wrangler.SafeConcatName(gb.Name, fleetWorkspaceClusterRulesName), + }, + Subjects: []rbac.Subject{ + rancherbac.GetGRBSubject(grb), + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler.go new file mode 100644 index 0000000..2755eb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler.go @@ -0,0 +1,204 @@ +package globalroles + +import ( + "errors" + "fmt" + + "github.com/rancher/rancher/pkg/controllers" + + wrangler "github.com/rancher/wrangler/v3/pkg/name" + + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + localFleetWorkspace = "fleet-local" + fleetWorkspaceClusterRulesName = "fwcr" + fleetWorkspaceVerbsName = "fwv" +) + +var ( + errReconcileResourceRules = fmt.Errorf("reconciling fleet resource rules cluster role failed") + errReconcileWorkspaceVerbs = fmt.Errorf("reconciling fleet workspace verbs cluster role failed") +) + +// fleetWorkspaceRoleHandler manages ClusterRoles created for the InheritedFleetWorkspacePermissions field. It manages 2 roles: +// - 1) CR for ResourceRules +// - 2) CR for WorkspaceVerbs +type fleetWorkspaceRoleHandler struct { + crClient rbacv1.ClusterRoleController + crCache rbacv1.ClusterRoleCache + fwCache mgmtcontroller.FleetWorkspaceCache +} + +func newFleetWorkspaceRoleHandler(management *config.ManagementContext) *fleetWorkspaceRoleHandler { + return &fleetWorkspaceRoleHandler{ + crClient: management.Wrangler.RBAC.ClusterRole(), + crCache: management.Wrangler.RBAC.ClusterRole().Cache(), + fwCache: management.Wrangler.Mgmt.FleetWorkspace().Cache(), + } +} + +// ReconcileFleetWorkspacePermissions reconciles backing ClusterRoles created for granting permission to fleet workspaces. +func (h *fleetWorkspaceRoleHandler) reconcileFleetWorkspacePermissions(gr *v3.GlobalRole) error { + var returnErr error + if err := h.reconcileResourceRules(gr); err != nil { + returnErr = errors.Join(returnErr, errReconcileResourceRules, err) + } + if err := h.reconcileWorkspaceVerbs(gr); err != nil { + returnErr = errors.Join(returnErr, errReconcileWorkspaceVerbs, err) + } + + return returnErr +} + +func (h *fleetWorkspaceRoleHandler) reconcileResourceRules(gr *v3.GlobalRole) error { + crName := wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName) + cr, err := h.crCache.Get(crName) + if err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't get ClusterRole: %w", err) + } + if gr.InheritedFleetWorkspacePermissions != nil && gr.InheritedFleetWorkspacePermissions.ResourceRules != nil { + _, err := h.crClient.Create(backingResourceRulesClusterRole(gr, crName)) + if err != nil { + return fmt.Errorf("couldn't create ClusterRole: %w", err) + } + } + return nil + } + + if gr.InheritedFleetWorkspacePermissions == nil || gr.InheritedFleetWorkspacePermissions.ResourceRules == nil { + err := h.crClient.Delete(crName, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't delete ClusterRole: %w", err) + } + return nil + } + if !equality.Semantic.DeepEqual(cr.Rules, gr.InheritedFleetWorkspacePermissions.ResourceRules) { + // undo modifications if cr has changed + cr.Rules = gr.InheritedFleetWorkspacePermissions.ResourceRules + _, err := h.crClient.Update(cr) + if err != nil { + return fmt.Errorf("couldn't update ClusterRole: %w", err) + } + } + + return nil +} + +func (h *fleetWorkspaceRoleHandler) reconcileWorkspaceVerbs(gr *v3.GlobalRole) error { + crName := wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName) + cr, err := h.crCache.Get(crName) + crMissing := apierrors.IsNotFound(err) + if err != nil && !crMissing { + return err + } + if gr.InheritedFleetWorkspacePermissions == nil || gr.InheritedFleetWorkspacePermissions.WorkspaceVerbs == nil { + if !crMissing { + err := h.crClient.Delete(crName, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("couldn't delete ClusterRole: %w", err) + } + } + return nil + } + + workspacesNames, err := h.fleetWorkspaceNames() + if err != nil { + return fmt.Errorf("couldn't get fleet workspace names: %w", err) + } + if len(workspacesNames) == 0 { + // skip if there are no workspaces besides local + return nil + } + desiredCR := backingWorkspaceVerbsClusterRole(gr, crName, workspacesNames) + if crMissing { + _, err := h.crClient.Create(desiredCR) + if err != nil { + return fmt.Errorf("couldn't create ClusterRole: %w", err) + } + } else if !equality.Semantic.DeepEqual(cr.Rules, desiredCR.Rules) { + // undo modifications if cr has changed + cr.Rules = desiredCR.Rules + _, err := h.crClient.Update(cr) + if err != nil { + return fmt.Errorf("couldn't update ClusterRole: %w", err) + } + } + + return nil +} + +func backingResourceRulesClusterRole(gr *v3.GlobalRole, crName string) *v1.ClusterRole { + return &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v3.GlobalRoleGroupVersionKind.GroupVersion().String(), + Kind: v3.GlobalRoleGroupVersionKind.Kind, + Name: gr.Name, + UID: gr.UID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(gr.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + Rules: gr.InheritedFleetWorkspacePermissions.ResourceRules, + } +} + +func backingWorkspaceVerbsClusterRole(gr *v3.GlobalRole, crName string, workspaceNames []string) *v1.ClusterRole { + return &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v3.GlobalRoleGroupVersionKind.GroupVersion().String(), + Kind: v3.GlobalRoleGroupVersionKind.Kind, + Name: gr.Name, + UID: gr.UID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(gr.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + Rules: []v1.PolicyRule{ + { + Verbs: gr.InheritedFleetWorkspacePermissions.WorkspaceVerbs, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"fleetworkspaces"}, + ResourceNames: workspaceNames, + }, + }, + } +} + +func (h *fleetWorkspaceRoleHandler) fleetWorkspaceNames() ([]string, error) { + fleetWorkspaces, err := h.fwCache.List(labels.Everything()) + if err != nil { + return nil, err + } + + var workspacesNames []string + for _, fleetWorkspace := range fleetWorkspaces { + if fleetWorkspace.Name != localFleetWorkspace { + workspacesNames = append(workspacesNames, fleetWorkspace.Name) + } + } + + return workspacesNames, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler_test.go new file mode 100644 index 0000000..db9b9e3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/fleetworkspace_role_handler_test.go @@ -0,0 +1,431 @@ +package globalroles + +import ( + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + genv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + wrangler "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + rbac "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + gr = &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + InheritedFleetWorkspacePermissions: &v3.FleetWorkspacePermission{ + ResourceRules: []rbac.PolicyRule{ + { + Verbs: []string{"get", "list"}, + APIGroups: []string{"fleet.cattle.io"}, + Resources: []string{"gitrepos", "bundles"}, + }, + }, + WorkspaceVerbs: []string{"get", "list"}, + }, + } + + crResourceRulesMeta = metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName), + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRole", + Name: grName, + UID: grUID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(grName), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + } + + crWorkspaceVerbsMeta = metav1.ObjectMeta{ + Name: wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName), + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRole", + Name: grName, + UID: grUID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(grName), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + } + + fleetWorkspaces = []*v3.FleetWorkspace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fleet-local", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fleet-default", + }, + }, + } + + fleetWorkspaceNames = []string{"fleet-default"} +) + +func TestReconcileFleetPermissions(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + crClient *fake.MockNonNamespacedControllerInterface[*rbac.ClusterRole, *rbac.ClusterRoleList] + crCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRole] + fwCache *fake.MockNonNamespacedCacheInterface[*v3.FleetWorkspace] + } + + tests := map[string]struct { + stateSetup func(state testState) + gr *v3.GlobalRole + }{ + "backing ClusterRoles are created for a new GlobalRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames)) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + gr: gr, + }, + "no update if ClusterRoles are present, and haven't changed": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames), nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)), nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + gr: gr, + }, + "backing Roles and ClusterRoles are updated with new content": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames), nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName)), nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crClient.EXPECT().Update(&rbac.ClusterRole{ + ObjectMeta: crResourceRulesMeta, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"fleet.cattle.io"}, + Resources: []string{"gitrepos"}, + }, + }, + }) + state.crClient.EXPECT().Update(&rbac.ClusterRole{ + ObjectMeta: crWorkspaceVerbsMeta, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"fleetworkspaces"}, + ResourceNames: []string{"fleet-default"}, + }, + }, + }) + }, + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + InheritedFleetWorkspacePermissions: &v3.FleetWorkspacePermission{ + ResourceRules: []rbac.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"fleet.cattle.io"}, + Resources: []string{"gitrepos"}, + }, + }, + WorkspaceVerbs: []string{"*"}, + }, + }, + }, + "backing ClusterRole for fleetworkspace cluster-wide resource is not created if there are no fleetworkspaces besides local": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.fwCache.EXPECT().List(labels.Everything()).Return([]*v3.FleetWorkspace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fleet-local", + }, + }, + }, nil) + }, + gr: gr, + }, + "no backing ClusterRoles are created, updated or deleted if InheritedFleetWorkspacePermissions is not provided ": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + }, + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + }, + }, + "existing backing ClusterRoles are deleted if InheritedFleetWorkspacePermissions is nil": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.crClient.EXPECT().Delete(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName), &metav1.DeleteOptions{}) + state.crClient.EXPECT().Delete(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}) + }, + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + }, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + state := testState{ + crClient: fake.NewMockNonNamespacedControllerInterface[*rbac.ClusterRole, *rbac.ClusterRoleList](ctrl), + crCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRole](ctrl), + fwCache: fake.NewMockNonNamespacedCacheInterface[*v3.FleetWorkspace](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + h := fleetWorkspaceRoleHandler{ + crClient: state.crClient, + crCache: state.crCache, + fwCache: state.fwCache, + } + + err := h.reconcileFleetWorkspacePermissions(test.gr) + + assert.Equal(t, err, nil) + }) + } +} + +func TestReconcileFleetPermissions_errors(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + type testState struct { + crClient *fake.MockNonNamespacedControllerInterface[*rbac.ClusterRole, *rbac.ClusterRoleList] + crCache *fake.MockNonNamespacedCacheInterface[*rbac.ClusterRole] + fwCache *fake.MockNonNamespacedCacheInterface[*v3.FleetWorkspace] + } + unexpectedErr := errors.NewServiceUnavailable("unexpected error") + + tests := map[string]struct { + stateSetup func(state testState) + globalRole *v3.GlobalRole + wantErrs []error + }{ + "Error retrieving resource rules ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames)) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + globalRole: gr, + wantErrs: []error{errReconcileResourceRules, unexpectedErr}, + }, + "Error creating resource rules ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames)) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + globalRole: gr, + wantErrs: []error{errReconcileResourceRules, unexpectedErr}, + }, + "Error updating resource rules ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + state.crClient.EXPECT().Update(&rbac.ClusterRole{ + Rules: gr.InheritedFleetWorkspacePermissions.ResourceRules, + }).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames)) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + globalRole: gr, + wantErrs: []error{errReconcileResourceRules, unexpectedErr}, + }, + "Error deleting resource rules ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(&rbac.ClusterRole{}, nil) + state.crClient.EXPECT().Delete(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName), &metav1.DeleteOptions{}).Return(unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), fleetWorkspaceNames)) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + }, + globalRole: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + }, + wantErrs: []error{errReconcileResourceRules, unexpectedErr}, + }, + "Error retrieving workspace verbs ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, unexpectedErr) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + }, + globalRole: gr, + wantErrs: []error{errReconcileWorkspaceVerbs, unexpectedErr}, + }, + "Error creating workspace verbs ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crClient.EXPECT().Create(mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), []string{"fleet-default"})).Return(nil, unexpectedErr) + }, + globalRole: gr, + wantErrs: []error{errReconcileWorkspaceVerbs, unexpectedErr}, + }, + "Error updating workspace verbs ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crClient.EXPECT().Update(&rbac.ClusterRole{ + Rules: mockWorkspaceVerbsClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceVerbsName), []string{"fleet-default"}).Rules, + }).Return(nil, unexpectedErr) + }, + globalRole: gr, + wantErrs: []error{errReconcileWorkspaceVerbs, unexpectedErr}, + }, + "Error deleting workspace verbs ClusterRole": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(&rbac.ClusterRole{}, nil) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, nil) + state.crClient.EXPECT().Delete(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName), &metav1.DeleteOptions{}).Return(unexpectedErr) + }, + globalRole: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: grName, + UID: grUID, + }, + InheritedFleetWorkspacePermissions: &v3.FleetWorkspacePermission{ + ResourceRules: gr.InheritedFleetWorkspacePermissions.ResourceRules, + }, + }, + wantErrs: []error{errReconcileWorkspaceVerbs, unexpectedErr}, + }, + "Error getting fleet workspaces": { + stateSetup: func(state testState) { + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceClusterRulesName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.crClient.EXPECT().Create(mockResourceRulesClusterRole(gr, wrangler.SafeConcatName(gr.Name, fleetWorkspaceClusterRulesName))) + state.crCache.EXPECT().Get(wrangler.SafeConcatName(grName, fleetWorkspaceVerbsName)).Return(nil, errors.NewNotFound(schema.GroupResource{}, "")) + state.fwCache.EXPECT().List(labels.Everything()).Return(fleetWorkspaces, unexpectedErr) + }, + globalRole: gr, + wantErrs: []error{errReconcileWorkspaceVerbs, unexpectedErr}, + }, + } + + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + state := testState{ + crClient: fake.NewMockNonNamespacedControllerInterface[*rbac.ClusterRole, *rbac.ClusterRoleList](ctrl), + crCache: fake.NewMockNonNamespacedCacheInterface[*rbac.ClusterRole](ctrl), + fwCache: fake.NewMockNonNamespacedCacheInterface[*v3.FleetWorkspace](ctrl), + } + if test.stateSetup != nil { + test.stateSetup(state) + } + h := fleetWorkspaceRoleHandler{ + crClient: state.crClient, + crCache: state.crCache, + fwCache: state.fwCache, + } + err := h.reconcileFleetWorkspacePermissions(test.globalRole) + + for _, wantErr := range test.wantErrs { + assert.ErrorIs(t, err, wantErr) + } + }) + } +} + +func mockResourceRulesClusterRole(gr *v3.GlobalRole, crName string) *rbac.ClusterRole { + return &rbac.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: genv3.GlobalRoleGroupVersionKind.GroupVersion().String(), + Kind: genv3.GlobalRoleGroupVersionKind.Kind, + Name: gr.Name, + UID: gr.UID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(gr.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + Rules: gr.InheritedFleetWorkspacePermissions.ResourceRules, + } +} + +func mockWorkspaceVerbsClusterRole(gr *v3.GlobalRole, crName string, workspaceNames []string) *rbac.ClusterRole { + return &rbac.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: genv3.GlobalRoleGroupVersionKind.GroupVersion().String(), + Kind: genv3.GlobalRoleGroupVersionKind.Kind, + Name: gr.Name, + UID: gr.UID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: wrangler.SafeConcatName(gr.Name), + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + }, + Rules: []rbac.PolicyRule{ + { + Verbs: gr.InheritedFleetWorkspacePermissions.WorkspaceVerbs, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"fleetworkspaces"}, + ResourceNames: workspaceNames, + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler.go new file mode 100644 index 0000000..1996481 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler.go @@ -0,0 +1,467 @@ +package globalroles + +import ( + "errors" + "fmt" + "reflect" + "time" + + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io" + mgmtconv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + wrangler "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/apimachinery/pkg/types" + + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + globalRoleLabel = map[string]string{"authz.management.cattle.io/globalrole": "true"} + crNameAnnotation = "authz.management.cattle.io/cr-name" + initialSyncAnnotation = "authz.management.cattle.io/initial-sync" + clusterRoleKind = "ClusterRole" +) + +const ( + grOwnerLabel = "authz.management.cattle.io/gr-owner" +) + +const ( + SummaryInProgress = "InProgress" + SummaryCompleted = "Completed" + SummaryError = "Error" + SummaryTerminating = "Terminating" +) + +// Condition reason types +const ( + ClusterRoleExists = "ClusterRoleExists" + NamespacedRuleRoleExists = "NamespacedRuleRoleExists" + CatalogRoleExists = "CatalogRoleExists" + NamespaceNotFound = "NamespaceNotFound" + NamespaceTerminating = "NamespaceTerminating" + FailedToGetRole = "GetRoleFailed" + FailedToCreateRole = "CreateRoleFailed" + FailedToUpdateRole = "UpdateRoleFailed" + FailedToGetNamespace = "GetNamespaceFailed" + FailedToCreateClusterRole = "CreateClusterRoleFailed" + FailedToUpdateClusterRole = "UpdateClusterRoleFailed" +) + +type fleetPermissionsRoleHandler interface { + reconcileFleetWorkspacePermissions(globalRole *v3.GlobalRole) error +} + +func newGlobalRoleLifecycle(management *config.ManagementContext) *globalRoleLifecycle { + return &globalRoleLifecycle{ + crLister: management.RBAC.ClusterRoles("").Controller().Lister(), + crClient: management.RBAC.ClusterRoles(""), + nsCache: management.Wrangler.Core.Namespace().Cache(), + rLister: management.RBAC.Roles("").Controller().Lister(), + rClient: management.RBAC.Roles(""), + grClient: management.Wrangler.Mgmt.GlobalRole(), + fleetPermissionsHandler: newFleetWorkspaceRoleHandler(management), + } +} + +type globalRoleLifecycle struct { + crLister rbacv1.ClusterRoleLister + crClient rbacv1.ClusterRoleInterface + nsCache wcorev1.NamespaceCache + rLister rbacv1.RoleLister + rClient rbacv1.RoleInterface + grClient mgmtconv3.GlobalRoleClient + fleetPermissionsHandler fleetPermissionsRoleHandler +} + +func (gr *globalRoleLifecycle) Create(obj *v3.GlobalRole) (runtime.Object, error) { + // ObjectMeta.Generation does not get updated when the Status is updated. + // If only the status has been updated and we have finished updating the status (status.Summary != "InProgress") + // we don't need to perform a reconcile as nothing has changed. + if obj.Status.ObservedGeneration == obj.ObjectMeta.Generation && obj.Status.Summary != SummaryInProgress { + return obj, nil + } + returnError := errors.Join( + gr.setGRAsInProgress(obj), // set GR status to "in progress" while the underlying roles get added + gr.reconcileGlobalRole(obj), + gr.reconcileCatalogRole(obj), + gr.reconcileNamespacedRoles(obj), + gr.fleetPermissionsHandler.reconcileFleetWorkspacePermissions(obj), + gr.setGRAsCompleted(obj), + ) + return obj, returnError +} + +func (gr *globalRoleLifecycle) Updated(obj *v3.GlobalRole) (runtime.Object, error) { + // ObjectMeta.Generation does not get updated when the Status is updated. + // If only the status has been updated and we have finished updating the status (status.Summary != "InProgress") + // we don't need to perform a reconcile as nothing has changed. + if obj.Status.ObservedGeneration == obj.ObjectMeta.Generation && obj.Status.Summary != SummaryInProgress { + return obj, nil + } + + returnError := errors.Join( + gr.setGRAsInProgress(obj), // set GR status to "in progress" while the underlying roles get added + gr.reconcileGlobalRole(obj), + gr.reconcileCatalogRole(obj), + gr.reconcileNamespacedRoles(obj), + gr.fleetPermissionsHandler.reconcileFleetWorkspacePermissions(obj), + gr.setGRAsCompleted(obj), + ) + return nil, returnError +} + +func (gr *globalRoleLifecycle) Remove(obj *v3.GlobalRole) (runtime.Object, error) { + // Don't need to delete the created ClusterRole or Roles because owner reference will take care of them + err := gr.setGRAsTerminating(obj) + return nil, err +} + +func (gr *globalRoleLifecycle) reconcileGlobalRole(globalRole *v3.GlobalRole) error { + crName := getCRName(globalRole) + condition := metav1.Condition{ + Type: ClusterRoleExists, + } + + clusterRole, _ := gr.crLister.Get("", crName) + if clusterRole != nil { + if !reflect.DeepEqual(globalRole.Rules, clusterRole.Rules) { + clusterRole.Rules = globalRole.Rules + logrus.Infof("[%v] Updating clusterRole %v. GlobalRole rules have changed. Have: %+v. Want: %+v", grController, clusterRole.Name, clusterRole.Rules, globalRole.Rules) + if _, err := gr.crClient.Update(clusterRole); err != nil { + addCondition(globalRole, condition, FailedToUpdateClusterRole, crName, err) + return fmt.Errorf("couldn't update ClusterRole %v: %w", clusterRole.Name, err) + } + } + addCondition(globalRole, condition, ClusterRoleExists, crName, nil) + return nil + } + + logrus.Infof("[%v] Creating clusterRole %v for corresponding GlobalRole", grController, crName) + _, err := gr.crClient.Create(&v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: crName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRole.TypeMeta.APIVersion, + Kind: globalRole.TypeMeta.Kind, + Name: globalRole.Name, + UID: globalRole.UID, + }, + }, + Labels: globalRoleLabel, + }, + Rules: globalRole.Rules, + }) + if err != nil { + addCondition(globalRole, condition, FailedToCreateClusterRole, crName, err) + return err + } + // Add an annotation to the globalrole indicating the name we used for future updates + if globalRole.Annotations == nil { + globalRole.Annotations = map[string]string{} + } + globalRole.Annotations[crNameAnnotation] = crName + addCondition(globalRole, condition, ClusterRoleExists, crName, nil) + return nil +} + +func (gr *globalRoleLifecycle) reconcileCatalogRole(globalRole *v3.GlobalRole) error { + // rules which give template/template version access need to have a specific namespaced role created, since the + // backend resources that they grant access to are namespaced resources + var catalogRules []v1.PolicyRule + for _, rule := range globalRole.Rules { + ruleGivesTemplateAccess := rbac.RuleGivesResourceAccess(rule, TemplateResourceRule) + ruleGivesTemplateVersionAccess := rbac.RuleGivesResourceAccess(rule, TemplateVersionResourceRule) + if !(ruleGivesTemplateAccess || ruleGivesTemplateVersionAccess) { + // if rule doesn't give access to templates or template versions, move on without evaluating further + continue + } + ruleCopy := rule.DeepCopy() + ruleCopy.APIGroups = []string{mgmt.GroupName} + ruleCopy.Resources = []string{} + // NonResource URLS are only used for ClusterRoles - these roles are namespaced, so no need to include + ruleCopy.NonResourceURLs = []string{} + if ruleGivesTemplateAccess { + ruleCopy.Resources = append(ruleCopy.Resources, catalogTemplateResourceRule) + } + if ruleGivesTemplateVersionAccess { + ruleCopy.Resources = append(ruleCopy.Resources, catalogTemplateVersionResourceRule) + } + catalogRules = append(catalogRules, *ruleCopy) + } + if len(catalogRules) == 0 { + return nil + } + // if this GR gives access to templates/template versions, create a role in cattle-global-data for access + roleName := globalRole.Name + "-" + GlobalCatalogRole + condition := metav1.Condition{ + Type: CatalogRoleExists, + } + role, err := gr.rLister.Get(namespace.GlobalNamespace, roleName) + if err != nil { + if !apierrors.IsNotFound(err) { + addCondition(globalRole, condition, FailedToGetRole, roleName, err) + return err + } + role = &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: namespace.GlobalNamespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRole.APIVersion, + Kind: globalRole.Kind, + Name: globalRole.Name, + UID: globalRole.UID, + }, + }, + }, + Rules: catalogRules, + } + _, err = gr.rClient.Create(role) + if err != nil && !apierrors.IsAlreadyExists(err) { + addCondition(globalRole, condition, FailedToCreateRole, roleName, err) + return err + } + } else { + // if we found the role, make sure that the rules are up-to-date and give the same access as their grs + updateRule := false + for _, rule := range catalogRules { + ruleFound := false + for _, existingRule := range globalRole.Rules { + if reflect.DeepEqual(rule, existingRule) { + ruleFound = true + break + } + } + if !ruleFound { + // if we need to update any individual rule, just replace them all + updateRule = true + break + } + } + if updateRule { + newRole := role.DeepCopy() + newRole.Rules = catalogRules + _, err := gr.rClient.Update(newRole) + if err != nil { + addCondition(globalRole, condition, FailedToUpdateRole, roleName, err) + return err + } + } + } + addCondition(globalRole, condition, CatalogRoleExists, roleName, nil) + return nil +} + +// reconcileNamespacedRoles ensures that Roles exist in each namespace of NamespacedRules +func (gr *globalRoleLifecycle) reconcileNamespacedRoles(globalRole *v3.GlobalRole) error { + var returnError error + globalRoleName := wrangler.SafeConcatName(globalRole.Name) + + // For collecting all the roles that should exist for the GlobalRole + roleUIDs := map[types.UID]struct{}{} + + for ns, rules := range globalRole.NamespacedRules { + roleName := wrangler.SafeConcatName(globalRole.Name, ns) + condition := metav1.Condition{ + Type: NamespacedRuleRoleExists, + } + + namespace, err := gr.nsCache.Get(ns) + if apierrors.IsNotFound(err) || namespace == nil { + // When a namespace is not found, don't re-enqueue GlobalRole + logrus.Warnf("[%v] Namespace %s not found. Not re-enqueueing GlobalRole %s", grController, ns, globalRole.Name) + addCondition(globalRole, condition, NamespaceNotFound, roleName, fmt.Errorf("namespace %s not found", ns)) + continue + } else if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't get namespace %s: %w", ns, err)) + addCondition(globalRole, condition, FailedToGetNamespace, roleName, err) + continue + } + + // Check if the role exists + role, err := gr.rLister.Get(ns, roleName) + if err != nil { + if !apierrors.IsNotFound(err) { + returnError = errors.Join(returnError, err) + addCondition(globalRole, condition, FailedToGetRole, roleName, err) + continue + } + + // If the namespace is terminating, don't create a Role + if namespace.Status.Phase == corev1.NamespaceTerminating { + logrus.Warnf("[%v] Namespace %s is terminating. Not creating role %s for %s", grController, ns, roleName, globalRole.Name) + addCondition(globalRole, condition, NamespaceTerminating, roleName, fmt.Errorf("namespace %s is terminating", ns)) + continue + } + + newRole := &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: ns, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRole.APIVersion, + Kind: globalRole.Kind, + Name: globalRole.Name, + UID: globalRole.UID, + }, + }, + Labels: map[string]string{ + grOwnerLabel: globalRoleName, + }, + }, + Rules: rules, + } + createdRole, err := gr.rClient.Create(newRole) + if err == nil { + roleUIDs[createdRole.UID] = struct{}{} + addCondition(globalRole, condition, NamespacedRuleRoleExists, roleName, nil) + continue + } + + if !apierrors.IsAlreadyExists(err) { + returnError = errors.Join(returnError, err) + addCondition(globalRole, condition, FailedToCreateRole, roleName, err) + continue + } + + // In the case that the role already exists, we get it and check that the rules are correct + role, err = gr.rLister.Get(ns, roleName) + if err != nil { + returnError = errors.Join(returnError, err) + addCondition(globalRole, condition, FailedToGetRole, roleName, err) + continue + } + } + if role != nil { + roleUIDs[role.GetUID()] = struct{}{} + + // Check that the rules for the existing role are correct and that it has the right Owner Label + if reflect.DeepEqual(role.Rules, rules) && role.Labels != nil && role.Labels[grOwnerLabel] == globalRoleName { + addCondition(globalRole, condition, NamespacedRuleRoleExists, roleName, nil) + continue + } + + newRole := role.DeepCopy() + newRole.Rules = rules + if newRole.Labels == nil { + newRole.Labels = map[string]string{} + } + newRole.Labels[grOwnerLabel] = globalRoleName + + _, err := gr.rClient.Update(newRole) + if err != nil { + returnError = errors.Join(returnError, err) + addCondition(globalRole, condition, FailedToUpdateRole, roleName, err) + continue + } + addCondition(globalRole, condition, NamespacedRuleRoleExists, roleName, nil) + } + } + + // get all the roles claiming to be owned by this GR and remove any that shouldn't exist + r, err := labels.NewRequirement(grOwnerLabel, selection.Equals, []string{globalRoleName}) + if err != nil { + return errors.Join(returnError, fmt.Errorf("couldn't create label: %s: %w", grOwnerLabel, err)) + } + + roles, err := gr.rLister.List("", labels.NewSelector().Add(*r)) + if err != nil { + return errors.Join(returnError, fmt.Errorf("couldn't list roles with label %s : %s: %w", grOwnerLabel, globalRoleName, err)) + } + + // After creating/updating all Roles, if the number of RBs with the grOwnerLabel is the same as + // as the number of created/updated Roles, we know there are no invalid Roles to purge + if len(roleUIDs) != len(roles) { + err = gr.purgeInvalidNamespacedRoles(roles, roleUIDs) + if err != nil { + returnError = errors.Join(returnError, err) + } + } + return returnError +} + +// purgeInvalidNamespacedRoles removes any roles that aren't in the slice of UIDS that we created/updated in reconcileNamespacedRoles +func (gr *globalRoleLifecycle) purgeInvalidNamespacedRoles(roles []*v1.Role, uids map[types.UID]struct{}) error { + var returnError error + for _, r := range roles { + if _, ok := uids[r.UID]; !ok { + err := gr.rClient.DeleteNamespaced(r.Namespace, r.Name, &metav1.DeleteOptions{}) + if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't delete role %s: %w", r.Name, err)) + } + } + } + return returnError +} + +func (gr *globalRoleLifecycle) setGRAsInProgress(globalRole *v3.GlobalRole) error { + globalRole.Status.Conditions = []metav1.Condition{} + globalRole.Status.Summary = SummaryInProgress + globalRole.Status.LastUpdate = time.Now().String() + updatedGR, err := gr.grClient.UpdateStatus(globalRole) + // For future updates, we want the latest version of our GlobalRole + *globalRole = *updatedGR + return err +} + +func (gr *globalRoleLifecycle) setGRAsCompleted(globalRole *v3.GlobalRole) error { + globalRole.Status.Summary = SummaryCompleted + for _, c := range globalRole.Status.Conditions { + if c.Status != metav1.ConditionTrue { + globalRole.Status.Summary = SummaryError + break + } + } + globalRole.Status.LastUpdate = time.Now().String() + globalRole.Status.ObservedGeneration = globalRole.ObjectMeta.Generation + _, err := gr.grClient.UpdateStatus(globalRole) + return err +} + +func (gr *globalRoleLifecycle) setGRAsTerminating(globalRole *v3.GlobalRole) error { + globalRole.Status.Conditions = []metav1.Condition{} + globalRole.Status.Summary = SummaryTerminating + globalRole.Status.LastUpdate = time.Now().String() + _, err := gr.grClient.UpdateStatus(globalRole) + return err +} + +func getCRName(globalRole *v3.GlobalRole) string { + if crName, ok := globalRole.Annotations[crNameAnnotation]; ok { + return crName + } + return generateCRName(globalRole.Name) +} + +func generateCRName(name string) string { + return "cattle-globalrole-" + name +} + +func addCondition(globalRole *v3.GlobalRole, condition metav1.Condition, reason, name string, err error) { + if err != nil { + condition.Status = metav1.ConditionFalse + condition.Message = fmt.Sprintf("%s not created: %v", name, err) + } else { + condition.Status = metav1.ConditionTrue + condition.Message = fmt.Sprintf("%s created", name) + } + condition.Reason = reason + condition.LastTransitionTime = metav1.Time{Time: time.Now()} + globalRole.Status.Conditions = append(globalRole.Status.Conditions, condition) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler_test.go new file mode 100644 index 0000000..f2f9b49 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrole_handler_test.go @@ -0,0 +1,1741 @@ +package globalroles + +import ( + "fmt" + "testing" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/golang/mock/gomock" + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io" + mgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + normanv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + rbacFakes "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// using a subset of condition, because we don't need to check LastTransitionTime or Message +type reducedCondition struct { + reason string + status metav1.ConditionStatus +} + +const generation int64 = 1 + +var ( + readPodPolicyRule = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + } + + readConfigPolicyRule = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"configmaps"}, + } + adminPodPolicyRule = rbacv1.PolicyRule{ + Verbs: []string{"*"}, + APIGroups: []string{""}, + Resources: []string{"pod"}, + } + templatePolicyRule = rbacv1.PolicyRule{ + Verbs: []string{"*"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + } + // templatePolicyRule gets transformed into catalogTemplatePolicyRule via reconcileCatalogRole + catalogTemplatePolicyRule = rbacv1.PolicyRule{ + Verbs: []string{"*"}, + APIGroups: []string{mgmt.GroupName}, + Resources: []string{ + catalogTemplateResourceRule, + catalogTemplateVersionResourceRule, + }, + NonResourceURLs: []string{}, + } + + defaultGR = v3.GlobalRole{ + Rules: []rbacv1.PolicyRule{ + readPodPolicyRule, + }, + } + readConfigCR = rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clusterRole", + }, + Rules: []rbacv1.PolicyRule{ + readConfigPolicyRule, + }, + } + readPodCR = rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "clusterRole", + }, + Rules: []rbacv1.PolicyRule{ + readPodPolicyRule, + }, + } + + catalogGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "catalogRole", + }, + Rules: []rbacv1.PolicyRule{ + templatePolicyRule, + }, + } + + namespacedRulesGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGR", + UID: "00000000", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "fake-kind", + APIVersion: "fake-version", + }, + NamespacedRules: map[string][]rbacv1.PolicyRule{ + "namespace1": { + readPodPolicyRule, + readConfigPolicyRule, + }, + "namespace2": { + adminPodPolicyRule, + readPodPolicyRule, + }, + }, + } + namespacedRulesOwnerRef = metav1.OwnerReference{ + APIVersion: namespacedRulesGR.APIVersion, + Kind: namespacedRulesGR.Kind, + Name: namespacedRulesGR.Name, + UID: namespacedRulesGR.UID, + } + + updatedNamespacedRulesGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGR", + }, + NamespacedRules: map[string][]rbacv1.PolicyRule{ + "namespace1": { + readPodPolicyRule, + }, + "namespace2": { + adminPodPolicyRule, + readPodPolicyRule, + readConfigPolicyRule, + }, + }, + } +) + +type grTestStateChanges struct { + t *testing.T + createdRoles map[string]*rbacv1.Role + deletedRoles map[string]struct{} + createdClusterRoles map[string]*rbacv1.ClusterRole +} +type grTestState struct { + nsCacheMock *fake.MockNonNamespacedCacheInterface[*corev1.Namespace] + rListerMock *rbacFakes.RoleListerMock + rClientMock *rbacFakes.RoleInterfaceMock + crListerMock *rbacFakes.ClusterRoleListerMock + crClientMock *rbacFakes.ClusterRoleInterfaceMock + counter int + stateChanges *grTestStateChanges +} + +func TestReconcileGlobalRole(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + stateSetup func(grTestState) + stateAssertions func(grTestStateChanges) + globalRole *v3.GlobalRole + wantError bool + condition reducedCondition + annotation string + }{ + { + name: "no changes to clusterRole", + stateSetup: func(state grTestState) { + state.crListerMock.GetFunc = func(_, _ string) (*normanv1.ClusterRole, error) { + return readPodCR.DeepCopy(), nil + } + }, + globalRole: defaultGR.DeepCopy(), + wantError: false, + condition: reducedCondition{ + reason: ClusterRoleExists, + status: metav1.ConditionTrue, + }, + }, + { + name: "clusterRole is updated", + stateSetup: func(state grTestState) { + state.crListerMock.GetFunc = func(_, _ string) (*normanv1.ClusterRole, error) { + return readConfigCR.DeepCopy(), nil + } + state.crClientMock.UpdateFunc = func(cr *normanv1.ClusterRole) (*normanv1.ClusterRole, error) { + state.stateChanges.createdClusterRoles[cr.Name] = cr + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdClusterRoles, 1) + cr, ok := gtsc.createdClusterRoles["clusterRole"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, &readPodCR, cr) + }, + globalRole: defaultGR.DeepCopy(), + wantError: false, + condition: reducedCondition{ + reason: ClusterRoleExists, + status: metav1.ConditionTrue, + }, + }, + { + name: "update clusterRole fails", + stateSetup: func(state grTestState) { + state.crListerMock.GetFunc = func(_, _ string) (*normanv1.ClusterRole, error) { + return readConfigCR.DeepCopy(), nil + } + state.crClientMock.UpdateFunc = func(cr *normanv1.ClusterRole) (*normanv1.ClusterRole, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: defaultGR.DeepCopy(), + wantError: true, + condition: reducedCondition{ + reason: FailedToUpdateClusterRole, + status: metav1.ConditionFalse, + }, + }, + { + name: "create clusterRole fails", + stateSetup: func(state grTestState) { + state.crListerMock.GetFunc = func(_, _ string) (*normanv1.ClusterRole, error) { + return nil, nil + } + state.crClientMock.CreateFunc = func(cr *normanv1.ClusterRole) (*normanv1.ClusterRole, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: defaultGR.DeepCopy(), + wantError: true, + condition: reducedCondition{ + reason: FailedToCreateClusterRole, + status: metav1.ConditionFalse, + }, + }, + { + name: "clusterRole is created", + stateSetup: func(state grTestState) { + state.crListerMock.GetFunc = func(_, _ string) (*normanv1.ClusterRole, error) { + return nil, nil + } + state.crClientMock.CreateFunc = func(cr *normanv1.ClusterRole) (*normanv1.ClusterRole, error) { + state.stateChanges.createdClusterRoles[cr.Name] = cr + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdClusterRoles, 1) + cr, ok := gtsc.createdClusterRoles["cattle-globalrole-"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, readPodCR.Rules, cr.Rules) + }, + globalRole: defaultGR.DeepCopy(), + wantError: false, + condition: reducedCondition{ + reason: ClusterRoleExists, + status: metav1.ConditionTrue, + }, + annotation: "cattle-globalrole-", + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + state := setupTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + grLifecycle.crLister = state.crListerMock + grLifecycle.crClient = state.crClientMock + + err := grLifecycle.reconcileGlobalRole(test.globalRole) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + if test.annotation != "" { + require.Equal(t, test.annotation, test.globalRole.Annotations[crNameAnnotation]) + } + // only 1 ClusterRole is created, so there should only ever be 1 condition + require.Len(t, test.globalRole.Status.Conditions, 1) + c := test.globalRole.Status.Conditions[0] + rc := reducedCondition{ + reason: c.Reason, + status: c.Status, + } + require.Equal(t, test.condition, rc) + require.Equal(t, ClusterRoleExists, c.Type) + }) + } +} + +func TestReconcileCatalogRole(t *testing.T) { + t.Parallel() + tests := []struct { + name string + stateSetup func(grTestState) + stateAssertions func(grTestStateChanges) + globalRole *v3.GlobalRole + wantError bool + condition *reducedCondition + }{ + { + name: "no catalog role", + globalRole: &v3.GlobalRole{ + Rules: []rbacv1.PolicyRule{ + catalogTemplatePolicyRule, + }, + }, + wantError: false, + }, + { + name: "get role failed", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace, name string) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: catalogGR.DeepCopy(), + wantError: true, + condition: &reducedCondition{ + reason: FailedToGetRole, + status: metav1.ConditionFalse, + }, + }, + { + name: "create role failed", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(in1 *rbacv1.Role) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: catalogGR.DeepCopy(), + wantError: true, + condition: &reducedCondition{ + reason: FailedToCreateRole, + status: metav1.ConditionFalse, + }, + }, + { + name: "create role succeeds", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 1) + r, ok := gtsc.createdRoles["catalogRole-global-catalog"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, catalogTemplatePolicyRule, r.Rules[0]) + }, + globalRole: catalogGR.DeepCopy(), + wantError: false, + condition: &reducedCondition{ + reason: CatalogRoleExists, + status: metav1.ConditionTrue, + }, + }, + { + name: "update role failed", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return &rbacv1.Role{ + Rules: []rbacv1.PolicyRule{readPodPolicyRule}, + }, nil + } + state.rClientMock.UpdateFunc = func(_ *rbacv1.Role) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: catalogGR.DeepCopy(), + wantError: true, + condition: &reducedCondition{ + reason: FailedToUpdateRole, + status: metav1.ConditionFalse, + }, + }, + { + name: "update role succeeds", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + }, + Rules: []rbacv1.PolicyRule{readPodPolicyRule}, + }, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 1) + r, ok := gtsc.createdRoles["test-role"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, catalogTemplatePolicyRule, r.Rules[0]) + }, + globalRole: catalogGR.DeepCopy(), + wantError: false, + condition: &reducedCondition{ + reason: CatalogRoleExists, + status: metav1.ConditionTrue, + }, + }, + { + name: "update role no changes", + stateSetup: func(state grTestState) { + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-role", + }, + Rules: []rbacv1.PolicyRule{readConfigPolicyRule}, + }, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 0) + }, + // templatePolicyRule is a catalog rule, but it is covered by catalogTemplatePolicyRule + // so the update does not need to happen since the user has all needed rules + globalRole: &v3.GlobalRole{ + Rules: []rbacv1.PolicyRule{ + templatePolicyRule, + catalogTemplatePolicyRule, + }, + }, + wantError: false, + condition: &reducedCondition{ + reason: CatalogRoleExists, + status: metav1.ConditionTrue, + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + state := setupTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + grLifecycle.rLister = state.rListerMock + grLifecycle.rClient = state.rClientMock + + err := grLifecycle.reconcileCatalogRole(test.globalRole) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + if test.condition != nil { + // only 1 ClusterRole is created, so there should only ever be 1 condition + require.Len(t, test.globalRole.Status.Conditions, 1) + c := test.globalRole.Status.Conditions[0] + require.Equal(t, test.condition.reason, c.Reason) + require.Equal(t, test.condition.status, c.Status) + require.Equal(t, CatalogRoleExists, c.Type) + } + }) + } +} + +func TestReconcileNamespacedRoles(t *testing.T) { + t.Parallel() + + activeNamespace := &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + } + terminatingNamespace := &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceTerminating, + }, + } + + tests := []struct { + name string + stateSetup func(grTestState) + stateAssertions func(grTestStateChanges) + globalRole *v3.GlobalRole + wantError bool + conditions []reducedCondition + }{ + { + name: "getting namespace fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, fmt.Errorf("error")) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: FailedToGetNamespace, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "namespace is not found", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + + nsNotFound := apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nsNotFound) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespaceNotFound, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "namespace is nil", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(nil, nil) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespaceNotFound, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "getting role fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: FailedToGetRole, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "creating role fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: FailedToCreateRole, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "created role already exists but get continuously fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + return nil, apierrors.NewAlreadyExists(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: FailedToGetRole, + status: metav1.ConditionFalse, + }, + }, + }, + { + // It's possible that a user can create the invalid role in the middle of the reconcile + // In that case, the first attempt to get the role fails. Then the reconcile function attempts to + // create the role and finds that it already exists. It gets the new role and checks that it is valid + name: "role gets created incorrectly mid reconcile", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + state.rListerMock.GetFunc = func(namespace, _ string) (*rbacv1.Role, error) { + // counter == 0 means that the create hasn't happened and should fail + // counter == 1 means that the create has occurred and should return an incorrect role + if state.counter == 0 { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } else { + state.counter = 0 + role := &rbacv1.Role{} + if namespace == "namespace1" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + } + role.Rules = []rbacv1.PolicyRule{ + readPodPolicyRule, + readConfigPolicyRule, + } + } else if namespace == "namespace2" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace2", + Namespace: "namespace2", + Labels: map[string]string{grOwnerLabel: "badGR"}, + } + role.Rules = []rbacv1.PolicyRule{ + adminPodPolicyRule, + readPodPolicyRule, + } + } + return role, nil + } + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.counter = 1 + return nil, apierrors.NewAlreadyExists(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 2) + + role, ok := gtsc.createdRoles["namespacedRulesGR-namespace1"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace1", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readConfigPolicyRule, role.Rules[1]) + + role, ok = gtsc.createdRoles["namespacedRulesGR-namespace2"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace2", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, adminPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[1]) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "create roles successfully", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 2) + + role, ok := gtsc.createdRoles["namespacedRulesGR-namespace1"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace1", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readConfigPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, namespacedRulesOwnerRef, role.OwnerReferences[0]) + + role, ok = gtsc.createdRoles["namespacedRulesGR-namespace2"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace2", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, adminPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, namespacedRulesOwnerRef, role.OwnerReferences[0]) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "create role in terminating namespace", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(terminatingNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, name string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 0) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespaceTerminating, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "some roles have errors but rest get created", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + first := state.nsCacheMock.EXPECT().Get(gomock.Any()).Return(activeNamespace, fmt.Errorf("error")) + second := state.nsCacheMock.EXPECT().Get(gomock.Any()).Return(activeNamespace, nil) + gomock.InOrder(first, second) + + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + // The second role should be created despite the first getting an error + // Because the order is not guaranteed, we can't assert any info on the + // created role, just that it exists + require.Len(gtsc.t, gtsc.createdRoles, 1) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + { + reason: FailedToGetNamespace, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "update an existing role with rule and label changes", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{} + if namespace == "namespace1" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + } + role.Rules = []rbacv1.PolicyRule{ + readPodPolicyRule, + readConfigPolicyRule, + } + } else if namespace == "namespace2" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace2", + Namespace: "namespace2", + Labels: map[string]string{grOwnerLabel: "badGR"}, + } + role.Rules = []rbacv1.PolicyRule{ + adminPodPolicyRule, + readPodPolicyRule, + } + } + + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "" + return role, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 2) + + role, ok := gtsc.createdRoles["namespacedRulesGR-namespace1"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace1", role.Namespace) + require.Len(gtsc.t, role.Rules, 1) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + + role, ok = gtsc.createdRoles["namespacedRulesGR-namespace2"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace2", role.Namespace) + require.Len(gtsc.t, role.Rules, 3) + require.Equal(gtsc.t, adminPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, readConfigPolicyRule, role.Rules[2]) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + }, + globalRole: updatedNamespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "update an existing role no changes", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{} + if namespace == "namespace1" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + Labels: map[string]string{ + grOwnerLabel: "namespacedRulesGR", + }, + } + role.Rules = []rbacv1.PolicyRule{ + readPodPolicyRule, + readConfigPolicyRule, + } + } else if namespace == "namespace2" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace2", + Namespace: "namespace2", + Labels: map[string]string{ + grOwnerLabel: "namespacedRulesGR", + }, + } + role.Rules = []rbacv1.PolicyRule{ + adminPodPolicyRule, + readPodPolicyRule, + } + } + + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + return nil, nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 0) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "update role fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + }, + Rules: []rbacv1.PolicyRule{}, + } + + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + conditions: []reducedCondition{ + { + reason: FailedToUpdateRole, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "remove roles that falsely claim to be owned by GR after create", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + roles := []*rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role-1", + UID: "2222", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role-1", + UID: "1111", + }, + }, + } + + return roles, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + role.UID = "1111" + return role, nil + } + state.rClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRoles[name] = struct{}{} + return nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 2) + + role, ok := gtsc.createdRoles["namespacedRulesGR-namespace1"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace1", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readConfigPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, namespacedRulesOwnerRef, role.OwnerReferences[0]) + + role, ok = gtsc.createdRoles["namespacedRulesGR-namespace2"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace2", role.Namespace) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + require.Len(gtsc.t, role.Rules, 2) + require.Equal(gtsc.t, adminPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, namespacedRulesOwnerRef, role.OwnerReferences[0]) + + require.Contains(gtsc.t, gtsc.deletedRoles, "deleted-role-1") + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "remove invalid role despite terminating namespace", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + roles := []*rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role-1", + UID: "1111", + }, + }, + } + + return roles, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(terminatingNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleGroupVersionKind.Group, + Resource: normanv1.RoleGroupVersionResource.Resource, + }, "") + } + state.rClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRoles[name] = struct{}{} + return nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.deletedRoles, 1) + require.Contains(gtsc.t, gtsc.deletedRoles, "deleted-role-1") + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespaceTerminating, + status: metav1.ConditionFalse, + }, + }, + }, + { + name: "delete Role fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + roles := []*rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role-1", + UID: "2222", + }, + }, + } + + return roles, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + return nil, nil + } + state.rClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + return fmt.Errorf("error") + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + }, + { + name: "remove roles that falsely claim to be owned by GR after update", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + roles := []*rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role-1", + UID: "1111", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role-2", + UID: "2222", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role-1", + UID: "3333", + }, + }, + } + + return roles, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{} + if namespace == "namespace1" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + } + role.Rules = []rbacv1.PolicyRule{ + readPodPolicyRule, + readConfigPolicyRule, + } + role.UID = "1111" + } else if namespace == "namespace2" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace2", + Namespace: "namespace2", + Labels: map[string]string{grOwnerLabel: "badGR"}, + } + role.Rules = []rbacv1.PolicyRule{ + adminPodPolicyRule, + readPodPolicyRule, + } + role.UID = "2222" + } + + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.createdRoles[role.Name] = role + return role, nil + } + state.rClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRoles[name] = struct{}{} + return nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.createdRoles, 2) + + role, ok := gtsc.createdRoles["namespacedRulesGR-namespace1"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace1", role.Namespace) + require.Len(gtsc.t, role.Rules, 1) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + + role, ok = gtsc.createdRoles["namespacedRulesGR-namespace2"] + require.True(gtsc.t, ok) + require.Equal(gtsc.t, "namespace2", role.Namespace) + require.Len(gtsc.t, role.Rules, 3) + require.Equal(gtsc.t, adminPodPolicyRule, role.Rules[0]) + require.Equal(gtsc.t, readPodPolicyRule, role.Rules[1]) + require.Equal(gtsc.t, readConfigPolicyRule, role.Rules[2]) + require.Equal(gtsc.t, "namespacedRulesGR", role.Labels[grOwnerLabel]) + + require.Contains(gtsc.t, gtsc.deletedRoles, "deleted-role-1") + }, + globalRole: updatedNamespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + { + name: "listing existing roles fails", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: true, + }, + { + name: "roles that should exist with no changes don't get deleted", + stateSetup: func(state grTestState) { + state.rListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.Role, error) { + roles := []*rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role-1", + UID: "1111", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role-2", + UID: "2222", + }, + }, + } + + return roles, nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{} + if namespace == "namespace1" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace1", + Namespace: "namespace1", + Labels: map[string]string{grOwnerLabel: "namespacedRulesGR"}, + } + role.Rules = []rbacv1.PolicyRule{ + readPodPolicyRule, + readConfigPolicyRule, + } + role.UID = "1111" + } else if namespace == "namespace2" { + role.ObjectMeta = metav1.ObjectMeta{ + Name: "namespacedRulesGR-namespace2", + Namespace: "namespace2", + Labels: map[string]string{grOwnerLabel: "namespacedRulesGR"}, + } + role.Rules = []rbacv1.PolicyRule{ + adminPodPolicyRule, + readPodPolicyRule, + } + role.UID = "2222" + } + + return role, nil + } + state.rClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRoles[name] = struct{}{} + return nil + } + }, + stateAssertions: func(gtsc grTestStateChanges) { + require.Len(gtsc.t, gtsc.deletedRoles, 0) + }, + globalRole: namespacedRulesGR.DeepCopy(), + wantError: false, + conditions: []reducedCondition{ + { + reason: NamespacedRuleRoleExists, + status: metav1.ConditionTrue, + }, + }, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + state := setupTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + grLifecycle.nsCache = state.nsCacheMock + grLifecycle.rLister = state.rListerMock + grLifecycle.rClient = state.rClientMock + + err := grLifecycle.reconcileNamespacedRoles(test.globalRole) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + if test.conditions != nil { + // All tests are done with 2 NamespacedRules + require.Len(t, test.globalRole.Status.Conditions, 2) + for _, c := range test.globalRole.Status.Conditions { + rc := reducedCondition{ + reason: c.Reason, + status: c.Status, + } + require.Contains(t, test.conditions, rc) + require.Equal(t, NamespacedRuleRoleExists, c.Type) + } + } + }) + } +} + +func setupTest(t *testing.T) grTestState { + ctrl := gomock.NewController(t) + nsCacheMock := fake.NewMockNonNamespacedCacheInterface[*corev1.Namespace](ctrl) + rListerMock := rbacFakes.RoleListerMock{} + rClientMock := rbacFakes.RoleInterfaceMock{} + crListerMock := rbacFakes.ClusterRoleListerMock{} + crClientMock := rbacFakes.ClusterRoleInterfaceMock{} + + stateChanges := grTestStateChanges{ + t: t, + createdRoles: map[string]*rbacv1.Role{}, + deletedRoles: map[string]struct{}{}, + createdClusterRoles: map[string]*rbacv1.ClusterRole{}, + } + state := grTestState{ + nsCacheMock: nsCacheMock, + rListerMock: &rListerMock, + rClientMock: &rClientMock, + crListerMock: &crListerMock, + crClientMock: &crClientMock, + stateChanges: &stateChanges, + } + return state +} + +func TestSetGRAsInProgress(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + oldGR *v3.GlobalRole + updateReturn error + wantError bool + }{ + { + name: "update gr status to InProgress", + oldGR: &v3.GlobalRole{ + Status: mgmtv3.GlobalRoleStatus{ + Summary: SummaryCompleted, + Conditions: []metav1.Condition{ + { + Type: "test", + Status: metav1.ConditionTrue, + }, + }, + }, + }, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr with empty status to InProgress", + oldGR: &v3.GlobalRole{ + Status: mgmtv3.GlobalRoleStatus{}, + }, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr with nil status to InProgress", + oldGR: &v3.GlobalRole{}, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr fails", + oldGR: &v3.GlobalRole{}, + updateReturn: fmt.Errorf("error"), + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + ctrl := gomock.NewController(t) + + grClientMock := fake.NewMockNonNamespacedControllerInterface[*v3.GlobalRole, *v3.GlobalRoleList](ctrl) + var updatedGR *v3.GlobalRole + grClientMock.EXPECT().UpdateStatus(gomock.Any()).AnyTimes().DoAndReturn( + func(gr *v3.GlobalRole) (*v3.GlobalRole, error) { + updatedGR = gr + return updatedGR, test.updateReturn + }, + ) + grLifecycle.grClient = grClientMock + + err := grLifecycle.setGRAsInProgress(test.oldGR) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + require.Empty(t, updatedGR.Status.Conditions) + require.Equal(t, SummaryInProgress, updatedGR.Status.Summary) + }) + } +} + +func TestSetGRAsCompleted(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + gr *v3.GlobalRole + summary string + updateReturn error + wantError bool + }{ + { + name: "gr with a met condition is Completed", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{ + { + Type: "test1", + Status: metav1.ConditionTrue, + }, + }, + }, + }, + summary: SummaryCompleted, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with multiple met conditions is Completed", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{ + { + Type: "test1", + Status: metav1.ConditionTrue, + }, + { + Type: "test2", + Status: metav1.ConditionTrue, + }, + }, + }, + }, + summary: SummaryCompleted, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with no conditions is Completed", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{}, + }, + }, + summary: SummaryCompleted, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with nil status is Completed", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + }, + summary: SummaryCompleted, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with one unmet and one met condition is Error", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{ + { + Type: "test1", + Status: metav1.ConditionTrue, + }, + { + Type: "test2", + Status: metav1.ConditionFalse, + }, + }, + }, + }, + summary: SummaryError, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with multiple unmet conditions is Error", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{ + { + Type: "test1", + Status: metav1.ConditionFalse, + }, + { + Type: "test2", + Status: metav1.ConditionFalse, + }, + }, + }, + }, + summary: SummaryError, + updateReturn: nil, + wantError: false, + }, + { + name: "gr with unknown conditions is Error", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + Status: mgmtv3.GlobalRoleStatus{ + Conditions: []metav1.Condition{ + { + Type: "test1", + Status: metav1.ConditionUnknown, + }, + { + Type: "test2", + Status: metav1.ConditionTrue, + }, + }, + }, + }, + summary: SummaryError, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr fails", + gr: &v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Generation: generation, + }, + }, + updateReturn: fmt.Errorf("error"), + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + ctrl := gomock.NewController(t) + grClientMock := fake.NewMockNonNamespacedControllerInterface[*v3.GlobalRole, *v3.GlobalRoleList](ctrl) + var updatedGR *v3.GlobalRole + grClientMock.EXPECT().UpdateStatus(gomock.Any()).AnyTimes().DoAndReturn( + func(gr *v3.GlobalRole) (*v3.GlobalRole, error) { + updatedGR = gr + return nil, test.updateReturn + }, + ) + + grLifecycle.grClient = grClientMock + err := grLifecycle.setGRAsCompleted(test.gr) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.summary != "" { + require.Equal(t, test.summary, updatedGR.Status.Summary) + } + require.Equal(t, generation, updatedGR.Status.ObservedGeneration) + }) + } +} + +func TestSetGRAsTerminating(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + oldGR *v3.GlobalRole + updateReturn error + wantError bool + }{ + { + name: "update gr status to Terminating", + oldGR: &v3.GlobalRole{ + Status: mgmtv3.GlobalRoleStatus{ + Summary: SummaryCompleted, + Conditions: []metav1.Condition{ + { + Type: "test", + Status: metav1.ConditionTrue, + }, + }, + }, + }, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr with empty status to Terminating", + oldGR: &v3.GlobalRole{ + Status: mgmtv3.GlobalRoleStatus{}, + }, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr with nil status to Terminating", + oldGR: &v3.GlobalRole{}, + updateReturn: nil, + wantError: false, + }, + { + name: "update gr fails", + oldGR: &v3.GlobalRole{}, + updateReturn: fmt.Errorf("error"), + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grLifecycle := globalRoleLifecycle{} + ctrl := gomock.NewController(t) + + grClientMock := fake.NewMockNonNamespacedControllerInterface[*v3.GlobalRole, *v3.GlobalRoleList](ctrl) + var updatedGR *v3.GlobalRole + grClientMock.EXPECT().UpdateStatus(gomock.Any()).AnyTimes().DoAndReturn( + func(gr *v3.GlobalRole) (*v3.GlobalRole, error) { + updatedGR = gr + return updatedGR, test.updateReturn + }, + ) + grLifecycle.grClient = grClientMock + + err := grLifecycle.setGRAsTerminating(test.oldGR) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + require.Empty(t, updatedGR.Status.Conditions) + require.Equal(t, SummaryTerminating, updatedGR.Status.Summary) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler.go new file mode 100644 index 0000000..abd3ef4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler.go @@ -0,0 +1,727 @@ +package globalroles + +import ( + "errors" + "fmt" + "reflect" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + wrangler "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/apimachinery/pkg/types" +) + +var ( + globalRoleBindingLabel = map[string]string{"authz.management.cattle.io/globalrolebinding": "true"} +) + +const ( + catalogTemplateResourceRule = "catalogtemplates" + catalogTemplateVersionResourceRule = "catalogtemplateversions" + crbNameAnnotation = "authz.management.cattle.io/crb-name" + crtbGrbOwnerIndex = "authz.management.cattle.io/crtb-owner" + crbNamePrefix = "cattle-globalrolebinding-" + GlobalCatalogRole = "global-catalog" + globalCatalogRoleBinding = "global-catalog-binding" + TemplateResourceRule = "templates" + TemplateVersionResourceRule = "templateversions" + localClusterName = "local" + grbOwnerLabel = "authz.management.cattle.io/grb-owner" + fleetWorkspacePermissionLabel = "authz.management.cattle.io/fleet-workspace-permissions" +) + +func newGlobalRoleBindingLifecycle(management *config.ManagementContext, clusterManager *clustermanager.Manager) *globalRoleBindingLifecycle { + management.Wrangler.Mgmt.ClusterRoleTemplateBinding().Cache().AddIndexer(crtbGrbOwnerIndex, crtbGrbOwnerIndexer) + return &globalRoleBindingLifecycle{ + clusters: management.Management.Clusters(""), + clusterLister: management.Management.Clusters("").Controller().Lister(), + projectLister: management.Management.Projects("").Controller().Lister(), + clusterManager: clusterManager, + clusterRoles: management.RBAC.ClusterRoles(""), + crbClient: management.RBAC.ClusterRoleBindings(""), + crbLister: management.RBAC.ClusterRoleBindings("").Controller().Lister(), + crLister: management.RBAC.ClusterRoles("").Controller().Lister(), + crtbClient: management.Management.ClusterRoleTemplateBindings(""), + crtbCache: management.Wrangler.Mgmt.ClusterRoleTemplateBinding().Cache(), + grLister: management.Management.GlobalRoles("").Controller().Lister(), + nsCache: management.Wrangler.Core.Namespace().Cache(), + roles: management.RBAC.Roles(""), + roleLister: management.RBAC.Roles("").Controller().Lister(), + roleBindings: management.RBAC.RoleBindings(""), + roleBindingLister: management.RBAC.RoleBindings("").Controller().Lister(), + fleetPermissionsHandler: newFleetWorkspaceBindingHandler(management), + } +} + +// crtbGrbOwnerIndexer indexes a CRTB to a key identifying the target cluster and owning GRB +func crtbGrbOwnerIndexer(crtb *v3.ClusterRoleTemplateBinding) ([]string, error) { + // the label, unlike the owner ref, is protected by the webhook, so we use it as a source of truth + grbOwner, ok := crtb.Labels[grbOwnerLabel] + if !ok { + return nil, nil + } + return []string{fmt.Sprintf("%s/%s", crtb.ClusterName, grbOwner)}, nil +} + +type fleetPermissionsHandler interface { + reconcileFleetWorkspacePermissionsBindings(globalRoleBinding *v3.GlobalRoleBinding) error +} + +type globalRoleBindingLifecycle struct { + clusters v3.ClusterInterface + clusterLister v3.ClusterLister + projectLister v3.ProjectLister + clusterManager *clustermanager.Manager + clusterRoles rbacv1.ClusterRoleInterface + crLister rbacv1.ClusterRoleLister + crbClient rbacv1.ClusterRoleBindingInterface + crbLister rbacv1.ClusterRoleBindingLister + crtbCache mgmtcontroller.ClusterRoleTemplateBindingCache + crtbClient v3.ClusterRoleTemplateBindingInterface + grLister v3.GlobalRoleLister + nsCache wcorev1.NamespaceCache + roles rbacv1.RoleInterface + roleLister rbacv1.RoleLister + roleBindings rbacv1.RoleBindingInterface + roleBindingLister rbacv1.RoleBindingLister + fleetPermissionsHandler fleetPermissionsHandler +} + +func (grb *globalRoleBindingLifecycle) Create(obj *v3.GlobalRoleBinding) (runtime.Object, error) { + returnError := errors.Join( + grb.reconcileClusterPermissions(obj), + grb.reconcileGlobalRoleBinding(obj), + grb.reconcileNamespacedRoleBindings(obj), + grb.fleetPermissionsHandler.reconcileFleetWorkspacePermissionsBindings(obj), + ) + return obj, returnError +} + +func (grb *globalRoleBindingLifecycle) Updated(obj *v3.GlobalRoleBinding) (runtime.Object, error) { + returnError := errors.Join( + grb.reconcileClusterPermissions(obj), + grb.reconcileGlobalRoleBinding(obj), + grb.reconcileNamespacedRoleBindings(obj), + grb.fleetPermissionsHandler.reconcileFleetWorkspacePermissionsBindings(obj), + ) + return obj, returnError +} + +func (grb *globalRoleBindingLifecycle) Remove(obj *v3.GlobalRoleBinding) (runtime.Object, error) { + if obj.GlobalRoleName == rbac.GlobalAdmin || obj.GlobalRoleName == rbac.GlobalRestrictedAdmin { + return obj, grb.deleteAdminBinding(obj) + } + // Don't need to delete the created ClusterRole or RoleBindings because owner reference will take care of them + return obj, nil +} + +func (grb *globalRoleBindingLifecycle) deleteAdminBinding(obj *v3.GlobalRoleBinding) error { + // Explicit API call to ensure we have the most recent cluster info when deleting admin bindings + clusters, err := grb.clusters.List(metav1.ListOptions{}) + if err != nil { + return err + } + + // Collect all the errors to delete as many user context bindings as possible + var allErrors []error + + for _, cluster := range clusters.Items { + userContext, err := grb.clusterManager.UserContext(cluster.Name) + if err != nil { + // ClusterUnavailable error indicates the record can't talk to the downstream cluster + if !clustermanager.IsClusterUnavailableErr(err) { + allErrors = append(allErrors, err) + } + continue + } + + bindingName := rbac.GrbCRBName(obj) + b, err := userContext.RBAC.ClusterRoleBindings("").Controller().Lister().Get("", bindingName) + if err != nil { + // User context clusterRoleBinding doesn't exist + if !apierrors.IsNotFound(err) { + allErrors = append(allErrors, err) + } + continue + } + + err = userContext.RBAC.ClusterRoleBindings("").Delete(b.Name, &metav1.DeleteOptions{}) + if err != nil { + // User context clusterRoleBinding doesn't exist + if !apierrors.IsNotFound(err) { + allErrors = append(allErrors, err) + } + continue + } + + } + + if len(allErrors) > 0 { + return fmt.Errorf("errors deleting admin global role binding: %v", allErrors) + } + return nil +} + +// reconcileClusterPermissions grants permissions for the binding in all downstream (non-local) clusters. Will also +// remove invalid bindings (bindings not for active RoleTemplates or for invalid subjects). +func (grb *globalRoleBindingLifecycle) reconcileClusterPermissions(globalRoleBinding *v3.GlobalRoleBinding) error { + globalRole, err := grb.grLister.Get("", globalRoleBinding.GlobalRoleName) + if err != nil { + return fmt.Errorf("unable to get globalRole %s: %w", globalRoleBinding.Name, err) + } + clusters, err := grb.clusterLister.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("unable to list clusters when reconciling globalRoleBinding %s: %w", globalRoleBinding.Name, err) + } + + var missedClusters bool + for _, cluster := range clusters { + // we don't sync permissions for the local cluster, but we do want to purge user-created permissions + if cluster.Name == localClusterName { + err := grb.purgeCorruptRoles(nil, cluster, globalRoleBinding) + if err != nil { + // failure to remove bad bindings shouldn't affect our ability to sync new permissions, so we log and keep processing + logrus.Errorf("unable to purge roles for cluster %s and grb %s, some bindings may remain: %s", cluster.Name, globalRoleBinding.Name, err.Error()) + missedClusters = true + } + // inheritedClusterRoles only apply on non-local clusters, so skip the local cluster + continue + } + err := grb.purgeCorruptRoles(globalRole.InheritedClusterRoles, cluster, globalRoleBinding) + if err != nil { + // failure to remove bad bindings shouldn't affect our ability to sync new permissions, so we log and keep processing + logrus.Errorf("unable to purge roles for cluster %s and grb %s, some bindings may remain: %s", cluster.Name, globalRoleBinding.Name, err.Error()) + missedClusters = true + } + missingRTs, err := grb.findMissingRTs(globalRole.InheritedClusterRoles, cluster, globalRoleBinding) + if err != nil { + logrus.Errorf("unable to find missing roles for cluster %s and grb %s, some permissions may be missing: %s", cluster.Name, globalRoleBinding.Name, err.Error()) + missedClusters = true + continue + } + // at this point, the only remaining items are roleTemplates that we don't have a CRTB for in this cluster + for _, wantRT := range missingRTs { + // create a crtb in the backing namespace for the cluster + logrus.Infof("creating backing crtb for grb %s in cluster %s for roleTemplate %s", globalRoleBinding.Name, cluster.Name, wantRT) + _, err = grb.crtbClient.Create(&v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "crtb-grb-", + Namespace: cluster.Name, + // the owner ref needs to be mutable by the k8s garbage collector but we need + // a way to identify what CRTBs are from GRBs unambiguously for validation + Labels: map[string]string{ + grbOwnerLabel: globalRoleBinding.Name, + controllers.K8sManagedByKey: controllers.ManagerValue, + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: v3.GlobalRoleBindingGroupVersionKind.Kind, + Name: globalRoleBinding.Name, + UID: globalRoleBinding.UID, + }, + }, + }, + ClusterName: cluster.Name, + RoleTemplateName: wantRT, + UserName: globalRoleBinding.UserName, + GroupPrincipalName: globalRoleBinding.GroupPrincipalName, + }) + // we don't immediately return so that we can create as many CRTBs as we can + if err != nil { + logrus.Errorf("failed to create crtb for globalRoleBinding %s in cluster %s: %s", globalRoleBinding.Name, cluster.Name, err.Error()) + missedClusters = true + } + } + } + if missedClusters { + return fmt.Errorf("unable to reconcile backing crtbs for globalRoleBinding %s, some permissions may be missing", globalRoleBinding.Name) + } + return nil +} + +// purgeCorruptRoles removes any CRTBs which were created for this role in the past, but are no longer valid, either +// because they aren't for a currently requested RoleTemplate, or because they have been corrupted by user intervention. +// Will return an error if a binding can't be deleted +func (grb *globalRoleBindingLifecycle) purgeCorruptRoles(wantRTs []string, cluster *v3.Cluster, binding *v3.GlobalRoleBinding) error { + currentCRTBs, err := grb.crtbCache.GetByIndex(crtbGrbOwnerIndex, fmt.Sprintf("%s/%s", cluster.Name, binding.Name)) + if err != nil { + return fmt.Errorf("unable to get CRTBs for cluster %s: %w", cluster.Name, err) + } + var deleteErr error + seenRTs := map[string]struct{}{} + for _, crtb := range currentCRTBs { + foundRT := false + for _, roleTemplate := range wantRTs { + if roleTemplate == crtb.RoleTemplateName { + foundRT = true + break + } + } + _, seen := seenRTs[crtb.RoleTemplateName] + // if the RT isn't one of the ones that we requested, or is corrupt, or refers to the same RT as a prior + // valid RT, then we remove it. + if !foundRT || !isCRTBValid(crtb, cluster, binding) || seen { + // CRTBs can't update some of these fields, so the safest method is to delete/re-create + err := grb.crtbClient.DeleteNamespaced(crtb.Namespace, crtb.Name, &metav1.DeleteOptions{}) + if err != nil { + // failure to delete one crtb does not prevent our ability to delete other crtbs, or to determine + // which rts we want to remove + crtbErr := fmt.Errorf("unable to delete backing crtb %s for globalRoleBinding %s: %w", crtb.Name, binding.Name, err) + deleteErr = errors.Join(deleteErr, crtbErr) + } + } else { + seenRTs[crtb.RoleTemplateName] = struct{}{} + } + } + return deleteErr +} + +// findMissingRTs finds which RoleTemplates were in wantRTs but don't have a valid binding for this cluster yet +func (grb *globalRoleBindingLifecycle) findMissingRTs(wantRTs []string, cluster *v3.Cluster, binding *v3.GlobalRoleBinding) ([]string, error) { + currentRTs := map[string]struct{}{} + for _, wantRT := range wantRTs { + currentRTs[wantRT] = struct{}{} + } + currentCRTBs, err := grb.crtbCache.GetByIndex(crtbGrbOwnerIndex, fmt.Sprintf("%s/%s", cluster.Name, binding.Name)) + if err != nil { + return nil, fmt.Errorf("unable to get CRTBs for cluster %s: %w", cluster.Name, err) + } + for _, crtb := range currentCRTBs { + _, rtOk := currentRTs[crtb.RoleTemplateName] + if rtOk && isCRTBValid(crtb, cluster, binding) { + delete(currentRTs, crtb.RoleTemplateName) + } + } + missingRTs := make([]string, 0, len(currentRTs)) + for missingRT := range currentRTs { + missingRTs = append(missingRTs, missingRT) + } + return missingRTs, nil + +} + +func (grb *globalRoleBindingLifecycle) reconcileGlobalRoleBinding(globalRoleBinding *v3.GlobalRoleBinding) error { + crbName, ok := globalRoleBinding.Annotations[crbNameAnnotation] + if !ok { + crbName = crbNamePrefix + globalRoleBinding.Name + } + + subject := rbac.GetGRBSubject(globalRoleBinding) + if globalRoleBinding.GlobalRoleName == rbac.GlobalRestrictedAdmin { + if err := grb.syncDownstreamClusterPermissions(subject, globalRoleBinding); err != nil { + return err + } + } + + crb, _ := grb.crbLister.Get("", crbName) + if crb != nil { + subjects := []v1.Subject{subject} + updateSubject := !reflect.DeepEqual(subjects, crb.Subjects) + + updateRoleRef := false + var roleRef v1.RoleRef + gr, _ := grb.grLister.Get("", globalRoleBinding.GlobalRoleName) + if gr != nil { + crNameFromGR := getCRName(gr) + if crNameFromGR != crb.RoleRef.Name { + updateRoleRef = true + roleRef = v1.RoleRef{ + Name: crNameFromGR, + Kind: clusterRoleKind, + } + } + } + if updateSubject || updateRoleRef { + crb = crb.DeepCopy() + if updateRoleRef { + crb.RoleRef = roleRef + } + crb.Subjects = subjects + logrus.Infof("[%v] Updating clusterRoleBinding %v for globalRoleBinding %v user %v", grbController, crb.Name, globalRoleBinding.Name, globalRoleBinding.UserName) + if _, err := grb.crbClient.Update(crb); err != nil { + return fmt.Errorf("couldn't update ClusterRoleBinding %v: %w", crb.Name, err) + } + } + return grb.addRulesForTemplateAndTemplateVersions(globalRoleBinding, subject) + } + + logrus.Infof("Creating new GlobalRoleBinding for GlobalRoleBinding %v", globalRoleBinding.Name) + gr, _ := grb.grLister.Get("", globalRoleBinding.GlobalRoleName) + var crName string + if gr != nil { + crName = getCRName(gr) + } else { + crName = generateCRName(globalRoleBinding.GlobalRoleName) + } + logrus.Infof("[%v] Creating clusterRoleBinding for globalRoleBinding %v for user %v with role %v", grbController, globalRoleBinding.Name, globalRoleBinding.UserName, crName) + _, err := grb.crbClient.Create(&v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRoleBinding.APIVersion, + Kind: globalRoleBinding.Kind, + Name: globalRoleBinding.Name, + UID: globalRoleBinding.UID, + }, + }, + Labels: globalRoleBindingLabel, + }, + Subjects: []v1.Subject{subject}, + RoleRef: v1.RoleRef{ + Name: crName, + Kind: clusterRoleKind, + }, + }) + if err != nil { + return err + } + // Add an annotation to the globalrole indicating the name we used for future updates + if globalRoleBinding.Annotations == nil { + globalRoleBinding.Annotations = map[string]string{} + } + globalRoleBinding.Annotations[crbNameAnnotation] = crbName + + return grb.addRulesForTemplateAndTemplateVersions(globalRoleBinding, subject) +} + +func (grb *globalRoleBindingLifecycle) addRulesForTemplateAndTemplateVersions(globalRoleBinding *v3.GlobalRoleBinding, subject v1.Subject) error { + // Check if the current globalRole has rules for templates and templateversions + gr, err := grb.grLister.Get("", globalRoleBinding.GlobalRoleName) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + isCatalogRole := false + if gr != nil { + for _, rule := range gr.Rules { + if rbac.RuleGivesResourceAccess(rule, TemplateResourceRule) || rbac.RuleGivesResourceAccess(rule, TemplateVersionResourceRule) { + isCatalogRole = true + break + } + } + } + // Roles that give catalog access (i.e. that give access to template/templateversions in the management api group) + // are the only ones that need this special role/rolebinding created for them + if isCatalogRole { + roleName := gr.Name + "-" + GlobalCatalogRole + _, err := grb.roleLister.Get(namespace.GlobalNamespace, roleName) + if err != nil { + return err + } + // create a binding to the namespaced role which corresponds to the GlobalRole this grb refers to + grbName := globalRoleBinding.Name + "-" + globalCatalogRoleBinding + _, err = grb.roleBindingLister.Get(namespace.GlobalNamespace, grbName) + if err != nil { + if apierrors.IsNotFound(err) { + rb := &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: grbName, + Namespace: namespace.GlobalNamespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRoleBinding.APIVersion, + Kind: globalRoleBinding.Kind, + Name: globalRoleBinding.Name, + UID: globalRoleBinding.UID, + }, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: v1.RoleRef{ + Kind: "Role", + Name: roleName, + }, + } + _, err = grb.roleBindings.Create(rb) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else { + return err + } + } + } + return nil +} + +func (grb *globalRoleBindingLifecycle) syncDownstreamClusterPermissions(subject v1.Subject, globalRoleBinding *v3.GlobalRoleBinding) error { + if err := grb.createRestrictedAdminCRBsForUserClusters(subject, globalRoleBinding); err != nil { + return err + } + + return grb.grantRestrictedAdminUserClusterPermissions(subject, globalRoleBinding) +} + +func (grb *globalRoleBindingLifecycle) createRestrictedAdminCRBsForUserClusters(subject v1.Subject, globalRoleBinding *v3.GlobalRoleBinding) error { + // Get CR for each downstream cluster, create CRB with this subject for each such CR + r, _ := labels.NewRequirement(rbac.RestrictedAdminCRForClusters, selection.Exists, []string{}) + crs, err := grb.crLister.List("", labels.NewSelector().Add(*r)) + if err != nil { + return err + } + + var returnErr error + for _, cr := range crs { + clusterName := cr.Labels[rbac.RestrictedAdminCRForClusters] + crbName := clusterName + rbac.RestrictedAdminCRBForClusters + globalRoleBinding.Name + crb, err := grb.crbLister.Get("", crbName) + if err != nil && !apierrors.IsNotFound(err) { + returnErr = errors.Join(returnErr, err) + continue + } + if crb != nil { + continue + } + _, err = grb.crbClient.Create(&v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + OwnerReferences: cr.OwnerReferences, + }, + RoleRef: v1.RoleRef{ + Kind: "ClusterRole", + Name: cr.Name, + }, + Subjects: []v1.Subject{subject}, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + returnErr = errors.Join(returnErr, err) + } + } + return returnErr +} + +func (grb *globalRoleBindingLifecycle) grantRestrictedAdminUserClusterPermissions(subject v1.Subject, globalRoleBinding *v3.GlobalRoleBinding) error { + var returnErr error + clusters, err := grb.clusterLister.List("", labels.NewSelector()) + if err != nil { + return err + } + for _, cluster := range clusters { + if cluster.Name == "local" { + continue + } + rbName := fmt.Sprintf("%s-%s", globalRoleBinding.Name, rbac.RestrictedAdminClusterRoleBinding) + _, err := grb.roleBindingLister.Get(cluster.Name, rbName) + if err != nil { + if !apierrors.IsNotFound(err) { + returnErr = errors.Join(returnErr, err) + continue + } + _, err := grb.roleBindings.Create(&v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: rbName, + Namespace: cluster.Name, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRoleBinding.APIVersion, + Kind: globalRoleBinding.Kind, + UID: globalRoleBinding.UID, + Name: globalRoleBinding.Name, + }, + }, + }, + RoleRef: v1.RoleRef{ + Name: rbac.ClusterCRDsClusterRole, + Kind: "ClusterRole", + }, + Subjects: []v1.Subject{subject}, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + returnErr = errors.Join(returnErr, err) + continue + } + } + + projects, err := grb.projectLister.List(cluster.Name, labels.NewSelector()) + if err != nil { + returnErr = errors.Join(returnErr, err) + continue + } + + for _, project := range projects { + rbName := fmt.Sprintf("%s-%s", globalRoleBinding.Name, rbac.RestrictedAdminProjectRoleBinding) + _, err := grb.roleBindingLister.Get(project.Name, rbName) + if err != nil { + if apierrors.IsNotFound(err) { + _, err := grb.roleBindings.Create(&v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: rbName, + Namespace: project.Name, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRoleBinding.APIVersion, + Kind: globalRoleBinding.Kind, + UID: globalRoleBinding.UID, + Name: globalRoleBinding.Name, + }, + }, + }, + RoleRef: v1.RoleRef{ + Name: rbac.ProjectCRDsClusterRole, + Kind: "ClusterRole", + }, + Subjects: []v1.Subject{subject}, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + returnErr = errors.Join(returnErr, err) + } + } else { + returnErr = errors.Join(returnErr, err) + } + } + } + } + return returnErr +} + +// reconcileNamespacedRoleBindings ensures that RoleBindings exist for each namespace listed in NamespacedRules +// from the associated GlobalRole +func (grb *globalRoleBindingLifecycle) reconcileNamespacedRoleBindings(globalRoleBinding *v3.GlobalRoleBinding) error { + var returnError error + grbName := wrangler.SafeConcatName(globalRoleBinding.Name) + gr, err := grb.grLister.Get("", globalRoleBinding.GlobalRoleName) + if err != nil { + return fmt.Errorf("unable to get globalRole %s: %w", globalRoleBinding.GlobalRoleName, err) + } + + roleBindingUIDs := map[types.UID]struct{}{} + + for ns := range gr.NamespacedRules { + namespace, err := grb.nsCache.Get(ns) + if apierrors.IsNotFound(err) || namespace == nil { + // When a namespace is not found, don't re-enqueue GlobalRoleBinding + logrus.Warnf("[%v] Namespace %s not found. Not re-enqueueing GlobalRoleBinding %s", grController, ns, globalRoleBinding.Name) + continue + } else if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't get namespace %s: %w", ns, err)) + continue + } + + roleName := wrangler.SafeConcatName(gr.Name, ns) + roleRef := v1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: roleName, + } + + subject := rbac.GetGRBSubject(globalRoleBinding) + rbName := wrangler.SafeConcatName(globalRoleBinding.Name, ns) + roleBinding, err := grb.roleBindingLister.Get(ns, rbName) + if err == nil { + if reflect.DeepEqual(roleRef, roleBinding.RoleRef) && roleBinding.Labels != nil && roleBinding.Labels[grbOwnerLabel] == grbName { + roleBindingUIDs[roleBinding.UID] = struct{}{} + continue + } + // Since roleRef is immutable, we have to delete and recreate the RB + err = grb.roleBindings.DeleteNamespaced(roleBinding.Namespace, roleBinding.Name, &metav1.DeleteOptions{}) + if err != nil { + returnError = errors.Join(returnError, err) + continue + } + } else if !apierrors.IsNotFound(err) { + returnError = errors.Join(returnError, err) + continue + } + + // If the namespace is terminating, don't create RoleBinding + if namespace.Status.Phase == corev1.NamespaceTerminating { + logrus.Warnf("[%v] Namespace %s is terminating. Not creating roleBinding %s for %s", grController, ns, rbName, globalRoleBinding.Name) + continue + } + + // Create a new RoleBinding + newRoleBinding := &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: rbName, + Namespace: ns, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: globalRoleBinding.APIVersion, + Kind: globalRoleBinding.Kind, + UID: globalRoleBinding.UID, + Name: globalRoleBinding.Name, + }, + }, + Labels: map[string]string{ + grbOwnerLabel: grbName, + }, + }, + RoleRef: roleRef, + Subjects: []v1.Subject{subject}, + } + + createdRB, err := grb.roleBindings.Create(newRoleBinding) + if err != nil { + returnError = errors.Join(returnError, err) + continue + } + roleBindingUIDs[createdRB.UID] = struct{}{} + } + + // get all the roleBindings claiming to be owned by this GRB and remove any that shouldn't exist + r, err := labels.NewRequirement(grbOwnerLabel, selection.Equals, []string{grbName}) + if err != nil { + return errors.Join(returnError, fmt.Errorf("couldn't create label: %s: %w", grOwnerLabel, err)) + } + // exclude roleBindings created for granting fleet workspace permissions + rFleet, err := labels.NewRequirement(fleetWorkspacePermissionLabel, selection.DoesNotExist, []string{}) + if err != nil { + return errors.Join(returnError, fmt.Errorf("couldn't create label: %s: %w", grOwnerLabel, err)) + } + + rbs, err := grb.roleBindingLister.List("", labels.NewSelector().Add(*r).Add(*rFleet)) + if err != nil { + return errors.Join(returnError, + fmt.Errorf("couldn't list roleBindings with label %s : %s: %w", grbOwnerLabel, grbName, err)) + } + + // After creating/updating all RBs, if the number of RBs with the grbOwnerLabel is the same as + // as the number of created/updated RBs, we know there are no invalid RBs to purge + if len(rbs) != len(roleBindingUIDs) { + err = grb.purgeInvalidNamespacedRBs(rbs, roleBindingUIDs) + if err != nil { + returnError = errors.Join(returnError, err) + } + } + return returnError +} + +// purgeInvalidNamespacedRBs removes any roleBindings that aren't in the namespaces listed in the associated GlobalRole.namespacedRules +func (grb *globalRoleBindingLifecycle) purgeInvalidNamespacedRBs(rbs []*v1.RoleBinding, uids map[types.UID]struct{}) error { + var returnError error + for _, rb := range rbs { + if _, ok := uids[rb.UID]; !ok { + err := grb.roleBindings.DeleteNamespaced(rb.Namespace, rb.Name, &metav1.DeleteOptions{}) + if err != nil { + returnError = errors.Join(returnError, fmt.Errorf("couldn't delete roleBinding %s: %w", rb.Name, err)) + } + } + } + return returnError +} + +// isCRTBValid determines if a given CRTB is up to date for a given cluster and owning global role binding. Should +// only be used in the context of CRTBs owned by GRBs +func isCRTBValid(crtb *v3.ClusterRoleTemplateBinding, cluster *v3.Cluster, binding *v3.GlobalRoleBinding) bool { + return crtb != nil && cluster != nil && binding != nil && + crtb.ClusterName == cluster.Name && + crtb.UserName == binding.UserName && + crtb.GroupPrincipalName == binding.GroupPrincipalName && + crtb.DeletionTimestamp == nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler_test.go new file mode 100644 index 0000000..263bc6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/globalrolebinding_handler_test.go @@ -0,0 +1,1944 @@ +package globalroles + +import ( + "fmt" + "testing" + "time" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + apisv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + normanv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + rbacFakes "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" +) + +var ( + inheritedTestGr = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "inherit-test-gr", + }, + InheritedClusterRoles: []string{"cluster-owner"}, + } + noInheritTestGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "noinherit-test-gr", + }, + InheritedClusterRoles: []string{}, + } + missingInheritTestGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "missing-test-gr", + }, + } + purgeTestGR = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "purge-inherit-test-gr", + }, + InheritedClusterRoles: []string{"already-exists", "missing", + "wrong-cluster-name", "wrong-user-name", "wrong-group-name", + "deleting", "duplicate"}, + } + notLocalCluster = v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "not-local", + }, + } + errorCluster = v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "error", + }, + } + localCluster = v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "local", + }, + } + namespacedRulesGRB = v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGRB", + }, + UserName: "username", + GlobalRoleName: "namespacedRulesGR", + } +) + +type grbTestStateChanges struct { + t *testing.T + createdCRTBs []*v3.ClusterRoleTemplateBinding + createdCRBs []*rbacv1.ClusterRoleBinding + deletedCRTBNames []string + createdRBs map[string]*rbacv1.RoleBinding + deletedRBsNames map[string]struct{} + fwhCalled bool +} +type grbTestState struct { + crtbCacheMock *fake.MockCacheInterface[*v3.ClusterRoleTemplateBinding] + grListerMock *fakes.GlobalRoleListerMock + crbListerMock *rbacFakes.ClusterRoleBindingListerMock + clusterListerMock *fakes.ClusterListerMock + crtbClientMock *fakes.ClusterRoleTemplateBindingInterfaceMock + crbClientMock *rbacFakes.ClusterRoleBindingInterfaceMock + nsCacheMock *fake.MockNonNamespacedCacheInterface[*corev1.Namespace] + rListerMock *rbacFakes.RoleListerMock + rbListerMock *rbacFakes.RoleBindingListerMock + rbClientMock *rbacFakes.RoleBindingInterfaceMock + fwhMock *fleetPermissionsHandlerMock + stateChanges *grbTestStateChanges +} + +func TestCreateUpdate(t *testing.T) { + // right now, create and update have the same input/output, so they are tested in the same way + t.Parallel() + + readOnlyRoleName := "read-only" + userName := "test-user" + gr := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-gr", + UID: "5678", + }, + Rules: []rbacv1.PolicyRule{readPodPolicyRule}, + InheritedClusterRoles: []string{readOnlyRoleName}, + } + + grb := v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + TypeMeta: metav1.TypeMeta{ + APIVersion: apisv3.GlobalRoleBindingGroupVersionKind.GroupVersion().String(), + Kind: apisv3.GlobalRoleBindingGroupVersionKind.Kind, + }, + GlobalRoleName: gr.Name, + UserName: userName, + } + grbOwnerRef := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: "test-grb", + UID: types.UID("1234"), + } + + addAnnotation := func(grb *v3.GlobalRoleBinding) *v3.GlobalRoleBinding { + newGRB := grb.DeepCopy() + newGRB.Annotations = map[string]string{ + "authz.management.cattle.io/crb-name": "cattle-globalrolebinding-" + grb.Name, + } + return newGRB + } + + tests := []struct { + name string + stateSetup func(grbTestState) + stateAssertions func(grbTestStateChanges) + inputBinding *v3.GlobalRoleBinding + wantBinding *v3.GlobalRoleBinding + wantError bool + }{ + { + name: "success on both cluster and global permissions", + stateSetup: func(state grbTestState) { + // mocks for both cluster and global permissions + state.grListerMock.GetFunc = func(namespace, name string) (*v3.GlobalRole, error) { + if name == gr.Name && namespace == "" { + return &gr, nil + } + return nil, fmt.Errorf("not found") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + // mocks for just cluster permissions + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + + // mocks for just global permissions + state.crbListerMock.GetFunc = func(namespace, name string) (*rbacv1.ClusterRoleBinding, error) { + return nil, fmt.Errorf("not found") + } + state.crbClientMock.CreateFunc = func(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + state.stateChanges.createdCRBs = append(state.stateChanges.createdCRBs, crb) + return crb, nil + } + + // mocks for fleet workspace permissions + state.fwhMock.reconcileFleetWorkspacePermissionsFunc = func(globalRoleBinding *v3.GlobalRoleBinding) error { + state.stateChanges.fwhCalled = true + return nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + require.Len(stateChanges.t, stateChanges.createdCRBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + + // cluster assertions + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, readOnlyRoleName, crtb.RoleTemplateName) + require.Equal(stateChanges.t, userName, crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crtb.OwnerReferences[0]) + + // global assertions + crb := stateChanges.createdCRBs[0] + bindingName := "cattle-globalrolebinding-" + grb.Name + roleName := "cattle-globalrole-" + gr.Name + require.Equal(stateChanges.t, bindingName, crb.Name) + require.Len(stateChanges.t, crb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crb.OwnerReferences[0]) + require.Equal(stateChanges.t, rbacv1.RoleRef{Name: roleName, Kind: "ClusterRole"}, crb.RoleRef) + require.Equal(stateChanges.t, rbacv1.Subject{Name: userName, Kind: "User", APIGroup: rbacv1.GroupName}, crb.Subjects[0]) + require.Equal(stateChanges.t, "true", crb.Labels["authz.management.cattle.io/globalrolebinding"]) + + // fleet workspace assertions + require.Equal(stateChanges.t, true, stateChanges.fwhCalled) + }, + inputBinding: grb.DeepCopy(), + wantBinding: addAnnotation(&grb), + wantError: false, + }, + { + name: "success on global, failure on cluster", + stateSetup: func(state grbTestState) { + // mocks for both cluster and global permissions + state.grListerMock.GetFunc = func(namespace, name string) (*v3.GlobalRole, error) { + if name == gr.Name && namespace == "" { + return &gr, nil + } + return nil, fmt.Errorf("not found") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + // mocks for just cluster permissions + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return nil, fmt.Errorf("server not available") + } + + // mocks for just global permissions + state.crbListerMock.GetFunc = func(namespace, name string) (*rbacv1.ClusterRoleBinding, error) { + return nil, fmt.Errorf("not found") + } + state.crbClientMock.CreateFunc = func(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + state.stateChanges.createdCRBs = append(state.stateChanges.createdCRBs, crb) + return crb, nil + } + + // mocks for fleet workspace permissions + state.fwhMock.reconcileFleetWorkspacePermissionsFunc = func(globalRoleBinding *v3.GlobalRoleBinding) error { + state.stateChanges.fwhCalled = true + return nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.createdCRBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + + // global assertions + crb := stateChanges.createdCRBs[0] + bindingName := "cattle-globalrolebinding-" + grb.Name + roleName := "cattle-globalrole-" + gr.Name + require.Equal(stateChanges.t, bindingName, crb.Name) + ownerRef := crb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + require.Equal(stateChanges.t, rbacv1.RoleRef{Name: roleName, Kind: "ClusterRole"}, crb.RoleRef) + require.Equal(stateChanges.t, rbacv1.Subject{Name: userName, Kind: "User", APIGroup: rbacv1.GroupName}, crb.Subjects[0]) + require.Equal(stateChanges.t, "true", crb.Labels["authz.management.cattle.io/globalrolebinding"]) + + // fleet workspace assertions + require.Equal(stateChanges.t, true, stateChanges.fwhCalled) + }, + inputBinding: grb.DeepCopy(), + wantBinding: addAnnotation(&grb), + wantError: true, + }, + { + name: "success on cluster, failure on global", + stateSetup: func(state grbTestState) { + // mocks for both cluster and global permissions + state.grListerMock.GetFunc = func(namespace, name string) (*v3.GlobalRole, error) { + if name == gr.Name && namespace == "" { + return &gr, nil + } + return nil, fmt.Errorf("not found") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + // mocks for just cluster permissions + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + + // mocks for just global permissions + state.crbListerMock.GetFunc = func(namespace, name string) (*rbacv1.ClusterRoleBinding, error) { + return nil, fmt.Errorf("not found") + } + state.crbClientMock.CreateFunc = func(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + state.stateChanges.createdCRBs = append(state.stateChanges.createdCRBs, crb) + return nil, fmt.Errorf("server not available") + } + + // mocks for fleet workspace permissions + state.fwhMock.reconcileFleetWorkspacePermissionsFunc = func(globalRoleBinding *v3.GlobalRoleBinding) error { + state.stateChanges.fwhCalled = true + return nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + require.Len(stateChanges.t, stateChanges.createdCRBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + + // cluster assertions + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, readOnlyRoleName, crtb.RoleTemplateName) + require.Equal(stateChanges.t, userName, crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crtb.OwnerReferences[0]) + + // global assertions + crb := stateChanges.createdCRBs[0] + bindingName := "cattle-globalrolebinding-" + grb.Name + roleName := "cattle-globalrole-" + gr.Name + require.Equal(stateChanges.t, bindingName, crb.Name) + require.Len(stateChanges.t, crb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crb.OwnerReferences[0]) + require.Equal(stateChanges.t, rbacv1.RoleRef{Name: roleName, Kind: "ClusterRole"}, crb.RoleRef) + require.Equal(stateChanges.t, rbacv1.Subject{Name: userName, Kind: "User", APIGroup: rbacv1.GroupName}, crb.Subjects[0]) + require.Equal(stateChanges.t, "true", crb.Labels["authz.management.cattle.io/globalrolebinding"]) + + // fleet workspace assertions + require.Equal(stateChanges.t, true, stateChanges.fwhCalled) + }, + inputBinding: grb.DeepCopy(), + wantBinding: &grb, + wantError: true, + }, + { + name: "failure on cluster and global", + stateSetup: func(state grbTestState) { + // mocks for both cluster and global permissions + state.grListerMock.GetFunc = func(namespace, name string) (*v3.GlobalRole, error) { + return nil, fmt.Errorf("not found") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + // mocks for just cluster permissions + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + + // mocks for just global permissions + state.crbListerMock.GetFunc = func(namespace, name string) (*rbacv1.ClusterRoleBinding, error) { + return nil, fmt.Errorf("not found") + } + state.crbClientMock.CreateFunc = func(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + state.stateChanges.createdCRBs = append(state.stateChanges.createdCRBs, crb) + return nil, fmt.Errorf("server not available") + } + + // mocks for fleet workspace permissions + state.fwhMock.reconcileFleetWorkspacePermissionsFunc = func(globalRoleBinding *v3.GlobalRoleBinding) error { + state.stateChanges.fwhCalled = true + return nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.createdCRBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + + // global assertions + crb := stateChanges.createdCRBs[0] + bindingName := "cattle-globalrolebinding-" + grb.Name + roleName := "cattle-globalrole-" + gr.Name + require.Equal(stateChanges.t, bindingName, crb.Name) + require.Len(stateChanges.t, crb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crb.OwnerReferences[0]) + require.Equal(stateChanges.t, rbacv1.RoleRef{Name: roleName, Kind: "ClusterRole"}, crb.RoleRef) + require.Equal(stateChanges.t, rbacv1.Subject{Name: userName, Kind: "User", APIGroup: rbacv1.GroupName}, crb.Subjects[0]) + require.Equal(stateChanges.t, "true", crb.Labels["authz.management.cattle.io/globalrolebinding"]) + + // fleet workspace assertions + require.Equal(stateChanges.t, true, stateChanges.fwhCalled) + }, + inputBinding: grb.DeepCopy(), + wantBinding: &grb, + wantError: true, + }, + { + name: "success on cluster and global permissions, failure on fleet workspace permissions", + stateSetup: func(state grbTestState) { + // mocks for both cluster and global permissions + state.grListerMock.GetFunc = func(namespace, name string) (*v3.GlobalRole, error) { + if name == gr.Name && namespace == "" { + return &gr, nil + } + return nil, fmt.Errorf("not found") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + // mocks for just cluster permissions + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + + // mocks for just global permissions + state.crbListerMock.GetFunc = func(namespace, name string) (*rbacv1.ClusterRoleBinding, error) { + return nil, fmt.Errorf("not found") + } + state.crbClientMock.CreateFunc = func(crb *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + state.stateChanges.createdCRBs = append(state.stateChanges.createdCRBs, crb) + return crb, nil + } + + // mocks for fleet workspace permissions + state.fwhMock.reconcileFleetWorkspacePermissionsFunc = func(globalRoleBinding *v3.GlobalRoleBinding) error { + state.stateChanges.fwhCalled = true + return fmt.Errorf("unavailable") + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + require.Len(stateChanges.t, stateChanges.createdCRBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + + // cluster assertions + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, readOnlyRoleName, crtb.RoleTemplateName) + require.Equal(stateChanges.t, userName, crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crtb.OwnerReferences[0]) + + // global assertions + crb := stateChanges.createdCRBs[0] + bindingName := "cattle-globalrolebinding-" + grb.Name + roleName := "cattle-globalrole-" + gr.Name + require.Equal(stateChanges.t, bindingName, crb.Name) + require.Len(stateChanges.t, crb.OwnerReferences, 1) + require.Equal(stateChanges.t, grbOwnerRef, crb.OwnerReferences[0]) + require.Equal(stateChanges.t, rbacv1.RoleRef{Name: roleName, Kind: "ClusterRole"}, crb.RoleRef) + require.Equal(stateChanges.t, rbacv1.Subject{Name: userName, Kind: "User", APIGroup: rbacv1.GroupName}, crb.Subjects[0]) + require.Equal(stateChanges.t, "true", crb.Labels["authz.management.cattle.io/globalrolebinding"]) + + // fleet workspace assertions + require.Equal(stateChanges.t, true, stateChanges.fwhCalled) + }, + inputBinding: grb.DeepCopy(), + wantBinding: addAnnotation(&grb), + wantError: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + grbLifecycle := globalRoleBindingLifecycle{} + testFuncs := []func(*v3.GlobalRoleBinding) (runtime.Object, error){grbLifecycle.Create, grbLifecycle.Updated} + for _, testFunc := range testFuncs { + ctrl := gomock.NewController(t) + crtbCacheMock := fake.NewMockCacheInterface[*v3.ClusterRoleTemplateBinding](ctrl) + grListerMock := fakes.GlobalRoleListerMock{} + crbListerMock := rbacFakes.ClusterRoleBindingListerMock{} + clusterListerMock := fakes.ClusterListerMock{} + crtbClientMock := fakes.ClusterRoleTemplateBindingInterfaceMock{} + crbClientMock := rbacFakes.ClusterRoleBindingInterfaceMock{} + rbListerMock := rbacFakes.RoleBindingListerMock{} + fphMock := fleetPermissionsHandlerMock{} + + stateChanges := grbTestStateChanges{ + t: t, + createdCRTBs: []*v3.ClusterRoleTemplateBinding{}, + createdCRBs: []*rbacv1.ClusterRoleBinding{}, + deletedCRTBNames: []string{}, + } + state := grbTestState{ + crtbCacheMock: crtbCacheMock, + grListerMock: &grListerMock, + crbListerMock: &crbListerMock, + clusterListerMock: &clusterListerMock, + crtbClientMock: &crtbClientMock, + crbClientMock: &crbClientMock, + rbListerMock: &rbListerMock, + fwhMock: &fphMock, + stateChanges: &stateChanges, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + grbLifecycle.grLister = &grListerMock + grbLifecycle.crbLister = &crbListerMock + grbLifecycle.crtbCache = crtbCacheMock + grbLifecycle.clusterLister = &clusterListerMock + grbLifecycle.crtbClient = &crtbClientMock + grbLifecycle.crbClient = &crbClientMock + grbLifecycle.roleBindingLister = &rbListerMock + grbLifecycle.fleetPermissionsHandler = &fphMock + res, resErr := testFunc(test.inputBinding) + require.Equal(t, test.wantBinding, res) + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + } + }) + } +} + +func Test_crtbGrbOwnerIndexer(t *testing.T) { + t.Parallel() + grbOwnedCRTB := &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-alread-exists", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "other-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "some-cluster", + }, + RoleTemplateName: "already-exists", + ClusterName: "other-cluster", + UserName: "test-user", + GroupPrincipalName: "", + } + keys, err := crtbGrbOwnerIndexer(grbOwnedCRTB) + require.NoError(t, err) + require.Len(t, keys, 1) + require.Equal(t, "other-cluster/test-grb", keys[0]) + + noLabelCRTB := &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-alread-exists", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "other-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "some-cluster", + }, + RoleTemplateName: "already-exists", + ClusterName: "other-cluster", + UserName: "test-user", + GroupPrincipalName: "", + } + keys, err = crtbGrbOwnerIndexer(noLabelCRTB) + require.NoError(t, err) + require.Len(t, keys, 0) + + standardCRTB := &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-123xyz", + Namespace: "some-cluster", + }, + RoleTemplateName: "already-exists", + ClusterName: "some-cluster", + UserName: "test-user", + GroupPrincipalName: "", + } + keys, err = crtbGrbOwnerIndexer(standardCRTB) + require.NoError(t, err) + require.Len(t, keys, 0) +} + +func Test_reconcileClusterPermissions(t *testing.T) { + t.Parallel() + grListerGetFunc := func(_ string, name string) (*v3.GlobalRole, error) { + switch name { + case inheritedTestGr.Name: + return &inheritedTestGr, nil + case noInheritTestGR.Name: + return &noInheritTestGR, nil + case missingInheritTestGR.Name: + return &missingInheritTestGR, nil + case purgeTestGR.Name: + return &purgeTestGR, nil + default: + return nil, fmt.Errorf("not found") + } + } + + tests := []struct { + name string + stateSetup func(state grbTestState) + inputObject *v3.GlobalRoleBinding + stateAssertions func(stateChanges grbTestStateChanges) + wantError bool + }{ + { + name: "no inherited roles", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: noInheritTestGR.Name, + UserName: "test-user", + }, + wantError: false, + }, + { + name: "missing inherited roles", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: missingInheritTestGR.Name, + UserName: "test-user", + }, + wantError: false, + }, + { + name: "inherited cluster roles", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "cluster-owner", crtb.RoleTemplateName) + require.Equal(stateChanges.t, "test-user", crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + ownerRef := crtb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: inheritedTestGr.Name, + UserName: "test-user", + }, + wantError: false, + }, + { + name: "inherited cluster roles, purge innacurate roles", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-already-exists-local", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "local", + }, + RoleTemplateName: "already-exists", + ClusterName: "local", + UserName: "test-user", + GroupPrincipalName: "", + }, + }, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-already-exists", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "already-exists", + ClusterName: "not-local", + UserName: "test-user", + GroupPrincipalName: "", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-wrong-cluster-name", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "wrong-cluster-name", + ClusterName: "does-not-exist", + UserName: "test-user", + GroupPrincipalName: "", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-wrong-user-name", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "wrong-user-name", + ClusterName: "not-local", + UserName: "wrong-user", + GroupPrincipalName: "", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-wrong-group-name", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "wrong-group-name", + ClusterName: "not-local", + UserName: "test-user", + GroupPrincipalName: "wrong-group", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-deleting", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + DeletionTimestamp: &metav1.Time{Time: time.Now()}, + }, + RoleTemplateName: "deleting", + ClusterName: "not-local", + UserName: "test-user", + GroupPrincipalName: "", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-duplicate", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "duplicate", + ClusterName: "not-local", + UserName: "test-user", + GroupPrincipalName: "", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-duplicate-2", + Labels: map[string]string{ + grbOwnerLabel: "test-grb", + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + UID: "1234", + Name: "test-grb", + }, + }, + GenerateName: "crtb-grb-", + Namespace: "not-local", + }, + RoleTemplateName: "duplicate", + ClusterName: "not-local", + UserName: "test-user", + GroupPrincipalName: "", + }, + }, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 5) + var roleTemplateNames []string + for _, crtb := range stateChanges.createdCRTBs { + roleTemplateNames = append(roleTemplateNames, crtb.RoleTemplateName) + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-user", crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + ownerRef := crtb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + } + require.Contains(stateChanges.t, roleTemplateNames, "missing") + require.Contains(stateChanges.t, roleTemplateNames, "wrong-cluster-name") + require.Contains(stateChanges.t, roleTemplateNames, "wrong-user-name") + require.Contains(stateChanges.t, roleTemplateNames, "wrong-group-name") + require.Contains(stateChanges.t, roleTemplateNames, "deleting") + + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 6) + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-wrong-cluster-name") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-wrong-user-name") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-wrong-group-name") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-deleting") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-duplicate-2") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-already-exists-local") + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: purgeTestGR.Name, + UserName: "test-user", + }, + wantError: false, + }, + { + name: "cluster lister error", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return nil, fmt.Errorf("server unavailable") + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: inheritedTestGr.Name, + UserName: "test-user", + }, + wantError: true, + }, + { + name: "crtb creation error", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "error/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + if crtb.ClusterName == errorCluster.Name { + return nil, fmt.Errorf("server unavailable") + } + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{&errorCluster, ¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 2) + var clusterNames []string + for _, crtb := range stateChanges.createdCRTBs { + clusterNames = append(clusterNames, crtb.ClusterName) + require.Equal(stateChanges.t, crtb.ClusterName, crtb.Namespace) + require.Equal(stateChanges.t, "cluster-owner", crtb.RoleTemplateName) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-user", crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + ownerRef := crtb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + } + require.Contains(stateChanges.t, clusterNames, notLocalCluster.Name) + require.Contains(stateChanges.t, clusterNames, errorCluster.Name) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: inheritedTestGr.Name, + UserName: "test-user", + }, + wantError: true, + }, + { + name: "indexer error", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "not-local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{}, nil).Times(2) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "error/test-grb").Return(nil, fmt.Errorf("indexer error")).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{&errorCluster, ¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "not-local", crtb.Namespace) + require.Equal(stateChanges.t, "not-local", crtb.ClusterName) + require.Equal(stateChanges.t, "cluster-owner", crtb.RoleTemplateName) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-user", crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + ownerRef := crtb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: inheritedTestGr.Name, + UserName: "test-user", + }, + wantError: true, + }, + { + name: "crtb delete error", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "local/test-grb").Return([]*v3.ClusterRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-delete-local", + GenerateName: "crtb-grb-", + Namespace: "local", + }, + RoleTemplateName: "not-valid", + ClusterName: "local", + UserName: "test-user", + GroupPrincipalName: "", + }, + }, nil) + state.crtbCacheMock.EXPECT().GetByIndex(crtbGrbOwnerIndex, "error/test-grb").Return([]*v3.ClusterRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "crtb-grb-delete", + GenerateName: "crtb-grb-", + Namespace: "error", + }, + RoleTemplateName: "not-valid", + ClusterName: "error", + UserName: "test-user", + GroupPrincipalName: "", + }, + }, nil).Times(2) + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + if name == "crtb-grb-delete" || name == "crtb-grb-delete-local" { + return fmt.Errorf("server unavailable") + } + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{&errorCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 1) + crtb := stateChanges.createdCRTBs[0] + require.Equal(stateChanges.t, "error", crtb.Namespace) + require.Equal(stateChanges.t, "error", crtb.ClusterName) + require.Equal(stateChanges.t, "cluster-owner", crtb.RoleTemplateName) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-grb", crtb.Labels[grbOwnerLabel]) + require.Equal(stateChanges.t, "test-user", crtb.UserName) + require.Equal(stateChanges.t, "", crtb.GroupPrincipalName) + require.Len(stateChanges.t, crtb.OwnerReferences, 1) + ownerRef := crtb.OwnerReferences[0] + require.Equal(stateChanges.t, "management.cattle.io/v3", ownerRef.APIVersion) + require.Equal(stateChanges.t, "GlobalRoleBinding", ownerRef.Kind) + require.Equal(stateChanges.t, "test-grb", ownerRef.Name) + require.Equal(stateChanges.t, types.UID("1234"), ownerRef.UID) + + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 2) + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-delete") + require.Contains(stateChanges.t, stateChanges.deletedCRTBNames, "crtb-grb-delete-local") + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: inheritedTestGr.Name, + UserName: "test-user", + }, + wantError: true, + }, + { + name: "no global role", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = grListerGetFunc + state.crtbClientMock.CreateFunc = func(crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + state.stateChanges.createdCRTBs = append(state.stateChanges.createdCRTBs, crtb) + return crtb, nil + } + state.crtbClientMock.DeleteNamespacedFunc = func(_ string, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedCRTBNames = append(state.stateChanges.deletedCRTBNames, name) + return nil + } + state.clusterListerMock.ListFunc = func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + return []*v3.Cluster{&errorCluster, ¬LocalCluster, &localCluster}, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdCRTBs, 0) + require.Len(stateChanges.t, stateChanges.deletedCRTBNames, 0) + }, + inputObject: &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-grb", + UID: "1234", + }, + GlobalRoleName: "error", + UserName: "test-user", + }, + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + crtbCacheMock := fake.NewMockCacheInterface[*v3.ClusterRoleTemplateBinding](ctrl) + grListerMock := fakes.GlobalRoleListerMock{} + clusterListerMock := fakes.ClusterListerMock{} + crtbClientMock := fakes.ClusterRoleTemplateBindingInterfaceMock{} + state := grbTestState{ + crtbCacheMock: crtbCacheMock, + grListerMock: &grListerMock, + clusterListerMock: &clusterListerMock, + crtbClientMock: &crtbClientMock, + stateChanges: &grbTestStateChanges{ + t: t, + createdCRTBs: []*v3.ClusterRoleTemplateBinding{}, + deletedCRTBNames: []string{}, + }, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + grbLifecycle := globalRoleBindingLifecycle{ + grLister: &grListerMock, + crtbCache: crtbCacheMock, + clusterLister: &clusterListerMock, + crtbClient: &crtbClientMock, + } + resErr := grbLifecycle.reconcileClusterPermissions(test.inputObject) + if test.wantError { + require.Error(t, resErr) + } else { + require.NoError(t, resErr) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + }) + } + +} + +func Test_reconcileNamespacedPermissions(t *testing.T) { + t.Parallel() + + activeNamespace := &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + } + terminatingNamespace := &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceTerminating, + }, + } + + tests := []struct { + name string + stateSetup func(grbTestState) + stateAssertions func(grbTestStateChanges) + globalRoleBinding *v3.GlobalRoleBinding + wantError bool + }{ + { + name: "global role not found", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return nil, fmt.Errorf("error") + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "getting namespace fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, fmt.Errorf("error")) + + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "namespace is nil", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(nil, nil) + + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "getting roleBinding fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(_, _ string) (*rbacv1.RoleBinding, error) { + return nil, fmt.Errorf("error") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "creating roleBinding fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(_, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + return nil, fmt.Errorf("error") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "roleBindings get created", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + state.rbListerMock.GetFunc = func(_, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 2) + + roleBinding, ok := stateChanges.createdRBs["namespacedRulesGRB-namespace1"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace1", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace1", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + subject := rbacv1.Subject{ + Kind: "User", + Name: "username", + APIGroup: rbacv1.GroupName, + } + require.Len(stateChanges.t, roleBinding.Subjects, 1) + require.Equal(stateChanges.t, subject, roleBinding.Subjects[0]) + + roleBinding, ok = stateChanges.createdRBs["namespacedRulesGRB-namespace2"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace2", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace2", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Len(stateChanges.t, roleBinding.Subjects, 1) + require.Equal(stateChanges.t, subject, roleBinding.Subjects[0]) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "roleBindings don't get created in a terminating namespace", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(terminatingNamespace, nil) + + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + state.rbListerMock.GetFunc = func(_, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 0) + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "one NS not found, still creates other RB", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + first := state.nsCacheMock.EXPECT().Get(gomock.Any()).Return(activeNamespace, fmt.Errorf("error")) + second := state.nsCacheMock.EXPECT().Get(gomock.Any()).Return(activeNamespace, nil) + gomock.InOrder(first, second) + + state.rbListerMock.GetFunc = func(_, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + // The second roleBindings should be created despite the first getting an error + // Because the order is not guaranteed, we can't assert any info on the + // created roleBinding, just that it exists + require.Len(stateChanges.t, stateChanges.createdRBs, 1) + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "delete roleBinding from terminating namespace", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get("namespace1").Return(terminatingNamespace, nil) + state.nsCacheMock.EXPECT().Get("namespace2").Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + if namespace == "namespace1" { + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGRB-" + namespace, + Namespace: namespace, + }, + } + return roleBinding, nil + } else { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + // in the case of a terminating namespace, the bad RoleBinding should be deleted, not updated + require.Len(stateChanges.t, stateChanges.deletedRBsNames, 1) + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "namespacedRulesGRB-namespace1") + + // The second RoleBinding in an active namespace should still get created + require.Len(stateChanges.t, stateChanges.createdRBs, 1) + roleBinding, ok := stateChanges.createdRBs["namespacedRulesGRB-namespace2"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace2", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace2", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "update roleBindings with bad roleRef name", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGRB-" + namespace, + Namespace: namespace, + }, + RoleRef: rbacv1.RoleRef{ + Name: "badRoleName", + Kind: "Role", + }, + } + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return nil + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.deletedRBsNames, 2) + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "namespacedRulesGRB-namespace1") + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "namespacedRulesGRB-namespace2") + + require.Len(stateChanges.t, stateChanges.createdRBs, 2) + roleBinding, ok := stateChanges.createdRBs["namespacedRulesGRB-namespace1"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace1", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace1", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + + roleBinding, ok = stateChanges.createdRBs["namespacedRulesGRB-namespace2"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace2", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace2", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "update roleBindings with bad grbOwner label", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGRB-" + namespace, + Namespace: namespace, + Labels: map[string]string{grbOwnerLabel: "bad-owner"}, + }, + RoleRef: rbacv1.RoleRef{ + Name: "namespacedRulesGR-" + namespace, + Kind: "Role", + }, + } + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return nil + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[roleBinding.Name] = roleBinding + roleBinding.UID = "" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Len(stateChanges.t, stateChanges.deletedRBsNames, 2) + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "namespacedRulesGRB-namespace1") + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "namespacedRulesGRB-namespace2") + + require.Len(stateChanges.t, stateChanges.createdRBs, 2) + roleBinding, ok := stateChanges.createdRBs["namespacedRulesGRB-namespace1"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace1", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace1", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + + roleBinding, ok = stateChanges.createdRBs["namespacedRulesGRB-namespace2"] + require.True(stateChanges.t, ok) + require.Equal(stateChanges.t, "namespace2", roleBinding.ObjectMeta.Namespace) + require.Equal(stateChanges.t, "namespacedRulesGR-namespace2", roleBinding.RoleRef.Name) + require.Equal(stateChanges.t, "Role", roleBinding.RoleRef.Kind) + require.Equal(stateChanges.t, "namespacedRulesGRB", roleBinding.Labels[grbOwnerLabel]) + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "update roleBindings fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespacedRulesGRB-" + namespace, + Namespace: namespace, + }, + } + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + return fmt.Errorf("error") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, nil + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "purge RBs that falsely claim to be owned by GRB", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + roleBinding.UID = "1111" + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + roleBindings := []*rbacv1.RoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role", + UID: "2222", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role", + UID: "1111", + }, + }, + } + return roleBindings, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "deleted-role") + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "do not purge RBs that correctly claim to belong to GRB", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, name string) (*rbacv1.RoleBinding, error) { + roleRef := rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: "namespacedRulesGR-" + namespace, + } + + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + grbOwnerLabel: "namespacedRulesGRB", + }, + UID: "1111", + }, + RoleRef: roleRef, + } + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + roleBindings := []*rbacv1.RoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role", + UID: "2222", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role", + UID: "1111", + }, + }, + } + return roleBindings, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "deleted-role") + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: false, + }, + { + name: "delete purged RBs fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + roleBinding.UID = "1111" + return roleBinding, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *metav1.DeleteOptions) error { + state.stateChanges.deletedRBsNames[name] = struct{}{} + return fmt.Errorf("error") + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + roleBindings := []*rbacv1.RoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "deleted-role", + UID: "2222", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "kept-role", + UID: "1111", + }, + }, + } + return roleBindings, nil + } + }, + stateAssertions: func(stateChanges grbTestStateChanges) { + require.Contains(stateChanges.t, stateChanges.deletedRBsNames, "deleted-role") + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + { + name: "list RBs fails", + stateSetup: func(state grbTestState) { + state.grListerMock.GetFunc = func(_, _ string) (*v3.GlobalRole, error) { + return namespacedRulesGR.DeepCopy(), nil + } + state.nsCacheMock.EXPECT().Get(gomock.Any()).AnyTimes().Return(activeNamespace, nil) + + state.rbListerMock.GetFunc = func(namespace string, _ string) (*rbacv1.RoleBinding, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{ + Group: normanv1.RoleBindingGroupVersionKind.Group, + Resource: normanv1.RoleBindingGroupVersionResource.Resource, + }, "") + } + state.rbClientMock.CreateFunc = func(roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + roleBinding.UID = "1111" + return roleBinding, nil + } + state.rbListerMock.ListFunc = func(_ string, _ labels.Selector) ([]*rbacv1.RoleBinding, error) { + return nil, fmt.Errorf("error") + } + }, + globalRoleBinding: namespacedRulesGRB.DeepCopy(), + wantError: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + ctrl := gomock.NewController(t) + grbLifecycle := globalRoleBindingLifecycle{} + grLister := fakes.GlobalRoleListerMock{} + nsCacheMock := fake.NewMockNonNamespacedCacheInterface[*corev1.Namespace](ctrl) + rLister := rbacFakes.RoleListerMock{} + rbLister := rbacFakes.RoleBindingListerMock{} + rbClient := rbacFakes.RoleBindingInterfaceMock{} + + stateChanges := grbTestStateChanges{ + t: t, + createdRBs: map[string]*rbacv1.RoleBinding{}, + deletedRBsNames: map[string]struct{}{}, + } + state := grbTestState{ + nsCacheMock: nsCacheMock, + grListerMock: &grLister, + rListerMock: &rLister, + rbListerMock: &rbLister, + rbClientMock: &rbClient, + stateChanges: &stateChanges, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + + grbLifecycle.nsCache = nsCacheMock + grbLifecycle.grLister = &grLister + grbLifecycle.roleLister = &rLister + grbLifecycle.roleBindingLister = &rbLister + grbLifecycle.roleBindings = &rbClient + err := grbLifecycle.reconcileNamespacedRoleBindings(test.globalRoleBinding) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + }) + } +} + +type fleetPermissionsHandlerMock struct { + reconcileFleetWorkspacePermissionsFunc func(globalRoleBinding *v3.GlobalRoleBinding) error +} + +func (f *fleetPermissionsHandlerMock) reconcileFleetWorkspacePermissionsBindings(globalRoleBinding *v3.GlobalRoleBinding) error { + return f.reconcileFleetWorkspacePermissionsFunc(globalRoleBinding) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/register.go new file mode 100644 index 0000000..6239b92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/globalroles/register.go @@ -0,0 +1,42 @@ +package globalroles + +import ( + "context" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/relatedresource" +) + +const ( + grController = "mgmt-auth-gr-controller" + grbController = "mgmt-auth-grb-controller" +) + +func Register(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + management.Wrangler.Mgmt.GlobalRoleBinding().Cache().AddIndexer(grbGrIndex, grbGrIndexer) + management.Wrangler.Mgmt.GlobalRoleBinding().Cache().AddIndexer(grbSafeConcatIndex, grbSafeConcatIndexer) + management.Wrangler.Mgmt.GlobalRole().Cache().AddIndexer(grNsIndex, grNsIndexer) + management.Wrangler.Mgmt.GlobalRole().Cache().AddIndexer(grSafeConcatIndex, grSafeConcatIndexer) + enqueuer := globalRBACEnqueuer{ + grbCache: management.Wrangler.Mgmt.GlobalRoleBinding().Cache(), + grCache: management.Wrangler.Mgmt.GlobalRole().Cache(), + clusterClient: management.Wrangler.Mgmt.Cluster(), + } + relatedresource.WatchClusterScoped(ctx, grbEnqueuer, enqueuer.enqueueGRBs, management.Wrangler.Mgmt.GlobalRoleBinding(), management.Wrangler.Mgmt.GlobalRole()) + relatedresource.WatchClusterScoped(ctx, clusterGrEnqueuer, enqueuer.clusterEnqueueGRs, management.Wrangler.Mgmt.GlobalRole(), management.Wrangler.Mgmt.Cluster()) + relatedresource.WatchClusterScoped(ctx, crtbGRBEnqueuer, enqueuer.crtbEnqueueGRB, management.Wrangler.Mgmt.GlobalRoleBinding(), management.Wrangler.Mgmt.ClusterRoleTemplateBinding()) + + relatedresource.WatchClusterScoped(ctx, roleEnqueuer, enqueuer.roleEnqueueGR, management.Wrangler.Mgmt.GlobalRole(), management.Wrangler.RBAC.Role()) + relatedresource.WatchClusterScoped(ctx, roleBindingEnqueuer, enqueuer.roleBindingEnqueueGRB, management.Wrangler.Mgmt.GlobalRoleBinding(), management.Wrangler.RBAC.RoleBinding()) + relatedresource.WatchClusterScoped(ctx, namespaceGrEnqueuer, enqueuer.namespaceEnqueueGR, management.Wrangler.Mgmt.GlobalRole(), management.Wrangler.Core.Namespace()) + + relatedresource.WatchClusterScoped(ctx, fleetWorkspaceGrbEnqueuer, enqueuer.fleetWorkspaceEnqueueGR, management.Wrangler.Mgmt.GlobalRole(), management.Wrangler.Mgmt.FleetWorkspace()) + relatedresource.WatchClusterScoped(ctx, clusterRoleEnqueuer, enqueuer.clusterRoleEnqueueGR, management.Wrangler.Mgmt.GlobalRole(), management.Wrangler.RBAC.ClusterRole()) + relatedresource.WatchClusterScoped(ctx, clusterRoleBindingEnqueuer, enqueuer.clusterRoleBindingEnqueueGRB, management.Wrangler.Mgmt.GlobalRoleBinding(), management.Wrangler.RBAC.ClusterRoleBinding()) + + gr := newGlobalRoleLifecycle(management.WithAgent(grController)) + grb := newGlobalRoleBindingLifecycle(management.WithAgent(grbController), clusterManager) + management.Management.GlobalRoles("").AddLifecycle(ctx, grController, gr) + management.Management.GlobalRoleBindings("").AddLifecycle(ctx, grbController, grb) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/indexes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/indexes.go new file mode 100644 index 0000000..dfd9d0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/indexes.go @@ -0,0 +1,76 @@ +package auth + +import ( + "strings" + + "github.com/sirupsen/logrus" + v1 "k8s.io/api/rbac/v1" + meta2 "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" +) + +func rbByOwner(rb *v1.RoleBinding) ([]string, error) { + return getRBOwnerKey(rb), nil +} + +func getRBOwnerKey(rb *v1.RoleBinding) []string { + var owners []string + for _, o := range rb.OwnerReferences { + owners = append(owners, string(o.UID)) + } + return owners +} + +func rbRoleSubjectKey(roleName string, subject v1.Subject) string { + return roleName + "." + subject.Kind + "." + subject.Name +} + +func rbRoleSubjectKeys(roleName string, subjects []v1.Subject) []string { + var keys []string + for _, s := range subjects { + keys = append(keys, rbRoleSubjectKey(roleName, s)) + } + return keys +} + +func indexByMembershipBindingOwner(obj interface{}) ([]string, error) { + ro, ok := obj.(runtime.Object) + if !ok { + return []string{}, nil + } + + meta, err := meta2.Accessor(ro) + if err != nil { + logrus.Warnf("[indexByMembershipBindingOwner] unexpected object type: %T, err: %v", obj, err.Error()) + return []string{}, nil + } + + ns := meta.GetNamespace() + var keys []string + for k, v := range meta.GetLabels() { + if v == MembershipBindingOwner { + keys = append(keys, strings.Join([]string{ns, k}, "/")) + } + } + + return keys, nil +} + +func rbByClusterRoleAndSubject(rb *v1.ClusterRoleBinding) ([]string, error) { + var subjects []v1.Subject + var roleName string + + roleName = rb.RoleRef.Name + subjects = rb.Subjects + return rbRoleSubjectKeys(roleName, subjects), nil +} + +func rbByRoleAndSubject(rb *v1.RoleBinding) ([]string, error) { + var subjects []v1.Subject + var roleName string + + roleName = rb.RoleRef.Name + subjects = rb.Subjects + + return rbRoleSubjectKeys(roleName, subjects), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_grb_cleaner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_grb_cleaner.go new file mode 100644 index 0000000..8d3eed4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_grb_cleaner.go @@ -0,0 +1,66 @@ +package auth + +import ( + "strings" + + grbstore "github.com/rancher/rancher/pkg/api/norman/store/globalrolebindings" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +type grbCleaner struct { + mgmt *config.ManagementContext +} + +func newLegacyGRBCleaner(m *config.ManagementContext) *grbCleaner { + return &grbCleaner{ + mgmt: m, + } +} + +// sync cleans up all GRBs to drop cluster-scoped lifecycle handler finalizers +func (p *grbCleaner) sync(key string, obj *v3.GlobalRoleBinding) (runtime.Object, error) { + if key == "" || obj == nil { + return nil, nil + } + if obj.Annotations[grbstore.GrbVersion] == "true" { + return obj, nil + } + + obj.SetFinalizers(cleanFinalizers(obj.GetFinalizers(), "clusterscoped.controller.cattle.io/grb-sync_")) + cleanAnnotations := cleanAnnotations(obj.GetAnnotations(), "lifecycle.cattle.io/create.grb-sync_") + + if cleanAnnotations == nil { + cleanAnnotations = make(map[string]string) + } + delete(cleanAnnotations, grbstore.OldGrbVersion) + cleanAnnotations[grbstore.GrbVersion] = "true" + obj.SetAnnotations(cleanAnnotations) + return p.mgmt.Management.GlobalRoleBindings("").Update(obj) +} + +// cleanFinalizers takes a list of finalizers and removes any finalizer that has the matching prefix +func cleanFinalizers(finalizers []string, prefix string) []string { + var newFinalizers []string + for _, finalizer := range finalizers { + if strings.HasPrefix(finalizer, prefix) { + continue + } + newFinalizers = append(newFinalizers, finalizer) + } + return newFinalizers +} + +// cleanAnnotations takes an objects annotations and removes any annotation that has the matching prefix +// returning a new map +func cleanAnnotations(annotations map[string]string, prefix string) map[string]string { + newAnnos := make(map[string]string) + for k, v := range annotations { + if strings.HasPrefix(k, prefix) { + continue + } + newAnnos[k] = v + } + return newAnnos +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_rt_cleaner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_rt_cleaner.go new file mode 100644 index 0000000..478f2e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/legacy_rt_cleaner.go @@ -0,0 +1,41 @@ +package auth + +import ( + "github.com/rancher/rancher/pkg/api/norman/store/roletemplate" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +type rtCleaner struct { + clusterLister v3.ClusterLister + mgmt *config.ManagementContext +} + +func newLegacyRTCleaner(mgmt *config.ManagementContext) *rtCleaner { + return &rtCleaner{ + mgmt: mgmt, + clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + } +} + +// sync cleans up all roleTemplates to drop cluster-scoped lifecycle handler finalizers +func (p *rtCleaner) sync(key string, obj *v3.RoleTemplate) (runtime.Object, error) { + if key == "" || obj == nil { + return nil, nil + } + if obj.Annotations[roletemplate.RTVersion] == "true" { + return obj, nil + } + + obj.SetFinalizers(cleanFinalizers(obj.GetFinalizers(), "clusterscoped.controller.cattle.io/cluster-roletemplate-sync_")) + cleanAnnotations := cleanAnnotations(obj.GetAnnotations(), "lifecycle.cattle.io/create.cluster-roletemplate-sync_") + + if cleanAnnotations == nil { + cleanAnnotations = make(map[string]string) + } + delete(cleanAnnotations, roletemplate.OldRTVersion) + cleanAnnotations[roletemplate.RTVersion] = "true" + obj.SetAnnotations(cleanAnnotations) + return p.mgmt.Management.RoleTemplates("").Update(obj) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager.go new file mode 100644 index 0000000..1fdda2d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager.go @@ -0,0 +1,967 @@ +package auth + +import ( + "errors" + "fmt" + "reflect" + "slices" + "sort" + + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/controllers/managementuser/rbac" + v13 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/client-go/tools/cache" +) + +const ( + clusterContext = "cluster" + projectContext = "project" + + rolesCircularSoftLimit = 100 + rolesCircularHardLimit = 500 + clusterNameLabel = "cluster.cattle.io/name" +) + +var commonClusterAndProjectMgmtPlaneResources = map[string]bool{ + "catalogtemplates": true, + "catalogtemplateversions": true, +} + +func newRTBLifecycles(management *config.ManagementContext) (*prtbLifecycle, *crtbLifecycle) { + crbInformer := management.RBAC.ClusterRoleBindings("").Controller().Informer() + rbInformer := management.RBAC.RoleBindings("").Controller().Informer() + + prtb := &prtbLifecycle{ + mgr: &manager{ + mgmt: management, + crLister: management.RBAC.ClusterRoles("").Controller().Lister(), + nsLister: management.Core.Namespaces("").Controller().Lister(), + rLister: management.RBAC.Roles("").Controller().Lister(), + rClient: management.RBAC.Roles(""), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + rbClient: management.RBAC.RoleBindings(""), + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + rbIndexer: rbInformer.GetIndexer(), + crbIndexer: crbInformer.GetIndexer(), + controller: ptrbMGMTController, + }, + projectLister: management.Management.Projects("").Controller().Lister(), + clusterLister: management.Management.Clusters("").Controller().Lister(), + userMGR: management.UserManager, + userLister: management.Management.Users("").Controller().Lister(), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + rbClient: management.RBAC.RoleBindings(""), + crbLister: management.RBAC.ClusterRoleBindings("").Controller().Lister(), + crbClient: management.RBAC.ClusterRoleBindings(""), + prtbClient: management.Management.ProjectRoleTemplateBindings(""), + } + crtb := &crtbLifecycle{ + mgr: &manager{ + mgmt: management, + crLister: management.RBAC.ClusterRoles("").Controller().Lister(), + nsLister: management.Core.Namespaces("").Controller().Lister(), + rLister: management.RBAC.Roles("").Controller().Lister(), + rClient: management.RBAC.Roles(""), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + rbClient: management.RBAC.RoleBindings(""), + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + rbIndexer: rbInformer.GetIndexer(), + crbIndexer: crbInformer.GetIndexer(), + controller: ctrbMGMTController, + }, + clusterLister: management.Management.Clusters("").Controller().Lister(), + userMGR: management.UserManager, + userLister: management.Management.Users("").Controller().Lister(), + projectLister: management.Management.Projects("").Controller().Lister(), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + rbClient: management.RBAC.RoleBindings(""), + crbLister: management.RBAC.ClusterRoleBindings("").Controller().Lister(), + crbClient: management.RBAC.ClusterRoleBindings(""), + crtbClient: management.Management.ClusterRoleTemplateBindings(""), + } + return prtb, crtb +} + +type managerInterface interface { + reconcileClusterMembershipBindingForDelete(string, string) error + reconcileProjectMembershipBindingForDelete(string, string, string) error + removeAuthV2Permissions(string, runtime.Object) error + checkReferencedRoles(string, string, int) (bool, error) + ensureClusterMembershipBinding(string, string, *v3.Cluster, bool, v1.Subject) error + ensureProjectMembershipBinding(string, string, string, *v3.Project, bool, v1.Subject) error + grantManagementPlanePrivileges(string, map[string]string, v1.Subject, interface{}) error + grantManagementClusterScopedPrivilegesInProjectNamespace(string, string, map[string]string, v1.Subject, *v3.ClusterRoleTemplateBinding) error + grantManagementProjectScopedPrivilegesInClusterNamespace(string, string, map[string]string, v1.Subject, *v3.ProjectRoleTemplateBinding) error +} + +type manager struct { + crLister typesrbacv1.ClusterRoleLister + rLister typesrbacv1.RoleLister + rClient typesrbacv1.RoleInterface + rbLister typesrbacv1.RoleBindingLister + rbClient typesrbacv1.RoleBindingInterface + rtLister v3.RoleTemplateLister + nsLister v13.NamespaceLister + rbIndexer cache.Indexer + crbIndexer cache.Indexer + mgmt *config.ManagementContext + controller string +} + +// When a CRTB is created that gives a subject some permissions in a project or cluster, we need to create a "membership" binding +// that gives the subject access to the the cluster custom resource itself +// This is painfully similar to ensureProjectMemberBinding, but making one function that handles both is overly complex +func (m *manager) ensureClusterMembershipBinding(roleName, rtbNsAndName string, cluster *v3.Cluster, makeOwner bool, subject v1.Subject) error { + if err := m.createClusterMembershipRole(roleName, cluster, makeOwner); err != nil { + return err + } + + key := rbRoleSubjectKey(roleName, subject) + crbs, err := m.crbIndexer.ByIndex(membershipBindingOwnerIndex, "/"+rtbNsAndName) + if err != nil { + return err + } + var crb *v1.ClusterRoleBinding + for _, iCRB := range crbs { + if iCRB, ok := iCRB.(*v1.ClusterRoleBinding); ok { + if len(iCRB.Subjects) != 1 { + iKey := rbRoleSubjectKey(iCRB.RoleRef.Name, iCRB.Subjects[0]) + if iKey == key { + crb = iCRB + continue + } + } + } + } + + if err := m.reconcileClusterMembershipBindingForDelete(roleName, rtbNsAndName); err != nil { + return err + } + + if crb != nil { + return nil + } + + objs, err := m.crbIndexer.ByIndex(rbByRoleAndSubjectIndex, key) + if err != nil { + return err + } + + if len(objs) == 0 { + logrus.Infof("[%v] Creating clusterRoleBinding for membership in cluster %v for subject %v", m.controller, cluster.Name, subject.Name) + roleRef := v1.RoleRef{ + Kind: "ClusterRole", + Name: roleName, + } + crbName := pkgrbac.NameForClusterRoleBinding(roleRef, subject) // use deterministic name for crb + _, err = m.mgmt.RBAC.ClusterRoleBindings("").Create(&v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + Annotations: map[string]string{clusterNameLabel: cluster.Name}, + Labels: map[string]string{ + rtbNsAndName: MembershipBindingOwner, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: roleRef, + }) + if !apierrors.IsAlreadyExists(err) { + return err + } + + // if the binding exists but was not found in the index, manually retrieve it so that we can add appropriate labels + crb, err := m.mgmt.RBAC.ClusterRoleBindings("").Get(crbName, metav1.GetOptions{}) + if err != nil { + return err + } + objs = append(objs, crb) + } + + crb, _ = objs[0].(*v1.ClusterRoleBinding) + for owner := range crb.Labels { + if rtbNsAndName == owner { + return nil + } + } + + crb = crb.DeepCopy() + if crb.Labels == nil { + crb.Labels = map[string]string{} + } + crb.Labels[rtbNsAndName] = MembershipBindingOwner + logrus.Infof("[%v] Updating clusterRoleBinding %v for cluster membership in cluster %v for subject %v", m.controller, crb.Name, cluster.Name, subject.Name) + _, err = m.mgmt.RBAC.ClusterRoleBindings("").Update(crb) + return err +} + +// When a PRTB is created that gives a subject some permissions in a project or cluster, we need to create a "membership" binding +// that gives the subject access to the the project/cluster custom resource itself +func (m *manager) ensureProjectMembershipBinding(roleName, rtbNsAndName, namespace string, project *v3.Project, makeOwner bool, subject v1.Subject) error { + if err := m.createProjectMembershipRole(roleName, namespace, project, makeOwner); err != nil { + return err + } + + key := rbRoleSubjectKey(roleName, subject) + rbs, err := m.rbIndexer.ByIndex(membershipBindingOwnerIndex, namespace+"/"+rtbNsAndName) + if err != nil { + return err + } + var rb *v1.RoleBinding + for _, iRB := range rbs { + if iRB, ok := iRB.(*v1.RoleBinding); ok { + if len(iRB.Subjects) != 1 { + iKey := rbRoleSubjectKey(iRB.RoleRef.Name, iRB.Subjects[0]) + if iKey == key { + rb = iRB + continue + } + } + } + } + + if err := m.reconcileProjectMembershipBindingForDelete(namespace, roleName, rtbNsAndName); err != nil { + return err + } + + if rb != nil { + return nil + } + + objs, err := m.rbIndexer.ByIndex(rbByRoleAndSubjectIndex, key) + if err != nil { + return err + } + + if len(objs) == 0 { + logrus.Infof("[%v] Creating roleBinding for membership in project %v for subject %v", m.controller, project.Name, subject.Name) + roleRef := v1.RoleRef{ + Kind: "Role", + Name: roleName, + } + // use deterministic name for rb + rbName := pkgrbac.NameForRoleBinding(namespace, roleRef, subject) + _, err = m.mgmt.RBAC.RoleBindings(namespace).Create(&v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: rbName, + Labels: map[string]string{ + rtbNsAndName: MembershipBindingOwner, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: roleRef, + }) + if !apierrors.IsAlreadyExists(err) { + return err + } + + // if the binding already exists but was not found in the index, manually retrieve it so that we can add appropriate labels + rb, err := m.mgmt.RBAC.RoleBindings(namespace).Get(rbName, metav1.GetOptions{}) + if err != nil { + return err + } + objs = append(objs, rb) + } + + rb, _ = objs[0].(*v1.RoleBinding) + for owner := range rb.Labels { + if rtbNsAndName == owner { + return nil + } + } + + rb = rb.DeepCopy() + if rb.Labels == nil { + rb.Labels = map[string]string{} + } + rb.Labels[rtbNsAndName] = MembershipBindingOwner + logrus.Infof("[%v] Updating roleBinding %v for project membership in project %v for subject %v", m.controller, rb.Name, project.Name, subject.Name) + _, err = m.mgmt.RBAC.RoleBindings(namespace).Update(rb) + return err +} + +// Creates a role that lets the bound subject see (if they are an ordinary member) the project or cluster in the mgmt api +// (or CRUD the project/cluster if they are an owner) +func (m *manager) createClusterMembershipRole(roleName string, cluster *v3.Cluster, makeOwner bool) error { + if cr, _ := m.crLister.Get("", roleName); cr == nil { + return m.createMembershipRole(clusterResource, roleName, makeOwner, cluster, m.mgmt.RBAC.ClusterRoles("").ObjectClient(), true) + } + return nil +} + +// Creates a role that lets the bound subject see (if they are an ordinary member) the project in the mgmt api +// (or CRUD the project if they are an owner) +func (m *manager) createProjectMembershipRole(roleName, namespace string, project *v3.Project, makeOwner bool) error { + if cr, _ := m.rLister.Get(namespace, roleName); cr == nil { + return m.createMembershipRole(projectResource, roleName, makeOwner, project, m.mgmt.RBAC.Roles(namespace).ObjectClient(), false) + } + return nil +} + +func (m *manager) createMembershipRole(resourceType, roleName string, makeOwner bool, ownerObject interface{}, client *objectclient.ObjectClient, clusterRole bool) error { + metaObj, err := meta.Accessor(ownerObject) + if err != nil { + return err + } + typeMeta, err := meta.TypeAccessor(ownerObject) + if err != nil { + return err + } + rules := []v1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Resources: []string{resourceType}, + ResourceNames: []string{metaObj.GetName()}, + Verbs: []string{"get"}, + }, + } + + if makeOwner { + rules[0].Verbs = []string{"*"} + } else { + rules[0].Verbs = []string{"get"} + } + logrus.Infof("[%v] Creating role/clusterRole %v", m.controller, roleName) + var toCreate runtime.Object + objectMeta := metav1.ObjectMeta{ + Name: roleName, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: typeMeta.GetAPIVersion(), + Kind: typeMeta.GetKind(), + Name: metaObj.GetName(), + UID: metaObj.GetUID(), + }, + }, + } + if clusterRole { + objectMeta.Annotations = map[string]string{clusterNameLabel: metaObj.GetName()} + toCreate = &v1.ClusterRole{ + ObjectMeta: objectMeta, + Rules: rules, + } + } else { + toCreate = &v1.Role{ + ObjectMeta: objectMeta, + Rules: rules, + } + } + _, err = client.Create(toCreate) + return err +} + +// The CRTB has been deleted or modified, either delete or update the membership binding so that the subject +// is removed from the cluster if they should be +func (m *manager) reconcileClusterMembershipBindingForDelete(roleToKeep, rtbNsAndName string) error { + convert := func(i interface{}) string { + rb, _ := i.(*v1.ClusterRoleBinding) + return rb.RoleRef.Name + } + + return m.reconcileMembershipBindingForDelete("", roleToKeep, rtbNsAndName, m.crbIndexer, convert, m.mgmt.RBAC.ClusterRoleBindings("").ObjectClient()) +} + +// The PRTB has been deleted, either delete or update the project membership binding so that the subject +// is removed from the project if they should be +func (m *manager) reconcileProjectMembershipBindingForDelete(namespace, roleToKeep, rtbNsAndName string) error { + convert := func(i interface{}) string { + rb, _ := i.(*v1.RoleBinding) + return rb.RoleRef.Name + } + + return m.reconcileMembershipBindingForDelete(namespace, roleToKeep, rtbNsAndName, m.rbIndexer, convert, m.mgmt.RBAC.RoleBindings(namespace).ObjectClient()) +} + +type convertFn func(i interface{}) string + +func (m *manager) reconcileMembershipBindingForDelete(namespace, roleToKeep, rtbNsAndName string, index cache.Indexer, convert convertFn, client *objectclient.ObjectClient) error { + roleBindings, err := index.ByIndex(membershipBindingOwnerIndex, namespace+"/"+rtbNsAndName) + if err != nil { + return err + } + + for _, elt := range roleBindings { + obj, ok := elt.(runtime.Object) + if !ok { + continue + } + + // copy so we don't modify object in cache + objCopy := obj.DeepCopyObject() + + objMeta, err := meta.Accessor(objCopy) + if err != nil { + return err + } + + roleName := convert(objCopy) + if roleName == roleToKeep { + continue + } + var otherOwners bool + for k, v := range objMeta.GetLabels() { + if k == rtbNsAndName && v == MembershipBindingOwner { + delete(objMeta.GetLabels(), k) + } else if v == MembershipBindingOwner { + // Another rtb is also linked to this roleBinding so don't delete + otherOwners = true + } + } + + if !otherOwners { + logrus.Infof("[%v] Deleting roleBinding %v", m.controller, objMeta.GetName()) + if err := client.Delete(objMeta.GetName(), &metav1.DeleteOptions{}); err != nil { + if apierrors.IsNotFound(err) { + continue + } + return err + } + } else { + logrus.Infof("[%v] Updating owner label for roleBinding %v", m.controller, objMeta.GetName()) + if _, err := client.Update(objMeta.GetName(), objCopy); err != nil { + return err + } + } + } + + return nil +} + +// removeAuthV2Permissions finds any roleBindings based off the owner annotation from the incoming owner. +// This is similar to an ownerReference but this is used across namespaces which ownerReferences does not support. +func (m *manager) removeAuthV2Permissions(setID string, owner runtime.Object) error { + // Get the selector for the dependent roleBindings + selector, err := apply.GetSelectorFromOwner(setID, owner) + if err != nil { + return err + } + + roleBindings, err := m.rbLister.List("", selector) + if err != nil { + return err + } + + var returnErr error + for _, binding := range roleBindings { + err := m.rbClient.DeleteNamespaced(binding.Namespace, binding.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + // Combine all errors so we try our best to delete everything in the first run + returnErr = errors.Join(returnErr, err) + } + } + + return returnErr +} + +// Certain resources (projects, machines, prtbs, crtbs, clusterevents, etc) exist in the management plane but are scoped to clusters or +// projects. They need special RBAC handling because the need to be authorized just inside of the namespace that backs the project +// or cluster they belong to. +func (m *manager) grantManagementPlanePrivileges(roleTemplateName string, resources map[string]string, subject v1.Subject, binding interface{}) error { + bindingMeta, err := meta.Accessor(binding) + if err != nil { + return err + } + bindingTypeMeta, err := meta.TypeAccessor(binding) + if err != nil { + return err + } + namespace := bindingMeta.GetNamespace() + + roles, err := m.gatherAndDedupeRoles(roleTemplateName) + if err != nil { + return err + } + + desiredRBs := map[string]*v1.RoleBinding{} + for _, role := range roles { + resourceToVerbs := map[string]map[string]string{} + for resource, apiGroup := range resources { + verbs, err := m.checkForManagementPlaneRules(role, resource, apiGroup) + if err != nil { + return err + } + if len(verbs) > 0 { + resourceToVerbs[resource] = verbs + bindingName := bindingMeta.GetName() + "-" + role.Name + if _, ok := desiredRBs[bindingName]; !ok { + desiredRBs[bindingName] = &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: bindingTypeMeta.GetAPIVersion(), + Kind: bindingTypeMeta.GetKind(), + Name: bindingMeta.GetName(), + UID: bindingMeta.GetUID(), + }, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: v1.RoleRef{ + Kind: "Role", + Name: role.Name, + }, + } + } + } + } + if len(resourceToVerbs) > 0 { + if err := m.reconcileManagementPlaneRole(namespace, resourceToVerbs, role); err != nil { + return err + } + } + } + + currentRBs := map[string]*v1.RoleBinding{} + current, err := m.rbIndexer.ByIndex(rbByOwnerIndex, string(bindingMeta.GetUID())) + if err != nil { + return err + } + for _, c := range current { + rb := c.(*v1.RoleBinding) + currentRBs[rb.Name] = rb + } + + return m.reconcileDesiredMGMTPlaneRoleBindings(currentRBs, desiredRBs, namespace) +} + +// grantManagementClusterScopedPrivilegesInProjectNamespace ensures that rolebindings for roles like cluster-owner (that should be able to fully +// manage all projects in a cluster) grant proper permissions to project-scoped resources. Specifically, this satisfies the use case that +// a cluster owner should be able to manage the members of all projects in their cluster +func (m *manager) grantManagementClusterScopedPrivilegesInProjectNamespace(roleTemplateName, projectNamespace string, resources map[string]string, + subject v1.Subject, binding *v3.ClusterRoleTemplateBinding) error { + roles, err := m.gatherAndDedupeRoles(roleTemplateName) + if err != nil { + return err + } + + desiredRBs := map[string]*v1.RoleBinding{} + bindingKey := pkgrbac.GetRTBLabel(binding.ObjectMeta) + for _, role := range roles { + resourceToVerbs := map[string]map[string]string{} + for resource, apiGroup := range resources { + // Adding this check, because we want cluster-owners to have access to catalogtemplates/versions of all projects, but no other cluster roles + // need to access catalogtemplates of projects they do not belong to + if !role.Administrative && commonClusterAndProjectMgmtPlaneResources[resource] { + continue + + } + verbs, err := m.checkForManagementPlaneRules(role, resource, apiGroup) + if err != nil { + return err + } + if len(verbs) > 0 { + resourceToVerbs[resource] = verbs + + bindingName := binding.Name + "-" + role.Name + if _, ok := desiredRBs[bindingName]; !ok { + desiredRBs[bindingName] = &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + Namespace: projectNamespace, + Labels: map[string]string{ + bindingKey: CrtbInProjectBindingOwner, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: v1.RoleRef{ + Kind: "Role", + Name: role.Name, + }, + } + } + } + } + if len(resourceToVerbs) > 0 { + if err := m.reconcileManagementPlaneRole(projectNamespace, resourceToVerbs, role); err != nil { + return err + } + } + } + + currentRBs := map[string]*v1.RoleBinding{} + set := labels.Set(map[string]string{bindingKey: CrtbInProjectBindingOwner}) + current, err := m.rbLister.List(projectNamespace, set.AsSelector()) + if err != nil { + return err + } + for _, rb := range current { + currentRBs[rb.Name] = rb + } + + return m.reconcileDesiredMGMTPlaneRoleBindings(currentRBs, desiredRBs, projectNamespace) +} + +// grantManagementProjectScopedPrivilegesInClusterNamespace ensures that project roles grant permissions to certain cluster-scoped +// resources(notifier, clusterpipelines). These resources exists in cluster namespace but need to be shared between projects. +func (m *manager) grantManagementProjectScopedPrivilegesInClusterNamespace(roleTemplateName, clusterNamespace string, resources map[string]string, + subject v1.Subject, binding *v3.ProjectRoleTemplateBinding) error { + roles, err := m.gatherAndDedupeRoles(roleTemplateName) + if err != nil { + return err + } + + desiredRBs := map[string]*v1.RoleBinding{} + bindingKey := pkgrbac.GetRTBLabel(binding.ObjectMeta) + for _, role := range roles { + resourceToVerbs := map[string]map[string]string{} + for resource, apiGroup := range resources { + verbs, err := m.checkForManagementPlaneRules(role, resource, apiGroup) + if err != nil { + return err + } + if len(verbs) > 0 { + resourceToVerbs[resource] = verbs + + bindingName := fmt.Sprintf("%s-%s-%s", binding.Namespace, binding.Name, role.Name) + + if _, ok := desiredRBs[bindingName]; !ok { + desiredRBs[bindingName] = &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + Namespace: clusterNamespace, + Labels: map[string]string{ + bindingKey: PrtbInClusterBindingOwner, + }, + }, + Subjects: []v1.Subject{subject}, + RoleRef: v1.RoleRef{ + Kind: "Role", + Name: role.Name, + }, + } + } + } + } + if len(resourceToVerbs) > 0 { + if err := m.reconcileManagementPlaneRole(clusterNamespace, resourceToVerbs, role); err != nil { + return err + } + } + } + + currentRBs := map[string]*v1.RoleBinding{} + set := labels.Set(map[string]string{bindingKey: PrtbInClusterBindingOwner}) + current, err := m.rbLister.List(clusterNamespace, set.AsSelector()) + if err != nil { + return err + } + for _, rb := range current { + currentRBs[rb.Name] = rb + } + + return m.reconcileDesiredMGMTPlaneRoleBindings(currentRBs, desiredRBs, clusterNamespace) +} + +func (m *manager) gatherAndDedupeRoles(roleTemplateName string) (map[string]*v3.RoleTemplate, error) { + rt, err := m.rtLister.Get("", roleTemplateName) + if err != nil { + return nil, err + } + allRoles := map[string]*v3.RoleTemplate{} + if err := m.gatherRoleTemplates(rt, allRoles); err != nil { + return nil, err + } + + //de-dupe + roles := map[string]*v3.RoleTemplate{} + for _, role := range allRoles { + roles[role.Name] = role + } + + //toLower + rbac.ToLowerRoleTemplates(roles) + return roles, nil +} + +// reconcileDesiredMGMTPlaneRoleBindings ensures that the desired management plane role bindings +// exist and delete any that should not exist +func (m *manager) reconcileDesiredMGMTPlaneRoleBindings(currentRBs, desiredRBs map[string]*v1.RoleBinding, namespace string) error { + rbsToDelete := map[string]bool{} + processed := map[string]bool{} + for _, rb := range currentRBs { + // protect against an rb being in the list more than once (shouldn't happen, but just to be safe) + if ok := processed[rb.Name]; ok { + continue + } + processed[rb.Name] = true + + if _, ok := desiredRBs[rb.Name]; ok { + delete(desiredRBs, rb.Name) + } else { + rbsToDelete[rb.Name] = true + } + } + + for name := range rbsToDelete { + logrus.Infof("[%v] Deleting roleBinding %v", m.controller, name) + if err := m.rbClient.DeleteNamespaced(namespace, name, &metav1.DeleteOptions{}); err != nil { + return err + } + } + + // If the namespace is terminating don't create RoleBindings + ns, err := m.nsLister.Get("", namespace) + if err != nil { + return fmt.Errorf("couldn't get namespace %v: %w", namespace, err) + } + if ns.Status.Phase == corev1.NamespaceTerminating { + logrus.Warnf("[%v] Namespace %v is terminating, not creating roleBindings", m.controller, namespace) + return nil + } + + for _, rb := range desiredRBs { + logrus.Infof("[%v] Creating roleBinding for subject %v with role %v in namespace %v", m.controller, rb.Subjects[0].Name, rb.RoleRef.Name, rb.Namespace) + _, err := m.rbClient.Create(rb) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } + + return nil +} + +// If the roleTemplate has rules granting access to a management plane resource, return the verbs for those rules +func (m *manager) checkForManagementPlaneRules(role *v3.RoleTemplate, managementPlaneResource string, apiGroup string) (map[string]string, error) { + var rules []v1.PolicyRule + if role.External { + if role.ExternalRules != nil { + rules = append(rules, role.ExternalRules...) + } else { + externalRole, err := m.crLister.Get("", role.Name) + if err != nil && !apierrors.IsNotFound(err) { + // dont error if it doesnt exist + return nil, err + } + if externalRole != nil { + rules = externalRole.Rules + } + } + } else { + rules = role.Rules + } + + verbs := map[string]string{} + for _, rule := range rules { + if (slice.ContainsString(rule.Resources, managementPlaneResource) || slice.ContainsString(rule.Resources, "*")) && len(rule.ResourceNames) == 0 { + if checkGroup(apiGroup, rule) { + for _, v := range rule.Verbs { + verbs[v] = apiGroup + } + } + } + } + + return verbs, nil +} + +func checkGroup(apiGroup string, rule v1.PolicyRule) bool { + for _, rg := range rule.APIGroups { + if rg == apiGroup || rg == "*" { + return true + } + } + return false +} + +// reconcileManagementPlaneRole ensures that the management plane role exists and has the right rules. +// If not, update or create it as needed. +func (m *manager) reconcileManagementPlaneRole(namespace string, resourceToVerbs map[string]map[string]string, rt *v3.RoleTemplate) error { + update := false + if role, err := m.rLister.Get(namespace, rt.Name); err == nil && role != nil { + newRole := role.DeepCopy() + // If the permissions specified by resourceToVerbs is a subset of the existing + // rules of the Role, don't update + for resource, newVerbs := range resourceToVerbs { + currentVerbs := map[string]string{} + for _, rule := range role.Rules { + if slice.ContainsString(rule.Resources, resource) || slice.ContainsString(rule.Resources, "*") { + for _, v := range rule.Verbs { + if rule.APIGroups[0] == newVerbs[v] { + currentVerbs[v] = rule.APIGroups[0] + } else if rule.APIGroups[0] == "*" || newVerbs[v] == "*" { + currentVerbs[v] = newVerbs[v] + } + } + } + } + + if !reflect.DeepEqual(currentVerbs, newVerbs) { + update = true + role = role.DeepCopy() + added := false + for i, rule := range newRole.Rules { + if slice.ContainsString(rule.Resources, resource) || slice.ContainsString(rule.Resources, "*") { + newRole.Rules[i] = buildRule(resource, newVerbs) + added = true + } + } + if !added { + newRole.Rules = append(newRole.Rules, buildRule(resource, newVerbs)) + } + } + } + + // check if any Rule should be removed + if len(resourceToVerbs) < len(role.Rules) { + newRole.Rules = slices.DeleteFunc(newRole.Rules, func(rule v1.PolicyRule) bool { + for resource := range resourceToVerbs { + if slice.ContainsString(rule.Resources, resource) || slice.ContainsString(rule.Resources, "*") { + return false + } + } + update = true + return true + }) + } + + if update { + logrus.Infof("[%v] Updating role %v in namespace %v", m.controller, newRole.Name, namespace) + _, err := m.rClient.Update(newRole) + return err + } + return nil + } + + // If the namespace is terminating, don't create a Role in it + ns, err := m.nsLister.Get("", namespace) + if err != nil { + return fmt.Errorf("couldn't get namespace %v: %w", namespace, err) + } + if ns.Status.Phase == corev1.NamespaceTerminating { + logrus.Warnf("[%v] Namespace %v is terminating, not creating role", m.controller, namespace) + return nil + } + + var rules []v1.PolicyRule + for resource, newVerbs := range resourceToVerbs { + rules = append(rules, buildRule(resource, newVerbs)) + } + logrus.Infof("[%v] Creating role %v in namespace %v", m.controller, rt.Name, namespace) + _, err = m.rClient.Create(&v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: rt.Name, + Namespace: namespace, + }, + Rules: rules, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("couldn't create role %v: %w", rt.Name, err) + } + + return nil +} + +func (m *manager) gatherRoleTemplates(rt *v3.RoleTemplate, roleTemplates map[string]*v3.RoleTemplate) error { + roleTemplates[rt.Name] = rt + + for _, rtName := range rt.RoleTemplateNames { + subRT, err := m.rtLister.Get("", rtName) + if err != nil { + return fmt.Errorf("couldn't get RoleTemplate %s: %w", rtName, err) + } + if err := m.gatherRoleTemplates(subRT, roleTemplates); err != nil { + return fmt.Errorf("couldn't gather RoleTemplate %s: %w", rtName, err) + } + } + + return nil +} + +func buildRule(resource string, verbs map[string]string) v1.PolicyRule { + var vs []string + var apiGroup string + for v, g := range verbs { + vs = append(vs, v) + // This is not efficient but our list of verbs will always be > 10 and we don't know the verbs to access the apiGroup + // Checking for empty string also won't help since core api group is empty string + apiGroup = g + } + + // Sort the verbs, a map does not guarantee order + sort.Strings(vs) + + return v1.PolicyRule{ + Resources: []string{resource}, + Verbs: vs, + APIGroups: []string{apiGroup}, + } +} + +func (m *manager) checkReferencedRoles(roleTemplateName, roleTemplateContext string, depthCounter int) (bool, error) { + if depthCounter == rolesCircularSoftLimit { + logrus.Warnf("roletemplate has caused %v recursive function calls", rolesCircularSoftLimit) + } + if depthCounter >= rolesCircularHardLimit { + return false, fmt.Errorf("roletemplate '%s' has caused %d recursive function calls, possible circular dependency", roleTemplateName, rolesCircularHardLimit) + } + roleTemplate, err := m.rtLister.Get("", roleTemplateName) + if err != nil { + return false, err + } + + // Only check if we are in the same context, if the roleTemplate is from a different context then + // it can't possibly be a owner in the callers context. + if roleTemplate.Context != roleTemplateContext { + return false, nil + } + + // upon upgrades, crtb/prtbs are reconciled before roletemplates. + // So these roles won't have the "own" verb at the time of this check added 2.4.6 onwards + if roleTemplate.Builtin && roleTemplate.Context == projectContext && roleTemplateName == "project-owner" { + return true, nil + } + if roleTemplate.Builtin && roleTemplate.Context == clusterContext && roleTemplateName == "cluster-owner" { + return true, nil + } + + for _, rule := range roleTemplate.Rules { + if slice.ContainsString(rule.Resources, projectResource) || slice.ContainsString(rule.Resources, clusterResource) { + if slice.ContainsString(rule.Verbs, "own") { + return true, nil + } + } + } + isOwnerRole := false + if len(roleTemplate.RoleTemplateNames) > 0 { + depthCounter++ + // get referenced roletemplate + for _, rtName := range roleTemplate.RoleTemplateNames { + isOwnerRole, err = m.checkReferencedRoles(rtName, roleTemplateContext, depthCounter) + if err != nil { + return false, err + } + if isOwnerRole { + return true, nil + } + } + } + return isOwnerRole, nil +} + +func getLabelRequirements(objMeta metav1.ObjectMeta) ([]labels.Requirement, error) { + reqUpdatedLabel, err := labels.NewRequirement(rtbLabelUpdated, selection.DoesNotExist, []string{}) + if err != nil { + return []labels.Requirement{}, err + } + reqNsAndNameLabel, err := labels.NewRequirement(pkgrbac.GetRTBLabel(objMeta), selection.DoesNotExist, []string{}) + if err != nil { + return []labels.Requirement{}, err + } + return []labels.Requirement{*reqUpdatedLabel, *reqNsAndNameLabel}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager_test.go new file mode 100644 index 0000000..cddc3d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/manager_test.go @@ -0,0 +1,721 @@ +package auth + +import ( + "fmt" + "testing" + + normanFakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + fakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + rbacFakes "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var roles = map[string]*v3.RoleTemplate{ + "recursive1": { + RoleTemplateNames: []string{"recursive2"}, + }, + "recursive2": { + RoleTemplateNames: []string{"recursive1"}, + }, + "non-recursive": {}, + "inherit non-recursive": { + RoleTemplateNames: []string{"non-recursive"}, + }, +} + +func Test_checkReferencedRoles(t *testing.T) { + manager := &manager{ + rtLister: &fakes.RoleTemplateListerMock{ + GetFunc: roleListerGetFunc, + }, + } + + type args struct { + rtName string + rtContext string + depthCounter int + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Non-recursive role, none inherited", + args: args{ + rtName: "non-recursive", + rtContext: "", + depthCounter: 0, + }, + wantErr: false, + }, + { + name: "Non-recursive role, inherits another", + args: args{ + rtName: "inherit non-recursive", + rtContext: "", + depthCounter: 0, + }, + wantErr: false, + }, + { + name: "Recursive role", + args: args{ + rtName: "recursive1", + rtContext: "", + depthCounter: 0, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := manager.checkReferencedRoles(tt.args.rtName, tt.args.rtContext, tt.args.depthCounter) + if tt.wantErr { + assert.Error(t, err, "expected an error, got none") + } else { + assert.NoError(t, err, fmt.Sprintf("expected no error, got: %v", err)) + } + }) + } +} + +func roleListerGetFunc(ns, name string) (*v3.RoleTemplate, error) { + role, ok := roles[name] + if !ok { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: v3.RoleTemplateGroupVersionKind.Group, + Resource: v3.RoleTemplateGroupVersionResource.Resource, + }, name) + } + return role, nil +} + +func Test_reconcileDesiredMGMTPlaneRoleBindings(t *testing.T) { + t.Parallel() + + type StateChanges struct { + t *testing.T + createdRBs map[string]*rbacv1.RoleBinding + deletedRBs map[string]bool + } + + type State struct { + nsListerMock *normanFakes.NamespaceListerMock + rbClientMock *rbacFakes.RoleBindingInterfaceMock + stateChanges *StateChanges + } + + rb1 := &rbacv1.RoleBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: "rb1", + Namespace: "ns1", + }, + RoleRef: rbacv1.RoleRef{ + Name: "roleRef1", + }, + Subjects: []rbacv1.Subject{{Name: "subject1"}}, + } + rb2 := &rbacv1.RoleBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: "rb2", + Namespace: "ns2", + }, + RoleRef: rbacv1.RoleRef{ + Name: "roleRef2", + }, + Subjects: []rbacv1.Subject{{Name: "subject2"}}, + } + rb3 := &rbacv1.RoleBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: "rb3", + Namespace: "ns3", + }, + RoleRef: rbacv1.RoleRef{ + Name: "roleRef3", + }, + Subjects: []rbacv1.Subject{{Name: "subject3"}}, + } + + tests := []struct { + name string + currentRBs map[string]*rbacv1.RoleBinding + desiredRBs map[string]*rbacv1.RoleBinding + stateSetup func(State) + stateAssertions func(StateChanges) + wantError bool + }{ + { + name: "get namespace fails", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return nil, fmt.Errorf("error") + } + }, + wantError: true, + }, + { + name: "namespace is terminating", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceTerminating, + }, + }, nil + } + }, + wantError: false, + }, + { + name: "create rb fails", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + return nil, fmt.Errorf("error") + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + return nil + } + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb2}, + wantError: true, + }, + { + name: "delete rb fails", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + return fmt.Errorf("error") + } + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb2}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1}, + wantError: true, + }, + { + name: "add new rb", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[rb.Name] = rb + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + state.stateChanges.deletedRBs[name] = true + return nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 1) + require.Contains(stateChanges.t, stateChanges.createdRBs, "rb2") + require.Len(stateChanges.t, stateChanges.deletedRBs, 0) + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb2}, + wantError: false, + }, + { + name: "delete unwanted rb", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[rb.Name] = rb + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + state.stateChanges.deletedRBs[name] = true + return nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 0) + require.Len(stateChanges.t, stateChanges.deletedRBs, 1) + require.Contains(stateChanges.t, stateChanges.deletedRBs, "rb2") + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb2}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1}, + wantError: false, + }, + { + name: "delete unwanted rb and add new rb", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[rb.Name] = rb + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + state.stateChanges.deletedRBs[name] = true + return nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 1) + require.Contains(stateChanges.t, stateChanges.createdRBs, "rb3") + require.Len(stateChanges.t, stateChanges.deletedRBs, 1) + require.Contains(stateChanges.t, stateChanges.deletedRBs, "rb2") + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb2}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb3": rb3}, + wantError: false, + }, + { + name: "ignore duplicate current rbs", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(namespace string, name string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, nil + } + state.rbClientMock.CreateFunc = func(rb *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + state.stateChanges.createdRBs[rb.Name] = rb + return nil, nil + } + state.rbClientMock.DeleteNamespacedFunc = func(_, name string, _ *v1.DeleteOptions) error { + state.stateChanges.deletedRBs[name] = true + return nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.Len(stateChanges.t, stateChanges.createdRBs, 0) + require.Len(stateChanges.t, stateChanges.deletedRBs, 0) + }, + currentRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1, "rb2": rb1}, + desiredRBs: map[string]*rbacv1.RoleBinding{"rb1": rb1}, + wantError: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + manager := manager{} + nsLister := normanFakes.NamespaceListerMock{} + rbClient := rbacFakes.RoleBindingInterfaceMock{} + + stateChanges := StateChanges{ + t: t, + createdRBs: map[string]*rbacv1.RoleBinding{}, + deletedRBs: map[string]bool{}, + } + state := State{ + nsListerMock: &nsLister, + rbClientMock: &rbClient, + stateChanges: &stateChanges, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + manager.nsLister = &nsLister + manager.rbClient = &rbClient + + err := manager.reconcileDesiredMGMTPlaneRoleBindings(test.currentRBs, test.desiredRBs, "") + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + }) + } +} + +func Test_reconcileManagementPlaneRole(t *testing.T) { + t.Parallel() + + type StateChanges struct { + t *testing.T + newRole *rbacv1.Role + } + + type State struct { + nsListerMock *normanFakes.NamespaceListerMock + rListerMock *rbacFakes.RoleListerMock + rClientMock *rbacFakes.RoleInterfaceMock + stateChanges *StateChanges + } + + rules := map[string]map[string]string{ + "resource1": { + "verb1": "group1", + "verb2": "group1", + }, + "resource2": { + "verb3": "group2", + "verb4": "group2", + }, + } + rule1 := rbacv1.PolicyRule{ + Resources: []string{"resource1"}, + Verbs: []string{"verb1", "verb2"}, + APIGroups: []string{"group1"}, + } + rule2 := rbacv1.PolicyRule{ + Resources: []string{"resource2"}, + Verbs: []string{"verb3", "verb4"}, + APIGroups: []string{"group2"}, + } + rule3 := rbacv1.PolicyRule{ + Resources: []string{"resource3"}, + Verbs: []string{"verb3", "verb4"}, + APIGroups: []string{"group3"}, + } + roleTemplate := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: "roleTemplate", + }, + } + activeNamespace := &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + } + + tests := []struct { + name string + namespace string + resourceToVerbs map[string]map[string]string + roleTemplate *v3.RoleTemplate + stateSetup func(State) + stateAssertions func(StateChanges) + wantError bool + }{ + { + name: "get namespace fails", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(_, _ string) (*corev1.Namespace, error) { + return nil, fmt.Errorf("error") + } + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: true, + }, + { + name: "namespace is terminating", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(_, _ string) (*corev1.Namespace, error) { + return &corev1.Namespace{ + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceTerminating, + }, + }, nil + } + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "create role fails", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(_, _ string) (*corev1.Namespace, error) { + return activeNamespace, nil + } + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + return nil, fmt.Errorf("error") + } + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: true, + }, + { + name: "role already has the right verbs", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + Rules: []rbacv1.PolicyRule{rule1, rule2}, + } + return role, nil + } + // it should not create a role + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 0) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "role does not exist", + stateSetup: func(state State) { + state.nsListerMock.GetFunc = func(_, _ string) (*corev1.Namespace, error) { + return activeNamespace, nil + } + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + return nil, nil + } + state.rClientMock.CreateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 2) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule1) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule2) + require.Equal(stateChanges.t, "roleTemplate", stateChanges.newRole.Name) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "role is missing a rule", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: "role", + }, + Rules: []rbacv1.PolicyRule{rule1}, + } + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 2) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule1) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule2) + require.Equal(stateChanges.t, "role", stateChanges.newRole.Name) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "role has no rules", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: "role", + }, + Rules: []rbacv1.PolicyRule{}, + } + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 2) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule1) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule2) + require.Equal(stateChanges.t, "role", stateChanges.newRole.Name) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "role has rule that is missing verb", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: "role", + }, + Rules: []rbacv1.PolicyRule{ + rule1, + { + Resources: []string{"resource2"}, + Verbs: []string{"verb3"}, + APIGroups: []string{"group2"}, + }, + }, + } + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 2) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule1) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule2) + require.Equal(stateChanges.t, "role", stateChanges.newRole.Name) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "existing role rules are a superset of resourceToVerbs", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: "role", + }, + Rules: []rbacv1.PolicyRule{ + { + Resources: []string{"*"}, + Verbs: []string{"verb1", "verb2"}, + APIGroups: []string{"group1"}, + }, + { + Resources: []string{"resource2"}, + Verbs: []string{"verb3", "verb4"}, + APIGroups: []string{"*"}, + }, + }, + } + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 0) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + { + name: "role have an extra rule, which means a Rule was removed from the RoleTemplate and should be removed", + stateSetup: func(state State) { + state.rListerMock.GetFunc = func(_, _ string) (*rbacv1.Role, error) { + role := &rbacv1.Role{ + ObjectMeta: v1.ObjectMeta{ + Name: "role", + }, + Rules: []rbacv1.PolicyRule{rule1, rule2, rule3}, + } + return role, nil + } + state.rClientMock.UpdateFunc = func(role *rbacv1.Role) (*rbacv1.Role, error) { + state.stateChanges.newRole = role + return nil, nil + } + }, + stateAssertions: func(stateChanges StateChanges) { + require.NotNil(stateChanges.t, stateChanges.newRole) + require.Len(stateChanges.t, stateChanges.newRole.Rules, 2) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule1) + require.Contains(stateChanges.t, stateChanges.newRole.Rules, rule2) + require.Equal(stateChanges.t, "role", stateChanges.newRole.Name) + }, + roleTemplate: roleTemplate, + resourceToVerbs: rules, + wantError: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + manager := manager{} + nsLister := normanFakes.NamespaceListerMock{} + rLister := rbacFakes.RoleListerMock{} + rClient := rbacFakes.RoleInterfaceMock{} + + stateChanges := StateChanges{ + t: t, + newRole: &rbacv1.Role{}, + } + state := State{ + nsListerMock: &nsLister, + rListerMock: &rLister, + rClientMock: &rClient, + stateChanges: &stateChanges, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + manager.nsLister = &nsLister + manager.rLister = &rLister + manager.rClient = &rClient + + err := manager.reconcileManagementPlaneRole(test.namespace, test.resourceToVerbs, test.roleTemplate) + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + if test.stateAssertions != nil { + test.stateAssertions(*state.stateChanges) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler.go new file mode 100644 index 0000000..75418d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler.go @@ -0,0 +1,661 @@ +package auth + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "reflect" + "strings" + "time" + + "github.com/rancher/norman/condition" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/systemimage" + wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/sirupsen/logrus" + v12 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + kerrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + creatorIDAnn = "field.cattle.io/creatorId" + creatorOwnerBindingAnnotation = "authz.management.cattle.io/creator-owner-binding" + projectCreateController = "mgmt-project-rbac-create" + clusterCreateController = "mgmt-cluster-rbac-delete" // TODO the word delete here is wrong, but changing it would break backwards compatibility + projectRemoveController = "mgmt-project-rbac-remove" + clusterRemoveController = "mgmt-cluster-rbac-remove" + roleTemplatesRequired = "authz.management.cattle.io/creator-role-bindings" +) + +var defaultProjectLabels = labels.Set(map[string]string{"authz.management.cattle.io/default-project": "true"}) +var systemProjectLabels = labels.Set(map[string]string{"authz.management.cattle.io/system-project": "true"}) +var crtbCreatorOwnerAnnotations = map[string]string{creatorOwnerBindingAnnotation: "true"} + +func newPandCLifecycles(management *config.ManagementContext) (*projectLifecycle, *clusterLifecycle) { + m := &mgr{ + mgmt: management, + nsLister: management.Core.Namespaces("").Controller().Lister(), + prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + crtbLister: management.Management.ClusterRoleTemplateBindings("").Controller().Lister(), + crtbClient: management.Management.ClusterRoleTemplateBindings(""), + projectLister: management.Management.Projects("").Controller().Lister(), + projects: management.Wrangler.Mgmt.Project(), + roleTemplateLister: management.Management.RoleTemplates("").Controller().Lister(), + systemAccountManager: systemaccount.NewManager(management), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + roleBindings: management.RBAC.RoleBindings(""), + } + p := &projectLifecycle{ + mgr: m, + } + c := &clusterLifecycle{ + mgr: m, + } + return p, c +} + +type projectLifecycle struct { + mgr *mgr +} + +func (l *projectLifecycle) sync(key string, orig *apisv3.Project) (runtime.Object, error) { + if orig == nil || orig.DeletionTimestamp != nil { + projectID := "" + splits := strings.Split(key, "/") + if len(splits) == 2 { + projectID = splits[1] + } + // remove the system account created for this project + logrus.Debugf("Deleting system user for project %v", projectID) + if err := l.mgr.systemAccountManager.RemoveSystemAccount(projectID); err != nil { + return nil, err + } + return nil, nil + } + + obj := orig.DeepCopyObject() + + obj, err := l.mgr.reconcileResourceToNamespace(obj, projectCreateController) + if err != nil { + return nil, err + } + + obj, err = l.mgr.reconcileCreatorRTB(obj) + if err != nil { + return nil, err + } + + // update if it has changed + if obj != nil && !reflect.DeepEqual(orig, obj) { + logrus.Infof("[%v] Updating project %v", projectCreateController, orig.Name) + obj, err = l.mgr.mgmt.Management.Projects("").ObjectClient().Update(orig.Name, obj) + if err != nil { + return nil, err + } + } + if err != nil && !kerrors.IsAlreadyExists(err) { + return nil, err + } + + if err := l.enqueueCrtbs(orig); err != nil { + return obj, err + } + + return obj, nil +} + +func (l *projectLifecycle) enqueueCrtbs(project *apisv3.Project) error { + // get all crtbs in current project's cluster + clusterID := project.Namespace + crtbs, err := l.mgr.crtbLister.List(clusterID, labels.Everything()) + if err != nil { + return err + } + // enqueue them so crtb controller picks them up and lists all projects and generates rolebindings for each crtb in the projects + for _, crtb := range crtbs { + l.mgr.crtbClient.Controller().Enqueue(clusterID, crtb.Name) + } + return nil +} + +func (l *projectLifecycle) Create(obj *apisv3.Project) (runtime.Object, error) { + // no-op because the sync function will take care of it + return obj, nil +} + +func (l *projectLifecycle) Updated(obj *apisv3.Project) (runtime.Object, error) { + // no-op because the sync function will take care of it + return obj, nil +} + +func (l *projectLifecycle) Remove(obj *apisv3.Project) (runtime.Object, error) { + var returnErr error + set := labels.Set{rbac.RestrictedAdminProjectRoleBinding: "true"} + rbs, err := l.mgr.rbLister.List(obj.Name, labels.SelectorFromSet(set)) + returnErr = errors.Join(returnErr, err) + + for _, rb := range rbs { + err := l.mgr.roleBindings.DeleteNamespaced(obj.Name, rb.Name, &v1.DeleteOptions{}) + returnErr = errors.Join(returnErr, err) + } + err = l.mgr.deleteNamespace(obj, projectRemoveController) + returnErr = errors.Join(returnErr, err) + return obj, returnErr +} + +type clusterLifecycle struct { + mgr *mgr +} + +func (l *clusterLifecycle) sync(key string, orig *apisv3.Cluster) (runtime.Object, error) { + if orig == nil || !orig.DeletionTimestamp.IsZero() { + return orig, nil + } + + obj := orig.DeepCopyObject() + obj, err := l.mgr.reconcileResourceToNamespace(obj, clusterCreateController) + if err != nil { + return nil, err + } + + obj, err = l.mgr.createDefaultProject(obj) + if err != nil { + return nil, err + } + + obj, err = l.mgr.createSystemProject(obj) + if err != nil { + return nil, err + } + obj, err = l.mgr.addRTAnnotation(obj, "cluster") + if err != nil { + return nil, err + } + + // update if it has changed + if obj != nil && !reflect.DeepEqual(orig, obj) { + logrus.Infof("[%v] Updating cluster %v", clusterCreateController, orig.Name) + _, err = l.mgr.mgmt.Management.Clusters("").ObjectClient().Update(orig.Name, obj) + if err != nil { + return nil, err + } + } + + obj, err = l.mgr.reconcileCreatorRTB(obj) + if err != nil { + return nil, err + } + + // update if it has changed + if obj != nil && !reflect.DeepEqual(orig, obj) { + logrus.Infof("[%v] Updating cluster %v", clusterCreateController, orig.Name) + _, err = l.mgr.mgmt.Management.Clusters("").ObjectClient().Update(orig.Name, obj) + if err != nil { + return nil, err + } + } + + return nil, nil +} + +func (l *clusterLifecycle) Create(obj *apisv3.Cluster) (runtime.Object, error) { + // no-op because the sync function will take care of it + return obj, nil +} + +func (l *clusterLifecycle) Updated(obj *apisv3.Cluster) (runtime.Object, error) { + // no-op because the sync function will take care of it + return obj, nil +} + +func (l *clusterLifecycle) Remove(obj *apisv3.Cluster) (runtime.Object, error) { + if len(obj.Finalizers) > 1 { + logrus.Debugf("Skipping rbac cleanup for cluster [%s] until all other finalizers are removed.", obj.Name) + return obj, generic.ErrSkip + } + + var returnErr error + set := labels.Set{rbac.RestrictedAdminClusterRoleBinding: "true"} + rbs, err := l.mgr.rbLister.List(obj.Name, labels.SelectorFromSet(set)) + returnErr = errors.Join(returnErr, err) + + for _, rb := range rbs { + err := l.mgr.roleBindings.DeleteNamespaced(obj.Name, rb.Name, &v1.DeleteOptions{}) + returnErr = errors.Join(returnErr, err) + } + returnErr = errors.Join( + l.mgr.deleteSystemProject(obj, clusterRemoveController), + l.mgr.deleteNamespace(obj, clusterRemoveController), + ) + return obj, returnErr +} + +type mgr struct { + mgmt *config.ManagementContext + nsLister corev1.NamespaceLister + projectLister v3.ProjectLister + projects wranglerv3.ProjectClient + + prtbLister v3.ProjectRoleTemplateBindingLister + crtbLister v3.ClusterRoleTemplateBindingLister + crtbClient v3.ClusterRoleTemplateBindingInterface + roleTemplateLister v3.RoleTemplateLister + clusterRoleClient rrbacv1.ClusterRoleInterface + systemAccountManager *systemaccount.Manager + rbLister rrbacv1.RoleBindingLister + roleBindings rrbacv1.RoleBindingInterface +} + +func (m *mgr) createDefaultProject(obj runtime.Object) (runtime.Object, error) { + return m.createProject(project.Default, v32.ClusterConditionDefaultProjectCreated, obj, defaultProjectLabels) +} + +func (m *mgr) createSystemProject(obj runtime.Object) (runtime.Object, error) { + return m.createProject(project.System, v32.ClusterConditionSystemProjectCreated, obj, systemProjectLabels) +} + +func (m *mgr) createProject(name string, cond condition.Cond, obj runtime.Object, labels labels.Set) (runtime.Object, error) { + return cond.DoUntilTrue(obj, func() (runtime.Object, error) { + metaAccessor, err := meta.Accessor(obj) + if err != nil { + return obj, err + } + // Attempt to use the cache first + projects, err := m.projectLister.List(metaAccessor.GetName(), labels.AsSelector()) + if err != nil || len(projects) > 0 { + return obj, err + } + + // Cache failed, try the API + projects2, err := m.projects.List(metaAccessor.GetName(), v1.ListOptions{LabelSelector: labels.String()}) + if err != nil || len(projects2.Items) > 0 { + return obj, err + } + + annotation := map[string]string{} + + creatorID := metaAccessor.GetAnnotations()[creatorIDAnn] + if creatorID != "" { + annotation[creatorIDAnn] = creatorID + } + + if name == project.System { + latestSystemVersion, err := systemimage.GetSystemImageVersion() + if err != nil { + return obj, err + } + annotation[project.SystemImageVersionAnn] = latestSystemVersion + } + + project := &apisv3.Project{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "p-", + Annotations: annotation, + Labels: labels, + }, + Spec: v32.ProjectSpec{ + DisplayName: name, + Description: fmt.Sprintf("%s project created for the cluster", name), + ClusterName: metaAccessor.GetName(), + }, + } + updated, err := m.addRTAnnotation(project, "project") + if err != nil { + return obj, err + } + project = updated.(*apisv3.Project) + logrus.Infof("[%v] Creating %s project for cluster %v", clusterCreateController, name, metaAccessor.GetName()) + if _, err = m.mgmt.Management.Projects(metaAccessor.GetName()).Create(project); err != nil { + return obj, err + } + return obj, nil + }) +} + +// deleteSystemProject deletes the system project(s) for a cluster in preparation for deleting the cluster namespace. +// Normally, the webhook prevents deleting the system project, so Rancher needs to use the sudo user to force it. +// Otherwise, the deleted namespace will be stuck terminating because it cannot garbage collect the project. +func (m *mgr) deleteSystemProject(cluster *apisv3.Cluster, controller string) error { + bypassClient, err := m.projects.WithImpersonation(controllers.WebhookImpersonation()) + if err != nil { + return fmt.Errorf("[%s] failed to create impersonation client: %w", controller, err) + } + projects, err := m.projectLister.List(cluster.Name, systemProjectLabels.AsSelector()) + if err != nil { + return fmt.Errorf("[%s] failed to list projects: %w", controller, err) + } + var deleteError error + for _, p := range projects { + logrus.Infof("[%s] Deleting project %s", controller, p.Name) + err = bypassClient.Delete(p.Namespace, p.Name, nil) + if err != nil { + deleteError = errors.Join(deleteError, fmt.Errorf("[%s] failed to delete project '%s/%s': %w", controller, p.Namespace, p.Name, err)) + } + } + return deleteError +} + +func (m *mgr) reconcileCreatorRTB(obj runtime.Object) (runtime.Object, error) { + return v32.CreatorMadeOwner.DoUntilTrue(obj, func() (runtime.Object, error) { + metaAccessor, err := meta.Accessor(obj) + if err != nil { + return obj, err + } + + typeAccessor, err := meta.TypeAccessor(obj) + if err != nil { + return obj, err + } + + creatorID, ok := metaAccessor.GetAnnotations()[creatorIDAnn] + if !ok || creatorID == "" { + logrus.Warnf("%v %v has no creatorId annotation. Cannot add creator as owner", typeAccessor.GetKind(), metaAccessor.GetName()) + return obj, nil + } + + switch typeAccessor.GetKind() { + case v3.ProjectGroupVersionKind.Kind: + project := obj.(*apisv3.Project) + + if v32.ProjectConditionInitialRolesPopulated.IsTrue(project) { + // The projectRoleBindings are already completed, no need to check + break + } + + // If the project does not have the annotation it indicates the + // project is from a previous rancher version so don't add the + // default bindings. + roleJSON, ok := project.Annotations[roleTemplatesRequired] + if !ok { + return project, nil + } + + roleMap := make(map[string][]string) + err = json.Unmarshal([]byte(roleJSON), &roleMap) + if err != nil { + return obj, err + } + + var createdRoles []string + + for _, role := range roleMap["required"] { + rtbName := "creator-" + role + + if rtb, _ := m.prtbLister.Get(metaAccessor.GetName(), rtbName); rtb != nil { + createdRoles = append(createdRoles, role) + // This projectRoleBinding exists, need to check all of them so keep going + continue + } + + // The projectRoleBinding doesn't exist yet so create it + om := v1.ObjectMeta{ + Name: rtbName, + Namespace: metaAccessor.GetName(), + } + + logrus.Infof("[%v] Creating creator projectRoleTemplateBinding for user %v for project %v", projectCreateController, creatorID, metaAccessor.GetName()) + if _, err := m.mgmt.Management.ProjectRoleTemplateBindings(metaAccessor.GetName()).Create(&apisv3.ProjectRoleTemplateBinding{ + ObjectMeta: om, + ProjectName: metaAccessor.GetNamespace() + ":" + metaAccessor.GetName(), + RoleTemplateName: role, + UserName: creatorID, + }); err != nil && !apierrors.IsAlreadyExists(err) { + return obj, err + } + createdRoles = append(createdRoles, role) + } + + project = project.DeepCopy() + + roleMap["created"] = createdRoles + d, err := json.Marshal(roleMap) + if err != nil { + return obj, err + } + + project.Annotations[roleTemplatesRequired] = string(d) + + if reflect.DeepEqual(roleMap["required"], createdRoles) { + v32.ProjectConditionInitialRolesPopulated.True(project) + logrus.Infof("[%v] Setting InitialRolesPopulated condition on project %v", ctrbMGMTController, project.Name) + } + if _, err := m.mgmt.Management.Projects("").Update(project); err != nil { + return obj, err + } + + case v3.ClusterGroupVersionKind.Kind: + cluster := obj.(*apisv3.Cluster) + + if v32.ClusterConditionInitialRolesPopulated.IsTrue(cluster) { + // The clusterRoleBindings are already completed, no need to check + break + } + + roleJSON, ok := cluster.Annotations[roleTemplatesRequired] + if !ok { + return cluster, nil + } + + roleMap := make(map[string][]string) + err = json.Unmarshal([]byte(roleJSON), &roleMap) + if err != nil { + return obj, err + } + + var createdRoles []string + + for _, role := range roleMap["required"] { + rtbName := "creator-" + role + + if rtb, _ := m.crtbLister.Get(metaAccessor.GetName(), rtbName); rtb != nil { + createdRoles = append(createdRoles, role) + // This clusterRoleBinding exists, need to check all of them so keep going + continue + } + + // The clusterRoleBinding doesn't exist yet so create it + om := v1.ObjectMeta{ + Name: rtbName, + Namespace: metaAccessor.GetName(), + } + om.Annotations = crtbCreatorOwnerAnnotations + + logrus.Infof("[%v] Creating creator clusterRoleTemplateBinding for user %v for cluster %v", projectCreateController, creatorID, metaAccessor.GetName()) + if _, err := m.mgmt.Management.ClusterRoleTemplateBindings(metaAccessor.GetName()).Create(&apisv3.ClusterRoleTemplateBinding{ + ObjectMeta: om, + ClusterName: metaAccessor.GetName(), + RoleTemplateName: role, + UserName: creatorID, + }); err != nil && !apierrors.IsAlreadyExists(err) { + return obj, err + } + createdRoles = append(createdRoles, role) + } + + roleMap["created"] = createdRoles + d, err := json.Marshal(roleMap) + if err != nil { + return obj, err + } + + updateCondition := reflect.DeepEqual(roleMap["required"], createdRoles) + + err = m.updateClusterAnnotationandCondition(cluster, string(d), updateCondition) + if err != nil { + return obj, err + } + } + + return obj, nil + }) +} + +func (m *mgr) deleteNamespace(obj runtime.Object, controller string) error { + o, err := meta.Accessor(obj) + if err != nil { + return condition.Error("MissingMetadata", err) + } + + nsClient := m.mgmt.K8sClient.CoreV1().Namespaces() + ns, err := nsClient.Get(context.TODO(), o.GetName(), v1.GetOptions{}) + if apierrors.IsNotFound(err) { + return nil + } + if ns.Status.Phase != v12.NamespaceTerminating { + logrus.Infof("[%s] Deleting namespace %s", controller, o.GetName()) + err = nsClient.Delete(context.TODO(), o.GetName(), v1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + return nil + } + } + return err +} + +func (m *mgr) reconcileResourceToNamespace(obj runtime.Object, controller string) (runtime.Object, error) { + return v32.NamespaceBackedResource.Do(obj, func() (runtime.Object, error) { + o, err := meta.Accessor(obj) + if err != nil { + return obj, condition.Error("MissingMetadata", err) + } + t, err := meta.TypeAccessor(obj) + if err != nil { + return obj, condition.Error("MissingTypeMetadata", err) + } + + ns, _ := m.nsLister.Get("", o.GetName()) + if ns == nil { + nsClient := m.mgmt.K8sClient.CoreV1().Namespaces() + logrus.Infof("[%v] Creating namespace %v", controller, o.GetName()) + _, err := nsClient.Create(context.TODO(), &v12.Namespace{ + ObjectMeta: v1.ObjectMeta{ + Name: o.GetName(), + Annotations: map[string]string{ + "management.cattle.io/system-namespace": "true", + }, + }, + }, v1.CreateOptions{}) + if err != nil { + return obj, condition.Error("NamespaceCreationFailure", fmt.Errorf("failed to create namespace for %v %v: %w", t.GetKind(), o.GetName(), err)) + } + } + + return obj, nil + }) +} + +func (m *mgr) addRTAnnotation(obj runtime.Object, context string) (runtime.Object, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return obj, err + } + + // If the annotation is already there move along + if _, ok := meta.GetAnnotations()[roleTemplatesRequired]; ok { + return obj, nil + } + + rt, err := m.roleTemplateLister.List("", labels.NewSelector()) + if err != nil { + return obj, err + } + + annoMap := make(map[string][]string) + + var restrictedAdmin bool + if settings.RestrictedDefaultAdmin.Get() == "true" { + restrictedAdmin = true + } + + annoMap["created"] = []string{} + annoMap["required"] = []string{} + + switch context { + case "project": + // If we are in restricted mode, ensure the default projects are not granting + // permissions to the restricted-admin + if restrictedAdmin { + proj := obj.(*apisv3.Project) + if proj.Spec.ClusterName == "local" && (proj.Spec.DisplayName == "Default" || proj.Spec.DisplayName == "System") { + break + } + } + + for _, role := range rt { + if role.ProjectCreatorDefault && !role.Locked { + annoMap["required"] = append(annoMap["required"], role.Name) + } + } + case "cluster": + // If we are in restricted mode, ensure we don't give the default restricted-admin + // the default permissions in the cluster + if restrictedAdmin && meta.GetName() == "local" { + break + } + + for _, role := range rt { + if role.ClusterCreatorDefault && !role.Locked { + annoMap["required"] = append(annoMap["required"], role.Name) + } + } + } + + d, err := json.Marshal(annoMap) + if err != nil { + return obj, err + } + + // Save the required role templates to the annotation on the obj + if meta.GetAnnotations() == nil { + meta.SetAnnotations(make(map[string]string)) + } + meta.GetAnnotations()[roleTemplatesRequired] = string(d) + return obj, nil +} + +func (m *mgr) updateClusterAnnotationandCondition(cluster *apisv3.Cluster, anno string, updateCondition bool) error { + sleep := 100 + for i := 0; i <= 3; i++ { + c, err := m.mgmt.Management.Clusters("").Get(cluster.Name, v1.GetOptions{}) + if err != nil { + return err + } + + c.Annotations[roleTemplatesRequired] = anno + + if updateCondition { + v32.ClusterConditionInitialRolesPopulated.True(c) + } + _, err = m.mgmt.Management.Clusters("").Update(c) + if err != nil { + if apierrors.IsConflict(err) { + time.Sleep(time.Duration(sleep) * time.Millisecond) + sleep *= 2 + continue + } + return err + } + // Only log if we successfully updated the cluster + if updateCondition { + logrus.Infof("[%v] Setting InitialRolesPopulated condition on cluster %v", ctrbMGMTController, cluster.Name) + } + return nil + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler_test.go new file mode 100644 index 0000000..101aecd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/project_cluster_handler_test.go @@ -0,0 +1,54 @@ +package auth + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +const clusterID = "test-cluster" + +func TestEnqueueCrtbsOnProjectCreation(t *testing.T) { + existingCrtbs := []*v3.ClusterRoleTemplateBinding{ + {ObjectMeta: v1.ObjectMeta{ + Name: "crtb-1", + Namespace: clusterID, + }}, + {ObjectMeta: v1.ObjectMeta{ + Name: "crtb-2", + Namespace: clusterID, + }}, + } + + mockedClusterRoleTemplateBindingController := fakes.ClusterRoleTemplateBindingControllerMock{ + EnqueueFunc: func(namespace string, name string) {}, + } + c := projectLifecycle{ + mgr: &mgr{ + crtbLister: &fakes.ClusterRoleTemplateBindingListerMock{ + ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterRoleTemplateBinding, error) { + return existingCrtbs, nil + }, + }, + crtbClient: &fakes.ClusterRoleTemplateBindingInterfaceMock{ + ControllerFunc: func() v3.ClusterRoleTemplateBindingController { + return &mockedClusterRoleTemplateBindingController + }, + }, + }, + } + + newProject := v3.Project{ + ObjectMeta: v1.ObjectMeta{ + Name: "test-project", + Namespace: clusterID, + }, + } + c.enqueueCrtbs(&newProject) + assert.Equal(t, len(existingCrtbs), len(mockedClusterRoleTemplateBindingController.EnqueueCalls())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_handler.go new file mode 100644 index 0000000..cc72ba8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_handler.go @@ -0,0 +1,315 @@ +package auth + +import ( + "errors" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/controllers/management/authprovisioningv2" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/util/retry" +) + +const ( + projectResource = "projects" + ptrbMGMTController = "mgmt-auth-prtb-controller" +) + +var projectManagementPlaneResources = map[string]string{ + "apps": "project.cattle.io", + "apprevisions": "project.cattle.io", + "catalogtemplates": "management.cattle.io", + "catalogtemplateversions": "management.cattle.io", + "sourcecodeproviderconfigs": "project.cattle.io", + "projectloggings": "management.cattle.io", + "projectalertrules": "management.cattle.io", + "projectalertgroups": "management.cattle.io", + "projectcatalogs": "management.cattle.io", + "projectmonitorgraphs": "management.cattle.io", + "projectroletemplatebindings": "management.cattle.io", + "secrets": "", +} +var prtbClusterManagmentPlaneResources = map[string]string{ + "notifiers": "management.cattle.io", + "clustercatalogs": "management.cattle.io", + "catalogtemplates": "management.cattle.io", + "catalogtemplateversions": "management.cattle.io", +} + +type prtbLifecycle struct { + mgr managerInterface + projectLister v3.ProjectLister + clusterLister v3.ClusterLister + userMGR user.Manager + userLister v3.UserLister + rbLister typesrbacv1.RoleBindingLister + rbClient typesrbacv1.RoleBindingInterface + crbLister typesrbacv1.ClusterRoleBindingLister + crbClient typesrbacv1.ClusterRoleBindingInterface + prtbClient v3.ProjectRoleTemplateBindingInterface +} + +func (p *prtbLifecycle) Create(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + if obj.ServiceAccount != "" { + return obj, nil + } + obj, err := p.reconcileSubject(obj) + if err != nil { + return nil, err + } + err = p.reconcileBindings(obj) + return obj, err +} + +func (p *prtbLifecycle) Updated(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + if obj.ServiceAccount != "" { + return obj, nil + } + obj, err := p.reconcileSubject(obj) + if err != nil { + return nil, err + } + if err := p.reconcileLabels(obj); err != nil { + return nil, err + } + err = p.reconcileBindings(obj) + return obj, err +} + +func (p *prtbLifecycle) Remove(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + parts := strings.SplitN(obj.ProjectName, ":", 2) + if len(parts) < 2 { + return nil, fmt.Errorf("cannot determine project and cluster from %v", obj.ProjectName) + } + clusterName := parts[0] + rtbNsAndName := pkgrbac.GetRTBLabel(obj.ObjectMeta) + if err := p.mgr.reconcileProjectMembershipBindingForDelete(clusterName, "", rtbNsAndName); err != nil { + return nil, err + } + + if err := p.mgr.reconcileClusterMembershipBindingForDelete("", rtbNsAndName); err != nil { + return nil, err + } + + if err := p.removeMGMTProjectScopedPrivilegesInClusterNamespace(obj, clusterName); err != nil { + return nil, err + } + + err := p.mgr.removeAuthV2Permissions(authprovisioningv2.PRTBRoleBindingID, obj) + + return nil, err +} + +func (p *prtbLifecycle) reconcileSubject(binding *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + if binding.GroupName != "" || binding.GroupPrincipalName != "" || (binding.UserPrincipalName != "" && binding.UserName != "") { + return binding, nil + } + + if binding.UserPrincipalName != "" && binding.UserName == "" { + displayName := binding.Annotations["auth.cattle.io/principal-display-name"] + user, err := p.userMGR.EnsureUser(binding.UserPrincipalName, displayName) + if err != nil { + return binding, err + } + + binding.UserName = user.Name + return binding, nil + } + + if binding.UserPrincipalName == "" && binding.UserName != "" { + u, err := p.userLister.Get("", binding.UserName) + if err != nil { + return binding, err + } + for _, p := range u.PrincipalIDs { + if strings.HasSuffix(p, binding.UserName) { + binding.UserPrincipalName = p + break + } + } + return binding, nil + } + + return nil, fmt.Errorf("Binding %v has no subject", binding.Name) +} + +// When a PRTB is created or updated, translate it into several k8s roles and bindings to actually enforce the RBAC. +// Specifically: +// - ensure the subject can see the project and its parent cluster in the mgmt API +// - if the subject was granted owner permissions for the project, ensure they can create/update/delete the project +// - if the subject was granted privileges to mgmt plane resources that are scoped to the project, enforce those rules in the project's mgmt plane namespace +func (p *prtbLifecycle) reconcileBindings(binding *v3.ProjectRoleTemplateBinding) error { + if binding.UserName == "" && binding.GroupPrincipalName == "" && binding.GroupName == "" { + return nil + } + + parts := strings.SplitN(binding.ProjectName, ":", 2) + if len(parts) < 2 { + return fmt.Errorf("cannot determine project and cluster from %v", binding.ProjectName) + } + + clusterName := parts[0] + projectName := parts[1] + proj, err := p.projectLister.Get(clusterName, projectName) + if err != nil { + return err + } + if proj == nil { + return fmt.Errorf("cannot create binding because project %v was not found", projectName) + } + + cluster, err := p.clusterLister.Get("", clusterName) + if err != nil { + return err + } + if cluster == nil { + return fmt.Errorf("cannot create binding because cluster %v was not found", clusterName) + } + + roleName := strings.ToLower(fmt.Sprintf("%v-clustermember", clusterName)) + // if roletemplate is not builtin, check if it's inherited/cloned + isOwnerRole, err := p.mgr.checkReferencedRoles(binding.RoleTemplateName, projectContext, 0) + if err != nil { + return err + } + var projectRoleName string + if isOwnerRole { + projectRoleName = strings.ToLower(fmt.Sprintf("%v-projectowner", projectName)) + } else { + projectRoleName = strings.ToLower(fmt.Sprintf("%v-projectmember", projectName)) + } + + subject, err := pkgrbac.BuildSubjectFromRTB(binding) + if err != nil { + return err + } + rtbNsAndName := pkgrbac.GetRTBLabel(binding.ObjectMeta) + if err := p.mgr.ensureProjectMembershipBinding(projectRoleName, rtbNsAndName, clusterName, proj, isOwnerRole, subject); err != nil { + return err + } + if err := p.mgr.ensureClusterMembershipBinding(roleName, rtbNsAndName, cluster, false, subject); err != nil { + return err + } + if err := p.mgr.grantManagementProjectScopedPrivilegesInClusterNamespace(binding.RoleTemplateName, proj.Namespace, prtbClusterManagmentPlaneResources, subject, binding); err != nil { + return err + } + return p.mgr.grantManagementPlanePrivileges(binding.RoleTemplateName, projectManagementPlaneResources, subject, binding) +} + +// removeMGMTProjectScopedPrivilegesInClusterNamespace revokes access that project roles were granted to certain cluster scoped resources like +// catalogtemplates, when the prtb is deleted, by deleting the rolebinding created for this prtb in the cluster's namespace +func (p *prtbLifecycle) removeMGMTProjectScopedPrivilegesInClusterNamespace(binding *v3.ProjectRoleTemplateBinding, clusterName string) error { + set := labels.Set(map[string]string{pkgrbac.GetRTBLabel(binding.ObjectMeta): PrtbInClusterBindingOwner}) + rbs, err := p.rbLister.List(clusterName, set.AsSelector()) + if err != nil { + return err + } + for _, rb := range rbs { + var removeBinding bool + sub := rb.Subjects[0] + if sub.Kind == rbacv1.GroupKind && sub.Name == binding.GroupName { + removeBinding = true + } + if sub.Kind == rbacv1.GroupKind && sub.Name == binding.GroupPrincipalName { + removeBinding = true + } + if sub.Kind == rbacv1.UserKind && sub.Name == binding.UserName { + removeBinding = true + } + if removeBinding { + logrus.Infof("[%v] Deleting rolebinding %v in namespace %v for prtb %v", ptrbMGMTController, rb.Name, clusterName, binding.Name) + if err := p.rbClient.DeleteNamespaced(clusterName, rb.Name, &v1.DeleteOptions{}); err != nil { + return err + } + } + } + return nil +} + +func (p *prtbLifecycle) reconcileLabels(binding *v3.ProjectRoleTemplateBinding) error { + /* Prior to 2.5, for every PRTB, following CRBs and RBs are created in the management clusters + 1. PRTB.UID is the label key for a CRB, PRTB.UID=memberhsip-binding-owner + 2. PRTB.UID is label key for the RB, PRTB.UID=memberhsip-binding-owner + 3. PRTB.UID is label key for RB, PRTB.UID=prtb-in-cluster-binding-owner + */ + if binding.Labels[RtbCrbRbLabelsUpdated] == "true" { + return nil + } + + var returnErr error + requirements, err := getLabelRequirements(binding.ObjectMeta) + if err != nil { + return err + } + bindingKey := pkgrbac.GetRTBLabel(binding.ObjectMeta) + set := labels.Set(map[string]string{string(binding.UID): MembershipBindingOwnerLegacy}) + crbs, err := p.crbLister.List(v1.NamespaceAll, set.AsSelector().Add(requirements...)) + if err != nil { + return err + } + for _, crb := range crbs { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crbToUpdate, updateErr := p.crbClient.Get(crb.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crbToUpdate.Labels == nil { + crbToUpdate.Labels = make(map[string]string) + } + crbToUpdate.Labels[bindingKey] = MembershipBindingOwner + crbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := p.crbClient.Update(crbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + + for _, prtbLabel := range []string{MembershipBindingOwner, PrtbInClusterBindingOwner} { + set = map[string]string{string(binding.UID): prtbLabel} + rbs, err := p.rbLister.List(v1.NamespaceAll, set.AsSelector().Add(requirements...)) + if err != nil { + return err + } + for _, rb := range rbs { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + rbToUpdate, updateErr := p.rbClient.GetNamespaced(rb.Namespace, rb.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if rbToUpdate.Labels == nil { + rbToUpdate.Labels = make(map[string]string) + } + rbToUpdate.Labels[bindingKey] = prtbLabel + rbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := p.rbClient.Update(rbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + } + if returnErr != nil { + return returnErr + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + prtbToUpdate, updateErr := p.prtbClient.GetNamespaced(binding.Namespace, binding.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if prtbToUpdate.Labels == nil { + prtbToUpdate.Labels = make(map[string]string) + } + prtbToUpdate.Labels[RtbCrbRbLabelsUpdated] = "true" + _, err := p.prtbClient.Update(prtbToUpdate) + return err + }) + return retryErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller.go new file mode 100644 index 0000000..05e2221 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller.go @@ -0,0 +1,45 @@ +package auth + +import ( + apiv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + prtbServiceAccountControllerName = "prtb-service-account-controller" + serviceAccountAnnotation = "management.cattle.io/serviceAccount" +) + +type prtbServiceAccountController struct { + prtbClient wranglerv3.ProjectRoleTemplateBindingClient +} + +func newPRTBServiceAccountController(mgmt *config.ManagementContext) *prtbServiceAccountController { + return &prtbServiceAccountController{ + prtbClient: mgmt.Wrangler.Mgmt.ProjectRoleTemplateBinding(), + } +} + +func (c prtbServiceAccountController) sync(_ string, prtb *apiv3.ProjectRoleTemplateBinding) (runtime.Object, error) { + if prtb == nil { + return prtb, nil + } + if prtb.ServiceAccount != "" { + if _, ok := prtb.Annotations[serviceAccountAnnotation]; ok { + return prtb, nil + } + copied := prtb.DeepCopy() + if copied.Annotations == nil { + copied.Annotations = make(map[string]string) + } + copied.Annotations[serviceAccountAnnotation] = copied.ServiceAccount + upd, err := c.prtbClient.Update(copied) + if err != nil { + return nil, err + } + return upd, nil + } + return prtb, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller_test.go new file mode 100644 index 0000000..986d179 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/prtb_sa_controller_test.go @@ -0,0 +1,81 @@ +package auth + +import ( + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestPRTBControllerFindsObjectsWithServiceAccountFieldAndSavesItAsAnnotation(t *testing.T) { + t.Parallel() + req := require.New(t) + + cache := []v3.ProjectRoleTemplateBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "sa-prtb", + }, + ProjectName: "rke:p1", + RoleTemplateName: "project-member", + ServiceAccount: "p1:default", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "sa-prtb-processed", + Annotations: map[string]string{ + "management.cattle.io/serviceAccount": "p1:sa1", + }, + }, + ProjectName: "rke:p1", + RoleTemplateName: "project-member", + ServiceAccount: "p1:sa1", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "user-prtb", + }, + ProjectName: "rke:p1", + RoleTemplateName: "project-member", + UserName: "user1", + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "group-prtb", + }, + ProjectName: "rke:p1", + RoleTemplateName: "project-member", + GroupName: "group1", + }, + } + + ctrl := gomock.NewController(t) + client := fake.NewMockClientInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList](ctrl) + client.EXPECT().Update(gomock.Any()).DoAndReturn(func(obj *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + for i := range cache { + if cache[i].Name == obj.Name { + cache[i] = *obj + break + } + } + return obj, nil + }).Times(1) // Only one object must be updated. + + controller := prtbServiceAccountController{ + prtbClient: client, + } + for _, prtb := range cache { + upd, err := controller.sync("", &prtb) + req.NoError(err) + req.NotNil(upd) + } + + req.Len(cache, 4) + req.Equal(map[string]string{"management.cattle.io/serviceAccount": "p1:default"}, cache[0].Annotations) + req.Equal(map[string]string{"management.cattle.io/serviceAccount": "p1:sa1"}, cache[1].Annotations) + req.Nil(cache[2].Annotations) + req.Nil(cache[3].Annotations) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/register.go new file mode 100644 index 0000000..0a10e31 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/register.go @@ -0,0 +1,93 @@ +package auth + +import ( + "context" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/auth/globalroles" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + v1 "k8s.io/api/rbac/v1" + "k8s.io/client-go/tools/cache" +) + +func RegisterWranglerIndexers(config *wrangler.Context) { + config.RBAC.ClusterRoleBinding().Cache().AddIndexer(rbByRoleAndSubjectIndex, rbByClusterRoleAndSubject) + config.RBAC.ClusterRoleBinding().Cache().AddIndexer(membershipBindingOwnerIndex, func(obj *v1.ClusterRoleBinding) ([]string, error) { + return indexByMembershipBindingOwner(obj) + }) + + config.RBAC.RoleBinding().Cache().AddIndexer(rbByOwnerIndex, rbByOwner) + config.RBAC.RoleBinding().Cache().AddIndexer(rbByRoleAndSubjectIndex, rbByRoleAndSubject) + config.RBAC.RoleBinding().Cache().AddIndexer(membershipBindingOwnerIndex, func(obj *v1.RoleBinding) ([]string, error) { + return indexByMembershipBindingOwner(obj) + }) +} + +func RegisterIndexers(scaledContext *config.ScaledContext) error { + prtbInformer := scaledContext.Management.ProjectRoleTemplateBindings("").Controller().Informer() + prtbIndexers := map[string]cache.IndexFunc{ + prtbByRoleTemplateIndex: prtbByRoleTemplate, + prtbByUserRefKey: prtbByUserRefFunc, + } + if err := prtbInformer.AddIndexers(prtbIndexers); err != nil { + return err + } + + crtbInformer := scaledContext.Management.ClusterRoleTemplateBindings("").Controller().Informer() + crtbIndexers := map[string]cache.IndexFunc{ + crtbByRoleTemplateIndex: crtbByRoleTemplate, + crtbByUserRefKey: crtbByUserRefFunc, + } + if err := crtbInformer.AddIndexers(crtbIndexers); err != nil { + return err + } + + tokenInformer := scaledContext.Management.Tokens("").Controller().Informer() + if err := tokenInformer.AddIndexers(map[string]cache.IndexFunc{ + tokenByUserRefKey: tokenByUserRefFunc, + }); err != nil { + return err + } + + grbInformer := scaledContext.Management.GlobalRoleBindings("").Controller().Informer() + return grbInformer.AddIndexers(map[string]cache.IndexFunc{ + grbByUserRefKey: grbByUserRefFunc, + }) +} + +func RegisterEarly(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + prtb, crtb := newRTBLifecycles(management.WithAgent("mgmt-auth-crtb-prtb-controller")) + p, c := newPandCLifecycles(management) + u := newUserLifecycle(management, clusterManager) + n := newTokenController(management.WithAgent(tokenController)) + ac := newAuthConfigController(ctx, management, clusterManager.ScaledContext) + ua := newUserAttributeController(management.WithAgent(userAttributeController)) + s := newAuthSettingController(ctx, management) + rt := newRoleTemplateLifecycle(management, clusterManager) + grbLegacy := newLegacyGRBCleaner(management) + rtLegacy := newLegacyRTCleaner(management) + prtbServiceAccountFinder := newPRTBServiceAccountController(management) + + management.Management.ClusterRoleTemplateBindings("").AddLifecycle(ctx, ctrbMGMTController, crtb) + management.Management.ProjectRoleTemplateBindings("").AddLifecycle(ctx, ptrbMGMTController, prtb) + management.Management.Users("").AddLifecycle(ctx, userController, u) + management.Management.RoleTemplates("").AddLifecycle(ctx, roleTemplateLifecycleName, rt) + + management.Management.Clusters("").AddHandler(ctx, clusterCreateController, c.sync) + management.Management.Projects("").AddHandler(ctx, projectCreateController, p.sync) + management.Management.ProjectRoleTemplateBindings("").AddHandler(ctx, prtbServiceAccountControllerName, prtbServiceAccountFinder.sync) + management.Management.Tokens("").AddHandler(ctx, tokenController, n.sync) + management.Management.AuthConfigs("").AddHandler(ctx, authConfigControllerName, ac.sync) + management.Management.UserAttributes("").AddHandler(ctx, userAttributeController, ua.sync) + management.Management.Settings("").AddHandler(ctx, authSettingController, s.sync) + management.Management.GlobalRoleBindings("").AddHandler(ctx, "legacy-grb-cleaner", grbLegacy.sync) + management.Management.RoleTemplates("").AddHandler(ctx, "legacy-rt-cleaner", rtLegacy.sync) + globalroles.Register(ctx, management, clusterManager) +} + +func RegisterLate(ctx context.Context, management *config.ManagementContext) { + p, c := newPandCLifecycles(management) + management.Management.Projects("").AddLifecycle(ctx, projectRemoveController, p) + management.Management.Clusters("").AddLifecycle(ctx, clusterRemoveController, c) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle.go new file mode 100644 index 0000000..f364ebe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle.go @@ -0,0 +1,186 @@ +package auth + +import ( + "errors" + "fmt" + + "github.com/rancher/rancher/pkg/clustermanager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/apply" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + roleTemplateLifecycleName = "mgmt-auth-roletemplate-lifecycle" + prtbByRoleTemplateIndex = "management.cattle.io/prtb-by-role-template" + crtbByRoleTemplateIndex = "management.cattle.io/crtb-by-role-template" +) + +type roleTemplateLifecycle struct { + prtbIndexer cache.Indexer + prtbClient v3.ProjectRoleTemplateBindingInterface + crtbIndexer cache.Indexer + crtbClient v3.ClusterRoleTemplateBindingInterface + clusters v3.ClusterInterface + roles rbacv1.RoleInterface + roleLister rbacv1.RoleLister + clusterManager *clustermanager.Manager +} + +func newRoleTemplateLifecycle(management *config.ManagementContext, clusterManager *clustermanager.Manager) v3.RoleTemplateLifecycle { + prtbInformer := management.Management.ProjectRoleTemplateBindings("").Controller().Informer() + crtbInformer := management.Management.ClusterRoleTemplateBindings("").Controller().Informer() + + rtl := &roleTemplateLifecycle{ + prtbIndexer: prtbInformer.GetIndexer(), + prtbClient: management.Management.ProjectRoleTemplateBindings(""), + crtbIndexer: crtbInformer.GetIndexer(), + crtbClient: management.Management.ClusterRoleTemplateBindings(""), + clusters: management.Management.Clusters(""), + roles: management.RBAC.Roles(""), + roleLister: management.RBAC.Roles("").Controller().Lister(), + clusterManager: clusterManager, + } + return rtl +} + +func (rtl *roleTemplateLifecycle) Create(obj *v3.RoleTemplate) (runtime.Object, error) { + return rtl.enqueueRtbs(obj) +} + +func (rtl *roleTemplateLifecycle) Updated(obj *v3.RoleTemplate) (runtime.Object, error) { + return rtl.enqueueRtbs(obj) +} + +// enqueueRtbs enqueues crtbs and prtbs associated to the role template. +func (rtl *roleTemplateLifecycle) enqueueRtbs(obj *v3.RoleTemplate) (runtime.Object, error) { + if err := rtl.enqueuePrtbs(obj); err != nil { + return nil, err + } + + if err := rtl.enqueueCrtbs(obj); err != nil { + return nil, err + } + + return nil, nil +} + +func (rtl *roleTemplateLifecycle) Remove(obj *v3.RoleTemplate) (runtime.Object, error) { + clusters, err := rtl.clusters.List(metav1.ListOptions{}) + if err != nil { + return obj, err + } + + // Collect all the errors to delete as many user context cluster roles as possible + var allErrors []error + + for _, cluster := range clusters.Items { + userContext, err := rtl.clusterManager.UserContext(cluster.Name) + if err != nil { + // ClusterUnavailable error indicates the record can't talk to the downstream cluster + if !clustermanager.IsClusterUnavailableErr(err) { + allErrors = append(allErrors, err) + } + continue + } + + b, err := userContext.RBAC.ClusterRoles("").Controller().Lister().Get("", obj.Name) + if err != nil { + // User context clusterRole doesn't exist + if !apierrors.IsNotFound(err) { + allErrors = append(allErrors, err) + } + continue + } + + err = userContext.RBAC.ClusterRoles("").Delete(b.Name, &metav1.DeleteOptions{}) + if err != nil { + // User context clusterRole doesn't exist + if !apierrors.IsNotFound(err) { + allErrors = append(allErrors, err) + } + continue + } + } + + if len(allErrors) > 0 { + return obj, fmt.Errorf("errors deleting dowstream clusterRole: %v", allErrors) + } + + return obj, rtl.removeAuthV2Roles(obj) +} + +// removeAuthV2Roles finds any roles based off the owner annotation from the incoming roleTemplate. +// This is similar to an ownerReference but this is used across namespaces which ownerReferences does not support. +func (rtl *roleTemplateLifecycle) removeAuthV2Roles(roleTemplate *v3.RoleTemplate) error { + // Get the selector for the dependent roles + selector, err := apply.GetSelectorFromOwner("auth-prov-v2-roletemplate", roleTemplate) + if err != nil { + return err + } + + roles, err := rtl.roleLister.List("", selector) + if err != nil { + return err + } + + var returnErr error + for _, role := range roles { + err := rtl.roles.DeleteNamespaced(role.Namespace, role.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + // Combine all errors so we try our best to delete everything in the first run + returnErr = errors.Join(returnErr, err) + } + } + + return returnErr +} + +// enqueue any prtbs linked to this roleTemplate in order to re-sync them via reconcileBindings +func (rtl *roleTemplateLifecycle) enqueuePrtbs(updatedRT *v3.RoleTemplate) error { + prtbs, err := rtl.prtbIndexer.ByIndex(prtbByRoleTemplateIndex, updatedRT.Name) + if err != nil { + return err + } + for _, x := range prtbs { + if prtb, ok := x.(*v3.ProjectRoleTemplateBinding); ok { + rtl.prtbClient.Controller().Enqueue(prtb.Namespace, prtb.Name) + } + } + return nil +} + +// enqueue any crtbs linked to this roleTemplate in order to re-sync them via reconcileBindings +func (rtl *roleTemplateLifecycle) enqueueCrtbs(updatedRT *v3.RoleTemplate) error { + crtbs, err := rtl.crtbIndexer.ByIndex(crtbByRoleTemplateIndex, updatedRT.Name) + if err != nil { + return err + } + for _, x := range crtbs { + if crtb, ok := x.(*v3.ClusterRoleTemplateBinding); ok { + rtl.crtbClient.Controller().Enqueue(crtb.Namespace, crtb.Name) + } + } + return nil +} + +func prtbByRoleTemplate(obj interface{}) ([]string, error) { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{prtb.RoleTemplateName}, nil +} + +func crtbByRoleTemplate(obj interface{}) ([]string, error) { + crtb, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{crtb.RoleTemplateName}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle_test.go new file mode 100644 index 0000000..ff6328f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/role_template_lifecycle_test.go @@ -0,0 +1,137 @@ +package auth + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +const testNamespace = "test-cluster" +const testRoleTemplateName = "fake-role-template" + +func TestEnqueuePrtbsOnRoleTemplateUpdate(t *testing.T) { + existingPrtbs := []*v3.ProjectRoleTemplateBinding{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "prtb-1", + Namespace: testNamespace, + }, + RoleTemplateName: testRoleTemplateName, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "prtb-2", + Namespace: testNamespace, + }, + RoleTemplateName: "this-is-not-the-rt-you-are-looking-for", + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "prtb-3", + Namespace: testNamespace, + }, + RoleTemplateName: testRoleTemplateName, + }, + } + + // Mock prtb controller to catch enqueue calls + mockedProjectRoleTemplateBindingController := fakes.ProjectRoleTemplateBindingControllerMock{ + EnqueueFunc: func(namespace string, name string) {}, + } + + // Setup a mock indexer that uses our custom index and method, then add test objects + indexers := map[string]cache.IndexFunc{ + prtbByRoleTemplateIndex: prtbByRoleTemplate, + } + mockIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + mockIndexer.AddIndexers(indexers) + for _, obj := range existingPrtbs { + mockIndexer.Add(obj) + } + + rtl := roleTemplateLifecycle{ + prtbIndexer: mockIndexer, + prtbClient: &fakes.ProjectRoleTemplateBindingInterfaceMock{ + ControllerFunc: func() v3.ProjectRoleTemplateBindingController { + return &mockedProjectRoleTemplateBindingController + }, + }, + } + + updatedRT := v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: testRoleTemplateName, + Namespace: testNamespace, + }, + } + // Now pass in a roleTemplate with name that matches a subset of test objects + err := rtl.enqueuePrtbs(&updatedRT) + assert.Nil(t, err) + assert.Equal(t, 2, len(mockedProjectRoleTemplateBindingController.EnqueueCalls())) +} + +func TestEnqueueCrtbsOnRoleTemplateUpdate(t *testing.T) { + existingCrtbs := []*v3.ClusterRoleTemplateBinding{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "crtb-1", + Namespace: testNamespace, + }, + RoleTemplateName: testRoleTemplateName, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "crtb-2", + Namespace: testNamespace, + }, + RoleTemplateName: "this-is-not-the-rt-you-are-looking-for", + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "crtb-3", + Namespace: testNamespace, + }, + RoleTemplateName: testRoleTemplateName, + }, + } + + // Mock crtb controller to catch enqueue calls + mockCrtbController := fakes.ClusterRoleTemplateBindingControllerMock{ + EnqueueFunc: func(namespace string, name string) {}, + } + + // Setup a mock indexer that uses our custom index and method, then add test objects + indexers := map[string]cache.IndexFunc{ + crtbByRoleTemplateIndex: crtbByRoleTemplate, + } + mockIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + mockIndexer.AddIndexers(indexers) + for _, obj := range existingCrtbs { + mockIndexer.Add(obj) + } + + rtl := roleTemplateLifecycle{ + crtbIndexer: mockIndexer, + crtbClient: &fakes.ClusterRoleTemplateBindingInterfaceMock{ + ControllerFunc: func() v3.ClusterRoleTemplateBindingController { + return &mockCrtbController + }, + }, + } + + updatedRT := v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: testRoleTemplateName, + Namespace: testNamespace, + }, + } + // Now pass in a roleTemplate with name that matches a subset of test objects + err := rtl.enqueueCrtbs(&updatedRT) + assert.Nil(t, err) + assert.Equal(t, 2, len(mockCrtbController.EnqueueCalls())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting.go new file mode 100644 index 0000000..79182cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting.go @@ -0,0 +1,62 @@ +package auth + +import ( + "context" + "fmt" + + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/providers/azure" + "github.com/rancher/rancher/pkg/auth/userretention" + "github.com/rancher/rancher/pkg/crondaemon" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +const authSettingController = "mgmt-auth-settings-controller" + +type SettingController struct { + ensureUserRetentionLabels func() error + scheduleUserRetention func(string) error +} + +func newAuthSettingController(ctx context.Context, mgmt *config.ManagementContext) *SettingController { + userRetention := userretention.New(mgmt.Wrangler) + userRetentionDaemon := crondaemon.New(ctx, "userretention", userRetention.Run) + userRetentionLabeler := userretention.NewUserLabeler(ctx, mgmt.Wrangler) + + return &SettingController{ + ensureUserRetentionLabels: userRetentionLabeler.EnsureForAll, + scheduleUserRetention: userRetentionDaemon.Schedule, + } +} + +// sync is called periodically and on real updates +func (c *SettingController) sync(key string, obj *v3.Setting) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + switch obj.Name { + case settings.AuthUserInfoResyncCron.Name: + providerrefresh.UpdateRefreshCronTime(obj.Value) + case settings.AuthUserInfoMaxAgeSeconds.Name: + providerrefresh.UpdateRefreshMaxAge(obj.Value) + case settings.AzureGroupCacheSize.Name: + azure.UpdateGroupCacheSize(obj.Value) + case settings.UserRetentionCron.Name: + if err := c.scheduleUserRetention(obj.Value); err != nil { + logrus.Errorf("Failed to schedule user retention daemon: %v", err) + } + case settings.DisableInactiveUserAfter.Name, + settings.DeleteInactiveUserAfter.Name, + settings.UserLastLoginDefault.Name: + if err := c.ensureUserRetentionLabels(); err != nil { + return nil, fmt.Errorf("error updating retention labels for users: %w", err) + } + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting_test.go new file mode 100644 index 0000000..1d18918 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/setting_test.go @@ -0,0 +1,75 @@ +package auth + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestSettingsSyncWithEmptyAzureGroupCacheSize(t *testing.T) { + name := settings.AzureGroupCacheSize.Name + controller := SettingController{} + + _, err := controller.sync(name, &v3.Setting{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Value: "", + }) + if err != nil { + t.Fatal(err) + } +} + +func TestSettingsSyncEnsureUserRetentionLabels(t *testing.T) { + for _, name := range []string{ + settings.DisableInactiveUserAfter.Name, + settings.DeleteInactiveUserAfter.Name, + settings.UserLastLoginDefault.Name, + } { + t.Run(name, func(t *testing.T) { + var ensureLabelsCalledTimes int + controller := &SettingController{ + ensureUserRetentionLabels: func() error { + ensureLabelsCalledTimes++ + return nil + }, + } + + _, err := controller.sync(name, &v3.Setting{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Value: "1h", + }) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, ensureLabelsCalledTimes; want != got { + t.Errorf("Expected ensureLabelsCalledTimes: %d got %d", want, got) + } + }) + } +} + +func TestSettingsSyncScheduleUserRetention(t *testing.T) { + var scheduleRetentionCalledTimes int + controller := &SettingController{ + scheduleUserRetention: func(_ string) error { + scheduleRetentionCalledTimes++ + return nil + }, + } + + name := settings.UserRetentionCron.Name + _, err := controller.sync(name, &v3.Setting{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Value: "* * * * *", + }) + if err != nil { + t.Fatal(err) + } + + if want, got := 1, scheduleRetentionCalledTimes; want != got { + t.Fatalf("Expected scheduleRetentionCalledTimes: %d got %d", want, got) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token.go new file mode 100644 index 0000000..fe2504e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token.go @@ -0,0 +1,126 @@ +package auth + +import ( + tokenUtil "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + tokenController = "mgmt-auth-tokens-controller" +) + +type TokenController struct { + tokens v3.TokenInterface + userAttributes v3.UserAttributeInterface + userAttributesLister v3.UserAttributeLister +} + +func newTokenController(mgmt *config.ManagementContext) *TokenController { + n := &TokenController{ + tokens: mgmt.Management.Tokens(""), + userAttributes: mgmt.Management.UserAttributes(""), + userAttributesLister: mgmt.Management.UserAttributes("").Controller().Lister(), + } + return n +} + +// sync is called periodically and on real updates +func (t *TokenController) sync(key string, obj *v3.Token) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + // remove legacy finalizers + if obj.DeletionTimestamp != nil { + finalizers := obj.GetFinalizers() + newObj := obj.DeepCopy() + for i, finalizer := range finalizers { + if finalizer == "controller.cattle.io/cat-token-controller" { + finalizers = append(finalizers[:i], finalizers[i+1:]...) + newObj = obj.DeepCopy() + newObj.SetFinalizers(finalizers) + var err error + newObj, err = t.tokens.Update(newObj) + if err != nil { + return obj, err + } + obj = newObj + break + } + } + } + + if obj.TTLMillis != 0 && obj.ExpiresAt == "" { + //compute and save expiresAt + newObj := obj.DeepCopy() + var err error + tokenUtil.SetTokenExpiresAt(newObj) + if newObj, err = t.tokens.Update(newObj); err != nil { + return obj, err + } + obj = newObj + } + + // trigger corresponding UserAttribute resource to refresh if token potentially + // provides new information that is missing from the UserAttribute resource + refreshUserAttributes, err := t.userAttributesNeedsRefresh(obj.UserID) + if err != nil { + return obj, err + } + + if refreshUserAttributes { + if err = t.triggerUserAttributesRefresh(obj.UserID); err != nil { + return obj, err + } + } + + // DO NOT remove until tokenHashing is always + // expected. Anything below this will only execute + // if tokenHashing is enabled + if !features.TokenHashing.Enabled() { + return obj, nil + } + + if obj.Annotations[tokenUtil.TokenHashed] != "true" { + newObj := obj.DeepCopy() + err := tokenUtil.ConvertTokenKeyToHash(newObj) + if err != nil { + return obj, err + } + if _, err := t.tokens.Update(newObj); err != nil { + return obj, err + } + obj = newObj + } + + return obj, nil +} + +func (t *TokenController) userAttributesNeedsRefresh(user string) (bool, error) { + if user == "" { + return false, nil + } + + userAttribute, err := t.userAttributesLister.Get("", user) + if err != nil { + if errors.IsNotFound(err) { + return false, nil + } + return false, err + } + return userAttribute.ExtraByProvider == nil, nil +} + +func (t *TokenController) triggerUserAttributesRefresh(user string) error { + userAttribute, err := t.userAttributesLister.Get("", user) + if err != nil { + return err + } + + userAttribute.NeedsRefresh = true + _, err = t.userAttributes.Update(userAttribute) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token_test.go new file mode 100644 index 0000000..c974520 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/token_test.go @@ -0,0 +1,376 @@ +package auth + +import ( + "fmt" + "testing" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + tokens2 "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/auth/tokens/hashers" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type tokenTestCase struct { + inputToken *v3.Token + expectedOutputToken *v3.Token + inputUserAttribute *v3.UserAttribute + expectedOutputUserAttribute *v3.UserAttribute + enableHashing bool + description string +} + +func TestSync(t *testing.T) { + tokens := make(map[string]*v3.Token) + userAttributes := make(map[string]*v3.UserAttribute) + + testTokenController := TokenController{ + tokens: &fakes.TokenInterfaceMock{ + UpdateFunc: func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + userAttributes: &fakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil + }, + }, + userAttributesLister: &fakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + } + testCases := populateTestCases(tokens, userAttributes) + for _, testcase := range testCases { + testErr := fmt.Sprintf("test case failed: %s", testcase.description) + if testcase.enableHashing { + features.TokenHashing.Set(true) + } + returnToken, _ := testTokenController.sync(testcase.inputToken.Name, testcase.inputToken) + storedToken, _ := testTokenController.tokens.Get(testcase.inputToken.Name, metav1.GetOptions{}) + assert.Equalf(t, returnToken, storedToken, fmt.Sprintf("%s", testcase.inputToken.Name), testErr) + features.TokenHashing.Set(false) + if testcase.enableHashing { + tokenVal := returnToken.(*v3.Token).Token + assert.NotEqualf(t, tokenVal, testcase.inputToken.Token, testErr) + hasher, err := hashers.GetHasherForHash(tokenVal) + assert.Nil(t, err) + assert.Nil(t, hasher.VerifyHash(tokenVal, testcase.inputToken.Token)) + testcase.expectedOutputToken.Token = "" + returnToken.(*v3.Token).Token = "" + } + assert.Equalf(t, testcase.expectedOutputToken, returnToken, fmt.Sprintf("%s", testcase.inputToken.Name), testErr) + if testcase.inputUserAttribute == nil { + continue + } + returnUserAttribute, _ := testTokenController.userAttributesLister.Get("", testcase.inputUserAttribute.Name) + assert.Equalf(t, testcase.expectedOutputUserAttribute, returnUserAttribute, fmt.Sprintf("%s", testcase.inputToken.Name), testErr) + } + + // test error from token update + testTokenErrorUpdateController := TokenController{ + tokens: &fakes.TokenInterfaceMock{ + UpdateFunc: func(token *v3.Token) (*v3.Token, error) { + return nil, errors.NewServiceUnavailable("test reason") + }, + GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + userAttributes: &fakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil + }, + }, + userAttributesLister: &fakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + } + genericTestToken := &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testtoken", + }, + Token: "1234", + // TTLMillis not being 0 while ExpiresAt is "" should trigger an update + TTLMillis: 300, + } + _, err := testTokenErrorUpdateController.sync(genericTestToken.Name, genericTestToken) + assert.NotNilf(t, err, "handler should return err when token client's update function returns error") + + // test error from userattribute update + testUserAttributeErrorUpdateController := TokenController{ + tokens: &fakes.TokenInterfaceMock{ + UpdateFunc: func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + userAttributes: &fakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return nil, errors.NewServiceUnavailable("test reason") + }, + }, + userAttributesLister: &fakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + } + genericTestToken = &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testtoken", + }, + // UserID not being "" should trigger userattribute refresh check + UserID: "abcd", + } + userAttributes = map[string]*v3.UserAttribute{ + // ExtraByProvider being nil should trigger a userattribute update + "abcd": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + } + _, err = testUserAttributeErrorUpdateController.sync(genericTestToken.Name, genericTestToken) + assert.NotNilf(t, err, "handler should return err when userattribute client's update function returns error") + + // test non-notfound error from userattribute lister get + testUserAttributeErrorGetController := TokenController{ + tokens: &fakes.TokenInterfaceMock{ + UpdateFunc: func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + userAttributes: &fakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil + }, + }, + userAttributesLister: &fakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { + return nil, errors.NewServiceUnavailable("test reason") + }, + }, + } + genericTestToken = &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testtoken", + }, + // UserID not being "" should trigger userattribute refresh check + UserID: "abcd", + } + _, err = testUserAttributeErrorGetController.sync(genericTestToken.Name, genericTestToken) + assert.NotNilf(t, err, "handler should return err when userattribute lister's get function returns non-notfound error") + + // test notfound error from userattribute lister get + testUserAttributeErrorGetController = TokenController{ + tokens: &fakes.TokenInterfaceMock{ + UpdateFunc: func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + userAttributes: &fakes.UserAttributeInterfaceMock{ + UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil + }, + }, + userAttributesLister: &fakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { + return nil, errors.NewNotFound(schema.GroupResource{}, name) + }, + }, + } + genericTestToken = &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testtoken", + }, + // UserID not being "" should trigger userattribute refresh check + UserID: "abcd", + } + _, err = testUserAttributeErrorGetController.sync(genericTestToken.Name, genericTestToken) + assert.Nil(t, err, "handler should not return err when userattribute lister's get function returns notfound error") +} + +func populateTestCases(tokens map[string]*v3.Token, userAttributes map[string]*v3.UserAttribute) []tokenTestCase { + timeNow := metav1.NewTime(time.Now()) + hashedToken, _ := hashers.GetHasher().CreateHash("1234") + testCases := []tokenTestCase{ + { + inputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "2", "3"}, + }, + }, + expectedOutputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "2", "3"}, + }, + }, + description: "Base case that confirms no changes are made to a token that does not have the" + + " \"controller.cattle.io/cat-token-controller\" finalizer.", + }, + { + inputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "controller.cattle.io/cat-token-controller", "3"}, + }, + }, + expectedOutputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "controller.cattle.io/cat-token-controller", "3"}, + }, + }, + description: "Tests that the \"controller.cattle.io/cat-token-controller\" finalizer is not removed if the token does" + + "not have a deltion timestamp.", + }, + { + inputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "controller.cattle.io/cat-token-controller", "3"}, + DeletionTimestamp: &timeNow, + }, + }, + expectedOutputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"1", "3"}, + DeletionTimestamp: &timeNow, + }, + }, + description: "Tests the the \"controller.cattle.io/cat-token-controller\" is removed if token possesses" + + " deletion timestamp.", + }, + { + inputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: timeNow, + }, + TTLMillis: 300, + }, + expectedOutputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: timeNow, + }, + TTLMillis: 300, + ExpiresAt: timeNow.Add(300 * time.Millisecond).UTC().Format(time.RFC3339), + }, + }, + { + inputToken: &v3.Token{UserID: "testuser"}, + expectedOutputToken: &v3.Token{UserID: "testuser"}, + inputUserAttribute: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + expectedOutputUserAttribute: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + NeedsRefresh: true, + }, + description: "Tests that UserAttribute is trigger for a refresh if it is missing info that can" + + "potentially be provided by the token.", + }, + { + inputToken: &v3.Token{UserID: "testuser2"}, + expectedOutputToken: &v3.Token{UserID: "testuser2"}, + inputUserAttribute: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser2", + }, + ExtraByProvider: map[string]map[string][]string{"something": {"something": []string{"something"}}}, + }, + expectedOutputUserAttribute: &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser2", + }, + ExtraByProvider: map[string]map[string][]string{"something": {"something": []string{"something"}}}, + }, + description: "Tests that UserAttribute is not triggered for a refresh if it is not missing info that can" + + "potentially be provided by the token.", + }, + { + inputToken: &v3.Token{ + Token: "1234", + }, + expectedOutputToken: &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{tokens2.TokenHashed: "true"}, + }, + Token: hashedToken, + }, + enableHashing: true, + description: "", + }, + } + for index, testCase := range testCases { + id := fmt.Sprintf("test%d", index) + testCase.inputToken.Name = id + testCase.expectedOutputToken.Name = id + tokens[id] = testCase.inputToken.DeepCopy() + if testCase.inputUserAttribute == nil { + continue + } + userAttributes[testCase.inputUserAttribute.Name] = testCase.inputUserAttribute.DeepCopy() + } + return testCases +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user.go new file mode 100644 index 0000000..136391e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user.go @@ -0,0 +1,457 @@ +package auth + +import ( + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + + "github.com/rancher/rancher/pkg/clustermanager" + wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + v12 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +type userLifecycle struct { + prtb v3.ProjectRoleTemplateBindingInterface + crtb v3.ClusterRoleTemplateBindingInterface + grb wranglerv3.GlobalRoleBindingController + users v3.UserInterface + tokens v3.TokenInterface + namespaces v1.NamespaceInterface + namespaceLister v1.NamespaceLister + secrets v1.SecretInterface + secretsLister v1.SecretLister + prtbLister v3.ProjectRoleTemplateBindingLister + crtbLister v3.ClusterRoleTemplateBindingLister + grbLister v3.GlobalRoleBindingLister + prtbIndexer cache.Indexer + crtbIndexer cache.Indexer + grbIndexer cache.Indexer + tokenIndexer cache.Indexer + userManager user.Manager + clusterLister v3.ClusterLister + clusterManager *clustermanager.Manager +} + +const ( + crtbByUserRefKey = "auth.management.cattle.io/crtb-by-user-ref" + prtbByUserRefKey = "auth.management.cattle.io/prtb-by-user-ref" + grbByUserRefKey = "auth.management.cattle.io/grb-by-user-ref" + tokenByUserRefKey = "auth.management.cattle.io/token-by-user-ref" + userController = "mgmt-auth-users-controller" +) + +func newUserLifecycle(management *config.ManagementContext, clusterManager *clustermanager.Manager) *userLifecycle { + lfc := &userLifecycle{ + prtb: management.Management.ProjectRoleTemplateBindings(""), + crtb: management.Management.ClusterRoleTemplateBindings(""), + grb: management.Wrangler.Mgmt.GlobalRoleBinding(), + users: management.Management.Users(""), + tokens: management.Management.Tokens(""), + namespaces: management.Core.Namespaces(""), + secrets: management.Core.Secrets(""), + secretsLister: management.Core.Secrets("").Controller().Lister(), + namespaceLister: management.Core.Namespaces("").Controller().Lister(), + userManager: management.UserManager, + clusterLister: management.Management.Clusters("").Controller().Lister(), + clusterManager: clusterManager, + } + + prtbInformer := management.Management.ProjectRoleTemplateBindings("").Controller().Informer() + lfc.prtbIndexer = prtbInformer.GetIndexer() + + crtbInformer := management.Management.ClusterRoleTemplateBindings("").Controller().Informer() + lfc.crtbIndexer = crtbInformer.GetIndexer() + + grbInformer := management.Management.GlobalRoleBindings("").Controller().Informer() + lfc.grbIndexer = grbInformer.GetIndexer() + + tokenInformer := management.Management.Tokens("").Controller().Informer() + lfc.tokenIndexer = tokenInformer.GetIndexer() + + return lfc +} + +func grbByUserRefFunc(obj interface{}) ([]string, error) { + globalRoleBinding, ok := obj.(*v3.GlobalRoleBinding) + if !ok { + return []string{}, nil + } + + return []string{globalRoleBinding.UserName}, nil +} + +func prtbByUserRefFunc(obj interface{}) ([]string, error) { + projectRoleBinding, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok || projectRoleBinding.UserName == "" { + return []string{}, nil + } + + return []string{projectRoleBinding.UserName}, nil +} + +func crtbByUserRefFunc(obj interface{}) ([]string, error) { + clusterRoleBinding, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok || clusterRoleBinding.UserName == "" { + return []string{}, nil + } + + return []string{clusterRoleBinding.UserName}, nil +} + +func tokenByUserRefFunc(obj interface{}) ([]string, error) { + token, ok := obj.(*v3.Token) + if !ok { + return []string{}, nil + } + + return []string{token.UserID}, nil +} + +// hasLocalPrincipalID returns true in case the user +// has at least one PrincipalID that starts with "local://". +// Returns false otherwise. +func hasLocalPrincipalID(user *v3.User) bool { + var match = false + for _, id := range user.PrincipalIDs { + if strings.HasPrefix(id, "local://") { + match = true + break + } + } + return match +} + +// Create creates a new user role binding and sets the Status.Conditions.Type = "InitialRolesPopulated", +// and then returns the object. Otherwise returns an error. +func (l *userLifecycle) Create(user *v3.User) (runtime.Object, error) { + if !hasLocalPrincipalID(user) { + user.PrincipalIDs = append(user.PrincipalIDs, "local://"+user.Name) + } + + // creatorIDAnn indicates it was created through the API, create the new + // user bindings and add the annotation UserConditionInitialRolesPopulated + if user.ObjectMeta.Annotations[creatorIDAnn] != "" { + u, err := v32.UserConditionInitialRolesPopulated.DoUntilTrue(user, func() (runtime.Object, error) { + err := l.userManager.CreateNewUserClusterRoleBinding(user.Name, user.UID) + if err != nil { + return nil, err + } + return user, nil + }) + if err != nil { + return nil, err + } + user = u.(*v3.User) + } + + return user, nil +} + +func (l *userLifecycle) Updated(user *v3.User) (runtime.Object, error) { + err := l.userManager.CreateNewUserClusterRoleBinding(user.Name, user.UID) + if err != nil { + return nil, err + } + return user, nil +} + +func (l *userLifecycle) Remove(user *v3.User) (runtime.Object, error) { + clusterRoles, err := l.getCRTBByUserName(user.Name) + if err != nil { + return nil, err + } + + err = l.deleteAllCRTB(clusterRoles) + if err != nil { + return nil, err + } + + projectRoles, err := l.getPRTBByUserName(user.Name) + if err != nil { + return nil, err + } + + err = l.deleteAllPRTB(projectRoles) + if err != nil { + return nil, err + } + + globalRoles, err := l.getGRBByUserName(user.Name) + if err != nil { + return nil, err + } + + err = l.deleteAllGRB(globalRoles) + if err != nil { + return nil, err + } + + tokens, err := l.getTokensByUserName(user.Name) + if err != nil { + return nil, err + } + + err = l.deleteClusterUserAttributes(user.Name, tokens) + if err != nil { + return nil, err + } + + err = l.deleteAllTokens(tokens) + if err != nil { + return nil, err + } + + err = l.deleteUserNamespace(user.Name) + if err != nil { + return nil, err + } + + err = l.deleteUserSecret(user.Name) + if err != nil { + return nil, err + } + + user, err = l.removeLegacyFinalizers(user) + if err != nil { + return nil, err + } + + return user, nil +} + +func (l *userLifecycle) getCRTBByUserName(username string) ([]*v3.ClusterRoleTemplateBinding, error) { + obj, err := l.crtbIndexer.ByIndex(crtbByUserRefKey, username) + if err != nil { + return nil, fmt.Errorf("error getting cluster roles: %v", err) + } + + var crtbs []*v3.ClusterRoleTemplateBinding + for _, o := range obj { + crtb, ok := o.(*v3.ClusterRoleTemplateBinding) + if !ok { + return nil, fmt.Errorf("error converting obj to cluster role template binding: %v", o) + } + + crtbs = append(crtbs, crtb) + } + + return crtbs, nil +} + +func (l *userLifecycle) getPRTBByUserName(username string) ([]*v3.ProjectRoleTemplateBinding, error) { + objs, err := l.prtbIndexer.ByIndex(prtbByUserRefKey, username) + if err != nil { + return nil, fmt.Errorf("error getting indexed project roles: %v", err) + } + + var prtbs []*v3.ProjectRoleTemplateBinding + for _, obj := range objs { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return nil, fmt.Errorf("could not convert obj to v3.ProjectRoleTemplateBinding") + } + + prtbs = append(prtbs, prtb) + } + + return prtbs, nil +} + +func (l *userLifecycle) getGRBByUserName(username string) ([]*v3.GlobalRoleBinding, error) { + objs, err := l.grbIndexer.ByIndex(grbByUserRefKey, username) + if err != nil { + return nil, fmt.Errorf("error getting indexed global roles: %v", err) + } + + var grbs []*v3.GlobalRoleBinding + for _, obj := range objs { + grb, ok := obj.(*v3.GlobalRoleBinding) + if !ok { + return nil, fmt.Errorf("could not convert obj to v3.GlobalRoleBinding") + } + + grbs = append(grbs, grb) + } + + return grbs, nil +} + +func (l *userLifecycle) getTokensByUserName(username string) ([]*v3.Token, error) { + objs, err := l.tokenIndexer.ByIndex(tokenByUserRefKey, username) + if err != nil { + return nil, fmt.Errorf("error getting indexed tokens: %v", err) + } + + var tokens []*v3.Token + for _, obj := range objs { + token, ok := obj.(*v3.Token) + if !ok { + return nil, fmt.Errorf("could not convert to *v3.Token: %v", obj) + } + + tokens = append(tokens, token) + } + + return tokens, nil +} + +func (l *userLifecycle) deleteAllCRTB(crtbs []*v3.ClusterRoleTemplateBinding) error { + for _, crtb := range crtbs { + var err error + if crtb.Namespace == "" { + logrus.Infof("[%v] Deleting clusterRoleTemplateBinding %v for user %v", userController, crtb.Name, crtb.UserName) + err = l.crtb.Delete(crtb.Name, &metav1.DeleteOptions{}) + } else { + logrus.Infof("[%v] Deleting clusterRoleTemplateBinding %v for user %v", userController, crtb.Name, crtb.UserName) + err = l.crtb.DeleteNamespaced(crtb.Namespace, crtb.Name, &metav1.DeleteOptions{}) + } + if err != nil { + return fmt.Errorf("error deleting cluster role: %v", err) + } + } + + return nil +} + +func (l *userLifecycle) deleteAllPRTB(prtbs []*v3.ProjectRoleTemplateBinding) error { + for _, prtb := range prtbs { + var err error + if prtb.Namespace == "" { + logrus.Infof("[%v] Deleting projectRoleTemplateBinding %v for user %v", userController, prtb.Name, prtb.UserName) + err = l.prtb.Delete(prtb.Name, &metav1.DeleteOptions{}) + } else { + logrus.Infof("[%v] Deleting projectRoleTemplateBinding %v for user %v", userController, prtb.Name, prtb.UserName) + err = l.prtb.DeleteNamespaced(prtb.Namespace, prtb.Name, &metav1.DeleteOptions{}) + } + if err != nil { + return fmt.Errorf("error deleting projet role: %v", err) + } + } + + return nil +} + +func (l *userLifecycle) deleteAllGRB(grbs []*v3.GlobalRoleBinding) error { + // some GRBs can refer to GRs which inherit cluster Roles. Rancher's service account lacks the permission + // to delete these GRBs directly, so it needs to bypass the webhook + grbClient, err := l.grb.WithImpersonation(controllers.WebhookImpersonation()) + if err != nil { + return fmt.Errorf("error when impersonating webhook to delete globalRoleBindings: %w", err) + } + for _, grb := range grbs { + logrus.Infof("[%v] Deleting globalRoleBinding %v for user %v", userController, grb.Name, grb.UserName) + err = grbClient.Delete(grb.Name, &metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting globalRoleBinding %v: %v", grb.Name, err) + + } + } + + return nil +} + +func (l *userLifecycle) deleteClusterUserAttributes(username string, tokens []*v3.Token) error { + if len(tokens) == 0 { + return nil + } + // find the set of clusters associated with a list of tokens + set := make(map[string]*v3.Cluster) + for _, token := range tokens { + cluster, err := l.clusterLister.Get("", token.ClusterName) + if err != nil { + if errors.IsNotFound(err) { + continue + } + return err + } + set[token.ClusterName] = cluster + } + + for _, cluster := range set { + userCtx, err := l.clusterManager.UserContextNoControllers(cluster.Name) + if err != nil { + return err + } + err = userCtx.Cluster.ClusterUserAttributes("cattle-system").Delete(username, &metav1.DeleteOptions{}) + if err != nil && !errors.IsNotFound(err) { + return err + } + } + return nil +} + +func (l *userLifecycle) deleteAllTokens(tokens []*v3.Token) error { + for _, token := range tokens { + logrus.Infof("[%v] Deleting token %v for user %v", userController, token.Name, token.UserID) + err := l.tokens.DeleteNamespaced(token.Namespace, token.Name, &metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting token: %v", err) + } + } + + return nil +} + +func (l *userLifecycle) deleteUserNamespace(username string) error { + namespace, err := l.namespaceLister.Get("", username) + if err != nil { + if errors.IsNotFound(err) { + return nil // nothing to delete + } + + return fmt.Errorf("error getting user namespace: %v", err) + } + + if namespace.Status.Phase == v12.NamespaceTerminating { + return nil // nothing to do namespace is already deleting + } + + logrus.Infof("[%v] Deleting namespace backing user %v", userController, username) + err = l.namespaces.Delete(username, &metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting user namespace: %v", err) + } + + return nil +} + +func (l *userLifecycle) deleteUserSecret(username string) error { + _, err := l.secretsLister.Get("cattle-system", username+"-secret") + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return fmt.Errorf("error getting user secret: %v", err) + } + + logrus.Infof("[%v] Deleting secret backing user %v", userController, username) + return l.secrets.DeleteNamespaced("cattle-system", username+"-secret", &metav1.DeleteOptions{}) +} + +func (l *userLifecycle) removeLegacyFinalizers(user *v3.User) (*v3.User, error) { + finalizers := user.GetFinalizers() + for i, finalizer := range finalizers { + if finalizer == "controller.cattle.io/cat-user-controller" { + finalizers = append(finalizers[:i], finalizers[i+1:]...) + user = user.DeepCopy() + user.SetFinalizers(finalizers) + updatedUser, err := l.users.Update(user) + if err != nil { + return nil, err + } + return updatedUser, err + } + } + return user, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler.go new file mode 100644 index 0000000..0de902b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler.go @@ -0,0 +1,112 @@ +// Package auth contains handlers and helpful functions for managing authentication. This includes token cleanup and +// managing Rancher's RBAC kubernetes resources: ClusterRoleTemplateBindings and ProjectRoleTemplateBindings. +package auth + +import ( + "context" + "fmt" + + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/userretention" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + userAttributeController = "mgmt-auth-userattributes-controller" +) + +type UserAttributeController struct { + userAttributes mgmtcontrollers.UserAttributeClient + providerRefresh func(attribs *v3.UserAttribute) (*v3.UserAttribute, error) + ensureUserRetentionLabels func(attribs *v3.UserAttribute) error +} + +func newUserAttributeController(mgmt *config.ManagementContext) *UserAttributeController { + userretentionLabeler := userretention.NewUserLabeler(context.Background(), mgmt.Wrangler) + + return &UserAttributeController{ + userAttributes: mgmt.Wrangler.Mgmt.UserAttribute(), + providerRefresh: providerrefresh.RefreshAttributes, + ensureUserRetentionLabels: userretentionLabeler.EnsureForAttributes, + } +} + +// sync is called periodically and on real updates +func (c *UserAttributeController) sync(key string, attribs *v3.UserAttribute) (runtime.Object, error) { + if attribs == nil || attribs.DeletionTimestamp != nil { + return nil, nil + } + + // Preserve the name as attribs can be set to nil by the following calls. + name := attribs.Name + + err := c.ensureUserRetentionLabels(attribs) + if err != nil { + return nil, fmt.Errorf("error setting user retention labels for user %s: %w", name, err) + } + + if !attribs.NeedsRefresh { + return attribs, nil + } + + // We want to avoid mutiple provider refresh calls as it's a very expensive operation + // that caused issues in the past. To avoid this we: + // 1. Re-fetch the object and recheck NeedsRefresh before proceeding with refresh + // as it's possible that it's already false by the time RefreshAttributes finishes + // e.g. if the user logins while refresh is running. + // 2. Explicitly handle the update conflict and carry over the RefreshAttributes changes + // to a fresh state of the object and attempt to update it one more time. + // This is a temporary measure to make sure capturing last login time doesn't makes things worse. + // We want to move away from this pattern of triggering a refresh by using a field (NeedsRefresh) + // on the resource object itself, which is inherently racey. + // Instead we plan to have a dedicated CRD for triggering refreshes. + attribs, err = c.userAttributes.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("error getting user attribute %s before provider refresh: %w", name, err) + } + if !attribs.NeedsRefresh { + return attribs, nil + } + + attribs, err = c.providerRefresh(attribs) + if err != nil { + return nil, fmt.Errorf("error refreshing user attribute %s: %w", name, err) + } + + updated, err := c.userAttributes.Update(attribs) + if err == nil { + return updated, nil + } + + // We deliberately wrap and shadow the original error so that we can return it later on. + // IsConflict is still able to figure out if it's a conflict. + err = fmt.Errorf("error updating user attribute %s after provider refresh: %w", name, err) + if !apierrors.IsConflict(err) { + return nil, err + } + + newAttribs, nerr := c.userAttributes.Get(name, metav1.GetOptions{}) + if nerr != nil { + logrus.Errorf("error getting new version of user attribute %s: %v", name, nerr) + return nil, err // Deliberately return the original error. + } + + newAttribs.NeedsRefresh = attribs.NeedsRefresh + newAttribs.LastRefresh = attribs.LastRefresh + newAttribs.GroupPrincipals = attribs.GroupPrincipals + newAttribs.ExtraByProvider = attribs.ExtraByProvider + + updated, nerr = c.userAttributes.Update(newAttribs) + if nerr != nil { + logrus.Errorf("error updating new version of user attribute %s: %v", name, nerr) + return nil, err // Deliberately return the original error. + } + + return updated, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler_test.go new file mode 100644 index 0000000..1ad8141 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_attribute_handler_test.go @@ -0,0 +1,331 @@ +package auth + +import ( + "fmt" + "testing" + "time" + + "github.com/golang/mock/gomock" + management "github.com/rancher/rancher/pkg/apis/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestSyncEnsureUserRetentionLabels(t *testing.T) { + userID := "u-abcdef" + ctrl := gomock.NewController(t) + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return userAttribute.DeepCopy(), nil + }) + + var ensureLabelsCalledTimes int + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { + ensureLabelsCalledTimes++ + return nil + }, + } + + newAttribs := func(lastLogin metav1.Time) *v3.UserAttribute { + return &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + LastLogin: &lastLogin, + } + } + + // Make sure labeler was called. + _, err := controller.sync("", newAttribs(metav1.NewTime(time.Now()))) + require.NoError(t, err) + assert.Equal(t, 1, ensureLabelsCalledTimes) +} + +func TestSyncProviderRefreshNoConflict(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + NeedsRefresh: true, + } + + var ( + userAttributesGetCalledTimes int + userAttributesUpdateCalledTimes int + providerRefreshCalledTimes int + ) + + now := time.Now().Truncate(time.Second) + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + userAttributesGetCalledTimes++ + return attribs.DeepCopy(), nil + }) + userAttributeClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributesUpdateCalledTimes++ + attribs = userAttribute.DeepCopy() + return attribs, nil + }) + + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { return nil }, + providerRefresh: func(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + providerRefreshCalledTimes++ + a := attribs.DeepCopy() + a.NeedsRefresh = false + a.LastRefresh = now.Format(time.RFC3339) + a.GroupPrincipals = map[string]v3.Principals{"activedirectory": {}} + a.ExtraByProvider = map[string]map[string][]string{"activedirectory": {}} + return a, nil + }, + } + + obj, err := controller.sync("", attribs) + require.NoError(t, err) + + synced, ok := obj.(*v3.UserAttribute) + assert.True(t, ok) + assert.NotNil(t, synced) + + assert.Equal(t, 1, providerRefreshCalledTimes) + assert.Equal(t, 1, userAttributesGetCalledTimes) + assert.Equal(t, 1, userAttributesUpdateCalledTimes) + + assert.False(t, synced.NeedsRefresh) + assert.Equal(t, now.Format(time.RFC3339), synced.LastRefresh) + assert.Contains(t, synced.GroupPrincipals, "activedirectory") + assert.Contains(t, synced.ExtraByProvider, "activedirectory") +} + +func TestSyncProviderRefreshConflict(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + NeedsRefresh: true, + } + + var ( + userAttributesGetCalledTimes int + userAttributesUpdateCalledTimes int + providerRefreshCalledTimes int + ) + + groupResource := schema.GroupResource{ + Group: management.GroupName, + Resource: v3.UserAttributeResourceName, + } + + now := time.Now().Truncate(time.Second) + + ctrl := gomock.NewController(t) + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + userAttributesGetCalledTimes++ + + a := attribs.DeepCopy() + if userAttributesGetCalledTimes > 1 { + a.LastLogin = &metav1.Time{Time: now} + } + + return a, nil + }) + userAttributeClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributesUpdateCalledTimes++ + + if userAttributesUpdateCalledTimes == 1 { + return nil, apierrors.NewConflict(groupResource, userAttribute.Name, fmt.Errorf("some error")) + } + + attribs = userAttribute.DeepCopy() + return attribs, nil + }) + + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { return nil }, + providerRefresh: func(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + providerRefreshCalledTimes++ + a := attribs.DeepCopy() + a.NeedsRefresh = false + a.LastRefresh = now.Format(time.RFC3339) + a.GroupPrincipals = map[string]v3.Principals{"activedirectory": {}} + a.ExtraByProvider = map[string]map[string][]string{"activedirectory": {}} + return a, nil + }, + } + + obj, err := controller.sync("", attribs) + require.NoError(t, err) + + synced, ok := obj.(*v3.UserAttribute) + assert.True(t, ok) + assert.NotNil(t, synced) + + assert.Equal(t, 1, providerRefreshCalledTimes) + assert.Equal(t, 2, userAttributesGetCalledTimes) + // Make sure Update is called the second time. + assert.Equal(t, 2, userAttributesUpdateCalledTimes) + + // Make sure that changes from the provider refresh call were merged. + assert.Equal(t, now, synced.LastLogin.Time) + assert.False(t, synced.NeedsRefresh) + assert.Equal(t, now.Format(time.RFC3339), synced.LastRefresh) + assert.Contains(t, synced.GroupPrincipals, "activedirectory") + assert.Contains(t, synced.ExtraByProvider, "activedirectory") +} + +func TestSyncProviderRefreshUpdateNonConflictError(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + NeedsRefresh: true, + } + + var ( + userAttributesGetCalledTimes int + providerRefreshCalledTimes int + ) + + now := time.Now().Truncate(time.Second) + + ctrl := gomock.NewController(t) + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + userAttributesGetCalledTimes++ + + a := attribs.DeepCopy() + if userAttributesGetCalledTimes > 1 { + a.LastLogin = &metav1.Time{Time: now} + } + + return a, nil + }) + userAttributeClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return nil, fmt.Errorf("some error") + }) + + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { return nil }, + providerRefresh: func(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + providerRefreshCalledTimes++ + a := attribs.DeepCopy() + a.NeedsRefresh = false + a.LastRefresh = now.Format(time.RFC3339) + a.GroupPrincipals = map[string]v3.Principals{"activedirectory": {}} + a.ExtraByProvider = map[string]map[string][]string{"activedirectory": {}} + return a, nil + }, + } + + _, err := controller.sync("", attribs) + require.Error(t, err) + + assert.Equal(t, 1, providerRefreshCalledTimes) + assert.Equal(t, 1, userAttributesGetCalledTimes) +} + +func TestSyncProviderRefreshErrorAfterHandlingConflict(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + NeedsRefresh: true, + } + + var ( + userAttributesGetCalledTimes int + providerRefreshCalledTimes int + ) + + groupResource := schema.GroupResource{ + Group: management.GroupName, + Resource: v3.UserAttributeResourceName, + } + + now := time.Now().Truncate(time.Second) + + ctrl := gomock.NewController(t) + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + userAttributesGetCalledTimes++ + + a := attribs.DeepCopy() + if userAttributesGetCalledTimes > 1 { + a.LastLogin = &metav1.Time{Time: now} + } + + return a, nil + }) + userAttributeClient.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return nil, apierrors.NewConflict(groupResource, userAttribute.Name, fmt.Errorf("some error")) + }) + + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { return nil }, + providerRefresh: func(attribs *v3.UserAttribute) (*v3.UserAttribute, error) { + providerRefreshCalledTimes++ + a := attribs.DeepCopy() + a.NeedsRefresh = false + a.LastRefresh = now.Format(time.RFC3339) + a.GroupPrincipals = map[string]v3.Principals{"activedirectory": {}} + a.ExtraByProvider = map[string]map[string][]string{"activedirectory": {}} + return a, nil + }, + } + + _, err := controller.sync("", attribs) + require.Error(t, err) + + assert.Equal(t, 1, providerRefreshCalledTimes) + assert.Equal(t, 2, userAttributesGetCalledTimes) +} + +func TestSyncGetUserAttributeFails(t *testing.T) { + userID := "u-abcdef" + attribs := &v3.UserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: userID, + }, + NeedsRefresh: true, + } + + ctrl := gomock.NewController(t) + + userAttributeClient := fake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributeClient.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes().DoAndReturn(func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + return nil, fmt.Errorf("some error") + }) + userAttributeClient.EXPECT().Update(gomock.Any()).Times(0) + + controller := UserAttributeController{ + userAttributes: userAttributeClient, + ensureUserRetentionLabels: func(attribs *v3.UserAttribute) error { return nil }, + } + + _, err := controller.sync("", attribs) + require.Error(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_test.go new file mode 100644 index 0000000..6defe71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/user_test.go @@ -0,0 +1,786 @@ +package auth + +import ( + "fmt" + "testing" + + management "github.com/rancher/rancher/pkg/apis/management.cattle.io" + fakes "github.com/rancher/rancher/pkg/controllers/management/auth/fakes" + coreFakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementFakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + v12 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func Test_hasLocalPrincipalID(t *testing.T) { + type args struct { + user *v3.User + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "has local PrincipalID", + args: args{ + user: &v3.User{ + Username: "testuser", + PrincipalIDs: []string{ + "ID1", + "ID2", + "local://testuser", + }, + }, + }, + want: true, + }, + { + name: "has no local PrincipalIDs", + args: args{ + user: &v3.User{ + Username: "testuser", + PrincipalIDs: []string{ + "ID1", + "ID2", + }, + }, + }, + want: false, + }, + { + name: "PrincipalIDs is empty", + args: args{ + user: &v3.User{ + Username: "testuser", + PrincipalIDs: []string{}, + }, + }, + want: false, + }, + { + name: "has multiple local PrincipalIDs", + args: args{ + user: &v3.User{ + Username: "testuser", + PrincipalIDs: []string{ + "ID1", + "local://localuser", + "ID2", + "local://testuser", + }, + }, + }, + want: true, + }, + { + name: "PrincipalIDs is nil", + args: args{ + user: &v3.User{ + Username: "testuser", + PrincipalIDs: nil, + }, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := hasLocalPrincipalID(tt.args.user); got != tt.want { + t.Errorf("hasValidPrincipalIDs() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCreate(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockUserManager := fakes.NewMockManager(ctrl) + + ul := &userLifecycle{ + userManager: mockUserManager, + } + + tests := []struct { + name string + inputUser *v3.User + mockSetup func() + expectedUser *v3.User + expectedError bool + }{ + { + name: "User without local principal IDs", + inputUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Annotations: map[string]string{}, + }, + PrincipalIDs: []string{}, + }, + mockSetup: func() {}, + expectedUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Annotations: map[string]string{}, + }, + PrincipalIDs: []string{"local://testuser"}, + }, + expectedError: false, + }, + { + name: "User with creatorID annotation and successful role binding", + inputUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + UID: defaultCRTB.UID, + Annotations: map[string]string{creatorIDAnn: "creator"}, + }, + PrincipalIDs: []string{}, + }, + mockSetup: func() { + mockUserManager.EXPECT().CreateNewUserClusterRoleBinding("testuser", defaultCRTB.UID).Return(nil) + }, + expectedUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Annotations: map[string]string{creatorIDAnn: "creator"}, + }, + PrincipalIDs: []string{"local://testuser"}, + }, + expectedError: false, + }, + { + name: "User with creatorID annotation and role binding error", + inputUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Annotations: map[string]string{creatorIDAnn: "creator"}, + }, + PrincipalIDs: []string{}, + }, + mockSetup: func() { + mockUserManager.EXPECT().CreateNewUserClusterRoleBinding("testuser", defaultCRTB.UID).Return(fmt.Errorf("role binding error")) + }, + expectedUser: nil, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + _, err := ul.Create(tt.inputUser) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestUpdated(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockUserManager := fakes.NewMockManager(ctrl) + + ul := &userLifecycle{ + userManager: mockUserManager, + } + + tests := []struct { + name string + inputUser *v3.User + mockSetup func() + expectedUser *v3.User + expectedError bool + }{ + { + name: "user was not updated properly", + inputUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + PrincipalIDs: []string{}, + }, + mockSetup: func() { + mockUserManager.EXPECT().CreateNewUserClusterRoleBinding("testuser", defaultCRTB.UID).Return(fmt.Errorf("error updating user")) + }, + expectedUser: nil, + expectedError: true, + }, + { + name: "user was updated", + inputUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + PrincipalIDs: []string{}, + }, + mockSetup: func() { + mockUserManager.EXPECT().CreateNewUserClusterRoleBinding("testuser", defaultCRTB.UID).Return(nil) + }, + expectedUser: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Annotations: map[string]string{creatorIDAnn: "creator"}, + }, + PrincipalIDs: []string{"local://testuser"}, + }, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + _, err := ul.Updated(tt.inputUser) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_deleteAllCRTB(t *testing.T) { + ctrbMock := &managementFakes.ClusterRoleTemplateBindingInterfaceMock{} + + ul := &userLifecycle{ + crtb: ctrbMock, + } + + tests := []struct { + name string + inputCRTB []*v3.ClusterRoleTemplateBinding + mockSetup func() + expectedError bool + }{ + { + name: "crtb deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "crtbs deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser-2", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "namespaced crtbs deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Namespace: "testnamespace", + }, + }, + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser-2", + Namespace: "testnamespace", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "crtbs (non and namespaced) deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser-2", + Namespace: "testnamespace", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "crtbs (non and namespaced) not deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser-2", + Namespace: "testnamespace", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("namespaced crtb not deleted") + } + }, + expectedError: true, + }, + { + name: "crtbs not deleted properly", + inputCRTB: []*v3.ClusterRoleTemplateBinding{ + &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + }, + }, + }, + mockSetup: func() { + ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("some error") + } + }, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + err := ul.deleteAllCRTB(tt.inputCRTB) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_deleteAllPRTB(t *testing.T) { + prtbMock := &managementFakes.ProjectRoleTemplateBindingInterfaceMock{} + + ul := &userLifecycle{ + prtb: prtbMock, + } + + tests := []struct { + name string + inputPRTB []*v3.ProjectRoleTemplateBinding + mockSetup func() + expectedError bool + }{ + { + name: "remove namespaced prtb", + inputPRTB: []*v3.ProjectRoleTemplateBinding{ + &v3.ProjectRoleTemplateBinding{ + UserName: "testuser", + ObjectMeta: metav1.ObjectMeta{ + Name: "testprtb", + Namespace: "testprtbns", + }, + }, + }, + mockSetup: func() { + prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "remove all prtb", + inputPRTB: []*v3.ProjectRoleTemplateBinding{ + &v3.ProjectRoleTemplateBinding{ + UserName: "testuser", + ObjectMeta: metav1.ObjectMeta{ + Name: "testprtb", + Namespace: "testprtbns", + }, + }, + &v3.ProjectRoleTemplateBinding{ + UserName: "testuser2", + ObjectMeta: metav1.ObjectMeta{ + Name: "testprtb2", + }, + }, + }, + mockSetup: func() { + prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return nil + } + prtbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "error deleting namespaced prtb", + inputPRTB: []*v3.ProjectRoleTemplateBinding{ + &v3.ProjectRoleTemplateBinding{ + UserName: "testuser", + ObjectMeta: metav1.ObjectMeta{ + Name: "testprtb", + Namespace: "testprtbns", + }, + }, + }, + mockSetup: func() { + prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("some error") + } + }, + expectedError: true, + }, + { + name: "error deleting prtb", + inputPRTB: []*v3.ProjectRoleTemplateBinding{ + &v3.ProjectRoleTemplateBinding{ + UserName: "testuser", + ObjectMeta: metav1.ObjectMeta{ + Name: "testprtb", + }, + }, + }, + mockSetup: func() { + prtbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("some error") + } + }, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + err := ul.deleteAllPRTB(tt.inputPRTB) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_deleteUserNamespace(t *testing.T) { + namespaceMock := &coreFakes.NamespaceInterfaceMock{} + namespaceListerMock := &coreFakes.NamespaceListerMock{} + + ul := &userLifecycle{ + namespaces: namespaceMock, + namespaceLister: namespaceListerMock, + } + + tests := []struct { + name string + username string + mockSetup func() + expectedError bool + }{ + { + name: "delete namespace", + username: "testuser", + mockSetup: func() { + namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { + return &v12.Namespace{}, nil + } + namespaceMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "error getting namespace", + username: "testuser", + mockSetup: func() { + namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { + return nil, fmt.Errorf("some error") + } + }, + expectedError: true, + }, + { + name: "error deleting namespace", + username: "testuser", + mockSetup: func() { + namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { + return &v12.Namespace{}, nil + } + namespaceMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("some error") + } + }, + expectedError: true, + }, + { + name: "namespace is in termination state", + username: "testuser", + mockSetup: func() { + namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { + return &v12.Namespace{ + Status: v12.NamespaceStatus{ + Phase: v12.NamespaceTerminating, + }, + }, nil + } + }, + expectedError: false, + }, + { + name: "namespace was not found", + username: "testuser", + mockSetup: func() { + namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: management.GroupName, + Resource: "Namespace", + }, "testns") + } + }, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + err := ul.deleteUserNamespace(tt.username) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_deleteUserSecret(t *testing.T) { + secretsMock := &coreFakes.SecretInterfaceMock{} + secretsListerMock := &coreFakes.SecretListerMock{} + + ul := &userLifecycle{ + secrets: secretsMock, + secretsLister: secretsListerMock, + } + + tests := []struct { + name string + username string + mockSetup func() + expectedError bool + }{ + { + name: "delete secret", + username: "testuser", + mockSetup: func() { + secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { + return &v12.Secret{}, nil + } + secretsMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return nil + } + }, + expectedError: false, + }, + { + name: "error getting secret", + username: "testuser", + mockSetup: func() { + secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { + return nil, fmt.Errorf("some error") + } + }, + expectedError: true, + }, + { + name: "error deleting secret", + username: "testuser", + mockSetup: func() { + secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { + return &v12.Secret{}, nil + } + secretsMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { + return fmt.Errorf("some error") + } + }, + expectedError: true, + }, + { + name: "secret not found", + username: "testuser", + mockSetup: func() { + secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: management.GroupName, + Resource: "Secrets", + }, "testsecret") + } + }, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + err := ul.deleteUserSecret(tt.username) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_removeLegacyFinalizers(t *testing.T) { + usersMock := &managementFakes.UserInterfaceMock{} + + ul := &userLifecycle{ + users: usersMock, + } + + tests := []struct { + name string + user *v3.User + mockSetup func() + expectedError bool + }{ + { + name: "no need to remove finalizers", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Finalizers: []string{ + "controller.cattle.io/test-finalizer", + }, + }, + }, + mockSetup: func() {}, + expectedError: false, + }, + { + name: "remove desired finalizer", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Finalizers: []string{ + "controller.cattle.io/test-finalizer", + "controller.cattle.io/cat-user-controller", + }, + }, + }, + mockSetup: func() { + usersMock.UpdateFunc = func(in1 *v3.User) (*v3.User, error) { + return &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Finalizers: []string{ + "controller.cattle.io/test-finalizer", + }, + }, + }, nil + } + }, + expectedError: false, + }, + { + name: "got error when updating user", + user: &v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testuser", + Finalizers: []string{ + "controller.cattle.io/test-finalizer", + "controller.cattle.io/cat-user-controller", + }, + }, + }, + mockSetup: func() { + usersMock.UpdateFunc = func(in1 *v3.User) (*v3.User, error) { + return nil, fmt.Errorf("some error") + } + }, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.mockSetup() + + user, err := ul.removeLegacyFinalizers(tt.user) + + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.NotContains(t, user.Finalizers, "controller.cattle.io/cat-user-controller") + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/zz_manager_fakes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/zz_manager_fakes.go new file mode 100644 index 0000000..5445787 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/auth/zz_manager_fakes.go @@ -0,0 +1,169 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: manager.go +// +// Generated by this command: +// +// mockgen -source=manager.go -destination=zz_manager_fakes.go -package=auth +// + +// Package auth is a generated GoMock package. +package auth + +import ( + reflect "reflect" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + gomock "go.uber.org/mock/gomock" + v1 "k8s.io/api/rbac/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// MockmanagerInterface is a mock of managerInterface interface. +type MockmanagerInterface struct { + ctrl *gomock.Controller + recorder *MockmanagerInterfaceMockRecorder +} + +// MockmanagerInterfaceMockRecorder is the mock recorder for MockmanagerInterface. +type MockmanagerInterfaceMockRecorder struct { + mock *MockmanagerInterface +} + +// NewMockmanagerInterface creates a new mock instance. +func NewMockmanagerInterface(ctrl *gomock.Controller) *MockmanagerInterface { + mock := &MockmanagerInterface{ctrl: ctrl} + mock.recorder = &MockmanagerInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockmanagerInterface) EXPECT() *MockmanagerInterfaceMockRecorder { + return m.recorder +} + +// checkReferencedRoles mocks base method. +func (m *MockmanagerInterface) checkReferencedRoles(arg0, arg1 string, arg2 int) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "checkReferencedRoles", arg0, arg1, arg2) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// checkReferencedRoles indicates an expected call of checkReferencedRoles. +func (mr *MockmanagerInterfaceMockRecorder) checkReferencedRoles(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "checkReferencedRoles", reflect.TypeOf((*MockmanagerInterface)(nil).checkReferencedRoles), arg0, arg1, arg2) +} + +// ensureClusterMembershipBinding mocks base method. +func (m *MockmanagerInterface) ensureClusterMembershipBinding(arg0, arg1 string, arg2 *v3.Cluster, arg3 bool, arg4 v1.Subject) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureClusterMembershipBinding", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureClusterMembershipBinding indicates an expected call of ensureClusterMembershipBinding. +func (mr *MockmanagerInterfaceMockRecorder) ensureClusterMembershipBinding(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureClusterMembershipBinding", reflect.TypeOf((*MockmanagerInterface)(nil).ensureClusterMembershipBinding), arg0, arg1, arg2, arg3, arg4) +} + +// ensureProjectMembershipBinding mocks base method. +func (m *MockmanagerInterface) ensureProjectMembershipBinding(arg0, arg1, arg2 string, arg3 *v3.Project, arg4 bool, arg5 v1.Subject) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureProjectMembershipBinding", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureProjectMembershipBinding indicates an expected call of ensureProjectMembershipBinding. +func (mr *MockmanagerInterfaceMockRecorder) ensureProjectMembershipBinding(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureProjectMembershipBinding", reflect.TypeOf((*MockmanagerInterface)(nil).ensureProjectMembershipBinding), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// grantManagementClusterScopedPrivilegesInProjectNamespace mocks base method. +func (m *MockmanagerInterface) grantManagementClusterScopedPrivilegesInProjectNamespace(arg0, arg1 string, arg2 map[string]string, arg3 v1.Subject, arg4 *v3.ClusterRoleTemplateBinding) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "grantManagementClusterScopedPrivilegesInProjectNamespace", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// grantManagementClusterScopedPrivilegesInProjectNamespace indicates an expected call of grantManagementClusterScopedPrivilegesInProjectNamespace. +func (mr *MockmanagerInterfaceMockRecorder) grantManagementClusterScopedPrivilegesInProjectNamespace(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "grantManagementClusterScopedPrivilegesInProjectNamespace", reflect.TypeOf((*MockmanagerInterface)(nil).grantManagementClusterScopedPrivilegesInProjectNamespace), arg0, arg1, arg2, arg3, arg4) +} + +// grantManagementPlanePrivileges mocks base method. +func (m *MockmanagerInterface) grantManagementPlanePrivileges(arg0 string, arg1 map[string]string, arg2 v1.Subject, arg3 any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "grantManagementPlanePrivileges", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 +} + +// grantManagementPlanePrivileges indicates an expected call of grantManagementPlanePrivileges. +func (mr *MockmanagerInterfaceMockRecorder) grantManagementPlanePrivileges(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "grantManagementPlanePrivileges", reflect.TypeOf((*MockmanagerInterface)(nil).grantManagementPlanePrivileges), arg0, arg1, arg2, arg3) +} + +// grantManagementProjectScopedPrivilegesInClusterNamespace mocks base method. +func (m *MockmanagerInterface) grantManagementProjectScopedPrivilegesInClusterNamespace(arg0, arg1 string, arg2 map[string]string, arg3 v1.Subject, arg4 *v3.ProjectRoleTemplateBinding) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "grantManagementProjectScopedPrivilegesInClusterNamespace", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 +} + +// grantManagementProjectScopedPrivilegesInClusterNamespace indicates an expected call of grantManagementProjectScopedPrivilegesInClusterNamespace. +func (mr *MockmanagerInterfaceMockRecorder) grantManagementProjectScopedPrivilegesInClusterNamespace(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "grantManagementProjectScopedPrivilegesInClusterNamespace", reflect.TypeOf((*MockmanagerInterface)(nil).grantManagementProjectScopedPrivilegesInClusterNamespace), arg0, arg1, arg2, arg3, arg4) +} + +// reconcileClusterMembershipBindingForDelete mocks base method. +func (m *MockmanagerInterface) reconcileClusterMembershipBindingForDelete(arg0, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "reconcileClusterMembershipBindingForDelete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// reconcileClusterMembershipBindingForDelete indicates an expected call of reconcileClusterMembershipBindingForDelete. +func (mr *MockmanagerInterfaceMockRecorder) reconcileClusterMembershipBindingForDelete(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "reconcileClusterMembershipBindingForDelete", reflect.TypeOf((*MockmanagerInterface)(nil).reconcileClusterMembershipBindingForDelete), arg0, arg1) +} + +// reconcileProjectMembershipBindingForDelete mocks base method. +func (m *MockmanagerInterface) reconcileProjectMembershipBindingForDelete(arg0, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "reconcileProjectMembershipBindingForDelete", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// reconcileProjectMembershipBindingForDelete indicates an expected call of reconcileProjectMembershipBindingForDelete. +func (mr *MockmanagerInterfaceMockRecorder) reconcileProjectMembershipBindingForDelete(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "reconcileProjectMembershipBindingForDelete", reflect.TypeOf((*MockmanagerInterface)(nil).reconcileProjectMembershipBindingForDelete), arg0, arg1, arg2) +} + +// removeAuthV2Permissions mocks base method. +func (m *MockmanagerInterface) removeAuthV2Permissions(arg0 string, arg1 runtime.Object) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "removeAuthV2Permissions", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// removeAuthV2Permissions indicates an expected call of removeAuthV2Permissions. +func (mr *MockmanagerInterfaceMockRecorder) removeAuthV2Permissions(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "removeAuthV2Permissions", reflect.TypeOf((*MockmanagerInterface)(nil).removeAuthV2Permissions), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/authprovisioningv2.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/authprovisioningv2.go new file mode 100644 index 0000000..074594e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/authprovisioningv2.go @@ -0,0 +1,113 @@ +package authprovisioningv2 + +import ( + "context" + "sync" + + "github.com/moby/locker" + "github.com/rancher/lasso/pkg/dynamic" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/features" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + provisioningcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/apply" + apiextcontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io/v1" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/gvk" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + byClusterName = "byClusterName" + crbtByRoleTemplateName = "crbtByRoleTemplateName" +) + +type handler struct { + mgmtCtx *config.ManagementContext + roleLocker locker.Locker + roleCache rbacv1.RoleCache + roleController rbacv1.RoleController + roleBindingController rbacv1.RoleBindingController + clusterRoleController rbacv1.ClusterRoleController + clusterRoleBindingController rbacv1.ClusterRoleBindingController + clusterRoleCache rbacv1.ClusterRoleCache + roleTemplateController mgmtcontrollers.RoleTemplateController + clusterRoleTemplateBindings mgmtcontrollers.ClusterRoleTemplateBindingCache + clusterRoleTemplateBindingController mgmtcontrollers.ClusterRoleTemplateBindingController + projectRoleTemplateBindingController mgmtcontrollers.ProjectRoleTemplateBindingController + roleTemplatesCache mgmtcontrollers.RoleTemplateCache + clusters provisioningcontrollers.ClusterCache + mgmtClusters mgmtcontrollers.ClusterCache + crdCache apiextcontrollers.CustomResourceDefinitionCache + dynamic *dynamic.Controller + resources map[schema.GroupVersionKind]resourceMatch + resourcesList []resourceMatch + resourcesLock sync.RWMutex + apply apply.Apply + roleBindingApply apply.Apply + provisioningClusterGVK schema.GroupVersionKind +} + +func Register(ctx context.Context, clients *wrangler.Context, management *config.ManagementContext) error { + clusterGVK, err := gvk.Get(&v1.Cluster{}) + if err != nil { + // this is a build issue if it happens + panic(err) + } + + h := &handler{ + mgmtCtx: management, + roleCache: clients.RBAC.Role().Cache(), + roleController: clients.RBAC.Role(), + roleBindingController: clients.RBAC.RoleBinding(), + clusterRoleController: clients.RBAC.ClusterRole(), + clusterRoleBindingController: clients.RBAC.ClusterRoleBinding(), + clusterRoleCache: clients.RBAC.ClusterRole().Cache(), + roleTemplateController: clients.Mgmt.RoleTemplate(), + clusterRoleTemplateBindings: clients.Mgmt.ClusterRoleTemplateBinding().Cache(), + clusterRoleTemplateBindingController: clients.Mgmt.ClusterRoleTemplateBinding(), + projectRoleTemplateBindingController: clients.Mgmt.ProjectRoleTemplateBinding(), + roleTemplatesCache: clients.Mgmt.RoleTemplate().Cache(), + clusters: clients.Provisioning.Cluster().Cache(), + mgmtClusters: clients.Mgmt.Cluster().Cache(), + crdCache: clients.CRD.CustomResourceDefinition().Cache(), + dynamic: clients.Dynamic, + apply: clients.Apply.WithCacheTypes( + clients.Mgmt.RoleTemplate(), + clients.RBAC.Role()), + roleBindingApply: clients.Apply.WithCacheTypes( + clients.Mgmt.ClusterRoleTemplateBinding(), + clients.RBAC.RoleBinding()), + resources: map[schema.GroupVersionKind]resourceMatch{}, + provisioningClusterGVK: clusterGVK, + } + + if err := h.initializeCRDs(clients.CRD.CustomResourceDefinition()); err != nil { + return err + } + + h.dynamic.AddIndexer(clusterIndexed, h.gvkMatcher, indexByCluster) + h.dynamic.OnChange(ctx, "auth-prov-v2-trigger", h.gvkMatcher, h.OnClusterObjectChanged) + clients.Mgmt.RoleTemplate().OnChange(ctx, "auth-prov-v2-roletemplate", h.OnChange) + clients.Mgmt.ClusterRoleTemplateBinding().OnChange(ctx, "auth-prov-v2-crtb", h.OnCRTB) + clients.Mgmt.ProjectRoleTemplateBinding().OnChange(ctx, "auth-prov-v2-prtb", h.OnPRTB) + clients.RBAC.Role().OnRemove(ctx, "auth-prov-v2-role", h.OnRemoveRole) + clients.RBAC.RoleBinding().OnRemove(ctx, "auth-prov-v2-rb", h.OnRemoveRoleBinding) + clients.RBAC.ClusterRole().OnRemove(ctx, "auth-prov-v2-crole", h.OnRemoveClusterRole) + clients.RBAC.ClusterRoleBinding().OnRemove(ctx, "auth-prov-v2-crb", h.OnRemoveClusterRoleBinding) + clients.Provisioning.Cluster().OnChange(ctx, "auth-prov-v2-cluster", h.OnCluster) + clients.CRD.CustomResourceDefinition().OnChange(ctx, "auth-prov-v2-crd", h.OnCRD) + if features.RKE2.Enabled() { + clients.Dynamic.OnChange(ctx, "auth-prov-v2-rke-machine-config", validMachineConfigGVK, h.OnMachineConfigChange) + } + clients.Provisioning.Cluster().Cache().AddIndexer(byClusterName, func(obj *v1.Cluster) ([]string, error) { + return []string{obj.Status.ClusterName}, nil + }) + clients.Mgmt.ClusterRoleTemplateBinding().Cache().AddIndexer(crbtByRoleTemplateName, func(obj *v3.ClusterRoleTemplateBinding) ([]string, error) { + return []string{obj.RoleTemplateName}, nil + }) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/cluster.go new file mode 100644 index 0000000..4d521c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/cluster.go @@ -0,0 +1,103 @@ +package authprovisioningv2 + +import ( + "fmt" + "reflect" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/rbac" + rbacv1 "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OnCluster creates the roles required for users to be able to see/manage the +// provisioning cluster resource +func (h *handler) OnCluster(key string, cluster *v1.Cluster) (*v1.Cluster, error) { + if cluster == nil { + return cluster, nil + } + + if cluster.DeletionTimestamp != nil { + return cluster, h.cleanClusterAdminRoleBindings(cluster) + } + + return cluster, h.createClusterViewRole(cluster) +} + +func (h *handler) createClusterViewRole(cluster *v1.Cluster) error { + roleName := clusterViewName(cluster) + role := &rbacv1.Role{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: cluster.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: cluster.APIVersion, + Kind: cluster.Kind, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{cluster.GroupVersionKind().Group}, + Resources: []string{"clusters"}, + ResourceNames: []string{cluster.Name}, + Verbs: []string{"get"}, + }, + }, + } + + existingRole, err := h.roleCache.Get(cluster.Namespace, roleName) + if err != nil { + if !k8serrors.IsNotFound(err) { + return err + } + + if _, err := h.roleController.Create(role); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + return nil + } + + if !reflect.DeepEqual(existingRole.Rules, role.Rules) { + existingRole = existingRole.DeepCopy() + existingRole.Rules = role.Rules + _, err := h.roleController.Update(existingRole) + return err + } + + return nil +} + +func (h *handler) cleanClusterAdminRoleBindings(cluster *v1.Cluster) error { + // Collect all the errors to delete as many rolebindings as possible + var allErrors []error + + roleName := rbac.ProvisioningClusterAdminName(cluster) + rbList, err := h.roleBindingController.List(cluster.Namespace, metav1.ListOptions{}) + if err != nil { + return err + } + + for _, roleBinding := range rbList.Items { + if roleBinding.RoleRef.Kind == "Role" && roleBinding.RoleRef.Name == roleName { + err = h.roleBindingController.Delete(roleBinding.Namespace, roleBinding.Name, &metav1.DeleteOptions{}) + if err != nil { + // Continue if this RoleBinding doesn't exist + if !k8serrors.IsNotFound(err) { + allErrors = append(allErrors, err) + } + continue + } + } + } + + if len(allErrors) > 0 { + return fmt.Errorf("errors deleting cluster admin role binding: %v", allErrors) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/crtb.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/crtb.go new file mode 100644 index 0000000..bdded27 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/crtb.go @@ -0,0 +1,146 @@ +package authprovisioningv2 + +import ( + "reflect" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const CRTBRoleBindingID = "auth-prov-v2-crtb-rolebinding" + +// OnCRTB create a "membership" binding that gives the subject access to the the cluster custom resource itself +// along with granting any clusterIndexed permissions based on the roleTemplate +func (h *handler) OnCRTB(key string, crtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + if crtb == nil || crtb.DeletionTimestamp != nil || crtb.RoleTemplateName == "" || crtb.ClusterName == "" { + return crtb, nil + } + + clusters, err := h.clusters.GetByIndex(byClusterName, crtb.ClusterName) + if err != nil { + return nil, err + } + + if len(clusters) == 0 { + // When no provisioning cluster is found, enqueue the CRTB to wait for + // the provisioning cluster to be created. If we don't try again + // permissions for the provisioning objects won't be created until an + // update to the CRTB happens again. + logrus.Debugf("[auth-prov-v2-crtb] No provisioning cluster found for cluster %v, enqueuing CRTB %v ", crtb.ClusterName, crtb.Name) + h.clusterRoleTemplateBindingController.EnqueueAfter(crtb.Namespace, crtb.Name, 10*time.Second) + return crtb, nil + } + + cluster := clusters[0] + + rt, err := h.roleTemplatesCache.Get(crtb.RoleTemplateName) + if err != nil { + return crtb, err + } + + clusterIndexed, provisioningCluster, err := h.isClusterIndexed(rt) + if err != nil { + return crtb, err + } + + subject, err := rbac.BuildSubjectFromRTB(crtb) + if err != nil { + return nil, err + } + + hashedSubject := hashSubject(subject) + + var bindings []runtime.Object + + // Based on the rules in the roleTemplate we need to decide if an additional role binding + // needs to be created in order to give the subject of the CRTB permissions to view + // the provisioning cluster. The additional binding is added as oppose to editing the + // the existing role because not all CRTBs grant clusterIndexed permissions.This will also + // make troubleshooting permissions assigned to a user easier and makes tying a role + // back to a roleTemplate easier. + // clusterIndexed and provisioningCluster are both true: One binding is created for the original CRTB + // because the roleTemplate already grants permissions to the provisioning cluster. + // clusterIndexed and provisioningCluster are both false: One binding is created which grants + // permissions to view the provisioning cluster as the roleTemplate does not grant any clusterIndexed items. + // clusterIndexed is true and provisioningCluster is false: Two bindings are created, one + // for the original CRTB and a 2nd one for viewing the provisioning cluster since the original + // roleTemplate does not grant permission for the provisioning cluster. + if clusterIndexed { + // The roleBinding name format: crt--- + // Example: crt-cluster1-creator-cluster-owner-blxbujr34t + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName("crt", cluster.Name, crtb.Name, hashedSubject), + Namespace: cluster.Namespace, + Annotations: map[string]string{clusterNameLabel: cluster.GetName(), clusterNamespaceLabel: cluster.GetNamespace()}, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: roleTemplateRoleName(crtb.RoleTemplateName, cluster.Name), + }, + Subjects: []rbacv1.Subject{subject}, + } + bindings = append(bindings, roleBinding) + } + + if !provisioningCluster { + // The roleBinding name format: r-cluster--view-- + // Example: r-cluster1-view-crtb-foo-wn5d5n7udr + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(clusterViewName(cluster), crtb.Name, hashedSubject), + Namespace: cluster.Namespace, + Annotations: map[string]string{clusterNameLabel: cluster.GetName(), clusterNamespaceLabel: cluster.GetNamespace()}, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: clusterViewName(cluster), + }, + Subjects: []rbacv1.Subject{subject}, + } + bindings = append(bindings, roleBinding) + } + + return crtb, h.roleBindingApply. + WithListerNamespace(cluster.Namespace). + WithSetID(CRTBRoleBindingID). + WithOwner(crtb). + ApplyObjects(bindings...) +} + +func (h *handler) isClusterIndexed(rt *v3.RoleTemplate) (bool, bool, error) { + var clusterIndexed, provisioningCluster bool + + rules, err := rbac.RulesFromTemplate(h.clusterRoleCache, h.roleTemplatesCache, rt) + if err != nil { + return clusterIndexed, provisioningCluster, err + } + + for _, rule := range rules { + if len(rule.NonResourceURLs) > 0 || len(rule.ResourceNames) > 0 { + continue + } + matches, err := h.getMatchingClusterIndexedTypes(rule) + if err != nil { + return clusterIndexed, provisioningCluster, err + } + if len(matches) > 0 { + clusterIndexed = true + for _, match := range matches { + if reflect.DeepEqual(match.GVK, h.provisioningClusterGVK) { + return clusterIndexed, true, nil + } + } + } + + } + return clusterIndexed, provisioningCluster, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/indexer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/indexer.go new file mode 100644 index 0000000..a2a8a41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/indexer.go @@ -0,0 +1,88 @@ +package authprovisioningv2 + +import ( + "fmt" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/controllers/capr/dynamicschema" + "github.com/rancher/wrangler/v3/pkg/data" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type clusterNames interface { + GetClusterNames() []string +} + +func getObjectClusterNames(obj runtime.Object) ([]string, error) { + clusterNamed, ok := obj.(clusterNames) + if ok { + return clusterNamed.GetClusterNames(), nil + } + + switch o := obj.(type) { + case *capi.Machine: + return []string{o.Spec.ClusterName}, nil + case *capi.Cluster: + return []string{o.Name}, nil + case *v1.Cluster: + return []string{o.Name}, nil + } + + gvk := obj.GetObjectKind().GroupVersionKind() + if gvk.Group == dynamicschema.MachineConfigAPIGroup { + objMeta, err := meta.Accessor(obj) + // If there is an error, skip this block + if err == nil { + for _, owner := range objMeta.GetOwnerReferences() { + if owner.APIVersion == "provisioning.cattle.io/v1" && owner.Kind == "Cluster" { + return []string{owner.Name}, nil + } + } + } + } + + objData, err := data.Convert(obj) + if err != nil { + return nil, err + } + clusterName := objData.String("spec", "clusterName") + if clusterName != "" { + return []string{clusterName}, nil + } + + var result []string + targets := objData.Slice("spec", "target") + if len(targets) == 1 { + clusterName := objData.String("clusterName") + if clusterName != "" { + result = append(result, clusterName) + } + } + + return result, nil +} + +func indexByCluster(obj runtime.Object) ([]string, error) { + clusterNames, err := getObjectClusterNames(obj) + if err != nil { + return nil, err + } + + if len(clusterNames) == 0 { + return nil, nil + } + + meta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + + result := make([]string, 0, len(clusterNames)) + for _, clusterName := range clusterNames { + result = append(result, fmt.Sprintf("%s/%s", meta.GetNamespace(), clusterName)) + } + + return result, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/machineconfigs.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/machineconfigs.go new file mode 100644 index 0000000..cb48e6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/machineconfigs.go @@ -0,0 +1,79 @@ +package authprovisioningv2 + +import ( + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/nodetemplate" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/wrangler/v3/pkg/data" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func validMachineConfigGVK(gvk schema.GroupVersionKind) bool { + return gvk.Group == "rke-machine-config.cattle.io" && + gvk.Version == "v1" && + strings.HasSuffix(gvk.Kind, "Config") +} + +func (h *handler) OnMachineConfigChange(obj runtime.Object) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + + objMeta, err := meta.Accessor(obj) + if err != nil || !objMeta.GetDeletionTimestamp().IsZero() { + return nil, err + } + + // if owner bindings annotation is present, the node template is in the proper namespace and has had + // its creator rolebindings created + annotations := objMeta.GetAnnotations() + if annotations != nil && annotations[nodetemplate.OwnerBindingsAnno] == "true" { + return obj, nil + } + + gvk := obj.GetObjectKind().GroupVersionKind() + creatorID, ok := annotations[rbac.CreatorIDAnn] + if !ok { + // If the creatorID annotation is not present, then the roles and rolebindings cannot be created. + // We don't error here because there could be existing machine configs without this annotation. + return obj, nil + } + + apiVersion, kind := gvk.ToAPIVersionAndKind() + resourceName := strings.ToLower(kind) + if strings.HasSuffix(resourceName, "config") { + resourceName += "s" + } + // Create Role and RBs if they do not exist + if err := rbac.CreateRoleAndRoleBinding(resourceName, kind, objMeta.GetName(), objMeta.GetNamespace(), apiVersion, creatorID, []string{gvk.Group}, + objMeta.GetUID(), + []v32.Member{}, h.mgmtCtx); err != nil { + return nil, err + } + + dynamicMachineConfig, err := h.dynamic.Get(gvk, objMeta.GetNamespace(), objMeta.GetName()) + if err != nil { + return nil, err + } + + objData, err := data.Convert(dynamicMachineConfig.DeepCopyObject()) + if err != nil { + return nil, err + } + + anns := objData.Map("metadata", "annotations") + // owner bindings annotation is meant to prevent bindings from being created again if they have been removed from creator + anns[nodetemplate.OwnerBindingsAnno] = "true" + objData.SetNested(anns, "metadata", "annotations") + + if _, err = h.dynamic.Update(&unstructured.Unstructured{Object: objData}); err != nil { + return nil, err + } + + return h.dynamic.Get(gvk, objMeta.GetNamespace(), objMeta.GetName()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/prtb.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/prtb.go new file mode 100644 index 0000000..6755b7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/prtb.go @@ -0,0 +1,101 @@ +package authprovisioningv2 + +import ( + "crypto/sha256" + "encoding/base32" + "strings" + "time" + + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const PRTBRoleBindingID = "auth-prov-v2-prtb-rolebinding" + +func (h *handler) OnPRTB(key string, prtb *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + if prtb == nil || prtb.DeletionTimestamp != nil || prtb.RoleTemplateName == "" || prtb.ProjectName == "" || prtb.ServiceAccount != "" { + return prtb, nil + } + + parts := strings.SplitN(prtb.ProjectName, ":", 2) + if len(parts) < 2 { + return prtb, errors.Errorf("cannot determine project and cluster from %v", prtb.ProjectName) + } + + clusterName := parts[0] + + clusters, err := h.clusters.GetByIndex(byClusterName, clusterName) + if err != nil { + return prtb, err + } + + if len(clusters) == 0 { + // When no provisioning cluster is found, enqueue the PRTB to wait for + // the provisioning cluster to be created. If we don't try again + // permissions for the provisioning objects won't be created until an + // update to the PRTB happens again. + logrus.Debugf("[auth-prov-v2-prtb] No provisioning cluster found for cluster %v, enqueuing PRTB %v ", clusterName, prtb.Name) + h.projectRoleTemplateBindingController.EnqueueAfter(prtb.Namespace, prtb.Name, 10*time.Second) + return prtb, nil + } + + cluster := clusters[0] + + err = h.ensureClusterViewBinding(cluster, prtb) + + return prtb, err +} + +func (h *handler) ensureClusterViewBinding(cluster *v1.Cluster, prtb *v3.ProjectRoleTemplateBinding) error { + subject, err := rbac.BuildSubjectFromRTB(prtb) + if err != nil { + return err + } + + // The roleBinding name format: r-cluster--view--- + // Example: r-cluster1-view-prtb-bar-foo-wn5d5n7udr + roleBinding := &rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(clusterViewName(cluster), prtb.Namespace, prtb.Name, hashSubject(subject)), + Namespace: cluster.Namespace, + Annotations: map[string]string{clusterNameLabel: cluster.GetName(), clusterNamespaceLabel: cluster.GetNamespace()}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: cluster.APIVersion, + Kind: cluster.Kind, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "Role", + Name: clusterViewName(cluster), + }, + } + + roleBinding.Subjects = []rbacv1.Subject{subject} + + return h.roleBindingApply. + WithListerNamespace(cluster.Namespace). + WithSetID(PRTBRoleBindingID). + WithOwner(prtb). + ApplyObjects(roleBinding) +} + +func clusterViewName(cluster *v1.Cluster) string { + return name.SafeConcatName("r-cluster", cluster.Name, "view") +} + +func hashSubject(subject rbacv1.Subject) string { + h := sha256.New() + h.Write([]byte(subject.String())) + return strings.ToLower(base32.StdEncoding.WithPadding(-1).EncodeToString(h.Sum(nil))[:10]) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role.go new file mode 100644 index 0000000..dd55aa9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role.go @@ -0,0 +1,434 @@ +package authprovisioningv2 + +import ( + "fmt" + "sort" + "strings" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/rbac" + apiextcontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/name" + rbacv1 "k8s.io/api/rbac/v1" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + clusterIndexed = "clusterIndexed" + clusterIndexedLabel = "auth.cattle.io/cluster-indexed" + clusterNameLabel = "cluster.cattle.io/name" + clusterNamespaceLabel = "cluster.cattle.io/namespace" + reenqueueTime = time.Second * 5 +) + +func (h *handler) initializeCRDs(crdClient apiextcontrollers.CustomResourceDefinitionClient) error { + crds, err := crdClient.List(metav1.ListOptions{ + LabelSelector: clusterIndexedLabel + "=true", + }) + if err != nil { + return err + } + + for _, crd := range crds.Items { + match := crdToResourceMatch(&crd) + if match == nil { + continue + } + h.modifyResources(*match, true) + } + + return nil +} + +func crdToResourceMatch(crd *apiextv1.CustomResourceDefinition) *resourceMatch { + if crd.Status.AcceptedNames.Kind == "" || len(crd.Spec.Versions) == 0 { + return nil + } + + version := crd.Spec.Versions[0] + + for _, ver := range crd.Spec.Versions { + if !ver.Deprecated { + version = ver + break + } + } + + gvk := schema.GroupVersionKind{ + Group: crd.Spec.Group, + Version: version.Name, + Kind: crd.Status.AcceptedNames.Kind, + } + + return &resourceMatch{ + GVK: gvk, + Resource: crd.Status.AcceptedNames.Plural, + } +} + +func (h *handler) gvkMatcher(gvk schema.GroupVersionKind) bool { + h.resourcesLock.RLock() + defer h.resourcesLock.RUnlock() + _, ok := h.resources[gvk] + return ok +} + +func (h *handler) modifyResources(resource resourceMatch, addResource bool) { + h.resourcesLock.Lock() + defer h.resourcesLock.Unlock() + _, resourceExists := h.resources[resource.GVK] + if addResource && !resourceExists { + h.resources[resource.GVK] = resource + } else if !addResource && resourceExists { + delete(h.resources, resource.GVK) + } else { + return + } + + resources := make([]resourceMatch, 0, len(h.resources)) + for _, v := range h.resources { + resources = append(resources, v) + } + sort.Slice(resources, func(i, j int) bool { + return resources[i].GVK.String() < resources[j].GVK.String() + }) + h.resourcesList = resources +} + +func (h *handler) OnCRD(key string, crd *apiextv1.CustomResourceDefinition) (*apiextv1.CustomResourceDefinition, error) { + if crd == nil || crd.Labels[clusterIndexedLabel] != "true" { + return crd, nil + } + + if resourceMatch := crdToResourceMatch(crd); resourceMatch != nil { + h.modifyResources(*resourceMatch, crd.DeletionTimestamp.IsZero()) + } + + return crd, nil +} + +func (h *handler) OnClusterObjectChanged(obj runtime.Object) (runtime.Object, error) { + clusterNames, err := getObjectClusterNames(obj) + if err != nil { + return nil, err + } + objMeta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + for _, clusterName := range clusterNames { + h.roleTemplateController.Enqueue(fmt.Sprintf("cluster/%s/%s", objMeta.GetNamespace(), clusterName)) + } + return obj, nil +} + +func (h *handler) OnChange(key string, rt *v3.RoleTemplate) (*v3.RoleTemplate, error) { + if rt != nil { + if rt.DeletionTimestamp != nil { + return rt, nil + } + return rt, h.objects(rt, true, nil) + } + + if strings.HasPrefix(key, "cluster/") { + parts := strings.Split(key, "/") + if len(parts) != 3 { + return rt, nil + } + + cluster, err := h.clusters.Get(parts[1], parts[2]) + if apierror.IsNotFound(err) { + // ignore not found + return rt, nil + } else if err != nil { + return rt, err + } + + rts, err := h.roleTemplatesCache.List(labels.Everything()) + if err != nil { + return rt, err + } + for _, rt := range rts { + if err := h.objects(rt, false, cluster); err != nil { + return nil, err + } + } + } + + return rt, nil +} + +func (h *handler) hasAnnotationsForDeletingCluster(annotations map[string]string, isClusterRole bool) (bool, error) { + clusterName, cOK := annotations[clusterNameLabel] + clusterNamespace, cnOK := annotations[clusterNamespaceLabel] + if !cOK || (!cnOK && !isClusterRole) { + // if this role doesn't have a clustername/namespace label it isn't one of the protected roles, so move on + return false, nil + } + + mgmtCluster, err := h.mgmtClusters.Get(clusterName) + if err != nil { + if !apierror.IsNotFound(err) { + return false, err + } + // if management cluster was not found, ensure it's nil + mgmtCluster = nil + } + + cluster, err := h.clusters.Get(clusterNamespace, clusterName) + if err != nil { + if !apierror.IsNotFound(err) { + return false, err + } + // if cluster was not found, ensure cluster is nil + cluster = nil + } + + if (cluster != nil && cluster.DeletionTimestamp != nil) || (mgmtCluster != nil && mgmtCluster.DeletionTimestamp != nil) { + // if the cluster is being deleted + return true, nil + } + + return false, nil +} + +func (h *handler) OnRemoveRole(key string, role *rbacv1.Role) (*rbacv1.Role, error) { + shouldEnqueue, err := h.hasAnnotationsForDeletingCluster(role.Annotations, false) + if err != nil { + return role, err + } + if !shouldEnqueue { + return role, nil + } + // Enqueue to ensure perms remain until full delete. Err skips don't re-enqueue, so we do that manually + h.roleController.EnqueueAfter(role.Namespace, role.Name, reenqueueTime) + return role, generic.ErrSkip +} + +func (h *handler) OnRemoveRoleBinding(key string, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) { + shouldEnqueue, err := h.hasAnnotationsForDeletingCluster(roleBinding.Annotations, false) + if err != nil { + return roleBinding, err + } + if !shouldEnqueue { + return roleBinding, nil + } + // Enqueue to ensure perms remain until full delete. Err skips don't re-enqueue, so we do that manually + h.roleBindingController.EnqueueAfter(roleBinding.Namespace, roleBinding.Name, reenqueueTime) + return roleBinding, generic.ErrSkip +} + +func (h *handler) OnRemoveClusterRole(key string, role *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + shouldEnqueue, err := h.hasAnnotationsForDeletingCluster(role.Annotations, true) + if err != nil { + return role, err + } + if !shouldEnqueue { + return role, nil + } + // Enqueue to ensure perms remain until full delete. Err skips don't re-enqueue, so we do that manually + h.clusterRoleController.EnqueueAfter(role.Name, reenqueueTime) + return role, generic.ErrSkip +} + +func (h *handler) OnRemoveClusterRoleBinding(key string, roleBinding *rbacv1.ClusterRoleBinding) (*rbacv1.ClusterRoleBinding, error) { + shouldEnqueue, err := h.hasAnnotationsForDeletingCluster(roleBinding.Annotations, true) + if err != nil { + return roleBinding, err + } + if !shouldEnqueue { + return roleBinding, nil + } + // Enqueue to ensure perms remain until full delete. Err skips don't re-enqueue, so we do that manually + h.clusterRoleBindingController.EnqueueAfter(roleBinding.Name, reenqueueTime) + return roleBinding, generic.ErrSkip +} + +func (h *handler) objects(rt *v3.RoleTemplate, enqueue bool, cluster *v1.Cluster) error { + var ( + matchResults []match + ) + + if rt.Context != "cluster" { + return nil + } + + rules, err := rbac.RulesFromTemplate(h.clusterRoleCache, h.roleTemplatesCache, rt) + if err != nil { + return err + } + + for _, rule := range rules { + if len(rule.NonResourceURLs) > 0 || len(rule.ResourceNames) > 0 { + continue + } + matches, err := h.getMatchingClusterIndexedTypes(rule) + if err != nil { + return err + } + for _, matched := range matches { + matchResults = append(matchResults, match{ + Rule: rbacv1.PolicyRule{ + Verbs: rule.Verbs, + APIGroups: []string{matched.GVK.Group}, + Resources: []string{matched.Resource}, + }, + Match: matched, + }) + } + } + + if len(matchResults) == 0 { + return nil + } + + if enqueue { + crtbs, err := h.clusterRoleTemplateBindings.GetByIndex(crbtByRoleTemplateName, rt.Name) + if err != nil { + return err + } + for _, crtb := range crtbs { + h.clusterRoleTemplateBindingController.Enqueue(crtb.Namespace, crtb.Name) + } + } + + var clusters []*v1.Cluster + if cluster == nil { + var err error + clusters, err = h.clusters.List("", labels.Everything()) + if err != nil { + return err + } + } else { + clusters = []*v1.Cluster{cluster} + } + + for _, cluster := range clusters { + err := h.createRoleForCluster(rt, matchResults, cluster) + if err != nil { + return err + } + } + + return nil +} + +func (h *handler) getResourceNames(resourceMatch resourceMatch, cluster *v1.Cluster) ([]string, error) { + objs, err := h.dynamic.GetByIndex(resourceMatch.GVK, clusterIndexed, fmt.Sprintf("%s/%s", cluster.Namespace, cluster.Name)) + if err != nil { + return nil, err + } + result := make([]string, 0, len(objs)) + for _, obj := range objs { + objMeta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + result = append(result, objMeta.GetName()) + } + return result, nil +} + +func roleTemplateRoleName(rtName, clusterName string) string { + return name.SafeConcatName("crt", clusterName, rtName) +} + +func (h *handler) createRoleForCluster(rt *v3.RoleTemplate, matches []match, cluster *v1.Cluster) error { + h.roleLocker.Lock(cluster.Namespace + "/" + cluster.Name) + defer h.roleLocker.Unlock(cluster.Namespace + "/" + cluster.Name) + + role := rbacv1.Role{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: roleTemplateRoleName(rt.Name, cluster.Name), + Namespace: cluster.Namespace, + Annotations: map[string]string{clusterNameLabel: cluster.GetName(), clusterNamespaceLabel: cluster.GetNamespace()}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: cluster.APIVersion, + Kind: cluster.Kind, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + } + + for _, match := range matches { + names, err := h.getResourceNames(match.Match, cluster) + if err != nil { + return err + } + if len(names) == 0 { + continue + } + role.Rules = append(role.Rules, rbacv1.PolicyRule{ + Verbs: match.Rule.Verbs, + APIGroups: match.Rule.APIGroups, + Resources: match.Rule.Resources, + ResourceNames: names, + }) + } + + return h.apply. + WithListerNamespace(role.Namespace). + WithSetID("auth-prov-v2-roletemplate" + "-" + cluster.Name). + WithOwner(rt). + ApplyObjects(&role) +} + +type match struct { + Rule rbacv1.PolicyRule + Match resourceMatch +} + +type resourceMatch struct { + GVK schema.GroupVersionKind + Resource string +} + +func (r *resourceMatch) Matches(rule rbacv1.PolicyRule) bool { + return r.matchesGroup(rule) && r.matchesResource(rule) +} + +func (r *resourceMatch) matchesGroup(rule rbacv1.PolicyRule) bool { + for _, group := range rule.APIGroups { + if group == "*" || group == r.GVK.Group { + return true + } + } + return false +} + +func (r *resourceMatch) matchesResource(rule rbacv1.PolicyRule) bool { + for _, resource := range rule.Resources { + if resource == "*" || resource == r.Resource { + return true + } + } + return false +} + +func (h *handler) candidateTypes() []resourceMatch { + h.resourcesLock.RLock() + defer h.resourcesLock.RUnlock() + return h.resourcesList +} + +func (h *handler) getMatchingClusterIndexedTypes(rule rbacv1.PolicyRule) (result []resourceMatch, _ error) { + for _, candidate := range h.candidateTypes() { + if candidate.Matches(rule) { + result = append(result, candidate) + } + } + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role_test.go new file mode 100644 index 0000000..8436e96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/authprovisioningv2/role_test.go @@ -0,0 +1,357 @@ +package authprovisioningv2 + +import ( + "errors" + "testing" + + "github.com/golang/mock/gomock" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + apisv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/api/rbac/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + clusterDeletingAnnotationLabel = "deleting" + clusterDeletedAnnotationLabel = "deleted" + genericAnnotationLabel = "clusternamespace" + clusterErrorAnnotationLabel = "other error" + noAnnotation = map[string]string{} +) + +func Test_handler_hasClusterAnnotationsAndDeletionTimestamp(t *testing.T) { + funcName := "handler.hasClusterAnnotationsAndDeletionTimestamp()" + + tests := []struct { + name string + annotations map[string]string + wantErr bool + want bool + }{ + // Enqueued (returned generic.ErrSkip) + { + name: "Cluster not deleted, should requeue", + annotations: createNameAndNamespaceAnnotation(clusterDeletingAnnotationLabel), + wantErr: false, + want: true, + }, + // Other cluster error (clusters.get return err other than IsNotFound) + { + name: "Cluster cache returned unexpected error", + annotations: createNameAndNamespaceAnnotation(clusterErrorAnnotationLabel), + wantErr: true, + want: false, + }, + // cluster is not found (clusters.get returns IsNotFound err) + { + name: "Cluster deleted, can delete", + annotations: createNameAndNamespaceAnnotation(clusterDeletedAnnotationLabel), + wantErr: false, + want: false, + }, + // non-cluster deletion (cluster has no DeletionTimestamp) + { + name: "Other removal reason, can delete", + annotations: createNameAndNamespaceAnnotation(genericAnnotationLabel), + wantErr: false, + want: false, + }, + // no annotations + { + name: "non-annotated, can delete", + annotations: noAnnotation, + wantErr: false, + want: false, + }, + } + isClusterArg := true + for i := 0; i < 2; i++ { + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // first returned value is always the same role object as the role argument + enqueue, err := simpleHandler(t).hasAnnotationsForDeletingCluster(tt.annotations, isClusterArg) + if enqueue != tt.want { + t.Errorf("%v returned %v, wanted %v", funcName, enqueue, tt.want) + } + if err == nil && tt.wantErr { + t.Errorf("%v got nil error, wanted %v", funcName, tt.want) + return + } + if err != nil && !tt.wantErr { + t.Errorf("%v got error = %v, but wanted none", funcName, err) + return + } + if err != nil && tt.wantErr { + if tt.want && err != generic.ErrSkip { + t.Errorf("%v wanted ErrSkip, got err = %v", funcName, err) + } + } + }) + } + isClusterArg = !isClusterArg + } +} + +func Test_OnRemoveRole(t *testing.T) { + funcName := "OnRemoveRole()" + tests := []struct { + name string + role *v1.Role + wantEnqueue bool + wantErr bool + }{ + { + name: "Want enqueue", + role: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAndNamespaceAnnotation(clusterDeletingAnnotationLabel), + }, + }, + wantEnqueue: true, + wantErr: false, + }, + { + name: "Want no error", + role: &v1.Role{}, + wantEnqueue: false, + wantErr: false, + }, + { + name: "Want error", + role: &v1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAndNamespaceAnnotation(clusterErrorAnnotationLabel), + }, + }, + wantEnqueue: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := simpleHandler(t).OnRemoveRole("", tt.role) + if tt.wantEnqueue && err != generic.ErrSkip { + t.Errorf("%v wanted enqueue, got err = %v", funcName, err) + return + } + if err != nil && !tt.wantEnqueue && !tt.wantErr { + t.Errorf("%v wanted no error, got err = %v", funcName, err) + } + }) + } +} + +func Test_OnRemoveRoleBinding(t *testing.T) { + funcName := "OnRemoveRoleBinding()" + tests := []struct { + name string + role *v1.RoleBinding + wantEnqueue bool + wantErr bool + }{ + { + name: "Want enqueue", + role: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAndNamespaceAnnotation(clusterDeletingAnnotationLabel), + }, + }, + wantEnqueue: true, + wantErr: false, + }, + { + name: "Want no error", + role: &v1.RoleBinding{}, + wantEnqueue: false, + wantErr: false, + }, + { + name: "Want error", + role: &v1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAndNamespaceAnnotation(clusterErrorAnnotationLabel), + }, + }, + wantEnqueue: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := simpleHandler(t).OnRemoveRoleBinding("", tt.role) + if tt.wantEnqueue && err != generic.ErrSkip { + t.Errorf("%v wanted enqueue, got err = %v", funcName, err) + return + } + if err != nil && !tt.wantEnqueue && !tt.wantErr { + t.Errorf("%v wanted no error, got err = %v", funcName, err) + } + }) + } +} + +func Test_OnRemoveClusterRole(t *testing.T) { + funcName := "OnRemoveClusterRole()" + tests := []struct { + name string + role *v1.ClusterRole + wantEnqueue bool + wantErr bool + }{ + { + name: "Want enqueue", + role: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAnnotation(clusterDeletingAnnotationLabel), + }, + }, + wantEnqueue: true, + wantErr: false, + }, + { + name: "Want no error", + role: &v1.ClusterRole{}, + wantEnqueue: false, + wantErr: false, + }, + { + name: "Want error", + role: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAnnotation(clusterErrorAnnotationLabel), + }, + }, + wantEnqueue: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := simpleHandler(t).OnRemoveClusterRole("", tt.role) + if tt.wantEnqueue && err != generic.ErrSkip { + t.Errorf("%v wanted enqueue, got err = %v", funcName, err) + return + } + if err != nil && !tt.wantEnqueue && !tt.wantErr { + t.Errorf("%v wanted no error, got err = %v", funcName, err) + } + }) + } +} + +func Test_OnRemoveClusterRoleBinding(t *testing.T) { + funcName := "OnRemoveClusterRoleBinding()" + tests := []struct { + name string + role *v1.ClusterRoleBinding + wantEnqueue bool + wantErr bool + }{ + { + name: "Want enqueue", + role: &v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAnnotation(clusterDeletingAnnotationLabel), + }, + }, + wantEnqueue: true, + wantErr: false, + }, + { + name: "Want no error", + role: &v1.ClusterRoleBinding{}, + wantEnqueue: false, + wantErr: false, + }, + { + name: "Want error", + role: &v1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: createNameAnnotation(clusterErrorAnnotationLabel), + }, + }, + wantEnqueue: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := simpleHandler(t).OnRemoveClusterRoleBinding("", tt.role) + if tt.wantEnqueue && err != generic.ErrSkip { + t.Errorf("%v wanted enqueue, got err = %v", funcName, err) + return + } + if err != nil && !tt.wantEnqueue && !tt.wantErr { + t.Errorf("%v wanted no error, got err = %v", funcName, err) + } + }) + } +} + +func createNameAndNamespaceAnnotation(n string) map[string]string { + return map[string]string{clusterNameLabel: n, clusterNamespaceLabel: n} +} + +func createNameAnnotation(n string) map[string]string { + return map[string]string{clusterNameLabel: n} +} + +func simpleHandler(t *testing.T) *handler { + t.Helper() + ctrl := gomock.NewController(t) + + mockRoleController := fake.NewMockControllerInterface[*rbacv1.Role, *rbacv1.RoleList](ctrl) + mockRoleController.EXPECT().EnqueueAfter(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + mockRoleBindingController := fake.NewMockControllerInterface[*rbacv1.RoleBinding, *rbacv1.RoleBindingList](ctrl) + mockRoleBindingController.EXPECT().EnqueueAfter(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + mockCluster := fake.NewMockCacheInterface[*apisv1.Cluster](ctrl) + mockCluster.EXPECT().Get("deleted", gomock.Any()).Return(nil, apierror.NewNotFound(schema.GroupResource{}, "deleted")).AnyTimes() + mockCluster.EXPECT().Get("deleting", gomock.Any()).Return(newDeletingCuster(), nil).AnyTimes() + mockCluster.EXPECT().Get("other error", gomock.Any()).Return(nil, errors.New("other error")).AnyTimes() + mockCluster.EXPECT().Get(gomock.Any(), gomock.Any()).Return(&provisioningv1.Cluster{}, nil).AnyTimes() + + mockMgmtCluster := fake.NewMockNonNamespacedCacheInterface[*apisv3.Cluster](ctrl) + mockMgmtCluster.EXPECT().Get("deleted").Return(nil, apierror.NewNotFound(schema.GroupResource{}, "deleted")).AnyTimes() + mockMgmtCluster.EXPECT().Get("deleting").Return(newDeletingMgmtCuster(), nil).AnyTimes() + mockMgmtCluster.EXPECT().Get("other error").Return(nil, errors.New("other error")).AnyTimes() + mockMgmtCluster.EXPECT().Get(gomock.Any()).Return(&v3.Cluster{}, nil).AnyTimes() + + mockClusterRoleController := fake.NewMockNonNamespacedControllerInterface[*rbacv1.ClusterRole, *rbacv1.ClusterRoleList](ctrl) + mockClusterRoleController.EXPECT().EnqueueAfter(gomock.Any(), gomock.Any()).AnyTimes() + + mockClusterRoleBindingController := fake.NewMockNonNamespacedControllerInterface[*rbacv1.ClusterRoleBinding, *rbacv1.ClusterRoleBindingList](ctrl) + mockClusterRoleBindingController.EXPECT().EnqueueAfter(gomock.Any(), gomock.Any()).AnyTimes() + + return &handler{ + roleController: mockRoleController, + roleBindingController: mockRoleBindingController, + clusters: mockCluster, + mgmtClusters: mockMgmtCluster, + clusterRoleController: mockClusterRoleController, + clusterRoleBindingController: mockClusterRoleBindingController, + } + +} +func newDeletingCuster() *provisioningv1.Cluster { + c := &provisioningv1.Cluster{} + c.DeletionTimestamp = &metav1.Time{} + return c +} +func newDeletingMgmtCuster() *v3.Cluster { + c := &v3.Cluster{} + c.DeletionTimestamp = &metav1.Time{} + return c +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/certsexpiration/certsexpiration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/certsexpiration/certsexpiration.go new file mode 100644 index 0000000..2f9397d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/certsexpiration/certsexpiration.go @@ -0,0 +1,85 @@ +package certsexpiration + +import ( + "context" + "reflect" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/client-go/kubernetes" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rkecerts" + "github.com/rancher/rancher/pkg/types/config" + rkeCluster "github.com/rancher/rke/cluster" + "github.com/sirupsen/logrus" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +// This controller handles cert expiration for local cluster only +func Register(ctx context.Context, management *config.ManagementContext) { + c := &certsExpiration{ + clusters: management.Management.Clusters(""), + k8sClient: management.K8sClient, + } + management.Management.Clusters("").AddHandler(ctx, "certificate-expiration", c.sync) +} + +type certsExpiration struct { + clusters v3.ClusterInterface + k8sClient kubernetes.Interface +} + +func (c *certsExpiration) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster == nil || cluster.Name != "local" { + return cluster, nil // We are only checking local cluster + } + fullState, err := rkeCluster.GetFullStateFromK8s(context.Background(), c.k8sClient) + if err != nil { + if k8sErrors.IsNotFound(err) { + return cluster, nil // not an rke cluster, nothing we can do + } + return cluster, err + } + + certBundle := fullState.CurrentState.CertificatesBundle + if err != nil { + return cluster, err + } + rkecerts.CleanCertificateBundle(certBundle) + + certsExpInfo := map[string]v32.CertExpiration{} + for certName, certObj := range certBundle { + info, err := rkecerts.GetCertExpiration(certObj.CertificatePEM) + if err != nil { + logrus.Debugf("failed to get expiration date for certificate [%s] for local cluster: %v", certName, err) + continue + } + certsExpInfo[certName] = info + err = logCertExpirationWarning(certName, info) + if err != nil { + logrus.Warnf("certificate [%s] from local cluster has or will expire and date is corrupted: %v", certName, err) + continue + } + } + // Update certExpiration on cluster obj in order for it to display in API, and the UI if expiring + if !reflect.DeepEqual(cluster.Status.CertificatesExpiration, certsExpInfo) { + cluster.Status.CertificatesExpiration = certsExpInfo + return c.clusters.Update(cluster) + } + return cluster, nil +} + +func logCertExpirationWarning(name string, certExp v32.CertExpiration) error { + date, err := time.Parse(time.RFC3339, certExp.ExpirationDate) + if err != nil { + return err + } + if time.Now().UTC().After(date) { // warn if expired + logrus.Warnf("Certificate from local cluster has expired: %s", name) + } else if time.Now().UTC().AddDate(0, 1, 0).After(date) { // warn if within a month + logrus.Warnf("Certificate from local cluster will expire soon: %s", name) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cloudcredential/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cloudcredential/controller.go new file mode 100644 index 0000000..0416242 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cloudcredential/controller.go @@ -0,0 +1,62 @@ +package cloudcredential + +import ( + "context" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/rancher/pkg/controllers/management/rbac" + typesv1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" +) + +type Controller struct { + managementContext *config.ManagementContext +} + +func Register(ctx context.Context, management *config.ManagementContext) { + m := Controller{ + managementContext: management, + } + management.Core.Secrets("").AddHandler(ctx, "management-cloudcredential-controller", m.ccSync) +} + +func (n *Controller) ccSync(key string, cloudCredential *v1.Secret) (runtime.Object, error) { + if cloudCredential == nil || cloudCredential.DeletionTimestamp != nil { + return cloudCredential, nil + } + if !configExists(cloudCredential.Data) { + return cloudCredential, nil + } + metaAccessor, err := meta.Accessor(cloudCredential) + if err != nil { + return cloudCredential, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return cloudCredential, fmt.Errorf("cloud credential %v has no creatorId annotation", cloudCredential.Name) + } + if err := rbac.CreateRoleAndRoleBinding( + rbac.CloudCredentialResource, typesv1.SecretResource.Kind, cloudCredential.Name, namespace.GlobalNamespace, "v1", creatorID, []string{"*"}, cloudCredential.UID, []v32.Member{}, + n.managementContext); err != nil { + return nil, err + } + + return cloudCredential, nil +} + +func configExists(data map[string][]byte) bool { + for key := range data { + splitKey := strings.Split(key, "-") + if len(splitKey) == 2 && strings.HasSuffix(splitKey[0], "Config") { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller.go new file mode 100644 index 0000000..035c72e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller.go @@ -0,0 +1,270 @@ +package cluster + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "strconv" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rketypes "github.com/rancher/rke/types" + + errorsutil "github.com/pkg/errors" + normantypes "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rancher/pkg/kontainer-engine/types" + managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rke/cloudprovider/aws" + "github.com/rancher/rke/cloudprovider/azure" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + GoogleCloudLoadBalancer = "GCLB" + ElasticLoadBalancer = "ELB" + AzureL4LB = "Azure L4 LB" + NginxIngressProvider = "Nginx" + DefaultNodePortRange = "30000-32767" + capabilitiesAnnotation = "capabilities/" +) + +type controller struct { + clusterClient v3.ClusterInterface + nodeLister v3.NodeLister + kontainerDriverLister v3.KontainerDriverLister + namespaces v1.NamespaceInterface + coreV1 v1.Interface + capabilitiesSchema *normantypes.Schema +} + +func Register(ctx context.Context, management *config.ManagementContext) { + c := controller{ + clusterClient: management.Management.Clusters(""), + nodeLister: management.Management.Nodes("").Controller().Lister(), + kontainerDriverLister: management.Management.KontainerDrivers("").Controller().Lister(), + namespaces: management.Core.Namespaces(""), + coreV1: management.Core, + capabilitiesSchema: management.Schemas.Schema(&managementschema.Version, client.CapabilitiesType).InternalSchema, + } + + c.clusterClient.AddHandler(ctx, "clusterCreateUpdate", c.capsSync) +} + +func (c *controller) capsSync(key string, cluster *v3.Cluster) (runtime.Object, error) { + var err error + if cluster == nil || cluster.DeletionTimestamp != nil { + return nil, nil + } + + if cluster.Spec.ImportedConfig != nil { + return nil, nil + } + capabilities := v32.Capabilities{} + + if cluster.Spec.RancherKubernetesEngineConfig != nil { + capabilities.NodePortRange = DefaultNodePortRange + // taint support capability is set in provisioner and update cluster is called, so we should retain the capability here + if cluster.Status.Capabilities.TaintSupport != nil && *cluster.Status.Capabilities.TaintSupport { + supportsTaints := true + capabilities.TaintSupport = &supportsTaints + } + if capabilities, err = c.RKECapabilities(capabilities, *cluster.Spec.RancherKubernetesEngineConfig, cluster.Name); err != nil { + return nil, err + } + } else if cluster.Spec.GenericEngineConfig != nil { + capabilities.NodePortRange = DefaultNodePortRange + driverName, ok := (*cluster.Spec.GenericEngineConfig)["driverName"].(string) + if !ok { + logrus.Warnf("cluster %v had generic engine config but no driver name, k8s capabilities will "+ + "not be populated correctly", key) + return nil, nil + } + + kontainerDriver, err := c.kontainerDriverLister.Get("", driverName) + if err != nil { + if !errors.IsNotFound(err) { + return nil, errorsutil.WithMessage(err, fmt.Sprintf("error getting kontainer driver: %v", driverName)) + } + //do not return not found errors since the driver may have been deleted + return nil, nil + } + + driver := service.NewEngineService( + clusterprovisioner.NewPersistentStore(c.namespaces, c.coreV1), + ) + k8sCapabilities, err := driver.GetK8sCapabilities(context.Background(), kontainerDriver.Name, kontainerDriver, + cluster.Spec) + if err != nil { + return nil, fmt.Errorf("error getting k8s capabilities: %v", err) + } + + capabilities = toCapabilities(k8sCapabilities) + } + + capabilities, err = c.overrideCapabilities(cluster.Annotations, capabilities) + if err != nil { + return nil, err + } + + if !reflect.DeepEqual(capabilities, cluster.Status.Capabilities) { + toUpdateCluster := cluster.DeepCopy() + toUpdateCluster.Status.Capabilities = capabilities + if _, err := c.clusterClient.Update(toUpdateCluster); err != nil { + return nil, err + } + return toUpdateCluster, nil + } + + return nil, nil +} + +// overrideCapabilities masks the given Capabilities struct with values extracted from annotations prefixed with +// "capabilities.cattle.io/" +func (c *controller) overrideCapabilities(annotations map[string]string, oldCapabilities v32.Capabilities) (v32.Capabilities, error) { + capabilities := v32.Capabilities{} + + capabilitiesMap, err := convert.EncodeToMap(oldCapabilities) + if err != nil { + return capabilities, err + } + + var isUpdate bool + for annoKey, annoValue := range annotations { + if strings.HasPrefix(annoKey, capabilitiesAnnotation) { + capability := strings.TrimPrefix(annoKey, capabilitiesAnnotation) + val, err := c.parseResourceInterface(capability, annoValue) + if err != nil { + return capabilities, err + } + capabilitiesMap[capability] = val + isUpdate = true + } + + } + + if isUpdate { + if err := convert.ToObj(capabilitiesMap, &capabilities); err != nil { + return capabilities, err + } + return capabilities, nil + } + + return oldCapabilities, nil +} + +// parseResourceInterface converts a capability annotation to the appropriate type based on given schema. +// Json format is assumed if type is not bool, string, or integer. +func (c *controller) parseResourceInterface(key string, annoValue string) (interface{}, error) { + resourceField, ok := c.capabilitiesSchema.ResourceFields[key] + if resourceField.Nullable && annoValue == "" { + return nil, nil + } + + if !ok { + return nil, fmt.Errorf("resource field [%s] from capabillities annotation not found", key) + } + + fieldType := c.capabilitiesSchema.ResourceFields[key].Type + switch fieldType { + case "string": + return annoValue, nil + case "boolean": + return strconv.ParseBool(annoValue) + case "integer": + return strconv.Atoi(annoValue) + default: + var result interface{} + + err := json.Unmarshal([]byte(annoValue), &result) + if err != nil { + return nil, err + } + return result, nil + } +} + +func (c *controller) RKECapabilities(capabilities v32.Capabilities, rkeConfig rketypes.RancherKubernetesEngineConfig, clusterName string) (v32.Capabilities, error) { + switch rkeConfig.CloudProvider.Name { + case aws.AWSCloudProviderName: + capabilities.LoadBalancerCapabilities = c.L4Capability(true, ElasticLoadBalancer, []string{"TCP"}, true) + case azure.AzureCloudProviderName: + capabilities.LoadBalancerCapabilities = c.L4Capability(true, AzureL4LB, []string{"TCP", "UDP"}, true) + } + // only if not custom, non custom clusters have nodepools set + nodes, err := c.nodeLister.List(clusterName, labels.Everything()) + if err != nil { + return capabilities, err + } + + if len(nodes) > 0 { + if nodes[0].Spec.NodePoolName != "" { + capabilities.NodePoolScalingSupported = true + } + } + + ingressController := c.IngressCapability(true, rkeConfig.Ingress.Provider) + capabilities.IngressCapabilities = []v32.IngressCapabilities{ingressController} + if rkeConfig.Services.KubeAPI.ServiceNodePortRange != "" { + capabilities.NodePortRange = rkeConfig.Services.KubeAPI.ServiceNodePortRange + } else if rkeConfig.Services.KubeAPI.ExtraArgs["service-node-port-range"] != "" { + capabilities.NodePortRange = rkeConfig.Services.KubeAPI.ExtraArgs["service-node-port-range"] + } + + return capabilities, nil +} + +func (c *controller) L4Capability(enabled bool, providerName string, protocols []string, healthCheck bool) v32.LoadBalancerCapabilities { + l4lb := v32.LoadBalancerCapabilities{ + Enabled: &enabled, + Provider: providerName, + ProtocolsSupported: protocols, + HealthCheckSupported: healthCheck, + } + return l4lb +} + +func (c *controller) IngressCapability(httpLBEnabled bool, providerName string) v32.IngressCapabilities { + customDefaultBackendDisabled := false + ing := v32.IngressCapabilities{ + IngressProvider: providerName, + } + if strings.EqualFold(providerName, NginxIngressProvider) { + ing.CustomDefaultBackend = &customDefaultBackendDisabled + } + return ing +} + +func toCapabilities(k8sCapabilities *types.K8SCapabilities) v32.Capabilities { + var controllers []v32.IngressCapabilities + + for _, controller := range k8sCapabilities.IngressControllers { + controllers = append(controllers, v32.IngressCapabilities{ + CustomDefaultBackend: &controller.CustomDefaultBackend, + IngressProvider: controller.IngressProvider, + }) + } + + return v32.Capabilities{ + IngressCapabilities: controllers, + LoadBalancerCapabilities: v32.LoadBalancerCapabilities{ + Enabled: &k8sCapabilities.L4LoadBalancer.Enabled, + HealthCheckSupported: k8sCapabilities.L4LoadBalancer.HealthCheckSupported, + ProtocolsSupported: k8sCapabilities.L4LoadBalancer.ProtocolsSupported, + Provider: k8sCapabilities.L4LoadBalancer.Provider, + }, + NodePoolScalingSupported: k8sCapabilities.NodePoolScalingSupported, + NodePortRange: k8sCapabilities.NodePortRange, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller_test.go new file mode 100644 index 0000000..5f55619 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/clustercontroller_test.go @@ -0,0 +1,197 @@ +package cluster + +import ( + "fmt" + "reflect" + "testing" + + "github.com/rancher/norman/types" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/rancher/rke/cloudprovider/aws" + "github.com/rancher/rke/cloudprovider/azure" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/utils/pointer" +) + +const testServiceNodePortRange = "10000-32769" + +func initializeController() *controller { + c := controller{ + nodeLister: &fakes.NodeListerMock{ + ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Node, error) { + return []*v3.Node{}, nil + }, + }, + } + return &c +} + +func TestSetNodePortRange(t *testing.T) { + c := initializeController() + testCluster := v3.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCluster", + }, + } + testCluster.Spec.RancherKubernetesEngineConfig = &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + KubeAPI: rketypes.KubeAPIService{ + ServiceNodePortRange: testServiceNodePortRange, + }, + }, + } + caps := v32.Capabilities{} + caps, err := c.RKECapabilities(caps, *testCluster.Spec.RancherKubernetesEngineConfig, testCluster.Name) + assert.Nil(t, err) + assert.Equal(t, testServiceNodePortRange, caps.NodePortRange) +} + +func TestLoadBalancerCapability(t *testing.T) { + c := initializeController() + lbCap := true + testCluster := v3.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: "testCluster", + }, + } + testCluster.Spec.RancherKubernetesEngineConfig = &rketypes.RancherKubernetesEngineConfig{} + + // map of cloud provider name to expected lb capability + cloudProviderLBCapabilityMap := map[rketypes.CloudProvider]*bool{ + rketypes.CloudProvider{}: nil, + rketypes.CloudProvider{Name: aws.AWSCloudProviderName}: &lbCap, + rketypes.CloudProvider{Name: azure.AzureCloudProviderName}: &lbCap, + } + for cloudProvider, expectedLB := range cloudProviderLBCapabilityMap { + testCluster.Spec.RancherKubernetesEngineConfig.CloudProvider = cloudProvider + caps := v32.Capabilities{} + caps, err := c.RKECapabilities(caps, *testCluster.Spec.RancherKubernetesEngineConfig, testCluster.Name) + assert.Nil(t, err) + assert.Equal(t, expectedLB, caps.LoadBalancerCapabilities.Enabled) + } +} + +func TestIngressCapability(t *testing.T) { + c := initializeController() + rkeSpec := v32.ClusterSpec{ + ClusterSpecBase: v32.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Ingress: rketypes.IngressConfig{ + Provider: NginxIngressProvider, + }, + }, + }, + } + testClusters := []v3.Cluster{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "clusterWithNginx", + }, + Spec: rkeSpec, + }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "clusterWithoutNginx", + }, + Spec: rkeSpec, + }, + } + // don't set nginx as the ingress provider for second cluster + testClusters[1].Spec.RancherKubernetesEngineConfig.Ingress.Provider = "" + + for _, testCluster := range testClusters { + caps := v32.Capabilities{} + caps, err := c.RKECapabilities(caps, *testCluster.Spec.RancherKubernetesEngineConfig, testCluster.Name) + assert.Nil(t, err) + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Ingress.Provider, caps.IngressCapabilities[0].IngressProvider) + } +} + +type capabilitiesTestCase struct { + annotations map[string]string + capabilities v32.Capabilities + result v32.Capabilities + errMsg string +} + +func TestOverrideCapabilities(t *testing.T) { + assert := assert.New(t) + + fakeCapabilitiesSchema := types.Schema{ + ResourceFields: map[string]types.Field{ + "pspEnabled": { + Type: "boolean", + }, + "nodePortRange": { + Type: "string", + }, + "ingressCapabilities": { + Type: "something", + }, + }, + } + tests := []capabilitiesTestCase{ + { + annotations: map[string]string{ + fmt.Sprintf("%s%s", capabilitiesAnnotation, "pspEnabled"): "true", + }, + capabilities: v32.Capabilities{}, + }, + { + annotations: map[string]string{ + fmt.Sprintf("%s%s", capabilitiesAnnotation, "nodePortRange"): "9999", + }, + capabilities: v32.Capabilities{}, + result: v32.Capabilities{ + NodePortRange: "9999", + }, + }, + { + annotations: map[string]string{ + fmt.Sprintf("%s%s", capabilitiesAnnotation, "ingressCapabilities"): "[{\"customDefaultBackend\":true,\"ingressProvider\":\"asdf\"}]", + }, + capabilities: v32.Capabilities{}, + result: v32.Capabilities{ + IngressCapabilities: []v32.IngressCapabilities{ + { + CustomDefaultBackend: pointer.BoolPtr(true), + IngressProvider: "asdf", + }, + }, + }, + }, + { + annotations: map[string]string{ + fmt.Sprintf("%s%s", capabilitiesAnnotation, "notarealcapability"): "something", + }, + capabilities: v32.Capabilities{}, + errMsg: "resource field [notarealcapability] from capabillities annotation not found", + }, + { + annotations: map[string]string{ + fmt.Sprintf("%s%s", capabilitiesAnnotation, "pspEnabled"): "5", + }, + capabilities: v32.Capabilities{}, + errMsg: "strconv.ParseBool: parsing \"5\": invalid syntax", + }, + } + + c := controller{ + capabilitiesSchema: &fakeCapabilitiesSchema, + } + for _, test := range tests { + result, err := c.overrideCapabilities(test.annotations, test.capabilities) + if err != nil { + assert.Equal(test.errMsg, err.Error()) + } else { + assert.True(reflect.DeepEqual(test.result, result)) + } + } + + assert.Nil(nil) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/indexers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/indexers.go new file mode 100644 index 0000000..9dfa283 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/cluster/indexers.go @@ -0,0 +1,30 @@ +package cluster + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +const ByCloudCredential = "byCloudCredential" + +func RegisterIndexers(context *config.ScaledContext) { + context.Wrangler.Mgmt.Cluster().Cache().AddIndexer(ByCloudCredential, byCloudCredentialIndexer) +} + +func byCloudCredentialIndexer(obj *v3.Cluster) ([]string, error) { + switch { + case obj.Spec.EKSConfig != nil: + if obj.Spec.EKSConfig.AmazonCredentialSecret != "" { + return []string{obj.Spec.EKSConfig.AmazonCredentialSecret}, nil + } + case obj.Spec.AKSConfig != nil: + if obj.Spec.AKSConfig.AzureCredentialSecret != "" { + return []string{obj.Spec.AKSConfig.AzureCredentialSecret}, nil + } + case obj.Spec.GKEConfig != nil: + if obj.Spec.GKEConfig.GoogleCredentialSecret != "" { + return []string{obj.Spec.GKEConfig.GoogleCredentialSecret}, nil + } + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconfigcopier/clusterconfigcopier.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconfigcopier/clusterconfigcopier.go new file mode 100644 index 0000000..31a5c0a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconfigcopier/clusterconfigcopier.go @@ -0,0 +1,45 @@ +package clusterconfigcopier + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +type controller struct { +} + +func Register(ctx context.Context, management *config.ManagementContext) { + c := controller{} + + management.Management.Clusters("").AddHandler(ctx, "clusterconfigcopier", c.sync) +} + +func (c *controller) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if key == "" { + return cluster, nil + } + + if cluster.Spec.GenericEngineConfig != nil { + return cluster, nil + } + + if cluster.Spec.AmazonElasticContainerServiceConfig != nil { + cluster.Spec.GenericEngineConfig = cluster.Spec.AmazonElasticContainerServiceConfig + (*cluster.Spec.GenericEngineConfig)["driverName"] = "amazonelasticcontainerservice" + } + + if cluster.Spec.AzureKubernetesServiceConfig != nil { + cluster.Spec.GenericEngineConfig = cluster.Spec.AzureKubernetesServiceConfig + (*cluster.Spec.GenericEngineConfig)["driverName"] = "azurekubernetesservice" + } + + if cluster.Spec.GoogleKubernetesEngineConfig != nil { + cluster.Spec.GenericEngineConfig = cluster.Spec.GoogleKubernetesEngineConfig + (*cluster.Spec.GenericEngineConfig)["driverName"] = "googlekubernetesengine" + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconnected/clusterconnected.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconnected/clusterconnected.go new file mode 100644 index 0000000..fd4a70c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterconnected/clusterconnected.go @@ -0,0 +1,133 @@ +package clusterconnected + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/rancher/rancher/pkg/api/steve/proxy" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/remotedialer" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +var ( + Connected = condition.Cond("Connected") +) + +func Register(ctx context.Context, wrangler *wrangler.Context) { + c := checker{ + clusterCache: wrangler.Mgmt.Cluster().Cache(), + clusters: wrangler.Mgmt.Cluster(), + tunnelServer: wrangler.TunnelServer, + } + + go func() { + for range ticker.Context(ctx, 15*time.Second) { + if err := c.check(); err != nil { + logrus.Errorf("failed to check cluster connectivity: %v", err) + } + } + }() +} + +type checker struct { + clusterCache managementcontrollers.ClusterCache + clusters managementcontrollers.ClusterClient + tunnelServer *remotedialer.Server +} + +func (c *checker) check() error { + clusters, err := c.clusterCache.List(labels.Everything()) + if err != nil { + return err + } + + for _, cluster := range clusters { + if err := c.checkCluster(cluster); err != nil { + logrus.Errorf("failed to check connectivity of cluster [%s]: %v", cluster.Name, err) + } + } + return nil +} + +func (c *checker) hasSession(cluster *v3.Cluster) bool { + clientKey := proxy.Prefix + cluster.Name + hasSession := c.tunnelServer.HasSession(clientKey) + if !hasSession { + return false + } + + dialer := c.tunnelServer.Dialer(clientKey) + transport := &http.Transport{ + DialContext: dialer, + } + defer transport.CloseIdleConnections() + client := &http.Client{ + Transport: transport, + } + resp, err := client.Get("http://not-used/ping") + if err != nil { + return false + } + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + return resp.StatusCode == http.StatusOK +} + +func (c *checker) checkCluster(cluster *v3.Cluster) error { + if cluster.Spec.Internal { + if !Connected.IsTrue(cluster) { + return c.updateClusterConnectedCondition(cluster, true) + } + return nil + } + + hasSession := c.hasSession(cluster) + // The simpler condition of hasSession == Connected.IsTrue(cluster) is not + // used because it treats a non-existent conditions as False + if hasSession && Connected.IsTrue(cluster) { + return nil + } else if !hasSession && Connected.IsFalse(cluster) && v3.ClusterConditionReady.GetReason(cluster) == "Disconnected" { + return nil + } + + return c.updateClusterConnectedCondition(cluster, hasSession) +} + +func (c *checker) updateClusterConnectedCondition(cluster *v3.Cluster, connected bool) error { + if cluster == nil { + return fmt.Errorf("cluster cannot be nil") + } + for i := 0; i < 3; i++ { + cluster = cluster.DeepCopy() + Connected.SetStatusBool(cluster, connected) + if !connected && v3.ClusterConditionProvisioned.IsTrue(cluster) { + v3.ClusterConditionReady.False(cluster) + v3.ClusterConditionReady.Reason(cluster, "Disconnected") + v3.ClusterConditionReady.Message(cluster, "Cluster agent is not connected") + } + logrus.Tracef("[clusterConnectedCondition] update cluster %v", cluster.Name) + _, err := c.clusters.Update(cluster) + if apierror.IsConflict(err) { + cluster, err = c.clusters.Get(cluster.Name, metav1.GetOptions{}) + if err != nil { + return err + } + continue + } + return err + } + return fmt.Errorf("unable to update cluster connected condition") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterdeploy/clusterdeploy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterdeploy/clusterdeploy.go new file mode 100644 index 0000000..fe29cba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterdeploy/clusterdeploy.go @@ -0,0 +1,623 @@ +package clusterdeploy + +import ( + "bytes" + "context" + "fmt" + "reflect" + "regexp" + "strings" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/tokens" + util "github.com/rancher/rancher/pkg/cluster" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/managementuser/healthsyncer" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/kubectl" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/systemtemplate" + "github.com/rancher/rancher/pkg/taints" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +const ( + AgentForceDeployAnn = "io.cattle.agent.force.deploy" + nodeImage = "nodeImage" + clusterImage = "clusterImage" +) + +var ErrCantConnectToAPI = errors.New("cannot connect to the cluster's Kubernetes API") + +var ( + agentImagesMutex sync.RWMutex + agentImages = map[string]map[string]string{ + nodeImage: {}, + clusterImage: {}, + } + controlPlaneTaintsMutex sync.RWMutex + controlPlaneTaints = make(map[string][]corev1.Taint) + controlPlaneLabels = map[string]string{ + "node-role.kubernetes.io/master": "true", + "node-role.kubernetes.io/controlplane": "true", + "node-role.kubernetes.io/control-plane": "true", + } +) + +func Register(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + c := &clusterDeploy{ + mgmt: management, + systemAccountManager: systemaccount.NewManager(management), + userManager: management.UserManager, + clusters: management.Management.Clusters(""), + nodeLister: management.Management.Nodes("").Controller().Lister(), + clusterManager: clusterManager, + secretLister: management.Core.Secrets("").Controller().Lister(), + ctx: ctx, + } + + management.Management.Clusters("").AddHandler(ctx, "cluster-deploy", c.sync) +} + +type clusterDeploy struct { + systemAccountManager *systemaccount.Manager + userManager user.Manager + clusters v3.ClusterInterface + clusterManager *clustermanager.Manager + mgmt *config.ManagementContext + nodeLister v3.NodeLister + secretLister v1.SecretLister + ctx context.Context +} + +func (cd *clusterDeploy) sync(key string, cluster *apimgmtv3.Cluster) (runtime.Object, error) { + logrus.Tracef("clusterDeploy: sync called for key [%s]", key) + var ( + err, updateErr error + ) + + if cluster == nil || cluster.DeletionTimestamp != nil { + // remove the system account user created for this cluster + if err := cd.systemAccountManager.RemoveSystemAccount(key); err != nil { + return nil, err + } + return nil, nil + } + + original := cluster + cluster = original.DeepCopy() + + if cluster.Status.Driver == apimgmtv3.ClusterDriverRKE { + if cluster.Spec.LocalClusterAuthEndpoint.Enabled { + cluster.Spec.RancherKubernetesEngineConfig.Authentication.Strategy = "x509|webhook" + } else { + cluster.Spec.RancherKubernetesEngineConfig.Authentication.Strategy = "x509" + } + logrus.Tracef("clusterDeploy: sync: cluster.Spec.RancherKubernetesEngineConfig.Authentication.Strategy set to [%s] for cluster [%s]", cluster.Spec.RancherKubernetesEngineConfig.Authentication.Strategy, cluster.Name) + } + + err = cd.doSync(cluster) + if cluster != nil && !reflect.DeepEqual(cluster, original) { + logrus.Tracef("clusterDeploy: sync: cluster changed, calling Update on cluster [%s]", cluster.Name) + _, updateErr = cd.clusters.Update(cluster) + } + + if err != nil { + return nil, err + } + return nil, updateErr +} + +func (cd *clusterDeploy) doSync(cluster *apimgmtv3.Cluster) error { + logrus.Tracef("clusterDeploy: doSync called for cluster [%s]", cluster.Name) + + if !apimgmtv3.ClusterConditionProvisioned.IsTrue(cluster) { + logrus.Tracef("clusterDeploy: doSync: cluster [%s] is not yet provisioned (ClusterConditionProvisioned is not True)", cluster.Name) + return nil + } + + // Skip further work if the cluster's API is not reachable according to HealthSyncer criteria + // Note that we don't check the cluster's ClusterConditionReady status here, as HealthSyncer is not running + // prior deployment of the cluster agent + uc, err := cd.clusterManager.UserContextNoControllersReconnecting(cluster.Name, false) + if err != nil { + return err + } + if err := healthsyncer.IsAPIUp(cd.ctx, uc.K8sClient.CoreV1().Namespaces()); err != nil { + logrus.Tracef("clusterDeploy: doSync: cannot connect to API for cluster [%s]", cluster.Name) + return ErrCantConnectToAPI + } + + nodes, err := cd.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return err + } + logrus.Tracef("clusterDeploy: doSync: found [%d] nodes for cluster [%s]", len(nodes), cluster.Name) + + if len(nodes) == 0 { + return nil + } + + _, err = apimgmtv3.ClusterConditionSystemAccountCreated.DoUntilTrue(cluster, func() (runtime.Object, error) { + logrus.Tracef("clusterDeploy: doSync: Creating SystemAccount for cluster [%s]", cluster.Name) + return cluster, cd.systemAccountManager.CreateSystemAccount(cluster) + }) + if err != nil { + return err + } + + if cluster.Status.AgentImage != "" && !agentImagesCached(cluster.Name) { + if err := cd.cacheAgentImages(cluster.Name); err != nil { + return err + } + } + + if !controlPlaneTaintsCached(cluster.Name) { + if err := cd.cacheControlPlaneTaints(cluster.Name); err != nil { + return err + } + } + + err = cd.deployAgent(cluster) + if err != nil { + return err + } + + return cd.setNetworkPolicyAnn(cluster) +} + +// agentFeaturesChanged will treat a missing key as false. This means we only detect changes +// when we set a feature to true so we can't reliably set a feature to false that is enabled by default. +// This behavior makes adding new def false features not cause the agent to redeploy. +func agentFeaturesChanged(desired, actual map[string]bool) bool { + for k, v := range desired { + if actual[k] != v { + return true + } + } + + for k, v := range actual { + if desired[k] != v { + return true + } + } + + return false +} + +func redeployAgent(cluster *apimgmtv3.Cluster, desiredAgent, desiredAuth string, desiredFeatures map[string]bool, desiredTaints []corev1.Taint) bool { + logrus.Tracef("clusterDeploy: redeployAgent called for cluster [%s]", cluster.Name) + if !apimgmtv3.ClusterConditionAgentDeployed.IsTrue(cluster) { + return true + } + forceDeploy := cluster.Annotations[AgentForceDeployAnn] == "true" + imageChange := cluster.Status.AgentImage != desiredAgent || cluster.Status.AuthImage != desiredAuth + agentFeaturesChanged := agentFeaturesChanged(desiredFeatures, cluster.Status.AgentFeatures) + repoChange := false + if cluster.Spec.RancherKubernetesEngineConfig != nil { + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + if len(cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.PrivateRegistries) > 0 { + desiredRepo := util.GetPrivateRegistry(cluster) + appliedRepo := &cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.PrivateRegistries[0] + + if desiredRepo != nil && appliedRepo != nil && !reflect.DeepEqual(desiredRepo, appliedRepo) { + repoChange = true + } + if (desiredRepo == nil && appliedRepo != nil) || (desiredRepo != nil && appliedRepo == nil) { + repoChange = true + } + } + } + } + + if forceDeploy || imageChange || repoChange || agentFeaturesChanged { + logrus.Infof("Redeploy Rancher Agents is needed for %s: forceDeploy=%v, agent/auth image changed=%v,"+ + " private repo changed=%v, agent features changed=%v", cluster.Name, forceDeploy, imageChange, repoChange, + agentFeaturesChanged) + logrus.Tracef("clusterDeploy: redeployAgent: cluster.Status.AgentImage: [%s], desiredAgent: [%s]", cluster.Status.AgentImage, desiredAgent) + logrus.Tracef("clusterDeploy: redeployAgent: cluster.Status.AuthImage [%s], desiredAuth: [%s]", cluster.Status.AuthImage, desiredAuth) + logrus.Tracef("clusterDeploy: redeployAgent: cluster.Status.AgentFeatures [%v], desiredFeatures: [%v]", cluster.Status.AgentFeatures, desiredFeatures) + return true + } + + na, ca := getAgentImages(cluster.Name) + if (cluster.Status.AgentImage != na && cluster.Status.Driver == apimgmtv3.ClusterDriverRKE) || cluster.Status.AgentImage != ca { + // downstream agent does not match, kick a redeploy with settings agent + logrus.Infof("clusterDeploy: redeployAgent: redeploy Rancher agents due to downstream agent image mismatch for [%s]: was [%s] and will be [%s]", + cluster.Name, na, image.ResolveWithCluster(settings.AgentImage.Get(), cluster)) + clearAgentImages(cluster.Name) + return true + } + + // Taints/tolerations + // Current control plane taints are cached for comparison + currentTaints := getCachedControlPlaneTaints(cluster.Name) + logrus.Tracef("clusterDeploy: redeployAgent: cluster [%s] currentTaints: [%v]", cluster.Name, currentTaints) + logrus.Tracef("clusterDeploy: redeployAgent: cluster [%s] desiredTaints: [%v]", cluster.Name, desiredTaints) + toAdd, toDelete := taints.GetToDiffTaints(currentTaints, desiredTaints) + // Any change to current triggers redeploy + if len(toAdd) > 0 || len(toDelete) > 0 { + logrus.Infof("clusterDeploy: redeployAgent: redeploy Rancher agents due to toleration mismatch for [%s], was [%v] and will be [%v]", cluster.Name, currentTaints, desiredTaints) + // Clear cache to refresh + clearControlPlaneTaints(cluster.Name) + return true + } + + if !reflect.DeepEqual(append(settings.DefaultAgentSettingsAsEnvVars(), cluster.Spec.AgentEnvVars...), cluster.Status.AppliedAgentEnvVars) { + logrus.Infof("clusterDeploy: redeployAgent: redeploy Rancher agents due to agent env vars mismatched for [%s], was [%v] and will be [%v]", cluster.Name, cluster.Status.AppliedAgentEnvVars, cluster.Spec.AgentEnvVars) + return true + } + + if !reflect.DeepEqual(cluster.Spec.ClusterAgentDeploymentCustomization, cluster.Status.AppliedClusterAgentDeploymentCustomization) { + logrus.Infof("clusterDeploy: redeployAgent: redeploy Rancher agents due to agent customization mismatch for [%s], was [%v] and will be [%v]", cluster.Name, cluster.Status.AppliedClusterAgentDeploymentCustomization, cluster.Spec.ClusterAgentDeploymentCustomization) + return true + } + + logrus.Tracef("clusterDeploy: redeployAgent: returning false for redeployAgent") + + return false +} + +func (cd *clusterDeploy) deployAgent(cluster *apimgmtv3.Cluster) error { + if cluster.Spec.Internal { + return nil + } + + desiredAgent := systemtemplate.GetDesiredAgentImage(cluster) + desiredAuth := systemtemplate.GetDesiredAuthImage(cluster) + desiredFeatures := systemtemplate.GetDesiredFeatures(cluster) + + logrus.Tracef("clusterDeploy: deployAgent: desiredFeatures is [%v] for cluster [%s]", desiredFeatures, cluster.Name) + + desiredTaints, err := cd.getControlPlaneTaints(cluster.Name) + if err != nil { + return err + } + logrus.Tracef("clusterDeploy: deployAgent: desiredTaints is [%v] for cluster [%s]", desiredTaints, cluster.Name) + + if !redeployAgent(cluster, desiredAgent, desiredAuth, desiredFeatures, desiredTaints) { + return nil + } + + kubeConfig, tokenName, err := cd.getKubeConfig(cluster) + if err != nil { + return err + } + defer func() { + if err := cd.mgmt.SystemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for clusterdeploy token [%s] failed, will not retry: %v", tokenName, err) + } + }() + + if _, err = apimgmtv3.ClusterConditionAgentDeployed.Do(cluster, func() (runtime.Object, error) { + yaml, err := cd.getYAML(cluster, desiredAgent, desiredAuth, desiredFeatures, desiredTaints) + if err != nil { + return cluster, err + } + logrus.Tracef("clusterDeploy: deployAgent: agent YAML: %v", string(yaml)) + var output []byte + for i := 0; i < 5; i++ { + // This will fail almost always the first time because when we create the namespace in the file it won't have privileges. + // This allows for 5*5 seconds for the cluster to be ready to apply the agent YAML before erroring out + logrus.Tracef("clusterDeploy: deployAgent: applying agent YAML for cluster [%s], try #%d: %v", cluster.Name, i+1, string(output)) + output, err = kubectl.Apply(yaml, kubeConfig) + if err == nil { + logrus.Debugf("clusterDeploy: deployAgent: successfully applied agent YAML for cluster [%s], try #%d", cluster.Name, i+1) + break + } + logrus.Debugf("clusterDeploy: deployAgent: error while applying agent YAML for cluster [%s], try #%d", cluster.Name, i+1) + time.Sleep(5 * time.Second) + } + if err != nil { + return cluster, errors.WithMessage(types.NewErrors(err, errors.New(formatKubectlApplyOutput(string(output)))), "Error while applying agent YAML, it will be retried automatically") + } + apimgmtv3.ClusterConditionAgentDeployed.Message(cluster, string(output)) + if !cluster.Spec.LocalClusterAuthEndpoint.Enabled && cluster.Status.AppliedSpec.LocalClusterAuthEndpoint.Enabled && cluster.Status.AuthImage != "" { + output, err = kubectl.Delete([]byte(systemtemplate.AuthDaemonSet), kubeConfig) + } + if err != nil { + logrus.Tracef("Output from kubectl delete kube-api-auth DaemonSet, output: %s, err: %v", string(output), err) + // Ignore if the resource does not exist and it returns 'daemonsets.apps "kube-api-auth" not found' + dsNotFoundError := "daemonsets.apps \"kube-api-auth\" not found" + if !strings.Contains(string(output), dsNotFoundError) { + return cluster, errors.WithMessage(types.NewErrors(err, errors.New(string(output))), "kubectl delete failed") + } + logrus.Debugf("Ignored '%s' error during delete kube-api-auth DaemonSet", dsNotFoundError) + } + if cluster.Status.Driver != apimgmtv3.ClusterDriverRKE { + if output, err = kubectl.Delete([]byte(systemtemplate.NodeAgentDaemonSet), kubeConfig); err != nil { + logrus.Tracef("Output from kubectl delete cattle-node-agent DaemonSet, output: %s, err: %v", string(output), err) + // Ignore if the resource does not exist and it returns 'daemonsets.apps "kube-api-auth" not found' + dsNotFoundError := "daemonsets.apps \"cattle-node-agent\" not found" + if !strings.Contains(string(output), dsNotFoundError) { + return cluster, errors.WithMessage(types.NewErrors(err, errors.New(string(output))), "kubectl delete failed") + } + logrus.Debugf("Ignored '%s' error during delete cattle-node-agent DaemonSet", dsNotFoundError) + } + } else if strings.ToLower(settings.AgentRolloutWait.Get()) == "true" { + // Check for agent daemonset rollout if parameter is set and driverv32.ClusterDriverRKE + timeout := settings.AgentRolloutTimeout.Get() + _, err = time.ParseDuration(timeout) + if err != nil { + logrus.Warnf("[deployAgent] agent-rollout-timeout setting must be in Duration format. Using default: 300s") + timeout = "300s" + } + logrus.Debugf("clusterDeploy: deployAgent: waiting rollout agent daemonset for cluster [%s]", cluster.Name) + output, err := kubectl.RolloutStatusWithNamespace("cattle-system", "ds/cattle-node-agent", timeout, kubeConfig) + if err != nil { + logrus.Debugf("clusterDeploy: deployAgent: timeout waiting rollout agent daemonset for cluster [%s]: %v", cluster.Name, err) + return cluster, errors.WithMessage(types.NewErrors(err, errors.New(formatKubectlApplyOutput(string(output)))), "Timeout waiting rollout agent daemonset") + } + logrus.Debugf("clusterDeploy: deployAgent: successfully rollout agent daemonset for cluster [%s]", cluster.Name) + apimgmtv3.ClusterConditionAgentDeployed.Message(cluster, "Successfully rollout agent daemonset") + } + apimgmtv3.ClusterConditionAgentDeployed.Message(cluster, string(output)) + return cluster, nil + }); err != nil { + return err + } + + if err = cd.cacheAgentImages(cluster.Name); err != nil { + return err + } + + cluster.Status.AgentImage = desiredAgent + cluster.Status.AgentFeatures = desiredFeatures + if cluster.Spec.DesiredAgentImage == "fixed" { + cluster.Spec.DesiredAgentImage = desiredAgent + } + cluster.Status.AuthImage = desiredAuth + if cluster.Spec.DesiredAuthImage == "fixed" { + cluster.Spec.DesiredAuthImage = desiredAuth + } + if cluster.Annotations[AgentForceDeployAnn] == "true" { + cluster.Annotations[AgentForceDeployAnn] = "false" + } + + cluster.Status.AppliedAgentEnvVars = append(settings.DefaultAgentSettingsAsEnvVars(), cluster.Spec.AgentEnvVars...) + + cluster.Status.AppliedClusterAgentDeploymentCustomization = cluster.Spec.ClusterAgentDeploymentCustomization + + return nil +} + +func (cd *clusterDeploy) setNetworkPolicyAnn(cluster *apimgmtv3.Cluster) error { + if cluster.Spec.EnableNetworkPolicy != nil { + return nil + } + // set current state for upgraded canal clusters + if cluster.Spec.RancherKubernetesEngineConfig != nil && + cluster.Spec.RancherKubernetesEngineConfig.Network.Plugin == "canal" { + enableNetworkPolicy := true + cluster.Spec.EnableNetworkPolicy = &enableNetworkPolicy + cluster.Annotations["networking.management.cattle.io/enable-network-policy"] = "true" + } + return nil +} + +func (cd *clusterDeploy) getKubeConfig(cluster *apimgmtv3.Cluster) (*clientcmdapi.Config, string, error) { + logrus.Tracef("clusterDeploy: getKubeConfig called for cluster [%s]", cluster.Name) + systemUser, err := cd.systemAccountManager.GetSystemUser(cluster.Name) + if err != nil { + return nil, "", err + } + + tokenPrefix := fmt.Sprintf("%s-%s", "agent", systemUser.Name) + token, err := cd.mgmt.SystemTokens.EnsureSystemToken(tokenPrefix, "token for agent deployment", "agent", systemUser.Name, nil, true) + if err != nil { + return nil, "", err + } + + tokenName, _ := tokens.SplitTokenParts(token) + return cd.clusterManager.KubeConfig(cluster.Name, token), tokenName, nil +} + +func (cd *clusterDeploy) getYAML(cluster *apimgmtv3.Cluster, agentImage, authImage string, features map[string]bool, taints []corev1.Taint) ([]byte, error) { + logrus.Tracef("clusterDeploy: getYAML: Desired agent image is [%s] for cluster [%s]", agentImage, cluster.Name) + logrus.Tracef("clusterDeploy: getYAML: Desired auth image is [%s] for cluster [%s]", authImage, cluster.Name) + logrus.Tracef("clusterDeploy: getYAML: Desired features are [%v] for cluster [%s]", features, cluster.Name) + logrus.Tracef("clusterDeploy: getYAML: Desired taints are [%v] for cluster [%s]", taints, cluster.Name) + + token, err := cd.systemAccountManager.GetOrCreateSystemClusterToken(cluster.Name) + if err != nil { + return nil, err + } + + url := settings.ServerURL.Get() + if url == "" { + cd.clusters.Controller().EnqueueAfter("", cluster.Name, time.Second) + return nil, fmt.Errorf("waiting for server-url setting to be set") + } + + buf := &bytes.Buffer{} + err = systemtemplate.SystemTemplate(buf, agentImage, authImage, cluster.Name, token, url, cluster.Spec.WindowsPreferedCluster, + cluster, features, taints, cd.secretLister) + + return buf.Bytes(), err +} + +func (cd *clusterDeploy) getClusterAgentImage(name string) (string, error) { + uc, err := cd.clusterManager.UserContextNoControllers(name) + if err != nil { + return "", err + } + + d, err := uc.Apps.Deployments("cattle-system").Get("cattle-cluster-agent", metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return "", err + } + return "", nil + } + + for _, c := range d.Spec.Template.Spec.Containers { + if c.Name == "cluster-register" { + return c.Image, nil + } + } + + return "", nil +} + +func (cd *clusterDeploy) getNodeAgentImage(name string) (string, error) { + uc, err := cd.clusterManager.UserContextNoControllers(name) + if err != nil { + return "", err + } + + ds, err := uc.Apps.DaemonSets("cattle-system").Get("cattle-node-agent", metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return "", err + } + return "", nil + } + + for _, c := range ds.Spec.Template.Spec.Containers { + if c.Name == "agent" { + return c.Image, nil + } + } + + return "", nil +} + +func (cd *clusterDeploy) cacheAgentImages(name string) error { + na, err := cd.getNodeAgentImage(name) + if err != nil { + return err + } + + ca, err := cd.getClusterAgentImage(name) + if err != nil { + return err + } + + agentImagesMutex.Lock() + defer agentImagesMutex.Unlock() + agentImages[nodeImage][name] = na + agentImages[clusterImage][name] = ca + return nil +} + +func agentImagesCached(name string) bool { + na, ca := getAgentImages(name) + return na != "" && ca != "" +} + +func controlPlaneTaintsCached(name string) bool { + controlPlaneTaintsMutex.RLock() + defer controlPlaneTaintsMutex.RUnlock() + if _, ok := controlPlaneTaints[name]; ok { + return true + } + return false +} + +func getAgentImages(name string) (string, string) { + agentImagesMutex.RLock() + defer agentImagesMutex.RUnlock() + return agentImages[nodeImage][name], agentImages[clusterImage][name] +} + +func getCachedControlPlaneTaints(name string) []corev1.Taint { + controlPlaneTaintsMutex.RLock() + defer controlPlaneTaintsMutex.RUnlock() + if _, ok := controlPlaneTaints[name]; ok { + return controlPlaneTaints[name] + } + return nil +} + +func clearAgentImages(name string) { + logrus.Tracef("clusterDeploy: clearAgentImages called for [%s]", name) + agentImagesMutex.Lock() + defer agentImagesMutex.Unlock() + delete(agentImages[nodeImage], name) + delete(agentImages[clusterImage], name) +} + +func clearControlPlaneTaints(name string) { + logrus.Tracef("clusterDeploy: clearControlPlaneTaints called for [%s]", name) + controlPlaneTaintsMutex.Lock() + defer controlPlaneTaintsMutex.Unlock() + delete(controlPlaneTaints, name) +} + +func (cd *clusterDeploy) cacheControlPlaneTaints(name string) error { + taints, err := cd.getControlPlaneTaints(name) + if err != nil { + return err + } + + controlPlaneTaintsMutex.Lock() + defer controlPlaneTaintsMutex.Unlock() + controlPlaneTaints[name] = taints + return nil +} + +func (cd *clusterDeploy) getControlPlaneTaints(name string) ([]corev1.Taint, error) { + var allTaints []corev1.Taint + var controlPlaneLabelFound bool + nodes, err := cd.nodeLister.List(name, labels.Everything()) + if err != nil { + return nil, err + } + logrus.Debugf("clusterDeploy: getControlPlaneTaints: Length of nodes for cluster [%s] is: %d", name, len(nodes)) + + for _, node := range nodes { + controlPlaneLabelFound = false + // Filtering nodes for controlplane nodes based on labels + for controlPlaneLabelKey, controlPlaneLabelValue := range controlPlaneLabels { + if labelValue, ok := node.Status.NodeLabels[controlPlaneLabelKey]; ok { + logrus.Tracef("clusterDeploy: getControlPlaneTaints: node [%s] has label key [%s]", node.Status.NodeName, controlPlaneLabelKey) + if labelValue == controlPlaneLabelValue { + logrus.Tracef("clusterDeploy: getControlPlaneTaints: node [%s] has label key [%s] and label value [%s]", node.Status.NodeName, controlPlaneLabelKey, controlPlaneLabelValue) + controlPlaneLabelFound = true + break + } + } + } + if controlPlaneLabelFound { + toAdd, _ := taints.GetToDiffTaints(allTaints, node.Spec.InternalNodeSpec.Taints) + for _, taintStr := range toAdd { + if !strings.HasPrefix(taintStr.Key, "node.kubernetes.io") { + logrus.Debugf("clusterDeploy: getControlPlaneTaints: toAdd: %v", toAdd) + allTaints = append(allTaints, taintStr) + continue + } + logrus.Tracef("clusterDeploy: getControlPlaneTaints: skipping taint [%v] because its k8s internal", taintStr) + } + } + } + logrus.Debugf("clusterDeploy: getControlPlaneTaints: allTaints: %v", allTaints) + + return allTaints, nil +} + +func formatKubectlApplyOutput(log string) string { + // Strip newlines to compact output + log = strings.Replace(log, "\n", " ", -1) + // Strip token from output + tokenRegex := regexp.MustCompile(`^.*?\"token\":\"(.*?)\"`) + token := tokenRegex.FindStringSubmatch(log) + if len(token) == 2 { + log = strings.Replace(log, token[1], "REDACTED", 1) + } + return log +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc.go new file mode 100644 index 0000000..4c93303 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc.go @@ -0,0 +1,139 @@ +package clustergc + +import ( + "context" + "strings" + "time" + + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/dynamic" +) + +func Register(ctx context.Context, management *config.ManagementContext) { + gc := &gcLifecycle{ + mgmt: management, + } + + management.Management.Clusters("").AddLifecycle(ctx, "cluster-scoped-gc", gc) +} + +type gcLifecycle struct { + mgmt *config.ManagementContext +} + +func (c *gcLifecycle) Create(obj *v3.Cluster) (runtime.Object, error) { + return obj, nil +} + +func (c *gcLifecycle) Updated(obj *v3.Cluster) (runtime.Object, error) { + return nil, nil +} + +func cleanFinalizers(clusterName string, object *unstructured.Unstructured, dynamicClient dynamic.ResourceInterface) (*unstructured.Unstructured, error) { + object = object.DeepCopy() + modified := false + md, err := meta.Accessor(object) + if err != nil { + return object, err + } + finalizers := md.GetFinalizers() + for i := len(finalizers) - 1; i >= 0; i-- { + f := finalizers[i] + if strings.HasPrefix(f, lifecycle.ScopedFinalizerKey) && strings.HasSuffix(f, "_"+clusterName) { + finalizers = append(finalizers[:i], finalizers[i+1:]...) + modified = true + } + } + + if modified { + md.SetFinalizers(finalizers) + obj, e := dynamicClient.Update(context.TODO(), object, metav1.UpdateOptions{}) + return obj, e + } + return object, nil +} + +func (c *gcLifecycle) waitForNodeRemoval(cluster *v3.Cluster) error { + if cluster.Status.Driver != v32.ClusterDriverRKE { + return nil // not an rke1 node, no need to pause + } + + nodes, err := c.mgmt.Management.Nodes("").Controller().Lister().List(cluster.Name, labels.Everything()) + if err != nil && !errors.IsNotFound(err) { + return err + } + var waitForNodeDelete bool + for _, n := range nodes { + // trigger the deletion of node for a custom cluster + if n.Status.NodeTemplateSpec == nil && n.DeletionTimestamp == nil { + _ = c.mgmt.Management.Nodes(n.Namespace).Delete(n.Name, &metav1.DeleteOptions{}) + waitForNodeDelete = true + } + } + if waitForNodeDelete { + logrus.Debugf("[cluster-scoped-gc] custom cluster %s still has rke1 nodes, checking again in 15s", cluster.Name) + c.mgmt.Management.Clusters("").Controller().EnqueueAfter(cluster.Namespace, cluster.Name, 15*time.Second) + return generic.ErrSkip + } + + return nil +} + +// Remove check all objects that have had a cluster scoped finalizer added to them to ensure dangling finalizers do not +// remain on objects that no longer have handlers associated with them +func (c *gcLifecycle) Remove(cluster *v3.Cluster) (runtime.Object, error) { + if err := c.waitForNodeRemoval(cluster); err != nil { + return cluster, err // ErrSkip if we still need to wait + } + + RESTconfig := c.mgmt.RESTConfig + // due to the large number of api calls, temporary raise the burst limit in order to reduce client throttling + RESTconfig.Burst = 25 + dynamicClient, err := dynamic.NewForConfig(&RESTconfig) + if err != nil { + return nil, err + } + decodedMap := resource.GetClusterScopedTypes() + //if map is empty, fall back to checking all Rancher types + if len(decodedMap) == 0 { + decodedMap = resource.Get() + } + var g errgroup.Group + + for key := range decodedMap { + actualKey := key // https://golang.org/doc/faq#closures_and_goroutines + g.Go(func() error { + objList, err := dynamicClient.Resource(actualKey).List(context.TODO(), metav1.ListOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return nil + } + return err + } + for _, obj := range objList.Items { + _, err = cleanFinalizers(cluster.Name, &obj, dynamicClient.Resource(actualKey).Namespace(obj.GetNamespace())) + if err != nil { + return err + } + } + return nil + }) + } + if err = g.Wait(); err != nil { + return nil, err + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc_test.go new file mode 100644 index 0000000..ef62c39 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustergc/cluster_scoped_gc_test.go @@ -0,0 +1,147 @@ +package clustergc + +import ( + "context" + "testing" + + "github.com/rancher/norman/lifecycle" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" +) + +func TestCleanFinalizersGeneric(t *testing.T) { + tests := []struct { + name string + clusterName string + object *unstructured.Unstructured + wantFinal []string + }{ + { + name: "basic case", + clusterName: "test", + object: finalizerFactory( + lifecycle.ScopedFinalizerKey + "blah" + "_" + "test", + ), + wantFinal: []string{}, + }, + { + "DontRemoveUnrelated", + "a", + finalizerFactory( + lifecycle.ScopedFinalizerKey+"App"+"_"+"b", + lifecycle.ScopedFinalizerKey+"App"+"_"+"a", + ), + []string{lifecycle.ScopedFinalizerKey + "App" + "_" + "b"}, + }, + { + "NoFinalizers", + "a", + &unstructured.Unstructured{}, + nil, + }, + { + "DontAffectNonScoped", + "a", + finalizerFactory("controller.cattle.io/" + "App" + "_" + "a"), + []string{"controller.cattle.io/" + "App" + "_" + "a"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + object, err := cleanFinalizers(tt.clusterName, tt.object, mockDynamicResourceInterface{}) + if err != nil { + t.Errorf("cleanFinalizersGeneric() error = %v", err) + } + md, err := meta.Accessor(object) + if err != nil { + t.Errorf("cleanFinalizersGeneric() error = %v", err) + } + finalizers := md.GetFinalizers() + assert.Equal(t, tt.wantFinal, finalizers) + }) + } +} + +// use meta accessors to set finalizer values +func finalizerFactory(finals ...string) *unstructured.Unstructured { + + randomStr := "nameofType" + metadata := &metav1.ObjectMeta{ + Name: randomStr, + Finalizers: finals, + } + unstruct := &unstructured.Unstructured{} + err := setObjectMeta(unstruct, metadata) + if err != nil { + panic(err) + } + return unstruct + +} + +func setObjectMeta(u *unstructured.Unstructured, objectMeta *metav1.ObjectMeta) error { + if objectMeta == nil { + unstructured.RemoveNestedField(u.UnstructuredContent(), "metadata") + return nil + } + metadata, err := runtime.DefaultUnstructuredConverter.ToUnstructured(objectMeta) + if err != nil { + return err + } + if u.Object == nil { + u.Object = make(map[string]interface{}) + } + u.Object["metadata"] = metadata + return nil +} + +type mockDynamicResourceInterface struct{} + +func (i mockDynamicResourceInterface) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (i mockDynamicResourceInterface) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) Update(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + return obj, nil +} + +func (mockDynamicResourceInterface) Create(ctx context.Context, obj *unstructured.Unstructured, options metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) Delete(ctx context.Context, name string, options metav1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (mockDynamicResourceInterface) DeleteCollection(ctx context.Context, options metav1.DeleteOptions, listOptions metav1.ListOptions) error { + panic("implement me") +} + +func (mockDynamicResourceInterface) Get(ctx context.Context, name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (mockDynamicResourceInterface) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusteroperator/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusteroperator/utils.go new file mode 100644 index 0000000..2181dab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusteroperator/utils.go @@ -0,0 +1,206 @@ +package clusteroperator + +import ( + "encoding/base64" + "fmt" + "strings" + "time" + + "github.com/rancher/norman/condition" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalog/manager" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + projectv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/drivers/util" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/systemaccount" + typesDialer "github.com/rancher/rancher/pkg/types/config/dialer" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/util/retry" +) + +const ( + localCluster = "local" + systemNS = "cattle-system" +) + +type OperatorController struct { + ClusterEnqueueAfter func(name string, duration time.Duration) + SecretsCache wranglerv1.SecretCache + Secrets corev1.SecretInterface + TemplateCache v3.CatalogTemplateCache + ProjectCache v3.ProjectCache + AppLister projectv3.AppLister + AppClient projectv3.AppInterface + NsClient corev1.NamespaceInterface + ClusterClient v3.ClusterClient + CatalogManager manager.CatalogManager + SystemAccountManager *systemaccount.Manager + DynamicClient dynamic.NamespaceableResourceInterface + ClientDialer typesDialer.Factory + Discovery discovery.DiscoveryInterface +} + +func (e *OperatorController) SetUnknown(cluster *mgmtv3.Cluster, condition condition.Cond, message string) (*mgmtv3.Cluster, error) { + if condition.IsUnknown(cluster) && condition.GetMessage(cluster) == message { + return cluster, nil + } + cluster = cluster.DeepCopy() + condition.Unknown(cluster) + condition.Message(cluster, message) + var err error + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + return cluster, nil +} + +func (e *OperatorController) SetTrue(cluster *mgmtv3.Cluster, condition condition.Cond, message string) (*mgmtv3.Cluster, error) { + if condition.IsTrue(cluster) && condition.GetMessage(cluster) == message { + return cluster, nil + } + cluster = cluster.DeepCopy() + condition.True(cluster) + condition.Message(cluster, message) + var err error + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + return cluster, nil +} + +func (e *OperatorController) SetFalse(cluster *mgmtv3.Cluster, condition condition.Cond, message string) (*mgmtv3.Cluster, error) { + if condition.IsFalse(cluster) && condition.GetMessage(cluster) == message { + return cluster, nil + } + cluster = cluster.DeepCopy() + condition.False(cluster) + condition.Message(cluster, message) + var err error + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + return cluster, nil +} + +// RecordCAAndAPIEndpoint reads the cluster config's secret once available. The CA cert and API endpoint are then copied to the cluster status. +func (e *OperatorController) RecordCAAndAPIEndpoint(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + backoff := wait.Backoff{ + Duration: 2 * time.Second, + Factor: 2, + Jitter: 0, + Steps: 6, + Cap: 20 * time.Second, + } + + var caSecret *corev1.Secret + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + var err error + caSecret, err = e.SecretsCache.Get(namespace.GlobalNamespace, cluster.Name) + if err != nil { + if !errors.IsNotFound(err) { + return false, err + } + logrus.Infof("waiting for cluster [%s] data needed to generate service account token", cluster.Name) + return false, nil + } + return true, nil + }) + if err != nil { + return cluster, fmt.Errorf("failed waiting for cluster [%s] secret: %s", cluster.Name, err) + } + + apiEndpoint := string(caSecret.Data["endpoint"]) + if !strings.HasPrefix(apiEndpoint, "https://") { + apiEndpoint = "https://" + apiEndpoint + } + caCert, err := addAdditionalCA(e.SecretsCache, string(caSecret.Data["ca"])) + if err != nil { + return cluster, err + } + if cluster.Status.APIEndpoint == apiEndpoint && cluster.Status.CACert == caCert { + return cluster, nil + } + + var currentCluster *mgmtv3.Cluster + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + currentCluster, err = e.ClusterClient.Get(cluster.Name, v1.GetOptions{}) + if err != nil { + return err + } + currentCluster.Status.APIEndpoint = apiEndpoint + currentCluster.Status.CACert = caCert + currentCluster, err = e.ClusterClient.Update(currentCluster) + return err + }) + + return currentCluster, err +} + +// checkCRDReady checks whether necessary CRD(AKSConfig/EKSConfig/GKEConfig), has been created yet +func (e *OperatorController) CheckCrdReady(cluster *mgmtv3.Cluster, clusterType string) (*mgmtv3.Cluster, error) { + resources, err := e.Discovery.ServerResourcesForGroupVersion(fmt.Sprintf("%s.cattle.io/v1", clusterType)) + if err != nil && !errors.IsNotFound(err) { + return cluster, err + } + if errors.IsNotFound(err) || len(resources.APIResources) == 0 { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, fmt.Sprintf("Waiting on %s crd to be initialized", clusterType)) + if err != nil { + return cluster, err + } + return cluster, fmt.Errorf("waiting %s crd to be initialized, cluster: %v", clusterType, cluster.Name) + } + return cluster, nil +} + +func GenerateSAToken(restConfig *rest.Config) (string, error) { + clientSet, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return "", fmt.Errorf("error creating clientset: %v", err) + } + + return util.GenerateServiceAccountToken(clientSet) +} + +func addAdditionalCA(secretsCache wranglerv1.SecretCache, caCert string) (string, error) { + additionalCA, err := getAdditionalCA(secretsCache) + if err != nil { + return caCert, err + } + if additionalCA == nil { + return caCert, nil + } + + caBytes, err := base64.StdEncoding.DecodeString(caCert) + if err != nil { + return "", err + } + + return base64.StdEncoding.EncodeToString(append(caBytes, additionalCA...)), nil +} + +func getAdditionalCA(secretsCache wranglerv1.SecretCache) ([]byte, error) { + secret, err := secretsCache.Get(namespace.System, "tls-ca-additional") + if err != nil && !errors.IsNotFound(err) { + return nil, err + } + + if secret == nil { + return nil, nil + } + + return secret.Data["ca-additional.pem"], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/driver.go new file mode 100644 index 0000000..679b98c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/driver.go @@ -0,0 +1,204 @@ +package clusterprovisioner + +import ( + "fmt" + "reflect" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/clusterprovisioninglogger" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const DriverNameField = "driverName" + +func (p *Provisioner) driverCreate(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec) (api string, token string, cert string, err error) { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionProvisioned) + defer logger.Close() + + spec = cleanRKE(spec) + spec, err = assemblers.AssembleRKEConfigSpec(cluster, spec, p.SecretLister) + if err != nil { + return "", "", "", err + } + + if newCluster, err := p.Clusters.Update(cluster); err == nil { + cluster = newCluster + } + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + return "", "", "", err + } + + return p.engineService.Create(ctx, cluster.Name, kontainerDriver, spec) +} + +func (p *Provisioner) getKontainerDriver(spec apimgmtv3.ClusterSpec) (*apimgmtv3.KontainerDriver, error) { + if spec.GenericEngineConfig != nil { + return p.KontainerDriverLister.Get("", (*spec.GenericEngineConfig)[DriverNameField].(string)) + } + + if spec.RancherKubernetesEngineConfig != nil { + return p.KontainerDriverLister.Get("", service.RancherKubernetesEngineDriverName) + } + + if spec.ImportedConfig != nil { + return p.KontainerDriverLister.Get("", "import") + } + + return nil, fmt.Errorf("no kontainer driver for cluster %v", spec.DisplayName) +} + +// driverUpdate updates the given cluster with the new config from `spec` using its driver. If `forceUpdate` is true, +// the update will be performed regardless of whether the spec has changed at all. Otherwise, the update will only +// occur if the spec has changed. +func (p *Provisioner) driverUpdate( + cluster *apimgmtv3.Cluster, + spec apimgmtv3.ClusterSpec, + forceUpdate bool, +) (api string, token string, cert string, updateTriggered bool, err error) { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionUpdated) + defer logger.Close() + + spec = cleanRKE(spec) + applied := cleanRKE(cluster.Status.AppliedSpec) + + configUnchanged := spec.RancherKubernetesEngineConfig != nil && + cluster.Status.APIEndpoint != "" && + cluster.Status.ServiceAccountTokenSecret != "" && + reflect.DeepEqual(applied.RancherKubernetesEngineConfig, spec.RancherKubernetesEngineConfig) + if configUnchanged && !forceUpdate { + secret, err := p.Secrets.GetNamespaced("cattle-global-data", cluster.Status.ServiceAccountTokenSecret, v1.GetOptions{}) + if err != nil { + logrus.Errorf("Could not find service account token secret %s for cluster %s: [%v]", cluster.Status.ServiceAccountTokenSecret, cluster.Name, err) + return cluster.Status.APIEndpoint, "", cluster.Status.CACert, false, err + } + return cluster.Status.APIEndpoint, string(secret.Data["credential"]), cluster.Status.CACert, false, nil + } + + if spec.RancherKubernetesEngineConfig != nil && spec.RancherKubernetesEngineConfig.Services.Etcd.Snapshot == nil && + applied.RancherKubernetesEngineConfig != nil && applied.RancherKubernetesEngineConfig.Services.Etcd.Snapshot == nil { + _false := false + cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.Snapshot = &_false + } + + spec, err = assemblers.AssembleRKEConfigSpec(cluster, spec, p.SecretLister) + if err != nil { + return "", "", "", false, err + } + + if newCluster, err := p.Clusters.Update(cluster); err == nil { + cluster = newCluster + } + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + return "", "", "", false, err + } + + api, token, cert, err = p.engineService.Update(ctx, cluster.Name, kontainerDriver, spec) + return api, token, cert, true, err +} + +func (p *Provisioner) driverRemove(cluster *apimgmtv3.Cluster, forceRemove bool) error { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionProvisioned) + defer logger.Close() + + spec := cleanRKE(cluster.Spec) + + _, err := apimgmtv3.ClusterConditionUpdated.Do(cluster, func() (runtime.Object, error) { + if newCluster, err := p.Clusters.Update(cluster); err == nil { + cluster = newCluster + } + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + if apierrors.IsNotFound(err) { + logrus.Warnf("Could not find kontainer driver for cluster removal [%v]", err) + return nil, nil + } + return nil, err + } + + return cluster, p.engineService.Remove(ctx, cluster.Name, kontainerDriver, spec, forceRemove) + }) + + return err +} + +func (p *Provisioner) driverRestore(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec, snapshot string) (string, string, string, error) { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionUpdated) + defer logger.Close() + + spec = cleanRKE(spec) + spec, err := assemblers.AssembleRKEConfigSpec(cluster, spec, p.SecretLister) + if err != nil { + return "", "", "", err + } + + newCluster, err := p.Clusters.Update(cluster) + if err == nil { + cluster = newCluster + } + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + return "", "", "", err + } + return p.engineService.ETCDRestore(ctx, cluster.Name, kontainerDriver, spec, snapshot) + +} + +func (p *Provisioner) generateServiceAccount(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec) (string, error) { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionUpdated) + defer logger.Close() + + spec = cleanRKE(spec) + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + return "", err + } + + return p.engineService.GenerateServiceAccount(ctx, cluster.Name, kontainerDriver, spec) +} + +func (p *Provisioner) removeLegacyServiceAccount(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec) error { + ctx, logger := clusterprovisioninglogger.NewLogger(p.Clusters, p.ConfigMaps, cluster, apimgmtv3.ClusterConditionUpdated) + defer logger.Close() + + spec = cleanRKE(spec) + + kontainerDriver, err := p.getKontainerDriver(spec) + if err != nil { + return err + } + + return p.engineService.RemoveLegacyServiceAccount(ctx, cluster.Name, kontainerDriver, spec) +} + +func cleanRKE(spec apimgmtv3.ClusterSpec) apimgmtv3.ClusterSpec { + if spec.RancherKubernetesEngineConfig == nil { + return spec + } + + result := spec.DeepCopy() + + var filteredNodes []rketypes.RKEConfigNode + for _, node := range spec.RancherKubernetesEngineConfig.Nodes { + if len(node.Role) == 1 && node.Role[0] == services.WorkerRole { + continue + } + filteredNodes = append(filteredNodes, node) + } + + result.RancherKubernetesEngineConfig.Nodes = filteredNodes + return *result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/provisioner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/provisioner.go new file mode 100644 index 0000000..d884e15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/provisioner.go @@ -0,0 +1,1138 @@ +package clusterprovisioner + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "path" + "reflect" + "sort" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/controller" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/slice" + "github.com/rancher/norman/types/values" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + util "github.com/rancher/rancher/pkg/cluster" + "github.com/rancher/rancher/pkg/controllers/management/imported" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + v1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/drivers/rke" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rancher/pkg/kontainerdriver" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/rkedialerfactory" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/flowcontrol" +) + +const ( + RKEDriverKey = "rancherKubernetesEngineConfig" + KontainerEngineUpdate = "provisioner.cattle.io/ke-driver-update" + RkeRestoreAnnotation = "rke.cattle.io/restore" + RKEForceUpdate = "rke.cattle.io/force-update" +) + +type Provisioner struct { + ClusterController v3.ClusterController + Clusters v3.ClusterInterface + ConfigMaps corev1.ConfigMapInterface + NodeLister v3.NodeLister + Nodes v3.NodeInterface + engineService *service.EngineService + backoff *flowcontrol.Backoff + KontainerDriverLister v3.KontainerDriverLister + DynamicSchemasLister v3.DynamicSchemaLister + DaemonsetLister v1.DaemonSetLister + Backups v3.EtcdBackupLister + RKESystemImages v3.RkeK8sSystemImageInterface + RKESystemImagesLister v3.RkeK8sSystemImageLister + SecretLister corev1.SecretLister + Secrets corev1.SecretInterface +} + +func Register(ctx context.Context, management *config.ManagementContext) { + p := &Provisioner{ + engineService: service.NewEngineService(NewPersistentStore(management.Core.Namespaces(""), management.Core)), + Clusters: management.Management.Clusters(""), + ConfigMaps: management.Core.ConfigMaps(""), + ClusterController: management.Management.Clusters("").Controller(), + NodeLister: management.Management.Nodes("").Controller().Lister(), + Nodes: management.Management.Nodes(""), + backoff: flowcontrol.NewBackOff(30*time.Second, 10*time.Minute), + KontainerDriverLister: management.Management.KontainerDrivers("").Controller().Lister(), + DynamicSchemasLister: management.Management.DynamicSchemas("").Controller().Lister(), + Backups: management.Management.EtcdBackups("").Controller().Lister(), + RKESystemImagesLister: management.Management.RkeK8sSystemImages("").Controller().Lister(), + RKESystemImages: management.Management.RkeK8sSystemImages(""), + DaemonsetLister: management.Apps.DaemonSets("").Controller().Lister(), + SecretLister: management.Core.Secrets("").Controller().Lister(), + Secrets: management.Core.Secrets(""), + } + // Add handlers + p.Clusters.AddLifecycle(ctx, "cluster-provisioner-controller", p) + management.Management.Nodes("").AddHandler(ctx, "cluster-provisioner-controller", p.machineChanged) + + local := &rkedialerfactory.RKEDialerFactory{ + Factory: management.Dialer, + Ctx: ctx, + } + docker := &rkedialerfactory.RKEDialerFactory{ + Factory: management.Dialer, + Docker: true, + Ctx: ctx, + } + + driver := service.Drivers[service.RancherKubernetesEngineDriverName] + rkeDriver := driver.(*rke.Driver) + rkeDriver.DockerDialer = docker.Build + rkeDriver.LocalDialer = local.Build + rkeDriver.WrapTransportFactory = docker.WrapTransport + mgmt := management.Management + rkeDriver.DataStore = NewDataStore(mgmt.RkeAddons("").Controller().Lister(), + mgmt.RkeAddons(""), + mgmt.RkeK8sServiceOptions("").Controller().Lister(), + mgmt.RkeK8sServiceOptions(""), + mgmt.RkeK8sSystemImages("").Controller().Lister(), + mgmt.RkeK8sSystemImages("")) +} + +func skipOperatorCluster(action string, cluster *apimgmtv3.Cluster) bool { + msgFmt := "%s cluster [%s] will be managed by %s-operator-controller, skipping %s" + switch { + case cluster.Spec.AKSConfig != nil: + logrus.Debugf(msgFmt, "AKS", cluster.Name, "aks", action) + return true + case cluster.Spec.EKSConfig != nil: + logrus.Debugf(msgFmt, "EKS", cluster.Name, "eks", action) + return true + case cluster.Spec.GKEConfig != nil: + logrus.Debugf(msgFmt, "GKE", cluster.Name, "gke", action) + return true + default: + return false + } +} + +func isRke1CustomCluster(cluster *apimgmtv3.Cluster, nodes []*apimgmtv3.Node) bool { + if cluster.Status.Driver == apimgmtv3.ClusterDriverRKE { + for _, n := range nodes { + if n.Status.NodeTemplateSpec == nil { + return true + } + } + } + return false +} + +func (p *Provisioner) Remove(cluster *apimgmtv3.Cluster) (runtime.Object, error) { + if skipOperatorCluster("remove", cluster) { + return cluster, nil + } + + logrus.Infof("Deleting cluster [%s]", cluster.Name) + if skipLocalK3sImported(cluster) || + cluster.Status.Driver == "" { + return nil, nil + } + + nodes, err := p.NodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return cluster, err + } + + if isRke1CustomCluster(cluster, nodes) { + logrus.Debugf("Skipping RKE1 Custom Cluster in favor of node-cleanup logic [%s] ", cluster.Name) + return cluster, nil + } + + for i := 0; i < 4; i++ { + // cluster will be forcefully removed on last attempt + err := p.driverRemove(cluster, i == 3) + if err == nil { + break + } + if i == 3 { + return cluster, fmt.Errorf("failed to remove the cluster [%s]: %v", cluster.Name, err) + } + time.Sleep(1 * time.Second) + } + logrus.Infof("Deleted cluster [%s]", cluster.Name) + + // cluster object will definitely have changed, reload + return p.Clusters.Get(cluster.Name, metav1.GetOptions{}) +} + +func (p *Provisioner) Updated(cluster *apimgmtv3.Cluster) (runtime.Object, error) { + if skipOperatorCluster("update", cluster) { + return cluster, nil + } + + if imported.IsAdministratedByProvisioningCluster(cluster) { + reconcileACE(cluster) + return p.Clusters.Update(cluster) + } + + obj, err := apimgmtv3.ClusterConditionUpdated.Do(cluster, func() (runtime.Object, error) { + anno, _ := cluster.Annotations[KontainerEngineUpdate] + if anno == "updated" { + // Cluster has already been updated proceed as usual + setVersion(cluster) + return p.update(cluster, false) + + } else if strings.HasPrefix(anno, "updating/") { + // Check if it's been updating for more than 20 seconds, this lets + // the controller take over attempting to update the cluster + pieces := strings.Split(anno, "/") + t, err := time.Parse(time.RFC3339, pieces[1]) + if err != nil || int(time.Since(t)/time.Second) > 20 { + cluster.Annotations[KontainerEngineUpdate] = "updated" + return p.Clusters.Update(cluster) + } + // Go routine is already running to update the cluster so wait + return nil, nil + } + // Set the annotation and kickoff the update + c, err := p.setKontainerEngineUpdate(cluster, "updating") + if err != nil { + return cluster, err + } + go p.waitForSchema(c) + return nil, nil + }) + + return obj.(*apimgmtv3.Cluster), err +} + +// waitForSchema waits for the driver and schema to be populated for the cluster +func (p *Provisioner) waitForSchema(cluster *apimgmtv3.Cluster) { + var driver string + if cluster.Spec.GenericEngineConfig == nil { + if cluster.Spec.AmazonElasticContainerServiceConfig != nil { + driver = "amazonelasticcontainerservice" + } + + if cluster.Spec.AzureKubernetesServiceConfig != nil { + driver = "azurekubernetesservice" + } + + if cluster.Spec.GoogleKubernetesEngineConfig != nil { + driver = "googlekubernetesengine" + } + } else { + if d, ok := (*cluster.Spec.GenericEngineConfig)["driverName"]; ok { + driver = d.(string) + } + } + + if driver != "" { + var schemaName string + backoff := wait.Backoff{ + Duration: 2 * time.Second, + Factor: 1, + Jitter: 0, + Steps: 7, + } + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + driver, err := p.KontainerDriverLister.Get("", driver) + if err != nil { + if !apierrors.IsNotFound(err) { + return false, err + } + return false, nil + } + + if driver.Spec.BuiltIn { + schemaName = driver.Status.DisplayName + "Config" + } else { + schemaName = driver.Status.DisplayName + "EngineConfig" + } + + _, err = p.DynamicSchemasLister.Get("", strings.ToLower(schemaName)) + if err != nil { + if !apierrors.IsNotFound(err) { + return false, err + } + return false, nil + } + + return true, nil + }) + if err != nil { + logrus.Warnf("[cluster-provisioner-controller] Failed to find driver %v and schema %v for cluster %v on upgrade: %v", + driver, schemaName, cluster.Name, err) + } + } + + _, err := p.setKontainerEngineUpdate(cluster, "updated") + if err != nil { + logrus.Warnf("[cluster-provisioner-controller] Failed to set annotation on cluster %v on upgrade: %v", cluster.Name, err) + } + p.ClusterController.Enqueue(cluster.Namespace, cluster.Name) +} + +func (p *Provisioner) setKontainerEngineUpdate(cluster *apimgmtv3.Cluster, anno string) (*apimgmtv3.Cluster, error) { + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 6, + } + + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + newCluster, err := p.Clusters.Get(cluster.Name, metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return false, err + } + return false, nil + } + + if anno == "updating" { + // Add a timestamp for comparison since this anno was added + anno = anno + "/" + time.Now().Format(time.RFC3339) + } + + newCluster.Annotations[KontainerEngineUpdate] = anno + newCluster, err = p.Clusters.Update(newCluster) + if err != nil { + if apierrors.IsConflict(err) { + return false, nil + } + return false, err + } + cluster = newCluster + return true, nil + }) + if err != nil { + return cluster, fmt.Errorf("[setKontainerEngineUpdate] Failed to update cluster [%s]: %v", cluster.Name, err) + } + return cluster, nil +} + +func setVersion(cluster *apimgmtv3.Cluster) { + if cluster.Spec.RancherKubernetesEngineConfig != nil { + if cluster.Spec.RancherKubernetesEngineConfig.Version == "" { + // set version from the applied spec + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Version != "" { + cluster.Spec.RancherKubernetesEngineConfig.Version = cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Version + } else { + cluster.Spec.RancherKubernetesEngineConfig.Version = settings.KubernetesVersion.Get() + } + } + } + } else if cluster.Spec.AmazonElasticContainerServiceConfig != nil { + if cluster.Status.Version != nil { + setConfigVersion := func(config *apimgmtv3.MapStringInterface) { + v, found := values.GetValue(*config, "kubernetesVersion") + if !found || convert.ToString(v) == "" && cluster.Status.Version != nil && cluster.Status.Version.Major != "" && len(cluster.Status.Version.Minor) > 1 { + values.PutValue(*config, fmt.Sprintf("%s.%s", cluster.Status.Version.Major, cluster.Status.Version.Minor[:2]), "kubernetesVersion") + } + } + + // during upgrade it is possible genericEngineConfig has not been set + if newConfig := cluster.Spec.AmazonElasticContainerServiceConfig; newConfig != nil { + setConfigVersion(newConfig) + } + + if oldConfig := cluster.Status.AppliedSpec.AmazonElasticContainerServiceConfig; oldConfig != nil { + setConfigVersion(oldConfig) + } + } + } +} + +func (p *Provisioner) update(cluster *apimgmtv3.Cluster, create bool) (*apimgmtv3.Cluster, error) { + cluster, err := p.reconcileCluster(cluster, create) + if err != nil || imported.IsAdministratedByProvisioningCluster(cluster) { + return cluster, err + } + + apimgmtv3.ClusterConditionProvisioned.True(cluster) + apimgmtv3.ClusterConditionProvisioned.Message(cluster, "") + apimgmtv3.ClusterConditionProvisioned.Reason(cluster, "") + apimgmtv3.ClusterConditionPending.True(cluster) + + if cluster.Spec.RancherKubernetesEngineConfig != nil || cluster.Spec.GenericEngineConfig != nil { + return cluster, nil + } + nodes, err := p.NodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return cluster, err + } + err = p.k3sBasedClusterConfig(cluster, nodes) + if err != nil { + return cluster, err + } + + return cluster, nil +} + +func (p *Provisioner) machineChanged(key string, machine *apimgmtv3.Node) (runtime.Object, error) { + parts := strings.SplitN(key, "/", 2) + + p.ClusterController.Enqueue("", parts[0]) + + return machine, nil +} + +func (p *Provisioner) Create(cluster *apimgmtv3.Cluster) (runtime.Object, error) { + if skipOperatorCluster("create", cluster) || imported.IsAdministratedByProvisioningCluster(cluster) { + return cluster, nil + } + + var err error + // Initialize conditions, be careful to not continually update them + apimgmtv3.ClusterConditionPending.CreateUnknownIfNotExists(cluster) + apimgmtv3.ClusterConditionProvisioned.CreateUnknownIfNotExists(cluster) + + if apimgmtv3.ClusterConditionWaiting.GetStatus(cluster) == "" { + apimgmtv3.ClusterConditionWaiting.Unknown(cluster) + if apimgmtv3.ClusterConditionWaiting.GetMessage(cluster) == "" { + apimgmtv3.ClusterConditionWaiting.Message(cluster, "Waiting for API to be available") + } + } + + cluster, err = p.pending(cluster) + if err != nil { + return cluster, err + } + + return p.provision(cluster) +} + +func (p *Provisioner) provision(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + obj, err := apimgmtv3.ClusterConditionProvisioned.Do(cluster, func() (runtime.Object, error) { + return p.update(cluster, true) + }) + return obj.(*apimgmtv3.Cluster), err +} + +func (p *Provisioner) pending(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if skipLocalK3sImported(cluster) { + return cluster, nil + } + + driver, err := p.validateDriver(cluster) + if err != nil { + return cluster, err + } + + if driver == "" { + return cluster, &controller.ForgetError{ + Err: fmt.Errorf("waiting for full cluster configuration"), + Reason: "Pending"} + } + + if driver != cluster.Status.Driver { + cluster.Status.Driver = driver + if driver == apimgmtv3.ClusterDriverRKE && cluster.Spec.RancherKubernetesEngineConfig == nil { + cluster.Spec.RancherKubernetesEngineConfig = &rketypes.RancherKubernetesEngineConfig{} + } + return p.Clusters.Update(cluster) + } + + return cluster, nil + +} + +func (p *Provisioner) backoffFailure(cluster *apimgmtv3.Cluster, spec *apimgmtv3.ClusterSpec) (bool, time.Duration) { + if cluster.Status.FailedSpec == nil { + return false, 0 + } + + if !reflect.DeepEqual(cluster.Status.FailedSpec, spec) { + return false, 0 + } + + if p.backoff.IsInBackOffSinceUpdate(cluster.Name, time.Now()) { + go func() { + time.Sleep(p.backoff.Get(cluster.Name)) + p.ClusterController.Enqueue("", cluster.Name) + }() + return true, p.backoff.Get(cluster.Name) + } + + return false, 0 +} + +var errKeyRotationFailed = errors.New("encryption key rotation failed, please restore your cluster from backup") + +func (p *Provisioner) reconcileCluster(cluster *apimgmtv3.Cluster, create bool) (*apimgmtv3.Cluster, error) { + if skipLocalK3sImported(cluster) { + reconcileACE(cluster) + return cluster, nil + } + + var ( + apiEndpoint, serviceAccountToken, caCert string + err error + ) + + if cluster.Name != "local" && !apimgmtv3.ClusterConditionServiceAccountMigrated.IsTrue(cluster) && + apimgmtv3.ClusterConditionProvisioned.IsTrue(cluster) { + driverName, err := p.validateDriver(cluster) + if err != nil { + return nil, err + } + + spec, _, err := p.getConfig(true, cluster.Spec, driverName, cluster.Name) + if err != nil { + return nil, err + } + + serviceAccountToken, err = p.generateServiceAccount(cluster, *spec) + if err != nil { + return nil, err + } + + secret, err := secretmigrator.NewMigrator(p.SecretLister, p.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, serviceAccountToken, cluster) + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + apimgmtv3.ClusterConditionServiceAccountMigrated.True(cluster) + + // Update the cluster in k8s + cluster, err = p.Clusters.Update(cluster) + if err != nil { + return nil, err + } + + err = p.removeLegacyServiceAccount(cluster, *spec) + if err != nil { + return nil, err + } + } + + p.setGenericConfigs(cluster) + + // Compute the new spec from the cluster resource. + spec, configChanged, err := p.getSpec(cluster) + if err != nil { + return cluster, err + } + + // If there is no change to cluster config and the force update annotation is not set to true, a reconcile is + // not necessary, so we can just return early. + forceUpdate := cluster.Annotations != nil && cluster.Annotations[RKEForceUpdate] == "true" + if !configChanged && !forceUpdate { + return cluster, nil + } + + if ok, delay := p.backoffFailure(cluster, spec); ok { + return cluster, &controller.ForgetError{Err: fmt.Errorf("backing off failure, delay: %v", delay)} + } + + logrus.Infof("Provisioning cluster [%s]", cluster.Name) + var updateTriggered bool + if create { + logrus.Infof("Creating cluster [%s]", cluster.Name) + // setting updateTriggered to true since rke up will be called on cluster create + updateTriggered = true + apiEndpoint, serviceAccountToken, caCert, err = p.driverCreate(cluster, *spec) + if err != nil && err.Error() == "cluster already exists" { + logrus.Infof("Create done, Updating cluster [%s]", cluster.Name) + apiEndpoint, serviceAccountToken, caCert, updateTriggered, err = p.driverUpdate(cluster, *spec, forceUpdate) + } + } else if spec.RancherKubernetesEngineConfig != nil && spec.RancherKubernetesEngineConfig.Restore.Restore { + logrus.Infof("Restoring cluster [%s] from backup", cluster.Name) + // cluster may need to be restored if key rotation fails + // ensure restore does not get short-circuited by key rotation since RKE checks for key rotation before restore + spec.RancherKubernetesEngineConfig.RotateEncryptionKey = false + apiEndpoint, serviceAccountToken, caCert, err = p.restoreClusterBackup(cluster, *spec) + } else if strings.Contains(apimgmtv3.ClusterConditionUpdated.GetMessage(cluster), errKeyRotationFailed.Error()) { + logrus.Infof("Key rotation failed, cluster needs to be restored. Skipping driver updates.") + return cluster, nil // prevent driver updates if the cluster needs to be restored + } else if spec.RancherKubernetesEngineConfig != nil && spec.RancherKubernetesEngineConfig.RotateCertificates != nil { + logrus.Infof("Rotating certificates for cluster [%s]", cluster.Name) + apiEndpoint, serviceAccountToken, caCert, updateTriggered, err = p.driverUpdate(cluster, *spec, forceUpdate) + } else if spec.RancherKubernetesEngineConfig != nil && spec.RancherKubernetesEngineConfig.RotateEncryptionKey { + logrus.Infof("Rotating encryption key for cluster [%s]", cluster.Name) + apiEndpoint, serviceAccountToken, caCert, updateTriggered, err = p.driverUpdate(cluster, *spec, forceUpdate) + if err != nil { + logrus.Errorf("[reconcileCluster] Encryption key rotation error: %v", err) + // an error during key rotation means the user has to restore their cluster + err = errKeyRotationFailed + } + } else { + logrus.Infof("Updating cluster [%s]", cluster.Name) + + // Attempt to manually trigger updating, otherwise it will not be triggered until after exiting reconcile + apimgmtv3.ClusterConditionUpdated.Unknown(cluster) + cluster, err = p.Clusters.Update(cluster) + if err != nil { + return cluster, fmt.Errorf("[reconcileCluster] Failed to update cluster [%s]: %v", cluster.Name, err) + } + + apiEndpoint, serviceAccountToken, caCert, updateTriggered, err = p.driverUpdate(cluster, *spec, forceUpdate) + } + // at this point we know the cluster has been modified in driverCreate/Update so reload + if newCluster, reloadErr := p.Clusters.Get(cluster.Name, metav1.GetOptions{}); reloadErr == nil { + cluster = newCluster + } + + cluster, recordErr := p.recordFailure(cluster, *spec, err) + if recordErr != nil { + return cluster, recordErr + } + + // from here on we want to return the cluster, not just nil, so that the error can be properly recorded + if err != nil { + return cluster, err + } + + err = p.removeLegacyServiceAccount(cluster, *spec) + if err != nil { + return nil, err + } + + apimgmtv3.ClusterConditionServiceAccountMigrated.True(cluster) + + secret, err := secretmigrator.NewMigrator(p.SecretLister, p.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, serviceAccountToken, cluster) + if err != nil { + return nil, err + } + + saved := false + for i := 0; i < 20; i++ { + cluster, err = p.Clusters.Get(cluster.Name, metav1.GetOptions{}) + if err != nil { + return cluster, err + } + + censoredSpec, err := p.censorGenericEngineConfig(*spec) + if err != nil { + return cluster, err + } + + cluster.Status.AppliedSpec = censoredSpec + cluster.Status.APIEndpoint = apiEndpoint + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + cluster.Status.CACert = caCert + resetRkeConfigFlags(cluster, updateTriggered) + + // initialize on first rke up + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil && cluster.Status.NodeVersion == 0 { + cluster.Status.NodeVersion++ + } + + // Remove the force reconcile annotation from the cluster since it has been reconciled successfully. + delete(cluster.Annotations, RKEForceUpdate) + + if cluster, err = p.Clusters.Update(cluster); err == nil { + saved = true + break + } else { + logrus.Errorf("failed to update cluster [%s]: %v", cluster.Name, err) + time.Sleep(2) + } + } + + if !saved { + return cluster, fmt.Errorf("failed to update cluster") + } + + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + logrus.Infof("Updated cluster [%s] with node version [%v]", cluster.Name, cluster.Status.NodeVersion) + p.reconcileForUpgrade(cluster.Name) + } + + logrus.Infof("Provisioned cluster [%s]", cluster.Name) + return cluster, nil +} + +func (p *Provisioner) reconcileForUpgrade(clusterName string) { + p.Nodes.Controller().Enqueue(clusterName, "upgrade_") +} + +func (p *Provisioner) setGenericConfigs(cluster *apimgmtv3.Cluster) { + if cluster.Spec.GenericEngineConfig == nil || cluster.Status.AppliedSpec.GenericEngineConfig == nil { + setGenericConfig := func(spec *apimgmtv3.ClusterSpec) { + if spec.GenericEngineConfig == nil { + if spec.AmazonElasticContainerServiceConfig != nil { + spec.GenericEngineConfig = spec.AmazonElasticContainerServiceConfig + (*spec.GenericEngineConfig)["driverName"] = "amazonelasticcontainerservice" + spec.AmazonElasticContainerServiceConfig = nil + } + + if spec.AzureKubernetesServiceConfig != nil { + spec.GenericEngineConfig = spec.AzureKubernetesServiceConfig + (*spec.GenericEngineConfig)["driverName"] = "azurekubernetesservice" + spec.AzureKubernetesServiceConfig = nil + } + + if spec.GoogleKubernetesEngineConfig != nil { + spec.GenericEngineConfig = spec.GoogleKubernetesEngineConfig + (*spec.GenericEngineConfig)["driverName"] = "googlekubernetesengine" + spec.GoogleKubernetesEngineConfig = nil + } + } + } + + setGenericConfig(&cluster.Spec) + setGenericConfig(&cluster.Status.AppliedSpec) + } +} + +func resetRkeConfigFlags(cluster *apimgmtv3.Cluster, updateTriggered bool) { + if cluster.Spec.RancherKubernetesEngineConfig != nil { + cluster.Spec.RancherKubernetesEngineConfig.RotateEncryptionKey = false + cluster.Spec.RancherKubernetesEngineConfig.RotateCertificates = nil + if cluster.Spec.RancherKubernetesEngineConfig.Restore.Restore { + cluster.Annotations[RkeRestoreAnnotation] = "true" + cluster.Status.NodeVersion++ + } + cluster.Spec.RancherKubernetesEngineConfig.Restore = rketypes.RestoreConfig{} + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.RotateCertificates = nil + cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Restore = rketypes.RestoreConfig{} + } + if !updateTriggered { + return + } + if cluster.Status.Capabilities.TaintSupport == nil || !*cluster.Status.Capabilities.TaintSupport { + supportsTaints := true + cluster.Status.Capabilities.TaintSupport = &supportsTaints + } + } +} + +func copyMap(toCopy apimgmtv3.MapStringInterface) apimgmtv3.MapStringInterface { + newMap := apimgmtv3.MapStringInterface{} + + for k, v := range toCopy { + newMap[k] = v + } + + return newMap +} + +func (p *Provisioner) censorGenericEngineConfig(input apimgmtv3.ClusterSpec) (apimgmtv3.ClusterSpec, error) { + if input.GenericEngineConfig == nil { + // nothing to do + return input, nil + } + + config := copyMap(*input.GenericEngineConfig) + driverName, ok := config[DriverNameField].(string) + if !ok { + // can't figure out driver type so blank out the whole thing + logrus.Warnf("cluster %v has a generic engine config but no driver type field; can't hide password "+ + "fields so removing the entire config", input.DisplayName) + input.GenericEngineConfig = nil + return input, nil + } + + driver, err := p.KontainerDriverLister.Get("", driverName) + if err != nil { + return apimgmtv3.ClusterSpec{}, err + } + + var schemaName string + if driver.Spec.BuiltIn { + schemaName = driver.Status.DisplayName + "Config" + } else { + schemaName = driver.Status.DisplayName + "EngineConfig" + } + + kontainerDriverSchema, err := p.DynamicSchemasLister.Get("", strings.ToLower(schemaName)) + if err != nil { + return apimgmtv3.ClusterSpec{}, fmt.Errorf("error getting dynamic schema %v", err) + } + + for key := range config { + field := kontainerDriverSchema.Spec.ResourceFields[key] + if field.Type == "password" { + delete(config, key) + } + } + + input.GenericEngineConfig = &config + return input, nil +} + +func skipLocalK3sImported(cluster *apimgmtv3.Cluster) bool { + return cluster.Status.Driver == apimgmtv3.ClusterDriverLocal || + cluster.Status.Driver == apimgmtv3.ClusterDriverImported || + cluster.Status.Driver == apimgmtv3.ClusterDriverK3s || + cluster.Status.Driver == apimgmtv3.ClusterDriverK3os || + cluster.Status.Driver == apimgmtv3.ClusterDriverRke2 || + cluster.Status.Driver == apimgmtv3.ClusterDriverRancherD +} + +func (p *Provisioner) getConfig(reconcileRKE bool, spec apimgmtv3.ClusterSpec, driverName, clusterName string) (*apimgmtv3.ClusterSpec, interface{}, error) { + var v interface{} + if spec.GenericEngineConfig == nil { + if spec.RancherKubernetesEngineConfig != nil { + var err error + v, err = convert.EncodeToMap(spec.RancherKubernetesEngineConfig) + if err != nil { + return nil, nil, err + } + } else { + v = map[string]interface{}{} + } + } else { + v = *spec.GenericEngineConfig + } + + if driverName == apimgmtv3.ClusterDriverRKE && spec.RancherKubernetesEngineConfig != nil { + spec.RancherKubernetesEngineConfig = spec.RancherKubernetesEngineConfig.DeepCopy() + + if reconcileRKE { + nodes, err := p.reconcileRKENodes(clusterName) + if err != nil { + return nil, nil, err + } + spec.RancherKubernetesEngineConfig.Nodes = nodes + } + + systemImages, err := p.getSystemImages(spec) + if err != nil { + return nil, nil, err + } + + spec.RancherKubernetesEngineConfig.SystemImages = *systemImages + data, _ := convert.EncodeToMap(spec) + v, _ = data[RKEDriverKey] + } + + return &spec, v, nil +} + +func (p *Provisioner) validateDriver(cluster *apimgmtv3.Cluster) (string, error) { + oldDriver := cluster.Status.Driver + + if oldDriver == apimgmtv3.ClusterDriverImported { + return apimgmtv3.ClusterDriverImported, nil + } + + newDriver, err := kontainerdriver.GetDriver(cluster, p.KontainerDriverLister) + if err != nil { + return "", err + } + + if oldDriver == "" && newDriver == "" { + return newDriver, nil + } + + if oldDriver == "" { + return newDriver, nil + } + + if newDriver == "" { + return "", &controller.ForgetError{ + Err: fmt.Errorf("waiting for nodes"), + Reason: "Pending", + } + } + + if oldDriver != newDriver { + return newDriver, fmt.Errorf("driver change from %s to %s not allowed", oldDriver, newDriver) + } + + return newDriver, nil +} + +func (p *Provisioner) getSystemImages(spec apimgmtv3.ClusterSpec) (*rketypes.RKESystemImages, error) { + version := spec.RancherKubernetesEngineConfig.Version + if version == "" { + return nil, fmt.Errorf("kubernetes version (spec.rancherKubernetesEngineConfig.kubernetesVersion) is unset") + } + // fetch system images from settings + systemImages, err := kd.GetRKESystemImages(version, p.RKESystemImagesLister, p.RKESystemImages) + if err != nil { + return nil, fmt.Errorf("failed to find system images for version %s: %v", version, err) + } + + privateRegistry := util.GetPrivateRegistryURL(&apimgmtv3.Cluster{Spec: spec}) + if privateRegistry == "" { + return &systemImages, nil + } + + // prepend private repo + imagesMap, err := convert.EncodeToMap(systemImages) + if err != nil { + return nil, err + } + updatedMap := make(map[string]interface{}) + for key, value := range imagesMap { + newValue := fmt.Sprintf("%s/%s", privateRegistry, value) + updatedMap[key] = newValue + } + // Decoding updateMap to systemImages using json marshal/unmarshal to honor field names + updatedByte, err := json.Marshal(updatedMap) + if err != nil { + return nil, err + } + err = json.Unmarshal(updatedByte, &systemImages) + if err != nil { + return nil, err + } + logrus.Debugf("Updated system images to use private registry [%s]: %#v", privateRegistry, systemImages) + return &systemImages, nil +} + +// getSpec computes the spec from the given cluster. Returns an error if the spec could not be computed. Otherwise, +// returns the spec and a boolean that will be true if the cluster config has changed and false otherwise. +func (p *Provisioner) getSpec(cluster *apimgmtv3.Cluster) (spec *apimgmtv3.ClusterSpec, configChanged bool, err error) { + driverName, err := p.validateDriver(cluster) + if err != nil { + return nil, false, err + } + + censoredOldSpec, err := p.censorGenericEngineConfig(cluster.Status.AppliedSpec) + if err != nil { + return nil, false, err + } + + _, oldConfig, err := p.getConfig(false, censoredOldSpec, driverName, cluster.Name) + if err != nil { + return nil, false, err + } + + censoredSpec, err := p.censorGenericEngineConfig(cluster.Spec) + if err != nil { + return nil, false, err + } + + _, newConfig, err := p.getConfig(true, censoredSpec, driverName, cluster.Name) + if err != nil { + return nil, false, err + } + + newSpec, _, err := p.getConfig(true, cluster.Spec, driverName, cluster.Name) + return newSpec, !reflect.DeepEqual(oldConfig, newConfig), err +} + +func (p *Provisioner) reconcileRKENodes(clusterName string) ([]rketypes.RKEConfigNode, error) { + machines, err := p.NodeLister.List(clusterName, labels.Everything()) + if err != nil { + return nil, err + } + + var etcd, controlplane, worker bool + var nodes []rketypes.RKEConfigNode + for _, machine := range machines { + if machine.DeletionTimestamp != nil { + continue + } + + if apimgmtv3.NodeConditionProvisioned.IsUnknown(machine) && (machine.Spec.Etcd || machine.Spec.ControlPlane) { + return nil, &controller.ForgetError{ + Err: fmt.Errorf("waiting for %s to finish provisioning", machine.Spec.RequestedHostname), + Reason: "Provisioning", + } + } + + if machine.Status.NodeConfig == nil { + continue + } + + if len(machine.Status.NodeConfig.Role) == 0 { + continue + } + + if !apimgmtv3.NodeConditionProvisioned.IsTrue(machine) { + continue + } + + if slice.ContainsString(machine.Status.NodeConfig.Role, services.ETCDRole) { + etcd = true + } + if slice.ContainsString(machine.Status.NodeConfig.Role, services.ControlRole) { + controlplane = true + } + if slice.ContainsString(machine.Status.NodeConfig.Role, services.WorkerRole) { + worker = true + } + + node := *machine.Status.NodeConfig + if node.User == "" { + node.User = "root" + } + if node.Port == "" { + node.Port = "22" + } + if node.NodeName == "" { + node.NodeName = ref.FromStrings(machine.Namespace, machine.Name) + } + nodes = append(nodes, node) + } + + if !etcd || !controlplane || !worker { + return nil, &controller.ForgetError{ + Err: fmt.Errorf("waiting for etcd, controlplane and worker nodes to be registered"), + Reason: "Provisioning", + } + } + + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].NodeName < nodes[j].NodeName + }) + + return nodes, nil +} + +func (p *Provisioner) recordFailure(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec, err error) (*apimgmtv3.Cluster, error) { + if err == nil { + p.backoff.DeleteEntry(cluster.Name) + if cluster.Status.FailedSpec == nil { + return cluster, nil + } + + cluster.Status.FailedSpec = nil + return p.Clusters.Update(cluster) + } + + p.backoff.Next(cluster.Name, time.Now()) + cluster.Status.FailedSpec = &spec + newCluster, _ := p.Clusters.Update(cluster) + // mask the error + return newCluster, nil +} + +func (p *Provisioner) restoreClusterBackup(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec) (api string, token string, cert string, err error) { + snapshot := strings.Split(spec.RancherKubernetesEngineConfig.Restore.SnapshotName, ":")[1] + backup, err := p.Backups.Get(cluster.Name, snapshot) + if err != nil { + return "", "", "", err + } + if backup.Spec.ClusterID != cluster.Name { + return "", "", "", fmt.Errorf("snapshot [%s] is not a backup of cluster [%s]", backup.Name, cluster.Name) + } + + api, token, cert, err = p.driverRestore(cluster, spec, GetBackupFilename(backup)) + if err != nil { + return "", "", "", err + } + // checking if we have s3 config and that it's not inconsistent. This happens + // when restore is performed with invalid credentials and then the cluster is updated to fix it. + if spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + s3Config := cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig + appliedS3Conf := cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig + + if !reflect.DeepEqual(s3Config, appliedS3Conf) { + logrus.Infof("updated spec during restore detected for cluster [%s], update is required", cluster.Name) + api, token, cert, _, err = p.driverUpdate(cluster, spec, false) + } + } + return api, token, cert, err +} + +func GetBackupFilenameFromURL(URL string) (string, error) { + if !isValidURL(URL) { + return "", fmt.Errorf("URL is not valid: [%s]", URL) + } + parsedURL, err := url.Parse(URL) + if err != nil { + return "", err + } + if parsedURL.Path == "" { + return "", fmt.Errorf("No path found in URL: [%s]", URL) + } + extractedPath := path.Base(parsedURL.Path) + return extractedPath, nil +} + +// isValidURL tests a string to determine if it is a url or not. +// https://golangcode.com/how-to-check-if-a-string-is-a-url/ +func isValidURL(URL string) bool { + _, err := url.ParseRequestURI(URL) + if err != nil { + return false + } + return true +} + +func GetBackupFilename(backup *apimgmtv3.EtcdBackup) string { + snapshot := backup.Name + if filename, err := GetBackupFilenameFromURL(backup.Spec.Filename); err == nil { // s3 file + // need to remove extension + snapshot = strings.TrimSuffix(filename, path.Ext(filename)) + } else if len(backup.Spec.Filename) != 0 { // not s3 url + snapshot = strings.TrimSuffix(backup.Spec.Filename, path.Ext(backup.Spec.Filename)) + } + return snapshot +} + +// transform an imported cluster into a k3s or k3os cluster using its discovered version +func (p *Provisioner) k3sBasedClusterConfig(cluster *apimgmtv3.Cluster, nodes []*apimgmtv3.Node) error { + // version is not found until cluster is provisioned + if cluster.Status.Driver == "" || cluster.Status.Version == nil || len(nodes) == 0 { + return &controller.ForgetError{ + Err: fmt.Errorf("waiting for full cluster configuration"), + Reason: "Pending"} + } + if cluster.Status.Driver == apimgmtv3.ClusterDriverK3s || + cluster.Status.Driver == apimgmtv3.ClusterDriverK3os || + cluster.Status.Driver == apimgmtv3.ClusterDriverRke2 || + cluster.Status.Driver == apimgmtv3.ClusterDriverRancherD || + imported.IsAdministratedByProvisioningCluster(cluster) { + return nil // no-op + } + isEmbedded := cluster.Status.Driver == apimgmtv3.ClusterDriverLocal + + if strings.Contains(cluster.Status.Version.String(), "k3s") { + for _, node := range nodes { + if _, ok := node.Status.NodeLabels["k3os.io/mode"]; ok { + cluster.Status.Driver = apimgmtv3.ClusterDriverK3os + break + } + } + if cluster.Status.Driver != apimgmtv3.ClusterDriverK3os { + cluster.Status.Driver = apimgmtv3.ClusterDriverK3s + } + // only set these values on init, and not for embedded clusters as those shouldn't be upgraded + if cluster.Spec.K3sConfig == nil && !isEmbedded { + cluster.Spec.K3sConfig = &apimgmtv3.K3sConfig{ + Version: cluster.Status.Version.String(), + } + cluster.Spec.K3sConfig.SetStrategy(1, 1) + } + } else if strings.Contains(cluster.Status.Version.String(), "rke2") { + + _, err := p.DaemonsetLister.Get("cattle-system", "rancher") + if apierrors.IsNotFound(err) { + cluster.Status.Driver = apimgmtv3.ClusterDriverRke2 + } else if err != nil { + return err + } else { + cluster.Status.Driver = apimgmtv3.ClusterDriverRancherD + return nil + } + if cluster.Spec.Rke2Config == nil { + cluster.Spec.Rke2Config = &apimgmtv3.Rke2Config{ + Version: cluster.Status.Version.String(), + } + cluster.Spec.Rke2Config.SetStrategy(1, 1) + } + } + return nil +} + +func reconcileACE(cluster *apimgmtv3.Cluster) { + if imported.IsAdministratedByProvisioningCluster(cluster) || cluster.Status.Driver == apimgmtv3.ClusterDriverRke2 || cluster.Status.Driver == apimgmtv3.ClusterDriverK3s { + cluster.Status.AppliedSpec.LocalClusterAuthEndpoint = cluster.Spec.LocalClusterAuthEndpoint + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/rke_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/rke_store.go new file mode 100644 index 0000000..5fabe87 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/rke_store.go @@ -0,0 +1,95 @@ +package clusterprovisioner + +import ( + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + kontainerengine "github.com/rancher/rancher/pkg/kontainer-engine/drivers/rke" + "github.com/rancher/rancher/pkg/namespace" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/rke/types/kdm" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type rkeStore struct { + AddonLister v3.RkeAddonLister + Addons v3.RkeAddonInterface + SvcOptionLister v3.RkeK8sServiceOptionLister + SvcOptions v3.RkeK8sServiceOptionInterface + SystemImagesLister v3.RkeK8sSystemImageLister + SystemImages v3.RkeK8sSystemImageInterface +} + +var addonMap = map[string]bool{ + kdm.Calico: true, + kdm.Flannel: true, + kdm.Canal: true, + kdm.Weave: true, + kdm.NginxIngress: true, + kdm.MetricsServer: true, + kdm.KubeDNS: true, + kdm.CoreDNS: true, +} + +func NewDataStore(addonLister v3.RkeAddonLister, addons v3.RkeAddonInterface, + svcOptionLister v3.RkeK8sServiceOptionLister, svcOptions v3.RkeK8sServiceOptionInterface, + sysImageLister v3.RkeK8sSystemImageLister, sysImages v3.RkeK8sSystemImageInterface) kontainerengine.Store { + return &rkeStore{ + AddonLister: addonLister, + Addons: addons, + SvcOptionLister: svcOptionLister, + SvcOptions: svcOptions, + SystemImagesLister: sysImageLister, + SystemImages: sysImages, + } +} + +func (a *rkeStore) GetAddonTemplates(k8sVersion string) (map[string]interface{}, error) { + data := map[string]interface{}{} + sysImage, err := a.SystemImagesLister.Get(namespace.GlobalNamespace, k8sVersion) + if err != nil { + if !errors.IsNotFound(err) { + logrus.Errorf("getAddonTemplates: error finding system image for %s %v", k8sVersion, err) + return data, err + } + sysImage, err = a.SystemImages.GetNamespaced(namespace.GlobalNamespace, k8sVersion, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("getAddonTemplates: error finding system image for %s %v", k8sVersion, err) + return data, err + } + } + for k, v := range sysImage.Labels { + if _, ok := addonMap[k]; !ok { + continue + } + template, err := kd.GetRKEAddonTemplate(v, a.AddonLister, a.Addons) + if err != nil { + logrus.Errorf("getAddonTemplates: k8sVersion %s addon %s [%v]", k8sVersion, v, err) + return data, err + } + if template != "" { + data[k] = template + } + } + return data, nil +} + +func (a *rkeStore) GetServiceOptions(k8sVersion string) (map[string]*rketypes.KubernetesServicesOptions, error) { + linuxSvcOptions, err := kd.GetRKEK8sServiceOptions(k8sVersion, a.SvcOptionLister, a.SvcOptions, a.SystemImagesLister, a.SystemImages, kd.Linux) + if err != nil { + logrus.Errorf("getLinuxK8sServiceOptions: k8sVersion %s [%v]", k8sVersion, err) + return nil, err + } + + windowsSvcOptions, err := kd.GetRKEK8sServiceOptions(k8sVersion, a.SvcOptionLister, a.SvcOptions, a.SystemImagesLister, a.SystemImages, kd.Windows) + if err != nil { + logrus.Errorf("getWindowsK8sServiceOptions: k8sVersion %s [%v]", k8sVersion, err) + return nil, err + } + + return map[string]*rketypes.KubernetesServicesOptions{ + "k8s-service-options": linuxSvcOptions, + "k8s-windows-service-options": windowsSvcOptions, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/store.go new file mode 100644 index 0000000..7490856 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterprovisioner/store.go @@ -0,0 +1,65 @@ +package clusterprovisioner + +import ( + "encoding/json" + + "github.com/rancher/rancher/pkg/encryptedstore" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/kontainer-engine/cluster" + "github.com/sirupsen/logrus" +) + +const ( + dataKey = "cluster" +) + +func NewPersistentStore(namespaces v1.NamespaceInterface, secretsGetter v1.SecretsGetter) cluster.PersistentStore { + store, err := encryptedstore.NewGenericEncryptedStore("c-", "", namespaces, secretsGetter) + if err != nil { + logrus.Fatal(err) + } + + return &engineStore{ + store: store, + } +} + +type engineStore struct { + store *encryptedstore.GenericEncryptedStore +} + +func (s *engineStore) GetStatus(name string) (string, error) { + cls, err := s.Get(name) + if err != nil { + return "", err + } + return cls.Status, nil +} + +func (s *engineStore) Get(name string) (cluster.Cluster, error) { + cluster := cluster.Cluster{} + data, err := s.store.Get(name) + if err != nil { + return cluster, err + } + return cluster, json.Unmarshal([]byte(data[dataKey]), &cluster) +} + +func (s *engineStore) Remove(name string) error { + return s.store.Remove(name) +} + +func (s *engineStore) Store(cluster cluster.Cluster) error { + content, err := json.Marshal(cluster) + if err != nil { + return err + } + return s.store.Set(cluster.Name, map[string]string{ + dataKey: string(content), + }) +} + +func (s *engineStore) PersistStatus(cluster cluster.Cluster, status string) error { + cluster.Status = status + return s.Store(cluster) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstats/statsaggregator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstats/statsaggregator.go new file mode 100644 index 0000000..e9903be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstats/statsaggregator.go @@ -0,0 +1,335 @@ +package clusterstats + +import ( + "context" + "reflect" + "regexp" + "strconv" + "time" + + "github.com/pkg/errors" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/clustermanager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + nodeRoleControlPlane = "node-role.kubernetes.io/controlplane" + nodeRoleControlPlaneHyphen = "node-role.kubernetes.io/control-plane" + nodeRoleETCD = "node-role.kubernetes.io/etcd" + nodeRoleMaster = "node-role.kubernetes.io/master" + agentVersionUpgraded = "agent.cluster.cattle.io/upgraded-v1.22" +) + +var numericReg = regexp.MustCompile("[^0-9]") + +type StatsAggregator struct { + NodesLister v3.NodeLister + Clusters v3.ClusterInterface + ClusterManager *clustermanager.Manager +} + +type ClusterNodeData struct { + Capacity v1.ResourceList + Allocatable v1.ResourceList + Requested v1.ResourceList + Limits v1.ResourceList + ConditionNoDiskPressureStatus v1.ConditionStatus + ConditionNoMemoryPressureStatus v1.ConditionStatus +} + +func Register(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + clustersClient := management.Management.Clusters("") + machinesClient := management.Management.Nodes("") + + s := &StatsAggregator{ + NodesLister: machinesClient.Controller().Lister(), + Clusters: clustersClient, + ClusterManager: clusterManager, + } + + clustersClient.AddHandler(ctx, "cluster-stats", s.sync) + machinesClient.AddHandler(ctx, "cluster-stats", s.machineChanged) +} + +func (s *StatsAggregator) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster == nil { + return nil, nil + } + + return nil, s.aggregate(cluster, cluster.Name) +} + +func (s *StatsAggregator) aggregate(cluster *v3.Cluster, clusterName string) error { + allMachines, err := s.NodesLister.List(cluster.Name, labels.Everything()) + if err != nil { + return err + } + + workerCounts := make(map[string]int) + var machines []*v3.Node + // only include worker nodes + for _, m := range allMachines { + // if none are set, then nodes syncer has not completed + if !m.Spec.Worker && !m.Spec.ControlPlane && !m.Spec.Etcd { + return errors.Errorf("node role cannot be determined because node %s has not finished syncing. retrying", m.Status.NodeName) + } + if isTaintedNoExecuteNoSchedule(m) && !m.Spec.Worker { + continue + } + if m.Spec.InternalNodeSpec.Unschedulable { + continue + } + + if os, ok := m.Status.NodeLabels["kubernetes.io/os"]; ok && m.Spec.Worker { + workerCounts[os]++ + } + + machines = append(machines, m) + } + + origStatus := cluster.Status.DeepCopy() + cluster = cluster.DeepCopy() + + cluster.Status.NodeCount = len(allMachines) + if c, ok := workerCounts["windows"]; ok { + cluster.Status.WindowsWorkerCount = c + } + if c, ok := workerCounts["linux"]; ok { + cluster.Status.LinuxWorkerCount = c + } + + // capacity keys + pods, mem, cpu := resource.Quantity{}, resource.Quantity{}, resource.Quantity{} + // allocatable keys + apods, amem, acpu := resource.Quantity{}, resource.Quantity{}, resource.Quantity{} + // requested keys + rpods, rmem, rcpu := resource.Quantity{}, resource.Quantity{}, resource.Quantity{} + // limited keys + lpods, lmem, lcpu := resource.Quantity{}, resource.Quantity{}, resource.Quantity{} + + condDisk := v1.ConditionTrue + condMem := v1.ConditionTrue + + for _, machine := range machines { + capacity := machine.Status.InternalNodeStatus.Capacity + if capacity != nil { + pods.Add(*capacity.Pods()) + mem.Add(*capacity.Memory()) + cpu.Add(*capacity.Cpu()) + } + allocatable := machine.Status.InternalNodeStatus.Allocatable + if allocatable != nil { + apods.Add(*allocatable.Pods()) + amem.Add(*allocatable.Memory()) + acpu.Add(*allocatable.Cpu()) + } + requested := machine.Status.Requested + if requested != nil { + rpods.Add(*requested.Pods()) + rmem.Add(*requested.Memory()) + rcpu.Add(*requested.Cpu()) + } + limits := machine.Status.Limits + if limits != nil { + lpods.Add(*limits.Pods()) + lmem.Add(*limits.Memory()) + lcpu.Add(*limits.Cpu()) + } + + if condDisk == v1.ConditionTrue && v32.ClusterConditionNoDiskPressure.IsTrue(machine) { + condDisk = v1.ConditionFalse + } + if condMem == v1.ConditionTrue && v32.ClusterConditionNoMemoryPressure.IsTrue(machine) { + condMem = v1.ConditionFalse + } + } + + cluster.Status.Capacity = v1.ResourceList{v1.ResourcePods: pods, v1.ResourceMemory: mem, v1.ResourceCPU: cpu} + cluster.Status.Allocatable = v1.ResourceList{v1.ResourcePods: apods, v1.ResourceMemory: amem, v1.ResourceCPU: acpu} + cluster.Status.Requested = v1.ResourceList{v1.ResourcePods: rpods, v1.ResourceMemory: rmem, v1.ResourceCPU: rcpu} + cluster.Status.Limits = v1.ResourceList{v1.ResourcePods: lpods, v1.ResourceMemory: lmem, v1.ResourceCPU: lcpu} + if condDisk == v1.ConditionTrue { + v32.ClusterConditionNoDiskPressure.True(cluster) + } else { + v32.ClusterConditionNoDiskPressure.False(cluster) + } + if condMem == v1.ConditionTrue { + v32.ClusterConditionNoMemoryPressure.True(cluster) + } else { + v32.ClusterConditionNoMemoryPressure.False(cluster) + } + + var oldVersion int + if cluster.Status.Version != nil { + oldVersion, err = minorVersion(cluster) + if err != nil { + return err + } + } + versionChanged := s.updateVersion(cluster) + + if statusChanged(origStatus, &cluster.Status) || versionChanged { + _, err = s.Clusters.Update(cluster) + return err + } + + // If the cluster went through an upgrade from <=1.21 to >=1.22, restart + // the cluster agent in order to restart controllers that will no longer work + // with the new API. + if versionChanged && !cluster.Spec.Internal { + newVersion, err := minorVersion(cluster) + if err != nil { + return err + } + if newVersion >= 22 && oldVersion <= 21 { + err := s.restartAgentDeployment(cluster) + if err != nil { + return err + } + } + } + + return nil +} + +func minorVersion(cluster *v3.Cluster) (int, error) { + minorVersion := numericReg.ReplaceAllString(cluster.Status.Version.Minor, "") + return strconv.Atoi(minorVersion) +} + +func (s *StatsAggregator) updateVersion(cluster *v3.Cluster) bool { + updated := false + userContext, err := s.ClusterManager.UserContextNoControllersReconnecting(cluster.Name, false) + if err == nil { + callWithTimeout(func() { + // This has the tendency to timeout + version, err := userContext.K8sClient.Discovery().ServerVersion() + if err == nil { + isClusterVersionOk := cluster.Status.Version != nil + isNewVersionOk := version != nil + if isClusterVersionOk != isNewVersionOk || + (isClusterVersionOk && *cluster.Status.Version != *version) { + cluster.Status.Version = version + updated = true + } + } + }) + } + return updated +} + +// restartAgentDeployment sets an annotation on the cluster agent deployment template +// which will force a restart of the deployment. This is used when the cluster is +// upgraded to >=1.22 to ensure that controllers that are not compatible with v1.22 APIs +// are stopped, and controllers that are only compatible with v1.22 are started. +func (s *StatsAggregator) restartAgentDeployment(cluster *v3.Cluster) error { + userContext, err := s.ClusterManager.UserContextNoControllers(cluster.Name) + if err != nil { + return err + } + deployment, err := userContext.Apps.Deployments("cattle-system").Get("cattle-cluster-agent", metav1.GetOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + if apierrors.IsNotFound(err) { + return nil + } + // Add annotation to the agent deployment template in order to force a restart + if deployment.Spec.Template.Annotations == nil { + deployment.Spec.Template.Annotations = make(map[string]string) + } + if deployment.Spec.Template.Annotations[agentVersionUpgraded] != "true" { + logrus.Tracef("statsAggregator: updated cluster %s to v1.22, annotating agent deployment", cluster.Name) + toUpdate := deployment.DeepCopy() + toUpdate.Spec.Template.Annotations[agentVersionUpgraded] = "true" + _, err = userContext.Apps.Deployments("cattle-system").Update(toUpdate) + if err != nil { + return err + } + } + return nil +} + +func statusChanged(existingCluster, newCluster *v32.ClusterStatus) bool { + if !reflect.DeepEqual(existingCluster.Conditions, newCluster.Conditions) { + return true + } + + if existingCluster.LinuxWorkerCount != newCluster.LinuxWorkerCount || + existingCluster.WindowsWorkerCount != newCluster.WindowsWorkerCount || + existingCluster.NodeCount != newCluster.NodeCount { + return true + } + + if resourceListChanged(existingCluster.Capacity, newCluster.Capacity) { + return true + } + + if resourceListChanged(existingCluster.Allocatable, newCluster.Allocatable) { + return true + } + + if resourceListChanged(existingCluster.Requested, newCluster.Requested) { + return true + } + + if resourceListChanged(existingCluster.Limits, newCluster.Limits) { + return true + } + + return false +} + +func resourceListChanged(oldList, newList v1.ResourceList) bool { + if len(oldList) != len(newList) { + return true + } + + for k, v := range oldList { + if v.Cmp(newList[k]) != 0 { + return true + } + } + + return false +} + +func callWithTimeout(do func()) { + done := make(chan struct{}) + go func() { + defer close(done) + do() + }() + + select { + case <-done: + case <-time.After(15 * time.Second): + } +} + +func (s *StatsAggregator) machineChanged(key string, machine *v3.Node) (runtime.Object, error) { + if machine != nil { + s.Clusters.Controller().Enqueue("", machine.Namespace) + } + return nil, nil +} + +func isTaintedNoExecuteNoSchedule(m *v3.Node) bool { + for _, taint := range m.Spec.InternalNodeSpec.Taints { + isETCDOrControlPlane := taint.Key == nodeRoleControlPlane || taint.Key == nodeRoleETCD || + taint.Key == nodeRoleControlPlaneHyphen || taint.Key == nodeRoleMaster + if isETCDOrControlPlane && (taint.Effect == "NoSchedule" || taint.Effect == "NoExecute") { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstatus/temporarycredentials.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstatus/temporarycredentials.go new file mode 100644 index 0000000..aef875a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterstatus/temporarycredentials.go @@ -0,0 +1,55 @@ +package clusterstatus + +import ( + "context" + "fmt" + "strconv" + + "k8s.io/apimachinery/pkg/runtime" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +const TemporaryCredentialsAnnotationKey = "clusterstatus.management.cattle.io/temporary-security-credentials" + +func Register(ctx context.Context, management *config.ManagementContext) { + c := &clusterAnnotations{ + clusters: management.Management.Clusters(""), + } + + management.Management.Clusters("").AddHandler(ctx, "temporary-credentials", c.sync) +} + +type clusterAnnotations struct { + clusters v3.ClusterInterface +} + +func (cd *clusterAnnotations) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if key == "" || cluster == nil || cluster.DeletionTimestamp != nil { + return nil, nil + } + + if genericConfig := cluster.Spec.GenericEngineConfig; genericConfig != nil { + eksConfig := *genericConfig + if eksConfig["driverName"] != "amazonelasticcontainerservice" { + return nil, nil + } + + newValue := strconv.FormatBool(eksConfig["sessionToken"] != "" && eksConfig["sessionToken"] != nil) + original := cluster + cluster = original.DeepCopy() + + if cluster.Annotations == nil { + cluster.Annotations = make(map[string]string) + } + + cluster.Annotations[TemporaryCredentialsAnnotationKey] = newValue + _, err := cd.clusters.Update(cluster) + if err != nil { + return nil, fmt.Errorf("error updating temporary credentials annotation: %v", err) + } + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/clustertemplate_rbac.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/clustertemplate_rbac.go new file mode 100644 index 0000000..12026dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/clustertemplate_rbac.go @@ -0,0 +1,115 @@ +package clustertemplate + +import ( + "context" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + creatorIDAnn = "field.cattle.io/creatorId" + ctLabel = "io.cattle.field/clusterTemplateId" +) + +type clusterTemplateController struct { + clusterTemplates v3.ClusterTemplateInterface + clusterTemplateRevisionLister v3.ClusterTemplateRevisionLister + managementContext *config.ManagementContext +} + +type clusterTemplateRevisionController struct { + clusterTemplateRevisions v3.ClusterTemplateRevisionInterface + clusterTemplateRevisionLister v3.ClusterTemplateRevisionLister + clusterTemplateLister v3.ClusterTemplateLister + managementContext *config.ManagementContext +} + +func registerRbacControllers(ctx context.Context, mgmt *config.ManagementContext) { + ct := clusterTemplateController{ + managementContext: mgmt, + clusterTemplates: mgmt.Management.ClusterTemplates(""), + clusterTemplateRevisionLister: mgmt.Management.ClusterTemplateRevisions("").Controller().Lister(), + } + ct.clusterTemplates.AddHandler(ctx, "cluster-template-rbac-controller", ct.sync) + + ctr := clusterTemplateRevisionController{ + managementContext: mgmt, + clusterTemplateRevisions: mgmt.Management.ClusterTemplateRevisions(""), + clusterTemplateRevisionLister: mgmt.Management.ClusterTemplateRevisions("").Controller().Lister(), + clusterTemplateLister: mgmt.Management.ClusterTemplates("").Controller().Lister(), + } + ctr.clusterTemplateRevisions.AddHandler(ctx, "cluster-template-rev-rbac-controller", ctr.sync) +} + +func (ct *clusterTemplateController) sync(key string, clusterTemplate *v3.ClusterTemplate) (runtime.Object, error) { + if clusterTemplate == nil || clusterTemplate.DeletionTimestamp != nil { + return nil, nil + } + metaAccessor, err := meta.Accessor(clusterTemplate) + if err != nil { + return clusterTemplate, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return clusterTemplate, fmt.Errorf("clusterTemplate %v has no creatorId annotation", metaAccessor.GetName()) + } + + if err := rbac.CreateRoleAndRoleBinding(rbac.ClusterTemplateResource, v3.ClusterTemplateGroupVersionKind.Kind, clusterTemplate.Name, namespace.GlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + clusterTemplate.UID, + clusterTemplate.Spec.Members, ct.managementContext); err != nil { + return nil, err + } + + //see if any revision exists and call CreateRoleAndRoleBinding for it so that if this is an update request adding/removing members, + //it reflects on the permissions for revisions too + revisions, err := ct.clusterTemplateRevisionLister.List(namespace.GlobalNamespace, labels.SelectorFromSet(map[string]string{ctLabel: clusterTemplate.Name})) + if err != nil && !apierrors.IsNotFound(err) { + return clusterTemplate, err + } + for _, rev := range revisions { + ct.managementContext.Management.ClusterTemplateRevisions("").Controller().Enqueue(namespace.GlobalNamespace, rev.Name) + } + return clusterTemplate, nil +} + +func (ctr *clusterTemplateRevisionController) sync(key string, clusterTemplateRev *v3.ClusterTemplateRevision) (runtime.Object, error) { + if clusterTemplateRev == nil || clusterTemplateRev.DeletionTimestamp != nil { + return nil, nil + } + metaAccessor, err := meta.Accessor(clusterTemplateRev) + if err != nil { + return clusterTemplateRev, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return clusterTemplateRev, fmt.Errorf("clusterTemplateRevision %v has no creatorId annotation", metaAccessor.GetName()) + } + // get members field from clusterTemplate + split := strings.SplitN(clusterTemplateRev.Spec.ClusterTemplateName, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("error in splitting clusterTemplate name %v", clusterTemplateRev.Spec.ClusterTemplateName) + } + templateName := split[1] + clusterTemp, err := ctr.clusterTemplateLister.Get(namespace.GlobalNamespace, templateName) + if err != nil { + return nil, err + } + if err := rbac.CreateRoleAndRoleBinding(rbac.ClusterTemplateRevisionResource, v3.ClusterTemplateRevisionGroupVersionKind.Kind, clusterTemplateRev.Name, namespace.GlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + clusterTemplateRev.UID, + clusterTemp.Spec.Members, ctr.managementContext); err != nil { + return nil, err + } + return clusterTemplateRev, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/revision_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/revision_controller.go new file mode 100644 index 0000000..083df6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clustertemplate/revision_controller.go @@ -0,0 +1,97 @@ +package clustertemplate + +import ( + "context" + + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + RevisionController = "mgmt-cluster-template-revision-controller" + clusterTemplateLabel = "io.cattle.field/clusterTemplateId" +) + +type RevController struct { + clusterTemplates v3.ClusterTemplateInterface + clusterTemplateLister v3.ClusterTemplateLister + clusterTemplateRevisions v3.ClusterTemplateRevisionInterface + clusterTemplateRevisionLister v3.ClusterTemplateRevisionLister +} + +func newRevController(ctx context.Context, mgmt *config.ManagementContext) *RevController { + n := &RevController{ + clusterTemplates: mgmt.Management.ClusterTemplates(namespace.GlobalNamespace), + clusterTemplateLister: mgmt.Management.ClusterTemplates(namespace.GlobalNamespace).Controller().Lister(), + clusterTemplateRevisions: mgmt.Management.ClusterTemplateRevisions(namespace.GlobalNamespace), + clusterTemplateRevisionLister: mgmt.Management.ClusterTemplateRevisions(namespace.GlobalNamespace).Controller().Lister(), + } + return n +} + +func Register(ctx context.Context, management *config.ManagementContext) { + n := newRevController(ctx, management) + if n != nil { + management.Management.ClusterTemplateRevisions("").AddHandler(ctx, RevisionController, n.sync) + } + registerRbacControllers(ctx, management) +} + +// sync is called periodically and on real updates +func (n *RevController) sync(key string, obj *v3.ClusterTemplateRevision) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + if obj.Spec.ClusterTemplateName == "" { + return nil, nil + } + //load the template + split := strings.SplitN(obj.Spec.ClusterTemplateName, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("error in splitting clusterTemplate name %v", obj.Spec.ClusterTemplateName) + } + templateName := split[1] + template, err := n.clusterTemplateLister.Get(namespace.GlobalNamespace, templateName) + if err != nil { + return nil, err + } + if template.Spec.DefaultRevisionName != "" { + return nil, nil + } + //if default is not set, set the revision to this revision if only one found + set := labels.Set(map[string]string{clusterTemplateLabel: templateName}) + revisionList, err := n.clusterTemplateRevisionLister.List(namespace.GlobalNamespace, set.AsSelector()) + if err != nil { + return nil, err + } + revisionCount := len(revisionList) + if revisionCount == 0 { + //check from etcd + revlist, err := n.clusterTemplateRevisions.List(metav1.ListOptions{LabelSelector: set.AsSelector().String()}) + if err != nil { + return nil, err + } + if len(revlist.Items) != 0 { + revisionCount = len(revlist.Items) + } + } + + if revisionCount == 1 { + templateCopy := template.DeepCopy() + templateCopy.Spec.DefaultRevisionName = namespace.GlobalNamespace + ":" + obj.Name + _, err := n.clusterTemplates.Update(templateCopy) + if err != nil { + return nil, err + } + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/aks_upstream_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/aks_upstream_spec.go new file mode 100644 index 0000000..c4db6de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/aks_upstream_spec.go @@ -0,0 +1,26 @@ +package clusterupstreamrefresher + +import ( + "context" + + akscontroller "github.com/rancher/aks-operator/controller" + aksv1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" +) + +func BuildAKSUpstreamSpec(secretsCache wranglerv1.SecretCache, secretClient wranglerv1.SecretClient, cluster *mgmtv3.Cluster) (*aksv1.AKSClusterConfigSpec, error) { + ctx := context.Background() + upstreamSpec, err := akscontroller.BuildUpstreamClusterState(ctx, secretsCache, secretClient, cluster.Spec.AKSConfig) + if err != nil { + return nil, err + } + + upstreamSpec.ClusterName = cluster.Spec.AKSConfig.ClusterName + upstreamSpec.ResourceLocation = cluster.Spec.AKSConfig.ResourceLocation + upstreamSpec.ResourceGroup = cluster.Spec.AKSConfig.ResourceGroup + upstreamSpec.AzureCredentialSecret = cluster.Spec.AKSConfig.AzureCredentialSecret + upstreamSpec.Imported = cluster.Spec.AKSConfig.Imported + + return upstreamSpec, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/cluster_upstream_refresher.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/cluster_upstream_refresher.go new file mode 100644 index 0000000..8299ba9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/cluster_upstream_refresher.go @@ -0,0 +1,298 @@ +package clusterupstreamrefresher + +import ( + "context" + "fmt" + "reflect" + "strconv" + "strings" + "time" + + aksv1 "github.com/rancher/aks-operator/pkg/apis/aks.cattle.io/v1" + eksv1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + gkev1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + noKEv2Provider = "none" + clusterLastRefreshTime = "clusters.management.cattle.io/ke-last-refresh" + refreshSettingFormat = "%s-refresh" +) + +type clusterRefreshController struct { + secretsCache wranglerv1.SecretCache + secretClient wranglerv1.SecretClient + clusterClient v3.ClusterClient + clusterCache v3.ClusterCache + clusterEnqueueAfter func(name string, duration time.Duration) +} + +// for other cloud drivers, please edit HERE +type clusterConfig struct { + aksConfig *aksv1.AKSClusterConfigSpec + eksConfig *eksv1.EKSClusterConfigSpec + gkeConfig *gkev1.GKEClusterConfigSpec +} + +func Register(ctx context.Context, wContext *wrangler.Context) { + c := clusterRefreshController{ + secretsCache: wContext.Core.Secret().Cache(), + secretClient: wContext.Core.Secret(), + clusterClient: wContext.Mgmt.Cluster(), + clusterCache: wContext.Mgmt.Cluster().Cache(), + clusterEnqueueAfter: wContext.Mgmt.Cluster().EnqueueAfter, + } + + wContext.Mgmt.Cluster().OnChange(ctx, "cluster-refresher-controller", c.onClusterChange) +} + +func (c *clusterRefreshController) onClusterChange(key string, cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil { + return cluster, nil + } + + provider, ready := getProviderAndReadyStatus(cluster) + if provider == noKEv2Provider || !ready { + return cluster, nil + } + + providerRefreshInterval, err := getProviderRefreshInterval(provider) + if err != nil { + return cluster, err + } + + nextRefresh, err := nextRefreshTime(providerRefreshInterval, cluster.Annotations[clusterLastRefreshTime]) + if err != nil { + return cluster, err + } + + now := time.Now() + if nextRefresh.Before(now) { + cluster, err = c.refreshClusterUpstreamSpec(cluster, provider) + if err != nil { + return cluster, err + } + c.clusterEnqueueAfter(key, providerRefreshInterval) + } else { + c.clusterEnqueueAfter(key, nextRefresh.Sub(now)) + } + + return cluster, nil +} + +// getProviderAndReadyStatus returns the managed cluster provider of the given +// cluster and whether it is ready to be refresh and synced. +func getProviderAndReadyStatus(cluster *mgmtv3.Cluster) (string, bool) { + // for other cloud drivers, please edit HERE + switch { + case cluster.Spec.AKSConfig != nil: + if cluster.Status.AKSStatus.UpstreamSpec == nil { + logrus.Debugf("initial upstream spec for cluster [%s] has not been set by cluster handler yet, skipping", cluster.Name) + return apimgmtv3.ClusterDriverAKS, false + } + return apimgmtv3.ClusterDriverAKS, true + case cluster.Spec.EKSConfig != nil: + if cluster.Status.EKSStatus.UpstreamSpec == nil { + logrus.Debugf("initial upstream spec for cluster [%s] has not been set by cluster handler yet, skipping", cluster.Name) + return apimgmtv3.ClusterDriverEKS, false + } + return apimgmtv3.ClusterDriverEKS, true + case cluster.Spec.GKEConfig != nil: + if cluster.Status.GKEStatus.UpstreamSpec == nil { + logrus.Debugf("initial upstream spec for cluster [%s] has not been set by cluster handler yet, skipping", cluster.Name) + return apimgmtv3.ClusterDriverGKE, false + } + return apimgmtv3.ClusterDriverGKE, true + default: + return noKEv2Provider, false + } +} + +// getProviderRefreshInterval returns the duration that should pass between +// refreshing a cluster created by the given cloud provider. +func getProviderRefreshInterval(provider string) (time.Duration, error) { + providerRefreshInterval := settings.GetSettingByID(fmt.Sprintf(refreshSettingFormat, strings.ToLower(provider))) + if providerRefreshInterval == "" { + return 300 * time.Second, nil + } + refreshInterval, err := strconv.Atoi(providerRefreshInterval) + if err != nil { + return 300 * time.Second, err + } + + return time.Duration(refreshInterval) * time.Second, nil +} + +// nextRefreshTime checks lastRefreshTime and refreshInterval and when the next refresh should occur +func nextRefreshTime(refreshInterval time.Duration, lastRefreshTime string) (time.Time, error) { + if lastRefreshTime == "" { + return time.Time{}, nil + } + + lastRefreshUnix, err := strconv.ParseInt(lastRefreshTime, 10, 64) + if err != nil { + return time.Time{}, fmt.Errorf("unable to parse last KEv2 refresh time [%s]: %v", lastRefreshTime, err) + } + + return time.Unix(lastRefreshUnix, 0).Add(refreshInterval), nil +} + +func (c *clusterRefreshController) refreshClusterUpstreamSpec(cluster *mgmtv3.Cluster, cloudDriver string) (*mgmtv3.Cluster, error) { + logrus.Debugf("checking cluster [%s] upstream state for changes", cluster.Name) + + // In this call, it is possible to get errors back with non-nil upstreamSpec. + // If upstreamSpec is nil then the syncing failed for some reason. This is reported to the user, and this function returns at the end of this if-statement. + // If upstreamSpec is non-nil then the syncing occurred as expected, but the node groups have health issues that are reported to the user. + // In this second case, the message is set on the Updated condition, but execution continues because the sync was successful. + upstreamConfig, err := getComparableUpstreamSpec(c.secretsCache, c.secretClient, cluster) + if err != nil { + var syncFailed string + if upstreamConfig == nil || (upstreamConfig.gkeConfig == nil && upstreamConfig.eksConfig == nil && upstreamConfig.aksConfig == nil) { + syncFailed = ": syncing failed" + } + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionUpdated.False(cluster) + apimgmtv3.ClusterConditionUpdated.Message(cluster, fmt.Sprintf("[Syncing error%s] %s", syncFailed, err.Error())) + + // Only continue if one of the configs on upstreamConfig is not nil. + // Otherwise, an error occurred and no syncing should occur. + if upstreamConfig == nil || (upstreamConfig.gkeConfig == nil && upstreamConfig.eksConfig == nil && upstreamConfig.aksConfig == nil) { + return c.updateCluster(cluster) + } + } else if strings.Contains(apimgmtv3.ClusterConditionUpdated.GetMessage(cluster), "[Syncing error") { + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionUpdated.True(cluster) + apimgmtv3.ClusterConditionUpdated.Message(cluster, "") + } + + var initialClusterConfig, appliedClusterConfig, upstreamClusterConfig, upstreamSpec interface{} + // for other cloud drivers, please edit HERE + switch cloudDriver { + case apimgmtv3.ClusterDriverAKS: + initialClusterConfig = cluster.Spec.AKSConfig + appliedClusterConfig = cluster.Status.AppliedSpec.AKSConfig + upstreamClusterConfig = cluster.Status.AKSStatus.UpstreamSpec + upstreamSpec = upstreamConfig.aksConfig + case apimgmtv3.ClusterDriverEKS: + initialClusterConfig = cluster.Spec.EKSConfig + appliedClusterConfig = cluster.Status.AppliedSpec.EKSConfig + upstreamClusterConfig = cluster.Status.EKSStatus.UpstreamSpec + upstreamSpec = upstreamConfig.eksConfig + case apimgmtv3.ClusterDriverGKE: + initialClusterConfig = cluster.Spec.GKEConfig + appliedClusterConfig = cluster.Status.AppliedSpec.GKEConfig + upstreamClusterConfig = cluster.Status.GKEStatus.UpstreamSpec + upstreamSpec = upstreamConfig.gkeConfig + } + + // compare saved cluster.Status...UpstreamSpec with upstreamSpec, + // if there is difference then update cluster.Status...UpstreamSpec + if !reflect.DeepEqual(upstreamClusterConfig, upstreamSpec) { + logrus.Debugf("updating cluster [%s], upstream change detected", cluster.Name) + cluster = cluster.DeepCopy() + // for other cloud drivers, please edit HERE + switch cloudDriver { + case apimgmtv3.ClusterDriverAKS: + cluster.Status.AKSStatus.UpstreamSpec = upstreamConfig.aksConfig + case apimgmtv3.ClusterDriverEKS: + cluster.Status.EKSStatus.UpstreamSpec = upstreamConfig.eksConfig + case apimgmtv3.ClusterDriverGKE: + cluster.Status.GKEStatus.UpstreamSpec = upstreamConfig.gkeConfig + } + } + + // check if cluster is still updating changes + if !reflect.DeepEqual(initialClusterConfig, appliedClusterConfig) { + logrus.Debugf("cluster [%s] currently updating, skipping spec sync", cluster.Name) + return c.updateCluster(cluster) + } + + // check for changes between upstream spec on cluster and initial ClusterConfig object + specMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(initialClusterConfig) + if err != nil { + return cluster, err + } + + upstreamSpecMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(upstreamSpec) + if err != nil { + return cluster, err + } + + var updateClusterConfig bool + for key, value := range upstreamSpecMap { + if specMap[key] == nil { + continue + } + if reflect.DeepEqual(specMap[key], value) { + continue + } + updateClusterConfig = true + specMap[key] = value + } + + if updateClusterConfig { + logrus.Debugf("change detected for cluster [%s], updating spec", cluster.Name) + // for other cloud drivers, please edit HERE + switch cloudDriver { + case apimgmtv3.ClusterDriverAKS: + err = runtime.DefaultUnstructuredConverter.FromUnstructured(specMap, cluster.Spec.AKSConfig) + if err != nil { + return cluster, err + } + case apimgmtv3.ClusterDriverEKS: + err = runtime.DefaultUnstructuredConverter.FromUnstructured(specMap, cluster.Spec.EKSConfig) + if err != nil { + return cluster, err + } + case apimgmtv3.ClusterDriverGKE: + err = runtime.DefaultUnstructuredConverter.FromUnstructured(specMap, cluster.Spec.GKEConfig) + if err != nil { + return cluster, err + } + } + } else { + logrus.Debugf("cluster [%s] matches upstream, skipping spec sync", cluster.Name) + } + + return c.updateCluster(cluster) +} + +func (c *clusterRefreshController) updateCluster(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if cluster.Annotations == nil { + cluster.Annotations = make(map[string]string) + } + // Update the cluster refresh time. + cluster.Annotations[clusterLastRefreshTime] = strconv.FormatInt(time.Now().Unix(), 10) + + return c.clusterClient.Update(cluster) +} + +func getComparableUpstreamSpec(secretsCache wranglerv1.SecretCache, secretClient wranglerv1.SecretClient, cluster *mgmtv3.Cluster) (*clusterConfig, error) { + clusterCfg := &clusterConfig{} + + // for other cloud drivers, please edit HERE + switch cluster.Status.Driver { + case apimgmtv3.ClusterDriverAKS: + aksConfig, err := BuildAKSUpstreamSpec(secretsCache, secretClient, cluster) + clusterCfg.aksConfig = aksConfig + return clusterCfg, err + case apimgmtv3.ClusterDriverEKS: + eksConfig, err := BuildEKSUpstreamSpec(secretClient, cluster) + clusterCfg.eksConfig = eksConfig + return clusterCfg, err + case apimgmtv3.ClusterDriverGKE: + gkeConfig, err := BuildGKEUpstreamSpec(secretsCache, secretClient, cluster) + clusterCfg.gkeConfig = gkeConfig + return clusterCfg, err + default: + return nil, fmt.Errorf("unsupported cloud driver") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/eks_upstream_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/eks_upstream_spec.go new file mode 100644 index 0000000..6f76392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/eks_upstream_spec.go @@ -0,0 +1,174 @@ +package clusterupstreamrefresher + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/eks" + ekscontroller "github.com/rancher/eks-operator/controller" + eksv1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/robfig/cron" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + eksUpstreamRefresh = "eks-refresh" + eksRefreshCronDeprecated = "eks-refresh-cron" + eksRefreshCronAnnotation = "settings.management.cattle.io/migrated" +) + +func BuildEKSUpstreamSpec(secretClient wranglerv1.SecretClient, cluster *mgmtv3.Cluster) (*eksv1.EKSClusterConfigSpec, error) { + ctx := context.Background() + eksService, err := ekscontroller.StartEKSService(ctx, secretClient, *cluster.Spec.EKSConfig) + if err != nil { + return nil, err + } + + clusterState, err := eksService.DescribeCluster(ctx, + &eks.DescribeClusterInput{ + Name: aws.String(cluster.Spec.EKSConfig.DisplayName), + }) + if err != nil { + return nil, err + } + + ngs, err := eksService.ListNodegroups(ctx, + &eks.ListNodegroupsInput{ + ClusterName: aws.String(cluster.Spec.EKSConfig.DisplayName), + }) + if err != nil { + return nil, err + } + + // gather upstream node groups states + var nodeGroupStates []*eks.DescribeNodegroupOutput + var errs []string + for _, ngName := range ngs.Nodegroups { + ng, err := eksService.DescribeNodegroup(ctx, + &eks.DescribeNodegroupInput{ + ClusterName: aws.String(cluster.Spec.EKSConfig.DisplayName), + NodegroupName: aws.String(ngName), + }) + if err != nil { + return nil, err + } + + nodeGroupStates = append(nodeGroupStates, ng) + var nodeGroupMustBeDeleted string + if len(ng.Nodegroup.Health.Issues) != 0 { + var issueMessages []string + for _, issue := range ng.Nodegroup.Health.Issues { + issueMessages = append(issueMessages, aws.ToString(issue.Message)) + if !ekscontroller.NodeGroupIssueIsUpdatable(string(issue.Code)) { + nodeGroupMustBeDeleted = ": node group cannot be updated, must be deleted and recreated" + } + } + errs = append(errs, fmt.Sprintf("health error for node group [%s] in cluster [%s]: %s%s", + aws.ToString(ng.Nodegroup.NodegroupName), + cluster.Name, + strings.Join(issueMessages, "; "), + nodeGroupMustBeDeleted, + )) + } + } + + ec2Service, err := ekscontroller.StartEC2Service(ctx, secretClient, *cluster.Spec.EKSConfig) + if err != nil { + return nil, err + } + upstreamSpec, _, err := ekscontroller.BuildUpstreamClusterState(ctx, cluster.Spec.DisplayName, cluster.Status.EKSStatus.ManagedLaunchTemplateID, clusterState, nodeGroupStates, ec2Service, eksService, false) + if err != nil { + // If we get an error here, then syncing is broken + return nil, err + } + + upstreamSpec.DisplayName = cluster.Spec.EKSConfig.DisplayName + upstreamSpec.Region = cluster.Spec.EKSConfig.Region + upstreamSpec.AmazonCredentialSecret = cluster.Spec.EKSConfig.AmazonCredentialSecret + upstreamSpec.Imported = cluster.Spec.EKSConfig.Imported + upstreamSpec.Subnets = cluster.Spec.EKSConfig.Subnets + upstreamSpec.SecurityGroups = cluster.Spec.EKSConfig.SecurityGroups + upstreamSpec.ServiceRole = cluster.Spec.EKSConfig.ServiceRole + + if len(errs) != 0 { + // If there are errors here, we can still sync, but there are problems with the nodegroups that should be reported + err = fmt.Errorf("error for cluster [%s]: %s", + cluster.Name, + strings.Join(errs, "\n")) + } + + return upstreamSpec, err +} + +// MigrateEksRefreshCronSetting migrates the deprecated eks-refresh-cron setting to new +// setting only if default setting was changed +// This function will be run only once during startup by pkg/multiclustermanager/app.go +func MigrateEksRefreshCronSetting(wContext *wrangler.Context) { + settingsClient := wContext.Mgmt.Setting() + eksCronSetting, err := settingsClient.Get(eksRefreshCronDeprecated, metav1.GetOptions{}) + if errors.IsNotFound(err) { + return + } else if err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error getting %s setting: %v", eksRefreshCronDeprecated, err) + return + } + if eksCronSetting.Annotations != nil && eksCronSetting.Annotations[eksRefreshCronAnnotation] == "true" { + return + } + + eksCronAnnotate := make(map[string]string) + if eksCronSetting.Annotations != nil { + eksCronAnnotate = eksCronSetting.Annotations + } + eksCronAnnotate[eksRefreshCronAnnotation] = "true" + + settingsClientCache := wContext.Mgmt.Setting().Cache() + eksRefreshSetting, err := settingsClientCache.Get(eksUpstreamRefresh) + if errors.IsNotFound(err) { + return + } else if err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error getting %s setting: %v", eksUpstreamRefresh, err) + return + } + + if eksRefreshSetting.Value != "" || eksCronSetting.Value == "" { + eksCronSetting.SetAnnotations(eksCronAnnotate) + if _, err = settingsClient.Update(eksCronSetting); err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error annotating eks-refresh-cron setting: %v", err) + } + return + } + + eksSchedule, err := cron.ParseStandard(eksCronSetting.Value) + if err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error parsing cron schedule %s setting: %v", eksRefreshCronDeprecated, err) + return + } + + next := eksSchedule.Next(time.Now()) + refreshTime := int(eksSchedule.Next(next).Sub(next) / time.Second) + + err = settings.EKSUpstreamRefresh.Set(fmt.Sprint(refreshTime)) + if err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error updating eks-refresh setting: %v", err) + } + eksCronSetting.SetAnnotations(eksCronAnnotate) + if _, err = settingsClient.Update(eksCronSetting); err != nil { + logrus.Errorf("Unable to complete EKS cron migration, will attempt at next rancher startup. "+ + "Error annotating eks-refresh-cron setting: %v", err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/gke_upstream_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/gke_upstream_spec.go new file mode 100644 index 0000000..7993b30 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/clusterupstreamrefresher/gke_upstream_spec.go @@ -0,0 +1,27 @@ +package clusterupstreamrefresher + +import ( + "context" + + gkecontroller "github.com/rancher/gke-operator/controller" + gkev1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" +) + +func BuildGKEUpstreamSpec(secretsCache wranglerv1.SecretCache, secretClient wranglerv1.SecretClient, cluster *mgmtv3.Cluster) (*gkev1.GKEClusterConfigSpec, error) { + ctx := context.Background() + upstreamSpec, err := gkecontroller.BuildUpstreamClusterState(ctx, secretsCache, secretClient, cluster.Spec.GKEConfig) + if err != nil { + return nil, err + } + + upstreamSpec.ClusterName = cluster.Spec.GKEConfig.ClusterName + upstreamSpec.Region = cluster.Spec.GKEConfig.Region + upstreamSpec.Zone = cluster.Spec.GKEConfig.Zone + upstreamSpec.GoogleCredentialSecret = cluster.Spec.GKEConfig.GoogleCredentialSecret + upstreamSpec.ProjectID = cluster.Spec.GKEConfig.ProjectID + upstreamSpec.Imported = cluster.Spec.GKEConfig.Imported + + return upstreamSpec, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/controller.go new file mode 100644 index 0000000..90d5cb8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/controller.go @@ -0,0 +1,70 @@ +package management + +import ( + "context" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/agentupgrade" + "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/rancher/pkg/controllers/management/certsexpiration" + "github.com/rancher/rancher/pkg/controllers/management/cloudcredential" + "github.com/rancher/rancher/pkg/controllers/management/cluster" + "github.com/rancher/rancher/pkg/controllers/management/clusterdeploy" + "github.com/rancher/rancher/pkg/controllers/management/clustergc" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + "github.com/rancher/rancher/pkg/controllers/management/clusterstats" + "github.com/rancher/rancher/pkg/controllers/management/clusterstatus" + "github.com/rancher/rancher/pkg/controllers/management/clustertemplate" + "github.com/rancher/rancher/pkg/controllers/management/drivers/kontainerdriver" + "github.com/rancher/rancher/pkg/controllers/management/drivers/nodedriver" + "github.com/rancher/rancher/pkg/controllers/management/etcdbackup" + "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + "github.com/rancher/rancher/pkg/controllers/management/node" + "github.com/rancher/rancher/pkg/controllers/management/nodepool" + "github.com/rancher/rancher/pkg/controllers/management/nodetemplate" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/controllers/management/restrictedadminrbac" + "github.com/rancher/rancher/pkg/controllers/management/rkeworkerupgrader" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/controllers/management/settings" + "github.com/rancher/rancher/pkg/controllers/management/usercontrollers" + "github.com/rancher/rancher/pkg/controllers/managementlegacy" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, management *config.ManagementContext, manager *clustermanager.Manager, wrangler *wrangler.Context) { + // auth handlers need to run early to create namespaces that back clusters and projects + // also, these handlers are purely in the mgmt plane, so they are lightweight compared to those that interact with machines and clusters + auth.RegisterEarly(ctx, management, manager) + usercontrollers.RegisterEarly(ctx, management, manager) + + // a-z + agentupgrade.Register(ctx, management) + certsexpiration.Register(ctx, management) + cluster.Register(ctx, management) + clusterdeploy.Register(ctx, management, manager) + clustergc.Register(ctx, management) + clusterprovisioner.Register(ctx, management) + clusterstats.Register(ctx, management, manager) + clusterstatus.Register(ctx, management) + kontainerdriver.Register(ctx, management) + kontainerdrivermetadata.Register(ctx, management) + nodedriver.Register(ctx, management) + nodepool.Register(ctx, management) + cloudcredential.Register(ctx, management) + node.Register(ctx, management, manager) + + etcdbackup.Register(ctx, management) + clustertemplate.Register(ctx, management) + nodetemplate.Register(ctx, management) + rkeworkerupgrader.Register(ctx, management, manager.ScaledContext) + rbac.Register(ctx, management) + restrictedadminrbac.Register(ctx, management, wrangler) + secretmigrator.Register(ctx, management) + settings.Register(ctx, management) + managementlegacy.Register(ctx, management, manager) + + // Register last + auth.RegisterLate(ctx, management) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/base_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/base_driver.go new file mode 100644 index 0000000..26e9c8b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/base_driver.go @@ -0,0 +1,352 @@ +package drivers + +import ( + "bytes" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "fmt" + "hash" + "io" + "net/http" + "net/url" + "os" + "os/exec" + "path" + "path/filepath" + "strings" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +type BaseDriver struct { + Builtin bool + URL string + DriverHash string + DriverName string + BinaryPrefix string +} + +func (d *BaseDriver) Name() string { + return d.DriverName +} + +func (d *BaseDriver) Hash() string { + return d.DriverHash +} + +func (d *BaseDriver) Checksum() string { + return d.DriverName +} + +func (d *BaseDriver) FriendlyName() string { + return strings.TrimPrefix(d.DriverName, d.BinaryPrefix) +} + +func (d *BaseDriver) Remove() error { + cacheFilePrefix := d.cacheFile() + content, err := os.ReadFile(cacheFilePrefix) + if os.IsNotExist(err) { + return nil + } + + if err != nil { + return err + } + + dest := path.Join(binDir(), string(content)) + _ = os.Remove(dest) + _ = os.Remove(cacheFilePrefix + "-" + string(content)) + _ = os.Remove(cacheFilePrefix) + + return nil +} + +func (d *BaseDriver) Stage(forceUpdate bool) error { + if err := d.getError(); err != nil { + return err + } + + return d.setError(d.stage(forceUpdate)) +} + +func (d *BaseDriver) setError(err error) error { + errFile := d.cacheFile() + ".error" + + if err != nil { + _ = os.MkdirAll(path.Dir(errFile), 0700) + _ = os.WriteFile(errFile, []byte(err.Error()), 0600) + } + return err +} + +func (d *BaseDriver) getError() error { + errFile := d.cacheFile() + ".error" + + if content, err := os.ReadFile(errFile); err == nil { + logrus.Errorf("Returning previous error: %s", content) + d.ClearError() + return errors.New(string(content)) + } + + return nil +} + +func (d *BaseDriver) ClearError() { + errFile := d.cacheFile() + ".error" + _ = os.Remove(errFile) +} + +func (d *BaseDriver) stage(forceUpdate bool) error { + if d.Builtin { + return nil + } + + cacheFilePrefix := d.cacheFile() + + driverName, err := isInstalled(cacheFilePrefix) + if !forceUpdate && err != nil || driverName != "" { + d.DriverName = driverName + return err + } + + tempFile, err := os.CreateTemp("", "machine-driver") + if err != nil { + return err + } + defer os.Remove(tempFile.Name()) + defer tempFile.Close() + + hasher, err := getHasher(d.DriverHash) + if err != nil { + return err + } + + downloadDest := io.Writer(tempFile) + if hasher != nil { + downloadDest = io.MultiWriter(tempFile, hasher) + } + + if err := d.download(downloadDest); err != nil { + return err + } + + if got, ok := compare(hasher, d.DriverHash); !ok { + return fmt.Errorf("hash does not match, got %s, expected %s", got, d.DriverHash) + } + + if err := tempFile.Close(); err != nil { + return err + } + + driverName, err = d.copyBinary(cacheFilePrefix, tempFile.Name()) + if err != nil { + return err + } + + d.DriverName = driverName + return nil +} + +// Exists will return true if the executable binary for the driver can be found +// and the cache file exists (in case of upgrades the binary will match but +// the cache will not yet exist) +func (d *BaseDriver) Exists() bool { + if d.DriverName == "" { + return false + } + if d.Builtin { + return true + } + _, err := os.Stat(d.binName()) + if err == nil { + // The executable is there but does it come from the right version? + _, err = os.Stat(d.srcBinName()) + } + return err == nil +} + +func isElf(input string) bool { + f, err := os.Open(input) + if err != nil { + return false + } + defer f.Close() + + elf := make([]byte, 4) + if _, err := f.Read(elf); err != nil { + return false + } + //support unix binary and mac-os binary mach-o + return bytes.Compare(elf, []byte{0x7f, 0x45, 0x4c, 0x46}) == 0 || bytes.Compare(elf, []byte{0xcf, 0xfa, 0xed, 0xfe}) == 0 +} + +func (d *BaseDriver) copyBinary(cacheFile, input string) (string, error) { + temp, err := os.MkdirTemp("", "machine-driver-extract") + if err != nil { + return "", err + } + defer os.RemoveAll(temp) + + file := "" + driverName := "" + + if isElf(input) { + file = input + u, err := url.Parse(d.URL) + if err != nil { + return "", err + } + + if !strings.HasPrefix(path.Base(u.Path), d.BinaryPrefix) { + return "", fmt.Errorf("invalid URL %s, path should be of the format %s*", d.URL, d.BinaryPrefix) + } + + s := strings.TrimPrefix(path.Base(u.Path), d.BinaryPrefix) + name := strings.FieldsFunc(s, func(r rune) bool { + return r == '-' || r == '_' || r == '.' + })[0] + + if name == "" { + return "", fmt.Errorf("invalid URL %s, NAME is empty, path should be of the format %sNAME", d.URL, d.BinaryPrefix) + } + driverName = d.BinaryPrefix + name + } else { + if err := exec.Command("tar", "xvf", input, "-C", temp).Run(); err != nil { + if err := exec.Command("unzip", "-o", input, "-d", temp).Run(); err != nil { + return "", fmt.Errorf("failed to extract") + } + } + } + + _ = filepath.Walk(temp, func(p string, info os.FileInfo, err error) error { + if info.IsDir() { + return nil + } + + if strings.HasPrefix(path.Base(p), d.BinaryPrefix) { + file = p + } + + return nil + }) + + if file == "" { + return "", fmt.Errorf("failed to find driver in archive. There must be a file of form %s*", d.BinaryPrefix) + } + + if driverName == "" { + driverName = path.Base(file) + } + f, err := os.Open(file) + if err != nil { + return "", err + } + defer f.Close() + + if err := os.MkdirAll(path.Dir(cacheFile), 0755); err != nil { + return "", err + } + + driverName = strings.ToLower(driverName) + dest, err := os.Create(cacheFile + "-" + driverName) + if err != nil { + return "", err + } + defer dest.Close() + + if _, err := io.Copy(dest, f); err != nil { + return "", err + } + + logrus.Infof("Found driver %s", driverName) + return driverName, os.WriteFile(cacheFile, []byte(driverName), 0644) +} + +// binName is the full path to the binary executable. This does not take in +// account the version of the binary +func (d *BaseDriver) binName() string { + return path.Join(binDir(), d.DriverName) +} + +// srcBinName is the full path of the cached/hashed binary executable. This takes +// in account the version of the binary +func (d *BaseDriver) srcBinName() string { + return d.cacheFile() + "-" + d.DriverName +} + +func binDir() string { + if dl := os.Getenv("CATTLE_DEV_MODE"); dl != "" { + return "./management-state/bin" + } + + return "/opt/drivers/management-state/bin" +} + +func compare(hash hash.Hash, value string) (string, bool) { + if hash == nil { + return "", true + } + + got := hex.EncodeToString(hash.Sum([]byte{})) + expected := strings.TrimSpace(strings.ToLower(value)) + + return got, got == expected +} + +func getHasher(hash string) (hash.Hash, error) { + switch len(hash) { + case 0: + return nil, nil + case 32: + return md5.New(), nil + case 40: + return sha1.New(), nil + case 64: + return sha256.New(), nil + case 128: + return sha512.New(), nil + } + + return nil, fmt.Errorf("invalid hash format: %s", hash) +} + +func (d *BaseDriver) download(dest io.Writer) error { + logrus.Infof("Download %s", d.URL) + resp, err := http.Get(d.URL) + if err != nil { + return err + } + defer resp.Body.Close() + + _, err = io.Copy(dest, resp.Body) + return err +} + +func (d *BaseDriver) cacheFile() string { + key := sha256Bytes([]byte(d.URL + d.DriverHash)) + + base := os.Getenv("CATTLE_HOME") + if base == "" { + base = "./management-state" + } + + return path.Join(base, "machine-drivers", key) +} + +func isInstalled(file string) (string, error) { + content, err := os.ReadFile(file) + if os.IsNotExist(err) { + return "", nil + } + return strings.ToLower(strings.TrimSpace(string(content))), err +} + +func sha256Bytes(content []byte) string { + hash := sha256.New() + _, _ = io.Copy(hash, bytes.NewBuffer(content)) + return hex.EncodeToString(hash.Sum([]byte{})) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/dynamic_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/dynamic_driver.go new file mode 100644 index 0000000..29d422f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/dynamic_driver.go @@ -0,0 +1,106 @@ +package drivers + +import ( + "fmt" + "io" + "os" + "os/exec" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" +) + +type DynamicDriver struct { + BaseDriver +} + +var DockerMachineDriverPrefix = "docker-machine-driver-" + +func NewDynamicDriver(builtin bool, name, url, hash string) *DynamicDriver { + d := &DynamicDriver{ + BaseDriver{ + Builtin: builtin, + DriverName: name, + URL: url, + DriverHash: hash, + BinaryPrefix: DockerMachineDriverPrefix, + }, + } + if !strings.HasPrefix(d.DriverName, DockerMachineDriverPrefix) { + d.DriverName = DockerMachineDriverPrefix + d.DriverName + } + return d +} + +func (d *DynamicDriver) Install() error { + if d.Builtin { + return nil + } + + if err := d.copyTo(d.binName()); err != nil { + return err + } + + if os.Getenv("CATTLE_DEV_MODE") != "" { + return nil + } + + return d.copyTo(fmt.Sprintf("%s/assets/%s", settings.UIPath.Get(), d.DriverName)) +} + +func (d *BaseDriver) copyTo(dest string) error { + binaryPath := d.binName() + tmpPath := binaryPath + "-tmp" + f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + if err != nil { + return errors.Wrapf(err, "Couldn't open %v for writing", tmpPath) + } + defer f.Close() + + src, err := os.Open(d.srcBinName()) + if err != nil { + return errors.Wrapf(err, "Couldn't open %v for copying", d.srcBinName()) + } + defer src.Close() + + logrus.Infof("Copying %v => %v", d.srcBinName(), tmpPath) + _, err = io.Copy(f, src) + if err != nil { + return errors.Wrapf(err, "Couldn't copy %v to %v", d.srcBinName(), tmpPath) + } + + err = os.Rename(tmpPath, dest) + if err != nil { + return errors.Wrapf(err, "Couldn't copy driver %v to %v", d.Name(), dest) + } + + return nil +} + +// Executable is will return nil if the driver can be executed +func (d *BaseDriver) Executable() error { + if d.DriverName == "" { + return fmt.Errorf("Empty driver name") + } + + if d.Builtin { + return nil + } + + binaryPath := d.binName() + _, err := os.Stat(binaryPath) + if err != nil { + return fmt.Errorf("Driver %s not found", binaryPath) + } + cmd := exec.Command(binaryPath) + err = cmd.Start() + if err != nil { + return errors.Wrapf(err, "Driver binary %s couldn't execute", binaryPath) + } + + // We don't care about the exit code, just want to make sure we can execute the binary + _ = cmd.Wait() + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainer_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainer_driver.go new file mode 100644 index 0000000..b4864c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainer_driver.go @@ -0,0 +1,94 @@ +package drivers + +import ( + "io" + "os" + "path" + "strings" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +type KontainerDriver struct { + BaseDriver +} + +var KontainerDriverPrefix = "kontainer-engine-driver-" + +func NewKontainerDriver(builtin bool, name, url, hash string) *KontainerDriver { + d := &KontainerDriver{ + BaseDriver{ + Builtin: builtin, + DriverName: name, + URL: url, + DriverHash: hash, + BinaryPrefix: KontainerDriverPrefix, + }, + } + if !strings.HasPrefix(d.DriverName, KontainerDriverPrefix) { + d.DriverName = KontainerDriverPrefix + d.DriverName + } + return d +} + +func (d *KontainerDriver) Install() (string, error) { + if d.Builtin { + return "", nil + } + + installPath := path.Join(installDir(), d.DriverName) + tmpPath := installPath + "-tmp" + f, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755) + if err != nil { + return "", errors.Wrapf(err, "Couldn't open %v for writing", tmpPath) + } + defer f.Close() + + src, err := os.Open(d.srcBinName()) + if err != nil { + return "", errors.Wrapf(err, "Couldn't open %v for copying", d.srcBinName()) + } + defer src.Close() + + logrus.Infof("Copying %v => %v", d.srcBinName(), tmpPath) + _, err = io.Copy(f, src) + if err != nil { + return "", errors.Wrapf(err, "Couldn't copy %v to %v", d.srcBinName(), tmpPath) + } + + err = os.Rename(tmpPath, installPath) + if err != nil { + return "", errors.Wrapf(err, "Couldn't copy driver %v to %v", d.Name(), installPath) + } + + return path.Join(runDir(), d.DriverName), nil +} + +func (d *KontainerDriver) Exists() bool { + if d.DriverName == "" { + return false + } + if d.Builtin { + return true + } + binaryPath := path.Join(installDir(), d.DriverName) + _, err := os.Stat(binaryPath) + return err == nil +} + +func installDir() string { + if dl := os.Getenv("CATTLE_DEV_MODE"); dl != "" { + return "./management-state/bin" + } + + return "/opt/jail/driver-jail/management-state/bin" +} + +func runDir() string { + if dl := os.Getenv("CATTLE_DEV_MODE"); dl != "" { + return "./management-state/bin" + } + + return "/management-state/bin" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainerdriver/kontainerdriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainerdriver/kontainerdriver.go new file mode 100644 index 0000000..65e4abf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/kontainerdriver/kontainerdriver.go @@ -0,0 +1,493 @@ +package kontainerdriver + +import ( + "context" + "fmt" + "reflect" + "regexp" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + errorsutil "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + "github.com/rancher/rancher/pkg/controllers/management/drivers" + "github.com/rancher/rancher/pkg/controllers/management/drivers/nodedriver" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rancher/pkg/kontainer-engine/types" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v13 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + driverNameLabel = "io.cattle.kontainer_driver.name" + DriverDir = "./management-state/kontainer-drivers/" +) + +var kontainerDriverName = regexp.MustCompile("kontainer-engine-driver-(.+)$") + +func Register(ctx context.Context, management *config.ManagementContext) { + lifecycle := &Lifecycle{ + dynamicSchemas: management.Management.DynamicSchemas(""), + dynamicSchemasLister: management.Management.DynamicSchemas("").Controller().Lister(), + namespaces: management.Core.Namespaces(""), + coreV1: management.Core, + } + + management.Management.KontainerDrivers("").AddLifecycle(ctx, "mgmt-kontainer-driver-lifecycle", lifecycle) +} + +type Lifecycle struct { + dynamicSchemas v3.DynamicSchemaInterface + dynamicSchemasLister v3.DynamicSchemaLister + namespaces v1.NamespaceInterface + coreV1 corev1.Interface +} + +func (l *Lifecycle) Create(obj *v3.KontainerDriver) (runtime.Object, error) { + logrus.Infof("create kontainerdriver %v", obj.Name) + + // return early if driver is not active + // set driver to a non-transitioning state + if !obj.Spec.Active { + v32.KontainerDriverConditionInactive.True(obj) + return obj, nil + } + + if obj.Spec.BuiltIn { + v32.KontainerDriverConditionDownloaded.True(obj) + v32.KontainerDriverConditionInstalled.True(obj) + } else { + v32.KontainerDriverConditionDownloaded.Unknown(obj) + v32.KontainerDriverConditionInstalled.Unknown(obj) + } + + if hasStaticSchema(obj) { + v32.KontainerDriverConditionActive.True(obj) + } else { + v32.KontainerDriverConditionActive.Unknown(obj) + } + + return obj, nil +} + +func (l *Lifecycle) driverExists(obj *v3.KontainerDriver) bool { + return drivers.NewKontainerDriver(obj.Spec.BuiltIn, obj.Status.DisplayName, obj.Spec.URL, obj.Spec.Checksum).Exists() +} + +func (l *Lifecycle) download(obj *v3.KontainerDriver) (*v3.KontainerDriver, error) { + driver := drivers.NewKontainerDriver(obj.Spec.BuiltIn, obj.Status.DisplayName, obj.Spec.URL, obj.Spec.Checksum) + err := driver.Stage(false) + if err != nil { + return nil, err + } + + v32.KontainerDriverConditionDownloaded.True(obj) + + path, err := driver.Install() + if err != nil { + return nil, err + } + + v32.KontainerDriverConditionInstalled.True(obj) + + obj.Status.ExecutablePath = path + matches := kontainerDriverName.FindStringSubmatch(path) + if len(matches) < 2 { + return nil, fmt.Errorf("could not parse name of kontainer driver from path: %v", path) + } + + obj.Status.DisplayName = matches[1] + obj.Status.ActualURL = obj.Spec.URL + + logrus.Infof("kontainerdriver %v downloaded and registered at %v", obj.Name, path) + + return obj, nil +} + +func (l *Lifecycle) createDynamicSchema(obj *v3.KontainerDriver) error { + resourceFields, err := l.getResourceFields(obj) + if err != nil { + return err + } + + dynamicSchema := &v3.DynamicSchema{ + Spec: v32.DynamicSchemaSpec{ + SchemaName: getDynamicTypeName(obj), + ResourceFields: resourceFields, + }, + } + dynamicSchema.Name = strings.ToLower(getDynamicTypeName(obj)) + dynamicSchema.OwnerReferences = []v13.OwnerReference{ + { + UID: obj.UID, + Kind: obj.Kind, + APIVersion: obj.APIVersion, + Name: obj.Name, + }, + } + dynamicSchema.Labels = map[string]string{} + dynamicSchema.Labels[obj.Name] = obj.Status.DisplayName + dynamicSchema.Labels[driverNameLabel] = obj.Status.DisplayName + _, err = l.dynamicSchemas.Create(dynamicSchema) + if err != nil && !errors.IsAlreadyExists(err) { + return errorsutil.WithMessage(err, "error creating dynamic schema") + } + + return l.createOrUpdateKontainerDriverTypes(obj) +} + +func (l *Lifecycle) createOrUpdateDynamicSchema(obj *v3.KontainerDriver) error { + dynamicSchema, err := l.dynamicSchemasLister.Get("", strings.ToLower(getDynamicTypeName(obj))) + if errors.IsNotFound(err) { + return l.createDynamicSchema(obj) + } + if err != nil { + return err + + } + + return l.updateDynamicSchema(dynamicSchema, obj) +} + +func (l *Lifecycle) updateDynamicSchema(dynamicSchema *v3.DynamicSchema, obj *v3.KontainerDriver) error { + dynamicSchema = dynamicSchema.DeepCopy() + + fields, err := l.getResourceFields(obj) + if err != nil { + return err + } + + dynamicSchema.Spec.ResourceFields = fields + + logrus.Infof("dynamic schema for kontainerdriver %v updating", obj.Name) + + if _, err = l.dynamicSchemas.Update(dynamicSchema); err != nil { + return err + } + + return l.createOrUpdateKontainerDriverTypes(obj) +} + +func (l *Lifecycle) getResourceFields(obj *v3.KontainerDriver) (map[string]v32.Field, error) { + driver := service.NewEngineService( + clusterprovisioner.NewPersistentStore(l.namespaces, l.coreV1), + ) + flags, err := driver.GetDriverCreateOptions(context.Background(), obj.Name, obj, v32.ClusterSpec{ + GenericEngineConfig: &v32.MapStringInterface{ + clusterprovisioner.DriverNameField: obj.Status.DisplayName, + }, + }) + if err != nil { + return nil, err + } + + resourceFields := map[string]v32.Field{} + for key, flag := range flags.Options { + formattedName, field, err := toResourceField(key, flag) + if err != nil { + return nil, errorsutil.WithMessage(err, "error formatting field name") + } + + resourceFields[formattedName] = field + } + + // all drivers need a driverName field so kontainer-engine knows what type they are + resourceFields[clusterprovisioner.DriverNameField] = v32.Field{ + Create: true, + Update: true, + Type: "string", + Default: v32.Values{ + StringValue: obj.Name, + }, + } + + return resourceFields, nil +} + +func (l *Lifecycle) createOrUpdateKontainerDriverTypes(obj *v3.KontainerDriver) error { + nodedriver.SchemaLock.Lock() + defer nodedriver.SchemaLock.Unlock() + + embeddedType := getDynamicTypeName(obj) + fieldName := getDynamicFieldName(obj) + + clusterSchema, err := l.dynamicSchemasLister.Get("", "cluster") + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + resourceField := map[string]v32.Field{} + resourceField[fieldName] = v32.Field{ + Create: true, + Nullable: true, + Update: true, + Type: embeddedType, + } + + dynamicSchema := &v3.DynamicSchema{} + dynamicSchema.Name = "cluster" + dynamicSchema.Spec.ResourceFields = resourceField + dynamicSchema.Spec.Embed = true + dynamicSchema.Spec.EmbedType = "cluster" + _, err := l.dynamicSchemas.Create(dynamicSchema) + if err != nil { + return err + } + return nil + } + + clusterSchema = clusterSchema.DeepCopy() + + shouldUpdate := false + + if clusterSchema.Spec.ResourceFields == nil { + clusterSchema.Spec.ResourceFields = map[string]v32.Field{} + } + if _, ok := clusterSchema.Spec.ResourceFields[fieldName]; !ok { + // if embedded we add the type to schema + clusterSchema.Spec.ResourceFields[fieldName] = v32.Field{ + Create: true, + Nullable: true, + Update: true, + Type: embeddedType, + } + shouldUpdate = true + } + + if shouldUpdate { + _, err = l.dynamicSchemas.Update(clusterSchema) + if err != nil { + return err + } + } + + return nil +} + +func toResourceField(name string, flag *types.Flag) (string, v32.Field, error) { + field := v32.Field{ + Create: true, + Update: true, + Type: "string", + } + + name, err := toLowerCamelCase(name) + if err != nil { + return name, field, err + } + + field.Description = flag.Usage + + if flag.Type == types.StringType { + field.Default.StringValue = flag.Value + + if flag.Password { + field.Type = "password" + } else { + field.Type = "string" + } + + if flag.Default != nil { + field.Default.StringValue = flag.Default.DefaultString + } + } else if flag.Type == types.IntType || flag.Type == types.IntPointerType { + field.Type = "int" + + if flag.Default != nil { + field.Default.IntValue = int(flag.Default.DefaultInt) + } + } else if flag.Type == types.BoolType || flag.Type == types.BoolPointerType { + field.Type = "boolean" + + if flag.Default != nil { + field.Default.BoolValue = flag.Default.DefaultBool + } + } else if flag.Type == types.StringSliceType { + field.Type = "array[string]" + + if flag.Default != nil { + field.Default.StringSliceValue = flag.Default.DefaultStringSlice.Value + } + } else { + return name, field, fmt.Errorf("unknown type of flag %v: %v", flag, reflect.TypeOf(flag)) + } + + return name, field, nil +} + +func toLowerCamelCase(nodeFlagName string) (string, error) { + flagNameParts := strings.Split(nodeFlagName, "-") + flagName := flagNameParts[0] + for _, flagNamePart := range flagNameParts[1:] { + flagName = flagName + strings.ToUpper(flagNamePart[:1]) + flagNamePart[1:] + } + return flagName, nil +} + +func (l *Lifecycle) Updated(obj *v3.KontainerDriver) (runtime.Object, error) { + logrus.Infof("update kontainerdriver %v", obj.Name) + if hasStaticSchema(obj) { + return obj, nil + } + + if obj.Spec.BuiltIn && v32.KontainerDriverConditionActive.IsTrue(obj) { + // Builtin drivers can still have their schema change during Rancher upgrades so we need to try + return obj, l.createOrUpdateDynamicSchema(obj) + } + + var err error + var tmpObj runtime.Object + switch { // dealing with deactivate action + case !obj.Spec.Active && l.DynamicSchemaExists(obj): + v32.KontainerDriverConditionInactive.Unknown(obj) + // delete the active condition + var i int + for _, con := range obj.Status.Conditions { + if con.Type != string(v32.KontainerDriverConditionActive) { + obj.Status.Conditions[i] = con + i++ + } + } + obj.Status.Conditions = obj.Status.Conditions[:i] + // we don't need to show the Inactivating state so we don't need to store the Inactivate condition + fallthrough + case !obj.Spec.Active: + tmpObj, err = v32.KontainerDriverConditionInactive.DoUntilTrue(obj, func() (runtime.Object, error) { + if err = l.dynamicSchemas.Delete(getDynamicTypeName(obj), &v13.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return nil, fmt.Errorf("error deleting schema: %v", err) + } + if err = l.removeFieldFromCluster(obj); err != nil { + return nil, err + } + + return obj, nil + }) + obj = tmpObj.(*v3.KontainerDriver) + + // redownload file if active AND url changed or not downloaded + // prevents downloading on air-gapped installations + // and update the Downloaded condition to Unknown to show the downloading state + case !v32.KontainerDriverConditionDownloaded.IsUnknown(obj) && + (obj.Spec.URL != obj.Status.ActualURL || + v32.KontainerDriverConditionDownloaded.IsFalse(obj) || + !l.driverExists(obj)): + v32.KontainerDriverConditionDownloaded.Unknown(obj) + + // if it is a buildin driver, set true without downloading + case obj.Spec.BuiltIn && !v32.KontainerDriverConditionDownloaded.IsTrue(obj): + v32.KontainerDriverConditionDownloaded.True(obj) + v32.KontainerDriverConditionInstalled.True(obj) + + // handling download process + case !obj.Spec.BuiltIn && !v32.KontainerDriverConditionDownloaded.IsTrue(obj): + obj, err = l.download(obj) + if err != nil { + return obj, err + } + + // Force create/update of schemas + v32.KontainerDriverConditionActive.Unknown(obj) + + // set active status to unknown to show the activating state + case !l.DynamicSchemaExists(obj) && !v32.KontainerDriverConditionActive.IsUnknown(obj): + v32.KontainerDriverConditionActive.Unknown(obj) + + // create schema and set active status to true + default: + tmpObj, err = v32.KontainerDriverConditionActive.DoUntilTrue(obj, func() (runtime.Object, error) { + return obj, l.createOrUpdateDynamicSchema(obj) + }) + obj = tmpObj.(*v3.KontainerDriver) + } + + return obj, err +} + +func hasStaticSchema(obj *v3.KontainerDriver) bool { + return obj.Name == service.RancherKubernetesEngineDriverName || obj.Name == service.ImportDriverName +} + +func getDynamicTypeName(obj *v3.KontainerDriver) string { + var s string + if obj.Spec.BuiltIn { + s = obj.Status.DisplayName + "Config" + } else { + s = obj.Status.DisplayName + "EngineConfig" + } + + return s +} + +func getDynamicFieldName(obj *v3.KontainerDriver) string { + if obj.Spec.BuiltIn { + return obj.Status.DisplayName + "Config" + } + + return obj.Status.DisplayName + "EngineConfig" +} + +// Remove the Kontainer Cluster driver, see also the Schema.Store for kontainer driver +func (l *Lifecycle) Remove(obj *v3.KontainerDriver) (runtime.Object, error) { + logrus.Infof("remove kontainerdriver %v", obj.Name) + + driver := drivers.NewKontainerDriver(obj.Spec.BuiltIn, obj.Name, obj.Spec.URL, obj.Spec.Checksum) + err := driver.Remove() + if err != nil { + return nil, err + } + + if hasStaticSchema(obj) { + return obj, nil + } + + if err := l.dynamicSchemas.Delete(getDynamicTypeName(obj), &v13.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return nil, fmt.Errorf("error deleting dynamic schema: %v", err) + } + + if err := l.removeFieldFromCluster(obj); err != nil { + return nil, err + } + + return obj, nil +} + +// Removes the v3/dynamicschema "cluster"'s resourceField associated with the KontainerDriver obj +func (l *Lifecycle) removeFieldFromCluster(obj *v3.KontainerDriver) error { + nodedriver.SchemaLock.Lock() + defer nodedriver.SchemaLock.Unlock() + + fieldName := getDynamicFieldName(obj) + + nodeSchema, err := l.dynamicSchemasLister.Get("", "cluster") + if err != nil { + return fmt.Errorf("error getting schema: %v", err) // this error may fire during Rancher startup + } + + nodeSchema = nodeSchema.DeepCopy() + + delete(nodeSchema.Spec.ResourceFields, fieldName) + + if _, err = l.dynamicSchemas.Update(nodeSchema); err != nil { + return fmt.Errorf("error removing schema from cluster: %v", err) + } + + return nil +} + +func (l *Lifecycle) DynamicSchemaExists(obj *v3.KontainerDriver) bool { + if obj == nil { + return false + } + if obj.Spec.BuiltIn { + return true + } + + _, err := l.dynamicSchemasLister.Get("", strings.ToLower(getDynamicTypeName(obj))) + return err == nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/flag.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/flag.go new file mode 100644 index 0000000..6685d14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/flag.go @@ -0,0 +1,15 @@ +package nodedriver + +type BoolPointerFlag struct { + Name string + Usage string + EnvVar string +} + +func (f BoolPointerFlag) String() string { + return f.Name +} + +func (f BoolPointerFlag) Default() interface{} { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/machine_driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/machine_driver.go new file mode 100644 index 0000000..7aca324 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/machine_driver.go @@ -0,0 +1,541 @@ +package nodedriver + +import ( + "context" + "encoding/json" + "fmt" + "os/exec" + "reflect" + "strconv" + "strings" + "sync" + + errs "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/drivers" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + SchemaLock = sync.Mutex{} + driverLock = sync.Mutex{} + // DriverToSchemaFields maps Driver field => schema field + // The opposite of this lives in pkg/controllers/management/node/controller.go + DriverToSchemaFields = map[string]map[string]string{ + "aliyunecs": {"sshKeypath": "sshKeyContents"}, + "amazonec2": {"sshKeypath": "sshKeyContents", "userdata": "userdata"}, + "azure": {"customData": "customData"}, + "digitalocean": {"sshKeyPath": "sshKeyContents", "userdata": "userdata"}, + "exoscale": {"sshKey": "sshKey", "userdata": "userdata"}, + "openstack": {"cacert": "cacert", "privateKeyFile": "privateKeyFile", "userDataFile": "userDataFile"}, + "otc": {"privateKeyFile": "privateKeyFile"}, + "packet": {"userdata": "userdata"}, + "pod": {"userdata": "userdata"}, + "vmwarevsphere": {"cloud-config": "cloudConfig"}, + "google": {"authEncodedJson": "authEncodedJson"}, + } + SSHKeyFields = map[string]bool{ + "sshKeyContents": true, + "sshKey": true, + "privateKeyFile": true, + } +) + +const ( + driverNameLabel = "io.cattle.node_driver.name" + uiFieldHintsAnno = "io.cattle.nodedriver/ui-field-hints" +) + +func Register(ctx context.Context, management *config.ManagementContext) { + nodeDriverClient := management.Management.NodeDrivers("") + nodeDriverLifecycle := &Lifecycle{ + nodeDriverClient: nodeDriverClient, + schemaClient: management.Management.DynamicSchemas(""), + schemaLister: management.Management.DynamicSchemas("").Controller().Lister(), + secretStore: management.Core.Secrets(""), + nsStore: management.Core.Namespaces(""), + schemas: management.Schemas, + } + + version, err := getRancherMachineVersion() + if err != nil { + logrus.Warnf("error getting rancher-machine version: %v", err) + } + nodeDriverLifecycle.dockerMachineVersion = version + + nodeDriverClient.AddLifecycle(ctx, "node-driver-controller", nodeDriverLifecycle) +} + +type Lifecycle struct { + nodeDriverClient v3.NodeDriverInterface + schemaClient v3.DynamicSchemaInterface + schemaLister v3.DynamicSchemaLister + secretStore v1.SecretInterface + nsStore v1.NamespaceInterface + schemas *types.Schemas + dockerMachineVersion string +} + +func (m *Lifecycle) Create(obj *v32.NodeDriver) (runtime.Object, error) { + return m.download(obj) +} + +func (m *Lifecycle) download(obj *v32.NodeDriver) (*v32.NodeDriver, error) { + driverLock.Lock() + defer driverLock.Unlock() + if !obj.Spec.Active && !obj.Spec.AddCloudCredential { + return obj, nil + } + + forceUpdate := m.checkDriverVersion(obj) + if v32.NodeDriverConditionDownloaded.GetStatus(obj) == "" || v32.NodeDriverConditionInstalled.GetStatus(obj) == "" { + forceUpdate = true + } + + err := errs.New("not found") + // if node driver was created, we also activate the driver by default + driver := drivers.NewDynamicDriver(obj.Spec.Builtin, obj.Spec.DisplayName, obj.Spec.URL, obj.Spec.Checksum) + schemaName := obj.Spec.DisplayName + "config" + var existingSchema *v32.DynamicSchema + if obj.Spec.DisplayName != "" { + existingSchema, err = m.schemaLister.Get("", schemaName) + } + + if driver.Exists() && err == nil && !forceUpdate { + // add credential schema + credFields := map[string]v32.Field{} + pubCredFields, privateCredFields, passwordFields, defaults, optionals := getCredFields(obj.Annotations) + for name, field := range existingSchema.Spec.ResourceFields { + if SSHKeyFields[name] || passwordFields[name] || privateCredFields[name] { + if field.Type != "password" { + forceUpdate = true + break + } + } + // even if forceUpdate is false, calculate credFields to check if credSchema needs to be updated + if privateCredFields[name] || pubCredFields[name] { + credField := field + credField.Required = !optionals[name] + if val, ok := defaults[name]; ok { + credField = updateDefault(credField, val, field.Type) + } + credFields[name] = credField + } + } + if !forceUpdate { + return m.createCredSchema(obj, credFields) + } + } + + if !driver.Exists() || forceUpdate { + v32.NodeDriverConditionDownloaded.Unknown(obj) + v32.NodeDriverConditionInstalled.Unknown(obj) + } + + newObj, err := v32.NodeDriverConditionDownloaded.Once(obj, func() (runtime.Object, error) { + // update status + obj, err = m.nodeDriverClient.Update(obj) + if err != nil { + return nil, err + } + + if err := driver.Stage(forceUpdate); err != nil { + return nil, err + } + return obj, nil + }) + if err != nil { + return obj, err + } + + obj = newObj.(*v32.NodeDriver) + newObj, err = v32.NodeDriverConditionInstalled.Once(obj, func() (runtime.Object, error) { + if err := driver.Install(); err != nil { + return nil, err + } + if err = driver.Executable(); err != nil { + return nil, err + } + obj.Spec.DisplayName = strings.TrimPrefix(driver.Name(), drivers.DockerMachineDriverPrefix) + return obj, nil + }) + if err != nil { + return newObj.(*v32.NodeDriver), err + } + + obj = newObj.(*v32.NodeDriver) + driverName := strings.TrimPrefix(driver.Name(), drivers.DockerMachineDriverPrefix) + + obj = m.addVersionInfo(obj) + + obj, err = m.addUIHintsAnno(driverName, obj) + if err != nil { + return obj, errs.Wrap(err, "failed JSON in addUIHintsAnno") + } + + flags, err := getCreateFlagsForDriver(driverName) + if err != nil { + return nil, err + } + credFields := map[string]v32.Field{} + resourceFields := map[string]v32.Field{} + pubCredFields, privateCredFields, passwordFields, defaults, optionals := getCredFields(obj.Annotations) + for _, flag := range flags { + name, field, err := FlagToField(flag) + if err != nil { + return nil, err + } + if aliases, ok := DriverToSchemaFields[driverName]; ok { + // convert path fields to their alias to take file contents + if alias, ok := aliases[name]; ok { + name = alias + field.Description = fmt.Sprintf("File contents for %v", alias) + } + } + + if privateCredFields[name] || passwordFields[name] || SSHKeyFields[name] { + field.Type = "password" + } + + if pubCredFields[name] || privateCredFields[name] { + credField := field + credField.Required = !optionals[name] + if val, ok := defaults[name]; ok { + credField = updateDefault(credField, val, field.Type) + } + credFields[name] = credField + } + + resourceFields[name] = field + } + dynamicSchema := &v32.DynamicSchema{ + Spec: v32.DynamicSchemaSpec{ + ResourceFields: resourceFields, + }, + } + dynamicSchema.Name = obj.Spec.DisplayName + "config" + dynamicSchema.OwnerReferences = []metav1.OwnerReference{ + { + UID: obj.UID, + Kind: obj.Kind, + APIVersion: obj.APIVersion, + Name: obj.Name, + }, + } + dynamicSchema.Labels = map[string]string{} + dynamicSchema.Labels[driverNameLabel] = obj.Spec.DisplayName + + _, err = m.schemaClient.Create(dynamicSchema) + if err != nil { + if !errors.IsAlreadyExists(err) { + return obj, err + } + ds, err := m.schemaClient.Get(dynamicSchema.Name, metav1.GetOptions{}) + if err != nil { + return obj, err + } + ds.Spec.ResourceFields = resourceFields + + _, err = m.schemaClient.Update(ds) + if err != nil { + return obj, err + } + } + + return m.createCredSchema(obj, credFields) +} + +func (m *Lifecycle) createCredSchema(obj *v32.NodeDriver, credFields map[string]v32.Field) (*v32.NodeDriver, error) { + name := credentialConfigSchemaName(obj.Spec.DisplayName) + credSchema, err := m.schemaLister.Get("", name) + + if name == "amazonec2credentialconfig" { + credFields["defaultRegion"] = v32.Field{ + Type: "string", + Description: "AWS Default Region", + DynamicField: true, + Create: true, + Update: true, + } + } + + if err != nil { + if errors.IsNotFound(err) { + credentialSchema := &v32.DynamicSchema{ + Spec: v32.DynamicSchemaSpec{ + ResourceFields: credFields, + }, + } + credentialSchema.Name = name + credentialSchema.OwnerReferences = []metav1.OwnerReference{ + { + UID: obj.UID, + Kind: obj.Kind, + APIVersion: obj.APIVersion, + Name: obj.Name, + }, + } + _, err := m.schemaClient.Create(credentialSchema) + return obj, err + } + return obj, err + } else if !reflect.DeepEqual(credSchema.Spec.ResourceFields, credFields) { + toUpdate := credSchema.DeepCopy() + toUpdate.Spec.ResourceFields = credFields + _, err := m.schemaClient.Update(toUpdate) + if err != nil { + return obj, err + } + } + return obj, nil +} + +func (m *Lifecycle) checkDriverVersion(obj *v32.NodeDriver) bool { + if v32.NodeDriverConditionDownloaded.IsUnknown(obj) || v32.NodeDriverConditionInstalled.IsUnknown(obj) { + return true + } + + driverName := strings.TrimPrefix(obj.Spec.DisplayName, drivers.DockerMachineDriverPrefix) + + if _, ok := DriverToSchemaFields[driverName]; ok { + if val, ok := obj.Annotations[uiFieldHintsAnno]; !ok || val == "" { + return true + } + } + + // Builtin drivers use the rancher-machine version to validate against + if obj.Spec.Builtin { + if obj.Status.AppliedDockerMachineVersion != m.dockerMachineVersion { + return true + } + return false + } + + if obj.Spec.URL != obj.Status.AppliedURL || obj.Spec.Checksum != obj.Status.AppliedChecksum { + return true + } + + return false +} + +func (m *Lifecycle) addVersionInfo(obj *v32.NodeDriver) *v32.NodeDriver { + if obj.Spec.Builtin { + obj.Status.AppliedDockerMachineVersion = m.dockerMachineVersion + } else { + obj.Status.AppliedURL = obj.Spec.URL + obj.Status.AppliedChecksum = obj.Spec.Checksum + } + return obj +} + +func (m *Lifecycle) addUIHintsAnno(driverName string, obj *v32.NodeDriver) (*v32.NodeDriver, error) { + if aliases, ok := DriverToSchemaFields[driverName]; ok { + anno := make(map[string]map[string]string) + + for _, aliased := range aliases { + anno[aliased] = map[string]string{ + "type": "multiline", + } + } + + jsonAnno, err := json.Marshal(anno) + if err != nil { + return obj, err + } + + if obj.Annotations == nil { + obj.Annotations = make(map[string]string) + } + + obj.Annotations[uiFieldHintsAnno] = string(jsonAnno) + } + return obj, nil +} + +func (m *Lifecycle) Updated(obj *v32.NodeDriver) (runtime.Object, error) { + var err error + + obj, err = m.download(obj) + if err != nil { + return obj, err + } + + if err := m.createOrUpdateNodeForEmbeddedType(obj.Spec.DisplayName+"config", obj.Spec.DisplayName+"Config", obj.Spec.Active); err != nil { + return obj, err + } + + if err := m.createOrUpdateNodeForEmbeddedTypeCredential(credentialConfigSchemaName(obj.Spec.DisplayName), + obj.Spec.DisplayName+"credentialConfig", obj.Spec.Active || obj.Spec.AddCloudCredential); err != nil { + return obj, err + } + + v32.NodeDriverConditionActive.True(obj) + v32.NodeDriverConditionInactive.True(obj) + + return obj, nil +} + +func (m *Lifecycle) Remove(obj *v32.NodeDriver) (runtime.Object, error) { + schemas, err := m.schemaClient.List(metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", driverNameLabel, obj.Spec.DisplayName), + }) + if err != nil { + return obj, err + } + for _, schema := range schemas.Items { + logrus.Infof("Deleting schema %s", schema.Name) + if err := m.schemaClient.Delete(schema.Name, &metav1.DeleteOptions{}); err != nil { + return obj, err + } + logrus.Infof("Deleting schema %s done", schema.Name) + } + if err := m.createOrUpdateNodeForEmbeddedType(obj.Spec.DisplayName+"config", obj.Spec.DisplayName+"Config", false); err != nil { + return obj, err + } + return obj, nil +} + +func (m *Lifecycle) createOrUpdateNodeForEmbeddedTypeCredential(embeddedType, fieldName string, embedded bool) error { + SchemaLock.Lock() + defer SchemaLock.Unlock() + + return m.createOrUpdateNodeForEmbeddedTypeWithParents(embeddedType, fieldName, "credentialconfig", "cloudCredential", embedded, true) +} + +func (m *Lifecycle) createOrUpdateNodeForEmbeddedType(embeddedType, fieldName string, embedded bool) error { + SchemaLock.Lock() + defer SchemaLock.Unlock() + + if err := m.createOrUpdateNodeForEmbeddedTypeWithParents(embeddedType, fieldName, "nodeconfig", "node", embedded, false); err != nil { + return err + } + + return m.createOrUpdateNodeForEmbeddedTypeWithParents(embeddedType, fieldName, "nodetemplateconfig", "nodeTemplate", embedded, true) +} + +func (m *Lifecycle) createOrUpdateNodeForEmbeddedTypeWithParents(embeddedType, fieldName, schemaID, parentID string, embedded, update bool) error { + nodeSchema, err := m.schemaLister.Get("", schemaID) + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + resourceField := map[string]v32.Field{} + if embedded { + resourceField[fieldName] = v32.Field{ + Create: true, + Nullable: true, + Update: update, + Type: embeddedType, + } + } + dynamicSchema := &v32.DynamicSchema{} + dynamicSchema.Name = schemaID + dynamicSchema.Spec.ResourceFields = resourceField + dynamicSchema.Spec.Embed = true + dynamicSchema.Spec.EmbedType = parentID + _, err := m.schemaClient.Create(dynamicSchema) + if err != nil { + return err + } + return nil + } + + nodeSchema = nodeSchema.DeepCopy() + + shouldUpdate := false + if embedded { + if nodeSchema.Spec.ResourceFields == nil { + nodeSchema.Spec.ResourceFields = map[string]v32.Field{} + } + if _, ok := nodeSchema.Spec.ResourceFields[fieldName]; !ok { + // if embedded we add the type to schema + logrus.Infof("uploading %s to %s schema", fieldName, schemaID) + nodeSchema.Spec.ResourceFields[fieldName] = v32.Field{ + Create: true, + Nullable: true, + Update: update, + Type: embeddedType, + } + shouldUpdate = true + } + } else { + // if not we delete it from schema + if _, ok := nodeSchema.Spec.ResourceFields[fieldName]; ok { + logrus.Infof("deleting %s from %s schema", fieldName, schemaID) + delete(nodeSchema.Spec.ResourceFields, fieldName) + shouldUpdate = true + } + } + + if shouldUpdate { + _, err = m.schemaClient.Update(nodeSchema) + if err != nil { + return err + } + } + + return nil +} + +func getCredFields(annotations map[string]string) (map[string]bool, map[string]bool, map[string]bool, map[string]string, map[string]bool) { + getMap := func(fields string) map[string]bool { + data := map[string]bool{} + for _, field := range strings.Split(fields, ",") { + data[field] = true + } + return data + } + getDefaults := func(fields string) map[string]string { + data := map[string]string{} + for _, pattern := range strings.Split(fields, ",") { + split := strings.SplitN(pattern, ":", 2) + if len(split) == 2 { + data[split[0]] = split[1] + } + } + return data + } + return getMap(annotations["publicCredentialFields"]), + getMap(annotations["privateCredentialFields"]), + getMap(annotations["passwordFields"]), + getDefaults(annotations["defaults"]), + getMap(annotations["optionalCredentialFields"]) +} + +func credentialConfigSchemaName(driverName string) string { + return fmt.Sprintf("%s%s", driverName, "credentialconfig") +} + +func updateDefault(credField v32.Field, val, kind string) v32.Field { + switch kind { + case "int": + i, err := strconv.Atoi(val) + if err == nil { + credField.Default = v32.Values{IntValue: i} + } else { + logrus.Errorf("error converting %s to int %v", val, err) + } + case "boolean": + credField.Default = v32.Values{BoolValue: convert.ToBool(val)} + case "array[string]": + credField.Default = v32.Values{StringSliceValue: convert.ToStringSlice(val)} + case "password", "string": + credField.Default = v32.Values{StringValue: val} + default: + logrus.Errorf("unsupported kind for default val:%s kind:%s", val, kind) + } + return credField +} + +func getRancherMachineVersion() (string, error) { + cmd := exec.Command("rancher-machine", "--version") + out, err := cmd.CombinedOutput() + return string(out), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/utils.go new file mode 100644 index 0000000..0c32018 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/drivers/nodedriver/utils.go @@ -0,0 +1,117 @@ +package nodedriver + +import ( + "fmt" + "net/rpc" + "reflect" + "strconv" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/machine/libmachine/drivers/plugin/localbinary" + rpcdriver "github.com/rancher/machine/libmachine/drivers/rpc" + cli "github.com/rancher/machine/libmachine/mcnflag" + "github.com/sirupsen/logrus" +) + +func FlagToField(flag cli.Flag) (string, v32.Field, error) { + field := v32.Field{ + Create: true, + Update: true, + Type: "string", + } + + name, err := ToLowerCamelCase(flag.String()) + if err != nil { + return name, field, err + } + + switch v := flag.(type) { + case *cli.StringFlag: + field.Description = v.Usage + field.Default.StringValue = v.Value + case *cli.IntFlag: + // This will make the int flag appear as a string field in the rancher API, but we are doing this to maintain + // backward compatibility, at least until we fix a bug that prevents nodeDriver schemas from updating upon + // a Rancher upgrade + field.Description = v.Usage + field.Default.StringValue = strconv.Itoa(v.Value) + case *cli.BoolFlag: + field.Type = "boolean" + field.Description = v.Usage + case *cli.StringSliceFlag: + field.Type = "array[string]" + field.Description = v.Usage + field.Nullable = true + field.Default.StringSliceValue = v.Value + case *BoolPointerFlag: + field.Type = "boolean" + field.Description = v.Usage + default: + return name, field, fmt.Errorf("unknown type of flag %v: %v", flag, reflect.TypeOf(flag)) + } + + return name, field, nil +} + +func ToLowerCamelCase(nodeFlagName string) (string, error) { + parts := strings.SplitN(nodeFlagName, "-", 2) + if len(parts) != 2 { + return "", fmt.Errorf("parameter %s does not follow expected naming convention [DRIVER]-[FLAG-NAME]", nodeFlagName) + } + flagNameParts := strings.Split(parts[1], "-") + flagName := flagNameParts[0] + for _, flagNamePart := range flagNameParts[1:] { + flagName = flagName + strings.ToUpper(flagNamePart[:1]) + flagNamePart[1:] + } + return flagName, nil +} + +func getCreateFlagsForDriver(driver string) ([]cli.Flag, error) { + var flags []cli.Flag + // NOTE(cmurphy): There is not currently a real google machine driver, but + // we still want to be able to create a Google cloud credential to use with + // GKE. This fake driver flag allows us to go through the motions of + // handling the credential fields without actually needing to run the + // machine driver binary. + if driver == "google" { + flags = []cli.Flag{ + &cli.StringFlag{ + Name: "google-auth-encoded-json", + }, + } + return flags, nil + } + + logrus.Debug("Starting binary ", driver) + p, err := localbinary.NewPlugin(driver) + if err != nil { + return nil, err + } + go func() { + err := p.Serve() + if err != nil { + logrus.Debugf("Error serving plugin server for driver=%s, err=%v", driver, err) + } + }() + defer p.Close() + addr, err := p.Address() + if err != nil { + return nil, err + } + + rpcclient, err := rpc.DialHTTP("tcp", addr) + if err != nil { + return nil, fmt.Errorf("Error dialing to plugin server's address(%v), err=%v", addr, err) + } + defer rpcclient.Close() + + c := rpcdriver.NewInternalClient(rpcclient) + + if err := c.Call(".GetCreateFlags", struct{}{}, &flags); err != nil { + return nil, fmt.Errorf("Error getting flags err=%v", err) + } + + return flags, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler.go new file mode 100644 index 0000000..5a74ad0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler.go @@ -0,0 +1,635 @@ +package eks + +import ( + "context" + "encoding/base64" + stderrors "errors" + "fmt" + "net" + "net/url" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/eks" + eksv1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + "github.com/rancher/eks-operator/utils" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + "github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/dialer" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + typesDialer "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "sigs.k8s.io/aws-iam-authenticator/pkg/token" +) + +const ( + eksAPIGroup = "eks.cattle.io" + eksV1 = "eks.cattle.io/v1" + eksOperatorTemplate = "system-library-rancher-eks-operator" + eksOperator = "rancher-eks-operator" + eksShortName = "EKS" + enqueueTime = time.Second * 5 + importedAnno = "eks.cattle.io/imported" +) + +type eksOperatorController struct { + clusteroperator.OperatorController + secretClient corecontrollers.SecretClient +} + +func Register(ctx context.Context, wContext *wrangler.Context, mgmtCtx *config.ManagementContext) { + eksClusterConfigResource := schema.GroupVersionResource{ + Group: eksAPIGroup, + Version: "v1", + Resource: "eksclusterconfigs", + } + + eksCCDynamicClient := mgmtCtx.DynamicClient.Resource(eksClusterConfigResource) + e := &eksOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: wContext.Mgmt.Cluster().EnqueueAfter, + SecretsCache: wContext.Core.Secret().Cache(), + Secrets: mgmtCtx.Core.Secrets(""), + TemplateCache: wContext.Mgmt.CatalogTemplate().Cache(), + ProjectCache: wContext.Mgmt.Project().Cache(), + AppLister: mgmtCtx.Project.Apps("").Controller().Lister(), + AppClient: mgmtCtx.Project.Apps(""), + NsClient: mgmtCtx.Core.Namespaces(""), + ClusterClient: wContext.Mgmt.Cluster(), + CatalogManager: mgmtCtx.CatalogManager, + SystemAccountManager: systemaccount.NewManager(mgmtCtx), + DynamicClient: eksCCDynamicClient, + ClientDialer: mgmtCtx.Dialer, + Discovery: wContext.K8s.Discovery(), + }, + secretClient: wContext.Core.Secret(), + } + + wContext.Mgmt.Cluster().OnChange(ctx, "eks-operator-controller", e.onClusterChange) +} + +func (e *eksOperatorController) onClusterChange(key string, cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil { + return cluster, nil + } + + if cluster.Spec.EKSConfig == nil { + return cluster, nil + } + + cluster, err := e.CheckCrdReady(cluster, "eks") + if err != nil { + return cluster, err + } + + // set driver name + if cluster.Status.Driver == "" { + cluster = cluster.DeepCopy() + cluster.Status.Driver = apimgmtv3.ClusterDriverEKS + var err error + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + + // get EKS Cluster Config, if it does not exist, create it + eksClusterConfigDynamic, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Get(context.TODO(), cluster.Name, v1.GetOptions{}) + if err != nil { + if !errors.IsNotFound(err) { + return cluster, err + } + + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "Waiting for API to be available") + if err != nil { + return cluster, err + } + + eksClusterConfigDynamic, err = buildEKSCCCreateObject(cluster) + if err != nil { + return cluster, err + } + + eksClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Create(context.TODO(), eksClusterConfigDynamic, v1.CreateOptions{}) + if err != nil { + return cluster, err + } + + } + + eksClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&cluster.Spec.EKSConfig) + if err != nil { + return cluster, err + } + + // check for changes between EKS spec on cluster and the EKS spec on the EKSClusterConfig object + if !reflect.DeepEqual(eksClusterConfigMap, eksClusterConfigDynamic.Object["spec"]) { + logrus.Infof("change detected for cluster [%s], updating EKSClusterConfig", cluster.Name) + return e.updateEKSClusterConfig(cluster, eksClusterConfigDynamic, eksClusterConfigMap) + } + + // get EKS Cluster Config's phase + status, _ := eksClusterConfigDynamic.Object["status"].(map[string]interface{}) + phase, _ := status["phase"] + failureMessage, _ := status["failureMessage"].(string) + if strings.Contains(failureMessage, "403") { + failureMessage = fmt.Sprintf("cannot access EKS, check cloud credential: %s", failureMessage) + } + switch phase { + case "creating": + if cluster.Status.EKSStatus.UpstreamSpec == nil { + cluster, err = e.setInitialUpstreamSpec(cluster) + if err != nil { + if !notFound(err) { + return cluster, err + } + } + return cluster, nil + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster EKS [%s] to finish creating", cluster.Name) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster EKS [%s] create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + case "active": + if cluster.Spec.EKSConfig.Imported { + if cluster.Status.EKSStatus.UpstreamSpec == nil { + // non imported clusters will have already had upstream spec set + return e.setInitialUpstreamSpec(cluster) + } + + if apimgmtv3.ClusterConditionPending.IsUnknown(cluster) { + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionPending.True(cluster) + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + } + + if apimgmtv3.ClusterConditionUpdated.IsFalse(cluster) && strings.HasPrefix(apimgmtv3.ClusterConditionUpdated.GetMessage(cluster), "[Syncing error") { + return cluster, fmt.Errorf(apimgmtv3.ClusterConditionUpdated.GetMessage(cluster)) + } + + // EKS cluster must have at least one node to run cluster agent. The best way to verify + // if a cluster has self-managed node or nodegroup is to check if the cluster agent was deployed. + // Issue: https://github.com/rancher/eks-operator/issues/301 + addNgMessage := "Cluster must have at least one managed nodegroup or one self-managed node." + noNodeGroupsOnSpec := len(cluster.Spec.EKSConfig.NodeGroups) == 0 + noNodeGroupsOnUpstreamSpec := len(cluster.Status.EKSStatus.UpstreamSpec.NodeGroups) == 0 + if !apimgmtv3.ClusterConditionAgentDeployed.IsTrue(cluster) && + ((cluster.Spec.EKSConfig.NodeGroups != nil && noNodeGroupsOnSpec) || + (cluster.Spec.EKSConfig.NodeGroups == nil && noNodeGroupsOnUpstreamSpec)) { + cluster, err = e.SetFalse(cluster, apimgmtv3.ClusterConditionWaiting, addNgMessage) + if err != nil { + return cluster, err + } + } else { + if apimgmtv3.ClusterConditionWaiting.GetMessage(cluster) == addNgMessage { + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionWaiting.Message(cluster, "Waiting for API to be available") + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + } + + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + // If there are no subnets it can be assumed that networking fields are not provided. In which case they + // should be created by the eks-operator, and needs to be copied to the cluster object. + if len(cluster.Status.EKSStatus.Subnets) == 0 { + subnets, _ := status["subnets"].([]interface{}) + if len(subnets) != 0 { + // network field have been generated and are ready to be copied + virtualNetwork, _ := status["virtualNetwork"].(string) + subnets, _ := status["subnets"].([]interface{}) + securityGroups, _ := status["securityGroups"].([]interface{}) + cluster = cluster.DeepCopy() + + // change fields on status to not be generated + cluster.Status.EKSStatus.VirtualNetwork = virtualNetwork + for _, val := range subnets { + cluster.Status.EKSStatus.Subnets = append(cluster.Status.EKSStatus.Subnets, val.(string)) + } + for _, val := range securityGroups { + cluster.Status.EKSStatus.SecurityGroups = append(cluster.Status.EKSStatus.SecurityGroups, val.(string)) + } + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + } + + if cluster.Status.APIEndpoint == "" { + return e.RecordCAAndAPIEndpoint(cluster) + } + + if cluster.Status.EKSStatus.PrivateRequiresTunnel == nil && !*cluster.Status.EKSStatus.UpstreamSpec.PublicAccess { + // In this case, the API endpoint is private and it has not been determined if Rancher must tunnel to communicate with it. + // Check to see if we can still use the public API endpoint even though + // the cluster has private-only access + serviceToken, mustTunnel, err := e.generateSATokenWithPublicAPI(cluster) + if mustTunnel != nil { + cluster = cluster.DeepCopy() + cluster.Status.EKSStatus.PrivateRequiresTunnel = mustTunnel + if serviceToken != "" { + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, serviceToken, cluster) + if err != nil { + return cluster, err + } + if secret == nil { + logrus.Debugf("Empty service account token secret returned for cluster [%s]", cluster.Name) + return cluster, fmt.Errorf("failed to create or update service account token secret, secret can't be empty") + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + } + return e.ClusterClient.Update(cluster) + } + if err != nil { + return cluster, err + } + } + + if cluster.Status.ServiceAccountTokenSecret == "" { + cluster, err = e.generateAndSetServiceAccount(cluster) + if err != nil { + var statusErr error + if err == dialer.ErrAgentDisconnected { + // In this case, the API endpoint is private and rancher is waiting for the import cluster command to be run. + cluster, statusErr = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "waiting for cluster agent to be deployed") + if statusErr == nil { + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + } + return cluster, statusErr + } + cluster, statusErr = e.SetFalse(cluster, apimgmtv3.ClusterConditionWaiting, + fmt.Sprintf("failed to communicate with cluster: %v", err)) + if statusErr != nil { + return cluster, statusErr + } + return cluster, err + } + } + + managedLaunchTemplateID, _ := status["managedLaunchTemplateID"].(string) + if managedLaunchTemplateID != "" && cluster.Status.EKSStatus.ManagedLaunchTemplateID != managedLaunchTemplateID { + cluster = cluster.DeepCopy() + cluster.Status.EKSStatus.ManagedLaunchTemplateID = managedLaunchTemplateID + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + + managedLaunchTemplateVersions, _ := status["managedLaunchTemplateVersions"].(map[string]interface{}) + if !reflect.DeepEqual(cluster.Status.EKSStatus.ManagedLaunchTemplateVersions, managedLaunchTemplateVersions) { + managedLaunchTemplateVersionsToString := make(map[string]string, len(managedLaunchTemplateVersions)) + for key, value := range managedLaunchTemplateVersions { + managedLaunchTemplateVersionsToString[key] = value.(string) + } + cluster = cluster.DeepCopy() + cluster.Status.EKSStatus.ManagedLaunchTemplateVersions = managedLaunchTemplateVersionsToString + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + + generatedNodeRole, _ := status["generatedNodeRole"].(string) + if generatedNodeRole != "" && cluster.Status.EKSStatus.GeneratedNodeRole != generatedNodeRole { + cluster = cluster.DeepCopy() + cluster.Status.EKSStatus.GeneratedNodeRole = generatedNodeRole + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + + return e.SetTrue(cluster, apimgmtv3.ClusterConditionUpdated, "") + case "updating": + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster EKS [%s] to update", cluster.Name) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + } + logrus.Infof("waiting for cluster EKS [%s] update failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionUpdated, failureMessage) + default: + if cluster.Spec.EKSConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + if cluster.Spec.EKSConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster EKS [%s] pre-create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + } +} + +func (e *eksOperatorController) setInitialUpstreamSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + cluster = cluster.DeepCopy() + upstreamSpec, err := clusterupstreamrefresher.BuildEKSUpstreamSpec(e.secretClient, cluster) + if err != nil { + return cluster, err + } + cluster.Status.EKSStatus.UpstreamSpec = upstreamSpec + return e.ClusterClient.Update(cluster) +} + +// updateEKSClusterConfig updates the EKSClusterConfig object's spec with the cluster's EKSConfig if they are not equal.. +func (e *eksOperatorController) updateEKSClusterConfig(cluster *mgmtv3.Cluster, eksClusterConfigDynamic *unstructured.Unstructured, spec map[string]interface{}) (*mgmtv3.Cluster, error) { + list, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).List(context.TODO(), v1.ListOptions{}) + if err != nil { + return cluster, err + } + selector := fields.OneTermEqualSelector("metadata.name", cluster.Name) + w, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Watch(context.TODO(), v1.ListOptions{ResourceVersion: list.GetResourceVersion(), FieldSelector: selector.String()}) + if err != nil { + return cluster, err + } + eksClusterConfigDynamic.Object["spec"] = spec + eksClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Update(context.TODO(), eksClusterConfigDynamic, v1.UpdateOptions{}) + if err != nil { + return cluster, err + } + + // EKS cluster and node group statuses are not always immediately updated. This cause the EKSConfig to + // stay in "active" for a few seconds, causing the cluster to go back to "active". + timeout := time.NewTimer(10 * time.Second) + for { + select { + case event := <-w.ResultChan(): + eksClusterConfigDynamic = event.Object.(*unstructured.Unstructured) + status, _ := eksClusterConfigDynamic.Object["status"].(map[string]interface{}) + if status["phase"] == "active" { + continue + } + + // this enqueue is necessary to ensure that the controller is reentered with the updating phase + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + case <-timeout.C: + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + return cluster, nil + } + } +} + +// generateAndSetServiceAccount uses the API endpoint and CA cert to generate a service account token. The token is then copied to the cluster status. +func (e *eksOperatorController) generateAndSetServiceAccount(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + clusterDialer, err := e.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + restConfig, err := e.getRestConfig(cluster, clusterDialer) + if err != nil { + return cluster, err + } + + saToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + return cluster, err + } + + cluster = cluster.DeepCopy() + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, saToken, cluster) + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return e.ClusterClient.Update(cluster) +} + +// buildEKSCCCreateObject returns an object that can be used with the kubernetes dynamic client to +// create an EKSClusterConfig that matches the spec contained in the cluster's EKSConfig. +func buildEKSCCCreateObject(cluster *mgmtv3.Cluster) (*unstructured.Unstructured, error) { + eksClusterConfig := eksv1.EKSClusterConfig{ + TypeMeta: v1.TypeMeta{ + Kind: "EKSClusterConfig", + APIVersion: eksV1, + }, + ObjectMeta: v1.ObjectMeta{ + Name: cluster.Name, + OwnerReferences: []v1.OwnerReference{ + { + Kind: cluster.Kind, + APIVersion: rbac.RancherManagementAPIVersion, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + Spec: *cluster.Spec.EKSConfig, + } + + // convert EKS cluster config into unstructured object so it can be used with dynamic client + eksClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&eksClusterConfig) + if err != nil { + return nil, err + } + + return &unstructured.Unstructured{ + Object: eksClusterConfigMap, + }, nil +} + +// recordAppliedSpec sets the cluster's current spec as its appliedSpec +func (e *eksOperatorController) recordAppliedSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if reflect.DeepEqual(cluster.Status.AppliedSpec.EKSConfig, cluster.Spec.EKSConfig) { + return cluster, nil + } + + cluster = cluster.DeepCopy() + cluster.Status.AppliedSpec.EKSConfig = cluster.Spec.EKSConfig + return e.ClusterClient.Update(cluster) +} + +// generateSATokenWithPublicAPI tries to get a service account token from the cluster using the public API endpoint. +// This function is called if the cluster has only privateEndpoint enabled and not publicly available. +// If Rancher is able to communicate with the cluster through its API endpoint even though it is private, then this function will retrieve +// a service account token and the *bool returned will refer to a false value (doesn't have to tunnel). +// +// If the Rancher server cannot connect to the cluster's API endpoint, then one of the two errors below will happen. +// In this case, we know that Rancher must use the cluster agent tunnel for communication. This function will return an empty service account token, +// and the *bool return value will refer to a true value (must tunnel). +// +// If an error different from the two below occur, then the *bool return value will be nil, indicating that Rancher was not able to determine if +// tunneling is required to communicate with the cluster. +func (e *eksOperatorController) generateSATokenWithPublicAPI(cluster *mgmtv3.Cluster) (string, *bool, error) { + restConfig, err := e.getRestConfig(cluster, (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext) + if err != nil { + return "", nil, err + } + + requiresTunnel := new(bool) + serviceToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + *requiresTunnel = true + var dnsError *net.DNSError + if stderrors.As(err, &dnsError) && !dnsError.IsTemporary { + return "", requiresTunnel, nil + } + + // In the existence of a proxy, it may be the case that the following error occurs, + // in which case rancher should use the tunnel connection to communicate with the cluster. + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + + // Not able to determine if tunneling is required. + requiresTunnel = nil + } + + return serviceToken, requiresTunnel, err +} + +func (e *eksOperatorController) getAWSSession(cluster *mgmtv3.Cluster) (*session.Session, error) { + awsConfig := &aws.Config{} + eksConfig := cluster.Spec.EKSConfig + + if region := eksConfig.Region; region != "" { + awsConfig.Region = aws.String(region) + } + + ns, id := utils.Parse(eksConfig.AmazonCredentialSecret) + if amazonCredentialSecret := eksConfig.AmazonCredentialSecret; amazonCredentialSecret != "" { + secret, err := e.SecretsCache.Get(ns, id) + if err != nil { + return nil, fmt.Errorf("error getting secret %s/%s: %w", ns, id, err) + } + + accessKeyBytes := secret.Data["amazonec2credentialConfig-accessKey"] + secretKeyBytes := secret.Data["amazonec2credentialConfig-secretKey"] + if accessKeyBytes == nil || secretKeyBytes == nil { + return nil, fmt.Errorf("invalid aws cloud credential") + } + + accessKey := string(accessKeyBytes) + secretKey := string(secretKeyBytes) + + awsConfig.Credentials = credentials.NewStaticCredentials(accessKey, secretKey, "") + } + + sess, err := session.NewSession(awsConfig) + if err != nil { + return nil, fmt.Errorf("error getting new aws session: %w", err) + } + return sess, nil +} + +func (e *eksOperatorController) getAccessToken(cluster *mgmtv3.Cluster) (string, error) { + sess, err := e.getAWSSession(cluster) + if err != nil { + return "", err + } + generator, err := token.NewGenerator(false, false) + if err != nil { + return "", err + } + + awsToken, err := generator.GetWithOptions(&token.GetTokenOptions{ + Session: sess, + ClusterID: cluster.Spec.EKSConfig.DisplayName, + }) + if err != nil { + return "", err + } + + return awsToken.Token, nil +} + +func (e *eksOperatorController) getRestConfig(cluster *mgmtv3.Cluster, dialer typesDialer.Dialer) (*rest.Config, error) { + accessToken, err := e.getAccessToken(cluster) + if err != nil { + return nil, err + } + + decodedCA, err := base64.StdEncoding.DecodeString(cluster.Status.CACert) + if err != nil { + return nil, err + } + + return &rest.Config{ + Host: cluster.Status.APIEndpoint, + TLSClientConfig: rest.TLSClientConfig{ + CAData: decodedCA, + }, + BearerToken: accessToken, + Dial: dialer, + }, nil +} + +func notFound(err error) bool { + if awsErr, ok := err.(awserr.Error); ok { + return awsErr.Code() == eks.ErrCodeResourceNotFoundException + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_interface_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_interface_test.go new file mode 100644 index 0000000..9bd3f81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_interface_test.go @@ -0,0 +1,613 @@ +package eks + +import ( + "context" + "net" + + openapi2 "github.com/google/gnostic-models/openapiv2" + "github.com/rancher/rancher/pkg/types/config/dialer" + meta1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/version" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/openapi" + "k8s.io/client-go/rest" +) + +const ( + MockDefaultEksClusterConfigFilename = "test/onclusterchange_ekscc_default.json" + MockCreateEksClusterConfigFilename = "test/onclusterchange_ekscc_create.json" + MockActiveEksClusterConfigFilename = "test/onclusterchange_ekscc_active.json" + MockUpdateEksClusterConfigFilename = "test/onclusterchange_ekscc_update.json" + MockEksClusterConfigUpdatedFilename = "test/updateeksclusterconfig_updated.json" +) + +// mock interfaces + +// mock dynamic client (to return a mock EksClusterConfig) + +// Test 1 - cluster in default/unknown state. Get will return an EksClusterConfig with an unknown provisioning phase. +// The rest of the method signatures have to be implemented to mock the interface. There will be one mock of this +// interface for each test. + +type MockNamespaceableResourceInterfaceDefault struct{} + +func (m MockNamespaceableResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceDefault{} +} + +func (m MockNamespaceableResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceDefault struct{} + +func (m MockResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockDefaultEksClusterConfigFilename) +} + +func (m MockResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} +func (m MockResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 2 - cluster in creating state + +type MockNamespaceableResourceInterfaceCreate struct{} + +func (m MockNamespaceableResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceCreate{} +} + +func (m MockNamespaceableResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceCreate struct{} + +func (m MockResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockCreateEksClusterConfigFilename) +} + +func (m MockResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 3 - cluster in active state + +type MockNamespaceableResourceInterfaceActive struct{} + +func (m MockNamespaceableResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceActive{} +} + +func (m MockNamespaceableResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceActive struct{} + +func (m MockResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockActiveEksClusterConfigFilename) +} + +func (m MockResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + // TODO implement me + panic("implement me") +} + +func (m MockResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + // TODO implement me + panic("implement me") +} + +// Test 4 - cluster in update node pool state + +type MockNamespaceableResourceInterfaceUpdate struct{} + +func (m MockNamespaceableResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceUpdate{} +} + +func (m MockNamespaceableResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceUpdate struct{} + +func (m MockResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockUpdateEksClusterConfigFilename) +} + +func (m MockResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test UpdateEksClusterConfig + +type MockNamespaceableResourceInterfaceEksCC struct{} + +func (m MockNamespaceableResourceInterfaceEksCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceEksCC{} +} + +func (m MockNamespaceableResourceInterfaceEksCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceEksCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceEksCC struct{} + +func (m MockResourceInterfaceEksCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceEksCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockEksClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceEksCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceEksCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceEksCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceEksCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockEksClusterConfig(MockEksClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceEksCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return &unstructured.UnstructuredList{ + Object: map[string]interface{}{ + "apiVersion": "Eks.cattle.io/v1", + "kind": "EksClusterConfigList", + "metadata": map[string]interface{}{"resourceVersion": "142650"}, + }, + Items: nil, + }, nil +} + +func (m MockResourceInterfaceEksCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceEksCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// mock interface that returns a watch event (for updateEksClusterConfig test) + +type MockInterface struct{} + +func (m MockInterface) Stop() {} + +func (m MockInterface) ResultChan() <-chan watch.Event { + return make(chan watch.Event) +} + +func (m MockResourceInterfaceEksCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return MockInterface{}, nil +} + +func (m MockResourceInterfaceEksCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// mock cluster dialer + +type MockFactory struct{} + +func (m MockFactory) ClusterDialer(clusterName string, retryOnError bool) (dialer.Dialer, error) { + // pass a dialer func to the client + dialer := func(ctx context.Context, network, address string) (net.Conn, error) { + return nil, nil + } + return dialer, nil +} + +func (m MockFactory) DockerDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +func (m MockFactory) NodeDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +type Dialer func(ctx context.Context, network, address string) (net.Conn, error) + +// mock discovery + +type MockDiscovery struct{} + +func (m MockDiscovery) RESTClient() rest.Interface { + panic("implement me") +} + +func (m MockDiscovery) ServerGroups() (*meta1.APIGroupList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*meta1.APIResourceList, error) { + + return &meta1.APIResourceList{ + TypeMeta: meta1.TypeMeta{}, + GroupVersion: "", + APIResources: []meta1.APIResource{ + {Name: "EksClusterConfig"}, + {Name: "status"}}, + }, nil +} + +func (m MockDiscovery) ServerGroupsAndResources() ([]*meta1.APIGroup, []*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredNamespacedResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerVersion() (*version.Info, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPISchema() (*openapi2.Document, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPIV3() openapi.Client { + panic("implement me") +} + +func (m MockDiscovery) WithLegacy() discovery.DiscoveryInterface { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_test.go new file mode 100644 index 0000000..78366a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_mockc_test.go @@ -0,0 +1,242 @@ +//nolint:all // this file was originally generated by github.com/kelveny/mockcompose +package eks + +import ( + "embed" + "encoding/base64" + stderrors "errors" + "net" + "net/url" + "testing" + "time" + + "github.com/ghodss/yaml" + "github.com/golang/mock/gomock" + v1 "github.com/rancher/eks-operator/pkg/apis/eks.cattle.io/v1" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesDialer "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + secretv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/json" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +//go:embed test/* +var testFs embed.FS + +type mockEksOperatorController struct { + eksOperatorController + mock.Mock +} + +func getMockEksOperatorController(t *testing.T, clusterState string) mockEksOperatorController { + t.Helper() + ctrl := gomock.NewController(t) + clusterMock := fake.NewMockNonNamespacedClientInterface[*apisv3.Cluster, *apisv3.ClusterList](ctrl) + clusterMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(c *apisv3.Cluster) (*apisv3.Cluster, error) { + return c, nil + }, + ).AnyTimes() + + var dynamicClient dynamic.NamespaceableResourceInterface + + switch clusterState { + case "default": + dynamicClient = MockNamespaceableResourceInterfaceDefault{} + case "create": + dynamicClient = MockNamespaceableResourceInterfaceCreate{} + case "active": + dynamicClient = MockNamespaceableResourceInterfaceActive{} + case "update": + dynamicClient = MockNamespaceableResourceInterfaceUpdate{} + case "Ekscc": + dynamicClient = MockNamespaceableResourceInterfaceEksCC{} + default: + dynamicClient = nil + } + + return mockEksOperatorController{ + eksOperatorController: eksOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: func(name string, duration time.Duration) {}, + SecretsCache: nil, + Secrets: nil, + TemplateCache: nil, + ProjectCache: nil, + AppLister: nil, + AppClient: nil, + NsClient: nil, + ClusterClient: clusterMock, + CatalogManager: nil, + SystemAccountManager: nil, + DynamicClient: dynamicClient, + ClientDialer: MockFactory{}, + Discovery: MockDiscovery{}, + }, + }, + Mock: mock.Mock{}, + } +} + +// test setInitialUpstreamSpec + +func (m *mockEksOperatorController) setInitialUpstreamSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + + // mock + upstreamSpec := &v1.EKSClusterConfigSpec{} + + cluster = cluster.DeepCopy() + cluster.Status.EKSStatus.UpstreamSpec = upstreamSpec + return m.ClusterClient.Update(cluster) +} + +// test generateAndSetServiceAccount with mock sibling func (getAccessToken) + +func (m *mockEksOperatorController) generateAndSetServiceAccount(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + clusterDialer, err := m.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + _, err = m.getRestConfig(cluster, clusterDialer) + if err != nil { + return cluster, err + } + + // mock + secret := secretv1.Secret{} + secret.Name = "cluster-serviceaccounttoken-sl7wm" + + cluster = cluster.DeepCopy() + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return m.ClusterClient.Update(cluster) +} + +// test generateSATokenWithPublicAPI with mock sibling func (getRestConfig) + +func (m *mockEksOperatorController) generateSATokenWithPublicAPI(cluster *mgmtv3.Cluster) (string, *bool, error) { + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + _, err := m.getRestConfig(cluster, (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext) + if err != nil { + return "", nil, err + } + + requiresTunnel := new(bool) + + // mock serviceToken + serviceToken, err := "testtoken12345", nil + + if err != nil { + *requiresTunnel = true + var dnsError *net.DNSError + if stderrors.As(err, &dnsError) && !dnsError.IsTemporary { + return "", requiresTunnel, nil + } + + // In the existence of a proxy, it may be the case that the following error occurs, + // in which case rancher should use the tunnel connection to communicate with the cluster. + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + + // Not able to determine if tunneling is required. + requiresTunnel = nil + } + + return serviceToken, requiresTunnel, err +} + +func (m *mockEksOperatorController) getAccessToken(cluster *mgmtv3.Cluster) (string, error) { + + _mc_ret := m.Called(cluster) + + var _r0 string + + if _rfn, ok := _mc_ret.Get(0).(func(*mgmtv3.Cluster) string); ok { + _r0 = _rfn(cluster) + } else { + if _mc_ret.Get(0) != nil { + _r0 = _mc_ret.Get(0).(string) + } + } + + var _r1 error + + if _rfn, ok := _mc_ret.Get(1).(func(*mgmtv3.Cluster) error); ok { + _r1 = _rfn(cluster) + } else { + _r1 = _mc_ret.Error(1) + } + + return _r0, _r1 + +} + +func (m *mockEksOperatorController) getRestConfig(cluster *mgmtv3.Cluster, dialer typesDialer.Dialer) (*rest.Config, error) { + // mock + m.Mock.On("getAccessToken", cluster).Return("testaccesstoken", nil) + + accessToken, err := m.getAccessToken(cluster) + if err != nil { + return nil, err + } + decodedCA, err := base64.StdEncoding.DecodeString(cluster.Status.CACert) + if err != nil { + return nil, err + } + return &rest.Config{Host: cluster.Status.APIEndpoint, TLSClientConfig: rest.TLSClientConfig{CAData: decodedCA}, BearerToken: accessToken, Dial: dialer}, nil +} + +// utility + +func getMockV3Cluster(filename string) (mgmtv3.Cluster, error) { + var mockCluster mgmtv3.Cluster + + // Read the embedded file + cluster, err := testFs.ReadFile(filename) + if err != nil { + return mockCluster, err + } + // Unmarshal cluster yaml into a management v3 cluster object + err = yaml.Unmarshal(cluster, &mockCluster) + if err != nil { + return mockCluster, err + } + + return mockCluster, nil +} + +func getMockEksClusterConfig(filename string) (*unstructured.Unstructured, error) { + var EksClusterConfig *unstructured.Unstructured + + // Read the embedded file + bytes, err := testFs.ReadFile(filename) + if err != nil { + return EksClusterConfig, err + } + // Unmarshal json into an unstructured cluster config object + err = json.Unmarshal(bytes, &EksClusterConfig) + if err != nil { + return EksClusterConfig, err + } + + return EksClusterConfig, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_test.go new file mode 100644 index 0000000..4862c97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/eks_cluster_handler_test.go @@ -0,0 +1,292 @@ +package eks + +import ( + "github.com/rancher/rancher/pkg/capr" + "reflect" + "testing" + + "github.com/Azure/go-autorest/autorest/to" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" +) + +const ( + MockDefaultClusterFilename = "test/onclusterchange_default.yaml" + MockCreateClusterFilename = "test/onclusterchange_create.yaml" + MockActiveClusterFilename = "test/onclusterchange_active.yaml" + MockUpdateClusterFilename = "test/onclusterchange_update.yaml" + MockEksClusterConfigFilename = "test/updateeksclusterconfig.json" + MockEksClusterConfigClusterFilename = "test/updateeksclusterconfig.yaml" + MockBuildEksCCCreateObjectFilename = "test/buildekscccreateobject.json" +) + +var mockOperatorController mockEksOperatorController // Operator controller with mock interfaces & sibling funcs + +/* +* Test_onClusterChange +- cluster == nil. Return (nil nil) +- cluster.DeletionTimestamp or cluster.EksConfig == nil, return (nil nil) +- default phase +- create phase +- active phase +- update node pool phase +*/ +func Test_onClusterChange_ClusterIsNil(t *testing.T) { + cluster, _ := mockOperatorController.onClusterChange("", nil) + if cluster != nil { + t.Errorf("cluster should have returned nil") + } +} + +func Test_onClusterChange_EKSConfigIsNil(t *testing.T) { + mockCluster := &v3.Cluster{ + Spec: v3.ClusterSpec{ + EKSConfig: nil, + }, + } + + cluster, _ := mockOperatorController.onClusterChange("", mockCluster) + if !reflect.DeepEqual(cluster, mockCluster) { + t.Errorf("cluster should have returned with no update") + } +} + +func Test_onClusterChange_Default(t *testing.T) { + + // setup + // create an instance of the operator controller with mock data to simulate the onChangeCluster function reacting + // to a real cluster! + mockOperatorController = getMockEksOperatorController(t, "default") + + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + // run test + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // validate results + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Create(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Active(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsTrue(cluster) { + t.Errorf("provisioned and updated status should be True and cluster returned successfully") + } +} + +func Test_onClusterChange_UpdateNodePool(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "update") + mockCluster, err := getMockV3Cluster(MockUpdateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // check that cluster is updating node pool + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsUnknown(cluster) { + t.Errorf("provisioned status should be True, updated status should be Unknown and cluster returned successfully") + } +} + +/* +* Test_setInitialUpstreamSpec +- success: buildUpstreamClusterState returns a valid upstream spec +*/ +func Test_setInitialUpstreamSpec(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.setInitialUpstreamSpec(&mockCluster) + + if err != nil { + t.Errorf("error running setInitialUpstreamSpec: %s", err) + } + if cluster.Status.EKSStatus.UpstreamSpec == nil { + t.Errorf("upstreamSpec should have been set and cluster returned successfully") + } +} + +/* +* Test_updateEKSClusterConfig + - success: EKS cluster tags are removed. EKS cluster is not immediately updated. Cluster sits in active for a few + seconds, return (cluster nil) +*/ +func Test_updateEKSClusterConfig(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "Ekscc") + mockCluster, err := getMockV3Cluster(MockEksClusterConfigClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + mockEksClusterConfig, err := getMockEksClusterConfig(MockEksClusterConfigFilename) + + // test remove tags from the cluster + _, err = mockOperatorController.updateEKSClusterConfig(&mockCluster, mockEksClusterConfig, nil) + + if err != nil { + t.Errorf("error running updateEKSClusterConfig: %s", err) + } +} + +/* +* Test_generateAndSetServiceAccount +- success: service account token generated, cluster updated! Return updated cluster.Status +- error generating service account token. Return (cluster, err) +*/ +func Test_generateAndSetServiceAccount(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.generateAndSetServiceAccount(&mockCluster) + + // check that serviceAccountToken name and token are set + if err != nil { + t.Errorf("error running generateAndSetServiceAccount: %s", err) + } + if cluster.Status.ServiceAccountTokenSecret == "" { + t.Errorf("service account token secret should have been set on Status and cluster returned successfully") + } +} + +/* +* Test_buildEKSCCCreateObject +- success: EKSClusterConfig object created, return (EKSClusterConfig nil) +*/ +func Test_buildEKSCCCreateObject(t *testing.T) { + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + expected, err := getMockEksClusterConfig(MockBuildEksCCCreateObjectFilename) + + ekscc, err := buildEKSCCCreateObject(&mockCluster) + + if err != nil { + t.Errorf("error running buildEKSCCCreateObject: %s", err) + } + if !reflect.DeepEqual(ekscc, expected) { + t.Errorf("EKS cluster config object was not built as expected") + } +} + +/* +* Test_recordAppliedSpec +- success: set current spec as applied spec. Return (updated cluster err) +- success: EksConfig and Applied Spec EksConfig are equal. Return (cluster nil) +*/ +func Test_recordAppliedSpec_Updated(t *testing.T) { + // We use a mock cluster that is still provisioning and in an Unknown state, because that is when the applied spec + // needs to be updated. + mockOperatorController = getMockEksOperatorController(t, "default") + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if cluster.Status.AppliedSpec.EKSConfig == nil { + t.Errorf("cluster Status.AppliedSpec should have been updated with EKSConfig") + } +} + +func Test_recordAppliedSpec_NoUpdate(t *testing.T) { + // A mock active cluster already has the EKSConfig set on the applied spec, so no update is required. + mockOperatorController = getMockEksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if !reflect.DeepEqual(cluster.Status.AppliedSpec, mockCluster.Status.AppliedSpec) { + t.Errorf("cluster Status.AppliedSpec should have no update and cluster returned successfully") + } +} + +func Test_getAccessToken(t *testing.T) { + t.Skip("not implemented: requires EKS controller") +} + +/* + - Test_generateSATokenWithPublicAPI + PRIVATE CLUSTER ONLY + - success in getting a service account token from the public API endpoint. Return (token mustTunnel=false nil) + - failure to get service account token. Return ("" mustTunnel=true err) + - unknown error. Return ("" mustTunnel=nil err) +*/ +func Test_generateSATokenWithPublicAPI(t *testing.T) { + mockOperatorController = getMockEksOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + input := mockCluster.DeepCopy() + hasPublicAccess := false + input.Status.EKSStatus.UpstreamSpec.PublicAccess = &hasPublicAccess + + token, requiresTunnel, err := mockOperatorController.generateSATokenWithPublicAPI(input) + + if err != nil { + t.Errorf("error running generateSATokenWithPublicAPI: %s", err) + } + if token == "" || to.Bool(requiresTunnel) != false { + t.Errorf("values (token, requiresTunnel=false, nil) should have been returned successfully") + } +} + +/** Test_getRestConfig + */ +func Test_getRestConfig(t *testing.T) { + t.Skip("not implemented: requires EKS controller") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/buildekscccreateobject.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/buildekscccreateobject.json new file mode 100644 index 0000000..80347ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/buildekscccreateobject.json @@ -0,0 +1,70 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "metadata": { + "creationTimestamp": null, + "name": "c-r64vb", + "ownerReferences": [ + { + "apiVersion": "management.cattle.io/v3", + "kind": "Cluster", + "name": "c-r64vb", + "uid": "ced870a2-50a7-4c12-ba8c-ef84e6616fbf" + } + ] + }, + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "eks-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [], + "tags": {}, + "userData": "", + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "generatedNodeRole": "", + "managedLaunchTemplateID": "", + "managedLaunchTemplateVersions": null, + "networkFieldsSource": "", + "phase": "", + "securityGroups": null, + "subnets": null, + "templateVersionsToDelete": null, + "virtualNetwork": "" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_active.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_active.yaml new file mode 100644 index 0000000..27254a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_active.yaml @@ -0,0 +1,132 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: eks-test + dockerRootDir: /var/lib/docker + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: eks-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: null + gpu: false + imageId: null + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole": null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: null + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: {} + userData: null + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + apiEndpoint: https://apiendpoint.us-east-2.eks.amazonaws.com + appliedSpec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: eks-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: null + gpu: false + imageId: null + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: null + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: {} + userData: null + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + conditions: + - lastUpdateTime: "2022-08-15T18:08:55-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-16T11:20:47-04:00" + status: "True" + type: Updated + driver: EKS + eksStatus: + upstreamSpec: + publicAccess: true + generatedNodeRole: "arn:aws:iam::role/test" + serviceAccountTokenSecret: cluster-serviceaccounttoken-secret diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_create.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_create.yaml new file mode 100644 index 0000000..36416fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_create.yaml @@ -0,0 +1,67 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: eks-test + dockerRootDir: /var/lib/docker + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: eks-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole: null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: [] + tags: {} + userData: "" + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: [] + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-15T17:55:31-04:00" + status: Unknown + type: Provisioned + driver: EKS + eksStatus: + upstreamSpec: + testField: "upstream spec is already set" + generatedNodeRole: "arn:aws:iam::role/test" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_default.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_default.yaml new file mode 100644 index 0000000..fe99c01 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_default.yaml @@ -0,0 +1,87 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +metadata: + annotations: + authz.management.cattle.io/creator-role-bindings: '{"created":["cluster-owner"],"required":["cluster-owner"]}' + field.cattle.io/creatorId: user-rgtsq + lifecycle.cattle.io/create.cluster-agent-controller-cleanup: "true" + lifecycle.cattle.io/create.cluster-provisioner-controller: "true" + lifecycle.cattle.io/create.cluster-scoped-gc: "true" + lifecycle.cattle.io/create.mgmt-cluster-rbac-remove: "true" + creationTimestamp: "2022-08-15T21:51:40Z" + finalizers: + - wrangler.cattle.io/mgmt-cluster-remove + - controller.cattle.io/cluster-agent-controller-cleanup + - controller.cattle.io/cluster-scoped-gc + - controller.cattle.io/cluster-provisioner-controller + - controller.cattle.io/mgmt-cluster-rbac-remove + generateName: c- + generation: 13 + labels: + cattle.io/creator: norman + name: c-r64vb + resourceVersion: "362231" + uid: ced870a2-50a7-4c12-ba8c-ef84e6616fbf +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: eks-test + dockerRootDir: /var/lib/docker + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: eks-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole: null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: [] + tags: {} + userData: "" + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: [] + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-15T17:51:47-04:00" + message: Waiting on eks crd to be initialized + status: Unknown + type: Provisioned + driver: EKS + generatedNodeRole: "arn:aws:iam::role/test" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_active.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_active.json new file mode 100644 index 0000000..343d8bc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_active.json @@ -0,0 +1,167 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "metadata": { + "creationTimestamp": "2022-08-15T21:51:51Z", + "finalizers": [ + "wrangler.cattle.io/eks-controller-remove" + ], + "generation": 9, + "managedFields": [ + { + "apiVersion": "eks.cattle.io/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:ownerReferences": { + ".": {}, + "k:{\"uid\":\"ced870a2-50a7-4c12-ba8c-ef84e6616fbf\"}": {} + } + }, + "f:spec": { + ".": {}, + "f:amazonCredentialSecret": {}, + "f:displayName": {}, + "f:imported": {}, + "f:kmsKey": {}, + "f:kubernetesVersion": {}, + "f:loggingTypes": {}, + "f:nodeGroups": {}, + "f:privateAccess": {}, + "f:publicAccess": {}, + "f:publicAccessSources": {}, + "f:ebsCSIDriver": {}, + "f:region": {}, + "f:secretsEncryption": {}, + "f:securityGroups": {}, + "f:serviceRole": {}, + "f:subnets": {}, + "f:tags": {} + } + }, + "manager": "___go_build_main_go", + "operation": "Update", + "time": "2022-08-15T21:51:51Z" + }, + { + "apiVersion": "eks.cattle.io/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:metadata": { + "f:finalizers": { + ".": {}, + "v:\"wrangler.cattle.io/eks-controller-remove\"": {} + } + }, + "f:status": { + ".": {}, + "f:failureMessage": {}, + "f:managedLaunchTemplateVersions": {}, + "f:networkFieldsSource": {}, + "f:securityGroups": {}, + "f:subnets": {}, + "f:virtualNetwork": {} + } + }, + "manager": "eks-operator", + "operation": "Update", + "time": "2022-08-15T21:57:22Z" + }, + { + "apiVersion": "eks.cattle.io/v1", + "fieldsType": "FieldsV1", + "fieldsV1": { + "f:status": { + "f:managedLaunchTemplateID": {}, + "f:managedLaunchTemplateVersions": { + "f:nodegroup": {} + }, + "f:phase": {}, + "f:templateVersionsToDelete": {} + } + }, + "manager": "eks-operator", + "operation": "Update", + "subresource": "status", + "time": "2022-08-16T14:59:52Z" + } + ], + "name": "c-r64vb", + "namespace": "cattle-global-data", + "ownerReferences": [ + { + "apiVersion": "management.cattle.io/v3", + "kind": "Cluster", + "name": "c-r64vb", + "uid": "ced870a2-50a7-4c12-ba8c-ef84e6616fbf" + } + ], + "resourceVersion": "398125", + "uid": "94341fca-b417-4834-a3e3-61bcbe18d01d" + }, + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "eks-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": null, + "gpu": false, + "imageId": null, + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "tags": {}, + "userData": null, + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [ + "0.0.0.0/0" + ], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "managedLaunchTemplateID": "lt-id", + "managedLaunchTemplateVersions": { + "nodegroup": "2" + }, + "networkFieldsSource": "generated", + "phase": "active", + "securityGroups": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "templateVersionsToDelete": null, + "virtualNetwork": "vpc-network" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_create.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_create.json new file mode 100644 index 0000000..f477f76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_create.json @@ -0,0 +1,61 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "eks-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [], + "tags": {}, + "userData": "", + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "managedLaunchTemplateID": "", + "managedLaunchTemplateVersions": null, + "networkFieldsSource": "generated", + "phase": "creating", + "securityGroups": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "templateVersionsToDelete": null, + "virtualNetwork": "vpc-network" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_default.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_default.json new file mode 100644 index 0000000..7abf756 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_default.json @@ -0,0 +1,46 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "eks-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [], + "tags": {}, + "userData": "", + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_update.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_update.json new file mode 100644 index 0000000..d1f139b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_ekscc_update.json @@ -0,0 +1,91 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "eks-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "tags": {}, + "userData": "", + "version": "1.22" + }, + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup2", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [], + "tags": {}, + "userData": "", + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [ + "0.0.0.0/0" + ], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "managedLaunchTemplateID": "lt-id", + "managedLaunchTemplateVersions": { + "nodegroup": "2" + }, + "networkFieldsSource": "generated", + "phase": "updating", + "securityGroups": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "templateVersionsToDelete": null, + "virtualNetwork": "vpc-network" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_update.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_update.yaml new file mode 100644 index 0000000..b304701 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/onclusterchange_update.yaml @@ -0,0 +1,90 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: eks-test + dockerRootDir: /var/lib/docker + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: eks-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole: null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: {} + userData: "" + version: "1.22" + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodegroupName: nodegroup2 + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: [] + tags: {} + userData: "" + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-15T18:08:55-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-16T11:32:29-04:00" + status: Unknown + type: Updated + driver: EKS + generatedNodeRole: "arn:aws:iam::role/test" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.json new file mode 100644 index 0000000..cac5bc0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.json @@ -0,0 +1,69 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "ekscc-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": null, + "gpu": false, + "imageId": null, + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "tags": {}, + "userData": null, + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [ + "0.0.0.0/0" + ], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "managedLaunchTemplateID": "lt-id", + "managedLaunchTemplateVersions": { + "nodegroup": "2" + }, + "networkFieldsSource": "generated", + "phase": "active", + "securityGroups": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "templateVersionsToDelete": null, + "virtualNetwork": "vpc-network" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.yaml new file mode 100644 index 0000000..fa74da5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig.yaml @@ -0,0 +1,281 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: ekscc-test + dockerRootDir: /var/lib/docker + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: ekscc-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole: null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: + TESTKEY: TESTVALUE + userData: "" + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + agentFeatures: + embedded-cluster-api: false + fleet: false + monitoringv1: false + multi-cluster-management: false + multi-cluster-management-agent: true + provisioningv2: false + rke2: false + agentImage: rancher/rancher-agent:v2.6-head + allocatable: + cpu: 3860m + memory: 6824936Ki + pods: "34" + apiEndpoint: https://apiendpoint.us-east-2.eks.amazonaws.com + appliedAgentEnvVars: + - name: CATTLE_SERVER_VERSION + value: dev + - name: CATTLE_INSTALL_UUID + value: 3573e14c-efce-425e-ae8a-7ddc80578c5e + - name: CATTLE_INGRESS_IP_DOMAIN + value: sslip.io + appliedEnableNetworkPolicy: false + appliedPodSecurityPolicyTemplateId: "" + appliedSpec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + eksConfig: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: ekscc-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: null + gpu: false + imageId: null + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: null + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: {} + userData: null + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + authImage: "" + caCert: testcacertvalue12345678910 + capabilities: + loadBalancerCapabilities: {} + capacity: + cpu: "4" + memory: 7934952Ki + pods: "34" + conditions: + - status: "True" + type: Pending + - lastUpdateTime: "2022-08-17T18:55:19-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-17T18:58:36-04:00" + status: "True" + type: Waiting + - lastUpdateTime: "2022-08-17T18:43:43-04:00" + status: "True" + type: BackingNamespaceCreated + - lastUpdateTime: "2022-08-17T18:43:44-04:00" + status: "True" + type: DefaultProjectCreated + - lastUpdateTime: "2022-08-17T18:43:44-04:00" + status: "True" + type: SystemProjectCreated + - lastUpdateTime: "2022-08-17T18:43:44-04:00" + status: "True" + type: InitialRolesPopulated + - lastUpdateTime: "2022-08-17T18:43:46-04:00" + status: "True" + type: CreatorMadeOwner + - lastUpdateTime: "2022-08-17T22:58:31Z" + status: "True" + type: Connected + - lastUpdateTime: "2022-08-17T18:43:47-04:00" + status: "True" + type: NoDiskPressure + - lastUpdateTime: "2022-08-17T18:43:47-04:00" + status: "True" + type: NoMemoryPressure + - lastUpdateTime: "2022-08-17T18:43:47-04:00" + status: "True" + type: SecretsMigrated + - lastUpdateTime: "2022-08-17T18:43:47-04:00" + status: "True" + type: ServiceAccountSecretsMigrated + - lastUpdateTime: "2022-08-17T18:57:47-04:00" + status: "True" + type: Updated + - lastUpdateTime: "2022-08-17T18:58:36-04:00" + status: "True" + type: Ready + - lastUpdateTime: "2022-08-17T18:57:52-04:00" + status: "True" + type: GlobalAdminsSynced + - lastUpdateTime: "2022-08-17T18:58:01-04:00" + status: "True" + type: SystemAccountCreated + - lastUpdateTime: "2022-08-17T18:58:03-04:00" + status: "True" + type: AgentDeployed + driver: EKS + eksStatus: + managedLaunchTemplateID: lt-id + managedLaunchTemplateVersions: + nodegroup: "2" + privateRequiresTunnel: null + securityGroups: null + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + upstreamSpec: + amazonCredentialSecret: cattle-global-data:cc-kxfmx + displayName: ekscc-test + imported: false + kmsKey: "" + kubernetesVersion: "1.22" + loggingTypes: [] + nodeGroups: + - arm: false + desiredSize: 2 + diskSize: 20 + ec2SshKey: null + gpu: false + imageId: null + instanceType: t3.medium + labels: {} + launchTemplate: null + maxSize: 2 + minSize: 2 + nodeRole: null + nodegroupName: nodegroup + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: null + subnets: + - subnet-01 + - subnet-02 + - subnet-03 + tags: {} + userData: null + version: "1.22" + privateAccess: false + publicAccess: true + publicAccessSources: + - 0.0.0.0/0 + ebsCSIDriver: false + region: us-east-2 + secretsEncryption: false + securityGroups: [] + serviceRole: "" + subnets: [] + tags: {} + virtualNetwork: vpc-network + generatedNodeRole: "arn:aws:iam::role/test" + limits: + cpu: "0" + memory: 340Mi + pods: "0" + linuxWorkerCount: 2 + nodeCount: 2 + provider: eks + requested: + cpu: 450m + memory: 140Mi + pods: "9" + serviceAccountTokenSecret: cluster-serviceaccounttoken-secret + version: + buildDate: "2022-07-06T18:06:23Z" + compiler: gc + gitCommit: b9628d6d3867ffd84c704af0befd31c7451cdc37 + gitTreeState: clean + gitVersion: v1.22.11-eks-18ef993 + goVersion: go1.16.15 + major: "1" + minor: 22+ + platform: linux/amd64 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig_updated.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig_updated.json new file mode 100644 index 0000000..0b456db --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/eks/test/updateeksclusterconfig_updated.json @@ -0,0 +1,71 @@ +{ + "apiVersion": "eks.cattle.io/v1", + "kind": "EKSClusterConfig", + "spec": { + "amazonCredentialSecret": "cattle-global-data:cc-kxfmx", + "displayName": "ekscc-test", + "imported": false, + "kmsKey": "", + "kubernetesVersion": "1.22", + "loggingTypes": [], + "nodeGroups": [ + { + "arm": false, + "desiredSize": 2, + "diskSize": 20, + "ec2SshKey": "", + "gpu": false, + "imageId": "", + "instanceType": "t3.medium", + "labels": {}, + "launchTemplate": null, + "maxSize": 2, + "minSize": 2, + "nodeRole": null, + "nodegroupName": "nodegroup", + "requestSpotInstances": false, + "resourceTags": {}, + "spotInstanceTypes": [], + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "tags": { + "TESTKEY": "TESTVALUE" + }, + "userData": "", + "version": "1.22" + } + ], + "privateAccess": false, + "publicAccess": true, + "publicAccessSources": [ + "0.0.0.0/0" + ], + "ebsCSIDriver": false, + "region": "us-east-2", + "secretsEncryption": false, + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {} + }, + "status": { + "failureMessage": "", + "managedLaunchTemplateID": "lt-id", + "managedLaunchTemplateVersions": { + "nodegroup": "2" + }, + "networkFieldsSource": "generated", + "phase": "updating", + "securityGroups": null, + "subnets": [ + "subnet-01", + "subnet-02", + "subnet-03" + ], + "templateVersionsToDelete": null, + "virtualNetwork": "vpc-network" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup.go new file mode 100644 index 0000000..2c439ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup.go @@ -0,0 +1,704 @@ +package etcdbackup + +import ( + "bytes" + "compress/gzip" + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "net/http" + "sort" + "strings" + "time" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/drivers/rke" + "github.com/rancher/rancher/pkg/kontainer-engine/service" + "github.com/rancher/rancher/pkg/rkedialerfactory" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" + rkecluster "github.com/rancher/rke/cluster" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/wrangler/v3/pkg/ticker" + log "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + clusterBackupCheckInterval = 5 * time.Minute + compressedExtension = "zip" + s3Endpoint = "s3.amazonaws.com" +) + +type Controller struct { + ctx context.Context + clusterClient v3.ClusterInterface + clusterLister v3.ClusterLister + backupClient v3.EtcdBackupInterface + backupLister v3.EtcdBackupLister + backupDriver *service.EngineService + KontainerDriverLister v3.KontainerDriverLister + secretLister v1.SecretLister +} + +func Register(ctx context.Context, management *config.ManagementContext) { + c := &Controller{ + ctx: ctx, + clusterClient: management.Management.Clusters(""), + clusterLister: management.Management.Clusters("").Controller().Lister(), + backupClient: management.Management.EtcdBackups(""), + backupLister: management.Management.EtcdBackups("").Controller().Lister(), + backupDriver: service.NewEngineService(clusterprovisioner.NewPersistentStore(management.Core.Namespaces(""), management.Core)), + secretLister: management.Core.Secrets("").Controller().Lister(), + KontainerDriverLister: management.Management.KontainerDrivers("").Controller().Lister(), + } + + local := &rkedialerfactory.RKEDialerFactory{ + Factory: management.Dialer, + Ctx: ctx, + } + docker := &rkedialerfactory.RKEDialerFactory{ + Factory: management.Dialer, + Docker: true, + Ctx: ctx, + } + driver := service.Drivers[service.RancherKubernetesEngineDriverName] + rkeDriver := driver.(*rke.Driver) + rkeDriver.DockerDialer = docker.Build + rkeDriver.LocalDialer = local.Build + rkeDriver.WrapTransportFactory = docker.WrapTransport + + c.backupClient.AddLifecycle(ctx, "etcdbackup-controller", c) + go c.clusterBackupSync(ctx, clusterBackupCheckInterval) +} + +func (c *Controller) Create(b *v3.EtcdBackup) (runtime.Object, error) { + if rketypes.BackupConditionCompleted.IsFalse(b) || rketypes.BackupConditionCompleted.IsTrue(b) { + return b, nil + } + + cluster, err := c.clusterClient.Get(b.Spec.ClusterID, metav1.GetOptions{}) + if err != nil { + return b, err + } + + if !isBackupSet(cluster.Spec.RancherKubernetesEngineConfig) { + return b, fmt.Errorf("[etcd-backup] cluster doesn't have a backup config") + } + + rketypes.BackupConditionCreated.Unknown(b) + b, err = c.backupClient.Update(b) + if err != nil { + return b, err + } + + log.Infof("[etcd-backup] cluster [%s] backup added to queue: %s", cluster.Name, b.Name) + + backups, err := c.getBackupsList(cluster) + if err != nil { + return b, err + } + + if anyBackupsRunning(cluster, backups) { + return b, nil + } + + if next := nextBackup(backups); next == nil || next.Name == b.Name { + b, err = c.createBackupForCluster(b, cluster) + if err != nil { + return b, fmt.Errorf("[etcd-backup] failed to perform etcd backup: %v", err) + } + } + + return b, nil +} + +func (c *Controller) Remove(b *v3.EtcdBackup) (runtime.Object, error) { + if !rketypes.BackupConditionCreated.IsTrue(b) { + return b, nil + } + log.Debugf("[etcd-backup] deleting backup %s ", b.Name) + if err := c.etcdRemoveSnapshotWithBackoff(b); err != nil { + log.Errorf("[etcd-backup] unable to delete backup backup [%s]: %v", b.Name, err) + } + return b, nil +} + +func (c *Controller) Updated(b *v3.EtcdBackup) (runtime.Object, error) { + return b, nil +} + +func (c *Controller) clusterBackupSync(ctx context.Context, interval time.Duration) error { + for range ticker.Context(ctx, interval) { + clusters, err := c.clusterLister.List("", labels.NewSelector()) + if err != nil { + log.Error(fmt.Errorf("[etcd-backup] error while listing clusters: %v", err)) + return err + } + for _, cluster := range clusters { + log.Debugf("[etcd-backup] checking backups for cluster [%s]", cluster.Name) + if err = c.runWaitingBackups(cluster); err != nil { + log.Error(fmt.Errorf("[etcd-backup] error running waiting cluster backups for cluster [%s]: %v", cluster.Name, err)) + } + if err = c.createRecurringBackup(cluster); err != nil { + log.Error(fmt.Errorf("[etcd-backup] error while syncing cluster backups for for cluster [%s]: %v", cluster.Name, err)) + } + } + } + return nil +} + +type FilterFunc = func(backup *v3.EtcdBackup) bool + +// filterBackups will test each backup within backups to determine if the filter validates (i.e. returns true) for the +// given backup. If any filter is false, the backup is considered invalid. +func filterBackups(backups []*v3.EtcdBackup, filter ...FilterFunc) []*v3.EtcdBackup { + ret := make([]*v3.EtcdBackup, 0) +OUTER: + for _, backup := range backups { + for _, f := range filter { + if !f(backup) { + continue OUTER + } + } + ret = append(ret, backup) + } + return ret +} + +func (c *Controller) runWaitingBackups(cluster *v3.Cluster) error { + if cluster == nil || cluster.DeletionTimestamp != nil { + return nil + } + // check if the cluster is eligible for backup. + if !shouldBackup(cluster) { + return nil + } + + backups, err := c.getBackupsList(cluster) + if err != nil { + return err + } + + if anyBackupsRunning(cluster, backups) { + return nil + } + + var next *v3.EtcdBackup + if next = nextBackup(backups); next != nil { + log.Infof("[etcd-backup] cluster [%s] backup starting from queue: %s", cluster.Name, next.Name) + if _, err := c.createBackupForCluster(next, cluster); err != nil { + return err + } + } + + return nil +} + +func (c *Controller) createRecurringBackup(cluster *v3.Cluster) error { + if cluster == nil || cluster.DeletionTimestamp != nil { + return nil + } + // check if the cluster is eligible for backup. + if !shouldBackup(cluster) { + return nil + } + + backups, err := c.getBackupsList(cluster) + if err != nil { + return err + } + + recurringBackups := filterBackups(backups, IsBackupRecurring) + chronologicalSort(recurringBackups) + + // cluster has no recurring backups, we need to create initial backup + if len(recurringBackups) == 0 { + log.Debugf("[etcd-backup] cluster [%s] has no backups, creating first backup", cluster.Name) + newBackup, err := c.createNewBackup(cluster) + if err != nil { + return fmt.Errorf("error while creating backup for cluster [%s]: %v", cluster.Name, err) + } + log.Debugf("[etcd-backup] cluster [%s] new backup is created: %s", cluster.Name, newBackup.Name) + return nil + } + + if anyBackupsRunning(cluster, recurringBackups) || anyBackupsQueued(recurringBackups) { + return nil + } + + newestBackup := recurringBackups[0] + for _, clusterBackup := range recurringBackups[1:] { + if getBackupCompletedTime(clusterBackup).After(getBackupCompletedTime(newestBackup)) { + newestBackup = clusterBackup + } + } + + // this cluster has backups, lets see if the last one is old enough + // a new backup is due if this is true + intervalHours := cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.IntervalHours + backupIntervalHours := time.Duration(intervalHours) * time.Hour + + if time.Since(getBackupCompletedTime(newestBackup)) > backupIntervalHours { + newBackup, err := c.createNewBackup(cluster) + if err != nil { + return fmt.Errorf("error while create new backup for cluster [%s]: %v", cluster.Name, err) + } + log.Debugf("[etcd-backup] new backup created: %s", newBackup.Name) + } + + return nil +} + +func IsBackupRecurring(backup *v3.EtcdBackup) bool { + return !backup.Spec.Manual +} + +func (c *Controller) createBackupForCluster(b *v3.EtcdBackup, cluster *v3.Cluster) (*v3.EtcdBackup, error) { + var err error + if b.DeletionTimestamp != nil || rketypes.BackupConditionCreated.IsUnknown(b) { + b.Spec.Filename = generateBackupFilename(b.Name, cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig) + b.Spec.BackupConfig = *cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig + rketypes.BackupConditionCreated.True(b) + // we set ConditionCompleted to Unknown to avoid incorrect "active" state + rketypes.BackupConditionCompleted.Unknown(b) + b, err = c.backupClient.Update(b) + if err != nil { + return b, err + } + } + b, saveErr := c.etcdSave(b) + b, err = c.backupClient.Update(b) + if err != nil { + return b, err + } + + if saveErr != nil { + if !b.Spec.Manual { + _ = c.rotateFailedBackups(cluster) + } + return b, saveErr + } + + if !b.Spec.Manual { + _ = c.rotateSuccessfulBackups(cluster) + } + return b, nil +} + +func anyBackupsRunning(cluster *v3.Cluster, backups []*v3.EtcdBackup) bool { + clusterTimeout := getTimeout(cluster) + for _, backup := range backups { + if !rketypes.BackupConditionCreated.IsTrue(backup) { + continue + } + // cluster backup is younger than its timeout and completion is unknown + // therefore, it's currently running + if time.Since(getBackupCreatedTime(backup)) < clusterTimeout && rketypes.BackupConditionCompleted.IsUnknown(backup) { + log.Debugf("[etcd-backup] cluster [%s] is currently creating a backup, skipping", cluster.Name) + return true + } + } + return false +} + +func anyBackupsQueued(backups []*v3.EtcdBackup) bool { + for _, backup := range backups { + if rketypes.BackupConditionCreated.IsTrue(backup) && + !rketypes.BackupConditionCompleted.IsTrue(backup) && + !rketypes.BackupConditionCompleted.IsFalse(backup) { + return true + } + } + return false +} + +func getTimeout(cluster *v3.Cluster) time.Duration { + if rkeCfg := cluster.Spec.RancherKubernetesEngineConfig; rkeCfg != nil && rkeCfg.Services.Etcd.BackupConfig.Timeout > 0 { + return time.Duration(rkeCfg.Services.Etcd.BackupConfig.Timeout) * time.Second + } + return time.Duration(rkecluster.DefaultEtcdBackupConfigTimeout) * time.Second +} + +func nextBackup(backups []*v3.EtcdBackup) *v3.EtcdBackup { + var next *v3.EtcdBackup + + // check for backups in queue + for _, backup := range backups { + if !rketypes.BackupConditionCreated.IsUnknown(backup) { + continue + } + if next == nil || backup.CreationTimestamp.Time.Before(next.CreationTimestamp.Time) { + next = backup + } + } + return next +} + +func (c *Controller) createNewBackup(cluster *v3.Cluster) (*v3.EtcdBackup, error) { + newBackup, err := NewBackupObject(cluster, false) + if err != nil { + return nil, err + } + rketypes.BackupConditionCreated.CreateUnknownIfNotExists(newBackup) + return c.backupClient.Create(newBackup) +} + +// etcdSave will utilize RKE to take a snapshot on each of the nodes. +func (c *Controller) etcdSave(b *v3.EtcdBackup) (*v3.EtcdBackup, error) { + kontainerDriver, err := c.KontainerDriverLister.Get("", service.RancherKubernetesEngineDriverName) + if err != nil { + return b, err + } + + snapshotName := clusterprovisioner.GetBackupFilename(b) + bObj, err := rketypes.BackupConditionCompleted.Do(b, func() (runtime.Object, error) { + cluster, err := c.clusterClient.Get(b.Spec.ClusterID, metav1.GetOptions{}) + if err != nil { + return b, err + } + cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig = b.Spec.BackupConfig.DeepCopy() + spec, err := assemblers.AssembleS3Credential(cluster.GetSecret("S3CredentialSecret"), assemblers.ClusterType, cluster.Name, cluster.Spec, c.secretLister) + if err != nil { + return b, err + } + // no need to retry, RKE will retry for us + if err = c.backupDriver.ETCDSave(c.ctx, cluster.Name, kontainerDriver, spec, snapshotName); err != nil { + log.Warnf("%v", err) + } + return b, err + }) + b = bObj.(*v3.EtcdBackup) + if err != nil { + rketypes.BackupConditionCompleted.False(b) + rketypes.BackupConditionCompleted.ReasonAndMessageFromError(b, err) + return b, err + } + return b, nil +} + +func (c *Controller) etcdRemoveSnapshotWithBackoff(b *v3.EtcdBackup) error { + backoff := getBackoff() + + kontainerDriver, err := c.KontainerDriverLister.Get("", service.RancherKubernetesEngineDriverName) + if err != nil { + return err + } + cluster, err := c.clusterClient.Get(b.Spec.ClusterID, metav1.GetOptions{}) + if err != nil { + return err + } + cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig = b.Spec.BackupConfig.DeepCopy() + spec, err := assemblers.AssembleS3Credential(cluster.GetSecret("S3CredentialSecret"), assemblers.ClusterType, cluster.Name, cluster.Spec, c.secretLister) + if err != nil { + return err + } + snapshotName := clusterprovisioner.GetBackupFilename(b) + return wait.ExponentialBackoff(backoff, func() (bool, error) { + if inErr := c.backupDriver.ETCDRemoveSnapshot(c.ctx, cluster.Name, kontainerDriver, spec, snapshotName); inErr != nil { + log.Warnf("%v", inErr) + return false, nil + } + return true, nil + }) +} + +func (c *Controller) rotateSuccessfulBackups(cluster *v3.Cluster) error { + log.Infof("[etcd-backup] Rotating successful recurring backups") + return c.rotateBackups(cluster, IsBackupCompleted) +} + +func IsBackupCompleted(backup *v3.EtcdBackup) bool { + return rketypes.BackupConditionCompleted.IsTrue(backup) +} + +func (c *Controller) rotateFailedBackups(cluster *v3.Cluster) error { + log.Infof("[etcd-backup] Rotating failed recurring backups") + return c.rotateBackups(cluster, IsBackupFailed) +} + +func IsBackupFailed(backup *v3.EtcdBackup) bool { + return rketypes.BackupConditionCompleted.IsFalse(backup) +} + +func (c *Controller) rotateBackups(cluster *v3.Cluster, filter FilterFunc) error { + retention := cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.Retention + backups, err := c.getBackupsList(cluster) + if err != nil { + return err + } + backups = filterBackups(backups, IsBackupRecurring, filter) + if len(backups) <= retention { + return nil + } + chronologicalSort(backups) + + if err = c.removeBackups(backups[retention:]); err != nil { + return err + } + return nil +} + +func (c *Controller) removeBackups(backups []*v3.EtcdBackup) error { + for _, backup := range backups { + if err := c.backupClient.DeleteNamespaced(backup.Namespace, backup.Name, &metav1.DeleteOptions{}); err != nil { + return err + } + } + return nil +} + +func NewBackupObject(cluster *v3.Cluster, manual bool) (*v3.EtcdBackup, error) { + controller := true + typeFlag := "r" // recurring is the default + providerFlag := "l" // local is the default + + if manual { + typeFlag = "m" // manual backup + } + if cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + providerFlag = "s" // s3 backup + } + prefix := fmt.Sprintf("%s-%s%s-", cluster.Name, typeFlag, providerFlag) + + compressedCluster, err := CompressCluster(cluster) + if err != nil { + return nil, err + } + + return &v3.EtcdBackup{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Name, + GenerateName: prefix, + OwnerReferences: []metav1.OwnerReference{ + { + Name: cluster.Name, + UID: cluster.UID, + APIVersion: cluster.APIVersion, + Kind: cluster.Kind, + Controller: &controller, + }, + }, + }, + Spec: rketypes.EtcdBackupSpec{ + ClusterID: cluster.Name, + Manual: manual, + }, + Status: rketypes.EtcdBackupStatus{ + KubernetesVersion: cluster.Spec.RancherKubernetesEngineConfig.Version, + ClusterObject: compressedCluster, + }, + }, nil +} + +func CompressCluster(cluster *v3.Cluster) (string, error) { + jsonCluster, err := json.Marshal(cluster) + if err != nil { + return "", err + } + + var gzCluster bytes.Buffer + gz := gzip.NewWriter(&gzCluster) + defer gz.Close() + + _, err = gz.Write([]byte(jsonCluster)) + if err != nil { + return "", err + } + + if err := gz.Close(); err != nil { + return "", err + } + + return base64.StdEncoding.EncodeToString(gzCluster.Bytes()), nil +} + +func DecompressCluster(cluster string) (*v3.Cluster, error) { + clusterGzip, err := base64.StdEncoding.DecodeString(cluster) + if err != nil { + return nil, fmt.Errorf("error base64.DecodeString: %v", err) + } + + buffer := bytes.NewBuffer(clusterGzip) + + var gz io.Reader + gz, err = gzip.NewReader(buffer) + if err != nil { + return nil, err + } + + var clusterJSON bytes.Buffer + _, err = io.Copy(&clusterJSON, gz) + if err != nil { + return nil, err + } + + c := v3.Cluster{} + err = json.Unmarshal(clusterJSON.Bytes(), &c) + if err != nil { + return nil, err + } + + return &c, nil +} + +func generateBackupFilename(snapshotName string, backupConfig *rketypes.BackupConfig) string { + // no backup config + if backupConfig == nil { + return "" + } + filename := fmt.Sprintf("%s_%s.%s", snapshotName, time.Now().Format(time.RFC3339), compressedExtension) + if backupConfig.SafeTimestamp { + filename = strings.ReplaceAll(filename, ":", "-") + } + // s3 backup + if backupConfig != nil && + backupConfig.S3BackupConfig != nil { + if len(backupConfig.S3BackupConfig.Folder) != 0 { + return fmt.Sprintf("https://%s/%s/%s/%s", backupConfig.S3BackupConfig.Endpoint, backupConfig.S3BackupConfig.BucketName, backupConfig.S3BackupConfig.Folder, filename) + } + return fmt.Sprintf("https://%s/%s/%s", backupConfig.S3BackupConfig.Endpoint, backupConfig.S3BackupConfig.BucketName, filename) + } + // local backup + return filename + +} + +func GetS3Client(sbc *rketypes.S3BackupConfig, timeout int, dialer dialer.Dialer) (*minio.Client, error) { + if sbc == nil { + return nil, fmt.Errorf("Can't find S3 backup target configuration") + } + var creds *credentials.Credentials + var tr http.RoundTripper = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } + endpoint := sbc.Endpoint + // no access credentials, we assume IAM roles + if sbc.AccessKey == "" || + sbc.SecretKey == "" { + creds = credentials.NewIAM("") + if sbc.Endpoint == "" { + endpoint = s3Endpoint + } + } else { + accessKey := sbc.AccessKey + secretKey := sbc.SecretKey + creds = credentials.NewStatic(accessKey, secretKey, "", credentials.SignatureDefault) + } + + bucketLookup := getBucketLookupType(endpoint) + opt := minio.Options{ + Creds: creds, + Region: sbc.Region, + Secure: true, + BucketLookup: bucketLookup, + Transport: tr, + } + if sbc.CustomCA != "" { + opt.Transport = getCustomCATransport(tr, sbc.CustomCA) + } + s3Client, err := minio.New(endpoint, &opt) + if err != nil { + return nil, err + } + return s3Client, nil +} + +func chronologicalSort(backups []*v3.EtcdBackup) { + sort.Slice(backups, func(i, j int) bool { + return getBackupCreatedTime(backups[i]).After(getBackupCreatedTime(backups[j])) + }) +} + +func (c *Controller) getBackupsList(cluster *v3.Cluster) ([]*v3.EtcdBackup, error) { + backups, err := c.backupLister.List(cluster.Name, labels.NewSelector()) + return backups, err +} + +func getBucketLookupType(endpoint string) minio.BucketLookupType { + if endpoint == "" { + return minio.BucketLookupAuto + } + if strings.Contains(endpoint, "aliyun") { + return minio.BucketLookupDNS + } + return minio.BucketLookupAuto +} + +func getBackupCompletedTime(o runtime.Object) time.Time { + t, _ := time.Parse(time.RFC3339, rketypes.BackupConditionCompleted.GetLastUpdated(o)) + return t +} + +func getBackupCreatedTime(o runtime.Object) time.Time { + t, _ := time.Parse(time.RFC3339, rketypes.BackupConditionCreated.GetLastUpdated(o)) + return t +} + +func shouldBackup(cluster *v3.Cluster) bool { + // not an rke cluster, we do nothing + if cluster.Spec.RancherKubernetesEngineConfig == nil { + log.Debugf("[etcd-backup] [%s] is not an rke cluster, skipping..", cluster.Name) + return false + } + if !isBackupSet(cluster.Spec.RancherKubernetesEngineConfig) { + // no backend backup config + log.Debugf("[etcd-backup] no backup config for cluster [%s]", cluster.Name) + return false + } + // we only work with ready clusters + if !v32.ClusterConditionReady.IsTrue(cluster) { + return false + } + + if !isRecurringBackupEnabled(cluster.Spec.RancherKubernetesEngineConfig) { + log.Debugf("[etcd-backup] recurring backup is disabled cluster [%s]", cluster.Name) + return false + } + return true +} + +func getBackoff() wait.Backoff { + return wait.Backoff{ + Duration: 1000 * time.Millisecond, + Factor: 2, + Jitter: 0, + Steps: 5, + } +} + +func isBackupSet(rkeConfig *rketypes.RancherKubernetesEngineConfig) bool { + return rkeConfig != nil && // rke cluster + rkeConfig.Services.Etcd.BackupConfig != nil // backupConfig is set +} + +func isRecurringBackupEnabled(rkeConfig *rketypes.RancherKubernetesEngineConfig) bool { + return isBackupSet(rkeConfig) && rkeConfig.Services.Etcd.BackupConfig.Enabled != nil && *rkeConfig.Services.Etcd.BackupConfig.Enabled +} + +func getCustomCATransport(tr http.RoundTripper, ca string) http.RoundTripper { + certPool := x509.NewCertPool() + certPool.AppendCertsFromPEM([]byte(ca)) + tr.(*http.Transport).TLSClientConfig = &tls.Config{ + RootCAs: certPool, + } + return tr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup_test.go new file mode 100644 index 0000000..e267f40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/etcdbackup/etcdbackup_test.go @@ -0,0 +1,80 @@ +package etcdbackup + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" +) + +func Test_filterBackups(t *testing.T) { + recurring := &v3.EtcdBackup{} + manual := &v3.EtcdBackup{ + Spec: rketypes.EtcdBackupSpec{ + Manual: true, + }, + } + failed := &v3.EtcdBackup{} + rketypes.BackupConditionCompleted.False(failed) + completed := &v3.EtcdBackup{} + rketypes.BackupConditionCompleted.True(completed) + + tests := []struct { + name string + input []*v3.EtcdBackup + expected []*v3.EtcdBackup + filters []FilterFunc + }{ + { + name: "recurring", + input: []*v3.EtcdBackup{ + manual, recurring, + }, + expected: []*v3.EtcdBackup{ + recurring, + }, + filters: []FilterFunc{ + IsBackupRecurring, + }, + }, { + name: "completed", + input: []*v3.EtcdBackup{ + completed, failed, + }, + expected: []*v3.EtcdBackup{ + completed, + }, + filters: []FilterFunc{ + IsBackupCompleted, + }, + }, { + name: "failed", + input: []*v3.EtcdBackup{ + completed, failed, + }, + expected: []*v3.EtcdBackup{ + failed, + }, + filters: []FilterFunc{ + IsBackupFailed, + }, + }, { + name: "recurring and completed", + input: []*v3.EtcdBackup{ + recurring, manual, completed, failed, + }, + expected: []*v3.EtcdBackup{ + completed, + }, + filters: []FilterFunc{ + IsBackupRecurring, IsBackupCompleted, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, filterBackups(tt.input, tt.filters...)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/feature/feature_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/feature/feature_handler.go new file mode 100644 index 0000000..7866f6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/feature/feature_handler.go @@ -0,0 +1,170 @@ +package feature + +import ( + "context" + "fmt" + "reflect" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/features" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" +) + +type handler struct { + featuresClient managementv3.FeatureClient + tokensLister managementv3.TokenCache + tokenEnqueue func(string, time.Duration) + nodeDriverController managementv3.NodeDriverController +} + +func Register(ctx context.Context, wContext *wrangler.Context) { + h := handler{ + featuresClient: wContext.Mgmt.Feature(), + tokensLister: wContext.Mgmt.Token().Cache(), + tokenEnqueue: wContext.Mgmt.Token().EnqueueAfter, + nodeDriverController: wContext.Mgmt.NodeDriver(), + } + wContext.Mgmt.Feature().OnChange(ctx, "feature-handler", h.sync) +} + +func (h *handler) sync(_ string, obj *v3.Feature) (*v3.Feature, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + obj, err := h.setLockedValue(obj) + if err != nil { + return obj, err + } + + if obj.Name == features.TokenHashing.Name() { + return obj, h.refreshTokens() + } + + if obj.Name == features.Harvester.Name() { + return obj, h.toggleHarvesterNodeDriver(obj.Name) + } + + if obj.Name == features.HarvesterBaremetalContainerWorkload.Name() { + return obj, h.syncHarvesterFeature(obj) + } + return obj, nil +} + +// syncHarvesterFeature ensures that Harvester feature is enabled +// if baremetal management feature is enabled and annotates feature with experimental annotation +func (h *handler) syncHarvesterFeature(obj *v3.Feature) error { + + objCopy := obj.DeepCopy() + + if objCopy.Annotations == nil { + objCopy.Annotations = make(map[string]string) + } + + objCopy.Annotations[v3.ExperimentalFeatureKey] = v3.ExperimentalFeatureValue + + if !reflect.DeepEqual(obj, objCopy) { + _, err := h.featuresClient.Update(objCopy) + return err + } + + // if feature is enabled, ensure harvester feature is also enabled + if features.GetFeatureByName(obj.Name).Enabled() { + harvesterFeature, err := h.featuresClient.Get(features.Harvester.Name(), metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error fetching feature %s: %w", features.Harvester.Name(), err) + } + harvesterFeatureCopy := harvesterFeature.DeepCopy() + if harvesterFeatureCopy.Spec.Value == nil || !*harvesterFeatureCopy.Spec.Value { + harvesterFeatureCopy.Spec.Value = &[]bool{true}[0] + } + if !reflect.DeepEqual(harvesterFeature, harvesterFeatureCopy) { + if _, err := h.featuresClient.Update(harvesterFeatureCopy); err != nil { + return fmt.Errorf("error updating Harvester feature %s: %w", obj.Name, err) + } + } + } + + return nil +} + +func (h *handler) toggleHarvesterNodeDriver(harvester string) error { + if val := features.GetFeatureByName(harvester).Enabled(); val { + m, err := h.nodeDriverController.Cache().Get(harvester) + if err != nil { + return err + } + m.Spec.Active = val + _, err = h.nodeDriverController.Update(m) + return err + } + return nil +} + +func (h *handler) refreshTokens() error { + tokenList, err := h.tokensLister.List(labels.Everything()) + if err != nil { + return err + } + for _, token := range tokenList { + if token.Annotations[tokens.TokenHashed] == "true" { + continue + } + h.tokenEnqueue(token.Name, 10*time.Second) + } + return nil +} + +// setLockedValue evaluates whether a value should be written to the lockedValue +// field on status and records the value if so. +func (h *handler) setLockedValue(obj *v3.Feature) (*v3.Feature, error) { + lockedValueFromSpec := EvaluateLockedValueFromSpec(obj) + + if lockedValueFromSpec == nil && obj.Status.LockedValue == nil { + return obj, nil + } + // Should update if locked value from spec does not match locked value on status. This includes if one is nil and + // the other is not. + update := (lockedValueFromSpec == nil && obj.Status.LockedValue != nil) || + (lockedValueFromSpec != nil && obj.Status.LockedValue == nil) || *lockedValueFromSpec != *obj.Status.LockedValue + + if !update { + return obj, nil + } + + featureCopy := obj.DeepCopy() + featureCopy.Status.LockedValue = lockedValueFromSpec + return h.featuresClient.Update(featureCopy) +} + +// EvaluateLockedValueFromSpec evaluates whether updates to a feature's effective value +// should be prevented. If so LockedValue returns the value that should +// be pinned to a feature. If nil is returned, the features value can be +// changed and those changes should toggle the associated behavior. +// Return value meanings: +// * nil - not currently locked +// * false - currently locked and false value +// * true - currently locked and true value +func EvaluateLockedValueFromSpec(obj *v3.Feature) *bool { + if obj.Status.LockedValue != nil { + return obj.Status.LockedValue + } + switch obj.Name { + case features.TokenHashing.Name(): + if obj.Spec.Value == nil { + return nil + } + if !(*obj.Spec.Value) { + return nil + } + value := true + return &value + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler.go new file mode 100644 index 0000000..9a3947b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler.go @@ -0,0 +1,493 @@ +package gke + +import ( + "context" + "encoding/base64" + stderrors "errors" + "fmt" + "net" + "net/http" + "net/url" + "reflect" + "strings" + "time" + + "github.com/rancher/gke-operator/controller" + gkev1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + "github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + "github.com/rancher/rancher/pkg/dialer" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + typesDialer "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rancher/pkg/wrangler" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + "golang.org/x/oauth2" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" +) + +const ( + gkeAPIGroup = "gke.cattle.io" + gkeV1 = "gke.cattle.io/v1" + gkeOperatorTemplate = "system-library-rancher-gke-operator" + gkeOperator = "rancher-gke-operator" + gkeShortName = "GKE" + enqueueTime = time.Second * 5 +) + +type gkeOperatorController struct { + clusteroperator.OperatorController + secretClient corecontrollers.SecretClient +} + +func Register(ctx context.Context, wContext *wrangler.Context, mgmtCtx *config.ManagementContext) { + gkeClusterConfigResource := schema.GroupVersionResource{ + Group: gkeAPIGroup, + Version: "v1", + Resource: "gkeclusterconfigs", + } + + gkeCCDynamicClient := mgmtCtx.DynamicClient.Resource(gkeClusterConfigResource) + e := &gkeOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: wContext.Mgmt.Cluster().EnqueueAfter, + Secrets: mgmtCtx.Core.Secrets(""), + SecretsCache: wContext.Core.Secret().Cache(), + TemplateCache: wContext.Mgmt.CatalogTemplate().Cache(), + ProjectCache: wContext.Mgmt.Project().Cache(), + AppLister: mgmtCtx.Project.Apps("").Controller().Lister(), + AppClient: mgmtCtx.Project.Apps(""), + NsClient: mgmtCtx.Core.Namespaces(""), + ClusterClient: wContext.Mgmt.Cluster(), + CatalogManager: mgmtCtx.CatalogManager, + SystemAccountManager: systemaccount.NewManager(mgmtCtx), + DynamicClient: gkeCCDynamicClient, + ClientDialer: mgmtCtx.Dialer, + Discovery: wContext.K8s.Discovery(), + }, + secretClient: wContext.Core.Secret(), + } + + wContext.Mgmt.Cluster().OnChange(ctx, "gke-operator-controller", e.onClusterChange) +} + +func (e *gkeOperatorController) onClusterChange(key string, cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil || cluster.Spec.GKEConfig == nil { + return cluster, nil + } + + // set driver name + if cluster.Status.Driver == "" { + cluster = cluster.DeepCopy() + cluster.Status.Driver = apimgmtv3.ClusterDriverGKE + var err error + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + + cluster, err := e.CheckCrdReady(cluster, "gke") + if err != nil { + return cluster, err + } + + // get gke Cluster Config, if it does not exist, create it + gkeClusterConfigDynamic, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Get(context.TODO(), cluster.Name, v1.GetOptions{}) + if err != nil { + if !errors.IsNotFound(err) { + return cluster, err + } + + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "Waiting for API to be available") + if err != nil { + return cluster, err + } + + gkeClusterConfigDynamic, err = buildGKECCCreateObject(cluster) + if err != nil { + return cluster, err + } + + gkeClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Create(context.TODO(), gkeClusterConfigDynamic, v1.CreateOptions{}) + if err != nil { + return cluster, err + } + + } + + gkeClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&cluster.Spec.GKEConfig) + if err != nil { + return cluster, err + } + + // check for changes between gke spec on cluster and the gke spec on the gkeClusterConfig object + if !reflect.DeepEqual(gkeClusterConfigMap, gkeClusterConfigDynamic.Object["spec"]) { + logrus.Infof("change detected for cluster [%s], updating GKEClusterConfig", cluster.Name) + return e.updateGKEClusterConfig(cluster, gkeClusterConfigDynamic, gkeClusterConfigMap) + } + + // get gke Cluster Config's phase + status, _ := gkeClusterConfigDynamic.Object["status"].(map[string]interface{}) + phase, _ := status["phase"] + failureMessage, _ := status["failureMessage"].(string) + if strings.Contains(failureMessage, "403") { + failureMessage = fmt.Sprintf("cannot access gke, check cloud credential: %s", failureMessage) + } + + switch phase { + case "creating": + if cluster.Status.GKEStatus.UpstreamSpec == nil { + cluster, err = e.setInitialUpstreamSpec(cluster) + if err != nil { + return cluster, err + } + return cluster, nil + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster GKE [%s] to finish creating", cluster.Name) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster GKE [%s] create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + case "active": + if cluster.Spec.GKEConfig.Imported { + if cluster.Status.GKEStatus.UpstreamSpec == nil { + // non imported clusters will have already had upstream spec set + return e.setInitialUpstreamSpec(cluster) + } + + if apimgmtv3.ClusterConditionPending.IsUnknown(cluster) { + cluster = cluster.DeepCopy() + apimgmtv3.ClusterConditionPending.True(cluster) + cluster, err = e.ClusterClient.Update(cluster) + if err != nil { + return cluster, err + } + } + } + + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + if cluster.Status.APIEndpoint == "" { + return e.RecordCAAndAPIEndpoint(cluster) + } + + if cluster.Status.GKEStatus.PrivateRequiresTunnel == nil && + cluster.Status.GKEStatus.UpstreamSpec.PrivateClusterConfig != nil && + cluster.Status.GKEStatus.UpstreamSpec.PrivateClusterConfig.EnablePrivateEndpoint { + // In this case, the API endpoint is private and it has not been determined if Rancher must tunnel to communicate with it. + // Check to see if we can still use the control plane endpoint even though + // the cluster has private-only access + serviceToken, mustTunnel, err := e.generateSATokenWithPublicAPI(cluster) + if err != nil { + return cluster, err + } + if mustTunnel != nil { + cluster = cluster.DeepCopy() + cluster.Status.GKEStatus.PrivateRequiresTunnel = mustTunnel + if serviceToken != "" { + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, serviceToken, cluster) + if err != nil { + return cluster, err + } + if secret == nil { + logrus.Debugf("Empty service account token secret returned for cluster [%s]", cluster.Name) + return cluster, fmt.Errorf("failed to create or update service account token secret, secret can't be empty") + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + } + return e.ClusterClient.Update(cluster) + } + } + + if cluster.Status.ServiceAccountTokenSecret == "" { + cluster, err = e.generateAndSetServiceAccount(cluster) + if err != nil { + var statusErr error + if err == dialer.ErrAgentDisconnected { + // In this case, the API endpoint is private and rancher is waiting for the import cluster command to be run. + cluster, statusErr = e.SetUnknown(cluster, apimgmtv3.ClusterConditionWaiting, "waiting for cluster agent to be deployed") + if statusErr == nil { + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + } + return cluster, statusErr + } + cluster, statusErr = e.SetFalse(cluster, apimgmtv3.ClusterConditionWaiting, + fmt.Sprintf("failed to communicate with cluster: %v", err)) + if statusErr != nil { + return cluster, statusErr + } + return cluster, err + } + } + + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + return e.SetTrue(cluster, apimgmtv3.ClusterConditionUpdated, "") + case "updating": + cluster, err = e.SetTrue(cluster, apimgmtv3.ClusterConditionProvisioned, "") + if err != nil { + return cluster, err + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + logrus.Infof("waiting for cluster GKE [%s] to update", cluster.Name) + + // If the HealthSyncer runs while upgrading a zonal cluster, the control plane may not be reachable. + // This adds additional context to the error message to help explain that this is normal. + readyMsg := apimgmtv3.ClusterConditionReady.GetMessage(cluster) + helpMsg := ": control plane may be unavailable while it is being upgraded" + if apimgmtv3.ClusterConditionReady.IsFalse(cluster) && strings.Contains(readyMsg, "connect: connection refused") && !strings.Contains(readyMsg, helpMsg) { + msg := apimgmtv3.ClusterConditionReady.GetMessage(cluster) + helpMsg + // return here; ClusterConditionUpdated is most likely already set, and + // if not will be set on the next loop + return e.SetFalse(cluster, apimgmtv3.ClusterConditionReady, msg) + } + + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + } + logrus.Infof("waiting for cluster GKE [%s] update failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionUpdated, failureMessage) + default: + if cluster.Spec.GKEConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + if failureMessage == "" { + if cluster.Spec.GKEConfig.Imported { + cluster, err = e.SetUnknown(cluster, apimgmtv3.ClusterConditionPending, "") + if err != nil { + return cluster, err + } + logrus.Infof("waiting for cluster import [%s] to start", cluster.Name) + } else { + logrus.Infof("waiting for cluster create [%s] to start", cluster.Name) + } + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionProvisioned, "") + } + logrus.Infof("waiting for cluster GKE [%s] pre-create failure to be resolved", cluster.Name) + return e.SetFalse(cluster, apimgmtv3.ClusterConditionProvisioned, failureMessage) + } +} + +// setInitialUpstreamSpec builds a view of the upstream cluster and adds it to the status of the cluster resource +func (e *gkeOperatorController) setInitialUpstreamSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + cluster = cluster.DeepCopy() + upstreamSpec, err := clusterupstreamrefresher.BuildGKEUpstreamSpec(e.SecretsCache, e.secretClient, cluster) + if err != nil { + return cluster, err + } + cluster.Status.GKEStatus.UpstreamSpec = upstreamSpec + return e.ClusterClient.Update(cluster) +} + +// updateGKEClusterConfig updates the GKEClusterConfig object's spec with the cluster's GKEConfig if they are not equal. +func (e *gkeOperatorController) updateGKEClusterConfig(cluster *mgmtv3.Cluster, gkeClusterConfigDynamic *unstructured.Unstructured, spec map[string]interface{}) (*mgmtv3.Cluster, error) { + list, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).List(context.TODO(), v1.ListOptions{}) + if err != nil { + return cluster, err + } + selector := fields.OneTermEqualSelector("metadata.name", cluster.Name) + w, err := e.DynamicClient.Namespace(namespace.GlobalNamespace).Watch(context.TODO(), v1.ListOptions{ResourceVersion: list.GetResourceVersion(), FieldSelector: selector.String()}) + if err != nil { + return cluster, err + } + gkeClusterConfigDynamic.Object["spec"] = spec + gkeClusterConfigDynamic, err = e.DynamicClient.Namespace(namespace.GlobalNamespace).Update(context.TODO(), gkeClusterConfigDynamic, v1.UpdateOptions{}) + if err != nil { + return cluster, err + } + + // GKE cluster and node pool statuses are not always immediately updated. This cause the GKEConfig to + // stay in "active" for a few seconds, causing the cluster to go back to "active". + timeout := time.NewTimer(10 * time.Second) + for { + select { + case event := <-w.ResultChan(): + gkeClusterConfigDynamic = event.Object.(*unstructured.Unstructured) + status, _ := gkeClusterConfigDynamic.Object["status"].(map[string]interface{}) + if status["phase"] == "active" { + continue + } + + // this enqueue is necessary to ensure that the controller is reentered with the updating phase + e.ClusterEnqueueAfter(cluster.Name, enqueueTime) + return e.SetUnknown(cluster, apimgmtv3.ClusterConditionUpdated, "") + case <-timeout.C: + cluster, err = e.recordAppliedSpec(cluster) + if err != nil { + return cluster, err + } + return cluster, nil + } + } +} + +// generateAndSetServiceAccount uses the API endpoint and CA cert to generate a service account token. The token is then copied to the cluster status. +func (e *gkeOperatorController) generateAndSetServiceAccount(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + clusterDialer, err := e.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + restConfig, err := e.getRestConfig(cluster, clusterDialer) + if err != nil { + return cluster, err + } + + saToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + return cluster, fmt.Errorf("error generating service account token: %w", err) + } + + cluster = cluster.DeepCopy() + secret, err := secretmigrator.NewMigrator(e.SecretsCache, e.Secrets).CreateOrUpdateServiceAccountTokenSecret(cluster.Status.ServiceAccountTokenSecret, saToken, cluster) + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return e.ClusterClient.Update(cluster) +} + +// buildGKECCCreateObject returns an object that can be used with the kubernetes dynamic client to +// create an GKEClusterConfig that matches the spec contained in the cluster's GKEConfig. +func buildGKECCCreateObject(cluster *mgmtv3.Cluster) (*unstructured.Unstructured, error) { + gkeClusterConfig := gkev1.GKEClusterConfig{ + TypeMeta: v1.TypeMeta{ + Kind: "GKEClusterConfig", + APIVersion: gkeV1, + }, + ObjectMeta: v1.ObjectMeta{ + Name: cluster.Name, + OwnerReferences: []v1.OwnerReference{ + { + Kind: cluster.Kind, + APIVersion: rbac.RancherManagementAPIVersion, + Name: cluster.Name, + UID: cluster.UID, + }, + }, + }, + Spec: *cluster.Spec.GKEConfig, + } + + // convert GKE cluster config into unstructured object so it can be used with dynamic client + gkeClusterConfigMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&gkeClusterConfig) + if err != nil { + return nil, err + } + + return &unstructured.Unstructured{ + Object: gkeClusterConfigMap, + }, nil +} + +// recordAppliedSpec sets the cluster's current spec as its appliedSpec +func (e *gkeOperatorController) recordAppliedSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if reflect.DeepEqual(cluster.Status.AppliedSpec.GKEConfig, cluster.Spec.GKEConfig) { + return cluster, nil + } + + cluster = cluster.DeepCopy() + cluster.Status.AppliedSpec.GKEConfig = cluster.Spec.GKEConfig + return e.ClusterClient.Update(cluster) +} + +// generateSATokenWithPublicAPI tries to get a service account token from the cluster using the public API endpoint. +// This function is called if the cluster has only privateEndpoint enabled and not publicly available. +// If Rancher is able to communicate with the cluster through its API endpoint even though it is private, then this function will retrieve +// a service account token and the *bool returned will refer to a false value (doesn't have to tunnel). +// +// If the Rancher server cannot connect to the cluster's API endpoint, then one of the two errors below will happen. +// In this case, we know that Rancher must use the cluster agent tunnel for communication. This function will return an empty service account token, +// and the *bool return value will refer to a true value (must tunnel). +// +// If an error different from the two below occur, then the *bool return value will be nil, indicating that Rancher was not able to determine if +// tunneling is required to communicate with the cluster. +func (e *gkeOperatorController) generateSATokenWithPublicAPI(cluster *mgmtv3.Cluster) (string, *bool, error) { + restConfig, err := e.getRestConfig(cluster, (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext) + if err != nil { + return "", nil, err + } + requiresTunnel := new(bool) + serviceToken, err := clusteroperator.GenerateSAToken(restConfig) + if err != nil { + *requiresTunnel = true + if strings.Contains(err.Error(), "dial tcp") { + return "", requiresTunnel, nil + } + + // In the existence of a proxy, it may be the case that the following error occurs, + // in which case rancher should use the tunnel connection to communicate with the cluster. + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + + // Not able to determine if tunneling is required. + requiresTunnel = nil + } + + return serviceToken, requiresTunnel, err +} + +func (e *gkeOperatorController) getRestConfig(cluster *mgmtv3.Cluster, dialer typesDialer.Dialer) (*rest.Config, error) { + ctx := context.Background() + ts, err := controller.GetTokenSource(ctx, e.secretClient, cluster.Spec.GKEConfig) + if err != nil { + return nil, err + } + + decodedCA, err := base64.StdEncoding.DecodeString(cluster.Status.CACert) + if err != nil { + return nil, err + } + + return &rest.Config{ + Host: cluster.Status.APIEndpoint, + TLSClientConfig: rest.TLSClientConfig{ + CAData: decodedCA, + }, + WrapTransport: func(rt http.RoundTripper) http.RoundTripper { + return &oauth2.Transport{ + Source: ts, + Base: rt, + } + }, + Dial: dialer, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_interface_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_interface_test.go new file mode 100644 index 0000000..b8af9a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_interface_test.go @@ -0,0 +1,612 @@ +package gke + +import ( + "context" + "net" + + openapi2 "github.com/google/gnostic-models/openapiv2" + "github.com/rancher/rancher/pkg/types/config/dialer" + meta1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/version" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/openapi" + "k8s.io/client-go/rest" +) + +const ( + MockDefaultgkeClusterConfigFilename = "test/onclusterchange_gkecc_default.json" + MockCreategkeClusterConfigFilename = "test/onclusterchange_gkecc_create.json" + MockActivegkeClusterConfigFilename = "test/onclusterchange_gkecc_active.json" + MockUpdategkeClusterConfigFilename = "test/onclusterchange_gkecc_update.json" + MockgkeClusterConfigUpdatedFilename = "test/updategkeclusterconfig_updated.json" +) + +// mock interfaces + +// mock dynamic client (to return a mock gkeClusterConfig) + +// Test 1 - cluster in default/unknown state. Get will return an gkeClusterConfig with an unknown provisioning phase. +// The rest of the method signatures have to be implemented to mock the interface. There will be one mock of this +// interface for each test. + +type MockNamespaceableResourceInterfaceDefault struct{} + +func (m MockNamespaceableResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceDefault{} +} + +func (m MockNamespaceableResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceDefault struct{} + +func (m MockResourceInterfaceDefault) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockDefaultgkeClusterConfigFilename) +} + +func (m MockResourceInterfaceDefault) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceDefault) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 2 - cluster in creating state + +type MockNamespaceableResourceInterfaceCreate struct{} + +func (m MockNamespaceableResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceCreate{} +} + +func (m MockNamespaceableResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceCreate struct{} + +func (m MockResourceInterfaceCreate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockCreategkeClusterConfigFilename) +} + +func (m MockResourceInterfaceCreate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceCreate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 3 - cluster in active state + +type MockNamespaceableResourceInterfaceActive struct{} + +func (m MockNamespaceableResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceActive{} +} + +func (m MockNamespaceableResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceActive struct{} + +func (m MockResourceInterfaceActive) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockActivegkeClusterConfigFilename) +} + +func (m MockResourceInterfaceActive) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockResourceInterfaceActive) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test 4 - cluster in update node pool state + +type MockNamespaceableResourceInterfaceUpdate struct{} + +func (m MockNamespaceableResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceUpdate{} +} + +func (m MockNamespaceableResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceUpdate struct{} + +func (m MockResourceInterfaceUpdate) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceUpdate) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockUpdategkeClusterConfigFilename) +} + +func (m MockResourceInterfaceUpdate) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return nil, nil +} + +func (m MockResourceInterfaceUpdate) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// Test UpdateGKEClusterConfig + +type MockNamespaceableResourceInterfaceGkeCC struct{} + +func (m MockNamespaceableResourceInterfaceGkeCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Namespace(s string) dynamic.ResourceInterface { + return MockResourceInterfaceGkeCC{} +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m MockNamespaceableResourceInterfaceGkeCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +type MockResourceInterfaceGkeCC struct{} + +func (m MockResourceInterfaceGkeCC) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options meta1.ApplyOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) Create(ctx context.Context, obj *unstructured.Unstructured, options meta1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) Update(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockgkeClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceGkeCC) UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options meta1.UpdateOptions) (*unstructured.Unstructured, error) { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) Delete(ctx context.Context, name string, options meta1.DeleteOptions, subresources ...string) error { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) DeleteCollection(ctx context.Context, options meta1.DeleteOptions, listOptions meta1.ListOptions) error { + panic("implement me") +} + +func (m MockResourceInterfaceGkeCC) Get(ctx context.Context, name string, options meta1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) { + return getMockGkeClusterConfig(MockgkeClusterConfigUpdatedFilename) +} + +func (m MockResourceInterfaceGkeCC) List(ctx context.Context, opts meta1.ListOptions) (*unstructured.UnstructuredList, error) { + return &unstructured.UnstructuredList{ + Object: map[string]interface{}{ + "apiVersion": "gke.cattle.io/v1", + "kind": "gkeClusterConfigList", + "metadata": map[string]interface{}{"resourceVersion": "142650"}, + }, + Items: nil, + }, nil +} + +// mock interface that returns a watch event (for updateGKEClusterConfig test) + +type MockInterface struct{} + +func (m MockInterface) Stop() {} + +func (m MockInterface) ResultChan() <-chan watch.Event { + return make(chan watch.Event) +} + +func (m MockResourceInterfaceGkeCC) Watch(ctx context.Context, opts meta1.ListOptions) (watch.Interface, error) { + return MockInterface{}, nil +} + +func (m MockResourceInterfaceGkeCC) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options meta1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error) { + panic("implement me") +} + +// mock cluster dialer + +type MockFactory struct{} + +func (m MockFactory) ClusterDialer(clusterName string, retryOnError bool) (dialer.Dialer, error) { + // pass a dialer func to the client + dialer := func(ctx context.Context, network, address string) (net.Conn, error) { + return nil, nil + } + return dialer, nil +} + +func (m MockFactory) DockerDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +func (m MockFactory) NodeDialer(clusterName, machineName string) (dialer.Dialer, error) { + panic("implement me") +} + +type Dialer func(ctx context.Context, network, address string) (net.Conn, error) + +// mock discovery + +type MockDiscovery struct{} + +func (m MockDiscovery) RESTClient() rest.Interface { + panic("implement me") +} + +func (m MockDiscovery) ServerGroups() (*meta1.APIGroupList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*meta1.APIResourceList, error) { + + return &meta1.APIResourceList{ + TypeMeta: meta1.TypeMeta{}, + GroupVersion: "", + APIResources: []meta1.APIResource{ + {Name: "gkeClusterConfig"}, + {Name: "status"}}, + }, nil +} + +func (m MockDiscovery) ServerGroupsAndResources() ([]*meta1.APIGroup, []*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerPreferredNamespacedResources() ([]*meta1.APIResourceList, error) { + panic("implement me") +} + +func (m MockDiscovery) ServerVersion() (*version.Info, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPISchema() (*openapi2.Document, error) { + panic("implement me") +} + +func (m MockDiscovery) OpenAPIV3() openapi.Client { + panic("implement me") +} + +func (m MockDiscovery) WithLegacy() discovery.DiscoveryInterface { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_test.go new file mode 100644 index 0000000..e5746fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_mockc_test.go @@ -0,0 +1,222 @@ +//nolint:all // this file was originally generated by github.com/kelveny/mockcompose +package gke + +import ( + "embed" + stderrors "errors" + "fmt" + "net" + "net/url" + "testing" + "time" + + "github.com/ghodss/yaml" + "github.com/golang/mock/gomock" + v1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusteroperator" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + secretv1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/json" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +//go:embed test/* +var testFs embed.FS + +type mockGkeOperatorController struct { + gkeOperatorController + mock.Mock +} + +func getMockGkeOperatorController(t *testing.T, clusterState string) mockGkeOperatorController { + t.Helper() + ctrl := gomock.NewController(t) + clusterMock := fake.NewMockNonNamespacedClientInterface[*apisv3.Cluster, *apisv3.ClusterList](ctrl) + clusterMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(c *apisv3.Cluster) (*apisv3.Cluster, error) { + return c, nil + }, + ).AnyTimes() + + var dynamicClient dynamic.NamespaceableResourceInterface + + switch clusterState { + case "default": + dynamicClient = MockNamespaceableResourceInterfaceDefault{} + case "create": + dynamicClient = MockNamespaceableResourceInterfaceCreate{} + case "active": + dynamicClient = MockNamespaceableResourceInterfaceActive{} + case "update": + dynamicClient = MockNamespaceableResourceInterfaceUpdate{} + case "gkecc": + dynamicClient = MockNamespaceableResourceInterfaceGkeCC{} + default: + dynamicClient = nil + } + + return mockGkeOperatorController{ + gkeOperatorController: gkeOperatorController{ + OperatorController: clusteroperator.OperatorController{ + ClusterEnqueueAfter: func(name string, duration time.Duration) {}, + SecretsCache: nil, + Secrets: nil, + TemplateCache: nil, + ProjectCache: nil, + AppLister: nil, + AppClient: nil, + NsClient: nil, + ClusterClient: clusterMock, + CatalogManager: nil, + SystemAccountManager: nil, + DynamicClient: dynamicClient, + ClientDialer: MockFactory{}, + Discovery: MockDiscovery{}, + }, + }, + Mock: mock.Mock{}, + } +} + +// test setInitialUpstreamSpec + +func (m *mockGkeOperatorController) setInitialUpstreamSpec(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + logrus.Infof("setting initial upstreamSpec on cluster [%s]", cluster.Name) + + // mock + upstreamSpec := &v1.GKEClusterConfigSpec{} + + cluster = cluster.DeepCopy() + cluster.Status.GKEStatus.UpstreamSpec = upstreamSpec + return m.ClusterClient.Update(cluster) +} + +// test generateAndSetServiceAccount with mock sibling func (getRestConfig) + +func (m *mockGkeOperatorController) generateAndSetServiceAccount(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + restConfig, err := m.getRestConfig(cluster) + if err != nil { + return cluster, fmt.Errorf("error getting kube config: %v", err) + } + + clusterDialer, err := m.ClientDialer.ClusterDialer(cluster.Name, true) + if err != nil { + return cluster, err + } + + restConfig.Dial = clusterDialer + cluster = cluster.DeepCopy() + + // mock + secret := secretv1.Secret{} + secret.Name = "cluster-serviceaccounttoken-sl7wm" + + if err != nil { + return nil, err + } + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + return m.ClusterClient.Update(cluster) +} + +// test generateSATokenWithPublicAPI with mock sibling func (getRestConfig) + +func (m *mockGkeOperatorController) generateSATokenWithPublicAPI(cluster *mgmtv3.Cluster) (string, *bool, error) { + // mock + m.Mock.On("getRestConfig", cluster).Return(&rest.Config{}, nil) + + restConfig, err := m.getRestConfig(cluster) + if err != nil { + return "", nil, err + } + requiresTunnel := new(bool) + restConfig.Dial = (&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext + + // mock serviceToken + serviceToken, err := "testtoken12345", nil + + if err != nil { + *requiresTunnel = true + var dnsError *net.DNSError + if stderrors.As(err, &dnsError) && !dnsError.IsTemporary { + return "", requiresTunnel, nil + } + var urlError *url.Error + if stderrors.As(err, &urlError) && urlError.Timeout() { + return "", requiresTunnel, nil + } + requiresTunnel = nil + } + return serviceToken, requiresTunnel, err +} + +func (m *mockGkeOperatorController) getRestConfig(cluster *mgmtv3.Cluster) (*rest.Config, error) { + + _mc_ret := m.Called(cluster) + + var _r0 *rest.Config + + if _rfn, ok := _mc_ret.Get(0).(func(*mgmtv3.Cluster) *rest.Config); ok { + _r0 = _rfn(cluster) + } else { + if _mc_ret.Get(0) != nil { + _r0 = _mc_ret.Get(0).(*rest.Config) + } + } + + var _r1 error + + if _rfn, ok := _mc_ret.Get(1).(func(*mgmtv3.Cluster) error); ok { + _r1 = _rfn(cluster) + } else { + _r1 = _mc_ret.Error(1) + } + + return _r0, _r1 + +} + +// utility + +func getMockV3Cluster(filename string) (mgmtv3.Cluster, error) { + var mockCluster mgmtv3.Cluster + + // Read the embedded file + cluster, err := testFs.ReadFile(filename) + if err != nil { + return mockCluster, err + } + // Unmarshal cluster yaml into a management v3 cluster object + err = yaml.Unmarshal(cluster, &mockCluster) + if err != nil { + return mockCluster, err + } + + return mockCluster, nil +} + +func getMockGkeClusterConfig(filename string) (*unstructured.Unstructured, error) { + var gkeClusterConfig *unstructured.Unstructured + + // Read the embedded file + bytes, err := testFs.ReadFile(filename) + if err != nil { + return gkeClusterConfig, err + } + // Unmarshal json into an unstructured cluster config object + err = json.Unmarshal(bytes, &gkeClusterConfig) + if err != nil { + return gkeClusterConfig, err + } + + return gkeClusterConfig, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_test.go new file mode 100644 index 0000000..6adcc0c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/gke_cluster_handler_test.go @@ -0,0 +1,292 @@ +package gke + +import ( + "reflect" + "testing" + + "github.com/rancher/rancher/pkg/capr" + + "github.com/Azure/go-autorest/autorest/to" + v1 "github.com/rancher/gke-operator/pkg/apis/gke.cattle.io/v1" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" +) + +const ( + MockDefaultClusterFilename = "test/onclusterchange_default.yaml" + MockCreateClusterFilename = "test/onclusterchange_create.yaml" + MockActiveClusterFilename = "test/onclusterchange_active.yaml" + MockUpdateClusterFilename = "test/onclusterchange_update.yaml" + MockGkeClusterConfigFilename = "test/updategkeclusterconfig.json" + MockGkeClusterConfigClusterFilename = "test/updategkeclusterconfig.yaml" + MockBuildGkeCCCreateObjectFilename = "test/buildgkecccreateobject.json" +) + +var mockOperatorController mockGkeOperatorController // Operator controller with mock interfaces & sibling funcs + +/* +* Test_onClusterChange +- cluster == nil. Return (nil nil) +- cluster.DeletionTimestamp or cluster.gkeConfig == nil, return (nil nil) +- default phase +- create phase +- active phase +- update node pool phase +*/ +func Test_onClusterChange_ClusterIsNil(t *testing.T) { + cluster, _ := mockOperatorController.onClusterChange("", nil) + if cluster != nil { + t.Errorf("cluster should have returned nil") + } +} + +func Test_onClusterChange_GKEConfigIsNil(t *testing.T) { + mockCluster := &v3.Cluster{ + Spec: v3.ClusterSpec{ + GKEConfig: nil, + }, + } + + cluster, _ := mockOperatorController.onClusterChange("", mockCluster) + if !reflect.DeepEqual(cluster, mockCluster) { + t.Errorf("cluster should have returned with no update") + } +} + +func Test_onClusterChange_Default(t *testing.T) { + + // setup + // create an instance of the operator controller with mock data to simulate the onChangeCluster function reacting + // to a real cluster! + mockOperatorController = getMockGkeOperatorController(t, "default") + + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + // run test + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // validate results + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Create(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsUnknown(cluster) { + t.Errorf("provisioned status should be Unknown and cluster returned successfully") + } +} + +func Test_onClusterChange_Active(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsTrue(cluster) { + t.Errorf("provisioned and updated status should be True and cluster returned successfully") + } +} + +func Test_onClusterChange_UpdateNodePool(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "update") + mockCluster, err := getMockV3Cluster(MockUpdateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.onClusterChange("", &mockCluster) + + // check that cluster is updating node pool + if err != nil { + t.Errorf("error running onClusterChange: %s", err) + } + if !capr.Provisioned.IsTrue(cluster) || !capr.Updated.IsUnknown(cluster) { + t.Errorf("provisioned status should be True, updated status should be Unknown and cluster returned successfully") + } +} + +/* +* Test_setInitialUpstreamSpec +- success: buildUpstreamClusterState returns a valid upstream spec +*/ +func Test_setInitialUpstreamSpec(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "create") + mockCluster, err := getMockV3Cluster(MockCreateClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.setInitialUpstreamSpec(&mockCluster) + + if err != nil { + t.Errorf("error running setInitialUpstreamSpec: %s", err) + } + if cluster.Status.GKEStatus.UpstreamSpec == nil { + t.Errorf("upstreamSpec should have been set and cluster returned successfully") + } +} + +/* +* Test_updateGKEClusterConfig + - success: gke cluster tags are removed. gke cluster is not immediately updated. Cluster sits in active for a few + seconds, return (cluster nil) +*/ +func Test_updateGKEClusterConfig(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "gkecc") + mockCluster, err := getMockV3Cluster(MockGkeClusterConfigClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + mockGkeClusterConfig, err := getMockGkeClusterConfig(MockGkeClusterConfigFilename) + + // test remove tags from the cluster + _, err = mockOperatorController.updateGKEClusterConfig(&mockCluster, mockGkeClusterConfig, nil) + + if err != nil { + t.Errorf("error running updateGKEClusterConfig: %s", err) + } +} + +/* +* Test_generateAndSetServiceAccount +- success: service account token generated, cluster updated! Return updated cluster.Status +- error generating service account token. Return (cluster, err) +*/ +func Test_generateAndSetServiceAccount(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.generateAndSetServiceAccount(&mockCluster) + + // check that serviceAccountToken name and token are set + if err != nil { + t.Errorf("error running generateAndSetServiceAccount: %s", err) + } + if cluster.Status.ServiceAccountTokenSecret == "" { + t.Errorf("service account token secret should have been set on Status and cluster returned successfully") + } +} + +/* +* Test_buildGKECCCreateObject +- success: gkeClusterConfig object created, return (gkeClusterConfig nil) +*/ +func Test_buildGKECCCreateObject(t *testing.T) { + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + expected, err := getMockGkeClusterConfig(MockBuildGkeCCCreateObjectFilename) + + gkecc, err := buildGKECCCreateObject(&mockCluster) + + if err != nil { + t.Errorf("error running buildGKECCCreateObject: %s", err) + } + if !reflect.DeepEqual(gkecc, expected) { + t.Errorf("GKE cluster config object was not built as expected") + } +} + +/* +* Test_recordAppliedSpec +- success: set current spec as applied spec. Return (updated cluster err) +- success: gkeConfig and Applied Spec gkeConfig are equal. Return (cluster nil) +*/ +func Test_recordAppliedSpec_Updated(t *testing.T) { + // We use a mock cluster that is still provisioning and in an Unknown state, because that is when the applied spec + // needs to be updated. + mockOperatorController = getMockGkeOperatorController(t, "default") + mockCluster, err := getMockV3Cluster(MockDefaultClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if cluster.Status.AppliedSpec.GKEConfig == nil { + t.Errorf("cluster Status.AppliedSpec should have been updated with GKEConfig") + } +} + +func Test_recordAppliedSpec_NoUpdate(t *testing.T) { + // A mock active cluster already has the gkeConfig set on the applied spec, so no update is required. + mockOperatorController = getMockGkeOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + + cluster, err := mockOperatorController.recordAppliedSpec(&mockCluster) + + if err != nil { + t.Errorf("error running recordAppliedSpec: %s", err) + } + if !reflect.DeepEqual(cluster.Status.AppliedSpec, mockCluster.Status.AppliedSpec) { + t.Errorf("cluster Status.AppliedSpec should have no update and cluster returned successfully") + } +} + +/* + - Test_generateSATokenWithPublicAPI + PRIVATE CLUSTER ONLY + - success in getting a service account token from the public API endpoint. Return (token mustTunnel=false nil) + - failure to get service account token. Return ("" mustTunnel=true err) + - unknown error. Return ("" mustTunnel=nil err) +*/ +func Test_generateSATokenWithPublicAPI(t *testing.T) { + mockOperatorController = getMockGkeOperatorController(t, "active") + mockCluster, err := getMockV3Cluster(MockActiveClusterFilename) + if err != nil { + t.Errorf("error getting mock v3 cluster: %s", err) + } + input := mockCluster.DeepCopy() + input.Status.GKEStatus.PrivateRequiresTunnel = nil + input.Status.GKEStatus.UpstreamSpec.PrivateClusterConfig = &v1.GKEPrivateClusterConfig{ + EnablePrivateEndpoint: true, + } + + token, requiresTunnel, err := mockOperatorController.generateSATokenWithPublicAPI(input) + + if err != nil { + t.Errorf("error running generateSATokenWithPublicAPI: %s", err) + } + if token == "" || to.Bool(requiresTunnel) != false { + t.Errorf("values (token, requiresTunnel=false, nil) should have been returned successfully") + } +} + +/** Test_getRestConfig + */ +func Test_getRestConfig(t *testing.T) { + t.Skip("not implemented: requires GKE controller") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/buildgkecccreateobject.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/buildgkecccreateobject.json new file mode 100644 index 0000000..ea94092 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/buildgkecccreateobject.json @@ -0,0 +1,76 @@ +{ + "kind": "GKEClusterConfig", + "apiVersion": "gke.cattle.io/v1", + "metadata": { + "name": "c-5tzkk", + "creationTimestamp": null, + "ownerReferences": [ + { + "apiVersion": "management.cattle.io/v3", + "kind": "Cluster", + "name": "c-5tzkk", + "uid": "53cd1838-e5ea-4d12-bb5c-9ecab9d8631b" + } + ] + }, + "spec": { + "region": "", + "zone": "us-central1-c", + "imported": false, + "description": "", + "labels": {}, + "enableKubernetesAlpha": false, + "clusterAddons": { + "httpLoadBalancing": true, + "horizontalPodAutoscaling": true + }, + "clusterIpv4Cidr": "", + "projectID": "test-project-id", + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "clusterName": "gke-test", + "kubernetesVersion": "1.22.11-gke.400", + "loggingService": "logging.googleapis.com/kubernetes", + "monitoringService": "monitoring.googleapis.com/kubernetes", + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400", + "management": { + "autoRepair": true, + "autoUpgrade": true + } + } + ], + "network": "default", + "subnetwork": "default", + "networkPolicyEnabled": false, + "privateClusterConfig": {}, + "ipAllocationPolicy": { + "useIpAliases": true + }, + "masterAuthorizedNetworks": {}, + "locations": [], + "maintenanceWindow": "", + "autopilotConfig": {} + }, + "status": { + "phase": "" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_active.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_active.yaml new file mode 100644 index 0000000..7b4d030 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_active.yaml @@ -0,0 +1,167 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: gke-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: 10.124.0.0/14 + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + clusterIpv4CidrBlock: 10.124.0.0/14 + clusterSecondaryRangeName: gke-gke-test-pods-fedcba98 + servicesIpv4CidrBlock: 10.0.0.0/20 + servicesSecondaryRangeName: gke-gke-test-services-fedcba98 + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: + - us-central1-c + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: + enabled: false + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + apiEndpoint: https://apiendpoint + appliedSpec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: 10.124.0.0/14 + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + clusterIpv4CidrBlock: 10.124.0.0/14 + clusterSecondaryRangeName: gke-gke-test-pods-fedcba98 + servicesIpv4CidrBlock: 10.0.0.0/20 + servicesSecondaryRangeName: gke-gke-test-services-fedcba98 + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: + - us-central1-c + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: {} + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + conditions: + - lastUpdateTime: "2022-08-22T15:25:19-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-22T16:56:11-04:00" + status: "True" + type: Updated + driver: GKE + gkeStatus: + upstreamSpec: + privateClusterConfig: {} + serviceAccountTokenSecret: cluster-serviceaccounttoken-secret diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_create.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_create.yaml new file mode 100644 index 0000000..80f6d7c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_create.yaml @@ -0,0 +1,75 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: gke-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: "" + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: [] + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: {} + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - status: Unknown + type: Provisioned + driver: GKE + gkeStatus: + upstreamSpec: + testField: "upstream spec is already set" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_default.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_default.yaml new file mode 100644 index 0000000..ccfeeaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_default.yaml @@ -0,0 +1,94 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +metadata: + annotations: + authz.management.cattle.io/creator-role-bindings: '{"created":["cluster-owner"],"required":["cluster-owner"]}' + field.cattle.io/creatorId: user-rgtsq + lifecycle.cattle.io/create.cluster-agent-controller-cleanup: "true" + lifecycle.cattle.io/create.cluster-provisioner-controller: "true" + lifecycle.cattle.io/create.cluster-scoped-gc: "true" + lifecycle.cattle.io/create.mgmt-cluster-rbac-remove: "true" + creationTimestamp: "2022-08-22T19:19:00Z" + finalizers: + - wrangler.cattle.io/mgmt-cluster-remove + - controller.cattle.io/cluster-agent-controller-cleanup + - controller.cattle.io/cluster-scoped-gc + - controller.cattle.io/cluster-provisioner-controller + - controller.cattle.io/mgmt-cluster-rbac-remove + generateName: c- + generation: 12 + labels: + cattle.io/creator: norman + name: c-5tzkk + resourceVersion: "688695" + uid: 53cd1838-e5ea-4d12-bb5c-9ecab9d8631b +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: gke-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: "" + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: [] + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: {} + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - status: Unknown + type: Provisioned + driver: GKE diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_active.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_active.json new file mode 100644 index 0000000..07353ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_active.json @@ -0,0 +1,80 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "10.124.0.0/14", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "clusterIpv4CidrBlock": "10.124.0.0/14", + "clusterSecondaryRangeName": "gke-gke-test-pods-fedcba98", + "servicesIpv4CidrBlock": "10.0.0.0/20", + "servicesSecondaryRangeName": "gke-gke-test-services-fedcba98", + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": {}, + "locations": [ + "us-central1-c" + ], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2" + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + }, + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2" + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup2", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": {} + }, + "status": { + "failureMessage": "", + "phase": "active" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_create.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_create.json new file mode 100644 index 0000000..246de45 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_create.json @@ -0,0 +1,65 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": {}, + "locations": [], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": {} + }, + "status": { + "failureMessage": "", + "phase": "creating" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_default.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_default.json new file mode 100644 index 0000000..2f9146e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_default.json @@ -0,0 +1,61 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": {}, + "locations": [], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": {} + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_update.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_update.json new file mode 100644 index 0000000..8d0a195 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_gkecc_update.json @@ -0,0 +1,90 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": {}, + "locations": [], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + }, + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup2", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": {} + }, + "status": { + "failureMessage": "", + "phase": "updating" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_update.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_update.yaml new file mode 100644 index 0000000..a269d3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/onclusterchange_update.yaml @@ -0,0 +1,96 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: gke-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: "" + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: [] + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: {} + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + conditions: + - lastUpdateTime: "2022-08-22T15:25:19-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-22T15:28:08-04:00" + status: Unknown + type: Updated + driver: GKE diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.json new file mode 100644 index 0000000..0c38532 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.json @@ -0,0 +1,82 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "10.124.0.0/14", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "clusterIpv4CidrBlock": "10.124.0.0/14", + "clusterSecondaryRangeName": "gke-gke-test-pods-fedcba98", + "servicesIpv4CidrBlock": "10.0.0.0/20", + "servicesSecondaryRangeName": "gke-gke-test-services-fedcba98", + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": {}, + "locations": [ + "us-central1-c" + ], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2" + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + }, + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2" + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup2", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": { + "enabled": false + } + }, + "status": { + "failureMessage": "", + "phase": "active" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.yaml new file mode 100644 index 0000000..44a2a64 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig.yaml @@ -0,0 +1,341 @@ +apiVersion: management.cattle.io/v3 +kind: Cluster +spec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: gke-test + dockerRootDir: /var/lib/docker + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: false + fleetWorkspaceName: fleet-default + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: 10.124.0.0/14 + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + clusterIpv4CidrBlock: 10.124.0.0/14 + clusterSecondaryRangeName: gke-gke-test-pods-fedcba98 + servicesIpv4CidrBlock: 10.0.0.0/20 + servicesSecondaryRangeName: gke-gke-test-services-fedcba98 + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: + TESTKEY: TESTVALUE + locations: [] + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: + enabled: false + maxNodeCount: 0 + minNodeCount: 0 + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + labels: {} + localSsdCount: 0 + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + preemptible: false + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: + enabled: false + maxNodeCount: 0 + minNodeCount: 0 + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + labels: {} + localSsdCount: 0 + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + preemptible: false + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: + enabled: false + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false +status: + agentFeatures: + embedded-cluster-api: false + fleet: false + monitoringv1: false + multi-cluster-management: false + multi-cluster-management-agent: true + provisioningv2: false + rke2: false + agentImage: rancher/rancher-agent:v2.6-head + allocatable: + cpu: 11580m + memory: 34513328Ki + pods: "660" + apiEndpoint: https://apiendpoint + appliedAgentEnvVars: + - name: CATTLE_SERVER_VERSION + value: dev + - name: CATTLE_INSTALL_UUID + value: 3573e14c-efce-425e-ae8a-7ddc80578c5e + - name: CATTLE_INGRESS_IP_DOMAIN + value: sslip.io + appliedEnableNetworkPolicy: false + appliedPodSecurityPolicyTemplateId: "" + appliedSpec: + agentImageOverride: "" + answers: {} + clusterSecrets: {} + description: "" + desiredAgentImage: "" + desiredAuthImage: "" + displayName: "" + enableClusterAlerting: false + enableClusterMonitoring: false + enableNetworkPolicy: null + gkeConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: 10.124.0.0/14 + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + clusterIpv4CidrBlock: 10.124.0.0/14 + clusterSecondaryRangeName: gke-gke-test-pods-fedcba98 + servicesIpv4CidrBlock: 10.0.0.0/20 + servicesSecondaryRangeName: gke-gke-test-services-fedcba98 + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: + - us-central1-c + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: + enabled: false + internal: false + localClusterAuthEndpoint: + enabled: false + windowsPreferedCluster: false + authImage: "" + caCert: testcacertvalue12345678910 + capabilities: + loadBalancerCapabilities: {} + capacity: + cpu: "12" + memory: 45793712Ki + pods: "660" + conditions: + - status: "True" + type: Pending + - lastUpdateTime: "2022-08-22T15:25:19-04:00" + status: "True" + type: Provisioned + - lastUpdateTime: "2022-08-22T15:26:39-04:00" + status: "True" + type: Waiting + - lastUpdateTime: "2022-08-22T15:19:01-04:00" + status: "True" + type: BackingNamespaceCreated + - lastUpdateTime: "2022-08-22T15:19:01-04:00" + status: "True" + type: DefaultProjectCreated + - lastUpdateTime: "2022-08-22T15:19:01-04:00" + status: "True" + type: SystemProjectCreated + - lastUpdateTime: "2022-08-22T15:19:02-04:00" + status: "True" + type: InitialRolesPopulated + - lastUpdateTime: "2022-08-22T15:19:06-04:00" + status: "True" + type: CreatorMadeOwner + - lastUpdateTime: "2022-08-22T15:19:08-04:00" + status: "True" + type: NoDiskPressure + - lastUpdateTime: "2022-08-22T15:19:08-04:00" + status: "True" + type: NoMemoryPressure + - lastUpdateTime: "2022-08-22T15:19:09-04:00" + status: "True" + type: SecretsMigrated + - lastUpdateTime: "2022-08-22T15:19:10-04:00" + status: "True" + type: ServiceAccountSecretsMigrated + - lastUpdateTime: "2022-08-22T21:52:32Z" + status: "True" + type: Connected + - lastUpdateTime: "2022-08-22T17:52:48-04:00" + status: "True" + type: Ready + - lastUpdateTime: "2022-08-22T16:56:11-04:00" + status: "True" + type: Updated + - lastUpdateTime: "2022-08-22T15:25:26-04:00" + status: "True" + type: GlobalAdminsSynced + - lastUpdateTime: "2022-08-22T15:25:30-04:00" + status: "True" + type: SystemAccountCreated + - lastUpdateTime: "2022-08-22T15:25:41-04:00" + status: "True" + type: AgentDeployed + driver: GKE + gkeStatus: + privateRequiresTunnel: null + upstreamSpec: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + clusterIpv4Cidr: 10.124.0.0/14 + clusterName: gke-test + description: "" + enableKubernetesAlpha: false + googleCredentialSecret: cattle-global-data:cc-swv64 + imported: false + ipAllocationPolicy: + clusterIpv4CidrBlock: 10.124.0.0/14 + clusterSecondaryRangeName: gke-gke-test-pods-fedcba98 + servicesIpv4CidrBlock: 10.0.0.0/20 + servicesSecondaryRangeName: gke-gke-test-services-fedcba98 + useIpAliases: true + kubernetesVersion: 1.22.11-gke.400 + labels: {} + locations: + - us-central1-c + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: {} + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyEnabled: false + nodePools: + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup + version: 1.22.11-gke.400 + - autoscaling: {} + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS + machineType: n1-standard-2 + initialNodeCount: 3 + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: nodegroup2 + version: 1.22.11-gke.400 + privateClusterConfig: {} + projectID: test-project-id + region: "" + subnetwork: default + zone: us-central1-c + autopilotConfig: + enabled: false + limits: + cpu: 287m + memory: 5433Mi + pods: "0" + linuxWorkerCount: 6 + nodeCount: 6 + provider: gke + requested: + cpu: 1947m + memory: "2278069888" + pods: "40" + serviceAccountTokenSecret: cluster-serviceaccounttoken-secret diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig_updated.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig_updated.json new file mode 100644 index 0000000..5ed38a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/gke/test/updategkeclusterconfig_updated.json @@ -0,0 +1,98 @@ +{ + "apiVersion": "gke.cattle.io/v1", + "kind": "GKEClusterConfig", + "spec": { + "clusterAddons": { + "horizontalPodAutoscaling": true, + "httpLoadBalancing": true + }, + "clusterIpv4Cidr": "10.124.0.0/14", + "clusterName": "gke-test", + "description": "", + "enableKubernetesAlpha": false, + "googleCredentialSecret": "cattle-global-data:cc-swv64", + "imported": false, + "ipAllocationPolicy": { + "clusterIpv4CidrBlock": "10.124.0.0/14", + "clusterSecondaryRangeName": "gke-gke-test-pods-fedcba98", + "servicesIpv4CidrBlock": "10.0.0.0/20", + "servicesSecondaryRangeName": "gke-gke-test-services-fedcba98", + "useIpAliases": true + }, + "kubernetesVersion": "1.22.11-gke.400", + "labels": { + "TESTKEY": "TESTVALUE" + }, + "locations": [], + "loggingService": "logging.googleapis.com/kubernetes", + "maintenanceWindow": "", + "masterAuthorizedNetworks": {}, + "monitoringService": "monitoring.googleapis.com/kubernetes", + "network": "default", + "networkPolicyEnabled": false, + "nodePools": [ + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup", + "version": "1.22.11-gke.400" + }, + { + "autoscaling": {}, + "config": { + "diskSizeGb": 100, + "diskType": "pd-standard", + "imageType": "COS", + "machineType": "n1-standard-2", + "oauthScopes": [ + "https://www.googleapis.com/auth/devstorage.read_only", + "https://www.googleapis.com/auth/logging.write", + "https://www.googleapis.com/auth/monitoring", + "https://www.googleapis.com/auth/servicecontrol", + "https://www.googleapis.com/auth/service.management.readonly", + "https://www.googleapis.com/auth/trace.append" + ] + }, + "initialNodeCount": 3, + "management": { + "autoRepair": true, + "autoUpgrade": true + }, + "maxPodsConstraint": 110, + "name": "nodegroup2", + "version": "1.22.11-gke.400" + } + ], + "privateClusterConfig": {}, + "projectID": "test-project-id", + "region": "", + "subnetwork": "default", + "zone": "us-central1-c", + "autopilotConfig": { + "enabled": false + } + }, + "status": { + "failureMessage": "", + "phase": "active" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/imported/imported.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/imported/imported.go new file mode 100644 index 0000000..ffd9dce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/imported/imported.go @@ -0,0 +1,7 @@ +package imported + +import v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + +func IsAdministratedByProvisioningCluster(cluster *v3.Cluster) bool { + return (cluster.Status.Driver == v3.ClusterDriverImported || cluster.Status.Driver == "") && cluster.Annotations["provisioning.cattle.io/administrated"] == "true" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans.go new file mode 100644 index 0000000..01b5a50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans.go @@ -0,0 +1,253 @@ +package k3sbasedupgrade + +import ( + "context" + "fmt" + "reflect" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusterdeploy" + planClientset "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + planv1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const MaxDisplayNodes = 10 + +// deployPlans creates a master and worker plan in the downstream cluster to instrument +// the system-upgrade-controller in the downstream cluster +func (h *handler) deployPlans(cluster *v3.Cluster, isK3s, isRke2 bool) error { + var ( + upgradeImage string + masterPlanName string + workerPlanName string + Version string + strategy v32.ClusterUpgradeStrategy + ) + switch { + case isRke2: + upgradeImage = settings.PrefixPrivateRegistry(rke2upgradeImage) + masterPlanName = rke2MasterPlanName + workerPlanName = rke2WorkerPlanName + Version = cluster.Spec.Rke2Config.Version + strategy = cluster.Spec.Rke2Config.ClusterUpgradeStrategy + case isK3s: + upgradeImage = settings.PrefixPrivateRegistry(k3supgradeImage) + masterPlanName = k3sMasterPlanName + workerPlanName = k3sWorkerPlanName + Version = cluster.Spec.K3sConfig.Version + strategy = cluster.Spec.K3sConfig.ClusterUpgradeStrategy + } + // access downstream cluster + clusterCtx, err := h.manager.UserContextNoControllers(cluster.Name) + if err != nil { + return err + + } + + // create a client for GETing Plans in the downstream cluster + planConfig, err := planClientset.NewForConfig(&clusterCtx.RESTConfig) + if err != nil { + return err + } + planClient := planConfig.Plans(metav1.NamespaceAll) + + planList, err := planClient.List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + masterPlan := &planv1.Plan{} + workerPlan := &planv1.Plan{} + // deactivate all existing plans that are not managed by Rancher + for i, plan := range planList.Items { + if _, ok := plan.Labels[rancherManagedPlan]; !ok { + // inverse selection is used here, we select a non-existent label + lsr := metav1.LabelSelectorRequirement{ + Key: upgradeDisableLabelKey, + Operator: metav1.LabelSelectorOpExists, + } + plan.Spec.NodeSelector.MatchExpressions = append(plan.Spec.NodeSelector.MatchExpressions, lsr) + + _, err = planConfig.Plans(plan.Namespace).Update(context.TODO(), &plan, metav1.UpdateOptions{}) + if err != nil { + return err + } + + } else { + + switch name := plan.Name; name { + case k3sMasterPlanName, rke2MasterPlanName: + if plan.Namespace == systemUpgradeNS { + // reference absolute memory location + masterPlan = &planList.Items[i] + } + case k3sWorkerPlanName, rke2WorkerPlanName: + if plan.Namespace == systemUpgradeNS { + // reference absolute memory location + workerPlan = &planList.Items[i] + } + } + } + } + // if rancher plans exist, do we need to update? + if masterPlan.Name != "" || workerPlan.Name != "" { + if masterPlan.Name != "" { + newMaster := configureMasterPlan(*masterPlan, Version, + strategy.ServerConcurrency, + strategy.DrainServerNodes, masterPlanName) + + if !cmp(*masterPlan, newMaster) { + logrus.Infof("[k3s-based-upgrader] updating plan [%s] in cluster [%s]", newMaster.Name, cluster.Name) + planClient = planConfig.Plans(systemUpgradeNS) + masterPlan, err = planClient.Update(context.TODO(), &newMaster, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + } + + if workerPlan.Name != "" { + newWorker := configureWorkerPlan(*workerPlan, Version, + strategy.WorkerConcurrency, + strategy.DrainWorkerNodes, upgradeImage, workerPlanName, masterPlanName) + + if !cmp(*workerPlan, newWorker) { + logrus.Infof("[k3s-based-upgrader] updating plan [%s] in cluster [%s]", newWorker.Name, cluster.Name) + planClient = planConfig.Plans(systemUpgradeNS) + workerPlan, err = planClient.Update(context.TODO(), &newWorker, metav1.UpdateOptions{}) + if err != nil { + return err + } + } + } + + } else { // create the plans + logrus.Infof("[k3s-based-upgrader] creating plans in cluster [%s]", cluster.Name) + planClient = planConfig.Plans(systemUpgradeNS) + genMasterPlan := generateMasterPlan(Version, + strategy.ServerConcurrency, + strategy.DrainServerNodes, upgradeImage, masterPlanName) + + masterPlan, err = planClient.Create(context.TODO(), &genMasterPlan, metav1.CreateOptions{}) + if err != nil { + return err + } + genWorkerPlan := generateWorkerPlan(Version, + strategy.WorkerConcurrency, + strategy.DrainWorkerNodes, upgradeImage, workerPlanName, masterPlanName) + + workerPlan, err = planClient.Create(context.TODO(), &genWorkerPlan, metav1.CreateOptions{}) + if err != nil { + return err + } + logrus.Infof("[k3s-based-upgrader] plans successfully deployed into cluster [%s]", cluster.Name) + } + + cluster, err = h.modifyClusterCondition(cluster, *masterPlan, *workerPlan, strategy) + if err != nil { + return err + } + return nil +} + +// cmp compares two plans but does not compare their Status, returns true if they are the same +func cmp(a, b planv1.Plan) bool { + if a.Namespace != b.Namespace { + return false + } + + if a.Spec.Version != b.Spec.Version { + return false + } + + if a.Spec.Concurrency != b.Spec.Concurrency { + return false + } + + if !reflect.DeepEqual(a.Spec, b.Spec) { + return false + } + if !reflect.DeepEqual(a.Labels, b.Labels) { + return false + } + if !reflect.DeepEqual(a.TypeMeta, b.TypeMeta) { + return false + } + return true +} + +// cluster state management during the upgrade, plans may be "" +func (h *handler) modifyClusterCondition(cluster *v3.Cluster, masterPlan, workerPlan planv1.Plan, strategy v32.ClusterUpgradeStrategy) (*v3.Cluster, error) { + + // implement a simple state machine + // UpgradedTrue => GenericUpgrading => MasterPlanUpgrading || WorkerPlanUpgrading => UpgradedTrue + + if masterPlan.Name == "" && workerPlan.Name == "" { + // enter upgrading state + if v32.ClusterConditionUpgraded.IsTrue(cluster) { + v32.ClusterConditionUpgraded.Unknown(cluster) + v32.ClusterConditionUpgraded.Message(cluster, "cluster is being upgraded") + return h.clusterClient.Update(cluster) + } + if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + // remain in upgrading state if we are passed empty plans + return cluster, nil + } + } + + if masterPlan.Name != "" && len(masterPlan.Status.Applying) > 0 { + v32.ClusterConditionUpgraded.Unknown(cluster) + c := strategy.ServerConcurrency + masterPlanMessage := fmt.Sprintf("controlplane node [%s] being upgraded", + upgradingMessage(c, masterPlan.Status.Applying)) + return h.enqueueOrUpdate(cluster, masterPlanMessage) + + } + + if workerPlan.Name != "" && len(workerPlan.Status.Applying) > 0 { + v32.ClusterConditionUpgraded.Unknown(cluster) + c := strategy.WorkerConcurrency + workerPlanMessage := fmt.Sprintf("worker node [%s] being upgraded", + upgradingMessage(c, workerPlan.Status.Applying)) + return h.enqueueOrUpdate(cluster, workerPlanMessage) + } + + // if we made it this far nothing is applying + // see k3supgrade_handler also + v32.ClusterConditionUpgraded.True(cluster) + if cluster.Spec.LocalClusterAuthEndpoint.Enabled { + // If ACE is enabled, the force a re-deploy of the cluster-agent and kube-api-auth + cluster.Annotations[clusterdeploy.AgentForceDeployAnn] = "true" + } + return h.clusterClient.Update(cluster) + +} + +func upgradingMessage(concurrency int, nodes []string) string { + // concurrency max can be very large + if concurrency > len(nodes) { + concurrency = len(nodes) + } + if concurrency > MaxDisplayNodes { + concurrency = MaxDisplayNodes + } + + return strings.Join(nodes[:concurrency], ", ") +} + +func (h *handler) enqueueOrUpdate(cluster *v3.Cluster, upgradeMessage string) (*v3.Cluster, error) { + if v32.ClusterConditionUpgraded.GetMessage(cluster) == upgradeMessage { + // update would be no op + h.clusterEnqueueAfter(cluster.Name, time.Second*5) // prevent controller from remaining in this state + return cluster, nil + } + + v32.ClusterConditionUpgraded.Message(cluster, upgradeMessage) + return h.clusterClient.Update(cluster) + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans_test.go new file mode 100644 index 0000000..03ac163 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/deployPlans_test.go @@ -0,0 +1,49 @@ +package k3sbasedupgrade + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_upgradingMessage(t *testing.T) { + + tests := []struct { + name string + concurrency int + nodes []string + want string + }{ + // concurrency cannot be negative, min is set to 1 via Norman struct tag + { + name: "base", + concurrency: 2, + nodes: []string{"node1", "node2"}, + want: "node1, node2", + }, + { + name: "single", + concurrency: 1, + nodes: []string{"node1", "node2"}, + want: "node1", + }, + { + name: "high concurrency", + concurrency: 50000, + nodes: []string{"n1", "n2", "n3"}, + want: "n1, n2, n3", + }, + { + name: "max + 1", + concurrency: MaxDisplayNodes + 1, + nodes: []string{"n1", "n2", "n3", "n3", "n4", "n5", "n6", "n7", "n8", "n9", "n10", "n11"}, + want: "n1, n2, n3, n3, n4, n5, n6, n7, n8, n9", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := upgradingMessage(tt.concurrency, tt.nodes) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/k3sbased_upgrade_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/k3sbased_upgrade_handler.go new file mode 100644 index 0000000..a658ff4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/k3sbased_upgrade_handler.go @@ -0,0 +1,261 @@ +package k3sbasedupgrade + +import ( + "fmt" + "strings" + + "github.com/coreos/go-semver/semver" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v33 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + app2 "github.com/rancher/rancher/pkg/app" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/ref" + planv1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +func (h *handler) onClusterChange(key string, cluster *v3.Cluster) (*v3.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil { + return nil, nil + } + isK3s := cluster.Status.Driver == v32.ClusterDriverK3s + isRke2 := cluster.Status.Driver == v32.ClusterDriverRke2 + // only applies to k3s/rke2 clusters + if !isK3s && !isRke2 { + return cluster, nil + } + // Don't allow nil configs to continue for given cluster type + if (isK3s && cluster.Spec.K3sConfig == nil) || (isRke2 && cluster.Spec.Rke2Config == nil) { + return cluster, nil + } + + var ( + updateVersion string + strategy v32.ClusterUpgradeStrategy + ) + switch { + case isK3s: + updateVersion = cluster.Spec.K3sConfig.Version + strategy = cluster.Spec.K3sConfig.ClusterUpgradeStrategy + case isRke2: + updateVersion = cluster.Spec.Rke2Config.Version + strategy = cluster.Spec.Rke2Config.ClusterUpgradeStrategy + + } + if updateVersion == "" { + return cluster, nil + } + + // Check if the cluster is undergoing a Kubernetes version upgrade, and that + // all downstream nodes also need the upgrade + isNewer, err := IsNewerVersion(cluster.Status.Version.GitVersion, updateVersion) + if err != nil { + return cluster, err + } + if !isNewer { + needsUpgrade, err := h.nodesNeedUpgrade(cluster, updateVersion) + if err != nil { + return cluster, err + } + if !needsUpgrade { + // if upgrade was in progress, make sure to set the state back + if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + logrus.Infof("[k3s-based-upgrader] finished upgrading cluster [%s]", cluster.Name) + v32.ClusterConditionUpgraded.True(cluster) + v32.ClusterConditionUpgraded.Message(cluster, "") + return h.clusterClient.Update(cluster) + } + return cluster, nil + } + + } + + if v32.ClusterConditionUpgraded.IsTrue(cluster) { + logrus.Infof("[k3s-based-upgrader] upgrading cluster [%s] version from [%s] to [%s]", + cluster.Name, cluster.Status.Version.GitVersion, updateVersion) + if isNewer { + logrus.Debugf("[k3s-based-upgrader] upgrading cluster [%s] because cluster version [%s] is newer than observed version [%s]", + cluster.Name, updateVersion, cluster.Status.Version.GitVersion) + } else { + logrus.Debugf("[k3s-based-upgrader] upgrading cluster [%s] because cluster version [%s] is newer than observed node version", + cluster.Name, updateVersion) + } + } + + // set cluster upgrading status + cluster, err = h.modifyClusterCondition(cluster, planv1.Plan{}, planv1.Plan{}, strategy) + if err != nil { + return cluster, err + } + + // create or update k3supgradecontroller if necessary + if err = h.deployK3sBasedUpgradeController(cluster.Name, isK3s, isRke2); err != nil { + return cluster, err + } + + // deploy plans into downstream cluster + if err = h.deployPlans(cluster, isK3s, isRke2); err != nil { + return cluster, err + } + + return cluster, nil +} + +// deployK3sBaseUpgradeController creates a rancher k3s/rke2 upgrader controller if one does not exist. +// Updates k3s upgrader controller if one exists and is not the newest available version. +func (h *handler) deployK3sBasedUpgradeController(clusterName string, isK3s, isRke2 bool) error { + userCtx, err := h.manager.UserContextNoControllers(clusterName) + if err != nil { + return err + } + + projectLister := userCtx.Management.Management.Projects("").Controller().Lister() + systemProject, err := project.GetSystemProject(clusterName, projectLister) + if err != nil { + return err + } + + templateID := k3sUpgraderCatalogName + template, err := h.templateLister.Get(namespace.GlobalNamespace, templateID) + if err != nil { + return err + } + + latestTemplateVersion, err := h.catalogManager.LatestAvailableTemplateVersion(template, clusterName) + if err != nil { + return err + } + + creator, err := h.systemAccountManager.GetSystemUser(clusterName) + if err != nil { + return err + } + systemProjectID := ref.Ref(systemProject) + _, systemProjectName := ref.Parse(systemProjectID) + + nsClient := userCtx.Core.Namespaces("") + appProjectName, err := app2.EnsureAppProjectName(nsClient, systemProjectName, clusterName, systemUpgradeNS, creator.Name) + if err != nil { + return err + } + + appLister := userCtx.Management.Project.Apps("").Controller().Lister() + appClient := userCtx.Management.Project.Apps("") + + latestVersionID := latestTemplateVersion.ExternalID + var appname string + switch { + case isK3s: + appname = "rancher-k3s-upgrader" + case isRke2: + appname = "rancher-rke2-upgrader" + } + app, err := appLister.Get(systemProjectName, appname) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + logrus.Infof("[k3s-based-upgrader] installing app [%s] in cluster [%s]", appname, clusterName) + desiredApp := &v33.App{ + ObjectMeta: metav1.ObjectMeta{ + Name: appname, + Namespace: systemProjectName, + Annotations: map[string]string{ + "field.cattle.io/creatorId": creator.Name, + }, + }, + Spec: v33.AppSpec{ + Description: "Upgrade controller for k3s based clusters", + ExternalID: latestVersionID, + ProjectName: appProjectName, + TargetNamespace: systemUpgradeNS, + }, + } + + // k3s upgrader doesn't exist yet, so it will need to be created + if _, err = appClient.Create(desiredApp); err != nil { + return err + } + } else { + if !checkDeployed(app) { + if !v33.AppConditionForceUpgrade.IsUnknown(app) { + v33.AppConditionForceUpgrade.Unknown(app) + } + logrus.Warnln("force redeploying system-upgrade-controller") + if _, err = appClient.Update(app); err != nil { + return err + } + } + + // everything is up-to-date and are set up properly, no need to update. + if app.Spec.ExternalID == latestVersionID { + return nil + } + + desiredApp := app.DeepCopy() + desiredApp.Spec.ExternalID = latestVersionID + logrus.Infof("[k3s-based-upgrader] updating app [%s] in cluster [%s]", appname, clusterName) + // new version of k3s upgrade available, or the valuesYaml have changed, update app + if _, err = appClient.Update(desiredApp); err != nil { + return err + } + } + + return nil +} + +// IsNewerVersion returns true if updated versions semver is newer and false if its +// semver is older. If semver is equal then metadata is alphanumerically compared. +func IsNewerVersion(prevVersion, updatedVersion string) (bool, error) { + parseErrMsg := "failed to parse version: %v" + prevVer, err := semver.NewVersion(strings.TrimPrefix(prevVersion, "v")) + if err != nil { + return false, fmt.Errorf(parseErrMsg, err) + } + + updatedVer, err := semver.NewVersion(strings.TrimPrefix(updatedVersion, "v")) + if err != nil { + return false, fmt.Errorf(parseErrMsg, err) + } + + switch updatedVer.Compare(*prevVer) { + case -1: + return false, nil + case 1: + return true, nil + default: + // using metadata to determine precedence is against semver standards + // this is ignored because it because k3s uses it to precedence between + // two versions based on same k8s version + return updatedVer.Metadata > prevVer.Metadata, nil + } +} + +// nodeNeedsUpgrade checks all nodes in cluster, returns true if they still need to be upgraded +func (h *handler) nodesNeedUpgrade(cluster *v3.Cluster, version string) (bool, error) { + v3NodeList, err := h.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return false, err + } + for _, node := range v3NodeList { + isNewer, err := IsNewerVersion(node.Status.InternalNodeStatus.NodeInfo.KubeletVersion, version) + if err != nil { + return false, err + } + if isNewer { + logrus.Debugf("[k3s-based-upgrader] cluster [%s] version [%s] is newer than observed node [%s] version [%s]", + cluster.Name, version, node.Name, node.Status.InternalNodeStatus.NodeInfo.KubeletVersion) + return true, nil + } + } + return false, nil +} + +func checkDeployed(app *v33.App) bool { + return v33.AppConditionDeployed.IsTrue(app) || v33.AppConditionInstalled.IsTrue(app) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/register.go new file mode 100644 index 0000000..7550988 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/register.go @@ -0,0 +1,54 @@ +package k3sbasedupgrade + +import ( + "context" + "time" + + manager2 "github.com/rancher/rancher/pkg/catalog/manager" + "github.com/rancher/rancher/pkg/clustermanager" + wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + projectv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type handler struct { + systemUpgradeNamespace string + clusterCache wranglerv3.ClusterCache + clusterClient wranglerv3.ClusterClient + catalogManager manager2.CatalogManager + apps projectv3.AppInterface + appLister projectv3.AppLister + templateLister v3.CatalogTemplateLister + nodeLister v3.NodeLister + systemAccountManager *systemaccount.Manager + manager *clustermanager.Manager + clusterEnqueueAfter func(name string, duration time.Duration) +} + +const ( + systemUpgradeNS = "cattle-system" + rancherManagedPlan = "rancher-managed" + upgradeDisableLabelKey = "upgrade.cattle.io/disable" + k3sUpgraderCatalogName = "system-library-rancher-k3s-upgrader" +) + +func Register(ctx context.Context, wContext *wrangler.Context, mgmtCtx *config.ManagementContext, manager *clustermanager.Manager) { + h := &handler{ + systemUpgradeNamespace: systemUpgradeNS, + clusterCache: wContext.Mgmt.Cluster().Cache(), + clusterClient: wContext.Mgmt.Cluster(), + catalogManager: mgmtCtx.CatalogManager, + clusterEnqueueAfter: wContext.Mgmt.Cluster().EnqueueAfter, + apps: mgmtCtx.Project.Apps(metav1.NamespaceAll), + appLister: mgmtCtx.Project.Apps("").Controller().Lister(), + templateLister: mgmtCtx.Management.CatalogTemplates("").Controller().Lister(), + nodeLister: mgmtCtx.Management.Nodes("").Controller().Lister(), + systemAccountManager: systemaccount.NewManager(mgmtCtx), + manager: manager, + } + wContext.Mgmt.Cluster().OnChange(ctx, "k3s-upgrade-controller", h.onClusterChange) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template.go new file mode 100644 index 0000000..42e8649 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template.go @@ -0,0 +1,168 @@ +package k3sbasedupgrade + +import ( + "strings" + + "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io" + planv1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubectl/pkg/describe" +) + +const k3sMasterPlanName = "k3s-master-plan" +const k3sWorkerPlanName = "k3s-worker-plan" +const systemUpgradeServiceAccount = "system-upgrade-controller" +const k3supgradeImage = "rancher/k3s-upgrade" +const rke2upgradeImage = "rancher/rke2-upgrade" +const rke2MasterPlanName = "rke2-master-plan" +const rke2WorkerPlanName = "rke2-worker-plan" + +var genericPlan = planv1.Plan{ + TypeMeta: metav1.TypeMeta{ + Kind: "Plan", + APIVersion: upgrade.GroupName + `/v1`, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: systemUpgradeNS, + Labels: map[string]string{rancherManagedPlan: "true"}, + }, + Spec: planv1.PlanSpec{ + Concurrency: 0, + ServiceAccountName: systemUpgradeServiceAccount, + Cordon: true, + Upgrade: &planv1.ContainerSpec{}, + }, + Status: planv1.PlanStatus{}, +} + +func generateMasterPlan(version string, concurrency int, drain bool, upgradeImage, masterPlanName string) planv1.Plan { + masterPlan := genericPlan + masterPlan.Spec.Upgrade.Image = upgradeImage + masterPlan.Name = masterPlanName + masterPlan.Spec.Version = version + masterPlan.Spec.Concurrency = int64(concurrency) + + if drain { + masterPlan.Spec.Drain = &planv1.DrainSpec{ + Force: true, + } + } + + // only select master nodes + masterPlan.Spec.NodeSelector = &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{{ + + Key: describe.LabelNodeRolePrefix + "master", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"true"}, + }}, + } + + masterPlan.Spec.Tolerations = []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }} + + return masterPlan +} + +func generateWorkerPlan(version string, concurrency int, drain bool, upgradeImage, workerPlanName, masterPlanName string) planv1.Plan { + workerPlan := genericPlan + workerPlan.Spec.Upgrade.Image = upgradeImage + workerPlan.Name = workerPlanName + workerPlan.Spec.Version = version + workerPlan.Spec.Concurrency = int64(concurrency) + + if drain { + workerPlan.Spec.Drain = &planv1.DrainSpec{ + Force: true, + } + } + + // worker plans wait for master plans to complete + workerPlan.Spec.Prepare = &planv1.ContainerSpec{ + Image: upgradeImage + ":" + parseVersion(version), + Args: []string{"prepare", masterPlanName}, + } + // select all nodes that are not master + workerPlan.Spec.NodeSelector = &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: describe.LabelNodeRolePrefix + "master", + Operator: metav1.LabelSelectorOpDoesNotExist, + }}, + } + + workerPlan.Spec.Tolerations = []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }} + + return workerPlan +} + +func configureMasterPlan(masterPlan planv1.Plan, version string, concurrency int, drain bool, masterPlanName string) planv1.Plan { + masterPlan.Name = masterPlanName + masterPlan.Spec.Version = version + masterPlan.Spec.Concurrency = int64(concurrency) + + if drain { + masterPlan.Spec.Drain = &planv1.DrainSpec{ + Force: true, + } + } + + // only select master nodes + masterPlan.Spec.NodeSelector = &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{{ + + Key: describe.LabelNodeRolePrefix + "master", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"true"}, + }}, + } + + masterPlan.Spec.Tolerations = []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }} + + masterPlan.Spec.ServiceAccountName = genericPlan.Spec.ServiceAccountName + + return masterPlan +} + +func configureWorkerPlan(workerPlan planv1.Plan, version string, concurrency int, drain bool, upgradeImage, workerPlanName, masterPlanName string) planv1.Plan { + workerPlan.Name = workerPlanName + workerPlan.Spec.Version = version + workerPlan.Spec.Concurrency = int64(concurrency) + + if drain { + workerPlan.Spec.Drain = &planv1.DrainSpec{ + Force: true, + } + } + + // worker plans wait for master plans to complete + workerPlan.Spec.Prepare = &planv1.ContainerSpec{ + Image: upgradeImage + ":" + parseVersion(version), + Args: []string{"prepare", masterPlanName}, + } + + workerPlan.Spec.NodeSelector = &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{{ + Key: describe.LabelNodeRolePrefix + "master", + Operator: metav1.LabelSelectorOpDoesNotExist, + }}, + } + + workerPlan.Spec.Tolerations = []corev1.Toleration{{ + Operator: corev1.TolerationOpExists, + }} + + workerPlan.Spec.ServiceAccountName = genericPlan.Spec.ServiceAccountName + + return workerPlan +} + +// a valid k3s version needs to be converted to valid docker tag (v1.17.3+k3s1 => v1.17.3-k3s1) +func parseVersion(v string) string { + return strings.Replace(v, "+", "-", -1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template_test.go new file mode 100644 index 0000000..0c1ee80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/k3sbasedupgrade/template_test.go @@ -0,0 +1,25 @@ +package k3sbasedupgrade + +import "testing" + +func Test_parseVersion(t *testing.T) { + + tests := []struct { + name string + version string + want string + }{ + { + "base", + "v1.17.3+k3s1", + "v1.17.3-k3s1", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := parseVersion(tt.version); got != tt.want { + t.Errorf("parseVersion() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data.go new file mode 100644 index 0000000..62ab928 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data.go @@ -0,0 +1,708 @@ +package kontainerdrivermetadata + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "reflect" + "sort" + "strings" + + "github.com/blang/semver" + mVersion "github.com/mcuadros/go-version" + "github.com/rancher/norman/types/convert" + setting2 "github.com/rancher/rancher/pkg/api/norman/store/setting" + "github.com/rancher/rancher/pkg/channelserver" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/rke/types/kdm" + "github.com/rancher/rke/util" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type OSType int + +const ( + Linux OSType = iota + Windows +) + +const ( + APIVersion = "management.cattle.io/v3" + DataJSONLocation = "/var/lib/rancher-data/driver-metadata/data.json" + sendRKELabel = "io.cattle.rke_store" + svcOptionLinuxKey = "service-option-linux-key" + svcOptionWindowsKey = "service-option-windows-key" + rkeSystemImageKind = "RkeK8sSystemImage" + rkeServiceOptionKind = "RkeK8sServiceOption" + rkeAddonKind = "RkeAddon" +) + +var existLabel = map[string]string{sendRKELabel: "false"} + +// settings corresponding to keys in setting2.MetadataSettings +var userUpdateSettingMap = map[string]settings.Setting{ + settings.KubernetesVersion.Name: settings.KubernetesVersion, + settings.KubernetesVersionsCurrent.Name: settings.KubernetesVersionsCurrent, + settings.KubernetesVersionsDeprecated.Name: settings.KubernetesVersionsDeprecated, +} + +var rancherUpdateSettingMap = map[string]settings.Setting{ + settings.KubernetesVersion.Name: settings.KubernetesVersion, + settings.KubernetesVersionsCurrent.Name: settings.KubernetesVersionsCurrent, + settings.KubernetesVersionsDeprecated.Name: settings.KubernetesVersionsDeprecated, + settings.UIKubernetesDefaultVersion.Name: settings.UIKubernetesDefaultVersion, + settings.UIKubernetesSupportedVersions.Name: settings.UIKubernetesSupportedVersions, + settings.KubernetesVersionToSystemImages.Name: settings.KubernetesVersionToSystemImages, + settings.KubernetesVersionToServiceOptions.Name: settings.KubernetesVersionToServiceOptions, + settings.Rke2DefaultVersion.Name: settings.Rke2DefaultVersion, + settings.K3sDefaultVersion.Name: settings.K3sDefaultVersion, +} + +func (md *MetadataController) loadDataFromLocal() (kdm.Data, error) { + if os.Getenv("CATTLE_DEV_MODE") != "" { + return kdm.Data{}, nil + } + logrus.Infof("Retrieve data.json from local path %v", DataJSONLocation) + data, err := ioutil.ReadFile(DataJSONLocation) + if err != nil { + return kdm.Data{}, err + } + return kdm.FromData(data) +} + +func (md *MetadataController) createOrUpdateMetadata(data kdm.Data) error { + localData, err := md.loadDataFromLocal() + if err != nil { + return err + } + if err := md.saveSystemImages(data.K8sVersionRKESystemImages, data.K8sVersionedTemplates, + data.K8sVersionInfo, data.K8sVersionServiceOptions, data.K8sVersionWindowsServiceOptions, data.RancherDefaultK8sVersions); err != nil { + return err + } + if err := md.saveAllServiceOptions(data.K8sVersionServiceOptions, data.K8sVersionWindowsServiceOptions, + localData.K8sVersionServiceOptions, localData.K8sVersionWindowsServiceOptions); err != nil { + return err + } + if err := md.saveAddons(data, localData.K8sVersionedTemplates); err != nil { + return err + } + return nil +} + +func (md *MetadataController) createOrUpdateMetadataFromLocal() error { + driverData, err := md.loadDataFromLocal() + if err != nil { + return err + } + if err := md.saveSystemImages(driverData.K8sVersionRKESystemImages, driverData.K8sVersionedTemplates, + driverData.K8sVersionInfo, driverData.K8sVersionServiceOptions, driverData.K8sVersionWindowsServiceOptions, driverData.RancherDefaultK8sVersions); err != nil { + return err + } + if err := md.saveAllServiceOptions(driverData.K8sVersionServiceOptions, driverData.K8sVersionWindowsServiceOptions, nil, nil); err != nil { + return err + } + if err := md.saveAddons(driverData, nil); err != nil { + return err + } + return nil +} + +func (md *MetadataController) saveSystemImages(K8sVersionRKESystemImages map[string]rketypes.RKESystemImages, + AddonsData map[string]map[string]string, + K8sVersionInfo map[string]rketypes.K8sVersionInfo, + ServiceOptions map[string]rketypes.KubernetesServicesOptions, + ServiceOptionsWindows map[string]rketypes.KubernetesServicesOptions, + DefaultK8sVersions map[string]string) error { + maxVersionForMajorK8sVersion := map[string]string{} + deprecatedMap := map[string]bool{} + rancherVersion := settings.GetRancherVersion() + var maxIgnore []string + for k8sVersion, systemImages := range K8sVersionRKESystemImages { + rancherVersionInfo, minorOk := K8sVersionInfo[k8sVersion] + if minorOk && toIgnoreForAllK8s(rancherVersionInfo, rancherVersion) { + deprecatedMap[k8sVersion] = true + continue + } + majorVersion := util.GetTagMajorVersion(k8sVersion) + majorVersionInfo, majorOk := K8sVersionInfo[majorVersion] + if majorOk && toIgnoreForAllK8s(majorVersionInfo, rancherVersion) { + deprecatedMap[k8sVersion] = true + continue + } + labelsMap, err := getLabelMap(k8sVersion, AddonsData, ServiceOptions, ServiceOptionsWindows) + if err != nil { + return err + } + if err := md.createOrUpdateSystemImageCRD(k8sVersion, systemImages, labelsMap); err != nil { + return err + } + if minorOk && toIgnoreForK8sCurrent(rancherVersionInfo, rancherVersion) { + maxIgnore = append(maxIgnore, k8sVersion) + continue + } + if majorOk && toIgnoreForK8sCurrent(majorVersionInfo, rancherVersion) { + maxIgnore = append(maxIgnore, k8sVersion) + continue + } + if curr, ok := maxVersionForMajorK8sVersion[majorVersion]; !ok || mVersion.Compare(k8sVersion, curr, ">") { + maxVersionForMajorK8sVersion[majorVersion] = k8sVersion + } + } + logrus.Debugf("driverMetadata deprecated %v max incompatible versions %v", deprecatedMap, maxIgnore) + + return md.updateSettings(maxVersionForMajorK8sVersion, rancherVersion, ServiceOptions, DefaultK8sVersions, deprecatedMap) +} + +func toIgnoreForAllK8s(rancherVersionInfo rketypes.K8sVersionInfo, rancherVersion string) bool { + if rancherVersionInfo.DeprecateRancherVersion != "" && mVersion.Compare(rancherVersion, rancherVersionInfo.DeprecateRancherVersion, ">=") { + return true + } + if rancherVersionInfo.MinRancherVersion != "" && mVersion.Compare(rancherVersion, rancherVersionInfo.MinRancherVersion, "<") { + // only respect min versions, even if max is present - we need to support upgraded clusters + return true + } + return false +} + +func toIgnoreForK8sCurrent(majorVersionInfo rketypes.K8sVersionInfo, rancherVersion string) bool { + if majorVersionInfo.MaxRancherVersion != "" && mVersion.Compare(rancherVersion, majorVersionInfo.MaxRancherVersion, ">") { + // include in K8sVersionCurrent only if less then max version + return true + } + return false +} + +func (md *MetadataController) saveAllServiceOptions(linuxSvcOptions map[string]rketypes.KubernetesServicesOptions, + windowsSvcOptions map[string]rketypes.KubernetesServicesOptions, localLinuxSvcOptions map[string]rketypes.KubernetesServicesOptions, + localWindowsSvcOptions map[string]rketypes.KubernetesServicesOptions) error { + // save linux options + if err := md.saveServiceOptions(linuxSvcOptions, localLinuxSvcOptions, Linux); err != nil { + return err + } + // save windows options + return md.saveServiceOptions(windowsSvcOptions, localWindowsSvcOptions, Windows) +} + +func (md *MetadataController) saveServiceOptions(k8sVersionServiceOptions map[string]rketypes.KubernetesServicesOptions, + localK8sVersionServiceOptions map[string]rketypes.KubernetesServicesOptions, osType OSType) error { + rkeDataKeys := getRKEVendorOptions(localK8sVersionServiceOptions) + for k8sVersion, serviceOptions := range k8sVersionServiceOptions { + if err := md.createOrUpdateServiceOptionCRD(k8sVersion, serviceOptions, rkeDataKeys, osType); err != nil { + return err + } + } + return nil +} + +func (md *MetadataController) saveAddons(data kdm.Data, localTemplates map[string]map[string]string) error { + k8sVersionedTemplates := data.K8sVersionedTemplates + rkeAddonKeys := getRKEVendorData(localTemplates) + for addon, template := range k8sVersionedTemplates[kdm.TemplateKeys] { + if err := md.createOrUpdateAddonCRD(addon, template, rkeAddonKeys); err != nil { + return err + } + } + return nil +} + +func (md *MetadataController) createOrUpdateSystemImageCRD(k8sVersion string, systemImages rketypes.RKESystemImages, pluginsMap map[string]string) error { + sysImage, err := md.getRKESystemImage(k8sVersion) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + sysImage = &v3.RkeK8sSystemImage{ + ObjectMeta: metav1.ObjectMeta{ + Name: k8sVersion, + Namespace: namespace.GlobalNamespace, + Labels: pluginsMap, + }, + SystemImages: systemImages, + TypeMeta: metav1.TypeMeta{ + Kind: rkeSystemImageKind, + APIVersion: APIVersion, + }, + } + if _, err := md.SystemImages.Create(sysImage); err != nil && !errors.IsAlreadyExists(err) { + return err + } + return nil + } + dataEqual := reflect.DeepEqual(sysImage.SystemImages, systemImages) + labelsEqual := reflect.DeepEqual(sysImage.Labels, pluginsMap) + if dataEqual && labelsEqual { + return nil + } + sysImageCopy := sysImage.DeepCopy() + if !dataEqual { + logrus.Debugf("systemImage changed %s", k8sVersion) + sysImageCopy.SystemImages = systemImages + } + if !labelsEqual { + logrus.Debugf("systemImage labels changed %s old: %v new: %v", k8sVersion, sysImageCopy.Labels, pluginsMap) + for k, v := range pluginsMap { + sysImageCopy.Labels[k] = v + } + } + if _, err := md.SystemImages.Update(sysImageCopy); err != nil { + return err + } + return nil +} + +func (md *MetadataController) createOrUpdateServiceOptionCRD(k8sVersion string, serviceOptions rketypes.KubernetesServicesOptions, rkeDataKeys map[string]bool, osType OSType) error { + svcOption, err := md.getRKEServiceOption(k8sVersion, osType) + _, exists := rkeDataKeys[k8sVersion] + name := getVersionNameWithOsType(k8sVersion, osType) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + svcOption = &v3.RkeK8sServiceOption{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace.GlobalNamespace, + }, + ServiceOptions: serviceOptions, + TypeMeta: metav1.TypeMeta{ + Kind: rkeServiceOptionKind, + APIVersion: APIVersion, + }, + } + if exists { + svcOption.Labels = existLabel + } + if _, err := md.ServiceOptions.Create(svcOption); err != nil && !errors.IsAlreadyExists(err) { + return err + } + return nil + } + var svcOptionCopy *v3.RkeK8sServiceOption + dataEqual := reflect.DeepEqual(svcOption.ServiceOptions, serviceOptions) + labelsEqual := labelEqual(svcOption.Labels, exists) + if dataEqual && labelsEqual { + return nil + } + svcOptionCopy = svcOption.DeepCopy() + if !dataEqual { + logrus.Debugf("serviceOptions changed %s", name) + svcOptionCopy.ServiceOptions = serviceOptions + } + if !labelsEqual { + logrus.Debugf("serviceOptions labels changed %s old: %v new: %v", name, svcOptionCopy.Labels, exists) + svcOptionCopy.Labels = updateLabel(svcOptionCopy.Labels, exists) + } + if svcOptionCopy != nil { + if _, err := md.ServiceOptions.Update(svcOptionCopy); err != nil { + return err + } + } + return nil +} + +func (md *MetadataController) createOrUpdateAddonCRD(addonName, template string, rkeAddonKeys map[string]bool) error { + _, exists := rkeAddonKeys[addonName] + addon, err := md.getRKEAddon(addonName) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + addon = &v3.RkeAddon{ + ObjectMeta: metav1.ObjectMeta{ + Name: addonName, + Namespace: namespace.GlobalNamespace, + }, + Template: template, + TypeMeta: metav1.TypeMeta{ + Kind: rkeAddonKind, + APIVersion: APIVersion, + }, + } + if exists { + addon.Labels = existLabel + } + if _, err := md.Addons.Create(addon); err != nil && !errors.IsAlreadyExists(err) { + return err + } + return nil + } + var addonCopy *v3.RkeAddon + dataEqual := reflect.DeepEqual(addon.Template, template) + labelsEqual := labelEqual(addon.Labels, exists) + if dataEqual && labelsEqual { + return nil + } + addonCopy = addon.DeepCopy() + if !dataEqual { + logrus.Debugf("addonTemplate changed %s", addonName) + addonCopy.Template = template + } + if !labelsEqual { + logrus.Debugf("addonTemplate labels changed %s old: %v new: %v", addonName, addonCopy.Labels, exists) + addonCopy.Labels = updateLabel(addonCopy.Labels, exists) + } + if addonCopy != nil { + if _, err := md.Addons.Update(addonCopy); err != nil { + return err + } + } + return nil +} + +func getLabelMap(k8sVersion string, data map[string]map[string]string, + svcOption map[string]rketypes.KubernetesServicesOptions, svcOptionWindows map[string]rketypes.KubernetesServicesOptions) (map[string]string, error) { + toMatch, err := semver.Make(k8sVersion[1:]) + if err != nil { + return nil, fmt.Errorf("k8sVersion not sem-ver %s %v", k8sVersion, err) + } + labelMap := map[string]string{"cattle.io/creator": "norman"} + for addon, addonData := range data { + if addon == kdm.TemplateKeys { + continue + } + found := false + for k8sRange, key := range addonData { + testRange, err := semver.ParseRange(k8sRange) + if err != nil { + logrus.Errorf("getPluginData: range for %s not sem-ver %v %v", addon, testRange, err) + continue + } + if testRange(toMatch) { + labelMap[addon] = key + found = true + break + } + } + if !found { + logrus.Debugf("getPluginData: no template found for k8sVersion %s plugin %s", k8sVersion, addon) + } + } + // store service options + majorKey := util.GetTagMajorVersion(k8sVersion) + if _, ok := svcOption[k8sVersion]; ok { + labelMap[svcOptionLinuxKey] = getVersionNameWithOsType(k8sVersion, Linux) + } else if _, ok := svcOption[majorKey]; ok { + labelMap[svcOptionLinuxKey] = getVersionNameWithOsType(majorKey, Linux) + } + + if _, ok := svcOptionWindows[k8sVersion]; ok { + labelMap[svcOptionWindowsKey] = getVersionNameWithOsType(k8sVersion, Windows) + } else if _, ok := svcOptionWindows[majorKey]; ok { + labelMap[svcOptionWindowsKey] = getVersionNameWithOsType(majorKey, Windows) + } + + return labelMap, nil +} + +func getRKEVendorData(templates map[string]map[string]string) map[string]bool { + keys := map[string]bool{} + if templates == nil { + return keys + } + templateData, ok := templates[kdm.TemplateKeys] + if !ok { + return keys + } + for templateKey := range templateData { + keys[templateKey] = true + } + return keys +} + +func getRKEVendorOptions(options map[string]rketypes.KubernetesServicesOptions) map[string]bool { + keys := map[string]bool{} + for k8sVersion := range options { + keys[k8sVersion] = true + } + return keys +} + +func (md *MetadataController) getRKEAddon(name string) (*v3.RkeAddon, error) { + return md.AddonsLister.Get(namespace.GlobalNamespace, name) +} + +func (md *MetadataController) getRKEServiceOption(k8sVersion string, osType OSType) (*v3.RkeK8sServiceOption, error) { + return md.ServiceOptionsLister.Get(namespace.GlobalNamespace, getVersionNameWithOsType(k8sVersion, osType)) +} + +func (md *MetadataController) getRKESystemImage(k8sVersion string) (*v3.RkeK8sSystemImage, error) { + return md.SystemImagesLister.Get(namespace.GlobalNamespace, k8sVersion) +} + +func getVersionNameWithOsType(str string, osType OSType) string { + if osType == Windows { + return getWindowsName(str) + } + return str +} + +func getWindowsName(str string) string { + return fmt.Sprintf("w%s", str) +} + +func (md *MetadataController) updateSettings(maxVersionForMajorK8sVersion map[string]string, rancherVersion string, + K8sVersionServiceOptions map[string]rketypes.KubernetesServicesOptions, DefaultK8sVersions map[string]string, + deprecated map[string]bool) error { + + userSettings, userUpdated, err := md.getUserSettings() + if err != nil { + return err + } + + updateSettings, err := toUpdate(maxVersionForMajorK8sVersion, deprecated, DefaultK8sVersions, rancherVersion, K8sVersionServiceOptions) + if err != nil { + return err + } + + if !userUpdated { + if err := md.updateSettingFromFields(updateSettings, map[string]string{}); err != nil { + return err + } + } else { + userMaxVersionForMajorK8sVersion, userDeprecated, err := getUserSettings(userSettings, DefaultK8sVersions) + if err != nil { + return err + } + + if len(userMaxVersionForMajorK8sVersion) == 0 { + userMaxVersionForMajorK8sVersion = maxVersionForMajorK8sVersion + } + + if len(userDeprecated) == 0 { + userDeprecated = deprecated + } + + userUpdateSettings, err := toUpdate(userMaxVersionForMajorK8sVersion, userDeprecated, DefaultK8sVersions, rancherVersion, K8sVersionServiceOptions) + if err != nil { + return err + } + + if err := md.updateSettingFromFields(userUpdateSettings, userSettings); err != nil { + return err + } + } + + return nil +} + +func (md *MetadataController) getUserSettings() (map[string]string, bool, error) { + userSettings := map[string]string{} + get := func(key string) string { + if setting, ok := userUpdateSettingMap[key]; ok { + return setting.Get() + } + return "" + } + for key := range userUpdateSettingMap { + setting, err := md.SettingLister.Get("", key) + if err != nil { + if !errors.IsNotFound(err) { + return nil, false, fmt.Errorf("driverMetadata: error getting setting %s: %v", key, err) + } + setting, err = md.Settings.Get(key, metav1.GetOptions{}) + if err != nil { + return nil, false, fmt.Errorf("driverMetadata: error getting setting %s: %v", key, err) + } + } + if val, ok := setting.Labels[setting2.UserUpdateLabel]; ok && convert.ToString(val) == "true" { + userSettings[key] = get(key) + } + } + logrus.Debugf("driverMetadata: userSettings %v", userSettings) + if len(userSettings) > 0 { + return userSettings, true, nil + } + return userSettings, false, nil +} + +func toUpdate(maxVersionForMajorK8sVersion map[string]string, deprecated map[string]bool, + defaultK8sVersions map[string]string, rancherVersion string, k8sVersionServiceOptions map[string]rketypes.KubernetesServicesOptions) (map[string]string, error) { + + var k8sVersionsCurrent []string + var maxVersions []string + for k, v := range maxVersionForMajorK8sVersion { + if !deprecated[k] { + k8sVersionsCurrent = append(k8sVersionsCurrent, v) + maxVersions = append(maxVersions, k) + } + } + if len(maxVersions) == 0 { + return nil, fmt.Errorf("driverMetadata: no max version %v", maxVersionForMajorK8sVersion) + } + sort.Strings(k8sVersionsCurrent) + sort.Strings(maxVersions) + + defaultK8sVersion, err := getDefaultK8sVersion(defaultK8sVersions, k8sVersionsCurrent, rancherVersion) + if err != nil { + return nil, err + } + + k8sVersionRKESystemImages := map[string]interface{}{} + k8sVersionSvcOptions := map[string]rketypes.KubernetesServicesOptions{} + + for majorVersion, k8sVersion := range maxVersionForMajorK8sVersion { + if !deprecated[k8sVersion] { + k8sVersionRKESystemImages[k8sVersion] = nil + k8sVersionSvcOptions[k8sVersion] = k8sVersionServiceOptions[majorVersion] + } + } + + k8sCurrRKEdata, err := marshal(k8sVersionRKESystemImages) + if err != nil { + return nil, err + } + + k8sSvcOptionData, err := marshal(k8sVersionSvcOptions) + if err != nil { + return nil, err + } + + deprecatedData, err := marshal(deprecated) + if err != nil { + return nil, err + } + + minVersion := maxVersions[0] + maxVersion := util.GetTagMajorVersion(defaultK8sVersion) + uiSupported := fmt.Sprintf(">=%s.x <=%s.x", minVersion, maxVersion) + uiDefaultRange := fmt.Sprintf("<=%s.x", maxVersion) + + rke2DefaultVersion := channelserver.GetDefaultByRuntimeAndServerVersion(context.TODO(), "rke2", rancherVersion) + k3sDefaultVersion := channelserver.GetDefaultByRuntimeAndServerVersion(context.TODO(), "k3s", rancherVersion) + + return map[string]string{ + settings.KubernetesVersionsCurrent.Name: strings.Join(k8sVersionsCurrent, ","), + settings.KubernetesVersion.Name: defaultK8sVersion, + settings.KubernetesVersionsDeprecated.Name: deprecatedData, + settings.UIKubernetesDefaultVersion.Name: uiDefaultRange, + settings.UIKubernetesSupportedVersions.Name: uiSupported, + settings.KubernetesVersionToSystemImages.Name: k8sCurrRKEdata, + settings.KubernetesVersionToServiceOptions.Name: k8sSvcOptionData, + settings.Rke2DefaultVersion.Name: rke2DefaultVersion, + settings.K3sDefaultVersion.Name: k3sDefaultVersion, + }, nil +} + +func (md *MetadataController) updateSettingFromFields(updateField map[string]string, skip map[string]string) error { + for key, setting := range rancherUpdateSettingMap { + if _, ok := skip[key]; ok { + continue + } + if _, ok := updateField[key]; !ok { + return fmt.Errorf("driverMetadata: updated value not present for setting %s", key) + } + oldVal := setting.Get() + newVal := updateField[key] + if oldVal != newVal { + if err := setting.Set(newVal); err != nil { + return err + } + } + } + return nil +} + +func getUserSettings(userSettings map[string]string, defaultK8sVersions map[string]string) (map[string]string, map[string]bool, error) { + userMaxVersionForMajorK8sVersion := map[string]string{} + if val, ok := userSettings[settings.KubernetesVersionsCurrent.Name]; ok { + versions := strings.Split(val, ",") + for _, version := range versions { + userMaxVersionForMajorK8sVersion[util.GetTagMajorVersion(version)] = version + } + } + + userDeprecated := map[string]bool{} + if val, ok := userSettings[settings.KubernetesVersionsDeprecated.Name]; ok { + deprecatedVersions := make(map[string]bool) + if val != "" { + if err := json.Unmarshal([]byte(val), &deprecatedVersions); err != nil { + return nil, nil, err + } + } + for key, val := range deprecatedVersions { + userDeprecated[key] = val + } + } + + if val, ok := userSettings[settings.KubernetesVersion.Name]; ok { + defaultK8sVersions["user"] = val + } + + return userMaxVersionForMajorK8sVersion, userDeprecated, nil +} + +func getDefaultK8sVersion(rancherDefaultK8sVersions map[string]string, k8sCurrVersions []string, rancherVersion string) (string, error) { + defaultK8sVersion, ok := rancherDefaultK8sVersions["user"] + if ok && defaultK8sVersion != "" { + found := false + for _, k8sVersion := range k8sCurrVersions { + if k8sVersion == defaultK8sVersion { + found = true + break + } + } + if !found { + return "", fmt.Errorf("driverMetadata: unable to find default k8s version in current k8s %s %v", defaultK8sVersion, k8sCurrVersions) + } + return defaultK8sVersion, nil + } + + defaultK8sVersionRange, ok := rancherDefaultK8sVersions[rancherVersion] + if !ok || defaultK8sVersionRange == "" { + defaultK8sVersionRange = rancherDefaultK8sVersions["default"] + } + // get matching default k8s from k8s curr + toMatch := util.GetTagMajorVersion(defaultK8sVersionRange) + + for _, k8sCurr := range k8sCurrVersions { + toTest := util.GetTagMajorVersion(k8sCurr) + if toTest == toMatch { + defaultK8sVersion = k8sCurr + break + } + } + if defaultK8sVersion == "" { + return "", fmt.Errorf("driverMetadata: unable to find default k8s version in current k8s %s %v", defaultK8sVersionRange, k8sCurrVersions) + } + return defaultK8sVersion, nil +} + +func marshal(data interface{}) (string, error) { + b, err := json.Marshal(data) + if err != nil { + return "", err + } + return string(b), nil +} + +func labelEqual(labels map[string]string, exists bool) bool { + toSendValue := "true" + if exists { + toSendValue = "false" + } + if _, ok := labels[sendRKELabel]; !ok { + return toSendValue == "true" + } + return toSendValue == labels[sendRKELabel] +} + +func updateLabel(labels map[string]string, exists bool) map[string]string { + if exists { + if labels == nil { + return map[string]string{ + sendRKELabel: "false", + } + } + labels[sendRKELabel] = "false" + return labels + } + delete(labels, sendRKELabel) + return labels +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data_getter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data_getter.go new file mode 100644 index 0000000..6c64050 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/data_getter.go @@ -0,0 +1,166 @@ +package kontainerdrivermetadata + +import ( + "fmt" + + mVersion "github.com/mcuadros/go-version" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/rke/util" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func GetRKESystemImages(k8sVersion string, sysImageLister v3.RkeK8sSystemImageLister, sysImages v3.RkeK8sSystemImageInterface) (rketypes.RKESystemImages, error) { + name := k8sVersion + sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, name) + if err != nil { + if !errors.IsNotFound(err) { + return rketypes.RKESystemImages{}, err + } + sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{}) + if err != nil { + return rketypes.RKESystemImages{}, err + } + } + return sysImage.SystemImages, err +} + +func GetRKEAddonTemplate(addonName string, addonLister v3.RkeAddonLister, addons v3.RkeAddonInterface) (string, error) { + addon, err := addonLister.Get(namespace.GlobalNamespace, addonName) + if err != nil { + if !errors.IsNotFound(err) { + return "", err + } + addon, err = addons.GetNamespaced(namespace.GlobalNamespace, addonName, metav1.GetOptions{}) + if err != nil { + return "", err + } + } + if addon.Labels[sendRKELabel] == "false" { + return "", nil + } + return addon.Template, err +} + +func getRKEServiceOption(name string, svcOptionLister v3.RkeK8sServiceOptionLister, svcOptions v3.RkeK8sServiceOptionInterface) (*rketypes.KubernetesServicesOptions, error) { + var k8sSvcOption *rketypes.KubernetesServicesOptions + svcOption, err := svcOptionLister.Get(namespace.GlobalNamespace, name) + if err != nil { + if !errors.IsNotFound(err) { + return k8sSvcOption, err + } + svcOption, err = svcOptions.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{}) + if err != nil { + return k8sSvcOption, err + } + } + if svcOption.Labels[sendRKELabel] == "false" { + return k8sSvcOption, nil + } + logrus.Debugf("getRKEServiceOption: sending svcOption %s", name) + return &svcOption.ServiceOptions, nil +} + +func GetRKEK8sServiceOptions(k8sVersion string, svcOptionLister v3.RkeK8sServiceOptionLister, + svcOptions v3.RkeK8sServiceOptionInterface, sysImageLister v3.RkeK8sSystemImageLister, + sysImages v3.RkeK8sSystemImageInterface, osType OSType) (*rketypes.KubernetesServicesOptions, error) { + + var k8sSvcOption *rketypes.KubernetesServicesOptions + sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, k8sVersion) + if err != nil { + if !errors.IsNotFound(err) { + logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err) + return k8sSvcOption, err + } + sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, k8sVersion, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err) + return k8sSvcOption, err + } + } + key := svcOptionLinuxKey + if osType == Windows { + key = svcOptionWindowsKey + } + val, ok := sysImage.Labels[key] + // It's possible that we have a k8s version with no windows svcOptions. In this case, we just warn and return nil. + // if we have in fact windows nodes trying to use that version, the error will show in reknodeconfig server. + if !ok && osType == Windows { + logrus.Debugf("getSvcOptions: no service-option key present for %s", k8sVersion) + return k8sSvcOption, nil + } else if !ok { + return k8sSvcOption, fmt.Errorf("getSvcOptions: no service-option key present for %s", k8sVersion) + } + return getRKEServiceOption(val, svcOptionLister, svcOptions) +} + +func GetK8sVersionInfo( + rancherVersion string, + rkeSysImages map[string]rketypes.RKESystemImages, + linuxSvcOptions map[string]rketypes.KubernetesServicesOptions, + windowsSvcOptions map[string]rketypes.KubernetesServicesOptions, + rancherVersions map[string]rketypes.K8sVersionInfo, +) (linuxInfo, windowsInfo *VersionInfo) { + + linuxInfo = newVersionInfo() + windowsInfo = newVersionInfo() + + maxVersionForMajorK8sVersion := map[string]string{} + for k8sVersion := range rkeSysImages { + if rancherVersionInfo, ok := rancherVersions[k8sVersion]; ok && toIgnoreForAllK8s(rancherVersionInfo, rancherVersion) { + continue + } + majorVersion := util.GetTagMajorVersion(k8sVersion) + if majorVersionInfo, ok := rancherVersions[majorVersion]; ok && toIgnoreForK8sCurrent(majorVersionInfo, rancherVersion) { + continue + } + if curr, ok := maxVersionForMajorK8sVersion[majorVersion]; !ok || mVersion.Compare(k8sVersion, curr, ">") { + maxVersionForMajorK8sVersion[majorVersion] = k8sVersion + } + } + for majorVersion, k8sVersion := range maxVersionForMajorK8sVersion { + sysImgs, exist := rkeSysImages[k8sVersion] + if !exist { + continue + } + // windows has been supported since v1.14, + // the following logic would not find `< v1.14` service options + if svcOptions, exist := windowsSvcOptions[majorVersion]; exist { + // only keep the related images for windows + windowsSysImgs := rketypes.RKESystemImages{ + NginxProxy: sysImgs.NginxProxy, + CertDownloader: sysImgs.CertDownloader, + KubernetesServicesSidecar: sysImgs.KubernetesServicesSidecar, + Kubernetes: sysImgs.Kubernetes, + WindowsPodInfraContainer: sysImgs.WindowsPodInfraContainer, + } + + windowsInfo.RKESystemImages[k8sVersion] = windowsSysImgs + windowsInfo.KubernetesServicesOptions[k8sVersion] = svcOptions + } + if svcOptions, exist := linuxSvcOptions[majorVersion]; exist { + // clean the unrelated images for linux + sysImgs.WindowsPodInfraContainer = "" + + linuxInfo.RKESystemImages[k8sVersion] = sysImgs + linuxInfo.KubernetesServicesOptions[k8sVersion] = svcOptions + } + } + + return linuxInfo, windowsInfo +} + +type VersionInfo struct { + RKESystemImages map[string]rketypes.RKESystemImages + KubernetesServicesOptions map[string]rketypes.KubernetesServicesOptions +} + +func newVersionInfo() *VersionInfo { + return &VersionInfo{ + RKESystemImages: map[string]rketypes.RKESystemImages{}, + KubernetesServicesOptions: map[string]rketypes.KubernetesServicesOptions{}, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/metadata_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/metadata_handler.go new file mode 100644 index 0000000..58b8b1b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/metadata_handler.go @@ -0,0 +1,157 @@ +package kontainerdrivermetadata + +import ( + "context" + "fmt" + "net/http" + "path/filepath" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/channelserver" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +type MetadataController struct { + NamespacesLister v1.NamespaceLister + SystemImagesLister v3.RkeK8sSystemImageLister + SystemImages v3.RkeK8sSystemImageInterface + ServiceOptionsLister v3.RkeK8sServiceOptionLister + ServiceOptions v3.RkeK8sServiceOptionInterface + AddonsLister v3.RkeAddonLister + Addons v3.RkeAddonInterface + SettingLister v3.SettingLister + Settings v3.SettingInterface + url *MetadataURL +} + +type MetadataURL struct { + //http path + path string + // branch set if .git path by user + branch string + // latestHash, isGit set in parseURL + latestHash string + isGit bool +} + +const ( + rkeMetadataConfig = "rke-metadata-config" + refreshInterval = "refresh-interval-minutes" + fileLoc = "data/data.json" +) + +var ( + httpClient = &http.Client{ + Timeout: time.Second * 30, + } + dataPath = filepath.Join("./management-state", "driver-metadata", "rke") + prevHash string + fileMapLock = sync.Mutex{} + fileMapData = map[string]bool{} +) + +func Register(ctx context.Context, management *config.ManagementContext) { + mgmt := management.Management + + m := &MetadataController{ + SystemImagesLister: mgmt.RkeK8sSystemImages("").Controller().Lister(), + SystemImages: mgmt.RkeK8sSystemImages(""), + ServiceOptionsLister: mgmt.RkeK8sServiceOptions("").Controller().Lister(), + ServiceOptions: mgmt.RkeK8sServiceOptions(""), + NamespacesLister: management.Core.Namespaces("").Controller().Lister(), + AddonsLister: mgmt.RkeAddons("").Controller().Lister(), + Addons: mgmt.RkeAddons(""), + SettingLister: mgmt.Settings("").Controller().Lister(), + Settings: mgmt.Settings(""), + } + + mgmt.Settings("").AddHandler(ctx, "rke-metadata-handler", m.sync) + mgmt.Settings("").Controller().Enqueue("", rkeMetadataConfig) +} + +func (m *MetadataController) sync(key string, setting *v3.Setting) (runtime.Object, error) { + if setting == nil || (setting.Name != rkeMetadataConfig) { + return nil, nil + } + + if _, err := m.NamespacesLister.Get("", namespace.GlobalNamespace); err != nil { + return nil, fmt.Errorf("failed to get %s namespace", namespace.GlobalNamespace) + } + + value := setting.Value + if value == "" { + value = setting.Default + } + settingValues, err := getSettingValues(value) + if err != nil { + return nil, fmt.Errorf("error getting setting values: %v", err) + } + + metadata, err := parseURL(settingValues) + if err != nil { + return nil, err + } + m.url = metadata + + interval, err := convert.ToNumber(settingValues[refreshInterval]) + if err != nil { + return nil, fmt.Errorf("invalid number %v", interval) + } + + if interval > 0 { + logrus.Infof("Refreshing driverMetadata in %v minutes", interval) + m.Settings.Controller().EnqueueAfter(setting.Namespace, setting.Name, time.Minute*time.Duration(interval)) + } + + // refresh to sync k3s/rke2 releases + channelserver.Refresh() + return setting, m.refresh() +} + +func (m *MetadataController) refresh() error { + if !toSync(m.url) { + logrus.Infof("driverMetadata: skip sync, hash up to date %v", m.url.latestHash) + return nil + } + if !storeMap(m.url) { + logrus.Infof("driverMetadata: already in progress") + return nil + } + defer deleteMap(m.url) + if err := m.Refresh(m.url); err != nil { + logrus.Warnf("%v, Fallback to refresh from local file path %v", err, DataJSONLocation) + return errors.Wrapf(m.createOrUpdateMetadataFromLocal(), "failed to refresh from local file path: %s", DataJSONLocation) + } + setFinalPath(m.url) + return nil +} + +func (m *MetadataController) Refresh(url *MetadataURL) error { + data, err := loadData(url) + if err != nil { + return errors.Wrapf(err, "failed to refresh data from upstream %v", url.path) + } + logrus.Infof("driverMetadata: refreshing data from upstream %v", url.path) + return errors.Wrap(m.createOrUpdateMetadata(data), "failed to create or update driverMetadata") +} + +func GetURLSettingValue() (*MetadataURL, error) { + settingValues, err := getSettingValues(settings.RkeMetadataConfig.Get()) + if err != nil { + return nil, err + } + url, err := parseURL(settingValues) + if err != nil { + return nil, fmt.Errorf("error parsing url %v %v", url, err) + } + return url, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/url.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/url.go new file mode 100644 index 0000000..aba3600 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/kontainerdrivermetadata/url.go @@ -0,0 +1,156 @@ +package kontainerdrivermetadata + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/git" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rke/types/kdm" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" +) + +func parseURL(rkeData map[string]interface{}) (*MetadataURL, error) { + url := &MetadataURL{} + path, ok := rkeData["url"] + if !ok { + return nil, fmt.Errorf("url not present in settings %s", settings.RkeMetadataConfig.Get()) + } + url.path = convert.ToString(path) + branch, ok := rkeData["branch"] + if !ok { + return url, nil + } + url.branch = convert.ToString(branch) + latestHash, err := git.RemoteBranchHeadCommit(url.path, url.branch) + if err != nil { + return nil, fmt.Errorf("error getting latest commit %s %s %v", url.path, url.branch, err) + } + url.latestHash = latestHash + if strings.HasSuffix(url.path, ".git") { + url.isGit = true + } + return url, nil +} + +func loadData(url *MetadataURL) (kdm.Data, error) { + if url.isGit { + return getDataGit(url.path, url.branch) + } + return getDataHTTP(url.path) +} + +func getDataHTTP(url string) (kdm.Data, error) { + var data kdm.Data + resp, err := httpClient.Get(url) + if err != nil { + return data, fmt.Errorf("driverMetadata err %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return data, fmt.Errorf("driverMetadata statusCode %v", resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return data, fmt.Errorf("driverMetadata read response body error %v", err) + } + + if err := json.Unmarshal(body, &data); err != nil { + return data, fmt.Errorf("driverMetadata %v", err) + } + return data, nil +} + +func getDataGit(urlPath, branch string) (kdm.Data, error) { + var data kdm.Data + + if _, err := os.Stat(dataPath); os.IsNotExist(err) { + if err := os.MkdirAll(dataPath, 0755); err != nil { + return data, fmt.Errorf("error creating directory %v", err) + } + } + + name, err := randomtoken.Generate() + if err != nil { + return data, fmt.Errorf("error generating metadata dirName %v", err) + } + + path := fmt.Sprintf("%s/%s", dataPath, fmt.Sprintf("data-%s", name)) + if err := git.CloneWithDepth(path, urlPath, branch, 1); err != nil { + return data, fmt.Errorf("error cloning repo %s %s: %v", urlPath, branch, err) + } + + filePath := fmt.Sprintf("%s/%s", path, fileLoc) + file, err := os.Open(filePath) + if err != nil { + return data, fmt.Errorf("error opening file %s %v", filePath, err) + } + defer file.Close() + + buf, err := ioutil.ReadAll(file) + if err != nil { + return data, fmt.Errorf("error reading file %s %v", filePath, err) + } + + if err := json.Unmarshal(buf, &data); err != nil { + return data, fmt.Errorf("error unmarshaling metadata contents %v", err) + } + + if err := os.RemoveAll(path); err != nil { + logrus.Errorf("error removing metadata path %s %v", path, err) + } + return data, nil +} + +func getSettingValues(value string) (map[string]interface{}, error) { + urlData := map[string]interface{}{} + if err := json.Unmarshal([]byte(value), &urlData); err != nil { + return nil, fmt.Errorf("unmarshal err %v", err) + } + return urlData, nil +} + +func setFinalPath(url *MetadataURL) { + if url.isGit { + prevHash = url.latestHash + } +} + +func toSync(url *MetadataURL) bool { + // check if hash changed for Git, can't do much for normal url + if url.isGit { + return prevHash != url.latestHash + } + return true +} + +func deleteMap(url *MetadataURL) { + key := getKey(url) + fileMapLock.Lock() + delete(fileMapData, key) + fileMapLock.Unlock() +} + +func storeMap(url *MetadataURL) bool { + key := getKey(url) + fileMapLock.Lock() + defer fileMapLock.Unlock() + if _, ok := fileMapData[key]; ok { + return false + } + fileMapData[key] = true + return true +} + +func getKey(url *MetadataURL) string { + if url.isGit { + return url.latestHash + } + return url.path +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup.go new file mode 100644 index 0000000..2fc9ba4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup.go @@ -0,0 +1,441 @@ +package node + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + "github.com/rancher/rancher/pkg/agent/clean" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + util "github.com/rancher/rancher/pkg/cluster" + "github.com/rancher/rancher/pkg/dialer" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/kubectl" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemtemplate" + "github.com/rancher/rancher/pkg/types/config" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + kerror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + cleanupPodLabel = "rke.cattle.io/cleanup-node" + userNodeRemoveAnnotationPrefix = "lifecycle.cattle.io/create.user-node-remove_" + userNodeRemoveCleanupAnnotationOld = "nodes.management.cattle.io/user-node-remove-cleanup" +) + +func (m *Lifecycle) deleteV1Node(node *v3.Node) (runtime.Object, error) { + logrus.Debugf("[node-cleanup] Deleting v1.node for [%v] node", node.Status.NodeName) + if nodehelper.IgnoreNode(node.Status.NodeName, node.Status.NodeLabels) { + logrus.Debugf("[node-cleanup] Skipping v1.node removal for [%v] node", node.Status.NodeName) + return node, nil + } + + if node.Status.NodeName == "" { + logrus.Debugf("[node-cleanup] Skipping v1.node removal for machine [%v] without node name", node.Name) + return node, nil + } + + cluster, err := m.clusterLister.Get("", node.Namespace) + if err != nil { + if kerror.IsNotFound(err) { + logrus.Debugf("[node-cleanup] Skipping v1.node removal for machine [%v] without cluster [%v]", node.Name, node.Namespace) + return node, nil + } + return node, err + } + userClient, err := m.clusterManager.UserContextFromCluster(cluster) + if err != nil { + return node, err + } + if userClient == nil { + logrus.Debugf("[node-cleanup] cluster is already deleted, cannot delete RKE node") + return node, nil + } + + ctx, cancel := context.WithTimeout(context.TODO(), 45*time.Second) + defer cancel() + err = userClient.K8sClient.CoreV1().Nodes().Delete( + ctx, node.Status.NodeName, metav1.DeleteOptions{}) + if err != nil && !kerror.IsNotFound(err) && + ctx.Err() != context.DeadlineExceeded && + !strings.Contains(err.Error(), dialer.ErrAgentDisconnected.Error()) && + !strings.Contains(err.Error(), "connection refused") { + return node, err + } + + return node, nil +} + +func (m *Lifecycle) drainNode(node *v3.Node) error { + nodeCopy := node.DeepCopy() // copy for cache protection as we do no updating but need things set for the drain + cluster, err := m.clusterLister.Get("", nodeCopy.Namespace) + if err != nil { + if kerror.IsNotFound(err) { + return nil + } + return err + } + + nodePool, err := m.getNodePool(node.Spec.NodePoolName) + if err != nil && !kerror.IsNotFound(err) { + return err + } + + if !nodehelper.DrainBeforeDelete(nodeCopy, cluster, nodePool) { + return nil + } + + logrus.Infof("[node-cleanup] node [%s] requires draining before delete", nodeCopy.Spec.RequestedHostname) + kubeConfig, _, err := m.getKubeConfig(cluster) + if err != nil { + return fmt.Errorf("node [%s] error getting kubeConfig", nodeCopy.Spec.RequestedHostname) + } + + if nodeCopy.Spec.NodeDrainInput == nil { + logrus.Debugf("[node-cleanup] node [%s] has no NodeDrainInput, creating one with 60s timeout", + nodeCopy.Spec.RequestedHostname) + nodeCopy.Spec.NodeDrainInput = &rketypes.NodeDrainInput{ + Force: true, + DeleteLocalData: true, + GracePeriod: 60, + Timeout: 60, + } + } + + backoff := wait.Backoff{ + Duration: 2 * time.Second, + Factor: 1, + Jitter: 0, + Steps: 3, + } + + logrus.Infof("[node-cleanup] node [%s] attempting to drain, retrying up to 3 times", nodeCopy.Spec.RequestedHostname) + // purposefully ignoring kubectl.drain error. However, if the node fails to drain after 3 attempts + // wait.ExponentialBackoff will still return a wait.ErrWaitTimeout error, which must also be ignored. + // Otherwise, the node will not actually delete and resources will be orphaned in the provider. + _ = wait.ExponentialBackoff(backoff, func() (bool, error) { + ctx, cancel := context.WithTimeout(m.ctx, time.Duration(nodeCopy.Spec.NodeDrainInput.Timeout)*time.Second) + defer cancel() + + _, msg, err := kubectl.Drain(ctx, kubeConfig, nodeCopy.Status.NodeName, nodehelper.GetDrainFlags(nodeCopy)) + if ctx.Err() != nil { + logrus.Errorf("[node-cleanup] node [%s] kubectl drain failed, retrying: %s", nodeCopy.Spec.RequestedHostname, ctx.Err()) + return false, nil + } + if err != nil { + logrus.Errorf("[node-cleanup] node [%s] kubectl drain error, retrying: %s", nodeCopy.Spec.RequestedHostname, err) + return false, nil + } + + logrus.Infof("[node-cleanup] node [%s] kubectl drain response: %s", nodeCopy.Spec.RequestedHostname, msg) + return true, nil + }) + return nil // always return nil so the node is deleted regardless of drain outcome +} + +func (m *Lifecycle) cleanRKENode(node *v3.Node) error { + if !features.RKE1CustomNodeCleanup.Enabled() { + return nil + } + + cluster, err := m.clusterLister.Get("", node.Namespace) + if err != nil { + if kerror.IsNotFound(err) { + return nil // no cluster, we'll never figure out if this is an RKE1 cluster + } + return err + } + + if cluster.Status.Driver != v3.ClusterDriverRKE { + return nil // not an rke node, bail out + } + + userContext, err := m.clusterManager.UserContextFromCluster(cluster) + if err != nil { + return err + } + if userContext == nil { + logrus.Debugf("[node-cleanup] cluster is already deleted, cannot clean RKE node") + return nil + } + + job, err := m.createCleanupJob(userContext, cluster, node) + if err != nil { + return err + } + + if err = m.waitUntilJobCompletes(userContext, job); err != nil && !errors.Is(err, wait.ErrWaitTimeout) { + return err + } + + return m.waitUntilJobDeletes(userContext, node.Name, job) +} + +func (m *Lifecycle) waitForJobCondition(userContext *config.UserContext, job *batchv1.Job, condition func(*batchv1.Job, error) bool, logMessage string) error { + if job == nil { + return nil + } + backoff := wait.Backoff{ + Duration: 3 * time.Second, + Factor: 1, + Jitter: 0, + Steps: 10, + } + + logrus.Infof("[node-cleanup] validating cleanup job %s %sd, retrying up to 10 times", job.Name, logMessage) + // purposefully ignoring error, if the drain fails this falls back to deleting the node as usual + return wait.ExponentialBackoff(backoff, func() (bool, error) { + ctx, cancel := context.WithTimeout(m.ctx, backoff.Duration) + defer cancel() + + j, err := userContext.K8sClient.BatchV1().Jobs(job.Namespace).Get(ctx, job.Name, metav1.GetOptions{}) + if ctx.Err() != nil { + logrus.Errorf("[node-cleanup] context failed while retrieving job %s, retrying: %s", job.Name, ctx.Err()) + return false, nil + } + if err != nil { + // kubectl failed continue on with delete any way + logrus.Errorf("[node-cleanup] failed to get job %s, retrying: %v", job.Name, err) + } + + if !condition(j, err) { + logrus.Infof("[node-cleanup] waiting for %s job to %s", job.Name, logMessage) + return false, nil + } + + logrus.Infof("[node-cleanup] finished waiting for job %s to %s", job.Name, logMessage) + return true, nil + }) +} + +func (m *Lifecycle) waitUntilJobCompletes(userContext *config.UserContext, job *batchv1.Job) error { + return m.waitForJobCondition( + userContext, + job, + func(j *batchv1.Job, err error) bool { return err == nil && j.Status.Succeeded > 0 }, + "complete", + ) +} + +func (m *Lifecycle) waitUntilJobDeletes(userContext *config.UserContext, nodeName string, job *batchv1.Job) error { + return m.waitForJobCondition(userContext, job, func(j *batchv1.Job, err error) bool { + if err == nil { + if j.DeletionTimestamp.IsZero() { + err = userContext.BatchV1.Jobs(j.Namespace).Delete(j.Name, &metav1.DeleteOptions{PropagationPolicy: &[]metav1.DeletionPropagation{metav1.DeletePropagationForeground}[0]}) + } else if pods, err := userContext.Core.Pods(j.Namespace).List(metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", cleanupPodLabel, nodeName)}); err != nil && !kerror.IsNotFound(err) { + logrus.Errorf("[node-cleanup] failed to list cleanup pods for node %s: %v", nodeName, err) + return false + } else if err == nil && len(pods.Items) > 0 { + if err = userContext.Core.Pods(j.Namespace).Delete(pods.Items[0].Name, &metav1.DeleteOptions{GracePeriodSeconds: &[]int64{0}[0]}); err != nil { + logrus.Errorf("[node-cleanup] failed to delete cleanup pod %s for node %s: %v", pods.Items[0].Name, nodeName, err) + return false + } + } + } + return kerror.IsNotFound(err) + }, + "delete") +} + +func (m *Lifecycle) createCleanupJob(userContext *config.UserContext, cluster *v3.Cluster, node *v3.Node) (*batchv1.Job, error) { + nodeLabel := "cattle.io/node" + + // find if someone else already kicked this job off + existingJob, err := userContext.K8sClient.BatchV1().Jobs("default").List(m.ctx, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", nodeLabel, node.Name), + }) + if err != nil && !kerror.IsNotFound(err) { + if strings.Contains(err.Error(), dialer.ErrAgentDisconnected.Error()) || + strings.Contains(err.Error(), "connection refused") { + return nil, nil // can't connect, just continue on with deleting v3 node + } + return nil, err + } + + if len(existingJob.Items) != 0 { + if existingJob.Items[0].DeletionTimestamp.IsZero() { + // found an existing job that isn't deleting, so assuming another run of the controller is working on it. + // Return an "already exists" error. + return nil, &kerror.StatusError{ + ErrStatus: metav1.Status{ + Reason: metav1.StatusReasonAlreadyExists, + Message: fmt.Sprintf("job already exists for %s/%s", node.Namespace, node.Name), + }, + } + } + + return nil, m.waitUntilJobDeletes(userContext, node.Name, &existingJob.Items[0]) + } + + meta := metav1.ObjectMeta{ + GenerateName: "cattle-node-cleanup-", + Namespace: "default", + Labels: map[string]string{ + "cattle.io/creator": "norman", + nodeLabel: node.Name, + }, + } + + var tolerations []corev1.Toleration + + for _, taint := range node.Spec.InternalNodeSpec.Taints { + tolerations = append(tolerations, corev1.Toleration{ + Effect: taint.Effect, + Key: taint.Key, + Operator: "Exists", + }) + } + + var mounts []corev1.VolumeMount + var volumes []corev1.Volume + + if os, ok := node.Status.NodeLabels["kubernetes.io/os"]; ok && os == "windows" { + t := corev1.HostPathType("") + volumes = append(volumes, corev1.Volume{ + Name: "docker", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "\\\\.\\pipe\\docker_engine", + Type: &t, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + MountPath: "\\\\.\\pipe\\docker_engine", + Name: "docker", + }) + } else { + socket := corev1.HostPathType("Socket") + volumes = append(volumes, corev1.Volume{ + Name: "docker", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "/var/run/docker.sock", + Type: &socket, + }, + }, + }) + mounts = append(mounts, corev1.VolumeMount{ + MountPath: "/var/run/docker.sock", + Name: "docker", + }) + } + + env := []corev1.EnvVar{ + { + Name: "AGENT_IMAGE", + Value: settings.AgentImage.Get(), + }, + } + + if cluster.Spec.RancherKubernetesEngineConfig != nil { + env = append(env, + corev1.EnvVar{ + Name: "PREFIX_PATH", + Value: cluster.Spec.RancherKubernetesEngineConfig.PrefixPath, + }, + corev1.EnvVar{ + Name: "WINDOWS_PREFIX_PATH", + Value: cluster.Spec.RancherKubernetesEngineConfig.WindowsPrefixPath, + }, + ) + } + + var imagePullSecrets []corev1.LocalObjectReference + // We don't need the value of these secrets, however their existence means there should be a secret to add to the list + // of imagePullSecrets + if cluster.GetSecret(v3.ClusterPrivateRegistrySecret) != "" || cluster.Spec.ClusterSecrets.PrivateRegistryECRSecret != "" { + if url, _, err := util.GeneratePrivateRegistryEncodedDockerConfig(cluster, m.secretLister); err != nil { + return nil, err + } else if url != "" { + imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{Name: "cattle-private-registry"}) + } + } + + fiveMin := int32(5 * 60) + job := batchv1.Job{ + ObjectMeta: meta, + Spec: batchv1.JobSpec{ + TTLSecondsAfterFinished: &fiveMin, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + cleanupPodLabel: node.Name, + }, + }, + Spec: corev1.PodSpec{ + ImagePullSecrets: imagePullSecrets, + RestartPolicy: "Never", + NodeSelector: map[string]string{ + "kubernetes.io/hostname": node.Status.NodeName, + }, + Tolerations: tolerations, + Volumes: volumes, + Containers: []corev1.Container{ + { + Name: clean.NodeCleanupContainerName, + Image: systemtemplate.GetDesiredAgentImage(cluster), + Args: []string{"--", "agent", "clean", "job"}, + Env: env, + VolumeMounts: mounts, + ImagePullPolicy: corev1.PullIfNotPresent, + }, + }, + }, + }, + }, + } + + return userContext.K8sClient.BatchV1().Jobs("default").Create(context.TODO(), &job, metav1.CreateOptions{}) +} + +func (m *Lifecycle) userNodeRemoveCleanup(obj *v3.Node) *v3.Node { + obj = obj.DeepCopy() + obj.SetFinalizers(removeFinalizerWithPrefix(obj.GetFinalizers(), userNodeRemoveFinalizerPrefix)) + + if obj.DeletionTimestamp == nil { + annos := obj.GetAnnotations() + if annos == nil { + annos = make(map[string]string) + } else { + annos = removeAnnotationWithPrefix(annos, userNodeRemoveAnnotationPrefix) + delete(annos, userNodeRemoveCleanupAnnotationOld) + } + + annos[userNodeRemoveCleanupAnnotation] = "true" + obj.SetAnnotations(annos) + } + return obj +} + +func removeFinalizerWithPrefix(finalizers []string, prefix string) []string { + var nf []string + for _, finalizer := range finalizers { + if strings.HasPrefix(finalizer, prefix) { + logrus.Debugf("[node-cleanup] finalizer with prefix [%s] will be removed", prefix) + continue + } + nf = append(nf, finalizer) + } + return nf +} + +func removeAnnotationWithPrefix(annotations map[string]string, prefix string) map[string]string { + for k := range annotations { + if strings.HasPrefix(k, prefix) { + logrus.Debugf("[node-cleanup] annotation with prefix [%s] will be removed", prefix) + delete(annotations, k) + } + } + return annotations +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup_test.go new file mode 100644 index 0000000..d2a999a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/cleanup_test.go @@ -0,0 +1,101 @@ +package node + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRemoveFinalizers(t *testing.T) { + tests := []struct { + name string + prefix string + input []string + expected []string + }{ + { + name: "empty input", + prefix: "test_prefix", + input: []string{}, + expected: nil, + }, + { + name: "nil input", + prefix: "test_prefix", + input: nil, + expected: nil, + }, + { + name: "empty prefix", + prefix: "", + input: []string{"testing.cattle.io/a_test"}, + expected: nil, + }, + { + name: "match", + prefix: "testing.cattle.io/a_", + input: []string{"testing.cattle.io/a_test"}, + expected: nil, + }, + { + name: "no match", + prefix: "testing.cattle.io/b_", + input: []string{"testing.cattle.io/a_test"}, + expected: []string{"testing.cattle.io/a_test"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := assert.New(t) + actual := removeFinalizerWithPrefix(tt.input, tt.prefix) + a.Equal(tt.expected, actual) + }) + } +} + +func TestRemoveAnnotations(t *testing.T) { + tests := []struct { + name string + prefix string + input map[string]string + expected map[string]string + }{ + { + name: "empty input", + prefix: "test_prefix", + input: map[string]string{}, + expected: map[string]string{}, + }, + { + name: "nil input", + prefix: "test_prefix", + input: nil, + expected: nil, + }, + { + name: "empty prefix", + prefix: "", + input: map[string]string{"testing.cattle.io/a_test": "true"}, + expected: map[string]string{}, + }, + { + name: "match", + prefix: "testing.cattle.io/a_", + input: map[string]string{"testing.cattle.io/a_test": "true"}, + expected: map[string]string{}, + }, + { + name: "no match", + prefix: "testing.cattle.io/b_", + input: map[string]string{"testing.cattle.io/a_test": "true"}, + expected: map[string]string{"testing.cattle.io/a_test": "true"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := assert.New(t) + actual := removeAnnotationWithPrefix(tt.input, tt.prefix) + a.Equal(tt.expected, actual) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller.go new file mode 100644 index 0000000..4300db6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller.go @@ -0,0 +1,824 @@ +package node + +import ( + "context" + "crypto/sha256" + "encoding/base32" + "encoding/json" + "fmt" + "os" + "path" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + util "github.com/rancher/rancher/pkg/cluster" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterregistrationtoken" + "github.com/rancher/rancher/pkg/controllers/management/drivers/nodedriver" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + "github.com/rancher/rancher/pkg/encryptedstore" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/jailer" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/nodeconfig" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/taints" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/rancher/pkg/user" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" + v1 "k8s.io/api/core/v1" + kerror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + typedv1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +const ( + amazonec2 = "amazonec2" + userNodeRemoveCleanupAnnotation = "cleanup.cattle.io/user-node-remove" + userNodeRemoveFinalizerPrefix = "clusterscoped.controller.cattle.io/user-node-remove_" +) + +// SchemaToDriverFields maps Schema field => driver field +// The opposite of this lives in pkg/controllers/management/drivers/nodedriver/machine_driver.go +var SchemaToDriverFields = map[string]map[string]string{ + "aliyunecs": {"sshKeyContents": "sshKeypath"}, + "amazonec2": {"sshKeyContents": "sshKeypath", "userdata": "userdata"}, + "azure": {"customData": "customData"}, + "digitalocean": {"sshKeyContents": "sshKeyPath", "userdata": "userdata"}, + "exoscale": {"sshKey": "sshKey", "userdata": "userdata"}, + "openstack": {"cacert": "cacert", "privateKeyFile": "privateKeyFile", "userDataFile": "userDataFile"}, + "otc": {"privateKeyFile": "privateKeyFile"}, + "packet": {"userdata": "userdata"}, + "pod": {"userdata": "userdata"}, + "vmwarevsphere": {"cloudConfig": "cloud-config"}, + "google": {"authEncodedJson": "authEncodedJson"}, +} + +func Register(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + secretStore, err := nodeconfig.NewStore(management.Core.Namespaces(""), management.Core) + if err != nil { + logrus.Fatal(err) + } + + nodeClient := management.Management.Nodes("") + + nodeLifecycle := &Lifecycle{ + ctx: ctx, + systemAccountManager: systemaccount.NewManager(management), + secretStore: secretStore, + nodeClient: nodeClient, + nodeTemplateClient: management.Management.NodeTemplates(""), + nodePoolLister: management.Management.NodePools("").Controller().Lister(), + nodePoolController: management.Management.NodePools("").Controller(), + nodeTemplateGenericClient: management.Management.NodeTemplates("").ObjectClient().UnstructuredClient(), + configMapGetter: management.K8sClient.CoreV1(), + clusterLister: management.Management.Clusters("").Controller().Lister(), + schemaLister: management.Management.DynamicSchemas("").Controller().Lister(), + secretLister: management.Core.Secrets("").Controller().Lister(), + userManager: management.UserManager, + systemTokens: management.SystemTokens, + clusterManager: clusterManager, + devMode: os.Getenv("CATTLE_DEV_MODE") != "", + } + + nodeClient.AddLifecycle(ctx, "node-controller", nodeLifecycle) + nodeClient.AddHandler(ctx, "node-controller-sync", nodeLifecycle.sync) +} + +type Lifecycle struct { + ctx context.Context + systemAccountManager *systemaccount.Manager + secretStore *encryptedstore.GenericEncryptedStore + nodeTemplateGenericClient objectclient.GenericClient + nodeClient v3.NodeInterface + nodeTemplateClient v3.NodeTemplateInterface + nodePoolLister v3.NodePoolLister + nodePoolController v3.NodePoolController + configMapGetter typedv1.ConfigMapsGetter + clusterLister v3.ClusterLister + schemaLister v3.DynamicSchemaLister + secretLister corev1.SecretLister + userManager user.Manager + systemTokens systemtokens.Interface + clusterManager *clustermanager.Manager + devMode bool +} + +func (m *Lifecycle) setupCustom(obj *apimgmtv3.Node) { + obj.Status.NodeConfig = &rketypes.RKEConfigNode{ + NodeName: obj.Namespace + ":" + obj.Name, + HostnameOverride: obj.Spec.RequestedHostname, + Address: obj.Spec.CustomConfig.Address, + InternalAddress: obj.Spec.CustomConfig.InternalAddress, + User: obj.Spec.CustomConfig.User, + DockerSocket: obj.Spec.CustomConfig.DockerSocket, + SSHKey: obj.Spec.CustomConfig.SSHKey, + Labels: obj.Spec.CustomConfig.Label, + Port: "22", + Role: roles(obj), + Taints: taints.GetRKETaintsFromStrings(obj.Spec.CustomConfig.Taints), + } + + if obj.Status.NodeConfig.User == "" { + obj.Status.NodeConfig.User = "root" + } + + obj.Status.InternalNodeStatus.Addresses = []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: obj.Status.NodeConfig.Address, + }, + } +} + +func isCustom(obj *apimgmtv3.Node) bool { + return obj.Spec.CustomConfig != nil && obj.Spec.CustomConfig.Address != "" +} + +func (m *Lifecycle) setWaiting(node *apimgmtv3.Node) { + apimgmtv3.NodeConditionRegistered.IsUnknown(node) + apimgmtv3.NodeConditionRegistered.Message(node, "waiting to register with Kubernetes") +} + +func (m *Lifecycle) Create(obj *apimgmtv3.Node) (runtime.Object, error) { + if isCustom(obj) { + m.setupCustom(obj) + newObj, err := apimgmtv3.NodeConditionInitialized.Once(obj, func() (runtime.Object, error) { + if err := validateCustomHost(obj); err != nil { + return obj, err + } + m.setWaiting(obj) + return obj, nil + }) + return newObj.(*apimgmtv3.Node), err + } + + if obj.Spec.NodeTemplateName == "" { + return obj, nil + } + + newObj, err := apimgmtv3.NodeConditionInitialized.Once(obj, func() (runtime.Object, error) { + logrus.Debugf("[node-controller] Called apimgmtv3.NodeConditionInitialized.Once for [%s] in namespace [%s]", obj.Name, obj.Namespace) + // Ensure jail is created first, else the function `NewNodeConfig` will create the full jail path (including parent jail directory) and CreateJail will remove the directory as it does not contain a done file + if !m.devMode { + err := jailer.CreateJail(obj.Namespace) + if err != nil { + return nil, errors.WithMessage(err, "node create jail error") + } + } + + nodeConfig, err := nodeconfig.NewNodeConfig(m.secretStore, obj) + if err != nil { + return obj, errors.WithMessagef(err, "failed to create node driver config for node [%v]", obj.Name) + } + + defer nodeConfig.Cleanup() + + err = m.refreshNodeConfig(nodeConfig, obj) + if err != nil { + return nil, errors.WithMessagef(err, "unable to create config for node %v", obj.Name) + } + + template, err := m.getNodeTemplate(obj.Spec.NodeTemplateName) + if err != nil { + return obj, err + } + obj.Status.NodeTemplateSpec = &template.Spec + if obj.Spec.RequestedHostname == "" { + obj.Spec.RequestedHostname = obj.Name + } + + if obj.Status.NodeTemplateSpec.EngineInstallURL == "" { + obj.Status.NodeTemplateSpec.EngineInstallURL = settings.EngineInstallURL.Get() + } + + return obj, nil + }) + + return newObj.(*apimgmtv3.Node), err +} + +func (m *Lifecycle) getNodeTemplate(nodeTemplateName string) (*apimgmtv3.NodeTemplate, error) { + ns, n := ref.Parse(nodeTemplateName) + logrus.Debugf("[node-controller] getNodeTemplate parsed [%s] to ns: [%s] and n: [%s]", nodeTemplateName, ns, n) + return m.nodeTemplateClient.GetNamespaced(ns, n, metav1.GetOptions{}) +} + +func (m *Lifecycle) getNodePool(nodePoolName string) (*apimgmtv3.NodePool, error) { + ns, p := ref.Parse(nodePoolName) + return m.nodePoolLister.Get(ns, p) +} + +func (m *Lifecycle) Remove(machine *apimgmtv3.Node) (obj runtime.Object, err error) { + machine = m.userNodeRemoveCleanup(machine) + + if machine.Status.NodeTemplateSpec == nil { + if err = m.cleanRKENode(machine); err != nil { + return machine, err + } + + return m.deleteV1Node(machine) + } + + obj, err = apimgmtv3.NodeConditionRemoved.DoUntilTrue(machine, func() (runtime.Object, error) { + found, err := m.isNodeInAppliedSpec(machine) + if err != nil { + return machine, err + } + if found { + return machine, errors.New("waiting for node to be removed from cluster") + } + + if !m.devMode { + err = jailer.CreateJail(machine.Namespace) + if err != nil { + return nil, errors.WithMessage(err, "node remove jail error") + } + } + + config, err := nodeconfig.NewNodeConfig(m.secretStore, machine) + if err != nil { + return machine, err + } + + if err = config.Restore(); err != nil { + return machine, err + } + + defer config.Remove() + + err = m.refreshNodeConfig(config, machine) + if err != nil { + return nil, errors.WithMessagef(err, "unable to refresh config for node %v", machine.Name) + } + + exists, err := nodeExists(config.Dir(), machine) + if err != nil { + return machine, err + } + + if exists { + logrus.Infof("[node-controller] Removing node %s", machine.Spec.RequestedHostname) + if err = m.drainNode(machine); err != nil { + return machine, err + } + + driverConfig, err := config.DriverConfig() + if err != nil { + return nil, err + } + + configRawMap := map[string]any{} + if err := json.Unmarshal([]byte(driverConfig), &configRawMap); err != nil { + return obj, errors.Wrap(err, "failed to unmarshal node config") + } + + if err = deleteNode(config.Dir(), machine, configRawMap); err != nil { + return machine, err + } + logrus.Infof("[node-controller] Removing node %s done", machine.Spec.RequestedHostname) + } + + return machine, nil + }) + + machine = obj.(*apimgmtv3.Node) + if err != nil { + return machine, err + } + + return m.deleteV1Node(machine) +} + +func (m *Lifecycle) provision(driverConfig, nodeDir string, obj *apimgmtv3.Node) (*apimgmtv3.Node, error) { + configRawMap := map[string]interface{}{} + if err := json.Unmarshal([]byte(driverConfig), &configRawMap); err != nil { + return obj, errors.Wrap(err, "failed to unmarshal node config") + } + + // Since we know this will take a long time persist so user sees status + obj, err := m.nodeClient.Update(obj) + if err != nil { + return obj, err + } + + err = aliasToPath(obj.Status.NodeTemplateSpec.Driver, configRawMap, obj.Namespace) + if err != nil { + return obj, err + } + + createCommandsArgs := buildCreateCommand(obj, configRawMap) + cmd, err := buildCommand(nodeDir, obj, createCommandsArgs) + if err != nil { + return obj, err + } + + logrus.Infof("[node-controller] Provisioning node %s", obj.Spec.RequestedHostname) + + stdoutReader, stderrReader, err := startReturnOutput(cmd) + if err != nil { + return obj, err + } + defer stdoutReader.Close() + defer stderrReader.Close() + defer cmd.Wait() + + obj, err = m.reportStatus(stdoutReader, stderrReader, obj) + if err != nil { + return obj, err + } + + if err = cmd.Wait(); err != nil { + return obj, err + } + + if err = m.deployAgent(nodeDir, obj); err != nil { + return obj, err + } + + logrus.Infof("[node-controller] Provisioning node %s done", obj.Spec.RequestedHostname) + return obj, nil +} + +func aliasToPath(driver string, config map[string]interface{}, ns string) error { + devMode := os.Getenv("CATTLE_DEV_MODE") != "" + baseDir := path.Join("/opt/jail", ns) + if devMode { + baseDir = os.TempDir() + } + // Check if the required driver has aliased fields + if fields, ok := SchemaToDriverFields[driver]; ok { + hasher := sha256.New() + for schemaField, driverField := range fields { + if fileRaw, ok := config[schemaField]; ok { + fileContents := fileRaw.(string) + // Delete our aliased fields + delete(config, schemaField) + if fileContents == "" { + continue + } + + fileName := driverField + if ok := nodedriver.SSHKeyFields[schemaField]; ok { + fileName = "id_rsa" + } + + // The ending newline gets stripped, add em back + if !strings.HasSuffix(fileContents, "\n") { + fileContents = fileContents + "\n" + } + + hasher.Reset() + hasher.Write([]byte(fileContents)) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + + fileDir := path.Join(baseDir, sha) + + // Delete the fileDir path if it's not a directory + if info, err := os.Stat(fileDir); err == nil && !info.IsDir() { + if err := os.Remove(fileDir); err != nil { + return err + } + } + + err := os.MkdirAll(fileDir, 0755) + if err != nil { + return err + } + fullPath := path.Join(fileDir, fileName) + err = os.WriteFile(fullPath, []byte(fileContents), 0600) + if err != nil { + return err + } + // Add the field and path + if devMode { + config[driverField] = fullPath + } else { + config[driverField] = path.Join("/", sha, fileName) + } + } + } + } + return nil +} + +func (m *Lifecycle) deployAgent(nodeDir string, obj *apimgmtv3.Node) error { + token, err := m.systemAccountManager.GetOrCreateSystemClusterToken(obj.Namespace) + if err != nil { + return err + } + + cluster, err := m.clusterLister.Get("", obj.Namespace) + if err != nil { + return err + } + + // make a deep copy of the cluster, so we are not modifying the original cluster object + clusterCopy := cluster.DeepCopy() + clusterCopy.Spec, err = assemblers.AssembleRKEConfigSpec(clusterCopy, clusterCopy.Spec, m.secretLister) + if err != nil { + return err + } + err = m.authenticateRegistry(nodeDir, obj, clusterCopy) + if err != nil { + return err + } + + drun, err := clusterregistrationtoken.NodeCommand(token, cluster) + if err != nil { + return err + } + args := buildAgentCommand(obj, drun) + cmd, err := buildCommand(nodeDir, obj, args) + if err != nil { + return err + } + + output, err := cmd.CombinedOutput() + if err != nil { + return errors.Wrap(err, string(output)) + } + + return nil +} + +// authenticateRegistry authenticates the machine to a private registry if one is defined on the cluster +// this enables the agent image to be pulled from the private registry +func (m *Lifecycle) authenticateRegistry(nodeDir string, node *apimgmtv3.Node, cluster *apimgmtv3.Cluster) error { + reg := util.GetPrivateRegistry(cluster) + // if there is no private registry defined or there is a registry without credentials, return since auth is not needed + if reg == nil || reg.User == "" || reg.Password == "" { + return nil + } + + logrus.Infof("[node-controller] private registry detected, authenticating %s to %s", node.Spec.RequestedHostname, reg.URL) + + login := clusterregistrationtoken.LoginCommand(*reg) + args := buildLoginCommand(node, login) + cmd, err := buildCommand(nodeDir, node, args) + if err != nil { + return err + } + + logrus.Tracef("[node-controller] login command: %s", cmd.String()) + + output, err := cmd.CombinedOutput() + if err != nil { + return errors.Wrap(err, string(output)) + } + + return nil +} + +func (m *Lifecycle) ready(obj *apimgmtv3.Node) (*apimgmtv3.Node, error) { + config, err := nodeconfig.NewNodeConfig(m.secretStore, obj) + if err != nil { + return obj, err + } + defer config.Cleanup() + + if err := config.Restore(); err != nil { + return obj, err + } + + err = m.refreshNodeConfig(config, obj) + if err != nil { + return nil, errors.WithMessagef(err, "unable to refresh config for node %v", obj.Name) + } + + driverConfig, err := config.DriverConfig() + if err != nil { + return nil, err + } + + // Provision in the background so we can poll and save the config + done := make(chan error) + go func() { + newObj, err := m.provision(driverConfig, config.Dir(), obj) + obj = newObj + done <- err + }() + + // Poll and save config +outer: + for { + select { + case err = <-done: + break outer + case <-time.After(5 * time.Second): + _ = config.Save() + } + } + + newObj, saveError := apimgmtv3.NodeConditionConfigSaved.Once(obj, func() (runtime.Object, error) { + return m.saveConfig(config, config.FullDir(), obj) + }) + obj = newObj.(*apimgmtv3.Node) + if err == nil { + return obj, saveError + } + return obj, err +} + +func (m *Lifecycle) sync(_ string, machine *apimgmtv3.Node) (runtime.Object, error) { + if machine == nil { + return nil, nil + } + + if machine.Annotations[userNodeRemoveCleanupAnnotation] != "true" { + machine = m.userNodeRemoveCleanup(machine) + } + + return m.nodeClient.Update(machine) +} + +func (m *Lifecycle) Updated(obj *apimgmtv3.Node) (runtime.Object, error) { + newObj, err := apimgmtv3.NodeConditionProvisioned.Once(obj, func() (runtime.Object, error) { + if obj.Status.NodeTemplateSpec == nil { + m.setWaiting(obj) + return obj, nil + } + + if !m.devMode { + logrus.Infof("Creating jail for %v", obj.Namespace) + err := jailer.CreateJail(obj.Namespace) + if err != nil { + return nil, errors.WithMessage(err, "node update jail error") + } + } + + obj, err := m.ready(obj) + if err == nil { + m.setWaiting(obj) + } + return obj, err + }) + return newObj.(*apimgmtv3.Node), err +} + +func (m *Lifecycle) saveConfig(config *nodeconfig.NodeConfig, nodeDir string, obj *apimgmtv3.Node) (*apimgmtv3.Node, error) { + logrus.Infof("[node-controller] Generating and uploading node config %s", obj.Spec.RequestedHostname) + if err := config.Save(); err != nil { + return obj, err + } + + ip, err := config.IP() + if err != nil { + return obj, err + } + + internalAddress, err := config.InternalIP() + if err != nil { + return obj, err + } + + keyPath, err := config.SSHKeyPath() + if err != nil { + return obj, err + } + + _, err = getSSHKey(nodeDir, keyPath, obj) + if err != nil { + return obj, err + } + + sshUser, err := config.SSHUser() + if err != nil { + return obj, err + } + + if err = config.Save(); err != nil { + return obj, err + } + + template, err := m.getNodeTemplate(obj.Spec.NodeTemplateName) + if err != nil { + return obj, err + } + + pool, err := m.getNodePool(obj.Spec.NodePoolName) + if err != nil { + return obj, err + } + + obj.Status.NodeConfig = &rketypes.RKEConfigNode{ + NodeName: obj.Namespace + ":" + obj.Name, + Address: ip, + InternalAddress: internalAddress, + User: sshUser, + Role: roles(obj), + HostnameOverride: obj.Spec.RequestedHostname, + Labels: template.Labels, + } + obj.Status.InternalNodeStatus.Addresses = []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: obj.Status.NodeConfig.Address, + }, + } + + if len(obj.Status.NodeConfig.Role) == 0 { + obj.Status.NodeConfig.Role = []string{"worker"} + } + + templateSet := taints.GetKeyEffectTaintSet(template.Spec.NodeTaints) + nodeSet := taints.GetKeyEffectTaintSet(pool.Spec.NodeTaints) + expectTaints := pool.Spec.NodeTaints + + for key, ti := range templateSet { + // the expected taints are based on the node pool. so we don't need to set taints with same key and effect by template because + // the taints from node pool should override the taints from template. + if _, ok := nodeSet[key]; !ok { + expectTaints = append(expectTaints, template.Spec.NodeTaints[ti]) + } + } + obj.Status.NodeConfig.Taints = taints.GetRKETaintsFromTaints(expectTaints) + + return obj, nil +} + +func (m *Lifecycle) refreshNodeConfig(nc *nodeconfig.NodeConfig, obj *apimgmtv3.Node) error { + template, err := m.getNodeTemplate(obj.Spec.NodeTemplateName) + if err != nil { + return err + } + + rawTemplate, err := m.nodeTemplateGenericClient.GetNamespaced(template.Namespace, template.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + data := rawTemplate.(*unstructured.Unstructured).Object + rawConfig, ok := values.GetValue(data, template.Spec.Driver+"Config") + if !ok { + return fmt.Errorf("refreshNodeConfig: node config not specified for node %v", obj.Name) + } + + if err := m.updateRawConfigFromCredential(data, rawConfig, template); err != nil { + logrus.Debugf("[node-controller] refreshNodeConfig: error calling updateRawConfigFromCredential for [%v]: %v", obj.Name, err) + return err + } + + var update bool + + if template.Spec.Driver == amazonec2 { + setEc2ClusterIDTag(rawConfig, obj.Namespace) + logrus.Debug("[node-controller] refreshNodeConfig: Updating amazonec2 machine config") + // TODO: Update to not be amazon specific, this needs to be moved to the driver + update, err = nc.UpdateAmazonAuth(rawConfig) + if err != nil { + return err + } + } + + bytes, err := json.Marshal(rawConfig) + if err != nil { + return errors.Wrap(err, "failed to marshal node driver config") + } + + newConfig := string(bytes) + + currentConfig, err := nc.DriverConfig() + if err != nil { + return err + } + + if currentConfig != newConfig || update { + err = nc.SetDriverConfig(string(bytes)) + if err != nil { + return err + } + + return nc.Save() + } + + return nil +} + +func (m *Lifecycle) isNodeInAppliedSpec(node *apimgmtv3.Node) (bool, error) { + // worker/controlplane nodes can just be immediately deleted + if !node.Spec.Etcd { + return false, nil + } + + cluster, err := m.clusterLister.Get("", node.Namespace) + if err != nil { + if kerror.IsNotFound(err) { + return false, nil + } + return false, err + } + if cluster == nil { + return false, nil + } + if cluster.DeletionTimestamp != nil { + return false, nil + } + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + return false, nil + } + + for _, rkeNode := range cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Nodes { + nodeName := rkeNode.NodeName + if len(nodeName) == 0 { + continue + } + if nodeName == fmt.Sprintf("%s:%s", node.Namespace, node.Name) { + return true, nil + } + } + return false, nil +} + +func validateCustomHost(obj *apimgmtv3.Node) error { + if obj.Spec.Imported { + return nil + } + + customConfig := obj.Spec.CustomConfig + signer, err := ssh.ParsePrivateKey([]byte(customConfig.SSHKey)) + if err != nil { + return errors.Wrapf(err, "sshKey format is invalid") + } + config := &ssh.ClientConfig{ + User: customConfig.User, + Auth: []ssh.AuthMethod{ + ssh.PublicKeys(signer), + }, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), + } + conn, err := ssh.Dial("tcp", customConfig.Address+":22", config) + if err != nil { + return errors.Wrapf(err, "Failed to validate ssh connection to address [%s]", customConfig.Address) + } + defer conn.Close() + return nil +} + +func roles(node *apimgmtv3.Node) []string { + var roles []string + if node.Spec.Etcd { + roles = append(roles, "etcd") + } + if node.Spec.ControlPlane { + roles = append(roles, "controlplane") + } + if node.Spec.Worker { + roles = append(roles, "worker") + } + if len(roles) == 0 { + return []string{"worker"} + } + return roles +} + +func (m *Lifecycle) setCredFields(data interface{}, fields map[string]apimgmtv3.Field, credID string) error { + splitID := strings.Split(credID, ":") + if len(splitID) != 2 { + return fmt.Errorf("invalid credential id %s", credID) + } + cred, err := m.secretLister.Get(namespace.GlobalNamespace, splitID[1]) + if err != nil { + return err + } + if ans := convert.ToMapInterface(data); len(ans) > 0 { + for key, val := range cred.Data { + splitKey := strings.Split(key, "-") + if len(splitKey) == 2 && strings.HasSuffix(splitKey[0], "Config") { + if _, ok := fields[splitKey[1]]; ok { + ans[splitKey[1]] = string(val) + } + } + } + } + return nil +} + +func (m *Lifecycle) updateRawConfigFromCredential(data map[string]interface{}, rawConfig interface{}, template *apimgmtv3.NodeTemplate) error { + credID := convert.ToString(values.GetValueN(data, "spec", "cloudCredentialName")) + if credID != "" { + existingSchema, err := m.schemaLister.Get("", template.Spec.Driver+"config") + if err != nil { + return err + } + logrus.Debugf("[node-controller] setCredFields for credentialName %s", credID) + err = m.setCredFields(rawConfig, existingSchema.Spec.ResourceFields, credID) + if err != nil { + return errors.Wrap(err, "failed to set credential fields") + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller_test.go new file mode 100644 index 0000000..37bde72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/controller_test.go @@ -0,0 +1,78 @@ +package node + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" + "testing" + + "github.com/rancher/rancher/pkg/controllers/management/drivers/nodedriver" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAliasMaps(t *testing.T) { + assert := assert.New(t) + assert.Len(SchemaToDriverFields, len(nodedriver.DriverToSchemaFields), "Alias maps are not equal") + for driver, fields := range SchemaToDriverFields { + assert.Contains(nodedriver.DriverToSchemaFields, driver) + nodeAliases := nodedriver.DriverToSchemaFields[driver] + for k, v := range fields { + // check that the value from the first map is the key to the 2nd map + val, ok := nodeAliases[v] + require.True(t, ok, fmt.Sprintf("Alias %v not found", v)) + // check that the value from the 2nd map is equal to the key from the first + assert.Equal(k, val) + } + } +} + +func TestAliasToPath(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + os.Setenv("CATTLE_DEV_MODE", "true") + defer os.Unsetenv("CATTLE_DEV_MODE") + + for driver, fields := range SchemaToDriverFields { + testData, _ := createFakeConfig(fields) + + err := aliasToPath(driver, testData, "fake") + assert.Nil(err) + for alias := range nodedriver.DriverToSchemaFields[driver] { + assert.Contains(testData, alias) + } + tempdir := os.TempDir() + + for _, v := range testData { + filePath := v.(string) + // validate the temp dir is in the path for the field + assert.Contains(filePath, tempdir) + // valide the file exists on disk + _, err = os.Stat(filePath) + require.Nil(err) + + // assert the file contents starts with our expected string + b, err := ioutil.ReadFile(filePath) + require.Nil(err) + assert.Contains(string(b), "fakecontent") + os.Remove(filePath) + } + } +} + +func createFakeConfig(fields map[string]string) (map[string]interface{}, []string) { + fakeContents := []string{} + testData := make(map[string]interface{}) + + base := "fakecontent" + i := 0 + for k := range fields { + content := base + strconv.Itoa(i) + fakeContents = append(fakeContents, content) + testData[k] = content + i++ + } + return testData, fakeContents + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/utils.go new file mode 100644 index 0000000..dac8f33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/node/utils.go @@ -0,0 +1,391 @@ +package node + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path" + "path/filepath" + "regexp" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/jailer" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +var regExHyphen = regexp.MustCompile("([a-z])([A-Z])") + +var ( + RegExNodeDirEnv = regexp.MustCompile("^" + nodeDirEnvKey + ".*") + RegExNodePluginToken = regexp.MustCompile("^" + "MACHINE_PLUGIN_TOKEN=" + ".*") + RegExNodeDriverName = regexp.MustCompile("^" + "MACHINE_PLUGIN_DRIVER_NAME=" + ".*") +) + +const ( + errorCreatingNode = "Error creating machine: " + nodeDirEnvKey = "MACHINE_STORAGE_PATH=" + nodeCmd = "rancher-machine" + ec2TagFlag = "tags" +) + +func buildAgentCommand(node *v3.Node, dockerRun string) []string { + drun := strings.Fields(dockerRun) + cmd := []string{"ssh", node.Spec.RequestedHostname} + cmd = append(cmd, drun...) + cmd = append(cmd, "-r", "-n", node.Name) + return cmd +} + +func buildLoginCommand(node *v3.Node, login string) []string { + cmd := []string{"ssh", node.Spec.RequestedHostname} + cmd = append(cmd, strings.Fields(login)...) + return cmd +} + +func buildCreateCommand(node *v3.Node, configMap map[string]interface{}) []string { + sDriver := strings.ToLower(node.Status.NodeTemplateSpec.Driver) + cmd := []string{"create", "-d", sDriver} + + cmd = append(cmd, buildEngineOpts("--engine-install-url", []string{node.Status.NodeTemplateSpec.EngineInstallURL})...) + cmd = append(cmd, buildEngineOpts("--engine-opt", mapToSlice(node.Status.NodeTemplateSpec.EngineOpt))...) + cmd = append(cmd, buildEngineOpts("--engine-opt", storageOptMapToSlice(node.Status.NodeTemplateSpec.StorageOpt))...) + cmd = append(cmd, buildEngineOpts("--engine-opt", logOptMapToSlice(node.Status.NodeTemplateSpec.LogOpt))...) + cmd = append(cmd, buildEngineOpts("--engine-env", mapToSlice(node.Status.NodeTemplateSpec.EngineEnv))...) + cmd = append(cmd, buildEngineOpts("--engine-insecure-registry", node.Status.NodeTemplateSpec.EngineInsecureRegistry)...) + cmd = append(cmd, buildEngineOpts("--engine-label", mapToSlice(node.Status.NodeTemplateSpec.EngineLabel))...) + cmd = append(cmd, buildEngineOpts("--engine-registry-mirror", node.Status.NodeTemplateSpec.EngineRegistryMirror)...) + cmd = append(cmd, buildEngineOpts("--engine-storage-driver", []string{node.Status.NodeTemplateSpec.EngineStorageDriver})...) + + // Append driver-specific flags to the command. + cmd = append(cmd, buildDriverFlags(sDriver, configMap)...) + + // Add the hostname to the command. + cmd = append(cmd, node.Spec.RequestedHostname) + return cmd +} + +// buildDriverFlags extracts driver-specific configuration from the given configmap and turns it into CLI flags. +func buildDriverFlags(driverName string, configMap map[string]any) []string { + cmd := make([]string, 0) + + for k, v := range configMap { + dmField := "--" + driverName + "-" + strings.ToLower(regExHyphen.ReplaceAllString(k, "${1}-${2}")) + if v == nil { + continue + } + + switch v.(type) { + case float64: + cmd = append(cmd, dmField, fmt.Sprintf("%v", v)) + case string: + if v.(string) != "" { + cmd = append(cmd, dmField, v.(string)) + } + case bool: + if v.(bool) { + cmd = append(cmd, dmField) + } + case []interface{}: + for _, s := range v.([]interface{}) { + if _, ok := s.(string); ok { + cmd = append(cmd, dmField, s.(string)) + } + } + } + } + + return cmd +} + +func buildEngineOpts(name string, values []string) []string { + var opts []string + for _, value := range values { + if value == "" { + continue + } + opts = append(opts, name, value) + } + return opts +} + +func mapToSlice(m map[string]string) []string { + ret := make([]string, len(m)) + for k, v := range m { + ret = append(ret, fmt.Sprintf("%s=%s", k, v)) + } + return ret +} + +func storageOptMapToSlice(m map[string]string) []string { + ret := make([]string, len(m)) + for k, v := range m { + ret = append(ret, fmt.Sprintf("storage-opt %s=%s", k, v)) + } + return ret +} + +func logOptMapToSlice(m map[string]string) []string { + ret := make([]string, len(m)) + for k, v := range m { + ret = append(ret, fmt.Sprintf("log-opt %s=%s", k, v)) + } + return ret +} + +func buildCommand(nodeDir string, node *v3.Node, cmdArgs []string) (*exec.Cmd, error) { + // only in trace because machine has sensitive details and we can't control who debugs what in there easily + if logrus.GetLevel() >= logrus.TraceLevel { + // prepend --debug to pass directly to machine + cmdArgs = append([]string{"--debug"}, cmdArgs...) + } + + // In dev_mode, don't need jail or reference to jail in command + if os.Getenv("CATTLE_DEV_MODE") != "" { + env := initEnviron(nodeDir) + command := exec.Command(nodeCmd, cmdArgs...) + command.Env = env + logrus.Tracef("buildCommand args: %v", command.Args) + return command, nil + } + + command := exec.Command(nodeCmd, cmdArgs...) + command.Env = []string{ + nodeDirEnvKey + nodeDir, + "PATH=/usr/bin:/var/lib/rancher/management-state/bin", + } + logrus.Tracef("buildCommand args: %v", command.Args) + return jailer.JailCommand(command, path.Join(jailer.BaseJailPath, node.Namespace)) +} + +func initEnviron(nodeDir string) []string { + env := os.Environ() + found := false + for idx, ev := range env { + if RegExNodeDirEnv.MatchString(ev) { + env[idx] = nodeDirEnvKey + nodeDir + found = true + } + if RegExNodePluginToken.MatchString(ev) { + env[idx] = "" + } + if RegExNodeDriverName.MatchString(ev) { + env[idx] = "" + } + } + if !found { + env = append(env, nodeDirEnvKey+nodeDir) + } + return env +} + +func startReturnOutput(command *exec.Cmd) (io.ReadCloser, io.ReadCloser, error) { + readerStdout, err := command.StdoutPipe() + if err != nil { + return nil, nil, err + } + + readerStderr, err := command.StderrPipe() + if err != nil { + return nil, nil, err + } + + if err := command.Start(); err != nil { + readerStdout.Close() + readerStderr.Close() + return nil, nil, err + } + + return readerStdout, readerStderr, nil +} + +func getSSHKey(nodeDir, keyPath string, obj *v3.Node) (string, error) { + keyName := filepath.Base(keyPath) + if keyName == "" || keyName == "." || keyName == string(filepath.Separator) { + keyName = "id_rsa" + } + if err := waitUntilSSHKey(nodeDir, keyName, obj); err != nil { + return "", err + } + + return getSSHPrivateKey(nodeDir, keyName, obj) +} + +func (m *Lifecycle) reportStatus(stdoutReader io.Reader, stderrReader io.Reader, node *v3.Node) (*v3.Node, error) { + scanner := bufio.NewScanner(stdoutReader) + debugPrefix := fmt.Sprintf("(%s) DBG | ", node.Spec.RequestedHostname) + for scanner.Scan() { + msg := scanner.Text() + if strings.Contains(msg, "To see how to connect") { + continue + } + _, err := filterDockerMessage(msg, node) + if err != nil { + return node, err + } + if strings.HasPrefix(msg, debugPrefix) { + // calls in machine with log.Debug are all prefixed and spammy so only log + // under trace and don't add to the v3.NodeConditionProvisioned.Message + logrus.Tracef("[node-controller] [cluster-id: %s] %v", node.ObjClusterName(), msg) + } else { + logrus.Infof("[node-controller] [cluster-id: %s] %v", node.ObjClusterName(), msg) + v32.NodeConditionProvisioned.Message(node, msg) + } + + // ignore update errors + if newObj, err := m.nodeClient.Update(node); err == nil { + node = newObj + } else { + node, _ = m.nodeClient.Get(node.Name, metav1.GetOptions{}) + } + } + scanner = bufio.NewScanner(stderrReader) + for scanner.Scan() { + msg := scanner.Text() + return node, errors.New(msg) + } + return node, nil +} + +func filterDockerMessage(msg string, node *v3.Node) (string, error) { + if strings.Contains(msg, errorCreatingNode) { + return "", errors.New(msg) + } + if strings.Contains(msg, node.Spec.RequestedHostname) { + return "", nil + } + return msg, nil +} + +func nodeExists(nodeDir string, node *v3.Node) (bool, error) { + command, err := buildCommand(nodeDir, node, []string{"ls", "-q"}) + if err != nil { + return false, err + } + + r, err := command.StdoutPipe() + if err != nil { + return false, err + } + + if err = command.Start(); err != nil { + return false, err + } + defer command.Wait() + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + foundName := scanner.Text() + if foundName == node.Spec.RequestedHostname { + return true, nil + } + } + if err = scanner.Err(); err != nil { + return false, err + } + + if err := command.Wait(); err != nil { + return false, err + } + + return false, nil +} + +func deleteNode(nodeDir string, node *v3.Node, configMap map[string]any) error { + // We're passing the `--update-config` flag here along with driver-specific flags to tell Rancher Machine + // to reload the driver-specific flags we pass via CLI flags. They need to be reloaded to account for cases + // were configuration used by Rancher machine (namely cloud credentials) change while the machine is still running. + // If we didn't do this, a user could create a machine and change the cloud credential it uses, leaving Rancher + // unable to remove the machine afterward because Rancher machine will always use the old credential it stored on + // machine creation. + driverName := strings.ToLower(node.Status.NodeTemplateSpec.Driver) + args := append([]string{"rm", "-f", "--update-config"}, buildDriverFlags(driverName, configMap)...) + + args = append(args, node.Spec.RequestedHostname) + command, err := buildCommand(nodeDir, node, args) + if err != nil { + return err + } + stdoutReader, stderrReader, err := startReturnOutput(command) + if err != nil { + return err + } + defer stdoutReader.Close() + defer stderrReader.Close() + scanner := bufio.NewScanner(stdoutReader) + for scanner.Scan() { + msg := scanner.Text() + logrus.Infof("[node-controller] %v", msg) + } + scanner = bufio.NewScanner(stderrReader) + for scanner.Scan() { + msg := scanner.Text() + logrus.Warnf("[node-controller] %v", msg) + } + + return command.Wait() +} + +func getSSHPrivateKey(nodeDir, keyName string, node *v3.Node) (string, error) { + keyPath := filepath.Join(nodeDir, "machines", node.Spec.RequestedHostname, keyName) + data, err := ioutil.ReadFile(keyPath) + if err != nil { + return "", nil + } + return string(data), nil +} + +func waitUntilSSHKey(nodeDir, keyName string, node *v3.Node) error { + keyPath := filepath.Join(nodeDir, "machines", node.Spec.RequestedHostname, keyName) + startTime := time.Now() + increments := 1 + for { + if time.Now().After(startTime.Add(15 * time.Second)) { + return errors.New("Timeout waiting for ssh key") + } + if _, err := os.Stat(keyPath); err != nil { + logrus.Debugf("keyPath not found. The node is probably still provisioning. Sleep %v second", increments) + time.Sleep(time.Duration(increments) * time.Second) + increments = increments * 2 + continue + } + return nil + } +} + +func setEc2ClusterIDTag(data interface{}, clusterID string) { + if m, ok := data.(map[string]interface{}); ok { + tagValue := fmt.Sprintf("kubernetes.io/cluster/%s,owned", clusterID) + if tags, ok := m[ec2TagFlag]; !ok || convert.ToString(tags) == "" { + m[ec2TagFlag] = tagValue + } else { + m[ec2TagFlag] = convert.ToString(tags) + "," + tagValue + } + } +} + +func (m *Lifecycle) getKubeConfig(cluster *v3.Cluster) (*clientcmdapi.Config, string, error) { + user, err := m.systemAccountManager.GetSystemUser(cluster.Name) + if err != nil { + return nil, "", err + } + + tokenPrefix := "node-removal-drain-" + user.Name + token, err := m.systemTokens.EnsureSystemToken(tokenPrefix, "token for node drain during removal", "agent", user.Name, nil, true) + if err != nil { + return nil, "", err + } + + tokenName, _ := tokens.SplitTokenParts(token) + return m.clusterManager.KubeConfig(cluster.Name, token), tokenName, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool.go new file mode 100644 index 0000000..8f6ca26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool.go @@ -0,0 +1,568 @@ +package nodepool + +import ( + "context" + "fmt" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "sync" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" +) + +var ( + nameRegexp = regexp.MustCompile("^(.*?)([0-9]+)$") +) + +const ( + ReconcileAnnotation = "nodepool.cattle.io/reconcile" +) + +type Controller struct { + NodePoolController v3.NodePoolController + NodePoolLister v3.NodePoolLister + NodePools v3.NodePoolInterface + NodeLister v3.NodeLister + Nodes v3.NodeInterface + mutex sync.RWMutex + syncmap map[string]bool +} + +// Register registers the nodepool controller against the managementcontext. +func Register(ctx context.Context, management *config.ManagementContext) { + p := &Controller{ + NodePoolController: management.Management.NodePools("").Controller(), + NodePoolLister: management.Management.NodePools("").Controller().Lister(), + NodePools: management.Management.NodePools(""), + NodeLister: management.Management.Nodes("").Controller().Lister(), + Nodes: management.Management.Nodes(""), + syncmap: make(map[string]bool), + } + + // Add handlers + p.NodePools.AddLifecycle(ctx, "nodepool-provisioner", p) + management.Management.Nodes("").AddHandler(ctx, "nodepool-provisioner", p.nodeChanged) +} + +// Create does a noop for nodepool. +func (c *Controller) Create(nodePool *v3.NodePool) (runtime.Object, error) { + return nodePool, nil +} + +// needsReconcile checks the nodepool to see if reconciliation is necessary. +func (c *Controller) needsReconcile(nodePool *v3.NodePool, nodes []*v3.Node) bool { + changed, _, err := c.createOrCheckNodes(nodePool, nodes, true) + if err != nil { + logrus.Debugf("[nodepool] error checking pool for reconciliation: %s", err) + } + + return changed +} + +// reconcile reconciles the nodepool provided if necessary +func (c *Controller) reconcile(nodePool *v3.NodePool, nodes []*v3.Node) (runtime.Object, error) { + _, qty, err := c.createOrCheckNodes(nodePool, nodes, false) + if err != nil { + return nodePool, fmt.Errorf("[nodepool] reconcile error, create or check nodes: %s", err) + } + + // In certain cases, the nodepool quantity can actually decrease through a `createOrCheckNodes` call, like + // for scaling down a specific node. In this case, we need to update the nodePool object with the latest + // quantity so that on a future reconciliation loop, we do not recreate a node that was specifically scaled down. + if qty != nodePool.Spec.Quantity { + nodePool.Spec.Quantity = qty + } + + nodePool, err = c.updateNodePoolAnnotationAndSpec(nodePool, "", true) + if err != nil { + return nodePool, fmt.Errorf("[nodepool] error updating reconcile annotation to updated: %s", err) + } + return nodePool, nil +} + +// Updated reconciles a nodepool if necessary +func (c *Controller) Updated(nodePool *v3.NodePool) (runtime.Object, error) { + if nodePool != nil { + logrus.Tracef("[nodepool] Updated called for nodepool %s: %+v", nodePool.Name, nodePool) + } + obj, err := v32.NodePoolConditionUpdated.Do(nodePool, func() (runtime.Object, error) { + anno, _ := nodePool.Annotations[ReconcileAnnotation] + logrus.Debugf("[nodepool] nodepool %s reconcile annotation value was: %s", nodePool.Name, anno) + if anno == "" { + nodes, err := c.nodes(nodePool) + if err != nil { + return nodePool, err + } + if c.needsReconcile(nodePool, nodes) { + logrus.Debugf("[nodepool] reconcile needed for %s", nodePool.Name) + np, err := c.updateNodePoolAnnotationAndSpec(nodePool, "updating", false) + if err != nil { + return nodePool, err + } + logrus.Debugf("[nodepool] calling reconcile for %s", nodePool.Name) + return c.reconcile(np, nodes) + } + } else if strings.HasPrefix(anno, "updating/") { + // gate updating the node pool to every 120s. + // This has the potential to race if the reconcile loop takes longer than 120 seconds, but this is a + // very rare case as there is nothing in reconcile/needsReconcile that should block. It is more likely that + // Rancher will die/panic from leader election loss, and a new instance of Rancher will take over (and thus, + // need to clear the annotation) in order to reconcile the pool. + pieces := strings.Split(anno, "/") + t, err := time.Parse(time.RFC3339, pieces[1]) + if err != nil || int(time.Since(t)/time.Second) > 120 { + logrus.Debugf("[nodepool] attempting to clear reconcile annotation for %s", nodePool.Name) + nodePool.Annotations[ReconcileAnnotation] = "" + return c.NodePools.Update(nodePool) + } + logrus.Debugf("[nodepool] reconcile annotation was already set for %s, not attempting to reconcile", nodePool.Name) + return nodePool, nil + } + + // pool doesn't need to reconcile, nothing to do + return nodePool, nil + }) + + logrus.Tracef("[nodepool] Updated handler for nodepool %s finished", obj.(*v3.NodePool).Name) + return obj.(*v3.NodePool), err +} + +// Remove removes a nodepool and all corresponding nodes for the nodepool. +func (c *Controller) Remove(nodePool *v3.NodePool) (runtime.Object, error) { + logrus.Infof("[nodepool] deleting nodepool %s", nodePool.Name) + + logrus.Debugf("[nodepool] listing nodes for pool %s", nodePool.Name) + nodeList, err := c.Nodes.ListNamespaced(nodePool.Namespace, metav1.ListOptions{}) + if err != nil { + return nodePool, err + } + + for _, node := range nodeList.Items { + _, nodePoolName := ref.Parse(node.Spec.NodePoolName) + if nodePoolName != nodePool.Name { + continue + } + + if err := c.deleteNodeBackoffAndRetry(&node); err != nil { + return nodePool, err + } + } + + return nodePool, nil +} + +// nodes returns a slice of node objects listed directly from the Kubernetes API. +func (c *Controller) nodes(nodePool *v3.NodePool) ([]*v3.Node, error) { + nodeList, err := c.Nodes.ListNamespaced(nodePool.Namespace, metav1.ListOptions{}) + if err != nil { + return nil, err + } + + var nodes []*v3.Node + for i := range nodeList.Items { + nodes = append(nodes, &nodeList.Items[i]) + } + + return nodes, nil +} + +// updateNodePoolAnnotationAndSpec will retrieve and update the latest version from the Kubernetes API of the nodepool provided. +// It will set the annotation and spec.quantity (if setQuantity is true), and return the updated nodepool. +func (c *Controller) updateNodePoolAnnotationAndSpec(nodePool *v3.NodePool, anno string, setQuantity bool) (*v3.NodePool, error) { + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 6, + } + + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + newPool, err := c.NodePools.GetNamespaced(nodePool.Namespace, nodePool.Name, metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return false, err + } + return false, nil + } + + if anno == "updating" { + // Add a timestamp for comparison since this anno was added + anno = anno + "/" + time.Now().Format(time.RFC3339) + } + + newPool.Annotations[ReconcileAnnotation] = anno + if setQuantity { + // in case the pool size changed during reconcile, like for + // example if scaling down a specific node through node.spec.ScaledownTime. + newPool.Spec.Quantity = nodePool.Spec.Quantity + } + newPool, err = c.NodePools.Update(newPool) + if err != nil { + if apierrors.IsConflict(err) { + logrus.Debugf("[nodepool] received conflict on nodepool reconcile annotation set attempt to %s on nodepool %s", anno, nodePool.Name) + return false, nil + } + return false, err + } + nodePool = newPool + return true, nil + }) + if err != nil { + return nodePool, fmt.Errorf("[nodepool] Failed to update nodePool annotation [%s]: %v", nodePool.Name, err) + } + logrus.Debugf("[nodepool] reconcile annotation set for nodePool %s to %s", nodePool.Name, anno) + return nodePool, nil +} + +// nodeChanged handles a machine object and enqueues the nodepool that corresponds to the node. +func (c *Controller) nodeChanged(key string, node *v3.Node) (runtime.Object, error) { + if node == nil { + nps, err := c.NodePoolLister.List("", labels.Everything()) + if err != nil { + return nil, err + } + for _, np := range nps { + c.NodePoolController.Enqueue(np.Namespace, np.Name) + } + } else if node.Spec.NodePoolName != "" { + ns, name := ref.Parse(node.Spec.NodePoolName) + c.NodePoolController.Enqueue(ns, name) + } + + return nil, nil +} + +// createNode creates a node with the requestedHostname with the nodepool if simulate is false. It sets all nodePool +// annotations on the node except for the reconcile annotation. +func (c *Controller) createNode(requestedHostname string, nodePool *v3.NodePool, simulate bool) (*v3.Node, error) { + newNode := &v3.Node{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "m-", + Namespace: nodePool.Namespace, + Labels: nodePool.Labels, + Annotations: nodePool.Annotations, + }, + Spec: v32.NodeSpec{ + Etcd: nodePool.Spec.Etcd, + ControlPlane: nodePool.Spec.ControlPlane, + Worker: nodePool.Spec.Worker, + NodeTemplateName: nodePool.Spec.NodeTemplateName, + NodePoolName: ref.Ref(nodePool), + RequestedHostname: requestedHostname, + }, + } + + delete(newNode.Annotations, ReconcileAnnotation) // don't set the reconcile annotation on the node being created. + if simulate { + return newNode, nil + } + + n, err := c.Nodes.Create(newNode) + if err != nil { + return nil, err + } + + logrus.Debugf("[nodepool] node created %s with requested hostname %s", n.Name, requestedHostname) + return n, nil +} + +// deleteNodeBackoffAndRetry deletes the provided node with a backoff, and sets the propagation to background to prevent +// blocking the delete call. +func (c *Controller) deleteNodeBackoffAndRetry(node *v3.Node) error { + backoff := wait.Backoff{ + Duration: 500 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 6, + } + + logrus.Debugf("[nodepool] attempting to delete node %s", node.Name) + f := metav1.DeletePropagationBackground + return wait.ExponentialBackoff(backoff, func() (bool, error) { + err := c.Nodes.DeleteNamespaced(node.Namespace, node.Name, &metav1.DeleteOptions{ + PropagationPolicy: &f, + }) + if err != nil { + if apierrors.IsNotFound(err) { + return true, nil + } + return false, nil + } + return true, nil + }) +} + +// parsePrefix parses the prefix provided based on the regex and returns the prefix, the minimum length of the numbered +// suffix, and the start number. +func parsePrefix(fullPrefix string) (prefix string, minLength, start int) { + m := nameRegexp.FindStringSubmatch(fullPrefix) + if len(m) == 0 { + return fullPrefix, 1, 1 + } + prefix = m[1] + start, _ = strconv.Atoi(m[2]) + return prefix, len(m[2]), start +} + +// createOrCheckNodes will filter the nodes passed in for nodes that belong to the nodepool, and reconcile the nodes +// (creating or deleting them as necessary). The function accepts a nodepool, a slice of node pointers, and a simulate +// boolean that will disable node deletion if set to true. The function returns a boolean that indicates whether a +// change was made, an int indicating the new desired quantity of the nodepool, and an error if one exists. Notably, +// createOrCheckNodes does not mutate the passed in nodePool object. +func (c *Controller) createOrCheckNodes(nodePool *v3.NodePool, allNodes []*v3.Node, simulate bool) (bool, int, error) { + var ( + err error + byName = map[string]*v3.Node{} + changed = false + nodes []*v3.Node + deleteNotReadyAfter = nodePool.Spec.DeleteNotReadyAfterSecs * time.Second + ) + + quantity := nodePool.Spec.Quantity + for _, node := range allNodes { + byName[node.Spec.RequestedHostname] = node + + _, nodePoolName := ref.Parse(node.Spec.NodePoolName) + if nodePoolName != nodePool.Name || node.DeletionTimestamp != nil { + continue + } + + // If it has been more than 2 minutes since node creation and the Provisioned, Initialized, or ConfigSaved + // conditions are not set, go ahead and delete the node. Note this is a change in behavior from before, + // when we used to put a sleep in a goroutine and let it delete the node eventually, which could + // cause a race condition. + if v32.NodeConditionProvisioned.IsFalse(node) || v32.NodeConditionInitialized.IsFalse(node) || v32.NodeConditionConfigSaved.IsFalse(node) { + if time.Now().After(node.CreationTimestamp.Add(2 * time.Minute)) { + changed = true + if !simulate { + logrus.Debugf("[nodepool] node %s in nodepool %s didn't have required conditions in time, deleting", node.Name, nodePool.Name) + if err = c.deleteNodeBackoffAndRetry(node); err != nil { + return false, quantity, err + } + } + continue + } + } + + // handle nodes that have a defined scaledown time. + if node.Spec.ScaledownTime != "" { + logrus.Debugf("[nodepool] (simulate: %t) scaledown time detected for %s: %s and now it is %s", + simulate, node.Name, node.Spec.ScaledownTime, time.Now().Format(time.RFC3339)) + scaledown, err := time.Parse(time.RFC3339, node.Spec.ScaledownTime) + if err != nil { + logrus.Errorf("[nodepool] failed to parse scaledown time, is it in RFC3339? %s: %s", node.Spec.ScaledownTime, err) + } else { + if scaledown.Before(time.Now()) { + changed = true + if !simulate { + logrus.Debugf("[nodepool] scaling down, removing node %s", node.Name) + if err = c.deleteNodeBackoffAndRetry(node); err != nil { + return false, quantity, err + } + } + quantity-- + continue + } + + // scaledown happening in the future, enqueue after to check again later + c.NodePoolController.EnqueueAfter(nodePool.Namespace, nodePool.Name, scaledown.Sub(time.Now())) + } + } + + // remove unreachable node with the unreachable taint & status of Ready being Unknown + q := getUnreachableTaint(node.Spec.InternalNodeSpec.Taints) + if q != nil && deleteNotReadyAfter > 0 { + changed = true + if isNodeReadyUnknown(node) && !simulate { + start := q.TimeAdded.Time + if time.Since(start) > deleteNotReadyAfter { + err = c.deleteNodeBackoffAndRetry(node) + if err != nil { + return false, quantity, err + } + } else { + c.mutex.Lock() + nodeid := node.Namespace + ":" + node.Name + if _, ok := c.syncmap[nodeid]; !ok { + c.syncmap[nodeid] = true + go c.requeue(deleteNotReadyAfter, nodePool, node) + } + c.mutex.Unlock() + } + } + } + nodes = append(nodes, node) + } + + if quantity < 0 { + quantity = 0 + } + + prefix, minLength, start := parsePrefix(nodePool.Spec.HostnamePrefix) + for i := start; len(nodes) < quantity; i++ { + ia := strconv.Itoa(i) + name := prefix + ia + if len(ia) < minLength { + name = fmt.Sprintf("%s%0"+strconv.Itoa(minLength)+"d", prefix, i) + } + + if byName[name] != nil { + continue + } + + changed = true + newNode, err := c.createNode(name, nodePool, simulate) + if err != nil { + return false, quantity, err + } + + byName[newNode.Spec.RequestedHostname] = newNode + nodes = append(nodes, newNode) + } + + // Scale down the top node sorted by hostname. + for len(nodes) > quantity { + sort.Sort(byHostname(nodes)) + + toDelete := nodes[len(nodes)-1] + + changed = true + if !simulate { + c.deleteNodeBackoffAndRetry(toDelete) + } + + nodes = nodes[:len(nodes)-1] + delete(byName, toDelete.Spec.RequestedHostname) + } + + for _, n := range nodes { + if needRoleUpdate(n, nodePool) { + changed = true + _, err := c.updateNodeRoles(n, nodePool, simulate) + if err != nil { + return false, quantity, err + } + } + } + + return changed, quantity, nil +} + +// needRoleUpdate checks the node against the nodepool to determine whether the node needs to have its noderoles updated. +func needRoleUpdate(node *v3.Node, nodePool *v3.NodePool) bool { + if node.Status.NodeConfig == nil { + return false + } + if len(node.Status.NodeConfig.Role) == 0 && !nodePool.Spec.Worker { + return true + } + + nodeRolesMap := map[string]bool{} + nodeRolesMap[services.ETCDRole] = false + nodeRolesMap[services.ControlRole] = false + nodeRolesMap[services.WorkerRole] = false + + for _, role := range node.Status.NodeConfig.Role { + switch r := role; r { + case services.ETCDRole: + nodeRolesMap[services.ETCDRole] = true + case services.ControlRole: + nodeRolesMap[services.ControlRole] = true + case services.WorkerRole: + nodeRolesMap[services.WorkerRole] = true + } + } + poolRolesMap := map[string]bool{} + poolRolesMap[services.ETCDRole] = nodePool.Spec.Etcd + poolRolesMap[services.ControlRole] = nodePool.Spec.ControlPlane + poolRolesMap[services.WorkerRole] = nodePool.Spec.Worker + + r := !reflect.DeepEqual(nodeRolesMap, poolRolesMap) + if r { + logrus.Debugf("[nodepool] updating machine [%s] roles: nodepoolRoles: {%+v} node roles: {%+v}", node.Name, poolRolesMap, nodeRolesMap) + } + return r +} + +// updateNodeRoles updates an existing node with new node roles if simulate is false. +func (c *Controller) updateNodeRoles(existing *v3.Node, nodePool *v3.NodePool, simulate bool) (*v3.Node, error) { + toUpdate := existing.DeepCopy() + var newRoles []string + + if nodePool.Spec.ControlPlane { + newRoles = append(newRoles, "controlplane") + } + if nodePool.Spec.Etcd { + newRoles = append(newRoles, "etcd") + } + if nodePool.Spec.Worker { + newRoles = append(newRoles, "worker") + } + + if len(newRoles) == 0 { + newRoles = []string{"worker"} + } + + toUpdate.Status.NodeConfig.Role = newRoles + if simulate { + return toUpdate, nil + } + return c.Nodes.Update(toUpdate) +} + +// requeue checks every 5 seconds if the node is still unreachable with one goroutine per node +func (c *Controller) requeue(timeout time.Duration, np *v3.NodePool, node *v3.Node) { + t := getUnreachableTaint(node.Spec.InternalNodeSpec.Taints) + for t != nil { + time.Sleep(5 * time.Second) + exist, err := c.NodeLister.Get(node.Namespace, node.Name) + if err != nil { + break + } + t = getUnreachableTaint(exist.Spec.InternalNodeSpec.Taints) + if t != nil && time.Since(t.TimeAdded.Time) > timeout { + logrus.Debugf("[nodepool] requeue is now enqueuing nodepool as node is still unreachable for longer than timeout: %s/%s", np.Namespace, np.Name) + c.NodePoolController.Enqueue(np.Namespace, np.Name) + break + } + } + c.mutex.Lock() + delete(c.syncmap, node.Namespace+":"+node.Name) + c.mutex.Unlock() +} + +// getUnreachableTaint searches the provided taint slice for the v1.TaintNodeUnreachable taint, and if it exists, +// returns the taint. +func getUnreachableTaint(taints []v1.Taint) *v1.Taint { + for _, taint := range taints { + if taint.Key == v1.TaintNodeUnreachable { + return &taint + } + } + return nil +} + +// IsNodeReady returns true if a node Ready condition is Unknown; false otherwise. +func isNodeReadyUnknown(node *v3.Node) bool { + for _, c := range node.Status.InternalNodeStatus.Conditions { + if c.Type == v1.NodeReady { + return c.Status == v1.ConditionUnknown + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool_test.go new file mode 100644 index 0000000..2fed9db --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/nodepool_test.go @@ -0,0 +1,164 @@ +package nodepool + +import ( + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_parsePrefix(t *testing.T) { + + tests := []struct { + name string + fullPrefix string + wantPrefix string + wantMinLength int + wantStart int + }{{ + name: "prefix with an 2 digit integer", + fullPrefix: "my-worker25", + wantPrefix: "my-worker", + wantMinLength: 2, + wantStart: 25, + }, { + name: "prefix with an 1 digit integer", + fullPrefix: "pool4", + wantPrefix: "pool", + wantMinLength: 1, + wantStart: 4, + }, { + name: "default case", + fullPrefix: "genericNodepool", + wantPrefix: "genericNodepool", + wantMinLength: 1, + wantStart: 1, + }, + } + for _, tt := range tests { + + gotPrefix, gotMinLength, gotStart := parsePrefix(tt.fullPrefix) + + assert.Equal(t, tt.wantPrefix, gotPrefix) + assert.Equal(t, tt.wantMinLength, gotMinLength) + assert.Equal(t, tt.wantStart, gotStart) + } +} + +func Test_roleUpdate(t *testing.T) { + var tests = []struct { + name string + node *v3.Node + nodepool *v3.NodePool + want bool + nodeAfterUpdate *v3.Node + }{ + { + name: "all roles; nodepool & node", + node: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + Role: []string{services.ETCDRole, services.ControlRole, services.WorkerRole}, + }, + }, + }, + nodepool: &v3.NodePool{ + // per the types struct tags, these will always be defined and never be nil + Spec: v32.NodePoolSpec{ + Etcd: true, + ControlPlane: true, + Worker: true, + }, + }, + want: false, + nodeAfterUpdate: nil, + }, + { + name: "worker only", + node: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + Role: []string{services.WorkerRole}, + }, + }, + }, + nodepool: &v3.NodePool{ + Spec: v32.NodePoolSpec{ + Etcd: false, + ControlPlane: false, + Worker: true, + }, + }, + want: false, + nodeAfterUpdate: nil, + }, + { + name: "worker => controlplane ", + node: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + Role: []string{services.WorkerRole}, + }, + }, + }, + nodepool: &v3.NodePool{ + Spec: v32.NodePoolSpec{ + Etcd: true, + ControlPlane: true, + Worker: true, + }, + }, + want: true, + nodeAfterUpdate: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + // order matters here + Role: []string{services.ControlRole, services.ETCDRole, services.WorkerRole}, + }, + }, + }, + }, + { + name: "controlplane => worker", + node: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + Role: []string{services.WorkerRole, services.ETCDRole, services.ControlRole}, + }, + }, + }, + nodepool: &v3.NodePool{ + Spec: v32.NodePoolSpec{ + Etcd: false, + ControlPlane: false, + Worker: true, + }, + }, + want: true, + nodeAfterUpdate: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{ + // order matters here + Role: []string{services.WorkerRole}, + }, + }, + }, + }, + } + c := &Controller{} + for _, tt := range tests { + got := needRoleUpdate(tt.node, tt.nodepool) + require.Equal(t, tt.want, got) + if got { + newNode, err := c.updateNodeRoles(tt.node, tt.nodepool, true) + if err != nil { + t.Errorf("error updating node role: %v", err) + } + assert.EqualValues(t, tt.nodeAfterUpdate, newNode) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort.go new file mode 100644 index 0000000..820e787 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort.go @@ -0,0 +1,80 @@ +package nodepool + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +//implement natural sort of a slice of nodeHostnames + +type byHostname []*v3.Node + +func (n byHostname) Len() int { return len(n) } +func (n byHostname) Swap(i, j int) { n[i], n[j] = n[j], n[i] } + +func (n byHostname) Less(i, j int) bool { + s := n[i].Spec.RequestedHostname + t := n[j].Spec.RequestedHostname + return NaturalLess(s, t) +} + +// from https://github.com/fvbommel/util/blob/efcd4e0f97874370259c7d93e12aad57911dea81/sortorder/natsort.go +func isdigit(b byte) bool { return '0' <= b && b <= '9' } + +// NaturalLess compares two strings using natural ordering. This means that e.g. +// "abc2" < "abc12". +// +// Non-digit sequences and numbers are compared separately. The former are +// compared bytewise, while the latter are compared numerically (except that +// the number of leading zeros is used as a tie-breaker, so e.g. "2" < "02") +// +// Limitation: only ASCII digits (0-9) are considered. +func NaturalLess(str1, str2 string) bool { + idx1, idx2 := 0, 0 + for idx1 < len(str1) && idx2 < len(str2) { + c1, c2 := str1[idx1], str2[idx2] + dig1, dig2 := isdigit(c1), isdigit(c2) + switch { + case dig1 != dig2: // Digits before other characters. + return dig1 // True if LHS is a digit, false if the RHS is one. + case !dig1: // && !dig2, because dig1 == dig2 + // UTF-8 compares bytewise-lexicographically, no need to decode + // codepoints. + if c1 != c2 { + return c1 < c2 + } + idx1++ + idx2++ + default: // Digits + // Eat zeros. + for ; idx1 < len(str1) && str1[idx1] == '0'; idx1++ { + } + for ; idx2 < len(str2) && str2[idx2] == '0'; idx2++ { + } + // Eat all digits. + nonZero1, nonZero2 := idx1, idx2 + for ; idx1 < len(str1) && isdigit(str1[idx1]); idx1++ { + } + for ; idx2 < len(str2) && isdigit(str2[idx2]); idx2++ { + } + // If lengths of numbers with non-zero prefix differ, the shorter + // one is less. + if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 { + return len1 < len2 + } + // If they're equal, string comparison is correct. + if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 { + return nr1 < nr2 + } + // Otherwise, the one with less zeros is less. + // Because everything up to the number is equal, comparing the index + // after the zeros is sufficient. + if nonZero1 != nonZero2 { + return nonZero1 < nonZero2 + } + } + // They're identical so far, so continue comparing. + } + // So far they are identical. At least one is ended. If the other continues, + // it sorts last. + return len(str1) < len(str2) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort_test.go new file mode 100644 index 0000000..e8b80eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodepool/sort_test.go @@ -0,0 +1,60 @@ +package nodepool + +import "testing" + +func TestNaturalLess(t *testing.T) { + testset := []struct { + s1, s2 string + less bool + }{ + { + "daxworker9", + "daxworker10", + true, + }, + { + "dax10worker9", + "daxworker10", + true, + }, + { + "string-with-hyphens", + "stringwithouthyphens", + true, + }, + {"0", "00", true}, + {"00", "0", false}, + {"aa", "ab", true}, + {"ab", "abc", true}, + {"abc", "ad", true}, + {"ab1", "ab2", true}, + {"ab1c", "ab1c", false}, + {"ab12", "abc", true}, + {"ab2a", "ab10", true}, + {"a0001", "a0000001", true}, + {"a10", "abcdefgh2", true}, + {"аб2аб", "аб10аб", true}, + {"2аб", "3аб", true}, + // + {"a1b", "a01b", true}, + {"a01b", "a1b", false}, + {"ab01b", "ab010b", true}, + {"ab010b", "ab01b", false}, + {"a01b001", "a001b01", true}, + {"a001b01", "a01b001", false}, + {"a1", "a1x", true}, + {"1ax", "1b", true}, + {"1b", "1ax", false}, + // + {"082", "83", true}, + // + {"083a", "9a", false}, + {"9a", "083a", true}, + } + for _, v := range testset { + if res := NaturalLess(v.s1, v.s2); res != v.less { + t.Errorf("Compared %#q to %#q: expected %v, got %v", + v.s1, v.s2, v.less, res) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodetemplate/nodetemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodetemplate/nodetemplate.go new file mode 100644 index 0000000..28b0671 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/nodetemplate/nodetemplate.go @@ -0,0 +1,278 @@ +package nodetemplate + +import ( + "context" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" +) + +const ( + OwnerBindingsAnno = "ownerBindingsCreated" + vmwaredriver = "vmwarevsphere" +) + +type nodeTemplateController struct { + ntClient v3.NodeTemplateInterface + ntLister v3.NodeTemplateLister + npLister v3.NodePoolLister + npClient v3.NodePoolInterface + nsLister v1.NamespaceLister + nsClient v1.NamespaceInterface + nodesLister v3.NodeLister + nodeClient v3.NodeInterface + ntDynamicClient dynamic.NamespaceableResourceInterface + mgmtCtx *config.ManagementContext +} + +func Register(ctx context.Context, mgmt *config.ManagementContext) { + // Parts of the node template in k8s are dynamic, such as an azureConfig. If the dynamic client is not use then the + // dynamic fields, like azureConfig, are stripped when marshalling the data into the NodeTemplate struct. If changes + // are made, and that struct is committed to k8s, then the dynamic field is effectively removed. + restConfig := mgmt.RESTConfig + dynamicClient, err := dynamic.NewForConfig(&restConfig) + if err != nil { + panic(fmt.Sprintf("[NodeTemplate Register] error creating dynamic client: %v", err)) + } + + s := schema.GroupVersionResource{ + Group: "management.cattle.io", + Version: "v3", + Resource: "nodetemplates", + } + ntDynamicClient := dynamicClient.Resource(s) + + nt := nodeTemplateController{ + ntClient: mgmt.Management.NodeTemplates(""), + npLister: mgmt.Management.NodePools("").Controller().Lister(), + npClient: mgmt.Management.NodePools(""), + nsLister: mgmt.Core.Namespaces("").Controller().Lister(), + nsClient: mgmt.Core.Namespaces(""), + nodesLister: mgmt.Management.Nodes("").Controller().Lister(), + nodeClient: mgmt.Management.Nodes(""), + ntDynamicClient: ntDynamicClient, + mgmtCtx: mgmt, + } + + mgmt.Management.NodeTemplates("").Controller().AddHandler(ctx, "nt-grb-handler", nt.sync) +} + +func (nt *nodeTemplateController) sync(key string, nodeTemplate *v3.NodeTemplate) (runtime.Object, error) { + if nodeTemplate == nil || nodeTemplate.DeletionTimestamp != nil { + return nil, nil + } + + // if owner bindings annotation is present, the node template is in the proper namespace and has had + // its creator rolebindings created + if nodeTemplate.Annotations != nil && nodeTemplate.Annotations[OwnerBindingsAnno] == "true" { + return nodeTemplate, nil + } + + creatorID, ok := nodeTemplate.Annotations[rbac.CreatorIDAnn] + if !ok { + return nodeTemplate, fmt.Errorf("nodeTemplate [%v] has no creatorId annotation", nodeTemplate.Name) + } + + var migratedTemplate bool + + if nodeTemplate.Namespace != namespace.NodeTemplateGlobalNamespace { + // node template must be migrated to global namespace + var err error + nodeTemplate, err = nt.migrateNodeTemplate(nt.ntDynamicClient, nodeTemplate) + if err != nil { + return nil, err + } + + migratedTemplate = true + } + + // Create Role and RBs if they do not exist + if err := rbac.CreateRoleAndRoleBinding(rbac.NodeTemplateResource, v3.NodeTemplateGroupVersionKind.Kind, nodeTemplate.Name, namespace.NodeTemplateGlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + nodeTemplate.UID, + []v32.Member{}, nt.mgmtCtx); err != nil { + return nil, err + } + + dynamicNodeTemplate, err := nt.ntDynamicClient.Namespace(namespace.NodeTemplateGlobalNamespace).Get(context.TODO(), nodeTemplate.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + annotations := dynamicNodeTemplate.GetAnnotations() + // owner bindings annotation is meant to prevent bindings from being created again if they have been removed from creator + annotations[OwnerBindingsAnno] = "true" + dynamicNodeTemplate.SetAnnotations(annotations) + + if _, err = nt.ntDynamicClient.Namespace(namespace.NodeTemplateGlobalNamespace).Update(context.TODO(), dynamicNodeTemplate, metav1.UpdateOptions{}); err != nil { + return nil, err + } + + // if a migrations has been performed, then the original node template object has been deleted + if migratedTemplate { + return nil, nil + } + + return nt.ntClient.GetNamespaced(nodeTemplate.Namespace, nodeTemplate.Name, metav1.GetOptions{}) +} + +// migrateNodeTemplate creates duplicate of node template in the global node template namespace, creates new role bindings +// for duplicate, then deletes old node template +func (nt *nodeTemplateController) migrateNodeTemplate(ntDynamicClient dynamic.NamespaceableResourceInterface, nodeTemplate *v3.NodeTemplate) (*v3.NodeTemplate, error) { + logrus.Infof("migrating node template [%s]", nodeTemplate.Spec.DisplayName) + + migratedNTName := fmt.Sprintf("nt-%s-%s", nodeTemplate.Namespace, nodeTemplate.Name) + fullLegacyNTName := fmt.Sprintf("%s:%s", nodeTemplate.Namespace, nodeTemplate.Name) + fullMigratedNTName := fmt.Sprintf("%s:%s", namespace.NodeTemplateGlobalNamespace, migratedNTName) + + dynamicNodeTemplate, err := ntDynamicClient.Namespace(nodeTemplate.Namespace).Get(context.TODO(), nodeTemplate.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + if err := nt.createGlobalNodeTemplateClone(nodeTemplate.Name, migratedNTName, dynamicNodeTemplate, ntDynamicClient); err != nil { + return nil, err + } + + // update any node pools referencing old node template + if err := nt.reviseNodePoolNodeTemplate(fullMigratedNTName, fullLegacyNTName); err != nil { + return nil, err + } + + // update any nodes referencing old node template + if err := nt.reviseNodes(fullMigratedNTName, fullLegacyNTName); err != nil { + return nil, err + } + + // delete old node template + if err := nt.ntClient.DeleteNamespaced(nodeTemplate.Namespace, nodeTemplate.Name, &metav1.DeleteOptions{}); err != nil { + return nil, err + } + + logrus.Infof("successfully migrated node template [%s]", nodeTemplate.Spec.DisplayName) + return nt.ntClient.GetNamespaced(namespace.NodeTemplateGlobalNamespace, migratedNTName, metav1.GetOptions{}) +} + +// reviseNodes searches for nodePools that reference the old node template and replaces it with the new, global template +func (nt *nodeTemplateController) reviseNodePoolNodeTemplate(fullMigratedNTName, fullLegacyNTName string) error { + npList, err := nt.npLister.List("", labels.Everything()) + if err != nil { + return err + } + for _, np := range npList { + if np.Spec.NodeTemplateName == fullLegacyNTName { + npCopy := np.DeepCopy() + npCopy.Spec.NodeTemplateName = fullMigratedNTName + + if _, err := nt.npClient.Update(npCopy); err != nil { + return err + } + } + } + return nil +} + +// reviseNodes searches for nodes that reference the old node template and replaces it with the new, global template +func (nt *nodeTemplateController) reviseNodes(fullMigratedNTName, fullLegacyNTName string) error { + nodeList, err := nt.nodesLister.List("", labels.Everything()) + if err != nil { + return err + } + for _, node := range nodeList { + if node.Spec.NodeTemplateName == fullLegacyNTName { + nodeCopy := node.DeepCopy() + nodeCopy.Spec.NodeTemplateName = fullMigratedNTName + + if _, err := nt.nodeClient.Update(nodeCopy); err != nil { + return err + } + } + } + return nil +} + +// createGlobalNodeTemplateClone creates a global clone of the given legacy node template if it does not exist +func (nt *nodeTemplateController) createGlobalNodeTemplateClone(legacyName, cloneName string, dynamicNodeTemplate *unstructured.Unstructured, + client dynamic.NamespaceableResourceInterface) error { + if _, err := nt.ntClient.GetNamespaced(namespace.NodeTemplateGlobalNamespace, cloneName, metav1.GetOptions{}); err != nil { + if !errors.IsNotFound(err) { + return err + } + + globalNodeTemplate := dynamicNodeTemplate + + annotations := dynamicNodeTemplate.GetAnnotations() + labels := dynamicNodeTemplate.GetLabels() + globalNodeTemplate.Object["metadata"] = map[string]interface{}{ + "name": cloneName, + "namespace": namespace.NodeTemplateGlobalNamespace, + "annotations": annotations, + "labels": labels, + } + + vsphereLegacyNormalizer(globalNodeTemplate) + + if _, err = client.Namespace(namespace.NodeTemplateGlobalNamespace).Create(context.TODO(), globalNodeTemplate, metav1.CreateOptions{}); err != nil { + return err + } + } + + return nil +} + +/* +legacy vmwarevsphere nodetemplates were free form text fields +and this is an attempt to normalize the data to a valid vsphere path +e.g. "My Network" becomes "/DC_NAME/networks/My Network" +*/ +func vsphereLegacyNormalizer(nt *unstructured.Unstructured) { + spec, ok := nt.Object["spec"].(map[string]interface{}) + if !ok { + return + } + + driver, _ := spec["driver"] + if driver != vmwaredriver { + return + } + + k := vmwaredriver + "Config" + c, ok := nt.Object[k].(map[string]interface{}) + if !ok { + return + } + + dc, _ := c["datacenter"].(string) + if dc != "" && !strings.HasPrefix(dc, "/") { + dc = "/" + dc + c["datacenter"] = dc + } + + ds, _ := c["datastore"].(string) + if ds != "" && !strings.HasPrefix(ds, "/") { + c["datastore"] = fmt.Sprintf("%s/datastore/%s", dc, ds) + } + + nets, _ := c["network"].([]interface{}) + for i, net := range nets { + n := net.(string) + if n != "" && !strings.HasPrefix(n, "/") { + n = fmt.Sprintf("%s/network/%s", dc, n) + nets[i] = n + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/legacy_ownerrefs_cleaner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/legacy_ownerrefs_cleaner.go new file mode 100644 index 0000000..366b970 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/legacy_ownerrefs_cleaner.go @@ -0,0 +1,214 @@ +/* Following objects had Roles and RoleBindings with incorrect OwnerRefs prior to 2.4.6: +Cloud Credential (Secret representing a cloud credential) +Node Template +Cluster Template +Cluster Template Revision +Global DNS Entry +Global DNS Provider +Multi Cluster App +Multi Cluster App Revision + +this controller updates the ownerReferences on these roles and rolebindings to use the correct Kind/APIVersion fields +*/ + +package rbac + +import ( + "context" + + typesv1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + namespaces "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/util/retry" +) + +const ( + ownerRefUpdated = "auth.management.cattle.io/owner-ref-updated" +) + +type ownerRefCleaner struct { + roles v1.RoleInterface + roleBindings v1.RoleBindingInterface +} + +func Register(ctx context.Context, m *config.ManagementContext) { + o := ownerRefCleaner{ + roles: m.RBAC.Roles(""), + roleBindings: m.RBAC.RoleBindings(""), + } + o.roles.AddHandler(ctx, "legacy-role-ownerref-cleaner", o.roleSync) + o.roleBindings.AddHandler(ctx, "legacy-rolebinding-ownerref-cleaner", o.roleBindingSync) +} + +// roleSync updates roles for these resources that have incorrect ownerRefs +func (o *ownerRefCleaner) roleSync(key string, role *v1.Role) (runtime.Object, error) { + if role == nil || role.DeletionTimestamp != nil { + return nil, nil + } + if val, ok := role.Labels[ownerRefUpdated]; ok && val == "true" { + return nil, nil + } + // All these resources are either created in cattle-global-data ns, or in case of node templates in cattle-global-nt ns + if role.Namespace != namespaces.GlobalNamespace && role.Namespace != namespaces.NodeTemplateGlobalNamespace { + return nil, nil + } + if len(role.OwnerReferences) == 0 { + return nil, nil + } + + needsUpdate := correctOwnerRefs(&role.OwnerReferences) + if !needsUpdate { + return nil, nil + } + logrus.Infof("Updating ownerReferences of Role %v/%v", role.Namespace, role.Name) + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + roleToUpdate, updateErr := o.roles.GetNamespaced(role.Namespace, role.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + roleToUpdate.OwnerReferences = role.OwnerReferences + if roleToUpdate.Labels == nil { + roleToUpdate.Labels = make(map[string]string) + } + roleToUpdate.Labels[ownerRefUpdated] = "true" + _, err := o.roles.Update(roleToUpdate) + return err + }) + + return nil, retryErr +} + +// roleBindingSync updates roles for these resources that have incorrect ownerRefs +func (o *ownerRefCleaner) roleBindingSync(key string, roleBinding *v1.RoleBinding) (runtime.Object, error) { + if roleBinding == nil || roleBinding.DeletionTimestamp != nil { + return nil, nil + } + if val, ok := roleBinding.Labels[ownerRefUpdated]; ok && val == "true" { + return nil, nil + } + // All these resources are either created in cattle-global-data ns, or in case of node templates in cattle-global-nt ns + if roleBinding.Namespace != namespaces.GlobalNamespace && roleBinding.Namespace != namespaces.NodeTemplateGlobalNamespace { + return nil, nil + } + if len(roleBinding.OwnerReferences) == 0 { + return nil, nil + } + + needsUpdate := correctOwnerRefs(&roleBinding.OwnerReferences) + if !needsUpdate { + return nil, nil + } + + logrus.Infof("Updating ownerReferences of RoleBinding %v/%v", roleBinding.Namespace, roleBinding.Name) + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + rbToUpdate, updateErr := o.roleBindings.GetNamespaced(roleBinding.Namespace, roleBinding.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + rbToUpdate.OwnerReferences = roleBinding.OwnerReferences + if rbToUpdate.Labels == nil { + rbToUpdate.Labels = make(map[string]string) + } + rbToUpdate.Labels[ownerRefUpdated] = "true" + _, err := o.roleBindings.Update(rbToUpdate) + return err + }) + + return nil, retryErr +} + +func correctOwnerRefs(ownerReferences *[]metav1.OwnerReference) bool { + var needsUpdate bool + for ind, ownerRef := range *ownerReferences { + switch ownerRef.Kind { + case "secrets": + /* Cloud credentials (represented by a Secret) had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: v1 + kind: secrets + name: cc-q56qf + uid: 709d1cb7-a4a6-422d-8887-d330f977ac49 + Only the kind field is incorrect, need to change it to "Secret"*/ + ownerRef.Kind = typesv1.SecretResource.Kind + needsUpdate = true + case "nodetemplates": + /* Node Templates had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: nodetemplates + name: nt-6wclz + uid: fcd6be81-0368-4e0b-a511-705c2bae4d82 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.NodeTemplateGroupVersionKind.Kind + needsUpdate = true + case "clustertemplates": + /* Cluster Templates had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: clustertemplates + name: ct-8thxx + uid: a09f047d-f78e-4895-8848-0d12088435d1 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.ClusterTemplateGroupVersionKind.Kind + needsUpdate = true + case "clustertemplaterevisions": + /* Cluster Template Revisions had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: clustertemplaterevisions + name: ctr-98ks7 + uid: a1f5a67f-44bc-4011-aec6-d40ccfe12442 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.ClusterTemplateRevisionGroupVersionKind.Kind + needsUpdate = true + case "globaldnses": + /* Global DNS entries had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: globaldnses + name: gd-s82dh + uid: 3ecf8b69-525b-4a11-85a9-e34cae71f761 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.GlobalDnsGroupVersionKind.Kind + needsUpdate = true + case "globaldnsproviders": + /* Global DNS providers had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: globaldnsproviders + name: rajashree-test + uid: 1e1775da-1eb2-4d9b-99d6-9020f7357ee2 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.GlobalDnsProviderGroupVersionKind.Kind + needsUpdate = true + case "multiclusterapps": + /* Multi Cluster Apps had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: multiclusterapps + name: wp + uid: fe24c360-d35d-48f6-8295-9a66fdefac79 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.MultiClusterAppGroupVersionKind.Kind + needsUpdate = true + case "multiclusterapprevisions": + /* Multi Cluster Revisions had a Role & RoleBinding created for them with this ownerRef format: + - apiVersion: management.cattle.io + kind: multiclusterapprevisions + name: mcapprevision-mbh68 + uid: f0c30e41-dbe0-4057-8fac-760b0d8f54e1 + The APIVersion and Kind both fields are incorrect*/ + ownerRef.APIVersion = RancherManagementAPIVersion + ownerRef.Kind = v3.MultiClusterAppRevisionGroupVersionKind.Kind + needsUpdate = true + } + (*ownerReferences)[ind] = ownerRef + } + return needsUpdate +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/rbac.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/rbac.go new file mode 100644 index 0000000..407030c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rbac/rbac.go @@ -0,0 +1,317 @@ +package rbac + +import ( + "fmt" + "reflect" + "sort" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/types/config" + k8srbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apiserver/pkg/authentication/user" +) + +const ( + OwnerAccess = "owner" + MemberAccess = "member" + ReadOnlyAccess = "read-only" + MultiClusterAppResource = "multiclusterapps" + MultiClusterAppRevisionResource = "multiclusterapprevisions" + GlobalDNSResource = "globaldnses" + GlobalDNSProviderResource = "globaldnsproviders" + ClusterTemplateResource = "clustertemplates" + ClusterTemplateRevisionResource = "clustertemplaterevisions" + CloudCredentialResource = "secrets" + CreatorIDAnn = "field.cattle.io/creatorId" + RancherManagementAPIVersion = "management.cattle.io/v3" + RancherManagementAPIGroup = "management.cattle.io" + NodeTemplateResource = "nodetemplates" +) + +var subjectWithAllUsers = k8srbacv1.Subject{ + Kind: "Group", + Name: user.AllAuthenticated, + APIGroup: rbacv1.GroupName, +} + +func CreateRoleAndRoleBinding(resource, kind, name, namespace, apiVersion, creatorID string, apiGroup []string, UID types.UID, members []v32.Member, + mgmt *config.ManagementContext) error { + /* Create 3 Roles containing the CRD, and the current CR in resourceNames list + 1. Role with owner verbs (Owner access, includes creator); name multiclusterapp.Name + "-ma" / (globalDNS.Name + "-ga") + 2. Role with "get", "list" "watch" verbs (ReadOnly access); name multiclusterapp.Name + "-mr" / (globalDNS.Name + "-gr") + 3. Role with "update" verb (Member access); name multiclusterapp.Name + "-mu" / (globalDNS.Name + "-gu") + */ + + if _, err := createRole(resource, kind, name, namespace, OwnerAccess, apiVersion, apiGroup, UID, mgmt); err != nil { + return err + } + + // Create a roleBinding referring the role with everything access, and containing creator of the resource, along with + // any members that have everything access + var ownerAccessSubjects, readOnlyAccessSubjects, memberAccessSubjects []k8srbacv1.Subject + ownerAccessSubjects = append(ownerAccessSubjects, k8srbacv1.Subject{Kind: "User", Name: creatorID, APIGroup: rbacv1.GroupName}) + for _, m := range members { + s, err := buildSubjectForMember(m, mgmt) + if err != nil { + return err + } + switch m.AccessType { + case OwnerAccess: + ownerAccessSubjects = append(ownerAccessSubjects, s) + case MemberAccess: + memberAccessSubjects = append(memberAccessSubjects, s) + case ReadOnlyAccess: + readOnlyAccessSubjects = append(readOnlyAccessSubjects, s) + default: + if resource == GlobalDNSProviderResource || resource == GlobalDNSResource { + // since these two resources only have one access type "owner" for their members + ownerAccessSubjects = append(ownerAccessSubjects, s) + } else { + // for mcapp and cluster templates which can have other access types + readOnlyAccessSubjects = append(readOnlyAccessSubjects, s) + } + } + } + + // There will always be a role and rolebinding for owner access (admin) + if err := createRoleBindingForMembers(resource, kind, name, namespace, OwnerAccess, apiVersion, UID, ownerAccessSubjects, mgmt); err != nil { + return err + } + + // Check if there are members with readonly or member(update) access; if found then create rolebindings for those + if len(readOnlyAccessSubjects) > 0 { + if _, err := createRole(resource, kind, name, namespace, ReadOnlyAccess, apiVersion, apiGroup, UID, mgmt); err != nil { + return err + } + if err := createRoleBindingForMembers(resource, kind, name, namespace, ReadOnlyAccess, apiVersion, UID, readOnlyAccessSubjects, mgmt); err != nil { + return err + } + } else { + // check if rolebinding for read-only access exists, if it does then delete it, since there are no longer + // any read-only members in the spec. + roleName, _ := GetRoleNameAndVerbs(ReadOnlyAccess, name, resource) + if err := deleteRoleAndRoleBinding(roleName, namespace, mgmt); err != nil { + return err + } + } + + if len(memberAccessSubjects) > 0 { + if _, err := createRole(resource, kind, name, namespace, MemberAccess, apiVersion, apiGroup, UID, mgmt); err != nil { + return err + } + if err := createRoleBindingForMembers(resource, kind, name, namespace, MemberAccess, apiVersion, UID, memberAccessSubjects, mgmt); err != nil { + return err + } + } else { + // check if rolebinding for member access (update access type) exists, if it does then delete it, + // since there are no longer any members with update access in the spec. + roleName, _ := GetRoleNameAndVerbs(MemberAccess, name, resource) + return deleteRoleAndRoleBinding(roleName, namespace, mgmt) + } + return nil +} + +func createRole(resourceType, resourceKind, resourceName, namespace, roleAccess, apiVersion string, apiGroups []string, resourceUID types.UID, + mgmt *config.ManagementContext) (*k8srbacv1.Role, error) { + roleName, verbs := GetRoleNameAndVerbs(roleAccess, resourceName, resourceType) + ownerReference := metav1.OwnerReference{ + APIVersion: apiVersion, + Kind: resourceKind, + Name: resourceName, + UID: resourceUID, + } + newRole := &k8srbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ownerReference}, + }, + Rules: []k8srbacv1.PolicyRule{ + { + APIGroups: apiGroups, + Resources: []string{resourceType}, + ResourceNames: []string{resourceName}, + Verbs: verbs, + }, + }, + } + role, err := mgmt.RBAC.Roles("").Controller().Lister().Get(namespace, roleName) + if err != nil { + if apierrors.IsNotFound(err) { + role, err = mgmt.RBAC.Roles("").Create(newRole) + if err != nil { + return nil, err + } + } else { + return nil, err + } + } else if role != nil { + if !reflect.DeepEqual(newRole.Rules, role.Rules) { + toUpdate := newRole.DeepCopy() + updated, err := mgmt.RBAC.Roles("").Update(toUpdate) + if err != nil { + return updated, err + } + } + } + return role, nil +} + +func createRoleBindingForMembers(resourceType, resourceKind, resourceName, namespace, roleAccess, apiVersion string, UID types.UID, + subjects []k8srbacv1.Subject, mgmt *config.ManagementContext) error { + roleName, _ := GetRoleNameAndVerbs(roleAccess, resourceName, resourceType) + // we can define the rolebinding first, since if it's not already present we can call create. And if it's present then we'll + // still need to compare the current members' list + sort.Slice(subjects, func(i, j int) bool { return subjects[i].Name < subjects[j].Name }) + return createRoleBinding(resourceKind, resourceName, namespace, roleName, apiVersion, mgmt, UID, subjects) +} + +func createRoleBinding(resourceKind, resourceName, namespace, roleName, apiVersion string, mgmt *config.ManagementContext, + resourceUID types.UID, subjects []k8srbacv1.Subject) error { + ownerReference := metav1.OwnerReference{ + APIVersion: apiVersion, + Kind: resourceKind, + Name: resourceName, + UID: resourceUID, + } + newRoleBinding := &k8srbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ownerReference}, + }, + RoleRef: k8srbacv1.RoleRef{ + Name: roleName, + Kind: "Role", + }, + Subjects: subjects, + } + + roleBinding, err := mgmt.RBAC.RoleBindings("").Controller().Lister().Get(namespace, roleName) + if err != nil { + if apierrors.IsNotFound(err) { + _, err = mgmt.RBAC.RoleBindings("").Create(newRoleBinding) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else { + return err + } + } else if roleBinding != nil { + if !reflect.DeepEqual(roleBinding.Subjects, newRoleBinding.Subjects) { + toUpdate := newRoleBinding.DeepCopy() + _, err := mgmt.RBAC.RoleBindings("").Update(toUpdate) + if err != nil { + return err + } + } + } + return nil +} + +func GetRoleNameAndVerbs(roleAccess string, resourceName string, resourceType string) (string, []string) { + var roleName string + var verbs []string + + switch resourceType { + case MultiClusterAppResource: + resourceName += "-m-" + case MultiClusterAppRevisionResource: + resourceName += "-mr-" + case GlobalDNSResource: + resourceName += "-g-" + case GlobalDNSProviderResource: + resourceName += "-gp-" + case ClusterTemplateResource: + resourceName += "-ct-" + case ClusterTemplateRevisionResource: + resourceName += "-ctr-" + case NodeTemplateResource: + resourceName += "-nt-" + default: + resourceName += "-" + resourceType + "-" + } + switch roleAccess { + case OwnerAccess: + roleName = resourceName + "a" + verbs = []string{"*"} + case MemberAccess: + roleName = resourceName + "u" + verbs = []string{"update", "get", "list", "watch"} + case ReadOnlyAccess: + roleName = resourceName + "r" + verbs = []string{"get", "list", "watch"} + } + + return roleName, verbs +} + +func deleteRoleAndRoleBinding(roleName, namespace string, mgmt *config.ManagementContext) error { + err := mgmt.RBAC.Roles("").DeleteNamespaced(namespace, roleName, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return err + } + err = mgmt.RBAC.RoleBindings("").DeleteNamespaced(namespace, roleName, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return err + } + return nil +} + +func buildSubjectForMember(member v32.Member, managementContext *config.ManagementContext) (k8srbacv1.Subject, error) { + var name, kind string + member, err := checkAndSetUserFields(member, managementContext) + if err != nil { + return k8srbacv1.Subject{}, err + } + + if member.UserName != "" { + name = member.UserName + kind = "User" + } + + if member.GroupPrincipalName != "" { + if name != "" { + return k8srbacv1.Subject{}, fmt.Errorf("member %v has both username and groupPrincipalId set", member) + } + name = member.GroupPrincipalName + kind = "Group" + } + + if name == "" { + return k8srbacv1.Subject{}, fmt.Errorf("member %v doesn't have any name fields set", member) + } + + if name == "*" { + // member.GroupPrincipalName = subjectWithAllUsers.Name + return subjectWithAllUsers, nil + } + + return k8srbacv1.Subject{ + Kind: kind, + Name: name, + APIGroup: rbacv1.GroupName, + }, nil +} + +func checkAndSetUserFields(m v32.Member, managementContext *config.ManagementContext) (v32.Member, error) { + if m.GroupPrincipalName != "" || (m.UserPrincipalName != "" && m.UserName != "") { + return m, nil + } + if m.UserPrincipalName != "" && m.UserName == "" { + displayName := m.DisplayName + user, err := managementContext.UserManager.EnsureUser(m.UserPrincipalName, displayName) + if err != nil { + return m, err + } + + m.UserName = user.Name + return m, nil + } + return m, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster.go new file mode 100644 index 0000000..e62ea75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster.go @@ -0,0 +1,124 @@ +package restrictedadminrbac + +import ( + "errors" + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +// clusterOwnerSync ensures that the given enqueued GRB has a cluster-owner CRTB in all downstream clusters iff the role is GlobalRestrictedAdmin. +func (r *rbaccontroller) clusterOwnerSync(_ string, grb *v3.GlobalRoleBinding) (runtime.Object, error) { + if grb == nil || grb.DeletionTimestamp != nil || grb.GlobalRoleName != rbac.GlobalRestrictedAdmin { + return nil, nil + } + clusters, err := r.clusterCache.List(labels.Everything()) + if err != nil { + return nil, fmt.Errorf("failed to list clusters: %w", err) + } + var retError error + for _, cluster := range clusters { + if cluster.Name == "local" { + // do not sync to the local cluster + continue + } + crtbName := name.SafeConcatName(rbac.GetGRBTargetKey(grb), "restricted-admin", "cluster-owner") + _, err := r.crtbCache.Get(cluster.Name, crtbName) + if err != nil && !apierrors.IsNotFound(err) { + retError = errors.Join(retError, fmt.Errorf("failed to get CRTB '%s' from cache: %w", crtbName, err)) + continue + } + if err == nil { + // CRTB was already created. + // we do not need to check for equivalence between the current CRTB and the desired CRTB + // this is because the fields we care about can not be modified + continue + } + + // add the restricted admin user as a member of the downstream cluster + // by creating a CRTB in the local custer in the namespace named after the downstream cluster. + crtb := v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crtbName, + Namespace: cluster.Name, + Labels: map[string]string{sourceKey: grbHandlerName}, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: grb.APIVersion, + Kind: grb.Kind, + Name: grb.Name, + UID: grb.UID, + }, + }, + }, + ClusterName: cluster.Name, + RoleTemplateName: "cluster-owner", + } + + // CRTBs must contain either user or group information but not both. + // we will attempt to first use the userName then if not assign the groupName. + if grb.UserName != "" { + crtb.UserName = grb.UserName + } else { + crtb.GroupPrincipalName = grb.GroupPrincipalName + } + + _, err = r.crtbCtrl.Create(&crtb) + if err != nil && !apierrors.IsAlreadyExists(err) { + retError = errors.Join(retError, fmt.Errorf("failed to create a CRTB '%s': %w", crtbName, err)) + continue + } + } + return nil, retError +} + +// enqueueGrbOnCRTB returns a resolver which provides the key to the GRBs that owns a given CRTB if one exist. +func (r *rbaccontroller) enqueueGrbOnCRTB(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + crtb, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok || crtb == nil { + return nil, nil + } + + var grbOwner []*metav1.OwnerReference + for i := range crtb.OwnerReferences { + ref := &crtb.OwnerReferences[i] + if ref.Kind == "GlobalRoleBinding" && ref.APIVersion == v3.SchemeGroupVersion.String() { + grbOwner = append(grbOwner, ref) + } + } + + if grbOwner == nil { + // there are no owner references to GlobalRoleBindings + return nil, nil + } + + keys := make([]relatedresource.Key, 0, len(grbOwner)) + for _, owner := range grbOwner { + grb, err := r.grbCache.Get(owner.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, nil + } + return nil, fmt.Errorf("failed to get owner reference '%s' from cache: %w", owner.Name, err) + } + keys = append(keys, relatedresource.Key{Name: grb.Name}) + } + + return keys, nil +} + +// enqueueGrbOnCluster returns a resolver which provides the keys to all restrictedAdminGRBs. +func (r *rbaccontroller) enqueueGrbOnCluster(_, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + cluster, ok := obj.(*v3.Cluster) + if !ok || cluster == nil || cluster.DeletionTimestamp != nil || cluster.Name == "local" { + return nil, nil + } + return r.getRestrictedAdminGRBs() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster_test.go new file mode 100644 index 0000000..923b883 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/cluster_test.go @@ -0,0 +1,469 @@ +// mocks created with the following commands +// mockgen --build_flags=--mod=mod -package restrictedadminrbac -destination ./mockIndexer_test.go k8s.io/client-go/tools/cache Indexer +package restrictedadminrbac + +import ( + "errors" + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var errExpected = errors.New("expected error") + +func Test_rbaccontroller_clusterOwnerSync(t *testing.T) { + localCluster := &v3.Cluster{} + localCluster.Name = "local" + downstream1 := &v3.Cluster{} + downstream1.Name = "down1" + downstream2 := &v3.Cluster{} + downstream2.Name = "down2" + + baseGrb := &v3.GlobalRoleBinding{} + baseGrb.Name = "baseGRB" + baseGrb.GlobalRoleName = rbac.GlobalRestrictedAdmin + baseGrb.APIVersion = "api/version" + baseGrb.Kind = "CoolKind" + baseGrb.UID = "123" + baseGrb.UserName = "user32" + baseGrb.GroupPrincipalName = "group29" + + groupCrtb := &v3.GlobalRoleBinding{} + *groupCrtb = *baseGrb + groupCrtb.UserName = "" + + tests := []struct { + name string + setup func(*mockController) + grb *v3.GlobalRoleBinding + wantErr bool + }{ + { + name: "New Restricted Admin valid CRTB", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1}, nil) + mc.mockCRTBCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).DoAndReturn(func(newCrtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + require.Equal(mc.t, newCrtb.OwnerReferences[0].APIVersion, baseGrb.APIVersion) + require.Equal(mc.t, newCrtb.OwnerReferences[0].Kind, baseGrb.Kind) + require.Equal(mc.t, newCrtb.OwnerReferences[0].Name, baseGrb.Name) + require.Equal(mc.t, newCrtb.OwnerReferences[0].UID, baseGrb.UID) + require.Equal(mc.t, newCrtb.RoleTemplateName, "cluster-owner") + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + require.Equal(mc.t, newCrtb.Namespace, downstream1.Name) + require.Equal(mc.t, newCrtb.Labels, map[string]string{sourceKey: grbHandlerName}) + require.Equal(mc.t, newCrtb.UserName, baseGrb.UserName) + require.Equal(mc.t, newCrtb.UserPrincipalName, "") + require.Equal(mc.t, newCrtb.GroupName, "") + require.Equal(mc.t, newCrtb.GroupPrincipalName, "") + return newCrtb, nil + }) + }, + }, + { + name: "skip local cluster", + grb: groupCrtb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1, localCluster}, nil) + mc.mockCRTBCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).DoAndReturn(func(newCrtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + require.Equal(mc.t, newCrtb.OwnerReferences[0].APIVersion, baseGrb.APIVersion) + require.Equal(mc.t, newCrtb.OwnerReferences[0].Kind, baseGrb.Kind) + require.Equal(mc.t, newCrtb.OwnerReferences[0].Name, baseGrb.Name) + require.Equal(mc.t, newCrtb.OwnerReferences[0].UID, baseGrb.UID) + require.Equal(mc.t, newCrtb.RoleTemplateName, "cluster-owner") + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + require.Equal(mc.t, newCrtb.Namespace, downstream1.Name) + require.Equal(mc.t, newCrtb.Labels, map[string]string{sourceKey: grbHandlerName}) + require.Equal(mc.t, newCrtb.UserName, "") + require.Equal(mc.t, newCrtb.UserPrincipalName, "") + require.Equal(mc.t, newCrtb.GroupName, "") + require.Equal(mc.t, newCrtb.GroupPrincipalName, baseGrb.GroupPrincipalName) + return newCrtb, nil + }) + }, + }, + { + name: "handle multiple cluster", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1, localCluster, downstream2}, nil) + mc.mockCRTBCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")).Times(2) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).DoAndReturn(func(newCrtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + if newCrtb.ClusterName != downstream1.Name && newCrtb.ClusterName != downstream2.Name { + require.FailNowf(mc.t, "Unknown cluster name for CRTB '%s'", newCrtb.ClusterName) + } + return newCrtb, nil + }).Times(2) + }, + }, + { + name: "CRTB already created", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1}, nil) + mc.mockCRTBCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, nil) + }, + }, + { + name: "One CRTB already created one not found", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1, downstream2}, nil) + mc.mockCRTBCache.EXPECT().Get(downstream1.Name, gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + mc.mockCRTBCache.EXPECT().Get(downstream2.Name, gomock.Any()).Return(nil, nil) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).DoAndReturn(func(newCrtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + return newCrtb, nil + }) + }, + }, + { + name: "Nil Object", + grb: nil, + setup: func(mc *mockController) {}, + }, + { + name: "Non restricted-admin GRB", + grb: &v3.GlobalRoleBinding{}, + setup: func(mc *mockController) {}, + }, + { + name: "List Error", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return(nil, errExpected) + }, + wantErr: true, + }, + { + name: "CRTB Cache Error", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1}, nil) + mc.mockCRTBCache.EXPECT().Get(downstream1.Name, gomock.Any()).Return(nil, errExpected) + }, + wantErr: true, + }, + { + name: "Create error", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream1}, nil) + mc.mockCRTBCache.EXPECT().Get(downstream1.Name, gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).Return(nil, errExpected) + }, + wantErr: true, + }, + { + name: "One Error One Create", + grb: baseGrb, + setup: func(mc *mockController) { + mc.mockClusterCache.EXPECT().List(gomock.Any()).Return([]*v3.Cluster{downstream2, downstream1}, nil) + mc.mockCRTBCache.EXPECT().Get(downstream1.Name, gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + mc.mockCRTBCache.EXPECT().Get(downstream2.Name, gomock.Any()).Return(nil, errExpected) + mc.mockCRTBCtrl.EXPECT().Create(gomock.Any()).DoAndReturn(func(newCrtb *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + require.Equal(mc.t, newCrtb.ClusterName, downstream1.Name) + return newCrtb, nil + }) + }, + wantErr: true, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + mockCtrl := newMockController(t) + tt.setup(mockCtrl) + r := mockCtrl.rbacController() + _, err := r.clusterOwnerSync("", tt.grb) + + if tt.wantErr { + require.Error(t, err, "Expected an error from clusterOwnerSync") + return + } + require.NoError(t, err, "Unexpected error from clusterOwnerSync") + }) + } +} + +func Test_enqueueGrbOnCRTB(t *testing.T) { + testGrb := &v3.GlobalRoleBinding{} + testGrb2 := &v3.GlobalRoleBinding{} + testGrb.Name = "test-grb" + testGrb2.Name = "test-grb2" + + baseCRTB := v3.ClusterRoleTemplateBinding{} + baseCRTB.Name = "baseCrtb" + + tests := []struct { + name string + setup func(*mockController) + crtb func() runtime.Object + wantErr bool + wantKeys []relatedresource.Key + }{ + { + name: "restricted-admin owner", + setup: func(mc *mockController) { + mc.mockGRBCache.EXPECT().Get(testGrb.Name).Return(testGrb, nil) + }, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: testGrb.Name, + }, + } + return &ret + }, + wantKeys: []relatedresource.Key{{Name: testGrb.Name}}, + }, + { + name: "wrong group version", + setup: func(mc *mockController) {}, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "v3", + Kind: "GlobalRoleBinding", + Name: testGrb.Name, + }, + } + return &ret + }, + }, + { + name: "wrong kind", + setup: func(mc *mockController) {}, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "RoleTemplate", + Name: testGrb.Name, + }, + } + return &ret + }, + }, + { + name: "multiple owners", + setup: func(mc *mockController) { + mc.mockGRBCache.EXPECT().Get(testGrb.Name).Return(testGrb, nil) + mc.mockGRBCache.EXPECT().Get(testGrb2.Name).Return(testGrb2, nil) + }, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: testGrb.Name, + }, + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: testGrb2.Name, + }, + } + return &ret + }, + wantKeys: []relatedresource.Key{{Name: testGrb.Name}, {Name: testGrb2.Name}}, + }, + { + name: "failed to get GRB", + setup: func(mc *mockController) { + mc.mockGRBCache.EXPECT().Get(testGrb.Name).Return(nil, errExpected) + }, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: testGrb.Name, + }, + } + return &ret + }, + wantErr: true, + }, + { + name: "GRB not found", + setup: func(mc *mockController) { + mc.mockGRBCache.EXPECT().Get(testGrb.Name).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "")) + }, + crtb: func() runtime.Object { + ret := baseCRTB + ret.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRoleBinding", + Name: testGrb.Name, + }, + } + return &ret + }, + }, + { + name: "object not a CRTB", + setup: func(mc *mockController) {}, + crtb: func() runtime.Object { + return &v3.ProjectRoleTemplateBinding{} + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + mockCtrl := newMockController(t) + tt.setup(mockCtrl) + r := mockCtrl.rbacController() + keys, err := r.enqueueGrbOnCRTB("", "", tt.crtb()) + if tt.wantErr { + require.Error(t, err, "Expected an error from enqueueGrbOnCRTB") + return + } + require.NoError(t, err, "Unexpected error from enqueueGrbOnCRTB") + require.Equal(t, tt.wantKeys, keys, "incorrect related keys returned") + }) + } +} + +func Test_enqueueGrbOnCluster(t *testing.T) { + testGrb := &v3.GlobalRoleBinding{} + testGrb2 := &v3.GlobalRoleBinding{} + testGrb.Name = "test-grb" + testGrb2.Name = "test-grb2" + + localCluster := &v3.Cluster{} + localCluster.Name = "local" + downstream1 := &v3.Cluster{} + downstream1.Name = "down1" + deletedCluster := &v3.Cluster{} + deletedCluster.Name = "deleted" + deletedCluster.DeletionTimestamp = &v1.Time{} + + tests := []struct { + name string + setup func(*mockController) + cluster runtime.Object + wantErr bool + wantKeys []relatedresource.Key + }{ + { + name: "downstream cluster changed", + setup: func(mc *mockController) { + mc.mockIndexer.EXPECT().ByIndex(grbByRoleIndex, rbac.GlobalRestrictedAdmin).Return([]any{testGrb, testGrb2}, nil) + }, + cluster: downstream1, + wantKeys: []relatedresource.Key{{Name: testGrb.Name}, {Name: testGrb2.Name}}, + }, + { + name: "failed to get grbs", + setup: func(mc *mockController) { + mc.mockIndexer.EXPECT().ByIndex(grbByRoleIndex, rbac.GlobalRestrictedAdmin).Return(nil, errExpected) + }, + cluster: downstream1, + wantErr: true, + }, + { + name: "local cluster changed", + setup: func(mc *mockController) { + }, + cluster: localCluster, + }, + { + name: "non cluster object given", + setup: func(mc *mockController) {}, + cluster: testGrb, + }, + { + name: "nil cluster given", + setup: func(mc *mockController) {}, + cluster: nil, + }, + { + name: "cluster is being deleted", + setup: func(mc *mockController) {}, + cluster: deletedCluster, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + mockCtrl := newMockController(t) + tt.setup(mockCtrl) + r := mockCtrl.rbacController() + keys, err := r.enqueueGrbOnCluster("", "", tt.cluster) + if tt.wantErr { + require.Error(t, err, "Expected an error from enqueueGrbOnCluster") + return + } + require.NoError(t, err, "Unexpected error from enqueueGrbOnCluster") + require.Equal(t, tt.wantKeys, keys, "incorrect related keys returned") + }) + } +} + +func newMockController(t *testing.T) *mockController { + t.Helper() + ctrl := gomock.NewController(t) + clusterCache := fake.NewMockNonNamespacedCacheInterface[*v3.Cluster](ctrl) + crtbCache := fake.NewMockCacheInterface[*v3.ClusterRoleTemplateBinding](ctrl) + crtbCtrl := fake.NewMockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList](ctrl) + grbCache := fake.NewMockNonNamespacedCacheInterface[*v3.GlobalRoleBinding](ctrl) + grbIndexer := NewMockIndexer(ctrl) + return &mockController{ + t: t, + mockIndexer: grbIndexer, + mockClusterCache: clusterCache, + mockCRTBCache: crtbCache, + mockCRTBCtrl: crtbCtrl, + mockGRBCache: grbCache, + } +} + +type mockController struct { + t *testing.T + mockIndexer *MockIndexer + mockClusterCache *fake.MockNonNamespacedCacheInterface[*v3.Cluster] + mockCRTBCache *fake.MockCacheInterface[*v3.ClusterRoleTemplateBinding] + mockCRTBCtrl *fake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList] + mockGRBCache *fake.MockNonNamespacedCacheInterface[*v3.GlobalRoleBinding] + mockRBInterface *fakes.RoleBindingInterfaceMock + mockRBLister *fakes.RoleBindingListerMock +} + +func (m *mockController) rbacController() *rbaccontroller { + return &rbaccontroller{ + grbIndexer: m.mockIndexer, + clusterCache: m.mockClusterCache, + crtbCache: m.mockCRTBCache, + crtbCtrl: m.mockCRTBCtrl, + grbCache: m.mockGRBCache, + roleBindings: m.mockRBInterface, + rbLister: m.mockRBLister, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet.go new file mode 100644 index 0000000..8902372 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet.go @@ -0,0 +1,110 @@ +package restrictedadminrbac + +import ( + "errors" + "fmt" + "reflect" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + fleetconst "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + k8srbac "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +func (r *rbaccontroller) enqueueGrb(namespace, _ string, obj runtime.Object) ([]relatedresource.Key, error) { + if fw, ok := obj.(*v3.FleetWorkspace); !ok || fw.Name == fleetconst.ClustersLocalNamespace { + return nil, nil + } + + return r.getRestrictedAdminGRBs() +} + +func (r *rbaccontroller) ensureRestricedAdminForFleet(key string, obj *v3.GlobalRoleBinding) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + if obj.GlobalRoleName != rbac.GlobalRestrictedAdmin { + return obj, nil + } + + fleetworkspaces, err := r.fleetworkspaces.Controller().Lister().List("", labels.Everything()) + if err != nil { + return obj, nil + } + + var finalError error + for _, fw := range fleetworkspaces { + if fw.Name == fleetconst.ClustersLocalNamespace { + continue + } + err := r.ensureRolebinding(fw.Name, rbac.GetGRBSubject(obj), obj) + finalError = errors.Join(finalError, err) + } + return obj, finalError +} + +func (r *rbaccontroller) ensureRolebinding(namespace string, subject k8srbac.Subject, grb *v3.GlobalRoleBinding) error { + name := fmt.Sprintf("%s-fleetworkspace-%s", grb.Name, rbac.RestrictedAdminClusterRoleBinding) + ownerRefs := []metav1.OwnerReference{ + { + APIVersion: grb.TypeMeta.APIVersion, + Kind: grb.TypeMeta.Kind, + UID: grb.UID, + Name: grb.Name, + }, + } + roleRef := k8srbac.RoleRef{ + Name: "fleetworkspace-admin", + Kind: "ClusterRole", + } + subjects := []k8srbac.Subject{ + subject, + } + + rb, err := r.rbLister.Get(namespace, name) + if err != nil { + if !k8serrors.IsNotFound(err) { + // list call failed for unknown reason, give up + return fmt.Errorf("unable to list backing role %s/%s: %w", namespace, name, err) + } + + // role binding not found, create it + _, err = r.roleBindings.Create(&k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{rbac.RestrictedAdminClusterRoleBinding: "true"}, + OwnerReferences: ownerRefs, + }, + RoleRef: roleRef, + Subjects: subjects, + }) + if err != nil && !k8serrors.IsAlreadyExists(err) { + return fmt.Errorf("unable to create backing role %s/%s: %w", namespace, name, err) + } + return nil + } + + // role binding found, possibly in dirty state. Make sure relevant fields are set right + label, ok := rb.Labels[rbac.RestrictedAdminClusterRoleBinding] + if !ok || label != "true" || + !reflect.DeepEqual(rb.OwnerReferences, ownerRefs) || + !reflect.DeepEqual(rb.RoleRef, roleRef) || + !reflect.DeepEqual(rb.Subjects, subjects) { + + rb.Labels[rbac.RestrictedAdminClusterRoleBinding] = "true" + rb.OwnerReferences = ownerRefs + rb.RoleRef = roleRef + rb.Subjects = subjects + + _, err = r.roleBindings.Update(rb) + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet_test.go new file mode 100644 index 0000000..ab21415 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/fleet_test.go @@ -0,0 +1,279 @@ +package restrictedadminrbac + +import ( + "strings" + "testing" + + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/rancher/rancher/pkg/rbac" + "github.com/stretchr/testify/assert" + k8srbac "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_rbaccontroller_ensureRolebinding(t *testing.T) { + namespace := "fleet-default" + subject := k8srbac.Subject{ + Kind: "User", + Name: "TestUser", + Namespace: "", + } + grb := &v3.GlobalRoleBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: "GlobalRoleBinding", + APIVersion: "management.cattle.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testGrb", + Namespace: "testNamespace", + UID: "1234", + }, + UserName: subject.Name, + GroupPrincipalName: "", + GlobalRoleName: "", + } + name := grb.Name + "-fleetworkspace-" + rbac.RestrictedAdminClusterRoleBinding + ownerRefs := []metav1.OwnerReference{ + { + APIVersion: grb.TypeMeta.APIVersion, + Kind: grb.TypeMeta.Kind, + UID: grb.UID, + Name: grb.Name, + }, + } + roleRef := k8srbac.RoleRef{ + Name: "fleetworkspace-admin", + Kind: "ClusterRole", + } + subjects := []k8srbac.Subject{ + subject, + } + expected := &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{rbac.RestrictedAdminClusterRoleBinding: "true"}, + OwnerReferences: ownerRefs, + }, + RoleRef: roleRef, + Subjects: subjects, + } + + tests := []struct { + name string + setup func(*mockController) + wantErr bool + expectedErr string + }{ + { + name: "no previously existing rolebinding", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return nil, &k8serrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonNotFound}} + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + CreateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + assert.Equal(c.t, rb, expected) + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "one previously existing incorrect rolebinding (wrong Labels)", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{}, + OwnerReferences: ownerRefs, + }, + RoleRef: roleRef, + Subjects: subjects, + }, nil + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + UpdateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + assert.Equal(c.t, rb, expected) + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "one previously existing incorrect rolebinding (wrong OwnerReferences)", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{rbac.RestrictedAdminClusterRoleBinding: "true"}, + OwnerReferences: []metav1.OwnerReference{}, + }, + RoleRef: roleRef, + Subjects: subjects, + }, nil + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + UpdateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + assert.Equal(c.t, rb, expected) + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "one previously existing incorrect rolebinding (wrong RoleRef)", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{rbac.RestrictedAdminClusterRoleBinding: "true"}, + OwnerReferences: ownerRefs, + }, + RoleRef: k8srbac.RoleRef{}, + Subjects: subjects, + }, nil + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + UpdateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + assert.Equal(c.t, rb, expected) + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "one previously existing incorrect rolebinding (wrong Subjects)", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{rbac.RestrictedAdminClusterRoleBinding: "true"}, + OwnerReferences: ownerRefs, + }, + RoleRef: roleRef, + Subjects: []k8srbac.Subject{}, + }, nil + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + UpdateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + assert.Equal(c.t, rb, expected) + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "one previously existing correct rolebinding", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return expected, nil + }, + } + }, + wantErr: false, + }, + { + name: "unexpected error in Get call", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return nil, errors.New("Unexpected error ABC") + }, + } + }, + wantErr: true, + expectedErr: "Unexpected error ABC", + }, + { + name: "unexpected error in Create call", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return nil, &k8serrors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonNotFound}} + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + CreateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + return nil, errors.New("Unexpected error ABC") + }, + } + }, + wantErr: true, + expectedErr: "Unexpected error ABC", + }, + { + name: "unexpected error in Update call", + setup: func(c *mockController) { + c.mockRBLister = &fakes.RoleBindingListerMock{ + GetFunc: func(namespace string, name string) (*k8srbac.RoleBinding, error) { + return &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: map[string]string{}, + OwnerReferences: ownerRefs, + }, + RoleRef: roleRef, + Subjects: subjects, + }, nil + }, + } + + c.mockRBInterface = &fakes.RoleBindingInterfaceMock{ + UpdateFunc: func(rb *k8srbac.RoleBinding) (*k8srbac.RoleBinding, error) { + return nil, errors.New("Unexpected error ABC") + }, + } + }, + wantErr: true, + expectedErr: "Unexpected error ABC", + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + mockCtrl := newMockController(t) + tt.setup(mockCtrl) + r := mockCtrl.rbacController() + err := r.ensureRolebinding(namespace, subject, grb) + if (err != nil) != tt.wantErr || (tt.wantErr == true && !strings.Contains(err.Error(), tt.expectedErr)) { + t.Errorf("ensureRolebinding() error = %v, wantErr %v, expectedErr %v", err, tt.wantErr, tt.expectedErr) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/mockIndexer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/mockIndexer_test.go new file mode 100644 index 0000000..40aa28a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/mockIndexer_test.go @@ -0,0 +1,252 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: k8s.io/client-go/tools/cache (interfaces: Indexer) + +// Package restrictedadminrbac is a generated GoMock package. +package restrictedadminrbac + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + cache "k8s.io/client-go/tools/cache" +) + +// MockIndexer is a mock of Indexer interface. +type MockIndexer struct { + ctrl *gomock.Controller + recorder *MockIndexerMockRecorder +} + +// MockIndexerMockRecorder is the mock recorder for MockIndexer. +type MockIndexerMockRecorder struct { + mock *MockIndexer +} + +// NewMockIndexer creates a new mock instance. +func NewMockIndexer(ctrl *gomock.Controller) *MockIndexer { + mock := &MockIndexer{ctrl: ctrl} + mock.recorder = &MockIndexerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockIndexer) EXPECT() *MockIndexerMockRecorder { + return m.recorder +} + +// Add mocks base method. +func (m *MockIndexer) Add(arg0 interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Add", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Add indicates an expected call of Add. +func (mr *MockIndexerMockRecorder) Add(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockIndexer)(nil).Add), arg0) +} + +// AddIndexers mocks base method. +func (m *MockIndexer) AddIndexers(arg0 cache.Indexers) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddIndexers", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddIndexers indicates an expected call of AddIndexers. +func (mr *MockIndexerMockRecorder) AddIndexers(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddIndexers", reflect.TypeOf((*MockIndexer)(nil).AddIndexers), arg0) +} + +// ByIndex mocks base method. +func (m *MockIndexer) ByIndex(arg0, arg1 string) ([]interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ByIndex", arg0, arg1) + ret0, _ := ret[0].([]interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ByIndex indicates an expected call of ByIndex. +func (mr *MockIndexerMockRecorder) ByIndex(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ByIndex", reflect.TypeOf((*MockIndexer)(nil).ByIndex), arg0, arg1) +} + +// Delete mocks base method. +func (m *MockIndexer) Delete(arg0 interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockIndexerMockRecorder) Delete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockIndexer)(nil).Delete), arg0) +} + +// Get mocks base method. +func (m *MockIndexer) Get(arg0 interface{}) (interface{}, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// Get indicates an expected call of Get. +func (mr *MockIndexerMockRecorder) Get(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockIndexer)(nil).Get), arg0) +} + +// GetByKey mocks base method. +func (m *MockIndexer) GetByKey(arg0 string) (interface{}, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetByKey", arg0) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetByKey indicates an expected call of GetByKey. +func (mr *MockIndexerMockRecorder) GetByKey(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByKey", reflect.TypeOf((*MockIndexer)(nil).GetByKey), arg0) +} + +// GetIndexers mocks base method. +func (m *MockIndexer) GetIndexers() cache.Indexers { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetIndexers") + ret0, _ := ret[0].(cache.Indexers) + return ret0 +} + +// GetIndexers indicates an expected call of GetIndexers. +func (mr *MockIndexerMockRecorder) GetIndexers() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIndexers", reflect.TypeOf((*MockIndexer)(nil).GetIndexers)) +} + +// Index mocks base method. +func (m *MockIndexer) Index(arg0 string, arg1 interface{}) ([]interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Index", arg0, arg1) + ret0, _ := ret[0].([]interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Index indicates an expected call of Index. +func (mr *MockIndexerMockRecorder) Index(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Index", reflect.TypeOf((*MockIndexer)(nil).Index), arg0, arg1) +} + +// IndexKeys mocks base method. +func (m *MockIndexer) IndexKeys(arg0, arg1 string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IndexKeys", arg0, arg1) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// IndexKeys indicates an expected call of IndexKeys. +func (mr *MockIndexerMockRecorder) IndexKeys(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IndexKeys", reflect.TypeOf((*MockIndexer)(nil).IndexKeys), arg0, arg1) +} + +// List mocks base method. +func (m *MockIndexer) List() []interface{} { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List") + ret0, _ := ret[0].([]interface{}) + return ret0 +} + +// List indicates an expected call of List. +func (mr *MockIndexerMockRecorder) List() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockIndexer)(nil).List)) +} + +// ListIndexFuncValues mocks base method. +func (m *MockIndexer) ListIndexFuncValues(arg0 string) []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListIndexFuncValues", arg0) + ret0, _ := ret[0].([]string) + return ret0 +} + +// ListIndexFuncValues indicates an expected call of ListIndexFuncValues. +func (mr *MockIndexerMockRecorder) ListIndexFuncValues(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListIndexFuncValues", reflect.TypeOf((*MockIndexer)(nil).ListIndexFuncValues), arg0) +} + +// ListKeys mocks base method. +func (m *MockIndexer) ListKeys() []string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListKeys") + ret0, _ := ret[0].([]string) + return ret0 +} + +// ListKeys indicates an expected call of ListKeys. +func (mr *MockIndexerMockRecorder) ListKeys() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListKeys", reflect.TypeOf((*MockIndexer)(nil).ListKeys)) +} + +// Replace mocks base method. +func (m *MockIndexer) Replace(arg0 []interface{}, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Replace", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Replace indicates an expected call of Replace. +func (mr *MockIndexerMockRecorder) Replace(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Replace", reflect.TypeOf((*MockIndexer)(nil).Replace), arg0, arg1) +} + +// Resync mocks base method. +func (m *MockIndexer) Resync() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Resync") + ret0, _ := ret[0].(error) + return ret0 +} + +// Resync indicates an expected call of Resync. +func (mr *MockIndexerMockRecorder) Resync() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Resync", reflect.TypeOf((*MockIndexer)(nil).Resync)) +} + +// Update mocks base method. +func (m *MockIndexer) Update(arg0 interface{}) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Update indicates an expected call of Update. +func (mr *MockIndexerMockRecorder) Update(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockIndexer)(nil).Update), arg0) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/register.go new file mode 100644 index 0000000..099c2fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/restrictedadminrbac/register.go @@ -0,0 +1,80 @@ +package restrictedadminrbac + +import ( + "context" + + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "k8s.io/client-go/tools/cache" +) + +type rbaccontroller struct { + grbIndexer cache.Indexer + roleBindings v1.RoleBindingInterface + rbLister v1.RoleBindingLister + fleetworkspaces v3.FleetWorkspaceInterface + clusterCache mgmtv3.ClusterCache + grbCache mgmtv3.GlobalRoleBindingCache + crtbCache mgmtv3.ClusterRoleTemplateBindingCache + crtbCtrl mgmtv3.ClusterRoleTemplateBindingClient +} + +const ( + grbByRoleIndex = "management.cattle.io/grb-by-role" + sourceKey = "field.cattle.io/source" + grbHandlerName = "restrictedAdminsClusterOwner" +) + +func Register(ctx context.Context, management *config.ManagementContext, wrangler *wrangler.Context) { + + informer := management.Management.GlobalRoleBindings("").Controller().Informer() + globalRoleBindings := management.Management.GlobalRoleBindings("") + r := rbaccontroller{ + grbIndexer: informer.GetIndexer(), + roleBindings: management.RBAC.RoleBindings(""), + rbLister: management.RBAC.RoleBindings("").Controller().Lister(), + fleetworkspaces: management.Management.FleetWorkspaces(""), + clusterCache: management.Wrangler.Mgmt.Cluster().Cache(), + crtbCache: management.Wrangler.Mgmt.ClusterRoleTemplateBinding().Cache(), + crtbCtrl: management.Wrangler.Mgmt.ClusterRoleTemplateBinding(), + grbCache: management.Wrangler.Mgmt.GlobalRoleBinding().Cache(), + } + globalRoleBindings.AddHandler(ctx, grbHandlerName, r.clusterOwnerSync) + globalRoleBindings.AddHandler(ctx, "restrictedAdminGlobalBindingsFleet", r.ensureRestricedAdminForFleet) + + // if a fleetwokspace changes then enqueue the restricted-admin globalRoleBindings + relatedresource.Watch(ctx, "restricted-admin-fleet", r.enqueueGrb, globalRoleBindings.Controller(), wrangler.Mgmt.FleetWorkspace()) + + // if a cluster is updated enqueue the restricted-admin globalRoleBindings + relatedresource.Watch(ctx, "restricted-admin-cluster", r.enqueueGrbOnCluster, globalRoleBindings.Controller(), wrangler.Mgmt.Cluster()) + + // if a CRTB that is owned by a GRB is modified enqueue the GRB to reconcile the modified CRTB. + relatedresource.Watch(ctx, "restricted-admin-crtb", r.enqueueGrbOnCRTB, globalRoleBindings.Controller(), wrangler.Mgmt.ClusterRoleTemplateBinding()) +} + +// getRestrictedAdminGRBs gets returns a list of keys for all restricted admin GlobalRoleBindings. +func (r *rbaccontroller) getRestrictedAdminGRBs() ([]relatedresource.Key, error) { + grbs, err := r.grbIndexer.ByIndex(grbByRoleIndex, rbac.GlobalRestrictedAdmin) + if err != nil { + return nil, err + } + + result := make([]relatedresource.Key, 0, len(grbs)) + for _, grbObj := range grbs { + grb, ok := grbObj.(*v3.GlobalRoleBinding) + if !ok { + continue + } + result = append(result, relatedresource.Key{ + Namespace: grb.Namespace, + Name: grb.Name, + }) + } + + return result, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/node.go new file mode 100644 index 0000000..56516c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/node.go @@ -0,0 +1,231 @@ +package rkeworkerupgrader + +import ( + "fmt" + "sort" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + nodehelper "github.com/rancher/rancher/pkg/node" + nodeserver "github.com/rancher/rancher/pkg/rkenodeconfigserver" + rkeservices "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" +) + +type upgradeStatus struct { + /* + prepare: pre-process for upgrade: cordon/drain + process: update node plan, state: upgrading + */ + // active => cordon/drain + toPrepare []*v3.Node + // cordon/drain => upgrading + toProcess []*v3.Node + // upgrading => upgraded => uncordon + upgraded []*v3.Node + // notReady => stuck in cordoned (unavailable nodes get new plan without NodeConditionUpgraded) + toUncordon []*v3.Node + // unavailable nodes + notReady []*v3.Node + // upgraded active nodes + done int + // nodes qualified to upgrade + filtered int + // nodes in upgrading state + upgrading int +} + +func (uh *upgradeHandler) prepareNode(node *v3.Node, toDrain bool, nodeDrainInput *v32.NodeDrainInput) error { + var nodeCopy *v3.Node + if toDrain { + if node.Spec.DesiredNodeUnschedulable == "drain" { + return nil + } + nodeCopy = node.DeepCopy() + nodeCopy.Spec.DesiredNodeUnschedulable = "drain" + nodeCopy.Spec.NodeDrainInput = nodeDrainInput + } else { + if node.Spec.DesiredNodeUnschedulable == "true" || node.Spec.InternalNodeSpec.Unschedulable { + return nil + } + nodeCopy = node.DeepCopy() + nodeCopy.Spec.DesiredNodeUnschedulable = "true" + } + + if _, err := uh.nodes.Update(nodeCopy); err != nil { + return err + } + return nil +} + +func (uh *upgradeHandler) setNodePlan(node *v3.Node, cluster *v3.Cluster, upgrade bool) error { + nodePlan, err := uh.getNodePlan(node, cluster) + if err != nil { + return fmt.Errorf("setNodePlan: error getting node plan for [%s]: %v", node.Name, err) + } + + nodeCopy := node.DeepCopy() + nodeCopy.Status.NodePlan.Plan = nodePlan + nodeCopy.Status.NodePlan.Version = cluster.Status.NodeVersion + + if upgrade { + nodeCopy.Status.NodePlan.AgentCheckInterval = nodeserver.AgentCheckIntervalDuringUpgrade + v32.NodeConditionUpgraded.Unknown(nodeCopy) + v32.NodeConditionUpgraded.Message(nodeCopy, "upgrading") + } + + if _, err := uh.nodes.Update(nodeCopy); err != nil { + return err + } + + return nil +} + +func (uh *upgradeHandler) updateNodeActive(node *v3.Node) error { + nodeCopy := node.DeepCopy() + v32.NodeConditionUpgraded.True(nodeCopy) + v32.NodeConditionUpgraded.Message(nodeCopy, "") + + // reset the node + nodeCopy.Spec.DesiredNodeUnschedulable = "false" + nodeCopy.Status.NodePlan.AgentCheckInterval = nodeserver.DefaultAgentCheckInterval + + if _, err := uh.nodes.Update(nodeCopy); err != nil { + return err + } + + return nil +} + +func skipNode(node *v3.Node) bool { + clusterName := node.Namespace + if node.DeletionTimestamp != nil { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is getting deleted", clusterName, node.Name) + return true + } + + if node.Status.NodeConfig == nil { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] nodeConfig is empty", clusterName, node.Name) + return true + } + + if !workerOnly(node.Status.NodeConfig.Role) { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is not a workerOnly node", clusterName, node.Name) + return true + } + + // skip provisioning nodes + if !v32.NodeConditionProvisioned.IsTrue(node) { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is not provisioned", clusterName, node.Name) + return true + } + + // skip registering nodes + if !v32.NodeConditionRegistered.IsTrue(node) { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is not registered", clusterName, node.Name) + return true + } + + return false +} + +func (uh *upgradeHandler) filterNodes(nodes []*v3.Node, expectedVersion int, drain bool) *upgradeStatus { + status := &upgradeStatus{} + for _, node := range nodes { + + if skipNode(node) { + continue + } + + status.filtered++ + + // check for nodeConditionReady + if !nodehelper.IsMachineReady(node) { + // update plan for nodes that were attempted for upgrade + if v32.NodeConditionUpgraded.IsUnknown(node) { + status.upgrading++ + status.toProcess = append(status.toProcess, node) + } else { + status.notReady = append(status.notReady, node) + } + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is not ready", node.Namespace, node.Name) + continue + } + + if node.Status.AppliedNodeVersion == expectedVersion { + if v32.NodeConditionUpgraded.IsUnknown(node) { + status.upgraded = append(status.upgraded, node) + } + if !node.Spec.InternalNodeSpec.Unschedulable { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] is done", node.Namespace, node.Name) + status.done++ + } else { + // node hasn't un-cordoned, so consider it upgrading in terms of maxUnavailable count + status.upgrading++ + // node has already upgraded, but condition is not unknown, so uncordon it + if !v32.NodeConditionUpgraded.IsUnknown(node) && node.Spec.DesiredNodeUnschedulable != "false" { + status.toUncordon = append(status.toUncordon, node) + } + } + continue + } + + if preparingNode(node, drain) { + // draining or cordoning + status.upgrading++ + continue + } + + if preparedNode(node, drain) { + // node ready to upgrade + status.upgrading++ + status.toProcess = append(status.toProcess, node) + continue + } + + status.toPrepare = append(status.toPrepare, node) + } + + sortByNodeName(status.toPrepare) + sortByNodeName(status.toProcess) + sortByNodeName(status.upgraded) + sortByNodeName(status.notReady) + + return status +} + +func sortByNodeName(arr []*v3.Node) { + // v3.Node.Name is auto generated, format: `m-xxxx` + sort.Slice(arr, func(i, j int) bool { return arr[i].Name < arr[j].Name }) +} + +func preparingNode(node *v3.Node, drain bool) bool { + if drain { + return node.Spec.DesiredNodeUnschedulable == "drain" + } + return node.Spec.DesiredNodeUnschedulable == "true" +} + +func preparedNode(node *v3.Node, drain bool) bool { + if drain { + return v32.NodeConditionDrained.IsTrue(node) + } + return node.Spec.InternalNodeSpec.Unschedulable +} + +func workerOnly(roles []string) bool { + worker := false + for _, role := range roles { + if role == rkeservices.ETCDRole { + return false + } + if role == rkeservices.ControlRole { + return false + } + if role == rkeservices.WorkerRole { + worker = true + } + } + return worker +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/plan.go new file mode 100644 index 0000000..1f633c3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/plan.go @@ -0,0 +1,372 @@ +package rkeworkerupgrader + +import ( + "fmt" + "reflect" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/librke" + nodeserver "github.com/rancher/rancher/pkg/rkenodeconfigserver" + rkeservices "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" +) + +const ( + restoreKey = "CATTLE_ETCD_RESTORE_GENERATION" + kubeletProcess = "kubelet" +) + +func (uh *upgradeHandler) nonWorkerPlan(node *v3.Node, cluster *v3.Cluster) (*rketypes.RKEConfigNodePlan, error) { + appliedSpec, err := assemblers.AssembleRKEConfigSpec(cluster, *cluster.Status.AppliedSpec.DeepCopy(), uh.secretLister) + if err != nil { + return nil, err + } + rkeConfig := appliedSpec.RancherKubernetesEngineConfig.DeepCopy() + rkeConfig.Nodes = []rketypes.RKEConfigNode{ + *node.Status.NodeConfig, + } + rkeConfig.Nodes[0].Role = []string{rkeservices.WorkerRole, rkeservices.ETCDRole, rkeservices.ControlRole} + + infos, err := librke.GetDockerInfo(node) + if err != nil { + return nil, err + } + + hostAddress := node.Status.NodeConfig.Address + hostDockerInfo := infos[hostAddress] + + logrus.Debugf("getDockerInfo for node [%s] dockerInfo [%s]", node.Name, hostDockerInfo.DockerRootDir) + + svcOptions, err := uh.getServiceOptions(rkeConfig.Version, hostDockerInfo.OSType) + if err != nil { + return nil, err + } + + plan, err := librke.New().GeneratePlan(uh.ctx, rkeConfig, infos, svcOptions) + if err != nil { + return nil, err + } + + token, err := uh.systemAccountManager.GetOrCreateSystemClusterToken(cluster.Name) + if err != nil { + return nil, errors.Wrapf(err, "failed to create or get cluster token for share-mnt") + } + + np := &rketypes.RKEConfigNodePlan{} + + for _, tempNode := range plan.Nodes { + if tempNode.Address == hostAddress { + + np.Processes, err = nodeserver.AugmentProcesses(token, tempNode.Processes, false, + node.Status.NodeConfig.HostnameOverride, cluster, uh.secretLister) + if err != nil { + return np, err + } + + np.Processes = nodeserver.AppendTaintsToKubeletArgs(np.Processes, node.Status.NodeConfig.Taints) + + return np, nil + } + } + + return nil, fmt.Errorf("failed to find plan for %s", hostAddress) +} + +func (uh *upgradeHandler) workerPlan(node *v3.Node, cluster *v3.Cluster) (*rketypes.RKEConfigNodePlan, error) { + infos, err := librke.GetDockerInfo(node) + if err != nil { + return nil, err + } + + hostAddress := node.Status.NodeConfig.Address + hostDockerInfo := infos[hostAddress] + + appliedSpec, err := assemblers.AssembleRKEConfigSpec(cluster, *cluster.Status.AppliedSpec.DeepCopy(), uh.secretLister) + if err != nil { + return nil, err + } + + rkeConfig := appliedSpec.RancherKubernetesEngineConfig.DeepCopy() + nodeserver.FilterHostForSpec(rkeConfig, node) + + logrus.Debugf("[workerplan] The number of nodes sent to the plan: %v", len(rkeConfig.Nodes)) + svcOptions, err := uh.getServiceOptions(rkeConfig.Version, hostDockerInfo.OSType) + if err != nil { + return nil, err + } + + plan, err := librke.New().GeneratePlan(uh.ctx, rkeConfig, infos, svcOptions) + if err != nil { + return nil, err + } + + logrus.Debugf("[workerplan] getDockerInfo for node [%s] dockerInfo [%s]", node.Name, hostDockerInfo.DockerRootDir) + + np := &rketypes.RKEConfigNodePlan{} + + token, err := uh.systemAccountManager.GetOrCreateSystemClusterToken(cluster.Name) + if err != nil { + return nil, errors.Wrapf(err, "failed to create or get cluster token for share-mnt") + } + for _, tempNode := range plan.Nodes { + if tempNode.Address == hostAddress { + if hostDockerInfo.OSType == "windows" { // compatible with Windows + np.Processes = nodeserver.EnhanceWindowsProcesses(tempNode.Processes) + } else { + np.Processes, err = nodeserver.AugmentProcesses(token, tempNode.Processes, true, + node.Status.NodeConfig.HostnameOverride, cluster, uh.secretLister) + if err != nil { + return np, err + } + } + if cluster.Annotations[clusterprovisioner.RkeRestoreAnnotation] == "true" { + // This is for the node agent to be able to detect changes in the node plan for kubelet, + // and therefore to recreate the kubelet container on worker nodes after RKE restores an etcd snapshot. + // The value is not meant to represent the node version, it is chosen because it increases linearly. + newEnvVar := fmt.Sprintf("%s=%d", restoreKey, cluster.Status.NodeVersion) + logrus.Debugf("[workerplan] adding/updating env var [%s] on node [%s]", newEnvVar, node.Name) + np.Processes[kubeletProcess] = AddEnvVarToProcess(np.Processes[kubeletProcess], newEnvVar) + } else { + // A normal, non-restoring-etcd-snapshot, updating on the cluster drops the above env var from the new plan, + // which results in a change in the plan that, in theory, should trigger the redeployment of the kubelet container. + // However, currently it does not happen which is a bug (GH-43308). + // Adding the env var back is to avoid regression in the future when the bug is fixed. + if node.Status.NodePlan != nil && node.Status.NodePlan.Plan != nil { + oldProcess, found := node.Status.NodePlan.Plan.Processes[kubeletProcess] + if found { + for _, env := range oldProcess.Env { + if strings.HasPrefix(env, restoreKey) { + np.Processes[kubeletProcess] = AddEnvVarToProcess(np.Processes[kubeletProcess], env) + break + } + } + } + } + } + + np.Processes = nodeserver.AppendTaintsToKubeletArgs(np.Processes, node.Status.NodeConfig.Taints) + np.Files = tempNode.Files + + return np, nil + } + } + + return nil, fmt.Errorf("[workerplan] failed to find plan for %s", hostAddress) + +} + +func (uh *upgradeHandler) getServiceOptions(k8sVersion string, osType string) (map[string]interface{}, error) { + data := map[string]interface{}{} + svcOptions, err := kd.GetRKEK8sServiceOptions(k8sVersion, uh.serviceOptionsLister, + uh.serviceOptions, uh.sysImagesLister, uh.sysImages, kd.Linux) + if err != nil { + logrus.Errorf("getK8sServiceOptions: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptions != nil { + data["k8s-service-options"] = svcOptions + } + if osType == "windows" { + svcOptionsWindows, err := kd.GetRKEK8sServiceOptions(k8sVersion, uh.serviceOptionsLister, + uh.serviceOptions, uh.sysImagesLister, uh.sysImages, kd.Windows) + if err != nil { + logrus.Errorf("getK8sServiceOptionsWindows: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptionsWindows != nil { + data["k8s-windows-service-options"] = svcOptionsWindows + } + } + return data, nil +} + +func planChangedForUpgrade(newPlan *rketypes.RKEConfigNodePlan, oldPlan *rketypes.RKEConfigNodePlan) bool { + if newPlan == nil || oldPlan == nil { + return true + } + newProcesses := newPlan.Processes + oldProcesses := oldPlan.Processes + + if len(newProcesses) != len(oldProcesses) { + logrus.Infof("number of processes changed: old: %v new: %v", len(oldProcesses), len(newProcesses)) + return true + } + + for k, newProcess := range newProcesses { + if strings.Contains(k, "share-mnt") { + // don't need to upgrade if share-mnt changed + continue + } + oldProcess, ok := oldProcesses[k] + if !ok { + return true + } + + if processChanged(newProcess, oldProcess) { + return true + } + } + + return false +} + +func processChanged(newp rketypes.Process, oldp rketypes.Process) bool { + name := newp.Name + + if oldp.Image != newp.Image { + logrus.Infof("image changed for [%s] old: %s new: %s", name, oldp.Image, newp.Image) + return true + } + + if sliceChangedUnordered(oldp.Command, newp.Command) { + logrus.Infof("command changed for [%s] old: %v new: %v", name, oldp.Command, newp.Command) + return true + } + + if sliceChangedUnordered(oldp.Env, newp.Env) { + logrus.Infof("env changed for [%s] old: %v new %v", name, oldp.Env, newp.Env) + return true + } + + if sliceChangedUnordered(oldp.Args, newp.Args) { + logrus.Infof("args changed for [%s] old: %v new %v", name, oldp.Args, newp.Args) + return true + } + + if sliceChanged(oldp.Binds, newp.Binds) { + logrus.Infof("binds changed for [%s] old: %v new %v", name, oldp.Binds, newp.Binds) + return true + } + + if sliceChanged(oldp.VolumesFrom, newp.VolumesFrom) { + logrus.Infof("volumesFrom changed for [%s] old: %v new %v", name, oldp.VolumesFrom, newp.VolumesFrom) + return true + } + + if sliceChanged(oldp.Publish, newp.Publish) { + logrus.Infof("publish changed for [%s] old: %v new %v", name, oldp.Publish, newp.Publish) + return true + } + + oldProcess := forCompareProcess(oldp) + newProcess := forCompareProcess(newp) + + if !reflect.DeepEqual(oldProcess, newProcess) { + logrus.Infof("process changed for [%s] old: %#v new %#v", name, oldProcess, newProcess) + return true + } + + return false + +} + +type compareProcess struct { + Labels map[string]string + NetworkMode string + PidMode string + Privileged bool +} + +func forCompareProcess(p rketypes.Process) compareProcess { + return compareProcess{ + Labels: p.Labels, + NetworkMode: p.NetworkMode, + PidMode: p.PidMode, + Privileged: p.Privileged, + } +} + +func sliceChangedUnordered(olds, news []string) bool { + oldMap := sliceToMap(olds) + newMap := sliceToMap(news) + + if !reflect.DeepEqual(oldMap, newMap) { + return true + } + return false +} + +func sliceChanged(olds, news []string) bool { + if len(olds) == 0 && len(news) == 0 { + // DeepEqual considers []string{} and []string(nil) as different + return false + } + + if !reflect.DeepEqual(olds, news) { + return true + } + + return false +} + +func planChangedForUpdate(newPlan, oldPlan *rketypes.RKEConfigNodePlan) bool { + // files passed in node config + if !reflect.DeepEqual(newPlan.Files, oldPlan.Files) { + return true + } + // things that aren't included to restart container + for k, newProcess := range newPlan.Processes { + if oldProcess, ok := oldPlan.Processes[k]; ok { + if oldProcess.Name != newProcess.Name { + return true + } + + if oldProcess.HealthCheck.URL != newProcess.HealthCheck.URL { + return true + } + + if oldProcess.RestartPolicy != newProcess.RestartPolicy { + return true + } + + if oldProcess.ImageRegistryAuthConfig != newProcess.ImageRegistryAuthConfig { + return true + } + + if strings.Contains(k, "share-mnt") { + // don't need to upgrade if share-mnt changed + if processChanged(newProcess, oldProcess) { + return true + } + } + } + } + + return false + +} + +func sliceToMap(s []string) map[string]bool { + m := map[string]bool{} + for _, v := range s { + m[v] = true + } + return m +} + +// AddEnvVarToProcess adds or overwrites the existing env var in target process +func AddEnvVarToProcess(process rketypes.Process, newEnvVar string) rketypes.Process { + if process.Name == "" || process.Image == "" || newEnvVar == "" { + return process + } + targetKey := strings.SplitN(newEnvVar, "=", 2)[0] + found := false + for i, env := range process.Env { + k := strings.SplitN(env, "=", 2)[0] + if k == targetKey { + process.Env[i] = newEnvVar + found = true + break + } + } + if !found { + process.Env = append(process.Env, newEnvVar) + } + return process +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/upgrade.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/upgrade.go new file mode 100644 index 0000000..3290d3b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/rkeworkerupgrader/upgrade.go @@ -0,0 +1,538 @@ +package rkeworkerupgrader + +import ( + "context" + "fmt" + "strings" + "time" + + "github.com/moby/locker" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + nodehelper "github.com/rancher/rancher/pkg/node" + nodeserver "github.com/rancher/rancher/pkg/rkenodeconfigserver" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + rkedefaults "github.com/rancher/rke/cluster" + rketypes "github.com/rancher/rke/types" + "github.com/rancher/rke/util" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/wait" +) + +type upgradeHandler struct { + clusters v3.ClusterInterface + nodes v3.NodeInterface + nodeLister v3.NodeLister + clusterLister v3.ClusterLister + secretLister v1.SecretLister + lookup *nodeserver.BundleLookup + systemAccountManager *systemaccount.Manager + serviceOptionsLister v3.RkeK8sServiceOptionLister + serviceOptions v3.RkeK8sServiceOptionInterface + sysImagesLister v3.RkeK8sSystemImageLister + sysImages v3.RkeK8sSystemImageInterface + clusterLock *locker.Locker + ctx context.Context +} + +func Register(ctx context.Context, mgmt *config.ManagementContext, scaledContext *config.ScaledContext) { + + uh := &upgradeHandler{ + clusters: mgmt.Management.Clusters(""), + clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + nodes: mgmt.Management.Nodes(""), + nodeLister: mgmt.Management.Nodes("").Controller().Lister(), + secretLister: mgmt.Core.Secrets("").Controller().Lister(), + lookup: nodeserver.NewLookup(scaledContext.Core.Namespaces(""), scaledContext.Core), + systemAccountManager: systemaccount.NewManagerFromScale(scaledContext), + serviceOptionsLister: mgmt.Management.RkeK8sServiceOptions("").Controller().Lister(), + serviceOptions: mgmt.Management.RkeK8sServiceOptions(""), + sysImagesLister: mgmt.Management.RkeK8sSystemImages("").Controller().Lister(), + sysImages: mgmt.Management.RkeK8sSystemImages(""), + clusterLock: locker.New(), + ctx: ctx, + } + + mgmt.Management.Nodes("").Controller().AddHandler(ctx, "rke-worker-upgrader", uh.Sync) +} + +func (uh *upgradeHandler) Sync(key string, node *v3.Node) (runtime.Object, error) { + if strings.HasSuffix(key, "upgrade_") { + + cName := strings.Split(key, "/")[0] + // provisioner.go updates cluster's AppliedSpec and then enqueues "upgrade_" key to call this sync. + // Node plan gets calculated using cluster's AppliedSpec, so fetch the object from db instead of Lister to avoid race. + cluster, err := uh.clusters.Get(cName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + if cluster.DeletionTimestamp != nil || cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + return nil, nil + } + + if cluster.Annotations[clusterprovisioner.RkeRestoreAnnotation] == "true" { + // rke completed etcd snapshot restore, need to update plan for nodes so worker nodes reset to old rkeConfig + return node, uh.restore(cluster) + } + + logrus.Infof("checking cluster [%s] for worker nodes upgrade", cluster.Name) + + if toUpgrade, planChanged, err := uh.toUpgradeCluster(cluster); err != nil { + return nil, err + } else if toUpgrade { + if err := uh.upgradeCluster(cluster, key, planChanged); err != nil { + return nil, err + } + } + + return nil, nil + } + + if node == nil || node.DeletionTimestamp != nil || !v32.NodeConditionProvisioned.IsTrue(node) { + return node, nil + } + + cluster, err := uh.clusterLister.Get("", node.Namespace) + if err != nil { + return nil, err + } + + if cluster.DeletionTimestamp != nil || cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + return node, nil + } + + if node.Status.NodePlan == nil { + return uh.updateNodePlan(node, cluster, true) + } + + if v32.ClusterConditionUpdated.IsUnknown(cluster) || cluster.Annotations[clusterprovisioner.RkeRestoreAnnotation] == "true" { + return node, nil + } + + if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + // if sync is for a node that was just updated, do nothing + + // node is already updated to cordon/drain/uncordon, do nothing + if node.Spec.DesiredNodeUnschedulable != "" { + logrus.Debugf("cluster [%s] worker-upgrade: return node [%s], unschedulable field [%v]", cluster.Name, + node.Name, node.Spec.DesiredNodeUnschedulable) + return node, nil + } + // node is upgrading and already updated with new node plan, do nothing + if v32.NodeConditionUpgraded.IsUnknown(node) && node.Status.AppliedNodeVersion != cluster.Status.NodeVersion { + if node.Status.NodePlan.Version == cluster.Status.NodeVersion { + logrus.Debugf("cluster [%s] worker-upgrade: return node [%s], plan's updated [%v]", cluster.Name, + node.Name, cluster.Status.NodeVersion) + return node, nil + } + } + + logrus.Infof("cluster [%s] worker-upgrade: call upgrade to reconcile for node [%s]", cluster.Name, node.Name) + if err := uh.upgradeCluster(cluster, node.Name, false); err != nil { + return nil, err + } + return node, nil + } + + // proceed only if node and cluster's versions mismatch + if cluster.Status.NodeVersion == node.Status.NodePlan.Version { + return node, nil + } + + nodePlan, err := uh.getNodePlan(node, cluster) + if err != nil { + return nil, err + } + + if node.Status.AppliedNodeVersion == 0 { + // node never received appliedNodeVersion + if planChangedForUpgrade(nodePlan, node.Status.NodePlan.Plan) || planChangedForUpdate(nodePlan, node.Status.NodePlan.Plan) { + return uh.updateNodePlan(node, cluster, false) + } + } else { + if planChangedForUpdate(nodePlan, node.Status.NodePlan.Plan) { + logrus.Infof("cluster [%s] worker-upgrade: plan changed for update [%s]", cluster.Name, node.Name) + return uh.updateNodePlan(node, cluster, false) + } + } + + return node, nil +} + +func (uh *upgradeHandler) updateNodePlan(node *v3.Node, cluster *v3.Cluster, create bool) (*v3.Node, error) { + if node.Status.NodeConfig == nil || node.Status.DockerInfo == nil { + logrus.Debugf("cluster [%s] worker-upgrade: node [%s] waiting for node status sync: "+ + "nodeConfigNil [%v] dockerInfoNil [%v]", cluster.Name, node.Name, node.Status.NodeConfig == nil, node.Status.DockerInfo == nil) + // can't create correct node plan if node config or docker info hasn't been set + return node, nil + } + nodePlan, err := uh.getNodePlan(node, cluster) + if err != nil { + return nil, fmt.Errorf("getNodePlan error for node [%s]: %v", node.Name, err) + } + + nodeCopy := node.DeepCopy() + np := &v32.NodePlan{ + Plan: nodePlan, + Version: cluster.Status.NodeVersion, + } + if node.Status.NodePlan == nil || node.Status.NodePlan.AgentCheckInterval == 0 { + // default + np.AgentCheckInterval = nodeserver.DefaultAgentCheckInterval + } else { + np.AgentCheckInterval = node.Status.NodePlan.AgentCheckInterval + } + nodeCopy.Status.NodePlan = np + + updated, err := uh.nodes.Update(nodeCopy) + if err != nil { + return nil, fmt.Errorf("error updating node [%s] with plan %v", node.Name, err) + } + + if create { + logrus.Debugf("cluster [%s]: created node plan for node [%s]", cluster.Name, node.Name) + } else { + logrus.Debugf("cluster [%s] worker-upgrade: updated node [%s] with plan [%v]", cluster.Name, node.Name, np.Version) + } + + return updated, err +} + +func (uh *upgradeHandler) updateNodePlanVersion(node *v3.Node, cluster *v3.Cluster) (*v3.Node, error) { + nodeCopy := node.DeepCopy() + nodeCopy.Status.NodePlan.Version = cluster.Status.NodeVersion + logrus.Infof("cluster [%s] worker-upgrade: updating node [%s] with plan version [%v]", cluster.Name, + node.Name, nodeCopy.Status.NodePlan.Version) + + updated, err := uh.nodes.Update(nodeCopy) + if err != nil { + return nil, err + } + return updated, err + +} + +func (uh *upgradeHandler) getNodePlan(node *v3.Node, cluster *v3.Cluster) (*rketypes.RKEConfigNodePlan, error) { + var ( + nodePlan *rketypes.RKEConfigNodePlan + err error + ) + if nodehelper.IsNonWorker(node.Status.NodeConfig) { + nodePlan, err = uh.nonWorkerPlan(node, cluster) + } else { + nodePlan, err = uh.workerPlan(node, cluster) + } + return nodePlan, err +} + +func (uh *upgradeHandler) upgradeCluster(cluster *v3.Cluster, nodeName string, planChanged bool) error { + clusterName := cluster.Name + + uh.clusterLock.Lock(clusterName) + defer uh.clusterLock.Unlock(clusterName) + + logrus.Debugf("cluster [%s] upgrading condition: [%v] plan changed: [%v]", clusterName, v32.ClusterConditionUpgraded.IsUnknown(cluster), planChanged) + + var ( + clusterCopy *v3.Cluster + err error + ) + if !v32.ClusterConditionUpgraded.IsUnknown(cluster) || planChanged { + clusterCopy = cluster.DeepCopy() + v32.ClusterConditionUpgraded.Unknown(clusterCopy) + v32.ClusterConditionUpgraded.Message(clusterCopy, "updating worker nodes") + clusterCopy.Status.NodeVersion++ + } + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.UpgradeStrategy == nil { + if clusterCopy == nil { + clusterCopy = cluster.DeepCopy() + } + clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.UpgradeStrategy = &rketypes.NodeUpgradeStrategy{ + MaxUnavailableWorker: rkedefaults.DefaultMaxUnavailableWorker, + MaxUnavailableControlplane: rkedefaults.DefaultMaxUnavailableControlplane, + Drain: func() *bool { b := false; return &b }(), + } + } + if clusterCopy != nil { + cluster, err = uh.clusters.Update(clusterCopy) + if err != nil { + return err + } + logrus.Infof("cluster [%s] worker-upgrade: updated cluster nodeVersion [%v] upgradeStrategy [%v] ", clusterName, + clusterCopy.Status.NodeVersion, cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.UpgradeStrategy) + } + + logrus.Debugf("cluster [%s] worker-upgrade cluster status node version [%v]", clusterName, cluster.Status.NodeVersion) + nodes, err := uh.nodeLister.List(clusterName, labels.Everything()) + if err != nil { + return err + } + + upgradeStrategy := cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.UpgradeStrategy + toDrain := upgradeStrategy.Drain != nil && *upgradeStrategy.Drain + + // get current upgrade status of nodes + status := uh.filterNodes(nodes, cluster.Status.NodeVersion, toDrain) + + maxAllowed, err := CalculateMaxUnavailable(upgradeStrategy.MaxUnavailableWorker, status.filtered) + if err != nil { + return err + } + + logrus.Debugf("cluster [%s] worker-upgrade: workerNodeInfo: nodes %v maxAllowed %v upgrading %v notReady %v "+ + "toProcess %v toPrepare %v done %v toUncordon %v", cluster.Name, status.filtered, maxAllowed, status.upgrading, + keys(status.notReady), keys(status.toProcess), keys(status.toPrepare), keys(status.upgraded), keys(status.toUncordon)) + + for _, node := range status.upgraded { + if v32.NodeConditionUpgraded.IsTrue(node) { + continue + } + + if err := uh.updateNodeActive(node); err != nil { + return err + } + + logrus.Infof("cluster [%s] worker-upgrade: updated node [%s] to uncordon", clusterName, node.Name) + } + + for _, node := range status.toUncordon { + if err := uh.updateNodeActive(node); err != nil { + return err + } + logrus.Infof("cluster [%s] worker-upgrade: updated node [%s] to uncordon", clusterName, node.Name) + } + + notReady := len(status.notReady) + if notReady > maxAllowed { + return fmt.Errorf("cluster [%s] worker-upgrade: not enough nodes to upgrade: nodes %v notReady %v maxUnavailable %v", + clusterName, status.filtered, keys(status.notReady), maxAllowed) + } + + if notReady > 0 { + // update plan for unavailable nodes + for _, node := range status.notReady { + if node.Status.NodePlan.Version == cluster.Status.NodeVersion { + continue + } + + if err := uh.setNodePlan(node, cluster, false); err != nil { + return err + } + + logrus.Infof("cluster [%s] worker-upgrade: updated upgrading unavailable node [%s] with version %v", + clusterName, node.Name, cluster.Status.NodeVersion) + + } + } + + unavailable := status.upgrading + notReady + + if unavailable > maxAllowed { + return fmt.Errorf("cluster [%s] worker-upgrade: more than allowed nodes upgrading for cluster: unavailable %v maxUnavailable %v", + clusterName, unavailable, maxAllowed) + } + + for _, node := range status.toProcess { + if node.Status.NodePlan.Version == cluster.Status.NodeVersion { + continue + } + + if err := uh.setNodePlan(node, cluster, true); err != nil { + return err + } + + logrus.Infof("cluster [%s] worker-upgrade: updated node [%s] to upgrade", clusterName, node.Name) + } + + var nodeDrainInput *rketypes.NodeDrainInput + state := "cordon" + if toDrain { + nodeDrainInput = upgradeStrategy.DrainInput + state = "drain" + } + + for _, node := range status.toPrepare { + if unavailable == maxAllowed { + break + } + unavailable++ + + if err := uh.prepareNode(node, toDrain, nodeDrainInput); err != nil { + return err + } + + logrus.Infof("cluster [%s] worker-upgrade: updated node [%s] to %s", clusterName, node.Name, state) + } + + if status.done == status.filtered { + logrus.Debugf("cluster [%s] worker-upgrade: cluster is done upgrading, done %v len(nodes) %v", clusterName, status.done, status.filtered) + if !v32.ClusterConditionUpgraded.IsTrue(cluster) { + clusterCopy := cluster.DeepCopy() + v32.ClusterConditionUpgraded.True(clusterCopy) + v32.ClusterConditionUpgraded.Message(clusterCopy, "") + + if _, err := uh.clusters.Update(clusterCopy); err != nil { + return err + } + + logrus.Infof("cluster [%s] worker-upgrade: finished upgrade", clusterName) + } + } + + return nil +} + +func (uh *upgradeHandler) toUpgradeCluster(cluster *v3.Cluster) (bool, bool, error) { + nodes, err := uh.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return false, false, err + } + + for _, node := range nodes { + if node.Status.NodeConfig == nil { + continue + } + + if !workerOnly(node.Status.NodeConfig.Role) { + continue + } + + if node.Status.NodePlan == nil || v32.NodeConditionRegistered.IsUnknown(node) { + // enqueue if node plan isn't initialized yet + if node.Status.NodePlan == nil { + uh.nodes.Controller().Enqueue(node.Namespace, node.Name) + } + // node's not yet registered, change in its node plan should do nothing for cluster upgrade + continue + } + + // if cluster's already upgrading, skip nodes that are yet to upgrade, planChangedForUpgrade will always be true + if v32.ClusterConditionUpgraded.IsUnknown(cluster) && node.Status.AppliedNodeVersion != cluster.Status.NodeVersion { + continue + } + + nodePlan, err := uh.getNodePlan(node, cluster) + if err != nil { + return false, false, err + } + + if planChangedForUpgrade(nodePlan, node.Status.NodePlan.Plan) { + return true, true, nil + } + } + + if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + return true, false, nil + } + + return false, false, nil +} + +func (uh *upgradeHandler) restore(cluster *v3.Cluster) error { + nodes, err := uh.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return err + } + + var errgrp errgroup.Group + nodesQueue := util.GetObjectQueue(nodes) + for w := 0; w < 5; w++ { + errgrp.Go(func() error { + var errList []error + for node := range nodesQueue { + node := node.(*v3.Node) + if node.Status.NodeConfig != nil && workerOnly(node.Status.NodeConfig.Role) { + if node.Status.NodePlan.Version != cluster.Status.NodeVersion { + if err := uh.setNodePlan(node, cluster, false); err != nil { + errList = append(errList, err) + } + logrus.Infof("cluster [%s]: updated node [%s] for restore, plan version [%v]", cluster.Name, + node.Name, cluster.Status.NodeVersion) + } + } + } + return util.ErrList(errList) + }) + } + if err := errgrp.Wait(); err != nil { + return err + } + + toUpdate := getRestoredCluster(cluster.DeepCopy()) + if _, err := uh.clusters.Update(toUpdate); err != nil { + if !errors.IsConflict(err) { + return err + } + return uh.retryClusterUpdate(cluster.Name) + } + return nil +} + +func getRestoredCluster(cluster *v3.Cluster) *v3.Cluster { + cluster.Annotations[clusterprovisioner.RkeRestoreAnnotation] = "false" + + // if restore's for a cluster stuck in upgrading, update it as upgraded + if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + v32.ClusterConditionUpgraded.True(cluster) + v32.ClusterConditionUpgraded.Message(cluster, "restored worker nodes") + } + + return cluster +} + +func (uh *upgradeHandler) retryClusterUpdate(name string) error { + backoff := wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 7, + } + + return wait.ExponentialBackoff(backoff, func() (bool, error) { + cluster, err := uh.clusters.Get(name, metav1.GetOptions{}) + if err != nil { + return false, err + } + if cluster.Annotations[clusterprovisioner.RkeRestoreAnnotation] != "false" { + _, err = uh.clusters.Update(getRestoredCluster(cluster)) + if err != nil { + logrus.Debugf("cluster [%s] restore: error resetting restore annotation %v", cluster.Name, err) + if errors.IsConflict(err) { + return false, nil + } + return false, err + } + } + return true, nil + }) + +} + +func keys(nodes []*v3.Node) []string { + keys := make([]string, len(nodes)) + for _, node := range nodes { + keys = append(keys, node.Name) + } + return keys +} + +func CalculateMaxUnavailable(maxUnavailable string, nodes int) (int, error) { + parsedMax := intstr.Parse(maxUnavailable) + maxAllowed, err := intstr.GetValueFromIntOrPercent(&parsedMax, nodes, false) + if err != nil { + return 0, err + } + if maxAllowed > 0 { + return maxAllowed, nil + } + return 1, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/assemblers/assemblers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/assemblers/assemblers.go new file mode 100644 index 0000000..6198b79 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/assemblers/assemblers.go @@ -0,0 +1,530 @@ +package assemblers + +import ( + "encoding/json" + "strings" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" + "k8s.io/kubernetes/pkg/credentialprovider" +) + +const ( + ClusterType = "cluster" + ClusterTemplateRevisionType = "cluster template revision" + SecretNamespace = namespace.GlobalNamespace + SecretKey = "credential" +) + +type Assembler func(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) + +// AssemblePrivateRegistryCredential looks up the registry Secret and inserts the keys into the PrivateRegistries list on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssemblePrivateRegistryCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || len(spec.RancherKubernetesEngineConfig.PrivateRegistries) == 0 { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.PrivateRegistries[0].Password != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + registrySecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + + dockerCfg := credentialprovider.DockerConfigJSON{} + err = json.Unmarshal(registrySecret.Data[corev1.DockerConfigJsonKey], &dockerCfg) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + for i, privateRegistry := range specCopy.RancherKubernetesEngineConfig.PrivateRegistries { + if reg, ok := dockerCfg.Auths[privateRegistry.URL]; ok { + specCopy.RancherKubernetesEngineConfig.PrivateRegistries[i].User = reg.Username + specCopy.RancherKubernetesEngineConfig.PrivateRegistries[i].Password = reg.Password + } + } + return *specCopy, nil +} + +// AssembleS3Credential looks up the S3 backup config Secret and inserts the keys into the S3BackupConfig on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleS3Credential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig == nil || spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + s3Cred, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey = string(s3Cred.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleWeaveCredential looks up the weave Secret and inserts the keys into the network provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleWeaveCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + weaveSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password = string(weaveSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleVsphereGlobalCredential looks up the vsphere global Secret and inserts the keys into the cloud provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleVsphereGlobalCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + vsphereSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password = string(vsphereSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleVsphereVirtualCenterCredential looks up the vsphere virtualcenter Secret and inserts the keys into the cloud provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleVsphereVirtualCenterCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider == nil { + return spec, nil + } + if secretRef == "" { + for _, v := range spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + if v.Password != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + break + } + } + return spec, nil + + } + vcenterSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + for k, v := range vcenterSecret.Data { + vCenter := specCopy.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] + vCenter.Password = string(v) + specCopy.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] = vCenter + } + return *specCopy, nil +} + +// AssembleOpenStackCredential looks up the OpenStack Secret and inserts the keys into the cloud provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleOpenStackCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + + } + openStackSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password = string(openStackSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleAADClientSecretCredential looks up the AAD client secret Secret and inserts the keys into the cloud provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleAADClientSecretCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + + } + aadClientSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret = string(aadClientSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleAADCertCredential looks up the AAD client cert password Secret and inserts the keys into the cloud provider config on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleAADCertCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + aadCertSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword = string(aadCertSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleACIAPICUserKeyCredential looks up the aci apic user key Secret and inserts the keys into the AciNetworkProvider on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleACIAPICUserKeyCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + + } + aciUserKeySecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey = string(aciUserKeySecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleACITokenCredential looks up the aci token Secret and inserts the keys into the AciNetworkProvider on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleACITokenCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + + } + aciTokenSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token = string(aciTokenSecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleACIKafkaClientKeyCredential looks up the aci kafka client key Secret and inserts the keys into the AciNetworkProvider on the Cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleACIKafkaClientKeyCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + + } + aciKafkaClientKeySecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + specCopy := spec.DeepCopy() + specCopy.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey = string(aciKafkaClientKeySecret.Data[SecretKey]) + return *specCopy, nil +} + +// AssembleSecretsEncryptionProvidersSecretCredential looks up the rke KubeAPI secrets encryption configuration and +// inserts it back into the cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleSecretsEncryptionProvidersSecretCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig == nil || + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources != nil { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + secretsEncryptionProvidersSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + var resource []apiserverv1.ResourceConfiguration + err = json.Unmarshal(secretsEncryptionProvidersSecret.Data[SecretKey], &resource) + if err != nil { + return spec, err + } + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources = resource + return spec, nil +} + +// AssembleBastionHostSSHKeyCredential looks up bastion host ssh key and inserts it back into the cluster spec. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleBastionHostSSHKeyCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil { + return spec, nil + } + if secretRef == "" { + if spec.RancherKubernetesEngineConfig.BastionHost.SSHKey != "" { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + } + return spec, nil + } + bastionHostSSHKeySecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + spec.RancherKubernetesEngineConfig.BastionHost.SSHKey = string(bastionHostSSHKeySecret.Data[SecretKey]) + return spec, nil +} + +// AssembleKubeletExtraEnvCredential looks up the AWS_SECRET_ACCESS_KEY extraEnv for the kubelet if it exists. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssembleKubeletExtraEnvCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil { + return spec, nil + } + if secretRef == "" { + for _, e := range spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv { + if strings.Contains(e, "AWS_SECRET_ACCESS_KEY") { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + break + } + } + return spec, nil + } + kubeletExtraEnvSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + env := "AWS_SECRET_ACCESS_KEY=" + string(kubeletExtraEnvSecret.Data[SecretKey]) + spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv = append(spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv, env) + return spec, nil +} + +// AssemblePrivateRegistryECRCredential looks up Private Registry's ECR credential auth info, if it exists. +// It returns a new copy of the spec without modifying the original. The Cluster is never updated. +func AssemblePrivateRegistryECRCredential(secretRef, objType, objName string, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + if spec.RancherKubernetesEngineConfig == nil || + len(spec.RancherKubernetesEngineConfig.PrivateRegistries) == 0 { + return spec, nil + } + if secretRef == "" { + for _, r := range spec.RancherKubernetesEngineConfig.PrivateRegistries { + if ecr := r.ECRCredentialPlugin; ecr != nil && (ecr.AwsSecretAccessKey != "" || ecr.AwsSessionToken != "") { + logrus.Warnf("[secretmigrator] secrets for %s %s are not finished migrating", objType, objName) + break + } + } + return spec, nil + } + privateRegistryECRSecret, err := secretLister.Get(SecretNamespace, secretRef) + if err != nil { + return spec, err + } + + data, ok := privateRegistryECRSecret.Data[SecretKey] + if !ok { + return spec, nil + } + var registries map[string]string + err = json.Unmarshal(data, ®istries) + if err != nil { + return spec, err + } + + for i, reg := range spec.RancherKubernetesEngineConfig.PrivateRegistries { + if ecrData, ok := registries[reg.URL]; ok { + var ecr rketypes.ECRCredentialPlugin + err := json.Unmarshal([]byte(ecrData), &ecr) + if err != nil { + return spec, err + } + spec.RancherKubernetesEngineConfig.PrivateRegistries[i].ECRCredentialPlugin.AwsSecretAccessKey = ecr.AwsSecretAccessKey + spec.RancherKubernetesEngineConfig.PrivateRegistries[i].ECRCredentialPlugin.AwsSessionToken = ecr.AwsSessionToken + } + } + + return spec, nil +} + +// AssembleRKEConfigSpec is a wrapper assembler for assembling configs on Clusters. +// While cluster is unmodified, the spec field is modified in place, and DeepCopy() must be called on it prior to this +// function or unintended changes may occur. +func AssembleRKEConfigSpec(cluster *apimgmtv3.Cluster, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + spec, err := AssembleS3Credential(cluster.GetSecret("S3CredentialSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssemblePrivateRegistryCredential(cluster.GetSecret("PrivateRegistrySecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleWeaveCredential(cluster.GetSecret("WeavePasswordSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleVsphereGlobalCredential(cluster.GetSecret("VsphereSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleVsphereVirtualCenterCredential(cluster.GetSecret("VirtualCenterSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleOpenStackCredential(cluster.GetSecret("OpenStackSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleAADClientSecretCredential(cluster.GetSecret("AADClientSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleAADCertCredential(cluster.GetSecret("AADClientCertSecret"), ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACIAPICUserKeyCredential(cluster.Spec.ClusterSecrets.ACIAPICUserKeySecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACITokenCredential(cluster.Spec.ClusterSecrets.ACITokenSecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACIKafkaClientKeyCredential(cluster.Spec.ClusterSecrets.ACIKafkaClientKeySecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleSecretsEncryptionProvidersSecretCredential(cluster.Spec.ClusterSecrets.SecretsEncryptionProvidersSecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleBastionHostSSHKeyCredential(cluster.Spec.ClusterSecrets.BastionHostSSHKeySecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleKubeletExtraEnvCredential(cluster.Spec.ClusterSecrets.KubeletExtraEnvSecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssemblePrivateRegistryECRCredential(cluster.Spec.ClusterSecrets.PrivateRegistryECRSecret, ClusterType, cluster.Name, spec, secretLister) + if err != nil { + return spec, err + } + return spec, nil +} + +// AssembleRKEConfigTemplateSpec is a wrapper assembler for assembling configs on ClusterTemplateRevisions. It returns a ClusterSpec. +func AssembleRKEConfigTemplateSpec(template *apimgmtv3.ClusterTemplateRevision, spec apimgmtv3.ClusterSpec, secretLister v1.SecretLister) (apimgmtv3.ClusterSpec, error) { + spec, err := AssembleS3Credential(template.Status.S3CredentialSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssemblePrivateRegistryCredential(template.Status.PrivateRegistrySecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleWeaveCredential(template.Status.WeavePasswordSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleVsphereGlobalCredential(template.Status.VsphereSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleVsphereVirtualCenterCredential(template.Status.VirtualCenterSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleOpenStackCredential(template.Status.OpenStackSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleAADClientSecretCredential(template.Status.AADClientSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleAADCertCredential(template.Status.AADClientCertSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACIAPICUserKeyCredential(template.Status.ACIAPICUserKeySecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACITokenCredential(template.Status.ACITokenSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleACIKafkaClientKeyCredential(template.Status.ACIKafkaClientKeySecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleSecretsEncryptionProvidersSecretCredential(template.Status.SecretsEncryptionProvidersSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleBastionHostSSHKeyCredential(template.Status.BastionHostSSHKeySecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssembleKubeletExtraEnvCredential(template.Status.KubeletExtraEnvSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + spec, err = AssemblePrivateRegistryECRCredential(template.Status.PrivateRegistryECRSecret, ClusterTemplateRevisionType, template.Name, spec, secretLister) + if err != nil { + return spec, err + } + return spec, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig.go new file mode 100644 index 0000000..c933ede --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig.go @@ -0,0 +1,257 @@ +package secretmigrator + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/mitchellh/mapstructure" + "github.com/rancher/norman/condition" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/namespace" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + serviceAccountPasswordFieldName = "serviceaccountpassword" + authConfigKind = "authconfig" +) + +// syncAuthConfig syncs the authentication config and removes/migrates secrets as needed. +func (h *handler) syncAuthConfig(_ string, authConfig *apimgmtv3.AuthConfig) (runtime.Object, error) { + if authConfig == nil || !authConfig.Enabled { + return authConfig, nil + } + + switch authConfig.Type { + case client.ShibbolethConfigType: + obj, err := h.migrateAuthConfigPasswordToSecret(authConfig, + apimgmtv3.AuthConfigConditionSecretsMigrated, h.migrateShibbolethSecrets) + if err != nil { + return obj, err + } + return h.fixShibbolethSecretReference(obj) + case client.OKTAConfigType: + return h.migrateAuthConfigPasswordToSecret(authConfig, + apimgmtv3.AuthConfigOKTAPasswordMigrated, + h.migrateOKTASecrets) + default: + return h.migrateAuthConfig(authConfig) + } +} + +func (h *handler) migrateAuthConfig(authConfig *apimgmtv3.AuthConfig) (runtime.Object, error) { + unstructuredConfig, err := getUnstructuredAuthConfigByName(h.authConfigs, authConfig.Name) + if err != nil { + return nil, err + } + newUnstructuredConfig, err := setUnstructuredStatus(unstructuredConfig, apimgmtv3.AuthConfigConditionSecretsMigrated, "True") + if err != nil { + return nil, fmt.Errorf("failed to set the status on unstructured AuthConfig %s: %w", authConfig.Name, err) + } + + updated, err := h.authConfigs.Update(authConfig.Name, newUnstructuredConfig) + if err != nil { + return nil, fmt.Errorf("unable to update migration status of authconfig: %w", err) + } + return updated, nil +} + +func (h *handler) migrateAuthConfigPasswordToSecret(authConfig *apimgmtv3.AuthConfig, cond condition.Cond, f func(runtime.Unstructured) (runtime.Object, error)) (runtime.Object, error) { + if cond.IsTrue(authConfig) { + return authConfig, nil + } + + updated, err := cond.DoUntilTrue(authConfig, func() (runtime.Object, error) { + unstructuredConfig, err := getUnstructuredAuthConfigByName(h.authConfigs, authConfig.Name) + if err != nil { + return nil, err + } + + return f(unstructuredConfig) + }) + if err != nil { + return nil, fmt.Errorf("failed to update status for AuthConfig %s: %w", authConfig.Name, err) + } + updatedAuthConfig, err := h.authConfigs.Update(authConfig.Name, updated) + if err != nil { + return nil, fmt.Errorf("failed to update AuthConfig %s: %w", authConfig.Name, err) + } + + return updatedAuthConfig, nil +} + +func (h *handler) fixShibbolethSecretReference(obj runtime.Object) (runtime.Object, error) { + shibbConfig := &apimgmtv3.ShibbolethConfig{} + switch v := obj.(type) { + case *apimgmtv3.ShibbolethConfig: + shibbConfig = v + case *apimgmtv3.AuthConfig: + unstructuredConfig, err := getUnstructuredAuthConfigByName(h.authConfigs, v.Name) + if err != nil { + return nil, err + } + + if err := common.Decode(unstructuredConfig.UnstructuredContent(), shibbConfig); err != nil { + return nil, fmt.Errorf("unable to decode ShibbolethConfig: %w", err) + } + } + + if apimgmtv3.AuthConfigConditionShibbolethSecretFixed.IsTrue(shibbConfig) { + return obj, nil + } + + updated, err := apimgmtv3.AuthConfigConditionShibbolethSecretFixed.DoUntilTrue(shibbConfig, func() (runtime.Object, error) { + // This is fixing a bug where the secret was created as a lower-case + // name, but referenced with mixed-case. + const badSecretName = "cattle-global-data:shibbolethconfig-serviceAccountPassword" + if shibbConfig.OpenLdapConfig.ServiceAccountPassword == badSecretName { + shibbConfig.OpenLdapConfig.ServiceAccountPassword = strings.ToLower(shibbConfig.OpenLdapConfig.ServiceAccountPassword) + } + return shibbConfig, nil + }) + + if err != nil { + return nil, fmt.Errorf("failed to update status for AuthConfig %s: %w", shibbConfig.Name, err) + } + + updatedShibbolethConfig, err := h.authConfigs.Update(shibbConfig.Name, updated) + if err != nil { + return nil, fmt.Errorf("failed to update AuthConfig %s: %w", shibbConfig.Name, err) + } + + return updatedShibbolethConfig, nil +} + +// migrateShibbolethSecrets effects the migration of secrets for the Shibboleth provider. +func (h *handler) migrateShibbolethSecrets(unstructuredConfig runtime.Unstructured) (runtime.Object, error) { + shibbConfig := &apimgmtv3.ShibbolethConfig{} + err := common.Decode(unstructuredConfig.UnstructuredContent(), shibbConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode ShibbolethConfig: %w", err) + } + + if shibbConfig.OpenLdapConfig.ServiceAccountPassword == "" { + // OpenLDAP is not configured, so nothing else is needed + return shibbConfig, nil + } + + secretName := fmt.Sprintf("%s-%s", strings.ToLower(shibbConfig.Type), serviceAccountPasswordFieldName) + lowercaseFieldName := strings.ToLower(serviceAccountPasswordFieldName) + + // cannot use createOrUpdateSecretForCredential because the credential is saved in the secret with a key of + // "credential", but our AuthProviders look for "serviceaccountpassword" + secret, err := h.migrator.createOrUpdateSecret( + secretName, + namespace.GlobalNamespace, + map[string]string{ + lowercaseFieldName: shibbConfig.OpenLdapConfig.ServiceAccountPassword, + }, + nil, + shibbConfig, + authConfigKind, + lowercaseFieldName) + if err != nil { + return nil, err + } + + shibbConfig.OpenLdapConfig.ServiceAccountPassword = common.NameForSecret(secret) + + return shibbConfig, nil +} + +// migrateOKTASecrets effects the migration of secrets for the OKTA provider. +func (h *handler) migrateOKTASecrets(unstructuredConfig runtime.Unstructured) (runtime.Object, error) { + oktaConfig := &apimgmtv3.OKTAConfig{} + err := common.Decode(unstructuredConfig.UnstructuredContent(), oktaConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode OKTAConfig: %w", err) + } + + if oktaConfig.OpenLdapConfig.ServiceAccountPassword == "" { + // OpenLDAP is not configured, so nothing else is needed + return oktaConfig, nil + } + secretName := fmt.Sprintf("%s-%s", strings.ToLower(oktaConfig.Type), serviceAccountPasswordFieldName) + lowercaseFieldName := strings.ToLower(serviceAccountPasswordFieldName) + + // cannot use createOrUpdateSecretForCredential because the credential is saved in the secret with a key of + // "credential", but our AuthProviders look for "serviceaccountpassword" + _, err = h.migrator.createOrUpdateSecret( + secretName, + namespace.GlobalNamespace, + map[string]string{ + lowercaseFieldName: oktaConfig.OpenLdapConfig.ServiceAccountPassword, + }, + nil, + oktaConfig, + authConfigKind, + lowercaseFieldName) + if err != nil { + return nil, err + } + + lowerType := strings.ToLower(oktaConfig.Type) + fullSecretName := common.GetFullSecretName(lowerType, serviceAccountPasswordFieldName) + oktaConfig.OpenLdapConfig.ServiceAccountPassword = fullSecretName + + return oktaConfig, nil +} + +func setUnstructuredStatus(unstructured runtime.Unstructured, key condition.Cond, value corev1.ConditionStatus) (runtime.Unstructured, error) { + content := unstructured.UnstructuredContent() + status, ok := content["status"].(map[string]any) + if !ok { + status = map[string]any{} + } + + var authConfigStatus apimgmtv3.AuthConfigStatus + if err := mapstructure.Decode(status, &authConfigStatus); err != nil { + return nil, err + } + var found bool + for i, cond := range authConfigStatus.Conditions { + if cond.Type == key { + authConfigStatus.Conditions[i].Status = value + found = true + break + } + } + if !found { + authConfigStatus.Conditions = append(authConfigStatus.Conditions, apimgmtv3.AuthConfigConditions{ + Type: key, + Status: value, + }) + } + newBytes, err := json.Marshal(authConfigStatus) + if err != nil { + return nil, fmt.Errorf("failed to re-marshal auth config status to bytes %w", err) + } + var newContent map[string]any + if err := json.Unmarshal(newBytes, &newContent); err != nil { + return nil, fmt.Errorf("failed to unmarshal auth config status as bytes to map %w", err) + } + content["status"] = newContent + + unstructured.SetUnstructuredContent(content) + return unstructured, nil +} + +// getUnstructuredAuthConfig attempts to get the unstructured AuthConfig for the AuthConfig that is passed in. +func getUnstructuredAuthConfigByName(unstructuredClient authConfigsClient, name string) (runtime.Unstructured, error) { + unstructuredAuthConfig, err := unstructuredClient.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve unstructured data for AuthConfig from cluster: %w", err) + } + + unstructured, ok := unstructuredAuthConfig.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to read unstructured data for AuthConfig") + } + + return unstructured, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig_test.go new file mode 100644 index 0000000..a0c3c5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/authconfig_test.go @@ -0,0 +1,637 @@ +package secretmigrator + +import ( + "fmt" + "reflect" + "strings" + "testing" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/condition" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/saml" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + corefakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/rancher/rancher/pkg/namespace" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + testPassword = "testpass1234" + testCreationStampString = "2023-05-15T19:28:22Z" +) + +func TestSetUnstructuredStatus(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + input unstructuredConfig + output unstructuredConfig + }{ + { + name: "config with no status", + input: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + }, + }, + output: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "True", + "type": "SecretsMigrated", + }, + }, + }, + }, + }, + }, + { + name: "config has a status with no conditions", + input: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{}, + }, + }, + output: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "True", + "type": "SecretsMigrated", + }, + }, + }, + }, + }, + }, + { + name: "config has a status with no matching conditions", + input: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "Foo", + "type": "Something", + }, + }, + }, + }, + }, + output: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "Foo", + "type": "Something", + }, + map[string]any{ + "status": "True", + "type": "SecretsMigrated", + }, + }, + }, + }, + }, + }, + { + name: "config has a status with matching condition", + input: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "Unknown", + "type": "SecretsMigrated", + }, + }, + }, + }, + }, + output: unstructuredConfig{ + values: map[string]any{ + "foo": "bar", + "status": map[string]any{ + "conditions": []any{ + map[string]any{ + "status": "True", + "type": "SecretsMigrated", + }, + }, + }, + }, + }, + }, + } + + const cond = apimgmtv3.AuthConfigConditionSecretsMigrated + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + got, err := setUnstructuredStatus(&test.input, cond, "True") + if err != nil { + t.Fatalf("got an unexpected error: %v", err) + } + if !reflect.DeepEqual(got, &test.output) { + t.Errorf("expected %+v, got %+v", test.output, got) + } + }) + } + +} + +type unstructuredConfig struct { + values map[string]any +} + +func (c *unstructuredConfig) UnstructuredContent() map[string]interface{} { + return c.values +} + +func (c *unstructuredConfig) SetUnstructuredContent(m map[string]interface{}) { + c.values = m +} + +func (c *unstructuredConfig) GetObjectKind() schema.ObjectKind { + panic("implement me") +} + +// EachListItemWithAlloc implements runtime.Unstructured. +func (*unstructuredConfig) EachListItemWithAlloc(func(runtime.Object) error) error { + panic("implement me") +} + +func (c *unstructuredConfig) DeepCopyObject() runtime.Object { + panic("implement me") +} + +func (c *unstructuredConfig) NewEmptyInstance() runtime.Unstructured { + panic("implement me") +} + +func (c *unstructuredConfig) IsList() bool { + panic("implement me") +} + +func (c *unstructuredConfig) EachListItem(f func(runtime.Object) error) error { + panic("implement me") +} + +func TestShibbolethAuthConfigMigration(t *testing.T) { + errorCreateSecret := fmt.Errorf("failed to create secret") + + testcases := []struct { + name string + unstructuredAuthConfig map[string]any + authConfig apimgmtv3.AuthConfig + expectedSecretName string + expectedError bool + openLDAPEnabled bool + expectedErrorCreateSecret bool + wantConditions []condition.Cond + wantSecretRef string + }{ + { + name: "test migrating Shibboleth configuration with openLDAP", + expectedSecretName: fmt.Sprintf("shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + authConfig: newTestShibbolethConfig(), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(withOpenLDAP), + expectedError: false, + openLDAPEnabled: true, + wantConditions: []condition.Cond{ + apimgmtv3.AuthConfigConditionSecretsMigrated, + apimgmtv3.AuthConfigConditionShibbolethSecretFixed, + }, + wantSecretRef: fmt.Sprintf("cattle-global-data:shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + }, + { + name: "test migrating existing Shibboleth config", + authConfig: newTestShibbolethConfig(func(ac *apimgmtv3.AuthConfig) { + ac.Status = apimgmtv3.AuthConfigStatus{ + Conditions: []apimgmtv3.AuthConfigConditions{ + apimgmtv3.AuthConfigConditions{ + Type: apimgmtv3.AuthConfigConditionSecretsMigrated, + Status: "True", + LastUpdateTime: "2024-05-13T15:20:34+01:00", + }, + }, + } + }), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(), + wantConditions: []condition.Cond{}, + }, + { + name: "test migrating Shibboleth configuration without OpenLDAP", + authConfig: newTestShibbolethConfig(), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(), + expectedError: false, + openLDAPEnabled: false, + wantConditions: []condition.Cond{apimgmtv3.AuthConfigConditionSecretsMigrated}, + wantSecretRef: fmt.Sprintf("cattle-global-data:shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + }, + { + name: "test migrating non Shibboleth configuration", + authConfig: getMockNonShibbolethConfig(), + expectedError: false, + openLDAPEnabled: false, + wantConditions: []condition.Cond{}, + }, + { + name: "test migrating Shibboleth with incorrect secret name", + authConfig: newTestShibbolethConfig(func(ac *apimgmtv3.AuthConfig) { + ac.Status = apimgmtv3.AuthConfigStatus{ + Conditions: []apimgmtv3.AuthConfigConditions{ + apimgmtv3.AuthConfigConditions{ + Type: apimgmtv3.AuthConfigConditionSecretsMigrated, + Status: "True", + LastUpdateTime: "2024-05-13T15:20:34+01:00", + }, + }, + } + }), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(func(s map[string]any) { + s["openLdapConfig"] = map[string]any{ + // This is the incorrect secret name from SURE-7772 + "serviceAccountPassword": "cattle-global-data:shibbolethconfig-serviceAccountPassword", + } + }), + expectedError: false, + openLDAPEnabled: true, + wantConditions: []condition.Cond{ + apimgmtv3.AuthConfigConditionShibbolethSecretFixed, + }, + wantSecretRef: fmt.Sprintf("cattle-global-data:shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + }, + { + name: "test migrating Shibboleth with different secret name", + authConfig: newTestShibbolethConfig(func(ac *apimgmtv3.AuthConfig) { + ac.Status = apimgmtv3.AuthConfigStatus{ + Conditions: []apimgmtv3.AuthConfigConditions{ + apimgmtv3.AuthConfigConditions{ + Type: apimgmtv3.AuthConfigConditionSecretsMigrated, + Status: "True", + LastUpdateTime: "2024-05-13T15:20:34+01:00", + }, + }, + } + }), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(func(s map[string]any) { + s["openLdapConfig"] = map[string]any{ + // This is perhaps a user-configured name. + "serviceAccountPassword": "cattle-global-data:testing-Password", + } + }), + expectedError: false, + openLDAPEnabled: true, + wantConditions: []condition.Cond{ + apimgmtv3.AuthConfigConditionShibbolethSecretFixed, + }, + wantSecretRef: fmt.Sprintf("cattle-global-data:testing-Password"), + }, + { + name: "test migrating Shibboleth without migrated secret", + expectedSecretName: fmt.Sprintf("shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + authConfig: newTestShibbolethConfig(), + unstructuredAuthConfig: getUnstructuredShibbolethConfig(func(s map[string]any) { + s["openLdapConfig"] = map[string]any{ + "serviceAccountPassword": testPassword, + } + }), + expectedError: false, + openLDAPEnabled: true, + wantConditions: []condition.Cond{ + apimgmtv3.AuthConfigConditionSecretsMigrated, + apimgmtv3.AuthConfigConditionShibbolethSecretFixed, + }, + wantSecretRef: fmt.Sprintf("cattle-global-data:shibbolethconfig-%s", strings.ToLower(serviceAccountPasswordFieldName)), + }, + } + + conditionTypes := func(s apimgmtv3.AuthConfigStatus) []condition.Cond { + var result []condition.Cond + for _, c := range s.Conditions { + result = append(result, c.Type) + } + + return result + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + h := newFakeHandler( + tt.unstructuredAuthConfig, + func(secret *corev1.Secret) (*corev1.Secret, error) { + if tt.expectedErrorCreateSecret { + return nil, errorCreateSecret + } + + assert.Equal(t, tt.expectedSecretName, secret.Name, "secret name did not match") + assert.Equal(t, namespace.GlobalNamespace, secret.Namespace) + assert.Equal(t, testPassword, secret.StringData[strings.ToLower(serviceAccountPasswordFieldName)]) + + return secret, nil + }, + func(secret *corev1.Secret) (*corev1.Secret, error) { + return nil, nil + }, + func(namespace string, name string) (*corev1.Secret, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "secrets"}, name) + }, + ) + + config, err := h.syncAuthConfig("test", &tt.authConfig) + + if tt.openLDAPEnabled { + if tt.expectedError { + assert.Error(t, err) + assert.Nil(t, config) + return + } + + if tt.expectedErrorCreateSecret { + assert.Error(t, err) + assert.True(t, errors.Is(err, errorCreateSecret)) + assert.Nil(t, config) + return + } + + assert.NotNil(t, config) + assert.NoError(t, err) + + shibbConfig := config.(*apimgmtv3.ShibbolethConfig) + + assert.NotNil(t, shibbConfig) + + assert.Equal(t, tt.wantConditions, conditionTypes(shibbConfig.Status)) + assert.Equal(t, tt.authConfig.ObjectMeta, shibbConfig.SamlConfig.ObjectMeta) + assert.Equal(t, tt.authConfig.TypeMeta, shibbConfig.SamlConfig.TypeMeta) + assert.Equal(t, tt.wantSecretRef, shibbConfig.OpenLdapConfig.ServiceAccountPassword) + + return + } + + assert.NoError(t, err) + assert.NotNil(t, config) + }) + } +} + +func TestOKTAAuthConfigMigration(t *testing.T) { + timeStamp, _ := time.Parse(time.RFC3339, testCreationStampString) + testcases := []struct { + name string + unstructuredAuthConfig map[string]any + authConfig apimgmtv3.AuthConfig + expectedLdapConfig apimgmtv3.LdapFields + wantStringData map[string]string + // wantMigration is true when we expect the migration to execute + wantMigration bool + }{ + { + name: "test migrating OKTA configuration with openLDAP", + unstructuredAuthConfig: getUnstructuredOKTA(withOpenLDAP), + authConfig: apimgmtv3.AuthConfig{ + Type: "oktaConfig", + Enabled: true, + ObjectMeta: metav1.ObjectMeta{ + Name: "okta", + CreationTimestamp: metav1.NewTime(timeStamp), + }, + TypeMeta: metav1.TypeMeta{ + Kind: "AuthConfig", + APIVersion: "management.cattle.io/v3", + }, + }, + expectedLdapConfig: apimgmtv3.LdapFields{ + ServiceAccountPassword: "cattle-global-data:oktaconfig-serviceaccountpassword", + }, + wantStringData: map[string]string{ + "serviceaccountpassword": "testpass1234", + }, + wantMigration: true, + }, + { + name: "test migrating with existing migration", + unstructuredAuthConfig: getUnstructuredOKTA(withOpenLDAP), + wantMigration: true, + authConfig: apimgmtv3.AuthConfig{ + Type: "oktaConfig", + Enabled: true, + ObjectMeta: metav1.ObjectMeta{ + Name: "okta", + CreationTimestamp: metav1.NewTime(timeStamp), + }, + TypeMeta: metav1.TypeMeta{ + Kind: "AuthConfig", + APIVersion: "management.cattle.io/v3", + }, + Status: apimgmtv3.AuthConfigStatus{ + Conditions: []apimgmtv3.AuthConfigConditions{ + apimgmtv3.AuthConfigConditions{ + Type: apimgmtv3.AuthConfigConditionSecretsMigrated, + Status: "True", + LastUpdateTime: "2024-05-13T15:20:34+01:00", + LastTransitionTime: "", + Reason: "", + Message: "", + }, + }, + }, + }, + expectedLdapConfig: apimgmtv3.LdapFields{ + ServiceAccountPassword: "cattle-global-data:oktaconfig-serviceaccountpassword", + }, + wantStringData: map[string]string{ + "serviceaccountpassword": "testpass1234", + }, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + h := newFakeHandler( + tt.unstructuredAuthConfig, + func(secret *corev1.Secret) (*corev1.Secret, error) { + assert.Equal(t, "oktaconfig-serviceaccountpassword", secret.Name) + assert.Equal(t, namespace.GlobalNamespace, secret.Namespace) + assert.Equal(t, tt.wantStringData, secret.StringData) + + return secret, nil + }, + func(secret *corev1.Secret) (*corev1.Secret, error) { + return nil, nil + }, + func(namespace string, name string) (*corev1.Secret, error) { + return nil, apierrors.NewNotFound(schema.GroupResource{Resource: "secrets"}, name) + }, + ) + + config, err := h.syncAuthConfig("test", &tt.authConfig) + + assert.NotNil(t, config) + assert.NoError(t, err) + + oktaConfig, ok := config.(*apimgmtv3.OKTAConfig) + + assert.Equal(t, tt.wantMigration, ok) + if !tt.wantMigration { + return + } + assert.NotNil(t, oktaConfig) + + assert.NotEmpty(t, oktaConfig.Status.Conditions) + assert.NotNil(t, oktaConfig.Status.Conditions[0]) + assert.Equal(t, apimgmtv3.AuthConfigOKTAPasswordMigrated, oktaConfig.Status.Conditions[0].Type) + assert.Equal(t, tt.expectedLdapConfig, oktaConfig.OpenLdapConfig) + }) + } +} + +func newFakeHandler( + authConfig map[string]any, + secretCreateFunc func(*corev1.Secret) (*corev1.Secret, error), + secretUpdateFunc func(*corev1.Secret) (*corev1.Secret, error), + secretGetFunc func(string, string) (*corev1.Secret, error), +) *handler { + secretInterfaceMock := corefakes.SecretInterfaceMock{ + CreateFunc: secretCreateFunc, + UpdateFunc: secretUpdateFunc, + } + + secretListerMock := corefakes.SecretListerMock{ + GetFunc: secretGetFunc, + } + + h := &handler{ + migrator: NewMigrator(&secretListerMock, &secretInterfaceMock), + authConfigs: newMockAuthConfigClient(authConfig), + authConfigLister: &fakes.AuthConfigListerMock{}, + } + return h +} + +func newTestShibbolethConfig(opts ...func(*apimgmtv3.AuthConfig)) apimgmtv3.AuthConfig { + timeStamp, _ := time.Parse(time.RFC3339, testCreationStampString) + ac := apimgmtv3.AuthConfig{ + Type: "shibbolethConfig", + Enabled: true, + ObjectMeta: metav1.ObjectMeta{ + Name: saml.ShibbolethName, + CreationTimestamp: metav1.NewTime(timeStamp), + }, + TypeMeta: metav1.TypeMeta{ + Kind: "AuthConfig", + APIVersion: "management.cattle.io/v3", + }, + } + + for _, opt := range opts { + opt(&ac) + } + + return ac +} + +func getMockNonShibbolethConfig() apimgmtv3.AuthConfig { + return apimgmtv3.AuthConfig{ + Type: "NOTshibbolethConfig", + Enabled: true, + ObjectMeta: metav1.ObjectMeta{ + Name: "fake", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "AuthConfig", + APIVersion: "management.cattle.io/v3", + }, + } +} + +func withOpenLDAP(s map[string]any) { + s["openLdapConfig"] = map[string]any{ + "serviceAccountPassword": testPassword, + } +} + +func getUnstructuredShibbolethConfig(opts ...func(map[string]any)) map[string]any { + timeStamp, _ := time.Parse(time.RFC3339, testCreationStampString) + createdTime := metav1.NewTime(timeStamp) + + raw := map[string]any{ + "metadata": map[string]any{ + "name": saml.ShibbolethName, + "creationtimestamp": createdTime, + }, + "kind": "AuthConfig", + "apiVersion": "management.cattle.io/v3", + "type": client.ShibbolethConfigType, + "enabled": true, + } + + for _, o := range opts { + o(raw) + } + + return raw +} + +func getUnstructuredOKTA(opts ...func(map[string]any)) map[string]any { + timeStamp, _ := time.Parse(time.RFC3339, testCreationStampString) + createdTime := metav1.NewTime(timeStamp) + + raw := map[string]any{ + "metadata": map[string]any{ + "name": "okta", + "creationtimestamp": createdTime, + }, + "kind": "AuthConfig", + "apiVersion": "management.cattle.io/v3", + "type": client.OKTAConfigType, + "enabled": true, + "serviceAccountPassword": testPassword, + } + + for _, o := range opts { + o(raw) + } + + return raw +} + +type mockAuthConfigClient struct { + config map[string]any +} + +func newMockAuthConfigClient(authConfig map[string]any) authConfigsClient { + return mockAuthConfigClient{config: authConfig} +} + +func (m mockAuthConfigClient) Get(name string, opts metav1.GetOptions) (runtime.Object, error) { + o := unstructured.Unstructured{} + o.SetUnstructuredContent(m.config) + return &o, nil +} + +func (m mockAuthConfigClient) Update(name string, o runtime.Object) (runtime.Object, error) { + return o, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalog/assemblers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalog/assemblers.go new file mode 100644 index 0000000..580cb86 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalog/assemblers.go @@ -0,0 +1,28 @@ +package catalog + +import ( + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/sirupsen/logrus" +) + +const secretKey = "credential" + +// AssembleCatalogCredential looks up the Catalog Secret and inserts the value into the catalog spec. +// It returns a new copy of the Spec without modifying the original. The Catalog is never updated. +func AssembleCatalogCredential(catalog *apimgmtv3.Catalog, secretLister v1.SecretLister) (apimgmtv3.CatalogSpec, error) { + if catalog.GetSecret() == "" { + if catalog.Spec.Password != "" { + logrus.Warnf("[secretmigrator] secrets for catalog %s are not finished migrating", catalog.Name) + } + return catalog.Spec, nil + } + secret, err := secretLister.Get(namespace.GlobalNamespace, catalog.GetSecret()) + if err != nil { + return catalog.Spec, err + } + spec := catalog.Spec.DeepCopy() + spec.Password = string(secret.Data[secretKey]) + return *spec, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalogs.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalogs.go new file mode 100644 index 0000000..11313a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/catalogs.go @@ -0,0 +1,57 @@ +package secretmigrator + +import ( + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func (h *handler) syncCatalog(key string, catalog *v3.Catalog) (runtime.Object, error) { + if catalog == nil || catalog.DeletionTimestamp != nil { + return catalog, nil + } + + obj, err := apimgmtv3.CatalogConditionSecretsMigrated.DoUntilTrue(catalog, func() (runtime.Object, error) { + if catalog.Status.CredentialSecret == "" && catalog.Spec.Password != "" { + logrus.Tracef("[secretmigrator] migrating secrets for global catalog %s", catalog.Name) + secret, err := h.migrator.CreateOrUpdateCatalogSecret("", catalog.Spec.Password, catalog) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for global catalog %s, will retry: %v", catalog.Name, err) + return nil, err + } + if secret != nil { + logrus.Tracef("[secretmigrator] secret found for global catalog %s", catalog.Name) + catalog.Status.CredentialSecret = secret.Name + catalog.Spec.Password = "" + catalogCopy, err := h.catalogs.Update(catalog) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for global catalog %s, will retry: %v", catalog.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return nil, err + } + catalog = catalogCopy + } + } + + logrus.Tracef("[secretmigrator] setting catalog condition and updating catalog %s", catalog.Name) + apimgmtv3.CatalogConditionSecretsMigrated.True(catalog) + return h.catalogs.Update(catalog) + }) + return obj.(*v3.Catalog), err +} + +// CreateOrUpdateCatalogSecret accepts an optional secret name and a catalog password +// and creates a Secret for the credential if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateCatalogSecret(secretName, password string, owner runtime.Object) (*corev1.Secret, error) { + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, password, nil, owner, "catalog", "password") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/cloudconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/cloudconfig.go new file mode 100644 index 0000000..05f669f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/cloudconfig.go @@ -0,0 +1,56 @@ +package secretmigrator + +import ( + "strings" + + "github.com/rancher/norman/types/convert" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// cloudConfigSecretRemover deletes any detected secrets within the clusters cloud-provider-config +// field which have the expected secret format, the AuthorizedSecretAnnotation, +// and the AuthorizedSecretDeletesOnClusterRemovalAnnotation. Secrets without the AuthorizedSecretDeletesOnClusterRemovalAnnotation +// annotation are not removed, and are assumed to be user created. Only secrets without any OwnerReferences are removed. +func (h *handler) cloudConfigSecretRemover(_ string, cluster *v1.Cluster) (*v1.Cluster, error) { + if cluster == nil || cluster.Spec.RKEConfig == nil || cluster.Name == "local" { + return cluster, nil + } + + for _, e := range cluster.Spec.RKEConfig.MachineSelectorConfig { + cloudProviderConfig := convert.ToString(e.Config.Data["cloud-provider-config"]) + + // check if the cloud-provider-config value points to a secret + if cloudProviderConfig == "" || !strings.HasPrefix(cloudProviderConfig, "secret://") { + continue + } + + cleanSecretNamespaceAndName := strings.TrimPrefix(cloudProviderConfig, "secret://") + namespaceAndName := strings.Split(cleanSecretNamespaceAndName, ":") + + // ensure the secret format is proper + if len(namespaceAndName) != 2 { + logrus.Errorf("[cloud-config-secret-remover] error encountered while handling secrets deletion for cloud-provider-config: provided secret value is not of form secret://namespace:name") + continue + } + + secret, err := h.migrator.secrets.GetNamespaced(namespaceAndName[0], namespaceAndName[1], metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[cloud-config-secret-remover] error encountered while retrieving secret %s:%s defined within cloud-provider-config: %s", namespaceAndName[0], namespaceAndName[1], err) + continue + } + + authorizedForCluster := secret.Annotations[AuthorizedSecretAnnotation] + deleteSecretOnClusterRemoval := secret.Annotations[AuthorizedSecretDeletesOnClusterRemovalAnnotation] + + if authorizedForCluster == cluster.Name && deleteSecretOnClusterRemoval == "true" { + if len(secret.OwnerReferences) == 0 { + h.migrator.CleanupKnownSecrets([]*corev1.Secret{secret}) + } + } + } + + return cluster, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters.go new file mode 100644 index 0000000..9191eda --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters.go @@ -0,0 +1,1112 @@ +package secretmigrator + +import ( + "encoding/json" + "fmt" + "reflect" + "regexp" + "strings" + + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + "github.com/rancher/rancher/pkg/fleet" + + "github.com/rancher/norman/types/convert" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kubernetes/pkg/credentialprovider" +) + +const ( + SecretNamespace = assemblers.SecretNamespace + SecretKey = assemblers.SecretKey + S3BackupAnswersPath = "rancherKubernetesEngineConfig.services.etcd.backupConfig.s3BackupConfig.secretKey" + WeavePasswordAnswersPath = "rancherKubernetesEngineConfig.network.weaveNetworkProvider.password" + RegistryPasswordAnswersPath = "rancherKubernetesEngineConfig.privateRegistries[%d].password" + VsphereGlobalAnswersPath = "rancherKubernetesEngineConfig.cloudProvider.vsphereCloudProvider.global.password" + VcenterAnswersPath = "rancherKubernetesEngineConfig.cloudProvider.vsphereCloudProvider.virtualCenter[%s].password" + OpenStackAnswersPath = "rancherKubernetesEngineConfig.cloudProvider.openstackCloudProvider.global.password" + AADClientAnswersPath = "rancherKubernetesEngineConfig.cloudProvider.azureCloudProvider.aadClientSecret" + AADCertAnswersPath = "rancherKubernetesEngineConfig.cloudProvider.azureCloudProvider.aadClientCertPassword" + ACIUserKeyAnswersPath = "rancherKubernetesEngineConfig.network.aciNetworkProvider.apicUserKey" + ACITokenAnswersPath = "rancherKubernetesEngineConfig.network.aciNetworkProvider.token" + ACIKafkaClientKeyAnswersPath = "rancherKubernetesEngineConfig.network.aciNetworkProvider.kafkaClientKey" +) + +var PrivateRegistryQuestion = regexp.MustCompile(`rancherKubernetesEngineConfig.privateRegistries[[0-9]+].password`) +var VcenterQuestion = regexp.MustCompile(`rancherKubernetesEngineConfig.cloudProvider.vsphereCloudProvider.virtualCenter\[.+\].password`) + +func (h *handler) sync(_ string, cluster *apimgmtv3.Cluster) (runtime.Object, error) { + if cluster == nil || cluster.DeletionTimestamp != nil { + return cluster, nil + } + + var err error + cluster, err = h.migrateClusterSecrets(cluster) + if err != nil { + // cluster is returned here since multiple updates take place in migrateClusterSecrets and the object + // will be set according to most up to date + return cluster, err + } + + cluster, err = h.migrateServiceAccountSecrets(cluster) + if err != nil { + return cluster, err + } + + cluster, err = h.migrateRKESecrets(cluster) + if err != nil { + return cluster, err + } + + return h.migrateACISecrets(cluster) +} + +type CreateOrUpdateSecretFunc func(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) + +// CreateOrUpdatePrivateRegistrySecret accepts an optional secret name and a RancherKubernetesEngineConfig object and creates a dockerconfigjson Secret +// containing the login credentials for every registry in the array, if there are any. +// If an owner is passed, the owner is set as an owner reference on the Secret. If no owner is passed, +// the caller is responsible for calling UpdateSecretOwnerReference once the owner is known. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdatePrivateRegistrySecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil { + return nil, nil + } + rkeConfig = rkeConfig.DeepCopy() + privateRegistries := rkeConfig.PrivateRegistries + if len(privateRegistries) == 0 { + return nil, nil + } + var existing *corev1.Secret + var err error + if secretName != "" { + existing, err = m.secretLister.Get(SecretNamespace, secretName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + } + registry := credentialprovider.DockerConfigJSON{ + Auths: map[string]credentialprovider.DockerConfigEntry{}, + } + active := make(map[string]struct{}) + registrySecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, // if empty, the secret will be created with a generated name + GenerateName: "cluster-registry-", + Namespace: SecretNamespace, + }, + Data: map[string][]byte{}, + Type: corev1.SecretTypeDockerConfigJson, + } + if owner != nil { + gvk := owner.GetObjectKind().GroupVersionKind() + accessor, err := meta.Accessor(owner) + if err != nil { + return nil, err + } + registrySecret.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: gvk.Group + "/" + gvk.Version, + Kind: gvk.Kind, + Name: accessor.GetName(), + UID: accessor.GetUID(), + }, + } + } + if existing != nil { + err = json.Unmarshal(existing.Data[corev1.DockerConfigJsonKey], ®istry) + if err != nil { + return nil, err + } + } + for _, privateRegistry := range privateRegistries { + active[privateRegistry.URL] = struct{}{} + // If the existing private registry is NOT changed when the cluster is updated, the password will be empty as + // it has been cleaned up in the previous reconciliation and the username will match the existing value. It is + // the only case where Rancher should not update the secret to prevent from wiping the password from the secret. + if privateRegistry.Password == "" && privateRegistry.User != "" { + if v, ok := registry.Auths[privateRegistry.URL]; ok { + if privateRegistry.User == v.Username { + continue + } + } + } + // empty username or password or both means unsetting the value(s), which is a valid use case + // limitation: if a URL is repeated in the privateRegistries list, it will be overwritten in the registry secret + registry.Auths[privateRegistry.URL] = credentialprovider.DockerConfigEntry{ + Username: privateRegistry.User, + Password: privateRegistry.Password, + } + } + registryJSON, err := json.Marshal(registry) + if err != nil { + return nil, err + } + registrySecret.Data = map[string][]byte{ + corev1.DockerConfigJsonKey: registryJSON, + } + if existing == nil { + registrySecret, err = m.secrets.Create(registrySecret) + if err != nil { + return nil, err + } + } else { + for url := range registry.Auths { + if _, ok := active[url]; !ok { + delete(registry.Auths, url) + } + } + registrySecret.Data[corev1.DockerConfigJsonKey], err = json.Marshal(registry) + if err != nil { + return nil, err + } + if !reflect.DeepEqual(existing.Data, registrySecret.Data) { + return m.secrets.Update(registrySecret) + } + } + return registrySecret, nil +} + +// CleanRegistries unsets the password of every private registry in the list. +// Must be called after passwords have been migrated. +func CleanRegistries(privateRegistries []rketypes.PrivateRegistry) []rketypes.PrivateRegistry { + for i := range privateRegistries { + privateRegistries[i].Password = "" + } + return privateRegistries +} + +// UpdateSecretOwnerReference sets an object as owner of a given Secret and updates the Secret. +// The object must be a non-namespaced resource. +func (m *Migrator) UpdateSecretOwnerReference(secret *corev1.Secret, owner metav1.OwnerReference) error { + if len(secret.OwnerReferences) == 0 || !reflect.DeepEqual(secret.OwnerReferences[0], owner) { + secret.OwnerReferences = []metav1.OwnerReference{owner} + _, err := m.secrets.Update(secret) + return err + } + return nil +} + +// createOrUpdateSecret accepts an optional secret name and tries to update it with the provided data if it exists, or creates it. +// If an owner is provided, it sets it as an owner reference before creating it. If annotations are provided, they are added +// before the secret is created. +func (m *Migrator) createOrUpdateSecret(secretName, secretNamespace string, data, annotations map[string]string, owner runtime.Object, kind, field string) (*corev1.Secret, error) { + var existing *corev1.Secret + var err error + if secretName != "" { + existing, err = m.secretLister.Get(secretNamespace, secretName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + GenerateName: fmt.Sprintf("%s-%s-", kind, field), + Namespace: secretNamespace, + }, + StringData: data, + Type: corev1.SecretTypeOpaque, + } + if owner != nil { + gvk := owner.GetObjectKind().GroupVersionKind() + accessor, err := meta.Accessor(owner) + if err != nil { + return nil, err + } + secret.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: gvk.Group + "/" + gvk.Version, + Kind: gvk.Kind, + Name: accessor.GetName(), + UID: accessor.GetUID(), + }, + } + } + if annotations != nil { + secret.Annotations = annotations + } + if existing == nil { + return m.secrets.Create(secret) + } + if !reflect.DeepEqual(existing.StringData, secret.StringData) { + existing.StringData = data + return m.secrets.Update(existing) + } + + return secret, nil +} + +// createOrUpdateSecretForCredential accepts an optional secret name and a value containing the data that needs to be sanitized, +// and creates a secret to hold the sanitized data. If an owner is passed, the owner is set as an owner reference on the secret. +func (m *Migrator) createOrUpdateSecretForCredential(secretName, secretNamespace, secretValue string, annotations map[string]string, owner runtime.Object, kind, field string) (*corev1.Secret, error) { + if secretValue == "" { + if secretName == "" { + logrus.Debugf("Secret name is empty") + } + logrus.Debugf("Refusing to create empty secret [%s]/[%s]", secretNamespace, secretName) + return nil, nil + } + data := map[string]string{ + SecretKey: secretValue, + } + secret, err := m.createOrUpdateSecret(secretName, secretNamespace, data, annotations, owner, kind, field) + if err != nil { + return nil, fmt.Errorf("error creating secret for credential: %w", err) + } + return secret, nil +} + +// CreateOrUpdateS3Secret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the S3BackupConfig credentials if there are any. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateS3Secret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.Services.Etcd.BackupConfig == nil || rkeConfig.Services.Etcd.BackupConfig.S3BackupConfig == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey, nil, owner, "cluster", "s3backup") +} + +// CreateOrUpdateWeaveSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the Weave CNI password if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateWeaveSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.Network.WeaveNetworkProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.Network.WeaveNetworkProvider.Password, nil, owner, "cluster", "weave") +} + +// CreateOrUpdateVsphereGlobalSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the Vsphere global password if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateVsphereGlobalSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.CloudProvider.VsphereCloudProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.CloudProvider.VsphereCloudProvider.Global.Password, nil, owner, "cluster", "vsphereglobal") +} + +// CreateOrUpdateVsphereVirtualCenterSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the Vsphere VirtualCenter password if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateVsphereVirtualCenterSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.CloudProvider.VsphereCloudProvider == nil { + return nil, nil + } + data := map[string]string{} + for k, v := range rkeConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + if v.Password != "" { + data[k] = v.Password + } + } + if len(data) == 0 { + return nil, nil + } + return m.createOrUpdateSecret(secretName, SecretNamespace, data, nil, owner, "cluster", "vspherevcenter") +} + +// CreateOrUpdateOpenStackSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the OpenStack password if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateOpenStackSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.CloudProvider.OpenstackCloudProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.CloudProvider.OpenstackCloudProvider.Global.Password, nil, owner, "cluster", "openstack") +} + +// CreateOrUpdateAADClientSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the AAD client secret if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateAADClientSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.CloudProvider.AzureCloudProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.CloudProvider.AzureCloudProvider.AADClientSecret, nil, owner, "cluster", "aadclientsecret") +} + +// CreateOrUpdateAADCertSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the AAD client cert password if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateAADCertSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.CloudProvider.AzureCloudProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword, nil, owner, "cluster", "aadcert") +} + +// CreateOrUpdateSourceCodeProviderConfigSecret accepts an optional secret name and a client secret or +// private key for a SourceCodeProviderConfig and creates a Secret for the credential if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateSourceCodeProviderConfigSecret(secretName string, credential string, owner runtime.Object, provider string) (*corev1.Secret, error) { + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, credential, nil, owner, "sourcecodeproviderconfig", provider) +} + +// CreateOrUpdateHarvesterCloudConfigSecret accepts an optional secret name and a client secret or +// harvester cloud-provider-config and creates a Secret for the credential if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateHarvesterCloudConfigSecret(secretName string, credential string, annotations map[string]string, owner runtime.Object, provider string) (*corev1.Secret, error) { + return m.createOrUpdateSecretForCredential(secretName, fleet.ClustersDefaultNamespace, credential, annotations, owner, "harvester", provider) +} + +// CreateOrUpdateACIAPICUserKeySecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the AciNetworkProvider user key if there are any. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateACIAPICUserKeySecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.Network.AciNetworkProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.Network.AciNetworkProvider.ApicUserKey, nil, owner, "cluster", "acikey") +} + +// CreateOrUpdateACITokenSecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the AciNetworkProvider token if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateACITokenSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.Network.AciNetworkProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.Network.AciNetworkProvider.Token, nil, owner, "cluster", "acitoken") +} + +// CreateOrUpdateACIKafkaClientKeySecret accepts an optional secret name and a RancherKubernetesEngineConfig object +// and creates a Secret for the AciNetworkProvider kafka client key if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateACIKafkaClientKeySecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.Network.AciNetworkProvider == nil { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.Network.AciNetworkProvider.KafkaClientKey, nil, owner, "cluster", "acikafkakey") +} + +// CreateOrUpdateSecretsEncryptionProvidersSecret accepts an optional secret name and an rkeConfig and creates a +// Secret containing the list of Custom Encryption Resources. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// If the desired number of encryption keys is empty, a secret is not created. +// The entire encryption configuration is stored wholesale as a json blob, due to the variable amount of data. +func (m *Migrator) CreateOrUpdateSecretsEncryptionProvidersSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || + rkeConfig.Services.KubeAPI.SecretsEncryptionConfig == nil || + rkeConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig == nil || + len(rkeConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources) == 0 { + return nil, nil + } + data, err := json.Marshal(rkeConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources) + if err != nil { + return nil, err + } + strData := string(data) + if len(strData) == 0 { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, strData, nil, owner, "cluster", "secretsencryptionproviders") +} + +// CreateOrUpdateBastionHostSSHKeySecret accepts an optional secret name and an rkeConfig and creates a +// Secret containing the bastion host ssh key. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// If the ssh key is unset, a secret is not created. +func (m *Migrator) CreateOrUpdateBastionHostSSHKeySecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || rkeConfig.BastionHost.SSHKey == "" { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, rkeConfig.BastionHost.SSHKey, nil, owner, "cluster", "bastionhostsshkey") +} + +// CreateOrUpdateKubeletExtraEnvSecret accepts an optional secret name and an rkeConfig and creates a +// Secret containing the AWS_SECRET_ACCESS_KEY env variable. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// If the environment variable are not present is unset, a secret is not created. +func (m *Migrator) CreateOrUpdateKubeletExtraEnvSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || len(rkeConfig.Services.Kubelet.ExtraEnv) == 0 { + return nil, nil + } + var awsSecretKey string + for _, k := range rkeConfig.Services.Kubelet.ExtraEnv { + s := strings.Split(k, "=") + if len(s) != 2 { + continue + } + key, value := s[0], s[1] + if key == "AWS_SECRET_ACCESS_KEY" { + awsSecretKey = value + break + } + } + if awsSecretKey == "" { + return nil, nil + } + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, awsSecretKey, nil, owner, "cluster", "kubeletextraenv") +} + +// CreateOrUpdatePrivateRegistryECRSecret accepts an optional secret name and an rkeConfig and creates a +// Secret containing the ecr credentials. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// If there are no credentials set, a secret is not created. +func (m *Migrator) CreateOrUpdatePrivateRegistryECRSecret(secretName string, rkeConfig *rketypes.RancherKubernetesEngineConfig, owner runtime.Object) (*corev1.Secret, error) { + if rkeConfig == nil || len(rkeConfig.PrivateRegistries) == 0 { + return nil, nil + } + data := map[string]string{} + for _, v := range rkeConfig.PrivateRegistries { + if v.ECRCredentialPlugin != nil { + if v.ECRCredentialPlugin.AwsSecretAccessKey != "" || v.ECRCredentialPlugin.AwsSessionToken != "" { + ecr := *v.ECRCredentialPlugin + ecr.AwsAccessKeyID = "" + ecrData, err := json.Marshal(&ecr) + if err != nil { + return nil, err + } + data[v.URL] = string(ecrData) + } + } + } + if len(data) == 0 { + return nil, nil + } + b, err := json.Marshal(data) + if err != nil { + return nil, err + } + data = map[string]string{ + SecretKey: string(b), + } + return m.createOrUpdateSecret(secretName, SecretNamespace, data, nil, owner, "cluster", "privateregistryecr") +} + +// Cleanup deletes a secret if provided a secret name, otherwise does nothing. +func (m *Migrator) Cleanup(secretName string) error { + if secretName == "" { + return nil + } + _, err := m.secretLister.Get(SecretNamespace, secretName) + if apierrors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + err = m.secrets.DeleteNamespaced(SecretNamespace, secretName, &metav1.DeleteOptions{}) + return err +} + +// CleanupKnownSecrets deletes a slice of secrets and logs any encountered errors at a WARNING level. +func (m *Migrator) CleanupKnownSecrets(secrets []*corev1.Secret) { + for _, secret := range secrets { + cleanUpErr := m.secrets.DeleteNamespaced(secret.Namespace, secret.Name, &metav1.DeleteOptions{}) + if cleanUpErr != nil { + logrus.Warnf("[secretmigrator] error encountered while handling secrets cleanup for migration error; secret %s:%s may not have been cleaned up: %s", secret.Namespace, secret.Name, cleanUpErr) + } + } +} + +// isHarvesterCluster determines if a v1.Cluster represents a harvester cluster +func (m *Migrator) isHarvesterCluster(cluster *v1.Cluster) bool { + if cluster == nil || cluster.Spec.RKEConfig == nil { + return false + } + + for _, selectorConfig := range cluster.Spec.RKEConfig.MachineSelectorConfig { + if strings.ToLower(convert.ToString(selectorConfig.Config.Data["cloud-provider-name"])) == "harvester" { + return true + } + } + + return false +} + +// CreateOrUpdateServiceAccountTokenSecret accepts an optional secret name and a token string +// and creates a Secret for the cluster service account token if there is one. +// If an owner is passed, the owner is set as an owner reference on the Secret. +// It returns a reference to the Secret if one was created. If the returned Secret is not nil and there is no error, +// the caller is responsible for un-setting the secret data, setting a reference to the Secret, and +// updating the Cluster object, if applicable. +func (m *Migrator) CreateOrUpdateServiceAccountTokenSecret(secretName string, credential string, owner runtime.Object) (*corev1.Secret, error) { + return m.createOrUpdateSecretForCredential(secretName, SecretNamespace, credential, nil, owner, "cluster", "serviceaccounttoken") +} + +// MatchesQuestionPath checks whether the given string matches the question-formatted path of the +// s3 secret, weave password, or registry password. +func MatchesQuestionPath(variable string) bool { + return variable == S3BackupAnswersPath || + variable == WeavePasswordAnswersPath || + PrivateRegistryQuestion.MatchString(variable) || + variable == VsphereGlobalAnswersPath || + VcenterQuestion.MatchString(variable) || + variable == OpenStackAnswersPath || + variable == AADClientAnswersPath || + variable == AADCertAnswersPath || + variable == ACIUserKeyAnswersPath || + variable == ACITokenAnswersPath || + variable == ACIKafkaClientKeyAnswersPath +} + +// cleanQuestions removes credentials from the questions and answers sections of the cluster object. +// Answers are already substituted into the spec in norman, so they can be deleted without migration. +func cleanQuestions(cluster *apimgmtv3.Cluster) { + cleanQuestions := func(questions []apimgmtv3.Question) { + for i, q := range questions { + if MatchesQuestionPath(q.Variable) { + questions[i].Default = "" + } + } + } + if len(cluster.Spec.ClusterTemplateQuestions) > 0 { + cleanQuestions(cluster.Spec.ClusterTemplateQuestions) + } + if len(cluster.Status.AppliedSpec.ClusterTemplateQuestions) > 0 { + cleanQuestions(cluster.Status.AppliedSpec.ClusterTemplateQuestions) + } + if cluster.Status.FailedSpec != nil && len(cluster.Status.FailedSpec.ClusterTemplateQuestions) > 0 { + cleanQuestions(cluster.Status.FailedSpec.ClusterTemplateQuestions) + } + cleanAnswers := func(answers *apimgmtv3.Answer) { + for i := 0; ; i++ { + key := fmt.Sprintf(RegistryPasswordAnswersPath, i) + if _, ok := answers.Values[key]; !ok { + break + } + delete(answers.Values, key) + } + if cluster.Spec.RancherKubernetesEngineConfig != nil && + cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider != nil { + vcenters := cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter + for k := range vcenters { + key := fmt.Sprintf(VcenterAnswersPath, k) + delete(answers.Values, key) + } + } + delete(answers.Values, S3BackupAnswersPath) + delete(answers.Values, WeavePasswordAnswersPath) + delete(answers.Values, VsphereGlobalAnswersPath) + delete(answers.Values, OpenStackAnswersPath) + delete(answers.Values, AADClientAnswersPath) + delete(answers.Values, AADCertAnswersPath) + delete(answers.Values, ACIUserKeyAnswersPath) + delete(answers.Values, ACITokenAnswersPath) + delete(answers.Values, ACIKafkaClientKeyAnswersPath) + } + if cluster.Spec.ClusterTemplateAnswers.Values != nil { + cleanAnswers(&cluster.Spec.ClusterTemplateAnswers) + } + if cluster.Status.AppliedSpec.ClusterTemplateAnswers.Values != nil { + cleanAnswers(&cluster.Status.AppliedSpec.ClusterTemplateAnswers) + } + if cluster.Status.FailedSpec != nil && cluster.Status.FailedSpec.ClusterTemplateAnswers.Values != nil { + cleanAnswers(&cluster.Status.FailedSpec.ClusterTemplateAnswers) + } +} + +type cleanupFunc func(spec *apimgmtv3.ClusterSpec) + +func (h *handler) migrateSecret(cluster *apimgmtv3.Cluster, secretName, secretClass string, secretField *string, createOrUpdateSecret CreateOrUpdateSecretFunc, cleanup cleanupFunc) (*apimgmtv3.Cluster, error) { + if cluster.GetSecret(secretName) != "" { + return cluster, nil + } + logrus.Tracef("[secretmigrator] migrating %s secrets for cluster %s", secretClass, cluster.Name) + secret, err := createOrUpdateSecret(cluster.GetSecret(secretName), cluster.Spec.RancherKubernetesEngineConfig, cluster) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate %s secrets for cluster %s, will retry: %v", secretClass, cluster.Name, err) + return cluster, err + } + if secret != nil { + logrus.Tracef("[secretmigrator] %s found for cluster %s", secretClass, cluster.Name) + *secretField = secret.Name + cleanup(&cluster.Spec) + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + cleanup(&cluster.Status.AppliedSpec) + } + if cluster.Status.FailedSpec != nil && cluster.Status.FailedSpec.RancherKubernetesEngineConfig != nil { + cleanup(cluster.Status.FailedSpec) + } + + clusterCopy, err := h.clusters.Update(cluster) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate %s secrets for cluster %s, will retry: %v", secretClass, cluster.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + cluster = clusterCopy.DeepCopy() + } + return cluster, nil +} + +func (h *handler) migrateClusterSecrets(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if apimgmtv3.ClusterConditionSecretsMigrated.IsTrue(cluster) { + return cluster, nil + } + clusterCopy := cluster.DeepCopy() + var err error + obj, doErr := apimgmtv3.ClusterConditionSecretsMigrated.DoUntilTrue(clusterCopy, func() (runtime.Object, error) { + // s3 backup cred + clusterCopy, err = h.migrateSecret(clusterCopy, "S3CredentialSecret", "S3", &clusterCopy.Spec.ClusterSecrets.S3CredentialSecret, h.migrator.CreateOrUpdateS3Secret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil { + return + } + spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // private registry + clusterCopy, err = h.migrateSecret(clusterCopy, "PrivateRegistrySecret", "private registry", &clusterCopy.Spec.ClusterSecrets.PrivateRegistrySecret, h.migrator.CreateOrUpdatePrivateRegistrySecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil { + return + } + spec.RancherKubernetesEngineConfig.PrivateRegistries = CleanRegistries(spec.RancherKubernetesEngineConfig.PrivateRegistries) + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // weave CNI password + clusterCopy, err = h.migrateSecret(clusterCopy, "WeavePasswordSecret", "weave CNI", &clusterCopy.Spec.ClusterSecrets.WeavePasswordSecret, h.migrator.CreateOrUpdateWeaveSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider == nil { + return + } + spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + // cloud provider secrets + // vsphere global + clusterCopy, err = h.migrateSecret(clusterCopy, "VsphereSecret", "vsphere global", &clusterCopy.Spec.ClusterSecrets.VsphereSecret, h.migrator.CreateOrUpdateVsphereGlobalSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider == nil { + return + } + spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + // vsphere virtual center + clusterCopy, err = h.migrateSecret(clusterCopy, "VirtualCenterSecret", "vsphere virtualcenter", &clusterCopy.Spec.ClusterSecrets.VirtualCenterSecret, h.migrator.CreateOrUpdateVsphereVirtualCenterSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider == nil { + return + } + for k, v := range clusterCopy.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + v.Password = "" + clusterCopy.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] = v + } + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + // openstack + clusterCopy, err = h.migrateSecret(clusterCopy, "OpenStackSecret", "openstack", &clusterCopy.Spec.ClusterSecrets.OpenStackSecret, h.migrator.CreateOrUpdateOpenStackSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider == nil { + return + } + spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + // aad client secret + clusterCopy, err = h.migrateSecret(clusterCopy, "AADClientSecret", "aad client", &clusterCopy.Spec.ClusterSecrets.AADClientSecret, h.migrator.CreateOrUpdateAADClientSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider == nil { + return + } + spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + // aad cert password + clusterCopy, err = h.migrateSecret(clusterCopy, "AADClientCertSecret", "aad cert", &clusterCopy.Spec.ClusterSecrets.AADClientCertSecret, h.migrator.CreateOrUpdateAADCertSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || spec.RancherKubernetesEngineConfig == nil || spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider == nil { + return + } + spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // cluster template questions and answers + logrus.Tracef("[secretmigrator] cleaning questions and answers from cluster %s", clusterCopy.Name) + cleanQuestions(clusterCopy) + + // cluster catalogs + clusterCatalogs, err := h.clusterCatalogLister.List(clusterCopy.Name, labels.NewSelector()) + if err != nil { + logrus.Errorf("[secretmigrator] failed to get cluster catalogs for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + for _, c := range clusterCatalogs { + if c.GetSecret() == "" && c.Spec.Password != "" { + logrus.Tracef("[secretmigrator] migrating secrets for cluster catalog %s in cluster %s", c.Name, clusterCopy.Name) + secret, err := h.migrator.CreateOrUpdateCatalogSecret(c.GetSecret(), c.Spec.Password, cluster) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for cluster catalog %s in cluster %s, will retry: %v", c.Name, clusterCopy.Name, err) + return cluster, err + } + if secret != nil { + logrus.Tracef("[secretmigrator] secret found for cluster catalog %s in cluster %s", c.Name, clusterCopy.Name) + c.Spec.CatalogSecrets.CredentialSecret = secret.Name + c.Spec.Password = "" + _, err = h.clusterCatalogs.Update(c) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for cluster catalog %s in cluster %s, will retry: %v", c.Name, clusterCopy.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + } + } + } + + projects, err := h.projectLister.List(clusterCopy.Name, labels.NewSelector()) + if err != nil { + logrus.Errorf("[secretmigrator] failed to get projects for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + + // project catalogs + for _, p := range projects { + projectCatalogs, err := h.projectCatalogLister.List(p.Name, labels.NewSelector()) + if err != nil { + logrus.Errorf("[secretmigrator] failed to get project catalogs for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + for _, c := range projectCatalogs { + if c.GetSecret() == "" && c.Spec.Password != "" { + logrus.Tracef("[secretmigrator] migrating secrets for project catalog %s in cluster %s", c.Name, clusterCopy.Name) + secret, err := h.migrator.CreateOrUpdateCatalogSecret(c.GetSecret(), c.Spec.Password, clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for project catalog %s in cluster %s, will retry: %v", c.Name, clusterCopy.Name, err) + return cluster, err + } + if secret != nil { + logrus.Tracef("[secretmigrator] secret found for project catalog %s in cluster %s", c.Name, clusterCopy.Name) + c.Spec.CatalogSecrets.CredentialSecret = secret.Name + c.Spec.Password = "" + _, err = h.projectCatalogs.Update(c) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets for project catalog %s in cluster %s, will retry: %v", c.Name, clusterCopy.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + } + } + } + } + return clusterCopy, err + }) + + logrus.Tracef("[secretmigrator] setting cluster condition [%s] and updating cluster [%s]", apimgmtv3.ClusterConditionSecretsMigrated, clusterCopy.Name) + // this is done for safety, but obj should never be nil as long as the object passed into Do() is not nil + clusterCopy, _ = obj.(*apimgmtv3.Cluster) + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + return cluster, err + } + cluster = clusterCopy.DeepCopy() + return cluster, doErr +} + +func (h *handler) migrateServiceAccountSecrets(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if apimgmtv3.ClusterConditionServiceAccountSecretsMigrated.IsTrue(cluster) { + return cluster, nil + } + clusterCopy := cluster.DeepCopy() + obj, doErr := apimgmtv3.ClusterConditionServiceAccountSecretsMigrated.DoUntilTrue(clusterCopy, func() (runtime.Object, error) { + // serviceAccountToken + if clusterCopy.Status.ServiceAccountTokenSecret == "" { + logrus.Tracef("[secretmigrator] migrating service account token secret for cluster %s", clusterCopy.Name) + saSecret, err := h.migrator.CreateOrUpdateServiceAccountTokenSecret(clusterCopy.Status.ServiceAccountTokenSecret, clusterCopy.Status.ServiceAccountToken, clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate service account token secret for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + if saSecret != nil { + logrus.Tracef("[secretmigrator] service account token secret found for cluster %s", clusterCopy.Name) + clusterCopy.Status.ServiceAccountTokenSecret = saSecret.Name + clusterCopy.Status.ServiceAccountToken = "" + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate service account token secret for cluster %s, will retry: %v", cluster.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, saSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + cluster = clusterCopy + } + } + return clusterCopy, nil + }) + logrus.Tracef("[secretmigrator] setting cluster condition [%s] and updating cluster [%s]", apimgmtv3.ClusterConditionServiceAccountSecretsMigrated, clusterCopy.Name) + // this is done for safety, but obj should never be nil as long as the object passed into DoUntilTrue() is not nil + clusterCopy, _ = obj.(*apimgmtv3.Cluster) + var err error + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + return cluster, err + } + cluster = clusterCopy.DeepCopy() + return cluster, doErr +} + +func (h *handler) migrateACISecrets(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if apimgmtv3.ClusterConditionACISecretsMigrated.IsTrue(cluster) { + return cluster, nil + } + clusterCopy := cluster.DeepCopy() + obj, doErr := apimgmtv3.ClusterConditionACISecretsMigrated.DoUntilTrue(clusterCopy, func() (runtime.Object, error) { + // aci apic user key + if clusterCopy.Spec.ClusterSecrets.ACIAPICUserKeySecret == "" { + logrus.Tracef("[secretmigrator] migrating aci apic user key secret for cluster %s", clusterCopy.Name) + aciUserKeySecret, err := h.migrator.CreateOrUpdateACIAPICUserKeySecret(clusterCopy.Spec.ClusterSecrets.ACIAPICUserKeySecret, clusterCopy.Spec.RancherKubernetesEngineConfig, clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci apic user key secret for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + if aciUserKeySecret != nil { + logrus.Tracef("[secretmigrator] aci apic user key secret found for cluster %s", clusterCopy.Name) + clusterCopy.Spec.ClusterSecrets.ACIAPICUserKeySecret = aciUserKeySecret.Name + clusterCopy.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey = "" + if clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey = "" + } + if clusterCopy.Status.FailedSpec != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey = "" + } + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci apic user key secret for cluster %s, will retry: %v", cluster.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciUserKeySecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + cluster = clusterCopy + } + } + + // aci token + if clusterCopy.Spec.ClusterSecrets.ACITokenSecret == "" { + logrus.Tracef("[secretmigrator] migrating aci token secret for cluster %s", clusterCopy.Name) + aciTokenSecret, err := h.migrator.CreateOrUpdateACITokenSecret(clusterCopy.Spec.ClusterSecrets.ACITokenSecret, clusterCopy.Spec.RancherKubernetesEngineConfig, clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci token secret for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + if aciTokenSecret != nil { + logrus.Tracef("[secretmigrator] aci token secret found for cluster %s", clusterCopy.Name) + clusterCopy.Spec.ClusterSecrets.ACITokenSecret = aciTokenSecret.Name + clusterCopy.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token = "" + if clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token = "" + } + if clusterCopy.Status.FailedSpec != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token = "" + } + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci token secret for cluster %s, will retry: %v", cluster.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciTokenSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + cluster = clusterCopy + } + } + + // aci kafka client key + if clusterCopy.Spec.ClusterSecrets.ACIKafkaClientKeySecret == "" { + logrus.Tracef("[secretmigrator] migrating aci kafkaClientKey secret for cluster %s", clusterCopy.Name) + aciKafkaClientKeySecret, err := h.migrator.CreateOrUpdateACIKafkaClientKeySecret(clusterCopy.Spec.ClusterSecrets.ACIKafkaClientKeySecret, clusterCopy.Spec.RancherKubernetesEngineConfig, clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci kafka client key secret for cluster %s, will retry: %v", clusterCopy.Name, err) + return cluster, err + } + if aciKafkaClientKeySecret != nil { + logrus.Tracef("[secretmigrator] aci kafka client key secret found for cluster %s", clusterCopy.Name) + clusterCopy.Spec.ClusterSecrets.ACIKafkaClientKeySecret = aciKafkaClientKeySecret.Name + clusterCopy.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey = "" + if clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.AppliedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey = "" + } + if clusterCopy.Status.FailedSpec != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig != nil && clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider != nil { + clusterCopy.Status.FailedSpec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey = "" + } + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci kafka client key secret for cluster %s, will retry: %v", cluster.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciKafkaClientKeySecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return cluster, err + } + cluster = clusterCopy + } + } + return clusterCopy, nil + }) + logrus.Tracef("[secretmigrator] setting cluster condition [%s] and updating cluster [%s]", apimgmtv3.ClusterConditionACISecretsMigrated, clusterCopy.Name) + // this is done for safety, but obj should never be nil as long as the object passed into Do() is not nil + clusterCopy, _ = obj.(*apimgmtv3.Cluster) + var err error + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + return cluster, err + } + cluster = clusterCopy.DeepCopy() + return cluster, doErr +} + +func (h *handler) migrateRKESecrets(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if apimgmtv3.ClusterConditionRKESecretsMigrated.IsTrue(cluster) { + return cluster, nil + } + clusterCopy := cluster.DeepCopy() + var err error + obj, doErr := apimgmtv3.ClusterConditionRKESecretsMigrated.DoUntilTrue(clusterCopy, func() (runtime.Object, error) { + // rke secrets encryption + clusterCopy, err = h.migrateSecret(clusterCopy, "SecretsEncryptionProvidersSecret", "secrets encryption providers", &clusterCopy.Spec.ClusterSecrets.SecretsEncryptionProvidersSecret, h.migrator.CreateOrUpdateSecretsEncryptionProvidersSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig == nil || + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig == nil { + return + } + spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources = nil + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // rke bastion host + clusterCopy, err = h.migrateSecret(clusterCopy, "BastionHostSSHKeySecret", "bastion host ssh key", &clusterCopy.Spec.ClusterSecrets.BastionHostSSHKeySecret, h.migrator.CreateOrUpdateBastionHostSSHKeySecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || + spec.RancherKubernetesEngineConfig == nil { + return + } + spec.RancherKubernetesEngineConfig.BastionHost.SSHKey = "" + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // rke kubelet extra env + clusterCopy, err = h.migrateSecret(clusterCopy, "KubeletExtraEnvSecret", "kubelet extra env", &clusterCopy.Spec.ClusterSecrets.KubeletExtraEnvSecret, h.migrator.CreateOrUpdateKubeletExtraEnvSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || + spec.RancherKubernetesEngineConfig == nil { + return + } + env := make([]string, 0, len(spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv)) + for _, e := range spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv { + if !strings.Contains(e, "AWS_SECRET_ACCESS_KEY") { + env = append(env, e) + } + } + spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv = env + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + // rke private registry ecr + clusterCopy, err = h.migrateSecret(clusterCopy, "PrivateRegistryECRSecret", "private registry ecr", &clusterCopy.Spec.ClusterSecrets.PrivateRegistryECRSecret, h.migrator.CreateOrUpdatePrivateRegistryECRSecret, func(spec *apimgmtv3.ClusterSpec) { + if spec == nil || + spec.RancherKubernetesEngineConfig == nil { + return + } + for _, reg := range spec.RancherKubernetesEngineConfig.PrivateRegistries { + if ecr := reg.ECRCredentialPlugin; ecr != nil { + ecr.AwsSecretAccessKey = "" + ecr.AwsSessionToken = "" + } + } + }) + if err != nil { + return cluster, err + } + cluster = clusterCopy + + return clusterCopy, nil + }) + logrus.Tracef("[secretmigrator] setting cluster condition [%s] and updating cluster [%s]", apimgmtv3.ClusterConditionRKESecretsMigrated, clusterCopy.Name) + // this is done for safety, but obj should never be nil as long as the object passed into Do() is not nil + clusterCopy, _ = obj.(*apimgmtv3.Cluster) + clusterCopy, err = h.clusters.Update(clusterCopy) + if err != nil { + return cluster, err + } + cluster = clusterCopy.DeepCopy() + return cluster, doErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters_test.go new file mode 100644 index 0000000..2aa91ce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clusters_test.go @@ -0,0 +1,671 @@ +package secretmigrator + +import ( + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "reflect" + "strconv" + "testing" + "time" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + corefakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + v3fakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + apiserverv1 "k8s.io/apiserver/pkg/apis/apiserver/v1" + "k8s.io/kubernetes/pkg/credentialprovider" +) + +var ( + mockSecrets = make(map[string]*corev1.Secret) + mockClusters = make(map[string]*apimgmtv3.Cluster) +) + +const ( + secretsNS = "cattle-global-data" +) + +func resetMockSecrets() { + mockSecrets = make(map[string]*corev1.Secret) +} + +func resetMockClusters() { + mockClusters = make(map[string]*apimgmtv3.Cluster) +} + +func newTestHandler(t *testing.T) *handler { + secrets := corefakes.SecretInterfaceMock{ + CreateFunc: func(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.GenerateName != "" { + uniqueIdentifier := md5.Sum([]byte(time.Now().String())) + secret.Name = secret.GenerateName + hex.EncodeToString(uniqueIdentifier[:])[:5] + secret.GenerateName = "" + } + // All key-value pairs in the stringData field are internally merged into the data field. + // If a key appears in both the data and the stringData field, the value specified in the stringData field takes + // precedence. + // https://kubernetes.io/docs/concepts/configuration/secret/#restriction-names-data + // All keys and values are merged into the data field on write, overwriting any existing values. + // The stringData field is never output when reading from the API. + // https://pkg.go.dev/k8s.io/api/core/v1@v0.24.2#Secret.StringData + if secret.StringData != nil && len(secret.StringData) != 0 { + if secret.Data == nil { + secret.Data = map[string][]byte{} + } + for k, v := range secret.StringData { + secret.Data[k] = []byte(v) + } + } + secret.ResourceVersion = "0" + secret.StringData = map[string]string{} + key := fmt.Sprintf("%s:%s", secret.Namespace, secret.Name) + mockSecrets[key] = secret.DeepCopy() + return mockSecrets[key], nil + }, + UpdateFunc: func(secret *corev1.Secret) (*corev1.Secret, error) { + key := fmt.Sprintf("%s:%s", secret.Namespace, secret.Name) + if _, ok := mockSecrets[key]; !ok { + return nil, apierror.NewNotFound(schema.GroupResource{}, fmt.Sprintf("secret [%s] not found", key)) + } + + if secret.StringData != nil && len(secret.StringData) != 0 { + for k, v := range secret.StringData { + secret.Data[k] = []byte(v) + } + } + secret.StringData = map[string]string{} + rv, _ := strconv.Atoi(mockSecrets[key].ObjectMeta.ResourceVersion) + rv++ + if reflect.DeepEqual(secret, mockSecrets[key]) { + assert.Fail(t, "update called with no changes") + } + secret.ResourceVersion = strconv.Itoa(rv) + mockSecrets[key] = secret + return mockSecrets[key].DeepCopy(), nil + }, + DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { + key := fmt.Sprintf("%s:%s", namespace, name) + if _, ok := mockSecrets[key]; !ok { + return apierror.NewNotFound(schema.GroupResource{}, fmt.Sprintf("secret [%s] not found", key)) + } + mockSecrets[fmt.Sprintf("%s:%s", namespace, name)] = nil + return nil + }, + } + + secretLister := corefakes.SecretListerMock{ + GetFunc: func(namespace string, name string) (*corev1.Secret, error) { + id := fmt.Sprintf("%s:%s", namespace, name) + secret, ok := mockSecrets[fmt.Sprintf("%s:%s", namespace, name)] + if !ok { + return nil, apierror.NewNotFound(schema.GroupResource{}, id) + } + return secret.DeepCopy(), nil + }, + } + + clusterCatalogLister := &v3fakes.ClusterCatalogListerMock{ + ListFunc: func(namespace string, selector labels.Selector) ([]*apimgmtv3.ClusterCatalog, error) { + var list []*apimgmtv3.ClusterCatalog + return list, nil + }, + } + + projectLister := &v3fakes.ProjectListerMock{ + ListFunc: func(namespace string, selector labels.Selector) ([]*apimgmtv3.Project, error) { + var list []*apimgmtv3.Project + return list, nil + }, + } + return &handler{ + clusters: &v3fakes.ClusterInterfaceMock{ + CreateFunc: func(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + mockClusters[cluster.Name] = cluster.DeepCopy() + mockClusters[cluster.Name].ObjectMeta.ResourceVersion = "0" + return mockClusters[cluster.Name], nil + }, + UpdateFunc: func(cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if _, ok := mockClusters[cluster.Name]; !ok { + return nil, apierror.NewNotFound(schema.GroupResource{}, fmt.Sprintf("cluster [%s]", cluster.Name)) + } + if reflect.DeepEqual(mockClusters[cluster.Name], cluster) { + assert.Fail(t, "update called with no changes") + } + mockClusters[cluster.Name] = cluster.DeepCopy() + rv, _ := strconv.Atoi(mockClusters[cluster.Name].ObjectMeta.ResourceVersion) + rv++ + mockClusters[cluster.Name].ObjectMeta.ResourceVersion = strconv.Itoa(rv) + return mockClusters[cluster.Name].DeepCopy(), nil + }, + GetFunc: func(name string, opts metav1.GetOptions) (*apimgmtv3.Cluster, error) { + cluster, ok := mockClusters[name] + if !ok { + gvk := cluster.GroupVersionKind() + return nil, apierror.NewNotFound(schema.GroupResource{Group: gvk.Group, Resource: gvk.Kind}, name) + } + return cluster.DeepCopy(), nil + }, + }, + migrator: NewMigrator(&secretLister, &secrets), + clusterCatalogLister: clusterCatalogLister, + projectLister: projectLister, + } +} + +func TestMigrateClusterSecrets(t *testing.T) { + h := newTestHandler(t) + defer resetMockClusters() + defer resetMockSecrets() + secretKey := "abcdefg123" + testCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + }, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{ + { + URL: "testurl", + Password: secretKey, + }, + }, + Services: rketypes.RKEConfigServices{ + Etcd: rketypes.ETCDService{ + BackupConfig: &rketypes.BackupConfig{ + S3BackupConfig: &rketypes.S3BackupConfig{ + SecretKey: secretKey, + }, + }, + }, + }, + Network: rketypes.NetworkConfig{ + WeaveNetworkProvider: &rketypes.WeaveNetworkProvider{ + Password: secretKey, + }, + }, + CloudProvider: rketypes.CloudProvider{ + VsphereCloudProvider: &rketypes.VsphereCloudProvider{ + Global: rketypes.GlobalVsphereOpts{ + Password: secretKey, + }, + VirtualCenter: map[string]rketypes.VirtualCenterConfig{ + "vc1": { + Password: secretKey, + }, + }, + }, + OpenstackCloudProvider: &rketypes.OpenstackCloudProvider{ + Global: rketypes.GlobalOpenstackOpts{ + Password: secretKey, + }, + }, + AzureCloudProvider: &rketypes.AzureCloudProvider{ + AADClientSecret: secretKey, + AADClientCertPassword: secretKey, + }, + }, + }, + }, + }, + } + testCluster, err := h.clusters.Create(testCluster) + assert.Nil(t, err) + cluster, err := h.migrateClusterSecrets(testCluster) + assert.Nil(t, err) + + registry := credentialprovider.DockerConfigJSON{ + Auths: credentialprovider.DockerConfig{ + "testurl": credentialprovider.DockerConfigEntry{ + Password: secretKey, + }, + }, + } + + registryJSON, err := json.Marshal(registry) + assert.Nil(t, err) + + tests := []struct { + name string + field string + secretName string + key string + expected string + }{ + { + name: "privateRegistry", + field: cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries[0].Password, + secretName: cluster.Spec.ClusterSecrets.PrivateRegistrySecret, + key: corev1.DockerConfigJsonKey, + expected: string(registryJSON), + }, + { + name: "s3Secret", + field: cluster.Spec.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey, + secretName: cluster.Spec.ClusterSecrets.S3CredentialSecret, + key: SecretKey, + expected: secretKey, + }, + { + name: "WeavePassword", + field: cluster.Spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password, + secretName: cluster.Spec.ClusterSecrets.WeavePasswordSecret, + key: SecretKey, + expected: secretKey, + }, + { + name: "VspherePassword", + field: cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password, + secretName: cluster.Spec.ClusterSecrets.VsphereSecret, + key: SecretKey, + expected: secretKey, + }, + { + name: "VirtualCenterPassword", + field: cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter["vc1"].Password, + secretName: cluster.Spec.ClusterSecrets.VirtualCenterSecret, + key: "vc1", + expected: secretKey, + }, + { + name: "OpenStackPassword", + field: cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password, + secretName: cluster.Spec.ClusterSecrets.OpenStackSecret, + key: SecretKey, + expected: secretKey, + }, + { + name: "AADClientSecret", + field: cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret, + secretName: cluster.Spec.ClusterSecrets.AADClientSecret, + key: SecretKey, + expected: secretKey, + }, + { + name: "AADClientCertSecret", + field: cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword, + secretName: cluster.Spec.ClusterSecrets.AADClientCertSecret, + key: SecretKey, + expected: secretKey, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, "", tt.field) + assert.NotEqual(t, "", tt.secretName) + secret, err := h.migrator.secretLister.Get(secretsNS, tt.secretName) + assert.Nil(t, err) + assert.Equal(t, tt.expected, string(secret.Data[tt.key])) + }) + } + + assert.True(t, apimgmtv3.ClusterConditionSecretsMigrated.IsTrue(cluster)) + + // test that cluster does not get updated if migrated again + clusterCopy := cluster.DeepCopy() + clusterCopy, err = h.migrateClusterSecrets(clusterCopy) + assert.Nil(t, err) + assert.Equal(t, cluster, clusterCopy) + + testCluster2 := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster2", + }, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Etcd: rketypes.ETCDService{ + BackupConfig: &rketypes.BackupConfig{ + S3BackupConfig: &rketypes.S3BackupConfig{ + SecretKey: secretKey, + }, + }, + }, + }, + }, + }, + }, + } + cluster, err = h.migrateClusterSecrets(testCluster2) + assert.Equal(t, err.Error(), fmt.Sprintf(" \"cluster [%s]\" not found", testCluster2.Name)) + // no change should + assert.Equal(t, cluster.Spec.RancherKubernetesEngineConfig, testCluster2.Spec.RancherKubernetesEngineConfig) + assert.Equal(t, cluster, testCluster2) + assert.True(t, apimgmtv3.ClusterConditionSecretsMigrated.IsFalse(cluster)) +} + +func TestMigrateClusterServiceAccountToken(t *testing.T) { + h := newTestHandler(t) + defer resetMockClusters() + defer resetMockSecrets() + token := "somefaketoken" + + testCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + }, + Status: apimgmtv3.ClusterStatus{ + ServiceAccountToken: token, + }, + } + _, err := h.clusters.Create(testCluster) + assert.Nil(t, err) + cluster, err := h.migrateServiceAccountSecrets(testCluster) + assert.Nil(t, err) + assert.Equal(t, cluster.Status.ServiceAccountToken, "") + + secretName := cluster.Status.ServiceAccountTokenSecret + assert.NotEqual(t, secretName, "") + secret, err := h.migrator.secretLister.Get(secretsNS, secretName) + assert.Nil(t, err) + assert.Equal(t, secret.Data[SecretKey], []byte(token)) + assert.True(t, apimgmtv3.ClusterConditionServiceAccountSecretsMigrated.IsTrue(cluster)) + + // test that cluster object does not get updated if migrated again + clusterCopy := cluster.DeepCopy() + clusterCopy, err = h.migrateServiceAccountSecrets(clusterCopy) + assert.Nil(t, err) + assert.Equal(t, cluster, clusterCopy) // purposefully test pointer equality +} + +func TestMigrateRKESecrets(t *testing.T) { + h := newTestHandler(t) + defer resetMockClusters() + defer resetMockSecrets() + + testCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + }, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + BastionHost: rketypes.BastionHost{ + SSHKey: "sshKey", + }, + PrivateRegistries: []rketypes.PrivateRegistry{ + { + URL: "testurl", + ECRCredentialPlugin: &rketypes.ECRCredentialPlugin{ + AwsAccessKeyID: "keyId", + AwsSecretAccessKey: "secret", + AwsSessionToken: "token", + }, + }, + }, + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + BaseService: rketypes.BaseService{ + ExtraEnv: []string{ + "AWS_ACCESS_KEY_ID=keyId", + "AWS_SECRET_ACCESS_KEY=secret", + }, + }, + }, + KubeAPI: rketypes.KubeAPIService{ + SecretsEncryptionConfig: &rketypes.SecretsEncryptionConfig{ + CustomConfig: &apiserverv1.EncryptionConfiguration{ + Resources: []apiserverv1.ResourceConfiguration{ + { + Providers: []apiserverv1.ProviderConfiguration{ + { + AESGCM: &apiserverv1.AESConfiguration{ + Keys: []apiserverv1.Key{ + { + Name: "testName", + Secret: "testSecret", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + _, err := h.clusters.Create(testCluster) + assert.Nil(t, err) + cluster, err := h.migrateRKESecrets(testCluster) + assert.Nil(t, err) + + // test that cluster object does not get updated if migrated again + clusterCopy := cluster.DeepCopy() + clusterCopy, err = h.migrateRKESecrets(clusterCopy) + assert.Nil(t, err) + assert.Equal(t, cluster, clusterCopy) + + type verifyFunc func(t *testing.T, cluster *apimgmtv3.Cluster) + + emptyStringCondition := func(fields ...string) verifyFunc { + return func(t *testing.T, cluster *apimgmtv3.Cluster) { + for _, field := range fields { + assert.Equal(t, "", field) + } + } + } + + tests := []struct { + name string + cleanupVerifyFunc verifyFunc + secretName string + key string + expected string + assembler assemblers.Assembler + assembleVerifyFunc verifyFunc + }{ + { + name: "rkeSecretsEncryptionCustomConfig", + cleanupVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Nil(t, cluster.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources) + }, + secretName: cluster.Spec.ClusterSecrets.SecretsEncryptionProvidersSecret, + key: SecretKey, + expected: `[{"resources":null,"providers":[{"aesgcm":{"keys":[{"name":"testName","secret":"testSecret"}]}}]}]`, + assembler: assemblers.AssembleSecretsEncryptionProvidersSecretCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig, cluster.Spec.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig) + }, + }, + { + name: "bastionHostSSHKey", + cleanupVerifyFunc: emptyStringCondition(cluster.Spec.RancherKubernetesEngineConfig.BastionHost.SSHKey), + secretName: cluster.Spec.ClusterSecrets.BastionHostSSHKeySecret, + key: SecretKey, + expected: "sshKey", + assembler: assemblers.AssembleBastionHostSSHKeyCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.BastionHost.SSHKey, cluster.Spec.RancherKubernetesEngineConfig.BastionHost.SSHKey) + }, + }, + { + name: "kubeletExtraEnv", + cleanupVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Len(t, cluster.Spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv, 1) + assert.Equal(t, "AWS_ACCESS_KEY_ID=keyId", cluster.Spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv[0]) + }, + secretName: cluster.Spec.ClusterSecrets.KubeletExtraEnvSecret, + key: SecretKey, + expected: "secret", + assembler: assemblers.AssembleKubeletExtraEnvCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv, cluster.Spec.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv) + }, + }, + { + name: "privateRegistryECR", + cleanupVerifyFunc: emptyStringCondition( + cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries[0].ECRCredentialPlugin.AwsSecretAccessKey, + cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries[0].ECRCredentialPlugin.AwsSessionToken, + ), + secretName: cluster.Spec.ClusterSecrets.PrivateRegistryECRSecret, + key: SecretKey, + expected: `{"testurl":"{\"awsSecretAccessKey\":\"secret\",\"awsAccessToken\":\"token\"}"}`, + assembler: assemblers.AssemblePrivateRegistryECRCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries, cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.cleanupVerifyFunc(t, cluster) + assert.NotEqual(t, "", tt.secretName) + secret, err := h.migrator.secretLister.Get(secretsNS, tt.secretName) + assert.Nil(t, err) + assert.Equal(t, tt.expected, string(secret.Data[tt.key])) + cluster.Spec, err = tt.assembler(tt.secretName, "", "", cluster.Spec, h.migrator.secretLister) + assert.Nil(t, err) + tt.assembleVerifyFunc(t, cluster) + }) + } + + assert.True(t, apimgmtv3.ClusterConditionRKESecretsMigrated.IsTrue(cluster)) +} + +func TestMigrateACISecrets(t *testing.T) { + h := newTestHandler(t) + defer resetMockClusters() + defer resetMockSecrets() + + testCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + }, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Network: rketypes.NetworkConfig{ + Plugin: "aci", + AciNetworkProvider: &rketypes.AciNetworkProvider{ + Token: "secret", + ApicUserKey: "secret", + KafkaClientKey: "secret", + }, + }, + }, + }, + }, + } + _, err := h.clusters.Create(testCluster) + assert.Nil(t, err) + cluster, err := h.migrateACISecrets(testCluster) + assert.Nil(t, err) + + // test that cluster object does not get updated if migrated again + clusterCopy := cluster.DeepCopy() + clusterCopy, err = h.migrateACISecrets(clusterCopy) + assert.Nil(t, err) + assert.Equal(t, cluster, clusterCopy) + + type verifyFunc func(t *testing.T, cluster *apimgmtv3.Cluster) + + emptyStringCondition := func(fields ...string) verifyFunc { + return func(t *testing.T, cluster *apimgmtv3.Cluster) { + for _, field := range fields { + assert.Equal(t, "", field) + } + } + } + + tests := []struct { + name string + cleanupVerifyFunc verifyFunc + secretName string + key string + expected string + assembler assemblers.Assembler + assembleVerifyFunc verifyFunc + }{ + { + name: "token", + cleanupVerifyFunc: emptyStringCondition(cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token), + secretName: cluster.Spec.ClusterSecrets.ACITokenSecret, + key: SecretKey, + expected: "secret", + assembler: assemblers.AssembleACITokenCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token, cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token) + }, + }, + { + name: "user key", + cleanupVerifyFunc: emptyStringCondition(cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey), + secretName: cluster.Spec.ClusterSecrets.ACIAPICUserKeySecret, + key: SecretKey, + expected: "secret", + assembler: assemblers.AssembleACIAPICUserKeyCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey, cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey) + }, + }, + { + name: "kafka key", + cleanupVerifyFunc: emptyStringCondition(cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey), + secretName: cluster.Spec.ClusterSecrets.ACIKafkaClientKeySecret, + key: SecretKey, + expected: "secret", + assembler: assemblers.AssembleACIKafkaClientKeyCredential, + assembleVerifyFunc: func(t *testing.T, cluster *apimgmtv3.Cluster) { + assert.Equal(t, testCluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey, cluster.Spec.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.cleanupVerifyFunc(t, cluster) + assert.NotEqual(t, "", tt.secretName) + secret, err := h.migrator.secretLister.Get(secretsNS, tt.secretName) + assert.Nil(t, err) + assert.Equal(t, tt.expected, string(secret.Data[tt.key])) + cluster.Spec, err = tt.assembler(tt.secretName, "", "", cluster.Spec, h.migrator.secretLister) + assert.Nil(t, err) + tt.assembleVerifyFunc(t, cluster) + }) + } + + assert.True(t, apimgmtv3.ClusterConditionACISecretsMigrated.IsTrue(cluster)) +} + +func TestSync(t *testing.T) { + h := newTestHandler(t) + defer resetMockClusters() + defer resetMockSecrets() + testCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testcluster", + }, + } + testCluster, err := h.clusters.Create(testCluster) + assert.Nil(t, err) + got, err := h.sync("", testCluster) + assert.Nil(t, err) + assert.True(t, apimgmtv3.ClusterConditionSecretsMigrated.IsTrue(got)) + assert.True(t, apimgmtv3.ClusterConditionServiceAccountSecretsMigrated.IsTrue(got)) + assert.True(t, apimgmtv3.ClusterConditionRKESecretsMigrated.IsTrue(got)) + assert.True(t, apimgmtv3.ClusterConditionACISecretsMigrated.IsTrue(got)) + + testClusterCopy := got.(*apimgmtv3.Cluster).DeepCopy() + got, err = h.sync("", testClusterCopy) + + assert.Nil(t, err) + assert.Equal(t, got, testClusterCopy) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clustertemplaterevisions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clustertemplaterevisions.go new file mode 100644 index 0000000..010a3ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/clustertemplaterevisions.go @@ -0,0 +1,491 @@ +package secretmigrator + +import ( + "strings" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func (h *handler) syncTemplate(_ string, clusterTemplateRevision *apimgmtv3.ClusterTemplateRevision) (runtime.Object, error) { + if clusterTemplateRevision == nil || clusterTemplateRevision.DeletionTimestamp != nil { + return clusterTemplateRevision, nil + } + clusterTemplateRevisionCopy := clusterTemplateRevision.DeepCopy() + obj, doErr := apimgmtv3.ClusterTemplateRevisionConditionSecretsMigrated.DoUntilTrue(clusterTemplateRevisionCopy, func() (runtime.Object, error) { + // privateRegistries + if clusterTemplateRevisionCopy.Status.PrivateRegistrySecret == "" { + logrus.Tracef("[secretmigrator] migrating private registry secrets for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + regSecret, err := h.migrator.CreateOrUpdatePrivateRegistrySecret(clusterTemplateRevisionCopy.Status.PrivateRegistrySecret, clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate private registry secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if regSecret != nil { + logrus.Tracef("[secretmigrator] private registry secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.PrivateRegistrySecret = regSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.PrivateRegistries = CleanRegistries(clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.PrivateRegistries) + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate private registry secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, regSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // s3 backup cred + if clusterTemplateRevisionCopy.Status.S3CredentialSecret == "" { + logrus.Tracef("[secretmigrator] migrating S3 secrets for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + s3Secret, err := h.migrator.CreateOrUpdateS3Secret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate S3 secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if s3Secret != nil { + logrus.Tracef("[secretmigrator] S3 secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.S3CredentialSecret = s3Secret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig.SecretKey = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate S3 secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, s3Secret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // weave CNI password + if clusterTemplateRevisionCopy.Status.WeavePasswordSecret == "" { + logrus.Tracef("[secretmigrator] migrating weave CNI secrets for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + weaveSecret, err := h.migrator.CreateOrUpdateWeaveSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate weave CNI secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if weaveSecret != nil { + logrus.Tracef("[secretmigrator] weave secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.WeavePasswordSecret = weaveSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate weave CNI secrets for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, weaveSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // cloud provider secrets + + // vsphere global + if clusterTemplateRevisionCopy.Status.VsphereSecret == "" { + logrus.Tracef("[secretmigrator] migrating vsphere global secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + vsphereSecret, err := h.migrator.CreateOrUpdateVsphereGlobalSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate vsphere global secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if vsphereSecret != nil { + logrus.Tracef("[secretmigrator] vsphere global secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.VsphereSecret = vsphereSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate vsphere global secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, vsphereSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + // vsphere virtual center + if clusterTemplateRevisionCopy.Status.VirtualCenterSecret == "" { + logrus.Tracef("[secretmigrator] migrating vsphere virtualcenter secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + vcenterSecret, err := h.migrator.CreateOrUpdateVsphereVirtualCenterSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate vsphere virtualcenter secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if vcenterSecret != nil { + logrus.Tracef("[secretmigrator] vsphere virtualcenter secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.VirtualCenterSecret = vcenterSecret.Name + for k, v := range clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter { + v.Password = "" + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter[k] = v + } + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate vsphere virtualcenter secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, vcenterSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + // openstack + if clusterTemplateRevisionCopy.Status.OpenStackSecret == "" { + logrus.Tracef("[secretmigrator] migrating openstack secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + openStackSecret, err := h.migrator.CreateOrUpdateOpenStackSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, nil) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate openstack secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if openStackSecret != nil { + logrus.Tracef("[secretmigrator] openstack secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.OpenStackSecret = openStackSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate openstack secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, openStackSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + // aad client secret + if clusterTemplateRevisionCopy.Status.AADClientSecret == "" { + logrus.Tracef("[secretmigrator] migrating aad client secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + aadClientSecret, err := h.migrator.CreateOrUpdateAADClientSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, nil) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aad client secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if aadClientSecret != nil { + logrus.Tracef("[secretmigrator] aad client secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.AADClientSecret = aadClientSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aad client secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aadClientSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + // aad cert password + if clusterTemplateRevisionCopy.Status.AADClientCertSecret == "" { + logrus.Tracef("[secretmigrator] migrating aad cert secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + aadCertSecret, err := h.migrator.CreateOrUpdateAADCertSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, nil) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aad cert secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if aadCertSecret != nil { + logrus.Tracef("[secretmigrator] aad cert secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.AADClientCertSecret = aadCertSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aad cert secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aadCertSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // cluster template questions and answers + // The cluster store will look up defaults in the ClusterConfig after assembling it. + logrus.Tracef("[secretmigrator] cleaning questions and answers from clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + for i, q := range clusterTemplateRevisionCopy.Spec.Questions { + if MatchesQuestionPath(q.Variable) { + clusterTemplateRevisionCopy.Spec.Questions[i].Default = "" + } + } + + var err error + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + return clusterTemplateRevisionCopy, nil + }) + clusterTemplateRevisionCopy, _ = obj.(*apimgmtv3.ClusterTemplateRevision) + var err error + logrus.Tracef("[secretmigrator] setting clusterTemplateRevision [%s] condition and updating clusterTemplateRevision [%s]", apimgmtv3.ClusterTemplateRevisionConditionSecretsMigrated, clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy.DeepCopy() + if doErr != nil { + return clusterTemplateRevision, doErr + } + + obj, doErr = apimgmtv3.ClusterTemplateRevisionConditionACISecretsMigrated.DoUntilTrue(clusterTemplateRevisionCopy, func() (runtime.Object, error) { + // aci apic user key + if clusterTemplateRevisionCopy.Status.ACIAPICUserKeySecret == "" { + logrus.Tracef("[secretmigrator] migrating aci apic user key secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + aciAPICUserKeySecret, err := h.migrator.CreateOrUpdateACIAPICUserKeySecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci apic user key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if aciAPICUserKeySecret != nil { + logrus.Tracef("[secretmigrator] aci apic user key secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.ACIAPICUserKeySecret = aciAPICUserKeySecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Network.AciNetworkProvider.ApicUserKey = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci apic user key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciAPICUserKeySecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // aci token + if clusterTemplateRevisionCopy.Status.ACITokenSecret == "" { + logrus.Tracef("[secretmigrator] migrating aci token secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + aciTokenSecret, err := h.migrator.CreateOrUpdateACITokenSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci token secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if aciTokenSecret != nil { + logrus.Tracef("[secretmigrator] aci token secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.ACITokenSecret = aciTokenSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Network.AciNetworkProvider.Token = "" + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci token secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciTokenSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // aci kafka client key + if clusterTemplateRevisionCopy.Status.ACIKafkaClientKeySecret == "" { + logrus.Tracef("[secretmigrator] migrating aci kafka client key secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + aciKafkaClientKeySecret, err := h.migrator.CreateOrUpdateACIKafkaClientKeySecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci kafka client key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if aciKafkaClientKeySecret != nil { + logrus.Tracef("[secretmigrator] aci kafka client key secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.ACIKafkaClientKeySecret = aciKafkaClientKeySecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Network.AciNetworkProvider.KafkaClientKey = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate aci kafka client key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, aciKafkaClientKeySecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // cluster template questions and answers + // The cluster store will look up defaults in the ClusterConfig after assembling it. + logrus.Tracef("[secretmigrator] cleaning questions and answers from clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + for i, q := range clusterTemplateRevisionCopy.Spec.Questions { + if MatchesQuestionPath(q.Variable) { + clusterTemplateRevisionCopy.Spec.Questions[i].Default = "" + } + } + + var err error + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + return clusterTemplateRevisionCopy, nil + }) + + clusterTemplateRevisionCopy, _ = obj.(*apimgmtv3.ClusterTemplateRevision) + logrus.Tracef("[secretmigrator] setting clusterTemplateRevision [%s] condition and updating clusterTemplateRevision [%s]", apimgmtv3.ClusterTemplateRevisionConditionACISecretsMigrated, clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy.DeepCopy() + if doErr != nil { + return clusterTemplateRevision, doErr + } + + obj, doErr = apimgmtv3.ClusterTemplateRevisionConditionRKESecretsMigrated.DoUntilTrue(clusterTemplateRevisionCopy, func() (runtime.Object, error) { + // rke secrets encryption providers + if clusterTemplateRevisionCopy.Status.SecretsEncryptionProvidersSecret == "" { + logrus.Tracef("[secretmigrator] migrating secrets encryption provider secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + secretsEncryptionProvidersSecret, err := h.migrator.CreateOrUpdateSecretsEncryptionProvidersSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets encryption provider secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if secretsEncryptionProvidersSecret != nil { + logrus.Tracef("[secretmigrator] secrets encryption provider secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.SecretsEncryptionProvidersSecret = secretsEncryptionProvidersSecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Services.KubeAPI.SecretsEncryptionConfig.CustomConfig.Resources = nil + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate secrets encryption provider secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, secretsEncryptionProvidersSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // rke bastion host + if clusterTemplateRevisionCopy.Status.BastionHostSSHKeySecret == "" { + logrus.Tracef("[secretmigrator] migrating rke bastion host ssh key secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + bastionHostSSHKeySecret, err := h.migrator.CreateOrUpdateBastionHostSSHKeySecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke bastion host ssh key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if bastionHostSSHKeySecret != nil { + logrus.Tracef("[secretmigrator] rke bastion host ssh key secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.BastionHostSSHKeySecret = bastionHostSSHKeySecret.Name + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.BastionHost.SSHKey = "" + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke bastion host ssh key secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, bastionHostSSHKeySecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // rke kubelet extra env + if clusterTemplateRevisionCopy.Status.KubeletExtraEnvSecret == "" { + logrus.Tracef("[secretmigrator] migrating rke kubelet extra env secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + kubeletExtraEnvSecret, err := h.migrator.CreateOrUpdateKubeletExtraEnvSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke kubelet extra env secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if kubeletExtraEnvSecret != nil { + logrus.Tracef("[secretmigrator] rke kubelet extra env secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.KubeletExtraEnvSecret = kubeletExtraEnvSecret.Name + env := make([]string, 0, len(clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv)) + for _, e := range clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv { + if !strings.Contains(e, "AWS_SECRET_ACCESS_KEY") { + env = append(env, e) + } + } + clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.Services.Kubelet.ExtraEnv = env + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke kubelet extra env secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, kubeletExtraEnvSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // rke private registry ecr + if clusterTemplateRevisionCopy.Status.PrivateRegistryECRSecret == "" { + logrus.Tracef("[secretmigrator] migrating rke private registry ecr secret for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + privateRegistryEcrSecret, err := h.migrator.CreateOrUpdatePrivateRegistryECRSecret("", clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig, clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke private registry ecr secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevisionCopy.Name, err) + return clusterTemplateRevision, err + } + if privateRegistryEcrSecret != nil { + logrus.Tracef("[secretmigrator] rke private registry ecr secret found for clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy.Status.PrivateRegistryECRSecret = privateRegistryEcrSecret.Name + for _, reg := range clusterTemplateRevisionCopy.Spec.ClusterConfig.RancherKubernetesEngineConfig.PrivateRegistries { + if ecr := reg.ECRCredentialPlugin; ecr != nil { + ecr.AwsSecretAccessKey = "" + ecr.AwsSessionToken = "" + } + } + clusterTemplateRevisionCopy, err := h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + logrus.Errorf("[secretmigrator] failed to migrate rke private registry ecr secret for clusterTemplateRevision %s, will retry: %v", clusterTemplateRevision.Name, err) + deleteErr := h.migrator.secrets.DeleteNamespaced(SecretNamespace, privateRegistryEcrSecret.Name, &metav1.DeleteOptions{}) + if deleteErr != nil { + logrus.Errorf("[secretmigrator] encountered error while handling migration error: %v", deleteErr) + } + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + } + } + + // cluster template questions and answers + // The cluster store will look up defaults in the ClusterConfig after assembling it. + logrus.Tracef("[secretmigrator] cleaning questions and answers from clusterTemplateRevision %s", clusterTemplateRevisionCopy.Name) + for i, q := range clusterTemplateRevisionCopy.Spec.Questions { + if MatchesQuestionPath(q.Variable) { + clusterTemplateRevisionCopy.Spec.Questions[i].Default = "" + } + } + + var err error + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy + return clusterTemplateRevisionCopy, nil + }) + + clusterTemplateRevisionCopy, _ = obj.(*apimgmtv3.ClusterTemplateRevision) + logrus.Tracef("[secretmigrator] setting clusterTemplateRevision [%s] condition and updating clusterTemplateRevision [%s]", apimgmtv3.ClusterTemplateRevisionConditionRKESecretsMigrated, clusterTemplateRevisionCopy.Name) + clusterTemplateRevisionCopy, err = h.clusterTemplateRevisions.Update(clusterTemplateRevisionCopy) + if err != nil { + return clusterTemplateRevision, err + } + clusterTemplateRevision = clusterTemplateRevisionCopy.DeepCopy() + return clusterTemplateRevision, doErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/harvester.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/harvester.go new file mode 100644 index 0000000..97a775e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/harvester.go @@ -0,0 +1,105 @@ +package secretmigrator + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rke "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + AuthorizedSecretAnnotation = "v2prov-secret-authorized-for-cluster" + AuthorizedSecretDeletesOnClusterRemovalAnnotation = "v2prov-authorized-secret-deletes-on-cluster-removal" +) + +func (h *handler) syncHarvesterCloudConfig(_ string, cluster *v1.Cluster) (*v1.Cluster, error) { + if cluster == nil || cluster.DeletionTimestamp != nil || cluster.Spec.RKEConfig == nil || cluster.Name == "local" { + return cluster, nil + } + + if v3.ClusterConditionHarvesterCloudProviderConfigMigrated.IsTrue(cluster) || !h.migrator.isHarvesterCluster(cluster) { + return cluster, nil + } + + cluster = cluster.DeepCopy() + updatedRKEConfig := cluster.Spec.RKEConfig.DeepCopy() + initialRKEConfig := cluster.Spec.RKEConfig.DeepCopy() + + harvesterConfigSecrets, err := h.migrator.migrateHarvesterCloudProviderConfig(updatedRKEConfig, cluster, cluster.Name) + if err != nil { + return cluster, err + } + + if len(harvesterConfigSecrets) != 0 { + cluster.Spec.RKEConfig = updatedRKEConfig + cluster, err = h.provisioningClusters.Update(cluster) + if err != nil { + h.migrator.CleanupKnownSecrets(harvesterConfigSecrets) + cluster.Spec.RKEConfig = initialRKEConfig + return cluster, err + } + } + + v3.ClusterConditionHarvesterCloudProviderConfigMigrated.True(cluster) + cluster, err = h.provisioningClusters.UpdateStatus(cluster) + if err != nil { + h.migrator.CleanupKnownSecrets(harvesterConfigSecrets) + cluster.Spec.RKEConfig = initialRKEConfig + return cluster, err + } + return cluster, nil +} + +func (m *Migrator) migrateHarvesterCloudProviderConfig(rkeConfig *v1.RKEConfig, owner runtime.Object, clusterName string) ([]*corev1.Secret, error) { + if rkeConfig == nil || len(rkeConfig.MachineSelectorConfig) == 0 { + return nil, nil + } + + secrets := make([]*corev1.Secret, 0, len(rkeConfig.MachineSelectorConfig)) + for i := range rkeConfig.MachineSelectorConfig { + secret, err := m.createOrUpdateHarvesterCloudProviderConfigSecret(clusterName, rkeConfig.MachineSelectorConfig[i], owner) + if err != nil { + m.CleanupKnownSecrets(secrets) + return nil, err + } + + if secret != nil { + secrets = append(secrets, secret) + rkeConfig.MachineSelectorConfig[i].Config.Data["cloud-provider-config"] = fmt.Sprintf("secret://%s:%s", secret.Namespace, secret.Name) + } + } + + return secrets, nil +} + +func (m *Migrator) createOrUpdateHarvesterCloudProviderConfigSecret(clusterName string, machineSelectorConfig rke.RKESystemConfig, owner runtime.Object) (*corev1.Secret, error) { + name, nameFound := machineSelectorConfig.Config.Data["cloud-provider-name"] + if !nameFound { + return nil, nil + } + + if strings.ToLower(convert.ToString(name)) != "harvester" { + return nil, nil + } + + cloudConfig, cloudProviderConfigFound := machineSelectorConfig.Config.Data["cloud-provider-config"] + if !cloudProviderConfigFound { + return nil, nil + } + + // don't create a new secret if one has already been provided. + if strings.HasPrefix(convert.ToString(cloudConfig), "secret://") { + return nil, nil + } + + annotation := map[string]string{ + AuthorizedSecretAnnotation: clusterName, + } + + return m.CreateOrUpdateHarvesterCloudConfigSecret("", convert.ToString(cloudConfig), annotation, owner, "cloud-provider-config") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/register.go new file mode 100644 index 0000000..0c5a592 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/secretmigrator/register.go @@ -0,0 +1,78 @@ +package secretmigrator + +import ( + "context" + + provv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type Migrator struct { + secretLister v1.SecretLister + secrets v1.SecretInterface +} + +type authConfigsClient interface { + Get(name string, opts metav1.GetOptions) (runtime.Object, error) + Update(name string, o runtime.Object) (runtime.Object, error) +} + +type handler struct { + migrator *Migrator + authConfigLister v3.AuthConfigLister + clusters v3.ClusterInterface + provisioningClusters provv1.ClusterController + clusterTemplateRevisions v3.ClusterTemplateRevisionInterface + catalogLister v3.CatalogLister + catalogs v3.CatalogInterface + clusterCatalogLister v3.ClusterCatalogLister + clusterCatalogs v3.ClusterCatalogInterface + projectCatalogLister v3.ProjectCatalogLister + projectCatalogs v3.ProjectCatalogInterface + projectLister v3.ProjectLister + // AuthConfigs contain internal-only fields that deal with various auth providers. + // Those fields are not present everywhere, nor are they defined in the CRD. Given + // that, the regular client will "eat" those internal-only fields, so in this case, we use + // the unstructured client, losing some validation, but gaining the flexibility we require. + authConfigs authConfigsClient +} + +func NewMigrator(secretLister v1.SecretLister, secrets v1.SecretInterface) *Migrator { + return &Migrator{ + secretLister: secretLister, + secrets: secrets, + } +} + +func Register(ctx context.Context, management *config.ManagementContext) { + management = management.WithAgent("secret-migrator") + h := handler{ + migrator: NewMigrator( + management.Core.Secrets("").Controller().Lister(), + management.Core.Secrets(""), + ), + authConfigs: management.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), + authConfigLister: management.Management.AuthConfigs("").Controller().Lister(), + clusters: management.Management.Clusters(""), + provisioningClusters: management.Wrangler.Provisioning.Cluster(), + clusterTemplateRevisions: management.Management.ClusterTemplateRevisions(""), + catalogLister: management.Management.Catalogs("").Controller().Lister(), + catalogs: management.Management.Catalogs(""), + clusterCatalogLister: management.Management.ClusterCatalogs("").Controller().Lister(), + clusterCatalogs: management.Management.ClusterCatalogs(""), + projectCatalogLister: management.Management.ProjectCatalogs("").Controller().Lister(), + projectCatalogs: management.Management.ProjectCatalogs(""), + projectLister: management.Management.Projects("").Controller().Lister(), + } + management.Management.AuthConfigs("").AddHandler(ctx, "authconfigs-secret-migrator", h.syncAuthConfig) + management.Management.Clusters("").AddHandler(ctx, "cluster-secret-migrator", h.sync) + management.Management.ClusterTemplateRevisions("").AddHandler(ctx, "clustertemplaterevision-secret-migrator", h.syncTemplate) + management.Management.Catalogs("").AddHandler(ctx, "catalog-secret-migrator", h.syncCatalog) + + management.Wrangler.Provisioning.Cluster().OnChange(ctx, "harvester-secret-migrator", h.syncHarvesterCloudConfig) + management.Wrangler.Provisioning.Cluster().OnRemove(ctx, "cloud-config-secret-remover", h.cloudConfigSecretRemover) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/settings/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/settings/controller.go new file mode 100644 index 0000000..4e565cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/settings/controller.go @@ -0,0 +1,52 @@ +package settings + +import ( + "context" + + apis "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +var toCopy = map[string]bool{} + +type handler struct { + cluster v3.ClusterController +} + +func init() { + defaultSettings := settings.DefaultAgentSettings() + + for _, s := range defaultSettings { + toCopy[s.Name] = true + } +} + +func Register(ctx context.Context, management *config.ManagementContext) { + h := &handler{ + cluster: management.Management.Clusters("").Controller(), + } + + management.Management.Settings("").AddHandler(ctx, "copy-settings", h.onChange) +} + +func (h *handler) onChange(key string, obj *apis.Setting) (runtime.Object, error) { + if obj == nil || !toCopy[obj.Name] { + return nil, nil + } + + clusters, err := h.cluster.Lister().List("", labels.Everything()) + if err != nil { + return obj, err + } + for _, c := range clusters { + if c.Name != "local" { + h.cluster.Enqueue("", c.Name) + } + } + + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/README.md new file mode 100644 index 0000000..c2d861e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/README.md @@ -0,0 +1,9 @@ +### e2e tests + +Right now, these tests assume there is at least one running k8s cluster to run against. So, they're currently skipped in CI. But, they are helpful for development and sanity checking. + +Here's how to run them (from this directory): +``` +TEST_CLUSTER_MGR_CONFIG=~/.kube/config TEST_CLUSTER_CONFIG=~/.kube/config go test -check.vv -v . +``` +Obviously, the path to the kube-config file must be valid. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/authz_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/authz_test.go new file mode 100644 index 0000000..7131447 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/authz_test.go @@ -0,0 +1,418 @@ +package e2e + +import ( + "context" + "testing" + + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/controllers/managementuser/rbac" + authzv1 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "gopkg.in/check.v1" + rbacv1 "k8s.io/api/rbac/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + clientset "k8s.io/client-go/kubernetes" +) + +// Hook up gocheck into the "go test" runner. +func Test(t *testing.T) { check.TestingT(t) } + +type AuthzSuite struct { + extClient *extclient.Clientset + clusterClient *clientset.Clientset + ctx *config.UserContext +} + +var _ = check.Suite(&AuthzSuite{}) + +func (s *AuthzSuite) TestClusterRoleTemplateBindingCreate(c *check.C) { + // create project + + // create RoleTemplate (this one will be referenced by the next one) + podRORoleTemplateName := "testsubcrt1" + s.clusterClient.RbacV1().ClusterRoles().Delete(context.TODO(), podRORoleTemplateName, metav1.DeleteOptions{}) + subRT, err := s.createRoleTemplate(podRORoleTemplateName, + []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + ResourceNames: []string{}, + NonResourceURLs: []string{}, + }, + }, []string{}, false, c) + c.Assert(err, check.IsNil) + + // create RoleTemplate that will reference the first one + rtName := "testcrt1" + s.clusterClient.RbacV1().ClusterRoles().Delete(context.TODO(), rtName, metav1.DeleteOptions{}) + rt, err := s.createRoleTemplate(rtName, + []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"apps", "extensions"}, + Resources: []string{"deployments"}, + ResourceNames: []string{}, + NonResourceURLs: []string{}, + }, + }, []string{podRORoleTemplateName}, false, c) + c.Assert(err, check.IsNil) + + // create namespace and watchers for resources in that namespace + bindingWatcher := s.clusterBindingWatcher(c) + defer bindingWatcher.Stop() + + // create ProjectRoleTemplateBinding + subject := rbacv1.Subject{ + Kind: "User", + Name: "user1", + } + binding := s.createCRTBinding("testcbinding1", subject, rtName, c) + + // assert binding is created properly + newBindings := map[string]bool{} + roleNames := []string{rt.Name, subRT.Name} + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + if watch.Modified == watchEvent.Type || watch.Added == watchEvent.Type { + if binding, ok := watchEvent.Object.(*rbacv1.ClusterRoleBinding); ok { + newBindings[binding.Name] = true + c.Assert(binding.Subjects[0].Kind, check.Equals, subject.Kind) + c.Assert(binding.Subjects[0].Name, check.Equals, subject.Name) + c.Assert(slice.ContainsString(roleNames, binding.RoleRef.Name), check.Equals, true) + c.Assert(binding.RoleRef.Kind, check.Equals, "ClusterRole") + } + } + return len(newBindings) == 2 + }) + + // assert corresponding role is created with all the rules + rolesExpected := map[string]*authzv1.RoleTemplate{ + subRT.Name: subRT, + rt.Name: rt, + } + + rolesActual := map[string]rbacv1.ClusterRole{} + rs, err := s.clusterClient.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + for _, r := range rs.Items { + if _, ok := rolesExpected[r.Name]; ok { + rolesActual[r.Name] = r + } + } + c.Assert(len(rolesActual), check.Equals, 2) + for name, rt := range rolesExpected { + c.Assert(rolesActual[name].Rules, check.DeepEquals, rt.Rules) + } + + // Delete the PRTB + bindingWatcher.Stop() + bindingWatcher = s.clusterBindingWatcher(c) + + err = s.ctx.Management.Management.ClusterRoleTemplateBindings("").Delete(binding.Name, &metav1.DeleteOptions{}) + c.Assert(err, check.IsNil) + + deletes := map[string]bool{} + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + if watch.Deleted == watchEvent.Type { + if binding, ok := watchEvent.Object.(*rbacv1.ClusterRoleBinding); ok { + deletes[binding.Name] = true + } + } + return len(deletes) == 2 + }) +} + +func (s *AuthzSuite) TestRoleTemplateBindingCreate(c *check.C) { + // create project + projectName := "testproject1" + + // create RoleTemplate (this one will be referenced by the next one) + podRORoleTemplateName := "testsubrt1" + s.clusterClient.RbacV1().ClusterRoles().Delete(context.TODO(), podRORoleTemplateName, metav1.DeleteOptions{}) + subRT, err := s.createRoleTemplate(podRORoleTemplateName, + []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + ResourceNames: []string{}, + NonResourceURLs: []string{}, + }, + }, []string{}, false, c) + c.Assert(err, check.IsNil) + + // create RoleTemplate that will reference the first one + rtName := "testrt1" + s.clusterClient.RbacV1().ClusterRoles().Delete(context.TODO(), rtName, metav1.DeleteOptions{}) + rt, err := s.createRoleTemplate(rtName, + []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"apps", "extensions"}, + Resources: []string{"deployments"}, + ResourceNames: []string{}, + NonResourceURLs: []string{}, + }, + }, []string{podRORoleTemplateName}, false, c) + c.Assert(err, check.IsNil) + + // create namespace and watchers for resources in that namespace + ns := setupNS("testauthzns1", projectName, s.clusterClient.CoreV1().Namespaces(), c) + defer deleteNSOnPass(ns.Name, s.clusterClient.CoreV1().Namespaces(), c) + bindingWatcher := s.bindingWatcher(ns.Name, c) + defer bindingWatcher.Stop() + + // create ProjectRoleTemplateBinding + subject := rbacv1.Subject{ + Kind: "User", + Name: "user1", + } + binding := s.createPRTBinding("testbinding1", subject, projectName, rtName, c) + + // assert binding is created properly + newBindings := map[string]bool{} + roleNames := []string{rt.Name, subRT.Name} + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + if watch.Modified == watchEvent.Type || watch.Added == watchEvent.Type { + if binding, ok := watchEvent.Object.(*rbacv1.RoleBinding); ok { + newBindings[binding.Name] = true + c.Assert(binding.Subjects[0].Kind, check.Equals, subject.Kind) + c.Assert(binding.Subjects[0].Name, check.Equals, subject.Name) + c.Assert(slice.ContainsString(roleNames, binding.RoleRef.Name), check.Equals, true) + c.Assert(binding.RoleRef.Kind, check.Equals, "ClusterRole") + } + } + return len(newBindings) == 2 + }) + + // assert corresponding role is created with all the rules + rolesExpected := map[string]*authzv1.RoleTemplate{ + subRT.Name: subRT, + rt.Name: rt, + } + + rolesActual := map[string]rbacv1.ClusterRole{} + rs, err := s.clusterClient.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + for _, r := range rs.Items { + if _, ok := rolesExpected[r.Name]; ok { + rolesActual[r.Name] = r + } + } + c.Assert(len(rolesActual), check.Equals, 2) + for name, rt := range rolesExpected { + c.Assert(rolesActual[name].Rules, check.DeepEquals, rt.Rules) + } + + // Delete the PRTB + bindingWatcher.Stop() + bindingWatcher = s.bindingWatcher(ns.Name, c) + + err = s.ctx.Management.Management.ProjectRoleTemplateBindings("default").Delete(binding.Name, &metav1.DeleteOptions{}) + c.Assert(err, check.IsNil) + + deletes := map[string]bool{} + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + if watch.Deleted == watchEvent.Type { + if binding, ok := watchEvent.Object.(*rbacv1.RoleBinding); ok { + deletes[binding.Name] = true + } + } + return len(deletes) == 2 + }) +} + +func (s *AuthzSuite) TestBuiltinRoleTemplateBindingCreate(c *check.C) { + // create project + projectName := "testproject2" + + // create RoleTemplate that user will be bound to + rtName := "testrt2" + _, err := s.createRoleTemplate(rtName, + []rbacv1.PolicyRule{}, []string{}, true, c) + c.Assert(err, check.IsNil) + + // create namespace and watchers for resources in that namespace + ns := setupNS("testauthzbuiltinns1", projectName, s.clusterClient.CoreV1().Namespaces(), c) + defer deleteNSOnPass(ns.Name, s.clusterClient.CoreV1().Namespaces(), c) + bindingWatcher := s.bindingWatcher(ns.Name, c) + defer bindingWatcher.Stop() + + roles, err := s.clusterClient.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + rolesPreCount := len(roles.Items) + + // create ProjectRoleTemplateBinding + subject := rbacv1.Subject{ + Kind: "User", + Name: "user1", + } + binding := s.createPRTBinding("testbuiltin1", subject, projectName, rtName, c) + + // assert binding is created properly + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + if watch.Modified == watchEvent.Type || watch.Added == watchEvent.Type { + if binding, ok := watchEvent.Object.(*rbacv1.RoleBinding); ok { + c.Assert(binding.Subjects[0].Kind, check.Equals, subject.Kind) + c.Assert(binding.Subjects[0].Name, check.Equals, subject.Name) + c.Assert(binding.RoleRef.Name, check.Equals, rtName) + c.Assert(binding.RoleRef.Kind, check.Equals, "ClusterRole") + return true + } + } + return false + }) + + // ensure no new roles were created in the namespace + roles, err = s.clusterClient.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + rolesPostCount := len(roles.Items) + c.Assert(rolesPostCount, check.Equals, rolesPreCount) + + // Delete the PRTB + bindingWatcher.Stop() + bindingWatcher = s.bindingWatcher(ns.Name, c) + + err = s.ctx.Management.Management.ProjectRoleTemplateBindings("default").Delete(binding.Name, &metav1.DeleteOptions{}) + c.Assert(err, check.IsNil) + + watchChecker(bindingWatcher, c, func(watchEvent watch.Event) bool { + return watch.Deleted == watchEvent.Type + }) +} + +func (s *AuthzSuite) createCRTBinding(bindingName string, subject rbacv1.Subject, rtName string, c *check.C) *authzv1.ClusterRoleTemplateBinding { + binding, err := s.ctx.Management.Management.ClusterRoleTemplateBindings("").Create(&authzv1.ClusterRoleTemplateBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: "ClusterRoleTemplateBinding", + APIVersion: "management.cattle.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + }, + UserName: subject.Name, + RoleTemplateName: rtName, + }) + + c.Assert(err, check.IsNil) + c.Assert(binding.Name, check.Equals, bindingName) + return binding +} + +func (s *AuthzSuite) createPRTBinding(bindingName string, subject rbacv1.Subject, projectName string, rtName string, c *check.C) *authzv1.ProjectRoleTemplateBinding { + binding, err := s.ctx.Management.Management.ProjectRoleTemplateBindings("default").Create(&authzv1.ProjectRoleTemplateBinding{ + TypeMeta: metav1.TypeMeta{ + Kind: "ProjectRoleTemplateBinding", + APIVersion: "management.cattle.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + }, + UserName: subject.Name, + ProjectName: projectName, + RoleTemplateName: rtName, + }) + + c.Assert(err, check.IsNil) + c.Assert(binding.Name, check.Equals, bindingName) + return binding +} + +func (s *AuthzSuite) createRoleTemplate(name string, rules []rbacv1.PolicyRule, prts []string, builtin bool, c *check.C) (*authzv1.RoleTemplate, error) { + rt, err := s.ctx.Management.Management.RoleTemplates("").Create(&authzv1.RoleTemplate{ + TypeMeta: metav1.TypeMeta{ + Kind: "RoleTemplate", + APIVersion: "management.cattle.io/v3", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Rules: rules, + RoleTemplateNames: prts, + Builtin: builtin, + }) + c.Assert(err, check.IsNil) + c.Assert(rt.Name, check.Equals, name) + return rt, err +} + + +func (s *AuthzSuite) clusterBindingWatcher(c *check.C) watch.Interface { + bindingClient := s.clusterClient.RbacV1().ClusterRoleBindings() + bList, err := bindingClient.List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + bListMeta, err := meta.ListAccessor(bList) + c.Assert(err, check.IsNil) + bindingWatch, err := bindingClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: bListMeta.GetResourceVersion()}) + c.Assert(err, check.IsNil) + return bindingWatch +} + +func (s *AuthzSuite) bindingWatcher(namespace string, c *check.C) watch.Interface { + bindingClient := s.clusterClient.RbacV1().RoleBindings(namespace) + bList, err := bindingClient.List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + bListMeta, err := meta.ListAccessor(bList) + c.Assert(err, check.IsNil) + bindingWatch, err := bindingClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: bListMeta.GetResourceVersion()}) + c.Assert(err, check.IsNil) + return bindingWatch +} + +func (s *AuthzSuite) roleWatcher(c *check.C) watch.Interface { + roleClient := s.clusterClient.RbacV1().ClusterRoles() + initialList, err := roleClient.List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + initialListListMeta, err := meta.ListAccessor(initialList) + c.Assert(err, check.IsNil) + roleWatch, err := roleClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: initialListListMeta.GetResourceVersion()}) + c.Assert(err, check.IsNil) + return roleWatch +} + +func (s *AuthzSuite) SetUpSuite(c *check.C) { + c.Skip("Environments not configured for client setup: TEST_CLUSTER_CONFIG is missing") + clusterClient, extClient, workload := clientForSetup(c) + s.extClient = extClient + s.clusterClient = clusterClient + s.ctx = workload + s.setupCRDs(c) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + rbac.Register(ctx, workload) + + err := workload.Start(ctx) + c.Assert(err, check.IsNil) + err = workload.Management.ControllerFactory.Start(ctx, 5) + c.Assert(err, check.IsNil) + +} + +func (s *AuthzSuite) setupCRDs(c *check.C) { + crdClient := s.extClient.ApiextensionsV1().CustomResourceDefinitions() + + initialList, err := crdClient.List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + + initialListListMeta, err := meta.ListAccessor(initialList) + c.Assert(err, check.IsNil) + + crdWatch, err := crdClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: initialListListMeta.GetResourceVersion()}) + c.Assert(err, check.IsNil) + defer crdWatch.Stop() + + setupCRD("roletemplate", "roletemplates", "management.cattle.io", "RoleTemplate", "v3", + apiextensionsv1.ClusterScoped, crdClient, crdWatch, c) + + setupCRD("projectroletemplatebinding", "projectroletemplatebindings", "management.cattle.io", "ProjectRoleTemplateBinding", "v3", + apiextensionsv1.ClusterScoped, crdClient, crdWatch, c) + + setupCRD("clusterroletemplatebinding", "clusterroletemplatebindings", "management.cattle.io", "ClusterRoleTemplateBinding", "v3", + apiextensionsv1.ClusterScoped, crdClient, crdWatch, c) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/common_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/common_test.go new file mode 100644 index 0000000..2efb2bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/common_test.go @@ -0,0 +1,199 @@ +package e2e + +import ( + "context" + "os" + "time" + + "github.com/rancher/rancher/pkg/types/config" + "gopkg.in/check.v1" + corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + crdclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + clientset "k8s.io/client-go/kubernetes" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/tools/clientcmd" +) + +func setupNS(name, projectName string, nsClient v1.NamespaceInterface, c *check.C) *corev1.Namespace { + if _, err := nsClient.Get(context.TODO(), name, metav1.GetOptions{}); err == nil { + nsList, err := nsClient.List(context.TODO(), metav1.ListOptions{}) + c.Assert(err, check.IsNil) + nsListMeta, err := meta.ListAccessor(nsList) + c.Assert(err, check.IsNil) + nsWatch, err := nsClient.Watch(context.TODO(), metav1.ListOptions{ResourceVersion: nsListMeta.GetResourceVersion()}) + c.Assert(err, check.IsNil) + defer nsWatch.Stop() + + if err := nsClient.Delete(context.TODO(), name, metav1.DeleteOptions{}); err != nil { + c.Fatal(err) + } + + Loop: + for { + select { + case watchEvent := <-nsWatch.ResultChan(): + if watch.Deleted == watchEvent.Type || watch.Modified == watchEvent.Type { + if ns, ok := watchEvent.Object.(*corev1.Namespace); ok && ns.Name == name { + for i := 0; i < 10; i++ { + if ns, err := nsClient.Get(context.TODO(), name, metav1.GetOptions{}); err == nil { + if ns.Status.Phase == corev1.NamespaceTerminating && len(ns.Spec.Finalizers) == 0 { + break Loop + } + } else { + break Loop + } + time.Sleep(time.Second) + } + } + } + case <-time.After(15 * time.Second): + c.Fatalf("Timeout waiting for namesapce to delete") + } + } + } + + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Annotations: map[string]string{ + "field.cattle.io/projectId": projectName, + }, + }, + } + ns, err := nsClient.Create(context.TODO(), ns, metav1.CreateOptions{}) + c.Assert(err, check.IsNil) + + return ns +} + +func setupCRD(name, plural, group, kind, version string, scope apiextensionsv1.ResourceScope, crdClient crdclient.CustomResourceDefinitionInterface, + crdWatch watch.Interface, c *check.C) { + fullName := plural + "." + group + + if err := crdClient.Delete(context.TODO(), fullName, metav1.DeleteOptions{}); err == nil { + waitForCRDDeleted(fullName, crdWatch, crdClient, c) + } + + crd := newCRD(fullName, name, plural, group, kind, version, scope) + _, err := crdClient.Create(context.TODO(), crd, metav1.CreateOptions{}) + c.Assert(err, check.IsNil) + waitForCRDEstablished(fullName, crdWatch, crdClient, c) +} + +func waitForCRDEstablished(name string, crdWatch watch.Interface, crdClient crdclient.CustomResourceDefinitionInterface, c *check.C) { + for { + select { + case watchEvent := <-crdWatch.ResultChan(): + if watch.Modified == watchEvent.Type || watch.Added == watchEvent.Type { + if crd, ok := watchEvent.Object.(*apiextensionsv1.CustomResourceDefinition); ok && crd.Name == name { + got, err := crdClient.Get(context.TODO(), name, metav1.GetOptions{}) + c.Assert(err, check.IsNil) + + for _, c := range got.Status.Conditions { + if apiextensionsv1.Established == c.Type && apiextensionsv1.ConditionTrue == c.Status { + return + } + } + } + } + case <-time.After(5 * time.Second): + c.Fatalf("Timeout waiting for CRD %v to be established", name) + } + } +} + +func waitForCRDDeleted(name string, crdWatch watch.Interface, crdClient crdclient.CustomResourceDefinitionInterface, c *check.C) { +Loop: + for { + select { + case watchEvent := <-crdWatch.ResultChan(): + if watch.Deleted == watchEvent.Type { + if crd, ok := watchEvent.Object.(*apiextensionsv1.CustomResourceDefinition); ok && crd.Name == name { + break Loop + } + } + case <-time.After(5 * time.Second): + c.Fatalf("timeout waiting for CRD %v to be deleted", name) + } + } +} + +func newCRD(fullName, name, plural, group, kind, version string, scope apiextensionsv1.ResourceScope) *apiextensionsv1.CustomResourceDefinition { + return &apiextensionsv1.CustomResourceDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: fullName, + }, + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Group: group, + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: version, + Served: true, + Storage: true, + Schema: &apiextensionsv1.CustomResourceValidation{ + OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{ + Type: "object", + XPreserveUnknownFields: &[]bool{true}[0], + }, + }, + }, + }, + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: plural, + Singular: name, + Kind: kind, + }, + Scope: scope, + }, + } +} + +func clientForSetup(c *check.C) (*clientset.Clientset, *extclient.Clientset, *config.UserContext) { + mgrConfig := os.Getenv("TEST_CLUSTER_MGR_CONFIG") + clusterKubeConfig, err := clientcmd.BuildConfigFromFlags("", mgrConfig) + c.Assert(err, check.IsNil) + + extensionClient, err := extclient.NewForConfig(clusterKubeConfig) + c.Assert(err, check.IsNil) + + conf := os.Getenv("TEST_CLUSTER_CONFIG") + workloadKubeConfig, err := clientcmd.BuildConfigFromFlags("", conf) + c.Assert(err, check.IsNil) + + clusterClient, err := clientset.NewForConfig(workloadKubeConfig) + c.Assert(err, check.IsNil) + + scaledContext, err := config.NewScaledContext(*clusterKubeConfig, nil) + c.Assert(err, check.IsNil) + + workload, err := config.NewUserContext(scaledContext, *workloadKubeConfig, "") + c.Assert(err, check.IsNil) + + return clusterClient, extensionClient, workload +} + +func watchChecker(watcher watch.Interface, c *check.C, checker func(watchEvent watch.Event) bool) { + for { + select { + case watchEvent := <-watcher.ResultChan(): + if checker(watchEvent) { + return + } + case <-time.After(5 * time.Second): + c.Fatalf("Timeout waiting watch condition") + } + } +} + +func deleteNSOnPass(name string, nsClient v1.NamespaceInterface, c *check.C) { + if !c.Failed() { + if err := nsClient.Delete(context.TODO(), name, metav1.DeleteOptions{}); err != nil { + c.Logf("Error deleting ns %v: %v", name, err) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/master.conf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/master.conf new file mode 100644 index 0000000..1756cee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/test/e2e/master.conf @@ -0,0 +1,24 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority: /home/cjellick/.minikube/ca.crt + server: https://192.168.43.12:8443 + name: app1 +- cluster: + certificate-authority: /home/cjellick/.minikube/ca.crt + server: https://192.168.43.231:8443 + name: master +contexts: +- context: + cluster: master + user: master + name: master +current-context: master +kind: Config +preferences: {} +users: +- name: master + user: + as-user-extra: {} + client-certificate: /home/cjellick/.minikube/client.crt + client-key: /home/cjellick/.minikube/client.key diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/usercontrollers/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/usercontrollers/controller.go new file mode 100644 index 0000000..5b1713f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/usercontrollers/controller.go @@ -0,0 +1,478 @@ +package usercontrollers + +import ( + "context" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/imported" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + batchV1 "k8s.io/api/batch/v1" + coreV1 "k8s.io/api/core/v1" + rbacV1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" +) + +const ( + WebhookClusterRoleBindingName = "rancher-webhook" + WebhookConfigurationName = "rancher.cattle.io" +) + +var ( + // There is a mirror list in pkg/agent/clean/clean.go. If these are getting + // updated consider if that update needs to apply to the user cluster as well + + // List of namespace labels that will be removed + nsLabels = []string{ + nslabels.ProjectIDFieldLabel, + } + + // List of namespace annotations that will be removed + nsAnnotations = []string{ + "cattle.io/status", + "field.cattle.io/creatorId", + "field.cattle.io/resourceQuotaTemplateId", + "lifecycle.cattle.io/create.namespace-auth", + nslabels.ProjectIDFieldLabel, + helm.AppIDsLabel, + } +) + +/* +RegisterEarly registers ClusterLifecycleCleanup controller which is responsible for stopping rancher agent in user cluster, +and de-registering k8s controllers, on cluster.remove +*/ +func RegisterEarly(ctx context.Context, management *config.ManagementContext, manager *clustermanager.Manager) { + lifecycle := &ClusterLifecycleCleanup{ + Manager: manager, + ctx: ctx, + } + + clusterClient := management.Management.Clusters("") + clusterClient.AddLifecycle(ctx, "cluster-agent-controller-cleanup", lifecycle) +} + +type ClusterLifecycleCleanup struct { + Manager *clustermanager.Manager + ctx context.Context +} + +func (c *ClusterLifecycleCleanup) Create(obj *v3.Cluster) (runtime.Object, error) { + return nil, nil +} + +func (c *ClusterLifecycleCleanup) Remove(obj *v3.Cluster) (runtime.Object, error) { + if obj == nil { + return obj, nil + } + + // Try to clean up an imported cluster 3 times, then move on. + backoff := wait.Backoff{ + Duration: 3 * time.Second, + Factor: 1, + Steps: 3, + } + + if err := wait.ExponentialBackoff(backoff, func() (bool, error) { + var err error + if obj.Name == "local" && obj.Spec.Internal { + err = c.cleanupLocalCluster(obj) + } else if obj.Status.Driver == v32.ClusterDriverK3s || + obj.Status.Driver == v32.ClusterDriverK3os || + obj.Status.Driver == v32.ClusterDriverRke2 || + obj.Status.Driver == v32.ClusterDriverRancherD || + (obj.Status.Driver == v32.ClusterDriverImported && !imported.IsAdministratedByProvisioningCluster(obj)) || + (obj.Status.AKSStatus.UpstreamSpec != nil && obj.Status.AKSStatus.UpstreamSpec.Imported) || + (obj.Status.EKSStatus.UpstreamSpec != nil && obj.Status.EKSStatus.UpstreamSpec.Imported) || + (obj.Status.GKEStatus.UpstreamSpec != nil && obj.Status.GKEStatus.UpstreamSpec.Imported) { + err = c.cleanupImportedCluster(obj) + } + if err != nil { + logrus.Infof("[cluster-cleanup] error cleaning up cluster [%s]: %v", obj.Name, err) + } + return err == nil, nil + }); err != nil { + logrus.Warnf("[cluster-cleanup] could not clean imported cluster [%s], moving on with removing cluster: %v", obj.Name, err) + } + + c.Manager.Stop(obj) + return nil, nil +} + +func (c *ClusterLifecycleCleanup) cleanupLocalCluster(obj *v3.Cluster) error { + userContext, err := c.Manager.UserContextFromCluster(obj) + if err != nil { + return err + } + if userContext == nil { + logrus.Debugf("could not get context for local cluster, skipping cleanup") + return nil + } + + err = cleanupNamespaces(userContext.K8sClient) + if err != nil { + return err + } + + propagationBackground := metav1.DeletePropagationBackground + deleteOptions := &metav1.DeleteOptions{ + PropagationPolicy: &propagationBackground, + } + + err = userContext.Apps.Deployments("cattle-system").Delete("cattle-cluster-agent", deleteOptions) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + err = userContext.Apps.DaemonSets("cattle-system").Delete("cattle-node-agent", deleteOptions) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil +} + +func (c *ClusterLifecycleCleanup) Updated(obj *v3.Cluster) (runtime.Object, error) { + return nil, nil +} + +func (c *ClusterLifecycleCleanup) cleanupImportedCluster(cluster *v3.Cluster) error { + userContext, err := c.Manager.UserContextFromCluster(cluster) + if err != nil { + return err + } + if userContext == nil { + logrus.Debugf("could not get context for imported cluster, skipping cleanup") + return nil + } + + role, err := c.createCleanupClusterRole(userContext) + if err != nil { + return err + } + + sa, err := c.createCleanupServiceAccount(userContext) + if err != nil { + return err + } + + crb, err := c.createCleanupClusterRoleBinding(userContext, role.Name, sa.Name) + if err != nil { + return err + } + + job, err := c.createCleanupJob(userContext, sa.Name) + if err != nil { + return err + } + + or := []metav1.OwnerReference{ + metav1.OwnerReference{ + APIVersion: "batch/v1", + Kind: "Job", + Name: job.Name, + UID: job.UID, + }, + } + + // These resouces need the ownerReference added so they get cleaned up after + // the job deletes itself. + + err = c.updateClusterRoleOwner(userContext, role, or) + if err != nil { + return err + } + + err = c.updateServiceAccountOwner(userContext, sa, or) + if err != nil { + return err + } + + err = c.updateClusterRoleBindingOwner(userContext, crb, or) + if err != nil { + return err + } + + return nil +} + +func (c *ClusterLifecycleCleanup) createCleanupClusterRole(userContext *config.UserContext) (*rbacV1.ClusterRole, error) { + meta := metav1.ObjectMeta{ + GenerateName: "cattle-cleanup-", + } + + rules := []rbacV1.PolicyRule{ + // This is needed to check for cattle-system, remove finalizers and delete + { + Verbs: []string{"list", "get", "update", "delete"}, + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + }, + { + Verbs: []string{"list", "get", "delete"}, + APIGroups: []string{"rbac.authorization.k8s.io"}, + Resources: []string{"roles", "rolebindings", "clusterroles", "clusterrolebindings"}, + }, + // The job is going to delete itself after running to trigger ownerReference + // cleanup of the clusterRole, serviceAccount and clusterRoleBinding + { + Verbs: []string{"list", "get", "delete"}, + APIGroups: []string{"batch"}, + Resources: []string{"jobs"}, + }, + // The job checks for the presence of the rancher service first + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"services"}, + ResourceNames: []string{"rancher"}, + }, + { + Verbs: []string{"delete"}, + APIGroups: []string{"admissionregistration.k8s.io"}, + Resources: []string{"validatingwebhookconfigurations", "mutatingwebhookconfigurations"}, + ResourceNames: []string{WebhookConfigurationName}, + }, + } + clusterRole := rbacV1.ClusterRole{ + ObjectMeta: meta, + Rules: rules, + } + return userContext.K8sClient.RbacV1().ClusterRoles().Create(context.TODO(), &clusterRole, metav1.CreateOptions{}) +} + +func (c *ClusterLifecycleCleanup) createCleanupServiceAccount(userContext *config.UserContext) (*coreV1.ServiceAccount, error) { + meta := metav1.ObjectMeta{ + GenerateName: "cattle-cleanup-", + Namespace: "default", + } + serviceAccount := coreV1.ServiceAccount{ + ObjectMeta: meta, + } + return userContext.K8sClient.CoreV1().ServiceAccounts("default").Create(context.TODO(), &serviceAccount, metav1.CreateOptions{}) +} + +func (c *ClusterLifecycleCleanup) createCleanupClusterRoleBinding( + userContext *config.UserContext, + role, sa string, +) (*rbacV1.ClusterRoleBinding, error) { + meta := metav1.ObjectMeta{ + GenerateName: "cattle-cleanup-", + Namespace: "default", + } + clusterRoleBinding := rbacV1.ClusterRoleBinding{ + ObjectMeta: meta, + Subjects: []rbacV1.Subject{ + rbacV1.Subject{ + Kind: "ServiceAccount", + Name: sa, + Namespace: "default", + }, + }, + RoleRef: rbacV1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: role, + }, + } + return userContext.K8sClient.RbacV1().ClusterRoleBindings().Create(context.TODO(), &clusterRoleBinding, metav1.CreateOptions{}) +} + +func (c *ClusterLifecycleCleanup) createCleanupJob(userContext *config.UserContext, sa string) (*batchV1.Job, error) { + meta := metav1.ObjectMeta{ + GenerateName: "cattle-cleanup-", + Namespace: "default", + Labels: map[string]string{"cattle.io/creator": "norman"}, + } + + job := batchV1.Job{ + ObjectMeta: meta, + Spec: batchV1.JobSpec{ + Template: coreV1.PodTemplateSpec{ + Spec: coreV1.PodSpec{ + ServiceAccountName: sa, + Containers: []coreV1.Container{ + coreV1.Container{ + Name: "cleanup-agent", + Image: image.Resolve(settings.AgentImage.Get()), + Env: []coreV1.EnvVar{ + coreV1.EnvVar{ + Name: "CLUSTER_CLEANUP", + Value: "true", + }, + coreV1.EnvVar{ + Name: "SLEEP_FIRST", + Value: "true", + }, + }, + ImagePullPolicy: coreV1.PullAlways, + SecurityContext: &coreV1.SecurityContext{ + RunAsUser: &[]int64{1000}[0], + RunAsGroup: &[]int64{1000}[0], + }, + }, + }, + RestartPolicy: "OnFailure", + }, + }, + }, + } + return userContext.K8sClient.BatchV1().Jobs("default").Create(context.TODO(), &job, metav1.CreateOptions{}) +} + +func (c *ClusterLifecycleCleanup) updateClusterRoleOwner( + userContext *config.UserContext, + role *rbacV1.ClusterRole, + or []metav1.OwnerReference, +) error { + return tryUpdate(func() error { + role, err := userContext.K8sClient.RbacV1().ClusterRoles().Get(context.TODO(), role.Name, metav1.GetOptions{}) + if err != nil { + return err + } + role.OwnerReferences = or + + _, err = userContext.K8sClient.RbacV1().ClusterRoles().Update(context.TODO(), role, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }) +} + +func (c *ClusterLifecycleCleanup) updateServiceAccountOwner( + userContext *config.UserContext, + sa *coreV1.ServiceAccount, + or []metav1.OwnerReference, +) error { + return tryUpdate(func() error { + sa, err := userContext.K8sClient.CoreV1().ServiceAccounts("default").Get(context.TODO(), sa.Name, metav1.GetOptions{}) + if err != nil { + return err + } + sa.OwnerReferences = or + + _, err = userContext.K8sClient.CoreV1().ServiceAccounts("default").Update(context.TODO(), sa, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }) +} + +func (c *ClusterLifecycleCleanup) updateClusterRoleBindingOwner( + userContext *config.UserContext, + crb *rbacV1.ClusterRoleBinding, + or []metav1.OwnerReference, +) error { + return tryUpdate(func() error { + crb, err := userContext.K8sClient.RbacV1().ClusterRoleBindings().Get(context.TODO(), crb.Name, metav1.GetOptions{}) + if err != nil { + return err + } + crb.OwnerReferences = or + + _, err = userContext.K8sClient.RbacV1().ClusterRoleBindings().Update(context.TODO(), crb, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil + }) +} + +func cleanupNamespaces(client kubernetes.Interface) error { + logrus.Debug("Starting cleanup of local cluster namespaces") + namespaces, err := client.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + + for _, ns := range namespaces.Items { + err = tryUpdate(func() error { + nameSpace, err := client.CoreV1().Namespaces().Get(context.TODO(), ns.Name, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + + var updated bool + + // Cleanup finalizers + if len(nameSpace.Finalizers) > 0 { + finalizers := []string{} + for _, finalizer := range nameSpace.Finalizers { + if finalizer != "controller.cattle.io/namespace-auth" { + finalizers = append(finalizers, finalizer) + } + } + if len(nameSpace.Finalizers) != len(finalizers) { + updated = true + nameSpace.Finalizers = finalizers + } + } + + // Cleanup labels + for _, label := range nsLabels { + if _, ok := nameSpace.Labels[label]; ok { + updated = ok + delete(nameSpace.Labels, label) + } + } + + // Cleanup annotations + for _, anno := range nsAnnotations { + if _, ok := nameSpace.Annotations[anno]; ok { + updated = ok + delete(nameSpace.Annotations, anno) + } + } + + if updated { + logrus.Debugf("Updating local namespace: %v", nameSpace.Name) + _, err = client.CoreV1().Namespaces().Update(context.TODO(), nameSpace, metav1.UpdateOptions{}) + if err != nil { + return err + } + + } + + return nil + }) + + if err != nil { + return err + } + } + + return nil +} + +// tryUpdate runs the input func and if the error returned is a conflict error +// from k8s it will sleep and attempt to run the func again. This is useful +// when attempting to update an object. +func tryUpdate(f func() error) error { + timeout := 100 + for i := 0; i <= 3; i++ { + err := f() + if err != nil { + if apierrors.IsConflict(err) { + time.Sleep(time.Duration(timeout) * time.Millisecond) + timeout *= 2 + continue + } + return err + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/wrangler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/wrangler.go new file mode 100644 index 0000000..21952ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/management/wrangler.go @@ -0,0 +1,35 @@ +package management + +import ( + "context" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/aks" + "github.com/rancher/rancher/pkg/controllers/management/authprovisioningv2" + "github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher" + "github.com/rancher/rancher/pkg/controllers/management/eks" + "github.com/rancher/rancher/pkg/controllers/management/feature" + "github.com/rancher/rancher/pkg/controllers/management/gke" + "github.com/rancher/rancher/pkg/controllers/management/k3sbasedupgrade" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" +) + +func RegisterWrangler(ctx context.Context, wranglerContext *wrangler.Context, management *config.ManagementContext, manager *clustermanager.Manager) error { + k3sbasedupgrade.Register(ctx, wranglerContext, management, manager) + aks.Register(ctx, wranglerContext, management) + eks.Register(ctx, wranglerContext, management) + gke.Register(ctx, wranglerContext, management) + clusterupstreamrefresher.Register(ctx, wranglerContext) + + feature.Register(ctx, wranglerContext) + + if features.ProvisioningV2.Enabled() { + if err := authprovisioningv2.Register(ctx, wranglerContext, management); err != nil { + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/controllers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/controllers.go new file mode 100644 index 0000000..1173618 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/controllers.go @@ -0,0 +1,32 @@ +package managementagent + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/managementagent/dnsrecord" + "github.com/rancher/rancher/pkg/controllers/managementagent/endpoints" + "github.com/rancher/rancher/pkg/controllers/managementagent/externalservice" + "github.com/rancher/rancher/pkg/controllers/managementagent/ingress" + "github.com/rancher/rancher/pkg/controllers/managementagent/ingresshostgen" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + "github.com/rancher/rancher/pkg/controllers/managementagent/nsserviceaccount" + "github.com/rancher/rancher/pkg/controllers/managementagent/podresources" + "github.com/rancher/rancher/pkg/controllers/managementagent/targetworkloadservice" + "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, cluster *config.UserOnlyContext) error { + dnsrecord.Register(ctx, cluster) + externalservice.Register(ctx, cluster) + endpoints.Register(ctx, cluster) + ingress.Register(ctx, cluster) + ingresshostgen.Register(ctx, cluster) + nslabels.Register(ctx, cluster) + podresources.Register(ctx, cluster) + targetworkloadservice.Register(ctx, cluster) + workload.Register(ctx, cluster) + nsserviceaccount.Register(ctx, cluster) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/dnsrecord/dnsrecord.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/dnsrecord/dnsrecord.go new file mode 100644 index 0000000..231c375 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/dnsrecord/dnsrecord.go @@ -0,0 +1,280 @@ +package dnsrecord + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + + "sync" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/convert" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + DNSAnnotation = "field.cattle.io/targetDnsRecordIds" + SvcTypeExternalName = "ExternalName" +) + +var dnsServiceUUIDToTargetEndpointUUIDs sync.Map +var serviceUUIDToHostNameAlias sync.Map + +// Controller is responsible for monitoring DNSRecord services +// and populating the endpoint based on target service endpoints. +// The controller DOES NOT monitor the changes to the target endpoints; +// that would be handled in the by EndpointController +type Controller struct { + endpoints v1.EndpointsInterface + services v1.ServiceInterface + serviceController v1.ServiceController + endpointLister v1.EndpointsLister + serviceLister v1.ServiceLister +} + +// EndpointController is responsible for monitoring endpoints +// finding out if they are the part of DNSRecord service +// and calling the update on the target service +type EndpointController struct { + serviceController v1.ServiceController + serviceLister v1.ServiceLister +} + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + c := &Controller{ + endpoints: workload.Core.Endpoints(""), + services: workload.Core.Services(""), + serviceController: workload.Core.Services("").Controller(), + endpointLister: workload.Core.Endpoints("").Controller().Lister(), + serviceLister: workload.Core.Services("").Controller().Lister(), + } + + e := &EndpointController{ + serviceController: workload.Core.Services("").Controller(), + serviceLister: workload.Core.Services("").Controller().Lister(), + } + workload.Core.Services("").AddHandler(ctx, "dnsRecordController", c.sync) + workload.Core.Endpoints("").AddHandler(ctx, "dnsRecordEndpointsController", e.reconcileServicesForEndpoint) + +} + +func (c *Controller) sync(key string, obj *corev1.Service) (runtime.Object, error) { + // no need to handle the remove + if obj == nil || obj.DeletionTimestamp != nil { + c.queueUpdateForExtNameSvc(key, true) + dnsServiceUUIDToTargetEndpointUUIDs.Delete(key) + return nil, nil + } + c.queueUpdateForExtNameSvc(key, false) + return nil, c.reconcileEndpoints(key, obj) +} + +func (c *Controller) reconcileEndpoints(key string, obj *corev1.Service) error { + // only process services having targetDNSRecordIds in annotation + if obj.Annotations == nil { + return nil + } + value, ok := obj.Annotations[DNSAnnotation] + if !ok { + return nil + } + + var records []string + err := json.Unmarshal([]byte(value), &records) + if err != nil { + // just log the error, can't really do anything here. + logrus.Debugf("Failed to unmarshal targetDnsRecordIds, error: %v", err) + return nil + } + if records == nil { + return nil + } + + var newEndpointSubsets []corev1.EndpointSubset + var addresses []corev1.EndpointAddress + targetEndpointUUIDs := make(map[string]bool) + toHandleExternalName := false + var externalName string + for _, record := range records { + groomed := strings.TrimSpace(record) + namespaceService := strings.Split(groomed, ":") + if len(namespaceService) < 2 { + return fmt.Errorf("wrong format for dns record [%s]", groomed) + } + namespace := namespaceService[0] + service := namespaceService[1] + targetEndpoint, err := c.endpointLister.Get(namespace, service) + if err != nil { + exists, name, beingDeleted, err := c.checkLinkedSvc(namespace, service, obj.Spec.ExternalName) + if err != nil { + return errors.Wrapf(err, "Error fetching dns hostName service [%s] in namespace [%s] : %s", service, namespace, err) + } + aliasExtType := obj.Spec.Type == SvcTypeExternalName + if aliasExtType && beingDeleted { + logrus.Debugf("Cannot fetch dns hostName service [%s] in namespace [%s] : it is being deleted", service, namespace) + } + if exists || aliasExtType { + toHandleExternalName = true + externalName = name + svcKey := fmt.Sprintf("%s/%s", namespace, service) + serviceUUIDToHostNameAlias.Store(svcKey, key) + continue + } + logrus.Warnf("Failed to fetch endpoints for dns record [%s]: [%v]", groomed, err) + continue + } + if targetEndpoint.DeletionTimestamp != nil { + logrus.Warnf("Failed to fetch endpoints for dns record [%s]: endpoint is being removed", groomed) + continue + } + for _, subset := range targetEndpoint.Subsets { + for _, addr := range subset.Addresses { + addresses = append(addresses, addr) + } + } + targetEndpointUUID := fmt.Sprintf("%s/%s", targetEndpoint.Namespace, targetEndpoint.Name) + targetEndpointUUIDs[targetEndpointUUID] = true + } + + var ports []corev1.EndpointPort + if len(addresses) > 0 { + for _, p := range obj.Spec.Ports { + epPort := corev1.EndpointPort{Name: p.Name, Protocol: p.Protocol, Port: p.TargetPort.IntVal} + ports = append(ports, epPort) + } + if len(ports) == 0 { + epPort := corev1.EndpointPort{Name: "default", Protocol: corev1.ProtocolTCP, Port: 42} + ports = append(ports, epPort) + } + newEndpointSubsets = append(newEndpointSubsets, corev1.EndpointSubset{ + Addresses: addresses, + Ports: ports, + }) + } + + if toHandleExternalName { + if externalName == "" { + logrus.Infof("Deleting dns record [%s] HostName, externalName empty", obj.Name) + if err := c.services.DeleteNamespaced(obj.Namespace, obj.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "Error deleting dns record [%s]", obj.Name) + } + } else if obj.Spec.Type == SvcTypeExternalName && + obj.Spec.ExternalName == externalName && + obj.Spec.ClusterIP == "" { + logrus.Infof("HostName dns record [%s] up to date", obj.Name) + } else { + svcAlias := obj.DeepCopy() + svcAlias.Spec.Type = SvcTypeExternalName + svcAlias.Spec.ExternalName = externalName + svcAlias.Spec.ClusterIP = "" + logrus.Infof("Updating HostName of dns record [%s] to %s", obj.Name, externalName) + if _, err := c.services.Update(svcAlias); err != nil && !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "Error updating dns record [%s]", obj.Name) + } + } + return nil + } + + dnsServiceUUIDToTargetEndpointUUIDs.Store(key, targetEndpointUUIDs) + + ep, err := c.endpointLister.Get(obj.Namespace, obj.Name) + if err != nil && !apierrors.IsNotFound(err) { + return errors.Wrapf(err, "Failed to fetch endpoints for DNSRecord service [%s] in namespace [%s]", obj.Name, obj.Namespace) + } + + if ep == nil { + controller := true + ownerRef := metav1.OwnerReference{ + Name: obj.Name, + APIVersion: "v1", + UID: obj.UID, + Kind: "Service", + Controller: &controller, + } + + ep := &corev1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: obj.Name, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + Namespace: obj.Namespace, + }, + Subsets: newEndpointSubsets, + } + logrus.Infof("Creating endpoints for targetDnsRecordIds service [%s]: %v", key, ep.Subsets) + if _, err := c.endpoints.Create(ep); err != nil { + return err + } + } else { + if reflect.DeepEqual(ep.Subsets, newEndpointSubsets) { + logrus.Debugf("Endpoints are up to date for DNSRecord service [%s]", obj.Name) + return nil + } + logrus.Infof("Updating endpoints for DNSRecord service [%s]. Old: [%v], new: [%v]", obj.Name, ep.Subsets, newEndpointSubsets) + toUpdate := ep.DeepCopy() + toUpdate.Subsets = newEndpointSubsets + _, err = c.endpoints.Update(toUpdate) + if err != nil { + return errors.Wrapf(err, "Failed to update endpoint for DNSRecord service [%s]", obj.Name) + } + } + + return nil +} + +func (c *EndpointController) reconcileServicesForEndpoint(key string, obj *corev1.Endpoints) (runtime.Object, error) { + var dnsRecordServicesToReconcile []string + dnsServiceUUIDToTargetEndpointUUIDs.Range(func(k, v interface{}) bool { + if _, ok := v.(map[string]bool)[key]; ok { + dnsRecordServicesToReconcile = append(dnsRecordServicesToReconcile, k.(string)) + } + return true + }) + + for _, dnsRecordServiceToReconcile := range dnsRecordServicesToReconcile { + splitted := strings.Split(dnsRecordServiceToReconcile, "/") + namespace := splitted[0] + serviceName := splitted[1] + c.serviceController.Enqueue(namespace, serviceName) + } + + return nil, nil +} + +func (c *Controller) queueUpdateForExtNameSvc(key string, delete bool) { + alias, ok := serviceUUIDToHostNameAlias.Load(key) + if ok && delete { + serviceUUIDToHostNameAlias.Delete(key) + } + if ok { + splitted := strings.Split(convert.ToString(alias), "/") + namespace := splitted[0] + aliasName := splitted[1] + c.serviceController.Enqueue(namespace, aliasName) + } +} + +func (c *Controller) checkLinkedSvc(namespace string, service string, original string) (bool, string, bool, error) { + svc, err := c.serviceLister.Get(namespace, service) + if err != nil { + if apierrors.IsNotFound(err) { + return false, "", false, nil + } + return false, "", false, err + } + if svc.Spec.Type == SvcTypeExternalName { + if svc.DeletionTimestamp != nil { + return true, "", true, nil + } + return true, svc.Spec.ExternalName, false, nil + } + return false, original, false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/endpoints.go new file mode 100644 index 0000000..37f9c4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/endpoints.go @@ -0,0 +1,354 @@ +package endpoints + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net" + "reflect" + "sort" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + workloadUtil "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ingresswrapper" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation" +) + +const ( + allEndpoints = "_all_endpoints_" + endpointsAnnotation = "field.cattle.io/publicEndpoints" +) + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + s := &ServicesController{ + services: workload.Core.Services(""), + workloadController: workloadUtil.NewWorkloadController(ctx, workload, nil), + nodesLister: workload.Core.Nodes("").Controller().Lister(), + clusterName: workload.ClusterName, + } + workload.Core.Services("").AddHandler(ctx, "servicesEndpointsController", s.sync) + + p := &PodsController{ + podLister: workload.Core.Pods("").Controller().Lister(), + workloadController: workloadUtil.NewWorkloadController(ctx, workload, nil), + } + workload.Core.Pods("").AddHandler(ctx, "hostPortEndpointsController", p.sync) + + w := &WorkloadEndpointsController{ + ingressLister: ingresswrapper.NewCompatLister(workload.Networking, workload.Extensions, workload.K8sClient), + serviceLister: workload.Core.Services("").Controller().Lister(), + podLister: workload.Core.Pods("").Controller().Lister(), + nodeLister: workload.Core.Nodes("").Controller().Lister(), + clusterName: workload.ClusterName, + } + w.WorkloadController = workloadUtil.NewWorkloadController(ctx, workload, w.UpdateEndpoints) + + i := &IngressEndpointsController{ + workloadController: workloadUtil.NewWorkloadController(ctx, workload, nil), + ingressInterface: ingresswrapper.NewCompatInterface(workload.Networking, workload.Extensions, workload.K8sClient), + } + if i.ingressInterface.ServerSupportsIngressV1 { + workload.Networking.Ingresses("").AddHandler(ctx, "ingressEndpointsController", ingresswrapper.CompatSyncV1(i.sync)) + } else { + workload.Extensions.Ingresses("").AddHandler(ctx, "ingressEndpointsController", ingresswrapper.CompatSyncV1Beta1(i.sync)) + } +} + +func areEqualEndpoints(one []v32.PublicEndpoint, two []v32.PublicEndpoint) bool { + oneMap := map[string]bool{} + twoMap := map[string]bool{} + for _, value := range one { + oneMap[publicEndpointToString(value)] = true + } + for _, value := range two { + twoMap[publicEndpointToString(value)] = true + } + return reflect.DeepEqual(oneMap, twoMap) +} + +func publicEndpointsToString(eps []v32.PublicEndpoint) (string, error) { + b, err := json.Marshal(eps) + if err != nil { + return "", err + } + return string(b), nil +} + +func getPublicEndpointsFromAnnotations(annotations map[string]string) []v32.PublicEndpoint { + var eps []v32.PublicEndpoint + if annotations == nil { + return eps + } + if val, ok := annotations[endpointsAnnotation]; ok { + err := json.Unmarshal([]byte(val), &eps) + if err != nil { + logrus.Errorf("Failed to read public endpoints from annotation %v", err) + return eps + } + } + return eps +} + +func convertServiceToPublicEndpoints(svc *corev1.Service, clusterName string, node *managementv3.Node, allNodesIP string) ([]v32.PublicEndpoint, error) { + var eps []v32.PublicEndpoint + if svc.DeletionTimestamp != nil { + return eps, nil + } + if !(svc.Spec.Type == "NodePort" || svc.Spec.Type == "LoadBalancer") { + return eps, nil + } + address := "" + nodeName := "" + if node != nil { + address = nodehelper.GetEndpointNodeIP(node) + nodeName = fmt.Sprintf("%s:%s", clusterName, node.Name) + } + + svcName := fmt.Sprintf("%s:%s", svc.Namespace, svc.Name) + if svc.Spec.Type == "NodePort" { + var addresses []string + if allNodesIP != "" { + addresses = append(addresses, allNodesIP) + } + for _, port := range svc.Spec.Ports { + if port.NodePort == 0 { + continue + } + p := v32.PublicEndpoint{ + NodeName: nodeName, + Port: port.NodePort, + Addresses: addresses, + Protocol: string(port.Protocol), + ServiceName: svcName, + AllNodes: true, + } + //for getting endpoints of specific node + if address != "" { + p.Addresses = append(p.Addresses, address) + } + eps = append(eps, p) + } + } else { + var addresses []string + for _, ingressEp := range svc.Status.LoadBalancer.Ingress { + address = ingressEp.Hostname + if address == "" { + address = ingressEp.IP + } + addresses = append(addresses, address) + } + if len(addresses) > 0 { + for _, port := range svc.Spec.Ports { + p := v32.PublicEndpoint{ + NodeName: "", + Addresses: addresses, + Port: port.Port, + Protocol: string(port.Protocol), + ServiceName: svcName, + AllNodes: false, + } + eps = append(eps, p) + } + } + } + + return eps, nil +} + +func convertHostPortToEndpoint(pod *corev1.Pod, clusterName string, node *v1.Node) ([]v32.PublicEndpoint, error) { + var eps []v32.PublicEndpoint + if pod.DeletionTimestamp != nil { + return eps, nil + } + if pod.Status.Phase != corev1.PodRunning { + return eps, nil + } + if node == nil { + return eps, nil + } + for _, c := range pod.Spec.Containers { + for _, p := range c.Ports { + if p.HostPort == 0 { + continue + } + var address string + if p.HostIP != "" { + address = p.HostIP + } else { + address = nodehelper.GetEndpointV1NodeIP(node) + } + p := v32.PublicEndpoint{ + NodeName: fmt.Sprintf("%s:%s", clusterName, node.Name), + Addresses: []string{address}, + Port: p.HostPort, + Protocol: string(p.Protocol), + PodName: fmt.Sprintf("%s:%s", pod.Namespace, pod.Name), + AllNodes: false, + } + eps = append(eps, p) + } + } + + return eps, nil +} + +func publicEndpointToString(p v32.PublicEndpoint) string { + sort.Strings(p.Addresses) + return fmt.Sprintf("%s_%v_%v_%s_%s_%s_%s_%s_%s", p.NodeName, p.Addresses, p.Port, p.Protocol, p.ServiceName, p.PodName, p.IngressName, p.Hostname, p.Path) +} + +func getNodeNameToMachine(nodeLister v1.NodeLister) (map[string]*v1.Node, error) { + nodes, err := nodeLister.List("", labels.NewSelector()) + if err != nil { + return nil, err + } + machineMap := map[string]*v1.Node{} + for _, node := range nodes { + machineMap[node.Name] = node + } + return machineMap, nil +} + +func isMachineReady(machine *managementv3.Node) bool { + for _, cond := range machine.Status.InternalNodeStatus.Conditions { + if cond.Type == corev1.NodeReady { + return cond.Status == corev1.ConditionTrue + } + } + return false +} + +func getAllNodesPublicEndpointIP(nodesLister v1.NodeLister, clusterName string) (string, error) { + var addresses []string + nodes, err := nodesLister.List(clusterName, labels.NewSelector()) + if err != nil { + return "", err + } + for _, node := range nodes { + if node.Labels["node-role.kubernetes.io/worker"] == "true" && nodehelper.IsNodeReady(node) { + nodePublicIP := getEndpointNodeAddress(node) + if nodePublicIP != "" { + addresses = append(addresses, nodePublicIP) + } + } + } + if len(addresses) == 0 { + return "", nil + } + + sort.Slice(addresses, func(i, j int) bool { + return strings.Compare(addresses[i], addresses[j]) < 0 + }) + return addresses[0], nil +} + +func convertIngressToServicePublicEndpointsMap(ingress ingresswrapper.Ingress, allNodes bool) (map[string][]v32.PublicEndpoint, error) { + epsMap := map[string][]v32.PublicEndpoint{} + obj, err := ingresswrapper.ToCompatIngress(ingress) + if err != nil { + return epsMap, err + } + if len(obj.Status.LoadBalancer.Ingress) == 0 { + return epsMap, nil + } + var addresses []string + var ips []net.IP + for _, address := range obj.Status.LoadBalancer.Ingress { + addresses = append(addresses, address.IP) + ips = append(ips, net.ParseIP(address.IP)) + } + if allNodes { + sort.Slice(addresses, func(i, j int) bool { + return bytes.Compare(ips[i], ips[j]) < 0 + }) + addresses = []string{ips[0].String()} + } + + if len(addresses) == 0 { + return epsMap, nil + } + + tlsHosts := sets.NewString() + for _, t := range obj.Spec.TLS { + tlsHosts.Insert(t.Hosts...) + } + + ports := map[int32]string{80: "HTTP", 443: "HTTPS"} + ipDomain := settings.IngressIPDomain.Get() + for _, rule := range obj.Spec.Rules { + //If the hostname is auto-generated, the public endpoint should be shown only when the + //hostname is done auto-generation + if rule.Host == ipDomain { + continue + } + if rule.HTTP == nil { + continue + } + for _, path := range rule.HTTP.Paths { + for port, proto := range ports { + if port == 80 { + if tlsHosts.Has(rule.Host) { + continue + } + } else { + if !tlsHosts.Has(rule.Host) && rule.Host != "" { + continue + } + } + if path.Backend.Service == nil { + continue + } + p := v32.PublicEndpoint{ + Hostname: rule.Host, + Path: path.Path, + ServiceName: fmt.Sprintf("%s:%s", obj.Namespace, path.Backend.Service.Name), + Addresses: addresses, + Port: port, + Protocol: proto, + AllNodes: allNodes, + IngressName: fmt.Sprintf("%s:%s", obj.Namespace, obj.Name), + } + epsMap[path.Backend.Service.Name] = append(epsMap[path.Backend.Service.Name], p) + } + } + } + return epsMap, nil +} + +func convertIngressToPublicEndpoints(obj ingresswrapper.Ingress, isRKE bool) ([]v32.PublicEndpoint, error) { + var eps []v32.PublicEndpoint + epsMap, err := convertIngressToServicePublicEndpointsMap(obj, isRKE) + if err != nil { + return eps, err + } + for _, v := range epsMap { + eps = append(eps, v...) + } + return eps, nil +} + +func getEndpointNodeAddress(machine *v1.Node) string { + endpointAddress := nodehelper.GetEndpointV1NodeIP(machine) + if endpointAddress == "" { + return "" + } + publicIP := net.ParseIP(endpointAddress) + if publicIP != nil && publicIP.String() != "" { + return publicIP.String() + } + if errs := validation.IsDNS1123Label(endpointAddress); errs != nil { + return "" + } + return endpointAddress +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/ingress_endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/ingress_endpoints.go new file mode 100644 index 0000000..a5988b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/ingress_endpoints.go @@ -0,0 +1,73 @@ +package endpoints + +import ( + "reflect" + "strings" + + workloadutil "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +type IngressEndpointsController struct { + workloadController workloadutil.CommonController + ingressInterface ingresswrapper.CompatInterface +} + +func (c *IngressEndpointsController) sync(key string, obj ingresswrapper.Ingress) (runtime.Object, error) { + namespace := "" + if obj != nil && !reflect.ValueOf(obj).IsNil() { + namespace = obj.GetNamespace() + } else { + split := strings.Split(key, "/") + if len(split) == 2 { + namespace = split[0] + } + } + c.workloadController.EnqueueAllWorkloads(namespace) + + if obj == nil || reflect.ValueOf(obj).IsNil() || obj.GetDeletionTimestamp() != nil { + return nil, nil + } + + if _, err := c.reconcileEndpointsForIngress(obj); err != nil { + return nil, err + } + return nil, nil +} + +func (c *IngressEndpointsController) reconcileEndpointsForIngress(obj ingresswrapper.Ingress) (bool, error) { + fromObj, err := convertIngressToPublicEndpoints(obj, settings.IsRKE.Get() == "true") + if err != nil { + return false, err + } + fromAnnotation := getPublicEndpointsFromAnnotations(obj.GetAnnotations()) + + if areEqualEndpoints(fromAnnotation, fromObj) { + return false, nil + } + + epsToUpdate, err := publicEndpointsToString(fromObj) + if err != nil { + return false, err + } + + logrus.Infof("Updating ingress [%s:%s] with public endpoints [%v]", obj.GetNamespace(), obj.GetName(), epsToUpdate) + + toUpdate, err := ingresswrapper.ToCompatIngress(obj.DeepCopyObject()) + if err != nil { + return false, err + } + + annotations := toUpdate.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + annotations[endpointsAnnotation] = epsToUpdate + toUpdate.SetAnnotations(annotations) + + _, err = c.ingressInterface.Update(toUpdate) + return false, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/pod_endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/pod_endpoints.go new file mode 100644 index 0000000..50b30ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/pod_endpoints.go @@ -0,0 +1,91 @@ +package endpoints + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + + workloadutil "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// This controller is responsible for monitoring pods having host port set +// and sending an update event to the corresponding workload +// so the endpoints can be reconciled for those + +type PodsController struct { + podLister v1.PodLister + workloadController workloadutil.CommonController +} + +func (c *PodsController) sync(key string, obj *corev1.Pod) (runtime.Object, error) { + if obj == nil && !strings.HasSuffix(key, allEndpoints) { + return nil, nil + } + + var pods []*corev1.Pod + var err error + if strings.HasSuffix(key, allEndpoints) { + namespace := "" + if !strings.EqualFold(key, allEndpoints) { + namespace = strings.TrimSuffix(key, fmt.Sprintf("/%s", allEndpoints)) + } + pods, err = c.podLister.List(namespace, labels.NewSelector()) + if err != nil { + return nil, err + } + } else { + pods = append(pods, obj) + } + + workloadsToUpdate := map[string]*workloadutil.Workload{} + if err != nil { + return nil, err + } + for _, pod := range pods { + if pod.Spec.NodeName != "" && podHasHostPort(pod) { + workloads, err := c.workloadController.GetWorkloadsMatchingLabels(pod.Namespace, pod.Labels) + if err != nil { + return nil, err + } + for _, w := range workloads { + + existingPublicEps := getPublicEndpointsFromAnnotations(w.Annotations) + found := false + for _, ep := range existingPublicEps { + if ep.PodName == pod.Name { + found = true + break + } + } + // push changes only when + // a) the workload doesn't have the pod's endpoint for active pod + // b) pod is removed + if found == (pod.DeletionTimestamp != nil) { + workloadsToUpdate[key] = w + } + } + } + } + + // push changes to workload + for _, w := range workloadsToUpdate { + c.workloadController.EnqueueWorkload(w) + } + + return nil, nil +} + +func podHasHostPort(obj *corev1.Pod) bool { + for _, c := range obj.Spec.Containers { + for _, p := range c.Ports { + if p.HostPort != 0 { + return true + } + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/service_endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/service_endpoints.go new file mode 100644 index 0000000..a4f5054 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/service_endpoints.go @@ -0,0 +1,82 @@ +package endpoints + +import ( + workloadutil "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// This controller is responsible for monitoring services +// and setting public endpoints on them (if they are of type NodePort or LoadBalancer) + +type ServicesController struct { + services v1.ServiceInterface + workloadController workloadutil.CommonController + nodesLister v1.NodeLister + clusterName string +} + +func (s *ServicesController) sync(key string, obj *corev1.Service) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + namespace := "" + if obj != nil { + namespace = obj.Namespace + } + // push changes to all the workloads, so service + // endpoints can be removed from there + //since service is removed, there is no way to narrow down the pod/workload search + s.workloadController.EnqueueAllWorkloads(namespace) + return nil, nil + } + _, err := s.reconcileEndpointsForService(obj) + if err != nil { + return nil, err + } + + return nil, nil +} + +func (s *ServicesController) reconcileEndpointsForService(svc *corev1.Service) (bool, error) { + // 1. update service with endpoints + allNodesIP, err := getAllNodesPublicEndpointIP(s.nodesLister, s.clusterName) + if err != nil { + return false, err + } + newPublicEps, err := convertServiceToPublicEndpoints(svc, "", nil, allNodesIP) + if err != nil { + return false, err + } + + existingPublicEps := getPublicEndpointsFromAnnotations(svc.Annotations) + if areEqualEndpoints(existingPublicEps, newPublicEps) { + return false, nil + } + toUpdate := svc.DeepCopy() + epsToUpdate, err := publicEndpointsToString(newPublicEps) + if err != nil { + return false, err + } + + logrus.Infof("Updating service [%s] with public endpoints [%v]", svc.Name, epsToUpdate) + if toUpdate.Annotations == nil { + toUpdate.Annotations = map[string]string{} + } + toUpdate.Annotations[endpointsAnnotation] = epsToUpdate + _, err = s.services.Update(toUpdate) + if err != nil { + return false, err + } + + // 2. Push changes to workload behind the service + workloads, err := s.workloadController.GetWorkloadsMatchingSelector(svc.Namespace, svc.Spec.Selector) + if err != nil { + return false, err + } + for _, w := range workloads { + s.workloadController.EnqueueWorkload(w) + } + + return true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/workload_endpoints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/workload_endpoints.go new file mode 100644 index 0000000..b972a0d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/endpoints/workload_endpoints.go @@ -0,0 +1,184 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + + workloadutil "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// This controller is responsible for monitoring workloads +// and setting public endpoints on them based on HostPort pods +// and NodePort services backing up the workload + +type WorkloadEndpointsController struct { + ingressLister ingresswrapper.CompatLister + serviceLister v1.ServiceLister + podLister v1.PodLister + WorkloadController workloadutil.CommonController + nodeLister v1.NodeLister + clusterName string + serverSupportsIngressV1 bool +} + +func (c *WorkloadEndpointsController) UpdateEndpoints(key string, obj *workloadutil.Workload) error { + if obj == nil && key != allEndpoints { + return nil + } + + var workloads []*workloadutil.Workload + var services []*corev1.Service + var ingresses []*ingresswrapper.CompatIngress + var err error + if strings.HasSuffix(key, allEndpoints) { + namespace := "" + if !strings.EqualFold(key, allEndpoints) { + namespace = strings.TrimSuffix(key, fmt.Sprintf("/%s", allEndpoints)) + } + workloads, err = c.WorkloadController.GetAllWorkloads(namespace) + if err != nil { + return err + } + services, err = c.serviceLister.List(namespace, labels.NewSelector()) + if err != nil { + return err + } + ingresses, err = c.ingressLister.List(namespace, labels.NewSelector()) + + } else { + // do not update endpoints for job, cronJob and for workload owned by controller (ReplicaSet) + if strings.EqualFold(obj.Kind, "job") || strings.EqualFold(obj.Kind, "cronJob") { + return nil + } + for _, o := range obj.OwnerReferences { + if o.Controller != nil && *o.Controller { + return nil + } + } + ingresses, err = c.ingressLister.List(obj.Namespace, labels.NewSelector()) + if err != nil { + return err + } + services, err = c.serviceLister.List(obj.Namespace, labels.NewSelector()) + workloads = append(workloads, obj) + } + if err != nil { + return err + } + + nodeNameToMachine, err := getNodeNameToMachine(c.nodeLister) + if err != nil { + return err + } + allNodesIP, err := getAllNodesPublicEndpointIP(c.nodeLister, c.clusterName) + if err != nil { + return err + } + // get ingress endpoint group by service + serviceToIngressEndpoints := make(map[string][]v32.PublicEndpoint) + for _, ingress := range ingresses { + epsMap, err := convertIngressToServicePublicEndpointsMap(ingress, settings.IsRKE.Get() == "true") + if err != nil { + return err + } + for k, v := range epsMap { + serviceToIngressEndpoints[k] = append(serviceToIngressEndpoints[k], v...) + } + } + + for _, w := range workloads { + // 1. Get endpoints from services + var newPublicEps []v32.PublicEndpoint + for _, svc := range services { + set := labels.Set{} + for key, val := range svc.Spec.Selector { + set[key] = val + } + selector := labels.SelectorFromSet(set) + found := false + if selector.Matches(labels.Set(w.SelectorLabels)) && !selector.Empty() { + // direct selector match + found = true + } else { + // match based off the workload + value, ok := svc.Annotations[workloadutil.WorkloadAnnotation] + if !ok || value == "" { + continue + } + var workloadIDs []string + err := json.Unmarshal([]byte(value), &workloadIDs) + if err != nil { + logrus.WithError(err).Errorf("Unmarshalling %s workloadIDs of %s Error", value, svc.Name) + continue + } + for _, workloadID := range workloadIDs { + splitted := strings.Split(workloadID, ":") + if len(splitted) != 3 { + continue + } + namespace := splitted[1] + name := splitted[2] + if w.Name == name && w.Namespace == namespace { + found = true + break + } + } + } + if found { + eps, err := convertServiceToPublicEndpoints(svc, "", nil, allNodesIP) + if err != nil { + return err + } + newPublicEps = append(newPublicEps, eps...) + if ingressEndpoints, ok := serviceToIngressEndpoints[svc.Name]; ok { + newPublicEps = append(newPublicEps, ingressEndpoints...) + } + } + } + + // 2. Get endpoints from HostPort pods matching the selector + set := labels.Set{} + for key, val := range w.SelectorLabels { + set[key] = val + } + pods, err := c.podLister.List(w.Namespace, labels.SelectorFromSet(set)) + if err != nil { + return err + } + for _, pod := range pods { + eps, err := convertHostPortToEndpoint(pod, c.clusterName, nodeNameToMachine[pod.Spec.NodeName]) + if err != nil { + return err + } + newPublicEps = append(newPublicEps, eps...) + } + + existingPublicEps := getPublicEndpointsFromAnnotations(w.Annotations) + if areEqualEndpoints(existingPublicEps, newPublicEps) { + return nil + } + epsToUpdate, err := publicEndpointsToString(newPublicEps) + if err != nil { + return err + } + + logrus.Infof("Updating workload [%s] with public endpoints [%v]", key, epsToUpdate) + + annotations := map[string]string{ + endpointsAnnotation: epsToUpdate, + } + if err = c.WorkloadController.UpdateWorkload(w, annotations); err != nil { + return err + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/externalservice/external_ip_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/externalservice/external_ip_service.go new file mode 100644 index 0000000..c765a5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/externalservice/external_ip_service.go @@ -0,0 +1,137 @@ +package externalservice + +import ( + "context" + + "reflect" + + "encoding/json" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// this controller monitors services with "field.cattle.io/ipAddresses" annotation +// and creates an endpoint for it + +const ( + ExternalIPsAnnotation = "field.cattle.io/ipAddresses" +) + +type Controller struct { + endpointsLister v1.EndpointsLister + endpoints v1.EndpointsInterface +} + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + c := &Controller{ + endpoints: workload.Core.Endpoints(""), + endpointsLister: workload.Core.Endpoints("").Controller().Lister(), + } + workload.Core.Services("").AddHandler(ctx, "externalIpServiceController", c.sync) +} + +func (c *Controller) sync(key string, obj *corev1.Service) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + if obj.Annotations == nil { + return nil, nil + } + + var newSubsets []corev1.EndpointSubset + if val, ok := obj.Annotations[ExternalIPsAnnotation]; !ok || val == "" { + return nil, nil + } + var ipsStr []string + err := json.Unmarshal([]byte(obj.Annotations[ExternalIPsAnnotation]), &ipsStr) + if err != nil { + logrus.Debugf("Failed to unmarshal ipAddresses, error: %v", err) + return nil, nil + } + if ipsStr == nil { + return nil, nil + } + + var addresses []corev1.EndpointAddress + for _, ipStr := range ipsStr { + addresses = append(addresses, corev1.EndpointAddress{IP: ipStr}) + } + var ports []corev1.EndpointPort + if len(addresses) > 0 { + for _, p := range obj.Spec.Ports { + epPort := corev1.EndpointPort{Name: p.Name, Protocol: p.Protocol, Port: p.TargetPort.IntVal} + ports = append(ports, epPort) + } + if len(ports) == 0 { + epPort := corev1.EndpointPort{Name: "default", Protocol: corev1.ProtocolTCP, Port: 42} + ports = append(ports, epPort) + } + newSubsets = append(newSubsets, corev1.EndpointSubset{ + Addresses: addresses, + Ports: ports, + }) + } + + existing, err := c.endpointsLister.Get(obj.Namespace, obj.Name) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + + if existing == nil { + controller := true + ownerRef := metav1.OwnerReference{ + Name: obj.Name, + APIVersion: "v1", + UID: obj.UID, + Kind: "Service", + Controller: &controller, + } + + ep := &corev1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: obj.Name, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + Namespace: obj.Namespace, + }, + Subsets: newSubsets, + } + logrus.Infof("Creating endpoints for external ip service [%s]: %v", key, ep.Subsets) + if _, err := c.endpoints.Create(ep); err != nil { + return nil, err + } + } else if subsetsChanged(newSubsets, existing.Subsets) { + toUpdate := existing.DeepCopy() + toUpdate.Subsets = newSubsets + logrus.Infof("Updating endpoints for external ip service [%s]: %v", key, toUpdate.Subsets) + if _, err := c.endpoints.Update(toUpdate); err != nil { + return nil, err + } + } + return nil, nil +} + +func subsetsChanged(new []corev1.EndpointSubset, old []corev1.EndpointSubset) bool { + if len(new) != len(old) { + return true + } + for _, newEP := range new { + found := false + for _, oldEP := range old { + if reflect.DeepEqual(newEP, oldEP) { + found = true + break + } + } + if !found { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress.go new file mode 100644 index 0000000..5c13f68 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress.go @@ -0,0 +1,209 @@ +package ingress + +import ( + "context" + "reflect" + + "k8s.io/apimachinery/pkg/runtime" + + "github.com/rancher/norman/types/convert" + util "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// This controller is responsible for monitoring ingress and +// creating services for them if the service is missing +// Creation would only happen if the service reference was put by Rancher API based on +// ingress.backend.workloadId. This information is stored in state field in the annotation + +type Controller struct { + serviceLister v1.ServiceLister + services v1.ServiceInterface + nodeLister v1.NodeLister +} + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + c := &Controller{ + services: workload.Core.Services(""), + serviceLister: workload.Core.Services("").Controller().Lister(), + nodeLister: workload.Core.Nodes("").Controller().Lister(), + } + if ingresswrapper.ServerSupportsIngressV1(workload.K8sClient) { + workload.Networking.Ingresses("").AddHandler(ctx, "ingressWorkloadController", ingresswrapper.CompatSyncV1(c.sync)) + } else { + workload.Extensions.Ingresses("").AddHandler(ctx, "ingressWorkloadController", ingresswrapper.CompatSyncV1Beta1(c.sync)) + } +} + +func (c *Controller) sync(key string, ingress ingresswrapper.Ingress) (runtime.Object, error) { + if ingress == nil || reflect.ValueOf(ingress).IsNil() || ingress.GetDeletionTimestamp() != nil { + return nil, nil + } + + obj, err := ingresswrapper.ToCompatIngress(ingress) + if err != nil { + return obj, err + } + state := GetIngressState(obj) + if state == nil { + return nil, nil + } + + expectedServices, err := generateExpectedServices(state, obj) + if err != nil { + return nil, err + } + + existingServices, err := getIngressRelatedServices(c.serviceLister, obj, expectedServices) + if err != nil { + return nil, err + } + + needNodePort := c.needNodePort() + + // 1. clean up first, delete or update the service is existing + for _, service := range existingServices { + shouldDelete, toUpdate, err := updateOrDelete(obj, service, expectedServices, needNodePort) + if err != nil { + return nil, err + } + if shouldDelete { + if err := c.services.DeleteNamespaced(obj.GetNamespace(), service.Name, &metav1.DeleteOptions{}); err != nil { + return nil, err + } + continue + } + if toUpdate != nil { + if _, err := c.services.Update(toUpdate); err != nil { + return nil, err + } + } + // don't create the services which already exist + delete(expectedServices, service.Name) + } + + // 2. create the new services + for _, ingressService := range expectedServices { + var toCreate *corev1.Service + var err error + if needNodePort { + toCreate, err = ingressService.generateNewService(obj, corev1.ServiceTypeNodePort) + } else { + toCreate, err = ingressService.generateNewService(obj, corev1.ServiceTypeClusterIP) + } + if err != nil { + return nil, err + } + logrus.Infof("Creating %s service %s for ingress %s, port %d", ingressService.serviceName, toCreate.Spec.Type, key, ingressService.servicePort) + if _, err := c.services.Create(toCreate); err != nil { + return nil, err + } + } + + return nil, nil +} + +func generateExpectedServices(state map[string]string, obj *ingresswrapper.CompatIngress) (map[string]ingressService, error) { + var err error + rtn := map[string]ingressService{} + for _, r := range obj.Spec.Rules { + host := r.Host + if r.HTTP == nil { + continue + } + for _, b := range r.HTTP.Paths { + key := GetStateKey(obj.GetName(), obj.GetNamespace(), host, b.Path, convert.ToString(b.Backend.Service.Port.Number)) + if workloadIDs, ok := state[key]; ok { + rtn[b.Backend.Service.Name], err = generateIngressService(b.Backend.Service.Name, b.Backend.Service.Port.Number, workloadIDs) + if err != nil { + return nil, err + } + } + } + } + if obj.Spec.DefaultBackend != nil { + key := GetStateKey(obj.GetName(), obj.GetNamespace(), "", "/", convert.ToString(obj.Spec.DefaultBackend.Service.Port.Number)) + if workloadIDs, ok := state[key]; ok { + rtn[obj.Spec.DefaultBackend.Service.Name], err = generateIngressService(obj.Spec.DefaultBackend.Service.Name, obj.Spec.DefaultBackend.Service.Port.Number, workloadIDs) + if err != nil { + return nil, err + } + } + } + return rtn, nil +} + +func getIngressRelatedServices(serviceLister v1.ServiceLister, obj *ingresswrapper.CompatIngress, expectedServices map[string]ingressService) (map[string]*corev1.Service, error) { + rtn := map[string]*corev1.Service{} + services, err := serviceLister.List(obj.GetNamespace(), labels.NewSelector()) + if err != nil { + return nil, err + } + for _, service := range services { + //mark the service which related to ingress + if _, ok := expectedServices[service.Name]; ok { + rtn[service.Name] = service + continue + } + //mark the service which own by ingress but not related to ingress + ok, err := IsServiceOwnedByIngress(obj, service) + if err != nil { + return nil, err + } + if ok { + rtn[service.Name] = service + } + } + return rtn, nil +} + +func updateOrDelete(obj *ingresswrapper.CompatIngress, service *corev1.Service, expectedServices map[string]ingressService, isNeedNodePort bool) (bool, *corev1.Service, error) { + shouldDelete := false + var toUpdate *corev1.Service + serviceIsOwnedByIngress, err := IsServiceOwnedByIngress(obj, service) + if err != nil { + return false, nil, err + } + s, ok := expectedServices[service.Name] + if ok { + if service.Annotations == nil { + service.Annotations = map[string]string{} + } + // handling issue https://github.com/rancher/rancher/issues/13717. + // if node port is using by non-GKE for ingress service, we should replace them. + if service.Spec.Type == corev1.ServiceTypeNodePort && !isNeedNodePort && serviceIsOwnedByIngress { + shouldDelete = true + } else { + if service.Annotations[util.WorkloadAnnotation] != s.workloadIDs && s.workloadIDs != "" { + toUpdate = service.DeepCopy() + toUpdate.Annotations[util.WorkloadAnnotation] = s.workloadIDs + } + } + } else { + //delete those service owned by ingress + if serviceIsOwnedByIngress { + shouldDelete = true + } + } + return shouldDelete, toUpdate, nil +} + +func (c *Controller) needNodePort() bool { + nodes, err := c.nodeLister.List("", labels.NewSelector()) + if err != nil { + return false + } + + for _, node := range nodes { + if label, ok := node.Labels["cloud.google.com/gke-nodepool"]; ok && label != "" { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress_common.go new file mode 100644 index 0000000..2963854 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingress/ingress_common.go @@ -0,0 +1,106 @@ +package ingress + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strings" + + "github.com/rancher/norman/types/convert" + util "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + ingressStateAnnotation = "field.cattle.io/ingressState" +) + +func GetStateKey(name, namespace, host string, path string, port string) string { + ipDomain := settings.IngressIPDomain.Get() + if ipDomain != "" && strings.HasSuffix(host, ipDomain) { + host = ipDomain + } + key := fmt.Sprintf("%s/%s/%s/%s/%s", name, namespace, host, path, port) + return base64.URLEncoding.EncodeToString([]byte(key)) +} + +func GetIngressState(obj ingresswrapper.Ingress) map[string]string { + annotations := obj.GetAnnotations() + if annotations == nil { + return nil + } + if v, ok := annotations[ingressStateAnnotation]; ok { + state := make(map[string]string) + json.Unmarshal([]byte(convert.ToString(v)), &state) + return state + } + return nil +} + +type ingressService struct { + serviceName string + servicePort int32 + workloadIDs string +} + +func generateIngressService(name string, port int32, workloadIDs string) (ingressService, error) { + rtn := ingressService{ + serviceName: name, + servicePort: port, + } + if workloadIDs != "" { + b, err := json.Marshal(strings.Split(workloadIDs, "/")) + if err != nil { + logrus.WithError(err).Warnf("marshal workload ids %s string error", workloadIDs) + return rtn, err + } + rtn.workloadIDs = string(b) + } + return rtn, nil +} + +func (i *ingressService) generateNewService(obj *ingresswrapper.CompatIngress, serviceType corev1.ServiceType) (*corev1.Service, error) { + controller := true + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: i.serviceName, + OwnerReferences: []metav1.OwnerReference{ + { + Name: obj.Name, + APIVersion: obj.APIVersion, + UID: obj.UID, + Kind: obj.Kind, + Controller: &controller, + }, + }, + Namespace: obj.Namespace, + Annotations: map[string]string{ + util.WorkloadAnnotation: i.workloadIDs, + }, + }, + Spec: corev1.ServiceSpec{ + Type: serviceType, + Ports: []corev1.ServicePort{ + { + Port: i.servicePort, + TargetPort: intstr.FromInt(int(i.servicePort)), + Protocol: "TCP", + }, + }, + }, + }, nil +} + +func IsServiceOwnedByIngress(obj *ingresswrapper.CompatIngress, service *corev1.Service) (bool, error) { + for i, owners := 0, service.GetOwnerReferences(); owners != nil && i < len(owners); i++ { + if owners[i].UID == obj.UID && owners[i].Kind == obj.Kind { + return true, nil + } + } + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen.go new file mode 100644 index 0000000..68738c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen.go @@ -0,0 +1,86 @@ +package ingresshostgen + +import ( + "context" + "fmt" + "reflect" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" +) + +type IngressHostGen struct { + ingress ingresswrapper.CompatInterface +} + +func Register(ctx context.Context, userOnlyContext *config.UserOnlyContext) { + c := &IngressHostGen{ + ingress: ingresswrapper.NewCompatInterface(userOnlyContext.Networking, userOnlyContext.Extensions, userOnlyContext.K8sClient), + } + if c.ingress.ServerSupportsIngressV1 { + userOnlyContext.Networking.Ingresses("").AddHandler(ctx, "ingress-host-gen", ingresswrapper.CompatSyncV1(c.sync)) + } else { + userOnlyContext.Extensions.Ingresses("").AddHandler(ctx, "ingress-host-gen", ingresswrapper.CompatSyncV1Beta1(c.sync)) + } +} + +func isGeneratedDomain(obj ingresswrapper.Ingress, host, domain string) bool { + parts := strings.Split(host, ".") + return strings.HasSuffix(host, "."+domain) && len(parts) == 8 && parts[1] == obj.GetNamespace() +} + +func (i *IngressHostGen) sync(key string, ingress ingresswrapper.Ingress) (runtime.Object, error) { + if ingress == nil || reflect.ValueOf(ingress).IsNil() || ingress.GetDeletionTimestamp() != nil { + return nil, nil + } + + obj, err := ingresswrapper.ToCompatIngress(ingress) + if err != nil { + return obj, err + } + + ipDomain := settings.IngressIPDomain.Get() + if ipDomain == "" { + return nil, nil + } + + var xipHost string + for _, status := range obj.Status.LoadBalancer.Ingress { + if status.IP != "" { + xipHost = fmt.Sprintf("%s.%s.%s.%s", obj.GetName(), obj.GetNamespace(), status.IP, ipDomain) + break + } + } + + if xipHost == "" { + return nil, nil + } + + changed := false + for _, rule := range obj.Spec.Rules { + if (isGeneratedDomain(obj, rule.Host, ipDomain) || rule.Host == ipDomain) && rule.Host != xipHost { + changed = true + break + } + } + + if !changed { + return nil, nil + } + + obj, err = ingresswrapper.ToCompatIngress(obj.DeepCopy()) + if err != nil { + return obj, err + } + for i, rule := range obj.Spec.Rules { + if strings.HasSuffix(rule.Host, ipDomain) { + obj.Spec.Rules[i].Host = xipHost + } + } + + return i.ingress.Update(obj) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen_test.go new file mode 100644 index 0000000..6b551a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/ingresshostgen/ingresshostgen_test.go @@ -0,0 +1,227 @@ +package ingresshostgen + +import ( + "testing" + + rnetworkingv1 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + rnetworkingv1fakes "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1/fakes" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/require" + knetworkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/kubernetes/fake" +) + +type NetworkingInterface struct { + *rnetworkingv1fakes.IngressesGetterMock + *rnetworkingv1fakes.NetworkPoliciesGetterMock +} + +var ( + originalIngressIPDomain = settings.IngressIPDomain.Get() +) + +type cleanupFunc func() + +func Test_Sync(t *testing.T) { + clientset := fake.NewSimpleClientset() + clientset.Discovery().(*fakediscovery.FakeDiscovery).Resources = []*metav1.APIResourceList{ + { + GroupVersion: "networking.k8s.io/v1", + APIResources: []metav1.APIResource{ + { + Kind: "Ingress", + }, + }, + }, + } + + mockedIngressesGetter := &rnetworkingv1fakes.IngressesGetterMock{ + IngressesFunc: func(namespace string) rnetworkingv1.IngressInterface { + return &rnetworkingv1fakes.IngressInterfaceMock{ + UpdateFunc: func(obj *rnetworkingv1.Ingress) (*rnetworkingv1.Ingress, error) { + return obj, nil + }, + } + }, + } + ingressCompat := ingresswrapper.NewCompatInterface(&NetworkingInterface{ + IngressesGetterMock: mockedIngressesGetter, + NetworkPoliciesGetterMock: &rnetworkingv1fakes.NetworkPoliciesGetterMock{}, + }, nil, clientset) + gen := &IngressHostGen{ + ingress: ingressCompat, + } + tests := []struct { + desc string + name string + namespace string + setup func() cleanupFunc + rules []knetworkingv1.IngressRule + statusIngress []knetworkingv1.IngressLoadBalancerIngress + // If nil, then we expect sync to return nil, nil + expectedRules []knetworkingv1.IngressRule + }{ + { + desc: "single ip and host matching", + name: "foo", + namespace: "bar", + rules: []knetworkingv1.IngressRule{ + { + Host: "sslip.io", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + }, + expectedRules: []knetworkingv1.IngressRule{ + { + Host: "foo.bar.192.0.2.1.sslip.io", + }, + }, + }, + { + desc: "not matching ingress IP domain", + name: "foo", + namespace: "bar", + rules: []knetworkingv1.IngressRule{ + { + Host: "example.com", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + }, + }, + { + desc: "already generated", + name: "foo", + namespace: "bar", + rules: []knetworkingv1.IngressRule{ + { + Host: "foo.bar.192.0.2.1.sslip.io", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + }, + }, + { + desc: "different ingress IP domain matching host", + name: "foo", + namespace: "bar", + setup: func() cleanupFunc { + settings.IngressIPDomain.Set("example.com") + return func() { + settings.IngressIPDomain.Set(originalIngressIPDomain) + } + }, + rules: []knetworkingv1.IngressRule{ + { + Host: "example.com", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + }, + expectedRules: []knetworkingv1.IngressRule{ + { + Host: "foo.bar.192.0.2.1.example.com", + }, + }, + }, + { + desc: "different ingress IP domain not matching host", + name: "foo", + namespace: "bar", + setup: func() cleanupFunc { + settings.IngressIPDomain.Set("example.com") + return func() { + settings.IngressIPDomain.Set(originalIngressIPDomain) + } + }, + rules: []knetworkingv1.IngressRule{ + { + Host: "sslip.io", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + }, + }, + { + desc: "many hosts and IPs matching IP domain", + name: "foo", + namespace: "bar", + rules: []knetworkingv1.IngressRule{ + { + Host: "example.com", + }, + { + Host: "sslip.io", + }, + }, + statusIngress: []knetworkingv1.IngressLoadBalancerIngress{ + { + IP: "192.0.2.1", + }, + { + IP: "192.0.2.2", + }, + }, + expectedRules: []knetworkingv1.IngressRule{ + { + Host: "example.com", + }, + { + Host: "foo.bar.192.0.2.1.sslip.io", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + if tt.setup != nil { + cleanup := tt.setup() + defer cleanup() + } + + obj := &knetworkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: tt.name, + Namespace: tt.namespace, + }, + Spec: knetworkingv1.IngressSpec{ + Rules: tt.rules, + }, + Status: knetworkingv1.IngressStatus{ + LoadBalancer: knetworkingv1.IngressLoadBalancerStatus{ + Ingress: tt.statusIngress, + }, + }, + } + updatedObj, err := gen.sync("", obj) + require.NoError(t, err, "unexpected error") + + if updatedObj == nil { + require.Nil(t, tt.expectedRules) + return + } + + updatedIngress := updatedObj.(*knetworkingv1.Ingress) + require.Equal(t, tt.expectedRules, updatedIngress.Spec.Rules) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nslabels/labels.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nslabels/labels.go new file mode 100644 index 0000000..7dd7e22 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nslabels/labels.go @@ -0,0 +1,117 @@ +package nslabels + +import ( + "context" + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + + typescorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + ProjectIDFieldLabel = "field.cattle.io/projectId" + ProjectScopedSecretAnnotation = "secret.user.cattle.io/secret" +) + +type namespaceHandler struct { + secrets v1.SecretInterface + nsClient typescorev1.NamespaceInterface +} + +func Register(ctx context.Context, cluster *config.UserOnlyContext) { + logrus.Infof("Registering namespaceHandler for adding labels ") + nsh := &namespaceHandler{ + secrets: cluster.Core.Secrets(""), + nsClient: cluster.Core.Namespaces(""), + } + cluster.Core.Namespaces("").AddHandler(ctx, "namespaceHandler", nsh.Sync) +} + +func (nsh *namespaceHandler) Sync(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil { + return nil, nil + } + logrus.Debugf("namespaceHandler: Sync: key=%v, ns=%+v", key, *ns) + + field, ok := ns.Annotations[ProjectIDFieldLabel] + if !ok { + return nil, nil + } + + projectID := "" + clusterID := "" + if field != "" { + splits := strings.Split(field, ":") + if len(splits) != 2 { + return nil, nil + } + projectID = splits[1] + clusterID = splits[0] + } + + logrus.Debugf("namespaceHandler: Sync: projectID=%v", projectID) + + if err := nsh.addProjectIDLabelToNamespace(ns, projectID, clusterID); err != nil { + logrus.Errorf("namespaceHandler: Sync: error adding project id label to namespace err=%v", err) + return nil, nil + } + + return nil, nil +} + +func (nsh *namespaceHandler) addProjectIDLabelToNamespace(ns *corev1.Namespace, projectID string, clusterID string) error { + if ns == nil { + return fmt.Errorf("cannot add label to nil namespace") + } + if ns.Labels[ProjectIDFieldLabel] != projectID { + if err := nsh.updateProjectIDLabelForSecrets(projectID, ns.Name, clusterID); err != nil { + logrus.Trace(err) + } + logrus.Infof("namespaceHandler: addProjectIDLabelToNamespace: adding label %v=%v to namespace=%v", ProjectIDFieldLabel, projectID, ns.Name) + nscopy := ns.DeepCopy() + if nscopy.Labels == nil { + nscopy.Labels = map[string]string{} + } + nscopy.Labels[ProjectIDFieldLabel] = projectID + if _, err := nsh.nsClient.Update(nscopy); err != nil { + return err + } + } + + return nil +} + +func (nsh *namespaceHandler) updateProjectIDLabelForSecrets(projectID string, namespace string, clusterID string) error { + secrets, err := nsh.secrets.List(metav1.ListOptions{FieldSelector: fmt.Sprintf("metadata.namespace=%s", namespace)}) + if err != nil { + return err + } + for _, secret := range secrets.Items { + if secret.Annotations[ProjectScopedSecretAnnotation] == "true" { + if err := nsh.secrets.DeleteNamespaced(namespace, secret.Name, &metav1.DeleteOptions{}); err != nil { + return err + } + } else { + secretCopy := secret.DeepCopy() + if secretCopy.Annotations == nil { + secretCopy.Annotations = make(map[string]string) + } + if projectID == "" { + secretCopy.Annotations[ProjectIDFieldLabel] = projectID + } else { + secretCopy.Annotations[ProjectIDFieldLabel] = fmt.Sprintf("%s:%s", clusterID, projectID) + } + if _, err := nsh.secrets.Update(secretCopy); err != nil { + return err + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nsserviceaccount/nssvcaccnt.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nsserviceaccount/nssvcaccnt.go new file mode 100644 index 0000000..0aceadb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/nsserviceaccount/nssvcaccnt.go @@ -0,0 +1,70 @@ +package nsserviceaccount + +import ( + "context" + + rv1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + projectIDAnnotation = "field.cattle.io/projectId" + sysNamespaceAnnotation = "management.cattle.io/system-namespace" + NoDefaultSATokenAnnotation = "management.cattle.io/no-default-sa-token" +) + +type defaultSvcAccountHandler struct { + serviceAccountsLister rv1.ServiceAccountLister + serviceAccounts rv1.ServiceAccountInterface +} + +func Register(ctx context.Context, cluster *config.UserOnlyContext) { + logrus.Debugf("Registering defaultSvcAccountHandler for checking default service account of system namespaces") + nsh := &defaultSvcAccountHandler{ + serviceAccounts: cluster.Core.ServiceAccounts(""), + serviceAccountsLister: cluster.Core.ServiceAccounts("").Controller().Lister(), + } + cluster.Core.Namespaces("").AddHandler(ctx, "defaultSvcAccountHandler", nsh.Sync) +} + +func (nsh *defaultSvcAccountHandler) Sync(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil || ns.DeletionTimestamp != nil { + return nil, nil + } + logrus.Debugf("defaultSvcAccountHandler: Sync service account: key=%v", key) + //handle default svcAccount of system namespaces only + if err := nsh.handleIfSystemNSDefaultSA(ns); err != nil { + logrus.Errorf("defaultSvcAccountHandler: Sync: error handling default ServiceAccount of namespace key=%v, err=%v", key, err) + } + return nil, nil +} + +func (nsh *defaultSvcAccountHandler) handleIfSystemNSDefaultSA(ns *corev1.Namespace) error { + if ns.Annotations[NoDefaultSATokenAnnotation] != "true" { + return nil + } + + defSvcAccnt, err := nsh.serviceAccountsLister.Get(ns.Name, "default") + if apierrors.IsNotFound(err) { + return nil + } else if err != nil { + return err + } + + if defSvcAccnt.AutomountServiceAccountToken != nil && *defSvcAccnt.AutomountServiceAccountToken == false { + return nil + } + automountServiceAccountToken := false + defSvcAccnt.AutomountServiceAccountToken = &automountServiceAccountToken + logrus.Debugf("defaultSvcAccountHandler: updating default service account key=%v", defSvcAccnt) + _, err = nsh.serviceAccounts.Update(defSvcAccnt) + if err != nil { + logrus.Errorf("defaultSvcAccountHandler: error updating default service account flag for namespace: %v, err=%+v", ns.Name, err) + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/podresources/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/podresources/register.go new file mode 100644 index 0000000..97686c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/podresources/register.go @@ -0,0 +1,146 @@ +package podresources + +import ( + "context" + "encoding/json" + "time" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + RequestsAnnotation = "management.cattle.io/pod-requests" + LimitsAnnotation = "management.cattle.io/pod-limits" +) + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + p := podResources{ + podLister: workload.Core.Pods("").Controller().Lister(), + nodes: workload.Core.Nodes(""), + } + + workload.Core.Nodes("").AddHandler(ctx, "podresource", p.onChange) +} + +type podResources struct { + podLister v1.PodLister + nodes v1.NodeInterface +} + +func (p *podResources) onChange(key string, node *corev1.Node) (runtime.Object, error) { + if node == nil { + return node, nil + } + + p.nodes.Controller().EnqueueAfter("", node.Name, 15*time.Second) + + pods, err := p.getNonTerminatedPods(node) + if err != nil { + return nil, err + } + + requests, limits, err := getPodResourceAnnotations(pods) + if err != nil { + return nil, err + } + + if node.Annotations[RequestsAnnotation] != requests || + node.Annotations[LimitsAnnotation] != limits { + node := node.DeepCopy() + if node.Annotations == nil { + node.Annotations = map[string]string{} + } + node.Annotations[RequestsAnnotation] = requests + node.Annotations[LimitsAnnotation] = limits + return p.nodes.Update(node) + } + + return node, nil +} + +func (p *podResources) getNonTerminatedPods(node *corev1.Node) ([]*corev1.Pod, error) { + var pods []*corev1.Pod + fromCache, err := p.podLister.List("", labels.NewSelector()) + if err != nil { + return pods, err + } + + for _, pod := range fromCache { + if pod.Spec.NodeName != node.Name { + continue + } + // kubectl uses this cache to filter out the pods + if pod.Status.Phase == "Succeeded" || pod.Status.Phase == "Failed" { + continue + } + pods = append(pods, pod) + } + return pods, nil +} + +func getPodResourceAnnotations(pods []*corev1.Pod) (string, string, error) { + requests, limits := aggregateRequestAndLimitsForNode(pods) + requestsBytes, err := json.Marshal(requests) + if err != nil { + return "", "", err + } + + limitsBytes, err := json.Marshal(limits) + return string(requestsBytes), string(limitsBytes), err +} + +func aggregateRequestAndLimitsForNode(pods []*corev1.Pod) (map[corev1.ResourceName]resource.Quantity, map[corev1.ResourceName]resource.Quantity) { + requests, limits := map[corev1.ResourceName]resource.Quantity{}, map[corev1.ResourceName]resource.Quantity{} + for _, pod := range pods { + podRequests, podLimits := getPodData(pod) + addMap(podRequests, requests) + addMap(podLimits, limits) + } + if pods != nil { + requests[corev1.ResourcePods] = *resource.NewQuantity(int64(len(pods)), resource.DecimalSI) + } + return requests, limits +} + +func getPodData(pod *corev1.Pod) (map[corev1.ResourceName]resource.Quantity, map[corev1.ResourceName]resource.Quantity) { + requests, limits := map[corev1.ResourceName]resource.Quantity{}, map[corev1.ResourceName]resource.Quantity{} + for _, container := range pod.Spec.Containers { + addMap(container.Resources.Requests, requests) + addMap(container.Resources.Limits, limits) + } + + for _, container := range pod.Spec.InitContainers { + addMapForInit(container.Resources.Requests, requests) + addMapForInit(container.Resources.Limits, limits) + } + return requests, limits +} + +func addMap(data1 map[corev1.ResourceName]resource.Quantity, data2 map[corev1.ResourceName]resource.Quantity) { + for name, quantity := range data1 { + if value, ok := data2[name]; !ok { + data2[name] = quantity.DeepCopy() + } else { + value.Add(quantity) + data2[name] = value + } + } +} + +func addMapForInit(data1 map[corev1.ResourceName]resource.Quantity, data2 map[corev1.ResourceName]resource.Quantity) { + for name, quantity := range data1 { + value, ok := data2[name] + if !ok { + data2[name] = quantity.DeepCopy() + continue + } + if quantity.Cmp(value) > 0 { + data2[name] = quantity.DeepCopy() + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/targetworkloadservice/target_workload_service.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/targetworkloadservice/target_workload_service.go new file mode 100644 index 0000000..751d42a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/targetworkloadservice/target_workload_service.go @@ -0,0 +1,319 @@ +package targetworkloadservice + +import ( + "context" + "encoding/json" + + "k8s.io/apimachinery/pkg/runtime" + + "fmt" + + "strings" + + "sync" + + "reflect" + + "github.com/pkg/errors" + util "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" +) + +// This controller is responsible for monitoring services with targetWorkloadIds, +// locating corresponding pods, and marking them with the label to satisfy service selector + +const ( + WorkloadIDLabelPrefix = "workloadID" + creatorLabelKey = "cattle.io/creator" + creatorNorman = "norman" +) + +var workloadServiceUUIDToWorkloadIDs sync.Map + +type Controller struct { + pods v1.PodInterface + workloadLister util.CommonController + podLister v1.PodLister + services v1.ServiceInterface +} + +type PodController struct { + pods v1.PodInterface + workloadLister util.CommonController + serviceLister v1.ServiceLister +} + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + c := &Controller{ + pods: workload.Core.Pods(""), + workloadLister: util.NewWorkloadController(ctx, workload, nil), + podLister: workload.Core.Pods("").Controller().Lister(), + services: workload.Core.Services(""), + } + p := &PodController{ + workloadLister: util.NewWorkloadController(ctx, workload, nil), + pods: workload.Core.Pods(""), + serviceLister: workload.Core.Services("").Controller().Lister(), + } + workload.Core.Services("").AddHandler(ctx, "workloadServiceController", c.sync) + workload.Core.Pods("").AddHandler(ctx, "podToWorkloadServiceController", p.sync) +} + +func (c *Controller) sync(key string, obj *corev1.Service) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + if value, ok := workloadServiceUUIDToWorkloadIDs.Load(key); ok { + if err := c.updateServiceWorkloadPods(key, value.(map[string]bool)); err != nil { + return nil, err + } + } + // delete from the workload map + workloadServiceUUIDToWorkloadIDs.Delete(key) + return nil, nil + } + + // add WorkloadID selector only if service is created by norman + if obj.Labels == nil || obj.Labels[creatorLabelKey] != creatorNorman { + return obj, nil + } + + workloadIDs := getServiceWorkloadIDs(obj) + // update pods (if needed) with service selector labels + targetWorkloadIDs, err := c.reconcilePods(key, obj, workloadIDs) + if err != nil { + return nil, err + } + + // if workloadIDs changed, push update for all the pods, so they reconcile the labels + workloadIDsToUpdate := map[string]bool{} + oldMap, ok := workloadServiceUUIDToWorkloadIDs.Load(key) + if ok { + for workloadID := range oldMap.(map[string]bool) { + workloadIDsToUpdate[workloadID] = true + } + } + for workloadID := range targetWorkloadIDs { + workloadIDsToUpdate[workloadID] = true + } + + if err := c.updateServiceWorkloadPods(key, workloadIDsToUpdate); err != nil { + return nil, err + } + + //reset the map + workloadServiceUUIDToWorkloadIDs.Store(key, targetWorkloadIDs) + + return nil, nil +} + +func getServiceWorkloadIDs(obj *corev1.Service) []string { + var workloadIDs []string + if obj.Annotations == nil { + return workloadIDs + } + value, ok := obj.Annotations[util.WorkloadAnnotation] + if !ok || value == "" { + return workloadIDs + } + noop, ok := obj.Annotations[util.WorkloadAnnotatioNoop] + if ok && noop == "true" { + return workloadIDs + } + + err := json.Unmarshal([]byte(value), &workloadIDs) + if err != nil { + // just log the error, can't really do anything here. + logrus.Debugf("Failed to unmarshal targetWorkloadIds, error: %v", err) + } + return workloadIDs +} + +func (c *Controller) fetchWorkload(workloadID string) (*util.Workload, error) { + workload, err := c.workloadLister.GetByWorkloadIDRetryAPIIfNotFound(workloadID) + if err != nil && apierrors.IsNotFound(err) { + logrus.Warnf("Failed to fetch workload [%s]: [%v]", workloadID, err) + return nil, nil + } + + return workload, err +} + +func (c *Controller) updateServiceWorkloadPods(key string, workloadIDsToCleanup map[string]bool) error { + if len(workloadIDsToCleanup) == 0 { + return nil + } + var podsToEnqueue []*corev1.Pod + var workloadsToCleanup []*util.Workload + for workloadID := range workloadIDsToCleanup { + workload, err := c.fetchWorkload(workloadID) + if err != nil { + return err + } + if workload == nil { + continue + } + pods, err := c.getPodsForWorkload(workload) + if err != nil { + return err + } + podsToEnqueue = append(podsToEnqueue, pods...) + workloadsToCleanup = append(workloadsToCleanup, workload) + } + + for _, pod := range podsToEnqueue { + c.pods.Controller().Enqueue(pod.Namespace, pod.Name) + } + + for _, workload := range workloadsToCleanup { + c.workloadLister.EnqueueWorkload(workload) + } + return nil +} + +func (c *Controller) reconcilePods(key string, obj *corev1.Service, workloadIDs []string) (map[string]bool, error) { + if len(workloadIDs) == 0 { + return nil, nil + } + if obj.Spec.Selector == nil { + obj.Spec.Selector = map[string]string{} + } + selectorToAdd := getServiceSelector(obj.Name) + var toUpdate *corev1.Service + if _, ok := obj.Spec.Selector[selectorToAdd]; !ok { + toUpdate = obj.DeepCopy() + toUpdate.Spec.Selector[selectorToAdd] = "true" + _, err := c.services.Update(toUpdate) + if err != nil { + return nil, err + } + } + return c.updatePods(key, obj, workloadIDs) +} + +func (c *Controller) getPodsForWorkload(workload *util.Workload) ([]*corev1.Pod, error) { + set := labels.Set{} + for key, val := range workload.SelectorLabels { + set[key] = val + } + workloadSelector := labels.SelectorFromSet(set) + return c.podLister.List(workload.Namespace, workloadSelector) +} + +func (c *Controller) updatePods(serviceName string, obj *corev1.Service, workloadIDs []string) (map[string]bool, error) { + var podsToUpdate []*corev1.Pod + targetWorkloadIDs := map[string]bool{} + for _, workloadID := range workloadIDs { + workload, err := c.fetchWorkload(workloadID) + if err != nil { + return nil, err + } + if workload == nil { + continue + } + + pods, err := c.getPodsForWorkload(workload) + if err != nil { + return nil, err + } + + // Add workload/deployment to the system map + targetWorkloadIDs[workloadID] = true + + // Find all the pods satisfying deployments' selectors + for _, pod := range pods { + if pod.DeletionTimestamp != nil { + continue + } + for svsSelectorKey, svcSelectorValue := range obj.Spec.Selector { + if value, ok := pod.Labels[svsSelectorKey]; ok && value == svcSelectorValue { + continue + } + podsToUpdate = append(podsToUpdate, pod) + } + } + } + + // Update the pods with the label + for _, pod := range podsToUpdate { + toUpdate := pod.DeepCopy() + for svcSelectorKey, svcSelectorValue := range obj.Spec.Selector { + toUpdate.Labels[svcSelectorKey] = svcSelectorValue + } + if _, err := c.pods.Update(toUpdate); err != nil { + return nil, errors.Wrapf(err, "Failed to update pod [%s] with workload service selector [%s]", + pod.Name, fmt.Sprintf("%s/%s", obj.Namespace, obj.Name)) + } + } + return targetWorkloadIDs, nil +} + +func getServiceSelector(serviceName string) string { + return fmt.Sprintf("%s_%s", WorkloadIDLabelPrefix, serviceName) +} + +func (c *PodController) sync(key string, obj *corev1.Pod) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + // filter out deployments that are match for the pods + workloads, err := c.workloadLister.GetWorkloadsMatchingLabels(obj.Namespace, obj.Labels) + if err != nil { + return nil, err + } + + workloadServiceUUIDsToAdd := map[string]bool{} + for _, d := range workloads { + workloadServiceUUIDToWorkloadIDs.Range(func(k, v interface{}) bool { + if _, ok := v.(map[string]bool)[d.Key]; ok { + workloadServiceUUIDsToAdd[k.(string)] = true + } + return true + }) + } + + workloadServicesLabels := map[string]string{} + for workloadServiceUUID := range workloadServiceUUIDsToAdd { + parts := strings.Split(workloadServiceUUID, "/") + workloadService, err := c.serviceLister.Get(parts[0], parts[1]) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + if workloadService == nil { + logrus.Warnf("Failed to fetch service [%s]: [%v]", workloadServiceUUID, err) + workloadServiceUUIDToWorkloadIDs.Delete(workloadServiceUUID) + continue + } + + for key, value := range workloadService.Spec.Selector { + workloadServicesLabels[key] = value + } + } + + // remove old labels + labels := map[string]string{} + for key, value := range obj.Labels { + if strings.HasPrefix(key, WorkloadIDLabelPrefix) { + if _, ok := workloadServicesLabels[key]; !ok { + continue + } + } + labels[key] = value + } + + // add new labels + for key, value := range workloadServicesLabels { + labels[key] = value + } + + if reflect.DeepEqual(obj.Labels, labels) { + return nil, nil + } + toUpdate := obj.DeepCopy() + toUpdate.Labels = labels + _, err = c.pods.Update(toUpdate) + return nil, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload.go new file mode 100644 index 0000000..4b909ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload.go @@ -0,0 +1,308 @@ +package workload + +import ( + "context" + "encoding/json" + "reflect" + + "strings" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/validation" +) + +// This controller is responsible for monitoring workloads and +// creating services for them +// a) when rancher ports annotation is present, create service based on annotation ports +// b) when annotation is missing, create a headless service + +const ( + creatorIDAnnotation = "field.cattle.io/creatorId" +) + +type Controller struct { + workloadController CommonController + serviceLister v1.ServiceLister + services v1.ServiceInterface +} + +func Register(ctx context.Context, workload *config.UserOnlyContext) { + c := &Controller{ + serviceLister: workload.Core.Services("").Controller().Lister(), + services: workload.Core.Services(""), + } + c.workloadController = NewWorkloadController(ctx, workload, c.CreateService) +} + +func getName() string { + return "workloadServiceGenerationController" +} + +func (c *Controller) CreateService(key string, w *Workload) error { + // do not create service for job, cronJob and for workload owned by controller (ReplicaSet) + if strings.EqualFold(w.Kind, "job") || strings.EqualFold(w.Kind, "cronJob") { + return nil + } + for _, o := range w.OwnerReferences { + if o.Controller != nil && *o.Controller { + return nil + } + } + + if _, ok := w.Annotations[creatorIDAnnotation]; !ok { + return nil + } + + if errs := validation.IsDNS1123Subdomain(w.Name); len(errs) != 0 { + logrus.Debugf("Not creating service for workload [%s]: dns name is invalid", w.Name) + return nil + } + + return c.CreateServiceForWorkload(w) +} + +func (c *Controller) serviceExistsForWorkload(workload *Workload, service *Service) (*corev1.Service, error) { + s, err := c.serviceLister.Get(workload.Namespace, service.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, nil + } + return nil, err + } + + if s.DeletionTimestamp != nil { + return nil, nil + } + + return s, nil +} + +func (c *Controller) CreateServiceForWorkload(workload *Workload) error { + services := map[corev1.ServiceType]Service{} + if _, ok := workload.TemplateSpec.Annotations[PortsAnnotation]; ok { + svcs, err := generateServicesFromPortsAnnotation(workload) + if err != nil { + return err + } + for _, service := range svcs { + services[service.Type] = service + } + } + // always create cluster ip service, if missing in ports + if _, ok := services[ClusterIPServiceType]; !ok { + service := generateClusterIPServiceFromContainers(workload) + services[service.Type] = *service + } + + // 1. Create new services + for _, toCreate := range services { + existing, err := c.serviceExistsForWorkload(workload, &toCreate) + if err != nil { + return err + } + + recreate := false + // to handle clusterIP to headless service updates + // as clusterIP field is immutable + if existing != nil && toCreate.Type == ClusterIPServiceType { + clusterIPNew := toCreate.ClusterIP + custerIPOld := existing.Spec.ClusterIP + if clusterIPNew != custerIPOld && (clusterIPNew == "None" || custerIPOld == "None") { + err = c.services.DeleteNamespaced(existing.Namespace, existing.Name, &metav1.DeleteOptions{}) + if err != nil { + return err + } + recreate = true + } + } + + if existing == nil || recreate { + if err := c.createService(toCreate, workload); err != nil { + return err + } + } else { + // check if the port of the same type + if existing.Spec.Type != toCreate.Type { + logrus.Warnf("Service [%s/%s] already exists but with diff type. Expected type [%s], actual type [%v]", existing.Name, existing.Namespace, toCreate.Type, existing.Spec.Type) + return nil + } + isOwner := false + for _, ref := range existing.OwnerReferences { + if reflect.DeepEqual(ref.UID, workload.UUID) { + isOwner = true + break + } + } + if !isOwner { + logrus.Warnf("Service [%s/%s] already exists but with diff owner", existing.Name, existing.Namespace) + return nil + } + + if ArePortsEqual(toCreate.ServicePorts, existing.Spec.Ports) { + continue + } + + if err := c.updateService(toCreate, existing); err != nil { + return err + } + } + } + // 2. Cleanup services that are no longer needed + existingSvcs, err := c.getServicesOwnedByWorkload(workload) + if err != nil { + return err + } + var toRemove []*corev1.Service + for _, existingSvc := range existingSvcs { + toCreate, ok := services[existingSvc.Spec.Type] + if ok && toCreate.Name == existingSvc.Name { + continue + } + toRemove = append(toRemove, existingSvc) + } + for _, svc := range toRemove { + logrus.Infof("Deleting [%s/%s] service of type [%s] for workload [%s/%s]", svc.Namespace, svc.Name, svc.Spec.Type, + workload.Namespace, workload.Name) + if err := c.services.DeleteNamespaced(svc.Namespace, svc.Name, &metav1.DeleteOptions{}); err != nil { + return err + } + } + + return nil +} + +func (c *Controller) updateService(toUpdate Service, existing *corev1.Service) error { + existingPortNameToPort := map[string]corev1.ServicePort{} + for _, p := range existing.Spec.Ports { + existingPortNameToPort[p.Name] = p + } + + var portsToUpdate []corev1.ServicePort + for _, p := range toUpdate.ServicePorts { + if val, ok := existingPortNameToPort[p.Name]; ok { + if val.Port == p.Port { + if p.NodePort != val.NodePort { + if p.NodePort == 0 { + // random port handling to avoid infinite updates + p.NodePort = val.NodePort + } + } + } + } + portsToUpdate = append(portsToUpdate, p) + } + + existing.Spec.Ports = portsToUpdate + if existing.Spec.Type == ClusterIPServiceType && existing.Spec.ClusterIP == "None" { + existing.Spec.ClusterIP = toUpdate.ClusterIP + } + logrus.Infof("Updating [%s/%s] service with ports [%v]", existing.Namespace, existing.Name, portsToUpdate) + _, err := c.services.Update(existing) + if err != nil { + return err + } + + return nil +} + +func (c *Controller) getServicesOwnedByWorkload(workload *Workload) ([]*corev1.Service, error) { + var toReturn []*corev1.Service + services, err := c.serviceLister.List(workload.Namespace, labels.NewSelector()) + if err != nil { + return toReturn, err + } + for _, svc := range services { + if _, ok := svc.Annotations[WorkloaAnnotationdPortBasedService]; ok { + for _, o := range svc.OwnerReferences { + if o.UID == workload.UUID { + toReturn = append(toReturn, svc) + break + } + } + } + } + return toReturn, nil +} + +func (c *Controller) createService(toCreate Service, workload *Workload) error { + controller := true + ownerRef := metav1.OwnerReference{ + Name: workload.Name, + APIVersion: workload.APIVersion, + UID: workload.UUID, + Kind: workload.Kind, + Controller: &controller, + } + + serviceAnnotations := map[string]string{} + workloadAnnotationValue, err := IDAnnotationToString(workload.Key) + if err != nil { + return err + } + serviceAnnotations[WorkloadAnnotation] = workloadAnnotationValue + serviceAnnotations[WorkloadAnnotatioNoop] = "true" + serviceAnnotations[WorkloaAnnotationdPortBasedService] = "true" + + service := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ownerRef}, + Namespace: workload.Namespace, + Name: toCreate.Name, + Annotations: serviceAnnotations, + }, + Spec: corev1.ServiceSpec{ + ClusterIP: toCreate.ClusterIP, + Type: toCreate.Type, + Ports: toCreate.ServicePorts, + Selector: workload.SelectorLabels, + }, + } + + logrus.Infof("Creating [%s/%s] service of type [%s] with ports [%v] for workload %s", service.Namespace, service.Name, + service.Spec.Type, toCreate.ServicePorts, workload.Key) + _, err = c.services.Create(service) + if err != nil { + if apierrors.IsAlreadyExists(err) { + return nil + } + return err + } + return nil +} + +func ArePortsEqual(one []corev1.ServicePort, two []corev1.ServicePort) bool { + if len(one) != len(two) { + return false + } + + for _, o := range one { + found := false + for _, t := range two { + nodePortsEqual := (o.NodePort == 0 || t.NodePort == 0) || (o.NodePort == t.NodePort) + if o.TargetPort == t.TargetPort && o.Protocol == t.Protocol && o.Port == t.Port && nodePortsEqual { + found = true + break + } + } + if !found { + return false + } + } + + return true +} + +func IDAnnotationToString(workloadID string) (string, error) { + ws := []string{workloadID} + b, err := json.Marshal(ws) + if err != nil { + return "", err + } + return string(b), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload_common.go new file mode 100644 index 0000000..1d40918 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementagent/workload/workload_common.go @@ -0,0 +1,829 @@ +package workload + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/rancher/norman/types/convert" + appsv1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + batchv1 "github.com/rancher/rancher/pkg/generated/norman/batch/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + k8sappv1 "k8s.io/api/apps/v1" + corebatchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + AppVersion = "apps/v1beta2" + BatchBetaVersion = "batch/v1beta1" + BatchVersion = "batch/v1" + WorkloadAnnotation = "field.cattle.io/targetWorkloadIds" + PortsAnnotation = "field.cattle.io/ports" + ClusterIPServiceType = "ClusterIP" + DeploymentType = "deployment" + ReplicationControllerType = "replicationcontroller" + ReplicaSetType = "replicaset" + DaemonSetType = "daemonset" + StatefulSetType = "statefulset" + JobType = "job" + CronJobType = "cronjob" + WorkloadAnnotatioNoop = "workload.cattle.io/targetWorkloadIdNoop" + WorkloaAnnotationdPortBasedService = "workload.cattle.io/workloadPortBased" +) + +var WorkloadKinds = map[string]bool{ + "Deployment": true, + "ReplicationController": true, + "ReplicaSet": true, + "DaemonSet": true, + "StatefulSet": true, + "Job": true, + "CronJob": true, +} + +type Workload struct { + Name string + Namespace string + UUID types.UID + SelectorLabels map[string]string + Annotations map[string]string + TemplateSpec *corev1.PodTemplateSpec + Kind string + APIVersion string + OwnerReferences []metav1.OwnerReference + Labels map[string]string + Key string + Status *Status +} + +type Status struct { + Replicas int32 + AvailableReplicas int32 + Conditions []map[string]interface{} +} + +type CommonController struct { + DeploymentLister appsv1.DeploymentLister + ReplicationControllerLister v1.ReplicationControllerLister + ReplicaSetLister appsv1.ReplicaSetLister + DaemonSetLister appsv1.DaemonSetLister + StatefulSetLister appsv1.StatefulSetLister + JobLister batchv1.JobLister + CronJobLister batchv1.CronJobLister + Deployments appsv1.DeploymentInterface + ReplicationControllers v1.ReplicationControllerInterface + ReplicaSets appsv1.ReplicaSetInterface + DaemonSets appsv1.DaemonSetInterface + StatefulSets appsv1.StatefulSetInterface + Jobs batchv1.JobInterface + CronJobs batchv1.CronJobInterface + Sync func(key string, w *Workload) error +} + +func NewWorkloadController(ctx context.Context, workload *config.UserOnlyContext, f func(key string, w *Workload) error) CommonController { + c := CommonController{ + DeploymentLister: workload.Apps.Deployments("").Controller().Lister(), + ReplicationControllerLister: workload.Core.ReplicationControllers("").Controller().Lister(), + ReplicaSetLister: workload.Apps.ReplicaSets("").Controller().Lister(), + DaemonSetLister: workload.Apps.DaemonSets("").Controller().Lister(), + StatefulSetLister: workload.Apps.StatefulSets("").Controller().Lister(), + JobLister: workload.BatchV1.Jobs("").Controller().Lister(), + CronJobLister: workload.BatchV1.CronJobs("").Controller().Lister(), + Deployments: workload.Apps.Deployments(""), + ReplicationControllers: workload.Core.ReplicationControllers(""), + ReplicaSets: workload.Apps.ReplicaSets(""), + DaemonSets: workload.Apps.DaemonSets(""), + StatefulSets: workload.Apps.StatefulSets(""), + Jobs: workload.BatchV1.Jobs(""), + CronJobs: workload.BatchV1.CronJobs(""), + Sync: f, + } + if f != nil { + workload.Apps.Deployments("").AddHandler(ctx, getName(), c.syncDeployments) + workload.Core.ReplicationControllers("").AddHandler(ctx, getName(), c.syncReplicationControllers) + workload.Apps.ReplicaSets("").AddHandler(ctx, getName(), c.syncReplicaSet) + workload.Apps.DaemonSets("").AddHandler(ctx, getName(), c.syncDaemonSet) + workload.Apps.StatefulSets("").AddHandler(ctx, getName(), c.syncStatefulSet) + workload.BatchV1.Jobs("").AddHandler(ctx, getName(), c.syncJob) + workload.BatchV1.CronJobs("").AddHandler(ctx, getName(), c.syncCronJob) + } + return c +} + +func (c *CommonController) syncDeployments(key string, obj *k8sappv1.Deployment) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + w, err := c.getWorkload(key, DeploymentType) + if err != nil || w == nil { + return nil, err + } + + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncReplicationControllers(key string, obj *corev1.ReplicationController) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, ReplicationControllerType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncReplicaSet(key string, obj *k8sappv1.ReplicaSet) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, ReplicaSetType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncDaemonSet(key string, obj *k8sappv1.DaemonSet) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, DaemonSetType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncStatefulSet(key string, obj *k8sappv1.StatefulSet) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, StatefulSetType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncJob(key string, obj *corebatchv1.Job) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, JobType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c *CommonController) syncCronJob(key string, obj *corebatchv1.CronJob) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + w, err := c.getWorkload(key, CronJobType) + if err != nil || w == nil { + return nil, err + } + return nil, c.Sync(key, w) +} + +func (c CommonController) getWorkload(key string, objectType string) (*Workload, error) { + splitted := strings.Split(key, "/") + namespace := splitted[0] + name := splitted[1] + return c.GetByWorkloadID(getWorkloadID(objectType, namespace, name)) +} + +func (c CommonController) GetByWorkloadID(key string) (*Workload, error) { + return c.getByWorkloadIDFromCacheOrAPI(key, false) +} + +func (c CommonController) GetByWorkloadIDRetryAPIIfNotFound(key string) (*Workload, error) { + return c.getByWorkloadIDFromCacheOrAPI(key, true) +} + +func (c CommonController) getByWorkloadIDFromCacheOrAPI(key string, retry bool) (*Workload, error) { + splitted := strings.Split(key, ":") + if len(splitted) != 3 { + return nil, fmt.Errorf("workload name [%s] is invalid", key) + } + workloadType := strings.ToLower(splitted[0]) + namespace := splitted[1] + name := splitted[2] + var workload *Workload + switch workloadType { + case ReplicationControllerType: + o, err := c.ReplicationControllerLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.ReplicationControllers.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + labelSelector := &metav1.LabelSelector{ + MatchLabels: o.Spec.Selector, + } + workload = getWorkload(namespace, name, workloadType, AppVersion, o.UID, labelSelector, o.Annotations, o.Spec.Template, + o.OwnerReferences, o.Labels, o.Status.Replicas, o.Status.AvailableReplicas, convert.ToMapSlice(o.Status.Conditions)) + case ReplicaSetType: + o, err := c.ReplicaSetLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.ReplicaSets.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + + workload = getWorkload(namespace, name, workloadType, AppVersion, o.UID, o.Spec.Selector, o.Annotations, &o.Spec.Template, + o.OwnerReferences, o.Labels, o.Status.Replicas, o.Status.AvailableReplicas, convert.ToMapSlice(o.Status.Conditions)) + case DaemonSetType: + o, err := c.DaemonSetLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.DaemonSets.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + + workload = getWorkload(namespace, name, workloadType, AppVersion, o.UID, o.Spec.Selector, o.Annotations, &o.Spec.Template, + o.OwnerReferences, o.Labels, o.Status.DesiredNumberScheduled, o.Status.NumberAvailable, convert.ToMapSlice(o.Status.Conditions)) + case StatefulSetType: + o, err := c.StatefulSetLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.StatefulSets.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + + workload = getWorkload(namespace, name, workloadType, AppVersion, o.UID, o.Spec.Selector, o.Annotations, &o.Spec.Template, + o.OwnerReferences, o.Labels, o.Status.Replicas, o.Status.ReadyReplicas, convert.ToMapSlice(o.Status.Conditions)) + case JobType: + o, err := c.JobLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.Jobs.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + var labelSelector *metav1.LabelSelector + if o.Spec.Selector != nil { + labelSelector = &metav1.LabelSelector{ + MatchLabels: o.Spec.Selector.MatchLabels, + } + } + + workload = getWorkload(namespace, name, workloadType, BatchVersion, o.UID, labelSelector, o.Annotations, &o.Spec.Template, + o.OwnerReferences, o.Labels, 0, 0, convert.ToMapSlice(o.Status.Conditions)) + case CronJobType: + o, err := c.CronJobLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.CronJobs.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + var labelSelector *metav1.LabelSelector + if o.Spec.JobTemplate.Spec.Selector != nil { + labelSelector = &metav1.LabelSelector{ + MatchLabels: o.Spec.JobTemplate.Spec.Selector.MatchLabels, + } + } + + workload = getWorkload(namespace, name, workloadType, BatchBetaVersion, o.UID, labelSelector, o.Annotations, &o.Spec.JobTemplate.Spec.Template, + o.OwnerReferences, o.Labels, 0, 0, nil) + default: + o, err := c.DeploymentLister.Get(namespace, name) + if err != nil && apierrors.IsNotFound(err) && retry { + o, err = c.Deployments.GetNamespaced(namespace, name, metav1.GetOptions{}) + } + if err != nil || o.DeletionTimestamp != nil { + return nil, err + } + + workload = getWorkload(namespace, name, DeploymentType, AppVersion, o.UID, o.Spec.Selector, o.Annotations, &o.Spec.Template, + o.OwnerReferences, o.Labels, o.Status.Replicas, o.Status.AvailableReplicas, convert.ToMapSlice(o.Status.Conditions)) + } + return workload, nil +} + +func getWorkload(namespace string, name string, kind string, apiVersion string, UUID types.UID, selectorLabels *metav1.LabelSelector, + annotations map[string]string, podTemplateSpec *corev1.PodTemplateSpec, ownerRefs []metav1.OwnerReference, labels map[string]string, + replicas, availableReplicas int32, conditions []map[string]interface{}) *Workload { + w := &Workload{ + Name: name, + Namespace: namespace, + SelectorLabels: getSelectorLables(selectorLabels), + UUID: UUID, + Annotations: annotations, + TemplateSpec: podTemplateSpec, + OwnerReferences: ownerRefs, + Kind: kind, + APIVersion: apiVersion, + Labels: labels, + Key: fmt.Sprintf("%s:%s:%s", kind, namespace, name), + Status: &Status{ + Replicas: replicas, + AvailableReplicas: availableReplicas, + Conditions: conditions, + }, + } + return w +} + +func (c CommonController) GetAllWorkloads(namespace string) ([]*Workload, error) { + var workloads []*Workload + + // deployments + ds, err := c.DeploymentLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range ds { + workload, err := c.GetByWorkloadID(getWorkloadID(DeploymentType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // replication controllers + rcs, err := c.ReplicationControllerLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range rcs { + workload, err := c.GetByWorkloadID(getWorkloadID(ReplicationControllerType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // replica sets + rss, err := c.ReplicaSetLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range rss { + workload, err := c.GetByWorkloadID(getWorkloadID(ReplicaSetType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // daemon sets + dss, err := c.DaemonSetLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range dss { + workload, err := c.GetByWorkloadID(getWorkloadID(DaemonSetType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // stateful sets + sts, err := c.StatefulSetLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range sts { + workload, err := c.GetByWorkloadID(getWorkloadID(StatefulSetType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // jobs + jobs, err := c.JobLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range jobs { + workload, err := c.GetByWorkloadID(getWorkloadID(JobType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + // cron jobs + cronJobs, err := c.CronJobLister.List(namespace, labels.NewSelector()) + if err != nil { + return workloads, err + } + + for _, o := range cronJobs { + workload, err := c.GetByWorkloadID(getWorkloadID(CronJobType, o.Namespace, o.Name)) + if err != nil || workload == nil { + return workloads, err + } + workloads = append(workloads, workload) + } + + return workloads, nil +} + +func (c CommonController) GetWorkloadsMatchingLabels(namespace string, targetLabels map[string]string) ([]*Workload, error) { + var workloads []*Workload + allWorkloads, err := c.GetAllWorkloads(namespace) + if err != nil { + return workloads, err + } + + for _, workload := range allWorkloads { + workloadSelector := labels.SelectorFromSet(workload.SelectorLabels) + if workloadSelector.Matches(labels.Set(targetLabels)) { + workloads = append(workloads, workload) + } + } + + return workloads, nil +} + +func (c CommonController) GetWorkloadsMatchingSelector(namespace string, selectorLabels map[string]string) ([]*Workload, error) { + var workloads []*Workload + allWorkloads, err := c.GetAllWorkloads(namespace) + if err != nil { + return workloads, err + } + + selector := labels.SelectorFromSet(selectorLabels) + for _, workload := range allWorkloads { + if selector.Matches(labels.Set(workload.Labels)) { + workloads = append(workloads, workload) + } + } + + return workloads, nil +} + +func getSelectorLables(s *metav1.LabelSelector) map[string]string { + if s == nil { + return nil + } + selectorLabels := map[string]string{} + for key, value := range s.MatchLabels { + selectorLabels[key] = value + } + return selectorLabels +} + +type Service struct { + Type corev1.ServiceType + ClusterIP string + ServicePorts []corev1.ServicePort + Name string +} + +type ContainerPort struct { + Kind string `json:"kind,omitempty"` + SourcePort int `json:"sourcePort,omitempty"` + DNSName string `json:"dnsName,omitempty"` + Name string `json:"name,omitempty"` + Protocol string `json:"protocol,omitempty"` + ContainerPort int32 `json:"containerPort,omitempty"` +} + +func generateClusterIPServiceFromContainers(workload *Workload) *Service { + var servicePorts []corev1.ServicePort + for _, c := range workload.TemplateSpec.Spec.Containers { + for _, p := range c.Ports { + var portName string + if p.Name == "" { + portName = fmt.Sprintf("%s-%s", strconv.FormatInt(int64(p.ContainerPort), 10), c.Name) + } else { + portName = fmt.Sprintf("%s-%s", p.Name, c.Name) + } + servicePort := corev1.ServicePort{ + Port: p.ContainerPort, + TargetPort: intstr.Parse(strconv.FormatInt(int64(p.ContainerPort), 10)), + Protocol: p.Protocol, + Name: portName, + } + + servicePorts = append(servicePorts, servicePort) + } + } + clusterIP := "" + // append default port as sky dns won't work w/o at least one port being set + if len(servicePorts) == 0 { + servicePort := corev1.ServicePort{ + Port: 42, + TargetPort: intstr.Parse(strconv.FormatInt(42, 10)), + Protocol: corev1.Protocol(corev1.ProtocolTCP), + Name: "default", + } + clusterIP = "None" + servicePorts = append(servicePorts, servicePort) + } + + return &Service{ + Type: ClusterIPServiceType, + ClusterIP: clusterIP, + ServicePorts: servicePorts, + Name: workload.Name, + } +} + +func generateServicesFromPortsAnnotation(workload *Workload) ([]Service, error) { + var services []Service + val, ok := workload.TemplateSpec.Annotations[PortsAnnotation] + if !ok { + return services, nil + } + var portList [][]ContainerPort + err := json.Unmarshal([]byte(val), &portList) + if err != nil { + return services, err + } + + svcTypeToPort := map[corev1.ServiceType][]ContainerPort{} + for _, l := range portList { + for _, port := range l { + if port.Kind == "HostPort" { + continue + } + svcType := corev1.ServiceType(port.Kind) + svcTypeToPort[svcType] = append(svcTypeToPort[svcType], port) + } + } + + for svcType, ports := range svcTypeToPort { + servicePorts := map[string][]corev1.ServicePort{} + for _, p := range ports { + var nodePort int32 + var clusterIPPort int32 + if svcType == corev1.ServiceTypeNodePort { + nodePort = int32(p.SourcePort) + clusterIPPort = p.ContainerPort + } else { + if p.SourcePort == 0 { + clusterIPPort = p.ContainerPort + } else { + clusterIPPort = int32(p.SourcePort) + } + } + servicePort := corev1.ServicePort{ + Port: clusterIPPort, + TargetPort: intstr.Parse(strconv.FormatInt(int64(p.ContainerPort), 10)), + NodePort: nodePort, + Protocol: corev1.Protocol(p.Protocol), + Name: p.Name, + } + dnsName := p.DNSName + if dnsName == "" { + dnsName = workload.Name + } + servicePorts[dnsName] = append(servicePorts[dnsName], servicePort) + } + // append default port as sky dns won't work w/o at least one port being set + if len(servicePorts) == 0 { + servicePort := corev1.ServicePort{ + Port: 42, + TargetPort: intstr.Parse(strconv.FormatInt(42, 10)), + Protocol: corev1.Protocol(corev1.ProtocolTCP), + Name: "default", + } + servicePorts[workload.Name] = append(servicePorts[workload.Name], servicePort) + } + + for dnsName, servicePorts := range servicePorts { + services = append(services, Service{ + Type: svcType, + ServicePorts: servicePorts, + Name: dnsName, + }) + } + + } + + return services, nil +} + +func getWorkloadID(objectType string, namespace string, name string) string { + return fmt.Sprintf("%s:%s:%s", objectType, namespace, name) +} + +func (c CommonController) UpdateWorkload(w *Workload, annotations map[string]string) error { + // only annotations updates are supported + switch w.Kind { + case DeploymentType: + o, err := c.DeploymentLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + + _, err = c.Deployments.Update(toUpdate) + if err != nil { + return err + } + case ReplicationControllerType: + o, err := c.ReplicationControllerLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.ReplicationControllers.Update(toUpdate) + if err != nil { + return err + } + case ReplicaSetType: + o, err := c.ReplicaSetLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.ReplicaSets.Update(toUpdate) + if err != nil { + return err + } + case DaemonSetType: + o, err := c.DaemonSetLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.DaemonSets.Update(toUpdate) + if err != nil { + return err + } + case StatefulSetType: + o, err := c.StatefulSetLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.StatefulSets.Update(toUpdate) + if err != nil { + return err + } + case JobType: + o, err := c.JobLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.Jobs.Update(toUpdate) + if err != nil { + return err + } + case CronJobType: + o, err := c.CronJobLister.Get(w.Namespace, w.Name) + if err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + toUpdate := o.DeepCopy() + if toUpdate.Annotations == nil { + toUpdate.Annotations = make(map[string]string) + } + for key, value := range annotations { + toUpdate.Annotations[key] = value + } + _, err = c.CronJobs.Update(toUpdate) + if err != nil { + return err + } + } + return nil +} + +func (c CommonController) EnqueueWorkload(w *Workload) { + switch w.Kind { + case DeploymentType: + c.Deployments.Controller().Enqueue(w.Namespace, w.Name) + case ReplicationControllerType: + c.ReplicationControllers.Controller().Enqueue(w.Namespace, w.Name) + case ReplicaSetType: + c.ReplicaSets.Controller().Enqueue(w.Namespace, w.Name) + case DaemonSetType: + c.DaemonSets.Controller().Enqueue(w.Namespace, w.Name) + case StatefulSetType: + c.StatefulSets.Controller().Enqueue(w.Namespace, w.Name) + case JobType: + c.Jobs.Controller().Enqueue(w.Namespace, w.Name) + case CronJobType: + c.CronJobs.Controller().Enqueue(w.Namespace, w.Name) + } +} + +func (c CommonController) EnqueueAllWorkloads(namespace string) error { + ws, err := c.GetAllWorkloads(namespace) + if err != nil { + return err + } + for _, w := range ws { + c.EnqueueWorkload(w) + } + return nil +} + +func (c CommonController) GetActualFromWorkload(w *Workload) ( + deploy *k8sappv1.Deployment, + rc *corev1.ReplicationController, + rs *k8sappv1.ReplicaSet, + ds *k8sappv1.DaemonSet, + ss *k8sappv1.StatefulSet, + job *corebatchv1.Job, + cj *corebatchv1.CronJob, + err error, +) { + switch w.Kind { + case DeploymentType: + deploy, err = c.DeploymentLister.Get(w.Namespace, w.Name) + case ReplicationControllerType: + rc, err = c.ReplicationControllerLister.Get(w.Namespace, w.Name) + case ReplicaSetType: + rs, err = c.ReplicaSetLister.Get(w.Namespace, w.Name) + case DaemonSetType: + ds, err = c.DaemonSetLister.Get(w.Namespace, w.Name) + case StatefulSetType: + ss, err = c.StatefulSetLister.Get(w.Namespace, w.Name) + case JobType: + job, err = c.JobLister.Get(w.Namespace, w.Name) + case CronJobType: + cj, err = c.CronJobLister.Get(w.Namespace, w.Name) + } + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/catalog/catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/catalog/catalog.go new file mode 100644 index 0000000..9a543d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/catalog/catalog.go @@ -0,0 +1,144 @@ +package catalog + +import ( + "context" + "os" + "path/filepath" + "strings" + "time" + + "github.com/bep/debounce" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type CacheCleaner struct { + catalogClient v3.CatalogInterface + projectCatalogClient v3.ProjectCatalogInterface + clusterCatalogClient v3.ClusterCatalogInterface + debounce func(func()) +} + +func Register(ctx context.Context, context *config.ScaledContext) { + cleaner := &CacheCleaner{ + catalogClient: context.Management.Catalogs(""), + projectCatalogClient: context.Management.ProjectCatalogs(""), + clusterCatalogClient: context.Management.ClusterCatalogs(""), + debounce: debounce.New(time.Minute), + } + go cleaner.runPeriodicCatalogCacheCleaner(ctx, time.Hour) + + context.Management.Catalogs("").Controller().AddHandler(ctx, "catalogCache", cleaner.destroyCatalogSync) + context.Management.ClusterCatalogs("").Controller().AddHandler(ctx, "clusterCatalogCache", cleaner.destroyClusterCatalogSync) + context.Management.ProjectCatalogs("").Controller().AddHandler(ctx, "projectCatalogCache", cleaner.destroyProjectCatalogSync) +} + +func (c *CacheCleaner) runPeriodicCatalogCacheCleaner(ctx context.Context, interval time.Duration) { + c.GoCleanupLogError() + for range ticker.Context(ctx, interval) { + c.GoCleanupLogError() + } +} + +func (c *CacheCleaner) destroyCatalogSync(key string, obj *v3.Catalog) (runtime.Object, error) { + c.debounce(c.GoCleanupLogError) + return nil, nil +} + +func (c *CacheCleaner) destroyClusterCatalogSync(key string, obj *v3.ClusterCatalog) (runtime.Object, error) { + c.debounce(c.GoCleanupLogError) + return nil, nil +} + +func (c *CacheCleaner) destroyProjectCatalogSync(key string, obj *v3.ProjectCatalog) (runtime.Object, error) { + c.debounce(c.GoCleanupLogError) + return nil, nil +} + +func (c *CacheCleaner) GoCleanupLogError() { + go func() { + if err := c.Cleanup(); err != nil { + logrus.Errorf("Catalog-cache cleanup error: %s", err) + } + }() +} + +func (c *CacheCleaner) Cleanup() error { + logrus.Debug("Catalog-cache running cleanup") + + catalogCacheFiles, err := readDirNames(helmlib.CatalogCache) + if err != nil && !os.IsNotExist(err) { + return err + } + iconCacheFiles, err := readDirNames(helmlib.IconCache) + if err != nil && !os.IsNotExist(err) { + return err + } + if len(catalogCacheFiles) == 0 && len(iconCacheFiles) == 0 { + return nil + } + + var catalogHashes = map[string]bool{} + + catalogs, err := c.catalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, catalog := range catalogs.Items { + catalogHashes[helmlib.CatalogSHA256Hash(&catalog)] = true + } + clusterCatalogs, err := c.clusterCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, clusterCatalog := range clusterCatalogs.Items { + catalogHashes[helmlib.CatalogSHA256Hash(&clusterCatalog.Catalog)] = true + } + projectCatalogs, err := c.projectCatalogClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + for _, projectCatalog := range projectCatalogs.Items { + catalogHashes[helmlib.CatalogSHA256Hash(&projectCatalog.Catalog)] = true + } + + var cleanupCount int + cleanupCount += cleanupPath(helmlib.CatalogCache, catalogCacheFiles, catalogHashes) + cleanupCount += cleanupPath(helmlib.IconCache, iconCacheFiles, catalogHashes) + if cleanupCount > 0 { + logrus.Infof("Catalog-cache removed %d entries from disk", cleanupCount) + } + return nil +} + +func readDirNames(dir string) ([]string, error) { + pathFile, err := os.Open(dir) + defer pathFile.Close() + if err != nil { + return nil, err + } + return pathFile.Readdirnames(0) +} + +func cleanupPath(dir string, files []string, valid map[string]bool) int { + var count int + for _, file := range files { + if valid[file] || strings.HasPrefix(file, ".") { + continue + } + + dirFile := filepath.Join(dir, file) + helmlib.Locker.Lock(file) + os.RemoveAll(dirFile) + helmlib.Locker.Unlock(file) + + count++ + logrus.Debugf("Catalog-cache removed entry from disk: %s", dirFile) + } + return count +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/controllers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/controllers.go new file mode 100644 index 0000000..5bf4d04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/controllers.go @@ -0,0 +1,53 @@ +package managementapi + +import ( + "context" + + normanapi "github.com/rancher/norman/api" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/auth" + v3cluster "github.com/rancher/rancher/pkg/controllers/management/cluster" + + "github.com/rancher/rancher/pkg/controllers/managementapi/catalog" + "github.com/rancher/rancher/pkg/controllers/managementapi/dynamicschema" + "github.com/rancher/rancher/pkg/controllers/managementapi/samlconfig" + "github.com/rancher/rancher/pkg/controllers/managementapi/usercontrollers" + whitelistproxyKontainerDriver "github.com/rancher/rancher/pkg/controllers/managementapi/whitelistproxy/kontainerdriver" + whitelistproxyNodeDriver "github.com/rancher/rancher/pkg/controllers/managementapi/whitelistproxy/nodedriver" + "github.com/rancher/rancher/pkg/controllers/managementuser/clusterauthtoken" + "github.com/rancher/rancher/pkg/controllers/managementuser/rbac" + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, scaledContext *config.ScaledContext, clusterManager *clustermanager.Manager, server *normanapi.Server) error { + if err := registerIndexers(scaledContext); err != nil { + return err + } + + catalog.Register(ctx, scaledContext) + dynamicschema.Register(ctx, scaledContext, server.Schemas) + whitelistproxyNodeDriver.Register(ctx, scaledContext) + whitelistproxyKontainerDriver.Register(ctx, scaledContext) + samlconfig.Register(ctx, scaledContext) + usercontrollers.Register(ctx, scaledContext, clusterManager) + return nil +} + +func registerIndexers(scaledContext *config.ScaledContext) error { + if err := clusterauthtoken.RegisterIndexers(scaledContext); err != nil { + return err + } + if err := rbac.RegisterIndexers(scaledContext); err != nil { + return err + } + if err := auth.RegisterIndexers(scaledContext); err != nil { + return err + } + if err := tokens.RegisterIndexer(scaledContext); err != nil { + return err + } + + v3cluster.RegisterIndexers(scaledContext) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/dynamicschema/dynamicschema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/dynamicschema/dynamicschema.go new file mode 100644 index 0000000..45ba137 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/dynamicschema/dynamicschema.go @@ -0,0 +1,96 @@ +package dynamicschema + +import ( + "context" + "sync" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +type Controller struct { + sync.Mutex + Schemas *types.Schemas + lister v3.DynamicSchemaLister + known map[string]bool +} + +func Register(ctx context.Context, management *config.ScaledContext, schemas *types.Schemas) { + c := &Controller{ + Schemas: schemas, + } + management.Management.DynamicSchemas("").AddHandler(ctx, "dynamic-schema", c.Sync) +} + +func (c *Controller) Sync(key string, dynamicSchema *v3.DynamicSchema) (runtime.Object, error) { + c.Lock() + defer c.Unlock() + + if dynamicSchema == nil { + return nil, c.remove(key) + } + + return nil, c.add(dynamicSchema) +} + +func (c *Controller) remove(id string) error { + schema := c.Schemas.Schema(&managementSchema.Version, id) + if schema != nil { + c.Schemas.RemoveSchema(*schema) + } + return nil +} + +func (c *Controller) add(dynamicSchema *v3.DynamicSchema) error { + schema := types.Schema{} + if err := convert.ToObj(dynamicSchema.Spec, &schema); err != nil { + return err + } + + for name, field := range schema.ResourceFields { + defMap, ok := field.Default.(map[string]interface{}) + if !ok { + continue + } + + // set to nil because if map is len() == 0 + field.Default = nil + + switch field.Type { + case "string", "password": + field.Default = defMap["stringValue"] + case "int": + field.Default = defMap["intValue"] + case "boolean": + field.Default = defMap["boolValue"] + case "array[string]": + field.Default = defMap["stringSliceValue"] + } + + field.DynamicField = true + + schema.ResourceFields[name] = field + } + + // we need to maintain backwards compatibility with older dynamic schemas that were created before we had the + // schema name field + if dynamicSchema.Spec.SchemaName != "" { + schema.ID = dynamicSchema.Spec.SchemaName + } else { + schema.ID = dynamicSchema.Name + } + schema.Version = managementSchema.Version + schema.DynamicSchemaVersion = dynamicSchema.ResourceVersion + + if schema.Embed { + c.Schemas.AddSchema(schema) + } else { + c.Schemas.ForceAddSchema(schema) + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/samlconfig/samlconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/samlconfig/samlconfig.go new file mode 100644 index 0000000..ddb7107 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/samlconfig/samlconfig.go @@ -0,0 +1,75 @@ +package samlconfig + +import ( + "context" + "fmt" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/saml" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type authProvider struct { + authConfigs v3.AuthConfigInterface + secrets corev1.SecretInterface +} + +func Register(ctx context.Context, apiContext *config.ScaledContext) { + a := newAuthProvider(apiContext) + apiContext.Management.AuthConfigs("").AddHandler(ctx, "authConfigController", a.sync) +} + +func newAuthProvider(apiContext *config.ScaledContext) *authProvider { + a := &authProvider{ + authConfigs: apiContext.Management.AuthConfigs(""), + secrets: apiContext.Core.Secrets(""), + } + return a +} + +func (a *authProvider) sync(key string, config *v3.AuthConfig) (runtime.Object, error) { + samlConfig := &v32.SamlConfig{} + if key == "" || config == nil { + return nil, nil + } + + if config.Name != saml.PingName && config.Name != saml.ADFSName && config.Name != saml.KeyCloakName && + config.Name != saml.OKTAName && config.Name != saml.ShibbolethName { + return nil, nil + } + + if !config.Enabled { + return nil, nil + } + + authConfigObj, err := a.authConfigs.ObjectClient().UnstructuredClient().Get(config.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to retrieve SamlConfig, error: %v", err) + } + + u, ok := authConfigObj.(runtime.Unstructured) + if !ok { + return nil, fmt.Errorf("failed to retrieve SamlConfig, cannot read k8s Unstructured data") + } + storedSamlConfigMap := u.UnstructuredContent() + err = common.Decode(storedSamlConfigMap, samlConfig) + if err != nil { + return nil, fmt.Errorf("unable to decode Azure Config: %w", err) + } + + if samlConfig.SpKey != "" { + value, err := common.ReadFromSecret(a.secrets, samlConfig.SpKey, "spkey") + + if err != nil { + return nil, err + } + samlConfig.SpKey = value + } + + return nil, saml.InitializeSamlServiceProvider(samlConfig, config.Name) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller.go new file mode 100644 index 0000000..def9b32 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller.go @@ -0,0 +1,260 @@ +package usercontrollers + +import ( + "context" + "fmt" + "hash/crc32" + "math" + "sort" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + v33 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/clustermanager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/metrics" + tpeermanager "github.com/rancher/rancher/pkg/peermanager" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/version" +) + +// currentClusterControllersVersion is the version of the controllers that are run in the local cluster for a particular downstream cluster. +const currentClusterControllersVersion = "management.cattle.io/current-cluster-controllers-version" + +// Register adds the user-controllers-controller handler and starts the peer manager. +func Register(ctx context.Context, scaledContext *config.ScaledContext, clusterManager *clustermanager.Manager) { + u := &userControllersController{ + starter: clusterManager, + clusterLister: scaledContext.Management.Clusters("").Controller().Lister(), + clusters: scaledContext.Management.Clusters(""), + clustered: scaledContext.PeerManager != nil, + ctx: ctx, + start: time.Now(), + } + + scaledContext.Management.Clusters("").AddHandler(ctx, "user-controllers-controller", u.sync) + + if scaledContext.PeerManager != nil { + c := make(chan tpeermanager.Peers, 100) + scaledContext.PeerManager.AddListener(c) + + go func() { + for peer := range c { + if err := u.setPeers(&peer); err != nil { + logrus.Errorf("Failed syncing peers [%v]: %v", peer, err) + } + } + }() + + go func() { + <-ctx.Done() + scaledContext.PeerManager.RemoveListener(c) + close(c) + }() + } + + go func() { + for { + select { + case <-ctx.Done(): + return + case <-time.After(5 * time.Second): + if err := u.setPeers(nil); err == nil { + time.Sleep(2 * time.Minute) + } + } + } + }() +} + +// controllerStarter starts and stops controllers for a given cluster. +type controllerStarter interface { + Start(ctx context.Context, cluster *v3.Cluster, clusterOwner bool) error + Stop(cluster *v3.Cluster) +} + +type userControllersController struct { + sync.Mutex + clustered bool + starter controllerStarter + clusterLister v3.ClusterLister + clusters v3.ClusterInterface + ctx context.Context + peers tpeermanager.Peers + start time.Time +} + +func (u *userControllersController) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster != nil && cluster.DeletionTimestamp != nil { + err := u.cleanFinalizers(key, cluster) + if err != nil { + return nil, fmt.Errorf("userControllersController: failed to clean finalizers for cluster %s: %w", cluster.Name, err) + } + } + if key == relatedresource.AllKey { + err := u.setPeers(nil) + if err != nil { + return nil, fmt.Errorf("userControllersController: failed to set peers for key %s: %w", key, err) + } + return nil, nil + } + + // Check if the cluster has been upgraded to a major or minor version and restart the controllers. + if cluster != nil && cluster.Status.Version != nil { + var err error + currentVersion, err := getCurrentClusterControllersVersion(cluster) + // If the version is not found on the annotation, set it and update the cluster object. + var clusterCopy *v3.Cluster + if err != nil { + if clusterCopy, err = u.saveClusterControllersVersionAnnotation(cluster, cluster.Status.Version.String()); err != nil { + return nil, fmt.Errorf("userControllersController: failed to save version annotation for cluster %s: %w", cluster.Name, err) + } + cluster = clusterCopy + u.clusters.Controller().Enqueue("", relatedresource.AllKey) + return cluster, nil + } + + newVersion, err := version.ParseSemantic(cluster.Status.Version.String()) + if err != nil { + logrus.Errorf("failed to parse the K8s version of the upgraded cluster %s, will not restart cluster controllers: %v", cluster.Name, err) + u.clusters.Controller().Enqueue("", relatedresource.AllKey) + return cluster, nil + } + + if !clusterVersionChanged(currentVersion, newVersion) { + u.clusters.Controller().Enqueue("", relatedresource.AllKey) + return cluster, nil + } + + u.starter.Stop(cluster) + err = u.starter.Start(u.ctx, cluster, u.amOwner(u.peers, cluster)) + if err != nil { + return nil, fmt.Errorf("userControllersController: unable to restart controllers for cluster %s: %w", cluster.Name, err) + } + if clusterCopy, err = u.saveClusterControllersVersionAnnotation(cluster, newVersion.String()); err != nil { + return nil, fmt.Errorf("userControllersController: failed to save new version annotation for cluster %s: %w", cluster.Name, err) + } + cluster = clusterCopy + } + + u.clusters.Controller().Enqueue("", relatedresource.AllKey) + return cluster, nil +} + +// saveClusterControllersVersionAnnotation updates and persists a cluster object with a given value for the annotation +// that indicates the cluster controllers' version. It does not matter if the provided version starts with a "v" or doesn't, +// as it's parsed the same by other code. +func (u *userControllersController) saveClusterControllersVersionAnnotation(cluster *v3.Cluster, value string) (*v3.Cluster, error) { + cluster = cluster.DeepCopy() + cluster.Annotations[currentClusterControllersVersion] = value + cluster, err := u.clusters.Update(cluster) + if err != nil { + return nil, fmt.Errorf("unable to update cluster %s with annotation indicating its K8s version: %w", cluster.Name, err) + } + return cluster, nil +} + +func getCurrentClusterControllersVersion(cluster *v3.Cluster) (*version.Version, error) { + v := cluster.Annotations[currentClusterControllersVersion] + return version.ParseSemantic(v) +} + +// clusterVersionChanged checks if the two given cluster versions differ in the major or minor levels. +func clusterVersionChanged(current, new *version.Version) bool { + return current.Major() != new.Major() || current.Minor() != new.Minor() +} + +func (u *userControllersController) setPeers(peers *tpeermanager.Peers) error { + u.Lock() + defer u.Unlock() + + if peers != nil { + u.peers = *peers + u.peers.IDs = append(u.peers.IDs, u.peers.SelfID) + sort.Strings(u.peers.IDs) + } + + return u.peersSync() +} + +func (u *userControllersController) peersSync() error { + clusters, err := u.clusterLister.List("", labels.Everything()) + if err != nil { + return err + } + + var ( + errs []error + ) + + for _, cluster := range clusters { + if cluster.DeletionTimestamp != nil || !v33.ClusterConditionProvisioned.IsTrue(cluster) { + u.starter.Stop(cluster) + } else { + amOwner := u.amOwner(u.peers, cluster) + if amOwner { + metrics.SetClusterOwner(u.peers.SelfID, cluster.Name) + } else { + metrics.UnsetClusterOwner(u.peers.SelfID, cluster.Name) + } + if err := u.starter.Start(u.ctx, cluster, amOwner); err != nil { + errs = append(errs, errors.Wrapf(err, "failed to start user controllers for cluster %s", cluster.Name)) + } + } + } + + return types.NewErrors(errs...) +} + +func (u *userControllersController) amOwner(peers tpeermanager.Peers, cluster *v3.Cluster) bool { + if !u.clustered { + return true + } + + if !peers.Ready || len(peers.IDs) == 0 || (len(peers.IDs) == 1 && !peers.Leader) { + return false + } + + ck := crc32.ChecksumIEEE([]byte(cluster.UID)) + if ck == math.MaxUint32 { + ck-- + } + + scaled := int(ck) * len(peers.IDs) / math.MaxUint32 + logrus.Debugf("%s(%v): (%v * %v) / %v = %v[%v] = %v, self = %v\n", cluster.Name, cluster.UID, ck, + uint32(len(peers.IDs)), math.MaxUint32, peers.IDs, scaled, peers.IDs[scaled], peers.SelfID) + return peers.IDs[scaled] == peers.SelfID +} + +func (u *userControllersController) cleanFinalizers(key string, cluster *v3.Cluster) error { + c, err := u.clusters.Get(key, metav1.GetOptions{}) + if err != nil { + return err + } + + var updated bool + var newFinalizers []string + + for _, finalizer := range c.ObjectMeta.Finalizers { + if finalizer == "controller.cattle.io/cluster-agent-controller" { + updated = true + continue + } + newFinalizers = append(newFinalizers, finalizer) + } + + if updated { + c.ObjectMeta.Finalizers = newFinalizers + _, err = u.clusters.Update(c) + return err + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller_test.go new file mode 100644 index 0000000..a95153e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/usercontrollers/usercontroller_test.go @@ -0,0 +1,261 @@ +package usercontrollers + +import ( + "context" + "errors" + "testing" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/version" +) + +func newMockUserControllersController(starter *simpleControllerStarter) *userControllersController { + mockClusterController := &fakes.ClusterControllerMock{ + EnqueueFunc: func(namespace string, name string) {}, + } + return &userControllersController{ + starter: starter, + clusterLister: &fakes.ClusterListerMock{}, + clusters: &fakes.ClusterInterfaceMock{ + ControllerFunc: func() v3.ClusterController { + return mockClusterController + }, + UpdateFunc: func(c *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if c.Name == "bad cluster" { + return c, errors.New("failed to update the cluster object") + } + return c, nil + }, + }, + } +} + +type simpleControllerStarter struct { + startCalled bool + stopCalled bool +} + +func (s *simpleControllerStarter) Start(ctx context.Context, c *v3.Cluster, clusterOwner bool) error { + if c.Name == "nonstarter cluster" { + return errors.New("failed to start the cluster controllers") + } + s.startCalled = true + return nil +} + +func (s *simpleControllerStarter) Stop(cluster *v3.Cluster) { + s.stopCalled = true +} + +func TestAnnotationFailsToBeSaved(t *testing.T) { + t.Parallel() + t.Run("initial annotation fails to be saved", func(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bad cluster", + Annotations: map[string]string{}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + } + + obj, err := controller.sync("", cluster) + require.Error(t, err) + require.Nil(t, obj) + assert.False(t, starter.startCalled) + assert.False(t, starter.stopCalled) + }) + + t.Run("new annotation fails to be saved after controllers restart", func(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "bad cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.22.0"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + } + + obj, err := controller.sync("", cluster) + require.Error(t, err) + require.Nil(t, obj) + assert.True(t, starter.startCalled) + assert.True(t, starter.stopCalled) + }) +} + +func TestClusterControllerFailsToRestart(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "nonstarter cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.22.0"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + } + + obj, err := controller.sync("", cluster) + require.Error(t, err) + require.Nil(t, obj) + assert.True(t, starter.stopCalled) + assert.False(t, starter.startCalled) +} + +func TestClusterWithoutControllersVersionAnnotationGetsUpdated(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + } + + obj, err := controller.sync("", cluster) + require.NoError(t, err) + require.NotNil(t, obj) + assert.Equal(t, "1.23.4", obj.(*v3.Cluster).Annotations[currentClusterControllersVersion]) + assert.False(t, starter.startCalled) + assert.False(t, starter.stopCalled) +} + +func TestClusterControllersNotRestartedOnPatchVersionChange(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.23.0"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.1"}, + }, + } + + obj, err := controller.sync("", cluster) + require.NoError(t, err) + require.NotNil(t, obj) + + // The annotation is also not updated. + assert.Equal(t, "1.23.0", obj.(*v3.Cluster).Annotations[currentClusterControllersVersion]) + + assert.False(t, starter.startCalled) + assert.False(t, starter.stopCalled) +} + +func TestClusterControllersWereStoppedAndStartedOnVersionChange(t *testing.T) { + t.Parallel() + t.Run("cluster version moved up", func(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.23.4"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.25.2"}, + }, + } + + obj, err := controller.sync("", cluster) + require.NoError(t, err) + require.NotNil(t, obj) + assert.Equal(t, "1.25.2", obj.(*v3.Cluster).Annotations[currentClusterControllersVersion]) + assert.True(t, starter.startCalled) + assert.True(t, starter.stopCalled) + }) + + t.Run("cluster version moved down", func(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + cluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.23.4"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.22.1"}, + }, + } + + obj, err := controller.sync("", cluster) + require.NoError(t, err) + require.NotNil(t, obj) + assert.Equal(t, "1.22.1", obj.(*v3.Cluster).Annotations[currentClusterControllersVersion]) + assert.True(t, starter.startCalled) + assert.True(t, starter.stopCalled) + }) +} + +func TestClusterControllerEnqueuesControllers(t *testing.T) { + t.Parallel() + tests := []struct { + name string + cluster *v3.Cluster + }{ + { + name: "nil cluster enqueues all controllers", + cluster: nil, + }, + { + name: "same version cluster enqueues all controllers", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{currentClusterControllersVersion: "1.23.4"}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + }, + }, + { + name: "new cluster enqueues all controllers", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster", + Annotations: map[string]string{}, + }, + Status: apimgmtv3.ClusterStatus{ + Version: &version.Info{GitVersion: "1.23.4"}, + }, + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + starter := simpleControllerStarter{} + controller := newMockUserControllersController(&starter) + _, err := controller.sync("", test.cluster) + require.NoError(t, err) + assert.Equal(t, 1, len(controller.clusters.Controller().(*fakes.ClusterControllerMock).EnqueueCalls())) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/kontainerdriver/kontainerdriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/kontainerdriver/kontainerdriver.go new file mode 100644 index 0000000..66d835a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/kontainerdriver/kontainerdriver.go @@ -0,0 +1,31 @@ +package kontainerdriver + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/multiclustermanager/whitelist" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +func Register(ctx context.Context, management *config.ScaledContext) { + management.Management.KontainerDrivers("").AddHandler(ctx, "whitelist-proxy", sync) +} + +func sync(key string, kontainerDriver *v3.KontainerDriver) (runtime.Object, error) { + if key == "" || kontainerDriver == nil { + return nil, nil + } + if kontainerDriver.DeletionTimestamp != nil { + for _, d := range kontainerDriver.Spec.WhitelistDomains { + whitelist.Proxy.Rm(d) + } + return nil, nil + } + + for _, d := range kontainerDriver.Spec.WhitelistDomains { + whitelist.Proxy.Add(d) + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/nodedriver/nodedriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/nodedriver/nodedriver.go new file mode 100644 index 0000000..b5684bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementapi/whitelistproxy/nodedriver/nodedriver.go @@ -0,0 +1,31 @@ +package nodedriver + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/multiclustermanager/whitelist" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +func Register(ctx context.Context, management *config.ScaledContext) { + management.Management.NodeDrivers("").AddHandler(ctx, "whitelist-proxy", sync) +} + +func sync(key string, nodeDriver *v3.NodeDriver) (runtime.Object, error) { + if key == "" || nodeDriver == nil { + return nil, nil + } + if nodeDriver.DeletionTimestamp != nil { + for _, d := range nodeDriver.Spec.WhitelistDomains { + whitelist.Proxy.Rm(d) + } + return nil, nil + } + + for _, d := range nodeDriver.Spec.WhitelistDomains { + whitelist.Proxy.Add(d) + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/catalog/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/catalog/controller.go new file mode 100644 index 0000000..320ecd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/catalog/controller.go @@ -0,0 +1,105 @@ +package catalog + +import ( + "context" + "os" + "path" + "time" + + "github.com/rancher/rancher/pkg/catalog/manager" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" + + "k8s.io/apimachinery/pkg/labels" +) + +func Register(ctx context.Context, management *config.ManagementContext) { + // remove old disk cache + oldCache := path.Join("management-state", "catalog-controller") + os.RemoveAll(oldCache) + + // TODO: Get values from settings + if err := Run(ctx, 3600, management); err != nil { + panic(err) + } +} + +func runRefreshCatalog(ctx context.Context, interval int, controller v3.CatalogController, m *manager.Manager) { + for range ticker.Context(ctx, time.Duration(interval)*time.Second) { + catalogs, err := m.CatalogLister.List("", labels.NewSelector()) + if err != nil { + logrus.Error(err) + continue + } + for _, catalog := range catalogs { + controller.Enqueue("", catalog.Name) + } + } +} + +func runRefreshProjectCatalog(ctx context.Context, interval int, controller v3.ProjectCatalogController, m *manager.Manager) { + for range ticker.Context(ctx, time.Duration(interval)*time.Second) { + projectCatalogs, err := m.ProjectCatalogLister.List("", labels.NewSelector()) + if err != nil { + logrus.Error(err) + continue + } + for _, pc := range projectCatalogs { + controller.Enqueue(pc.Namespace, pc.Name) + } + } +} + +func runRefreshClusterCatalog(ctx context.Context, interval int, controller v3.ClusterCatalogController, m *manager.Manager) { + for range ticker.Context(ctx, time.Duration(interval)*time.Second) { + clusterCatalogs, err := m.ClusterCatalogLister.List("", labels.NewSelector()) + if err != nil { + logrus.Error(err) + continue + } + for _, cc := range clusterCatalogs { + controller.Enqueue(cc.Namespace, cc.Name) + } + } +} + +func doUntilSucceeds(ctx context.Context, retryPeriod time.Duration, f func() bool) { + for { + if f() { + return + } + select { + case <-time.After(retryPeriod): + case <-ctx.Done(): + return + } + } +} + +func Run(ctx context.Context, refreshInterval int, management *config.ManagementContext) error { + logrus.Infof("Starting catalog controller") + m := manager.New(management.Management, management.Project, management.Core) + + controller := management.Management.Catalogs("").Controller() + controller.AddHandler(ctx, "catalog", m.Sync) + + logrus.Infof("Starting project-level catalog controller") + projectCatalogController := management.Management.ProjectCatalogs("").Controller() + projectCatalogController.AddHandler(ctx, "projectCatalog", m.ProjectCatalogSync) + + logrus.Infof("Starting cluster-level catalog controller") + clusterCatalogController := management.Management.ClusterCatalogs("").Controller() + clusterCatalogController.AddHandler(ctx, "clusterCatalog", m.ClusterCatalogSync) + + var failureRetryPeriod = 15 * time.Minute + go doUntilSucceeds(ctx, failureRetryPeriod, m.DeleteOldTemplateContent) + go doUntilSucceeds(ctx, failureRetryPeriod, m.DeleteBadCatalogTemplates) + + go runRefreshCatalog(ctx, refreshInterval, controller, m) + go runRefreshProjectCatalog(ctx, refreshInterval, projectCatalogController, m) + go runRefreshClusterCatalog(ctx, refreshInterval, clusterCatalogController, m) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/common.go new file mode 100644 index 0000000..ea65475 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/common.go @@ -0,0 +1,123 @@ +package common + +import ( + "strings" + + "github.com/rancher/norman/clientbase" + "github.com/rancher/norman/types" +) + +func SortSchema(schemas map[string]types.Schema) []string { + inserted := map[string]bool{} + result := []string{} + for i := 0; i < 100; i++ { + for k, schema := range schemas { + if inserted[k] { + continue + } + ready := true + for fieldName, field := range schema.ResourceFields { + if strings.Contains(field.Type, "reference") { + reference := GetReference(field.Type) + if isNamespaceIDRef(reference, k) { + continue + } + if !inserted[reference] && fieldName != "creatorId" && k != reference { + ready = false + } + } + } + if ready { + inserted[k] = true + result = append(result, k) + } + } + } + return result +} + +var ( + namespacedSchema = map[string]bool{ + "project": true, + } +) + +func isNamespaceIDRef(ref, schemaType string) bool { + if ref == "namespace" && namespacedSchema[schemaType] { + return true + } + return false +} + +func GetReference(name string) string { + name = strings.TrimSuffix(strings.TrimPrefix(name, "array["), "]") + r := strings.TrimSuffix(strings.TrimPrefix(name, "reference["), "]") + return strings.TrimPrefix(strings.TrimPrefix(strings.TrimPrefix(r, "/v3/schemas/"), "/v3/clusters/schemas/"), "/v3/projects/schemas/") +} + +// ReplaceGlobalReference replace name to id +func ReplaceGlobalReference(schema types.Schema, data map[string]interface{}, referenceMap map[string]map[string]string, client *clientbase.APIBaseClient) error { + for key, field := range schema.ResourceFields { + if strings.Contains(field.Type, "reference") { + reference := GetReference(field.Type) + if _, ok := data[key]; !ok { + continue + } + if err := FillInReferenceMap(client, reference, referenceMap, nil); err != nil { + return err + } + if strings.HasPrefix(field.Type, "array") { + r := []string{} + for _, k := range data[key].([]interface{}) { + r = append(r, referenceMap[reference][k.(string)]) + } + data[key] = r + } else { + if referenceMap[reference][data[key].(string)] != "" { + data[key] = referenceMap[reference][data[key].(string)] + } + } + } + } + return nil +} + +func FillInReferenceMap(client *clientbase.APIBaseClient, schemaKey string, referenceMap map[string]map[string]string, filter map[string]string) error { + if _, ok := referenceMap[schemaKey]; ok { + return nil + } + referenceMap[schemaKey] = map[string]string{} + respObj := map[string]interface{}{} + if err := client.List(schemaKey, &types.ListOpts{}, &respObj); err != nil { + return err + } + if data, ok := respObj["data"]; ok { + if collections, ok := data.([]interface{}); ok { + for _, obj := range collections { + if objMap, ok := obj.(map[string]interface{}); ok { + id := GetValue(objMap, "id") + name := GetValue(objMap, "name") + filtered := true + for k, v := range filter { + if GetValue(objMap, k) != v { + filtered = false + } + } + if filtered { + referenceMap[schemaKey][name] = id + } + } + } + } + } + return nil +} + +func GetValue(data map[string]interface{}, key string) string { + if v, ok := data[key]; ok { + if _, ok := v.(string); ok { + return v.(string) + } + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/port_getter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/port_getter.go new file mode 100644 index 0000000..683f3eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/common/port_getter.go @@ -0,0 +1,8 @@ +package common + +import clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + +type KubeConfigGetter interface { + KubeConfig(clusterName, token string) *clientcmdapi.Config + GetHTTPSPort() int +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/controller.go new file mode 100644 index 0000000..ffc745e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/compose/controller.go @@ -0,0 +1,332 @@ +package compose + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + "github.com/rancher/norman/clientbase" + "github.com/rancher/norman/controller" + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/auth/tokens" + clusterClient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3" + projectClient "github.com/rancher/rancher/pkg/client/generated/project/v3" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/compose/common" + "github.com/rancher/rancher/pkg/generated/compose" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + composeTokenPrefix = "compose-token-" + description = "token for compose" + url = "https://localhost:%v/v3" +) + +// Lifecycle for GlobalComposeConfig is a controller which watches composeConfig and execute the yaml config and create a bunch of global resources. There is no sync logic between yaml file and resources, which means config is only executed once. And resource is not deleted even if the compose config is deleted. +type Lifecycle struct { + TokenClient v3.TokenInterface + UserClient v3.UserInterface + systemTokens systemtokens.Interface + UserManager user.Manager + HTTPSPortGetter common.KubeConfigGetter + ComposeClient v3.ComposeConfigInterface +} + +func Register(ctx context.Context, managementContext *config.ManagementContext, portGetter common.KubeConfigGetter) { + composeClient := managementContext.Management.ComposeConfigs("") + tokenClient := managementContext.Management.Tokens("") + userClient := managementContext.Management.Users("") + l := Lifecycle{ + systemTokens: managementContext.SystemTokens, + HTTPSPortGetter: portGetter, + UserManager: managementContext.UserManager, + TokenClient: tokenClient, + UserClient: userClient, + ComposeClient: composeClient, + } + composeClient.AddHandler(ctx, "compose-controller", l.sync) +} + +func (l Lifecycle) sync(key string, obj *v3.ComposeConfig) (runtime.Object, error) { + if key == "" || obj == nil { + return nil, nil + } + newObj, err := v32.ComposeConditionExecuted.Once(obj, func() (runtime.Object, error) { + obj, err := l.Create(obj) + if err != nil { + return obj, &controller.ForgetError{ + Err: err, + } + } + return obj, nil + }) + + obj, _ = l.ComposeClient.Update(newObj.(*v3.ComposeConfig)) + return obj, err +} + +func (l Lifecycle) Create(obj *v3.ComposeConfig) (*v3.ComposeConfig, error) { + userID := obj.Annotations["field.cattle.io/creatorId"] + user, err := l.UserClient.Get(userID, metav1.GetOptions{}) + if err != nil { + return obj, err + } + tokenPrefix := composeTokenPrefix + user.Name + token, err := l.systemTokens.EnsureSystemToken(tokenPrefix, description, "compose", user.Name, nil, true) + if err != nil { + return obj, err + } + tokenName, _ := tokens.SplitTokenParts(token) + defer func() { + if err := l.systemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for compose token [%s] failed, will not retry: %v", tokenName, err) + } + }() + + config := &compose.Config{} + if err := yaml.Unmarshal([]byte(obj.Spec.RancherCompose), config); err != nil { + return obj, err + } + if err := up(token, l.HTTPSPortGetter.GetHTTPSPort(), config); err != nil { + return obj, err + } + v32.ComposeConditionExecuted.True(obj) + return obj, nil +} + +func GetSchemas(token string, port int) (map[string]types.Schema, map[string]types.Schema, map[string]types.Schema, error) { + cc, err := clusterClient.NewClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port) + "/clusters", + TokenKey: token, + Insecure: true, + }) + if err != nil { + return nil, nil, nil, err + } + mc, err := managementClient.NewClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port), + TokenKey: token, + Insecure: true, + }) + if err != nil { + return nil, nil, nil, err + } + pc, err := projectClient.NewClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port) + "/projects", + TokenKey: token, + Insecure: true, + }) + if err != nil { + return nil, nil, nil, err + } + return cc.Types, mc.Types, pc.Types, nil +} + +func up(token string, port int, config *compose.Config) error { + clusterSchemas, managementSchemas, projectSchemas, err := GetSchemas(token, port) + if err != nil { + return err + } + + // referenceMap is a map of schemaType with name -> id value + referenceMap := map[string]map[string]string{} + + rawData, err := json.Marshal(config) + if err != nil { + return err + } + rawMap := map[string]interface{}{} + if err := json.Unmarshal(rawData, &rawMap); err != nil { + return err + } + delete(rawMap, "version") + allSchemas := getAllSchemas(clusterSchemas, managementSchemas, projectSchemas) + sortedSchemas := common.SortSchema(allSchemas) + + baseClusterClient, err := clientbase.NewAPIClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port) + "/cluster", + TokenKey: token, + Insecure: true, + }) + if err != nil { + return err + } + baseManagementClient, err := clientbase.NewAPIClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port), + TokenKey: token, + Insecure: true, + }) + if err != nil { + return err + } + baseProjectClient, err := clientbase.NewAPIClient(&clientbase.ClientOpts{ + URL: fmt.Sprintf(url, port) + "/project", + TokenKey: token, + Insecure: true, + }) + if err != nil { + return err + } + baseURL := fmt.Sprintf(url, port) + configManager := configClientManager{ + clusterSchemas: clusterSchemas, + managementSchemas: managementSchemas, + projectSchemas: projectSchemas, + baseClusterClient: &baseClusterClient, + baseManagementClient: &baseManagementClient, + baseProjectClient: &baseProjectClient, + baseURL: baseURL, + } + + for _, schemaKey := range sortedSchemas { + key := allSchemas[schemaKey].PluralName + v, ok := rawMap[key] + if !ok { + continue + } + value, ok := v.(map[string]interface{}) + if !ok { + continue + } + var baseClient *clientbase.APIBaseClient + for name, data := range value { + dataMap, ok := data.(map[string]interface{}) + if !ok { + break + } + baseClient, err = configManager.ConfigBaseClient(schemaKey, dataMap, referenceMap, "") + if err != nil { + return err + } + if err := common.ReplaceGlobalReference(allSchemas[schemaKey], dataMap, referenceMap, &baseManagementClient); err != nil { + return err + } + clusterID := convert.ToString(dataMap["clusterId"]) + baseClient, err = configManager.ConfigBaseClient(schemaKey, dataMap, referenceMap, clusterID) + if err != nil { + return err + } + dataMap["name"] = name + respObj := map[string]interface{}{} + // in here we have to make sure the same name won't be created twice + created := map[string]string{} + if err := baseClient.List(schemaKey, &types.ListOpts{}, &respObj); err != nil { + return err + } + if data, ok := respObj["data"]; ok { + if collections, ok := data.([]interface{}); ok { + for _, obj := range collections { + if objMap, ok := obj.(map[string]interface{}); ok { + createdName := common.GetValue(objMap, "name") + if createdName != "" { + created[createdName] = common.GetValue(objMap, "id") + } + } + } + } + } + + id := "" + if v, ok := created[name]; ok { + id = v + existing := &types.Resource{} + if err := baseClient.ByID(schemaKey, id, existing); err != nil { + return err + } + if err := baseClient.Update(schemaKey, existing, dataMap, nil); err != nil { + return err + } + } else { + if err := baseClient.Create(schemaKey, dataMap, &respObj); err != nil && !strings.Contains(err.Error(), "already exist") { + return err + } else if err != nil && strings.Contains(err.Error(), "already exist") { + break + } + v, ok := respObj["id"] + if !ok { + return errors.Errorf("id is missing after creating %s obj", schemaKey) + } + id = v.(string) + } + } + // fill in reference map name -> id + if err := common.FillInReferenceMap(baseClient, schemaKey, referenceMap, nil); err != nil { + return err + } + } + return nil +} + +type configClientManager struct { + clusterSchemas map[string]types.Schema + managementSchemas map[string]types.Schema + projectSchemas map[string]types.Schema + baseClusterClient *clientbase.APIBaseClient + baseManagementClient *clientbase.APIBaseClient + baseProjectClient *clientbase.APIBaseClient + baseURL string +} + +// GetBaseClient config a baseClient with a special base url based on schema type +func (c configClientManager) ConfigBaseClient(schemaType string, data map[string]interface{}, referenceMap map[string]map[string]string, clusterID string) (*clientbase.APIBaseClient, error) { + if _, ok := c.clusterSchemas[schemaType]; ok { + c.baseClusterClient.Opts.URL = c.baseURL + fmt.Sprintf("/cluster/%s", clusterID) + return c.baseClusterClient, nil + } + + if _, ok := c.managementSchemas[schemaType]; ok { + return c.baseManagementClient, nil + } + + if _, ok := c.projectSchemas[schemaType]; ok { + projectName := common.GetValue(data, "projectId") + if _, ok := referenceMap["project"]; !ok { + filter := map[string]string{ + "clusterId": clusterID, + } + if err := common.FillInReferenceMap(c.baseManagementClient, "project", referenceMap, filter); err != nil { + return nil, err + } + } + projectID := referenceMap["project"][projectName] + c.baseProjectClient.Opts.URL = c.baseURL + fmt.Sprintf("/projects/%s", projectID) + return c.baseProjectClient, nil + } + return nil, errors.Errorf("schema type %s not supported", schemaType) +} + +func getAllSchemas(clusterSchemas, managementSchemas, projectSchemas map[string]types.Schema) map[string]types.Schema { + r := map[string]types.Schema{} + for k, schema := range clusterSchemas { + if _, ok := schema.ResourceFields["creatorId"]; !ok { + continue + } + r[k] = schema + } + for k, schema := range managementSchemas { + if _, ok := schema.ResourceFields["creatorId"]; !ok { + continue + } + r[k] = schema + } + for k, schema := range projectSchemas { + if _, ok := schema.ResourceFields["creatorId"]; !ok { + continue + } + r[k] = schema + } + return r +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/controller.go new file mode 100644 index 0000000..2c15a8e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/controller.go @@ -0,0 +1,19 @@ +package managementlegacy + +import ( + "context" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/catalog" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/compose" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/globaldns" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/multiclusterapp" + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, management *config.ManagementContext, manager *clustermanager.Manager) { + catalog.Register(ctx, management) + compose.Register(ctx, management, manager) + globaldns.Register(ctx, management) + multiclusterapp.Register(ctx, management, manager) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldns_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldns_handler.go new file mode 100644 index 0000000..ac04100 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldns_handler.go @@ -0,0 +1,377 @@ +package globaldns + +import ( + "context" + "fmt" + "net" + "strconv" + "strings" + + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + + "github.com/rancher/rancher/pkg/ingresswrapper" + kextv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + GlobaldnsController = "mgmt-global-dns-controller" + annotationIngressClass = "kubernetes.io/ingress.class" + annotationFilter = "annotationFilter" + annotationDNSTTL = "external-dns.alpha.kubernetes.io/ttl" + defaultIngressClass = "rancher-external-dns" +) + +type GDController struct { + ingresses ingresswrapper.CompatClient + managementContext *config.ManagementContext + globalDNSProviderLister v3.GlobalDnsProviderLister +} + +func newGlobalDNSController(ctx context.Context, mgmt *config.ManagementContext) *GDController { + + n := &GDController{ + ingresses: ingresswrapper.NewCompatClient(mgmt.K8sClient, namespace.GlobalNamespace), + managementContext: mgmt, + globalDNSProviderLister: mgmt.Management.GlobalDnsProviders(namespace.GlobalNamespace).Controller().Lister(), + } + return n +} + +// sync is called periodically and on real updates +func (n *GDController) sync(key string, obj *v3.GlobalDns) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + metaAccessor, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return nil, fmt.Errorf("GlobalDNS %v has no creatorId annotation", metaAccessor.GetName()) + } + + if err := rbac.CreateRoleAndRoleBinding(rbac.GlobalDNSResource, v3.GlobalDnsGroupVersionKind.Kind, obj.Name, namespace.GlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + obj.UID, obj.Spec.Members, n.managementContext); err != nil { + return nil, err + } + //check if status.endpoints is set, if yes create a dummy ingress if not already present + //if ingress exists, update endpoints if different + + var isUpdate bool + + //check if ingress for this globaldns is already present + ingress, err := n.getIngressForGlobalDNS(obj) + + if err != nil && !k8serrors.IsNotFound(err) { + return nil, fmt.Errorf("GlobalDNSController: Error listing ingress for the GlobalDNS %v", err) + } + + if ingress != nil && err == nil { + isUpdate = true + } + + if len(obj.Status.Endpoints) == 0 && !isUpdate { + return nil, nil + } + + if !isUpdate { + ingress, err = n.createIngressForGlobalDNS(obj) + if err != nil { + return nil, fmt.Errorf("GlobalDNSController: Error creating an ingress for the GlobalDNS %v", err) + } + } + + err = n.updateIngressForDNS(ingress, obj) + if err != nil { + return nil, fmt.Errorf("GlobalDNSController: Error updating ingress for the GlobalDNS %v", err) + } + + return nil, nil +} + +func (n *GDController) getIngressForGlobalDNS(globaldns *v3.GlobalDns) (ingresswrapper.Ingress, error) { + ingress, err := n.ingresses.Get(context.TODO(), strings.Join([]string{"globaldns-ingress", globaldns.Name}, "-"), metav1.GetOptions{}) + if err != nil { + return nil, err + } + //make sure the ingress is owned by this globalDNS + if n.isIngressOwnedByGlobalDNS(ingress, globaldns) { + return ingress, nil + } + return nil, nil +} + +func (n *GDController) isIngressOwnedByGlobalDNS(obj ingresswrapper.Ingress, globaldns *v3.GlobalDns) bool { + for i, owners := 0, obj.GetOwnerReferences(); owners != nil && i < len(owners); i++ { + if owners[i].UID == globaldns.UID && owners[i].Kind == globaldns.Kind { + return true + } + } + return false +} + +func (n *GDController) createIngressForGlobalDNS(globaldns *v3.GlobalDns) (ingresswrapper.Ingress, error) { + var ingressSpec ingresswrapper.Ingress + if n.ingresses.ServerSupportsIngressV1 { + ingressSpec = n.generateNewIngressV1Spec(globaldns) + } else { + ingressSpec = n.generateNewIngressV1Beta1Spec(globaldns) + } + annotations := ingressSpec.GetAnnotations() + if globaldns.Spec.TTL != 0 { + annotations[annotationDNSTTL] = strconv.FormatInt(globaldns.Spec.TTL, 10) + } + if globaldns.Spec.ProviderName != "" { + ingressClass, err := n.getIngressClass(globaldns.Spec.ProviderName) + if err != nil { + return nil, err + } + if ingressClass != "" { + annotations[annotationIngressClass] = ingressClass + } + } + ingressSpec.SetAnnotations(annotations) + ingressObj, err := n.ingresses.Create(context.TODO(), ingressSpec, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + logrus.Infof("Created ingress %v for globalDNS %s", ingressObj.GetName(), globaldns.Name) + return ingressObj, nil +} + +func (n *GDController) generateNewIngressV1Spec(globaldns *v3.GlobalDns) *knetworkingv1.Ingress { + controller := true + pathType := knetworkingv1.PathTypeImplementationSpecific + return &knetworkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.Join([]string{"globaldns-ingress", globaldns.Name}, "-"), + OwnerReferences: []metav1.OwnerReference{ + { + Name: globaldns.Name, + APIVersion: globaldns.APIVersion, + UID: globaldns.UID, + Kind: globaldns.Kind, + Controller: &controller, + }, + }, + Annotations: map[string]string{ + annotationIngressClass: "rancher-external-dns", + }, + Namespace: globaldns.Namespace, + }, + Spec: knetworkingv1.IngressSpec{ + Rules: []knetworkingv1.IngressRule{ + { + Host: globaldns.Spec.FQDN, + IngressRuleValue: knetworkingv1.IngressRuleValue{ + HTTP: &knetworkingv1.HTTPIngressRuleValue{ + Paths: []knetworkingv1.HTTPIngressPath{ + { + Backend: knetworkingv1.IngressBackend{ + Service: &knetworkingv1.IngressServiceBackend{ + Name: "http-svc-dummy", + Port: knetworkingv1.ServiceBackendPort{ + Number: 42, + }, + }, + }, + PathType: &pathType, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (n *GDController) generateNewIngressV1Beta1Spec(globaldns *v3.GlobalDns) *kextv1beta1.Ingress { + controller := true + return &kextv1beta1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: strings.Join([]string{"globaldns-ingress", globaldns.Name}, "-"), + OwnerReferences: []metav1.OwnerReference{ + { + Name: globaldns.Name, + APIVersion: globaldns.APIVersion, + UID: globaldns.UID, + Kind: globaldns.Kind, + Controller: &controller, + }, + }, + Annotations: map[string]string{ + annotationIngressClass: "rancher-external-dns", + }, + Namespace: globaldns.Namespace, + }, + Spec: kextv1beta1.IngressSpec{ + Rules: []kextv1beta1.IngressRule{ + { + Host: globaldns.Spec.FQDN, + IngressRuleValue: kextv1beta1.IngressRuleValue{ + HTTP: &kextv1beta1.HTTPIngressRuleValue{ + Paths: []kextv1beta1.HTTPIngressPath{ + { + Backend: kextv1beta1.IngressBackend{ + ServiceName: "http-svc-dummy", + ServicePort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 42, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func (n *GDController) getIngressClass(globalDNSProviderName string) (string, error) { + providerName, err := n.getGlobalDNSProviderName(globalDNSProviderName) + if err != nil { + return defaultIngressClass, err + } + + provider, err := n.globalDNSProviderLister.Get(namespace.GlobalNamespace, providerName) + if err != nil && k8serrors.IsNotFound(err) { + logrus.Errorf("GlobalDNSController: Object Not found Error %v, while listing GlobalDNSProvider by name %v", err, providerName) + return defaultIngressClass, nil + } + if err != nil { + return defaultIngressClass, fmt.Errorf("GlobalDNSController: Error %v Listing GlobalDNSProvider by name %v", err, providerName) + } + + var options map[string]string + if provider.Spec.Route53ProviderConfig != nil { + options = provider.Spec.Route53ProviderConfig.AdditionalOptions + } else if provider.Spec.CloudflareProviderConfig != nil { + options = provider.Spec.CloudflareProviderConfig.AdditionalOptions + } else if provider.Spec.AlidnsProviderConfig != nil { + options = provider.Spec.AlidnsProviderConfig.AdditionalOptions + } + + if options != nil { + ingressClassAnnotation, ok := options[annotationFilter] + if ok { + prefix := annotationIngressClass + "=" + if strings.HasPrefix(ingressClassAnnotation, prefix) { + return strings.TrimPrefix(ingressClassAnnotation, prefix), nil + } + } + } + return defaultIngressClass, nil +} + +func (n *GDController) getGlobalDNSProviderName(globalDNSProviderName string) (string, error) { + split := strings.SplitN(globalDNSProviderName, ":", 2) + if len(split) != 2 { + return "", fmt.Errorf("error in splitting globalDNSProviderName %v", globalDNSProviderName) + } + provider := split[1] + return provider, nil +} + +func (n *GDController) updateIngressForDNS(ingress ingresswrapper.Ingress, obj *v3.GlobalDns) error { + var err error + + ingressObj, err := ingresswrapper.ToCompatIngress(ingress) + if err != nil { + return err + } + if n.ifEndpointsDiffer(ingressObj.Status.LoadBalancer.Ingress, obj.Status.Endpoints) { + ingressObj.Status.LoadBalancer.Ingress = n.sliceToStatus(obj.Status.Endpoints) + ingressObj, err = n.ingresses.UpdateStatus(context.TODO(), ingress, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("GlobalDNSController: Error updating Ingress %v", err) + } + } + + var updateIngress bool + if len(ingressObj.Spec.Rules) > 0 { + if !strings.EqualFold(ingressObj.Spec.Rules[0].Host, obj.Spec.FQDN) { + ingressObj.Spec.Rules[0].Host = obj.Spec.FQDN + updateIngress = true + } + } + + ttlvalue := strconv.FormatInt(obj.Spec.TTL, 10) + if !strings.EqualFold(ingressObj.Annotations[annotationDNSTTL], ttlvalue) { + ingressObj.Annotations[annotationDNSTTL] = ttlvalue + updateIngress = true + } + + if obj.Spec.ProviderName != "" { + ingressClass, err := n.getIngressClass(obj.Spec.ProviderName) + if err != nil { + return err + } + if !strings.EqualFold(ingressObj.Annotations[annotationIngressClass], ingressClass) { + ingressObj.Annotations[annotationIngressClass] = ingressClass + updateIngress = true + } + } + + if updateIngress { + _, err := n.ingresses.Update(context.TODO(), ingressObj, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("GlobalDNSController: Error updating Ingress %v", err) + } + } + + return nil +} +func (n *GDController) ifEndpointsDiffer(ingressEps []knetworkingv1.IngressLoadBalancerIngress, endpoints []string) bool { + if len(ingressEps) != len(endpoints) { + return true + } + + mapIngEndpoints := n.gatherIngressEndpoints(ingressEps) + for _, ep := range endpoints { + if !mapIngEndpoints[ep] { + return true + } + } + return false +} + +func (n *GDController) gatherIngressEndpoints(ingressEps []knetworkingv1.IngressLoadBalancerIngress) map[string]bool { + mapIngEndpoints := make(map[string]bool) + for _, ep := range ingressEps { + if ep.IP != "" { + mapIngEndpoints[ep.IP] = true + } else if ep.Hostname != "" { + mapIngEndpoints[ep.Hostname] = true + } + } + return mapIngEndpoints +} + +// sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress +func (n *GDController) sliceToStatus(endpoints []string) []knetworkingv1.IngressLoadBalancerIngress { + lbi := []knetworkingv1.IngressLoadBalancerIngress{} + for _, ep := range endpoints { + if net.ParseIP(ep) == nil { + lbi = append(lbi, knetworkingv1.IngressLoadBalancerIngress{Hostname: ep}) + } else { + lbi = append(lbi, knetworkingv1.IngressLoadBalancerIngress{IP: ep}) + } + } + return lbi +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_catalog_launcher.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_catalog_launcher.go new file mode 100644 index 0000000..327a314 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_catalog_launcher.go @@ -0,0 +1,378 @@ +package globaldns + +import ( + "context" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + "github.com/rancher/norman/types/convert" + passwordutil "github.com/rancher/rancher/pkg/api/norman/store/password" + "github.com/rancher/rancher/pkg/catalog/manager" + cutils "github.com/rancher/rancher/pkg/catalog/utils" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + GlobaldnsProviderCatalogLauncher = "mgmt-global-dns-provider-catalog-launcher" + cattleCreatorIDAnnotationKey = "field.cattle.io/creatorId" + localClusterName = "local" + templateName = "rancher-external-dns" +) + +type ProviderCatalogLauncher struct { + managementContext *config.ManagementContext + Apps pv3.AppInterface + ProjectLister v3.ProjectLister + appLister pv3.AppLister + userManager user.Manager + secrets v1.SecretInterface + templateLister v3.CatalogTemplateLister + catalogManager manager.CatalogManager +} + +func newGlobalDNSProviderCatalogLauncher(ctx context.Context, mgmt *config.ManagementContext) *ProviderCatalogLauncher { + n := &ProviderCatalogLauncher{ + managementContext: mgmt, + Apps: mgmt.Project.Apps(""), + ProjectLister: mgmt.Management.Projects("").Controller().Lister(), + appLister: mgmt.Project.Apps("").Controller().Lister(), + userManager: mgmt.UserManager, + secrets: mgmt.Core.Secrets(""), + templateLister: mgmt.Management.CatalogTemplates(metav1.NamespaceAll).Controller().Lister(), + catalogManager: mgmt.CatalogManager, + } + return n +} + +// sync is called periodically and on real updates +func (n *ProviderCatalogLauncher) sync(key string, obj *v3.GlobalDnsProvider) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, n.deleteExternalDNSApp(key) + } + metaAccessor, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return nil, fmt.Errorf("GlobalDNS %v has no creatorId annotation", metaAccessor.GetName()) + } + + if err := rbac.CreateRoleAndRoleBinding(rbac.GlobalDNSProviderResource, v3.GlobalDnsProviderGroupVersionKind.Kind, obj.Name, namespace.GlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + obj.UID, obj.Spec.Members, n.managementContext); err != nil { + return nil, err + } + + //handle external-dns deployment + if obj.Spec.Route53ProviderConfig != nil { + return n.handleRoute53Provider(obj) + } + + if obj.Spec.CloudflareProviderConfig != nil { + return n.handleCloudflareProvider(obj) + } + + if obj.Spec.AlidnsProviderConfig != nil { + return n.handleAlidnsProvider(obj) + } + + return nil, nil +} + +func (n *ProviderCatalogLauncher) handleRoute53Provider(obj *v3.GlobalDnsProvider) (runtime.Object, error) { + rancherInstallUUID := settings.InstallUUID.Get() + //create external-dns route53 provider + + secretKey := obj.Spec.Route53ProviderConfig.SecretKey + //read the secret if found + var err error + if strings.HasPrefix(obj.Spec.Route53ProviderConfig.SecretKey, namespace.GlobalNamespace) { + secretKey, err = passwordutil.GetValueForPasswordField(obj.Spec.Route53ProviderConfig.SecretKey, n.secrets) + if err != nil { + return nil, err + } + } + + answers := map[string]string{ + "provider": "aws", + "aws.zoneType": obj.Spec.Route53ProviderConfig.ZoneType, + "aws.accessKey": obj.Spec.Route53ProviderConfig.AccessKey, + "aws.secretKey": secretKey, + "txtOwnerId": rancherInstallUUID + "_" + obj.Name, + "rbac.create": "true", + "policy": "sync", + "aws.credentialsPath": obj.Spec.Route53ProviderConfig.CredentialsPath, + "aws.roleArn": obj.Spec.Route53ProviderConfig.RoleArn, + "aws.region": obj.Spec.Route53ProviderConfig.Region, + } + for k, v := range obj.Spec.Route53ProviderConfig.AdditionalOptions { + if _, ok := answers[k]; !ok { + answers[k] = v + } + } + + if obj.Spec.RootDomain != "" { + answers["domainFilters[0]"] = obj.Spec.RootDomain + } + return n.createUpdateExternalDNSApp(obj, answers) +} + +func (n *ProviderCatalogLauncher) handleCloudflareProvider(obj *v3.GlobalDnsProvider) (runtime.Object, error) { + rancherInstallUUID := settings.InstallUUID.Get() + + isProxy := "true" + if obj.Spec.CloudflareProviderConfig.ProxySetting != nil { + isProxy = convert.ToString(*obj.Spec.CloudflareProviderConfig.ProxySetting) + } + + secretAPIKey := obj.Spec.CloudflareProviderConfig.APIKey + //read the secret if found + var err error + if strings.HasPrefix(obj.Spec.CloudflareProviderConfig.APIKey, namespace.GlobalNamespace) { + secretAPIKey, err = passwordutil.GetValueForPasswordField(obj.Spec.CloudflareProviderConfig.APIKey, n.secrets) + if err != nil { + return nil, err + } + } + + //create external-dns route53 provider + answers := map[string]string{ + "provider": "cloudflare", + "cloudflare.apiKey": secretAPIKey, + "cloudflare.email": obj.Spec.CloudflareProviderConfig.APIEmail, + "txtOwnerId": rancherInstallUUID + "_" + obj.Name, + "rbac.create": "true", + "policy": "sync", + "cloudflare.proxied": isProxy, + } + for k, v := range obj.Spec.CloudflareProviderConfig.AdditionalOptions { + if _, ok := answers[k]; !ok { + answers[k] = v + } + } + + if obj.Spec.RootDomain != "" { + answers["domainFilters[0]"] = obj.Spec.RootDomain + } + + return n.createUpdateExternalDNSApp(obj, answers) +} + +func (n *ProviderCatalogLauncher) handleAlidnsProvider(obj *v3.GlobalDnsProvider) (runtime.Object, error) { + rancherInstallUUID := settings.InstallUUID.Get() + + secretKey := obj.Spec.AlidnsProviderConfig.SecretKey + //read the secret if found + var err error + if strings.HasPrefix(obj.Spec.AlidnsProviderConfig.SecretKey, namespace.GlobalNamespace) { + secretKey, err = passwordutil.GetValueForPasswordField(obj.Spec.AlidnsProviderConfig.SecretKey, n.secrets) + if err != nil { + return nil, err + } + } + + //create external-dns alidns provider + answers := map[string]string{ + "provider": "alibabacloud", + "alibabacloud.zoneType": "public", + "alibabacloud.accessKey": obj.Spec.AlidnsProviderConfig.AccessKey, + "alibabacloud.secretKey": secretKey, + "txtOwnerId": rancherInstallUUID + "_" + obj.Name, + "rbac.create": "true", + "policy": "sync", + } + for k, v := range obj.Spec.AlidnsProviderConfig.AdditionalOptions { + if _, ok := answers[k]; !ok { + answers[k] = v + } + } + + if obj.Spec.RootDomain != "" { + answers["domainFilters[0]"] = obj.Spec.RootDomain + } + + return n.createUpdateExternalDNSApp(obj, answers) +} + +func (n *ProviderCatalogLauncher) createUpdateExternalDNSApp(obj *v3.GlobalDnsProvider, answers map[string]string) (runtime.Object, error) { + //check if provider already running for this GlobalDNSProvider. + existingApp, err := n.getProviderIfAlreadyRunning(obj.Name) + if err != nil { + return nil, err + } + + if existingApp != nil { + var shouldUpdate bool + var appToUpdate *pv3.App + + //check if answers should be updated + if answersDiffer(existingApp.Spec.Answers, answers) { + appToUpdate = existingApp.DeepCopy() + updateAnswers(appToUpdate.Spec.Answers, answers) + shouldUpdate = true + } + + //check if ownerRef to GlobalDnsProvider is present; drop if yes + if len(existingApp.OwnerReferences) > 0 { + for _, ref := range existingApp.OwnerReferences { + if ref.UID == obj.UID { + if appToUpdate == nil { + appToUpdate = existingApp.DeepCopy() + } + removeOwnerRef(appToUpdate, ref) + shouldUpdate = true + break + } + } + } + + if shouldUpdate { + _, err = n.Apps.Update(appToUpdate) + if err != nil && !apierrors.IsAlreadyExists(err) { + return nil, err + } + } + } else { + //create new app + appCatalogID, err := n.getExternalDNSCatalogID(localClusterName) + if err != nil { + return nil, err + } + sysProject, err := n.getSystemProjectID() + if err != nil { + return nil, err + } + + creator, err := n.userManager.EnsureUser(fmt.Sprintf("system://%s", localClusterName), "System account for Cluster "+localClusterName) + if err != nil { + return nil, err + } + toCreate := pv3.App{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{cattleCreatorIDAnnotationKey: creator.Name}, + Name: fmt.Sprintf("%s-%s", "systemapp", obj.Name), + Namespace: sysProject, + }, + Spec: v32.AppSpec{ + ProjectName: localClusterName + ":" + sysProject, + TargetNamespace: namespace.GlobalNamespace, + ExternalID: appCatalogID, + Answers: answers, + }, + } + // Now create the App instance + _, err = n.Apps.Create(&toCreate) + if err != nil && !apierrors.IsAlreadyExists(err) { + return nil, err + } + } + return nil, nil +} + +func (n *ProviderCatalogLauncher) deleteExternalDNSApp(key string) error { + _, globalDNSproviderName, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return err + } + //check if provider already running for this GlobalDNSProvider. + existingApp, err := n.getProviderIfAlreadyRunning(globalDNSproviderName) + if err != nil { + return err + } + if existingApp != nil { + //delete this app since GlobalDNSProvider is deleted + if err := n.Apps.DeleteNamespaced(existingApp.Namespace, existingApp.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return err + } + } + return nil +} + +func (n *ProviderCatalogLauncher) getProviderIfAlreadyRunning(globalDNSProviderName string) (*pv3.App, error) { + sysProject, err := n.getSystemProjectID() + if err != nil { + return nil, err + } + existingApp, err := n.appLister.Get(sysProject, fmt.Sprintf("%s-%s", "systemapp", globalDNSProviderName)) + + if (err != nil && k8serrors.IsNotFound(err)) || existingApp == nil { + return nil, nil + } else if err != nil && !k8serrors.IsNotFound(err) { + logrus.Errorf("GlobaldnsProviderCatalogLauncher: Error listing external-dns %v app %v", globalDNSProviderName, err) + return nil, err + } + + return existingApp, nil +} + +func (n *ProviderCatalogLauncher) getSystemProjectID() (string, error) { + systemProject, err := project.GetSystemProject(localClusterName, n.ProjectLister) + if err != nil { + return "", err + } + + return systemProject.Name, nil +} + +func (n *ProviderCatalogLauncher) getExternalDNSCatalogID(clusterName string) (string, error) { + templateVersionID := n.getRancherExternalDNSTemplateID() + return n.catalogManager.GetSystemAppCatalogID(templateVersionID, clusterName) +} + +func (n *ProviderCatalogLauncher) getRancherExternalDNSTemplateID() string { + return fmt.Sprintf("%s-%s", cutils.SystemLibraryName, templateName) +} + +func CopyCreatorID(toAnnotations, fromAnnotations map[string]string) map[string]string { + if val, exist := fromAnnotations[cattleCreatorIDAnnotationKey]; exist { + if toAnnotations == nil { + toAnnotations = make(map[string]string, 2) + } + + toAnnotations[cattleCreatorIDAnnotationKey] = val + } + return toAnnotations +} + +func answersDiffer(appAnswers map[string]string, newAnswers map[string]string) bool { + for key, value := range newAnswers { + if !strings.EqualFold(appAnswers[key], value) { + return true + } + } + return false +} + +func updateAnswers(appAnswers map[string]string, newAnswers map[string]string) { + for key, value := range newAnswers { + appAnswers[key] = value + } +} + +func removeOwnerRef(app *pv3.App, refToRemove metav1.OwnerReference) { + var newRef []metav1.OwnerReference + for _, ref := range app.OwnerReferences { + if ref.Name != refToRemove.Name && ref.UID != refToRemove.UID { + newRef = append(newRef, ref) + } + } + app.OwnerReferences = newRef +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_secret_syncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_secret_syncer.go new file mode 100644 index 0000000..e9ab2f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/globaldnsprovider_secret_syncer.go @@ -0,0 +1,85 @@ +package globaldns + +import ( + "context" + "strings" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + GlobaldnsProviderSecretSyncer = "mgmt-global-dns-provider-secret-syncer" +) + +type ProviderSecretSyncer struct { + globalDNSProviders v3.GlobalDnsProviderInterface + globalDNSProviderLister v3.GlobalDnsProviderLister +} + +func newProviderSecretSyncer(ctx context.Context, mgmt *config.ManagementContext) *ProviderSecretSyncer { + n := &ProviderSecretSyncer{ + globalDNSProviders: mgmt.Management.GlobalDnsProviders(""), + globalDNSProviderLister: mgmt.Management.GlobalDnsProviders("").Controller().Lister(), + } + return n +} + +// sync is called periodically and on real updates +func (n *ProviderSecretSyncer) sync(key string, obj *corev1.Secret) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + if !strings.EqualFold(obj.Namespace, namespace.GlobalNamespace) { + return nil, nil + } + + return n.reconcileAllGlobalDNSProviders(key) +} + +func (n *ProviderSecretSyncer) reconcileAllGlobalDNSProviders(key string) (runtime.Object, error) { + globalDNSProviderList, err := n.globalDNSProviderLister.List(namespace.GlobalNamespace, labels.NewSelector()) + if err != nil { + return nil, err + } + + for _, globalDNSProviderObj := range globalDNSProviderList { + //call update on each GlobalDNSProvider obj that refers to this current secret + usesSecret := n.doesGlobalDNSProviderUseSecret(key, globalDNSProviderObj) + if usesSecret { + //enqueue it to the globalDNS controller + n.globalDNSProviders.Controller().Enqueue(namespace.GlobalNamespace, globalDNSProviderObj.Name) + } + } + return nil, nil +} + +func (n *ProviderSecretSyncer) doesGlobalDNSProviderUseSecret(key string, globalDNSProviderObj *v3.GlobalDnsProvider) bool { + var secretRef string + if globalDNSProviderObj.Spec.Route53ProviderConfig != nil { + secretRef = globalDNSProviderObj.Spec.Route53ProviderConfig.SecretKey + } + + if globalDNSProviderObj.Spec.CloudflareProviderConfig != nil { + secretRef = globalDNSProviderObj.Spec.CloudflareProviderConfig.APIKey + } + + if globalDNSProviderObj.Spec.AlidnsProviderConfig != nil { + secretRef = globalDNSProviderObj.Spec.AlidnsProviderConfig.SecretKey + } + + if secretRef != "" && strings.HasPrefix(secretRef, namespace.GlobalNamespace) { + ns, secret := ref.Parse(secretRef) + if strings.EqualFold(key, ns+"/"+secret) { + return true + } + + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/register.go new file mode 100644 index 0000000..342071b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/globaldns/register.go @@ -0,0 +1,25 @@ +package globaldns + +import ( + "context" + + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, management *config.ManagementContext) { + n := newGlobalDNSController(ctx, management) + if n != nil { + management.Management.GlobalDnses("").AddHandler(ctx, GlobaldnsController, n.sync) + } + + cp := newGlobalDNSProviderCatalogLauncher(ctx, management) + if cp != nil { + management.Management.GlobalDnsProviders("").AddHandler(ctx, GlobaldnsProviderCatalogLauncher, cp.sync) + } + + sp := newProviderSecretSyncer(ctx, management) + if sp != nil { + management.Core.Secrets("").AddHandler(ctx, GlobaldnsProviderSecretSyncer, sp.sync) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/controller_multiclusterapp.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/controller_multiclusterapp.go new file mode 100644 index 0000000..6a31d8f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/controller_multiclusterapp.go @@ -0,0 +1,666 @@ +package multiclusterapp + +import ( + "context" + "fmt" + "reflect" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v33 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + "k8s.io/apimachinery/pkg/api/meta" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + globalScopeAnswersKey = "global" + creatorIDAnn = "field.cattle.io/creatorId" + MultiClusterAppIDSelector = "mcapp" + mcAppLabel = "io.cattle.field/multiClusterAppId" +) + +type MCAppManager struct { + apps pv3.AppInterface + appLister pv3.AppLister + multiClusterApps v3.MultiClusterAppInterface + multiClusterAppRevisions v3.MultiClusterAppRevisionInterface + multiClusterAppRevisionLister v3.MultiClusterAppRevisionLister + templateVersionLister v3.CatalogTemplateVersionLister + projectLister v3.ProjectLister + clusterLister v3.ClusterLister + userManager user.Manager + ctx context.Context +} + +func StartMCAppManagementController(ctx context.Context, mgmt *config.ManagementContext, clusterManager *clustermanager.Manager) { + management := mgmt.Management + mcApps := management.MultiClusterApps("") + m := &MCAppManager{ + ctx: ctx, + apps: mgmt.Project.Apps(""), + appLister: mgmt.Project.Apps("").Controller().Lister(), + multiClusterApps: mcApps, + multiClusterAppRevisions: management.MultiClusterAppRevisions(""), + multiClusterAppRevisionLister: management.MultiClusterAppRevisions("").Controller().Lister(), + projectLister: management.Projects("").Controller().Lister(), + clusterLister: management.Clusters("").Controller().Lister(), + templateVersionLister: management.CatalogTemplateVersions("").Controller().Lister(), + userManager: mgmt.UserManager, + } + mcAppTickerData = map[string]*IntervalData{} + m.multiClusterApps.AddHandler(ctx, "multi-cluster-app-controller", m.sync) +} + +func (m *MCAppManager) sync(key string, mcapp *v3.MultiClusterApp) (runtime.Object, error) { + if mcapp == nil || mcapp.DeletionTimestamp != nil { + _, mcappName, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return mcapp, err + } + deleteContext(mcappName) + return m.deleteApps(mcappName, mcapp) + } + + // creatorID is actual user who created mcapp, to be used for mcapp revisions of this mcapp + metaAccessor, err := meta.Accessor(mcapp) + if err != nil { + return mcapp, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return mcapp, fmt.Errorf("MultiClusterApp %v has no creatorId annotation. Cannot create apps for %v", metaAccessor.GetName(), mcapp.Name) + } + // systemUserName is creatorID for app, the username of the service account created for this multiclusterapp + systemUser, err := m.userManager.EnsureUser(fmt.Sprintf("system://%s", mcapp.Name), "System account for Multiclusterapp "+mcapp.Name) + if err != nil { + return nil, err + } + systemUserName := systemUser.Name + + answersMap, err := m.createAnswersMap(mcapp.Spec.Answers) + if err != nil { + return mcapp, err + } + + externalID, mcapp, err := m.getExternalID(mcapp) + if err != nil { + return mcapp, err + } + + mcapp = mcapp.DeepCopy() + if err := m.reconcileTargetsForDelete(mcapp); err != nil { + return mcapp, err + } + + changed, err := m.isChanged(mcapp) + if err != nil { + return mcapp, err + } + + toUpdate := false + if changed { + toUpdate, err = m.toUpdate(mcapp) + if err != nil { + return mcapp, err + } + } + + batchSize := len(mcapp.Spec.Targets) + if toUpdate && mcapp.Spec.UpgradeStrategy.RollingUpdate != nil { + if mcapp.Spec.UpgradeStrategy.RollingUpdate.Interval != 0 { + batchSize = mcapp.Spec.UpgradeStrategy.RollingUpdate.BatchSize + } + } + + resp, err := m.createApps(mcapp, externalID, answersMap, systemUserName, batchSize, toUpdate) + if err != nil { + return resp.object, err + } + + if !changed { + if mcapp.Status.RevisionName == "" { + return m.setRevisionAndUpdate(mcapp, creatorID) + } + return mcapp, nil + } + + if resp.count == len(mcapp.Spec.Targets) && v32.MultiClusterAppConditionInstalled.IsUnknown(mcapp) && + v32.MultiClusterAppConditionInstalled.GetMessage(mcapp) == "upgrading" { + deleteContext(mcapp.Name) + return m.setRevisionAndUpdate(mcapp, creatorID) + } + + if !toUpdate || resp.remaining <= 0 { + return mcapp, nil + } + + for i, app := range resp.updateApps { + if _, err := m.updateApp(app, answersMap, externalID, resp.projects[i]); err != nil { + return mcapp, err + } + resp.remaining-- + if resp.remaining == 0 { + break + } + } + + setInstalledUnknown(mcapp) + upd, err := m.updateCondition(mcapp, setInstalledUnknown) + if err != nil { + return mcapp, err + } + storeContext(m.ctx, mcapp, m.multiClusterApps) + return upd, err +} + +type Response struct { + object *v3.MultiClusterApp + projects []string + updateApps []*pv3.App + remaining int + count int +} + +func (m *MCAppManager) createApps(mcapp *v3.MultiClusterApp, externalID string, answersMap map[string]scopeAnswers, + creatorID string, batchSize int, toUpdate bool) (*Response, error) { + + var mcappToUpdate *v3.MultiClusterApp + var updateApps []*pv3.App + var projects []string + + ann := map[string]string{ + creatorIDAnn: creatorID, + } + set := labels.Set(map[string]string{MultiClusterAppIDSelector: mcapp.Name}) + + resp := &Response{object: mcapp} + + updateBatchSize := batchSize + count := 0 + + // for all targets, create the App{} instance, so that helm controller App lifecycle can pick it up + // only one app per project named mcapp-{{mcapp.Name}} + for ind, t := range mcapp.Spec.Targets { + split := strings.SplitN(t.ProjectName, ":", 2) + if len(split) != 2 { + return resp, fmt.Errorf("error in splitting project ID %v", t.ProjectName) + } + projectNS := split[1] + // check if this app already exists + if t.AppName != "" { + app, err := m.appLister.Get(projectNS, t.AppName) + if err != nil || app == nil { + return resp, fmt.Errorf("error %v getting app %s in %s", err, t.AppName, projectNS) + } + if val, ok := app.Labels[MultiClusterAppIDSelector]; !ok || val != mcapp.Name { + return resp, fmt.Errorf("app %s in %s missing multi cluster app label", t.AppName, projectNS) + } + appUpdated := false + if app.Spec.ExternalID == externalID { + answers, answersSetString := getScopeAnswers(answersMap, t.ProjectName) + if reflect.DeepEqual(app.Spec.Answers, answers) && + reflect.DeepEqual(app.Spec.AnswersSetString, answersSetString) { + appUpdated = true + } + } + if appUpdated { + count++ + if !v33.AppConditionInstalled.IsTrue(app) || !v33.AppConditionDeployed.IsTrue(app) { + toUpdate = false + updateApps = []*pv3.App{} + } + continue + } + if toUpdate && updateBatchSize > 0 { + updateApps = append(updateApps, app) + projects = append(projects, t.ProjectName) + updateBatchSize-- + } + continue + } + if batchSize > 0 { + appName, mcapp, err := m.createApp(mcapp, answersMap, ann, set, projectNS, creatorID, externalID, t.ProjectName) + if err != nil { + return resp, fmt.Errorf("error %v in creating multiclusterapp: %v", err, mcapp) + } + if appName != "" { + if mcappToUpdate == nil { + mcappToUpdate = mcapp.DeepCopy() + } + mcappToUpdate.Spec.Targets[ind].AppName = appName + batchSize-- + count++ + } + } + } + + if mcappToUpdate != nil && !reflect.DeepEqual(mcapp, mcappToUpdate) { + upd, err := m.multiClusterApps.Update(mcappToUpdate) + if err != nil { + resp.object = mcappToUpdate + return resp, err + } + resp.object = upd + } + + resp.updateApps = updateApps + resp.projects = projects + resp.count = count + resp.remaining = batchSize + + return resp, nil +} + +func (m *MCAppManager) updateApp(app *pv3.App, answersMap map[string]scopeAnswers, externalID string, projectName string) (*pv3.App, error) { + app = app.DeepCopy() + answers, answersSetString := getScopeAnswers(answersMap, projectName) + app.Spec.Answers = answers + app.Spec.AnswersSetString = answersSetString + app.Spec.ExternalID = externalID + updatedObj, err := m.apps.Update(app) + if err != nil && apierrors.IsConflict(err) { + _, projectNS := ref.Parse(projectName) + for i := 0; i < 5; i++ { + latestObj, err := m.apps.GetNamespaced(projectNS, app.Name, metav1.GetOptions{}) + if err != nil { + return latestObj, err + } + latestToUpdate := latestObj.DeepCopy() + answers, answersSetString := getScopeAnswers(answersMap, projectName) + latestToUpdate.Spec.Answers = answers + latestToUpdate.Spec.AnswersSetString = answersSetString + latestToUpdate.Spec.ExternalID = externalID + updated, err := m.apps.Update(latestToUpdate) + if err != nil && apierrors.IsConflict(err) { + time.Sleep(5 * time.Millisecond) + continue + } + return updated, err + } + return app, err + } + return updatedObj, err +} + +func (m *MCAppManager) createRevision(mcapp *v3.MultiClusterApp, creatorID string) (*v3.MultiClusterAppRevision, error) { + ownerReference := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: v3.MultiClusterAppGroupVersionKind.Kind, + Name: mcapp.Name, + UID: mcapp.UID, + } + revision := &v3.MultiClusterAppRevision{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + creatorIDAnn: creatorID, + }, + OwnerReferences: []metav1.OwnerReference{ownerReference}, + }, + } + revision.GenerateName = "mcapprevision-" + revision.Labels = map[string]string{ + mcAppLabel: mcapp.Name, + } + revision.Answers = mcapp.Spec.Answers + revision.TemplateVersionName = mcapp.Spec.TemplateVersionName + revision.Namespace = namespace.GlobalNamespace + return m.multiClusterAppRevisions.Create(revision) +} + +func (m *MCAppManager) setRevisionAndUpdate(mcapp *v3.MultiClusterApp, creatorID string) (*v3.MultiClusterApp, error) { + latestMcApp, err := m.multiClusterApps.GetNamespaced(namespace.GlobalNamespace, mcapp.Name, metav1.GetOptions{}) + if err != nil { + return mcapp, err + } + if latestMcApp.Status.RevisionName != "" { + currRevision, err := m.multiClusterAppRevisionLister.Get(namespace.GlobalNamespace, latestMcApp.Status.RevisionName) + if err != nil { + return mcapp, err + } + if currRevision.TemplateVersionName == mcapp.Spec.TemplateVersionName && + reflect.DeepEqual(currRevision.Answers, mcapp.Spec.Answers) { + return mcapp, nil + } + mcapp = latestMcApp + } + setInstalledDone(mcapp) + rev, err := m.createRevision(mcapp, creatorID) + if err != nil { + return mcapp, err + } + mcapp.Status.RevisionName = rev.Name + return m.updateCondition(mcapp, setInstalledDone) +} + +func (m *MCAppManager) isChanged(mcapp *v3.MultiClusterApp) (bool, error) { + if mcapp.Status.RevisionName == "" { + return false, nil + } + mcappRevision, err := m.multiClusterAppRevisionLister.Get(namespace.GlobalNamespace, mcapp.Status.RevisionName) + if err != nil { + return false, err + } + if mcapp.Spec.TemplateVersionName != mcappRevision.TemplateVersionName { + return true, nil + } + if !reflect.DeepEqual(mcapp.Spec.Answers, mcappRevision.Answers) { + return true, nil + } + return false, nil +} + +func (m *MCAppManager) toUpdate(mcapp *v3.MultiClusterApp) (bool, error) { + if v32.MultiClusterAppConditionInstalled.IsUnknown(mcapp) && v32.MultiClusterAppConditionInstalled.GetMessage(mcapp) == "upgrading" { + lastUpdated, err := time.Parse(time.RFC3339, v32.MultiClusterAppConditionInstalled.GetLastUpdated(mcapp)) + if err != nil { + return false, err + } + interval := 0 + if mcapp.Spec.UpgradeStrategy.RollingUpdate != nil { + interval = mcapp.Spec.UpgradeStrategy.RollingUpdate.Interval + } + if time.Since(lastUpdated) < time.Duration(interval)*time.Second { + return false, nil + } + } + return true, nil +} + +func (m *MCAppManager) createApp(mcapp *v3.MultiClusterApp, answersMap map[string]scopeAnswers, ann map[string]string, + set map[string]string, projectNS string, creatorID string, externalID string, projectName string) (string, *v3.MultiClusterApp, error) { + nsName := getAppNamespaceName(mcapp.Name, projectNS) + app, err := m.appLister.Get(projectNS, nsName) + if err != nil { + if !apierrors.IsNotFound(err) { + return "", mcapp, err + } + answers, answersSetString := getScopeAnswers(answersMap, projectName) + toCreate := pv3.App{ + ObjectMeta: metav1.ObjectMeta{ + Name: nsName, + Namespace: projectNS, + Annotations: ann, + Labels: set, + }, + Spec: v33.AppSpec{ + ProjectName: projectName, + TargetNamespace: nsName, + ExternalID: externalID, + MultiClusterAppName: mcapp.Name, + Answers: answers, + AnswersSetString: answersSetString, + Wait: mcapp.Spec.Wait, + Timeout: mcapp.Spec.Timeout, + }, + } + // Now create the App instance + app, err = m.apps.Create(&toCreate) + if err != nil && !apierrors.IsAlreadyExists(err) { + return "", mcapp, err + } + } + return app.Name, mcapp, nil +} + +// deleteApps finds all apps created by this multiclusterapp and deletes them +func (m *MCAppManager) deleteApps(mcAppName string, mcapp *v3.MultiClusterApp) (runtime.Object, error) { + // get all apps with label "multiClusterAppId" = name of this app + appsToDelete := []*pv3.App{} + set := labels.Set(map[string]string{MultiClusterAppIDSelector: mcAppName}) + var err error + + if mcapp == nil { + appsToDelete, err = m.getAllApps(mcAppName) + if err != nil { + return nil, err + } + } else { + for _, t := range mcapp.Spec.Targets { + split := strings.SplitN(t.ProjectName, ":", 2) + if len(split) != 2 { + return mcapp, fmt.Errorf("error in splitting project ID %v", t.ProjectName) + } + projectNS := split[1] + apps, err := m.appLister.List(projectNS, set.AsSelector()) + if err != nil { + return nil, err + } + appsToDelete = append(appsToDelete, apps...) + } + } + if err := m.delete(appsToDelete); err != nil { + return nil, err + } + return nil, nil +} + +func (m *MCAppManager) getAllApps(mcAppName string) ([]*pv3.App, error) { + // to get all apps, get all clusters first, then get all apps in all projects of all clusters + allApps := []*pv3.App{} + set := labels.Set(map[string]string{MultiClusterAppIDSelector: mcAppName}) + clusters, err := m.clusterLister.List("", labels.NewSelector()) + if err != nil { + return allApps, err + } + for _, c := range clusters { + projects, err := m.projectLister.List(c.Name, labels.NewSelector()) + if err != nil { + return allApps, err + } + for _, p := range projects { + apps, err := m.appLister.List(p.Name, set.AsSelector()) + if err != nil { + return allApps, err + } + allApps = append(allApps, apps...) + } + } + return allApps, err +} + +func (m *MCAppManager) reconcileTargetsForDelete(mcapp *v3.MultiClusterApp) error { + existingApps := map[string]bool{} + set := labels.Set(map[string]string{MultiClusterAppIDSelector: mcapp.Name}) + for _, t := range mcapp.Spec.Targets { + split := strings.SplitN(t.ProjectName, ":", 2) + if len(split) != 2 { + return fmt.Errorf("error in splitting project ID %v", t.ProjectName) + } + projectNS := split[1] + apps, err := m.appLister.List(projectNS, set.AsSelector()) + if err != nil { + return err + } + for _, app := range apps { + existingApps[app.Namespace] = true + } + } + allApps, err := m.getAllApps(mcapp.Name) + if err != nil { + return err + } + toDelete := []*pv3.App{} + for _, app := range allApps { + if _, ok := existingApps[app.Namespace]; !ok { + toDelete = append(toDelete, app) + } + } + if len(toDelete) > 0 { + logrus.Debugf("deleting apps for mcapp %s toDelete %v", mcapp.Name, toDelete) + } + return m.delete(toDelete) +} + +func (m *MCAppManager) delete(appsToDelete []*pv3.App) error { + var g errgroup.Group + for ind := range appsToDelete { + app := appsToDelete[ind] + g.Go(func() error { + if err := m.apps.DeleteNamespaced(app.Namespace, app.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil + }) + } + return g.Wait() +} + +func (m *MCAppManager) updateCondition(mcappToUpdate *v3.MultiClusterApp, setCondition func(mcapp *v3.MultiClusterApp)) (*v3.MultiClusterApp, error) { + updatedObj, err := m.multiClusterApps.Update(mcappToUpdate) + if err != nil && apierrors.IsConflict(err) { + // retry 5 times + for i := 0; i < 5; i++ { + latestMcApp, err := m.multiClusterApps.GetNamespaced(namespace.GlobalNamespace, mcappToUpdate.Name, metav1.GetOptions{}) + if err != nil { + return latestMcApp, err + } + latestToUpdate := latestMcApp.DeepCopy() + for ind, t := range mcappToUpdate.Spec.Targets { + if t.AppName != "" { + latestToUpdate.Spec.Targets[ind].AppName = t.AppName + } + } + latestToUpdate.Status.RevisionName = mcappToUpdate.Status.RevisionName + setCondition(latestToUpdate) + updatedMcApp, err := m.multiClusterApps.Update(latestToUpdate) + if err != nil && apierrors.IsConflict(err) { + time.Sleep(5 * time.Millisecond) + continue + } + return updatedMcApp, err + } + return mcappToUpdate, err + } + return updatedObj, err +} + +func setInstalledUnknown(mcapp *v3.MultiClusterApp) { + v32.MultiClusterAppConditionInstalled.Unknown(mcapp) + v32.MultiClusterAppConditionInstalled.Message(mcapp, "upgrading") + v32.MultiClusterAppConditionInstalled.LastUpdated(mcapp, time.Now().Format(time.RFC3339)) +} + +func setInstalledDone(mcapp *v3.MultiClusterApp) { + v32.MultiClusterAppConditionInstalled.True(mcapp) + v32.MultiClusterAppConditionInstalled.Message(mcapp, "") +} + +type scopeAnswers struct { + answers map[string]string + answersSetString map[string]string +} + +func getScopeAnswers(answersMap map[string]scopeAnswers, projectName string) (map[string]string, map[string]string) { + // Find answers for this project, if not found then try finding for the cluster this project belongs to, else finally use the global scoped answers + if len(answersMap) > 0 { + if a, ok := answersMap[projectName]; ok { + return a.answers, a.answersSetString + } + // Find the answers for the cluster of this project + clusterName := strings.SplitN(projectName, ":", 2)[0] + if a, ok := answersMap[clusterName]; ok { + return a.answers, a.answersSetString + } + if a, ok := answersMap[globalScopeAnswersKey]; ok { + return a.answers, a.answersSetString + } + } + return map[string]string{}, map[string]string{} +} + +func (m *MCAppManager) createAnswersMap(answers []v32.Answer) (map[string]scopeAnswers, error) { + // This function creates a map where keys are the scope of the answers (ProjectName, ClusterName, or "global"), and + // the values are scopeAnswers structs containing the answers and answersSetString. Global answers apply to all scopes, + // whereas project and cluster answers will override the global scope. Therefore we create a global map first and then + // merge with the project/cluster map. + var globalAnswers scopeAnswers + var answersMap = make(map[string]scopeAnswers) + + for _, a := range answers { + if a.ProjectName == "" && a.ClusterName == "" { + globalAnswers = scopeAnswers{ + answers: a.Values, + answersSetString: a.ValuesSetString, + } + answersMap[globalScopeAnswersKey] = scopeAnswers{ + answers: a.Values, + answersSetString: a.ValuesSetString, + } + } + } + for _, a := range answers { + if a.ClusterName != "" { + // Using k8s labels.Merge, since by definition: + // Merge combines given maps, and does not check for any conflicts between the maps. In case of conflicts, second map (labels2) wins + // And we want cluster level keys to override keys from global/cluster for that cluster + answersMap[a.ClusterName] = scopeAnswers{ + answers: labels.Merge(globalAnswers.answers, a.Values), + answersSetString: labels.Merge(globalAnswers.answersSetString, a.ValuesSetString), + } + } + } + for _, a := range answers { + if a.ProjectName != "" { + // Check if answers for the cluster of this project are provided + split := strings.SplitN(a.ProjectName, ":", 2) + if len(split) != 2 { + return answersMap, fmt.Errorf("error in splitting project name: %v", a.ProjectName) + } + clusterName := split[0] + // Using k8s labels.Merge, since by definition: + // Merge combines given maps, and does not check for any conflicts between the maps. In case of conflicts, second map (labels2) wins + // And we want project level keys to override keys from global level for that project + if clusterAnswers, ok := answersMap[clusterName]; ok { + answersMap[a.ProjectName] = scopeAnswers{ + answers: labels.Merge(clusterAnswers.answers, a.Values), + answersSetString: labels.Merge(clusterAnswers.answersSetString, a.ValuesSetString), + } + } else { + answersMap[a.ProjectName] = scopeAnswers{ + answers: labels.Merge(globalAnswers.answers, a.Values), + answersSetString: labels.Merge(globalAnswers.answersSetString, a.ValuesSetString), + } + } + } + } + return answersMap, nil +} + +// getExternalID gets the TemplateVersion.Spec.ExternalID field +func (m *MCAppManager) getExternalID(mcapp *v3.MultiClusterApp) (string, *v3.MultiClusterApp, error) { + // create the externalID field, it's also present on the templateVersion. So get the templateVersion and read its externalID field + split := strings.SplitN(mcapp.Spec.TemplateVersionName, ":", 2) + templateVersionNamespace := split[0] + templateVersionName := split[1] + tv, err := m.templateVersionLister.Get(templateVersionNamespace, templateVersionName) + if err != nil { + return "", mcapp, err + } + if tv == nil { + return "", mcapp, fmt.Errorf("invalid templateVersion provided: %v", mcapp.Spec.TemplateVersionName) + } + + externalID := tv.Spec.ExternalID + return externalID, mcapp, nil +} + +func getAppNamespaceName(mcappName, projectNS string) string { + return fmt.Sprintf("%s-%s", mcappName, projectNS) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/enqueue.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/enqueue.go new file mode 100644 index 0000000..a2d3c38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/enqueue.go @@ -0,0 +1,32 @@ +package multiclusterapp + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/runtime" +) + +func StartMCAppEnqueueController(ctx context.Context, management *config.ManagementContext) { + m := MCAppEnqueueController{ + mcApps: management.Management.MultiClusterApps(""), + } + management.Project.Apps("").AddHandler(ctx, "management-mcapp-enqueue-controller", m.sync) +} + +type MCAppEnqueueController struct { + mcApps v3.MultiClusterAppInterface +} + +func (m *MCAppEnqueueController) sync(key string, app *pv3.App) (runtime.Object, error) { + if app == nil { + return app, nil + } + if mcappName, ok := app.Labels[MultiClusterAppIDSelector]; ok { + m.mcApps.Controller().Enqueue(namespace.GlobalNamespace, mcappName) + } + return app, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/handler_multiclusterapp.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/handler_multiclusterapp.go new file mode 100644 index 0000000..cdf6675 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/handler_multiclusterapp.go @@ -0,0 +1,401 @@ +package multiclusterapp + +import ( + "context" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/controllers/management/rbac" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/user" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +const ownerRefUpdated = "auth.management.cattle.io/owner-ref-updated" + +type MCAppController struct { + multiClusterApps v3.MultiClusterAppInterface + multiClusterAppRevisionLister v3.MultiClusterAppRevisionLister + managementContext *config.ManagementContext + prtbs v3.ProjectRoleTemplateBindingInterface + prtbLister v3.ProjectRoleTemplateBindingLister + crtbs v3.ClusterRoleTemplateBindingInterface + crtbLister v3.ClusterRoleTemplateBindingLister + rtLister v3.RoleTemplateLister + users v3.UserInterface + userManager user.Manager +} + +type MCAppRevisionController struct { + managementContext *config.ManagementContext + multiClusterAppLister v3.MultiClusterAppLister + multiClusterAppRevisions v3.MultiClusterAppRevisionInterface +} + +type ProjectController struct { + mcAppsLister v3.MultiClusterAppLister + mcApps v3.MultiClusterAppInterface + projectLister v3.ProjectLister +} + +type ClusterController struct { + mcAppsLister v3.MultiClusterAppLister + mcApps v3.MultiClusterAppInterface + clusterLister v3.ClusterLister +} + +func Register(ctx context.Context, management *config.ManagementContext, clusterManager *clustermanager.Manager) { + mcApps := management.Management.MultiClusterApps("") + m := MCAppController{ + multiClusterApps: mcApps, + multiClusterAppRevisionLister: management.Management.MultiClusterAppRevisions("").Controller().Lister(), + managementContext: management, + prtbs: management.Management.ProjectRoleTemplateBindings(""), + prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + crtbs: management.Management.ClusterRoleTemplateBindings(""), + crtbLister: management.Management.ClusterRoleTemplateBindings("").Controller().Lister(), + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + userManager: management.UserManager, + users: management.Management.Users(""), + } + r := MCAppRevisionController{ + managementContext: management, + multiClusterAppLister: management.Management.MultiClusterApps("").Controller().Lister(), + multiClusterAppRevisions: management.Management.MultiClusterAppRevisions(""), + } + projects := management.Management.Projects("") + p := ProjectController{ + mcAppsLister: mcApps.Controller().Lister(), + mcApps: mcApps, + projectLister: projects.Controller().Lister(), + } + clusters := management.Management.Clusters("") + c := ClusterController{ + mcAppsLister: mcApps.Controller().Lister(), + mcApps: mcApps, + clusterLister: clusters.Controller().Lister(), + } + m.multiClusterApps.AddHandler(ctx, "management-multiclusterapp-rbac-controller", m.sync) + management.Management.MultiClusterAppRevisions("").AddHandler(ctx, "management-multiclusterapp-revisions-rbac", r.sync) + projects.AddHandler(ctx, "management-mcapp-project-controller", p.sync) + clusters.AddHandler(ctx, "management-mcapp-cluster-controller", c.sync) + + StartMCAppStateController(ctx, management) + StartMCAppManagementController(ctx, management, clusterManager) + StartMCAppEnqueueController(ctx, management) +} + +func (mc *MCAppController) sync(key string, mcapp *v3.MultiClusterApp) (runtime.Object, error) { + if mcapp == nil || mcapp.DeletionTimestamp != nil { + // multiclusterapp is being deleted, remove the sys acc created for it + _, mcappName, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, err + } + u, err := mc.userManager.GetUserByPrincipalID(fmt.Sprintf("system://%s", mcappName)) + if err != nil { + return nil, err + } + if u == nil { + // user not found, must have been removed + return nil, nil + } + if err := mc.users.Delete(u.Name, &v1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return nil, err + } + return nil, nil + } + metaAccessor, err := meta.Accessor(mcapp) + if err != nil { + return mcapp, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return mcapp, fmt.Errorf("MultiClusterApp %v has no creatorId annotation. Cannot create apps for %v", metaAccessor.GetName(), mcapp.Name) + } + + systemUserPrincipalID := fmt.Sprintf("system://%s", mcapp.Name) + systemUser, err := mc.userManager.EnsureUser(systemUserPrincipalID, "System account for Multiclusterapp "+mcapp.Name) + if err != nil { + return nil, err + } + var prtbName, crtbName string + // create PRTBs with this service account for all roles of multiclusterapp + for _, r := range mcapp.Spec.Roles { + rt, err := mc.rtLister.Get("", r) + if err != nil { + return nil, err + } + + for _, p := range mcapp.Spec.Targets { + if p.ProjectName == "" { + continue + } + split := strings.SplitN(p.ProjectName, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("invalid project name") + } + clusterName := split[0] + projectName := split[1] + + if rt.Context == "project" { + prtbName = mcapp.Name + "-" + r + // check if these prtbs already exist + if err = mc.createPrtb(projectName, p.ProjectName, prtbName, r, systemUser.Name, systemUserPrincipalID); err != nil { + return nil, err + } + } else if rt.Context == "cluster" { + crtbName = mcapp.Name + "-" + r + mc.createCrtb(clusterName, crtbName, r, systemUser.Name, systemUserPrincipalID) + } + } + } + + if err := rbac.CreateRoleAndRoleBinding(rbac.MultiClusterAppResource, v3.MultiClusterAppGroupVersionKind.Kind, mcapp.Name, namespace.GlobalNamespace, + rbac.RancherManagementAPIVersion, creatorID, []string{rbac.RancherManagementAPIGroup}, + mcapp.UID, + mcapp.Spec.Members, mc.managementContext); err != nil { + return nil, err + } + + // see if any revision exists and call CreateRoleAndRoleBinding for it so that if this is an update request adding/removing members, + // it reflects on the permissions for revisions too + revisions, err := mc.multiClusterAppRevisionLister.List(namespace.GlobalNamespace, labels.SelectorFromSet(map[string]string{mcAppLabel: mcapp.Name})) + if err != nil { + return mcapp, err + } + for _, rev := range revisions { + if err := rbac.CreateRoleAndRoleBinding( + rbac.MultiClusterAppRevisionResource, v3.MultiClusterAppRevisionGroupVersionKind.Kind, rev.Name, namespace.GlobalNamespace, rbac.RancherManagementAPIVersion, + creatorID, []string{rbac.RancherManagementAPIGroup}, rev.UID, mcapp.Spec.Members, + mc.managementContext); err != nil { + return nil, err + } + } + + return nil, nil +} + +func (r *MCAppRevisionController) sync(key string, mcappRevision *v3.MultiClusterAppRevision) (runtime.Object, error) { + if mcappRevision == nil || mcappRevision.DeletionTimestamp != nil { + return mcappRevision, nil + } + + if err := r.updateOwnerRef(mcappRevision); err != nil { + return mcappRevision, err + } + + metaAccessor, err := meta.Accessor(mcappRevision) + if err != nil { + return mcappRevision, err + } + creatorID, ok := metaAccessor.GetAnnotations()[rbac.CreatorIDAnn] + if !ok { + return mcappRevision, fmt.Errorf("mcapp revision %v has no creatorId annotation", mcappRevision.Name) + } + // get the Members field from mcapp + mcappName, ok := mcappRevision.Labels[mcAppLabel] + if !ok { + return mcappRevision, fmt.Errorf("mcapp revision created without setting mcapp label") + } + mcapp, err := r.multiClusterAppLister.Get(namespace.GlobalNamespace, mcappName) + if err != nil { + return mcappRevision, err + } + + if err := rbac.CreateRoleAndRoleBinding( + rbac.MultiClusterAppRevisionResource, v3.MultiClusterAppRevisionGroupVersionKind.Kind, mcappRevision.Name, namespace.GlobalNamespace, rbac.RancherManagementAPIVersion, + creatorID, []string{rbac.RancherManagementAPIGroup}, mcappRevision.UID, mcapp.Spec.Members, + r.managementContext); err != nil { + return nil, err + } + + return mcappRevision, nil +} + +func (r *MCAppRevisionController) updateOwnerRef(mcappRevision *v3.MultiClusterAppRevision) error { + /* MCAppRevision has had wrong OwnerReference format till 2.5, the ownerReference kind should be "MultiClusterApp" and not "multiclusterapps" + ownerReferences: + - apiVersion: management.cattle.io/v3 + kind: multiclusterapps + name: datadogmcapp + uid: 32cdd51f-b152-44fa-93bb-1054a3203541 + The revisions created before 2.5 need to be updated to use the right format + */ + if mcappRevision.Labels != nil && mcappRevision.Labels[ownerRefUpdated] == "true" { + return nil + } + var needsUpdate bool + for ind, ownerRef := range mcappRevision.OwnerReferences { + if ownerRef.Kind == "multiclusterapps" { + ownerRef.Kind = v3.MultiClusterAppGroupVersionKind.Kind + mcappRevision.OwnerReferences[ind] = ownerRef + needsUpdate = true + } + } + + if !needsUpdate { + return nil + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + mcappRevisionToUpdate, updateErr := r.multiClusterAppRevisions.GetNamespaced(mcappRevision.Namespace, mcappRevision.Name, v1.GetOptions{}) + if updateErr != nil { + return updateErr + } + mcappRevisionToUpdate.OwnerReferences = mcappRevision.OwnerReferences + if mcappRevisionToUpdate.Labels == nil { + mcappRevisionToUpdate.Labels = make(map[string]string) + } + mcappRevisionToUpdate.Labels[ownerRefUpdated] = "true" + _, err := r.multiClusterAppRevisions.Update(mcappRevisionToUpdate) + return err + }) + + return retryErr +} + +func (p *ProjectController) sync(key string, project *v3.Project) (runtime.Object, error) { + if project != nil && project.DeletionTimestamp == nil { + return project, nil + } + splitKey := strings.SplitN(key, "/", 2) + if len(splitKey) != 2 || splitKey[0] == "" || splitKey[1] == "" { + return project, fmt.Errorf("invalid project id %s", key) + } + clusterName, projectName := splitKey[0], splitKey[1] + key = fmt.Sprintf("%s:%s", clusterName, projectName) + mcApps, err := p.mcAppsLister.List(namespace.GlobalNamespace, labels.NewSelector()) + if err != nil { + return project, err + } + for _, mcApp := range mcApps { + if mcApp.DeletionTimestamp != nil { + continue + } + var toUpdate *v3.MultiClusterApp + for i, target := range mcApp.Spec.Targets { + if target.ProjectName == key { + toUpdate = mcApp.DeepCopy() + toUpdate.Spec.Targets = append(toUpdate.Spec.Targets[:i], toUpdate.Spec.Targets[i+1:]...) + p.updateAnswersForProject(key, toUpdate) + break + } + } + if toUpdate != nil { + if _, err := p.mcApps.Update(toUpdate); err != nil { + return project, fmt.Errorf("error updating mcapp %s for project %s", mcApp.Name, key) + } + } + } + return project, nil +} + +func (p *ProjectController) updateAnswersForProject(projectName string, mcapp *v3.MultiClusterApp) { + for i := len(mcapp.Spec.Answers) - 1; i >= 0; i-- { + if mcapp.Spec.Answers[i].ProjectName == projectName { + mcapp.Spec.Answers = append(mcapp.Spec.Answers[:i], mcapp.Spec.Answers[i+1:]...) + break + } + } +} + +func (c *ClusterController) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster != nil && cluster.DeletionTimestamp == nil { + return cluster, nil + } + mcApps, err := c.mcAppsLister.List(namespace.GlobalNamespace, labels.NewSelector()) + if err != nil { + return cluster, err + } + for _, mcApp := range mcApps { + if mcApp.DeletionTimestamp != nil { + continue + } + var toUpdate *v3.MultiClusterApp + for i := len(mcApp.Spec.Targets) - 1; i >= 0; i-- { + clusterName, _ := ref.Parse(mcApp.Spec.Targets[i].ProjectName) + if clusterName == key { + if toUpdate == nil { + toUpdate = mcApp.DeepCopy() + } + toUpdate.Spec.Targets = append(toUpdate.Spec.Targets[:i], toUpdate.Spec.Targets[i+1:]...) + } + } + if toUpdate != nil { + c.updateAnswersForCluster(key, toUpdate) + if _, err := c.mcApps.Update(toUpdate); err != nil { + return cluster, fmt.Errorf("error updating mcapp %s for cluster %s", mcApp.Name, key) + } + } + } + return cluster, nil +} + +func (c *ClusterController) updateAnswersForCluster(clusterName string, mcapp *v3.MultiClusterApp) { + for i := len(mcapp.Spec.Answers) - 1; i >= 0; i-- { + projClusterName, _ := ref.Parse(mcapp.Spec.Answers[i].ProjectName) + if mcapp.Spec.Answers[i].ClusterName == clusterName || projClusterName == clusterName { + mcapp.Spec.Answers = append(mcapp.Spec.Answers[:i], mcapp.Spec.Answers[i+1:]...) + } + } +} + +func (mc *MCAppController) createPrtb(projectName, projectID, prtbName, roleTemplateName, systemUserName, systemUserPrincipalID string) error { + _, err := mc.prtbLister.Get(projectName, prtbName) + if err != nil { + if apierrors.IsNotFound(err) { + _, err := mc.prtbs.Create(&v3.ProjectRoleTemplateBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: prtbName, + Namespace: projectName, + }, + UserName: systemUserName, + UserPrincipalName: systemUserPrincipalID, + RoleTemplateName: roleTemplateName, + ProjectName: projectID, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else { + return err + } + } + return nil +} + +func (mc *MCAppController) createCrtb(clusterName, crtbName, roleTemplateName, systemUserName, systemUserPrincipalID string) error { + _, err := mc.crtbLister.Get(clusterName, crtbName) + if err != nil { + if apierrors.IsNotFound(err) { + _, err := mc.crtbs.Create(&v3.ClusterRoleTemplateBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: crtbName, + Namespace: clusterName, + }, + UserName: systemUserName, + UserPrincipalName: systemUserPrincipalID, + RoleTemplateName: roleTemplateName, + ClusterName: clusterName, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else { + return err + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/interval.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/interval.go new file mode 100644 index 0000000..4cc33e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/interval.go @@ -0,0 +1,63 @@ +package multiclusterapp + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" +) + +type IntervalData struct { + interval int + cancelFunc context.CancelFunc +} + +var mcAppTickerData map[string]*IntervalData +var mcAppDataLock = sync.Mutex{} + +func storeContext(cctx context.Context, mcapp *v3.MultiClusterApp, mcApps v3.MultiClusterAppInterface) { + if mcapp.Spec.UpgradeStrategy.RollingUpdate == nil { + return + } + set := mcapp.Spec.UpgradeStrategy.RollingUpdate.Interval + if set == 0 { + return + } + defer mcAppDataLock.Unlock() + mcAppDataLock.Lock() + if data, ok := mcAppTickerData[mcapp.Name]; ok { + if data.interval == set { + return + } + data.interval = set + data.cancelFunc() + delete(mcAppTickerData, mcapp.Name) + } + ctx, cancel := context.WithCancel(cctx) + go startTicker(ctx, set, mcApps, mcapp.Name) + mcAppTickerData[mcapp.Name] = &IntervalData{ + interval: set, + cancelFunc: cancel, + } +} + +func deleteContext(mcappName string) { + mcAppDataLock.Lock() + if data, ok := mcAppTickerData[mcappName]; ok { + data.cancelFunc() + delete(mcAppTickerData, mcappName) + } + mcAppDataLock.Unlock() +} + +func startTicker(ctx context.Context, set int, mcApps v3.MultiClusterAppInterface, name string) { + interval := time.Duration(set) * time.Second + for range ticker.Context(ctx, interval) { + logrus.Debugf("mcappTicker: interval %v enqueue %s", set, name) + mcApps.Controller().Enqueue(namespace.GlobalNamespace, name) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/state.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/state.go new file mode 100644 index 0000000..6f6e5cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementlegacy/multiclusterapp/state.go @@ -0,0 +1,138 @@ +package multiclusterapp + +import ( + "context" + "fmt" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v33 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + installing = "installing" + deploying = "deploying" + active = "active" +) + +// StartMCAppStateController gets all corresponding apps and update condition on multi cluster app sync +func StartMCAppStateController(ctx context.Context, management *config.ManagementContext) { + mcApps := management.Management.MultiClusterApps("") + s := &MCAppStateController{ + Apps: management.Project.Apps("").Controller().Lister(), + MultiClusterApps: mcApps, + } + mcApps.AddHandler(ctx, "multi-cluster-app-state-controller", s.sync) +} + +type MCAppStateController struct { + Apps pv3.AppLister + MultiClusterApps v3.MultiClusterAppInterface +} + +func (m *MCAppStateController) sync(key string, mcapp *v3.MultiClusterApp) (runtime.Object, error) { + if mcapp == nil || mcapp.DeletionTimestamp != nil { + return mcapp, nil + } + mcappState := active + if v32.MultiClusterAppConditionInstalled.IsUnknown(mcapp) && v32.MultiClusterAppConditionInstalled.GetMessage(mcapp) == "upgrading" { + mcappState = "" + } + var toUpdate *v3.MultiClusterApp + for ind, t := range mcapp.Spec.Targets { + if t.AppName == "" { + mcappState = installing + continue + } + split := strings.SplitN(t.ProjectName, ":", 2) + if len(split) != 2 { + return mcapp, fmt.Errorf("error in splitting project ID %v", t.ProjectName) + } + projectNS := split[1] + app, err := m.Apps.Get(projectNS, t.AppName) + if err != nil { + if errors.IsNotFound(err) { + logrus.Debugf("app %s not found for mcapp %s in projectNS %s", t.AppName, mcapp.Name, projectNS) + if mcappState != "" { + mcappState = installing + } + continue + } + return mcapp, err + } + if value, ok := app.Labels[MultiClusterAppIDSelector]; !ok || value != mcapp.Name { + return mcapp, fmt.Errorf("app %s missing label selector for %s", t.AppName, mcapp.Name) + } + if !v33.AppConditionInstalled.IsTrue(app) { + toUpdate = setAppState(toUpdate, ind, installing, mcapp) + if mcappState != "" { + mcappState = installing + } + } else if !v33.AppConditionDeployed.IsTrue(app) { + toUpdate = setAppState(toUpdate, ind, deploying, mcapp) + if mcappState == active { + mcappState = deploying + } + } else { + toUpdate = setAppState(toUpdate, ind, active, mcapp) + } + } + if mcappState == installing || mcappState == deploying { + toUpdate = setMcAppStateUnknown(toUpdate, mcapp, mcappState) + } else if mcappState == active { + toUpdate = setMcappStateActive(toUpdate, mcapp) + } + if toUpdate != nil { + return m.MultiClusterApps.Update(toUpdate) + } + return mcapp, nil +} + +func setAppState(toUpdate *v3.MultiClusterApp, ind int, state string, mcapp *v3.MultiClusterApp) *v3.MultiClusterApp { + if mcapp.Spec.Targets[ind].State == state { + return toUpdate + } + if toUpdate == nil { + toUpdate = mcapp.DeepCopy() + } + toUpdate.Spec.Targets[ind].State = state + return toUpdate +} + +func setMcappStateActive(toUpdate *v3.MultiClusterApp, mcapp *v3.MultiClusterApp) *v3.MultiClusterApp { + if v32.MultiClusterAppConditionInstalled.IsTrue(mcapp) && v32.MultiClusterAppConditionDeployed.IsTrue(mcapp) { + return toUpdate + } + if toUpdate == nil { + toUpdate = mcapp.DeepCopy() + } + v32.MultiClusterAppConditionDeployed.True(toUpdate) + v32.MultiClusterAppConditionInstalled.True(toUpdate) + return toUpdate +} + +func setMcAppStateUnknown(toUpdate *v3.MultiClusterApp, mcapp *v3.MultiClusterApp, state string) *v3.MultiClusterApp { + cond := v32.MultiClusterAppConditionInstalled + cleanCond := v32.MultiClusterAppConditionDeployed + if state == deploying { + cond = v32.MultiClusterAppConditionDeployed + cleanCond = v32.MultiClusterAppConditionInstalled + } + if !cond.IsUnknown(mcapp) { + if toUpdate == nil { + toUpdate = mcapp.DeepCopy() + } + if cleanCond.IsUnknown(toUpdate) { + cleanCond.True(toUpdate) + } + cond.Unknown(toUpdate) + } + return toUpdate +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator.go new file mode 100644 index 0000000..a080042 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator.go @@ -0,0 +1,80 @@ +package cavalidator + +import ( + "context" + + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/condition" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + CertificateAuthorityValid = condition.Cond("AgentTlsStrictCheck") + CacertsValid = "CATTLE_CACERTS_VALID" +) + +type CertificateAuthorityValidator struct { + clusterName string + clusterLister v3.ClusterLister + clusters v3.ClusterInterface + secrets corev1.SecretController +} + +func Register(ctx context.Context, downstream *config.UserContext) { + c := &CertificateAuthorityValidator{ + clusterName: downstream.ClusterName, + clusterLister: downstream.Management.Management.Clusters("").Controller().Lister(), + clusters: downstream.Management.Management.Clusters(""), + secrets: downstream.Core.Secrets(namespace.System).Controller(), + } + + c.secrets.AddHandler(ctx, "cavalidator-secret", c.onStvAggregationSecret) +} + +func (c *CertificateAuthorityValidator) onStvAggregationSecret(_ string, obj *corev1.Secret) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + + if obj.Name == "stv-aggregation" && obj.Namespace == namespace.System { + mgmtCluster, err := c.clusterLister.Get("", c.clusterName) + if err != nil { + return obj, err + } + if string(obj.Data[CacertsValid]) == "true" && len(obj.Data["ca.crt"]) != 0 { + if !CertificateAuthorityValid.IsTrue(mgmtCluster) { + newMgmtCluster := mgmtCluster.DeepCopy() + CertificateAuthorityValid.True(newMgmtCluster) + _, err = c.clusters.Update(newMgmtCluster) + if err != nil { + return obj, err + } + } + return obj, nil + } + var needsUpdate bool + if string(obj.Data[CacertsValid]) == "false" { + if !CertificateAuthorityValid.IsFalse(mgmtCluster) { + needsUpdate = true + mgmtCluster = mgmtCluster.DeepCopy() + CertificateAuthorityValid.False(mgmtCluster) + } + } else { + if !CertificateAuthorityValid.IsUnknown(mgmtCluster) { + needsUpdate = true + mgmtCluster = mgmtCluster.DeepCopy() + CertificateAuthorityValid.Unknown(mgmtCluster) + } + } + if needsUpdate { + _, err = c.clusters.Update(mgmtCluster) + if err != nil { + return obj, err + } + } + } + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator_test.go new file mode 100644 index 0000000..c815dc1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/cavalidator_test.go @@ -0,0 +1,167 @@ +// mocks created with the following commands +// +// mockgen --build_flags=--mod=mod -package cavalidator -destination ./v3mgmntMocks_test.go github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3 ClusterInterface,ClusterLister +// mockgen --build_flags=--mod=mod -package cavalidator -destination ./v1coreMocks_test.go github.com/rancher/rancher/pkg/generated/norman/core/v1 SecretController + +package cavalidator + +import ( + "github.com/golang/mock/gomock" + mgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "testing" +) + +type testMocks struct { + t *testing.T + mockCluster *MockClusterInterface + mockClusterLister *MockClusterLister + mockSecret *MockSecretController +} + +func newMocks(t *testing.T) *testMocks { + t.Helper() + ctrl := gomock.NewController(t) + return &testMocks{ + t: t, + mockCluster: NewMockClusterInterface(ctrl), + mockClusterLister: NewMockClusterLister(ctrl), + mockSecret: NewMockSecretController(ctrl), + } +} + +func TestCAValidator_clusterConditionManipulation(t *testing.T) { + type args struct { + conditionSet bool + expectedConditionValue string + secret *corev1.Secret + cluster *mgmtv3.Cluster + } + + tests := []struct { + name string + args args + }{ + { + name: "test-empty-secret-unknown", + args: args{ + conditionSet: true, + expectedConditionValue: "Unknown", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "stv-aggregation", + Namespace: namespace.System, + }, + }, + cluster: &mgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-cluster", + }, + }, + }, + }, + { + name: "test-bad-but-stv-aggregation-secret", + args: args{ + conditionSet: true, + expectedConditionValue: "Unknown", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "stv-aggregation", + Namespace: namespace.System, + }, + Data: map[string][]byte{ + CacertsValid: []byte("asdf"), + "ca.crt": []byte("test"), + }, + }, + cluster: &mgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-cluster", + }, + }, + }, + }, + { + name: "test-good-ca", + args: args{ + conditionSet: true, + expectedConditionValue: "True", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "stv-aggregation", + Namespace: namespace.System, + }, + Data: map[string][]byte{ + CacertsValid: []byte("true"), + "ca.crt": []byte("test"), + }, + }, + cluster: &mgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-cluster", + }, + }, + }, + }, + { + name: "test-bad-ca", + args: args{ + conditionSet: true, + expectedConditionValue: "False", + secret: &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "stv-aggregation", + Namespace: namespace.System, + }, + Data: map[string][]byte{ + CacertsValid: []byte("false"), + "ca.crt": []byte("test"), + }, + }, + cluster: &mgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-cluster", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mocks := newMocks(t) + cav := &CertificateAuthorityValidator{ + clusterName: tt.args.cluster.Name, + clusterLister: mocks.mockClusterLister, + clusters: mocks.mockCluster, + secrets: mocks.mockSecret, + } + + a := assert.New(t) + + if tt.args.secret != nil && tt.args.secret.Name == "stv-aggregation" && tt.args.secret.Namespace == namespace.System { + mocks.mockClusterLister.EXPECT().Get("", tt.args.cluster.Name).Return(tt.args.cluster, nil) + } + + if tt.args.conditionSet { + mocks.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *mgmtv3.Cluster) (*mgmtv3.Cluster, error) { + if tt.args.conditionSet { + require.Len(t, cluster.Status.Conditions, 1) + require.Equal(t, string(CertificateAuthorityValid), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(t, tt.args.expectedConditionValue, string(cluster.Status.Conditions[0].Status), "expected condition value to be set") + } else { + require.Len(t, cluster.Status.Conditions, 0) + } + return cluster, nil + }) + } + + _, err := cav.onStvAggregationSecret(tt.args.secret.Name, tt.args.secret) + a.NoError(err) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v1coreMocks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v1coreMocks_test.go new file mode 100644 index 0000000..c3d2397 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v1coreMocks_test.go @@ -0,0 +1,153 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/generated/norman/core/v1 (interfaces: SecretController) + +// Package cavalidator is a generated GoMock package. +package cavalidator + +import ( + context "context" + reflect "reflect" + time "time" + + gomock "github.com/golang/mock/gomock" + controller "github.com/rancher/norman/controller" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + cache "k8s.io/client-go/tools/cache" +) + +// MockSecretController is a mock of SecretController interface. +type MockSecretController struct { + ctrl *gomock.Controller + recorder *MockSecretControllerMockRecorder +} + +// MockSecretControllerMockRecorder is the mock recorder for MockSecretController. +type MockSecretControllerMockRecorder struct { + mock *MockSecretController +} + +// NewMockSecretController creates a new mock instance. +func NewMockSecretController(ctrl *gomock.Controller) *MockSecretController { + mock := &MockSecretController{ctrl: ctrl} + mock.recorder = &MockSecretControllerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSecretController) EXPECT() *MockSecretControllerMockRecorder { + return m.recorder +} + +// AddClusterScopedFeatureHandler mocks base method. +func (m *MockSecretController) AddClusterScopedFeatureHandler(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v1.SecretHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureHandler", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureHandler indicates an expected call of AddClusterScopedFeatureHandler. +func (mr *MockSecretControllerMockRecorder) AddClusterScopedFeatureHandler(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureHandler", reflect.TypeOf((*MockSecretController)(nil).AddClusterScopedFeatureHandler), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedHandler mocks base method. +func (m *MockSecretController) AddClusterScopedHandler(arg0 context.Context, arg1, arg2 string, arg3 v1.SecretHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedHandler", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedHandler indicates an expected call of AddClusterScopedHandler. +func (mr *MockSecretControllerMockRecorder) AddClusterScopedHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedHandler", reflect.TypeOf((*MockSecretController)(nil).AddClusterScopedHandler), arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler mocks base method. +func (m *MockSecretController) AddFeatureHandler(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v1.SecretHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureHandler", arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler indicates an expected call of AddFeatureHandler. +func (mr *MockSecretControllerMockRecorder) AddFeatureHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureHandler", reflect.TypeOf((*MockSecretController)(nil).AddFeatureHandler), arg0, arg1, arg2, arg3) +} + +// AddHandler mocks base method. +func (m *MockSecretController) AddHandler(arg0 context.Context, arg1 string, arg2 v1.SecretHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddHandler", arg0, arg1, arg2) +} + +// AddHandler indicates an expected call of AddHandler. +func (mr *MockSecretControllerMockRecorder) AddHandler(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddHandler", reflect.TypeOf((*MockSecretController)(nil).AddHandler), arg0, arg1, arg2) +} + +// Enqueue mocks base method. +func (m *MockSecretController) Enqueue(arg0, arg1 string) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Enqueue", arg0, arg1) +} + +// Enqueue indicates an expected call of Enqueue. +func (mr *MockSecretControllerMockRecorder) Enqueue(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enqueue", reflect.TypeOf((*MockSecretController)(nil).Enqueue), arg0, arg1) +} + +// EnqueueAfter mocks base method. +func (m *MockSecretController) EnqueueAfter(arg0, arg1 string, arg2 time.Duration) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "EnqueueAfter", arg0, arg1, arg2) +} + +// EnqueueAfter indicates an expected call of EnqueueAfter. +func (mr *MockSecretControllerMockRecorder) EnqueueAfter(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnqueueAfter", reflect.TypeOf((*MockSecretController)(nil).EnqueueAfter), arg0, arg1, arg2) +} + +// Generic mocks base method. +func (m *MockSecretController) Generic() controller.GenericController { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Generic") + ret0, _ := ret[0].(controller.GenericController) + return ret0 +} + +// Generic indicates an expected call of Generic. +func (mr *MockSecretControllerMockRecorder) Generic() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Generic", reflect.TypeOf((*MockSecretController)(nil).Generic)) +} + +// Informer mocks base method. +func (m *MockSecretController) Informer() cache.SharedIndexInformer { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Informer") + ret0, _ := ret[0].(cache.SharedIndexInformer) + return ret0 +} + +// Informer indicates an expected call of Informer. +func (mr *MockSecretControllerMockRecorder) Informer() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Informer", reflect.TypeOf((*MockSecretController)(nil).Informer)) +} + +// Lister mocks base method. +func (m *MockSecretController) Lister() v1.SecretLister { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Lister") + ret0, _ := ret[0].(v1.SecretLister) + return ret0 +} + +// Lister indicates an expected call of Lister. +func (mr *MockSecretControllerMockRecorder) Lister() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lister", reflect.TypeOf((*MockSecretController)(nil).Lister)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v3mgmntMocks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v3mgmntMocks_test.go new file mode 100644 index 0000000..2e30b5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/cavalidator/v3mgmntMocks_test.go @@ -0,0 +1,365 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3 (interfaces: ClusterInterface,ClusterLister) + +// Package cavalidator is a generated GoMock package. +package cavalidator + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + objectclient "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v30 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + watch "k8s.io/apimachinery/pkg/watch" +) + +// MockClusterInterface is a mock of ClusterInterface interface. +type MockClusterInterface struct { + ctrl *gomock.Controller + recorder *MockClusterInterfaceMockRecorder +} + +// MockClusterInterfaceMockRecorder is the mock recorder for MockClusterInterface. +type MockClusterInterfaceMockRecorder struct { + mock *MockClusterInterface +} + +// NewMockClusterInterface creates a new mock instance. +func NewMockClusterInterface(ctrl *gomock.Controller) *MockClusterInterface { + mock := &MockClusterInterface{ctrl: ctrl} + mock.recorder = &MockClusterInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterInterface) EXPECT() *MockClusterInterfaceMockRecorder { + return m.recorder +} + +// AddClusterScopedFeatureHandler mocks base method. +func (m *MockClusterInterface) AddClusterScopedFeatureHandler(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureHandler", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureHandler indicates an expected call of AddClusterScopedFeatureHandler. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedFeatureHandler(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedFeatureHandler), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle mocks base method. +func (m *MockClusterInterface) AddClusterScopedFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureLifecycle", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle indicates an expected call of AddClusterScopedFeatureLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedFeatureLifecycle(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedFeatureLifecycle), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedHandler mocks base method. +func (m *MockClusterInterface) AddClusterScopedHandler(arg0 context.Context, arg1, arg2 string, arg3 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedHandler", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedHandler indicates an expected call of AddClusterScopedHandler. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedHandler), arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle mocks base method. +func (m *MockClusterInterface) AddClusterScopedLifecycle(arg0 context.Context, arg1, arg2 string, arg3 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedLifecycle", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle indicates an expected call of AddClusterScopedLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedLifecycle), arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler mocks base method. +func (m *MockClusterInterface) AddFeatureHandler(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureHandler", arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler indicates an expected call of AddFeatureHandler. +func (mr *MockClusterInterfaceMockRecorder) AddFeatureHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddFeatureHandler), arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle mocks base method. +func (m *MockClusterInterface) AddFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureLifecycle", arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle indicates an expected call of AddFeatureLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddFeatureLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddFeatureLifecycle), arg0, arg1, arg2, arg3) +} + +// AddHandler mocks base method. +func (m *MockClusterInterface) AddHandler(arg0 context.Context, arg1 string, arg2 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddHandler", arg0, arg1, arg2) +} + +// AddHandler indicates an expected call of AddHandler. +func (mr *MockClusterInterfaceMockRecorder) AddHandler(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddHandler), arg0, arg1, arg2) +} + +// AddLifecycle mocks base method. +func (m *MockClusterInterface) AddLifecycle(arg0 context.Context, arg1 string, arg2 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddLifecycle", arg0, arg1, arg2) +} + +// AddLifecycle indicates an expected call of AddLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddLifecycle(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddLifecycle), arg0, arg1, arg2) +} + +// Controller mocks base method. +func (m *MockClusterInterface) Controller() v30.ClusterController { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Controller") + ret0, _ := ret[0].(v30.ClusterController) + return ret0 +} + +// Controller indicates an expected call of Controller. +func (mr *MockClusterInterfaceMockRecorder) Controller() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Controller", reflect.TypeOf((*MockClusterInterface)(nil).Controller)) +} + +// Create mocks base method. +func (m *MockClusterInterface) Create(arg0 *v3.Cluster) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockClusterInterfaceMockRecorder) Create(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClusterInterface)(nil).Create), arg0) +} + +// Delete mocks base method. +func (m *MockClusterInterface) Delete(arg0 string, arg1 *v1.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClusterInterfaceMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClusterInterface)(nil).Delete), arg0, arg1) +} + +// DeleteCollection mocks base method. +func (m *MockClusterInterface) DeleteCollection(arg0 *v1.DeleteOptions, arg1 v1.ListOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteCollection", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteCollection indicates an expected call of DeleteCollection. +func (mr *MockClusterInterfaceMockRecorder) DeleteCollection(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCollection", reflect.TypeOf((*MockClusterInterface)(nil).DeleteCollection), arg0, arg1) +} + +// DeleteNamespaced mocks base method. +func (m *MockClusterInterface) DeleteNamespaced(arg0, arg1 string, arg2 *v1.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteNamespaced indicates an expected call of DeleteNamespaced. +func (mr *MockClusterInterfaceMockRecorder) DeleteNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).DeleteNamespaced), arg0, arg1, arg2) +} + +// Get mocks base method. +func (m *MockClusterInterface) Get(arg0 string, arg1 v1.GetOptions) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClusterInterfaceMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClusterInterface)(nil).Get), arg0, arg1) +} + +// GetNamespaced mocks base method. +func (m *MockClusterInterface) GetNamespaced(arg0, arg1 string, arg2 v1.GetOptions) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNamespaced indicates an expected call of GetNamespaced. +func (mr *MockClusterInterfaceMockRecorder) GetNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).GetNamespaced), arg0, arg1, arg2) +} + +// List mocks base method. +func (m *MockClusterInterface) List(arg0 v1.ListOptions) (*v3.ClusterList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", arg0) + ret0, _ := ret[0].(*v3.ClusterList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClusterInterfaceMockRecorder) List(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClusterInterface)(nil).List), arg0) +} + +// ListNamespaced mocks base method. +func (m *MockClusterInterface) ListNamespaced(arg0 string, arg1 v1.ListOptions) (*v3.ClusterList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListNamespaced", arg0, arg1) + ret0, _ := ret[0].(*v3.ClusterList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListNamespaced indicates an expected call of ListNamespaced. +func (mr *MockClusterInterfaceMockRecorder) ListNamespaced(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).ListNamespaced), arg0, arg1) +} + +// ObjectClient mocks base method. +func (m *MockClusterInterface) ObjectClient() *objectclient.ObjectClient { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ObjectClient") + ret0, _ := ret[0].(*objectclient.ObjectClient) + return ret0 +} + +// ObjectClient indicates an expected call of ObjectClient. +func (mr *MockClusterInterfaceMockRecorder) ObjectClient() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ObjectClient", reflect.TypeOf((*MockClusterInterface)(nil).ObjectClient)) +} + +// Update mocks base method. +func (m *MockClusterInterface) Update(arg0 *v3.Cluster) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockClusterInterfaceMockRecorder) Update(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockClusterInterface)(nil).Update), arg0) +} + +// Watch mocks base method. +func (m *MockClusterInterface) Watch(arg0 v1.ListOptions) (watch.Interface, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Watch", arg0) + ret0, _ := ret[0].(watch.Interface) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Watch indicates an expected call of Watch. +func (mr *MockClusterInterfaceMockRecorder) Watch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClusterInterface)(nil).Watch), arg0) +} + +// MockClusterLister is a mock of ClusterLister interface. +type MockClusterLister struct { + ctrl *gomock.Controller + recorder *MockClusterListerMockRecorder +} + +// MockClusterListerMockRecorder is the mock recorder for MockClusterLister. +type MockClusterListerMockRecorder struct { + mock *MockClusterLister +} + +// NewMockClusterLister creates a new mock instance. +func NewMockClusterLister(ctrl *gomock.Controller) *MockClusterLister { + mock := &MockClusterLister{ctrl: ctrl} + mock.recorder = &MockClusterListerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterLister) EXPECT() *MockClusterListerMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockClusterLister) Get(arg0, arg1 string) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClusterListerMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClusterLister)(nil).Get), arg0, arg1) +} + +// List mocks base method. +func (m *MockClusterLister) List(arg0 string, arg1 labels.Selector) ([]*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", arg0, arg1) + ret0, _ := ret[0].([]*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClusterListerMockRecorder) List(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClusterLister)(nil).List), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration.go new file mode 100644 index 0000000..6a5c734 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration.go @@ -0,0 +1,189 @@ +package certsexpiration + +import ( + "context" + "encoding/json" + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rketypes "github.com/rancher/rke/types" + + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/cluster" + "github.com/rancher/rancher/pkg/rkecerts" + "github.com/rancher/rancher/pkg/types/config" + rkecluster "github.com/rancher/rke/cluster" + "github.com/rancher/rke/hosts" + "github.com/rancher/rke/pki" + "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +type Controller struct { + ClusterName string + ClusterLister v3.ClusterLister + ClusterClient v3.ClusterInterface + ClusterStore cluster.PersistentStore + SecretLister v1.SecretLister +} + +func Register(ctx context.Context, userContext *config.UserContext) { + starter := userContext.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, userContext) + return nil + }) + + clusters := userContext.Management.Management.Clusters("") + clusters.AddHandler(ctx, "certs-expiration-deferred", func(key string, obj *v32.Cluster) (runtime.Object, error) { + if obj != nil && + obj.Name == userContext.ClusterName && + obj.Spec.RancherKubernetesEngineConfig != nil && + obj.Status.AppliedSpec.RancherKubernetesEngineConfig != nil { + return obj, starter() + } + return obj, nil + }) +} + +func registerDeferred(ctx context.Context, userContext *config.UserContext) { + c := &Controller{ + ClusterName: userContext.ClusterName, + ClusterLister: userContext.Management.Management.Clusters("").Controller().Lister(), + ClusterClient: userContext.Management.Management.Clusters(""), + ClusterStore: clusterprovisioner.NewPersistentStore(userContext.Management.Core.Namespaces(""), userContext.Management.Core), + SecretLister: userContext.Core.Secrets("").Controller().Lister(), + } + + userContext.Management.Management.Clusters("").AddHandler(ctx, "certificate-expiration", c.sync) +} + +func (c Controller) sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if key == "" || cluster == nil || cluster.DeletionTimestamp != nil || cluster.Name != c.ClusterName { + return cluster, nil + } + + if cluster.Spec.RancherKubernetesEngineConfig == nil { + return cluster, nil + } + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + return cluster, nil + } + certsExpInfo := map[string]v32.CertExpiration{} + + cluster, err := c.ClusterLister.Get("", key) + if err != nil { + return cluster, err + } + certBundle, err := c.getClusterCertificateBundle(cluster.Name) + if err != nil { + return cluster, err + } + for certName, certObj := range certBundle { + info, err := rkecerts.GetCertExpiration(certObj.CertificatePEM) + if err != nil { + logrus.Debugf("failed to get expiration date for certificate [%s] for cluster [%s]:%v", certName, key, err) + continue + } + certsExpInfo[certName] = info + } + logrus.Debugf("Checking and deleting unused certificates for cluster %s", cluster.Name) + deleteUnusedCerts(certsExpInfo, cluster.Status.AppliedSpec.RancherKubernetesEngineConfig) + if !reflect.DeepEqual(cluster.Status.CertificatesExpiration, certsExpInfo) { + toUpdate := cluster.DeepCopy() + toUpdate.Status.CertificatesExpiration = certsExpInfo + return c.ClusterClient.Update(toUpdate) + } + return cluster, nil + +} + +func (c Controller) getClusterCertificateBundle(clusterName string) (map[string]pki.CertificatePKI, error) { + // cluster has a state file ? + currentState, err := getRKECurrentStateFromStore(c.ClusterStore, clusterName) + if err != nil { + return nil, err + } + if currentState != nil { + rkecerts.CleanCertificateBundle(currentState.CertificatesBundle) + return currentState.CertificatesBundle, nil + } + + // No state file, let's try get the certs from the user cluster + certs, err := c.getCertsFromUserCluster() + if err != nil { + return nil, err + } + rkecerts.CleanCertificateBundle(certs) + return certs, nil +} + +func getRKECurrentStateFromStore(store cluster.PersistentStore, clusterName string) (*rkecluster.State, error) { + cluster, err := store.Get(clusterName) + if err != nil { + return nil, err + } + var fullState rkecluster.FullState + stateStr, ok := cluster.Metadata["fullState"] + if !ok { + return nil, nil + } + err = json.Unmarshal([]byte(stateStr), &fullState) + if err != nil { + return nil, err + } + return &fullState.CurrentState, nil +} + +func (c Controller) getCertsFromUserCluster() (map[string]pki.CertificatePKI, error) { + certs := map[string]pki.CertificatePKI{} + secrets, err := c.SecretLister.List("kube-system", labels.Everything()) + if err != nil { + return nil, err + } + for _, secret := range secrets { + if strings.HasPrefix(secret.GetName(), "kube-") && + secret.Type == corev1.SecretTypeOpaque { + cert, ok := secret.Data["Certificate"] + if !ok { + logrus.Debugf("secret [%s] for cluster [%s] doesn't contain a certificate", secret.GetName(), c.ClusterName) + continue + } + certs[secret.GetName()] = pki.CertificatePKI{CertificatePEM: string(cert)} + } + } + return certs, nil +} + +// deleteUnusedCerts removes unused certs and cleans up kubelet certs when GenerateServingCertificate is disabled +func deleteUnusedCerts(certsExpInfo map[string]v32.CertExpiration, rancherKubernetesEngineConfig *rketypes.RancherKubernetesEngineConfig) { + unusedCerts := make(map[string]bool) + for k := range certsExpInfo { + if strings.HasPrefix(k, pki.EtcdCertName) || strings.HasPrefix(k, pki.KubeletCertName) { + unusedCerts[k] = true + } + } + etcdHosts := hosts.NodesToHosts(rancherKubernetesEngineConfig.Nodes, services.ETCDRole) + allHosts := hosts.NodesToHosts(rancherKubernetesEngineConfig.Nodes, "") + for _, host := range etcdHosts { + etcdName := pki.GetCrtNameForHost(host, pki.EtcdCertName) + delete(unusedCerts, etcdName) + } + if pki.IsKubeletGenerateServingCertificateEnabledinConfig(rancherKubernetesEngineConfig) { + for _, host := range allHosts { + kubeletName := pki.GetCrtNameForHost(host, pki.KubeletCertName) + delete(unusedCerts, kubeletName) + } + } + + for k := range unusedCerts { + logrus.Infof("Deleting unused certificate: %s", k) + delete(certsExpInfo, k) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration_test.go new file mode 100644 index 0000000..23779d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/certsexpiration/certsexpiration_test.go @@ -0,0 +1,245 @@ +package certsexpiration + +import ( + "reflect" + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" +) + +func TestDeleteUnusedCerts(t *testing.T) { + tests := []struct { + name string + certs map[string]v32.CertExpiration + rancherKubernetesEngineConfig *rketypes.RancherKubernetesEngineConfig + expectNewCerts map[string]v32.CertExpiration + }{ + { + name: "Keep valid etcd certs", + certs: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-etcd-172-17-0-4": v32.CertExpiration{}, + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + rancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + GenerateServingCertificate: true, + }, + }, + Nodes: []rketypes.RKEConfigNode{ + { + Address: "172.17.0.3", + Role: []string{ + "etcd", + }, + }, + { + Address: "172.17.0.4", + Role: []string{ + "etcd", + }, + }, + { + Address: "172.17.0.5", + Role: []string{ + "etcd", + }, + }, + }, + }, + expectNewCerts: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-etcd-172-17-0-4": v32.CertExpiration{}, + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + }, + { + name: "Keep valid kubelet certs", + certs: map[string]v32.CertExpiration{ + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-kubelet-172-17-0-3": v32.CertExpiration{}, + "kube-kubelet-172-17-0-5": v32.CertExpiration{}, + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + rancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + GenerateServingCertificate: true, + }, + }, + Nodes: []rketypes.RKEConfigNode{ + { + Address: "172.17.0.3", + Role: []string{ + "worker", + }, + }, + { + Address: "172.17.0.4", + Role: []string{ + "worker", + }, + }, + { + Address: "172.17.0.5", + Role: []string{ + "etcd", + }, + }, + }, + }, + expectNewCerts: map[string]v32.CertExpiration{ + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-kubelet-172-17-0-3": v32.CertExpiration{}, + "kube-kubelet-172-17-0-5": v32.CertExpiration{}, + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + }, + { + name: "Remove unused etcd certs", + certs: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-etcd-172-17-0-4": v32.CertExpiration{}, + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-kubelet-172-17-0-5": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + rancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + GenerateServingCertificate: true, + }, + }, + Nodes: []rketypes.RKEConfigNode{ + { + Address: "172.17.0.5", + Role: []string{ + "etcd", + "woker", + }, + }, + { + Address: "172.17.0.4", + Role: []string{ + "woker", + }, + }, + }, + }, + expectNewCerts: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-5": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-kubelet-172-17-0-5": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + }, + { + name: "Remove unused kubelet certs", + certs: map[string]v32.CertExpiration{ + "kube-kubelet-172-17-0-1": v32.CertExpiration{}, + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-3": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + rancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + GenerateServingCertificate: true, + }, + }, + Nodes: []rketypes.RKEConfigNode{ + { + Address: "172.17.0.3", + Role: []string{ + "etcd", + "woker", + }, + }, + { + Address: "172.17.0.4", + Role: []string{ + "woker", + }, + }, + }, + }, + expectNewCerts: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-3": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + }, + { + name: "Clean up kubelet certs when GenerateServingCertificate is disabled", + certs: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-kubelet-172-17-0-3": v32.CertExpiration{}, + "kube-kubelet-172-17-0-4": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + rancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + Services: rketypes.RKEConfigServices{ + Kubelet: rketypes.KubeletService{ + GenerateServingCertificate: false, + }, + }, + Nodes: []rketypes.RKEConfigNode{ + { + Address: "172.17.0.3", + Role: []string{ + "etcd", + "woker", + }, + }, + { + Address: "172.17.0.4", + Role: []string{ + "woker", + }, + }, + }, + }, + expectNewCerts: map[string]v32.CertExpiration{ + "kube-etcd-172-17-0-3": v32.CertExpiration{}, + "kube-node": v32.CertExpiration{}, + "kube-apiserver": v32.CertExpiration{}, + "kube-proxy": v32.CertExpiration{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + deleteUnusedCerts(tt.certs, tt.rancherKubernetesEngineConfig) + assert.Equal(t, true, reflect.DeepEqual(tt.certs, tt.expectNewCerts)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute.go new file mode 100644 index 0000000..b18ddeb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute.go @@ -0,0 +1,64 @@ +package clusterauthtoken + +import ( + "fmt" + + clusterv3 "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type clusterUserAttributeHandler struct { + userAttribute managementv3.UserAttributeInterface + userAttributeLister managementv3.UserAttributeLister + clusterUserAttribute clusterv3.ClusterUserAttributeInterface +} + +// Sync clusterUserAttributes and userAttributes +func (h *clusterUserAttributeHandler) Sync(key string, clusterUserAttribute *clusterv3.ClusterUserAttribute) (runtime.Object, error) { + if clusterUserAttribute == nil || clusterUserAttribute.DeletionTimestamp != nil { + return nil, nil + } + + userAttribute, err := h.userAttributeLister.Get("", clusterUserAttribute.Name) + if err != nil { + // If the corresponding UserAttribute no longer exists, we need to clean up the ClusterUserAttribute. + if !apierrors.IsNotFound(err) { + return nil, err + } + + // There is a chance that it hasn't ended up in the cache yet so we try to get it afresh. + userAttribute, err = h.userAttribute.Get(clusterUserAttribute.Name, metav1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + return nil, err + } + + err = h.clusterUserAttribute.Delete(clusterUserAttribute.Name, &metav1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) && !apierrors.IsGone(err) { + return nil, fmt.Errorf("error deleting orphaned clusteruserattribute %s: %w", clusterUserAttribute.Name, err) + } + + logrus.Infof("Deleted orphaned clusteruserattribute %s", clusterUserAttribute.Name) + return nil, nil + } + // The userAttribute exists, proceed. + } + + if !clusterUserAttribute.NeedsRefresh { + return nil, nil + } + if userAttribute.NeedsRefresh { + return nil, nil + } + if userAttribute.LastRefresh != clusterUserAttribute.LastRefresh { + return nil, nil + } + + userAttribute.NeedsRefresh = true + _, err = h.userAttribute.Update(userAttribute) + return nil, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute_test.go new file mode 100644 index 0000000..e0e0672 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/cluster_user_attribute_test.go @@ -0,0 +1,173 @@ +package clusterauthtoken + +import ( + "errors" + "fmt" + "testing" + + clusterv3 "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3" + clusterFakes "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3/fakes" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + managementFakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestClusterUserAttributeHandlerCleanup(t *testing.T) { + clusterUserAttribute := &clusterv3.ClusterUserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: "u-bdploclm4x", + }, + } + + var userAttributeGetCalledTimes int + userAttributes := &managementFakes.UserAttributeInterfaceMock{ + GetFunc: func(name string, opts metav1.GetOptions) (*managementv3.UserAttribute, error) { + userAttributeGetCalledTimes++ + return nil, apierrors.NewNotFound(managementv3.Resource("userattributes"), name) + }, + } + + var userAttributeListerGetCalledTimes int + userAttributeLister := &managementFakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*managementv3.UserAttribute, error) { + userAttributeListerGetCalledTimes++ + return nil, apierrors.NewNotFound(managementv3.Resource("userattributes"), name) + }, + } + + var deleted bool + clusterUserAttributes := &clusterFakes.ClusterUserAttributeInterfaceMock{ + DeleteFunc: func(name string, opts *metav1.DeleteOptions) error { + if name == clusterUserAttribute.Name { + deleted = true + } + return nil + }, + } + + handler := &clusterUserAttributeHandler{ + userAttribute: userAttributes, + userAttributeLister: userAttributeLister, + clusterUserAttribute: clusterUserAttributes, + } + + _, err := handler.Sync("", clusterUserAttribute) + if err != nil { + t.Fatal(err) + } + + if !deleted { + t.Error("Expected ClusterUserAttribute to be deleted") + } + if want, got := 1, userAttributeGetCalledTimes; want != got { + t.Errorf("Expected userAttributeGetCalledTimes %d got %d", want, got) + } + if want, got := 1, userAttributeListerGetCalledTimes; want != got { + t.Errorf("Expected userAttributeListerGetCalledTimes %d got %d", want, got) + } +} + +func TestClusterUserAttributeHandlerCleanupErrors(t *testing.T) { + attribName := "u-bdploclm4x" + someErr := fmt.Errorf("some error") + notFoundErr := apierrors.NewNotFound(managementv3.Resource("userattributes"), attribName) + + tests := []struct { + desc string + userAttributeGetErr error + userAttributeListerGetErr error + clusterUserAttributeDeleteErr error + shouldErr bool + }{ + { + desc: "userAttributeListerGet error", + userAttributeListerGetErr: someErr, + shouldErr: true, + }, + { + desc: "userAttributeGet error", + userAttributeListerGetErr: notFoundErr, + userAttributeGetErr: someErr, + shouldErr: true, + }, + { + desc: "userAttributeDelete error", + userAttributeGetErr: notFoundErr, + userAttributeListerGetErr: notFoundErr, + clusterUserAttributeDeleteErr: someErr, + shouldErr: true, + }, + { + desc: "userAttributeDelete errors with NotFound", + userAttributeGetErr: notFoundErr, + userAttributeListerGetErr: notFoundErr, + clusterUserAttributeDeleteErr: notFoundErr, + }, + { + desc: "userAttributeDelete errors with Gone", + userAttributeGetErr: notFoundErr, + userAttributeListerGetErr: notFoundErr, + clusterUserAttributeDeleteErr: apierrors.NewGone("gone"), + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.desc, func(t *testing.T) { + t.Parallel() + + userAttributes := &managementFakes.UserAttributeInterfaceMock{ + GetFunc: func(name string, opts metav1.GetOptions) (*managementv3.UserAttribute, error) { + if name != attribName { + t.Errorf("Unexpected name in userAttributes.Get call: %s", name) + } + return nil, tt.userAttributeGetErr + }, + } + + userAttributeLister := &managementFakes.UserAttributeListerMock{ + GetFunc: func(namespace string, name string) (*managementv3.UserAttribute, error) { + if name != attribName { + t.Errorf("Unexpected name in userAttributeLister.Get call: %s", name) + } + return nil, tt.userAttributeListerGetErr + }, + } + + clusterUserAttributes := &clusterFakes.ClusterUserAttributeInterfaceMock{ + DeleteFunc: func(name string, opts *metav1.DeleteOptions) error { + if name != attribName { + t.Errorf("Unexpected name in clusterUserAttributes.Delete call: %s", name) + } + return tt.clusterUserAttributeDeleteErr + }, + } + + handler := &clusterUserAttributeHandler{ + userAttribute: userAttributes, + userAttributeLister: userAttributeLister, + clusterUserAttribute: clusterUserAttributes, + } + + _, err := handler.Sync("", &clusterv3.ClusterUserAttribute{ + ObjectMeta: metav1.ObjectMeta{ + Name: attribName, + }, + }) + if tt.shouldErr { + if err == nil { + t.Fatal("Expected an error") + } + + if !errors.Is(err, someErr) { + t.Errorf("Unexpected error: %v", err) + } + } else { + if err != nil { + t.Fatal(err) + } + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/constants.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/constants.go new file mode 100644 index 0000000..09b13da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/constants.go @@ -0,0 +1,6 @@ +package common + +const ( + DefaultNamespace = "cattle-system" + AuthProviderRefreshDebounceSettingName = "auth-provider-refresh-debounce-seconds" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/crypto.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/crypto.go new file mode 100644 index 0000000..68d4618 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/clusterauthtoken/common/crypto.go @@ -0,0 +1,71 @@ +package common + +import ( + "bytes" + "crypto/rand" + "encoding/base64" + "fmt" + + "golang.org/x/crypto/scrypt" +) + +const Version = 1 +const hashFormat = "$%d:%x:%d:%d:%d:%s" + +func CreateHash(secretKey string) (string, error) { + const ( + n = 15 + r = 8 + p = 1 + keyLen = 64 + saltLen = 8 + ) + salt := make([]byte, saltLen) + + _, err := rand.Read(salt) + if err != nil { + return "", err + } + + dk, err := scrypt.Key([]byte(secretKey), salt, 1<=1.22.0") + +type ClusterControllerLifecycle interface { + Stop(cluster *v3.Cluster) +} + +type HealthSyncer struct { + ctx context.Context + clusterName string + clusterLister v3.ClusterLister + clusters v3.ClusterInterface + componentStatuses corev1.ComponentStatusInterface + namespaces corev1.NamespaceInterface + k8s kubernetes.Interface +} + +func Register(ctx context.Context, workload *config.UserContext) { + h := &HealthSyncer{ + ctx: ctx, + clusterName: workload.ClusterName, + clusterLister: workload.Management.Management.Clusters("").Controller().Lister(), + clusters: workload.Management.Management.Clusters(""), + componentStatuses: workload.Core.ComponentStatuses(""), + namespaces: workload.Core.Namespaces(""), + k8s: workload.K8sClient, + } + + go h.syncHealth(ctx, syncInterval) +} + +func (h *HealthSyncer) syncHealth(ctx context.Context, syncHealth time.Duration) { + for range ticker.Context(ctx, syncHealth) { + err := h.updateClusterHealth() + if err != nil && !apierrors.IsConflict(err) { + logrus.Error(err) + } + } +} + +func (h *HealthSyncer) getComponentStatus(cluster *v3.Cluster) error { + // Prior to k8s v1.14, we only needed to list the ComponentStatuses from the user cluster. + // As of k8s v1.14, kubeapi returns a successful ComponentStatuses response even if etcd is not available. + // To work around this, now we try to get a namespace from the API, even if not found, it means the API is up. + if err := IsAPIUp(h.ctx, h.k8s.CoreV1().Namespaces()); err != nil { + return condition.Error("ComponentStatusFetchingFailure", errors.Wrap(err, "Failed to communicate with API server during namespace check")) + } + + cluster.Status.ComponentStatuses = []v32.ClusterComponentStatus{} + if cluster.Status.Version == nil { + return nil + } + parts := versionMatchRE.FindStringSubmatch(cluster.Status.Version.String()) + if parts == nil || len(parts) < 2 { + return condition.Error("ComponentStatusFetchingFailure", fmt.Errorf("Failed to parse cluster status version %s", + cluster.Status.Version.String())) + } + k8sVersion, err := semver.Parse(parts[1]) + if err != nil { + return condition.Error("ComponentStatusFetchingFailure", fmt.Errorf("Failed to parse cluster k8s version %s", + cluster.Status.Version.String())) + } + if componentStatusDisabledRange(k8sVersion) { + return nil + } + cses, err := h.componentStatuses.List(metav1.ListOptions{}) + if err != nil { + return condition.Error("ComponentStatusFetchingFailure", errors.Wrap(err, "Failed to communicate with API server")) + } + clusterType := cluster.Status.Provider // the provider detector is more accurate but we can fall back on the driver in some cases + if clusterType == "" { + clusterType = cluster.Status.Driver + } + excludedComponents, ok := excludedComponentMap[clusterType] + for _, cs := range cses.Items { + if ok && slice.ContainsString(excludedComponents, cs.Name) { + continue + } + clusterCS := convertToClusterComponentStatus(&cs) + cluster.Status.ComponentStatuses = append(cluster.Status.ComponentStatuses, *clusterCS) + } + sort.Slice(cluster.Status.ComponentStatuses, func(i, j int) bool { + return cluster.Status.ComponentStatuses[i].Name < cluster.Status.ComponentStatuses[j].Name + }) + + return nil +} + +// IsAPIUp checks if the Kubernetes API server is up and etcd is available. +// It gets a namespace from the API, even if not found, it means the API is up. +// It returns nil if the API is up, otherwise it returns an error. +func IsAPIUp(ctx context.Context, ns typedv1.NamespaceInterface) error { + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + if _, err := ns.Get(ctx, "kube-system", metav1.GetOptions{}); err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil +} + +func (h *HealthSyncer) updateClusterHealth() error { + oldCluster, err := h.getCluster() + if err != nil { + return err + } + cluster := oldCluster.DeepCopy() + if !v32.ClusterConditionProvisioned.IsTrue(cluster) { + logrus.Debugf("Skip updating cluster health - cluster [%s] not provisioned yet", h.clusterName) + return nil + } + + // cluster condition ready is set to false if connected is false, return to avoid setting it to true incorrectly + if clusterconnected.Connected.IsFalse(cluster) { + logrus.Debugf("Skip updating cluster condition ready - cluster agent for [%s] isn't connected yet", h.clusterName) + return nil + } + + newObj, err := v32.ClusterConditionReady.Do(cluster, func() (runtime.Object, error) { + for i := 0; ; i++ { + err := h.getComponentStatus(cluster) + if err == nil || i > 1 { + return cluster, errors.Wrap(err, "cluster health check failed") + } + select { + case <-h.ctx.Done(): + return cluster, err + case <-time.After(5 * time.Second): + } + } + }) + + if err == nil { + v32.ClusterConditionWaiting.True(newObj) + v32.ClusterConditionWaiting.Message(newObj, "") + } + + if !reflect.DeepEqual(oldCluster, newObj) { + logrus.Tracef("[healthSyncer] update cluster %s", cluster.Name) + if _, err := h.clusters.Update(newObj.(*v3.Cluster)); err != nil { + return errors.Wrapf(err, "[updateClusterHealth] Failed to update cluster [%s]", cluster.Name) + } + } + + // Purposefully not return error. This is so when the cluster goes unavailable we don't just keep failing + // which will essentially keep the controller alive forever, instead of shutting down. + return nil +} + +func (h *HealthSyncer) getCluster() (*v3.Cluster, error) { + return h.clusterLister.Get("", h.clusterName) +} + +func convertToClusterComponentStatus(cs *v1.ComponentStatus) *v32.ClusterComponentStatus { + return &v32.ClusterComponentStatus{ + Name: cs.Name, + Conditions: cs.Conditions, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/healthsyncer/healthsyncer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/healthsyncer/healthsyncer_test.go new file mode 100644 index 0000000..3ff8a9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/healthsyncer/healthsyncer_test.go @@ -0,0 +1,118 @@ +package healthsyncer + +import ( + "context" + "net" + "testing" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + applycorev1 "k8s.io/client-go/applyconfigurations/core/v1" + typedv1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +func TestIsAPIUp(t *testing.T) { + type args struct { + ctx context.Context + ns typedv1.NamespaceInterface + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "api-up", + args: args{ + ctx: context.Background(), + ns: mockNamespaces{ + getter: func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + return &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test"}}, nil + }, + }, + }, + wantErr: false, + }, + { + name: "api-down", + args: args{ + ctx: context.Background(), + ns: mockNamespaces{ + getter: func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + return nil, net.UnknownNetworkError("unknown network error") + }, + }, + }, + wantErr: true, + }, + { + name: "api-timeout", + args: args{ + ctx: context.Background(), + ns: mockNamespaces{ + getter: func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + return nil, context.DeadlineExceeded + }, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := IsAPIUp(tt.args.ctx, tt.args.ns); (err != nil) != tt.wantErr { + t.Errorf("IsAPIUp() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +type mockNamespaces struct { + getter func(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) +} + +func (m mockNamespaces) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + return m.getter(ctx, name, opts) +} + +func (m mockNamespaces) Create(ctx context.Context, namespace *v1.Namespace, opts metav1.CreateOptions) (*v1.Namespace, error) { + panic("implement me") +} + +func (m mockNamespaces) Update(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { + panic("implement me") +} + +func (m mockNamespaces) UpdateStatus(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { + panic("implement me") +} + +func (m mockNamespaces) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + panic("implement me") +} + +func (m mockNamespaces) List(ctx context.Context, opts metav1.ListOptions) (*v1.NamespaceList, error) { + panic("implement me") +} + +func (m mockNamespaces) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + panic("implement me") +} + +func (m mockNamespaces) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Namespace, err error) { + panic("implement me") +} + +func (m mockNamespaces) Apply(ctx context.Context, namespace *applycorev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { + panic("implement me") +} + +func (m mockNamespaces) ApplyStatus(ctx context.Context, namespace *applycorev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { + panic("implement me") +} + +func (m mockNamespaces) Finalize(ctx context.Context, item *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { + panic("implement me") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/machinerole/machinerole.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/machinerole/machinerole.go new file mode 100644 index 0000000..40b8611 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/machinerole/machinerole.go @@ -0,0 +1,56 @@ +package machinerole + +import ( + "context" + + "github.com/rancher/rancher/pkg/capr" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/types/config" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +type handler struct { + clusterName string + nodes v1.NodeInterface + secretsLister v1.SecretLister +} + +func Register(ctx context.Context, context *config.UserContext) { + h := handler{ + clusterName: context.ClusterName, + nodes: context.Core.Nodes(""), + secretsLister: context.Management.Core.Secrets("").Controller().Lister(), + } + context.Core.Nodes("").Controller().AddHandler(ctx, "machine-worker-label", h.WorkerLabelSync) +} + +func (h *handler) WorkerLabelSync(_ string, node *corev1.Node) (runtime.Object, error) { + if node == nil || node.DeletionTimestamp != nil || node.Labels == nil || node.Annotations == nil { + return node, nil + } + + if _, ok := node.Labels["node-role.kubernetes.io/worker"]; ok { + return node, nil + } + machineName := node.Annotations[capi.MachineAnnotation] + if machineName == "" { + return node, nil + } + machineNS := node.Annotations[capi.ClusterNamespaceAnnotation] + if machineNS == "" { + return node, nil + } + + secrets, err := h.secretsLister.List(machineNS, labels.SelectorFromSet(labels.Set{capr.MachineNameLabel: machineName, capr.WorkerRoleLabel: "true"})) + if err != nil || len(secrets) == 0 { + return node, err + } + + node = node.DeepCopy() + node.Labels["node-role.kubernetes.io/worker"] = "true" + + return h.nodes.Update(node) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterHandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterHandler.go new file mode 100644 index 0000000..b22ecbc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterHandler.go @@ -0,0 +1,165 @@ +package networkpolicy + +import ( + "fmt" + + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/managementuser/nodesyncer" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +type clusterHandler struct { + cluster *config.UserContext + pnpLister v3.ProjectNetworkPolicyLister + podLister v1.PodLister + serviceLister v1.ServiceLister + pLister v3.ProjectLister + clusters v3.ClusterInterface + pnps v3.ProjectNetworkPolicyInterface + npmgr *netpolMgr + clusterNamespace string +} + +/* +clusterHandler enqueues resources for creating/deleting network policies +based on cluster.Annotations[netPolAnnotation] and sets status if successful +*/ + +func (ch *clusterHandler) Sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster == nil || cluster.DeletionTimestamp != nil || + cluster.Name != ch.clusterNamespace || + !v32.ClusterConditionReady.IsTrue(cluster) { + return nil, nil + } + + if cluster.Spec.EnableNetworkPolicy == nil { + return nil, nil + } + + toEnable := convert.ToBool(cluster.Annotations[netPolAnnotation]) + + if cluster.Status.AppliedEnableNetworkPolicy == toEnable { + return nil, nil + } + + if toEnable != *cluster.Spec.EnableNetworkPolicy { + // allow clusterNetAnnHandler to update first + return nil, nil + } + + var err error + if toEnable { + logrus.Infof("clusterHandler: calling sync to create network policies for cluster %v", cluster.Name) + err = ch.createNetworkPolicies(cluster) + } else { + logrus.Infof("clusterHandler: deleting network policies for cluster %s", cluster.Name) + err = ch.deleteNetworkPolicies(cluster) + } + + if err != nil { + return nil, err + } + + cluster.Status.AppliedEnableNetworkPolicy = toEnable + + _, err = ch.clusters.Update(cluster) + if err != nil { + return nil, err + } + + return nil, nil +} + +func (ch *clusterHandler) createNetworkPolicies(cluster *v3.Cluster) error { + projects, err := ch.pLister.List(cluster.Name, labels.NewSelector()) + if err != nil { + return fmt.Errorf("projectLister: %v", err) + } + + for _, project := range projects { + ch.npmgr.projects.Controller().Enqueue(project.Namespace, project.Name) + } + + systemNamespaces, _, err := ch.npmgr.getSystemNSInfo(cluster.Name) + if err != nil { + return fmt.Errorf("systemNS: %v", err) + } + + //hostPort + pods, err := ch.podLister.List("", labels.NewSelector()) + if err != nil { + return fmt.Errorf("podLister: %v", err) + } + + for _, pod := range pods { + if systemNamespaces[pod.Namespace] { + continue + } + if hostPortPod(pod) { + ch.cluster.Core.Pods("").Controller().Enqueue(pod.Namespace, pod.Name) + } + } + + // nodePort + svcs, err := ch.serviceLister.List("", labels.NewSelector()) + if err != nil { + return err + } + for _, svc := range svcs { + if systemNamespaces[svc.Namespace] { + continue + } + if nodePortService(svc) { + ch.cluster.Core.Services("").Controller().Enqueue(svc.Namespace, svc.Name) + } + } + + ch.cluster.Management.Management.Nodes(ch.cluster.ClusterName).Controller().Enqueue( + cluster.Name, fmt.Sprintf("%s/%s", ch.cluster.ClusterName, nodesyncer.AllNodeKey)) + + return nil + //skipping nssyncer, projectSyncer + nodehandler would result into handling nssyncer as well +} + +// deleteNetworkPolicies removes Rancher created NetworkPolicy resources from the downstream cluster and +// removes ProjectNetworkPolicy resources from the management cluster +func (ch *clusterHandler) deleteNetworkPolicies(cluster *v3.Cluster) error { + // consider nps for deletion if they were created by Rancher, i.e. they have a label: "cattle.io/creator": "norman" + set := labels.Set(map[string]string{creatorLabel: creatorNorman}) + nps, err := ch.npmgr.npLister.List("", set.AsSelector()) + if err != nil { + return fmt.Errorf("npLister: %v", err) + } + for _, np := range nps { + if err := ch.npmgr.delete(np.Namespace, np.Name); err != nil { + return fmt.Errorf("npDelete: %v", err) + } + } + + projects, err := ch.pLister.List(cluster.Name, labels.NewSelector()) + if err != nil { + return fmt.Errorf("projectLister: %v", err) + } + + for _, project := range projects { + pnps, err := ch.pnpLister.List(project.Name, labels.NewSelector()) + if err != nil { + return fmt.Errorf("pnpLister: %v", err) + } + + for _, pnp := range pnps { + err := ch.pnps.DeleteNamespaced(pnp.Namespace, pnp.Name, &metav1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("pnpDelete: %v", err) + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterNetAnnHandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterNetAnnHandler.go new file mode 100644 index 0000000..0381486 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/clusterNetAnnHandler.go @@ -0,0 +1,47 @@ +package networkpolicy + +import ( + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +const netPolAnnotation = "networking.management.cattle.io/enable-network-policy" + +/* +clusterNetAnnHandler syncs cluster.Spec.EnableNetworkPolicy to cluster.Annotations[netPolAnnotation] +All network policy controllers read from this annotation value to decide if network policy is enabled +*/ +type clusterNetAnnHandler struct { + clusters v3.ClusterInterface + clusterNamespace string +} + +func (cn *clusterNetAnnHandler) Sync(key string, cluster *v3.Cluster) (runtime.Object, error) { + if cluster == nil || cluster.DeletionTimestamp != nil || + cluster.Name != cn.clusterNamespace || + !v32.ClusterConditionProvisioned.IsTrue(cluster) { + return nil, nil + } + + if cluster.Spec.EnableNetworkPolicy == nil { + return nil, nil + } + + if *cluster.Spec.EnableNetworkPolicy == convert.ToBool(cluster.Annotations[netPolAnnotation]) { + return nil, nil + } + + logrus.Infof("clusterNetAnnHandler: updating EnableNetworkPolicy of cluster %s to %v", cluster.Name, + *cluster.Spec.EnableNetworkPolicy) + + cluster.Annotations[netPolAnnotation] = convert.ToString(*cluster.Spec.EnableNetworkPolicy) + + if _, err := cn.clusters.Update(cluster); err != nil { + return nil, err + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/netpol.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/netpol.go new file mode 100644 index 0000000..f17d7a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/netpol.go @@ -0,0 +1,480 @@ +package networkpolicy + +import ( + "errors" + "fmt" + "net" + "reflect" + "sort" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/imported" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + rancherv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + typescorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rnetworkingv1 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + + cluster2 "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + rkecluster "github.com/rancher/rke/cluster" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + knetworkingv1 "k8s.io/api/networking/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" +) + +const ( + systemProjectLabel = "authz.management.cattle.io/system-project" + creatorLabel = "cattle.io/creator" +) + +const ( + defaultNamespacePolicyName = "np-default" + defaultSystemProjectNamespacePolicyName = "np-default-allow-all" + hostNetworkPolicyName = "hn-nodes" + creatorNorman = "norman" +) + +var ErrNodeNotFound = errors.New("node not found") + +type netpolMgr struct { + clusterLister v3.ClusterLister + clusters rancherv1.ClusterCache + nsLister typescorev1.NamespaceLister + nodeLister typescorev1.NodeLister + pods typescorev1.PodInterface + projects v3.ProjectInterface + npLister rnetworkingv1.NetworkPolicyLister + npClient rnetworkingv1.Interface + projLister v3.ProjectLister + clusterNamespace string +} + +func (npmgr *netpolMgr) program(np *knetworkingv1.NetworkPolicy) error { + existing, err := npmgr.npLister.Get(np.Namespace, np.Name) + logrus.Debugf("netpolMgr: program: existing=%+v, err=%v", existing, err) + if err != nil { + if kerrors.IsNotFound(err) { + logrus.Debugf("netpolMgr: program: about to create np=%+v", *np) + _, err = npmgr.npClient.NetworkPolicies(np.Namespace).Create(np) + if err != nil && !kerrors.IsAlreadyExists(err) && !kerrors.IsForbidden(err) { + return fmt.Errorf("netpolMgr: program: error creating network policy err=%v", err) + } + } else { + return fmt.Errorf("netpolMgr: program: got unexpected error while getting network policy=%v", err) + } + } else { + logrus.Debugf("netpolMgr: program: existing=%+v", existing) + if existing.DeletionTimestamp == nil && !reflect.DeepEqual(existing.Spec, np.Spec) { + logrus.Debugf("netpolMgr: program: about to update np=%+v", *np) + _, err = npmgr.npClient.NetworkPolicies(np.Namespace).Update(np) + if err != nil { + return fmt.Errorf("netpolMgr: program: error updating network policy err=%v", err) + } + } else { + logrus.Debugf("netpolMgr: program: no need to update np=%+v", *np) + } + } + return nil +} + +func (npmgr *netpolMgr) delete(policyNamespace, policyName string) error { + existing, err := npmgr.npLister.Get(policyNamespace, policyName) + logrus.Debugf("netpolMgr: delete: existing=%+v, err=%v", existing, err) + if err != nil { + if kerrors.IsNotFound(err) { + return nil + } + return fmt.Errorf("netpolMgr: delete: got unexpected error while getting network policy=%v", err) + } + logrus.Debugf("netpolMgr: delete: existing=%+v", existing) + err = npmgr.npClient.NetworkPolicies(existing.Namespace).Delete(existing.Name, &v1.DeleteOptions{}) + if err != nil { + return fmt.Errorf("netpolMgr: delete: error deleting network policy err=%v", err) + } + return nil +} + +func (npmgr *netpolMgr) programNetworkPolicy(projectID string, clusterNamespace string) error { + logrus.Debugf("netpolMgr: programNetworkPolicy: projectID=%v", projectID) + // Get namespaces belonging to project + set := labels.Set(map[string]string{nslabels.ProjectIDFieldLabel: projectID}) + namespaces, err := npmgr.nsLister.List("", set.AsSelector()) + if err != nil { + return fmt.Errorf("netpolMgr: couldn't list namespaces with projectID %v err=%v", projectID, err) + } + logrus.Debugf("netpolMgr: programNetworkPolicy: namespaces=%+v", namespaces) + + systemNamespaces, systemProjectID, err := npmgr.getSystemNSInfo(clusterNamespace) + if err != nil { + return fmt.Errorf("netpolMgr: programNetworkPolicy getSystemNamespaces: err=%v", err) + } + + for _, aNS := range namespaces { + id, _ := aNS.Labels[nslabels.ProjectIDFieldLabel] + + // add an allow all network policy to system project namespaces + // this is the same as having no network policy, i.e. it allows all ingress and egress traffic to/from the namespace + // this is needed to ensure CIS Scans pass. See: https://github.com/rancher/rancher/issues/30211 for more info + // we also guard against overriding existing network policies, the default network policy for a namespace in the system project + // will only be added if there are no other network policies in the namespace (network policies are additive) + if systemNamespaces[aNS.Name] { + npmgr.delete(aNS.Name, defaultNamespacePolicyName) + + // this requirement includes objects with no creatorLabel or a value != creatorNorman + labelReq, err := labels.NewRequirement(creatorLabel, selection.NotEquals, []string{creatorNorman}) + if err != nil { // this won't happen since creatorLabel and creatorNorman are constants and valid per validation rules in labels.NewRequirement + return err + } + // select user network policies, which are ones that don't have a label with creator == norman + nps, err := npmgr.npLister.List(aNS.Name, labels.NewSelector().Add(*labelReq)) + if err != nil { + return err + } + + // there are existing network policies in this system project based namespace, skip programming default + if len(nps) > 0 { + logrus.Debugf("netPolMgr: namespace=%s in project=%s has existing network policies, skipping programming %s", aNS.Name, id, defaultSystemProjectNamespacePolicyName) + continue + } + + // program default network policy for system project based namespace + logrus.Debugf("netPolMgr: programming %s for namespace=%s in project=%s", defaultSystemProjectNamespacePolicyName, aNS.Name, id) + if err := npmgr.program(generateAllowAllNetworkPolicy(aNS, systemProjectID)); err != nil { + return fmt.Errorf( + "netPolMgr: programNetworkPolicy: error programming network policy %s for system project based namespace=%s err=%v", + defaultSystemProjectNamespacePolicyName, aNS.Name, err, + ) + } + continue + } + + // namespace is not in system project, so ensure it doesn't have the default policy for system project based namespaces + if id != systemProjectID { + npmgr.delete(aNS.Name, defaultSystemProjectNamespacePolicyName) + } + if id == "" { + npmgr.delete(aNS.Name, defaultNamespacePolicyName) + continue + } + if aNS.DeletionTimestamp != nil { + logrus.Debugf("netpolMgr: programNetworkPolicy: aNS=%+v marked for deletion, skipping", aNS) + continue + } + + np := generateDefaultNamespaceNetworkPolicy(aNS, projectID, systemProjectID) + if err := npmgr.program(np); err != nil { + return fmt.Errorf("netpolMgr: programNetworkPolicy: error programming default network policy for ns=%v err=%v", aNS.Name, err) + } + } + return nil +} + +const ( + calicoIPIPTunnelAddrAnno = "projectcalico.org/IPv4IPIPTunnelAddr" + calicoVXLANTunnelAddrAnno = "projectcalico.org/IPv4VXLANTunnelAddr" + calicoIPv4AddrAnno = "projectcalico.org/IPv4Address" + calicoIPv6AddrAnno = "projectcalico.org/IPv6Address" +) + +func (npmgr *netpolMgr) handleHostNetwork(clusterNamespace string) error { + nodes, err := npmgr.nodeLister.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("couldn't list nodes err=%v", err) + } + + cni, err := npmgr.getClusterCNI(clusterNamespace, nodes[0]) + if err != nil { + return err + } + + logrus.Debugf("netpolMgr: handleHostNetwork: processing %d nodes", len(nodes)) + np := generateNodesNetworkPolicy() + + // This for loop builds CNI specific host network policies to allow traffic from ingress controllers through to endpoints. + // Calico nodes require special handling. Calico has the following routing modes: IP in IP, VXLAN, and Direct. + // RKE1 deploys calico with IP in IP routing, while RKE2 deploys calico with VXLAN routing. + // When calico sends traffic to pods, the source IP address changes to either the IPIP tunnel address or the VXLAN tunnel address, + // depending on the routing mode. These are the IPs that the host network policy needs to use. + var policies []knetworkingv1.NetworkPolicyPeer + for _, node := range nodes { + // for calico, we get the IPs for the hn-nodes policy from the tunnel address annotations, which are managed by calico-node + if cni == rkecluster.CalicoNetworkPlugin { // RKE1/2 use the same "calico" value + tunnelAddr, ok := node.Annotations[calicoIPIPTunnelAddrAnno] + if !ok { + tunnelAddr = node.Annotations[calicoVXLANTunnelAddrAnno] + } + if tunnelAddr == "" { + logrus.Debugf("netpolMgr: handleHostNetwork: calico: node=%+v", node) + logrus.Errorf("netpolMgr: handleHostNetwork: calico: couldn't get tunnel address for node %v err=%v", node.Name, err) + continue + } + ipBlock := knetworkingv1.IPBlock{ + CIDR: tunnelAddr + "/32", + } + policies = append(policies, knetworkingv1.NetworkPolicyPeer{IPBlock: &ipBlock}) + continue + } + + // other CNIs + podCIDRFirstIP, _, err := net.ParseCIDR(node.Spec.PodCIDR) + if err != nil { + logrus.Debugf("netpolMgr: handleHostNetwork: node=%+v", node) + logrus.Errorf("netpolMgr: handleHostNetwork: couldn't parse PodCIDR(%v) for node %v err=%v", node.Spec.PodCIDR, node.Name, err) + continue + } + ipBlock := knetworkingv1.IPBlock{ + CIDR: podCIDRFirstIP.String() + "/32", + } + policies = append(policies, knetworkingv1.NetworkPolicyPeer{IPBlock: &ipBlock}) + } + + // set the policies on the resource + np.Spec.Ingress[0].From = policies + + // An empty ingress rule allows all traffic to the namespace + // so we need to skip creating the network policy here if that's what we have. + if len(np.Spec.Ingress[0].From) == 0 { + logrus.Debugf("netpolMgr: handleHostNetwork: no host addresses found, skipping programming the %s policy", hostNetworkPolicyName) + return nil + } + + // sort ipblocks so it always appears in a certain order + sort.Slice(np.Spec.Ingress[0].From, func(i, j int) bool { + return np.Spec.Ingress[0].From[i].IPBlock.CIDR < np.Spec.Ingress[0].From[j].IPBlock.CIDR + }) + + namespaces, err := npmgr.nsLister.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("couldn't list namespaces err=%v", err) + } + + systemNamespaces, _, err := npmgr.getSystemNSInfo(clusterNamespace) + if err != nil { + return fmt.Errorf("netpolMgr: handleHostNetwork getSystemNamespaces: err=%v", err) + } + for _, aNS := range namespaces { + projectID, _ := aNS.Labels[nslabels.ProjectIDFieldLabel] + if systemNamespaces[aNS.Name] || projectID == "" { + npmgr.delete(aNS.Name, hostNetworkPolicyName) + continue + } + if aNS.DeletionTimestamp != nil || aNS.Status.Phase == corev1.NamespaceTerminating { + logrus.Debugf("netpolMgr: handleHostNetwork: aNS=%+v marked for deletion/termination, skipping", aNS) + continue + } + if _, ok := aNS.Labels[nslabels.ProjectIDFieldLabel]; !ok { + continue + } + + logrus.Debugf("netpolMgr: handleHostNetwork: aNS=%+v", aNS) + + np.OwnerReferences = []v1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Namespace", + UID: aNS.UID, + Name: aNS.Name, + }, + } + np.Namespace = aNS.Name + if err := npmgr.program(np); err != nil { + logrus.Errorf("netpolMgr: handleHostNetwork: error programming hostNetwork network policy for ns=%v err=%v", aNS.Name, err) + } + } + return nil +} + +// getClusterCNI returns the cluster's CNI name if it is found or an api error +func (npmgr *netpolMgr) getClusterCNI(clusterName string, node *corev1.Node) (string, error) { + cluster, err := npmgr.clusterLister.Get("", clusterName) + if err != nil { + return "", err + } + + // this returns the CNI for provisioned RKE2 clusters + if isProvisionedRke2Cluster(cluster) { + return npmgr.getRKE2ClusterCNI(cluster) + } + + // this returns the CNI for imported RKE2 clusters + if cluster.Spec.Rke2Config != nil { + return npmgr.getImportedRke2ClusterCNI(node) + } + + if cluster.Spec.RancherKubernetesEngineConfig != nil { + return cluster.Spec.RancherKubernetesEngineConfig.Network.Plugin, nil + } + + return "", nil +} + +// isProvisionedRke2Cluster check to see if this is a rancher provisioned rke2 cluster +func isProvisionedRke2Cluster(cluster *v3.Cluster) bool { + return cluster.Status.Provider == v32.ClusterDriverRke2 && imported.IsAdministratedByProvisioningCluster(cluster) +} + +// getRKE2ClusterCNI returns the RKE2 cluster CNI name if it is found, or an api error +func (npmgr *netpolMgr) getRKE2ClusterCNI(mgmtCluster *v3.Cluster) (string, error) { + clusters, err := npmgr.clusters.GetByIndex(cluster2.ByCluster, mgmtCluster.Name) + if err != nil { + return "", err + } + if len(clusters) != 1 { + return "", fmt.Errorf("could not map to v1.Cluster for v3.Cluster: %s", mgmtCluster.Name) + } + + cluster := clusters[0] + if rke := cluster.Spec.RKEConfig; rke != nil && rke.MachineGlobalConfig.Data["cni"] != "" { + cni, ok := rke.MachineGlobalConfig.Data["cni"].(string) + if !ok { + return "", nil + } + return cni, nil + } + + return "", nil +} + +// getImportedRke2ClusterCNI gets the CNI for the imported RKE2 cluster, or returns an error if not found. +// Since cluster.Spec.RKEConfig from management.cattle.io/v3 isn't set for imported RKE2 clusters, +// we're relying on node annotations. +// This method currently only retrieves the CNI if it's set to Calico. +// TODO: Revise the approach if we begin storing CNI information in the provisioning.cattle.io/v1 cluster object. +func (npmgr *netpolMgr) getImportedRke2ClusterCNI(node *corev1.Node) (string, error) { + if node != nil { + if node.Annotations[calicoIPv4AddrAnno] != "" || node.Annotations[calicoIPv6AddrAnno] != "" { + return rkecluster.CalicoNetworkPlugin, nil + } + return "", nil + } + return "", ErrNodeNotFound +} + +func (npmgr *netpolMgr) getSystemNSInfo(clusterNamespace string) (map[string]bool, string, error) { + systemNamespaces := map[string]bool{} + set := labels.Set(map[string]string{systemProjectLabel: "true"}) + projects, err := npmgr.projLister.List(clusterNamespace, set.AsSelector()) + systemProjectID := "" + if err != nil { + return nil, systemProjectID, err + } + if len(projects) == 0 { + return systemNamespaces, systemProjectID, + fmt.Errorf("systemNamespaces: no system project for cluster %s", clusterNamespace) + } + if len(projects) > 1 { + return systemNamespaces, systemProjectID, + fmt.Errorf("systemNamespaces: more than one system project in cluster %s", clusterNamespace) + } + // ns.Annotations[projectIDAnnotation] = fmt.Sprintf("%v:%v", n.m.clusterName, projects[0].Name) + // ns.Labels[ProjectIDFieldLabel] = projectID / projects[0].Name + systemProjectID = projects[0].Name + if systemProjectID == "" { + return nil, systemProjectID, fmt.Errorf("sytemNamespaces: system project id cannot be empty") + } + set = labels.Set(map[string]string{nslabels.ProjectIDFieldLabel: systemProjectID}) + namespaces, err := npmgr.nsLister.List("", set.AsSelector()) + if err != nil { + return nil, systemProjectID, + fmt.Errorf("sytemNamespaces: couldn't list namespaces err=%v", err) + } + for _, ns := range namespaces { + if _, ok := systemNamespaces[ns.Name]; !ok { + systemNamespaces[ns.Name] = true + } + } + return systemNamespaces, systemProjectID, nil +} + +func generateDefaultNamespaceNetworkPolicy(aNS *corev1.Namespace, projectID string, systemProjectID string) *knetworkingv1.NetworkPolicy { + return &knetworkingv1.NetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: defaultNamespacePolicyName, + Namespace: aNS.Name, + Labels: map[string]string{ + nslabels.ProjectIDFieldLabel: projectID, + creatorLabel: creatorNorman, + }, + }, + Spec: knetworkingv1.NetworkPolicySpec{ + // An empty PodSelector selects all pods in this Namespace. + PodSelector: v1.LabelSelector{}, + Ingress: []knetworkingv1.NetworkPolicyIngressRule{ + { + From: []knetworkingv1.NetworkPolicyPeer{ + { + NamespaceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{nslabels.ProjectIDFieldLabel: projectID}, + }, + }, + { + NamespaceSelector: &v1.LabelSelector{ + MatchLabels: map[string]string{nslabels.ProjectIDFieldLabel: systemProjectID}, + }, + }, + }, + }, + }, + PolicyTypes: []knetworkingv1.PolicyType{ + knetworkingv1.PolicyTypeIngress, + }, + }, + } +} + +func generateAllowAllNetworkPolicy(ns *corev1.Namespace, systemProjectID string) *knetworkingv1.NetworkPolicy { + return &knetworkingv1.NetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: defaultSystemProjectNamespacePolicyName, + Namespace: ns.Name, + Labels: map[string]string{ + nslabels.ProjectIDFieldLabel: systemProjectID, + creatorLabel: creatorNorman, + }, + }, + Spec: knetworkingv1.NetworkPolicySpec{ + // An empty PodSelector selects all pods in this Namespace. + PodSelector: v1.LabelSelector{}, + Ingress: []knetworkingv1.NetworkPolicyIngressRule{ + {}, + }, + Egress: []knetworkingv1.NetworkPolicyEgressRule{ + {}, + }, + PolicyTypes: []knetworkingv1.PolicyType{ + knetworkingv1.PolicyTypeIngress, + knetworkingv1.PolicyTypeEgress, + }, + }, + } +} + +func generateNodesNetworkPolicy() *knetworkingv1.NetworkPolicy { + return &knetworkingv1.NetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: hostNetworkPolicyName, + Labels: map[string]string{ + creatorLabel: creatorNorman, + }, + }, + Spec: knetworkingv1.NetworkPolicySpec{ + PodSelector: v1.LabelSelector{}, + Ingress: []knetworkingv1.NetworkPolicyIngressRule{ + { + From: []knetworkingv1.NetworkPolicyPeer{}, + }, + }, + PolicyTypes: []knetworkingv1.PolicyType{ + knetworkingv1.PolicyTypeIngress, + }, + }, + } +} + +func portToString(port knetworkingv1.NetworkPolicyPort) string { + return fmt.Sprintf("%v/%v", port.Port, port.Protocol) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nodehandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nodehandler.go new file mode 100644 index 0000000..2d7f055 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nodehandler.go @@ -0,0 +1,31 @@ +package networkpolicy + +import ( + "fmt" + + "github.com/rancher/rancher/pkg/controllers/managementuser/nodesyncer" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +type nodeHandler struct { + npmgr *netpolMgr + clusterLister v3.ClusterLister + clusterNamespace string +} + +func (nh *nodeHandler) Sync(key string, machine *v3.Node) (runtime.Object, error) { + if key == fmt.Sprintf("%s/%s", nh.clusterNamespace, nodesyncer.AllNodeKey) { + disabled, err := isNetworkPolicyDisabled(nh.clusterNamespace, nh.clusterLister) + if err != nil { + return nil, err + } + if disabled { + return nil, nil + } + logrus.Debugf("nodeHandler: Sync: key=%v", key) + return nil, nh.npmgr.handleHostNetwork(nh.clusterNamespace) + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nssyncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nssyncer.go new file mode 100644 index 0000000..c4afc98 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/nssyncer.go @@ -0,0 +1,115 @@ +package networkpolicy + +import ( + "fmt" + + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +type nsSyncer struct { + npmgr *netpolMgr + clusterLister v3.ClusterLister + serviceLister v1.ServiceLister + podLister v1.PodLister + serviceClient v1.ServiceInterface + podClient v1.PodInterface + clusterNamespace string +} + +// Sync invokes Policy Handler to program the native network policies +func (nss *nsSyncer) Sync(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil || ns.DeletionTimestamp != nil { + return nil, nil + } + + disabled, err := isNetworkPolicyDisabled(nss.clusterNamespace, nss.clusterLister) + if err != nil { + return nil, err + } + if disabled { + return nil, nil + } + + logrus.Debugf("nsSyncer: Sync: %v, %+v", ns.Name, *ns) + + projectID := ns.Labels[nslabels.ProjectIDFieldLabel] + movedToNone := projectID == "" + if !movedToNone { + logrus.Debugf("nsSyncer: Sync: ns=%v projectID=%v", ns.Name, projectID) + // program project isolation network policy + if err := nss.npmgr.programNetworkPolicy(projectID, nss.clusterNamespace); err != nil { + return nil, fmt.Errorf("nsSyncer: Sync: error programming network policy: %v (ns=%v, projectID=%v), ", err, ns.Name, projectID) + } + } + // handle moving of namespace between projects + if err := nss.syncOnMove(ns.Name, projectID, movedToNone); err != nil { + return nil, fmt.Errorf("nsSyncer: Sync: error moving network policy: %v (ns=%v, projectID=%v), ", err, ns.Name, projectID) + } + if movedToNone { + return nil, nil + } + + // handle if hostNetwork policy is needed + return nil, nss.npmgr.handleHostNetwork(nss.clusterNamespace) +} + +func (nss *nsSyncer) syncOnMove(nsName string, projectID string, movedToNone bool) error { + systemNamespaces, _, err := nss.npmgr.getSystemNSInfo(nss.clusterNamespace) + if err != nil { + return fmt.Errorf("nsSyncer: error getting systemNamespaces %v", err) + } + if movedToNone { + nss.npmgr.delete(nsName, defaultNamespacePolicyName) + nss.npmgr.delete(nsName, hostNetworkPolicyName) + nss.npmgr.delete(nsName, defaultSystemProjectNamespacePolicyName) + } + if err = nss.syncNodePortServices(systemNamespaces, nsName, movedToNone); err != nil { + return fmt.Errorf("nsSyncer: error syncing services %v", err) + } + if err = nss.syncHostPortPods(systemNamespaces, nsName, movedToNone); err != nil { + return fmt.Errorf("nsSyncer: error syncing pods %v", err) + } + return nil +} + +func (nss *nsSyncer) syncNodePortServices(systemNamespaces map[string]bool, nsName string, moved bool) error { + svcs, err := nss.serviceLister.List(nsName, labels.NewSelector()) + if err != nil { + return err + } + for _, svc := range svcs { + if systemNamespaces[svc.Namespace] || moved { + policyName := getNodePortsPolicyName(svc) + nss.npmgr.delete(svc.Namespace, policyName) + continue + } + if nodePortService(svc) { + nss.serviceClient.Controller().Enqueue(svc.Namespace, svc.Name) + } + } + return nil +} + +func (nss *nsSyncer) syncHostPortPods(systemNamespaces map[string]bool, nsName string, moved bool) error { + pods, err := nss.podLister.List(nsName, labels.NewSelector()) + if err != nil { + return err + } + for _, pod := range pods { + if systemNamespaces[pod.Namespace] || moved { + policyName := getHostPortsPolicyName(pod) + nss.npmgr.delete(pod.Namespace, policyName) + continue + } + if hostPortPod(pod) { + nss.podClient.Controller().Enqueue(pod.Namespace, pod.Name) + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/pnpsyncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/pnpsyncer.go new file mode 100644 index 0000000..500da62 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/pnpsyncer.go @@ -0,0 +1,20 @@ +package networkpolicy + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +type projectNetworkPolicySyncer struct { + npmgr *netpolMgr +} + +// Sync invokes the Policy Handler to take care of installing the native network policies +func (pnps *projectNetworkPolicySyncer) Sync(key string, pnp *v3.ProjectNetworkPolicy) (runtime.Object, error) { + if pnp == nil || pnp.DeletionTimestamp != nil { + return nil, nil + } + logrus.Debugf("projectNetworkPolicySyncer: Sync: pnp=%+v", pnp) + return nil, pnps.npmgr.programNetworkPolicy(pnp.Namespace, pnps.npmgr.clusterNamespace) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/podhandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/podhandler.go new file mode 100644 index 0000000..3a31346 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/podhandler.go @@ -0,0 +1,174 @@ +package networkpolicy + +import ( + "fmt" + + "sort" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + knetworkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" +) + +const ( + // PodNameFieldLabel is used to specify the podName for pods + // with hostPort specified + PodNameFieldLabel = "field.cattle.io/podName" +) + +type podHandler struct { + npmgr *netpolMgr + pods v1.PodInterface + clusterLister v3.ClusterLister + clusterNamespace string +} + +func (ph *podHandler) Sync(key string, pod *corev1.Pod) (runtime.Object, error) { + if pod == nil || pod.DeletionTimestamp != nil { + return nil, nil + } + disabled, err := isNetworkPolicyDisabled(ph.clusterNamespace, ph.clusterLister) + if err != nil { + return nil, err + } + if disabled { + return nil, nil + } + moved, err := isNamespaceMoved(pod.Namespace, ph.npmgr.nsLister) + if err != nil { + return nil, err + } + if moved { + return nil, nil + } + systemNamespaces, _, err := ph.npmgr.getSystemNSInfo(ph.clusterNamespace) + if err != nil { + return nil, fmt.Errorf("netpolMgr: podHandler: getSystemNamespaces: err=%v", err) + } + logrus.Debugf("podHandler: Sync: %+v", *pod) + if err := ph.addLabelIfHostPortsPresent(pod, systemNamespaces); err != nil { + return nil, err + } + return nil, ph.npmgr.hostPortsUpdateHandler(pod, systemNamespaces) +} + +// k8s native network policy can select pods only using labels, +// hence need to add a label which can be used to select this pod +// which has hostPorts +func (ph *podHandler) addLabelIfHostPortsPresent(pod *corev1.Pod, systemNamespaces map[string]bool) error { + if pod.Labels != nil { + if _, ok := systemNamespaces[pod.Namespace]; ok { + if _, ok := pod.Labels[PodNameFieldLabel]; ok { + // we don't create network policies in system namespaces, delete label + logrus.Debugf("podHandler: addLabelIfHostPortsPresent: deleting podNameFieldLabel %+v in %s", pod.Labels, pod.Namespace) + podCopy := pod.DeepCopy() + delete(podCopy.Labels, PodNameFieldLabel) + _, err := ph.pods.Update(podCopy) + if err != nil { + return err + } + } + // don't add hostPort label for pods in system namespaces + return nil + } + } + hasHostPorts := false +Loop: + for _, c := range pod.Spec.Containers { + for _, port := range c.Ports { + if port.HostPort != 0 { + hasHostPorts = true + break Loop + } + } + } + if hasHostPorts { + logrus.Debugf("podHandler: addLabelIfHostPortsPresent: pod=%+v has HostPort", *pod) + podCopy := pod.DeepCopy() + if podCopy.Labels == nil { + podCopy.Labels = map[string]string{} + } + podCopy.Labels[PodNameFieldLabel] = podCopy.Name + _, err := ph.pods.Update(podCopy) + if err != nil { + return err + } + } + return nil +} + +func (npmgr *netpolMgr) hostPortsUpdateHandler(pod *corev1.Pod, systemNamespaces map[string]bool) error { + policyName := getHostPortsPolicyName(pod) + + if _, ok := systemNamespaces[pod.Namespace]; ok { + npmgr.delete(pod.Namespace, policyName) + return nil + } + + np := generatePodNetworkPolicy(pod, policyName) + hasHostPorts := false + for _, c := range pod.Spec.Containers { + for _, port := range c.Ports { + if port.HostPort != 0 { + hp := intstr.FromInt(int(port.ContainerPort)) + proto := corev1.Protocol(port.Protocol) + p := knetworkingv1.NetworkPolicyPort{ + Protocol: &proto, + Port: &hp, + } + np.Spec.Ingress[0].Ports = append(np.Spec.Ingress[0].Ports, p) + hasHostPorts = true + } + } + } + if !hasHostPorts { + return nil + } + // sort ports so it always appears in a certain order + sort.Slice(np.Spec.Ingress[0].Ports, func(i, j int) bool { + return portToString(np.Spec.Ingress[0].Ports[i]) < portToString(np.Spec.Ingress[0].Ports[j]) + }) + + logrus.Debugf("netpolMgr: hostPortsUpdateHandler: pod=%+v has host ports, hence programming np=%+v", *pod, *np) + return npmgr.program(np) +} + +func getHostPortsPolicyName(pod *corev1.Pod) string { + return "hp-" + pod.Name +} + +func generatePodNetworkPolicy(pod *corev1.Pod, policyName string) *knetworkingv1.NetworkPolicy { + return &knetworkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: policyName, + Namespace: pod.Namespace, + Labels: map[string]string{ + creatorLabel: creatorNorman, + }, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Pod", + UID: pod.UID, + Name: pod.Name, + }, + }, + }, + Spec: knetworkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{PodNameFieldLabel: pod.Name}, + }, + Ingress: []knetworkingv1.NetworkPolicyIngressRule{ + { + From: []knetworkingv1.NetworkPolicyPeer{}, + Ports: []knetworkingv1.NetworkPolicyPort{}, + }, + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/projectsyncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/projectsyncer.go new file mode 100644 index 0000000..89bbd9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/projectsyncer.go @@ -0,0 +1,94 @@ +package networkpolicy + +import ( + "fmt" + "reflect" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/condition" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/meta" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +type projectSyncer struct { + pnpLister v3.ProjectNetworkPolicyLister + pnpClient v3.ProjectNetworkPolicyInterface + projClient v3.ProjectInterface + clusterLister v3.ClusterLister + clusterNamespace string +} + +// Sync is responsible for creating a default ProjectNetworkPolicy for +// every project created. There is no need to worry about clean up, as +// this pnp object is tied to the namespace of the project, it's deleted +// automatically. +func (ps *projectSyncer) Sync(key string, p *v3.Project) (runtime.Object, error) { + if p == nil || p.DeletionTimestamp != nil { + return nil, nil + } + disabled, err := isNetworkPolicyDisabled(ps.clusterNamespace, ps.clusterLister) + if err != nil { + return nil, err + } + if disabled { + return nil, nil + } + updated, err := ps.createDefaultNetworkPolicy(p) + if err != nil { + return nil, err + } + + // update if it has changed + if updated != nil && !reflect.DeepEqual(p, updated) { + _, err = ps.projClient.Update(updated) + if err != nil { + return nil, err + } + } + + return nil, nil +} + +func (ps *projectSyncer) createDefaultNetworkPolicy(p *v3.Project) (*v3.Project, error) { + updated, err := v32.DefaultNetworkPolicyCreated.Do(p, func() (runtime.Object, error) { + o, err := meta.Accessor(p) + if err != nil { + return p, condition.Error("MissingMetadata", err) + } + + projectName := o.GetName() + defaultPolicyName := "pnp-" + projectName + existingPolicies, err := ps.pnpLister.List(defaultPolicyName, labels.Everything()) + if err != nil { + logrus.Errorf("projectSyncer: createDefaultNetworkPolicy: error fetching existing project network policy: %v", err) + return p, err + } + if len(existingPolicies) == 0 { + pnpDesc := fmt.Sprintf("Default network policy for project %v", projectName) + _, err = ps.pnpClient.Create(&v3.ProjectNetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: defaultPolicyName, + Namespace: projectName, + }, + Spec: v32.ProjectNetworkPolicySpec{ + Description: pnpDesc, + ProjectName: o.GetNamespace() + ":" + projectName, + }, + }) + if err == nil { + logrus.Infof("projectSyncer: createDefaultNetworkPolicy: successfully created default network policy for project: %v", projectName) + } + } + + return p, nil + }) + if err != nil { + return p, err + } + return updated.(*v3.Project), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/register.go new file mode 100644 index 0000000..6de6fc3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/register.go @@ -0,0 +1,76 @@ +package networkpolicy + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/runtime" +) + +// Register initializes the controllers and registers +func Register(ctx context.Context, cluster *config.UserContext) { + starter := cluster.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, cluster) + return nil + }) + clusters := cluster.Management.Management.Clusters("") + clusters.AddHandler(ctx, "networkpolicy-deferred", func(key string, obj *v3.Cluster) (runtime.Object, error) { + if obj != nil && + obj.Name == cluster.ClusterName && + obj.Spec.EnableNetworkPolicy != nil && + *obj.Spec.EnableNetworkPolicy { + return obj, starter() + } + return obj, nil + }) +} + +func registerDeferred(ctx context.Context, cluster *config.UserContext) { + logrus.Infof("Registering project network policy") + + pnpLister := cluster.Management.Management.ProjectNetworkPolicies("").Controller().Lister() + pnps := cluster.Management.Management.ProjectNetworkPolicies("") + projectLister := cluster.Management.Management.Projects(cluster.ClusterName).Controller().Lister() + projects := cluster.Management.Management.Projects(cluster.ClusterName) + clusterLister := cluster.Management.Management.Clusters("").Controller().Lister() + mgmtClusters := cluster.Management.Management.Clusters("") + clusters := cluster.Management.Wrangler.Provisioning.Cluster().Cache() + + nodeLister := cluster.Core.Nodes("").Controller().Lister() + nsLister := cluster.Core.Namespaces("").Controller().Lister() + nses := cluster.Core.Namespaces("") + serviceLister := cluster.Core.Services("").Controller().Lister() + services := cluster.Core.Services("") + podLister := cluster.Core.Pods("").Controller().Lister() + pods := cluster.Core.Pods("") + + npLister := cluster.Networking.NetworkPolicies("").Controller().Lister() + npClient := cluster.Networking + + npmgr := &netpolMgr{clusterLister, clusters, nsLister, nodeLister, pods, projects, + npLister, npClient, projectLister, cluster.ClusterName} + ps := &projectSyncer{pnpLister, pnps, projects, clusterLister, cluster.ClusterName} + nss := &nsSyncer{npmgr, clusterLister, serviceLister, podLister, + services, pods, cluster.ClusterName} + pnpsyncer := &projectNetworkPolicySyncer{npmgr} + podHandler := &podHandler{npmgr, pods, clusterLister, cluster.ClusterName} + serviceHandler := &serviceHandler{npmgr, clusterLister, cluster.ClusterName} + nodeHandler := &nodeHandler{npmgr, clusterLister, cluster.ClusterName} + clusterHandler := &clusterHandler{cluster, pnpLister, podLister, + serviceLister, projectLister, mgmtClusters, pnps, npmgr, cluster.ClusterName} + + clusterNetAnnHandler := &clusterNetAnnHandler{mgmtClusters, cluster.ClusterName} + + projects.Controller().AddClusterScopedHandler(ctx, "projectSyncer", cluster.ClusterName, ps.Sync) + pnps.AddClusterScopedHandler(ctx, "projectNetworkPolicySyncer", cluster.ClusterName, pnpsyncer.Sync) + nses.AddHandler(ctx, "namespaceLifecycle", nss.Sync) + pods.AddHandler(ctx, "podHandler", podHandler.Sync) + services.AddHandler(ctx, "serviceHandler", serviceHandler.Sync) + + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "nodeHandler", nodeHandler.Sync) + mgmtClusters.AddHandler(ctx, "clusterHandler", clusterHandler.Sync) + + mgmtClusters.AddHandler(ctx, "clusterNetAnnHandler", clusterNetAnnHandler.Sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/servicehandler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/servicehandler.go new file mode 100644 index 0000000..53780b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/servicehandler.go @@ -0,0 +1,115 @@ +package networkpolicy + +import ( + "fmt" + + "sort" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + knetworkingv1 "k8s.io/api/networking/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type serviceHandler struct { + npmgr *netpolMgr + clusterLister v3.ClusterLister + clusterNamespace string +} + +func (sh *serviceHandler) Sync(key string, service *corev1.Service) (runtime.Object, error) { + if service == nil || service.DeletionTimestamp != nil { + return nil, nil + } + disabled, err := isNetworkPolicyDisabled(sh.clusterNamespace, sh.clusterLister) + if err != nil { + return nil, err + } + if disabled { + return nil, nil + } + moved, err := isNamespaceMoved(service.Namespace, sh.npmgr.nsLister) + if err != nil { + return nil, err + } + if moved { + return nil, nil + } + logrus.Debugf("serviceHandler: Sync: %+v", *service) + return nil, sh.npmgr.nodePortsUpdateHandler(service, sh.clusterNamespace) +} + +func (npmgr *netpolMgr) nodePortsUpdateHandler(service *corev1.Service, clusterNamespace string) error { + systemNamespaces, _, err := npmgr.getSystemNSInfo(clusterNamespace) + if err != nil { + return fmt.Errorf("netpolMgr: hostPortsUpdateHandler: getSystemNamespaces: err=%v", err) + } + policyName := getNodePortsPolicyName(service) + if _, ok := systemNamespaces[service.Namespace]; ok { + npmgr.delete(service.Namespace, policyName) + return nil + } + np := generateServiceNetworkPolicy(service, policyName) + hasNodePorts := false + for _, port := range service.Spec.Ports { + if port.NodePort != 0 { + tp := port.TargetPort + proto := corev1.Protocol(port.Protocol) + p := knetworkingv1.NetworkPolicyPort{ + Protocol: &proto, + Port: &tp, + } + np.Spec.Ingress[0].Ports = append(np.Spec.Ingress[0].Ports, p) + hasNodePorts = true + } + } + + // sort ports so it always appears in a certain order + sort.Slice(np.Spec.Ingress[0].Ports, func(i, j int) bool { + return portToString(np.Spec.Ingress[0].Ports[i]) < portToString(np.Spec.Ingress[0].Ports[j]) + }) + if hasNodePorts { + logrus.Debugf("netpolMgr: nodePortsUpdateHandler: service=%+v has node ports, hence programming np=%+v", *service, *np) + return npmgr.program(np) + } + + return nil +} + +func getNodePortsPolicyName(service *corev1.Service) string { + return "np-" + service.Name +} + +func generateServiceNetworkPolicy(service *corev1.Service, policyName string) *knetworkingv1.NetworkPolicy { + np := &knetworkingv1.NetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: policyName, + Namespace: service.Namespace, + Labels: map[string]string{ + creatorLabel: creatorNorman, + }, + OwnerReferences: []v1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Service", + UID: service.UID, + Name: service.Name, + }, + }, + }, + Spec: knetworkingv1.NetworkPolicySpec{ + PodSelector: v1.LabelSelector{ + MatchLabels: service.Spec.Selector, + }, + Ingress: []knetworkingv1.NetworkPolicyIngressRule{ + { + From: []knetworkingv1.NetworkPolicyPeer{}, + Ports: []knetworkingv1.NetworkPolicyPort{}, + }, + }, + }, + } + return np +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/utils.go new file mode 100644 index 0000000..8a29cda --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/networkpolicy/utils.go @@ -0,0 +1,50 @@ +package networkpolicy + +import ( + "fmt" + + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/controllers/managementagent/nslabels" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + corev1 "k8s.io/api/core/v1" +) + +func isNetworkPolicyDisabled(clusterNamespace string, clusterLister v3.ClusterLister) (bool, error) { + cluster, err := clusterLister.Get("", clusterNamespace) + if err != nil { + return false, fmt.Errorf("error getting cluster %v", err) + } + return !convert.ToBool(cluster.Annotations[netPolAnnotation]), nil +} + +func isNamespaceMoved(namespace string, nsLister v1.NamespaceLister) (bool, error) { + ns, err := nsLister.Get("", namespace) + if err != nil { + return false, fmt.Errorf("error getting ns %v", err) + } + if _, ok := ns.Annotations[nslabels.ProjectIDFieldLabel]; !ok { + return true, nil + } + return ns.Annotations[nslabels.ProjectIDFieldLabel] == "", nil +} + +func nodePortService(service *corev1.Service) bool { + for _, port := range service.Spec.Ports { + if port.NodePort != 0 { + return true + } + } + return false +} + +func hostPortPod(pod *corev1.Pod) bool { + for _, c := range pod.Spec.Containers { + for _, port := range c.Ports { + if port.HostPort != 0 { + return true + } + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/cordonfieldssyncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/cordonfieldssyncer.go new file mode 100644 index 0000000..af63eff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/cordonfieldssyncer.go @@ -0,0 +1,333 @@ +package nodesyncer + +import ( + "context" + "fmt" + "strings" + "sync" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kubectl" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +const ( + drainTokenPrefix = "drain-node-" + description = "token for drain" +) + +var nodeMapLock = sync.Mutex{} +var toIgnoreErrs = []string{"--ignore-daemonsets", "--delete-local-data", "--force", "did not complete within", "global timeout reached"} + +func (m *nodesSyncer) syncCordonFields(key string, obj *v3.Node) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil || obj.Spec.DesiredNodeUnschedulable == "" { + return nil, nil + } + + if obj.Spec.DesiredNodeUnschedulable != "true" && obj.Spec.DesiredNodeUnschedulable != "false" { + return nil, nil + } + + node, err := nodehelper.GetNodeForMachine(obj, m.nodeLister) + if err != nil || node == nil || node.DeletionTimestamp != nil { + return nil, err + } + desiredValue := convert.ToBool(obj.Spec.DesiredNodeUnschedulable) + if node.Spec.Unschedulable != desiredValue { + toUpdate := node.DeepCopy() + toUpdate.Spec.Unschedulable = desiredValue + if _, err = m.nodeClient.Update(toUpdate); err != nil { + return nil, err + } + } + + logrus.Debugf("cordonNode: [%v] desired %v current %v", obj.Name, desiredValue, obj.Spec.InternalNodeSpec.Unschedulable) + // reset only after Unschedulable reflects correctly + if obj.Spec.InternalNodeSpec.Unschedulable == desiredValue { + nodeCopy := obj.DeepCopy() + nodeCopy.Spec.DesiredNodeUnschedulable = "" + + if !obj.Spec.InternalNodeSpec.Unschedulable { + removeDrainCondition(nodeCopy) + } + + obj, err = m.machines.Update(nodeCopy) + } + + return obj, err +} + +func (d *nodeDrain) drainNode(key string, obj *v3.Node) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil || obj.Spec.DesiredNodeUnschedulable == "" { + return nil, nil + } + + if obj.Spec.DesiredNodeUnschedulable != "drain" && obj.Spec.DesiredNodeUnschedulable != "stopDrain" { + return nil, nil + } + + if obj.Spec.DesiredNodeUnschedulable == "drain" { + nodeMapLock.Lock() + if _, ok := d.nodesToContext[obj.Name]; ok { + nodeMapLock.Unlock() + return nil, nil + } + nodeMapLock.Unlock() + + node, err := nodehelper.GetNodeForMachine(obj, d.nodeLister) + if err != nil { + return nil, err + } + if node == nil { + return nil, fmt.Errorf("nodeDrain: error finding node [%s]", obj.Spec.RequestedHostname) + } + ctx, cancel := context.WithCancel(d.ctx) + + nodeMapLock.Lock() + d.nodesToContext[obj.Name] = cancel + nodeMapLock.Unlock() + + go d.drain(ctx, obj, node.Name, cancel) + + } else if obj.Spec.DesiredNodeUnschedulable == "stopDrain" { + nodeMapLock.Lock() + cancelFunc, ok := d.nodesToContext[obj.Name] + nodeMapLock.Unlock() + + if ok { + cancelFunc() + } + return nil, d.resetDesiredNodeUnschedulable(obj) + } + return nil, nil +} + +func (d *nodeDrain) updateNode(node *v3.Node, updateFunc func(node *v3.Node, originalErr error, kubeErr error), originalErr error, kubeErr error) (*v3.Node, error) { + updatedObj, err := d.machines.Update(node) + if err != nil && errors.IsConflict(err) { + // retrying twelve times, if conflict error still exists, give up + for i := 0; i < 12; i++ { + latestObj, err := d.machines.Get(node.Name, metav1.GetOptions{}) + if err != nil { + logrus.Warnf("nodeDrain: error fetching node %s", node.Spec.RequestedHostname) + return nil, err + } + updateFunc(latestObj, originalErr, kubeErr) + updatedObj, err = d.machines.Update(latestObj) + if err != nil && errors.IsConflict(err) { + logrus.Debugf("nodeDrain: conflict error, will retry again %s", node.Spec.RequestedHostname) + time.Sleep(5 * time.Millisecond) + continue + } + return updatedObj, err + } + } + return updatedObj, err +} + +func (d *nodeDrain) drain(ctx context.Context, obj *v3.Node, nodeName string, cancel context.CancelFunc) { + defer deleteFromContextMap(d.nodesToContext, obj.Name) + + for { + select { + case <-ctx.Done(): + return + default: + } + + stopped := false + updatedObj, err := v32.NodeConditionDrained.DoUntilTrue(obj, func() (runtime.Object, error) { + kubeConfig, tokenName, err := d.getKubeConfig() + if err != nil { + logrus.Errorf("nodeDrain: error getting kubeConfig for node %s", obj.Name) + return obj, fmt.Errorf("error getting kubeConfig for node %s", obj.Name) + } + defer func() { + if err := d.systemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for nodesyncer token [%s] failed, will not retry: %v", tokenName, err) + } + }() + + nodeCopy := obj.DeepCopy() + setConditionDraining(nodeCopy, nil, nil) + nodeObj, err := d.updateNode(nodeCopy, setConditionDraining, nil, nil) + if err != nil { + return obj, err + } + logrus.Infof("Draining node %s in %s with flags %v", nodeName, obj.Namespace, + strings.Join(nodehelper.GetDrainFlags(nodeObj), " ")) + _, msg, err := kubectl.Drain(ctx, kubeConfig, nodeName, nodehelper.GetDrainFlags(nodeObj)) + if err != nil { + if ctx.Err() == context.Canceled { + stopped = true + logrus.Infof(fmt.Sprintf("Stopped draining %s in %s", nodeName, obj.Namespace)) + return nodeObj, nil + } + errMsg := filterErrorMsg(msg, nodeName) + return nodeObj, fmt.Errorf("%s", errMsg) + } + return nodeObj, nil + }) + kubeErr := err + if err != nil { + ignore, timeoutErr := ignoreErr(err.Error()) + if ignore { + if timeoutErr { + err = fmt.Errorf(fmt.Sprintf("Drain failed: drain did not complete within %vs", + obj.Spec.NodeDrainInput.Timeout)) + } else { + // log before ignoring + logrus.Errorf("nodeDrain: kubectl error ignore draining node [%s] in cluster [%s]: %v", nodeName, + d.clusterName, kubeErr) + } + kubeErr = nil + } + } + if !stopped { + nodeCopy := updatedObj.(*v3.Node).DeepCopy() + setConditionComplete(nodeCopy, err, kubeErr) + _, updateErr := d.updateNode(nodeCopy, setConditionComplete, err, kubeErr) + if kubeErr != nil || updateErr != nil { + if kubeErr != nil { + logrus.Errorf("nodeDrain: kubectl error draining node [%s] in cluster [%s]: %v", nodeName, + d.clusterName, kubeErr) + } else { + logrus.Errorf("nodeDrain: condition update failure for node [%s] in cluster [%s]: %v", + nodeName, d.clusterName, updateErr) + } + d.machines.Controller().Enqueue("", fmt.Sprintf("%s/%s", d.clusterName, obj.Name)) + } + cancel() + } + } +} + +func (d *nodeDrain) resetDesiredNodeUnschedulable(obj *v3.Node) error { + nodeCopy := obj.DeepCopy() + removeDrainCondition(nodeCopy) + nodeCopy.Spec.DesiredNodeUnschedulable = "" + if _, err := d.machines.Update(nodeCopy); err != nil { + return err + } + return nil +} + +func (d *nodeDrain) getKubeConfig() (*clientcmdapi.Config, string, error) { + cluster, err := d.clusterLister.Get("", d.clusterName) + if err != nil { + return nil, "", err + } + user, err := d.systemAccountManager.GetSystemUser(cluster.Name) + if err != nil { + return nil, "", err + } + tokenPrefix := drainTokenPrefix + user.Name + token, err := d.systemTokens.EnsureSystemToken(tokenPrefix, description, "drain-node", user.Name, nil, true) + if err != nil { + return nil, "", err + } + kubeConfig := d.kubeConfigGetter.KubeConfig(d.clusterName, token) + for k := range kubeConfig.Clusters { + kubeConfig.Clusters[k].InsecureSkipTLSVerify = true + } + tokenName, _ := tokens.SplitTokenParts(token) + return kubeConfig, tokenName, nil +} + +func filterErrorMsg(msg string, nodeName string) string { + var upd []string + lines := strings.Split(msg, "\n") + for _, line := range lines[1:] { + if strings.HasPrefix(line, "WARNING") || strings.HasPrefix(line, nodeName) { + continue + } + if strings.Contains(line, "aborting") { + continue + } + if strings.HasPrefix(line, "There are pending nodes ") { + // for only one node in our case + continue + } + if strings.HasPrefix(line, "There are pending pods ") { + // already considered error + continue + } + if strings.HasPrefix(line, "error") && strings.Contains(line, "unable to drain node") { + // actual reason at end + continue + } + if strings.HasPrefix(line, "pod") && strings.Contains(line, "evicted") { + // evicted successfully + continue + } + upd = append(upd, line) + } + return strings.Join(upd, "\n") +} + +func removeDrainCondition(obj *v3.Node) { + exists := false + for _, condition := range obj.Status.Conditions { + if condition.Type == "Drained" { + exists = true + break + } + } + if exists { + var conditions []v32.NodeCondition + for _, condition := range obj.Status.Conditions { + if condition.Type == "Drained" { + continue + } + conditions = append(conditions, condition) + } + obj.Status.Conditions = conditions + } +} + +func deleteFromContextMap(data map[string]context.CancelFunc, id string) { + nodeMapLock.Lock() + delete(data, id) + nodeMapLock.Unlock() +} + +func ignoreErr(msg string) (bool, bool) { + for _, val := range toIgnoreErrs { + if strings.Contains(msg, val) { + // check if timeout error + if !strings.HasPrefix(val, "--") { + return true, true + } + return true, false + } + } + return false, false +} + +func setConditionDraining(node *v3.Node, err error, kubeErr error) { + v32.NodeConditionDrained.Unknown(node) + v32.NodeConditionDrained.Reason(node, "") + v32.NodeConditionDrained.Message(node, "") +} + +func setConditionComplete(node *v3.Node, err error, kubeErr error) { + if err == nil { + v32.NodeConditionDrained.True(node) + } else { + v32.NodeConditionDrained.False(node) + v32.NodeConditionDrained.ReasonAndMessageFromError(node, err) + } + if kubeErr == nil { + node.Spec.DesiredNodeUnschedulable = "" + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer.go new file mode 100644 index 0000000..f12a2ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer.go @@ -0,0 +1,878 @@ +package nodesyncer + +import ( + "context" + "encoding/json" + "fmt" + "reflect" + "sort" + "strings" + + "github.com/pkg/errors" + cond "github.com/rancher/norman/condition" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/assemblers" + "github.com/rancher/rancher/pkg/controllers/managementagent/podresources" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/compose/common" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + provcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontrollers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/librke" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + rketypes "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + AllNodeKey = "_machine_all_" + annotationName = "management.cattle.io/nodesyncer" +) + +type nodeSyncer struct { + machines v3.NodeInterface + clusterNamespace string + nodesSyncer *nodesSyncer +} + +type nodesSyncer struct { + machines v3.NodeInterface + machineLister v3.NodeLister + nodeLister v1.NodeLister + nodeClient v1.NodeInterface + clusterNamespace string + clusterLister v3.ClusterLister + serviceOptionsLister v3.RkeK8sServiceOptionLister + serviceOptions v3.RkeK8sServiceOptionInterface + sysImagesLister v3.RkeK8sSystemImageLister + sysImages v3.RkeK8sSystemImageInterface + secretLister v1.SecretLister + provClusterCache provcontrollers.ClusterCache + capiClusterCache capicontrollers.ClusterCache + rkeControlPlaneCache rkecontrollers.RKEControlPlaneCache +} + +type nodeDrain struct { + systemTokens systemtokens.Interface + tokenClient v3.TokenInterface + userClient v3.UserInterface + kubeConfigGetter common.KubeConfigGetter + clusterName string + systemAccountManager *systemaccount.Manager + clusterLister v3.ClusterLister + machines v3.NodeInterface + nodeLister v1.NodeLister + ctx context.Context + nodesToContext map[string]context.CancelFunc +} + +type canChangeValuePolicy func(key string) bool + +func Register(ctx context.Context, cluster *config.UserContext, kubeConfigGetter common.KubeConfigGetter) { + m := &nodesSyncer{ + clusterNamespace: cluster.ClusterName, + machines: cluster.Management.Management.Nodes(cluster.ClusterName), + machineLister: cluster.Management.Management.Nodes(cluster.ClusterName).Controller().Lister(), + nodeLister: cluster.Core.Nodes("").Controller().Lister(), + nodeClient: cluster.Core.Nodes(""), + clusterLister: cluster.Management.Management.Clusters("").Controller().Lister(), + serviceOptionsLister: cluster.Management.Management.RkeK8sServiceOptions("").Controller().Lister(), + serviceOptions: cluster.Management.Management.RkeK8sServiceOptions(""), + sysImagesLister: cluster.Management.Management.RkeK8sSystemImages("").Controller().Lister(), + sysImages: cluster.Management.Management.RkeK8sSystemImages(""), + secretLister: cluster.Management.Core.Secrets("").Controller().Lister(), + provClusterCache: cluster.Management.Wrangler.Provisioning.Cluster().Cache(), + capiClusterCache: cluster.Management.Wrangler.CAPI.Cluster().Cache(), + rkeControlPlaneCache: cluster.Management.Wrangler.RKE.RKEControlPlane().Cache(), + } + + n := &nodeSyncer{ + clusterNamespace: cluster.ClusterName, + machines: cluster.Management.Management.Nodes(cluster.ClusterName), + nodesSyncer: m, + } + + d := &nodeDrain{ + systemTokens: cluster.Management.SystemTokens, + tokenClient: cluster.Management.Management.Tokens(""), + userClient: cluster.Management.Management.Users(""), + kubeConfigGetter: kubeConfigGetter, + clusterName: cluster.ClusterName, + systemAccountManager: systemaccount.NewManager(cluster.Management), + clusterLister: cluster.Management.Management.Clusters("").Controller().Lister(), + machines: cluster.Management.Management.Nodes(cluster.ClusterName), + nodeLister: cluster.Core.Nodes("").Controller().Lister(), + ctx: ctx, + nodesToContext: map[string]context.CancelFunc{}, + } + + cluster.Core.Nodes("").Controller().AddHandler(ctx, "nodesSyncer", n.sync) + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "machinesSyncer", m.sync) + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "machinesLabelSyncer", m.syncLabels) + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "cordonFieldsSyncer", m.syncCordonFields) + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "drainNodeSyncer", d.drainNode) + cluster.Management.Management.Nodes(cluster.ClusterName).Controller().AddHandler(ctx, "machineTaintSyncer", m.syncTaints) +} + +func (n *nodeSyncer) sync(key string, node *corev1.Node) (runtime.Object, error) { + needUpdate, err := n.needUpdate(key, node) + if err != nil { + return nil, err + } + if needUpdate { + n.machines.Controller().Enqueue(n.clusterNamespace, AllNodeKey) + } + + return nil, nil +} + +func (n *nodeSyncer) needUpdate(_ string, node *corev1.Node) (bool, error) { + if node == nil || node.DeletionTimestamp != nil { + return true, nil + } + existing, err := n.nodesSyncer.getMachineForNodeFromCache(node) + if err != nil { + return false, err + } + if existing == nil { + return true, nil + } + if existing.Annotations[annotationName] == "" { + existing = existing.DeepCopy() + if existing.Annotations == nil { + existing.Annotations = make(map[string]string) + } + existing.Annotations[annotationName] = "true" + if _, err = n.nodesSyncer.machines.Update(existing); err != nil { + return false, err + } + return true, nil + } + toUpdate, err := n.nodesSyncer.convertNodeToMachine(node, existing) + if err != nil { + return false, err + } + + // update only when nothing changed + if objectsAreEqual(existing, toUpdate) { + return false, nil + } + return true, nil +} + +func (m *nodesSyncer) sync(key string, _ *apimgmtv3.Node) (runtime.Object, error) { + if key == fmt.Sprintf("%s/%s", m.clusterNamespace, AllNodeKey) { + return nil, m.reconcileAll() + } + return nil, nil +} + +func (m *nodesSyncer) updateNodeAndNode(node *corev1.Node, obj *apimgmtv3.Node) (*corev1.Node, *apimgmtv3.Node, error) { + node, err := m.nodeClient.Update(node) + if err != nil { + // Return apimgmtv3.Node is nil because it hasn't been persisted and therefor out of sync with cache + // so we don't want to return it from the handler + return node, nil, err + } + + obj, err = m.machines.Update(obj) + if err != nil { + // Same logic as above, but more so that we don't know the state of this object + return node, nil, err + } + + return node, obj, nil +} + +func (m *nodesSyncer) updateLabels(node *corev1.Node, obj *apimgmtv3.Node, nodePlan rketypes.RKEConfigNodePlan) (*corev1.Node, *apimgmtv3.Node, error) { + finalMap, changed := computeDelta(node.Labels, nodePlan.Labels, obj.Spec.MetadataUpdate.Labels, onlyKubeLabels) + if !changed { + return node, obj, nil + } + + node, obj = node.DeepCopy(), obj.DeepCopy() + if obj.Status.NodeConfig != nil { + planValues, changed := computePlanDelta(obj.Status.NodeConfig.Labels, obj.Spec.MetadataUpdate.Labels) + if changed { + obj.Status.NodeConfig.Labels = planValues + } + } + + node.Labels = finalMap + + obj.Spec.MetadataUpdate.Labels = apimgmtv3.MapDelta{} + + return m.updateNodeAndNode(node, obj) +} + +// For any key that already exist in the plan, we should update or delete. For others, do not touch the plan. +func computePlanDelta(planValues map[string]string, delta apimgmtv3.MapDelta) (map[string]string, bool) { + update := false + for k, v := range delta.Add { + if planValues[k] != "" { + update = true + planValues[k] = v + } + } + + for k := range delta.Delete { + if planValues[k] != "" { + update = true + delete(planValues, k) + } + } + return planValues, update + +} + +func (m *nodesSyncer) updateAnnotations(node *corev1.Node, obj *apimgmtv3.Node, nodePlan rketypes.RKEConfigNodePlan) (*corev1.Node, *apimgmtv3.Node, error) { + finalMap, changed := computeDelta(node.Annotations, nodePlan.Annotations, obj.Spec.MetadataUpdate.Annotations, allowAllPolicy) + if !changed { + return node, obj, nil + } + + node, obj = node.DeepCopy(), obj.DeepCopy() + node.Annotations = finalMap + obj.Spec.MetadataUpdate.Annotations = apimgmtv3.MapDelta{} + + return m.updateNodeAndNode(node, obj) +} + +func (m *nodesSyncer) syncLabels(_ string, obj *apimgmtv3.Node) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + + node, err := nodehelper.GetNodeForMachine(obj, m.nodeLister) + if err != nil || node == nil { + return nil, err + } + + nodePlan, err := m.getNodePlan(obj) + if err != nil { + return obj, err + } + + node, obj, err = m.updateLabels(node, obj, nodePlan) + if err != nil { + return obj, err + } + + _, obj, err = m.updateAnnotations(node, obj, nodePlan) + return obj, err +} + +func onlyKubeLabels(key string) bool { + return strings.Contains(key, "kubernetes.io") +} + +func allowAllPolicy(_ string) bool { + return true +} + +// computeDelta will return the final updated map to apply and a boolean indicating whether there are changes to be applied. +// If the boolean is false, the caller need not take any action as the data is already in sync. +func computeDelta(currentState map[string]string, planValues map[string]string, delta apimgmtv3.MapDelta, canChangeValue canChangeValuePolicy) (map[string]string, bool) { + result := map[string]string{} + changed := false + + // copy map + for k, v := range currentState { + result[k] = v + } + + for k, v := range planValues { + currentValue, ok := result[k] + // if the key is missing or the value is allowed to be changed + if !ok || (currentValue != v && canChangeValue(k)) { + result[k] = v + changed = true + } + } + + for k, v := range delta.Add { + if result[k] != v { + changed = true + result[k] = v + } + } + + for k := range delta.Delete { + if _, ok := result[k]; ok { + delete(result, k) + changed = true + } + } + + return result, changed +} + +func (m *nodesSyncer) getNodePlan(node *apimgmtv3.Node) (rketypes.RKEConfigNodePlan, error) { + cluster, err := m.clusterLister.Get("", node.Namespace) + if err != nil { + return rketypes.RKEConfigNodePlan{}, err + } + + if cluster.Status.Driver != apimgmtv3.ClusterDriverRKE || cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + return rketypes.RKEConfigNodePlan{}, nil + } + + if node.Status.NodeConfig == nil { + return rketypes.RKEConfigNodePlan{}, nil + } + + dockerInfo, err := librke.GetDockerInfo(node) + if err != nil { + return rketypes.RKEConfigNodePlan{}, err + } + + hostAddress := node.Status.NodeConfig.Address + hostDockerInfo := dockerInfo[hostAddress] + + svcOptions, err := m.getServiceOptions(cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Version, hostDockerInfo.OSType) + if err != nil { + return rketypes.RKEConfigNodePlan{}, err + } + + appliedSpec, err := assemblers.AssembleRKEConfigSpec(cluster, *cluster.Status.AppliedSpec.DeepCopy(), m.secretLister) + if err != nil { + return rketypes.RKEConfigNodePlan{}, err + } + plan, err := librke.New().GeneratePlan(context.Background(), appliedSpec.RancherKubernetesEngineConfig, dockerInfo, svcOptions) + if err != nil { + return rketypes.RKEConfigNodePlan{}, err + } + + for _, nodePlan := range plan.Nodes { + if nodePlan.Address == node.Status.NodeConfig.Address { + return nodePlan, nil + } + } + + return rketypes.RKEConfigNodePlan{}, nil +} + +func (m *nodesSyncer) getServiceOptions(k8sVersion string, osType string) (map[string]interface{}, error) { + data := map[string]interface{}{} + svcOptions, err := kd.GetRKEK8sServiceOptions(k8sVersion, m.serviceOptionsLister, m.serviceOptions, m.sysImagesLister, m.sysImages, kd.Linux) + if err != nil { + logrus.Errorf("getK8sServiceOptions: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptions != nil { + data["k8s-service-options"] = svcOptions + } + if osType == "windows" { + svcOptionsWindows, err := kd.GetRKEK8sServiceOptions(k8sVersion, m.serviceOptionsLister, m.serviceOptions, m.sysImagesLister, m.sysImages, kd.Windows) + if err != nil { + logrus.Errorf("getK8sServiceOptionsWindows: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptionsWindows != nil { + data["k8s-windows-service-options"] = svcOptionsWindows + } + } + return data, nil +} + +func (m *nodesSyncer) reconcileAll() error { + // skip reconcile if we are restoring from backup, + // this is needed to avoid adding/deleting replaced nodes that might be in the + // snapshots before the cluster restore/reconcile is complete + if m.clusterNamespace != "local" { // we don't check for local cluster + if restoring, err := m.isClusterRestoring(); restoring { + return nil + } else if err != nil { + return err + } + } + + nodes, err := m.nodeLister.List("", labels.NewSelector()) + if err != nil { + return err + } + + nodeMap := make(map[string]*corev1.Node, len(nodes)) + for _, node := range nodes { + nodeMap[node.Name] = node + } + + machines, err := m.machineLister.List(m.clusterNamespace, labels.NewSelector()) + if err != nil { + return err + } + machineMap := make(map[string]*apimgmtv3.Node) + toDelete := make(map[string]*apimgmtv3.Node) + for _, machine := range machines { + node, err := nodehelper.GetNodeForMachine(machine, m.nodeLister) + if err != nil { + return err + } + if node == nil { + logrus.Debugf("Failed to get node for machine [%s], preparing to delete", machine.Name) + toDelete[machine.Name] = machine + continue + } + machineMap[node.Name] = machine + } + nodeCache := &NodeCache{} + + // reconcile machines for existing nodes + for name, node := range nodeMap { + machine := machineMap[name] + err = m.reconcileNodeForNode(machine, node, nodeCache) + if err != nil { + return err + } + } + // run the logic for machine to remove + for name, machine := range machineMap { + if _, ok := nodeMap[name]; !ok { + if err = m.removeNode(machine); err != nil { + return err + } + } + } + + for _, machine := range toDelete { + if err = m.removeNode(machine); err != nil { + return err + } + } + + return nil +} + +func (m *nodesSyncer) reconcileNodeForNode(machine *apimgmtv3.Node, node *corev1.Node, nodeCache *NodeCache) error { + if machine == nil { + return m.createNode(node, nodeCache) + } + return m.updateNode(machine, node) +} + +func (m *nodesSyncer) removeNode(machine *apimgmtv3.Node) error { + if machine.DeletionTimestamp != nil { + return nil + } + if machine.Annotations == nil { + return nil + } + + if _, ok := machine.Annotations[annotationName]; !ok { + return nil + } + + err := m.machines.Delete(machine.ObjectMeta.Name, nil) + if err != nil { + return errors.Wrapf(err, "Failed to delete machine [%s]", machine.Name) + } + logrus.Infof("Deleted cluster node %s [%s]", machine.Name, machine.Status.NodeName) + return nil +} + +func (m *nodesSyncer) updateNode(existing *apimgmtv3.Node, node *corev1.Node) error { + toUpdate, err := m.convertNodeToMachine(node, existing) + if err != nil { + return err + } + // update only when nothing changed + if objectsAreEqual(existing, toUpdate) { + return nil + } + logrus.Debugf("Updating machine for node [%s]", node.Name) + _, err = m.machines.Update(toUpdate) + if err != nil { + return errors.Wrapf(err, "Failed to update machine for node [%s]", node.Name) + } + logrus.Debugf("Updated machine for node [%s]", node.Name) + return nil +} + +func (m *nodesSyncer) createNode(node *corev1.Node, nodeCache *NodeCache) error { + // respect user defined name or label + if nodehelper.IgnoreNode(node.Name, node.Labels) { + logrus.Debugf("Skipping apimgmtv3.Node creation for [%v] node", node.Name) + return nil + } + + // try to get machine from api, in case cache didn't get the update + existing, err := m.getMachineForNode(node, nodeCache) + if err != nil { + return err + } + if existing != nil { + return nil + } + machine, err := m.convertNodeToMachine(node, existing) + if err != nil { + return err + } + + if machine.Annotations == nil { + machine.Annotations = make(map[string]string) + } + machine.Annotations[annotationName] = "true" + + _, err = m.machines.Create(machine) + if err != nil { + return errors.Wrapf(err, "Failed to create machine for node [%s]", node.Name) + } + logrus.Infof("Created machine for node [%s]", node.Name) + return nil +} + +func (m *nodesSyncer) getMachineForNodeFromCache(node *corev1.Node) (*apimgmtv3.Node, error) { + return nodehelper.GetMachineForNode(node, m.clusterNamespace, m.machineLister) +} + +type NodeCache struct { + all []*apimgmtv3.Node + byName map[string][]*apimgmtv3.Node +} + +func (n *NodeCache) Add(machine *apimgmtv3.Node) { + if n.byName == nil { + n.byName = map[string][]*apimgmtv3.Node{} + } + if name, ok := machine.Labels[nodehelper.LabelNodeName]; ok { + n.byName[name] = append(n.byName[name], machine) + } + n.all = append(n.all, machine) +} + +func (m *nodesSyncer) getMachineForNode(node *corev1.Node, nodeCache *NodeCache) (*apimgmtv3.Node, error) { + if len(nodeCache.all) == 0 { + machines, err := m.machines.List(metav1.ListOptions{}) + if err != nil { + return nil, err + } + for i := range machines.Items { + nodeCache.Add(&machines.Items[i]) + } + } + + machines := nodeCache.byName[node.Name] + if len(machines) == 0 { + machines = nodeCache.all + } + + for _, machine := range machines { + if machine.Namespace == m.clusterNamespace { + if nodehelper.IsNodeForNode(node, machine) { + return machine, nil + } + } + } + + return nil, nil +} + +func resetConditions(machine *apimgmtv3.Node) *apimgmtv3.Node { + if machine.Status.InternalNodeStatus.Conditions == nil { + return machine + } + updated := machine.DeepCopy() + var toUpdateConds []corev1.NodeCondition + for _, cond := range machine.Status.InternalNodeStatus.Conditions { + toUpdateCond := cond.DeepCopy() + toUpdateCond.LastHeartbeatTime = metav1.Time{} + toUpdateCond.LastTransitionTime = metav1.Time{} + toUpdateConds = append(toUpdateConds, *toUpdateCond) + } + sort.Slice(toUpdateConds, func(i, j int) bool { + return toUpdateConds[i].Type < toUpdateConds[j].Type + }) + updated.Status.InternalNodeStatus.Conditions = toUpdateConds + return updated +} + +func objectsAreEqual(existing *apimgmtv3.Node, toUpdate *apimgmtv3.Node) bool { + // we are updating spec and status only, so compare them + toUpdateToCompare := resetConditions(toUpdate) + existingToCompare := resetConditions(existing) + statusEqual := statusEqualTest(toUpdateToCompare.Status.InternalNodeStatus, existingToCompare.Status.InternalNodeStatus) + conditionsEqual := reflect.DeepEqual(toUpdateToCompare.Status.Conditions, existing.Status.Conditions) + labelsEqual := reflect.DeepEqual(toUpdateToCompare.Status.NodeLabels, existing.Status.NodeLabels) && reflect.DeepEqual(toUpdateToCompare.Labels, existing.Labels) + annotationsEqual := reflect.DeepEqual(toUpdateToCompare.Status.NodeAnnotations, existing.Status.NodeAnnotations) + specEqual := reflect.DeepEqual(toUpdateToCompare.Spec.InternalNodeSpec, existingToCompare.Spec.InternalNodeSpec) + nodeNameEqual := toUpdateToCompare.Status.NodeName == existingToCompare.Status.NodeName + requestsEqual := isEqual(toUpdateToCompare.Status.Requested, existingToCompare.Status.Requested) + limitsEqual := isEqual(toUpdateToCompare.Status.Limits, existingToCompare.Status.Limits) + rolesEqual := toUpdateToCompare.Spec.Worker == existingToCompare.Spec.Worker && toUpdateToCompare.Spec.Etcd == existingToCompare.Spec.Etcd && + toUpdateToCompare.Spec.ControlPlane == existingToCompare.Spec.ControlPlane + + retVal := statusEqual && conditionsEqual && specEqual && nodeNameEqual && labelsEqual && annotationsEqual && requestsEqual && limitsEqual && rolesEqual + if !retVal { + logrus.Debugf("ObjectsAreEqualResults for %s: statusEqual: %t conditionsEqual: %t specEqual: %t"+ + " nodeNameEqual: %t labelsEqual: %t annotationsEqual: %t requestsEqual: %t limitsEqual: %t rolesEqual: %t", + toUpdate.Name, statusEqual, conditionsEqual, specEqual, nodeNameEqual, labelsEqual, annotationsEqual, requestsEqual, limitsEqual, rolesEqual) + } + return retVal +} + +func statusEqualTest(proposed, existing corev1.NodeStatus) bool { + // Tests here should validate that fields of the corev1.NodeStatus type are equal for Rancher's purposes. + // The Images field lists would be equal if they contain the same data regardless of order. Using reflect.DeepEqual + // does not see lists with the same content but different order as equal, and would cause + // Rancher to update the resource unnecessarily. So if Images becomes a field we need to validate we need to add + // a custom method to validate the equality. + // + // Rancher doesn't use the following NodeStatus data, so for time savings we are skipping, but in the future these tests + // should be added here. + // + // SKIP: + // - Images # Do not use reflect.DeepEquals on this field for testing. + // - NodeInfo + // - DaemonEndpoints + // - Phase + + // Capacity + if !reflect.DeepEqual(proposed.Capacity, existing.Capacity) { + logrus.Debugf("Changes in Capacity, proposed %#v, existing: %#v", proposed.Capacity, existing.Capacity) + return false + } + + // Allocatable + if !reflect.DeepEqual(proposed.Allocatable, existing.Allocatable) { + logrus.Debugf("Changes in Allocatable, proposed %#v, existing: %#v", proposed.Allocatable, existing.Allocatable) + return false + } + + // Conditions + if !reflect.DeepEqual(proposed.Conditions, existing.Conditions) { + logrus.Debugf("Changes in Conditions, proposed %#v, existing: %#v", proposed.Conditions, existing.Conditions) + return false + } + + // Addresses + if !reflect.DeepEqual(proposed.Addresses, existing.Addresses) { + logrus.Debugf("Changes in Addresses, proposed %#v, existing: %#v", proposed.Addresses, existing.Addresses) + return false + } + + // Volumes in use (This test might prove to be an issue if order is not returned consistently.) + if !reflect.DeepEqual(proposed.VolumesInUse, existing.VolumesInUse) { + logrus.Debugf("Changes in VolumesInUse, proposed %#v, existing: %#v", proposed.VolumesInUse, existing.VolumesInUse) + return false + } + + // VolumesAttached (This test might prove to cause excessive updates if order is not returned consistently.) + if !reflect.DeepEqual(proposed.VolumesAttached, existing.VolumesAttached) { + logrus.Debugf("Changes in VolumesAttached, proposed %#v, existing: %#v", proposed.VolumesAttached, existing.VolumesAttached) + return false + } + + // Compare Node's Kubernetes versions + if proposed.NodeInfo.KubeletVersion != existing.NodeInfo.KubeletVersion || + proposed.NodeInfo.KubeProxyVersion != existing.NodeInfo.KubeProxyVersion || + proposed.NodeInfo.ContainerRuntimeVersion != existing.NodeInfo.ContainerRuntimeVersion { + logrus.Debugf("Changes in KubernetesInfo, "+ + "KubeletVersion proposed %#v, existing: %#v"+ + "KubeProxyVersion proposed %#v, existing: %#v"+ + "ContainerRuntimeVersion proposed %#v, existing: %#v", + proposed.NodeInfo.KubeletVersion, existing.NodeInfo.KubeletVersion, + proposed.NodeInfo.KubeProxyVersion, existing.NodeInfo.KubeProxyVersion, + proposed.NodeInfo.ContainerRuntimeVersion, existing.NodeInfo.ContainerRuntimeVersion) + return false + } + + return true +} + +func cleanStatus(machine *apimgmtv3.Node) { + var conditions []corev1.NodeCondition + for _, condition := range machine.Status.InternalNodeStatus.Conditions { + if condition.Type == "Ready" { + conditions = append(conditions, condition) + readyCondition := apimgmtv3.NodeCondition{ + Type: cond.Cond(condition.Type), + Status: condition.Status, + LastTransitionTime: condition.LastTransitionTime.String(), + LastUpdateTime: condition.LastHeartbeatTime.String(), + Reason: condition.Reason, + Message: condition.Message, + } + var exists bool + for i, cond := range machine.Status.Conditions { + if cond.Type == "Ready" { + exists = true + machine.Status.Conditions[i] = readyCondition + break + } + } + if !exists { + machine.Status.Conditions = append(machine.Status.Conditions, readyCondition) + } + } + } + + machine.Status.InternalNodeStatus.Config = nil + machine.Status.InternalNodeStatus.VolumesInUse = nil + machine.Status.InternalNodeStatus.VolumesAttached = nil + machine.Status.InternalNodeStatus.Images = nil + machine.Status.InternalNodeStatus.Conditions = conditions + + annoMap := make(map[string]string, len(machine.Status.NodeAnnotations)) + for key, val := range machine.Status.NodeAnnotations { + if key == podresources.LimitsAnnotation || key == podresources.RequestsAnnotation { + continue + } + annoMap[key] = val + } + + machine.Status.NodeAnnotations = annoMap +} + +func getResourceList(annotation string, node *corev1.Node) corev1.ResourceList { + val := node.Annotations[annotation] + if val == "" { + return nil + } + result := corev1.ResourceList{} + if err := json.Unmarshal([]byte(val), &result); err != nil { + return corev1.ResourceList{} + } + return result +} + +func (m *nodesSyncer) convertNodeToMachine(node *corev1.Node, existing *apimgmtv3.Node) (*apimgmtv3.Node, error) { + var machine *apimgmtv3.Node + if existing == nil { + machine = &apimgmtv3.Node{ + Spec: apimgmtv3.NodeSpec{}, + Status: apimgmtv3.NodeStatus{}, + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "machine-"}, + } + machine.Namespace = m.clusterNamespace + machine.Status.Requested = make(map[corev1.ResourceName]resource.Quantity) + machine.Status.Limits = make(map[corev1.ResourceName]resource.Quantity) + machine.Spec.InternalNodeSpec = *node.Spec.DeepCopy() + machine.Status.InternalNodeStatus = *node.Status.DeepCopy() + machine.Spec.RequestedHostname = node.Name + } else { + machine = existing.DeepCopy() + machine.Spec.InternalNodeSpec = *node.Spec.DeepCopy() + machine.Status.InternalNodeStatus = *node.Status.DeepCopy() + } + + requests := getResourceList(podresources.RequestsAnnotation, node) + limits := getResourceList(podresources.LimitsAnnotation, node) + if machine.Status.Requested == nil { + machine.Status.Requested = corev1.ResourceList{} + } + if machine.Status.Limits == nil { + machine.Status.Limits = corev1.ResourceList{} + } + + for name, quantity := range requests { + machine.Status.Requested[name] = quantity + } + for name, quantity := range limits { + machine.Status.Limits[name] = quantity + } + machine.Status.NodeLabels = make(map[string]string, len(node.Labels)) + for k, v := range node.Labels { + machine.Status.NodeLabels[k] = v + } + determineNodeRoles(machine) + machine.Status.NodeAnnotations = make(map[string]string, len(node.Annotations)) + for k, v := range node.Annotations { + machine.Status.NodeAnnotations[k] = v + } + machine.Status.NodeName = node.Name + machine.APIVersion = "management.cattle.io/v3" + machine.Kind = "Node" + if machine.Labels == nil { + machine.Labels = map[string]string{} + } + machine.Labels[nodehelper.LabelNodeName] = node.Name + cleanStatus(machine) + apimgmtv3.NodeConditionRegistered.True(machine) + apimgmtv3.NodeConditionRegistered.Message(machine, "registered with kubernetes") + return machine, nil +} + +func isEqual(data1 map[corev1.ResourceName]resource.Quantity, data2 map[corev1.ResourceName]resource.Quantity) bool { + if len(data1) == 0 && len(data2) == 0 { + return true + } + if data1 == nil || data2 == nil { + return false + } + for key, value := range data1 { + if _, exists := data2[key]; !exists { + return false + } + value2 := data2[key] + if value.Value() != value2.Value() { + return false + } + } + return true +} + +func (m *nodesSyncer) isClusterRestoring() (bool, error) { + cluster, err := m.clusterLister.Get("", m.clusterNamespace) + if err != nil { + return false, err + } + if cluster.Spec.RancherKubernetesEngineConfig != nil && + cluster.Spec.RancherKubernetesEngineConfig.Restore.Restore { + return true, nil + } + if cluster.Status.Driver == "imported" { + return false, nil + } + if strings.HasPrefix(cluster.Name, "c-m-") { + provCluster, err := m.provClusterCache.Get(cluster.Spec.FleetWorkspaceName, cluster.Spec.DisplayName) + if err != nil { + return false, err + } + capiCluster, err := m.capiClusterCache.Get(provCluster.Namespace, provCluster.Name) + if apierrors.IsNotFound(err) { + return false, nil + } + if err != nil { + return false, err + } + if capiCluster.Spec.ControlPlaneRef.Kind != "RKEControlPlane" || capiCluster.Spec.ControlPlaneRef.APIVersion != "rke.cattle.io/v1" { + return false, nil + } + controlplane, err := m.rkeControlPlaneCache.Get(capiCluster.Spec.ControlPlaneRef.Namespace, capiCluster.Spec.ControlPlaneRef.Name) + if err != nil { + return false, err + } + phase := controlplane.Status.ETCDSnapshotRestorePhase + return phase != "" && phase != rkev1.ETCDSnapshotPhaseFinished && phase != rkev1.ETCDSnapshotPhaseFailed, nil + } + + return false, nil +} + +func determineNodeRoles(machine *apimgmtv3.Node) { + if machine.Status.NodeLabels != nil { + _, etcd := machine.Status.NodeLabels["node-role.kubernetes.io/etcd"] + _, control := machine.Status.NodeLabels["node-role.kubernetes.io/controlplane"] + _, master := machine.Status.NodeLabels["node-role.kubernetes.io/master"] + _, worker := machine.Status.NodeLabels["node-role.kubernetes.io/worker"] + machine.Spec.Etcd = etcd + machine.Spec.Worker = worker + machine.Spec.ControlPlane = control || master + if !machine.Spec.Worker && !machine.Spec.ControlPlane && !machine.Spec.Etcd { + machine.Spec.Worker = true + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer_test.go new file mode 100644 index 0000000..ab8c221 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodessyncer_test.go @@ -0,0 +1,138 @@ +package nodesyncer + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" +) + +func TestDetermineNodeRole(t *testing.T) { + var tests = []struct { + name string + node *v3.Node + expectedNode *v3.Node + }{ + { + name: "all node labels", + node: &v3.Node{ + Spec: v3.NodeSpec{}, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{ + "node-role.kubernetes.io/etcd": "true", + "node-role.kubernetes.io/controlplane": "true", + "node-role.kubernetes.io/master": "true", + "node-role.kubernetes.io/worker": "true"}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: true, + ControlPlane: true, + Worker: true, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{ + "node-role.kubernetes.io/etcd": "true", + "node-role.kubernetes.io/controlplane": "true", + "node-role.kubernetes.io/master": "true", + "node-role.kubernetes.io/worker": "true"}, + }, + }, + }, + { + name: "etcd node label", + node: &v3.Node{ + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/etcd": "true"}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: true, + ControlPlane: false, + Worker: false, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/etcd": "true"}, + }, + }, + }, + { + name: "controlplane node label", + node: &v3.Node{ + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/controlplane": "true"}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: false, + ControlPlane: true, + Worker: false, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/controlplane": "true"}, + }, + }, + }, + { + name: "master node label", + node: &v3.Node{ + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/master": "true"}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: false, + ControlPlane: true, + Worker: false, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/master": "true"}, + }, + }, + }, + { + name: "worker node label", + node: &v3.Node{ + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/worker": "true"}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: false, + ControlPlane: false, + Worker: true, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{"node-role.kubernetes.io/worker": "true"}, + }, + }, + }, + { + name: "no node labels set", + node: &v3.Node{ + Status: v3.NodeStatus{ + NodeLabels: map[string]string{}, + }, + }, + expectedNode: &v3.Node{ + Spec: v3.NodeSpec{ + Etcd: false, + ControlPlane: false, + Worker: true, + }, + Status: v3.NodeStatus{ + NodeLabels: map[string]string{}, + }, + }, + }, + } + for _, tt := range tests { + determineNodeRoles(tt.node) + assert.EqualValues(t, tt.expectedNode, tt.node) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints.go new file mode 100644 index 0000000..4a5fdbd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints.go @@ -0,0 +1,68 @@ +package nodesyncer + +import ( + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/taints" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func (m *nodesSyncer) syncTaints(key string, obj *v3.Node) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return obj, nil + } + + if !v32.NodeConditionRegistered.IsTrue(obj) { + return obj, nil + } + + if obj.Spec.UpdateTaintsFromAPI == nil { + return obj, nil + } + node, err := nodehelper.GetNodeForMachine(obj, m.nodeLister) + if err != nil || node == nil { + return obj, err + } + toAdd, toDel := taints.GetToDiffTaints(node.Spec.Taints, obj.Spec.DesiredNodeTaints) + newObj := obj.DeepCopy() + if len(toAdd) != 0 || len(toDel) != 0 { + newNode := node.DeepCopy() + var taintList []corev1.Taint + for index, taint := range newNode.Spec.Taints { + if _, ok := toDel[index]; !ok { + taintList = append(taintList, taint) + } + } + for _, taintStr := range toAdd { + taintList = append(taintList, taintStr) + } + newNode.Spec.Taints = taintList + if _, err := m.nodeClient.Update(newNode); err != nil && !isDuplicate(err) { + return obj, errors.Wrapf(err, "failed to update corev1.Node %s from v3.Node %s in node taint controller", node.Name, obj.Name) + } else if isDuplicate(err) { + // If the node has duplicated taints, we should skip the error and set desired taints to nil and stop trying again. + // The taints will be duplicated if they have same key and effect in k8s version >= 1.14, and same key only in version k8s <=1.13 + logrus.Errorf("failed to update corev1.Node %s from v3.Node %s in node taint controller, error: %s", node.Name, obj.Name, err.Error()) + } else if !reflect.DeepEqual(newObj.Spec.DesiredNodeTaints, newObj.Spec.InternalNodeSpec.Taints) { + newObj.Spec.InternalNodeSpec.Taints = taintList + } + } + newObj.Spec.DesiredNodeTaints = nil + newObj.Spec.UpdateTaintsFromAPI = nil + return m.machines.Update(newObj) +} + +func isDuplicate(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "taints must be unique by key and effect pair") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints_test.go new file mode 100644 index 0000000..8302974 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nodesyncer/nodetaints_test.go @@ -0,0 +1,204 @@ +package nodesyncer + +import ( + "fmt" + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/httperror" + fake1 "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + fake3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + nodehelper "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/taints" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type syncTaintsTestCase struct { + name string + machine v3.Node + node v1.Node + nodeShouldUpdate bool + nodeUpdated bool + machineShouldUpdate bool + machineUpdated bool +} + +func TestSyncNodeTaints(t *testing.T) { + falseValue := false + testCases := []*syncTaintsTestCase{ + &syncTaintsTestCase{ + name: "test taints equal", + machineShouldUpdate: true, + nodeShouldUpdate: false, + machine: v3.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test1", Labels: map[string]string{nodehelper.LabelNodeName: "test1"}}, + Status: v32.NodeStatus{ + Conditions: []v32.NodeCondition{ + v32.NodeCondition{ + Type: v32.NodeConditionRegistered, + Status: v1.ConditionTrue, + }, + }, + NodeName: "test1", + }, + Spec: v32.NodeSpec{ + DesiredNodeTaints: []v1.Taint{ + v1.Taint{Key: "test-key", Value: "test-value", Effect: v1.TaintEffectNoSchedule}, + }, + UpdateTaintsFromAPI: &falseValue, + }, + }, + node: v1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test1"}, + Spec: v1.NodeSpec{ + Taints: []v1.Taint{ + v1.Taint{Key: "test-key", Value: "test-value", Effect: v1.TaintEffectNoSchedule}, + }, + }, + }, + }, + &syncTaintsTestCase{ + name: "test add taints", + machineShouldUpdate: true, + nodeShouldUpdate: true, + machine: v3.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test2", Labels: map[string]string{nodehelper.LabelNodeName: "test2"}}, + Status: v32.NodeStatus{ + Conditions: []v32.NodeCondition{ + v32.NodeCondition{ + Type: v32.NodeConditionRegistered, + Status: v1.ConditionTrue, + }, + }, + NodeName: "test2", + }, + Spec: v32.NodeSpec{ + DesiredNodeTaints: []v1.Taint{ + v1.Taint{Key: "test-key", Value: "test-value", Effect: v1.TaintEffectNoSchedule}, + }, + UpdateTaintsFromAPI: &falseValue, + }, + }, + node: v1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test2"}, + Spec: v1.NodeSpec{}, + }, + }, + &syncTaintsTestCase{ + name: "test remove taints", + machineShouldUpdate: true, + nodeShouldUpdate: true, + machine: v3.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test3", Labels: map[string]string{nodehelper.LabelNodeName: "test3"}}, + Status: v32.NodeStatus{ + Conditions: []v32.NodeCondition{ + v32.NodeCondition{ + Type: v32.NodeConditionRegistered, + Status: v1.ConditionTrue, + }, + }, + NodeName: "test3", + }, + Spec: v32.NodeSpec{ + UpdateTaintsFromAPI: &falseValue, + }, + }, + node: v1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "test3"}, + Spec: v1.NodeSpec{ + Taints: []v1.Taint{ + v1.Taint{Key: "test-key", Value: "test-value", Effect: v1.TaintEffectNoSchedule}, + }, + }, + }, + }, + } + syncer := nodesSyncer{ + machines: &fake3.NodeInterfaceMock{ + UpdateFunc: getMachineUpdateFunc(t, testCases), + }, + nodeLister: &fake1.NodeListerMock{ + GetFunc: getNodeListerGetFunc(t, testCases), + }, + nodeClient: &fake1.NodeInterfaceMock{ + UpdateFunc: getNodeInterfaceUpdateFunc(t, testCases), + }, + } + for _, c := range testCases { + if _, err := syncer.syncTaints(c.machine.Name, &c.machine); err != nil { + t.Fatalf("test case %s failed, syncTaints return errors %s", c.name, err.Error()) + } + if c.nodeShouldUpdate != c.nodeUpdated { + t.Fatalf("test case %s failed, expect node update status is %v but got %v", c.name, c.nodeShouldUpdate, c.nodeUpdated) + } + if c.machineShouldUpdate != c.machineUpdated { + t.Fatalf("test case %s failed, expect machine update status is %v but got %v", c.name, c.machineShouldUpdate, c.machineUpdated) + } + } +} + +func getMachineUpdateFunc(t *testing.T, cases []*syncTaintsTestCase) func(*v3.Node) (*v3.Node, error) { + machineSet := caseByMachine(t, cases) + return func(in1 *v3.Node) (*v3.Node, error) { + c := machineSet[in1.Name] + c.machineUpdated = true + c.machine = *in1 + if c.machine.Spec.DesiredNodeTaints != nil || c.machine.Spec.UpdateTaintsFromAPI != nil { + t.Fatalf("test case %s failed, update machine in node taints syncer should set DesiredNodeTaints and UpdateTaintsFromAPI to nil", c.name) + } + return &c.machine, nil + } +} + +func getNodeListerGetFunc(t *testing.T, cases []*syncTaintsTestCase) func(string, string) (*v1.Node, error) { + nodeSet := caseByNode(t, cases) + return func(namespace string, name string) (*v1.Node, error) { + c, ok := nodeSet[name] + if !ok { + return nil, httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("node %s not found", name)) + } + return &c.node, nil + } +} + +func getNodeInterfaceUpdateFunc(t *testing.T, cases []*syncTaintsTestCase) func(*v1.Node) (*v1.Node, error) { + nodeSet := caseByNode(t, cases) + return func(in1 *v1.Node) (*v1.Node, error) { + c, ok := nodeSet[in1.Name] + if !ok { + return nil, httperror.NewAPIError(httperror.NotFound, fmt.Sprintf("node %s not found", in1.Name)) + } + toAdd, toDel := taints.GetToDiffTaints(in1.Spec.Taints, c.machine.Spec.DesiredNodeTaints) + if len(toAdd) != 0 || len(toDel) != 0 { + return nil, fmt.Errorf("test case %s failed, node taints are different from machine taints", c.name) + } + c.nodeUpdated = true + c.node = *in1 + return in1, nil + } +} + +func caseByMachine(t *testing.T, cases []*syncTaintsTestCase) map[string]*syncTaintsTestCase { + rtn := map[string]*syncTaintsTestCase{} + for _, c := range cases { + if _, ok := rtn[c.machine.Name]; ok { + t.Fatalf("test case %s has duplicated machine name %s", c.name, c.machine.Name) + } + rtn[c.machine.Name] = c + } + return rtn +} + +func caseByNode(t *testing.T, cases []*syncTaintsTestCase) map[string]*syncTaintsTestCase { + rtn := map[string]*syncTaintsTestCase{} + for _, c := range cases { + if _, ok := rtn[c.node.Name]; ok { + t.Fatalf("test case %s has duplicated node name %s", c.name, c.node.Name) + } + rtn[c.node.Name] = c + } + return rtn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nsserviceaccount/nssvcaccnt.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nsserviceaccount/nssvcaccnt.go new file mode 100644 index 0000000..16bef00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/nsserviceaccount/nssvcaccnt.go @@ -0,0 +1,98 @@ +package nsserviceaccount + +import ( + "context" + "fmt" + "strings" + + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/controllers/managementagent/nsserviceaccount" + rv1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + projectIDAnnotation = "field.cattle.io/projectId" + sysNamespaceAnnotation = "management.cattle.io/system-namespace" +) + +type defaultSvcAccountHandler struct { + namespaces rv1.NamespaceInterface + projectLister v3.ProjectLister + clusterName string +} + +func Register(ctx context.Context, cluster *config.UserContext) { + logrus.Debugf("Registering defaultSvcAccountHandler for checking default service account of system namespaces") + nsh := &defaultSvcAccountHandler{ + namespaces: cluster.Core.Namespaces(""), + clusterName: cluster.ClusterName, + projectLister: cluster.Management.Management.Projects("").Controller().Lister(), + } + cluster.Core.Namespaces("").AddHandler(ctx, "defaultSvcAccountHandler", nsh.Sync) +} + +func (nsh *defaultSvcAccountHandler) Sync(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil || ns.DeletionTimestamp != nil { + return nil, nil + } + logrus.Debugf("defaultSvcAccountHandler: Sync service account: key=%v", key) + //handle default svcAccount of system namespaces only + ret, err := nsh.handleIfSystemNSDefaultSA(ns) + if err != nil { + logrus.Errorf("defaultSvcAccountHandler: Sync: error handling default ServiceAccount of namespace key=%v, err=%v", key, err) + } + return ret, err +} + +func (nsh *defaultSvcAccountHandler) handleIfSystemNSDefaultSA(ns *corev1.Namespace) (runtime.Object, error) { + namespace := ns.Name + proj, err := project.GetSystemProject(nsh.clusterName, nsh.projectLister) + if err != nil { + return nil, err + } + sysProjAnn := fmt.Sprintf("%v:%v", nsh.clusterName, proj.Name) + if namespace == "kube-system" || namespace == "default" || (!nsh.isSystemNS(namespace) && !nsh.isSystemProjectNS(ns, sysProjAnn)) { + return nil, nil + } + if ns.Annotations[nsserviceaccount.NoDefaultSATokenAnnotation] != "true" { + ns = ns.DeepCopy() + if ns.Annotations == nil { + ns.Annotations = map[string]string{} + } + ns.Annotations[nsserviceaccount.NoDefaultSATokenAnnotation] = "true" + return nsh.namespaces.Update(ns) + } + return ns, nil +} + +func (nsh *defaultSvcAccountHandler) isSystemNS(namespace string) bool { + systemNamespacesStr := settings.SystemNamespaces.Get() + if systemNamespacesStr == "" { + return false + } + systemNamespaces := strings.Split(systemNamespacesStr, ",") + return slice.ContainsString(systemNamespaces, namespace) +} + +func (nsh *defaultSvcAccountHandler) isSystemProjectNS(nsObj *corev1.Namespace, sysProjectAnnotation string) bool { + if nsObj.Annotations == nil { + return false + } + + if val, ok := nsObj.Annotations[sysNamespaceAnnotation]; ok && val == "true" { + return true + } + + if prjAnnVal, ok := nsObj.Annotations[projectIDAnnotation]; ok && prjAnnVal == sysProjectAnnotation { + return true + } + + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler.go new file mode 100644 index 0000000..cc382ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler.go @@ -0,0 +1,119 @@ +package rbac + +import ( + "fmt" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + k8srbac "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + grbByRoleIndex = "management.cattle.io/grb-by-role" +) + +func newClusterHandler(workload *config.UserContext) v3.ClusterHandlerFunc { //*clusterHandler { + informer := workload.Management.Management.GlobalRoleBindings("").Controller().Informer() + + ch := &clusterHandler{ + clusterName: workload.ClusterName, + grbIndexer: informer.GetIndexer(), + // Management level resources + clusters: workload.Management.Management.Clusters(""), + // User context resources + userCRB: workload.RBAC.ClusterRoleBindings(""), + userCRBLister: workload.RBAC.ClusterRoleBindings("").Controller().Lister(), + } + return ch.sync +} + +type clusterHandler struct { + clusterName string + grbIndexer cache.Indexer + // Management level resources + clusters v3.ClusterInterface + // User context resources + userCRB v1.ClusterRoleBindingInterface + userCRBLister v1.ClusterRoleBindingLister +} + +func (h *clusterHandler) sync(key string, obj *v3.Cluster) (runtime.Object, error) { + // We receive clusters with no data, when that happens no checks will work so just ignore them + if key == "" || obj == nil || obj.Name == "" { + return nil, nil + } + + // Don't operate on a cluster this handler isn't created for + if h.clusterName != obj.Name { + return nil, nil + } + + if !v32.ClusterConditionGlobalAdminsSynced.IsTrue(obj) { + err := h.doSync(obj) + if err != nil { + return nil, err + } + return h.clusters.Update(obj) + } + return obj, nil +} + +// doSync syncs CRBs for all GlobalAdmins to the clustere role 'cluster-admin'. +func (h *clusterHandler) doSync(cluster *v3.Cluster) error { + _, err := v32.ClusterConditionGlobalAdminsSynced.DoUntilTrue(cluster, func() (runtime.Object, error) { + grbs, err := h.grbIndexer.ByIndex(grbByRoleIndex, rbac.GlobalAdmin) + if err != nil { + return nil, fmt.Errorf("failed to list GlobalRoleBindings for global-admin: %w", err) + } + + for _, x := range grbs { + grb, ok := x.(*v32.GlobalRoleBinding) + if !ok || grb == nil { + continue + } + bindingName := rbac.GrbCRBName(grb) + _, err := h.userCRBLister.Get("", bindingName) + if err == nil { + // binding exists, nothing to do + continue + } + if !k8serrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to get GlobalRoleBinding for '%s': %w", bindingName, err) + } + + _, err = h.userCRB.Create(&k8srbac.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + }, + Subjects: []k8srbac.Subject{ + rbac.GetGRBSubject(grb), + }, + RoleRef: k8srbac.RoleRef{ + Name: "cluster-admin", + Kind: "ClusterRole", + }, + }) + if err != nil && !k8serrors.IsAlreadyExists(err) { + return nil, fmt.Errorf("failed to create new ClusterRoleBinding for GlobalRoleBinding '%s': %w", grb.Name, err) + } + } + return nil, nil + }) + return err +} + +func grbByRole(obj interface{}) ([]string, error) { + grb, ok := obj.(*v32.GlobalRoleBinding) + if !ok { + return []string{}, nil + } + + return []string{grb.GlobalRoleName}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler_test.go new file mode 100644 index 0000000..1f89a00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/cluster_handler_test.go @@ -0,0 +1,309 @@ +// mocks created with the following commands +// +// mockgen --build_flags=--mod=mod -package rbac -destination ./v3mgmntMocks_test.go github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3 ClusterInterface +// mockgen --build_flags=--mod=mod -package rbac -destination ./v1rbacMocks_test.go github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1 ClusterRoleBindingInterface,ClusterRoleBindingLister +package rbac + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/stretchr/testify/require" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" +) + +var ( + errNotFound = apierrors.NewNotFound(schema.GroupResource{}, "") + errAlreadyExist = apierrors.NewAlreadyExists(schema.GroupResource{}, "") + errExpected = fmt.Errorf("expected test error") +) + +func Test_clusterHandler_sync(t *testing.T) { + testGrbs := []*v32.GlobalRoleBinding{ + {ObjectMeta: metav1.ObjectMeta{Name: "GRB1"}, GlobalRoleName: rbac.GlobalAdmin}, + {ObjectMeta: metav1.ObjectMeta{Name: "GRB2"}, GlobalRoleName: rbac.GlobalAdmin}, + {ObjectMeta: metav1.ObjectMeta{Name: "GRB3"}, GlobalRoleName: rbac.GlobalAdmin}, + } + testCluster := &v32.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "testCluster"}} + falseCluster := &v32.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "falseCluster"}} + falseCluster.Status.Conditions = []v32.ClusterCondition{ + {Type: v32.ClusterConditionType(v32.ClusterConditionGlobalAdminsSynced), Status: "False"}, + } + trueCluster := &v32.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "preSet"}} + trueCluster.Status.Conditions = []v32.ClusterCondition{ + {Type: v32.ClusterConditionType(v32.ClusterConditionGlobalAdminsSynced), Status: "True"}, + } + tests := []struct { + name string + setup func(mocks *testMocks) + clusterName string + key string + cluster *v32.Cluster + wantErr bool + }{ + { + name: "single GRB condition not set", + clusterName: testCluster.Name, + key: testCluster.Name, + cluster: testCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil).Times(1) + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "single GRB condition false", + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil).Times(1) + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "condition true", + clusterName: trueCluster.Name, + key: trueCluster.Name, + cluster: trueCluster.DeepCopy(), + setup: func(m *testMocks) {}, + }, + { + name: "multiple GRBs", + clusterName: testCluster.Name, + key: testCluster.Name, + cluster: testCluster.DeepCopy(), + setup: func(m *testMocks) { + for _, obj := range testGrbs { + m.mockCache.Add(obj) + } + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[1])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[2])).Return(nil, errNotFound) + + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil).Times(3) + + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "multiple GRBs one CRB already exist in cache", + clusterName: testCluster.Name, + key: testCluster.Name, + cluster: testCluster.DeepCopy(), + setup: func(m *testMocks) { + for _, obj := range testGrbs { + m.mockCache.Add(obj) + } + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[1])).Return(&rbacv1.ClusterRoleBinding{}, nil) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[2])).Return(nil, errNotFound) + + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil).Times(2) + + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "multiple GRBs one CRB already exist, but not in cache", + clusterName: testCluster.Name, + key: testCluster.Name, + cluster: testCluster.DeepCopy(), + setup: func(m *testMocks) { + for _, obj := range testGrbs { + m.mockCache.Add(obj) + } + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[1])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[2])).Return(nil, errNotFound) + + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, errAlreadyExist) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil) + + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "no admin GRBs returned", + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCluster.EXPECT().Update(gomock.Any()).DoAndReturn(func(cluster *v32.Cluster) (*v32.Cluster, error) { + require.Len(m.t, cluster.Status.Conditions, 1) + require.Equal(m.t, string(v32.ClusterConditionGlobalAdminsSynced), string(cluster.Status.Conditions[0].Type), "incorrect condition set") + require.Equal(m.t, "True", string(cluster.Status.Conditions[0].Status), "expected true condition to be set") + return cluster, nil + }) + }, + }, + { + name: "failed indexer call", + wantErr: true, + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + // create empty indexer + m.mockCache = cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + }, + }, + { + name: "failed create call", + wantErr: true, + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, errExpected) + }, + }, + { + name: "failed cache get", + wantErr: true, + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errExpected) + }, + }, + { + name: "failed create multiple GRBs", + wantErr: true, + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockCache.Add(testGrbs[1]) + m.mockCache.Add(testGrbs[2]) + + // first GRB returns not found and is created + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[1])).Return(nil, errNotFound) + + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil) + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, errExpected) + }, + }, + { + name: "failed cache get multiple GRBs", + wantErr: true, + clusterName: falseCluster.Name, + key: falseCluster.Name, + cluster: falseCluster.DeepCopy(), + setup: func(m *testMocks) { + m.mockCache.Add(testGrbs[0]) + m.mockCache.Add(testGrbs[1]) + m.mockCache.Add(testGrbs[2]) + + // first GRB returns not found and is created + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[0])).Return(nil, errNotFound) + + // second GRB returns an error and the handler returns that error. + m.mockLister.EXPECT().Get("", rbac.GrbCRBName(testGrbs[1])).Return(nil, errExpected) + + m.mockInt.EXPECT().Create(gomock.Any()).Return(nil, nil) + }, + }, + { + name: "nil cluster", + clusterName: testCluster.Name, + key: testCluster.Name, + cluster: nil, + setup: func(m *testMocks) {}, + }, + { + name: "cluster mismatch", + clusterName: "unique", + key: testCluster.Name, + cluster: testCluster.DeepCopy(), + setup: func(m *testMocks) {}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mocks := newMocks(t) + tt.setup(mocks) + h := &clusterHandler{ + clusterName: tt.clusterName, + clusters: mocks.mockCluster, + userCRB: mocks.mockInt, + userCRBLister: mocks.mockLister, + grbIndexer: mocks.mockCache, + } + _, err := h.sync(tt.key, tt.cluster) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} + +type testMocks struct { + t *testing.T + mockCluster *MockClusterInterface + mockInt *MockClusterRoleBindingInterface + mockLister *MockClusterRoleBindingLister + mockCache cache.Indexer +} + +func newMocks(t *testing.T) *testMocks { + t.Helper() + ctrl := gomock.NewController(t) + indexers := map[string]cache.IndexFunc{ + grbByRoleIndex: grbByRole, + } + mockIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + mockIndexer.AddIndexers(indexers) + return &testMocks{ + t: t, + mockCluster: NewMockClusterInterface(ctrl), + mockInt: NewMockClusterRoleBindingInterface(ctrl), + mockLister: NewMockClusterRoleBindingLister(ctrl), + mockCache: mockIndexer, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/clusterrole_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/clusterrole_handler.go new file mode 100644 index 0000000..35891ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/clusterrole_handler.go @@ -0,0 +1,42 @@ +package rbac + +import ( + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type crHandler struct { + clusterRoles typesrbacv1.ClusterRoleInterface + roleTemplateLister v3.RoleTemplateLister +} + +func newClusterRoleHandler(r *manager) *crHandler { + return &crHandler{ + clusterRoles: r.clusterRoles, + roleTemplateLister: r.rtLister, + } +} + +// sync validates that a clusterRole's parent roleTemplate still exists in management +// and will remove the clusterRole if the roleTemplate no longer exists. +func (c *crHandler) sync(key string, obj *rbacv1.ClusterRole) (runtime.Object, error) { + if key == "" || obj == nil { + return nil, nil + } + + if owner, ok := obj.Annotations[clusterRoleOwner]; ok { + _, err := c.roleTemplateLister.Get("", owner) + if err != nil { + if apierrors.IsNotFound(err) { + return obj, c.clusterRoles.Delete(obj.Name, &metav1.DeleteOptions{}) + } + return obj, err + } + } + + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler.go new file mode 100644 index 0000000..52aea81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler.go @@ -0,0 +1,173 @@ +package rbac + +import ( + "errors" + "fmt" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/client-go/util/retry" +) + +func newCRTBLifecycle(m *manager, management *config.ManagementContext) *crtbLifecycle { + return &crtbLifecycle{ + m: m, + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + crbLister: m.workload.RBAC.ClusterRoleBindings("").Controller().Lister(), + crbClient: m.workload.RBAC.ClusterRoleBindings(""), + crtbClient: management.Management.ClusterRoleTemplateBindings(""), + } +} + +type crtbLifecycle struct { + m managerInterface + rtLister v3.RoleTemplateLister + crbLister typesrbacv1.ClusterRoleBindingLister + crbClient typesrbacv1.ClusterRoleBindingInterface + crtbClient v3.ClusterRoleTemplateBindingInterface +} + +func (c *crtbLifecycle) Create(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + err := c.syncCRTB(obj) + return obj, err +} + +func (c *crtbLifecycle) Updated(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + if err := c.reconcileCRTBUserClusterLabels(obj); err != nil { + return obj, err + } + err := c.syncCRTB(obj) + return obj, err +} + +func (c *crtbLifecycle) Remove(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + err := c.ensureCRTBDelete(obj) + return obj, err +} + +func (c *crtbLifecycle) syncCRTB(binding *v3.ClusterRoleTemplateBinding) error { + if binding.RoleTemplateName == "" { + logrus.Warnf("ClusterRoleTemplateBinding %v has no role template set. Skipping.", binding.Name) + return nil + } + + if binding.UserName == "" && binding.GroupPrincipalName == "" && binding.GroupName == "" { + return nil + } + + rt, err := c.rtLister.Get("", binding.RoleTemplateName) + if err != nil { + return fmt.Errorf("couldn't get role template %v: %w", binding.RoleTemplateName, err) + } + + roles := map[string]*v3.RoleTemplate{} + if err := c.m.gatherRoles(rt, roles, 0); err != nil { + return err + } + + if err := c.m.ensureRoles(roles); err != nil { + return fmt.Errorf("couldn't ensure roles: %w", err) + } + + if err := c.m.ensureClusterBindings(roles, binding); err != nil { + return fmt.Errorf("couldn't ensure cluster bindings %v: %w", binding, err) + } + + if binding.UserName != "" { + if err := c.m.ensureServiceAccountImpersonator(binding.UserName); err != nil { + return fmt.Errorf("couldn't ensure service account impersonator: %w", err) + } + } + + return nil +} + +func (c *crtbLifecycle) ensureCRTBDelete(binding *v3.ClusterRoleTemplateBinding) error { + set := labels.Set(map[string]string{rtbOwnerLabel: pkgrbac.GetRTBLabel(binding.ObjectMeta)}) + rbs, err := c.crbLister.List("", set.AsSelector()) + if err != nil { + return fmt.Errorf("couldn't list clusterrolebindings with selector %s: %w", set.AsSelector(), err) + } + + for _, rb := range rbs { + if err := c.crbClient.Delete(rb.Name, &metav1.DeleteOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("error deleting clusterrolebinding %v: %w", rb.Name, err) + } + } + } + + if err := c.m.deleteServiceAccountImpersonator(binding.UserName); err != nil { + return fmt.Errorf("error deleting service account impersonator: %w", err) + } + + return nil +} + +func (c *crtbLifecycle) reconcileCRTBUserClusterLabels(binding *v3.ClusterRoleTemplateBinding) error { + /* Prior to 2.5, for every CRTB, following CRBs are created in the user clusters + 1. CRTB.UID is the label value for a CRB, authz.cluster.cattle.io/rtb-owner=CRTB.UID + Using this labels, list the CRBs and update them to add a label with ns+name of CRTB + */ + if binding.Labels[rtbCrbRbLabelsUpdated] == "true" { + return nil + } + + var returnErr error + set := labels.Set(map[string]string{rtbOwnerLabelLegacy: string(binding.UID)}) + reqUpdatedLabel, err := labels.NewRequirement(rtbLabelUpdated, selection.DoesNotExist, []string{}) + if err != nil { + return err + } + reqNsAndNameLabel, err := labels.NewRequirement(rtbOwnerLabel, selection.DoesNotExist, []string{}) + if err != nil { + return err + } + set.AsSelector().Add(*reqUpdatedLabel, *reqNsAndNameLabel) + userCRBs, err := c.crbClient.List(metav1.ListOptions{LabelSelector: set.AsSelector().Add(*reqUpdatedLabel, *reqNsAndNameLabel).String()}) + if err != nil { + return err + } + bindingValue := pkgrbac.GetRTBLabel(binding.ObjectMeta) + for _, crb := range userCRBs.Items { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crbToUpdate, updateErr := c.crbClient.Get(crb.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crbToUpdate.Labels == nil { + crbToUpdate.Labels = make(map[string]string) + } + crbToUpdate.Labels[rtbOwnerLabel] = bindingValue + crbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := c.crbClient.Update(crbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + if returnErr != nil { + return returnErr + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crtbToUpdate, updateErr := c.crtbClient.GetNamespaced(binding.Namespace, binding.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crtbToUpdate.Labels == nil { + crtbToUpdate.Labels = make(map[string]string) + } + crtbToUpdate.Labels[rtbCrbRbLabelsUpdated] = "true" + _, err := c.crtbClient.Update(crtbToUpdate) + return err + }) + return retryErr +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler_test.go new file mode 100644 index 0000000..f2b6e0b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/crtb_handler_test.go @@ -0,0 +1,159 @@ +package rbac + +import ( + "fmt" + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +var ( + e = fmt.Errorf("error") + defaultCRTB = v3.ClusterRoleTemplateBinding{ + UserName: "crtb-name", + RoleTemplateName: "rt-name", + } + noRoleTemplateCRTB = v3.ClusterRoleTemplateBinding{ + UserName: "crtb-name", + RoleTemplateName: "", + } + noSubjectCRTB = v3.ClusterRoleTemplateBinding{ + UserName: "", + GroupName: "", + GroupPrincipalName: "", + RoleTemplateName: "rt-name", + } +) + +type crtbTestState struct { + managerMock *MockmanagerInterface + rtListerMock *fakes.RoleTemplateListerMock +} + +func TestSyncCRTB(t *testing.T) { + t.Parallel() + tests := []struct { + name string + stateSetup func(crtbTestState) + crtb *v3.ClusterRoleTemplateBinding + wantError bool + }{ + { + name: "crtb with no role template", + crtb: noRoleTemplateCRTB.DeepCopy(), + }, + { + name: "crtb with no subject", + crtb: noSubjectCRTB.DeepCopy(), + }, + { + name: "error getting roletemplate", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, e + } + }, + crtb: defaultCRTB.DeepCopy(), + wantError: true, + }, + { + name: "error gathering roles", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, nil + } + cts.managerMock.EXPECT().gatherRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(e) + }, + crtb: defaultCRTB.DeepCopy(), + wantError: true, + }, + { + name: "error ensuring roles", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, nil + } + cts.managerMock.EXPECT().gatherRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureRoles(gomock.Any()).Return(e) + }, + crtb: defaultCRTB.DeepCopy(), + wantError: true, + }, + { + name: "error ensuring cluster bindings", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, nil + } + cts.managerMock.EXPECT().gatherRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureRoles(gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureClusterBindings(gomock.Any(), gomock.Any()).Return(e) + }, + crtb: defaultCRTB.DeepCopy(), + wantError: true, + }, + { + name: "error ensuring service account impersonator", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, nil + } + cts.managerMock.EXPECT().gatherRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureRoles(gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureClusterBindings(gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureServiceAccountImpersonator(gomock.Any()).Return(e) + }, + crtb: defaultCRTB.DeepCopy(), + wantError: true, + }, + { + name: "success", + stateSetup: func(cts crtbTestState) { + cts.rtListerMock.GetFunc = func(namespace, name string) (*v3.RoleTemplate, error) { + return nil, nil + } + cts.managerMock.EXPECT().gatherRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureRoles(gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureClusterBindings(gomock.Any(), gomock.Any()).Return(nil) + cts.managerMock.EXPECT().ensureServiceAccountImpersonator(gomock.Any()).Return(nil) + }, + crtb: defaultCRTB.DeepCopy(), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + crtbLifecycle := crtbLifecycle{} + state := setupCRTBTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + crtbLifecycle.rtLister = state.rtListerMock + crtbLifecycle.m = state.managerMock + + err := crtbLifecycle.syncCRTB(test.crtb) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func setupCRTBTest(t *testing.T) crtbTestState { + ctrl := gomock.NewController(t) + fakeManager := NewMockmanagerInterface(ctrl) + rtListerMock := fakes.RoleTemplateListerMock{} + state := crtbTestState{ + managerMock: fakeManager, + rtListerMock: &rtListerMock, + } + return state +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/globalrolebinding_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/globalrolebinding_handler.go new file mode 100644 index 0000000..de3146c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/globalrolebinding_handler.go @@ -0,0 +1,165 @@ +package rbac + +import ( + "fmt" + + "github.com/rancher/norman/types/slice" + apisv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + v12 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + grbByUserAndRoleIndex = "authz.cluster.cattle.io/grb-by-user-and-role" + grbHandlerName = "grb-cluster-sync" +) + +func RegisterIndexers(scaledContext *config.ScaledContext) error { + informer := scaledContext.Management.GlobalRoleBindings("").Controller().Informer() + indexers := map[string]cache.IndexFunc{ + grbByUserAndRoleIndex: grbByUserAndRole, + grbByRoleIndex: grbByRole, + } + if err := informer.AddIndexers(indexers); err != nil { + return err + } + + // Add cache informer to project role template bindings + prtbInformer := scaledContext.Management.ProjectRoleTemplateBindings("").Controller().Informer() + prtbIndexers := map[string]cache.IndexFunc{ + prtbByProjectIndex: prtbByProjectName, + prtbByProjecSubjectIndex: prtbByProjectAndSubject, + rtbByClusterAndRoleTemplateIndex: rtbByClusterAndRoleTemplateName, + prtbByUIDIndex: prtbByUID, + prtbByNsAndNameIndex: prtbByNsName, + rtbByClusterAndUserIndex: rtbByClusterAndUserNotDeleting, + } + if err := prtbInformer.AddIndexers(prtbIndexers); err != nil { + return err + } + + crtbInformer := scaledContext.Management.ClusterRoleTemplateBindings("").Controller().Informer() + crtbIndexers := map[string]cache.IndexFunc{ + rtbByClusterAndRoleTemplateIndex: rtbByClusterAndRoleTemplateName, + rtbByClusterAndUserIndex: rtbByClusterAndUserNotDeleting, + } + return crtbInformer.AddIndexers(crtbIndexers) +} + +func newGlobalRoleBindingHandler(workload *config.UserContext) v3.GlobalRoleBindingHandlerFunc { + + h := &grbHandler{ + clusterName: workload.ClusterName, + clusterRoleBindings: workload.RBAC.ClusterRoleBindings(""), + crbLister: workload.RBAC.ClusterRoleBindings("").Controller().Lister(), + // The following clients/controllers all point at the management cluster + grLister: workload.Management.Management.GlobalRoles("").Controller().Lister(), + } + + return h.sync +} + +// grbHandler ensures the global admins have full access to every cluster. If a globalRoleBinding is created that uses +// the admin role, then the user in that binding gets a clusterRoleBinding in every user cluster to the cluster-admin role +type grbHandler struct { + clusterName string + clusterRoleBindings rbacv1.ClusterRoleBindingInterface + crbLister rbacv1.ClusterRoleBindingLister + grLister v3.GlobalRoleLister +} + +func (c *grbHandler) sync(key string, obj *apisv3.GlobalRoleBinding) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return obj, nil + } + isAdmin, err := c.isAdminRole(obj.GlobalRoleName) + if err != nil { + return nil, err + } + if !isAdmin { + return obj, nil + } + + logrus.Debugf("%v is an admin role", obj.GlobalRoleName) + + return obj, c.ensureClusterAdminBinding(obj) +} + +// ensureClusterAdminBinding creates a ClusterRoleBinding for GRB subject to +// the Kubernetes "cluster-admin" ClusterRole in the downstream cluster. +func (c *grbHandler) ensureClusterAdminBinding(obj *apisv3.GlobalRoleBinding) error { + bindingName := rbac.GrbCRBName(obj) + _, err := c.crbLister.Get("", bindingName) + if err != nil && !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to get ClusterRoleBinding '%s' from the cache: %w", bindingName, err) + } + + if err == nil { + // binding exists, nothing to do + return nil + } + + _, err = c.clusterRoleBindings.Create(&v12.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingName, + }, + Subjects: []v12.Subject{rbac.GetGRBSubject(obj)}, + RoleRef: v12.RoleRef{ + Name: "cluster-admin", + Kind: "ClusterRole", + }, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("failed to create ClusterRoleBinding '%s' for admin in downstream '%s': %w", bindingName, c.clusterName, err) + } + return nil +} + +// isAdminRole detects whether a GlobalRole has admin permissions or not. +func (c *grbHandler) isAdminRole(rtName string) (bool, error) { + gr, err := c.grLister.Get("", rtName) + if err != nil { + return false, err + } + + // global role is builtin admin role + if gr.Builtin && gr.Name == rbac.GlobalAdmin { + return true, nil + } + + var hasResourceRule, hasNonResourceRule bool + for _, rule := range gr.Rules { + if slice.ContainsString(rule.Resources, "*") && slice.ContainsString(rule.APIGroups, "*") && slice.ContainsString(rule.Verbs, "*") { + hasResourceRule = true + continue + } + if slice.ContainsString(rule.NonResourceURLs, "*") && slice.ContainsString(rule.Verbs, "*") { + hasNonResourceRule = true + continue + } + } + + // global role has an admin resource rule, and admin nonResourceURLs rule + if hasResourceRule && hasNonResourceRule { + return true, nil + } + + return false, nil +} + +func grbByUserAndRole(obj interface{}) ([]string, error) { + grb, ok := obj.(*apisv3.GlobalRoleBinding) + if !ok { + return []string{}, nil + } + + return []string{rbac.GetGRBTargetKey(grb) + "-" + grb.GlobalRoleName}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base.go new file mode 100644 index 0000000..ce25417 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base.go @@ -0,0 +1,575 @@ +package rbac + +import ( + "context" + "fmt" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/types/convert" + wranglerv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/managementuser/resourcequota" + typescorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + nsutils "github.com/rancher/rancher/pkg/namespace" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + rtbOwnerLabel = "authz.cluster.cattle.io/rtb-owner-updated" + rtbOwnerLabelLegacy = "authz.cluster.cattle.io/rtb-owner" + clusterRoleOwner = "authz.cluster.cattle.io/clusterrole-owner" + projectIDAnnotation = "field.cattle.io/projectId" + prtbByProjectIndex = "authz.cluster.cattle.io/prtb-by-project" + prtbByProjecSubjectIndex = "authz.cluster.cattle.io/prtb-by-project-subject" + prtbByUIDIndex = "authz.cluster.cattle.io/rtb-owner" + prtbByNsAndNameIndex = "authz.cluster.cattle.io/rtb-owner-updated" + rtbByClusterAndRoleTemplateIndex = "authz.cluster.cattle.io/rtb-by-cluster-rt" + rtbByClusterAndUserIndex = "authz.cluster.cattle.io/rtb-by-cluster-user" + nsByProjectIndex = "authz.cluster.cattle.io/ns-by-project" + crByNSIndex = "authz.cluster.cattle.io/cr-by-ns" + crbByRoleAndSubjectIndex = "authz.cluster.cattle.io/crb-by-role-and-subject" + rtbLabelUpdated = "authz.cluster.cattle.io/rtb-label-updated" + rtbCrbRbLabelsUpdated = "authz.cluster.cattle.io/crb-rb-labels-updated" + rtByInheritedRTsIndex = "authz.cluster.cattle.io/rts-by-inherited-rts" + impersonationLabel = "authz.cluster.cattle.io/impersonator" + + rolesCircularSoftLimit = 100 + rolesCircularHardLimit = 500 +) + +func Register(ctx context.Context, workload *config.UserContext) { + management := workload.Management.WithAgent("rbac-handler-base") + + // Add cache informer to project role template bindings + prtbInformer := workload.Management.Management.ProjectRoleTemplateBindings("").Controller().Informer() + crtbInformer := workload.Management.Management.ClusterRoleTemplateBindings("").Controller().Informer() + + // Index for looking up namespaces by projectID annotation + nsInformer := workload.Core.Namespaces("").Controller().Informer() + nsIndexers := map[string]cache.IndexFunc{ + nsByProjectIndex: nsutils.NsByProjectID, + } + nsInformer.AddIndexers(nsIndexers) + + // Get ClusterRoles by the namespaces the authorizes because they are in a project + crInformer := workload.RBAC.ClusterRoles("").Controller().Informer() + crIndexers := map[string]cache.IndexFunc{ + crByNSIndex: crByNS, + } + crInformer.AddIndexers(crIndexers) + + // Get ClusterRoleBindings by subject name and kind + crbInformer := workload.RBAC.ClusterRoleBindings("").Controller().Informer() + crbIndexers := map[string]cache.IndexFunc{ + crbByRoleAndSubjectIndex: crbByRoleAndSubject, + } + crbInformer.AddIndexers(crbIndexers) + + // Get RoleTemplates by RoleTemplate they inherit from + rtInformer := workload.Management.Wrangler.Mgmt.RoleTemplate().Informer() + rtIndexers := map[string]cache.IndexFunc{ + rtByInheritedRTsIndex: rtByInterhitedRTs, + } + rtInformer.AddIndexers(rtIndexers) + + r := &manager{ + workload: workload, + prtbIndexer: prtbInformer.GetIndexer(), + crtbIndexer: crtbInformer.GetIndexer(), + nsIndexer: nsInformer.GetIndexer(), + crIndexer: crInformer.GetIndexer(), + crbIndexer: crbInformer.GetIndexer(), + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + rbLister: workload.RBAC.RoleBindings("").Controller().Lister(), + crbLister: workload.RBAC.ClusterRoleBindings("").Controller().Lister(), + crLister: workload.RBAC.ClusterRoles("").Controller().Lister(), + clusterRoles: workload.RBAC.ClusterRoles(""), + clusterRoleBindings: workload.RBAC.ClusterRoleBindings(""), + nsLister: workload.Core.Namespaces("").Controller().Lister(), + nsController: workload.Core.Namespaces("").Controller(), + clusterLister: management.Management.Clusters("").Controller().Lister(), + projectLister: management.Management.Projects(workload.ClusterName).Controller().Lister(), + userLister: management.Management.Users("").Controller().Lister(), + userAttributeLister: management.Management.UserAttributes("").Controller().Lister(), + clusterName: workload.ClusterName, + } + management.Management.Projects(workload.ClusterName).AddClusterScopedLifecycle(ctx, "project-namespace-auth", workload.ClusterName, newProjectLifecycle(r)) + management.Management.ProjectRoleTemplateBindings("").AddClusterScopedLifecycle(ctx, "cluster-prtb-sync", workload.ClusterName, newPRTBLifecycle(r, management, nsInformer)) + workload.RBAC.ClusterRoles("").AddHandler(ctx, "cluster-clusterrole-sync", newClusterRoleHandler(r).sync) + workload.RBAC.ClusterRoleBindings("").AddHandler(ctx, "legacy-crb-cleaner-sync", newLegacyCRBCleaner(r).sync) + management.Management.ClusterRoleTemplateBindings("").AddClusterScopedLifecycle(ctx, "cluster-crtb-sync", workload.ClusterName, newCRTBLifecycle(r, management)) + management.Management.Clusters("").AddHandler(ctx, "global-admin-cluster-sync", newClusterHandler(workload)) + management.Management.GlobalRoleBindings("").AddHandler(ctx, grbHandlerName, newGlobalRoleBindingHandler(workload)) + + sync := &resourcequota.SyncController{ + Namespaces: workload.Core.Namespaces(""), + NsIndexer: nsInformer.GetIndexer(), + ResourceQuotas: workload.Core.ResourceQuotas(""), + ResourceQuotaLister: workload.Core.ResourceQuotas("").Controller().Lister(), + LimitRange: workload.Core.LimitRanges(""), + LimitRangeLister: workload.Core.LimitRanges("").Controller().Lister(), + ProjectLister: management.Management.Projects(workload.ClusterName).Controller().Lister(), + } + + workload.Core.Namespaces("").AddLifecycle(ctx, "namespace-auth", newNamespaceLifecycle(r, sync)) + management.Management.RoleTemplates("").AddHandler(ctx, "cluster-roletemplate-sync", newRTLifecycle(r)) + relatedresource.WatchClusterScoped(ctx, "enqueue-beneficiary-roletemplates", newRTEnqueueFunc(rtInformer.GetIndexer()), + management.Wrangler.Mgmt.RoleTemplate(), management.Wrangler.Mgmt.RoleTemplate()) +} + +type managerInterface interface { + gatherRoles(*v3.RoleTemplate, map[string]*v3.RoleTemplate, int) error + ensureRoles(map[string]*v3.RoleTemplate) error + ensureClusterBindings(map[string]*v3.RoleTemplate, *v3.ClusterRoleTemplateBinding) error + ensureProjectRoleBindings(string, map[string]*v3.RoleTemplate, *v3.ProjectRoleTemplateBinding) error + ensureServiceAccountImpersonator(string) error + deleteServiceAccountImpersonator(string) error + ensureGlobalResourcesRolesForPRTB(string, map[string]*v3.RoleTemplate) ([]string, error) + reconcileProjectAccessToGlobalResources(*v3.ProjectRoleTemplateBinding, []string) (map[string]bool, error) + noRemainingOwnerLabels(*rbacv1.ClusterRoleBinding) (bool, error) +} + +type manager struct { + workload *config.UserContext + rtLister v3.RoleTemplateLister + prtbIndexer cache.Indexer + crtbIndexer cache.Indexer + nsIndexer cache.Indexer + crIndexer cache.Indexer + crbIndexer cache.Indexer + crLister typesrbacv1.ClusterRoleLister + clusterRoles typesrbacv1.ClusterRoleInterface + crbLister typesrbacv1.ClusterRoleBindingLister + clusterRoleBindings typesrbacv1.ClusterRoleBindingInterface + rbLister typesrbacv1.RoleBindingLister + nsLister typescorev1.NamespaceLister + nsController typescorev1.NamespaceController + clusterLister v3.ClusterLister + projectLister v3.ProjectLister + userLister v3.UserLister + userAttributeLister v3.UserAttributeLister + clusterName string +} + +func (m *manager) ensureRoles(rts map[string]*v3.RoleTemplate) error { + for _, rt := range rts { + if rt.External { + continue + } + if err := m.ensureClusterRoles(rt); err != nil { + return err + } + } + return nil +} + +func (m *manager) ensureClusterRoles(rt *v3.RoleTemplate) error { + if clusterRole, err := m.crLister.Get("", rt.Name); err == nil && clusterRole != nil { + err := m.compareAndUpdateClusterRole(clusterRole, rt) + if err == nil { + return nil + } + if apierrors.IsConflict(err) { + // get object from etcd and retry + clusterRole, err := m.clusterRoles.Get(rt.Name, metav1.GetOptions{}) + if err != nil { + return errors.Wrapf(err, "error getting clusterRole %v", rt.Name) + } + return m.compareAndUpdateClusterRole(clusterRole, rt) + } + return errors.Wrapf(err, "couldn't update clusterRole %v", rt.Name) + } + + return m.createClusterRole(rt) +} + +func (m *manager) compareAndUpdateClusterRole(clusterRole *rbacv1.ClusterRole, rt *v3.RoleTemplate) error { + if equality.Semantic.DeepEqual(clusterRole.Rules, rt.Rules) { + return nil + } + clusterRole = clusterRole.DeepCopy() + clusterRole.Rules = rt.Rules + logrus.Infof("Updating clusterRole %v because of rules difference with roleTemplate %v (%v).", clusterRole.Name, rt.DisplayName, rt.Name) + _, err := m.clusterRoles.Update(clusterRole) + if err != nil { + return errors.Wrapf(err, "couldn't update clusterRole %v", rt.Name) + } + return nil +} + +func (m *manager) createClusterRole(rt *v3.RoleTemplate) error { + logrus.Infof("Creating clusterRole for roleTemplate %v (%v).", rt.DisplayName, rt.Name) + _, err := m.clusterRoles.Create(&rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: rt.Name, + Annotations: map[string]string{clusterRoleOwner: rt.Name}, + }, + Rules: rt.Rules, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return errors.Wrapf(err, "couldn't create clusterRole %v", rt.Name) + } + return nil +} + +func ToLowerRoleTemplates(roleTemplates map[string]*v3.RoleTemplate) { + // clean the roles for kubeneretes: lowercase resources and verbs + for key, rt := range roleTemplates { + if rt.External { + continue + } + rt = rt.DeepCopy() + + var toLowerRules []rbacv1.PolicyRule + for _, r := range rt.Rules { + rule := r.DeepCopy() + + var resources []string + for _, re := range r.Resources { + resources = append(resources, strings.ToLower(re)) + } + rule.Resources = resources + + var verbs []string + for _, v := range r.Verbs { + verbs = append(verbs, strings.ToLower(v)) + } + rule.Verbs = verbs + toLowerRules = append(toLowerRules, *rule) + } + rt.Rules = toLowerRules + roleTemplates[key] = rt + } +} + +func (m *manager) gatherRoles(rt *v3.RoleTemplate, roleTemplates map[string]*v3.RoleTemplate, depthCounter int) error { + if depthCounter == rolesCircularSoftLimit { + logrus.Warnf("roletemplate has caused %v recursive function calls", rolesCircularSoftLimit) + } + if depthCounter >= rolesCircularHardLimit { + return fmt.Errorf("roletemplate '%s' has caused %d recursive function calls, possible circular dependency", rt.Name, rolesCircularHardLimit) + } + err := m.gatherRolesRecurse(rt, roleTemplates, depthCounter) + if err != nil { + return err + } + ToLowerRoleTemplates(roleTemplates) + return nil +} + +func (m *manager) gatherRolesRecurse(rt *v3.RoleTemplate, roleTemplates map[string]*v3.RoleTemplate, depthCounter int) error { + roleTemplates[rt.Name] = rt + depthCounter++ + + for _, rtName := range rt.RoleTemplateNames { + subRT, err := m.rtLister.Get("", rtName) + if err != nil { + return errors.Wrapf(err, "couldn't get RoleTemplate %s", rtName) + } + if err := m.gatherRoles(subRT, roleTemplates, depthCounter); err != nil { + return err + } + } + + return nil +} + +func (m *manager) ensureClusterBindings(roles map[string]*v3.RoleTemplate, binding *v3.ClusterRoleTemplateBinding) error { + create := func(objectMeta metav1.ObjectMeta, subjects []rbacv1.Subject, roleRef rbacv1.RoleRef) runtime.Object { + return &rbacv1.ClusterRoleBinding{ + ObjectMeta: objectMeta, + Subjects: subjects, + RoleRef: roleRef, + } + } + + list := func(ns string, selector labels.Selector) ([]interface{}, error) { + currentRBs, err := m.crbLister.List(ns, selector) + if err != nil { + return nil, err + } + var items []interface{} + for _, c := range currentRBs { + items = append(items, c) + } + return items, nil + } + + convert := func(i interface{}) (string, string, []rbacv1.Subject) { + crb, _ := i.(*rbacv1.ClusterRoleBinding) + return crb.Name, crb.RoleRef.Name, crb.Subjects + } + + return m.ensureBindings("", roles, binding, m.workload.RBAC.ClusterRoleBindings("").ObjectClient(), create, list, convert) +} + +func (m *manager) ensureProjectRoleBindings(ns string, roles map[string]*v3.RoleTemplate, binding *v3.ProjectRoleTemplateBinding) error { + create := func(objectMeta metav1.ObjectMeta, subjects []rbacv1.Subject, roleRef rbacv1.RoleRef) runtime.Object { + return &rbacv1.RoleBinding{ + ObjectMeta: objectMeta, + Subjects: subjects, + RoleRef: roleRef, + } + } + + list := func(ns string, selector labels.Selector) ([]interface{}, error) { + currentRBs, err := m.rbLister.List(ns, selector) + if err != nil { + return nil, err + } + var items []interface{} + for _, c := range currentRBs { + items = append(items, c) + } + return items, nil + } + + convert := func(i interface{}) (string, string, []rbacv1.Subject) { + rb, _ := i.(*rbacv1.RoleBinding) + return rb.Name, rb.RoleRef.Name, rb.Subjects + } + + return m.ensureBindings(ns, roles, binding, m.workload.RBAC.RoleBindings(ns).ObjectClient(), create, list, convert) +} + +type createFn func(objectMeta metav1.ObjectMeta, subjects []rbacv1.Subject, roleRef rbacv1.RoleRef) runtime.Object +type listFn func(ns string, selector labels.Selector) ([]interface{}, error) +type convertFn func(i interface{}) (string, string, []rbacv1.Subject) + +func (m *manager) ensureBindings(ns string, roles map[string]*v3.RoleTemplate, binding metav1.Object, client *objectclient.ObjectClient, + create createFn, list listFn, convert convertFn) error { + objMeta := meta.AsPartialObjectMetadata(binding).ObjectMeta + + desiredRBs := map[string]runtime.Object{} + subject, err := pkgrbac.BuildSubjectFromRTB(binding) + if err != nil { + return err + } + for roleName := range roles { + rbKey, objectMeta, subjects, roleRef := bindingParts(ns, roleName, objMeta, subject) + desiredRBs[rbKey] = create(objectMeta, subjects, roleRef) + } + + set := labels.Set(map[string]string{rtbOwnerLabel: pkgrbac.GetRTBLabel(objMeta)}) + currentRBs, err := list(ns, set.AsSelector()) + if err != nil { + return err + } + rbsToDelete := map[string]bool{} + processed := map[string]bool{} + for _, rb := range currentRBs { + rbName, roleName, subjects := convert(rb) + // protect against an rb being in the list more than once (shouldn't happen, but just to be safe) + if ok := processed[rbName]; ok { + continue + } + processed[rbName] = true + + if len(subjects) != 1 { + rbsToDelete[rbName] = true + continue + } + + crbKey := rbRoleSubjectKey(roleName, subjects[0]) + if _, ok := desiredRBs[crbKey]; ok { + delete(desiredRBs, crbKey) + } else { + rbsToDelete[rbName] = true + } + } + + for key, rb := range desiredRBs { + switch roleBinding := rb.(type) { + case *rbacv1.RoleBinding: + _, err := m.workload.RBAC.RoleBindings("").Controller().Lister().Get(ns, roleBinding.Name) + if apierrors.IsNotFound(err) { + logrus.Infof("Creating roleBinding %v in %s", key, ns) + _, err := m.workload.RBAC.RoleBindings(ns).Create(roleBinding) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } else if err != nil { + return err + } + case *rbacv1.ClusterRoleBinding: + logrus.Infof("Creating clusterRoleBinding %v", key) + _, err := m.workload.RBAC.ClusterRoleBindings("").Create(roleBinding) + if err != nil && !apierrors.IsAlreadyExists(err) { + return err + } + } + } + + for name := range rbsToDelete { + logrus.Infof("Deleting roleBinding %v", name) + if err := client.Delete(name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return err + } + } + return nil +} + +func bindingParts(namespace, roleName string, objMeta metav1.ObjectMeta, subject rbacv1.Subject) (string, metav1.ObjectMeta, []rbacv1.Subject, rbacv1.RoleRef) { + key := rbRoleSubjectKey(roleName, subject) + + roleRef := rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: roleName, + } + + var name string + if namespace == "" { // if namespace is empty, binding will be ClusterRoleBinding, so name accordingly + name = pkgrbac.NameForClusterRoleBinding(roleRef, subject) + } else { + name = pkgrbac.NameForRoleBinding(namespace, roleRef, subject) + } + + return key, + metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{rtbOwnerLabel: pkgrbac.GetRTBLabel(objMeta)}, + }, + []rbacv1.Subject{subject}, + roleRef +} + +func prtbByProjectName(obj interface{}) ([]string, error) { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{prtb.ProjectName}, nil +} + +func getPRTBProjectAndSubjectKey(prtb *v3.ProjectRoleTemplateBinding) string { + var name string + if prtb.UserName != "" { + name = prtb.UserName + } else if prtb.UserPrincipalName != "" { + name = prtb.UserPrincipalName + } else if prtb.GroupName != "" { + name = prtb.GroupName + } else if prtb.GroupPrincipalName != "" { + name = prtb.GroupPrincipalName + } else if prtb.ServiceAccount != "" { + name = prtb.ServiceAccount + } + return prtb.ProjectName + "." + name +} + +func prtbByProjectAndSubject(obj interface{}) ([]string, error) { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{getPRTBProjectAndSubjectKey(prtb)}, nil +} + +func prtbByUID(obj interface{}) ([]string, error) { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{convert.ToString(prtb.UID)}, nil +} + +func prtbByNsName(obj interface{}) ([]string, error) { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + return []string{}, nil + } + return []string{pkgrbac.GetRTBLabel(prtb.ObjectMeta)}, nil +} + +func crbRoleSubjectKeys(roleName string, subjects []rbacv1.Subject) []string { + var keys []string + for _, s := range subjects { + keys = append(keys, rbRoleSubjectKey(roleName, s)) + } + return keys +} + +func rbRoleSubjectKey(roleName string, subject rbacv1.Subject) string { + return subject.Kind + " " + subject.Name + " Role " + roleName +} + +func crbByRoleAndSubject(obj interface{}) ([]string, error) { + crb, ok := obj.(*rbacv1.ClusterRoleBinding) + if !ok { + return []string{}, nil + } + return crbRoleSubjectKeys(crb.RoleRef.Name, crb.Subjects), nil +} + +func rtbByClusterAndRoleTemplateName(obj interface{}) ([]string, error) { + var idx string + switch rtb := obj.(type) { + case *v3.ProjectRoleTemplateBinding: + if rtb.RoleTemplateName != "" && rtb.ProjectName != "" { + parts := strings.SplitN(rtb.ProjectName, ":", 2) + if len(parts) == 2 { + idx = parts[0] + "-" + rtb.RoleTemplateName + } + } + case *v3.ClusterRoleTemplateBinding: + if rtb.RoleTemplateName != "" && rtb.ClusterName != "" { + idx = rtb.ClusterName + "-" + rtb.RoleTemplateName + } + } + + if idx == "" { + return []string{}, nil + } + return []string{idx}, nil +} + +func rtByInterhitedRTs(obj interface{}) ([]string, error) { + rt, ok := obj.(*wranglerv3.RoleTemplate) + if !ok { + return nil, fmt.Errorf("failed to convert object to *RoleTemplate in indexer [%s]", rtByInheritedRTsIndex) + } + return rt.RoleTemplateNames, nil +} + +func rtbByClusterAndUserNotDeleting(obj interface{}) ([]string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return []string{}, err + } + if meta.GetDeletionTimestamp() != nil { + return []string{}, nil + } + var idx string + switch rtb := obj.(type) { + case *v3.ProjectRoleTemplateBinding: + if rtb.UserName != "" && rtb.ProjectName != "" { + parts := strings.SplitN(rtb.ProjectName, ":", 2) + if len(parts) == 2 { + idx = parts[0] + "-" + rtb.UserName + } + } + case *v3.ClusterRoleTemplateBinding: + if rtb.UserName != "" && rtb.ClusterName != "" { + idx = rtb.ClusterName + "-" + rtb.UserName + } + } + + if idx == "" { + return []string{}, nil + } + return []string{idx}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base_test.go new file mode 100644 index 0000000..30f0e7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/handler_base_test.go @@ -0,0 +1,347 @@ +package rbac + +import ( + "fmt" + "sync" + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + fakes2 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +var ( + recursiveTestRoleTemplates = map[string]*v3.RoleTemplate{ + "recursive1": { + RoleTemplateNames: []string{"recursive2"}, + }, + "recursive2": { + RoleTemplateNames: []string{"recursive1"}, + }, + "non-recursive": {}, + "inherit non-recursive": { + RoleTemplateNames: []string{"non-recursive"}, + }, + } + createNSRoleTemplate = &v3.RoleTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "create-ns", + }, + Builtin: true, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + Verbs: []string{"create"}, + }, + }, + } +) + +type clientErrs struct { + getError error + listError error + updateError error + createError error +} + +type managerOpt func(m *manager) + +func newManager(opts ...managerOpt) *manager { + manager := &manager{ + clusterName: "testcluster", + rtLister: &fakes.RoleTemplateListerMock{}, + crLister: &fakes2.ClusterRoleListerMock{}, + } + + for _, opt := range opts { + opt(manager) + } + + return manager +} + +// withRoleTemplates setup a rtLister mock with the provided roleTemplates and errors +func withRoleTemplates(roleTemplates map[string]*v3.RoleTemplate, errs *clientErrs) managerOpt { + if roleTemplates == nil { + roleTemplates = map[string]*v3.RoleTemplate{} + } + + if errs == nil { + errs = &clientErrs{} + } + + syncRoleTemplates := &sync.Map{} + for k, v := range roleTemplates { + syncRoleTemplates.Store(k, v) + } + + return func(m *manager) { + m.rtLister = &fakes.RoleTemplateListerMock{ + ListFunc: newListFunc[*v3.RoleTemplate](syncRoleTemplates, errs.listError), + GetFunc: func(namespace string, name string) (*v3.RoleTemplate, error) { + if errs.getError != nil { + return nil, errs.getError + } + + rtVal, ok := syncRoleTemplates.Load(name) + if !ok { + return nil, errors.NewNotFound(v3.RoleTemplateGroupVersionResource.GroupResource(), name) + } + + rt := rtVal.(*v3.RoleTemplate) + return rt.DeepCopy(), nil + }, + } + } +} + +// withRoleTemplates setup a crLister and clusterRoles mock with the provided clusterRoles and errors +func withClusterRoles(clusterRoles map[string]*v1.ClusterRole, errs *clientErrs) managerOpt { + if clusterRoles == nil { + clusterRoles = map[string]*v1.ClusterRole{} + } + + if errs == nil { + errs = &clientErrs{} + } + + syncClusterRoles := &sync.Map{} + for k, v := range clusterRoles { + syncClusterRoles.Store(k, v) + } + + return func(m *manager) { + m.crLister = &fakes2.ClusterRoleListerMock{ + ListFunc: newListFunc[*v1.ClusterRole](syncClusterRoles, errs.listError), + GetFunc: func(namespace string, name string) (*v1.ClusterRole, error) { + if errs.getError != nil { + return nil, errs.getError + } + + crVal, ok := syncClusterRoles.Load(name) + if !ok { + return nil, errors.NewNotFound(v3.RoleTemplateGroupVersionResource.GroupResource(), name) + } + + cr := crVal.(*v1.ClusterRole) + return cr.DeepCopy(), nil + }, + } + + m.clusterRoles = &fakes2.ClusterRoleInterfaceMock{ + GetFunc: func(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { + if errs.getError != nil { + return nil, errs.getError + } + + crVal, ok := syncClusterRoles.Load(name) + if !ok { + return nil, errors.NewNotFound(v3.RoleTemplateGroupVersionResource.GroupResource(), name) + } + + cr := crVal.(*v1.ClusterRole) + return cr.DeepCopy(), nil + }, + UpdateFunc: func(cr *v1.ClusterRole) (*v1.ClusterRole, error) { + if errs.updateError != nil { + return nil, errs.updateError + } + + _, ok := syncClusterRoles.Load(cr.Name) + if !ok { + return nil, errors.NewNotFound(v3.RoleTemplateGroupVersionResource.GroupResource(), cr.Name) + } + + syncClusterRoles.Store(cr.Name, cr) + return cr.DeepCopy(), nil + }, + CreateFunc: func(cr *v1.ClusterRole) (*v1.ClusterRole, error) { + if errs.createError != nil { + return nil, errs.createError + } + + _, ok := syncClusterRoles.Load(cr.Name) + if ok { + return nil, errors.NewAlreadyExists(v3.RoleTemplateGroupVersionResource.GroupResource(), cr.Name) + } + + syncClusterRoles.Store(cr.Name, cr) + return cr.DeepCopy(), nil + }, + } + } +} + +func newListFunc[T any](resourceMap *sync.Map, err error) func(string, labels.Selector) ([]T, error) { + return func(namespace string, selector labels.Selector) ([]T, error) { + if err != nil { + return nil, err + } + + resourceList := []T{} + resourceMap.Range(func(key, value any) bool { + resourceList = append(resourceList, value.(T)) + return true + }) + + return resourceList, nil + } +} + +func Test_gatherRoles(t *testing.T) { + m := newManager(withRoleTemplates(recursiveTestRoleTemplates, nil)) + + emptyRoleTemplates := make(map[string]*v3.RoleTemplate) + type args struct { + rt *v3.RoleTemplate + roleTemplates map[string]*v3.RoleTemplate + depthCounter int + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Non-recursive role, none inherited", + args: args{ + rt: recursiveTestRoleTemplates["non-recursive"], + roleTemplates: emptyRoleTemplates, + depthCounter: 0, + }, + wantErr: false, + }, + { + name: "Non-recursive role, inherits another", + args: args{ + rt: recursiveTestRoleTemplates["inherit non-recursive"], + roleTemplates: emptyRoleTemplates, + depthCounter: 0, + }, + wantErr: false, + }, + { + name: "Recursive role", + args: args{ + rt: recursiveTestRoleTemplates["recursive1"], + roleTemplates: emptyRoleTemplates, + depthCounter: 0, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := m.gatherRoles(tt.args.rt, tt.args.roleTemplates, tt.args.depthCounter) + if tt.wantErr { + assert.Error(t, err, "expected an error, received none") + } else { + assert.NoError(t, err, fmt.Sprintf("expected no err, got %v", err)) + } + }) + } +} + +func TestCompareAndUpdateClusterRole(t *testing.T) { + t.Parallel() + + tests := map[string]struct { + clusterRole *v1.ClusterRole + roleTemplate *v3.RoleTemplate + wantNumUpdatesCalls int + }{ + "semantic difference": { + clusterRole: &v1.ClusterRole{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + }, + }, + }, + roleTemplate: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + ResourceNames: []string{}, + NonResourceURLs: []string{}, + }, + }, + }, + wantNumUpdatesCalls: 0, + }, + "no difference": { + clusterRole: &v1.ClusterRole{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + }, + }, + }, + roleTemplate: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + }, + }, + }, + wantNumUpdatesCalls: 0, + }, + "difference": { + clusterRole: &v1.ClusterRole{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + }, + }, + }, + roleTemplate: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get", "update"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + }, + }, + }, + wantNumUpdatesCalls: 1, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + numUpdatesCalled := 0 + var updateParamCalled *v1.ClusterRole + clusterRolesMock := &fakes2.ClusterRoleInterfaceMock{ + UpdateFunc: func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { + numUpdatesCalled++ + updateParamCalled = in1 + return &v1.ClusterRole{}, nil + }, + } + m := manager{clusterRoles: clusterRolesMock} + err := m.compareAndUpdateClusterRole(test.clusterRole, test.roleTemplate) + assert.NoError(t, err) + assert.Equal(t, test.wantNumUpdatesCalls, numUpdatesCalled) + if test.wantNumUpdatesCalls > 0 { + assert.Equal(t, test.roleTemplate.Rules, updateParamCalled.Rules) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/impersonation_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/impersonation_handler.go new file mode 100644 index 0000000..a25297d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/impersonation_handler.go @@ -0,0 +1,44 @@ +package rbac + +import ( + "github.com/rancher/rancher/pkg/impersonation" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" +) + +func (m *manager) ensureServiceAccountImpersonator(username string) error { + logrus.Debugf("ensuring service account impersonator for %s", username) + i, err := impersonation.New(&user.DefaultInfo{UID: username}, m.workload) + if apierrors.IsNotFound(err) { + logrus.Warnf("could not find user %s, will not create impersonation account on cluster", username) + return nil + } + if err != nil { + return err + } + _, err = i.SetUpImpersonation() + return err +} + +func (m *manager) deleteServiceAccountImpersonator(username string) error { + crtbs, err := m.crtbIndexer.ByIndex(rtbByClusterAndUserIndex, m.workload.ClusterName+"-"+username) + if err != nil { + return err + } + prtbs, err := m.prtbIndexer.ByIndex(rtbByClusterAndUserIndex, m.workload.ClusterName+"-"+username) + if err != nil { + return err + } + if len(crtbs)+len(prtbs) > 0 { + return nil + } + roleName := impersonation.ImpersonationPrefix + username + logrus.Debugf("deleting service account impersonator for %s", username) + err = m.workload.RBAC.ClusterRoles("").Delete(roleName, &metav1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + return nil + } + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/legacy_prtb_cleaner.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/legacy_prtb_cleaner.go new file mode 100644 index 0000000..ac06c78 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/legacy_prtb_cleaner.go @@ -0,0 +1,74 @@ +package rbac + +import ( + "regexp" + + "k8s.io/apimachinery/pkg/runtime" + + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var crbNamePattern = regexp.MustCompile("clusterrolebinding-.+") +var namespaceRoleRefPattern = regexp.MustCompile(".+-namespaces-.+") +var promotedRoleRefPattern = regexp.MustCompile(".+-promoted") + +const createNSRoleRef = "create-ns" + +func newLegacyCRBCleaner(m *manager) *crbCleaner { + return &crbCleaner{ + m: m, + } +} + +type crbCleaner struct { + m *manager +} + +func (p *crbCleaner) sync(key string, obj *rbacv1.ClusterRoleBinding) (runtime.Object, error) { + if key == "" || obj == nil { + return nil, nil + } + + eligible, err := p.eligibleForDeletion(obj) + if err != nil { + return nil, err + } + + if eligible { + if err := p.m.workload.RBAC.ClusterRoleBindings("").Delete(obj.Name, &metav1.DeleteOptions{}); err != nil { + if !errors.IsNotFound(err) { + return nil, err + } + } + } + + return obj, nil +} + +func (p *crbCleaner) eligibleForDeletion(crb *rbacv1.ClusterRoleBinding) (bool, error) { + if !crbNamePattern.MatchString(crb.Name) { + return false, nil + } + + if noOwners, err := p.m.noRemainingOwnerLabels(crb); !noOwners || err != nil { + return false, err + } + + roleRefName := crb.RoleRef.Name + + if roleRefName == createNSRoleRef { + return true, nil + } + + if namespaceRoleRefPattern.MatchString(roleRefName) { + return true, nil + } + + if promotedRoleRefPattern.MatchString(roleRefName) { + return true, nil + } + + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler.go new file mode 100644 index 0000000..fc15fe4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler.go @@ -0,0 +1,569 @@ +package rbac + +import ( + "fmt" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/apis/management.cattle.io" + apisV3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/managementuser/resourcequota" + fleetconst "github.com/rancher/rancher/pkg/fleet" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + namespaceutil "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/project" + projectpkg "github.com/rancher/rancher/pkg/project" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + projectNSGetClusterRoleNameFmt = "%v-namespaces-%v" + projectNSAnn = "authz.cluster.auth.io/project-namespaces" + initialRoleCondition = "InitialRolesPopulated" + manageNSVerb = "manage-namespaces" + projectNSEditVerb = "*" +) + +var projectNSVerbToSuffix = map[string]string{ + "get": "readonly", + projectNSEditVerb: "edit", +} +var defaultProjectLabels = labels.Set(map[string]string{"authz.management.cattle.io/default-project": "true"}) +var systemProjectLabels = labels.Set(map[string]string{"authz.management.cattle.io/system-project": "true"}) +var initialProjectToLabels = map[string]labels.Set{ + project.Default: defaultProjectLabels, + project.System: systemProjectLabels, +} + +func newNamespaceLifecycle(m *manager, sync *resourcequota.SyncController) *nsLifecycle { + return &nsLifecycle{m: m, rq: sync} +} + +type nsLifecycle struct { + m *manager + rq *resourcequota.SyncController +} + +func (n *nsLifecycle) Create(obj *v1.Namespace) (runtime.Object, error) { + obj, err := n.resourceQuotaInit(obj) + if err != nil { + return obj, err + } + + hasPRTBs, err := n.syncNS(obj) + if err != nil { + return obj, err + } + + if err := n.assignToInitialProject(obj); err != nil { + return obj, err + } + + go updateStatusAnnotation(hasPRTBs, obj.DeepCopy(), n.m) + + return obj, err +} + +func (n *nsLifecycle) resourceQuotaInit(obj *v1.Namespace) (*v1.Namespace, error) { + ns, err := n.rq.CreateResourceQuota(obj) + if ns, ok := ns.(*v1.Namespace); ok { + return ns, err + } + return nil, err +} + +func (n *nsLifecycle) Updated(obj *v1.Namespace) (runtime.Object, error) { + _, err := n.syncNS(obj) + return obj, err +} + +func (n *nsLifecycle) Remove(obj *v1.Namespace) (runtime.Object, error) { + err := n.reconcileNamespaceProjectClusterRole(obj) + return obj, err +} + +func (n *nsLifecycle) syncNS(obj *v1.Namespace) (bool, error) { + // add fleet namespace to system project + if IsFleetNamespace(obj) && + // If this is the local cluster, then only move the namespace to ths system project if the projectIDAnnotation is + // empty or beings with "local" (i.e. not c-). If the projectIDAnnotation begins with something other than "local" + // then it is likely that local cluster is the tenant cluster in a hosted Rancher setup and the namespace belongs to + // the system project for the cluster in the host cluster. Moving it here would only cause the namespace to be + // continually moved between projects forever. + (n.m.clusterName != "local" || obj.Annotations[projectIDAnnotation] == "" || strings.HasPrefix(obj.Annotations[projectIDAnnotation], "local")) { + + systemProjectName, err := n.GetSystemProjectName() + if err != nil { + return false, errors.Wrapf(err, "failed to add namespace %s to system project", obj.Name) + } + + // When there is no system project, we should not set this annotation as a result because the project name + // is empty. If the annotation already exists, and there is no system project, then we need to delete the + // annotation. + if systemProjectName != "" { + obj.Annotations[projectIDAnnotation] = fmt.Sprintf("%v:%v", n.m.clusterName, systemProjectName) + } else { + delete(obj.Annotations, projectIDAnnotation) + } + } + + hasPRTBs, err := n.ensurePRTBAddToNamespace(obj) + if err != nil { + return false, err + } + + if err := n.reconcileNamespaceProjectClusterRole(obj); err != nil { + return false, err + } + + return hasPRTBs, nil +} + +func (n *nsLifecycle) assignToInitialProject(ns *v1.Namespace) error { + initialProjectsToNamespaces, err := getDefaultAndSystemProjectsToNamespaces() + if err != nil { + return err + } + for projectName, namespaces := range initialProjectsToNamespaces { + for _, nsToCheck := range namespaces { + if nsToCheck == ns.Name { + projectID := ns.Annotations[projectIDAnnotation] + if projectID != "" { + return nil + } + projects, err := n.m.projectLister.List(n.m.clusterName, initialProjectToLabels[projectName].AsSelector()) + if err != nil { + return err + } + if len(projects) == 0 { + continue + } + if len(projects) > 1 { + return fmt.Errorf("cluster [%s] contains more than 1 [%s] project", n.m.clusterName, projectName) + } + if projects[0] == nil { + continue + } + if ns.Annotations == nil { + ns.Annotations = map[string]string{} + } + ns.Annotations[projectIDAnnotation] = fmt.Sprintf("%v:%v", n.m.clusterName, projects[0].Name) + } + } + } + + return nil +} + +func (n *nsLifecycle) GetSystemProjectName() (string, error) { + projects, err := n.m.projectLister.List(n.m.clusterName, initialProjectToLabels[projectpkg.System].AsSelector()) + if err != nil { + return "", err + } + if len(projects) == 0 { + return "", nil + } + if len(projects) > 1 { + return "", fmt.Errorf("cluster [%s] contains more than 1 [%s] project", n.m.clusterName, projectpkg.System) + } + if projects[0] == nil { + return "", nil + } + return projects[0].Name, nil +} + +func IsFleetNamespace(ns *v1.Namespace) bool { + return ns.Name == fleetconst.ClustersLocalNamespace || ns.Name == fleetconst.ClustersDefaultNamespace || ns.Name == fleetconst.ReleaseClustersNamespace || ns.Labels["fleet.cattle.io/managed"] == "true" +} + +func (n *nsLifecycle) ensurePRTBAddToNamespace(ns *v1.Namespace) (bool, error) { + // Get project that contain this namespace + projectID := ns.Annotations[projectIDAnnotation] + if len(projectID) == 0 { + // if namespace does not belong to a project, delete all rolebindings from that namespace that were created for a PRTB + // such rolebindings will have the label "authz.cluster.cattle.io/rtb-owner" prior to 2.5 and + // "authz.cluster.cattle.io/rtb-owner-updated" 2.5 onwards + rbs, err := n.m.rbLister.List(ns.Name, labels.Everything()) + if err != nil { + return false, errors.Wrapf(err, "couldn't list role bindings in %s", ns.Name) + } + client := n.m.workload.RBAC.RoleBindings(ns.Name).ObjectClient() + for _, rb := range rbs { + // rtbOwnerLabelLegacy + if uid := convert.ToString(rb.Labels[rtbOwnerLabelLegacy]); uid != "" { + logrus.Infof("Deleting role binding %s in %s", rb.Name, ns.Name) + if err := client.Delete(rb.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return false, errors.Wrapf(err, "couldn't delete role binding %s", rb.Name) + } + } + if nsAndName := convert.ToString(rb.Labels[rtbOwnerLabel]); nsAndName != "" { + logrus.Infof("Deleting role binding %s in %s", rb.Name, ns.Name) + if err := client.Delete(rb.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return false, errors.Wrapf(err, "couldn't delete role binding %s", rb.Name) + } + } + } + return false, nil + } + + prtbs, err := n.m.prtbIndexer.ByIndex(prtbByProjectIndex, projectID) + if err != nil { + return false, errors.Wrapf(err, "couldn't get project role binding templates associated with project id %s", projectID) + } + hasPRTBs := len(prtbs) > 0 + + for _, prtb := range prtbs { + prtb, ok := prtb.(*v3.ProjectRoleTemplateBinding) + if !ok { + return false, errors.Wrapf(err, "object %v is not valid project role template binding", prtb) + } + + if prtb.UserName == "" && prtb.GroupPrincipalName == "" && prtb.GroupName == "" { + continue + } + + if prtb.RoleTemplateName == "" { + logrus.Warnf("ProjectRoleTemplateBinding %v has no role template set. Skipping.", prtb.Name) + continue + } + + rt, err := n.m.rtLister.Get("", prtb.RoleTemplateName) + if err != nil { + return false, errors.Wrapf(err, "couldn't get role template %v", prtb.RoleTemplateName) + } + + roles := map[string]*v3.RoleTemplate{} + if err := n.m.gatherRoles(rt, roles, 0); err != nil { + return false, err + } + + if err := n.m.ensureRoles(roles); err != nil { + return false, errors.Wrap(err, "couldn't ensure roles") + } + + if err := n.m.ensureProjectRoleBindings(ns.Name, roles, prtb); err != nil { + return false, errors.Wrapf(err, "couldn't ensure binding %v in %v", prtb.Name, ns.Name) + } + } + + var namespace string + if parts := strings.SplitN(projectID, ":", 2); len(parts) == 2 && len(parts[1]) > 0 { + namespace = parts[1] + } else { + return hasPRTBs, nil + } + + rbs, err := n.m.rbLister.List(ns.Name, labels.Everything()) + if err != nil { + return false, errors.Wrapf(err, "couldn't list role bindings in %s", ns.Name) + } + client := n.m.workload.RBAC.RoleBindings(ns.Name).ObjectClient() + + for _, rb := range rbs { + if uid := convert.ToString(rb.Labels[rtbOwnerLabelLegacy]); uid != "" { + prtbs, err := n.m.prtbIndexer.ByIndex(prtbByUIDIndex, uid) + if err != nil { + if apierrors.IsNotFound(err) { + continue + } else { + return false, errors.Wrapf(err, "couldn't find prtb for %s", rb.Name) + } + } + for _, prtb := range prtbs { + if prtb, ok := prtb.(*v3.ProjectRoleTemplateBinding); ok { + if prtb.Namespace != namespace { + logrus.Infof("Deleting role binding %s in %s", rb.Name, ns.Name) + if err := client.Delete(rb.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return false, errors.Wrapf(err, "couldn't delete role binding %s", rb.Name) + } + } + } + } + } + + if nsAndName := convert.ToString(rb.Labels[rtbOwnerLabel]); nsAndName != "" { + prtbs, err := n.m.prtbIndexer.ByIndex(prtbByNsAndNameIndex, nsAndName) + if err != nil { + if apierrors.IsNotFound(err) { + continue + } else { + return false, errors.Wrapf(err, "couldn't find prtb for %s", rb.Name) + } + } + for _, prtb := range prtbs { + if prtb, ok := prtb.(*v3.ProjectRoleTemplateBinding); ok { + if prtb.Namespace != namespace { + logrus.Infof("Deleting role binding %s in %s", rb.Name, ns.Name) + if err := client.Delete(rb.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return false, errors.Wrapf(err, "couldn't delete role binding %s", rb.Name) + } + } + } + } + } + } + return hasPRTBs, nil +} + +// To ensure that all users in a project can do a GET on the namespaces in that project, this +// function ensures that a ClusterRole exists for the project that grants get access to the +// namespaces in the project. A corresponding PRTB handler will ensure that a binding to this +// ClusterRole exists for every project member +func (n *nsLifecycle) reconcileNamespaceProjectClusterRole(ns *v1.Namespace) error { + for verb, name := range projectNSVerbToSuffix { + var desiredRole string + var projectName string + if ns.DeletionTimestamp == nil { + if parts := strings.SplitN(ns.Annotations[projectIDAnnotation], ":", 2); len(parts) == 2 && len(parts[1]) > 0 { + projectName = parts[1] + desiredRole = fmt.Sprintf(projectNSGetClusterRoleNameFmt, parts[1], name) + } + } + + clusterRoles, err := n.m.crIndexer.ByIndex(crByNSIndex, ns.Name) + if err != nil { + return err + } + + roleCli := n.m.clusterRoles + nsInDesiredRole := false + for _, c := range clusterRoles { + cr, ok := c.(*rbacv1.ClusterRole) + if !ok { + return errors.Errorf("%v is not a ClusterRole", c) + } + + if cr.Name == desiredRole { + nsInDesiredRole = true + continue + } + + // This ClusterRole has a reference to the namespace, but is not the desired role. Namespace has been moved; remove it from this ClusterRole + undesiredRole := cr.DeepCopy() + modified := false + for i := range undesiredRole.Rules { + r := &undesiredRole.Rules[i] + if slice.ContainsString(r.Verbs, verb) && slice.ContainsString(r.Resources, "namespaces") && slice.ContainsString(r.ResourceNames, ns.Name) { + modified = true + resNames := r.ResourceNames + for i := len(resNames) - 1; i >= 0; i-- { + if resNames[i] == ns.Name { + resNames = append(resNames[:i], resNames[i+1:]...) + } + } + r.ResourceNames = resNames + } + } + //if ResourceNames is empty, delete the rule and delete the role if no rules exist + toDeleteRules := 0 + for _, rule := range undesiredRole.Rules { + if len(rule.ResourceNames) == 0 { + toDeleteRules++ + } + } + if toDeleteRules == len(undesiredRole.Rules) { + logrus.Infof("Deleting ClusterRole %s", undesiredRole.Name) + if err = roleCli.Delete(undesiredRole.Name, &metav1.DeleteOptions{}); err != nil { + return err + } + continue + } else if toDeleteRules != 0 { + var updatedRules []rbacv1.PolicyRule + for _, rule := range undesiredRole.Rules { + if len(rule.ResourceNames) != 0 { + updatedRules = append(updatedRules, rule) + } + } + undesiredRole.Rules = updatedRules + } + if modified { + if _, err = roleCli.Update(undesiredRole); err != nil { + return err + } + } + } + + if !nsInDesiredRole && desiredRole != "" { + mustUpdate := true + cr, err := n.m.crLister.Get("", desiredRole) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + + // Create new role + if cr == nil { + return n.m.createProjectNSRole(desiredRole, verb, ns.Name, projectName) + } + + // Check to see if retrieved role has the namespace (small chance cache could have been updated) + for _, r := range cr.Rules { + if slice.ContainsString(r.Verbs, verb) && slice.ContainsString(r.Resources, "namespaces") && slice.ContainsString(r.ResourceNames, ns.Name) { + // ns already in the role, nothing to do + mustUpdate = false + } + } + if mustUpdate { + cr = cr.DeepCopy() + appendedToExisting := false + for i := range cr.Rules { + r := &cr.Rules[i] + if slice.ContainsString(r.Verbs, verb) && slice.ContainsString(r.Resources, "namespaces") { + r.ResourceNames = append(r.ResourceNames, ns.Name) + appendedToExisting = true + break + } + } + + if !appendedToExisting { + cr.Rules = append(cr.Rules, rbacv1.PolicyRule{ + APIGroups: []string{""}, + Verbs: []string{verb}, + Resources: []string{"namespaces"}, + ResourceNames: []string{ns.Name}, + }) + } + + _, err = roleCli.Update(cr) + return err + } + } + } + + return nil +} + +func (m *manager) createProjectNSRole(roleName, verb, ns, projectName string) error { + roleCli := m.clusterRoles + + cr := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Annotations: map[string]string{projectNSAnn: roleName}, + }, + } + if ns != "" { + cr.Rules = []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Verbs: []string{verb}, + Resources: []string{"namespaces"}, + ResourceNames: []string{ns}, + }, + } + } + // the verbs passed into this function come from projectNSVerbToSuffix which only contains two verbs, one for read + // permissions and one for write. Only the write permission should get the manage-ns verb + if verb == projectNSEditVerb { + cr = addManageNSPermission(cr, projectName) + } + _, err := roleCli.Create(cr) + return err +} + +func addManageNSPermission(clusterRole *rbacv1.ClusterRole, projectName string) *rbacv1.ClusterRole { + if clusterRole.Rules == nil { + clusterRole.Rules = []rbacv1.PolicyRule{} + } + clusterRole.Rules = append(clusterRole.Rules, rbacv1.PolicyRule{ + APIGroups: []string{management.GroupName}, + Verbs: []string{manageNSVerb}, + Resources: []string{apisV3.ProjectResourceName}, + ResourceNames: []string{projectName}, + }) + if clusterRole.Annotations == nil { + clusterRole.Annotations = map[string]string{} + } + return clusterRole +} + +func crByNS(obj interface{}) ([]string, error) { + cr, ok := obj.(*rbacv1.ClusterRole) + if !ok { + return []string{}, nil + } + + if _, ok := cr.Annotations[projectNSAnn]; !ok { + return []string{}, nil + } + + var result []string + for _, r := range cr.Rules { + if slice.ContainsString(r.Resources, "namespaces") && (slice.ContainsString(r.Verbs, "get") || slice.ContainsString(r.Verbs, "*")) { + result = append(result, r.ResourceNames...) + } + } + return result, nil +} + +func updateStatusAnnotation(hasPRTBs bool, namespace *v1.Namespace, mgr *manager) { + if _, ok := namespace.Annotations[projectIDAnnotation]; ok { + for i := 0; i < 10; i++ { + time.Sleep(time.Millisecond * 500) + clusterRoles, err := mgr.crIndexer.ByIndex(crByNSIndex, namespace.Name) + if err != nil { + logrus.Warnf("error getting cluster roles for ns %v for status update: %v", namespace.Name, err) + continue + } + if len(clusterRoles) < 2 { + continue + } + + creator := namespace.Annotations["field.cattle.io/creatorId"] + if creator != "" { + found := false + for _, crx := range clusterRoles { + cr, _ := crx.(*rbacv1.ClusterRole) + crbKey := rbRoleSubjectKey(cr.Name, rbacv1.Subject{Kind: "User", Name: creator}) + crbs, _ := mgr.crbIndexer.ByIndex(crbByRoleAndSubjectIndex, crbKey) + if len(crbs) > 0 { + found = true + break + } + } + if !found { + continue + } + } + + if hasPRTBs { + bindings, err := mgr.rbLister.List(namespace.Name, labels.Everything()) + if err != nil { + logrus.Warnf("error getting bindings for ns %v for status update: %v", namespace.Name, err) + continue + } + if len(bindings) > 0 { + break + } + } + } + } + + for i := 0; i < 10; i++ { + ns, err := mgr.workload.Core.Namespaces("").Get(namespace.Name, metav1.GetOptions{}) + if err != nil { + logrus.Errorf("error getting ns %v for status update: %v", namespace.Name, err) + return + } + if err := namespaceutil.SetNamespaceCondition(ns, time.Second*1, initialRoleCondition, true, ""); err != nil { + logrus.Warnf("fail to set %v condition on ns %v: %v", initialRoleCondition, namespace.Name, err) + continue + } + _, err = mgr.workload.Core.Namespaces("").Update(ns) + if err == nil { + break + } + if !apierrors.IsConflict(err) { + logrus.Warnf("error updating ns %v status: %v", ns.Name, err) + } + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler_test.go new file mode 100644 index 0000000..0654416 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/namespace_handler_test.go @@ -0,0 +1,492 @@ +package rbac + +import ( + "fmt" + "testing" + + "github.com/rancher/rancher/pkg/apis/management.cattle.io" + apisV3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" +) + +func TestReconcileNamespaceProjectClusterRole(t *testing.T) { + const namespaceName = "test-ns" + tests := []struct { + name string + indexedRoles []*rbacv1.ClusterRole + currentRoles []*rbacv1.ClusterRole + projectNSAnnotation string + indexerError error + updateError error + createError error + deleteError error + getError error + + wantRoles []*rbacv1.ClusterRole + wantDeleteRoleNames []string + wantError bool + }{ + { + name: "create read-only", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + }, + wantRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + }, + wantError: false, + }, + { + name: "update old create new read-only", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + addNamespaceToClusterRole("otherNamespace", "get", createClusterRoleForProject("p-123abc", namespaceName, "get")), + }, + wantRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + createClusterRoleForProject("p-123abc", "otherNamespace", "get"), + }, + wantError: false, + }, + { + name: "delete old create new read-only", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + createClusterRoleForProject("p-123abc", namespaceName, "get"), + }, + wantRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + }, + wantDeleteRoleNames: []string{createRoleName("p-123abc", "get")}, + wantError: false, + }, + { + name: "delete old update new read-only", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + createClusterRoleForProject("p-123abc", namespaceName, "get"), + }, + currentRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", "otherNamespace", "get"), + }, + wantRoles: []*rbacv1.ClusterRole{ + addNamespaceToClusterRole(namespaceName, "get", createClusterRoleForProject("p-123xyz", "otherNamespace", "get")), + }, + wantDeleteRoleNames: []string{createRoleName("p-123abc", "get")}, + wantError: false, + }, + { + name: "create edit", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + }, + wantRoles: []*rbacv1.ClusterRole{ + addManagePermissionToClusterRole("p-123xyz", createClusterRoleForProject("p-123xyz", namespaceName, "*")), + }, + wantError: false, + }, + { + name: "update old create new edit", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + addManagePermissionToClusterRole("p-123abc", addNamespaceToClusterRole("otherNamespace", "*", createClusterRoleForProject("p-123abc", namespaceName, "*"))), + }, + wantRoles: []*rbacv1.ClusterRole{ + addManagePermissionToClusterRole("p-123xyz", createClusterRoleForProject("p-123xyz", namespaceName, "*")), + addManagePermissionToClusterRole("p-123abc", createClusterRoleForProject("p-123abc", "otherNamespace", "*")), + }, + wantError: false, + }, + { + name: "update old update new edit", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "get"), + addManagePermissionToClusterRole("p-123abc", createClusterRoleForProject("p-123abc", namespaceName, "*")), + }, + currentRoles: []*rbacv1.ClusterRole{ + addManagePermissionToClusterRole("p-123xyz", createClusterRoleForProject("p-123xyz", "otherNamespace", "*")), + }, + wantRoles: []*rbacv1.ClusterRole{ + addManagePermissionToClusterRole("p-123xyz", addNamespaceToClusterRole(namespaceName, "*", createClusterRoleForProject("p-123xyz", "otherNamespace", "*"))), + addManagePermissionToClusterRole("p-123abc", createBaseClusterRoleForProject("p-123abc", "*")), + }, + wantError: false, + }, + { + name: "indexer error", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexerError: fmt.Errorf("unable to read from indexer"), + wantError: true, + }, + { + name: "update error", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + addNamespaceToClusterRole("otherNamespace", "get", createClusterRoleForProject("p-123abc", namespaceName, "get")), + }, + updateError: fmt.Errorf("unable to update"), + wantError: true, + }, + { + name: "create error", + projectNSAnnotation: "c-123xyz:p-123xyz", + createError: fmt.Errorf("unable to create"), + wantError: true, + }, + { + name: "delete error", + projectNSAnnotation: "c-123xyz:p-123xyz", + indexedRoles: []*rbacv1.ClusterRole{ + createClusterRoleForProject("p-123xyz", namespaceName, "*"), + createClusterRoleForProject("p-123abc", namespaceName, "get"), + }, + deleteError: fmt.Errorf("unable to delete"), + wantError: true, + }, + { + name: "get error", + projectNSAnnotation: "c-123xyz:p-123xyz", + getError: fmt.Errorf("unable to get"), + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + var newRoles []*rbacv1.ClusterRole + var deletedRoleNames []string + indexer := DummyIndexer{ + clusterRoles: map[string][]*rbacv1.ClusterRole{ + namespaceName: test.indexedRoles, + }, + err: test.indexerError, + } + fakeLister := &fakes.ClusterRoleListerMock{ + GetFunc: func(namespace string, name string) (*rbacv1.ClusterRole, error) { + if test.getError != nil { + return nil, test.getError + } + for _, role := range test.currentRoles { + if role.Name == name { + return role, nil + } + } + return nil, apierror.NewNotFound(schema.GroupResource{ + Group: "rbac.authorization.k8s.io", + Resource: "ClusterRoles", + }, name) + }, + } + fakeClusterRoles := &fakes.ClusterRoleInterfaceMock{ + CreateFunc: func(in *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + newRoles = append(newRoles, in) + if test.createError != nil { + return nil, test.createError + } + return in, nil + }, + UpdateFunc: func(in *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + newRoles = append(newRoles, in) + if test.updateError != nil { + return nil, test.updateError + } + return in, nil + }, + DeleteFunc: func(name string, options *metav1.DeleteOptions) error { + deletedRoleNames = append(deletedRoleNames, name) + if test.deleteError != nil { + return test.deleteError + } + return nil + }, + } + lifecycle := nsLifecycle{ + m: &manager{ + crLister: fakeLister, + crIndexer: &indexer, + clusterRoles: fakeClusterRoles, + }, + } + err := lifecycle.reconcileNamespaceProjectClusterRole(&corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespaceName, + Annotations: map[string]string{ + projectIDAnnotation: test.projectNSAnnotation, + }, + }, + }) + if test.wantError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Len(t, newRoles, len(test.wantRoles)) + for _, role := range test.wantRoles { + assert.Contains(t, newRoles, role) + } + assert.Len(t, deletedRoleNames, len(test.wantDeleteRoleNames)) + for _, roleName := range test.wantDeleteRoleNames { + assert.Contains(t, deletedRoleNames, roleName) + } + } + }) + } + +} + +func TestCreateProjectNSRole(t *testing.T) { + t.Parallel() + + type testCase struct { + description string + verb string + namespace string + projectName string + startingCR *v1.ClusterRole + expectedCR *v1.ClusterRole + createError error + expectedErr string + } + testCases := []testCase{ + { + description: "create get role", + verb: "get", + projectName: "p-123xyz", + expectedCR: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-readonly", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-readonly", + }, + }, + }, + }, + { + description: "create edit role", + verb: "*", + projectName: "p-123xyz", + expectedCR: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + }, + { + description: "do not change role if already exists and return AlreadyExists error", + verb: "*", + projectName: "p-123xyz", + expectedCR: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + startingCR: &v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + expectedErr: `roletemplates.management.cattle.io "p-123xyz-namespaces-edit" already exists`, + }, + { + description: "test should return non-AlreadyExists error", + verb: "*", + projectName: "p-123xyz", + createError: errors.NewInternalError(fmt.Errorf("some error")), + expectedErr: "Internal error occurred: some error", + }, + } + for _, test := range testCases { + clusterRoles := map[string]*v1.ClusterRole{} + if test.startingCR != nil { + clusterRoles = map[string]*v1.ClusterRole{ + test.startingCR.Name: test.startingCR, + } + } + + m := newManager(withClusterRoles(clusterRoles, &clientErrs{createError: test.createError})) + + roleName := fmt.Sprintf(projectNSGetClusterRoleNameFmt, test.projectName, projectNSVerbToSuffix[test.verb]) + err := m.createProjectNSRole(roleName, test.verb, test.namespace, test.projectName) + + crMock := m.clusterRoles.(*fakes.ClusterRoleInterfaceMock) + calls := crMock.CreateCalls() + assert.Len(t, calls, 1) + + if test.expectedErr != "" { + assert.ErrorContains(t, err, test.expectedErr, test.description) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedCR, calls[0].In1, test.description) + } + } +} + +func createClusterRoleForProject(projectName string, namespace string, verb string) *rbacv1.ClusterRole { + cr := createBaseClusterRoleForProject(projectName, verb) + return addNamespaceToClusterRole(namespace, verb, cr) +} + +func createBaseClusterRoleForProject(projectName string, verb string) *rbacv1.ClusterRole { + roleName := createRoleName(projectName, verb) + newCR := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Annotations: map[string]string{ + projectNSAnn: roleName, + }, + }, + } + return newCR.DeepCopy() +} + +func addNamespaceToClusterRole(namespace string, verb string, clusterRole *rbacv1.ClusterRole) *rbacv1.ClusterRole { + if clusterRole.Rules == nil { + clusterRole.Rules = []rbacv1.PolicyRule{} + } + foundIdx := -1 + // aggregate to a single rule for all NS if we can + for i, rule := range clusterRole.Rules { + hasApiGroup := false + for _, apiGroup := range rule.APIGroups { + if apiGroup == "" { + hasApiGroup = true + break + } + } + if !hasApiGroup { + continue + } + + hasNamespaces := false + for _, resource := range rule.Resources { + if resource == "namespaces" { + hasNamespaces = true + break + } + } + if !hasNamespaces { + continue + } + foundIdx = i + } + if foundIdx >= 0 { + clusterRole.Rules[foundIdx].ResourceNames = append(clusterRole.Rules[foundIdx].ResourceNames, namespace) + return clusterRole + } + rule := rbacv1.PolicyRule{ + APIGroups: []string{""}, + Verbs: []string{verb}, + Resources: []string{"namespaces"}, + ResourceNames: []string{namespace}, + } + clusterRole.Rules = append(clusterRole.Rules, rule) + return clusterRole +} + +func addManagePermissionToClusterRole(projectName string, clusterRole *rbacv1.ClusterRole) *rbacv1.ClusterRole { + if clusterRole.Rules == nil { + clusterRole.Rules = []rbacv1.PolicyRule{} + } + rule := rbacv1.PolicyRule{ + APIGroups: []string{management.GroupName}, + Verbs: []string{manageNSVerb}, + Resources: []string{apisV3.ProjectResourceName}, + ResourceNames: []string{projectName}, + } + clusterRole.Rules = append(clusterRole.Rules, rule) + return clusterRole +} + +func createRoleName(projectName string, verb string) string { + return fmt.Sprintf(projectNSGetClusterRoleNameFmt, projectName, projectNSVerbToSuffix[verb]) +} + +type DummyIndexer struct { + cache.Store + clusterRoles map[string][]*rbacv1.ClusterRole + err error +} + +func (d *DummyIndexer) Index(indexName string, obj interface{}) ([]interface{}, error) { + return nil, nil +} + +func (d *DummyIndexer) IndexKeys(indexName, indexKey string) ([]string, error) { + return []string{}, nil +} + +func (d *DummyIndexer) ListIndexFuncValues(indexName string) []string { + return []string{} +} + +func (d *DummyIndexer) ByIndex(indexName, indexKey string) ([]interface{}, error) { + if indexName != crByNSIndex { + return nil, fmt.Errorf("dummy indexer only supports %s for index name, %s given", crByNSIndex, indexName) + } + if d.err != nil { + return nil, d.err + } + crs := d.clusterRoles[indexKey] + var interfaces []interface{} + for _, cr := range crs { + interfaces = append(interfaces, cr) + } + return interfaces, nil +} + +func (d *DummyIndexer) GetIndexers() cache.Indexers { + return nil +} + +func (d *DummyIndexer) AddIndexers(newIndexers cache.Indexers) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler.go new file mode 100644 index 0000000..e986b77 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler.go @@ -0,0 +1,215 @@ +package rbac + +import ( + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/apis/management.cattle.io" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + projectpkg "github.com/rancher/rancher/pkg/project" + "github.com/rancher/rancher/pkg/settings" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" +) + +func newProjectLifecycle(r *manager) *pLifecycle { + return &pLifecycle{m: r} +} + +type pLifecycle struct { + m *manager +} + +func (p *pLifecycle) Create(project *v3.Project) (runtime.Object, error) { + for verb, suffix := range projectNSVerbToSuffix { + roleName := fmt.Sprintf(projectNSGetClusterRoleNameFmt, project.Name, suffix) + _, err := p.m.crLister.Get("", roleName) + if err == nil || !apierrors.IsNotFound(err) { + continue + } + + err = p.m.createProjectNSRole(roleName, verb, "", project.Name) + if err != nil { + return project, err + } + + } + + err := p.ensureNamespacesAssigned(project) + return project, err +} + +func (p *pLifecycle) Updated(project *v3.Project) (runtime.Object, error) { + err := p.ensureNamespaceRolesUpdated(project) + if err != nil { + return project, err + } + err = p.ensureNamespacesAssigned(project) + return project, err +} + +func (p *pLifecycle) Remove(project *v3.Project) (runtime.Object, error) { + for _, suffix := range projectNSVerbToSuffix { + roleName := fmt.Sprintf(projectNSGetClusterRoleNameFmt, project.Name, suffix) + + err := p.m.workload.RBAC.ClusterRoles("").Delete(roleName, &v1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return project, err + } + } + + projectID := project.Namespace + ":" + project.Name + namespaces, err := p.m.nsIndexer.ByIndex(nsByProjectIndex, projectID) + if err != nil { + return project, err + } + + for _, o := range namespaces { + namespace, _ := o.(*corev1.Namespace) + if _, ok := namespace.Annotations["field.cattle.io/creatorId"]; ok { + err := p.m.workload.Core.Namespaces("").Delete(namespace.Name, &v1.DeleteOptions{}) + if err != nil && !apierrors.IsNotFound(err) { + return project, err + } + } else { + namespace = namespace.DeepCopy() + if namespace.Annotations != nil { + delete(namespace.Annotations, projectIDAnnotation) + _, err := p.m.workload.Core.Namespaces("").Update(namespace) + if err != nil { + return project, err + } + } + } + } + + return nil, nil +} + +func (p *pLifecycle) ensureNamespacesAssigned(project *v3.Project) error { + projectName := "" + if _, ok := project.Labels["authz.management.cattle.io/default-project"]; ok { + projectName = projectpkg.Default + } else if _, ok := project.Labels["authz.management.cattle.io/system-project"]; ok { + projectName = projectpkg.System + } + if projectName == "" { + return nil + } + + switch projectName { + case projectpkg.Default: + if err := p.ensureDefaultNamespaceAssigned(project); err != nil { + return err + } + case projectpkg.System: + if err := p.ensureSystemNamespaceAssigned(project); err != nil { + return err + } + default: + return nil + } + + _, err := p.m.workload.Management.Management.Projects(p.m.workload.ClusterName).Update(project) + return err +} + +func (p *pLifecycle) ensureDefaultNamespaceAssigned(project *v3.Project) error { + _, err := v32.ProjectConditionDefaultNamespacesAssigned.DoUntilTrue(project, func() (runtime.Object, error) { + return nil, p.assignNamespacesToProject(project, projectpkg.Default) + }) + return err +} + +func (p *pLifecycle) ensureSystemNamespaceAssigned(project *v3.Project) error { + _, err := v32.ProjectConditionSystemNamespacesAssigned.DoUntilTrue(project, func() (runtime.Object, error) { + return nil, p.assignNamespacesToProject(project, projectpkg.System) + }) + return err +} + +// ensureNamespaceRolesUpdated makes sure that the namespace roles have up-to-date rules, and issues updates if they don't +func (p *pLifecycle) ensureNamespaceRolesUpdated(project *v3.Project) error { + // right now, only the edit role for namespaces has need of an update + suffix := projectNSVerbToSuffix[projectNSEditVerb] + roleName := fmt.Sprintf(projectNSGetClusterRoleNameFmt, project.Name, suffix) + cr, err := p.m.crLister.Get("", roleName) + if err != nil { + if apierrors.IsNotFound(err) { + return p.m.createProjectNSRole(roleName, projectNSEditVerb, "", project.Name) + } + return fmt.Errorf("unable to get backing cluster role for project %s: %w", project.Name, err) + } + // manage-ns permission was added later on in rancher's lifecycle, so we may need to update the CR if it doesn't + // have this permission + manageNSRecord := authorizer.AttributesRecord{ + Verb: manageNSVerb, + APIGroup: management.GroupName, + Resource: v32.ProjectResourceName, + Name: project.Name, + ResourceRequest: true, + } + if !rbac.RulesAllow(manageNSRecord, cr.Rules...) { + // only add the manageNS permission so that we don't overwrite the other permissions dynamically given by the + // namespace_handler + cr = addManageNSPermission(cr, project.Name) + _, err = p.m.clusterRoles.Update(cr) + if err != nil { + return fmt.Errorf("unable to update backing cluster role for project %s: %w", project.Name, err) + } + } + return nil +} + +func (p *pLifecycle) assignNamespacesToProject(project *v3.Project, projectName string) error { + initialProjectsToNamespaces, err := getDefaultAndSystemProjectsToNamespaces() + if err != nil { + return err + } + for _, nsName := range initialProjectsToNamespaces[projectName] { + ns, err := p.m.nsLister.Get("", nsName) + if err != nil { + if apierrors.IsNotFound(err) { + continue + } + return err + } + projectID := ns.Annotations[projectIDAnnotation] + if projectID != "" { + continue + } + + ns = ns.DeepCopy() + if ns.Annotations == nil { + ns.Annotations = map[string]string{} + } + ns.Annotations[projectIDAnnotation] = fmt.Sprintf("%v:%v", p.m.clusterName, project.Name) + if _, err := p.m.workload.Core.Namespaces(p.m.clusterName).Update(ns); err != nil { + return err + } + } + return nil +} + +func getDefaultAndSystemProjectsToNamespaces() (map[string][]string, error) { + systemNamespacesStr := settings.SystemNamespaces.Get() + var systemNamespaces []string + if systemNamespacesStr == "" { + return nil, fmt.Errorf("failed to load setting %v", settings.SystemNamespaces) + } + + splitted := strings.Split(systemNamespacesStr, ",") + for _, s := range splitted { + systemNamespaces = append(systemNamespaces, strings.TrimSpace(s)) + } + + return map[string][]string{ + projectpkg.Default: {"default"}, + projectpkg.System: systemNamespaces, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler_test.go new file mode 100644 index 0000000..b0d1a0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/project_handler_test.go @@ -0,0 +1,332 @@ +package rbac + +import ( + "fmt" + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/stretchr/testify/assert" + rbacv1 "k8s.io/api/rbac/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestCreate(t *testing.T) { + const projectName = "p-123xyz" + tests := []struct { + name string + existingClusterRoleNames []string + getErr error + createErr error + + wantErr bool + wantRoles []rbacv1.ClusterRole + }{ + { + name: "basic create", + wantRoles: []rbacv1.ClusterRole{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-readonly", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-readonly", + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + }, + }, + { + name: "get error", + getErr: fmt.Errorf("unexpected error"), + wantErr: false, + }, + { + name: "create error", + createErr: fmt.Errorf("unexpected error"), + wantErr: true, + }, + { + name: "roles already exist", + existingClusterRoleNames: []string{"p-123xyz-namespaces-readonly", "p-123xyz-namespaces-edit"}, + wantErr: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + project := &v3.Project{ + ObjectMeta: metav1.ObjectMeta{ + Name: projectName, + }, + } + var newCRs []*rbacv1.ClusterRole + lifecycle := pLifecycle{ + m: &manager{ + crLister: &fakes.ClusterRoleListerMock{ + GetFunc: func(namespace string, name string) (*rbacv1.ClusterRole, error) { + if test.getErr != nil { + return nil, test.getErr + } + for _, clusterRoleName := range test.existingClusterRoleNames { + if clusterRoleName == name { + return &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleName, + }, + }, nil + } + } + return nil, apierror.NewNotFound(schema.GroupResource{ + Group: "rbac.authorization.k8s.io", + Resource: "ClusterRoles", + }, name) + }, + }, + clusterRoles: &fakes.ClusterRoleInterfaceMock{ + CreateFunc: func(in *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + newCRs = append(newCRs, in) + if test.createErr != nil { + return nil, test.createErr + } + return in, nil + }, + }, + }, + } + _, err := lifecycle.Create(project) + if test.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, len(test.wantRoles), len(newCRs)) + for _, desiredRole := range test.wantRoles { + assert.Contains(t, newCRs, &desiredRole) + } + } + }) + } +} + +func TestUpdated(t *testing.T) { + const projectName = "p-123xyz" + tests := []struct { + name string + currentClusterRole *rbacv1.ClusterRole + getError error + updError error + createError error + + wantError bool + wantClusterRole *rbacv1.ClusterRole + }{ + { + name: "missing cluster role annotation", + currentClusterRole: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Verbs: []string{"*"}, + Resources: []string{"namespaces"}, + ResourceNames: []string{"test-ns"}, + }, + }, + }, + wantError: false, + wantClusterRole: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Verbs: []string{"*"}, + Resources: []string{"namespaces"}, + ResourceNames: []string{"test-ns"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + }, + { + name: "annotation present", + currentClusterRole: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Verbs: []string{"*"}, + Resources: []string{"namespaces"}, + ResourceNames: []string{"test-ns"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + wantError: false, + }, + { + name: "missing cluster role", + wantClusterRole: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + Annotations: map[string]string{ + projectNSAnn: "p-123xyz-namespaces-edit", + }, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Verbs: []string{"manage-namespaces"}, + Resources: []string{"projects"}, + ResourceNames: []string{"p-123xyz"}, + }, + }, + }, + wantError: false, + }, + { + name: "get error", + getError: fmt.Errorf("unexpected error"), + wantError: true, + }, + { + name: "create error", + createError: fmt.Errorf("unexpected error"), + wantError: true, + }, + { + name: "update error", + currentClusterRole: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "p-123xyz-namespaces-edit", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Verbs: []string{"*"}, + Resources: []string{"namespaces"}, + ResourceNames: []string{"test-ns"}, + }, + }, + }, + updError: fmt.Errorf("unexpected error"), + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + project := &v3.Project{ + ObjectMeta: metav1.ObjectMeta{ + Name: projectName, + }, + } + var newCRs []*rbacv1.ClusterRole + lifecycle := pLifecycle{ + m: &manager{ + crLister: &fakes.ClusterRoleListerMock{ + GetFunc: func(namespace string, name string) (*rbacv1.ClusterRole, error) { + if test.getError != nil { + return nil, test.getError + } + if test.currentClusterRole != nil && name == test.currentClusterRole.Name { + return test.currentClusterRole, nil + } + return nil, apierror.NewNotFound(schema.GroupResource{ + Group: "rbac.authorization.k8s.io", + Resource: "ClusterRoles", + }, name) + }, + }, + clusterRoles: &fakes.ClusterRoleInterfaceMock{ + CreateFunc: func(in *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + newCRs = append(newCRs, in) + if test.createError != nil { + return nil, test.createError + } + return in, nil + }, + UpdateFunc: func(in *rbacv1.ClusterRole) (*rbacv1.ClusterRole, error) { + newCRs = append(newCRs, in) + if test.updError != nil { + return nil, test.updError + } + return in, nil + }, + }, + }, + } + _, err := lifecycle.Updated(project) + if test.wantError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + if test.wantClusterRole != nil { + assert.Len(t, newCRs, 1) + assert.Equal(t, test.wantClusterRole, newCRs[0]) + } + } + }) + } +} + +type fakeRBAC struct { + clusterRoleFake fakes.ClusterRoleInterfaceMock + clusterRoleBindingFake fakes.ClusterRoleBindingInterfaceMock + roleFake fakes.RoleInterfaceMock + roleBindingFake fakes.RoleBindingInterfaceMock +} + +func (f *fakeRBAC) ClusterRoles(namespace string) v1.ClusterRoleInterface { return &f.clusterRoleFake } + +func (f *fakeRBAC) ClusterRoleBindings(namespace string) v1.ClusterRoleBindingInterface { + return &f.clusterRoleBindingFake +} + +func (f *fakeRBAC) Roles(namespace string) v1.RoleInterface { return &f.roleFake } + +func (f *fakeRBAC) RoleBindings(namespace string) v1.RoleBindingInterface { return &f.roleBindingFake } diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler.go new file mode 100644 index 0000000..1c13047 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler.go @@ -0,0 +1,517 @@ +package rbac + +import ( + "errors" + "fmt" + "reflect" + "strings" + + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/slice" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/retry" +) + +const owner = "owner-user" + +// globalResourceRulesNeededInProjects is the set of PolicyRules that need to be present on *-promoted ClusterRoles +// Binding a user to a *-promoted ClusterRole with these PolicyRules results in that user being granted access to these "global" resources. +// The PolicyRule for each resource is the base policy rule, verbs are added dynamically and the key is used for the Resources value of each rule +var globalResourceRulesNeededInProjects = map[string]rbacv1.PolicyRule{ + "navlinks": rbacv1.PolicyRule{ + APIGroups: []string{"ui.cattle.io"}, + }, + "nodes": rbacv1.PolicyRule{ + APIGroups: []string{""}, + }, + "persistentvolumes": rbacv1.PolicyRule{ + APIGroups: []string{"", "core"}, + }, + "storageclasses": rbacv1.PolicyRule{ + APIGroups: []string{"storage.k8s.io"}, + }, + "apiservices": rbacv1.PolicyRule{ + APIGroups: []string{"apiregistration.k8s.io"}, + }, + "clusterrepos": rbacv1.PolicyRule{ + APIGroups: []string{"catalog.cattle.io"}, + }, + "clusters": rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + // since *-promoted roles may be applied in all clusters, the resource name needs to be "local" + // performing 'kubectl get clusters.management.cattle.io local' needs to work for the user within the context of the cluster they are promoted in, + // otherwise certain functionality that relies on this global permission will not work correctly, e.g. kubectl shell + // this will not grant the user permissions on the management cluster unless they are added as a project member/owner/read-only within that cluster + ResourceNames: []string{"local"}, + }, +} + +func newPRTBLifecycle(m *manager, management *config.ManagementContext, nsInformer cache.SharedIndexInformer) *prtbLifecycle { + return &prtbLifecycle{ + m: m, + rtLister: management.Management.RoleTemplates("").Controller().Lister(), + nsIndexer: nsInformer.GetIndexer(), + rbLister: m.workload.RBAC.RoleBindings("").Controller().Lister(), + rbClient: m.workload.RBAC.RoleBindings(""), + crbLister: m.workload.RBAC.ClusterRoleBindings("").Controller().Lister(), + crbClient: m.workload.RBAC.ClusterRoleBindings(""), + prtbClient: management.Management.ProjectRoleTemplateBindings(""), + } +} + +type prtbLifecycle struct { + m managerInterface + rtLister v3.RoleTemplateLister + nsIndexer cache.Indexer + rbLister typesrbacv1.RoleBindingLister + rbClient typesrbacv1.RoleBindingInterface + crbLister typesrbacv1.ClusterRoleBindingLister + crbClient typesrbacv1.ClusterRoleBindingInterface + prtbClient v3.ProjectRoleTemplateBindingInterface +} + +func (p *prtbLifecycle) Create(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + err := p.syncPRTB(obj) + return obj, err +} + +func (p *prtbLifecycle) Updated(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + if err := p.reconcilePRTBUserClusterLabels(obj); err != nil { + return obj, err + } + err := p.syncPRTB(obj) + return obj, err +} + +func (p *prtbLifecycle) Remove(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + err := p.ensurePRTBDelete(obj) + return obj, err +} + +func (p *prtbLifecycle) syncPRTB(binding *v3.ProjectRoleTemplateBinding) error { + if binding.RoleTemplateName == "" { + logrus.Warnf("ProjectRoleTemplateBinding %v has no role template set. Skipping.", binding.Name) + return nil + } + if binding.UserName == "" && binding.GroupPrincipalName == "" && binding.GroupName == "" { + return nil + } + + rt, err := p.rtLister.Get("", binding.RoleTemplateName) + if err != nil { + return fmt.Errorf("couldn't get role template %v: %w", binding.RoleTemplateName, err) + } + + // Get namespaces belonging to project + namespaces, err := p.nsIndexer.ByIndex(nsByProjectIndex, binding.ProjectName) + if err != nil { + return fmt.Errorf("couldn't list namespaces with project ID %v: %w", binding.ProjectName, err) + } + roles := map[string]*v3.RoleTemplate{} + if err := p.m.gatherRoles(rt, roles, 0); err != nil { + return err + } + + if err := p.m.ensureRoles(roles); err != nil { + return fmt.Errorf("couldn't ensure roles: %w", err) + } + + for _, n := range namespaces { + ns := n.(*v1.Namespace) + if !ns.DeletionTimestamp.IsZero() { + continue + } + if err := p.m.ensureProjectRoleBindings(ns.Name, roles, binding); err != nil { + return fmt.Errorf("couldn't ensure binding %v in %v: %w", binding.Name, ns.Name, err) + } + } + + if binding.UserName != "" { + if err := p.m.ensureServiceAccountImpersonator(binding.UserName); err != nil { + return fmt.Errorf("couldn't ensure service account impersonator: %w", err) + } + } + + return p.reconcileProjectAccessToGlobalResources(binding, roles) +} + +func (p *prtbLifecycle) ensurePRTBDelete(binding *v3.ProjectRoleTemplateBinding) error { + // Get namespaces belonging to project + namespaces, err := p.nsIndexer.ByIndex(nsByProjectIndex, binding.ProjectName) + if err != nil { + return fmt.Errorf("couldn't list namespaces with project ID %v: %w", binding.ProjectName, err) + } + + set := labels.Set(map[string]string{rtbOwnerLabel: pkgrbac.GetRTBLabel(binding.ObjectMeta)}) + for _, n := range namespaces { + ns := n.(*v1.Namespace) + rbs, err := p.rbLister.List(ns.Name, set.AsSelector()) + if err != nil { + return fmt.Errorf("couldn't list rolebindings with selector %s: %w", set.AsSelector(), err) + } + + for _, rb := range rbs { + if err := p.rbClient.DeleteNamespaced(ns.Name, rb.Name, &metav1.DeleteOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return fmt.Errorf("error deleting rolebinding %v: %w", rb.Name, err) + } + } + } + } + + if err := p.m.deleteServiceAccountImpersonator(binding.UserName); err != nil { + return fmt.Errorf("error deleting service account impersonator: %w", err) + } + + return p.reconcileProjectAccessToGlobalResourcesForDelete(binding) +} + +func (p *prtbLifecycle) reconcileProjectAccessToGlobalResources(binding *v3.ProjectRoleTemplateBinding, rts map[string]*v3.RoleTemplate) error { + roles, err := p.m.ensureGlobalResourcesRolesForPRTB(parseProjectName(binding.ProjectName), rts) + if err != nil { + return err + } + _, err = p.m.reconcileProjectAccessToGlobalResources(binding, roles) + if err != nil { + return err + } + return nil +} + +func (p *prtbLifecycle) reconcileProjectAccessToGlobalResourcesForDelete(binding *v3.ProjectRoleTemplateBinding) error { + rtbNsAndName := pkgrbac.GetRTBLabel(binding.ObjectMeta) + set := labels.Set(map[string]string{rtbNsAndName: owner}) + crbs, err := p.crbLister.List("", set.AsSelector()) + if err != nil { + return err + } + + for _, crb := range crbs { + crb = crb.DeepCopy() + for k, v := range crb.Labels { + if k == rtbNsAndName && v == owner { + delete(crb.Labels, k) + } + } + + eligibleForDeletion, err := p.m.noRemainingOwnerLabels(crb) + if err != nil { + return err + } + + if eligibleForDeletion { + if err := p.crbClient.Delete(crb.Name, &metav1.DeleteOptions{}); err != nil { + if apierrors.IsNotFound(err) { + continue + } + return err + } + } else { + if _, err := p.crbClient.Update(crb); err != nil { + return err + } + } + } + + return nil +} + +func (m *manager) noRemainingOwnerLabels(crb *rbacv1.ClusterRoleBinding) (bool, error) { + for k, v := range crb.Labels { + if v == owner { + if exists, err := m.ownerExists(k); exists || err != nil { + return false, err + } + if exists, err := m.ownerExistsByNsName(k); exists || err != nil { + return false, err + } + } + + if k == rtbOwnerLabelLegacy { + if exists, err := m.ownerExists(v); exists || err != nil { + return false, err + } + } + if k == rtbOwnerLabel { + if exists, err := m.ownerExistsByNsName(v); exists || err != nil { + return false, err + } + } + } + + return true, nil +} + +func (m *manager) ownerExists(uid interface{}) (bool, error) { + prtbs, err := m.prtbIndexer.ByIndex(prtbByUIDIndex, convert.ToString(uid)) + return len(prtbs) > 0, err +} + +func (m *manager) ownerExistsByNsName(nsAndName interface{}) (bool, error) { + prtbs, err := m.prtbIndexer.ByIndex(prtbByNsAndNameIndex, convert.ToString(nsAndName)) + return len(prtbs) > 0, err +} + +// If the roleTemplate has rules granting access to non-namespaced (global) resource, return the verbs for those rules +func (m *manager) checkForGlobalResourceRules(role *v3.RoleTemplate, resource string, baseRule rbacv1.PolicyRule) (sets.Set[string], error) { + var rules []rbacv1.PolicyRule + if role.External { + externalRole, err := m.crLister.Get("", role.Name) + if err != nil && !apierrors.IsNotFound(err) { + // dont error if it doesnt exist + return nil, err + } + if externalRole != nil { + rules = externalRole.Rules + } + } else { + rules = role.Rules + } + + verbs := sets.New[string]() + for _, rule := range rules { + // given the global resource, we check if the passed in RoleTemplate has a corresponding rule, if it does, we add the verbs specified in the rule to the map of verbs that is returned + // NOTE: ResourceNames are checked since some global resources are scoped to specific resources, e.g. management.cattle.io/v3.Clusters are scoped to just the "local" cluster resource + if (slice.ContainsString(rule.Resources, resource) || slice.ContainsString(rule.Resources, "*")) && reflect.DeepEqual(rule.ResourceNames, baseRule.ResourceNames) { + if checkGroup(resource, rule) { + verbs.Insert(rule.Verbs...) + } + } + } + + return verbs, nil +} + +// reconcileRoleForProjectAccessToGlobalResource ensure the clusterRole used to grant access of global resources +// to users/groups in projects has appropriate rules for the given resource and verbs. +// It returns the created or updated ClusterRole name, or blank "" if none were created or updated. +// The roleName is used to find and create/update the relevant '-promoted' ClusterRole. +func (m *manager) reconcileRoleForProjectAccessToGlobalResource(resource string, roleName string, newVerbs sets.Set[string], baseRule rbacv1.PolicyRule) (string, error) { + if roleName == "" { + return "", fmt.Errorf("cannot reconcile Role: missing roleName") + } + roleName = roleName + "-promoted" + + role, err := m.crLister.Get("", roleName) + if err != nil { + if !apierrors.IsNotFound(err) { + return "", fmt.Errorf("get cluster role %s failed: %w", roleName, err) + } + + // try to create the role if not found + + // if newVerbs are empty we can skip the creation and return a blank role name + // to let the caller knows that this was a no-op + if len(newVerbs) == 0 { + return "", nil + } + + logrus.Infof("Creating clusterRole %v for project access to global resource.", roleName) + + clusterRole := &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + }, + Rules: []rbacv1.PolicyRule{buildRule(resource, newVerbs, baseRule)}, + } + + _, err := m.clusterRoles.Create(clusterRole) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return "", fmt.Errorf("couldn't create role %v: %w", roleName, err) + } + logrus.Infof("Trying to create an already existing clusterRole %v for project access to global resource.", roleName) + } + + return roleName, nil + } + + // role already exists -> updating / reconciling + + currentVerbs := sets.New[string]() + currentResourceNames := sets.New[string]() + for _, rule := range role.Rules { + if slice.ContainsString(rule.Resources, resource) { + currentVerbs.Insert(rule.Verbs...) + currentResourceNames.Insert(rule.ResourceNames...) + } + } + + desiredResourceNames := sets.New(baseRule.ResourceNames...) + + // if the currentVerbs and the currentResourceNames matches the desired state we can return + if currentVerbs.Equal(newVerbs) && currentResourceNames.Equal(desiredResourceNames) { + return roleName, nil + } + + // if the verbs or the resourceNames in the promoted clusterrole don't match what's desired then the role requires updating + // desired verbs are passed in and the desired resourceNames come from the resource's base rule + role = role.DeepCopy() + + added := false + for i, rule := range role.Rules { + if slice.ContainsString(rule.Resources, resource) { + role.Rules[i] = buildRule(resource, newVerbs, baseRule) + added = true + } + } + if !added { + role.Rules = append(role.Rules, buildRule(resource, newVerbs, baseRule)) + } + + // check if we need to delete some policy rules + if len(newVerbs) == 0 { + newRules := []rbacv1.PolicyRule{} + for _, rule := range role.Rules { + if !slice.ContainsString(rule.Resources, resource) { + newRules = append(newRules, rule) + } + } + role.Rules = newRules + } + + logrus.Infof("Updating clusterRole %v for project access to global resource.", role.Name) + _, err = m.clusterRoles.Update(role) + if err != nil { + return "", fmt.Errorf("couldn't update role %v: %w", role.Name, err) + } + return roleName, nil +} + +// checkGroup returns true if the passed in PolicyRule has a group that matches the corresponding baseRule for the passed in global resource +func checkGroup(resource string, rule rbacv1.PolicyRule) bool { + if slice.ContainsString(rule.APIGroups, "*") { + return true + } + + baseRule, ok := globalResourceRulesNeededInProjects[resource] + if !ok { + return false + } + + for _, rg := range rule.APIGroups { + if slice.ContainsString(baseRule.APIGroups, rg) { + return true + } + } + + return false +} + +func buildRule(resource string, verbs sets.Set[string], baseRule rbacv1.PolicyRule) rbacv1.PolicyRule { + return rbacv1.PolicyRule{ + Resources: []string{resource}, + Verbs: sets.List(verbs), // List returns a sorted array of the verbs + APIGroups: baseRule.APIGroups, + ResourceNames: baseRule.ResourceNames, + } +} + +func (p *prtbLifecycle) reconcilePRTBUserClusterLabels(binding *v3.ProjectRoleTemplateBinding) error { + /* Prior to 2.5, for every PRTB, following CRBs are created in the user clusters + 1. PRTB.UID is the label key for a CRB, PRTB.UID=owner-user + 2. PRTB.UID is the label value for RBs with authz.cluster.cattle.io/rtb-owner: PRTB.UID + Using this labels, list the CRBs and update them to add a label with ns+name of CRTB + */ + if binding.Labels[rtbCrbRbLabelsUpdated] == "true" { + return nil + } + + var returnErr error + reqUpdatedLabel, err := labels.NewRequirement(rtbLabelUpdated, selection.DoesNotExist, []string{}) + if err != nil { + return err + } + reqNsAndNameLabel, err := labels.NewRequirement(pkgrbac.GetRTBLabel(binding.ObjectMeta), selection.DoesNotExist, []string{}) + if err != nil { + return err + } + set := labels.Set(map[string]string{string(binding.UID): owner}) + userCRBs, err := p.crbClient.List(metav1.ListOptions{LabelSelector: set.AsSelector().Add(*reqUpdatedLabel, *reqNsAndNameLabel).String()}) + if err != nil { + return err + } + bindingLabel := pkgrbac.GetRTBLabel(binding.ObjectMeta) + + for _, crb := range userCRBs.Items { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + crbToUpdate, updateErr := p.crbClient.Get(crb.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if crbToUpdate.Labels == nil { + crbToUpdate.Labels = make(map[string]string) + } + crbToUpdate.Labels[bindingLabel] = owner + crbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := p.crbClient.Update(crbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + + reqUpdatedOwnerLabel, err := labels.NewRequirement(rtbOwnerLabel, selection.DoesNotExist, []string{}) + if err != nil { + return err + } + set = map[string]string{rtbOwnerLabelLegacy: string(binding.UID)} + rbs, err := p.rbLister.List(v1.NamespaceAll, set.AsSelector().Add(*reqUpdatedLabel, *reqUpdatedOwnerLabel)) + if err != nil { + return err + } + for _, rb := range rbs { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + rbToUpdate, updateErr := p.rbClient.GetNamespaced(rb.Namespace, rb.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if rbToUpdate.Labels == nil { + rbToUpdate.Labels = make(map[string]string) + } + rbToUpdate.Labels[rtbOwnerLabel] = bindingLabel + rbToUpdate.Labels[rtbLabelUpdated] = "true" + _, err := p.rbClient.Update(rbToUpdate) + return err + }) + returnErr = errors.Join(returnErr, retryErr) + } + + if returnErr != nil { + return returnErr + } + + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + prtbToUpdate, updateErr := p.prtbClient.GetNamespaced(binding.Namespace, binding.Name, metav1.GetOptions{}) + if updateErr != nil { + return updateErr + } + if prtbToUpdate.Labels == nil { + prtbToUpdate.Labels = make(map[string]string) + } + prtbToUpdate.Labels[rtbCrbRbLabelsUpdated] = "true" + _, err := p.prtbClient.Update(prtbToUpdate) + return err + }) + return retryErr +} + +func parseProjectName(id string) string { + parts := strings.SplitN(id, ":", 2) + if len(parts) != 2 || len(parts[1]) == 0 { + return "" + } + return parts[1] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler_test.go new file mode 100644 index 0000000..208f51b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/prtb_handler_test.go @@ -0,0 +1,628 @@ +package rbac + +import ( + "errors" + "fmt" + "io" + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + typesrbacv1fakes "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" +) + +type prtbTestState struct { + managerMock *MockmanagerInterface +} + +func TestReconcileProjectAccessToGlobalResources(t *testing.T) { + t.Parallel() + + defaultPRTB := v3.ProjectRoleTemplateBinding{ + ProjectName: "default", + } + + tests := []struct { + name string + stateSetup func(prtbTestState) + prtb *v3.ProjectRoleTemplateBinding + rts map[string]*v3.RoleTemplate + wantError bool + }{ + { + name: "error ensuring global resource roles", + stateSetup: func(pts prtbTestState) { + pts.managerMock.EXPECT().ensureGlobalResourcesRolesForPRTB(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")) + }, + prtb: defaultPRTB.DeepCopy(), + rts: nil, + wantError: true, + }, + { + name: "error reconciling access to global resources", + stateSetup: func(pts prtbTestState) { + pts.managerMock.EXPECT().ensureGlobalResourcesRolesForPRTB(gomock.Any(), gomock.Any()).Return(nil, nil) + pts.managerMock.EXPECT().reconcileProjectAccessToGlobalResources(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")) + }, + prtb: defaultPRTB.DeepCopy(), + rts: nil, + wantError: true, + }, + { + name: "success", + stateSetup: func(pts prtbTestState) { + pts.managerMock.EXPECT().ensureGlobalResourcesRolesForPRTB(gomock.Any(), gomock.Any()).Return(nil, nil) + pts.managerMock.EXPECT().reconcileProjectAccessToGlobalResources(gomock.Any(), gomock.Any()).Return(nil, nil) + }, + prtb: defaultPRTB.DeepCopy(), + rts: nil, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + prtbLifecycle := prtbLifecycle{} + state := setupPRTBTest(t) + if test.stateSetup != nil { + test.stateSetup(state) + } + prtbLifecycle.m = state.managerMock + + err := prtbLifecycle.reconcileProjectAccessToGlobalResources(test.prtb, test.rts) + + if test.wantError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func setupPRTBTest(t *testing.T) prtbTestState { + ctrl := gomock.NewController(t) + managerMock := NewMockmanagerInterface(ctrl) + state := prtbTestState{ + managerMock: managerMock, + } + return state +} + +func Test_manager_checkForGlobalResourceRules(t *testing.T) { + type tests struct { + name string + role *v3.RoleTemplate + resource string + baseRule rbacv1.PolicyRule + want sets.Set[string] + } + + testCases := []tests{ + { + name: "valid_api_group_persistentvolumes", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{""}, + Resources: []string{"persistentvolumes"}, + }, + }, + }, + resource: "persistentvolumes", + baseRule: rbacv1.PolicyRule{}, + want: sets.New("put"), + }, + { + name: "invalid_api_group_persistentvolumes", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{"foo"}, + Resources: []string{"persistentvolumes"}, + }, + }, + }, + resource: "persistentvolumes", + baseRule: rbacv1.PolicyRule{}, + want: sets.New[string](), + }, + { + name: "valid_api_group_storageclasses", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{"storage.k8s.io"}, + Resources: []string{"storageclasses"}, + }, + }, + }, + resource: "storageclasses", + baseRule: rbacv1.PolicyRule{}, + want: sets.New("put"), + }, + { + name: "invalid_api_group_storageclasses", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{"foo"}, + Resources: []string{"storageclasses"}, + }, + }, + }, + resource: "storageclasses", + baseRule: rbacv1.PolicyRule{}, + want: sets.New[string](), + }, + { + name: "valid_api_group_start", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{""}, + Resources: []string{"*"}, + }, + }, + }, + resource: "persistentvolumes", + baseRule: rbacv1.PolicyRule{}, + want: sets.New("put"), + }, + { + name: "invalid_api_group_star", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"put"}, + APIGroups: []string{"foo"}, + Resources: []string{"*"}, + }, + }, + }, + resource: "persistentvolumes", + baseRule: rbacv1.PolicyRule{}, + want: sets.New[string](), + }, + { + name: "cluster_rule_match", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"clusters"}, + }, + }, + }, + resource: "clusters", + baseRule: rbacv1.PolicyRule{}, + want: sets.New("get"), + }, + { + name: "cluster_rule_resource_names_match", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"clusters"}, + ResourceNames: []string{"local"}, + }, + }, + }, + resource: "clusters", + baseRule: rbacv1.PolicyRule{ + ResourceNames: []string{"local"}, + }, + want: sets.New("get"), + }, + { + name: "cluster_rule_baserule_resource_names_no_match", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"clusters"}, + }, + }, + }, + resource: "clusters", + baseRule: rbacv1.PolicyRule{ + ResourceNames: []string{"local"}, + }, + want: sets.New[string](), + }, + { + name: "cluster_rule_roletemplate_resource_names_no_match", + role: &v3.RoleTemplate{ + Rules: []v1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"clusters"}, + ResourceNames: []string{"local"}, + }, + }, + }, + resource: "clusters", + baseRule: rbacv1.PolicyRule{}, + want: sets.New[string](), + }, + } + + m := &manager{} + + for _, test := range testCases { + got, err := m.checkForGlobalResourceRules(test.role, test.resource, test.baseRule) + assert.Nil(t, err) + assert.Equal(t, test.want, got, fmt.Sprintf("test %v failed", test.name)) + } +} + +func Test_manager_reconcileRoleForProjectAccessToGlobalResource(t *testing.T) { + // discard logs to avoid cluttering + logrus.SetOutput(io.Discard) + + type args struct { + resource string + rtName string + newVerbs sets.Set[string] + baseRule rbacv1.PolicyRule + } + + tests := []struct { + name string + crListerMockGetResult *v1.ClusterRole + crListerMockGetErr error + clusterRolesMockCreateResult *v1.ClusterRole + clusterRolesMockCreateErr error + clusterRolesMockUpdateResult *v1.ClusterRole + clusterRolesMockUpdateErr error + args args + want string + wantErr bool + }{ + { + name: "missing role name will fail", + args: args{ + rtName: "", + }, + wantErr: true, + }, + { + name: "failing create will return an error", + args: args{ + rtName: "myrole", + newVerbs: sets.New("get", "list"), + }, + crListerMockGetErr: errNotFound, + clusterRolesMockCreateErr: errors.New("something bad happened"), + wantErr: true, + }, + { + name: "reconciling non existing ClusterRole with no verbs is no-op", + args: args{ + rtName: "myrole", + newVerbs: sets.New[string](), + }, + crListerMockGetErr: errNotFound, + want: "", + }, + { + name: "existing ClusterRole will not update if no need to reconcile", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("list", "delete"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"list", "delete"}, + }, + }, + }, + want: "myrole-promoted", + }, + { + name: "non existing ClusterRole will create a new promoted ClusterRole", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("get", "list"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetErr: errNotFound, + clusterRolesMockCreateResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"get", "list"}, + }}, + }, + want: "myrole-promoted", + }, + { + name: "existing ClusterRole will update it adding missing rules", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("list", "delete"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"another"}, + Verbs: []string{"get", "list"}, + }, + }, + }, + clusterRolesMockUpdateResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"another"}, + Verbs: []string{"get", "list"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"delete", "list"}, + }, + }, + }, + want: "myrole-promoted", + }, + { + name: "existing ClusterRole will update it", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("list", "delete"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"another.cattle.io"}, + ResourceNames: []string{"foobar"}, + Resources: []string{"nodes"}, + Verbs: []string{"create"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"get", "list"}, + }, + }, + }, + clusterRolesMockUpdateResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"another.cattle.io"}, + ResourceNames: []string{"foobar"}, + Resources: []string{"nodes"}, + Verbs: []string{"create"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"delete", "list"}, + }, + }, + }, + want: "myrole-promoted", + }, + { + name: "removing verbs from policy will remove the rule", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New[string](), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"another.cattle.io"}, + ResourceNames: []string{"foobar"}, + Resources: []string{"nodes"}, + Verbs: []string{"create"}, + }, + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"get", "list"}, + }, + }, + }, + clusterRolesMockUpdateResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"another.cattle.io"}, + ResourceNames: []string{"foobar"}, + Resources: []string{"nodes"}, + Verbs: []string{"create"}, + }, + }, + }, + want: "myrole-promoted", + }, + { + name: "get fail will return an error", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("get", "list"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetErr: errors.New("get failed"), + wantErr: true, + }, + { + name: "update fail will return an error", + args: args{ + rtName: "myrole", + resource: "myresource", + newVerbs: sets.New("list", "delete"), + baseRule: rbacv1.PolicyRule{ + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + }, + }, + crListerMockGetResult: &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myrole-promoted", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + ResourceNames: []string{"local"}, + Resources: []string{"myresource"}, + Verbs: []string{"get", "list"}, + }, + }, + }, + clusterRolesMockUpdateErr: errors.New("something bad happened"), + wantErr: true, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + // setup ClusterRoleLister mock + crListerMock := &typesrbacv1fakes.ClusterRoleListerMock{ + GetFunc: func(namespace, name string) (*v1.ClusterRole, error) { + return tc.crListerMockGetResult, tc.crListerMockGetErr + }, + } + + // setup ClusterRole mock: it will just return the passed ClusterRole or the error + clusterRolesMock := &typesrbacv1fakes.ClusterRoleInterfaceMock{ + CreateFunc: func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { + return in1, tc.clusterRolesMockCreateErr + }, + UpdateFunc: func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { + return in1, tc.clusterRolesMockUpdateErr + }, + } + + manager := manager{ + crLister: crListerMock, + clusterRoles: clusterRolesMock, + } + + got, err := manager.reconcileRoleForProjectAccessToGlobalResource(tc.args.resource, tc.args.rtName, tc.args.newVerbs, tc.args.baseRule) + assert.Equal(t, tc.want, got) + if tc.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + + // if result and err are nil the method should have not been called + if tc.crListerMockGetResult == nil && tc.crListerMockGetErr == nil { + assert.Empty(t, crListerMock.GetCalls()) + } else { + // otherwise only one call to Get is expected + assert.Len(t, crListerMock.GetCalls(), 1) + } + + // if result and err are nil the method should have not been called + if tc.clusterRolesMockCreateResult == nil && tc.clusterRolesMockCreateErr == nil { + assert.Empty(t, clusterRolesMock.CreateCalls()) + } else { + // otherwise only one call to Get is expected, and the values should match + results := clusterRolesMock.CreateCalls() + assert.Len(t, results, 1) + + if tc.clusterRolesMockCreateErr == nil { + assert.Equal(t, tc.clusterRolesMockCreateResult, results[0].In1) + } + } + + // if result and err are nil the method should have not been called + if tc.clusterRolesMockUpdateResult == nil && tc.clusterRolesMockUpdateErr == nil { + assert.Empty(t, clusterRolesMock.UpdateCalls()) + } else { + // otherwise only one call to Update is expected, and the values should match + results := clusterRolesMock.UpdateCalls() + assert.Len(t, results, 1) + + if tc.clusterRolesMockUpdateErr == nil { + assert.Equal(t, tc.clusterRolesMockUpdateResult, results[0].In1) + } + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate.go new file mode 100644 index 0000000..ddc8a7d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate.go @@ -0,0 +1,156 @@ +package rbac + +import ( + "fmt" + + "github.com/rancher/norman/types/slice" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pkgrbac "github.com/rancher/rancher/pkg/rbac" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" +) + +func (m *manager) reconcileProjectAccessToGlobalResources(binding *v3.ProjectRoleTemplateBinding, roles []string) (map[string]bool, error) { + if len(roles) == 0 { + return nil, nil + } + + bindingCli := m.workload.RBAC.ClusterRoleBindings("") + + rtbUID := pkgrbac.GetRTBLabel(binding.ObjectMeta) + subject, err := pkgrbac.BuildSubjectFromRTB(binding) + if err != nil { + return nil, err + } + crbsToKeep := make(map[string]bool) + for _, role := range roles { + crbKey := rbRoleSubjectKey(role, subject) + crbs, _ := m.crbIndexer.ByIndex(crbByRoleAndSubjectIndex, crbKey) + if len(crbs) == 0 { + logrus.Infof("Creating clusterRoleBinding for project access to global resource for subject %v role %v.", subject.Name, role) + roleRef := rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: role, + } + crbName := pkgrbac.NameForClusterRoleBinding(roleRef, subject) + createdCRB, err := bindingCli.Create(&rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crbName, + Labels: map[string]string{ + rtbUID: owner, + }, + }, + Subjects: []rbacv1.Subject{subject}, + RoleRef: roleRef, + }) + if err == nil { + crbsToKeep[createdCRB.Name] = true + continue + } + if !apierrors.IsAlreadyExists(err) { + return nil, err + } + + // the binding exists but was not found in the index, manually retrieve it so that we can add appropriate labels + crb, err := bindingCli.Get(crbName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + crbs = append(crbs, crb) + } + + CRBs: + for _, obj := range crbs { + crb, ok := obj.(*rbacv1.ClusterRoleBinding) + if !ok { + continue + } + + crbsToKeep[crb.Name] = true + for owner := range crb.Labels { + if rtbUID == owner { + continue CRBs + } + } + + crb = crb.DeepCopy() + if crb.Labels == nil { + crb.Labels = map[string]string{} + } + crb.Labels[rtbUID] = owner + logrus.Infof("Updating clusterRoleBinding %v for project access to global resource for subject %v role %v.", crb.Name, subject.Name, role) + _, err := bindingCli.Update(crb) + if err != nil { + return nil, err + } + } + } + + return crbsToKeep, nil +} + +// EnsureGlobalResourcesRolesForPRTB ensures that all necessary roles exist and contain the rules needed to +// enforce permissions described by RoleTemplate rules. A slice of strings indicating role names is returned. +func (m *manager) ensureGlobalResourcesRolesForPRTB(projectName string, rts map[string]*v3.RoleTemplate) ([]string, error) { + roles := sets.New[string]() + + if projectName == "" { + return nil, nil + } + + var roleVerb, roleSuffix string + for _, r := range rts { + for _, rule := range r.Rules { + hasNamespaceResources := slice.ContainsString(rule.Resources, "namespaces") || slice.ContainsString(rule.Resources, "*") + hasNamespaceGroup := slice.ContainsString(rule.APIGroups, "") || slice.ContainsString(rule.APIGroups, "*") + if hasNamespaceGroup && hasNamespaceResources && len(rule.ResourceNames) == 0 { + if slice.ContainsString(rule.Verbs, "*") || slice.ContainsString(rule.Verbs, "create") { + roleVerb = "*" + roles.Insert("create-ns") + if nsRole, _ := m.crLister.Get("", "create-ns"); nsRole == nil { + createNSRT, err := m.rtLister.Get("", "create-ns") + if err != nil { + return nil, err + } + if err := m.ensureRoles(map[string]*v3.RoleTemplate{"create-ns": createNSRT}); err != nil && !apierrors.IsAlreadyExists(err) { + return nil, err + } + } + break + } + } + + } + } + if roleVerb == "" { + roleVerb = "get" + } + roleSuffix = projectNSVerbToSuffix[roleVerb] + role := fmt.Sprintf(projectNSGetClusterRoleNameFmt, projectName, roleSuffix) + roles.Insert(role) + + for _, rt := range rts { + for resource, baseRule := range globalResourceRulesNeededInProjects { + verbs, err := m.checkForGlobalResourceRules(rt, resource, baseRule) + if err != nil { + return nil, err + } + + roleName, err := m.reconcileRoleForProjectAccessToGlobalResource(resource, rt.Name, verbs, baseRule) + if err != nil { + return nil, err + } + + // if a role was created or updated append it to the existing roles + if roleName != "" { + roles.Insert(roleName) + } + } + } + + return sets.List(roles), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate_test.go new file mode 100644 index 0000000..31f9799 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/reconcile_roletemplate_test.go @@ -0,0 +1,274 @@ +package rbac + +import ( + "io" + "testing" + + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestEnsureGlobalResourcesRolesForPRTB(t *testing.T) { + t.Parallel() + logrus.SetOutput(io.Discard) + + defaultManager := newManager( + withRoleTemplates(map[string]*v3.RoleTemplate{"create-ns": createNSRoleTemplate}, nil), + withClusterRoles(nil, nil), + ) + + type testCase struct { + description string + manager *manager + projectName string + roleTemplates map[string]*v3.RoleTemplate + expectedRoles []string + expectedError string + } + testCases := []testCase{ + { + description: "global resource rule should grant namespace read", + projectName: "testproject", + expectedRoles: []string{"testproject-namespaces-readonly"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt1": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt1", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{""}, + Resources: []string{"configmaps"}, + }, + }, + }, + }, + }, + { + description: "namespace create rule should grant create-ns and a namespaces-edit role", + projectName: "testproject", + expectedRoles: []string{"create-ns", "testproject-namespaces-edit"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt2": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt2", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"create"}, + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + }, + }, + }, + }, + }, + { + description: "namespace create rule for other API group should grant namespaces-read role only", + projectName: "testproject", + expectedRoles: []string{"testproject-namespaces-readonly"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt3": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt3", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"create"}, + APIGroups: []string{"some.other.apigroup"}, + Resources: []string{"namespaces"}, + }, + }, + }, + }, + }, + { + description: "namespace * rule for other API group should grant namespaces-read role only", + projectName: "testproject", + expectedRoles: []string{"testproject-namespaces-readonly"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt4": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt4", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"some.other.apigroup"}, + Resources: []string{"namespaces"}, + }, + }, + }, + }, + }, + { + description: "global resource rule result in promoted role returned", + projectName: "testproject", + expectedRoles: []string{"testproject-namespaces-readonly", "testrt5-promoted"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt5": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt5", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"catalog.cattle.io"}, + Resources: []string{"clusterrepos"}, + }, + }, + }, + }, + }, + { + description: "empty project name will result in no roles returned", + projectName: "", + expectedRoles: nil, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt6": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt6", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"catalog.cattle.io"}, + Resources: []string{"clusterrepos"}, + }, + }, + }, + }, + }, + { + description: "* resources and non-core APIGroup should only result in namespace-readonly role", + projectName: "testproject", + expectedRoles: []string{"testproject-namespaces-readonly"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt7": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt7", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"some.other.apigroup"}, + Resources: []string{"*"}, + }, + }, + }, + }, + }, + { + description: "* resources and * APIGroup should only result in namespace-readonly and promoted role", + projectName: "testproject", + expectedRoles: []string{"create-ns", "testproject-namespaces-edit", "testrt8-promoted"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt8": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt8", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + }, + }, + }, + }, + }, + { + description: "* resources and core (\"\") APIGroup should only result in namespace-readonly and promoted role", + projectName: "testproject", + expectedRoles: []string{"create-ns", "testproject-namespaces-edit", "testrt9-promoted"}, + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt9": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt9", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{""}, + Resources: []string{"*"}, + }, + }, + }, + }, + }, + { + projectName: "testproject", + description: "error return when RoleTemplate client returns error", + manager: newManager( + withRoleTemplates(map[string]*v3.RoleTemplate{"create-ns": createNSRoleTemplate}, &clientErrs{getError: errNotFound}), + withClusterRoles(nil, nil), + ), + expectedError: "not found", + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"create"}, + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + }, + }, + }, + }, + }, + { + projectName: "testproject", + description: "error return when ClusterRole client returns error and RoleTemplate is external", + manager: newManager( + withRoleTemplates(map[string]*v3.RoleTemplate{"create-ns": createNSRoleTemplate}, nil), + withClusterRoles(nil, &clientErrs{getError: apierrors.NewInternalError(errors.New("internal error"))}), + ), + expectedError: "internal error", + roleTemplates: map[string]*v3.RoleTemplate{ + "testrt": { + ObjectMeta: metav1.ObjectMeta{ + Name: "testrt", + }, + Rules: []v1.PolicyRule{ + { + Verbs: []string{"create"}, + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + }, + }, + External: true, + }, + }, + }, + } + for _, test := range testCases { + test := test + t.Run(test.description, func(t *testing.T) { + t.Parallel() + + manager := test.manager + if manager == nil { + manager = defaultManager + } + + roles, err := manager.ensureGlobalResourcesRolesForPRTB(test.projectName, test.roleTemplates) + + if test.expectedError != "" { + assert.ErrorContains(t, err, test.expectedError) + assert.Nil(t, roles) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedRoles, roles, test.description) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/roletemplate_handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/roletemplate_handler.go new file mode 100644 index 0000000..0f64772 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/roletemplate_handler.go @@ -0,0 +1,163 @@ +package rbac + +import ( + "github.com/pkg/errors" + wranglerv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +func newRTLifecycle(m *manager) v3.RoleTemplateHandlerFunc { + rtSync := &rtSync{m: m} + return rtSync.sync +} + +// rtSync is responsible for ensuring that roleTemplates and their corresponding clusterRoles stay in sync. +// This means that if a roleTemplate's rules change, this handler will ensure the corresponding clusterRole's rules are changed +// If a roleTemplate is removed the management lifecycle will remove the clusterRole from user clusters +// This handler does not create new clusterRoles. They are created on the fly when a ProjectRoleTemplateBinding or +// ClusterRoleTemplateBinding references the roleTemplates. This handler only ensures they remain in-sync after being created +type rtSync struct { + m *manager +} + +func newRTEnqueueFunc(rtIndxer cache.Indexer) relatedresource.Resolver { + return (&rtEnqueue{rtIndexer: rtIndxer}).rtRelatedResources +} + +// rtEnqueue is responsible for returning RoleTemplates names that inherit from a changed roletemplate and should be +// enqueued as a result. This is to ensure those beneficiary roletemplates make the necessary syncs for their own +// corresponding clusterRoles. +type rtEnqueue struct { + rtIndexer cache.Indexer +} + +func (c *rtSync) sync(key string, obj *v3.RoleTemplate) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + // check if there are any PRTBs/CRTBs referencing this RoleTemplate for this cluster + prtbs, err := c.m.prtbIndexer.ByIndex(rtbByClusterAndRoleTemplateIndex, c.m.workload.ClusterName+"-"+obj.Name) + if err != nil { + return obj, err + } + hasPRTBs := len(prtbs) > 0 + hasRTBs := hasPRTBs + var crtbs []interface{} + if !hasRTBs { + crtbs, err = c.m.crtbIndexer.ByIndex(rtbByClusterAndRoleTemplateIndex, c.m.workload.ClusterName+"-"+obj.Name) + if err != nil { + return obj, err + } + hasRTBs = len(crtbs) > 0 + } + + // No RTBs referencing this RoleTemplate in this cluster, do not attempt to sync + if !hasRTBs { + return obj, nil + } + + err = c.syncRT(obj, hasPRTBs, prtbs, crtbs) + return obj, err +} + +func (c *rtSync) syncRT(template *v3.RoleTemplate, usedInProjects bool, prtbs []interface{}, crtbs []interface{}) error { + roleTemplates := map[string]*v3.RoleTemplate{} + if err := c.m.gatherRoles(template, roleTemplates, 0); err != nil { + return err + } + + if err := c.m.ensureRoles(roleTemplates); err != nil { + return errors.Wrapf(err, "couldn't ensure roles") + } + + if usedInProjects { + for _, rt := range roleTemplates { + for resource, baseRule := range globalResourceRulesNeededInProjects { + verbs, err := c.m.checkForGlobalResourceRules(rt, resource, baseRule) + if err != nil { + return err + } + + roleName, err := c.m.reconcileRoleForProjectAccessToGlobalResource(resource, rt.Name, verbs, baseRule) + if err != nil { + return errors.Wrapf(err, "couldn't reconcile role '%s' for project access to global resources", roleName) + } + } + } + } + + for _, obj := range prtbs { + prtb, ok := obj.(*v3.ProjectRoleTemplateBinding) + if !ok { + continue + } + + roles, err := c.m.ensureGlobalResourcesRolesForPRTB(parseProjectName(prtb.ProjectName), roleTemplates) + if err != nil { + return err + } + crbsToKeep, err := c.m.reconcileProjectAccessToGlobalResources(prtb, roles) + if err != nil { + return err + } + + rtbNsAndName := rbac.GetRTBLabel(prtb.ObjectMeta) + set := labels.Set(map[string]string{rtbNsAndName: owner}) + existingCrbs, err := c.m.crbLister.List("", set.AsSelector()) + if err != nil { + return err + } + + for _, crb := range existingCrbs { + if !crbsToKeep[crb.Name] { + c.m.clusterRoleBindings.Delete(crb.Name, &metav1.DeleteOptions{}) + } + } + + // Get namespaces belonging to project to update the rolebinding in the namespaces of this project for the user + namespaces, err := c.m.nsIndexer.ByIndex(nsByProjectIndex, prtb.ProjectName) + if err != nil { + return errors.Wrapf(err, "couldn't list namespaces with project ID %v", prtb.ProjectName) + } + + for _, n := range namespaces { + ns := n.(*v1.Namespace) + if !ns.DeletionTimestamp.IsZero() { + continue + } + if err := c.m.ensureProjectRoleBindings(ns.Name, roleTemplates, prtb); err != nil { + return errors.Wrapf(err, "couldn't ensure binding %v in %v", prtb.Name, ns.Name) + } + } + } + + for _, obj := range crtbs { + crtb, ok := obj.(*v3.ClusterRoleTemplateBinding) + if !ok { + continue + } + if err := c.m.ensureClusterBindings(roleTemplates, crtb); err != nil { + return err + } + } + return nil +} + +func (r *rtEnqueue) rtRelatedResources(_, name string, _ runtime.Object) ([]relatedresource.Key, error) { + beneficiaryRTs, err := r.rtIndexer.ByIndex(rtByInheritedRTsIndex, name) + if err != nil { + return nil, err + } + result := make([]relatedresource.Key, len(beneficiaryRTs)) + for i, rt := range beneficiaryRTs { + result[i] = relatedresource.Key{Name: rt.(*wranglerv3.RoleTemplate).Name} + } + return result, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v1rbacMocks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v1rbacMocks_test.go new file mode 100644 index 0000000..29e7df5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v1rbacMocks_test.go @@ -0,0 +1,365 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1 (interfaces: ClusterRoleBindingInterface,ClusterRoleBindingLister) + +// Package rbac is a generated GoMock package. +package rbac + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + objectclient "github.com/rancher/norman/objectclient" + v1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + v10 "k8s.io/api/rbac/v1" + v11 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + watch "k8s.io/apimachinery/pkg/watch" +) + +// MockClusterRoleBindingInterface is a mock of ClusterRoleBindingInterface interface. +type MockClusterRoleBindingInterface struct { + ctrl *gomock.Controller + recorder *MockClusterRoleBindingInterfaceMockRecorder +} + +// MockClusterRoleBindingInterfaceMockRecorder is the mock recorder for MockClusterRoleBindingInterface. +type MockClusterRoleBindingInterfaceMockRecorder struct { + mock *MockClusterRoleBindingInterface +} + +// NewMockClusterRoleBindingInterface creates a new mock instance. +func NewMockClusterRoleBindingInterface(ctrl *gomock.Controller) *MockClusterRoleBindingInterface { + mock := &MockClusterRoleBindingInterface{ctrl: ctrl} + mock.recorder = &MockClusterRoleBindingInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterRoleBindingInterface) EXPECT() *MockClusterRoleBindingInterfaceMockRecorder { + return m.recorder +} + +// AddClusterScopedFeatureHandler mocks base method. +func (m *MockClusterRoleBindingInterface) AddClusterScopedFeatureHandler(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v1.ClusterRoleBindingHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureHandler", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureHandler indicates an expected call of AddClusterScopedFeatureHandler. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddClusterScopedFeatureHandler(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureHandler", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddClusterScopedFeatureHandler), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle mocks base method. +func (m *MockClusterRoleBindingInterface) AddClusterScopedFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v1.ClusterRoleBindingLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureLifecycle", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle indicates an expected call of AddClusterScopedFeatureLifecycle. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddClusterScopedFeatureLifecycle(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureLifecycle", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddClusterScopedFeatureLifecycle), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedHandler mocks base method. +func (m *MockClusterRoleBindingInterface) AddClusterScopedHandler(arg0 context.Context, arg1, arg2 string, arg3 v1.ClusterRoleBindingHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedHandler", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedHandler indicates an expected call of AddClusterScopedHandler. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddClusterScopedHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedHandler", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddClusterScopedHandler), arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle mocks base method. +func (m *MockClusterRoleBindingInterface) AddClusterScopedLifecycle(arg0 context.Context, arg1, arg2 string, arg3 v1.ClusterRoleBindingLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedLifecycle", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle indicates an expected call of AddClusterScopedLifecycle. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddClusterScopedLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedLifecycle", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddClusterScopedLifecycle), arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler mocks base method. +func (m *MockClusterRoleBindingInterface) AddFeatureHandler(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v1.ClusterRoleBindingHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureHandler", arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler indicates an expected call of AddFeatureHandler. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddFeatureHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureHandler", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddFeatureHandler), arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle mocks base method. +func (m *MockClusterRoleBindingInterface) AddFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v1.ClusterRoleBindingLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureLifecycle", arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle indicates an expected call of AddFeatureLifecycle. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddFeatureLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureLifecycle", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddFeatureLifecycle), arg0, arg1, arg2, arg3) +} + +// AddHandler mocks base method. +func (m *MockClusterRoleBindingInterface) AddHandler(arg0 context.Context, arg1 string, arg2 v1.ClusterRoleBindingHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddHandler", arg0, arg1, arg2) +} + +// AddHandler indicates an expected call of AddHandler. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddHandler(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddHandler", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddHandler), arg0, arg1, arg2) +} + +// AddLifecycle mocks base method. +func (m *MockClusterRoleBindingInterface) AddLifecycle(arg0 context.Context, arg1 string, arg2 v1.ClusterRoleBindingLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddLifecycle", arg0, arg1, arg2) +} + +// AddLifecycle indicates an expected call of AddLifecycle. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) AddLifecycle(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLifecycle", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).AddLifecycle), arg0, arg1, arg2) +} + +// Controller mocks base method. +func (m *MockClusterRoleBindingInterface) Controller() v1.ClusterRoleBindingController { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Controller") + ret0, _ := ret[0].(v1.ClusterRoleBindingController) + return ret0 +} + +// Controller indicates an expected call of Controller. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Controller() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Controller", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Controller)) +} + +// Create mocks base method. +func (m *MockClusterRoleBindingInterface) Create(arg0 *v10.ClusterRoleBinding) (*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Create(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Create), arg0) +} + +// Delete mocks base method. +func (m *MockClusterRoleBindingInterface) Delete(arg0 string, arg1 *v11.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Delete), arg0, arg1) +} + +// DeleteCollection mocks base method. +func (m *MockClusterRoleBindingInterface) DeleteCollection(arg0 *v11.DeleteOptions, arg1 v11.ListOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteCollection", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteCollection indicates an expected call of DeleteCollection. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) DeleteCollection(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCollection", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).DeleteCollection), arg0, arg1) +} + +// DeleteNamespaced mocks base method. +func (m *MockClusterRoleBindingInterface) DeleteNamespaced(arg0, arg1 string, arg2 *v11.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteNamespaced indicates an expected call of DeleteNamespaced. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) DeleteNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteNamespaced", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).DeleteNamespaced), arg0, arg1, arg2) +} + +// Get mocks base method. +func (m *MockClusterRoleBindingInterface) Get(arg0 string, arg1 v11.GetOptions) (*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Get), arg0, arg1) +} + +// GetNamespaced mocks base method. +func (m *MockClusterRoleBindingInterface) GetNamespaced(arg0, arg1 string, arg2 v11.GetOptions) (*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNamespaced indicates an expected call of GetNamespaced. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) GetNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespaced", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).GetNamespaced), arg0, arg1, arg2) +} + +// List mocks base method. +func (m *MockClusterRoleBindingInterface) List(arg0 v11.ListOptions) (*v10.ClusterRoleBindingList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", arg0) + ret0, _ := ret[0].(*v10.ClusterRoleBindingList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) List(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).List), arg0) +} + +// ListNamespaced mocks base method. +func (m *MockClusterRoleBindingInterface) ListNamespaced(arg0 string, arg1 v11.ListOptions) (*v10.ClusterRoleBindingList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListNamespaced", arg0, arg1) + ret0, _ := ret[0].(*v10.ClusterRoleBindingList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListNamespaced indicates an expected call of ListNamespaced. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) ListNamespaced(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNamespaced", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).ListNamespaced), arg0, arg1) +} + +// ObjectClient mocks base method. +func (m *MockClusterRoleBindingInterface) ObjectClient() *objectclient.ObjectClient { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ObjectClient") + ret0, _ := ret[0].(*objectclient.ObjectClient) + return ret0 +} + +// ObjectClient indicates an expected call of ObjectClient. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) ObjectClient() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ObjectClient", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).ObjectClient)) +} + +// Update mocks base method. +func (m *MockClusterRoleBindingInterface) Update(arg0 *v10.ClusterRoleBinding) (*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0) + ret0, _ := ret[0].(*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Update(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Update), arg0) +} + +// Watch mocks base method. +func (m *MockClusterRoleBindingInterface) Watch(arg0 v11.ListOptions) (watch.Interface, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Watch", arg0) + ret0, _ := ret[0].(watch.Interface) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Watch indicates an expected call of Watch. +func (mr *MockClusterRoleBindingInterfaceMockRecorder) Watch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClusterRoleBindingInterface)(nil).Watch), arg0) +} + +// MockClusterRoleBindingLister is a mock of ClusterRoleBindingLister interface. +type MockClusterRoleBindingLister struct { + ctrl *gomock.Controller + recorder *MockClusterRoleBindingListerMockRecorder +} + +// MockClusterRoleBindingListerMockRecorder is the mock recorder for MockClusterRoleBindingLister. +type MockClusterRoleBindingListerMockRecorder struct { + mock *MockClusterRoleBindingLister +} + +// NewMockClusterRoleBindingLister creates a new mock instance. +func NewMockClusterRoleBindingLister(ctrl *gomock.Controller) *MockClusterRoleBindingLister { + mock := &MockClusterRoleBindingLister{ctrl: ctrl} + mock.recorder = &MockClusterRoleBindingListerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterRoleBindingLister) EXPECT() *MockClusterRoleBindingListerMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockClusterRoleBindingLister) Get(arg0, arg1 string) (*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClusterRoleBindingListerMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClusterRoleBindingLister)(nil).Get), arg0, arg1) +} + +// List mocks base method. +func (m *MockClusterRoleBindingLister) List(arg0 string, arg1 labels.Selector) ([]*v10.ClusterRoleBinding, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", arg0, arg1) + ret0, _ := ret[0].([]*v10.ClusterRoleBinding) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClusterRoleBindingListerMockRecorder) List(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClusterRoleBindingLister)(nil).List), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v3mgmntMocks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v3mgmntMocks_test.go new file mode 100644 index 0000000..5715a10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/v3mgmntMocks_test.go @@ -0,0 +1,311 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3 (interfaces: ClusterInterface) + +// Package rbac is a generated GoMock package. +package rbac + +import ( + context "context" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + objectclient "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v30 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + watch "k8s.io/apimachinery/pkg/watch" +) + +// MockClusterInterface is a mock of ClusterInterface interface. +type MockClusterInterface struct { + ctrl *gomock.Controller + recorder *MockClusterInterfaceMockRecorder +} + +// MockClusterInterfaceMockRecorder is the mock recorder for MockClusterInterface. +type MockClusterInterfaceMockRecorder struct { + mock *MockClusterInterface +} + +// NewMockClusterInterface creates a new mock instance. +func NewMockClusterInterface(ctrl *gomock.Controller) *MockClusterInterface { + mock := &MockClusterInterface{ctrl: ctrl} + mock.recorder = &MockClusterInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterInterface) EXPECT() *MockClusterInterfaceMockRecorder { + return m.recorder +} + +// AddClusterScopedFeatureHandler mocks base method. +func (m *MockClusterInterface) AddClusterScopedFeatureHandler(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureHandler", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureHandler indicates an expected call of AddClusterScopedFeatureHandler. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedFeatureHandler(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedFeatureHandler), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle mocks base method. +func (m *MockClusterInterface) AddClusterScopedFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2, arg3 string, arg4 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedFeatureLifecycle", arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedFeatureLifecycle indicates an expected call of AddClusterScopedFeatureLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedFeatureLifecycle(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedFeatureLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedFeatureLifecycle), arg0, arg1, arg2, arg3, arg4) +} + +// AddClusterScopedHandler mocks base method. +func (m *MockClusterInterface) AddClusterScopedHandler(arg0 context.Context, arg1, arg2 string, arg3 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedHandler", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedHandler indicates an expected call of AddClusterScopedHandler. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedHandler), arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle mocks base method. +func (m *MockClusterInterface) AddClusterScopedLifecycle(arg0 context.Context, arg1, arg2 string, arg3 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddClusterScopedLifecycle", arg0, arg1, arg2, arg3) +} + +// AddClusterScopedLifecycle indicates an expected call of AddClusterScopedLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddClusterScopedLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddClusterScopedLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddClusterScopedLifecycle), arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler mocks base method. +func (m *MockClusterInterface) AddFeatureHandler(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureHandler", arg0, arg1, arg2, arg3) +} + +// AddFeatureHandler indicates an expected call of AddFeatureHandler. +func (mr *MockClusterInterfaceMockRecorder) AddFeatureHandler(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddFeatureHandler), arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle mocks base method. +func (m *MockClusterInterface) AddFeatureLifecycle(arg0 context.Context, arg1 func() bool, arg2 string, arg3 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddFeatureLifecycle", arg0, arg1, arg2, arg3) +} + +// AddFeatureLifecycle indicates an expected call of AddFeatureLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddFeatureLifecycle(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddFeatureLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddFeatureLifecycle), arg0, arg1, arg2, arg3) +} + +// AddHandler mocks base method. +func (m *MockClusterInterface) AddHandler(arg0 context.Context, arg1 string, arg2 v30.ClusterHandlerFunc) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddHandler", arg0, arg1, arg2) +} + +// AddHandler indicates an expected call of AddHandler. +func (mr *MockClusterInterfaceMockRecorder) AddHandler(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddHandler", reflect.TypeOf((*MockClusterInterface)(nil).AddHandler), arg0, arg1, arg2) +} + +// AddLifecycle mocks base method. +func (m *MockClusterInterface) AddLifecycle(arg0 context.Context, arg1 string, arg2 v30.ClusterLifecycle) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddLifecycle", arg0, arg1, arg2) +} + +// AddLifecycle indicates an expected call of AddLifecycle. +func (mr *MockClusterInterfaceMockRecorder) AddLifecycle(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLifecycle", reflect.TypeOf((*MockClusterInterface)(nil).AddLifecycle), arg0, arg1, arg2) +} + +// Controller mocks base method. +func (m *MockClusterInterface) Controller() v30.ClusterController { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Controller") + ret0, _ := ret[0].(v30.ClusterController) + return ret0 +} + +// Controller indicates an expected call of Controller. +func (mr *MockClusterInterfaceMockRecorder) Controller() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Controller", reflect.TypeOf((*MockClusterInterface)(nil).Controller)) +} + +// Create mocks base method. +func (m *MockClusterInterface) Create(arg0 *v3.Cluster) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockClusterInterfaceMockRecorder) Create(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockClusterInterface)(nil).Create), arg0) +} + +// Delete mocks base method. +func (m *MockClusterInterface) Delete(arg0 string, arg1 *v1.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockClusterInterfaceMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClusterInterface)(nil).Delete), arg0, arg1) +} + +// DeleteCollection mocks base method. +func (m *MockClusterInterface) DeleteCollection(arg0 *v1.DeleteOptions, arg1 v1.ListOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteCollection", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteCollection indicates an expected call of DeleteCollection. +func (mr *MockClusterInterfaceMockRecorder) DeleteCollection(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCollection", reflect.TypeOf((*MockClusterInterface)(nil).DeleteCollection), arg0, arg1) +} + +// DeleteNamespaced mocks base method. +func (m *MockClusterInterface) DeleteNamespaced(arg0, arg1 string, arg2 *v1.DeleteOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteNamespaced indicates an expected call of DeleteNamespaced. +func (mr *MockClusterInterfaceMockRecorder) DeleteNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).DeleteNamespaced), arg0, arg1, arg2) +} + +// Get mocks base method. +func (m *MockClusterInterface) Get(arg0 string, arg1 v1.GetOptions) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0, arg1) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockClusterInterfaceMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClusterInterface)(nil).Get), arg0, arg1) +} + +// GetNamespaced mocks base method. +func (m *MockClusterInterface) GetNamespaced(arg0, arg1 string, arg2 v1.GetOptions) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNamespaced", arg0, arg1, arg2) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNamespaced indicates an expected call of GetNamespaced. +func (mr *MockClusterInterfaceMockRecorder) GetNamespaced(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).GetNamespaced), arg0, arg1, arg2) +} + +// List mocks base method. +func (m *MockClusterInterface) List(arg0 v1.ListOptions) (*v3.ClusterList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", arg0) + ret0, _ := ret[0].(*v3.ClusterList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockClusterInterfaceMockRecorder) List(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockClusterInterface)(nil).List), arg0) +} + +// ListNamespaced mocks base method. +func (m *MockClusterInterface) ListNamespaced(arg0 string, arg1 v1.ListOptions) (*v3.ClusterList, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListNamespaced", arg0, arg1) + ret0, _ := ret[0].(*v3.ClusterList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListNamespaced indicates an expected call of ListNamespaced. +func (mr *MockClusterInterfaceMockRecorder) ListNamespaced(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNamespaced", reflect.TypeOf((*MockClusterInterface)(nil).ListNamespaced), arg0, arg1) +} + +// ObjectClient mocks base method. +func (m *MockClusterInterface) ObjectClient() *objectclient.ObjectClient { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ObjectClient") + ret0, _ := ret[0].(*objectclient.ObjectClient) + return ret0 +} + +// ObjectClient indicates an expected call of ObjectClient. +func (mr *MockClusterInterfaceMockRecorder) ObjectClient() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ObjectClient", reflect.TypeOf((*MockClusterInterface)(nil).ObjectClient)) +} + +// Update mocks base method. +func (m *MockClusterInterface) Update(arg0 *v3.Cluster) (*v3.Cluster, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Update", arg0) + ret0, _ := ret[0].(*v3.Cluster) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockClusterInterfaceMockRecorder) Update(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockClusterInterface)(nil).Update), arg0) +} + +// Watch mocks base method. +func (m *MockClusterInterface) Watch(arg0 v1.ListOptions) (watch.Interface, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Watch", arg0) + ret0, _ := ret[0].(watch.Interface) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Watch indicates an expected call of Watch. +func (mr *MockClusterInterfaceMockRecorder) Watch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockClusterInterface)(nil).Watch), arg0) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/zz_manager_fakes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/zz_manager_fakes.go new file mode 100644 index 0000000..af4003a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/rbac/zz_manager_fakes.go @@ -0,0 +1,170 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: handler_base.go +// +// Generated by this command: +// +// mockgen -source handler_base.go -destination=zz_manager_fakes.go -package=rbac +// + +// Package rbac is a generated GoMock package. +package rbac + +import ( + reflect "reflect" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + gomock "go.uber.org/mock/gomock" + v1 "k8s.io/api/rbac/v1" +) + +// MockmanagerInterface is a mock of managerInterface interface. +type MockmanagerInterface struct { + ctrl *gomock.Controller + recorder *MockmanagerInterfaceMockRecorder +} + +// MockmanagerInterfaceMockRecorder is the mock recorder for MockmanagerInterface. +type MockmanagerInterfaceMockRecorder struct { + mock *MockmanagerInterface +} + +// NewMockmanagerInterface creates a new mock instance. +func NewMockmanagerInterface(ctrl *gomock.Controller) *MockmanagerInterface { + mock := &MockmanagerInterface{ctrl: ctrl} + mock.recorder = &MockmanagerInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockmanagerInterface) EXPECT() *MockmanagerInterfaceMockRecorder { + return m.recorder +} + +// deleteServiceAccountImpersonator mocks base method. +func (m *MockmanagerInterface) deleteServiceAccountImpersonator(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "deleteServiceAccountImpersonator", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// deleteServiceAccountImpersonator indicates an expected call of deleteServiceAccountImpersonator. +func (mr *MockmanagerInterfaceMockRecorder) deleteServiceAccountImpersonator(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "deleteServiceAccountImpersonator", reflect.TypeOf((*MockmanagerInterface)(nil).deleteServiceAccountImpersonator), arg0) +} + +// ensureClusterBindings mocks base method. +func (m *MockmanagerInterface) ensureClusterBindings(arg0 map[string]*v3.RoleTemplate, arg1 *v3.ClusterRoleTemplateBinding) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureClusterBindings", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureClusterBindings indicates an expected call of ensureClusterBindings. +func (mr *MockmanagerInterfaceMockRecorder) ensureClusterBindings(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureClusterBindings", reflect.TypeOf((*MockmanagerInterface)(nil).ensureClusterBindings), arg0, arg1) +} + +// ensureGlobalResourcesRolesForPRTB mocks base method. +func (m *MockmanagerInterface) ensureGlobalResourcesRolesForPRTB(arg0 string, arg1 map[string]*v3.RoleTemplate) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureGlobalResourcesRolesForPRTB", arg0, arg1) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ensureGlobalResourcesRolesForPRTB indicates an expected call of ensureGlobalResourcesRolesForPRTB. +func (mr *MockmanagerInterfaceMockRecorder) ensureGlobalResourcesRolesForPRTB(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureGlobalResourcesRolesForPRTB", reflect.TypeOf((*MockmanagerInterface)(nil).ensureGlobalResourcesRolesForPRTB), arg0, arg1) +} + +// ensureProjectRoleBindings mocks base method. +func (m *MockmanagerInterface) ensureProjectRoleBindings(arg0 string, arg1 map[string]*v3.RoleTemplate, arg2 *v3.ProjectRoleTemplateBinding) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureProjectRoleBindings", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureProjectRoleBindings indicates an expected call of ensureProjectRoleBindings. +func (mr *MockmanagerInterfaceMockRecorder) ensureProjectRoleBindings(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureProjectRoleBindings", reflect.TypeOf((*MockmanagerInterface)(nil).ensureProjectRoleBindings), arg0, arg1, arg2) +} + +// ensureRoles mocks base method. +func (m *MockmanagerInterface) ensureRoles(arg0 map[string]*v3.RoleTemplate) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureRoles", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureRoles indicates an expected call of ensureRoles. +func (mr *MockmanagerInterfaceMockRecorder) ensureRoles(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureRoles", reflect.TypeOf((*MockmanagerInterface)(nil).ensureRoles), arg0) +} + +// ensureServiceAccountImpersonator mocks base method. +func (m *MockmanagerInterface) ensureServiceAccountImpersonator(arg0 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ensureServiceAccountImpersonator", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ensureServiceAccountImpersonator indicates an expected call of ensureServiceAccountImpersonator. +func (mr *MockmanagerInterfaceMockRecorder) ensureServiceAccountImpersonator(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ensureServiceAccountImpersonator", reflect.TypeOf((*MockmanagerInterface)(nil).ensureServiceAccountImpersonator), arg0) +} + +// gatherRoles mocks base method. +func (m *MockmanagerInterface) gatherRoles(arg0 *v3.RoleTemplate, arg1 map[string]*v3.RoleTemplate, arg2 int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "gatherRoles", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// gatherRoles indicates an expected call of gatherRoles. +func (mr *MockmanagerInterfaceMockRecorder) gatherRoles(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "gatherRoles", reflect.TypeOf((*MockmanagerInterface)(nil).gatherRoles), arg0, arg1, arg2) +} + +// noRemainingOwnerLabels mocks base method. +func (m *MockmanagerInterface) noRemainingOwnerLabels(arg0 *v1.ClusterRoleBinding) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "noRemainingOwnerLabels", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// noRemainingOwnerLabels indicates an expected call of noRemainingOwnerLabels. +func (mr *MockmanagerInterfaceMockRecorder) noRemainingOwnerLabels(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "noRemainingOwnerLabels", reflect.TypeOf((*MockmanagerInterface)(nil).noRemainingOwnerLabels), arg0) +} + +// reconcileProjectAccessToGlobalResources mocks base method. +func (m *MockmanagerInterface) reconcileProjectAccessToGlobalResources(arg0 *v3.ProjectRoleTemplateBinding, arg1 []string) (map[string]bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "reconcileProjectAccessToGlobalResources", arg0, arg1) + ret0, _ := ret[0].(map[string]bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// reconcileProjectAccessToGlobalResources indicates an expected call of reconcileProjectAccessToGlobalResources. +func (mr *MockmanagerInterfaceMockRecorder) reconcileProjectAccessToGlobalResources(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "reconcileProjectAccessToGlobalResources", reflect.TypeOf((*MockmanagerInterface)(nil).reconcileProjectAccessToGlobalResources), arg0, arg1) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/namespace_quota_reset.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/namespace_quota_reset.go new file mode 100644 index 0000000..d658167 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/namespace_quota_reset.go @@ -0,0 +1,48 @@ +package resourcequota + +import ( + "fmt" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + clientcache "k8s.io/client-go/tools/cache" +) + +/* +quotaResetController is responsible for resetting resource quota on the namespace +when project resource quota gets reset +*/ +type quotaResetController struct { + namespaces v1.NamespaceInterface + nsIndexer clientcache.Indexer +} + +func (c *quotaResetController) resetNamespaceQuota(key string, project *v3.Project) (runtime.Object, error) { + if project == nil || project.DeletionTimestamp != nil { + return nil, nil + } + if project.Spec.ResourceQuota != nil { + return nil, nil + } + projectID := fmt.Sprintf("%s:%s", project.Namespace, project.Name) + namespaces, err := c.nsIndexer.ByIndex(nsByProjectIndex, projectID) + if err != nil { + return nil, err + } + for _, n := range namespaces { + ns := n.(*corev1.Namespace) + quota := getNamespaceResourceQuota(ns) + if quota == "" { + continue + } + toUpdate := ns.DeepCopy() + delete(toUpdate.Annotations, resourceQuotaAnnotation) + if _, err := c.namespaces.Update(toUpdate); err != nil { + return nil, err + } + } + + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/register.go new file mode 100644 index 0000000..fc2d75e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/register.go @@ -0,0 +1,88 @@ +package resourcequota + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" +) + +const ( + nsByProjectIndex = "resourcequota.cluster.cattle.io/ns-by-project" +) + +func Register(ctx context.Context, cluster *config.UserContext) { + starter := cluster.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, cluster) + return nil + }) + + projects := cluster.Management.Management.Projects(cluster.ClusterName) + projects.AddHandler(ctx, "resourcequota-deferred", func(key string, obj *v3.Project) (runtime.Object, error) { + if obj != nil && + (obj.Spec.ResourceQuota != nil || + obj.Spec.ContainerDefaultResourceLimit != nil || + obj.Spec.NamespaceDefaultResourceQuota != nil) { + return obj, starter() + } + return obj, nil + }) + +} + +func registerDeferred(ctx context.Context, cluster *config.UserContext) { + // Index for looking up Namespaces by projectID annotation + nsInformer := cluster.Core.Namespaces("").Controller().Informer() + nsIndexers := map[string]cache.IndexFunc{ + nsByProjectIndex: nsByProjectID, + } + nsInformer.AddIndexers(nsIndexers) + sync := &SyncController{ + Namespaces: cluster.Core.Namespaces(""), + NsIndexer: nsInformer.GetIndexer(), + ResourceQuotas: cluster.Core.ResourceQuotas(""), + ResourceQuotaLister: cluster.Core.ResourceQuotas("").Controller().Lister(), + LimitRange: cluster.Core.LimitRanges(""), + LimitRangeLister: cluster.Core.LimitRanges("").Controller().Lister(), + ProjectLister: cluster.Management.Management.Projects(cluster.ClusterName).Controller().Lister(), + } + cluster.Core.Namespaces("").AddHandler(ctx, "resourceQuotaSyncController", sync.syncResourceQuota) + + reconcile := &reconcileController{ + namespaces: cluster.Core.Namespaces(""), + nsIndexer: nsInformer.GetIndexer(), + } + + cluster.Management.Management.Projects(cluster.ClusterName).AddHandler(ctx, "resourceQuotaNamespacesReconcileController", reconcile.reconcileNamespaces) + + calculate := &calculateLimitController{ + nsIndexer: nsInformer.GetIndexer(), + projectLister: cluster.Management.Management.Projects(cluster.ClusterName).Controller().Lister(), + projects: cluster.Management.Management.Projects(cluster.ClusterName), + clusterName: cluster.ClusterName, + } + cluster.Core.Namespaces("").AddHandler(ctx, "resourceQuotaUsedLimitController", calculate.calculateResourceQuotaUsed) + cluster.Management.Management.Projects(cluster.ClusterName).AddHandler(ctx, "resourceQuotaProjectUsedLimitController", calculate.calculateResourceQuotaUsedProject) + + reset := "aResetController{ + nsIndexer: nsInformer.GetIndexer(), + namespaces: cluster.Core.Namespaces(""), + } + cluster.Management.Management.Projects(cluster.ClusterName).AddHandler(ctx, "namespaceResourceQuotaResetController", reset.resetNamespaceQuota) +} + +func nsByProjectID(obj interface{}) ([]string, error) { + ns, ok := obj.(*corev1.Namespace) + if !ok { + return []string{}, nil + } + + if id, ok := ns.Annotations[projectIDAnnotation]; ok { + return []string{id}, nil + } + + return []string{}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_calculate_used.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_calculate_used.go new file mode 100644 index 0000000..fe87a23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_calculate_used.go @@ -0,0 +1,100 @@ +package resourcequota + +import ( + "fmt" + "reflect" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + namespaceutil "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/ref" + validate "github.com/rancher/rancher/pkg/resourcequota" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + quota "k8s.io/apiserver/pkg/quota/v1" + clientcache "k8s.io/client-go/tools/cache" +) + +/* +collectController is responsible for calculate the combined limit set on the project's Namespaces, +and setting this information in the project +*/ +type calculateLimitController struct { + projectLister v3.ProjectLister + projects v3.ProjectInterface + nsIndexer clientcache.Indexer + clusterName string +} + +func (c *calculateLimitController) calculateResourceQuotaUsed(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil { + return nil, nil + } + projectID := getProjectID(ns) + if projectID == "" { + return nil, nil + } + return nil, c.calculateProjectResourceQuota(projectID) +} + +func (c *calculateLimitController) calculateResourceQuotaUsedProject(key string, p *v3.Project) (runtime.Object, error) { + if p == nil || p.DeletionTimestamp != nil { + return nil, nil + } + + return nil, c.calculateProjectResourceQuota(fmt.Sprintf("%s:%s", c.clusterName, p.Name)) +} + +func (c *calculateLimitController) calculateProjectResourceQuota(projectID string) error { + projectNamespace, projectName := ref.Parse(projectID) + project, err := c.projectLister.Get(projectNamespace, projectName) + if err != nil || project.Spec.ResourceQuota == nil { + if errors.IsNotFound(err) { + // If Rancher is unaware of a project, we should ignore trying to calculate the project resource quota + // A non-existent project is likely managed by another Rancher (e.g. Hosted Rancher) + return nil + } + return err + } + + namespaces, err := c.nsIndexer.ByIndex(nsByProjectIndex, projectID) + if err != nil { + return err + } + nssResourceList := corev1.ResourceList{} + for _, n := range namespaces { + ns := n.(*corev1.Namespace) + if ns.DeletionTimestamp != nil { + continue + } + set, err := namespaceutil.IsNamespaceConditionSet(ns, ResourceQuotaValidatedCondition, true) + if err != nil { + return err + } + if !set { + continue + } + nsLimit, err := getNamespaceResourceQuotaLimit(ns) + if err != nil { + return err + } + nsResourceList, err := validate.ConvertLimitToResourceList(nsLimit) + if err != nil { + return err + } + nssResourceList = quota.Add(nssResourceList, nsResourceList) + } + limit, err := convertResourceListToLimit(nssResourceList) + if err != nil { + return err + } + + if reflect.DeepEqual(project.Spec.ResourceQuota.UsedLimit, limit) { + return nil + } + + toUpdate := project.DeepCopy() + toUpdate.Spec.ResourceQuota.UsedLimit = *limit + _, err = c.projects.Update(toUpdate) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_common.go new file mode 100644 index 0000000..4860555 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_common.go @@ -0,0 +1,273 @@ +package resourcequota + +import ( + "encoding/json" + + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" +) + +func convertResourceListToLimit(rList corev1.ResourceList) (*v32.ResourceQuotaLimit, error) { + converted, err := convert.EncodeToMap(rList) + if err != nil { + return nil, err + } + + convertedMap := map[string]string{} + for key, value := range converted { + convertedMap[key] = convert.ToString(value) + } + + toReturn := &v32.ResourceQuotaLimit{} + err = convert.ToObj(convertedMap, toReturn) + + return toReturn, err +} + +func convertResourceLimitResourceQuotaSpec(limit *v32.ResourceQuotaLimit) (*corev1.ResourceQuotaSpec, error) { + converted, err := convertProjectResourceLimitToResourceList(limit) + if err != nil { + return nil, err + } + quotaSpec := &corev1.ResourceQuotaSpec{ + Hard: converted, + } + return quotaSpec, err +} + +// convertProjectResourceLimitToResourceList tries to convert a Rancher-defined resource quota limit to its native Kubernetes notation. +func convertProjectResourceLimitToResourceList(limit *v32.ResourceQuotaLimit) (corev1.ResourceList, error) { + in, err := json.Marshal(limit) + if err != nil { + return nil, err + } + limitsMap := map[string]string{} + err = json.Unmarshal(in, &limitsMap) + if err != nil { + return nil, err + } + + limits := corev1.ResourceList{} + for key, value := range limitsMap { + var resourceName corev1.ResourceName + if val, ok := resourceQuotaConversion[key]; ok { + resourceName = corev1.ResourceName(val) + } else { + resourceName = corev1.ResourceName(key) + } + + resourceQuantity, err := resource.ParseQuantity(value) + if err != nil { + return nil, err + } + + limits[resourceName] = resourceQuantity + } + return limits, nil +} + +func convertContainerResourceLimitToResourceList(limit *v32.ContainerResourceLimit) (corev1.ResourceList, corev1.ResourceList, error) { + in, err := json.Marshal(limit) + if err != nil { + return nil, nil, err + } + limitsMap := map[string]string{} + err = json.Unmarshal(in, &limitsMap) + if err != nil { + return nil, nil, err + } + + if len(limitsMap) == 0 { + return nil, nil, nil + } + + limits := corev1.ResourceList{} + requests := corev1.ResourceList{} + for key, value := range limitsMap { + var resourceName corev1.ResourceName + request := false + if val, ok := limitRangerRequestConversion[key]; ok { + resourceName = corev1.ResourceName(val) + request = true + } else if val, ok := limitRangerLimitConversion[key]; ok { + resourceName = corev1.ResourceName(val) + } + if resourceName == "" { + continue + } + + resourceQuantity, err := resource.ParseQuantity(value) + if err != nil { + return nil, nil, err + } + if request { + requests[resourceName] = resourceQuantity + } else { + limits[resourceName] = resourceQuantity + } + + } + return requests, limits, nil +} + +var limitRangerRequestConversion = map[string]string{ + "requestsCpu": "cpu", + "requestsMemory": "memory", +} + +var limitRangerLimitConversion = map[string]string{ + "limitsCpu": "cpu", + "limitsMemory": "memory", +} + +var resourceQuotaConversion = map[string]string{ + "replicationControllers": "replicationcontrollers", + "configMaps": "configmaps", + "persistentVolumeClaims": "persistentvolumeclaims", + "servicesNodePorts": "services.nodeports", + "servicesLoadBalancers": "services.loadbalancers", + "requestsCpu": "requests.cpu", + "requestsMemory": "requests.memory", + "requestsStorage": "requests.storage", + "limitsCpu": "limits.cpu", + "limitsMemory": "limits.memory", +} + +func getNamespaceResourceQuota(ns *corev1.Namespace) string { + if ns.Annotations == nil { + return "" + } + return ns.Annotations[resourceQuotaAnnotation] +} + +func getNamespaceContainerDefaultResourceLimit(ns *corev1.Namespace) string { + if ns.Annotations == nil { + return "" + } + return ns.Annotations[limitRangeAnnotation] +} + +func getProjectResourceQuotaLimit(ns *corev1.Namespace, projectLister v3.ProjectLister) (*v32.ResourceQuotaLimit, string, error) { + projectID := getProjectID(ns) + if projectID == "" { + return nil, "", nil + } + projectNamespace, projectName := ref.Parse(projectID) + if projectName == "" { + return nil, "", nil + } + project, err := projectLister.Get(projectNamespace, projectName) + if err != nil || project.Spec.ResourceQuota == nil { + if errors.IsNotFound(err) { + // If Rancher is unaware of a project, we should ignore trying to get the resource quota limit + // A non-existent project is likely managed by another Rancher (e.g. Hosted Rancher) + return nil, "", nil + } + return nil, "", err + } + return &project.Spec.ResourceQuota.Limit, projectID, nil +} + +func getProjectNamespaceDefaultQuota(ns *corev1.Namespace, projectLister v3.ProjectLister) (*v32.NamespaceResourceQuota, error) { + projectID := getProjectID(ns) + if projectID == "" { + return nil, nil + } + projectNamespace, projectName := ref.Parse(projectID) + if projectName == "" { + return nil, nil + } + project, err := projectLister.Get(projectNamespace, projectName) + if err != nil || project.Spec.ResourceQuota == nil { + if errors.IsNotFound(err) { + // If Rancher is unaware of a project, we should ignore trying to get the default namespace quota + // A non-existent project is likely managed by another Rancher (e.g. Hosted Rancher) + return nil, nil + } + return nil, err + } + return project.Spec.NamespaceDefaultResourceQuota, nil +} + +func getProjectContainerDefaultLimit(ns *corev1.Namespace, projectLister v3.ProjectLister) (*v32.ContainerResourceLimit, error) { + projectID := getProjectID(ns) + if projectID == "" { + return nil, nil + } + projectNamespace, projectName := ref.Parse(projectID) + if projectName == "" { + return nil, nil + } + project, err := projectLister.Get(projectNamespace, projectName) + if err != nil { + if errors.IsNotFound(err) { + // If Rancher is unaware of a project, we should ignore trying to get the default container limit + // A non-existent project is likely managed by another Rancher (e.g. Hosted Rancher) + return nil, nil + } + return nil, err + } + return project.Spec.ContainerDefaultResourceLimit, nil +} + +func getNamespaceResourceQuotaLimit(ns *corev1.Namespace) (*v32.ResourceQuotaLimit, error) { + value := getNamespaceResourceQuota(ns) + if value == "" { + return nil, nil + } + var nsQuota v32.NamespaceResourceQuota + err := json.Unmarshal([]byte(convert.ToString(value)), &nsQuota) + if err != nil { + return nil, err + } + return &nsQuota.Limit, err +} + +func getNamespaceContainerResourceLimit(ns *corev1.Namespace) (*v32.ContainerResourceLimit, error) { + value := getNamespaceContainerDefaultResourceLimit(ns) + // rework after api framework change is done + // when annotation field is passed as null, the annotation should be removed + // instead of being updated with the null value + if value == "" || value == "null" { + return nil, nil + } + var nsLimit v32.ContainerResourceLimit + err := json.Unmarshal([]byte(convert.ToString(value)), &nsLimit) + if err != nil { + return nil, err + } + return &nsLimit, err +} + +func getProjectID(ns *corev1.Namespace) string { + if ns.Annotations != nil { + return ns.Annotations[projectIDAnnotation] + } + return "" +} + +func convertPodResourceLimitToLimitRangeSpec(podResourceLimit *v32.ContainerResourceLimit) (*corev1.LimitRangeSpec, error) { + request, limit, err := convertContainerResourceLimitToResourceList(podResourceLimit) + if err != nil { + return nil, err + } + if request == nil && limit == nil { + return nil, nil + } + + item := corev1.LimitRangeItem{ + Type: corev1.LimitTypeContainer, + Default: limit, + DefaultRequest: request, + } + limits := []corev1.LimitRangeItem{item} + limitRangeSpec := &corev1.LimitRangeSpec{ + Limits: limits, + } + return limitRangeSpec, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync.go new file mode 100644 index 0000000..72177e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync.go @@ -0,0 +1,502 @@ +package resourcequota + +import ( + "encoding/json" + "fmt" + "reflect" + "time" + + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + namespaceutil "github.com/rancher/rancher/pkg/namespace" + validate "github.com/rancher/rancher/pkg/resourcequota" + "github.com/rancher/rancher/pkg/utils" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + clientcache "k8s.io/client-go/tools/cache" +) + +const ( + projectIDAnnotation = "field.cattle.io/projectId" + resourceQuotaLabel = "resourcequota.management.cattle.io/default-resource-quota" + resourceQuotaAnnotation = "field.cattle.io/resourceQuota" + limitRangeAnnotation = "field.cattle.io/containerDefaultResourceLimit" + ResourceQuotaValidatedCondition = "ResourceQuotaValidated" + ResourceQuotaInitCondition = "ResourceQuotaInit" +) + +/* +SyncController takes care of creating Kubernetes resource quota based on the resource limits +defined in namespace.resourceQuota +*/ +type SyncController struct { + ProjectLister v3.ProjectLister + Namespaces v1.NamespaceInterface + ResourceQuotas v1.ResourceQuotaInterface + ResourceQuotaLister v1.ResourceQuotaLister + LimitRange v1.LimitRangeInterface + LimitRangeLister v1.LimitRangeLister + NsIndexer clientcache.Indexer +} + +func (c *SyncController) syncResourceQuota(key string, ns *corev1.Namespace) (runtime.Object, error) { + if ns == nil || ns.DeletionTimestamp != nil { + return nil, nil + } + + _, err := c.CreateResourceQuota(ns) + if err != nil { + return nil, err + } + + return nil, c.createLimitRange(ns) +} + +func (c *SyncController) createLimitRange(ns *corev1.Namespace) error { + existing, err := c.getExistingLimitRange(ns) + if err != nil { + return err + } + + limitRangeSpec, err := c.getResourceLimitToUpdate(ns) + if err != nil { + return err + } + + operation := "none" + if existing == nil { + if limitRangeSpec != nil { + operation = "create" + } + } else { + if limitRangeSpec == nil { + operation = "delete" + } else if limitsChanged(existing.Spec.Limits, limitRangeSpec.Limits) { + operation = "update" + } + } + + switch operation { + case "create": + return c.createDefaultLimitRange(ns, limitRangeSpec) + case "update": + return c.updateDefaultLimitRange(existing, limitRangeSpec) + case "delete": + return c.deleteDefaultLimitRange(existing) + } + + return nil +} + +func limitsChanged(existing []corev1.LimitRangeItem, toUpdate []corev1.LimitRangeItem) bool { + if len(existing) != len(toUpdate) { + return true + } + if len(existing) == 0 || len(toUpdate) == 0 { + return true + } + if !apiequality.Semantic.DeepEqual(existing[0].DefaultRequest, toUpdate[0].DefaultRequest) { + return true + } + + if !apiequality.Semantic.DeepEqual(existing[0].Default, toUpdate[0].Default) { + return true + } + return false +} + +func (c *SyncController) CreateResourceQuota(ns *corev1.Namespace) (runtime.Object, error) { + existing, err := c.getExistingResourceQuota(ns) + if err != nil { + return ns, err + } + + requestedQuotaLimit, newQuotaSpec, err := c.deriveRequestedResourceQuota(ns) + if err != nil { + return ns, err + } + + operation := "none" + if existing == nil { + if newQuotaSpec != nil && len(newQuotaSpec.Hard) > 0 { + operation = "create" + } + } else { + if newQuotaSpec == nil || len(newQuotaSpec.Hard) == 0 { + operation = "delete" + } else if !apiequality.Semantic.DeepEqual(existing.Spec.Hard, newQuotaSpec.Hard) { + operation = "update" + } + } + + var updated *corev1.Namespace + var operationErr error + switch operation { + case "create": + isFit, updated, exceeded, err := c.validateAndSetNamespaceQuota(ns, &v32.NamespaceResourceQuota{Limit: *requestedQuotaLimit}) + if err != nil { + return updated, err + } + if !isFit { + // Create a quota with zeros only for overused resources. + limit, err := zeroOutResourceQuotaLimit(requestedQuotaLimit, exceeded) + if err != nil { + return updated, err + } + + newQuotaSpec, err = convertResourceLimitResourceQuotaSpec(limit) + if err != nil { + return updated, err + } + } + operationErr = c.createResourceQuota(ns, newQuotaSpec) + case "update": + isFit, upd, _, err := c.validateAndSetNamespaceQuota(ns, &v32.NamespaceResourceQuota{Limit: *requestedQuotaLimit}) + if err != nil { + return upd, err + } + if !isFit { + updated = upd + break + } + operationErr = c.updateResourceQuota(existing, newQuotaSpec) + case "delete": + updatedNs := ns.DeepCopy() + delete(updatedNs.Annotations, resourceQuotaAnnotation) + updatedNs, err = c.Namespaces.Update(updatedNs) + if err != nil { + return updatedNs, err + } + operationErr = c.deleteResourceQuota(existing) + } + + if updated == nil { + updated = ns + } + + if operationErr != nil { + logrus.Errorf("Failed to perform operation %q on namespace %q: %v", operation, ns.Name, operationErr) + return updated, operationErr + } + + set, err := namespaceutil.IsNamespaceConditionSet(ns, ResourceQuotaInitCondition, true) + if err != nil || set { + return updated, err + } + toUpdate := updated.DeepCopy() + namespaceutil.SetNamespaceCondition(toUpdate, time.Second*1, ResourceQuotaInitCondition, true, "") + return c.Namespaces.Update(toUpdate) +} + +func (c *SyncController) updateResourceQuota(quota *corev1.ResourceQuota, spec *corev1.ResourceQuotaSpec) error { + toUpdate := quota.DeepCopy() + toUpdate.Spec = *spec + logrus.Infof("Updating default resource quota for namespace %v", toUpdate.Namespace) + _, err := c.ResourceQuotas.Update(toUpdate) + return err +} + +func (c *SyncController) updateDefaultLimitRange(limitRange *corev1.LimitRange, spec *corev1.LimitRangeSpec) error { + toUpdate := limitRange.DeepCopy() + toUpdate.Spec = *spec + logrus.Infof("Updating default limit range for namespace %v", toUpdate.Namespace) + _, err := c.LimitRange.Update(toUpdate) + return err +} + +func (c *SyncController) deleteResourceQuota(quota *corev1.ResourceQuota) error { + logrus.Infof("Deleting default resource quota for namespace %v", quota.Namespace) + return c.ResourceQuotas.DeleteNamespaced(quota.Namespace, quota.Name, &metav1.DeleteOptions{}) +} + +func (c *SyncController) deleteDefaultLimitRange(limitRange *corev1.LimitRange) error { + logrus.Infof("Deleting limit range %v for namespace %v", limitRange.Name, limitRange.Namespace) + return c.LimitRange.DeleteNamespaced(limitRange.Namespace, limitRange.Name, &metav1.DeleteOptions{}) +} + +func (c *SyncController) getExistingResourceQuota(ns *corev1.Namespace) (*corev1.ResourceQuota, error) { + set := labels.Set(map[string]string{resourceQuotaLabel: "true"}) + quota, err := c.ResourceQuotaLister.List(ns.Name, set.AsSelector()) + if err != nil { + return nil, err + } + if len(quota) == 0 { + return nil, nil + } + return quota[0], nil +} + +func (c *SyncController) getExistingLimitRange(ns *corev1.Namespace) (*corev1.LimitRange, error) { + set := labels.Set(map[string]string{resourceQuotaLabel: "true"}) + limitRanger, err := c.LimitRangeLister.List(ns.Name, set.AsSelector()) + if err != nil { + return nil, err + } + if len(limitRanger) == 0 { + return nil, nil + } + return limitRanger[0], nil +} + +// deriveRequestedResourceQuota tries to obtain the new namespace's resource quota limit and its quota spec. +// It derives it by looking up the requested quota limit. If it's not found, then it looks up the project's default +// quota for a namespace. If it's also not found, then the method returns nil. +// If only the requested quota limit exists, then nil returned (no limits). +// If only the project's default namespace limit exists, then it is returned. +// If both exist, then the two limits are merged, with requested limits having priority for overlapping resources. +func (c *SyncController) deriveRequestedResourceQuota(ns *corev1.Namespace) (*v32.ResourceQuotaLimit, *corev1.ResourceQuotaSpec, error) { + requested, err := getNamespaceResourceQuotaLimit(ns) + if err != nil { + return nil, nil, err + } + + defaultQuota, err := getProjectNamespaceDefaultQuota(ns, c.ProjectLister) + if err != nil { + return nil, nil, err + } + + var quotaLimit *v32.ResourceQuotaLimit + + if requested != nil && defaultQuota == nil { + return nil, nil, nil + } else if requested == nil && defaultQuota != nil { + quotaLimit = &defaultQuota.Limit + } else if requested != nil && defaultQuota != nil { + quotaLimit, err = completeQuota(requested, &defaultQuota.Limit) + if err != nil { + return nil, nil, err + } + } else { + // This use case arises when users create a namespace outside any projects. + return nil, nil, nil + } + + newQuotaSpec, err := convertResourceLimitResourceQuotaSpec(quotaLimit) + if err != nil { + return nil, nil, err + } + return quotaLimit, newQuotaSpec, nil +} + +func (c *SyncController) createResourceQuota(ns *corev1.Namespace, spec *corev1.ResourceQuotaSpec) error { + resourceQuota := &corev1.ResourceQuota{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "default-", + Namespace: ns.Name, + Labels: map[string]string{resourceQuotaLabel: "true"}, + }, + Spec: *spec, + } + logrus.Infof("Creating default resource quota for namespace %v", ns.Name) + _, err := c.ResourceQuotas.Create(resourceQuota) + return err +} + +func (c *SyncController) createDefaultLimitRange(ns *corev1.Namespace, spec *corev1.LimitRangeSpec) error { + limitRange := &corev1.LimitRange{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "default-", + Namespace: ns.Name, + Labels: map[string]string{resourceQuotaLabel: "true"}, + }, + Spec: *spec, + } + logrus.Infof("Creating limit range %v for namespace %v", limitRange.Spec, ns.Name) + _, err := c.LimitRange.Create(limitRange) + return err +} + +func (c *SyncController) validateAndSetNamespaceQuota(ns *corev1.Namespace, quotaToUpdate *v32.NamespaceResourceQuota) (bool, *corev1.Namespace, corev1.ResourceList, error) { + if ns == nil || ns.DeletionTimestamp != nil { + return true, ns, nil, nil + } + + // get project limit + projectLimit, projectID, err := getProjectResourceQuotaLimit(ns, c.ProjectLister) + if err != nil { + return false, ns, nil, err + } + + if projectLimit == nil { + return true, ns, nil, err + } + + updatedNs := ns.DeepCopy() + if quotaToUpdate != nil { + if updatedNs.Annotations == nil { + updatedNs.Annotations = map[string]string{} + } + b, err := json.Marshal(quotaToUpdate) + if err != nil { + return false, ns, nil, err + } + updatedNs.Annotations[resourceQuotaAnnotation] = string(b) + updatedNs, err = c.Namespaces.Update(updatedNs) + if err != nil { + return false, updatedNs, nil, err + } + } + + // validate resource quota + mu := validate.GetProjectLock(projectID) + mu.Lock() + defer mu.Unlock() + + // Get other namespaces' limits. + nsLimits, err := c.getNamespacesLimits(ns, projectID) + if err != nil { + return false, updatedNs, nil, err + } + isFit, exceeded, err := validate.IsQuotaFit("aToUpdate.Limit, nsLimits, projectLimit) + if err != nil { + return false, updatedNs, nil, err + } + + var msg string + if !isFit && exceeded != nil { + msg = fmt.Sprintf("Resource quota [%v] exceeds project limit", utils.FormatResourceList(exceeded)) + } + + validated, err := c.setValidated(updatedNs, isFit, msg) + + return isFit, validated, exceeded, err +} + +func (c *SyncController) getNamespacesLimits(ns *v1.Namespace, projectID string) ([]*v32.ResourceQuotaLimit, error) { + objects, err := c.NsIndexer.ByIndex(nsByProjectIndex, projectID) + if err != nil { + return nil, err + } + var nsLimits []*v32.ResourceQuotaLimit + for _, o := range objects { + other := o.(*corev1.Namespace) + // Skip itself. + if other.Name == ns.Name { + continue + } + nsLimit, err := getNamespaceResourceQuotaLimit(other) + if err != nil { + return nil, err + } + nsLimits = append(nsLimits, nsLimit) + } + return nsLimits, nil +} + +func (c *SyncController) setValidated(ns *corev1.Namespace, value bool, msg string) (*corev1.Namespace, error) { + toUpdate := ns.DeepCopy() + if err := namespaceutil.SetNamespaceCondition(toUpdate, time.Second*1, ResourceQuotaValidatedCondition, value, msg); err != nil { + return ns, err + } + return c.Namespaces.Update(toUpdate) +} + +func (c *SyncController) getResourceLimitToUpdate(ns *corev1.Namespace) (*corev1.LimitRangeSpec, error) { + nsLimit, err := getNamespaceContainerResourceLimit(ns) + if err != nil { + return nil, err + } + projectLimit, err := getProjectContainerDefaultLimit(ns, c.ProjectLister) + if err != nil { + return nil, err + } + + // rework after api framework change is done + // when annotation field is passed as null, the annotation should be removed + // instead of being updated with the null value + var updatedLimit *v32.ContainerResourceLimit + if nsLimit != nil { + // check if fields need to be removed or set + // based on the default quota + updatedLimit, err = completeLimit(nsLimit, projectLimit) + if err != nil { + return nil, err + } + } + + if updatedLimit != nil { + return convertPodResourceLimitToLimitRangeSpec(updatedLimit) + } + if nsLimit != nil { + return convertPodResourceLimitToLimitRangeSpec(nsLimit) + } + if projectLimit != nil { + return convertPodResourceLimitToLimitRangeSpec(projectLimit) + } + return nil, nil +} + +func completeQuota(requestedQuota *v32.ResourceQuotaLimit, defaultQuota *v32.ResourceQuotaLimit) (*v32.ResourceQuotaLimit, error) { + if requestedQuota == nil || defaultQuota == nil { + return nil, nil + } + requestedQuotaMap, err := convert.EncodeToMap(requestedQuota) + if err != nil { + return nil, err + } + newLimitMap, err := convert.EncodeToMap(defaultQuota) + if err != nil { + return nil, err + } + for key, value := range requestedQuotaMap { + // Only override the values for keys (resources) that actually exist in the project quota. + if newLimitMap[key] != nil { + newLimitMap[key] = value + } + } + + toReturn := &v32.ResourceQuotaLimit{} + err = convert.ToObj(newLimitMap, toReturn) + return toReturn, err +} + +func completeLimit(existingLimit *v32.ContainerResourceLimit, defaultLimit *v32.ContainerResourceLimit) (*v32.ContainerResourceLimit, error) { + if defaultLimit == nil { + return nil, nil + } + existingLimitMap, err := convert.EncodeToMap(existingLimit) + if err != nil { + return nil, err + } + newLimitMap, err := convert.EncodeToMap(defaultLimit) + if err != nil { + return nil, err + } + for key, value := range existingLimitMap { + if _, ok := newLimitMap[key]; ok { + newLimitMap[key] = value + } + } + + if reflect.DeepEqual(existingLimitMap, newLimitMap) { + return nil, nil + } + + newLimit := &v32.ContainerResourceLimit{} + err = convert.ToObj(newLimitMap, newLimit) + return newLimit, err +} + +// zeroOutResourceQuotaLimit takes a resource quota limit and a list of resources exceeding the quota, +// and returns a new quota limit with exceeded resources zeroed out. +func zeroOutResourceQuotaLimit(limit *v32.ResourceQuotaLimit, exceeded corev1.ResourceList) (*v32.ResourceQuotaLimit, error) { + limitMap, err := convert.EncodeToMap(limit) + if err != nil { + return nil, err + } + + for k := range exceeded { + resource := string(k) + limitMap[resource] = "0" + } + + toReturn := &v32.ResourceQuotaLimit{} + err = convert.ToObj(limitMap, toReturn) + return toReturn, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync_test.go new file mode 100644 index 0000000..aae9109 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_sync_test.go @@ -0,0 +1,109 @@ +package resourcequota + +import ( + "reflect" + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/resource" +) + +func TestLimitsChanged(t *testing.T) { + + tests := []struct { + name string + existing []corev1.LimitRangeItem + toUpdate []corev1.LimitRangeItem + expected bool + }{ + { + name: "limitsChange using semantic.DeepEqual", + existing: []corev1.LimitRangeItem{ + { + Type: corev1.LimitTypePod, + Default: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewQuantity(1, resource.DecimalSI), + }, + DefaultRequest: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewMilliQuantity(1000, resource.DecimalSI), + }, + }, + }, + toUpdate: []corev1.LimitRangeItem{ + { + Type: corev1.LimitTypePod, + Default: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewQuantity(1, resource.DecimalSI), + }, + DefaultRequest: corev1.ResourceList{ + corev1.ResourceCPU: *resource.NewQuantity(1, resource.DecimalSI), + }, + }, + }, + expected: false, + }, + } + + for _, tt := range tests { + result := limitsChanged(tt.existing, tt.toUpdate) + assert.Equal(t, tt.expected, result) + } +} + +func TestSemanticDeepEqual(t *testing.T) { + + tests := []struct { + name string + method func(x, y interface{}) bool + src *v32.ResourceQuotaLimit + dst *v32.ResourceQuotaLimit + expected bool + }{ + { + name: "compare ResourceQuota using reflect.DeepEqual", + method: reflect.DeepEqual, + src: &v32.ResourceQuotaLimit{ + Pods: "30", + RequestsCPU: "1000m", + }, + dst: &v32.ResourceQuotaLimit{ + Pods: "30", + RequestsCPU: "1", + }, + expected: false, + }, + { + name: "compare ResourceQuota using semantic.DeepEqual", + method: apiequality.Semantic.DeepEqual, + src: &v32.ResourceQuotaLimit{ + Pods: "30", + RequestsCPU: "1000m", + }, + dst: &v32.ResourceQuotaLimit{ + Pods: "30", + RequestsCPU: "1", + }, + expected: true, + }, + } + + for _, tt := range tests { + srcResourceList, err := convertProjectResourceLimitToResourceList(tt.src) + if err != nil { + t.Error(err) + } + + dstResourceList, err := convertProjectResourceLimitToResourceList(tt.dst) + if err != nil { + t.Error(err) + } + + result := tt.method(srcResourceList, dstResourceList) + assert.Equal(t, tt.expected, result) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_validate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_validate.go new file mode 100644 index 0000000..f849570 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/resourcequota/resource_quota_validate.go @@ -0,0 +1,37 @@ +package resourcequota + +import ( + "fmt" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + clientcache "k8s.io/client-go/tools/cache" +) + +/* +reconcile controller listens on project updates, and enqueues the namespaces of the project +so they get a chance to reconcile the resource quotas +*/ +type reconcileController struct { + namespaces v1.NamespaceInterface + nsIndexer clientcache.Indexer +} + +func (r *reconcileController) reconcileNamespaces(key string, p *v3.Project) (runtime.Object, error) { + if p == nil || p.DeletionTimestamp != nil { + return nil, nil + } + projectID := fmt.Sprintf("%s:%s", p.Namespace, p.Name) + namespaces, err := r.nsIndexer.ByIndex(nsByProjectIndex, projectID) + if err != nil { + return nil, err + } + + for _, n := range namespaces { + ns := n.(*corev1.Namespace) + r.namespaces.Controller().Enqueue("", ns.Name) + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/secret/secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/secret/secret.go new file mode 100644 index 0000000..40cb9b6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/secret/secret.go @@ -0,0 +1,309 @@ +package secret + +import ( + "context" + "fmt" + "reflect" + "strings" + + "k8s.io/apimachinery/pkg/runtime" + + "github.com/rancher/norman/controller" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// SecretController listens for secret CUD in management API +// and propagates the changes to all corresponding namespaces in cluster API + +// NamespaceController listens to cluster namespace events, +// reads secrets from the management namespace of corresponding project, +// and creates the secrets in the cluster namespace + +const ( + projectIDLabel = "field.cattle.io/projectId" + create = "create" + update = "update" + projectNamespaceAnnotation = "management.cattle.io/system-namespace" + userSecretAnnotation = "secret.user.cattle.io/secret" +) + +type Controller struct { + secrets v1.SecretInterface + secretLister v1.SecretLister + clusterNamespaceLister v1.NamespaceLister + managementNamespaceLister v1.NamespaceLister + projectLister v3.ProjectLister + clusterName string +} + +func Register(ctx context.Context, cluster *config.UserContext) { + starter := cluster.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, cluster) + return nil + }) + + projectLister := cluster.Management.Management.Projects("").Controller().Lister() + secrets := cluster.Management.Core.Secrets("") + secrets.AddHandler(ctx, "secret-deferred", func(key string, obj *corev1.Secret) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + + _, err := projectLister.Get(cluster.ClusterName, obj.Namespace) + if errors.IsNotFound(err) { + return obj, nil + } else if err != nil { + return obj, err + } + + if !strings.HasPrefix(obj.Name, "default-token-") { + return obj, starter() + } + + return obj, nil + }) +} + +func registerDeferred(ctx context.Context, cluster *config.UserContext) { + clusterSecretsClient := cluster.Core.Secrets("") + s := &Controller{ + secrets: clusterSecretsClient, + secretLister: clusterSecretsClient.Controller().Lister(), + clusterNamespaceLister: cluster.Core.Namespaces("").Controller().Lister(), + managementNamespaceLister: cluster.Management.Core.Namespaces("").Controller().Lister(), + projectLister: cluster.Management.Management.Projects(cluster.ClusterName).Controller().Lister(), + clusterName: cluster.ClusterName, + } + + n := &NamespaceController{ + clusterSecretsClient: clusterSecretsClient, + clusterSecretsLister: clusterSecretsClient.Controller().Lister(), + managementSecrets: cluster.Management.Core.Secrets("").Controller().Lister(), + } + cluster.Core.Namespaces("").AddHandler(ctx, "secretsController", n.sync) + + sync := v1.NewSecretLifecycleAdapter(fmt.Sprintf("secretsController_%s", cluster.ClusterName), true, + cluster.Management.Core.Secrets(""), s) + + cluster.Management.Core.Secrets("").AddHandler(ctx, "secretsController", func(key string, obj *corev1.Secret) (runtime.Object, error) { + if obj == nil { + logrus.Tracef("secretsController: AddHandler: obj is nil, calling sync") + return sync(key, nil) + } + if !controller.ObjectInCluster(cluster.ClusterName, obj) { + logrus.Tracef("secretsController: AddHandler: obj [%s] is not in cluster [%s], returning nil", obj.Name, cluster.ClusterName) + return nil, nil + } + + if obj.Type == corev1.SecretTypeServiceAccountToken { + logrus.Tracef("secretsController: AddHandler: obj [%s] is Service Account token, skipping", obj.Name) + return nil, nil + } + + if obj.Labels != nil { + if obj.Labels["cattle.io/creator"] == "norman" { + logrus.Tracef("secretsController: AddHandler: obj [%s] labels in [%s] contain cattle.io/creator=norman, calling sync", obj.Name, cluster.ClusterName) + return sync(key, obj) + } + } + + return nil, nil + }) +} + +type NamespaceController struct { + clusterSecretsClient v1.SecretInterface + clusterSecretsLister v1.SecretLister + managementSecrets v1.SecretLister +} + +func (n *NamespaceController) sync(key string, obj *corev1.Namespace) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + logrus.Tracef("secretsController: sync called for key [%s] in namespace [%s]", key, obj.Name) + // field.cattle.io/projectId value is : + logrus.Tracef("secretsController: sync: key [%s], obj.Annotations[projectIDLabel]: [%s]", key, obj.Annotations[projectIDLabel]) + if obj.Annotations[projectIDLabel] != "" { + parts := strings.Split(obj.Annotations[projectIDLabel], ":") + if len(parts) == 2 { + if parts[1] == "" { + logrus.Debugf("[NamspaceController|sync] empty project name found in obj.Annotations[projectIDLabel] for cluster: %s", parts[0]) + return nil, nil + } + // on the management side, secret's namespace name equals to project name + secrets, err := n.managementSecrets.List(parts[1], labels.NewSelector()) + if err != nil { + return nil, err + } + logrus.Tracef("secretsController: sync: length of secrets for [%s] in namespace [%s] is %d", parts[1], obj.Name, len(secrets)) + for _, secret := range secrets { + // skip service account token secrets + if secret.Type == corev1.SecretTypeServiceAccountToken { + logrus.Tracef("secretsController: AddHandler: secret [%s] is Service Account token, skipping", secret.Name) + continue + } + namespacedSecret := getNamespacedSecret(secret, obj.Name) + if _, err := n.clusterSecretsLister.Get(namespacedSecret.Namespace, namespacedSecret.Name); err == nil { + continue + } + logrus.Infof("Creating secret [%s] into namespace [%s]", namespacedSecret.Name, obj.Name) + _, err := n.clusterSecretsClient.Create(namespacedSecret) + if err != nil && !errors.IsAlreadyExists(err) { + return nil, err + } + } + } + } + return nil, nil +} + +func (s *Controller) Create(obj *corev1.Secret) (runtime.Object, error) { + logrus.Tracef("secretsController: Create called for [%s]", obj.Name) + return nil, s.createOrUpdate(obj, create) +} + +func (s *Controller) Updated(obj *corev1.Secret) (runtime.Object, error) { + logrus.Tracef("secretsController: Updated called for [%s]", obj.Name) + return nil, s.createOrUpdate(obj, update) +} + +func (s *Controller) Remove(obj *corev1.Secret) (runtime.Object, error) { + logrus.Tracef("secretsController: Remove called for [%s]", obj.Name) + clusterNamespaces, err := s.getClusterNamespaces(obj) + if err != nil { + return nil, err + } + + for _, namespace := range clusterNamespaces { + logrus.Infof("Deleting secret [%s] in namespace [%s]", obj.Name, namespace.Name) + if err := s.secrets.DeleteNamespaced(namespace.Name, obj.Name, &metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return nil, err + } + } + return nil, nil +} + +func (s *Controller) getClusterNamespaces(obj *corev1.Secret) ([]*corev1.Namespace, error) { + logrus.Tracef("secretsController: getClusterNamespaces called for [%s]", obj.Name) + var toReturn []*corev1.Namespace + projectNamespace, err := s.managementNamespaceLister.Get("", obj.Namespace) + if err != nil { + if errors.IsNotFound(err) { + logrus.Warnf("Project namespace [%s] can't be found", obj.Namespace) + return toReturn, nil + } + return toReturn, err + } + if projectNamespace.Annotations == nil { + return toReturn, nil + } + if val, ok := projectNamespace.Annotations[projectNamespaceAnnotation]; !(ok && val == "true") { + return toReturn, nil + } + + // Ignore projects from other clusters. Project namespace name = project name, so use it to locate the project + _, err = s.projectLister.Get(s.clusterName, projectNamespace.Name) + if err != nil { + if errors.IsNotFound(err) { + return toReturn, nil + } + return toReturn, err + } + + namespaces, err := s.clusterNamespaceLister.List("", labels.NewSelector()) + if err != nil { + return toReturn, err + } + // system project namespace name == project.Name + projectID := obj.Namespace + + for _, namespace := range namespaces { + parts := strings.Split(namespace.Annotations[projectIDLabel], ":") + if len(parts) == 2 && parts[1] == projectID { + toReturn = append(toReturn, namespace) + } + } + return toReturn, nil +} + +func (s *Controller) createOrUpdate(obj *corev1.Secret, action string) error { + logrus.Tracef("secretsController: createOrUpdate called for [%s]", obj.Name) + if obj.Annotations[projectIDLabel] != "" { + parts := strings.Split(obj.Annotations[projectIDLabel], ":") + if len(parts) == 2 { + if parts[0] != s.clusterName { + return nil + } + } + } + clusterNamespaces, err := s.getClusterNamespaces(obj) + if err != nil { + return err + } + for _, namespace := range clusterNamespaces { + if !namespace.DeletionTimestamp.IsZero() { + continue + } + // copy the secret into namespace + namespacedSecret := getNamespacedSecret(obj, namespace.Name) + switch action { + case create: + if _, err := s.secretLister.Get(namespacedSecret.Namespace, namespacedSecret.Name); err == nil { + continue + } + logrus.Infof("Copying secret [%s] into namespace [%s]", namespacedSecret.Name, namespace.Name) + _, err := s.secrets.Create(namespacedSecret) + if err != nil && !errors.IsAlreadyExists(err) { + return err + } + case update: + if existing, err := s.secretLister.Get(namespacedSecret.Namespace, namespacedSecret.Name); err == nil && + reflect.DeepEqual(existing.Data, namespacedSecret.Data) { + continue + } + logrus.Infof("Updating secret [%s] into namespace [%s]", namespacedSecret.Name, namespace.Name) + _, err := s.secrets.Update(namespacedSecret) + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + logrus.Infof("Updating secret [%s] returned NotFound, creating secret [%s] into namespace [%s]", namespacedSecret.Name, namespacedSecret.Name, namespace.Name) + _, err := s.secrets.Create(namespacedSecret) + if err != nil { + return err + } + } + } + } + + return nil +} + +func getNamespacedSecret(obj *corev1.Secret, namespace string) *corev1.Secret { + namespacedSecret := &corev1.Secret{} + namespacedSecret.Name = obj.Name + namespacedSecret.Kind = obj.Kind + namespacedSecret.Data = obj.Data + namespacedSecret.StringData = obj.StringData + namespacedSecret.Namespace = namespace + namespacedSecret.Type = obj.Type + namespacedSecret.Annotations = make(map[string]string) + namespacedSecret.Labels = make(map[string]string) + copyMap(namespacedSecret.Annotations, obj.Annotations) + copyMap(namespacedSecret.Labels, obj.Labels) + namespacedSecret.Annotations[userSecretAnnotation] = "true" + return namespacedSecret +} + +func copyMap(dst map[string]string, src map[string]string) { + for k, v := range src { + dst[k] = v + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/snapshotbackpopulate/snapshotbackpopulate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/snapshotbackpopulate/snapshotbackpopulate.go new file mode 100644 index 0000000..c0205e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/snapshotbackpopulate/snapshotbackpopulate.go @@ -0,0 +1,361 @@ +package snapshotbackpopulate + +import ( + "context" + "encoding/json" + "fmt" + "regexp" + "strings" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + cluster2 "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + provisioningcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkev1controllers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +var ( + configMapNames = map[string]bool{ + "k3s-etcd-snapshots": true, + "rke2-etcd-snapshots": true, + } + InvalidKeyChars = regexp.MustCompile(`[^-.a-zA-Z0-9]`) +) + +const ( + StorageAnnotationKey = "etcdsnapshot.rke.io/storage" + SnapshotNameKey = "etcdsnapshot.rke.io/snapshot-file-name" + SnapshotBackpopulateReconciledKey = "etcdsnapshot.rke.io/snapshotbackpopulate-reconciled" + StorageS3 = "s3" + StorageLocal = "local" +) + +type handler struct { + clusterName string + clusterNamespace string + clusterCache provisioningcontrollers.ClusterCache + clusters provisioningcontrollers.ClusterClient + etcdSnapshotCache rkev1controllers.ETCDSnapshotCache + etcdSnapshots rkev1controllers.ETCDSnapshotClient + machineCache capicontrollers.MachineCache + activeConfigMap string + v1ClusterName string +} + +// Register sets up the v2provisioning snapshot backpopulate controller. This controller is responsible for monitoring +// the downstream etcd-snapshots configmap and backpopulating snapshots into etcd snapshot objects in the management cluster. +func Register(ctx context.Context, userContext *config.UserContext) { + h := handler{ + clusterName: userContext.ClusterName, + clusterCache: userContext.Management.Wrangler.Provisioning.Cluster().Cache(), + clusters: userContext.Management.Wrangler.Provisioning.Cluster(), + etcdSnapshotCache: userContext.Management.Wrangler.RKE.ETCDSnapshot().Cache(), + etcdSnapshots: userContext.Management.Wrangler.RKE.ETCDSnapshot(), + machineCache: userContext.Management.Wrangler.CAPI.Machine().Cache(), + } + + userContext.Core.ConfigMaps("kube-system").Controller().AddHandler(ctx, "snapshotbackpopulate", h.OnChange) + relatedresource.Watch(ctx, "snapshot-reconcile-trigger", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if snapshot, ok := obj.(*rkev1.ETCDSnapshot); ok && snapshot.Spec.ClusterName == h.v1ClusterName && h.activeConfigMap != "" { + return []relatedresource.Key{{ + Namespace: "kube-system", + Name: h.activeConfigMap, + }}, nil + } + return nil, nil + }, userContext.Core.ConfigMaps("kube-system").Controller(), userContext.Management.Wrangler.RKE.ETCDSnapshot()) +} + +func (h *handler) OnChange(key string, configMap *corev1.ConfigMap) (runtime.Object, error) { + if configMap == nil { + return nil, nil + } + + if configMap.Namespace != "kube-system" || !configMapNames[configMap.Name] { + return configMap, nil + } + + if h.activeConfigMap == "" { + h.activeConfigMap = configMap.Name + } + + clusters, err := h.clusterCache.GetByIndex(cluster2.ByCluster, h.clusterName) + if err != nil || len(clusters) != 1 { + return configMap, fmt.Errorf("error while retrieving cluster %s from cache via index: %w", h.clusterName, err) + } + + cluster := clusters[0] + + if h.v1ClusterName == "" { + h.v1ClusterName = cluster.Name + } + + logrus.Infof("[snapshotbackpopulate] rkecluster %s/%s: processing configmap %s/%s", cluster.Namespace, cluster.Name, configMap.Namespace, configMap.Name) + + actualEtcdSnapshots := h.configMapToSnapshots(configMap, cluster) + + ls, err := labels.Parse(fmt.Sprintf("%s=%s", capr.ClusterNameLabel, cluster.Name)) + if err != nil { + return configMap, err + } + + currentEtcdSnapshots, err := h.etcdSnapshotCache.List(cluster.Namespace, ls) + if err != nil { + return configMap, fmt.Errorf("error while listing existing etcd snapshots for cluster %s: %w", cluster.Name, err) + } + + // currentEtcdSnapshotsToKeep is a map of etcd snapshots snapshot objects we have retrieved from the management cluster. + currentEtcdSnapshotsToKeep := map[string]*rkev1.ETCDSnapshot{} + + // iterate over the current etcd snapshots objects retrieved from the management cluster + // if snapshot object is not found in the etcd snapshot configmap, mark it missing. if it is a local snapshot + // and no machine can be found for it, go ahead and delete it. + // if the snapshot object is found in the configmap, add it to the currentEtcdSnapshotsToKeep for reconciliation + for _, existingSnapshotCR := range currentEtcdSnapshots { + storageLocation, ok := existingSnapshotCR.GetAnnotations()[StorageAnnotationKey] + if !ok { + storageLocation = StorageLocal + if existingSnapshotCR.SnapshotFile.NodeName == StorageS3 { + storageLocation = StorageS3 + } + } + snapshotKey := existingSnapshotCR.SnapshotFile.Name + storageLocation + // check to see if the snapshot CR we have is found in the etcd-snapshots configmap, and if it is not found in the configmap, mark it as missing + if _, ok := actualEtcdSnapshots[snapshotKey]; !ok { + // the snapshot custom resource we are processing does not exist in the configmap + if storageLocation != StorageS3 { + // check to make sure the machine actually exists for the snapshot + var listSuccessful bool + var machine *capi.Machine + + if existingSnapshotCR.Labels[capr.MachineIDLabel] == "" { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s was missing machine ID label: %s", cluster.Namespace, cluster.Name, existingSnapshotCR.Namespace, existingSnapshotCR.Name, capr.MachineIDLabel) + // If the machineID label was not set, fall back to looking up the machine by node name, as this may be a snapshot from an earlier version of Rancher that created local snapshots using the snapshotbackpopulate controller, which means the snapshot should not have the machine ID label. + listSuccessful, machine, err = capr.GetMachineFromNode(h.machineCache, existingSnapshotCR.SnapshotFile.NodeName, cluster) + } else { + listSuccessful, machine, err = capr.GetMachineByID(h.machineCache, existingSnapshotCR.Labels[capr.MachineIDLabel], cluster.Namespace, cluster.Name) + } + if listSuccessful && machine == nil && err != nil { + // delete the CR because we don't have a corresponding machine for it + logrus.Infof("[snapshotbackpopulate] rkecluster %s/%s: deleting snapshot %s as corresponding machine (ID: %s) was not found", cluster.Namespace, cluster.Name, existingSnapshotCR.Name, existingSnapshotCR.Labels[capr.MachineIDLabel]) + if err := h.etcdSnapshots.Delete(existingSnapshotCR.Namespace, existingSnapshotCR.Name, &metav1.DeleteOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return configMap, err + } + } + continue + } + } + // indicate that it should be OK to delete the etcd snapshot object + // don't delete the snapshots here because our configmap can be outdated. we will reconcile based on the system-agent output via the periodic output + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: updating status missing=true on etcd snapshot %s/%s as it was not found in the actual snapshot config map", cluster.Namespace, cluster.Name, existingSnapshotCR.Namespace, existingSnapshotCR.Name) + logrus.Tracef("[snapshotbackpopulate] rkecluster %s/%s: etcd snapshot was %s/%s: %v", cluster.Namespace, cluster.Name, existingSnapshotCR.Namespace, existingSnapshotCR.Name, existingSnapshotCR) + existingSnapshotCR = existingSnapshotCR.DeepCopy() + existingSnapshotCR.Status.Missing = true // a missing snapshot indicates that it was not found in the (rke2|k3s)-etcd-snapshots configmap. This could potentially be a transient situation after an etcd snapshot restore to an older/newer datastore, when new snapshots have not been taken. + if existingSnapshotCR, err = h.etcdSnapshots.UpdateStatus(existingSnapshotCR); err != nil && !apierrors.IsNotFound(err) { + return configMap, fmt.Errorf("rkecluster %s/%s: error while setting status missing=true on etcd snapshot %s/%s: %w", cluster.Namespace, cluster.Name, existingSnapshotCR.Namespace, existingSnapshotCR.Name, err) + } + continue + } + currentEtcdSnapshotsToKeep[snapshotKey] = existingSnapshotCR + } + + // iterate over the snapshots that are listed in the downstream cluster configmap + // if the snapshot is found in the list of snapshots objects that exist in the management cluster, check to see if the etcdsnapshot object needs to be reconciled with more accurate information. + // if the snapshot is not found in the list of snapshot objects that exist in the management cluster and the snapshot is an S3 snapshot, create it in the management cluster. + for snapshotKey, cmGeneratedSnapshot := range actualEtcdSnapshots { + if snapshot, ok := currentEtcdSnapshotsToKeep[snapshotKey]; ok { + // the snapshot CR exists in the management cluster. check to see if the configmap data needs to be set on the snapshot. + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: checking to see if etcdsnapshot %s/%s needs to be updated", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + logrus.Tracef("[snapshotbackpopulate] rkecluster %s/%s: comparing etcd snapshot %s/%s: %v : %v", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name, cmGeneratedSnapshot, snapshot) + snapshot = snapshot.DeepCopy() + var updated bool + if !equality.Semantic.DeepEqual(snapshot.SnapshotFile, cmGeneratedSnapshot.SnapshotFile) { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s SnapshotFile contents differed from configmap", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + originalSnapshotFile := snapshot.SnapshotFile + snapshot.SnapshotFile = cmGeneratedSnapshot.SnapshotFile + if originalSnapshotFile.Metadata != "" && snapshot.SnapshotFile.Metadata == "" { + snapshot.SnapshotFile.Metadata = originalSnapshotFile.Metadata + } + if originalSnapshotFile.Message != "" && snapshot.SnapshotFile.Message == "" { + snapshot.SnapshotFile.Message = originalSnapshotFile.Message + } + if !equality.Semantic.DeepEqual(snapshot.SnapshotFile, originalSnapshotFile) { + updated = true + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s SnapshotFile contents were different, triggering update", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + logrus.Tracef("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s SnapshotFile contents %v vs %v", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name, originalSnapshotFile, snapshot.SnapshotFile) + } + } + if snapshot.Spec.ClusterName != cmGeneratedSnapshot.Spec.ClusterName { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s clusterName did not match %s vs %s", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name, snapshot.Spec.ClusterName, cmGeneratedSnapshot.Spec.ClusterName) + snapshot.Spec.ClusterName = cmGeneratedSnapshot.Spec.ClusterName + updated = true + } + if labelsUpdated := reconcileStringMaps(snapshot.Labels, cmGeneratedSnapshot.Labels, []string{capr.ClusterNameLabel, capr.NodeNameLabel, capr.MachineIDLabel}); labelsUpdated { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s labels did not match", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + updated = true + } + if annotationsUpdated := reconcileStringMaps(snapshot.Annotations, cmGeneratedSnapshot.Annotations, []string{SnapshotNameKey, StorageAnnotationKey, SnapshotBackpopulateReconciledKey}); annotationsUpdated { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: snapshot %s/%s annotations did not match", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + updated = true + } + if updated { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: updating etcdsnapshot %s/%s", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name) + snapshot, err = h.etcdSnapshots.Update(snapshot) + if err != nil { + return configMap, fmt.Errorf("rkecluster %s/%s: error while updating etcd snapshot %s/%s: %w", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name, err) + } + } + if snapshot.Status.Missing { + // if we get to this point and the snapshot object missing status is true, reset it to false as we know it is no longer missing. + snapshot.Status.Missing = false + // the kube-apiserver only accepts status updates on deliberate subresource status updates which is why we have to double-call an update here if the missing is set incorrectly + if _, err := h.etcdSnapshots.UpdateStatus(snapshot); err != nil && !apierrors.IsNotFound(err) { + return configMap, fmt.Errorf("rkecluster %s/%s: error while setting status missing=false on etcd snapshot %s/%s: %w", cluster.Namespace, cluster.Name, snapshot.Namespace, snapshot.Name, err) + } + } + } else { + // create the snapshot in the mgmt cluster if it is an s3 snapshot + // we only create S3 snapshots in the snapshotbackpopulate controller. + // local snapshots are created by the `plansecret` controller based on real output of the snapshot data, and then updated by this controller. + if cmGeneratedSnapshot.SnapshotFile.NodeName != "s3" { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: not creating etcd snapshot %s/%s as it is on a local node", cluster.Namespace, cluster.Name, cmGeneratedSnapshot.Namespace, cmGeneratedSnapshot.Name) + continue + } + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: creating s3 etcd snapshot %s/%s as it differed from the actual snapshot config map", cluster.Namespace, cluster.Name, cmGeneratedSnapshot.Namespace, cmGeneratedSnapshot.Name) + logrus.Tracef("[snapshotbackpopulate] rkecluster %s/%s: creating s3 etcd snapshot %s/%s: %v", cluster.Namespace, cluster.Name, cmGeneratedSnapshot.Namespace, cmGeneratedSnapshot.Name, cmGeneratedSnapshot) + _, err = h.etcdSnapshots.Create(&cmGeneratedSnapshot) + if err != nil { + if apierrors.IsAlreadyExists(err) { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: duplicate snapshot found when creating s3 snapshot %s/%s", cluster.Namespace, cluster.Name, cmGeneratedSnapshot.Namespace, cmGeneratedSnapshot.Name) + continue + } + logrus.Errorf("rkecluster %s/%s: error while creating s3 etcd snapshot %s/%s: %s", cluster.Namespace, cluster.Name, cmGeneratedSnapshot.Namespace, cmGeneratedSnapshot.Name, err.Error()) + } + } + } + return configMap, nil +} + +func reconcileStringMaps(input map[string]string, new map[string]string, keys []string) bool { + var updated bool + for _, key := range keys { + if input[key] == "" && new[key] != "" { + input[key] = new[key] + updated = true + } + } + return updated +} + +// configMapToSnapshots parses the given configmap and returns a map of etcd snapshots. The snapshotbackpopulate controller will only create snapshots from this map that are located in S3. +// The snapshots will have 2 or 3 labels, 2 if they are S3 snapshots (cluster name and node name), and 3 if they are local snapshots. They will always have 2 annotations. +func (h *handler) configMapToSnapshots(configMap *corev1.ConfigMap, cluster *provv1.Cluster) map[string]rkev1.ETCDSnapshot { + result := map[string]rkev1.ETCDSnapshot{} + for k, v := range configMap.Data { + file := &snapshotFile{} + if err := json.Unmarshal([]byte(v), file); err != nil { + logrus.Errorf("rkecluster %s/%s: invalid non-json value in %s/%s for key %s: %v", cluster.Namespace, cluster.Name, configMap.Namespace, configMap.Name, k, err) + continue + } + snapshot := rkev1.ETCDSnapshot{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Namespace, + Labels: map[string]string{ + capr.ClusterNameLabel: cluster.Name, + capr.NodeNameLabel: file.NodeName, + }, + Annotations: map[string]string{ + SnapshotNameKey: file.Name, + StorageAnnotationKey: StorageLocal, + SnapshotBackpopulateReconciledKey: "true", + }, + OwnerReferences: []metav1.OwnerReference{}, + }, + Spec: rkev1.ETCDSnapshotSpec{ + ClusterName: cluster.Name, + }, + SnapshotFile: rkev1.ETCDSnapshotFile{ + Name: file.Name, + Location: file.Location, + Metadata: file.Metadata, + Message: file.Message, + NodeName: file.NodeName, + CreatedAt: file.CreatedAt, + Size: file.Size, + Status: file.Status, + }, + } + fileSuffix := StorageLocal + if file.S3 != nil { + // if the snapshot is an S3 snapshot, set the corresponding S3-related figures. + fileSuffix = StorageS3 + snapshot.SnapshotFile.S3 = &rkev1.ETCDSnapshotS3{ + Endpoint: file.S3.Endpoint, + EndpointCA: file.S3.EndpointCA, + SkipSSLVerify: file.S3.SkipSSLVerify, + Bucket: file.S3.Bucket, + Region: file.S3.Region, + Folder: file.S3.Folder, + } + snapshot.OwnerReferences = []metav1.OwnerReference{{ + APIVersion: cluster.APIVersion, + Kind: cluster.Kind, + Name: cluster.Name, + UID: cluster.UID, + Controller: &[]bool{true}[0], + BlockOwnerDeletion: &[]bool{true}[0], + }} + snapshot.Annotations[StorageAnnotationKey] = StorageS3 + } else { + listSuccessful, machine, err := capr.GetMachineFromNode(h.machineCache, file.NodeName, cluster) + if listSuccessful && err != nil { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: error getting machine from node (%s) for snapshot (%s/%s): %v", cluster.Namespace, cluster.Name, file.NodeName, snapshot.Namespace, snapshot.Name, err) + } else if listSuccessful && machine != nil && machine.Labels[capr.MachineIDLabel] == "" { + logrus.Debugf("[snapshotbackpopulate] rkecluster %s/%s: machine (%s/%s) for snapshot %s on node: %s had empty Machine ID label", cluster.Namespace, cluster.Name, machine.Namespace, machine.Name, file.Name, file.NodeName) + } else { + snapshot.Labels[capr.MachineIDLabel] = machine.Labels[capr.MachineIDLabel] + } + } + snapshot.Name = name.SafeConcatName(cluster.Name, strings.ToLower(InvalidKeyChars.ReplaceAllString(snapshot.SnapshotFile.Name, "-")), fileSuffix) + result[snapshot.SnapshotFile.Name+fileSuffix] = snapshot + } + return result +} + +type s3Config struct { + Endpoint string `json:"endpoint,omitempty"` + EndpointCA string `json:"endpointCA,omitempty"` + SkipSSLVerify bool `json:"skipSSLVerify,omitempty"` + Bucket string `json:"bucket,omitempty"` + Region string `json:"region,omitempty"` + Folder string `json:"folder,omitempty"` +} + +// snapshotFile represents a single snapshot and it's +// metadata, and is used to unmarshal snapshot data from +// the downstream config map. +type snapshotFile struct { + Name string `json:"name"` + Location string `json:"location,omitempty"` + NodeName string `json:"nodeName,omitempty"` + Metadata string `json:"metadata,omitempty"` + Message string `json:"message,omitempty"` + CreatedAt *metav1.Time `json:"createdAt,omitempty"` + Size int64 `json:"size,omitempty"` + Status string `json:"status,omitempty"` + S3 *s3Config `json:"s3Config,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/linux_node_taints.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/linux_node_taints.go new file mode 100644 index 0000000..9e35a67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/linux_node_taints.go @@ -0,0 +1,62 @@ +package windows + +import ( + "fmt" + + apicorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/taints" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + nodeTaint = v1.Taint{ + Key: "cattle.io/os", + Value: "linux", + Effect: v1.TaintEffectNoSchedule, + } + HostOSLabels = []labels.Set{ + labels.Set(map[string]string{ + "beta.kubernetes.io/os": "linux", + }), + labels.Set(map[string]string{ + "kubernetes.io/os": "linux", + }), + } +) + +// NodeTaintsController This controller will only run on the cluster with windowsPreferred is true. +// It will add taints to the v1.Node.Spec.Taints to the nodes with label beta.kubernetes.io/os=linux. +type NodeTaintsController struct { + nodeClient apicorev1.NodeInterface +} + +func (n *NodeTaintsController) sync(key string, obj *v1.Node) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return obj, nil + } + found := false + for _, hostOSLabel := range HostOSLabels { + if hostOSLabel.AsSelector().Matches(labels.Set(obj.Labels)) { + found = true + break + } + } + if !found { + return obj, nil + } + + taintSet := taints.GetTaintSet(obj.Spec.Taints) + // taint exists on nodes + if _, ok := taintSet[taints.GetTaintsString(nodeTaint)]; ok { + return obj, nil + } + + newObj := obj.DeepCopy() + newObj.Spec.Taints = append(newObj.Spec.Taints, nodeTaint) + if _, err := n.nodeClient.Update(newObj); err != nil { + return nil, fmt.Errorf("failed to update node taints for node %s/%s, error: %s", obj.Namespace, obj.Name, err.Error()) + } + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/node_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/node_test.go new file mode 100644 index 0000000..6fb63a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/node_test.go @@ -0,0 +1,87 @@ +package windows + +import ( + "fmt" + "testing" + + apicorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + fakes1 "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type testcase struct { + name string + node *v1.Node + called bool + shouldCall bool +} + +var ( + windowsNodeLabel = map[string]string{ + "beta.kubernetes.io/os": "windows", + } +) + +func Test_nodeController(t *testing.T) { + cases := []*testcase{ + &testcase{ + name: "test node with linux host labels", + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: HostOSLabels[0], + }, + }, + shouldCall: true, + }, + &testcase{ + name: "test node with windows host labels", + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: windowsNodeLabel, + }, + }, + shouldCall: false, + }, + &testcase{ + name: "test node with linux node labels and node taints", + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: HostOSLabels[0], + }, + Spec: v1.NodeSpec{ + Taints: []v1.Taint{ + nodeTaint, + }, + }, + }, + shouldCall: false, + }, + } + n := &NodeTaintsController{ + nodeClient: NewNodeInterface(cases), + } + for _, c := range cases { + _, err := n.sync(c.node.Name, c.node) + assert.Nilf(t, err, "failed to sync node, test case: %s", c.name) + assert.Equal(t, c.shouldCall, c.called, "unexpected call update function, test case: %s", c.name) + } +} + +func NewNodeInterface(cases []*testcase) apicorev1.NodeInterface { + return &fakes1.NodeInterfaceMock{ + UpdateFunc: func(in1 *v1.Node) (*v1.Node, error) { + for _, c := range cases { + if c.node.Name == in1.Name { + c.called = true + return in1, nil + } + } + return in1, fmt.Errorf("case not found, %+v", in1) + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/register.go new file mode 100644 index 0000000..4d137af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuser/windows/register.go @@ -0,0 +1,18 @@ +package windows + +import ( + "context" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, cluster *v3.Cluster, userContext *config.UserContext) { + if !cluster.Spec.WindowsPreferedCluster { + return + } + node := &NodeTaintsController{ + nodeClient: userContext.Core.Nodes(""), + } + userContext.Core.Nodes("").AddHandler(ctx, "linux-node-taints-handler", node.sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/controllers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/controllers.go new file mode 100644 index 0000000..e2c0955 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/controllers.go @@ -0,0 +1,22 @@ +package managementuserlegacy + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/managementlegacy/compose/common" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/globaldns" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/systemimage" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, mgmt *config.ScaledContext, cluster *config.UserContext, clusterRec *managementv3.Cluster, kubeConfigGetter common.KubeConfigGetter) error { + helm.Register(ctx, mgmt, cluster, kubeConfigGetter) + systemimage.Register(ctx, cluster) + globaldns.Register(ctx, cluster) + + // register controller for API + cluster.APIAggregation.APIServices("").Controller() + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/globaldns_common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/globaldns_common.go new file mode 100644 index 0000000..cd61997 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/globaldns_common.go @@ -0,0 +1,75 @@ +package globaldns + +import ( + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + networkingv1 "k8s.io/api/networking/v1" +) + +func gatherIngressEndpoints(ingressEps []networkingv1.IngressLoadBalancerIngress) []string { + var endpoints []string + for _, ep := range ingressEps { + if ep.IP != "" { + endpoints = append(endpoints, ep.IP) + } else if ep.Hostname != "" { + endpoints = append(endpoints, ep.Hostname) + } + } + return endpoints +} + +func getMultiClusterAppName(multiClusterAppName string) (string, error) { + split := strings.SplitN(multiClusterAppName, ":", 2) + if len(split) != 2 { + return "", fmt.Errorf("error in splitting multiclusterapp ID %v", multiClusterAppName) + } + mcappName := split[1] + return mcappName, nil +} + +func ifEndpointsDiffer(endpointsOne []string, endpointsTwo []string) bool { + if len(endpointsOne) != len(endpointsTwo) { + return true + } + + mapEndpointsOne := make(map[string]bool) + for _, ep := range endpointsOne { + mapEndpointsOne[ep] = true + } + + for _, ep := range endpointsTwo { + if !mapEndpointsOne[ep] { + return true + } + } + return false +} + +func dedupEndpoints(endpoints []string) []string { + mapEndpoints := make(map[string]bool) + res := []string{} + for _, ep := range endpoints { + if !mapEndpoints[ep] { + mapEndpoints[ep] = true + res = append(res, ep) + } + } + return res +} + +func reconcileGlobalDNSEndpoints(globalDNS *v3.GlobalDns) { + //aggregate all clusterEndpoints and form the final DNS endpoints[] + var reconciledEps []string + originalEps := globalDNS.Status.Endpoints + + for _, clusterEndpoints := range globalDNS.Status.ClusterEndpoints { + reconciledEps = append(reconciledEps, clusterEndpoints...) + } + + //update the DNS endpoints if different + if ifEndpointsDiffer(originalEps, reconciledEps) { + globalDNS.Status.Endpoints = reconciledEps + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_globaldns_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_globaldns_controller.go new file mode 100644 index 0000000..9c4f479 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_globaldns_controller.go @@ -0,0 +1,183 @@ +package globaldns + +import ( + "fmt" + "strings" + + v1coreRancher "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ingresswrapper" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +type UserGlobalDNSController struct { + ingressLister ingresswrapper.CompatLister + globalDNSs v3.GlobalDnsInterface + multiclusterappLister v3.MultiClusterAppLister + namespaceLister v1coreRancher.NamespaceLister + clusterName string +} + +func newUserGlobalDNSController(clusterContext *config.UserContext) *UserGlobalDNSController { + g := UserGlobalDNSController{ + ingressLister: ingresswrapper.NewCompatLister(clusterContext.Networking, clusterContext.Extensions, clusterContext.K8sClient), + globalDNSs: clusterContext.Management.Management.GlobalDnses(""), + multiclusterappLister: clusterContext.Management.Management.MultiClusterApps("").Controller().Lister(), + namespaceLister: clusterContext.Core.Namespaces("").Controller().Lister(), + clusterName: clusterContext.ClusterName, + } + return &g +} + +func (g *UserGlobalDNSController) sync(key string, obj *v3.GlobalDns) (runtime.Object, error) { + + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + var targetEndpoints []string + var err error + + if obj.Spec.MultiClusterAppName != "" { + targetEndpoints, err = g.reconcileMultiClusterApp(obj) + } else if len(obj.Spec.ProjectNames) > 0 { + targetEndpoints, err = g.reconcileProjects(obj) + } + + if err != nil { + return nil, err + } + + //compare with the clusterEndpoints and find endpoints to update and remove. + return g.refreshGlobalDNSEndpoints(obj, targetEndpoints) +} + +func (g *UserGlobalDNSController) reconcileMultiClusterApp(obj *v3.GlobalDns) ([]string, error) { + // If multiclusterappID is set, look for ingresses in the projects of multiclusterapp's targets + // Get multiclusterapp by name set on GlobalDNS spec + mcappName, err := getMultiClusterAppName(obj.Spec.MultiClusterAppName) + if err != nil { + return nil, err + } + + mcapp, err := g.multiclusterappLister.Get(namespace.GlobalNamespace, mcappName) + if err != nil && k8serrors.IsNotFound(err) { + logrus.Debugf("UserGlobalDNSController: Object Not found Error %v, while listing MulticlusterApp by name %v", err, mcappName) + return nil, nil + } + if err != nil { + return nil, fmt.Errorf("UserGlobalDNSController: Error %v Listing MulticlusterApp by name %v", err, mcappName) + } + + // go through target projects which are part of the current cluster and find all ingresses + var allIngresses []*ingresswrapper.CompatIngress + + for _, t := range mcapp.Spec.Targets { + split := strings.SplitN(t.ProjectName, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("error in splitting project ID %v", t.ProjectName) + } + // check if the target project in this iteration is same as the cluster in current context + if split[0] != g.clusterName { + continue + } + + // each target will have appName, this appName is also the namespace in which all workloads for this app are created + var err error + allIngresses, err = g.ingressLister.List(t.AppName, labels.NewSelector()) + if err != nil { + return nil, err + } + } + + //gather endpoints + return g.fetchGlobalDNSEndpointsForIngresses(allIngresses, obj) +} + +func (g *UserGlobalDNSController) reconcileProjects(obj *v3.GlobalDns) ([]string, error) { + // go through target projects which are part of the current cluster and find all ingresses + var allIngresses []*ingresswrapper.CompatIngress + + allNamespaces, err := g.namespaceLister.List("", labels.NewSelector()) + if err != nil { + return nil, fmt.Errorf("UserGlobalDNSController: Error listing cluster namespaces %v", err) + } + + for _, projectNameSet := range obj.Spec.ProjectNames { + split := strings.SplitN(projectNameSet, ":", 2) + if len(split) != 2 { + return nil, fmt.Errorf("UserGlobalDNSController: Error in splitting project Name %v", projectNameSet) + } + // check if the project in this iteration belongs to the same cluster in current context + if split[0] != g.clusterName { + continue + } + projectID := split[1] + //list all namespaces in this project and list all ingresses within each namespace + var namespacesInProject []string + for _, namespace := range allNamespaces { + nameSpaceProject := namespace.ObjectMeta.Labels[projectSelectorLabel] + if strings.EqualFold(projectID, nameSpaceProject) { + namespacesInProject = append(namespacesInProject, namespace.Name) + } + } + for _, namespace := range namespacesInProject { + var err error + allIngresses, err = g.ingressLister.List(namespace, labels.NewSelector()) + if err != nil { + return nil, err + } + } + } + //gather endpoints + return g.fetchGlobalDNSEndpointsForIngresses(allIngresses, obj) +} + +func (g *UserGlobalDNSController) fetchGlobalDNSEndpointsForIngresses(ingresses []*ingresswrapper.CompatIngress, obj *v3.GlobalDns) ([]string, error) { + if len(ingresses) == 0 { + return nil, nil + } + + var allEndpoints []string + //gather endpoints from all ingresses + for _, ing := range ingresses { + if gdns, ok := ing.GetAnnotations()[annotationGlobalDNS]; ok { + // check if the globalDNS in annotation is same as the FQDN set on the GlobalDNS + if gdns != obj.Spec.FQDN { + continue + } + //gather endpoints from the ingress + ingressEndpoints := gatherIngressEndpoints(ing.Status.LoadBalancer.Ingress) + allEndpoints = append(allEndpoints, ingressEndpoints...) + } + } + return allEndpoints, nil +} + +func (g *UserGlobalDNSController) refreshGlobalDNSEndpoints(globalDNS *v3.GlobalDns, ingressEndpointsForCluster []string) (*v3.GlobalDns, error) { + + globalDNSToUpdate := globalDNS.DeepCopy() + uniqueEndpointsForCluster := dedupEndpoints(ingressEndpointsForCluster) + + if len(globalDNSToUpdate.Status.ClusterEndpoints) == 0 { + globalDNSToUpdate.Status.ClusterEndpoints = make(map[string][]string) + } + + clusterEps := globalDNSToUpdate.Status.ClusterEndpoints[g.clusterName] + if ifEndpointsDiffer(clusterEps, uniqueEndpointsForCluster) { + globalDNSToUpdate.Status.ClusterEndpoints[g.clusterName] = uniqueEndpointsForCluster + reconcileGlobalDNSEndpoints(globalDNSToUpdate) + + updated, err := g.globalDNSs.Update(globalDNSToUpdate) + if err != nil { + return updated, fmt.Errorf("UserGlobalDNSController: Failed to update GlobalDNS endpoints with error %v", err) + } + return updated, nil + } + return nil, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_ingress.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_ingress.go new file mode 100644 index 0000000..19756ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/globaldns/user_cluster_ingress.go @@ -0,0 +1,145 @@ +package globaldns + +import ( + "context" + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/rancher/rancher/pkg/ingresswrapper" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + annotationGlobalDNS = "rancher.io/globalDNS.hostname" + appSelectorLabel = "io.cattle.field/appId" + projectSelectorLabel = "field.cattle.io/projectId" + UserIngressControllerName = "globaldns-useringress-controller" + UserGlobalDNSControllerName = "user-controller-watching-globaldns" +) + +type UserIngressController struct { + globalDNSs v3.GlobalDnsInterface + globalDNSLister v3.GlobalDnsLister + multiclusterappLister v3.MultiClusterAppLister + clusterName string +} + +func newUserIngressController(ctx context.Context, clusterContext *config.UserContext) *UserIngressController { + n := &UserIngressController{ + globalDNSs: clusterContext.Management.Management.GlobalDnses(""), + globalDNSLister: clusterContext.Management.Management.GlobalDnses("").Controller().Lister(), + multiclusterappLister: clusterContext.Management.Management.MultiClusterApps("").Controller().Lister(), + clusterName: clusterContext.ClusterName, + } + return n +} + +func Register(ctx context.Context, clusterContext *config.UserContext) { + n := newUserIngressController(ctx, clusterContext) + starter := clusterContext.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, clusterContext) + return nil + }) + + globalDNS := clusterContext.Management.Management.GlobalDnses("") + globalDNS.AddHandler(ctx, "globaldns-deferred", func(key string, obj *v3.GlobalDns) (runtime.Object, error) { + if obj == nil { + return obj, nil + } else if ok, err := n.doesGlobalDNSTargetCurrentCluster(obj); err != nil { + return obj, err + } else if ok { + return obj, starter() + } + return obj, nil + }) +} + +func registerDeferred(ctx context.Context, clusterContext *config.UserContext) { + n := newUserIngressController(ctx, clusterContext) + if ingresswrapper.ServerSupportsIngressV1(clusterContext.K8sClient) { + clusterContext.Networking.Ingresses("").AddHandler(ctx, UserIngressControllerName, ingresswrapper.CompatSyncV1(n.sync)) + } else { + clusterContext.Extensions.Ingresses("").AddHandler(ctx, UserIngressControllerName, ingresswrapper.CompatSyncV1Beta1(n.sync)) + } + g := newUserGlobalDNSController(clusterContext) + clusterContext.Management.Management.GlobalDnses("").AddHandler(ctx, UserGlobalDNSControllerName, g.sync) +} + +func (ic *UserIngressController) sync(key string, obj ingresswrapper.Ingress) (runtime.Object, error) { + return ic.reconcileAllGlobalDNSs() +} + +func (ic *UserIngressController) noGlobalDNS() (bool, error) { + gd, err := ic.globalDNSLister.List(namespace.GlobalNamespace, labels.NewSelector()) + if err != nil { + return true, err + } + + return len(gd) == 0, nil +} + +func (ic *UserIngressController) reconcileAllGlobalDNSs() (runtime.Object, error) { + globalDNSList, err := ic.globalDNSLister.List(namespace.GlobalNamespace, labels.NewSelector()) + if err != nil { + return nil, err + } + + for _, globalDNSObj := range globalDNSList { + //call update on each GlobalDNS obj that refers to this current cluster + targetsCluster, err := ic.doesGlobalDNSTargetCurrentCluster(globalDNSObj) + if err != nil { + return nil, err + } + if targetsCluster { + //enqueue it to the globalDNS controller + ic.globalDNSs.Controller().Enqueue(namespace.GlobalNamespace, globalDNSObj.Name) + } + } + return nil, nil +} + +func (ic *UserIngressController) doesGlobalDNSTargetCurrentCluster(globalDNS *v3.GlobalDns) (bool, error) { + var targetProjectNames []string + + if globalDNS.Spec.MultiClusterAppName != "" { + mcappName, err := getMultiClusterAppName(globalDNS.Spec.MultiClusterAppName) + if err != nil { + return false, err + } + mcapp, err := ic.multiclusterappLister.Get(namespace.GlobalNamespace, mcappName) + if err != nil && k8serrors.IsNotFound(err) { + logrus.Debugf("UserIngressController: reconcileallgdns, multiclusterapp not found by name %v, might be marked for deletion", mcappName) + //pass the check and let the controller continue in this case, it will enqueue update to globaldns and the other controller will figure out the endpoint updates + return true, nil + } + if err != nil { + return false, err + } + for _, t := range mcapp.Spec.Targets { + targetProjectNames = append(targetProjectNames, t.ProjectName) + } + } else if len(globalDNS.Spec.ProjectNames) > 0 { + targetProjectNames = append(targetProjectNames, globalDNS.Spec.ProjectNames...) + } + + // go through target projects and check if its part of the current cluster + for _, projectNameSet := range targetProjectNames { + split := strings.SplitN(projectNameSet, ":", 2) + if len(split) != 2 { + return false, fmt.Errorf("UserIngressController: Error in splitting project Name %v", projectNameSet) + } + // check if the project in this iteration belongs to the same cluster in current context + if split[0] == ic.clusterName { + return true, nil + } + } + + return false, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common.go new file mode 100644 index 0000000..7676cd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common.go @@ -0,0 +1,254 @@ +package helm + +import ( + "bytes" + "context" + "encoding/base64" + "fmt" + "io/ioutil" + "math" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + helmlib "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/jailer" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + appLabel = "io.cattle.field/appId" + failedLabel = "io.cattle.field/failed-revision" +) + +func writeTempDir(rootDir string, files map[string]string) error { + for name, content := range files { + fp := filepath.Join(rootDir, name) + if err := os.MkdirAll(filepath.Dir(fp), 0755); err != nil { + return err + } + if err := ioutil.WriteFile(fp, []byte(content), 0644); err != nil { + return err + } + } + return nil +} + +func getAppSubDir(files map[string]string) string { + var minLen = math.MaxInt32 + var appSubDir string + for filename := range files { + dir, file := filepath.Split(filename) + if strings.EqualFold(file, "Chart.yaml") { + pathLen := len(filepath.SplitList(dir)) + if minLen > pathLen { + appSubDir = dir + minLen = pathLen + } + } + } + return appSubDir +} + +func helmInstall(tempDirs *common.HelmPath, app *v3.App) (string, error) { + cont, cancel := context.WithCancel(context.Background()) + defer cancel() + addr := common.GenerateRandomPort() + if !common.IsHelm3(app.Status.HelmVersion) { + go func() { + err := common.StartTiller(cont, tempDirs, addr, app.Spec.TargetNamespace) + if err != nil { + logrus.Errorf("got error while stopping tiller, error message: %s", err.Error()) + } + }() + } + err := common.InstallCharts(tempDirs, addr, app) + if err != nil { + return "", err + } + return renderNotes(app, tempDirs, addr) +} + +func helmDelete(tempDirs *common.HelmPath, app *v3.App) error { + cont, cancel := context.WithCancel(context.Background()) + defer cancel() + addr := common.GenerateRandomPort() + if !common.IsHelm3(app.Status.HelmVersion) { + go func() { + err := common.StartTiller(cont, tempDirs, addr, app.Spec.TargetNamespace) + if err != nil { + logrus.Errorf("got error while stopping tiller, error message: %s", err.Error()) + } + }() + } + return common.DeleteCharts(tempDirs, addr, app) +} + +func (l *Lifecycle) generateTemplates(obj *v3.App) (string, *common.HelmPath, error) { + var appSubDir string + files := map[string]string{} + if obj.Spec.ExternalID != "" { + templateVersionID, templateVersionNamespace, err := common.ParseExternalID(obj.Spec.ExternalID) + if err != nil { + return "", nil, err + } + + templateVersion, err := l.TemplateVersionClient.GetNamespaced(templateVersionNamespace, templateVersionID, metav1.GetOptions{}) + if err != nil { + return "", nil, err + } + + namespace, catalogName, catalogType, _, _, err := common.SplitExternalID(templateVersion.Spec.ExternalID) + if err != nil { + return "", nil, err + } + catalog, err := helmlib.GetCatalog(catalogType, namespace, catalogName, l.CatalogLister, l.ClusterCatalogLister, l.ProjectCatalogLister) + if err != nil { + return "", nil, err + } + + helm, err := helmlib.New(catalog, l.SecretLister) + if err != nil { + return "", nil, err + } + + files, err = helm.LoadChart(&templateVersion.Spec, nil) + if err != nil { + return "", nil, err + } + appSubDir = templateVersion.Spec.VersionName + } else { + for k, v := range obj.Spec.Files { + content, err := base64.StdEncoding.DecodeString(v) + if err != nil { + return "", nil, err + } + files[k] = string(content) + } + appSubDir = getAppSubDir(files) + } + + tempDir, err := createTempDir(obj) + if err != nil { + return "", nil, err + } + if err := writeTempDir(tempDir.FullPath, files); err != nil { + return "", nil, err + } + + appDir := filepath.Join(tempDir.InJailPath, appSubDir) + tempDir.AppDirInJail = appDir + tempDir.AppDirFull = filepath.Join(tempDir.FullPath, appSubDir) + + extraArgs := common.GetExtraArgs(obj) + setValues, err := common.GenerateAnswerSetValues(obj, tempDir, extraArgs) + if err != nil { + return "", nil, err + } + + var commands []string + var cmd *exec.Cmd + if common.IsHelm3(obj.Status.HelmVersion) { + tokenName, err := l.writeKubeConfig(obj, tempDir.KubeConfigFull, false) + if err != nil { + return "", nil, err + } + defer func() { + if err := l.systemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for helm token [%s] failed, will not retry: %v", tokenName, err) + } + }() + commands = append([]string{"template", obj.Name, "--include-crds", appDir, "--namespace", obj.Spec.TargetNamespace, "--kubeconfig", tempDir.KubeConfigInJail}, setValues...) + cmd = exec.Command(common.HelmV3, commands...) + } else { + commands = append([]string{"template", appDir, "--name", obj.Name, "--namespace", obj.Spec.TargetNamespace}, setValues...) + cmd = exec.Command(common.HelmV2, commands...) + } + sbOut := &bytes.Buffer{} + sbErr := &bytes.Buffer{} + cmd.Stdout = sbOut + cmd.Stderr = sbErr + cmd, err = jailer.JailCommand(cmd, tempDir.FullPath) + if err != nil { + return "", nil, err + } + if err := cmd.Start(); err != nil { + return "", nil, errors.Wrapf(err, "start helm template failed. %s", sbErr.String()) + } + if err := cmd.Wait(); err != nil { + return "", nil, errors.Wrapf(err, "wait helm template failed. %s", sbErr.String()) + } + + template := sbOut.String() + return template, tempDir, nil +} + +func createTempDir(obj *v3.App) (*common.HelmPath, error) { + if os.Getenv("CATTLE_DEV_MODE") != "" { + dir, err := ioutil.TempDir("", "helm-") + if err != nil { + return nil, err + } + return &common.HelmPath{ + FullPath: dir, + InJailPath: dir, + KubeConfigFull: filepath.Join(dir, ".kubeconfig"), + KubeConfigInJail: filepath.Join(dir, ".kubeconfig"), + KustomizeFull: filepath.Join(dir, "kustomize.sh"), + KustomizeInJail: filepath.Join(dir, "kustomize.sh"), + }, nil + } + + jailDir := obj.Spec.ProjectName + ":" + obj.Name + + err := jailer.CreateJail(jailDir) + if err != nil { + return nil, err + } + + paths := &common.HelmPath{ + FullPath: filepath.Join(jailer.BaseJailPath, jailDir), + InJailPath: "/", + KubeConfigFull: filepath.Join(jailer.BaseJailPath, jailDir, ".kubeconfig"), + KubeConfigInJail: "/.kubeconfig", + KustomizeFull: filepath.Join(jailer.BaseJailPath, jailDir, "kustomize.sh"), + KustomizeInJail: "/kustomize.sh", + } + + return paths, nil +} + +func renderNotes(obj *v3.App, tempDirs *common.HelmPath, port string) (string, error) { + var cmd *exec.Cmd + if common.IsHelm3(obj.Status.HelmVersion) { + commands := []string{"get", "notes", obj.Name, "-n", obj.Spec.TargetNamespace, "--kubeconfig", tempDirs.KubeConfigInJail} + cmd = exec.Command(common.HelmV3, commands...) + } else { + // helm get requires tiller to be running + commands := []string{"get", "notes", obj.Name} + cmd = exec.Command(common.HelmV2, commands...) + cmd.Env = []string{fmt.Sprintf("%s=%s", "HELM_HOST", "127.0.0.1:"+port)} + } + noteOut := &bytes.Buffer{} + sbErr := &bytes.Buffer{} + cmd.Stdout = noteOut + cmd.Stderr = sbErr + var err error + cmd, err = jailer.JailCommand(cmd, tempDirs.FullPath) + if err != nil { + return "", err + } + if err := cmd.Start(); err != nil { + return "", errors.Wrapf(err, "start helm get notes failed. %s", sbErr.String()) + } + if err := cmd.Wait(); err != nil { + return "", errors.Wrapf(err, "wait helm get notes failed. %s", sbErr.String()) + } + notes := noteOut.String() + return notes, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common.go new file mode 100644 index 0000000..6594b9e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common.go @@ -0,0 +1,412 @@ +package common + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "math/rand" + "net" + "net/url" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "text/template" + "time" + + "github.com/ghodss/yaml" + "github.com/pkg/errors" + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/jailer" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" +) + +const ( + base = 32768 + end = 61000 + tillerName = "rancher-tiller" + HelmV2 = "rancher-helm" + HelmV3 = "helm_v3" + forceUpgradeStr = "--force" + appLabel = "io.cattle.field/appId" + kustomizeTransformFile = "common-labels.yaml" + kustomizeTransformSpecs = ` +apiVersion: builtin +kind: LabelTransformer +metadata: + name: common-labels +labels: + {{.}} +fieldSpecs: +- path: metadata/labels + create: true +- path: spec/selector + create: true + version: v1 + kind: ReplicationController +- path: spec/template/metadata/labels + create: true + version: v1 + kind: ReplicationController +- path: spec/selector/matchLabels + create: true + kind: Deployment +- path: spec/template/metadata/labels + create: true + kind: Deployment +- path: spec/selector/matchLabels + create: true + kind: ReplicaSet +- path: spec/template/metadata/labels + create: true + kind: ReplicaSet +- path: spec/selector/matchLabels + create: true + kind: DaemonSet +- path: spec/template/metadata/labels + create: true + kind: DaemonSet +- path: spec/selector/matchLabels + create: true + group: apps + kind: StatefulSet +- path: spec/template/metadata/labels + create: true + group: apps + kind: StatefulSet +- path: spec/volumeClaimTemplates[]/metadata/labels + create: true + group: apps + kind: StatefulSet +- path: spec/template/metadata/labels + create: true + group: batch + kind: Job +- path: spec/jobTemplate/metadata/labels + create: true + group: batch + kind: CronJob +- path: spec/jobTemplate/spec/template/metadata/labels + create: true + group: batch + kind: CronJob +` +) + +type HelmPath struct { + // /opt/jail/ + FullPath string + // / + InJailPath string + // /opt/jail//.kubeconfig + KubeConfigFull string + // /.kubeconfig + KubeConfigInJail string + // /opt/jail// + AppDirFull string + // / + AppDirInJail string + // /opt/jail//kustomize.sh + KustomizeFull string + // /kustomize.sh + KustomizeInJail string +} + +// Marshal kustomization settings into YAML +type Kustomization struct { + Resources []string `json:"resources"` + Transformers []string `json:"transformers"` +} + +func ParseExternalID(externalID string) (string, string, error) { + templateVersionNamespace, catalog, _, template, version, err := SplitExternalID(externalID) + if err != nil { + return "", "", err + } + return strings.Join([]string{catalog, template, version}, "-"), templateVersionNamespace, nil +} + +func SplitExternalID(externalID string) (string, string, string, string, string, error) { + var templateVersionNamespace, catalog string + values, err := url.Parse(externalID) + if err != nil { + return "", "", "", "", "", err + } + catalogWithNamespace := values.Query().Get("catalog") + catalogType := values.Query().Get("type") + template := values.Query().Get("template") + version := values.Query().Get("version") + split := strings.SplitN(catalogWithNamespace, "/", 2) + if len(split) == 2 { + templateVersionNamespace = split[0] + catalog = split[1] + } + //pre-upgrade setups will have global catalogs, where externalId field on templateversions won't have namespace. + // since these are global catalogs, we can default to global namespace + if templateVersionNamespace == "" { + templateVersionNamespace = namespace.GlobalNamespace + catalog = catalogWithNamespace + } + return templateVersionNamespace, catalog, catalogType, template, version, nil +} + +// StartTiller start tiller server and return the listening address of the grpc address +func StartTiller(context context.Context, tempDirs *HelmPath, port, namespace string) error { + probePort := GenerateRandomPort() + cmd := exec.Command(tillerName, "--listen", ":"+port, "--probe-listen", ":"+probePort) + cmd.Env = []string{fmt.Sprintf("%s=%s", "KUBECONFIG", tempDirs.KubeConfigInJail), fmt.Sprintf("%s=%s", "TILLER_NAMESPACE", namespace), fmt.Sprintf("%s=%s", "TILLER_HISTORY_MAX", settings.HelmMaxHistory.Get())} + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + cmd, err := jailer.JailCommand(cmd, tempDirs.FullPath) + if err != nil { + return err + } + + if err := cmd.Start(); err != nil { + return err + } + defer cmd.Wait() + select { + case <-context.Done(): + logrus.Debug("Stopping Tiller") + return cmd.Process.Kill() + } +} + +func GenerateRandomPort() string { + s1 := rand.NewSource(time.Now().UnixNano()) + r1 := rand.New(s1) + for { + port := base + r1.Intn(end-base+1) + ln, err := net.Listen("tcp", ":"+strconv.Itoa(port)) + if err != nil { + continue + } + ln.Close() + return strconv.Itoa(port) + } +} + +func InstallCharts(tempDirs *HelmPath, port string, obj *v3.App) error { + logrus.Debugf("InstallCharts - helm path info %+v\n", tempDirs) + extraArgs := GetExtraArgs(obj) + timeoutArgs := getTimeoutArgs(obj) + setValues, err := GenerateAnswerSetValues(obj, tempDirs, extraArgs) + if err != nil { + return err + } + var commands []string + if IsHelm3(obj.Status.HelmVersion) { + err = createKustomizeFiles(tempDirs, obj.Name) + if err != nil { + return err + } + logrus.Infof("Installing chart using helm version: %s", HelmV3) + commands = append([]string{"upgrade", "--install", obj.Name, "--namespace", obj.Spec.TargetNamespace, "--kubeconfig", tempDirs.KubeConfigInJail, "--post-renderer", tempDirs.KustomizeInJail, "--history-max", settings.HelmMaxHistory.Get()}, timeoutArgs...) + } else { + logrus.Infof("Installing chart using helm version: %s", HelmV2) + commands = append([]string{"upgrade", "--install", "--namespace", obj.Spec.TargetNamespace, obj.Name}, timeoutArgs...) + } + commands = append(commands, setValues...) + commands = append(commands, tempDirs.AppDirInJail) + + if v32.AppConditionForceUpgrade.IsUnknown(obj) { + commands = append(commands, forceUpgradeStr) + // don't leave force recreate on the object + v32.AppConditionForceUpgrade.True(obj) + } + var cmd *exec.Cmd + // switch userTriggeredAction back + v32.AppConditionUserTriggeredAction.Unknown(obj) + if IsHelm3(obj.Status.HelmVersion) { + cmd = exec.Command(HelmV3, commands...) + } else { + cmd = exec.Command(HelmV2, commands...) + } + cmd.Env = []string{fmt.Sprintf("%s=%s", "HELM_HOST", "127.0.0.1:"+port), fmt.Sprintf("%s=%s", "CATTLE_KUSTOMIZE_YAML", tempDirs.InJailPath)} + stderrBuf := &bytes.Buffer{} + cmd.Stdout = os.Stdout + cmd.Stderr = stderrBuf + cmd, err = jailer.JailCommand(cmd, tempDirs.FullPath) + if err != nil { + return err + } + if err := cmd.Start(); err != nil { + return errors.Errorf("failed to install app %s. %s", obj.Name, stderrBuf.String()) + } + if err := cmd.Wait(); err != nil { + // if the first install failed, the second install would have error message like `has no deployed releases`, then the + // original error is masked. We need to filter out the message and always return the last one if error matches this pattern + if strings.Contains(stderrBuf.String(), "has no deployed releases") { + if !v32.AppConditionForceUpgrade.IsUnknown(obj) { + v32.AppConditionForceUpgrade.Unknown(obj) + } + return errors.New(v32.AppConditionInstalled.GetMessage(obj)) + } + return errors.Errorf("failed to install app %s. %s", obj.Name, stderrBuf.String()) + } + return nil +} + +// getTimeoutArgs generates the appropriate arguments for helm depending on the app's timeout and wait fields +func getTimeoutArgs(app *v3.App) []string { + var timeoutArgs []string + + if app.Spec.Wait { + timeoutArgs = append(timeoutArgs, "--wait") + } + if app.Status.HelmVersion == HelmV3 { + timeoutArgs = append(timeoutArgs, "--timeout", fmt.Sprintf("%ss", strconv.Itoa(app.Spec.Timeout))) + } else { + timeoutArgs = append(timeoutArgs, "--timeout", strconv.Itoa(app.Spec.Timeout)) + } + return timeoutArgs +} + +// Convert answers map into a slice of "k=v" formatted values with escaped commas (Required by Helm) +func answersMapToValuesSlice(answers, extraArgs map[string]string) []string { + var slice []string + for k, v := range answers { + if _, ok := extraArgs[k]; ok { + continue + } + slice = append(slice, fmt.Sprintf("%s=%s", k, escapeCommas(v))) + } + for k, v := range extraArgs { + slice = append(slice, fmt.Sprintf("%s=%s", k, escapeCommas(v))) + } + return slice +} + +func GenerateAnswerSetValues(app *v3.App, tempDir *HelmPath, extraArgs map[string]string) ([]string, error) { + var values []string + // A user-supplied values.yaml will override the default values.yaml + if app.Spec.ValuesYaml != "" { + custom := "custom-values.yaml" + valuesYaml := filepath.Join(tempDir.FullPath, custom) + if err := ioutil.WriteFile(valuesYaml, []byte(app.Spec.ValuesYaml), 0755); err != nil { + return values, err + } + values = append(values, "--values", filepath.Join(tempDir.InJailPath, custom)) + } + // Values in --set args will override values in the user-supplied values.yaml + if app.Spec.Answers != nil || extraArgs != nil { + setValues := answersMapToValuesSlice(app.Spec.Answers, extraArgs) + values = append(values, "--set", strings.Join(setValues, ",")) + } + // Values in --set-string args will override values in --set args because + // Helm gives presedence to the right-most set flag + if app.Spec.AnswersSetString != nil { + setStringValues := answersMapToValuesSlice(app.Spec.AnswersSetString, map[string]string{}) + values = append(values, "--set-string", strings.Join(setStringValues, ",")) + } + return values, nil +} + +func DeleteCharts(tempDirs *HelmPath, port string, obj *v3.App) error { + var cmd *exec.Cmd + if IsHelm3(obj.Status.HelmVersion) { + logrus.Infof("Deleting chart using helm version: %s", HelmV3) + cmd = exec.Command(HelmV3, "uninstall", obj.Name, "--kubeconfig", tempDirs.KubeConfigInJail, "--namespace", obj.Spec.TargetNamespace) + } else { + logrus.Infof("Deleting chart using helm version: %s", HelmV2) + cmd = exec.Command(HelmV2, "delete", "--purge", obj.Name) + } + cmd.Env = []string{fmt.Sprintf("%s=%s", "HELM_HOST", "127.0.0.1:"+port)} + cmd, err := jailer.JailCommand(cmd, tempDirs.FullPath) + if err != nil { + return err + } + combinedOutput, err := cmd.CombinedOutput() + if err != nil && combinedOutput != nil && strings.Contains(string(combinedOutput), fmt.Sprintf("Error: release: \"%s\" not found", obj.Name)) { + return nil + } + return errors.New(string(combinedOutput)) +} + +// escapeCommas will escape the commas in a string, unless helm would identify it as a list +func escapeCommas(value string) string { + if len(value) == 0 { + return value + } + // as far as helm is concerned, an answer starting with '{' is a list + // commas in lists are not escaped for users as they are also used as delimiters + if strings.HasPrefix(value, "{") { + return value + } + return strings.Replace(value, ",", "\\,", -1) +} + +// generates the kustomization yaml that is used by the helm 3 post rendered to +// add the app labels needed to track the workloads with the app deployment +func createKustomizeFiles(tempDirs *HelmPath, labelValue string) error { + err := createKustomizeTransformFile(tempDirs, labelValue) + if err != nil { + return err + } + resources := []string{"all.yaml"} + transformers := []string{kustomizeTransformFile} + k := Kustomization{resources, transformers} + y, err := yaml.Marshal(k) + if err != nil { + return err + } + kpath := filepath.Join(tempDirs.FullPath, "/kustomization.yaml") + err = ioutil.WriteFile(kpath, y, 0644) + if err != nil { + return err + } + logrus.Debugf("successfully created kustomization.yaml in %s", kpath) + + // set file link to ensure kustomize.sh works in dev move without having to copy + // the file to the "injail" location + if os.Getenv("CATTLE_DEV_MODE") != "" { + kpath = filepath.Join(tempDirs.InJailPath, "/kustomize.sh") + err = os.Link("./kustomize.sh", kpath) + if err != nil { + err = os.Link(filepath.Join(os.Getenv("DAPPER_SOURCE"), "package/kustomize.sh"), kpath) + if err != nil { + return err + } + } + logrus.Debugf("successfully linked kustomize.sh to %s", kpath) + } + return nil +} + +// generates the kustomization transformers yaml from tmpl that is used by the helm 3 post rendered to +// add the app labels needed to track the workloads with the app deployment +// this is required to avoid the app labels being added on k8s objects selectors +func createKustomizeTransformFile(tempDirs *HelmPath, value string) error { + ktValue := appLabel + ": " + value + tmpl := template.New("KustomizeTransform") + tmpl, err := tmpl.Parse(kustomizeTransformSpecs) + if err != nil { + return err + } + result := &bytes.Buffer{} + err = tmpl.Execute(result, ktValue) + if err != nil { + return err + } + ktPath := filepath.Join(tempDirs.FullPath, "/"+kustomizeTransformFile) + err = ioutil.WriteFile(ktPath, result.Bytes(), 0644) + if err != nil { + return err + } + logrus.Debugf("successfully created %s in %s", kustomizeTransformFile, ktPath) + return nil +} + +func IsHelm3(helmName string) bool { + if helmName == HelmV3 || strings.ToLower(helmName) == "v3" { + return true + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common_test.go new file mode 100644 index 0000000..19c0687 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/common_test.go @@ -0,0 +1,46 @@ +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type testCase struct { + input string + expect string +} + +func newTestCase(input string, expect string) testCase { + return testCase{ + input, + expect, + } +} +func TestEscapeCommas(t *testing.T) { + assert := assert.New(t) + + invalidArguments := []testCase{ + newTestCase("asdf", "asdf"), // no commas, so nothing should be escaped + newTestCase("{asdf", "{asdf"), + newTestCase("asdf{", "asdf{"), + newTestCase("asdf}", "asdf}"), + newTestCase("asd}asdf", "asd}asdf"), + newTestCase("asd{asdf}dasf", "asd{asdf}dasf"), + newTestCase("as,df", "as\\,df"), // value not a list so commas should be escaped + newTestCase("asd,f{", "asd\\,f{"), + newTestCase("as,df}", "as\\,df}"), + newTestCase("asd}as,df", "asd}as\\,df"), + newTestCase("asd{asdf}da,sf", "asd{asdf}da\\,sf"), + newTestCase(",asdf", "\\,asdf"), + newTestCase("{,asdf", "{,asdf"), // helm would recognize as a list, commas should not be escaped + newTestCase("{as,df}", "{as,df}"), + newTestCase("{{", "{{"), + newTestCase("", ""), + } + + for _, arg := range invalidArguments { + result := escapeCommas(arg.input) + assert.Equal(arg.expect, result) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_injection.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_injection.go new file mode 100644 index 0000000..60e690f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_injection.go @@ -0,0 +1,58 @@ +package common + +import ( + "net/url" + + cutils "github.com/rancher/rancher/pkg/catalog/utils" + v3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" +) + +type InjectAppArgsFunc func(obj *v3.App) (content map[string]string) + +var ( + extraArgsFuncs = []InjectAppArgsFunc{ + injectDefaultRegistry, + injectClusterInfo, + } +) + +func injectDefaultRegistry(obj *v3.App) map[string]string { + values, err := url.Parse(obj.Spec.ExternalID) + if err != nil { + logrus.Errorf("parsing externalID failed: %s", err.Error()) + return nil + } + + if values.Query().Get("catalog") != cutils.SystemLibraryName { + return nil + } + + reg := settings.SystemDefaultRegistry.Get() + if reg == "" { + return nil + } + + return map[string]string{"systemDefaultRegistry": reg, "cattle.systemDefaultRegistry": reg} +} + +func injectClusterInfo(obj *v3.App) map[string]string { + clusterName, projectName := ref.Parse(obj.Spec.ProjectName) + return map[string]string{ + "clusterName": clusterName, + "projectName": projectName, + } +} + +func GetExtraArgs(app *v3.App) map[string]string { + rtn := map[string]string{} + for _, afunc := range extraArgsFuncs { + content := afunc(app) + for k, v := range content { + rtn["global."+k] = v + } + } + return rtn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_test.go new file mode 100644 index 0000000..8c46224 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/common/extra_args_test.go @@ -0,0 +1,49 @@ +package common + +import ( + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" +) + +func Test_injectDefaultRegistry(t *testing.T) { + testRegistry := "test.registry.com" + err := settings.SystemDefaultRegistry.Set(testRegistry) + assert.Nil(t, err, "failed to set system default registry settings") + + testCases := []struct { + app *v3.App + want bool + }{ + { + app: &v3.App{ + Spec: v32.AppSpec{ + ExternalID: "catalog://?catalog=library&template=wordpress&version=2.1.11", + }, + }, + want: false, + }, + { + app: &v3.App{ + Spec: v32.AppSpec{ + ExternalID: "catalog://?catalog=system-library&template=rancher-external-dns&version=0.1.0", + }, + }, + want: true, + }, + } + + for _, testCase := range testCases { + testApp := testCase.app + injectMap := injectDefaultRegistry(testApp) + if !testCase.want { + assert.Nilf(t, injectMap, "catalog id %s should not get default registry parameters", testApp.Spec.ExternalID) + } else { + v, _ := injectMap["systemDefaultRegistry"] + assert.Equalf(t, testRegistry, v, "catalog id %s should not get default registry parameters", testApp.Spec.ExternalID) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/controller.go new file mode 100644 index 0000000..d210273 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/controller.go @@ -0,0 +1,498 @@ +package helm + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "fmt" + "os" + "reflect" + "sort" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + errorsutil "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/controllers/managementlegacy/compose/common" + hCommon "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/rancher/pkg/user" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +const ( + helmTokenPrefix = "helm-token-" + description = "token for helm chart deployment" + AppIDsLabel = "cattle.io/appIds" + creatorIDAnn = "field.cattle.io/creatorId" + MultiClusterAppIDSelector = "mcapp" + projectIDFieldLabel = "field.cattle.io/projectId" + defaultMaxRevisionCount = 10 +) + +func Register(ctx context.Context, mgmt *config.ScaledContext, user *config.UserContext, kubeConfigGetter common.KubeConfigGetter) { + starter := user.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, mgmt, user, kubeConfigGetter) + return nil + }) + + apps := user.Management.Project.Apps("") + apps.AddClusterScopedHandler(ctx, "helm-deferred", user.ClusterName, func(key string, obj *v32.App) (runtime.Object, error) { + return obj, starter() + }) +} + +func registerDeferred(ctx context.Context, mgmt *config.ScaledContext, user *config.UserContext, kubeConfigGetter common.KubeConfigGetter) { + appClient := user.Management.Project.Apps("") + stackLifecycle := &Lifecycle{ + KubeConfigGetter: kubeConfigGetter, + SystemAccountManager: systemaccount.NewManager(user.Management), + TokenClient: user.Management.Management.Tokens(""), + UserClient: user.Management.Management.Users(""), + K8sClient: user.K8sClient, + TemplateVersionClient: user.Management.Management.CatalogTemplateVersions(""), + TemplateClient: user.Management.Management.CatalogTemplates(""), + CatalogLister: user.Management.Management.Catalogs("").Controller().Lister(), + ClusterCatalogLister: user.Management.Management.ClusterCatalogs("").Controller().Lister(), + ProjectCatalogLister: user.Management.Management.ProjectCatalogs("").Controller().Lister(), + TemplateVersionLister: user.Management.Management.CatalogTemplateVersions("").Controller().Lister(), + ClusterName: user.ClusterName, + systemTokens: user.Management.SystemTokens, + AppRevisionGetter: user.Management.Project, + AppGetter: user.Management.Project, + AppsLister: user.Management.Project.Apps("").Controller().Lister(), + NsLister: user.Core.Namespaces("").Controller().Lister(), + NsClient: user.Core.Namespaces(""), + SecretLister: mgmt.Core.Secrets("").Controller().Lister(), + } + appClient.AddClusterScopedLifecycle(ctx, "helm-controller", user.ClusterName, stackLifecycle) + + StartStateCalculator(ctx, user) +} + +type Lifecycle struct { + systemTokens systemtokens.Interface + KubeConfigGetter common.KubeConfigGetter + SystemAccountManager *systemaccount.Manager + UserManager user.Manager + TokenClient mgmtv3.TokenInterface + UserClient mgmtv3.UserInterface + TemplateVersionClient mgmtv3.CatalogTemplateVersionInterface + TemplateClient mgmtv3.CatalogTemplateInterface + CatalogLister mgmtv3.CatalogLister + ClusterCatalogLister mgmtv3.ClusterCatalogLister + ProjectCatalogLister mgmtv3.ProjectCatalogLister + TemplateVersionLister mgmtv3.CatalogTemplateVersionLister + K8sClient kubernetes.Interface + ClusterName string + AppRevisionGetter v3.AppRevisionsGetter + AppGetter v3.AppsGetter + AppsLister v3.AppLister + NsLister corev1.NamespaceLister + NsClient corev1.NamespaceInterface + SecretLister corev1.SecretLister +} + +func (l *Lifecycle) Create(obj *v3.App) (runtime.Object, error) { + v32.AppConditionMigrated.True(obj) + v32.AppConditionUserTriggeredAction.Unknown(obj) + if obj.Spec.ExternalID != "" { + helmVersion, err := l.getHelmVersion(obj) + if err != nil { + return nil, err + } + obj.Status.HelmVersion = helmVersion + } + + return obj, nil +} + +/* +Updated depends on several conditions: + + AppConditionMigrated: protects upgrade path for apps <2.1 + AppConditionInstalled: flips status in UI and drives logic + AppConditionDeployed: flips status in UI + AppConditionForceUpgrade: add destructive `--force` param to helm upgrade when set to Unknown + AppConditionUserTriggeredAction: Indicates when `upgrade` or `rollback` is called by the user +*/ +func (l *Lifecycle) Updated(obj *v3.App) (runtime.Object, error) { + if obj.Spec.ExternalID == "" && len(obj.Spec.Files) == 0 { + return obj, nil + } + // always refresh app to avoid updating app twice + _, projectName := ref.Parse(obj.Spec.ProjectName) + var err error + obj, err = l.AppsLister.Get(projectName, obj.Name) + if err != nil { + return obj, err + } + // if app was created before 2.1, run migrate to install a no-op helm release + newObj, err := v32.AppConditionMigrated.Once(obj, func() (runtime.Object, error) { + return l.DeployApp(obj) + }) + if err != nil { + return obj, err + } + + obj = newObj.(*v3.App) + appRevisionClient := l.AppRevisionGetter.AppRevisions(projectName) + if obj.Spec.AppRevisionName != "" { + currentRevision, err := appRevisionClient.Get(obj.Spec.AppRevisionName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + /* + This if statement gates most of the logic for Update. We should only deploy the app when we actually want to. + But we call update when we may only want to change a UI status. In those cases, we should return here and not + go further. We want to deploy the app when: + * The current App revision is different than the app, ex. the app is different than it was before + * The force upgrade flag is set, where AppConditionForceUpgrade being unknown is equal to true. + * The user caused the action by way of clicking either upgrade or rollback + */ + if isSame(obj, currentRevision) && !v32.AppConditionForceUpgrade.IsUnknown(obj) && + !v32.AppConditionUserTriggeredAction.IsTrue(obj) { + if !v32.AppConditionForceUpgrade.IsTrue(obj) { + v32.AppConditionForceUpgrade.True(obj) + } + logrus.Debugf("[helm-controller] App %v doesn't require update", obj.Name) + return obj, nil + } + } + logrus.Debugf("[helm-controller] Updating app %v", obj.Name) + created := false + if obj.Spec.MultiClusterAppName != "" { + if _, err := l.NsLister.Get("", obj.Spec.TargetNamespace); err != nil && !errors.IsNotFound(err) { + return obj, err + } else if err != nil && errors.IsNotFound(err) { + n := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: obj.Spec.TargetNamespace, + Labels: map[string]string{ + projectIDFieldLabel: obj.Namespace, + MultiClusterAppIDSelector: obj.Spec.MultiClusterAppName}, + Annotations: map[string]string{ + projectIDFieldLabel: fmt.Sprintf("%s:%s", l.ClusterName, obj.Namespace), + creatorIDAnn: obj.Annotations[creatorIDAnn], + AppIDsLabel: obj.Name}, + }, + } + ns, err := l.NsClient.Create(&n) + if err != nil { + if !errors.IsAlreadyExists(err) { + return obj, err + } + if ns.DeletionTimestamp != nil { + return obj, fmt.Errorf("waiting for namespace %s to be terminated", obj.Namespace) + } + } else if err == nil { + created = true + } + } + } + result, err := l.DeployApp(obj) + if err != nil { + return result, err + } + if !v32.AppConditionForceUpgrade.IsTrue(obj) { + v32.AppConditionForceUpgrade.True(obj) + } + ns, err := l.NsClient.Get(obj.Spec.TargetNamespace, metav1.GetOptions{}) + if err != nil { + if !errors.IsNotFound(err) { + return result, err + } + if obj.Spec.MultiClusterAppName != "" { + return obj, fmt.Errorf("namespace not found after app creation %s", obj.Name) + } + return result, nil + } + if created { + return result, nil + } + if ns.Annotations[AppIDsLabel] == "" { + ns.Annotations[AppIDsLabel] = obj.Name + } else { + parts := strings.Split(ns.Annotations[AppIDsLabel], ",") + appIDs := map[string]struct{}{} + for _, part := range parts { + appIDs[part] = struct{}{} + } + appIDs[obj.Name] = struct{}{} + appIDList := []string{} + for k := range appIDs { + appIDList = append(appIDList, k) + } + sort.Strings(appIDList) + ns.Annotations[AppIDsLabel] = strings.Join(appIDList, ",") + } + if _, err := l.NsClient.Update(ns); err != nil { + return result, err + } + return result, nil +} + +func (l *Lifecycle) DeployApp(obj *v3.App) (*v3.App, error) { + obj = obj.DeepCopy() + var err error + if v32.AppConditionInstalled.IsTrue(obj) { + v32.AppConditionInstalled.Unknown(obj) + // update status in the UI + obj, err = l.AppGetter.Apps("").Update(obj) + if err != nil { + return obj, err + } + } + newObj, err := v32.AppConditionInstalled.Do(obj, func() (runtime.Object, error) { + template, tempDirs, err := l.generateTemplates(obj) + if err != nil { + return obj, err + } + defer os.RemoveAll(tempDirs.FullPath) + if err := l.Run(obj, template, tempDirs); err != nil { + return obj, err + } + return obj, nil + }) + return newObj.(*v3.App), err +} + +func (l *Lifecycle) Remove(obj *v3.App) (runtime.Object, error) { + _, projectName := ref.Parse(obj.Spec.ProjectName) + appRevisionClient := l.AppRevisionGetter.AppRevisions(projectName) + revisions, err := appRevisionClient.List(metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", appLabel, obj.Name), + }) + if err != nil { + return obj, err + } + for _, revision := range revisions.Items { + if err := appRevisionClient.Delete(revision.Name, &metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return obj, err + } + } + if !(obj.Annotations["cattle.io/skipUninstall"] == "true") { + tempDirs, err := createTempDir(obj) + if err != nil { + return obj, err + } + defer os.RemoveAll(tempDirs.FullPath) + tokenName, err := l.writeKubeConfig(obj, tempDirs.KubeConfigFull, true) + if err != nil { + return obj, err + } + defer func() { + if err := l.systemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for helm token [%s] failed, will not retry: %v", tokenName, err) + } + }() + // try three times and succeed + start := time.Second * 1 + for i := 0; i < 3; i++ { + if err = helmDelete(tempDirs, obj); err == nil { + break + } + logrus.Warn(err) + time.Sleep(start) + start *= 2 + } + } + ns, err := l.NsClient.Get(obj.Spec.TargetNamespace, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return obj, err + } else if errors.IsNotFound(err) { + return obj, nil + } + if val, ok := ns.Labels[MultiClusterAppIDSelector]; ok && val == obj.Spec.MultiClusterAppName { + err := l.NsClient.Delete(ns.Name, &metav1.DeleteOptions{}) + if errors.IsNotFound(err) { + return obj, nil + } + return obj, err + } + appIDs := strings.Split(ns.Annotations[AppIDsLabel], ",") + appAnno := "" + for _, appID := range appIDs { + if appID == obj.Name { + continue + } + appAnno += appID + "," + } + if appAnno == "" { + delete(ns.Annotations, AppIDsLabel) + } else { + appAnno = strings.TrimSuffix(appAnno, ",") + ns.Annotations[AppIDsLabel] = appAnno + } + if _, err := l.NsClient.Update(ns); err != nil { + return obj, err + } + return obj, nil +} + +func (l *Lifecycle) Run(obj *v3.App, template string, tempDirs *hCommon.HelmPath) error { + defer l.pruneOldRevisions(obj) + tokenName, err := l.writeKubeConfig(obj, tempDirs.KubeConfigFull, false) + if err != nil { + return err + } + defer func() { + if err := l.systemTokens.DeleteToken(tokenName); err != nil { + logrus.Errorf("cleanup for helm token [%s] failed, will not retry: %v", tokenName, err) + } + }() + notes, err := helmInstall(tempDirs, obj) + if err != nil { + // create an app revision so that user can decide to continue + err2 := l.createAppRevision(obj, template, notes, true) + if err2 != nil { + return errorsutil.Wrapf(err, "error encountered while creating appRevision %v", + err2) + } + return err + } + return l.createAppRevision(obj, template, notes, false) +} + +// pruneOldRevisions checks if the total number of app revisions does not exceed the set maximum. +// If it does, the method deletes the oldest revision(s) to maintain the maximum number of revisions and no more. +func (l *Lifecycle) pruneOldRevisions(obj *v3.App) { + if obj.Spec.MaxRevisionCount < 1 { + obj.Spec.MaxRevisionCount = defaultMaxRevisionCount + } + _, projectName := ref.Parse(obj.Spec.ProjectName) + appRevisionClient := l.AppRevisionGetter.AppRevisions(projectName) + revisions, err := appRevisionClient.List(metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", appLabel, obj.Name), + }) + if err != nil { + logrus.Warnf("[helm-controller] Failed to list revisions for app %s: %v", projectName, err) + return + } + // Sort revisions by creation timestamp, starting with the oldest. + sort.Slice(revisions.Items, func(i, j int) bool { + return revisions.Items[i].CreationTimestamp.Before(&revisions.Items[j].CreationTimestamp) + }) + if len(revisions.Items) > obj.Spec.MaxRevisionCount { + logrus.Tracef("[helm-controller] App %s is exceeding the maximum (%d) number of stored revisions", obj.Name, obj.Spec.MaxRevisionCount) + deleteCount := len(revisions.Items) - obj.Spec.MaxRevisionCount + for _, revision := range revisions.Items[:deleteCount] { + if err := appRevisionClient.Delete(revision.Name, &metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + logrus.Warnf("[helm-controller] Failed to delete app revision %s: %v", revision.Name, err) + } + } + } +} + +func (l *Lifecycle) createAppRevision(obj *v3.App, template, notes string, failed bool) error { + _, projectName := ref.Parse(obj.Spec.ProjectName) + appRevisionClient := l.AppRevisionGetter.AppRevisions(projectName) + release := &v3.AppRevision{} + release.GenerateName = "apprevision-" + release.Labels = map[string]string{ + appLabel: obj.Name, + } + if failed { + release.Labels[failedLabel] = "true" + } + release.Spec.ProjectName = obj.Spec.ProjectName + release.Status.Answers = obj.Spec.Answers + release.Status.AnswersSetString = obj.Spec.AnswersSetString + release.Status.ExternalID = obj.Spec.ExternalID + release.Status.ValuesYaml = obj.Spec.ValuesYaml + release.Status.Files = obj.Spec.Files + + digest := sha256.New() + digest.Write([]byte(template)) + tag := hex.EncodeToString(digest.Sum(nil)) + release.Status.Digest = tag + + createdRevision, err := appRevisionClient.Create(release) + if err != nil { + return err + } + obj.Spec.AppRevisionName = createdRevision.Name + obj.Status.Notes = notes + if obj.Spec.Files != nil { + obj.Status.AppliedFiles = obj.Spec.Files + } + return err +} + +func (l *Lifecycle) writeKubeConfig(obj *v3.App, kubePath string, remove bool) (string, error) { + var token string + + userID := obj.Annotations["field.cattle.io/creatorId"] + user, err := l.UserClient.Get(userID, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return "", err + } else if errors.IsNotFound(err) && remove { + token, err = l.SystemAccountManager.CreateProjectHelmSystemToken(obj.Namespace) + } else if err == nil { + token, err = l.systemTokens.EnsureSystemToken(helmTokenPrefix+user.Name, description, "helm", user.Name, nil, true) + } + if err != nil { + return "", err + } + + kubeConfig := l.KubeConfigGetter.KubeConfig(l.ClusterName, token) + for k := range kubeConfig.Clusters { + kubeConfig.Clusters[k].InsecureSkipTLSVerify = true + } + + if err := clientcmd.WriteToFile(*kubeConfig, kubePath); err != nil { + return "", err + } + tokenID, _ := tokens.SplitTokenParts(token) + return tokenID, nil +} + +func isSame(obj *v3.App, revision *v3.AppRevision) bool { + if obj.Spec.ExternalID != "" { + if revision.Status.ExternalID == obj.Spec.ExternalID && + reflect.DeepEqual(revision.Status.Answers, obj.Spec.Answers) && + reflect.DeepEqual(revision.Status.AnswersSetString, obj.Spec.AnswersSetString) && + reflect.DeepEqual(revision.Status.ValuesYaml, obj.Spec.ValuesYaml) { + return true + } + return false + } + + if obj.Status.AppliedFiles != nil { + if reflect.DeepEqual(obj.Status.AppliedFiles, obj.Spec.Files) && + reflect.DeepEqual(revision.Status.Answers, obj.Spec.Answers) && + reflect.DeepEqual(revision.Status.AnswersSetString, obj.Spec.AnswersSetString) && + reflect.DeepEqual(revision.Status.ValuesYaml, obj.Spec.ValuesYaml) { + return true + } + return false + } + + return false +} + +func (l *Lifecycle) getHelmVersion(obj *v3.App) (string, error) { + templateVersionID, templateVersionNamespace, err := hCommon.ParseExternalID(obj.Spec.ExternalID) + if err != nil { + return "", err + } + templateVersion, err := l.TemplateVersionLister.Get(templateVersionNamespace, templateVersionID) + if err != nil { + return "", err + } + return templateVersion.Status.HelmVersion, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/state.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/state.go new file mode 100644 index 0000000..4d005a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/helm/state.go @@ -0,0 +1,180 @@ +package helm + +import ( + "context" + "fmt" + "strings" + + v33 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + + "github.com/rancher/norman/types/convert" + util "github.com/rancher/rancher/pkg/controllers/managementagent/workload" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + pv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + projectLabel = "field.cattle.io/projectId" +) + +func StartStateCalculator(ctx context.Context, cluster *config.UserContext) { + apps := cluster.Management.Project.Apps("") + w := &AppStateCalculator{ + appLister: apps.Controller().Lister(), + apps: apps, + multiClusterApps: cluster.Management.Management.MultiClusterApps(""), + namespaceLister: cluster.Core.Namespaces("").Controller().Lister(), + projectLister: cluster.Management.Management.Projects(cluster.ClusterName).Controller().Lister(), + clusterName: cluster.ClusterName, + } + w.workloadLister = util.NewWorkloadController(ctx, cluster.UserOnlyContext(), w.sync) + apps.Controller().AddHandler(ctx, "app-state-controller", w.syncAppState) +} + +type AppStateCalculator struct { + apps pv3.AppInterface + appLister pv3.AppLister + namespaceLister corev1.NamespaceLister + multiClusterApps v3.MultiClusterAppInterface + workloadLister util.CommonController + projectLister v3.ProjectLister + clusterName string +} + +func (s *AppStateCalculator) sync(key string, obj *util.Workload) error { + if obj == nil { + return nil + } + if label, ok := obj.Labels[appLabel]; ok { + ns, err := s.namespaceLister.Get("", obj.Namespace) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + logrus.Errorf("error getting namespace %s for app %s: %v", obj.Namespace, obj.Name, err) + return nil + } + projectNS := ns.Labels[projectLabel] + if projectNS == "" { + return fmt.Errorf("cannot find app namespace in labels of %s", obj.Namespace) + } + app, err := s.appLister.Get(projectNS, label) + if err != nil { + if errors.IsNotFound(err) { + // If Rancher is unaware of an app, we should ignore tracking its state + // A non-existent app is likely managed by another Rancher (e.g. Hosted Rancher) + return nil + } + if !errors.IsNotFound(err) { + return err + } + logrus.Errorf("error getting app %s %v", label, err) + return nil + } + if app != nil && app.DeletionTimestamp == nil { + s.apps.Controller().Enqueue(app.Namespace, app.Name) + } + } + return nil +} + +func (s *AppStateCalculator) syncAppState(key string, app *pv3.App) (runtime.Object, error) { + if app == nil || app.DeletionTimestamp != nil { + return nil, nil + } + if !v32.AppConditionInstalled.IsTrue(app) { + return app, nil + } + project, err := s.projectLister.Get(s.clusterName, app.Namespace) + if err != nil && !errors.IsNotFound(err) { + return app, err + } + if err != nil || project == nil || project.DeletionTimestamp != nil { + return app, nil + } + workloads, err := s.getWorkloadsByApp(app.Name) + if err != nil { + return app, fmt.Errorf("error getting workloads %v", err) + } + updatingWorkloads := getUpdating(workloads) + toUpdate := app.DeepCopy() + if len(updatingWorkloads) == 0 { + if v32.AppConditionDeployed.IsTrue(toUpdate) { + return app, nil + } + v32.AppConditionDeployed.True(toUpdate) + v32.AppConditionDeployed.Reason(toUpdate, "") + v32.AppConditionDeployed.Message(toUpdate, "") + } else { + existing := strings.Split(v33.MultiClusterAppConditionDeployed.GetMessage(toUpdate), ",") + if Equal(existing, updatingWorkloads) { + return app, nil + } + v32.AppConditionDeployed.Unknown(toUpdate) + v32.AppConditionDeployed.Message(toUpdate, GetMsg(updatingWorkloads)) + v32.AppConditionDeployed.Reason(toUpdate, "workloads are updating") + } + return s.apps.Update(toUpdate) +} + +func (s *AppStateCalculator) getWorkloadsByApp(name string) ([]*util.Workload, error) { + label := map[string]string{ + appLabel: name, + } + workloads, err := s.workloadLister.GetWorkloadsMatchingSelector("", label) + if err != nil { + return nil, err + } + return workloads, nil +} + +func getUpdating(workloads []*util.Workload) map[string]bool { + updatingWorkloads := map[string]bool{} + for _, workload := range workloads { + if workload.Kind == util.ReplicaSetType { + continue + } + if hasUpdatingCondition(workload.Status.Conditions) { + updatingWorkloads[workload.Name] = true + } else if workload.Status.Replicas != workload.Status.AvailableReplicas { + updatingWorkloads[workload.Name] = true + } + } + return updatingWorkloads +} + +func hasUpdatingCondition(conditions []map[string]interface{}) bool { + for _, condition := range conditions { + status := convert.ToString(condition["status"]) + if status == "False" || status == "Unknown" { + return true + } + } + return false +} + +func GetMsg(data map[string]bool) string { + var keys []string + for key := range data { + keys = append(keys, key) + } + return fmt.Sprintf("%s", strings.Join(keys, ",")) +} + +func Equal(existing []string, toUpdate map[string]bool) bool { + if len(existing) != len(toUpdate) { + return false + } + for _, name := range existing { + if _, ok := toUpdate[name]; !ok { + return false + } + } + return true +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/register.go new file mode 100644 index 0000000..3aa1e56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/register.go @@ -0,0 +1,32 @@ +package systemimage + +import ( + "context" + + "github.com/rancher/rancher/pkg/types/config" +) + +func Register(ctx context.Context, cluster *config.UserContext) { + _ = cluster.DeferredStart(ctx, func(ctx context.Context) error { + registerDeferred(ctx, cluster) + return nil + }) +} + +func registerDeferred(ctx context.Context, cluster *config.UserContext) { + projClient := cluster.Management.Management.Projects(cluster.ClusterName) + catalogClient := cluster.Management.Management.Catalogs("") + systemServices := getSystemService() + for _, v := range systemServices { + v.Init(cluster) + } + + syncer := Syncer{ + clusterName: cluster.ClusterName, + projects: projClient, + projectLister: projClient.Controller().Lister(), + systemServices: systemServices, + } + projClient.AddClusterScopedHandler(ctx, "system-image-upgrade-controller", cluster.ClusterName, syncer.SyncProject) + catalogClient.AddHandler(ctx, "system-image-upgrade-catalog-controller", syncer.SyncCatalog) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/systemimage.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/systemimage.go new file mode 100644 index 0000000..9066b88 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/systemimage.go @@ -0,0 +1,122 @@ +package systemimage + +import ( + "encoding/json" + "fmt" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/catalog/manager" + cutils "github.com/rancher/rancher/pkg/catalog/utils" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/project" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +var systemProjectLabels = labels.Set(map[string]string{"authz.management.cattle.io/system-project": "true"}) + +type Syncer struct { + clusterName string + projectLister v3.ProjectLister + projects v3.ProjectInterface + systemServices map[string]SystemService +} + +func (s *Syncer) SyncProject(key string, obj *v3.Project) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + return obj, s.Sync() +} + +func (s *Syncer) SyncCatalog(key string, obj *v3.Catalog) (runtime.Object, error) { + if obj == nil || obj.DeletionTimestamp != nil { + return nil, nil + } + + if obj.Name != cutils.SystemLibraryName { + return obj, nil + } + + return obj, s.Sync() +} + +func (s *Syncer) Sync() error { + projects, err := s.projectLister.List(s.clusterName, systemProjectLabels.AsSelector()) + if err != nil { + return fmt.Errorf("get projects failed when try to upgrade system tools, %v", err) + } + + var systemProject *v3.Project + for _, v := range projects { + if v.Spec.DisplayName == project.System { + systemProject = v.DeepCopy() + } + } + + if systemProject == nil { + return nil + } + + versionMap := make(map[string]string) + curSysImageVersion := systemProject.Annotations[project.SystemImageVersionAnn] + if curSysImageVersion != "" { + if err = json.Unmarshal([]byte(curSysImageVersion), &versionMap); err != nil { + return fmt.Errorf("unmashal current system service version failed, %v", err) + } + } + + changed := false + for k, v := range s.systemServices { + oldVersion := versionMap[k] + newVersion, err := v.Upgrade(oldVersion) + if err != nil { + _, ok := err.(manager.IncompatibleTemplateVersionErr) + if ok { + // there's no valid version to update to, so don't update the versionMap with this systemService + continue + } + return errors.Wrapf(err, "upgrade cluster %s system service %s failed", s.clusterName, k) + } + if oldVersion != newVersion { + changed = true + versionMap[k] = newVersion + } + } + + if !changed { + return nil + } + + newVersion, err := json.Marshal(versionMap) + if err != nil { + return fmt.Errorf("marshal new system service version %v failed, %v", versionMap, err) + } + + systemProject.Annotations[project.SystemImageVersionAnn] = string(newVersion) + _, err = s.projects.Update(systemProject) + return err +} + +func GetSystemImageVersion() (string, error) { + versionMap := make(map[string]string) + systemServices := getSystemService() + for k, v := range systemServices { + version, err := v.Version() + if err != nil { + return "", err + } + versionMap[k] = version + } + + b, err := json.Marshal(versionMap) + if err != nil { + return "", fmt.Errorf("marshal toolsSystemImages failed: %v", err) + } + + return string(b), nil +} + +func getSystemService() map[string]SystemService { + return map[string]SystemService{} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/upgrader.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/upgrader.go new file mode 100644 index 0000000..eaaf3c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/managementuserlegacy/systemimage/upgrader.go @@ -0,0 +1,11 @@ +package systemimage + +import ( + "github.com/rancher/rancher/pkg/types/config" +) + +type SystemService interface { + Init(cluster *config.UserContext) + Upgrade(currentVersion string) (newVersion string, err error) + Version() (string, error) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver.go new file mode 100644 index 0000000..208ed26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver.go @@ -0,0 +1,61 @@ +package nodedriver + +import ( + "context" + "sync/atomic" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/drivers" + "github.com/rancher/rancher/pkg/wrangler" +) + +var leader = atomic.Bool{} + +func Register(ctx context.Context, wrangler *wrangler.Context) { + wrangler.Mgmt.NodeDriver().OnChange(ctx, "custom-node-driver-handler", onChange) + + // when this pod becomes the leader, do not run the onChange code + wrangler.OnLeader(func(ctx context.Context) error { + leader.Store(true) + return nil + }) +} + +func onChange(_ string, obj *v3.NodeDriver) (*v3.NodeDriver, error) { + if obj == nil { + return obj, nil + } + + // if leader, no need to sync + if leader.Load() { + return obj, nil + } + + if !obj.Spec.Active { + return obj, nil + } + + // only cache drivers which are not built-in to rancher image + if obj.Spec.Builtin { + return obj, nil + } + + driver := drivers.NewDynamicDriver(obj.Spec.Builtin, obj.Spec.DisplayName, obj.Spec.URL, obj.Spec.Checksum) + if driver.Exists() { + return obj, nil + } + + if err := driver.Stage(true); err != nil { + return obj, err + } + + if err := driver.Install(); err != nil { + return obj, err + } + + if err := driver.Executable(); err != nil { + return obj, err + } + + return obj, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver_test.go new file mode 100644 index 0000000..35ffc46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/nodedriver/nodedriver_test.go @@ -0,0 +1,46 @@ +package nodedriver + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" +) + +func TestOnChange(t *testing.T) { + tests := []struct { + name string + driver *v3.NodeDriver + expected *v3.NodeDriver + expectErr bool + }{ + { + name: "nil", + driver: nil, + expected: nil, + expectErr: false, + }, + { + name: "not active", + driver: &v3.NodeDriver{}, + expected: &v3.NodeDriver{}, + expectErr: false, + }, + { + name: "builtin", + driver: &v3.NodeDriver{Spec: v3.NodeDriverSpec{Builtin: true}}, + expected: &v3.NodeDriver{Spec: v3.NodeDriverSpec{Builtin: true}}, + expectErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := onChange("", tt.driver) + if tt.expectErr { + assert.NotNil(t, err) + } + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/options.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/options.go new file mode 100644 index 0000000..ad28e97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/options.go @@ -0,0 +1,54 @@ +/* +Package controllers contains logic for handlers that belong to controllers and options for configuring controllers. +*/ +package controllers + +import ( + "os" + "strings" + + "github.com/rancher/lasso/pkg/controller" + "k8s.io/client-go/rest" +) + +type controllerContextType string + +const ( + User controllerContextType = "user" + Scaled controllerContextType = "scaled" + Management controllerContextType = "mgmt" + K8sManagedByKey = "app.kubernetes.io/managed-by" + ManagerValue = "rancher" +) + +// GetOptsFromEnv configures a SharedControllersFactoryOptions using env var and return a pointer to it. +func GetOptsFromEnv(contextType controllerContextType) *controller.SharedControllerFactoryOptions { + return &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: syncOnlyChangedObjects(contextType), + } +} + +// syncOnlyChangedObjects returns whether the env var CATTLE_SYNC_ONLY_CHANGED_OBJECTS indicates that controllers for the +// given context type should skip running enqueue if the event triggering the update func is not actual update. +func syncOnlyChangedObjects(option controllerContextType) bool { + skipUpdate := os.Getenv("CATTLE_SYNC_ONLY_CHANGED_OBJECTS") + if skipUpdate == "" { + return false + } + parts := strings.Split(skipUpdate, ",") + + for _, part := range parts { + if controllerContextType(part) == option { + return true + } + } + return false +} + +// WebhookImpersonation returns a ImpersonationConfig that can be used for impersonating the webhook's sudo account and bypass validation. +func WebhookImpersonation() rest.ImpersonationConfig { + return rest.ImpersonationConfig{ + UserName: "system:serviceaccount:cattle-system:rancher-webhook-sudo", + Groups: []string{"system:masters"}, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller.go new file mode 100644 index 0000000..9025251 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller.go @@ -0,0 +1,565 @@ +package cluster + +import ( + "context" + "regexp" + "strconv" + + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rocontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontrollers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/genericcondition" + "github.com/rancher/wrangler/v3/pkg/kstatus" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/rancher/wrangler/v3/pkg/yaml" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + ByCluster = "by-cluster" + ByCloudCred = "by-cloud-cred" + creatorIDAnn = "field.cattle.io/creatorId" + administratedAnn = "provisioning.cattle.io/administrated" + mgmtClusterNameAnn = "provisioning.cattle.io/management-cluster-name" + fleetWorkspaceNameAnn = "provisioning.cattle.io/fleet-workspace-name" +) + +var ( + mgmtNameRegexp = regexp.MustCompile("^(c-[a-z0-9]{5}|local)$") +) + +type handler struct { + mgmtClusterCache mgmtcontrollers.ClusterCache + mgmtClusters mgmtcontrollers.ClusterController + clusterTokenCache mgmtcontrollers.ClusterRegistrationTokenCache + clusterTokens mgmtcontrollers.ClusterRegistrationTokenClient + featureCache mgmtcontrollers.FeatureCache + featureClient mgmtcontrollers.FeatureClient + clusters rocontrollers.ClusterController + clusterCache rocontrollers.ClusterCache + rkeControlPlanes rkecontrollers.RKEControlPlaneClient + rkeControlPlanesCache rkecontrollers.RKEControlPlaneCache + secretCache corecontrollers.SecretCache + kubeconfigManager *kubeconfig.Manager + apply apply.Apply + + capiClustersCache capicontrollers.ClusterCache + capiClusters capicontrollers.ClusterClient + capiMachinesCache capicontrollers.MachineCache +} + +func Register( + ctx context.Context, + clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + h := handler{ + mgmtClusterCache: clients.Mgmt.Cluster().Cache(), + mgmtClusters: clients.Mgmt.Cluster(), + clusterTokenCache: clients.Mgmt.ClusterRegistrationToken().Cache(), + clusterTokens: clients.Mgmt.ClusterRegistrationToken(), + featureCache: clients.Mgmt.Feature().Cache(), + featureClient: clients.Mgmt.Feature(), + clusters: clients.Provisioning.Cluster(), + clusterCache: clients.Provisioning.Cluster().Cache(), + rkeControlPlanes: clients.RKE.RKEControlPlane(), + rkeControlPlanesCache: clients.RKE.RKEControlPlane().Cache(), + secretCache: clients.Core.Secret().Cache(), + capiClustersCache: clients.CAPI.Cluster().Cache(), + capiClusters: clients.CAPI.Cluster(), + capiMachinesCache: clients.CAPI.Machine().Cache(), + kubeconfigManager: kubeconfigManager, + apply: clients.Apply.WithCacheTypes( + clients.Provisioning.Cluster(), + clients.Mgmt.Cluster()), + } + + // Register a generating handler in order to generate clusters.provisioning.cattle.io/v1 objects based on + // clusters.management.cattle.io/v3 (legacy) cluster objects. + mgmtcontrollers.RegisterClusterGeneratingHandler(ctx, + clients.Mgmt.Cluster(), + clients.Apply.WithCacheTypes(clients.Provisioning.Cluster()), + "", + "provisioning-cluster-create", + h.generateProvisioningClusterFromLegacyCluster, + nil) + + clusterCreateApply := clients.Apply.WithCacheTypes(clients.Mgmt.Cluster(), + clients.Mgmt.ClusterRegistrationToken(), + clients.RBAC.ClusterRoleBinding(), + clients.Core.Namespace(), + clients.Core.Secret()) + + if features.MCM.Enabled() { + clusterCreateApply = clusterCreateApply.WithCacheTypes(clients.Mgmt.ClusterRoleTemplateBinding()) + } + + // Register a generating handler in order to generate clusters.management.cattle.io/v3 objects based on + // clusters.provisioning.cattle.io/v1 objects. + rocontrollers.RegisterClusterGeneratingHandler(ctx, + clients.Provisioning.Cluster(), + clusterCreateApply, + "Created", + "cluster-create", + h.generateLegacyClusterFromProvisioningCluster, + &generic.GeneratingHandlerOptions{ + AllowClusterScoped: true, + }, + ) + + clients.Mgmt.Cluster().OnChange(ctx, "cluster-watch", h.createToken) + relatedresource.Watch(ctx, "cluster-watch", h.clusterWatch, + clients.Provisioning.Cluster(), clients.Mgmt.Cluster()) + + clients.Mgmt.Cluster().OnRemove(ctx, "mgmt-cluster-remove", h.OnMgmtClusterRemove) + clients.Provisioning.Cluster().OnRemove(ctx, "provisioning-cluster-remove", h.OnClusterRemove) +} + +func RegisterIndexers(config *wrangler.Context) { + config.Provisioning.Cluster().Cache().AddIndexer(ByCluster, byClusterIndex) + config.Provisioning.Cluster().Cache().AddIndexer(ByCloudCred, byCloudCredentialIndex) +} + +func byClusterIndex(obj *v1.Cluster) ([]string, error) { + if obj.Status.ClusterName == "" { + return nil, nil + } + return []string{obj.Status.ClusterName}, nil +} + +func byCloudCredentialIndex(obj *v1.Cluster) ([]string, error) { + if obj.Spec.CloudCredentialSecretName == "" { + return nil, nil + } + return []string{obj.Spec.CloudCredentialSecretName}, nil +} + +func (h *handler) clusterWatch(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + cluster, ok := obj.(*v3.Cluster) + if !ok { + return nil, nil + } + operatorClusters, err := h.clusterCache.GetByIndex(ByCluster, cluster.Name) + if err != nil || len(operatorClusters) == 0 { + // ignore + return nil, nil + } + return []relatedresource.Key{ + { + Namespace: operatorClusters[0].Namespace, + Name: operatorClusters[0].Name, + }, + }, nil +} + +// isLegacyCluster returns true if the cluster name for a clusters.provisioning.cattle.io/v1 or +// clusters.management.cattle.io/v3 cluster name matches the regex for a legacy cluster (c-XXXXX|local) where XXXXX is a +// random string of characters. +func (h *handler) isLegacyCluster(cluster interface{}) bool { + if c, ok := cluster.(*v3.Cluster); ok { + return mgmtNameRegexp.MatchString(c.Name) + } else if c, ok := cluster.(*v1.Cluster); ok { + return mgmtNameRegexp.MatchString(c.Name) + } + return false +} + +// generateProvisioningClusterFromLegacyCluster will generate a clusters.provisioning.cattle.io/v1 object with a passed +// in clusters.management.cattle.io/v3 object. It will not generate a clusters.provisioning.cattle.io/v1 cluster if the +// cluster FleetWorkspaceName is empty or if the cluster name does not match (c-XXXXX|local) where XXXXX is a random +// string of characters. +func (h *handler) generateProvisioningClusterFromLegacyCluster(cluster *v3.Cluster, status v3.ClusterStatus) ([]runtime.Object, v3.ClusterStatus, error) { + if !h.isLegacyCluster(cluster) || cluster.Spec.FleetWorkspaceName == "" { + return nil, status, nil + } + provCluster := &v1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Name, + Namespace: cluster.Spec.FleetWorkspaceName, + Labels: yaml.CleanAnnotationsForExport(cluster.Labels), + Annotations: yaml.CleanAnnotationsForExport(cluster.Annotations), + }, + } + + if cluster.Spec.ClusterAgentDeploymentCustomization != nil { + clusterAgentCustomizationCopy := cluster.Spec.ClusterAgentDeploymentCustomization.DeepCopy() + provCluster.Spec.ClusterAgentDeploymentCustomization = &v1.AgentDeploymentCustomization{ + AppendTolerations: clusterAgentCustomizationCopy.AppendTolerations, + OverrideAffinity: clusterAgentCustomizationCopy.OverrideAffinity, + OverrideResourceRequirements: clusterAgentCustomizationCopy.OverrideResourceRequirements, + } + } + if cluster.Spec.FleetAgentDeploymentCustomization != nil { + fleetAgentCustomizationCopy := cluster.Spec.FleetAgentDeploymentCustomization.DeepCopy() + provCluster.Spec.FleetAgentDeploymentCustomization = &v1.AgentDeploymentCustomization{ + AppendTolerations: fleetAgentCustomizationCopy.AppendTolerations, + OverrideAffinity: fleetAgentCustomizationCopy.OverrideAffinity, + OverrideResourceRequirements: fleetAgentCustomizationCopy.OverrideResourceRequirements, + } + } + + return []runtime.Object{ + provCluster, + }, status, nil +} + +// generateLegacyClusterFromProvisioningCluster will generate and return a clusters.management.cattle.io/v3 object based +// on the clusters.provisioning.cattle.io/v1 object passed in. +func (h *handler) generateLegacyClusterFromProvisioningCluster(cluster *v1.Cluster, status v1.ClusterStatus) ([]runtime.Object, v1.ClusterStatus, error) { + switch { + case cluster.Spec.ClusterAPIConfig != nil: + return h.createClusterAndDeployAgent(cluster, status) + default: + return h.createCluster(cluster, status, v3.ClusterSpec{ + ImportedConfig: &v3.ImportedConfig{}, + }) + } +} + +func NormalizeCluster(cluster *v3.Cluster, isImportedCluster bool) (runtime.Object, error) { + // We do this so that we don't clobber status because the rancher object is pretty dirty and doesn't have a status subresource + data, err := convert.EncodeToMap(cluster) + if err != nil { + return nil, err + } + spec, _ := data["spec"].(map[string]interface{}) + if _, ok := spec["localClusterAuthEndpoint"]; ok && isImportedCluster { + // For imported clusters, we need to delete the localClusterAuthEndpoint so that it doesn't get overwritten here. + // In general, imported clusters don't support localClusterAuthEndpoint. + // However, imported RKE2/K3S clusters do and this is driven by the management cluster. + delete(spec, "localClusterAuthEndpoint") + } + data = map[string]interface{}{ + "metadata": data["metadata"], + "spec": spec, + } + data["kind"] = "Cluster" + data["apiVersion"] = "management.cattle.io/v3" + return &unstructured.Unstructured{Object: data}, nil +} + +func (h *handler) createToken(_ string, cluster *v3.Cluster) (*v3.Cluster, error) { + if cluster == nil { + return cluster, nil + } + _, err := h.clusterTokenCache.Get(cluster.Name, "default-token") + if apierror.IsNotFound(err) { + _, err = h.clusterTokens.Create(&v3.ClusterRegistrationToken{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-token", + Namespace: cluster.Name, + }, + Spec: v3.ClusterRegistrationTokenSpec{ + ClusterName: cluster.Name, + }, + }) + return cluster, err + } + return cluster, err +} + +func (h *handler) createCluster(cluster *v1.Cluster, status v1.ClusterStatus, spec v3.ClusterSpec) ([]runtime.Object, v1.ClusterStatus, error) { + if h.isLegacyCluster(cluster) { + mgmtCluster, err := h.mgmtClusterCache.Get(cluster.Name) + if err != nil { + return nil, status, err + } + return h.updateStatus(nil, cluster, status, mgmtCluster) + } + return h.createNewCluster(cluster, status, spec) +} + +func mgmtClusterName() (string, error) { + rand, err := randomtoken.Generate() + if err != nil { + return "", err + } + return name.SafeConcatName("c", "m", rand[:8]), nil +} + +// createNewCluster creates a homologated clusters.management.cattle.io/v3 object based on a +// clusters.provisioning.cattle.io/v1 object and the spec of the clusters.management.cattle.io/v3 object passed in. +func (h *handler) createNewCluster(cluster *v1.Cluster, status v1.ClusterStatus, spec v3.ClusterSpec) ([]runtime.Object, v1.ClusterStatus, error) { + spec.DisplayName = cluster.Name + spec.Description = cluster.Annotations["field.cattle.io/description"] + spec.DefaultPodSecurityAdmissionConfigurationTemplateName = cluster.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName + spec.DefaultClusterRoleForProjectMembers = cluster.Spec.DefaultClusterRoleForProjectMembers + spec.EnableNetworkPolicy = cluster.Spec.EnableNetworkPolicy + spec.DesiredAgentImage = image.ResolveWithCluster(settings.AgentImage.Get(), cluster) + spec.DesiredAuthImage = image.ResolveWithCluster(settings.AuthImage.Get(), cluster) + + spec.ClusterSecrets.PrivateRegistrySecret = image.GetPrivateRepoSecretFromCluster(cluster) + spec.ClusterSecrets.PrivateRegistryURL = image.GetPrivateRepoURLFromCluster(cluster) + + spec.AgentEnvVars = nil + for _, env := range cluster.Spec.AgentEnvVars { + spec.AgentEnvVars = append(spec.AgentEnvVars, corev1.EnvVar{ + Name: env.Name, + Value: env.Value, + }) + } + + if cluster.Spec.RKEConfig != nil { + if dir := cluster.Spec.RKEConfig.DataDirectories.SystemAgent; dir != "" { + spec.AgentEnvVars = append(spec.AgentEnvVars, corev1.EnvVar{ + Name: capr.SystemAgentDataDirEnvVar, + Value: dir, + }) + } + } + + switch capr.GetRuntime(cluster.Spec.KubernetesVersion) { + case capr.RuntimeRKE2: + spec.AgentEnvVars = append(spec.AgentEnvVars, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/rke2/bin", + }) + default: + spec.AgentEnvVars = append(spec.AgentEnvVars, corev1.EnvVar{ + Name: capr.SystemAgentFallbackPathEnvVar, + Value: "/opt/bin", + }) + } + + if cluster.Spec.ClusterAgentDeploymentCustomization != nil { + clusterAgentCustomizationCopy := cluster.Spec.ClusterAgentDeploymentCustomization.DeepCopy() + spec.ClusterAgentDeploymentCustomization = &v3.AgentDeploymentCustomization{ + AppendTolerations: clusterAgentCustomizationCopy.AppendTolerations, + OverrideAffinity: clusterAgentCustomizationCopy.OverrideAffinity, + OverrideResourceRequirements: clusterAgentCustomizationCopy.OverrideResourceRequirements, + } + } + if cluster.Spec.FleetAgentDeploymentCustomization != nil { + fleetAgentCustomizationCopy := cluster.Spec.FleetAgentDeploymentCustomization.DeepCopy() + spec.FleetAgentDeploymentCustomization = &v3.AgentDeploymentCustomization{ + AppendTolerations: fleetAgentCustomizationCopy.AppendTolerations, + OverrideAffinity: fleetAgentCustomizationCopy.OverrideAffinity, + OverrideResourceRequirements: fleetAgentCustomizationCopy.OverrideResourceRequirements, + } + } + + if cluster.Spec.RKEConfig != nil { + if err := h.updateFeatureLockedValue(true); err != nil { + return nil, status, err + } + } + + spec.LocalClusterAuthEndpoint = v3.LocalClusterAuthEndpoint{ + FQDN: cluster.Spec.LocalClusterAuthEndpoint.FQDN, + CACerts: cluster.Spec.LocalClusterAuthEndpoint.CACerts, + Enabled: cluster.Spec.LocalClusterAuthEndpoint.Enabled, + } + + newCluster := &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Status.ClusterName, + Labels: cluster.Labels, + Annotations: map[string]string{administratedAnn: strconv.FormatBool(cluster.Spec.RKEConfig != nil)}, + }, + Spec: spec, + } + + if mgmtClusterNameAnnVal, ok := cluster.Annotations[mgmtClusterNameAnn]; ok && mgmtClusterNameAnnVal != "" && newCluster.Name == "" { + // If the management cluster name annotation is set to a non-empty value, and the mgmt cluster name has not been set yet, set the cluster name to the mgmt cluster name. + newCluster.Name = mgmtClusterNameAnnVal + } else if newCluster.Name == "" { + // If the management cluster name annotation is not set and the cluster name has not yet been generated, generate and set a new mgmt cluster name. + mgmtName, err := mgmtClusterName() + if err != nil { + return nil, status, err + } + newCluster.Name = mgmtName + } + + for k, v := range cluster.Annotations { + newCluster.Annotations[k] = v + } + + delete(cluster.Annotations, creatorIDAnn) + + if features.ProvisioningV2FleetWorkspaceBackPopulation.Enabled() { + if forcedFleetWorkspaceName, ok := cluster.Annotations[fleetWorkspaceNameAnn]; ok && forcedFleetWorkspaceName != "" { // force set the fleet workspace name + newCluster.Spec.FleetWorkspaceName = forcedFleetWorkspaceName + } else { + if err := h.backpopulateMgmtClusterFleetWorkspaceName(newCluster); err != nil { + return nil, status, err + } + if newCluster.Spec.FleetWorkspaceName == "" { // fall back to using the provisioning cluster namespace as the fleet workspace name + newCluster.Spec.FleetWorkspaceName = cluster.Namespace + } + } + } else { + newCluster.Spec.FleetWorkspaceName = cluster.Namespace + } + + status.FleetWorkspaceName = newCluster.Spec.FleetWorkspaceName + + normalizedCluster, err := NormalizeCluster(newCluster, cluster.Spec.RKEConfig == nil) + if err != nil { + return nil, status, err + } + + return h.updateStatus([]runtime.Object{ + normalizedCluster, + }, cluster, status, newCluster) +} + +// backpopulateMgmtClusterFleetWorkspaceName backpopulates the fleet workspace name field from the v3 management cluster object onto the new desired object +func (h *handler) backpopulateMgmtClusterFleetWorkspaceName(rCluster *v3.Cluster) error { + if rCluster == nil { + return nil + } + existing, err := h.mgmtClusterCache.Get(rCluster.Name) + if err != nil && !apierror.IsNotFound(err) { + return err + } + if existing != nil { + rCluster.Spec.FleetWorkspaceName = existing.Spec.FleetWorkspaceName + } + return nil +} + +// updateStatus will update the status on the clusters.provisioning.cattle.io/v1 object. +func (h *handler) updateStatus(objs []runtime.Object, cluster *v1.Cluster, status v1.ClusterStatus, rCluster *v3.Cluster) ([]runtime.Object, v1.ClusterStatus, error) { + ready := false + existing, err := h.mgmtClusterCache.Get(rCluster.Name) + if err != nil && !apierror.IsNotFound(err) { + return nil, status, err + } else if err == nil { + if condition.Cond("Ready").IsTrue(existing) { + ready = true + } + for _, messageCond := range existing.Status.Conditions { + if messageCond.Type == "Updated" || messageCond.Type == "Provisioned" || messageCond.Type == "Removed" || (cluster.Spec.RKEConfig != nil && messageCond.Type == "Ready") { + // Don't copy these conditions from v3 management object to the v1 provisioning object. This is because we copy these specific conditions from other places and we need to prevent clobbering. + // Updated - This is copied from the rkecontrolplane Ready condition to the v1 object by the rke2/provisioningcluster/controller.go via the reconcile function + // Provisioned - This is copied from the rkecontrolplane Ready condition to the v1 object by the rke2/provisioningcluster/controller.go via the reconcile function + // Removed - This is copied from the rkecontrolplane Removed condition on rkecontrolplane deletion. + // Ready - Conditionally, if RKEConfig != nil. This is copied from the rkecontrolplane Ready condition (if cluster is not stable) or v3/management cluster Ready condition (if cluster is stable) by the rke2/provisioningcluster/controller.go via the reconcile function + continue + } + + found := false + newCond := genericcondition.GenericCondition{ + Type: string(messageCond.Type), + Status: messageCond.Status, + LastUpdateTime: messageCond.LastUpdateTime, + LastTransitionTime: messageCond.LastTransitionTime, + Reason: messageCond.Reason, + Message: messageCond.Message, + } + for i, provCond := range status.Conditions { + if provCond.Type != string(messageCond.Type) { + continue + } + found = true + status.Conditions[i] = newCond + } + if !found { + status.Conditions = append(status.Conditions, newCond) + } + } + status.AgentDeployed = v3.ClusterConditionAgentDeployed.IsTrue(existing) + } + + // Never set ready back to false because we will end up deleting the secret + status.Ready = status.Ready || ready + status.ObservedGeneration = cluster.Generation + status.ClusterName = rCluster.Name + if status.Ready { + kstatus.SetActive(&status) + } else { + kstatus.SetTransitioning(&status, "") + } + + if status.Ready { + secret, err := h.kubeconfigManager.GetKubeConfig(cluster, status) + if err != nil { + return nil, status, err + } + if secret != nil { + status.ClientSecretName = secret.Name + + if features.MCM.Enabled() { + crtb, err := h.kubeconfigManager.GetCRTBForClusterOwner(cluster, status) + if err != nil { + return nil, status, err + } + objs = append(objs, crtb) + } else if cluster.Namespace == fleetconst.ClustersLocalNamespace && cluster.Name == "local" { + user, err := h.kubeconfigManager.EnsureUser(cluster.Namespace, cluster.Name) + if err != nil { + return objs, status, err + } + objs = append(objs, &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fleet-local-cluster-admin", + }, + Subjects: []rbacv1.Subject{{ + Kind: "User", + APIGroup: rbacv1.GroupName, + Name: user, + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: "cluster-admin", + }, + }) + } + } + } + + return objs, status, nil +} + +func (h *handler) updateFeatureLockedValue(lockValueToTrue bool) error { + feature, err := h.featureCache.Get(features.RKE2.Name()) + if err != nil { + return err + } + + if feature.Status.LockedValue == nil && !lockValueToTrue || feature.Status.LockedValue != nil && *feature.Status.LockedValue == lockValueToTrue { + return nil + } + + feature = feature.DeepCopy() + if lockValueToTrue { + feature.Status.LockedValue = &lockValueToTrue + } else { + clusters, err := h.clusters.Cache().List("", labels.Everything()) + if err != nil { + return err + } + + for _, cluster := range clusters { + if cluster.DeletionTimestamp.IsZero() && !h.isLegacyCluster(cluster) && cluster.Spec.RKEConfig != nil { + return nil + } + } + feature.Status.LockedValue = nil + } + + _, err = h.featureClient.Update(feature) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller_test.go new file mode 100644 index 0000000..17368bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/controller_test.go @@ -0,0 +1,254 @@ +package cluster + +import ( + "encoding/json" + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestRegexp(t *testing.T) { + assert.True(t, mgmtNameRegexp.MatchString("local")) + assert.False(t, mgmtNameRegexp.MatchString("alocal")) + assert.False(t, mgmtNameRegexp.MatchString("localb")) + assert.True(t, mgmtNameRegexp.MatchString("c-12345")) + assert.False(t, mgmtNameRegexp.MatchString("ac-12345")) + assert.False(t, mgmtNameRegexp.MatchString("c-12345b")) + assert.False(t, mgmtNameRegexp.MatchString("ac-12345b")) +} + +func TestController_generateProvisioningClusterFromLegacyCluster(t *testing.T) { + tests := []struct { + name string + cluster *v3.Cluster + }{ + { + name: "test-default", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-11111", + }, + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{}, + FleetWorkspaceName: "test-fleet-workspace-name", + }, + }, + }, + { + name: "test-cluster-agent-customization", + cluster: &v3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-22222", + }, + Spec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{ + ClusterAgentDeploymentCustomization: getTestClusterAgentCustomizationV3(), + FleetAgentDeploymentCustomization: getTestFleetAgentCustomizationV3(), + }, + FleetWorkspaceName: "test-fleet-workspace-name", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := handler{} + + obj, _, err := h.generateProvisioningClusterFromLegacyCluster(tt.cluster, tt.cluster.Status) + + assert.Nil(t, err) + assert.NotNil(t, obj, "Expected non-nil prov cluster obj") + provCluster := obj[0].(*v1.Cluster) + + switch tt.name { + case "test-default": + assert.Nil(t, provCluster.Spec.ClusterAgentDeploymentCustomization) + assert.Nil(t, provCluster.Spec.FleetAgentDeploymentCustomization) + case "test-cluster-agent-customization": + assert.Equal(t, getTestClusterAgentCustomizationV1(), provCluster.Spec.ClusterAgentDeploymentCustomization) + assert.Equal(t, getTestFleetAgentCustomizationV1(), provCluster.Spec.FleetAgentDeploymentCustomization) + } + }) + } +} + +func TestController_createNewCluster(t *testing.T) { + tests := []struct { + name string + cluster *v1.Cluster + clusterSpec v3.ClusterSpec + }{ + { + name: "test-default", + cluster: &v1.Cluster{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: v1.ClusterSpec{}, + }, + clusterSpec: v3.ClusterSpec{}, + }, + { + name: "test-cluster-agent-customization", + cluster: &v1.Cluster{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: v1.ClusterSpec{ + ClusterAgentDeploymentCustomization: getTestClusterAgentCustomizationV1(), + FleetAgentDeploymentCustomization: getTestFleetAgentCustomizationV1(), + }, + }, + clusterSpec: v3.ClusterSpec{ + ClusterSpecBase: v3.ClusterSpecBase{}, + }, + }, + } + + mockCtrl := gomock.NewController(t) + clusterCache := fake.NewMockNonNamespacedCacheInterface[*v3.Cluster](mockCtrl) + clusterCache.EXPECT().Get(gomock.AssignableToTypeOf("")).Return(&v3.Cluster{}, nil).AnyTimes() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := handler{ + mgmtClusterCache: clusterCache, + } + + obj, _, err := h.createNewCluster(tt.cluster, tt.cluster.Status, tt.clusterSpec) + + assert.Nil(t, err) + assert.NotNil(t, obj, "Expected non-nil v3 cluster obj") + jsonData, _ := json.Marshal(obj[0]) + var legacyCluster v3.Cluster + json.Unmarshal(jsonData, &legacyCluster) + + switch tt.name { + case "test-default": + assert.Nil(t, legacyCluster.Spec.ClusterAgentDeploymentCustomization) + assert.Nil(t, legacyCluster.Spec.FleetAgentDeploymentCustomization) + case "test-cluster-agent-customization": + assert.Equal(t, getTestClusterAgentCustomizationV3(), legacyCluster.Spec.ClusterAgentDeploymentCustomization) + assert.Equal(t, getTestFleetAgentCustomizationV3(), legacyCluster.Spec.FleetAgentDeploymentCustomization) + } + }) + } +} + +func getTestClusterAgentCustomizationV1() *v1.AgentDeploymentCustomization { + return &v1.AgentDeploymentCustomization{ + AppendTolerations: getTestClusterAgentToleration(), + OverrideAffinity: getTestClusterAgentAffinity(), + OverrideResourceRequirements: getTestClusterAgentResourceReq(), + } +} + +func getTestClusterAgentCustomizationV3() *v3.AgentDeploymentCustomization { + return &v3.AgentDeploymentCustomization{ + AppendTolerations: getTestClusterAgentToleration(), + OverrideAffinity: getTestClusterAgentAffinity(), + OverrideResourceRequirements: getTestClusterAgentResourceReq(), + } +} + +func getTestFleetAgentCustomizationV1() *v1.AgentDeploymentCustomization { + return &v1.AgentDeploymentCustomization{ + AppendTolerations: getTestFleetAgentToleration(), + OverrideAffinity: getTestFleetAgentAffinity(), + OverrideResourceRequirements: getTestFleetAgentResourceReq(), + } +} + +func getTestFleetAgentCustomizationV3() *v3.AgentDeploymentCustomization { + return &v3.AgentDeploymentCustomization{ + AppendTolerations: getTestFleetAgentToleration(), + OverrideAffinity: getTestFleetAgentAffinity(), + OverrideResourceRequirements: getTestFleetAgentResourceReq(), + } +} + +func getTestClusterAgentToleration() []corev1.Toleration { + return []corev1.Toleration{{ + Effect: "NoSchedule", + Key: "node-role.kubernetes.io/controlplane-test", + Value: "true", + }, + } +} + +func getTestClusterAgentAffinity() *corev1.Affinity { + return &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "cattle.io/cluster-agent-test", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } +} + +func getTestClusterAgentResourceReq() *corev1.ResourceRequirements { + return &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("500m"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("250Mi"), + }, + } +} + +func getTestFleetAgentToleration() []corev1.Toleration { + return []corev1.Toleration{ + { + Key: "key", + Operator: corev1.TolerationOpEqual, + Value: "value", + }, + } +} + +func getTestFleetAgentAffinity() *corev1.Affinity { + return &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "fleet.cattle.io/agent", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } +} + +func getTestFleetAgentResourceReq() *corev1.ResourceRequirements { + return &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/import.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/import.go new file mode 100644 index 0000000..1bdc599 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/import.go @@ -0,0 +1,136 @@ +package cluster + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "net/http" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/yaml" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/clientcmd" +) + +func (h *handler) createClusterAndDeployAgent(cluster *v1.Cluster, status v1.ClusterStatus) ([]runtime.Object, v1.ClusterStatus, error) { + objs, status, err := h.createCluster(cluster, status, v3.ClusterSpec{ + ImportedConfig: &v3.ImportedConfig{}, + }) + if err != nil { + return nil, status, err + } + + if status.AgentDeployed || status.ClusterName == "" { + return objs, status, nil + } + + ok, err := h.deployAgent(cluster, status) + if err != nil { + return objs, status, err + } + + status.AgentDeployed = ok + return objs, status, nil +} + +func (h *handler) deployAgent(cluster *v1.Cluster, status v1.ClusterStatus) (bool, error) { + if _, err := h.mgmtClusterCache.Get(status.ClusterName); apierror.IsNotFound(err) { + h.clusters.EnqueueAfter(cluster.Namespace, cluster.Name, 2*time.Second) + // wait until the cluster is created + return false, nil + } else if err != nil { + return false, err + } + + tokens, err := h.clusterTokenCache.List(status.ClusterName, labels.Everything()) + if err != nil { + return false, err + } + + if len(tokens) == 0 { + h.clusters.EnqueueAfter(cluster.Namespace, cluster.Name, 2*time.Second) + return false, err + } + + tokenValue := tokens[0].Status.Token + if tokenValue == "" { + h.clusters.EnqueueAfter(cluster.Namespace, cluster.Name, 2*time.Second) + return false, nil + } + + secretName := fmt.Sprintf("%s-kubeconfig", cluster.Spec.ClusterAPIConfig.ClusterName) + return true, h.deploy(cluster, cluster.Namespace, secretName, tokenValue) +} + +func (h *handler) deploy(cluster *v1.Cluster, secretNamespace, secretName string, token string) error { + secret, err := h.secretCache.Get(secretNamespace, secretName) + if apierror.IsNotFound(err) { + h.clusters.EnqueueAfter(cluster.Namespace, cluster.Name, 2*time.Second) + return generic.ErrSkip + } else if err != nil { + return err + } + + if len(secret.Data) == 0 { + h.clusters.EnqueueAfter(cluster.Namespace, cluster.Name, 2*time.Second) + return generic.ErrSkip + } + + cfg, err := clientcmd.RESTConfigFromKubeConfig(secret.Data["value"]) + if err != nil { + return err + } + + serverURL, cacert := settings.InternalServerURL.Get(), settings.InternalCACerts.Get() + + httpClient, err := h.httpClientForCA(cacert) + if err != nil { + return err + } + + resp, err := httpClient.Get(fmt.Sprintf("%s/v3/import/%s.yaml", serverURL, token)) + if err != nil { + return err + } + defer resp.Body.Close() + + objs, err := yaml.ToObjects(resp.Body) + if err != nil { + return err + } + + apply, err := apply.NewForConfig(cfg) + if err != nil { + return err + } + + return apply. + WithDynamicLookup(). + WithSetID("cluster-agent-setup"). + ApplyObjects(objs...) +} + +func (h *handler) httpClientForCA(cacert string) (*http.Client, error) { + if cacert == "" { + return http.DefaultClient, nil + } + + pool := x509.NewCertPool() + pool.AppendCertsFromPEM([]byte(cacert)) + + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tls.Config{ + RootCAs: pool, + } + + return &http.Client{ + Transport: transport, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/remove.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/remove.go new file mode 100644 index 0000000..5848bb1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/cluster/remove.go @@ -0,0 +1,132 @@ +package cluster + +import ( + "fmt" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/apimachinery/pkg/api/equality" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func (h *handler) OnMgmtClusterRemove(_ string, cluster *v3.Cluster) (*v3.Cluster, error) { + provisioningClusters, err := h.clusterCache.GetByIndex(ByCluster, cluster.Name) + if err != nil { + return nil, err + } + + var legacyCluster bool + for _, provisioningCluster := range provisioningClusters { + legacyCluster = legacyCluster || h.isLegacyCluster(provisioningCluster) + if err := h.clusters.Delete(provisioningCluster.Namespace, provisioningCluster.Name, nil); err != nil { + return nil, err + } + } + + if len(provisioningClusters) == 0 || legacyCluster { + // If any of the provisioning clusters are legacy clusters (i.e. RKE1 clusters) then we don't wait for the + // provisioning clusters to be deleted because the provisioning cluster is waiting for the management cluster to delete. + return cluster, nil + } + + h.mgmtClusters.EnqueueAfter(cluster.Name, 5*time.Second) + // generic.ErrSkip will mark the cluster object as reconciled, but won't remove the finalizer. + // The finalizer should be removed after the provisioning cluster is gone. + return cluster, generic.ErrSkip +} + +func (h *handler) OnClusterRemove(_ string, cluster *v1.Cluster) (*v1.Cluster, error) { + oldStatus := cluster.Status + cluster = cluster.DeepCopy() + + err := capr.DoRemoveAndUpdateStatus(cluster, h.doClusterRemove(cluster), h.clusters.EnqueueAfter) + + if equality.Semantic.DeepEqual(oldStatus, cluster.Status) { + return cluster, err + } + + cluster, updateErr := h.clusters.UpdateStatus(cluster) + if updateErr != nil { + return cluster, updateErr + } + + return cluster, err +} + +func (h *handler) doClusterRemove(cluster *v1.Cluster) func() (string, error) { + return func() (string, error) { + if cluster.Status.ClusterName != "" { + mgmtCluster, err := h.mgmtClusters.Get(cluster.Status.ClusterName, metav1.GetOptions{}) + if err != nil { + // We do nothing if the management cluster does not exist (IsNotFound) because it's been deleted. + if !apierrors.IsNotFound(err) { + return "", err + } + } else if cluster.Namespace == mgmtCluster.Spec.FleetWorkspaceName { + // We only delete the management cluster if its FleetWorkspaceName matches the provisioning cluster's + // namespace. The reason: if there's a mismatch, we know that the provisioning cluster needs to be migrated + // because the user moved the Fleet cluster (and provisioning cluster, by extension) to another + // FleetWorkspace. Ultimately, the aforementioned cluster objects are re-created in another namespace. + err := h.mgmtClusters.Delete(cluster.Status.ClusterName, nil) + if err != nil && !apierrors.IsNotFound(err) { + return "", err + } + + if h.isLegacyCluster(cluster) { + // If this is a legacy cluster (i.e. RKE1 cluster) then we should wait to remove the provisioning cluster until the v3.Cluster is gone. + _, err = h.mgmtClusterCache.Get(cluster.Status.ClusterName) + if !apierrors.IsNotFound(err) { + return fmt.Sprintf("waiting for cluster [%s] to delete", cluster.Status.ClusterName), nil + } + } else { + if err = h.updateFeatureLockedValue(false); err != nil { + return "", err + } + } + } + } + + capiCluster, capiClusterErr := h.capiClustersCache.Get(cluster.Namespace, cluster.Name) + if capiClusterErr != nil && !apierrors.IsNotFound(capiClusterErr) { + return "", capiClusterErr + } + + if capiCluster != nil { + if capiCluster.DeletionTimestamp == nil { + // Deleting the CAPI cluster will start the process of deleting Machines, Bootstraps, etc. + if err := h.capiClusters.Delete(capiCluster.Namespace, capiCluster.Name, &metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + return "", err + } + } + + _, err := h.rkeControlPlanesCache.Get(cluster.Namespace, cluster.Name) + if err != nil && !apierrors.IsNotFound(err) { + return "", err + } else if err == nil { + return "", generic.ErrSkip + } + } + + machines, err := h.capiMachinesCache.List(cluster.Namespace, labels.SelectorFromSet(labels.Set{capi.ClusterNameLabel: cluster.Name})) + if err != nil { + return "", err + } + + // Machines will delete first so report their status, if any exist. + if len(machines) > 0 { + return capr.GetMachineDeletionStatus(machines) + } + + if capiClusterErr == nil { + return fmt.Sprintf("waiting for cluster-api cluster [%s] to delete", cluster.Name), nil + } + + return "", h.kubeconfigManager.DeleteUser(cluster.Namespace, cluster.Name) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/controllers.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/controllers.go new file mode 100644 index 0000000..0a6bb9b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/controllers.go @@ -0,0 +1,31 @@ +package provisioningv2 + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/fleetcluster" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/fleetworkspace" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/managedchart" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/provisioningcluster" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/provisioninglog" + "github.com/rancher/rancher/pkg/controllers/provisioningv2/secret" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Register(ctx context.Context, clients *wrangler.Context, kubeconfigManager *kubeconfig.Manager) { + cluster.Register(ctx, clients, kubeconfigManager) + if features.MCM.Enabled() { + secret.Register(ctx, clients) + } + provisioningcluster.Register(ctx, clients) + provisioninglog.Register(ctx, clients) + + if features.Fleet.Enabled() { + managedchart.Register(ctx, clients) + fleetcluster.Register(ctx, clients) + fleetworkspace.Register(ctx, clients) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster.go new file mode 100644 index 0000000..0348ebc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster.go @@ -0,0 +1,232 @@ +package fleetcluster + +import ( + "context" + "os" + "time" + + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + mgmtcluster "github.com/rancher/rancher/pkg/cluster" + fleetconst "github.com/rancher/rancher/pkg/fleet" + fleetpkg "github.com/rancher/rancher/pkg/fleet" + fleetcontrollers "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rocontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/provisioningv2/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/apply" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/yaml" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/client-go/tools/clientcmd" +) + +// ClusterHostGetter provides cluster API server URL retrieval. +type ClusterHostGetter interface { + GetClusterHost(clientcmd.ClientConfig) (string, []byte, error) +} + +type fleetHostGetter struct{} + +// GetClusterHost enables fleetHostGetter to implement interface ClusterHostGetter. +func (g fleetHostGetter) GetClusterHost(cfg clientcmd.ClientConfig) (string, []byte, error) { + return fleetpkg.GetClusterHost(cfg) +} + +type handler struct { + clientConfig clientcmd.ClientConfig + clusters v3.ClusterClient + clustersCache v3.ClusterCache + hostGetter ClusterHostGetter + secretsController corecontrollers.SecretController + fleetClusters fleetcontrollers.ClusterController + apply apply.Apply + getPrivateRepoURL func(*provv1.Cluster, *apimgmtv3.Cluster) string +} + +// Register registers the fleetcluster controller, which is responsible for creating fleet cluster objects. +// When fleet cluster objects are created, Fleet uses the object to deploy the fleet-agent into the cluster. Notably, +// the fleetcluster operates on both provisioning and management clusters in Rancher, by way of transformation logic +// in the provisioningcluster rke2 controller (a clusters.provisioning.cattle.io/v1 object is generated for every +// corresponding clusters.management.cattle.io/v3 object, if one does not already exist, and vice-versa) +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + clientConfig: clients.ClientConfig, + clusters: clients.Mgmt.Cluster(), + clustersCache: clients.Mgmt.Cluster().Cache(), + hostGetter: fleetHostGetter{}, + secretsController: clients.Core.Secret(), + fleetClusters: clients.Fleet.Cluster(), + apply: clients.Apply.WithCacheTypes(clients.Provisioning.Cluster()), + } + + h.getPrivateRepoURL = func(cluster *provv1.Cluster, mgmtCluster *apimgmtv3.Cluster) string { + if cluster.Spec.RKEConfig == nil { + // If the RKEConfig is nil, we are likely dealing with + // a legacy (v3/mgmt) cluster, and need to check the v3 + // cluster for the cluster level registry. + return mgmtcluster.GetPrivateRegistryURL(mgmtCluster) + } + return image.GetPrivateRepoURLFromCluster(cluster) + } + + rocontrollers.RegisterClusterGeneratingHandler(ctx, + clients.Provisioning.Cluster(), + clients.Apply. + WithCacheTypes(clients.Fleet.Cluster(), + clients.Fleet.ClusterGroup(), + clients.Provisioning.Cluster()), + "", + "fleet-cluster", + h.createCluster, + nil, + ) + + clients.Mgmt.Cluster().OnChange(ctx, "fleet-cluster-assign", h.assignWorkspace) + clients.Fleet.Cluster().OnChange(ctx, "fleet-local-agent-migration", h.ensureAgentMigrated) +} + +func (h *handler) assignWorkspace(key string, cluster *apimgmtv3.Cluster) (*apimgmtv3.Cluster, error) { + if cluster == nil { + return cluster, nil + } + + if cluster.Spec.Internal && cluster.Spec.FleetWorkspaceName == "" { + newCluster := cluster.DeepCopy() + newCluster.Spec.FleetWorkspaceName = fleetconst.ClustersLocalNamespace + return h.clusters.Update(newCluster) + } else if cluster.Spec.Internal { + return cluster, nil + } + + if cluster.Spec.FleetWorkspaceName == "" { + def := settings.FleetDefaultWorkspaceName.Get() + if def == "" { + return cluster, nil + } + + newCluster := cluster.DeepCopy() + newCluster.Spec.FleetWorkspaceName = def + return h.clusters.Update(newCluster) + } + + return cluster, nil +} + +func (h *handler) ensureAgentMigrated(key string, cluster *fleet.Cluster) (*fleet.Cluster, error) { + if cluster != nil && cluster.Name == "local" && cluster.Namespace == fleetconst.ClustersLocalNamespace && + cluster.Spec.AgentNamespace == "" { + // keep re-enqueueing until agentNamespace is set. This happens before the fleet + // CRD is upgraded to include the new agentNamespace field + h.fleetClusters.EnqueueAfter(cluster.Namespace, cluster.Name, 5*time.Second) + } + return cluster, nil +} + +func (h *handler) createCluster(cluster *provv1.Cluster, status provv1.ClusterStatus) ([]runtime.Object, provv1.ClusterStatus, error) { + if status.ClusterName == "" || status.ClientSecretName == "" { + return nil, status, nil + } + + mgmtCluster, err := h.clustersCache.Get(status.ClusterName) + if err != nil { + return nil, status, err + } + + if !apimgmtv3.ClusterConditionReady.IsTrue(mgmtCluster) { + return nil, status, generic.ErrSkip + } + + if mgmtCluster.Spec.FleetWorkspaceName == "" { + // Only create a cluster if the fleet workspace name is set on the management cluster object, otherwise, apply an empty set of objects. + return nil, status, nil + } + + // this removes any annotations containing "cattle.io" or starting with "kubectl.kubernetes.io" + labels := yaml.CleanAnnotationsForExport(mgmtCluster.Labels) + labels["management.cattle.io/cluster-name"] = mgmtCluster.Name + if errs := validation.IsValidLabelValue(mgmtCluster.Spec.DisplayName); len(errs) == 0 { + labels["management.cattle.io/cluster-display-name"] = mgmtCluster.Spec.DisplayName + } + + agentNamespace := "" + clientSecret := status.ClientSecretName + + objs := []runtime.Object{} + if mgmtCluster.Spec.Internal { + // When not running inside a cluster (which may happen in local dev setups), do not populate API server + // host and CA information which then comes from the local host + if os.Getenv("KUBERNETES_PORT") != "" { + h.addAPIServer(clientSecret) + } + + agentNamespace = fleetconst.ReleaseLocalNamespace + // restore fleet's hardcoded name label for the local cluster + labels["name"] = "local" + // default cluster group, used if fleet bundle has no targets, uses hardcoded name label + objs = append(objs, &fleet.ClusterGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + Namespace: cluster.Namespace, + }, + Spec: fleet.ClusterGroupSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"name": "local"}, + }, + }, + }) + } + + agentAffinity, err := mgmtcluster.GetFleetAgentAffinity(mgmtCluster) + if err != nil { + return nil, status, err + } + + return append(objs, &fleet.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Name, + Namespace: mgmtCluster.Spec.FleetWorkspaceName, + Labels: labels, + }, + Spec: fleet.ClusterSpec{ + KubeConfigSecret: clientSecret, + KubeConfigSecretNamespace: cluster.Namespace, + AgentEnvVars: mgmtCluster.Spec.AgentEnvVars, + AgentNamespace: agentNamespace, + PrivateRepoURL: h.getPrivateRepoURL(cluster, mgmtCluster), + AgentTolerations: mgmtcluster.GetFleetAgentTolerations(mgmtCluster), + AgentAffinity: agentAffinity, + AgentResources: mgmtcluster.GetFleetAgentResourceRequirements(mgmtCluster), + }, + }), status, nil +} + +// addAPIServer populates the internal API server URL and CA into the provided secret, which should be used as the +// KubeConfig secret in the local cluster. +func (h *handler) addAPIServer(clientSecret string) { + secret, err := h.secretsController.Cache().Get(fleetconst.ClustersLocalNamespace, clientSecret) + if err != nil { + logrus.Warnf("local cluster provisioning: failed to get client secret: %v", err) + return + } + + host, ca, err := h.hostGetter.GetClusterHost(h.clientConfig) + if err != nil { + logrus.Warnf("local cluster provisioning: failed to get internal API server URL: %v", err) + return + } + + secret.Data["apiServerURL"] = []byte(host) + secret.Data["apiServerCA"] = ca + + if _, err := h.secretsController.Update(secret); err != nil { + logrus.Warnf("local cluster provisioning: failed to update client secret: %v", err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster_test.go new file mode 100644 index 0000000..72f16fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/fleetcluster_test.go @@ -0,0 +1,362 @@ +// mockgen --build_flags=--mod=mod -package fleetcluster -destination=./mock_cluster_host_getter_test.go github.com/rancher/rancher/pkg/controllers/provisioningv2/fleetcluster ClusterHostGetter +package fleetcluster + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + errNotImplemented = fmt.Errorf("unimplemented") + errNotFound = fmt.Errorf("not found") + + builtinAffinity = corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "fleet.cattle.io/agent", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } + linuxAffinity = corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + } + resourceReq = &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + } + tolerations = []corev1.Toleration{ + { + Key: "key", + Operator: corev1.TolerationOpEqual, + Value: "value", + }, + } +) + +func TestClusterCustomization(t *testing.T) { + require := require.New(t) + + h := &handler{ + getPrivateRepoURL: func(*provv1.Cluster, *apimgmtv3.Cluster) string { return "" }, + } + + cluster := &provv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", Namespace: "test-namespace", + }, + Spec: provv1.ClusterSpec{}, + } + clusterStatus := provv1.ClusterStatus{ClusterName: "cluster-name", ClientSecretName: "client-secret-name"} + + labels := map[string]string{"cluster-group": "cluster-group-name"} + + tests := []struct { + name string + cluster *provv1.Cluster + status provv1.ClusterStatus + cachedClusters map[string]*apimgmtv3.Cluster + expectedFleet *fleet.Cluster + }{ + { + "cluster-has-no-customization", + cluster, + clusterStatus, + map[string]*apimgmtv3.Cluster{ + "cluster-name": newMgmtCluster( + "cluster-name", + labels, + apimgmtv3.ClusterSpec{ + FleetWorkspaceName: "fleet-default", + }, + ), + }, + &fleet.Cluster{ + Spec: fleet.ClusterSpec{ + AgentAffinity: &builtinAffinity, + }, + }, + }, + { + "cluster-has-affinity-override", + cluster, + clusterStatus, + map[string]*apimgmtv3.Cluster{ + "cluster-name": newMgmtCluster( + "cluster-name", + labels, + apimgmtv3.ClusterSpec{ + FleetWorkspaceName: "fleet-default", + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + FleetAgentDeploymentCustomization: &apimgmtv3.AgentDeploymentCustomization{ + OverrideAffinity: &linuxAffinity, + OverrideResourceRequirements: &corev1.ResourceRequirements{}, + AppendTolerations: []corev1.Toleration{}, + }, + }, + }, + ), + }, + &fleet.Cluster{ + Spec: fleet.ClusterSpec{ + AgentAffinity: &linuxAffinity, + AgentResources: &corev1.ResourceRequirements{}, + AgentTolerations: []corev1.Toleration{}, + }, + }, + }, + { + "cluster-has-custom-tolerations-and-resources", + cluster, + clusterStatus, + map[string]*apimgmtv3.Cluster{ + "cluster-name": newMgmtCluster( + "cluster-name", + labels, + apimgmtv3.ClusterSpec{ + FleetWorkspaceName: "fleet-default", + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + FleetAgentDeploymentCustomization: &apimgmtv3.AgentDeploymentCustomization{ + OverrideAffinity: nil, + OverrideResourceRequirements: resourceReq, + AppendTolerations: tolerations, + }, + }, + }, + ), + }, + &fleet.Cluster{ + Spec: fleet.ClusterSpec{ + AgentAffinity: &builtinAffinity, + AgentResources: resourceReq, + AgentTolerations: tolerations, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + + h.clustersCache = newClusterCache(t, ctrl, tt.cachedClusters) + objs, _, err := h.createCluster(tt.cluster, tt.status) + require.Nil(err) + require.NotNil(objs) + + require.Equal(1, len(objs)) + + fleetCluster, ok := objs[0].(*fleet.Cluster) + if !ok { + t.Errorf("Expected fleet cluster, got %t", objs[0]) + } + + require.Equal(tt.expectedFleet.Spec.AgentAffinity, fleetCluster.Spec.AgentAffinity) + require.Equal(tt.expectedFleet.Spec.AgentResources, fleetCluster.Spec.AgentResources) + require.Equal(tt.expectedFleet.Spec.AgentTolerations, fleetCluster.Spec.AgentTolerations) + }) + } + +} + +func TestCreateCluster(t *testing.T) { + h := &handler{ + getPrivateRepoURL: func(*provv1.Cluster, *apimgmtv3.Cluster) string { return "" }, + } + + tests := []struct { + name string + cluster *provv1.Cluster + status provv1.ClusterStatus + cachedClusters map[string]*apimgmtv3.Cluster + expectedLen int + }{ + { + name: "creates only cluster when external", + cluster: &provv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Namespace: "fleet-default", + }, + Spec: provv1.ClusterSpec{}, + }, + status: provv1.ClusterStatus{ + ClusterName: "cluster-name", + ClientSecretName: "client-secret-name", + }, + + cachedClusters: map[string]*apimgmtv3.Cluster{ + "cluster-name": newMgmtCluster( + "cluster-name", + map[string]string{ + "cluster-group": "cluster-group-name", + }, + apimgmtv3.ClusterSpec{ + FleetWorkspaceName: "fleet-default", + Internal: false, + }, + ), + }, + expectedLen: 1, // cluster only + }, + { + name: "creates internal cluster and cluster group", + cluster: &provv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "local-cluster", + Namespace: "fleet-local", + }, + Spec: provv1.ClusterSpec{}, + }, + status: provv1.ClusterStatus{ + ClusterName: "local-cluster", + ClientSecretName: "local-kubeconfig", + }, + cachedClusters: map[string]*apimgmtv3.Cluster{ + "local-cluster": newMgmtCluster( + "local-cluster", + map[string]string{ + "cluster-group": "default", + }, + apimgmtv3.ClusterSpec{ + FleetWorkspaceName: "fleet-local", + Internal: true, + }, + ), + }, + expectedLen: 2, // cluster and cluster group + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + + h.clustersCache = newClusterCache(t, ctrl, tt.cachedClusters) + + objs, _, err := h.createCluster(tt.cluster, tt.status) + + if objs == nil { + t.Errorf("Expected non-nil objs: %v", err) + } + + if err != nil { + t.Errorf("Expected nil err") + } + + if len(objs) != tt.expectedLen { + t.Errorf("Expected %d objects, got %d", tt.expectedLen, len(objs)) + } + + foundCluster := false + for _, obj := range objs { + cluster, ok := obj.(*fleet.Cluster) + + if !ok { + continue + } + + if cluster.Name == tt.cluster.Name && cluster.Namespace == tt.cluster.Namespace { + foundCluster = true + } + } + + if !foundCluster { + t.Errorf("Did not find expected cluster %v among created objects %v", tt.cluster, objs) + } + }) + } +} + +func newMgmtCluster(name string, labels map[string]string, spec apimgmtv3.ClusterSpec) *apimgmtv3.Cluster { + spec.DisplayName = name + mgmtCluster := &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: labels, + }, + Spec: spec, + } + apimgmtv3.ClusterConditionReady.SetStatus(mgmtCluster, "True") + return mgmtCluster + +} + +// implements v3.ClusterCache +func newClusterCache(t *testing.T, ctrl *gomock.Controller, clusters map[string]*apimgmtv3.Cluster) v3.ClusterCache { + t.Helper() + clusterCache := fake.NewMockNonNamespacedCacheInterface[*apimgmtv3.Cluster](ctrl) + clusterCache.EXPECT().Get(gomock.Any()).DoAndReturn(func(name string) (*apimgmtv3.Cluster, error) { + if c, ok := clusters[name]; ok { + return c, nil + } + return nil, errNotFound + }).AnyTimes() + return clusterCache +} + +// newSecretsCache returns a mock secrets cache. +func newSecretsCache(t *testing.T, ctrl *gomock.Controller, namespace string, secrets map[string]*corev1.Secret) *fake.MockCacheInterface[*corev1.Secret] { + t.Helper() + secretCache := fake.NewMockCacheInterface[*corev1.Secret](ctrl) + secretCache.EXPECT().Get(namespace, "local-kubeconfig"). + Return( + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "local-kubeconfig", + }, + Data: map[string][]byte{}, + }, nil). + AnyTimes() + return secretCache +} + +// newSecretsController returns a mock secrets controller. +func newSecretsController( + t *testing.T, + namespace string, + updatedSecret *corev1.Secret, +) corecontrollers.SecretController { + t.Helper() + ctrl := gomock.NewController(t) + + return fake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/mock_cluster_host_getter_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/mock_cluster_host_getter_test.go new file mode 100644 index 0000000..6777ea2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetcluster/mock_cluster_host_getter_test.go @@ -0,0 +1,51 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/rancher/rancher/pkg/controllers/provisioningv2/fleetcluster (interfaces: ClusterHostGetter) + +// Package fleetcluster is a generated GoMock package. +package fleetcluster + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + clientcmd "k8s.io/client-go/tools/clientcmd" +) + +// MockClusterHostGetter is a mock of ClusterHostGetter interface. +type MockClusterHostGetter struct { + ctrl *gomock.Controller + recorder *MockClusterHostGetterMockRecorder +} + +// MockClusterHostGetterMockRecorder is the mock recorder for MockClusterHostGetter. +type MockClusterHostGetterMockRecorder struct { + mock *MockClusterHostGetter +} + +// NewMockClusterHostGetter creates a new mock instance. +func NewMockClusterHostGetter(ctrl *gomock.Controller) *MockClusterHostGetter { + mock := &MockClusterHostGetter{ctrl: ctrl} + mock.recorder = &MockClusterHostGetterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockClusterHostGetter) EXPECT() *MockClusterHostGetterMockRecorder { + return m.recorder +} + +// GetClusterHost mocks base method. +func (m *MockClusterHostGetter) GetClusterHost(arg0 clientcmd.ClientConfig) (string, []byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetClusterHost", arg0) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].([]byte) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetClusterHost indicates an expected call of GetClusterHost. +func (mr *MockClusterHostGetterMockRecorder) GetClusterHost(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClusterHost", reflect.TypeOf((*MockClusterHostGetter)(nil).GetClusterHost), arg0) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetworkspace/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetworkspace/controller.go new file mode 100644 index 0000000..bc29f32 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/fleetworkspace/controller.go @@ -0,0 +1,146 @@ +package fleetworkspace + +import ( + "context" + + fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/yaml" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + managed = "provisioning.cattle.io/managed" +) + +type handle struct { + workspaceCache mgmtcontrollers.FleetWorkspaceCache + namespaceCache v1.NamespaceCache + workspaces mgmtcontrollers.FleetWorkspaceClient +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handle{ + workspaceCache: clients.Mgmt.FleetWorkspace().Cache(), + workspaces: clients.Mgmt.FleetWorkspace(), + namespaceCache: clients.Core.Namespace().Cache(), + } + + if features.MCM.Enabled() { + clients.Mgmt.Setting().OnChange(ctx, "default-workspace", h.OnSetting) + } + + mgmtcontrollers.RegisterFleetWorkspaceGeneratingHandler(ctx, + clients.Mgmt.FleetWorkspace(), + clients.Apply. + WithCacheTypes(clients.Core.Namespace()), + "", + "workspace", + h.OnChange, + &generic.GeneratingHandlerOptions{ + AllowClusterScoped: true, + }) + + clients.Fleet.Cluster().OnChange(ctx, "workspace-backport-cluster", + func(s string, obj *fleet.Cluster) (*fleet.Cluster, error) { + if obj == nil { + return nil, nil + } + return obj, h.onFleetObject(obj) + }) + clients.Fleet.Bundle().OnChange(ctx, "workspace-backport-bundle", + func(s string, obj *fleet.Bundle) (*fleet.Bundle, error) { + if obj == nil { + return nil, nil + } + return obj, h.onFleetObject(obj) + }) +} + +func (h *handle) OnSetting(key string, setting *mgmt.Setting) (*mgmt.Setting, error) { + if setting == nil || setting.Name != "fleet-default-workspace-name" { + return setting, nil + } + + value := setting.Value + if value == "" { + value = setting.Default + } + + if value == "" { + return setting, nil + } + + _, err := h.workspaceCache.Get(value) + if apierror.IsNotFound(err) { + _, err = h.workspaces.Create(&mgmt.FleetWorkspace{ + ObjectMeta: metav1.ObjectMeta{ + Name: value, + }, + }) + } + + return setting, err +} + +func (h *handle) OnChange(workspace *mgmt.FleetWorkspace, status mgmt.FleetWorkspaceStatus) ([]runtime.Object, mgmt.FleetWorkspaceStatus, error) { + if workspace.Annotations[managed] == "false" { + return nil, status, nil + } + + return []runtime.Object{ + &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: workspace.Name, + Labels: yaml.CleanAnnotationsForExport(workspace.Labels), + }, + }, + }, status, nil +} + +func (h *handle) onFleetObject(obj runtime.Object) error { + m, err := meta.Accessor(obj) + if err != nil { + return err + } + + _, err = h.workspaceCache.Get(m.GetNamespace()) + if apierror.IsNotFound(err) { + ns, err := h.namespaceCache.Get(m.GetNamespace()) + if err != nil { + return err + } + + _, err = h.workspaces.Create(&mgmt.FleetWorkspace{ + ObjectMeta: metav1.ObjectMeta{ + Name: m.GetNamespace(), + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Namespace", + Name: ns.Name, + UID: ns.UID, + }, + }, + Annotations: map[string]string{ + managed: "false", + }, + }, + Status: mgmt.FleetWorkspaceStatus{}, + }) + if apierror.IsAlreadyExists(err) { + return nil + } + } + + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/managedchart/managedchart.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/managedchart/managedchart.go new file mode 100644 index 0000000..4adc2f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/managedchart/managedchart.go @@ -0,0 +1,176 @@ +package managedchart + +import ( + tar2 "archive/tar" + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "io" + "sort" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/catalogv2/content" + fleetcontrollers "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +const ( + chartByRepo = "chartByRepo" +) + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + charts: content.NewManager( + clients.K8s.Discovery(), + clients.Core.ConfigMap().Cache(), + clients.Core.Secret().Cache(), + clients.Catalog.ClusterRepo().Cache()), + mccCache: clients.Mgmt.ManagedChart().Cache(), + mccController: clients.Mgmt.ManagedChart(), + bundleCache: clients.Fleet.Bundle().Cache(), + } + + clients.Catalog.ClusterRepo().OnChange(ctx, "mcc-repo", h.OnRepoChange) + relatedresource.Watch(ctx, + "mcc-from-bundle-trigger", + relatedresource.OwnerResolver(true, v3.SchemeGroupVersion.String(), "ManagedChart"), + clients.Mgmt.ManagedChart(), + clients.Fleet.Bundle()) + mgmtcontrollers.RegisterManagedChartGeneratingHandler(ctx, + clients.Mgmt.ManagedChart(), + clients.Apply. + WithSetOwnerReference(true, true). + WithCacheTypes( + clients.Mgmt.ManagedChart(), + clients.Fleet.Bundle()), + "Defined", + "mcc-bundle", + h.OnChange, + nil) + clients.Mgmt.ManagedChart().Cache().AddIndexer(chartByRepo, func(obj *v3.ManagedChart) ([]string, error) { + return []string{obj.Spec.RepoName}, nil + }) +} + +type handler struct { + charts *content.Manager + mccCache mgmtcontrollers.ManagedChartCache + mccController mgmtcontrollers.ManagedChartController + bundleCache fleetcontrollers.BundleCache +} + +func (h *handler) OnRepoChange(key string, _ *v1.ClusterRepo) (*v1.ClusterRepo, error) { + mccs, err := h.mccCache.GetByIndex(chartByRepo, key) + if err != nil { + return nil, err + } + + for _, mcc := range mccs { + h.mccController.Enqueue(mcc.Namespace, mcc.Name) + } + + return nil, nil +} + +func (h *handler) OnChange(mcc *v3.ManagedChart, status v3.ManagedChartStatus) ([]runtime.Object, v3.ManagedChartStatus, error) { + chart, err := h.charts.Chart("", mcc.Spec.RepoName, mcc.Spec.Chart, mcc.Spec.Version, true) + if err != nil { + return nil, status, err + } + defer chart.Close() + + bundle := &v1alpha1.Bundle{ + ObjectMeta: metav1.ObjectMeta{ + Name: capr.SafeConcatName(capr.MaxHelmReleaseNameLength, "mcc", mcc.Name), + Namespace: mcc.Namespace, + }, + Spec: v1alpha1.BundleSpec{ + BundleDeploymentOptions: v1alpha1.BundleDeploymentOptions{ + DefaultNamespace: mcc.Spec.DefaultNamespace, + TargetNamespace: mcc.Spec.TargetNamespace, + Helm: &v1alpha1.HelmOptions{ + ReleaseName: name.Limit(mcc.Spec.ReleaseName, capr.MaxHelmReleaseNameLength), + Version: mcc.Spec.Version, + TimeoutSeconds: mcc.Spec.TimeoutSeconds, + Values: mcc.Spec.Values, + Force: mcc.Spec.Force, + TakeOwnership: mcc.Spec.TakeOwnership, + MaxHistory: mcc.Spec.MaxHistory, + }, + ServiceAccount: mcc.Spec.ServiceAccount, + Diff: mcc.Spec.Diff, + }, + Paused: mcc.Spec.Paused, + RolloutStrategy: mcc.Spec.RolloutStrategy, + Targets: mcc.Spec.Targets, + }, + } + + gz, err := gzip.NewReader(chart) + if err != nil { + return nil, status, err + } + + tar := tar2.NewReader(gz) + for { + next, err := tar.Next() + if errors.Is(err, io.EOF) { + break + } else if err != nil { + return nil, status, err + } + + if next.Typeflag != tar2.TypeReg { + continue + } + + buf := &bytes.Buffer{} + gz := gzip.NewWriter(buf) + if _, err := io.Copy(gz, tar); err != nil { + return nil, status, err + } + if err := gz.Close(); err != nil { + return nil, status, err + } + + name := strings.TrimPrefix(next.Name, mcc.Spec.Chart+"/") + bundle.Spec.Resources = append(bundle.Spec.Resources, v1alpha1.BundleResource{ + Name: name, + Content: base64.StdEncoding.EncodeToString(buf.Bytes()), + Encoding: "base64+gz", + }) + } + + sort.Slice(bundle.Spec.Resources, func(i, j int) bool { + return bundle.Spec.Resources[i].Name < bundle.Spec.Resources[j].Name + }) + + status, err = h.updateStatus(status, bundle) + return []runtime.Object{ + bundle, + }, status, err +} + +func (h *handler) updateStatus(status v3.ManagedChartStatus, bundle *v1alpha1.Bundle) (v3.ManagedChartStatus, error) { + bundle, err := h.bundleCache.Get(bundle.Namespace, bundle.Name) + if apierrors.IsNotFound(err) { + return status, nil + } else if err != nil { + return status, err + } + + status.BundleStatus = bundle.Status + return status, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller.go new file mode 100644 index 0000000..64158ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller.go @@ -0,0 +1,462 @@ +package provisioningcluster + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/rancher/lasso/pkg/dynamic" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rancherv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/features" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rocontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + rkecontroller "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/condition" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/relatedresource" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apierror "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + byNodeInfra = "by-node-infra" + restoreRKEConfigKubernetesVersion = "kubernetesVersion" + restoreRKEConfigAll = "all" + restoreRKEConfigNone = "none" +) + +type handler struct { + dynamic *dynamic.Controller + dynamicSchema mgmtcontroller.DynamicSchemaCache + clusterCache rocontrollers.ClusterCache + clusterController rocontrollers.ClusterController + secretCache corecontrollers.SecretCache + secretClient corecontrollers.SecretClient + capiClusters capicontrollers.ClusterCache + mgmtClusterCache mgmtcontroller.ClusterCache + mgmtClusterClient mgmtcontroller.ClusterClient + rkeControlPlane rkecontroller.RKEControlPlaneCache + etcdSnapshotCache rkecontroller.ETCDSnapshotCache + capiMachineCache capicontrollers.MachineCache +} + +func Register(ctx context.Context, clients *wrangler.Context) { + h := handler{ + dynamic: clients.Dynamic, + secretCache: clients.Core.Secret().Cache(), + secretClient: clients.Core.Secret(), + clusterCache: clients.Provisioning.Cluster().Cache(), + clusterController: clients.Provisioning.Cluster(), + capiClusters: clients.CAPI.Cluster().Cache(), + rkeControlPlane: clients.RKE.RKEControlPlane().Cache(), + etcdSnapshotCache: clients.RKE.ETCDSnapshot().Cache(), + capiMachineCache: clients.CAPI.Machine().Cache(), + } + + if features.MCM.Enabled() { + h.dynamicSchema = clients.Mgmt.DynamicSchema().Cache() + h.mgmtClusterCache = clients.Mgmt.Cluster().Cache() + h.mgmtClusterClient = clients.Mgmt.Cluster() + } + + clients.Dynamic.OnChange(ctx, "rke-dynamic", matchRKENodeGroup, h.infraWatch) + clients.Provisioning.Cluster().Cache().AddIndexer(byNodeInfra, byNodeInfraIndex) + + rocontrollers.RegisterClusterGeneratingHandler(ctx, + clients.Provisioning.Cluster(), + clients.Apply. + // Because capi wants to own objects we don't set ownerreference with apply + WithDynamicLookup(). + WithCacheTypes( + clients.CAPI.Cluster(), + clients.CAPI.MachineDeployment(), + clients.CAPI.MachineHealthCheck(), + clients.RKE.RKEControlPlane(), + clients.RKE.RKECluster(), + clients.RKE.RKEBootstrapTemplate(), + ), + "RKECluster", + "rke-cluster", + h.OnRancherClusterChange, + nil) + + relatedresource.Watch(ctx, "provisioning-cluster-trigger", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { + if cp, ok := obj.(*rkev1.RKEControlPlane); ok { + return []relatedresource.Key{{ + Namespace: namespace, + Name: cp.Spec.ClusterName, + }}, nil + } + return nil, nil + }, clients.Provisioning.Cluster(), clients.RKE.RKEControlPlane()) + + clients.Provisioning.Cluster().OnChange(ctx, "provisioning-cluster-change", h.OnChange) + clients.Provisioning.Cluster().OnRemove(ctx, "rke-cluster-remove", h.OnRemove) +} + +func byNodeInfraIndex(obj *rancherv1.Cluster) ([]string, error) { + if obj.Status.ClusterName == "" || obj.Spec.RKEConfig == nil { + return nil, nil + } + + var result []string + for _, np := range obj.Spec.RKEConfig.MachinePools { + if np.NodeConfig == nil { + continue + } + result = append(result, toInfraRefKey(*np.NodeConfig, obj.Namespace)) + } + + return result, nil +} + +func toInfraRefKey(ref corev1.ObjectReference, namespace string) string { + if ref.APIVersion == "" { + ref.APIVersion = capr.DefaultMachineConfigAPIVersion + } + return fmt.Sprintf("%s/%s/%s/%s", ref.APIVersion, ref.Kind, namespace, ref.Name) +} + +func matchRKENodeGroup(gvk schema.GroupVersionKind) bool { + return gvk.GroupVersion().String() == capr.DefaultMachineConfigAPIVersion && + strings.HasSuffix(gvk.Kind, "Config") +} + +func (h *handler) infraWatch(obj runtime.Object) (runtime.Object, error) { + if obj == nil { + return nil, nil + } + + typeInfo, err := meta.TypeAccessor(obj) + if err != nil { + return nil, err + } + + meta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + + indexKey := toInfraRefKey(corev1.ObjectReference{ + Kind: typeInfo.GetKind(), + Namespace: meta.GetNamespace(), + Name: meta.GetName(), + APIVersion: typeInfo.GetAPIVersion(), + }, meta.GetNamespace()) + clusters, err := h.clusterCache.GetByIndex(byNodeInfra, indexKey) + if err != nil { + return nil, err + } + + for _, cluster := range clusters { + h.clusterController.Enqueue(cluster.Namespace, cluster.Name) + } + + return obj, nil +} + +func (h *handler) OnChange(_ string, cluster *rancherv1.Cluster) (*rancherv1.Cluster, error) { + if cluster == nil || !cluster.DeletionTimestamp.IsZero() || cluster.Spec.RKEConfig == nil { + return cluster, nil + } + + // the outer loop searches for machine pools without a populated DynamicSchemaSpec field + for i, machinePool := range cluster.Spec.RKEConfig.MachinePools { + var spec apimgmtv3.DynamicSchemaSpec + if machinePool.DynamicSchemaSpec != "" && json.Unmarshal([]byte(machinePool.DynamicSchemaSpec), &spec) == nil { + continue + } + if machinePool.NodeConfig == nil { + continue + } + apiVersion := machinePool.NodeConfig.APIVersion + if apiVersion != capr.DefaultMachineConfigAPIVersion && apiVersion != "" { + continue + } + // if the field is empty or invalid, add to any machine pools that do not have it and update the cluster + clusterCopy := cluster.DeepCopy() + for j := i; j < len(cluster.Spec.RKEConfig.MachinePools); j++ { + machinePool := cluster.Spec.RKEConfig.MachinePools[j] + spec = apimgmtv3.DynamicSchemaSpec{} + if machinePool.DynamicSchemaSpec != "" && json.Unmarshal([]byte(machinePool.DynamicSchemaSpec), &spec) == nil { + continue + } + nodeConfig := machinePool.NodeConfig + if nodeConfig == nil { + return cluster, fmt.Errorf("machine pool node config must not be nil") + } + apiVersion := nodeConfig.APIVersion + if apiVersion != capr.DefaultMachineConfigAPIVersion && apiVersion != "" { + continue + } + ds, err := h.dynamicSchema.Get(strings.ToLower(nodeConfig.Kind)) + if err != nil { + return cluster, err + } + specJSON, err := json.Marshal(ds.Spec) + if err != nil { + return cluster, err + } + clusterCopy.Spec.RKEConfig.MachinePools[j].DynamicSchemaSpec = string(specJSON) + } + return h.clusterController.Update(clusterCopy) + } + return cluster, nil +} + +func (h *handler) findSnapshotClusterSpec(snapshotNamespace, snapshotName string) (*rancherv1.ClusterSpec, error) { + snapshot, err := h.etcdSnapshotCache.Get(snapshotNamespace, snapshotName) + if err != nil { + return nil, fmt.Errorf("error retrieving etcdsnapshot %s/%s: %w", snapshotNamespace, snapshotName, err) + } + return capr.ParseSnapshotClusterSpecOrError(snapshot) +} + +// reconcileClusterSpecEtcdRestore reconciles the cluster against the desiredSpec, but only sets fields that should be set +// during an etcd restore. It expects the cluster object to be writable without conflict (i.e. DeepCopy). It returns a bool which indicates +// whether the cluster was changed +func reconcileClusterSpecEtcdRestore(cluster *rancherv1.Cluster, desiredSpec rancherv1.ClusterSpec) bool { + // don't overwrite/change the cluster spec for certain entries + changed := false + if !equality.Semantic.DeepEqual(cluster.Spec.RKEConfig.MachineGlobalConfig, desiredSpec.RKEConfig.MachineGlobalConfig) { + changed = true + cluster.Spec.RKEConfig.MachineGlobalConfig = desiredSpec.RKEConfig.MachineGlobalConfig + } + if !equality.Semantic.DeepEqual(cluster.Spec.RKEConfig.MachineSelectorConfig, desiredSpec.RKEConfig.MachineSelectorConfig) { + changed = true + cluster.Spec.RKEConfig.MachineSelectorConfig = desiredSpec.RKEConfig.MachineSelectorConfig + } + if !equality.Semantic.DeepEqual(cluster.Spec.RKEConfig.ChartValues, desiredSpec.RKEConfig.ChartValues) { + changed = true + cluster.Spec.RKEConfig.ChartValues = desiredSpec.RKEConfig.ChartValues + } + if !equality.Semantic.DeepEqual(cluster.Spec.RKEConfig.Registries, desiredSpec.RKEConfig.Registries) { + changed = true + cluster.Spec.RKEConfig.Registries = desiredSpec.RKEConfig.Registries + } + if !equality.Semantic.DeepEqual(cluster.Spec.RKEConfig.UpgradeStrategy, desiredSpec.RKEConfig.UpgradeStrategy) { + changed = true + cluster.Spec.RKEConfig.UpgradeStrategy = desiredSpec.RKEConfig.UpgradeStrategy + } + if cluster.Spec.RKEConfig.AdditionalManifest != desiredSpec.RKEConfig.AdditionalManifest { + changed = true + cluster.Spec.RKEConfig.AdditionalManifest = desiredSpec.RKEConfig.AdditionalManifest + } + if cluster.Spec.RKEConfig.Networking != desiredSpec.RKEConfig.Networking { + changed = true + cluster.Spec.RKEConfig.Networking = desiredSpec.RKEConfig.Networking + } + if cluster.Spec.KubernetesVersion != desiredSpec.KubernetesVersion { + changed = true + cluster.Spec.KubernetesVersion = desiredSpec.KubernetesVersion + } + if cluster.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName != desiredSpec.DefaultPodSecurityAdmissionConfigurationTemplateName { + changed = true + cluster.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName = desiredSpec.DefaultPodSecurityAdmissionConfigurationTemplateName + } + if !equality.Semantic.DeepEqual(cluster.Spec.ClusterAgentDeploymentCustomization, desiredSpec.ClusterAgentDeploymentCustomization) { + changed = true + cluster.Spec.ClusterAgentDeploymentCustomization = desiredSpec.ClusterAgentDeploymentCustomization + } + if !equality.Semantic.DeepEqual(cluster.Spec.FleetAgentDeploymentCustomization, desiredSpec.FleetAgentDeploymentCustomization) { + changed = true + cluster.Spec.FleetAgentDeploymentCustomization = desiredSpec.FleetAgentDeploymentCustomization + } + return changed +} + +// OnRancherClusterChange is called when the `clusters.provisioning.cattle.io` object is changed and is responsible for generating runtime images for the purpose of performing reconciliation +func (h *handler) OnRancherClusterChange(obj *rancherv1.Cluster, status rancherv1.ClusterStatus) ([]runtime.Object, rancherv1.ClusterStatus, error) { + if obj.Spec.RKEConfig == nil || obj.Status.ClusterName == "" || obj.DeletionTimestamp != nil { + return nil, status, nil + } + + if obj.Spec.KubernetesVersion == "" { + return nil, status, fmt.Errorf("kubernetesVersion not set on %s/%s", obj.Namespace, obj.Name) + } + + if len(obj.Finalizers) == 0 && obj.DeletionTimestamp.IsZero() { + // If the cluster doesn't have any finalizers, then we don't apply any objects to ensure the finalizer can be put on the cluster. + return nil, status, generic.ErrSkip + } + + rkeCP, err := h.getRKEControlPlaneForCluster(obj) + if err != nil { + return nil, status, err + } + + mgmtCluster, err := h.retrieveMgmtClusterFromCache(obj) + if err != nil { + // don't return because the management cluster condition updating should not be blocking + logrus.Errorf("rkecluster %s/%s: error while retrieving management cluster from cache: %v", obj.Namespace, obj.Name, err) + } + + // If the rkecontrolplane is not nil, we can check it to determine action items. + if rkeCP != nil { + // If EtcdSnapshotRestore is not nil, we need to check to see if we need to update the cluster object it. + if obj.Spec.RKEConfig.ETCDSnapshotRestore != nil && + obj.Spec.RKEConfig.ETCDSnapshotRestore.Name != "" && + obj.Spec.RKEConfig.ETCDSnapshotRestore.RestoreRKEConfig != "" && + obj.Spec.RKEConfig.ETCDSnapshotRestore.RestoreRKEConfig != restoreRKEConfigNone { + logrus.Debugf("rkecluster %s/%s: Reconciling rkeconfig against specified etcd restore snapshot metadata", obj.Namespace, obj.Name) + if !equality.Semantic.DeepEqual(rkeCP.Status.ETCDSnapshotRestore, obj.Spec.RKEConfig.ETCDSnapshotRestore) { + clusterSpec, err := h.findSnapshotClusterSpec(obj.Namespace, obj.Spec.RKEConfig.ETCDSnapshotRestore.Name) + if err != nil { + return nil, status, err + } + switch obj.Spec.RKEConfig.ETCDSnapshotRestore.RestoreRKEConfig { + case restoreRKEConfigKubernetesVersion: + if obj.Spec.KubernetesVersion != clusterSpec.KubernetesVersion { + logrus.Infof("rkecluster %s/%s: restoring Kubernetes version from %s to %s for etcd snapshot restore (snapshot: %s)", obj.Namespace, obj.Name, obj.Spec.KubernetesVersion, clusterSpec.KubernetesVersion, obj.Spec.RKEConfig.ETCDSnapshotRestore.Name) + obj = obj.DeepCopy() + obj.Spec.KubernetesVersion = clusterSpec.KubernetesVersion + _, err = h.clusterController.Update(obj) + if err == nil { + err = generic.ErrSkip // if update was successful, return ErrSkip waiting for caches to sync + } + return nil, status, err + } + case restoreRKEConfigAll: + newCluster := obj.DeepCopy() + if reconcileClusterSpecEtcdRestore(newCluster, *clusterSpec) { + logrus.Infof("rkecluster %s/%s: restoring RKE config for etcd snapshot restore (snapshot: %s)", obj.Namespace, obj.Name, obj.Spec.RKEConfig.ETCDSnapshotRestore.Name) + _, err = h.clusterController.Update(newCluster) + if err == nil { + err = generic.ErrSkip // if update was successful, return ErrSkip waiting for caches to sync + } + return nil, status, err + } + } + } + } + + reconcileCondition(&status, capr.Updated, rkeCP, capr.Ready) + reconcileCondition(&status, capr.Provisioned, rkeCP, capr.Ready) + + // If the Stable condition is not true, then copy the Ready condition from the rkeControlPlane to the v1.Clusters object + // Otherwise, use the v3 clusters Ready condition. Note that we use `IsTrue` here because `IsFalse` specifically looks + // for `False`, and the condition may not be defined which would not match `IsFalse`. + useRKEControlPlaneReadyStatus := !capr.Stable.IsTrue(rkeCP) + if useRKEControlPlaneReadyStatus { + reconcileCondition(&status, capr.Ready, rkeCP, capr.Ready) + } + if mgmtCluster != nil { + if !useRKEControlPlaneReadyStatus { + reconcileCondition(&status, capr.Ready, mgmtCluster, capr.Ready) + } + reconcileCondition(mgmtCluster, capr.Updated, rkeCP, capr.Ready) + reconcileCondition(mgmtCluster, capr.Provisioned, rkeCP, capr.Provisioned) // This was originally set by checking machine provisioning, but now we simply set it to true. + _, err := h.mgmtClusterClient.Update(mgmtCluster) + if err != nil { + return nil, status, err + } + } + } + + objs, err := objects(obj, h.dynamic, h.dynamicSchema, h.secretCache) + return objs, status, err +} + +// getRKEControlPlaneForCluster retrieves the rkecontrolplane that corresponds to a provisioning cluster object. +// If it cannot retrieve the corresponding CAPI cluster (is not found), if the capi cluster controlplane ref is not +// an rkecontrolplane, or the rkecontrolplane object can't be found and the cluster is deleting, it returns nil, nil. +func (h *handler) getRKEControlPlaneForCluster(cluster *rancherv1.Cluster) (*rkev1.RKEControlPlane, error) { + capiCluster, err := h.capiClusters.Get(cluster.Namespace, cluster.Name) + if apierror.IsNotFound(err) { + return nil, nil + } else if err != nil { + return nil, err + } + + if capiCluster.Spec.ControlPlaneRef == nil || + capiCluster.Spec.ControlPlaneRef.Kind != "RKEControlPlane" { + return nil, nil + } + + cp, err := h.rkeControlPlane.Get(capiCluster.Spec.ControlPlaneRef.Namespace, capiCluster.Spec.ControlPlaneRef.Name) + if apierror.IsNotFound(err) && cluster.DeletionTimestamp != nil { + return nil, nil + } else if err != nil { + return nil, err + } + return cp, nil +} + +// retrieveMgmtClusterFromCache retrieves an editable copy of the v3.Clusters object from the mgmtCache +func (h *handler) retrieveMgmtClusterFromCache(cluster *rancherv1.Cluster) (*apimgmtv3.Cluster, error) { + if cluster == nil { + return nil, fmt.Errorf("cluster was nil") + } + if h.mgmtClusterCache == nil { + return nil, fmt.Errorf("management cluster cache was nil") + } + mgmtCluster, err := h.mgmtClusterCache.Get(cluster.Status.ClusterName) + if err != nil { + return nil, err + } + return mgmtCluster.DeepCopy(), nil +} + +// reconcileCondition accepts an object, a condition to reconcile on the object, and the status/reason/message to reconcile. +// It returns a boolean indicating whether the condition was changed. +func reconcileCondition(to interface{}, toCondition condition.Cond, from interface{}, fromCondition condition.Cond) bool { + if fromCondition.GetStatus(from) != toCondition.GetStatus(to) || fromCondition.GetReason(from) != toCondition.GetReason(to) || fromCondition.GetMessage(from) != toCondition.GetMessage(to) { + toCondition.SetStatus(to, fromCondition.GetStatus(from)) + toCondition.Reason(to, fromCondition.GetReason(from)) + toCondition.Message(to, fromCondition.GetMessage(from)) + return true + } + return false +} + +func (h *handler) OnRemove(_ string, cluster *rancherv1.Cluster) (*rancherv1.Cluster, error) { + if cluster == nil || cluster.Spec.RKEConfig == nil || cluster.Status.ClusterName == "" { + return nil, nil + } + + rkeCP, err := h.getRKEControlPlaneForCluster(cluster) + if err != nil || rkeCP == nil { + return cluster, err + } + + // Check to see if the management cluster still exists. If it exists, copy the Removed condition from the + // controlplane to the object. If it does not exist, allow the v1 Cluster object to be removed. + mgmtCluster, err := h.retrieveMgmtClusterFromCache(cluster) + if err != nil { + if apierror.IsNotFound(err) { + // go ahead and proceed with removal + return cluster, nil + } + logrus.Errorf("rkecluster %s/%s: error retrieving management cluster during removal of cluster: %v", cluster.Namespace, cluster.Name, err) + } + if mgmtCluster != nil && reconcileCondition(mgmtCluster, capr.Removed, rkeCP, capr.Removed) { + _, err = h.mgmtClusterClient.Update(mgmtCluster) + if apierror.IsNotFound(err) { + return cluster, nil + } else if err != nil { + return cluster, err + } + } + + status := cluster.Status.DeepCopy() + if reconcileCondition(status, capr.Removed, rkeCP, capr.Removed) { + cluster.Status = *status + cluster, err = h.clusterController.UpdateStatus(cluster) + if err != nil { + return cluster, err + } + } + return cluster, generic.ErrSkip +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller_test.go new file mode 100644 index 0000000..c2fe036 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/controller_test.go @@ -0,0 +1,457 @@ +package provisioningcluster + +import ( + "errors" + "testing" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/genericcondition" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func TestProvisioningClusterController_reconcileConditions(t *testing.T) { + type dummyObject struct { + Status struct { + Conditions []genericcondition.GenericCondition + } + } + type args struct { + conditionA condition.Cond + conditionB condition.Cond + objectAConditionAMessage string + objectAConditionAReason string + objectAConditionAStatus string + objectBConditionAMessage string + objectBConditionAReason string + objectBConditionAStatus string + objectAConditionBMessage string + objectAConditionBReason string + objectAConditionBStatus string + objectBConditionBMessage string + objectBConditionBReason string + objectBConditionBStatus string + expectedObjectAConditionAMessage string + expectedObjectAConditionAReason string + expectedObjectAConditionAStatus string + expectedObjectBConditionAMessage string + expectedObjectBConditionAReason string + expectedObjectBConditionAStatus string + expectedObjectAConditionBMessage string + expectedObjectAConditionBReason string + expectedObjectAConditionBStatus string + expectedObjectBConditionBMessage string + expectedObjectBConditionBReason string + expectedObjectBConditionBStatus string + expectChange bool + } + + tests := []struct { + name string + args args + }{ + { + name: "basic copy", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "myMessage", + objectAConditionAReason: "myReason", + objectAConditionAStatus: "myStatus", + objectBConditionAMessage: "", + objectBConditionAReason: "", + objectBConditionAStatus: "", + objectAConditionBMessage: "", + objectAConditionBReason: "", + objectAConditionBStatus: "", + objectBConditionBMessage: "", + objectBConditionBReason: "", + objectBConditionBStatus: "", + expectedObjectAConditionAMessage: "myMessage", + expectedObjectAConditionAReason: "myReason", + expectedObjectAConditionAStatus: "myStatus", + expectedObjectBConditionAMessage: "", + expectedObjectBConditionAReason: "", + expectedObjectBConditionAStatus: "", + expectedObjectAConditionBMessage: "", + expectedObjectAConditionBReason: "", + expectedObjectAConditionBStatus: "", + expectedObjectBConditionBMessage: "myMessage", + expectedObjectBConditionBReason: "myReason", + expectedObjectBConditionBStatus: "myStatus", + expectChange: true, + }, + }, + { + name: "basic erase", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "", + objectAConditionAReason: "", + objectAConditionAStatus: "", + objectBConditionAMessage: "", + objectBConditionAReason: "", + objectBConditionAStatus: "", + objectAConditionBMessage: "", + objectAConditionBReason: "", + objectAConditionBStatus: "", + objectBConditionBMessage: "myMessage", + objectBConditionBReason: "myReason", + objectBConditionBStatus: "myStatus", + expectedObjectAConditionAMessage: "", + expectedObjectAConditionAReason: "", + expectedObjectAConditionAStatus: "", + expectedObjectBConditionAMessage: "", + expectedObjectBConditionAReason: "", + expectedObjectBConditionAStatus: "", + expectedObjectAConditionBMessage: "", + expectedObjectAConditionBReason: "", + expectedObjectAConditionBStatus: "", + expectedObjectBConditionBMessage: "", + expectedObjectBConditionBReason: "", + expectedObjectBConditionBStatus: "", + expectChange: true, + }, + }, + { + name: "basic overwrite", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "wow", + objectAConditionAReason: "wowreason", + objectAConditionAStatus: "wowstatus", + objectBConditionAMessage: "", + objectBConditionAReason: "", + objectBConditionAStatus: "", + objectAConditionBMessage: "", + objectAConditionBReason: "", + objectAConditionBStatus: "", + objectBConditionBMessage: "myMessage", + objectBConditionBReason: "myReason", + objectBConditionBStatus: "myStatus", + expectedObjectAConditionAMessage: "wow", + expectedObjectAConditionAReason: "wowreason", + expectedObjectAConditionAStatus: "wowstatus", + expectedObjectBConditionAMessage: "", + expectedObjectBConditionAReason: "", + expectedObjectBConditionAStatus: "", + expectedObjectAConditionBMessage: "", + expectedObjectAConditionBReason: "", + expectedObjectAConditionBStatus: "", + expectedObjectBConditionBMessage: "wow", + expectedObjectBConditionBReason: "wowreason", + expectedObjectBConditionBStatus: "wowstatus", + expectChange: true, + }, + }, + { + name: "copy around other conditions", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "myMessage", + objectAConditionAReason: "myReason", + objectAConditionAStatus: "myStatus", + objectBConditionAMessage: "donttouch", + objectBConditionAReason: "thiscondition", + objectBConditionAStatus: "becauseifyoudoitsbroken", + objectAConditionBMessage: "orthisone", + objectAConditionBReason: "andthisone", + objectAConditionBStatus: "alsothisone", + objectBConditionBMessage: "", + objectBConditionBReason: "", + objectBConditionBStatus: "", + expectedObjectAConditionAMessage: "myMessage", + expectedObjectAConditionAReason: "myReason", + expectedObjectAConditionAStatus: "myStatus", + expectedObjectBConditionAMessage: "donttouch", + expectedObjectBConditionAReason: "thiscondition", + expectedObjectBConditionAStatus: "becauseifyoudoitsbroken", + expectedObjectAConditionBMessage: "orthisone", + expectedObjectAConditionBReason: "andthisone", + expectedObjectAConditionBStatus: "alsothisone", + expectedObjectBConditionBMessage: "myMessage", + expectedObjectBConditionBReason: "myReason", + expectedObjectBConditionBStatus: "myStatus", + expectChange: true, + }, + }, + { + name: "erase around other conditions", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "", + objectAConditionAReason: "", + objectAConditionAStatus: "", + objectBConditionAMessage: "donttouch", + objectBConditionAReason: "thiscondition", + objectBConditionAStatus: "becauseifyoudoitsbroken", + objectAConditionBMessage: "orthisone", + objectAConditionBReason: "andthisone", + objectAConditionBStatus: "alsothisone", + objectBConditionBMessage: "myMessage", + objectBConditionBReason: "myReason", + objectBConditionBStatus: "myStatus", + expectedObjectAConditionAMessage: "", + expectedObjectAConditionAReason: "", + expectedObjectAConditionAStatus: "", + expectedObjectBConditionAMessage: "donttouch", + expectedObjectBConditionAReason: "thiscondition", + expectedObjectBConditionAStatus: "becauseifyoudoitsbroken", + expectedObjectAConditionBMessage: "orthisone", + expectedObjectAConditionBReason: "andthisone", + expectedObjectAConditionBStatus: "alsothisone", + expectedObjectBConditionBMessage: "", + expectedObjectBConditionBReason: "", + expectedObjectBConditionBStatus: "", + expectChange: true, + }, + }, + { + name: "overwrite around other conditions", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "wow", + objectAConditionAReason: "wowreason", + objectAConditionAStatus: "wowstatus", + objectBConditionAMessage: "donttouch", + objectBConditionAReason: "thiscondition", + objectBConditionAStatus: "becauseifyoudoitsbroken", + objectAConditionBMessage: "orthisone", + objectAConditionBReason: "andthisone", + objectAConditionBStatus: "alsothisone", + objectBConditionBMessage: "myMessage", + objectBConditionBReason: "myReason", + objectBConditionBStatus: "myStatus", + expectedObjectAConditionAMessage: "wow", + expectedObjectAConditionAReason: "wowreason", + expectedObjectAConditionAStatus: "wowstatus", + expectedObjectBConditionAMessage: "donttouch", + expectedObjectBConditionAReason: "thiscondition", + expectedObjectBConditionAStatus: "becauseifyoudoitsbroken", + expectedObjectAConditionBMessage: "orthisone", + expectedObjectAConditionBReason: "andthisone", + expectedObjectAConditionBStatus: "alsothisone", + expectedObjectBConditionBMessage: "wow", + expectedObjectBConditionBReason: "wowreason", + expectedObjectBConditionBStatus: "wowstatus", + expectChange: true, + }, + }, + { + name: "no changes", + args: args{ + conditionA: condition.Cond("conditionA"), + conditionB: condition.Cond("conditionB"), + objectAConditionAMessage: "wow", + objectAConditionAReason: "wowreason", + objectAConditionAStatus: "wowstatus", + objectBConditionAMessage: "donttouch", + objectBConditionAReason: "thiscondition", + objectBConditionAStatus: "becauseifyoudoitsbroken", + objectAConditionBMessage: "orthisone", + objectAConditionBReason: "andthisone", + objectAConditionBStatus: "alsothisone", + objectBConditionBMessage: "wow", + objectBConditionBReason: "wowreason", + objectBConditionBStatus: "wowstatus", + expectedObjectAConditionAMessage: "wow", + expectedObjectAConditionAReason: "wowreason", + expectedObjectAConditionAStatus: "wowstatus", + expectedObjectBConditionAMessage: "donttouch", + expectedObjectBConditionAReason: "thiscondition", + expectedObjectBConditionAStatus: "becauseifyoudoitsbroken", + expectedObjectAConditionBMessage: "orthisone", + expectedObjectAConditionBReason: "andthisone", + expectedObjectAConditionBStatus: "alsothisone", + expectedObjectBConditionBMessage: "wow", + expectedObjectBConditionBReason: "wowreason", + expectedObjectBConditionBStatus: "wowstatus", + expectChange: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // This tests copying object A condition A to object B condition B. + a := assert.New(t) + var objectA = dummyObject{} + var objectB = dummyObject{} + + if tt.args.objectAConditionAMessage != "" { + tt.args.conditionA.Message(&objectA, tt.args.objectAConditionAMessage) + } + if tt.args.objectAConditionAReason != "" { + tt.args.conditionA.Reason(&objectA, tt.args.objectAConditionAReason) + } + if tt.args.objectAConditionAStatus != "" { + tt.args.conditionA.SetStatus(&objectA, tt.args.objectAConditionAStatus) + } + if tt.args.objectAConditionBMessage != "" { + tt.args.conditionB.Message(&objectA, tt.args.objectAConditionBMessage) + } + if tt.args.objectAConditionBReason != "" { + tt.args.conditionB.Reason(&objectA, tt.args.objectAConditionBReason) + } + if tt.args.objectAConditionBStatus != "" { + tt.args.conditionB.SetStatus(&objectA, tt.args.objectAConditionBStatus) + } + if tt.args.objectBConditionAMessage != "" { + tt.args.conditionA.Message(&objectB, tt.args.objectBConditionAMessage) + } + if tt.args.objectBConditionAReason != "" { + tt.args.conditionA.Reason(&objectB, tt.args.objectBConditionAReason) + } + if tt.args.objectBConditionAStatus != "" { + tt.args.conditionA.SetStatus(&objectB, tt.args.objectBConditionAStatus) + } + if tt.args.objectBConditionBMessage != "" { + tt.args.conditionB.Message(&objectB, tt.args.objectBConditionBMessage) + } + if tt.args.objectBConditionBReason != "" { + tt.args.conditionB.Reason(&objectB, tt.args.objectBConditionBReason) + } + if tt.args.objectBConditionBStatus != "" { + tt.args.conditionB.SetStatus(&objectB, tt.args.objectBConditionBStatus) + } + + a.Equal(tt.args.objectAConditionAMessage, tt.args.conditionA.GetMessage(&objectA)) + a.Equal(tt.args.objectAConditionAReason, tt.args.conditionA.GetReason(&objectA)) + a.Equal(tt.args.objectAConditionAStatus, tt.args.conditionA.GetStatus(&objectA)) + a.Equal(tt.args.objectAConditionBMessage, tt.args.conditionB.GetMessage(&objectA)) + a.Equal(tt.args.objectAConditionBReason, tt.args.conditionB.GetReason(&objectA)) + a.Equal(tt.args.objectAConditionBStatus, tt.args.conditionB.GetStatus(&objectA)) + + a.Equal(tt.args.objectBConditionAMessage, tt.args.conditionA.GetMessage(&objectB)) + a.Equal(tt.args.objectBConditionAReason, tt.args.conditionA.GetReason(&objectB)) + a.Equal(tt.args.objectBConditionAStatus, tt.args.conditionA.GetStatus(&objectB)) + a.Equal(tt.args.objectBConditionBMessage, tt.args.conditionB.GetMessage(&objectB)) + a.Equal(tt.args.objectBConditionBReason, tt.args.conditionB.GetReason(&objectB)) + a.Equal(tt.args.objectBConditionBStatus, tt.args.conditionB.GetStatus(&objectB)) + + a.Equal(tt.args.expectChange, reconcileCondition(&objectB, tt.args.conditionB, &objectA, tt.args.conditionA)) + + a.Equal(tt.args.expectedObjectAConditionAMessage, tt.args.conditionA.GetMessage(&objectA)) + a.Equal(tt.args.expectedObjectAConditionAReason, tt.args.conditionA.GetReason(&objectA)) + a.Equal(tt.args.expectedObjectAConditionAStatus, tt.args.conditionA.GetStatus(&objectA)) + a.Equal(tt.args.expectedObjectAConditionBMessage, tt.args.conditionB.GetMessage(&objectA)) + a.Equal(tt.args.expectedObjectAConditionBReason, tt.args.conditionB.GetReason(&objectA)) + a.Equal(tt.args.expectedObjectAConditionBStatus, tt.args.conditionB.GetStatus(&objectA)) + + a.Equal(tt.args.expectedObjectBConditionAMessage, tt.args.conditionA.GetMessage(&objectB)) + a.Equal(tt.args.expectedObjectBConditionAReason, tt.args.conditionA.GetReason(&objectB)) + a.Equal(tt.args.expectedObjectBConditionAStatus, tt.args.conditionA.GetStatus(&objectB)) + a.Equal(tt.args.expectedObjectBConditionBMessage, tt.args.conditionB.GetMessage(&objectB)) + a.Equal(tt.args.expectedObjectBConditionBReason, tt.args.conditionB.GetReason(&objectB)) + a.Equal(tt.args.expectedObjectBConditionBStatus, tt.args.conditionB.GetStatus(&objectB)) + }) + } + +} + +func TestGeneratingHandler(t *testing.T) { + tests := []struct { + name string + obj *provv1.Cluster + expected []runtime.Object + expectedStatus provv1.ClusterStatus + expectedErr error + }{ + { + name: "no rkeconfig", + obj: &provv1.Cluster{}, + expected: nil, + expectedStatus: provv1.ClusterStatus{}, + expectedErr: nil, + }, + { + name: "no cluster name", + obj: &provv1.Cluster{ + Spec: provv1.ClusterSpec{ + RKEConfig: &provv1.RKEConfig{}, + }, + }, + expected: nil, + expectedStatus: provv1.ClusterStatus{}, + expectedErr: nil, + }, + { + name: "deleting", + obj: &provv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + DeletionTimestamp: &[]metav1.Time{metav1.Now()}[0], + }, + Spec: provv1.ClusterSpec{ + RKEConfig: &provv1.RKEConfig{}, + }, + Status: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + }, + expected: nil, + expectedStatus: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + expectedErr: nil, + }, + { + name: "k8s version", + obj: &provv1.Cluster{ + Spec: provv1.ClusterSpec{ + RKEConfig: &provv1.RKEConfig{}, + }, + Status: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + }, + expected: nil, + expectedStatus: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + expectedErr: errors.New("kubernetesVersion not set on /"), + }, + { + name: "no finalizers", + obj: &provv1.Cluster{ + Spec: provv1.ClusterSpec{ + KubernetesVersion: "test-version", + RKEConfig: &provv1.RKEConfig{}, + }, + Status: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + }, + expected: nil, + expectedStatus: provv1.ClusterStatus{ + ClusterName: "test-cluster", + }, + expectedErr: generic.ErrSkip, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := &handler{} + var status provv1.ClusterStatus + if tt.obj != nil { + status = tt.obj.Status + } + objs, generatedStatus, err := h.OnRancherClusterChange(tt.obj, status) + assert.Equal(t, tt.expected, objs) + assert.Equal(t, tt.expectedStatus, generatedStatus) + if tt.expectedErr != nil { + assert.NotNil(t, err) + assert.Equal(t, tt.expectedErr.Error(), err.Error()) + } else { + assert.Nil(t, err) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template.go new file mode 100644 index 0000000..69c32c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template.go @@ -0,0 +1,598 @@ +package provisioningcluster + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/lasso/pkg/dynamic" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rancherv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/capr/planner" + "github.com/rancher/rancher/pkg/controllers/capr/machineprovision" + mgmtcontroller "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/gvk" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/intstr" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func getInfraRef(rkeCluster *rkev1.RKECluster) *corev1.ObjectReference { + gvk, _ := gvk.Get(rkeCluster) + infraRef := &corev1.ObjectReference{ + Name: rkeCluster.Name, + } + infraRef.APIVersion, infraRef.Kind = gvk.ToAPIVersionAndKind() + return infraRef +} + +// objects generates the corresponding rkecontrolplanes.rke.cattle.io, clusters.cluster.x-k8s.io, and +// machinedeployments.cluster.x-k8s.io objects based on the passed in clusters.provisioning.cattle.io object +func objects(cluster *rancherv1.Cluster, dynamic *dynamic.Controller, dynamicSchema mgmtcontroller.DynamicSchemaCache, secrets v1.SecretCache) (result []runtime.Object, _ error) { + if !cluster.DeletionTimestamp.IsZero() { + return nil, nil + } + + infraRef := cluster.Spec.RKEConfig.InfrastructureRef + if infraRef == nil { + rkeCluster := rkeCluster(cluster) + infraRef = getInfraRef(rkeCluster) + result = append(result, rkeCluster) + } + + rkeControlPlane, err := rkeControlPlane(cluster) + if err != nil { + return nil, err + } + result = append(result, rkeControlPlane) + + capiCluster := capiCluster(cluster, rkeControlPlane, infraRef) + result = append(result, capiCluster) + + machineDeployments, err := machineDeployments(cluster, capiCluster, dynamic, dynamicSchema, secrets) + if err != nil { + return nil, err + } + + result = append(result, machineDeployments...) + return result, nil +} + +func pruneBySchema(data map[string]interface{}, dynamicSchemaSpec v3.DynamicSchemaSpec) { + for k := range data { + if _, ok := dynamicSchemaSpec.ResourceFields[k]; !ok { + delete(data, k) + } + } +} + +func takeOwnership(dynamic *dynamic.Controller, cluster *rancherv1.Cluster, nodeConfig runtime.Object) error { + m, err := meta.Accessor(nodeConfig) + if err != nil { + return err + } + + for _, owner := range m.GetOwnerReferences() { + if owner.Kind == "Cluster" && owner.APIVersion == "provisioning.cattle.io/v1" { + if owner.Name != cluster.Name { + return fmt.Errorf("can not use %s/%s [%v] because it is already owned by cluster %s", + m.GetNamespace(), m.GetName(), nodeConfig.GetObjectKind().GroupVersionKind(), owner.Name) + } + return nil + } + if owner.Controller != nil && *owner.Controller { + return fmt.Errorf("can not use %s/%s [%v] because it is already owned by %s %s", + m.GetNamespace(), m.GetName(), nodeConfig.GetObjectKind().GroupVersionKind(), owner.Kind, owner.Name) + } + } + + // Take ownership + + nodeConfig = nodeConfig.DeepCopyObject() + m, err = meta.Accessor(nodeConfig) + if err != nil { + return err + } + m.SetOwnerReferences(append(m.GetOwnerReferences(), metav1.OwnerReference{ + APIVersion: "provisioning.cattle.io/v1", + Kind: "Cluster", + Name: cluster.Name, + UID: cluster.UID, + Controller: &[]bool{true}[0], + BlockOwnerDeletion: &[]bool{true}[0], + })) + _, err = dynamic.Update(nodeConfig) + return err +} + +func toMachineTemplate(machinePoolName string, cluster *rancherv1.Cluster, machinePool rancherv1.RKEMachinePool, + dynamic *dynamic.Controller, secrets v1.SecretCache) (*unstructured.Unstructured, error) { + apiVersion := machinePool.NodeConfig.APIVersion + kind := machinePool.NodeConfig.Kind + if apiVersion == "" { + apiVersion = capr.DefaultMachineConfigAPIVersion + } + + gvk := schema.FromAPIVersionAndKind(apiVersion, kind) + nodeConfig, err := dynamic.Get(gvk, cluster.Namespace, machinePool.NodeConfig.Name) + if err != nil { + return nil, err + } + + if err := takeOwnership(dynamic, cluster, nodeConfig); err != nil { + return nil, err + } + + machinePoolData, err := data.Convert(nodeConfig.DeepCopyObject()) + if err != nil { + return nil, err + } + + if machinePool.DynamicSchemaSpec == "" { + logrus.Debugf("rkecluster %s/%s: waiting for dynamic schema to be populated for machine pool %s", cluster.Namespace, cluster.Name, machinePoolName) + return nil, generic.ErrSkip + } + var spec v3.DynamicSchemaSpec + err = json.Unmarshal([]byte(machinePool.DynamicSchemaSpec), &spec) + if err != nil { + return nil, err + } + + pruneBySchema(machinePoolData, spec) + + commonData, err := convert.EncodeToMap(machinePool.RKECommonNodeConfig) + if err != nil { + return nil, err + } + + machinePoolData.Set("common", commonData) + secretName := cluster.Spec.CloudCredentialSecretName + if machinePool.CloudCredentialSecretName != "" { + secretName = machinePool.CloudCredentialSecretName + } + + if secretName != "" { + _, err := machineprovision.GetCloudCredentialSecret(secrets, cluster.Namespace, secretName) + if err != nil { + return nil, err + } + machinePoolData.SetNested(secretName, "common", "cloudCredentialSecretName") + } + + ustr := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "kind": strings.TrimSuffix(kind, "Config") + "MachineTemplate", + "apiVersion": capr.RKEMachineAPIVersion, + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{ + capr.MachineTemplateClonedFromGroupVersionAnn: gvk.GroupVersion().String(), + capr.MachineTemplateClonedFromKindAnn: gvk.Kind, + capr.MachineTemplateClonedFromNameAnn: machinePool.NodeConfig.Name, + }, + "name": machinePoolName, + "namespace": cluster.Namespace, + "labels": map[string]interface{}{ + apply.LabelPrune: "false", + }, + }, + "spec": map[string]interface{}{ + "clusterName": cluster.Name, + "template": map[string]interface{}{ + "spec": map[string]interface{}(machinePoolData), + }, + }, + }, + } + mtHash := createMachineTemplateHash(ustr.Object) + ustr.SetName(name.SafeConcatName(ustr.GetName(), mtHash)) + newLabels := ustr.GetLabels() + newLabels[capr.MachineTemplateHashLabel] = mtHash + ustr.SetLabels(newLabels) + return ustr, nil +} + +func populateHostnameLengthLimitAnnotation(mp rancherv1.RKEMachinePool, cluster *rancherv1.Cluster, annotations map[string]string) error { + if cluster == nil { + return errors.New("cannot add hostname length limit annotation for nil cluster") + } + if annotations == nil { + return errors.Errorf("cannot add hostname length limit annotation for nil annotations") + } + hostnameLimit := 0 + + if limit := mp.HostnameLengthLimit; limit != 0 { + if limit < capr.MinimumHostnameLengthLimit { + logrus.Errorf("rkecluster %s/%s: cannot use machine pool %s hostname length limit, %d under minimum value of %d", cluster.Namespace, cluster.Name, mp.Name, limit, capr.MinimumHostnameLengthLimit) + } else if limit > capr.MaximumHostnameLengthLimit { + logrus.Errorf("rkecluster %s/%s: cannot use machine pool %s hostname length limit, %d under minimum value of %d", cluster.Namespace, cluster.Name, mp.Name, limit, capr.MinimumHostnameLengthLimit) + } else { + hostnameLimit = limit + } + } + + // if the machine pool limit was not specified, or was invalid, fallback to cluster default + if limit := cluster.Spec.RKEConfig.MachinePoolDefaults.HostnameLengthLimit; hostnameLimit == 0 && limit != 0 { + if limit < capr.MinimumHostnameLengthLimit { + logrus.Errorf("rkecluster %s/%s: cannot use cluster machine pool default hostname length limit, %d under minimum value of %d", cluster.Namespace, cluster.Name, limit, capr.MinimumHostnameLengthLimit) + } else if limit > capr.MaximumHostnameLengthLimit { + logrus.Errorf("rkecluster %s/%s: cannot use cluster machine pool default hostname length limit, %d under minimum value of %d", cluster.Namespace, cluster.Name, limit, capr.MinimumHostnameLengthLimit) + } else { + hostnameLimit = limit + } + } + + if hostnameLimit != 0 { + annotations[capr.HostnameLengthLimitAnnotation] = strconv.Itoa(hostnameLimit) + } + + return nil +} + +func createMachineTemplateHash(dataMap map[string]interface{}) string { + ustr := &unstructured.Unstructured{Object: dataMap} + dataMap = ustr.DeepCopy().Object + + name, _, _ := unstructured.NestedString(dataMap, "metadata", "name") + spec, _, _ := unstructured.NestedMap(dataMap, "spec", "template", "spec") + unstructured.RemoveNestedField(spec, "common") + planner.PruneEmpty(spec) + + sha := sha256.New() + sha.Write([]byte(name)) + + // ignore errors, shouldn't happen + bytes, _ := json.Marshal(spec) + + sha.Write(bytes) + + hash := sha.Sum(nil) + return hex.EncodeToString(hash[:])[:8] +} + +func machineDeployments(cluster *rancherv1.Cluster, capiCluster *capi.Cluster, dynamic *dynamic.Controller, + dynamicSchema mgmtcontroller.DynamicSchemaCache, secrets v1.SecretCache) (result []runtime.Object, _ error) { + bootstrapName := name.SafeConcatName(cluster.Name, "bootstrap", "template") + + if dynamicSchema == nil { + return nil, nil + } + + if len(cluster.Spec.RKEConfig.MachinePools) > 0 { + result = append(result, &rkev1.RKEBootstrapTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Namespace, + Name: bootstrapName, + Labels: map[string]string{ + capr.ClusterNameLabel: cluster.Name, + }, + }, + Spec: rkev1.RKEBootstrapTemplateSpec{ + ClusterName: cluster.Name, + Template: rkev1.RKEBootstrap{ + Spec: rkev1.RKEBootstrapSpec{ + ClusterName: cluster.Name, + }, + }, + }, + }) + } + + machinePoolNames := map[string]bool{} + for _, machinePool := range cluster.Spec.RKEConfig.MachinePools { + if machinePool.Quantity != nil && *machinePool.Quantity == 0 { + continue + } + if machinePool.Name == "" || machinePool.NodeConfig == nil || machinePool.NodeConfig.Name == "" || machinePool.NodeConfig.Kind == "" { + return nil, fmt.Errorf("invalid machinePool [%s] missing name or valid config", machinePool.Name) + } + if !machinePool.EtcdRole && + !machinePool.ControlPlaneRole && + !machinePool.WorkerRole { + return nil, fmt.Errorf("at least one role of etcd, control-plane or worker must be assigned to machinePool [%s]", machinePool.Name) + } + + if machinePoolNames[machinePool.Name] { + return nil, fmt.Errorf("duplicate machinePool name [%s] used", machinePool.Name) + } + machinePoolNames[machinePool.Name] = true + + var ( + machineDeploymentName = name.SafeConcatName(cluster.Name, machinePool.Name) + infraRef corev1.ObjectReference + ) + + if machinePool.NodeConfig.APIVersion == "" || machinePool.NodeConfig.APIVersion == "rke-machine-config.cattle.io/v1" { + machineTemplate, err := toMachineTemplate(machineDeploymentName, cluster, machinePool, dynamic, secrets) + if err != nil { + return nil, err + } + + result = append(result, machineTemplate) + infraRef = corev1.ObjectReference{ + APIVersion: machineTemplate.GetAPIVersion(), + Kind: machineTemplate.GetKind(), + Namespace: machineTemplate.GetNamespace(), + Name: machineTemplate.GetName(), + } + } else { + infraRef = *machinePool.NodeConfig + } + + if machinePool.MachineOS == "" { + machinePool.MachineOS = capr.DefaultMachineOS + } + if machinePool.MachineDeploymentLabels == nil { + machinePool.MachineDeploymentLabels = make(map[string]string) + } + machinePool.MachineDeploymentLabels[capr.CattleOSLabel] = machinePool.MachineOS + + machineDeploymentLabels := map[string]string{} + for k, v := range machinePool.Labels { + machineDeploymentLabels[k] = v + } + for k, v := range machinePool.MachineDeploymentLabels { + machineDeploymentLabels[k] = v + } + + machineSpecAnnotations := map[string]string{} + // Ignore drain if DrainBeforeDelete is unset + if !machinePool.DrainBeforeDelete { + machineSpecAnnotations[capi.ExcludeNodeDrainingAnnotation] = "true" + } + + err := populateHostnameLengthLimitAnnotation(machinePool, cluster, machineSpecAnnotations) + if err != nil { + return nil, err + } + + machineDeployment := &capi.MachineDeployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Namespace, + Name: machineDeploymentName, + Labels: machineDeploymentLabels, + Annotations: machinePool.MachineDeploymentAnnotations, + }, + Spec: capi.MachineDeploymentSpec{ + ClusterName: capiCluster.Name, + Replicas: machinePool.Quantity, + Strategy: &capi.MachineDeploymentStrategy{ + // RollingUpdate is the default, so no harm in setting it here. + Type: capi.RollingUpdateMachineDeploymentStrategyType, + RollingUpdate: &capi.MachineRollingUpdateDeployment{ + // Delete oldest machines by default. + DeletePolicy: &[]string{string(capi.OldestMachineSetDeletePolicy)}[0], + }, + }, + Template: capi.MachineTemplateSpec{ + ObjectMeta: capi.ObjectMeta{ + Labels: map[string]string{ + capi.ClusterNameLabel: capiCluster.Name, + capr.ClusterNameLabel: capiCluster.Name, + capi.MachineDeploymentNameLabel: machineDeploymentName, + capr.RKEMachinePoolNameLabel: machinePool.Name, + }, + Annotations: machineSpecAnnotations, + }, + Spec: capi.MachineSpec{ + ClusterName: capiCluster.Name, + Bootstrap: capi.Bootstrap{ + ConfigRef: &corev1.ObjectReference{ + Kind: "RKEBootstrapTemplate", + Namespace: cluster.Namespace, + Name: bootstrapName, + APIVersion: capr.RKEAPIVersion, + }, + }, + InfrastructureRef: infraRef, + NodeDrainTimeout: machinePool.DrainBeforeDeleteTimeout, + }, + }, + Paused: machinePool.Paused, + }, + } + if machinePool.RollingUpdate != nil { + machineDeployment.Spec.Strategy.RollingUpdate.MaxSurge = machinePool.RollingUpdate.MaxSurge + machineDeployment.Spec.Strategy.RollingUpdate.MaxUnavailable = machinePool.RollingUpdate.MaxUnavailable + } + + if machinePool.EtcdRole { + machineDeployment.Spec.Template.Labels[capr.EtcdRoleLabel] = "true" + } + + if machinePool.ControlPlaneRole { + machineDeployment.Spec.Template.Labels[capr.ControlPlaneRoleLabel] = "true" + machineDeployment.Spec.Template.Labels[capi.MachineControlPlaneLabel] = "true" + } + + if machinePool.WorkerRole { + machineDeployment.Spec.Template.Labels[capr.WorkerRoleLabel] = "true" + } + + if len(machinePool.MachineOS) > 0 { + machineDeployment.Spec.Template.Labels[capr.CattleOSLabel] = machinePool.MachineOS + } else { + machineDeployment.Spec.Template.Labels[capr.CattleOSLabel] = capr.DefaultMachineOS + } + + if len(machinePool.Labels) > 0 { + for k, v := range machinePool.Labels { + machineDeployment.Spec.Template.Labels[k] = v + } + if err := assign(machineDeployment.Spec.Template.Annotations, capr.LabelsAnnotation, machinePool.Labels); err != nil { + return nil, err + } + } + + if len(machinePool.Taints) > 0 { + if err := assign(machineDeployment.Spec.Template.Annotations, capr.TaintsAnnotation, machinePool.Taints); err != nil { + return nil, err + } + } + + result = append(result, machineDeployment) + + // if a health check timeout was specified create health checks for this machine pool + if machinePool.UnhealthyNodeTimeout != nil && machinePool.UnhealthyNodeTimeout.Duration > 0 { + hc := deploymentHealthChecks(machineDeployment, machinePool) + result = append(result, hc) + } + } + + return result, nil +} + +// deploymentHealthChecks Health checks will mark a machine as failed if it has any of the conditions below for the duration of the given timeout. https://cluster-api.sigs.k8s.io/tasks/healthcheck.html#what-is-a-machinehealthcheck +func deploymentHealthChecks(machineDeployment *capi.MachineDeployment, machinePool rancherv1.RKEMachinePool) *capi.MachineHealthCheck { + var maxUnhealthy *intstr.IntOrString + if machinePool.MaxUnhealthy != nil { + maxUnhealthy = new(intstr.IntOrString) + *maxUnhealthy = intstr.Parse(*machinePool.MaxUnhealthy) + } + + return &capi.MachineHealthCheck{ + ObjectMeta: metav1.ObjectMeta{ + Name: machineDeployment.Name, + Namespace: machineDeployment.Namespace, + }, + Spec: capi.MachineHealthCheckSpec{ + ClusterName: machineDeployment.Spec.ClusterName, + Selector: metav1.LabelSelector{ // this health check only applies to machines in this deployment + MatchLabels: map[string]string{ + capi.MachineDeploymentNameLabel: machineDeployment.Name, + }, + }, + UnhealthyConditions: []capi.UnhealthyCondition{ // if a node status is unready or unknown for the timeout mark it unhealthy + { + Status: corev1.ConditionUnknown, + Type: corev1.NodeReady, + Timeout: *machinePool.UnhealthyNodeTimeout, + }, + { + Status: corev1.ConditionFalse, + Type: corev1.NodeReady, + Timeout: *machinePool.UnhealthyNodeTimeout, + }, + }, + MaxUnhealthy: maxUnhealthy, + UnhealthyRange: machinePool.UnhealthyRange, + NodeStartupTimeout: machinePool.NodeStartupTimeout, + }, + } +} + +func assign(labels map[string]string, key string, value interface{}) error { + data, err := json.Marshal(value) + if err != nil { + return err + } + labels[key] = string(data) + return nil +} + +func rkeCluster(cluster *rancherv1.Cluster) *rkev1.RKECluster { + return &rkev1.RKECluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Name, + Namespace: cluster.Namespace, + Annotations: map[string]string{capr.DeleteMissingCustomMachinesAfterAnnotation: cluster.Annotations[capr.DeleteMissingCustomMachinesAfterAnnotation]}, + }, + } +} + +// rkeControlPlane generates the rkecontrolplane object for a provided cluster object +func rkeControlPlane(cluster *rancherv1.Cluster) (*rkev1.RKEControlPlane, error) { + // We need to base64/gzip encode the spec of our rancherv1.Cluster object so that we can reference it from the + // downstream cluster + filteredClusterSpec := cluster.Spec.DeepCopy() + // set the corresponding specification for various operations to nil as these cause unnecessary reconciliation. + filteredClusterSpec.RKEConfig.ETCDSnapshotRestore = nil + filteredClusterSpec.RKEConfig.ETCDSnapshotCreate = nil + filteredClusterSpec.RKEConfig.RotateEncryptionKeys = nil + filteredClusterSpec.RKEConfig.RotateCertificates = nil + b64GZCluster, err := capr.CompressInterface(filteredClusterSpec) + if err != nil { + logrus.Errorf("cluster: %s/%s : error while gz/b64 encoding cluster specification: %v", cluster.Namespace, cluster.Name, err) + return nil, err + } + rkeConfig := cluster.Spec.RKEConfig.DeepCopy() + return &rkev1.RKEControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Name, + Namespace: cluster.Namespace, + Labels: map[string]string{ + capr.InitNodeMachineIDLabel: cluster.Labels[capr.InitNodeMachineIDLabel], + }, + Annotations: map[string]string{ + capr.ClusterSpecAnnotation: b64GZCluster, + }, + }, + Spec: rkev1.RKEControlPlaneSpec{ + RKEClusterSpecCommon: rkeConfig.RKEClusterSpecCommon, + LocalClusterAuthEndpoint: *cluster.Spec.LocalClusterAuthEndpoint.DeepCopy(), + ETCDSnapshotRestore: rkeConfig.ETCDSnapshotRestore, + ETCDSnapshotCreate: rkeConfig.ETCDSnapshotCreate, + RotateCertificates: rkeConfig.RotateCertificates, + RotateEncryptionKeys: rkeConfig.RotateEncryptionKeys, + KubernetesVersion: cluster.Spec.KubernetesVersion, + ManagementClusterName: cluster.Status.ClusterName, // management cluster + AgentEnvVars: cluster.Spec.AgentEnvVars, + ClusterName: cluster.Name, // cluster name is for the CAPI cluster + }, + }, nil +} + +func capiCluster(cluster *rancherv1.Cluster, rkeControlPlane *rkev1.RKEControlPlane, infraRef *corev1.ObjectReference) *capi.Cluster { + gvk, err := gvk.Get(rkeControlPlane) + if err != nil { + // this is a build issue if it happens + panic(err) + } + + apiVersion, kind := gvk.ToAPIVersionAndKind() + + ownerGVK := rancherv1.SchemeGroupVersion.WithKind("Cluster") + ownerAPIVersion, _ := ownerGVK.ToAPIVersionAndKind() + return &capi.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: cluster.Name, + Namespace: cluster.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: ownerAPIVersion, + Kind: ownerGVK.Kind, + Name: cluster.Name, + UID: cluster.UID, + Controller: &[]bool{true}[0], + BlockOwnerDeletion: &[]bool{true}[0], + }, + }, + }, + Spec: capi.ClusterSpec{ + InfrastructureRef: infraRef, + ControlPlaneRef: &corev1.ObjectReference{ + Kind: kind, + Namespace: rkeControlPlane.Namespace, + Name: rkeControlPlane.Name, + APIVersion: apiVersion, + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template_test.go new file mode 100644 index 0000000..58f2ef5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioningcluster/template_test.go @@ -0,0 +1,96 @@ +package provisioningcluster + +import ( + "testing" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/stretchr/testify/assert" +) + +func TestPopulateHostnameLengthLimitAnnotation(t *testing.T) { + tests := []struct { + name string + machinePool provv1.RKEMachinePool + defaultHostnameLengthLimit int + expected map[string]string + }{ + { + name: "default", + expected: map[string]string{}, + }, + { + name: "machine pool valid", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 32}, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "32"}, + }, + { + name: "machine pool valid min", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 10}, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "10"}, + }, + { + name: "machine pool valid max", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 63}, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "63"}, + }, + { + name: "machine pool < min", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 1}, + expected: map[string]string{}, + }, + { + name: "machine pool > max", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 64}, + expected: map[string]string{}, + }, + { + name: "default valid", + defaultHostnameLengthLimit: 32, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "32"}, + }, + { + name: "default valid min", + defaultHostnameLengthLimit: 10, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "10"}, + }, + { + name: "default valid max", + defaultHostnameLengthLimit: 63, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "63"}, + }, + { + name: "default < min", + defaultHostnameLengthLimit: 1, + expected: map[string]string{}, + }, + { + name: "default > max", + defaultHostnameLengthLimit: 64, + expected: map[string]string{}, + }, + { + name: "prefer pool value over default", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 16}, + defaultHostnameLengthLimit: 32, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "16"}, + }, + { + name: "fallback default", + machinePool: provv1.RKEMachinePool{HostnameLengthLimit: 1234}, + defaultHostnameLengthLimit: 32, + expected: map[string]string{"rke.cattle.io/hostname-length-limit": "32"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + annotations := map[string]string{} + tt.machinePool.Name = tt.name + err := populateHostnameLengthLimitAnnotation(tt.machinePool, &provv1.Cluster{Spec: provv1.ClusterSpec{RKEConfig: &provv1.RKEConfig{ + MachinePoolDefaults: provv1.RKEMachinePoolDefaults{HostnameLengthLimit: tt.defaultHostnameLengthLimit}, + }}}, annotations) + assert.NoError(t, err) + assert.Equal(t, tt.expected, annotations) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioninglog/provisioninglog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioninglog/provisioninglog.go new file mode 100644 index 0000000..a38565d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/provisioninglog/provisioninglog.go @@ -0,0 +1,141 @@ +package provisioninglog + +import ( + "context" + "fmt" + "regexp" + "strings" + "time" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterindex" + provisioningcontrollers "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + provisioningLogName = "provisioning-log" + maxLen = 10000 +) + +var ( + clusterRegexp = regexp.MustCompile("^c-m-[a-z0-9]{8}$") +) + +func Register(ctx context.Context, clients *wrangler.Context) { + h := &handler{ + configMapsCache: clients.Core.ConfigMap().Cache(), + configMaps: clients.Core.ConfigMap(), + clusterCache: clients.Provisioning.Cluster().Cache(), + } + + clients.Core.Namespace().OnChange(ctx, "prov-log-namespace", h.OnNamespace) + clients.Core.ConfigMap().OnChange(ctx, "prov-log-configmap", h.OnConfigMap) +} + +type handler struct { + configMapsCache corev1controllers.ConfigMapCache + configMaps corev1controllers.ConfigMapController + clusterCache provisioningcontrollers.ClusterCache +} + +func (h *handler) OnConfigMap(key string, cm *corev1.ConfigMap) (*corev1.ConfigMap, error) { + if cm == nil || !cm.DeletionTimestamp.IsZero() { + return nil, nil + } + if cm.Name != provisioningLogName || (!clusterRegexp.MatchString(cm.Namespace) && cm.Namespace != "local") { + return cm, nil + } + provCluster, err := h.clusterCache.GetByIndex(clusterindex.ClusterV1ByClusterV3Reference, cm.Namespace) + if err != nil && !apierrors.IsNotFound(err) { + return cm, err + } + if apierrors.IsNotFound(err) || len(provCluster) == 0 { + h.configMaps.EnqueueAfter(cm.Namespace, cm.Name, 2*time.Second) + return cm, nil + } + if provCluster[0].Spec.RKEConfig == nil { + return cm, nil + } + + h.configMaps.EnqueueAfter(cm.Namespace, cm.Name, 2*time.Second) + return h.recordMessage(provCluster[0], cm) +} + +func appendLog(error bool, oldLog, log string) string { + if len(oldLog) > maxLen { + oldLog = oldLog[:maxLen] + oldLog = strings.TrimRightFunc(oldLog, func(r rune) bool { + return r != '\n' + }) + } + prefix := " [INFO ] " + if error { + prefix = " [ERROR] " + } + return oldLog + time.Now().Format(time.RFC3339) + prefix + log + "\n" +} + +func (h *handler) recordMessage(provCluster *provv1.Cluster, cm *corev1.ConfigMap) (*corev1.ConfigMap, error) { + msg := capr.Provisioned.GetMessage(provCluster) + error := capr.Provisioned.IsFalse(provCluster) + done := capr.Provisioned.IsTrue(provCluster) + + if done && msg == "" { + done = capr.Updated.IsTrue(provCluster) + msg = capr.Updated.GetMessage(provCluster) + error = capr.Updated.IsFalse(provCluster) + } + + if done && msg == "" && provCluster.Status.Ready { + msg = "provisioning done" + } + + if msg == "" { + return cm, nil + } + + if strings.Contains(msg, "the object has been modified; please apply your changes to the latest version and try again") { + msg = fmt.Sprintf("Transient error encountered: %s", msg) + } + + last := cm.Data["last"] + if msg == last { + return cm, nil + } + + cm = cm.DeepCopy() + if cm.Data == nil { + cm.Data = map[string]string{} + } + + cm.Data["log"] = appendLog(error, cm.Data["log"], msg) + cm.Data["last"] = msg + return h.configMaps.Update(cm) +} + +func (h *handler) OnNamespace(key string, ns *corev1.Namespace) (*corev1.Namespace, error) { + if ns == nil || !ns.DeletionTimestamp.IsZero() { + return nil, nil + } + if !clusterRegexp.MatchString(ns.Name) { + return ns, nil + } + if _, err := h.configMapsCache.Get(ns.Name, provisioningLogName); apierrors.IsNotFound(err) { + _, err := h.configMaps.Create(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: provisioningLogName, + Namespace: ns.Name, + }, + }) + if err != nil { + return nil, fmt.Errorf("creating %s for %s: %w", provisioningLogName, ns.Name, err) + } + } + return ns, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/secret/secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/secret/secret.go new file mode 100644 index 0000000..84b9ecc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/controllers/provisioningv2/secret/secret.go @@ -0,0 +1,136 @@ +package secret + +import ( + "context" + + "github.com/rancher/rancher/pkg/controllers/management/rbac" + "github.com/rancher/rancher/pkg/wrangler" + wranglerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + v1 "k8s.io/api/core/v1" + k8srbac "k8s.io/api/rbac/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Register(ctx context.Context, clients *wrangler.Context) { + h := handler{ + roles: clients.RBAC.Role(), + rolesCache: clients.RBAC.Role().Cache(), + roleBindings: clients.RBAC.RoleBinding(), + roleBindingsCache: clients.RBAC.RoleBinding().Cache(), + secrets: clients.Core.Secret(), + } + + clients.Core.Secret().OnChange(ctx, "provisioning-v2-secret", h.OnSecret) +} + +type handler struct { + roles rbacv1.RoleClient + rolesCache rbacv1.RoleCache + roleBindings rbacv1.RoleBindingClient + roleBindingsCache rbacv1.RoleBindingCache + secrets wranglerv1.SecretClient +} + +// OnSecret syncs a creators permissions to a provisioning cloud-credential. This is based off +// the creator ID annotation that is added in the webhook when the secret is created. A role +// and binding are created to grant the creator permissions and then the annotation is removed. +func (h *handler) OnSecret(key string, secret *v1.Secret) (*v1.Secret, error) { + if secret == nil || secret.DeletionTimestamp != nil || secret.Type != "provisioning.cattle.io/cloud-credential" { + return secret, nil + } + creatorID, ok := secret.Annotations[rbac.CreatorIDAnn] + if !ok || creatorID == "" { + return secret, nil + } + + if err := h.ensureCreatorPermissions(creatorID, secret); err != nil { + return secret, err + } + + s := secret.DeepCopy() + delete(s.Annotations, rbac.CreatorIDAnn) + + return h.secrets.Update(s) +} + +func (h *handler) ensureCreatorPermissions(creatorID string, secret *v1.Secret) error { + name := creatorID + "-" + secret.Name + + // The owner reference for the role and binding are tied to the secret since a + // user is not guaranteed to be a management.cattle.io user CR + ownerRef := metav1.OwnerReference{ + APIVersion: v1.SchemeGroupVersion.Version, + Kind: "Secret", + Name: secret.Name, + UID: secret.UID, + } + if err := h.ensureRole(secret.Namespace, name, ownerRef); err != nil { + return err + } + + return h.ensureBinding(secret.Namespace, name, creatorID, ownerRef) +} + +func (h *handler) ensureRole(namespace, name string, ownerRef metav1.OwnerReference) error { + _, err := h.rolesCache.Get(namespace, name) + if err != nil { + if !k8serrors.IsNotFound(err) { + return err + } + + role := &k8srbac.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + }, + Rules: []k8srbac.PolicyRule{ + { + Verbs: []string{"get", "update", "delete"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{ownerRef.Name}, + }, + }, + } + + if _, err := h.roles.Create(role); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + } + return nil +} + +func (h *handler) ensureBinding(namespace, name, creatorID string, ownerRef metav1.OwnerReference) error { + _, err := h.roleBindingsCache.Get(namespace, name) + if err != nil { + if !k8serrors.IsNotFound(err) { + return err + } + + binding := &k8srbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + OwnerReferences: []metav1.OwnerReference{ownerRef}, + }, + Subjects: []k8srbac.Subject{ + { + Kind: k8srbac.UserKind, + Name: creatorID, + }, + }, + RoleRef: k8srbac.RoleRef{ + Kind: "Role", + Name: name, + }, + } + + if _, err := h.roleBindings.Create(binding); err != nil && !k8serrors.IsAlreadyExists(err) { + return err + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds.go new file mode 100644 index 0000000..6156177 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds.go @@ -0,0 +1,173 @@ +// Package crds is used for installing rancher CRDs. +package crds + +import ( + "context" + "embed" + "fmt" + "path/filepath" + "time" + + "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/rancher/wrangler/v3/pkg/yaml" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + clientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" +) + +const ( + baseDir = "." + + // readyDuration time to wait for CRDs to be ready. + readyDuration = time.Minute * 1 + + k8sManagedByKey = "app.kubernetes.io/managed-by" + managerValue = "rancher" + crdKind = "CustomResourceDefinition" +) + +var ( + //go:embed yaml + crdFS embed.FS + + errDuplicate = fmt.Errorf("duplicate CRD") +) + +// EnsureRequired will ensure all required CRDs needed by Rancher based on the currently enabled features are installed and up to date. +func EnsureRequired(ctx context.Context, crdClient clientv1.CustomResourceDefinitionInterface) error { + return Ensure(ctx, crdClient, RequiredCRDs()) +} + +// Ensure will ensure all given CRD names are installed and up to date. +// Ensure looks for matching crd names inside the embedded directory 'yaml'. +func Ensure(ctx context.Context, crdClient clientv1.CustomResourceDefinitionInterface, crdNames []string) error { + toCreateCRDs, err := getCRDs(crdNames) + if err != nil { + return fmt.Errorf("failed to get CRDs: %w", err) + } + + ownedByRancher, err := labels.NewRequirement(k8sManagedByKey, selection.Equals, []string{managerValue}) + if err != nil { + return fmt.Errorf("failed to create crd label selector: %w", err) + } + selector := labels.NewSelector().Add(*ownedByRancher) + + err = crd.BatchCreateCRDs(ctx, crdClient, selector, readyDuration, toCreateCRDs) + if err != nil { + return fmt.Errorf("failed to create CRDs: %w", err) + } + + return nil +} + +// getCRDs finds all embedded CRDs that match the given list of CRDs. If a CRD is specified and not found an error is returned. +func getCRDs(crdNames []string) ([]*apiextv1.CustomResourceDefinition, error) { + allCRDs, err := crdsFromDir(baseDir) + if err != nil { + return nil, err + } + + capiMap := toMap(CAPICRDs()) + bootstrapFleetMap := toMap(bootstrapFleet()) + + retCRDs := []*apiextv1.CustomResourceDefinition{} + + for _, crdName := range crdNames { + // only return CRDs that are specified and have been migrated to the new CRD generation flow + if !MigratedResources[crdName] { + continue + } + + crd, found := allCRDs[crdName] + if !found { + return nil, fmt.Errorf("CRD yaml '%s' not found in embedded file system", crdName) + } + + if crd.Labels == nil { + crd.Labels = map[string]string{} + } + + // dynamically add labels to capi crds since we do not generate them. + if capiMap[crd.Name] { + crd.Labels["auth.cattle.io/cluster-indexed"] = "true" + } + + // Add managed by label + if bootstrapFleetMap[crd.Name] { + // Ensure labels/annotations are set so that helm will manage this + crd.Labels[k8sManagedByKey] = "Helm" + if crd.Annotations == nil { + crd.Annotations = map[string]string{} + } + crd.Annotations["meta.helm.sh/release-name"] = fleet.CRDChartName + crd.Annotations["meta.helm.sh/release-namespace"] = fleet.ReleaseNamespace + } else { + // since this CRD is installed by rancher add the manged by label + crd.Labels[k8sManagedByKey] = managerValue + } + + retCRDs = append(retCRDs, crd) + } + + return retCRDs, nil +} + +// crdsFromDir recursively traverses the embedded yaml directory and find all CRD yamls. +func crdsFromDir(dirName string) (map[string]*apiextv1.CustomResourceDefinition, error) { + // read all entries in the embedded directory + crdFiles, err := crdFS.ReadDir(dirName) + if err != nil { + return nil, fmt.Errorf("failed to read embedded dir '%s': %w", dirName, err) + } + + allCRDs := map[string]*apiextv1.CustomResourceDefinition{} + for _, dirEntry := range crdFiles { + fullPath := filepath.Join(dirName, dirEntry.Name()) + if dirEntry.IsDir() { + // if the entry is the dir recurse into that folder to get all crds + subCRDs, err := crdsFromDir(fullPath) + if err != nil { + return nil, err + } + for k, v := range subCRDs { + if _, ok := allCRDs[k]; ok { + return nil, fmt.Errorf("%w for '%s", errDuplicate, k) + } + allCRDs[k] = v + } + continue + } + + // read the file and convert it to a crd object + file, err := crdFS.Open(fullPath) + if err != nil { + return nil, fmt.Errorf("failed to open embedded file '%s': %w", fullPath, err) + } + crdObjs, err := yaml.UnmarshalWithJSONDecoder[*apiextv1.CustomResourceDefinition](file) + if err != nil { + return nil, fmt.Errorf("failed to convert embedded file '%s' to yaml: %w", fullPath, err) + } + for _, crdObj := range crdObjs { + if crdObj.Kind != crdKind { + // if the yaml is not a CRD return an error + return nil, fmt.Errorf("decoded object is not '%s' instead found Kind='%s'", crdKind, crdObj.Kind) + } + if _, ok := allCRDs[crdObj.Name]; ok { + return nil, fmt.Errorf("%w for '%s", errDuplicate, crdObj.Name) + } + allCRDs[crdObj.Name] = crdObj + } + } + return allCRDs, nil +} + +// toMap converts a list of slice to a map. +func toMap(strings []string) map[string]bool { + retMap := make(map[string]bool, len(strings)) + for _, name := range strings { + retMap[name] = true + } + return retMap +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds_test.go new file mode 100644 index 0000000..3147fd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/crds_test.go @@ -0,0 +1,215 @@ +// Package crds is used for installing rancher CRDs +package crds + +import ( + "context" + "embed" + "fmt" + "sort" + "testing" + + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/fleet" + "github.com/stretchr/testify/require" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + fakeclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1/fake" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + k8stesting "k8s.io/client-go/testing" +) + +const ( + capiCRD = "clusters.cluster.x-k8s.io" + rtCRD = "roletemplates.management.cattle.io" + grCRD = "globalroles.management.cattle.io" + bootstrapFleetCRD = "clusters.fleet.cattle.io" +) + +var ( + originalFs = crdFS + originalMigrated = MigratedResources + + //go:embed yaml_test/yaml + validFS embed.FS + + //go:embed yaml_test/dup_yaml + dupFs embed.FS + + //go:embed yaml_test/pod_yaml + podFS embed.FS + + //go:embed yaml_test/bad_yaml + badFS embed.FS + + staticCRD = &apiextv1.CustomResourceDefinition{ + TypeMeta: v1.TypeMeta{Kind: "CustomResourceDefinition", APIVersion: "apiextensions.k8s.io/v1"}, + ObjectMeta: v1.ObjectMeta{Name: "crdName"}, + Status: apiextv1.CustomResourceDefinitionStatus{Conditions: []apiextv1.CustomResourceDefinitionCondition{ + { + Type: "NamesAccepted", + Status: "True", + Reason: "NoConflicts", + Message: "no conflicts found", + }, + { + Type: "Established", + Status: "True", + Reason: "InitialNamesAccepted", + Message: "the initial names have been accepted", + }, + }}, + } +) + +func TestEnsure_MCM(t *testing.T) { + defer resetGlobals() + testClient := setupFakeClient() + crdFS = validFS + + migrated := map[string]bool{rtCRD: true, capiCRD: true, grCRD: false} + expected := []string{rtCRD, capiCRD} + + features.MCM.Set(true) + + MigratedResources = migrated + err := EnsureRequired(context.Background(), testClient.client) + require.NoError(t, err, "unexpected error when creating yaml") + sort.Strings(expected) + sort.Strings(testClient.CrdNames) + require.Equal(t, expected, testClient.CrdNames, "unexpected CRDs created") +} + +func TestEnsure_NonMCM(t *testing.T) { + defer resetGlobals() + testClient := setupFakeClient() + crdFS = validFS + + features.MCM.Set(false) + MigratedResources = map[string]bool{rtCRD: true, capiCRD: true, grCRD: false} + expected := []string{capiCRD} + + err := EnsureRequired(context.Background(), testClient.client) + require.NoError(t, err, "unexpected error when creating yaml") + sort.Strings(expected) + sort.Strings(testClient.CrdNames) + require.Equal(t, expected, testClient.CrdNames, "unexpected CRDs created") +} + +func TestEnsure_MissingCRDs(t *testing.T) { + defer resetGlobals() + MigratedResources = map[string]bool{"doese-not-exist": true} + _, err := getCRDs([]string{"doese-not-exist"}) + require.Error(t, err, "expected error when CRDs could not be found") +} + +func TestEnsure_DesiredFS(t *testing.T) { + // This test is to verify that the crdFS is not accidentally changed to embed an unexpected file system. + entries, err := crdFS.ReadDir(baseDir) + require.NoError(t, err, "failed to read CRD FS") + require.Len(t, entries, 1, "expected one `yaml` dir in FileSystem") + require.Equal(t, entries[0].Name(), "yaml", "expected one `yaml` dir in FileSystem") +} + +func TestEnsure_DuplicateCRDs(t *testing.T) { + defer resetGlobals() + crdFS = dupFs + err := EnsureRequired(context.Background(), setupFakeClient().client) + require.ErrorIs(t, err, errDuplicate, "expected duplicate error for redefined CRDs") +} + +func TestEnsure_InvalidCRDs(t *testing.T) { + defer resetGlobals() + crdFS = badFS + err := EnsureRequired(context.Background(), setupFakeClient().client) + require.Error(t, err, "expected error when invalid YAML file is encountered") +} + +func TestEnsure_NonCRDsFound(t *testing.T) { + defer resetGlobals() + crdFS = podFS + err := EnsureRequired(context.Background(), setupFakeClient().client) + require.Error(t, err, "expected error when invalid YAML file is encountered") +} + +func TestEnsure_failedCreate(t *testing.T) { + defer resetGlobals() + testClient := setupFakeClient() + crdFS = validFS + MigratedResources = map[string]bool{rtCRD: true} + testsErr := fmt.Errorf("test error") + testClient.client.Fake.PrependReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + return true, nil, testsErr + }) + features.MCM.Set(true) + err := EnsureRequired(context.Background(), testClient.client) + require.ErrorIs(t, err, testsErr, "expected error when creating YAML file got='%v'", err) +} + +func TestEnusure_metadata(t *testing.T) { + defer resetGlobals() + testClient := setupFakeClient() + crdFS = validFS + + MigratedResources = map[string]bool{rtCRD: true, capiCRD: true, bootstrapFleetCRD: true} + expected := []string{rtCRD, capiCRD, bootstrapFleetCRD} + + features.MCM.Set(true) + features.Fleet.Set(true) + features.EmbeddedClusterAPI.Set(true) + features.ProvisioningV2.Set(true) + + err := EnsureRequired(context.Background(), testClient.client) + require.NoError(t, err, "unexpected error when creating yaml") + sort.Strings(expected) + sort.Strings(testClient.CrdNames) + require.Equal(t, expected, testClient.CrdNames, "unexpected CRDs created") + + rtCRDObj, ok := testClient.CRDValues[rtCRD] + require.True(t, ok, "%s CRD not found", rtCRD) + require.NotNil(t, rtCRDObj.Labels, "rancher managed object missing labels") + require.Equal(t, managerValue, rtCRDObj.Labels[k8sManagedByKey], "%s CRD missing expected managed-by label", rtCRD) + + capiCRDObj, ok := testClient.CRDValues[capiCRD] + require.True(t, ok, "%s CRD not found", capiCRD) + require.NotNil(t, capiCRDObj.Labels, "rancher managed object missing labels") + require.Equal(t, managerValue, capiCRDObj.Labels[k8sManagedByKey], "%s CRD missing expected managed-by label", capiCRD) + require.Equal(t, "true", capiCRDObj.Labels["auth.cattle.io/cluster-indexed"], "%s CRD missing expected auth label", capiCRD) + + fleetObj, ok := testClient.CRDValues[bootstrapFleetCRD] + require.True(t, ok, "%s CRD not found", bootstrapFleetCRD) + require.NotNil(t, fleetObj.Labels, "fleet managed object missing labels") + require.Equal(t, "Helm", fleetObj.Labels[k8sManagedByKey], "%s CRD missing expected managed-by label", bootstrapFleetCRD) + require.NotNil(t, fleetObj.Annotations, "fleet managed object missing annotations") + require.Equal(t, fleet.CRDChartName, fleetObj.Annotations["meta.helm.sh/release-name"], "%s CRD missing expected annotation", bootstrapFleetCRD) + require.Equal(t, fleet.ReleaseNamespace, fleetObj.Annotations["meta.helm.sh/release-namespace"], "%s CRD missing expected annotation", bootstrapFleetCRD) +} + +func setupFakeClient() *FakeClient { + fakeClient := &FakeClient{client: fakeclientset.NewSimpleClientset(staticCRD).ApiextensionsV1().CustomResourceDefinitions().(*fake.FakeCustomResourceDefinitions)} + fakeClient.client.Fake.PrependReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + crd := action.(k8stesting.CreateAction).GetObject().(*apiextv1.CustomResourceDefinition) + fakeClient.CrdNames = append(fakeClient.CrdNames, crd.Name) + if fakeClient.CRDValues == nil { + fakeClient.CRDValues = map[string]*apiextv1.CustomResourceDefinition{} + } + fakeClient.CRDValues[crd.Name] = crd + return true, staticCRD, nil + }) + fakeClient.client.Fake.PrependReactor("get", "customresourcedefinitions", func(k8stesting.Action) (handled bool, ret runtime.Object, err error) { + return true, staticCRD, nil + }) + + return fakeClient +} + +type FakeClient struct { + client *fake.FakeCustomResourceDefinitions + CrdNames []string + CRDValues map[string]*apiextv1.CustomResourceDefinition +} + +func resetGlobals() { + crdFS = originalFs + MigratedResources = originalMigrated +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds.go new file mode 100644 index 0000000..f14efd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds.go @@ -0,0 +1,223 @@ +package dashboard + +import ( + "context" + + fleetv1alpha1api "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + uiv1 "github.com/rancher/rancher/pkg/apis/ui.cattle.io/v1" + "github.com/rancher/rancher/pkg/crds" + "github.com/rancher/rancher/pkg/crds/provisioningv2" + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +var ( + bootstrapFleet = map[string]interface{}{ + "bundles.fleet.cattle.io": fleetv1alpha1api.Bundle{}, + "clusters.fleet.cattle.io": fleetv1alpha1api.Cluster{}, + "clustergroups.fleet.cattle.io": fleetv1alpha1api.ClusterGroup{}, + } +) + +func FeatureCRD() crd.CRD { + return newCRD(&v3.Feature{}, func(c crd.CRD) crd.CRD { + c.NonNamespace = true + return c. + WithColumn("Custom Value", ".spec.value"). + WithColumn("Default", ".status.default"). + WithColumn("Description", ".status.description") + }) +} + +func List(cfg *rest.Config) (_ []crd.CRD, err error) { + result := []crd.CRD{ + newCRD(&uiv1.NavLink{}, func(c crd.CRD) crd.CRD { + c.Status = false + c.NonNamespace = true + c.GVK.Kind = "NavLink" + c.GVK.Group = "ui.cattle.io" + c.GVK.Version = "v1" + return c + }), + newCRD(&v3.PodSecurityAdmissionConfigurationTemplate{}, func(c crd.CRD) crd.CRD { + c.NonNamespace = true + c.GVK.Kind = "PodSecurityAdmissionConfigurationTemplate" + c.GVK.Version = "v3" + return c + }), + newCRD(&v3.Cluster{}, func(c crd.CRD) crd.CRD { + c.Status = false + c.NonNamespace = true + c.GVK.Kind = "Cluster" + c.GVK.Group = "management.cattle.io" + c.GVK.Version = "v3" + c.SchemaObject = nil + return c + }), + newCRD(&v3.APIService{}, func(c crd.CRD) crd.CRD { + c.NonNamespace = true + c.Status = true + return c + }), + newCRD(&v3.ClusterRegistrationToken{}, func(c crd.CRD) crd.CRD { + return c + }), + newCRD(&v3.Setting{}, func(c crd.CRD) crd.CRD { + c.NonNamespace = true + return c. + WithColumn("Value", ".value") + }), + newCRD(&v3.Preference{}, func(c crd.CRD) crd.CRD { + return c. + WithColumn("Value", ".value") + }), + FeatureCRD(), + newCRD(&catalogv1.ClusterRepo{}, func(c crd.CRD) crd.CRD { + c.NonNamespace = true + return c. + WithStatus(). + WithCategories("catalog"). + WithColumn("URL", ".spec.url") + }), + newCRD(&catalogv1.Operation{}, func(c crd.CRD) crd.CRD { + return c. + WithStatus(). + WithCategories("catalog"). + WithColumn("Target Namespace", ".status.podNamespace"). + WithColumn("Command", ".status.command") + }), + newCRD(&catalogv1.App{}, func(c crd.CRD) crd.CRD { + return c. + WithStatus(). + WithCategories("catalog"). + WithColumn("Chart", ".spec.chart.metadata.name"). + WithColumn("Version", ".spec.chart.metadata.version"). + WithColumn("Release Name", ".spec.name"). + WithColumn("Release Version", ".spec.version"). + WithColumn("Status", ".spec.info.status") + }), + } + + if features.Fleet.Enabled() { + result = append(result, crd.CRD{ + SchemaObject: v3.FleetWorkspace{}, + NonNamespace: true, + }) + result, err = fleetBootstrap(result, cfg) + if err != nil { + return nil, err + } + if features.ProvisioningV2.Enabled() { + result = append(result, crd.CRD{ + SchemaObject: v3.ManagedChart{}, + }.WithStatus()) + } + } + + if features.ProvisioningV2.Enabled() { + result = append(result, provisioningv2.List()...) + } + for i := len(result) - 1; i >= 0; i-- { + if crds.MigratedResources[result[i].Name()] { + // remove the migrated resource from the result slice so we do not install a dynamic definition + result = append(result[:i], result[i+1:]...) + } + } + return result, nil +} + +func fleetBootstrap(crds []crd.CRD, cfg *rest.Config) ([]crd.CRD, error) { + if !features.Fleet.Enabled() { + return crds, nil + } + + f, err := apiextensions.NewFactoryFromConfig(cfg) + if err != nil { + return nil, err + } + + for name, schemaObj := range bootstrapFleet { + _, err = f.Apiextensions().V1().CustomResourceDefinition().Get(name, metav1.GetOptions{}) + if err == nil { + continue + } else if !apierror.IsNotFound(err) { + return nil, err + } + + crds = append(crds, crd.CRD{ + SchemaObject: schemaObj, + Status: true, + // Ensure labels/annotations are set so that helm will manage this + Labels: map[string]string{ + "app.kubernetes.io/managed-by": "Helm", + }, + Annotations: map[string]string{ + "meta.helm.sh/release-name": fleetconst.CRDChartName, + "meta.helm.sh/release-namespace": fleetconst.ReleaseNamespace, + }, + }) + } + + return crds, nil +} + +func Webhooks() []runtime.Object { + if features.ProvisioningV2.Enabled() { + return provisioningv2.Webhooks() + } + return nil +} + +func CreateFeatureCRD(ctx context.Context, cfg *rest.Config) error { + factory, err := crd.NewFactoryFromClient(cfg) + if err != nil { + return err + } + + return factory.BatchCreateCRDs(ctx, FeatureCRD()).BatchWait() +} + +func Create(ctx context.Context, cfg *rest.Config) error { + factory, err := crd.NewFactoryFromClient(cfg) + if err != nil { + return err + } + + apply, err := apply.NewForConfig(cfg) + if err != nil { + return err + } + apply = apply. + WithSetID("crd-webhooks"). + WithDynamicLookup(). + WithNoDelete() + if err := apply.ApplyObjects(Webhooks()...); err != nil { + return err + } + + crds, err := List(cfg) + if err != nil { + return err + } + + return factory.BatchCreateCRDs(ctx, crds...).BatchWait() +} + +func newCRD(obj interface{}, customize func(crd.CRD) crd.CRD) crd.CRD { + crd := crd.CRD{ + SchemaObject: obj, + } + if customize != nil { + crd = customize(crd) + } + return crd +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds_test.go new file mode 100644 index 0000000..d58ae3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/dashboard/crds_test.go @@ -0,0 +1,44 @@ +package dashboard + +import ( + "testing" + + "github.com/rancher/rancher/pkg/crds" + "github.com/rancher/rancher/pkg/features" + "github.com/stretchr/testify/require" +) + +func TestList(t *testing.T) { + // setting fleet to false so we can test with a nil cfg + features.Fleet.Set(false) + + originalMigrated := crds.MigratedResources + defer func() { + crds.MigratedResources = originalMigrated + }() + + crds.MigratedResources = nil + + result, err := List(nil) + require.NoError(t, err, "unexpected error while listing CRDs") + found := false + for _, crd := range result { + if crd.Name() == "clusters.management.cattle.io" { + found = true + break + } + } + require.Truef(t, found, "missing expected clusters CRD result=%v", result) + + // test that when the CRD is in the migrated list it does not get installed. + crds.MigratedResources = map[string]bool{"clusters.management.cattle.io": true} + + result, err = List(nil) + require.NoError(t, err, "unexpected error while listing CRDs") + + for _, crd := range result { + if crd.Name() == "clusters.management.cattle.io" { + require.FailNow(t, "clusters.management.cattle.io", "unexpected clusters CRD result") + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/management/crds.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/management/crds.go new file mode 100644 index 0000000..44f15ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/management/crds.go @@ -0,0 +1,43 @@ +package dashboard + +import ( + "context" + + "github.com/rancher/wrangler/v3/pkg/crd" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +func List() []crd.CRD { + return nil +} + +func Objects() (result []runtime.Object, err error) { + for _, crdDef := range List() { + crd, err := crdDef.ToCustomResourceDefinition() + if err != nil { + return nil, err + } + result = append(result, crd) + } + return +} + +func Create(ctx context.Context, cfg *rest.Config) error { + factory, err := crd.NewFactoryFromClient(cfg) + if err != nil { + return err + } + + return factory.BatchCreateCRDs(ctx, List()...).BatchWait() +} + +func newCRD(obj interface{}, customize func(crd.CRD) crd.CRD) crd.CRD { + crd := crd.CRD{ + SchemaObject: obj, + } + if customize != nil { + crd = customize(crd) + } + return crd +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/names.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/names.go new file mode 100644 index 0000000..39ade23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/names.go @@ -0,0 +1,296 @@ +package crds + +import "github.com/rancher/rancher/pkg/features" + +// RequiredCRDs returns a list of CRD to install based on enabled features. +func RequiredCRDs() []string { + requiredCRDS := BasicCRDs() + if features.ProvisioningV2.Enabled() { + requiredCRDS = append(requiredCRDS, ProvisioningV2CRDs()...) + if features.RKE2.Enabled() { + requiredCRDS = append(requiredCRDS, RKE2CRDs()...) + } + if features.EmbeddedClusterAPI.Enabled() { + requiredCRDS = append(requiredCRDS, CAPICRDs()...) + } + if features.Fleet.Enabled() { + requiredCRDS = append(requiredCRDS, "managedcharts.management.cattle.io") + } + } + if features.Fleet.Enabled() { + requiredCRDS = append(requiredCRDS, FleetCRDs()...) + } + if features.MCM.Enabled() { + requiredCRDS = append(requiredCRDS, MCMCRDs()...) + } + if features.Auth.Enabled() { + requiredCRDS = append(requiredCRDS, AuthCRDs()...) + } + if features.UIExtension.Enabled() { + requiredCRDS = append(requiredCRDS, UIPluginsCRD()...) + } + return requiredCRDS +} + +// BasicCRDs returns a list of CRD names needed to run rancher. +func BasicCRDs() []string { + return []string{ + "apps.catalog.cattle.io", + "clusterrepos.catalog.cattle.io", + "operations.catalog.cattle.io", + "apiservices.management.cattle.io", + "clusters.management.cattle.io", + "clusterregistrationtokens.management.cattle.io", + "features.management.cattle.io", + "podsecurityadmissionconfigurationtemplates.management.cattle.io", + "preferences.management.cattle.io", + "settings.management.cattle.io", + "navlinks.ui.cattle.io", + } +} + +// ProvisioningV2CRDs returns a list of CRD names needed for ProvisioningV2. +func ProvisioningV2CRDs() []string { + return []string{ + "clusters.provisioning.cattle.io", + } +} + +// CAPICRDs returns a list of CRD names needed for CAPI. +func CAPICRDs() []string { + return []string{ + "machines.cluster.x-k8s.io", + "machinehealthchecks.cluster.x-k8s.io", + "machinedeployments.cluster.x-k8s.io", + "machinesets.cluster.x-k8s.io", + "clusters.cluster.x-k8s.io", + } +} + +// RKE2CRDs returns a list of CRD names needed for RKE2. +func RKE2CRDs() []string { + return []string{ + "clusters.provisioning.cattle.io", + "custommachines.rke.cattle.io", + "etcdsnapshots.rke.cattle.io", + "rkebootstraps.rke.cattle.io", + "rkebootstraptemplates.rke.cattle.io", + "rkeclusters.rke.cattle.io", + "rkecontrolplanes.rke.cattle.io", + } +} + +// FleetCRDs returns a list of CRD names needed for Fleet. +func FleetCRDs() []string { + return append( + bootstrapFleet(), + "fleetworkspaces.management.cattle.io", + ) +} + +func bootstrapFleet() []string { + return []string{ + "bundles.fleet.cattle.io", + "clusters.fleet.cattle.io", + "clustergroups.fleet.cattle.io", + } +} + +// AuthCRDs returns a list of CRD names needed for authentication. +func AuthCRDs() []string { + return []string{ + "authconfigs.management.cattle.io", + "groups.management.cattle.io", + "groupmembers.management.cattle.io", + "tokens.management.cattle.io", + "users.management.cattle.io", + "userattributes.management.cattle.io", + "clusterproxyconfigs.management.cattle.io", + } +} + +// ClusterAuthCRDs returns a list of CRD names needed for ACE. +func ClusterAuthCRDs() []string { + return []string{ + "clusterauthtokens.cluster.cattle.io", + "clusteruserattributes.cluster.cattle.io", + } +} + +// MCMCRDs returns a list of CRD names needed for Multi CLuster Management. +func MCMCRDs() []string { + return []string{ + "authconfigs.management.cattle.io", + "catalogs.management.cattle.io", + "catalogtemplates.management.cattle.io", + "catalogtemplateversions.management.cattle.io", + "clusters.management.cattle.io", + "clusteralerts.management.cattle.io", + "clusteralertgroups.management.cattle.io", + "clusteralertrules.management.cattle.io", + "clustercatalogs.management.cattle.io", + "clustermonitorgraphs.management.cattle.io", + "clusterregistrationtokens.management.cattle.io", + "clusterroletemplatebindings.management.cattle.io", + "clustertemplates.management.cattle.io", + "clustertemplaterevisions.management.cattle.io", + "composeconfigs.management.cattle.io", + "dynamicschemas.management.cattle.io", + "etcdbackups.management.cattle.io", + "features.management.cattle.io", + "fleetworkspaces.management.cattle.io", + "globaldnss.management.cattle.io", + "globaldnsproviders.management.cattle.io", + "globalroles.management.cattle.io", + "globalrolebindings.management.cattle.io", + "groups.management.cattle.io", + "groupmembers.management.cattle.io", + "kontainerdrivers.management.cattle.io", + "monitormetrics.management.cattle.io", + "multiclusterapps.management.cattle.io", + "multiclusterapprevisions.management.cattle.io", + "nodes.management.cattle.io", + "nodedrivers.management.cattle.io", + "nodepools.management.cattle.io", + "nodetemplates.management.cattle.io", + "notifiers.management.cattle.io", + "podsecurityadmissionconfigurationtemplates.management.cattle.io", + "preferences.management.cattle.io", + "projects.management.cattle.io", + "projectalerts.management.cattle.io", + "projectalertgroups.management.cattle.io", + "projectalertrules.management.cattle.io", + "projectcatalogs.management.cattle.io", + "projectmonitorgraphs.management.cattle.io", + "projectnetworkpolicys.management.cattle.io", + "projectroletemplatebindings.management.cattle.io", + "rancherusernotificationtypes.management.cattle.io", + "rkeaddons.management.cattle.io", + "rkek8sserviceoptions.management.cattle.io", + "rkek8ssystemimages.management.cattle.io", + "roletemplates.management.cattle.io", + "samltokens.management.cattle.io", + "settings.management.cattle.io", + "templates.management.cattle.io", + "templatecontents.management.cattle.io", + "templateversions.management.cattle.io", + "tokens.management.cattle.io", + "users.management.cattle.io", + "userattributes.management.cattle.io", + } +} + +// UIPluginsCRD returns a list of CRD names needed to enable UIPlugins +func UIPluginsCRD() []string { + return []string{ + "uiplugins.catalog.cattle.io", + } +} + +// MigratedResources map list of resource that have been migrated after all resource have a CRD this can be removed. +var MigratedResources = map[string]bool{ + "activedirectoryproviders.management.cattle.io": false, + "apiservices.management.cattle.io": false, + "apprevisions.project.cattle.io": false, + "apps.catalog.cattle.io": false, + "apps.project.cattle.io": false, + "authconfigs.management.cattle.io": false, + "authproviders.management.cattle.io": false, + "authtokens.management.cattle.io": false, + "azureadproviders.management.cattle.io": false, + "basicauths.project.cattle.io": false, + "catalogs.management.cattle.io": false, + "catalogtemplates.management.cattle.io": false, + "catalogtemplateversions.management.cattle.io": false, + "certificates.project.cattle.io": false, + "cloudcredentials.management.cattle.io": false, + "clusteralertgroups.management.cattle.io": false, + "clusteralertrules.management.cattle.io": false, + "clusteralerts.management.cattle.io": false, + "clusterauthtokens.cluster.cattle.io": false, + "clusterclasses.cluster.x-k8s.io": false, + "clusterloggings.management.cattle.io": false, + "clustermonitorgraphs.management.cattle.io": false, + "clusterproxyconfigs.management.cattle.io": true, + "clusterregistrationtokens.management.cattle.io": false, + "clusterrepoes.catalog.cattle.io": false, + "clusterresourcesetbindings.addons.cluster.x-k8s.io": false, + "clusterroletemplatebindings.management.cattle.io": true, + "clusters.cluster.x-k8s.io": false, + "clusters.management.cattle.io": false, + "clusters.provisioning.cattle.io": false, + "clustertemplaterevisions.management.cattle.io": false, + "clustertemplates.management.cattle.io": false, + "clusteruserattributes.cluster.cattle.io": false, + "composeconfigs.management.cattle.io": false, + "custommachines.rke.cattle.io": false, + "dockercredentials.project.cattle.io": false, + "dynamicschemas.management.cattle.io": false, + "etcdbackups.management.cattle.io": false, + "etcdsnapshots.rke.cattle.io": false, + "extensionconfigs.runtime.cluster.x-k8s.io": false, + "features.management.cattle.io": false, + "fleetworkspaces.management.cattle.io": false, + "freeipaproviders.management.cattle.io": false, + "githubproviders.management.cattle.io": false, + "globaldns.management.cattle.io": false, + "globaldnsproviders.management.cattle.io": false, + "globalrolebindings.management.cattle.io": true, + "globalroles.management.cattle.io": true, + "googleoauthproviders.management.cattle.io": false, + "groupmembers.management.cattle.io": false, + "groups.management.cattle.io": false, + "ipaddressclaims.ipam.cluster.x-k8s.io": false, + "kontainerdrivers.management.cattle.io": false, + "localproviders.management.cattle.io": false, + "machinedeployments.cluster.x-k8s.io": false, + "machinepools.cluster.x-k8s.io": false, + "machines.cluster.x-k8s.io": false, + "machinesets.cluster.x-k8s.io": false, + "managedcharts.management.cattle.io": false, + "monitormetrics.management.cattle.io": false, + "multiclusterapprevisions.management.cattle.io": false, + "multiclusterapps.management.cattle.io": false, + "navlinks.ui.cattle.io": false, + "nodedrivers.management.cattle.io": false, + "nodepools.management.cattle.io": false, + "nodes.management.cattle.io": false, + "nodetemplates.management.cattle.io": false, + "notifiers.management.cattle.io": false, + "oidcproviders.management.cattle.io": false, + "openldapproviders.management.cattle.io": false, + "operations.catalog.cattle.io": false, + "podsecurityadmissionconfigurationtemplates.management.cattle.io": false, + "preferences.management.cattle.io": false, + "principals.management.cattle.io": false, + "projectalertgroups.management.cattle.io": false, + "projectalertrules.management.cattle.io": false, + "projectalerts.management.cattle.io": false, + "projectloggings.management.cattle.io": false, + "projectmonitorgraphs.management.cattle.io": false, + "projectnetworkpolicies.management.cattle.io": false, + "projectroletemplatebindings.management.cattle.io": true, + "projects.management.cattle.io": true, + "rancherusernotifications.management.cattle.io": false, + "rkeaddons.management.cattle.io": false, + "rkebootstraps.rke.cattle.io": false, + "rkebootstraptemplates.rke.cattle.io": false, + "rkeclusters.rke.cattle.io": false, + "rkecontrolplanes.rke.cattle.io": false, + "rkek8sserviceoptions.management.cattle.io": false, + "rkek8ssystemimages.management.cattle.io": false, + "roletemplates.management.cattle.io": true, + "samlproviders.management.cattle.io": false, + "samltokens.management.cattle.io": false, + "serviceaccounttokens.project.cattle.io": false, + "settings.management.cattle.io": false, + "sshauths.project.cattle.io": false, + "templatecontents.management.cattle.io": false, + "templates.management.cattle.io": false, + "templateversions.management.cattle.io": false, + "tokens.management.cattle.io": false, + "userattributes.management.cattle.io": false, + "users.management.cattle.io": false, + "uiplugins.catalog.cattle.io": true, + "workloads.project.cattle.io": false, +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-crds.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-crds.yaml new file mode 100644 index 0000000..acb2de7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-crds.yaml @@ -0,0 +1,11839 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterclasses.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterClass + listKind: ClusterClassList + plural: clusterclasses + shortNames: + - cc + singular: clusterclass + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Time duration since creation of ClusterClass + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterClass is a template which can be used to create managed topologies. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterClassSpec describes the desired state of the ClusterClass. + properties: + controlPlane: + description: |- + ControlPlane is a reference to a local struct that holds the details + for provisioning the Control Plane for the Cluster. + properties: + machineInfrastructure: + description: |- + MachineTemplate defines the metadata and infrastructure information + for control plane machines. + + + This field is supported if and only if the control plane provider template + referenced above is Machine based and supports setting replicas. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the machines of the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the topology. + + + This field is supported if and only if the control plane provider template + referenced is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure is a reference to a provider-specific template that holds + the details for provisioning infrastructure specific cluster + for the underlying provider. + The underlying provider is responsible for the implementation + of the template to an infrastructure cluster. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + workers: + description: |- + Workers describes the worker nodes for the cluster. + It is a collection of node types which can be used to create + the worker nodes of the cluster. + properties: + machineDeployments: + description: |- + MachineDeployments is a list of machine deployment classes that can be used to create + a set of worker nodes. + items: + description: |- + MachineDeploymentClass serves as a template to define a set of worker nodes of the cluster + provisioned using the `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of worker node present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachineDeployment. + type: string + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachineDeployment objects representing a set of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + type: object + type: object + type: object + served: false + storage: false + subresources: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterClass + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterClass is a template which can be used to create managed topologies. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterClassSpec describes the desired state of the ClusterClass. + properties: + controlPlane: + description: |- + ControlPlane is a reference to a local struct that holds the details + for provisioning the Control Plane for the Cluster. + properties: + machineHealthCheck: + description: |- + MachineHealthCheck defines a MachineHealthCheck for this ControlPlaneClass. + This field is supported if and only if the ControlPlane provider template + referenced above is Machine based and supports setting replicas. + properties: + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + machineInfrastructure: + description: |- + MachineInfrastructure defines the metadata and infrastructure information + for control plane machines. + + + This field is supported if and only if the control plane provider template + referenced above is Machine based and supports setting replicas. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane + if the ControlPlaneTemplate referenced is machine based. If not, it is applied only to the + ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the topology. + + + This field is supported if and only if the control plane provider template + referenced is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the control plane provider object. + properties: + template: + description: |- + Template defines the template to use for generating the name of the ControlPlane object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure is a reference to a provider-specific template that holds + the details for provisioning infrastructure specific cluster + for the underlying provider. + The underlying provider is responsible for the implementation + of the template to an infrastructure cluster. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + patches: + description: |- + Patches defines the patches which are applied to customize + referenced templates of a ClusterClass. + Note: Patches will be applied in the order of the array. + items: + description: ClusterClassPatch defines a patch which is applied to customize the referenced templates. + properties: + definitions: + description: |- + Definitions define inline patches. + Note: Patches will be applied in the order of the array. + Note: Exactly one of Definitions or External must be set. + items: + description: PatchDefinition defines a patch which is applied to customize the referenced templates. + properties: + jsonPatches: + description: |- + JSONPatches defines the patches which should be applied on the templates + matching the selector. + Note: Patches will be applied in the order of the array. + items: + description: JSONPatch defines a JSON patch. + properties: + op: + description: |- + Op defines the operation of the patch. + Note: Only `add`, `replace` and `remove` are supported. + type: string + path: + description: |- + Path defines the path of the patch. + Note: Only the spec of a template can be patched, thus the path has to start with /spec/. + Note: For now the only allowed array modifications are `append` and `prepend`, i.e.: + * for op: `add`: only index 0 (prepend) and - (append) are allowed + * for op: `replace` or `remove`: no indexes are allowed + type: string + value: + description: |- + Value defines the value of the patch. + Note: Either Value or ValueFrom is required for add and replace + operations. Only one of them is allowed to be set at the same time. + Note: We have to use apiextensionsv1.JSON instead of our JSON type, + because controller-tools has a hard-coded schema for apiextensionsv1.JSON + which cannot be produced by another type (unset type field). + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: |- + ValueFrom defines the value of the patch. + Note: Either Value or ValueFrom is required for add and replace + operations. Only one of them is allowed to be set at the same time. + properties: + template: + description: |- + Template is the Go template to be used to calculate the value. + A template can reference variables defined in .spec.variables and builtin variables. + Note: The template must evaluate to a valid YAML or JSON value. + type: string + variable: + description: |- + Variable is the variable to be used as value. + Variable can be one of the variables defined in .spec.variables or a builtin variable. + type: string + type: object + required: + - op + - path + type: object + type: array + selector: + description: Selector defines on which templates the patch should be applied. + properties: + apiVersion: + description: APIVersion filters templates by apiVersion. + type: string + kind: + description: Kind filters templates by kind. + type: string + matchResources: + description: MatchResources selects templates based on where they are referenced. + properties: + controlPlane: + description: |- + ControlPlane selects templates referenced in .spec.ControlPlane. + Note: this will match the controlPlane and also the controlPlane + machineInfrastructure (depending on the kind and apiVersion). + type: boolean + infrastructureCluster: + description: InfrastructureCluster selects templates referenced in .spec.infrastructure. + type: boolean + machineDeploymentClass: + description: |- + MachineDeploymentClass selects templates referenced in specific MachineDeploymentClasses in + .spec.workers.machineDeployments. + properties: + names: + description: Names selects templates by class names. + items: + type: string + type: array + type: object + machinePoolClass: + description: |- + MachinePoolClass selects templates referenced in specific MachinePoolClasses in + .spec.workers.machinePools. + properties: + names: + description: Names selects templates by class names. + items: + type: string + type: array + type: object + type: object + required: + - apiVersion + - kind + - matchResources + type: object + required: + - jsonPatches + - selector + type: object + type: array + description: + description: Description is a human-readable description of this patch. + type: string + enabledIf: + description: |- + EnabledIf is a Go template to be used to calculate if a patch should be enabled. + It can reference variables defined in .spec.variables and builtin variables. + The patch will be enabled if the template evaluates to `true`, otherwise it will + be disabled. + If EnabledIf is not set, the patch will be enabled per default. + type: string + external: + description: |- + External defines an external patch. + Note: Exactly one of Definitions or External must be set. + properties: + discoverVariablesExtension: + description: DiscoverVariablesExtension references an extension which is called to discover variables. + type: string + generateExtension: + description: GenerateExtension references an extension which is called to generate patches. + type: string + settings: + additionalProperties: + type: string + description: |- + Settings defines key value pairs to be passed to the extensions. + Values defined here take precedence over the values defined in the + corresponding ExtensionConfig. + type: object + validateExtension: + description: ValidateExtension references an extension which is called to validate the topology. + type: string + type: object + name: + description: Name of the patch. + type: string + required: + - name + type: object + type: array + variables: + description: |- + Variables defines the variables which can be configured + in the Cluster topology and are then used in patches. + items: + description: |- + ClusterClassVariable defines a variable which can + be configured in the Cluster topology and used in patches. + properties: + metadata: + description: |- + Metadata is the metadata of a variable. + It can be used to add additional data for higher level tools to + a ClusterClassVariable. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map that can be used to store and + retrieve arbitrary metadata. + They are not queryable. + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) variables. + type: object + type: object + name: + description: Name of the variable. + type: string + required: + description: |- + Required specifies if the variable is required. + Note: this applies to the variable as a whole and thus the + top-level object defined in the schema. If nested fields are + required, this will be specified inside the schema. + type: boolean + schema: + description: Schema defines the schema of the variable. + properties: + openAPIV3Schema: + description: |- + OpenAPIV3Schema defines the schema of a variable via OpenAPI v3 + schema. The schema is a subset of the schema used in + Kubernetes CRDs. + properties: + additionalProperties: + description: |- + AdditionalProperties specifies the schema of values in a map (keys are always strings). + NOTE: Can only be set if type is object. + NOTE: AdditionalProperties is mutually exclusive with Properties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + default: + description: |- + Default is the default value of the variable. + NOTE: Can be set for all types. + x-kubernetes-preserve-unknown-fields: true + description: + description: Description is a human-readable description of this variable. + type: string + enum: + description: |- + Enum is the list of valid values of the variable. + NOTE: Can be set for all types. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + example: + description: Example is an example for this variable. + x-kubernetes-preserve-unknown-fields: true + exclusiveMaximum: + description: |- + ExclusiveMaximum specifies if the Maximum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + exclusiveMinimum: + description: |- + ExclusiveMinimum specifies if the Minimum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + format: + description: |- + Format is an OpenAPI v3 format string. Unknown formats are ignored. + For a list of supported formats please see: (of the k8s.io/apiextensions-apiserver version we're currently using) + https://github.com/kubernetes/apiextensions-apiserver/blob/master/pkg/apiserver/validation/formats.go + NOTE: Can only be set if type is string. + type: string + items: + description: |- + Items specifies fields of an array. + NOTE: Can only be set if type is array. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + maxItems: + description: |- + MaxItems is the max length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + maxLength: + description: |- + MaxLength is the max length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + maximum: + description: |- + Maximum is the maximum of an integer or number variable. + If ExclusiveMaximum is false, the variable is valid if it is lower than, or equal to, the value of Maximum. + If ExclusiveMaximum is true, the variable is valid if it is strictly lower than the value of Maximum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + minItems: + description: |- + MinItems is the min length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + minLength: + description: |- + MinLength is the min length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + minimum: + description: |- + Minimum is the minimum of an integer or number variable. + If ExclusiveMinimum is false, the variable is valid if it is greater than, or equal to, the value of Minimum. + If ExclusiveMinimum is true, the variable is valid if it is strictly greater than the value of Minimum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + pattern: + description: |- + Pattern is the regex which a string variable must match. + NOTE: Can only be set if type is string. + type: string + properties: + description: |- + Properties specifies fields of an object. + NOTE: Can only be set if type is object. + NOTE: Properties is mutually exclusive with AdditionalProperties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + required: + description: |- + Required specifies which fields of an object are required. + NOTE: Can only be set if type is object. + items: + type: string + type: array + type: + description: |- + Type is the type of the variable. + Valid values are: object, array, string, integer, number or boolean. + type: string + uniqueItems: + description: |- + UniqueItems specifies if items in an array must be unique. + NOTE: Can only be set if type is array. + type: boolean + x-kubernetes-preserve-unknown-fields: + description: |- + XPreserveUnknownFields allows setting fields in a variable object + which are not defined in the variable schema. This affects fields recursively, + except if nested properties or additionalProperties are specified in the schema. + type: boolean + required: + - type + type: object + required: + - openAPIV3Schema + type: object + required: + - name + - required + - schema + type: object + type: array + workers: + description: |- + Workers describes the worker nodes for the cluster. + It is a collection of node types which can be used to create + the worker nodes of the cluster. + properties: + machineDeployments: + description: |- + MachineDeployments is a list of machine deployment classes that can be used to create + a set of worker nodes. + items: + description: |- + MachineDeploymentClass serves as a template to define a set of worker nodes of the cluster + provisioned using the `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of worker node present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachineDeployment. + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machines will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + machineHealthCheck: + description: MachineHealthCheck defines a MachineHealthCheck for this MachineDeploymentClass. + properties: + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + format: int32 + type: integer + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the MachineDeployment. + properties: + template: + description: |- + Template defines the template to use for generating the name of the MachineDeployment object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .machineDeployment.topologyName }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + * `.machineDeployment.topologyName`: The name of the MachineDeployment topology (Cluster.spec.topology.workers.machineDeployments[].name). + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachineDeployment objects representing a set of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + machinePools: + description: |- + MachinePools is a list of machine pool classes that can be used to create + a set of worker nodes. + items: + description: |- + MachinePoolClass serves as a template to define a pool of worker nodes of the cluster + provisioned using `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of machine pool present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachinePool. + type: string + failureDomains: + description: |- + FailureDomains is the list of failure domains the MachinePool should be attached to. + Must match a key in the FailureDomains map stored on the cluster object. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine pool should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + format: int32 + type: integer + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the MachinePool. + properties: + template: + description: |- + Template defines the template to use for generating the name of the MachinePool object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .machinePool.topologyName }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + * `.machinePool.topologyName`: The name of the MachinePool topology (Cluster.spec.topology.workers.machinePools[].name). + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine Pool is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachinePools objects representing a pool of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of the Machines in the MachinePool. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of the MachinePool. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachinePool. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + type: object + type: object + status: + description: ClusterClassStatus defines the observed state of the ClusterClass. + properties: + conditions: + description: Conditions defines current observed state of the ClusterClass. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + variables: + description: Variables is a list of ClusterClassStatusVariable that are defined for the ClusterClass. + items: + description: ClusterClassStatusVariable defines a variable which appears in the status of a ClusterClass. + properties: + definitions: + description: Definitions is a list of definitions for a variable. + items: + description: ClusterClassStatusVariableDefinition defines a variable which appears in the status of a ClusterClass. + properties: + from: + description: |- + From specifies the origin of the variable definition. + This will be `inline` for variables defined in the ClusterClass or the name of a patch defined in the ClusterClass + for variables discovered from a DiscoverVariables runtime extensions. + type: string + metadata: + description: |- + Metadata is the metadata of a variable. + It can be used to add additional data for higher level tools to + a ClusterClassVariable. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map that can be used to store and + retrieve arbitrary metadata. + They are not queryable. + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) variables. + type: object + type: object + required: + description: |- + Required specifies if the variable is required. + Note: this applies to the variable as a whole and thus the + top-level object defined in the schema. If nested fields are + required, this will be specified inside the schema. + type: boolean + schema: + description: Schema defines the schema of the variable. + properties: + openAPIV3Schema: + description: |- + OpenAPIV3Schema defines the schema of a variable via OpenAPI v3 + schema. The schema is a subset of the schema used in + Kubernetes CRDs. + properties: + additionalProperties: + description: |- + AdditionalProperties specifies the schema of values in a map (keys are always strings). + NOTE: Can only be set if type is object. + NOTE: AdditionalProperties is mutually exclusive with Properties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + default: + description: |- + Default is the default value of the variable. + NOTE: Can be set for all types. + x-kubernetes-preserve-unknown-fields: true + description: + description: Description is a human-readable description of this variable. + type: string + enum: + description: |- + Enum is the list of valid values of the variable. + NOTE: Can be set for all types. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + example: + description: Example is an example for this variable. + x-kubernetes-preserve-unknown-fields: true + exclusiveMaximum: + description: |- + ExclusiveMaximum specifies if the Maximum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + exclusiveMinimum: + description: |- + ExclusiveMinimum specifies if the Minimum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + format: + description: |- + Format is an OpenAPI v3 format string. Unknown formats are ignored. + For a list of supported formats please see: (of the k8s.io/apiextensions-apiserver version we're currently using) + https://github.com/kubernetes/apiextensions-apiserver/blob/master/pkg/apiserver/validation/formats.go + NOTE: Can only be set if type is string. + type: string + items: + description: |- + Items specifies fields of an array. + NOTE: Can only be set if type is array. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + maxItems: + description: |- + MaxItems is the max length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + maxLength: + description: |- + MaxLength is the max length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + maximum: + description: |- + Maximum is the maximum of an integer or number variable. + If ExclusiveMaximum is false, the variable is valid if it is lower than, or equal to, the value of Maximum. + If ExclusiveMaximum is true, the variable is valid if it is strictly lower than the value of Maximum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + minItems: + description: |- + MinItems is the min length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + minLength: + description: |- + MinLength is the min length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + minimum: + description: |- + Minimum is the minimum of an integer or number variable. + If ExclusiveMinimum is false, the variable is valid if it is greater than, or equal to, the value of Minimum. + If ExclusiveMinimum is true, the variable is valid if it is strictly greater than the value of Minimum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + pattern: + description: |- + Pattern is the regex which a string variable must match. + NOTE: Can only be set if type is string. + type: string + properties: + description: |- + Properties specifies fields of an object. + NOTE: Can only be set if type is object. + NOTE: Properties is mutually exclusive with AdditionalProperties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + required: + description: |- + Required specifies which fields of an object are required. + NOTE: Can only be set if type is object. + items: + type: string + type: array + type: + description: |- + Type is the type of the variable. + Valid values are: object, array, string, integer, number or boolean. + type: string + uniqueItems: + description: |- + UniqueItems specifies if items in an array must be unique. + NOTE: Can only be set if type is array. + type: boolean + x-kubernetes-preserve-unknown-fields: + description: |- + XPreserveUnknownFields allows setting fields in a variable object + which are not defined in the variable schema. This affects fields recursively, + except if nested properties or additionalProperties are specified in the schema. + type: boolean + required: + - type + type: object + required: + - openAPIV3Schema + type: object + required: + - from + - required + - schema + type: object + type: array + definitionsConflict: + description: DefinitionsConflict specifies whether or not there are conflicting definitions for a single variable name. + type: boolean + name: + description: Name is the name of the variable. + type: string + required: + - definitions + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterresourcesetbindings.addons.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: addons.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterResourceSetBinding + listKind: ClusterResourceSetBindingList + plural: clusterresourcesetbindings + singular: clusterresourcesetbinding + scope: Namespaced + versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSetBinding + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSetBinding + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + clusterName: + description: |- + ClusterName is the name of the Cluster this binding applies to. + Note: this field mandatory in v1beta2. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterresourcesets.addons.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: addons.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterResourceSet + listKind: ClusterResourceSetList + plural: clusterresourcesets + singular: clusterresourceset + scope: Namespaced + versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSet is the Schema for the clusterresourcesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSet is the Schema for the clusterresourcesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + Label selector cannot be empty. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterResourceSet is the Schema for the clusterresourcesets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + Label selector cannot be empty. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + - Reconcile + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusters.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: Cluster + listKind: ClusterList + plural: clusters + shortNames: + - cl + singular: cluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + controlPlaneInitialized: + description: ControlPlaneInitialized defines if the control plane has been initialized. + type: boolean + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + Cluster is the Schema for the clusters API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + topology: + description: |- + This encapsulates the topology for the cluster. + NOTE: It is required to enable the ClusterTopology + feature gate flag to activate managed topologies support; + this feature is highly experimental, and parts of it might still be not implemented. + properties: + class: + description: The name of the ClusterClass object to create the topology. + type: string + controlPlane: + description: ControlPlane describes the cluster control plane. + properties: + metadata: + description: |- + Metadata is the metadata applied to the machines of the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + + + This field is supported if and only if the control plane provider template + referenced in the ClusterClass is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + replicas: + description: |- + Replicas is the number of control plane nodes. + If the value is nil, the ControlPlane object is created without the number of Replicas + and it's assumed that the control plane controller does not implement support for this field. + When specified against a control plane provider that lacks support for this field, this value will be ignored. + format: int32 + type: integer + type: object + rolloutAfter: + description: |- + RolloutAfter performs a rollout of the entire cluster one component at a time, + control plane first and then machine deployments. + format: date-time + type: string + version: + description: The Kubernetes version of the cluster. + type: string + workers: + description: |- + Workers encapsulates the different constructs that form the worker nodes + for the cluster. + properties: + machineDeployments: + description: MachineDeployments is a list of machine deployments in the cluster. + items: + description: |- + MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology. + This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachineDeploymentClass used to create the set of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + metadata: + description: |- + Metadata is the metadata applied to the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + name: + description: |- + Name is the unique identifier for this MachineDeploymentTopology. + The value is used with other unique identifiers to create a MachineDeployment's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + replicas: + description: |- + Replicas is the number of worker nodes belonging to this set. + If the value is nil, the MachineDeployment is created without the number of Replicas (defaulting to zero) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + required: + - class + - name + type: object + type: array + type: object + required: + - class + - version + type: object + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: ClusterClass of this Cluster, empty if the Cluster is not using a ClusterClass + jsonPath: .spec.topology.class + name: ClusterClass + type: string + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this Cluster + jsonPath: .spec.topology.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + topology: + description: |- + This encapsulates the topology for the cluster. + NOTE: It is required to enable the ClusterTopology + feature gate flag to activate managed topologies support; + this feature is highly experimental, and parts of it might still be not implemented. + properties: + class: + description: The name of the ClusterClass object to create the topology. + type: string + controlPlane: + description: ControlPlane describes the cluster control plane. + properties: + machineHealthCheck: + description: |- + MachineHealthCheck allows to enable, disable and override + the MachineHealthCheck configuration in the ClusterClass for this control plane. + properties: + enable: + description: |- + Enable controls if a MachineHealthCheck should be created for the target machines. + + + If false: No MachineHealthCheck will be created. + + + If not set(default): A MachineHealthCheck will be created if it is defined here or + in the associated ClusterClass. If no MachineHealthCheck is defined then none will be created. + + + If true: A MachineHealthCheck is guaranteed to be created. Cluster validation will + block if `enable` is true and no MachineHealthCheck definition is available. + type: boolean + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + metadata: + description: |- + Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane + if the ControlPlaneTemplate referenced by the ClusterClass is machine based. If not, it + is applied only to the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of control plane nodes. + If the value is nil, the ControlPlane object is created without the number of Replicas + and it's assumed that the control plane controller does not implement support for this field. + When specified against a control plane provider that lacks support for this field, this value will be ignored. + format: int32 + type: integer + variables: + description: Variables can be used to customize the ControlPlane through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + type: object + rolloutAfter: + description: |- + RolloutAfter performs a rollout of the entire cluster one component at a time, + control plane first and then machine deployments. + + + Deprecated: This field has no function and is going to be removed in the next apiVersion. + format: date-time + type: string + variables: + description: |- + Variables can be used to customize the Cluster through + patches. They must comply to the corresponding + VariableClasses defined in the ClusterClass. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + version: + description: The Kubernetes version of the cluster. + type: string + workers: + description: |- + Workers encapsulates the different constructs that form the worker nodes + for the cluster. + properties: + machineDeployments: + description: MachineDeployments is a list of machine deployments in the cluster. + items: + description: |- + MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology. + This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachineDeploymentClass used to create the set of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machines will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + machineHealthCheck: + description: |- + MachineHealthCheck allows to enable, disable and override + the MachineHealthCheck configuration in the ClusterClass for this MachineDeployment. + properties: + enable: + description: |- + Enable controls if a MachineHealthCheck should be created for the target machines. + + + If false: No MachineHealthCheck will be created. + + + If not set(default): A MachineHealthCheck will be created if it is defined here or + in the associated ClusterClass. If no MachineHealthCheck is defined then none will be created. + + + If true: A MachineHealthCheck is guaranteed to be created. Cluster validation will + block if `enable` is true and no MachineHealthCheck definition is available. + type: boolean + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this MachineDeploymentTopology. + The value is used with other unique identifiers to create a MachineDeployment's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of worker nodes belonging to this set. + If the value is nil, the MachineDeployment is created without the number of Replicas (defaulting to 1) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + variables: + description: Variables can be used to customize the MachineDeployment through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + required: + - class + - name + type: object + type: array + machinePools: + description: MachinePools is a list of machine pools in the cluster. + items: + description: |- + MachinePoolTopology specifies the different parameters for a pool of worker nodes in the topology. + This pool of nodes is managed by a MachinePool object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachinePoolClass used to create the pool of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + failureDomains: + description: |- + FailureDomains is the list of failure domains the machine pool will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + items: + type: string + type: array + metadata: + description: |- + Metadata is the metadata applied to the MachinePool. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine pool should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this MachinePoolTopology. + The value is used with other unique identifiers to create a MachinePool's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the MachinePool + hosts after the MachinePool is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of nodes belonging to this pool. + If the value is nil, the MachinePool is created without the number of Replicas (defaulting to 1) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + variables: + description: Variables can be used to customize the MachinePool through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + required: + - class + - name + type: object + type: array + type: object + required: + - class + - version + type: object + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: extensionconfigs.runtime.cluster.x-k8s.io +spec: + group: runtime.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ExtensionConfig + listKind: ExtensionConfigList + plural: extensionconfigs + shortNames: + - ext + singular: extensionconfig + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Time duration since creation of ExtensionConfig + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ExtensionConfig is the Schema for the ExtensionConfig API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ExtensionConfigSpec is the desired state of the ExtensionConfig + properties: + clientConfig: + description: ClientConfig defines how to communicate with the Extension server. + properties: + caBundle: + description: CABundle is a PEM encoded CA bundle which will be used to validate the Extension server's server certificate. + format: byte + type: string + service: + description: |- + Service is a reference to the Kubernetes service for the Extension server. + Note: Exactly one of `url` or `service` must be specified. + + + If the Extension server is running within a cluster, then you should use `service`. + properties: + name: + description: Name is the name of the service. + type: string + namespace: + description: Namespace is the namespace of the service. + type: string + path: + description: |- + Path is an optional URL path and if present may be any string permissible in + a URL. If a path is set it will be used as prefix to the hook-specific path. + type: string + port: + description: |- + Port is the port on the service that's hosting the Extension server. + Defaults to 443. + Port should be a valid port number (1-65535, inclusive). + format: int32 + type: integer + required: + - name + - namespace + type: object + url: + description: |- + URL gives the location of the Extension server, in standard URL form + (`scheme://host:port/path`). + Note: Exactly one of `url` or `service` must be specified. + + + The scheme must be "https". + + + The `host` should not refer to a service running in the cluster; use + the `service` field instead. + + + A path is optional, and if present may be any string permissible in + a URL. If a path is set it will be used as prefix to the hook-specific path. + + + Attempting to use a user or basic auth e.g. "user:password@" is not + allowed. Fragments ("#...") and query parameters ("?...") are not + allowed either. + type: string + type: object + namespaceSelector: + description: |- + NamespaceSelector decides whether to call the hook for an object based + on whether the namespace for that object matches the selector. + Defaults to the empty LabelSelector, which matches all objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + settings: + additionalProperties: + type: string + description: |- + Settings defines key value pairs to be passed to all calls + to all supported RuntimeExtensions. + Note: Settings can be overridden on the ClusterClass. + type: object + required: + - clientConfig + type: object + status: + description: ExtensionConfigStatus is the current state of the ExtensionConfig + properties: + conditions: + description: Conditions define the current service state of the ExtensionConfig. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + handlers: + description: Handlers defines the current ExtensionHandlers supported by an Extension. + items: + description: ExtensionHandler specifies the details of a handler for a particular runtime hook registered by an Extension server. + properties: + failurePolicy: + description: |- + FailurePolicy defines how failures in calls to the ExtensionHandler should be handled by a client. + Defaults to Fail if not set. + type: string + name: + description: Name is the unique name of the ExtensionHandler. + type: string + requestHook: + description: RequestHook defines the versioned runtime hook which this ExtensionHandler serves. + properties: + apiVersion: + description: APIVersion is the group and version of the Hook. + type: string + hook: + description: Hook is the name of the hook. + type: string + required: + - apiVersion + - hook + type: object + timeoutSeconds: + description: |- + TimeoutSeconds defines the timeout duration for client calls to the ExtensionHandler. + Defaults to 10 is not set. + format: int32 + type: integer + required: + - name + - requestHook + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: ipaddressclaims.ipam.cluster.x-k8s.io +spec: + group: ipam.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: IPAddressClaim + listKind: IPAddressClaimList + plural: ipaddressclaims + singular: ipaddressclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Name of the pool to allocate an address from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool to allocate an address from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdressClaim + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IPAddressClaim is the Schema for the ipaddressclaim API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressClaimSpec is the desired state of an IPAddressClaim. + properties: + poolRef: + description: PoolRef is a reference to the pool from which an IP address should be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - poolRef + type: object + status: + description: IPAddressClaimStatus is the observed status of a IPAddressClaim. + properties: + addressRef: + description: AddressRef is a reference to the address that was created for this claim. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + description: Conditions summarises the current state of the IPAddressClaim + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Name of the pool to allocate an address from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool to allocate an address from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdressClaim + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: IPAddressClaim is the Schema for the ipaddressclaim API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressClaimSpec is the desired state of an IPAddressClaim. + properties: + poolRef: + description: PoolRef is a reference to the pool from which an IP address should be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - poolRef + type: object + status: + description: IPAddressClaimStatus is the observed status of a IPAddressClaim. + properties: + addressRef: + description: AddressRef is a reference to the address that was created for this claim. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + description: Conditions summarises the current state of the IPAddressClaim + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: ipaddresses.ipam.cluster.x-k8s.io +spec: + group: ipam.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: IPAddress + listKind: IPAddressList + plural: ipaddresses + singular: ipaddress + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Address + jsonPath: .spec.address + name: Address + type: string + - description: Name of the pool the address is from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool the address is from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdress + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IPAddress is the Schema for the ipaddress API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressSpec is the desired state of an IPAddress. + properties: + address: + description: Address is the IP address. + type: string + claimRef: + description: ClaimRef is a reference to the claim this IPAddress was created for. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + gateway: + description: Gateway is the network gateway of the network the address is from. + type: string + poolRef: + description: PoolRef is a reference to the pool that this IPAddress was created from. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + prefix: + description: Prefix is the prefix of the address. + type: integer + required: + - address + - claimRef + - poolRef + - prefix + type: object + type: object + served: true + storage: false + subresources: {} + - additionalPrinterColumns: + - description: Address + jsonPath: .spec.address + name: Address + type: string + - description: Name of the pool the address is from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool the address is from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdress + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: IPAddress is the Schema for the ipaddress API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressSpec is the desired state of an IPAddress. + properties: + address: + description: Address is the IP address. + type: string + claimRef: + description: ClaimRef is a reference to the claim this IPAddress was created for. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + gateway: + description: Gateway is the network gateway of the network the address is from. + type: string + poolRef: + description: PoolRef is a reference to the pool that this IPAddress was created from. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + prefix: + description: Prefix is the prefix of the address. + type: integer + required: + - address + - claimRef + - poolRef + - prefix + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinedeployments.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineDeployment + listKind: MachineDeploymentList + plural: machinedeployments + shortNames: + - md + singular: machinedeployment + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineDeployment is the Schema for the machinedeployments API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Currently the only supported strategy is + "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineDeployment + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineDeployment is the Schema for the machinedeployments API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + default: 1 + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. + Default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineDeployment. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this MachineDeployment + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of MachineDeployment + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachineDeployment + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineDeployment is the Schema for the machinedeployments API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. + Defaults to 0 (machine will be considered available as soon as the Node is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + description: |- + Number of desired machines. + This is a pointer to distinguish between explicit zero and not specified. + + + Defaults to: + * if the Kubernetes autoscaler min size and max size annotations are set: + - if it's a new MachineDeployment, use min size + - if the replicas field of the old MachineDeployment is < min size, use min size + - if the replicas field of the old MachineDeployment is > max size, use max size + - if the replicas field of the old MachineDeployment is in the (min size, max size) range, keep the value from the oldMD + * otherwise use 1 + Note: Defaulting will be run whenever the replicas field is not set: + * A new MachineDeployment is created with replicas not set. + * On an existing MachineDeployment the replicas field was first set and is now unset. + Those cases are especially relevant for the following Kubernetes autoscaler use cases: + * A new MachineDeployment is created and replicas should be managed by the autoscaler + * An existing MachineDeployment which initially wasn't controlled by the autoscaler + should be later controlled by the autoscaler + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + rolloutAfter: + description: |- + RolloutAfter is a field to indicate a rollout should be performed + after the specified time even if no changes have been made to the + MachineDeployment. + Example: In the YAML the time can be specified in the RFC3339 format. + To specify the rolloutAfter target as March 9, 2023, at 9 am UTC + use "2023-03-09T09:00:00Z". + format: date-time + type: string + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineDeployment. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinehealthchecks.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineHealthCheck + listKind: MachineHealthCheckList + plural: machinehealthchecks + shortNames: + - mhc + - mhcs + singular: machinehealthcheck + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineHealthCheck is the Schema for the machinehealthchecks API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineHealthCheck + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineHealthCheck is the Schema for the machinehealthchecks API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If not set, this value is defaulted to 10 minutes. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + - description: Time duration since creation of MachineHealthCheck + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineHealthCheck is the Schema for the machinehealthchecks API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If not set, this value is defaulted to 10 minutes. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinepools.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachinePool + listKind: MachinePoolList + plural: machinepools + shortNames: + - mp + singular: machinepool + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachinePool is the Schema for the machinepools API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + strategy: + description: |- + The deployment strategy to use to replace existing machine instances with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Currently the only supported strategy is + "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of MachinePool + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachinePool is the Schema for the machinepools API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this MachinePool + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of MachinePool + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachinePool is the Schema for the machinepools API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + NOTE: No logic is implemented for this field and it currently has no behaviour. + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machines.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: Machine + listKind: MachineList + plural: machines + shortNames: + - ma + singular: machine + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + priority: 1 + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + Machine is the Schema for the machines API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + version: + description: |- + Version specifies the current version of Kubernetes running + on the corresponding Node. This is meant to be a means of bubbling + up status from the Node to the Machine. + It is entirely optional, but useful for end-user UX if it’s present. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of Machine + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + priority: 1 + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + Machine is the Schema for the machines API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeInfo: + description: |- + NodeInfo is a set of ids/uuids to uniquely identify the node. + More info: https://kubernetes.io/docs/concepts/nodes/node/#info + properties: + architecture: + description: The Architecture reported by the node + type: string + bootID: + description: Boot ID reported by the node. + type: string + containerRuntimeVersion: + description: ContainerRuntime Version reported by the node through runtime remote API (e.g. containerd://1.4.2). + type: string + kernelVersion: + description: Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64). + type: string + kubeProxyVersion: + description: KubeProxy Version reported by the node. + type: string + kubeletVersion: + description: Kubelet Version reported by the node. + type: string + machineID: + description: |- + MachineID reported by the node. For unique machine identification + in the cluster this field is preferred. Learn more from man(5) + machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html + type: string + operatingSystem: + description: The Operating System reported by the node + type: string + osImage: + description: OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)). + type: string + systemUUID: + description: |- + SystemUUID reported by the node. For unique machine identification + MachineID is preferred. This field is specific to Red Hat hosts + https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid + type: string + required: + - architecture + - bootID + - containerRuntimeVersion + - kernelVersion + - kubeProxyVersion + - kubeletVersion + - machineID + - operatingSystem + - osImage + - systemUUID + type: object + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + version: + description: |- + Version specifies the current version of Kubernetes running + on the corresponding Node. This is meant to be a means of bubbling + up status from the Node to the Machine. + It is entirely optional, but useful for end-user UX if it’s present. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + type: string + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of Machine + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Machine is the Schema for the machines API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP, InternalIP, ExternalDNS or InternalDNS. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + certificatesExpiryDate: + description: |- + CertificatesExpiryDate is the expiry date of the machine certificates. + This value is only set for control plane machines. + format: date-time + type: string + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeInfo: + description: |- + NodeInfo is a set of ids/uuids to uniquely identify the node. + More info: https://kubernetes.io/docs/concepts/nodes/node/#info + properties: + architecture: + description: The Architecture reported by the node + type: string + bootID: + description: Boot ID reported by the node. + type: string + containerRuntimeVersion: + description: ContainerRuntime Version reported by the node through runtime remote API (e.g. containerd://1.4.2). + type: string + kernelVersion: + description: Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64). + type: string + kubeProxyVersion: + description: KubeProxy Version reported by the node. + type: string + kubeletVersion: + description: Kubelet Version reported by the node. + type: string + machineID: + description: |- + MachineID reported by the node. For unique machine identification + in the cluster this field is preferred. Learn more from man(5) + machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html + type: string + operatingSystem: + description: The Operating System reported by the node + type: string + osImage: + description: OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)). + type: string + systemUUID: + description: |- + SystemUUID reported by the node. For unique machine identification + MachineID is preferred. This field is specific to Red Hat hosts + https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid + type: string + required: + - architecture + - bootID + - containerRuntimeVersion + - kernelVersion + - kubeProxyVersion + - kubeletVersion + - machineID + - operatingSystem + - osImage + - systemUUID + type: object + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinesets.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineSet + listKind: MachineSetList + plural: machinesets + shortNames: + - ms + singular: machineset + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineSet is the Schema for the machinesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready. + Defaults to 0 (machine will be considered available as soon as it is ready) + format: int32 + type: integer + replicas: + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineSet is the Schema for the machinesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready. + Defaults to 0 (machine will be considered available as soon as it is ready) + format: int32 + type: integer + replicas: + default: 1 + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this machineset + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Time duration since creation of MachineSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachineSet + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineSet is the Schema for the machinesets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. + Defaults to 0 (machine will be considered available as soon as the Node is ready) + format: int32 + type: integer + replicas: + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + + + Defaults to: + * if the Kubernetes autoscaler min size and max size annotations are set: + - if it's a new MachineSet, use min size + - if the replicas field of the old MachineSet is < min size, use min size + - if the replicas field of the old MachineSet is > max size, use max size + - if the replicas field of the old MachineSet is in the (min size, max size) range, keep the value from the oldMS + * otherwise use 1 + Note: Defaulting will be run whenever the replicas field is not set: + * A new MachineSet is created with replicas not set. + * On an existing MachineSet the replicas field was first set and is now unset. + Those cases are especially relevant for the following Kubernetes autoscaler use cases: + * A new MachineSet is created and replicas should be managed by the autoscaler + * An existing MachineSet which initially wasn't controlled by the autoscaler + should be later controlled by the autoscaler + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-webhooks.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-webhooks.yaml new file mode 100644 index 0000000..dc7d124 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/capi-webhooks.yaml @@ -0,0 +1,480 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-cluster + failurePolicy: Fail + matchPolicy: Equivalent + name: default.cluster.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - clusters + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-clusterclass + failurePolicy: Fail + matchPolicy: Equivalent + name: default.clusterclass.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - clusterclasses + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-machine + failurePolicy: Fail + matchPolicy: Equivalent + name: default.machine.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machines + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-machinedeployment + failurePolicy: Fail + matchPolicy: Equivalent + name: default.machinedeployment.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinedeployments + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-machinehealthcheck + failurePolicy: Fail + matchPolicy: Equivalent + name: default.machinehealthcheck.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinehealthchecks + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-machineset + failurePolicy: Fail + matchPolicy: Equivalent + name: default.machineset.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinesets + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-runtime-cluster-x-k8s-io-v1alpha1-extensionconfig + failurePolicy: Fail + matchPolicy: Equivalent + name: default.extensionconfig.runtime.addons.cluster.x-k8s.io + rules: + - apiGroups: + - runtime.cluster.x-k8s.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - extensionconfigs + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-cluster-x-k8s-io-v1beta1-machinepool + failurePolicy: Fail + matchPolicy: Equivalent + name: default.machinepool.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinepools + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /mutate-addons-cluster-x-k8s-io-v1beta1-clusterresourceset + failurePolicy: Fail + matchPolicy: Equivalent + name: default.clusterresourceset.addons.cluster.x-k8s.io + rules: + - apiGroups: + - addons.cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - clusterresourcesets + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: validating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-cluster + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.cluster.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - clusters + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-clusterclass + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.clusterclass.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - clusterclasses + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-machine + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.machine.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machines + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-machinedeployment + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.machinedeployment.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinedeployments + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-machinehealthcheck + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.machinehealthcheck.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinehealthchecks + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-machineset + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.machineset.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinesets + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-runtime-cluster-x-k8s-io-v1alpha1-extensionconfig + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.extensionconfig.runtime.cluster.x-k8s.io + rules: + - apiGroups: + - runtime.cluster.x-k8s.io + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - extensionconfigs + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-cluster-x-k8s-io-v1beta1-machinepool + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.machinepool.cluster.x-k8s.io + rules: + - apiGroups: + - cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - machinepools + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-addons-cluster-x-k8s-io-v1beta1-clusterresourceset + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.clusterresourceset.addons.cluster.x-k8s.io + rules: + - apiGroups: + - addons.cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - clusterresourcesets + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-addons-cluster-x-k8s-io-v1beta1-clusterresourcesetbinding + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.clusterresourcesetbinding.addons.cluster.x-k8s.io + rules: + - apiGroups: + - addons.cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - clusterresourcesetbindings + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-ipam-cluster-x-k8s-io-v1beta1-ipaddress + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.ipaddress.ipam.cluster.x-k8s.io + rules: + - apiGroups: + - ipam.cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - ipaddresses + sideEffects: None + - admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /validate-ipam-cluster-x-k8s-io-v1beta1-ipaddressclaim + failurePolicy: Fail + matchPolicy: Equivalent + name: validation.ipaddressclaim.ipam.cluster.x-k8s.io + rules: + - apiGroups: + - ipam.cluster.x-k8s.io + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - ipaddressclaims + sideEffects: None diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/crds.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/crds.go new file mode 100644 index 0000000..d50c597 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/provisioningv2/crds.go @@ -0,0 +1,200 @@ +package provisioningv2 + +import ( + "embed" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/yaml" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + capiCRDs = map[string]bool{ + "Machine": true, + "MachineHealthCheck": true, + "MachineDeployment": true, + "MachineSet": true, + "Cluster": true, + } + + //go:embed capi-crds.yaml capi-webhooks.yaml + capiData embed.FS +) + +func List() (result []crd.CRD) { + result = append(result, provisioning()...) + if features.RKE2.Enabled() { + result = append(result, rke2()...) + } + if features.EmbeddedClusterAPI.Enabled() { + result = append(result, capi()...) + } + return +} + +func provisioning() []crd.CRD { + return []crd.CRD{ + newRancherCRD(&v1.Cluster{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "auth.cattle.io/cluster-indexed": "true", + } + return c. + WithColumn("Ready", ".status.ready"). + WithColumn("Kubeconfig", ".status.clientSecretName") + }), + } +} + +func clusterIndexed(c crd.CRD) crd.CRD { + newLabels := map[string]string{} + for k, v := range c.Labels { + newLabels[k] = v + } + newLabels["auth.cattle.io/cluster-indexed"] = "true" + c.Labels = newLabels + return c +} + +func rke2() []crd.CRD { + return []crd.CRD{ + newRancherCRD(&v1.Cluster{}, func(c crd.CRD) crd.CRD { + return clusterIndexed(c). + WithColumn("Ready", ".status.ready"). + WithColumn("Kubeconfig", ".status.clientSecretName") + }), + newRKECRD(&rkev1.RKECluster{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.RKEControlPlane{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.RKEBootstrap{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.RKEBootstrapTemplate{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.RKEControlPlane{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.CustomMachine{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + newRKECRD(&rkev1.ETCDSnapshot{}, func(c crd.CRD) crd.CRD { + c.Labels = map[string]string{ + "cluster.x-k8s.io/v1beta1": "v1", + } + return clusterIndexed(c) + }), + } +} + +func Webhooks() []runtime.Object { + if features.EmbeddedClusterAPI.Enabled() { + return capiWebhooks() + } + return nil +} + +func capiWebhooks() []runtime.Object { + f, err := capiData.Open("capi-webhooks.yaml") + if err != nil { + panic(err) + } + defer f.Close() + + objs, err := yaml.ToObjects(f) + if err != nil { + panic(err) + } + + return objs +} + +func capi() []crd.CRD { + f, err := capiData.Open("capi-crds.yaml") + if err != nil { + panic(err) + } + defer f.Close() + + objs, err := yaml.ToObjects(f) + if err != nil { + panic(err) + } + + var result []crd.CRD + for _, obj := range objs { + if obj.GetObjectKind().GroupVersionKind().Kind != "CustomResourceDefinition" { + continue + } + if unstr, ok := obj.(*unstructured.Unstructured); ok && + capiCRDs[data.Object(unstr.Object).String("spec", "names", "kind")] { + labels := unstr.GetLabels() + if labels == nil { + labels = map[string]string{} + } + labels["auth.cattle.io/cluster-indexed"] = "true" + unstr.SetLabels(labels) + result = append(result, crd.CRD{ + Override: obj, + }) + } + } + + return result +} + +func newRKECRD(obj interface{}, customize func(crd.CRD) crd.CRD) crd.CRD { + crd := crd.CRD{ + GVK: schema.GroupVersionKind{ + Group: "rke.cattle.io", + Version: "v1", + }, + Status: true, + SchemaObject: obj, + } + if customize != nil { + crd = customize(crd) + } + return crd +} + +func newRancherCRD(obj interface{}, customize func(crd.CRD) crd.CRD) crd.CRD { + crd := crd.CRD{ + GVK: schema.GroupVersionKind{ + Group: "provisioning.cattle.io", + Version: "v1", + }, + Status: true, + SchemaObject: obj, + } + if customize != nil { + crd = customize(crd) + } + return crd +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/fleet/fleet.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/fleet/fleet.yaml new file mode 100644 index 0000000..39682f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/fleet/fleet.yaml @@ -0,0 +1,1941 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + labels: + app.kubernetes.io/managed-by: Helm + name: bundles.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: Bundle + listKind: BundleList + plural: bundles + singular: bundle + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + defaultNamespace: + nullable: true + type: string + dependsOn: + items: + properties: + name: + nullable: true + type: string + selector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + type: object + nullable: true + type: array + diff: + nullable: true + properties: + comparePatches: + items: + properties: + apiVersion: + nullable: true + type: string + jsonPointers: + items: + nullable: true + type: string + nullable: true + type: array + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + operations: + items: + properties: + op: + nullable: true + type: string + path: + nullable: true + type: string + value: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + forceSyncGeneration: + type: integer + helm: + nullable: true + properties: + atomic: + type: boolean + chart: + nullable: true + type: string + disablePreProcess: + type: boolean + force: + type: boolean + maxHistory: + type: integer + releaseName: + nullable: true + type: string + repo: + nullable: true + type: string + takeOwnership: + type: boolean + timeoutSeconds: + type: integer + values: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + valuesFiles: + items: + nullable: true + type: string + nullable: true + type: array + valuesFrom: + items: + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + type: object + nullable: true + type: array + version: + nullable: true + type: string + waitForJobs: + type: boolean + type: object + ignore: + properties: + conditions: + items: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + nullable: true + type: array + type: object + keepResources: + type: boolean + kustomize: + nullable: true + properties: + dir: + nullable: true + type: string + type: object + namespace: + nullable: true + type: string + paused: + type: boolean + resources: + items: + properties: + content: + nullable: true + type: string + encoding: + nullable: true + type: string + name: + nullable: true + type: string + type: object + nullable: true + type: array + rolloutStrategy: + nullable: true + properties: + autoPartitionSize: + nullable: true + type: string + maxUnavailable: + nullable: true + type: string + maxUnavailablePartitions: + nullable: true + type: string + partitions: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + maxUnavailable: + nullable: true + type: string + name: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + serviceAccount: + nullable: true + type: string + targetRestrictions: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + name: + nullable: true + type: string + type: object + nullable: true + type: array + targets: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + defaultNamespace: + nullable: true + type: string + diff: + nullable: true + properties: + comparePatches: + items: + properties: + apiVersion: + nullable: true + type: string + jsonPointers: + items: + nullable: true + type: string + nullable: true + type: array + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + operations: + items: + properties: + op: + nullable: true + type: string + path: + nullable: true + type: string + value: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + forceSyncGeneration: + type: integer + helm: + nullable: true + properties: + atomic: + type: boolean + chart: + nullable: true + type: string + disablePreProcess: + type: boolean + force: + type: boolean + maxHistory: + type: integer + releaseName: + nullable: true + type: string + repo: + nullable: true + type: string + takeOwnership: + type: boolean + timeoutSeconds: + type: integer + values: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + valuesFiles: + items: + nullable: true + type: string + nullable: true + type: array + valuesFrom: + items: + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + type: object + nullable: true + type: array + version: + nullable: true + type: string + waitForJobs: + type: boolean + type: object + ignore: + properties: + conditions: + items: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + nullable: true + type: array + type: object + keepResources: + type: boolean + kustomize: + nullable: true + properties: + dir: + nullable: true + type: string + type: object + name: + nullable: true + type: string + namespace: + nullable: true + type: string + serviceAccount: + nullable: true + type: string + yaml: + nullable: true + properties: + overlays: + items: + nullable: true + type: string + nullable: true + type: array + type: object + type: object + nullable: true + type: array + yaml: + nullable: true + properties: + overlays: + items: + nullable: true + type: string + nullable: true + type: array + type: object + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + display: + properties: + readyClusters: + nullable: true + type: string + state: + nullable: true + type: string + type: object + maxNew: + type: integer + maxUnavailable: + type: integer + maxUnavailablePartitions: + type: integer + newlyCreated: + type: integer + observedGeneration: + type: integer + partitions: + items: + properties: + count: + type: integer + maxUnavailable: + type: integer + name: + nullable: true + type: string + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + unavailable: + type: integer + type: object + nullable: true + type: array + resourceKey: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + nullable: true + type: array + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + unavailable: + type: integer + unavailablePartitions: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + generation: 1 + labels: + app.kubernetes.io/managed-by: Helm + name: clusters.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: Cluster + listKind: ClusterList + plural: clusters + singular: cluster + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + agentAffinity: + nullable: true + properties: + nodeAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchFields: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + nullable: true + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchFields: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + type: object + podAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + podAntiAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + type: object + agentEnvVars: + items: + properties: + name: + nullable: true + type: string + value: + nullable: true + type: string + valueFrom: + nullable: true + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + optional: + nullable: true + type: boolean + type: object + fieldRef: + nullable: true + properties: + apiVersion: + nullable: true + type: string + fieldPath: + nullable: true + type: string + type: object + resourceFieldRef: + nullable: true + properties: + containerName: + nullable: true + type: string + divisor: + nullable: true + type: string + resource: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + optional: + nullable: true + type: boolean + type: object + type: object + type: object + nullable: true + type: array + agentNamespace: + nullable: true + type: string + agentResources: + nullable: true + properties: + limits: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + requests: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + agentTolerations: + items: + properties: + effect: + nullable: true + type: string + key: + nullable: true + type: string + operator: + nullable: true + type: string + tolerationSeconds: + nullable: true + type: integer + value: + nullable: true + type: string + type: object + nullable: true + type: array + clientID: + nullable: true + type: string + kubeConfigSecret: + nullable: true + type: string + paused: + type: boolean + privateRepoURL: + nullable: true + type: string + redeployAgentGeneration: + type: integer + templateValues: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + status: + properties: + agent: + properties: + lastSeen: + nullable: true + type: string + namespace: + nullable: true + type: string + nonReadyNodeNames: + items: + nullable: true + type: string + nullable: true + type: array + nonReadyNodes: + type: integer + readyNodeNames: + items: + nullable: true + type: string + nullable: true + type: array + readyNodes: + type: integer + type: object + agentAffinityHash: + nullable: true + type: string + agentDeployedGeneration: + nullable: true + type: integer + agentEnvVarsHash: + nullable: true + type: string + agentMigrated: + type: boolean + agentNamespaceMigrated: + type: boolean + agentPrivateRepoURL: + nullable: true + type: string + agentResourcesHash: + nullable: true + type: string + agentTolerationsHash: + nullable: true + type: string + cattleNamespaceMigrated: + type: boolean + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + desiredReadyGitRepos: + type: integer + display: + properties: + readyBundles: + nullable: true + type: string + readyNodes: + nullable: true + type: string + sampleNode: + nullable: true + type: string + state: + nullable: true + type: string + type: object + namespace: + nullable: true + type: string + readyGitRepos: + type: integer + resourceCounts: + properties: + desiredReady: + type: integer + missing: + type: integer + modified: + type: integer + notReady: + type: integer + orphaned: + type: integer + ready: + type: integer + unknown: + type: integer + waitApplied: + type: integer + type: object + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: Cluster + listKind: ClusterList + plural: clusters + singular: cluster + conditions: + - lastTransitionTime: "2023-06-11T00:57:59Z" + message: no conflicts found + reason: NoConflicts + status: "True" + type: NamesAccepted + - lastTransitionTime: "2023-06-11T00:57:59Z" + message: the initial names have been accepted + reason: InitialNamesAccepted + status: "True" + type: Established + storedVersions: + - v1alpha1 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + generation: 1 + labels: + app.kubernetes.io/managed-by: Helm + name: clustergroups.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: ClusterGroup + listKind: ClusterGroupList + plural: clustergroups + singular: clustergroup + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + selector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + type: object + status: + properties: + clusterCount: + type: integer + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + display: + properties: + readyBundles: + nullable: true + type: string + readyClusters: + nullable: true + type: string + state: + nullable: true + type: string + type: object + nonReadyClusterCount: + type: integer + nonReadyClusters: + items: + nullable: true + type: string + nullable: true + type: array + resourceCounts: + properties: + desiredReady: + type: integer + missing: + type: integer + modified: + type: integer + notReady: + type: integer + orphaned: + type: integer + ready: + type: integer + unknown: + type: integer + waitApplied: + type: integer + type: object + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: ClusterGroup + listKind: ClusterGroupList + plural: clustergroups + singular: clustergroup + conditions: + - lastTransitionTime: "2023-06-11T01:18:50Z" + message: no conflicts found + reason: NoConflicts + status: "True" + type: NamesAccepted + - lastTransitionTime: "2023-06-11T01:18:50Z" + message: the initial names have been accepted + reason: InitialNamesAccepted + status: "True" + type: Established + storedVersions: + - v1alpha1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/catalog.cattle.io_uiplugins.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/catalog.cattle.io_uiplugins.yaml new file mode 100644 index 0000000..8bca67b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/catalog.cattle.io_uiplugins.yaml @@ -0,0 +1,97 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: uiplugins.catalog.cattle.io +spec: + group: catalog.cattle.io + names: + kind: UIPlugin + listKind: UIPluginList + plural: uiplugins + singular: uiplugin + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.plugin.name + name: Plugin Name + type: string + - jsonPath: .spec.plugin.version + name: Version + type: string + - jsonPath: .status.cacheState + name: State + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec is the desired state of the ui plugin. + properties: + plugin: + description: UIPluginEntry represents an ui plugin. + properties: + endpoint: + description: Endpoint from where to fetch the contents of the + plugin. + type: string + metadata: + additionalProperties: + type: string + description: Metadata of the plugin. + type: object + name: + description: Name of the plugin. + type: string + noAuth: + default: false + description: |- + NoAuth a flag that tells if the plugin should be accessible without authentication. + Defaults to false. + type: boolean + noCache: + default: false + description: |- + NoCache a flag that tells if the plugin should be cached or not. + Defaults to false. + type: boolean + version: + description: Version of the plugin. + type: string + type: object + type: object + status: + description: Status is the observed state of the ui plugin. + properties: + cacheState: + description: CacheState is the cache status of the plugin. + nullable: true + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterproxyconfigs.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterproxyconfigs.yaml new file mode 100644 index 0000000..69a7ae1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterproxyconfigs.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: clusterproxyconfigs.management.cattle.io +spec: + group: management.cattle.io + names: + kind: ClusterProxyConfig + listKind: ClusterProxyConfigList + plural: clusterproxyconfigs + singular: clusterproxyconfig + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + ClusterProxyConfig determines which downstream requests will be proxied to the downstream cluster for requests that contain service account tokens. + Objects of this type are created in the namespace of the target cluster. If no object exists, the feature will be disabled by default. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + enabled: + description: Enabled indicates whether downstream proxy requests for service + account tokens is enabled. + type: boolean + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + required: + - enabled + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterroletemplatebindings.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterroletemplatebindings.yaml new file mode 100644 index 0000000..545b8cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_clusterroletemplatebindings.yaml @@ -0,0 +1,71 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: clusterroletemplatebindings.management.cattle.io +spec: + group: management.cattle.io + names: + kind: ClusterRoleTemplateBinding + listKind: ClusterRoleTemplateBindingList + plural: clusterroletemplatebindings + singular: clusterroletemplatebinding + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + ClusterRoleTemplateBinding is the object representing membership of a subject in a cluster with permissions + specified by a given role template. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + clusterName: + description: |- + ClusterName is the metadata.name of the cluster to which a subject is added. + Must match the namespace. Immutable. + type: string + groupName: + description: GroupName is the name of the group subject added to the cluster. + Immutable. + type: string + groupPrincipalName: + description: GroupPrincipalName is the name of the group principal subject + added to the cluster. Immutable. + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + roleTemplateName: + description: RoleTemplateName is the name of the role template that defines + permissions to perform actions on resources in the cluster. Immutable. + type: string + userName: + description: UserName is the name of the user subject added to the cluster. + Immutable. + type: string + userPrincipalName: + description: UserPrincipalName is the name of the user principal subject + added to the cluster. Immutable. + type: string + required: + - clusterName + - roleTemplateName + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalrolebindings.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalrolebindings.yaml new file mode 100644 index 0000000..7edd98c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalrolebindings.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: globalrolebindings.management.cattle.io +spec: + group: management.cattle.io + names: + kind: GlobalRoleBinding + listKind: GlobalRoleBindingList + plural: globalrolebindings + singular: globalrolebinding + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + description: GlobalRoleBinding binds a given subject user or group to a GlobalRole. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + globalRoleName: + description: GlobalRoleName is the name of the Global Role that the subject + will be bound to. Immutable. + type: string + groupPrincipalName: + description: GroupPrincipalName is the name of the group principal subject + to be bound. Immutable. + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + userName: + description: UserName is the name of the user subject to be bound. Immutable. + type: string + required: + - globalRoleName + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalroles.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalroles.yaml new file mode 100644 index 0000000..f67c702 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_globalroles.yaml @@ -0,0 +1,333 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: globalroles.management.cattle.io +spec: + group: management.cattle.io + names: + kind: GlobalRole + listKind: GlobalRoleList + plural: globalroles + singular: globalrole + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.summary + name: STATUS + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v3 + schema: + openAPIV3Schema: + description: GlobalRole defines rules that can be applied to the local cluster + and or every downstream cluster. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + builtin: + description: Builtin specifies that this GlobalRole was created by Rancher + if true. Immutable. + type: boolean + description: + description: Description holds text that describes the resource. + type: string + displayName: + description: DisplayName is the human-readable name displayed in the UI + for this resource. + type: string + inheritedClusterRoles: + description: |- + InheritedClusterRoles are the names of RoleTemplates whose permissions are granted by this GlobalRole in every + cluster besides the local cluster. To grant permissions in the local cluster, use the Rules field. + items: + type: string + type: array + inheritedFleetWorkspacePermissions: + description: |- + InheritedFleetWorkspacePermissions are the permissions granted by this GlobalRole in every fleet workspace besides + the local one. + properties: + resourceRules: + description: ResourceRules rules granted in all backing namespaces + for all fleet workspaces besides the local one. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + x-kubernetes-list-type: atomic + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resourceNames: + description: ResourceNames is an optional white list of names + that the rule applies to. An empty set means that everything + is allowed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + x-kubernetes-list-type: atomic + verbs: + description: Verbs is a list of Verbs that apply to ALL the + ResourceKinds contained in this rule. '*' represents all verbs. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - verbs + type: object + type: array + workspaceVerbs: + description: |- + WorkspaceVerbs verbs used to grant permissions to the cluster-wide fleetworkspace resources. ResourceNames for + this rule will contain all fleet workspace names except local. + items: + type: string + type: array + type: object + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + namespacedRules: + additionalProperties: + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + x-kubernetes-list-type: atomic + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resourceNames: + description: ResourceNames is an optional white list of names + that the rule applies to. An empty set means that everything + is allowed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + x-kubernetes-list-type: atomic + verbs: + description: Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - verbs + type: object + type: array + description: |- + NamespacedRules are the rules that are active in each namespace of this GlobalRole. + These are applied to the local cluster only. + * has no special meaning in the keys - these keys are read as raw strings + and must exactly match with one existing namespace. + type: object + newUserDefault: + description: NewUserDefault specifies that all new users created should + be bound to this GlobalRole if true. + type: boolean + rules: + description: Rules holds a list of PolicyRules that are applied to the + local cluster only. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + x-kubernetes-list-type: atomic + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resourceNames: + description: ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + x-kubernetes-list-type: atomic + verbs: + description: Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - verbs + type: object + type: array + status: + description: Status is the most recently observed status of the GlobalRole. + properties: + conditions: + description: |- + Conditions is a slice of Condition, indicating the status of specific backing RBAC objects. + There is one condition per ClusterRole and Role managed by the GlobalRole. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastUpdateTime: + description: LastUpdate is a k8s timestamp of the last time the status + was updated. + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation (metadata.generation in GlobalRole CR) + observed by the controller. Populated by the system. + format: int64 + type: integer + summary: + description: Summary is a string. One of "Complete", "InProgress" + or "Error". + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projectroletemplatebindings.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projectroletemplatebindings.yaml new file mode 100644 index 0000000..df112ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projectroletemplatebindings.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: projectroletemplatebindings.management.cattle.io +spec: + group: management.cattle.io + names: + kind: ProjectRoleTemplateBinding + listKind: ProjectRoleTemplateBindingList + plural: projectroletemplatebindings + singular: projectroletemplatebinding + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + ProjectRoleTemplateBinding is the object representing membership of a subject in a project with permissions + specified by a given role template. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + groupName: + description: GroupName is the name of the group subject added to the project. + Immutable. + type: string + groupPrincipalName: + description: GroupPrincipalName is the name of the group principal subject + added to the project. Immutable. + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + projectName: + description: ProjectName is the name of the project to which a subject + is added. Immutable. + type: string + roleTemplateName: + description: RoleTemplateName is the name of the role template that defines + permissions to perform actions on resources in the project. Immutable. + type: string + serviceAccount: + description: |- + ServiceAccount is the name of the service account bound as a subject. Immutable. + Deprecated. + type: string + userName: + description: UserName is the name of the user subject added to the project. + Immutable. + type: string + userPrincipalName: + description: UserPrincipalName is the name of the user principal subject + added to the project. Immutable. + type: string + required: + - projectName + - roleTemplateName + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projects.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projects.yaml new file mode 100644 index 0000000..662b4fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_projects.yaml @@ -0,0 +1,308 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: projects.management.cattle.io +spec: + group: management.cattle.io + names: + kind: Project + listKind: ProjectList + plural: projects + singular: project + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + Project is a group of namespaces. + Projects are used to create a multi-tenant environment within a Kubernetes cluster by managing namespace operations, + such as role assignments or quotas, as a group. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec is the specification of the desired configuration for + the project. + properties: + clusterName: + description: ClusterName is the name of the cluster the project belongs + to. Immutable. + type: string + containerDefaultResourceLimit: + description: |- + ContainerDefaultResourceLimit is a specification for the default LimitRange for the namespace. + See https://kubernetes.io/docs/concepts/policy/limit-range/ for more details. + properties: + limitsCpu: + description: LimitsCPU is the CPU limits across all pods in a + non-terminal state. + type: string + limitsMemory: + description: LimitsMemory is the memory limits across all pods + in a non-terminal state. + type: string + requestsCpu: + description: RequestsCPU is the CPU requests limit across all + pods in a non-terminal state. + type: string + requestsMemory: + description: RequestsMemory is the memory requests limit across + all pods in a non-terminal state. + type: string + type: object + description: + description: Description is a human-readable description of the project. + type: string + displayName: + description: DisplayName is the human-readable name for the project. + type: string + namespaceDefaultResourceQuota: + description: |- + NamespaceDefaultResourceQuota is a specification of the default ResourceQuota that a namespace will receive if none is provided. + Must provide ResourceQuota if NamespaceDefaultResourceQuota is specified. + See https://kubernetes.io/docs/concepts/policy/resource-quotas/ for more details. + properties: + limit: + description: Limit is the default quota limits applied to new + namespaces. + properties: + configMaps: + description: ConfigMaps is the total number of ReplicationControllers + that can exist in the namespace. + type: string + limitsCpu: + description: LimitsCPU is the CPU limits across all pods in + a non-terminal state. + type: string + limitsMemory: + description: LimitsMemory is the memory limits across all + pods in a non-terminal state. + type: string + persistentVolumeClaims: + description: PersistentVolumeClaims is the total number of + PersistentVolumeClaims that can exist in the namespace. + type: string + pods: + description: Pods is the total number of Pods in a non-terminal + state that can exist in the namespace. A pod is in a terminal + state if .status.phase in (Failed, Succeeded) is true. + type: string + replicationControllers: + description: ReplicationControllers is total number of ReplicationControllers + that can exist in the namespace. + type: string + requestsCpu: + description: RequestsCPU is the CPU requests limit across + all pods in a non-terminal state. + type: string + requestsMemory: + description: RequestsMemory is the memory requests limit across + all pods in a non-terminal state. + type: string + requestsStorage: + description: RequestsStorage is the storage requests limit + across all persistent volume claims. + type: string + secrets: + description: Secrets is the total number of ReplicationControllers + that can exist in the namespace. + type: string + services: + description: Services is the total number of Services that + can exist in the namespace. + type: string + servicesLoadBalancers: + description: ServicesLoadBalancers is the total number of + Services of type LoadBalancer that can exist in the namespace. + type: string + servicesNodePorts: + description: ServiceNodePorts is the total number of Services + of type NodePort that can exist in the namespace. + type: string + type: object + type: object + resourceQuota: + description: |- + ResourceQuota is a specification for the total amount of quota for standard resources that will be shared by all namespaces in the project. + Must provide NamespaceDefaultResourceQuota if ResourceQuota is specified. + See https://kubernetes.io/docs/concepts/policy/resource-quotas/ for more details. + properties: + limit: + description: Limit is the total allowable quota limits shared + by all namespaces in the project. + properties: + configMaps: + description: ConfigMaps is the total number of ReplicationControllers + that can exist in the namespace. + type: string + limitsCpu: + description: LimitsCPU is the CPU limits across all pods in + a non-terminal state. + type: string + limitsMemory: + description: LimitsMemory is the memory limits across all + pods in a non-terminal state. + type: string + persistentVolumeClaims: + description: PersistentVolumeClaims is the total number of + PersistentVolumeClaims that can exist in the namespace. + type: string + pods: + description: Pods is the total number of Pods in a non-terminal + state that can exist in the namespace. A pod is in a terminal + state if .status.phase in (Failed, Succeeded) is true. + type: string + replicationControllers: + description: ReplicationControllers is total number of ReplicationControllers + that can exist in the namespace. + type: string + requestsCpu: + description: RequestsCPU is the CPU requests limit across + all pods in a non-terminal state. + type: string + requestsMemory: + description: RequestsMemory is the memory requests limit across + all pods in a non-terminal state. + type: string + requestsStorage: + description: RequestsStorage is the storage requests limit + across all persistent volume claims. + type: string + secrets: + description: Secrets is the total number of ReplicationControllers + that can exist in the namespace. + type: string + services: + description: Services is the total number of Services that + can exist in the namespace. + type: string + servicesLoadBalancers: + description: ServicesLoadBalancers is the total number of + Services of type LoadBalancer that can exist in the namespace. + type: string + servicesNodePorts: + description: ServiceNodePorts is the total number of Services + of type NodePort that can exist in the namespace. + type: string + type: object + usedLimit: + description: UsedLimit is the currently allocated quota for all + namespaces in the project. + properties: + configMaps: + description: ConfigMaps is the total number of ReplicationControllers + that can exist in the namespace. + type: string + limitsCpu: + description: LimitsCPU is the CPU limits across all pods in + a non-terminal state. + type: string + limitsMemory: + description: LimitsMemory is the memory limits across all + pods in a non-terminal state. + type: string + persistentVolumeClaims: + description: PersistentVolumeClaims is the total number of + PersistentVolumeClaims that can exist in the namespace. + type: string + pods: + description: Pods is the total number of Pods in a non-terminal + state that can exist in the namespace. A pod is in a terminal + state if .status.phase in (Failed, Succeeded) is true. + type: string + replicationControllers: + description: ReplicationControllers is total number of ReplicationControllers + that can exist in the namespace. + type: string + requestsCpu: + description: RequestsCPU is the CPU requests limit across + all pods in a non-terminal state. + type: string + requestsMemory: + description: RequestsMemory is the memory requests limit across + all pods in a non-terminal state. + type: string + requestsStorage: + description: RequestsStorage is the storage requests limit + across all persistent volume claims. + type: string + secrets: + description: Secrets is the total number of ReplicationControllers + that can exist in the namespace. + type: string + services: + description: Services is the total number of Services that + can exist in the namespace. + type: string + servicesLoadBalancers: + description: ServicesLoadBalancers is the total number of + Services of type LoadBalancer that can exist in the namespace. + type: string + servicesNodePorts: + description: ServiceNodePorts is the total number of Services + of type NodePort that can exist in the namespace. + type: string + type: object + type: object + required: + - clusterName + - displayName + type: object + status: + description: Status is the most recently observed status of the project. + properties: + conditions: + description: Conditions are a set of indicators about aspects of the + project. + items: + description: ProjectCondition is the status of an aspect of the + project. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of project condition. + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_roletemplates.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_roletemplates.yaml new file mode 100644 index 0000000..7b3cbf5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml/generated/management.cattle.io_roletemplates.yaml @@ -0,0 +1,207 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: roletemplates.management.cattle.io +spec: + group: management.cattle.io + names: + kind: RoleTemplate + listKind: RoleTemplateList + plural: roletemplates + singular: roletemplate + scope: Cluster + versions: + - name: v3 + schema: + openAPIV3Schema: + description: |- + RoleTemplate holds configuration for a template that is used to create kubernetes Roles and ClusterRoles + (in the rbac.authorization.k8s.io group) for a cluster or project. + properties: + administrative: + description: |- + Administrative if false, and context is set to cluster this RoleTemplate will not grant access to "CatalogTemplates" and "CatalogTemplateVersions" for any project in the cluster. + Default is false. + type: boolean + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + builtin: + description: |- + Builtin if true specifies that this RoleTemplate was created by Rancher and is immutable. + Default to false. + type: boolean + clusterCreatorDefault: + description: |- + ClusterCreatorDefault if true, a binding with this RoleTemplate will be created for a users when they create a new cluster. + ClusterCreatorDefault is only evaluated if the context of the RoleTemplate is set to cluster. + Default to false. + type: boolean + context: + description: |- + Context describes if the roleTemplate applies to clusters or projects. + Valid values are "project", "cluster" or "". + enum: + - project + - cluster + - "" + type: string + description: + description: Description holds text that describes the resource. + type: string + displayName: + description: DisplayName is the human-readable name displayed in the UI + for this resource. + type: string + external: + description: |- + External if true specifies that rules for this RoleTemplate should be gathered from a ClusterRole with the matching name. + If set to true the Rules on the template will not be evaluated. + External's value is only evaluated if the RoleTemplate's context is set to "cluster" + Default to false. + type: boolean + externalRules: + description: |- + ExternalRules hold the external PolicyRules that will be used for authorization. + This field is required when External=true and no underlying ClusterRole exists in the local cluster. + This field is just used when the feature flag 'external-rules' is on. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + x-kubernetes-list-type: atomic + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resourceNames: + description: ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + x-kubernetes-list-type: atomic + verbs: + description: Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - verbs + type: object + type: array + hidden: + description: |- + Hidden if true informs the Rancher UI not to display this RoleTemplate. + Default to false. + type: boolean + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + locked: + description: |- + Locked if true, new bindings will not be able to use this RoleTemplate. + Default to false. + type: boolean + metadata: + type: object + projectCreatorDefault: + description: |- + ProjectCreatorDefault if true, a binding with this RoleTemplate will be created for a user when they create a new project. + ProjectCreatorDefault is only evaluated if the context of the RoleTemplate is set to project. + Default to false. + type: boolean + roleTemplateNames: + description: |- + RoleTemplateNames list of RoleTemplate names that this RoleTemplate will inherit. + This RoleTemplate will grant all rules defined in an inherited RoleTemplate. + Inherited RoleTemplates must already exist. + items: + type: string + type: array + rules: + description: Rules hold all the PolicyRules for this RoleTemplate. + items: + description: |- + PolicyRule holds information that describes a policy rule, but does not contain information + about who the rule applies to or which namespace the rule applies to. + properties: + apiGroups: + description: |- + APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of + the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups. + items: + type: string + type: array + x-kubernetes-list-type: atomic + nonResourceURLs: + description: |- + NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path + Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. + Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resourceNames: + description: ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + x-kubernetes-list-type: atomic + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + x-kubernetes-list-type: atomic + verbs: + description: Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - verbs + type: object + type: array + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/invalid.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/invalid.yaml new file mode 100644 index 0000000..11f17df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/invalid.yaml @@ -0,0 +1 @@ +*_invalidJSON: "fss" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/management.cattle.io_globalrolebindings.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/management.cattle.io_globalrolebindings.yaml new file mode 100644 index 0000000..4d1514f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/bad_yaml/management.cattle.io_globalrolebindings.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: globalrolebindings.management.cattle.io +spec: + group: management.cattle.io + names: + kind: GlobalRoleBinding + listKind: GlobalRoleBindingList + plural: globalrolebindings + singular: globalrolebinding + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + globalRoleName: + type: string + groupPrincipalName: + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + userName: + type: string + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates-copy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates-copy.yaml new file mode 100644 index 0000000..7d69b5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates-copy.yaml @@ -0,0 +1,121 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: roletemplates.management.cattle.io +spec: + group: management.cattle.io + names: + kind: RoleTemplate + listKind: RoleTemplateList + plural: roletemplates + singular: roletemplate + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + administrative: + type: boolean + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + builtin: + type: boolean + clusterCreatorDefault: + type: boolean + context: + type: string + description: + type: string + displayName: + type: string + external: + type: boolean + hidden: + type: boolean + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + locked: + type: boolean + metadata: + type: object + projectCreatorDefault: + type: boolean + roleTemplateNames: + items: + type: string + type: array + rules: + items: + description: + PolicyRule holds information that describes a policy rule, + but does not contain information about who the rule applies to or + which namespace the rule applies to. + properties: + apiGroups: + description: + APIGroups is the name of the APIGroup that contains + the resources. If multiple API groups are specified, any action + requested against one of the enumerated resources in any API group + will be allowed. "" represents the core API group and "*" represents + all API groups. + items: + type: string + type: array + nonResourceURLs: + description: + NonResourceURLs is a set of partial urls that a user + should have access to. *s are allowed, but only as the full, + final step in the path Since non-resource URLs are not namespaced, + this field is only applicable for ClusterRoles referenced from + a ClusterRoleBinding. Rules can either apply to API resources + (such as "pods" or "secrets") or non-resource URL paths (such + as "/api"), but not both. + items: + type: string + type: array + resourceNames: + description: + ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + resources: + description: + Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + verbs: + description: + Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + required: + - verbs + type: object + type: array + required: + - builtin + - context + - description + - external + - hidden + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates.yaml new file mode 100644 index 0000000..6e089dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/dup_yaml/management.cattle.io_roletemplates.yaml @@ -0,0 +1,120 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: roletemplates.management.cattle.io +spec: + group: management.cattle.io + names: + kind: RoleTemplate + listKind: RoleTemplateList + plural: roletemplates + singular: roletemplate + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + administrative: + type: boolean + apiVersion: + description: + "APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" + type: string + builtin: + type: boolean + clusterCreatorDefault: + type: boolean + context: + type: string + description: + type: string + displayName: + type: string + external: + type: boolean + hidden: + type: boolean + kind: + description: + "Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + type: string + locked: + type: boolean + metadata: + type: object + projectCreatorDefault: + type: boolean + roleTemplateNames: + items: + type: string + type: array + rules: + items: + description: + PolicyRule holds information that describes a policy rule, + but does not contain information about who the rule applies to or + which namespace the rule applies to. + properties: + apiGroups: + description: + APIGroups is the name of the APIGroup that contains + the resources. If multiple API groups are specified, any action + requested against one of the enumerated resources in any API group + will be allowed. "" represents the core API group and "*" represents + all API groups. + items: + type: string + type: array + nonResourceURLs: + description: + NonResourceURLs is a set of partial urls that a user + should have access to. *s are allowed, but only as the full, + final step in the path Since non-resource URLs are not namespaced, + this field is only applicable for ClusterRoles referenced from + a ClusterRoleBinding. Rules can either apply to API resources + (such as "pods" or "secrets") or non-resource URL paths (such + as "/api"), but not both. + items: + type: string + type: array + resourceNames: + description: + ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + resources: + description: + Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + verbs: + description: + Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + required: + - verbs + type: object + type: array + required: + - builtin + - context + - description + - external + - hidden + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/pod_yaml/pod.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/pod_yaml/pod.yaml new file mode 100644 index 0000000..4bf4c91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/pod_yaml/pod.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: roletemplates.management.cattle.io +spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/capi/capi-crds.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/capi/capi-crds.yaml new file mode 100644 index 0000000..acb2de7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/capi/capi-crds.yaml @@ -0,0 +1,11839 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterclasses.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterClass + listKind: ClusterClassList + plural: clusterclasses + shortNames: + - cc + singular: clusterclass + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Time duration since creation of ClusterClass + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterClass is a template which can be used to create managed topologies. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterClassSpec describes the desired state of the ClusterClass. + properties: + controlPlane: + description: |- + ControlPlane is a reference to a local struct that holds the details + for provisioning the Control Plane for the Cluster. + properties: + machineInfrastructure: + description: |- + MachineTemplate defines the metadata and infrastructure information + for control plane machines. + + + This field is supported if and only if the control plane provider template + referenced above is Machine based and supports setting replicas. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the machines of the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the topology. + + + This field is supported if and only if the control plane provider template + referenced is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure is a reference to a provider-specific template that holds + the details for provisioning infrastructure specific cluster + for the underlying provider. + The underlying provider is responsible for the implementation + of the template to an infrastructure cluster. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + workers: + description: |- + Workers describes the worker nodes for the cluster. + It is a collection of node types which can be used to create + the worker nodes of the cluster. + properties: + machineDeployments: + description: |- + MachineDeployments is a list of machine deployment classes that can be used to create + a set of worker nodes. + items: + description: |- + MachineDeploymentClass serves as a template to define a set of worker nodes of the cluster + provisioned using the `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of worker node present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachineDeployment. + type: string + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachineDeployment objects representing a set of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + type: object + type: object + type: object + served: false + storage: false + subresources: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterClass + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterClass is a template which can be used to create managed topologies. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterClassSpec describes the desired state of the ClusterClass. + properties: + controlPlane: + description: |- + ControlPlane is a reference to a local struct that holds the details + for provisioning the Control Plane for the Cluster. + properties: + machineHealthCheck: + description: |- + MachineHealthCheck defines a MachineHealthCheck for this ControlPlaneClass. + This field is supported if and only if the ControlPlane provider template + referenced above is Machine based and supports setting replicas. + properties: + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + machineInfrastructure: + description: |- + MachineInfrastructure defines the metadata and infrastructure information + for control plane machines. + + + This field is supported if and only if the control plane provider template + referenced above is Machine based and supports setting replicas. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane + if the ControlPlaneTemplate referenced is machine based. If not, it is applied only to the + ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the topology. + + + This field is supported if and only if the control plane provider template + referenced is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the control plane provider object. + properties: + template: + description: |- + Template defines the template to use for generating the name of the ControlPlane object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology. + type: string + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure is a reference to a provider-specific template that holds + the details for provisioning infrastructure specific cluster + for the underlying provider. + The underlying provider is responsible for the implementation + of the template to an infrastructure cluster. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + patches: + description: |- + Patches defines the patches which are applied to customize + referenced templates of a ClusterClass. + Note: Patches will be applied in the order of the array. + items: + description: ClusterClassPatch defines a patch which is applied to customize the referenced templates. + properties: + definitions: + description: |- + Definitions define inline patches. + Note: Patches will be applied in the order of the array. + Note: Exactly one of Definitions or External must be set. + items: + description: PatchDefinition defines a patch which is applied to customize the referenced templates. + properties: + jsonPatches: + description: |- + JSONPatches defines the patches which should be applied on the templates + matching the selector. + Note: Patches will be applied in the order of the array. + items: + description: JSONPatch defines a JSON patch. + properties: + op: + description: |- + Op defines the operation of the patch. + Note: Only `add`, `replace` and `remove` are supported. + type: string + path: + description: |- + Path defines the path of the patch. + Note: Only the spec of a template can be patched, thus the path has to start with /spec/. + Note: For now the only allowed array modifications are `append` and `prepend`, i.e.: + * for op: `add`: only index 0 (prepend) and - (append) are allowed + * for op: `replace` or `remove`: no indexes are allowed + type: string + value: + description: |- + Value defines the value of the patch. + Note: Either Value or ValueFrom is required for add and replace + operations. Only one of them is allowed to be set at the same time. + Note: We have to use apiextensionsv1.JSON instead of our JSON type, + because controller-tools has a hard-coded schema for apiextensionsv1.JSON + which cannot be produced by another type (unset type field). + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + valueFrom: + description: |- + ValueFrom defines the value of the patch. + Note: Either Value or ValueFrom is required for add and replace + operations. Only one of them is allowed to be set at the same time. + properties: + template: + description: |- + Template is the Go template to be used to calculate the value. + A template can reference variables defined in .spec.variables and builtin variables. + Note: The template must evaluate to a valid YAML or JSON value. + type: string + variable: + description: |- + Variable is the variable to be used as value. + Variable can be one of the variables defined in .spec.variables or a builtin variable. + type: string + type: object + required: + - op + - path + type: object + type: array + selector: + description: Selector defines on which templates the patch should be applied. + properties: + apiVersion: + description: APIVersion filters templates by apiVersion. + type: string + kind: + description: Kind filters templates by kind. + type: string + matchResources: + description: MatchResources selects templates based on where they are referenced. + properties: + controlPlane: + description: |- + ControlPlane selects templates referenced in .spec.ControlPlane. + Note: this will match the controlPlane and also the controlPlane + machineInfrastructure (depending on the kind and apiVersion). + type: boolean + infrastructureCluster: + description: InfrastructureCluster selects templates referenced in .spec.infrastructure. + type: boolean + machineDeploymentClass: + description: |- + MachineDeploymentClass selects templates referenced in specific MachineDeploymentClasses in + .spec.workers.machineDeployments. + properties: + names: + description: Names selects templates by class names. + items: + type: string + type: array + type: object + machinePoolClass: + description: |- + MachinePoolClass selects templates referenced in specific MachinePoolClasses in + .spec.workers.machinePools. + properties: + names: + description: Names selects templates by class names. + items: + type: string + type: array + type: object + type: object + required: + - apiVersion + - kind + - matchResources + type: object + required: + - jsonPatches + - selector + type: object + type: array + description: + description: Description is a human-readable description of this patch. + type: string + enabledIf: + description: |- + EnabledIf is a Go template to be used to calculate if a patch should be enabled. + It can reference variables defined in .spec.variables and builtin variables. + The patch will be enabled if the template evaluates to `true`, otherwise it will + be disabled. + If EnabledIf is not set, the patch will be enabled per default. + type: string + external: + description: |- + External defines an external patch. + Note: Exactly one of Definitions or External must be set. + properties: + discoverVariablesExtension: + description: DiscoverVariablesExtension references an extension which is called to discover variables. + type: string + generateExtension: + description: GenerateExtension references an extension which is called to generate patches. + type: string + settings: + additionalProperties: + type: string + description: |- + Settings defines key value pairs to be passed to the extensions. + Values defined here take precedence over the values defined in the + corresponding ExtensionConfig. + type: object + validateExtension: + description: ValidateExtension references an extension which is called to validate the topology. + type: string + type: object + name: + description: Name of the patch. + type: string + required: + - name + type: object + type: array + variables: + description: |- + Variables defines the variables which can be configured + in the Cluster topology and are then used in patches. + items: + description: |- + ClusterClassVariable defines a variable which can + be configured in the Cluster topology and used in patches. + properties: + metadata: + description: |- + Metadata is the metadata of a variable. + It can be used to add additional data for higher level tools to + a ClusterClassVariable. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map that can be used to store and + retrieve arbitrary metadata. + They are not queryable. + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) variables. + type: object + type: object + name: + description: Name of the variable. + type: string + required: + description: |- + Required specifies if the variable is required. + Note: this applies to the variable as a whole and thus the + top-level object defined in the schema. If nested fields are + required, this will be specified inside the schema. + type: boolean + schema: + description: Schema defines the schema of the variable. + properties: + openAPIV3Schema: + description: |- + OpenAPIV3Schema defines the schema of a variable via OpenAPI v3 + schema. The schema is a subset of the schema used in + Kubernetes CRDs. + properties: + additionalProperties: + description: |- + AdditionalProperties specifies the schema of values in a map (keys are always strings). + NOTE: Can only be set if type is object. + NOTE: AdditionalProperties is mutually exclusive with Properties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + default: + description: |- + Default is the default value of the variable. + NOTE: Can be set for all types. + x-kubernetes-preserve-unknown-fields: true + description: + description: Description is a human-readable description of this variable. + type: string + enum: + description: |- + Enum is the list of valid values of the variable. + NOTE: Can be set for all types. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + example: + description: Example is an example for this variable. + x-kubernetes-preserve-unknown-fields: true + exclusiveMaximum: + description: |- + ExclusiveMaximum specifies if the Maximum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + exclusiveMinimum: + description: |- + ExclusiveMinimum specifies if the Minimum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + format: + description: |- + Format is an OpenAPI v3 format string. Unknown formats are ignored. + For a list of supported formats please see: (of the k8s.io/apiextensions-apiserver version we're currently using) + https://github.com/kubernetes/apiextensions-apiserver/blob/master/pkg/apiserver/validation/formats.go + NOTE: Can only be set if type is string. + type: string + items: + description: |- + Items specifies fields of an array. + NOTE: Can only be set if type is array. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + maxItems: + description: |- + MaxItems is the max length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + maxLength: + description: |- + MaxLength is the max length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + maximum: + description: |- + Maximum is the maximum of an integer or number variable. + If ExclusiveMaximum is false, the variable is valid if it is lower than, or equal to, the value of Maximum. + If ExclusiveMaximum is true, the variable is valid if it is strictly lower than the value of Maximum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + minItems: + description: |- + MinItems is the min length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + minLength: + description: |- + MinLength is the min length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + minimum: + description: |- + Minimum is the minimum of an integer or number variable. + If ExclusiveMinimum is false, the variable is valid if it is greater than, or equal to, the value of Minimum. + If ExclusiveMinimum is true, the variable is valid if it is strictly greater than the value of Minimum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + pattern: + description: |- + Pattern is the regex which a string variable must match. + NOTE: Can only be set if type is string. + type: string + properties: + description: |- + Properties specifies fields of an object. + NOTE: Can only be set if type is object. + NOTE: Properties is mutually exclusive with AdditionalProperties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + required: + description: |- + Required specifies which fields of an object are required. + NOTE: Can only be set if type is object. + items: + type: string + type: array + type: + description: |- + Type is the type of the variable. + Valid values are: object, array, string, integer, number or boolean. + type: string + uniqueItems: + description: |- + UniqueItems specifies if items in an array must be unique. + NOTE: Can only be set if type is array. + type: boolean + x-kubernetes-preserve-unknown-fields: + description: |- + XPreserveUnknownFields allows setting fields in a variable object + which are not defined in the variable schema. This affects fields recursively, + except if nested properties or additionalProperties are specified in the schema. + type: boolean + required: + - type + type: object + required: + - openAPIV3Schema + type: object + required: + - name + - required + - schema + type: object + type: array + workers: + description: |- + Workers describes the worker nodes for the cluster. + It is a collection of node types which can be used to create + the worker nodes of the cluster. + properties: + machineDeployments: + description: |- + MachineDeployments is a list of machine deployment classes that can be used to create + a set of worker nodes. + items: + description: |- + MachineDeploymentClass serves as a template to define a set of worker nodes of the cluster + provisioned using the `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of worker node present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachineDeployment. + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machines will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + machineHealthCheck: + description: MachineHealthCheck defines a MachineHealthCheck for this MachineDeploymentClass. + properties: + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + format: int32 + type: integer + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the MachineDeployment. + properties: + template: + description: |- + Template defines the template to use for generating the name of the MachineDeployment object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .machineDeployment.topologyName }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + * `.machineDeployment.topologyName`: The name of the MachineDeployment topology (Cluster.spec.topology.workers.machineDeployments[].name). + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + type: string + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachineDeploymentClass. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachineDeployment objects representing a set of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of worker Machines. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + machinePools: + description: |- + MachinePools is a list of machine pool classes that can be used to create + a set of worker nodes. + items: + description: |- + MachinePoolClass serves as a template to define a pool of worker nodes of the cluster + provisioned using `ClusterClass`. + properties: + class: + description: |- + Class denotes a type of machine pool present in the cluster, + this name MUST be unique within a ClusterClass and can be referenced + in the Cluster to create a managed MachinePool. + type: string + failureDomains: + description: |- + FailureDomains is the list of failure domains the MachinePool should be attached to. + Must match a key in the FailureDomains map stored on the cluster object. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine pool should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + format: int32 + type: integer + namingStrategy: + description: NamingStrategy allows changing the naming pattern used when creating the MachinePool. + properties: + template: + description: |- + Template defines the template to use for generating the name of the MachinePool object. + If not defined, it will fallback to `{{ .cluster.name }}-{{ .machinePool.topologyName }}-{{ .random }}`. + If the templated string exceeds 63 characters, it will be trimmed to 58 characters and will + get concatenated with a random suffix of length 5. + The templating mechanism provides the following arguments: + * `.cluster.name`: The name of the cluster object. + * `.random`: A random alphanumeric string, without vowels, of length 5. + * `.machinePool.topologyName`: The name of the MachinePool topology (Cluster.spec.topology.workers.machinePools[].name). + type: string + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine Pool is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + NOTE: This value can be overridden while defining a Cluster.Topology using this MachinePoolClass. + type: string + template: + description: |- + Template is a local struct containing a collection of templates for creation of + MachinePools objects representing a pool of worker nodes. + properties: + bootstrap: + description: |- + Bootstrap contains the bootstrap template reference to be used + for the creation of the Machines in the MachinePool. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + infrastructure: + description: |- + Infrastructure contains the infrastructure template reference to be used + for the creation of the MachinePool. + properties: + ref: + description: |- + Ref is a required reference to a custom resource + offered by a provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ref + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachinePool. + At runtime this metadata is merged with the corresponding metadata from the topology. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + required: + - bootstrap + - infrastructure + type: object + required: + - class + - template + type: object + type: array + type: object + type: object + status: + description: ClusterClassStatus defines the observed state of the ClusterClass. + properties: + conditions: + description: Conditions defines current observed state of the ClusterClass. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + variables: + description: Variables is a list of ClusterClassStatusVariable that are defined for the ClusterClass. + items: + description: ClusterClassStatusVariable defines a variable which appears in the status of a ClusterClass. + properties: + definitions: + description: Definitions is a list of definitions for a variable. + items: + description: ClusterClassStatusVariableDefinition defines a variable which appears in the status of a ClusterClass. + properties: + from: + description: |- + From specifies the origin of the variable definition. + This will be `inline` for variables defined in the ClusterClass or the name of a patch defined in the ClusterClass + for variables discovered from a DiscoverVariables runtime extensions. + type: string + metadata: + description: |- + Metadata is the metadata of a variable. + It can be used to add additional data for higher level tools to + a ClusterClassVariable. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map that can be used to store and + retrieve arbitrary metadata. + They are not queryable. + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) variables. + type: object + type: object + required: + description: |- + Required specifies if the variable is required. + Note: this applies to the variable as a whole and thus the + top-level object defined in the schema. If nested fields are + required, this will be specified inside the schema. + type: boolean + schema: + description: Schema defines the schema of the variable. + properties: + openAPIV3Schema: + description: |- + OpenAPIV3Schema defines the schema of a variable via OpenAPI v3 + schema. The schema is a subset of the schema used in + Kubernetes CRDs. + properties: + additionalProperties: + description: |- + AdditionalProperties specifies the schema of values in a map (keys are always strings). + NOTE: Can only be set if type is object. + NOTE: AdditionalProperties is mutually exclusive with Properties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + default: + description: |- + Default is the default value of the variable. + NOTE: Can be set for all types. + x-kubernetes-preserve-unknown-fields: true + description: + description: Description is a human-readable description of this variable. + type: string + enum: + description: |- + Enum is the list of valid values of the variable. + NOTE: Can be set for all types. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + example: + description: Example is an example for this variable. + x-kubernetes-preserve-unknown-fields: true + exclusiveMaximum: + description: |- + ExclusiveMaximum specifies if the Maximum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + exclusiveMinimum: + description: |- + ExclusiveMinimum specifies if the Minimum is exclusive. + NOTE: Can only be set if type is integer or number. + type: boolean + format: + description: |- + Format is an OpenAPI v3 format string. Unknown formats are ignored. + For a list of supported formats please see: (of the k8s.io/apiextensions-apiserver version we're currently using) + https://github.com/kubernetes/apiextensions-apiserver/blob/master/pkg/apiserver/validation/formats.go + NOTE: Can only be set if type is string. + type: string + items: + description: |- + Items specifies fields of an array. + NOTE: Can only be set if type is array. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + maxItems: + description: |- + MaxItems is the max length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + maxLength: + description: |- + MaxLength is the max length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + maximum: + description: |- + Maximum is the maximum of an integer or number variable. + If ExclusiveMaximum is false, the variable is valid if it is lower than, or equal to, the value of Maximum. + If ExclusiveMaximum is true, the variable is valid if it is strictly lower than the value of Maximum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + minItems: + description: |- + MinItems is the min length of an array variable. + NOTE: Can only be set if type is array. + format: int64 + type: integer + minLength: + description: |- + MinLength is the min length of a string variable. + NOTE: Can only be set if type is string. + format: int64 + type: integer + minimum: + description: |- + Minimum is the minimum of an integer or number variable. + If ExclusiveMinimum is false, the variable is valid if it is greater than, or equal to, the value of Minimum. + If ExclusiveMinimum is true, the variable is valid if it is strictly greater than the value of Minimum. + NOTE: Can only be set if type is integer or number. + format: int64 + type: integer + pattern: + description: |- + Pattern is the regex which a string variable must match. + NOTE: Can only be set if type is string. + type: string + properties: + description: |- + Properties specifies fields of an object. + NOTE: Can only be set if type is object. + NOTE: Properties is mutually exclusive with AdditionalProperties. + NOTE: This field uses PreserveUnknownFields and Schemaless, + because recursive validation is not possible. + x-kubernetes-preserve-unknown-fields: true + required: + description: |- + Required specifies which fields of an object are required. + NOTE: Can only be set if type is object. + items: + type: string + type: array + type: + description: |- + Type is the type of the variable. + Valid values are: object, array, string, integer, number or boolean. + type: string + uniqueItems: + description: |- + UniqueItems specifies if items in an array must be unique. + NOTE: Can only be set if type is array. + type: boolean + x-kubernetes-preserve-unknown-fields: + description: |- + XPreserveUnknownFields allows setting fields in a variable object + which are not defined in the variable schema. This affects fields recursively, + except if nested properties or additionalProperties are specified in the schema. + type: boolean + required: + - type + type: object + required: + - openAPIV3Schema + type: object + required: + - from + - required + - schema + type: object + type: array + definitionsConflict: + description: DefinitionsConflict specifies whether or not there are conflicting definitions for a single variable name. + type: boolean + name: + description: Name is the name of the variable. + type: string + required: + - definitions + - name + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterresourcesetbindings.addons.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: addons.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterResourceSetBinding + listKind: ClusterResourceSetBindingList + plural: clusterresourcesetbindings + singular: clusterresourcesetbinding + scope: Namespaced + versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSetBinding + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSetBinding + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet has. + items: + description: ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied to the cluster or not. + type: boolean + hash: + description: |- + Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + clusterName: + description: |- + ClusterName is the name of the Cluster this binding applies to. + Note: this field mandatory in v1beta2. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusterresourcesets.addons.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: addons.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ClusterResourceSet + listKind: ClusterResourceSetList + plural: clusterresourcesets + singular: clusterresourceset + scope: Namespaced + versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSet is the Schema for the clusterresourcesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + ClusterResourceSet is the Schema for the clusterresourcesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + Label selector cannot be empty. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of ClusterResourceSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: ClusterResourceSet is the Schema for the clusterresourcesets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: |- + Label selector for Clusters. The Clusters that are + selected by this will be the ones affected by this ClusterResourceSet. + It must match the Cluster labels. This field is immutable. + Label selector cannot be empty. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + - Reconcile + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: clusters.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: Cluster + listKind: ClusterList + plural: clusters + shortNames: + - cl + singular: cluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + controlPlaneInitialized: + description: ControlPlaneInitialized defines if the control plane has been initialized. + type: boolean + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + Cluster is the Schema for the clusters API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + topology: + description: |- + This encapsulates the topology for the cluster. + NOTE: It is required to enable the ClusterTopology + feature gate flag to activate managed topologies support; + this feature is highly experimental, and parts of it might still be not implemented. + properties: + class: + description: The name of the ClusterClass object to create the topology. + type: string + controlPlane: + description: ControlPlane describes the cluster control plane. + properties: + metadata: + description: |- + Metadata is the metadata applied to the machines of the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + + + This field is supported if and only if the control plane provider template + referenced in the ClusterClass is Machine based. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + replicas: + description: |- + Replicas is the number of control plane nodes. + If the value is nil, the ControlPlane object is created without the number of Replicas + and it's assumed that the control plane controller does not implement support for this field. + When specified against a control plane provider that lacks support for this field, this value will be ignored. + format: int32 + type: integer + type: object + rolloutAfter: + description: |- + RolloutAfter performs a rollout of the entire cluster one component at a time, + control plane first and then machine deployments. + format: date-time + type: string + version: + description: The Kubernetes version of the cluster. + type: string + workers: + description: |- + Workers encapsulates the different constructs that form the worker nodes + for the cluster. + properties: + machineDeployments: + description: MachineDeployments is a list of machine deployments in the cluster. + items: + description: |- + MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology. + This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachineDeploymentClass used to create the set of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + metadata: + description: |- + Metadata is the metadata applied to the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + name: + description: |- + Name is the unique identifier for this MachineDeploymentTopology. + The value is used with other unique identifiers to create a MachineDeployment's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + replicas: + description: |- + Replicas is the number of worker nodes belonging to this set. + If the value is nil, the MachineDeployment is created without the number of Replicas (defaulting to zero) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + required: + - class + - name + type: object + type: array + type: object + required: + - class + - version + type: object + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: ClusterClass of this Cluster, empty if the Cluster is not using a ClusterClass + jsonPath: .spec.topology.class + name: ClusterClass + type: string + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of Cluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this Cluster + jsonPath: .spec.topology.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: |- + APIServerPort specifies the port the API Server should bind to. + Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: |- + ControlPlaneRef is an optional reference to a provider-specific resource that holds + the details for provisioning the Control Plane for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: |- + InfrastructureRef is a reference to a provider-specific resource that holds the details + for provisioning infrastructure for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + type: boolean + topology: + description: |- + This encapsulates the topology for the cluster. + NOTE: It is required to enable the ClusterTopology + feature gate flag to activate managed topologies support; + this feature is highly experimental, and parts of it might still be not implemented. + properties: + class: + description: The name of the ClusterClass object to create the topology. + type: string + controlPlane: + description: ControlPlane describes the cluster control plane. + properties: + machineHealthCheck: + description: |- + MachineHealthCheck allows to enable, disable and override + the MachineHealthCheck configuration in the ClusterClass for this control plane. + properties: + enable: + description: |- + Enable controls if a MachineHealthCheck should be created for the target machines. + + + If false: No MachineHealthCheck will be created. + + + If not set(default): A MachineHealthCheck will be created if it is defined here or + in the associated ClusterClass. If no MachineHealthCheck is defined then none will be created. + + + If true: A MachineHealthCheck is guaranteed to be created. Cluster validation will + block if `enable` is true and no MachineHealthCheck definition is available. + type: boolean + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + metadata: + description: |- + Metadata is the metadata applied to the ControlPlane and the Machines of the ControlPlane + if the ControlPlaneTemplate referenced by the ClusterClass is machine based. If not, it + is applied only to the ControlPlane. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of control plane nodes. + If the value is nil, the ControlPlane object is created without the number of Replicas + and it's assumed that the control plane controller does not implement support for this field. + When specified against a control plane provider that lacks support for this field, this value will be ignored. + format: int32 + type: integer + variables: + description: Variables can be used to customize the ControlPlane through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + type: object + rolloutAfter: + description: |- + RolloutAfter performs a rollout of the entire cluster one component at a time, + control plane first and then machine deployments. + + + Deprecated: This field has no function and is going to be removed in the next apiVersion. + format: date-time + type: string + variables: + description: |- + Variables can be used to customize the Cluster through + patches. They must comply to the corresponding + VariableClasses defined in the ClusterClass. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + version: + description: The Kubernetes version of the cluster. + type: string + workers: + description: |- + Workers encapsulates the different constructs that form the worker nodes + for the cluster. + properties: + machineDeployments: + description: MachineDeployments is a list of machine deployments in the cluster. + items: + description: |- + MachineDeploymentTopology specifies the different parameters for a set of worker nodes in the topology. + This set of nodes is managed by a MachineDeployment object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachineDeploymentClass used to create the set of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machines will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + machineHealthCheck: + description: |- + MachineHealthCheck allows to enable, disable and override + the MachineHealthCheck configuration in the ClusterClass for this MachineDeployment. + properties: + enable: + description: |- + Enable controls if a MachineHealthCheck should be created for the target machines. + + + If false: No MachineHealthCheck will be created. + + + If not set(default): A MachineHealthCheck will be created if it is defined here or + in the associated ClusterClass. If no MachineHealthCheck is defined then none will be created. + + + If true: A MachineHealthCheck is guaranteed to be created. Cluster validation will + block if `enable` is true and no MachineHealthCheck definition is available. + type: boolean + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + type: object + metadata: + description: |- + Metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this MachineDeploymentTopology. + The value is used with other unique identifiers to create a MachineDeployment's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of worker nodes belonging to this set. + If the value is nil, the MachineDeployment is created without the number of Replicas (defaulting to 1) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + variables: + description: Variables can be used to customize the MachineDeployment through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + required: + - class + - name + type: object + type: array + machinePools: + description: MachinePools is a list of machine pools in the cluster. + items: + description: |- + MachinePoolTopology specifies the different parameters for a pool of worker nodes in the topology. + This pool of nodes is managed by a MachinePool object whose lifecycle is managed by the Cluster controller. + properties: + class: + description: |- + Class is the name of the MachinePoolClass used to create the pool of worker nodes. + This should match one of the deployment classes defined in the ClusterClass object + mentioned in the `Cluster.Spec.Class` field. + type: string + failureDomains: + description: |- + FailureDomains is the list of failure domains the machine pool will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + items: + type: string + type: array + metadata: + description: |- + Metadata is the metadata applied to the MachinePool. + At runtime this metadata is merged with the corresponding metadata from the ClusterClass. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine pool should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + name: + description: |- + Name is the unique identifier for this MachinePoolTopology. + The value is used with other unique identifiers to create a MachinePool's Name + (e.g. cluster's name, etc). In case the name is greater than the allowed maximum length, + the values are hashed together. + type: string + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the MachinePool + hosts after the MachinePool is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + replicas: + description: |- + Replicas is the number of nodes belonging to this pool. + If the value is nil, the MachinePool is created without the number of Replicas (defaulting to 1) + and it's assumed that an external entity (like cluster autoscaler) is responsible for the management + of this value. + format: int32 + type: integer + variables: + description: Variables can be used to customize the MachinePool through patches. + properties: + overrides: + description: Overrides can be used to override Cluster level variables. + items: + description: |- + ClusterVariable can be used to customize the Cluster through patches. Each ClusterVariable is associated with a + Variable definition in the ClusterClass `status` variables. + properties: + definitionFrom: + description: |- + DefinitionFrom specifies where the definition of this Variable is from. DefinitionFrom is `inline` when the + definition is from the ClusterClass `.spec.variables` or the name of a patch defined in the ClusterClass + `.spec.patches` where the patch is external and provides external variables. + This field is mandatory if the variable has `DefinitionsConflict: true` in ClusterClass `status.variables[]` + type: string + name: + description: Name of the variable. + type: string + value: + description: |- + Value of the variable. + Note: the value will be validated against the schema of the corresponding ClusterClassVariable + from the ClusterClass. + Note: We have to use apiextensionsv1.JSON instead of a custom JSON type, because controller-tools has a + hard-coded schema for apiextensionsv1.JSON which cannot be produced by another type via controller-tools, + i.e. it is not possible to have no type field. + Ref: https://github.com/kubernetes-sigs/controller-tools/blob/d0e03a142d0ecdd5491593e941ee1d6b5d91dba6/pkg/crd/known_types.go#L106-L111 + x-kubernetes-preserve-unknown-fields: true + required: + - name + - value + type: object + type: array + type: object + required: + - class + - name + type: object + type: array + type: object + required: + - class + - version + type: object + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: |- + FailureDomainSpec is the Schema for Cluster API failure domains. + It allows controllers to understand how many failure domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + type: object + failureMessage: + description: |- + FailureMessage indicates that there is a fatal problem reconciling the + state, and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a fatal problem reconciling the + state, and will be set to a token value suitable for + programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: extensionconfigs.runtime.cluster.x-k8s.io +spec: + group: runtime.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: ExtensionConfig + listKind: ExtensionConfigList + plural: extensionconfigs + shortNames: + - ext + singular: extensionconfig + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Time duration since creation of ExtensionConfig + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ExtensionConfig is the Schema for the ExtensionConfig API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ExtensionConfigSpec is the desired state of the ExtensionConfig + properties: + clientConfig: + description: ClientConfig defines how to communicate with the Extension server. + properties: + caBundle: + description: CABundle is a PEM encoded CA bundle which will be used to validate the Extension server's server certificate. + format: byte + type: string + service: + description: |- + Service is a reference to the Kubernetes service for the Extension server. + Note: Exactly one of `url` or `service` must be specified. + + + If the Extension server is running within a cluster, then you should use `service`. + properties: + name: + description: Name is the name of the service. + type: string + namespace: + description: Namespace is the namespace of the service. + type: string + path: + description: |- + Path is an optional URL path and if present may be any string permissible in + a URL. If a path is set it will be used as prefix to the hook-specific path. + type: string + port: + description: |- + Port is the port on the service that's hosting the Extension server. + Defaults to 443. + Port should be a valid port number (1-65535, inclusive). + format: int32 + type: integer + required: + - name + - namespace + type: object + url: + description: |- + URL gives the location of the Extension server, in standard URL form + (`scheme://host:port/path`). + Note: Exactly one of `url` or `service` must be specified. + + + The scheme must be "https". + + + The `host` should not refer to a service running in the cluster; use + the `service` field instead. + + + A path is optional, and if present may be any string permissible in + a URL. If a path is set it will be used as prefix to the hook-specific path. + + + Attempting to use a user or basic auth e.g. "user:password@" is not + allowed. Fragments ("#...") and query parameters ("?...") are not + allowed either. + type: string + type: object + namespaceSelector: + description: |- + NamespaceSelector decides whether to call the hook for an object based + on whether the namespace for that object matches the selector. + Defaults to the empty LabelSelector, which matches all objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + settings: + additionalProperties: + type: string + description: |- + Settings defines key value pairs to be passed to all calls + to all supported RuntimeExtensions. + Note: Settings can be overridden on the ClusterClass. + type: object + required: + - clientConfig + type: object + status: + description: ExtensionConfigStatus is the current state of the ExtensionConfig + properties: + conditions: + description: Conditions define the current service state of the ExtensionConfig. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + handlers: + description: Handlers defines the current ExtensionHandlers supported by an Extension. + items: + description: ExtensionHandler specifies the details of a handler for a particular runtime hook registered by an Extension server. + properties: + failurePolicy: + description: |- + FailurePolicy defines how failures in calls to the ExtensionHandler should be handled by a client. + Defaults to Fail if not set. + type: string + name: + description: Name is the unique name of the ExtensionHandler. + type: string + requestHook: + description: RequestHook defines the versioned runtime hook which this ExtensionHandler serves. + properties: + apiVersion: + description: APIVersion is the group and version of the Hook. + type: string + hook: + description: Hook is the name of the hook. + type: string + required: + - apiVersion + - hook + type: object + timeoutSeconds: + description: |- + TimeoutSeconds defines the timeout duration for client calls to the ExtensionHandler. + Defaults to 10 is not set. + format: int32 + type: integer + required: + - name + - requestHook + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: ipaddressclaims.ipam.cluster.x-k8s.io +spec: + group: ipam.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: IPAddressClaim + listKind: IPAddressClaimList + plural: ipaddressclaims + singular: ipaddressclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Name of the pool to allocate an address from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool to allocate an address from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdressClaim + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IPAddressClaim is the Schema for the ipaddressclaim API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressClaimSpec is the desired state of an IPAddressClaim. + properties: + poolRef: + description: PoolRef is a reference to the pool from which an IP address should be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - poolRef + type: object + status: + description: IPAddressClaimStatus is the observed status of a IPAddressClaim. + properties: + addressRef: + description: AddressRef is a reference to the address that was created for this claim. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + description: Conditions summarises the current state of the IPAddressClaim + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Name of the pool to allocate an address from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool to allocate an address from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdressClaim + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: IPAddressClaim is the Schema for the ipaddressclaim API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressClaimSpec is the desired state of an IPAddressClaim. + properties: + poolRef: + description: PoolRef is a reference to the pool from which an IP address should be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - poolRef + type: object + status: + description: IPAddressClaimStatus is the observed status of a IPAddressClaim. + properties: + addressRef: + description: AddressRef is a reference to the address that was created for this claim. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + conditions: + description: Conditions summarises the current state of the IPAddressClaim + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: ipaddresses.ipam.cluster.x-k8s.io +spec: + group: ipam.cluster.x-k8s.io + names: + categories: + - cluster-api + kind: IPAddress + listKind: IPAddressList + plural: ipaddresses + singular: ipaddress + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Address + jsonPath: .spec.address + name: Address + type: string + - description: Name of the pool the address is from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool the address is from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdress + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: IPAddress is the Schema for the ipaddress API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressSpec is the desired state of an IPAddress. + properties: + address: + description: Address is the IP address. + type: string + claimRef: + description: ClaimRef is a reference to the claim this IPAddress was created for. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + gateway: + description: Gateway is the network gateway of the network the address is from. + type: string + poolRef: + description: PoolRef is a reference to the pool that this IPAddress was created from. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + prefix: + description: Prefix is the prefix of the address. + type: integer + required: + - address + - claimRef + - poolRef + - prefix + type: object + type: object + served: true + storage: false + subresources: {} + - additionalPrinterColumns: + - description: Address + jsonPath: .spec.address + name: Address + type: string + - description: Name of the pool the address is from + jsonPath: .spec.poolRef.name + name: Pool Name + type: string + - description: Kind of the pool the address is from + jsonPath: .spec.poolRef.kind + name: Pool Kind + type: string + - description: Time duration since creation of IPAdress + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: IPAddress is the Schema for the ipaddress API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: IPAddressSpec is the desired state of an IPAddress. + properties: + address: + description: Address is the IP address. + type: string + claimRef: + description: ClaimRef is a reference to the claim this IPAddress was created for. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + gateway: + description: Gateway is the network gateway of the network the address is from. + type: string + poolRef: + description: PoolRef is a reference to the pool that this IPAddress was created from. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + prefix: + description: Prefix is the prefix of the address. + type: integer + required: + - address + - claimRef + - poolRef + - prefix + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinedeployments.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineDeployment + listKind: MachineDeploymentList + plural: machinedeployments + shortNames: + - md + singular: machinedeployment + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineDeployment is the Schema for the machinedeployments API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Currently the only supported strategy is + "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineDeployment + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineDeployment is the Schema for the machinedeployments API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine should + be ready. + Defaults to 0 (machine will be considered available as soon as it + is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + default: 1 + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. + Default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineDeployment. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this MachineDeployment + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of MachineDeployment + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachineDeployment + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineDeployment is the Schema for the machinedeployments API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. + Defaults to 0 (machine will be considered available as soon as the Node is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: |- + The maximum time in seconds for a deployment to make progress before it + is considered to be failed. The deployment controller will continue to + process failed deployments and a condition with a ProgressDeadlineExceeded + reason will be surfaced in the deployment status. Note that progress will + not be estimated during the time a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + description: |- + Number of desired machines. + This is a pointer to distinguish between explicit zero and not specified. + + + Defaults to: + * if the Kubernetes autoscaler min size and max size annotations are set: + - if it's a new MachineDeployment, use min size + - if the replicas field of the old MachineDeployment is < min size, use min size + - if the replicas field of the old MachineDeployment is > max size, use max size + - if the replicas field of the old MachineDeployment is in the (min size, max size) range, keep the value from the oldMD + * otherwise use 1 + Note: Defaulting will be run whenever the replicas field is not set: + * A new MachineDeployment is created with replicas not set. + * On an existing MachineDeployment the replicas field was first set and is now unset. + Those cases are especially relevant for the following Kubernetes autoscaler use cases: + * A new MachineDeployment is created and replicas should be managed by the autoscaler + * An existing MachineDeployment which initially wasn't controlled by the autoscaler + should be later controlled by the autoscaler + format: int32 + type: integer + revisionHistoryLimit: + description: |- + The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + rolloutAfter: + description: |- + RolloutAfter is a field to indicate a rollout should be performed + after the specified time even if no changes have been made to the + MachineDeployment. + Example: In the YAML the time can be specified in the RFC3339 format. + To specify the rolloutAfter target as March 9, 2023, at 9 am UTC + use "2023-03-09T09:00:00Z". + format: date-time + type: string + selector: + description: |- + Label selector for machines. Existing MachineSets whose machines are + selected by this will be the ones affected by this deployment. + It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: |- + The deployment strategy to use to replace existing machines with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + deletePolicy: + description: |- + DeletePolicy defines the policy used by the MachineDeployment to identify nodes to delete when downscaling. + Valid values are "Random, "Newest", "Oldest" + When no value is supplied, the default DeletePolicy of MachineSet is used + enum: + - Random + - Newest + - Oldest + type: string + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Allowed values are RollingUpdate and OnDelete. + The default is RollingUpdate. + enum: + - RollingUpdate + - OnDelete + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: |- + Total number of available machines (ready for at least minReadySeconds) + targeted by this deployment. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineDeployment. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: |- + Total number of non-terminated machines targeted by this deployment + (their labels match the selector). + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + unavailableReplicas: + description: |- + Total number of unavailable machines targeted by this deployment. + This is the total number of machines that are still required for + the deployment to have 100% available capacity. They may either + be machines that are running but not yet available or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: |- + Total number of non-terminated machines targeted by this deployment + that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinehealthchecks.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineHealthCheck + listKind: MachineHealthCheckList + plural: machinehealthchecks + shortNames: + - mhc + - mhcs + singular: machinehealthcheck + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineHealthCheck is the Schema for the machinehealthchecks API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineHealthCheck + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineHealthCheck is the Schema for the machinehealthchecks API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If not set, this value is defaulted to 10 minutes. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + - description: Time duration since creation of MachineHealthCheck + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineHealthCheck is the Schema for the machinehealthchecks API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: |- + Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: |- + Machines older than this duration without a node will be considered to have + failed and will be remediated. + If not set, this value is defaulted to 10 minutes. + If you wish to disable this feature, set the value explicitly to 0. + type: string + remediationTemplate: + description: |- + RemediationTemplate is a reference to a remediation template + provided by an infrastructure provider. + + + This field is completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off remediation of the machine to + a controller that lives outside of Cluster API. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: |- + UnhealthyConditions contains a list of the conditions that determine + whether a node is considered unhealthy. The conditions are combined in a + logical OR, i.e. if any of the conditions is met, the node is unhealthy. + items: + description: |- + UnhealthyCondition represents a Node condition type and value with a timeout + specified as a duration. When the named condition has been in the given + status for at least the timeout value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + unhealthyRange: + description: |- + Any further remediation is only allowed if the number of machines selected by "selector" as not healthy + is within the range of "UnhealthyRange". Takes precedence over MaxUnhealthy. + Eg. "[3-5]" - This means that remediation will be allowed only when: + (a) there are at least 3 unhealthy machines (and) + (b) there are at most 5 unhealthy machines + pattern: ^\[[0-9]+-[0-9]+\]$ + type: string + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + remediationsAllowed: + description: |- + RemediationsAllowed is the number of further remediations allowed by this machine health check before + maxUnhealthy short circuiting will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine health check is watching + items: + type: string + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinepools.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachinePool + listKind: MachinePoolList + plural: machinepools + shortNames: + - mp + singular: machinepool + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachinePool is the Schema for the machinepools API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + strategy: + description: |- + The deployment strategy to use to replace existing machine instances with + new ones. + properties: + rollingUpdate: + description: |- + Rolling update config params. Present only if + MachineDeploymentStrategyType = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be scheduled above the + desired number of machines. + Value can be an absolute number (ex: 5) or a percentage of + desired machines (ex: 10%). + This can not be 0 if MaxUnavailable is 0. + Absolute number is calculated from percentage by rounding up. + Defaults to 1. + Example: when this is set to 30%, the new MachineSet can be scaled + up immediately when the rolling update starts, such that the total + number of old and new machines do not exceed 130% of desired + machines. Once old machines have been killed, new MachineSet can + be scaled up further, ensuring that total number of machines running + at any time during the update is at most 130% of desired machines. + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: |- + The maximum number of machines that can be unavailable during the update. + Value can be an absolute number (ex: 5) or a percentage of desired + machines (ex: 10%). + Absolute number is calculated from percentage by rounding down. + This can not be 0 if MaxSurge is 0. + Defaults to 0. + Example: when this is set to 30%, the old MachineSet can be scaled + down to 70% of desired machines immediately when the rolling update + starts. Once new machines are ready, old MachineSet can be scaled + down further, followed by scaling up the new MachineSet, ensuring + that the total number of machines available at all times + during the update is at least 70% of desired machines. + x-kubernetes-int-or-string: true + type: object + type: + description: |- + Type of deployment. Currently the only supported strategy is + "RollingUpdate". + Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Time duration since creation of MachinePool + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachinePool is the Schema for the machinepools API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this MachinePool + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of MachinePool + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachinePool is the Schema for the machinepools API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool should be attached to. + items: + type: string + type: array + minReadySeconds: + description: |- + Minimum number of seconds for which a newly created machine instances should + be ready. + Defaults to 0 (machine instance will be considered available as soon as it + is ready) + NOTE: No logic is implemented for this field and it currently has no behaviour. + format: int32 + type: integer + providerIDList: + description: |- + ProviderIDList are the identification IDs of machine instances provided by the provider. + This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + items: + type: string + type: array + replicas: + description: |- + Number of desired machines. Defaults to 1. + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage indicates that there is a problem reconciling the state, + and will be set to a descriptive error message. + type: string + failureReason: + description: |- + FailureReason indicates that there is a problem reconciling the state, and + will be set to a token value suitable for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it they exist. + items: + description: |- + ObjectReference contains enough information to let you inspect or modify the referred object. + --- + New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. + 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. + 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular + restrictions like, "must refer only to types A and B" or "UID not honored" or "name must be restricted". + Those cannot be well described when embedded. + 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. + 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity + during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple + and the version of the actual struct is irrelevant. + 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type + will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. + + + Instead of using this type, create a locally provided and used type that is well-focused on your reference. + For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 . + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: |- + Total number of unavailable machine instances targeted by this machine pool. + This is the total number of machine instances that are still required for + the machine pool to have 100% available capacity. They may either + be machine instances that are running but not yet available or machine instances + that still have not been created. + format: int32 + type: integer + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machines.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: Machine + listKind: MachineList + plural: machines + shortNames: + - ma + singular: machine + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + priority: 1 + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + Machine is the Schema for the machines API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + version: + description: |- + Version specifies the current version of Kubernetes running + on the corresponding Node. This is meant to be a means of bubbling + up status from the Node to the Machine. + It is entirely optional, but useful for end-user UX if it’s present. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of Machine + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + priority: 1 + type: string + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + Machine is the Schema for the machines API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeInfo: + description: |- + NodeInfo is a set of ids/uuids to uniquely identify the node. + More info: https://kubernetes.io/docs/concepts/nodes/node/#info + properties: + architecture: + description: The Architecture reported by the node + type: string + bootID: + description: Boot ID reported by the node. + type: string + containerRuntimeVersion: + description: ContainerRuntime Version reported by the node through runtime remote API (e.g. containerd://1.4.2). + type: string + kernelVersion: + description: Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64). + type: string + kubeProxyVersion: + description: KubeProxy Version reported by the node. + type: string + kubeletVersion: + description: Kubelet Version reported by the node. + type: string + machineID: + description: |- + MachineID reported by the node. For unique machine identification + in the cluster this field is preferred. Learn more from man(5) + machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html + type: string + operatingSystem: + description: The Operating System reported by the node + type: string + osImage: + description: OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)). + type: string + systemUUID: + description: |- + SystemUUID reported by the node. For unique machine identification + MachineID is preferred. This field is specific to Red Hat hosts + https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid + type: string + required: + - architecture + - bootID + - containerRuntimeVersion + - kernelVersion + - kubeProxyVersion + - kubeletVersion + - machineID + - operatingSystem + - osImage + - systemUUID + type: object + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + version: + description: |- + Version specifies the current version of Kubernetes running + on the corresponding Node. This is meant to be a means of bubbling + up status from the Node to the Machine. + It is entirely optional, but useful for end-user UX if it’s present. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + type: string + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Time duration since creation of Machine + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: Machine is the Schema for the machines API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: |- + Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP, InternalIP, ExternalDNS or InternalDNS. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + certificatesExpiryDate: + description: |- + CertificatesExpiryDate is the expiry date of the machine certificates. + This value is only set for control plane machines. + format: date-time + type: string + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + description: |- + FailureMessage will be set in the event that there is a terminal problem + reconciling the Machine and will contain a more verbose string suitable + for logging and human consumption. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + failureReason: + description: |- + FailureReason will be set in the event that there is a terminal problem + reconciling the Machine and will contain a succinct value suitable + for machine interpretation. + + + This field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the Machine's spec or the configuration of + the controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the controller, or the + responsible controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the Machine object and/or logged in the + controller's output. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine last transitioned. + format: date-time + type: string + nodeInfo: + description: |- + NodeInfo is a set of ids/uuids to uniquely identify the node. + More info: https://kubernetes.io/docs/concepts/nodes/node/#info + properties: + architecture: + description: The Architecture reported by the node + type: string + bootID: + description: Boot ID reported by the node. + type: string + containerRuntimeVersion: + description: ContainerRuntime Version reported by the node through runtime remote API (e.g. containerd://1.4.2). + type: string + kernelVersion: + description: Kernel Version reported by the node from 'uname -r' (e.g. 3.16.0-0.bpo.4-amd64). + type: string + kubeProxyVersion: + description: KubeProxy Version reported by the node. + type: string + kubeletVersion: + description: Kubelet Version reported by the node. + type: string + machineID: + description: |- + MachineID reported by the node. For unique machine identification + in the cluster this field is preferred. Learn more from man(5) + machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html + type: string + operatingSystem: + description: The Operating System reported by the node + type: string + osImage: + description: OS Image reported by the node from /etc/os-release (e.g. Debian GNU/Linux 7 (wheezy)). + type: string + systemUUID: + description: |- + SystemUUID reported by the node. For unique machine identification + MachineID is preferred. This field is specific to Red Hat hosts + https://access.redhat.com/documentation/en-us/red_hat_subscription_management/1/html/rhsm/uuid + type: string + required: + - architecture + - bootID + - containerRuntimeVersion + - kernelVersion + - kubeProxyVersion + - kubeletVersion + - machineID + - operatingSystem + - osImage + - systemUUID + type: object + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed by the controller. + format: int64 + type: integer + phase: + description: |- + Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + labels: + cluster.x-k8s.io/provider: cluster-api + name: machinesets.cluster.x-k8s.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: capi-webhook-service + namespace: cattle-provisioning-capi-system + path: /convert + conversionReviewVersions: + - v1 + - v1beta1 + group: cluster.x-k8s.io + names: + categories: + - cluster-api + kind: MachineSet + listKind: MachineSetList + plural: machinesets + shortNames: + - ms + singular: machineset + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: |- + MachineSet is the Schema for the machinesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready. + Defaults to 0 (machine will be considered available as soon as it is ready) + format: int32 + type: integer + replicas: + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + generateName: + description: |- + GenerateName is an optional prefix, used by the server, to generate a unique + name ONLY IF the Name field has not been provided. + If this field is used, the name returned to the client will be different + than the name passed. This value will also be combined with a unique suffix. + The provided value has the same validation rules as the Name field, + and may be truncated by the length of the suffix required to make the value + unique on the server. + + + If this field is specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + ServerTimeout indicating a unique name could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the Retry-After header). + + + Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + name: + description: |- + Name must be unique within a namespace. Is required when creating resources, although + some resources may allow a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence and configuration + definition. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/identifiers#names + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + namespace: + description: |- + Namespace defines the space within each name must be unique. An empty namespace is + equivalent to the "default" namespace, but "default" is the canonical representation. + Not all objects are required to be scoped to a namespace - the value of this field for + those objects will be empty. + + + Must be a DNS_LABEL. + Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + + + Deprecated: This field has no function and is going to be removed in a next release. + type: string + ownerReferences: + description: |- + List of objects depended by this object. If ALL objects in the list have + been deleted, this object will be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, with the controller field set to true. + There cannot be more than one managing controller. + + + Deprecated: This field has no function and is going to be removed in a next release. + items: + description: |- + OwnerReference contains enough information to let you identify an owning + object. An owning object must be in the same namespace as the dependent, or + be cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: |- + If true, AND if the owner has the "foregroundDeletion" finalizer, then + the owner cannot be deleted from the key-value store until this + reference is removed. + See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and enforces the foreground deletion. + Defaults to false. + To set this field, a user needs "delete" permission of the owner, + otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.Data without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: |- + Data contains the bootstrap data, such as cloud-init details scripts. + If nil, the Machine should remain in the Pending state. + + + Deprecated: Switch to DataSecretName. + type: string + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Time duration since creation of MachineSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + deprecated: true + name: v1alpha4 + schema: + openAPIV3Schema: + description: |- + MachineSet is the Schema for the machinesets API. + + + Deprecated: This type will be removed in one of the next releases. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready. + Defaults to 0 (machine will be considered available as soon as it is ready) + format: int32 + type: integer + replicas: + default: 1 + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + Defaults to 1. + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - description: Cluster + jsonPath: .spec.clusterName + name: Cluster + type: string + - description: Total number of machines desired by this machineset + jsonPath: .spec.replicas + name: Desired + priority: 10 + type: integer + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Time duration since creation of MachineSet + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Kubernetes version associated with this MachineSet + jsonPath: .spec.template.spec.version + name: Version + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: MachineSet is the Schema for the machinesets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + deletePolicy: + description: |- + DeletePolicy defines the policy used to identify nodes to delete when downscaling. + Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: |- + MinReadySeconds is the minimum number of seconds for which a Node for a newly created machine should be ready before considering the replica available. + Defaults to 0 (machine will be considered available as soon as the Node is ready) + format: int32 + type: integer + replicas: + description: |- + Replicas is the number of desired replicas. + This is a pointer to distinguish between explicit zero and unspecified. + + + Defaults to: + * if the Kubernetes autoscaler min size and max size annotations are set: + - if it's a new MachineSet, use min size + - if the replicas field of the old MachineSet is < min size, use min size + - if the replicas field of the old MachineSet is > max size, use max size + - if the replicas field of the old MachineSet is in the (min size, max size) range, keep the value from the oldMS + * otherwise use 1 + Note: Defaulting will be run whenever the replicas field is not set: + * A new MachineSet is created with replicas not set. + * On an existing MachineSet the replicas field was first set and is now unset. + Those cases are especially relevant for the following Kubernetes autoscaler use cases: + * A new MachineSet is created and replicas should be managed by the autoscaler + * An existing MachineSet which initially wasn't controlled by the autoscaler + should be later controlled by the autoscaler + format: int32 + type: integer + selector: + description: |- + Selector is a label query over machines that should match the replica count. + Label keys and values that must match in order to be controlled by this MachineSet. + It must match the machine template's labels. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: |- + Template is the object that describes the machine that will be created if + insufficient replicas are detected. + Object references to custom resources are treated as templates. + properties: + metadata: + description: |- + Standard object's metadata. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: http://kubernetes.io/docs/user-guide/annotations + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. May match selectors of replication controllers + and services. + More info: http://kubernetes.io/docs/user-guide/labels + type: object + type: object + spec: + description: |- + Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bootstrap: + description: |- + Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: |- + ConfigRef is a reference to a bootstrap provider-specific resource + that holds configuration details. The reference is optional to + allow users/operators to specify Bootstrap.DataSecretName without + the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + dataSecretName: + description: |- + DataSecretName is the name of the secret that stores the bootstrap data script. + If nil, the Machine should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs to. + minLength: 1 + type: string + failureDomain: + description: |- + FailureDomain is the failure domain the machine will be created in. + Must match a key in the FailureDomains map stored on the cluster object. + type: string + infrastructureRef: + description: |- + InfrastructureRef is a required reference to a custom resource + offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + TODO: this design is not final and this field is subject to change in the future. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + nodeDeletionTimeout: + description: |- + NodeDeletionTimeout defines how long the controller will attempt to delete the Node that the Machine + hosts after the Machine is marked for deletion. A duration of 0 will retry deletion indefinitely. + Defaults to 10 seconds. + type: string + nodeDrainTimeout: + description: |- + NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + The default value is 0, meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + type: string + nodeVolumeDetachTimeout: + description: |- + NodeVolumeDetachTimeout is the total amount of time that the controller will spend on waiting for all volumes + to be detached. The default value is 0, meaning that the volumes can be detached without any time limitations. + type: string + providerID: + description: |- + ProviderID is the identification ID of the machine provided by the provider. + This field must match the provider ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: |- + Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + format: int32 + type: integer + conditions: + description: Conditions defines current service state of the MachineSet. + items: + description: Condition defines an observation of a Cluster API resource operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + A human readable message indicating details about the transition. + This field may be empty. + type: string + reason: + description: |- + The reason for the condition's last transition in CamelCase. + The specific API may choose whether or not this field is considered a guaranteed API. + This field may not be empty. + type: string + severity: + description: |- + Severity provides an explicit classification of Reason code, so the users or machines can immediately + understand the current situation and act accordingly. + The Severity field MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: |- + Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + can be useful (see .node.status.conditions), the ability to deconflict is important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + failureMessage: + type: string + failureReason: + description: |- + In the event that there is a terminal problem reconciling the + replicas, both FailureReason and FailureMessage will be set. FailureReason + will be populated with a succinct value suitable for machine + interpretation, while FailureMessage will contain a more verbose + string suitable for logging and human consumption. + + + These fields should not be set for transitive errors that a + controller faces that are expected to be fixed automatically over + time (like service outages), but instead indicate that something is + fundamentally wrong with the MachineTemplate's spec or the configuration of + the machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in the + spec, values that are unsupported by the machine controller, or the + responsible machine controller itself being critically misconfigured. + + + Any transient errors that occur during the reconciliation of Machines + can be added as events to the MachineSet object and/or logged in the + controller's output. + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: |- + Selector is the same as the label selector but in the string format to avoid introspection + by clients. The string will be in the same format as the query-param syntax. + More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/fleet/fleet.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/fleet/fleet.yaml new file mode 100644 index 0000000..39682f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/fleet/fleet.yaml @@ -0,0 +1,1941 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + labels: + app.kubernetes.io/managed-by: Helm + name: bundles.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: Bundle + listKind: BundleList + plural: bundles + singular: bundle + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + defaultNamespace: + nullable: true + type: string + dependsOn: + items: + properties: + name: + nullable: true + type: string + selector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + type: object + nullable: true + type: array + diff: + nullable: true + properties: + comparePatches: + items: + properties: + apiVersion: + nullable: true + type: string + jsonPointers: + items: + nullable: true + type: string + nullable: true + type: array + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + operations: + items: + properties: + op: + nullable: true + type: string + path: + nullable: true + type: string + value: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + forceSyncGeneration: + type: integer + helm: + nullable: true + properties: + atomic: + type: boolean + chart: + nullable: true + type: string + disablePreProcess: + type: boolean + force: + type: boolean + maxHistory: + type: integer + releaseName: + nullable: true + type: string + repo: + nullable: true + type: string + takeOwnership: + type: boolean + timeoutSeconds: + type: integer + values: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + valuesFiles: + items: + nullable: true + type: string + nullable: true + type: array + valuesFrom: + items: + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + type: object + nullable: true + type: array + version: + nullable: true + type: string + waitForJobs: + type: boolean + type: object + ignore: + properties: + conditions: + items: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + nullable: true + type: array + type: object + keepResources: + type: boolean + kustomize: + nullable: true + properties: + dir: + nullable: true + type: string + type: object + namespace: + nullable: true + type: string + paused: + type: boolean + resources: + items: + properties: + content: + nullable: true + type: string + encoding: + nullable: true + type: string + name: + nullable: true + type: string + type: object + nullable: true + type: array + rolloutStrategy: + nullable: true + properties: + autoPartitionSize: + nullable: true + type: string + maxUnavailable: + nullable: true + type: string + maxUnavailablePartitions: + nullable: true + type: string + partitions: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + maxUnavailable: + nullable: true + type: string + name: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + serviceAccount: + nullable: true + type: string + targetRestrictions: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + name: + nullable: true + type: string + type: object + nullable: true + type: array + targets: + items: + properties: + clusterGroup: + nullable: true + type: string + clusterGroupSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + clusterName: + nullable: true + type: string + clusterSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + defaultNamespace: + nullable: true + type: string + diff: + nullable: true + properties: + comparePatches: + items: + properties: + apiVersion: + nullable: true + type: string + jsonPointers: + items: + nullable: true + type: string + nullable: true + type: array + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + operations: + items: + properties: + op: + nullable: true + type: string + path: + nullable: true + type: string + value: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + forceSyncGeneration: + type: integer + helm: + nullable: true + properties: + atomic: + type: boolean + chart: + nullable: true + type: string + disablePreProcess: + type: boolean + force: + type: boolean + maxHistory: + type: integer + releaseName: + nullable: true + type: string + repo: + nullable: true + type: string + takeOwnership: + type: boolean + timeoutSeconds: + type: integer + values: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + valuesFiles: + items: + nullable: true + type: string + nullable: true + type: array + valuesFrom: + items: + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + type: object + nullable: true + type: array + version: + nullable: true + type: string + waitForJobs: + type: boolean + type: object + ignore: + properties: + conditions: + items: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + nullable: true + type: array + type: object + keepResources: + type: boolean + kustomize: + nullable: true + properties: + dir: + nullable: true + type: string + type: object + name: + nullable: true + type: string + namespace: + nullable: true + type: string + serviceAccount: + nullable: true + type: string + yaml: + nullable: true + properties: + overlays: + items: + nullable: true + type: string + nullable: true + type: array + type: object + type: object + nullable: true + type: array + yaml: + nullable: true + properties: + overlays: + items: + nullable: true + type: string + nullable: true + type: array + type: object + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + display: + properties: + readyClusters: + nullable: true + type: string + state: + nullable: true + type: string + type: object + maxNew: + type: integer + maxUnavailable: + type: integer + maxUnavailablePartitions: + type: integer + newlyCreated: + type: integer + observedGeneration: + type: integer + partitions: + items: + properties: + count: + type: integer + maxUnavailable: + type: integer + name: + nullable: true + type: string + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + unavailable: + type: integer + type: object + nullable: true + type: array + resourceKey: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + type: object + nullable: true + type: array + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + unavailable: + type: integer + unavailablePartitions: + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + generation: 1 + labels: + app.kubernetes.io/managed-by: Helm + name: clusters.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: Cluster + listKind: ClusterList + plural: clusters + singular: cluster + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + agentAffinity: + nullable: true + properties: + nodeAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchFields: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + nullable: true + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchFields: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + nullable: true + type: array + type: object + type: object + podAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + podAntiAffinity: + nullable: true + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + weight: + type: integer + type: object + nullable: true + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaceSelector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + namespaces: + items: + nullable: true + type: string + nullable: true + type: array + topologyKey: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + type: object + agentEnvVars: + items: + properties: + name: + nullable: true + type: string + value: + nullable: true + type: string + valueFrom: + nullable: true + properties: + configMapKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + optional: + nullable: true + type: boolean + type: object + fieldRef: + nullable: true + properties: + apiVersion: + nullable: true + type: string + fieldPath: + nullable: true + type: string + type: object + resourceFieldRef: + nullable: true + properties: + containerName: + nullable: true + type: string + divisor: + nullable: true + type: string + resource: + nullable: true + type: string + type: object + secretKeyRef: + nullable: true + properties: + key: + nullable: true + type: string + name: + nullable: true + type: string + optional: + nullable: true + type: boolean + type: object + type: object + type: object + nullable: true + type: array + agentNamespace: + nullable: true + type: string + agentResources: + nullable: true + properties: + limits: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + requests: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + agentTolerations: + items: + properties: + effect: + nullable: true + type: string + key: + nullable: true + type: string + operator: + nullable: true + type: string + tolerationSeconds: + nullable: true + type: integer + value: + nullable: true + type: string + type: object + nullable: true + type: array + clientID: + nullable: true + type: string + kubeConfigSecret: + nullable: true + type: string + paused: + type: boolean + privateRepoURL: + nullable: true + type: string + redeployAgentGeneration: + type: integer + templateValues: + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + status: + properties: + agent: + properties: + lastSeen: + nullable: true + type: string + namespace: + nullable: true + type: string + nonReadyNodeNames: + items: + nullable: true + type: string + nullable: true + type: array + nonReadyNodes: + type: integer + readyNodeNames: + items: + nullable: true + type: string + nullable: true + type: array + readyNodes: + type: integer + type: object + agentAffinityHash: + nullable: true + type: string + agentDeployedGeneration: + nullable: true + type: integer + agentEnvVarsHash: + nullable: true + type: string + agentMigrated: + type: boolean + agentNamespaceMigrated: + type: boolean + agentPrivateRepoURL: + nullable: true + type: string + agentResourcesHash: + nullable: true + type: string + agentTolerationsHash: + nullable: true + type: string + cattleNamespaceMigrated: + type: boolean + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + desiredReadyGitRepos: + type: integer + display: + properties: + readyBundles: + nullable: true + type: string + readyNodes: + nullable: true + type: string + sampleNode: + nullable: true + type: string + state: + nullable: true + type: string + type: object + namespace: + nullable: true + type: string + readyGitRepos: + type: integer + resourceCounts: + properties: + desiredReady: + type: integer + missing: + type: integer + modified: + type: integer + notReady: + type: integer + orphaned: + type: integer + ready: + type: integer + unknown: + type: integer + waitApplied: + type: integer + type: object + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: Cluster + listKind: ClusterList + plural: clusters + singular: cluster + conditions: + - lastTransitionTime: "2023-06-11T00:57:59Z" + message: no conflicts found + reason: NoConflicts + status: "True" + type: NamesAccepted + - lastTransitionTime: "2023-06-11T00:57:59Z" + message: the initial names have been accepted + reason: InitialNamesAccepted + status: "True" + type: Established + storedVersions: + - v1alpha1 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + meta.helm.sh/release-name: fleet-crd + meta.helm.sh/release-namespace: cattle-fleet-system + generation: 1 + labels: + app.kubernetes.io/managed-by: Helm + name: clustergroups.fleet.cattle.io +spec: + conversion: + strategy: None + group: fleet.cattle.io + names: + kind: ClusterGroup + listKind: ClusterGroupList + plural: clustergroups + singular: clustergroup + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + selector: + nullable: true + properties: + matchExpressions: + items: + properties: + key: + nullable: true + type: string + operator: + nullable: true + type: string + values: + items: + nullable: true + type: string + nullable: true + type: array + type: object + nullable: true + type: array + matchLabels: + additionalProperties: + nullable: true + type: string + nullable: true + type: object + type: object + type: object + status: + properties: + clusterCount: + type: integer + conditions: + items: + properties: + lastTransitionTime: + nullable: true + type: string + lastUpdateTime: + nullable: true + type: string + message: + nullable: true + type: string + reason: + nullable: true + type: string + status: + nullable: true + type: string + type: + nullable: true + type: string + type: object + nullable: true + type: array + display: + properties: + readyBundles: + nullable: true + type: string + readyClusters: + nullable: true + type: string + state: + nullable: true + type: string + type: object + nonReadyClusterCount: + type: integer + nonReadyClusters: + items: + nullable: true + type: string + nullable: true + type: array + resourceCounts: + properties: + desiredReady: + type: integer + missing: + type: integer + modified: + type: integer + notReady: + type: integer + orphaned: + type: integer + ready: + type: integer + unknown: + type: integer + waitApplied: + type: integer + type: object + summary: + properties: + desiredReady: + type: integer + errApplied: + type: integer + modified: + type: integer + nonReadyResources: + items: + properties: + bundleState: + nullable: true + type: string + message: + nullable: true + type: string + modifiedStatus: + items: + properties: + apiVersion: + nullable: true + type: string + delete: + type: boolean + kind: + nullable: true + type: string + missing: + type: boolean + name: + nullable: true + type: string + namespace: + nullable: true + type: string + patch: + nullable: true + type: string + type: object + nullable: true + type: array + name: + nullable: true + type: string + nonReadyStatus: + items: + properties: + apiVersion: + nullable: true + type: string + kind: + nullable: true + type: string + name: + nullable: true + type: string + namespace: + nullable: true + type: string + summary: + properties: + error: + type: boolean + message: + items: + nullable: true + type: string + nullable: true + type: array + state: + nullable: true + type: string + transitioning: + type: boolean + type: object + uid: + nullable: true + type: string + type: object + nullable: true + type: array + type: object + nullable: true + type: array + notReady: + type: integer + outOfSync: + type: integer + pending: + type: integer + ready: + type: integer + waitApplied: + type: integer + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: ClusterGroup + listKind: ClusterGroupList + plural: clustergroups + singular: clustergroup + conditions: + - lastTransitionTime: "2023-06-11T01:18:50Z" + message: no conflicts found + reason: NoConflicts + status: "True" + type: NamesAccepted + - lastTransitionTime: "2023-06-11T01:18:50Z" + message: the initial names have been accepted + reason: InitialNamesAccepted + status: "True" + type: Established + storedVersions: + - v1alpha1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_globalrolebindings.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_globalrolebindings.yaml new file mode 100644 index 0000000..4d1514f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_globalrolebindings.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: globalrolebindings.management.cattle.io +spec: + group: management.cattle.io + names: + kind: GlobalRoleBinding + listKind: GlobalRoleBindingList + plural: globalrolebindings + singular: globalrolebinding + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + globalRoleName: + type: string + groupPrincipalName: + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + userName: + type: string + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_roletemplates.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_roletemplates.yaml new file mode 100644 index 0000000..57ccff0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crds/yaml_test/yaml/generated/management.cattle.io_roletemplates.yaml @@ -0,0 +1,113 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.0 + name: roletemplates.management.cattle.io +spec: + group: management.cattle.io + names: + kind: RoleTemplate + listKind: RoleTemplateList + plural: roletemplates + singular: roletemplate + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + properties: + administrative: + type: boolean + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + builtin: + type: boolean + clusterCreatorDefault: + type: boolean + context: + type: string + description: + type: string + displayName: + type: string + external: + type: boolean + hidden: + type: boolean + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + locked: + type: boolean + metadata: + type: object + projectCreatorDefault: + type: boolean + roleTemplateNames: + items: + type: string + type: array + rules: + items: + description: PolicyRule holds information that describes a policy rule, + but does not contain information about who the rule applies to or + which namespace the rule applies to. + properties: + apiGroups: + description: APIGroups is the name of the APIGroup that contains + the resources. If multiple API groups are specified, any action + requested against one of the enumerated resources in any API group + will be allowed. "" represents the core API group and "*" represents + all API groups. + items: + type: string + type: array + nonResourceURLs: + description: NonResourceURLs is a set of partial urls that a user + should have access to. *s are allowed, but only as the full, + final step in the path Since non-resource URLs are not namespaced, + this field is only applicable for ClusterRoles referenced from + a ClusterRoleBinding. Rules can either apply to API resources + (such as "pods" or "secrets") or non-resource URL paths (such + as "/api"), but not both. + items: + type: string + type: array + resourceNames: + description: ResourceNames is an optional white list of names that + the rule applies to. An empty set means that everything is allowed. + items: + type: string + type: array + resources: + description: Resources is a list of resources this rule applies + to. '*' represents all resources. + items: + type: string + type: array + verbs: + description: Verbs is a list of Verbs that apply to ALL the ResourceKinds + contained in this rule. '*' represents all verbs. + items: + type: string + type: array + required: + - verbs + type: object + type: array + required: + - builtin + - context + - description + - external + - hidden + type: object + served: true + storage: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cron/jailsync.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cron/jailsync.go new file mode 100644 index 0000000..24b48c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/cron/jailsync.go @@ -0,0 +1,85 @@ +package cron + +import ( + "fmt" + "io/ioutil" + "os" + "path" + + "github.com/sirupsen/logrus" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/robfig/cron" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + cronSchedule = "0 0 * * *" // every 24 hours + jailPath = "/opt/jail" +) + +type jailSync struct { + clusters v3.ClusterInterface +} + +// StartJailSyncCron for cleaning up the /opt/jail dir +func StartJailSyncCron(scaledContext *config.ScaledContext) error { + ref := &jailSync{ + clusters: scaledContext.Management.Clusters(""), + } + + schedule, err := cron.ParseStandard(cronSchedule) + if err != nil { + return fmt.Errorf("error parsing auth refresh cron: %v", err) + } + + c := cron.New() + job := cron.FuncJob(ref.syncJails) + c.Schedule(schedule, job) + c.Start() + + return nil +} + +// syncJails removes any unneeded jails from old clusters. +func (j *jailSync) syncJails() { + // Get the clusters from the api to ensure we are up to date + clusters, err := j.clusters.List(metav1.ListOptions{}) + if err != nil { + logrus.Warnf("Error listing clusters for jail cleanup: %v", err) + } + + clusterMap := make(map[string]v3.Cluster) + for _, cluster := range clusters.Items { + clusterMap[cluster.Name] = cluster + } + + files, err := ioutil.ReadDir(jailPath) + if err != nil { + if !os.IsNotExist(err) { + logrus.Warnf("Error attempting to get files for jail cleanup: %v", err) + } + // The dir doesn't exist, nothing to do + return + } + + for _, file := range files { + if file.IsDir() { + dirName := file.Name() + // Don't drop the KE driver jail + if dirName == "driver-jail" { + continue + } + + // If the dir doesn't have a corresponding cluster delete it + if _, ok := clusterMap[dirName]; !ok { + clusterPath := path.Join(jailPath, dirName) + err = os.RemoveAll(clusterPath) + if err != nil { + logrus.Warnf("Error attempting to delete jail %v: %v", clusterPath, err) + } + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon.go new file mode 100644 index 0000000..73c7523 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon.go @@ -0,0 +1,154 @@ +package crondaemon + +import ( + "context" + "fmt" + "sync" + "sync/atomic" + + "github.com/robfig/cron" + "github.com/sirupsen/logrus" +) + +// runner defines the cron runner. +type runner interface { + Start() + Stop() + Schedule(cron.Schedule, cron.Job) +} + +// RunFunc is the function that is run by the daemon on the schedule. +type RunFunc func(context.Context) error + +// Daemon runs a runFunc on a cron schedule. +type Daemon struct { + mu sync.Mutex + ctx context.Context // The context to pass on each run invocation. + name string // The name of the daemon. + run RunFunc // The function to run on the cron schedule. + runner runner // The cron runner instance. + newRunner func() runner // The function that instantiates a new cron runner. + lastExp string // The last successfully applied cron expression. + running bool // True if the daemon was successfully scheduled and is running. + everScheduled bool // True if the daemon was ever scheduled. + done chan struct{} // The channel that is closed when the daemon is disabled by passing an empty cron expression. + runInProgress atomic.Bool // True if the run function is currently running. +} + +// New creates a new daemon instance. +func New(ctx context.Context, name string, run RunFunc) *Daemon { + return &Daemon{ + ctx: ctx, + name: name, + run: run, + newRunner: func() runner { + return cron.New() + }, + } +} + +// Schedule the daemon with the new cron expression. +// If the cron expression is empty, the daemon is stopped/disabled. +// Subsequent calls with the same cron expression are no-op. +// The daemon logs initial and all effective schedule calls using info level +// and errors returned by the run function using error level. +func (d *Daemon) Schedule(exp string) error { + d.mu.Lock() + defer d.mu.Unlock() + + if d.ctx.Err() != nil { + return nil + } + + if (!d.everScheduled || d.running) && exp == "" { + d.everScheduled = true + logrus.Info(d.withPrefix("daemon is disabled")) + } + + if d.running && exp == d.lastExp || + !d.running && exp == "" { + return nil + } + + if exp == "" { + if d.runner != nil { + d.runner.Stop() + } + close(d.done) + d.lastExp = "" + d.running = false + + return nil + } + + schedule, err := ParseCron(exp) + if err != nil { + return err + } + + d.lastExp = exp + d.everScheduled = true + + logrus.Info(d.withPrefix("daemon is scheduled with '" + exp + "'")) + + if d.runner != nil { + d.runner.Stop() + } + d.runner = d.newRunner() + d.runner.Schedule(schedule, cron.FuncJob(func() { + if d.runInProgress.Load() { + return // Skip if it the previous run is still in progress. + } + d.runInProgress.Store(true) + defer d.runInProgress.Store(false) + + if err := d.run(d.ctx); err != nil { + logrus.Error(d.withPrefix(err.Error())) + } + })) + d.runner.Start() + + d.done = make(chan struct{}) + if !d.running { + go func() { + select { + case <-d.done: + return + case <-d.ctx.Done(): + logrus.Info(d.withPrefix("context cancelled, stopping daemon")) + + d.mu.Lock() + defer d.mu.Unlock() + if d.runner != nil { + d.runner.Stop() + } + } + }() + } + d.running = true + + return nil +} + +// withPrefix is a helper that adds the daemon name to log messages. +func (d *Daemon) withPrefix(msg string) string { + if d.name == "" { + return msg + } + + return d.name + ": " + msg +} + +// ParseCron parses a cron expression. +func ParseCron(exp string) (cron.Schedule, error) { + if exp == "" { + return nil, nil + } + + schedule, err := cron.ParseStandard(exp) + if err != nil { + return nil, fmt.Errorf("error parsing cron: %w", err) + } + + return schedule, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon_test.go new file mode 100644 index 0000000..21075c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/crondaemon/daemon_test.go @@ -0,0 +1,326 @@ +package crondaemon + +import ( + "context" + "sync/atomic" + "testing" + "time" + + "github.com/robfig/cron" +) + +type fakeCronRunner struct { + ch chan time.Time + done chan struct{} + job cron.Job + running bool +} + +func (f *fakeCronRunner) Start() { + f.done = make(chan struct{}) + go func() { + for { + select { + case <-f.ch: + if f.job != nil { + go f.job.Run() + } + case <-f.done: + return + } + } + }() + f.running = true +} + +func (f *fakeCronRunner) Stop() { + if f.running { + close(f.done) + f.running = false + } +} + +func (f *fakeCronRunner) Schedule(_ cron.Schedule, job cron.Job) { + f.job = job +} + +func (f *fakeCronRunner) Wait() { + <-f.done +} + +func TestNew(t *testing.T) { + // This is a slow test that exercises the real cron runner. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var ran atomic.Uint32 + + daemon := New(ctx, "testdaemon", func(ctx context.Context) error { + ran.Add(1) + return nil + }) + + err := daemon.Schedule("@every 1s") + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second + 250*time.Millisecond) + if ran.Load() < 1 { + t.Errorf("Expected to run at least once") + } +} + +func TestScheduleAndDisable(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var ( + ran atomic.Uint32 + fakeRunner *fakeCronRunner + ) + + timeCh := make(chan time.Time) + defer close(timeCh) + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + fakeRunner = &fakeCronRunner{ch: timeCh} + return fakeRunner + }, + run: func(ctx context.Context) error { + ran.Add(1) + return nil + }, + } + + err := daemon.Schedule("") // This should have no effect. + if err != nil { + t.Fatal(err) + } + if fakeRunner != nil { + t.Fatal("Expected runner to not be running") + } + + err = daemon.Schedule("@every 1s") + if err != nil { + t.Fatal(err) + } + if fakeRunner == nil { + t.Fatal("Expected runner to not be nil") + } + if !fakeRunner.running { + t.Fatal("Expected runner to be running") + } + + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + if ran.Load() < 1 { + t.Errorf("Expected to run at least once") + } + + err = daemon.Schedule("@every 2s") + if err != nil { + t.Fatal(err) + } + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + if ran.Load() < 2 { + t.Errorf("Expected to run at least twice") + } + + err = daemon.Schedule("") + if err != nil { + t.Fatal(err) + } + + fakeRunner.Wait() + if fakeRunner.running { + t.Fatal("Expected runner to be stopped") + } +} + +func TestScheduleAndCancelContext(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var ( + ran atomic.Uint32 + fakeRunner *fakeCronRunner + ) + + timeCh := make(chan time.Time) + defer close(timeCh) + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + fakeRunner = &fakeCronRunner{ch: timeCh} + return fakeRunner + }, + run: func(ctx context.Context) error { + ran.Add(1) + return nil + }, + } + + daemon.Schedule("@every 1s") + if fakeRunner == nil { + t.Fatal("Expected runner to not be nil") + } + + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + if ran.Load() < 1 { + t.Errorf("Expected to run at least once") + } + + cancel() + + fakeRunner.Wait() + if fakeRunner.running { + t.Fatal("Expected runner to be stopped") + } +} + +func TestConcurrentRuns(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var ( + ran atomic.Uint32 + fakeRunner *fakeCronRunner + ) + + timeCh := make(chan time.Time) + defer close(timeCh) + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + fakeRunner = &fakeCronRunner{ch: timeCh} + return fakeRunner + }, + run: func(ctx context.Context) error { + ran.Add(1) + time.Sleep(250 * time.Millisecond) + return nil + }, + } + + daemon.Schedule("@every 1s") + if fakeRunner == nil { + t.Fatal("Expected runner to not be nil") + } + + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + + timeCh <- time.Now() + time.Sleep(600 * time.Millisecond) + + if want, got := uint32(1), ran.Load(); want != got { + t.Errorf("Expected to run %d got %d", want, got) + } +} + +func TestScheduleWithCanceledContext(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + t.Fatal("Unexpected call to newRunner") + return nil + }, + } + + daemon.Schedule("@every 1s") +} + +func TestScheduleWithInvalidCronExpression(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + t.Fatal("Unexpected call to newRunner") + return nil + }, + } + + err := daemon.Schedule("foo") + if err == nil { + t.Error("Expected error") + } +} + +func TestRescheduleWithInvalidCronExpression(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + var ( + ran atomic.Uint32 + fakeRunner *fakeCronRunner + ) + + timeCh := make(chan time.Time) + defer close(timeCh) + + daemon := &Daemon{ + ctx: ctx, + newRunner: func() runner { + fakeRunner = &fakeCronRunner{ch: timeCh} + return fakeRunner + }, + run: func(ctx context.Context) error { + ran.Add(1) + return nil + }, + } + + daemon.Schedule("@every 1s") + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + + err := daemon.Schedule("foo") // This should have no effect. + if err == nil { + t.Error("Expected error") + } + + timeCh <- time.Now() + time.Sleep(100 * time.Millisecond) + + if ran.Load() < 2 { + t.Errorf("Expected to run at least twice") + } +} + +func TestParseCron(t *testing.T) { + schedule, err := ParseCron("") + if err != nil { + t.Fatal(err) + } + if schedule != nil { + t.Fatal("Expected schedule to be nil") + } + + schedule, err = ParseCron("0 0 * * *") + if err != nil { + t.Fatal(err) + } + if schedule == nil { + t.Fatal("Expected schedule not be be nil") + } + + schedule, err = ParseCron("invalid") + if err == nil { + t.Fatal("Expected error") + } + if schedule != nil { + t.Fatal("Expected schedule to be nil") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/add.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/add.go new file mode 100644 index 0000000..75d9a78 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/add.go @@ -0,0 +1,45 @@ +package dashboard + +import ( + "context" + + "github.com/rancher/rancher/pkg/data/management" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/wrangler" + "k8s.io/client-go/kubernetes" +) + +func EarlyData(ctx context.Context, k8s kubernetes.Interface) error { + return addCattleGlobalNamespaces(ctx, k8s) +} + +func Add(ctx context.Context, wrangler *wrangler.Context, addLocal, removeLocal, embedded bool) error { + if !features.MCMAgent.Enabled() { + if _, err := management.BootstrapAdmin(wrangler); err != nil { + return err + } + } + if addLocal { + if err := addLocalCluster(embedded, wrangler); err != nil { + return err + } + } else if removeLocal { + if err := removeLocalCluster(wrangler); err != nil { + return err + } + } + + if err := addSetting(); err != nil { + return err + } + + if err := addRepos(ctx, wrangler); err != nil { + return err + } + + if err := AddFleetRoles(wrangler); err != nil { + return err + } + + return addUnauthenticatedRoles(wrangler.Apply) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/cluster_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/cluster_data.go new file mode 100644 index 0000000..a05a278 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/cluster_data.go @@ -0,0 +1,90 @@ +package dashboard + +import ( + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + fleetconst "github.com/rancher/rancher/pkg/fleet" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +func addLocalCluster(embedded bool, wrangler *wrangler.Context) error { + c := &v3.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: "local", + }, + Spec: v32.ClusterSpec{ + Internal: true, + DisplayName: "local", + FleetWorkspaceName: fleetconst.ClustersLocalNamespace, + ClusterSpecBase: v32.ClusterSpecBase{ + DockerRootDir: settings.InitialDockerRootDir.Get(), + }, + }, + Status: v32.ClusterStatus{ + Driver: v32.ClusterDriverImported, + Conditions: []v32.ClusterCondition{ + { + Type: "Ready", + Status: corev1.ConditionTrue, + }, + }, + }, + } + if embedded { + c.Status.Driver = v32.ClusterDriverLocal + } + + var err error + err = wait.PollImmediateInfinite(100*time.Millisecond, func() (bool, error) { + temporaryCluster, err := wrangler.Mgmt.Cluster().Create(c) + if err == nil { + c = temporaryCluster + return true, nil + } else if apierrors.IsAlreadyExists(err) { + temporaryCluster, err = wrangler.Mgmt.Cluster().Get("local", v1.GetOptions{}) + if err == nil { + c = temporaryCluster + return true, nil + } + } + if apierrors.IsServiceUnavailable(err) || apierrors.IsInternalError(err) { + return false, nil + } + return false, err + }) + if err != nil { + return err + } + + _, err = wrangler.Core.Namespace().Create(&corev1.Namespace{ + ObjectMeta: v1.ObjectMeta{ + Name: "local", + OwnerReferences: []v1.OwnerReference{ + { + APIVersion: v32.SchemeGroupVersion.String(), + Kind: c.Kind, + Name: c.Name, + UID: c.UID, + }, + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + return nil + } + + return err +} + +func removeLocalCluster(wrangler *wrangler.Context) error { + // Ignore error + _ = wrangler.Mgmt.Cluster().Delete("local", &v1.DeleteOptions{}) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/fleet.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/fleet.go new file mode 100644 index 0000000..c4976e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/fleet.go @@ -0,0 +1,220 @@ +package dashboard + +import ( + "reflect" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + mngtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/wrangler" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + v1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + adminRole = "fleetworkspace-admin" + memberRole = "fleetworkspace-member" + readonlyRole = "fleetworkspace-readonly" + apiServiceName = "git-webhook" +) + +func AddFleetRoles(wrangler *wrangler.Context) error { + f, err := wrangler.Mgmt.Feature().Get("fleet", metav1.GetOptions{}) + if err != nil { + return err + } + + if !features.IsEnabled(f) { + toDeleteClusterRole := []string{ + adminRole, + memberRole, + readonlyRole, + } + for _, name := range toDeleteClusterRole { + if err := wrangler.RBAC.ClusterRole().Delete(name, &metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return err + } + } + + if err := wrangler.Mgmt.APIService().Delete(apiServiceName, &metav1.DeleteOptions{}); err != nil && !errors.IsNotFound(err) { + return err + } + + return nil + } + + if err := ensureWebhookAPIService(wrangler.Mgmt.APIService()); err != nil { + return err + } + + return ensureFleetRoles(wrangler.RBAC) +} + +func ensureWebhookAPIService(apiservices mngtv3.APIServiceClient) error { + apiService := &v3.APIService{ + ObjectMeta: metav1.ObjectMeta{ + Name: apiServiceName, + }, + + Spec: v3.APIServiceSpec{ + SecretName: "stv-aggregation", + SecretNamespace: fleetconst.ReleaseNamespace, + Paths: []string{ + "/fleet/webhook", + }, + }, + } + + existing, err := apiservices.Get(apiService.Name, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + if _, err := apiservices.Create(apiService); err != nil { + return err + } + } else { + if !reflect.DeepEqual(existing.Spec, apiService.Spec) { + existing.Spec = apiService.Spec + if _, err := apiservices.Update(existing); err != nil { + return err + } + } + } + return nil +} + +func ensureFleetRoles(rbac rbacv1.Interface) error { + uiLabels := map[string]string{ + "management.cattle.io/ui-product": "fleet", + } + fleetWorkspaceAdminRole := v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: adminRole, + Labels: uiLabels, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{ + "fleet.cattle.io", + }, + Resources: []string{ + "clusterregistrationtokens", + "gitreporestrictions", + "clusterregistrations", + "clusters", + "gitrepos", + "bundles", + "clustergroups", + }, + Verbs: []string{ + "*", + }, + }, + { + APIGroups: []string{ + "rbac.authorization.k8s.io", + }, + Resources: []string{ + "rolebindings", + }, + Verbs: []string{ + "*", + }, + }, + }, + } + + fleetWorkspaceMemberRole := v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: memberRole, + Labels: uiLabels, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{ + "fleet.cattle.io", + }, + Resources: []string{ + "gitrepos", + "bundles", + }, + Verbs: []string{ + "*", + }, + }, + { + APIGroups: []string{ + "fleet.cattle.io", + }, + Resources: []string{ + "clusterregistrationtokens", + "gitreporestrictions", + "clusterregistrations", + "clusters", + "clustergroups", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + }, + } + + fleetWorkspaceReadonlyRole := v1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: readonlyRole, + Labels: uiLabels, + }, + Rules: []v1.PolicyRule{ + { + APIGroups: []string{ + "fleet.cattle.io", + }, + Resources: []string{ + "clusterregistrationtokens", + "gitreporestrictions", + "clusterregistrations", + "clusters", + "gitrepos", + "bundles", + "clustergroups", + }, + Verbs: []string{ + "get", + "list", + "watch", + }, + }, + }, + } + + clusterRoles := []v1.ClusterRole{ + fleetWorkspaceAdminRole, + fleetWorkspaceMemberRole, + fleetWorkspaceReadonlyRole, + } + + for _, role := range clusterRoles { + existing, err := rbac.ClusterRole().Get(role.Name, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + if _, err := rbac.ClusterRole().Create(&role); err != nil { + return err + } + } else { + if !reflect.DeepEqual(existing.Rules, role.Rules) || !reflect.DeepEqual(existing.Labels, role.Labels) { + if _, err := rbac.ClusterRole().Update(&role); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/namespace.go new file mode 100644 index 0000000..140072a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/namespace.go @@ -0,0 +1,51 @@ +package dashboard + +import ( + "context" + + "github.com/rancher/rancher/pkg/features" + fleetconst "github.com/rancher/rancher/pkg/fleet" + "github.com/rancher/rancher/pkg/namespace" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +func addCattleGlobalNamespaces(ctx context.Context, k8s kubernetes.Interface) error { + if features.Fleet.Enabled() { + _, err := k8s.CoreV1().Namespaces().Get(ctx, fleetconst.ClustersLocalNamespace, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = k8s.CoreV1().Namespaces().Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: fleetconst.ClustersLocalNamespace, + }, + }, metav1.CreateOptions{}) + } + if err != nil { + return err + } + } + _, err := k8s.CoreV1().Namespaces().Get(ctx, namespace.System, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = k8s.CoreV1().Namespaces().Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace.System, + }, + }, metav1.CreateOptions{}) + } + if err != nil { + return err + } + if features.UIExtension.Enabled() { + _, err = k8s.CoreV1().Namespaces().Get(ctx, namespace.UIPluginNamespace, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = k8s.CoreV1().Namespaces().Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace.UIPluginNamespace, + }, + }, metav1.CreateOptions{}) + } + } + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/rbac.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/rbac.go new file mode 100644 index 0000000..0057815 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/rbac.go @@ -0,0 +1,45 @@ +package dashboard + +import ( + "github.com/rancher/wrangler/v3/pkg/apply" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func addUnauthenticatedRoles(apply apply.Apply) error { + return apply. + WithDynamicLookup(). + WithSetID("cattle-unauthenticated"). + ApplyObjects( + &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-unauthenticated", + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"get"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"settings"}, + ResourceNames: []string{ + "first-login", "ui-pl", "ui-banners", "ui-brand", "ui-favicon", "ui-login-background-light", "ui-login-background-dark", "ui-primary-color", "ui-link-color", + "ui-banner-header", "ui-banner-footer", "ui-banner-login-consent"}, + }, + }, + }, + &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-unauthenticated", + }, + Subjects: []rbacv1.Subject{{ + Kind: "Group", + APIGroup: rbacv1.GroupName, + Name: "system:unauthenticated", + }}, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: "cattle-unauthenticated", + }, + }, + ) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/repo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/repo.go new file mode 100644 index 0000000..84e728e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/repo.go @@ -0,0 +1,89 @@ +package dashboard + +import ( + "context" + "strings" + + "github.com/rancher/rancher/pkg/features" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/rancher/rancher/pkg/settings" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/wrangler" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const defaultURL = "https://git.rancher.io/" + +var ( + prefix = "rancher-" +) + +func addRepo(wrangler *wrangler.Context, repoName, repoURL, branchName string) error { + if repoURL == "" || repoURL == defaultURL { + repoURL = defaultURL + strings.TrimPrefix(repoName, prefix) + } else { + logrus.Warnf( + "Charts URL for %q set to %q, which is not the default (%q). "+ + "If Rancher has issues finding charts, consider resetting this to the default value", + repoName, + repoURL, + defaultURL, + ) + } + + repo, err := wrangler.Catalog.ClusterRepo().Get(repoName, metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + _, err = wrangler.Catalog.ClusterRepo().Create(&v1.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: repoName, + }, + Spec: v1.RepoSpec{ + GitRepo: repoURL, + GitBranch: branchName, + }, + }) + } else if err == nil && (repo.Spec.GitRepo != repoURL || repo.Spec.GitBranch != branchName) { + repo.Spec.GitRepo = repoURL + repo.Spec.GitBranch = branchName + _, err = wrangler.Catalog.ClusterRepo().Update(repo) + } + + return err +} + +// addRepos upserts the rancher-charts, rancher-partner-charts and rancher-rke2-charts ClusterRepos +func addRepos(ctx context.Context, wrangler *wrangler.Context) error { + if err := addRepo( + wrangler, + "rancher-charts", + settings.ChartDefaultURL.Get(), + settings.ChartDefaultBranch.Get(), + ); err != nil { + return err + } + + if err := addRepo( + wrangler, + "rancher-partner-charts", + settings.PartnerChartDefaultURL.Get(), + settings.PartnerChartDefaultBranch.Get(), + ); err != nil { + return err + } + + if features.RKE2.Enabled() { + if err := addRepo( + wrangler, + "rancher-rke2-charts", + settings.RKE2ChartDefaultURL.Get(), + settings.RKE2ChartDefaultBranch.Get(), + ); err != nil { + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/setting.go new file mode 100644 index 0000000..2eb5dbb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/dashboard/setting.go @@ -0,0 +1,10 @@ +package dashboard + +import ( + "github.com/pborman/uuid" + "github.com/rancher/rancher/pkg/settings" +) + +func addSetting() error { + return settings.InstallUUID.SetIfUnset(uuid.NewRandom().String()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/add.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/add.go new file mode 100644 index 0000000..ea412dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/add.go @@ -0,0 +1,45 @@ +package management + +import ( + "context" + + "github.com/rancher/rancher/pkg/auth/data" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" +) + +func Add(ctx context.Context, wrangler *wrangler.Context, management *config.ManagementContext) error { + if err := sshKeyCleanup(management); err != nil { + return err + } + + _, err := addRoles(wrangler, management) + if err != nil { + return err + } + if err := addClusterRoleForNamespacedCRDs(management); err != nil { + return err + } + + if err := data.AuthConfigs(management); err != nil { + return err + } + + if err := syncCatalogs(management); err != nil { + return err + } + + if err = addDefaultPodSecurityAdmissionConfigurationTemplates(management); err != nil { + return err + } + + if err := addKontainerDrivers(management); err != nil { + return err + } + + if err := addCattleGlobalNamespaces(management); err != nil { + return err + } + + return addMachineDrivers(management) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bindings_cleanup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bindings_cleanup.go new file mode 100644 index 0000000..17f3e54 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bindings_cleanup.go @@ -0,0 +1,125 @@ +package management + +import ( + "time" + + "github.com/rancher/rancher/pkg/agent/clean" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + dupeBindingsCleanupKey = "DedupeBindingsDone" + orphanBindingsCleanupKey = "CleanupOrphanBindingsDone" + orphanCatalogBindingsCleanupKey = "CleanupOrphanCatalogBindingsDone" +) + +func CleanupDuplicateBindings(scaledContext *config.ScaledContext, wContext *wrangler.Context) { + // check if duplicate binding cleanup has run already + logrus.Infof("checking configmap %s/%s to determine if duplicate bindings cleanup needs to run", cattleNamespace, bootstrapAdminConfig) + if adminConfig, err := wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Get(scaledContext.RunContext, bootstrapAdminConfig, v1.GetOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + logrus.Warnf("unable to determine if duplicate bindings cleanup has ran, skipping: %v", err) + return + } + } else { + // config map already exists, check if the cleanup key is found + if _, ok := adminConfig.Data[dupeBindingsCleanupKey]; ok { + //cleanup has been run already, nothing to do here + logrus.Info("duplicate bindings cleanup has already run, skipping") + return + } + // run cleanup after delay to give other controllers a chance to create CRTBs/PRTBs and ease the load on the API at startup + const delayMinutes = 3 + logrus.Infof("bindings cleanup needed, waiting %v minutes before starting", delayMinutes) + time.Sleep(time.Minute * delayMinutes) + logrus.Info("starting duplicate binding cleanup") + err = clean.DuplicateBindings(&scaledContext.RESTConfig) + if err != nil { + logrus.Warnf("error in cleaning up duplicate bindings: %v", err) + return + } + // update configmap + reloadedConfig, err := wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Get(scaledContext.RunContext, bootstrapAdminConfig, v1.GetOptions{}) + if err != nil { + if !apierrors.IsNotFound(err) { + logrus.Warnf("unable to load configmap %v: %v", bootstrapAdminConfig, err) + return + } + } + + adminConfigCopy := reloadedConfig.DeepCopy() + if adminConfigCopy.Data == nil { + adminConfigCopy.Data = make(map[string]string) + } + adminConfigCopy.Data[dupeBindingsCleanupKey] = "yes" + + _, err = wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Update(scaledContext.RunContext, adminConfigCopy, v1.UpdateOptions{}) + if err != nil { + logrus.Warnf("error %v in updating %v configmap to record that the duplicate binding cleanup is done", err, bootstrapAdminConfig) + } + logrus.Infof("successfully cleaned up duplicate bindings") + } +} + +func CleanupOrphanBindings(scaledContext *config.ScaledContext, wContext *wrangler.Context) { + err := cleanupSpecificOrphanedBindings(scaledContext, wContext, orphanBindingsCleanupKey) + if err != nil { + logrus.Errorf("failed to cleanup orphan bindings") + } + err = cleanupSpecificOrphanedBindings(scaledContext, wContext, orphanCatalogBindingsCleanupKey) + if err != nil { + logrus.Errorf("failed to cleanup orphan catalog bindings") + } +} + +// Runs the cleanup process for orphaned bindings given a cleanupKey specifying which cleanup job should be run (orphanBindings or orphanCatalogBindings) +func cleanupSpecificOrphanedBindings(scaledContext *config.ScaledContext, wContext *wrangler.Context, cleanupKey string) error { + logrus.Infof("checking configmap %s/%s to determine if orphan bindings cleanup needs to run", cattleNamespace, bootstrapAdminConfig) + adminConfig, err := wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Get(scaledContext.RunContext, bootstrapAdminConfig, v1.GetOptions{}) + if err != nil { + logrus.Warnf("[%v] unable to determine if bindings cleanup has ran, skipping: %v", cleanupKey, err) + return err + } + + // config map exists, check if the cleanup key is found + if _, ok := adminConfig.Data[cleanupKey]; ok { + logrus.Infof("[%v] orphan bindings cleanup has already run, skipping", cleanupKey) + return nil + } + + // run cleanup + if cleanupKey == orphanBindingsCleanupKey { + err = clean.OrphanBindings(&scaledContext.RESTConfig) + } else { + err = clean.OrphanCatalogBindings(&scaledContext.RESTConfig) + } + if err != nil { + logrus.Warnf("[%v] error during orphan binding cleanup: %v", cleanupKey, err) + return err + } + + // update configmap + reloadedConfig, err := wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Get(scaledContext.RunContext, bootstrapAdminConfig, v1.GetOptions{}) + if err != nil { + logrus.Warnf("[%v] unable to get configmap %v: %v", cleanupKey, bootstrapAdminConfig, err) + return err + } + + adminConfigCopy := reloadedConfig.DeepCopy() + if adminConfigCopy.Data == nil { + adminConfigCopy.Data = make(map[string]string) + } + adminConfigCopy.Data[cleanupKey] = "yes" + + _, err = wContext.K8s.CoreV1().ConfigMaps(cattleNamespace).Update(scaledContext.RunContext, adminConfigCopy, v1.UpdateOptions{}) + if err != nil { + logrus.Warnf("[%v] error %v while updating configmap %v, unable to record completion of orphan binding cleanup", cleanupKey, err, bootstrapAdminConfig) + } + + logrus.Infof("[%v] successfully cleaned up orphan bindings", cleanupKey) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bootstrap_password.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bootstrap_password.go new file mode 100644 index 0000000..220f800 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/bootstrap_password.go @@ -0,0 +1,57 @@ +package management + +import ( + "context" + "os" + + "github.com/rancher/wrangler/v3/pkg/randomtoken" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +const ( + bootstrapPasswordSecretName = "bootstrap-secret" + bootstrapPasswordSecretKey = "bootstrapPassword" +) + +// GetBootstrapPassword reads the bootstrap password from it's secret. If the secret is not found +// it will be set from `CATTLE_BOOTSTRAP_PASSWORD` or generated if this is empty as well. +func GetBootstrapPassword(ctx context.Context, secrets corev1.SecretInterface) (string, bool, error) { + var s *v1.Secret + var err error + var generated bool + + // load the existing secret + s, err = secrets.Get(ctx, bootstrapPasswordSecretName, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return "", false, err + } + + // if the bootstrap password is set return it + if s.StringData[bootstrapPasswordSecretKey] != "" { + return s.StringData[bootstrapPasswordSecretKey], generated, nil + } + + // if the password is not set check the env and fall back to generating one + s.StringData = make(map[string]string) + s.StringData[bootstrapPasswordSecretKey] = os.Getenv("CATTLE_BOOTSTRAP_PASSWORD") + if s.StringData[bootstrapPasswordSecretKey] == "" { + generated = true + s.StringData[bootstrapPasswordSecretKey], _ = randomtoken.Generate() + } + + // persist the password + if s.GetResourceVersion() != "" { + _, err = secrets.Update(ctx, s, metav1.UpdateOptions{}) + } else { + s.Name = bootstrapPasswordSecretName + _, err = secrets.Create(ctx, s, metav1.CreateOptions{}) + } + if err != nil { + return "", false, err + } + + return s.StringData[bootstrapPasswordSecretKey], generated, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data.go new file mode 100644 index 0000000..bea2e50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data.go @@ -0,0 +1,215 @@ +package management + +import ( + "encoding/json" + "fmt" + "os" + "reflect" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/catalog/manager" + "github.com/rancher/rancher/pkg/catalog/utils" + + "github.com/rancher/rancher/pkg/controllers/managementuserlegacy/helm/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/helm" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + libraryURL = "https://git.rancher.io/charts" + libraryBranch = "master" + libraryName = "library" + + systemLibraryURL = "https://git.rancher.io/system-charts" + systemLibraryBranch = "master" + systemLibraryName = "system-library" + defSystemChartVer = "management.cattle.io/default-system-chart-version" + + helm3LibraryURL = "https://git.rancher.io/helm3-charts" + helm3LibraryBranch = "master" + helm3LibraryName = "helm3-library" + helm3HelmVersion = common.HelmV3 +) + +// updateCatalogURL updates annotations if they are outdated and system catalog url/branch if it matches outdated defaults +func updateCatalogURL(catalogClient v3.CatalogInterface, desiredDefaultURL string, desiredDefaultBranch string) error { + oldCatalog, err := catalogClient.Get(systemLibraryName, metav1.GetOptions{}) + if err != nil { + return err + } + desiredCatalog := oldCatalog.DeepCopy() + + if oldAnno := oldCatalog.Annotations[defSystemChartVer]; oldAnno == "" { + // If url/branch are old defaults, update - otherwise they are user set and should not be changed + if oldCatalog.Spec.URL == systemLibraryURL && oldCatalog.Spec.Branch == systemLibraryBranch { + setDesiredChartLib(desiredCatalog, desiredDefaultURL, desiredDefaultBranch) + } + } else { + oldAnnotations := make(map[string]interface{}) + json.Unmarshal([]byte(oldAnno), &oldAnnotations) + + // If url/branch catalog spec and annotation do not match, user likely has not changed it, so to new defaults + if oldCatalog.Spec.URL == oldAnnotations["url"] && oldCatalog.Spec.Branch == oldAnnotations["branch"] { + setDesiredChartLib(desiredCatalog, desiredDefaultURL, desiredDefaultBranch) + } + } + + // Annotation should be up to date with current desired default + setCatalogAnnotation(desiredCatalog, desiredDefaultURL, desiredDefaultBranch) + + // If old catalog does not match desired catalog state, update + if !reflect.DeepEqual(oldCatalog, desiredCatalog) { + return exponentialCatalogUpdate(catalogClient, desiredCatalog) + } + + return nil +} + +// setCatalogAnnotation sets default system chart version to match the desired URL and desired branch env variables +func setCatalogAnnotation(catalog *v3.Catalog, desiredURL string, desiredBranch string) { + if catalog.Annotations == nil { + catalog.Annotations = make(map[string]string) + } + systemChartMap := make(map[string]string) + systemChartMap["url"] = desiredURL + systemChartMap["branch"] = desiredBranch + + defChartAnno, _ := json.Marshal(systemChartMap) + catalog.Annotations[defSystemChartVer] = string(defChartAnno) +} + +// setDesiredChartLib sets the catalog url and branch to match the desired URL and desired branch env variables +func setDesiredChartLib(catalog *v3.Catalog, desiredURL string, desiredBranch string) { + catalog.Spec.URL = desiredURL + catalog.Spec.Branch = desiredBranch +} + +func exponentialCatalogUpdate(catalogClient v3.CatalogInterface, desiredCatalog *v3.Catalog) error { + backoff := wait.Backoff{ + Duration: 1 * time.Second, + Factor: 2, + Steps: 3, + } + catalog := desiredCatalog + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + if _, err := catalogClient.Update(catalog); err != nil { + if !errors.IsConflict(err) { + return false, err + } + + if catalog, err = catalogClient.Get(systemLibraryName, metav1.GetOptions{}); err != nil { + return false, err + } + catalog.Annotations[defSystemChartVer] = desiredCatalog.Annotations[defSystemChartVer] + setDesiredChartLib(catalog, desiredCatalog.Spec.URL, desiredCatalog.Spec.Branch) + + return false, nil + } + return true, nil + }) + if err != nil { + return fmt.Errorf("failed upgrading system-chart catalog: %v", err) + } + return nil +} + +func syncCatalogs(management *config.ManagementContext) error { + var bundledMode bool + if strings.ToLower(settings.SystemCatalog.Get()) == "bundled" { + bundledMode = true + } + return utilerrors.AggregateGoroutines( + // add charts + func() error { + // If running in bundled mode don't turn on the normal library by default + if bundledMode { + return nil + } + return doAddCatalogs(management, libraryName, libraryURL, libraryBranch, "", bundledMode) + }, + // add helm3 charts + func() error { + // If running in bundled mode don't turn on the normal library by default + if bundledMode { + return nil + } + return doAddCatalogs(management, helm3LibraryName, helm3LibraryURL, helm3LibraryBranch, helm3HelmVersion, bundledMode) + }, + // add system-charts + func() error { + if err := doAddCatalogs(management, systemLibraryName, systemLibraryURL, systemLibraryBranch, "", bundledMode); err != nil { + return err + } + desiredDefaultURL := systemLibraryURL + desiredDefaultBranch := "" + if devMode := os.Getenv("CATTLE_DEV_MODE"); devMode != "" { + desiredDefaultBranch = "dev" + } + + if fromEnvURL := os.Getenv("CATTLE_SYSTEM_CHART_DEFAULT_URL"); fromEnvURL != "" { + desiredDefaultURL = fromEnvURL + } + + if fromEnvBranch := os.Getenv("CATTLE_SYSTEM_CHART_DEFAULT_BRANCH"); fromEnvBranch != "" { + desiredDefaultBranch = fromEnvBranch + } + + if desiredDefaultBranch == "" { + panic(fmt.Errorf("If you are developing, set CATTLE_DEV_MODE environment variable to \"true\"." + + "Otherwise, set CATTLE_SYSTEM_CHART_DEFAULT_to desired default branch.")) + } + + return updateCatalogURL(management.Management.Catalogs(""), desiredDefaultURL, desiredDefaultBranch) + }, + ) +} + +func doAddCatalogs(management *config.ManagementContext, name, url, branch, helmVersion string, bundledMode bool) error { + var obj *v3.Catalog + var err error + + catalogClient := management.Management.Catalogs("") + + kind := helm.KindHelmGit + if bundledMode { + kind = helm.KindHelmInternal + } + + obj, err = catalogClient.Get(name, metav1.GetOptions{}) + if err != nil && !errors.IsNotFound(err) { + return err + } else if errors.IsNotFound(err) { + obj = &v3.Catalog{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Spec: v32.CatalogSpec{ + URL: url, + CatalogKind: kind, + Branch: branch, + HelmVersion: helmVersion, + }, + } + if obj, err = catalogClient.Create(obj); err != nil { + return err + } + } + + if bundledMode && obj.Name == utils.SystemLibraryName { + // force update the catalog cache on every startup; this ensures that setups using bundledMode can load new image + // into the ConfigMap when the bundled system-chart is updated (e.g. during Rancher upgrades) upon restarting Rancher + configMapInterface := management.Core.ConfigMaps("") + configMapLister := configMapInterface.Controller().Lister() + return manager.CreateOrUpdateSystemCatalogImageCache(obj, configMapInterface, configMapLister, true, true) + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data_test.go new file mode 100644 index 0000000..fcd69ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/catalog_data_test.go @@ -0,0 +1,217 @@ +package management + +import ( + "encoding/json" + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func NewCatalogClientMock(oldURL string, oldBranch string, annoURL string, annoBranch string) v3.CatalogInterface { + catalog := &v3.Catalog{ + Spec: v32.CatalogSpec{ + URL: oldURL, + Branch: oldBranch, + }, + } + + if annoURL != "" || annoBranch != "" { + setCatalogAnnotation(catalog, annoURL, annoBranch) + } + + return &fakes.CatalogInterfaceMock{ + GetFunc: func(name string, opts v1.GetOptions) (*v3.Catalog, error) { + if name == systemLibraryName { + return catalog, nil + } + return nil, nil + }, + UpdateFunc: func(c *v3.Catalog) (*v3.Catalog, error) { + catalog = c + return catalog, nil + }, + } +} + +// TestUpdateCatalogHasAnnoMatchEnv tests for scenarios where system-library catalog does not contain a chart version annotation +func TestUpdateCatalogNoAnno(t *testing.T) { + assert := assert.New(t) + + // If Annotations field is nil and current url/branch match v2.2.2 values, + // the url/branch should be set and annotation updated + c := NewCatalogClientMock(systemLibraryURL, systemLibraryBranch, "", "") + + updateCatalogURL(c, systemLibraryURL, "v3") + + catalog, err := c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v3", catalog.Spec.Branch) + + annoMap := make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v3", annoMap["branch"]) + + // If Annotations field is nil and current url/branch do not match v2.2.2 values, + // the url/branch should not be set and annotations should be updated + c = NewCatalogClientMock("https://test-system-chart-url.io/", "v4", "", "") + + updateCatalogURL(c, systemLibraryURL, "v3") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal("https://test-system-chart-url.io/", catalog.Spec.URL) + assert.Equal("v4", catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v3", annoMap["branch"]) +} + +// TestUpdateCatalogHasAnnoMatchEnv tests for scenarios where system-library catalog contains a chart version annotation, +// and the system-library catalog spec does match the "SYSTEM_CHART_DEFAULT" environment variable +func TestUpdateCatalogHasAnnoMatchEnv(t *testing.T) { + assert := assert.New(t) + + // If the url and branch DO match the old defaults and DO match environment and DO match annotation + // the url/branch and annotation should remain the same + c := NewCatalogClientMock(systemLibraryURL, systemLibraryBranch, systemLibraryURL, systemLibraryBranch) + + updateCatalogURL(c, systemLibraryURL, systemLibraryBranch) + catalog, err := c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal(systemLibraryBranch, catalog.Spec.Branch) + + annoMap := make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal(systemLibraryBranch, annoMap["branch"]) + + // If the url and branch DO match the old defaults and DO match environment and DO NOT match annotation + // the url/branch should NOT be updated and annotations should be updated + c = NewCatalogClientMock(systemLibraryURL, systemLibraryBranch, systemLibraryURL, "v3") + + updateCatalogURL(c, systemLibraryURL, systemLibraryBranch) + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal(systemLibraryBranch, catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal(systemLibraryBranch, annoMap["branch"]) + + // If the url and branch DO NOT match the old defaults and DO match environment and DO match annotation + // the url/branch should NOT be updated and annotations NOT should be updated + c = NewCatalogClientMock(systemLibraryURL, "v4", systemLibraryURL, "v4") + + updateCatalogURL(c, systemLibraryURL, "v4") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v4", catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v4", annoMap["branch"]) + + // If the url and branch DO NOT match the old defaults and DO match environment and DO NOT match annotation + // the url/branch should NOT be updated and annotations should be updated + c = NewCatalogClientMock(systemLibraryURL, "v5", systemLibraryURL, "v4") + + updateCatalogURL(c, systemLibraryURL, "v5") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v5", catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v5", annoMap["branch"]) +} + +// TestUpdateCatalogHasAnnoMatchEnv tests for scenarios where system-library catalog contains a chart version annotation, +// and the system-library catalog spec does not match the "SYSTEM_CHART_DEFAULT" environment variable +func TestUpdateCatalogHasAnnoNoMatchEnv(t *testing.T) { + assert := assert.New(t) + + // If the url and branch DO match the old defaults, DO NOT match Environment, DO match annotation + // the url/branch should be set and annotations should be updated + c := NewCatalogClientMock(systemLibraryURL, systemLibraryBranch, systemLibraryURL, systemLibraryBranch) + + updateCatalogURL(c, systemLibraryURL, "v2.2") + catalog, err := c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v2.2", catalog.Spec.Branch) + + annoMap := make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v2.2", annoMap["branch"]) + + // If the url and branch DO match the old defaults, DO NOT match Environment, DO NOT match annotation + // the url/branch should not be set and annotations should be updated (if not equal to environment) + c = NewCatalogClientMock(systemLibraryURL, systemLibraryBranch, systemLibraryURL, "v2") + + updateCatalogURL(c, systemLibraryURL, "v2.2") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal(systemLibraryBranch, catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v2.2", annoMap["branch"]) + + // If the url and branch DO NOT match the old defaults, DO NOT match Environment, DO match annotation + // the url/branch should be set and annotations should be updated + c = NewCatalogClientMock(systemLibraryURL, "v0.5", systemLibraryURL, "v0.5") + + updateCatalogURL(c, systemLibraryURL, "v2.2") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v2.2", catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(systemLibraryURL, annoMap["url"]) + assert.Equal("v2.2", annoMap["branch"]) + + // If the url and branch DO NOT match the old defaults, DO NOT match Environment, DO NOT match annotation + // the url/branch should not be set and annotations should be updated (if not equal to environment) + c = NewCatalogClientMock(systemLibraryURL, "v0.5", systemLibraryURL, "v1") + + updateCatalogURL(c, systemLibraryURL, "v2.2") + catalog, err = c.Get(systemLibraryName, v1.GetOptions{}) + assert.Nil(err) + assert.Equal(systemLibraryURL, catalog.Spec.URL) + assert.Equal("v0.5", catalog.Spec.Branch) + + annoMap = make(map[string]string) + err = json.Unmarshal([]byte(catalog.Annotations[defSystemChartVer]), &annoMap) + assert.Nil(err) + assert.Equal(annoMap["url"], systemLibraryURL) + assert.Equal(annoMap["branch"], "v2.2") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/ensure_admin_user.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/ensure_admin_user.go new file mode 100644 index 0000000..930be00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/ensure_admin_user.go @@ -0,0 +1,183 @@ +package management + +import ( + "fmt" + "os" + + "github.com/docker/docker/pkg/reexec" + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/auth/api/user" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/urfave/cli" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/clientcmd" +) + +func RegisterEnsureDefaultAdminCommand() { + reexec.Register("/usr/bin/ensure-default-admin", ensureDefaultAdmin) + reexec.Register("ensure-default-admin", ensureDefaultAdmin) +} + +func ensureDefaultAdmin() { + app := cli.NewApp() + app.Description = "Ensure an available default admin user" + + app.Action = func(c *cli.Context) error { + kubeConfigPath := os.ExpandEnv("$HOME/.kube/config") + if _, err := os.Stat(kubeConfigPath); err != nil { + kubeConfigPath = "" + } + + conf, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) + if err != nil { + return fmt.Errorf("Couldn't get kubeconfig. %v", err) + } + + client, err := v3.NewForConfig(*conf) + if err != nil { + return errors.Errorf("Couldn't get kubernetes client. %v", err) + } + + users, err := client.Users("").List(v1.ListOptions{}) + if err != nil { + return errors.Errorf("Error fetching users. %v", err) + } + + var admins []v3.User + for _, u := range users.Items { + if u.Username == "admin" { + admins = append(admins, u) + } + } + + count := len(admins) + if count > 1 { + var adminNames []string + for _, u := range admins { + adminNames = append(adminNames, u.Name) + } + return errors.Errorf("%v users were found with the name \"admin\". They are %v. Can only reset the default admin password when there is exactly one user with this label", + count, adminNames) + } else if count == 1 { + admin := admins[0] + fmt.Fprintf(os.Stdout, "Found existing default admin user (%v)\n", admin.Name) + + enabledChanged := ensureAdminIsEnabled(&admin) + labelingChanged := ensureAdminIsLabeled(&admin) + + if enabledChanged || labelingChanged { + _, err = client.Users("").Update(&admin) + } + if err != nil { + return errors.Errorf("Error updating user. %v", err) + } + err = ensureAdminIsAdmin(client, admin) + if err != nil { + return errors.Errorf("Couldn't make existing \"admin\" an actual admin. %v", err) + } + + } else { + err = createNewAdmin(client, length) + if err != nil { + return errors.Errorf("Couldn't create a new admin. %v", err) + } + } + + return err + } + + err := app.Run(os.Args) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func createNewAdmin(client v3.Interface, length int) error { + pass := generatePassword(length) + hashedPass, err := user.HashPasswordString(string(pass)) + if err != nil { + return err + } + + admin, err := client.Users("").Create(&v3.User{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "user-", + Labels: defaultAdminLabel, + }, + DisplayName: "Default Admin", + Username: "admin", + Password: string(hashedPass), + MustChangePassword: false, + }) + + if err != nil { + return err + } + + addAdminRoleToUser(client, *admin) + + fmt.Fprintf(os.Stdout, "New default admin user (%v):\n", admin.Name) + fmt.Fprintf(os.Stdout, "New password for default admin user (%v):\n%s\n", admin.Name, pass) + return err +} + +func ensureAdminIsEnabled(admin *v3.User) bool { + if admin.Enabled == nil || *admin.Enabled { + fmt.Fprintf(os.Stdout, "Existing default admin user (%v) is already enabled\n", admin.Name) + return false + } + + _true := true + admin.Enabled = &_true + fmt.Fprintf(os.Stdout, "Enabling existing default admin user (%v)\n", admin.Name) + return true +} + +func ensureAdminIsAdmin(client v3.Interface, admin v3.User) error { + bindings, err := client.GlobalRoleBindings("").List(v1.ListOptions{}) + if err != nil { + return err + } + + for _, b := range bindings.Items { + if b.UserName == admin.Name && b.GlobalRoleName == "admin" { + fmt.Fprintf(os.Stdout, "Existing default admin user (%v) is already an admin\n", admin.Name) + return nil + } + } + + fmt.Fprintf(os.Stdout, "Giving existing default admin user (%v) admin permissions\n", admin.Name) + return addAdminRoleToUser(client, admin) +} + +func ensureAdminIsLabeled(admin *v3.User) bool { + changed := true + if current, exists := admin.ObjectMeta.Labels[defaultAdminLabelKey]; exists { + changed = current != defaultAdminLabelValue + } + + if changed { + fmt.Fprintf(os.Stdout, "Labeling existing default admin user (%v) as admin\n", admin.Name) + + admin.ObjectMeta.Labels[defaultAdminLabelKey] = defaultAdminLabelValue + } else { + fmt.Fprintf(os.Stdout, "Existing default admin user (%v) already labeled as admin\n", admin.Name) + } + + return changed +} + +func addAdminRoleToUser(client v3.Interface, admin v3.User) error { + _, err := client.GlobalRoleBindings("").Create( + &v3.GlobalRoleBinding{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "globalrolebinding-", + Labels: defaultAdminLabel, + }, + UserName: admin.Name, + GlobalRoleName: "admin", + }) + + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/global_namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/global_namespace.go new file mode 100644 index 0000000..10abf85 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/global_namespace.go @@ -0,0 +1,46 @@ +package management + +import ( + "fmt" + + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" +) + +func addCattleGlobalNamespaces(management *config.ManagementContext) error { + if err := createNamespace(namespace.GlobalNamespace, management); err != nil { + return err + } + + if err := createNamespace(namespace.NodeTemplateGlobalNamespace, management); err != nil { + return err + } + + logrus.Debugf("calling sync for driver metadata") + management.Management.Settings("").Controller().Enqueue("", settings.RkeMetadataConfig.Name) + + return nil +} + +func createNamespace(namespace string, management *config.ManagementContext) error { + lister := management.Core.Namespaces("").Controller().Lister() + + ns, err := lister.Get("", namespace) + if k8serrors.IsNotFound(err) { + ns = &corev1.Namespace{} + ns.Name = namespace + if _, err := management.Core.Namespaces("").Create(ns); err != nil { + return fmt.Errorf("error creating %v namespace: %v", namespace, err) + } + logrus.Infof("Created %v namespace", namespace) + } else if err != nil { + return fmt.Errorf("error creating %v namespace: %v", namespace, err) + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/key_cleanup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/key_cleanup.go new file mode 100644 index 0000000..cc79b31 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/key_cleanup.go @@ -0,0 +1,50 @@ +package management + +import ( + "github.com/rancher/rancher/pkg/types/config" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func sshKeyCleanup(management *config.ManagementContext) error { + nodeClient := management.Management.Nodes("") + nodes, err := nodeClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, node := range nodes.Items { + if node.Status.NodeConfig != nil && node.Status.NodeConfig.SSHKey != "" { + node.Status.NodeConfig.SSHKey = "" + _, err = nodeClient.Update(&node) + if err != nil { + return err + } + } + } + + clusterClient := management.Management.Clusters("") + clusters, err := clusterClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, cluster := range clusters.Items { + if cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + continue + } + pruned := false + for i, node := range cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Nodes { + if node.SSHKey != "" { + cluster.Status.AppliedSpec.RancherKubernetesEngineConfig.Nodes[i].SSHKey = "" + pruned = true + } + } + if pruned { + _, err = clusterClient.Update(&cluster) + if err != nil { + return err + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/kontainerdriver_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/kontainerdriver_data.go new file mode 100644 index 0000000..93abbe3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/kontainerdriver_data.go @@ -0,0 +1,209 @@ +package management + +import ( + "fmt" + "os" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/rancher/pkg/controllers/management/drivers/kontainerdriver" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func addKontainerDrivers(management *config.ManagementContext) error { + // create binary drop location if not exists + err := os.MkdirAll(kontainerdriver.DriverDir, 0777) + if err != nil { + return fmt.Errorf("error creating binary drop folder: %v", err) + } + + creator := driverCreator{ + driversLister: management.Management.KontainerDrivers("").Controller().Lister(), + drivers: management.Management.KontainerDrivers(""), + } + + if err := cleanupImportDriver(creator); err != nil { + return err + } + + if err := creator.add("rancherKubernetesEngine"); err != nil { + return err + } + + if err := creator.add("googleKubernetesEngine"); err != nil { + return err + } + + if err := creator.add("azureKubernetesService"); err != nil { + return err + } + + if err := creator.add("amazonElasticContainerService"); err != nil { + return err + } + + if err := creator.addCustomDriver( + "baiducloudcontainerengine", + "https://drivers.rancher.cn/kontainer-engine-driver-baidu/0.2.0/kontainer-engine-driver-baidu-linux", + "4613e3be3ae5487b0e21dfa761b95de2144f80f98bf76847411e5fcada343d5e", + "https://drivers.rancher.cn/kontainer-engine-driver-baidu/0.2.0/component.js", + false, + "drivers.rancher.cn", "*.baidubce.com", + ); err != nil { + return err + } + + if err := creator.addCustomDriver( + "aliyunkubernetescontainerservice", + "https://drivers.rancher.cn/kontainer-engine-driver-aliyun/0.2.6/kontainer-engine-driver-aliyun-linux", + "8a5360269ec803e3d8cf2c9cc94c66879da03a1fd2b580912c1a83454509c84c", + "https://drivers.rancher.cn/pandaria/ui/cluster-driver-aliyun/0.1.1/component.js", + false, + "*.aliyuncs.com", + ); err != nil { + return err + } + + if err := creator.addCustomDriver( + "tencentkubernetesengine", + "https://drivers.rancher.cn/kontainer-engine-driver-tencent/0.3.0/kontainer-engine-driver-tencent-linux", + "ad5406502daf826874889963d7bdaed78db4689f147889ecf97394bc4e8d3d76", + "", + false, + "*.tencentcloudapi.com", "*.qcloud.com", + ); err != nil { + return err + } + + if err := creator.addCustomDriver( + "huaweicontainercloudengine", + "https://drivers.rancher.cn/kontainer-engine-driver-huawei/0.1.2/kontainer-engine-driver-huawei-linux", + "0b6c1dfaa477a60a3bd9f8a60a55fcafd883866c2c5c387aec75b95d6ba81d45", + "", + false, + "*.myhuaweicloud.com", + ); err != nil { + return err + } + if err := creator.addCustomDriver( + "oraclecontainerengine", + "https://github.com/rancher-plugins/kontainer-engine-driver-oke/releases/download/v1.8.3/kontainer-engine-driver-oke-linux", + "7bfde567e6d478f1da8d36531f765d348bff1cd3abe83c70ddf7766f46112170", + "", + false, + "*.oraclecloud.com", + ); err != nil { + return err + } + if err := creator.addCustomDriver( + "linodekubernetesengine", + "https://github.com/linode/kontainer-engine-driver-lke/releases/download/v0.0.9/kontainer-engine-driver-lke-linux-amd64", + "f489f3b354280f8a2859945de27c76b0a70a888976d4cebcb58a30fe161f4b97", + "", + false, + "api.linode.com", + ); err != nil { + return err + } + + return creator.addCustomDriver( + "opentelekomcloudcontainerengine", + "https://otc-rancher.obs.eu-de.otc.t-systems.com/cluster/driver/1.0.2/kontainer-engine-driver-otccce_linux_amd64.tar.gz", + "f2c0a8d1195cd51ae1ccdeb4a8defd2c3147b9a2c7510b091be0c12028740f5f", + "https://otc-rancher.obs.eu-de.otc.t-systems.com/cluster/ui/v1.1.0/component.js", + false, + "*.otc.t-systems.com", + ) +} + +func cleanupImportDriver(creator driverCreator) error { + var err error + if _, err = creator.driversLister.Get("", "import"); err == nil { + err = creator.drivers.Delete("import", &v1.DeleteOptions{}) + } + + if !errors.IsNotFound(err) { + return err + } + + return nil +} + +type driverCreator struct { + driversLister v3.KontainerDriverLister + drivers v3.KontainerDriverInterface +} + +func (c *driverCreator) add(name string) error { + logrus.Infof("adding kontainer driver %v", name) + + driver, err := c.driversLister.Get("", name) + if err != nil { + if errors.IsNotFound(err) { + _, err = c.drivers.Create(&v3.KontainerDriver{ + ObjectMeta: v1.ObjectMeta{ + Name: strings.ToLower(name), + Namespace: "", + }, + Spec: v32.KontainerDriverSpec{ + URL: "", + BuiltIn: true, + Active: true, + }, + Status: v32.KontainerDriverStatus{ + DisplayName: name, + }, + }) + if err != nil && !errors.IsAlreadyExists(err) { + return fmt.Errorf("error creating driver: %v", err) + } + } else { + return fmt.Errorf("error getting driver: %v", err) + } + } else { + driver.Spec.URL = "" + + _, err = c.drivers.Update(driver) + if err != nil { + return fmt.Errorf("error updating driver: %v", err) + } + } + + return nil +} + +func (c *driverCreator) addCustomDriver(name, url, checksum, uiURL string, active bool, domains ...string) error { + logrus.Infof("adding kontainer driver %v", name) + _, err := c.driversLister.Get("", name) + if err != nil { + if errors.IsNotFound(err) { + _, err = c.drivers.Create(&v3.KontainerDriver{ + ObjectMeta: v1.ObjectMeta{ + Name: strings.ToLower(name), + }, + Spec: v32.KontainerDriverSpec{ + URL: url, + BuiltIn: false, + Active: active, + Checksum: checksum, + UIURL: uiURL, + WhitelistDomains: domains, + }, + Status: v32.KontainerDriverStatus{ + DisplayName: name, + }, + }) + if err != nil && !errors.IsAlreadyExists(err) { + return fmt.Errorf("error creating driver: %v", err) + } + } else { + return fmt.Errorf("error getting driver: %v", err) + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/machinedriver_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/machinedriver_data.go new file mode 100644 index 0000000..02db231 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/machinedriver_data.go @@ -0,0 +1,227 @@ +package management + +import ( + "fmt" + "os" + "os/exec" + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + Amazonec2driver = "amazonec2" + Azuredriver = "azure" + DigitalOceandriver = "digitalocean" + ExoscaleDriver = "exoscale" + HarvesterDriver = "harvester" + Linodedriver = "linode" + NutanixDriver = "nutanix" + OCIDriver = "oci" + OTCDriver = "otc" + OpenstackDriver = "openstack" + PacketDriver = "packet" + PhoenixNAPDriver = "pnap" + RackspaceDriver = "rackspace" + SoftLayerDriver = "softlayer" + Vmwaredriver = "vmwarevsphere" + GoogleDriver = "google" + OutscaleDriver = "outscale" +) + +var DriverData = map[string]map[string][]string{ + Amazonec2driver: {"publicCredentialFields": []string{"accessKey"}, "privateCredentialFields": []string{"secretKey"}}, + Azuredriver: {"publicCredentialFields": []string{"clientId", "subscriptionId", "tenantId", "environment"}, "privateCredentialFields": []string{"clientSecret"}, "optionalCredentialFields": []string{"tenantId"}}, + DigitalOceandriver: {"privateCredentialFields": []string{"accessToken"}}, + ExoscaleDriver: {"privateCredentialFields": []string{"apiSecretKey"}}, + HarvesterDriver: {"publicCredentialFields": []string{"clusterType", "clusterId"}, "privateCredentialFields": []string{"kubeconfigContent"}, "optionalCredentialFields": []string{"clusterId"}}, + Linodedriver: {"privateCredentialFields": []string{"token"}, "passwordFields": []string{"rootPass"}}, + NutanixDriver: {"publicCredentialFields": []string{"endpoint", "username", "port"}, "privateCredentialFields": []string{"password"}}, + OCIDriver: {"publicCredentialFields": []string{"tenancyId", "userId", "fingerprint"}, "privateCredentialFields": []string{"privateKeyContents"}, "passwordFields": []string{"privateKeyPassphrase"}}, + OTCDriver: {"privateCredentialFields": []string{"accessKeySecret"}}, + OpenstackDriver: {"privateCredentialFields": []string{"password"}}, + PacketDriver: {"privateCredentialFields": []string{"apiKey"}}, + PhoenixNAPDriver: {"publicCredentialFields": []string{"clientIdentifier"}, "privateCredentialFields": []string{"clientSecret"}}, + RackspaceDriver: {"privateCredentialFields": []string{"apiKey"}}, + SoftLayerDriver: {"privateCredentialFields": []string{"apiKey"}}, + Vmwaredriver: {"publicCredentialFields": []string{"username", "vcenter", "vcenterPort"}, "privateCredentialFields": []string{"password"}}, + GoogleDriver: {"privateCredentialFields": []string{"authEncodedJson"}}, + OutscaleDriver: {"publicCredentialFields": []string{"accessKey", "region"}, "privateCredentialFields": []string{"secretKey"}}, +} + +var driverDefaults = map[string]map[string]string{ + HarvesterDriver: {"clusterType": "imported"}, + Vmwaredriver: {"vcenterPort": "443"}, +} + +type machineDriverCompare struct { + builtin bool + addCloudCredential bool + url string + uiURL string + checksum string + name string + whitelist []string + annotations map[string]string +} + +func addMachineDrivers(management *config.ManagementContext) error { + if err := addMachineDriver("pinganyunecs", "https://drivers.rancher.cn/node-driver-pinganyun/0.3.0/docker-machine-driver-pinganyunecs-linux.tgz", "https://drivers.rancher.cn/node-driver-pinganyun/0.3.0/component.js", "f84ccec11c2c1970d76d30150916933efe8ca49fe4c422c8954fc37f71273bb5", []string{"drivers.rancher.cn"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver("aliyunecs", "https://drivers.rancher.cn/node-driver-aliyun/1.0.4/docker-machine-driver-aliyunecs.tgz", "", "5990d40d71c421a85563df9caf069466f300cd75723effe4581751b0de9a6a0e", []string{"ecs.aliyuncs.com"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(Amazonec2driver, "local://", "", "", + []string{"iam.amazonaws.com", "iam.us-gov.amazonaws.com", "iam.%.amazonaws.com.cn", "ec2.%.amazonaws.com", "ec2.%.amazonaws.com.cn", "eks.%.amazonaws.com", "eks.%.amazonaws.com.cn", "kms.%.amazonaws.com", "kms.%.amazonaws.com.cn"}, + true, true, true, management); err != nil { + return err + } + if err := addMachineDriver(Azuredriver, "local://", "", "", nil, true, true, true, management); err != nil { + return err + } + if err := addMachineDriver("cloudca", "https://github.com/cloud-ca/docker-machine-driver-cloudca/files/2446837/docker-machine-driver-cloudca_v2.0.0_linux-amd64.zip", "https://objects-east.cloud.ca/v1/5ef827605f884961b94881e928e7a250/ui-driver-cloudca/v2.1.2/component.js", "2a55efd6d62d5f7fd27ce877d49596f4", []string{"objects-east.cloud.ca"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver("cloudscale", "https://github.com/cloudscale-ch/docker-machine-driver-cloudscale/releases/download/v1.2.0/docker-machine-driver-cloudscale_v1.2.0_linux_amd64.tar.gz", "https://objects.rma.cloudscale.ch/cloudscale-rancher-v2-ui-driver/component.js", "e33fbd6c2f87b1c470bcb653cc8aa50baf914a9d641a2f18f86a07c398cfb544", []string{"objects.rma.cloudscale.ch"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(DigitalOceandriver, "local://", "", "", []string{"api.digitalocean.com"}, true, true, false, management); err != nil { + return err + } + if err := addMachineDriver(ExoscaleDriver, "local://", "", "", []string{"api.exoscale.ch"}, false, true, false, management); err != nil { + return err + } + if err := addMachineDriver(GoogleDriver, "local://", "", "", nil, false, true, true, management); err != nil { + return err + } + harvesterEnabled := features.GetFeatureByName(HarvesterDriver).Enabled() + // make sure the version number is consistent with the one at Line 40 of package/Dockerfile + if err := addMachineDriver(HarvesterDriver, "https://releases.rancher.com/harvester-node-driver/v0.6.7/docker-machine-driver-harvester-amd64.tar.gz", "", "a913f22a7cad5d0df18e0dfa8a8ae19703c36eb8ed4f6a34ae471a06af0890c3", []string{"releases.rancher.com"}, harvesterEnabled, harvesterEnabled, false, management); err != nil { + return err + } + linodeBuiltin := true + if dl := os.Getenv("CATTLE_DEV_MODE"); dl != "" { + linodeBuiltin = isCommandAvailable("docker-machine-driver-linode") + } + if err := addMachineDriver(Linodedriver, "https://github.com/linode/docker-machine-driver-linode/releases/download/v0.1.12/docker-machine-driver-linode_linux-amd64.zip", "/assets/rancher-ui-driver-linode/component.js", "5fab97320e3965607340567b11857e76a2d9d87fe6dbb3571cc3df04db432c14", []string{"api.linode.com"}, linodeBuiltin, linodeBuiltin, false, management); err != nil { + return err + } + if err := addMachineDriver(OCIDriver, "https://github.com/rancher-plugins/rancher-machine-driver-oci/releases/download/v1.3.0/docker-machine-driver-oci-linux", "", "0a1afa6a0af85ecf3d77cc554960e36e1be5fd12b22b0155717b9289669e4021", []string{"*.oraclecloud.com"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(OpenstackDriver, "local://", "", "", nil, false, true, false, management); err != nil { + return err + } + if err := addMachineDriver(OTCDriver, "https://github.com/rancher-plugins/docker-machine-driver-otc/releases/download/v2019.5.7/docker-machine-driver-otc", "", "3f793ebb0ebd9477b9166ec542f77e25", nil, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(PacketDriver, "https://github.com/equinix/docker-machine-driver-metal/releases/download/v0.6.0/docker-machine-driver-metal_linux-amd64.zip", "https://rancher-drivers.equinixmetal.net/1.0.2/component.js", "fad5e551a35d2ef2db742b07ca6d61bb9c9b574d322d3000f0c557d5fb90a734", []string{"api.packet.net", "api.equinix.com", "rancher-drivers.equinixmetal.net"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(PhoenixNAPDriver, "https://github.com/phoenixnap/docker-machine-driver-pnap/releases/download/v0.5.1/docker-machine-driver-pnap_0.5.1_linux_amd64.zip", "", "5847599c24c137975fd190747a15ad4db9529ae35059b60e5f8bc9a470d55229", []string{"api.securedservers.com", "api.phoenixnap.com", "auth.phoenixnap.com"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(RackspaceDriver, "local://", "", "", nil, false, true, false, management); err != nil { + return err + } + if err := addMachineDriver(SoftLayerDriver, "local://", "", "", nil, false, true, false, management); err != nil { + return err + } + if err := addMachineDriver(NutanixDriver, "https://github.com/nutanix/docker-machine/releases/download/v3.6.0/docker-machine-driver-nutanix", "https://nutanix.github.io/rancher-ui-driver/v3.6.0/component.js", "d9710fe31a1357d1bbd57539a4b0b00e3ab3550fcaeffea18cbc145cb4e9b22f", []string{"nutanix.github.io"}, false, false, false, management); err != nil { + return err + } + if err := addMachineDriver(OutscaleDriver, "https://github.com/outscale/docker-machine-driver-outscale/releases/download/v0.2.0/docker-machine-driver-outscale_0.2.0_linux_amd64.zip", "https://oos.eu-west-2.outscale.com/rancher-ui-driver-outscale/v0.2.0/component.js", "bb539ed4e2b0f1a1083b29cbdbab59bde3efed0a3145fefc0b2f47026c48bfe0", []string{"oos.eu-west-2.outscale.com"}, false, false, false, management); err != nil { + return err + } + return addMachineDriver(Vmwaredriver, "local://", "", "", nil, true, true, false, management) +} + +func addMachineDriver(name, url, uiURL, checksum string, whitelist []string, active, builtin, addCloudCredential bool, management *config.ManagementContext) error { + lister := management.Management.NodeDrivers("").Controller().Lister() + cli := management.Management.NodeDrivers("") + m, _ := lister.Get("", name) + // annotations can have keys cred and password, values []string to be considered as a part of cloud credential + annotations := map[string]string{} + if m != nil { + for k, v := range m.Annotations { + annotations[k] = v + } + } + for key, fields := range DriverData[name] { + annotations[key] = strings.Join(fields, ",") + } + defaults := []string{} + for key, val := range driverDefaults[name] { + defaults = append(defaults, fmt.Sprintf("%s:%s", key, val)) + } + if len(defaults) > 0 { + annotations["defaults"] = strings.Join(defaults, ",") + } + if m != nil { + old := machineDriverCompare{ + builtin: m.Spec.Builtin, + addCloudCredential: m.Spec.AddCloudCredential, + url: m.Spec.URL, + uiURL: m.Spec.UIURL, + checksum: m.Spec.Checksum, + name: m.Spec.DisplayName, + whitelist: m.Spec.WhitelistDomains, + annotations: m.Annotations, + } + new := machineDriverCompare{ + builtin: builtin, + addCloudCredential: addCloudCredential, + url: url, + uiURL: uiURL, + checksum: checksum, + name: name, + whitelist: whitelist, + annotations: annotations, + } + if !reflect.DeepEqual(new, old) { + logrus.Infof("Updating node driver %v", name) + m.Spec.Builtin = builtin + m.Spec.AddCloudCredential = addCloudCredential + m.Spec.URL = url + m.Spec.UIURL = uiURL + m.Spec.Checksum = checksum + m.Spec.DisplayName = name + m.Spec.WhitelistDomains = whitelist + m.Annotations = annotations + _, err := cli.Update(m) + return err + } + return nil + } + + logrus.Infof("Creating node driver %v", name) + _, err := cli.Create(&v3.NodeDriver{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Annotations: annotations, + }, + Spec: v32.NodeDriverSpec{ + Active: active, + Builtin: builtin, + AddCloudCredential: addCloudCredential, + URL: url, + UIURL: uiURL, + DisplayName: name, + Checksum: checksum, + WhitelistDomains: whitelist, + }, + }) + + return err +} + +func isCommandAvailable(name string) bool { + return exec.Command("command", "-v", name).Run() == nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data.go new file mode 100644 index 0000000..6fb6e26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data.go @@ -0,0 +1,144 @@ +package management + +import ( + "fmt" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/util/retry" +) + +var FeatureAppNS = []string{ + "ingress-nginx", // This is for Ingress, not feature app + "kube-system", // Harvester, vSphere CPI, vSphere CSI, RKE2 restricted PSA Config + "cattle-system", // AKS/GKE/EKS Operator, Webhook, System Upgrade Controller + "cattle-epinio-system", // Epinio + "cattle-fleet-system", // Fleet + "cattle-fleet-local-system", // Fleet for the local cluster + "longhorn-system", // Longhorn + "cattle-neuvector-system", // Neuvector + "cattle-monitoring-system", // Monitoring and Sub-charts + "rancher-alerting-drivers", // Alert Driver + "cis-operator-system", // CIS Benchmark, RKE2 restricted PSA Config + "cattle-csp-adapter-system", // CSP Adapter + "cattle-externalip-system", // External IP Webhook + "cattle-gatekeeper-system", // Gatekeeper + "istio-system", // Istio and Sub-charts + "cattle-istio-system", // Kiali + "cattle-logging-system", // Logging + "cattle-windows-gmsa-system", // Windows GMSA + "cattle-sriov-system", // Sriov + "cattle-ui-plugin-system", // UI Plugin System + "tigera-operator", // RKE2 restricted PSA Config, source: https://github.com/rancher/rke2/blob/34633dcc188d3a79744636fe21529ef6f5d64d71/pkg/rke2/psa.go#L58 + "cattle-provisioning-capi-system", // CAPI core controller manager +} + +// addDefaultPodSecurityAdmissionConfigurationTemplates creates or updates the default PSACTs with the builtin templates. +func addDefaultPodSecurityAdmissionConfigurationTemplates(management *config.ManagementContext) error { + psactClient := management.Management.PodSecurityAdmissionConfigurationTemplates("") + templates := []*v3.PodSecurityAdmissionConfigurationTemplate{ + newPodSecurityAdmissionConfigurationTemplatePrivileged(), + newPodSecurityAdmissionConfigurationTemplateRestricted(), + } + for _, t := range templates { + if _, err := psactClient.Create(t); err != nil { + if !errors.IsAlreadyExists(err) { + return fmt.Errorf("failed to create default '%s' pod security admission configuration: %w", t.Name, err) + } + logrus.Tracef("updating default '%s' pod security admission configuration", t.Name) + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + // get the latest version of the object from the k8s API directly + existing, err := psactClient.Get(t.Name, metav1.GetOptions{}) + if err != nil { + return err + } + // We'd like to preserve user's additions to the exemptions, meanwhile merging everything from + // the built-in template into the existing psact for Rancher to work properly. It means that any + // value that is still in the built-in template but removed by user will be added back. + final := mergeExemptions(existing, t) + if _, err = psactClient.Update(final); err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + } + } + return nil +} + +// mergeExemptions returns a new pointer to PodSecurityAdmissionConfigurationTemplate which values are copied from +// the base but the exemptions field is the union set of the values from the base and the additional PSACT. +func mergeExemptions(base, additional *v3.PodSecurityAdmissionConfigurationTemplate) *v3.PodSecurityAdmissionConfigurationTemplate { + if base == nil { + return additional + } + if additional == nil { + return base + } + a := base.Configuration.Exemptions + b := additional.Configuration.Exemptions + final := base.DeepCopy() + final.Configuration.Exemptions.Usernames = sets.NewString(a.Usernames...).Insert(b.Usernames...).List() + final.Configuration.Exemptions.Namespaces = sets.NewString(a.Namespaces...).Insert(b.Namespaces...).List() + final.Configuration.Exemptions.RuntimeClasses = sets.NewString(a.RuntimeClasses...).Insert(b.RuntimeClasses...).List() + return final +} + +func newPodSecurityAdmissionConfigurationTemplateRestricted() *v3.PodSecurityAdmissionConfigurationTemplate { + return &v3.PodSecurityAdmissionConfigurationTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rancher-restricted", + }, + Description: "This is the built-in restricted Pod Security Admission Configuration Template. " + + "It defines a heavily restricted policy, based on current Pod hardening best practices. " + + "This policy contains namespace level exemptions for Rancher components.", + Configuration: v3.PodSecurityAdmissionConfigurationTemplateSpec{ + Defaults: v3.PodSecurityAdmissionConfigurationTemplateDefaults{ + Enforce: "restricted", + EnforceVersion: "latest", + Audit: "restricted", + AuditVersion: "latest", + Warn: "restricted", + WarnVersion: "latest", + }, + Exemptions: v3.PodSecurityAdmissionConfigurationTemplateExemptions{ + Usernames: []string{}, + RuntimeClasses: []string{}, + Namespaces: FeatureAppNS, + }, + }, + } +} + +func newPodSecurityAdmissionConfigurationTemplatePrivileged() *v3.PodSecurityAdmissionConfigurationTemplate { + return &v3.PodSecurityAdmissionConfigurationTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rancher-privileged", + }, + Description: "This is the built-in unrestricted Pod Security Admission Configuration Template. " + + "It defines the most permissive PSS policy, allowing for known privilege escalations. " + + "This policy contains no exemptions.", + Configuration: v3.PodSecurityAdmissionConfigurationTemplateSpec{ + Defaults: v3.PodSecurityAdmissionConfigurationTemplateDefaults{ + Enforce: "privileged", + EnforceVersion: "latest", + Audit: "privileged", + AuditVersion: "latest", + Warn: "privileged", + WarnVersion: "latest", + }, + Exemptions: v3.PodSecurityAdmissionConfigurationTemplateExemptions{ + Usernames: []string{}, + RuntimeClasses: []string{}, + Namespaces: []string{}, + }, + }, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data_test.go new file mode 100644 index 0000000..6749896 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/podadmissionconfigurationtemplate_data_test.go @@ -0,0 +1,117 @@ +package management + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + example1 = &v3.PodSecurityAdmissionConfigurationTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-example1", + }, + Description: "This is an example for testing", + Configuration: v3.PodSecurityAdmissionConfigurationTemplateSpec{ + Defaults: v3.PodSecurityAdmissionConfigurationTemplateDefaults{ + Enforce: "restricted", + EnforceVersion: "latest", + Audit: "restricted", + AuditVersion: "latest", + Warn: "restricted", + WarnVersion: "latest", + }, + Exemptions: v3.PodSecurityAdmissionConfigurationTemplateExemptions{ + Usernames: []string{"user-a", "user-b", "user-c"}, + RuntimeClasses: []string{"runtime-a", "runtime-b", "runtime-c"}, + Namespaces: []string{"ns-a", "ns-b", "ns-c"}, + }, + }, + } + example2 = &v3.PodSecurityAdmissionConfigurationTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "another-example", + }, + Description: "This is another example for testing", + Configuration: v3.PodSecurityAdmissionConfigurationTemplateSpec{ + Exemptions: v3.PodSecurityAdmissionConfigurationTemplateExemptions{ + Usernames: []string{"user-a", "user-1", "user-2", "user-3"}, + RuntimeClasses: []string{"runtime-1", "runtime-2", "runtime-3"}, + Namespaces: []string{"ns-1", "ns-2", "ns-3"}, + }, + }, + } + example1plug2 = &v3.PodSecurityAdmissionConfigurationTemplate{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-example1", + }, + Description: "This is an example for testing", + Configuration: v3.PodSecurityAdmissionConfigurationTemplateSpec{ + Defaults: v3.PodSecurityAdmissionConfigurationTemplateDefaults{ + Enforce: "restricted", + EnforceVersion: "latest", + Audit: "restricted", + AuditVersion: "latest", + Warn: "restricted", + WarnVersion: "latest", + }, + Exemptions: v3.PodSecurityAdmissionConfigurationTemplateExemptions{ + Usernames: []string{"user-1", "user-2", "user-3", "user-a", "user-b", "user-c"}, + RuntimeClasses: []string{"runtime-1", "runtime-2", "runtime-3", "runtime-a", "runtime-b", "runtime-c"}, + Namespaces: []string{"ns-1", "ns-2", "ns-3", "ns-a", "ns-b", "ns-c"}, + }, + }, + } +) + +func Test_merge(t *testing.T) { + type args struct { + base *v3.PodSecurityAdmissionConfigurationTemplate + additional *v3.PodSecurityAdmissionConfigurationTemplate + } + tests := []struct { + name string + args args + want *v3.PodSecurityAdmissionConfigurationTemplate + }{ + { + name: "base is empty", + args: args{ + base: nil, + additional: example1, + }, + want: example1, + }, + { + name: "additional is empty", + args: args{ + base: example1, + additional: nil, + }, + want: example1, + }, + { + name: "both are empty", + args: args{ + base: nil, + additional: nil, + }, + want: nil, + }, + { + name: "addition contains different exceptions", + args: args{ + base: example1, + additional: example2, + }, + want: example1plug2, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, mergeExemptions(tt.args.base, tt.args.additional), "mergeExemptions(%v, %v)", tt.args.base, tt.args.additional) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/resetpassword.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/resetpassword.go new file mode 100644 index 0000000..bf04e37 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/resetpassword.go @@ -0,0 +1,100 @@ +package management + +import ( + "crypto/rand" + "fmt" + "log" + "os" + + "github.com/docker/docker/pkg/reexec" + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/auth/api/user" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/urfave/cli" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/clientcmd" +) + +func RegisterPasswordResetCommand() { + reexec.Register("/usr/bin/reset-password", resetPassword) + reexec.Register("reset-password", resetPassword) +} + +const ( + length = 20 + cost = 10 + characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" +) + +func resetPassword() { + app := cli.NewApp() + app.Description = "Reset the password for the default admin user" + + app.Action = func(c *cli.Context) error { + kubeConfigPath := os.ExpandEnv("$HOME/.kube/config") + if _, err := os.Stat(kubeConfigPath); err != nil { + kubeConfigPath = "" + } + + conf, err := clientcmd.BuildConfigFromFlags("", kubeConfigPath) + if err != nil { + return fmt.Errorf("Couldn't get kubeconfig. %v", err) + } + + client, err := v3.NewForConfig(*conf) + if err != nil { + return errors.Errorf("Couldn't get kubernetes client. %v", err) + } + + set := labels.Set(map[string]string{"authz.management.cattle.io/bootstrapping": "admin-user"}) + admins, err := client.Users("").List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return errors.Errorf("Couldn't get default admin user. %v", err) + } + + count := len(admins.Items) + if count != 1 { + var users []string + for _, u := range admins.Items { + users = append(users, u.Name) + } + return errors.Errorf("%v users were found with %v label. They are %v. Can only reset the default admin password when there is exactly one user with this label", + count, set, users) + } + + admin := admins.Items[0] + pass := generatePassword(length) + hashedPass, err := user.HashPasswordString(string(pass)) + if err != nil { + return err + } + admin.Password = hashedPass + admin.MustChangePassword = false + _, err = client.Users("").Update(&admin) + fmt.Fprintf(os.Stdout, "New password for default admin user (%v):\n%s\n", admin.Name, pass) + return err + } + + err := app.Run(os.Args) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func generatePassword(length int) []byte { + bytes := make([]byte, length) + _, err := rand.Read(bytes) + if err != nil { + log.Fatal(err) + } + + out := make([]byte, length) + for i := range out { + index := uint8(bytes[i]) % uint8(len(characters)) + out[i] = characters[index] + } + + return out +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/role_data.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/role_data.go new file mode 100644 index 0000000..fe2b423 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/role_data.go @@ -0,0 +1,769 @@ +package management + +import ( + "context" + "errors" + "fmt" + "reflect" + "sort" + "sync" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/bcrypt" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/net" + "k8s.io/client-go/util/retry" +) + +const ( + bootstrappedRole = "authz.management.cattle.io/bootstrapped-role" + bootstrapAdminConfig = "admincreated" + cattleNamespace = "cattle-system" + defaultAdminLabelKey = "authz.management.cattle.io/bootstrapping" + defaultAdminLabelValue = "admin-user" +) + +var ( + defaultAdminLabel = map[string]string{defaultAdminLabelKey: defaultAdminLabelValue} + adminCreateLock sync.Mutex +) + +func addRoles(wrangler *wrangler.Context, management *config.ManagementContext) (string, error) { + rb := newRoleBuilder() + + rb.addRole("Create Clusters", "clusters-create"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("create"). + addRule().apiGroups("provisioning.cattle.io").resources("clusters").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("templates", "templateversions").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("nodedrivers").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("kontainerdrivers").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("podsecurityadmissionconfigurationtemplates").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("nodetemplates").verbs("*"). + addRule().apiGroups("").resources("secrets").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("cisconfigs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("cisbenchmarkversions").verbs("get", "list", "watch"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("create"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("rke.cattle.io").resources("etcdsnapshots").verbs("get", "list", "watch") + + rb.addRole("Manage Node Drivers", "nodedrivers-manage"). + addRule().apiGroups("management.cattle.io").resources("nodedrivers").verbs("*") + rb.addRole("Manage Cluster Drivers", "kontainerdrivers-manage"). + addRule().apiGroups("management.cattle.io").resources("kontainerdrivers").verbs("*") + rb.addRole("Manage Catalogs", "catalogs-manage"). + addRule().apiGroups("management.cattle.io").resources("catalogs", "templates", "templateversions").verbs("*") + rb.addRole("Use Catalog Templates", "catalogs-use"). + addRule().apiGroups("management.cattle.io").resources("templates", "templateversions").verbs("get", "list", "watch") + rb.addRole("Manage Users", "users-manage"). + addRule().apiGroups("management.cattle.io").resources("users", "globalrolebindings").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("globalroles").verbs("get", "list", "watch") + rb.addRole("Manage Roles", "roles-manage"). + addRule().apiGroups("management.cattle.io").resources("roletemplates").verbs("delete", "deletecollection", "get", "list", "patch", "create", "update", "watch") + rb.addRole("Manage Authentication", "authn-manage"). + addRule().apiGroups("management.cattle.io").resources("authconfigs").verbs("get", "list", "watch", "update") + rb.addRole("Manage Settings", "settings-manage"). + addRule().apiGroups("management.cattle.io").resources("settings").verbs("*") + rb.addRole("Manage Features", "features-manage"). + addRule().apiGroups("management.cattle.io").resources("features").verbs("get", "list", "watch", "update") + rb.addRole("Create RKE Templates", "clustertemplates-create"). + addRule().apiGroups("management.cattle.io").resources("clustertemplates").verbs("create") + rb.addRole("Create RKE Template Revisions", "clustertemplaterevisions-create"). + addRule().apiGroups("management.cattle.io").resources("clustertemplaterevisions").verbs("create") + rb.addRole("View Rancher Metrics", "view-rancher-metrics"). + addRule().apiGroups("management.cattle.io").resources("ranchermetrics").verbs("get") + + rb.addRole("Admin", "admin"). + addRule().apiGroups("*").resources("*").verbs("*"). + addRule().apiGroups().nonResourceURLs("*").verbs("*") + + // restricted-admin will get cluster admin access to all downstream clusters but limited access to the local cluster + restrictedAdminRole := addUserRules(rb.addRole("Restricted Admin", "restricted-admin")) + restrictedAdminRole. + addRule().apiGroups("").resources("secrets").verbs("create"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clustertemplates").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clustertemplaterevisions").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("globalrolebindings").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("globalroles").verbs("delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"). + addRule().apiGroups("management.cattle.io").resources("users", "userattribute", "groups", "groupmembers").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("podsecurityadmissionconfigurationtemplates").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("fleetworkspaces").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("authconfigs").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("nodedrivers").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("kontainerdrivers").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("roletemplates").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("catalogs", "templates", "templateversions").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("features").verbs("update", "patch", "security-enable").resourceNames("external-rules") + + // restricted-admin can edit settings if rancher is bootstrapped with restricted-admin role + if settings.RestrictedDefaultAdmin.Get() == "true" { + restrictedAdminRole. + addRule().apiGroups("management.cattle.io").resources("settings").verbs("*") + } + + userRole := addUserRules(rb.addRole("User", "user")) + userRole. + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("podsecurityadmissionconfigurationtemplates").verbs("get", "list", "watch") + + userRole.addNamespacedRule("cattle-global-data").addRule().apiGroups("").resources("secrets").verbs("create") + + rb.addRole("User Base", "user-base"). + addRule().apiGroups("management.cattle.io").resources("preferences").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("settings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("features").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("sourcecodecredentials").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("sourcecoderepositories").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("rancherusernotifications").verbs("get", "list", "watch") + + // TODO user should be dynamically authorized to only see herself + // TODO enable when groups are "in". they need to be self-service + + if err := rb.reconcileGlobalRoles(wrangler.Mgmt.GlobalRole()); err != nil { + return "", fmt.Errorf("problem reconciling global roles: %w", err) + } + + // RoleTemplates to be used inside of clusters + rb = newRoleBuilder() + + // K8s default roles + rb.addRoleTemplate("Kubernetes cluster-admin", "cluster-admin", "cluster", true, true, true) + rb.addRoleTemplate("Kubernetes admin", "admin", "project", true, true, false) + rb.addRoleTemplate("Kubernetes edit", "edit", "project", true, true, false) + rb.addRoleTemplate("Kubernetes view", "view", "project", true, true, false) + + // Cluster roles + rb.addRoleTemplate("Cluster Owner", "cluster-owner", "cluster", false, false, true). + addRule().apiGroups("*").resources("*").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("own"). + addRule().apiGroups("provisioning.cattle.io").resources("clusters").verbs("*"). + addRule().apiGroups("rke.cattle.io").resources("etcdsnapshots").verbs("get", "list", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machines").verbs("*"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("*"). + addRule().apiGroups("rke-machine.cattle.io").resources("*").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("projects").verbs("updatepsa"). + addRule().apiGroups("management.cattle.io").resources("clusterproxyconfigs").verbs("*"). + addRule().apiGroups().nonResourceURLs("*").verbs("*") + + rb.addRoleTemplate("Cluster Member", "cluster-member", "cluster", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusterroletemplatebindings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projects").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("nodes", "nodepools").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("nodes").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("apiregistration.k8s.io").resources("apiservices").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusterloggings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clustermonitorgraphs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplates").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplateversions").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusters").resourceNames("local").verbs("get"). + addRule().apiGroups("provisioning.cattle.io").resources("clusters").verbs("get", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machines").verbs("get", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machinedeployments").verbs("get", "watch"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("get", "watch"). + addRule().apiGroups("rke-machine.cattle.io").resources("*").verbs("get", "watch"). + addRule().apiGroups("metrics.k8s.io").resources("nodemetrics", "nodes").verbs("get", "list", "watch") + + rb.addRoleTemplate("Create Projects", "projects-create", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projects").verbs("create") + + rb.addRoleTemplate("View All Projects", "projects-view", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projects").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("namespaces").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch"). + setRoleTemplateNames("view") + + rb.addRoleTemplate("Manage Nodes", "nodes-manage", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("nodes", "nodepools").verbs("*"). + addRule().apiGroups("").resources("nodes").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clustermonitorgraphs").verbs("get", "list", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machines").verbs("*"). + addRule().apiGroups("cluster.x-k8s.io").resources("machinedeployments").verbs("*"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("*"). + addRule().apiGroups("rke-machine.cattle.io").resources("*").verbs("*") + + rb.addRoleTemplate("View Nodes", "nodes-view", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("nodes", "nodepools").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("nodes").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clustermonitorgraphs").verbs("get", "list", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machines").verbs("get", "watch"). + addRule().apiGroups("cluster.x-k8s.io").resources("machinedeployments").verbs("get", "watch"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("get", "watch"). + addRule().apiGroups("rke-machine.cattle.io").resources("*").verbs("get", "watch") + + rb.addRoleTemplate("Manage Storage", "storage-manage", "cluster", false, false, false). + addRule().apiGroups("").resources("persistentvolumes").verbs("*"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("*"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("*") + + rb.addRoleTemplate("Manage Cluster Members", "clusterroletemplatebindings-manage", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("clusterroletemplatebindings").verbs("*") + + rb.addRoleTemplate("View Cluster Members", "clusterroletemplatebindings-view", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("clusterroletemplatebindings").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Cluster Catalogs", "clustercatalogs-manage", "cluster", false, false, true). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("*"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("*") + + rb.addRoleTemplate("View Cluster Catalogs", "clustercatalogs-view", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Cluster Backups", "backups-manage", "cluster", false, false, false). + addRule().apiGroups("management.cattle.io").resources("etcdbackups").verbs("*") + + rb.addRoleTemplate("Manage Navlinks", "navlinks-manage", "cluster", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("*") + + // Project roles + rb.addRoleTemplate("Project Owner", "project-owner", "project", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("nodes").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("sourcecodeproviderconfigs").verbs("*"). + addRule().apiGroups("").resources("namespaces").verbs("create"). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("apiregistration.k8s.io").resources("apiservices").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("*"). + addRule().apiGroups("metrics.k8s.io").resources("pods").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectloggings").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectcatalogs").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplates").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplateversions").verbs("*"). + addRule().apiGroups("monitoring.coreos.com").resources("prometheuses", "prometheusrules", "servicemonitors").verbs("*"). + addRule().apiGroups("networking.istio.io").resources("destinationrules", "envoyfilters", "gateways", "serviceentries", "sidecars", "virtualservices").verbs("*"). + addRule().apiGroups("config.istio.io").resources("apikeys", "authorizations", "checknothings", "circonuses", "deniers", "fluentds", "handlers", "kubernetesenvs", "kuberneteses", "listcheckers", "listentries", "logentries", "memquotas", "metrics", "opas", "prometheuses", "quotas", "quotaspecbindings", "quotaspecs", "rbacs", "reportnothings", "rules", "solarwindses", "stackdrivers", "statsds", "stdios").verbs("*"). + addRule().apiGroups("authentication.istio.io").resources("policies").verbs("*"). + addRule().apiGroups("rbac.istio.io").resources("rbacconfigs", "serviceroles", "servicerolebindings").verbs("*"). + addRule().apiGroups("security.istio.io").resources("authorizationpolicies").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("projects").verbs("own"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("operations").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("releases").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("get").resourceNames("local"). + setRoleTemplateNames("admin") + + rb.addRoleTemplate("Project Member", "project-member", "project", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("*"). + addRule().apiGroups("").resources("namespaces").verbs("create"). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("apiregistration.k8s.io").resources("apiservices").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("*"). + addRule().apiGroups("metrics.k8s.io").resources("pods").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectloggings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectcatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplates").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("catalogtemplateversions").verbs("get", "list", "watch"). + addRule().apiGroups("monitoring.coreos.com").resources("prometheuses", "prometheusrules", "servicemonitors").verbs("*"). + addRule().apiGroups("networking.istio.io").resources("destinationrules", "envoyfilters", "gateways", "serviceentries", "sidecars", "virtualservices").verbs("*"). + addRule().apiGroups("config.istio.io").resources("apikeys", "authorizations", "checknothings", "circonuses", "deniers", "fluentds", "handlers", "kubernetesenvs", "kuberneteses", "listcheckers", "listentries", "logentries", "memquotas", "metrics", "opas", "prometheuses", "quotas", "quotaspecbindings", "quotaspecs", "rbacs", "reportnothings", "rules", "solarwindses", "stackdrivers", "statsds", "stdios").verbs("*"). + addRule().apiGroups("authentication.istio.io").resources("policies").verbs("*"). + addRule().apiGroups("rbac.istio.io").resources("rbacconfigs", "serviceroles", "servicerolebindings").verbs("*"). + addRule().apiGroups("security.istio.io").resources("authorizationpolicies").verbs("*"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("operations").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("releases").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("get").resourceNames("local"). + setRoleTemplateNames("edit") + + rb.addRoleTemplate("Read-only", "read-only", "project", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("apiregistration.k8s.io").resources("apiservices").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("get", "list", "watch"). + addRule().apiGroups("metrics.k8s.io").resources("pods").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectloggings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clustercatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("projectcatalogs").verbs("get", "list", "watch"). + addRule().apiGroups("monitoring.coreos.com").resources("prometheuses", "prometheusrules", "servicemonitors").verbs("get", "list", "watch"). + addRule().apiGroups("networking.istio.io").resources("destinationrules", "envoyfilters", "gateways", "serviceentries", "sidecars", "virtualservices").verbs("get", "list", "watch"). + addRule().apiGroups("config.istio.io").resources("apikeys", "authorizations", "checknothings", "circonuses", "deniers", "fluentds", "handlers", "kubernetesenvs", "kuberneteses", "listcheckers", "listentries", "logentries", "memquotas", "metrics", "opas", "prometheuses", "quotas", "quotaspecbindings", "quotaspecs", "rbacs", "reportnothings", "rules", "solarwindses", "stackdrivers", "statsds", "stdios").verbs("get", "list", "watch"). + addRule().apiGroups("authentication.istio.io").resources("policies").verbs("get", "list", "watch"). + addRule().apiGroups("rbac.istio.io").resources("rbacconfigs", "serviceroles", "servicerolebindings").verbs("get", "list", "watch"). + addRule().apiGroups("security.istio.io").resources("authorizationpolicies").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("clusterrepos").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("operations").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("releases").verbs("get", "list", "watch"). + addRule().apiGroups("catalog.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("get").resourceNames("local"). + setRoleTemplateNames("view") + + rb.addRoleTemplate("Create Namespaces", "create-ns", "project", false, false, false). + addRule().apiGroups("").resources("namespaces").verbs("create") + + rb.addRoleTemplate("Manage Workloads", "workloads-manage", "project", false, false, false). + addRule().apiGroups("").resources("pods", "pods/attach", "pods/exec", "pods/portforward", "pods/proxy", "replicationcontrollers", + "replicationcontrollers/scale").verbs("*"). + addRule().apiGroups("apps").resources("daemonsets", "deployments", "deployments/rollback", "deployments/scale", "replicasets", + "replicasets/scale", "statefulsets", "statefulsets/scale").verbs("*"). + addRule().apiGroups("autoscaling").resources("horizontalpodautoscalers").verbs("*"). + addRule().apiGroups("batch").resources("cronjobs", "jobs").verbs("*"). + addRule().apiGroups("").resources("limitranges", "pods/log", "pods/status", "replicationcontrollers/status", "resourcequotas", "resourcequotas/status", "bindings").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("*"). + rb.addRoleTemplate("View Workloads", "workloads-view", "project", false, false, false). + addRule().apiGroups("").resources("pods", "replicationcontrollers", "replicationcontrollers/scale").verbs("get", "list", "watch"). + addRule().apiGroups("apps").resources("daemonsets", "deployments", "deployments/rollback", "deployments/scale", "replicasets", + "replicasets/scale", "statefulsets").verbs("get", "list", "watch"). + addRule().apiGroups("autoscaling").resources("horizontalpodautoscalers").verbs("get", "list", "watch"). + addRule().apiGroups("batch").resources("cronjobs", "jobs").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("limitranges", "pods/log", "pods/status", "replicationcontrollers/status", "resourcequotas", "resourcequotas/status", "bindings").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apps").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("apprevisions").verbs("get", "list", "watch"). + rb.addRoleTemplate("Manage Ingress", "ingress-manage", "project", false, false, false). + addRule().apiGroups("extensions").resources("ingresses").verbs("*"). + addRule().apiGroups("networking.k8s.io").resources("ingresses").verbs("*") + + rb.addRoleTemplate("View Ingress", "ingress-view", "project", false, false, false). + addRule().apiGroups("extensions").resources("ingresses").verbs("get", "list", "watch"). + addRule().apiGroups("networking.k8s.io").resources("ingresses").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Services", "services-manage", "project", false, false, false). + addRule().apiGroups("").resources("services", "services/proxy", "endpoints").verbs("*") + + rb.addRoleTemplate("View Services", "services-view", "project", false, false, false). + addRule().apiGroups("").resources("services", "endpoints").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Secrets", "secrets-manage", "project", false, false, false). + addRule().apiGroups("").resources("secrets").verbs("*") + + rb.addRoleTemplate("View Secrets", "secrets-view", "project", false, false, false). + addRule().apiGroups("").resources("secrets").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Config Maps", "configmaps-manage", "project", false, false, false). + addRule().apiGroups("").resources("configmaps").verbs("*") + + rb.addRoleTemplate("View Config Maps", "configmaps-view", "project", false, false, false). + addRule().apiGroups("").resources("configmaps").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Volumes", "persistentvolumeclaims-manage", "project", false, false, false). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("*") + + rb.addRoleTemplate("View Volumes", "persistentvolumeclaims-view", "project", false, false, false). + addRule().apiGroups("").resources("persistentvolumes").verbs("get", "list", "watch"). + addRule().apiGroups("storage.k8s.io").resources("storageclasses").verbs("get", "list", "watch"). + addRule().apiGroups("").resources("persistentvolumeclaims").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Service Accounts", "serviceaccounts-manage", "project", false, false, false). + addRule().apiGroups("").resources("serviceaccounts").verbs("*") + + rb.addRoleTemplate("View Service Accounts", "serviceaccounts-view", "project", false, false, false). + addRule().apiGroups("").resources("serviceaccounts").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Project Members", "projectroletemplatebindings-manage", "project", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("*") + + rb.addRoleTemplate("View Project Members", "projectroletemplatebindings-view", "project", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projectroletemplatebindings").verbs("get", "list", "watch") + + rb.addRoleTemplate("Manage Project Catalogs", "projectcatalogs-manage", "project", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projectcatalogs").verbs("*") + + rb.addRoleTemplate("View Project Catalogs", "projectcatalogs-view", "project", false, false, false). + addRule().apiGroups("management.cattle.io").resources("projectcatalogs").verbs("get", "list", "watch") + + rb.addRoleTemplate("Project Monitoring View Role", "project-monitoring-readonly", "project", false, true, false). + addRule().apiGroups("monitoring.cattle.io").resources("prometheus").verbs("view"). + setRoleTemplateNames("view") + + proxyNames := []string{ + "http:rancher-monitoring-prometheus:9090", + "https:rancher-monitoring-prometheus:9090", + "http:rancher-monitoring-alertmanager:9093", + "https:rancher-monitoring-alertmanager:9093", + "http:rancher-monitoring-grafana:80", + "https:rancher-monitoring-grafana:80", + } + endpointNames := []string{ + "rancher-monitoring-prometheus", + "rancher-monitoring-alertmanager", + "rancher-monitoring-grafana", + } + + rb.addRoleTemplate("View Monitoring", "monitoring-ui-view", "project", true, false, false). + addExternalRule().apiGroups("").resources("services/proxy").verbs("get", "create").resourceNames(proxyNames...). + addExternalRule().apiGroups("").resources("endpoints").verbs("list").resourceNames(endpointNames...) + + rb.addRoleTemplate("View Navlinks", "navlinks-view", "project", false, false, false). + addRule().apiGroups("ui.cattle.io").resources("navlinks").verbs("get", "list", "watch") + + // Not specific to project or cluster + // TODO When clusterevents has value, consider adding this back in + //rb.addRoleTemplate("View Events", "events-view", "", true, false, false). + // addRule().apiGroups("").resources("events").verbs("get", "list", "watch"). + // addRule().apiGroups("management.cattle.io").resources("clusterevents").verbs("get", "list", "watch") + + if err := rb.reconcileRoleTemplates(wrangler.Mgmt.RoleTemplate()); err != nil { + return "", fmt.Errorf("problem reconciling role templates: %w", err) + } + + adminName, err := BootstrapAdmin(wrangler) + if err != nil { + return "", err + } + + err = bootstrapDefaultRoles(management) + if err != nil { + return "", err + } + + return adminName, nil +} + +func addUserRules(role *roleBuilder) *roleBuilder { + role. + addRule().apiGroups("management.cattle.io").resources("principals", "roletemplates").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("preferences").verbs("*"). + addRule().apiGroups("management.cattle.io").resources("settings").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("features").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("templates", "templateversions", "catalogs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("clusters").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("nodedrivers").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("kontainerdrivers").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("nodetemplates").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("fleetworkspaces").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("multiclusterapps", "globaldnses", "globaldnsproviders", "clustertemplaterevisions").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("rkek8ssystemimages").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("rkek8sserviceoptions").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("rkeaddons").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("cisconfigs").verbs("get", "list", "watch"). + addRule().apiGroups("management.cattle.io").resources("cisbenchmarkversions").verbs("get", "list", "watch"). + addRule().apiGroups("project.cattle.io").resources("sourcecodecredentials").verbs("*"). + addRule().apiGroups("project.cattle.io").resources("sourcecoderepositories").verbs("*"). + addRule().apiGroups("provisioning.cattle.io").resources("clusters").verbs("create"). + addRule().apiGroups("rke-machine-config.cattle.io").resources("*").verbs("create"). + addRule().apiGroups("management.cattle.io").resources("rancherusernotifications").verbs("get", "list", "watch") + return role +} + +// BootstrapAdmin checks if the bootstrapAdminConfig exists, if it does this indicates rancher has +// already created the admin user and should not attempt it again. Otherwise attempt to create the admin. +func BootstrapAdmin(management *wrangler.Context) (string, error) { + adminCreateLock.Lock() + defer adminCreateLock.Unlock() + + if settings.NoDefaultAdmin.Get() == "true" { + return "", nil + } + var adminName string + + set := labels.Set(defaultAdminLabel) + admins, err := management.Mgmt.User().List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return "", err + } + + if len(admins.Items) > 0 { + adminName = admins.Items[0].Name + } + + if _, err := management.K8s.CoreV1().ConfigMaps(cattleNamespace).Get(context.TODO(), bootstrapAdminConfig, v1.GetOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + logrus.Warnf("Unable to determine if admin user already created: %v", err) + return "", nil + } + } else { + // config map already exists, nothing to do + return adminName, nil + } + + users, err := management.Mgmt.User().List(v1.ListOptions{}) + if err != nil { + return "", err + } + + if len(users.Items) == 0 { + // Config map does not exist and no users, attempt to create the default admin user + bootstrapPassword, bootstrapPasswordIsGenerated, err := GetBootstrapPassword(context.TODO(), management.K8s.CoreV1().Secrets(cattleNamespace)) + if err != nil { + return "", fmt.Errorf("failed to retrieve bootstrap password: %w", err) + } + + bootstrapPasswordHash, _ := bcrypt.GenerateFromPassword([]byte(bootstrapPassword), bcrypt.DefaultCost) + + admin, err := management.Mgmt.User().Create(&v3.User{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "user-", + Labels: defaultAdminLabel, + }, + DisplayName: "Default Admin", + Username: "admin", + Password: string(bootstrapPasswordHash), + MustChangePassword: bootstrapPasswordIsGenerated || bootstrapPassword == "admin", + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return "", fmt.Errorf("can not ensure admin user exists: %w", err) + } + if err == nil { + var serverURL string + if settings.ServerURL.Get() != "" { + serverURL = settings.ServerURL.Get() + } + if serverURL == "" { + ip, err := net.ChooseHostInterface() + if err == nil { + serverURL = "https://" + ip.String() + } + } + if serverURL == "" { + serverURL = "https://" + "localhost" + } + + logrus.Infof("") + logrus.Infof("-----------------------------------------") + logrus.Infof("Welcome to Rancher") + if bootstrapPasswordIsGenerated { + logrus.Infof("A bootstrap password has been generated for your admin user.") + logrus.Infof("") + logrus.Infof("Bootstrap Password: %s", bootstrapPassword) + logrus.Infof("") + logrus.Infof("Use %s/dashboard/?setup=%s to complete setup in the UI", serverURL, bootstrapPassword) + } else { + logrus.Infof("") + logrus.Infof("Use %s/dashboard/ to complete setup in the UI", serverURL) + } + logrus.Infof("-----------------------------------------") + logrus.Infof("") + } + adminName = admin.Name + + bindings, err := management.Mgmt.GlobalRoleBinding().List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + logrus.Warnf("Failed to create default admin global role binding: %v", err) + bindings = &v3.GlobalRoleBindingList{} + } + if len(bindings.Items) == 0 { + adminRole := "admin" + if settings.RestrictedDefaultAdmin.Get() == "true" { + adminRole = "restricted-admin" + } + _, err = management.Mgmt.GlobalRoleBinding().Create( + &v3.GlobalRoleBinding{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "globalrolebinding-", + Labels: defaultAdminLabel, + }, + UserName: adminName, + GlobalRoleName: adminRole, + }) + if err != nil && !features.MCM.Enabled() { + _, crbErr := management.RBAC.ClusterRoleBinding().Create(&rbacv1.ClusterRoleBinding{ + ObjectMeta: v1.ObjectMeta{ + GenerateName: "default-admin-", + Labels: defaultAdminLabel, + }, + Subjects: []rbacv1.Subject{{ + Kind: "User", + APIGroup: rbacv1.GroupName, + Name: adminName, + }}, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: "cluster-admin", + }, + }) + if crbErr != nil { + logrus.Warnf("Failed to create default admin global role binding: %v", err) + } + } else if err != nil { + logrus.Warnf("Failed to create default admin global role binding: %v", err) + } else { + logrus.Info("Created default admin user and binding") + } + } + } + + adminConfigMap := corev1.ConfigMap{ + ObjectMeta: v1.ObjectMeta{ + Name: bootstrapAdminConfig, + Namespace: cattleNamespace, + }, + } + + _, err = management.K8s.CoreV1().ConfigMaps(cattleNamespace).Create(context.TODO(), &adminConfigMap, v1.CreateOptions{}) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + logrus.Warnf("Error creating admin config map: %v", err) + } + + } + return adminName, nil +} + +// bootstrapDefaultRoles will set the default roles for user login, cluster create +// and project create. If the default roles already have the bootstrappedRole +// annotation this will be a no-op as this was done on a previous startup and will +// now respect the currently selected defaults. +func bootstrapDefaultRoles(management *config.ManagementContext) error { + user, err := management.Management.GlobalRoles("").Get("user", v1.GetOptions{}) + if err != nil { + return err + } + if _, ok := user.Annotations[bootstrappedRole]; !ok { + copy := user.DeepCopy() + copy.NewUserDefault = true + if copy.Annotations == nil { + copy.Annotations = make(map[string]string) + } + copy.Annotations[bootstrappedRole] = "true" + + _, err := management.Management.GlobalRoles("").Update(copy) + if err != nil { + return err + } + } + + clusterRole, err := management.Management.RoleTemplates("").Get("cluster-owner", v1.GetOptions{}) + if err != nil { + return nil + } + if _, ok := clusterRole.Annotations[bootstrappedRole]; !ok { + copy := clusterRole.DeepCopy() + copy.ClusterCreatorDefault = true + if copy.Annotations == nil { + copy.Annotations = make(map[string]string) + } + copy.Annotations[bootstrappedRole] = "true" + + _, err := management.Management.RoleTemplates("").Update(copy) + if err != nil { + return err + } + } + + projectRole, err := management.Management.RoleTemplates("").Get("project-owner", v1.GetOptions{}) + if err != nil { + return nil + } + if _, ok := projectRole.Annotations[bootstrappedRole]; !ok { + copy := projectRole.DeepCopy() + copy.ProjectCreatorDefault = true + if copy.Annotations == nil { + copy.Annotations = make(map[string]string) + } + copy.Annotations[bootstrappedRole] = "true" + + _, err := management.Management.RoleTemplates("").Update(copy) + if err != nil { + return err + } + } + + return nil +} + +func addClusterRoleForNamespacedCRDs(management *config.ManagementContext) error { + var returnErr error + // If adding Rules for new CRDs to the below ClusterRole, make sure to add them in a sorted order + // ClusterCRDsClusterRole is a CR containing rules for granting restricted-admins access to all CRDs that can be created in a v3.Cluster's namespace + cr := rbacv1.ClusterRole{ + ObjectMeta: v1.ObjectMeta{ + Name: rbac.ClusterCRDsClusterRole, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"*"}, + Verbs: []string{"*"}, + }, + }, + } + err := createOrUpdateClusterRole(management, cr) + returnErr = errors.Join(returnErr, err) + + // ProjectCRDsClusterRole is a CR containing rules for granting restricted-admins access to all CRDs that can be created in a + // v3.Cluster and v3.Project's namespace + cr = rbacv1.ClusterRole{ + ObjectMeta: v1.ObjectMeta{ + Name: rbac.ProjectCRDsClusterRole, + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"*"}, + Verbs: []string{"*"}, + }, + { + APIGroups: []string{"project.cattle.io"}, + Resources: []string{"*"}, + Verbs: []string{"*"}, + }, + }, + } + err = createOrUpdateClusterRole(management, cr) + returnErr = errors.Join(returnErr, err) + + return returnErr +} + +func createOrUpdateClusterRole(management *config.ManagementContext, cr rbacv1.ClusterRole) error { + for _, rule := range cr.Rules { + sort.Slice(rule.APIGroups, func(i, j int) bool { return rule.APIGroups[i] < rule.APIGroups[j] }) + } + sort.Slice(cr.Rules, func(i, j int) bool { + return cr.Rules[i].APIGroups[0] < cr.Rules[j].APIGroups[0] + }) + _, err := management.RBAC.ClusterRoles("").Create(&cr) + if err != nil { + if !apierrors.IsAlreadyExists(err) { + return err + } + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + existingCR, err := management.RBAC.ClusterRoles("").Get(cr.Name, v1.GetOptions{}) + if err != nil { + return err + } + if reflect.DeepEqual(cr.Rules, existingCR.Rules) { + return nil + } + existingCR.Rules = cr.Rules + _, err = management.RBAC.ClusterRoles("").Update(existingCR) + return err + }) + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder.go new file mode 100644 index 0000000..3426f15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder.go @@ -0,0 +1,418 @@ +package management + +import ( + "fmt" + "reflect" + + "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" +) + +var defaultGRLabel = map[string]string{"authz.management.cattle.io/bootstrapping": "default-globalrole"} +var defaultRTLabel = map[string]string{"authz.management.cattle.io/bootstrapping": "default-roletemplate"} + +type roleBuilder struct { + previous *roleBuilder + next *roleBuilder + name string + displayName string + context string + builtin bool + external bool + hidden bool + administrative bool + roleTemplateNames []string + rules []*ruleBuilder + namespacedRules []*namespacedRuleBuilder + externalRules []*ruleBuilder +} + +func (rb *roleBuilder) String() string { + return fmt.Sprintf("%s (%s): %s", rb.displayName, rb.name, rb.rules) +} + +func newRoleBuilder() *roleBuilder { + return &roleBuilder{ + builtin: true, + } +} + +func (rb *roleBuilder) addRoleTemplate(displayName, name, context string, external, hidden, administrative bool) *roleBuilder { + r := rb.addRole(displayName, name) + r.context = context + r.external = external + r.hidden = hidden + r.administrative = administrative + return r +} + +func (rb *roleBuilder) addRole(displayName, name string) *roleBuilder { + if rb.name == "" { + rb.name = name + rb.displayName = displayName + return rb + } + + if rb.next != nil { + return rb.next.addRole(displayName, name) + } + rb.next = newRoleBuilder() + rb.next.name = name + rb.next.displayName = displayName + rb.next.previous = rb + + return rb.next +} + +func (rb *roleBuilder) addRule() *ruleBuilder { + r := &ruleBuilder{ + rb: rb, + } + rb.rules = append(rb.rules, r) + return r +} + +func (rb *roleBuilder) addExternalRule() *ruleBuilder { + r := &ruleBuilder{ + rb: rb, + } + rb.externalRules = append(rb.externalRules, r) + return r +} + +func (rb *roleBuilder) addNamespacedRule(namespace string) *namespacedRuleBuilder { + n := &namespacedRuleBuilder{ + rb: rb, + rules: []*ruleBuilder{}, + _namespace: namespace, + } + rb.namespacedRules = append(rb.namespacedRules, n) + return n +} + +func (rb *roleBuilder) setRoleTemplateNames(names ...string) *roleBuilder { + rb.roleTemplateNames = names + return rb +} + +func (rb *roleBuilder) first() *roleBuilder { + if rb.previous == nil { + return rb + } + return rb.previous.first() +} + +func (rb *roleBuilder) policyRules() []rbacv1.PolicyRule { + var prs []rbacv1.PolicyRule + for _, r := range rb.rules { + prs = append(prs, r.toPolicyRule()) + } + return prs +} + +func (rb *roleBuilder) policyExternalRules() []rbacv1.PolicyRule { + var prs []rbacv1.PolicyRule + for _, r := range rb.externalRules { + prs = append(prs, r.toPolicyRule()) + } + return prs +} + +func (rb *roleBuilder) namespacedPolicyRules() map[string][]rbacv1.PolicyRule { + if len(rb.namespacedRules) == 0 { + return nil + } + + nsRules := map[string][]rbacv1.PolicyRule{} + for _, n := range rb.namespacedRules { + var prs []rbacv1.PolicyRule + for _, r := range n.rules { + prs = append(prs, r.toPolicyRule()) + } + nsRules[n._namespace] = prs + } + return nsRules +} + +type ruleBuilder struct { + rb *roleBuilder + _verbs []string + _resources []string + _resourceNames []string + _apiGroups []string + _urls []string +} + +func (r *ruleBuilder) String() string { + return fmt.Sprintf("apigroups: %v, resource: %v, resourceNames: %v, nonResourceURLs %v, verbs: %v", r._apiGroups, r._resources, r._resourceNames, r._urls, r._verbs) +} + +func (r *ruleBuilder) verbs(v ...string) *ruleBuilder { + r._verbs = append(r._verbs, v...) + return r +} + +func (r *ruleBuilder) resources(rc ...string) *ruleBuilder { + r._resources = append(r._resources, rc...) + return r +} + +func (r *ruleBuilder) resourceNames(rn ...string) *ruleBuilder { + r._resourceNames = append(r._resourceNames, rn...) + return r +} + +func (r *ruleBuilder) apiGroups(a ...string) *ruleBuilder { + r._apiGroups = append(r._apiGroups, a...) + return r +} + +func (r *ruleBuilder) nonResourceURLs(u ...string) *ruleBuilder { + r._urls = append(r._urls, u...) + return r +} + +func (r *ruleBuilder) addRoleTemplate(displayName, name, context string, external, hidden, administrative bool) *roleBuilder { + return r.rb.addRoleTemplate(displayName, name, context, external, hidden, administrative) +} + +func (r *ruleBuilder) addRole(displayName, name string) *roleBuilder { + return r.rb.addRole(displayName, name) +} + +func (r *ruleBuilder) addRule() *ruleBuilder { + return r.rb.addRule() +} + +func (r *ruleBuilder) addExternalRule() *ruleBuilder { + return r.rb.addExternalRule() +} + +func (r *ruleBuilder) setRoleTemplateNames(names ...string) *roleBuilder { + return r.rb.setRoleTemplateNames(names...) +} + +func (r *ruleBuilder) reconcileGlobalRoles(grClient wranglerv3.GlobalRoleClient) error { + return r.rb.reconcileGlobalRoles(grClient) +} + +func (r *ruleBuilder) reconcileRoleTemplates(rtClient wranglerv3.RoleTemplateClient) error { + return r.rb.reconcileRoleTemplates(rtClient) +} + +func (r *ruleBuilder) toPolicyRule() rbacv1.PolicyRule { + return rbacv1.PolicyRule{ + APIGroups: r._apiGroups, + Resources: r._resources, + ResourceNames: r._resourceNames, + NonResourceURLs: r._urls, + Verbs: r._verbs, + } +} + +type namespacedRuleBuilder struct { + rb *roleBuilder + rules []*ruleBuilder + _namespace string +} + +func (n *namespacedRuleBuilder) String() string { + return fmt.Sprintf("namespace: %v, rules: %v", n._namespace, n.rules) +} + +func (n *namespacedRuleBuilder) addRule() *ruleBuilder { + r := &ruleBuilder{ + rb: n.rb, + } + n.rules = append(n.rules, r) + return r +} + +// buildFnc takes in a roleBuilder and returns desired runtime.Objects. +type buildFnc[T runtime.Object] func(thisRB *roleBuilder) (name string, object T, err error) + +// compareAndModifyFnc check two objects and returns if they are different as well as the desired object to create. +// haveObj will be mutated and returned contain the desired values from the wantObj. +type compareAndModifyFnc[T runtime.Object] func(haveObj T, wantObj T) (isDifferent bool, desiredObject T, err error) + +// gatherExistingFnc returns a map of objects that already exist using the object name as the key. +type gatherExistingFnc[T runtime.Object] func() (ObjectNameMap map[string]T, err error) + +func reconcile[T generic.RuntimeMetaObject, TList runtime.Object]( + rb *roleBuilder, build buildFnc[T], gatherExisting gatherExistingFnc[T], + compareAndModify compareAndModifyFnc[T], client generic.NonNamespacedClientInterface[T, TList]) error { + current := rb.first() + builtRoles := map[string]T{} + for current != nil { + name, role, err := build(current) + if err != nil { + return errors.Wrapf(err, "couldn't create %v", name) + } + if name != "" { + builtRoles[name] = role + } + current = current.next + } + + existing, err := gatherExisting() + if err != nil { + return err + } + + for name := range existing { + if _, ok := builtRoles[name]; !ok { + logrus.Infof("Removing %v", name) + if err := client.Delete(name, nil); err != nil { + return errors.Wrapf(err, "couldn't delete %v", name) + } + delete(existing, name) + } + } + + for name, gr := range builtRoles { + if existingCR, ok := existing[name]; ok { + equal, modified, err := compareAndModify(existingCR, gr) + if err != nil { + return err + } + if !equal { + if _, err := client.Update(modified); err != nil { + return errors.Wrapf(err, "couldn't update %v", name) + } + } + continue + } + + logrus.Infof("Creating %v", name) + if _, err := client.Create(gr); err != nil { + return errors.Wrapf(err, "couldn't create %v", name) + } + } + + return nil +} + +func (rb *roleBuilder) reconcileGlobalRoles(grClient wranglerv3.GlobalRoleClient) error { + logrus.Info("Reconciling GlobalRoles") + build := func(current *roleBuilder) (string, *v3.GlobalRole, error) { + gr := &v3.GlobalRole{ + ObjectMeta: v1.ObjectMeta{ + Name: current.name, + Labels: defaultGRLabel, + }, + DisplayName: current.displayName, + Rules: current.policyRules(), + Builtin: current.builtin, + NamespacedRules: current.namespacedPolicyRules(), + } + return gr.Name, gr, nil + } + + gather := func() (map[string]*v3.GlobalRole, error) { + set := labels.Set(defaultGRLabel) + existingList, err := grClient.List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return nil, errors.Wrapf(err, "couldn't list globalRoles with selector %s", set) + } + + existing := map[string]*v3.GlobalRole{} + for _, e := range existingList.Items { + existing[e.Name] = e.DeepCopy() + } + + return existing, nil + } + + compareAndMod := func(haveGR *v3.GlobalRole, wantGR *v3.GlobalRole) (bool, *v3.GlobalRole, error) { + builtin := haveGR.Builtin == wantGR.Builtin + equal := builtin && haveGR.DisplayName == wantGR.DisplayName && reflect.DeepEqual(haveGR.Rules, wantGR.Rules) && reflect.DeepEqual(haveGR.NamespacedRules, wantGR.NamespacedRules) + + haveGR.DisplayName = wantGR.DisplayName + haveGR.Rules = wantGR.Rules + haveGR.NamespacedRules = wantGR.NamespacedRules + haveGR.Builtin = wantGR.Builtin + + return equal, haveGR, nil + } + + // create a new client that impersonates the webhook to bypass field validation that would normally block updating builtin roles + bypassClient, err := grClient.WithImpersonation(controllers.WebhookImpersonation()) + if err != nil { + return fmt.Errorf("failed to make impersonation client: %w", err) + } + return reconcile(rb, build, gather, compareAndMod, bypassClient) +} + +func (rb *roleBuilder) reconcileRoleTemplates(rtClient wranglerv3.RoleTemplateClient) error { + logrus.Info("Reconciling RoleTemplates") + build := func(current *roleBuilder) (string, *v3.RoleTemplate, error) { + if current.externalRules != nil && !current.external { + return "", nil, fmt.Errorf("can't create RoleTemplate with externalRules and external=false") + } + role := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: current.name, + Labels: defaultRTLabel, + }, + DisplayName: current.displayName, + Builtin: current.builtin, + External: current.external, + ExternalRules: current.policyExternalRules(), + Hidden: current.hidden, + Context: current.context, + Rules: current.policyRules(), + RoleTemplateNames: current.roleTemplateNames, + Administrative: current.administrative, + } + return role.Name, role, nil + } + + gather := func() (map[string]*v3.RoleTemplate, error) { + set := labels.Set(defaultRTLabel) + existingList, err := rtClient.List(v1.ListOptions{LabelSelector: set.String()}) + if err != nil { + return nil, errors.Wrapf(err, "couldn't list roleTemplate with selector %s", set) + } + + existing := map[string]*v3.RoleTemplate{} + for _, e := range existingList.Items { + existing[e.Name] = e.DeepCopy() + } + + return existing, nil + } + + compareAndMod := func(haveRT *v3.RoleTemplate, wantRT *v3.RoleTemplate) (bool, *v3.RoleTemplate, error) { + equal := haveRT.DisplayName == wantRT.DisplayName && reflect.DeepEqual(haveRT.Rules, wantRT.Rules) && reflect.DeepEqual(haveRT.ExternalRules, wantRT.ExternalRules) && + reflect.DeepEqual(haveRT.RoleTemplateNames, wantRT.RoleTemplateNames) && haveRT.Builtin == wantRT.Builtin && + haveRT.External == wantRT.External && haveRT.Hidden == wantRT.Hidden && haveRT.Context == wantRT.Context && + haveRT.Administrative == wantRT.Administrative + + haveRT.DisplayName = wantRT.DisplayName + haveRT.Rules = wantRT.Rules + haveRT.ExternalRules = wantRT.ExternalRules + haveRT.RoleTemplateNames = wantRT.RoleTemplateNames + haveRT.Builtin = wantRT.Builtin + haveRT.External = wantRT.External + haveRT.Hidden = wantRT.Hidden + haveRT.Context = wantRT.Context + haveRT.Administrative = wantRT.Administrative + + return equal, haveRT, nil + } + + // create a new client that impersonates the webhook to bypass field validation that would normally block updating builtin roles + bypassClient, err := rtClient.WithImpersonation(controllers.WebhookImpersonation()) + if err != nil { + return fmt.Errorf("failed to make impersonation client: %w", err) + } + return reconcile(rb, build, gather, compareAndMod, bypassClient) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder_test.go new file mode 100644 index 0000000..eea299a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/rolebuilder_test.go @@ -0,0 +1,704 @@ +package management + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var errExpected = fmt.Errorf("expected error") + +type testMocks struct { + t *testing.T + grClientMock *fake.MockNonNamespacedClientInterface[*v3.GlobalRole, *v3.GlobalRoleList] + rtClientMock *fake.MockNonNamespacedClientInterface[*v3.RoleTemplate, *v3.RoleTemplateList] +} + +var ( + ruleReadPods = rbacv1.PolicyRule{ + Verbs: []string{"GET", "WATCH"}, + APIGroups: []string{"v1"}, + Resources: []string{"pods"}, + } + ruleReadServices = rbacv1.PolicyRule{ + Verbs: []string{"GET", "WATCH"}, + APIGroups: []string{"v1"}, + Resources: []string{"services"}, + } + ruleWriteNodes = rbacv1.PolicyRule{ + Verbs: []string{"PUT", "CREATE", "UPDATE"}, + APIGroups: []string{"v1"}, + Resources: []string{"nodes"}, + } + ruleAdmin = rbacv1.PolicyRule{ + Verbs: []string{"*"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + } +) + +func Test_reconcileGlobalRoles(t *testing.T) { + readGR := &v3.GlobalRole{ + ObjectMeta: v1.ObjectMeta{ + Name: "read-gr", + }, + DisplayName: "Read GR", + Rules: []rbacv1.PolicyRule{ruleReadPods, ruleReadServices}, + Builtin: true, + } + adminGR := &v3.GlobalRole{ + ObjectMeta: v1.ObjectMeta{ + Name: "admin-gr", + }, + DisplayName: "Admin GR", + Rules: []rbacv1.PolicyRule{ruleAdmin}, + Builtin: true, + } + basicGR := &v3.GlobalRole{ + ObjectMeta: v1.ObjectMeta{ + Name: "basic-gr", + }, + DisplayName: "Basic GR", + Rules: []rbacv1.PolicyRule{ruleReadPods}, + Builtin: true, + } + namespacedGR := &v3.GlobalRole{ + ObjectMeta: v1.ObjectMeta{ + Name: "namespaced-gr", + }, + DisplayName: "Namespaced GR", + NamespacedRules: map[string][]rbacv1.PolicyRule{ + "namespace1": {ruleReadPods}, + }, + Builtin: true, + } + tests := []struct { + name string + grsToCreate []*v3.GlobalRole + setup func(mocks testMocks) + wantErr bool + }{ + { + name: "Create new GR with no preexisting", + grsToCreate: []*v3.GlobalRole{basicGR}, + setup: func(mocks testMocks) { + + // return empty list + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(&v3.GlobalRoleList{}, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(basicGR)).DoAndReturn( + func(toCreate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, basicGR.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }) + }, + }, + { + name: "Create new GR and append to existing", + grsToCreate: []*v3.GlobalRole{basicGR, adminGR}, + setup: func(mocks testMocks) { + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*adminGR}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(basicGR)).DoAndReturn( + func(toCreate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, basicGR.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }) + + }, + }, + { + name: "Create multiple new GRs", + grsToCreate: []*v3.GlobalRole{basicGR, readGR, adminGR}, + setup: func(mocks testMocks) { + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*adminGR}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(basicGR)).DoAndReturn( + func(toCreate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, basicGR.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicGR.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }, + ) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(readGR)).DoAndReturn( + func(toCreate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, readGR.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, readGR.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, readGR.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }, + ) + }, + }, + { + name: "Create GR with NamespacedRules", + grsToCreate: []*v3.GlobalRole{namespacedGR}, + setup: func(mocks testMocks) { + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(&v3.GlobalRoleList{}, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(namespacedGR)).DoAndReturn( + func(toCreate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, namespacedGR.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, namespacedGR.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, namespacedGR.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, namespacedGR.NamespacedRules, toCreate.NamespacedRules, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }) + }, + }, + { + name: "Update existing GR DisplayName", + grsToCreate: []*v3.GlobalRole{adminGR}, + setup: func(mocks testMocks) { + oldAdmin := adminGR.DeepCopy() + oldAdmin.DisplayName = "Old Display Name" + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*oldAdmin}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Update(ObjectMatcher(adminGR)).DoAndReturn( + func(toUpdate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, adminGR.Rules, toUpdate.Rules, "roleBuilder attempted to update rules that were not changed") + require.EqualValues(mocks.t, adminGR.DisplayName, toUpdate.DisplayName, "roleBuilder did not attempt to update the correct DisplayName") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing GR Rules", + grsToCreate: []*v3.GlobalRole{adminGR}, + setup: func(mocks testMocks) { + oldAdmin := adminGR.DeepCopy() + oldAdmin.Rules = append(oldAdmin.Rules, ruleWriteNodes) + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*oldAdmin}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Update(ObjectMatcher(adminGR)).DoAndReturn( + func(toUpdate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, adminGR.Rules, toUpdate.Rules, "roleBuilder did not attempt to update the correct rules") + require.EqualValues(mocks.t, adminGR.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing GR Namespaced Rules", + grsToCreate: []*v3.GlobalRole{namespacedGR}, + setup: func(mocks testMocks) { + oldGR := namespacedGR.DeepCopy() + oldGR.NamespacedRules["namespace2"] = []rbacv1.PolicyRule{ruleReadServices} + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*oldGR}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Update(ObjectMatcher(namespacedGR)).DoAndReturn( + func(toUpdate *v3.GlobalRole) (*v3.GlobalRole, error) { + require.EqualValues(mocks.t, namespacedGR.Rules, toUpdate.Rules, "roleBuilder did not attempt to update the correct rules") + require.EqualValues(mocks.t, namespacedGR.NamespacedRules, toUpdate.NamespacedRules, "roleBuilder did not attempt to update the correct rules") + require.EqualValues(mocks.t, namespacedGR.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Delete existing GR Rules", + grsToCreate: nil, + setup: func(mocks testMocks) { + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*adminGR}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Delete(adminGR.Name, nil).Return(nil) + }, + }, + { + name: "Fail to delete existing GR Rules", + wantErr: true, + setup: func(mocks testMocks) { + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*adminGR}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Delete(adminGR.Name, nil).Return(errExpected) + }, + }, + { + name: "Fail to list existing GR Rules", + wantErr: true, + setup: func(mocks testMocks) { + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(nil, errExpected) + }, + }, + { + name: "Fail to create new GR", + grsToCreate: []*v3.GlobalRole{basicGR}, + wantErr: true, + setup: func(mocks testMocks) { + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(&v3.GlobalRoleList{}, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Create(ObjectMatcher(basicGR)).Return(nil, errExpected) + }, + }, + { + name: "Fail to update existing GR", + grsToCreate: []*v3.GlobalRole{adminGR}, + wantErr: true, + setup: func(mocks testMocks) { + oldAdmin := adminGR.DeepCopy() + oldAdmin.Rules = append(oldAdmin.Rules, ruleWriteNodes) + curr := &v3.GlobalRoleList{Items: []v3.GlobalRole{*oldAdmin}} + mocks.grClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.grClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.grClientMock, nil) + mocks.grClientMock.EXPECT().Update(ObjectMatcher(adminGR)).Return(nil, errExpected) + }, + }, + } + for _, tt := range tests { + test := tt + t.Run(test.name, func(t *testing.T) { + t.Parallel() + rb := newRoleBuilder() + addGlobalRole(rb, test.grsToCreate...) + ctrl := gomock.NewController(t) + mocks := testMocks{ + t: t, + grClientMock: fake.NewMockNonNamespacedClientInterface[*v3.GlobalRole, *v3.GlobalRoleList](ctrl), + } + if test.setup != nil { + test.setup(mocks) + } + err := rb.reconcileGlobalRoles(mocks.grClientMock) + if test.wantErr { + require.Error(t, err, "Expected an error while reconciling roles.") + } else { + require.NoError(t, err, "Unexpected error while reconciling roles.") + } + }) + } +} + +func Test_reconcileRoleTemplate(t *testing.T) { + readRT := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: "read-rt", + }, + DisplayName: "Read RT", + Rules: []rbacv1.PolicyRule{ruleReadPods, ruleReadServices}, + Context: "cluster", + Builtin: true, + } + adminRT := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: "admin-rt", + }, + DisplayName: "Admin RT", + Rules: []rbacv1.PolicyRule{ruleAdmin}, + Context: "cluster", + Builtin: true, + } + basicRT := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: "basic-rt", + }, + DisplayName: "Basic RT", + Rules: []rbacv1.PolicyRule{ruleReadPods}, + Context: "project", + Builtin: true, + } + invalidExternalRT := &v3.RoleTemplate{ + ObjectMeta: v1.ObjectMeta{ + Name: "invalid-external-rt", + }, + DisplayName: "External RT", + Rules: []rbacv1.PolicyRule{ruleAdmin}, + Context: "cluster", + Builtin: true, + ExternalRules: []rbacv1.PolicyRule{ruleReadPods}, + } + tests := []struct { + name string + rtsToCreate []*v3.RoleTemplate + setup func(mocks testMocks) + wantErr bool + }{ + { + name: "Create new RT with no preexisting roles", + rtsToCreate: []*v3.RoleTemplate{basicRT}, + setup: func(mocks testMocks) { + // return empty list + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(&v3.RoleTemplateList{}, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Create(ObjectMatcher(basicRT)).DoAndReturn( + func(toCreate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, basicRT.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }) + }, + }, + { + name: "Create new RT and append to existing", + rtsToCreate: []*v3.RoleTemplate{basicRT, adminRT}, + setup: func(mocks testMocks) { + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*adminRT}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Create(ObjectMatcher(basicRT)).DoAndReturn( + func(toCreate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, basicRT.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }) + }, + }, + { + name: "Create multiple new RTs", + rtsToCreate: []*v3.RoleTemplate{basicRT, adminRT, readRT}, + setup: func(mocks testMocks) { + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*adminRT}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Create(ObjectMatcher(basicRT)).DoAndReturn( + func(toCreate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, basicRT.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, basicRT.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }, + ) + mocks.rtClientMock.EXPECT().Create(ObjectMatcher(readRT)).DoAndReturn( + func(toCreate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, readRT.Rules, toCreate.Rules, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, readRT.Name, toCreate.Name, "roleBuilder did not attempt to create the correct role") + require.EqualValues(mocks.t, readRT.DisplayName, toCreate.DisplayName, "roleBuilder did not attempt to create the correct role") + return toCreate, nil + }, + ) + }, + }, + + { + name: "Update existing RT DisplayName", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.DisplayName = "Update Display Name" + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Rules, toUpdate.Rules, "roleBuilder attempted to update rules that were not changed") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder did not attempt to update the correct DisplayName") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT Rules", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Rules = append(oldAdmin.Rules, ruleWriteNodes) + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Rules, toUpdate.Rules, "roleBuilder did not attempt to update the correct rules") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT builtin bool", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Builtin = false + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Builtin, toUpdate.Builtin, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT External bool", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.External = true + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.External, toUpdate.External, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT external rules", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.External = true + oldAdmin.ExternalRules = []rbacv1.PolicyRule{ruleAdmin} + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.External, toUpdate.External, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.ExternalRules, toUpdate.ExternalRules, "roleBuilder did not make the correct external rules updates") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT Hidden bool", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Hidden = true + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Hidden, toUpdate.Hidden, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT Context", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Context = "project" + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Context, toUpdate.Context, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT inherited RoleTemplates", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.RoleTemplateNames = []string{readRT.Name} + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.RoleTemplateNames, toUpdate.RoleTemplateNames, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Update existing RT Administrative bool", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Administrative = true + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).DoAndReturn( + func(toUpdate *v3.RoleTemplate) (*v3.RoleTemplate, error) { + require.EqualValues(mocks.t, adminRT.Administrative, toUpdate.Administrative, "roleBuilder did not make the correct updates") + require.EqualValues(mocks.t, adminRT.DisplayName, toUpdate.DisplayName, "roleBuilder attempted to update the unchanged display name") + return toUpdate, nil + }) + }, + }, + { + name: "Delete existing RT Rules", + rtsToCreate: nil, + setup: func(mocks testMocks) { + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*adminRT}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Delete(adminRT.Name, nil).Return(nil) + }, + }, + { + name: "Fail to delete existing RT Rules", + rtsToCreate: nil, + setup: func(mocks testMocks) { + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*adminRT}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Delete(adminRT.Name, nil).Return(errExpected) + }, + wantErr: true, + }, + { + name: "Fail to list existing GRB Rules", + wantErr: true, + setup: func(mocks testMocks) { + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(nil, errExpected) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + }, + }, + { + name: "Fail to create new GRB", + rtsToCreate: []*v3.RoleTemplate{basicRT}, + wantErr: true, + setup: func(mocks testMocks) { + // return empty list + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(&v3.RoleTemplateList{}, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Create(ObjectMatcher(basicRT)).Return(nil, errExpected) + }, + }, + { + name: "Fail to update existing GRB", + rtsToCreate: []*v3.RoleTemplate{adminRT}, + wantErr: true, + setup: func(mocks testMocks) { + oldAdmin := adminRT.DeepCopy() + oldAdmin.Rules = append(oldAdmin.Rules, ruleWriteNodes) + curr := &v3.RoleTemplateList{Items: []v3.RoleTemplate{*oldAdmin}} + mocks.rtClientMock.EXPECT().List(gomock.Any()).Return(curr, nil) + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + mocks.rtClientMock.EXPECT().Update(ObjectMatcher(adminRT)).Return(nil, errExpected) + }, + }, + { + name: "Fail to create invalid external RoleTemplate", + rtsToCreate: []*v3.RoleTemplate{invalidExternalRT}, + wantErr: true, + setup: func(mocks testMocks) { + mocks.rtClientMock.EXPECT().WithImpersonation(controllers.WebhookImpersonation()).Return(mocks.rtClientMock, nil) + }, + }, + } + for _, tt := range tests { + test := tt + t.Run(test.name, func(t *testing.T) { + t.Parallel() + rb := newRoleBuilder() + addRoleTemplates(rb, test.rtsToCreate...) + ctrl := gomock.NewController(t) + mocks := testMocks{ + t: t, + rtClientMock: fake.NewMockNonNamespacedClientInterface[*v3.RoleTemplate, *v3.RoleTemplateList](ctrl), + } + if test.setup != nil { + test.setup(mocks) + } + err := rb.reconcileRoleTemplates(mocks.rtClientMock) + if test.wantErr { + require.Error(t, err, "Expected an error while reconciling roles.") + } else { + require.NoError(t, err, "Unexpected error while reconciling roles.") + } + }) + } +} + +func addGlobalRole(builder *roleBuilder, roles ...*v3.GlobalRole) { + for _, gr := range roles { + r := builder.addRole(gr.DisplayName, gr.Name) + addRules(r, gr.Rules...) + addNamespacedRules(builder, gr.NamespacedRules) + } +} + +func addRoleTemplates(builder *roleBuilder, templates ...*v3.RoleTemplate) { + for _, rt := range templates { + builder = builder.addRoleTemplate( + rt.DisplayName, rt.Name, rt.Context, rt.External, rt.Hidden, rt.Administrative, + ) + addRules(builder, rt.Rules...) + addExternalRules(builder, rt.ExternalRules...) + } +} + +func addRules(builder *roleBuilder, rules ...rbacv1.PolicyRule) { + for _, rule := range rules { + rb := builder.addRule() + rb.verbs(rule.Verbs...) + rb.apiGroups(rule.APIGroups...) + rb.resources(rule.Resources...) + rb.resourceNames(rule.ResourceNames...) + rb.nonResourceURLs(rule.NonResourceURLs...) + } +} +func addNamespacedRules(builder *roleBuilder, nsRules map[string][]rbacv1.PolicyRule) { + for ns, rules := range nsRules { + nsrb := builder.addNamespacedRule(ns) + for _, r := range rules { + rb := nsrb.addRule() + rb.verbs(r.Verbs...) + rb.apiGroups(r.APIGroups...) + rb.resources(r.Resources...) + rb.resourceNames(r.ResourceNames...) + rb.nonResourceURLs(r.NonResourceURLs...) + } + } +} + +func addExternalRules(builder *roleBuilder, externalRules ...rbacv1.PolicyRule) { + for _, rule := range externalRules { + rb := builder.addExternalRule() + rb.verbs(rule.Verbs...) + rb.apiGroups(rule.APIGroups...) + rb.resources(rule.Resources...) + rb.resourceNames(rule.ResourceNames...) + rb.nonResourceURLs(rule.NonResourceURLs...) + } +} + +type objectMatcher struct { + name string + namespace string +} + +func (o objectMatcher) Matches(x any) bool { + obj, ok := x.(v1.Object) + if !ok { + return false + } + return obj.GetName() == o.name && obj.GetNamespace() == o.namespace +} +func (o objectMatcher) String() string { + return fmt.Sprintf("is equal to metav1.Object with name: %q and namespace: %q", o.name, o.namespace) +} + +func ObjectMatcher(obj v1.Object) gomock.Matcher { + return &objectMatcher{obj.GetName(), obj.GetNamespace()} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/user_cleanup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/user_cleanup.go new file mode 100644 index 0000000..c81eca5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/data/management/user_cleanup.go @@ -0,0 +1,142 @@ +package management + +import ( + "context" + "fmt" + "strings" + "time" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/types/config" + + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" +) + +type userCleanup struct { + users v3.UserInterface + userLister v3.UserLister + clusterLister v3.ClusterLister + projectLister v3.ProjectLister +} + +func CleanupOrphanedSystemUsers(ctx context.Context, management *config.ManagementContext) { + u := userCleanup{ + users: management.Management.Users(""), + userLister: management.Management.Users("").Controller().Lister(), + clusterLister: management.Management.Clusters("").Controller().Lister(), + projectLister: management.Management.Projects("").Controller().Lister(), + } + + cleanupCtx, cleanupCancel := context.WithCancel(ctx) + go func(context.Context, context.CancelFunc) { + wait.PollImmediate(time.Hour*24, 0, func() (bool, error) { + logrus.Debugf("Starting orphaned system users cleanup with exponentialBackoff") + steps := 5 + backOffDuration := time.Minute * 10 + factor := 2 + var err error + for steps > 0 { + err = u.cleanup() + if err != nil { + time.Sleep(backOffDuration) + backOffDuration = time.Duration(factor) * backOffDuration + } else { + break + } + steps-- + } + if err != nil { + // returning false & nil because PollImmediate terminates on error + logrus.Error(err) + return false, nil + } + // no error returned, user cleanup done, calling the child context's cancelfunc to terminate child context + cleanupCancel() + return true, nil + }) + }(cleanupCtx, cleanupCancel) +} + +func (u *userCleanup) cleanup() error { + users, err := u.userLister.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("error listing users during system account users cleanup: %v", err) + } + clusters, err := u.clusterLister.List("", labels.Everything()) + if err != nil { + return fmt.Errorf("error listing clusters during system account users cleanup: %v", err) + } + var returnErr error + for _, user := range users { + systemUser := false + for _, principal := range user.PrincipalIDs { + if strings.HasPrefix(principal, "system://") { + systemUser = true + break + } + } + if !systemUser { + continue + } + if err := u.checkClusterOrProjectExistsForSystemUser(user, clusters); err != nil { + // errors are logged in checkClusterOrProjectExistsForSystemUser, but continue for loop for other users + // returning only one error at the end is sufficient for ExponentialBackoff/PollImmediate to try this again + returnErr = err + } + } + return returnErr +} + +func (u *userCleanup) checkClusterOrProjectExistsForSystemUser(user *v3.User, clusters []*v3.Cluster) error { + displayName := user.DisplayName + if strings.HasPrefix(user.DisplayName, systemaccount.ClusterSystemAccountPrefix) { + clusterID := strings.TrimPrefix(displayName, systemaccount.ClusterSystemAccountPrefix) + // check if this cluster exists, if not, delete this user + clusterExists := false + for _, cluster := range clusters { + if cluster.Name == clusterID { + clusterExists = true + break + } + } + if clusterExists { + return nil + } + // cluster not found, delete the system user + return u.deleteSystemUser(user.Name) + } else if strings.HasPrefix(user.DisplayName, systemaccount.ProjectSystemAccountPrefix) { + projectID := strings.TrimPrefix(displayName, systemaccount.ProjectSystemAccountPrefix) + // check if this project exists, if not, delete this user + // how to find the cluster ID of this project: go through all clusters + projectExists := false + for _, cluster := range clusters { + project, err := u.projectLister.Get(cluster.Name, projectID) + if err != nil && !errors.IsNotFound(err) { + return fmt.Errorf("error finding project %v during system account users cleanup: %v", projectID, err) + } else if err == nil && project != nil { + projectExists = true + break + } + } + if projectExists { + return nil + } + // project not found, so delete the system user for this project + return u.deleteSystemUser(user.Name) + } + return nil +} + +func (u *userCleanup) deleteSystemUser(userName string) error { + err := u.users.Delete(userName, &v1.DeleteOptions{}) + if err != nil && !errors.IsNotFound(err) && !errors.IsGone(err) { + return err + } + logrus.Debugf("Deleted system user %v since its associated cluster/project no longer exists", userName) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/dialer/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/dialer/factory.go new file mode 100644 index 0000000..95fae1f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/dialer/factory.go @@ -0,0 +1,379 @@ +package dialer + +import ( + "context" + "errors" + "fmt" + "net" + "net/url" + "os" + "strings" + "time" + + "github.com/rancher/norman/types/slice" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/remotedialer" + "github.com/rancher/rke/k8s" + "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + WaitForAgentError = "waiting for cluster [%s] agent to connect" +) + +var ErrAgentDisconnected = errors.New("cluster agent disconnected") + +func NewFactory(apiContext *config.ScaledContext, wrangler *wrangler.Context) (*Factory, error) { + return &Factory{ + clusterLister: apiContext.Management.Clusters("").Controller().Lister(), + nodeLister: apiContext.Management.Nodes("").Controller().Lister(), + TunnelServer: wrangler.TunnelServer, + }, nil +} + +type Factory struct { + nodeLister v3.NodeLister + clusterLister v3.ClusterLister + TunnelServer *remotedialer.Server +} + +func (f *Factory) ClusterDialer(clusterName string, retryOnError bool) (dialer.Dialer, error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + d, err := f.clusterDialer(clusterName, address, retryOnError) + if err != nil { + logrus.Debugf(WaitForAgentError, clusterName) + return nil, err + } + return d(ctx, network, address) + }, nil +} + +func IsCloudDriver(cluster *v3.Cluster) bool { + return !cluster.Spec.Internal && + cluster.Status.Driver != "" && + cluster.Status.Driver != v32.ClusterDriverImported && + cluster.Status.Driver != v32.ClusterDriverRKE && + cluster.Status.Driver != v32.ClusterDriverK3s && + cluster.Status.Driver != v32.ClusterDriverK3os && + cluster.Status.Driver != v32.ClusterDriverRke2 && + cluster.Status.Driver != v32.ClusterDriverRancherD +} + +func IsPublicCloudDriver(cluster *v3.Cluster) bool { + return IsCloudDriver(cluster) && !HasOnlyPrivateAPIEndpoint(cluster) +} + +func HasOnlyPrivateAPIEndpoint(cluster *v3.Cluster) bool { + switch cluster.Status.Driver { + case v32.ClusterDriverAKS: + if cluster.Status.AKSStatus.UpstreamSpec != nil && + cluster.Status.AKSStatus.UpstreamSpec.PrivateCluster != nil && + !*cluster.Status.AKSStatus.UpstreamSpec.PrivateCluster { + return false + } + return cluster.Status.AKSStatus.PrivateRequiresTunnel != nil && + *cluster.Status.AKSStatus.PrivateRequiresTunnel + case v32.ClusterDriverEKS: + if cluster.Status.EKSStatus.UpstreamSpec != nil && + cluster.Status.EKSStatus.UpstreamSpec.PublicAccess != nil && + *cluster.Status.EKSStatus.UpstreamSpec.PublicAccess { + return false + } + return cluster.Status.EKSStatus.PrivateRequiresTunnel != nil && + *cluster.Status.EKSStatus.PrivateRequiresTunnel + case v32.ClusterDriverGKE: + if cluster.Status.GKEStatus.UpstreamSpec != nil && + cluster.Status.GKEStatus.UpstreamSpec.PrivateClusterConfig != nil && + !cluster.Status.GKEStatus.UpstreamSpec.PrivateClusterConfig.EnablePrivateEndpoint { + return false + } + return cluster.Status.GKEStatus.PrivateRequiresTunnel != nil && + *cluster.Status.GKEStatus.PrivateRequiresTunnel + default: + return false + } +} + +func (f *Factory) translateClusterAddress(cluster *v3.Cluster, clusterHostPort, address string) string { + if clusterHostPort != address { + logrus.Tracef("dialerFactory: apiEndpoint clusterHostPort [%s] is not equal to address [%s]", clusterHostPort, address) + return address + } + + host, port, err := net.SplitHostPort(address) + if err != nil { + return address + } + + // Make sure that control plane node we are connecting to is not bad, also use internal address + nodes, err := f.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + logrus.Debugf("Error listing nodes while translating cluster address, returning address [%s], error: %v", address, err) + return address + } + + clusterGood := v32.ClusterConditionReady.IsTrue(cluster) + logrus.Tracef("dialerFactory: ClusterConditionReady for cluster [%s] is [%t]", cluster.Spec.DisplayName, clusterGood) + lastGoodHost := "" + logrus.Trace("dialerFactory: finding a node to tunnel the cluster connection") + for _, node := range nodes { + var ( + publicIP = node.Status.NodeAnnotations[k8s.ExternalAddressAnnotation] + privateIP = node.Status.NodeAnnotations[k8s.InternalAddressAnnotation] + ) + + fakeNode := &v1.Node{ + Status: node.Status.InternalNodeStatus, + } + + nodeGood := v32.NodeConditionRegistered.IsTrue(node) && v32.NodeConditionProvisioned.IsTrue(node) && + !v32.NodeConditionReady.IsUnknown(fakeNode) && node.DeletionTimestamp == nil + + if !nodeGood { + logrus.Tracef("dialerFactory: Skipping node [%s] for tunneling the cluster connection because nodeConditions are not as expected", node.Spec.RequestedHostname) + logrus.Tracef("dialerFactory: Node conditions for node [%s]: %+v", node.Status.NodeName, node.Status.Conditions) + continue + } + if privateIP == "" { + logrus.Tracef("dialerFactory: Skipping node [%s] for tunneling the cluster connection because privateIP is empty", node.Status.NodeName) + continue + } + + logrus.Tracef("dialerFactory: IP addresses for node [%s]: publicIP [%s], privateIP [%s]", node.Status.NodeName, publicIP, privateIP) + + if publicIP == host { + logrus.Tracef("dialerFactory: publicIP [%s] for node [%s] matches apiEndpoint host [%s], checking if cluster condition Ready is True", publicIP, node.Status.NodeName, host) + if clusterGood { + logrus.Trace("dialerFactory: cluster condition Ready is True") + host = privateIP + logrus.Tracef("dialerFactory: Using privateIP [%s] of node [%s] as node to tunnel the cluster connection", privateIP, node.Status.NodeName) + return fmt.Sprintf("%s:%s", host, port) + } + logrus.Debug("dialerFactory: cluster condition Ready is False") + } else if node.Status.NodeConfig != nil && slice.ContainsString(node.Status.NodeConfig.Role, services.ControlRole) { + logrus.Tracef("dialerFactory: setting node [%s] with privateIP [%s] as option for the connection as it is a controlplane node", node.Status.NodeName, privateIP) + lastGoodHost = privateIP + } + } + + if lastGoodHost != "" { + logrus.Tracef("dialerFactory: returning [%s:%s] as last good option to tunnel the cluster connection", lastGoodHost, port) + return fmt.Sprintf("%s:%s", lastGoodHost, port) + } + + logrus.Tracef("dialerFactory: returning [%s], as no good option was found (no match with apiEndpoint or a controlplane node with correct conditions", address) + return address +} + +func (f *Factory) clusterDialer(clusterName, address string, retryOnError bool) (dialer.Dialer, error) { + cluster, err := f.clusterLister.Get("", clusterName) + if err != nil { + return nil, err + } + + if cluster.Spec.Internal { + // For local (embedded, or import) we just assume we can connect directly + return native() + } + + hostPort := hostPort(cluster) + logrus.Tracef("dialerFactory: apiEndpoint hostPort for cluster [%s] is [%s]", clusterName, hostPort) + if (address == hostPort || isProxyAddress(address)) && IsPublicCloudDriver(cluster) { + // For cloud drivers we just connect directly to the k8s API, not through the tunnel. All other go through tunnel + return native() + } + + if f.TunnelServer.HasSession(cluster.Name) { + logrus.Tracef("dialerFactory: tunnel session found for cluster [%s]", cluster.Name) + cd := f.TunnelServer.Dialer(cluster.Name) + return func(ctx context.Context, network, address string) (net.Conn, error) { + if cluster.Status.Driver == v32.ClusterDriverRKE { + address = f.translateClusterAddress(cluster, hostPort, address) + } + logrus.Tracef("dialerFactory: returning network [%s] and address [%s] as clusterDialer", network, address) + return cd(ctx, network, address) + }, nil + } + logrus.Tracef("dialerFactory: no tunnel session found for cluster [%s], falling back to nodeDialer", cluster.Name) + + // Try to connect to a node for the cluster dialer + nodes, err := f.nodeLister.List(cluster.Name, labels.Everything()) + if err != nil { + return nil, err + } + + var localAPIEndpoint bool + if cluster.Status.Driver == v32.ClusterDriverRKE { + localAPIEndpoint = true + } + + for _, node := range nodes { + if node.DeletionTimestamp == nil && v32.NodeConditionProvisioned.IsTrue(node) && + (node.Spec.ControlPlane || v32.NodeConditionReady.IsTrue(node)) { + logrus.Tracef("dialerFactory: using node [%s]/[%s] for nodeDialer", + node.Labels["management.cattle.io/nodename"], node.Name) + if nodeDialer, err := f.nodeDialer(clusterName, node.Name); err == nil { + return func(ctx context.Context, network, address string) (net.Conn, error) { + if address == hostPort && localAPIEndpoint { + logrus.Trace("dialerFactory: rewriting address/port to 127.0.0.1:6443 as node may not" + + " have direct kube-api access") + // The node dialer may not have direct access to kube-api so we hit localhost:6443 instead + address = "127.0.0.1:6443" + } + logrus.Tracef("dialerFactory: Returning network [%s] and address [%s] as nodeDialer", network, address) + return nodeDialer(ctx, network, address) + }, nil + } + } + } + + if !retryOnError { + logrus.Debugf("No active connection for cluster [%s], returning", cluster.Name) + return nil, ErrAgentDisconnected + } + + logrus.Debugf("No active connection for cluster [%s], will wait for about 30 seconds", cluster.Name) + for i := 0; i < 4; i++ { + if f.TunnelServer.HasSession(cluster.Name) { + logrus.Debugf("Cluster [%s] has reconnected, resuming", cluster.Name) + cd := f.TunnelServer.Dialer(cluster.Name) + return func(ctx context.Context, network, address string) (net.Conn, error) { + if cluster.Status.Driver == v32.ClusterDriverRKE { + address = f.translateClusterAddress(cluster, hostPort, address) + } + logrus.Tracef("dialerFactory: returning network [%s] and address [%s] as clusterDialer", network, address) + return cd(ctx, network, address) + }, nil + } + time.Sleep(wait.Jitter(5*time.Second, 1)) + } + + return nil, ErrAgentDisconnected +} + +func hostPort(cluster *v3.Cluster) string { + u, err := url.Parse(cluster.Status.APIEndpoint) + if err != nil { + return "" + } + + if strings.Contains(u.Host, ":") { + return u.Host + } + return u.Host + ":443" +} + +func native() (dialer.Dialer, error) { + netDialer := net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + return netDialer.DialContext, nil +} + +func (f *Factory) DockerDialer(clusterName, machineName string) (dialer.Dialer, error) { + machine, err := f.nodeLister.Get(clusterName, machineName) + if err != nil { + return nil, err + } + + sessionKey := machineSessionKey(machine) + if f.TunnelServer.HasSession(sessionKey) { + network, address := "unix", "/var/run/docker.sock" + if machine.Status.InternalNodeStatus.NodeInfo.OperatingSystem == "windows" { + network, address = "npipe", "//./pipe/docker_engine" + } + d := f.TunnelServer.Dialer(sessionKey) + return func(ctx context.Context, _ string, _ string) (net.Conn, error) { + return d(ctx, network, address) + }, nil + } + + return nil, fmt.Errorf("can not build dialer to [%s:%s]", clusterName, machineName) +} + +func (f *Factory) NodeDialer(clusterName, machineName string) (dialer.Dialer, error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + d, err := f.nodeDialer(clusterName, machineName) + if err != nil { + return nil, err + } + return d(ctx, network, address) + }, nil +} + +func (f *Factory) nodeDialer(clusterName, machineName string) (dialer.Dialer, error) { + machine, err := f.nodeLister.Get(clusterName, machineName) + if err != nil { + return nil, err + } + + sessionKey := machineSessionKey(machine) + if f.TunnelServer.HasSession(sessionKey) { + d := f.TunnelServer.Dialer(sessionKey) + return dialer.Dialer(d), nil + } + + return nil, fmt.Errorf("can not build dialer to [%s:%s]", clusterName, machineName) +} + +func machineSessionKey(machine *v3.Node) string { + return fmt.Sprintf("%s:%s", machine.Namespace, machine.Name) +} + +func isProxyAddress(address string) bool { + proxy := getEnvAny("HTTP_PROXY", "http_proxy") + if proxy == "" { + proxy = getEnvAny("HTTPS_PROXY", "https_proxy") + } + + if proxy == "" { + return false + } + + parsed, err := parseProxy(proxy) + if err != nil { + logrus.Warnf("Failed to parse http_proxy url %s: %v", proxy, err) + return false + } + return parsed.Host == address +} + +func getEnvAny(names ...string) string { + for _, n := range names { + if val := os.Getenv(n); val != "" { + return val + } + } + return "" +} + +func parseProxy(proxy string) (*url.URL, error) { + if proxy == "" { + return nil, nil + } + + proxyURL, err := url.Parse(proxy) + if err != nil || + (proxyURL.Scheme != "http" && + proxyURL.Scheme != "https" && + proxyURL.Scheme != "socks5") { + // proxy was bogus. Try pre-pending "http://" to it and + // see if that parses correctly. If not, fall through + if proxyURL, err := url.Parse("http://" + proxy); err == nil { + return proxyURL, nil + } + } + if err != nil { + return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err) + } + return proxyURL, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/encryptedstore/secrets_store.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/encryptedstore/secrets_store.go new file mode 100644 index 0000000..6d84280 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/encryptedstore/secrets_store.go @@ -0,0 +1,155 @@ +package encryptedstore + +import ( + "reflect" + "time" + + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + defaultNamespace = "cattle-system" +) + +type GenericEncryptedStore struct { + prefix string + namespace string + secrets v1.SecretInterface + secretLister v1.SecretLister +} + +func NewGenericEncryptedStore(prefix, namespace string, namespaceInterface v1.NamespaceInterface, secretsGetter v1.SecretsGetter) (*GenericEncryptedStore, error) { + if namespace == "" { + namespace = defaultNamespace + } + + _, err := namespaceInterface.Get(namespace, metav1.GetOptions{}) + if errors.IsNotFound(err) { + ns := &corev1.Namespace{} + ns.Name = namespace + if _, err := namespaceInterface.Create(ns); err != nil { + return nil, err + } + } else if err != nil { + return nil, err + } + + return &GenericEncryptedStore{ + prefix: prefix, + namespace: namespace, + secrets: secretsGetter.Secrets(namespace), + secretLister: secretsGetter.Secrets(namespace).Controller().Lister(), + }, nil +} + +func (g *GenericEncryptedStore) Get(name string) (map[string]string, error) { + sec, err := g.secretLister.Get(g.namespace, g.getKey(name)) + if err != nil { + return nil, err + } + + result := map[string]string{} + for k, v := range sec.Data { + result[k] = string(v) + } + + return result, nil +} + +func (g *GenericEncryptedStore) getKey(name string) string { + return g.prefix + name +} + +func (g *GenericEncryptedStore) Set(name string, data map[string]string) error { + return g.set(name, data) +} + +func (g *GenericEncryptedStore) set(name string, data map[string]string) error { + logrus.Debugf("[GenericEncryptedStore]: set secret called for %v", g.getKey(name)) + sec, err := g.secretLister.Get(g.namespace, g.getKey(name)) + if errors.IsNotFound(err) { + logrus.Debugf("[GenericEncryptedStore]: Creating secret for %v", g.getKey(name)) + sec = &corev1.Secret{} + sec.Name = g.getKey(name) + sec.StringData = data + if _, err := g.secrets.Create(sec); err != nil { + if !errors.IsAlreadyExists(err) { + return err + } + logrus.Debugf("[GenericEncryptedStore]: secret %v already exists, updating secret", sec.Name) + // if secret already exists, update it with the current cluster status + return g.updateSecretWithBackoff(name, data) + } + return nil + } else if err != nil { + return err + } + + secToUpdate := prepareSecretForUpdate(sec, data) + if !reflect.DeepEqual(secToUpdate.Data, sec.Data) { + logrus.Debugf("[GenericEncryptedStore]: updating secret %v", g.getKey(name)) + _, err = g.secrets.Update(secToUpdate) + if err != nil { + if !errors.IsConflict(err) { + return err + } + return g.updateSecretWithBackoff(name, data) + } + } + return err +} + +func (g *GenericEncryptedStore) updateSecretWithBackoff(name string, data map[string]string) error { + backoff := wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 5, + } + return wait.ExponentialBackoff(backoff, func() (bool, error) { + // fetch secret from the db when retrying due to IsConflict/IsAlreadyExists error + secret, err := g.secrets.GetNamespaced(g.namespace, g.getKey(name), metav1.GetOptions{}) + if err != nil { + logrus.Errorf("[GenericEncryptedStore]: error getting secret %v from db: %v", g.getKey(name), err) + return false, err + } + secToUpdate := prepareSecretForUpdate(secret, data) + if !reflect.DeepEqual(secToUpdate.Data, secret.Data) { + _, err = g.secrets.Update(secToUpdate) + if err != nil { + if errors.IsConflict(err) { + logrus.Errorf("[GenericEncryptedStore]: conflict error updating secret %v: %v, retrying update", g.getKey(name), err) + return false, nil + } + logrus.Errorf("[GenericEncryptedStore]: error when updating secret %v: %v", g.getKey(name), err) + return false, err + } + logrus.Debugf("[GenericEncryptedStore]: successfully updated secret %v ", g.getKey(name)) + } + return true, nil + }) +} + +func prepareSecretForUpdate(secret *corev1.Secret, data map[string]string) *corev1.Secret { + secToUpdate := secret.DeepCopy() + if secToUpdate.Data == nil { + secToUpdate.Data = map[string][]byte{} + } + for k, v := range data { + secToUpdate.Data[k] = []byte(v) + } + return secToUpdate +} + +func (g *GenericEncryptedStore) Remove(name string) error { + err := g.secrets.Delete(g.getKey(name), nil) + if errors.IsNotFound(err) { + return nil + } + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature.go new file mode 100644 index 0000000..168a70b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature.go @@ -0,0 +1,354 @@ +package features + +import ( + "fmt" + "strconv" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + features = make(map[string]*Feature) + + // Features, ex.: ClusterRandomName = newFeature("cluster-randomizer", "Randomizes clusters.", false, false) + + UnsupportedStorageDrivers = newFeature( + "unsupported-storage-drivers", + "Allows the use of types for storage providers and provisioners that are not enabled by default.", + false, + true, + true) + IstioVirtualServiceUI = newFeature( + "istio-virtual-service-ui", + "Exposes a UI that enables users to create, read, update and delete virtual services and destination rules, which are traffic management features of Istio.", + true, + true, + true) + MCM = newFeature( + "multi-cluster-management", + "Multi-cluster provisioning and management of Kubernetes clusters.", + true, + false, + true) + MCMAgent = newFeature( + "multi-cluster-management-agent", + "Run downstream controllers for multi-cluster management.", + false, + false, + false) + Fleet = newFeature( + "fleet", + "Install Fleet when starting Rancher", + true, + false, + true) + Gitops = newFeature( + "continuous-delivery", + "Gitops components in fleet", + true, + false, + true) + Auth = newFeature( + "auth", + "Enable authentication", + true, + false, + false) + EmbeddedClusterAPI = newFeature( + "embedded-cluster-api", + "Enable a Rancher-managed instance of cluster-api core controller", + true, + false, + false) + RKE2 = newFeature( + "rke2", + "Enable provisioning of RKE2", + true, + false, + true) + Legacy = newFeature( + "legacy", + "Enable legacy features", + false, + true, + true) + ProvisioningV2 = newFeature( + "provisioningv2", + "Enable cluster-api based provisioning framework", + true, + false, + false) + TokenHashing = newFeature( + "token-hashing", + "Enable one way hashing of tokens. Once enabled token hashing can not be disabled", + false, + true, + true) + Harvester = newFeature( + "harvester", + "Enable Harvester integration, with ability to import and manage Harvester clusters", + true, + true, + true) + RKE1CustomNodeCleanup = newFeature( + "rke1-custom-node-cleanup", + "Enable cleanup RKE1 custom cluster nodes when they are deleted", + true, + true, + true) + HarvesterBaremetalContainerWorkload = newFeature( + "harvester-baremetal-container-workload", + "[Experimental]: Deploy container workloads to underlying harvester cluster", + false, + true, + true) + ProvisioningV2FleetWorkspaceBackPopulation = newFeature( + "provisioningv2-fleet-workspace-back-population", + "[Experimental]: Allow Fleet workspace name to be changed on clusters administrated by provisioning v2", + false, + false, + true) + UIExtension = newFeature( + "uiextension", + "Enable UI Extensions when starting Rancher", + true, + false, + true, + ) + UISQLCache = newFeature( + "ui-sql-cache", + "[Experimental]: Enable SQLite-backed caching to improve performance and provide additional UI sorting/filtering features.", + false, + false, + true) + RKE1UI = newFeature( + "rke1-ui", + "Enable RKE1 provisioning in the Rancher UI", + true, + true, + true) +) + +type Feature struct { + name string + description string + // val is the effective value- it is equal to default until explicitly changed. + // The order of precedence is lockedValue > value > default + val bool + // default value of feature + def bool + // if a feature is not dynamic, then rancher must be restarted when the value is changed + dynamic bool + // Whether we should install this feature or assume something else will install and manage the Feature CR + install bool +} + +// InitializeFeatures updates feature default if given valid --features flag and creates/updates necessary features in k8s +func InitializeFeatures(featuresClient managementv3.FeatureClient, featureArgs string) { + // applies any default values assigned in --features flag to feature map + if err := applyArgumentDefaults(featureArgs); err != nil { + logrus.Errorf("failed to apply feature args: %v", err) + } + + if featuresClient == nil { + return + } + + // external-rules feature flag was removed in 2.9. We need to delete it for users upgrading from 2.8. + err := featuresClient.Delete("external-rules", &metav1.DeleteOptions{}) + if err != nil && !errors.IsNotFound(err) { + logrus.Errorf("unable to delete external-rules feature: %v", err) + } + + // creates any features in map that do not exist, updates features with new default value + for key, f := range features { + featureState, err := featuresClient.Get(key, metav1.GetOptions{}) + if err != nil { + if !errors.IsNotFound(err) { + logrus.Errorf("unable to retrieve feature %s in initialize features: %v", f.name, err) + } + + if f.install { + // value starts off as nil, that way rancher can determine if value has been manually assigned + newFeature := &v3.Feature{ + ObjectMeta: metav1.ObjectMeta{ + Name: f.name, + }, + Spec: v3.FeatureSpec{ + Value: nil, + }, + Status: v3.FeatureStatus{ + Default: f.def, + Dynamic: f.dynamic, + Description: f.description, + }, + } + + if _, err := featuresClient.Create(newFeature); err != nil { + logrus.Errorf("unable to create feature %s in initialize features: %v", f.name, err) + } + } + } else { + newFeatureState := featureState.DeepCopy() + // checks if default value has changed + if featureState.Status.Default != f.def { + newFeatureState.Status.Default = f.def + } + + // checks if developer has changed dynamic value from previous rancher version + if featureState.Status.Dynamic != f.dynamic { + newFeatureState.Status.Dynamic = f.dynamic + } + + // checks if developer has changed description value from previous rancher version + if featureState.Status.Description != f.description { + newFeatureState.Status.Description = f.description + } + + newFeatureState, err = featuresClient.Update(newFeatureState) + if err != nil { + logrus.Errorf("unable to update feature %s in initialize features: %v", f.name, err) + continue + } + + if newFeatureState.Status.LockedValue != nil { + f.Set(*newFeatureState.Status.LockedValue) + continue + } + + if featureState.Spec.Value == nil { + continue + } + + if *featureState.Spec.Value == f.val { + continue + } + + f.Set(*featureState.Spec.Value) + } + } +} + +func SetFeature(featuresClient managementv3.FeatureClient, featureName string, value bool) error { + if featuresClient == nil { + return nil + } + + featureState, err := featuresClient.Get(featureName, metav1.GetOptions{}) + if err != nil { + return err + } + + featureState.Spec.Value = &[]bool{value}[0] + if _, err = featuresClient.Update(featureState); err != nil { + return err + } + + return nil +} + +// applyArgumentDefaults reads the features arguments and uses their values to overwrite +// the corresponding feature default value +func applyArgumentDefaults(featureArgs string) error { + if featureArgs == "" { + return nil + } + + formattingError := fmt.Errorf("feature argument [%s] should be of the form \"features=feature1=bool,feature2=bool\"", featureArgs) + args := strings.Split(featureArgs, ",") + + applyFeatureDefaults := make(map[string]bool) + + for _, feature := range args { + featureSet := strings.Split(feature, "=") + if len(featureSet) != 2 { + return formattingError + } + + key := featureSet[0] + if features[key] == nil { + return fmt.Errorf("\"%s\" is not a valid feature", key) + } + + value, err := strconv.ParseBool(featureSet[1]) + if err != nil { + return formattingError + } + + applyFeatureDefaults[key] = value + } + + // only want to apply defaults once all args have been parsed and validated + for k, v := range applyFeatureDefaults { + features[k].def = v + features[k].val = v + } + + return nil +} + +// Enabled returns whether the feature is enabled +func (f *Feature) Enabled() bool { + return f.val +} + +// Disable will disable a feature such that regardless of the user's choice it will always be false +func (f *Feature) Disable() { + f.val = false + f.def = false + delete(features, f.name) +} + +// Dynamic returns whether the feature is dynamic. Rancher must be restarted when +// a non-dynamic feature's effective value is changed. +func (f *Feature) Dynamic() bool { + return f.dynamic +} + +func (f *Feature) Set(val bool) { + f.val = val +} + +func (f *Feature) Name() string { + return f.name +} + +func GetFeatureByName(name string) *Feature { + return features[name] +} + +func IsEnabled(feature *v3.Feature) bool { + if feature == nil { + return false + } + if feature.Status.LockedValue != nil { + return *feature.Status.LockedValue + } + if feature.Spec.Value == nil { + return feature.Status.Default + } + return *feature.Spec.Value +} + +// newFeature adds feature to the global feature map +func newFeature(name, description string, def, dynamic, install bool) *Feature { + feature := &Feature{ + name: name, + description: description, + def: def, + val: def, + dynamic: dynamic, + install: install, + } + + // feature will be stored in feature map, features contained in feature + // map will then be initialized + features[name] = feature + + return feature +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature_test.go new file mode 100644 index 0000000..6afefeb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/feature_test.go @@ -0,0 +1,70 @@ +package features + +import ( + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var isDefFalse = newFeature("isfalse", "", false, false, true) + +// TestApplyArgumentDefaults ensure that applyArgumentsDefault accepts argument +// of the form "features=feature1=bool,feature2=bool" and nothing else +func TestApplyArgumentDefaults(t *testing.T) { + assert := assert.New(t) + + // each string contained below is expected to cause an error when passed + // to applyArgumentDefaults + invalidArguments := []string{ + "asdf", // argument must be of the form feature1=bool + "invalidfeature=true", // left hand of assignment must be existing feature + "invalidfeature=notabool", // right-hand of assignment but be bool parsable + "=asdf", + "=", + "invalid=invalid,=", + ",feature=true", + "invalidfeature=true,invalidfeature2=false", + "feature = false", + } + + for _, arg := range invalidArguments { + err := applyArgumentDefaults(arg) + assert.NotNil(err) + } +} + +func TestInitializeNil(t *testing.T) { + assert := assert.New(t) + assert.False(isDefFalse.Enabled()) + InitializeFeatures(nil, "isfalse=true") + assert.True(isDefFalse.Enabled()) +} + +func TestInitializeFeatures(t *testing.T) { + tests := map[string]struct { + featureMock func() managementv3.FeatureClient + features map[string]*Feature + }{ + "delete external-rules feature is called": { + featureMock: func() managementv3.FeatureClient { + mock := fake.NewMockNonNamespacedControllerInterface[*v3.Feature, *v3.FeatureList](gomock.NewController(t)) + mock.EXPECT().Delete("external-rules", &metav1.DeleteOptions{}) + + return mock + }, + features: nil, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + features = test.features // we can't run parallel tests if we modify this package var here. Code should be refactored to not use a package var if more tests cases are added. + InitializeFeatures(test.featureMock(), "") + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/migrate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/migrate.go new file mode 100644 index 0000000..e820917 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/features/migrate.go @@ -0,0 +1,93 @@ +package features + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/imported" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + t = true +) + +func MigrateFeatures(featuresClient managementv3.FeatureClient, crdClient v1.CustomResourceDefinitionClient, mgmtClusterClient managementv3.ClusterClient) error { + features, err := featuresClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + if len(features.Items) == 0 { + return nil + } + + hasLegacy := false + for _, feature := range features.Items { + switch feature.Name { + case Legacy.Name(): + hasLegacy = true + case MCM.Name(): + if err := enableMCMIfPreviouslyEnabled(&feature, featuresClient, crdClient); err != nil { + return err + } + case RKE2.Name(): + if err := enableRKE2IfClustersExist(&feature, featuresClient, mgmtClusterClient); err != nil { + return err + } + } + } + + if !hasLegacy { + _, err = featuresClient.Create(&v3.Feature{ + ObjectMeta: metav1.ObjectMeta{ + Name: Legacy.Name(), + }, + Spec: v3.FeatureSpec{ + Value: &t, + }, + }) + return err + } + + return nil +} + +func enableMCMIfPreviouslyEnabled(feature *v3.Feature, featuresClient managementv3.FeatureClient, crdClient v1.CustomResourceDefinitionClient) error { + if feature.Spec.Value == nil || *feature.Spec.Value { + return nil + } + + _, err := crdClient.Get("nodes.management.cattle.io", metav1.GetOptions{}) + if apierrors.IsNotFound(err) { + return nil + } else if err != nil { + return err + } + + return SetFeature(featuresClient, MCM.Name(), true) +} + +func enableRKE2IfClustersExist(feature *v3.Feature, featuresClient managementv3.FeatureClient, mgmtClusterClient managementv3.ClusterClient) error { + if feature.Spec.Value == nil || *feature.Spec.Value { + return nil + } + + clusters, err := mgmtClusterClient.List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, c := range clusters.Items { + if imported.IsAdministratedByProvisioningCluster(&c) { + feature = feature.DeepCopy() + feature.Spec.Value = &[]bool{true}[0] + feature.Status.LockedValue = feature.Spec.Value + + _, err = featuresClient.Update(feature) + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/const.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/const.go new file mode 100644 index 0000000..c171111 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/const.go @@ -0,0 +1,14 @@ +package fleet + +const ( + ReleaseNamespace = "cattle-fleet-system" + ReleaseLocalNamespace = "cattle-fleet-local-system" + ReleaseClustersNamespace = "cattle-fleet-clusters-system" + ReleaseLegacyNamespace = "fleet-system" + + ChartName = "fleet" + CRDChartName = "fleet-crd" + + ClustersDefaultNamespace = "fleet-default" + ClustersLocalNamespace = "fleet-local" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet.go new file mode 100644 index 0000000..f80cc8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet.go @@ -0,0 +1,66 @@ +package fleet + +import ( + "errors" + "fmt" + "os" + + "github.com/sirupsen/logrus" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/clientcmd/api" +) + +// GetClusterHost returns the API server host and CA for the specified client configuration. +func GetClusterHost(clientCfg clientcmd.ClientConfig) (string, []byte, error) { + icc, err := rest.InClusterConfig() + if err == nil { + ca, err := os.ReadFile(icc.CAFile) + return icc.Host, ca, err + } + + fail := func(err error) (string, []byte, error) { + return "", []byte{}, fmt.Errorf("fleet.GetClusterHost: unable to determine cluster host: %w", err) + } + + if clientCfg == nil { + return fail(errors.New("client config not set")) + } + + rawConfig, err := clientCfg.RawConfig() + if err != nil { + return fail(fmt.Errorf("no configuration available: %w", err)) + } + + cluster, ok := rawConfig.Clusters[rawConfig.CurrentContext] + if ok { + ca, err := getCA(cluster) + return cluster.Server, ca, err + } + + logrus.Warnf( + "API server host retrieval: no cluster found for the current context (%s)", + rawConfig.CurrentContext, + ) + + for k, v := range rawConfig.Clusters { + logrus.Warnf( + "API server host retrieval: picking server %s "+ + "with reference %s randomly from set of configured clusters", + v.Server, + k, + ) + ca, err := getCA(v) + return v.Server, ca, err + } + + return "", []byte{}, errors.New("failed to find cluster server parameter") +} + +// getCA retrieves certificate authority information for the specified cluster. +func getCA(cluster *api.Cluster) ([]byte, error) { + if len(cluster.CertificateAuthorityData) > 0 { + return cluster.CertificateAuthorityData, nil + } + return os.ReadFile(cluster.CertificateAuthority) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet_test.go new file mode 100644 index 0000000..7dc4188 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/fleet/fleet_test.go @@ -0,0 +1,112 @@ +package fleet_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + + "github.com/rancher/rancher/pkg/fleet" +) + +func TestGetClusterHost(t *testing.T) { + testCases := []struct { + name string + config clientcmdapi.Config + CAPath string + expectedHost []string // The (single) returned host must be an element of this slice. + expectedCA []byte + expectErr bool + }{ + // the in-cluster config case is not tested, as it would require a container with environment variables, + // token and cert files. + { + name: "returns host of raw config cluster with current context", + config: clientcmdapi.Config{ + CurrentContext: "foo", + Clusters: map[string]*clientcmdapi.Cluster{ + "foo": { + Server: "bar", + CertificateAuthorityData: []byte("baz"), + }, + }, + }, + expectedHost: []string{"bar"}, + expectedCA: []byte("baz"), + expectErr: false, + }, + { + name: "returns host of raw config cluster with current context with only cert path configured", + config: clientcmdapi.Config{ + CurrentContext: "foo", + Clusters: map[string]*clientcmdapi.Cluster{ + "foo": { + Server: "bar", + CertificateAuthority: "/tmp/baz.pem", + }, + }, + }, + CAPath: "/tmp/baz.pem", + expectedHost: []string{"bar"}, + expectedCA: []byte("baz"), + expectErr: false, + }, + { + name: "returns host of first found configured cluster when none found with current context", + config: clientcmdapi.Config{ + CurrentContext: "not-found", + Clusters: map[string]*clientcmdapi.Cluster{ + "first": { + Server: "first-server", + CertificateAuthorityData: []byte("baz"), + }, + "second": { + Server: "second-server", + CertificateAuthorityData: []byte("baz"), + }, + }, + }, + expectedHost: []string{"first-server", "second-server"}, + expectedCA: []byte("baz"), + expectErr: false, + }, + { + name: "returns error when no cluster found", + config: clientcmdapi.Config{ + CurrentContext: "not-found", + Clusters: map[string]*clientcmdapi.Cluster{}, + }, + expectedHost: []string{""}, + expectedCA: []byte(""), + expectErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.CAPath != "" { + CAFile, err := os.Create(tc.CAPath) + require.NoError(t, err) + + _, err = CAFile.Write(tc.expectedCA) + require.NoError(t, err) + + defer os.Remove(tc.CAPath) + } + + clientConfig := clientcmd.NewDefaultClientConfig(tc.config, nil) + host, ca, err := fleet.GetClusterHost(clientConfig) + + if tc.expectErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + assert.Contains(t, tc.expectedHost, host) + assert.Equal(t, tc.expectedCA, ca) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/clientset.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/clientset.go new file mode 100644 index 0000000..7a46f14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/clientset.go @@ -0,0 +1,159 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package versioned + +import ( + "fmt" + "net/http" + + catalogv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1" + provisioningv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1" + upgradev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + CatalogV1() catalogv1.CatalogV1Interface + ProvisioningV1() provisioningv1.ProvisioningV1Interface + RkeV1() rkev1.RkeV1Interface + UpgradeV1() upgradev1.UpgradeV1Interface +} + +// Clientset contains the clients for groups. +type Clientset struct { + *discovery.DiscoveryClient + catalogV1 *catalogv1.CatalogV1Client + provisioningV1 *provisioningv1.ProvisioningV1Client + rkeV1 *rkev1.RkeV1Client + upgradeV1 *upgradev1.UpgradeV1Client +} + +// CatalogV1 retrieves the CatalogV1Client +func (c *Clientset) CatalogV1() catalogv1.CatalogV1Interface { + return c.catalogV1 +} + +// ProvisioningV1 retrieves the ProvisioningV1Client +func (c *Clientset) ProvisioningV1() provisioningv1.ProvisioningV1Interface { + return c.provisioningV1 +} + +// RkeV1 retrieves the RkeV1Client +func (c *Clientset) RkeV1() rkev1.RkeV1Interface { + return c.rkeV1 +} + +// UpgradeV1 retrieves the UpgradeV1Client +func (c *Clientset) UpgradeV1() upgradev1.UpgradeV1Interface { + return c.upgradeV1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + + if configShallowCopy.UserAgent == "" { + configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() + } + + // share the transport between all clients + httpClient, err := rest.HTTPClientFor(&configShallowCopy) + if err != nil { + return nil, err + } + + return NewForConfigAndClient(&configShallowCopy, httpClient) +} + +// NewForConfigAndClient creates a new Clientset for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. +func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + + var cs Clientset + var err error + cs.catalogV1, err = catalogv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + cs.provisioningV1, err = provisioningv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + cs.rkeV1, err = rkev1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + cs.upgradeV1, err = upgradev1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + cs, err := NewForConfig(c) + if err != nil { + panic(err) + } + return cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.catalogV1 = catalogv1.New(c) + cs.provisioningV1 = provisioningv1.New(c) + cs.rkeV1 = rkev1.New(c) + cs.upgradeV1 = upgradev1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/clientset_generated.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/clientset_generated.go new file mode 100644 index 0000000..d25dd93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -0,0 +1,106 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + clientset "github.com/rancher/rancher/pkg/generated/clientset/versioned" + catalogv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1" + fakecatalogv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake" + provisioningv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1" + fakeprovisioningv1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake" + rkev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1" + fakerkev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake" + upgradev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1" + fakeupgradev1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{tracker: o} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery + tracker testing.ObjectTracker +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +func (c *Clientset) Tracker() testing.ObjectTracker { + return c.tracker +} + +var ( + _ clientset.Interface = &Clientset{} + _ testing.FakeClient = &Clientset{} +) + +// CatalogV1 retrieves the CatalogV1Client +func (c *Clientset) CatalogV1() catalogv1.CatalogV1Interface { + return &fakecatalogv1.FakeCatalogV1{Fake: &c.Fake} +} + +// ProvisioningV1 retrieves the ProvisioningV1Client +func (c *Clientset) ProvisioningV1() provisioningv1.ProvisioningV1Interface { + return &fakeprovisioningv1.FakeProvisioningV1{Fake: &c.Fake} +} + +// RkeV1 retrieves the RkeV1Client +func (c *Clientset) RkeV1() rkev1.RkeV1Interface { + return &fakerkev1.FakeRkeV1{Fake: &c.Fake} +} + +// UpgradeV1 retrieves the UpgradeV1Client +func (c *Clientset) UpgradeV1() upgradev1.UpgradeV1Interface { + return &fakeupgradev1.FakeUpgradeV1{Fake: &c.Fake} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/doc.go new file mode 100644 index 0000000..b4a36f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/register.go new file mode 100644 index 0000000..ac21d5e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/fake/register.go @@ -0,0 +1,62 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + upgradev1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) + +var localSchemeBuilder = runtime.SchemeBuilder{ + catalogv1.AddToScheme, + provisioningv1.AddToScheme, + rkev1.AddToScheme, + upgradev1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/doc.go new file mode 100644 index 0000000..7f882b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/register.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/register.go new file mode 100644 index 0000000..d28893f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/scheme/register.go @@ -0,0 +1,62 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package scheme + +import ( + catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + upgradev1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + catalogv1.AddToScheme, + provisioningv1.AddToScheme, + rkev1.AddToScheme, + upgradev1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/app.go new file mode 100644 index 0000000..3d16db0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/app.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// AppsGetter has a method to return a AppInterface. +// A group's client should implement this interface. +type AppsGetter interface { + Apps(namespace string) AppInterface +} + +// AppInterface has methods to work with App resources. +type AppInterface interface { + Create(ctx context.Context, app *v1.App, opts metav1.CreateOptions) (*v1.App, error) + Update(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (*v1.App, error) + UpdateStatus(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (*v1.App, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.App, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.AppList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.App, err error) + AppExpansion +} + +// apps implements AppInterface +type apps struct { + client rest.Interface + ns string +} + +// newApps returns a Apps +func newApps(c *CatalogV1Client, namespace string) *apps { + return &apps{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the app, and returns the corresponding app object, and an error if there is any. +func (c *apps) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.App, err error) { + result = &v1.App{} + err = c.client.Get(). + Namespace(c.ns). + Resource("apps"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Apps that match those selectors. +func (c *apps) List(ctx context.Context, opts metav1.ListOptions) (result *v1.AppList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.AppList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("apps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested apps. +func (c *apps) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("apps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a app and creates it. Returns the server's representation of the app, and an error, if there is any. +func (c *apps) Create(ctx context.Context, app *v1.App, opts metav1.CreateOptions) (result *v1.App, err error) { + result = &v1.App{} + err = c.client.Post(). + Namespace(c.ns). + Resource("apps"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(app). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a app and updates it. Returns the server's representation of the app, and an error, if there is any. +func (c *apps) Update(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (result *v1.App, err error) { + result = &v1.App{} + err = c.client.Put(). + Namespace(c.ns). + Resource("apps"). + Name(app.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(app). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *apps) UpdateStatus(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (result *v1.App, err error) { + result = &v1.App{} + err = c.client.Put(). + Namespace(c.ns). + Resource("apps"). + Name(app.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(app). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the app and deletes it. Returns an error if one occurs. +func (c *apps) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("apps"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *apps) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("apps"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched app. +func (c *apps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.App, err error) { + result = &v1.App{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("apps"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/catalog.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/catalog.cattle.io_client.go new file mode 100644 index 0000000..70a12e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/catalog.cattle.io_client.go @@ -0,0 +1,122 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type CatalogV1Interface interface { + RESTClient() rest.Interface + AppsGetter + ClusterReposGetter + OperationsGetter + UIPluginsGetter +} + +// CatalogV1Client is used to interact with features provided by the catalog.cattle.io group. +type CatalogV1Client struct { + restClient rest.Interface +} + +func (c *CatalogV1Client) Apps(namespace string) AppInterface { + return newApps(c, namespace) +} + +func (c *CatalogV1Client) ClusterRepos() ClusterRepoInterface { + return newClusterRepos(c) +} + +func (c *CatalogV1Client) Operations(namespace string) OperationInterface { + return newOperations(c, namespace) +} + +func (c *CatalogV1Client) UIPlugins(namespace string) UIPluginInterface { + return newUIPlugins(c, namespace) +} + +// NewForConfig creates a new CatalogV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*CatalogV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new CatalogV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CatalogV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &CatalogV1Client{client}, nil +} + +// NewForConfigOrDie creates a new CatalogV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CatalogV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CatalogV1Client for the given RESTClient. +func New(c rest.Interface) *CatalogV1Client { + return &CatalogV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CatalogV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/clusterrepo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/clusterrepo.go new file mode 100644 index 0000000..853dc9c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/clusterrepo.go @@ -0,0 +1,184 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterReposGetter has a method to return a ClusterRepoInterface. +// A group's client should implement this interface. +type ClusterReposGetter interface { + ClusterRepos() ClusterRepoInterface +} + +// ClusterRepoInterface has methods to work with ClusterRepo resources. +type ClusterRepoInterface interface { + Create(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.CreateOptions) (*v1.ClusterRepo, error) + Update(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (*v1.ClusterRepo, error) + UpdateStatus(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (*v1.ClusterRepo, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ClusterRepo, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ClusterRepoList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterRepo, err error) + ClusterRepoExpansion +} + +// clusterRepos implements ClusterRepoInterface +type clusterRepos struct { + client rest.Interface +} + +// newClusterRepos returns a ClusterRepos +func newClusterRepos(c *CatalogV1Client) *clusterRepos { + return &clusterRepos{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterRepo, and returns the corresponding clusterRepo object, and an error if there is any. +func (c *clusterRepos) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterRepo, err error) { + result = &v1.ClusterRepo{} + err = c.client.Get(). + Resource("clusterrepos"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterRepos that match those selectors. +func (c *clusterRepos) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterRepoList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ClusterRepoList{} + err = c.client.Get(). + Resource("clusterrepos"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterRepos. +func (c *clusterRepos) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clusterrepos"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterRepo and creates it. Returns the server's representation of the clusterRepo, and an error, if there is any. +func (c *clusterRepos) Create(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.CreateOptions) (result *v1.ClusterRepo, err error) { + result = &v1.ClusterRepo{} + err = c.client.Post(). + Resource("clusterrepos"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterRepo). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterRepo and updates it. Returns the server's representation of the clusterRepo, and an error, if there is any. +func (c *clusterRepos) Update(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (result *v1.ClusterRepo, err error) { + result = &v1.ClusterRepo{} + err = c.client.Put(). + Resource("clusterrepos"). + Name(clusterRepo.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterRepo). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusterRepos) UpdateStatus(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (result *v1.ClusterRepo, err error) { + result = &v1.ClusterRepo{} + err = c.client.Put(). + Resource("clusterrepos"). + Name(clusterRepo.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterRepo). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterRepo and deletes it. Returns an error if one occurs. +func (c *clusterRepos) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Resource("clusterrepos"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterRepos) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clusterrepos"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterRepo. +func (c *clusterRepos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterRepo, err error) { + result = &v1.ClusterRepo{} + err = c.client.Patch(pt). + Resource("clusterrepos"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/doc.go new file mode 100644 index 0000000..dd95e75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/doc.go new file mode 100644 index 0000000..de41d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_app.go new file mode 100644 index 0000000..21cb07c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_app.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeApps implements AppInterface +type FakeApps struct { + Fake *FakeCatalogV1 + ns string +} + +var appsResource = v1.SchemeGroupVersion.WithResource("apps") + +var appsKind = v1.SchemeGroupVersion.WithKind("App") + +// Get takes name of the app, and returns the corresponding app object, and an error if there is any. +func (c *FakeApps) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.App, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(appsResource, c.ns, name), &v1.App{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.App), err +} + +// List takes label and field selectors, and returns the list of Apps that match those selectors. +func (c *FakeApps) List(ctx context.Context, opts metav1.ListOptions) (result *v1.AppList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(appsResource, appsKind, c.ns, opts), &v1.AppList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.AppList{ListMeta: obj.(*v1.AppList).ListMeta} + for _, item := range obj.(*v1.AppList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested apps. +func (c *FakeApps) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(appsResource, c.ns, opts)) + +} + +// Create takes the representation of a app and creates it. Returns the server's representation of the app, and an error, if there is any. +func (c *FakeApps) Create(ctx context.Context, app *v1.App, opts metav1.CreateOptions) (result *v1.App, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(appsResource, c.ns, app), &v1.App{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.App), err +} + +// Update takes the representation of a app and updates it. Returns the server's representation of the app, and an error, if there is any. +func (c *FakeApps) Update(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (result *v1.App, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(appsResource, c.ns, app), &v1.App{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.App), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeApps) UpdateStatus(ctx context.Context, app *v1.App, opts metav1.UpdateOptions) (*v1.App, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(appsResource, "status", c.ns, app), &v1.App{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.App), err +} + +// Delete takes name of the app and deletes it. Returns an error if one occurs. +func (c *FakeApps) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(appsResource, c.ns, name, opts), &v1.App{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeApps) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(appsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.AppList{}) + return err +} + +// Patch applies the patch and returns the patched app. +func (c *FakeApps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.App, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(appsResource, c.ns, name, pt, data, subresources...), &v1.App{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.App), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_catalog.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_catalog.cattle.io_client.go new file mode 100644 index 0000000..ee96e46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_catalog.cattle.io_client.go @@ -0,0 +1,52 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeCatalogV1 struct { + *testing.Fake +} + +func (c *FakeCatalogV1) Apps(namespace string) v1.AppInterface { + return &FakeApps{c, namespace} +} + +func (c *FakeCatalogV1) ClusterRepos() v1.ClusterRepoInterface { + return &FakeClusterRepos{c} +} + +func (c *FakeCatalogV1) Operations(namespace string) v1.OperationInterface { + return &FakeOperations{c, namespace} +} + +func (c *FakeCatalogV1) UIPlugins(namespace string) v1.UIPluginInterface { + return &FakeUIPlugins{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeCatalogV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_clusterrepo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_clusterrepo.go new file mode 100644 index 0000000..4cbbf94 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_clusterrepo.go @@ -0,0 +1,132 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusterRepos implements ClusterRepoInterface +type FakeClusterRepos struct { + Fake *FakeCatalogV1 +} + +var clusterreposResource = v1.SchemeGroupVersion.WithResource("clusterrepos") + +var clusterreposKind = v1.SchemeGroupVersion.WithKind("ClusterRepo") + +// Get takes name of the clusterRepo, and returns the corresponding clusterRepo object, and an error if there is any. +func (c *FakeClusterRepos) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ClusterRepo, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clusterreposResource, name), &v1.ClusterRepo{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterRepo), err +} + +// List takes label and field selectors, and returns the list of ClusterRepos that match those selectors. +func (c *FakeClusterRepos) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterRepoList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clusterreposResource, clusterreposKind, opts), &v1.ClusterRepoList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ClusterRepoList{ListMeta: obj.(*v1.ClusterRepoList).ListMeta} + for _, item := range obj.(*v1.ClusterRepoList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterRepos. +func (c *FakeClusterRepos) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clusterreposResource, opts)) +} + +// Create takes the representation of a clusterRepo and creates it. Returns the server's representation of the clusterRepo, and an error, if there is any. +func (c *FakeClusterRepos) Create(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.CreateOptions) (result *v1.ClusterRepo, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clusterreposResource, clusterRepo), &v1.ClusterRepo{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterRepo), err +} + +// Update takes the representation of a clusterRepo and updates it. Returns the server's representation of the clusterRepo, and an error, if there is any. +func (c *FakeClusterRepos) Update(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (result *v1.ClusterRepo, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clusterreposResource, clusterRepo), &v1.ClusterRepo{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterRepo), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusterRepos) UpdateStatus(ctx context.Context, clusterRepo *v1.ClusterRepo, opts metav1.UpdateOptions) (*v1.ClusterRepo, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(clusterreposResource, "status", clusterRepo), &v1.ClusterRepo{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterRepo), err +} + +// Delete takes name of the clusterRepo and deletes it. Returns an error if one occurs. +func (c *FakeClusterRepos) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(clusterreposResource, name, opts), &v1.ClusterRepo{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterRepos) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clusterreposResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ClusterRepoList{}) + return err +} + +// Patch applies the patch and returns the patched clusterRepo. +func (c *FakeClusterRepos) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ClusterRepo, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clusterreposResource, name, pt, data, subresources...), &v1.ClusterRepo{}) + if obj == nil { + return nil, err + } + return obj.(*v1.ClusterRepo), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_operation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_operation.go new file mode 100644 index 0000000..5fd4060 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_operation.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeOperations implements OperationInterface +type FakeOperations struct { + Fake *FakeCatalogV1 + ns string +} + +var operationsResource = v1.SchemeGroupVersion.WithResource("operations") + +var operationsKind = v1.SchemeGroupVersion.WithKind("Operation") + +// Get takes name of the operation, and returns the corresponding operation object, and an error if there is any. +func (c *FakeOperations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Operation, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(operationsResource, c.ns, name), &v1.Operation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Operation), err +} + +// List takes label and field selectors, and returns the list of Operations that match those selectors. +func (c *FakeOperations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.OperationList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(operationsResource, operationsKind, c.ns, opts), &v1.OperationList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.OperationList{ListMeta: obj.(*v1.OperationList).ListMeta} + for _, item := range obj.(*v1.OperationList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested operations. +func (c *FakeOperations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(operationsResource, c.ns, opts)) + +} + +// Create takes the representation of a operation and creates it. Returns the server's representation of the operation, and an error, if there is any. +func (c *FakeOperations) Create(ctx context.Context, operation *v1.Operation, opts metav1.CreateOptions) (result *v1.Operation, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(operationsResource, c.ns, operation), &v1.Operation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Operation), err +} + +// Update takes the representation of a operation and updates it. Returns the server's representation of the operation, and an error, if there is any. +func (c *FakeOperations) Update(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (result *v1.Operation, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(operationsResource, c.ns, operation), &v1.Operation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Operation), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeOperations) UpdateStatus(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (*v1.Operation, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(operationsResource, "status", c.ns, operation), &v1.Operation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Operation), err +} + +// Delete takes name of the operation and deletes it. Returns an error if one occurs. +func (c *FakeOperations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(operationsResource, c.ns, name, opts), &v1.Operation{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeOperations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(operationsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.OperationList{}) + return err +} + +// Patch applies the patch and returns the patched operation. +func (c *FakeOperations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Operation, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(operationsResource, c.ns, name, pt, data, subresources...), &v1.Operation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Operation), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_uiplugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_uiplugin.go new file mode 100644 index 0000000..0f8da8e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/fake/fake_uiplugin.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeUIPlugins implements UIPluginInterface +type FakeUIPlugins struct { + Fake *FakeCatalogV1 + ns string +} + +var uipluginsResource = v1.SchemeGroupVersion.WithResource("uiplugins") + +var uipluginsKind = v1.SchemeGroupVersion.WithKind("UIPlugin") + +// Get takes name of the uIPlugin, and returns the corresponding uIPlugin object, and an error if there is any. +func (c *FakeUIPlugins) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.UIPlugin, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(uipluginsResource, c.ns, name), &v1.UIPlugin{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.UIPlugin), err +} + +// List takes label and field selectors, and returns the list of UIPlugins that match those selectors. +func (c *FakeUIPlugins) List(ctx context.Context, opts metav1.ListOptions) (result *v1.UIPluginList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(uipluginsResource, uipluginsKind, c.ns, opts), &v1.UIPluginList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.UIPluginList{ListMeta: obj.(*v1.UIPluginList).ListMeta} + for _, item := range obj.(*v1.UIPluginList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested uIPlugins. +func (c *FakeUIPlugins) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(uipluginsResource, c.ns, opts)) + +} + +// Create takes the representation of a uIPlugin and creates it. Returns the server's representation of the uIPlugin, and an error, if there is any. +func (c *FakeUIPlugins) Create(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.CreateOptions) (result *v1.UIPlugin, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(uipluginsResource, c.ns, uIPlugin), &v1.UIPlugin{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.UIPlugin), err +} + +// Update takes the representation of a uIPlugin and updates it. Returns the server's representation of the uIPlugin, and an error, if there is any. +func (c *FakeUIPlugins) Update(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (result *v1.UIPlugin, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(uipluginsResource, c.ns, uIPlugin), &v1.UIPlugin{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.UIPlugin), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeUIPlugins) UpdateStatus(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (*v1.UIPlugin, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(uipluginsResource, "status", c.ns, uIPlugin), &v1.UIPlugin{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.UIPlugin), err +} + +// Delete takes name of the uIPlugin and deletes it. Returns an error if one occurs. +func (c *FakeUIPlugins) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(uipluginsResource, c.ns, name, opts), &v1.UIPlugin{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeUIPlugins) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(uipluginsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.UIPluginList{}) + return err +} + +// Patch applies the patch and returns the patched uIPlugin. +func (c *FakeUIPlugins) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.UIPlugin, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(uipluginsResource, c.ns, name, pt, data, subresources...), &v1.UIPlugin{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.UIPlugin), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/generated_expansion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/generated_expansion.go new file mode 100644 index 0000000..a80c883 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/generated_expansion.go @@ -0,0 +1,27 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +type AppExpansion interface{} + +type ClusterRepoExpansion interface{} + +type OperationExpansion interface{} + +type UIPluginExpansion interface{} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/operation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/operation.go new file mode 100644 index 0000000..40e8615 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/operation.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// OperationsGetter has a method to return a OperationInterface. +// A group's client should implement this interface. +type OperationsGetter interface { + Operations(namespace string) OperationInterface +} + +// OperationInterface has methods to work with Operation resources. +type OperationInterface interface { + Create(ctx context.Context, operation *v1.Operation, opts metav1.CreateOptions) (*v1.Operation, error) + Update(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (*v1.Operation, error) + UpdateStatus(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (*v1.Operation, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Operation, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.OperationList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Operation, err error) + OperationExpansion +} + +// operations implements OperationInterface +type operations struct { + client rest.Interface + ns string +} + +// newOperations returns a Operations +func newOperations(c *CatalogV1Client, namespace string) *operations { + return &operations{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the operation, and returns the corresponding operation object, and an error if there is any. +func (c *operations) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Operation, err error) { + result = &v1.Operation{} + err = c.client.Get(). + Namespace(c.ns). + Resource("operations"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Operations that match those selectors. +func (c *operations) List(ctx context.Context, opts metav1.ListOptions) (result *v1.OperationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.OperationList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("operations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested operations. +func (c *operations) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("operations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a operation and creates it. Returns the server's representation of the operation, and an error, if there is any. +func (c *operations) Create(ctx context.Context, operation *v1.Operation, opts metav1.CreateOptions) (result *v1.Operation, err error) { + result = &v1.Operation{} + err = c.client.Post(). + Namespace(c.ns). + Resource("operations"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(operation). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a operation and updates it. Returns the server's representation of the operation, and an error, if there is any. +func (c *operations) Update(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (result *v1.Operation, err error) { + result = &v1.Operation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("operations"). + Name(operation.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(operation). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *operations) UpdateStatus(ctx context.Context, operation *v1.Operation, opts metav1.UpdateOptions) (result *v1.Operation, err error) { + result = &v1.Operation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("operations"). + Name(operation.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(operation). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the operation and deletes it. Returns an error if one occurs. +func (c *operations) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("operations"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *operations) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("operations"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched operation. +func (c *operations) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Operation, err error) { + result = &v1.Operation{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("operations"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/uiplugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/uiplugin.go new file mode 100644 index 0000000..d353fba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/catalog.cattle.io/v1/uiplugin.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// UIPluginsGetter has a method to return a UIPluginInterface. +// A group's client should implement this interface. +type UIPluginsGetter interface { + UIPlugins(namespace string) UIPluginInterface +} + +// UIPluginInterface has methods to work with UIPlugin resources. +type UIPluginInterface interface { + Create(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.CreateOptions) (*v1.UIPlugin, error) + Update(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (*v1.UIPlugin, error) + UpdateStatus(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (*v1.UIPlugin, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.UIPlugin, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.UIPluginList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.UIPlugin, err error) + UIPluginExpansion +} + +// uIPlugins implements UIPluginInterface +type uIPlugins struct { + client rest.Interface + ns string +} + +// newUIPlugins returns a UIPlugins +func newUIPlugins(c *CatalogV1Client, namespace string) *uIPlugins { + return &uIPlugins{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the uIPlugin, and returns the corresponding uIPlugin object, and an error if there is any. +func (c *uIPlugins) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.UIPlugin, err error) { + result = &v1.UIPlugin{} + err = c.client.Get(). + Namespace(c.ns). + Resource("uiplugins"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of UIPlugins that match those selectors. +func (c *uIPlugins) List(ctx context.Context, opts metav1.ListOptions) (result *v1.UIPluginList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.UIPluginList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("uiplugins"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested uIPlugins. +func (c *uIPlugins) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("uiplugins"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a uIPlugin and creates it. Returns the server's representation of the uIPlugin, and an error, if there is any. +func (c *uIPlugins) Create(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.CreateOptions) (result *v1.UIPlugin, err error) { + result = &v1.UIPlugin{} + err = c.client.Post(). + Namespace(c.ns). + Resource("uiplugins"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(uIPlugin). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a uIPlugin and updates it. Returns the server's representation of the uIPlugin, and an error, if there is any. +func (c *uIPlugins) Update(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (result *v1.UIPlugin, err error) { + result = &v1.UIPlugin{} + err = c.client.Put(). + Namespace(c.ns). + Resource("uiplugins"). + Name(uIPlugin.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(uIPlugin). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *uIPlugins) UpdateStatus(ctx context.Context, uIPlugin *v1.UIPlugin, opts metav1.UpdateOptions) (result *v1.UIPlugin, err error) { + result = &v1.UIPlugin{} + err = c.client.Put(). + Namespace(c.ns). + Resource("uiplugins"). + Name(uIPlugin.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(uIPlugin). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the uIPlugin and deletes it. Returns an error if one occurs. +func (c *uIPlugins) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("uiplugins"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *uIPlugins) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("uiplugins"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched uIPlugin. +func (c *uIPlugins) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.UIPlugin, err error) { + result = &v1.UIPlugin{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("uiplugins"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/cluster.go new file mode 100644 index 0000000..6700d20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/cluster.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClustersGetter has a method to return a ClusterInterface. +// A group's client should implement this interface. +type ClustersGetter interface { + Clusters(namespace string) ClusterInterface +} + +// ClusterInterface has methods to work with Cluster resources. +type ClusterInterface interface { + Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (*v1.Cluster, error) + Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) + UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Cluster, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ClusterList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) + ClusterExpansion +} + +// clusters implements ClusterInterface +type clusters struct { + client rest.Interface + ns string +} + +// newClusters returns a Clusters +func newClusters(c *ProvisioningV1Client, namespace string) *clusters { + return &clusters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any. +func (c *clusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Clusters that match those selectors. +func (c *clusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ClusterList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusters. +func (c *clusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *clusters) Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Post(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *clusters) Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("clusters"). + Name(cluster.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusters) UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("clusters"). + Name(cluster.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cluster). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cluster and deletes it. Returns an error if one occurs. +func (c *clusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("clusters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("clusters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cluster. +func (c *clusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) { + result = &v1.Cluster{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("clusters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/doc.go new file mode 100644 index 0000000..dd95e75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/doc.go new file mode 100644 index 0000000..de41d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_cluster.go new file mode 100644 index 0000000..bccc97a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_cluster.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusters implements ClusterInterface +type FakeClusters struct { + Fake *FakeProvisioningV1 + ns string +} + +var clustersResource = v1.SchemeGroupVersion.WithResource("clusters") + +var clustersKind = v1.SchemeGroupVersion.WithKind("Cluster") + +// Get takes name of the cluster, and returns the corresponding cluster object, and an error if there is any. +func (c *FakeClusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(clustersResource, c.ns, name), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// List takes label and field selectors, and returns the list of Clusters that match those selectors. +func (c *FakeClusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ClusterList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(clustersResource, clustersKind, c.ns, opts), &v1.ClusterList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ClusterList{ListMeta: obj.(*v1.ClusterList).ListMeta} + for _, item := range obj.(*v1.ClusterList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusters. +func (c *FakeClusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(clustersResource, c.ns, opts)) + +} + +// Create takes the representation of a cluster and creates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *FakeClusters) Create(ctx context.Context, cluster *v1.Cluster, opts metav1.CreateOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(clustersResource, c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// Update takes the representation of a cluster and updates it. Returns the server's representation of the cluster, and an error, if there is any. +func (c *FakeClusters) Update(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(clustersResource, c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusters) UpdateStatus(ctx context.Context, cluster *v1.Cluster, opts metav1.UpdateOptions) (*v1.Cluster, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(clustersResource, "status", c.ns, cluster), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} + +// Delete takes name of the cluster and deletes it. Returns an error if one occurs. +func (c *FakeClusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(clustersResource, c.ns, name, opts), &v1.Cluster{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(clustersResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ClusterList{}) + return err +} + +// Patch applies the patch and returns the patched cluster. +func (c *FakeClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Cluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(clustersResource, c.ns, name, pt, data, subresources...), &v1.Cluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Cluster), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_provisioning.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_provisioning.cattle.io_client.go new file mode 100644 index 0000000..26b1090 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/fake/fake_provisioning.cattle.io_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeProvisioningV1 struct { + *testing.Fake +} + +func (c *FakeProvisioningV1) Clusters(namespace string) v1.ClusterInterface { + return &FakeClusters{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeProvisioningV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/generated_expansion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/generated_expansion.go new file mode 100644 index 0000000..2a5520c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +type ClusterExpansion interface{} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/provisioning.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/provisioning.cattle.io_client.go new file mode 100644 index 0000000..db3bbb1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/provisioning.cattle.io/v1/provisioning.cattle.io_client.go @@ -0,0 +1,107 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type ProvisioningV1Interface interface { + RESTClient() rest.Interface + ClustersGetter +} + +// ProvisioningV1Client is used to interact with features provided by the provisioning.cattle.io group. +type ProvisioningV1Client struct { + restClient rest.Interface +} + +func (c *ProvisioningV1Client) Clusters(namespace string) ClusterInterface { + return newClusters(c, namespace) +} + +// NewForConfig creates a new ProvisioningV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*ProvisioningV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new ProvisioningV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ProvisioningV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &ProvisioningV1Client{client}, nil +} + +// NewForConfigOrDie creates a new ProvisioningV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ProvisioningV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ProvisioningV1Client for the given RESTClient. +func New(c rest.Interface) *ProvisioningV1Client { + return &ProvisioningV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *ProvisioningV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/custommachine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/custommachine.go new file mode 100644 index 0000000..ba3496c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/custommachine.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CustomMachinesGetter has a method to return a CustomMachineInterface. +// A group's client should implement this interface. +type CustomMachinesGetter interface { + CustomMachines(namespace string) CustomMachineInterface +} + +// CustomMachineInterface has methods to work with CustomMachine resources. +type CustomMachineInterface interface { + Create(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.CreateOptions) (*v1.CustomMachine, error) + Update(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (*v1.CustomMachine, error) + UpdateStatus(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (*v1.CustomMachine, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CustomMachine, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CustomMachineList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CustomMachine, err error) + CustomMachineExpansion +} + +// customMachines implements CustomMachineInterface +type customMachines struct { + client rest.Interface + ns string +} + +// newCustomMachines returns a CustomMachines +func newCustomMachines(c *RkeV1Client, namespace string) *customMachines { + return &customMachines{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the customMachine, and returns the corresponding customMachine object, and an error if there is any. +func (c *customMachines) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CustomMachine, err error) { + result = &v1.CustomMachine{} + err = c.client.Get(). + Namespace(c.ns). + Resource("custommachines"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CustomMachines that match those selectors. +func (c *customMachines) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CustomMachineList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CustomMachineList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("custommachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested customMachines. +func (c *customMachines) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("custommachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a customMachine and creates it. Returns the server's representation of the customMachine, and an error, if there is any. +func (c *customMachines) Create(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.CreateOptions) (result *v1.CustomMachine, err error) { + result = &v1.CustomMachine{} + err = c.client.Post(). + Namespace(c.ns). + Resource("custommachines"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customMachine). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a customMachine and updates it. Returns the server's representation of the customMachine, and an error, if there is any. +func (c *customMachines) Update(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (result *v1.CustomMachine, err error) { + result = &v1.CustomMachine{} + err = c.client.Put(). + Namespace(c.ns). + Resource("custommachines"). + Name(customMachine.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customMachine). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *customMachines) UpdateStatus(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (result *v1.CustomMachine, err error) { + result = &v1.CustomMachine{} + err = c.client.Put(). + Namespace(c.ns). + Resource("custommachines"). + Name(customMachine.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(customMachine). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the customMachine and deletes it. Returns an error if one occurs. +func (c *customMachines) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("custommachines"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *customMachines) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("custommachines"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched customMachine. +func (c *customMachines) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CustomMachine, err error) { + result = &v1.CustomMachine{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("custommachines"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/doc.go new file mode 100644 index 0000000..dd95e75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/etcdsnapshot.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/etcdsnapshot.go new file mode 100644 index 0000000..e12b53b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/etcdsnapshot.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ETCDSnapshotsGetter has a method to return a ETCDSnapshotInterface. +// A group's client should implement this interface. +type ETCDSnapshotsGetter interface { + ETCDSnapshots(namespace string) ETCDSnapshotInterface +} + +// ETCDSnapshotInterface has methods to work with ETCDSnapshot resources. +type ETCDSnapshotInterface interface { + Create(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.CreateOptions) (*v1.ETCDSnapshot, error) + Update(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (*v1.ETCDSnapshot, error) + UpdateStatus(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (*v1.ETCDSnapshot, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ETCDSnapshot, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.ETCDSnapshotList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshot, err error) + ETCDSnapshotExpansion +} + +// eTCDSnapshots implements ETCDSnapshotInterface +type eTCDSnapshots struct { + client rest.Interface + ns string +} + +// newETCDSnapshots returns a ETCDSnapshots +func newETCDSnapshots(c *RkeV1Client, namespace string) *eTCDSnapshots { + return &eTCDSnapshots{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the eTCDSnapshot, and returns the corresponding eTCDSnapshot object, and an error if there is any. +func (c *eTCDSnapshots) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ETCDSnapshot, err error) { + result = &v1.ETCDSnapshot{} + err = c.client.Get(). + Namespace(c.ns). + Resource("etcdsnapshots"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ETCDSnapshots that match those selectors. +func (c *eTCDSnapshots) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ETCDSnapshotList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.ETCDSnapshotList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("etcdsnapshots"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested eTCDSnapshots. +func (c *eTCDSnapshots) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("etcdsnapshots"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a eTCDSnapshot and creates it. Returns the server's representation of the eTCDSnapshot, and an error, if there is any. +func (c *eTCDSnapshots) Create(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.CreateOptions) (result *v1.ETCDSnapshot, err error) { + result = &v1.ETCDSnapshot{} + err = c.client.Post(). + Namespace(c.ns). + Resource("etcdsnapshots"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshot). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a eTCDSnapshot and updates it. Returns the server's representation of the eTCDSnapshot, and an error, if there is any. +func (c *eTCDSnapshots) Update(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (result *v1.ETCDSnapshot, err error) { + result = &v1.ETCDSnapshot{} + err = c.client.Put(). + Namespace(c.ns). + Resource("etcdsnapshots"). + Name(eTCDSnapshot.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshot). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *eTCDSnapshots) UpdateStatus(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (result *v1.ETCDSnapshot, err error) { + result = &v1.ETCDSnapshot{} + err = c.client.Put(). + Namespace(c.ns). + Resource("etcdsnapshots"). + Name(eTCDSnapshot.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(eTCDSnapshot). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the eTCDSnapshot and deletes it. Returns an error if one occurs. +func (c *eTCDSnapshots) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("etcdsnapshots"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *eTCDSnapshots) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("etcdsnapshots"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched eTCDSnapshot. +func (c *eTCDSnapshots) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshot, err error) { + result = &v1.ETCDSnapshot{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("etcdsnapshots"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/doc.go new file mode 100644 index 0000000..de41d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_custommachine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_custommachine.go new file mode 100644 index 0000000..47d63fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_custommachine.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCustomMachines implements CustomMachineInterface +type FakeCustomMachines struct { + Fake *FakeRkeV1 + ns string +} + +var custommachinesResource = v1.SchemeGroupVersion.WithResource("custommachines") + +var custommachinesKind = v1.SchemeGroupVersion.WithKind("CustomMachine") + +// Get takes name of the customMachine, and returns the corresponding customMachine object, and an error if there is any. +func (c *FakeCustomMachines) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CustomMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(custommachinesResource, c.ns, name), &v1.CustomMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.CustomMachine), err +} + +// List takes label and field selectors, and returns the list of CustomMachines that match those selectors. +func (c *FakeCustomMachines) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CustomMachineList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(custommachinesResource, custommachinesKind, c.ns, opts), &v1.CustomMachineList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.CustomMachineList{ListMeta: obj.(*v1.CustomMachineList).ListMeta} + for _, item := range obj.(*v1.CustomMachineList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested customMachines. +func (c *FakeCustomMachines) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(custommachinesResource, c.ns, opts)) + +} + +// Create takes the representation of a customMachine and creates it. Returns the server's representation of the customMachine, and an error, if there is any. +func (c *FakeCustomMachines) Create(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.CreateOptions) (result *v1.CustomMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(custommachinesResource, c.ns, customMachine), &v1.CustomMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.CustomMachine), err +} + +// Update takes the representation of a customMachine and updates it. Returns the server's representation of the customMachine, and an error, if there is any. +func (c *FakeCustomMachines) Update(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (result *v1.CustomMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(custommachinesResource, c.ns, customMachine), &v1.CustomMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.CustomMachine), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeCustomMachines) UpdateStatus(ctx context.Context, customMachine *v1.CustomMachine, opts metav1.UpdateOptions) (*v1.CustomMachine, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(custommachinesResource, "status", c.ns, customMachine), &v1.CustomMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.CustomMachine), err +} + +// Delete takes name of the customMachine and deletes it. Returns an error if one occurs. +func (c *FakeCustomMachines) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(custommachinesResource, c.ns, name, opts), &v1.CustomMachine{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCustomMachines) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(custommachinesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.CustomMachineList{}) + return err +} + +// Patch applies the patch and returns the patched customMachine. +func (c *FakeCustomMachines) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CustomMachine, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(custommachinesResource, c.ns, name, pt, data, subresources...), &v1.CustomMachine{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.CustomMachine), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_etcdsnapshot.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_etcdsnapshot.go new file mode 100644 index 0000000..b96fc70 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_etcdsnapshot.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeETCDSnapshots implements ETCDSnapshotInterface +type FakeETCDSnapshots struct { + Fake *FakeRkeV1 + ns string +} + +var etcdsnapshotsResource = v1.SchemeGroupVersion.WithResource("etcdsnapshots") + +var etcdsnapshotsKind = v1.SchemeGroupVersion.WithKind("ETCDSnapshot") + +// Get takes name of the eTCDSnapshot, and returns the corresponding eTCDSnapshot object, and an error if there is any. +func (c *FakeETCDSnapshots) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.ETCDSnapshot, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(etcdsnapshotsResource, c.ns, name), &v1.ETCDSnapshot{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshot), err +} + +// List takes label and field selectors, and returns the list of ETCDSnapshots that match those selectors. +func (c *FakeETCDSnapshots) List(ctx context.Context, opts metav1.ListOptions) (result *v1.ETCDSnapshotList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(etcdsnapshotsResource, etcdsnapshotsKind, c.ns, opts), &v1.ETCDSnapshotList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.ETCDSnapshotList{ListMeta: obj.(*v1.ETCDSnapshotList).ListMeta} + for _, item := range obj.(*v1.ETCDSnapshotList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested eTCDSnapshots. +func (c *FakeETCDSnapshots) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(etcdsnapshotsResource, c.ns, opts)) + +} + +// Create takes the representation of a eTCDSnapshot and creates it. Returns the server's representation of the eTCDSnapshot, and an error, if there is any. +func (c *FakeETCDSnapshots) Create(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.CreateOptions) (result *v1.ETCDSnapshot, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(etcdsnapshotsResource, c.ns, eTCDSnapshot), &v1.ETCDSnapshot{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshot), err +} + +// Update takes the representation of a eTCDSnapshot and updates it. Returns the server's representation of the eTCDSnapshot, and an error, if there is any. +func (c *FakeETCDSnapshots) Update(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (result *v1.ETCDSnapshot, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(etcdsnapshotsResource, c.ns, eTCDSnapshot), &v1.ETCDSnapshot{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshot), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeETCDSnapshots) UpdateStatus(ctx context.Context, eTCDSnapshot *v1.ETCDSnapshot, opts metav1.UpdateOptions) (*v1.ETCDSnapshot, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(etcdsnapshotsResource, "status", c.ns, eTCDSnapshot), &v1.ETCDSnapshot{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshot), err +} + +// Delete takes name of the eTCDSnapshot and deletes it. Returns an error if one occurs. +func (c *FakeETCDSnapshots) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(etcdsnapshotsResource, c.ns, name, opts), &v1.ETCDSnapshot{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeETCDSnapshots) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(etcdsnapshotsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.ETCDSnapshotList{}) + return err +} + +// Patch applies the patch and returns the patched eTCDSnapshot. +func (c *FakeETCDSnapshots) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.ETCDSnapshot, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(etcdsnapshotsResource, c.ns, name, pt, data, subresources...), &v1.ETCDSnapshot{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.ETCDSnapshot), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rke.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rke.cattle.io_client.go new file mode 100644 index 0000000..0ffacd4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rke.cattle.io_client.go @@ -0,0 +1,60 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeRkeV1 struct { + *testing.Fake +} + +func (c *FakeRkeV1) CustomMachines(namespace string) v1.CustomMachineInterface { + return &FakeCustomMachines{c, namespace} +} + +func (c *FakeRkeV1) ETCDSnapshots(namespace string) v1.ETCDSnapshotInterface { + return &FakeETCDSnapshots{c, namespace} +} + +func (c *FakeRkeV1) RKEBootstraps(namespace string) v1.RKEBootstrapInterface { + return &FakeRKEBootstraps{c, namespace} +} + +func (c *FakeRkeV1) RKEBootstrapTemplates(namespace string) v1.RKEBootstrapTemplateInterface { + return &FakeRKEBootstrapTemplates{c, namespace} +} + +func (c *FakeRkeV1) RKEClusters(namespace string) v1.RKEClusterInterface { + return &FakeRKEClusters{c, namespace} +} + +func (c *FakeRkeV1) RKEControlPlanes(namespace string) v1.RKEControlPlaneInterface { + return &FakeRKEControlPlanes{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeRkeV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstrap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstrap.go new file mode 100644 index 0000000..6ecfa81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstrap.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeRKEBootstraps implements RKEBootstrapInterface +type FakeRKEBootstraps struct { + Fake *FakeRkeV1 + ns string +} + +var rkebootstrapsResource = v1.SchemeGroupVersion.WithResource("rkebootstraps") + +var rkebootstrapsKind = v1.SchemeGroupVersion.WithKind("RKEBootstrap") + +// Get takes name of the rKEBootstrap, and returns the corresponding rKEBootstrap object, and an error if there is any. +func (c *FakeRKEBootstraps) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEBootstrap, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(rkebootstrapsResource, c.ns, name), &v1.RKEBootstrap{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrap), err +} + +// List takes label and field selectors, and returns the list of RKEBootstraps that match those selectors. +func (c *FakeRKEBootstraps) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEBootstrapList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(rkebootstrapsResource, rkebootstrapsKind, c.ns, opts), &v1.RKEBootstrapList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.RKEBootstrapList{ListMeta: obj.(*v1.RKEBootstrapList).ListMeta} + for _, item := range obj.(*v1.RKEBootstrapList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested rKEBootstraps. +func (c *FakeRKEBootstraps) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(rkebootstrapsResource, c.ns, opts)) + +} + +// Create takes the representation of a rKEBootstrap and creates it. Returns the server's representation of the rKEBootstrap, and an error, if there is any. +func (c *FakeRKEBootstraps) Create(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.CreateOptions) (result *v1.RKEBootstrap, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(rkebootstrapsResource, c.ns, rKEBootstrap), &v1.RKEBootstrap{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrap), err +} + +// Update takes the representation of a rKEBootstrap and updates it. Returns the server's representation of the rKEBootstrap, and an error, if there is any. +func (c *FakeRKEBootstraps) Update(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (result *v1.RKEBootstrap, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(rkebootstrapsResource, c.ns, rKEBootstrap), &v1.RKEBootstrap{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrap), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeRKEBootstraps) UpdateStatus(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (*v1.RKEBootstrap, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(rkebootstrapsResource, "status", c.ns, rKEBootstrap), &v1.RKEBootstrap{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrap), err +} + +// Delete takes name of the rKEBootstrap and deletes it. Returns an error if one occurs. +func (c *FakeRKEBootstraps) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(rkebootstrapsResource, c.ns, name, opts), &v1.RKEBootstrap{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeRKEBootstraps) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(rkebootstrapsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.RKEBootstrapList{}) + return err +} + +// Patch applies the patch and returns the patched rKEBootstrap. +func (c *FakeRKEBootstraps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrap, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(rkebootstrapsResource, c.ns, name, pt, data, subresources...), &v1.RKEBootstrap{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrap), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstraptemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstraptemplate.go new file mode 100644 index 0000000..c7ee623 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkebootstraptemplate.go @@ -0,0 +1,129 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeRKEBootstrapTemplates implements RKEBootstrapTemplateInterface +type FakeRKEBootstrapTemplates struct { + Fake *FakeRkeV1 + ns string +} + +var rkebootstraptemplatesResource = v1.SchemeGroupVersion.WithResource("rkebootstraptemplates") + +var rkebootstraptemplatesKind = v1.SchemeGroupVersion.WithKind("RKEBootstrapTemplate") + +// Get takes name of the rKEBootstrapTemplate, and returns the corresponding rKEBootstrapTemplate object, and an error if there is any. +func (c *FakeRKEBootstrapTemplates) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEBootstrapTemplate, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(rkebootstraptemplatesResource, c.ns, name), &v1.RKEBootstrapTemplate{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrapTemplate), err +} + +// List takes label and field selectors, and returns the list of RKEBootstrapTemplates that match those selectors. +func (c *FakeRKEBootstrapTemplates) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEBootstrapTemplateList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(rkebootstraptemplatesResource, rkebootstraptemplatesKind, c.ns, opts), &v1.RKEBootstrapTemplateList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.RKEBootstrapTemplateList{ListMeta: obj.(*v1.RKEBootstrapTemplateList).ListMeta} + for _, item := range obj.(*v1.RKEBootstrapTemplateList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested rKEBootstrapTemplates. +func (c *FakeRKEBootstrapTemplates) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(rkebootstraptemplatesResource, c.ns, opts)) + +} + +// Create takes the representation of a rKEBootstrapTemplate and creates it. Returns the server's representation of the rKEBootstrapTemplate, and an error, if there is any. +func (c *FakeRKEBootstrapTemplates) Create(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.CreateOptions) (result *v1.RKEBootstrapTemplate, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(rkebootstraptemplatesResource, c.ns, rKEBootstrapTemplate), &v1.RKEBootstrapTemplate{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrapTemplate), err +} + +// Update takes the representation of a rKEBootstrapTemplate and updates it. Returns the server's representation of the rKEBootstrapTemplate, and an error, if there is any. +func (c *FakeRKEBootstrapTemplates) Update(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.UpdateOptions) (result *v1.RKEBootstrapTemplate, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(rkebootstraptemplatesResource, c.ns, rKEBootstrapTemplate), &v1.RKEBootstrapTemplate{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrapTemplate), err +} + +// Delete takes name of the rKEBootstrapTemplate and deletes it. Returns an error if one occurs. +func (c *FakeRKEBootstrapTemplates) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(rkebootstraptemplatesResource, c.ns, name, opts), &v1.RKEBootstrapTemplate{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeRKEBootstrapTemplates) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(rkebootstraptemplatesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.RKEBootstrapTemplateList{}) + return err +} + +// Patch applies the patch and returns the patched rKEBootstrapTemplate. +func (c *FakeRKEBootstrapTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrapTemplate, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(rkebootstraptemplatesResource, c.ns, name, pt, data, subresources...), &v1.RKEBootstrapTemplate{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEBootstrapTemplate), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecluster.go new file mode 100644 index 0000000..708faaa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecluster.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeRKEClusters implements RKEClusterInterface +type FakeRKEClusters struct { + Fake *FakeRkeV1 + ns string +} + +var rkeclustersResource = v1.SchemeGroupVersion.WithResource("rkeclusters") + +var rkeclustersKind = v1.SchemeGroupVersion.WithKind("RKECluster") + +// Get takes name of the rKECluster, and returns the corresponding rKECluster object, and an error if there is any. +func (c *FakeRKEClusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKECluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(rkeclustersResource, c.ns, name), &v1.RKECluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKECluster), err +} + +// List takes label and field selectors, and returns the list of RKEClusters that match those selectors. +func (c *FakeRKEClusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEClusterList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(rkeclustersResource, rkeclustersKind, c.ns, opts), &v1.RKEClusterList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.RKEClusterList{ListMeta: obj.(*v1.RKEClusterList).ListMeta} + for _, item := range obj.(*v1.RKEClusterList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested rKEClusters. +func (c *FakeRKEClusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(rkeclustersResource, c.ns, opts)) + +} + +// Create takes the representation of a rKECluster and creates it. Returns the server's representation of the rKECluster, and an error, if there is any. +func (c *FakeRKEClusters) Create(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.CreateOptions) (result *v1.RKECluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(rkeclustersResource, c.ns, rKECluster), &v1.RKECluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKECluster), err +} + +// Update takes the representation of a rKECluster and updates it. Returns the server's representation of the rKECluster, and an error, if there is any. +func (c *FakeRKEClusters) Update(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (result *v1.RKECluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(rkeclustersResource, c.ns, rKECluster), &v1.RKECluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKECluster), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeRKEClusters) UpdateStatus(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (*v1.RKECluster, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(rkeclustersResource, "status", c.ns, rKECluster), &v1.RKECluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKECluster), err +} + +// Delete takes name of the rKECluster and deletes it. Returns an error if one occurs. +func (c *FakeRKEClusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(rkeclustersResource, c.ns, name, opts), &v1.RKECluster{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeRKEClusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(rkeclustersResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.RKEClusterList{}) + return err +} + +// Patch applies the patch and returns the patched rKECluster. +func (c *FakeRKEClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKECluster, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(rkeclustersResource, c.ns, name, pt, data, subresources...), &v1.RKECluster{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKECluster), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecontrolplane.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecontrolplane.go new file mode 100644 index 0000000..0a514e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/fake/fake_rkecontrolplane.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeRKEControlPlanes implements RKEControlPlaneInterface +type FakeRKEControlPlanes struct { + Fake *FakeRkeV1 + ns string +} + +var rkecontrolplanesResource = v1.SchemeGroupVersion.WithResource("rkecontrolplanes") + +var rkecontrolplanesKind = v1.SchemeGroupVersion.WithKind("RKEControlPlane") + +// Get takes name of the rKEControlPlane, and returns the corresponding rKEControlPlane object, and an error if there is any. +func (c *FakeRKEControlPlanes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEControlPlane, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(rkecontrolplanesResource, c.ns, name), &v1.RKEControlPlane{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEControlPlane), err +} + +// List takes label and field selectors, and returns the list of RKEControlPlanes that match those selectors. +func (c *FakeRKEControlPlanes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEControlPlaneList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(rkecontrolplanesResource, rkecontrolplanesKind, c.ns, opts), &v1.RKEControlPlaneList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.RKEControlPlaneList{ListMeta: obj.(*v1.RKEControlPlaneList).ListMeta} + for _, item := range obj.(*v1.RKEControlPlaneList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested rKEControlPlanes. +func (c *FakeRKEControlPlanes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(rkecontrolplanesResource, c.ns, opts)) + +} + +// Create takes the representation of a rKEControlPlane and creates it. Returns the server's representation of the rKEControlPlane, and an error, if there is any. +func (c *FakeRKEControlPlanes) Create(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.CreateOptions) (result *v1.RKEControlPlane, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(rkecontrolplanesResource, c.ns, rKEControlPlane), &v1.RKEControlPlane{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEControlPlane), err +} + +// Update takes the representation of a rKEControlPlane and updates it. Returns the server's representation of the rKEControlPlane, and an error, if there is any. +func (c *FakeRKEControlPlanes) Update(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (result *v1.RKEControlPlane, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(rkecontrolplanesResource, c.ns, rKEControlPlane), &v1.RKEControlPlane{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEControlPlane), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeRKEControlPlanes) UpdateStatus(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (*v1.RKEControlPlane, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(rkecontrolplanesResource, "status", c.ns, rKEControlPlane), &v1.RKEControlPlane{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEControlPlane), err +} + +// Delete takes name of the rKEControlPlane and deletes it. Returns an error if one occurs. +func (c *FakeRKEControlPlanes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(rkecontrolplanesResource, c.ns, name, opts), &v1.RKEControlPlane{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeRKEControlPlanes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(rkecontrolplanesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.RKEControlPlaneList{}) + return err +} + +// Patch applies the patch and returns the patched rKEControlPlane. +func (c *FakeRKEControlPlanes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEControlPlane, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(rkecontrolplanesResource, c.ns, name, pt, data, subresources...), &v1.RKEControlPlane{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.RKEControlPlane), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/generated_expansion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/generated_expansion.go new file mode 100644 index 0000000..00bb93c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/generated_expansion.go @@ -0,0 +1,31 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +type CustomMachineExpansion interface{} + +type ETCDSnapshotExpansion interface{} + +type RKEBootstrapExpansion interface{} + +type RKEBootstrapTemplateExpansion interface{} + +type RKEClusterExpansion interface{} + +type RKEControlPlaneExpansion interface{} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rke.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rke.cattle.io_client.go new file mode 100644 index 0000000..4bd4107 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rke.cattle.io_client.go @@ -0,0 +1,132 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type RkeV1Interface interface { + RESTClient() rest.Interface + CustomMachinesGetter + ETCDSnapshotsGetter + RKEBootstrapsGetter + RKEBootstrapTemplatesGetter + RKEClustersGetter + RKEControlPlanesGetter +} + +// RkeV1Client is used to interact with features provided by the rke.cattle.io group. +type RkeV1Client struct { + restClient rest.Interface +} + +func (c *RkeV1Client) CustomMachines(namespace string) CustomMachineInterface { + return newCustomMachines(c, namespace) +} + +func (c *RkeV1Client) ETCDSnapshots(namespace string) ETCDSnapshotInterface { + return newETCDSnapshots(c, namespace) +} + +func (c *RkeV1Client) RKEBootstraps(namespace string) RKEBootstrapInterface { + return newRKEBootstraps(c, namespace) +} + +func (c *RkeV1Client) RKEBootstrapTemplates(namespace string) RKEBootstrapTemplateInterface { + return newRKEBootstrapTemplates(c, namespace) +} + +func (c *RkeV1Client) RKEClusters(namespace string) RKEClusterInterface { + return newRKEClusters(c, namespace) +} + +func (c *RkeV1Client) RKEControlPlanes(namespace string) RKEControlPlaneInterface { + return newRKEControlPlanes(c, namespace) +} + +// NewForConfig creates a new RkeV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*RkeV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new RkeV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*RkeV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &RkeV1Client{client}, nil +} + +// NewForConfigOrDie creates a new RkeV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *RkeV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new RkeV1Client for the given RESTClient. +func New(c rest.Interface) *RkeV1Client { + return &RkeV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *RkeV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstrap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstrap.go new file mode 100644 index 0000000..16695ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstrap.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// RKEBootstrapsGetter has a method to return a RKEBootstrapInterface. +// A group's client should implement this interface. +type RKEBootstrapsGetter interface { + RKEBootstraps(namespace string) RKEBootstrapInterface +} + +// RKEBootstrapInterface has methods to work with RKEBootstrap resources. +type RKEBootstrapInterface interface { + Create(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.CreateOptions) (*v1.RKEBootstrap, error) + Update(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (*v1.RKEBootstrap, error) + UpdateStatus(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (*v1.RKEBootstrap, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RKEBootstrap, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RKEBootstrapList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrap, err error) + RKEBootstrapExpansion +} + +// rKEBootstraps implements RKEBootstrapInterface +type rKEBootstraps struct { + client rest.Interface + ns string +} + +// newRKEBootstraps returns a RKEBootstraps +func newRKEBootstraps(c *RkeV1Client, namespace string) *rKEBootstraps { + return &rKEBootstraps{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the rKEBootstrap, and returns the corresponding rKEBootstrap object, and an error if there is any. +func (c *rKEBootstraps) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEBootstrap, err error) { + result = &v1.RKEBootstrap{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraps"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of RKEBootstraps that match those selectors. +func (c *rKEBootstraps) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEBootstrapList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.RKEBootstrapList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested rKEBootstraps. +func (c *rKEBootstraps) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a rKEBootstrap and creates it. Returns the server's representation of the rKEBootstrap, and an error, if there is any. +func (c *rKEBootstraps) Create(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.CreateOptions) (result *v1.RKEBootstrap, err error) { + result = &v1.RKEBootstrap{} + err = c.client.Post(). + Namespace(c.ns). + Resource("rkebootstraps"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEBootstrap). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a rKEBootstrap and updates it. Returns the server's representation of the rKEBootstrap, and an error, if there is any. +func (c *rKEBootstraps) Update(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (result *v1.RKEBootstrap, err error) { + result = &v1.RKEBootstrap{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkebootstraps"). + Name(rKEBootstrap.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEBootstrap). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *rKEBootstraps) UpdateStatus(ctx context.Context, rKEBootstrap *v1.RKEBootstrap, opts metav1.UpdateOptions) (result *v1.RKEBootstrap, err error) { + result = &v1.RKEBootstrap{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkebootstraps"). + Name(rKEBootstrap.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEBootstrap). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the rKEBootstrap and deletes it. Returns an error if one occurs. +func (c *rKEBootstraps) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("rkebootstraps"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *rKEBootstraps) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("rkebootstraps"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched rKEBootstrap. +func (c *rKEBootstraps) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrap, err error) { + result = &v1.RKEBootstrap{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("rkebootstraps"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstraptemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstraptemplate.go new file mode 100644 index 0000000..43ba699 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkebootstraptemplate.go @@ -0,0 +1,178 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// RKEBootstrapTemplatesGetter has a method to return a RKEBootstrapTemplateInterface. +// A group's client should implement this interface. +type RKEBootstrapTemplatesGetter interface { + RKEBootstrapTemplates(namespace string) RKEBootstrapTemplateInterface +} + +// RKEBootstrapTemplateInterface has methods to work with RKEBootstrapTemplate resources. +type RKEBootstrapTemplateInterface interface { + Create(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.CreateOptions) (*v1.RKEBootstrapTemplate, error) + Update(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.UpdateOptions) (*v1.RKEBootstrapTemplate, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RKEBootstrapTemplate, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RKEBootstrapTemplateList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrapTemplate, err error) + RKEBootstrapTemplateExpansion +} + +// rKEBootstrapTemplates implements RKEBootstrapTemplateInterface +type rKEBootstrapTemplates struct { + client rest.Interface + ns string +} + +// newRKEBootstrapTemplates returns a RKEBootstrapTemplates +func newRKEBootstrapTemplates(c *RkeV1Client, namespace string) *rKEBootstrapTemplates { + return &rKEBootstrapTemplates{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the rKEBootstrapTemplate, and returns the corresponding rKEBootstrapTemplate object, and an error if there is any. +func (c *rKEBootstrapTemplates) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEBootstrapTemplate, err error) { + result = &v1.RKEBootstrapTemplate{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of RKEBootstrapTemplates that match those selectors. +func (c *rKEBootstrapTemplates) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEBootstrapTemplateList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.RKEBootstrapTemplateList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested rKEBootstrapTemplates. +func (c *rKEBootstrapTemplates) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a rKEBootstrapTemplate and creates it. Returns the server's representation of the rKEBootstrapTemplate, and an error, if there is any. +func (c *rKEBootstrapTemplates) Create(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.CreateOptions) (result *v1.RKEBootstrapTemplate, err error) { + result = &v1.RKEBootstrapTemplate{} + err = c.client.Post(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEBootstrapTemplate). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a rKEBootstrapTemplate and updates it. Returns the server's representation of the rKEBootstrapTemplate, and an error, if there is any. +func (c *rKEBootstrapTemplates) Update(ctx context.Context, rKEBootstrapTemplate *v1.RKEBootstrapTemplate, opts metav1.UpdateOptions) (result *v1.RKEBootstrapTemplate, err error) { + result = &v1.RKEBootstrapTemplate{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + Name(rKEBootstrapTemplate.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEBootstrapTemplate). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the rKEBootstrapTemplate and deletes it. Returns an error if one occurs. +func (c *rKEBootstrapTemplates) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *rKEBootstrapTemplates) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched rKEBootstrapTemplate. +func (c *rKEBootstrapTemplates) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEBootstrapTemplate, err error) { + result = &v1.RKEBootstrapTemplate{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("rkebootstraptemplates"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecluster.go new file mode 100644 index 0000000..3cb7ba4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecluster.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// RKEClustersGetter has a method to return a RKEClusterInterface. +// A group's client should implement this interface. +type RKEClustersGetter interface { + RKEClusters(namespace string) RKEClusterInterface +} + +// RKEClusterInterface has methods to work with RKECluster resources. +type RKEClusterInterface interface { + Create(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.CreateOptions) (*v1.RKECluster, error) + Update(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (*v1.RKECluster, error) + UpdateStatus(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (*v1.RKECluster, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RKECluster, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RKEClusterList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKECluster, err error) + RKEClusterExpansion +} + +// rKEClusters implements RKEClusterInterface +type rKEClusters struct { + client rest.Interface + ns string +} + +// newRKEClusters returns a RKEClusters +func newRKEClusters(c *RkeV1Client, namespace string) *rKEClusters { + return &rKEClusters{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the rKECluster, and returns the corresponding rKECluster object, and an error if there is any. +func (c *rKEClusters) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKECluster, err error) { + result = &v1.RKECluster{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkeclusters"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of RKEClusters that match those selectors. +func (c *rKEClusters) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEClusterList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.RKEClusterList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkeclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested rKEClusters. +func (c *rKEClusters) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("rkeclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a rKECluster and creates it. Returns the server's representation of the rKECluster, and an error, if there is any. +func (c *rKEClusters) Create(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.CreateOptions) (result *v1.RKECluster, err error) { + result = &v1.RKECluster{} + err = c.client.Post(). + Namespace(c.ns). + Resource("rkeclusters"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKECluster). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a rKECluster and updates it. Returns the server's representation of the rKECluster, and an error, if there is any. +func (c *rKEClusters) Update(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (result *v1.RKECluster, err error) { + result = &v1.RKECluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkeclusters"). + Name(rKECluster.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKECluster). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *rKEClusters) UpdateStatus(ctx context.Context, rKECluster *v1.RKECluster, opts metav1.UpdateOptions) (result *v1.RKECluster, err error) { + result = &v1.RKECluster{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkeclusters"). + Name(rKECluster.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKECluster). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the rKECluster and deletes it. Returns an error if one occurs. +func (c *rKEClusters) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("rkeclusters"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *rKEClusters) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("rkeclusters"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched rKECluster. +func (c *rKEClusters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKECluster, err error) { + result = &v1.RKECluster{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("rkeclusters"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecontrolplane.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecontrolplane.go new file mode 100644 index 0000000..4b58dba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/rke.cattle.io/v1/rkecontrolplane.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// RKEControlPlanesGetter has a method to return a RKEControlPlaneInterface. +// A group's client should implement this interface. +type RKEControlPlanesGetter interface { + RKEControlPlanes(namespace string) RKEControlPlaneInterface +} + +// RKEControlPlaneInterface has methods to work with RKEControlPlane resources. +type RKEControlPlaneInterface interface { + Create(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.CreateOptions) (*v1.RKEControlPlane, error) + Update(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (*v1.RKEControlPlane, error) + UpdateStatus(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (*v1.RKEControlPlane, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RKEControlPlane, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RKEControlPlaneList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEControlPlane, err error) + RKEControlPlaneExpansion +} + +// rKEControlPlanes implements RKEControlPlaneInterface +type rKEControlPlanes struct { + client rest.Interface + ns string +} + +// newRKEControlPlanes returns a RKEControlPlanes +func newRKEControlPlanes(c *RkeV1Client, namespace string) *rKEControlPlanes { + return &rKEControlPlanes{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the rKEControlPlane, and returns the corresponding rKEControlPlane object, and an error if there is any. +func (c *rKEControlPlanes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RKEControlPlane, err error) { + result = &v1.RKEControlPlane{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of RKEControlPlanes that match those selectors. +func (c *rKEControlPlanes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RKEControlPlaneList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.RKEControlPlaneList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested rKEControlPlanes. +func (c *rKEControlPlanes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a rKEControlPlane and creates it. Returns the server's representation of the rKEControlPlane, and an error, if there is any. +func (c *rKEControlPlanes) Create(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.CreateOptions) (result *v1.RKEControlPlane, err error) { + result = &v1.RKEControlPlane{} + err = c.client.Post(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEControlPlane). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a rKEControlPlane and updates it. Returns the server's representation of the rKEControlPlane, and an error, if there is any. +func (c *rKEControlPlanes) Update(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (result *v1.RKEControlPlane, err error) { + result = &v1.RKEControlPlane{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + Name(rKEControlPlane.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEControlPlane). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *rKEControlPlanes) UpdateStatus(ctx context.Context, rKEControlPlane *v1.RKEControlPlane, opts metav1.UpdateOptions) (result *v1.RKEControlPlane, err error) { + result = &v1.RKEControlPlane{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + Name(rKEControlPlane.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(rKEControlPlane). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the rKEControlPlane and deletes it. Returns an error if one occurs. +func (c *rKEControlPlanes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *rKEControlPlanes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("rkecontrolplanes"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched rKEControlPlane. +func (c *rKEControlPlanes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RKEControlPlane, err error) { + result = &v1.RKEControlPlane{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("rkecontrolplanes"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/doc.go new file mode 100644 index 0000000..dd95e75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/doc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/doc.go new file mode 100644 index 0000000..de41d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_plan.go new file mode 100644 index 0000000..5d54339 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_plan.go @@ -0,0 +1,141 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + "context" + + v1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakePlans implements PlanInterface +type FakePlans struct { + Fake *FakeUpgradeV1 + ns string +} + +var plansResource = v1.SchemeGroupVersion.WithResource("plans") + +var plansKind = v1.SchemeGroupVersion.WithKind("Plan") + +// Get takes name of the plan, and returns the corresponding plan object, and an error if there is any. +func (c *FakePlans) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Plan, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(plansResource, c.ns, name), &v1.Plan{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Plan), err +} + +// List takes label and field selectors, and returns the list of Plans that match those selectors. +func (c *FakePlans) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PlanList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(plansResource, plansKind, c.ns, opts), &v1.PlanList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.PlanList{ListMeta: obj.(*v1.PlanList).ListMeta} + for _, item := range obj.(*v1.PlanList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested plans. +func (c *FakePlans) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(plansResource, c.ns, opts)) + +} + +// Create takes the representation of a plan and creates it. Returns the server's representation of the plan, and an error, if there is any. +func (c *FakePlans) Create(ctx context.Context, plan *v1.Plan, opts metav1.CreateOptions) (result *v1.Plan, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(plansResource, c.ns, plan), &v1.Plan{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Plan), err +} + +// Update takes the representation of a plan and updates it. Returns the server's representation of the plan, and an error, if there is any. +func (c *FakePlans) Update(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (result *v1.Plan, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(plansResource, c.ns, plan), &v1.Plan{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Plan), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakePlans) UpdateStatus(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (*v1.Plan, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(plansResource, "status", c.ns, plan), &v1.Plan{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Plan), err +} + +// Delete takes name of the plan and deletes it. Returns an error if one occurs. +func (c *FakePlans) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(plansResource, c.ns, name, opts), &v1.Plan{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakePlans) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(plansResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.PlanList{}) + return err +} + +// Patch applies the patch and returns the patched plan. +func (c *FakePlans) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Plan, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(plansResource, c.ns, name, pt, data, subresources...), &v1.Plan{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.Plan), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_upgrade.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_upgrade.cattle.io_client.go new file mode 100644 index 0000000..7053e94 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/fake/fake_upgrade.cattle.io_client.go @@ -0,0 +1,40 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/rancher/rancher/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeUpgradeV1 struct { + *testing.Fake +} + +func (c *FakeUpgradeV1) Plans(namespace string) v1.PlanInterface { + return &FakePlans{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeUpgradeV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/generated_expansion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/generated_expansion.go new file mode 100644 index 0000000..2d22ce7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +type PlanExpansion interface{} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/plan.go new file mode 100644 index 0000000..135c177 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/plan.go @@ -0,0 +1,195 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + scheme "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + v1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// PlansGetter has a method to return a PlanInterface. +// A group's client should implement this interface. +type PlansGetter interface { + Plans(namespace string) PlanInterface +} + +// PlanInterface has methods to work with Plan resources. +type PlanInterface interface { + Create(ctx context.Context, plan *v1.Plan, opts metav1.CreateOptions) (*v1.Plan, error) + Update(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (*v1.Plan, error) + UpdateStatus(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (*v1.Plan, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Plan, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.PlanList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Plan, err error) + PlanExpansion +} + +// plans implements PlanInterface +type plans struct { + client rest.Interface + ns string +} + +// newPlans returns a Plans +func newPlans(c *UpgradeV1Client, namespace string) *plans { + return &plans{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the plan, and returns the corresponding plan object, and an error if there is any. +func (c *plans) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Plan, err error) { + result = &v1.Plan{} + err = c.client.Get(). + Namespace(c.ns). + Resource("plans"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Plans that match those selectors. +func (c *plans) List(ctx context.Context, opts metav1.ListOptions) (result *v1.PlanList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.PlanList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("plans"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested plans. +func (c *plans) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("plans"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a plan and creates it. Returns the server's representation of the plan, and an error, if there is any. +func (c *plans) Create(ctx context.Context, plan *v1.Plan, opts metav1.CreateOptions) (result *v1.Plan, err error) { + result = &v1.Plan{} + err = c.client.Post(). + Namespace(c.ns). + Resource("plans"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(plan). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a plan and updates it. Returns the server's representation of the plan, and an error, if there is any. +func (c *plans) Update(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (result *v1.Plan, err error) { + result = &v1.Plan{} + err = c.client.Put(). + Namespace(c.ns). + Resource("plans"). + Name(plan.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(plan). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *plans) UpdateStatus(ctx context.Context, plan *v1.Plan, opts metav1.UpdateOptions) (result *v1.Plan, err error) { + result = &v1.Plan{} + err = c.client.Put(). + Namespace(c.ns). + Resource("plans"). + Name(plan.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(plan). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the plan and deletes it. Returns an error if one occurs. +func (c *plans) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("plans"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *plans) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("plans"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched plan. +func (c *plans) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Plan, err error) { + result = &v1.Plan{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("plans"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/upgrade.cattle.io_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/upgrade.cattle.io_client.go new file mode 100644 index 0000000..80c7e28 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/clientset/versioned/typed/upgrade.cattle.io/v1/upgrade.cattle.io_client.go @@ -0,0 +1,107 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + "github.com/rancher/rancher/pkg/generated/clientset/versioned/scheme" + v1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + rest "k8s.io/client-go/rest" +) + +type UpgradeV1Interface interface { + RESTClient() rest.Interface + PlansGetter +} + +// UpgradeV1Client is used to interact with features provided by the upgrade.cattle.io group. +type UpgradeV1Client struct { + restClient rest.Interface +} + +func (c *UpgradeV1Client) Plans(namespace string) PlanInterface { + return newPlans(c, namespace) +} + +// NewForConfig creates a new UpgradeV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*UpgradeV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new UpgradeV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*UpgradeV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &UpgradeV1Client{client}, nil +} + +// NewForConfigOrDie creates a new UpgradeV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *UpgradeV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new UpgradeV1Client for the given RESTClient. +func New(c rest.Interface) *UpgradeV1Client { + return &UpgradeV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *UpgradeV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/compose/zz_generated_compose.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/compose/zz_generated_compose.go new file mode 100644 index 0000000..aab277a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/compose/zz_generated_compose.go @@ -0,0 +1,97 @@ +package compose + +import ( + clusterClient "github.com/rancher/rancher/pkg/client/generated/cluster/v3" + managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3" + projectClient "github.com/rancher/rancher/pkg/client/generated/project/v3" +) + +type Config struct { + Version string `yaml:"version,omitempty"` + + // Management Client + NodePools map[string]managementClient.NodePool `json:"nodePools,omitempty" yaml:"nodePools,omitempty"` + Nodes map[string]managementClient.Node `json:"nodes,omitempty" yaml:"nodes,omitempty"` + NodeDrivers map[string]managementClient.NodeDriver `json:"nodeDrivers,omitempty" yaml:"nodeDrivers,omitempty"` + NodeTemplates map[string]managementClient.NodeTemplate `json:"nodeTemplates,omitempty" yaml:"nodeTemplates,omitempty"` + PodSecurityAdmissionConfigurationTemplates map[string]managementClient.PodSecurityAdmissionConfigurationTemplate `json:"podSecurityAdmissionConfigurationTemplates,omitempty" yaml:"podSecurityAdmissionConfigurationTemplates,omitempty"` + Projects map[string]managementClient.Project `json:"projects,omitempty" yaml:"projects,omitempty"` + GlobalRoles map[string]managementClient.GlobalRole `json:"globalRoles,omitempty" yaml:"globalRoles,omitempty"` + GlobalRoleBindings map[string]managementClient.GlobalRoleBinding `json:"globalRoleBindings,omitempty" yaml:"globalRoleBindings,omitempty"` + RoleTemplates map[string]managementClient.RoleTemplate `json:"roleTemplates,omitempty" yaml:"roleTemplates,omitempty"` + ClusterRoleTemplateBindings map[string]managementClient.ClusterRoleTemplateBinding `json:"clusterRoleTemplateBindings,omitempty" yaml:"clusterRoleTemplateBindings,omitempty"` + ProjectRoleTemplateBindings map[string]managementClient.ProjectRoleTemplateBinding `json:"projectRoleTemplateBindings,omitempty" yaml:"projectRoleTemplateBindings,omitempty"` + Clusters map[string]managementClient.Cluster `json:"clusters,omitempty" yaml:"clusters,omitempty"` + ClusterRegistrationTokens map[string]managementClient.ClusterRegistrationToken `json:"clusterRegistrationTokens,omitempty" yaml:"clusterRegistrationTokens,omitempty"` + Catalogs map[string]managementClient.Catalog `json:"catalogs,omitempty" yaml:"catalogs,omitempty"` + Templates map[string]managementClient.Template `json:"templates,omitempty" yaml:"templates,omitempty"` + CatalogTemplates map[string]managementClient.CatalogTemplate `json:"catalogTemplates,omitempty" yaml:"catalogTemplates,omitempty"` + CatalogTemplateVersions map[string]managementClient.CatalogTemplateVersion `json:"catalogTemplateVersions,omitempty" yaml:"catalogTemplateVersions,omitempty"` + TemplateVersions map[string]managementClient.TemplateVersion `json:"templateVersions,omitempty" yaml:"templateVersions,omitempty"` + TemplateContents map[string]managementClient.TemplateContent `json:"templateContents,omitempty" yaml:"templateContents,omitempty"` + Groups map[string]managementClient.Group `json:"groups,omitempty" yaml:"groups,omitempty"` + GroupMembers map[string]managementClient.GroupMember `json:"groupMembers,omitempty" yaml:"groupMembers,omitempty"` + SamlTokens map[string]managementClient.SamlToken `json:"samlTokens,omitempty" yaml:"samlTokens,omitempty"` + Users map[string]managementClient.User `json:"users,omitempty" yaml:"users,omitempty"` + LdapConfigs map[string]managementClient.LdapConfig `json:"ldapConfigs,omitempty" yaml:"ldapConfigs,omitempty"` + Tokens map[string]managementClient.Token `json:"tokens,omitempty" yaml:"tokens,omitempty"` + DynamicSchemas map[string]managementClient.DynamicSchema `json:"dynamicSchemas,omitempty" yaml:"dynamicSchemas,omitempty"` + Preferences map[string]managementClient.Preference `json:"preferences,omitempty" yaml:"preferences,omitempty"` + Settings map[string]managementClient.Setting `json:"settings,omitempty" yaml:"settings,omitempty"` + Features map[string]managementClient.Feature `json:"features,omitempty" yaml:"features,omitempty"` + ComposeConfigs map[string]managementClient.ComposeConfig `json:"composeConfigs,omitempty" yaml:"composeConfigs,omitempty"` + ProjectCatalogs map[string]managementClient.ProjectCatalog `json:"projectCatalogs,omitempty" yaml:"projectCatalogs,omitempty"` + ClusterCatalogs map[string]managementClient.ClusterCatalog `json:"clusterCatalogs,omitempty" yaml:"clusterCatalogs,omitempty"` + MultiClusterApps map[string]managementClient.MultiClusterApp `json:"multiClusterApps,omitempty" yaml:"multiClusterApps,omitempty"` + MultiClusterAppRevisions map[string]managementClient.MultiClusterAppRevision `json:"multiClusterAppRevisions,omitempty" yaml:"multiClusterAppRevisions,omitempty"` + GlobalDnss map[string]managementClient.GlobalDns `json:"globalDnses,omitempty" yaml:"globalDnses,omitempty"` + GlobalDnsProviders map[string]managementClient.GlobalDnsProvider `json:"globalDnsProviders,omitempty" yaml:"globalDnsProviders,omitempty"` + KontainerDrivers map[string]managementClient.KontainerDriver `json:"kontainerDrivers,omitempty" yaml:"kontainerDrivers,omitempty"` + EtcdBackups map[string]managementClient.EtcdBackup `json:"etcdBackups,omitempty" yaml:"etcdBackups,omitempty"` + CloudCredentials map[string]managementClient.CloudCredential `json:"cloudCredentials,omitempty" yaml:"cloudCredentials,omitempty"` + ManagementSecrets map[string]managementClient.ManagementSecret `json:"managementSecrets,omitempty" yaml:"managementSecrets,omitempty"` + ClusterTemplates map[string]managementClient.ClusterTemplate `json:"clusterTemplates,omitempty" yaml:"clusterTemplates,omitempty"` + ClusterTemplateRevisions map[string]managementClient.ClusterTemplateRevision `json:"clusterTemplateRevisions,omitempty" yaml:"clusterTemplateRevisions,omitempty"` + RkeK8sSystemImages map[string]managementClient.RkeK8sSystemImage `json:"rkeK8sSystemImages,omitempty" yaml:"rkeK8sSystemImages,omitempty"` + RkeK8sServiceOptions map[string]managementClient.RkeK8sServiceOption `json:"rkeK8sServiceOptions,omitempty" yaml:"rkeK8sServiceOptions,omitempty"` + RkeAddons map[string]managementClient.RkeAddon `json:"rkeAddons,omitempty" yaml:"rkeAddons,omitempty"` + FleetWorkspaces map[string]managementClient.FleetWorkspace `json:"fleetWorkspaces,omitempty" yaml:"fleetWorkspaces,omitempty"` + RancherUserNotifications map[string]managementClient.RancherUserNotification `json:"rancherUserNotifications,omitempty" yaml:"rancherUserNotifications,omitempty"` + + // Cluster Client + Namespaces map[string]clusterClient.Namespace `json:"namespaces,omitempty" yaml:"namespaces,omitempty"` + PersistentVolumes map[string]clusterClient.PersistentVolume `json:"persistentVolumes,omitempty" yaml:"persistentVolumes,omitempty"` + StorageClasss map[string]clusterClient.StorageClass `json:"storageClasses,omitempty" yaml:"storageClasses,omitempty"` + APIServices map[string]clusterClient.APIService `json:"apiServices,omitempty" yaml:"apiServices,omitempty"` + + // Project Client + PersistentVolumeClaims map[string]projectClient.PersistentVolumeClaim `json:"persistentVolumeClaims,omitempty" yaml:"persistentVolumeClaims,omitempty"` + ConfigMaps map[string]projectClient.ConfigMap `json:"configMaps,omitempty" yaml:"configMaps,omitempty"` + Ingresss map[string]projectClient.Ingress `json:"ingresses,omitempty" yaml:"ingresses,omitempty"` + Secrets map[string]projectClient.Secret `json:"secrets,omitempty" yaml:"secrets,omitempty"` + ServiceAccountTokens map[string]projectClient.ServiceAccountToken `json:"serviceAccountTokens,omitempty" yaml:"serviceAccountTokens,omitempty"` + DockerCredentials map[string]projectClient.DockerCredential `json:"dockerCredentials,omitempty" yaml:"dockerCredentials,omitempty"` + Certificates map[string]projectClient.Certificate `json:"certificates,omitempty" yaml:"certificates,omitempty"` + BasicAuths map[string]projectClient.BasicAuth `json:"basicAuths,omitempty" yaml:"basicAuths,omitempty"` + SSHAuths map[string]projectClient.SSHAuth `json:"sshAuths,omitempty" yaml:"sshAuths,omitempty"` + NamespacedSecrets map[string]projectClient.NamespacedSecret `json:"namespacedSecrets,omitempty" yaml:"namespacedSecrets,omitempty"` + NamespacedServiceAccountTokens map[string]projectClient.NamespacedServiceAccountToken `json:"namespacedServiceAccountTokens,omitempty" yaml:"namespacedServiceAccountTokens,omitempty"` + NamespacedDockerCredentials map[string]projectClient.NamespacedDockerCredential `json:"namespacedDockerCredentials,omitempty" yaml:"namespacedDockerCredentials,omitempty"` + NamespacedCertificates map[string]projectClient.NamespacedCertificate `json:"namespacedCertificates,omitempty" yaml:"namespacedCertificates,omitempty"` + NamespacedBasicAuths map[string]projectClient.NamespacedBasicAuth `json:"namespacedBasicAuths,omitempty" yaml:"namespacedBasicAuths,omitempty"` + NamespacedSSHAuths map[string]projectClient.NamespacedSSHAuth `json:"namespacedSshAuths,omitempty" yaml:"namespacedSshAuths,omitempty"` + Services map[string]projectClient.Service `json:"services,omitempty" yaml:"services,omitempty"` + DNSRecords map[string]projectClient.DNSRecord `json:"dnsRecords,omitempty" yaml:"dnsRecords,omitempty"` + Pods map[string]projectClient.Pod `json:"pods,omitempty" yaml:"pods,omitempty"` + Deployments map[string]projectClient.Deployment `json:"deployments,omitempty" yaml:"deployments,omitempty"` + ReplicationControllers map[string]projectClient.ReplicationController `json:"replicationControllers,omitempty" yaml:"replicationControllers,omitempty"` + ReplicaSets map[string]projectClient.ReplicaSet `json:"replicaSets,omitempty" yaml:"replicaSets,omitempty"` + StatefulSets map[string]projectClient.StatefulSet `json:"statefulSets,omitempty" yaml:"statefulSets,omitempty"` + DaemonSets map[string]projectClient.DaemonSet `json:"daemonSets,omitempty" yaml:"daemonSets,omitempty"` + Jobs map[string]projectClient.Job `json:"jobs,omitempty" yaml:"jobs,omitempty"` + CronJobs map[string]projectClient.CronJob `json:"cronJobs,omitempty" yaml:"cronJobs,omitempty"` + Workloads map[string]projectClient.Workload `json:"workloads,omitempty" yaml:"workloads,omitempty"` + Apps map[string]projectClient.App `json:"apps,omitempty" yaml:"apps,omitempty"` + AppRevisions map[string]projectClient.AppRevision `json:"appRevisions,omitempty" yaml:"appRevisions,omitempty"` + HorizontalPodAutoscalers map[string]projectClient.HorizontalPodAutoscaler `json:"horizontalPodAutoscalers,omitempty" yaml:"horizontalPodAutoscalers,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/factory.go new file mode 100644 index 0000000..ec65d18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package catalog + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Catalog() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/interface.go new file mode 100644 index 0000000..dae509e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package catalog + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" +) + +type Interface interface { + V1() v1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1() v1.Interface { + return v1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/app.go new file mode 100644 index 0000000..7fab294 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/app.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// AppController interface for managing App resources. +type AppController interface { + generic.ControllerInterface[*v1.App, *v1.AppList] +} + +// AppClient interface for managing App resources in Kubernetes. +type AppClient interface { + generic.ClientInterface[*v1.App, *v1.AppList] +} + +// AppCache interface for retrieving App resources in memory. +type AppCache interface { + generic.CacheInterface[*v1.App] +} + +// AppStatusHandler is executed for every added or modified App. Should return the new status to be updated +type AppStatusHandler func(obj *v1.App, status v1.ReleaseStatus) (v1.ReleaseStatus, error) + +// AppGeneratingHandler is the top-level handler that is executed for every App event. It extends AppStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type AppGeneratingHandler func(obj *v1.App, status v1.ReleaseStatus) ([]runtime.Object, v1.ReleaseStatus, error) + +// RegisterAppStatusHandler configures a AppController to execute a AppStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppStatusHandler(ctx context.Context, controller AppController, condition condition.Cond, name string, handler AppStatusHandler) { + statusHandler := &appStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterAppGeneratingHandler configures a AppController to execute a AppGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppGeneratingHandler(ctx context.Context, controller AppController, apply apply.Apply, + condition condition.Cond, name string, handler AppGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &appGeneratingHandler{ + AppGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterAppStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type appStatusHandler struct { + client AppClient + condition condition.Cond + handler AppStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *appStatusHandler) sync(key string, obj *v1.App) (*v1.App, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type appGeneratingHandler struct { + AppGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *appGeneratingHandler) Remove(key string, obj *v1.App) (*v1.App, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.App{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured AppGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *appGeneratingHandler) Handle(obj *v1.App, status v1.ReleaseStatus) (v1.ReleaseStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.AppGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appGeneratingHandler) isNewResourceVersion(obj *v1.App) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appGeneratingHandler) storeResourceVersion(obj *v1.App) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/clusterrepo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/clusterrepo.go new file mode 100644 index 0000000..a4179b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/clusterrepo.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterRepoController interface for managing ClusterRepo resources. +type ClusterRepoController interface { + generic.NonNamespacedControllerInterface[*v1.ClusterRepo, *v1.ClusterRepoList] +} + +// ClusterRepoClient interface for managing ClusterRepo resources in Kubernetes. +type ClusterRepoClient interface { + generic.NonNamespacedClientInterface[*v1.ClusterRepo, *v1.ClusterRepoList] +} + +// ClusterRepoCache interface for retrieving ClusterRepo resources in memory. +type ClusterRepoCache interface { + generic.NonNamespacedCacheInterface[*v1.ClusterRepo] +} + +// ClusterRepoStatusHandler is executed for every added or modified ClusterRepo. Should return the new status to be updated +type ClusterRepoStatusHandler func(obj *v1.ClusterRepo, status v1.RepoStatus) (v1.RepoStatus, error) + +// ClusterRepoGeneratingHandler is the top-level handler that is executed for every ClusterRepo event. It extends ClusterRepoStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterRepoGeneratingHandler func(obj *v1.ClusterRepo, status v1.RepoStatus) ([]runtime.Object, v1.RepoStatus, error) + +// RegisterClusterRepoStatusHandler configures a ClusterRepoController to execute a ClusterRepoStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterRepoStatusHandler(ctx context.Context, controller ClusterRepoController, condition condition.Cond, name string, handler ClusterRepoStatusHandler) { + statusHandler := &clusterRepoStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterRepoGeneratingHandler configures a ClusterRepoController to execute a ClusterRepoGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterRepoGeneratingHandler(ctx context.Context, controller ClusterRepoController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterRepoGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterRepoGeneratingHandler{ + ClusterRepoGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterRepoStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterRepoStatusHandler struct { + client ClusterRepoClient + condition condition.Cond + handler ClusterRepoStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterRepoStatusHandler) sync(key string, obj *v1.ClusterRepo) (*v1.ClusterRepo, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterRepoGeneratingHandler struct { + ClusterRepoGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterRepoGeneratingHandler) Remove(key string, obj *v1.ClusterRepo) (*v1.ClusterRepo, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.ClusterRepo{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterRepoGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterRepoGeneratingHandler) Handle(obj *v1.ClusterRepo, status v1.RepoStatus) (v1.RepoStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterRepoGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterRepoGeneratingHandler) isNewResourceVersion(obj *v1.ClusterRepo) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterRepoGeneratingHandler) storeResourceVersion(obj *v1.ClusterRepo) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/interface.go new file mode 100644 index 0000000..9d31148 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/interface.go @@ -0,0 +1,64 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1.AddToScheme) +} + +type Interface interface { + App() AppController + ClusterRepo() ClusterRepoController + Operation() OperationController + UIPlugin() UIPluginController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) App() AppController { + return generic.NewController[*v1.App, *v1.AppList](schema.GroupVersionKind{Group: "catalog.cattle.io", Version: "v1", Kind: "App"}, "apps", true, v.controllerFactory) +} + +func (v *version) ClusterRepo() ClusterRepoController { + return generic.NewNonNamespacedController[*v1.ClusterRepo, *v1.ClusterRepoList](schema.GroupVersionKind{Group: "catalog.cattle.io", Version: "v1", Kind: "ClusterRepo"}, "clusterrepos", v.controllerFactory) +} + +func (v *version) Operation() OperationController { + return generic.NewController[*v1.Operation, *v1.OperationList](schema.GroupVersionKind{Group: "catalog.cattle.io", Version: "v1", Kind: "Operation"}, "operations", true, v.controllerFactory) +} + +func (v *version) UIPlugin() UIPluginController { + return generic.NewController[*v1.UIPlugin, *v1.UIPluginList](schema.GroupVersionKind{Group: "catalog.cattle.io", Version: "v1", Kind: "UIPlugin"}, "uiplugins", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/operation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/operation.go new file mode 100644 index 0000000..eafa5bc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/operation.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// OperationController interface for managing Operation resources. +type OperationController interface { + generic.ControllerInterface[*v1.Operation, *v1.OperationList] +} + +// OperationClient interface for managing Operation resources in Kubernetes. +type OperationClient interface { + generic.ClientInterface[*v1.Operation, *v1.OperationList] +} + +// OperationCache interface for retrieving Operation resources in memory. +type OperationCache interface { + generic.CacheInterface[*v1.Operation] +} + +// OperationStatusHandler is executed for every added or modified Operation. Should return the new status to be updated +type OperationStatusHandler func(obj *v1.Operation, status v1.OperationStatus) (v1.OperationStatus, error) + +// OperationGeneratingHandler is the top-level handler that is executed for every Operation event. It extends OperationStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type OperationGeneratingHandler func(obj *v1.Operation, status v1.OperationStatus) ([]runtime.Object, v1.OperationStatus, error) + +// RegisterOperationStatusHandler configures a OperationController to execute a OperationStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterOperationStatusHandler(ctx context.Context, controller OperationController, condition condition.Cond, name string, handler OperationStatusHandler) { + statusHandler := &operationStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterOperationGeneratingHandler configures a OperationController to execute a OperationGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterOperationGeneratingHandler(ctx context.Context, controller OperationController, apply apply.Apply, + condition condition.Cond, name string, handler OperationGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &operationGeneratingHandler{ + OperationGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterOperationStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type operationStatusHandler struct { + client OperationClient + condition condition.Cond + handler OperationStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *operationStatusHandler) sync(key string, obj *v1.Operation) (*v1.Operation, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type operationGeneratingHandler struct { + OperationGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *operationGeneratingHandler) Remove(key string, obj *v1.Operation) (*v1.Operation, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Operation{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured OperationGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *operationGeneratingHandler) Handle(obj *v1.Operation, status v1.OperationStatus) (v1.OperationStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.OperationGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *operationGeneratingHandler) isNewResourceVersion(obj *v1.Operation) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *operationGeneratingHandler) storeResourceVersion(obj *v1.Operation) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/uiplugin.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/uiplugin.go new file mode 100644 index 0000000..614d23f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/catalog.cattle.io/v1/uiplugin.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// UIPluginController interface for managing UIPlugin resources. +type UIPluginController interface { + generic.ControllerInterface[*v1.UIPlugin, *v1.UIPluginList] +} + +// UIPluginClient interface for managing UIPlugin resources in Kubernetes. +type UIPluginClient interface { + generic.ClientInterface[*v1.UIPlugin, *v1.UIPluginList] +} + +// UIPluginCache interface for retrieving UIPlugin resources in memory. +type UIPluginCache interface { + generic.CacheInterface[*v1.UIPlugin] +} + +// UIPluginStatusHandler is executed for every added or modified UIPlugin. Should return the new status to be updated +type UIPluginStatusHandler func(obj *v1.UIPlugin, status v1.UIPluginStatus) (v1.UIPluginStatus, error) + +// UIPluginGeneratingHandler is the top-level handler that is executed for every UIPlugin event. It extends UIPluginStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type UIPluginGeneratingHandler func(obj *v1.UIPlugin, status v1.UIPluginStatus) ([]runtime.Object, v1.UIPluginStatus, error) + +// RegisterUIPluginStatusHandler configures a UIPluginController to execute a UIPluginStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterUIPluginStatusHandler(ctx context.Context, controller UIPluginController, condition condition.Cond, name string, handler UIPluginStatusHandler) { + statusHandler := &uIPluginStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterUIPluginGeneratingHandler configures a UIPluginController to execute a UIPluginGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterUIPluginGeneratingHandler(ctx context.Context, controller UIPluginController, apply apply.Apply, + condition condition.Cond, name string, handler UIPluginGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &uIPluginGeneratingHandler{ + UIPluginGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterUIPluginStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type uIPluginStatusHandler struct { + client UIPluginClient + condition condition.Cond + handler UIPluginStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *uIPluginStatusHandler) sync(key string, obj *v1.UIPlugin) (*v1.UIPlugin, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type uIPluginGeneratingHandler struct { + UIPluginGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *uIPluginGeneratingHandler) Remove(key string, obj *v1.UIPlugin) (*v1.UIPlugin, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.UIPlugin{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured UIPluginGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *uIPluginGeneratingHandler) Handle(obj *v1.UIPlugin, status v1.UIPluginStatus) (v1.UIPluginStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.UIPluginGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *uIPluginGeneratingHandler) isNewResourceVersion(obj *v1.UIPlugin) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *uIPluginGeneratingHandler) storeResourceVersion(obj *v1.UIPlugin) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/factory.go new file mode 100644 index 0000000..7ec659b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package cluster + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Cluster() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/interface.go new file mode 100644 index 0000000..41ba43b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package cluster + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/generated/controllers/cluster.cattle.io/v3" +) + +type Interface interface { + V3() v3.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V3() v3.Interface { + return v3.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusterauthtoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusterauthtoken.go new file mode 100644 index 0000000..f393a02 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusterauthtoken.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterAuthTokenController interface for managing ClusterAuthToken resources. +type ClusterAuthTokenController interface { + generic.ControllerInterface[*v3.ClusterAuthToken, *v3.ClusterAuthTokenList] +} + +// ClusterAuthTokenClient interface for managing ClusterAuthToken resources in Kubernetes. +type ClusterAuthTokenClient interface { + generic.ClientInterface[*v3.ClusterAuthToken, *v3.ClusterAuthTokenList] +} + +// ClusterAuthTokenCache interface for retrieving ClusterAuthToken resources in memory. +type ClusterAuthTokenCache interface { + generic.CacheInterface[*v3.ClusterAuthToken] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusteruserattribute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusteruserattribute.go new file mode 100644 index 0000000..8ca0301 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/clusteruserattribute.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterUserAttributeController interface for managing ClusterUserAttribute resources. +type ClusterUserAttributeController interface { + generic.ControllerInterface[*v3.ClusterUserAttribute, *v3.ClusterUserAttributeList] +} + +// ClusterUserAttributeClient interface for managing ClusterUserAttribute resources in Kubernetes. +type ClusterUserAttributeClient interface { + generic.ClientInterface[*v3.ClusterUserAttribute, *v3.ClusterUserAttributeList] +} + +// ClusterUserAttributeCache interface for retrieving ClusterUserAttribute resources in memory. +type ClusterUserAttributeCache interface { + generic.CacheInterface[*v3.ClusterUserAttribute] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/interface.go new file mode 100644 index 0000000..add6e6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.cattle.io/v3/interface.go @@ -0,0 +1,54 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v3.AddToScheme) +} + +type Interface interface { + ClusterAuthToken() ClusterAuthTokenController + ClusterUserAttribute() ClusterUserAttributeController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) ClusterAuthToken() ClusterAuthTokenController { + return generic.NewController[*v3.ClusterAuthToken, *v3.ClusterAuthTokenList](schema.GroupVersionKind{Group: "cluster.cattle.io", Version: "v3", Kind: "ClusterAuthToken"}, "clusterauthtokens", true, v.controllerFactory) +} + +func (v *version) ClusterUserAttribute() ClusterUserAttributeController { + return generic.NewController[*v3.ClusterUserAttribute, *v3.ClusterUserAttributeList](schema.GroupVersionKind{Group: "cluster.cattle.io", Version: "v3", Kind: "ClusterUserAttribute"}, "clusteruserattributes", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/factory.go new file mode 100644 index 0000000..7ec659b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package cluster + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Cluster() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/interface.go new file mode 100644 index 0000000..c3f9422 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package cluster + +import ( + "github.com/rancher/lasso/pkg/controller" + v1beta1 "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" +) + +type Interface interface { + V1beta1() v1beta1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/cluster.go new file mode 100644 index 0000000..3a4c6f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/cluster.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "sync" + "time" + + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// ClusterController interface for managing Cluster resources. +type ClusterController interface { + generic.ControllerInterface[*v1beta1.Cluster, *v1beta1.ClusterList] +} + +// ClusterClient interface for managing Cluster resources in Kubernetes. +type ClusterClient interface { + generic.ClientInterface[*v1beta1.Cluster, *v1beta1.ClusterList] +} + +// ClusterCache interface for retrieving Cluster resources in memory. +type ClusterCache interface { + generic.CacheInterface[*v1beta1.Cluster] +} + +// ClusterStatusHandler is executed for every added or modified Cluster. Should return the new status to be updated +type ClusterStatusHandler func(obj *v1beta1.Cluster, status v1beta1.ClusterStatus) (v1beta1.ClusterStatus, error) + +// ClusterGeneratingHandler is the top-level handler that is executed for every Cluster event. It extends ClusterStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterGeneratingHandler func(obj *v1beta1.Cluster, status v1beta1.ClusterStatus) ([]runtime.Object, v1beta1.ClusterStatus, error) + +// RegisterClusterStatusHandler configures a ClusterController to execute a ClusterStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterStatusHandler(ctx context.Context, controller ClusterController, condition condition.Cond, name string, handler ClusterStatusHandler) { + statusHandler := &clusterStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterGeneratingHandler configures a ClusterController to execute a ClusterGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGeneratingHandler(ctx context.Context, controller ClusterController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterGeneratingHandler{ + ClusterGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterStatusHandler struct { + client ClusterClient + condition condition.Cond + handler ClusterStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterStatusHandler) sync(key string, obj *v1beta1.Cluster) (*v1beta1.Cluster, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterGeneratingHandler struct { + ClusterGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterGeneratingHandler) Remove(key string, obj *v1beta1.Cluster) (*v1beta1.Cluster, error) { + if obj != nil { + return obj, nil + } + + obj = &v1beta1.Cluster{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterGeneratingHandler) Handle(obj *v1beta1.Cluster, status v1beta1.ClusterStatus) (v1beta1.ClusterStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) isNewResourceVersion(obj *v1beta1.Cluster) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) storeResourceVersion(obj *v1beta1.Cluster) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/interface.go new file mode 100644 index 0000000..bf85fa3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/interface.go @@ -0,0 +1,69 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func init() { + schemes.Register(v1beta1.AddToScheme) +} + +type Interface interface { + Cluster() ClusterController + Machine() MachineController + MachineDeployment() MachineDeploymentController + MachineHealthCheck() MachineHealthCheckController + MachineSet() MachineSetController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) Cluster() ClusterController { + return generic.NewController[*v1beta1.Cluster, *v1beta1.ClusterList](schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "Cluster"}, "clusters", true, v.controllerFactory) +} + +func (v *version) Machine() MachineController { + return generic.NewController[*v1beta1.Machine, *v1beta1.MachineList](schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "Machine"}, "machines", true, v.controllerFactory) +} + +func (v *version) MachineDeployment() MachineDeploymentController { + return generic.NewController[*v1beta1.MachineDeployment, *v1beta1.MachineDeploymentList](schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "MachineDeployment"}, "machinedeployments", true, v.controllerFactory) +} + +func (v *version) MachineHealthCheck() MachineHealthCheckController { + return generic.NewController[*v1beta1.MachineHealthCheck, *v1beta1.MachineHealthCheckList](schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "MachineHealthCheck"}, "machinehealthchecks", true, v.controllerFactory) +} + +func (v *version) MachineSet() MachineSetController { + return generic.NewController[*v1beta1.MachineSet, *v1beta1.MachineSetList](schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "MachineSet"}, "machinesets", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machine.go new file mode 100644 index 0000000..4e020e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machine.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "sync" + "time" + + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// MachineController interface for managing Machine resources. +type MachineController interface { + generic.ControllerInterface[*v1beta1.Machine, *v1beta1.MachineList] +} + +// MachineClient interface for managing Machine resources in Kubernetes. +type MachineClient interface { + generic.ClientInterface[*v1beta1.Machine, *v1beta1.MachineList] +} + +// MachineCache interface for retrieving Machine resources in memory. +type MachineCache interface { + generic.CacheInterface[*v1beta1.Machine] +} + +// MachineStatusHandler is executed for every added or modified Machine. Should return the new status to be updated +type MachineStatusHandler func(obj *v1beta1.Machine, status v1beta1.MachineStatus) (v1beta1.MachineStatus, error) + +// MachineGeneratingHandler is the top-level handler that is executed for every Machine event. It extends MachineStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type MachineGeneratingHandler func(obj *v1beta1.Machine, status v1beta1.MachineStatus) ([]runtime.Object, v1beta1.MachineStatus, error) + +// RegisterMachineStatusHandler configures a MachineController to execute a MachineStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineStatusHandler(ctx context.Context, controller MachineController, condition condition.Cond, name string, handler MachineStatusHandler) { + statusHandler := &machineStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterMachineGeneratingHandler configures a MachineController to execute a MachineGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineGeneratingHandler(ctx context.Context, controller MachineController, apply apply.Apply, + condition condition.Cond, name string, handler MachineGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &machineGeneratingHandler{ + MachineGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterMachineStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type machineStatusHandler struct { + client MachineClient + condition condition.Cond + handler MachineStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *machineStatusHandler) sync(key string, obj *v1beta1.Machine) (*v1beta1.Machine, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type machineGeneratingHandler struct { + MachineGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *machineGeneratingHandler) Remove(key string, obj *v1beta1.Machine) (*v1beta1.Machine, error) { + if obj != nil { + return obj, nil + } + + obj = &v1beta1.Machine{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured MachineGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *machineGeneratingHandler) Handle(obj *v1beta1.Machine, status v1beta1.MachineStatus) (v1beta1.MachineStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.MachineGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineGeneratingHandler) isNewResourceVersion(obj *v1beta1.Machine) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineGeneratingHandler) storeResourceVersion(obj *v1beta1.Machine) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinedeployment.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinedeployment.go new file mode 100644 index 0000000..efdd492 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinedeployment.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "sync" + "time" + + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// MachineDeploymentController interface for managing MachineDeployment resources. +type MachineDeploymentController interface { + generic.ControllerInterface[*v1beta1.MachineDeployment, *v1beta1.MachineDeploymentList] +} + +// MachineDeploymentClient interface for managing MachineDeployment resources in Kubernetes. +type MachineDeploymentClient interface { + generic.ClientInterface[*v1beta1.MachineDeployment, *v1beta1.MachineDeploymentList] +} + +// MachineDeploymentCache interface for retrieving MachineDeployment resources in memory. +type MachineDeploymentCache interface { + generic.CacheInterface[*v1beta1.MachineDeployment] +} + +// MachineDeploymentStatusHandler is executed for every added or modified MachineDeployment. Should return the new status to be updated +type MachineDeploymentStatusHandler func(obj *v1beta1.MachineDeployment, status v1beta1.MachineDeploymentStatus) (v1beta1.MachineDeploymentStatus, error) + +// MachineDeploymentGeneratingHandler is the top-level handler that is executed for every MachineDeployment event. It extends MachineDeploymentStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type MachineDeploymentGeneratingHandler func(obj *v1beta1.MachineDeployment, status v1beta1.MachineDeploymentStatus) ([]runtime.Object, v1beta1.MachineDeploymentStatus, error) + +// RegisterMachineDeploymentStatusHandler configures a MachineDeploymentController to execute a MachineDeploymentStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineDeploymentStatusHandler(ctx context.Context, controller MachineDeploymentController, condition condition.Cond, name string, handler MachineDeploymentStatusHandler) { + statusHandler := &machineDeploymentStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterMachineDeploymentGeneratingHandler configures a MachineDeploymentController to execute a MachineDeploymentGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineDeploymentGeneratingHandler(ctx context.Context, controller MachineDeploymentController, apply apply.Apply, + condition condition.Cond, name string, handler MachineDeploymentGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &machineDeploymentGeneratingHandler{ + MachineDeploymentGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterMachineDeploymentStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type machineDeploymentStatusHandler struct { + client MachineDeploymentClient + condition condition.Cond + handler MachineDeploymentStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *machineDeploymentStatusHandler) sync(key string, obj *v1beta1.MachineDeployment) (*v1beta1.MachineDeployment, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type machineDeploymentGeneratingHandler struct { + MachineDeploymentGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *machineDeploymentGeneratingHandler) Remove(key string, obj *v1beta1.MachineDeployment) (*v1beta1.MachineDeployment, error) { + if obj != nil { + return obj, nil + } + + obj = &v1beta1.MachineDeployment{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured MachineDeploymentGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *machineDeploymentGeneratingHandler) Handle(obj *v1beta1.MachineDeployment, status v1beta1.MachineDeploymentStatus) (v1beta1.MachineDeploymentStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.MachineDeploymentGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineDeploymentGeneratingHandler) isNewResourceVersion(obj *v1beta1.MachineDeployment) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineDeploymentGeneratingHandler) storeResourceVersion(obj *v1beta1.MachineDeployment) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinehealthcheck.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinehealthcheck.go new file mode 100644 index 0000000..e728b0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machinehealthcheck.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "sync" + "time" + + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// MachineHealthCheckController interface for managing MachineHealthCheck resources. +type MachineHealthCheckController interface { + generic.ControllerInterface[*v1beta1.MachineHealthCheck, *v1beta1.MachineHealthCheckList] +} + +// MachineHealthCheckClient interface for managing MachineHealthCheck resources in Kubernetes. +type MachineHealthCheckClient interface { + generic.ClientInterface[*v1beta1.MachineHealthCheck, *v1beta1.MachineHealthCheckList] +} + +// MachineHealthCheckCache interface for retrieving MachineHealthCheck resources in memory. +type MachineHealthCheckCache interface { + generic.CacheInterface[*v1beta1.MachineHealthCheck] +} + +// MachineHealthCheckStatusHandler is executed for every added or modified MachineHealthCheck. Should return the new status to be updated +type MachineHealthCheckStatusHandler func(obj *v1beta1.MachineHealthCheck, status v1beta1.MachineHealthCheckStatus) (v1beta1.MachineHealthCheckStatus, error) + +// MachineHealthCheckGeneratingHandler is the top-level handler that is executed for every MachineHealthCheck event. It extends MachineHealthCheckStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type MachineHealthCheckGeneratingHandler func(obj *v1beta1.MachineHealthCheck, status v1beta1.MachineHealthCheckStatus) ([]runtime.Object, v1beta1.MachineHealthCheckStatus, error) + +// RegisterMachineHealthCheckStatusHandler configures a MachineHealthCheckController to execute a MachineHealthCheckStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineHealthCheckStatusHandler(ctx context.Context, controller MachineHealthCheckController, condition condition.Cond, name string, handler MachineHealthCheckStatusHandler) { + statusHandler := &machineHealthCheckStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterMachineHealthCheckGeneratingHandler configures a MachineHealthCheckController to execute a MachineHealthCheckGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineHealthCheckGeneratingHandler(ctx context.Context, controller MachineHealthCheckController, apply apply.Apply, + condition condition.Cond, name string, handler MachineHealthCheckGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &machineHealthCheckGeneratingHandler{ + MachineHealthCheckGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterMachineHealthCheckStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type machineHealthCheckStatusHandler struct { + client MachineHealthCheckClient + condition condition.Cond + handler MachineHealthCheckStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *machineHealthCheckStatusHandler) sync(key string, obj *v1beta1.MachineHealthCheck) (*v1beta1.MachineHealthCheck, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type machineHealthCheckGeneratingHandler struct { + MachineHealthCheckGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *machineHealthCheckGeneratingHandler) Remove(key string, obj *v1beta1.MachineHealthCheck) (*v1beta1.MachineHealthCheck, error) { + if obj != nil { + return obj, nil + } + + obj = &v1beta1.MachineHealthCheck{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured MachineHealthCheckGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *machineHealthCheckGeneratingHandler) Handle(obj *v1beta1.MachineHealthCheck, status v1beta1.MachineHealthCheckStatus) (v1beta1.MachineHealthCheckStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.MachineHealthCheckGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineHealthCheckGeneratingHandler) isNewResourceVersion(obj *v1beta1.MachineHealthCheck) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineHealthCheckGeneratingHandler) storeResourceVersion(obj *v1beta1.MachineHealthCheck) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machineset.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machineset.go new file mode 100644 index 0000000..dec1d99 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/cluster.x-k8s.io/v1beta1/machineset.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "sync" + "time" + + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// MachineSetController interface for managing MachineSet resources. +type MachineSetController interface { + generic.ControllerInterface[*v1beta1.MachineSet, *v1beta1.MachineSetList] +} + +// MachineSetClient interface for managing MachineSet resources in Kubernetes. +type MachineSetClient interface { + generic.ClientInterface[*v1beta1.MachineSet, *v1beta1.MachineSetList] +} + +// MachineSetCache interface for retrieving MachineSet resources in memory. +type MachineSetCache interface { + generic.CacheInterface[*v1beta1.MachineSet] +} + +// MachineSetStatusHandler is executed for every added or modified MachineSet. Should return the new status to be updated +type MachineSetStatusHandler func(obj *v1beta1.MachineSet, status v1beta1.MachineSetStatus) (v1beta1.MachineSetStatus, error) + +// MachineSetGeneratingHandler is the top-level handler that is executed for every MachineSet event. It extends MachineSetStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type MachineSetGeneratingHandler func(obj *v1beta1.MachineSet, status v1beta1.MachineSetStatus) ([]runtime.Object, v1beta1.MachineSetStatus, error) + +// RegisterMachineSetStatusHandler configures a MachineSetController to execute a MachineSetStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineSetStatusHandler(ctx context.Context, controller MachineSetController, condition condition.Cond, name string, handler MachineSetStatusHandler) { + statusHandler := &machineSetStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterMachineSetGeneratingHandler configures a MachineSetController to execute a MachineSetGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMachineSetGeneratingHandler(ctx context.Context, controller MachineSetController, apply apply.Apply, + condition condition.Cond, name string, handler MachineSetGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &machineSetGeneratingHandler{ + MachineSetGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterMachineSetStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type machineSetStatusHandler struct { + client MachineSetClient + condition condition.Cond + handler MachineSetStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *machineSetStatusHandler) sync(key string, obj *v1beta1.MachineSet) (*v1beta1.MachineSet, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type machineSetGeneratingHandler struct { + MachineSetGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *machineSetGeneratingHandler) Remove(key string, obj *v1beta1.MachineSet) (*v1beta1.MachineSet, error) { + if obj != nil { + return obj, nil + } + + obj = &v1beta1.MachineSet{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured MachineSetGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *machineSetGeneratingHandler) Handle(obj *v1beta1.MachineSet, status v1beta1.MachineSetStatus) (v1beta1.MachineSetStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.MachineSetGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineSetGeneratingHandler) isNewResourceVersion(obj *v1beta1.MachineSet) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *machineSetGeneratingHandler) storeResourceVersion(obj *v1beta1.MachineSet) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/factory.go new file mode 100644 index 0000000..73613aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fleet + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Fleet() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/interface.go new file mode 100644 index 0000000..23e81c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package fleet + +import ( + "github.com/rancher/lasso/pkg/controller" + v1alpha1 "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" +) + +type Interface interface { + V1alpha1() v1alpha1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/bundle.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/bundle.go new file mode 100644 index 0000000..afcab67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/bundle.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "sync" + "time" + + v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// BundleController interface for managing Bundle resources. +type BundleController interface { + generic.ControllerInterface[*v1alpha1.Bundle, *v1alpha1.BundleList] +} + +// BundleClient interface for managing Bundle resources in Kubernetes. +type BundleClient interface { + generic.ClientInterface[*v1alpha1.Bundle, *v1alpha1.BundleList] +} + +// BundleCache interface for retrieving Bundle resources in memory. +type BundleCache interface { + generic.CacheInterface[*v1alpha1.Bundle] +} + +// BundleStatusHandler is executed for every added or modified Bundle. Should return the new status to be updated +type BundleStatusHandler func(obj *v1alpha1.Bundle, status v1alpha1.BundleStatus) (v1alpha1.BundleStatus, error) + +// BundleGeneratingHandler is the top-level handler that is executed for every Bundle event. It extends BundleStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type BundleGeneratingHandler func(obj *v1alpha1.Bundle, status v1alpha1.BundleStatus) ([]runtime.Object, v1alpha1.BundleStatus, error) + +// RegisterBundleStatusHandler configures a BundleController to execute a BundleStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterBundleStatusHandler(ctx context.Context, controller BundleController, condition condition.Cond, name string, handler BundleStatusHandler) { + statusHandler := &bundleStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterBundleGeneratingHandler configures a BundleController to execute a BundleGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterBundleGeneratingHandler(ctx context.Context, controller BundleController, apply apply.Apply, + condition condition.Cond, name string, handler BundleGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &bundleGeneratingHandler{ + BundleGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterBundleStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type bundleStatusHandler struct { + client BundleClient + condition condition.Cond + handler BundleStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *bundleStatusHandler) sync(key string, obj *v1alpha1.Bundle) (*v1alpha1.Bundle, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type bundleGeneratingHandler struct { + BundleGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *bundleGeneratingHandler) Remove(key string, obj *v1alpha1.Bundle) (*v1alpha1.Bundle, error) { + if obj != nil { + return obj, nil + } + + obj = &v1alpha1.Bundle{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured BundleGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *bundleGeneratingHandler) Handle(obj *v1alpha1.Bundle, status v1alpha1.BundleStatus) (v1alpha1.BundleStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.BundleGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *bundleGeneratingHandler) isNewResourceVersion(obj *v1alpha1.Bundle) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *bundleGeneratingHandler) storeResourceVersion(obj *v1alpha1.Bundle) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/cluster.go new file mode 100644 index 0000000..0678df4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/cluster.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "sync" + "time" + + v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterController interface for managing Cluster resources. +type ClusterController interface { + generic.ControllerInterface[*v1alpha1.Cluster, *v1alpha1.ClusterList] +} + +// ClusterClient interface for managing Cluster resources in Kubernetes. +type ClusterClient interface { + generic.ClientInterface[*v1alpha1.Cluster, *v1alpha1.ClusterList] +} + +// ClusterCache interface for retrieving Cluster resources in memory. +type ClusterCache interface { + generic.CacheInterface[*v1alpha1.Cluster] +} + +// ClusterStatusHandler is executed for every added or modified Cluster. Should return the new status to be updated +type ClusterStatusHandler func(obj *v1alpha1.Cluster, status v1alpha1.ClusterStatus) (v1alpha1.ClusterStatus, error) + +// ClusterGeneratingHandler is the top-level handler that is executed for every Cluster event. It extends ClusterStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterGeneratingHandler func(obj *v1alpha1.Cluster, status v1alpha1.ClusterStatus) ([]runtime.Object, v1alpha1.ClusterStatus, error) + +// RegisterClusterStatusHandler configures a ClusterController to execute a ClusterStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterStatusHandler(ctx context.Context, controller ClusterController, condition condition.Cond, name string, handler ClusterStatusHandler) { + statusHandler := &clusterStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterGeneratingHandler configures a ClusterController to execute a ClusterGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGeneratingHandler(ctx context.Context, controller ClusterController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterGeneratingHandler{ + ClusterGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterStatusHandler struct { + client ClusterClient + condition condition.Cond + handler ClusterStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterStatusHandler) sync(key string, obj *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterGeneratingHandler struct { + ClusterGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterGeneratingHandler) Remove(key string, obj *v1alpha1.Cluster) (*v1alpha1.Cluster, error) { + if obj != nil { + return obj, nil + } + + obj = &v1alpha1.Cluster{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterGeneratingHandler) Handle(obj *v1alpha1.Cluster, status v1alpha1.ClusterStatus) (v1alpha1.ClusterStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) isNewResourceVersion(obj *v1alpha1.Cluster) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) storeResourceVersion(obj *v1alpha1.Cluster) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/clustergroup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/clustergroup.go new file mode 100644 index 0000000..76b7a26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/clustergroup.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "sync" + "time" + + v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterGroupController interface for managing ClusterGroup resources. +type ClusterGroupController interface { + generic.ControllerInterface[*v1alpha1.ClusterGroup, *v1alpha1.ClusterGroupList] +} + +// ClusterGroupClient interface for managing ClusterGroup resources in Kubernetes. +type ClusterGroupClient interface { + generic.ClientInterface[*v1alpha1.ClusterGroup, *v1alpha1.ClusterGroupList] +} + +// ClusterGroupCache interface for retrieving ClusterGroup resources in memory. +type ClusterGroupCache interface { + generic.CacheInterface[*v1alpha1.ClusterGroup] +} + +// ClusterGroupStatusHandler is executed for every added or modified ClusterGroup. Should return the new status to be updated +type ClusterGroupStatusHandler func(obj *v1alpha1.ClusterGroup, status v1alpha1.ClusterGroupStatus) (v1alpha1.ClusterGroupStatus, error) + +// ClusterGroupGeneratingHandler is the top-level handler that is executed for every ClusterGroup event. It extends ClusterGroupStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterGroupGeneratingHandler func(obj *v1alpha1.ClusterGroup, status v1alpha1.ClusterGroupStatus) ([]runtime.Object, v1alpha1.ClusterGroupStatus, error) + +// RegisterClusterGroupStatusHandler configures a ClusterGroupController to execute a ClusterGroupStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGroupStatusHandler(ctx context.Context, controller ClusterGroupController, condition condition.Cond, name string, handler ClusterGroupStatusHandler) { + statusHandler := &clusterGroupStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterGroupGeneratingHandler configures a ClusterGroupController to execute a ClusterGroupGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGroupGeneratingHandler(ctx context.Context, controller ClusterGroupController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterGroupGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterGroupGeneratingHandler{ + ClusterGroupGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterGroupStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterGroupStatusHandler struct { + client ClusterGroupClient + condition condition.Cond + handler ClusterGroupStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterGroupStatusHandler) sync(key string, obj *v1alpha1.ClusterGroup) (*v1alpha1.ClusterGroup, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterGroupGeneratingHandler struct { + ClusterGroupGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterGroupGeneratingHandler) Remove(key string, obj *v1alpha1.ClusterGroup) (*v1alpha1.ClusterGroup, error) { + if obj != nil { + return obj, nil + } + + obj = &v1alpha1.ClusterGroup{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterGroupGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterGroupGeneratingHandler) Handle(obj *v1alpha1.ClusterGroup, status v1alpha1.ClusterGroupStatus) (v1alpha1.ClusterGroupStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterGroupGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGroupGeneratingHandler) isNewResourceVersion(obj *v1alpha1.ClusterGroup) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGroupGeneratingHandler) storeResourceVersion(obj *v1alpha1.ClusterGroup) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/interface.go new file mode 100644 index 0000000..0394414 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/fleet.cattle.io/v1alpha1/interface.go @@ -0,0 +1,59 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1alpha1.AddToScheme) +} + +type Interface interface { + Bundle() BundleController + Cluster() ClusterController + ClusterGroup() ClusterGroupController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) Bundle() BundleController { + return generic.NewController[*v1alpha1.Bundle, *v1alpha1.BundleList](schema.GroupVersionKind{Group: "fleet.cattle.io", Version: "v1alpha1", Kind: "Bundle"}, "bundles", true, v.controllerFactory) +} + +func (v *version) Cluster() ClusterController { + return generic.NewController[*v1alpha1.Cluster, *v1alpha1.ClusterList](schema.GroupVersionKind{Group: "fleet.cattle.io", Version: "v1alpha1", Kind: "Cluster"}, "clusters", true, v.controllerFactory) +} + +func (v *version) ClusterGroup() ClusterGroupController { + return generic.NewController[*v1alpha1.ClusterGroup, *v1alpha1.ClusterGroupList](schema.GroupVersionKind{Group: "fleet.cattle.io", Version: "v1alpha1", Kind: "ClusterGroup"}, "clustergroups", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/factory.go new file mode 100644 index 0000000..0646367 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package management + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Management() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/interface.go new file mode 100644 index 0000000..e85f595 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package management + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" +) + +type Interface interface { + V3() v3.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V3() v3.Interface { + return v3.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/activedirectoryprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/activedirectoryprovider.go new file mode 100644 index 0000000..03712ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/activedirectoryprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ActiveDirectoryProviderController interface for managing ActiveDirectoryProvider resources. +type ActiveDirectoryProviderController interface { + generic.NonNamespacedControllerInterface[*v3.ActiveDirectoryProvider, *v3.ActiveDirectoryProviderList] +} + +// ActiveDirectoryProviderClient interface for managing ActiveDirectoryProvider resources in Kubernetes. +type ActiveDirectoryProviderClient interface { + generic.NonNamespacedClientInterface[*v3.ActiveDirectoryProvider, *v3.ActiveDirectoryProviderList] +} + +// ActiveDirectoryProviderCache interface for retrieving ActiveDirectoryProvider resources in memory. +type ActiveDirectoryProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.ActiveDirectoryProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/apiservice.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/apiservice.go new file mode 100644 index 0000000..6560e3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/apiservice.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// APIServiceController interface for managing APIService resources. +type APIServiceController interface { + generic.NonNamespacedControllerInterface[*v3.APIService, *v3.APIServiceList] +} + +// APIServiceClient interface for managing APIService resources in Kubernetes. +type APIServiceClient interface { + generic.NonNamespacedClientInterface[*v3.APIService, *v3.APIServiceList] +} + +// APIServiceCache interface for retrieving APIService resources in memory. +type APIServiceCache interface { + generic.NonNamespacedCacheInterface[*v3.APIService] +} + +// APIServiceStatusHandler is executed for every added or modified APIService. Should return the new status to be updated +type APIServiceStatusHandler func(obj *v3.APIService, status v3.APIServiceStatus) (v3.APIServiceStatus, error) + +// APIServiceGeneratingHandler is the top-level handler that is executed for every APIService event. It extends APIServiceStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type APIServiceGeneratingHandler func(obj *v3.APIService, status v3.APIServiceStatus) ([]runtime.Object, v3.APIServiceStatus, error) + +// RegisterAPIServiceStatusHandler configures a APIServiceController to execute a APIServiceStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAPIServiceStatusHandler(ctx context.Context, controller APIServiceController, condition condition.Cond, name string, handler APIServiceStatusHandler) { + statusHandler := &aPIServiceStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterAPIServiceGeneratingHandler configures a APIServiceController to execute a APIServiceGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAPIServiceGeneratingHandler(ctx context.Context, controller APIServiceController, apply apply.Apply, + condition condition.Cond, name string, handler APIServiceGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &aPIServiceGeneratingHandler{ + APIServiceGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterAPIServiceStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type aPIServiceStatusHandler struct { + client APIServiceClient + condition condition.Cond + handler APIServiceStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *aPIServiceStatusHandler) sync(key string, obj *v3.APIService) (*v3.APIService, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type aPIServiceGeneratingHandler struct { + APIServiceGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *aPIServiceGeneratingHandler) Remove(key string, obj *v3.APIService) (*v3.APIService, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.APIService{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured APIServiceGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *aPIServiceGeneratingHandler) Handle(obj *v3.APIService, status v3.APIServiceStatus) (v3.APIServiceStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.APIServiceGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *aPIServiceGeneratingHandler) isNewResourceVersion(obj *v3.APIService) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *aPIServiceGeneratingHandler) storeResourceVersion(obj *v3.APIService) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authconfig.go new file mode 100644 index 0000000..1e5ac70 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authconfig.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// AuthConfigController interface for managing AuthConfig resources. +type AuthConfigController interface { + generic.NonNamespacedControllerInterface[*v3.AuthConfig, *v3.AuthConfigList] +} + +// AuthConfigClient interface for managing AuthConfig resources in Kubernetes. +type AuthConfigClient interface { + generic.NonNamespacedClientInterface[*v3.AuthConfig, *v3.AuthConfigList] +} + +// AuthConfigCache interface for retrieving AuthConfig resources in memory. +type AuthConfigCache interface { + generic.NonNamespacedCacheInterface[*v3.AuthConfig] +} + +// AuthConfigStatusHandler is executed for every added or modified AuthConfig. Should return the new status to be updated +type AuthConfigStatusHandler func(obj *v3.AuthConfig, status v3.AuthConfigStatus) (v3.AuthConfigStatus, error) + +// AuthConfigGeneratingHandler is the top-level handler that is executed for every AuthConfig event. It extends AuthConfigStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type AuthConfigGeneratingHandler func(obj *v3.AuthConfig, status v3.AuthConfigStatus) ([]runtime.Object, v3.AuthConfigStatus, error) + +// RegisterAuthConfigStatusHandler configures a AuthConfigController to execute a AuthConfigStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAuthConfigStatusHandler(ctx context.Context, controller AuthConfigController, condition condition.Cond, name string, handler AuthConfigStatusHandler) { + statusHandler := &authConfigStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterAuthConfigGeneratingHandler configures a AuthConfigController to execute a AuthConfigGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAuthConfigGeneratingHandler(ctx context.Context, controller AuthConfigController, apply apply.Apply, + condition condition.Cond, name string, handler AuthConfigGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &authConfigGeneratingHandler{ + AuthConfigGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterAuthConfigStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type authConfigStatusHandler struct { + client AuthConfigClient + condition condition.Cond + handler AuthConfigStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *authConfigStatusHandler) sync(key string, obj *v3.AuthConfig) (*v3.AuthConfig, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type authConfigGeneratingHandler struct { + AuthConfigGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *authConfigGeneratingHandler) Remove(key string, obj *v3.AuthConfig) (*v3.AuthConfig, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.AuthConfig{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured AuthConfigGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *authConfigGeneratingHandler) Handle(obj *v3.AuthConfig, status v3.AuthConfigStatus) (v3.AuthConfigStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.AuthConfigGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *authConfigGeneratingHandler) isNewResourceVersion(obj *v3.AuthConfig) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *authConfigGeneratingHandler) storeResourceVersion(obj *v3.AuthConfig) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authprovider.go new file mode 100644 index 0000000..f7ebc34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// AuthProviderController interface for managing AuthProvider resources. +type AuthProviderController interface { + generic.NonNamespacedControllerInterface[*v3.AuthProvider, *v3.AuthProviderList] +} + +// AuthProviderClient interface for managing AuthProvider resources in Kubernetes. +type AuthProviderClient interface { + generic.NonNamespacedClientInterface[*v3.AuthProvider, *v3.AuthProviderList] +} + +// AuthProviderCache interface for retrieving AuthProvider resources in memory. +type AuthProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.AuthProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authtoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authtoken.go new file mode 100644 index 0000000..d827e34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/authtoken.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// AuthTokenController interface for managing AuthToken resources. +type AuthTokenController interface { + generic.NonNamespacedControllerInterface[*v3.AuthToken, *v3.AuthTokenList] +} + +// AuthTokenClient interface for managing AuthToken resources in Kubernetes. +type AuthTokenClient interface { + generic.NonNamespacedClientInterface[*v3.AuthToken, *v3.AuthTokenList] +} + +// AuthTokenCache interface for retrieving AuthToken resources in memory. +type AuthTokenCache interface { + generic.NonNamespacedCacheInterface[*v3.AuthToken] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/azureadprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/azureadprovider.go new file mode 100644 index 0000000..9be6a2f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/azureadprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// AzureADProviderController interface for managing AzureADProvider resources. +type AzureADProviderController interface { + generic.NonNamespacedControllerInterface[*v3.AzureADProvider, *v3.AzureADProviderList] +} + +// AzureADProviderClient interface for managing AzureADProvider resources in Kubernetes. +type AzureADProviderClient interface { + generic.NonNamespacedClientInterface[*v3.AzureADProvider, *v3.AzureADProviderList] +} + +// AzureADProviderCache interface for retrieving AzureADProvider resources in memory. +type AzureADProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.AzureADProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalog.go new file mode 100644 index 0000000..ed56cdb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalog.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// CatalogController interface for managing Catalog resources. +type CatalogController interface { + generic.NonNamespacedControllerInterface[*v3.Catalog, *v3.CatalogList] +} + +// CatalogClient interface for managing Catalog resources in Kubernetes. +type CatalogClient interface { + generic.NonNamespacedClientInterface[*v3.Catalog, *v3.CatalogList] +} + +// CatalogCache interface for retrieving Catalog resources in memory. +type CatalogCache interface { + generic.NonNamespacedCacheInterface[*v3.Catalog] +} + +// CatalogStatusHandler is executed for every added or modified Catalog. Should return the new status to be updated +type CatalogStatusHandler func(obj *v3.Catalog, status v3.CatalogStatus) (v3.CatalogStatus, error) + +// CatalogGeneratingHandler is the top-level handler that is executed for every Catalog event. It extends CatalogStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type CatalogGeneratingHandler func(obj *v3.Catalog, status v3.CatalogStatus) ([]runtime.Object, v3.CatalogStatus, error) + +// RegisterCatalogStatusHandler configures a CatalogController to execute a CatalogStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogStatusHandler(ctx context.Context, controller CatalogController, condition condition.Cond, name string, handler CatalogStatusHandler) { + statusHandler := &catalogStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterCatalogGeneratingHandler configures a CatalogController to execute a CatalogGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogGeneratingHandler(ctx context.Context, controller CatalogController, apply apply.Apply, + condition condition.Cond, name string, handler CatalogGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &catalogGeneratingHandler{ + CatalogGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterCatalogStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type catalogStatusHandler struct { + client CatalogClient + condition condition.Cond + handler CatalogStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *catalogStatusHandler) sync(key string, obj *v3.Catalog) (*v3.Catalog, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type catalogGeneratingHandler struct { + CatalogGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *catalogGeneratingHandler) Remove(key string, obj *v3.Catalog) (*v3.Catalog, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Catalog{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured CatalogGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *catalogGeneratingHandler) Handle(obj *v3.Catalog, status v3.CatalogStatus) (v3.CatalogStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.CatalogGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogGeneratingHandler) isNewResourceVersion(obj *v3.Catalog) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogGeneratingHandler) storeResourceVersion(obj *v3.Catalog) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplate.go new file mode 100644 index 0000000..fda1780 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplate.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// CatalogTemplateController interface for managing CatalogTemplate resources. +type CatalogTemplateController interface { + generic.ControllerInterface[*v3.CatalogTemplate, *v3.CatalogTemplateList] +} + +// CatalogTemplateClient interface for managing CatalogTemplate resources in Kubernetes. +type CatalogTemplateClient interface { + generic.ClientInterface[*v3.CatalogTemplate, *v3.CatalogTemplateList] +} + +// CatalogTemplateCache interface for retrieving CatalogTemplate resources in memory. +type CatalogTemplateCache interface { + generic.CacheInterface[*v3.CatalogTemplate] +} + +// CatalogTemplateStatusHandler is executed for every added or modified CatalogTemplate. Should return the new status to be updated +type CatalogTemplateStatusHandler func(obj *v3.CatalogTemplate, status v3.TemplateStatus) (v3.TemplateStatus, error) + +// CatalogTemplateGeneratingHandler is the top-level handler that is executed for every CatalogTemplate event. It extends CatalogTemplateStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type CatalogTemplateGeneratingHandler func(obj *v3.CatalogTemplate, status v3.TemplateStatus) ([]runtime.Object, v3.TemplateStatus, error) + +// RegisterCatalogTemplateStatusHandler configures a CatalogTemplateController to execute a CatalogTemplateStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogTemplateStatusHandler(ctx context.Context, controller CatalogTemplateController, condition condition.Cond, name string, handler CatalogTemplateStatusHandler) { + statusHandler := &catalogTemplateStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterCatalogTemplateGeneratingHandler configures a CatalogTemplateController to execute a CatalogTemplateGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogTemplateGeneratingHandler(ctx context.Context, controller CatalogTemplateController, apply apply.Apply, + condition condition.Cond, name string, handler CatalogTemplateGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &catalogTemplateGeneratingHandler{ + CatalogTemplateGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterCatalogTemplateStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type catalogTemplateStatusHandler struct { + client CatalogTemplateClient + condition condition.Cond + handler CatalogTemplateStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *catalogTemplateStatusHandler) sync(key string, obj *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type catalogTemplateGeneratingHandler struct { + CatalogTemplateGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *catalogTemplateGeneratingHandler) Remove(key string, obj *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.CatalogTemplate{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured CatalogTemplateGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *catalogTemplateGeneratingHandler) Handle(obj *v3.CatalogTemplate, status v3.TemplateStatus) (v3.TemplateStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.CatalogTemplateGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogTemplateGeneratingHandler) isNewResourceVersion(obj *v3.CatalogTemplate) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogTemplateGeneratingHandler) storeResourceVersion(obj *v3.CatalogTemplate) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplateversion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplateversion.go new file mode 100644 index 0000000..f517c0c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/catalogtemplateversion.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// CatalogTemplateVersionController interface for managing CatalogTemplateVersion resources. +type CatalogTemplateVersionController interface { + generic.ControllerInterface[*v3.CatalogTemplateVersion, *v3.CatalogTemplateVersionList] +} + +// CatalogTemplateVersionClient interface for managing CatalogTemplateVersion resources in Kubernetes. +type CatalogTemplateVersionClient interface { + generic.ClientInterface[*v3.CatalogTemplateVersion, *v3.CatalogTemplateVersionList] +} + +// CatalogTemplateVersionCache interface for retrieving CatalogTemplateVersion resources in memory. +type CatalogTemplateVersionCache interface { + generic.CacheInterface[*v3.CatalogTemplateVersion] +} + +// CatalogTemplateVersionStatusHandler is executed for every added or modified CatalogTemplateVersion. Should return the new status to be updated +type CatalogTemplateVersionStatusHandler func(obj *v3.CatalogTemplateVersion, status v3.TemplateVersionStatus) (v3.TemplateVersionStatus, error) + +// CatalogTemplateVersionGeneratingHandler is the top-level handler that is executed for every CatalogTemplateVersion event. It extends CatalogTemplateVersionStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type CatalogTemplateVersionGeneratingHandler func(obj *v3.CatalogTemplateVersion, status v3.TemplateVersionStatus) ([]runtime.Object, v3.TemplateVersionStatus, error) + +// RegisterCatalogTemplateVersionStatusHandler configures a CatalogTemplateVersionController to execute a CatalogTemplateVersionStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogTemplateVersionStatusHandler(ctx context.Context, controller CatalogTemplateVersionController, condition condition.Cond, name string, handler CatalogTemplateVersionStatusHandler) { + statusHandler := &catalogTemplateVersionStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterCatalogTemplateVersionGeneratingHandler configures a CatalogTemplateVersionController to execute a CatalogTemplateVersionGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCatalogTemplateVersionGeneratingHandler(ctx context.Context, controller CatalogTemplateVersionController, apply apply.Apply, + condition condition.Cond, name string, handler CatalogTemplateVersionGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &catalogTemplateVersionGeneratingHandler{ + CatalogTemplateVersionGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterCatalogTemplateVersionStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type catalogTemplateVersionStatusHandler struct { + client CatalogTemplateVersionClient + condition condition.Cond + handler CatalogTemplateVersionStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *catalogTemplateVersionStatusHandler) sync(key string, obj *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type catalogTemplateVersionGeneratingHandler struct { + CatalogTemplateVersionGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *catalogTemplateVersionGeneratingHandler) Remove(key string, obj *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.CatalogTemplateVersion{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured CatalogTemplateVersionGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *catalogTemplateVersionGeneratingHandler) Handle(obj *v3.CatalogTemplateVersion, status v3.TemplateVersionStatus) (v3.TemplateVersionStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.CatalogTemplateVersionGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogTemplateVersionGeneratingHandler) isNewResourceVersion(obj *v3.CatalogTemplateVersion) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *catalogTemplateVersionGeneratingHandler) storeResourceVersion(obj *v3.CatalogTemplateVersion) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cloudcredential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cloudcredential.go new file mode 100644 index 0000000..c53948b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cloudcredential.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// CloudCredentialController interface for managing CloudCredential resources. +type CloudCredentialController interface { + generic.ControllerInterface[*v3.CloudCredential, *v3.CloudCredentialList] +} + +// CloudCredentialClient interface for managing CloudCredential resources in Kubernetes. +type CloudCredentialClient interface { + generic.ClientInterface[*v3.CloudCredential, *v3.CloudCredentialList] +} + +// CloudCredentialCache interface for retrieving CloudCredential resources in memory. +type CloudCredentialCache interface { + generic.CacheInterface[*v3.CloudCredential] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cluster.go new file mode 100644 index 0000000..e513b6c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/cluster.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterController interface for managing Cluster resources. +type ClusterController interface { + generic.NonNamespacedControllerInterface[*v3.Cluster, *v3.ClusterList] +} + +// ClusterClient interface for managing Cluster resources in Kubernetes. +type ClusterClient interface { + generic.NonNamespacedClientInterface[*v3.Cluster, *v3.ClusterList] +} + +// ClusterCache interface for retrieving Cluster resources in memory. +type ClusterCache interface { + generic.NonNamespacedCacheInterface[*v3.Cluster] +} + +// ClusterStatusHandler is executed for every added or modified Cluster. Should return the new status to be updated +type ClusterStatusHandler func(obj *v3.Cluster, status v3.ClusterStatus) (v3.ClusterStatus, error) + +// ClusterGeneratingHandler is the top-level handler that is executed for every Cluster event. It extends ClusterStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterGeneratingHandler func(obj *v3.Cluster, status v3.ClusterStatus) ([]runtime.Object, v3.ClusterStatus, error) + +// RegisterClusterStatusHandler configures a ClusterController to execute a ClusterStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterStatusHandler(ctx context.Context, controller ClusterController, condition condition.Cond, name string, handler ClusterStatusHandler) { + statusHandler := &clusterStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterGeneratingHandler configures a ClusterController to execute a ClusterGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGeneratingHandler(ctx context.Context, controller ClusterController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterGeneratingHandler{ + ClusterGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterStatusHandler struct { + client ClusterClient + condition condition.Cond + handler ClusterStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterStatusHandler) sync(key string, obj *v3.Cluster) (*v3.Cluster, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterGeneratingHandler struct { + ClusterGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterGeneratingHandler) Remove(key string, obj *v3.Cluster) (*v3.Cluster, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Cluster{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterGeneratingHandler) Handle(obj *v3.Cluster, status v3.ClusterStatus) (v3.ClusterStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) isNewResourceVersion(obj *v3.Cluster) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) storeResourceVersion(obj *v3.Cluster) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustercatalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustercatalog.go new file mode 100644 index 0000000..8411404 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustercatalog.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterCatalogController interface for managing ClusterCatalog resources. +type ClusterCatalogController interface { + generic.ControllerInterface[*v3.ClusterCatalog, *v3.ClusterCatalogList] +} + +// ClusterCatalogClient interface for managing ClusterCatalog resources in Kubernetes. +type ClusterCatalogClient interface { + generic.ClientInterface[*v3.ClusterCatalog, *v3.ClusterCatalogList] +} + +// ClusterCatalogCache interface for retrieving ClusterCatalog resources in memory. +type ClusterCatalogCache interface { + generic.CacheInterface[*v3.ClusterCatalog] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterlogging.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterlogging.go new file mode 100644 index 0000000..2d7e84f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterlogging.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterLoggingController interface for managing ClusterLogging resources. +type ClusterLoggingController interface { + generic.ControllerInterface[*v3.ClusterLogging, *v3.ClusterLoggingList] +} + +// ClusterLoggingClient interface for managing ClusterLogging resources in Kubernetes. +type ClusterLoggingClient interface { + generic.ClientInterface[*v3.ClusterLogging, *v3.ClusterLoggingList] +} + +// ClusterLoggingCache interface for retrieving ClusterLogging resources in memory. +type ClusterLoggingCache interface { + generic.CacheInterface[*v3.ClusterLogging] +} + +// ClusterLoggingStatusHandler is executed for every added or modified ClusterLogging. Should return the new status to be updated +type ClusterLoggingStatusHandler func(obj *v3.ClusterLogging, status v3.ClusterLoggingStatus) (v3.ClusterLoggingStatus, error) + +// ClusterLoggingGeneratingHandler is the top-level handler that is executed for every ClusterLogging event. It extends ClusterLoggingStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterLoggingGeneratingHandler func(obj *v3.ClusterLogging, status v3.ClusterLoggingStatus) ([]runtime.Object, v3.ClusterLoggingStatus, error) + +// RegisterClusterLoggingStatusHandler configures a ClusterLoggingController to execute a ClusterLoggingStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterLoggingStatusHandler(ctx context.Context, controller ClusterLoggingController, condition condition.Cond, name string, handler ClusterLoggingStatusHandler) { + statusHandler := &clusterLoggingStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterLoggingGeneratingHandler configures a ClusterLoggingController to execute a ClusterLoggingGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterLoggingGeneratingHandler(ctx context.Context, controller ClusterLoggingController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterLoggingGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterLoggingGeneratingHandler{ + ClusterLoggingGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterLoggingStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterLoggingStatusHandler struct { + client ClusterLoggingClient + condition condition.Cond + handler ClusterLoggingStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterLoggingStatusHandler) sync(key string, obj *v3.ClusterLogging) (*v3.ClusterLogging, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterLoggingGeneratingHandler struct { + ClusterLoggingGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterLoggingGeneratingHandler) Remove(key string, obj *v3.ClusterLogging) (*v3.ClusterLogging, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ClusterLogging{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterLoggingGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterLoggingGeneratingHandler) Handle(obj *v3.ClusterLogging, status v3.ClusterLoggingStatus) (v3.ClusterLoggingStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterLoggingGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterLoggingGeneratingHandler) isNewResourceVersion(obj *v3.ClusterLogging) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterLoggingGeneratingHandler) storeResourceVersion(obj *v3.ClusterLogging) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterproxyconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterproxyconfig.go new file mode 100644 index 0000000..be599da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterproxyconfig.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterProxyConfigController interface for managing ClusterProxyConfig resources. +type ClusterProxyConfigController interface { + generic.ControllerInterface[*v3.ClusterProxyConfig, *v3.ClusterProxyConfigList] +} + +// ClusterProxyConfigClient interface for managing ClusterProxyConfig resources in Kubernetes. +type ClusterProxyConfigClient interface { + generic.ClientInterface[*v3.ClusterProxyConfig, *v3.ClusterProxyConfigList] +} + +// ClusterProxyConfigCache interface for retrieving ClusterProxyConfig resources in memory. +type ClusterProxyConfigCache interface { + generic.CacheInterface[*v3.ClusterProxyConfig] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterregistrationtoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterregistrationtoken.go new file mode 100644 index 0000000..a35967b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterregistrationtoken.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterRegistrationTokenController interface for managing ClusterRegistrationToken resources. +type ClusterRegistrationTokenController interface { + generic.ControllerInterface[*v3.ClusterRegistrationToken, *v3.ClusterRegistrationTokenList] +} + +// ClusterRegistrationTokenClient interface for managing ClusterRegistrationToken resources in Kubernetes. +type ClusterRegistrationTokenClient interface { + generic.ClientInterface[*v3.ClusterRegistrationToken, *v3.ClusterRegistrationTokenList] +} + +// ClusterRegistrationTokenCache interface for retrieving ClusterRegistrationToken resources in memory. +type ClusterRegistrationTokenCache interface { + generic.CacheInterface[*v3.ClusterRegistrationToken] +} + +// ClusterRegistrationTokenStatusHandler is executed for every added or modified ClusterRegistrationToken. Should return the new status to be updated +type ClusterRegistrationTokenStatusHandler func(obj *v3.ClusterRegistrationToken, status v3.ClusterRegistrationTokenStatus) (v3.ClusterRegistrationTokenStatus, error) + +// ClusterRegistrationTokenGeneratingHandler is the top-level handler that is executed for every ClusterRegistrationToken event. It extends ClusterRegistrationTokenStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterRegistrationTokenGeneratingHandler func(obj *v3.ClusterRegistrationToken, status v3.ClusterRegistrationTokenStatus) ([]runtime.Object, v3.ClusterRegistrationTokenStatus, error) + +// RegisterClusterRegistrationTokenStatusHandler configures a ClusterRegistrationTokenController to execute a ClusterRegistrationTokenStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterRegistrationTokenStatusHandler(ctx context.Context, controller ClusterRegistrationTokenController, condition condition.Cond, name string, handler ClusterRegistrationTokenStatusHandler) { + statusHandler := &clusterRegistrationTokenStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterRegistrationTokenGeneratingHandler configures a ClusterRegistrationTokenController to execute a ClusterRegistrationTokenGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterRegistrationTokenGeneratingHandler(ctx context.Context, controller ClusterRegistrationTokenController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterRegistrationTokenGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterRegistrationTokenGeneratingHandler{ + ClusterRegistrationTokenGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterRegistrationTokenStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterRegistrationTokenStatusHandler struct { + client ClusterRegistrationTokenClient + condition condition.Cond + handler ClusterRegistrationTokenStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterRegistrationTokenStatusHandler) sync(key string, obj *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterRegistrationTokenGeneratingHandler struct { + ClusterRegistrationTokenGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterRegistrationTokenGeneratingHandler) Remove(key string, obj *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ClusterRegistrationToken{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterRegistrationTokenGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterRegistrationTokenGeneratingHandler) Handle(obj *v3.ClusterRegistrationToken, status v3.ClusterRegistrationTokenStatus) (v3.ClusterRegistrationTokenStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterRegistrationTokenGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterRegistrationTokenGeneratingHandler) isNewResourceVersion(obj *v3.ClusterRegistrationToken) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterRegistrationTokenGeneratingHandler) storeResourceVersion(obj *v3.ClusterRegistrationToken) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterroletemplatebinding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterroletemplatebinding.go new file mode 100644 index 0000000..7a448b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clusterroletemplatebinding.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterRoleTemplateBindingController interface for managing ClusterRoleTemplateBinding resources. +type ClusterRoleTemplateBindingController interface { + generic.ControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList] +} + +// ClusterRoleTemplateBindingClient interface for managing ClusterRoleTemplateBinding resources in Kubernetes. +type ClusterRoleTemplateBindingClient interface { + generic.ClientInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList] +} + +// ClusterRoleTemplateBindingCache interface for retrieving ClusterRoleTemplateBinding resources in memory. +type ClusterRoleTemplateBindingCache interface { + generic.CacheInterface[*v3.ClusterRoleTemplateBinding] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplate.go new file mode 100644 index 0000000..c643a40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ClusterTemplateController interface for managing ClusterTemplate resources. +type ClusterTemplateController interface { + generic.ControllerInterface[*v3.ClusterTemplate, *v3.ClusterTemplateList] +} + +// ClusterTemplateClient interface for managing ClusterTemplate resources in Kubernetes. +type ClusterTemplateClient interface { + generic.ClientInterface[*v3.ClusterTemplate, *v3.ClusterTemplateList] +} + +// ClusterTemplateCache interface for retrieving ClusterTemplate resources in memory. +type ClusterTemplateCache interface { + generic.CacheInterface[*v3.ClusterTemplate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplaterevision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplaterevision.go new file mode 100644 index 0000000..cc15e89 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/clustertemplaterevision.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterTemplateRevisionController interface for managing ClusterTemplateRevision resources. +type ClusterTemplateRevisionController interface { + generic.ControllerInterface[*v3.ClusterTemplateRevision, *v3.ClusterTemplateRevisionList] +} + +// ClusterTemplateRevisionClient interface for managing ClusterTemplateRevision resources in Kubernetes. +type ClusterTemplateRevisionClient interface { + generic.ClientInterface[*v3.ClusterTemplateRevision, *v3.ClusterTemplateRevisionList] +} + +// ClusterTemplateRevisionCache interface for retrieving ClusterTemplateRevision resources in memory. +type ClusterTemplateRevisionCache interface { + generic.CacheInterface[*v3.ClusterTemplateRevision] +} + +// ClusterTemplateRevisionStatusHandler is executed for every added or modified ClusterTemplateRevision. Should return the new status to be updated +type ClusterTemplateRevisionStatusHandler func(obj *v3.ClusterTemplateRevision, status v3.ClusterTemplateRevisionStatus) (v3.ClusterTemplateRevisionStatus, error) + +// ClusterTemplateRevisionGeneratingHandler is the top-level handler that is executed for every ClusterTemplateRevision event. It extends ClusterTemplateRevisionStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterTemplateRevisionGeneratingHandler func(obj *v3.ClusterTemplateRevision, status v3.ClusterTemplateRevisionStatus) ([]runtime.Object, v3.ClusterTemplateRevisionStatus, error) + +// RegisterClusterTemplateRevisionStatusHandler configures a ClusterTemplateRevisionController to execute a ClusterTemplateRevisionStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterTemplateRevisionStatusHandler(ctx context.Context, controller ClusterTemplateRevisionController, condition condition.Cond, name string, handler ClusterTemplateRevisionStatusHandler) { + statusHandler := &clusterTemplateRevisionStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterTemplateRevisionGeneratingHandler configures a ClusterTemplateRevisionController to execute a ClusterTemplateRevisionGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterTemplateRevisionGeneratingHandler(ctx context.Context, controller ClusterTemplateRevisionController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterTemplateRevisionGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterTemplateRevisionGeneratingHandler{ + ClusterTemplateRevisionGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterTemplateRevisionStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterTemplateRevisionStatusHandler struct { + client ClusterTemplateRevisionClient + condition condition.Cond + handler ClusterTemplateRevisionStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterTemplateRevisionStatusHandler) sync(key string, obj *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterTemplateRevisionGeneratingHandler struct { + ClusterTemplateRevisionGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterTemplateRevisionGeneratingHandler) Remove(key string, obj *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ClusterTemplateRevision{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterTemplateRevisionGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterTemplateRevisionGeneratingHandler) Handle(obj *v3.ClusterTemplateRevision, status v3.ClusterTemplateRevisionStatus) (v3.ClusterTemplateRevisionStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterTemplateRevisionGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterTemplateRevisionGeneratingHandler) isNewResourceVersion(obj *v3.ClusterTemplateRevision) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterTemplateRevisionGeneratingHandler) storeResourceVersion(obj *v3.ClusterTemplateRevision) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/composeconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/composeconfig.go new file mode 100644 index 0000000..2a73eb8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/composeconfig.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ComposeConfigController interface for managing ComposeConfig resources. +type ComposeConfigController interface { + generic.NonNamespacedControllerInterface[*v3.ComposeConfig, *v3.ComposeConfigList] +} + +// ComposeConfigClient interface for managing ComposeConfig resources in Kubernetes. +type ComposeConfigClient interface { + generic.NonNamespacedClientInterface[*v3.ComposeConfig, *v3.ComposeConfigList] +} + +// ComposeConfigCache interface for retrieving ComposeConfig resources in memory. +type ComposeConfigCache interface { + generic.NonNamespacedCacheInterface[*v3.ComposeConfig] +} + +// ComposeConfigStatusHandler is executed for every added or modified ComposeConfig. Should return the new status to be updated +type ComposeConfigStatusHandler func(obj *v3.ComposeConfig, status v3.ComposeStatus) (v3.ComposeStatus, error) + +// ComposeConfigGeneratingHandler is the top-level handler that is executed for every ComposeConfig event. It extends ComposeConfigStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ComposeConfigGeneratingHandler func(obj *v3.ComposeConfig, status v3.ComposeStatus) ([]runtime.Object, v3.ComposeStatus, error) + +// RegisterComposeConfigStatusHandler configures a ComposeConfigController to execute a ComposeConfigStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterComposeConfigStatusHandler(ctx context.Context, controller ComposeConfigController, condition condition.Cond, name string, handler ComposeConfigStatusHandler) { + statusHandler := &composeConfigStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterComposeConfigGeneratingHandler configures a ComposeConfigController to execute a ComposeConfigGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterComposeConfigGeneratingHandler(ctx context.Context, controller ComposeConfigController, apply apply.Apply, + condition condition.Cond, name string, handler ComposeConfigGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &composeConfigGeneratingHandler{ + ComposeConfigGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterComposeConfigStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type composeConfigStatusHandler struct { + client ComposeConfigClient + condition condition.Cond + handler ComposeConfigStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *composeConfigStatusHandler) sync(key string, obj *v3.ComposeConfig) (*v3.ComposeConfig, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type composeConfigGeneratingHandler struct { + ComposeConfigGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *composeConfigGeneratingHandler) Remove(key string, obj *v3.ComposeConfig) (*v3.ComposeConfig, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ComposeConfig{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ComposeConfigGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *composeConfigGeneratingHandler) Handle(obj *v3.ComposeConfig, status v3.ComposeStatus) (v3.ComposeStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ComposeConfigGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *composeConfigGeneratingHandler) isNewResourceVersion(obj *v3.ComposeConfig) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *composeConfigGeneratingHandler) storeResourceVersion(obj *v3.ComposeConfig) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/dynamicschema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/dynamicschema.go new file mode 100644 index 0000000..cc75be5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/dynamicschema.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// DynamicSchemaController interface for managing DynamicSchema resources. +type DynamicSchemaController interface { + generic.NonNamespacedControllerInterface[*v3.DynamicSchema, *v3.DynamicSchemaList] +} + +// DynamicSchemaClient interface for managing DynamicSchema resources in Kubernetes. +type DynamicSchemaClient interface { + generic.NonNamespacedClientInterface[*v3.DynamicSchema, *v3.DynamicSchemaList] +} + +// DynamicSchemaCache interface for retrieving DynamicSchema resources in memory. +type DynamicSchemaCache interface { + generic.NonNamespacedCacheInterface[*v3.DynamicSchema] +} + +// DynamicSchemaStatusHandler is executed for every added or modified DynamicSchema. Should return the new status to be updated +type DynamicSchemaStatusHandler func(obj *v3.DynamicSchema, status v3.DynamicSchemaStatus) (v3.DynamicSchemaStatus, error) + +// DynamicSchemaGeneratingHandler is the top-level handler that is executed for every DynamicSchema event. It extends DynamicSchemaStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type DynamicSchemaGeneratingHandler func(obj *v3.DynamicSchema, status v3.DynamicSchemaStatus) ([]runtime.Object, v3.DynamicSchemaStatus, error) + +// RegisterDynamicSchemaStatusHandler configures a DynamicSchemaController to execute a DynamicSchemaStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterDynamicSchemaStatusHandler(ctx context.Context, controller DynamicSchemaController, condition condition.Cond, name string, handler DynamicSchemaStatusHandler) { + statusHandler := &dynamicSchemaStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterDynamicSchemaGeneratingHandler configures a DynamicSchemaController to execute a DynamicSchemaGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterDynamicSchemaGeneratingHandler(ctx context.Context, controller DynamicSchemaController, apply apply.Apply, + condition condition.Cond, name string, handler DynamicSchemaGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &dynamicSchemaGeneratingHandler{ + DynamicSchemaGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterDynamicSchemaStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type dynamicSchemaStatusHandler struct { + client DynamicSchemaClient + condition condition.Cond + handler DynamicSchemaStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *dynamicSchemaStatusHandler) sync(key string, obj *v3.DynamicSchema) (*v3.DynamicSchema, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type dynamicSchemaGeneratingHandler struct { + DynamicSchemaGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *dynamicSchemaGeneratingHandler) Remove(key string, obj *v3.DynamicSchema) (*v3.DynamicSchema, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.DynamicSchema{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured DynamicSchemaGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *dynamicSchemaGeneratingHandler) Handle(obj *v3.DynamicSchema, status v3.DynamicSchemaStatus) (v3.DynamicSchemaStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.DynamicSchemaGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *dynamicSchemaGeneratingHandler) isNewResourceVersion(obj *v3.DynamicSchema) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *dynamicSchemaGeneratingHandler) storeResourceVersion(obj *v3.DynamicSchema) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/etcdbackup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/etcdbackup.go new file mode 100644 index 0000000..1ef17c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/etcdbackup.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// EtcdBackupController interface for managing EtcdBackup resources. +type EtcdBackupController interface { + generic.ControllerInterface[*v3.EtcdBackup, *v3.EtcdBackupList] +} + +// EtcdBackupClient interface for managing EtcdBackup resources in Kubernetes. +type EtcdBackupClient interface { + generic.ClientInterface[*v3.EtcdBackup, *v3.EtcdBackupList] +} + +// EtcdBackupCache interface for retrieving EtcdBackup resources in memory. +type EtcdBackupCache interface { + generic.CacheInterface[*v3.EtcdBackup] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/feature.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/feature.go new file mode 100644 index 0000000..71f5271 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/feature.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// FeatureController interface for managing Feature resources. +type FeatureController interface { + generic.NonNamespacedControllerInterface[*v3.Feature, *v3.FeatureList] +} + +// FeatureClient interface for managing Feature resources in Kubernetes. +type FeatureClient interface { + generic.NonNamespacedClientInterface[*v3.Feature, *v3.FeatureList] +} + +// FeatureCache interface for retrieving Feature resources in memory. +type FeatureCache interface { + generic.NonNamespacedCacheInterface[*v3.Feature] +} + +// FeatureStatusHandler is executed for every added or modified Feature. Should return the new status to be updated +type FeatureStatusHandler func(obj *v3.Feature, status v3.FeatureStatus) (v3.FeatureStatus, error) + +// FeatureGeneratingHandler is the top-level handler that is executed for every Feature event. It extends FeatureStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type FeatureGeneratingHandler func(obj *v3.Feature, status v3.FeatureStatus) ([]runtime.Object, v3.FeatureStatus, error) + +// RegisterFeatureStatusHandler configures a FeatureController to execute a FeatureStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterFeatureStatusHandler(ctx context.Context, controller FeatureController, condition condition.Cond, name string, handler FeatureStatusHandler) { + statusHandler := &featureStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterFeatureGeneratingHandler configures a FeatureController to execute a FeatureGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterFeatureGeneratingHandler(ctx context.Context, controller FeatureController, apply apply.Apply, + condition condition.Cond, name string, handler FeatureGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &featureGeneratingHandler{ + FeatureGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterFeatureStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type featureStatusHandler struct { + client FeatureClient + condition condition.Cond + handler FeatureStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *featureStatusHandler) sync(key string, obj *v3.Feature) (*v3.Feature, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type featureGeneratingHandler struct { + FeatureGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *featureGeneratingHandler) Remove(key string, obj *v3.Feature) (*v3.Feature, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Feature{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured FeatureGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *featureGeneratingHandler) Handle(obj *v3.Feature, status v3.FeatureStatus) (v3.FeatureStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.FeatureGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *featureGeneratingHandler) isNewResourceVersion(obj *v3.Feature) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *featureGeneratingHandler) storeResourceVersion(obj *v3.Feature) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/fleetworkspace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/fleetworkspace.go new file mode 100644 index 0000000..0e5e1d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/fleetworkspace.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// FleetWorkspaceController interface for managing FleetWorkspace resources. +type FleetWorkspaceController interface { + generic.NonNamespacedControllerInterface[*v3.FleetWorkspace, *v3.FleetWorkspaceList] +} + +// FleetWorkspaceClient interface for managing FleetWorkspace resources in Kubernetes. +type FleetWorkspaceClient interface { + generic.NonNamespacedClientInterface[*v3.FleetWorkspace, *v3.FleetWorkspaceList] +} + +// FleetWorkspaceCache interface for retrieving FleetWorkspace resources in memory. +type FleetWorkspaceCache interface { + generic.NonNamespacedCacheInterface[*v3.FleetWorkspace] +} + +// FleetWorkspaceStatusHandler is executed for every added or modified FleetWorkspace. Should return the new status to be updated +type FleetWorkspaceStatusHandler func(obj *v3.FleetWorkspace, status v3.FleetWorkspaceStatus) (v3.FleetWorkspaceStatus, error) + +// FleetWorkspaceGeneratingHandler is the top-level handler that is executed for every FleetWorkspace event. It extends FleetWorkspaceStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type FleetWorkspaceGeneratingHandler func(obj *v3.FleetWorkspace, status v3.FleetWorkspaceStatus) ([]runtime.Object, v3.FleetWorkspaceStatus, error) + +// RegisterFleetWorkspaceStatusHandler configures a FleetWorkspaceController to execute a FleetWorkspaceStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterFleetWorkspaceStatusHandler(ctx context.Context, controller FleetWorkspaceController, condition condition.Cond, name string, handler FleetWorkspaceStatusHandler) { + statusHandler := &fleetWorkspaceStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterFleetWorkspaceGeneratingHandler configures a FleetWorkspaceController to execute a FleetWorkspaceGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterFleetWorkspaceGeneratingHandler(ctx context.Context, controller FleetWorkspaceController, apply apply.Apply, + condition condition.Cond, name string, handler FleetWorkspaceGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &fleetWorkspaceGeneratingHandler{ + FleetWorkspaceGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterFleetWorkspaceStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type fleetWorkspaceStatusHandler struct { + client FleetWorkspaceClient + condition condition.Cond + handler FleetWorkspaceStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *fleetWorkspaceStatusHandler) sync(key string, obj *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type fleetWorkspaceGeneratingHandler struct { + FleetWorkspaceGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *fleetWorkspaceGeneratingHandler) Remove(key string, obj *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.FleetWorkspace{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured FleetWorkspaceGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *fleetWorkspaceGeneratingHandler) Handle(obj *v3.FleetWorkspace, status v3.FleetWorkspaceStatus) (v3.FleetWorkspaceStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.FleetWorkspaceGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *fleetWorkspaceGeneratingHandler) isNewResourceVersion(obj *v3.FleetWorkspace) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *fleetWorkspaceGeneratingHandler) storeResourceVersion(obj *v3.FleetWorkspace) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/freeipaprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/freeipaprovider.go new file mode 100644 index 0000000..2346d4e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/freeipaprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// FreeIpaProviderController interface for managing FreeIpaProvider resources. +type FreeIpaProviderController interface { + generic.NonNamespacedControllerInterface[*v3.FreeIpaProvider, *v3.FreeIpaProviderList] +} + +// FreeIpaProviderClient interface for managing FreeIpaProvider resources in Kubernetes. +type FreeIpaProviderClient interface { + generic.NonNamespacedClientInterface[*v3.FreeIpaProvider, *v3.FreeIpaProviderList] +} + +// FreeIpaProviderCache interface for retrieving FreeIpaProvider resources in memory. +type FreeIpaProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.FreeIpaProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/genericoidcprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/genericoidcprovider.go new file mode 100644 index 0000000..8ac2078 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/genericoidcprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GenericOIDCProviderController interface for managing GenericOIDCProvider resources. +type GenericOIDCProviderController interface { + generic.NonNamespacedControllerInterface[*v3.GenericOIDCProvider, *v3.GenericOIDCProviderList] +} + +// GenericOIDCProviderClient interface for managing GenericOIDCProvider resources in Kubernetes. +type GenericOIDCProviderClient interface { + generic.NonNamespacedClientInterface[*v3.GenericOIDCProvider, *v3.GenericOIDCProviderList] +} + +// GenericOIDCProviderCache interface for retrieving GenericOIDCProvider resources in memory. +type GenericOIDCProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.GenericOIDCProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/githubprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/githubprovider.go new file mode 100644 index 0000000..4a54f2d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/githubprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GithubProviderController interface for managing GithubProvider resources. +type GithubProviderController interface { + generic.NonNamespacedControllerInterface[*v3.GithubProvider, *v3.GithubProviderList] +} + +// GithubProviderClient interface for managing GithubProvider resources in Kubernetes. +type GithubProviderClient interface { + generic.NonNamespacedClientInterface[*v3.GithubProvider, *v3.GithubProviderList] +} + +// GithubProviderCache interface for retrieving GithubProvider resources in memory. +type GithubProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.GithubProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldns.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldns.go new file mode 100644 index 0000000..14505e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldns.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GlobalDnsController interface for managing GlobalDns resources. +type GlobalDnsController interface { + generic.ControllerInterface[*v3.GlobalDns, *v3.GlobalDnsList] +} + +// GlobalDnsClient interface for managing GlobalDns resources in Kubernetes. +type GlobalDnsClient interface { + generic.ClientInterface[*v3.GlobalDns, *v3.GlobalDnsList] +} + +// GlobalDnsCache interface for retrieving GlobalDns resources in memory. +type GlobalDnsCache interface { + generic.CacheInterface[*v3.GlobalDns] +} + +// GlobalDnsStatusHandler is executed for every added or modified GlobalDns. Should return the new status to be updated +type GlobalDnsStatusHandler func(obj *v3.GlobalDns, status v3.GlobalDNSStatus) (v3.GlobalDNSStatus, error) + +// GlobalDnsGeneratingHandler is the top-level handler that is executed for every GlobalDns event. It extends GlobalDnsStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type GlobalDnsGeneratingHandler func(obj *v3.GlobalDns, status v3.GlobalDNSStatus) ([]runtime.Object, v3.GlobalDNSStatus, error) + +// RegisterGlobalDnsStatusHandler configures a GlobalDnsController to execute a GlobalDnsStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterGlobalDnsStatusHandler(ctx context.Context, controller GlobalDnsController, condition condition.Cond, name string, handler GlobalDnsStatusHandler) { + statusHandler := &globalDnsStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterGlobalDnsGeneratingHandler configures a GlobalDnsController to execute a GlobalDnsGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterGlobalDnsGeneratingHandler(ctx context.Context, controller GlobalDnsController, apply apply.Apply, + condition condition.Cond, name string, handler GlobalDnsGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &globalDnsGeneratingHandler{ + GlobalDnsGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterGlobalDnsStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type globalDnsStatusHandler struct { + client GlobalDnsClient + condition condition.Cond + handler GlobalDnsStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *globalDnsStatusHandler) sync(key string, obj *v3.GlobalDns) (*v3.GlobalDns, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type globalDnsGeneratingHandler struct { + GlobalDnsGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *globalDnsGeneratingHandler) Remove(key string, obj *v3.GlobalDns) (*v3.GlobalDns, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.GlobalDns{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured GlobalDnsGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *globalDnsGeneratingHandler) Handle(obj *v3.GlobalDns, status v3.GlobalDNSStatus) (v3.GlobalDNSStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.GlobalDnsGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *globalDnsGeneratingHandler) isNewResourceVersion(obj *v3.GlobalDns) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *globalDnsGeneratingHandler) storeResourceVersion(obj *v3.GlobalDns) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldnsprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldnsprovider.go new file mode 100644 index 0000000..12c6418 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globaldnsprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GlobalDnsProviderController interface for managing GlobalDnsProvider resources. +type GlobalDnsProviderController interface { + generic.ControllerInterface[*v3.GlobalDnsProvider, *v3.GlobalDnsProviderList] +} + +// GlobalDnsProviderClient interface for managing GlobalDnsProvider resources in Kubernetes. +type GlobalDnsProviderClient interface { + generic.ClientInterface[*v3.GlobalDnsProvider, *v3.GlobalDnsProviderList] +} + +// GlobalDnsProviderCache interface for retrieving GlobalDnsProvider resources in memory. +type GlobalDnsProviderCache interface { + generic.CacheInterface[*v3.GlobalDnsProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrole.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrole.go new file mode 100644 index 0000000..a1b8b61 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrole.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GlobalRoleController interface for managing GlobalRole resources. +type GlobalRoleController interface { + generic.NonNamespacedControllerInterface[*v3.GlobalRole, *v3.GlobalRoleList] +} + +// GlobalRoleClient interface for managing GlobalRole resources in Kubernetes. +type GlobalRoleClient interface { + generic.NonNamespacedClientInterface[*v3.GlobalRole, *v3.GlobalRoleList] +} + +// GlobalRoleCache interface for retrieving GlobalRole resources in memory. +type GlobalRoleCache interface { + generic.NonNamespacedCacheInterface[*v3.GlobalRole] +} + +// GlobalRoleStatusHandler is executed for every added or modified GlobalRole. Should return the new status to be updated +type GlobalRoleStatusHandler func(obj *v3.GlobalRole, status v3.GlobalRoleStatus) (v3.GlobalRoleStatus, error) + +// GlobalRoleGeneratingHandler is the top-level handler that is executed for every GlobalRole event. It extends GlobalRoleStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type GlobalRoleGeneratingHandler func(obj *v3.GlobalRole, status v3.GlobalRoleStatus) ([]runtime.Object, v3.GlobalRoleStatus, error) + +// RegisterGlobalRoleStatusHandler configures a GlobalRoleController to execute a GlobalRoleStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterGlobalRoleStatusHandler(ctx context.Context, controller GlobalRoleController, condition condition.Cond, name string, handler GlobalRoleStatusHandler) { + statusHandler := &globalRoleStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterGlobalRoleGeneratingHandler configures a GlobalRoleController to execute a GlobalRoleGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterGlobalRoleGeneratingHandler(ctx context.Context, controller GlobalRoleController, apply apply.Apply, + condition condition.Cond, name string, handler GlobalRoleGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &globalRoleGeneratingHandler{ + GlobalRoleGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterGlobalRoleStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type globalRoleStatusHandler struct { + client GlobalRoleClient + condition condition.Cond + handler GlobalRoleStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *globalRoleStatusHandler) sync(key string, obj *v3.GlobalRole) (*v3.GlobalRole, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type globalRoleGeneratingHandler struct { + GlobalRoleGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *globalRoleGeneratingHandler) Remove(key string, obj *v3.GlobalRole) (*v3.GlobalRole, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.GlobalRole{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured GlobalRoleGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *globalRoleGeneratingHandler) Handle(obj *v3.GlobalRole, status v3.GlobalRoleStatus) (v3.GlobalRoleStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.GlobalRoleGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *globalRoleGeneratingHandler) isNewResourceVersion(obj *v3.GlobalRole) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *globalRoleGeneratingHandler) storeResourceVersion(obj *v3.GlobalRole) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrolebinding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrolebinding.go new file mode 100644 index 0000000..3b00550 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/globalrolebinding.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GlobalRoleBindingController interface for managing GlobalRoleBinding resources. +type GlobalRoleBindingController interface { + generic.NonNamespacedControllerInterface[*v3.GlobalRoleBinding, *v3.GlobalRoleBindingList] +} + +// GlobalRoleBindingClient interface for managing GlobalRoleBinding resources in Kubernetes. +type GlobalRoleBindingClient interface { + generic.NonNamespacedClientInterface[*v3.GlobalRoleBinding, *v3.GlobalRoleBindingList] +} + +// GlobalRoleBindingCache interface for retrieving GlobalRoleBinding resources in memory. +type GlobalRoleBindingCache interface { + generic.NonNamespacedCacheInterface[*v3.GlobalRoleBinding] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/googleoauthprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/googleoauthprovider.go new file mode 100644 index 0000000..0b435fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/googleoauthprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GoogleOAuthProviderController interface for managing GoogleOAuthProvider resources. +type GoogleOAuthProviderController interface { + generic.NonNamespacedControllerInterface[*v3.GoogleOAuthProvider, *v3.GoogleOAuthProviderList] +} + +// GoogleOAuthProviderClient interface for managing GoogleOAuthProvider resources in Kubernetes. +type GoogleOAuthProviderClient interface { + generic.NonNamespacedClientInterface[*v3.GoogleOAuthProvider, *v3.GoogleOAuthProviderList] +} + +// GoogleOAuthProviderCache interface for retrieving GoogleOAuthProvider resources in memory. +type GoogleOAuthProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.GoogleOAuthProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/group.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/group.go new file mode 100644 index 0000000..4f4f98b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/group.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GroupController interface for managing Group resources. +type GroupController interface { + generic.NonNamespacedControllerInterface[*v3.Group, *v3.GroupList] +} + +// GroupClient interface for managing Group resources in Kubernetes. +type GroupClient interface { + generic.NonNamespacedClientInterface[*v3.Group, *v3.GroupList] +} + +// GroupCache interface for retrieving Group resources in memory. +type GroupCache interface { + generic.NonNamespacedCacheInterface[*v3.Group] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/groupmember.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/groupmember.go new file mode 100644 index 0000000..529b733 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/groupmember.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// GroupMemberController interface for managing GroupMember resources. +type GroupMemberController interface { + generic.NonNamespacedControllerInterface[*v3.GroupMember, *v3.GroupMemberList] +} + +// GroupMemberClient interface for managing GroupMember resources in Kubernetes. +type GroupMemberClient interface { + generic.NonNamespacedClientInterface[*v3.GroupMember, *v3.GroupMemberList] +} + +// GroupMemberCache interface for retrieving GroupMember resources in memory. +type GroupMemberCache interface { + generic.NonNamespacedCacheInterface[*v3.GroupMember] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/interface.go new file mode 100644 index 0000000..62bba5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/interface.go @@ -0,0 +1,374 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v3.AddToScheme) +} + +type Interface interface { + APIService() APIServiceController + ActiveDirectoryProvider() ActiveDirectoryProviderController + AuthConfig() AuthConfigController + AuthProvider() AuthProviderController + AuthToken() AuthTokenController + AzureADProvider() AzureADProviderController + Catalog() CatalogController + CatalogTemplate() CatalogTemplateController + CatalogTemplateVersion() CatalogTemplateVersionController + CloudCredential() CloudCredentialController + Cluster() ClusterController + ClusterCatalog() ClusterCatalogController + ClusterLogging() ClusterLoggingController + ClusterProxyConfig() ClusterProxyConfigController + ClusterRegistrationToken() ClusterRegistrationTokenController + ClusterRoleTemplateBinding() ClusterRoleTemplateBindingController + ClusterTemplate() ClusterTemplateController + ClusterTemplateRevision() ClusterTemplateRevisionController + ComposeConfig() ComposeConfigController + DynamicSchema() DynamicSchemaController + EtcdBackup() EtcdBackupController + Feature() FeatureController + FleetWorkspace() FleetWorkspaceController + FreeIpaProvider() FreeIpaProviderController + GenericOIDCProvider() GenericOIDCProviderController + GithubProvider() GithubProviderController + GlobalDns() GlobalDnsController + GlobalDnsProvider() GlobalDnsProviderController + GlobalRole() GlobalRoleController + GlobalRoleBinding() GlobalRoleBindingController + GoogleOAuthProvider() GoogleOAuthProviderController + Group() GroupController + GroupMember() GroupMemberController + KontainerDriver() KontainerDriverController + LocalProvider() LocalProviderController + ManagedChart() ManagedChartController + MultiClusterApp() MultiClusterAppController + MultiClusterAppRevision() MultiClusterAppRevisionController + Node() NodeController + NodeDriver() NodeDriverController + NodePool() NodePoolController + NodeTemplate() NodeTemplateController + OIDCProvider() OIDCProviderController + OpenLdapProvider() OpenLdapProviderController + PodSecurityAdmissionConfigurationTemplate() PodSecurityAdmissionConfigurationTemplateController + Preference() PreferenceController + Principal() PrincipalController + Project() ProjectController + ProjectCatalog() ProjectCatalogController + ProjectLogging() ProjectLoggingController + ProjectNetworkPolicy() ProjectNetworkPolicyController + ProjectRoleTemplateBinding() ProjectRoleTemplateBindingController + RancherUserNotification() RancherUserNotificationController + RkeAddon() RkeAddonController + RkeK8sServiceOption() RkeK8sServiceOptionController + RkeK8sSystemImage() RkeK8sSystemImageController + RoleTemplate() RoleTemplateController + SamlProvider() SamlProviderController + SamlToken() SamlTokenController + Setting() SettingController + Template() TemplateController + TemplateContent() TemplateContentController + TemplateVersion() TemplateVersionController + Token() TokenController + User() UserController + UserAttribute() UserAttributeController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) APIService() APIServiceController { + return generic.NewNonNamespacedController[*v3.APIService, *v3.APIServiceList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "APIService"}, "apiservices", v.controllerFactory) +} + +func (v *version) ActiveDirectoryProvider() ActiveDirectoryProviderController { + return generic.NewNonNamespacedController[*v3.ActiveDirectoryProvider, *v3.ActiveDirectoryProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ActiveDirectoryProvider"}, "activedirectoryproviders", v.controllerFactory) +} + +func (v *version) AuthConfig() AuthConfigController { + return generic.NewNonNamespacedController[*v3.AuthConfig, *v3.AuthConfigList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "AuthConfig"}, "authconfigs", v.controllerFactory) +} + +func (v *version) AuthProvider() AuthProviderController { + return generic.NewNonNamespacedController[*v3.AuthProvider, *v3.AuthProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "AuthProvider"}, "authproviders", v.controllerFactory) +} + +func (v *version) AuthToken() AuthTokenController { + return generic.NewNonNamespacedController[*v3.AuthToken, *v3.AuthTokenList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "AuthToken"}, "authtokens", v.controllerFactory) +} + +func (v *version) AzureADProvider() AzureADProviderController { + return generic.NewNonNamespacedController[*v3.AzureADProvider, *v3.AzureADProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "AzureADProvider"}, "azureadproviders", v.controllerFactory) +} + +func (v *version) Catalog() CatalogController { + return generic.NewNonNamespacedController[*v3.Catalog, *v3.CatalogList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Catalog"}, "catalogs", v.controllerFactory) +} + +func (v *version) CatalogTemplate() CatalogTemplateController { + return generic.NewController[*v3.CatalogTemplate, *v3.CatalogTemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "CatalogTemplate"}, "catalogtemplates", true, v.controllerFactory) +} + +func (v *version) CatalogTemplateVersion() CatalogTemplateVersionController { + return generic.NewController[*v3.CatalogTemplateVersion, *v3.CatalogTemplateVersionList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "CatalogTemplateVersion"}, "catalogtemplateversions", true, v.controllerFactory) +} + +func (v *version) CloudCredential() CloudCredentialController { + return generic.NewController[*v3.CloudCredential, *v3.CloudCredentialList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "CloudCredential"}, "cloudcredentials", true, v.controllerFactory) +} + +func (v *version) Cluster() ClusterController { + return generic.NewNonNamespacedController[*v3.Cluster, *v3.ClusterList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Cluster"}, "clusters", v.controllerFactory) +} + +func (v *version) ClusterCatalog() ClusterCatalogController { + return generic.NewController[*v3.ClusterCatalog, *v3.ClusterCatalogList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterCatalog"}, "clustercatalogs", true, v.controllerFactory) +} + +func (v *version) ClusterLogging() ClusterLoggingController { + return generic.NewController[*v3.ClusterLogging, *v3.ClusterLoggingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterLogging"}, "clusterloggings", true, v.controllerFactory) +} + +func (v *version) ClusterProxyConfig() ClusterProxyConfigController { + return generic.NewController[*v3.ClusterProxyConfig, *v3.ClusterProxyConfigList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterProxyConfig"}, "clusterproxyconfigs", true, v.controllerFactory) +} + +func (v *version) ClusterRegistrationToken() ClusterRegistrationTokenController { + return generic.NewController[*v3.ClusterRegistrationToken, *v3.ClusterRegistrationTokenList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterRegistrationToken"}, "clusterregistrationtokens", true, v.controllerFactory) +} + +func (v *version) ClusterRoleTemplateBinding() ClusterRoleTemplateBindingController { + return generic.NewController[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterRoleTemplateBinding"}, "clusterroletemplatebindings", true, v.controllerFactory) +} + +func (v *version) ClusterTemplate() ClusterTemplateController { + return generic.NewController[*v3.ClusterTemplate, *v3.ClusterTemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterTemplate"}, "clustertemplates", true, v.controllerFactory) +} + +func (v *version) ClusterTemplateRevision() ClusterTemplateRevisionController { + return generic.NewController[*v3.ClusterTemplateRevision, *v3.ClusterTemplateRevisionList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ClusterTemplateRevision"}, "clustertemplaterevisions", true, v.controllerFactory) +} + +func (v *version) ComposeConfig() ComposeConfigController { + return generic.NewNonNamespacedController[*v3.ComposeConfig, *v3.ComposeConfigList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ComposeConfig"}, "composeconfigs", v.controllerFactory) +} + +func (v *version) DynamicSchema() DynamicSchemaController { + return generic.NewNonNamespacedController[*v3.DynamicSchema, *v3.DynamicSchemaList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "DynamicSchema"}, "dynamicschemas", v.controllerFactory) +} + +func (v *version) EtcdBackup() EtcdBackupController { + return generic.NewController[*v3.EtcdBackup, *v3.EtcdBackupList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "EtcdBackup"}, "etcdbackups", true, v.controllerFactory) +} + +func (v *version) Feature() FeatureController { + return generic.NewNonNamespacedController[*v3.Feature, *v3.FeatureList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Feature"}, "features", v.controllerFactory) +} + +func (v *version) FleetWorkspace() FleetWorkspaceController { + return generic.NewNonNamespacedController[*v3.FleetWorkspace, *v3.FleetWorkspaceList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "FleetWorkspace"}, "fleetworkspaces", v.controllerFactory) +} + +func (v *version) FreeIpaProvider() FreeIpaProviderController { + return generic.NewNonNamespacedController[*v3.FreeIpaProvider, *v3.FreeIpaProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "FreeIpaProvider"}, "freeipaproviders", v.controllerFactory) +} + +func (v *version) GenericOIDCProvider() GenericOIDCProviderController { + return generic.NewNonNamespacedController[*v3.GenericOIDCProvider, *v3.GenericOIDCProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GenericOIDCProvider"}, "genericoidcproviders", v.controllerFactory) +} + +func (v *version) GithubProvider() GithubProviderController { + return generic.NewNonNamespacedController[*v3.GithubProvider, *v3.GithubProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GithubProvider"}, "githubproviders", v.controllerFactory) +} + +func (v *version) GlobalDns() GlobalDnsController { + return generic.NewController[*v3.GlobalDns, *v3.GlobalDnsList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GlobalDns"}, "globaldnses", true, v.controllerFactory) +} + +func (v *version) GlobalDnsProvider() GlobalDnsProviderController { + return generic.NewController[*v3.GlobalDnsProvider, *v3.GlobalDnsProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GlobalDnsProvider"}, "globaldnsproviders", true, v.controllerFactory) +} + +func (v *version) GlobalRole() GlobalRoleController { + return generic.NewNonNamespacedController[*v3.GlobalRole, *v3.GlobalRoleList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GlobalRole"}, "globalroles", v.controllerFactory) +} + +func (v *version) GlobalRoleBinding() GlobalRoleBindingController { + return generic.NewNonNamespacedController[*v3.GlobalRoleBinding, *v3.GlobalRoleBindingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GlobalRoleBinding"}, "globalrolebindings", v.controllerFactory) +} + +func (v *version) GoogleOAuthProvider() GoogleOAuthProviderController { + return generic.NewNonNamespacedController[*v3.GoogleOAuthProvider, *v3.GoogleOAuthProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GoogleOAuthProvider"}, "googleoauthproviders", v.controllerFactory) +} + +func (v *version) Group() GroupController { + return generic.NewNonNamespacedController[*v3.Group, *v3.GroupList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Group"}, "groups", v.controllerFactory) +} + +func (v *version) GroupMember() GroupMemberController { + return generic.NewNonNamespacedController[*v3.GroupMember, *v3.GroupMemberList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "GroupMember"}, "groupmembers", v.controllerFactory) +} + +func (v *version) KontainerDriver() KontainerDriverController { + return generic.NewNonNamespacedController[*v3.KontainerDriver, *v3.KontainerDriverList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "KontainerDriver"}, "kontainerdrivers", v.controllerFactory) +} + +func (v *version) LocalProvider() LocalProviderController { + return generic.NewNonNamespacedController[*v3.LocalProvider, *v3.LocalProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "LocalProvider"}, "localproviders", v.controllerFactory) +} + +func (v *version) ManagedChart() ManagedChartController { + return generic.NewController[*v3.ManagedChart, *v3.ManagedChartList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ManagedChart"}, "managedcharts", true, v.controllerFactory) +} + +func (v *version) MultiClusterApp() MultiClusterAppController { + return generic.NewController[*v3.MultiClusterApp, *v3.MultiClusterAppList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "MultiClusterApp"}, "multiclusterapps", true, v.controllerFactory) +} + +func (v *version) MultiClusterAppRevision() MultiClusterAppRevisionController { + return generic.NewController[*v3.MultiClusterAppRevision, *v3.MultiClusterAppRevisionList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "MultiClusterAppRevision"}, "multiclusterapprevisions", true, v.controllerFactory) +} + +func (v *version) Node() NodeController { + return generic.NewController[*v3.Node, *v3.NodeList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Node"}, "nodes", true, v.controllerFactory) +} + +func (v *version) NodeDriver() NodeDriverController { + return generic.NewNonNamespacedController[*v3.NodeDriver, *v3.NodeDriverList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "NodeDriver"}, "nodedrivers", v.controllerFactory) +} + +func (v *version) NodePool() NodePoolController { + return generic.NewController[*v3.NodePool, *v3.NodePoolList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "NodePool"}, "nodepools", true, v.controllerFactory) +} + +func (v *version) NodeTemplate() NodeTemplateController { + return generic.NewController[*v3.NodeTemplate, *v3.NodeTemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "NodeTemplate"}, "nodetemplates", true, v.controllerFactory) +} + +func (v *version) OIDCProvider() OIDCProviderController { + return generic.NewNonNamespacedController[*v3.OIDCProvider, *v3.OIDCProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "OIDCProvider"}, "oidcproviders", v.controllerFactory) +} + +func (v *version) OpenLdapProvider() OpenLdapProviderController { + return generic.NewNonNamespacedController[*v3.OpenLdapProvider, *v3.OpenLdapProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "OpenLdapProvider"}, "openldapproviders", v.controllerFactory) +} + +func (v *version) PodSecurityAdmissionConfigurationTemplate() PodSecurityAdmissionConfigurationTemplateController { + return generic.NewNonNamespacedController[*v3.PodSecurityAdmissionConfigurationTemplate, *v3.PodSecurityAdmissionConfigurationTemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "PodSecurityAdmissionConfigurationTemplate"}, "podsecurityadmissionconfigurationtemplates", v.controllerFactory) +} + +func (v *version) Preference() PreferenceController { + return generic.NewController[*v3.Preference, *v3.PreferenceList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Preference"}, "preferences", true, v.controllerFactory) +} + +func (v *version) Principal() PrincipalController { + return generic.NewNonNamespacedController[*v3.Principal, *v3.PrincipalList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Principal"}, "principals", v.controllerFactory) +} + +func (v *version) Project() ProjectController { + return generic.NewController[*v3.Project, *v3.ProjectList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Project"}, "projects", true, v.controllerFactory) +} + +func (v *version) ProjectCatalog() ProjectCatalogController { + return generic.NewController[*v3.ProjectCatalog, *v3.ProjectCatalogList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ProjectCatalog"}, "projectcatalogs", true, v.controllerFactory) +} + +func (v *version) ProjectLogging() ProjectLoggingController { + return generic.NewController[*v3.ProjectLogging, *v3.ProjectLoggingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ProjectLogging"}, "projectloggings", true, v.controllerFactory) +} + +func (v *version) ProjectNetworkPolicy() ProjectNetworkPolicyController { + return generic.NewController[*v3.ProjectNetworkPolicy, *v3.ProjectNetworkPolicyList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ProjectNetworkPolicy"}, "projectnetworkpolicies", true, v.controllerFactory) +} + +func (v *version) ProjectRoleTemplateBinding() ProjectRoleTemplateBindingController { + return generic.NewController[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "ProjectRoleTemplateBinding"}, "projectroletemplatebindings", true, v.controllerFactory) +} + +func (v *version) RancherUserNotification() RancherUserNotificationController { + return generic.NewNonNamespacedController[*v3.RancherUserNotification, *v3.RancherUserNotificationList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "RancherUserNotification"}, "rancherusernotifications", v.controllerFactory) +} + +func (v *version) RkeAddon() RkeAddonController { + return generic.NewController[*v3.RkeAddon, *v3.RkeAddonList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "RkeAddon"}, "rkeaddons", true, v.controllerFactory) +} + +func (v *version) RkeK8sServiceOption() RkeK8sServiceOptionController { + return generic.NewController[*v3.RkeK8sServiceOption, *v3.RkeK8sServiceOptionList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "RkeK8sServiceOption"}, "rkek8sserviceoptions", true, v.controllerFactory) +} + +func (v *version) RkeK8sSystemImage() RkeK8sSystemImageController { + return generic.NewController[*v3.RkeK8sSystemImage, *v3.RkeK8sSystemImageList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "RkeK8sSystemImage"}, "rkek8ssystemimages", true, v.controllerFactory) +} + +func (v *version) RoleTemplate() RoleTemplateController { + return generic.NewNonNamespacedController[*v3.RoleTemplate, *v3.RoleTemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "RoleTemplate"}, "roletemplates", v.controllerFactory) +} + +func (v *version) SamlProvider() SamlProviderController { + return generic.NewNonNamespacedController[*v3.SamlProvider, *v3.SamlProviderList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "SamlProvider"}, "samlproviders", v.controllerFactory) +} + +func (v *version) SamlToken() SamlTokenController { + return generic.NewNonNamespacedController[*v3.SamlToken, *v3.SamlTokenList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "SamlToken"}, "samltokens", v.controllerFactory) +} + +func (v *version) Setting() SettingController { + return generic.NewNonNamespacedController[*v3.Setting, *v3.SettingList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Setting"}, "settings", v.controllerFactory) +} + +func (v *version) Template() TemplateController { + return generic.NewNonNamespacedController[*v3.Template, *v3.TemplateList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Template"}, "templates", v.controllerFactory) +} + +func (v *version) TemplateContent() TemplateContentController { + return generic.NewNonNamespacedController[*v3.TemplateContent, *v3.TemplateContentList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "TemplateContent"}, "templatecontents", v.controllerFactory) +} + +func (v *version) TemplateVersion() TemplateVersionController { + return generic.NewNonNamespacedController[*v3.TemplateVersion, *v3.TemplateVersionList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "TemplateVersion"}, "templateversions", v.controllerFactory) +} + +func (v *version) Token() TokenController { + return generic.NewNonNamespacedController[*v3.Token, *v3.TokenList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "Token"}, "tokens", v.controllerFactory) +} + +func (v *version) User() UserController { + return generic.NewNonNamespacedController[*v3.User, *v3.UserList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "User"}, "users", v.controllerFactory) +} + +func (v *version) UserAttribute() UserAttributeController { + return generic.NewNonNamespacedController[*v3.UserAttribute, *v3.UserAttributeList](schema.GroupVersionKind{Group: "management.cattle.io", Version: "v3", Kind: "UserAttribute"}, "userattributes", v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/kontainerdriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/kontainerdriver.go new file mode 100644 index 0000000..f216c45 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/kontainerdriver.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// KontainerDriverController interface for managing KontainerDriver resources. +type KontainerDriverController interface { + generic.NonNamespacedControllerInterface[*v3.KontainerDriver, *v3.KontainerDriverList] +} + +// KontainerDriverClient interface for managing KontainerDriver resources in Kubernetes. +type KontainerDriverClient interface { + generic.NonNamespacedClientInterface[*v3.KontainerDriver, *v3.KontainerDriverList] +} + +// KontainerDriverCache interface for retrieving KontainerDriver resources in memory. +type KontainerDriverCache interface { + generic.NonNamespacedCacheInterface[*v3.KontainerDriver] +} + +// KontainerDriverStatusHandler is executed for every added or modified KontainerDriver. Should return the new status to be updated +type KontainerDriverStatusHandler func(obj *v3.KontainerDriver, status v3.KontainerDriverStatus) (v3.KontainerDriverStatus, error) + +// KontainerDriverGeneratingHandler is the top-level handler that is executed for every KontainerDriver event. It extends KontainerDriverStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type KontainerDriverGeneratingHandler func(obj *v3.KontainerDriver, status v3.KontainerDriverStatus) ([]runtime.Object, v3.KontainerDriverStatus, error) + +// RegisterKontainerDriverStatusHandler configures a KontainerDriverController to execute a KontainerDriverStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterKontainerDriverStatusHandler(ctx context.Context, controller KontainerDriverController, condition condition.Cond, name string, handler KontainerDriverStatusHandler) { + statusHandler := &kontainerDriverStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterKontainerDriverGeneratingHandler configures a KontainerDriverController to execute a KontainerDriverGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterKontainerDriverGeneratingHandler(ctx context.Context, controller KontainerDriverController, apply apply.Apply, + condition condition.Cond, name string, handler KontainerDriverGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &kontainerDriverGeneratingHandler{ + KontainerDriverGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterKontainerDriverStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type kontainerDriverStatusHandler struct { + client KontainerDriverClient + condition condition.Cond + handler KontainerDriverStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *kontainerDriverStatusHandler) sync(key string, obj *v3.KontainerDriver) (*v3.KontainerDriver, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type kontainerDriverGeneratingHandler struct { + KontainerDriverGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *kontainerDriverGeneratingHandler) Remove(key string, obj *v3.KontainerDriver) (*v3.KontainerDriver, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.KontainerDriver{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured KontainerDriverGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *kontainerDriverGeneratingHandler) Handle(obj *v3.KontainerDriver, status v3.KontainerDriverStatus) (v3.KontainerDriverStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.KontainerDriverGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *kontainerDriverGeneratingHandler) isNewResourceVersion(obj *v3.KontainerDriver) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *kontainerDriverGeneratingHandler) storeResourceVersion(obj *v3.KontainerDriver) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/localprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/localprovider.go new file mode 100644 index 0000000..b5773d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/localprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// LocalProviderController interface for managing LocalProvider resources. +type LocalProviderController interface { + generic.NonNamespacedControllerInterface[*v3.LocalProvider, *v3.LocalProviderList] +} + +// LocalProviderClient interface for managing LocalProvider resources in Kubernetes. +type LocalProviderClient interface { + generic.NonNamespacedClientInterface[*v3.LocalProvider, *v3.LocalProviderList] +} + +// LocalProviderCache interface for retrieving LocalProvider resources in memory. +type LocalProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.LocalProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/managedchart.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/managedchart.go new file mode 100644 index 0000000..30b36cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/managedchart.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ManagedChartController interface for managing ManagedChart resources. +type ManagedChartController interface { + generic.ControllerInterface[*v3.ManagedChart, *v3.ManagedChartList] +} + +// ManagedChartClient interface for managing ManagedChart resources in Kubernetes. +type ManagedChartClient interface { + generic.ClientInterface[*v3.ManagedChart, *v3.ManagedChartList] +} + +// ManagedChartCache interface for retrieving ManagedChart resources in memory. +type ManagedChartCache interface { + generic.CacheInterface[*v3.ManagedChart] +} + +// ManagedChartStatusHandler is executed for every added or modified ManagedChart. Should return the new status to be updated +type ManagedChartStatusHandler func(obj *v3.ManagedChart, status v3.ManagedChartStatus) (v3.ManagedChartStatus, error) + +// ManagedChartGeneratingHandler is the top-level handler that is executed for every ManagedChart event. It extends ManagedChartStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ManagedChartGeneratingHandler func(obj *v3.ManagedChart, status v3.ManagedChartStatus) ([]runtime.Object, v3.ManagedChartStatus, error) + +// RegisterManagedChartStatusHandler configures a ManagedChartController to execute a ManagedChartStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterManagedChartStatusHandler(ctx context.Context, controller ManagedChartController, condition condition.Cond, name string, handler ManagedChartStatusHandler) { + statusHandler := &managedChartStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterManagedChartGeneratingHandler configures a ManagedChartController to execute a ManagedChartGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterManagedChartGeneratingHandler(ctx context.Context, controller ManagedChartController, apply apply.Apply, + condition condition.Cond, name string, handler ManagedChartGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &managedChartGeneratingHandler{ + ManagedChartGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterManagedChartStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type managedChartStatusHandler struct { + client ManagedChartClient + condition condition.Cond + handler ManagedChartStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *managedChartStatusHandler) sync(key string, obj *v3.ManagedChart) (*v3.ManagedChart, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type managedChartGeneratingHandler struct { + ManagedChartGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *managedChartGeneratingHandler) Remove(key string, obj *v3.ManagedChart) (*v3.ManagedChart, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ManagedChart{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ManagedChartGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *managedChartGeneratingHandler) Handle(obj *v3.ManagedChart, status v3.ManagedChartStatus) (v3.ManagedChartStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ManagedChartGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *managedChartGeneratingHandler) isNewResourceVersion(obj *v3.ManagedChart) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *managedChartGeneratingHandler) storeResourceVersion(obj *v3.ManagedChart) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapp.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapp.go new file mode 100644 index 0000000..457f496 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapp.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// MultiClusterAppController interface for managing MultiClusterApp resources. +type MultiClusterAppController interface { + generic.ControllerInterface[*v3.MultiClusterApp, *v3.MultiClusterAppList] +} + +// MultiClusterAppClient interface for managing MultiClusterApp resources in Kubernetes. +type MultiClusterAppClient interface { + generic.ClientInterface[*v3.MultiClusterApp, *v3.MultiClusterAppList] +} + +// MultiClusterAppCache interface for retrieving MultiClusterApp resources in memory. +type MultiClusterAppCache interface { + generic.CacheInterface[*v3.MultiClusterApp] +} + +// MultiClusterAppStatusHandler is executed for every added or modified MultiClusterApp. Should return the new status to be updated +type MultiClusterAppStatusHandler func(obj *v3.MultiClusterApp, status v3.MultiClusterAppStatus) (v3.MultiClusterAppStatus, error) + +// MultiClusterAppGeneratingHandler is the top-level handler that is executed for every MultiClusterApp event. It extends MultiClusterAppStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type MultiClusterAppGeneratingHandler func(obj *v3.MultiClusterApp, status v3.MultiClusterAppStatus) ([]runtime.Object, v3.MultiClusterAppStatus, error) + +// RegisterMultiClusterAppStatusHandler configures a MultiClusterAppController to execute a MultiClusterAppStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMultiClusterAppStatusHandler(ctx context.Context, controller MultiClusterAppController, condition condition.Cond, name string, handler MultiClusterAppStatusHandler) { + statusHandler := &multiClusterAppStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterMultiClusterAppGeneratingHandler configures a MultiClusterAppController to execute a MultiClusterAppGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterMultiClusterAppGeneratingHandler(ctx context.Context, controller MultiClusterAppController, apply apply.Apply, + condition condition.Cond, name string, handler MultiClusterAppGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &multiClusterAppGeneratingHandler{ + MultiClusterAppGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterMultiClusterAppStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type multiClusterAppStatusHandler struct { + client MultiClusterAppClient + condition condition.Cond + handler MultiClusterAppStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *multiClusterAppStatusHandler) sync(key string, obj *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type multiClusterAppGeneratingHandler struct { + MultiClusterAppGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *multiClusterAppGeneratingHandler) Remove(key string, obj *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.MultiClusterApp{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured MultiClusterAppGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *multiClusterAppGeneratingHandler) Handle(obj *v3.MultiClusterApp, status v3.MultiClusterAppStatus) (v3.MultiClusterAppStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.MultiClusterAppGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *multiClusterAppGeneratingHandler) isNewResourceVersion(obj *v3.MultiClusterApp) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *multiClusterAppGeneratingHandler) storeResourceVersion(obj *v3.MultiClusterApp) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapprevision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapprevision.go new file mode 100644 index 0000000..513434b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/multiclusterapprevision.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// MultiClusterAppRevisionController interface for managing MultiClusterAppRevision resources. +type MultiClusterAppRevisionController interface { + generic.ControllerInterface[*v3.MultiClusterAppRevision, *v3.MultiClusterAppRevisionList] +} + +// MultiClusterAppRevisionClient interface for managing MultiClusterAppRevision resources in Kubernetes. +type MultiClusterAppRevisionClient interface { + generic.ClientInterface[*v3.MultiClusterAppRevision, *v3.MultiClusterAppRevisionList] +} + +// MultiClusterAppRevisionCache interface for retrieving MultiClusterAppRevision resources in memory. +type MultiClusterAppRevisionCache interface { + generic.CacheInterface[*v3.MultiClusterAppRevision] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/node.go new file mode 100644 index 0000000..f16769e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/node.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NodeController interface for managing Node resources. +type NodeController interface { + generic.ControllerInterface[*v3.Node, *v3.NodeList] +} + +// NodeClient interface for managing Node resources in Kubernetes. +type NodeClient interface { + generic.ClientInterface[*v3.Node, *v3.NodeList] +} + +// NodeCache interface for retrieving Node resources in memory. +type NodeCache interface { + generic.CacheInterface[*v3.Node] +} + +// NodeStatusHandler is executed for every added or modified Node. Should return the new status to be updated +type NodeStatusHandler func(obj *v3.Node, status v3.NodeStatus) (v3.NodeStatus, error) + +// NodeGeneratingHandler is the top-level handler that is executed for every Node event. It extends NodeStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type NodeGeneratingHandler func(obj *v3.Node, status v3.NodeStatus) ([]runtime.Object, v3.NodeStatus, error) + +// RegisterNodeStatusHandler configures a NodeController to execute a NodeStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeStatusHandler(ctx context.Context, controller NodeController, condition condition.Cond, name string, handler NodeStatusHandler) { + statusHandler := &nodeStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterNodeGeneratingHandler configures a NodeController to execute a NodeGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeGeneratingHandler(ctx context.Context, controller NodeController, apply apply.Apply, + condition condition.Cond, name string, handler NodeGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &nodeGeneratingHandler{ + NodeGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterNodeStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type nodeStatusHandler struct { + client NodeClient + condition condition.Cond + handler NodeStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *nodeStatusHandler) sync(key string, obj *v3.Node) (*v3.Node, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type nodeGeneratingHandler struct { + NodeGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *nodeGeneratingHandler) Remove(key string, obj *v3.Node) (*v3.Node, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Node{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured NodeGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *nodeGeneratingHandler) Handle(obj *v3.Node, status v3.NodeStatus) (v3.NodeStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.NodeGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeGeneratingHandler) isNewResourceVersion(obj *v3.Node) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeGeneratingHandler) storeResourceVersion(obj *v3.Node) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodedriver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodedriver.go new file mode 100644 index 0000000..bfe6fdf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodedriver.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NodeDriverController interface for managing NodeDriver resources. +type NodeDriverController interface { + generic.NonNamespacedControllerInterface[*v3.NodeDriver, *v3.NodeDriverList] +} + +// NodeDriverClient interface for managing NodeDriver resources in Kubernetes. +type NodeDriverClient interface { + generic.NonNamespacedClientInterface[*v3.NodeDriver, *v3.NodeDriverList] +} + +// NodeDriverCache interface for retrieving NodeDriver resources in memory. +type NodeDriverCache interface { + generic.NonNamespacedCacheInterface[*v3.NodeDriver] +} + +// NodeDriverStatusHandler is executed for every added or modified NodeDriver. Should return the new status to be updated +type NodeDriverStatusHandler func(obj *v3.NodeDriver, status v3.NodeDriverStatus) (v3.NodeDriverStatus, error) + +// NodeDriverGeneratingHandler is the top-level handler that is executed for every NodeDriver event. It extends NodeDriverStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type NodeDriverGeneratingHandler func(obj *v3.NodeDriver, status v3.NodeDriverStatus) ([]runtime.Object, v3.NodeDriverStatus, error) + +// RegisterNodeDriverStatusHandler configures a NodeDriverController to execute a NodeDriverStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeDriverStatusHandler(ctx context.Context, controller NodeDriverController, condition condition.Cond, name string, handler NodeDriverStatusHandler) { + statusHandler := &nodeDriverStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterNodeDriverGeneratingHandler configures a NodeDriverController to execute a NodeDriverGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeDriverGeneratingHandler(ctx context.Context, controller NodeDriverController, apply apply.Apply, + condition condition.Cond, name string, handler NodeDriverGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &nodeDriverGeneratingHandler{ + NodeDriverGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterNodeDriverStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type nodeDriverStatusHandler struct { + client NodeDriverClient + condition condition.Cond + handler NodeDriverStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *nodeDriverStatusHandler) sync(key string, obj *v3.NodeDriver) (*v3.NodeDriver, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type nodeDriverGeneratingHandler struct { + NodeDriverGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *nodeDriverGeneratingHandler) Remove(key string, obj *v3.NodeDriver) (*v3.NodeDriver, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.NodeDriver{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured NodeDriverGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *nodeDriverGeneratingHandler) Handle(obj *v3.NodeDriver, status v3.NodeDriverStatus) (v3.NodeDriverStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.NodeDriverGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeDriverGeneratingHandler) isNewResourceVersion(obj *v3.NodeDriver) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeDriverGeneratingHandler) storeResourceVersion(obj *v3.NodeDriver) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodepool.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodepool.go new file mode 100644 index 0000000..8397767 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodepool.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NodePoolController interface for managing NodePool resources. +type NodePoolController interface { + generic.ControllerInterface[*v3.NodePool, *v3.NodePoolList] +} + +// NodePoolClient interface for managing NodePool resources in Kubernetes. +type NodePoolClient interface { + generic.ClientInterface[*v3.NodePool, *v3.NodePoolList] +} + +// NodePoolCache interface for retrieving NodePool resources in memory. +type NodePoolCache interface { + generic.CacheInterface[*v3.NodePool] +} + +// NodePoolStatusHandler is executed for every added or modified NodePool. Should return the new status to be updated +type NodePoolStatusHandler func(obj *v3.NodePool, status v3.NodePoolStatus) (v3.NodePoolStatus, error) + +// NodePoolGeneratingHandler is the top-level handler that is executed for every NodePool event. It extends NodePoolStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type NodePoolGeneratingHandler func(obj *v3.NodePool, status v3.NodePoolStatus) ([]runtime.Object, v3.NodePoolStatus, error) + +// RegisterNodePoolStatusHandler configures a NodePoolController to execute a NodePoolStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodePoolStatusHandler(ctx context.Context, controller NodePoolController, condition condition.Cond, name string, handler NodePoolStatusHandler) { + statusHandler := &nodePoolStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterNodePoolGeneratingHandler configures a NodePoolController to execute a NodePoolGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodePoolGeneratingHandler(ctx context.Context, controller NodePoolController, apply apply.Apply, + condition condition.Cond, name string, handler NodePoolGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &nodePoolGeneratingHandler{ + NodePoolGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterNodePoolStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type nodePoolStatusHandler struct { + client NodePoolClient + condition condition.Cond + handler NodePoolStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *nodePoolStatusHandler) sync(key string, obj *v3.NodePool) (*v3.NodePool, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type nodePoolGeneratingHandler struct { + NodePoolGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *nodePoolGeneratingHandler) Remove(key string, obj *v3.NodePool) (*v3.NodePool, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.NodePool{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured NodePoolGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *nodePoolGeneratingHandler) Handle(obj *v3.NodePool, status v3.NodePoolStatus) (v3.NodePoolStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.NodePoolGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodePoolGeneratingHandler) isNewResourceVersion(obj *v3.NodePool) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodePoolGeneratingHandler) storeResourceVersion(obj *v3.NodePool) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodetemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodetemplate.go new file mode 100644 index 0000000..eee26a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/nodetemplate.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// NodeTemplateController interface for managing NodeTemplate resources. +type NodeTemplateController interface { + generic.ControllerInterface[*v3.NodeTemplate, *v3.NodeTemplateList] +} + +// NodeTemplateClient interface for managing NodeTemplate resources in Kubernetes. +type NodeTemplateClient interface { + generic.ClientInterface[*v3.NodeTemplate, *v3.NodeTemplateList] +} + +// NodeTemplateCache interface for retrieving NodeTemplate resources in memory. +type NodeTemplateCache interface { + generic.CacheInterface[*v3.NodeTemplate] +} + +// NodeTemplateStatusHandler is executed for every added or modified NodeTemplate. Should return the new status to be updated +type NodeTemplateStatusHandler func(obj *v3.NodeTemplate, status v3.NodeTemplateStatus) (v3.NodeTemplateStatus, error) + +// NodeTemplateGeneratingHandler is the top-level handler that is executed for every NodeTemplate event. It extends NodeTemplateStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type NodeTemplateGeneratingHandler func(obj *v3.NodeTemplate, status v3.NodeTemplateStatus) ([]runtime.Object, v3.NodeTemplateStatus, error) + +// RegisterNodeTemplateStatusHandler configures a NodeTemplateController to execute a NodeTemplateStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeTemplateStatusHandler(ctx context.Context, controller NodeTemplateController, condition condition.Cond, name string, handler NodeTemplateStatusHandler) { + statusHandler := &nodeTemplateStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterNodeTemplateGeneratingHandler configures a NodeTemplateController to execute a NodeTemplateGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterNodeTemplateGeneratingHandler(ctx context.Context, controller NodeTemplateController, apply apply.Apply, + condition condition.Cond, name string, handler NodeTemplateGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &nodeTemplateGeneratingHandler{ + NodeTemplateGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterNodeTemplateStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type nodeTemplateStatusHandler struct { + client NodeTemplateClient + condition condition.Cond + handler NodeTemplateStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *nodeTemplateStatusHandler) sync(key string, obj *v3.NodeTemplate) (*v3.NodeTemplate, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type nodeTemplateGeneratingHandler struct { + NodeTemplateGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *nodeTemplateGeneratingHandler) Remove(key string, obj *v3.NodeTemplate) (*v3.NodeTemplate, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.NodeTemplate{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured NodeTemplateGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *nodeTemplateGeneratingHandler) Handle(obj *v3.NodeTemplate, status v3.NodeTemplateStatus) (v3.NodeTemplateStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.NodeTemplateGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeTemplateGeneratingHandler) isNewResourceVersion(obj *v3.NodeTemplate) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *nodeTemplateGeneratingHandler) storeResourceVersion(obj *v3.NodeTemplate) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/oidcprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/oidcprovider.go new file mode 100644 index 0000000..c5bd8d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/oidcprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// OIDCProviderController interface for managing OIDCProvider resources. +type OIDCProviderController interface { + generic.NonNamespacedControllerInterface[*v3.OIDCProvider, *v3.OIDCProviderList] +} + +// OIDCProviderClient interface for managing OIDCProvider resources in Kubernetes. +type OIDCProviderClient interface { + generic.NonNamespacedClientInterface[*v3.OIDCProvider, *v3.OIDCProviderList] +} + +// OIDCProviderCache interface for retrieving OIDCProvider resources in memory. +type OIDCProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.OIDCProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/openldapprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/openldapprovider.go new file mode 100644 index 0000000..e179ba5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/openldapprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// OpenLdapProviderController interface for managing OpenLdapProvider resources. +type OpenLdapProviderController interface { + generic.NonNamespacedControllerInterface[*v3.OpenLdapProvider, *v3.OpenLdapProviderList] +} + +// OpenLdapProviderClient interface for managing OpenLdapProvider resources in Kubernetes. +type OpenLdapProviderClient interface { + generic.NonNamespacedClientInterface[*v3.OpenLdapProvider, *v3.OpenLdapProviderList] +} + +// OpenLdapProviderCache interface for retrieving OpenLdapProvider resources in memory. +type OpenLdapProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.OpenLdapProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/podsecurityadmissionconfigurationtemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/podsecurityadmissionconfigurationtemplate.go new file mode 100644 index 0000000..94b1e66 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/podsecurityadmissionconfigurationtemplate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// PodSecurityAdmissionConfigurationTemplateController interface for managing PodSecurityAdmissionConfigurationTemplate resources. +type PodSecurityAdmissionConfigurationTemplateController interface { + generic.NonNamespacedControllerInterface[*v3.PodSecurityAdmissionConfigurationTemplate, *v3.PodSecurityAdmissionConfigurationTemplateList] +} + +// PodSecurityAdmissionConfigurationTemplateClient interface for managing PodSecurityAdmissionConfigurationTemplate resources in Kubernetes. +type PodSecurityAdmissionConfigurationTemplateClient interface { + generic.NonNamespacedClientInterface[*v3.PodSecurityAdmissionConfigurationTemplate, *v3.PodSecurityAdmissionConfigurationTemplateList] +} + +// PodSecurityAdmissionConfigurationTemplateCache interface for retrieving PodSecurityAdmissionConfigurationTemplate resources in memory. +type PodSecurityAdmissionConfigurationTemplateCache interface { + generic.NonNamespacedCacheInterface[*v3.PodSecurityAdmissionConfigurationTemplate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/preference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/preference.go new file mode 100644 index 0000000..731434f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/preference.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// PreferenceController interface for managing Preference resources. +type PreferenceController interface { + generic.ControllerInterface[*v3.Preference, *v3.PreferenceList] +} + +// PreferenceClient interface for managing Preference resources in Kubernetes. +type PreferenceClient interface { + generic.ClientInterface[*v3.Preference, *v3.PreferenceList] +} + +// PreferenceCache interface for retrieving Preference resources in memory. +type PreferenceCache interface { + generic.CacheInterface[*v3.Preference] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/principal.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/principal.go new file mode 100644 index 0000000..d7957bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/principal.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// PrincipalController interface for managing Principal resources. +type PrincipalController interface { + generic.NonNamespacedControllerInterface[*v3.Principal, *v3.PrincipalList] +} + +// PrincipalClient interface for managing Principal resources in Kubernetes. +type PrincipalClient interface { + generic.NonNamespacedClientInterface[*v3.Principal, *v3.PrincipalList] +} + +// PrincipalCache interface for retrieving Principal resources in memory. +type PrincipalCache interface { + generic.NonNamespacedCacheInterface[*v3.Principal] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/project.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/project.go new file mode 100644 index 0000000..ad56aab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/project.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ProjectController interface for managing Project resources. +type ProjectController interface { + generic.ControllerInterface[*v3.Project, *v3.ProjectList] +} + +// ProjectClient interface for managing Project resources in Kubernetes. +type ProjectClient interface { + generic.ClientInterface[*v3.Project, *v3.ProjectList] +} + +// ProjectCache interface for retrieving Project resources in memory. +type ProjectCache interface { + generic.CacheInterface[*v3.Project] +} + +// ProjectStatusHandler is executed for every added or modified Project. Should return the new status to be updated +type ProjectStatusHandler func(obj *v3.Project, status v3.ProjectStatus) (v3.ProjectStatus, error) + +// ProjectGeneratingHandler is the top-level handler that is executed for every Project event. It extends ProjectStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ProjectGeneratingHandler func(obj *v3.Project, status v3.ProjectStatus) ([]runtime.Object, v3.ProjectStatus, error) + +// RegisterProjectStatusHandler configures a ProjectController to execute a ProjectStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterProjectStatusHandler(ctx context.Context, controller ProjectController, condition condition.Cond, name string, handler ProjectStatusHandler) { + statusHandler := &projectStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterProjectGeneratingHandler configures a ProjectController to execute a ProjectGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterProjectGeneratingHandler(ctx context.Context, controller ProjectController, apply apply.Apply, + condition condition.Cond, name string, handler ProjectGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &projectGeneratingHandler{ + ProjectGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterProjectStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type projectStatusHandler struct { + client ProjectClient + condition condition.Cond + handler ProjectStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *projectStatusHandler) sync(key string, obj *v3.Project) (*v3.Project, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type projectGeneratingHandler struct { + ProjectGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *projectGeneratingHandler) Remove(key string, obj *v3.Project) (*v3.Project, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Project{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ProjectGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *projectGeneratingHandler) Handle(obj *v3.Project, status v3.ProjectStatus) (v3.ProjectStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ProjectGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *projectGeneratingHandler) isNewResourceVersion(obj *v3.Project) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *projectGeneratingHandler) storeResourceVersion(obj *v3.Project) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectcatalog.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectcatalog.go new file mode 100644 index 0000000..41a3a10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectcatalog.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ProjectCatalogController interface for managing ProjectCatalog resources. +type ProjectCatalogController interface { + generic.ControllerInterface[*v3.ProjectCatalog, *v3.ProjectCatalogList] +} + +// ProjectCatalogClient interface for managing ProjectCatalog resources in Kubernetes. +type ProjectCatalogClient interface { + generic.ClientInterface[*v3.ProjectCatalog, *v3.ProjectCatalogList] +} + +// ProjectCatalogCache interface for retrieving ProjectCatalog resources in memory. +type ProjectCatalogCache interface { + generic.CacheInterface[*v3.ProjectCatalog] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectlogging.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectlogging.go new file mode 100644 index 0000000..b5c6629 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectlogging.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ProjectLoggingController interface for managing ProjectLogging resources. +type ProjectLoggingController interface { + generic.ControllerInterface[*v3.ProjectLogging, *v3.ProjectLoggingList] +} + +// ProjectLoggingClient interface for managing ProjectLogging resources in Kubernetes. +type ProjectLoggingClient interface { + generic.ClientInterface[*v3.ProjectLogging, *v3.ProjectLoggingList] +} + +// ProjectLoggingCache interface for retrieving ProjectLogging resources in memory. +type ProjectLoggingCache interface { + generic.CacheInterface[*v3.ProjectLogging] +} + +// ProjectLoggingStatusHandler is executed for every added or modified ProjectLogging. Should return the new status to be updated +type ProjectLoggingStatusHandler func(obj *v3.ProjectLogging, status v3.ProjectLoggingStatus) (v3.ProjectLoggingStatus, error) + +// ProjectLoggingGeneratingHandler is the top-level handler that is executed for every ProjectLogging event. It extends ProjectLoggingStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ProjectLoggingGeneratingHandler func(obj *v3.ProjectLogging, status v3.ProjectLoggingStatus) ([]runtime.Object, v3.ProjectLoggingStatus, error) + +// RegisterProjectLoggingStatusHandler configures a ProjectLoggingController to execute a ProjectLoggingStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterProjectLoggingStatusHandler(ctx context.Context, controller ProjectLoggingController, condition condition.Cond, name string, handler ProjectLoggingStatusHandler) { + statusHandler := &projectLoggingStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterProjectLoggingGeneratingHandler configures a ProjectLoggingController to execute a ProjectLoggingGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterProjectLoggingGeneratingHandler(ctx context.Context, controller ProjectLoggingController, apply apply.Apply, + condition condition.Cond, name string, handler ProjectLoggingGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &projectLoggingGeneratingHandler{ + ProjectLoggingGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterProjectLoggingStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type projectLoggingStatusHandler struct { + client ProjectLoggingClient + condition condition.Cond + handler ProjectLoggingStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *projectLoggingStatusHandler) sync(key string, obj *v3.ProjectLogging) (*v3.ProjectLogging, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type projectLoggingGeneratingHandler struct { + ProjectLoggingGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *projectLoggingGeneratingHandler) Remove(key string, obj *v3.ProjectLogging) (*v3.ProjectLogging, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.ProjectLogging{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ProjectLoggingGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *projectLoggingGeneratingHandler) Handle(obj *v3.ProjectLogging, status v3.ProjectLoggingStatus) (v3.ProjectLoggingStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ProjectLoggingGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *projectLoggingGeneratingHandler) isNewResourceVersion(obj *v3.ProjectLogging) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *projectLoggingGeneratingHandler) storeResourceVersion(obj *v3.ProjectLogging) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectnetworkpolicy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectnetworkpolicy.go new file mode 100644 index 0000000..2e1fa31 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectnetworkpolicy.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ProjectNetworkPolicyController interface for managing ProjectNetworkPolicy resources. +type ProjectNetworkPolicyController interface { + generic.ControllerInterface[*v3.ProjectNetworkPolicy, *v3.ProjectNetworkPolicyList] +} + +// ProjectNetworkPolicyClient interface for managing ProjectNetworkPolicy resources in Kubernetes. +type ProjectNetworkPolicyClient interface { + generic.ClientInterface[*v3.ProjectNetworkPolicy, *v3.ProjectNetworkPolicyList] +} + +// ProjectNetworkPolicyCache interface for retrieving ProjectNetworkPolicy resources in memory. +type ProjectNetworkPolicyCache interface { + generic.CacheInterface[*v3.ProjectNetworkPolicy] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectroletemplatebinding.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectroletemplatebinding.go new file mode 100644 index 0000000..20f81a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/projectroletemplatebinding.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ProjectRoleTemplateBindingController interface for managing ProjectRoleTemplateBinding resources. +type ProjectRoleTemplateBindingController interface { + generic.ControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList] +} + +// ProjectRoleTemplateBindingClient interface for managing ProjectRoleTemplateBinding resources in Kubernetes. +type ProjectRoleTemplateBindingClient interface { + generic.ClientInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList] +} + +// ProjectRoleTemplateBindingCache interface for retrieving ProjectRoleTemplateBinding resources in memory. +type ProjectRoleTemplateBindingCache interface { + generic.CacheInterface[*v3.ProjectRoleTemplateBinding] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rancherusernotification.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rancherusernotification.go new file mode 100644 index 0000000..ef3814d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rancherusernotification.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RancherUserNotificationController interface for managing RancherUserNotification resources. +type RancherUserNotificationController interface { + generic.NonNamespacedControllerInterface[*v3.RancherUserNotification, *v3.RancherUserNotificationList] +} + +// RancherUserNotificationClient interface for managing RancherUserNotification resources in Kubernetes. +type RancherUserNotificationClient interface { + generic.NonNamespacedClientInterface[*v3.RancherUserNotification, *v3.RancherUserNotificationList] +} + +// RancherUserNotificationCache interface for retrieving RancherUserNotification resources in memory. +type RancherUserNotificationCache interface { + generic.NonNamespacedCacheInterface[*v3.RancherUserNotification] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkeaddon.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkeaddon.go new file mode 100644 index 0000000..92a4ca2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkeaddon.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RkeAddonController interface for managing RkeAddon resources. +type RkeAddonController interface { + generic.ControllerInterface[*v3.RkeAddon, *v3.RkeAddonList] +} + +// RkeAddonClient interface for managing RkeAddon resources in Kubernetes. +type RkeAddonClient interface { + generic.ClientInterface[*v3.RkeAddon, *v3.RkeAddonList] +} + +// RkeAddonCache interface for retrieving RkeAddon resources in memory. +type RkeAddonCache interface { + generic.CacheInterface[*v3.RkeAddon] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8sserviceoption.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8sserviceoption.go new file mode 100644 index 0000000..4c3cd25 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8sserviceoption.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RkeK8sServiceOptionController interface for managing RkeK8sServiceOption resources. +type RkeK8sServiceOptionController interface { + generic.ControllerInterface[*v3.RkeK8sServiceOption, *v3.RkeK8sServiceOptionList] +} + +// RkeK8sServiceOptionClient interface for managing RkeK8sServiceOption resources in Kubernetes. +type RkeK8sServiceOptionClient interface { + generic.ClientInterface[*v3.RkeK8sServiceOption, *v3.RkeK8sServiceOptionList] +} + +// RkeK8sServiceOptionCache interface for retrieving RkeK8sServiceOption resources in memory. +type RkeK8sServiceOptionCache interface { + generic.CacheInterface[*v3.RkeK8sServiceOption] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8ssystemimage.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8ssystemimage.go new file mode 100644 index 0000000..a58e703 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/rkek8ssystemimage.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RkeK8sSystemImageController interface for managing RkeK8sSystemImage resources. +type RkeK8sSystemImageController interface { + generic.ControllerInterface[*v3.RkeK8sSystemImage, *v3.RkeK8sSystemImageList] +} + +// RkeK8sSystemImageClient interface for managing RkeK8sSystemImage resources in Kubernetes. +type RkeK8sSystemImageClient interface { + generic.ClientInterface[*v3.RkeK8sSystemImage, *v3.RkeK8sSystemImageList] +} + +// RkeK8sSystemImageCache interface for retrieving RkeK8sSystemImage resources in memory. +type RkeK8sSystemImageCache interface { + generic.CacheInterface[*v3.RkeK8sSystemImage] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/roletemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/roletemplate.go new file mode 100644 index 0000000..ed7fd54 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/roletemplate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RoleTemplateController interface for managing RoleTemplate resources. +type RoleTemplateController interface { + generic.NonNamespacedControllerInterface[*v3.RoleTemplate, *v3.RoleTemplateList] +} + +// RoleTemplateClient interface for managing RoleTemplate resources in Kubernetes. +type RoleTemplateClient interface { + generic.NonNamespacedClientInterface[*v3.RoleTemplate, *v3.RoleTemplateList] +} + +// RoleTemplateCache interface for retrieving RoleTemplate resources in memory. +type RoleTemplateCache interface { + generic.NonNamespacedCacheInterface[*v3.RoleTemplate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samlprovider.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samlprovider.go new file mode 100644 index 0000000..1a3045f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samlprovider.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// SamlProviderController interface for managing SamlProvider resources. +type SamlProviderController interface { + generic.NonNamespacedControllerInterface[*v3.SamlProvider, *v3.SamlProviderList] +} + +// SamlProviderClient interface for managing SamlProvider resources in Kubernetes. +type SamlProviderClient interface { + generic.NonNamespacedClientInterface[*v3.SamlProvider, *v3.SamlProviderList] +} + +// SamlProviderCache interface for retrieving SamlProvider resources in memory. +type SamlProviderCache interface { + generic.NonNamespacedCacheInterface[*v3.SamlProvider] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samltoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samltoken.go new file mode 100644 index 0000000..f4a0cc7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/samltoken.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// SamlTokenController interface for managing SamlToken resources. +type SamlTokenController interface { + generic.NonNamespacedControllerInterface[*v3.SamlToken, *v3.SamlTokenList] +} + +// SamlTokenClient interface for managing SamlToken resources in Kubernetes. +type SamlTokenClient interface { + generic.NonNamespacedClientInterface[*v3.SamlToken, *v3.SamlTokenList] +} + +// SamlTokenCache interface for retrieving SamlToken resources in memory. +type SamlTokenCache interface { + generic.NonNamespacedCacheInterface[*v3.SamlToken] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/setting.go new file mode 100644 index 0000000..75fec1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/setting.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// SettingController interface for managing Setting resources. +type SettingController interface { + generic.NonNamespacedControllerInterface[*v3.Setting, *v3.SettingList] +} + +// SettingClient interface for managing Setting resources in Kubernetes. +type SettingClient interface { + generic.NonNamespacedClientInterface[*v3.Setting, *v3.SettingList] +} + +// SettingCache interface for retrieving Setting resources in memory. +type SettingCache interface { + generic.NonNamespacedCacheInterface[*v3.Setting] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/template.go new file mode 100644 index 0000000..0dc4c5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/template.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// TemplateController interface for managing Template resources. +type TemplateController interface { + generic.NonNamespacedControllerInterface[*v3.Template, *v3.TemplateList] +} + +// TemplateClient interface for managing Template resources in Kubernetes. +type TemplateClient interface { + generic.NonNamespacedClientInterface[*v3.Template, *v3.TemplateList] +} + +// TemplateCache interface for retrieving Template resources in memory. +type TemplateCache interface { + generic.NonNamespacedCacheInterface[*v3.Template] +} + +// TemplateStatusHandler is executed for every added or modified Template. Should return the new status to be updated +type TemplateStatusHandler func(obj *v3.Template, status v3.TemplateStatus) (v3.TemplateStatus, error) + +// TemplateGeneratingHandler is the top-level handler that is executed for every Template event. It extends TemplateStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type TemplateGeneratingHandler func(obj *v3.Template, status v3.TemplateStatus) ([]runtime.Object, v3.TemplateStatus, error) + +// RegisterTemplateStatusHandler configures a TemplateController to execute a TemplateStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterTemplateStatusHandler(ctx context.Context, controller TemplateController, condition condition.Cond, name string, handler TemplateStatusHandler) { + statusHandler := &templateStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterTemplateGeneratingHandler configures a TemplateController to execute a TemplateGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterTemplateGeneratingHandler(ctx context.Context, controller TemplateController, apply apply.Apply, + condition condition.Cond, name string, handler TemplateGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &templateGeneratingHandler{ + TemplateGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterTemplateStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type templateStatusHandler struct { + client TemplateClient + condition condition.Cond + handler TemplateStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *templateStatusHandler) sync(key string, obj *v3.Template) (*v3.Template, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type templateGeneratingHandler struct { + TemplateGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *templateGeneratingHandler) Remove(key string, obj *v3.Template) (*v3.Template, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.Template{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured TemplateGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *templateGeneratingHandler) Handle(obj *v3.Template, status v3.TemplateStatus) (v3.TemplateStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.TemplateGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *templateGeneratingHandler) isNewResourceVersion(obj *v3.Template) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *templateGeneratingHandler) storeResourceVersion(obj *v3.Template) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templatecontent.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templatecontent.go new file mode 100644 index 0000000..4d50620 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templatecontent.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// TemplateContentController interface for managing TemplateContent resources. +type TemplateContentController interface { + generic.NonNamespacedControllerInterface[*v3.TemplateContent, *v3.TemplateContentList] +} + +// TemplateContentClient interface for managing TemplateContent resources in Kubernetes. +type TemplateContentClient interface { + generic.NonNamespacedClientInterface[*v3.TemplateContent, *v3.TemplateContentList] +} + +// TemplateContentCache interface for retrieving TemplateContent resources in memory. +type TemplateContentCache interface { + generic.NonNamespacedCacheInterface[*v3.TemplateContent] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templateversion.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templateversion.go new file mode 100644 index 0000000..7bbb439 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/templateversion.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// TemplateVersionController interface for managing TemplateVersion resources. +type TemplateVersionController interface { + generic.NonNamespacedControllerInterface[*v3.TemplateVersion, *v3.TemplateVersionList] +} + +// TemplateVersionClient interface for managing TemplateVersion resources in Kubernetes. +type TemplateVersionClient interface { + generic.NonNamespacedClientInterface[*v3.TemplateVersion, *v3.TemplateVersionList] +} + +// TemplateVersionCache interface for retrieving TemplateVersion resources in memory. +type TemplateVersionCache interface { + generic.NonNamespacedCacheInterface[*v3.TemplateVersion] +} + +// TemplateVersionStatusHandler is executed for every added or modified TemplateVersion. Should return the new status to be updated +type TemplateVersionStatusHandler func(obj *v3.TemplateVersion, status v3.TemplateVersionStatus) (v3.TemplateVersionStatus, error) + +// TemplateVersionGeneratingHandler is the top-level handler that is executed for every TemplateVersion event. It extends TemplateVersionStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type TemplateVersionGeneratingHandler func(obj *v3.TemplateVersion, status v3.TemplateVersionStatus) ([]runtime.Object, v3.TemplateVersionStatus, error) + +// RegisterTemplateVersionStatusHandler configures a TemplateVersionController to execute a TemplateVersionStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterTemplateVersionStatusHandler(ctx context.Context, controller TemplateVersionController, condition condition.Cond, name string, handler TemplateVersionStatusHandler) { + statusHandler := &templateVersionStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterTemplateVersionGeneratingHandler configures a TemplateVersionController to execute a TemplateVersionGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterTemplateVersionGeneratingHandler(ctx context.Context, controller TemplateVersionController, apply apply.Apply, + condition condition.Cond, name string, handler TemplateVersionGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &templateVersionGeneratingHandler{ + TemplateVersionGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterTemplateVersionStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type templateVersionStatusHandler struct { + client TemplateVersionClient + condition condition.Cond + handler TemplateVersionStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *templateVersionStatusHandler) sync(key string, obj *v3.TemplateVersion) (*v3.TemplateVersion, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type templateVersionGeneratingHandler struct { + TemplateVersionGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *templateVersionGeneratingHandler) Remove(key string, obj *v3.TemplateVersion) (*v3.TemplateVersion, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.TemplateVersion{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured TemplateVersionGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *templateVersionGeneratingHandler) Handle(obj *v3.TemplateVersion, status v3.TemplateVersionStatus) (v3.TemplateVersionStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.TemplateVersionGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *templateVersionGeneratingHandler) isNewResourceVersion(obj *v3.TemplateVersion) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *templateVersionGeneratingHandler) storeResourceVersion(obj *v3.TemplateVersion) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/token.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/token.go new file mode 100644 index 0000000..f87d89a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/token.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// TokenController interface for managing Token resources. +type TokenController interface { + generic.NonNamespacedControllerInterface[*v3.Token, *v3.TokenList] +} + +// TokenClient interface for managing Token resources in Kubernetes. +type TokenClient interface { + generic.NonNamespacedClientInterface[*v3.Token, *v3.TokenList] +} + +// TokenCache interface for retrieving Token resources in memory. +type TokenCache interface { + generic.NonNamespacedCacheInterface[*v3.Token] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/user.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/user.go new file mode 100644 index 0000000..81cb26f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/user.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// UserController interface for managing User resources. +type UserController interface { + generic.NonNamespacedControllerInterface[*v3.User, *v3.UserList] +} + +// UserClient interface for managing User resources in Kubernetes. +type UserClient interface { + generic.NonNamespacedClientInterface[*v3.User, *v3.UserList] +} + +// UserCache interface for retrieving User resources in memory. +type UserCache interface { + generic.NonNamespacedCacheInterface[*v3.User] +} + +// UserStatusHandler is executed for every added or modified User. Should return the new status to be updated +type UserStatusHandler func(obj *v3.User, status v3.UserStatus) (v3.UserStatus, error) + +// UserGeneratingHandler is the top-level handler that is executed for every User event. It extends UserStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type UserGeneratingHandler func(obj *v3.User, status v3.UserStatus) ([]runtime.Object, v3.UserStatus, error) + +// RegisterUserStatusHandler configures a UserController to execute a UserStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterUserStatusHandler(ctx context.Context, controller UserController, condition condition.Cond, name string, handler UserStatusHandler) { + statusHandler := &userStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterUserGeneratingHandler configures a UserController to execute a UserGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterUserGeneratingHandler(ctx context.Context, controller UserController, apply apply.Apply, + condition condition.Cond, name string, handler UserGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &userGeneratingHandler{ + UserGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterUserStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type userStatusHandler struct { + client UserClient + condition condition.Cond + handler UserStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *userStatusHandler) sync(key string, obj *v3.User) (*v3.User, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type userGeneratingHandler struct { + UserGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *userGeneratingHandler) Remove(key string, obj *v3.User) (*v3.User, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.User{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured UserGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *userGeneratingHandler) Handle(obj *v3.User, status v3.UserStatus) (v3.UserStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.UserGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *userGeneratingHandler) isNewResourceVersion(obj *v3.User) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *userGeneratingHandler) storeResourceVersion(obj *v3.User) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/userattribute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/userattribute.go new file mode 100644 index 0000000..5a9b35c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/management.cattle.io/v3/userattribute.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// UserAttributeController interface for managing UserAttribute resources. +type UserAttributeController interface { + generic.NonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList] +} + +// UserAttributeClient interface for managing UserAttribute resources in Kubernetes. +type UserAttributeClient interface { + generic.NonNamespacedClientInterface[*v3.UserAttribute, *v3.UserAttributeList] +} + +// UserAttributeCache interface for retrieving UserAttribute resources in memory. +type UserAttributeCache interface { + generic.NonNamespacedCacheInterface[*v3.UserAttribute] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/factory.go new file mode 100644 index 0000000..6d77d46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package project + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Project() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/interface.go new file mode 100644 index 0000000..7584a20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package project + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/generated/controllers/project.cattle.io/v3" +) + +type Interface interface { + V3() v3.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V3() v3.Interface { + return v3.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/app.go new file mode 100644 index 0000000..c127d91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/app.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// AppController interface for managing App resources. +type AppController interface { + generic.ControllerInterface[*v3.App, *v3.AppList] +} + +// AppClient interface for managing App resources in Kubernetes. +type AppClient interface { + generic.ClientInterface[*v3.App, *v3.AppList] +} + +// AppCache interface for retrieving App resources in memory. +type AppCache interface { + generic.CacheInterface[*v3.App] +} + +// AppStatusHandler is executed for every added or modified App. Should return the new status to be updated +type AppStatusHandler func(obj *v3.App, status v3.AppStatus) (v3.AppStatus, error) + +// AppGeneratingHandler is the top-level handler that is executed for every App event. It extends AppStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type AppGeneratingHandler func(obj *v3.App, status v3.AppStatus) ([]runtime.Object, v3.AppStatus, error) + +// RegisterAppStatusHandler configures a AppController to execute a AppStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppStatusHandler(ctx context.Context, controller AppController, condition condition.Cond, name string, handler AppStatusHandler) { + statusHandler := &appStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterAppGeneratingHandler configures a AppController to execute a AppGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppGeneratingHandler(ctx context.Context, controller AppController, apply apply.Apply, + condition condition.Cond, name string, handler AppGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &appGeneratingHandler{ + AppGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterAppStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type appStatusHandler struct { + client AppClient + condition condition.Cond + handler AppStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *appStatusHandler) sync(key string, obj *v3.App) (*v3.App, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type appGeneratingHandler struct { + AppGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *appGeneratingHandler) Remove(key string, obj *v3.App) (*v3.App, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.App{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured AppGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *appGeneratingHandler) Handle(obj *v3.App, status v3.AppStatus) (v3.AppStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.AppGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appGeneratingHandler) isNewResourceVersion(obj *v3.App) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appGeneratingHandler) storeResourceVersion(obj *v3.App) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/apprevision.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/apprevision.go new file mode 100644 index 0000000..27be37d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/apprevision.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "context" + "sync" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// AppRevisionController interface for managing AppRevision resources. +type AppRevisionController interface { + generic.ControllerInterface[*v3.AppRevision, *v3.AppRevisionList] +} + +// AppRevisionClient interface for managing AppRevision resources in Kubernetes. +type AppRevisionClient interface { + generic.ClientInterface[*v3.AppRevision, *v3.AppRevisionList] +} + +// AppRevisionCache interface for retrieving AppRevision resources in memory. +type AppRevisionCache interface { + generic.CacheInterface[*v3.AppRevision] +} + +// AppRevisionStatusHandler is executed for every added or modified AppRevision. Should return the new status to be updated +type AppRevisionStatusHandler func(obj *v3.AppRevision, status v3.AppRevisionStatus) (v3.AppRevisionStatus, error) + +// AppRevisionGeneratingHandler is the top-level handler that is executed for every AppRevision event. It extends AppRevisionStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type AppRevisionGeneratingHandler func(obj *v3.AppRevision, status v3.AppRevisionStatus) ([]runtime.Object, v3.AppRevisionStatus, error) + +// RegisterAppRevisionStatusHandler configures a AppRevisionController to execute a AppRevisionStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppRevisionStatusHandler(ctx context.Context, controller AppRevisionController, condition condition.Cond, name string, handler AppRevisionStatusHandler) { + statusHandler := &appRevisionStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterAppRevisionGeneratingHandler configures a AppRevisionController to execute a AppRevisionGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterAppRevisionGeneratingHandler(ctx context.Context, controller AppRevisionController, apply apply.Apply, + condition condition.Cond, name string, handler AppRevisionGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &appRevisionGeneratingHandler{ + AppRevisionGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterAppRevisionStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type appRevisionStatusHandler struct { + client AppRevisionClient + condition condition.Cond + handler AppRevisionStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *appRevisionStatusHandler) sync(key string, obj *v3.AppRevision) (*v3.AppRevision, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type appRevisionGeneratingHandler struct { + AppRevisionGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *appRevisionGeneratingHandler) Remove(key string, obj *v3.AppRevision) (*v3.AppRevision, error) { + if obj != nil { + return obj, nil + } + + obj = &v3.AppRevision{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured AppRevisionGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *appRevisionGeneratingHandler) Handle(obj *v3.AppRevision, status v3.AppRevisionStatus) (v3.AppRevisionStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.AppRevisionGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appRevisionGeneratingHandler) isNewResourceVersion(obj *v3.AppRevision) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *appRevisionGeneratingHandler) storeResourceVersion(obj *v3.AppRevision) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/basicauth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/basicauth.go new file mode 100644 index 0000000..60cb658 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/basicauth.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// BasicAuthController interface for managing BasicAuth resources. +type BasicAuthController interface { + generic.ControllerInterface[*v3.BasicAuth, *v3.BasicAuthList] +} + +// BasicAuthClient interface for managing BasicAuth resources in Kubernetes. +type BasicAuthClient interface { + generic.ClientInterface[*v3.BasicAuth, *v3.BasicAuthList] +} + +// BasicAuthCache interface for retrieving BasicAuth resources in memory. +type BasicAuthCache interface { + generic.CacheInterface[*v3.BasicAuth] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/certificate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/certificate.go new file mode 100644 index 0000000..129f769 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/certificate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// CertificateController interface for managing Certificate resources. +type CertificateController interface { + generic.ControllerInterface[*v3.Certificate, *v3.CertificateList] +} + +// CertificateClient interface for managing Certificate resources in Kubernetes. +type CertificateClient interface { + generic.ClientInterface[*v3.Certificate, *v3.CertificateList] +} + +// CertificateCache interface for retrieving Certificate resources in memory. +type CertificateCache interface { + generic.CacheInterface[*v3.Certificate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/dockercredential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/dockercredential.go new file mode 100644 index 0000000..8e218d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/dockercredential.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// DockerCredentialController interface for managing DockerCredential resources. +type DockerCredentialController interface { + generic.ControllerInterface[*v3.DockerCredential, *v3.DockerCredentialList] +} + +// DockerCredentialClient interface for managing DockerCredential resources in Kubernetes. +type DockerCredentialClient interface { + generic.ClientInterface[*v3.DockerCredential, *v3.DockerCredentialList] +} + +// DockerCredentialCache interface for retrieving DockerCredential resources in memory. +type DockerCredentialCache interface { + generic.CacheInterface[*v3.DockerCredential] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/interface.go new file mode 100644 index 0000000..317dbc3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/interface.go @@ -0,0 +1,109 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + "github.com/rancher/lasso/pkg/controller" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v3.AddToScheme) +} + +type Interface interface { + App() AppController + AppRevision() AppRevisionController + BasicAuth() BasicAuthController + Certificate() CertificateController + DockerCredential() DockerCredentialController + NamespacedBasicAuth() NamespacedBasicAuthController + NamespacedCertificate() NamespacedCertificateController + NamespacedDockerCredential() NamespacedDockerCredentialController + NamespacedSSHAuth() NamespacedSSHAuthController + NamespacedServiceAccountToken() NamespacedServiceAccountTokenController + SSHAuth() SSHAuthController + ServiceAccountToken() ServiceAccountTokenController + Workload() WorkloadController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) App() AppController { + return generic.NewController[*v3.App, *v3.AppList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "App"}, "apps", true, v.controllerFactory) +} + +func (v *version) AppRevision() AppRevisionController { + return generic.NewController[*v3.AppRevision, *v3.AppRevisionList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "AppRevision"}, "apprevisions", true, v.controllerFactory) +} + +func (v *version) BasicAuth() BasicAuthController { + return generic.NewController[*v3.BasicAuth, *v3.BasicAuthList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "BasicAuth"}, "basicauths", true, v.controllerFactory) +} + +func (v *version) Certificate() CertificateController { + return generic.NewController[*v3.Certificate, *v3.CertificateList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "Certificate"}, "certificates", true, v.controllerFactory) +} + +func (v *version) DockerCredential() DockerCredentialController { + return generic.NewController[*v3.DockerCredential, *v3.DockerCredentialList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "DockerCredential"}, "dockercredentials", true, v.controllerFactory) +} + +func (v *version) NamespacedBasicAuth() NamespacedBasicAuthController { + return generic.NewController[*v3.NamespacedBasicAuth, *v3.NamespacedBasicAuthList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "NamespacedBasicAuth"}, "namespacedbasicauths", true, v.controllerFactory) +} + +func (v *version) NamespacedCertificate() NamespacedCertificateController { + return generic.NewController[*v3.NamespacedCertificate, *v3.NamespacedCertificateList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "NamespacedCertificate"}, "namespacedcertificates", true, v.controllerFactory) +} + +func (v *version) NamespacedDockerCredential() NamespacedDockerCredentialController { + return generic.NewController[*v3.NamespacedDockerCredential, *v3.NamespacedDockerCredentialList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "NamespacedDockerCredential"}, "namespaceddockercredentials", true, v.controllerFactory) +} + +func (v *version) NamespacedSSHAuth() NamespacedSSHAuthController { + return generic.NewController[*v3.NamespacedSSHAuth, *v3.NamespacedSSHAuthList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "NamespacedSSHAuth"}, "namespacedsshauths", true, v.controllerFactory) +} + +func (v *version) NamespacedServiceAccountToken() NamespacedServiceAccountTokenController { + return generic.NewController[*v3.NamespacedServiceAccountToken, *v3.NamespacedServiceAccountTokenList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "NamespacedServiceAccountToken"}, "namespacedserviceaccounttokens", true, v.controllerFactory) +} + +func (v *version) SSHAuth() SSHAuthController { + return generic.NewController[*v3.SSHAuth, *v3.SSHAuthList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "SSHAuth"}, "sshauths", true, v.controllerFactory) +} + +func (v *version) ServiceAccountToken() ServiceAccountTokenController { + return generic.NewController[*v3.ServiceAccountToken, *v3.ServiceAccountTokenList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "ServiceAccountToken"}, "serviceaccounttokens", true, v.controllerFactory) +} + +func (v *version) Workload() WorkloadController { + return generic.NewController[*v3.Workload, *v3.WorkloadList](schema.GroupVersionKind{Group: "project.cattle.io", Version: "v3", Kind: "Workload"}, "workloads", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedbasicauth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedbasicauth.go new file mode 100644 index 0000000..9c17571 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedbasicauth.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NamespacedBasicAuthController interface for managing NamespacedBasicAuth resources. +type NamespacedBasicAuthController interface { + generic.ControllerInterface[*v3.NamespacedBasicAuth, *v3.NamespacedBasicAuthList] +} + +// NamespacedBasicAuthClient interface for managing NamespacedBasicAuth resources in Kubernetes. +type NamespacedBasicAuthClient interface { + generic.ClientInterface[*v3.NamespacedBasicAuth, *v3.NamespacedBasicAuthList] +} + +// NamespacedBasicAuthCache interface for retrieving NamespacedBasicAuth resources in memory. +type NamespacedBasicAuthCache interface { + generic.CacheInterface[*v3.NamespacedBasicAuth] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedcertificate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedcertificate.go new file mode 100644 index 0000000..e10a74e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedcertificate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NamespacedCertificateController interface for managing NamespacedCertificate resources. +type NamespacedCertificateController interface { + generic.ControllerInterface[*v3.NamespacedCertificate, *v3.NamespacedCertificateList] +} + +// NamespacedCertificateClient interface for managing NamespacedCertificate resources in Kubernetes. +type NamespacedCertificateClient interface { + generic.ClientInterface[*v3.NamespacedCertificate, *v3.NamespacedCertificateList] +} + +// NamespacedCertificateCache interface for retrieving NamespacedCertificate resources in memory. +type NamespacedCertificateCache interface { + generic.CacheInterface[*v3.NamespacedCertificate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespaceddockercredential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespaceddockercredential.go new file mode 100644 index 0000000..7421d81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespaceddockercredential.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NamespacedDockerCredentialController interface for managing NamespacedDockerCredential resources. +type NamespacedDockerCredentialController interface { + generic.ControllerInterface[*v3.NamespacedDockerCredential, *v3.NamespacedDockerCredentialList] +} + +// NamespacedDockerCredentialClient interface for managing NamespacedDockerCredential resources in Kubernetes. +type NamespacedDockerCredentialClient interface { + generic.ClientInterface[*v3.NamespacedDockerCredential, *v3.NamespacedDockerCredentialList] +} + +// NamespacedDockerCredentialCache interface for retrieving NamespacedDockerCredential resources in memory. +type NamespacedDockerCredentialCache interface { + generic.CacheInterface[*v3.NamespacedDockerCredential] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedserviceaccounttoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedserviceaccounttoken.go new file mode 100644 index 0000000..254c51f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedserviceaccounttoken.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NamespacedServiceAccountTokenController interface for managing NamespacedServiceAccountToken resources. +type NamespacedServiceAccountTokenController interface { + generic.ControllerInterface[*v3.NamespacedServiceAccountToken, *v3.NamespacedServiceAccountTokenList] +} + +// NamespacedServiceAccountTokenClient interface for managing NamespacedServiceAccountToken resources in Kubernetes. +type NamespacedServiceAccountTokenClient interface { + generic.ClientInterface[*v3.NamespacedServiceAccountToken, *v3.NamespacedServiceAccountTokenList] +} + +// NamespacedServiceAccountTokenCache interface for retrieving NamespacedServiceAccountToken resources in memory. +type NamespacedServiceAccountTokenCache interface { + generic.CacheInterface[*v3.NamespacedServiceAccountToken] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedsshauth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedsshauth.go new file mode 100644 index 0000000..a457e5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/namespacedsshauth.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NamespacedSSHAuthController interface for managing NamespacedSSHAuth resources. +type NamespacedSSHAuthController interface { + generic.ControllerInterface[*v3.NamespacedSSHAuth, *v3.NamespacedSSHAuthList] +} + +// NamespacedSSHAuthClient interface for managing NamespacedSSHAuth resources in Kubernetes. +type NamespacedSSHAuthClient interface { + generic.ClientInterface[*v3.NamespacedSSHAuth, *v3.NamespacedSSHAuthList] +} + +// NamespacedSSHAuthCache interface for retrieving NamespacedSSHAuth resources in memory. +type NamespacedSSHAuthCache interface { + generic.CacheInterface[*v3.NamespacedSSHAuth] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/serviceaccounttoken.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/serviceaccounttoken.go new file mode 100644 index 0000000..bb56a4d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/serviceaccounttoken.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// ServiceAccountTokenController interface for managing ServiceAccountToken resources. +type ServiceAccountTokenController interface { + generic.ControllerInterface[*v3.ServiceAccountToken, *v3.ServiceAccountTokenList] +} + +// ServiceAccountTokenClient interface for managing ServiceAccountToken resources in Kubernetes. +type ServiceAccountTokenClient interface { + generic.ClientInterface[*v3.ServiceAccountToken, *v3.ServiceAccountTokenList] +} + +// ServiceAccountTokenCache interface for retrieving ServiceAccountToken resources in memory. +type ServiceAccountTokenCache interface { + generic.CacheInterface[*v3.ServiceAccountToken] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/sshauth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/sshauth.go new file mode 100644 index 0000000..efeec7e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/sshauth.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// SSHAuthController interface for managing SSHAuth resources. +type SSHAuthController interface { + generic.ControllerInterface[*v3.SSHAuth, *v3.SSHAuthList] +} + +// SSHAuthClient interface for managing SSHAuth resources in Kubernetes. +type SSHAuthClient interface { + generic.ClientInterface[*v3.SSHAuth, *v3.SSHAuthList] +} + +// SSHAuthCache interface for retrieving SSHAuth resources in memory. +type SSHAuthCache interface { + generic.CacheInterface[*v3.SSHAuth] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/workload.go new file mode 100644 index 0000000..43dafed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/project.cattle.io/v3/workload.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v3 + +import ( + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// WorkloadController interface for managing Workload resources. +type WorkloadController interface { + generic.ControllerInterface[*v3.Workload, *v3.WorkloadList] +} + +// WorkloadClient interface for managing Workload resources in Kubernetes. +type WorkloadClient interface { + generic.ClientInterface[*v3.Workload, *v3.WorkloadList] +} + +// WorkloadCache interface for retrieving Workload resources in memory. +type WorkloadCache interface { + generic.CacheInterface[*v3.Workload] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/factory.go new file mode 100644 index 0000000..3a8b567 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package provisioning + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Provisioning() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/interface.go new file mode 100644 index 0000000..32f0752 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package provisioning + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" +) + +type Interface interface { + V1() v1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1() v1.Interface { + return v1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/cluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/cluster.go new file mode 100644 index 0000000..99e8b05 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/cluster.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ClusterController interface for managing Cluster resources. +type ClusterController interface { + generic.ControllerInterface[*v1.Cluster, *v1.ClusterList] +} + +// ClusterClient interface for managing Cluster resources in Kubernetes. +type ClusterClient interface { + generic.ClientInterface[*v1.Cluster, *v1.ClusterList] +} + +// ClusterCache interface for retrieving Cluster resources in memory. +type ClusterCache interface { + generic.CacheInterface[*v1.Cluster] +} + +// ClusterStatusHandler is executed for every added or modified Cluster. Should return the new status to be updated +type ClusterStatusHandler func(obj *v1.Cluster, status v1.ClusterStatus) (v1.ClusterStatus, error) + +// ClusterGeneratingHandler is the top-level handler that is executed for every Cluster event. It extends ClusterStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ClusterGeneratingHandler func(obj *v1.Cluster, status v1.ClusterStatus) ([]runtime.Object, v1.ClusterStatus, error) + +// RegisterClusterStatusHandler configures a ClusterController to execute a ClusterStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterStatusHandler(ctx context.Context, controller ClusterController, condition condition.Cond, name string, handler ClusterStatusHandler) { + statusHandler := &clusterStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterClusterGeneratingHandler configures a ClusterController to execute a ClusterGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterClusterGeneratingHandler(ctx context.Context, controller ClusterController, apply apply.Apply, + condition condition.Cond, name string, handler ClusterGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &clusterGeneratingHandler{ + ClusterGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterClusterStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type clusterStatusHandler struct { + client ClusterClient + condition condition.Cond + handler ClusterStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *clusterStatusHandler) sync(key string, obj *v1.Cluster) (*v1.Cluster, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type clusterGeneratingHandler struct { + ClusterGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *clusterGeneratingHandler) Remove(key string, obj *v1.Cluster) (*v1.Cluster, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Cluster{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ClusterGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *clusterGeneratingHandler) Handle(obj *v1.Cluster, status v1.ClusterStatus) (v1.ClusterStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ClusterGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) isNewResourceVersion(obj *v1.Cluster) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *clusterGeneratingHandler) storeResourceVersion(obj *v1.Cluster) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/interface.go new file mode 100644 index 0000000..ca3840a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/provisioning.cattle.io/v1/interface.go @@ -0,0 +1,49 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1.AddToScheme) +} + +type Interface interface { + Cluster() ClusterController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) Cluster() ClusterController { + return generic.NewController[*v1.Cluster, *v1.ClusterList](schema.GroupVersionKind{Group: "provisioning.cattle.io", Version: "v1", Kind: "Cluster"}, "clusters", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/factory.go new file mode 100644 index 0000000..24f8c48 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package rke + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Rke() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/interface.go new file mode 100644 index 0000000..038c47c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package rke + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" +) + +type Interface interface { + V1() v1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1() v1.Interface { + return v1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/custommachine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/custommachine.go new file mode 100644 index 0000000..97a58e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/custommachine.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// CustomMachineController interface for managing CustomMachine resources. +type CustomMachineController interface { + generic.ControllerInterface[*v1.CustomMachine, *v1.CustomMachineList] +} + +// CustomMachineClient interface for managing CustomMachine resources in Kubernetes. +type CustomMachineClient interface { + generic.ClientInterface[*v1.CustomMachine, *v1.CustomMachineList] +} + +// CustomMachineCache interface for retrieving CustomMachine resources in memory. +type CustomMachineCache interface { + generic.CacheInterface[*v1.CustomMachine] +} + +// CustomMachineStatusHandler is executed for every added or modified CustomMachine. Should return the new status to be updated +type CustomMachineStatusHandler func(obj *v1.CustomMachine, status v1.CustomMachineStatus) (v1.CustomMachineStatus, error) + +// CustomMachineGeneratingHandler is the top-level handler that is executed for every CustomMachine event. It extends CustomMachineStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type CustomMachineGeneratingHandler func(obj *v1.CustomMachine, status v1.CustomMachineStatus) ([]runtime.Object, v1.CustomMachineStatus, error) + +// RegisterCustomMachineStatusHandler configures a CustomMachineController to execute a CustomMachineStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCustomMachineStatusHandler(ctx context.Context, controller CustomMachineController, condition condition.Cond, name string, handler CustomMachineStatusHandler) { + statusHandler := &customMachineStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterCustomMachineGeneratingHandler configures a CustomMachineController to execute a CustomMachineGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterCustomMachineGeneratingHandler(ctx context.Context, controller CustomMachineController, apply apply.Apply, + condition condition.Cond, name string, handler CustomMachineGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &customMachineGeneratingHandler{ + CustomMachineGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterCustomMachineStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type customMachineStatusHandler struct { + client CustomMachineClient + condition condition.Cond + handler CustomMachineStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *customMachineStatusHandler) sync(key string, obj *v1.CustomMachine) (*v1.CustomMachine, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type customMachineGeneratingHandler struct { + CustomMachineGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *customMachineGeneratingHandler) Remove(key string, obj *v1.CustomMachine) (*v1.CustomMachine, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.CustomMachine{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured CustomMachineGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *customMachineGeneratingHandler) Handle(obj *v1.CustomMachine, status v1.CustomMachineStatus) (v1.CustomMachineStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.CustomMachineGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *customMachineGeneratingHandler) isNewResourceVersion(obj *v1.CustomMachine) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *customMachineGeneratingHandler) storeResourceVersion(obj *v1.CustomMachine) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/etcdsnapshot.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/etcdsnapshot.go new file mode 100644 index 0000000..9c82af6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/etcdsnapshot.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// ETCDSnapshotController interface for managing ETCDSnapshot resources. +type ETCDSnapshotController interface { + generic.ControllerInterface[*v1.ETCDSnapshot, *v1.ETCDSnapshotList] +} + +// ETCDSnapshotClient interface for managing ETCDSnapshot resources in Kubernetes. +type ETCDSnapshotClient interface { + generic.ClientInterface[*v1.ETCDSnapshot, *v1.ETCDSnapshotList] +} + +// ETCDSnapshotCache interface for retrieving ETCDSnapshot resources in memory. +type ETCDSnapshotCache interface { + generic.CacheInterface[*v1.ETCDSnapshot] +} + +// ETCDSnapshotStatusHandler is executed for every added or modified ETCDSnapshot. Should return the new status to be updated +type ETCDSnapshotStatusHandler func(obj *v1.ETCDSnapshot, status v1.ETCDSnapshotStatus) (v1.ETCDSnapshotStatus, error) + +// ETCDSnapshotGeneratingHandler is the top-level handler that is executed for every ETCDSnapshot event. It extends ETCDSnapshotStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type ETCDSnapshotGeneratingHandler func(obj *v1.ETCDSnapshot, status v1.ETCDSnapshotStatus) ([]runtime.Object, v1.ETCDSnapshotStatus, error) + +// RegisterETCDSnapshotStatusHandler configures a ETCDSnapshotController to execute a ETCDSnapshotStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterETCDSnapshotStatusHandler(ctx context.Context, controller ETCDSnapshotController, condition condition.Cond, name string, handler ETCDSnapshotStatusHandler) { + statusHandler := &eTCDSnapshotStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterETCDSnapshotGeneratingHandler configures a ETCDSnapshotController to execute a ETCDSnapshotGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterETCDSnapshotGeneratingHandler(ctx context.Context, controller ETCDSnapshotController, apply apply.Apply, + condition condition.Cond, name string, handler ETCDSnapshotGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &eTCDSnapshotGeneratingHandler{ + ETCDSnapshotGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterETCDSnapshotStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type eTCDSnapshotStatusHandler struct { + client ETCDSnapshotClient + condition condition.Cond + handler ETCDSnapshotStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *eTCDSnapshotStatusHandler) sync(key string, obj *v1.ETCDSnapshot) (*v1.ETCDSnapshot, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type eTCDSnapshotGeneratingHandler struct { + ETCDSnapshotGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *eTCDSnapshotGeneratingHandler) Remove(key string, obj *v1.ETCDSnapshot) (*v1.ETCDSnapshot, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.ETCDSnapshot{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured ETCDSnapshotGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *eTCDSnapshotGeneratingHandler) Handle(obj *v1.ETCDSnapshot, status v1.ETCDSnapshotStatus) (v1.ETCDSnapshotStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.ETCDSnapshotGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *eTCDSnapshotGeneratingHandler) isNewResourceVersion(obj *v1.ETCDSnapshot) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *eTCDSnapshotGeneratingHandler) storeResourceVersion(obj *v1.ETCDSnapshot) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/interface.go new file mode 100644 index 0000000..0cbb162 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/interface.go @@ -0,0 +1,74 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1.AddToScheme) +} + +type Interface interface { + CustomMachine() CustomMachineController + ETCDSnapshot() ETCDSnapshotController + RKEBootstrap() RKEBootstrapController + RKEBootstrapTemplate() RKEBootstrapTemplateController + RKECluster() RKEClusterController + RKEControlPlane() RKEControlPlaneController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) CustomMachine() CustomMachineController { + return generic.NewController[*v1.CustomMachine, *v1.CustomMachineList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "CustomMachine"}, "custommachines", true, v.controllerFactory) +} + +func (v *version) ETCDSnapshot() ETCDSnapshotController { + return generic.NewController[*v1.ETCDSnapshot, *v1.ETCDSnapshotList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "ETCDSnapshot"}, "etcdsnapshots", true, v.controllerFactory) +} + +func (v *version) RKEBootstrap() RKEBootstrapController { + return generic.NewController[*v1.RKEBootstrap, *v1.RKEBootstrapList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "RKEBootstrap"}, "rkebootstraps", true, v.controllerFactory) +} + +func (v *version) RKEBootstrapTemplate() RKEBootstrapTemplateController { + return generic.NewController[*v1.RKEBootstrapTemplate, *v1.RKEBootstrapTemplateList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "RKEBootstrapTemplate"}, "rkebootstraptemplates", true, v.controllerFactory) +} + +func (v *version) RKECluster() RKEClusterController { + return generic.NewController[*v1.RKECluster, *v1.RKEClusterList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "RKECluster"}, "rkeclusters", true, v.controllerFactory) +} + +func (v *version) RKEControlPlane() RKEControlPlaneController { + return generic.NewController[*v1.RKEControlPlane, *v1.RKEControlPlaneList](schema.GroupVersionKind{Group: "rke.cattle.io", Version: "v1", Kind: "RKEControlPlane"}, "rkecontrolplanes", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstrap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstrap.go new file mode 100644 index 0000000..796c6e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstrap.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// RKEBootstrapController interface for managing RKEBootstrap resources. +type RKEBootstrapController interface { + generic.ControllerInterface[*v1.RKEBootstrap, *v1.RKEBootstrapList] +} + +// RKEBootstrapClient interface for managing RKEBootstrap resources in Kubernetes. +type RKEBootstrapClient interface { + generic.ClientInterface[*v1.RKEBootstrap, *v1.RKEBootstrapList] +} + +// RKEBootstrapCache interface for retrieving RKEBootstrap resources in memory. +type RKEBootstrapCache interface { + generic.CacheInterface[*v1.RKEBootstrap] +} + +// RKEBootstrapStatusHandler is executed for every added or modified RKEBootstrap. Should return the new status to be updated +type RKEBootstrapStatusHandler func(obj *v1.RKEBootstrap, status v1.RKEBootstrapStatus) (v1.RKEBootstrapStatus, error) + +// RKEBootstrapGeneratingHandler is the top-level handler that is executed for every RKEBootstrap event. It extends RKEBootstrapStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type RKEBootstrapGeneratingHandler func(obj *v1.RKEBootstrap, status v1.RKEBootstrapStatus) ([]runtime.Object, v1.RKEBootstrapStatus, error) + +// RegisterRKEBootstrapStatusHandler configures a RKEBootstrapController to execute a RKEBootstrapStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEBootstrapStatusHandler(ctx context.Context, controller RKEBootstrapController, condition condition.Cond, name string, handler RKEBootstrapStatusHandler) { + statusHandler := &rKEBootstrapStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterRKEBootstrapGeneratingHandler configures a RKEBootstrapController to execute a RKEBootstrapGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEBootstrapGeneratingHandler(ctx context.Context, controller RKEBootstrapController, apply apply.Apply, + condition condition.Cond, name string, handler RKEBootstrapGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &rKEBootstrapGeneratingHandler{ + RKEBootstrapGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterRKEBootstrapStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type rKEBootstrapStatusHandler struct { + client RKEBootstrapClient + condition condition.Cond + handler RKEBootstrapStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *rKEBootstrapStatusHandler) sync(key string, obj *v1.RKEBootstrap) (*v1.RKEBootstrap, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type rKEBootstrapGeneratingHandler struct { + RKEBootstrapGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *rKEBootstrapGeneratingHandler) Remove(key string, obj *v1.RKEBootstrap) (*v1.RKEBootstrap, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.RKEBootstrap{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured RKEBootstrapGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *rKEBootstrapGeneratingHandler) Handle(obj *v1.RKEBootstrap, status v1.RKEBootstrapStatus) (v1.RKEBootstrapStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.RKEBootstrapGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEBootstrapGeneratingHandler) isNewResourceVersion(obj *v1.RKEBootstrap) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEBootstrapGeneratingHandler) storeResourceVersion(obj *v1.RKEBootstrap) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstraptemplate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstraptemplate.go new file mode 100644 index 0000000..7f59076 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkebootstraptemplate.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// RKEBootstrapTemplateController interface for managing RKEBootstrapTemplate resources. +type RKEBootstrapTemplateController interface { + generic.ControllerInterface[*v1.RKEBootstrapTemplate, *v1.RKEBootstrapTemplateList] +} + +// RKEBootstrapTemplateClient interface for managing RKEBootstrapTemplate resources in Kubernetes. +type RKEBootstrapTemplateClient interface { + generic.ClientInterface[*v1.RKEBootstrapTemplate, *v1.RKEBootstrapTemplateList] +} + +// RKEBootstrapTemplateCache interface for retrieving RKEBootstrapTemplate resources in memory. +type RKEBootstrapTemplateCache interface { + generic.CacheInterface[*v1.RKEBootstrapTemplate] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecluster.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecluster.go new file mode 100644 index 0000000..3acbd0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecluster.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// RKEClusterController interface for managing RKECluster resources. +type RKEClusterController interface { + generic.ControllerInterface[*v1.RKECluster, *v1.RKEClusterList] +} + +// RKEClusterClient interface for managing RKECluster resources in Kubernetes. +type RKEClusterClient interface { + generic.ClientInterface[*v1.RKECluster, *v1.RKEClusterList] +} + +// RKEClusterCache interface for retrieving RKECluster resources in memory. +type RKEClusterCache interface { + generic.CacheInterface[*v1.RKECluster] +} + +// RKEClusterStatusHandler is executed for every added or modified RKECluster. Should return the new status to be updated +type RKEClusterStatusHandler func(obj *v1.RKECluster, status v1.RKEClusterStatus) (v1.RKEClusterStatus, error) + +// RKEClusterGeneratingHandler is the top-level handler that is executed for every RKECluster event. It extends RKEClusterStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type RKEClusterGeneratingHandler func(obj *v1.RKECluster, status v1.RKEClusterStatus) ([]runtime.Object, v1.RKEClusterStatus, error) + +// RegisterRKEClusterStatusHandler configures a RKEClusterController to execute a RKEClusterStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEClusterStatusHandler(ctx context.Context, controller RKEClusterController, condition condition.Cond, name string, handler RKEClusterStatusHandler) { + statusHandler := &rKEClusterStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterRKEClusterGeneratingHandler configures a RKEClusterController to execute a RKEClusterGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEClusterGeneratingHandler(ctx context.Context, controller RKEClusterController, apply apply.Apply, + condition condition.Cond, name string, handler RKEClusterGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &rKEClusterGeneratingHandler{ + RKEClusterGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterRKEClusterStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type rKEClusterStatusHandler struct { + client RKEClusterClient + condition condition.Cond + handler RKEClusterStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *rKEClusterStatusHandler) sync(key string, obj *v1.RKECluster) (*v1.RKECluster, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type rKEClusterGeneratingHandler struct { + RKEClusterGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *rKEClusterGeneratingHandler) Remove(key string, obj *v1.RKECluster) (*v1.RKECluster, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.RKECluster{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured RKEClusterGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *rKEClusterGeneratingHandler) Handle(obj *v1.RKECluster, status v1.RKEClusterStatus) (v1.RKEClusterStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.RKEClusterGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEClusterGeneratingHandler) isNewResourceVersion(obj *v1.RKECluster) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEClusterGeneratingHandler) storeResourceVersion(obj *v1.RKECluster) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecontrolplane.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecontrolplane.go new file mode 100644 index 0000000..5ccc89c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/rke.cattle.io/v1/rkecontrolplane.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// RKEControlPlaneController interface for managing RKEControlPlane resources. +type RKEControlPlaneController interface { + generic.ControllerInterface[*v1.RKEControlPlane, *v1.RKEControlPlaneList] +} + +// RKEControlPlaneClient interface for managing RKEControlPlane resources in Kubernetes. +type RKEControlPlaneClient interface { + generic.ClientInterface[*v1.RKEControlPlane, *v1.RKEControlPlaneList] +} + +// RKEControlPlaneCache interface for retrieving RKEControlPlane resources in memory. +type RKEControlPlaneCache interface { + generic.CacheInterface[*v1.RKEControlPlane] +} + +// RKEControlPlaneStatusHandler is executed for every added or modified RKEControlPlane. Should return the new status to be updated +type RKEControlPlaneStatusHandler func(obj *v1.RKEControlPlane, status v1.RKEControlPlaneStatus) (v1.RKEControlPlaneStatus, error) + +// RKEControlPlaneGeneratingHandler is the top-level handler that is executed for every RKEControlPlane event. It extends RKEControlPlaneStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type RKEControlPlaneGeneratingHandler func(obj *v1.RKEControlPlane, status v1.RKEControlPlaneStatus) ([]runtime.Object, v1.RKEControlPlaneStatus, error) + +// RegisterRKEControlPlaneStatusHandler configures a RKEControlPlaneController to execute a RKEControlPlaneStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEControlPlaneStatusHandler(ctx context.Context, controller RKEControlPlaneController, condition condition.Cond, name string, handler RKEControlPlaneStatusHandler) { + statusHandler := &rKEControlPlaneStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterRKEControlPlaneGeneratingHandler configures a RKEControlPlaneController to execute a RKEControlPlaneGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterRKEControlPlaneGeneratingHandler(ctx context.Context, controller RKEControlPlaneController, apply apply.Apply, + condition condition.Cond, name string, handler RKEControlPlaneGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &rKEControlPlaneGeneratingHandler{ + RKEControlPlaneGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterRKEControlPlaneStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type rKEControlPlaneStatusHandler struct { + client RKEControlPlaneClient + condition condition.Cond + handler RKEControlPlaneStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *rKEControlPlaneStatusHandler) sync(key string, obj *v1.RKEControlPlane) (*v1.RKEControlPlane, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type rKEControlPlaneGeneratingHandler struct { + RKEControlPlaneGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *rKEControlPlaneGeneratingHandler) Remove(key string, obj *v1.RKEControlPlane) (*v1.RKEControlPlane, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.RKEControlPlane{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured RKEControlPlaneGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *rKEControlPlaneGeneratingHandler) Handle(obj *v1.RKEControlPlane, status v1.RKEControlPlaneStatus) (v1.RKEControlPlaneStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.RKEControlPlaneGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEControlPlaneGeneratingHandler) isNewResourceVersion(obj *v1.RKEControlPlane) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *rKEControlPlaneGeneratingHandler) storeResourceVersion(obj *v1.RKEControlPlane) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/factory.go new file mode 100644 index 0000000..3217651 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package ui + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Ui() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/interface.go new file mode 100644 index 0000000..618013d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package ui + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/generated/controllers/ui.cattle.io/v1" +) + +type Interface interface { + V1() v1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1() v1.Interface { + return v1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/interface.go new file mode 100644 index 0000000..9f4bdf6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/interface.go @@ -0,0 +1,49 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/apis/ui.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1.AddToScheme) +} + +type Interface interface { + NavLink() NavLinkController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) NavLink() NavLinkController { + return generic.NewController[*v1.NavLink, *v1.NavLinkList](schema.GroupVersionKind{Group: "ui.cattle.io", Version: "v1", Kind: "NavLink"}, "navlinks", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/navlink.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/navlink.go new file mode 100644 index 0000000..ee76b37 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/ui.cattle.io/v1/navlink.go @@ -0,0 +1,39 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/rancher/rancher/pkg/apis/ui.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" +) + +// NavLinkController interface for managing NavLink resources. +type NavLinkController interface { + generic.ControllerInterface[*v1.NavLink, *v1.NavLinkList] +} + +// NavLinkClient interface for managing NavLink resources in Kubernetes. +type NavLinkClient interface { + generic.ClientInterface[*v1.NavLink, *v1.NavLinkList] +} + +// NavLinkCache interface for retrieving NavLink resources in memory. +type NavLinkCache interface { + generic.CacheInterface[*v1.NavLink] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/factory.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/factory.go new file mode 100644 index 0000000..704e51e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/factory.go @@ -0,0 +1,72 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package upgrade + +import ( + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/v3/pkg/generic" + "k8s.io/client-go/rest" +) + +type Factory struct { + *generic.Factory +} + +func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { + f, err := NewFactoryFromConfig(config) + if err != nil { + panic(err) + } + return f +} + +func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, nil) +} + +func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions = generic.FactoryOptions + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + f, err := generic.NewFactoryFromConfigWithOptions(config, opts) + return &Factory{ + Factory: f, + }, err +} + +func NewFactoryFromConfigWithOptionsOrDie(config *rest.Config, opts *FactoryOptions) *Factory { + f, err := NewFactoryFromConfigWithOptions(config, opts) + if err != nil { + panic(err) + } + return f +} + +func (c *Factory) Upgrade() Interface { + return New(c.ControllerFactory()) +} + +func (c *Factory) WithAgent(userAgent string) Interface { + return New(controller.NewSharedControllerFactoryWithAgent(userAgent, c.ControllerFactory())) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/interface.go new file mode 100644 index 0000000..2626751 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/interface.go @@ -0,0 +1,43 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package upgrade + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/rancher/pkg/generated/controllers/upgrade.cattle.io/v1" +) + +type Interface interface { + V1() v1.Interface +} + +type group struct { + controllerFactory controller.SharedControllerFactory +} + +// New returns a new Interface. +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &group{ + controllerFactory: controllerFactory, + } +} + +func (g *group) V1() v1.Interface { + return v1.New(g.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/interface.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/interface.go new file mode 100644 index 0000000..4af2c03 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/interface.go @@ -0,0 +1,49 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "github.com/rancher/lasso/pkg/controller" + v1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/schemes" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func init() { + schemes.Register(v1.AddToScheme) +} + +type Interface interface { + Plan() PlanController +} + +func New(controllerFactory controller.SharedControllerFactory) Interface { + return &version{ + controllerFactory: controllerFactory, + } +} + +type version struct { + controllerFactory controller.SharedControllerFactory +} + +func (v *version) Plan() PlanController { + return generic.NewController[*v1.Plan, *v1.PlanList](schema.GroupVersionKind{Group: "upgrade.cattle.io", Version: "v1", Kind: "Plan"}, "plans", true, v.controllerFactory) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/plan.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/plan.go new file mode 100644 index 0000000..3bdc99d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/controllers/upgrade.cattle.io/v1/plan.go @@ -0,0 +1,208 @@ +/* +Copyright 2024 Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by main. DO NOT EDIT. + +package v1 + +import ( + "context" + "sync" + "time" + + v1 "github.com/rancher/system-upgrade-controller/pkg/apis/upgrade.cattle.io/v1" + "github.com/rancher/wrangler/v3/pkg/apply" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/kv" + "k8s.io/apimachinery/pkg/api/equality" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// PlanController interface for managing Plan resources. +type PlanController interface { + generic.ControllerInterface[*v1.Plan, *v1.PlanList] +} + +// PlanClient interface for managing Plan resources in Kubernetes. +type PlanClient interface { + generic.ClientInterface[*v1.Plan, *v1.PlanList] +} + +// PlanCache interface for retrieving Plan resources in memory. +type PlanCache interface { + generic.CacheInterface[*v1.Plan] +} + +// PlanStatusHandler is executed for every added or modified Plan. Should return the new status to be updated +type PlanStatusHandler func(obj *v1.Plan, status v1.PlanStatus) (v1.PlanStatus, error) + +// PlanGeneratingHandler is the top-level handler that is executed for every Plan event. It extends PlanStatusHandler by a returning a slice of child objects to be passed to apply.Apply +type PlanGeneratingHandler func(obj *v1.Plan, status v1.PlanStatus) ([]runtime.Object, v1.PlanStatus, error) + +// RegisterPlanStatusHandler configures a PlanController to execute a PlanStatusHandler for every events observed. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterPlanStatusHandler(ctx context.Context, controller PlanController, condition condition.Cond, name string, handler PlanStatusHandler) { + statusHandler := &planStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, generic.FromObjectHandlerToHandler(statusHandler.sync)) +} + +// RegisterPlanGeneratingHandler configures a PlanController to execute a PlanGeneratingHandler for every events observed, passing the returned objects to the provided apply.Apply. +// If a non-empty condition is provided, it will be updated in the status conditions for every handler execution +func RegisterPlanGeneratingHandler(ctx context.Context, controller PlanController, apply apply.Apply, + condition condition.Cond, name string, handler PlanGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &planGeneratingHandler{ + PlanGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterPlanStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type planStatusHandler struct { + client PlanClient + condition condition.Cond + handler PlanStatusHandler +} + +// sync is executed on every resource addition or modification. Executes the configured handlers and sends the updated status to the Kubernetes API +func (a *planStatusHandler) sync(key string, obj *v1.Plan) (*v1.Plan, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + if a.condition != "" { + // Since status has changed, update the lastUpdatedTime + a.condition.LastUpdated(&newStatus, time.Now().UTC().Format(time.RFC3339)) + } + + var newErr error + obj.Status = newStatus + newObj, newErr := a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + if newErr == nil { + obj = newObj + } + } + return obj, err +} + +type planGeneratingHandler struct { + PlanGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string + seen sync.Map +} + +// Remove handles the observed deletion of a resource, cascade deleting every associated resource previously applied +func (a *planGeneratingHandler) Remove(key string, obj *v1.Plan) (*v1.Plan, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Plan{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + if a.opts.UniqueApplyForResourceVersion { + a.seen.Delete(key) + } + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +// Handle executes the configured PlanGeneratingHandler and pass the resulting objects to apply.Apply, finally returning the new status of the resource +func (a *planGeneratingHandler) Handle(obj *v1.Plan, status v1.PlanStatus) (v1.PlanStatus, error) { + if !obj.DeletionTimestamp.IsZero() { + return status, nil + } + + objs, newStatus, err := a.PlanGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + if !a.isNewResourceVersion(obj) { + return newStatus, nil + } + + err = generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) + if err != nil { + return newStatus, err + } + a.storeResourceVersion(obj) + return newStatus, nil +} + +// isNewResourceVersion detects if a specific resource version was already successfully processed. +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *planGeneratingHandler) isNewResourceVersion(obj *v1.Plan) bool { + if !a.opts.UniqueApplyForResourceVersion { + return true + } + + // Apply once per resource version + key := obj.Namespace + "/" + obj.Name + previous, ok := a.seen.Load(key) + return !ok || previous != obj.ResourceVersion +} + +// storeResourceVersion keeps track of the latest resource version of an object for which Apply was executed +// Only used if UniqueApplyForResourceVersion is set in generic.GeneratingHandlerOptions +func (a *planGeneratingHandler) storeResourceVersion(obj *v1.Plan) { + if !a.opts.UniqueApplyForResourceVersion { + return + } + + key := obj.Namespace + "/" + obj.Name + a.seen.Store(key, obj.ResourceVersion) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/fakes/zz_generated_api_service_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/fakes/zz_generated_api_service_mock.go new file mode 100644 index 0000000..ba42c43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/fakes/zz_generated_api_service_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/apiregistration.k8s.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +var ( + lockAPIServiceListerMockGet sync.RWMutex + lockAPIServiceListerMockList sync.RWMutex +) + +// Ensure, that APIServiceListerMock does implement v11.APIServiceLister. +// If this is not the case, regenerate this file with moq. +var _ v11.APIServiceLister = &APIServiceListerMock{} + +// APIServiceListerMock is a mock implementation of v11.APIServiceLister. +// +// func TestSomethingThatUsesAPIServiceLister(t *testing.T) { +// +// // make and configure a mocked v11.APIServiceLister +// mockedAPIServiceLister := &APIServiceListerMock{ +// GetFunc: func(namespace string, name string) (*v1.APIService, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.APIService, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedAPIServiceLister in code that requires v11.APIServiceLister +// // and then make assertions. +// +// } +type APIServiceListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.APIService, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.APIService, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *APIServiceListerMock) Get(namespace string, name string) (*v1.APIService, error) { + if mock.GetFunc == nil { + panic("APIServiceListerMock.GetFunc: method is nil but APIServiceLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAPIServiceListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAPIServiceListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAPIServiceLister.GetCalls()) +func (mock *APIServiceListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAPIServiceListerMockGet.RLock() + calls = mock.calls.Get + lockAPIServiceListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *APIServiceListerMock) List(namespace string, selector labels.Selector) ([]*v1.APIService, error) { + if mock.ListFunc == nil { + panic("APIServiceListerMock.ListFunc: method is nil but APIServiceLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockAPIServiceListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAPIServiceListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAPIServiceLister.ListCalls()) +func (mock *APIServiceListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockAPIServiceListerMockList.RLock() + calls = mock.calls.List + lockAPIServiceListerMockList.RUnlock() + return calls +} + +var ( + lockAPIServiceControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockAPIServiceControllerMockAddClusterScopedHandler sync.RWMutex + lockAPIServiceControllerMockAddFeatureHandler sync.RWMutex + lockAPIServiceControllerMockAddHandler sync.RWMutex + lockAPIServiceControllerMockEnqueue sync.RWMutex + lockAPIServiceControllerMockEnqueueAfter sync.RWMutex + lockAPIServiceControllerMockGeneric sync.RWMutex + lockAPIServiceControllerMockInformer sync.RWMutex + lockAPIServiceControllerMockLister sync.RWMutex +) + +// Ensure, that APIServiceControllerMock does implement v11.APIServiceController. +// If this is not the case, regenerate this file with moq. +var _ v11.APIServiceController = &APIServiceControllerMock{} + +// APIServiceControllerMock is a mock implementation of v11.APIServiceController. +// +// func TestSomethingThatUsesAPIServiceController(t *testing.T) { +// +// // make and configure a mocked v11.APIServiceController +// mockedAPIServiceController := &APIServiceControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.APIServiceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.APIServiceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.APIServiceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.APIServiceLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedAPIServiceController in code that requires v11.APIServiceController +// // and then make assertions. +// +// } +type APIServiceControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.APIServiceHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.APIServiceHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.APIServiceHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.APIServiceLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.APIServiceHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.APIServiceHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.APIServiceHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.APIServiceHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *APIServiceControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.APIServiceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("APIServiceControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but APIServiceController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAPIServiceControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAPIServiceControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAPIServiceController.AddClusterScopedFeatureHandlerCalls()) +func (mock *APIServiceControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc + } + lockAPIServiceControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAPIServiceControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *APIServiceControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.APIServiceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("APIServiceControllerMock.AddClusterScopedHandlerFunc: method is nil but APIServiceController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAPIServiceControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAPIServiceControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAPIServiceController.AddClusterScopedHandlerCalls()) +func (mock *APIServiceControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.APIServiceHandlerFunc + } + lockAPIServiceControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAPIServiceControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *APIServiceControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("APIServiceControllerMock.AddFeatureHandlerFunc: method is nil but APIServiceController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAPIServiceControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAPIServiceControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAPIServiceController.AddFeatureHandlerCalls()) +func (mock *APIServiceControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc + } + lockAPIServiceControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAPIServiceControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *APIServiceControllerMock) AddHandler(ctx context.Context, name string, handler v11.APIServiceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("APIServiceControllerMock.AddHandlerFunc: method is nil but APIServiceController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockAPIServiceControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAPIServiceControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAPIServiceController.AddHandlerCalls()) +func (mock *APIServiceControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.APIServiceHandlerFunc + } + lockAPIServiceControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAPIServiceControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *APIServiceControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("APIServiceControllerMock.EnqueueFunc: method is nil but APIServiceController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAPIServiceControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockAPIServiceControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedAPIServiceController.EnqueueCalls()) +func (mock *APIServiceControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAPIServiceControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockAPIServiceControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *APIServiceControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("APIServiceControllerMock.EnqueueAfterFunc: method is nil but APIServiceController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockAPIServiceControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockAPIServiceControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedAPIServiceController.EnqueueAfterCalls()) +func (mock *APIServiceControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockAPIServiceControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockAPIServiceControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *APIServiceControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("APIServiceControllerMock.GenericFunc: method is nil but APIServiceController.Generic was just called") + } + callInfo := struct { + }{} + lockAPIServiceControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockAPIServiceControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedAPIServiceController.GenericCalls()) +func (mock *APIServiceControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockAPIServiceControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockAPIServiceControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *APIServiceControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("APIServiceControllerMock.InformerFunc: method is nil but APIServiceController.Informer was just called") + } + callInfo := struct { + }{} + lockAPIServiceControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockAPIServiceControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedAPIServiceController.InformerCalls()) +func (mock *APIServiceControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockAPIServiceControllerMockInformer.RLock() + calls = mock.calls.Informer + lockAPIServiceControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *APIServiceControllerMock) Lister() v11.APIServiceLister { + if mock.ListerFunc == nil { + panic("APIServiceControllerMock.ListerFunc: method is nil but APIServiceController.Lister was just called") + } + callInfo := struct { + }{} + lockAPIServiceControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockAPIServiceControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedAPIServiceController.ListerCalls()) +func (mock *APIServiceControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockAPIServiceControllerMockLister.RLock() + calls = mock.calls.Lister + lockAPIServiceControllerMockLister.RUnlock() + return calls +} + +var ( + lockAPIServiceInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockAPIServiceInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockAPIServiceInterfaceMockAddClusterScopedHandler sync.RWMutex + lockAPIServiceInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockAPIServiceInterfaceMockAddFeatureHandler sync.RWMutex + lockAPIServiceInterfaceMockAddFeatureLifecycle sync.RWMutex + lockAPIServiceInterfaceMockAddHandler sync.RWMutex + lockAPIServiceInterfaceMockAddLifecycle sync.RWMutex + lockAPIServiceInterfaceMockController sync.RWMutex + lockAPIServiceInterfaceMockCreate sync.RWMutex + lockAPIServiceInterfaceMockDelete sync.RWMutex + lockAPIServiceInterfaceMockDeleteCollection sync.RWMutex + lockAPIServiceInterfaceMockDeleteNamespaced sync.RWMutex + lockAPIServiceInterfaceMockGet sync.RWMutex + lockAPIServiceInterfaceMockGetNamespaced sync.RWMutex + lockAPIServiceInterfaceMockList sync.RWMutex + lockAPIServiceInterfaceMockListNamespaced sync.RWMutex + lockAPIServiceInterfaceMockObjectClient sync.RWMutex + lockAPIServiceInterfaceMockUpdate sync.RWMutex + lockAPIServiceInterfaceMockWatch sync.RWMutex +) + +// Ensure, that APIServiceInterfaceMock does implement v11.APIServiceInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.APIServiceInterface = &APIServiceInterfaceMock{} + +// APIServiceInterfaceMock is a mock implementation of v11.APIServiceInterface. +// +// func TestSomethingThatUsesAPIServiceInterface(t *testing.T) { +// +// // make and configure a mocked v11.APIServiceInterface +// mockedAPIServiceInterface := &APIServiceInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.APIServiceLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.APIServiceLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.APIServiceLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.APIServiceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.APIServiceLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.APIServiceController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.APIService) (*v1.APIService, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.APIService, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.APIService, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.APIServiceList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.APIServiceList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.APIService) (*v1.APIService, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedAPIServiceInterface in code that requires v11.APIServiceInterface +// // and then make assertions. +// +// } +type APIServiceInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.APIServiceLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.APIServiceLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.APIServiceLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.APIServiceHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.APIServiceLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.APIServiceController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.APIService) (*v1.APIService, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.APIService, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.APIService, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.APIServiceList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.APIServiceList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.APIService) (*v1.APIService, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.APIServiceHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.APIServiceLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.APIServiceHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.APIServiceLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.APIServiceHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.APIServiceLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.APIServiceHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.APIServiceLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.APIService + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.APIService + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *APIServiceInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("APIServiceInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but APIServiceInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAPIServiceInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAPIServiceInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *APIServiceInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc + } + lockAPIServiceInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAPIServiceInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *APIServiceInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.APIServiceLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("APIServiceInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but APIServiceInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAPIServiceInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockAPIServiceInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *APIServiceInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle + } + lockAPIServiceInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockAPIServiceInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *APIServiceInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.APIServiceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("APIServiceInterfaceMock.AddClusterScopedHandlerFunc: method is nil but APIServiceInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAPIServiceInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAPIServiceInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddClusterScopedHandlerCalls()) +func (mock *APIServiceInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.APIServiceHandlerFunc + } + lockAPIServiceInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAPIServiceInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *APIServiceInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.APIServiceLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("APIServiceInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but APIServiceInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAPIServiceInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockAPIServiceInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddClusterScopedLifecycleCalls()) +func (mock *APIServiceInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.APIServiceLifecycle + } + lockAPIServiceInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockAPIServiceInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *APIServiceInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.APIServiceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("APIServiceInterfaceMock.AddFeatureHandlerFunc: method is nil but APIServiceInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAPIServiceInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAPIServiceInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddFeatureHandlerCalls()) +func (mock *APIServiceInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.APIServiceHandlerFunc + } + lockAPIServiceInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAPIServiceInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *APIServiceInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.APIServiceLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("APIServiceInterfaceMock.AddFeatureLifecycleFunc: method is nil but APIServiceInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.APIServiceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockAPIServiceInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockAPIServiceInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddFeatureLifecycleCalls()) +func (mock *APIServiceInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.APIServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.APIServiceLifecycle + } + lockAPIServiceInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockAPIServiceInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *APIServiceInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.APIServiceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("APIServiceInterfaceMock.AddHandlerFunc: method is nil but APIServiceInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.APIServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockAPIServiceInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAPIServiceInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddHandlerCalls()) +func (mock *APIServiceInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.APIServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.APIServiceHandlerFunc + } + lockAPIServiceInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAPIServiceInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *APIServiceInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.APIServiceLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("APIServiceInterfaceMock.AddLifecycleFunc: method is nil but APIServiceInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.APIServiceLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockAPIServiceInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockAPIServiceInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedAPIServiceInterface.AddLifecycleCalls()) +func (mock *APIServiceInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.APIServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.APIServiceLifecycle + } + lockAPIServiceInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockAPIServiceInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *APIServiceInterfaceMock) Controller() v11.APIServiceController { + if mock.ControllerFunc == nil { + panic("APIServiceInterfaceMock.ControllerFunc: method is nil but APIServiceInterface.Controller was just called") + } + callInfo := struct { + }{} + lockAPIServiceInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockAPIServiceInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedAPIServiceInterface.ControllerCalls()) +func (mock *APIServiceInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockAPIServiceInterfaceMockController.RLock() + calls = mock.calls.Controller + lockAPIServiceInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *APIServiceInterfaceMock) Create(in1 *v1.APIService) (*v1.APIService, error) { + if mock.CreateFunc == nil { + panic("APIServiceInterfaceMock.CreateFunc: method is nil but APIServiceInterface.Create was just called") + } + callInfo := struct { + In1 *v1.APIService + }{ + In1: in1, + } + lockAPIServiceInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockAPIServiceInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedAPIServiceInterface.CreateCalls()) +func (mock *APIServiceInterfaceMock) CreateCalls() []struct { + In1 *v1.APIService +} { + var calls []struct { + In1 *v1.APIService + } + lockAPIServiceInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockAPIServiceInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *APIServiceInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("APIServiceInterfaceMock.DeleteFunc: method is nil but APIServiceInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockAPIServiceInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockAPIServiceInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedAPIServiceInterface.DeleteCalls()) +func (mock *APIServiceInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockAPIServiceInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockAPIServiceInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *APIServiceInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("APIServiceInterfaceMock.DeleteCollectionFunc: method is nil but APIServiceInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockAPIServiceInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockAPIServiceInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedAPIServiceInterface.DeleteCollectionCalls()) +func (mock *APIServiceInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockAPIServiceInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockAPIServiceInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *APIServiceInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("APIServiceInterfaceMock.DeleteNamespacedFunc: method is nil but APIServiceInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockAPIServiceInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockAPIServiceInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedAPIServiceInterface.DeleteNamespacedCalls()) +func (mock *APIServiceInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockAPIServiceInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockAPIServiceInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *APIServiceInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.APIService, error) { + if mock.GetFunc == nil { + panic("APIServiceInterfaceMock.GetFunc: method is nil but APIServiceInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockAPIServiceInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAPIServiceInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAPIServiceInterface.GetCalls()) +func (mock *APIServiceInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockAPIServiceInterfaceMockGet.RLock() + calls = mock.calls.Get + lockAPIServiceInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *APIServiceInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.APIService, error) { + if mock.GetNamespacedFunc == nil { + panic("APIServiceInterfaceMock.GetNamespacedFunc: method is nil but APIServiceInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockAPIServiceInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockAPIServiceInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedAPIServiceInterface.GetNamespacedCalls()) +func (mock *APIServiceInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockAPIServiceInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockAPIServiceInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *APIServiceInterfaceMock) List(opts metav1.ListOptions) (*v1.APIServiceList, error) { + if mock.ListFunc == nil { + panic("APIServiceInterfaceMock.ListFunc: method is nil but APIServiceInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAPIServiceInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAPIServiceInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAPIServiceInterface.ListCalls()) +func (mock *APIServiceInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAPIServiceInterfaceMockList.RLock() + calls = mock.calls.List + lockAPIServiceInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *APIServiceInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.APIServiceList, error) { + if mock.ListNamespacedFunc == nil { + panic("APIServiceInterfaceMock.ListNamespacedFunc: method is nil but APIServiceInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockAPIServiceInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockAPIServiceInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedAPIServiceInterface.ListNamespacedCalls()) +func (mock *APIServiceInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockAPIServiceInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockAPIServiceInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *APIServiceInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("APIServiceInterfaceMock.ObjectClientFunc: method is nil but APIServiceInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockAPIServiceInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockAPIServiceInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedAPIServiceInterface.ObjectClientCalls()) +func (mock *APIServiceInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockAPIServiceInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockAPIServiceInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *APIServiceInterfaceMock) Update(in1 *v1.APIService) (*v1.APIService, error) { + if mock.UpdateFunc == nil { + panic("APIServiceInterfaceMock.UpdateFunc: method is nil but APIServiceInterface.Update was just called") + } + callInfo := struct { + In1 *v1.APIService + }{ + In1: in1, + } + lockAPIServiceInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockAPIServiceInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedAPIServiceInterface.UpdateCalls()) +func (mock *APIServiceInterfaceMock) UpdateCalls() []struct { + In1 *v1.APIService +} { + var calls []struct { + In1 *v1.APIService + } + lockAPIServiceInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockAPIServiceInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *APIServiceInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("APIServiceInterfaceMock.WatchFunc: method is nil but APIServiceInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAPIServiceInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockAPIServiceInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedAPIServiceInterface.WatchCalls()) +func (mock *APIServiceInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAPIServiceInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockAPIServiceInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockAPIServicesGetterMockAPIServices sync.RWMutex +) + +// Ensure, that APIServicesGetterMock does implement v11.APIServicesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.APIServicesGetter = &APIServicesGetterMock{} + +// APIServicesGetterMock is a mock implementation of v11.APIServicesGetter. +// +// func TestSomethingThatUsesAPIServicesGetter(t *testing.T) { +// +// // make and configure a mocked v11.APIServicesGetter +// mockedAPIServicesGetter := &APIServicesGetterMock{ +// APIServicesFunc: func(namespace string) v11.APIServiceInterface { +// panic("mock out the APIServices method") +// }, +// } +// +// // use mockedAPIServicesGetter in code that requires v11.APIServicesGetter +// // and then make assertions. +// +// } +type APIServicesGetterMock struct { + // APIServicesFunc mocks the APIServices method. + APIServicesFunc func(namespace string) v11.APIServiceInterface + + // calls tracks calls to the methods. + calls struct { + // APIServices holds details about calls to the APIServices method. + APIServices []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// APIServices calls APIServicesFunc. +func (mock *APIServicesGetterMock) APIServices(namespace string) v11.APIServiceInterface { + if mock.APIServicesFunc == nil { + panic("APIServicesGetterMock.APIServicesFunc: method is nil but APIServicesGetter.APIServices was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockAPIServicesGetterMockAPIServices.Lock() + mock.calls.APIServices = append(mock.calls.APIServices, callInfo) + lockAPIServicesGetterMockAPIServices.Unlock() + return mock.APIServicesFunc(namespace) +} + +// APIServicesCalls gets all the calls that were made to APIServices. +// Check the length with: +// +// len(mockedAPIServicesGetter.APIServicesCalls()) +func (mock *APIServicesGetterMock) APIServicesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockAPIServicesGetterMockAPIServices.RLock() + calls = mock.calls.APIServices + lockAPIServicesGetterMockAPIServices.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_controller.go new file mode 100644 index 0000000..9415e6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +var ( + APIServiceGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "APIService", + } + APIServiceResource = metav1.APIResource{ + Name: "apiservices", + SingularName: "apiservice", + Namespaced: false, + Kind: APIServiceGroupVersionKind.Kind, + } + + APIServiceGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "apiservices", + } +) + +func init() { + resource.Put(APIServiceGroupVersionResource) +} + +// Deprecated: use v1.APIService instead +type APIService = v1.APIService + +func NewAPIService(namespace, name string, obj v1.APIService) *v1.APIService { + obj.APIVersion, obj.Kind = APIServiceGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type APIServiceHandlerFunc func(key string, obj *v1.APIService) (runtime.Object, error) + +type APIServiceChangeHandlerFunc func(obj *v1.APIService) (runtime.Object, error) + +type APIServiceLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.APIService, err error) + Get(namespace, name string) (*v1.APIService, error) +} + +type APIServiceController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() APIServiceLister + AddHandler(ctx context.Context, name string, handler APIServiceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync APIServiceHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler APIServiceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler APIServiceHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type APIServiceInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.APIService) (*v1.APIService, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.APIService, error) + Get(name string, opts metav1.GetOptions) (*v1.APIService, error) + Update(*v1.APIService) (*v1.APIService, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.APIServiceList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.APIServiceList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() APIServiceController + AddHandler(ctx context.Context, name string, sync APIServiceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync APIServiceHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle APIServiceLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle APIServiceLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync APIServiceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync APIServiceHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle APIServiceLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle APIServiceLifecycle) +} + +type apiServiceLister struct { + ns string + controller *apiServiceController +} + +func (l *apiServiceLister) List(namespace string, selector labels.Selector) (ret []*v1.APIService, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.APIService)) + }) + return +} + +func (l *apiServiceLister) Get(namespace, name string) (*v1.APIService, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: APIServiceGroupVersionKind.Group, + Resource: APIServiceGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.APIService), nil +} + +type apiServiceController struct { + ns string + controller.GenericController +} + +func (c *apiServiceController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *apiServiceController) Lister() APIServiceLister { + return &apiServiceLister{ + ns: c.ns, + controller: c, + } +} + +func (c *apiServiceController) AddHandler(ctx context.Context, name string, handler APIServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.APIService); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *apiServiceController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler APIServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.APIService); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *apiServiceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler APIServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.APIService); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *apiServiceController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler APIServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.APIService); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type apiServiceFactory struct { +} + +func (c apiServiceFactory) Object() runtime.Object { + return &v1.APIService{} +} + +func (c apiServiceFactory) List() runtime.Object { + return &v1.APIServiceList{} +} + +func (s *apiServiceClient) Controller() APIServiceController { + genericController := controller.NewGenericController(s.ns, APIServiceGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(APIServiceGroupVersionResource, APIServiceGroupVersionKind.Kind, false)) + + return &apiServiceController{ + ns: s.ns, + GenericController: genericController, + } +} + +type apiServiceClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller APIServiceController +} + +func (s *apiServiceClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *apiServiceClient) Create(o *v1.APIService) (*v1.APIService, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) Get(name string, opts metav1.GetOptions) (*v1.APIService, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.APIService, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) Update(o *v1.APIService) (*v1.APIService, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) UpdateStatus(o *v1.APIService) (*v1.APIService, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *apiServiceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *apiServiceClient) List(opts metav1.ListOptions) (*v1.APIServiceList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.APIServiceList), err +} + +func (s *apiServiceClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.APIServiceList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.APIServiceList), err +} + +func (s *apiServiceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *apiServiceClient) Patch(o *v1.APIService, patchType types.PatchType, data []byte, subresources ...string) (*v1.APIService, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.APIService), err +} + +func (s *apiServiceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *apiServiceClient) AddHandler(ctx context.Context, name string, sync APIServiceHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *apiServiceClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync APIServiceHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *apiServiceClient) AddLifecycle(ctx context.Context, name string, lifecycle APIServiceLifecycle) { + sync := NewAPIServiceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *apiServiceClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle APIServiceLifecycle) { + sync := NewAPIServiceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *apiServiceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync APIServiceHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *apiServiceClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync APIServiceHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *apiServiceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle APIServiceLifecycle) { + sync := NewAPIServiceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *apiServiceClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle APIServiceLifecycle) { + sync := NewAPIServiceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_lifecycle_adapter.go new file mode 100644 index 0000000..c8cd69c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_api_service_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +type APIServiceLifecycle interface { + Create(obj *v1.APIService) (runtime.Object, error) + Remove(obj *v1.APIService) (runtime.Object, error) + Updated(obj *v1.APIService) (runtime.Object, error) +} + +type apiServiceLifecycleAdapter struct { + lifecycle APIServiceLifecycle +} + +func (w *apiServiceLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *apiServiceLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *apiServiceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.APIService)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *apiServiceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.APIService)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *apiServiceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.APIService)) + if o == nil { + return nil, err + } + return o, err +} + +func NewAPIServiceLifecycleAdapter(name string, clusterScoped bool, client APIServiceInterface, l APIServiceLifecycle) APIServiceHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(APIServiceGroupVersionResource) + } + adapter := &apiServiceLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.APIService) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..e5a02de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_k8s_client.go @@ -0,0 +1,63 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +type Interface interface { + APIServicesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type APIServicesGetter interface { + APIServices(namespace string) APIServiceInterface +} + +func (c *Client) APIServices(namespace string) APIServiceInterface { + sharedClient := c.clientFactory.ForResourceKind(APIServiceGroupVersionResource, APIServiceGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &APIServiceResource, APIServiceGroupVersionKind, apiServiceFactory{}) + return &apiServiceClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_scheme.go new file mode 100644 index 0000000..6e0a0cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apiregistration.k8s.io/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "apiregistration.k8s.io" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_daemon_set_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_daemon_set_mock.go new file mode 100644 index 0000000..c27933d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_daemon_set_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockDaemonSetListerMockGet sync.RWMutex + lockDaemonSetListerMockList sync.RWMutex +) + +// Ensure, that DaemonSetListerMock does implement v11.DaemonSetLister. +// If this is not the case, regenerate this file with moq. +var _ v11.DaemonSetLister = &DaemonSetListerMock{} + +// DaemonSetListerMock is a mock implementation of v11.DaemonSetLister. +// +// func TestSomethingThatUsesDaemonSetLister(t *testing.T) { +// +// // make and configure a mocked v11.DaemonSetLister +// mockedDaemonSetLister := &DaemonSetListerMock{ +// GetFunc: func(namespace string, name string) (*v1.DaemonSet, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.DaemonSet, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedDaemonSetLister in code that requires v11.DaemonSetLister +// // and then make assertions. +// +// } +type DaemonSetListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.DaemonSet, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.DaemonSet, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *DaemonSetListerMock) Get(namespace string, name string) (*v1.DaemonSet, error) { + if mock.GetFunc == nil { + panic("DaemonSetListerMock.GetFunc: method is nil but DaemonSetLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDaemonSetListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDaemonSetListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDaemonSetLister.GetCalls()) +func (mock *DaemonSetListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDaemonSetListerMockGet.RLock() + calls = mock.calls.Get + lockDaemonSetListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DaemonSetListerMock) List(namespace string, selector labels.Selector) ([]*v1.DaemonSet, error) { + if mock.ListFunc == nil { + panic("DaemonSetListerMock.ListFunc: method is nil but DaemonSetLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockDaemonSetListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDaemonSetListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDaemonSetLister.ListCalls()) +func (mock *DaemonSetListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockDaemonSetListerMockList.RLock() + calls = mock.calls.List + lockDaemonSetListerMockList.RUnlock() + return calls +} + +var ( + lockDaemonSetControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockDaemonSetControllerMockAddClusterScopedHandler sync.RWMutex + lockDaemonSetControllerMockAddFeatureHandler sync.RWMutex + lockDaemonSetControllerMockAddHandler sync.RWMutex + lockDaemonSetControllerMockEnqueue sync.RWMutex + lockDaemonSetControllerMockEnqueueAfter sync.RWMutex + lockDaemonSetControllerMockGeneric sync.RWMutex + lockDaemonSetControllerMockInformer sync.RWMutex + lockDaemonSetControllerMockLister sync.RWMutex +) + +// Ensure, that DaemonSetControllerMock does implement v11.DaemonSetController. +// If this is not the case, regenerate this file with moq. +var _ v11.DaemonSetController = &DaemonSetControllerMock{} + +// DaemonSetControllerMock is a mock implementation of v11.DaemonSetController. +// +// func TestSomethingThatUsesDaemonSetController(t *testing.T) { +// +// // make and configure a mocked v11.DaemonSetController +// mockedDaemonSetController := &DaemonSetControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DaemonSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.DaemonSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.DaemonSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.DaemonSetLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedDaemonSetController in code that requires v11.DaemonSetController +// // and then make assertions. +// +// } +type DaemonSetControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DaemonSetHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.DaemonSetHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.DaemonSetHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.DaemonSetLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.DaemonSetHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.DaemonSetHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DaemonSetHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.DaemonSetHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DaemonSetControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DaemonSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DaemonSetControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but DaemonSetController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDaemonSetControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDaemonSetControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDaemonSetController.AddClusterScopedFeatureHandlerCalls()) +func (mock *DaemonSetControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc + } + lockDaemonSetControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDaemonSetControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DaemonSetControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.DaemonSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DaemonSetControllerMock.AddClusterScopedHandlerFunc: method is nil but DaemonSetController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDaemonSetControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDaemonSetControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDaemonSetController.AddClusterScopedHandlerCalls()) +func (mock *DaemonSetControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DaemonSetHandlerFunc + } + lockDaemonSetControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDaemonSetControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DaemonSetControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DaemonSetControllerMock.AddFeatureHandlerFunc: method is nil but DaemonSetController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDaemonSetControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDaemonSetControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDaemonSetController.AddFeatureHandlerCalls()) +func (mock *DaemonSetControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc + } + lockDaemonSetControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDaemonSetControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DaemonSetControllerMock) AddHandler(ctx context.Context, name string, handler v11.DaemonSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DaemonSetControllerMock.AddHandlerFunc: method is nil but DaemonSetController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockDaemonSetControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDaemonSetControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDaemonSetController.AddHandlerCalls()) +func (mock *DaemonSetControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.DaemonSetHandlerFunc + } + lockDaemonSetControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDaemonSetControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *DaemonSetControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("DaemonSetControllerMock.EnqueueFunc: method is nil but DaemonSetController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDaemonSetControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockDaemonSetControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedDaemonSetController.EnqueueCalls()) +func (mock *DaemonSetControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDaemonSetControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockDaemonSetControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *DaemonSetControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("DaemonSetControllerMock.EnqueueAfterFunc: method is nil but DaemonSetController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockDaemonSetControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockDaemonSetControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedDaemonSetController.EnqueueAfterCalls()) +func (mock *DaemonSetControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockDaemonSetControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockDaemonSetControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *DaemonSetControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("DaemonSetControllerMock.GenericFunc: method is nil but DaemonSetController.Generic was just called") + } + callInfo := struct { + }{} + lockDaemonSetControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockDaemonSetControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedDaemonSetController.GenericCalls()) +func (mock *DaemonSetControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockDaemonSetControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockDaemonSetControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *DaemonSetControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("DaemonSetControllerMock.InformerFunc: method is nil but DaemonSetController.Informer was just called") + } + callInfo := struct { + }{} + lockDaemonSetControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockDaemonSetControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedDaemonSetController.InformerCalls()) +func (mock *DaemonSetControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockDaemonSetControllerMockInformer.RLock() + calls = mock.calls.Informer + lockDaemonSetControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *DaemonSetControllerMock) Lister() v11.DaemonSetLister { + if mock.ListerFunc == nil { + panic("DaemonSetControllerMock.ListerFunc: method is nil but DaemonSetController.Lister was just called") + } + callInfo := struct { + }{} + lockDaemonSetControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockDaemonSetControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedDaemonSetController.ListerCalls()) +func (mock *DaemonSetControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockDaemonSetControllerMockLister.RLock() + calls = mock.calls.Lister + lockDaemonSetControllerMockLister.RUnlock() + return calls +} + +var ( + lockDaemonSetInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockDaemonSetInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockDaemonSetInterfaceMockAddClusterScopedHandler sync.RWMutex + lockDaemonSetInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockDaemonSetInterfaceMockAddFeatureHandler sync.RWMutex + lockDaemonSetInterfaceMockAddFeatureLifecycle sync.RWMutex + lockDaemonSetInterfaceMockAddHandler sync.RWMutex + lockDaemonSetInterfaceMockAddLifecycle sync.RWMutex + lockDaemonSetInterfaceMockController sync.RWMutex + lockDaemonSetInterfaceMockCreate sync.RWMutex + lockDaemonSetInterfaceMockDelete sync.RWMutex + lockDaemonSetInterfaceMockDeleteCollection sync.RWMutex + lockDaemonSetInterfaceMockDeleteNamespaced sync.RWMutex + lockDaemonSetInterfaceMockGet sync.RWMutex + lockDaemonSetInterfaceMockGetNamespaced sync.RWMutex + lockDaemonSetInterfaceMockList sync.RWMutex + lockDaemonSetInterfaceMockListNamespaced sync.RWMutex + lockDaemonSetInterfaceMockObjectClient sync.RWMutex + lockDaemonSetInterfaceMockUpdate sync.RWMutex + lockDaemonSetInterfaceMockWatch sync.RWMutex +) + +// Ensure, that DaemonSetInterfaceMock does implement v11.DaemonSetInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.DaemonSetInterface = &DaemonSetInterfaceMock{} + +// DaemonSetInterfaceMock is a mock implementation of v11.DaemonSetInterface. +// +// func TestSomethingThatUsesDaemonSetInterface(t *testing.T) { +// +// // make and configure a mocked v11.DaemonSetInterface +// mockedDaemonSetInterface := &DaemonSetInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.DaemonSetLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.DaemonSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.DaemonSetLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.DaemonSetController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.DaemonSet) (*v1.DaemonSet, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.DaemonSetList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.DaemonSetList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.DaemonSet) (*v1.DaemonSet, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedDaemonSetInterface in code that requires v11.DaemonSetInterface +// // and then make assertions. +// +// } +type DaemonSetInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.DaemonSetLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.DaemonSetHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.DaemonSetLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.DaemonSetController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.DaemonSet) (*v1.DaemonSet, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.DaemonSet, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.DaemonSet, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.DaemonSetList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.DaemonSetList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.DaemonSet) (*v1.DaemonSet, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.DaemonSetHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DaemonSetLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.DaemonSetHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DaemonSetLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DaemonSetHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DaemonSetLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DaemonSetHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DaemonSetLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.DaemonSet + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.DaemonSet + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DaemonSetInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DaemonSetInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but DaemonSetInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDaemonSetInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDaemonSetInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *DaemonSetInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc + } + lockDaemonSetInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDaemonSetInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *DaemonSetInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("DaemonSetInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but DaemonSetInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDaemonSetInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockDaemonSetInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *DaemonSetInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle + } + lockDaemonSetInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockDaemonSetInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DaemonSetInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.DaemonSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DaemonSetInterfaceMock.AddClusterScopedHandlerFunc: method is nil but DaemonSetInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDaemonSetInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDaemonSetInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddClusterScopedHandlerCalls()) +func (mock *DaemonSetInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DaemonSetHandlerFunc + } + lockDaemonSetInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDaemonSetInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *DaemonSetInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.DaemonSetLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("DaemonSetInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but DaemonSetInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDaemonSetInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockDaemonSetInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddClusterScopedLifecycleCalls()) +func (mock *DaemonSetInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DaemonSetLifecycle + } + lockDaemonSetInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockDaemonSetInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DaemonSetInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DaemonSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DaemonSetInterfaceMock.AddFeatureHandlerFunc: method is nil but DaemonSetInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDaemonSetInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDaemonSetInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddFeatureHandlerCalls()) +func (mock *DaemonSetInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DaemonSetHandlerFunc + } + lockDaemonSetInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDaemonSetInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *DaemonSetInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.DaemonSetLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("DaemonSetInterfaceMock.AddFeatureLifecycleFunc: method is nil but DaemonSetInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DaemonSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockDaemonSetInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockDaemonSetInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddFeatureLifecycleCalls()) +func (mock *DaemonSetInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DaemonSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DaemonSetLifecycle + } + lockDaemonSetInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockDaemonSetInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DaemonSetInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.DaemonSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DaemonSetInterfaceMock.AddHandlerFunc: method is nil but DaemonSetInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.DaemonSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockDaemonSetInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDaemonSetInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddHandlerCalls()) +func (mock *DaemonSetInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.DaemonSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.DaemonSetHandlerFunc + } + lockDaemonSetInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDaemonSetInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *DaemonSetInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.DaemonSetLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("DaemonSetInterfaceMock.AddLifecycleFunc: method is nil but DaemonSetInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.DaemonSetLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockDaemonSetInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockDaemonSetInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedDaemonSetInterface.AddLifecycleCalls()) +func (mock *DaemonSetInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.DaemonSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.DaemonSetLifecycle + } + lockDaemonSetInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockDaemonSetInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *DaemonSetInterfaceMock) Controller() v11.DaemonSetController { + if mock.ControllerFunc == nil { + panic("DaemonSetInterfaceMock.ControllerFunc: method is nil but DaemonSetInterface.Controller was just called") + } + callInfo := struct { + }{} + lockDaemonSetInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockDaemonSetInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedDaemonSetInterface.ControllerCalls()) +func (mock *DaemonSetInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockDaemonSetInterfaceMockController.RLock() + calls = mock.calls.Controller + lockDaemonSetInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *DaemonSetInterfaceMock) Create(in1 *v1.DaemonSet) (*v1.DaemonSet, error) { + if mock.CreateFunc == nil { + panic("DaemonSetInterfaceMock.CreateFunc: method is nil but DaemonSetInterface.Create was just called") + } + callInfo := struct { + In1 *v1.DaemonSet + }{ + In1: in1, + } + lockDaemonSetInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockDaemonSetInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedDaemonSetInterface.CreateCalls()) +func (mock *DaemonSetInterfaceMock) CreateCalls() []struct { + In1 *v1.DaemonSet +} { + var calls []struct { + In1 *v1.DaemonSet + } + lockDaemonSetInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockDaemonSetInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *DaemonSetInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("DaemonSetInterfaceMock.DeleteFunc: method is nil but DaemonSetInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockDaemonSetInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockDaemonSetInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedDaemonSetInterface.DeleteCalls()) +func (mock *DaemonSetInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockDaemonSetInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockDaemonSetInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *DaemonSetInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("DaemonSetInterfaceMock.DeleteCollectionFunc: method is nil but DaemonSetInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockDaemonSetInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockDaemonSetInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedDaemonSetInterface.DeleteCollectionCalls()) +func (mock *DaemonSetInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockDaemonSetInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockDaemonSetInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *DaemonSetInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("DaemonSetInterfaceMock.DeleteNamespacedFunc: method is nil but DaemonSetInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockDaemonSetInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockDaemonSetInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedDaemonSetInterface.DeleteNamespacedCalls()) +func (mock *DaemonSetInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockDaemonSetInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockDaemonSetInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *DaemonSetInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { + if mock.GetFunc == nil { + panic("DaemonSetInterfaceMock.GetFunc: method is nil but DaemonSetInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockDaemonSetInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDaemonSetInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDaemonSetInterface.GetCalls()) +func (mock *DaemonSetInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockDaemonSetInterfaceMockGet.RLock() + calls = mock.calls.Get + lockDaemonSetInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *DaemonSetInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { + if mock.GetNamespacedFunc == nil { + panic("DaemonSetInterfaceMock.GetNamespacedFunc: method is nil but DaemonSetInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockDaemonSetInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockDaemonSetInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedDaemonSetInterface.GetNamespacedCalls()) +func (mock *DaemonSetInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockDaemonSetInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockDaemonSetInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DaemonSetInterfaceMock) List(opts metav1.ListOptions) (*v1.DaemonSetList, error) { + if mock.ListFunc == nil { + panic("DaemonSetInterfaceMock.ListFunc: method is nil but DaemonSetInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDaemonSetInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDaemonSetInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDaemonSetInterface.ListCalls()) +func (mock *DaemonSetInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDaemonSetInterfaceMockList.RLock() + calls = mock.calls.List + lockDaemonSetInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *DaemonSetInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DaemonSetList, error) { + if mock.ListNamespacedFunc == nil { + panic("DaemonSetInterfaceMock.ListNamespacedFunc: method is nil but DaemonSetInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockDaemonSetInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockDaemonSetInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedDaemonSetInterface.ListNamespacedCalls()) +func (mock *DaemonSetInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockDaemonSetInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockDaemonSetInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *DaemonSetInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("DaemonSetInterfaceMock.ObjectClientFunc: method is nil but DaemonSetInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockDaemonSetInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockDaemonSetInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedDaemonSetInterface.ObjectClientCalls()) +func (mock *DaemonSetInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockDaemonSetInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockDaemonSetInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *DaemonSetInterfaceMock) Update(in1 *v1.DaemonSet) (*v1.DaemonSet, error) { + if mock.UpdateFunc == nil { + panic("DaemonSetInterfaceMock.UpdateFunc: method is nil but DaemonSetInterface.Update was just called") + } + callInfo := struct { + In1 *v1.DaemonSet + }{ + In1: in1, + } + lockDaemonSetInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockDaemonSetInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedDaemonSetInterface.UpdateCalls()) +func (mock *DaemonSetInterfaceMock) UpdateCalls() []struct { + In1 *v1.DaemonSet +} { + var calls []struct { + In1 *v1.DaemonSet + } + lockDaemonSetInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockDaemonSetInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *DaemonSetInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("DaemonSetInterfaceMock.WatchFunc: method is nil but DaemonSetInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDaemonSetInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockDaemonSetInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedDaemonSetInterface.WatchCalls()) +func (mock *DaemonSetInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDaemonSetInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockDaemonSetInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockDaemonSetsGetterMockDaemonSets sync.RWMutex +) + +// Ensure, that DaemonSetsGetterMock does implement v11.DaemonSetsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.DaemonSetsGetter = &DaemonSetsGetterMock{} + +// DaemonSetsGetterMock is a mock implementation of v11.DaemonSetsGetter. +// +// func TestSomethingThatUsesDaemonSetsGetter(t *testing.T) { +// +// // make and configure a mocked v11.DaemonSetsGetter +// mockedDaemonSetsGetter := &DaemonSetsGetterMock{ +// DaemonSetsFunc: func(namespace string) v11.DaemonSetInterface { +// panic("mock out the DaemonSets method") +// }, +// } +// +// // use mockedDaemonSetsGetter in code that requires v11.DaemonSetsGetter +// // and then make assertions. +// +// } +type DaemonSetsGetterMock struct { + // DaemonSetsFunc mocks the DaemonSets method. + DaemonSetsFunc func(namespace string) v11.DaemonSetInterface + + // calls tracks calls to the methods. + calls struct { + // DaemonSets holds details about calls to the DaemonSets method. + DaemonSets []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// DaemonSets calls DaemonSetsFunc. +func (mock *DaemonSetsGetterMock) DaemonSets(namespace string) v11.DaemonSetInterface { + if mock.DaemonSetsFunc == nil { + panic("DaemonSetsGetterMock.DaemonSetsFunc: method is nil but DaemonSetsGetter.DaemonSets was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockDaemonSetsGetterMockDaemonSets.Lock() + mock.calls.DaemonSets = append(mock.calls.DaemonSets, callInfo) + lockDaemonSetsGetterMockDaemonSets.Unlock() + return mock.DaemonSetsFunc(namespace) +} + +// DaemonSetsCalls gets all the calls that were made to DaemonSets. +// Check the length with: +// +// len(mockedDaemonSetsGetter.DaemonSetsCalls()) +func (mock *DaemonSetsGetterMock) DaemonSetsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockDaemonSetsGetterMockDaemonSets.RLock() + calls = mock.calls.DaemonSets + lockDaemonSetsGetterMockDaemonSets.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_deployment_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_deployment_mock.go new file mode 100644 index 0000000..26c28be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_deployment_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockDeploymentListerMockGet sync.RWMutex + lockDeploymentListerMockList sync.RWMutex +) + +// Ensure, that DeploymentListerMock does implement v11.DeploymentLister. +// If this is not the case, regenerate this file with moq. +var _ v11.DeploymentLister = &DeploymentListerMock{} + +// DeploymentListerMock is a mock implementation of v11.DeploymentLister. +// +// func TestSomethingThatUsesDeploymentLister(t *testing.T) { +// +// // make and configure a mocked v11.DeploymentLister +// mockedDeploymentLister := &DeploymentListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Deployment, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Deployment, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedDeploymentLister in code that requires v11.DeploymentLister +// // and then make assertions. +// +// } +type DeploymentListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Deployment, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Deployment, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *DeploymentListerMock) Get(namespace string, name string) (*v1.Deployment, error) { + if mock.GetFunc == nil { + panic("DeploymentListerMock.GetFunc: method is nil but DeploymentLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDeploymentListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDeploymentListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDeploymentLister.GetCalls()) +func (mock *DeploymentListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDeploymentListerMockGet.RLock() + calls = mock.calls.Get + lockDeploymentListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DeploymentListerMock) List(namespace string, selector labels.Selector) ([]*v1.Deployment, error) { + if mock.ListFunc == nil { + panic("DeploymentListerMock.ListFunc: method is nil but DeploymentLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockDeploymentListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDeploymentListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDeploymentLister.ListCalls()) +func (mock *DeploymentListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockDeploymentListerMockList.RLock() + calls = mock.calls.List + lockDeploymentListerMockList.RUnlock() + return calls +} + +var ( + lockDeploymentControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockDeploymentControllerMockAddClusterScopedHandler sync.RWMutex + lockDeploymentControllerMockAddFeatureHandler sync.RWMutex + lockDeploymentControllerMockAddHandler sync.RWMutex + lockDeploymentControllerMockEnqueue sync.RWMutex + lockDeploymentControllerMockEnqueueAfter sync.RWMutex + lockDeploymentControllerMockGeneric sync.RWMutex + lockDeploymentControllerMockInformer sync.RWMutex + lockDeploymentControllerMockLister sync.RWMutex +) + +// Ensure, that DeploymentControllerMock does implement v11.DeploymentController. +// If this is not the case, regenerate this file with moq. +var _ v11.DeploymentController = &DeploymentControllerMock{} + +// DeploymentControllerMock is a mock implementation of v11.DeploymentController. +// +// func TestSomethingThatUsesDeploymentController(t *testing.T) { +// +// // make and configure a mocked v11.DeploymentController +// mockedDeploymentController := &DeploymentControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DeploymentHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.DeploymentHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.DeploymentHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.DeploymentLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedDeploymentController in code that requires v11.DeploymentController +// // and then make assertions. +// +// } +type DeploymentControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DeploymentHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.DeploymentHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.DeploymentHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.DeploymentLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.DeploymentHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.DeploymentHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DeploymentHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.DeploymentHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DeploymentControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.DeploymentHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DeploymentControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but DeploymentController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDeploymentControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDeploymentControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDeploymentController.AddClusterScopedFeatureHandlerCalls()) +func (mock *DeploymentControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc + } + lockDeploymentControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDeploymentControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DeploymentControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.DeploymentHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DeploymentControllerMock.AddClusterScopedHandlerFunc: method is nil but DeploymentController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDeploymentControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDeploymentControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDeploymentController.AddClusterScopedHandlerCalls()) +func (mock *DeploymentControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.DeploymentHandlerFunc + } + lockDeploymentControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDeploymentControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DeploymentControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DeploymentControllerMock.AddFeatureHandlerFunc: method is nil but DeploymentController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDeploymentControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDeploymentControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDeploymentController.AddFeatureHandlerCalls()) +func (mock *DeploymentControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc + } + lockDeploymentControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDeploymentControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DeploymentControllerMock) AddHandler(ctx context.Context, name string, handler v11.DeploymentHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DeploymentControllerMock.AddHandlerFunc: method is nil but DeploymentController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockDeploymentControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDeploymentControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDeploymentController.AddHandlerCalls()) +func (mock *DeploymentControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.DeploymentHandlerFunc + } + lockDeploymentControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDeploymentControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *DeploymentControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("DeploymentControllerMock.EnqueueFunc: method is nil but DeploymentController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDeploymentControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockDeploymentControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedDeploymentController.EnqueueCalls()) +func (mock *DeploymentControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDeploymentControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockDeploymentControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *DeploymentControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("DeploymentControllerMock.EnqueueAfterFunc: method is nil but DeploymentController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockDeploymentControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockDeploymentControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedDeploymentController.EnqueueAfterCalls()) +func (mock *DeploymentControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockDeploymentControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockDeploymentControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *DeploymentControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("DeploymentControllerMock.GenericFunc: method is nil but DeploymentController.Generic was just called") + } + callInfo := struct { + }{} + lockDeploymentControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockDeploymentControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedDeploymentController.GenericCalls()) +func (mock *DeploymentControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockDeploymentControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockDeploymentControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *DeploymentControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("DeploymentControllerMock.InformerFunc: method is nil but DeploymentController.Informer was just called") + } + callInfo := struct { + }{} + lockDeploymentControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockDeploymentControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedDeploymentController.InformerCalls()) +func (mock *DeploymentControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockDeploymentControllerMockInformer.RLock() + calls = mock.calls.Informer + lockDeploymentControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *DeploymentControllerMock) Lister() v11.DeploymentLister { + if mock.ListerFunc == nil { + panic("DeploymentControllerMock.ListerFunc: method is nil but DeploymentController.Lister was just called") + } + callInfo := struct { + }{} + lockDeploymentControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockDeploymentControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedDeploymentController.ListerCalls()) +func (mock *DeploymentControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockDeploymentControllerMockLister.RLock() + calls = mock.calls.Lister + lockDeploymentControllerMockLister.RUnlock() + return calls +} + +var ( + lockDeploymentInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockDeploymentInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockDeploymentInterfaceMockAddClusterScopedHandler sync.RWMutex + lockDeploymentInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockDeploymentInterfaceMockAddFeatureHandler sync.RWMutex + lockDeploymentInterfaceMockAddFeatureLifecycle sync.RWMutex + lockDeploymentInterfaceMockAddHandler sync.RWMutex + lockDeploymentInterfaceMockAddLifecycle sync.RWMutex + lockDeploymentInterfaceMockController sync.RWMutex + lockDeploymentInterfaceMockCreate sync.RWMutex + lockDeploymentInterfaceMockDelete sync.RWMutex + lockDeploymentInterfaceMockDeleteCollection sync.RWMutex + lockDeploymentInterfaceMockDeleteNamespaced sync.RWMutex + lockDeploymentInterfaceMockGet sync.RWMutex + lockDeploymentInterfaceMockGetNamespaced sync.RWMutex + lockDeploymentInterfaceMockList sync.RWMutex + lockDeploymentInterfaceMockListNamespaced sync.RWMutex + lockDeploymentInterfaceMockObjectClient sync.RWMutex + lockDeploymentInterfaceMockUpdate sync.RWMutex + lockDeploymentInterfaceMockWatch sync.RWMutex +) + +// Ensure, that DeploymentInterfaceMock does implement v11.DeploymentInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.DeploymentInterface = &DeploymentInterfaceMock{} + +// DeploymentInterfaceMock is a mock implementation of v11.DeploymentInterface. +// +// func TestSomethingThatUsesDeploymentInterface(t *testing.T) { +// +// // make and configure a mocked v11.DeploymentInterface +// mockedDeploymentInterface := &DeploymentInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DeploymentLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.DeploymentLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.DeploymentLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.DeploymentHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.DeploymentLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.DeploymentController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Deployment) (*v1.Deployment, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Deployment, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Deployment, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.DeploymentList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.DeploymentList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Deployment) (*v1.Deployment, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedDeploymentInterface in code that requires v11.DeploymentInterface +// // and then make assertions. +// +// } +type DeploymentInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DeploymentLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.DeploymentLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.DeploymentLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.DeploymentHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.DeploymentLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.DeploymentController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Deployment) (*v1.Deployment, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Deployment, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Deployment, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.DeploymentList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.DeploymentList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Deployment) (*v1.Deployment, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.DeploymentHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DeploymentLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.DeploymentHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DeploymentLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DeploymentHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DeploymentLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.DeploymentHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.DeploymentLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Deployment + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Deployment + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DeploymentInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DeploymentInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but DeploymentInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDeploymentInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDeploymentInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDeploymentInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *DeploymentInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc + } + lockDeploymentInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDeploymentInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *DeploymentInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.DeploymentLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("DeploymentInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but DeploymentInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDeploymentInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockDeploymentInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedDeploymentInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *DeploymentInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle + } + lockDeploymentInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockDeploymentInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DeploymentInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.DeploymentHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DeploymentInterfaceMock.AddClusterScopedHandlerFunc: method is nil but DeploymentInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDeploymentInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDeploymentInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDeploymentInterface.AddClusterScopedHandlerCalls()) +func (mock *DeploymentInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.DeploymentHandlerFunc + } + lockDeploymentInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDeploymentInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *DeploymentInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.DeploymentLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("DeploymentInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but DeploymentInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDeploymentInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockDeploymentInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedDeploymentInterface.AddClusterScopedLifecycleCalls()) +func (mock *DeploymentInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.DeploymentLifecycle + } + lockDeploymentInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockDeploymentInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DeploymentInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.DeploymentHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DeploymentInterfaceMock.AddFeatureHandlerFunc: method is nil but DeploymentInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDeploymentInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDeploymentInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDeploymentInterface.AddFeatureHandlerCalls()) +func (mock *DeploymentInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.DeploymentHandlerFunc + } + lockDeploymentInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDeploymentInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *DeploymentInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.DeploymentLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("DeploymentInterfaceMock.AddFeatureLifecycleFunc: method is nil but DeploymentInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DeploymentLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockDeploymentInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockDeploymentInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedDeploymentInterface.AddFeatureLifecycleCalls()) +func (mock *DeploymentInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DeploymentLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.DeploymentLifecycle + } + lockDeploymentInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockDeploymentInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DeploymentInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.DeploymentHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DeploymentInterfaceMock.AddHandlerFunc: method is nil but DeploymentInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.DeploymentHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockDeploymentInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDeploymentInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDeploymentInterface.AddHandlerCalls()) +func (mock *DeploymentInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.DeploymentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.DeploymentHandlerFunc + } + lockDeploymentInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDeploymentInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *DeploymentInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.DeploymentLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("DeploymentInterfaceMock.AddLifecycleFunc: method is nil but DeploymentInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.DeploymentLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockDeploymentInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockDeploymentInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedDeploymentInterface.AddLifecycleCalls()) +func (mock *DeploymentInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.DeploymentLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.DeploymentLifecycle + } + lockDeploymentInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockDeploymentInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *DeploymentInterfaceMock) Controller() v11.DeploymentController { + if mock.ControllerFunc == nil { + panic("DeploymentInterfaceMock.ControllerFunc: method is nil but DeploymentInterface.Controller was just called") + } + callInfo := struct { + }{} + lockDeploymentInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockDeploymentInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedDeploymentInterface.ControllerCalls()) +func (mock *DeploymentInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockDeploymentInterfaceMockController.RLock() + calls = mock.calls.Controller + lockDeploymentInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *DeploymentInterfaceMock) Create(in1 *v1.Deployment) (*v1.Deployment, error) { + if mock.CreateFunc == nil { + panic("DeploymentInterfaceMock.CreateFunc: method is nil but DeploymentInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Deployment + }{ + In1: in1, + } + lockDeploymentInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockDeploymentInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedDeploymentInterface.CreateCalls()) +func (mock *DeploymentInterfaceMock) CreateCalls() []struct { + In1 *v1.Deployment +} { + var calls []struct { + In1 *v1.Deployment + } + lockDeploymentInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockDeploymentInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *DeploymentInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("DeploymentInterfaceMock.DeleteFunc: method is nil but DeploymentInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockDeploymentInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockDeploymentInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedDeploymentInterface.DeleteCalls()) +func (mock *DeploymentInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockDeploymentInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockDeploymentInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *DeploymentInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("DeploymentInterfaceMock.DeleteCollectionFunc: method is nil but DeploymentInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockDeploymentInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockDeploymentInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedDeploymentInterface.DeleteCollectionCalls()) +func (mock *DeploymentInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockDeploymentInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockDeploymentInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *DeploymentInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("DeploymentInterfaceMock.DeleteNamespacedFunc: method is nil but DeploymentInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockDeploymentInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockDeploymentInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedDeploymentInterface.DeleteNamespacedCalls()) +func (mock *DeploymentInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockDeploymentInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockDeploymentInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *DeploymentInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Deployment, error) { + if mock.GetFunc == nil { + panic("DeploymentInterfaceMock.GetFunc: method is nil but DeploymentInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockDeploymentInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDeploymentInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDeploymentInterface.GetCalls()) +func (mock *DeploymentInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockDeploymentInterfaceMockGet.RLock() + calls = mock.calls.Get + lockDeploymentInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *DeploymentInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Deployment, error) { + if mock.GetNamespacedFunc == nil { + panic("DeploymentInterfaceMock.GetNamespacedFunc: method is nil but DeploymentInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockDeploymentInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockDeploymentInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedDeploymentInterface.GetNamespacedCalls()) +func (mock *DeploymentInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockDeploymentInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockDeploymentInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DeploymentInterfaceMock) List(opts metav1.ListOptions) (*v1.DeploymentList, error) { + if mock.ListFunc == nil { + panic("DeploymentInterfaceMock.ListFunc: method is nil but DeploymentInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDeploymentInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDeploymentInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDeploymentInterface.ListCalls()) +func (mock *DeploymentInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDeploymentInterfaceMockList.RLock() + calls = mock.calls.List + lockDeploymentInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *DeploymentInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DeploymentList, error) { + if mock.ListNamespacedFunc == nil { + panic("DeploymentInterfaceMock.ListNamespacedFunc: method is nil but DeploymentInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockDeploymentInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockDeploymentInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedDeploymentInterface.ListNamespacedCalls()) +func (mock *DeploymentInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockDeploymentInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockDeploymentInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *DeploymentInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("DeploymentInterfaceMock.ObjectClientFunc: method is nil but DeploymentInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockDeploymentInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockDeploymentInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedDeploymentInterface.ObjectClientCalls()) +func (mock *DeploymentInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockDeploymentInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockDeploymentInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *DeploymentInterfaceMock) Update(in1 *v1.Deployment) (*v1.Deployment, error) { + if mock.UpdateFunc == nil { + panic("DeploymentInterfaceMock.UpdateFunc: method is nil but DeploymentInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Deployment + }{ + In1: in1, + } + lockDeploymentInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockDeploymentInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedDeploymentInterface.UpdateCalls()) +func (mock *DeploymentInterfaceMock) UpdateCalls() []struct { + In1 *v1.Deployment +} { + var calls []struct { + In1 *v1.Deployment + } + lockDeploymentInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockDeploymentInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *DeploymentInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("DeploymentInterfaceMock.WatchFunc: method is nil but DeploymentInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDeploymentInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockDeploymentInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedDeploymentInterface.WatchCalls()) +func (mock *DeploymentInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDeploymentInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockDeploymentInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockDeploymentsGetterMockDeployments sync.RWMutex +) + +// Ensure, that DeploymentsGetterMock does implement v11.DeploymentsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.DeploymentsGetter = &DeploymentsGetterMock{} + +// DeploymentsGetterMock is a mock implementation of v11.DeploymentsGetter. +// +// func TestSomethingThatUsesDeploymentsGetter(t *testing.T) { +// +// // make and configure a mocked v11.DeploymentsGetter +// mockedDeploymentsGetter := &DeploymentsGetterMock{ +// DeploymentsFunc: func(namespace string) v11.DeploymentInterface { +// panic("mock out the Deployments method") +// }, +// } +// +// // use mockedDeploymentsGetter in code that requires v11.DeploymentsGetter +// // and then make assertions. +// +// } +type DeploymentsGetterMock struct { + // DeploymentsFunc mocks the Deployments method. + DeploymentsFunc func(namespace string) v11.DeploymentInterface + + // calls tracks calls to the methods. + calls struct { + // Deployments holds details about calls to the Deployments method. + Deployments []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Deployments calls DeploymentsFunc. +func (mock *DeploymentsGetterMock) Deployments(namespace string) v11.DeploymentInterface { + if mock.DeploymentsFunc == nil { + panic("DeploymentsGetterMock.DeploymentsFunc: method is nil but DeploymentsGetter.Deployments was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockDeploymentsGetterMockDeployments.Lock() + mock.calls.Deployments = append(mock.calls.Deployments, callInfo) + lockDeploymentsGetterMockDeployments.Unlock() + return mock.DeploymentsFunc(namespace) +} + +// DeploymentsCalls gets all the calls that were made to Deployments. +// Check the length with: +// +// len(mockedDeploymentsGetter.DeploymentsCalls()) +func (mock *DeploymentsGetterMock) DeploymentsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockDeploymentsGetterMockDeployments.RLock() + calls = mock.calls.Deployments + lockDeploymentsGetterMockDeployments.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_replica_set_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_replica_set_mock.go new file mode 100644 index 0000000..0841963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_replica_set_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockReplicaSetListerMockGet sync.RWMutex + lockReplicaSetListerMockList sync.RWMutex +) + +// Ensure, that ReplicaSetListerMock does implement v11.ReplicaSetLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicaSetLister = &ReplicaSetListerMock{} + +// ReplicaSetListerMock is a mock implementation of v11.ReplicaSetLister. +// +// func TestSomethingThatUsesReplicaSetLister(t *testing.T) { +// +// // make and configure a mocked v11.ReplicaSetLister +// mockedReplicaSetLister := &ReplicaSetListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ReplicaSet, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ReplicaSet, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedReplicaSetLister in code that requires v11.ReplicaSetLister +// // and then make assertions. +// +// } +type ReplicaSetListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ReplicaSet, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ReplicaSet, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ReplicaSetListerMock) Get(namespace string, name string) (*v1.ReplicaSet, error) { + if mock.GetFunc == nil { + panic("ReplicaSetListerMock.GetFunc: method is nil but ReplicaSetLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockReplicaSetListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockReplicaSetListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedReplicaSetLister.GetCalls()) +func (mock *ReplicaSetListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockReplicaSetListerMockGet.RLock() + calls = mock.calls.Get + lockReplicaSetListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ReplicaSetListerMock) List(namespace string, selector labels.Selector) ([]*v1.ReplicaSet, error) { + if mock.ListFunc == nil { + panic("ReplicaSetListerMock.ListFunc: method is nil but ReplicaSetLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockReplicaSetListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockReplicaSetListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedReplicaSetLister.ListCalls()) +func (mock *ReplicaSetListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockReplicaSetListerMockList.RLock() + calls = mock.calls.List + lockReplicaSetListerMockList.RUnlock() + return calls +} + +var ( + lockReplicaSetControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockReplicaSetControllerMockAddClusterScopedHandler sync.RWMutex + lockReplicaSetControllerMockAddFeatureHandler sync.RWMutex + lockReplicaSetControllerMockAddHandler sync.RWMutex + lockReplicaSetControllerMockEnqueue sync.RWMutex + lockReplicaSetControllerMockEnqueueAfter sync.RWMutex + lockReplicaSetControllerMockGeneric sync.RWMutex + lockReplicaSetControllerMockInformer sync.RWMutex + lockReplicaSetControllerMockLister sync.RWMutex +) + +// Ensure, that ReplicaSetControllerMock does implement v11.ReplicaSetController. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicaSetController = &ReplicaSetControllerMock{} + +// ReplicaSetControllerMock is a mock implementation of v11.ReplicaSetController. +// +// func TestSomethingThatUsesReplicaSetController(t *testing.T) { +// +// // make and configure a mocked v11.ReplicaSetController +// mockedReplicaSetController := &ReplicaSetControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ReplicaSetLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedReplicaSetController in code that requires v11.ReplicaSetController +// // and then make assertions. +// +// } +type ReplicaSetControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ReplicaSetHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ReplicaSetLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ReplicaSetHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ReplicaSetHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicaSetHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ReplicaSetHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ReplicaSetControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ReplicaSetControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ReplicaSetController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockReplicaSetControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockReplicaSetControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedReplicaSetController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ReplicaSetControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc + } + lockReplicaSetControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockReplicaSetControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ReplicaSetControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ReplicaSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ReplicaSetControllerMock.AddClusterScopedHandlerFunc: method is nil but ReplicaSetController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockReplicaSetControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockReplicaSetControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedReplicaSetController.AddClusterScopedHandlerCalls()) +func (mock *ReplicaSetControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicaSetHandlerFunc + } + lockReplicaSetControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockReplicaSetControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ReplicaSetControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ReplicaSetControllerMock.AddFeatureHandlerFunc: method is nil but ReplicaSetController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockReplicaSetControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockReplicaSetControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedReplicaSetController.AddFeatureHandlerCalls()) +func (mock *ReplicaSetControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc + } + lockReplicaSetControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockReplicaSetControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ReplicaSetControllerMock) AddHandler(ctx context.Context, name string, handler v11.ReplicaSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ReplicaSetControllerMock.AddHandlerFunc: method is nil but ReplicaSetController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockReplicaSetControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockReplicaSetControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedReplicaSetController.AddHandlerCalls()) +func (mock *ReplicaSetControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ReplicaSetHandlerFunc + } + lockReplicaSetControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockReplicaSetControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ReplicaSetControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ReplicaSetControllerMock.EnqueueFunc: method is nil but ReplicaSetController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockReplicaSetControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockReplicaSetControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedReplicaSetController.EnqueueCalls()) +func (mock *ReplicaSetControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockReplicaSetControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockReplicaSetControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ReplicaSetControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ReplicaSetControllerMock.EnqueueAfterFunc: method is nil but ReplicaSetController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockReplicaSetControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockReplicaSetControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedReplicaSetController.EnqueueAfterCalls()) +func (mock *ReplicaSetControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockReplicaSetControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockReplicaSetControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ReplicaSetControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ReplicaSetControllerMock.GenericFunc: method is nil but ReplicaSetController.Generic was just called") + } + callInfo := struct { + }{} + lockReplicaSetControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockReplicaSetControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedReplicaSetController.GenericCalls()) +func (mock *ReplicaSetControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockReplicaSetControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockReplicaSetControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ReplicaSetControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ReplicaSetControllerMock.InformerFunc: method is nil but ReplicaSetController.Informer was just called") + } + callInfo := struct { + }{} + lockReplicaSetControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockReplicaSetControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedReplicaSetController.InformerCalls()) +func (mock *ReplicaSetControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockReplicaSetControllerMockInformer.RLock() + calls = mock.calls.Informer + lockReplicaSetControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ReplicaSetControllerMock) Lister() v11.ReplicaSetLister { + if mock.ListerFunc == nil { + panic("ReplicaSetControllerMock.ListerFunc: method is nil but ReplicaSetController.Lister was just called") + } + callInfo := struct { + }{} + lockReplicaSetControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockReplicaSetControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedReplicaSetController.ListerCalls()) +func (mock *ReplicaSetControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockReplicaSetControllerMockLister.RLock() + calls = mock.calls.Lister + lockReplicaSetControllerMockLister.RUnlock() + return calls +} + +var ( + lockReplicaSetInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockReplicaSetInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockReplicaSetInterfaceMockAddClusterScopedHandler sync.RWMutex + lockReplicaSetInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockReplicaSetInterfaceMockAddFeatureHandler sync.RWMutex + lockReplicaSetInterfaceMockAddFeatureLifecycle sync.RWMutex + lockReplicaSetInterfaceMockAddHandler sync.RWMutex + lockReplicaSetInterfaceMockAddLifecycle sync.RWMutex + lockReplicaSetInterfaceMockController sync.RWMutex + lockReplicaSetInterfaceMockCreate sync.RWMutex + lockReplicaSetInterfaceMockDelete sync.RWMutex + lockReplicaSetInterfaceMockDeleteCollection sync.RWMutex + lockReplicaSetInterfaceMockDeleteNamespaced sync.RWMutex + lockReplicaSetInterfaceMockGet sync.RWMutex + lockReplicaSetInterfaceMockGetNamespaced sync.RWMutex + lockReplicaSetInterfaceMockList sync.RWMutex + lockReplicaSetInterfaceMockListNamespaced sync.RWMutex + lockReplicaSetInterfaceMockObjectClient sync.RWMutex + lockReplicaSetInterfaceMockUpdate sync.RWMutex + lockReplicaSetInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ReplicaSetInterfaceMock does implement v11.ReplicaSetInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicaSetInterface = &ReplicaSetInterfaceMock{} + +// ReplicaSetInterfaceMock is a mock implementation of v11.ReplicaSetInterface. +// +// func TestSomethingThatUsesReplicaSetInterface(t *testing.T) { +// +// // make and configure a mocked v11.ReplicaSetInterface +// mockedReplicaSetInterface := &ReplicaSetInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicaSetLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ReplicaSetLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ReplicaSetController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ReplicaSetList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ReplicaSetList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedReplicaSetInterface in code that requires v11.ReplicaSetInterface +// // and then make assertions. +// +// } +type ReplicaSetInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicaSetLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ReplicaSetHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ReplicaSetLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ReplicaSetController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ReplicaSetList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ReplicaSetList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ReplicaSetHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicaSetLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ReplicaSetHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicaSetLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicaSetHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicaSetLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicaSetHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicaSetLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ReplicaSet + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ReplicaSet + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ReplicaSetInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ReplicaSetInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ReplicaSetInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockReplicaSetInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockReplicaSetInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ReplicaSetInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc + } + lockReplicaSetInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockReplicaSetInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ReplicaSetInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ReplicaSetInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ReplicaSetInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockReplicaSetInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockReplicaSetInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ReplicaSetInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle + } + lockReplicaSetInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockReplicaSetInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ReplicaSetInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicaSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ReplicaSetInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ReplicaSetInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockReplicaSetInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockReplicaSetInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddClusterScopedHandlerCalls()) +func (mock *ReplicaSetInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicaSetHandlerFunc + } + lockReplicaSetInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockReplicaSetInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ReplicaSetInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicaSetLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ReplicaSetInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ReplicaSetInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockReplicaSetInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockReplicaSetInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddClusterScopedLifecycleCalls()) +func (mock *ReplicaSetInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicaSetLifecycle + } + lockReplicaSetInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockReplicaSetInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ReplicaSetInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ReplicaSetInterfaceMock.AddFeatureHandlerFunc: method is nil but ReplicaSetInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockReplicaSetInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockReplicaSetInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddFeatureHandlerCalls()) +func (mock *ReplicaSetInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicaSetHandlerFunc + } + lockReplicaSetInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockReplicaSetInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ReplicaSetInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicaSetLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ReplicaSetInterfaceMock.AddFeatureLifecycleFunc: method is nil but ReplicaSetInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicaSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockReplicaSetInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockReplicaSetInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddFeatureLifecycleCalls()) +func (mock *ReplicaSetInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicaSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicaSetLifecycle + } + lockReplicaSetInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockReplicaSetInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ReplicaSetInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ReplicaSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ReplicaSetInterfaceMock.AddHandlerFunc: method is nil but ReplicaSetInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ReplicaSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockReplicaSetInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockReplicaSetInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddHandlerCalls()) +func (mock *ReplicaSetInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ReplicaSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ReplicaSetHandlerFunc + } + lockReplicaSetInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockReplicaSetInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ReplicaSetInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ReplicaSetLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ReplicaSetInterfaceMock.AddLifecycleFunc: method is nil but ReplicaSetInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicaSetLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockReplicaSetInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockReplicaSetInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedReplicaSetInterface.AddLifecycleCalls()) +func (mock *ReplicaSetInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicaSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicaSetLifecycle + } + lockReplicaSetInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockReplicaSetInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ReplicaSetInterfaceMock) Controller() v11.ReplicaSetController { + if mock.ControllerFunc == nil { + panic("ReplicaSetInterfaceMock.ControllerFunc: method is nil but ReplicaSetInterface.Controller was just called") + } + callInfo := struct { + }{} + lockReplicaSetInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockReplicaSetInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedReplicaSetInterface.ControllerCalls()) +func (mock *ReplicaSetInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockReplicaSetInterfaceMockController.RLock() + calls = mock.calls.Controller + lockReplicaSetInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ReplicaSetInterfaceMock) Create(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) { + if mock.CreateFunc == nil { + panic("ReplicaSetInterfaceMock.CreateFunc: method is nil but ReplicaSetInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ReplicaSet + }{ + In1: in1, + } + lockReplicaSetInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockReplicaSetInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedReplicaSetInterface.CreateCalls()) +func (mock *ReplicaSetInterfaceMock) CreateCalls() []struct { + In1 *v1.ReplicaSet +} { + var calls []struct { + In1 *v1.ReplicaSet + } + lockReplicaSetInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockReplicaSetInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ReplicaSetInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ReplicaSetInterfaceMock.DeleteFunc: method is nil but ReplicaSetInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockReplicaSetInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockReplicaSetInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedReplicaSetInterface.DeleteCalls()) +func (mock *ReplicaSetInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockReplicaSetInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockReplicaSetInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ReplicaSetInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ReplicaSetInterfaceMock.DeleteCollectionFunc: method is nil but ReplicaSetInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockReplicaSetInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockReplicaSetInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedReplicaSetInterface.DeleteCollectionCalls()) +func (mock *ReplicaSetInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockReplicaSetInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockReplicaSetInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ReplicaSetInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ReplicaSetInterfaceMock.DeleteNamespacedFunc: method is nil but ReplicaSetInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockReplicaSetInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockReplicaSetInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedReplicaSetInterface.DeleteNamespacedCalls()) +func (mock *ReplicaSetInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockReplicaSetInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockReplicaSetInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ReplicaSetInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { + if mock.GetFunc == nil { + panic("ReplicaSetInterfaceMock.GetFunc: method is nil but ReplicaSetInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockReplicaSetInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockReplicaSetInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedReplicaSetInterface.GetCalls()) +func (mock *ReplicaSetInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockReplicaSetInterfaceMockGet.RLock() + calls = mock.calls.Get + lockReplicaSetInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ReplicaSetInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { + if mock.GetNamespacedFunc == nil { + panic("ReplicaSetInterfaceMock.GetNamespacedFunc: method is nil but ReplicaSetInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockReplicaSetInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockReplicaSetInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedReplicaSetInterface.GetNamespacedCalls()) +func (mock *ReplicaSetInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockReplicaSetInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockReplicaSetInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ReplicaSetInterfaceMock) List(opts metav1.ListOptions) (*v1.ReplicaSetList, error) { + if mock.ListFunc == nil { + panic("ReplicaSetInterfaceMock.ListFunc: method is nil but ReplicaSetInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockReplicaSetInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockReplicaSetInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedReplicaSetInterface.ListCalls()) +func (mock *ReplicaSetInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockReplicaSetInterfaceMockList.RLock() + calls = mock.calls.List + lockReplicaSetInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ReplicaSetInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicaSetList, error) { + if mock.ListNamespacedFunc == nil { + panic("ReplicaSetInterfaceMock.ListNamespacedFunc: method is nil but ReplicaSetInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockReplicaSetInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockReplicaSetInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedReplicaSetInterface.ListNamespacedCalls()) +func (mock *ReplicaSetInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockReplicaSetInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockReplicaSetInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ReplicaSetInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ReplicaSetInterfaceMock.ObjectClientFunc: method is nil but ReplicaSetInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockReplicaSetInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockReplicaSetInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedReplicaSetInterface.ObjectClientCalls()) +func (mock *ReplicaSetInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockReplicaSetInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockReplicaSetInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ReplicaSetInterfaceMock) Update(in1 *v1.ReplicaSet) (*v1.ReplicaSet, error) { + if mock.UpdateFunc == nil { + panic("ReplicaSetInterfaceMock.UpdateFunc: method is nil but ReplicaSetInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ReplicaSet + }{ + In1: in1, + } + lockReplicaSetInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockReplicaSetInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedReplicaSetInterface.UpdateCalls()) +func (mock *ReplicaSetInterfaceMock) UpdateCalls() []struct { + In1 *v1.ReplicaSet +} { + var calls []struct { + In1 *v1.ReplicaSet + } + lockReplicaSetInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockReplicaSetInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ReplicaSetInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ReplicaSetInterfaceMock.WatchFunc: method is nil but ReplicaSetInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockReplicaSetInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockReplicaSetInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedReplicaSetInterface.WatchCalls()) +func (mock *ReplicaSetInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockReplicaSetInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockReplicaSetInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockReplicaSetsGetterMockReplicaSets sync.RWMutex +) + +// Ensure, that ReplicaSetsGetterMock does implement v11.ReplicaSetsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicaSetsGetter = &ReplicaSetsGetterMock{} + +// ReplicaSetsGetterMock is a mock implementation of v11.ReplicaSetsGetter. +// +// func TestSomethingThatUsesReplicaSetsGetter(t *testing.T) { +// +// // make and configure a mocked v11.ReplicaSetsGetter +// mockedReplicaSetsGetter := &ReplicaSetsGetterMock{ +// ReplicaSetsFunc: func(namespace string) v11.ReplicaSetInterface { +// panic("mock out the ReplicaSets method") +// }, +// } +// +// // use mockedReplicaSetsGetter in code that requires v11.ReplicaSetsGetter +// // and then make assertions. +// +// } +type ReplicaSetsGetterMock struct { + // ReplicaSetsFunc mocks the ReplicaSets method. + ReplicaSetsFunc func(namespace string) v11.ReplicaSetInterface + + // calls tracks calls to the methods. + calls struct { + // ReplicaSets holds details about calls to the ReplicaSets method. + ReplicaSets []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ReplicaSets calls ReplicaSetsFunc. +func (mock *ReplicaSetsGetterMock) ReplicaSets(namespace string) v11.ReplicaSetInterface { + if mock.ReplicaSetsFunc == nil { + panic("ReplicaSetsGetterMock.ReplicaSetsFunc: method is nil but ReplicaSetsGetter.ReplicaSets was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockReplicaSetsGetterMockReplicaSets.Lock() + mock.calls.ReplicaSets = append(mock.calls.ReplicaSets, callInfo) + lockReplicaSetsGetterMockReplicaSets.Unlock() + return mock.ReplicaSetsFunc(namespace) +} + +// ReplicaSetsCalls gets all the calls that were made to ReplicaSets. +// Check the length with: +// +// len(mockedReplicaSetsGetter.ReplicaSetsCalls()) +func (mock *ReplicaSetsGetterMock) ReplicaSetsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockReplicaSetsGetterMockReplicaSets.RLock() + calls = mock.calls.ReplicaSets + lockReplicaSetsGetterMockReplicaSets.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_stateful_set_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_stateful_set_mock.go new file mode 100644 index 0000000..134d87a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/fakes/zz_generated_stateful_set_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + v1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockStatefulSetListerMockGet sync.RWMutex + lockStatefulSetListerMockList sync.RWMutex +) + +// Ensure, that StatefulSetListerMock does implement v11.StatefulSetLister. +// If this is not the case, regenerate this file with moq. +var _ v11.StatefulSetLister = &StatefulSetListerMock{} + +// StatefulSetListerMock is a mock implementation of v11.StatefulSetLister. +// +// func TestSomethingThatUsesStatefulSetLister(t *testing.T) { +// +// // make and configure a mocked v11.StatefulSetLister +// mockedStatefulSetLister := &StatefulSetListerMock{ +// GetFunc: func(namespace string, name string) (*v1.StatefulSet, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.StatefulSet, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedStatefulSetLister in code that requires v11.StatefulSetLister +// // and then make assertions. +// +// } +type StatefulSetListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.StatefulSet, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.StatefulSet, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *StatefulSetListerMock) Get(namespace string, name string) (*v1.StatefulSet, error) { + if mock.GetFunc == nil { + panic("StatefulSetListerMock.GetFunc: method is nil but StatefulSetLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockStatefulSetListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockStatefulSetListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedStatefulSetLister.GetCalls()) +func (mock *StatefulSetListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockStatefulSetListerMockGet.RLock() + calls = mock.calls.Get + lockStatefulSetListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *StatefulSetListerMock) List(namespace string, selector labels.Selector) ([]*v1.StatefulSet, error) { + if mock.ListFunc == nil { + panic("StatefulSetListerMock.ListFunc: method is nil but StatefulSetLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockStatefulSetListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockStatefulSetListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedStatefulSetLister.ListCalls()) +func (mock *StatefulSetListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockStatefulSetListerMockList.RLock() + calls = mock.calls.List + lockStatefulSetListerMockList.RUnlock() + return calls +} + +var ( + lockStatefulSetControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockStatefulSetControllerMockAddClusterScopedHandler sync.RWMutex + lockStatefulSetControllerMockAddFeatureHandler sync.RWMutex + lockStatefulSetControllerMockAddHandler sync.RWMutex + lockStatefulSetControllerMockEnqueue sync.RWMutex + lockStatefulSetControllerMockEnqueueAfter sync.RWMutex + lockStatefulSetControllerMockGeneric sync.RWMutex + lockStatefulSetControllerMockInformer sync.RWMutex + lockStatefulSetControllerMockLister sync.RWMutex +) + +// Ensure, that StatefulSetControllerMock does implement v11.StatefulSetController. +// If this is not the case, regenerate this file with moq. +var _ v11.StatefulSetController = &StatefulSetControllerMock{} + +// StatefulSetControllerMock is a mock implementation of v11.StatefulSetController. +// +// func TestSomethingThatUsesStatefulSetController(t *testing.T) { +// +// // make and configure a mocked v11.StatefulSetController +// mockedStatefulSetController := &StatefulSetControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StatefulSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.StatefulSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.StatefulSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.StatefulSetLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedStatefulSetController in code that requires v11.StatefulSetController +// // and then make assertions. +// +// } +type StatefulSetControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StatefulSetHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.StatefulSetHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.StatefulSetHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.StatefulSetLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.StatefulSetHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.StatefulSetHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StatefulSetHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.StatefulSetHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *StatefulSetControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StatefulSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("StatefulSetControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but StatefulSetController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockStatefulSetControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockStatefulSetControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedStatefulSetController.AddClusterScopedFeatureHandlerCalls()) +func (mock *StatefulSetControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc + } + lockStatefulSetControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockStatefulSetControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *StatefulSetControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.StatefulSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("StatefulSetControllerMock.AddClusterScopedHandlerFunc: method is nil but StatefulSetController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockStatefulSetControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockStatefulSetControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedStatefulSetController.AddClusterScopedHandlerCalls()) +func (mock *StatefulSetControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StatefulSetHandlerFunc + } + lockStatefulSetControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockStatefulSetControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *StatefulSetControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("StatefulSetControllerMock.AddFeatureHandlerFunc: method is nil but StatefulSetController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockStatefulSetControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockStatefulSetControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedStatefulSetController.AddFeatureHandlerCalls()) +func (mock *StatefulSetControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc + } + lockStatefulSetControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockStatefulSetControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *StatefulSetControllerMock) AddHandler(ctx context.Context, name string, handler v11.StatefulSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("StatefulSetControllerMock.AddHandlerFunc: method is nil but StatefulSetController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockStatefulSetControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockStatefulSetControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedStatefulSetController.AddHandlerCalls()) +func (mock *StatefulSetControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.StatefulSetHandlerFunc + } + lockStatefulSetControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockStatefulSetControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *StatefulSetControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("StatefulSetControllerMock.EnqueueFunc: method is nil but StatefulSetController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockStatefulSetControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockStatefulSetControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedStatefulSetController.EnqueueCalls()) +func (mock *StatefulSetControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockStatefulSetControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockStatefulSetControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *StatefulSetControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("StatefulSetControllerMock.EnqueueAfterFunc: method is nil but StatefulSetController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockStatefulSetControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockStatefulSetControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedStatefulSetController.EnqueueAfterCalls()) +func (mock *StatefulSetControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockStatefulSetControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockStatefulSetControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *StatefulSetControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("StatefulSetControllerMock.GenericFunc: method is nil but StatefulSetController.Generic was just called") + } + callInfo := struct { + }{} + lockStatefulSetControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockStatefulSetControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedStatefulSetController.GenericCalls()) +func (mock *StatefulSetControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockStatefulSetControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockStatefulSetControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *StatefulSetControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("StatefulSetControllerMock.InformerFunc: method is nil but StatefulSetController.Informer was just called") + } + callInfo := struct { + }{} + lockStatefulSetControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockStatefulSetControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedStatefulSetController.InformerCalls()) +func (mock *StatefulSetControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockStatefulSetControllerMockInformer.RLock() + calls = mock.calls.Informer + lockStatefulSetControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *StatefulSetControllerMock) Lister() v11.StatefulSetLister { + if mock.ListerFunc == nil { + panic("StatefulSetControllerMock.ListerFunc: method is nil but StatefulSetController.Lister was just called") + } + callInfo := struct { + }{} + lockStatefulSetControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockStatefulSetControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedStatefulSetController.ListerCalls()) +func (mock *StatefulSetControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockStatefulSetControllerMockLister.RLock() + calls = mock.calls.Lister + lockStatefulSetControllerMockLister.RUnlock() + return calls +} + +var ( + lockStatefulSetInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockStatefulSetInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockStatefulSetInterfaceMockAddClusterScopedHandler sync.RWMutex + lockStatefulSetInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockStatefulSetInterfaceMockAddFeatureHandler sync.RWMutex + lockStatefulSetInterfaceMockAddFeatureLifecycle sync.RWMutex + lockStatefulSetInterfaceMockAddHandler sync.RWMutex + lockStatefulSetInterfaceMockAddLifecycle sync.RWMutex + lockStatefulSetInterfaceMockController sync.RWMutex + lockStatefulSetInterfaceMockCreate sync.RWMutex + lockStatefulSetInterfaceMockDelete sync.RWMutex + lockStatefulSetInterfaceMockDeleteCollection sync.RWMutex + lockStatefulSetInterfaceMockDeleteNamespaced sync.RWMutex + lockStatefulSetInterfaceMockGet sync.RWMutex + lockStatefulSetInterfaceMockGetNamespaced sync.RWMutex + lockStatefulSetInterfaceMockList sync.RWMutex + lockStatefulSetInterfaceMockListNamespaced sync.RWMutex + lockStatefulSetInterfaceMockObjectClient sync.RWMutex + lockStatefulSetInterfaceMockUpdate sync.RWMutex + lockStatefulSetInterfaceMockWatch sync.RWMutex +) + +// Ensure, that StatefulSetInterfaceMock does implement v11.StatefulSetInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.StatefulSetInterface = &StatefulSetInterfaceMock{} + +// StatefulSetInterfaceMock is a mock implementation of v11.StatefulSetInterface. +// +// func TestSomethingThatUsesStatefulSetInterface(t *testing.T) { +// +// // make and configure a mocked v11.StatefulSetInterface +// mockedStatefulSetInterface := &StatefulSetInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.StatefulSetLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.StatefulSetHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.StatefulSetLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.StatefulSetController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.StatefulSet) (*v1.StatefulSet, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.StatefulSetList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.StatefulSetList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.StatefulSet) (*v1.StatefulSet, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedStatefulSetInterface in code that requires v11.StatefulSetInterface +// // and then make assertions. +// +// } +type StatefulSetInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.StatefulSetLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.StatefulSetHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.StatefulSetLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.StatefulSetController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.StatefulSet) (*v1.StatefulSet, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.StatefulSet, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.StatefulSet, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.StatefulSetList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.StatefulSetList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.StatefulSet) (*v1.StatefulSet, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.StatefulSetHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StatefulSetLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.StatefulSetHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StatefulSetLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StatefulSetHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StatefulSetLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StatefulSetHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StatefulSetLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.StatefulSet + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.StatefulSet + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *StatefulSetInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("StatefulSetInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but StatefulSetInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockStatefulSetInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockStatefulSetInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *StatefulSetInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc + } + lockStatefulSetInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockStatefulSetInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *StatefulSetInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("StatefulSetInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but StatefulSetInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockStatefulSetInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockStatefulSetInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *StatefulSetInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle + } + lockStatefulSetInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockStatefulSetInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *StatefulSetInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.StatefulSetHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("StatefulSetInterfaceMock.AddClusterScopedHandlerFunc: method is nil but StatefulSetInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockStatefulSetInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockStatefulSetInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddClusterScopedHandlerCalls()) +func (mock *StatefulSetInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StatefulSetHandlerFunc + } + lockStatefulSetInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockStatefulSetInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *StatefulSetInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.StatefulSetLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("StatefulSetInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but StatefulSetInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockStatefulSetInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockStatefulSetInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddClusterScopedLifecycleCalls()) +func (mock *StatefulSetInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StatefulSetLifecycle + } + lockStatefulSetInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockStatefulSetInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *StatefulSetInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StatefulSetHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("StatefulSetInterfaceMock.AddFeatureHandlerFunc: method is nil but StatefulSetInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockStatefulSetInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockStatefulSetInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddFeatureHandlerCalls()) +func (mock *StatefulSetInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StatefulSetHandlerFunc + } + lockStatefulSetInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockStatefulSetInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *StatefulSetInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.StatefulSetLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("StatefulSetInterfaceMock.AddFeatureLifecycleFunc: method is nil but StatefulSetInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StatefulSetLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockStatefulSetInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockStatefulSetInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddFeatureLifecycleCalls()) +func (mock *StatefulSetInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StatefulSetLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StatefulSetLifecycle + } + lockStatefulSetInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockStatefulSetInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *StatefulSetInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.StatefulSetHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("StatefulSetInterfaceMock.AddHandlerFunc: method is nil but StatefulSetInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.StatefulSetHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockStatefulSetInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockStatefulSetInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddHandlerCalls()) +func (mock *StatefulSetInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.StatefulSetHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.StatefulSetHandlerFunc + } + lockStatefulSetInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockStatefulSetInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *StatefulSetInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.StatefulSetLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("StatefulSetInterfaceMock.AddLifecycleFunc: method is nil but StatefulSetInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.StatefulSetLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockStatefulSetInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockStatefulSetInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedStatefulSetInterface.AddLifecycleCalls()) +func (mock *StatefulSetInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.StatefulSetLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.StatefulSetLifecycle + } + lockStatefulSetInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockStatefulSetInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *StatefulSetInterfaceMock) Controller() v11.StatefulSetController { + if mock.ControllerFunc == nil { + panic("StatefulSetInterfaceMock.ControllerFunc: method is nil but StatefulSetInterface.Controller was just called") + } + callInfo := struct { + }{} + lockStatefulSetInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockStatefulSetInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedStatefulSetInterface.ControllerCalls()) +func (mock *StatefulSetInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockStatefulSetInterfaceMockController.RLock() + calls = mock.calls.Controller + lockStatefulSetInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *StatefulSetInterfaceMock) Create(in1 *v1.StatefulSet) (*v1.StatefulSet, error) { + if mock.CreateFunc == nil { + panic("StatefulSetInterfaceMock.CreateFunc: method is nil but StatefulSetInterface.Create was just called") + } + callInfo := struct { + In1 *v1.StatefulSet + }{ + In1: in1, + } + lockStatefulSetInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockStatefulSetInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedStatefulSetInterface.CreateCalls()) +func (mock *StatefulSetInterfaceMock) CreateCalls() []struct { + In1 *v1.StatefulSet +} { + var calls []struct { + In1 *v1.StatefulSet + } + lockStatefulSetInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockStatefulSetInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *StatefulSetInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("StatefulSetInterfaceMock.DeleteFunc: method is nil but StatefulSetInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockStatefulSetInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockStatefulSetInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedStatefulSetInterface.DeleteCalls()) +func (mock *StatefulSetInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockStatefulSetInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockStatefulSetInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *StatefulSetInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("StatefulSetInterfaceMock.DeleteCollectionFunc: method is nil but StatefulSetInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockStatefulSetInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockStatefulSetInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedStatefulSetInterface.DeleteCollectionCalls()) +func (mock *StatefulSetInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockStatefulSetInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockStatefulSetInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *StatefulSetInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("StatefulSetInterfaceMock.DeleteNamespacedFunc: method is nil but StatefulSetInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockStatefulSetInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockStatefulSetInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedStatefulSetInterface.DeleteNamespacedCalls()) +func (mock *StatefulSetInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockStatefulSetInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockStatefulSetInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *StatefulSetInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { + if mock.GetFunc == nil { + panic("StatefulSetInterfaceMock.GetFunc: method is nil but StatefulSetInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockStatefulSetInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockStatefulSetInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedStatefulSetInterface.GetCalls()) +func (mock *StatefulSetInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockStatefulSetInterfaceMockGet.RLock() + calls = mock.calls.Get + lockStatefulSetInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *StatefulSetInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { + if mock.GetNamespacedFunc == nil { + panic("StatefulSetInterfaceMock.GetNamespacedFunc: method is nil but StatefulSetInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockStatefulSetInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockStatefulSetInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedStatefulSetInterface.GetNamespacedCalls()) +func (mock *StatefulSetInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockStatefulSetInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockStatefulSetInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *StatefulSetInterfaceMock) List(opts metav1.ListOptions) (*v1.StatefulSetList, error) { + if mock.ListFunc == nil { + panic("StatefulSetInterfaceMock.ListFunc: method is nil but StatefulSetInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockStatefulSetInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockStatefulSetInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedStatefulSetInterface.ListCalls()) +func (mock *StatefulSetInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockStatefulSetInterfaceMockList.RLock() + calls = mock.calls.List + lockStatefulSetInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *StatefulSetInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StatefulSetList, error) { + if mock.ListNamespacedFunc == nil { + panic("StatefulSetInterfaceMock.ListNamespacedFunc: method is nil but StatefulSetInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockStatefulSetInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockStatefulSetInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedStatefulSetInterface.ListNamespacedCalls()) +func (mock *StatefulSetInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockStatefulSetInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockStatefulSetInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *StatefulSetInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("StatefulSetInterfaceMock.ObjectClientFunc: method is nil but StatefulSetInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockStatefulSetInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockStatefulSetInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedStatefulSetInterface.ObjectClientCalls()) +func (mock *StatefulSetInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockStatefulSetInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockStatefulSetInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *StatefulSetInterfaceMock) Update(in1 *v1.StatefulSet) (*v1.StatefulSet, error) { + if mock.UpdateFunc == nil { + panic("StatefulSetInterfaceMock.UpdateFunc: method is nil but StatefulSetInterface.Update was just called") + } + callInfo := struct { + In1 *v1.StatefulSet + }{ + In1: in1, + } + lockStatefulSetInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockStatefulSetInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedStatefulSetInterface.UpdateCalls()) +func (mock *StatefulSetInterfaceMock) UpdateCalls() []struct { + In1 *v1.StatefulSet +} { + var calls []struct { + In1 *v1.StatefulSet + } + lockStatefulSetInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockStatefulSetInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *StatefulSetInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("StatefulSetInterfaceMock.WatchFunc: method is nil but StatefulSetInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockStatefulSetInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockStatefulSetInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedStatefulSetInterface.WatchCalls()) +func (mock *StatefulSetInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockStatefulSetInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockStatefulSetInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockStatefulSetsGetterMockStatefulSets sync.RWMutex +) + +// Ensure, that StatefulSetsGetterMock does implement v11.StatefulSetsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.StatefulSetsGetter = &StatefulSetsGetterMock{} + +// StatefulSetsGetterMock is a mock implementation of v11.StatefulSetsGetter. +// +// func TestSomethingThatUsesStatefulSetsGetter(t *testing.T) { +// +// // make and configure a mocked v11.StatefulSetsGetter +// mockedStatefulSetsGetter := &StatefulSetsGetterMock{ +// StatefulSetsFunc: func(namespace string) v11.StatefulSetInterface { +// panic("mock out the StatefulSets method") +// }, +// } +// +// // use mockedStatefulSetsGetter in code that requires v11.StatefulSetsGetter +// // and then make assertions. +// +// } +type StatefulSetsGetterMock struct { + // StatefulSetsFunc mocks the StatefulSets method. + StatefulSetsFunc func(namespace string) v11.StatefulSetInterface + + // calls tracks calls to the methods. + calls struct { + // StatefulSets holds details about calls to the StatefulSets method. + StatefulSets []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// StatefulSets calls StatefulSetsFunc. +func (mock *StatefulSetsGetterMock) StatefulSets(namespace string) v11.StatefulSetInterface { + if mock.StatefulSetsFunc == nil { + panic("StatefulSetsGetterMock.StatefulSetsFunc: method is nil but StatefulSetsGetter.StatefulSets was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockStatefulSetsGetterMockStatefulSets.Lock() + mock.calls.StatefulSets = append(mock.calls.StatefulSets, callInfo) + lockStatefulSetsGetterMockStatefulSets.Unlock() + return mock.StatefulSetsFunc(namespace) +} + +// StatefulSetsCalls gets all the calls that were made to StatefulSets. +// Check the length with: +// +// len(mockedStatefulSetsGetter.StatefulSetsCalls()) +func (mock *StatefulSetsGetterMock) StatefulSetsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockStatefulSetsGetterMockStatefulSets.RLock() + calls = mock.calls.StatefulSets + lockStatefulSetsGetterMockStatefulSets.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_controller.go new file mode 100644 index 0000000..5e29e22 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + DaemonSetGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "DaemonSet", + } + DaemonSetResource = metav1.APIResource{ + Name: "daemonsets", + SingularName: "daemonset", + Namespaced: true, + + Kind: DaemonSetGroupVersionKind.Kind, + } + + DaemonSetGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "daemonsets", + } +) + +func init() { + resource.Put(DaemonSetGroupVersionResource) +} + +// Deprecated: use v1.DaemonSet instead +type DaemonSet = v1.DaemonSet + +func NewDaemonSet(namespace, name string, obj v1.DaemonSet) *v1.DaemonSet { + obj.APIVersion, obj.Kind = DaemonSetGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type DaemonSetHandlerFunc func(key string, obj *v1.DaemonSet) (runtime.Object, error) + +type DaemonSetChangeHandlerFunc func(obj *v1.DaemonSet) (runtime.Object, error) + +type DaemonSetLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.DaemonSet, err error) + Get(namespace, name string) (*v1.DaemonSet, error) +} + +type DaemonSetController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() DaemonSetLister + AddHandler(ctx context.Context, name string, handler DaemonSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DaemonSetHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler DaemonSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler DaemonSetHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type DaemonSetInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.DaemonSet) (*v1.DaemonSet, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.DaemonSet, error) + Get(name string, opts metav1.GetOptions) (*v1.DaemonSet, error) + Update(*v1.DaemonSet) (*v1.DaemonSet, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.DaemonSetList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DaemonSetList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() DaemonSetController + AddHandler(ctx context.Context, name string, sync DaemonSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DaemonSetHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle DaemonSetLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DaemonSetLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DaemonSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DaemonSetHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DaemonSetLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DaemonSetLifecycle) +} + +type daemonSetLister struct { + ns string + controller *daemonSetController +} + +func (l *daemonSetLister) List(namespace string, selector labels.Selector) (ret []*v1.DaemonSet, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.DaemonSet)) + }) + return +} + +func (l *daemonSetLister) Get(namespace, name string) (*v1.DaemonSet, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: DaemonSetGroupVersionKind.Group, + Resource: DaemonSetGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.DaemonSet), nil +} + +type daemonSetController struct { + ns string + controller.GenericController +} + +func (c *daemonSetController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *daemonSetController) Lister() DaemonSetLister { + return &daemonSetLister{ + ns: c.ns, + controller: c, + } +} + +func (c *daemonSetController) AddHandler(ctx context.Context, name string, handler DaemonSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.DaemonSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *daemonSetController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler DaemonSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.DaemonSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *daemonSetController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler DaemonSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.DaemonSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *daemonSetController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler DaemonSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.DaemonSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type daemonSetFactory struct { +} + +func (c daemonSetFactory) Object() runtime.Object { + return &v1.DaemonSet{} +} + +func (c daemonSetFactory) List() runtime.Object { + return &v1.DaemonSetList{} +} + +func (s *daemonSetClient) Controller() DaemonSetController { + genericController := controller.NewGenericController(s.ns, DaemonSetGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(DaemonSetGroupVersionResource, DaemonSetGroupVersionKind.Kind, true)) + + return &daemonSetController{ + ns: s.ns, + GenericController: genericController, + } +} + +type daemonSetClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller DaemonSetController +} + +func (s *daemonSetClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *daemonSetClient) Create(o *v1.DaemonSet) (*v1.DaemonSet, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) Get(name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.DaemonSet, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) Update(o *v1.DaemonSet) (*v1.DaemonSet, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) UpdateStatus(o *v1.DaemonSet) (*v1.DaemonSet, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *daemonSetClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *daemonSetClient) List(opts metav1.ListOptions) (*v1.DaemonSetList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.DaemonSetList), err +} + +func (s *daemonSetClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DaemonSetList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.DaemonSetList), err +} + +func (s *daemonSetClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *daemonSetClient) Patch(o *v1.DaemonSet, patchType types.PatchType, data []byte, subresources ...string) (*v1.DaemonSet, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.DaemonSet), err +} + +func (s *daemonSetClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *daemonSetClient) AddHandler(ctx context.Context, name string, sync DaemonSetHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *daemonSetClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DaemonSetHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *daemonSetClient) AddLifecycle(ctx context.Context, name string, lifecycle DaemonSetLifecycle) { + sync := NewDaemonSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *daemonSetClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DaemonSetLifecycle) { + sync := NewDaemonSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *daemonSetClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DaemonSetHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *daemonSetClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DaemonSetHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *daemonSetClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DaemonSetLifecycle) { + sync := NewDaemonSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *daemonSetClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DaemonSetLifecycle) { + sync := NewDaemonSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_lifecycle_adapter.go new file mode 100644 index 0000000..b0a4fe2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_daemon_set_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type DaemonSetLifecycle interface { + Create(obj *v1.DaemonSet) (runtime.Object, error) + Remove(obj *v1.DaemonSet) (runtime.Object, error) + Updated(obj *v1.DaemonSet) (runtime.Object, error) +} + +type daemonSetLifecycleAdapter struct { + lifecycle DaemonSetLifecycle +} + +func (w *daemonSetLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *daemonSetLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *daemonSetLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.DaemonSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *daemonSetLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.DaemonSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *daemonSetLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.DaemonSet)) + if o == nil { + return nil, err + } + return o, err +} + +func NewDaemonSetLifecycleAdapter(name string, clusterScoped bool, client DaemonSetInterface, l DaemonSetLifecycle) DaemonSetHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(DaemonSetGroupVersionResource) + } + adapter := &daemonSetLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.DaemonSet) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_controller.go new file mode 100644 index 0000000..731eff1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + DeploymentGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Deployment", + } + DeploymentResource = metav1.APIResource{ + Name: "deployments", + SingularName: "deployment", + Namespaced: true, + + Kind: DeploymentGroupVersionKind.Kind, + } + + DeploymentGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "deployments", + } +) + +func init() { + resource.Put(DeploymentGroupVersionResource) +} + +// Deprecated: use v1.Deployment instead +type Deployment = v1.Deployment + +func NewDeployment(namespace, name string, obj v1.Deployment) *v1.Deployment { + obj.APIVersion, obj.Kind = DeploymentGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type DeploymentHandlerFunc func(key string, obj *v1.Deployment) (runtime.Object, error) + +type DeploymentChangeHandlerFunc func(obj *v1.Deployment) (runtime.Object, error) + +type DeploymentLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Deployment, err error) + Get(namespace, name string) (*v1.Deployment, error) +} + +type DeploymentController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() DeploymentLister + AddHandler(ctx context.Context, name string, handler DeploymentHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DeploymentHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler DeploymentHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler DeploymentHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type DeploymentInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Deployment) (*v1.Deployment, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error) + Get(name string, opts metav1.GetOptions) (*v1.Deployment, error) + Update(*v1.Deployment) (*v1.Deployment, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.DeploymentList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DeploymentList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() DeploymentController + AddHandler(ctx context.Context, name string, sync DeploymentHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DeploymentHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle DeploymentLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DeploymentLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DeploymentHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DeploymentHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DeploymentLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DeploymentLifecycle) +} + +type deploymentLister struct { + ns string + controller *deploymentController +} + +func (l *deploymentLister) List(namespace string, selector labels.Selector) (ret []*v1.Deployment, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Deployment)) + }) + return +} + +func (l *deploymentLister) Get(namespace, name string) (*v1.Deployment, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: DeploymentGroupVersionKind.Group, + Resource: DeploymentGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Deployment), nil +} + +type deploymentController struct { + ns string + controller.GenericController +} + +func (c *deploymentController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *deploymentController) Lister() DeploymentLister { + return &deploymentLister{ + ns: c.ns, + controller: c, + } +} + +func (c *deploymentController) AddHandler(ctx context.Context, name string, handler DeploymentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Deployment); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *deploymentController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler DeploymentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Deployment); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *deploymentController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler DeploymentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Deployment); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *deploymentController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler DeploymentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Deployment); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type deploymentFactory struct { +} + +func (c deploymentFactory) Object() runtime.Object { + return &v1.Deployment{} +} + +func (c deploymentFactory) List() runtime.Object { + return &v1.DeploymentList{} +} + +func (s *deploymentClient) Controller() DeploymentController { + genericController := controller.NewGenericController(s.ns, DeploymentGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(DeploymentGroupVersionResource, DeploymentGroupVersionKind.Kind, true)) + + return &deploymentController{ + ns: s.ns, + GenericController: genericController, + } +} + +type deploymentClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller DeploymentController +} + +func (s *deploymentClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *deploymentClient) Create(o *v1.Deployment) (*v1.Deployment, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) Get(name string, opts metav1.GetOptions) (*v1.Deployment, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Deployment, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) Update(o *v1.Deployment) (*v1.Deployment, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) UpdateStatus(o *v1.Deployment) (*v1.Deployment, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *deploymentClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *deploymentClient) List(opts metav1.ListOptions) (*v1.DeploymentList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.DeploymentList), err +} + +func (s *deploymentClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.DeploymentList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.DeploymentList), err +} + +func (s *deploymentClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *deploymentClient) Patch(o *v1.Deployment, patchType types.PatchType, data []byte, subresources ...string) (*v1.Deployment, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Deployment), err +} + +func (s *deploymentClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *deploymentClient) AddHandler(ctx context.Context, name string, sync DeploymentHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *deploymentClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DeploymentHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *deploymentClient) AddLifecycle(ctx context.Context, name string, lifecycle DeploymentLifecycle) { + sync := NewDeploymentLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *deploymentClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DeploymentLifecycle) { + sync := NewDeploymentLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *deploymentClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DeploymentHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *deploymentClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DeploymentHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *deploymentClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DeploymentLifecycle) { + sync := NewDeploymentLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *deploymentClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DeploymentLifecycle) { + sync := NewDeploymentLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_lifecycle_adapter.go new file mode 100644 index 0000000..c4ccc19 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_deployment_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type DeploymentLifecycle interface { + Create(obj *v1.Deployment) (runtime.Object, error) + Remove(obj *v1.Deployment) (runtime.Object, error) + Updated(obj *v1.Deployment) (runtime.Object, error) +} + +type deploymentLifecycleAdapter struct { + lifecycle DeploymentLifecycle +} + +func (w *deploymentLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *deploymentLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *deploymentLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Deployment)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *deploymentLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Deployment)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *deploymentLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Deployment)) + if o == nil { + return nil, err + } + return o, err +} + +func NewDeploymentLifecycleAdapter(name string, clusterScoped bool, client DeploymentInterface, l DeploymentLifecycle) DeploymentHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(DeploymentGroupVersionResource) + } + adapter := &deploymentLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Deployment) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..23f727b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_k8s_client.go @@ -0,0 +1,108 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + DeploymentsGetter + DaemonSetsGetter + StatefulSetsGetter + ReplicaSetsGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type DeploymentsGetter interface { + Deployments(namespace string) DeploymentInterface +} + +func (c *Client) Deployments(namespace string) DeploymentInterface { + sharedClient := c.clientFactory.ForResourceKind(DeploymentGroupVersionResource, DeploymentGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &DeploymentResource, DeploymentGroupVersionKind, deploymentFactory{}) + return &deploymentClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type DaemonSetsGetter interface { + DaemonSets(namespace string) DaemonSetInterface +} + +func (c *Client) DaemonSets(namespace string) DaemonSetInterface { + sharedClient := c.clientFactory.ForResourceKind(DaemonSetGroupVersionResource, DaemonSetGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &DaemonSetResource, DaemonSetGroupVersionKind, daemonSetFactory{}) + return &daemonSetClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type StatefulSetsGetter interface { + StatefulSets(namespace string) StatefulSetInterface +} + +func (c *Client) StatefulSets(namespace string) StatefulSetInterface { + sharedClient := c.clientFactory.ForResourceKind(StatefulSetGroupVersionResource, StatefulSetGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &StatefulSetResource, StatefulSetGroupVersionKind, statefulSetFactory{}) + return &statefulSetClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ReplicaSetsGetter interface { + ReplicaSets(namespace string) ReplicaSetInterface +} + +func (c *Client) ReplicaSets(namespace string) ReplicaSetInterface { + sharedClient := c.clientFactory.ForResourceKind(ReplicaSetGroupVersionResource, ReplicaSetGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ReplicaSetResource, ReplicaSetGroupVersionKind, replicaSetFactory{}) + return &replicaSetClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_controller.go new file mode 100644 index 0000000..6dfc355 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ReplicaSetGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ReplicaSet", + } + ReplicaSetResource = metav1.APIResource{ + Name: "replicasets", + SingularName: "replicaset", + Namespaced: true, + + Kind: ReplicaSetGroupVersionKind.Kind, + } + + ReplicaSetGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "replicasets", + } +) + +func init() { + resource.Put(ReplicaSetGroupVersionResource) +} + +// Deprecated: use v1.ReplicaSet instead +type ReplicaSet = v1.ReplicaSet + +func NewReplicaSet(namespace, name string, obj v1.ReplicaSet) *v1.ReplicaSet { + obj.APIVersion, obj.Kind = ReplicaSetGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ReplicaSetHandlerFunc func(key string, obj *v1.ReplicaSet) (runtime.Object, error) + +type ReplicaSetChangeHandlerFunc func(obj *v1.ReplicaSet) (runtime.Object, error) + +type ReplicaSetLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ReplicaSet, err error) + Get(namespace, name string) (*v1.ReplicaSet, error) +} + +type ReplicaSetController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ReplicaSetLister + AddHandler(ctx context.Context, name string, handler ReplicaSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicaSetHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ReplicaSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ReplicaSetHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ReplicaSetInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ReplicaSet) (*v1.ReplicaSet, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) + Get(name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) + Update(*v1.ReplicaSet) (*v1.ReplicaSet, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ReplicaSetList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicaSetList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ReplicaSetController + AddHandler(ctx context.Context, name string, sync ReplicaSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicaSetHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ReplicaSetLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ReplicaSetLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ReplicaSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ReplicaSetHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ReplicaSetLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ReplicaSetLifecycle) +} + +type replicaSetLister struct { + ns string + controller *replicaSetController +} + +func (l *replicaSetLister) List(namespace string, selector labels.Selector) (ret []*v1.ReplicaSet, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ReplicaSet)) + }) + return +} + +func (l *replicaSetLister) Get(namespace, name string) (*v1.ReplicaSet, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ReplicaSetGroupVersionKind.Group, + Resource: ReplicaSetGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ReplicaSet), nil +} + +type replicaSetController struct { + ns string + controller.GenericController +} + +func (c *replicaSetController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *replicaSetController) Lister() ReplicaSetLister { + return &replicaSetLister{ + ns: c.ns, + controller: c, + } +} + +func (c *replicaSetController) AddHandler(ctx context.Context, name string, handler ReplicaSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicaSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicaSetController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ReplicaSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicaSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicaSetController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ReplicaSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicaSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicaSetController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ReplicaSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicaSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type replicaSetFactory struct { +} + +func (c replicaSetFactory) Object() runtime.Object { + return &v1.ReplicaSet{} +} + +func (c replicaSetFactory) List() runtime.Object { + return &v1.ReplicaSetList{} +} + +func (s *replicaSetClient) Controller() ReplicaSetController { + genericController := controller.NewGenericController(s.ns, ReplicaSetGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ReplicaSetGroupVersionResource, ReplicaSetGroupVersionKind.Kind, true)) + + return &replicaSetController{ + ns: s.ns, + GenericController: genericController, + } +} + +type replicaSetClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ReplicaSetController +} + +func (s *replicaSetClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *replicaSetClient) Create(o *v1.ReplicaSet) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) Get(name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) Update(o *v1.ReplicaSet) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) UpdateStatus(o *v1.ReplicaSet) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *replicaSetClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *replicaSetClient) List(opts metav1.ListOptions) (*v1.ReplicaSetList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ReplicaSetList), err +} + +func (s *replicaSetClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicaSetList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ReplicaSetList), err +} + +func (s *replicaSetClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *replicaSetClient) Patch(o *v1.ReplicaSet, patchType types.PatchType, data []byte, subresources ...string) (*v1.ReplicaSet, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ReplicaSet), err +} + +func (s *replicaSetClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *replicaSetClient) AddHandler(ctx context.Context, name string, sync ReplicaSetHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *replicaSetClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicaSetHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *replicaSetClient) AddLifecycle(ctx context.Context, name string, lifecycle ReplicaSetLifecycle) { + sync := NewReplicaSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *replicaSetClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ReplicaSetLifecycle) { + sync := NewReplicaSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *replicaSetClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ReplicaSetHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *replicaSetClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ReplicaSetHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *replicaSetClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ReplicaSetLifecycle) { + sync := NewReplicaSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *replicaSetClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ReplicaSetLifecycle) { + sync := NewReplicaSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_lifecycle_adapter.go new file mode 100644 index 0000000..e1b7d54 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_replica_set_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ReplicaSetLifecycle interface { + Create(obj *v1.ReplicaSet) (runtime.Object, error) + Remove(obj *v1.ReplicaSet) (runtime.Object, error) + Updated(obj *v1.ReplicaSet) (runtime.Object, error) +} + +type replicaSetLifecycleAdapter struct { + lifecycle ReplicaSetLifecycle +} + +func (w *replicaSetLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *replicaSetLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *replicaSetLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ReplicaSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *replicaSetLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ReplicaSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *replicaSetLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ReplicaSet)) + if o == nil { + return nil, err + } + return o, err +} + +func NewReplicaSetLifecycleAdapter(name string, clusterScoped bool, client ReplicaSetInterface, l ReplicaSetLifecycle) ReplicaSetHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ReplicaSetGroupVersionResource) + } + adapter := &replicaSetLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ReplicaSet) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_scheme.go new file mode 100644 index 0000000..30e1deb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "apps" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_controller.go new file mode 100644 index 0000000..f0b4265 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + StatefulSetGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "StatefulSet", + } + StatefulSetResource = metav1.APIResource{ + Name: "statefulsets", + SingularName: "statefulset", + Namespaced: true, + + Kind: StatefulSetGroupVersionKind.Kind, + } + + StatefulSetGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "statefulsets", + } +) + +func init() { + resource.Put(StatefulSetGroupVersionResource) +} + +// Deprecated: use v1.StatefulSet instead +type StatefulSet = v1.StatefulSet + +func NewStatefulSet(namespace, name string, obj v1.StatefulSet) *v1.StatefulSet { + obj.APIVersion, obj.Kind = StatefulSetGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type StatefulSetHandlerFunc func(key string, obj *v1.StatefulSet) (runtime.Object, error) + +type StatefulSetChangeHandlerFunc func(obj *v1.StatefulSet) (runtime.Object, error) + +type StatefulSetLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.StatefulSet, err error) + Get(namespace, name string) (*v1.StatefulSet, error) +} + +type StatefulSetController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() StatefulSetLister + AddHandler(ctx context.Context, name string, handler StatefulSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StatefulSetHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler StatefulSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler StatefulSetHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type StatefulSetInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.StatefulSet) (*v1.StatefulSet, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.StatefulSet, error) + Get(name string, opts metav1.GetOptions) (*v1.StatefulSet, error) + Update(*v1.StatefulSet) (*v1.StatefulSet, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.StatefulSetList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StatefulSetList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() StatefulSetController + AddHandler(ctx context.Context, name string, sync StatefulSetHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StatefulSetHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle StatefulSetLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle StatefulSetLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync StatefulSetHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync StatefulSetHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle StatefulSetLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle StatefulSetLifecycle) +} + +type statefulSetLister struct { + ns string + controller *statefulSetController +} + +func (l *statefulSetLister) List(namespace string, selector labels.Selector) (ret []*v1.StatefulSet, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.StatefulSet)) + }) + return +} + +func (l *statefulSetLister) Get(namespace, name string) (*v1.StatefulSet, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: StatefulSetGroupVersionKind.Group, + Resource: StatefulSetGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.StatefulSet), nil +} + +type statefulSetController struct { + ns string + controller.GenericController +} + +func (c *statefulSetController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *statefulSetController) Lister() StatefulSetLister { + return &statefulSetLister{ + ns: c.ns, + controller: c, + } +} + +func (c *statefulSetController) AddHandler(ctx context.Context, name string, handler StatefulSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StatefulSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *statefulSetController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler StatefulSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StatefulSet); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *statefulSetController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler StatefulSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StatefulSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *statefulSetController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler StatefulSetHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StatefulSet); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type statefulSetFactory struct { +} + +func (c statefulSetFactory) Object() runtime.Object { + return &v1.StatefulSet{} +} + +func (c statefulSetFactory) List() runtime.Object { + return &v1.StatefulSetList{} +} + +func (s *statefulSetClient) Controller() StatefulSetController { + genericController := controller.NewGenericController(s.ns, StatefulSetGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(StatefulSetGroupVersionResource, StatefulSetGroupVersionKind.Kind, true)) + + return &statefulSetController{ + ns: s.ns, + GenericController: genericController, + } +} + +type statefulSetClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller StatefulSetController +} + +func (s *statefulSetClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *statefulSetClient) Create(o *v1.StatefulSet) (*v1.StatefulSet, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) Get(name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.StatefulSet, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) Update(o *v1.StatefulSet) (*v1.StatefulSet, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) UpdateStatus(o *v1.StatefulSet) (*v1.StatefulSet, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *statefulSetClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *statefulSetClient) List(opts metav1.ListOptions) (*v1.StatefulSetList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.StatefulSetList), err +} + +func (s *statefulSetClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StatefulSetList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.StatefulSetList), err +} + +func (s *statefulSetClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *statefulSetClient) Patch(o *v1.StatefulSet, patchType types.PatchType, data []byte, subresources ...string) (*v1.StatefulSet, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.StatefulSet), err +} + +func (s *statefulSetClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *statefulSetClient) AddHandler(ctx context.Context, name string, sync StatefulSetHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *statefulSetClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StatefulSetHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *statefulSetClient) AddLifecycle(ctx context.Context, name string, lifecycle StatefulSetLifecycle) { + sync := NewStatefulSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *statefulSetClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle StatefulSetLifecycle) { + sync := NewStatefulSetLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *statefulSetClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync StatefulSetHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *statefulSetClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync StatefulSetHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *statefulSetClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle StatefulSetLifecycle) { + sync := NewStatefulSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *statefulSetClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle StatefulSetLifecycle) { + sync := NewStatefulSetLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_lifecycle_adapter.go new file mode 100644 index 0000000..6bc0ce9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/apps/v1/zz_generated_stateful_set_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type StatefulSetLifecycle interface { + Create(obj *v1.StatefulSet) (runtime.Object, error) + Remove(obj *v1.StatefulSet) (runtime.Object, error) + Updated(obj *v1.StatefulSet) (runtime.Object, error) +} + +type statefulSetLifecycleAdapter struct { + lifecycle StatefulSetLifecycle +} + +func (w *statefulSetLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *statefulSetLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *statefulSetLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.StatefulSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *statefulSetLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.StatefulSet)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *statefulSetLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.StatefulSet)) + if o == nil { + return nil, err + } + return o, err +} + +func NewStatefulSetLifecycleAdapter(name string, clusterScoped bool, client StatefulSetInterface, l StatefulSetLifecycle) StatefulSetHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(StatefulSetGroupVersionResource) + } + adapter := &statefulSetLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.StatefulSet) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/fakes/zz_generated_horizontal_pod_autoscaler_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/fakes/zz_generated_horizontal_pod_autoscaler_mock.go new file mode 100644 index 0000000..dcd27a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/fakes/zz_generated_horizontal_pod_autoscaler_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v21 "github.com/rancher/rancher/pkg/generated/norman/autoscaling/v2" + v2 "k8s.io/api/autoscaling/v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockHorizontalPodAutoscalerListerMockGet sync.RWMutex + lockHorizontalPodAutoscalerListerMockList sync.RWMutex +) + +// Ensure, that HorizontalPodAutoscalerListerMock does implement v21.HorizontalPodAutoscalerLister. +// If this is not the case, regenerate this file with moq. +var _ v21.HorizontalPodAutoscalerLister = &HorizontalPodAutoscalerListerMock{} + +// HorizontalPodAutoscalerListerMock is a mock implementation of v21.HorizontalPodAutoscalerLister. +// +// func TestSomethingThatUsesHorizontalPodAutoscalerLister(t *testing.T) { +// +// // make and configure a mocked v21.HorizontalPodAutoscalerLister +// mockedHorizontalPodAutoscalerLister := &HorizontalPodAutoscalerListerMock{ +// GetFunc: func(namespace string, name string) (*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedHorizontalPodAutoscalerLister in code that requires v21.HorizontalPodAutoscalerLister +// // and then make assertions. +// +// } +type HorizontalPodAutoscalerListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v2.HorizontalPodAutoscaler, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v2.HorizontalPodAutoscaler, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *HorizontalPodAutoscalerListerMock) Get(namespace string, name string) (*v2.HorizontalPodAutoscaler, error) { + if mock.GetFunc == nil { + panic("HorizontalPodAutoscalerListerMock.GetFunc: method is nil but HorizontalPodAutoscalerLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockHorizontalPodAutoscalerListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockHorizontalPodAutoscalerListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerLister.GetCalls()) +func (mock *HorizontalPodAutoscalerListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockHorizontalPodAutoscalerListerMockGet.RLock() + calls = mock.calls.Get + lockHorizontalPodAutoscalerListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *HorizontalPodAutoscalerListerMock) List(namespace string, selector labels.Selector) ([]*v2.HorizontalPodAutoscaler, error) { + if mock.ListFunc == nil { + panic("HorizontalPodAutoscalerListerMock.ListFunc: method is nil but HorizontalPodAutoscalerLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockHorizontalPodAutoscalerListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockHorizontalPodAutoscalerListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerLister.ListCalls()) +func (mock *HorizontalPodAutoscalerListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockHorizontalPodAutoscalerListerMockList.RLock() + calls = mock.calls.List + lockHorizontalPodAutoscalerListerMockList.RUnlock() + return calls +} + +var ( + lockHorizontalPodAutoscalerControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockHorizontalPodAutoscalerControllerMockAddClusterScopedHandler sync.RWMutex + lockHorizontalPodAutoscalerControllerMockAddFeatureHandler sync.RWMutex + lockHorizontalPodAutoscalerControllerMockAddHandler sync.RWMutex + lockHorizontalPodAutoscalerControllerMockEnqueue sync.RWMutex + lockHorizontalPodAutoscalerControllerMockEnqueueAfter sync.RWMutex + lockHorizontalPodAutoscalerControllerMockGeneric sync.RWMutex + lockHorizontalPodAutoscalerControllerMockInformer sync.RWMutex + lockHorizontalPodAutoscalerControllerMockLister sync.RWMutex +) + +// Ensure, that HorizontalPodAutoscalerControllerMock does implement v21.HorizontalPodAutoscalerController. +// If this is not the case, regenerate this file with moq. +var _ v21.HorizontalPodAutoscalerController = &HorizontalPodAutoscalerControllerMock{} + +// HorizontalPodAutoscalerControllerMock is a mock implementation of v21.HorizontalPodAutoscalerController. +// +// func TestSomethingThatUsesHorizontalPodAutoscalerController(t *testing.T) { +// +// // make and configure a mocked v21.HorizontalPodAutoscalerController +// mockedHorizontalPodAutoscalerController := &HorizontalPodAutoscalerControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v21.HorizontalPodAutoscalerLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedHorizontalPodAutoscalerController in code that requires v21.HorizontalPodAutoscalerController +// // and then make assertions. +// +// } +type HorizontalPodAutoscalerControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v21.HorizontalPodAutoscalerHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v21.HorizontalPodAutoscalerLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but HorizontalPodAutoscalerController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockHorizontalPodAutoscalerControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockHorizontalPodAutoscalerControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.AddClusterScopedFeatureHandlerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockHorizontalPodAutoscalerControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.AddClusterScopedHandlerFunc: method is nil but HorizontalPodAutoscalerController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockHorizontalPodAutoscalerControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockHorizontalPodAutoscalerControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.AddClusterScopedHandlerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockHorizontalPodAutoscalerControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.AddFeatureHandlerFunc: method is nil but HorizontalPodAutoscalerController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockHorizontalPodAutoscalerControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockHorizontalPodAutoscalerControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.AddFeatureHandlerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockHorizontalPodAutoscalerControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) AddHandler(ctx context.Context, name string, handler v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.AddHandlerFunc: method is nil but HorizontalPodAutoscalerController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockHorizontalPodAutoscalerControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockHorizontalPodAutoscalerControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.AddHandlerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockHorizontalPodAutoscalerControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *HorizontalPodAutoscalerControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.EnqueueFunc: method is nil but HorizontalPodAutoscalerController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockHorizontalPodAutoscalerControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockHorizontalPodAutoscalerControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.EnqueueCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockHorizontalPodAutoscalerControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockHorizontalPodAutoscalerControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *HorizontalPodAutoscalerControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.EnqueueAfterFunc: method is nil but HorizontalPodAutoscalerController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockHorizontalPodAutoscalerControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockHorizontalPodAutoscalerControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.EnqueueAfterCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockHorizontalPodAutoscalerControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockHorizontalPodAutoscalerControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *HorizontalPodAutoscalerControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.GenericFunc: method is nil but HorizontalPodAutoscalerController.Generic was just called") + } + callInfo := struct { + }{} + lockHorizontalPodAutoscalerControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockHorizontalPodAutoscalerControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.GenericCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockHorizontalPodAutoscalerControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockHorizontalPodAutoscalerControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.InformerFunc: method is nil but HorizontalPodAutoscalerController.Informer was just called") + } + callInfo := struct { + }{} + lockHorizontalPodAutoscalerControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockHorizontalPodAutoscalerControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.InformerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockHorizontalPodAutoscalerControllerMockInformer.RLock() + calls = mock.calls.Informer + lockHorizontalPodAutoscalerControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *HorizontalPodAutoscalerControllerMock) Lister() v21.HorizontalPodAutoscalerLister { + if mock.ListerFunc == nil { + panic("HorizontalPodAutoscalerControllerMock.ListerFunc: method is nil but HorizontalPodAutoscalerController.Lister was just called") + } + callInfo := struct { + }{} + lockHorizontalPodAutoscalerControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockHorizontalPodAutoscalerControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerController.ListerCalls()) +func (mock *HorizontalPodAutoscalerControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockHorizontalPodAutoscalerControllerMockLister.RLock() + calls = mock.calls.Lister + lockHorizontalPodAutoscalerControllerMockLister.RUnlock() + return calls +} + +var ( + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedHandler sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddFeatureHandler sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddFeatureLifecycle sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddHandler sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockAddLifecycle sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockController sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockCreate sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockDelete sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockDeleteCollection sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockDeleteNamespaced sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockGet sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockGetNamespaced sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockList sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockListNamespaced sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockObjectClient sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockUpdate sync.RWMutex + lockHorizontalPodAutoscalerInterfaceMockWatch sync.RWMutex +) + +// Ensure, that HorizontalPodAutoscalerInterfaceMock does implement v21.HorizontalPodAutoscalerInterface. +// If this is not the case, regenerate this file with moq. +var _ v21.HorizontalPodAutoscalerInterface = &HorizontalPodAutoscalerInterfaceMock{} + +// HorizontalPodAutoscalerInterfaceMock is a mock implementation of v21.HorizontalPodAutoscalerInterface. +// +// func TestSomethingThatUsesHorizontalPodAutoscalerInterface(t *testing.T) { +// +// // make and configure a mocked v21.HorizontalPodAutoscalerInterface +// mockedHorizontalPodAutoscalerInterface := &HorizontalPodAutoscalerInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v21.HorizontalPodAutoscalerController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedHorizontalPodAutoscalerInterface in code that requires v21.HorizontalPodAutoscalerInterface +// // and then make assertions. +// +// } +type HorizontalPodAutoscalerInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v21.HorizontalPodAutoscalerController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v2.HorizontalPodAutoscaler + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v2.HorizontalPodAutoscaler + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but HorizontalPodAutoscalerInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but HorizontalPodAutoscalerInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddClusterScopedHandlerFunc: method is nil but HorizontalPodAutoscalerInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddClusterScopedHandlerCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but HorizontalPodAutoscalerInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddClusterScopedLifecycleCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockHorizontalPodAutoscalerInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddFeatureHandlerFunc: method is nil but HorizontalPodAutoscalerInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockHorizontalPodAutoscalerInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddFeatureHandlerCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockHorizontalPodAutoscalerInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddFeatureLifecycleFunc: method is nil but HorizontalPodAutoscalerInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockHorizontalPodAutoscalerInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddFeatureLifecycleCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + lockHorizontalPodAutoscalerInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockHorizontalPodAutoscalerInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v21.HorizontalPodAutoscalerHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddHandlerFunc: method is nil but HorizontalPodAutoscalerInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockHorizontalPodAutoscalerInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddHandlerCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v21.HorizontalPodAutoscalerHandlerFunc + } + lockHorizontalPodAutoscalerInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockHorizontalPodAutoscalerInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v21.HorizontalPodAutoscalerLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.AddLifecycleFunc: method is nil but HorizontalPodAutoscalerInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockHorizontalPodAutoscalerInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockHorizontalPodAutoscalerInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.AddLifecycleCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v21.HorizontalPodAutoscalerLifecycle + } + lockHorizontalPodAutoscalerInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockHorizontalPodAutoscalerInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Controller() v21.HorizontalPodAutoscalerController { + if mock.ControllerFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.ControllerFunc: method is nil but HorizontalPodAutoscalerInterface.Controller was just called") + } + callInfo := struct { + }{} + lockHorizontalPodAutoscalerInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockHorizontalPodAutoscalerInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.ControllerCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockHorizontalPodAutoscalerInterfaceMockController.RLock() + calls = mock.calls.Controller + lockHorizontalPodAutoscalerInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Create(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { + if mock.CreateFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.CreateFunc: method is nil but HorizontalPodAutoscalerInterface.Create was just called") + } + callInfo := struct { + In1 *v2.HorizontalPodAutoscaler + }{ + In1: in1, + } + lockHorizontalPodAutoscalerInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockHorizontalPodAutoscalerInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.CreateCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) CreateCalls() []struct { + In1 *v2.HorizontalPodAutoscaler +} { + var calls []struct { + In1 *v2.HorizontalPodAutoscaler + } + lockHorizontalPodAutoscalerInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockHorizontalPodAutoscalerInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.DeleteFunc: method is nil but HorizontalPodAutoscalerInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockHorizontalPodAutoscalerInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockHorizontalPodAutoscalerInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.DeleteCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockHorizontalPodAutoscalerInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockHorizontalPodAutoscalerInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.DeleteCollectionFunc: method is nil but HorizontalPodAutoscalerInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockHorizontalPodAutoscalerInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockHorizontalPodAutoscalerInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.DeleteCollectionCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockHorizontalPodAutoscalerInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockHorizontalPodAutoscalerInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.DeleteNamespacedFunc: method is nil but HorizontalPodAutoscalerInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockHorizontalPodAutoscalerInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockHorizontalPodAutoscalerInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.DeleteNamespacedCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockHorizontalPodAutoscalerInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockHorizontalPodAutoscalerInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Get(name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { + if mock.GetFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.GetFunc: method is nil but HorizontalPodAutoscalerInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockHorizontalPodAutoscalerInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockHorizontalPodAutoscalerInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.GetCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockHorizontalPodAutoscalerInterfaceMockGet.RLock() + calls = mock.calls.Get + lockHorizontalPodAutoscalerInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { + if mock.GetNamespacedFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.GetNamespacedFunc: method is nil but HorizontalPodAutoscalerInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockHorizontalPodAutoscalerInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockHorizontalPodAutoscalerInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.GetNamespacedCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockHorizontalPodAutoscalerInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockHorizontalPodAutoscalerInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) List(opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { + if mock.ListFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.ListFunc: method is nil but HorizontalPodAutoscalerInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockHorizontalPodAutoscalerInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockHorizontalPodAutoscalerInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.ListCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockHorizontalPodAutoscalerInterfaceMockList.RLock() + calls = mock.calls.List + lockHorizontalPodAutoscalerInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { + if mock.ListNamespacedFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.ListNamespacedFunc: method is nil but HorizontalPodAutoscalerInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockHorizontalPodAutoscalerInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockHorizontalPodAutoscalerInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.ListNamespacedCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockHorizontalPodAutoscalerInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockHorizontalPodAutoscalerInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.ObjectClientFunc: method is nil but HorizontalPodAutoscalerInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockHorizontalPodAutoscalerInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockHorizontalPodAutoscalerInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.ObjectClientCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockHorizontalPodAutoscalerInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockHorizontalPodAutoscalerInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Update(in1 *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { + if mock.UpdateFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.UpdateFunc: method is nil but HorizontalPodAutoscalerInterface.Update was just called") + } + callInfo := struct { + In1 *v2.HorizontalPodAutoscaler + }{ + In1: in1, + } + lockHorizontalPodAutoscalerInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockHorizontalPodAutoscalerInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.UpdateCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) UpdateCalls() []struct { + In1 *v2.HorizontalPodAutoscaler +} { + var calls []struct { + In1 *v2.HorizontalPodAutoscaler + } + lockHorizontalPodAutoscalerInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockHorizontalPodAutoscalerInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *HorizontalPodAutoscalerInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("HorizontalPodAutoscalerInterfaceMock.WatchFunc: method is nil but HorizontalPodAutoscalerInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockHorizontalPodAutoscalerInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockHorizontalPodAutoscalerInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalerInterface.WatchCalls()) +func (mock *HorizontalPodAutoscalerInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockHorizontalPodAutoscalerInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockHorizontalPodAutoscalerInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockHorizontalPodAutoscalersGetterMockHorizontalPodAutoscalers sync.RWMutex +) + +// Ensure, that HorizontalPodAutoscalersGetterMock does implement v21.HorizontalPodAutoscalersGetter. +// If this is not the case, regenerate this file with moq. +var _ v21.HorizontalPodAutoscalersGetter = &HorizontalPodAutoscalersGetterMock{} + +// HorizontalPodAutoscalersGetterMock is a mock implementation of v21.HorizontalPodAutoscalersGetter. +// +// func TestSomethingThatUsesHorizontalPodAutoscalersGetter(t *testing.T) { +// +// // make and configure a mocked v21.HorizontalPodAutoscalersGetter +// mockedHorizontalPodAutoscalersGetter := &HorizontalPodAutoscalersGetterMock{ +// HorizontalPodAutoscalersFunc: func(namespace string) v21.HorizontalPodAutoscalerInterface { +// panic("mock out the HorizontalPodAutoscalers method") +// }, +// } +// +// // use mockedHorizontalPodAutoscalersGetter in code that requires v21.HorizontalPodAutoscalersGetter +// // and then make assertions. +// +// } +type HorizontalPodAutoscalersGetterMock struct { + // HorizontalPodAutoscalersFunc mocks the HorizontalPodAutoscalers method. + HorizontalPodAutoscalersFunc func(namespace string) v21.HorizontalPodAutoscalerInterface + + // calls tracks calls to the methods. + calls struct { + // HorizontalPodAutoscalers holds details about calls to the HorizontalPodAutoscalers method. + HorizontalPodAutoscalers []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// HorizontalPodAutoscalers calls HorizontalPodAutoscalersFunc. +func (mock *HorizontalPodAutoscalersGetterMock) HorizontalPodAutoscalers(namespace string) v21.HorizontalPodAutoscalerInterface { + if mock.HorizontalPodAutoscalersFunc == nil { + panic("HorizontalPodAutoscalersGetterMock.HorizontalPodAutoscalersFunc: method is nil but HorizontalPodAutoscalersGetter.HorizontalPodAutoscalers was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockHorizontalPodAutoscalersGetterMockHorizontalPodAutoscalers.Lock() + mock.calls.HorizontalPodAutoscalers = append(mock.calls.HorizontalPodAutoscalers, callInfo) + lockHorizontalPodAutoscalersGetterMockHorizontalPodAutoscalers.Unlock() + return mock.HorizontalPodAutoscalersFunc(namespace) +} + +// HorizontalPodAutoscalersCalls gets all the calls that were made to HorizontalPodAutoscalers. +// Check the length with: +// +// len(mockedHorizontalPodAutoscalersGetter.HorizontalPodAutoscalersCalls()) +func (mock *HorizontalPodAutoscalersGetterMock) HorizontalPodAutoscalersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockHorizontalPodAutoscalersGetterMockHorizontalPodAutoscalers.RLock() + calls = mock.calls.HorizontalPodAutoscalers + lockHorizontalPodAutoscalersGetterMockHorizontalPodAutoscalers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_controller.go new file mode 100644 index 0000000..ba5abc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_controller.go @@ -0,0 +1,326 @@ +package v2 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/autoscaling/v2" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + HorizontalPodAutoscalerGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "HorizontalPodAutoscaler", + } + HorizontalPodAutoscalerResource = metav1.APIResource{ + Name: "horizontalpodautoscalers", + SingularName: "horizontalpodautoscaler", + Namespaced: true, + + Kind: HorizontalPodAutoscalerGroupVersionKind.Kind, + } + + HorizontalPodAutoscalerGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "horizontalpodautoscalers", + } +) + +func init() { + resource.Put(HorizontalPodAutoscalerGroupVersionResource) +} + +// Deprecated: use v2.HorizontalPodAutoscaler instead +type HorizontalPodAutoscaler = v2.HorizontalPodAutoscaler + +func NewHorizontalPodAutoscaler(namespace, name string, obj v2.HorizontalPodAutoscaler) *v2.HorizontalPodAutoscaler { + obj.APIVersion, obj.Kind = HorizontalPodAutoscalerGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type HorizontalPodAutoscalerHandlerFunc func(key string, obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) + +type HorizontalPodAutoscalerChangeHandlerFunc func(obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) + +type HorizontalPodAutoscalerLister interface { + List(namespace string, selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) + Get(namespace, name string) (*v2.HorizontalPodAutoscaler, error) +} + +type HorizontalPodAutoscalerController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() HorizontalPodAutoscalerLister + AddHandler(ctx context.Context, name string, handler HorizontalPodAutoscalerHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync HorizontalPodAutoscalerHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler HorizontalPodAutoscalerHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler HorizontalPodAutoscalerHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type HorizontalPodAutoscalerInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) + Get(name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) + Update(*v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() HorizontalPodAutoscalerController + AddHandler(ctx context.Context, name string, sync HorizontalPodAutoscalerHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync HorizontalPodAutoscalerHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle HorizontalPodAutoscalerLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle HorizontalPodAutoscalerLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync HorizontalPodAutoscalerHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync HorizontalPodAutoscalerHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle HorizontalPodAutoscalerLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle HorizontalPodAutoscalerLifecycle) +} + +type horizontalPodAutoscalerLister struct { + ns string + controller *horizontalPodAutoscalerController +} + +func (l *horizontalPodAutoscalerLister) List(namespace string, selector labels.Selector) (ret []*v2.HorizontalPodAutoscaler, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v2.HorizontalPodAutoscaler)) + }) + return +} + +func (l *horizontalPodAutoscalerLister) Get(namespace, name string) (*v2.HorizontalPodAutoscaler, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: HorizontalPodAutoscalerGroupVersionKind.Group, + Resource: HorizontalPodAutoscalerGroupVersionResource.Resource, + }, key) + } + return obj.(*v2.HorizontalPodAutoscaler), nil +} + +type horizontalPodAutoscalerController struct { + ns string + controller.GenericController +} + +func (c *horizontalPodAutoscalerController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *horizontalPodAutoscalerController) Lister() HorizontalPodAutoscalerLister { + return &horizontalPodAutoscalerLister{ + ns: c.ns, + controller: c, + } +} + +func (c *horizontalPodAutoscalerController) AddHandler(ctx context.Context, name string, handler HorizontalPodAutoscalerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v2.HorizontalPodAutoscaler); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *horizontalPodAutoscalerController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler HorizontalPodAutoscalerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v2.HorizontalPodAutoscaler); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *horizontalPodAutoscalerController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler HorizontalPodAutoscalerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v2.HorizontalPodAutoscaler); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *horizontalPodAutoscalerController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler HorizontalPodAutoscalerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v2.HorizontalPodAutoscaler); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type horizontalPodAutoscalerFactory struct { +} + +func (c horizontalPodAutoscalerFactory) Object() runtime.Object { + return &v2.HorizontalPodAutoscaler{} +} + +func (c horizontalPodAutoscalerFactory) List() runtime.Object { + return &v2.HorizontalPodAutoscalerList{} +} + +func (s *horizontalPodAutoscalerClient) Controller() HorizontalPodAutoscalerController { + genericController := controller.NewGenericController(s.ns, HorizontalPodAutoscalerGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(HorizontalPodAutoscalerGroupVersionResource, HorizontalPodAutoscalerGroupVersionKind.Kind, true)) + + return &horizontalPodAutoscalerController{ + ns: s.ns, + GenericController: genericController, + } +} + +type horizontalPodAutoscalerClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller HorizontalPodAutoscalerController +} + +func (s *horizontalPodAutoscalerClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *horizontalPodAutoscalerClient) Create(o *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) Get(name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) Update(o *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) UpdateStatus(o *v2.HorizontalPodAutoscaler) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *horizontalPodAutoscalerClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *horizontalPodAutoscalerClient) List(opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v2.HorizontalPodAutoscalerList), err +} + +func (s *horizontalPodAutoscalerClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v2.HorizontalPodAutoscalerList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v2.HorizontalPodAutoscalerList), err +} + +func (s *horizontalPodAutoscalerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *horizontalPodAutoscalerClient) Patch(o *v2.HorizontalPodAutoscaler, patchType types.PatchType, data []byte, subresources ...string) (*v2.HorizontalPodAutoscaler, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v2.HorizontalPodAutoscaler), err +} + +func (s *horizontalPodAutoscalerClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *horizontalPodAutoscalerClient) AddHandler(ctx context.Context, name string, sync HorizontalPodAutoscalerHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *horizontalPodAutoscalerClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync HorizontalPodAutoscalerHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *horizontalPodAutoscalerClient) AddLifecycle(ctx context.Context, name string, lifecycle HorizontalPodAutoscalerLifecycle) { + sync := NewHorizontalPodAutoscalerLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *horizontalPodAutoscalerClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle HorizontalPodAutoscalerLifecycle) { + sync := NewHorizontalPodAutoscalerLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *horizontalPodAutoscalerClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync HorizontalPodAutoscalerHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *horizontalPodAutoscalerClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync HorizontalPodAutoscalerHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *horizontalPodAutoscalerClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle HorizontalPodAutoscalerLifecycle) { + sync := NewHorizontalPodAutoscalerLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *horizontalPodAutoscalerClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle HorizontalPodAutoscalerLifecycle) { + sync := NewHorizontalPodAutoscalerLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_lifecycle_adapter.go new file mode 100644 index 0000000..6aacbaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_horizontal_pod_autoscaler_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v2 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/autoscaling/v2" + "k8s.io/apimachinery/pkg/runtime" +) + +type HorizontalPodAutoscalerLifecycle interface { + Create(obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) + Remove(obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) + Updated(obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) +} + +type horizontalPodAutoscalerLifecycleAdapter struct { + lifecycle HorizontalPodAutoscalerLifecycle +} + +func (w *horizontalPodAutoscalerLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *horizontalPodAutoscalerLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *horizontalPodAutoscalerLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v2.HorizontalPodAutoscaler)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *horizontalPodAutoscalerLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v2.HorizontalPodAutoscaler)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *horizontalPodAutoscalerLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v2.HorizontalPodAutoscaler)) + if o == nil { + return nil, err + } + return o, err +} + +func NewHorizontalPodAutoscalerLifecycleAdapter(name string, clusterScoped bool, client HorizontalPodAutoscalerInterface, l HorizontalPodAutoscalerLifecycle) HorizontalPodAutoscalerHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(HorizontalPodAutoscalerGroupVersionResource) + } + adapter := &horizontalPodAutoscalerLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v2.HorizontalPodAutoscaler) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_k8s_client.go new file mode 100644 index 0000000..c554396 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_k8s_client.go @@ -0,0 +1,63 @@ +package v2 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/autoscaling/v2" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + HorizontalPodAutoscalersGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v2.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type HorizontalPodAutoscalersGetter interface { + HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface +} + +func (c *Client) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface { + sharedClient := c.clientFactory.ForResourceKind(HorizontalPodAutoscalerGroupVersionResource, HorizontalPodAutoscalerGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &HorizontalPodAutoscalerResource, HorizontalPodAutoscalerGroupVersionKind, horizontalPodAutoscalerFactory{}) + return &horizontalPodAutoscalerClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_scheme.go new file mode 100644 index 0000000..e5e5f58 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/autoscaling/v2/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "autoscaling" + Version = "v2" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_cron_job_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_cron_job_mock.go new file mode 100644 index 0000000..b8502be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_cron_job_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/batch/v1" + v1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCronJobListerMockGet sync.RWMutex + lockCronJobListerMockList sync.RWMutex +) + +// Ensure, that CronJobListerMock does implement v11.CronJobLister. +// If this is not the case, regenerate this file with moq. +var _ v11.CronJobLister = &CronJobListerMock{} + +// CronJobListerMock is a mock implementation of v11.CronJobLister. +// +// func TestSomethingThatUsesCronJobLister(t *testing.T) { +// +// // make and configure a mocked v11.CronJobLister +// mockedCronJobLister := &CronJobListerMock{ +// GetFunc: func(namespace string, name string) (*v1.CronJob, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.CronJob, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCronJobLister in code that requires v11.CronJobLister +// // and then make assertions. +// +// } +type CronJobListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.CronJob, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.CronJob, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CronJobListerMock) Get(namespace string, name string) (*v1.CronJob, error) { + if mock.GetFunc == nil { + panic("CronJobListerMock.GetFunc: method is nil but CronJobLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCronJobListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCronJobListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCronJobLister.GetCalls()) +func (mock *CronJobListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCronJobListerMockGet.RLock() + calls = mock.calls.Get + lockCronJobListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CronJobListerMock) List(namespace string, selector labels.Selector) ([]*v1.CronJob, error) { + if mock.ListFunc == nil { + panic("CronJobListerMock.ListFunc: method is nil but CronJobLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCronJobListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCronJobListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCronJobLister.ListCalls()) +func (mock *CronJobListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCronJobListerMockList.RLock() + calls = mock.calls.List + lockCronJobListerMockList.RUnlock() + return calls +} + +var ( + lockCronJobControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCronJobControllerMockAddClusterScopedHandler sync.RWMutex + lockCronJobControllerMockAddFeatureHandler sync.RWMutex + lockCronJobControllerMockAddHandler sync.RWMutex + lockCronJobControllerMockEnqueue sync.RWMutex + lockCronJobControllerMockEnqueueAfter sync.RWMutex + lockCronJobControllerMockGeneric sync.RWMutex + lockCronJobControllerMockInformer sync.RWMutex + lockCronJobControllerMockLister sync.RWMutex +) + +// Ensure, that CronJobControllerMock does implement v11.CronJobController. +// If this is not the case, regenerate this file with moq. +var _ v11.CronJobController = &CronJobControllerMock{} + +// CronJobControllerMock is a mock implementation of v11.CronJobController. +// +// func TestSomethingThatUsesCronJobController(t *testing.T) { +// +// // make and configure a mocked v11.CronJobController +// mockedCronJobController := &CronJobControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.CronJobHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.CronJobHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.CronJobHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.CronJobLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCronJobController in code that requires v11.CronJobController +// // and then make assertions. +// +// } +type CronJobControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.CronJobHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.CronJobHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.CronJobHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.CronJobLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.CronJobHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.CronJobHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.CronJobHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.CronJobHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CronJobControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.CronJobHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CronJobControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CronJobController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCronJobControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCronJobControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCronJobController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CronJobControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.CronJobHandlerFunc + } + lockCronJobControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCronJobControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CronJobControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.CronJobHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CronJobControllerMock.AddClusterScopedHandlerFunc: method is nil but CronJobController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCronJobControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCronJobControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCronJobController.AddClusterScopedHandlerCalls()) +func (mock *CronJobControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.CronJobHandlerFunc + } + lockCronJobControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCronJobControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CronJobControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CronJobControllerMock.AddFeatureHandlerFunc: method is nil but CronJobController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCronJobControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCronJobControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCronJobController.AddFeatureHandlerCalls()) +func (mock *CronJobControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc + } + lockCronJobControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCronJobControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CronJobControllerMock) AddHandler(ctx context.Context, name string, handler v11.CronJobHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CronJobControllerMock.AddHandlerFunc: method is nil but CronJobController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCronJobControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCronJobControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCronJobController.AddHandlerCalls()) +func (mock *CronJobControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.CronJobHandlerFunc + } + lockCronJobControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCronJobControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CronJobControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CronJobControllerMock.EnqueueFunc: method is nil but CronJobController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCronJobControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCronJobControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCronJobController.EnqueueCalls()) +func (mock *CronJobControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCronJobControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCronJobControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CronJobControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CronJobControllerMock.EnqueueAfterFunc: method is nil but CronJobController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCronJobControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCronJobControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCronJobController.EnqueueAfterCalls()) +func (mock *CronJobControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCronJobControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCronJobControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CronJobControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CronJobControllerMock.GenericFunc: method is nil but CronJobController.Generic was just called") + } + callInfo := struct { + }{} + lockCronJobControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCronJobControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCronJobController.GenericCalls()) +func (mock *CronJobControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCronJobControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCronJobControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CronJobControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CronJobControllerMock.InformerFunc: method is nil but CronJobController.Informer was just called") + } + callInfo := struct { + }{} + lockCronJobControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCronJobControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCronJobController.InformerCalls()) +func (mock *CronJobControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCronJobControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCronJobControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CronJobControllerMock) Lister() v11.CronJobLister { + if mock.ListerFunc == nil { + panic("CronJobControllerMock.ListerFunc: method is nil but CronJobController.Lister was just called") + } + callInfo := struct { + }{} + lockCronJobControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCronJobControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCronJobController.ListerCalls()) +func (mock *CronJobControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCronJobControllerMockLister.RLock() + calls = mock.calls.Lister + lockCronJobControllerMockLister.RUnlock() + return calls +} + +var ( + lockCronJobInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCronJobInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCronJobInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCronJobInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCronJobInterfaceMockAddFeatureHandler sync.RWMutex + lockCronJobInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCronJobInterfaceMockAddHandler sync.RWMutex + lockCronJobInterfaceMockAddLifecycle sync.RWMutex + lockCronJobInterfaceMockController sync.RWMutex + lockCronJobInterfaceMockCreate sync.RWMutex + lockCronJobInterfaceMockDelete sync.RWMutex + lockCronJobInterfaceMockDeleteCollection sync.RWMutex + lockCronJobInterfaceMockDeleteNamespaced sync.RWMutex + lockCronJobInterfaceMockGet sync.RWMutex + lockCronJobInterfaceMockGetNamespaced sync.RWMutex + lockCronJobInterfaceMockList sync.RWMutex + lockCronJobInterfaceMockListNamespaced sync.RWMutex + lockCronJobInterfaceMockObjectClient sync.RWMutex + lockCronJobInterfaceMockUpdate sync.RWMutex + lockCronJobInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CronJobInterfaceMock does implement v11.CronJobInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.CronJobInterface = &CronJobInterfaceMock{} + +// CronJobInterfaceMock is a mock implementation of v11.CronJobInterface. +// +// func TestSomethingThatUsesCronJobInterface(t *testing.T) { +// +// // make and configure a mocked v11.CronJobInterface +// mockedCronJobInterface := &CronJobInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.CronJobLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.CronJobLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.CronJobLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.CronJobHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.CronJobLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.CronJobController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.CronJob) (*v1.CronJob, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.CronJob, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.CronJob, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.CronJobList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.CronJobList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.CronJob) (*v1.CronJob, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCronJobInterface in code that requires v11.CronJobInterface +// // and then make assertions. +// +// } +type CronJobInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.CronJobLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.CronJobLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.CronJobLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.CronJobHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.CronJobLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.CronJobController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.CronJob) (*v1.CronJob, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.CronJob, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.CronJob, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.CronJobList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.CronJobList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.CronJob) (*v1.CronJob, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.CronJobHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.CronJobLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.CronJobHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.CronJobLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.CronJobHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.CronJobLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.CronJobHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.CronJobLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.CronJob + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.CronJob + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CronJobInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CronJobInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CronJobInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCronJobInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCronJobInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCronJobInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CronJobInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.CronJobHandlerFunc + } + lockCronJobInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCronJobInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CronJobInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.CronJobLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CronJobInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CronJobInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCronJobInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCronJobInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCronJobInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CronJobInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle + } + lockCronJobInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCronJobInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CronJobInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.CronJobHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CronJobInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CronJobInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCronJobInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCronJobInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCronJobInterface.AddClusterScopedHandlerCalls()) +func (mock *CronJobInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.CronJobHandlerFunc + } + lockCronJobInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCronJobInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CronJobInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.CronJobLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CronJobInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CronJobInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCronJobInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCronJobInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCronJobInterface.AddClusterScopedLifecycleCalls()) +func (mock *CronJobInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.CronJobLifecycle + } + lockCronJobInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCronJobInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CronJobInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.CronJobHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CronJobInterfaceMock.AddFeatureHandlerFunc: method is nil but CronJobInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCronJobInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCronJobInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCronJobInterface.AddFeatureHandlerCalls()) +func (mock *CronJobInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.CronJobHandlerFunc + } + lockCronJobInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCronJobInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CronJobInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.CronJobLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CronJobInterfaceMock.AddFeatureLifecycleFunc: method is nil but CronJobInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.CronJobLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCronJobInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCronJobInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCronJobInterface.AddFeatureLifecycleCalls()) +func (mock *CronJobInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.CronJobLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.CronJobLifecycle + } + lockCronJobInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCronJobInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CronJobInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.CronJobHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CronJobInterfaceMock.AddHandlerFunc: method is nil but CronJobInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.CronJobHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCronJobInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCronJobInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCronJobInterface.AddHandlerCalls()) +func (mock *CronJobInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.CronJobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.CronJobHandlerFunc + } + lockCronJobInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCronJobInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CronJobInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.CronJobLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CronJobInterfaceMock.AddLifecycleFunc: method is nil but CronJobInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.CronJobLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCronJobInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCronJobInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCronJobInterface.AddLifecycleCalls()) +func (mock *CronJobInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.CronJobLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.CronJobLifecycle + } + lockCronJobInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCronJobInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CronJobInterfaceMock) Controller() v11.CronJobController { + if mock.ControllerFunc == nil { + panic("CronJobInterfaceMock.ControllerFunc: method is nil but CronJobInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCronJobInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCronJobInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCronJobInterface.ControllerCalls()) +func (mock *CronJobInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCronJobInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCronJobInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CronJobInterfaceMock) Create(in1 *v1.CronJob) (*v1.CronJob, error) { + if mock.CreateFunc == nil { + panic("CronJobInterfaceMock.CreateFunc: method is nil but CronJobInterface.Create was just called") + } + callInfo := struct { + In1 *v1.CronJob + }{ + In1: in1, + } + lockCronJobInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCronJobInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCronJobInterface.CreateCalls()) +func (mock *CronJobInterfaceMock) CreateCalls() []struct { + In1 *v1.CronJob +} { + var calls []struct { + In1 *v1.CronJob + } + lockCronJobInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCronJobInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CronJobInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CronJobInterfaceMock.DeleteFunc: method is nil but CronJobInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCronJobInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCronJobInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCronJobInterface.DeleteCalls()) +func (mock *CronJobInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCronJobInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCronJobInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CronJobInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CronJobInterfaceMock.DeleteCollectionFunc: method is nil but CronJobInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCronJobInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCronJobInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCronJobInterface.DeleteCollectionCalls()) +func (mock *CronJobInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCronJobInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCronJobInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CronJobInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CronJobInterfaceMock.DeleteNamespacedFunc: method is nil but CronJobInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCronJobInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCronJobInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCronJobInterface.DeleteNamespacedCalls()) +func (mock *CronJobInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCronJobInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCronJobInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CronJobInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.CronJob, error) { + if mock.GetFunc == nil { + panic("CronJobInterfaceMock.GetFunc: method is nil but CronJobInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCronJobInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCronJobInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCronJobInterface.GetCalls()) +func (mock *CronJobInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCronJobInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCronJobInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CronJobInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.CronJob, error) { + if mock.GetNamespacedFunc == nil { + panic("CronJobInterfaceMock.GetNamespacedFunc: method is nil but CronJobInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCronJobInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCronJobInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCronJobInterface.GetNamespacedCalls()) +func (mock *CronJobInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCronJobInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCronJobInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CronJobInterfaceMock) List(opts metav1.ListOptions) (*v1.CronJobList, error) { + if mock.ListFunc == nil { + panic("CronJobInterfaceMock.ListFunc: method is nil but CronJobInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCronJobInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCronJobInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCronJobInterface.ListCalls()) +func (mock *CronJobInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCronJobInterfaceMockList.RLock() + calls = mock.calls.List + lockCronJobInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CronJobInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.CronJobList, error) { + if mock.ListNamespacedFunc == nil { + panic("CronJobInterfaceMock.ListNamespacedFunc: method is nil but CronJobInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCronJobInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCronJobInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCronJobInterface.ListNamespacedCalls()) +func (mock *CronJobInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCronJobInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCronJobInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CronJobInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CronJobInterfaceMock.ObjectClientFunc: method is nil but CronJobInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCronJobInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCronJobInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCronJobInterface.ObjectClientCalls()) +func (mock *CronJobInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCronJobInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCronJobInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CronJobInterfaceMock) Update(in1 *v1.CronJob) (*v1.CronJob, error) { + if mock.UpdateFunc == nil { + panic("CronJobInterfaceMock.UpdateFunc: method is nil but CronJobInterface.Update was just called") + } + callInfo := struct { + In1 *v1.CronJob + }{ + In1: in1, + } + lockCronJobInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCronJobInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCronJobInterface.UpdateCalls()) +func (mock *CronJobInterfaceMock) UpdateCalls() []struct { + In1 *v1.CronJob +} { + var calls []struct { + In1 *v1.CronJob + } + lockCronJobInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCronJobInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CronJobInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CronJobInterfaceMock.WatchFunc: method is nil but CronJobInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCronJobInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCronJobInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCronJobInterface.WatchCalls()) +func (mock *CronJobInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCronJobInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCronJobInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCronJobsGetterMockCronJobs sync.RWMutex +) + +// Ensure, that CronJobsGetterMock does implement v11.CronJobsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.CronJobsGetter = &CronJobsGetterMock{} + +// CronJobsGetterMock is a mock implementation of v11.CronJobsGetter. +// +// func TestSomethingThatUsesCronJobsGetter(t *testing.T) { +// +// // make and configure a mocked v11.CronJobsGetter +// mockedCronJobsGetter := &CronJobsGetterMock{ +// CronJobsFunc: func(namespace string) v11.CronJobInterface { +// panic("mock out the CronJobs method") +// }, +// } +// +// // use mockedCronJobsGetter in code that requires v11.CronJobsGetter +// // and then make assertions. +// +// } +type CronJobsGetterMock struct { + // CronJobsFunc mocks the CronJobs method. + CronJobsFunc func(namespace string) v11.CronJobInterface + + // calls tracks calls to the methods. + calls struct { + // CronJobs holds details about calls to the CronJobs method. + CronJobs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// CronJobs calls CronJobsFunc. +func (mock *CronJobsGetterMock) CronJobs(namespace string) v11.CronJobInterface { + if mock.CronJobsFunc == nil { + panic("CronJobsGetterMock.CronJobsFunc: method is nil but CronJobsGetter.CronJobs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCronJobsGetterMockCronJobs.Lock() + mock.calls.CronJobs = append(mock.calls.CronJobs, callInfo) + lockCronJobsGetterMockCronJobs.Unlock() + return mock.CronJobsFunc(namespace) +} + +// CronJobsCalls gets all the calls that were made to CronJobs. +// Check the length with: +// +// len(mockedCronJobsGetter.CronJobsCalls()) +func (mock *CronJobsGetterMock) CronJobsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCronJobsGetterMockCronJobs.RLock() + calls = mock.calls.CronJobs + lockCronJobsGetterMockCronJobs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_job_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_job_mock.go new file mode 100644 index 0000000..f85e094 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/fakes/zz_generated_job_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/batch/v1" + v1 "k8s.io/api/batch/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockJobListerMockGet sync.RWMutex + lockJobListerMockList sync.RWMutex +) + +// Ensure, that JobListerMock does implement v11.JobLister. +// If this is not the case, regenerate this file with moq. +var _ v11.JobLister = &JobListerMock{} + +// JobListerMock is a mock implementation of v11.JobLister. +// +// func TestSomethingThatUsesJobLister(t *testing.T) { +// +// // make and configure a mocked v11.JobLister +// mockedJobLister := &JobListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Job, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Job, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedJobLister in code that requires v11.JobLister +// // and then make assertions. +// +// } +type JobListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Job, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Job, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *JobListerMock) Get(namespace string, name string) (*v1.Job, error) { + if mock.GetFunc == nil { + panic("JobListerMock.GetFunc: method is nil but JobLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockJobListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockJobListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedJobLister.GetCalls()) +func (mock *JobListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockJobListerMockGet.RLock() + calls = mock.calls.Get + lockJobListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *JobListerMock) List(namespace string, selector labels.Selector) ([]*v1.Job, error) { + if mock.ListFunc == nil { + panic("JobListerMock.ListFunc: method is nil but JobLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockJobListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockJobListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedJobLister.ListCalls()) +func (mock *JobListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockJobListerMockList.RLock() + calls = mock.calls.List + lockJobListerMockList.RUnlock() + return calls +} + +var ( + lockJobControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockJobControllerMockAddClusterScopedHandler sync.RWMutex + lockJobControllerMockAddFeatureHandler sync.RWMutex + lockJobControllerMockAddHandler sync.RWMutex + lockJobControllerMockEnqueue sync.RWMutex + lockJobControllerMockEnqueueAfter sync.RWMutex + lockJobControllerMockGeneric sync.RWMutex + lockJobControllerMockInformer sync.RWMutex + lockJobControllerMockLister sync.RWMutex +) + +// Ensure, that JobControllerMock does implement v11.JobController. +// If this is not the case, regenerate this file with moq. +var _ v11.JobController = &JobControllerMock{} + +// JobControllerMock is a mock implementation of v11.JobController. +// +// func TestSomethingThatUsesJobController(t *testing.T) { +// +// // make and configure a mocked v11.JobController +// mockedJobController := &JobControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.JobHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.JobHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.JobHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.JobLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedJobController in code that requires v11.JobController +// // and then make assertions. +// +// } +type JobControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.JobHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.JobHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.JobHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.JobLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.JobHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.JobHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.JobHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.JobHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *JobControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.JobHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("JobControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but JobController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.JobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockJobControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockJobControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedJobController.AddClusterScopedFeatureHandlerCalls()) +func (mock *JobControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.JobHandlerFunc + } + lockJobControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockJobControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *JobControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.JobHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("JobControllerMock.AddClusterScopedHandlerFunc: method is nil but JobController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.JobHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockJobControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockJobControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedJobController.AddClusterScopedHandlerCalls()) +func (mock *JobControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.JobHandlerFunc + } + lockJobControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockJobControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *JobControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("JobControllerMock.AddFeatureHandlerFunc: method is nil but JobController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockJobControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockJobControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedJobController.AddFeatureHandlerCalls()) +func (mock *JobControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc + } + lockJobControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockJobControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *JobControllerMock) AddHandler(ctx context.Context, name string, handler v11.JobHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("JobControllerMock.AddHandlerFunc: method is nil but JobController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.JobHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockJobControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockJobControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedJobController.AddHandlerCalls()) +func (mock *JobControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.JobHandlerFunc + } + lockJobControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockJobControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *JobControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("JobControllerMock.EnqueueFunc: method is nil but JobController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockJobControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockJobControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedJobController.EnqueueCalls()) +func (mock *JobControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockJobControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockJobControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *JobControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("JobControllerMock.EnqueueAfterFunc: method is nil but JobController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockJobControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockJobControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedJobController.EnqueueAfterCalls()) +func (mock *JobControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockJobControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockJobControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *JobControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("JobControllerMock.GenericFunc: method is nil but JobController.Generic was just called") + } + callInfo := struct { + }{} + lockJobControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockJobControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedJobController.GenericCalls()) +func (mock *JobControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockJobControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockJobControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *JobControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("JobControllerMock.InformerFunc: method is nil but JobController.Informer was just called") + } + callInfo := struct { + }{} + lockJobControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockJobControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedJobController.InformerCalls()) +func (mock *JobControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockJobControllerMockInformer.RLock() + calls = mock.calls.Informer + lockJobControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *JobControllerMock) Lister() v11.JobLister { + if mock.ListerFunc == nil { + panic("JobControllerMock.ListerFunc: method is nil but JobController.Lister was just called") + } + callInfo := struct { + }{} + lockJobControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockJobControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedJobController.ListerCalls()) +func (mock *JobControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockJobControllerMockLister.RLock() + calls = mock.calls.Lister + lockJobControllerMockLister.RUnlock() + return calls +} + +var ( + lockJobInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockJobInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockJobInterfaceMockAddClusterScopedHandler sync.RWMutex + lockJobInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockJobInterfaceMockAddFeatureHandler sync.RWMutex + lockJobInterfaceMockAddFeatureLifecycle sync.RWMutex + lockJobInterfaceMockAddHandler sync.RWMutex + lockJobInterfaceMockAddLifecycle sync.RWMutex + lockJobInterfaceMockController sync.RWMutex + lockJobInterfaceMockCreate sync.RWMutex + lockJobInterfaceMockDelete sync.RWMutex + lockJobInterfaceMockDeleteCollection sync.RWMutex + lockJobInterfaceMockDeleteNamespaced sync.RWMutex + lockJobInterfaceMockGet sync.RWMutex + lockJobInterfaceMockGetNamespaced sync.RWMutex + lockJobInterfaceMockList sync.RWMutex + lockJobInterfaceMockListNamespaced sync.RWMutex + lockJobInterfaceMockObjectClient sync.RWMutex + lockJobInterfaceMockUpdate sync.RWMutex + lockJobInterfaceMockWatch sync.RWMutex +) + +// Ensure, that JobInterfaceMock does implement v11.JobInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.JobInterface = &JobInterfaceMock{} + +// JobInterfaceMock is a mock implementation of v11.JobInterface. +// +// func TestSomethingThatUsesJobInterface(t *testing.T) { +// +// // make and configure a mocked v11.JobInterface +// mockedJobInterface := &JobInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.JobLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.JobLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.JobLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.JobHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.JobLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.JobController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Job) (*v1.Job, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Job, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Job, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.JobList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.JobList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Job) (*v1.Job, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedJobInterface in code that requires v11.JobInterface +// // and then make assertions. +// +// } +type JobInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.JobLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.JobLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.JobLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.JobHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.JobLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.JobController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Job) (*v1.Job, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Job, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Job, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.JobList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.JobList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Job) (*v1.Job, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.JobHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.JobLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.JobHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.JobLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.JobHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.JobLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.JobHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.JobLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Job + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Job + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *JobInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("JobInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but JobInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.JobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockJobInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockJobInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedJobInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *JobInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.JobHandlerFunc + } + lockJobInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockJobInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *JobInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.JobLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("JobInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but JobInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.JobLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockJobInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockJobInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedJobInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *JobInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.JobLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.JobLifecycle + } + lockJobInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockJobInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *JobInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.JobHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("JobInterfaceMock.AddClusterScopedHandlerFunc: method is nil but JobInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.JobHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockJobInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockJobInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedJobInterface.AddClusterScopedHandlerCalls()) +func (mock *JobInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.JobHandlerFunc + } + lockJobInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockJobInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *JobInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.JobLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("JobInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but JobInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.JobLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockJobInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockJobInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedJobInterface.AddClusterScopedLifecycleCalls()) +func (mock *JobInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.JobLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.JobLifecycle + } + lockJobInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockJobInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *JobInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.JobHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("JobInterfaceMock.AddFeatureHandlerFunc: method is nil but JobInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockJobInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockJobInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedJobInterface.AddFeatureHandlerCalls()) +func (mock *JobInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.JobHandlerFunc + } + lockJobInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockJobInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *JobInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.JobLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("JobInterfaceMock.AddFeatureLifecycleFunc: method is nil but JobInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.JobLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockJobInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockJobInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedJobInterface.AddFeatureLifecycleCalls()) +func (mock *JobInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.JobLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.JobLifecycle + } + lockJobInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockJobInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *JobInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.JobHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("JobInterfaceMock.AddHandlerFunc: method is nil but JobInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.JobHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockJobInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockJobInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedJobInterface.AddHandlerCalls()) +func (mock *JobInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.JobHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.JobHandlerFunc + } + lockJobInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockJobInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *JobInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.JobLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("JobInterfaceMock.AddLifecycleFunc: method is nil but JobInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.JobLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockJobInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockJobInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedJobInterface.AddLifecycleCalls()) +func (mock *JobInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.JobLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.JobLifecycle + } + lockJobInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockJobInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *JobInterfaceMock) Controller() v11.JobController { + if mock.ControllerFunc == nil { + panic("JobInterfaceMock.ControllerFunc: method is nil but JobInterface.Controller was just called") + } + callInfo := struct { + }{} + lockJobInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockJobInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedJobInterface.ControllerCalls()) +func (mock *JobInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockJobInterfaceMockController.RLock() + calls = mock.calls.Controller + lockJobInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *JobInterfaceMock) Create(in1 *v1.Job) (*v1.Job, error) { + if mock.CreateFunc == nil { + panic("JobInterfaceMock.CreateFunc: method is nil but JobInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Job + }{ + In1: in1, + } + lockJobInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockJobInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedJobInterface.CreateCalls()) +func (mock *JobInterfaceMock) CreateCalls() []struct { + In1 *v1.Job +} { + var calls []struct { + In1 *v1.Job + } + lockJobInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockJobInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *JobInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("JobInterfaceMock.DeleteFunc: method is nil but JobInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockJobInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockJobInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedJobInterface.DeleteCalls()) +func (mock *JobInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockJobInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockJobInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *JobInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("JobInterfaceMock.DeleteCollectionFunc: method is nil but JobInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockJobInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockJobInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedJobInterface.DeleteCollectionCalls()) +func (mock *JobInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockJobInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockJobInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *JobInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("JobInterfaceMock.DeleteNamespacedFunc: method is nil but JobInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockJobInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockJobInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedJobInterface.DeleteNamespacedCalls()) +func (mock *JobInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockJobInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockJobInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *JobInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Job, error) { + if mock.GetFunc == nil { + panic("JobInterfaceMock.GetFunc: method is nil but JobInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockJobInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockJobInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedJobInterface.GetCalls()) +func (mock *JobInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockJobInterfaceMockGet.RLock() + calls = mock.calls.Get + lockJobInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *JobInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Job, error) { + if mock.GetNamespacedFunc == nil { + panic("JobInterfaceMock.GetNamespacedFunc: method is nil but JobInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockJobInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockJobInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedJobInterface.GetNamespacedCalls()) +func (mock *JobInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockJobInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockJobInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *JobInterfaceMock) List(opts metav1.ListOptions) (*v1.JobList, error) { + if mock.ListFunc == nil { + panic("JobInterfaceMock.ListFunc: method is nil but JobInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockJobInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockJobInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedJobInterface.ListCalls()) +func (mock *JobInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockJobInterfaceMockList.RLock() + calls = mock.calls.List + lockJobInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *JobInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.JobList, error) { + if mock.ListNamespacedFunc == nil { + panic("JobInterfaceMock.ListNamespacedFunc: method is nil but JobInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockJobInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockJobInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedJobInterface.ListNamespacedCalls()) +func (mock *JobInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockJobInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockJobInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *JobInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("JobInterfaceMock.ObjectClientFunc: method is nil but JobInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockJobInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockJobInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedJobInterface.ObjectClientCalls()) +func (mock *JobInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockJobInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockJobInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *JobInterfaceMock) Update(in1 *v1.Job) (*v1.Job, error) { + if mock.UpdateFunc == nil { + panic("JobInterfaceMock.UpdateFunc: method is nil but JobInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Job + }{ + In1: in1, + } + lockJobInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockJobInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedJobInterface.UpdateCalls()) +func (mock *JobInterfaceMock) UpdateCalls() []struct { + In1 *v1.Job +} { + var calls []struct { + In1 *v1.Job + } + lockJobInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockJobInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *JobInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("JobInterfaceMock.WatchFunc: method is nil but JobInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockJobInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockJobInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedJobInterface.WatchCalls()) +func (mock *JobInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockJobInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockJobInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockJobsGetterMockJobs sync.RWMutex +) + +// Ensure, that JobsGetterMock does implement v11.JobsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.JobsGetter = &JobsGetterMock{} + +// JobsGetterMock is a mock implementation of v11.JobsGetter. +// +// func TestSomethingThatUsesJobsGetter(t *testing.T) { +// +// // make and configure a mocked v11.JobsGetter +// mockedJobsGetter := &JobsGetterMock{ +// JobsFunc: func(namespace string) v11.JobInterface { +// panic("mock out the Jobs method") +// }, +// } +// +// // use mockedJobsGetter in code that requires v11.JobsGetter +// // and then make assertions. +// +// } +type JobsGetterMock struct { + // JobsFunc mocks the Jobs method. + JobsFunc func(namespace string) v11.JobInterface + + // calls tracks calls to the methods. + calls struct { + // Jobs holds details about calls to the Jobs method. + Jobs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Jobs calls JobsFunc. +func (mock *JobsGetterMock) Jobs(namespace string) v11.JobInterface { + if mock.JobsFunc == nil { + panic("JobsGetterMock.JobsFunc: method is nil but JobsGetter.Jobs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockJobsGetterMockJobs.Lock() + mock.calls.Jobs = append(mock.calls.Jobs, callInfo) + lockJobsGetterMockJobs.Unlock() + return mock.JobsFunc(namespace) +} + +// JobsCalls gets all the calls that were made to Jobs. +// Check the length with: +// +// len(mockedJobsGetter.JobsCalls()) +func (mock *JobsGetterMock) JobsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockJobsGetterMockJobs.RLock() + calls = mock.calls.Jobs + lockJobsGetterMockJobs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_controller.go new file mode 100644 index 0000000..c14c572 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CronJobGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "CronJob", + } + CronJobResource = metav1.APIResource{ + Name: "cronjobs", + SingularName: "cronjob", + Namespaced: true, + + Kind: CronJobGroupVersionKind.Kind, + } + + CronJobGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "cronjobs", + } +) + +func init() { + resource.Put(CronJobGroupVersionResource) +} + +// Deprecated: use v1.CronJob instead +type CronJob = v1.CronJob + +func NewCronJob(namespace, name string, obj v1.CronJob) *v1.CronJob { + obj.APIVersion, obj.Kind = CronJobGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CronJobHandlerFunc func(key string, obj *v1.CronJob) (runtime.Object, error) + +type CronJobChangeHandlerFunc func(obj *v1.CronJob) (runtime.Object, error) + +type CronJobLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.CronJob, err error) + Get(namespace, name string) (*v1.CronJob, error) +} + +type CronJobController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CronJobLister + AddHandler(ctx context.Context, name string, handler CronJobHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CronJobHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CronJobHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CronJobHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CronJobInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.CronJob) (*v1.CronJob, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.CronJob, error) + Get(name string, opts metav1.GetOptions) (*v1.CronJob, error) + Update(*v1.CronJob) (*v1.CronJob, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.CronJobList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.CronJobList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CronJobController + AddHandler(ctx context.Context, name string, sync CronJobHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CronJobHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CronJobLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CronJobLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CronJobHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CronJobHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CronJobLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CronJobLifecycle) +} + +type cronJobLister struct { + ns string + controller *cronJobController +} + +func (l *cronJobLister) List(namespace string, selector labels.Selector) (ret []*v1.CronJob, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.CronJob)) + }) + return +} + +func (l *cronJobLister) Get(namespace, name string) (*v1.CronJob, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CronJobGroupVersionKind.Group, + Resource: CronJobGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.CronJob), nil +} + +type cronJobController struct { + ns string + controller.GenericController +} + +func (c *cronJobController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *cronJobController) Lister() CronJobLister { + return &cronJobLister{ + ns: c.ns, + controller: c, + } +} + +func (c *cronJobController) AddHandler(ctx context.Context, name string, handler CronJobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.CronJob); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cronJobController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CronJobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.CronJob); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cronJobController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CronJobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.CronJob); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cronJobController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CronJobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.CronJob); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type cronJobFactory struct { +} + +func (c cronJobFactory) Object() runtime.Object { + return &v1.CronJob{} +} + +func (c cronJobFactory) List() runtime.Object { + return &v1.CronJobList{} +} + +func (s *cronJobClient) Controller() CronJobController { + genericController := controller.NewGenericController(s.ns, CronJobGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CronJobGroupVersionResource, CronJobGroupVersionKind.Kind, true)) + + return &cronJobController{ + ns: s.ns, + GenericController: genericController, + } +} + +type cronJobClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CronJobController +} + +func (s *cronJobClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *cronJobClient) Create(o *v1.CronJob) (*v1.CronJob, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) Get(name string, opts metav1.GetOptions) (*v1.CronJob, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.CronJob, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) Update(o *v1.CronJob) (*v1.CronJob, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) UpdateStatus(o *v1.CronJob) (*v1.CronJob, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *cronJobClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *cronJobClient) List(opts metav1.ListOptions) (*v1.CronJobList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.CronJobList), err +} + +func (s *cronJobClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.CronJobList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.CronJobList), err +} + +func (s *cronJobClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *cronJobClient) Patch(o *v1.CronJob, patchType types.PatchType, data []byte, subresources ...string) (*v1.CronJob, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.CronJob), err +} + +func (s *cronJobClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *cronJobClient) AddHandler(ctx context.Context, name string, sync CronJobHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *cronJobClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CronJobHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *cronJobClient) AddLifecycle(ctx context.Context, name string, lifecycle CronJobLifecycle) { + sync := NewCronJobLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *cronJobClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CronJobLifecycle) { + sync := NewCronJobLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *cronJobClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CronJobHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *cronJobClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CronJobHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *cronJobClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CronJobLifecycle) { + sync := NewCronJobLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *cronJobClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CronJobLifecycle) { + sync := NewCronJobLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_lifecycle_adapter.go new file mode 100644 index 0000000..3ec4f0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_cron_job_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type CronJobLifecycle interface { + Create(obj *v1.CronJob) (runtime.Object, error) + Remove(obj *v1.CronJob) (runtime.Object, error) + Updated(obj *v1.CronJob) (runtime.Object, error) +} + +type cronJobLifecycleAdapter struct { + lifecycle CronJobLifecycle +} + +func (w *cronJobLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *cronJobLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *cronJobLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.CronJob)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *cronJobLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.CronJob)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *cronJobLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.CronJob)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCronJobLifecycleAdapter(name string, clusterScoped bool, client CronJobInterface, l CronJobLifecycle) CronJobHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CronJobGroupVersionResource) + } + adapter := &cronJobLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.CronJob) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_controller.go new file mode 100644 index 0000000..1c70aa1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + JobGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Job", + } + JobResource = metav1.APIResource{ + Name: "jobs", + SingularName: "job", + Namespaced: true, + + Kind: JobGroupVersionKind.Kind, + } + + JobGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "jobs", + } +) + +func init() { + resource.Put(JobGroupVersionResource) +} + +// Deprecated: use v1.Job instead +type Job = v1.Job + +func NewJob(namespace, name string, obj v1.Job) *v1.Job { + obj.APIVersion, obj.Kind = JobGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type JobHandlerFunc func(key string, obj *v1.Job) (runtime.Object, error) + +type JobChangeHandlerFunc func(obj *v1.Job) (runtime.Object, error) + +type JobLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Job, err error) + Get(namespace, name string) (*v1.Job, error) +} + +type JobController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() JobLister + AddHandler(ctx context.Context, name string, handler JobHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync JobHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler JobHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler JobHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type JobInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Job) (*v1.Job, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Job, error) + Get(name string, opts metav1.GetOptions) (*v1.Job, error) + Update(*v1.Job) (*v1.Job, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.JobList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.JobList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() JobController + AddHandler(ctx context.Context, name string, sync JobHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync JobHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle JobLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle JobLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync JobHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync JobHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle JobLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle JobLifecycle) +} + +type jobLister struct { + ns string + controller *jobController +} + +func (l *jobLister) List(namespace string, selector labels.Selector) (ret []*v1.Job, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Job)) + }) + return +} + +func (l *jobLister) Get(namespace, name string) (*v1.Job, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: JobGroupVersionKind.Group, + Resource: JobGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Job), nil +} + +type jobController struct { + ns string + controller.GenericController +} + +func (c *jobController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *jobController) Lister() JobLister { + return &jobLister{ + ns: c.ns, + controller: c, + } +} + +func (c *jobController) AddHandler(ctx context.Context, name string, handler JobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Job); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *jobController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler JobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Job); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *jobController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler JobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Job); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *jobController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler JobHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Job); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type jobFactory struct { +} + +func (c jobFactory) Object() runtime.Object { + return &v1.Job{} +} + +func (c jobFactory) List() runtime.Object { + return &v1.JobList{} +} + +func (s *jobClient) Controller() JobController { + genericController := controller.NewGenericController(s.ns, JobGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(JobGroupVersionResource, JobGroupVersionKind.Kind, true)) + + return &jobController{ + ns: s.ns, + GenericController: genericController, + } +} + +type jobClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller JobController +} + +func (s *jobClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *jobClient) Create(o *v1.Job) (*v1.Job, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Job), err +} + +func (s *jobClient) Get(name string, opts metav1.GetOptions) (*v1.Job, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Job), err +} + +func (s *jobClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Job, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Job), err +} + +func (s *jobClient) Update(o *v1.Job) (*v1.Job, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Job), err +} + +func (s *jobClient) UpdateStatus(o *v1.Job) (*v1.Job, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Job), err +} + +func (s *jobClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *jobClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *jobClient) List(opts metav1.ListOptions) (*v1.JobList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.JobList), err +} + +func (s *jobClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.JobList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.JobList), err +} + +func (s *jobClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *jobClient) Patch(o *v1.Job, patchType types.PatchType, data []byte, subresources ...string) (*v1.Job, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Job), err +} + +func (s *jobClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *jobClient) AddHandler(ctx context.Context, name string, sync JobHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *jobClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync JobHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *jobClient) AddLifecycle(ctx context.Context, name string, lifecycle JobLifecycle) { + sync := NewJobLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *jobClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle JobLifecycle) { + sync := NewJobLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *jobClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync JobHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *jobClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync JobHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *jobClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle JobLifecycle) { + sync := NewJobLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *jobClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle JobLifecycle) { + sync := NewJobLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_lifecycle_adapter.go new file mode 100644 index 0000000..482878e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_job_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type JobLifecycle interface { + Create(obj *v1.Job) (runtime.Object, error) + Remove(obj *v1.Job) (runtime.Object, error) + Updated(obj *v1.Job) (runtime.Object, error) +} + +type jobLifecycleAdapter struct { + lifecycle JobLifecycle +} + +func (w *jobLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *jobLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *jobLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Job)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *jobLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Job)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *jobLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Job)) + if o == nil { + return nil, err + } + return o, err +} + +func NewJobLifecycleAdapter(name string, clusterScoped bool, client JobInterface, l JobLifecycle) JobHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(JobGroupVersionResource) + } + adapter := &jobLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Job) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..eda8220 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_k8s_client.go @@ -0,0 +1,78 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + JobsGetter + CronJobsGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type JobsGetter interface { + Jobs(namespace string) JobInterface +} + +func (c *Client) Jobs(namespace string) JobInterface { + sharedClient := c.clientFactory.ForResourceKind(JobGroupVersionResource, JobGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &JobResource, JobGroupVersionKind, jobFactory{}) + return &jobClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CronJobsGetter interface { + CronJobs(namespace string) CronJobInterface +} + +func (c *Client) CronJobs(namespace string) CronJobInterface { + sharedClient := c.clientFactory.ForResourceKind(CronJobGroupVersionResource, CronJobGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CronJobResource, CronJobGroupVersionKind, cronJobFactory{}) + return &cronJobClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_scheme.go new file mode 100644 index 0000000..4f51ce9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/batch/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "batch" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_auth_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_auth_token_mock.go new file mode 100644 index 0000000..e0d841c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_auth_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterAuthTokenListerMockGet sync.RWMutex + lockClusterAuthTokenListerMockList sync.RWMutex +) + +// Ensure, that ClusterAuthTokenListerMock does implement v31.ClusterAuthTokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterAuthTokenLister = &ClusterAuthTokenListerMock{} + +// ClusterAuthTokenListerMock is a mock implementation of v31.ClusterAuthTokenLister. +// +// func TestSomethingThatUsesClusterAuthTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterAuthTokenLister +// mockedClusterAuthTokenLister := &ClusterAuthTokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterAuthToken, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterAuthToken, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterAuthTokenLister in code that requires v31.ClusterAuthTokenLister +// // and then make assertions. +// +// } +type ClusterAuthTokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterAuthToken, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterAuthToken, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterAuthTokenListerMock) Get(namespace string, name string) (*v3.ClusterAuthToken, error) { + if mock.GetFunc == nil { + panic("ClusterAuthTokenListerMock.GetFunc: method is nil but ClusterAuthTokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterAuthTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterAuthTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterAuthTokenLister.GetCalls()) +func (mock *ClusterAuthTokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterAuthTokenListerMockGet.RLock() + calls = mock.calls.Get + lockClusterAuthTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterAuthTokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterAuthToken, error) { + if mock.ListFunc == nil { + panic("ClusterAuthTokenListerMock.ListFunc: method is nil but ClusterAuthTokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterAuthTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterAuthTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterAuthTokenLister.ListCalls()) +func (mock *ClusterAuthTokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterAuthTokenListerMockList.RLock() + calls = mock.calls.List + lockClusterAuthTokenListerMockList.RUnlock() + return calls +} + +var ( + lockClusterAuthTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterAuthTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterAuthTokenControllerMockAddFeatureHandler sync.RWMutex + lockClusterAuthTokenControllerMockAddHandler sync.RWMutex + lockClusterAuthTokenControllerMockEnqueue sync.RWMutex + lockClusterAuthTokenControllerMockEnqueueAfter sync.RWMutex + lockClusterAuthTokenControllerMockGeneric sync.RWMutex + lockClusterAuthTokenControllerMockInformer sync.RWMutex + lockClusterAuthTokenControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterAuthTokenControllerMock does implement v31.ClusterAuthTokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterAuthTokenController = &ClusterAuthTokenControllerMock{} + +// ClusterAuthTokenControllerMock is a mock implementation of v31.ClusterAuthTokenController. +// +// func TestSomethingThatUsesClusterAuthTokenController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterAuthTokenController +// mockedClusterAuthTokenController := &ClusterAuthTokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterAuthTokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterAuthTokenController in code that requires v31.ClusterAuthTokenController +// // and then make assertions. +// +// } +type ClusterAuthTokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterAuthTokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterAuthTokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterAuthTokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterAuthTokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterAuthTokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterAuthTokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterAuthTokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterAuthTokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterAuthTokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterAuthTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterAuthTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterAuthTokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterAuthTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterAuthTokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterAuthTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterAuthTokenControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterAuthTokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterAuthTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterAuthTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenController.AddClusterScopedHandlerCalls()) +func (mock *ClusterAuthTokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterAuthTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterAuthTokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterAuthTokenControllerMock.AddFeatureHandlerFunc: method is nil but ClusterAuthTokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterAuthTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterAuthTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenController.AddFeatureHandlerCalls()) +func (mock *ClusterAuthTokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterAuthTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterAuthTokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterAuthTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterAuthTokenControllerMock.AddHandlerFunc: method is nil but ClusterAuthTokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterAuthTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterAuthTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenController.AddHandlerCalls()) +func (mock *ClusterAuthTokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterAuthTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterAuthTokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterAuthTokenControllerMock.EnqueueFunc: method is nil but ClusterAuthTokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterAuthTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterAuthTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterAuthTokenController.EnqueueCalls()) +func (mock *ClusterAuthTokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterAuthTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterAuthTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterAuthTokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterAuthTokenControllerMock.EnqueueAfterFunc: method is nil but ClusterAuthTokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterAuthTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterAuthTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterAuthTokenController.EnqueueAfterCalls()) +func (mock *ClusterAuthTokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterAuthTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterAuthTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterAuthTokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterAuthTokenControllerMock.GenericFunc: method is nil but ClusterAuthTokenController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterAuthTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterAuthTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterAuthTokenController.GenericCalls()) +func (mock *ClusterAuthTokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterAuthTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterAuthTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterAuthTokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterAuthTokenControllerMock.InformerFunc: method is nil but ClusterAuthTokenController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterAuthTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterAuthTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterAuthTokenController.InformerCalls()) +func (mock *ClusterAuthTokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterAuthTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterAuthTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterAuthTokenControllerMock) Lister() v31.ClusterAuthTokenLister { + if mock.ListerFunc == nil { + panic("ClusterAuthTokenControllerMock.ListerFunc: method is nil but ClusterAuthTokenController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterAuthTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterAuthTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterAuthTokenController.ListerCalls()) +func (mock *ClusterAuthTokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterAuthTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterAuthTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterAuthTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterAuthTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterAuthTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterAuthTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterAuthTokenInterfaceMockAddHandler sync.RWMutex + lockClusterAuthTokenInterfaceMockAddLifecycle sync.RWMutex + lockClusterAuthTokenInterfaceMockController sync.RWMutex + lockClusterAuthTokenInterfaceMockCreate sync.RWMutex + lockClusterAuthTokenInterfaceMockDelete sync.RWMutex + lockClusterAuthTokenInterfaceMockDeleteCollection sync.RWMutex + lockClusterAuthTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterAuthTokenInterfaceMockGet sync.RWMutex + lockClusterAuthTokenInterfaceMockGetNamespaced sync.RWMutex + lockClusterAuthTokenInterfaceMockList sync.RWMutex + lockClusterAuthTokenInterfaceMockListNamespaced sync.RWMutex + lockClusterAuthTokenInterfaceMockObjectClient sync.RWMutex + lockClusterAuthTokenInterfaceMockUpdate sync.RWMutex + lockClusterAuthTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterAuthTokenInterfaceMock does implement v31.ClusterAuthTokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterAuthTokenInterface = &ClusterAuthTokenInterfaceMock{} + +// ClusterAuthTokenInterfaceMock is a mock implementation of v31.ClusterAuthTokenInterface. +// +// func TestSomethingThatUsesClusterAuthTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterAuthTokenInterface +// mockedClusterAuthTokenInterface := &ClusterAuthTokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterAuthTokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterAuthTokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterAuthTokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterAuthTokenInterface in code that requires v31.ClusterAuthTokenInterface +// // and then make assertions. +// +// } +type ClusterAuthTokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterAuthTokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterAuthTokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterAuthTokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterAuthTokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterAuthTokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterAuthTokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterAuthTokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterAuthTokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterAuthTokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterAuthTokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterAuthTokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterAuthToken + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterAuthToken + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterAuthTokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterAuthTokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle + } + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterAuthTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterAuthTokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterAuthTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterAuthTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterAuthTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterAuthTokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterAuthTokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterAuthTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterAuthTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterAuthTokenLifecycle + } + lockClusterAuthTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterAuthTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterAuthTokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterAuthTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterAuthTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddFeatureHandlerCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterAuthTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterAuthTokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterAuthTokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterAuthTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterAuthTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterAuthTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterAuthTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterAuthTokenLifecycle + } + lockClusterAuthTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterAuthTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterAuthTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddHandlerFunc: method is nil but ClusterAuthTokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterAuthTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterAuthTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterAuthTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddHandlerCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterAuthTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterAuthTokenHandlerFunc + } + lockClusterAuthTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterAuthTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterAuthTokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterAuthTokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterAuthTokenInterfaceMock.AddLifecycleFunc: method is nil but ClusterAuthTokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterAuthTokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterAuthTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterAuthTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.AddLifecycleCalls()) +func (mock *ClusterAuthTokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterAuthTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterAuthTokenLifecycle + } + lockClusterAuthTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterAuthTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterAuthTokenInterfaceMock) Controller() v31.ClusterAuthTokenController { + if mock.ControllerFunc == nil { + panic("ClusterAuthTokenInterfaceMock.ControllerFunc: method is nil but ClusterAuthTokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterAuthTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterAuthTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.ControllerCalls()) +func (mock *ClusterAuthTokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterAuthTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterAuthTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterAuthTokenInterfaceMock) Create(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { + if mock.CreateFunc == nil { + panic("ClusterAuthTokenInterfaceMock.CreateFunc: method is nil but ClusterAuthTokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterAuthToken + }{ + In1: in1, + } + lockClusterAuthTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterAuthTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.CreateCalls()) +func (mock *ClusterAuthTokenInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterAuthToken +} { + var calls []struct { + In1 *v3.ClusterAuthToken + } + lockClusterAuthTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterAuthTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterAuthTokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterAuthTokenInterfaceMock.DeleteFunc: method is nil but ClusterAuthTokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterAuthTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterAuthTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.DeleteCalls()) +func (mock *ClusterAuthTokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterAuthTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterAuthTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterAuthTokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterAuthTokenInterfaceMock.DeleteCollectionFunc: method is nil but ClusterAuthTokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterAuthTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterAuthTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.DeleteCollectionCalls()) +func (mock *ClusterAuthTokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterAuthTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterAuthTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterAuthTokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterAuthTokenInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterAuthTokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterAuthTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterAuthTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.DeleteNamespacedCalls()) +func (mock *ClusterAuthTokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterAuthTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterAuthTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterAuthTokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { + if mock.GetFunc == nil { + panic("ClusterAuthTokenInterfaceMock.GetFunc: method is nil but ClusterAuthTokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterAuthTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterAuthTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.GetCalls()) +func (mock *ClusterAuthTokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterAuthTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterAuthTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterAuthTokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterAuthTokenInterfaceMock.GetNamespacedFunc: method is nil but ClusterAuthTokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterAuthTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterAuthTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.GetNamespacedCalls()) +func (mock *ClusterAuthTokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterAuthTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterAuthTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterAuthTokenInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { + if mock.ListFunc == nil { + panic("ClusterAuthTokenInterfaceMock.ListFunc: method is nil but ClusterAuthTokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterAuthTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterAuthTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.ListCalls()) +func (mock *ClusterAuthTokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterAuthTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterAuthTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterAuthTokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterAuthTokenInterfaceMock.ListNamespacedFunc: method is nil but ClusterAuthTokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterAuthTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterAuthTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.ListNamespacedCalls()) +func (mock *ClusterAuthTokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterAuthTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterAuthTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterAuthTokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterAuthTokenInterfaceMock.ObjectClientFunc: method is nil but ClusterAuthTokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterAuthTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterAuthTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.ObjectClientCalls()) +func (mock *ClusterAuthTokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterAuthTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterAuthTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterAuthTokenInterfaceMock) Update(in1 *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { + if mock.UpdateFunc == nil { + panic("ClusterAuthTokenInterfaceMock.UpdateFunc: method is nil but ClusterAuthTokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterAuthToken + }{ + In1: in1, + } + lockClusterAuthTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterAuthTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.UpdateCalls()) +func (mock *ClusterAuthTokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterAuthToken +} { + var calls []struct { + In1 *v3.ClusterAuthToken + } + lockClusterAuthTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterAuthTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterAuthTokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterAuthTokenInterfaceMock.WatchFunc: method is nil but ClusterAuthTokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterAuthTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterAuthTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterAuthTokenInterface.WatchCalls()) +func (mock *ClusterAuthTokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterAuthTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterAuthTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterAuthTokensGetterMockClusterAuthTokens sync.RWMutex +) + +// Ensure, that ClusterAuthTokensGetterMock does implement v31.ClusterAuthTokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterAuthTokensGetter = &ClusterAuthTokensGetterMock{} + +// ClusterAuthTokensGetterMock is a mock implementation of v31.ClusterAuthTokensGetter. +// +// func TestSomethingThatUsesClusterAuthTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterAuthTokensGetter +// mockedClusterAuthTokensGetter := &ClusterAuthTokensGetterMock{ +// ClusterAuthTokensFunc: func(namespace string) v31.ClusterAuthTokenInterface { +// panic("mock out the ClusterAuthTokens method") +// }, +// } +// +// // use mockedClusterAuthTokensGetter in code that requires v31.ClusterAuthTokensGetter +// // and then make assertions. +// +// } +type ClusterAuthTokensGetterMock struct { + // ClusterAuthTokensFunc mocks the ClusterAuthTokens method. + ClusterAuthTokensFunc func(namespace string) v31.ClusterAuthTokenInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterAuthTokens holds details about calls to the ClusterAuthTokens method. + ClusterAuthTokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterAuthTokens calls ClusterAuthTokensFunc. +func (mock *ClusterAuthTokensGetterMock) ClusterAuthTokens(namespace string) v31.ClusterAuthTokenInterface { + if mock.ClusterAuthTokensFunc == nil { + panic("ClusterAuthTokensGetterMock.ClusterAuthTokensFunc: method is nil but ClusterAuthTokensGetter.ClusterAuthTokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterAuthTokensGetterMockClusterAuthTokens.Lock() + mock.calls.ClusterAuthTokens = append(mock.calls.ClusterAuthTokens, callInfo) + lockClusterAuthTokensGetterMockClusterAuthTokens.Unlock() + return mock.ClusterAuthTokensFunc(namespace) +} + +// ClusterAuthTokensCalls gets all the calls that were made to ClusterAuthTokens. +// Check the length with: +// +// len(mockedClusterAuthTokensGetter.ClusterAuthTokensCalls()) +func (mock *ClusterAuthTokensGetterMock) ClusterAuthTokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterAuthTokensGetterMockClusterAuthTokens.RLock() + calls = mock.calls.ClusterAuthTokens + lockClusterAuthTokensGetterMockClusterAuthTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_user_attribute_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_user_attribute_mock.go new file mode 100644 index 0000000..660b6e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/fakes/zz_generated_cluster_user_attribute_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterUserAttributeListerMockGet sync.RWMutex + lockClusterUserAttributeListerMockList sync.RWMutex +) + +// Ensure, that ClusterUserAttributeListerMock does implement v31.ClusterUserAttributeLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterUserAttributeLister = &ClusterUserAttributeListerMock{} + +// ClusterUserAttributeListerMock is a mock implementation of v31.ClusterUserAttributeLister. +// +// func TestSomethingThatUsesClusterUserAttributeLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterUserAttributeLister +// mockedClusterUserAttributeLister := &ClusterUserAttributeListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterUserAttribute, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterUserAttribute, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterUserAttributeLister in code that requires v31.ClusterUserAttributeLister +// // and then make assertions. +// +// } +type ClusterUserAttributeListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterUserAttribute, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterUserAttribute, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterUserAttributeListerMock) Get(namespace string, name string) (*v3.ClusterUserAttribute, error) { + if mock.GetFunc == nil { + panic("ClusterUserAttributeListerMock.GetFunc: method is nil but ClusterUserAttributeLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterUserAttributeListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterUserAttributeListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterUserAttributeLister.GetCalls()) +func (mock *ClusterUserAttributeListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterUserAttributeListerMockGet.RLock() + calls = mock.calls.Get + lockClusterUserAttributeListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterUserAttributeListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterUserAttribute, error) { + if mock.ListFunc == nil { + panic("ClusterUserAttributeListerMock.ListFunc: method is nil but ClusterUserAttributeLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterUserAttributeListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterUserAttributeListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterUserAttributeLister.ListCalls()) +func (mock *ClusterUserAttributeListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterUserAttributeListerMockList.RLock() + calls = mock.calls.List + lockClusterUserAttributeListerMockList.RUnlock() + return calls +} + +var ( + lockClusterUserAttributeControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterUserAttributeControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterUserAttributeControllerMockAddFeatureHandler sync.RWMutex + lockClusterUserAttributeControllerMockAddHandler sync.RWMutex + lockClusterUserAttributeControllerMockEnqueue sync.RWMutex + lockClusterUserAttributeControllerMockEnqueueAfter sync.RWMutex + lockClusterUserAttributeControllerMockGeneric sync.RWMutex + lockClusterUserAttributeControllerMockInformer sync.RWMutex + lockClusterUserAttributeControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterUserAttributeControllerMock does implement v31.ClusterUserAttributeController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterUserAttributeController = &ClusterUserAttributeControllerMock{} + +// ClusterUserAttributeControllerMock is a mock implementation of v31.ClusterUserAttributeController. +// +// func TestSomethingThatUsesClusterUserAttributeController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterUserAttributeController +// mockedClusterUserAttributeController := &ClusterUserAttributeControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterUserAttributeLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterUserAttributeController in code that requires v31.ClusterUserAttributeController +// // and then make assertions. +// +// } +type ClusterUserAttributeControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterUserAttributeHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterUserAttributeLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterUserAttributeHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterUserAttributeHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterUserAttributeHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterUserAttributeHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterUserAttributeControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterUserAttributeControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterUserAttributeController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterUserAttributeControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterUserAttributeControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterUserAttributeControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterUserAttributeControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterUserAttributeControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterUserAttributeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterUserAttributeControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterUserAttributeController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterUserAttributeControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterUserAttributeControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeController.AddClusterScopedHandlerCalls()) +func (mock *ClusterUserAttributeControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterUserAttributeControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterUserAttributeControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterUserAttributeControllerMock.AddFeatureHandlerFunc: method is nil but ClusterUserAttributeController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterUserAttributeControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterUserAttributeControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeController.AddFeatureHandlerCalls()) +func (mock *ClusterUserAttributeControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterUserAttributeControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterUserAttributeControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterUserAttributeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterUserAttributeControllerMock.AddHandlerFunc: method is nil but ClusterUserAttributeController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterUserAttributeControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterUserAttributeControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeController.AddHandlerCalls()) +func (mock *ClusterUserAttributeControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterUserAttributeControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterUserAttributeControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterUserAttributeControllerMock.EnqueueFunc: method is nil but ClusterUserAttributeController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterUserAttributeControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterUserAttributeControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterUserAttributeController.EnqueueCalls()) +func (mock *ClusterUserAttributeControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterUserAttributeControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterUserAttributeControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterUserAttributeControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterUserAttributeControllerMock.EnqueueAfterFunc: method is nil but ClusterUserAttributeController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterUserAttributeControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterUserAttributeControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterUserAttributeController.EnqueueAfterCalls()) +func (mock *ClusterUserAttributeControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterUserAttributeControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterUserAttributeControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterUserAttributeControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterUserAttributeControllerMock.GenericFunc: method is nil but ClusterUserAttributeController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterUserAttributeControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterUserAttributeControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterUserAttributeController.GenericCalls()) +func (mock *ClusterUserAttributeControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterUserAttributeControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterUserAttributeControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterUserAttributeControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterUserAttributeControllerMock.InformerFunc: method is nil but ClusterUserAttributeController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterUserAttributeControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterUserAttributeControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterUserAttributeController.InformerCalls()) +func (mock *ClusterUserAttributeControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterUserAttributeControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterUserAttributeControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterUserAttributeControllerMock) Lister() v31.ClusterUserAttributeLister { + if mock.ListerFunc == nil { + panic("ClusterUserAttributeControllerMock.ListerFunc: method is nil but ClusterUserAttributeController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterUserAttributeControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterUserAttributeControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterUserAttributeController.ListerCalls()) +func (mock *ClusterUserAttributeControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterUserAttributeControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterUserAttributeControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterUserAttributeInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterUserAttributeInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterUserAttributeInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterUserAttributeInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterUserAttributeInterfaceMockAddHandler sync.RWMutex + lockClusterUserAttributeInterfaceMockAddLifecycle sync.RWMutex + lockClusterUserAttributeInterfaceMockController sync.RWMutex + lockClusterUserAttributeInterfaceMockCreate sync.RWMutex + lockClusterUserAttributeInterfaceMockDelete sync.RWMutex + lockClusterUserAttributeInterfaceMockDeleteCollection sync.RWMutex + lockClusterUserAttributeInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterUserAttributeInterfaceMockGet sync.RWMutex + lockClusterUserAttributeInterfaceMockGetNamespaced sync.RWMutex + lockClusterUserAttributeInterfaceMockList sync.RWMutex + lockClusterUserAttributeInterfaceMockListNamespaced sync.RWMutex + lockClusterUserAttributeInterfaceMockObjectClient sync.RWMutex + lockClusterUserAttributeInterfaceMockUpdate sync.RWMutex + lockClusterUserAttributeInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterUserAttributeInterfaceMock does implement v31.ClusterUserAttributeInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterUserAttributeInterface = &ClusterUserAttributeInterfaceMock{} + +// ClusterUserAttributeInterfaceMock is a mock implementation of v31.ClusterUserAttributeInterface. +// +// func TestSomethingThatUsesClusterUserAttributeInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterUserAttributeInterface +// mockedClusterUserAttributeInterface := &ClusterUserAttributeInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterUserAttributeLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterUserAttributeLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterUserAttributeController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterUserAttributeInterface in code that requires v31.ClusterUserAttributeInterface +// // and then make assertions. +// +// } +type ClusterUserAttributeInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterUserAttributeLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterUserAttributeLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterUserAttributeController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterUserAttributeHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterUserAttributeLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterUserAttributeHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterUserAttributeLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterUserAttributeHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterUserAttributeLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterUserAttributeHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterUserAttributeLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterUserAttribute + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterUserAttribute + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterUserAttributeInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterUserAttributeInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle + } + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterUserAttributeInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterUserAttributeInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterUserAttributeInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterUserAttributeInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterUserAttributeLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterUserAttributeInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterUserAttributeInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterUserAttributeInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterUserAttributeLifecycle + } + lockClusterUserAttributeInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterUserAttributeInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterUserAttributeInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterUserAttributeInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterUserAttributeInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddFeatureHandlerCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterUserAttributeInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterUserAttributeLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterUserAttributeInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterUserAttributeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterUserAttributeInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterUserAttributeInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterUserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterUserAttributeLifecycle + } + lockClusterUserAttributeInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterUserAttributeInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterUserAttributeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddHandlerFunc: method is nil but ClusterUserAttributeInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterUserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterUserAttributeInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterUserAttributeInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddHandlerCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterUserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterUserAttributeHandlerFunc + } + lockClusterUserAttributeInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterUserAttributeInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterUserAttributeInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterUserAttributeLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterUserAttributeInterfaceMock.AddLifecycleFunc: method is nil but ClusterUserAttributeInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterUserAttributeLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterUserAttributeInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterUserAttributeInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.AddLifecycleCalls()) +func (mock *ClusterUserAttributeInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterUserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterUserAttributeLifecycle + } + lockClusterUserAttributeInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterUserAttributeInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterUserAttributeInterfaceMock) Controller() v31.ClusterUserAttributeController { + if mock.ControllerFunc == nil { + panic("ClusterUserAttributeInterfaceMock.ControllerFunc: method is nil but ClusterUserAttributeInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterUserAttributeInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterUserAttributeInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.ControllerCalls()) +func (mock *ClusterUserAttributeInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterUserAttributeInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterUserAttributeInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterUserAttributeInterfaceMock) Create(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { + if mock.CreateFunc == nil { + panic("ClusterUserAttributeInterfaceMock.CreateFunc: method is nil but ClusterUserAttributeInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterUserAttribute + }{ + In1: in1, + } + lockClusterUserAttributeInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterUserAttributeInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.CreateCalls()) +func (mock *ClusterUserAttributeInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterUserAttribute +} { + var calls []struct { + In1 *v3.ClusterUserAttribute + } + lockClusterUserAttributeInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterUserAttributeInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterUserAttributeInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterUserAttributeInterfaceMock.DeleteFunc: method is nil but ClusterUserAttributeInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterUserAttributeInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterUserAttributeInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.DeleteCalls()) +func (mock *ClusterUserAttributeInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterUserAttributeInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterUserAttributeInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterUserAttributeInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterUserAttributeInterfaceMock.DeleteCollectionFunc: method is nil but ClusterUserAttributeInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterUserAttributeInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterUserAttributeInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.DeleteCollectionCalls()) +func (mock *ClusterUserAttributeInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterUserAttributeInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterUserAttributeInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterUserAttributeInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterUserAttributeInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterUserAttributeInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterUserAttributeInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterUserAttributeInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.DeleteNamespacedCalls()) +func (mock *ClusterUserAttributeInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterUserAttributeInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterUserAttributeInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterUserAttributeInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { + if mock.GetFunc == nil { + panic("ClusterUserAttributeInterfaceMock.GetFunc: method is nil but ClusterUserAttributeInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterUserAttributeInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterUserAttributeInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.GetCalls()) +func (mock *ClusterUserAttributeInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterUserAttributeInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterUserAttributeInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterUserAttributeInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterUserAttributeInterfaceMock.GetNamespacedFunc: method is nil but ClusterUserAttributeInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterUserAttributeInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterUserAttributeInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.GetNamespacedCalls()) +func (mock *ClusterUserAttributeInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterUserAttributeInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterUserAttributeInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterUserAttributeInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { + if mock.ListFunc == nil { + panic("ClusterUserAttributeInterfaceMock.ListFunc: method is nil but ClusterUserAttributeInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterUserAttributeInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterUserAttributeInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.ListCalls()) +func (mock *ClusterUserAttributeInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterUserAttributeInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterUserAttributeInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterUserAttributeInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterUserAttributeInterfaceMock.ListNamespacedFunc: method is nil but ClusterUserAttributeInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterUserAttributeInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterUserAttributeInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.ListNamespacedCalls()) +func (mock *ClusterUserAttributeInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterUserAttributeInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterUserAttributeInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterUserAttributeInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterUserAttributeInterfaceMock.ObjectClientFunc: method is nil but ClusterUserAttributeInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterUserAttributeInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterUserAttributeInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.ObjectClientCalls()) +func (mock *ClusterUserAttributeInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterUserAttributeInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterUserAttributeInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterUserAttributeInterfaceMock) Update(in1 *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { + if mock.UpdateFunc == nil { + panic("ClusterUserAttributeInterfaceMock.UpdateFunc: method is nil but ClusterUserAttributeInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterUserAttribute + }{ + In1: in1, + } + lockClusterUserAttributeInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterUserAttributeInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.UpdateCalls()) +func (mock *ClusterUserAttributeInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterUserAttribute +} { + var calls []struct { + In1 *v3.ClusterUserAttribute + } + lockClusterUserAttributeInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterUserAttributeInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterUserAttributeInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterUserAttributeInterfaceMock.WatchFunc: method is nil but ClusterUserAttributeInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterUserAttributeInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterUserAttributeInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterUserAttributeInterface.WatchCalls()) +func (mock *ClusterUserAttributeInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterUserAttributeInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterUserAttributeInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterUserAttributesGetterMockClusterUserAttributes sync.RWMutex +) + +// Ensure, that ClusterUserAttributesGetterMock does implement v31.ClusterUserAttributesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterUserAttributesGetter = &ClusterUserAttributesGetterMock{} + +// ClusterUserAttributesGetterMock is a mock implementation of v31.ClusterUserAttributesGetter. +// +// func TestSomethingThatUsesClusterUserAttributesGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterUserAttributesGetter +// mockedClusterUserAttributesGetter := &ClusterUserAttributesGetterMock{ +// ClusterUserAttributesFunc: func(namespace string) v31.ClusterUserAttributeInterface { +// panic("mock out the ClusterUserAttributes method") +// }, +// } +// +// // use mockedClusterUserAttributesGetter in code that requires v31.ClusterUserAttributesGetter +// // and then make assertions. +// +// } +type ClusterUserAttributesGetterMock struct { + // ClusterUserAttributesFunc mocks the ClusterUserAttributes method. + ClusterUserAttributesFunc func(namespace string) v31.ClusterUserAttributeInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterUserAttributes holds details about calls to the ClusterUserAttributes method. + ClusterUserAttributes []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterUserAttributes calls ClusterUserAttributesFunc. +func (mock *ClusterUserAttributesGetterMock) ClusterUserAttributes(namespace string) v31.ClusterUserAttributeInterface { + if mock.ClusterUserAttributesFunc == nil { + panic("ClusterUserAttributesGetterMock.ClusterUserAttributesFunc: method is nil but ClusterUserAttributesGetter.ClusterUserAttributes was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterUserAttributesGetterMockClusterUserAttributes.Lock() + mock.calls.ClusterUserAttributes = append(mock.calls.ClusterUserAttributes, callInfo) + lockClusterUserAttributesGetterMockClusterUserAttributes.Unlock() + return mock.ClusterUserAttributesFunc(namespace) +} + +// ClusterUserAttributesCalls gets all the calls that were made to ClusterUserAttributes. +// Check the length with: +// +// len(mockedClusterUserAttributesGetter.ClusterUserAttributesCalls()) +func (mock *ClusterUserAttributesGetterMock) ClusterUserAttributesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterUserAttributesGetterMockClusterUserAttributes.RLock() + calls = mock.calls.ClusterUserAttributes + lockClusterUserAttributesGetterMockClusterUserAttributes.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_controller.go new file mode 100644 index 0000000..30ba08c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterAuthTokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterAuthToken", + } + ClusterAuthTokenResource = metav1.APIResource{ + Name: "clusterauthtokens", + SingularName: "clusterauthtoken", + Namespaced: true, + + Kind: ClusterAuthTokenGroupVersionKind.Kind, + } + + ClusterAuthTokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusterauthtokens", + } +) + +func init() { + resource.Put(ClusterAuthTokenGroupVersionResource) +} + +// Deprecated: use v3.ClusterAuthToken instead +type ClusterAuthToken = v3.ClusterAuthToken + +func NewClusterAuthToken(namespace, name string, obj v3.ClusterAuthToken) *v3.ClusterAuthToken { + obj.APIVersion, obj.Kind = ClusterAuthTokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterAuthTokenHandlerFunc func(key string, obj *v3.ClusterAuthToken) (runtime.Object, error) + +type ClusterAuthTokenChangeHandlerFunc func(obj *v3.ClusterAuthToken) (runtime.Object, error) + +type ClusterAuthTokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterAuthToken, err error) + Get(namespace, name string) (*v3.ClusterAuthToken, error) +} + +type ClusterAuthTokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterAuthTokenLister + AddHandler(ctx context.Context, name string, handler ClusterAuthTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterAuthTokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterAuthTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterAuthTokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterAuthTokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) + Update(*v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterAuthTokenController + AddHandler(ctx context.Context, name string, sync ClusterAuthTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterAuthTokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterAuthTokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterAuthTokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterAuthTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterAuthTokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterAuthTokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterAuthTokenLifecycle) +} + +type clusterAuthTokenLister struct { + ns string + controller *clusterAuthTokenController +} + +func (l *clusterAuthTokenLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterAuthToken, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterAuthToken)) + }) + return +} + +func (l *clusterAuthTokenLister) Get(namespace, name string) (*v3.ClusterAuthToken, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterAuthTokenGroupVersionKind.Group, + Resource: ClusterAuthTokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterAuthToken), nil +} + +type clusterAuthTokenController struct { + ns string + controller.GenericController +} + +func (c *clusterAuthTokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterAuthTokenController) Lister() ClusterAuthTokenLister { + return &clusterAuthTokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterAuthTokenController) AddHandler(ctx context.Context, name string, handler ClusterAuthTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterAuthToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterAuthTokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterAuthTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterAuthToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterAuthTokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterAuthTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterAuthToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterAuthTokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterAuthTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterAuthToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterAuthTokenFactory struct { +} + +func (c clusterAuthTokenFactory) Object() runtime.Object { + return &v3.ClusterAuthToken{} +} + +func (c clusterAuthTokenFactory) List() runtime.Object { + return &v3.ClusterAuthTokenList{} +} + +func (s *clusterAuthTokenClient) Controller() ClusterAuthTokenController { + genericController := controller.NewGenericController(s.ns, ClusterAuthTokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterAuthTokenGroupVersionResource, ClusterAuthTokenGroupVersionKind.Kind, true)) + + return &clusterAuthTokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterAuthTokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterAuthTokenController +} + +func (s *clusterAuthTokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterAuthTokenClient) Create(o *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) Update(o *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) UpdateStatus(o *v3.ClusterAuthToken) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterAuthTokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterAuthTokenClient) List(opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterAuthTokenList), err +} + +func (s *clusterAuthTokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterAuthTokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterAuthTokenList), err +} + +func (s *clusterAuthTokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterAuthTokenClient) Patch(o *v3.ClusterAuthToken, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterAuthToken, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterAuthToken), err +} + +func (s *clusterAuthTokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterAuthTokenClient) AddHandler(ctx context.Context, name string, sync ClusterAuthTokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterAuthTokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterAuthTokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterAuthTokenClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterAuthTokenLifecycle) { + sync := NewClusterAuthTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterAuthTokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterAuthTokenLifecycle) { + sync := NewClusterAuthTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterAuthTokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterAuthTokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterAuthTokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterAuthTokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterAuthTokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterAuthTokenLifecycle) { + sync := NewClusterAuthTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterAuthTokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterAuthTokenLifecycle) { + sync := NewClusterAuthTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_lifecycle_adapter.go new file mode 100644 index 0000000..01d91f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_auth_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterAuthTokenLifecycle interface { + Create(obj *v3.ClusterAuthToken) (runtime.Object, error) + Remove(obj *v3.ClusterAuthToken) (runtime.Object, error) + Updated(obj *v3.ClusterAuthToken) (runtime.Object, error) +} + +type clusterAuthTokenLifecycleAdapter struct { + lifecycle ClusterAuthTokenLifecycle +} + +func (w *clusterAuthTokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterAuthTokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterAuthTokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterAuthToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterAuthTokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterAuthToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterAuthTokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterAuthToken)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterAuthTokenLifecycleAdapter(name string, clusterScoped bool, client ClusterAuthTokenInterface, l ClusterAuthTokenLifecycle) ClusterAuthTokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterAuthTokenGroupVersionResource) + } + adapter := &clusterAuthTokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterAuthToken) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_controller.go new file mode 100644 index 0000000..ea28e8d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterUserAttributeGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterUserAttribute", + } + ClusterUserAttributeResource = metav1.APIResource{ + Name: "clusteruserattributes", + SingularName: "clusteruserattribute", + Namespaced: true, + + Kind: ClusterUserAttributeGroupVersionKind.Kind, + } + + ClusterUserAttributeGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusteruserattributes", + } +) + +func init() { + resource.Put(ClusterUserAttributeGroupVersionResource) +} + +// Deprecated: use v3.ClusterUserAttribute instead +type ClusterUserAttribute = v3.ClusterUserAttribute + +func NewClusterUserAttribute(namespace, name string, obj v3.ClusterUserAttribute) *v3.ClusterUserAttribute { + obj.APIVersion, obj.Kind = ClusterUserAttributeGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterUserAttributeHandlerFunc func(key string, obj *v3.ClusterUserAttribute) (runtime.Object, error) + +type ClusterUserAttributeChangeHandlerFunc func(obj *v3.ClusterUserAttribute) (runtime.Object, error) + +type ClusterUserAttributeLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterUserAttribute, err error) + Get(namespace, name string) (*v3.ClusterUserAttribute, error) +} + +type ClusterUserAttributeController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterUserAttributeLister + AddHandler(ctx context.Context, name string, handler ClusterUserAttributeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterUserAttributeHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterUserAttributeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterUserAttributeHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterUserAttributeInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) + Update(*v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterUserAttributeController + AddHandler(ctx context.Context, name string, sync ClusterUserAttributeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterUserAttributeHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterUserAttributeLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterUserAttributeLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterUserAttributeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterUserAttributeHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterUserAttributeLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterUserAttributeLifecycle) +} + +type clusterUserAttributeLister struct { + ns string + controller *clusterUserAttributeController +} + +func (l *clusterUserAttributeLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterUserAttribute, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterUserAttribute)) + }) + return +} + +func (l *clusterUserAttributeLister) Get(namespace, name string) (*v3.ClusterUserAttribute, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterUserAttributeGroupVersionKind.Group, + Resource: ClusterUserAttributeGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterUserAttribute), nil +} + +type clusterUserAttributeController struct { + ns string + controller.GenericController +} + +func (c *clusterUserAttributeController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterUserAttributeController) Lister() ClusterUserAttributeLister { + return &clusterUserAttributeLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterUserAttributeController) AddHandler(ctx context.Context, name string, handler ClusterUserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterUserAttribute); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterUserAttributeController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterUserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterUserAttribute); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterUserAttributeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterUserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterUserAttribute); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterUserAttributeController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterUserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterUserAttribute); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterUserAttributeFactory struct { +} + +func (c clusterUserAttributeFactory) Object() runtime.Object { + return &v3.ClusterUserAttribute{} +} + +func (c clusterUserAttributeFactory) List() runtime.Object { + return &v3.ClusterUserAttributeList{} +} + +func (s *clusterUserAttributeClient) Controller() ClusterUserAttributeController { + genericController := controller.NewGenericController(s.ns, ClusterUserAttributeGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterUserAttributeGroupVersionResource, ClusterUserAttributeGroupVersionKind.Kind, true)) + + return &clusterUserAttributeController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterUserAttributeClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterUserAttributeController +} + +func (s *clusterUserAttributeClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterUserAttributeClient) Create(o *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) Update(o *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) UpdateStatus(o *v3.ClusterUserAttribute) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterUserAttributeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterUserAttributeClient) List(opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterUserAttributeList), err +} + +func (s *clusterUserAttributeClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterUserAttributeList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterUserAttributeList), err +} + +func (s *clusterUserAttributeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterUserAttributeClient) Patch(o *v3.ClusterUserAttribute, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterUserAttribute, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterUserAttribute), err +} + +func (s *clusterUserAttributeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterUserAttributeClient) AddHandler(ctx context.Context, name string, sync ClusterUserAttributeHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterUserAttributeClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterUserAttributeHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterUserAttributeClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterUserAttributeLifecycle) { + sync := NewClusterUserAttributeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterUserAttributeClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterUserAttributeLifecycle) { + sync := NewClusterUserAttributeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterUserAttributeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterUserAttributeHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterUserAttributeClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterUserAttributeHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterUserAttributeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterUserAttributeLifecycle) { + sync := NewClusterUserAttributeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterUserAttributeClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterUserAttributeLifecycle) { + sync := NewClusterUserAttributeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_lifecycle_adapter.go new file mode 100644 index 0000000..7f224a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_cluster_user_attribute_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterUserAttributeLifecycle interface { + Create(obj *v3.ClusterUserAttribute) (runtime.Object, error) + Remove(obj *v3.ClusterUserAttribute) (runtime.Object, error) + Updated(obj *v3.ClusterUserAttribute) (runtime.Object, error) +} + +type clusterUserAttributeLifecycleAdapter struct { + lifecycle ClusterUserAttributeLifecycle +} + +func (w *clusterUserAttributeLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterUserAttributeLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterUserAttributeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterUserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterUserAttributeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterUserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterUserAttributeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterUserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterUserAttributeLifecycleAdapter(name string, clusterScoped bool, client ClusterUserAttributeInterface, l ClusterUserAttributeLifecycle) ClusterUserAttributeHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterUserAttributeGroupVersionResource) + } + adapter := &clusterUserAttributeLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterUserAttribute) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_k8s_client.go new file mode 100644 index 0000000..d95dbda --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_k8s_client.go @@ -0,0 +1,78 @@ +package v3 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + ClusterAuthTokensGetter + ClusterUserAttributesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v3.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type ClusterAuthTokensGetter interface { + ClusterAuthTokens(namespace string) ClusterAuthTokenInterface +} + +func (c *Client) ClusterAuthTokens(namespace string) ClusterAuthTokenInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterAuthTokenGroupVersionResource, ClusterAuthTokenGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterAuthTokenResource, ClusterAuthTokenGroupVersionKind, clusterAuthTokenFactory{}) + return &clusterAuthTokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterUserAttributesGetter interface { + ClusterUserAttributes(namespace string) ClusterUserAttributeInterface +} + +func (c *Client) ClusterUserAttributes(namespace string) ClusterUserAttributeInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterUserAttributeGroupVersionResource, ClusterUserAttributeGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterUserAttributeResource, ClusterUserAttributeGroupVersionKind, clusterUserAttributeFactory{}) + return &clusterUserAttributeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_scheme.go new file mode 100644 index 0000000..3613b92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/cluster.cattle.io/v3/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "cluster.cattle.io" + Version = "v3" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_component_status_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_component_status_mock.go new file mode 100644 index 0000000..9d9bf88 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_component_status_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockComponentStatusListerMockGet sync.RWMutex + lockComponentStatusListerMockList sync.RWMutex +) + +// Ensure, that ComponentStatusListerMock does implement v11.ComponentStatusLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ComponentStatusLister = &ComponentStatusListerMock{} + +// ComponentStatusListerMock is a mock implementation of v11.ComponentStatusLister. +// +// func TestSomethingThatUsesComponentStatusLister(t *testing.T) { +// +// // make and configure a mocked v11.ComponentStatusLister +// mockedComponentStatusLister := &ComponentStatusListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ComponentStatus, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ComponentStatus, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedComponentStatusLister in code that requires v11.ComponentStatusLister +// // and then make assertions. +// +// } +type ComponentStatusListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ComponentStatus, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ComponentStatus, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ComponentStatusListerMock) Get(namespace string, name string) (*v1.ComponentStatus, error) { + if mock.GetFunc == nil { + panic("ComponentStatusListerMock.GetFunc: method is nil but ComponentStatusLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockComponentStatusListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockComponentStatusListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedComponentStatusLister.GetCalls()) +func (mock *ComponentStatusListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockComponentStatusListerMockGet.RLock() + calls = mock.calls.Get + lockComponentStatusListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ComponentStatusListerMock) List(namespace string, selector labels.Selector) ([]*v1.ComponentStatus, error) { + if mock.ListFunc == nil { + panic("ComponentStatusListerMock.ListFunc: method is nil but ComponentStatusLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockComponentStatusListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockComponentStatusListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedComponentStatusLister.ListCalls()) +func (mock *ComponentStatusListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockComponentStatusListerMockList.RLock() + calls = mock.calls.List + lockComponentStatusListerMockList.RUnlock() + return calls +} + +var ( + lockComponentStatusControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockComponentStatusControllerMockAddClusterScopedHandler sync.RWMutex + lockComponentStatusControllerMockAddFeatureHandler sync.RWMutex + lockComponentStatusControllerMockAddHandler sync.RWMutex + lockComponentStatusControllerMockEnqueue sync.RWMutex + lockComponentStatusControllerMockEnqueueAfter sync.RWMutex + lockComponentStatusControllerMockGeneric sync.RWMutex + lockComponentStatusControllerMockInformer sync.RWMutex + lockComponentStatusControllerMockLister sync.RWMutex +) + +// Ensure, that ComponentStatusControllerMock does implement v11.ComponentStatusController. +// If this is not the case, regenerate this file with moq. +var _ v11.ComponentStatusController = &ComponentStatusControllerMock{} + +// ComponentStatusControllerMock is a mock implementation of v11.ComponentStatusController. +// +// func TestSomethingThatUsesComponentStatusController(t *testing.T) { +// +// // make and configure a mocked v11.ComponentStatusController +// mockedComponentStatusController := &ComponentStatusControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ComponentStatusLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedComponentStatusController in code that requires v11.ComponentStatusController +// // and then make assertions. +// +// } +type ComponentStatusControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ComponentStatusHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ComponentStatusLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ComponentStatusHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ComponentStatusHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ComponentStatusHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ComponentStatusHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ComponentStatusControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ComponentStatusControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ComponentStatusController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockComponentStatusControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockComponentStatusControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedComponentStatusController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ComponentStatusControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc + } + lockComponentStatusControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockComponentStatusControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ComponentStatusControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ComponentStatusHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ComponentStatusControllerMock.AddClusterScopedHandlerFunc: method is nil but ComponentStatusController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockComponentStatusControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockComponentStatusControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedComponentStatusController.AddClusterScopedHandlerCalls()) +func (mock *ComponentStatusControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ComponentStatusHandlerFunc + } + lockComponentStatusControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockComponentStatusControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ComponentStatusControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ComponentStatusControllerMock.AddFeatureHandlerFunc: method is nil but ComponentStatusController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockComponentStatusControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockComponentStatusControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedComponentStatusController.AddFeatureHandlerCalls()) +func (mock *ComponentStatusControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc + } + lockComponentStatusControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockComponentStatusControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ComponentStatusControllerMock) AddHandler(ctx context.Context, name string, handler v11.ComponentStatusHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ComponentStatusControllerMock.AddHandlerFunc: method is nil but ComponentStatusController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockComponentStatusControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockComponentStatusControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedComponentStatusController.AddHandlerCalls()) +func (mock *ComponentStatusControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ComponentStatusHandlerFunc + } + lockComponentStatusControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockComponentStatusControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ComponentStatusControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ComponentStatusControllerMock.EnqueueFunc: method is nil but ComponentStatusController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockComponentStatusControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockComponentStatusControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedComponentStatusController.EnqueueCalls()) +func (mock *ComponentStatusControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockComponentStatusControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockComponentStatusControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ComponentStatusControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ComponentStatusControllerMock.EnqueueAfterFunc: method is nil but ComponentStatusController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockComponentStatusControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockComponentStatusControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedComponentStatusController.EnqueueAfterCalls()) +func (mock *ComponentStatusControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockComponentStatusControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockComponentStatusControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ComponentStatusControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ComponentStatusControllerMock.GenericFunc: method is nil but ComponentStatusController.Generic was just called") + } + callInfo := struct { + }{} + lockComponentStatusControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockComponentStatusControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedComponentStatusController.GenericCalls()) +func (mock *ComponentStatusControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockComponentStatusControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockComponentStatusControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ComponentStatusControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ComponentStatusControllerMock.InformerFunc: method is nil but ComponentStatusController.Informer was just called") + } + callInfo := struct { + }{} + lockComponentStatusControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockComponentStatusControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedComponentStatusController.InformerCalls()) +func (mock *ComponentStatusControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockComponentStatusControllerMockInformer.RLock() + calls = mock.calls.Informer + lockComponentStatusControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ComponentStatusControllerMock) Lister() v11.ComponentStatusLister { + if mock.ListerFunc == nil { + panic("ComponentStatusControllerMock.ListerFunc: method is nil but ComponentStatusController.Lister was just called") + } + callInfo := struct { + }{} + lockComponentStatusControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockComponentStatusControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedComponentStatusController.ListerCalls()) +func (mock *ComponentStatusControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockComponentStatusControllerMockLister.RLock() + calls = mock.calls.Lister + lockComponentStatusControllerMockLister.RUnlock() + return calls +} + +var ( + lockComponentStatusInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockComponentStatusInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockComponentStatusInterfaceMockAddClusterScopedHandler sync.RWMutex + lockComponentStatusInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockComponentStatusInterfaceMockAddFeatureHandler sync.RWMutex + lockComponentStatusInterfaceMockAddFeatureLifecycle sync.RWMutex + lockComponentStatusInterfaceMockAddHandler sync.RWMutex + lockComponentStatusInterfaceMockAddLifecycle sync.RWMutex + lockComponentStatusInterfaceMockController sync.RWMutex + lockComponentStatusInterfaceMockCreate sync.RWMutex + lockComponentStatusInterfaceMockDelete sync.RWMutex + lockComponentStatusInterfaceMockDeleteCollection sync.RWMutex + lockComponentStatusInterfaceMockDeleteNamespaced sync.RWMutex + lockComponentStatusInterfaceMockGet sync.RWMutex + lockComponentStatusInterfaceMockGetNamespaced sync.RWMutex + lockComponentStatusInterfaceMockList sync.RWMutex + lockComponentStatusInterfaceMockListNamespaced sync.RWMutex + lockComponentStatusInterfaceMockObjectClient sync.RWMutex + lockComponentStatusInterfaceMockUpdate sync.RWMutex + lockComponentStatusInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ComponentStatusInterfaceMock does implement v11.ComponentStatusInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ComponentStatusInterface = &ComponentStatusInterfaceMock{} + +// ComponentStatusInterfaceMock is a mock implementation of v11.ComponentStatusInterface. +// +// func TestSomethingThatUsesComponentStatusInterface(t *testing.T) { +// +// // make and configure a mocked v11.ComponentStatusInterface +// mockedComponentStatusInterface := &ComponentStatusInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ComponentStatusLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ComponentStatusLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ComponentStatusController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ComponentStatusList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ComponentStatusList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedComponentStatusInterface in code that requires v11.ComponentStatusInterface +// // and then make assertions. +// +// } +type ComponentStatusInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ComponentStatusLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ComponentStatusHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ComponentStatusLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ComponentStatusController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ComponentStatusList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ComponentStatusList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ComponentStatusHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ComponentStatusLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ComponentStatusHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ComponentStatusLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ComponentStatusHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ComponentStatusLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ComponentStatusHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ComponentStatusLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ComponentStatus + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ComponentStatus + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ComponentStatusInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ComponentStatusInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ComponentStatusInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockComponentStatusInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockComponentStatusInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ComponentStatusInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc + } + lockComponentStatusInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockComponentStatusInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ComponentStatusInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ComponentStatusInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ComponentStatusInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockComponentStatusInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockComponentStatusInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ComponentStatusInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle + } + lockComponentStatusInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockComponentStatusInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ComponentStatusInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ComponentStatusHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ComponentStatusInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ComponentStatusInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockComponentStatusInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockComponentStatusInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddClusterScopedHandlerCalls()) +func (mock *ComponentStatusInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ComponentStatusHandlerFunc + } + lockComponentStatusInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockComponentStatusInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ComponentStatusInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ComponentStatusLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ComponentStatusInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ComponentStatusInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockComponentStatusInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockComponentStatusInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddClusterScopedLifecycleCalls()) +func (mock *ComponentStatusInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ComponentStatusLifecycle + } + lockComponentStatusInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockComponentStatusInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ComponentStatusInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ComponentStatusInterfaceMock.AddFeatureHandlerFunc: method is nil but ComponentStatusInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockComponentStatusInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockComponentStatusInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddFeatureHandlerCalls()) +func (mock *ComponentStatusInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ComponentStatusHandlerFunc + } + lockComponentStatusInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockComponentStatusInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ComponentStatusInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ComponentStatusLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ComponentStatusInterfaceMock.AddFeatureLifecycleFunc: method is nil but ComponentStatusInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ComponentStatusLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockComponentStatusInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockComponentStatusInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddFeatureLifecycleCalls()) +func (mock *ComponentStatusInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ComponentStatusLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ComponentStatusLifecycle + } + lockComponentStatusInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockComponentStatusInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ComponentStatusInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ComponentStatusHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ComponentStatusInterfaceMock.AddHandlerFunc: method is nil but ComponentStatusInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ComponentStatusHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockComponentStatusInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockComponentStatusInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddHandlerCalls()) +func (mock *ComponentStatusInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ComponentStatusHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ComponentStatusHandlerFunc + } + lockComponentStatusInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockComponentStatusInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ComponentStatusInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ComponentStatusLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ComponentStatusInterfaceMock.AddLifecycleFunc: method is nil but ComponentStatusInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ComponentStatusLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockComponentStatusInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockComponentStatusInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedComponentStatusInterface.AddLifecycleCalls()) +func (mock *ComponentStatusInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ComponentStatusLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ComponentStatusLifecycle + } + lockComponentStatusInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockComponentStatusInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ComponentStatusInterfaceMock) Controller() v11.ComponentStatusController { + if mock.ControllerFunc == nil { + panic("ComponentStatusInterfaceMock.ControllerFunc: method is nil but ComponentStatusInterface.Controller was just called") + } + callInfo := struct { + }{} + lockComponentStatusInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockComponentStatusInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedComponentStatusInterface.ControllerCalls()) +func (mock *ComponentStatusInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockComponentStatusInterfaceMockController.RLock() + calls = mock.calls.Controller + lockComponentStatusInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ComponentStatusInterfaceMock) Create(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) { + if mock.CreateFunc == nil { + panic("ComponentStatusInterfaceMock.CreateFunc: method is nil but ComponentStatusInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ComponentStatus + }{ + In1: in1, + } + lockComponentStatusInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockComponentStatusInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedComponentStatusInterface.CreateCalls()) +func (mock *ComponentStatusInterfaceMock) CreateCalls() []struct { + In1 *v1.ComponentStatus +} { + var calls []struct { + In1 *v1.ComponentStatus + } + lockComponentStatusInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockComponentStatusInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ComponentStatusInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ComponentStatusInterfaceMock.DeleteFunc: method is nil but ComponentStatusInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockComponentStatusInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockComponentStatusInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedComponentStatusInterface.DeleteCalls()) +func (mock *ComponentStatusInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockComponentStatusInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockComponentStatusInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ComponentStatusInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ComponentStatusInterfaceMock.DeleteCollectionFunc: method is nil but ComponentStatusInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockComponentStatusInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockComponentStatusInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedComponentStatusInterface.DeleteCollectionCalls()) +func (mock *ComponentStatusInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockComponentStatusInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockComponentStatusInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ComponentStatusInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ComponentStatusInterfaceMock.DeleteNamespacedFunc: method is nil but ComponentStatusInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockComponentStatusInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockComponentStatusInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedComponentStatusInterface.DeleteNamespacedCalls()) +func (mock *ComponentStatusInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockComponentStatusInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockComponentStatusInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ComponentStatusInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { + if mock.GetFunc == nil { + panic("ComponentStatusInterfaceMock.GetFunc: method is nil but ComponentStatusInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockComponentStatusInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockComponentStatusInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedComponentStatusInterface.GetCalls()) +func (mock *ComponentStatusInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockComponentStatusInterfaceMockGet.RLock() + calls = mock.calls.Get + lockComponentStatusInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ComponentStatusInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { + if mock.GetNamespacedFunc == nil { + panic("ComponentStatusInterfaceMock.GetNamespacedFunc: method is nil but ComponentStatusInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockComponentStatusInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockComponentStatusInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedComponentStatusInterface.GetNamespacedCalls()) +func (mock *ComponentStatusInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockComponentStatusInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockComponentStatusInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ComponentStatusInterfaceMock) List(opts metav1.ListOptions) (*v1.ComponentStatusList, error) { + if mock.ListFunc == nil { + panic("ComponentStatusInterfaceMock.ListFunc: method is nil but ComponentStatusInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockComponentStatusInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockComponentStatusInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedComponentStatusInterface.ListCalls()) +func (mock *ComponentStatusInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockComponentStatusInterfaceMockList.RLock() + calls = mock.calls.List + lockComponentStatusInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ComponentStatusInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ComponentStatusList, error) { + if mock.ListNamespacedFunc == nil { + panic("ComponentStatusInterfaceMock.ListNamespacedFunc: method is nil but ComponentStatusInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockComponentStatusInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockComponentStatusInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedComponentStatusInterface.ListNamespacedCalls()) +func (mock *ComponentStatusInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockComponentStatusInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockComponentStatusInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ComponentStatusInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ComponentStatusInterfaceMock.ObjectClientFunc: method is nil but ComponentStatusInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockComponentStatusInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockComponentStatusInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedComponentStatusInterface.ObjectClientCalls()) +func (mock *ComponentStatusInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockComponentStatusInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockComponentStatusInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ComponentStatusInterfaceMock) Update(in1 *v1.ComponentStatus) (*v1.ComponentStatus, error) { + if mock.UpdateFunc == nil { + panic("ComponentStatusInterfaceMock.UpdateFunc: method is nil but ComponentStatusInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ComponentStatus + }{ + In1: in1, + } + lockComponentStatusInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockComponentStatusInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedComponentStatusInterface.UpdateCalls()) +func (mock *ComponentStatusInterfaceMock) UpdateCalls() []struct { + In1 *v1.ComponentStatus +} { + var calls []struct { + In1 *v1.ComponentStatus + } + lockComponentStatusInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockComponentStatusInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ComponentStatusInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ComponentStatusInterfaceMock.WatchFunc: method is nil but ComponentStatusInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockComponentStatusInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockComponentStatusInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedComponentStatusInterface.WatchCalls()) +func (mock *ComponentStatusInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockComponentStatusInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockComponentStatusInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockComponentStatusesGetterMockComponentStatuses sync.RWMutex +) + +// Ensure, that ComponentStatusesGetterMock does implement v11.ComponentStatusesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ComponentStatusesGetter = &ComponentStatusesGetterMock{} + +// ComponentStatusesGetterMock is a mock implementation of v11.ComponentStatusesGetter. +// +// func TestSomethingThatUsesComponentStatusesGetter(t *testing.T) { +// +// // make and configure a mocked v11.ComponentStatusesGetter +// mockedComponentStatusesGetter := &ComponentStatusesGetterMock{ +// ComponentStatusesFunc: func(namespace string) v11.ComponentStatusInterface { +// panic("mock out the ComponentStatuses method") +// }, +// } +// +// // use mockedComponentStatusesGetter in code that requires v11.ComponentStatusesGetter +// // and then make assertions. +// +// } +type ComponentStatusesGetterMock struct { + // ComponentStatusesFunc mocks the ComponentStatuses method. + ComponentStatusesFunc func(namespace string) v11.ComponentStatusInterface + + // calls tracks calls to the methods. + calls struct { + // ComponentStatuses holds details about calls to the ComponentStatuses method. + ComponentStatuses []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ComponentStatuses calls ComponentStatusesFunc. +func (mock *ComponentStatusesGetterMock) ComponentStatuses(namespace string) v11.ComponentStatusInterface { + if mock.ComponentStatusesFunc == nil { + panic("ComponentStatusesGetterMock.ComponentStatusesFunc: method is nil but ComponentStatusesGetter.ComponentStatuses was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockComponentStatusesGetterMockComponentStatuses.Lock() + mock.calls.ComponentStatuses = append(mock.calls.ComponentStatuses, callInfo) + lockComponentStatusesGetterMockComponentStatuses.Unlock() + return mock.ComponentStatusesFunc(namespace) +} + +// ComponentStatusesCalls gets all the calls that were made to ComponentStatuses. +// Check the length with: +// +// len(mockedComponentStatusesGetter.ComponentStatusesCalls()) +func (mock *ComponentStatusesGetterMock) ComponentStatusesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockComponentStatusesGetterMockComponentStatuses.RLock() + calls = mock.calls.ComponentStatuses + lockComponentStatusesGetterMockComponentStatuses.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_config_map_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_config_map_mock.go new file mode 100644 index 0000000..61a2697 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_config_map_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockConfigMapListerMockGet sync.RWMutex + lockConfigMapListerMockList sync.RWMutex +) + +// Ensure, that ConfigMapListerMock does implement v11.ConfigMapLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ConfigMapLister = &ConfigMapListerMock{} + +// ConfigMapListerMock is a mock implementation of v11.ConfigMapLister. +// +// func TestSomethingThatUsesConfigMapLister(t *testing.T) { +// +// // make and configure a mocked v11.ConfigMapLister +// mockedConfigMapLister := &ConfigMapListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ConfigMap, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ConfigMap, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedConfigMapLister in code that requires v11.ConfigMapLister +// // and then make assertions. +// +// } +type ConfigMapListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ConfigMap, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ConfigMap, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ConfigMapListerMock) Get(namespace string, name string) (*v1.ConfigMap, error) { + if mock.GetFunc == nil { + panic("ConfigMapListerMock.GetFunc: method is nil but ConfigMapLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockConfigMapListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockConfigMapListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedConfigMapLister.GetCalls()) +func (mock *ConfigMapListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockConfigMapListerMockGet.RLock() + calls = mock.calls.Get + lockConfigMapListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ConfigMapListerMock) List(namespace string, selector labels.Selector) ([]*v1.ConfigMap, error) { + if mock.ListFunc == nil { + panic("ConfigMapListerMock.ListFunc: method is nil but ConfigMapLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockConfigMapListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockConfigMapListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedConfigMapLister.ListCalls()) +func (mock *ConfigMapListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockConfigMapListerMockList.RLock() + calls = mock.calls.List + lockConfigMapListerMockList.RUnlock() + return calls +} + +var ( + lockConfigMapControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockConfigMapControllerMockAddClusterScopedHandler sync.RWMutex + lockConfigMapControllerMockAddFeatureHandler sync.RWMutex + lockConfigMapControllerMockAddHandler sync.RWMutex + lockConfigMapControllerMockEnqueue sync.RWMutex + lockConfigMapControllerMockEnqueueAfter sync.RWMutex + lockConfigMapControllerMockGeneric sync.RWMutex + lockConfigMapControllerMockInformer sync.RWMutex + lockConfigMapControllerMockLister sync.RWMutex +) + +// Ensure, that ConfigMapControllerMock does implement v11.ConfigMapController. +// If this is not the case, regenerate this file with moq. +var _ v11.ConfigMapController = &ConfigMapControllerMock{} + +// ConfigMapControllerMock is a mock implementation of v11.ConfigMapController. +// +// func TestSomethingThatUsesConfigMapController(t *testing.T) { +// +// // make and configure a mocked v11.ConfigMapController +// mockedConfigMapController := &ConfigMapControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ConfigMapHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ConfigMapHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ConfigMapHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ConfigMapLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedConfigMapController in code that requires v11.ConfigMapController +// // and then make assertions. +// +// } +type ConfigMapControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ConfigMapHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ConfigMapHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ConfigMapHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ConfigMapLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ConfigMapHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ConfigMapHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ConfigMapHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ConfigMapHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ConfigMapControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ConfigMapHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ConfigMapControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ConfigMapController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockConfigMapControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockConfigMapControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedConfigMapController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ConfigMapControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc + } + lockConfigMapControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockConfigMapControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ConfigMapControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ConfigMapHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ConfigMapControllerMock.AddClusterScopedHandlerFunc: method is nil but ConfigMapController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockConfigMapControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockConfigMapControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedConfigMapController.AddClusterScopedHandlerCalls()) +func (mock *ConfigMapControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ConfigMapHandlerFunc + } + lockConfigMapControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockConfigMapControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ConfigMapControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ConfigMapControllerMock.AddFeatureHandlerFunc: method is nil but ConfigMapController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockConfigMapControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockConfigMapControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedConfigMapController.AddFeatureHandlerCalls()) +func (mock *ConfigMapControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc + } + lockConfigMapControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockConfigMapControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ConfigMapControllerMock) AddHandler(ctx context.Context, name string, handler v11.ConfigMapHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ConfigMapControllerMock.AddHandlerFunc: method is nil but ConfigMapController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockConfigMapControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockConfigMapControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedConfigMapController.AddHandlerCalls()) +func (mock *ConfigMapControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ConfigMapHandlerFunc + } + lockConfigMapControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockConfigMapControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ConfigMapControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ConfigMapControllerMock.EnqueueFunc: method is nil but ConfigMapController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockConfigMapControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockConfigMapControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedConfigMapController.EnqueueCalls()) +func (mock *ConfigMapControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockConfigMapControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockConfigMapControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ConfigMapControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ConfigMapControllerMock.EnqueueAfterFunc: method is nil but ConfigMapController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockConfigMapControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockConfigMapControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedConfigMapController.EnqueueAfterCalls()) +func (mock *ConfigMapControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockConfigMapControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockConfigMapControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ConfigMapControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ConfigMapControllerMock.GenericFunc: method is nil but ConfigMapController.Generic was just called") + } + callInfo := struct { + }{} + lockConfigMapControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockConfigMapControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedConfigMapController.GenericCalls()) +func (mock *ConfigMapControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockConfigMapControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockConfigMapControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ConfigMapControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ConfigMapControllerMock.InformerFunc: method is nil but ConfigMapController.Informer was just called") + } + callInfo := struct { + }{} + lockConfigMapControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockConfigMapControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedConfigMapController.InformerCalls()) +func (mock *ConfigMapControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockConfigMapControllerMockInformer.RLock() + calls = mock.calls.Informer + lockConfigMapControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ConfigMapControllerMock) Lister() v11.ConfigMapLister { + if mock.ListerFunc == nil { + panic("ConfigMapControllerMock.ListerFunc: method is nil but ConfigMapController.Lister was just called") + } + callInfo := struct { + }{} + lockConfigMapControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockConfigMapControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedConfigMapController.ListerCalls()) +func (mock *ConfigMapControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockConfigMapControllerMockLister.RLock() + calls = mock.calls.Lister + lockConfigMapControllerMockLister.RUnlock() + return calls +} + +var ( + lockConfigMapInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockConfigMapInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockConfigMapInterfaceMockAddClusterScopedHandler sync.RWMutex + lockConfigMapInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockConfigMapInterfaceMockAddFeatureHandler sync.RWMutex + lockConfigMapInterfaceMockAddFeatureLifecycle sync.RWMutex + lockConfigMapInterfaceMockAddHandler sync.RWMutex + lockConfigMapInterfaceMockAddLifecycle sync.RWMutex + lockConfigMapInterfaceMockController sync.RWMutex + lockConfigMapInterfaceMockCreate sync.RWMutex + lockConfigMapInterfaceMockDelete sync.RWMutex + lockConfigMapInterfaceMockDeleteCollection sync.RWMutex + lockConfigMapInterfaceMockDeleteNamespaced sync.RWMutex + lockConfigMapInterfaceMockGet sync.RWMutex + lockConfigMapInterfaceMockGetNamespaced sync.RWMutex + lockConfigMapInterfaceMockList sync.RWMutex + lockConfigMapInterfaceMockListNamespaced sync.RWMutex + lockConfigMapInterfaceMockObjectClient sync.RWMutex + lockConfigMapInterfaceMockUpdate sync.RWMutex + lockConfigMapInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ConfigMapInterfaceMock does implement v11.ConfigMapInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ConfigMapInterface = &ConfigMapInterfaceMock{} + +// ConfigMapInterfaceMock is a mock implementation of v11.ConfigMapInterface. +// +// func TestSomethingThatUsesConfigMapInterface(t *testing.T) { +// +// // make and configure a mocked v11.ConfigMapInterface +// mockedConfigMapInterface := &ConfigMapInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ConfigMapLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ConfigMapHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ConfigMapLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ConfigMapController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ConfigMap) (*v1.ConfigMap, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ConfigMapList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ConfigMapList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ConfigMap) (*v1.ConfigMap, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedConfigMapInterface in code that requires v11.ConfigMapInterface +// // and then make assertions. +// +// } +type ConfigMapInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ConfigMapLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ConfigMapHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ConfigMapLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ConfigMapController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ConfigMap) (*v1.ConfigMap, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ConfigMap, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ConfigMapList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ConfigMapList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ConfigMap) (*v1.ConfigMap, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ConfigMapHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ConfigMapLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ConfigMapHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ConfigMapLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ConfigMapHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ConfigMapLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ConfigMapHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ConfigMapLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ConfigMap + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ConfigMap + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ConfigMapInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ConfigMapInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ConfigMapInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockConfigMapInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockConfigMapInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedConfigMapInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ConfigMapInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc + } + lockConfigMapInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockConfigMapInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ConfigMapInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ConfigMapInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ConfigMapInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockConfigMapInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockConfigMapInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedConfigMapInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ConfigMapInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle + } + lockConfigMapInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockConfigMapInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ConfigMapInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ConfigMapHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ConfigMapInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ConfigMapInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockConfigMapInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockConfigMapInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedConfigMapInterface.AddClusterScopedHandlerCalls()) +func (mock *ConfigMapInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ConfigMapHandlerFunc + } + lockConfigMapInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockConfigMapInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ConfigMapInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ConfigMapLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ConfigMapInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ConfigMapInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockConfigMapInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockConfigMapInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedConfigMapInterface.AddClusterScopedLifecycleCalls()) +func (mock *ConfigMapInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ConfigMapLifecycle + } + lockConfigMapInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockConfigMapInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ConfigMapInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ConfigMapHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ConfigMapInterfaceMock.AddFeatureHandlerFunc: method is nil but ConfigMapInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockConfigMapInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockConfigMapInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedConfigMapInterface.AddFeatureHandlerCalls()) +func (mock *ConfigMapInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ConfigMapHandlerFunc + } + lockConfigMapInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockConfigMapInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ConfigMapInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ConfigMapLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ConfigMapInterfaceMock.AddFeatureLifecycleFunc: method is nil but ConfigMapInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ConfigMapLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockConfigMapInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockConfigMapInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedConfigMapInterface.AddFeatureLifecycleCalls()) +func (mock *ConfigMapInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ConfigMapLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ConfigMapLifecycle + } + lockConfigMapInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockConfigMapInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ConfigMapInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ConfigMapHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ConfigMapInterfaceMock.AddHandlerFunc: method is nil but ConfigMapInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ConfigMapHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockConfigMapInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockConfigMapInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedConfigMapInterface.AddHandlerCalls()) +func (mock *ConfigMapInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ConfigMapHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ConfigMapHandlerFunc + } + lockConfigMapInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockConfigMapInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ConfigMapInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ConfigMapLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ConfigMapInterfaceMock.AddLifecycleFunc: method is nil but ConfigMapInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ConfigMapLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockConfigMapInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockConfigMapInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedConfigMapInterface.AddLifecycleCalls()) +func (mock *ConfigMapInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ConfigMapLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ConfigMapLifecycle + } + lockConfigMapInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockConfigMapInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ConfigMapInterfaceMock) Controller() v11.ConfigMapController { + if mock.ControllerFunc == nil { + panic("ConfigMapInterfaceMock.ControllerFunc: method is nil but ConfigMapInterface.Controller was just called") + } + callInfo := struct { + }{} + lockConfigMapInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockConfigMapInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedConfigMapInterface.ControllerCalls()) +func (mock *ConfigMapInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockConfigMapInterfaceMockController.RLock() + calls = mock.calls.Controller + lockConfigMapInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ConfigMapInterfaceMock) Create(in1 *v1.ConfigMap) (*v1.ConfigMap, error) { + if mock.CreateFunc == nil { + panic("ConfigMapInterfaceMock.CreateFunc: method is nil but ConfigMapInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ConfigMap + }{ + In1: in1, + } + lockConfigMapInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockConfigMapInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedConfigMapInterface.CreateCalls()) +func (mock *ConfigMapInterfaceMock) CreateCalls() []struct { + In1 *v1.ConfigMap +} { + var calls []struct { + In1 *v1.ConfigMap + } + lockConfigMapInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockConfigMapInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ConfigMapInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ConfigMapInterfaceMock.DeleteFunc: method is nil but ConfigMapInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockConfigMapInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockConfigMapInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedConfigMapInterface.DeleteCalls()) +func (mock *ConfigMapInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockConfigMapInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockConfigMapInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ConfigMapInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ConfigMapInterfaceMock.DeleteCollectionFunc: method is nil but ConfigMapInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockConfigMapInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockConfigMapInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedConfigMapInterface.DeleteCollectionCalls()) +func (mock *ConfigMapInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockConfigMapInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockConfigMapInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ConfigMapInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ConfigMapInterfaceMock.DeleteNamespacedFunc: method is nil but ConfigMapInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockConfigMapInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockConfigMapInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedConfigMapInterface.DeleteNamespacedCalls()) +func (mock *ConfigMapInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockConfigMapInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockConfigMapInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ConfigMapInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { + if mock.GetFunc == nil { + panic("ConfigMapInterfaceMock.GetFunc: method is nil but ConfigMapInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockConfigMapInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockConfigMapInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedConfigMapInterface.GetCalls()) +func (mock *ConfigMapInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockConfigMapInterfaceMockGet.RLock() + calls = mock.calls.Get + lockConfigMapInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ConfigMapInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { + if mock.GetNamespacedFunc == nil { + panic("ConfigMapInterfaceMock.GetNamespacedFunc: method is nil but ConfigMapInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockConfigMapInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockConfigMapInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedConfigMapInterface.GetNamespacedCalls()) +func (mock *ConfigMapInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockConfigMapInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockConfigMapInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ConfigMapInterfaceMock) List(opts metav1.ListOptions) (*v1.ConfigMapList, error) { + if mock.ListFunc == nil { + panic("ConfigMapInterfaceMock.ListFunc: method is nil but ConfigMapInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockConfigMapInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockConfigMapInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedConfigMapInterface.ListCalls()) +func (mock *ConfigMapInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockConfigMapInterfaceMockList.RLock() + calls = mock.calls.List + lockConfigMapInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ConfigMapInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ConfigMapList, error) { + if mock.ListNamespacedFunc == nil { + panic("ConfigMapInterfaceMock.ListNamespacedFunc: method is nil but ConfigMapInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockConfigMapInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockConfigMapInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedConfigMapInterface.ListNamespacedCalls()) +func (mock *ConfigMapInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockConfigMapInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockConfigMapInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ConfigMapInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ConfigMapInterfaceMock.ObjectClientFunc: method is nil but ConfigMapInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockConfigMapInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockConfigMapInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedConfigMapInterface.ObjectClientCalls()) +func (mock *ConfigMapInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockConfigMapInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockConfigMapInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ConfigMapInterfaceMock) Update(in1 *v1.ConfigMap) (*v1.ConfigMap, error) { + if mock.UpdateFunc == nil { + panic("ConfigMapInterfaceMock.UpdateFunc: method is nil but ConfigMapInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ConfigMap + }{ + In1: in1, + } + lockConfigMapInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockConfigMapInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedConfigMapInterface.UpdateCalls()) +func (mock *ConfigMapInterfaceMock) UpdateCalls() []struct { + In1 *v1.ConfigMap +} { + var calls []struct { + In1 *v1.ConfigMap + } + lockConfigMapInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockConfigMapInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ConfigMapInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ConfigMapInterfaceMock.WatchFunc: method is nil but ConfigMapInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockConfigMapInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockConfigMapInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedConfigMapInterface.WatchCalls()) +func (mock *ConfigMapInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockConfigMapInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockConfigMapInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockConfigMapsGetterMockConfigMaps sync.RWMutex +) + +// Ensure, that ConfigMapsGetterMock does implement v11.ConfigMapsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ConfigMapsGetter = &ConfigMapsGetterMock{} + +// ConfigMapsGetterMock is a mock implementation of v11.ConfigMapsGetter. +// +// func TestSomethingThatUsesConfigMapsGetter(t *testing.T) { +// +// // make and configure a mocked v11.ConfigMapsGetter +// mockedConfigMapsGetter := &ConfigMapsGetterMock{ +// ConfigMapsFunc: func(namespace string) v11.ConfigMapInterface { +// panic("mock out the ConfigMaps method") +// }, +// } +// +// // use mockedConfigMapsGetter in code that requires v11.ConfigMapsGetter +// // and then make assertions. +// +// } +type ConfigMapsGetterMock struct { + // ConfigMapsFunc mocks the ConfigMaps method. + ConfigMapsFunc func(namespace string) v11.ConfigMapInterface + + // calls tracks calls to the methods. + calls struct { + // ConfigMaps holds details about calls to the ConfigMaps method. + ConfigMaps []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ConfigMaps calls ConfigMapsFunc. +func (mock *ConfigMapsGetterMock) ConfigMaps(namespace string) v11.ConfigMapInterface { + if mock.ConfigMapsFunc == nil { + panic("ConfigMapsGetterMock.ConfigMapsFunc: method is nil but ConfigMapsGetter.ConfigMaps was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockConfigMapsGetterMockConfigMaps.Lock() + mock.calls.ConfigMaps = append(mock.calls.ConfigMaps, callInfo) + lockConfigMapsGetterMockConfigMaps.Unlock() + return mock.ConfigMapsFunc(namespace) +} + +// ConfigMapsCalls gets all the calls that were made to ConfigMaps. +// Check the length with: +// +// len(mockedConfigMapsGetter.ConfigMapsCalls()) +func (mock *ConfigMapsGetterMock) ConfigMapsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockConfigMapsGetterMockConfigMaps.RLock() + calls = mock.calls.ConfigMaps + lockConfigMapsGetterMockConfigMaps.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_endpoints_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_endpoints_mock.go new file mode 100644 index 0000000..d89b13d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_endpoints_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockEndpointsListerMockGet sync.RWMutex + lockEndpointsListerMockList sync.RWMutex +) + +// Ensure, that EndpointsListerMock does implement v11.EndpointsLister. +// If this is not the case, regenerate this file with moq. +var _ v11.EndpointsLister = &EndpointsListerMock{} + +// EndpointsListerMock is a mock implementation of v11.EndpointsLister. +// +// func TestSomethingThatUsesEndpointsLister(t *testing.T) { +// +// // make and configure a mocked v11.EndpointsLister +// mockedEndpointsLister := &EndpointsListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Endpoints, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Endpoints, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedEndpointsLister in code that requires v11.EndpointsLister +// // and then make assertions. +// +// } +type EndpointsListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Endpoints, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Endpoints, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *EndpointsListerMock) Get(namespace string, name string) (*v1.Endpoints, error) { + if mock.GetFunc == nil { + panic("EndpointsListerMock.GetFunc: method is nil but EndpointsLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEndpointsListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEndpointsListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEndpointsLister.GetCalls()) +func (mock *EndpointsListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEndpointsListerMockGet.RLock() + calls = mock.calls.Get + lockEndpointsListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EndpointsListerMock) List(namespace string, selector labels.Selector) ([]*v1.Endpoints, error) { + if mock.ListFunc == nil { + panic("EndpointsListerMock.ListFunc: method is nil but EndpointsLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockEndpointsListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEndpointsListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEndpointsLister.ListCalls()) +func (mock *EndpointsListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockEndpointsListerMockList.RLock() + calls = mock.calls.List + lockEndpointsListerMockList.RUnlock() + return calls +} + +var ( + lockEndpointsControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockEndpointsControllerMockAddClusterScopedHandler sync.RWMutex + lockEndpointsControllerMockAddFeatureHandler sync.RWMutex + lockEndpointsControllerMockAddHandler sync.RWMutex + lockEndpointsControllerMockEnqueue sync.RWMutex + lockEndpointsControllerMockEnqueueAfter sync.RWMutex + lockEndpointsControllerMockGeneric sync.RWMutex + lockEndpointsControllerMockInformer sync.RWMutex + lockEndpointsControllerMockLister sync.RWMutex +) + +// Ensure, that EndpointsControllerMock does implement v11.EndpointsController. +// If this is not the case, regenerate this file with moq. +var _ v11.EndpointsController = &EndpointsControllerMock{} + +// EndpointsControllerMock is a mock implementation of v11.EndpointsController. +// +// func TestSomethingThatUsesEndpointsController(t *testing.T) { +// +// // make and configure a mocked v11.EndpointsController +// mockedEndpointsController := &EndpointsControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EndpointsHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.EndpointsHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.EndpointsHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.EndpointsLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedEndpointsController in code that requires v11.EndpointsController +// // and then make assertions. +// +// } +type EndpointsControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EndpointsHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.EndpointsHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.EndpointsHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.EndpointsLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.EndpointsHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.EndpointsHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EndpointsHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.EndpointsHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EndpointsControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EndpointsHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EndpointsControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but EndpointsController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEndpointsControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEndpointsControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEndpointsController.AddClusterScopedFeatureHandlerCalls()) +func (mock *EndpointsControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc + } + lockEndpointsControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEndpointsControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EndpointsControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.EndpointsHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EndpointsControllerMock.AddClusterScopedHandlerFunc: method is nil but EndpointsController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEndpointsControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEndpointsControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEndpointsController.AddClusterScopedHandlerCalls()) +func (mock *EndpointsControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EndpointsHandlerFunc + } + lockEndpointsControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEndpointsControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EndpointsControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EndpointsControllerMock.AddFeatureHandlerFunc: method is nil but EndpointsController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEndpointsControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEndpointsControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEndpointsController.AddFeatureHandlerCalls()) +func (mock *EndpointsControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc + } + lockEndpointsControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEndpointsControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EndpointsControllerMock) AddHandler(ctx context.Context, name string, handler v11.EndpointsHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EndpointsControllerMock.AddHandlerFunc: method is nil but EndpointsController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockEndpointsControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEndpointsControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEndpointsController.AddHandlerCalls()) +func (mock *EndpointsControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.EndpointsHandlerFunc + } + lockEndpointsControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEndpointsControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *EndpointsControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("EndpointsControllerMock.EnqueueFunc: method is nil but EndpointsController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEndpointsControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockEndpointsControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedEndpointsController.EnqueueCalls()) +func (mock *EndpointsControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEndpointsControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockEndpointsControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *EndpointsControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("EndpointsControllerMock.EnqueueAfterFunc: method is nil but EndpointsController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockEndpointsControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockEndpointsControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedEndpointsController.EnqueueAfterCalls()) +func (mock *EndpointsControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockEndpointsControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockEndpointsControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *EndpointsControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("EndpointsControllerMock.GenericFunc: method is nil but EndpointsController.Generic was just called") + } + callInfo := struct { + }{} + lockEndpointsControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockEndpointsControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedEndpointsController.GenericCalls()) +func (mock *EndpointsControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockEndpointsControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockEndpointsControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *EndpointsControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("EndpointsControllerMock.InformerFunc: method is nil but EndpointsController.Informer was just called") + } + callInfo := struct { + }{} + lockEndpointsControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockEndpointsControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedEndpointsController.InformerCalls()) +func (mock *EndpointsControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockEndpointsControllerMockInformer.RLock() + calls = mock.calls.Informer + lockEndpointsControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *EndpointsControllerMock) Lister() v11.EndpointsLister { + if mock.ListerFunc == nil { + panic("EndpointsControllerMock.ListerFunc: method is nil but EndpointsController.Lister was just called") + } + callInfo := struct { + }{} + lockEndpointsControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockEndpointsControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedEndpointsController.ListerCalls()) +func (mock *EndpointsControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockEndpointsControllerMockLister.RLock() + calls = mock.calls.Lister + lockEndpointsControllerMockLister.RUnlock() + return calls +} + +var ( + lockEndpointsInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockEndpointsInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockEndpointsInterfaceMockAddClusterScopedHandler sync.RWMutex + lockEndpointsInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockEndpointsInterfaceMockAddFeatureHandler sync.RWMutex + lockEndpointsInterfaceMockAddFeatureLifecycle sync.RWMutex + lockEndpointsInterfaceMockAddHandler sync.RWMutex + lockEndpointsInterfaceMockAddLifecycle sync.RWMutex + lockEndpointsInterfaceMockController sync.RWMutex + lockEndpointsInterfaceMockCreate sync.RWMutex + lockEndpointsInterfaceMockDelete sync.RWMutex + lockEndpointsInterfaceMockDeleteCollection sync.RWMutex + lockEndpointsInterfaceMockDeleteNamespaced sync.RWMutex + lockEndpointsInterfaceMockGet sync.RWMutex + lockEndpointsInterfaceMockGetNamespaced sync.RWMutex + lockEndpointsInterfaceMockList sync.RWMutex + lockEndpointsInterfaceMockListNamespaced sync.RWMutex + lockEndpointsInterfaceMockObjectClient sync.RWMutex + lockEndpointsInterfaceMockUpdate sync.RWMutex + lockEndpointsInterfaceMockWatch sync.RWMutex +) + +// Ensure, that EndpointsInterfaceMock does implement v11.EndpointsInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.EndpointsInterface = &EndpointsInterfaceMock{} + +// EndpointsInterfaceMock is a mock implementation of v11.EndpointsInterface. +// +// func TestSomethingThatUsesEndpointsInterface(t *testing.T) { +// +// // make and configure a mocked v11.EndpointsInterface +// mockedEndpointsInterface := &EndpointsInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EndpointsLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.EndpointsLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.EndpointsLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.EndpointsHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.EndpointsLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.EndpointsController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Endpoints) (*v1.Endpoints, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Endpoints, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Endpoints, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.EndpointsList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.EndpointsList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Endpoints) (*v1.Endpoints, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedEndpointsInterface in code that requires v11.EndpointsInterface +// // and then make assertions. +// +// } +type EndpointsInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EndpointsLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.EndpointsLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.EndpointsLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.EndpointsHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.EndpointsLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.EndpointsController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Endpoints) (*v1.Endpoints, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Endpoints, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Endpoints, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.EndpointsList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.EndpointsList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Endpoints) (*v1.Endpoints, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.EndpointsHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EndpointsLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.EndpointsHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EndpointsLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EndpointsHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EndpointsLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EndpointsHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EndpointsLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Endpoints + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Endpoints + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EndpointsInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EndpointsInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but EndpointsInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEndpointsInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEndpointsInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEndpointsInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *EndpointsInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc + } + lockEndpointsInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEndpointsInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *EndpointsInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EndpointsLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("EndpointsInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but EndpointsInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEndpointsInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockEndpointsInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedEndpointsInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *EndpointsInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle + } + lockEndpointsInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockEndpointsInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EndpointsInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.EndpointsHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EndpointsInterfaceMock.AddClusterScopedHandlerFunc: method is nil but EndpointsInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEndpointsInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEndpointsInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEndpointsInterface.AddClusterScopedHandlerCalls()) +func (mock *EndpointsInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EndpointsHandlerFunc + } + lockEndpointsInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEndpointsInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *EndpointsInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.EndpointsLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("EndpointsInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but EndpointsInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEndpointsInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockEndpointsInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedEndpointsInterface.AddClusterScopedLifecycleCalls()) +func (mock *EndpointsInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EndpointsLifecycle + } + lockEndpointsInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockEndpointsInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EndpointsInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EndpointsHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EndpointsInterfaceMock.AddFeatureHandlerFunc: method is nil but EndpointsInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEndpointsInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEndpointsInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEndpointsInterface.AddFeatureHandlerCalls()) +func (mock *EndpointsInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EndpointsHandlerFunc + } + lockEndpointsInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEndpointsInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *EndpointsInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.EndpointsLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("EndpointsInterfaceMock.AddFeatureLifecycleFunc: method is nil but EndpointsInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EndpointsLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockEndpointsInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockEndpointsInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedEndpointsInterface.AddFeatureLifecycleCalls()) +func (mock *EndpointsInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EndpointsLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EndpointsLifecycle + } + lockEndpointsInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockEndpointsInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EndpointsInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.EndpointsHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EndpointsInterfaceMock.AddHandlerFunc: method is nil but EndpointsInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.EndpointsHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockEndpointsInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEndpointsInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEndpointsInterface.AddHandlerCalls()) +func (mock *EndpointsInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.EndpointsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.EndpointsHandlerFunc + } + lockEndpointsInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEndpointsInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *EndpointsInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.EndpointsLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("EndpointsInterfaceMock.AddLifecycleFunc: method is nil but EndpointsInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.EndpointsLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockEndpointsInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockEndpointsInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedEndpointsInterface.AddLifecycleCalls()) +func (mock *EndpointsInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.EndpointsLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.EndpointsLifecycle + } + lockEndpointsInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockEndpointsInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *EndpointsInterfaceMock) Controller() v11.EndpointsController { + if mock.ControllerFunc == nil { + panic("EndpointsInterfaceMock.ControllerFunc: method is nil but EndpointsInterface.Controller was just called") + } + callInfo := struct { + }{} + lockEndpointsInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockEndpointsInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedEndpointsInterface.ControllerCalls()) +func (mock *EndpointsInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockEndpointsInterfaceMockController.RLock() + calls = mock.calls.Controller + lockEndpointsInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *EndpointsInterfaceMock) Create(in1 *v1.Endpoints) (*v1.Endpoints, error) { + if mock.CreateFunc == nil { + panic("EndpointsInterfaceMock.CreateFunc: method is nil but EndpointsInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Endpoints + }{ + In1: in1, + } + lockEndpointsInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockEndpointsInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedEndpointsInterface.CreateCalls()) +func (mock *EndpointsInterfaceMock) CreateCalls() []struct { + In1 *v1.Endpoints +} { + var calls []struct { + In1 *v1.Endpoints + } + lockEndpointsInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockEndpointsInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *EndpointsInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("EndpointsInterfaceMock.DeleteFunc: method is nil but EndpointsInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockEndpointsInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockEndpointsInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedEndpointsInterface.DeleteCalls()) +func (mock *EndpointsInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockEndpointsInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockEndpointsInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *EndpointsInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("EndpointsInterfaceMock.DeleteCollectionFunc: method is nil but EndpointsInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockEndpointsInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockEndpointsInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedEndpointsInterface.DeleteCollectionCalls()) +func (mock *EndpointsInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockEndpointsInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockEndpointsInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *EndpointsInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("EndpointsInterfaceMock.DeleteNamespacedFunc: method is nil but EndpointsInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockEndpointsInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockEndpointsInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedEndpointsInterface.DeleteNamespacedCalls()) +func (mock *EndpointsInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockEndpointsInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockEndpointsInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *EndpointsInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Endpoints, error) { + if mock.GetFunc == nil { + panic("EndpointsInterfaceMock.GetFunc: method is nil but EndpointsInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockEndpointsInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEndpointsInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEndpointsInterface.GetCalls()) +func (mock *EndpointsInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockEndpointsInterfaceMockGet.RLock() + calls = mock.calls.Get + lockEndpointsInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *EndpointsInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Endpoints, error) { + if mock.GetNamespacedFunc == nil { + panic("EndpointsInterfaceMock.GetNamespacedFunc: method is nil but EndpointsInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockEndpointsInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockEndpointsInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedEndpointsInterface.GetNamespacedCalls()) +func (mock *EndpointsInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockEndpointsInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockEndpointsInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EndpointsInterfaceMock) List(opts metav1.ListOptions) (*v1.EndpointsList, error) { + if mock.ListFunc == nil { + panic("EndpointsInterfaceMock.ListFunc: method is nil but EndpointsInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEndpointsInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEndpointsInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEndpointsInterface.ListCalls()) +func (mock *EndpointsInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEndpointsInterfaceMockList.RLock() + calls = mock.calls.List + lockEndpointsInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *EndpointsInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EndpointsList, error) { + if mock.ListNamespacedFunc == nil { + panic("EndpointsInterfaceMock.ListNamespacedFunc: method is nil but EndpointsInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockEndpointsInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockEndpointsInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedEndpointsInterface.ListNamespacedCalls()) +func (mock *EndpointsInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockEndpointsInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockEndpointsInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *EndpointsInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("EndpointsInterfaceMock.ObjectClientFunc: method is nil but EndpointsInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockEndpointsInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockEndpointsInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedEndpointsInterface.ObjectClientCalls()) +func (mock *EndpointsInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockEndpointsInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockEndpointsInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *EndpointsInterfaceMock) Update(in1 *v1.Endpoints) (*v1.Endpoints, error) { + if mock.UpdateFunc == nil { + panic("EndpointsInterfaceMock.UpdateFunc: method is nil but EndpointsInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Endpoints + }{ + In1: in1, + } + lockEndpointsInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockEndpointsInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedEndpointsInterface.UpdateCalls()) +func (mock *EndpointsInterfaceMock) UpdateCalls() []struct { + In1 *v1.Endpoints +} { + var calls []struct { + In1 *v1.Endpoints + } + lockEndpointsInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockEndpointsInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *EndpointsInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("EndpointsInterfaceMock.WatchFunc: method is nil but EndpointsInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEndpointsInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockEndpointsInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedEndpointsInterface.WatchCalls()) +func (mock *EndpointsInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEndpointsInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockEndpointsInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockEndpointsGetterMockEndpoints sync.RWMutex +) + +// Ensure, that EndpointsGetterMock does implement v11.EndpointsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.EndpointsGetter = &EndpointsGetterMock{} + +// EndpointsGetterMock is a mock implementation of v11.EndpointsGetter. +// +// func TestSomethingThatUsesEndpointsGetter(t *testing.T) { +// +// // make and configure a mocked v11.EndpointsGetter +// mockedEndpointsGetter := &EndpointsGetterMock{ +// EndpointsFunc: func(namespace string) v11.EndpointsInterface { +// panic("mock out the Endpoints method") +// }, +// } +// +// // use mockedEndpointsGetter in code that requires v11.EndpointsGetter +// // and then make assertions. +// +// } +type EndpointsGetterMock struct { + // EndpointsFunc mocks the Endpoints method. + EndpointsFunc func(namespace string) v11.EndpointsInterface + + // calls tracks calls to the methods. + calls struct { + // Endpoints holds details about calls to the Endpoints method. + Endpoints []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Endpoints calls EndpointsFunc. +func (mock *EndpointsGetterMock) Endpoints(namespace string) v11.EndpointsInterface { + if mock.EndpointsFunc == nil { + panic("EndpointsGetterMock.EndpointsFunc: method is nil but EndpointsGetter.Endpoints was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockEndpointsGetterMockEndpoints.Lock() + mock.calls.Endpoints = append(mock.calls.Endpoints, callInfo) + lockEndpointsGetterMockEndpoints.Unlock() + return mock.EndpointsFunc(namespace) +} + +// EndpointsCalls gets all the calls that were made to Endpoints. +// Check the length with: +// +// len(mockedEndpointsGetter.EndpointsCalls()) +func (mock *EndpointsGetterMock) EndpointsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockEndpointsGetterMockEndpoints.RLock() + calls = mock.calls.Endpoints + lockEndpointsGetterMockEndpoints.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_event_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_event_mock.go new file mode 100644 index 0000000..a03abaa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_event_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockEventListerMockGet sync.RWMutex + lockEventListerMockList sync.RWMutex +) + +// Ensure, that EventListerMock does implement v11.EventLister. +// If this is not the case, regenerate this file with moq. +var _ v11.EventLister = &EventListerMock{} + +// EventListerMock is a mock implementation of v11.EventLister. +// +// func TestSomethingThatUsesEventLister(t *testing.T) { +// +// // make and configure a mocked v11.EventLister +// mockedEventLister := &EventListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Event, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Event, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedEventLister in code that requires v11.EventLister +// // and then make assertions. +// +// } +type EventListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Event, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Event, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *EventListerMock) Get(namespace string, name string) (*v1.Event, error) { + if mock.GetFunc == nil { + panic("EventListerMock.GetFunc: method is nil but EventLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEventListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEventListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEventLister.GetCalls()) +func (mock *EventListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEventListerMockGet.RLock() + calls = mock.calls.Get + lockEventListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EventListerMock) List(namespace string, selector labels.Selector) ([]*v1.Event, error) { + if mock.ListFunc == nil { + panic("EventListerMock.ListFunc: method is nil but EventLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockEventListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEventListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEventLister.ListCalls()) +func (mock *EventListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockEventListerMockList.RLock() + calls = mock.calls.List + lockEventListerMockList.RUnlock() + return calls +} + +var ( + lockEventControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockEventControllerMockAddClusterScopedHandler sync.RWMutex + lockEventControllerMockAddFeatureHandler sync.RWMutex + lockEventControllerMockAddHandler sync.RWMutex + lockEventControllerMockEnqueue sync.RWMutex + lockEventControllerMockEnqueueAfter sync.RWMutex + lockEventControllerMockGeneric sync.RWMutex + lockEventControllerMockInformer sync.RWMutex + lockEventControllerMockLister sync.RWMutex +) + +// Ensure, that EventControllerMock does implement v11.EventController. +// If this is not the case, regenerate this file with moq. +var _ v11.EventController = &EventControllerMock{} + +// EventControllerMock is a mock implementation of v11.EventController. +// +// func TestSomethingThatUsesEventController(t *testing.T) { +// +// // make and configure a mocked v11.EventController +// mockedEventController := &EventControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EventHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.EventHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.EventHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.EventLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedEventController in code that requires v11.EventController +// // and then make assertions. +// +// } +type EventControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EventHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.EventHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.EventHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.EventLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.EventHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.EventHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EventHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.EventHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EventControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.EventHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EventControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but EventController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EventHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEventControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEventControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEventController.AddClusterScopedFeatureHandlerCalls()) +func (mock *EventControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.EventHandlerFunc + } + lockEventControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEventControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EventControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.EventHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EventControllerMock.AddClusterScopedHandlerFunc: method is nil but EventController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EventHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEventControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEventControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEventController.AddClusterScopedHandlerCalls()) +func (mock *EventControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.EventHandlerFunc + } + lockEventControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEventControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EventControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EventControllerMock.AddFeatureHandlerFunc: method is nil but EventController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEventControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEventControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEventController.AddFeatureHandlerCalls()) +func (mock *EventControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc + } + lockEventControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEventControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EventControllerMock) AddHandler(ctx context.Context, name string, handler v11.EventHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EventControllerMock.AddHandlerFunc: method is nil but EventController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.EventHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockEventControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEventControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEventController.AddHandlerCalls()) +func (mock *EventControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.EventHandlerFunc + } + lockEventControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEventControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *EventControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("EventControllerMock.EnqueueFunc: method is nil but EventController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEventControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockEventControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedEventController.EnqueueCalls()) +func (mock *EventControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEventControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockEventControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *EventControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("EventControllerMock.EnqueueAfterFunc: method is nil but EventController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockEventControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockEventControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedEventController.EnqueueAfterCalls()) +func (mock *EventControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockEventControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockEventControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *EventControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("EventControllerMock.GenericFunc: method is nil but EventController.Generic was just called") + } + callInfo := struct { + }{} + lockEventControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockEventControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedEventController.GenericCalls()) +func (mock *EventControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockEventControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockEventControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *EventControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("EventControllerMock.InformerFunc: method is nil but EventController.Informer was just called") + } + callInfo := struct { + }{} + lockEventControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockEventControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedEventController.InformerCalls()) +func (mock *EventControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockEventControllerMockInformer.RLock() + calls = mock.calls.Informer + lockEventControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *EventControllerMock) Lister() v11.EventLister { + if mock.ListerFunc == nil { + panic("EventControllerMock.ListerFunc: method is nil but EventController.Lister was just called") + } + callInfo := struct { + }{} + lockEventControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockEventControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedEventController.ListerCalls()) +func (mock *EventControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockEventControllerMockLister.RLock() + calls = mock.calls.Lister + lockEventControllerMockLister.RUnlock() + return calls +} + +var ( + lockEventInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockEventInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockEventInterfaceMockAddClusterScopedHandler sync.RWMutex + lockEventInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockEventInterfaceMockAddFeatureHandler sync.RWMutex + lockEventInterfaceMockAddFeatureLifecycle sync.RWMutex + lockEventInterfaceMockAddHandler sync.RWMutex + lockEventInterfaceMockAddLifecycle sync.RWMutex + lockEventInterfaceMockController sync.RWMutex + lockEventInterfaceMockCreate sync.RWMutex + lockEventInterfaceMockDelete sync.RWMutex + lockEventInterfaceMockDeleteCollection sync.RWMutex + lockEventInterfaceMockDeleteNamespaced sync.RWMutex + lockEventInterfaceMockGet sync.RWMutex + lockEventInterfaceMockGetNamespaced sync.RWMutex + lockEventInterfaceMockList sync.RWMutex + lockEventInterfaceMockListNamespaced sync.RWMutex + lockEventInterfaceMockObjectClient sync.RWMutex + lockEventInterfaceMockUpdate sync.RWMutex + lockEventInterfaceMockWatch sync.RWMutex +) + +// Ensure, that EventInterfaceMock does implement v11.EventInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.EventInterface = &EventInterfaceMock{} + +// EventInterfaceMock is a mock implementation of v11.EventInterface. +// +// func TestSomethingThatUsesEventInterface(t *testing.T) { +// +// // make and configure a mocked v11.EventInterface +// mockedEventInterface := &EventInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EventLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.EventLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.EventLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.EventHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.EventLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.EventController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Event) (*v1.Event, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Event, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Event, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.EventList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.EventList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Event) (*v1.Event, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedEventInterface in code that requires v11.EventInterface +// // and then make assertions. +// +// } +type EventInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EventLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.EventLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.EventLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.EventHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.EventLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.EventController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Event) (*v1.Event, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Event, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Event, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.EventList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.EventList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Event) (*v1.Event, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.EventHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EventLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.EventHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EventLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EventHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EventLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.EventHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.EventLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Event + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Event + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EventInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EventInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but EventInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EventHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEventInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEventInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEventInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *EventInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.EventHandlerFunc + } + lockEventInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEventInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *EventInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.EventLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("EventInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but EventInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EventLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEventInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockEventInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedEventInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *EventInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EventLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.EventLifecycle + } + lockEventInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockEventInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EventInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.EventHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EventInterfaceMock.AddClusterScopedHandlerFunc: method is nil but EventInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EventHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEventInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEventInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEventInterface.AddClusterScopedHandlerCalls()) +func (mock *EventInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.EventHandlerFunc + } + lockEventInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEventInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *EventInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.EventLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("EventInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but EventInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EventLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEventInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockEventInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedEventInterface.AddClusterScopedLifecycleCalls()) +func (mock *EventInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EventLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.EventLifecycle + } + lockEventInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockEventInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EventInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.EventHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EventInterfaceMock.AddFeatureHandlerFunc: method is nil but EventInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEventInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEventInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEventInterface.AddFeatureHandlerCalls()) +func (mock *EventInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.EventHandlerFunc + } + lockEventInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEventInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *EventInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.EventLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("EventInterfaceMock.AddFeatureLifecycleFunc: method is nil but EventInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EventLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockEventInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockEventInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedEventInterface.AddFeatureLifecycleCalls()) +func (mock *EventInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EventLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.EventLifecycle + } + lockEventInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockEventInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EventInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.EventHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EventInterfaceMock.AddHandlerFunc: method is nil but EventInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.EventHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockEventInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEventInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEventInterface.AddHandlerCalls()) +func (mock *EventInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.EventHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.EventHandlerFunc + } + lockEventInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEventInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *EventInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.EventLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("EventInterfaceMock.AddLifecycleFunc: method is nil but EventInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.EventLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockEventInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockEventInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedEventInterface.AddLifecycleCalls()) +func (mock *EventInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.EventLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.EventLifecycle + } + lockEventInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockEventInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *EventInterfaceMock) Controller() v11.EventController { + if mock.ControllerFunc == nil { + panic("EventInterfaceMock.ControllerFunc: method is nil but EventInterface.Controller was just called") + } + callInfo := struct { + }{} + lockEventInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockEventInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedEventInterface.ControllerCalls()) +func (mock *EventInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockEventInterfaceMockController.RLock() + calls = mock.calls.Controller + lockEventInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *EventInterfaceMock) Create(in1 *v1.Event) (*v1.Event, error) { + if mock.CreateFunc == nil { + panic("EventInterfaceMock.CreateFunc: method is nil but EventInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Event + }{ + In1: in1, + } + lockEventInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockEventInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedEventInterface.CreateCalls()) +func (mock *EventInterfaceMock) CreateCalls() []struct { + In1 *v1.Event +} { + var calls []struct { + In1 *v1.Event + } + lockEventInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockEventInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *EventInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("EventInterfaceMock.DeleteFunc: method is nil but EventInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockEventInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockEventInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedEventInterface.DeleteCalls()) +func (mock *EventInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockEventInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockEventInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *EventInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("EventInterfaceMock.DeleteCollectionFunc: method is nil but EventInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockEventInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockEventInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedEventInterface.DeleteCollectionCalls()) +func (mock *EventInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockEventInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockEventInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *EventInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("EventInterfaceMock.DeleteNamespacedFunc: method is nil but EventInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockEventInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockEventInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedEventInterface.DeleteNamespacedCalls()) +func (mock *EventInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockEventInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockEventInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *EventInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Event, error) { + if mock.GetFunc == nil { + panic("EventInterfaceMock.GetFunc: method is nil but EventInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockEventInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEventInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEventInterface.GetCalls()) +func (mock *EventInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockEventInterfaceMockGet.RLock() + calls = mock.calls.Get + lockEventInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *EventInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Event, error) { + if mock.GetNamespacedFunc == nil { + panic("EventInterfaceMock.GetNamespacedFunc: method is nil but EventInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockEventInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockEventInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedEventInterface.GetNamespacedCalls()) +func (mock *EventInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockEventInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockEventInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EventInterfaceMock) List(opts metav1.ListOptions) (*v1.EventList, error) { + if mock.ListFunc == nil { + panic("EventInterfaceMock.ListFunc: method is nil but EventInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEventInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEventInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEventInterface.ListCalls()) +func (mock *EventInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEventInterfaceMockList.RLock() + calls = mock.calls.List + lockEventInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *EventInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EventList, error) { + if mock.ListNamespacedFunc == nil { + panic("EventInterfaceMock.ListNamespacedFunc: method is nil but EventInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockEventInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockEventInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedEventInterface.ListNamespacedCalls()) +func (mock *EventInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockEventInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockEventInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *EventInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("EventInterfaceMock.ObjectClientFunc: method is nil but EventInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockEventInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockEventInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedEventInterface.ObjectClientCalls()) +func (mock *EventInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockEventInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockEventInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *EventInterfaceMock) Update(in1 *v1.Event) (*v1.Event, error) { + if mock.UpdateFunc == nil { + panic("EventInterfaceMock.UpdateFunc: method is nil but EventInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Event + }{ + In1: in1, + } + lockEventInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockEventInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedEventInterface.UpdateCalls()) +func (mock *EventInterfaceMock) UpdateCalls() []struct { + In1 *v1.Event +} { + var calls []struct { + In1 *v1.Event + } + lockEventInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockEventInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *EventInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("EventInterfaceMock.WatchFunc: method is nil but EventInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEventInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockEventInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedEventInterface.WatchCalls()) +func (mock *EventInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEventInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockEventInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockEventsGetterMockEvents sync.RWMutex +) + +// Ensure, that EventsGetterMock does implement v11.EventsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.EventsGetter = &EventsGetterMock{} + +// EventsGetterMock is a mock implementation of v11.EventsGetter. +// +// func TestSomethingThatUsesEventsGetter(t *testing.T) { +// +// // make and configure a mocked v11.EventsGetter +// mockedEventsGetter := &EventsGetterMock{ +// EventsFunc: func(namespace string) v11.EventInterface { +// panic("mock out the Events method") +// }, +// } +// +// // use mockedEventsGetter in code that requires v11.EventsGetter +// // and then make assertions. +// +// } +type EventsGetterMock struct { + // EventsFunc mocks the Events method. + EventsFunc func(namespace string) v11.EventInterface + + // calls tracks calls to the methods. + calls struct { + // Events holds details about calls to the Events method. + Events []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Events calls EventsFunc. +func (mock *EventsGetterMock) Events(namespace string) v11.EventInterface { + if mock.EventsFunc == nil { + panic("EventsGetterMock.EventsFunc: method is nil but EventsGetter.Events was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockEventsGetterMockEvents.Lock() + mock.calls.Events = append(mock.calls.Events, callInfo) + lockEventsGetterMockEvents.Unlock() + return mock.EventsFunc(namespace) +} + +// EventsCalls gets all the calls that were made to Events. +// Check the length with: +// +// len(mockedEventsGetter.EventsCalls()) +func (mock *EventsGetterMock) EventsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockEventsGetterMockEvents.RLock() + calls = mock.calls.Events + lockEventsGetterMockEvents.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_limit_range_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_limit_range_mock.go new file mode 100644 index 0000000..61eb492 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_limit_range_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockLimitRangeListerMockGet sync.RWMutex + lockLimitRangeListerMockList sync.RWMutex +) + +// Ensure, that LimitRangeListerMock does implement v11.LimitRangeLister. +// If this is not the case, regenerate this file with moq. +var _ v11.LimitRangeLister = &LimitRangeListerMock{} + +// LimitRangeListerMock is a mock implementation of v11.LimitRangeLister. +// +// func TestSomethingThatUsesLimitRangeLister(t *testing.T) { +// +// // make and configure a mocked v11.LimitRangeLister +// mockedLimitRangeLister := &LimitRangeListerMock{ +// GetFunc: func(namespace string, name string) (*v1.LimitRange, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.LimitRange, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedLimitRangeLister in code that requires v11.LimitRangeLister +// // and then make assertions. +// +// } +type LimitRangeListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.LimitRange, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.LimitRange, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *LimitRangeListerMock) Get(namespace string, name string) (*v1.LimitRange, error) { + if mock.GetFunc == nil { + panic("LimitRangeListerMock.GetFunc: method is nil but LimitRangeLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockLimitRangeListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockLimitRangeListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedLimitRangeLister.GetCalls()) +func (mock *LimitRangeListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockLimitRangeListerMockGet.RLock() + calls = mock.calls.Get + lockLimitRangeListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *LimitRangeListerMock) List(namespace string, selector labels.Selector) ([]*v1.LimitRange, error) { + if mock.ListFunc == nil { + panic("LimitRangeListerMock.ListFunc: method is nil but LimitRangeLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockLimitRangeListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockLimitRangeListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedLimitRangeLister.ListCalls()) +func (mock *LimitRangeListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockLimitRangeListerMockList.RLock() + calls = mock.calls.List + lockLimitRangeListerMockList.RUnlock() + return calls +} + +var ( + lockLimitRangeControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockLimitRangeControllerMockAddClusterScopedHandler sync.RWMutex + lockLimitRangeControllerMockAddFeatureHandler sync.RWMutex + lockLimitRangeControllerMockAddHandler sync.RWMutex + lockLimitRangeControllerMockEnqueue sync.RWMutex + lockLimitRangeControllerMockEnqueueAfter sync.RWMutex + lockLimitRangeControllerMockGeneric sync.RWMutex + lockLimitRangeControllerMockInformer sync.RWMutex + lockLimitRangeControllerMockLister sync.RWMutex +) + +// Ensure, that LimitRangeControllerMock does implement v11.LimitRangeController. +// If this is not the case, regenerate this file with moq. +var _ v11.LimitRangeController = &LimitRangeControllerMock{} + +// LimitRangeControllerMock is a mock implementation of v11.LimitRangeController. +// +// func TestSomethingThatUsesLimitRangeController(t *testing.T) { +// +// // make and configure a mocked v11.LimitRangeController +// mockedLimitRangeController := &LimitRangeControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.LimitRangeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.LimitRangeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.LimitRangeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.LimitRangeLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedLimitRangeController in code that requires v11.LimitRangeController +// // and then make assertions. +// +// } +type LimitRangeControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.LimitRangeHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.LimitRangeHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.LimitRangeHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.LimitRangeLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.LimitRangeHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.LimitRangeHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.LimitRangeHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.LimitRangeHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *LimitRangeControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.LimitRangeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("LimitRangeControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but LimitRangeController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockLimitRangeControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockLimitRangeControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedLimitRangeController.AddClusterScopedFeatureHandlerCalls()) +func (mock *LimitRangeControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc + } + lockLimitRangeControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockLimitRangeControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *LimitRangeControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.LimitRangeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("LimitRangeControllerMock.AddClusterScopedHandlerFunc: method is nil but LimitRangeController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockLimitRangeControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockLimitRangeControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedLimitRangeController.AddClusterScopedHandlerCalls()) +func (mock *LimitRangeControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.LimitRangeHandlerFunc + } + lockLimitRangeControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockLimitRangeControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *LimitRangeControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("LimitRangeControllerMock.AddFeatureHandlerFunc: method is nil but LimitRangeController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockLimitRangeControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockLimitRangeControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedLimitRangeController.AddFeatureHandlerCalls()) +func (mock *LimitRangeControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc + } + lockLimitRangeControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockLimitRangeControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *LimitRangeControllerMock) AddHandler(ctx context.Context, name string, handler v11.LimitRangeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("LimitRangeControllerMock.AddHandlerFunc: method is nil but LimitRangeController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockLimitRangeControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockLimitRangeControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedLimitRangeController.AddHandlerCalls()) +func (mock *LimitRangeControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.LimitRangeHandlerFunc + } + lockLimitRangeControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockLimitRangeControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *LimitRangeControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("LimitRangeControllerMock.EnqueueFunc: method is nil but LimitRangeController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockLimitRangeControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockLimitRangeControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedLimitRangeController.EnqueueCalls()) +func (mock *LimitRangeControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockLimitRangeControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockLimitRangeControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *LimitRangeControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("LimitRangeControllerMock.EnqueueAfterFunc: method is nil but LimitRangeController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockLimitRangeControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockLimitRangeControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedLimitRangeController.EnqueueAfterCalls()) +func (mock *LimitRangeControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockLimitRangeControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockLimitRangeControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *LimitRangeControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("LimitRangeControllerMock.GenericFunc: method is nil but LimitRangeController.Generic was just called") + } + callInfo := struct { + }{} + lockLimitRangeControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockLimitRangeControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedLimitRangeController.GenericCalls()) +func (mock *LimitRangeControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockLimitRangeControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockLimitRangeControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *LimitRangeControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("LimitRangeControllerMock.InformerFunc: method is nil but LimitRangeController.Informer was just called") + } + callInfo := struct { + }{} + lockLimitRangeControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockLimitRangeControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedLimitRangeController.InformerCalls()) +func (mock *LimitRangeControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockLimitRangeControllerMockInformer.RLock() + calls = mock.calls.Informer + lockLimitRangeControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *LimitRangeControllerMock) Lister() v11.LimitRangeLister { + if mock.ListerFunc == nil { + panic("LimitRangeControllerMock.ListerFunc: method is nil but LimitRangeController.Lister was just called") + } + callInfo := struct { + }{} + lockLimitRangeControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockLimitRangeControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedLimitRangeController.ListerCalls()) +func (mock *LimitRangeControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockLimitRangeControllerMockLister.RLock() + calls = mock.calls.Lister + lockLimitRangeControllerMockLister.RUnlock() + return calls +} + +var ( + lockLimitRangeInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockLimitRangeInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockLimitRangeInterfaceMockAddClusterScopedHandler sync.RWMutex + lockLimitRangeInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockLimitRangeInterfaceMockAddFeatureHandler sync.RWMutex + lockLimitRangeInterfaceMockAddFeatureLifecycle sync.RWMutex + lockLimitRangeInterfaceMockAddHandler sync.RWMutex + lockLimitRangeInterfaceMockAddLifecycle sync.RWMutex + lockLimitRangeInterfaceMockController sync.RWMutex + lockLimitRangeInterfaceMockCreate sync.RWMutex + lockLimitRangeInterfaceMockDelete sync.RWMutex + lockLimitRangeInterfaceMockDeleteCollection sync.RWMutex + lockLimitRangeInterfaceMockDeleteNamespaced sync.RWMutex + lockLimitRangeInterfaceMockGet sync.RWMutex + lockLimitRangeInterfaceMockGetNamespaced sync.RWMutex + lockLimitRangeInterfaceMockList sync.RWMutex + lockLimitRangeInterfaceMockListNamespaced sync.RWMutex + lockLimitRangeInterfaceMockObjectClient sync.RWMutex + lockLimitRangeInterfaceMockUpdate sync.RWMutex + lockLimitRangeInterfaceMockWatch sync.RWMutex +) + +// Ensure, that LimitRangeInterfaceMock does implement v11.LimitRangeInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.LimitRangeInterface = &LimitRangeInterfaceMock{} + +// LimitRangeInterfaceMock is a mock implementation of v11.LimitRangeInterface. +// +// func TestSomethingThatUsesLimitRangeInterface(t *testing.T) { +// +// // make and configure a mocked v11.LimitRangeInterface +// mockedLimitRangeInterface := &LimitRangeInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.LimitRangeLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.LimitRangeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.LimitRangeLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.LimitRangeController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.LimitRange) (*v1.LimitRange, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.LimitRange, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.LimitRange, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.LimitRangeList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.LimitRangeList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.LimitRange) (*v1.LimitRange, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedLimitRangeInterface in code that requires v11.LimitRangeInterface +// // and then make assertions. +// +// } +type LimitRangeInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.LimitRangeLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.LimitRangeHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.LimitRangeLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.LimitRangeController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.LimitRange) (*v1.LimitRange, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.LimitRange, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.LimitRange, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.LimitRangeList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.LimitRangeList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.LimitRange) (*v1.LimitRange, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.LimitRangeHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.LimitRangeLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.LimitRangeHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.LimitRangeLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.LimitRangeHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.LimitRangeLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.LimitRangeHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.LimitRangeLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.LimitRange + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.LimitRange + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *LimitRangeInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("LimitRangeInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but LimitRangeInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockLimitRangeInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockLimitRangeInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *LimitRangeInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc + } + lockLimitRangeInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockLimitRangeInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *LimitRangeInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("LimitRangeInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but LimitRangeInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockLimitRangeInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockLimitRangeInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *LimitRangeInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle + } + lockLimitRangeInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockLimitRangeInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *LimitRangeInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.LimitRangeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("LimitRangeInterfaceMock.AddClusterScopedHandlerFunc: method is nil but LimitRangeInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockLimitRangeInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockLimitRangeInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddClusterScopedHandlerCalls()) +func (mock *LimitRangeInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.LimitRangeHandlerFunc + } + lockLimitRangeInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockLimitRangeInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *LimitRangeInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.LimitRangeLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("LimitRangeInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but LimitRangeInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockLimitRangeInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockLimitRangeInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddClusterScopedLifecycleCalls()) +func (mock *LimitRangeInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.LimitRangeLifecycle + } + lockLimitRangeInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockLimitRangeInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *LimitRangeInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.LimitRangeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("LimitRangeInterfaceMock.AddFeatureHandlerFunc: method is nil but LimitRangeInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockLimitRangeInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockLimitRangeInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddFeatureHandlerCalls()) +func (mock *LimitRangeInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.LimitRangeHandlerFunc + } + lockLimitRangeInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockLimitRangeInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *LimitRangeInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.LimitRangeLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("LimitRangeInterfaceMock.AddFeatureLifecycleFunc: method is nil but LimitRangeInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.LimitRangeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockLimitRangeInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockLimitRangeInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddFeatureLifecycleCalls()) +func (mock *LimitRangeInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.LimitRangeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.LimitRangeLifecycle + } + lockLimitRangeInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockLimitRangeInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *LimitRangeInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.LimitRangeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("LimitRangeInterfaceMock.AddHandlerFunc: method is nil but LimitRangeInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.LimitRangeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockLimitRangeInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockLimitRangeInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddHandlerCalls()) +func (mock *LimitRangeInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.LimitRangeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.LimitRangeHandlerFunc + } + lockLimitRangeInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockLimitRangeInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *LimitRangeInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.LimitRangeLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("LimitRangeInterfaceMock.AddLifecycleFunc: method is nil but LimitRangeInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.LimitRangeLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockLimitRangeInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockLimitRangeInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedLimitRangeInterface.AddLifecycleCalls()) +func (mock *LimitRangeInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.LimitRangeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.LimitRangeLifecycle + } + lockLimitRangeInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockLimitRangeInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *LimitRangeInterfaceMock) Controller() v11.LimitRangeController { + if mock.ControllerFunc == nil { + panic("LimitRangeInterfaceMock.ControllerFunc: method is nil but LimitRangeInterface.Controller was just called") + } + callInfo := struct { + }{} + lockLimitRangeInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockLimitRangeInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedLimitRangeInterface.ControllerCalls()) +func (mock *LimitRangeInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockLimitRangeInterfaceMockController.RLock() + calls = mock.calls.Controller + lockLimitRangeInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *LimitRangeInterfaceMock) Create(in1 *v1.LimitRange) (*v1.LimitRange, error) { + if mock.CreateFunc == nil { + panic("LimitRangeInterfaceMock.CreateFunc: method is nil but LimitRangeInterface.Create was just called") + } + callInfo := struct { + In1 *v1.LimitRange + }{ + In1: in1, + } + lockLimitRangeInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockLimitRangeInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedLimitRangeInterface.CreateCalls()) +func (mock *LimitRangeInterfaceMock) CreateCalls() []struct { + In1 *v1.LimitRange +} { + var calls []struct { + In1 *v1.LimitRange + } + lockLimitRangeInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockLimitRangeInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *LimitRangeInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("LimitRangeInterfaceMock.DeleteFunc: method is nil but LimitRangeInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockLimitRangeInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockLimitRangeInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedLimitRangeInterface.DeleteCalls()) +func (mock *LimitRangeInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockLimitRangeInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockLimitRangeInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *LimitRangeInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("LimitRangeInterfaceMock.DeleteCollectionFunc: method is nil but LimitRangeInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockLimitRangeInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockLimitRangeInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedLimitRangeInterface.DeleteCollectionCalls()) +func (mock *LimitRangeInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockLimitRangeInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockLimitRangeInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *LimitRangeInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("LimitRangeInterfaceMock.DeleteNamespacedFunc: method is nil but LimitRangeInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockLimitRangeInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockLimitRangeInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedLimitRangeInterface.DeleteNamespacedCalls()) +func (mock *LimitRangeInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockLimitRangeInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockLimitRangeInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *LimitRangeInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.LimitRange, error) { + if mock.GetFunc == nil { + panic("LimitRangeInterfaceMock.GetFunc: method is nil but LimitRangeInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockLimitRangeInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockLimitRangeInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedLimitRangeInterface.GetCalls()) +func (mock *LimitRangeInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockLimitRangeInterfaceMockGet.RLock() + calls = mock.calls.Get + lockLimitRangeInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *LimitRangeInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.LimitRange, error) { + if mock.GetNamespacedFunc == nil { + panic("LimitRangeInterfaceMock.GetNamespacedFunc: method is nil but LimitRangeInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockLimitRangeInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockLimitRangeInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedLimitRangeInterface.GetNamespacedCalls()) +func (mock *LimitRangeInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockLimitRangeInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockLimitRangeInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *LimitRangeInterfaceMock) List(opts metav1.ListOptions) (*v1.LimitRangeList, error) { + if mock.ListFunc == nil { + panic("LimitRangeInterfaceMock.ListFunc: method is nil but LimitRangeInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockLimitRangeInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockLimitRangeInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedLimitRangeInterface.ListCalls()) +func (mock *LimitRangeInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockLimitRangeInterfaceMockList.RLock() + calls = mock.calls.List + lockLimitRangeInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *LimitRangeInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.LimitRangeList, error) { + if mock.ListNamespacedFunc == nil { + panic("LimitRangeInterfaceMock.ListNamespacedFunc: method is nil but LimitRangeInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockLimitRangeInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockLimitRangeInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedLimitRangeInterface.ListNamespacedCalls()) +func (mock *LimitRangeInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockLimitRangeInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockLimitRangeInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *LimitRangeInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("LimitRangeInterfaceMock.ObjectClientFunc: method is nil but LimitRangeInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockLimitRangeInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockLimitRangeInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedLimitRangeInterface.ObjectClientCalls()) +func (mock *LimitRangeInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockLimitRangeInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockLimitRangeInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *LimitRangeInterfaceMock) Update(in1 *v1.LimitRange) (*v1.LimitRange, error) { + if mock.UpdateFunc == nil { + panic("LimitRangeInterfaceMock.UpdateFunc: method is nil but LimitRangeInterface.Update was just called") + } + callInfo := struct { + In1 *v1.LimitRange + }{ + In1: in1, + } + lockLimitRangeInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockLimitRangeInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedLimitRangeInterface.UpdateCalls()) +func (mock *LimitRangeInterfaceMock) UpdateCalls() []struct { + In1 *v1.LimitRange +} { + var calls []struct { + In1 *v1.LimitRange + } + lockLimitRangeInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockLimitRangeInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *LimitRangeInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("LimitRangeInterfaceMock.WatchFunc: method is nil but LimitRangeInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockLimitRangeInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockLimitRangeInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedLimitRangeInterface.WatchCalls()) +func (mock *LimitRangeInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockLimitRangeInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockLimitRangeInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockLimitRangesGetterMockLimitRanges sync.RWMutex +) + +// Ensure, that LimitRangesGetterMock does implement v11.LimitRangesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.LimitRangesGetter = &LimitRangesGetterMock{} + +// LimitRangesGetterMock is a mock implementation of v11.LimitRangesGetter. +// +// func TestSomethingThatUsesLimitRangesGetter(t *testing.T) { +// +// // make and configure a mocked v11.LimitRangesGetter +// mockedLimitRangesGetter := &LimitRangesGetterMock{ +// LimitRangesFunc: func(namespace string) v11.LimitRangeInterface { +// panic("mock out the LimitRanges method") +// }, +// } +// +// // use mockedLimitRangesGetter in code that requires v11.LimitRangesGetter +// // and then make assertions. +// +// } +type LimitRangesGetterMock struct { + // LimitRangesFunc mocks the LimitRanges method. + LimitRangesFunc func(namespace string) v11.LimitRangeInterface + + // calls tracks calls to the methods. + calls struct { + // LimitRanges holds details about calls to the LimitRanges method. + LimitRanges []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// LimitRanges calls LimitRangesFunc. +func (mock *LimitRangesGetterMock) LimitRanges(namespace string) v11.LimitRangeInterface { + if mock.LimitRangesFunc == nil { + panic("LimitRangesGetterMock.LimitRangesFunc: method is nil but LimitRangesGetter.LimitRanges was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockLimitRangesGetterMockLimitRanges.Lock() + mock.calls.LimitRanges = append(mock.calls.LimitRanges, callInfo) + lockLimitRangesGetterMockLimitRanges.Unlock() + return mock.LimitRangesFunc(namespace) +} + +// LimitRangesCalls gets all the calls that were made to LimitRanges. +// Check the length with: +// +// len(mockedLimitRangesGetter.LimitRangesCalls()) +func (mock *LimitRangesGetterMock) LimitRangesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockLimitRangesGetterMockLimitRanges.RLock() + calls = mock.calls.LimitRanges + lockLimitRangesGetterMockLimitRanges.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_namespace_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_namespace_mock.go new file mode 100644 index 0000000..5e6aff0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_namespace_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespaceListerMockGet sync.RWMutex + lockNamespaceListerMockList sync.RWMutex +) + +// Ensure, that NamespaceListerMock does implement v11.NamespaceLister. +// If this is not the case, regenerate this file with moq. +var _ v11.NamespaceLister = &NamespaceListerMock{} + +// NamespaceListerMock is a mock implementation of v11.NamespaceLister. +// +// func TestSomethingThatUsesNamespaceLister(t *testing.T) { +// +// // make and configure a mocked v11.NamespaceLister +// mockedNamespaceLister := &NamespaceListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Namespace, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Namespace, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespaceLister in code that requires v11.NamespaceLister +// // and then make assertions. +// +// } +type NamespaceListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Namespace, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Namespace, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespaceListerMock) Get(namespace string, name string) (*v1.Namespace, error) { + if mock.GetFunc == nil { + panic("NamespaceListerMock.GetFunc: method is nil but NamespaceLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespaceListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespaceListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespaceLister.GetCalls()) +func (mock *NamespaceListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespaceListerMockGet.RLock() + calls = mock.calls.Get + lockNamespaceListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespaceListerMock) List(namespace string, selector labels.Selector) ([]*v1.Namespace, error) { + if mock.ListFunc == nil { + panic("NamespaceListerMock.ListFunc: method is nil but NamespaceLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespaceListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespaceListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespaceLister.ListCalls()) +func (mock *NamespaceListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespaceListerMockList.RLock() + calls = mock.calls.List + lockNamespaceListerMockList.RUnlock() + return calls +} + +var ( + lockNamespaceControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespaceControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespaceControllerMockAddFeatureHandler sync.RWMutex + lockNamespaceControllerMockAddHandler sync.RWMutex + lockNamespaceControllerMockEnqueue sync.RWMutex + lockNamespaceControllerMockEnqueueAfter sync.RWMutex + lockNamespaceControllerMockGeneric sync.RWMutex + lockNamespaceControllerMockInformer sync.RWMutex + lockNamespaceControllerMockLister sync.RWMutex +) + +// Ensure, that NamespaceControllerMock does implement v11.NamespaceController. +// If this is not the case, regenerate this file with moq. +var _ v11.NamespaceController = &NamespaceControllerMock{} + +// NamespaceControllerMock is a mock implementation of v11.NamespaceController. +// +// func TestSomethingThatUsesNamespaceController(t *testing.T) { +// +// // make and configure a mocked v11.NamespaceController +// mockedNamespaceController := &NamespaceControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NamespaceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.NamespaceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.NamespaceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.NamespaceLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespaceController in code that requires v11.NamespaceController +// // and then make assertions. +// +// } +type NamespaceControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NamespaceHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.NamespaceHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.NamespaceHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.NamespaceLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NamespaceHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NamespaceHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NamespaceHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.NamespaceHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespaceControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NamespaceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespaceControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespaceController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespaceControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespaceControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespaceController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespaceControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc + } + lockNamespaceControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespaceControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespaceControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.NamespaceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespaceControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespaceController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespaceControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespaceControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespaceController.AddClusterScopedHandlerCalls()) +func (mock *NamespaceControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NamespaceHandlerFunc + } + lockNamespaceControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespaceControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespaceControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespaceControllerMock.AddFeatureHandlerFunc: method is nil but NamespaceController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespaceControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespaceControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespaceController.AddFeatureHandlerCalls()) +func (mock *NamespaceControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc + } + lockNamespaceControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespaceControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespaceControllerMock) AddHandler(ctx context.Context, name string, handler v11.NamespaceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespaceControllerMock.AddHandlerFunc: method is nil but NamespaceController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespaceControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespaceControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespaceController.AddHandlerCalls()) +func (mock *NamespaceControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.NamespaceHandlerFunc + } + lockNamespaceControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespaceControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespaceControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespaceControllerMock.EnqueueFunc: method is nil but NamespaceController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespaceControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespaceControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespaceController.EnqueueCalls()) +func (mock *NamespaceControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespaceControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespaceControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespaceControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespaceControllerMock.EnqueueAfterFunc: method is nil but NamespaceController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespaceControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespaceControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespaceController.EnqueueAfterCalls()) +func (mock *NamespaceControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespaceControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespaceControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespaceControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespaceControllerMock.GenericFunc: method is nil but NamespaceController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespaceControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespaceControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespaceController.GenericCalls()) +func (mock *NamespaceControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespaceControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespaceControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespaceControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespaceControllerMock.InformerFunc: method is nil but NamespaceController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespaceControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespaceControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespaceController.InformerCalls()) +func (mock *NamespaceControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespaceControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespaceControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespaceControllerMock) Lister() v11.NamespaceLister { + if mock.ListerFunc == nil { + panic("NamespaceControllerMock.ListerFunc: method is nil but NamespaceController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespaceControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespaceControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespaceController.ListerCalls()) +func (mock *NamespaceControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespaceControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespaceControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespaceInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespaceInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespaceInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespaceInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespaceInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespaceInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespaceInterfaceMockAddHandler sync.RWMutex + lockNamespaceInterfaceMockAddLifecycle sync.RWMutex + lockNamespaceInterfaceMockController sync.RWMutex + lockNamespaceInterfaceMockCreate sync.RWMutex + lockNamespaceInterfaceMockDelete sync.RWMutex + lockNamespaceInterfaceMockDeleteCollection sync.RWMutex + lockNamespaceInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespaceInterfaceMockGet sync.RWMutex + lockNamespaceInterfaceMockGetNamespaced sync.RWMutex + lockNamespaceInterfaceMockList sync.RWMutex + lockNamespaceInterfaceMockListNamespaced sync.RWMutex + lockNamespaceInterfaceMockObjectClient sync.RWMutex + lockNamespaceInterfaceMockUpdate sync.RWMutex + lockNamespaceInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespaceInterfaceMock does implement v11.NamespaceInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.NamespaceInterface = &NamespaceInterfaceMock{} + +// NamespaceInterfaceMock is a mock implementation of v11.NamespaceInterface. +// +// func TestSomethingThatUsesNamespaceInterface(t *testing.T) { +// +// // make and configure a mocked v11.NamespaceInterface +// mockedNamespaceInterface := &NamespaceInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NamespaceLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.NamespaceLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NamespaceLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.NamespaceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.NamespaceLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.NamespaceController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Namespace) (*v1.Namespace, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Namespace, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Namespace, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.NamespaceList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.NamespaceList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Namespace) (*v1.Namespace, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespaceInterface in code that requires v11.NamespaceInterface +// // and then make assertions. +// +// } +type NamespaceInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NamespaceLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.NamespaceLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NamespaceLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.NamespaceHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.NamespaceLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.NamespaceController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Namespace) (*v1.Namespace, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Namespace, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Namespace, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.NamespaceList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.NamespaceList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Namespace) (*v1.Namespace, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NamespaceHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NamespaceLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NamespaceHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NamespaceLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NamespaceHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NamespaceLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NamespaceHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NamespaceLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Namespace + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Namespace + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespaceInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespaceInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespaceInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespaceInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespaceInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespaceInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespaceInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc + } + lockNamespaceInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespaceInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespaceInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NamespaceLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespaceInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespaceInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespaceInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespaceInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespaceInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespaceInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle + } + lockNamespaceInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespaceInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespaceInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.NamespaceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespaceInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespaceInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespaceInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespaceInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespaceInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespaceInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NamespaceHandlerFunc + } + lockNamespaceInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespaceInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespaceInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.NamespaceLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespaceInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespaceInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespaceInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespaceInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespaceInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespaceInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NamespaceLifecycle + } + lockNamespaceInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespaceInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespaceInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NamespaceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespaceInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespaceInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespaceInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespaceInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespaceInterface.AddFeatureHandlerCalls()) +func (mock *NamespaceInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NamespaceHandlerFunc + } + lockNamespaceInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespaceInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespaceInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.NamespaceLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespaceInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespaceInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NamespaceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespaceInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespaceInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespaceInterface.AddFeatureLifecycleCalls()) +func (mock *NamespaceInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NamespaceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NamespaceLifecycle + } + lockNamespaceInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespaceInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespaceInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.NamespaceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespaceInterfaceMock.AddHandlerFunc: method is nil but NamespaceInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.NamespaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespaceInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespaceInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespaceInterface.AddHandlerCalls()) +func (mock *NamespaceInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.NamespaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.NamespaceHandlerFunc + } + lockNamespaceInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespaceInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespaceInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.NamespaceLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespaceInterfaceMock.AddLifecycleFunc: method is nil but NamespaceInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.NamespaceLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespaceInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespaceInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespaceInterface.AddLifecycleCalls()) +func (mock *NamespaceInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.NamespaceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.NamespaceLifecycle + } + lockNamespaceInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespaceInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespaceInterfaceMock) Controller() v11.NamespaceController { + if mock.ControllerFunc == nil { + panic("NamespaceInterfaceMock.ControllerFunc: method is nil but NamespaceInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespaceInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespaceInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespaceInterface.ControllerCalls()) +func (mock *NamespaceInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespaceInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespaceInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespaceInterfaceMock) Create(in1 *v1.Namespace) (*v1.Namespace, error) { + if mock.CreateFunc == nil { + panic("NamespaceInterfaceMock.CreateFunc: method is nil but NamespaceInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Namespace + }{ + In1: in1, + } + lockNamespaceInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespaceInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespaceInterface.CreateCalls()) +func (mock *NamespaceInterfaceMock) CreateCalls() []struct { + In1 *v1.Namespace +} { + var calls []struct { + In1 *v1.Namespace + } + lockNamespaceInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespaceInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespaceInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespaceInterfaceMock.DeleteFunc: method is nil but NamespaceInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespaceInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespaceInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespaceInterface.DeleteCalls()) +func (mock *NamespaceInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespaceInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespaceInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespaceInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespaceInterfaceMock.DeleteCollectionFunc: method is nil but NamespaceInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespaceInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespaceInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespaceInterface.DeleteCollectionCalls()) +func (mock *NamespaceInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespaceInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespaceInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespaceInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespaceInterfaceMock.DeleteNamespacedFunc: method is nil but NamespaceInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespaceInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespaceInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespaceInterface.DeleteNamespacedCalls()) +func (mock *NamespaceInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespaceInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespaceInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespaceInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Namespace, error) { + if mock.GetFunc == nil { + panic("NamespaceInterfaceMock.GetFunc: method is nil but NamespaceInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespaceInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespaceInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespaceInterface.GetCalls()) +func (mock *NamespaceInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespaceInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespaceInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespaceInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespaceInterfaceMock.GetNamespacedFunc: method is nil but NamespaceInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespaceInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespaceInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespaceInterface.GetNamespacedCalls()) +func (mock *NamespaceInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespaceInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespaceInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespaceInterfaceMock) List(opts metav1.ListOptions) (*v1.NamespaceList, error) { + if mock.ListFunc == nil { + panic("NamespaceInterfaceMock.ListFunc: method is nil but NamespaceInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespaceInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespaceInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespaceInterface.ListCalls()) +func (mock *NamespaceInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespaceInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespaceInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespaceInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NamespaceList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespaceInterfaceMock.ListNamespacedFunc: method is nil but NamespaceInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespaceInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespaceInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespaceInterface.ListNamespacedCalls()) +func (mock *NamespaceInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespaceInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespaceInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespaceInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespaceInterfaceMock.ObjectClientFunc: method is nil but NamespaceInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespaceInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespaceInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespaceInterface.ObjectClientCalls()) +func (mock *NamespaceInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespaceInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespaceInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespaceInterfaceMock) Update(in1 *v1.Namespace) (*v1.Namespace, error) { + if mock.UpdateFunc == nil { + panic("NamespaceInterfaceMock.UpdateFunc: method is nil but NamespaceInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Namespace + }{ + In1: in1, + } + lockNamespaceInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespaceInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespaceInterface.UpdateCalls()) +func (mock *NamespaceInterfaceMock) UpdateCalls() []struct { + In1 *v1.Namespace +} { + var calls []struct { + In1 *v1.Namespace + } + lockNamespaceInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespaceInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespaceInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespaceInterfaceMock.WatchFunc: method is nil but NamespaceInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespaceInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespaceInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespaceInterface.WatchCalls()) +func (mock *NamespaceInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespaceInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespaceInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacesGetterMockNamespaces sync.RWMutex +) + +// Ensure, that NamespacesGetterMock does implement v11.NamespacesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.NamespacesGetter = &NamespacesGetterMock{} + +// NamespacesGetterMock is a mock implementation of v11.NamespacesGetter. +// +// func TestSomethingThatUsesNamespacesGetter(t *testing.T) { +// +// // make and configure a mocked v11.NamespacesGetter +// mockedNamespacesGetter := &NamespacesGetterMock{ +// NamespacesFunc: func(namespace string) v11.NamespaceInterface { +// panic("mock out the Namespaces method") +// }, +// } +// +// // use mockedNamespacesGetter in code that requires v11.NamespacesGetter +// // and then make assertions. +// +// } +type NamespacesGetterMock struct { + // NamespacesFunc mocks the Namespaces method. + NamespacesFunc func(namespace string) v11.NamespaceInterface + + // calls tracks calls to the methods. + calls struct { + // Namespaces holds details about calls to the Namespaces method. + Namespaces []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Namespaces calls NamespacesFunc. +func (mock *NamespacesGetterMock) Namespaces(namespace string) v11.NamespaceInterface { + if mock.NamespacesFunc == nil { + panic("NamespacesGetterMock.NamespacesFunc: method is nil but NamespacesGetter.Namespaces was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacesGetterMockNamespaces.Lock() + mock.calls.Namespaces = append(mock.calls.Namespaces, callInfo) + lockNamespacesGetterMockNamespaces.Unlock() + return mock.NamespacesFunc(namespace) +} + +// NamespacesCalls gets all the calls that were made to Namespaces. +// Check the length with: +// +// len(mockedNamespacesGetter.NamespacesCalls()) +func (mock *NamespacesGetterMock) NamespacesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacesGetterMockNamespaces.RLock() + calls = mock.calls.Namespaces + lockNamespacesGetterMockNamespaces.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_node_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_node_mock.go new file mode 100644 index 0000000..20bbb4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_node_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNodeListerMockGet sync.RWMutex + lockNodeListerMockList sync.RWMutex +) + +// Ensure, that NodeListerMock does implement v11.NodeLister. +// If this is not the case, regenerate this file with moq. +var _ v11.NodeLister = &NodeListerMock{} + +// NodeListerMock is a mock implementation of v11.NodeLister. +// +// func TestSomethingThatUsesNodeLister(t *testing.T) { +// +// // make and configure a mocked v11.NodeLister +// mockedNodeLister := &NodeListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Node, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Node, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNodeLister in code that requires v11.NodeLister +// // and then make assertions. +// +// } +type NodeListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Node, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Node, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NodeListerMock) Get(namespace string, name string) (*v1.Node, error) { + if mock.GetFunc == nil { + panic("NodeListerMock.GetFunc: method is nil but NodeLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeLister.GetCalls()) +func (mock *NodeListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeListerMockGet.RLock() + calls = mock.calls.Get + lockNodeListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeListerMock) List(namespace string, selector labels.Selector) ([]*v1.Node, error) { + if mock.ListFunc == nil { + panic("NodeListerMock.ListFunc: method is nil but NodeLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNodeListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeLister.ListCalls()) +func (mock *NodeListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNodeListerMockList.RLock() + calls = mock.calls.List + lockNodeListerMockList.RUnlock() + return calls +} + +var ( + lockNodeControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeControllerMockAddClusterScopedHandler sync.RWMutex + lockNodeControllerMockAddFeatureHandler sync.RWMutex + lockNodeControllerMockAddHandler sync.RWMutex + lockNodeControllerMockEnqueue sync.RWMutex + lockNodeControllerMockEnqueueAfter sync.RWMutex + lockNodeControllerMockGeneric sync.RWMutex + lockNodeControllerMockInformer sync.RWMutex + lockNodeControllerMockLister sync.RWMutex +) + +// Ensure, that NodeControllerMock does implement v11.NodeController. +// If this is not the case, regenerate this file with moq. +var _ v11.NodeController = &NodeControllerMock{} + +// NodeControllerMock is a mock implementation of v11.NodeController. +// +// func TestSomethingThatUsesNodeController(t *testing.T) { +// +// // make and configure a mocked v11.NodeController +// mockedNodeController := &NodeControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.NodeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.NodeLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNodeController in code that requires v11.NodeController +// // and then make assertions. +// +// } +type NodeControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NodeHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.NodeHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.NodeHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.NodeLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NodeHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NodeHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NodeHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.NodeHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NodeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NodeHandlerFunc + } + lockNodeControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.NodeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeControllerMock.AddClusterScopedHandlerFunc: method is nil but NodeController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeController.AddClusterScopedHandlerCalls()) +func (mock *NodeControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NodeHandlerFunc + } + lockNodeControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeControllerMock.AddFeatureHandlerFunc: method is nil but NodeController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeController.AddFeatureHandlerCalls()) +func (mock *NodeControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc + } + lockNodeControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeControllerMock) AddHandler(ctx context.Context, name string, handler v11.NodeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeControllerMock.AddHandlerFunc: method is nil but NodeController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNodeControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeController.AddHandlerCalls()) +func (mock *NodeControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.NodeHandlerFunc + } + lockNodeControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NodeControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NodeControllerMock.EnqueueFunc: method is nil but NodeController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNodeControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNodeController.EnqueueCalls()) +func (mock *NodeControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNodeControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NodeControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NodeControllerMock.EnqueueAfterFunc: method is nil but NodeController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNodeControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNodeControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNodeController.EnqueueAfterCalls()) +func (mock *NodeControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNodeControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNodeControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NodeControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NodeControllerMock.GenericFunc: method is nil but NodeController.Generic was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNodeControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNodeController.GenericCalls()) +func (mock *NodeControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNodeControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NodeControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NodeControllerMock.InformerFunc: method is nil but NodeController.Informer was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNodeControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNodeController.InformerCalls()) +func (mock *NodeControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNodeControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NodeControllerMock) Lister() v11.NodeLister { + if mock.ListerFunc == nil { + panic("NodeControllerMock.ListerFunc: method is nil but NodeController.Lister was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNodeControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNodeController.ListerCalls()) +func (mock *NodeControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockLister.RLock() + calls = mock.calls.Lister + lockNodeControllerMockLister.RUnlock() + return calls +} + +var ( + lockNodeInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNodeInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNodeInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNodeInterfaceMockAddFeatureHandler sync.RWMutex + lockNodeInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNodeInterfaceMockAddHandler sync.RWMutex + lockNodeInterfaceMockAddLifecycle sync.RWMutex + lockNodeInterfaceMockController sync.RWMutex + lockNodeInterfaceMockCreate sync.RWMutex + lockNodeInterfaceMockDelete sync.RWMutex + lockNodeInterfaceMockDeleteCollection sync.RWMutex + lockNodeInterfaceMockDeleteNamespaced sync.RWMutex + lockNodeInterfaceMockGet sync.RWMutex + lockNodeInterfaceMockGetNamespaced sync.RWMutex + lockNodeInterfaceMockList sync.RWMutex + lockNodeInterfaceMockListNamespaced sync.RWMutex + lockNodeInterfaceMockObjectClient sync.RWMutex + lockNodeInterfaceMockUpdate sync.RWMutex + lockNodeInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NodeInterfaceMock does implement v11.NodeInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.NodeInterface = &NodeInterfaceMock{} + +// NodeInterfaceMock is a mock implementation of v11.NodeInterface. +// +// func TestSomethingThatUsesNodeInterface(t *testing.T) { +// +// // make and configure a mocked v11.NodeInterface +// mockedNodeInterface := &NodeInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NodeLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.NodeLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NodeLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.NodeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.NodeLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.NodeController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Node) (*v1.Node, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Node, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Node, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.NodeList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.NodeList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Node) (*v1.Node, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNodeInterface in code that requires v11.NodeInterface +// // and then make assertions. +// +// } +type NodeInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NodeLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.NodeLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NodeLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.NodeHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.NodeLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.NodeController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Node) (*v1.Node, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Node, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Node, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.NodeList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.NodeList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Node) (*v1.Node, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NodeHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NodeLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NodeHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NodeLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NodeHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NodeLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NodeHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NodeLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Node + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Node + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NodeHandlerFunc + } + lockNodeInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NodeInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NodeLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NodeInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NodeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NodeLifecycle + } + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.NodeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NodeInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedHandlerCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NodeHandlerFunc + } + lockNodeInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NodeInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.NodeLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NodeInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NodeLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNodeInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedLifecycleCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NodeLifecycle + } + lockNodeInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNodeInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NodeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeInterfaceMock.AddFeatureHandlerFunc: method is nil but NodeInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddFeatureHandlerCalls()) +func (mock *NodeInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NodeHandlerFunc + } + lockNodeInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NodeInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.NodeLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NodeInterfaceMock.AddFeatureLifecycleFunc: method is nil but NodeInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NodeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNodeInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddFeatureLifecycleCalls()) +func (mock *NodeInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NodeLifecycle + } + lockNodeInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNodeInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.NodeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeInterfaceMock.AddHandlerFunc: method is nil but NodeInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddHandlerCalls()) +func (mock *NodeInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.NodeHandlerFunc + } + lockNodeInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NodeInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.NodeLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NodeInterfaceMock.AddLifecycleFunc: method is nil but NodeInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.NodeLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNodeInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddLifecycleCalls()) +func (mock *NodeInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.NodeLifecycle + } + lockNodeInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNodeInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NodeInterfaceMock) Controller() v11.NodeController { + if mock.ControllerFunc == nil { + panic("NodeInterfaceMock.ControllerFunc: method is nil but NodeInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNodeInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNodeInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNodeInterface.ControllerCalls()) +func (mock *NodeInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNodeInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNodeInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NodeInterfaceMock) Create(in1 *v1.Node) (*v1.Node, error) { + if mock.CreateFunc == nil { + panic("NodeInterfaceMock.CreateFunc: method is nil but NodeInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Node + }{ + In1: in1, + } + lockNodeInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNodeInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNodeInterface.CreateCalls()) +func (mock *NodeInterfaceMock) CreateCalls() []struct { + In1 *v1.Node +} { + var calls []struct { + In1 *v1.Node + } + lockNodeInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNodeInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NodeInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NodeInterfaceMock.DeleteFunc: method is nil but NodeInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNodeInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNodeInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNodeInterface.DeleteCalls()) +func (mock *NodeInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNodeInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNodeInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NodeInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NodeInterfaceMock.DeleteCollectionFunc: method is nil but NodeInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNodeInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNodeInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNodeInterface.DeleteCollectionCalls()) +func (mock *NodeInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNodeInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNodeInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NodeInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NodeInterfaceMock.DeleteNamespacedFunc: method is nil but NodeInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNodeInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNodeInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.DeleteNamespacedCalls()) +func (mock *NodeInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNodeInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNodeInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NodeInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Node, error) { + if mock.GetFunc == nil { + panic("NodeInterfaceMock.GetFunc: method is nil but NodeInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNodeInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeInterface.GetCalls()) +func (mock *NodeInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNodeInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNodeInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NodeInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Node, error) { + if mock.GetNamespacedFunc == nil { + panic("NodeInterfaceMock.GetNamespacedFunc: method is nil but NodeInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNodeInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNodeInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.GetNamespacedCalls()) +func (mock *NodeInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNodeInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNodeInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeInterfaceMock) List(opts metav1.ListOptions) (*v1.NodeList, error) { + if mock.ListFunc == nil { + panic("NodeInterfaceMock.ListFunc: method is nil but NodeInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeInterface.ListCalls()) +func (mock *NodeInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeInterfaceMockList.RLock() + calls = mock.calls.List + lockNodeInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NodeInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NodeList, error) { + if mock.ListNamespacedFunc == nil { + panic("NodeInterfaceMock.ListNamespacedFunc: method is nil but NodeInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNodeInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNodeInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.ListNamespacedCalls()) +func (mock *NodeInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNodeInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNodeInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NodeInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NodeInterfaceMock.ObjectClientFunc: method is nil but NodeInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNodeInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNodeInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNodeInterface.ObjectClientCalls()) +func (mock *NodeInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNodeInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNodeInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NodeInterfaceMock) Update(in1 *v1.Node) (*v1.Node, error) { + if mock.UpdateFunc == nil { + panic("NodeInterfaceMock.UpdateFunc: method is nil but NodeInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Node + }{ + In1: in1, + } + lockNodeInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNodeInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNodeInterface.UpdateCalls()) +func (mock *NodeInterfaceMock) UpdateCalls() []struct { + In1 *v1.Node +} { + var calls []struct { + In1 *v1.Node + } + lockNodeInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNodeInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NodeInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NodeInterfaceMock.WatchFunc: method is nil but NodeInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNodeInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNodeInterface.WatchCalls()) +func (mock *NodeInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNodeInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNodesGetterMockNodes sync.RWMutex +) + +// Ensure, that NodesGetterMock does implement v11.NodesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.NodesGetter = &NodesGetterMock{} + +// NodesGetterMock is a mock implementation of v11.NodesGetter. +// +// func TestSomethingThatUsesNodesGetter(t *testing.T) { +// +// // make and configure a mocked v11.NodesGetter +// mockedNodesGetter := &NodesGetterMock{ +// NodesFunc: func(namespace string) v11.NodeInterface { +// panic("mock out the Nodes method") +// }, +// } +// +// // use mockedNodesGetter in code that requires v11.NodesGetter +// // and then make assertions. +// +// } +type NodesGetterMock struct { + // NodesFunc mocks the Nodes method. + NodesFunc func(namespace string) v11.NodeInterface + + // calls tracks calls to the methods. + calls struct { + // Nodes holds details about calls to the Nodes method. + Nodes []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Nodes calls NodesFunc. +func (mock *NodesGetterMock) Nodes(namespace string) v11.NodeInterface { + if mock.NodesFunc == nil { + panic("NodesGetterMock.NodesFunc: method is nil but NodesGetter.Nodes was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNodesGetterMockNodes.Lock() + mock.calls.Nodes = append(mock.calls.Nodes, callInfo) + lockNodesGetterMockNodes.Unlock() + return mock.NodesFunc(namespace) +} + +// NodesCalls gets all the calls that were made to Nodes. +// Check the length with: +// +// len(mockedNodesGetter.NodesCalls()) +func (mock *NodesGetterMock) NodesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNodesGetterMockNodes.RLock() + calls = mock.calls.Nodes + lockNodesGetterMockNodes.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_persistent_volume_claim_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_persistent_volume_claim_mock.go new file mode 100644 index 0000000..664bbc9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_persistent_volume_claim_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockPersistentVolumeClaimListerMockGet sync.RWMutex + lockPersistentVolumeClaimListerMockList sync.RWMutex +) + +// Ensure, that PersistentVolumeClaimListerMock does implement v11.PersistentVolumeClaimLister. +// If this is not the case, regenerate this file with moq. +var _ v11.PersistentVolumeClaimLister = &PersistentVolumeClaimListerMock{} + +// PersistentVolumeClaimListerMock is a mock implementation of v11.PersistentVolumeClaimLister. +// +// func TestSomethingThatUsesPersistentVolumeClaimLister(t *testing.T) { +// +// // make and configure a mocked v11.PersistentVolumeClaimLister +// mockedPersistentVolumeClaimLister := &PersistentVolumeClaimListerMock{ +// GetFunc: func(namespace string, name string) (*v1.PersistentVolumeClaim, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.PersistentVolumeClaim, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedPersistentVolumeClaimLister in code that requires v11.PersistentVolumeClaimLister +// // and then make assertions. +// +// } +type PersistentVolumeClaimListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.PersistentVolumeClaim, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.PersistentVolumeClaim, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *PersistentVolumeClaimListerMock) Get(namespace string, name string) (*v1.PersistentVolumeClaim, error) { + if mock.GetFunc == nil { + panic("PersistentVolumeClaimListerMock.GetFunc: method is nil but PersistentVolumeClaimLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPersistentVolumeClaimListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPersistentVolumeClaimListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPersistentVolumeClaimLister.GetCalls()) +func (mock *PersistentVolumeClaimListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPersistentVolumeClaimListerMockGet.RLock() + calls = mock.calls.Get + lockPersistentVolumeClaimListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PersistentVolumeClaimListerMock) List(namespace string, selector labels.Selector) ([]*v1.PersistentVolumeClaim, error) { + if mock.ListFunc == nil { + panic("PersistentVolumeClaimListerMock.ListFunc: method is nil but PersistentVolumeClaimLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockPersistentVolumeClaimListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPersistentVolumeClaimListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPersistentVolumeClaimLister.ListCalls()) +func (mock *PersistentVolumeClaimListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockPersistentVolumeClaimListerMockList.RLock() + calls = mock.calls.List + lockPersistentVolumeClaimListerMockList.RUnlock() + return calls +} + +var ( + lockPersistentVolumeClaimControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockPersistentVolumeClaimControllerMockAddClusterScopedHandler sync.RWMutex + lockPersistentVolumeClaimControllerMockAddFeatureHandler sync.RWMutex + lockPersistentVolumeClaimControllerMockAddHandler sync.RWMutex + lockPersistentVolumeClaimControllerMockEnqueue sync.RWMutex + lockPersistentVolumeClaimControllerMockEnqueueAfter sync.RWMutex + lockPersistentVolumeClaimControllerMockGeneric sync.RWMutex + lockPersistentVolumeClaimControllerMockInformer sync.RWMutex + lockPersistentVolumeClaimControllerMockLister sync.RWMutex +) + +// Ensure, that PersistentVolumeClaimControllerMock does implement v11.PersistentVolumeClaimController. +// If this is not the case, regenerate this file with moq. +var _ v11.PersistentVolumeClaimController = &PersistentVolumeClaimControllerMock{} + +// PersistentVolumeClaimControllerMock is a mock implementation of v11.PersistentVolumeClaimController. +// +// func TestSomethingThatUsesPersistentVolumeClaimController(t *testing.T) { +// +// // make and configure a mocked v11.PersistentVolumeClaimController +// mockedPersistentVolumeClaimController := &PersistentVolumeClaimControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.PersistentVolumeClaimLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedPersistentVolumeClaimController in code that requires v11.PersistentVolumeClaimController +// // and then make assertions. +// +// } +type PersistentVolumeClaimControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.PersistentVolumeClaimHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.PersistentVolumeClaimLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.PersistentVolumeClaimHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.PersistentVolumeClaimHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PersistentVolumeClaimHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.PersistentVolumeClaimHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PersistentVolumeClaimControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PersistentVolumeClaimControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but PersistentVolumeClaimController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPersistentVolumeClaimControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPersistentVolumeClaimControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.AddClusterScopedFeatureHandlerCalls()) +func (mock *PersistentVolumeClaimControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPersistentVolumeClaimControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PersistentVolumeClaimControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PersistentVolumeClaimControllerMock.AddClusterScopedHandlerFunc: method is nil but PersistentVolumeClaimController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPersistentVolumeClaimControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPersistentVolumeClaimControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.AddClusterScopedHandlerCalls()) +func (mock *PersistentVolumeClaimControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPersistentVolumeClaimControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PersistentVolumeClaimControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PersistentVolumeClaimControllerMock.AddFeatureHandlerFunc: method is nil but PersistentVolumeClaimController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPersistentVolumeClaimControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPersistentVolumeClaimControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.AddFeatureHandlerCalls()) +func (mock *PersistentVolumeClaimControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPersistentVolumeClaimControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PersistentVolumeClaimControllerMock) AddHandler(ctx context.Context, name string, handler v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PersistentVolumeClaimControllerMock.AddHandlerFunc: method is nil but PersistentVolumeClaimController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockPersistentVolumeClaimControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPersistentVolumeClaimControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.AddHandlerCalls()) +func (mock *PersistentVolumeClaimControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPersistentVolumeClaimControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *PersistentVolumeClaimControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("PersistentVolumeClaimControllerMock.EnqueueFunc: method is nil but PersistentVolumeClaimController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPersistentVolumeClaimControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockPersistentVolumeClaimControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.EnqueueCalls()) +func (mock *PersistentVolumeClaimControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPersistentVolumeClaimControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockPersistentVolumeClaimControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *PersistentVolumeClaimControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("PersistentVolumeClaimControllerMock.EnqueueAfterFunc: method is nil but PersistentVolumeClaimController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockPersistentVolumeClaimControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockPersistentVolumeClaimControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.EnqueueAfterCalls()) +func (mock *PersistentVolumeClaimControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockPersistentVolumeClaimControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockPersistentVolumeClaimControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *PersistentVolumeClaimControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("PersistentVolumeClaimControllerMock.GenericFunc: method is nil but PersistentVolumeClaimController.Generic was just called") + } + callInfo := struct { + }{} + lockPersistentVolumeClaimControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockPersistentVolumeClaimControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.GenericCalls()) +func (mock *PersistentVolumeClaimControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockPersistentVolumeClaimControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockPersistentVolumeClaimControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *PersistentVolumeClaimControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("PersistentVolumeClaimControllerMock.InformerFunc: method is nil but PersistentVolumeClaimController.Informer was just called") + } + callInfo := struct { + }{} + lockPersistentVolumeClaimControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockPersistentVolumeClaimControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.InformerCalls()) +func (mock *PersistentVolumeClaimControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockPersistentVolumeClaimControllerMockInformer.RLock() + calls = mock.calls.Informer + lockPersistentVolumeClaimControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *PersistentVolumeClaimControllerMock) Lister() v11.PersistentVolumeClaimLister { + if mock.ListerFunc == nil { + panic("PersistentVolumeClaimControllerMock.ListerFunc: method is nil but PersistentVolumeClaimController.Lister was just called") + } + callInfo := struct { + }{} + lockPersistentVolumeClaimControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockPersistentVolumeClaimControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedPersistentVolumeClaimController.ListerCalls()) +func (mock *PersistentVolumeClaimControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockPersistentVolumeClaimControllerMockLister.RLock() + calls = mock.calls.Lister + lockPersistentVolumeClaimControllerMockLister.RUnlock() + return calls +} + +var ( + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddClusterScopedHandler sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddFeatureHandler sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddFeatureLifecycle sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddHandler sync.RWMutex + lockPersistentVolumeClaimInterfaceMockAddLifecycle sync.RWMutex + lockPersistentVolumeClaimInterfaceMockController sync.RWMutex + lockPersistentVolumeClaimInterfaceMockCreate sync.RWMutex + lockPersistentVolumeClaimInterfaceMockDelete sync.RWMutex + lockPersistentVolumeClaimInterfaceMockDeleteCollection sync.RWMutex + lockPersistentVolumeClaimInterfaceMockDeleteNamespaced sync.RWMutex + lockPersistentVolumeClaimInterfaceMockGet sync.RWMutex + lockPersistentVolumeClaimInterfaceMockGetNamespaced sync.RWMutex + lockPersistentVolumeClaimInterfaceMockList sync.RWMutex + lockPersistentVolumeClaimInterfaceMockListNamespaced sync.RWMutex + lockPersistentVolumeClaimInterfaceMockObjectClient sync.RWMutex + lockPersistentVolumeClaimInterfaceMockUpdate sync.RWMutex + lockPersistentVolumeClaimInterfaceMockWatch sync.RWMutex +) + +// Ensure, that PersistentVolumeClaimInterfaceMock does implement v11.PersistentVolumeClaimInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.PersistentVolumeClaimInterface = &PersistentVolumeClaimInterfaceMock{} + +// PersistentVolumeClaimInterfaceMock is a mock implementation of v11.PersistentVolumeClaimInterface. +// +// func TestSomethingThatUsesPersistentVolumeClaimInterface(t *testing.T) { +// +// // make and configure a mocked v11.PersistentVolumeClaimInterface +// mockedPersistentVolumeClaimInterface := &PersistentVolumeClaimInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.PersistentVolumeClaimLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.PersistentVolumeClaimLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.PersistentVolumeClaimController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedPersistentVolumeClaimInterface in code that requires v11.PersistentVolumeClaimInterface +// // and then make assertions. +// +// } +type PersistentVolumeClaimInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.PersistentVolumeClaimLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.PersistentVolumeClaimLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.PersistentVolumeClaimController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.PersistentVolumeClaimHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PersistentVolumeClaimLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.PersistentVolumeClaimHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PersistentVolumeClaimLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PersistentVolumeClaimHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PersistentVolumeClaimLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PersistentVolumeClaimHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PersistentVolumeClaimLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.PersistentVolumeClaim + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.PersistentVolumeClaim + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but PersistentVolumeClaimInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but PersistentVolumeClaimInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockPersistentVolumeClaimInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddClusterScopedHandlerFunc: method is nil but PersistentVolumeClaimInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPersistentVolumeClaimInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddClusterScopedHandlerCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPersistentVolumeClaimInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.PersistentVolumeClaimLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but PersistentVolumeClaimInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockPersistentVolumeClaimInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddClusterScopedLifecycleCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PersistentVolumeClaimLifecycle + } + lockPersistentVolumeClaimInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockPersistentVolumeClaimInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddFeatureHandlerFunc: method is nil but PersistentVolumeClaimInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPersistentVolumeClaimInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPersistentVolumeClaimInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddFeatureHandlerCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPersistentVolumeClaimInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.PersistentVolumeClaimLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddFeatureLifecycleFunc: method is nil but PersistentVolumeClaimInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockPersistentVolumeClaimInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockPersistentVolumeClaimInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddFeatureLifecycleCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle + } + lockPersistentVolumeClaimInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockPersistentVolumeClaimInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.PersistentVolumeClaimHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddHandlerFunc: method is nil but PersistentVolumeClaimInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockPersistentVolumeClaimInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPersistentVolumeClaimInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddHandlerCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.PersistentVolumeClaimHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.PersistentVolumeClaimHandlerFunc + } + lockPersistentVolumeClaimInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPersistentVolumeClaimInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *PersistentVolumeClaimInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.PersistentVolumeClaimLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.AddLifecycleFunc: method is nil but PersistentVolumeClaimInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockPersistentVolumeClaimInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockPersistentVolumeClaimInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.AddLifecycleCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.PersistentVolumeClaimLifecycle + } + lockPersistentVolumeClaimInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockPersistentVolumeClaimInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Controller() v11.PersistentVolumeClaimController { + if mock.ControllerFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.ControllerFunc: method is nil but PersistentVolumeClaimInterface.Controller was just called") + } + callInfo := struct { + }{} + lockPersistentVolumeClaimInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockPersistentVolumeClaimInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.ControllerCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockPersistentVolumeClaimInterfaceMockController.RLock() + calls = mock.calls.Controller + lockPersistentVolumeClaimInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Create(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + if mock.CreateFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.CreateFunc: method is nil but PersistentVolumeClaimInterface.Create was just called") + } + callInfo := struct { + In1 *v1.PersistentVolumeClaim + }{ + In1: in1, + } + lockPersistentVolumeClaimInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockPersistentVolumeClaimInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.CreateCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) CreateCalls() []struct { + In1 *v1.PersistentVolumeClaim +} { + var calls []struct { + In1 *v1.PersistentVolumeClaim + } + lockPersistentVolumeClaimInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockPersistentVolumeClaimInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.DeleteFunc: method is nil but PersistentVolumeClaimInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockPersistentVolumeClaimInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockPersistentVolumeClaimInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.DeleteCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockPersistentVolumeClaimInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockPersistentVolumeClaimInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *PersistentVolumeClaimInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.DeleteCollectionFunc: method is nil but PersistentVolumeClaimInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockPersistentVolumeClaimInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockPersistentVolumeClaimInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.DeleteCollectionCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockPersistentVolumeClaimInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockPersistentVolumeClaimInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *PersistentVolumeClaimInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.DeleteNamespacedFunc: method is nil but PersistentVolumeClaimInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockPersistentVolumeClaimInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockPersistentVolumeClaimInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.DeleteNamespacedCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockPersistentVolumeClaimInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockPersistentVolumeClaimInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { + if mock.GetFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.GetFunc: method is nil but PersistentVolumeClaimInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockPersistentVolumeClaimInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPersistentVolumeClaimInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.GetCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockPersistentVolumeClaimInterfaceMockGet.RLock() + calls = mock.calls.Get + lockPersistentVolumeClaimInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *PersistentVolumeClaimInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { + if mock.GetNamespacedFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.GetNamespacedFunc: method is nil but PersistentVolumeClaimInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockPersistentVolumeClaimInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockPersistentVolumeClaimInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.GetNamespacedCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockPersistentVolumeClaimInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockPersistentVolumeClaimInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PersistentVolumeClaimInterfaceMock) List(opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { + if mock.ListFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.ListFunc: method is nil but PersistentVolumeClaimInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPersistentVolumeClaimInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPersistentVolumeClaimInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.ListCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPersistentVolumeClaimInterfaceMockList.RLock() + calls = mock.calls.List + lockPersistentVolumeClaimInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *PersistentVolumeClaimInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { + if mock.ListNamespacedFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.ListNamespacedFunc: method is nil but PersistentVolumeClaimInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockPersistentVolumeClaimInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockPersistentVolumeClaimInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.ListNamespacedCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockPersistentVolumeClaimInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockPersistentVolumeClaimInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *PersistentVolumeClaimInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.ObjectClientFunc: method is nil but PersistentVolumeClaimInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockPersistentVolumeClaimInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockPersistentVolumeClaimInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.ObjectClientCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockPersistentVolumeClaimInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockPersistentVolumeClaimInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Update(in1 *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + if mock.UpdateFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.UpdateFunc: method is nil but PersistentVolumeClaimInterface.Update was just called") + } + callInfo := struct { + In1 *v1.PersistentVolumeClaim + }{ + In1: in1, + } + lockPersistentVolumeClaimInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockPersistentVolumeClaimInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.UpdateCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) UpdateCalls() []struct { + In1 *v1.PersistentVolumeClaim +} { + var calls []struct { + In1 *v1.PersistentVolumeClaim + } + lockPersistentVolumeClaimInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockPersistentVolumeClaimInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *PersistentVolumeClaimInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("PersistentVolumeClaimInterfaceMock.WatchFunc: method is nil but PersistentVolumeClaimInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPersistentVolumeClaimInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockPersistentVolumeClaimInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedPersistentVolumeClaimInterface.WatchCalls()) +func (mock *PersistentVolumeClaimInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPersistentVolumeClaimInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockPersistentVolumeClaimInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockPersistentVolumeClaimsGetterMockPersistentVolumeClaims sync.RWMutex +) + +// Ensure, that PersistentVolumeClaimsGetterMock does implement v11.PersistentVolumeClaimsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.PersistentVolumeClaimsGetter = &PersistentVolumeClaimsGetterMock{} + +// PersistentVolumeClaimsGetterMock is a mock implementation of v11.PersistentVolumeClaimsGetter. +// +// func TestSomethingThatUsesPersistentVolumeClaimsGetter(t *testing.T) { +// +// // make and configure a mocked v11.PersistentVolumeClaimsGetter +// mockedPersistentVolumeClaimsGetter := &PersistentVolumeClaimsGetterMock{ +// PersistentVolumeClaimsFunc: func(namespace string) v11.PersistentVolumeClaimInterface { +// panic("mock out the PersistentVolumeClaims method") +// }, +// } +// +// // use mockedPersistentVolumeClaimsGetter in code that requires v11.PersistentVolumeClaimsGetter +// // and then make assertions. +// +// } +type PersistentVolumeClaimsGetterMock struct { + // PersistentVolumeClaimsFunc mocks the PersistentVolumeClaims method. + PersistentVolumeClaimsFunc func(namespace string) v11.PersistentVolumeClaimInterface + + // calls tracks calls to the methods. + calls struct { + // PersistentVolumeClaims holds details about calls to the PersistentVolumeClaims method. + PersistentVolumeClaims []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// PersistentVolumeClaims calls PersistentVolumeClaimsFunc. +func (mock *PersistentVolumeClaimsGetterMock) PersistentVolumeClaims(namespace string) v11.PersistentVolumeClaimInterface { + if mock.PersistentVolumeClaimsFunc == nil { + panic("PersistentVolumeClaimsGetterMock.PersistentVolumeClaimsFunc: method is nil but PersistentVolumeClaimsGetter.PersistentVolumeClaims was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockPersistentVolumeClaimsGetterMockPersistentVolumeClaims.Lock() + mock.calls.PersistentVolumeClaims = append(mock.calls.PersistentVolumeClaims, callInfo) + lockPersistentVolumeClaimsGetterMockPersistentVolumeClaims.Unlock() + return mock.PersistentVolumeClaimsFunc(namespace) +} + +// PersistentVolumeClaimsCalls gets all the calls that were made to PersistentVolumeClaims. +// Check the length with: +// +// len(mockedPersistentVolumeClaimsGetter.PersistentVolumeClaimsCalls()) +func (mock *PersistentVolumeClaimsGetterMock) PersistentVolumeClaimsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockPersistentVolumeClaimsGetterMockPersistentVolumeClaims.RLock() + calls = mock.calls.PersistentVolumeClaims + lockPersistentVolumeClaimsGetterMockPersistentVolumeClaims.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_pod_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_pod_mock.go new file mode 100644 index 0000000..10d7211 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_pod_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockPodListerMockGet sync.RWMutex + lockPodListerMockList sync.RWMutex +) + +// Ensure, that PodListerMock does implement v11.PodLister. +// If this is not the case, regenerate this file with moq. +var _ v11.PodLister = &PodListerMock{} + +// PodListerMock is a mock implementation of v11.PodLister. +// +// func TestSomethingThatUsesPodLister(t *testing.T) { +// +// // make and configure a mocked v11.PodLister +// mockedPodLister := &PodListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Pod, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Pod, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedPodLister in code that requires v11.PodLister +// // and then make assertions. +// +// } +type PodListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Pod, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Pod, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *PodListerMock) Get(namespace string, name string) (*v1.Pod, error) { + if mock.GetFunc == nil { + panic("PodListerMock.GetFunc: method is nil but PodLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPodListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPodListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPodLister.GetCalls()) +func (mock *PodListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPodListerMockGet.RLock() + calls = mock.calls.Get + lockPodListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PodListerMock) List(namespace string, selector labels.Selector) ([]*v1.Pod, error) { + if mock.ListFunc == nil { + panic("PodListerMock.ListFunc: method is nil but PodLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockPodListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPodListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPodLister.ListCalls()) +func (mock *PodListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockPodListerMockList.RLock() + calls = mock.calls.List + lockPodListerMockList.RUnlock() + return calls +} + +var ( + lockPodControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockPodControllerMockAddClusterScopedHandler sync.RWMutex + lockPodControllerMockAddFeatureHandler sync.RWMutex + lockPodControllerMockAddHandler sync.RWMutex + lockPodControllerMockEnqueue sync.RWMutex + lockPodControllerMockEnqueueAfter sync.RWMutex + lockPodControllerMockGeneric sync.RWMutex + lockPodControllerMockInformer sync.RWMutex + lockPodControllerMockLister sync.RWMutex +) + +// Ensure, that PodControllerMock does implement v11.PodController. +// If this is not the case, regenerate this file with moq. +var _ v11.PodController = &PodControllerMock{} + +// PodControllerMock is a mock implementation of v11.PodController. +// +// func TestSomethingThatUsesPodController(t *testing.T) { +// +// // make and configure a mocked v11.PodController +// mockedPodController := &PodControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PodHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.PodHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.PodHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.PodLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedPodController in code that requires v11.PodController +// // and then make assertions. +// +// } +type PodControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PodHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.PodHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.PodHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.PodLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.PodHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.PodHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PodHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.PodHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PodControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.PodHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PodControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but PodController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PodHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPodControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPodControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPodController.AddClusterScopedFeatureHandlerCalls()) +func (mock *PodControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.PodHandlerFunc + } + lockPodControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPodControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PodControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.PodHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PodControllerMock.AddClusterScopedHandlerFunc: method is nil but PodController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PodHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPodControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPodControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPodController.AddClusterScopedHandlerCalls()) +func (mock *PodControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.PodHandlerFunc + } + lockPodControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPodControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PodControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PodControllerMock.AddFeatureHandlerFunc: method is nil but PodController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPodControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPodControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPodController.AddFeatureHandlerCalls()) +func (mock *PodControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc + } + lockPodControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPodControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PodControllerMock) AddHandler(ctx context.Context, name string, handler v11.PodHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PodControllerMock.AddHandlerFunc: method is nil but PodController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.PodHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockPodControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPodControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPodController.AddHandlerCalls()) +func (mock *PodControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.PodHandlerFunc + } + lockPodControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPodControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *PodControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("PodControllerMock.EnqueueFunc: method is nil but PodController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPodControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockPodControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedPodController.EnqueueCalls()) +func (mock *PodControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPodControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockPodControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *PodControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("PodControllerMock.EnqueueAfterFunc: method is nil but PodController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockPodControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockPodControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedPodController.EnqueueAfterCalls()) +func (mock *PodControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockPodControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockPodControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *PodControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("PodControllerMock.GenericFunc: method is nil but PodController.Generic was just called") + } + callInfo := struct { + }{} + lockPodControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockPodControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedPodController.GenericCalls()) +func (mock *PodControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockPodControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockPodControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *PodControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("PodControllerMock.InformerFunc: method is nil but PodController.Informer was just called") + } + callInfo := struct { + }{} + lockPodControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockPodControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedPodController.InformerCalls()) +func (mock *PodControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockPodControllerMockInformer.RLock() + calls = mock.calls.Informer + lockPodControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *PodControllerMock) Lister() v11.PodLister { + if mock.ListerFunc == nil { + panic("PodControllerMock.ListerFunc: method is nil but PodController.Lister was just called") + } + callInfo := struct { + }{} + lockPodControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockPodControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedPodController.ListerCalls()) +func (mock *PodControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockPodControllerMockLister.RLock() + calls = mock.calls.Lister + lockPodControllerMockLister.RUnlock() + return calls +} + +var ( + lockPodInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockPodInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockPodInterfaceMockAddClusterScopedHandler sync.RWMutex + lockPodInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockPodInterfaceMockAddFeatureHandler sync.RWMutex + lockPodInterfaceMockAddFeatureLifecycle sync.RWMutex + lockPodInterfaceMockAddHandler sync.RWMutex + lockPodInterfaceMockAddLifecycle sync.RWMutex + lockPodInterfaceMockController sync.RWMutex + lockPodInterfaceMockCreate sync.RWMutex + lockPodInterfaceMockDelete sync.RWMutex + lockPodInterfaceMockDeleteCollection sync.RWMutex + lockPodInterfaceMockDeleteNamespaced sync.RWMutex + lockPodInterfaceMockGet sync.RWMutex + lockPodInterfaceMockGetNamespaced sync.RWMutex + lockPodInterfaceMockList sync.RWMutex + lockPodInterfaceMockListNamespaced sync.RWMutex + lockPodInterfaceMockObjectClient sync.RWMutex + lockPodInterfaceMockUpdate sync.RWMutex + lockPodInterfaceMockWatch sync.RWMutex +) + +// Ensure, that PodInterfaceMock does implement v11.PodInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.PodInterface = &PodInterfaceMock{} + +// PodInterfaceMock is a mock implementation of v11.PodInterface. +// +// func TestSomethingThatUsesPodInterface(t *testing.T) { +// +// // make and configure a mocked v11.PodInterface +// mockedPodInterface := &PodInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PodLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.PodLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.PodLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.PodHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.PodLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.PodController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Pod) (*v1.Pod, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Pod, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Pod, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.PodList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.PodList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Pod) (*v1.Pod, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedPodInterface in code that requires v11.PodInterface +// // and then make assertions. +// +// } +type PodInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PodLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.PodLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.PodLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.PodHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.PodLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.PodController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Pod) (*v1.Pod, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Pod, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Pod, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.PodList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.PodList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Pod) (*v1.Pod, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.PodHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PodLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.PodHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PodLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PodHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PodLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.PodHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.PodLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Pod + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Pod + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PodInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PodInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but PodInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PodHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPodInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPodInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPodInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *PodInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.PodHandlerFunc + } + lockPodInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPodInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *PodInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.PodLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("PodInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but PodInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PodLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPodInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockPodInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedPodInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *PodInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PodLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.PodLifecycle + } + lockPodInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockPodInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PodInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.PodHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PodInterfaceMock.AddClusterScopedHandlerFunc: method is nil but PodInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PodHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPodInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPodInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPodInterface.AddClusterScopedHandlerCalls()) +func (mock *PodInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.PodHandlerFunc + } + lockPodInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPodInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *PodInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.PodLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("PodInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but PodInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PodLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPodInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockPodInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedPodInterface.AddClusterScopedLifecycleCalls()) +func (mock *PodInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PodLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.PodLifecycle + } + lockPodInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockPodInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PodInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.PodHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PodInterfaceMock.AddFeatureHandlerFunc: method is nil but PodInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPodInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPodInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPodInterface.AddFeatureHandlerCalls()) +func (mock *PodInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.PodHandlerFunc + } + lockPodInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPodInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *PodInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.PodLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("PodInterfaceMock.AddFeatureLifecycleFunc: method is nil but PodInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PodLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockPodInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockPodInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedPodInterface.AddFeatureLifecycleCalls()) +func (mock *PodInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PodLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.PodLifecycle + } + lockPodInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockPodInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PodInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.PodHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PodInterfaceMock.AddHandlerFunc: method is nil but PodInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.PodHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockPodInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPodInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPodInterface.AddHandlerCalls()) +func (mock *PodInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.PodHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.PodHandlerFunc + } + lockPodInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPodInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *PodInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.PodLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("PodInterfaceMock.AddLifecycleFunc: method is nil but PodInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.PodLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockPodInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockPodInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedPodInterface.AddLifecycleCalls()) +func (mock *PodInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.PodLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.PodLifecycle + } + lockPodInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockPodInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *PodInterfaceMock) Controller() v11.PodController { + if mock.ControllerFunc == nil { + panic("PodInterfaceMock.ControllerFunc: method is nil but PodInterface.Controller was just called") + } + callInfo := struct { + }{} + lockPodInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockPodInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedPodInterface.ControllerCalls()) +func (mock *PodInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockPodInterfaceMockController.RLock() + calls = mock.calls.Controller + lockPodInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *PodInterfaceMock) Create(in1 *v1.Pod) (*v1.Pod, error) { + if mock.CreateFunc == nil { + panic("PodInterfaceMock.CreateFunc: method is nil but PodInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Pod + }{ + In1: in1, + } + lockPodInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockPodInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedPodInterface.CreateCalls()) +func (mock *PodInterfaceMock) CreateCalls() []struct { + In1 *v1.Pod +} { + var calls []struct { + In1 *v1.Pod + } + lockPodInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockPodInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *PodInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("PodInterfaceMock.DeleteFunc: method is nil but PodInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockPodInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockPodInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedPodInterface.DeleteCalls()) +func (mock *PodInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockPodInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockPodInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *PodInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("PodInterfaceMock.DeleteCollectionFunc: method is nil but PodInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockPodInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockPodInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedPodInterface.DeleteCollectionCalls()) +func (mock *PodInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockPodInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockPodInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *PodInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("PodInterfaceMock.DeleteNamespacedFunc: method is nil but PodInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockPodInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockPodInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedPodInterface.DeleteNamespacedCalls()) +func (mock *PodInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockPodInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockPodInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *PodInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Pod, error) { + if mock.GetFunc == nil { + panic("PodInterfaceMock.GetFunc: method is nil but PodInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockPodInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPodInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPodInterface.GetCalls()) +func (mock *PodInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockPodInterfaceMockGet.RLock() + calls = mock.calls.Get + lockPodInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *PodInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Pod, error) { + if mock.GetNamespacedFunc == nil { + panic("PodInterfaceMock.GetNamespacedFunc: method is nil but PodInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockPodInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockPodInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedPodInterface.GetNamespacedCalls()) +func (mock *PodInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockPodInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockPodInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PodInterfaceMock) List(opts metav1.ListOptions) (*v1.PodList, error) { + if mock.ListFunc == nil { + panic("PodInterfaceMock.ListFunc: method is nil but PodInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPodInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPodInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPodInterface.ListCalls()) +func (mock *PodInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPodInterfaceMockList.RLock() + calls = mock.calls.List + lockPodInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *PodInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PodList, error) { + if mock.ListNamespacedFunc == nil { + panic("PodInterfaceMock.ListNamespacedFunc: method is nil but PodInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockPodInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockPodInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedPodInterface.ListNamespacedCalls()) +func (mock *PodInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockPodInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockPodInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *PodInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("PodInterfaceMock.ObjectClientFunc: method is nil but PodInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockPodInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockPodInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedPodInterface.ObjectClientCalls()) +func (mock *PodInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockPodInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockPodInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *PodInterfaceMock) Update(in1 *v1.Pod) (*v1.Pod, error) { + if mock.UpdateFunc == nil { + panic("PodInterfaceMock.UpdateFunc: method is nil but PodInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Pod + }{ + In1: in1, + } + lockPodInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockPodInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedPodInterface.UpdateCalls()) +func (mock *PodInterfaceMock) UpdateCalls() []struct { + In1 *v1.Pod +} { + var calls []struct { + In1 *v1.Pod + } + lockPodInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockPodInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *PodInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("PodInterfaceMock.WatchFunc: method is nil but PodInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPodInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockPodInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedPodInterface.WatchCalls()) +func (mock *PodInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPodInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockPodInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockPodsGetterMockPods sync.RWMutex +) + +// Ensure, that PodsGetterMock does implement v11.PodsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.PodsGetter = &PodsGetterMock{} + +// PodsGetterMock is a mock implementation of v11.PodsGetter. +// +// func TestSomethingThatUsesPodsGetter(t *testing.T) { +// +// // make and configure a mocked v11.PodsGetter +// mockedPodsGetter := &PodsGetterMock{ +// PodsFunc: func(namespace string) v11.PodInterface { +// panic("mock out the Pods method") +// }, +// } +// +// // use mockedPodsGetter in code that requires v11.PodsGetter +// // and then make assertions. +// +// } +type PodsGetterMock struct { + // PodsFunc mocks the Pods method. + PodsFunc func(namespace string) v11.PodInterface + + // calls tracks calls to the methods. + calls struct { + // Pods holds details about calls to the Pods method. + Pods []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Pods calls PodsFunc. +func (mock *PodsGetterMock) Pods(namespace string) v11.PodInterface { + if mock.PodsFunc == nil { + panic("PodsGetterMock.PodsFunc: method is nil but PodsGetter.Pods was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockPodsGetterMockPods.Lock() + mock.calls.Pods = append(mock.calls.Pods, callInfo) + lockPodsGetterMockPods.Unlock() + return mock.PodsFunc(namespace) +} + +// PodsCalls gets all the calls that were made to Pods. +// Check the length with: +// +// len(mockedPodsGetter.PodsCalls()) +func (mock *PodsGetterMock) PodsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockPodsGetterMockPods.RLock() + calls = mock.calls.Pods + lockPodsGetterMockPods.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_replication_controller_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_replication_controller_mock.go new file mode 100644 index 0000000..77eb50e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_replication_controller_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockReplicationControllerListerMockGet sync.RWMutex + lockReplicationControllerListerMockList sync.RWMutex +) + +// Ensure, that ReplicationControllerListerMock does implement v11.ReplicationControllerLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicationControllerLister = &ReplicationControllerListerMock{} + +// ReplicationControllerListerMock is a mock implementation of v11.ReplicationControllerLister. +// +// func TestSomethingThatUsesReplicationControllerLister(t *testing.T) { +// +// // make and configure a mocked v11.ReplicationControllerLister +// mockedReplicationControllerLister := &ReplicationControllerListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ReplicationController, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ReplicationController, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedReplicationControllerLister in code that requires v11.ReplicationControllerLister +// // and then make assertions. +// +// } +type ReplicationControllerListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ReplicationController, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ReplicationController, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ReplicationControllerListerMock) Get(namespace string, name string) (*v1.ReplicationController, error) { + if mock.GetFunc == nil { + panic("ReplicationControllerListerMock.GetFunc: method is nil but ReplicationControllerLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockReplicationControllerListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockReplicationControllerListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedReplicationControllerLister.GetCalls()) +func (mock *ReplicationControllerListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockReplicationControllerListerMockGet.RLock() + calls = mock.calls.Get + lockReplicationControllerListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ReplicationControllerListerMock) List(namespace string, selector labels.Selector) ([]*v1.ReplicationController, error) { + if mock.ListFunc == nil { + panic("ReplicationControllerListerMock.ListFunc: method is nil but ReplicationControllerLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockReplicationControllerListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockReplicationControllerListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedReplicationControllerLister.ListCalls()) +func (mock *ReplicationControllerListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockReplicationControllerListerMockList.RLock() + calls = mock.calls.List + lockReplicationControllerListerMockList.RUnlock() + return calls +} + +var ( + lockReplicationControllerControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockReplicationControllerControllerMockAddClusterScopedHandler sync.RWMutex + lockReplicationControllerControllerMockAddFeatureHandler sync.RWMutex + lockReplicationControllerControllerMockAddHandler sync.RWMutex + lockReplicationControllerControllerMockEnqueue sync.RWMutex + lockReplicationControllerControllerMockEnqueueAfter sync.RWMutex + lockReplicationControllerControllerMockGeneric sync.RWMutex + lockReplicationControllerControllerMockInformer sync.RWMutex + lockReplicationControllerControllerMockLister sync.RWMutex +) + +// Ensure, that ReplicationControllerControllerMock does implement v11.ReplicationControllerController. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicationControllerController = &ReplicationControllerControllerMock{} + +// ReplicationControllerControllerMock is a mock implementation of v11.ReplicationControllerController. +// +// func TestSomethingThatUsesReplicationControllerController(t *testing.T) { +// +// // make and configure a mocked v11.ReplicationControllerController +// mockedReplicationControllerController := &ReplicationControllerControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ReplicationControllerLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedReplicationControllerController in code that requires v11.ReplicationControllerController +// // and then make assertions. +// +// } +type ReplicationControllerControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ReplicationControllerHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ReplicationControllerLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ReplicationControllerHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ReplicationControllerHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicationControllerHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ReplicationControllerHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ReplicationControllerControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ReplicationControllerControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ReplicationControllerController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockReplicationControllerControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockReplicationControllerControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedReplicationControllerController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ReplicationControllerControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockReplicationControllerControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ReplicationControllerControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ReplicationControllerHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ReplicationControllerControllerMock.AddClusterScopedHandlerFunc: method is nil but ReplicationControllerController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockReplicationControllerControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockReplicationControllerControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedReplicationControllerController.AddClusterScopedHandlerCalls()) +func (mock *ReplicationControllerControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockReplicationControllerControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ReplicationControllerControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ReplicationControllerControllerMock.AddFeatureHandlerFunc: method is nil but ReplicationControllerController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockReplicationControllerControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockReplicationControllerControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedReplicationControllerController.AddFeatureHandlerCalls()) +func (mock *ReplicationControllerControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockReplicationControllerControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ReplicationControllerControllerMock) AddHandler(ctx context.Context, name string, handler v11.ReplicationControllerHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ReplicationControllerControllerMock.AddHandlerFunc: method is nil but ReplicationControllerController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockReplicationControllerControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockReplicationControllerControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedReplicationControllerController.AddHandlerCalls()) +func (mock *ReplicationControllerControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockReplicationControllerControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ReplicationControllerControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ReplicationControllerControllerMock.EnqueueFunc: method is nil but ReplicationControllerController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockReplicationControllerControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockReplicationControllerControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedReplicationControllerController.EnqueueCalls()) +func (mock *ReplicationControllerControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockReplicationControllerControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockReplicationControllerControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ReplicationControllerControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ReplicationControllerControllerMock.EnqueueAfterFunc: method is nil but ReplicationControllerController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockReplicationControllerControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockReplicationControllerControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedReplicationControllerController.EnqueueAfterCalls()) +func (mock *ReplicationControllerControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockReplicationControllerControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockReplicationControllerControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ReplicationControllerControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ReplicationControllerControllerMock.GenericFunc: method is nil but ReplicationControllerController.Generic was just called") + } + callInfo := struct { + }{} + lockReplicationControllerControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockReplicationControllerControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedReplicationControllerController.GenericCalls()) +func (mock *ReplicationControllerControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockReplicationControllerControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockReplicationControllerControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ReplicationControllerControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ReplicationControllerControllerMock.InformerFunc: method is nil but ReplicationControllerController.Informer was just called") + } + callInfo := struct { + }{} + lockReplicationControllerControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockReplicationControllerControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedReplicationControllerController.InformerCalls()) +func (mock *ReplicationControllerControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockReplicationControllerControllerMockInformer.RLock() + calls = mock.calls.Informer + lockReplicationControllerControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ReplicationControllerControllerMock) Lister() v11.ReplicationControllerLister { + if mock.ListerFunc == nil { + panic("ReplicationControllerControllerMock.ListerFunc: method is nil but ReplicationControllerController.Lister was just called") + } + callInfo := struct { + }{} + lockReplicationControllerControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockReplicationControllerControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedReplicationControllerController.ListerCalls()) +func (mock *ReplicationControllerControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockReplicationControllerControllerMockLister.RLock() + calls = mock.calls.Lister + lockReplicationControllerControllerMockLister.RUnlock() + return calls +} + +var ( + lockReplicationControllerInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockReplicationControllerInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockReplicationControllerInterfaceMockAddClusterScopedHandler sync.RWMutex + lockReplicationControllerInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockReplicationControllerInterfaceMockAddFeatureHandler sync.RWMutex + lockReplicationControllerInterfaceMockAddFeatureLifecycle sync.RWMutex + lockReplicationControllerInterfaceMockAddHandler sync.RWMutex + lockReplicationControllerInterfaceMockAddLifecycle sync.RWMutex + lockReplicationControllerInterfaceMockController sync.RWMutex + lockReplicationControllerInterfaceMockCreate sync.RWMutex + lockReplicationControllerInterfaceMockDelete sync.RWMutex + lockReplicationControllerInterfaceMockDeleteCollection sync.RWMutex + lockReplicationControllerInterfaceMockDeleteNamespaced sync.RWMutex + lockReplicationControllerInterfaceMockGet sync.RWMutex + lockReplicationControllerInterfaceMockGetNamespaced sync.RWMutex + lockReplicationControllerInterfaceMockList sync.RWMutex + lockReplicationControllerInterfaceMockListNamespaced sync.RWMutex + lockReplicationControllerInterfaceMockObjectClient sync.RWMutex + lockReplicationControllerInterfaceMockUpdate sync.RWMutex + lockReplicationControllerInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ReplicationControllerInterfaceMock does implement v11.ReplicationControllerInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicationControllerInterface = &ReplicationControllerInterfaceMock{} + +// ReplicationControllerInterfaceMock is a mock implementation of v11.ReplicationControllerInterface. +// +// func TestSomethingThatUsesReplicationControllerInterface(t *testing.T) { +// +// // make and configure a mocked v11.ReplicationControllerInterface +// mockedReplicationControllerInterface := &ReplicationControllerInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicationControllerLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ReplicationControllerLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ReplicationControllerController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ReplicationController) (*v1.ReplicationController, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ReplicationController) (*v1.ReplicationController, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedReplicationControllerInterface in code that requires v11.ReplicationControllerInterface +// // and then make assertions. +// +// } +type ReplicationControllerInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicationControllerLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ReplicationControllerLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ReplicationControllerController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ReplicationController) (*v1.ReplicationController, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ReplicationController, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicationController, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ReplicationControllerList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ReplicationController) (*v1.ReplicationController, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ReplicationControllerHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicationControllerLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ReplicationControllerHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicationControllerLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicationControllerHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicationControllerLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ReplicationControllerHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ReplicationControllerLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ReplicationController + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ReplicationController + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ReplicationControllerInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ReplicationControllerInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockReplicationControllerInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockReplicationControllerInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockReplicationControllerInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ReplicationControllerInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ReplicationControllerInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockReplicationControllerInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockReplicationControllerInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle + } + lockReplicationControllerInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockReplicationControllerInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ReplicationControllerHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ReplicationControllerInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ReplicationControllerInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockReplicationControllerInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockReplicationControllerInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddClusterScopedHandlerCalls()) +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockReplicationControllerInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ReplicationControllerLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ReplicationControllerInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ReplicationControllerInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockReplicationControllerInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockReplicationControllerInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddClusterScopedLifecycleCalls()) +func (mock *ReplicationControllerInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ReplicationControllerLifecycle + } + lockReplicationControllerInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockReplicationControllerInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ReplicationControllerInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ReplicationControllerInterfaceMock.AddFeatureHandlerFunc: method is nil but ReplicationControllerInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockReplicationControllerInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockReplicationControllerInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddFeatureHandlerCalls()) +func (mock *ReplicationControllerInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockReplicationControllerInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ReplicationControllerInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ReplicationControllerLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ReplicationControllerInterfaceMock.AddFeatureLifecycleFunc: method is nil but ReplicationControllerInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicationControllerLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockReplicationControllerInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockReplicationControllerInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddFeatureLifecycleCalls()) +func (mock *ReplicationControllerInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicationControllerLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ReplicationControllerLifecycle + } + lockReplicationControllerInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockReplicationControllerInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ReplicationControllerInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ReplicationControllerHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ReplicationControllerInterfaceMock.AddHandlerFunc: method is nil but ReplicationControllerInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ReplicationControllerHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockReplicationControllerInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockReplicationControllerInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddHandlerCalls()) +func (mock *ReplicationControllerInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ReplicationControllerHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ReplicationControllerHandlerFunc + } + lockReplicationControllerInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockReplicationControllerInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ReplicationControllerInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ReplicationControllerLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ReplicationControllerInterfaceMock.AddLifecycleFunc: method is nil but ReplicationControllerInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicationControllerLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockReplicationControllerInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockReplicationControllerInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedReplicationControllerInterface.AddLifecycleCalls()) +func (mock *ReplicationControllerInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicationControllerLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ReplicationControllerLifecycle + } + lockReplicationControllerInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockReplicationControllerInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ReplicationControllerInterfaceMock) Controller() v11.ReplicationControllerController { + if mock.ControllerFunc == nil { + panic("ReplicationControllerInterfaceMock.ControllerFunc: method is nil but ReplicationControllerInterface.Controller was just called") + } + callInfo := struct { + }{} + lockReplicationControllerInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockReplicationControllerInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedReplicationControllerInterface.ControllerCalls()) +func (mock *ReplicationControllerInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockReplicationControllerInterfaceMockController.RLock() + calls = mock.calls.Controller + lockReplicationControllerInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ReplicationControllerInterfaceMock) Create(in1 *v1.ReplicationController) (*v1.ReplicationController, error) { + if mock.CreateFunc == nil { + panic("ReplicationControllerInterfaceMock.CreateFunc: method is nil but ReplicationControllerInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ReplicationController + }{ + In1: in1, + } + lockReplicationControllerInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockReplicationControllerInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedReplicationControllerInterface.CreateCalls()) +func (mock *ReplicationControllerInterfaceMock) CreateCalls() []struct { + In1 *v1.ReplicationController +} { + var calls []struct { + In1 *v1.ReplicationController + } + lockReplicationControllerInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockReplicationControllerInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ReplicationControllerInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ReplicationControllerInterfaceMock.DeleteFunc: method is nil but ReplicationControllerInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockReplicationControllerInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockReplicationControllerInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedReplicationControllerInterface.DeleteCalls()) +func (mock *ReplicationControllerInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockReplicationControllerInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockReplicationControllerInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ReplicationControllerInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ReplicationControllerInterfaceMock.DeleteCollectionFunc: method is nil but ReplicationControllerInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockReplicationControllerInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockReplicationControllerInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedReplicationControllerInterface.DeleteCollectionCalls()) +func (mock *ReplicationControllerInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockReplicationControllerInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockReplicationControllerInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ReplicationControllerInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ReplicationControllerInterfaceMock.DeleteNamespacedFunc: method is nil but ReplicationControllerInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockReplicationControllerInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockReplicationControllerInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedReplicationControllerInterface.DeleteNamespacedCalls()) +func (mock *ReplicationControllerInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockReplicationControllerInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockReplicationControllerInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ReplicationControllerInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { + if mock.GetFunc == nil { + panic("ReplicationControllerInterfaceMock.GetFunc: method is nil but ReplicationControllerInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockReplicationControllerInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockReplicationControllerInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedReplicationControllerInterface.GetCalls()) +func (mock *ReplicationControllerInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockReplicationControllerInterfaceMockGet.RLock() + calls = mock.calls.Get + lockReplicationControllerInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ReplicationControllerInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { + if mock.GetNamespacedFunc == nil { + panic("ReplicationControllerInterfaceMock.GetNamespacedFunc: method is nil but ReplicationControllerInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockReplicationControllerInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockReplicationControllerInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedReplicationControllerInterface.GetNamespacedCalls()) +func (mock *ReplicationControllerInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockReplicationControllerInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockReplicationControllerInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ReplicationControllerInterfaceMock) List(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { + if mock.ListFunc == nil { + panic("ReplicationControllerInterfaceMock.ListFunc: method is nil but ReplicationControllerInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockReplicationControllerInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockReplicationControllerInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedReplicationControllerInterface.ListCalls()) +func (mock *ReplicationControllerInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockReplicationControllerInterfaceMockList.RLock() + calls = mock.calls.List + lockReplicationControllerInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ReplicationControllerInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { + if mock.ListNamespacedFunc == nil { + panic("ReplicationControllerInterfaceMock.ListNamespacedFunc: method is nil but ReplicationControllerInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockReplicationControllerInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockReplicationControllerInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedReplicationControllerInterface.ListNamespacedCalls()) +func (mock *ReplicationControllerInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockReplicationControllerInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockReplicationControllerInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ReplicationControllerInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ReplicationControllerInterfaceMock.ObjectClientFunc: method is nil but ReplicationControllerInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockReplicationControllerInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockReplicationControllerInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedReplicationControllerInterface.ObjectClientCalls()) +func (mock *ReplicationControllerInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockReplicationControllerInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockReplicationControllerInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ReplicationControllerInterfaceMock) Update(in1 *v1.ReplicationController) (*v1.ReplicationController, error) { + if mock.UpdateFunc == nil { + panic("ReplicationControllerInterfaceMock.UpdateFunc: method is nil but ReplicationControllerInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ReplicationController + }{ + In1: in1, + } + lockReplicationControllerInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockReplicationControllerInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedReplicationControllerInterface.UpdateCalls()) +func (mock *ReplicationControllerInterfaceMock) UpdateCalls() []struct { + In1 *v1.ReplicationController +} { + var calls []struct { + In1 *v1.ReplicationController + } + lockReplicationControllerInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockReplicationControllerInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ReplicationControllerInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ReplicationControllerInterfaceMock.WatchFunc: method is nil but ReplicationControllerInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockReplicationControllerInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockReplicationControllerInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedReplicationControllerInterface.WatchCalls()) +func (mock *ReplicationControllerInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockReplicationControllerInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockReplicationControllerInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockReplicationControllersGetterMockReplicationControllers sync.RWMutex +) + +// Ensure, that ReplicationControllersGetterMock does implement v11.ReplicationControllersGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ReplicationControllersGetter = &ReplicationControllersGetterMock{} + +// ReplicationControllersGetterMock is a mock implementation of v11.ReplicationControllersGetter. +// +// func TestSomethingThatUsesReplicationControllersGetter(t *testing.T) { +// +// // make and configure a mocked v11.ReplicationControllersGetter +// mockedReplicationControllersGetter := &ReplicationControllersGetterMock{ +// ReplicationControllersFunc: func(namespace string) v11.ReplicationControllerInterface { +// panic("mock out the ReplicationControllers method") +// }, +// } +// +// // use mockedReplicationControllersGetter in code that requires v11.ReplicationControllersGetter +// // and then make assertions. +// +// } +type ReplicationControllersGetterMock struct { + // ReplicationControllersFunc mocks the ReplicationControllers method. + ReplicationControllersFunc func(namespace string) v11.ReplicationControllerInterface + + // calls tracks calls to the methods. + calls struct { + // ReplicationControllers holds details about calls to the ReplicationControllers method. + ReplicationControllers []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ReplicationControllers calls ReplicationControllersFunc. +func (mock *ReplicationControllersGetterMock) ReplicationControllers(namespace string) v11.ReplicationControllerInterface { + if mock.ReplicationControllersFunc == nil { + panic("ReplicationControllersGetterMock.ReplicationControllersFunc: method is nil but ReplicationControllersGetter.ReplicationControllers was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockReplicationControllersGetterMockReplicationControllers.Lock() + mock.calls.ReplicationControllers = append(mock.calls.ReplicationControllers, callInfo) + lockReplicationControllersGetterMockReplicationControllers.Unlock() + return mock.ReplicationControllersFunc(namespace) +} + +// ReplicationControllersCalls gets all the calls that were made to ReplicationControllers. +// Check the length with: +// +// len(mockedReplicationControllersGetter.ReplicationControllersCalls()) +func (mock *ReplicationControllersGetterMock) ReplicationControllersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockReplicationControllersGetterMockReplicationControllers.RLock() + calls = mock.calls.ReplicationControllers + lockReplicationControllersGetterMockReplicationControllers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_resource_quota_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_resource_quota_mock.go new file mode 100644 index 0000000..2247361 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_resource_quota_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockResourceQuotaListerMockGet sync.RWMutex + lockResourceQuotaListerMockList sync.RWMutex +) + +// Ensure, that ResourceQuotaListerMock does implement v11.ResourceQuotaLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ResourceQuotaLister = &ResourceQuotaListerMock{} + +// ResourceQuotaListerMock is a mock implementation of v11.ResourceQuotaLister. +// +// func TestSomethingThatUsesResourceQuotaLister(t *testing.T) { +// +// // make and configure a mocked v11.ResourceQuotaLister +// mockedResourceQuotaLister := &ResourceQuotaListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ResourceQuota, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ResourceQuota, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedResourceQuotaLister in code that requires v11.ResourceQuotaLister +// // and then make assertions. +// +// } +type ResourceQuotaListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ResourceQuota, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ResourceQuota, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ResourceQuotaListerMock) Get(namespace string, name string) (*v1.ResourceQuota, error) { + if mock.GetFunc == nil { + panic("ResourceQuotaListerMock.GetFunc: method is nil but ResourceQuotaLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockResourceQuotaListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockResourceQuotaListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedResourceQuotaLister.GetCalls()) +func (mock *ResourceQuotaListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockResourceQuotaListerMockGet.RLock() + calls = mock.calls.Get + lockResourceQuotaListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ResourceQuotaListerMock) List(namespace string, selector labels.Selector) ([]*v1.ResourceQuota, error) { + if mock.ListFunc == nil { + panic("ResourceQuotaListerMock.ListFunc: method is nil but ResourceQuotaLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockResourceQuotaListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockResourceQuotaListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedResourceQuotaLister.ListCalls()) +func (mock *ResourceQuotaListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockResourceQuotaListerMockList.RLock() + calls = mock.calls.List + lockResourceQuotaListerMockList.RUnlock() + return calls +} + +var ( + lockResourceQuotaControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockResourceQuotaControllerMockAddClusterScopedHandler sync.RWMutex + lockResourceQuotaControllerMockAddFeatureHandler sync.RWMutex + lockResourceQuotaControllerMockAddHandler sync.RWMutex + lockResourceQuotaControllerMockEnqueue sync.RWMutex + lockResourceQuotaControllerMockEnqueueAfter sync.RWMutex + lockResourceQuotaControllerMockGeneric sync.RWMutex + lockResourceQuotaControllerMockInformer sync.RWMutex + lockResourceQuotaControllerMockLister sync.RWMutex +) + +// Ensure, that ResourceQuotaControllerMock does implement v11.ResourceQuotaController. +// If this is not the case, regenerate this file with moq. +var _ v11.ResourceQuotaController = &ResourceQuotaControllerMock{} + +// ResourceQuotaControllerMock is a mock implementation of v11.ResourceQuotaController. +// +// func TestSomethingThatUsesResourceQuotaController(t *testing.T) { +// +// // make and configure a mocked v11.ResourceQuotaController +// mockedResourceQuotaController := &ResourceQuotaControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ResourceQuotaLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedResourceQuotaController in code that requires v11.ResourceQuotaController +// // and then make assertions. +// +// } +type ResourceQuotaControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ResourceQuotaHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ResourceQuotaLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ResourceQuotaHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ResourceQuotaHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ResourceQuotaHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ResourceQuotaHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ResourceQuotaControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ResourceQuotaControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ResourceQuotaController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockResourceQuotaControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockResourceQuotaControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedResourceQuotaController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ResourceQuotaControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockResourceQuotaControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ResourceQuotaControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ResourceQuotaHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ResourceQuotaControllerMock.AddClusterScopedHandlerFunc: method is nil but ResourceQuotaController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockResourceQuotaControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockResourceQuotaControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedResourceQuotaController.AddClusterScopedHandlerCalls()) +func (mock *ResourceQuotaControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockResourceQuotaControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ResourceQuotaControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ResourceQuotaControllerMock.AddFeatureHandlerFunc: method is nil but ResourceQuotaController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockResourceQuotaControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockResourceQuotaControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedResourceQuotaController.AddFeatureHandlerCalls()) +func (mock *ResourceQuotaControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockResourceQuotaControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ResourceQuotaControllerMock) AddHandler(ctx context.Context, name string, handler v11.ResourceQuotaHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ResourceQuotaControllerMock.AddHandlerFunc: method is nil but ResourceQuotaController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockResourceQuotaControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockResourceQuotaControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedResourceQuotaController.AddHandlerCalls()) +func (mock *ResourceQuotaControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockResourceQuotaControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ResourceQuotaControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ResourceQuotaControllerMock.EnqueueFunc: method is nil but ResourceQuotaController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockResourceQuotaControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockResourceQuotaControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedResourceQuotaController.EnqueueCalls()) +func (mock *ResourceQuotaControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockResourceQuotaControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockResourceQuotaControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ResourceQuotaControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ResourceQuotaControllerMock.EnqueueAfterFunc: method is nil but ResourceQuotaController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockResourceQuotaControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockResourceQuotaControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedResourceQuotaController.EnqueueAfterCalls()) +func (mock *ResourceQuotaControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockResourceQuotaControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockResourceQuotaControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ResourceQuotaControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ResourceQuotaControllerMock.GenericFunc: method is nil but ResourceQuotaController.Generic was just called") + } + callInfo := struct { + }{} + lockResourceQuotaControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockResourceQuotaControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedResourceQuotaController.GenericCalls()) +func (mock *ResourceQuotaControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockResourceQuotaControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockResourceQuotaControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ResourceQuotaControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ResourceQuotaControllerMock.InformerFunc: method is nil but ResourceQuotaController.Informer was just called") + } + callInfo := struct { + }{} + lockResourceQuotaControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockResourceQuotaControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedResourceQuotaController.InformerCalls()) +func (mock *ResourceQuotaControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockResourceQuotaControllerMockInformer.RLock() + calls = mock.calls.Informer + lockResourceQuotaControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ResourceQuotaControllerMock) Lister() v11.ResourceQuotaLister { + if mock.ListerFunc == nil { + panic("ResourceQuotaControllerMock.ListerFunc: method is nil but ResourceQuotaController.Lister was just called") + } + callInfo := struct { + }{} + lockResourceQuotaControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockResourceQuotaControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedResourceQuotaController.ListerCalls()) +func (mock *ResourceQuotaControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockResourceQuotaControllerMockLister.RLock() + calls = mock.calls.Lister + lockResourceQuotaControllerMockLister.RUnlock() + return calls +} + +var ( + lockResourceQuotaInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockResourceQuotaInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockResourceQuotaInterfaceMockAddClusterScopedHandler sync.RWMutex + lockResourceQuotaInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockResourceQuotaInterfaceMockAddFeatureHandler sync.RWMutex + lockResourceQuotaInterfaceMockAddFeatureLifecycle sync.RWMutex + lockResourceQuotaInterfaceMockAddHandler sync.RWMutex + lockResourceQuotaInterfaceMockAddLifecycle sync.RWMutex + lockResourceQuotaInterfaceMockController sync.RWMutex + lockResourceQuotaInterfaceMockCreate sync.RWMutex + lockResourceQuotaInterfaceMockDelete sync.RWMutex + lockResourceQuotaInterfaceMockDeleteCollection sync.RWMutex + lockResourceQuotaInterfaceMockDeleteNamespaced sync.RWMutex + lockResourceQuotaInterfaceMockGet sync.RWMutex + lockResourceQuotaInterfaceMockGetNamespaced sync.RWMutex + lockResourceQuotaInterfaceMockList sync.RWMutex + lockResourceQuotaInterfaceMockListNamespaced sync.RWMutex + lockResourceQuotaInterfaceMockObjectClient sync.RWMutex + lockResourceQuotaInterfaceMockUpdate sync.RWMutex + lockResourceQuotaInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ResourceQuotaInterfaceMock does implement v11.ResourceQuotaInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ResourceQuotaInterface = &ResourceQuotaInterfaceMock{} + +// ResourceQuotaInterfaceMock is a mock implementation of v11.ResourceQuotaInterface. +// +// func TestSomethingThatUsesResourceQuotaInterface(t *testing.T) { +// +// // make and configure a mocked v11.ResourceQuotaInterface +// mockedResourceQuotaInterface := &ResourceQuotaInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ResourceQuotaLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ResourceQuotaLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ResourceQuotaController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedResourceQuotaInterface in code that requires v11.ResourceQuotaInterface +// // and then make assertions. +// +// } +type ResourceQuotaInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ResourceQuotaLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ResourceQuotaLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ResourceQuotaController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ResourceQuotaList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ResourceQuotaList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ResourceQuotaHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ResourceQuotaLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ResourceQuotaHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ResourceQuotaLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ResourceQuotaHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ResourceQuotaLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ResourceQuotaHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ResourceQuotaLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ResourceQuota + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ResourceQuota + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ResourceQuotaInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ResourceQuotaInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockResourceQuotaInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockResourceQuotaInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockResourceQuotaInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ResourceQuotaInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ResourceQuotaInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockResourceQuotaInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockResourceQuotaInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle + } + lockResourceQuotaInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockResourceQuotaInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ResourceQuotaHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ResourceQuotaInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ResourceQuotaInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockResourceQuotaInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockResourceQuotaInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddClusterScopedHandlerCalls()) +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockResourceQuotaInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ResourceQuotaLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ResourceQuotaInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ResourceQuotaInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockResourceQuotaInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockResourceQuotaInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddClusterScopedLifecycleCalls()) +func (mock *ResourceQuotaInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ResourceQuotaLifecycle + } + lockResourceQuotaInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockResourceQuotaInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ResourceQuotaInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ResourceQuotaInterfaceMock.AddFeatureHandlerFunc: method is nil but ResourceQuotaInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockResourceQuotaInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockResourceQuotaInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddFeatureHandlerCalls()) +func (mock *ResourceQuotaInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockResourceQuotaInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ResourceQuotaInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ResourceQuotaLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ResourceQuotaInterfaceMock.AddFeatureLifecycleFunc: method is nil but ResourceQuotaInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ResourceQuotaLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockResourceQuotaInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockResourceQuotaInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddFeatureLifecycleCalls()) +func (mock *ResourceQuotaInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ResourceQuotaLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ResourceQuotaLifecycle + } + lockResourceQuotaInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockResourceQuotaInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ResourceQuotaInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ResourceQuotaHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ResourceQuotaInterfaceMock.AddHandlerFunc: method is nil but ResourceQuotaInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ResourceQuotaHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockResourceQuotaInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockResourceQuotaInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddHandlerCalls()) +func (mock *ResourceQuotaInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ResourceQuotaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ResourceQuotaHandlerFunc + } + lockResourceQuotaInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockResourceQuotaInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ResourceQuotaInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ResourceQuotaLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ResourceQuotaInterfaceMock.AddLifecycleFunc: method is nil but ResourceQuotaInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ResourceQuotaLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockResourceQuotaInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockResourceQuotaInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedResourceQuotaInterface.AddLifecycleCalls()) +func (mock *ResourceQuotaInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ResourceQuotaLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ResourceQuotaLifecycle + } + lockResourceQuotaInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockResourceQuotaInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ResourceQuotaInterfaceMock) Controller() v11.ResourceQuotaController { + if mock.ControllerFunc == nil { + panic("ResourceQuotaInterfaceMock.ControllerFunc: method is nil but ResourceQuotaInterface.Controller was just called") + } + callInfo := struct { + }{} + lockResourceQuotaInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockResourceQuotaInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedResourceQuotaInterface.ControllerCalls()) +func (mock *ResourceQuotaInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockResourceQuotaInterfaceMockController.RLock() + calls = mock.calls.Controller + lockResourceQuotaInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ResourceQuotaInterfaceMock) Create(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) { + if mock.CreateFunc == nil { + panic("ResourceQuotaInterfaceMock.CreateFunc: method is nil but ResourceQuotaInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ResourceQuota + }{ + In1: in1, + } + lockResourceQuotaInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockResourceQuotaInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedResourceQuotaInterface.CreateCalls()) +func (mock *ResourceQuotaInterfaceMock) CreateCalls() []struct { + In1 *v1.ResourceQuota +} { + var calls []struct { + In1 *v1.ResourceQuota + } + lockResourceQuotaInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockResourceQuotaInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ResourceQuotaInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ResourceQuotaInterfaceMock.DeleteFunc: method is nil but ResourceQuotaInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockResourceQuotaInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockResourceQuotaInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedResourceQuotaInterface.DeleteCalls()) +func (mock *ResourceQuotaInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockResourceQuotaInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockResourceQuotaInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ResourceQuotaInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ResourceQuotaInterfaceMock.DeleteCollectionFunc: method is nil but ResourceQuotaInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockResourceQuotaInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockResourceQuotaInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedResourceQuotaInterface.DeleteCollectionCalls()) +func (mock *ResourceQuotaInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockResourceQuotaInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockResourceQuotaInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ResourceQuotaInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ResourceQuotaInterfaceMock.DeleteNamespacedFunc: method is nil but ResourceQuotaInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockResourceQuotaInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockResourceQuotaInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedResourceQuotaInterface.DeleteNamespacedCalls()) +func (mock *ResourceQuotaInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockResourceQuotaInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockResourceQuotaInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ResourceQuotaInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { + if mock.GetFunc == nil { + panic("ResourceQuotaInterfaceMock.GetFunc: method is nil but ResourceQuotaInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockResourceQuotaInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockResourceQuotaInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedResourceQuotaInterface.GetCalls()) +func (mock *ResourceQuotaInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockResourceQuotaInterfaceMockGet.RLock() + calls = mock.calls.Get + lockResourceQuotaInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ResourceQuotaInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { + if mock.GetNamespacedFunc == nil { + panic("ResourceQuotaInterfaceMock.GetNamespacedFunc: method is nil but ResourceQuotaInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockResourceQuotaInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockResourceQuotaInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedResourceQuotaInterface.GetNamespacedCalls()) +func (mock *ResourceQuotaInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockResourceQuotaInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockResourceQuotaInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ResourceQuotaInterfaceMock) List(opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { + if mock.ListFunc == nil { + panic("ResourceQuotaInterfaceMock.ListFunc: method is nil but ResourceQuotaInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockResourceQuotaInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockResourceQuotaInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedResourceQuotaInterface.ListCalls()) +func (mock *ResourceQuotaInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockResourceQuotaInterfaceMockList.RLock() + calls = mock.calls.List + lockResourceQuotaInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ResourceQuotaInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { + if mock.ListNamespacedFunc == nil { + panic("ResourceQuotaInterfaceMock.ListNamespacedFunc: method is nil but ResourceQuotaInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockResourceQuotaInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockResourceQuotaInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedResourceQuotaInterface.ListNamespacedCalls()) +func (mock *ResourceQuotaInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockResourceQuotaInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockResourceQuotaInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ResourceQuotaInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ResourceQuotaInterfaceMock.ObjectClientFunc: method is nil but ResourceQuotaInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockResourceQuotaInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockResourceQuotaInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedResourceQuotaInterface.ObjectClientCalls()) +func (mock *ResourceQuotaInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockResourceQuotaInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockResourceQuotaInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ResourceQuotaInterfaceMock) Update(in1 *v1.ResourceQuota) (*v1.ResourceQuota, error) { + if mock.UpdateFunc == nil { + panic("ResourceQuotaInterfaceMock.UpdateFunc: method is nil but ResourceQuotaInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ResourceQuota + }{ + In1: in1, + } + lockResourceQuotaInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockResourceQuotaInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedResourceQuotaInterface.UpdateCalls()) +func (mock *ResourceQuotaInterfaceMock) UpdateCalls() []struct { + In1 *v1.ResourceQuota +} { + var calls []struct { + In1 *v1.ResourceQuota + } + lockResourceQuotaInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockResourceQuotaInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ResourceQuotaInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ResourceQuotaInterfaceMock.WatchFunc: method is nil but ResourceQuotaInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockResourceQuotaInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockResourceQuotaInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedResourceQuotaInterface.WatchCalls()) +func (mock *ResourceQuotaInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockResourceQuotaInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockResourceQuotaInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockResourceQuotasGetterMockResourceQuotas sync.RWMutex +) + +// Ensure, that ResourceQuotasGetterMock does implement v11.ResourceQuotasGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ResourceQuotasGetter = &ResourceQuotasGetterMock{} + +// ResourceQuotasGetterMock is a mock implementation of v11.ResourceQuotasGetter. +// +// func TestSomethingThatUsesResourceQuotasGetter(t *testing.T) { +// +// // make and configure a mocked v11.ResourceQuotasGetter +// mockedResourceQuotasGetter := &ResourceQuotasGetterMock{ +// ResourceQuotasFunc: func(namespace string) v11.ResourceQuotaInterface { +// panic("mock out the ResourceQuotas method") +// }, +// } +// +// // use mockedResourceQuotasGetter in code that requires v11.ResourceQuotasGetter +// // and then make assertions. +// +// } +type ResourceQuotasGetterMock struct { + // ResourceQuotasFunc mocks the ResourceQuotas method. + ResourceQuotasFunc func(namespace string) v11.ResourceQuotaInterface + + // calls tracks calls to the methods. + calls struct { + // ResourceQuotas holds details about calls to the ResourceQuotas method. + ResourceQuotas []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ResourceQuotas calls ResourceQuotasFunc. +func (mock *ResourceQuotasGetterMock) ResourceQuotas(namespace string) v11.ResourceQuotaInterface { + if mock.ResourceQuotasFunc == nil { + panic("ResourceQuotasGetterMock.ResourceQuotasFunc: method is nil but ResourceQuotasGetter.ResourceQuotas was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockResourceQuotasGetterMockResourceQuotas.Lock() + mock.calls.ResourceQuotas = append(mock.calls.ResourceQuotas, callInfo) + lockResourceQuotasGetterMockResourceQuotas.Unlock() + return mock.ResourceQuotasFunc(namespace) +} + +// ResourceQuotasCalls gets all the calls that were made to ResourceQuotas. +// Check the length with: +// +// len(mockedResourceQuotasGetter.ResourceQuotasCalls()) +func (mock *ResourceQuotasGetterMock) ResourceQuotasCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockResourceQuotasGetterMockResourceQuotas.RLock() + calls = mock.calls.ResourceQuotas + lockResourceQuotasGetterMockResourceQuotas.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_secret_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_secret_mock.go new file mode 100644 index 0000000..cb6fac4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_secret_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockSecretListerMockGet sync.RWMutex + lockSecretListerMockList sync.RWMutex +) + +// Ensure, that SecretListerMock does implement v11.SecretLister. +// If this is not the case, regenerate this file with moq. +var _ v11.SecretLister = &SecretListerMock{} + +// SecretListerMock is a mock implementation of v11.SecretLister. +// +// func TestSomethingThatUsesSecretLister(t *testing.T) { +// +// // make and configure a mocked v11.SecretLister +// mockedSecretLister := &SecretListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Secret, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Secret, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedSecretLister in code that requires v11.SecretLister +// // and then make assertions. +// +// } +type SecretListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Secret, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Secret, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *SecretListerMock) Get(namespace string, name string) (*v1.Secret, error) { + if mock.GetFunc == nil { + panic("SecretListerMock.GetFunc: method is nil but SecretLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSecretListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSecretListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSecretLister.GetCalls()) +func (mock *SecretListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSecretListerMockGet.RLock() + calls = mock.calls.Get + lockSecretListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SecretListerMock) List(namespace string, selector labels.Selector) ([]*v1.Secret, error) { + if mock.ListFunc == nil { + panic("SecretListerMock.ListFunc: method is nil but SecretLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockSecretListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSecretListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSecretLister.ListCalls()) +func (mock *SecretListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockSecretListerMockList.RLock() + calls = mock.calls.List + lockSecretListerMockList.RUnlock() + return calls +} + +var ( + lockSecretControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockSecretControllerMockAddClusterScopedHandler sync.RWMutex + lockSecretControllerMockAddFeatureHandler sync.RWMutex + lockSecretControllerMockAddHandler sync.RWMutex + lockSecretControllerMockEnqueue sync.RWMutex + lockSecretControllerMockEnqueueAfter sync.RWMutex + lockSecretControllerMockGeneric sync.RWMutex + lockSecretControllerMockInformer sync.RWMutex + lockSecretControllerMockLister sync.RWMutex +) + +// Ensure, that SecretControllerMock does implement v11.SecretController. +// If this is not the case, regenerate this file with moq. +var _ v11.SecretController = &SecretControllerMock{} + +// SecretControllerMock is a mock implementation of v11.SecretController. +// +// func TestSomethingThatUsesSecretController(t *testing.T) { +// +// // make and configure a mocked v11.SecretController +// mockedSecretController := &SecretControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.SecretHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.SecretHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.SecretHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.SecretLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedSecretController in code that requires v11.SecretController +// // and then make assertions. +// +// } +type SecretControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.SecretHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.SecretHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.SecretHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.SecretLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.SecretHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.SecretHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.SecretHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.SecretHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SecretControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.SecretHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SecretControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but SecretController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.SecretHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSecretControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSecretControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSecretController.AddClusterScopedFeatureHandlerCalls()) +func (mock *SecretControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.SecretHandlerFunc + } + lockSecretControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSecretControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SecretControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.SecretHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SecretControllerMock.AddClusterScopedHandlerFunc: method is nil but SecretController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.SecretHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSecretControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSecretControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSecretController.AddClusterScopedHandlerCalls()) +func (mock *SecretControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.SecretHandlerFunc + } + lockSecretControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSecretControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SecretControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SecretControllerMock.AddFeatureHandlerFunc: method is nil but SecretController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSecretControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSecretControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSecretController.AddFeatureHandlerCalls()) +func (mock *SecretControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc + } + lockSecretControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSecretControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SecretControllerMock) AddHandler(ctx context.Context, name string, handler v11.SecretHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SecretControllerMock.AddHandlerFunc: method is nil but SecretController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.SecretHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockSecretControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSecretControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSecretController.AddHandlerCalls()) +func (mock *SecretControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.SecretHandlerFunc + } + lockSecretControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSecretControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *SecretControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("SecretControllerMock.EnqueueFunc: method is nil but SecretController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSecretControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockSecretControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedSecretController.EnqueueCalls()) +func (mock *SecretControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSecretControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockSecretControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *SecretControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("SecretControllerMock.EnqueueAfterFunc: method is nil but SecretController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockSecretControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockSecretControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedSecretController.EnqueueAfterCalls()) +func (mock *SecretControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockSecretControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockSecretControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *SecretControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("SecretControllerMock.GenericFunc: method is nil but SecretController.Generic was just called") + } + callInfo := struct { + }{} + lockSecretControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockSecretControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedSecretController.GenericCalls()) +func (mock *SecretControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockSecretControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockSecretControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *SecretControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("SecretControllerMock.InformerFunc: method is nil but SecretController.Informer was just called") + } + callInfo := struct { + }{} + lockSecretControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockSecretControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedSecretController.InformerCalls()) +func (mock *SecretControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockSecretControllerMockInformer.RLock() + calls = mock.calls.Informer + lockSecretControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *SecretControllerMock) Lister() v11.SecretLister { + if mock.ListerFunc == nil { + panic("SecretControllerMock.ListerFunc: method is nil but SecretController.Lister was just called") + } + callInfo := struct { + }{} + lockSecretControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockSecretControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedSecretController.ListerCalls()) +func (mock *SecretControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockSecretControllerMockLister.RLock() + calls = mock.calls.Lister + lockSecretControllerMockLister.RUnlock() + return calls +} + +var ( + lockSecretInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockSecretInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockSecretInterfaceMockAddClusterScopedHandler sync.RWMutex + lockSecretInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockSecretInterfaceMockAddFeatureHandler sync.RWMutex + lockSecretInterfaceMockAddFeatureLifecycle sync.RWMutex + lockSecretInterfaceMockAddHandler sync.RWMutex + lockSecretInterfaceMockAddLifecycle sync.RWMutex + lockSecretInterfaceMockController sync.RWMutex + lockSecretInterfaceMockCreate sync.RWMutex + lockSecretInterfaceMockDelete sync.RWMutex + lockSecretInterfaceMockDeleteCollection sync.RWMutex + lockSecretInterfaceMockDeleteNamespaced sync.RWMutex + lockSecretInterfaceMockGet sync.RWMutex + lockSecretInterfaceMockGetNamespaced sync.RWMutex + lockSecretInterfaceMockList sync.RWMutex + lockSecretInterfaceMockListNamespaced sync.RWMutex + lockSecretInterfaceMockObjectClient sync.RWMutex + lockSecretInterfaceMockUpdate sync.RWMutex + lockSecretInterfaceMockWatch sync.RWMutex +) + +// Ensure, that SecretInterfaceMock does implement v11.SecretInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.SecretInterface = &SecretInterfaceMock{} + +// SecretInterfaceMock is a mock implementation of v11.SecretInterface. +// +// func TestSomethingThatUsesSecretInterface(t *testing.T) { +// +// // make and configure a mocked v11.SecretInterface +// mockedSecretInterface := &SecretInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.SecretLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.SecretLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.SecretLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.SecretHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.SecretLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.SecretController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Secret) (*v1.Secret, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Secret, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Secret, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.SecretList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.SecretList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Secret) (*v1.Secret, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedSecretInterface in code that requires v11.SecretInterface +// // and then make assertions. +// +// } +type SecretInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.SecretLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.SecretLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.SecretLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.SecretHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.SecretLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.SecretController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Secret) (*v1.Secret, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Secret, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Secret, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.SecretList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.SecretList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Secret) (*v1.Secret, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.SecretHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.SecretLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.SecretHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.SecretLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.SecretHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.SecretLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.SecretHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.SecretLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Secret + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Secret + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SecretInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SecretInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but SecretInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.SecretHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSecretInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSecretInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSecretInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *SecretInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.SecretHandlerFunc + } + lockSecretInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSecretInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *SecretInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.SecretLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("SecretInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but SecretInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.SecretLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSecretInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockSecretInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedSecretInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *SecretInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.SecretLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.SecretLifecycle + } + lockSecretInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockSecretInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SecretInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.SecretHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SecretInterfaceMock.AddClusterScopedHandlerFunc: method is nil but SecretInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.SecretHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSecretInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSecretInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSecretInterface.AddClusterScopedHandlerCalls()) +func (mock *SecretInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.SecretHandlerFunc + } + lockSecretInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSecretInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *SecretInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.SecretLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("SecretInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but SecretInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.SecretLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSecretInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockSecretInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedSecretInterface.AddClusterScopedLifecycleCalls()) +func (mock *SecretInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.SecretLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.SecretLifecycle + } + lockSecretInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockSecretInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SecretInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.SecretHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SecretInterfaceMock.AddFeatureHandlerFunc: method is nil but SecretInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSecretInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSecretInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSecretInterface.AddFeatureHandlerCalls()) +func (mock *SecretInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.SecretHandlerFunc + } + lockSecretInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSecretInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *SecretInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.SecretLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("SecretInterfaceMock.AddFeatureLifecycleFunc: method is nil but SecretInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.SecretLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockSecretInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockSecretInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedSecretInterface.AddFeatureLifecycleCalls()) +func (mock *SecretInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.SecretLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.SecretLifecycle + } + lockSecretInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockSecretInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SecretInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.SecretHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SecretInterfaceMock.AddHandlerFunc: method is nil but SecretInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.SecretHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockSecretInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSecretInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSecretInterface.AddHandlerCalls()) +func (mock *SecretInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.SecretHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.SecretHandlerFunc + } + lockSecretInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSecretInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *SecretInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.SecretLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("SecretInterfaceMock.AddLifecycleFunc: method is nil but SecretInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.SecretLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockSecretInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockSecretInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedSecretInterface.AddLifecycleCalls()) +func (mock *SecretInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.SecretLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.SecretLifecycle + } + lockSecretInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockSecretInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *SecretInterfaceMock) Controller() v11.SecretController { + if mock.ControllerFunc == nil { + panic("SecretInterfaceMock.ControllerFunc: method is nil but SecretInterface.Controller was just called") + } + callInfo := struct { + }{} + lockSecretInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockSecretInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedSecretInterface.ControllerCalls()) +func (mock *SecretInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockSecretInterfaceMockController.RLock() + calls = mock.calls.Controller + lockSecretInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *SecretInterfaceMock) Create(in1 *v1.Secret) (*v1.Secret, error) { + if mock.CreateFunc == nil { + panic("SecretInterfaceMock.CreateFunc: method is nil but SecretInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Secret + }{ + In1: in1, + } + lockSecretInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockSecretInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedSecretInterface.CreateCalls()) +func (mock *SecretInterfaceMock) CreateCalls() []struct { + In1 *v1.Secret +} { + var calls []struct { + In1 *v1.Secret + } + lockSecretInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockSecretInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *SecretInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("SecretInterfaceMock.DeleteFunc: method is nil but SecretInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockSecretInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockSecretInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedSecretInterface.DeleteCalls()) +func (mock *SecretInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockSecretInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockSecretInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *SecretInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("SecretInterfaceMock.DeleteCollectionFunc: method is nil but SecretInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockSecretInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockSecretInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedSecretInterface.DeleteCollectionCalls()) +func (mock *SecretInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockSecretInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockSecretInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *SecretInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("SecretInterfaceMock.DeleteNamespacedFunc: method is nil but SecretInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockSecretInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockSecretInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedSecretInterface.DeleteNamespacedCalls()) +func (mock *SecretInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockSecretInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockSecretInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *SecretInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Secret, error) { + if mock.GetFunc == nil { + panic("SecretInterfaceMock.GetFunc: method is nil but SecretInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockSecretInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSecretInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSecretInterface.GetCalls()) +func (mock *SecretInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockSecretInterfaceMockGet.RLock() + calls = mock.calls.Get + lockSecretInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *SecretInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Secret, error) { + if mock.GetNamespacedFunc == nil { + panic("SecretInterfaceMock.GetNamespacedFunc: method is nil but SecretInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockSecretInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockSecretInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedSecretInterface.GetNamespacedCalls()) +func (mock *SecretInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockSecretInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockSecretInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SecretInterfaceMock) List(opts metav1.ListOptions) (*v1.SecretList, error) { + if mock.ListFunc == nil { + panic("SecretInterfaceMock.ListFunc: method is nil but SecretInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSecretInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSecretInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSecretInterface.ListCalls()) +func (mock *SecretInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSecretInterfaceMockList.RLock() + calls = mock.calls.List + lockSecretInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *SecretInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.SecretList, error) { + if mock.ListNamespacedFunc == nil { + panic("SecretInterfaceMock.ListNamespacedFunc: method is nil but SecretInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockSecretInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockSecretInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedSecretInterface.ListNamespacedCalls()) +func (mock *SecretInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockSecretInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockSecretInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *SecretInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("SecretInterfaceMock.ObjectClientFunc: method is nil but SecretInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockSecretInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockSecretInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedSecretInterface.ObjectClientCalls()) +func (mock *SecretInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockSecretInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockSecretInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *SecretInterfaceMock) Update(in1 *v1.Secret) (*v1.Secret, error) { + if mock.UpdateFunc == nil { + panic("SecretInterfaceMock.UpdateFunc: method is nil but SecretInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Secret + }{ + In1: in1, + } + lockSecretInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockSecretInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedSecretInterface.UpdateCalls()) +func (mock *SecretInterfaceMock) UpdateCalls() []struct { + In1 *v1.Secret +} { + var calls []struct { + In1 *v1.Secret + } + lockSecretInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockSecretInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *SecretInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("SecretInterfaceMock.WatchFunc: method is nil but SecretInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSecretInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockSecretInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedSecretInterface.WatchCalls()) +func (mock *SecretInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSecretInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockSecretInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockSecretsGetterMockSecrets sync.RWMutex +) + +// Ensure, that SecretsGetterMock does implement v11.SecretsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.SecretsGetter = &SecretsGetterMock{} + +// SecretsGetterMock is a mock implementation of v11.SecretsGetter. +// +// func TestSomethingThatUsesSecretsGetter(t *testing.T) { +// +// // make and configure a mocked v11.SecretsGetter +// mockedSecretsGetter := &SecretsGetterMock{ +// SecretsFunc: func(namespace string) v11.SecretInterface { +// panic("mock out the Secrets method") +// }, +// } +// +// // use mockedSecretsGetter in code that requires v11.SecretsGetter +// // and then make assertions. +// +// } +type SecretsGetterMock struct { + // SecretsFunc mocks the Secrets method. + SecretsFunc func(namespace string) v11.SecretInterface + + // calls tracks calls to the methods. + calls struct { + // Secrets holds details about calls to the Secrets method. + Secrets []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Secrets calls SecretsFunc. +func (mock *SecretsGetterMock) Secrets(namespace string) v11.SecretInterface { + if mock.SecretsFunc == nil { + panic("SecretsGetterMock.SecretsFunc: method is nil but SecretsGetter.Secrets was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockSecretsGetterMockSecrets.Lock() + mock.calls.Secrets = append(mock.calls.Secrets, callInfo) + lockSecretsGetterMockSecrets.Unlock() + return mock.SecretsFunc(namespace) +} + +// SecretsCalls gets all the calls that were made to Secrets. +// Check the length with: +// +// len(mockedSecretsGetter.SecretsCalls()) +func (mock *SecretsGetterMock) SecretsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockSecretsGetterMockSecrets.RLock() + calls = mock.calls.Secrets + lockSecretsGetterMockSecrets.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_account_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_account_mock.go new file mode 100644 index 0000000..c3b1d03 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_account_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockServiceAccountListerMockGet sync.RWMutex + lockServiceAccountListerMockList sync.RWMutex +) + +// Ensure, that ServiceAccountListerMock does implement v11.ServiceAccountLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceAccountLister = &ServiceAccountListerMock{} + +// ServiceAccountListerMock is a mock implementation of v11.ServiceAccountLister. +// +// func TestSomethingThatUsesServiceAccountLister(t *testing.T) { +// +// // make and configure a mocked v11.ServiceAccountLister +// mockedServiceAccountLister := &ServiceAccountListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ServiceAccount, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ServiceAccount, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedServiceAccountLister in code that requires v11.ServiceAccountLister +// // and then make assertions. +// +// } +type ServiceAccountListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ServiceAccount, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ServiceAccount, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ServiceAccountListerMock) Get(namespace string, name string) (*v1.ServiceAccount, error) { + if mock.GetFunc == nil { + panic("ServiceAccountListerMock.GetFunc: method is nil but ServiceAccountLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceAccountListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceAccountListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceAccountLister.GetCalls()) +func (mock *ServiceAccountListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceAccountListerMockGet.RLock() + calls = mock.calls.Get + lockServiceAccountListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceAccountListerMock) List(namespace string, selector labels.Selector) ([]*v1.ServiceAccount, error) { + if mock.ListFunc == nil { + panic("ServiceAccountListerMock.ListFunc: method is nil but ServiceAccountLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockServiceAccountListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceAccountListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceAccountLister.ListCalls()) +func (mock *ServiceAccountListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockServiceAccountListerMockList.RLock() + calls = mock.calls.List + lockServiceAccountListerMockList.RUnlock() + return calls +} + +var ( + lockServiceAccountControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceAccountControllerMockAddClusterScopedHandler sync.RWMutex + lockServiceAccountControllerMockAddFeatureHandler sync.RWMutex + lockServiceAccountControllerMockAddHandler sync.RWMutex + lockServiceAccountControllerMockEnqueue sync.RWMutex + lockServiceAccountControllerMockEnqueueAfter sync.RWMutex + lockServiceAccountControllerMockGeneric sync.RWMutex + lockServiceAccountControllerMockInformer sync.RWMutex + lockServiceAccountControllerMockLister sync.RWMutex +) + +// Ensure, that ServiceAccountControllerMock does implement v11.ServiceAccountController. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceAccountController = &ServiceAccountControllerMock{} + +// ServiceAccountControllerMock is a mock implementation of v11.ServiceAccountController. +// +// func TestSomethingThatUsesServiceAccountController(t *testing.T) { +// +// // make and configure a mocked v11.ServiceAccountController +// mockedServiceAccountController := &ServiceAccountControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ServiceAccountLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedServiceAccountController in code that requires v11.ServiceAccountController +// // and then make assertions. +// +// } +type ServiceAccountControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ServiceAccountHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ServiceAccountLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ServiceAccountHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ServiceAccountHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceAccountHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ServiceAccountHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceAccountControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceAccountControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceAccountController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceAccountControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceAccountControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceAccountControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc + } + lockServiceAccountControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceAccountControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceAccountControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ServiceAccountHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceAccountControllerMock.AddClusterScopedHandlerFunc: method is nil but ServiceAccountController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceAccountControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceAccountControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceAccountController.AddClusterScopedHandlerCalls()) +func (mock *ServiceAccountControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceAccountHandlerFunc + } + lockServiceAccountControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceAccountControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceAccountControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceAccountControllerMock.AddFeatureHandlerFunc: method is nil but ServiceAccountController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceAccountControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountController.AddFeatureHandlerCalls()) +func (mock *ServiceAccountControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc + } + lockServiceAccountControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceAccountControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceAccountControllerMock) AddHandler(ctx context.Context, name string, handler v11.ServiceAccountHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceAccountControllerMock.AddHandlerFunc: method is nil but ServiceAccountController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockServiceAccountControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceAccountControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceAccountController.AddHandlerCalls()) +func (mock *ServiceAccountControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ServiceAccountHandlerFunc + } + lockServiceAccountControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceAccountControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ServiceAccountControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ServiceAccountControllerMock.EnqueueFunc: method is nil but ServiceAccountController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceAccountControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockServiceAccountControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedServiceAccountController.EnqueueCalls()) +func (mock *ServiceAccountControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceAccountControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockServiceAccountControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ServiceAccountControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ServiceAccountControllerMock.EnqueueAfterFunc: method is nil but ServiceAccountController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockServiceAccountControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockServiceAccountControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedServiceAccountController.EnqueueAfterCalls()) +func (mock *ServiceAccountControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockServiceAccountControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockServiceAccountControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ServiceAccountControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ServiceAccountControllerMock.GenericFunc: method is nil but ServiceAccountController.Generic was just called") + } + callInfo := struct { + }{} + lockServiceAccountControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockServiceAccountControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedServiceAccountController.GenericCalls()) +func (mock *ServiceAccountControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockServiceAccountControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ServiceAccountControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ServiceAccountControllerMock.InformerFunc: method is nil but ServiceAccountController.Informer was just called") + } + callInfo := struct { + }{} + lockServiceAccountControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockServiceAccountControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedServiceAccountController.InformerCalls()) +func (mock *ServiceAccountControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountControllerMockInformer.RLock() + calls = mock.calls.Informer + lockServiceAccountControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ServiceAccountControllerMock) Lister() v11.ServiceAccountLister { + if mock.ListerFunc == nil { + panic("ServiceAccountControllerMock.ListerFunc: method is nil but ServiceAccountController.Lister was just called") + } + callInfo := struct { + }{} + lockServiceAccountControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockServiceAccountControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedServiceAccountController.ListerCalls()) +func (mock *ServiceAccountControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountControllerMockLister.RLock() + calls = mock.calls.Lister + lockServiceAccountControllerMockLister.RUnlock() + return calls +} + +var ( + lockServiceAccountInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceAccountInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockServiceAccountInterfaceMockAddClusterScopedHandler sync.RWMutex + lockServiceAccountInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockServiceAccountInterfaceMockAddFeatureHandler sync.RWMutex + lockServiceAccountInterfaceMockAddFeatureLifecycle sync.RWMutex + lockServiceAccountInterfaceMockAddHandler sync.RWMutex + lockServiceAccountInterfaceMockAddLifecycle sync.RWMutex + lockServiceAccountInterfaceMockController sync.RWMutex + lockServiceAccountInterfaceMockCreate sync.RWMutex + lockServiceAccountInterfaceMockDelete sync.RWMutex + lockServiceAccountInterfaceMockDeleteCollection sync.RWMutex + lockServiceAccountInterfaceMockDeleteNamespaced sync.RWMutex + lockServiceAccountInterfaceMockGet sync.RWMutex + lockServiceAccountInterfaceMockGetNamespaced sync.RWMutex + lockServiceAccountInterfaceMockList sync.RWMutex + lockServiceAccountInterfaceMockListNamespaced sync.RWMutex + lockServiceAccountInterfaceMockObjectClient sync.RWMutex + lockServiceAccountInterfaceMockUpdate sync.RWMutex + lockServiceAccountInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ServiceAccountInterfaceMock does implement v11.ServiceAccountInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceAccountInterface = &ServiceAccountInterfaceMock{} + +// ServiceAccountInterfaceMock is a mock implementation of v11.ServiceAccountInterface. +// +// func TestSomethingThatUsesServiceAccountInterface(t *testing.T) { +// +// // make and configure a mocked v11.ServiceAccountInterface +// mockedServiceAccountInterface := &ServiceAccountInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceAccountLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ServiceAccountLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ServiceAccountController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ServiceAccountList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ServiceAccountList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedServiceAccountInterface in code that requires v11.ServiceAccountInterface +// // and then make assertions. +// +// } +type ServiceAccountInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceAccountLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ServiceAccountHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ServiceAccountLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ServiceAccountController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ServiceAccountList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ServiceAccountList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ServiceAccountHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceAccountLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ServiceAccountHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceAccountLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceAccountHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceAccountLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceAccountHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceAccountLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ServiceAccount + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ServiceAccount + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceAccountInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceAccountInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceAccountInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceAccountInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceAccountInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceAccountInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc + } + lockServiceAccountInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceAccountInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ServiceAccountInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ServiceAccountInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ServiceAccountInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceAccountInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockServiceAccountInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ServiceAccountInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle + } + lockServiceAccountInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockServiceAccountInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceAccountInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceAccountHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceAccountInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ServiceAccountInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceAccountInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceAccountInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddClusterScopedHandlerCalls()) +func (mock *ServiceAccountInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceAccountHandlerFunc + } + lockServiceAccountInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceAccountInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ServiceAccountInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceAccountLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ServiceAccountInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ServiceAccountInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceAccountInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockServiceAccountInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddClusterScopedLifecycleCalls()) +func (mock *ServiceAccountInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceAccountLifecycle + } + lockServiceAccountInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockServiceAccountInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceAccountInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceAccountInterfaceMock.AddFeatureHandlerFunc: method is nil but ServiceAccountInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceAccountInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddFeatureHandlerCalls()) +func (mock *ServiceAccountInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceAccountHandlerFunc + } + lockServiceAccountInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceAccountInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ServiceAccountInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceAccountLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ServiceAccountInterfaceMock.AddFeatureLifecycleFunc: method is nil but ServiceAccountInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceAccountLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockServiceAccountInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockServiceAccountInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddFeatureLifecycleCalls()) +func (mock *ServiceAccountInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceAccountLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceAccountLifecycle + } + lockServiceAccountInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockServiceAccountInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceAccountInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ServiceAccountHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceAccountInterfaceMock.AddHandlerFunc: method is nil but ServiceAccountInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ServiceAccountHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceAccountInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddHandlerCalls()) +func (mock *ServiceAccountInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ServiceAccountHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ServiceAccountHandlerFunc + } + lockServiceAccountInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceAccountInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ServiceAccountInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ServiceAccountLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ServiceAccountInterfaceMock.AddLifecycleFunc: method is nil but ServiceAccountInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceAccountLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockServiceAccountInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockServiceAccountInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedServiceAccountInterface.AddLifecycleCalls()) +func (mock *ServiceAccountInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceAccountLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceAccountLifecycle + } + lockServiceAccountInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockServiceAccountInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ServiceAccountInterfaceMock) Controller() v11.ServiceAccountController { + if mock.ControllerFunc == nil { + panic("ServiceAccountInterfaceMock.ControllerFunc: method is nil but ServiceAccountInterface.Controller was just called") + } + callInfo := struct { + }{} + lockServiceAccountInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockServiceAccountInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedServiceAccountInterface.ControllerCalls()) +func (mock *ServiceAccountInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountInterfaceMockController.RLock() + calls = mock.calls.Controller + lockServiceAccountInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ServiceAccountInterfaceMock) Create(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) { + if mock.CreateFunc == nil { + panic("ServiceAccountInterfaceMock.CreateFunc: method is nil but ServiceAccountInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ServiceAccount + }{ + In1: in1, + } + lockServiceAccountInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockServiceAccountInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedServiceAccountInterface.CreateCalls()) +func (mock *ServiceAccountInterfaceMock) CreateCalls() []struct { + In1 *v1.ServiceAccount +} { + var calls []struct { + In1 *v1.ServiceAccount + } + lockServiceAccountInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockServiceAccountInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ServiceAccountInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ServiceAccountInterfaceMock.DeleteFunc: method is nil but ServiceAccountInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockServiceAccountInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockServiceAccountInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedServiceAccountInterface.DeleteCalls()) +func (mock *ServiceAccountInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockServiceAccountInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockServiceAccountInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ServiceAccountInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ServiceAccountInterfaceMock.DeleteCollectionFunc: method is nil but ServiceAccountInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockServiceAccountInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockServiceAccountInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedServiceAccountInterface.DeleteCollectionCalls()) +func (mock *ServiceAccountInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockServiceAccountInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockServiceAccountInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ServiceAccountInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ServiceAccountInterfaceMock.DeleteNamespacedFunc: method is nil but ServiceAccountInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockServiceAccountInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockServiceAccountInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedServiceAccountInterface.DeleteNamespacedCalls()) +func (mock *ServiceAccountInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockServiceAccountInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockServiceAccountInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ServiceAccountInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { + if mock.GetFunc == nil { + panic("ServiceAccountInterfaceMock.GetFunc: method is nil but ServiceAccountInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockServiceAccountInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceAccountInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceAccountInterface.GetCalls()) +func (mock *ServiceAccountInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockServiceAccountInterfaceMockGet.RLock() + calls = mock.calls.Get + lockServiceAccountInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ServiceAccountInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { + if mock.GetNamespacedFunc == nil { + panic("ServiceAccountInterfaceMock.GetNamespacedFunc: method is nil but ServiceAccountInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockServiceAccountInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockServiceAccountInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedServiceAccountInterface.GetNamespacedCalls()) +func (mock *ServiceAccountInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockServiceAccountInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockServiceAccountInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceAccountInterfaceMock) List(opts metav1.ListOptions) (*v1.ServiceAccountList, error) { + if mock.ListFunc == nil { + panic("ServiceAccountInterfaceMock.ListFunc: method is nil but ServiceAccountInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceAccountInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceAccountInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceAccountInterface.ListCalls()) +func (mock *ServiceAccountInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceAccountInterfaceMockList.RLock() + calls = mock.calls.List + lockServiceAccountInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ServiceAccountInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceAccountList, error) { + if mock.ListNamespacedFunc == nil { + panic("ServiceAccountInterfaceMock.ListNamespacedFunc: method is nil but ServiceAccountInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockServiceAccountInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockServiceAccountInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedServiceAccountInterface.ListNamespacedCalls()) +func (mock *ServiceAccountInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockServiceAccountInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockServiceAccountInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ServiceAccountInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ServiceAccountInterfaceMock.ObjectClientFunc: method is nil but ServiceAccountInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockServiceAccountInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockServiceAccountInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedServiceAccountInterface.ObjectClientCalls()) +func (mock *ServiceAccountInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockServiceAccountInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ServiceAccountInterfaceMock) Update(in1 *v1.ServiceAccount) (*v1.ServiceAccount, error) { + if mock.UpdateFunc == nil { + panic("ServiceAccountInterfaceMock.UpdateFunc: method is nil but ServiceAccountInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ServiceAccount + }{ + In1: in1, + } + lockServiceAccountInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockServiceAccountInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedServiceAccountInterface.UpdateCalls()) +func (mock *ServiceAccountInterfaceMock) UpdateCalls() []struct { + In1 *v1.ServiceAccount +} { + var calls []struct { + In1 *v1.ServiceAccount + } + lockServiceAccountInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockServiceAccountInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ServiceAccountInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ServiceAccountInterfaceMock.WatchFunc: method is nil but ServiceAccountInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceAccountInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockServiceAccountInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedServiceAccountInterface.WatchCalls()) +func (mock *ServiceAccountInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceAccountInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockServiceAccountInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockServiceAccountsGetterMockServiceAccounts sync.RWMutex +) + +// Ensure, that ServiceAccountsGetterMock does implement v11.ServiceAccountsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceAccountsGetter = &ServiceAccountsGetterMock{} + +// ServiceAccountsGetterMock is a mock implementation of v11.ServiceAccountsGetter. +// +// func TestSomethingThatUsesServiceAccountsGetter(t *testing.T) { +// +// // make and configure a mocked v11.ServiceAccountsGetter +// mockedServiceAccountsGetter := &ServiceAccountsGetterMock{ +// ServiceAccountsFunc: func(namespace string) v11.ServiceAccountInterface { +// panic("mock out the ServiceAccounts method") +// }, +// } +// +// // use mockedServiceAccountsGetter in code that requires v11.ServiceAccountsGetter +// // and then make assertions. +// +// } +type ServiceAccountsGetterMock struct { + // ServiceAccountsFunc mocks the ServiceAccounts method. + ServiceAccountsFunc func(namespace string) v11.ServiceAccountInterface + + // calls tracks calls to the methods. + calls struct { + // ServiceAccounts holds details about calls to the ServiceAccounts method. + ServiceAccounts []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ServiceAccounts calls ServiceAccountsFunc. +func (mock *ServiceAccountsGetterMock) ServiceAccounts(namespace string) v11.ServiceAccountInterface { + if mock.ServiceAccountsFunc == nil { + panic("ServiceAccountsGetterMock.ServiceAccountsFunc: method is nil but ServiceAccountsGetter.ServiceAccounts was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockServiceAccountsGetterMockServiceAccounts.Lock() + mock.calls.ServiceAccounts = append(mock.calls.ServiceAccounts, callInfo) + lockServiceAccountsGetterMockServiceAccounts.Unlock() + return mock.ServiceAccountsFunc(namespace) +} + +// ServiceAccountsCalls gets all the calls that were made to ServiceAccounts. +// Check the length with: +// +// len(mockedServiceAccountsGetter.ServiceAccountsCalls()) +func (mock *ServiceAccountsGetterMock) ServiceAccountsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockServiceAccountsGetterMockServiceAccounts.RLock() + calls = mock.calls.ServiceAccounts + lockServiceAccountsGetterMockServiceAccounts.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_mock.go new file mode 100644 index 0000000..48eb09c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/fakes/zz_generated_service_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockServiceListerMockGet sync.RWMutex + lockServiceListerMockList sync.RWMutex +) + +// Ensure, that ServiceListerMock does implement v11.ServiceLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceLister = &ServiceListerMock{} + +// ServiceListerMock is a mock implementation of v11.ServiceLister. +// +// func TestSomethingThatUsesServiceLister(t *testing.T) { +// +// // make and configure a mocked v11.ServiceLister +// mockedServiceLister := &ServiceListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Service, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Service, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedServiceLister in code that requires v11.ServiceLister +// // and then make assertions. +// +// } +type ServiceListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Service, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Service, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ServiceListerMock) Get(namespace string, name string) (*v1.Service, error) { + if mock.GetFunc == nil { + panic("ServiceListerMock.GetFunc: method is nil but ServiceLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceLister.GetCalls()) +func (mock *ServiceListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceListerMockGet.RLock() + calls = mock.calls.Get + lockServiceListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceListerMock) List(namespace string, selector labels.Selector) ([]*v1.Service, error) { + if mock.ListFunc == nil { + panic("ServiceListerMock.ListFunc: method is nil but ServiceLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockServiceListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceLister.ListCalls()) +func (mock *ServiceListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockServiceListerMockList.RLock() + calls = mock.calls.List + lockServiceListerMockList.RUnlock() + return calls +} + +var ( + lockServiceControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceControllerMockAddClusterScopedHandler sync.RWMutex + lockServiceControllerMockAddFeatureHandler sync.RWMutex + lockServiceControllerMockAddHandler sync.RWMutex + lockServiceControllerMockEnqueue sync.RWMutex + lockServiceControllerMockEnqueueAfter sync.RWMutex + lockServiceControllerMockGeneric sync.RWMutex + lockServiceControllerMockInformer sync.RWMutex + lockServiceControllerMockLister sync.RWMutex +) + +// Ensure, that ServiceControllerMock does implement v11.ServiceController. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceController = &ServiceControllerMock{} + +// ServiceControllerMock is a mock implementation of v11.ServiceController. +// +// func TestSomethingThatUsesServiceController(t *testing.T) { +// +// // make and configure a mocked v11.ServiceController +// mockedServiceController := &ServiceControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ServiceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ServiceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ServiceLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedServiceController in code that requires v11.ServiceController +// // and then make assertions. +// +// } +type ServiceControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ServiceHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ServiceHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ServiceLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ServiceHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ServiceHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ServiceHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ServiceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ServiceHandlerFunc + } + lockServiceControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ServiceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceControllerMock.AddClusterScopedHandlerFunc: method is nil but ServiceController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceController.AddClusterScopedHandlerCalls()) +func (mock *ServiceControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ServiceHandlerFunc + } + lockServiceControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceControllerMock.AddFeatureHandlerFunc: method is nil but ServiceController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceController.AddFeatureHandlerCalls()) +func (mock *ServiceControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc + } + lockServiceControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceControllerMock) AddHandler(ctx context.Context, name string, handler v11.ServiceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceControllerMock.AddHandlerFunc: method is nil but ServiceController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockServiceControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceController.AddHandlerCalls()) +func (mock *ServiceControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ServiceHandlerFunc + } + lockServiceControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ServiceControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ServiceControllerMock.EnqueueFunc: method is nil but ServiceController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockServiceControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedServiceController.EnqueueCalls()) +func (mock *ServiceControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockServiceControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ServiceControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ServiceControllerMock.EnqueueAfterFunc: method is nil but ServiceController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockServiceControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockServiceControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedServiceController.EnqueueAfterCalls()) +func (mock *ServiceControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockServiceControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockServiceControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ServiceControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ServiceControllerMock.GenericFunc: method is nil but ServiceController.Generic was just called") + } + callInfo := struct { + }{} + lockServiceControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockServiceControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedServiceController.GenericCalls()) +func (mock *ServiceControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockServiceControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockServiceControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ServiceControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ServiceControllerMock.InformerFunc: method is nil but ServiceController.Informer was just called") + } + callInfo := struct { + }{} + lockServiceControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockServiceControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedServiceController.InformerCalls()) +func (mock *ServiceControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockServiceControllerMockInformer.RLock() + calls = mock.calls.Informer + lockServiceControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ServiceControllerMock) Lister() v11.ServiceLister { + if mock.ListerFunc == nil { + panic("ServiceControllerMock.ListerFunc: method is nil but ServiceController.Lister was just called") + } + callInfo := struct { + }{} + lockServiceControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockServiceControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedServiceController.ListerCalls()) +func (mock *ServiceControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockServiceControllerMockLister.RLock() + calls = mock.calls.Lister + lockServiceControllerMockLister.RUnlock() + return calls +} + +var ( + lockServiceInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockServiceInterfaceMockAddClusterScopedHandler sync.RWMutex + lockServiceInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockServiceInterfaceMockAddFeatureHandler sync.RWMutex + lockServiceInterfaceMockAddFeatureLifecycle sync.RWMutex + lockServiceInterfaceMockAddHandler sync.RWMutex + lockServiceInterfaceMockAddLifecycle sync.RWMutex + lockServiceInterfaceMockController sync.RWMutex + lockServiceInterfaceMockCreate sync.RWMutex + lockServiceInterfaceMockDelete sync.RWMutex + lockServiceInterfaceMockDeleteCollection sync.RWMutex + lockServiceInterfaceMockDeleteNamespaced sync.RWMutex + lockServiceInterfaceMockGet sync.RWMutex + lockServiceInterfaceMockGetNamespaced sync.RWMutex + lockServiceInterfaceMockList sync.RWMutex + lockServiceInterfaceMockListNamespaced sync.RWMutex + lockServiceInterfaceMockObjectClient sync.RWMutex + lockServiceInterfaceMockUpdate sync.RWMutex + lockServiceInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ServiceInterfaceMock does implement v11.ServiceInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ServiceInterface = &ServiceInterfaceMock{} + +// ServiceInterfaceMock is a mock implementation of v11.ServiceInterface. +// +// func TestSomethingThatUsesServiceInterface(t *testing.T) { +// +// // make and configure a mocked v11.ServiceInterface +// mockedServiceInterface := &ServiceInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ServiceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ServiceLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ServiceController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Service) (*v1.Service, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Service, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Service, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ServiceList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ServiceList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Service) (*v1.Service, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedServiceInterface in code that requires v11.ServiceInterface +// // and then make assertions. +// +// } +type ServiceInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ServiceHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ServiceLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ServiceController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Service) (*v1.Service, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Service, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Service, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ServiceList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ServiceList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Service) (*v1.Service, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ServiceHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ServiceHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ServiceHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ServiceLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Service + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Service + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ServiceHandlerFunc + } + lockServiceInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ServiceInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ServiceLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ServiceInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ServiceInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockServiceInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ServiceInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle + } + lockServiceInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockServiceInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ServiceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ServiceInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceInterface.AddClusterScopedHandlerCalls()) +func (mock *ServiceInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ServiceHandlerFunc + } + lockServiceInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ServiceInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ServiceLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ServiceInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ServiceInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockServiceInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedServiceInterface.AddClusterScopedLifecycleCalls()) +func (mock *ServiceInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ServiceLifecycle + } + lockServiceInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockServiceInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ServiceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceInterfaceMock.AddFeatureHandlerFunc: method is nil but ServiceInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceInterface.AddFeatureHandlerCalls()) +func (mock *ServiceInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ServiceHandlerFunc + } + lockServiceInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ServiceInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ServiceLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ServiceInterfaceMock.AddFeatureLifecycleFunc: method is nil but ServiceInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockServiceInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockServiceInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceInterface.AddFeatureLifecycleCalls()) +func (mock *ServiceInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ServiceLifecycle + } + lockServiceInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockServiceInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ServiceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceInterfaceMock.AddHandlerFunc: method is nil but ServiceInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ServiceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockServiceInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceInterface.AddHandlerCalls()) +func (mock *ServiceInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ServiceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ServiceHandlerFunc + } + lockServiceInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ServiceInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ServiceLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ServiceInterfaceMock.AddLifecycleFunc: method is nil but ServiceInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockServiceInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockServiceInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedServiceInterface.AddLifecycleCalls()) +func (mock *ServiceInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ServiceLifecycle + } + lockServiceInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockServiceInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ServiceInterfaceMock) Controller() v11.ServiceController { + if mock.ControllerFunc == nil { + panic("ServiceInterfaceMock.ControllerFunc: method is nil but ServiceInterface.Controller was just called") + } + callInfo := struct { + }{} + lockServiceInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockServiceInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedServiceInterface.ControllerCalls()) +func (mock *ServiceInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockServiceInterfaceMockController.RLock() + calls = mock.calls.Controller + lockServiceInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ServiceInterfaceMock) Create(in1 *v1.Service) (*v1.Service, error) { + if mock.CreateFunc == nil { + panic("ServiceInterfaceMock.CreateFunc: method is nil but ServiceInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Service + }{ + In1: in1, + } + lockServiceInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockServiceInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedServiceInterface.CreateCalls()) +func (mock *ServiceInterfaceMock) CreateCalls() []struct { + In1 *v1.Service +} { + var calls []struct { + In1 *v1.Service + } + lockServiceInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockServiceInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ServiceInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ServiceInterfaceMock.DeleteFunc: method is nil but ServiceInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockServiceInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockServiceInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedServiceInterface.DeleteCalls()) +func (mock *ServiceInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockServiceInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockServiceInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ServiceInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ServiceInterfaceMock.DeleteCollectionFunc: method is nil but ServiceInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockServiceInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockServiceInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedServiceInterface.DeleteCollectionCalls()) +func (mock *ServiceInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockServiceInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockServiceInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ServiceInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ServiceInterfaceMock.DeleteNamespacedFunc: method is nil but ServiceInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockServiceInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockServiceInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedServiceInterface.DeleteNamespacedCalls()) +func (mock *ServiceInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockServiceInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockServiceInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ServiceInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Service, error) { + if mock.GetFunc == nil { + panic("ServiceInterfaceMock.GetFunc: method is nil but ServiceInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockServiceInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceInterface.GetCalls()) +func (mock *ServiceInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockServiceInterfaceMockGet.RLock() + calls = mock.calls.Get + lockServiceInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ServiceInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Service, error) { + if mock.GetNamespacedFunc == nil { + panic("ServiceInterfaceMock.GetNamespacedFunc: method is nil but ServiceInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockServiceInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockServiceInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedServiceInterface.GetNamespacedCalls()) +func (mock *ServiceInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockServiceInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockServiceInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceInterfaceMock) List(opts metav1.ListOptions) (*v1.ServiceList, error) { + if mock.ListFunc == nil { + panic("ServiceInterfaceMock.ListFunc: method is nil but ServiceInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceInterface.ListCalls()) +func (mock *ServiceInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceInterfaceMockList.RLock() + calls = mock.calls.List + lockServiceInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ServiceInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceList, error) { + if mock.ListNamespacedFunc == nil { + panic("ServiceInterfaceMock.ListNamespacedFunc: method is nil but ServiceInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockServiceInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockServiceInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedServiceInterface.ListNamespacedCalls()) +func (mock *ServiceInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockServiceInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockServiceInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ServiceInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ServiceInterfaceMock.ObjectClientFunc: method is nil but ServiceInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockServiceInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockServiceInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedServiceInterface.ObjectClientCalls()) +func (mock *ServiceInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockServiceInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockServiceInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ServiceInterfaceMock) Update(in1 *v1.Service) (*v1.Service, error) { + if mock.UpdateFunc == nil { + panic("ServiceInterfaceMock.UpdateFunc: method is nil but ServiceInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Service + }{ + In1: in1, + } + lockServiceInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockServiceInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedServiceInterface.UpdateCalls()) +func (mock *ServiceInterfaceMock) UpdateCalls() []struct { + In1 *v1.Service +} { + var calls []struct { + In1 *v1.Service + } + lockServiceInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockServiceInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ServiceInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ServiceInterfaceMock.WatchFunc: method is nil but ServiceInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockServiceInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedServiceInterface.WatchCalls()) +func (mock *ServiceInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockServiceInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockServicesGetterMockServices sync.RWMutex +) + +// Ensure, that ServicesGetterMock does implement v11.ServicesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ServicesGetter = &ServicesGetterMock{} + +// ServicesGetterMock is a mock implementation of v11.ServicesGetter. +// +// func TestSomethingThatUsesServicesGetter(t *testing.T) { +// +// // make and configure a mocked v11.ServicesGetter +// mockedServicesGetter := &ServicesGetterMock{ +// ServicesFunc: func(namespace string) v11.ServiceInterface { +// panic("mock out the Services method") +// }, +// } +// +// // use mockedServicesGetter in code that requires v11.ServicesGetter +// // and then make assertions. +// +// } +type ServicesGetterMock struct { + // ServicesFunc mocks the Services method. + ServicesFunc func(namespace string) v11.ServiceInterface + + // calls tracks calls to the methods. + calls struct { + // Services holds details about calls to the Services method. + Services []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Services calls ServicesFunc. +func (mock *ServicesGetterMock) Services(namespace string) v11.ServiceInterface { + if mock.ServicesFunc == nil { + panic("ServicesGetterMock.ServicesFunc: method is nil but ServicesGetter.Services was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockServicesGetterMockServices.Lock() + mock.calls.Services = append(mock.calls.Services, callInfo) + lockServicesGetterMockServices.Unlock() + return mock.ServicesFunc(namespace) +} + +// ServicesCalls gets all the calls that were made to Services. +// Check the length with: +// +// len(mockedServicesGetter.ServicesCalls()) +func (mock *ServicesGetterMock) ServicesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockServicesGetterMockServices.RLock() + calls = mock.calls.Services + lockServicesGetterMockServices.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_controller.go new file mode 100644 index 0000000..e5ed7cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ComponentStatusGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ComponentStatus", + } + ComponentStatusResource = metav1.APIResource{ + Name: "componentstatuses", + SingularName: "componentstatus", + Namespaced: false, + Kind: ComponentStatusGroupVersionKind.Kind, + } + + ComponentStatusGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "componentstatuses", + } +) + +func init() { + resource.Put(ComponentStatusGroupVersionResource) +} + +// Deprecated: use v1.ComponentStatus instead +type ComponentStatus = v1.ComponentStatus + +func NewComponentStatus(namespace, name string, obj v1.ComponentStatus) *v1.ComponentStatus { + obj.APIVersion, obj.Kind = ComponentStatusGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ComponentStatusHandlerFunc func(key string, obj *v1.ComponentStatus) (runtime.Object, error) + +type ComponentStatusChangeHandlerFunc func(obj *v1.ComponentStatus) (runtime.Object, error) + +type ComponentStatusLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ComponentStatus, err error) + Get(namespace, name string) (*v1.ComponentStatus, error) +} + +type ComponentStatusController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ComponentStatusLister + AddHandler(ctx context.Context, name string, handler ComponentStatusHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComponentStatusHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ComponentStatusHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ComponentStatusHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ComponentStatusInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ComponentStatus) (*v1.ComponentStatus, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) + Get(name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) + Update(*v1.ComponentStatus) (*v1.ComponentStatus, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ComponentStatusList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ComponentStatusList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ComponentStatusController + AddHandler(ctx context.Context, name string, sync ComponentStatusHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComponentStatusHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ComponentStatusLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ComponentStatusLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ComponentStatusHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ComponentStatusHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ComponentStatusLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ComponentStatusLifecycle) +} + +type componentStatusLister struct { + ns string + controller *componentStatusController +} + +func (l *componentStatusLister) List(namespace string, selector labels.Selector) (ret []*v1.ComponentStatus, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ComponentStatus)) + }) + return +} + +func (l *componentStatusLister) Get(namespace, name string) (*v1.ComponentStatus, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ComponentStatusGroupVersionKind.Group, + Resource: ComponentStatusGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ComponentStatus), nil +} + +type componentStatusController struct { + ns string + controller.GenericController +} + +func (c *componentStatusController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *componentStatusController) Lister() ComponentStatusLister { + return &componentStatusLister{ + ns: c.ns, + controller: c, + } +} + +func (c *componentStatusController) AddHandler(ctx context.Context, name string, handler ComponentStatusHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ComponentStatus); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *componentStatusController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ComponentStatusHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ComponentStatus); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *componentStatusController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ComponentStatusHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ComponentStatus); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *componentStatusController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ComponentStatusHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ComponentStatus); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type componentStatusFactory struct { +} + +func (c componentStatusFactory) Object() runtime.Object { + return &v1.ComponentStatus{} +} + +func (c componentStatusFactory) List() runtime.Object { + return &v1.ComponentStatusList{} +} + +func (s *componentStatusClient) Controller() ComponentStatusController { + genericController := controller.NewGenericController(s.ns, ComponentStatusGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ComponentStatusGroupVersionResource, ComponentStatusGroupVersionKind.Kind, false)) + + return &componentStatusController{ + ns: s.ns, + GenericController: genericController, + } +} + +type componentStatusClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ComponentStatusController +} + +func (s *componentStatusClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *componentStatusClient) Create(o *v1.ComponentStatus) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) Get(name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) Update(o *v1.ComponentStatus) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) UpdateStatus(o *v1.ComponentStatus) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *componentStatusClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *componentStatusClient) List(opts metav1.ListOptions) (*v1.ComponentStatusList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ComponentStatusList), err +} + +func (s *componentStatusClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ComponentStatusList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ComponentStatusList), err +} + +func (s *componentStatusClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *componentStatusClient) Patch(o *v1.ComponentStatus, patchType types.PatchType, data []byte, subresources ...string) (*v1.ComponentStatus, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ComponentStatus), err +} + +func (s *componentStatusClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *componentStatusClient) AddHandler(ctx context.Context, name string, sync ComponentStatusHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *componentStatusClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComponentStatusHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *componentStatusClient) AddLifecycle(ctx context.Context, name string, lifecycle ComponentStatusLifecycle) { + sync := NewComponentStatusLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *componentStatusClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ComponentStatusLifecycle) { + sync := NewComponentStatusLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *componentStatusClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ComponentStatusHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *componentStatusClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ComponentStatusHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *componentStatusClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ComponentStatusLifecycle) { + sync := NewComponentStatusLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *componentStatusClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ComponentStatusLifecycle) { + sync := NewComponentStatusLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_lifecycle_adapter.go new file mode 100644 index 0000000..438a4b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_component_status_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ComponentStatusLifecycle interface { + Create(obj *v1.ComponentStatus) (runtime.Object, error) + Remove(obj *v1.ComponentStatus) (runtime.Object, error) + Updated(obj *v1.ComponentStatus) (runtime.Object, error) +} + +type componentStatusLifecycleAdapter struct { + lifecycle ComponentStatusLifecycle +} + +func (w *componentStatusLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *componentStatusLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *componentStatusLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ComponentStatus)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *componentStatusLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ComponentStatus)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *componentStatusLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ComponentStatus)) + if o == nil { + return nil, err + } + return o, err +} + +func NewComponentStatusLifecycleAdapter(name string, clusterScoped bool, client ComponentStatusInterface, l ComponentStatusLifecycle) ComponentStatusHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ComponentStatusGroupVersionResource) + } + adapter := &componentStatusLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ComponentStatus) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_controller.go new file mode 100644 index 0000000..b900d81 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ConfigMapGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ConfigMap", + } + ConfigMapResource = metav1.APIResource{ + Name: "configmaps", + SingularName: "configmap", + Namespaced: true, + + Kind: ConfigMapGroupVersionKind.Kind, + } + + ConfigMapGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "configmaps", + } +) + +func init() { + resource.Put(ConfigMapGroupVersionResource) +} + +// Deprecated: use v1.ConfigMap instead +type ConfigMap = v1.ConfigMap + +func NewConfigMap(namespace, name string, obj v1.ConfigMap) *v1.ConfigMap { + obj.APIVersion, obj.Kind = ConfigMapGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ConfigMapHandlerFunc func(key string, obj *v1.ConfigMap) (runtime.Object, error) + +type ConfigMapChangeHandlerFunc func(obj *v1.ConfigMap) (runtime.Object, error) + +type ConfigMapLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ConfigMap, err error) + Get(namespace, name string) (*v1.ConfigMap, error) +} + +type ConfigMapController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ConfigMapLister + AddHandler(ctx context.Context, name string, handler ConfigMapHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ConfigMapHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ConfigMapHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ConfigMapHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ConfigMapInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ConfigMap) (*v1.ConfigMap, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) + Get(name string, opts metav1.GetOptions) (*v1.ConfigMap, error) + Update(*v1.ConfigMap) (*v1.ConfigMap, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ConfigMapList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ConfigMapList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ConfigMapController + AddHandler(ctx context.Context, name string, sync ConfigMapHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ConfigMapHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ConfigMapLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ConfigMapLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ConfigMapHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ConfigMapHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ConfigMapLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ConfigMapLifecycle) +} + +type configMapLister struct { + ns string + controller *configMapController +} + +func (l *configMapLister) List(namespace string, selector labels.Selector) (ret []*v1.ConfigMap, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ConfigMap)) + }) + return +} + +func (l *configMapLister) Get(namespace, name string) (*v1.ConfigMap, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ConfigMapGroupVersionKind.Group, + Resource: ConfigMapGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ConfigMap), nil +} + +type configMapController struct { + ns string + controller.GenericController +} + +func (c *configMapController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *configMapController) Lister() ConfigMapLister { + return &configMapLister{ + ns: c.ns, + controller: c, + } +} + +func (c *configMapController) AddHandler(ctx context.Context, name string, handler ConfigMapHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ConfigMap); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *configMapController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ConfigMapHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ConfigMap); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *configMapController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ConfigMapHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ConfigMap); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *configMapController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ConfigMapHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ConfigMap); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type configMapFactory struct { +} + +func (c configMapFactory) Object() runtime.Object { + return &v1.ConfigMap{} +} + +func (c configMapFactory) List() runtime.Object { + return &v1.ConfigMapList{} +} + +func (s *configMapClient) Controller() ConfigMapController { + genericController := controller.NewGenericController(s.ns, ConfigMapGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ConfigMapGroupVersionResource, ConfigMapGroupVersionKind.Kind, true)) + + return &configMapController{ + ns: s.ns, + GenericController: genericController, + } +} + +type configMapClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ConfigMapController +} + +func (s *configMapClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *configMapClient) Create(o *v1.ConfigMap) (*v1.ConfigMap, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) Get(name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) Update(o *v1.ConfigMap) (*v1.ConfigMap, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) UpdateStatus(o *v1.ConfigMap) (*v1.ConfigMap, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *configMapClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *configMapClient) List(opts metav1.ListOptions) (*v1.ConfigMapList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ConfigMapList), err +} + +func (s *configMapClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ConfigMapList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ConfigMapList), err +} + +func (s *configMapClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *configMapClient) Patch(o *v1.ConfigMap, patchType types.PatchType, data []byte, subresources ...string) (*v1.ConfigMap, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ConfigMap), err +} + +func (s *configMapClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *configMapClient) AddHandler(ctx context.Context, name string, sync ConfigMapHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *configMapClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ConfigMapHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *configMapClient) AddLifecycle(ctx context.Context, name string, lifecycle ConfigMapLifecycle) { + sync := NewConfigMapLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *configMapClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ConfigMapLifecycle) { + sync := NewConfigMapLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *configMapClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ConfigMapHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *configMapClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ConfigMapHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *configMapClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ConfigMapLifecycle) { + sync := NewConfigMapLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *configMapClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ConfigMapLifecycle) { + sync := NewConfigMapLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_lifecycle_adapter.go new file mode 100644 index 0000000..9695104 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_config_map_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ConfigMapLifecycle interface { + Create(obj *v1.ConfigMap) (runtime.Object, error) + Remove(obj *v1.ConfigMap) (runtime.Object, error) + Updated(obj *v1.ConfigMap) (runtime.Object, error) +} + +type configMapLifecycleAdapter struct { + lifecycle ConfigMapLifecycle +} + +func (w *configMapLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *configMapLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *configMapLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ConfigMap)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *configMapLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ConfigMap)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *configMapLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ConfigMap)) + if o == nil { + return nil, err + } + return o, err +} + +func NewConfigMapLifecycleAdapter(name string, clusterScoped bool, client ConfigMapInterface, l ConfigMapLifecycle) ConfigMapHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ConfigMapGroupVersionResource) + } + adapter := &configMapLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ConfigMap) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_controller.go new file mode 100644 index 0000000..80dc359 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + EndpointsGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Endpoints", + } + EndpointsResource = metav1.APIResource{ + Name: "endpoints", + SingularName: "endpoints", + Namespaced: true, + + Kind: EndpointsGroupVersionKind.Kind, + } + + EndpointsGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "endpoints", + } +) + +func init() { + resource.Put(EndpointsGroupVersionResource) +} + +// Deprecated: use v1.Endpoints instead +type Endpoints = v1.Endpoints + +func NewEndpoints(namespace, name string, obj v1.Endpoints) *v1.Endpoints { + obj.APIVersion, obj.Kind = EndpointsGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type EndpointsHandlerFunc func(key string, obj *v1.Endpoints) (runtime.Object, error) + +type EndpointsChangeHandlerFunc func(obj *v1.Endpoints) (runtime.Object, error) + +type EndpointsLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Endpoints, err error) + Get(namespace, name string) (*v1.Endpoints, error) +} + +type EndpointsController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() EndpointsLister + AddHandler(ctx context.Context, name string, handler EndpointsHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EndpointsHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler EndpointsHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler EndpointsHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type EndpointsInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Endpoints) (*v1.Endpoints, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Endpoints, error) + Get(name string, opts metav1.GetOptions) (*v1.Endpoints, error) + Update(*v1.Endpoints) (*v1.Endpoints, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.EndpointsList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EndpointsList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() EndpointsController + AddHandler(ctx context.Context, name string, sync EndpointsHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EndpointsHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle EndpointsLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EndpointsLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EndpointsHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EndpointsHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EndpointsLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EndpointsLifecycle) +} + +type endpointsLister struct { + ns string + controller *endpointsController +} + +func (l *endpointsLister) List(namespace string, selector labels.Selector) (ret []*v1.Endpoints, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Endpoints)) + }) + return +} + +func (l *endpointsLister) Get(namespace, name string) (*v1.Endpoints, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: EndpointsGroupVersionKind.Group, + Resource: EndpointsGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Endpoints), nil +} + +type endpointsController struct { + ns string + controller.GenericController +} + +func (c *endpointsController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *endpointsController) Lister() EndpointsLister { + return &endpointsLister{ + ns: c.ns, + controller: c, + } +} + +func (c *endpointsController) AddHandler(ctx context.Context, name string, handler EndpointsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Endpoints); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *endpointsController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler EndpointsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Endpoints); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *endpointsController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler EndpointsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Endpoints); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *endpointsController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler EndpointsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Endpoints); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type endpointsFactory struct { +} + +func (c endpointsFactory) Object() runtime.Object { + return &v1.Endpoints{} +} + +func (c endpointsFactory) List() runtime.Object { + return &v1.EndpointsList{} +} + +func (s *endpointsClient) Controller() EndpointsController { + genericController := controller.NewGenericController(s.ns, EndpointsGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(EndpointsGroupVersionResource, EndpointsGroupVersionKind.Kind, true)) + + return &endpointsController{ + ns: s.ns, + GenericController: genericController, + } +} + +type endpointsClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller EndpointsController +} + +func (s *endpointsClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *endpointsClient) Create(o *v1.Endpoints) (*v1.Endpoints, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) Get(name string, opts metav1.GetOptions) (*v1.Endpoints, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Endpoints, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) Update(o *v1.Endpoints) (*v1.Endpoints, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) UpdateStatus(o *v1.Endpoints) (*v1.Endpoints, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *endpointsClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *endpointsClient) List(opts metav1.ListOptions) (*v1.EndpointsList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.EndpointsList), err +} + +func (s *endpointsClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EndpointsList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.EndpointsList), err +} + +func (s *endpointsClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *endpointsClient) Patch(o *v1.Endpoints, patchType types.PatchType, data []byte, subresources ...string) (*v1.Endpoints, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Endpoints), err +} + +func (s *endpointsClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *endpointsClient) AddHandler(ctx context.Context, name string, sync EndpointsHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *endpointsClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EndpointsHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *endpointsClient) AddLifecycle(ctx context.Context, name string, lifecycle EndpointsLifecycle) { + sync := NewEndpointsLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *endpointsClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EndpointsLifecycle) { + sync := NewEndpointsLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *endpointsClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EndpointsHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *endpointsClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EndpointsHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *endpointsClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EndpointsLifecycle) { + sync := NewEndpointsLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *endpointsClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EndpointsLifecycle) { + sync := NewEndpointsLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_lifecycle_adapter.go new file mode 100644 index 0000000..a01b6f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_endpoints_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type EndpointsLifecycle interface { + Create(obj *v1.Endpoints) (runtime.Object, error) + Remove(obj *v1.Endpoints) (runtime.Object, error) + Updated(obj *v1.Endpoints) (runtime.Object, error) +} + +type endpointsLifecycleAdapter struct { + lifecycle EndpointsLifecycle +} + +func (w *endpointsLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *endpointsLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *endpointsLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Endpoints)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *endpointsLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Endpoints)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *endpointsLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Endpoints)) + if o == nil { + return nil, err + } + return o, err +} + +func NewEndpointsLifecycleAdapter(name string, clusterScoped bool, client EndpointsInterface, l EndpointsLifecycle) EndpointsHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(EndpointsGroupVersionResource) + } + adapter := &endpointsLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Endpoints) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_controller.go new file mode 100644 index 0000000..08935db --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + EventGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Event", + } + EventResource = metav1.APIResource{ + Name: "events", + SingularName: "event", + Namespaced: false, + Kind: EventGroupVersionKind.Kind, + } + + EventGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "events", + } +) + +func init() { + resource.Put(EventGroupVersionResource) +} + +// Deprecated: use v1.Event instead +type Event = v1.Event + +func NewEvent(namespace, name string, obj v1.Event) *v1.Event { + obj.APIVersion, obj.Kind = EventGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type EventHandlerFunc func(key string, obj *v1.Event) (runtime.Object, error) + +type EventChangeHandlerFunc func(obj *v1.Event) (runtime.Object, error) + +type EventLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Event, err error) + Get(namespace, name string) (*v1.Event, error) +} + +type EventController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() EventLister + AddHandler(ctx context.Context, name string, handler EventHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EventHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler EventHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler EventHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type EventInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Event) (*v1.Event, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Event, error) + Get(name string, opts metav1.GetOptions) (*v1.Event, error) + Update(*v1.Event) (*v1.Event, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.EventList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EventList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() EventController + AddHandler(ctx context.Context, name string, sync EventHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EventHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle EventLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EventLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EventHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EventHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EventLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EventLifecycle) +} + +type eventLister struct { + ns string + controller *eventController +} + +func (l *eventLister) List(namespace string, selector labels.Selector) (ret []*v1.Event, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Event)) + }) + return +} + +func (l *eventLister) Get(namespace, name string) (*v1.Event, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: EventGroupVersionKind.Group, + Resource: EventGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Event), nil +} + +type eventController struct { + ns string + controller.GenericController +} + +func (c *eventController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *eventController) Lister() EventLister { + return &eventLister{ + ns: c.ns, + controller: c, + } +} + +func (c *eventController) AddHandler(ctx context.Context, name string, handler EventHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Event); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *eventController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler EventHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Event); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *eventController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler EventHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Event); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *eventController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler EventHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Event); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type eventFactory struct { +} + +func (c eventFactory) Object() runtime.Object { + return &v1.Event{} +} + +func (c eventFactory) List() runtime.Object { + return &v1.EventList{} +} + +func (s *eventClient) Controller() EventController { + genericController := controller.NewGenericController(s.ns, EventGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(EventGroupVersionResource, EventGroupVersionKind.Kind, false)) + + return &eventController{ + ns: s.ns, + GenericController: genericController, + } +} + +type eventClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller EventController +} + +func (s *eventClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *eventClient) Create(o *v1.Event) (*v1.Event, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Event), err +} + +func (s *eventClient) Get(name string, opts metav1.GetOptions) (*v1.Event, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Event), err +} + +func (s *eventClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Event, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Event), err +} + +func (s *eventClient) Update(o *v1.Event) (*v1.Event, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Event), err +} + +func (s *eventClient) UpdateStatus(o *v1.Event) (*v1.Event, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Event), err +} + +func (s *eventClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *eventClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *eventClient) List(opts metav1.ListOptions) (*v1.EventList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.EventList), err +} + +func (s *eventClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.EventList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.EventList), err +} + +func (s *eventClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *eventClient) Patch(o *v1.Event, patchType types.PatchType, data []byte, subresources ...string) (*v1.Event, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Event), err +} + +func (s *eventClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *eventClient) AddHandler(ctx context.Context, name string, sync EventHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *eventClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EventHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *eventClient) AddLifecycle(ctx context.Context, name string, lifecycle EventLifecycle) { + sync := NewEventLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *eventClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EventLifecycle) { + sync := NewEventLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *eventClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EventHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *eventClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EventHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *eventClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EventLifecycle) { + sync := NewEventLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *eventClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EventLifecycle) { + sync := NewEventLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_lifecycle_adapter.go new file mode 100644 index 0000000..3f5fd4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_event_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type EventLifecycle interface { + Create(obj *v1.Event) (runtime.Object, error) + Remove(obj *v1.Event) (runtime.Object, error) + Updated(obj *v1.Event) (runtime.Object, error) +} + +type eventLifecycleAdapter struct { + lifecycle EventLifecycle +} + +func (w *eventLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *eventLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *eventLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Event)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *eventLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Event)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *eventLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Event)) + if o == nil { + return nil, err + } + return o, err +} + +func NewEventLifecycleAdapter(name string, clusterScoped bool, client EventInterface, l EventLifecycle) EventHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(EventGroupVersionResource) + } + adapter := &eventLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Event) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..f87c578 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_k8s_client.go @@ -0,0 +1,258 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + NodesGetter + ComponentStatusesGetter + NamespacesGetter + EventsGetter + EndpointsGetter + PersistentVolumeClaimsGetter + PodsGetter + ServicesGetter + SecretsGetter + ConfigMapsGetter + ServiceAccountsGetter + ReplicationControllersGetter + ResourceQuotasGetter + LimitRangesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type NodesGetter interface { + Nodes(namespace string) NodeInterface +} + +func (c *Client) Nodes(namespace string) NodeInterface { + sharedClient := c.clientFactory.ForResourceKind(NodeGroupVersionResource, NodeGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NodeResource, NodeGroupVersionKind, nodeFactory{}) + return &nodeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ComponentStatusesGetter interface { + ComponentStatuses(namespace string) ComponentStatusInterface +} + +func (c *Client) ComponentStatuses(namespace string) ComponentStatusInterface { + sharedClient := c.clientFactory.ForResourceKind(ComponentStatusGroupVersionResource, ComponentStatusGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ComponentStatusResource, ComponentStatusGroupVersionKind, componentStatusFactory{}) + return &componentStatusClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacesGetter interface { + Namespaces(namespace string) NamespaceInterface +} + +func (c *Client) Namespaces(namespace string) NamespaceInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespaceGroupVersionResource, NamespaceGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespaceResource, NamespaceGroupVersionKind, namespaceFactory{}) + return &namespaceClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type EventsGetter interface { + Events(namespace string) EventInterface +} + +func (c *Client) Events(namespace string) EventInterface { + sharedClient := c.clientFactory.ForResourceKind(EventGroupVersionResource, EventGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &EventResource, EventGroupVersionKind, eventFactory{}) + return &eventClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type EndpointsGetter interface { + Endpoints(namespace string) EndpointsInterface +} + +func (c *Client) Endpoints(namespace string) EndpointsInterface { + sharedClient := c.clientFactory.ForResourceKind(EndpointsGroupVersionResource, EndpointsGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &EndpointsResource, EndpointsGroupVersionKind, endpointsFactory{}) + return &endpointsClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PersistentVolumeClaimsGetter interface { + PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface +} + +func (c *Client) PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface { + sharedClient := c.clientFactory.ForResourceKind(PersistentVolumeClaimGroupVersionResource, PersistentVolumeClaimGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &PersistentVolumeClaimResource, PersistentVolumeClaimGroupVersionKind, persistentVolumeClaimFactory{}) + return &persistentVolumeClaimClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PodsGetter interface { + Pods(namespace string) PodInterface +} + +func (c *Client) Pods(namespace string) PodInterface { + sharedClient := c.clientFactory.ForResourceKind(PodGroupVersionResource, PodGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &PodResource, PodGroupVersionKind, podFactory{}) + return &podClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ServicesGetter interface { + Services(namespace string) ServiceInterface +} + +func (c *Client) Services(namespace string) ServiceInterface { + sharedClient := c.clientFactory.ForResourceKind(ServiceGroupVersionResource, ServiceGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ServiceResource, ServiceGroupVersionKind, serviceFactory{}) + return &serviceClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type SecretsGetter interface { + Secrets(namespace string) SecretInterface +} + +func (c *Client) Secrets(namespace string) SecretInterface { + sharedClient := c.clientFactory.ForResourceKind(SecretGroupVersionResource, SecretGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &SecretResource, SecretGroupVersionKind, secretFactory{}) + return &secretClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ConfigMapsGetter interface { + ConfigMaps(namespace string) ConfigMapInterface +} + +func (c *Client) ConfigMaps(namespace string) ConfigMapInterface { + sharedClient := c.clientFactory.ForResourceKind(ConfigMapGroupVersionResource, ConfigMapGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ConfigMapResource, ConfigMapGroupVersionKind, configMapFactory{}) + return &configMapClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ServiceAccountsGetter interface { + ServiceAccounts(namespace string) ServiceAccountInterface +} + +func (c *Client) ServiceAccounts(namespace string) ServiceAccountInterface { + sharedClient := c.clientFactory.ForResourceKind(ServiceAccountGroupVersionResource, ServiceAccountGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ServiceAccountResource, ServiceAccountGroupVersionKind, serviceAccountFactory{}) + return &serviceAccountClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ReplicationControllersGetter interface { + ReplicationControllers(namespace string) ReplicationControllerInterface +} + +func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { + sharedClient := c.clientFactory.ForResourceKind(ReplicationControllerGroupVersionResource, ReplicationControllerGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ReplicationControllerResource, ReplicationControllerGroupVersionKind, replicationControllerFactory{}) + return &replicationControllerClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ResourceQuotasGetter interface { + ResourceQuotas(namespace string) ResourceQuotaInterface +} + +func (c *Client) ResourceQuotas(namespace string) ResourceQuotaInterface { + sharedClient := c.clientFactory.ForResourceKind(ResourceQuotaGroupVersionResource, ResourceQuotaGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ResourceQuotaResource, ResourceQuotaGroupVersionKind, resourceQuotaFactory{}) + return &resourceQuotaClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type LimitRangesGetter interface { + LimitRanges(namespace string) LimitRangeInterface +} + +func (c *Client) LimitRanges(namespace string) LimitRangeInterface { + sharedClient := c.clientFactory.ForResourceKind(LimitRangeGroupVersionResource, LimitRangeGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &LimitRangeResource, LimitRangeGroupVersionKind, limitRangeFactory{}) + return &limitRangeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_controller.go new file mode 100644 index 0000000..9cf63a9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + LimitRangeGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "LimitRange", + } + LimitRangeResource = metav1.APIResource{ + Name: "limitranges", + SingularName: "limitrange", + Namespaced: true, + + Kind: LimitRangeGroupVersionKind.Kind, + } + + LimitRangeGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "limitranges", + } +) + +func init() { + resource.Put(LimitRangeGroupVersionResource) +} + +// Deprecated: use v1.LimitRange instead +type LimitRange = v1.LimitRange + +func NewLimitRange(namespace, name string, obj v1.LimitRange) *v1.LimitRange { + obj.APIVersion, obj.Kind = LimitRangeGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type LimitRangeHandlerFunc func(key string, obj *v1.LimitRange) (runtime.Object, error) + +type LimitRangeChangeHandlerFunc func(obj *v1.LimitRange) (runtime.Object, error) + +type LimitRangeLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.LimitRange, err error) + Get(namespace, name string) (*v1.LimitRange, error) +} + +type LimitRangeController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() LimitRangeLister + AddHandler(ctx context.Context, name string, handler LimitRangeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LimitRangeHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler LimitRangeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler LimitRangeHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type LimitRangeInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.LimitRange) (*v1.LimitRange, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.LimitRange, error) + Get(name string, opts metav1.GetOptions) (*v1.LimitRange, error) + Update(*v1.LimitRange) (*v1.LimitRange, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.LimitRangeList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.LimitRangeList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() LimitRangeController + AddHandler(ctx context.Context, name string, sync LimitRangeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LimitRangeHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle LimitRangeLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle LimitRangeLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync LimitRangeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync LimitRangeHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle LimitRangeLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle LimitRangeLifecycle) +} + +type limitRangeLister struct { + ns string + controller *limitRangeController +} + +func (l *limitRangeLister) List(namespace string, selector labels.Selector) (ret []*v1.LimitRange, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.LimitRange)) + }) + return +} + +func (l *limitRangeLister) Get(namespace, name string) (*v1.LimitRange, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: LimitRangeGroupVersionKind.Group, + Resource: LimitRangeGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.LimitRange), nil +} + +type limitRangeController struct { + ns string + controller.GenericController +} + +func (c *limitRangeController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *limitRangeController) Lister() LimitRangeLister { + return &limitRangeLister{ + ns: c.ns, + controller: c, + } +} + +func (c *limitRangeController) AddHandler(ctx context.Context, name string, handler LimitRangeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.LimitRange); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *limitRangeController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler LimitRangeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.LimitRange); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *limitRangeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler LimitRangeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.LimitRange); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *limitRangeController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler LimitRangeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.LimitRange); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type limitRangeFactory struct { +} + +func (c limitRangeFactory) Object() runtime.Object { + return &v1.LimitRange{} +} + +func (c limitRangeFactory) List() runtime.Object { + return &v1.LimitRangeList{} +} + +func (s *limitRangeClient) Controller() LimitRangeController { + genericController := controller.NewGenericController(s.ns, LimitRangeGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(LimitRangeGroupVersionResource, LimitRangeGroupVersionKind.Kind, true)) + + return &limitRangeController{ + ns: s.ns, + GenericController: genericController, + } +} + +type limitRangeClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller LimitRangeController +} + +func (s *limitRangeClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *limitRangeClient) Create(o *v1.LimitRange) (*v1.LimitRange, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) Get(name string, opts metav1.GetOptions) (*v1.LimitRange, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.LimitRange, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) Update(o *v1.LimitRange) (*v1.LimitRange, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) UpdateStatus(o *v1.LimitRange) (*v1.LimitRange, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *limitRangeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *limitRangeClient) List(opts metav1.ListOptions) (*v1.LimitRangeList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.LimitRangeList), err +} + +func (s *limitRangeClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.LimitRangeList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.LimitRangeList), err +} + +func (s *limitRangeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *limitRangeClient) Patch(o *v1.LimitRange, patchType types.PatchType, data []byte, subresources ...string) (*v1.LimitRange, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.LimitRange), err +} + +func (s *limitRangeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *limitRangeClient) AddHandler(ctx context.Context, name string, sync LimitRangeHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *limitRangeClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LimitRangeHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *limitRangeClient) AddLifecycle(ctx context.Context, name string, lifecycle LimitRangeLifecycle) { + sync := NewLimitRangeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *limitRangeClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle LimitRangeLifecycle) { + sync := NewLimitRangeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *limitRangeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync LimitRangeHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *limitRangeClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync LimitRangeHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *limitRangeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle LimitRangeLifecycle) { + sync := NewLimitRangeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *limitRangeClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle LimitRangeLifecycle) { + sync := NewLimitRangeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_lifecycle_adapter.go new file mode 100644 index 0000000..6769053 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_limit_range_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type LimitRangeLifecycle interface { + Create(obj *v1.LimitRange) (runtime.Object, error) + Remove(obj *v1.LimitRange) (runtime.Object, error) + Updated(obj *v1.LimitRange) (runtime.Object, error) +} + +type limitRangeLifecycleAdapter struct { + lifecycle LimitRangeLifecycle +} + +func (w *limitRangeLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *limitRangeLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *limitRangeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.LimitRange)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *limitRangeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.LimitRange)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *limitRangeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.LimitRange)) + if o == nil { + return nil, err + } + return o, err +} + +func NewLimitRangeLifecycleAdapter(name string, clusterScoped bool, client LimitRangeInterface, l LimitRangeLifecycle) LimitRangeHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(LimitRangeGroupVersionResource) + } + adapter := &limitRangeLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.LimitRange) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_controller.go new file mode 100644 index 0000000..5890ed0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespaceGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Namespace", + } + NamespaceResource = metav1.APIResource{ + Name: "namespaces", + SingularName: "namespace", + Namespaced: false, + Kind: NamespaceGroupVersionKind.Kind, + } + + NamespaceGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespaces", + } +) + +func init() { + resource.Put(NamespaceGroupVersionResource) +} + +// Deprecated: use v1.Namespace instead +type Namespace = v1.Namespace + +func NewNamespace(namespace, name string, obj v1.Namespace) *v1.Namespace { + obj.APIVersion, obj.Kind = NamespaceGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespaceHandlerFunc func(key string, obj *v1.Namespace) (runtime.Object, error) + +type NamespaceChangeHandlerFunc func(obj *v1.Namespace) (runtime.Object, error) + +type NamespaceLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Namespace, err error) + Get(namespace, name string) (*v1.Namespace, error) +} + +type NamespaceController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespaceLister + AddHandler(ctx context.Context, name string, handler NamespaceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespaceHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespaceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespaceHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespaceInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Namespace) (*v1.Namespace, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Namespace, error) + Get(name string, opts metav1.GetOptions) (*v1.Namespace, error) + Update(*v1.Namespace) (*v1.Namespace, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.NamespaceList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NamespaceList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespaceController + AddHandler(ctx context.Context, name string, sync NamespaceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespaceHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespaceLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespaceLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespaceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespaceHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespaceLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespaceLifecycle) +} + +type namespaceLister struct { + ns string + controller *namespaceController +} + +func (l *namespaceLister) List(namespace string, selector labels.Selector) (ret []*v1.Namespace, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Namespace)) + }) + return +} + +func (l *namespaceLister) Get(namespace, name string) (*v1.Namespace, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespaceGroupVersionKind.Group, + Resource: NamespaceGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Namespace), nil +} + +type namespaceController struct { + ns string + controller.GenericController +} + +func (c *namespaceController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespaceController) Lister() NamespaceLister { + return &namespaceLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespaceController) AddHandler(ctx context.Context, name string, handler NamespaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Namespace); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespaceController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Namespace); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespaceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Namespace); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespaceController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Namespace); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespaceFactory struct { +} + +func (c namespaceFactory) Object() runtime.Object { + return &v1.Namespace{} +} + +func (c namespaceFactory) List() runtime.Object { + return &v1.NamespaceList{} +} + +func (s *namespaceClient) Controller() NamespaceController { + genericController := controller.NewGenericController(s.ns, NamespaceGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespaceGroupVersionResource, NamespaceGroupVersionKind.Kind, false)) + + return &namespaceController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespaceClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespaceController +} + +func (s *namespaceClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespaceClient) Create(o *v1.Namespace) (*v1.Namespace, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) Get(name string, opts metav1.GetOptions) (*v1.Namespace, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Namespace, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) Update(o *v1.Namespace) (*v1.Namespace, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) UpdateStatus(o *v1.Namespace) (*v1.Namespace, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespaceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespaceClient) List(opts metav1.ListOptions) (*v1.NamespaceList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.NamespaceList), err +} + +func (s *namespaceClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NamespaceList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.NamespaceList), err +} + +func (s *namespaceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespaceClient) Patch(o *v1.Namespace, patchType types.PatchType, data []byte, subresources ...string) (*v1.Namespace, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Namespace), err +} + +func (s *namespaceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespaceClient) AddHandler(ctx context.Context, name string, sync NamespaceHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespaceClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespaceHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespaceClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespaceLifecycle) { + sync := NewNamespaceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespaceClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespaceLifecycle) { + sync := NewNamespaceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespaceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespaceHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespaceClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespaceHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespaceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespaceLifecycle) { + sync := NewNamespaceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespaceClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespaceLifecycle) { + sync := NewNamespaceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_lifecycle_adapter.go new file mode 100644 index 0000000..cfaca12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_namespace_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespaceLifecycle interface { + Create(obj *v1.Namespace) (runtime.Object, error) + Remove(obj *v1.Namespace) (runtime.Object, error) + Updated(obj *v1.Namespace) (runtime.Object, error) +} + +type namespaceLifecycleAdapter struct { + lifecycle NamespaceLifecycle +} + +func (w *namespaceLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespaceLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespaceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Namespace)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespaceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Namespace)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespaceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Namespace)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespaceLifecycleAdapter(name string, clusterScoped bool, client NamespaceInterface, l NamespaceLifecycle) NamespaceHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespaceGroupVersionResource) + } + adapter := &namespaceLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Namespace) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_controller.go new file mode 100644 index 0000000..bb22c62 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NodeGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Node", + } + NodeResource = metav1.APIResource{ + Name: "nodes", + SingularName: "node", + Namespaced: false, + Kind: NodeGroupVersionKind.Kind, + } + + NodeGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "nodes", + } +) + +func init() { + resource.Put(NodeGroupVersionResource) +} + +// Deprecated: use v1.Node instead +type Node = v1.Node + +func NewNode(namespace, name string, obj v1.Node) *v1.Node { + obj.APIVersion, obj.Kind = NodeGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NodeHandlerFunc func(key string, obj *v1.Node) (runtime.Object, error) + +type NodeChangeHandlerFunc func(obj *v1.Node) (runtime.Object, error) + +type NodeLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Node, err error) + Get(namespace, name string) (*v1.Node, error) +} + +type NodeController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NodeLister + AddHandler(ctx context.Context, name string, handler NodeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NodeHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NodeInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Node) (*v1.Node, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Node, error) + Get(name string, opts metav1.GetOptions) (*v1.Node, error) + Update(*v1.Node) (*v1.Node, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.NodeList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NodeList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NodeController + AddHandler(ctx context.Context, name string, sync NodeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeLifecycle) +} + +type nodeLister struct { + ns string + controller *nodeController +} + +func (l *nodeLister) List(namespace string, selector labels.Selector) (ret []*v1.Node, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Node)) + }) + return +} + +func (l *nodeLister) Get(namespace, name string) (*v1.Node, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NodeGroupVersionKind.Group, + Resource: NodeGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Node), nil +} + +type nodeController struct { + ns string + controller.GenericController +} + +func (c *nodeController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *nodeController) Lister() NodeLister { + return &nodeLister{ + ns: c.ns, + controller: c, + } +} + +func (c *nodeController) AddHandler(ctx context.Context, name string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Node); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Node); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Node); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Node); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type nodeFactory struct { +} + +func (c nodeFactory) Object() runtime.Object { + return &v1.Node{} +} + +func (c nodeFactory) List() runtime.Object { + return &v1.NodeList{} +} + +func (s *nodeClient) Controller() NodeController { + genericController := controller.NewGenericController(s.ns, NodeGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NodeGroupVersionResource, NodeGroupVersionKind.Kind, false)) + + return &nodeController{ + ns: s.ns, + GenericController: genericController, + } +} + +type nodeClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NodeController +} + +func (s *nodeClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *nodeClient) Create(o *v1.Node) (*v1.Node, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Node), err +} + +func (s *nodeClient) Get(name string, opts metav1.GetOptions) (*v1.Node, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Node), err +} + +func (s *nodeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Node, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Node), err +} + +func (s *nodeClient) Update(o *v1.Node) (*v1.Node, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Node), err +} + +func (s *nodeClient) UpdateStatus(o *v1.Node) (*v1.Node, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Node), err +} + +func (s *nodeClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *nodeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *nodeClient) List(opts metav1.ListOptions) (*v1.NodeList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.NodeList), err +} + +func (s *nodeClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NodeList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.NodeList), err +} + +func (s *nodeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *nodeClient) Patch(o *v1.Node, patchType types.PatchType, data []byte, subresources ...string) (*v1.Node, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Node), err +} + +func (s *nodeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *nodeClient) AddHandler(ctx context.Context, name string, sync NodeHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeClient) AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_lifecycle_adapter.go new file mode 100644 index 0000000..88ca9ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_node_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type NodeLifecycle interface { + Create(obj *v1.Node) (runtime.Object, error) + Remove(obj *v1.Node) (runtime.Object, error) + Updated(obj *v1.Node) (runtime.Object, error) +} + +type nodeLifecycleAdapter struct { + lifecycle NodeLifecycle +} + +func (w *nodeLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *nodeLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *nodeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNodeLifecycleAdapter(name string, clusterScoped bool, client NodeInterface, l NodeLifecycle) NodeHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NodeGroupVersionResource) + } + adapter := &nodeLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Node) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_controller.go new file mode 100644 index 0000000..7f30310 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + PersistentVolumeClaimGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "PersistentVolumeClaim", + } + PersistentVolumeClaimResource = metav1.APIResource{ + Name: "persistentvolumeclaims", + SingularName: "persistentvolumeclaim", + Namespaced: true, + + Kind: PersistentVolumeClaimGroupVersionKind.Kind, + } + + PersistentVolumeClaimGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "persistentvolumeclaims", + } +) + +func init() { + resource.Put(PersistentVolumeClaimGroupVersionResource) +} + +// Deprecated: use v1.PersistentVolumeClaim instead +type PersistentVolumeClaim = v1.PersistentVolumeClaim + +func NewPersistentVolumeClaim(namespace, name string, obj v1.PersistentVolumeClaim) *v1.PersistentVolumeClaim { + obj.APIVersion, obj.Kind = PersistentVolumeClaimGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type PersistentVolumeClaimHandlerFunc func(key string, obj *v1.PersistentVolumeClaim) (runtime.Object, error) + +type PersistentVolumeClaimChangeHandlerFunc func(obj *v1.PersistentVolumeClaim) (runtime.Object, error) + +type PersistentVolumeClaimLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) + Get(namespace, name string) (*v1.PersistentVolumeClaim, error) +} + +type PersistentVolumeClaimController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() PersistentVolumeClaimLister + AddHandler(ctx context.Context, name string, handler PersistentVolumeClaimHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PersistentVolumeClaimHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PersistentVolumeClaimHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler PersistentVolumeClaimHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type PersistentVolumeClaimInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) + Get(name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) + Update(*v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() PersistentVolumeClaimController + AddHandler(ctx context.Context, name string, sync PersistentVolumeClaimHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PersistentVolumeClaimHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle PersistentVolumeClaimLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PersistentVolumeClaimLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PersistentVolumeClaimHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PersistentVolumeClaimHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PersistentVolumeClaimLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PersistentVolumeClaimLifecycle) +} + +type persistentVolumeClaimLister struct { + ns string + controller *persistentVolumeClaimController +} + +func (l *persistentVolumeClaimLister) List(namespace string, selector labels.Selector) (ret []*v1.PersistentVolumeClaim, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.PersistentVolumeClaim)) + }) + return +} + +func (l *persistentVolumeClaimLister) Get(namespace, name string) (*v1.PersistentVolumeClaim, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: PersistentVolumeClaimGroupVersionKind.Group, + Resource: PersistentVolumeClaimGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.PersistentVolumeClaim), nil +} + +type persistentVolumeClaimController struct { + ns string + controller.GenericController +} + +func (c *persistentVolumeClaimController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *persistentVolumeClaimController) Lister() PersistentVolumeClaimLister { + return &persistentVolumeClaimLister{ + ns: c.ns, + controller: c, + } +} + +func (c *persistentVolumeClaimController) AddHandler(ctx context.Context, name string, handler PersistentVolumeClaimHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.PersistentVolumeClaim); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *persistentVolumeClaimController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler PersistentVolumeClaimHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.PersistentVolumeClaim); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *persistentVolumeClaimController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PersistentVolumeClaimHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.PersistentVolumeClaim); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *persistentVolumeClaimController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler PersistentVolumeClaimHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.PersistentVolumeClaim); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type persistentVolumeClaimFactory struct { +} + +func (c persistentVolumeClaimFactory) Object() runtime.Object { + return &v1.PersistentVolumeClaim{} +} + +func (c persistentVolumeClaimFactory) List() runtime.Object { + return &v1.PersistentVolumeClaimList{} +} + +func (s *persistentVolumeClaimClient) Controller() PersistentVolumeClaimController { + genericController := controller.NewGenericController(s.ns, PersistentVolumeClaimGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(PersistentVolumeClaimGroupVersionResource, PersistentVolumeClaimGroupVersionKind.Kind, true)) + + return &persistentVolumeClaimController{ + ns: s.ns, + GenericController: genericController, + } +} + +type persistentVolumeClaimClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller PersistentVolumeClaimController +} + +func (s *persistentVolumeClaimClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *persistentVolumeClaimClient) Create(o *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) Get(name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) Update(o *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) UpdateStatus(o *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *persistentVolumeClaimClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *persistentVolumeClaimClient) List(opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.PersistentVolumeClaimList), err +} + +func (s *persistentVolumeClaimClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PersistentVolumeClaimList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.PersistentVolumeClaimList), err +} + +func (s *persistentVolumeClaimClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *persistentVolumeClaimClient) Patch(o *v1.PersistentVolumeClaim, patchType types.PatchType, data []byte, subresources ...string) (*v1.PersistentVolumeClaim, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.PersistentVolumeClaim), err +} + +func (s *persistentVolumeClaimClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *persistentVolumeClaimClient) AddHandler(ctx context.Context, name string, sync PersistentVolumeClaimHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *persistentVolumeClaimClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PersistentVolumeClaimHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *persistentVolumeClaimClient) AddLifecycle(ctx context.Context, name string, lifecycle PersistentVolumeClaimLifecycle) { + sync := NewPersistentVolumeClaimLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *persistentVolumeClaimClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PersistentVolumeClaimLifecycle) { + sync := NewPersistentVolumeClaimLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *persistentVolumeClaimClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PersistentVolumeClaimHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *persistentVolumeClaimClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PersistentVolumeClaimHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *persistentVolumeClaimClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PersistentVolumeClaimLifecycle) { + sync := NewPersistentVolumeClaimLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *persistentVolumeClaimClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PersistentVolumeClaimLifecycle) { + sync := NewPersistentVolumeClaimLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_lifecycle_adapter.go new file mode 100644 index 0000000..ef6cdea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_persistent_volume_claim_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type PersistentVolumeClaimLifecycle interface { + Create(obj *v1.PersistentVolumeClaim) (runtime.Object, error) + Remove(obj *v1.PersistentVolumeClaim) (runtime.Object, error) + Updated(obj *v1.PersistentVolumeClaim) (runtime.Object, error) +} + +type persistentVolumeClaimLifecycleAdapter struct { + lifecycle PersistentVolumeClaimLifecycle +} + +func (w *persistentVolumeClaimLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *persistentVolumeClaimLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *persistentVolumeClaimLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.PersistentVolumeClaim)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *persistentVolumeClaimLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.PersistentVolumeClaim)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *persistentVolumeClaimLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.PersistentVolumeClaim)) + if o == nil { + return nil, err + } + return o, err +} + +func NewPersistentVolumeClaimLifecycleAdapter(name string, clusterScoped bool, client PersistentVolumeClaimInterface, l PersistentVolumeClaimLifecycle) PersistentVolumeClaimHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(PersistentVolumeClaimGroupVersionResource) + } + adapter := &persistentVolumeClaimLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.PersistentVolumeClaim) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_controller.go new file mode 100644 index 0000000..6b2258c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + PodGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Pod", + } + PodResource = metav1.APIResource{ + Name: "pods", + SingularName: "pod", + Namespaced: true, + + Kind: PodGroupVersionKind.Kind, + } + + PodGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "pods", + } +) + +func init() { + resource.Put(PodGroupVersionResource) +} + +// Deprecated: use v1.Pod instead +type Pod = v1.Pod + +func NewPod(namespace, name string, obj v1.Pod) *v1.Pod { + obj.APIVersion, obj.Kind = PodGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type PodHandlerFunc func(key string, obj *v1.Pod) (runtime.Object, error) + +type PodChangeHandlerFunc func(obj *v1.Pod) (runtime.Object, error) + +type PodLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Pod, err error) + Get(namespace, name string) (*v1.Pod, error) +} + +type PodController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() PodLister + AddHandler(ctx context.Context, name string, handler PodHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PodHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler PodHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type PodInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Pod) (*v1.Pod, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error) + Get(name string, opts metav1.GetOptions) (*v1.Pod, error) + Update(*v1.Pod) (*v1.Pod, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.PodList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PodList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() PodController + AddHandler(ctx context.Context, name string, sync PodHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle PodLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PodLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PodHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PodLifecycle) +} + +type podLister struct { + ns string + controller *podController +} + +func (l *podLister) List(namespace string, selector labels.Selector) (ret []*v1.Pod, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Pod)) + }) + return +} + +func (l *podLister) Get(namespace, name string) (*v1.Pod, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: PodGroupVersionKind.Group, + Resource: PodGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Pod), nil +} + +type podController struct { + ns string + controller.GenericController +} + +func (c *podController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *podController) Lister() PodLister { + return &podLister{ + ns: c.ns, + controller: c, + } +} + +func (c *podController) AddHandler(ctx context.Context, name string, handler PodHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Pod); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler PodHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Pod); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PodHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Pod); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler PodHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Pod); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type podFactory struct { +} + +func (c podFactory) Object() runtime.Object { + return &v1.Pod{} +} + +func (c podFactory) List() runtime.Object { + return &v1.PodList{} +} + +func (s *podClient) Controller() PodController { + genericController := controller.NewGenericController(s.ns, PodGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(PodGroupVersionResource, PodGroupVersionKind.Kind, true)) + + return &podController{ + ns: s.ns, + GenericController: genericController, + } +} + +type podClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller PodController +} + +func (s *podClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *podClient) Create(o *v1.Pod) (*v1.Pod, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Pod), err +} + +func (s *podClient) Get(name string, opts metav1.GetOptions) (*v1.Pod, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Pod), err +} + +func (s *podClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Pod, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Pod), err +} + +func (s *podClient) Update(o *v1.Pod) (*v1.Pod, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Pod), err +} + +func (s *podClient) UpdateStatus(o *v1.Pod) (*v1.Pod, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Pod), err +} + +func (s *podClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *podClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *podClient) List(opts metav1.ListOptions) (*v1.PodList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.PodList), err +} + +func (s *podClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.PodList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.PodList), err +} + +func (s *podClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *podClient) Patch(o *v1.Pod, patchType types.PatchType, data []byte, subresources ...string) (*v1.Pod, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Pod), err +} + +func (s *podClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *podClient) AddHandler(ctx context.Context, name string, sync PodHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *podClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *podClient) AddLifecycle(ctx context.Context, name string, lifecycle PodLifecycle) { + sync := NewPodLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *podClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PodLifecycle) { + sync := NewPodLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *podClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *podClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PodHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *podClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodLifecycle) { + sync := NewPodLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *podClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PodLifecycle) { + sync := NewPodLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_lifecycle_adapter.go new file mode 100644 index 0000000..30710fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_pod_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type PodLifecycle interface { + Create(obj *v1.Pod) (runtime.Object, error) + Remove(obj *v1.Pod) (runtime.Object, error) + Updated(obj *v1.Pod) (runtime.Object, error) +} + +type podLifecycleAdapter struct { + lifecycle PodLifecycle +} + +func (w *podLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *podLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *podLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Pod)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *podLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Pod)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *podLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Pod)) + if o == nil { + return nil, err + } + return o, err +} + +func NewPodLifecycleAdapter(name string, clusterScoped bool, client PodInterface, l PodLifecycle) PodHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(PodGroupVersionResource) + } + adapter := &podLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Pod) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_controller.go new file mode 100644 index 0000000..e0936b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ReplicationControllerGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ReplicationController", + } + ReplicationControllerResource = metav1.APIResource{ + Name: "replicationcontrollers", + SingularName: "replicationcontroller", + Namespaced: true, + + Kind: ReplicationControllerGroupVersionKind.Kind, + } + + ReplicationControllerGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "replicationcontrollers", + } +) + +func init() { + resource.Put(ReplicationControllerGroupVersionResource) +} + +// Deprecated: use v1.ReplicationController instead +type ReplicationController = v1.ReplicationController + +func NewReplicationController(namespace, name string, obj v1.ReplicationController) *v1.ReplicationController { + obj.APIVersion, obj.Kind = ReplicationControllerGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ReplicationControllerHandlerFunc func(key string, obj *v1.ReplicationController) (runtime.Object, error) + +type ReplicationControllerChangeHandlerFunc func(obj *v1.ReplicationController) (runtime.Object, error) + +type ReplicationControllerLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ReplicationController, err error) + Get(namespace, name string) (*v1.ReplicationController, error) +} + +type ReplicationControllerController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ReplicationControllerLister + AddHandler(ctx context.Context, name string, handler ReplicationControllerHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicationControllerHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ReplicationControllerHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ReplicationControllerHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ReplicationControllerInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ReplicationController) (*v1.ReplicationController, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ReplicationController, error) + Get(name string, opts metav1.GetOptions) (*v1.ReplicationController, error) + Update(*v1.ReplicationController) (*v1.ReplicationController, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicationControllerList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ReplicationControllerController + AddHandler(ctx context.Context, name string, sync ReplicationControllerHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicationControllerHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ReplicationControllerLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ReplicationControllerLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ReplicationControllerHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ReplicationControllerHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ReplicationControllerLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ReplicationControllerLifecycle) +} + +type replicationControllerLister struct { + ns string + controller *replicationControllerController +} + +func (l *replicationControllerLister) List(namespace string, selector labels.Selector) (ret []*v1.ReplicationController, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ReplicationController)) + }) + return +} + +func (l *replicationControllerLister) Get(namespace, name string) (*v1.ReplicationController, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ReplicationControllerGroupVersionKind.Group, + Resource: ReplicationControllerGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ReplicationController), nil +} + +type replicationControllerController struct { + ns string + controller.GenericController +} + +func (c *replicationControllerController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *replicationControllerController) Lister() ReplicationControllerLister { + return &replicationControllerLister{ + ns: c.ns, + controller: c, + } +} + +func (c *replicationControllerController) AddHandler(ctx context.Context, name string, handler ReplicationControllerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicationController); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicationControllerController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ReplicationControllerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicationController); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicationControllerController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ReplicationControllerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicationController); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *replicationControllerController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ReplicationControllerHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ReplicationController); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type replicationControllerFactory struct { +} + +func (c replicationControllerFactory) Object() runtime.Object { + return &v1.ReplicationController{} +} + +func (c replicationControllerFactory) List() runtime.Object { + return &v1.ReplicationControllerList{} +} + +func (s *replicationControllerClient) Controller() ReplicationControllerController { + genericController := controller.NewGenericController(s.ns, ReplicationControllerGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ReplicationControllerGroupVersionResource, ReplicationControllerGroupVersionKind.Kind, true)) + + return &replicationControllerController{ + ns: s.ns, + GenericController: genericController, + } +} + +type replicationControllerClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ReplicationControllerController +} + +func (s *replicationControllerClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *replicationControllerClient) Create(o *v1.ReplicationController) (*v1.ReplicationController, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) Get(name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ReplicationController, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) Update(o *v1.ReplicationController) (*v1.ReplicationController, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) UpdateStatus(o *v1.ReplicationController) (*v1.ReplicationController, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *replicationControllerClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *replicationControllerClient) List(opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ReplicationControllerList), err +} + +func (s *replicationControllerClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ReplicationControllerList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ReplicationControllerList), err +} + +func (s *replicationControllerClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *replicationControllerClient) Patch(o *v1.ReplicationController, patchType types.PatchType, data []byte, subresources ...string) (*v1.ReplicationController, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ReplicationController), err +} + +func (s *replicationControllerClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *replicationControllerClient) AddHandler(ctx context.Context, name string, sync ReplicationControllerHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *replicationControllerClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ReplicationControllerHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *replicationControllerClient) AddLifecycle(ctx context.Context, name string, lifecycle ReplicationControllerLifecycle) { + sync := NewReplicationControllerLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *replicationControllerClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ReplicationControllerLifecycle) { + sync := NewReplicationControllerLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *replicationControllerClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ReplicationControllerHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *replicationControllerClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ReplicationControllerHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *replicationControllerClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ReplicationControllerLifecycle) { + sync := NewReplicationControllerLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *replicationControllerClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ReplicationControllerLifecycle) { + sync := NewReplicationControllerLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_lifecycle_adapter.go new file mode 100644 index 0000000..c7746c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_replication_controller_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ReplicationControllerLifecycle interface { + Create(obj *v1.ReplicationController) (runtime.Object, error) + Remove(obj *v1.ReplicationController) (runtime.Object, error) + Updated(obj *v1.ReplicationController) (runtime.Object, error) +} + +type replicationControllerLifecycleAdapter struct { + lifecycle ReplicationControllerLifecycle +} + +func (w *replicationControllerLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *replicationControllerLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *replicationControllerLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ReplicationController)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *replicationControllerLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ReplicationController)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *replicationControllerLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ReplicationController)) + if o == nil { + return nil, err + } + return o, err +} + +func NewReplicationControllerLifecycleAdapter(name string, clusterScoped bool, client ReplicationControllerInterface, l ReplicationControllerLifecycle) ReplicationControllerHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ReplicationControllerGroupVersionResource) + } + adapter := &replicationControllerLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ReplicationController) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_controller.go new file mode 100644 index 0000000..225b130 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ResourceQuotaGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ResourceQuota", + } + ResourceQuotaResource = metav1.APIResource{ + Name: "resourcequotas", + SingularName: "resourcequota", + Namespaced: true, + + Kind: ResourceQuotaGroupVersionKind.Kind, + } + + ResourceQuotaGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "resourcequotas", + } +) + +func init() { + resource.Put(ResourceQuotaGroupVersionResource) +} + +// Deprecated: use v1.ResourceQuota instead +type ResourceQuota = v1.ResourceQuota + +func NewResourceQuota(namespace, name string, obj v1.ResourceQuota) *v1.ResourceQuota { + obj.APIVersion, obj.Kind = ResourceQuotaGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ResourceQuotaHandlerFunc func(key string, obj *v1.ResourceQuota) (runtime.Object, error) + +type ResourceQuotaChangeHandlerFunc func(obj *v1.ResourceQuota) (runtime.Object, error) + +type ResourceQuotaLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ResourceQuota, err error) + Get(namespace, name string) (*v1.ResourceQuota, error) +} + +type ResourceQuotaController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ResourceQuotaLister + AddHandler(ctx context.Context, name string, handler ResourceQuotaHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ResourceQuotaHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ResourceQuotaHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ResourceQuotaHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ResourceQuotaInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ResourceQuota) (*v1.ResourceQuota, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) + Get(name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) + Update(*v1.ResourceQuota) (*v1.ResourceQuota, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ResourceQuotaList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ResourceQuotaList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ResourceQuotaController + AddHandler(ctx context.Context, name string, sync ResourceQuotaHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ResourceQuotaHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ResourceQuotaLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ResourceQuotaLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ResourceQuotaHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ResourceQuotaHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ResourceQuotaLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ResourceQuotaLifecycle) +} + +type resourceQuotaLister struct { + ns string + controller *resourceQuotaController +} + +func (l *resourceQuotaLister) List(namespace string, selector labels.Selector) (ret []*v1.ResourceQuota, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ResourceQuota)) + }) + return +} + +func (l *resourceQuotaLister) Get(namespace, name string) (*v1.ResourceQuota, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ResourceQuotaGroupVersionKind.Group, + Resource: ResourceQuotaGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ResourceQuota), nil +} + +type resourceQuotaController struct { + ns string + controller.GenericController +} + +func (c *resourceQuotaController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *resourceQuotaController) Lister() ResourceQuotaLister { + return &resourceQuotaLister{ + ns: c.ns, + controller: c, + } +} + +func (c *resourceQuotaController) AddHandler(ctx context.Context, name string, handler ResourceQuotaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ResourceQuota); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *resourceQuotaController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ResourceQuotaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ResourceQuota); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *resourceQuotaController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ResourceQuotaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ResourceQuota); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *resourceQuotaController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ResourceQuotaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ResourceQuota); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type resourceQuotaFactory struct { +} + +func (c resourceQuotaFactory) Object() runtime.Object { + return &v1.ResourceQuota{} +} + +func (c resourceQuotaFactory) List() runtime.Object { + return &v1.ResourceQuotaList{} +} + +func (s *resourceQuotaClient) Controller() ResourceQuotaController { + genericController := controller.NewGenericController(s.ns, ResourceQuotaGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ResourceQuotaGroupVersionResource, ResourceQuotaGroupVersionKind.Kind, true)) + + return &resourceQuotaController{ + ns: s.ns, + GenericController: genericController, + } +} + +type resourceQuotaClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ResourceQuotaController +} + +func (s *resourceQuotaClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *resourceQuotaClient) Create(o *v1.ResourceQuota) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) Get(name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) Update(o *v1.ResourceQuota) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) UpdateStatus(o *v1.ResourceQuota) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *resourceQuotaClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *resourceQuotaClient) List(opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ResourceQuotaList), err +} + +func (s *resourceQuotaClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ResourceQuotaList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ResourceQuotaList), err +} + +func (s *resourceQuotaClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *resourceQuotaClient) Patch(o *v1.ResourceQuota, patchType types.PatchType, data []byte, subresources ...string) (*v1.ResourceQuota, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ResourceQuota), err +} + +func (s *resourceQuotaClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *resourceQuotaClient) AddHandler(ctx context.Context, name string, sync ResourceQuotaHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *resourceQuotaClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ResourceQuotaHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *resourceQuotaClient) AddLifecycle(ctx context.Context, name string, lifecycle ResourceQuotaLifecycle) { + sync := NewResourceQuotaLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *resourceQuotaClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ResourceQuotaLifecycle) { + sync := NewResourceQuotaLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *resourceQuotaClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ResourceQuotaHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *resourceQuotaClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ResourceQuotaHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *resourceQuotaClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ResourceQuotaLifecycle) { + sync := NewResourceQuotaLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *resourceQuotaClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ResourceQuotaLifecycle) { + sync := NewResourceQuotaLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_lifecycle_adapter.go new file mode 100644 index 0000000..3753336 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_resource_quota_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ResourceQuotaLifecycle interface { + Create(obj *v1.ResourceQuota) (runtime.Object, error) + Remove(obj *v1.ResourceQuota) (runtime.Object, error) + Updated(obj *v1.ResourceQuota) (runtime.Object, error) +} + +type resourceQuotaLifecycleAdapter struct { + lifecycle ResourceQuotaLifecycle +} + +func (w *resourceQuotaLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *resourceQuotaLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *resourceQuotaLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ResourceQuota)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *resourceQuotaLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ResourceQuota)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *resourceQuotaLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ResourceQuota)) + if o == nil { + return nil, err + } + return o, err +} + +func NewResourceQuotaLifecycleAdapter(name string, clusterScoped bool, client ResourceQuotaInterface, l ResourceQuotaLifecycle) ResourceQuotaHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ResourceQuotaGroupVersionResource) + } + adapter := &resourceQuotaLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ResourceQuota) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_scheme.go new file mode 100644 index 0000000..9a92857 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_controller.go new file mode 100644 index 0000000..39ea7fd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + SecretGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Secret", + } + SecretResource = metav1.APIResource{ + Name: "secrets", + SingularName: "secret", + Namespaced: true, + + Kind: SecretGroupVersionKind.Kind, + } + + SecretGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "secrets", + } +) + +func init() { + resource.Put(SecretGroupVersionResource) +} + +// Deprecated: use v1.Secret instead +type Secret = v1.Secret + +func NewSecret(namespace, name string, obj v1.Secret) *v1.Secret { + obj.APIVersion, obj.Kind = SecretGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type SecretHandlerFunc func(key string, obj *v1.Secret) (runtime.Object, error) + +type SecretChangeHandlerFunc func(obj *v1.Secret) (runtime.Object, error) + +type SecretLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Secret, err error) + Get(namespace, name string) (*v1.Secret, error) +} + +type SecretController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() SecretLister + AddHandler(ctx context.Context, name string, handler SecretHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SecretHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler SecretHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler SecretHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type SecretInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Secret) (*v1.Secret, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Secret, error) + Get(name string, opts metav1.GetOptions) (*v1.Secret, error) + Update(*v1.Secret) (*v1.Secret, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.SecretList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.SecretList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() SecretController + AddHandler(ctx context.Context, name string, sync SecretHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SecretHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle SecretLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SecretLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SecretHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SecretHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SecretLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SecretLifecycle) +} + +type secretLister struct { + ns string + controller *secretController +} + +func (l *secretLister) List(namespace string, selector labels.Selector) (ret []*v1.Secret, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Secret)) + }) + return +} + +func (l *secretLister) Get(namespace, name string) (*v1.Secret, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: SecretGroupVersionKind.Group, + Resource: SecretGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Secret), nil +} + +type secretController struct { + ns string + controller.GenericController +} + +func (c *secretController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *secretController) Lister() SecretLister { + return &secretLister{ + ns: c.ns, + controller: c, + } +} + +func (c *secretController) AddHandler(ctx context.Context, name string, handler SecretHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Secret); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *secretController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler SecretHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Secret); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *secretController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler SecretHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Secret); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *secretController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler SecretHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Secret); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type secretFactory struct { +} + +func (c secretFactory) Object() runtime.Object { + return &v1.Secret{} +} + +func (c secretFactory) List() runtime.Object { + return &v1.SecretList{} +} + +func (s *secretClient) Controller() SecretController { + genericController := controller.NewGenericController(s.ns, SecretGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(SecretGroupVersionResource, SecretGroupVersionKind.Kind, true)) + + return &secretController{ + ns: s.ns, + GenericController: genericController, + } +} + +type secretClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller SecretController +} + +func (s *secretClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *secretClient) Create(o *v1.Secret) (*v1.Secret, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Secret), err +} + +func (s *secretClient) Get(name string, opts metav1.GetOptions) (*v1.Secret, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Secret), err +} + +func (s *secretClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Secret, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Secret), err +} + +func (s *secretClient) Update(o *v1.Secret) (*v1.Secret, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Secret), err +} + +func (s *secretClient) UpdateStatus(o *v1.Secret) (*v1.Secret, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Secret), err +} + +func (s *secretClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *secretClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *secretClient) List(opts metav1.ListOptions) (*v1.SecretList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.SecretList), err +} + +func (s *secretClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.SecretList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.SecretList), err +} + +func (s *secretClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *secretClient) Patch(o *v1.Secret, patchType types.PatchType, data []byte, subresources ...string) (*v1.Secret, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Secret), err +} + +func (s *secretClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *secretClient) AddHandler(ctx context.Context, name string, sync SecretHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *secretClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SecretHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *secretClient) AddLifecycle(ctx context.Context, name string, lifecycle SecretLifecycle) { + sync := NewSecretLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *secretClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SecretLifecycle) { + sync := NewSecretLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *secretClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SecretHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *secretClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SecretHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *secretClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SecretLifecycle) { + sync := NewSecretLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *secretClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SecretLifecycle) { + sync := NewSecretLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_lifecycle_adapter.go new file mode 100644 index 0000000..67f9974 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_secret_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type SecretLifecycle interface { + Create(obj *v1.Secret) (runtime.Object, error) + Remove(obj *v1.Secret) (runtime.Object, error) + Updated(obj *v1.Secret) (runtime.Object, error) +} + +type secretLifecycleAdapter struct { + lifecycle SecretLifecycle +} + +func (w *secretLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *secretLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *secretLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Secret)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *secretLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Secret)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *secretLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Secret)) + if o == nil { + return nil, err + } + return o, err +} + +func NewSecretLifecycleAdapter(name string, clusterScoped bool, client SecretInterface, l SecretLifecycle) SecretHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(SecretGroupVersionResource) + } + adapter := &secretLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Secret) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_controller.go new file mode 100644 index 0000000..8fcf2d7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ServiceAccountGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ServiceAccount", + } + ServiceAccountResource = metav1.APIResource{ + Name: "serviceaccounts", + SingularName: "serviceaccount", + Namespaced: true, + + Kind: ServiceAccountGroupVersionKind.Kind, + } + + ServiceAccountGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "serviceaccounts", + } +) + +func init() { + resource.Put(ServiceAccountGroupVersionResource) +} + +// Deprecated: use v1.ServiceAccount instead +type ServiceAccount = v1.ServiceAccount + +func NewServiceAccount(namespace, name string, obj v1.ServiceAccount) *v1.ServiceAccount { + obj.APIVersion, obj.Kind = ServiceAccountGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ServiceAccountHandlerFunc func(key string, obj *v1.ServiceAccount) (runtime.Object, error) + +type ServiceAccountChangeHandlerFunc func(obj *v1.ServiceAccount) (runtime.Object, error) + +type ServiceAccountLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ServiceAccount, err error) + Get(namespace, name string) (*v1.ServiceAccount, error) +} + +type ServiceAccountController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ServiceAccountLister + AddHandler(ctx context.Context, name string, handler ServiceAccountHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ServiceAccountHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ServiceAccountHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ServiceAccountInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ServiceAccount) (*v1.ServiceAccount, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) + Get(name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) + Update(*v1.ServiceAccount) (*v1.ServiceAccount, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ServiceAccountList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceAccountList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ServiceAccountController + AddHandler(ctx context.Context, name string, sync ServiceAccountHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ServiceAccountLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceAccountLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceAccountHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceAccountHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceAccountLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceAccountLifecycle) +} + +type serviceAccountLister struct { + ns string + controller *serviceAccountController +} + +func (l *serviceAccountLister) List(namespace string, selector labels.Selector) (ret []*v1.ServiceAccount, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ServiceAccount)) + }) + return +} + +func (l *serviceAccountLister) Get(namespace, name string) (*v1.ServiceAccount, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ServiceAccountGroupVersionKind.Group, + Resource: ServiceAccountGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ServiceAccount), nil +} + +type serviceAccountController struct { + ns string + controller.GenericController +} + +func (c *serviceAccountController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *serviceAccountController) Lister() ServiceAccountLister { + return &serviceAccountLister{ + ns: c.ns, + controller: c, + } +} + +func (c *serviceAccountController) AddHandler(ctx context.Context, name string, handler ServiceAccountHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ServiceAccount); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ServiceAccountHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ServiceAccount); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ServiceAccountHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ServiceAccount); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ServiceAccountHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ServiceAccount); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type serviceAccountFactory struct { +} + +func (c serviceAccountFactory) Object() runtime.Object { + return &v1.ServiceAccount{} +} + +func (c serviceAccountFactory) List() runtime.Object { + return &v1.ServiceAccountList{} +} + +func (s *serviceAccountClient) Controller() ServiceAccountController { + genericController := controller.NewGenericController(s.ns, ServiceAccountGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ServiceAccountGroupVersionResource, ServiceAccountGroupVersionKind.Kind, true)) + + return &serviceAccountController{ + ns: s.ns, + GenericController: genericController, + } +} + +type serviceAccountClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ServiceAccountController +} + +func (s *serviceAccountClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *serviceAccountClient) Create(o *v1.ServiceAccount) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) Get(name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) Update(o *v1.ServiceAccount) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) UpdateStatus(o *v1.ServiceAccount) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *serviceAccountClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *serviceAccountClient) List(opts metav1.ListOptions) (*v1.ServiceAccountList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ServiceAccountList), err +} + +func (s *serviceAccountClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceAccountList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ServiceAccountList), err +} + +func (s *serviceAccountClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *serviceAccountClient) Patch(o *v1.ServiceAccount, patchType types.PatchType, data []byte, subresources ...string) (*v1.ServiceAccount, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ServiceAccount), err +} + +func (s *serviceAccountClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *serviceAccountClient) AddHandler(ctx context.Context, name string, sync ServiceAccountHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceAccountClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceAccountClient) AddLifecycle(ctx context.Context, name string, lifecycle ServiceAccountLifecycle) { + sync := NewServiceAccountLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceAccountClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceAccountLifecycle) { + sync := NewServiceAccountLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceAccountClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceAccountHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceAccountClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceAccountHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *serviceAccountClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceAccountLifecycle) { + sync := NewServiceAccountLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceAccountClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceAccountLifecycle) { + sync := NewServiceAccountLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_lifecycle_adapter.go new file mode 100644 index 0000000..a303486 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_account_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ServiceAccountLifecycle interface { + Create(obj *v1.ServiceAccount) (runtime.Object, error) + Remove(obj *v1.ServiceAccount) (runtime.Object, error) + Updated(obj *v1.ServiceAccount) (runtime.Object, error) +} + +type serviceAccountLifecycleAdapter struct { + lifecycle ServiceAccountLifecycle +} + +func (w *serviceAccountLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *serviceAccountLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *serviceAccountLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ServiceAccount)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceAccountLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ServiceAccount)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceAccountLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ServiceAccount)) + if o == nil { + return nil, err + } + return o, err +} + +func NewServiceAccountLifecycleAdapter(name string, clusterScoped bool, client ServiceAccountInterface, l ServiceAccountLifecycle) ServiceAccountHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ServiceAccountGroupVersionResource) + } + adapter := &serviceAccountLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ServiceAccount) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_controller.go new file mode 100644 index 0000000..866fa45 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ServiceGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Service", + } + ServiceResource = metav1.APIResource{ + Name: "services", + SingularName: "service", + Namespaced: true, + + Kind: ServiceGroupVersionKind.Kind, + } + + ServiceGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "services", + } +) + +func init() { + resource.Put(ServiceGroupVersionResource) +} + +// Deprecated: use v1.Service instead +type Service = v1.Service + +func NewService(namespace, name string, obj v1.Service) *v1.Service { + obj.APIVersion, obj.Kind = ServiceGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ServiceHandlerFunc func(key string, obj *v1.Service) (runtime.Object, error) + +type ServiceChangeHandlerFunc func(obj *v1.Service) (runtime.Object, error) + +type ServiceLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Service, err error) + Get(namespace, name string) (*v1.Service, error) +} + +type ServiceController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ServiceLister + AddHandler(ctx context.Context, name string, handler ServiceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ServiceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ServiceHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ServiceInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Service) (*v1.Service, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Service, error) + Get(name string, opts metav1.GetOptions) (*v1.Service, error) + Update(*v1.Service) (*v1.Service, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ServiceList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ServiceController + AddHandler(ctx context.Context, name string, sync ServiceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ServiceLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceLifecycle) +} + +type serviceLister struct { + ns string + controller *serviceController +} + +func (l *serviceLister) List(namespace string, selector labels.Selector) (ret []*v1.Service, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Service)) + }) + return +} + +func (l *serviceLister) Get(namespace, name string) (*v1.Service, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ServiceGroupVersionKind.Group, + Resource: ServiceGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Service), nil +} + +type serviceController struct { + ns string + controller.GenericController +} + +func (c *serviceController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *serviceController) Lister() ServiceLister { + return &serviceLister{ + ns: c.ns, + controller: c, + } +} + +func (c *serviceController) AddHandler(ctx context.Context, name string, handler ServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Service); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Service); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Service); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ServiceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Service); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type serviceFactory struct { +} + +func (c serviceFactory) Object() runtime.Object { + return &v1.Service{} +} + +func (c serviceFactory) List() runtime.Object { + return &v1.ServiceList{} +} + +func (s *serviceClient) Controller() ServiceController { + genericController := controller.NewGenericController(s.ns, ServiceGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ServiceGroupVersionResource, ServiceGroupVersionKind.Kind, true)) + + return &serviceController{ + ns: s.ns, + GenericController: genericController, + } +} + +type serviceClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ServiceController +} + +func (s *serviceClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *serviceClient) Create(o *v1.Service) (*v1.Service, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Service), err +} + +func (s *serviceClient) Get(name string, opts metav1.GetOptions) (*v1.Service, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Service), err +} + +func (s *serviceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Service, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Service), err +} + +func (s *serviceClient) Update(o *v1.Service) (*v1.Service, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Service), err +} + +func (s *serviceClient) UpdateStatus(o *v1.Service) (*v1.Service, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Service), err +} + +func (s *serviceClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *serviceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *serviceClient) List(opts metav1.ListOptions) (*v1.ServiceList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ServiceList), err +} + +func (s *serviceClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ServiceList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ServiceList), err +} + +func (s *serviceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *serviceClient) Patch(o *v1.Service, patchType types.PatchType, data []byte, subresources ...string) (*v1.Service, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Service), err +} + +func (s *serviceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *serviceClient) AddHandler(ctx context.Context, name string, sync ServiceHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceClient) AddLifecycle(ctx context.Context, name string, lifecycle ServiceLifecycle) { + sync := NewServiceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceLifecycle) { + sync := NewServiceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *serviceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceLifecycle) { + sync := NewServiceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceLifecycle) { + sync := NewServiceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_lifecycle_adapter.go new file mode 100644 index 0000000..f616505 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/core/v1/zz_generated_service_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ServiceLifecycle interface { + Create(obj *v1.Service) (runtime.Object, error) + Remove(obj *v1.Service) (runtime.Object, error) + Updated(obj *v1.Service) (runtime.Object, error) +} + +type serviceLifecycleAdapter struct { + lifecycle ServiceLifecycle +} + +func (w *serviceLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *serviceLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *serviceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Service)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Service)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Service)) + if o == nil { + return nil, err + } + return o, err +} + +func NewServiceLifecycleAdapter(name string, clusterScoped bool, client ServiceInterface, l ServiceLifecycle) ServiceHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ServiceGroupVersionResource) + } + adapter := &serviceLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Service) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/fakes/zz_generated_ingress_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/fakes/zz_generated_ingress_mock.go new file mode 100644 index 0000000..38db319 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/fakes/zz_generated_ingress_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v1beta11 "github.com/rancher/rancher/pkg/generated/norman/extensions/v1beta1" + "k8s.io/api/extensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockIngressListerMockGet sync.RWMutex + lockIngressListerMockList sync.RWMutex +) + +// Ensure, that IngressListerMock does implement v1beta11.IngressLister. +// If this is not the case, regenerate this file with moq. +var _ v1beta11.IngressLister = &IngressListerMock{} + +// IngressListerMock is a mock implementation of v1beta11.IngressLister. +// +// func TestSomethingThatUsesIngressLister(t *testing.T) { +// +// // make and configure a mocked v1beta11.IngressLister +// mockedIngressLister := &IngressListerMock{ +// GetFunc: func(namespace string, name string) (*v1beta1.Ingress, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1beta1.Ingress, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedIngressLister in code that requires v1beta11.IngressLister +// // and then make assertions. +// +// } +type IngressListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1beta1.Ingress, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1beta1.Ingress, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *IngressListerMock) Get(namespace string, name string) (*v1beta1.Ingress, error) { + if mock.GetFunc == nil { + panic("IngressListerMock.GetFunc: method is nil but IngressLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockIngressListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockIngressListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedIngressLister.GetCalls()) +func (mock *IngressListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockIngressListerMockGet.RLock() + calls = mock.calls.Get + lockIngressListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *IngressListerMock) List(namespace string, selector labels.Selector) ([]*v1beta1.Ingress, error) { + if mock.ListFunc == nil { + panic("IngressListerMock.ListFunc: method is nil but IngressLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockIngressListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockIngressListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedIngressLister.ListCalls()) +func (mock *IngressListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockIngressListerMockList.RLock() + calls = mock.calls.List + lockIngressListerMockList.RUnlock() + return calls +} + +var ( + lockIngressControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockIngressControllerMockAddClusterScopedHandler sync.RWMutex + lockIngressControllerMockAddFeatureHandler sync.RWMutex + lockIngressControllerMockAddHandler sync.RWMutex + lockIngressControllerMockEnqueue sync.RWMutex + lockIngressControllerMockEnqueueAfter sync.RWMutex + lockIngressControllerMockGeneric sync.RWMutex + lockIngressControllerMockInformer sync.RWMutex + lockIngressControllerMockLister sync.RWMutex +) + +// Ensure, that IngressControllerMock does implement v1beta11.IngressController. +// If this is not the case, regenerate this file with moq. +var _ v1beta11.IngressController = &IngressControllerMock{} + +// IngressControllerMock is a mock implementation of v1beta11.IngressController. +// +// func TestSomethingThatUsesIngressController(t *testing.T) { +// +// // make and configure a mocked v1beta11.IngressController +// mockedIngressController := &IngressControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v1beta11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v1beta11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v1beta11.IngressHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v1beta11.IngressLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedIngressController in code that requires v1beta11.IngressController +// // and then make assertions. +// +// } +type IngressControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v1beta11.IngressHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v1beta11.IngressHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v1beta11.IngressHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v1beta11.IngressLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v1beta11.IngressHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v1beta11.IngressHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v1beta11.IngressHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v1beta11.IngressHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *IngressControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v1beta11.IngressHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("IngressControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but IngressController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockIngressControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockIngressControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedIngressController.AddClusterScopedFeatureHandlerCalls()) +func (mock *IngressControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc + } + lockIngressControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockIngressControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *IngressControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v1beta11.IngressHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("IngressControllerMock.AddClusterScopedHandlerFunc: method is nil but IngressController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockIngressControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockIngressControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedIngressController.AddClusterScopedHandlerCalls()) +func (mock *IngressControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v1beta11.IngressHandlerFunc + } + lockIngressControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockIngressControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *IngressControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("IngressControllerMock.AddFeatureHandlerFunc: method is nil but IngressController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockIngressControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockIngressControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedIngressController.AddFeatureHandlerCalls()) +func (mock *IngressControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc + } + lockIngressControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockIngressControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *IngressControllerMock) AddHandler(ctx context.Context, name string, handler v1beta11.IngressHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("IngressControllerMock.AddHandlerFunc: method is nil but IngressController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockIngressControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockIngressControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedIngressController.AddHandlerCalls()) +func (mock *IngressControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v1beta11.IngressHandlerFunc + } + lockIngressControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockIngressControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *IngressControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("IngressControllerMock.EnqueueFunc: method is nil but IngressController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockIngressControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockIngressControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedIngressController.EnqueueCalls()) +func (mock *IngressControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockIngressControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockIngressControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *IngressControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("IngressControllerMock.EnqueueAfterFunc: method is nil but IngressController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockIngressControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockIngressControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedIngressController.EnqueueAfterCalls()) +func (mock *IngressControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockIngressControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockIngressControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *IngressControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("IngressControllerMock.GenericFunc: method is nil but IngressController.Generic was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockIngressControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedIngressController.GenericCalls()) +func (mock *IngressControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockIngressControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *IngressControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("IngressControllerMock.InformerFunc: method is nil but IngressController.Informer was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockIngressControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedIngressController.InformerCalls()) +func (mock *IngressControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockInformer.RLock() + calls = mock.calls.Informer + lockIngressControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *IngressControllerMock) Lister() v1beta11.IngressLister { + if mock.ListerFunc == nil { + panic("IngressControllerMock.ListerFunc: method is nil but IngressController.Lister was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockIngressControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedIngressController.ListerCalls()) +func (mock *IngressControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockLister.RLock() + calls = mock.calls.Lister + lockIngressControllerMockLister.RUnlock() + return calls +} + +var ( + lockIngressInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockIngressInterfaceMockAddClusterScopedHandler sync.RWMutex + lockIngressInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockIngressInterfaceMockAddFeatureHandler sync.RWMutex + lockIngressInterfaceMockAddFeatureLifecycle sync.RWMutex + lockIngressInterfaceMockAddHandler sync.RWMutex + lockIngressInterfaceMockAddLifecycle sync.RWMutex + lockIngressInterfaceMockController sync.RWMutex + lockIngressInterfaceMockCreate sync.RWMutex + lockIngressInterfaceMockDelete sync.RWMutex + lockIngressInterfaceMockDeleteCollection sync.RWMutex + lockIngressInterfaceMockDeleteNamespaced sync.RWMutex + lockIngressInterfaceMockGet sync.RWMutex + lockIngressInterfaceMockGetNamespaced sync.RWMutex + lockIngressInterfaceMockList sync.RWMutex + lockIngressInterfaceMockListNamespaced sync.RWMutex + lockIngressInterfaceMockObjectClient sync.RWMutex + lockIngressInterfaceMockUpdate sync.RWMutex + lockIngressInterfaceMockWatch sync.RWMutex +) + +// Ensure, that IngressInterfaceMock does implement v1beta11.IngressInterface. +// If this is not the case, regenerate this file with moq. +var _ v1beta11.IngressInterface = &IngressInterfaceMock{} + +// IngressInterfaceMock is a mock implementation of v1beta11.IngressInterface. +// +// func TestSomethingThatUsesIngressInterface(t *testing.T) { +// +// // make and configure a mocked v1beta11.IngressInterface +// mockedIngressInterface := &IngressInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v1beta11.IngressLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v1beta11.IngressHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v1beta11.IngressLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v1beta11.IngressController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1beta1.IngressList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1beta1.IngressList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedIngressInterface in code that requires v1beta11.IngressInterface +// // and then make assertions. +// +// } +type IngressInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v1beta11.IngressLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v1beta11.IngressHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v1beta11.IngressLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v1beta11.IngressController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1beta1.IngressList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1beta1.IngressList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v1beta11.IngressHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v1beta11.IngressLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v1beta11.IngressHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v1beta11.IngressLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v1beta11.IngressHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v1beta11.IngressLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v1beta11.IngressHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v1beta11.IngressLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1beta1.Ingress + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1beta1.Ingress + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *IngressInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but IngressInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockIngressInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc + } + lockIngressInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockIngressInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *IngressInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but IngressInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle + } + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *IngressInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v1beta11.IngressHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedHandlerFunc: method is nil but IngressInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockIngressInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedHandlerCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v1beta11.IngressHandlerFunc + } + lockIngressInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockIngressInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *IngressInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v1beta11.IngressLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but IngressInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockIngressInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedLifecycleCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v1beta11.IngressLifecycle + } + lockIngressInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockIngressInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *IngressInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v1beta11.IngressHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("IngressInterfaceMock.AddFeatureHandlerFunc: method is nil but IngressInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockIngressInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddFeatureHandlerCalls()) +func (mock *IngressInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v1beta11.IngressHandlerFunc + } + lockIngressInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockIngressInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *IngressInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v1beta11.IngressLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("IngressInterfaceMock.AddFeatureLifecycleFunc: method is nil but IngressInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v1beta11.IngressLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockIngressInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddFeatureLifecycleCalls()) +func (mock *IngressInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v1beta11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v1beta11.IngressLifecycle + } + lockIngressInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockIngressInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *IngressInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v1beta11.IngressHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("IngressInterfaceMock.AddHandlerFunc: method is nil but IngressInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v1beta11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockIngressInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddHandlerCalls()) +func (mock *IngressInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v1beta11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v1beta11.IngressHandlerFunc + } + lockIngressInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockIngressInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *IngressInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v1beta11.IngressLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("IngressInterfaceMock.AddLifecycleFunc: method is nil but IngressInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v1beta11.IngressLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockIngressInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddLifecycleCalls()) +func (mock *IngressInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v1beta11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v1beta11.IngressLifecycle + } + lockIngressInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockIngressInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *IngressInterfaceMock) Controller() v1beta11.IngressController { + if mock.ControllerFunc == nil { + panic("IngressInterfaceMock.ControllerFunc: method is nil but IngressInterface.Controller was just called") + } + callInfo := struct { + }{} + lockIngressInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockIngressInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedIngressInterface.ControllerCalls()) +func (mock *IngressInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockIngressInterfaceMockController.RLock() + calls = mock.calls.Controller + lockIngressInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *IngressInterfaceMock) Create(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) { + if mock.CreateFunc == nil { + panic("IngressInterfaceMock.CreateFunc: method is nil but IngressInterface.Create was just called") + } + callInfo := struct { + In1 *v1beta1.Ingress + }{ + In1: in1, + } + lockIngressInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockIngressInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedIngressInterface.CreateCalls()) +func (mock *IngressInterfaceMock) CreateCalls() []struct { + In1 *v1beta1.Ingress +} { + var calls []struct { + In1 *v1beta1.Ingress + } + lockIngressInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockIngressInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *IngressInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("IngressInterfaceMock.DeleteFunc: method is nil but IngressInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockIngressInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockIngressInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedIngressInterface.DeleteCalls()) +func (mock *IngressInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockIngressInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockIngressInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *IngressInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("IngressInterfaceMock.DeleteCollectionFunc: method is nil but IngressInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockIngressInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockIngressInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedIngressInterface.DeleteCollectionCalls()) +func (mock *IngressInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockIngressInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockIngressInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *IngressInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("IngressInterfaceMock.DeleteNamespacedFunc: method is nil but IngressInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockIngressInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockIngressInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.DeleteNamespacedCalls()) +func (mock *IngressInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockIngressInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockIngressInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *IngressInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { + if mock.GetFunc == nil { + panic("IngressInterfaceMock.GetFunc: method is nil but IngressInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockIngressInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockIngressInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedIngressInterface.GetCalls()) +func (mock *IngressInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockIngressInterfaceMockGet.RLock() + calls = mock.calls.Get + lockIngressInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *IngressInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { + if mock.GetNamespacedFunc == nil { + panic("IngressInterfaceMock.GetNamespacedFunc: method is nil but IngressInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockIngressInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockIngressInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.GetNamespacedCalls()) +func (mock *IngressInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockIngressInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockIngressInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *IngressInterfaceMock) List(opts metav1.ListOptions) (*v1beta1.IngressList, error) { + if mock.ListFunc == nil { + panic("IngressInterfaceMock.ListFunc: method is nil but IngressInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockIngressInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockIngressInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedIngressInterface.ListCalls()) +func (mock *IngressInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockIngressInterfaceMockList.RLock() + calls = mock.calls.List + lockIngressInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *IngressInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1beta1.IngressList, error) { + if mock.ListNamespacedFunc == nil { + panic("IngressInterfaceMock.ListNamespacedFunc: method is nil but IngressInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockIngressInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockIngressInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.ListNamespacedCalls()) +func (mock *IngressInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockIngressInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockIngressInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *IngressInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("IngressInterfaceMock.ObjectClientFunc: method is nil but IngressInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockIngressInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockIngressInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedIngressInterface.ObjectClientCalls()) +func (mock *IngressInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockIngressInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockIngressInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *IngressInterfaceMock) Update(in1 *v1beta1.Ingress) (*v1beta1.Ingress, error) { + if mock.UpdateFunc == nil { + panic("IngressInterfaceMock.UpdateFunc: method is nil but IngressInterface.Update was just called") + } + callInfo := struct { + In1 *v1beta1.Ingress + }{ + In1: in1, + } + lockIngressInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockIngressInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedIngressInterface.UpdateCalls()) +func (mock *IngressInterfaceMock) UpdateCalls() []struct { + In1 *v1beta1.Ingress +} { + var calls []struct { + In1 *v1beta1.Ingress + } + lockIngressInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockIngressInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *IngressInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("IngressInterfaceMock.WatchFunc: method is nil but IngressInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockIngressInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockIngressInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedIngressInterface.WatchCalls()) +func (mock *IngressInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockIngressInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockIngressInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockIngressesGetterMockIngresses sync.RWMutex +) + +// Ensure, that IngressesGetterMock does implement v1beta11.IngressesGetter. +// If this is not the case, regenerate this file with moq. +var _ v1beta11.IngressesGetter = &IngressesGetterMock{} + +// IngressesGetterMock is a mock implementation of v1beta11.IngressesGetter. +// +// func TestSomethingThatUsesIngressesGetter(t *testing.T) { +// +// // make and configure a mocked v1beta11.IngressesGetter +// mockedIngressesGetter := &IngressesGetterMock{ +// IngressesFunc: func(namespace string) v1beta11.IngressInterface { +// panic("mock out the Ingresses method") +// }, +// } +// +// // use mockedIngressesGetter in code that requires v1beta11.IngressesGetter +// // and then make assertions. +// +// } +type IngressesGetterMock struct { + // IngressesFunc mocks the Ingresses method. + IngressesFunc func(namespace string) v1beta11.IngressInterface + + // calls tracks calls to the methods. + calls struct { + // Ingresses holds details about calls to the Ingresses method. + Ingresses []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Ingresses calls IngressesFunc. +func (mock *IngressesGetterMock) Ingresses(namespace string) v1beta11.IngressInterface { + if mock.IngressesFunc == nil { + panic("IngressesGetterMock.IngressesFunc: method is nil but IngressesGetter.Ingresses was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockIngressesGetterMockIngresses.Lock() + mock.calls.Ingresses = append(mock.calls.Ingresses, callInfo) + lockIngressesGetterMockIngresses.Unlock() + return mock.IngressesFunc(namespace) +} + +// IngressesCalls gets all the calls that were made to Ingresses. +// Check the length with: +// +// len(mockedIngressesGetter.IngressesCalls()) +func (mock *IngressesGetterMock) IngressesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockIngressesGetterMockIngresses.RLock() + calls = mock.calls.Ingresses + lockIngressesGetterMockIngresses.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_controller.go new file mode 100644 index 0000000..f9bfd73 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_controller.go @@ -0,0 +1,326 @@ +package v1beta1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + IngressGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Ingress", + } + IngressResource = metav1.APIResource{ + Name: "ingresses", + SingularName: "ingress", + Namespaced: true, + + Kind: IngressGroupVersionKind.Kind, + } + + IngressGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "ingresses", + } +) + +func init() { + resource.Put(IngressGroupVersionResource) +} + +// Deprecated: use v1beta1.Ingress instead +type Ingress = v1beta1.Ingress + +func NewIngress(namespace, name string, obj v1beta1.Ingress) *v1beta1.Ingress { + obj.APIVersion, obj.Kind = IngressGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type IngressHandlerFunc func(key string, obj *v1beta1.Ingress) (runtime.Object, error) + +type IngressChangeHandlerFunc func(obj *v1beta1.Ingress) (runtime.Object, error) + +type IngressLister interface { + List(namespace string, selector labels.Selector) (ret []*v1beta1.Ingress, err error) + Get(namespace, name string) (*v1beta1.Ingress, error) +} + +type IngressController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() IngressLister + AddHandler(ctx context.Context, name string, handler IngressHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler IngressHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler IngressHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type IngressInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1beta1.Ingress) (*v1beta1.Ingress, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) + Get(name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) + Update(*v1beta1.Ingress) (*v1beta1.Ingress, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1beta1.IngressList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1beta1.IngressList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() IngressController + AddHandler(ctx context.Context, name string, sync IngressHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle IngressLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle IngressLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync IngressHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync IngressHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle IngressLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle IngressLifecycle) +} + +type ingressLister struct { + ns string + controller *ingressController +} + +func (l *ingressLister) List(namespace string, selector labels.Selector) (ret []*v1beta1.Ingress, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1beta1.Ingress)) + }) + return +} + +func (l *ingressLister) Get(namespace, name string) (*v1beta1.Ingress, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: IngressGroupVersionKind.Group, + Resource: IngressGroupVersionResource.Resource, + }, key) + } + return obj.(*v1beta1.Ingress), nil +} + +type ingressController struct { + ns string + controller.GenericController +} + +func (c *ingressController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *ingressController) Lister() IngressLister { + return &ingressLister{ + ns: c.ns, + controller: c, + } +} + +func (c *ingressController) AddHandler(ctx context.Context, name string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1beta1.Ingress); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1beta1.Ingress); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1beta1.Ingress); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1beta1.Ingress); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type ingressFactory struct { +} + +func (c ingressFactory) Object() runtime.Object { + return &v1beta1.Ingress{} +} + +func (c ingressFactory) List() runtime.Object { + return &v1beta1.IngressList{} +} + +func (s *ingressClient) Controller() IngressController { + genericController := controller.NewGenericController(s.ns, IngressGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(IngressGroupVersionResource, IngressGroupVersionKind.Kind, true)) + + return &ingressController{ + ns: s.ns, + GenericController: genericController, + } +} + +type ingressClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller IngressController +} + +func (s *ingressClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *ingressClient) Create(o *v1beta1.Ingress) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) Get(name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) Update(o *v1beta1.Ingress) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) UpdateStatus(o *v1beta1.Ingress) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *ingressClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *ingressClient) List(opts metav1.ListOptions) (*v1beta1.IngressList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1beta1.IngressList), err +} + +func (s *ingressClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1beta1.IngressList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1beta1.IngressList), err +} + +func (s *ingressClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *ingressClient) Patch(o *v1beta1.Ingress, patchType types.PatchType, data []byte, subresources ...string) (*v1beta1.Ingress, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1beta1.Ingress), err +} + +func (s *ingressClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *ingressClient) AddHandler(ctx context.Context, name string, sync IngressHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ingressClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ingressClient) AddLifecycle(ctx context.Context, name string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ingressClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ingressClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync IngressHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync IngressHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_lifecycle_adapter.go new file mode 100644 index 0000000..04cf978 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_ingress_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1beta1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/runtime" +) + +type IngressLifecycle interface { + Create(obj *v1beta1.Ingress) (runtime.Object, error) + Remove(obj *v1beta1.Ingress) (runtime.Object, error) + Updated(obj *v1beta1.Ingress) (runtime.Object, error) +} + +type ingressLifecycleAdapter struct { + lifecycle IngressLifecycle +} + +func (w *ingressLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *ingressLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *ingressLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1beta1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ingressLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1beta1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ingressLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1beta1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func NewIngressLifecycleAdapter(name string, clusterScoped bool, client IngressInterface, l IngressLifecycle) IngressHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(IngressGroupVersionResource) + } + adapter := &ingressLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1beta1.Ingress) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_k8s_client.go new file mode 100644 index 0000000..a9a7dbb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_k8s_client.go @@ -0,0 +1,63 @@ +package v1beta1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/extensions/v1beta1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + IngressesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1beta1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type IngressesGetter interface { + Ingresses(namespace string) IngressInterface +} + +func (c *Client) Ingresses(namespace string) IngressInterface { + sharedClient := c.clientFactory.ForResourceKind(IngressGroupVersionResource, IngressGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &IngressResource, IngressGroupVersionKind, ingressFactory{}) + return &ingressClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_scheme.go new file mode 100644 index 0000000..91c5b3a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/extensions/v1beta1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "extensions" + Version = "v1beta1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_auth_config_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_auth_config_mock.go new file mode 100644 index 0000000..096fa7f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_auth_config_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockAuthConfigListerMockGet sync.RWMutex + lockAuthConfigListerMockList sync.RWMutex +) + +// Ensure, that AuthConfigListerMock does implement v31.AuthConfigLister. +// If this is not the case, regenerate this file with moq. +var _ v31.AuthConfigLister = &AuthConfigListerMock{} + +// AuthConfigListerMock is a mock implementation of v31.AuthConfigLister. +// +// func TestSomethingThatUsesAuthConfigLister(t *testing.T) { +// +// // make and configure a mocked v31.AuthConfigLister +// mockedAuthConfigLister := &AuthConfigListerMock{ +// GetFunc: func(namespace string, name string) (*v3.AuthConfig, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.AuthConfig, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedAuthConfigLister in code that requires v31.AuthConfigLister +// // and then make assertions. +// +// } +type AuthConfigListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.AuthConfig, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.AuthConfig, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *AuthConfigListerMock) Get(namespace string, name string) (*v3.AuthConfig, error) { + if mock.GetFunc == nil { + panic("AuthConfigListerMock.GetFunc: method is nil but AuthConfigLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAuthConfigListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAuthConfigListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAuthConfigLister.GetCalls()) +func (mock *AuthConfigListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAuthConfigListerMockGet.RLock() + calls = mock.calls.Get + lockAuthConfigListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AuthConfigListerMock) List(namespace string, selector labels.Selector) ([]*v3.AuthConfig, error) { + if mock.ListFunc == nil { + panic("AuthConfigListerMock.ListFunc: method is nil but AuthConfigLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockAuthConfigListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAuthConfigListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAuthConfigLister.ListCalls()) +func (mock *AuthConfigListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockAuthConfigListerMockList.RLock() + calls = mock.calls.List + lockAuthConfigListerMockList.RUnlock() + return calls +} + +var ( + lockAuthConfigControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockAuthConfigControllerMockAddClusterScopedHandler sync.RWMutex + lockAuthConfigControllerMockAddFeatureHandler sync.RWMutex + lockAuthConfigControllerMockAddHandler sync.RWMutex + lockAuthConfigControllerMockEnqueue sync.RWMutex + lockAuthConfigControllerMockEnqueueAfter sync.RWMutex + lockAuthConfigControllerMockGeneric sync.RWMutex + lockAuthConfigControllerMockInformer sync.RWMutex + lockAuthConfigControllerMockLister sync.RWMutex +) + +// Ensure, that AuthConfigControllerMock does implement v31.AuthConfigController. +// If this is not the case, regenerate this file with moq. +var _ v31.AuthConfigController = &AuthConfigControllerMock{} + +// AuthConfigControllerMock is a mock implementation of v31.AuthConfigController. +// +// func TestSomethingThatUsesAuthConfigController(t *testing.T) { +// +// // make and configure a mocked v31.AuthConfigController +// mockedAuthConfigController := &AuthConfigControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AuthConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.AuthConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.AuthConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.AuthConfigLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedAuthConfigController in code that requires v31.AuthConfigController +// // and then make assertions. +// +// } +type AuthConfigControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AuthConfigHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.AuthConfigHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.AuthConfigHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.AuthConfigLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AuthConfigHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AuthConfigHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AuthConfigHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.AuthConfigHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AuthConfigControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AuthConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AuthConfigControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but AuthConfigController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAuthConfigControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAuthConfigControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAuthConfigController.AddClusterScopedFeatureHandlerCalls()) +func (mock *AuthConfigControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc + } + lockAuthConfigControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAuthConfigControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AuthConfigControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.AuthConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AuthConfigControllerMock.AddClusterScopedHandlerFunc: method is nil but AuthConfigController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAuthConfigControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAuthConfigControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAuthConfigController.AddClusterScopedHandlerCalls()) +func (mock *AuthConfigControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AuthConfigHandlerFunc + } + lockAuthConfigControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAuthConfigControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AuthConfigControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AuthConfigControllerMock.AddFeatureHandlerFunc: method is nil but AuthConfigController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAuthConfigControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAuthConfigControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAuthConfigController.AddFeatureHandlerCalls()) +func (mock *AuthConfigControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc + } + lockAuthConfigControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAuthConfigControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AuthConfigControllerMock) AddHandler(ctx context.Context, name string, handler v31.AuthConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AuthConfigControllerMock.AddHandlerFunc: method is nil but AuthConfigController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockAuthConfigControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAuthConfigControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAuthConfigController.AddHandlerCalls()) +func (mock *AuthConfigControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.AuthConfigHandlerFunc + } + lockAuthConfigControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAuthConfigControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *AuthConfigControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("AuthConfigControllerMock.EnqueueFunc: method is nil but AuthConfigController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAuthConfigControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockAuthConfigControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedAuthConfigController.EnqueueCalls()) +func (mock *AuthConfigControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAuthConfigControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockAuthConfigControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *AuthConfigControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("AuthConfigControllerMock.EnqueueAfterFunc: method is nil but AuthConfigController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockAuthConfigControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockAuthConfigControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedAuthConfigController.EnqueueAfterCalls()) +func (mock *AuthConfigControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockAuthConfigControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockAuthConfigControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *AuthConfigControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("AuthConfigControllerMock.GenericFunc: method is nil but AuthConfigController.Generic was just called") + } + callInfo := struct { + }{} + lockAuthConfigControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockAuthConfigControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedAuthConfigController.GenericCalls()) +func (mock *AuthConfigControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockAuthConfigControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockAuthConfigControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *AuthConfigControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("AuthConfigControllerMock.InformerFunc: method is nil but AuthConfigController.Informer was just called") + } + callInfo := struct { + }{} + lockAuthConfigControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockAuthConfigControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedAuthConfigController.InformerCalls()) +func (mock *AuthConfigControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockAuthConfigControllerMockInformer.RLock() + calls = mock.calls.Informer + lockAuthConfigControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *AuthConfigControllerMock) Lister() v31.AuthConfigLister { + if mock.ListerFunc == nil { + panic("AuthConfigControllerMock.ListerFunc: method is nil but AuthConfigController.Lister was just called") + } + callInfo := struct { + }{} + lockAuthConfigControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockAuthConfigControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedAuthConfigController.ListerCalls()) +func (mock *AuthConfigControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockAuthConfigControllerMockLister.RLock() + calls = mock.calls.Lister + lockAuthConfigControllerMockLister.RUnlock() + return calls +} + +var ( + lockAuthConfigInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockAuthConfigInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockAuthConfigInterfaceMockAddClusterScopedHandler sync.RWMutex + lockAuthConfigInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockAuthConfigInterfaceMockAddFeatureHandler sync.RWMutex + lockAuthConfigInterfaceMockAddFeatureLifecycle sync.RWMutex + lockAuthConfigInterfaceMockAddHandler sync.RWMutex + lockAuthConfigInterfaceMockAddLifecycle sync.RWMutex + lockAuthConfigInterfaceMockController sync.RWMutex + lockAuthConfigInterfaceMockCreate sync.RWMutex + lockAuthConfigInterfaceMockDelete sync.RWMutex + lockAuthConfigInterfaceMockDeleteCollection sync.RWMutex + lockAuthConfigInterfaceMockDeleteNamespaced sync.RWMutex + lockAuthConfigInterfaceMockGet sync.RWMutex + lockAuthConfigInterfaceMockGetNamespaced sync.RWMutex + lockAuthConfigInterfaceMockList sync.RWMutex + lockAuthConfigInterfaceMockListNamespaced sync.RWMutex + lockAuthConfigInterfaceMockObjectClient sync.RWMutex + lockAuthConfigInterfaceMockUpdate sync.RWMutex + lockAuthConfigInterfaceMockWatch sync.RWMutex +) + +// Ensure, that AuthConfigInterfaceMock does implement v31.AuthConfigInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.AuthConfigInterface = &AuthConfigInterfaceMock{} + +// AuthConfigInterfaceMock is a mock implementation of v31.AuthConfigInterface. +// +// func TestSomethingThatUsesAuthConfigInterface(t *testing.T) { +// +// // make and configure a mocked v31.AuthConfigInterface +// mockedAuthConfigInterface := &AuthConfigInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AuthConfigLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.AuthConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.AuthConfigLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.AuthConfigController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.AuthConfig) (*v3.AuthConfig, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.AuthConfigList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.AuthConfigList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.AuthConfig) (*v3.AuthConfig, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedAuthConfigInterface in code that requires v31.AuthConfigInterface +// // and then make assertions. +// +// } +type AuthConfigInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AuthConfigLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.AuthConfigHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.AuthConfigLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.AuthConfigController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.AuthConfig) (*v3.AuthConfig, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.AuthConfig, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.AuthConfig, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.AuthConfigList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.AuthConfigList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.AuthConfig) (*v3.AuthConfig, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AuthConfigHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AuthConfigLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AuthConfigHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AuthConfigLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AuthConfigHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AuthConfigLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AuthConfigHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AuthConfigLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.AuthConfig + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.AuthConfig + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AuthConfigInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AuthConfigInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but AuthConfigInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAuthConfigInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAuthConfigInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *AuthConfigInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc + } + lockAuthConfigInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAuthConfigInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *AuthConfigInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("AuthConfigInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but AuthConfigInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAuthConfigInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockAuthConfigInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *AuthConfigInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle + } + lockAuthConfigInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockAuthConfigInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AuthConfigInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.AuthConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AuthConfigInterfaceMock.AddClusterScopedHandlerFunc: method is nil but AuthConfigInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAuthConfigInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAuthConfigInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddClusterScopedHandlerCalls()) +func (mock *AuthConfigInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AuthConfigHandlerFunc + } + lockAuthConfigInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAuthConfigInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *AuthConfigInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.AuthConfigLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("AuthConfigInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but AuthConfigInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAuthConfigInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockAuthConfigInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddClusterScopedLifecycleCalls()) +func (mock *AuthConfigInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AuthConfigLifecycle + } + lockAuthConfigInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockAuthConfigInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AuthConfigInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AuthConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AuthConfigInterfaceMock.AddFeatureHandlerFunc: method is nil but AuthConfigInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAuthConfigInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAuthConfigInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddFeatureHandlerCalls()) +func (mock *AuthConfigInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AuthConfigHandlerFunc + } + lockAuthConfigInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAuthConfigInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *AuthConfigInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.AuthConfigLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("AuthConfigInterfaceMock.AddFeatureLifecycleFunc: method is nil but AuthConfigInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AuthConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockAuthConfigInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockAuthConfigInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddFeatureLifecycleCalls()) +func (mock *AuthConfigInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AuthConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AuthConfigLifecycle + } + lockAuthConfigInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockAuthConfigInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AuthConfigInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.AuthConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AuthConfigInterfaceMock.AddHandlerFunc: method is nil but AuthConfigInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.AuthConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockAuthConfigInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAuthConfigInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddHandlerCalls()) +func (mock *AuthConfigInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.AuthConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.AuthConfigHandlerFunc + } + lockAuthConfigInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAuthConfigInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *AuthConfigInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.AuthConfigLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("AuthConfigInterfaceMock.AddLifecycleFunc: method is nil but AuthConfigInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.AuthConfigLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockAuthConfigInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockAuthConfigInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedAuthConfigInterface.AddLifecycleCalls()) +func (mock *AuthConfigInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.AuthConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.AuthConfigLifecycle + } + lockAuthConfigInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockAuthConfigInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *AuthConfigInterfaceMock) Controller() v31.AuthConfigController { + if mock.ControllerFunc == nil { + panic("AuthConfigInterfaceMock.ControllerFunc: method is nil but AuthConfigInterface.Controller was just called") + } + callInfo := struct { + }{} + lockAuthConfigInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockAuthConfigInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedAuthConfigInterface.ControllerCalls()) +func (mock *AuthConfigInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockAuthConfigInterfaceMockController.RLock() + calls = mock.calls.Controller + lockAuthConfigInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *AuthConfigInterfaceMock) Create(in1 *v3.AuthConfig) (*v3.AuthConfig, error) { + if mock.CreateFunc == nil { + panic("AuthConfigInterfaceMock.CreateFunc: method is nil but AuthConfigInterface.Create was just called") + } + callInfo := struct { + In1 *v3.AuthConfig + }{ + In1: in1, + } + lockAuthConfigInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockAuthConfigInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedAuthConfigInterface.CreateCalls()) +func (mock *AuthConfigInterfaceMock) CreateCalls() []struct { + In1 *v3.AuthConfig +} { + var calls []struct { + In1 *v3.AuthConfig + } + lockAuthConfigInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockAuthConfigInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *AuthConfigInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("AuthConfigInterfaceMock.DeleteFunc: method is nil but AuthConfigInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockAuthConfigInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockAuthConfigInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedAuthConfigInterface.DeleteCalls()) +func (mock *AuthConfigInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockAuthConfigInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockAuthConfigInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *AuthConfigInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("AuthConfigInterfaceMock.DeleteCollectionFunc: method is nil but AuthConfigInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockAuthConfigInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockAuthConfigInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedAuthConfigInterface.DeleteCollectionCalls()) +func (mock *AuthConfigInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockAuthConfigInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockAuthConfigInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *AuthConfigInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("AuthConfigInterfaceMock.DeleteNamespacedFunc: method is nil but AuthConfigInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockAuthConfigInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockAuthConfigInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedAuthConfigInterface.DeleteNamespacedCalls()) +func (mock *AuthConfigInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockAuthConfigInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockAuthConfigInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *AuthConfigInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { + if mock.GetFunc == nil { + panic("AuthConfigInterfaceMock.GetFunc: method is nil but AuthConfigInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockAuthConfigInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAuthConfigInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAuthConfigInterface.GetCalls()) +func (mock *AuthConfigInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockAuthConfigInterfaceMockGet.RLock() + calls = mock.calls.Get + lockAuthConfigInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *AuthConfigInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { + if mock.GetNamespacedFunc == nil { + panic("AuthConfigInterfaceMock.GetNamespacedFunc: method is nil but AuthConfigInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockAuthConfigInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockAuthConfigInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedAuthConfigInterface.GetNamespacedCalls()) +func (mock *AuthConfigInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockAuthConfigInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockAuthConfigInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AuthConfigInterfaceMock) List(opts metav1.ListOptions) (*v3.AuthConfigList, error) { + if mock.ListFunc == nil { + panic("AuthConfigInterfaceMock.ListFunc: method is nil but AuthConfigInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAuthConfigInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAuthConfigInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAuthConfigInterface.ListCalls()) +func (mock *AuthConfigInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAuthConfigInterfaceMockList.RLock() + calls = mock.calls.List + lockAuthConfigInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *AuthConfigInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AuthConfigList, error) { + if mock.ListNamespacedFunc == nil { + panic("AuthConfigInterfaceMock.ListNamespacedFunc: method is nil but AuthConfigInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockAuthConfigInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockAuthConfigInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedAuthConfigInterface.ListNamespacedCalls()) +func (mock *AuthConfigInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockAuthConfigInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockAuthConfigInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *AuthConfigInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("AuthConfigInterfaceMock.ObjectClientFunc: method is nil but AuthConfigInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockAuthConfigInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockAuthConfigInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedAuthConfigInterface.ObjectClientCalls()) +func (mock *AuthConfigInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockAuthConfigInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockAuthConfigInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *AuthConfigInterfaceMock) Update(in1 *v3.AuthConfig) (*v3.AuthConfig, error) { + if mock.UpdateFunc == nil { + panic("AuthConfigInterfaceMock.UpdateFunc: method is nil but AuthConfigInterface.Update was just called") + } + callInfo := struct { + In1 *v3.AuthConfig + }{ + In1: in1, + } + lockAuthConfigInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockAuthConfigInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedAuthConfigInterface.UpdateCalls()) +func (mock *AuthConfigInterfaceMock) UpdateCalls() []struct { + In1 *v3.AuthConfig +} { + var calls []struct { + In1 *v3.AuthConfig + } + lockAuthConfigInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockAuthConfigInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *AuthConfigInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("AuthConfigInterfaceMock.WatchFunc: method is nil but AuthConfigInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAuthConfigInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockAuthConfigInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedAuthConfigInterface.WatchCalls()) +func (mock *AuthConfigInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAuthConfigInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockAuthConfigInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockAuthConfigsGetterMockAuthConfigs sync.RWMutex +) + +// Ensure, that AuthConfigsGetterMock does implement v31.AuthConfigsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.AuthConfigsGetter = &AuthConfigsGetterMock{} + +// AuthConfigsGetterMock is a mock implementation of v31.AuthConfigsGetter. +// +// func TestSomethingThatUsesAuthConfigsGetter(t *testing.T) { +// +// // make and configure a mocked v31.AuthConfigsGetter +// mockedAuthConfigsGetter := &AuthConfigsGetterMock{ +// AuthConfigsFunc: func(namespace string) v31.AuthConfigInterface { +// panic("mock out the AuthConfigs method") +// }, +// } +// +// // use mockedAuthConfigsGetter in code that requires v31.AuthConfigsGetter +// // and then make assertions. +// +// } +type AuthConfigsGetterMock struct { + // AuthConfigsFunc mocks the AuthConfigs method. + AuthConfigsFunc func(namespace string) v31.AuthConfigInterface + + // calls tracks calls to the methods. + calls struct { + // AuthConfigs holds details about calls to the AuthConfigs method. + AuthConfigs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// AuthConfigs calls AuthConfigsFunc. +func (mock *AuthConfigsGetterMock) AuthConfigs(namespace string) v31.AuthConfigInterface { + if mock.AuthConfigsFunc == nil { + panic("AuthConfigsGetterMock.AuthConfigsFunc: method is nil but AuthConfigsGetter.AuthConfigs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockAuthConfigsGetterMockAuthConfigs.Lock() + mock.calls.AuthConfigs = append(mock.calls.AuthConfigs, callInfo) + lockAuthConfigsGetterMockAuthConfigs.Unlock() + return mock.AuthConfigsFunc(namespace) +} + +// AuthConfigsCalls gets all the calls that were made to AuthConfigs. +// Check the length with: +// +// len(mockedAuthConfigsGetter.AuthConfigsCalls()) +func (mock *AuthConfigsGetterMock) AuthConfigsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockAuthConfigsGetterMockAuthConfigs.RLock() + calls = mock.calls.AuthConfigs + lockAuthConfigsGetterMockAuthConfigs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_mock.go new file mode 100644 index 0000000..89d2054 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCatalogListerMockGet sync.RWMutex + lockCatalogListerMockList sync.RWMutex +) + +// Ensure, that CatalogListerMock does implement v31.CatalogLister. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogLister = &CatalogListerMock{} + +// CatalogListerMock is a mock implementation of v31.CatalogLister. +// +// func TestSomethingThatUsesCatalogLister(t *testing.T) { +// +// // make and configure a mocked v31.CatalogLister +// mockedCatalogLister := &CatalogListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Catalog, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Catalog, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCatalogLister in code that requires v31.CatalogLister +// // and then make assertions. +// +// } +type CatalogListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Catalog, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Catalog, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CatalogListerMock) Get(namespace string, name string) (*v3.Catalog, error) { + if mock.GetFunc == nil { + panic("CatalogListerMock.GetFunc: method is nil but CatalogLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogLister.GetCalls()) +func (mock *CatalogListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogListerMockGet.RLock() + calls = mock.calls.Get + lockCatalogListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogListerMock) List(namespace string, selector labels.Selector) ([]*v3.Catalog, error) { + if mock.ListFunc == nil { + panic("CatalogListerMock.ListFunc: method is nil but CatalogLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCatalogListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogLister.ListCalls()) +func (mock *CatalogListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCatalogListerMockList.RLock() + calls = mock.calls.List + lockCatalogListerMockList.RUnlock() + return calls +} + +var ( + lockCatalogControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogControllerMockAddClusterScopedHandler sync.RWMutex + lockCatalogControllerMockAddFeatureHandler sync.RWMutex + lockCatalogControllerMockAddHandler sync.RWMutex + lockCatalogControllerMockEnqueue sync.RWMutex + lockCatalogControllerMockEnqueueAfter sync.RWMutex + lockCatalogControllerMockGeneric sync.RWMutex + lockCatalogControllerMockInformer sync.RWMutex + lockCatalogControllerMockLister sync.RWMutex +) + +// Ensure, that CatalogControllerMock does implement v31.CatalogController. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogController = &CatalogControllerMock{} + +// CatalogControllerMock is a mock implementation of v31.CatalogController. +// +// func TestSomethingThatUsesCatalogController(t *testing.T) { +// +// // make and configure a mocked v31.CatalogController +// mockedCatalogController := &CatalogControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.CatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.CatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.CatalogLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCatalogController in code that requires v31.CatalogController +// // and then make assertions. +// +// } +type CatalogControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.CatalogHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.CatalogHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.CatalogLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.CatalogHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogHandlerFunc + } + lockCatalogControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.CatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogControllerMock.AddClusterScopedHandlerFunc: method is nil but CatalogController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogController.AddClusterScopedHandlerCalls()) +func (mock *CatalogControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogHandlerFunc + } + lockCatalogControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogControllerMock.AddFeatureHandlerFunc: method is nil but CatalogController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogController.AddFeatureHandlerCalls()) +func (mock *CatalogControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc + } + lockCatalogControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogControllerMock) AddHandler(ctx context.Context, name string, handler v31.CatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogControllerMock.AddHandlerFunc: method is nil but CatalogController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCatalogControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogController.AddHandlerCalls()) +func (mock *CatalogControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.CatalogHandlerFunc + } + lockCatalogControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CatalogControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CatalogControllerMock.EnqueueFunc: method is nil but CatalogController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCatalogControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCatalogController.EnqueueCalls()) +func (mock *CatalogControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCatalogControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CatalogControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CatalogControllerMock.EnqueueAfterFunc: method is nil but CatalogController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCatalogControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCatalogControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCatalogController.EnqueueAfterCalls()) +func (mock *CatalogControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCatalogControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCatalogControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CatalogControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CatalogControllerMock.GenericFunc: method is nil but CatalogController.Generic was just called") + } + callInfo := struct { + }{} + lockCatalogControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCatalogControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCatalogController.GenericCalls()) +func (mock *CatalogControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCatalogControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCatalogControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CatalogControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CatalogControllerMock.InformerFunc: method is nil but CatalogController.Informer was just called") + } + callInfo := struct { + }{} + lockCatalogControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCatalogControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCatalogController.InformerCalls()) +func (mock *CatalogControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCatalogControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCatalogControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CatalogControllerMock) Lister() v31.CatalogLister { + if mock.ListerFunc == nil { + panic("CatalogControllerMock.ListerFunc: method is nil but CatalogController.Lister was just called") + } + callInfo := struct { + }{} + lockCatalogControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCatalogControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCatalogController.ListerCalls()) +func (mock *CatalogControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCatalogControllerMockLister.RLock() + calls = mock.calls.Lister + lockCatalogControllerMockLister.RUnlock() + return calls +} + +var ( + lockCatalogInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCatalogInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCatalogInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCatalogInterfaceMockAddFeatureHandler sync.RWMutex + lockCatalogInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCatalogInterfaceMockAddHandler sync.RWMutex + lockCatalogInterfaceMockAddLifecycle sync.RWMutex + lockCatalogInterfaceMockController sync.RWMutex + lockCatalogInterfaceMockCreate sync.RWMutex + lockCatalogInterfaceMockDelete sync.RWMutex + lockCatalogInterfaceMockDeleteCollection sync.RWMutex + lockCatalogInterfaceMockDeleteNamespaced sync.RWMutex + lockCatalogInterfaceMockGet sync.RWMutex + lockCatalogInterfaceMockGetNamespaced sync.RWMutex + lockCatalogInterfaceMockList sync.RWMutex + lockCatalogInterfaceMockListNamespaced sync.RWMutex + lockCatalogInterfaceMockObjectClient sync.RWMutex + lockCatalogInterfaceMockUpdate sync.RWMutex + lockCatalogInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CatalogInterfaceMock does implement v31.CatalogInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogInterface = &CatalogInterfaceMock{} + +// CatalogInterfaceMock is a mock implementation of v31.CatalogInterface. +// +// func TestSomethingThatUsesCatalogInterface(t *testing.T) { +// +// // make and configure a mocked v31.CatalogInterface +// mockedCatalogInterface := &CatalogInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.CatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.CatalogLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.CatalogController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Catalog) (*v3.Catalog, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Catalog, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Catalog, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.CatalogList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.CatalogList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Catalog) (*v3.Catalog, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCatalogInterface in code that requires v31.CatalogInterface +// // and then make assertions. +// +// } +type CatalogInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.CatalogHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.CatalogLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.CatalogController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Catalog) (*v3.Catalog, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Catalog, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Catalog, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.CatalogList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.CatalogList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Catalog) (*v3.Catalog, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Catalog + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Catalog + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogHandlerFunc + } + lockCatalogInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CatalogInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CatalogInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CatalogInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CatalogInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle + } + lockCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CatalogInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogInterface.AddClusterScopedHandlerCalls()) +func (mock *CatalogInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogHandlerFunc + } + lockCatalogInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CatalogInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CatalogInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CatalogInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCatalogInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCatalogInterface.AddClusterScopedLifecycleCalls()) +func (mock *CatalogInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogLifecycle + } + lockCatalogInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCatalogInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogInterfaceMock.AddFeatureHandlerFunc: method is nil but CatalogInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogInterface.AddFeatureHandlerCalls()) +func (mock *CatalogInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogHandlerFunc + } + lockCatalogInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CatalogInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CatalogInterfaceMock.AddFeatureLifecycleFunc: method is nil but CatalogInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCatalogInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogInterface.AddFeatureLifecycleCalls()) +func (mock *CatalogInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogLifecycle + } + lockCatalogInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCatalogInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.CatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogInterfaceMock.AddHandlerFunc: method is nil but CatalogInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.CatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCatalogInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogInterface.AddHandlerCalls()) +func (mock *CatalogInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.CatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.CatalogHandlerFunc + } + lockCatalogInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CatalogInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.CatalogLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CatalogInterfaceMock.AddLifecycleFunc: method is nil but CatalogInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCatalogInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCatalogInterface.AddLifecycleCalls()) +func (mock *CatalogInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogLifecycle + } + lockCatalogInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCatalogInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CatalogInterfaceMock) Controller() v31.CatalogController { + if mock.ControllerFunc == nil { + panic("CatalogInterfaceMock.ControllerFunc: method is nil but CatalogInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCatalogInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCatalogInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCatalogInterface.ControllerCalls()) +func (mock *CatalogInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCatalogInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCatalogInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CatalogInterfaceMock) Create(in1 *v3.Catalog) (*v3.Catalog, error) { + if mock.CreateFunc == nil { + panic("CatalogInterfaceMock.CreateFunc: method is nil but CatalogInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Catalog + }{ + In1: in1, + } + lockCatalogInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCatalogInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCatalogInterface.CreateCalls()) +func (mock *CatalogInterfaceMock) CreateCalls() []struct { + In1 *v3.Catalog +} { + var calls []struct { + In1 *v3.Catalog + } + lockCatalogInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCatalogInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CatalogInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CatalogInterfaceMock.DeleteFunc: method is nil but CatalogInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCatalogInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCatalogInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCatalogInterface.DeleteCalls()) +func (mock *CatalogInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCatalogInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCatalogInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CatalogInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CatalogInterfaceMock.DeleteCollectionFunc: method is nil but CatalogInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCatalogInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCatalogInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCatalogInterface.DeleteCollectionCalls()) +func (mock *CatalogInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCatalogInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCatalogInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CatalogInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CatalogInterfaceMock.DeleteNamespacedFunc: method is nil but CatalogInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCatalogInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCatalogInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCatalogInterface.DeleteNamespacedCalls()) +func (mock *CatalogInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCatalogInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCatalogInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CatalogInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Catalog, error) { + if mock.GetFunc == nil { + panic("CatalogInterfaceMock.GetFunc: method is nil but CatalogInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCatalogInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogInterface.GetCalls()) +func (mock *CatalogInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCatalogInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCatalogInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CatalogInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Catalog, error) { + if mock.GetNamespacedFunc == nil { + panic("CatalogInterfaceMock.GetNamespacedFunc: method is nil but CatalogInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCatalogInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCatalogInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCatalogInterface.GetNamespacedCalls()) +func (mock *CatalogInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCatalogInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCatalogInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogInterfaceMock) List(opts metav1.ListOptions) (*v3.CatalogList, error) { + if mock.ListFunc == nil { + panic("CatalogInterfaceMock.ListFunc: method is nil but CatalogInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogInterface.ListCalls()) +func (mock *CatalogInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogInterfaceMockList.RLock() + calls = mock.calls.List + lockCatalogInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CatalogInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogList, error) { + if mock.ListNamespacedFunc == nil { + panic("CatalogInterfaceMock.ListNamespacedFunc: method is nil but CatalogInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCatalogInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCatalogInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCatalogInterface.ListNamespacedCalls()) +func (mock *CatalogInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCatalogInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCatalogInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CatalogInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CatalogInterfaceMock.ObjectClientFunc: method is nil but CatalogInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCatalogInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCatalogInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCatalogInterface.ObjectClientCalls()) +func (mock *CatalogInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCatalogInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCatalogInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CatalogInterfaceMock) Update(in1 *v3.Catalog) (*v3.Catalog, error) { + if mock.UpdateFunc == nil { + panic("CatalogInterfaceMock.UpdateFunc: method is nil but CatalogInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Catalog + }{ + In1: in1, + } + lockCatalogInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCatalogInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCatalogInterface.UpdateCalls()) +func (mock *CatalogInterfaceMock) UpdateCalls() []struct { + In1 *v3.Catalog +} { + var calls []struct { + In1 *v3.Catalog + } + lockCatalogInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCatalogInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CatalogInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CatalogInterfaceMock.WatchFunc: method is nil but CatalogInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCatalogInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCatalogInterface.WatchCalls()) +func (mock *CatalogInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCatalogInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCatalogsGetterMockCatalogs sync.RWMutex +) + +// Ensure, that CatalogsGetterMock does implement v31.CatalogsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogsGetter = &CatalogsGetterMock{} + +// CatalogsGetterMock is a mock implementation of v31.CatalogsGetter. +// +// func TestSomethingThatUsesCatalogsGetter(t *testing.T) { +// +// // make and configure a mocked v31.CatalogsGetter +// mockedCatalogsGetter := &CatalogsGetterMock{ +// CatalogsFunc: func(namespace string) v31.CatalogInterface { +// panic("mock out the Catalogs method") +// }, +// } +// +// // use mockedCatalogsGetter in code that requires v31.CatalogsGetter +// // and then make assertions. +// +// } +type CatalogsGetterMock struct { + // CatalogsFunc mocks the Catalogs method. + CatalogsFunc func(namespace string) v31.CatalogInterface + + // calls tracks calls to the methods. + calls struct { + // Catalogs holds details about calls to the Catalogs method. + Catalogs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Catalogs calls CatalogsFunc. +func (mock *CatalogsGetterMock) Catalogs(namespace string) v31.CatalogInterface { + if mock.CatalogsFunc == nil { + panic("CatalogsGetterMock.CatalogsFunc: method is nil but CatalogsGetter.Catalogs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCatalogsGetterMockCatalogs.Lock() + mock.calls.Catalogs = append(mock.calls.Catalogs, callInfo) + lockCatalogsGetterMockCatalogs.Unlock() + return mock.CatalogsFunc(namespace) +} + +// CatalogsCalls gets all the calls that were made to Catalogs. +// Check the length with: +// +// len(mockedCatalogsGetter.CatalogsCalls()) +func (mock *CatalogsGetterMock) CatalogsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCatalogsGetterMockCatalogs.RLock() + calls = mock.calls.Catalogs + lockCatalogsGetterMockCatalogs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_mock.go new file mode 100644 index 0000000..1700573 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCatalogTemplateListerMockGet sync.RWMutex + lockCatalogTemplateListerMockList sync.RWMutex +) + +// Ensure, that CatalogTemplateListerMock does implement v31.CatalogTemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateLister = &CatalogTemplateListerMock{} + +// CatalogTemplateListerMock is a mock implementation of v31.CatalogTemplateLister. +// +// func TestSomethingThatUsesCatalogTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateLister +// mockedCatalogTemplateLister := &CatalogTemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.CatalogTemplate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.CatalogTemplate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCatalogTemplateLister in code that requires v31.CatalogTemplateLister +// // and then make assertions. +// +// } +type CatalogTemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.CatalogTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.CatalogTemplate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CatalogTemplateListerMock) Get(namespace string, name string) (*v3.CatalogTemplate, error) { + if mock.GetFunc == nil { + panic("CatalogTemplateListerMock.GetFunc: method is nil but CatalogTemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogTemplateLister.GetCalls()) +func (mock *CatalogTemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockCatalogTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogTemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.CatalogTemplate, error) { + if mock.ListFunc == nil { + panic("CatalogTemplateListerMock.ListFunc: method is nil but CatalogTemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCatalogTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogTemplateLister.ListCalls()) +func (mock *CatalogTemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCatalogTemplateListerMockList.RLock() + calls = mock.calls.List + lockCatalogTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockCatalogTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockCatalogTemplateControllerMockAddFeatureHandler sync.RWMutex + lockCatalogTemplateControllerMockAddHandler sync.RWMutex + lockCatalogTemplateControllerMockEnqueue sync.RWMutex + lockCatalogTemplateControllerMockEnqueueAfter sync.RWMutex + lockCatalogTemplateControllerMockGeneric sync.RWMutex + lockCatalogTemplateControllerMockInformer sync.RWMutex + lockCatalogTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that CatalogTemplateControllerMock does implement v31.CatalogTemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateController = &CatalogTemplateControllerMock{} + +// CatalogTemplateControllerMock is a mock implementation of v31.CatalogTemplateController. +// +// func TestSomethingThatUsesCatalogTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateController +// mockedCatalogTemplateController := &CatalogTemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.CatalogTemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCatalogTemplateController in code that requires v31.CatalogTemplateController +// // and then make assertions. +// +// } +type CatalogTemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.CatalogTemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.CatalogTemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogTemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogTemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.CatalogTemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogTemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogTemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogTemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogTemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogTemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogTemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but CatalogTemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogTemplateController.AddClusterScopedHandlerCalls()) +func (mock *CatalogTemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogTemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogTemplateControllerMock.AddFeatureHandlerFunc: method is nil but CatalogTemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateController.AddFeatureHandlerCalls()) +func (mock *CatalogTemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogTemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.CatalogTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogTemplateControllerMock.AddHandlerFunc: method is nil but CatalogTemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCatalogTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogTemplateController.AddHandlerCalls()) +func (mock *CatalogTemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CatalogTemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CatalogTemplateControllerMock.EnqueueFunc: method is nil but CatalogTemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCatalogTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCatalogTemplateController.EnqueueCalls()) +func (mock *CatalogTemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCatalogTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CatalogTemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CatalogTemplateControllerMock.EnqueueAfterFunc: method is nil but CatalogTemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCatalogTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCatalogTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCatalogTemplateController.EnqueueAfterCalls()) +func (mock *CatalogTemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCatalogTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCatalogTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CatalogTemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CatalogTemplateControllerMock.GenericFunc: method is nil but CatalogTemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCatalogTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCatalogTemplateController.GenericCalls()) +func (mock *CatalogTemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCatalogTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CatalogTemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CatalogTemplateControllerMock.InformerFunc: method is nil but CatalogTemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCatalogTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCatalogTemplateController.InformerCalls()) +func (mock *CatalogTemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCatalogTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CatalogTemplateControllerMock) Lister() v31.CatalogTemplateLister { + if mock.ListerFunc == nil { + panic("CatalogTemplateControllerMock.ListerFunc: method is nil but CatalogTemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCatalogTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCatalogTemplateController.ListerCalls()) +func (mock *CatalogTemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockCatalogTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCatalogTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCatalogTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCatalogTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockCatalogTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCatalogTemplateInterfaceMockAddHandler sync.RWMutex + lockCatalogTemplateInterfaceMockAddLifecycle sync.RWMutex + lockCatalogTemplateInterfaceMockController sync.RWMutex + lockCatalogTemplateInterfaceMockCreate sync.RWMutex + lockCatalogTemplateInterfaceMockDelete sync.RWMutex + lockCatalogTemplateInterfaceMockDeleteCollection sync.RWMutex + lockCatalogTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockCatalogTemplateInterfaceMockGet sync.RWMutex + lockCatalogTemplateInterfaceMockGetNamespaced sync.RWMutex + lockCatalogTemplateInterfaceMockList sync.RWMutex + lockCatalogTemplateInterfaceMockListNamespaced sync.RWMutex + lockCatalogTemplateInterfaceMockObjectClient sync.RWMutex + lockCatalogTemplateInterfaceMockUpdate sync.RWMutex + lockCatalogTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CatalogTemplateInterfaceMock does implement v31.CatalogTemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateInterface = &CatalogTemplateInterfaceMock{} + +// CatalogTemplateInterfaceMock is a mock implementation of v31.CatalogTemplateInterface. +// +// func TestSomethingThatUsesCatalogTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateInterface +// mockedCatalogTemplateInterface := &CatalogTemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.CatalogTemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.CatalogTemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCatalogTemplateInterface in code that requires v31.CatalogTemplateInterface +// // and then make assertions. +// +// } +type CatalogTemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.CatalogTemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.CatalogTemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.CatalogTemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogTemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogTemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.CatalogTemplate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.CatalogTemplate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogTemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogTemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CatalogTemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CatalogTemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle + } + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCatalogTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogTemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CatalogTemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CatalogTemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CatalogTemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCatalogTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *CatalogTemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateLifecycle + } + lockCatalogTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCatalogTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogTemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogTemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but CatalogTemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddFeatureHandlerCalls()) +func (mock *CatalogTemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CatalogTemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CatalogTemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but CatalogTemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCatalogTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *CatalogTemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateLifecycle + } + lockCatalogTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCatalogTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogTemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogTemplateInterfaceMock.AddHandlerFunc: method is nil but CatalogTemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddHandlerCalls()) +func (mock *CatalogTemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateHandlerFunc + } + lockCatalogTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CatalogTemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.CatalogTemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CatalogTemplateInterfaceMock.AddLifecycleFunc: method is nil but CatalogTemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCatalogTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.AddLifecycleCalls()) +func (mock *CatalogTemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateLifecycle + } + lockCatalogTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCatalogTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CatalogTemplateInterfaceMock) Controller() v31.CatalogTemplateController { + if mock.ControllerFunc == nil { + panic("CatalogTemplateInterfaceMock.ControllerFunc: method is nil but CatalogTemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCatalogTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.ControllerCalls()) +func (mock *CatalogTemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCatalogTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CatalogTemplateInterfaceMock) Create(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + if mock.CreateFunc == nil { + panic("CatalogTemplateInterfaceMock.CreateFunc: method is nil but CatalogTemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.CatalogTemplate + }{ + In1: in1, + } + lockCatalogTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCatalogTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.CreateCalls()) +func (mock *CatalogTemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.CatalogTemplate +} { + var calls []struct { + In1 *v3.CatalogTemplate + } + lockCatalogTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCatalogTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CatalogTemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CatalogTemplateInterfaceMock.DeleteFunc: method is nil but CatalogTemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCatalogTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCatalogTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.DeleteCalls()) +func (mock *CatalogTemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCatalogTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCatalogTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CatalogTemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CatalogTemplateInterfaceMock.DeleteCollectionFunc: method is nil but CatalogTemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCatalogTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCatalogTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.DeleteCollectionCalls()) +func (mock *CatalogTemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCatalogTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCatalogTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CatalogTemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CatalogTemplateInterfaceMock.DeleteNamespacedFunc: method is nil but CatalogTemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCatalogTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCatalogTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.DeleteNamespacedCalls()) +func (mock *CatalogTemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCatalogTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCatalogTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CatalogTemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { + if mock.GetFunc == nil { + panic("CatalogTemplateInterfaceMock.GetFunc: method is nil but CatalogTemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCatalogTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.GetCalls()) +func (mock *CatalogTemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCatalogTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCatalogTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CatalogTemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { + if mock.GetNamespacedFunc == nil { + panic("CatalogTemplateInterfaceMock.GetNamespacedFunc: method is nil but CatalogTemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCatalogTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCatalogTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.GetNamespacedCalls()) +func (mock *CatalogTemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCatalogTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCatalogTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogTemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { + if mock.ListFunc == nil { + panic("CatalogTemplateInterfaceMock.ListFunc: method is nil but CatalogTemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.ListCalls()) +func (mock *CatalogTemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockCatalogTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CatalogTemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("CatalogTemplateInterfaceMock.ListNamespacedFunc: method is nil but CatalogTemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCatalogTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCatalogTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.ListNamespacedCalls()) +func (mock *CatalogTemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCatalogTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCatalogTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CatalogTemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CatalogTemplateInterfaceMock.ObjectClientFunc: method is nil but CatalogTemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCatalogTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.ObjectClientCalls()) +func (mock *CatalogTemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCatalogTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CatalogTemplateInterfaceMock) Update(in1 *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + if mock.UpdateFunc == nil { + panic("CatalogTemplateInterfaceMock.UpdateFunc: method is nil but CatalogTemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.CatalogTemplate + }{ + In1: in1, + } + lockCatalogTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCatalogTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.UpdateCalls()) +func (mock *CatalogTemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.CatalogTemplate +} { + var calls []struct { + In1 *v3.CatalogTemplate + } + lockCatalogTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCatalogTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CatalogTemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CatalogTemplateInterfaceMock.WatchFunc: method is nil but CatalogTemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCatalogTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCatalogTemplateInterface.WatchCalls()) +func (mock *CatalogTemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCatalogTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCatalogTemplatesGetterMockCatalogTemplates sync.RWMutex +) + +// Ensure, that CatalogTemplatesGetterMock does implement v31.CatalogTemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplatesGetter = &CatalogTemplatesGetterMock{} + +// CatalogTemplatesGetterMock is a mock implementation of v31.CatalogTemplatesGetter. +// +// func TestSomethingThatUsesCatalogTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplatesGetter +// mockedCatalogTemplatesGetter := &CatalogTemplatesGetterMock{ +// CatalogTemplatesFunc: func(namespace string) v31.CatalogTemplateInterface { +// panic("mock out the CatalogTemplates method") +// }, +// } +// +// // use mockedCatalogTemplatesGetter in code that requires v31.CatalogTemplatesGetter +// // and then make assertions. +// +// } +type CatalogTemplatesGetterMock struct { + // CatalogTemplatesFunc mocks the CatalogTemplates method. + CatalogTemplatesFunc func(namespace string) v31.CatalogTemplateInterface + + // calls tracks calls to the methods. + calls struct { + // CatalogTemplates holds details about calls to the CatalogTemplates method. + CatalogTemplates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// CatalogTemplates calls CatalogTemplatesFunc. +func (mock *CatalogTemplatesGetterMock) CatalogTemplates(namespace string) v31.CatalogTemplateInterface { + if mock.CatalogTemplatesFunc == nil { + panic("CatalogTemplatesGetterMock.CatalogTemplatesFunc: method is nil but CatalogTemplatesGetter.CatalogTemplates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCatalogTemplatesGetterMockCatalogTemplates.Lock() + mock.calls.CatalogTemplates = append(mock.calls.CatalogTemplates, callInfo) + lockCatalogTemplatesGetterMockCatalogTemplates.Unlock() + return mock.CatalogTemplatesFunc(namespace) +} + +// CatalogTemplatesCalls gets all the calls that were made to CatalogTemplates. +// Check the length with: +// +// len(mockedCatalogTemplatesGetter.CatalogTemplatesCalls()) +func (mock *CatalogTemplatesGetterMock) CatalogTemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCatalogTemplatesGetterMockCatalogTemplates.RLock() + calls = mock.calls.CatalogTemplates + lockCatalogTemplatesGetterMockCatalogTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_version_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_version_mock.go new file mode 100644 index 0000000..81ac924 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_catalog_template_version_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCatalogTemplateVersionListerMockGet sync.RWMutex + lockCatalogTemplateVersionListerMockList sync.RWMutex +) + +// Ensure, that CatalogTemplateVersionListerMock does implement v31.CatalogTemplateVersionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateVersionLister = &CatalogTemplateVersionListerMock{} + +// CatalogTemplateVersionListerMock is a mock implementation of v31.CatalogTemplateVersionLister. +// +// func TestSomethingThatUsesCatalogTemplateVersionLister(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateVersionLister +// mockedCatalogTemplateVersionLister := &CatalogTemplateVersionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.CatalogTemplateVersion, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.CatalogTemplateVersion, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCatalogTemplateVersionLister in code that requires v31.CatalogTemplateVersionLister +// // and then make assertions. +// +// } +type CatalogTemplateVersionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.CatalogTemplateVersion, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.CatalogTemplateVersion, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CatalogTemplateVersionListerMock) Get(namespace string, name string) (*v3.CatalogTemplateVersion, error) { + if mock.GetFunc == nil { + panic("CatalogTemplateVersionListerMock.GetFunc: method is nil but CatalogTemplateVersionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogTemplateVersionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogTemplateVersionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogTemplateVersionLister.GetCalls()) +func (mock *CatalogTemplateVersionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogTemplateVersionListerMockGet.RLock() + calls = mock.calls.Get + lockCatalogTemplateVersionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogTemplateVersionListerMock) List(namespace string, selector labels.Selector) ([]*v3.CatalogTemplateVersion, error) { + if mock.ListFunc == nil { + panic("CatalogTemplateVersionListerMock.ListFunc: method is nil but CatalogTemplateVersionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCatalogTemplateVersionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogTemplateVersionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogTemplateVersionLister.ListCalls()) +func (mock *CatalogTemplateVersionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCatalogTemplateVersionListerMockList.RLock() + calls = mock.calls.List + lockCatalogTemplateVersionListerMockList.RUnlock() + return calls +} + +var ( + lockCatalogTemplateVersionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogTemplateVersionControllerMockAddClusterScopedHandler sync.RWMutex + lockCatalogTemplateVersionControllerMockAddFeatureHandler sync.RWMutex + lockCatalogTemplateVersionControllerMockAddHandler sync.RWMutex + lockCatalogTemplateVersionControllerMockEnqueue sync.RWMutex + lockCatalogTemplateVersionControllerMockEnqueueAfter sync.RWMutex + lockCatalogTemplateVersionControllerMockGeneric sync.RWMutex + lockCatalogTemplateVersionControllerMockInformer sync.RWMutex + lockCatalogTemplateVersionControllerMockLister sync.RWMutex +) + +// Ensure, that CatalogTemplateVersionControllerMock does implement v31.CatalogTemplateVersionController. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateVersionController = &CatalogTemplateVersionControllerMock{} + +// CatalogTemplateVersionControllerMock is a mock implementation of v31.CatalogTemplateVersionController. +// +// func TestSomethingThatUsesCatalogTemplateVersionController(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateVersionController +// mockedCatalogTemplateVersionController := &CatalogTemplateVersionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.CatalogTemplateVersionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCatalogTemplateVersionController in code that requires v31.CatalogTemplateVersionController +// // and then make assertions. +// +// } +type CatalogTemplateVersionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.CatalogTemplateVersionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.CatalogTemplateVersionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogTemplateVersionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CatalogTemplateVersionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateVersionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.CatalogTemplateVersionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogTemplateVersionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogTemplateVersionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogTemplateVersionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogTemplateVersionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogTemplateVersionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogTemplateVersionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogTemplateVersionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogTemplateVersionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogTemplateVersionControllerMock.AddClusterScopedHandlerFunc: method is nil but CatalogTemplateVersionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCatalogTemplateVersionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogTemplateVersionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.AddClusterScopedHandlerCalls()) +func (mock *CatalogTemplateVersionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogTemplateVersionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogTemplateVersionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogTemplateVersionControllerMock.AddFeatureHandlerFunc: method is nil but CatalogTemplateVersionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateVersionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogTemplateVersionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.AddFeatureHandlerCalls()) +func (mock *CatalogTemplateVersionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogTemplateVersionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogTemplateVersionControllerMock) AddHandler(ctx context.Context, name string, handler v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogTemplateVersionControllerMock.AddHandlerFunc: method is nil but CatalogTemplateVersionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCatalogTemplateVersionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogTemplateVersionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.AddHandlerCalls()) +func (mock *CatalogTemplateVersionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogTemplateVersionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CatalogTemplateVersionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CatalogTemplateVersionControllerMock.EnqueueFunc: method is nil but CatalogTemplateVersionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCatalogTemplateVersionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCatalogTemplateVersionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.EnqueueCalls()) +func (mock *CatalogTemplateVersionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCatalogTemplateVersionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCatalogTemplateVersionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CatalogTemplateVersionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CatalogTemplateVersionControllerMock.EnqueueAfterFunc: method is nil but CatalogTemplateVersionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCatalogTemplateVersionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCatalogTemplateVersionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.EnqueueAfterCalls()) +func (mock *CatalogTemplateVersionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCatalogTemplateVersionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCatalogTemplateVersionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CatalogTemplateVersionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CatalogTemplateVersionControllerMock.GenericFunc: method is nil but CatalogTemplateVersionController.Generic was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateVersionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCatalogTemplateVersionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.GenericCalls()) +func (mock *CatalogTemplateVersionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateVersionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCatalogTemplateVersionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CatalogTemplateVersionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CatalogTemplateVersionControllerMock.InformerFunc: method is nil but CatalogTemplateVersionController.Informer was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateVersionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCatalogTemplateVersionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.InformerCalls()) +func (mock *CatalogTemplateVersionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateVersionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCatalogTemplateVersionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CatalogTemplateVersionControllerMock) Lister() v31.CatalogTemplateVersionLister { + if mock.ListerFunc == nil { + panic("CatalogTemplateVersionControllerMock.ListerFunc: method is nil but CatalogTemplateVersionController.Lister was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateVersionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCatalogTemplateVersionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCatalogTemplateVersionController.ListerCalls()) +func (mock *CatalogTemplateVersionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateVersionControllerMockLister.RLock() + calls = mock.calls.Lister + lockCatalogTemplateVersionControllerMockLister.RUnlock() + return calls +} + +var ( + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddFeatureHandler sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddHandler sync.RWMutex + lockCatalogTemplateVersionInterfaceMockAddLifecycle sync.RWMutex + lockCatalogTemplateVersionInterfaceMockController sync.RWMutex + lockCatalogTemplateVersionInterfaceMockCreate sync.RWMutex + lockCatalogTemplateVersionInterfaceMockDelete sync.RWMutex + lockCatalogTemplateVersionInterfaceMockDeleteCollection sync.RWMutex + lockCatalogTemplateVersionInterfaceMockDeleteNamespaced sync.RWMutex + lockCatalogTemplateVersionInterfaceMockGet sync.RWMutex + lockCatalogTemplateVersionInterfaceMockGetNamespaced sync.RWMutex + lockCatalogTemplateVersionInterfaceMockList sync.RWMutex + lockCatalogTemplateVersionInterfaceMockListNamespaced sync.RWMutex + lockCatalogTemplateVersionInterfaceMockObjectClient sync.RWMutex + lockCatalogTemplateVersionInterfaceMockUpdate sync.RWMutex + lockCatalogTemplateVersionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CatalogTemplateVersionInterfaceMock does implement v31.CatalogTemplateVersionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateVersionInterface = &CatalogTemplateVersionInterfaceMock{} + +// CatalogTemplateVersionInterfaceMock is a mock implementation of v31.CatalogTemplateVersionInterface. +// +// func TestSomethingThatUsesCatalogTemplateVersionInterface(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateVersionInterface +// mockedCatalogTemplateVersionInterface := &CatalogTemplateVersionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateVersionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.CatalogTemplateVersionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.CatalogTemplateVersionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCatalogTemplateVersionInterface in code that requires v31.CatalogTemplateVersionInterface +// // and then make assertions. +// +// } +type CatalogTemplateVersionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateVersionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.CatalogTemplateVersionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.CatalogTemplateVersionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogTemplateVersionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateVersionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CatalogTemplateVersionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateVersionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateVersionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateVersionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CatalogTemplateVersionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CatalogTemplateVersionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.CatalogTemplateVersion + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.CatalogTemplateVersion + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CatalogTemplateVersionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CatalogTemplateVersionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCatalogTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CatalogTemplateVersionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCatalogTemplateVersionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddClusterScopedHandlerCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCatalogTemplateVersionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.CatalogTemplateVersionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CatalogTemplateVersionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCatalogTemplateVersionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddClusterScopedLifecycleCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CatalogTemplateVersionLifecycle + } + lockCatalogTemplateVersionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCatalogTemplateVersionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddFeatureHandlerFunc: method is nil but CatalogTemplateVersionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateVersionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCatalogTemplateVersionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddFeatureHandlerCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCatalogTemplateVersionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.CatalogTemplateVersionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddFeatureLifecycleFunc: method is nil but CatalogTemplateVersionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogTemplateVersionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCatalogTemplateVersionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddFeatureLifecycleCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle + } + lockCatalogTemplateVersionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCatalogTemplateVersionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.CatalogTemplateVersionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddHandlerFunc: method is nil but CatalogTemplateVersionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCatalogTemplateVersionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCatalogTemplateVersionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddHandlerCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.CatalogTemplateVersionHandlerFunc + } + lockCatalogTemplateVersionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCatalogTemplateVersionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CatalogTemplateVersionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.CatalogTemplateVersionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.AddLifecycleFunc: method is nil but CatalogTemplateVersionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCatalogTemplateVersionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCatalogTemplateVersionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.AddLifecycleCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.CatalogTemplateVersionLifecycle + } + lockCatalogTemplateVersionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCatalogTemplateVersionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Controller() v31.CatalogTemplateVersionController { + if mock.ControllerFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.ControllerFunc: method is nil but CatalogTemplateVersionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateVersionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCatalogTemplateVersionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.ControllerCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateVersionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCatalogTemplateVersionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Create(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + if mock.CreateFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.CreateFunc: method is nil but CatalogTemplateVersionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.CatalogTemplateVersion + }{ + In1: in1, + } + lockCatalogTemplateVersionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCatalogTemplateVersionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.CreateCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) CreateCalls() []struct { + In1 *v3.CatalogTemplateVersion +} { + var calls []struct { + In1 *v3.CatalogTemplateVersion + } + lockCatalogTemplateVersionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCatalogTemplateVersionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.DeleteFunc: method is nil but CatalogTemplateVersionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCatalogTemplateVersionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCatalogTemplateVersionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.DeleteCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCatalogTemplateVersionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCatalogTemplateVersionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CatalogTemplateVersionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.DeleteCollectionFunc: method is nil but CatalogTemplateVersionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCatalogTemplateVersionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCatalogTemplateVersionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.DeleteCollectionCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCatalogTemplateVersionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCatalogTemplateVersionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CatalogTemplateVersionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.DeleteNamespacedFunc: method is nil but CatalogTemplateVersionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCatalogTemplateVersionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCatalogTemplateVersionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.DeleteNamespacedCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCatalogTemplateVersionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCatalogTemplateVersionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { + if mock.GetFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.GetFunc: method is nil but CatalogTemplateVersionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCatalogTemplateVersionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCatalogTemplateVersionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.GetCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCatalogTemplateVersionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCatalogTemplateVersionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CatalogTemplateVersionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { + if mock.GetNamespacedFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.GetNamespacedFunc: method is nil but CatalogTemplateVersionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCatalogTemplateVersionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCatalogTemplateVersionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.GetNamespacedCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCatalogTemplateVersionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCatalogTemplateVersionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CatalogTemplateVersionInterfaceMock) List(opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { + if mock.ListFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.ListFunc: method is nil but CatalogTemplateVersionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogTemplateVersionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCatalogTemplateVersionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.ListCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogTemplateVersionInterfaceMockList.RLock() + calls = mock.calls.List + lockCatalogTemplateVersionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CatalogTemplateVersionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { + if mock.ListNamespacedFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.ListNamespacedFunc: method is nil but CatalogTemplateVersionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCatalogTemplateVersionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCatalogTemplateVersionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.ListNamespacedCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCatalogTemplateVersionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCatalogTemplateVersionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CatalogTemplateVersionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.ObjectClientFunc: method is nil but CatalogTemplateVersionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCatalogTemplateVersionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCatalogTemplateVersionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.ObjectClientCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCatalogTemplateVersionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCatalogTemplateVersionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Update(in1 *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + if mock.UpdateFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.UpdateFunc: method is nil but CatalogTemplateVersionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.CatalogTemplateVersion + }{ + In1: in1, + } + lockCatalogTemplateVersionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCatalogTemplateVersionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.UpdateCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) UpdateCalls() []struct { + In1 *v3.CatalogTemplateVersion +} { + var calls []struct { + In1 *v3.CatalogTemplateVersion + } + lockCatalogTemplateVersionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCatalogTemplateVersionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CatalogTemplateVersionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CatalogTemplateVersionInterfaceMock.WatchFunc: method is nil but CatalogTemplateVersionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCatalogTemplateVersionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCatalogTemplateVersionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCatalogTemplateVersionInterface.WatchCalls()) +func (mock *CatalogTemplateVersionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCatalogTemplateVersionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCatalogTemplateVersionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCatalogTemplateVersionsGetterMockCatalogTemplateVersions sync.RWMutex +) + +// Ensure, that CatalogTemplateVersionsGetterMock does implement v31.CatalogTemplateVersionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.CatalogTemplateVersionsGetter = &CatalogTemplateVersionsGetterMock{} + +// CatalogTemplateVersionsGetterMock is a mock implementation of v31.CatalogTemplateVersionsGetter. +// +// func TestSomethingThatUsesCatalogTemplateVersionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.CatalogTemplateVersionsGetter +// mockedCatalogTemplateVersionsGetter := &CatalogTemplateVersionsGetterMock{ +// CatalogTemplateVersionsFunc: func(namespace string) v31.CatalogTemplateVersionInterface { +// panic("mock out the CatalogTemplateVersions method") +// }, +// } +// +// // use mockedCatalogTemplateVersionsGetter in code that requires v31.CatalogTemplateVersionsGetter +// // and then make assertions. +// +// } +type CatalogTemplateVersionsGetterMock struct { + // CatalogTemplateVersionsFunc mocks the CatalogTemplateVersions method. + CatalogTemplateVersionsFunc func(namespace string) v31.CatalogTemplateVersionInterface + + // calls tracks calls to the methods. + calls struct { + // CatalogTemplateVersions holds details about calls to the CatalogTemplateVersions method. + CatalogTemplateVersions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// CatalogTemplateVersions calls CatalogTemplateVersionsFunc. +func (mock *CatalogTemplateVersionsGetterMock) CatalogTemplateVersions(namespace string) v31.CatalogTemplateVersionInterface { + if mock.CatalogTemplateVersionsFunc == nil { + panic("CatalogTemplateVersionsGetterMock.CatalogTemplateVersionsFunc: method is nil but CatalogTemplateVersionsGetter.CatalogTemplateVersions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCatalogTemplateVersionsGetterMockCatalogTemplateVersions.Lock() + mock.calls.CatalogTemplateVersions = append(mock.calls.CatalogTemplateVersions, callInfo) + lockCatalogTemplateVersionsGetterMockCatalogTemplateVersions.Unlock() + return mock.CatalogTemplateVersionsFunc(namespace) +} + +// CatalogTemplateVersionsCalls gets all the calls that were made to CatalogTemplateVersions. +// Check the length with: +// +// len(mockedCatalogTemplateVersionsGetter.CatalogTemplateVersionsCalls()) +func (mock *CatalogTemplateVersionsGetterMock) CatalogTemplateVersionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCatalogTemplateVersionsGetterMockCatalogTemplateVersions.RLock() + calls = mock.calls.CatalogTemplateVersions + lockCatalogTemplateVersionsGetterMockCatalogTemplateVersions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cloud_credential_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cloud_credential_mock.go new file mode 100644 index 0000000..7e20c78 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cloud_credential_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCloudCredentialListerMockGet sync.RWMutex + lockCloudCredentialListerMockList sync.RWMutex +) + +// Ensure, that CloudCredentialListerMock does implement v31.CloudCredentialLister. +// If this is not the case, regenerate this file with moq. +var _ v31.CloudCredentialLister = &CloudCredentialListerMock{} + +// CloudCredentialListerMock is a mock implementation of v31.CloudCredentialLister. +// +// func TestSomethingThatUsesCloudCredentialLister(t *testing.T) { +// +// // make and configure a mocked v31.CloudCredentialLister +// mockedCloudCredentialLister := &CloudCredentialListerMock{ +// GetFunc: func(namespace string, name string) (*v3.CloudCredential, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.CloudCredential, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCloudCredentialLister in code that requires v31.CloudCredentialLister +// // and then make assertions. +// +// } +type CloudCredentialListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.CloudCredential, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.CloudCredential, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CloudCredentialListerMock) Get(namespace string, name string) (*v3.CloudCredential, error) { + if mock.GetFunc == nil { + panic("CloudCredentialListerMock.GetFunc: method is nil but CloudCredentialLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCloudCredentialListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCloudCredentialListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCloudCredentialLister.GetCalls()) +func (mock *CloudCredentialListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCloudCredentialListerMockGet.RLock() + calls = mock.calls.Get + lockCloudCredentialListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CloudCredentialListerMock) List(namespace string, selector labels.Selector) ([]*v3.CloudCredential, error) { + if mock.ListFunc == nil { + panic("CloudCredentialListerMock.ListFunc: method is nil but CloudCredentialLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCloudCredentialListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCloudCredentialListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCloudCredentialLister.ListCalls()) +func (mock *CloudCredentialListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCloudCredentialListerMockList.RLock() + calls = mock.calls.List + lockCloudCredentialListerMockList.RUnlock() + return calls +} + +var ( + lockCloudCredentialControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCloudCredentialControllerMockAddClusterScopedHandler sync.RWMutex + lockCloudCredentialControllerMockAddFeatureHandler sync.RWMutex + lockCloudCredentialControllerMockAddHandler sync.RWMutex + lockCloudCredentialControllerMockEnqueue sync.RWMutex + lockCloudCredentialControllerMockEnqueueAfter sync.RWMutex + lockCloudCredentialControllerMockGeneric sync.RWMutex + lockCloudCredentialControllerMockInformer sync.RWMutex + lockCloudCredentialControllerMockLister sync.RWMutex +) + +// Ensure, that CloudCredentialControllerMock does implement v31.CloudCredentialController. +// If this is not the case, regenerate this file with moq. +var _ v31.CloudCredentialController = &CloudCredentialControllerMock{} + +// CloudCredentialControllerMock is a mock implementation of v31.CloudCredentialController. +// +// func TestSomethingThatUsesCloudCredentialController(t *testing.T) { +// +// // make and configure a mocked v31.CloudCredentialController +// mockedCloudCredentialController := &CloudCredentialControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.CloudCredentialLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCloudCredentialController in code that requires v31.CloudCredentialController +// // and then make assertions. +// +// } +type CloudCredentialControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.CloudCredentialHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.CloudCredentialLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CloudCredentialHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CloudCredentialHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CloudCredentialHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.CloudCredentialHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CloudCredentialControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CloudCredentialControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CloudCredentialController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCloudCredentialControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCloudCredentialControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCloudCredentialController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CloudCredentialControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc + } + lockCloudCredentialControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCloudCredentialControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CloudCredentialControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.CloudCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CloudCredentialControllerMock.AddClusterScopedHandlerFunc: method is nil but CloudCredentialController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCloudCredentialControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCloudCredentialControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCloudCredentialController.AddClusterScopedHandlerCalls()) +func (mock *CloudCredentialControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CloudCredentialHandlerFunc + } + lockCloudCredentialControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCloudCredentialControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CloudCredentialControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CloudCredentialControllerMock.AddFeatureHandlerFunc: method is nil but CloudCredentialController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCloudCredentialControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCloudCredentialControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCloudCredentialController.AddFeatureHandlerCalls()) +func (mock *CloudCredentialControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc + } + lockCloudCredentialControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCloudCredentialControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CloudCredentialControllerMock) AddHandler(ctx context.Context, name string, handler v31.CloudCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CloudCredentialControllerMock.AddHandlerFunc: method is nil but CloudCredentialController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCloudCredentialControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCloudCredentialControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCloudCredentialController.AddHandlerCalls()) +func (mock *CloudCredentialControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.CloudCredentialHandlerFunc + } + lockCloudCredentialControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCloudCredentialControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CloudCredentialControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CloudCredentialControllerMock.EnqueueFunc: method is nil but CloudCredentialController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCloudCredentialControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCloudCredentialControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCloudCredentialController.EnqueueCalls()) +func (mock *CloudCredentialControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCloudCredentialControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCloudCredentialControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CloudCredentialControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CloudCredentialControllerMock.EnqueueAfterFunc: method is nil but CloudCredentialController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCloudCredentialControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCloudCredentialControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCloudCredentialController.EnqueueAfterCalls()) +func (mock *CloudCredentialControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCloudCredentialControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCloudCredentialControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CloudCredentialControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CloudCredentialControllerMock.GenericFunc: method is nil but CloudCredentialController.Generic was just called") + } + callInfo := struct { + }{} + lockCloudCredentialControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCloudCredentialControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCloudCredentialController.GenericCalls()) +func (mock *CloudCredentialControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCloudCredentialControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCloudCredentialControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CloudCredentialControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CloudCredentialControllerMock.InformerFunc: method is nil but CloudCredentialController.Informer was just called") + } + callInfo := struct { + }{} + lockCloudCredentialControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCloudCredentialControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCloudCredentialController.InformerCalls()) +func (mock *CloudCredentialControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCloudCredentialControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCloudCredentialControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CloudCredentialControllerMock) Lister() v31.CloudCredentialLister { + if mock.ListerFunc == nil { + panic("CloudCredentialControllerMock.ListerFunc: method is nil but CloudCredentialController.Lister was just called") + } + callInfo := struct { + }{} + lockCloudCredentialControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCloudCredentialControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCloudCredentialController.ListerCalls()) +func (mock *CloudCredentialControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCloudCredentialControllerMockLister.RLock() + calls = mock.calls.Lister + lockCloudCredentialControllerMockLister.RUnlock() + return calls +} + +var ( + lockCloudCredentialInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCloudCredentialInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCloudCredentialInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCloudCredentialInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCloudCredentialInterfaceMockAddFeatureHandler sync.RWMutex + lockCloudCredentialInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCloudCredentialInterfaceMockAddHandler sync.RWMutex + lockCloudCredentialInterfaceMockAddLifecycle sync.RWMutex + lockCloudCredentialInterfaceMockController sync.RWMutex + lockCloudCredentialInterfaceMockCreate sync.RWMutex + lockCloudCredentialInterfaceMockDelete sync.RWMutex + lockCloudCredentialInterfaceMockDeleteCollection sync.RWMutex + lockCloudCredentialInterfaceMockDeleteNamespaced sync.RWMutex + lockCloudCredentialInterfaceMockGet sync.RWMutex + lockCloudCredentialInterfaceMockGetNamespaced sync.RWMutex + lockCloudCredentialInterfaceMockList sync.RWMutex + lockCloudCredentialInterfaceMockListNamespaced sync.RWMutex + lockCloudCredentialInterfaceMockObjectClient sync.RWMutex + lockCloudCredentialInterfaceMockUpdate sync.RWMutex + lockCloudCredentialInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CloudCredentialInterfaceMock does implement v31.CloudCredentialInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.CloudCredentialInterface = &CloudCredentialInterfaceMock{} + +// CloudCredentialInterfaceMock is a mock implementation of v31.CloudCredentialInterface. +// +// func TestSomethingThatUsesCloudCredentialInterface(t *testing.T) { +// +// // make and configure a mocked v31.CloudCredentialInterface +// mockedCloudCredentialInterface := &CloudCredentialInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CloudCredentialLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.CloudCredentialLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.CloudCredentialController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.CloudCredential) (*v3.CloudCredential, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.CloudCredentialList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.CloudCredentialList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.CloudCredential) (*v3.CloudCredential, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCloudCredentialInterface in code that requires v31.CloudCredentialInterface +// // and then make assertions. +// +// } +type CloudCredentialInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CloudCredentialLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.CloudCredentialHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.CloudCredentialLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.CloudCredentialController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.CloudCredential) (*v3.CloudCredential, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.CloudCredential, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.CloudCredential, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.CloudCredentialList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.CloudCredentialList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.CloudCredential) (*v3.CloudCredential, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CloudCredentialHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CloudCredentialLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CloudCredentialHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CloudCredentialLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CloudCredentialHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CloudCredentialLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CloudCredentialHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CloudCredentialLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.CloudCredential + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.CloudCredential + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CloudCredentialInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CloudCredentialInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CloudCredentialInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCloudCredentialInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCloudCredentialInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CloudCredentialInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc + } + lockCloudCredentialInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCloudCredentialInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CloudCredentialInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CloudCredentialInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CloudCredentialInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCloudCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCloudCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CloudCredentialInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle + } + lockCloudCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCloudCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CloudCredentialInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.CloudCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CloudCredentialInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CloudCredentialInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCloudCredentialInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCloudCredentialInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddClusterScopedHandlerCalls()) +func (mock *CloudCredentialInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CloudCredentialHandlerFunc + } + lockCloudCredentialInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCloudCredentialInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CloudCredentialInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.CloudCredentialLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CloudCredentialInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CloudCredentialInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCloudCredentialInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCloudCredentialInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddClusterScopedLifecycleCalls()) +func (mock *CloudCredentialInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CloudCredentialLifecycle + } + lockCloudCredentialInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCloudCredentialInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CloudCredentialInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CloudCredentialInterfaceMock.AddFeatureHandlerFunc: method is nil but CloudCredentialInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCloudCredentialInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCloudCredentialInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddFeatureHandlerCalls()) +func (mock *CloudCredentialInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CloudCredentialHandlerFunc + } + lockCloudCredentialInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCloudCredentialInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CloudCredentialInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.CloudCredentialLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CloudCredentialInterfaceMock.AddFeatureLifecycleFunc: method is nil but CloudCredentialInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CloudCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCloudCredentialInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCloudCredentialInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddFeatureLifecycleCalls()) +func (mock *CloudCredentialInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CloudCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CloudCredentialLifecycle + } + lockCloudCredentialInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCloudCredentialInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CloudCredentialInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.CloudCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CloudCredentialInterfaceMock.AddHandlerFunc: method is nil but CloudCredentialInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.CloudCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCloudCredentialInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCloudCredentialInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddHandlerCalls()) +func (mock *CloudCredentialInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.CloudCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.CloudCredentialHandlerFunc + } + lockCloudCredentialInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCloudCredentialInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CloudCredentialInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.CloudCredentialLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CloudCredentialInterfaceMock.AddLifecycleFunc: method is nil but CloudCredentialInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.CloudCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCloudCredentialInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCloudCredentialInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCloudCredentialInterface.AddLifecycleCalls()) +func (mock *CloudCredentialInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.CloudCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.CloudCredentialLifecycle + } + lockCloudCredentialInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCloudCredentialInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CloudCredentialInterfaceMock) Controller() v31.CloudCredentialController { + if mock.ControllerFunc == nil { + panic("CloudCredentialInterfaceMock.ControllerFunc: method is nil but CloudCredentialInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCloudCredentialInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCloudCredentialInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCloudCredentialInterface.ControllerCalls()) +func (mock *CloudCredentialInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCloudCredentialInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCloudCredentialInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CloudCredentialInterfaceMock) Create(in1 *v3.CloudCredential) (*v3.CloudCredential, error) { + if mock.CreateFunc == nil { + panic("CloudCredentialInterfaceMock.CreateFunc: method is nil but CloudCredentialInterface.Create was just called") + } + callInfo := struct { + In1 *v3.CloudCredential + }{ + In1: in1, + } + lockCloudCredentialInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCloudCredentialInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCloudCredentialInterface.CreateCalls()) +func (mock *CloudCredentialInterfaceMock) CreateCalls() []struct { + In1 *v3.CloudCredential +} { + var calls []struct { + In1 *v3.CloudCredential + } + lockCloudCredentialInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCloudCredentialInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CloudCredentialInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CloudCredentialInterfaceMock.DeleteFunc: method is nil but CloudCredentialInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCloudCredentialInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCloudCredentialInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCloudCredentialInterface.DeleteCalls()) +func (mock *CloudCredentialInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCloudCredentialInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCloudCredentialInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CloudCredentialInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CloudCredentialInterfaceMock.DeleteCollectionFunc: method is nil but CloudCredentialInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCloudCredentialInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCloudCredentialInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCloudCredentialInterface.DeleteCollectionCalls()) +func (mock *CloudCredentialInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCloudCredentialInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCloudCredentialInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CloudCredentialInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CloudCredentialInterfaceMock.DeleteNamespacedFunc: method is nil but CloudCredentialInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCloudCredentialInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCloudCredentialInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCloudCredentialInterface.DeleteNamespacedCalls()) +func (mock *CloudCredentialInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCloudCredentialInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCloudCredentialInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CloudCredentialInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { + if mock.GetFunc == nil { + panic("CloudCredentialInterfaceMock.GetFunc: method is nil but CloudCredentialInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCloudCredentialInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCloudCredentialInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCloudCredentialInterface.GetCalls()) +func (mock *CloudCredentialInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCloudCredentialInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCloudCredentialInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CloudCredentialInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { + if mock.GetNamespacedFunc == nil { + panic("CloudCredentialInterfaceMock.GetNamespacedFunc: method is nil but CloudCredentialInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCloudCredentialInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCloudCredentialInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCloudCredentialInterface.GetNamespacedCalls()) +func (mock *CloudCredentialInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCloudCredentialInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCloudCredentialInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CloudCredentialInterfaceMock) List(opts metav1.ListOptions) (*v3.CloudCredentialList, error) { + if mock.ListFunc == nil { + panic("CloudCredentialInterfaceMock.ListFunc: method is nil but CloudCredentialInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCloudCredentialInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCloudCredentialInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCloudCredentialInterface.ListCalls()) +func (mock *CloudCredentialInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCloudCredentialInterfaceMockList.RLock() + calls = mock.calls.List + lockCloudCredentialInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CloudCredentialInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CloudCredentialList, error) { + if mock.ListNamespacedFunc == nil { + panic("CloudCredentialInterfaceMock.ListNamespacedFunc: method is nil but CloudCredentialInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCloudCredentialInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCloudCredentialInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCloudCredentialInterface.ListNamespacedCalls()) +func (mock *CloudCredentialInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCloudCredentialInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCloudCredentialInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CloudCredentialInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CloudCredentialInterfaceMock.ObjectClientFunc: method is nil but CloudCredentialInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCloudCredentialInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCloudCredentialInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCloudCredentialInterface.ObjectClientCalls()) +func (mock *CloudCredentialInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCloudCredentialInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCloudCredentialInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CloudCredentialInterfaceMock) Update(in1 *v3.CloudCredential) (*v3.CloudCredential, error) { + if mock.UpdateFunc == nil { + panic("CloudCredentialInterfaceMock.UpdateFunc: method is nil but CloudCredentialInterface.Update was just called") + } + callInfo := struct { + In1 *v3.CloudCredential + }{ + In1: in1, + } + lockCloudCredentialInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCloudCredentialInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCloudCredentialInterface.UpdateCalls()) +func (mock *CloudCredentialInterfaceMock) UpdateCalls() []struct { + In1 *v3.CloudCredential +} { + var calls []struct { + In1 *v3.CloudCredential + } + lockCloudCredentialInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCloudCredentialInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CloudCredentialInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CloudCredentialInterfaceMock.WatchFunc: method is nil but CloudCredentialInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCloudCredentialInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCloudCredentialInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCloudCredentialInterface.WatchCalls()) +func (mock *CloudCredentialInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCloudCredentialInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCloudCredentialInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCloudCredentialsGetterMockCloudCredentials sync.RWMutex +) + +// Ensure, that CloudCredentialsGetterMock does implement v31.CloudCredentialsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.CloudCredentialsGetter = &CloudCredentialsGetterMock{} + +// CloudCredentialsGetterMock is a mock implementation of v31.CloudCredentialsGetter. +// +// func TestSomethingThatUsesCloudCredentialsGetter(t *testing.T) { +// +// // make and configure a mocked v31.CloudCredentialsGetter +// mockedCloudCredentialsGetter := &CloudCredentialsGetterMock{ +// CloudCredentialsFunc: func(namespace string) v31.CloudCredentialInterface { +// panic("mock out the CloudCredentials method") +// }, +// } +// +// // use mockedCloudCredentialsGetter in code that requires v31.CloudCredentialsGetter +// // and then make assertions. +// +// } +type CloudCredentialsGetterMock struct { + // CloudCredentialsFunc mocks the CloudCredentials method. + CloudCredentialsFunc func(namespace string) v31.CloudCredentialInterface + + // calls tracks calls to the methods. + calls struct { + // CloudCredentials holds details about calls to the CloudCredentials method. + CloudCredentials []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// CloudCredentials calls CloudCredentialsFunc. +func (mock *CloudCredentialsGetterMock) CloudCredentials(namespace string) v31.CloudCredentialInterface { + if mock.CloudCredentialsFunc == nil { + panic("CloudCredentialsGetterMock.CloudCredentialsFunc: method is nil but CloudCredentialsGetter.CloudCredentials was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCloudCredentialsGetterMockCloudCredentials.Lock() + mock.calls.CloudCredentials = append(mock.calls.CloudCredentials, callInfo) + lockCloudCredentialsGetterMockCloudCredentials.Unlock() + return mock.CloudCredentialsFunc(namespace) +} + +// CloudCredentialsCalls gets all the calls that were made to CloudCredentials. +// Check the length with: +// +// len(mockedCloudCredentialsGetter.CloudCredentialsCalls()) +func (mock *CloudCredentialsGetterMock) CloudCredentialsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCloudCredentialsGetterMockCloudCredentials.RLock() + calls = mock.calls.CloudCredentials + lockCloudCredentialsGetterMockCloudCredentials.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_catalog_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_catalog_mock.go new file mode 100644 index 0000000..0443ae0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_catalog_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterCatalogListerMockGet sync.RWMutex + lockClusterCatalogListerMockList sync.RWMutex +) + +// Ensure, that ClusterCatalogListerMock does implement v31.ClusterCatalogLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterCatalogLister = &ClusterCatalogListerMock{} + +// ClusterCatalogListerMock is a mock implementation of v31.ClusterCatalogLister. +// +// func TestSomethingThatUsesClusterCatalogLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterCatalogLister +// mockedClusterCatalogLister := &ClusterCatalogListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterCatalog, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterCatalog, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterCatalogLister in code that requires v31.ClusterCatalogLister +// // and then make assertions. +// +// } +type ClusterCatalogListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterCatalog, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterCatalog, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterCatalogListerMock) Get(namespace string, name string) (*v3.ClusterCatalog, error) { + if mock.GetFunc == nil { + panic("ClusterCatalogListerMock.GetFunc: method is nil but ClusterCatalogLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterCatalogListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterCatalogListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterCatalogLister.GetCalls()) +func (mock *ClusterCatalogListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterCatalogListerMockGet.RLock() + calls = mock.calls.Get + lockClusterCatalogListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterCatalogListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterCatalog, error) { + if mock.ListFunc == nil { + panic("ClusterCatalogListerMock.ListFunc: method is nil but ClusterCatalogLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterCatalogListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterCatalogListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterCatalogLister.ListCalls()) +func (mock *ClusterCatalogListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterCatalogListerMockList.RLock() + calls = mock.calls.List + lockClusterCatalogListerMockList.RUnlock() + return calls +} + +var ( + lockClusterCatalogControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterCatalogControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterCatalogControllerMockAddFeatureHandler sync.RWMutex + lockClusterCatalogControllerMockAddHandler sync.RWMutex + lockClusterCatalogControllerMockEnqueue sync.RWMutex + lockClusterCatalogControllerMockEnqueueAfter sync.RWMutex + lockClusterCatalogControllerMockGeneric sync.RWMutex + lockClusterCatalogControllerMockInformer sync.RWMutex + lockClusterCatalogControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterCatalogControllerMock does implement v31.ClusterCatalogController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterCatalogController = &ClusterCatalogControllerMock{} + +// ClusterCatalogControllerMock is a mock implementation of v31.ClusterCatalogController. +// +// func TestSomethingThatUsesClusterCatalogController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterCatalogController +// mockedClusterCatalogController := &ClusterCatalogControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterCatalogLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterCatalogController in code that requires v31.ClusterCatalogController +// // and then make assertions. +// +// } +type ClusterCatalogControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterCatalogHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterCatalogLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterCatalogHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterCatalogHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterCatalogHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterCatalogHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterCatalogControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterCatalogControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterCatalogController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterCatalogControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterCatalogControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterCatalogController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterCatalogControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterCatalogControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterCatalogControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterCatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterCatalogControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterCatalogController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterCatalogControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterCatalogControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterCatalogController.AddClusterScopedHandlerCalls()) +func (mock *ClusterCatalogControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterCatalogControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterCatalogControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterCatalogControllerMock.AddFeatureHandlerFunc: method is nil but ClusterCatalogController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterCatalogControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterCatalogControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterCatalogController.AddFeatureHandlerCalls()) +func (mock *ClusterCatalogControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterCatalogControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterCatalogControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterCatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterCatalogControllerMock.AddHandlerFunc: method is nil but ClusterCatalogController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterCatalogControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterCatalogControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterCatalogController.AddHandlerCalls()) +func (mock *ClusterCatalogControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterCatalogControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterCatalogControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterCatalogControllerMock.EnqueueFunc: method is nil but ClusterCatalogController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterCatalogControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterCatalogControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterCatalogController.EnqueueCalls()) +func (mock *ClusterCatalogControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterCatalogControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterCatalogControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterCatalogControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterCatalogControllerMock.EnqueueAfterFunc: method is nil but ClusterCatalogController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterCatalogControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterCatalogControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterCatalogController.EnqueueAfterCalls()) +func (mock *ClusterCatalogControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterCatalogControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterCatalogControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterCatalogControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterCatalogControllerMock.GenericFunc: method is nil but ClusterCatalogController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterCatalogControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterCatalogControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterCatalogController.GenericCalls()) +func (mock *ClusterCatalogControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterCatalogControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterCatalogControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterCatalogControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterCatalogControllerMock.InformerFunc: method is nil but ClusterCatalogController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterCatalogControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterCatalogControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterCatalogController.InformerCalls()) +func (mock *ClusterCatalogControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterCatalogControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterCatalogControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterCatalogControllerMock) Lister() v31.ClusterCatalogLister { + if mock.ListerFunc == nil { + panic("ClusterCatalogControllerMock.ListerFunc: method is nil but ClusterCatalogController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterCatalogControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterCatalogControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterCatalogController.ListerCalls()) +func (mock *ClusterCatalogControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterCatalogControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterCatalogControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterCatalogInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterCatalogInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterCatalogInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterCatalogInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterCatalogInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterCatalogInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterCatalogInterfaceMockAddHandler sync.RWMutex + lockClusterCatalogInterfaceMockAddLifecycle sync.RWMutex + lockClusterCatalogInterfaceMockController sync.RWMutex + lockClusterCatalogInterfaceMockCreate sync.RWMutex + lockClusterCatalogInterfaceMockDelete sync.RWMutex + lockClusterCatalogInterfaceMockDeleteCollection sync.RWMutex + lockClusterCatalogInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterCatalogInterfaceMockGet sync.RWMutex + lockClusterCatalogInterfaceMockGetNamespaced sync.RWMutex + lockClusterCatalogInterfaceMockList sync.RWMutex + lockClusterCatalogInterfaceMockListNamespaced sync.RWMutex + lockClusterCatalogInterfaceMockObjectClient sync.RWMutex + lockClusterCatalogInterfaceMockUpdate sync.RWMutex + lockClusterCatalogInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterCatalogInterfaceMock does implement v31.ClusterCatalogInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterCatalogInterface = &ClusterCatalogInterfaceMock{} + +// ClusterCatalogInterfaceMock is a mock implementation of v31.ClusterCatalogInterface. +// +// func TestSomethingThatUsesClusterCatalogInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterCatalogInterface +// mockedClusterCatalogInterface := &ClusterCatalogInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterCatalogLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterCatalogLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterCatalogController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterCatalogInterface in code that requires v31.ClusterCatalogInterface +// // and then make assertions. +// +// } +type ClusterCatalogInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterCatalogLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterCatalogLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterCatalogController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterCatalogList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterCatalogList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterCatalogHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterCatalogLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterCatalogHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterCatalogLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterCatalogHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterCatalogLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterCatalogHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterCatalogLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterCatalog + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterCatalog + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterCatalogInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterCatalogInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterCatalogInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterCatalogInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterCatalogInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterCatalogInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterCatalogInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle + } + lockClusterCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterCatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterCatalogInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterCatalogInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterCatalogInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterCatalogInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterCatalogInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterCatalogLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterCatalogInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterCatalogInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterCatalogInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterCatalogInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterCatalogInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterCatalogLifecycle + } + lockClusterCatalogInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterCatalogInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterCatalogInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterCatalogInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterCatalogInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterCatalogInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterCatalogInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddFeatureHandlerCalls()) +func (mock *ClusterCatalogInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterCatalogInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterCatalogInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterCatalogLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterCatalogInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterCatalogInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterCatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterCatalogInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterCatalogInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterCatalogInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterCatalogLifecycle + } + lockClusterCatalogInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterCatalogInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterCatalogInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterCatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterCatalogInterfaceMock.AddHandlerFunc: method is nil but ClusterCatalogInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterCatalogInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterCatalogInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddHandlerCalls()) +func (mock *ClusterCatalogInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterCatalogHandlerFunc + } + lockClusterCatalogInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterCatalogInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterCatalogInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterCatalogLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterCatalogInterfaceMock.AddLifecycleFunc: method is nil but ClusterCatalogInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterCatalogLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterCatalogInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterCatalogInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterCatalogInterface.AddLifecycleCalls()) +func (mock *ClusterCatalogInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterCatalogLifecycle + } + lockClusterCatalogInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterCatalogInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterCatalogInterfaceMock) Controller() v31.ClusterCatalogController { + if mock.ControllerFunc == nil { + panic("ClusterCatalogInterfaceMock.ControllerFunc: method is nil but ClusterCatalogInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterCatalogInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterCatalogInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterCatalogInterface.ControllerCalls()) +func (mock *ClusterCatalogInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterCatalogInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterCatalogInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterCatalogInterfaceMock) Create(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { + if mock.CreateFunc == nil { + panic("ClusterCatalogInterfaceMock.CreateFunc: method is nil but ClusterCatalogInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterCatalog + }{ + In1: in1, + } + lockClusterCatalogInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterCatalogInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterCatalogInterface.CreateCalls()) +func (mock *ClusterCatalogInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterCatalog +} { + var calls []struct { + In1 *v3.ClusterCatalog + } + lockClusterCatalogInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterCatalogInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterCatalogInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterCatalogInterfaceMock.DeleteFunc: method is nil but ClusterCatalogInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterCatalogInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterCatalogInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterCatalogInterface.DeleteCalls()) +func (mock *ClusterCatalogInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterCatalogInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterCatalogInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterCatalogInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterCatalogInterfaceMock.DeleteCollectionFunc: method is nil but ClusterCatalogInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterCatalogInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterCatalogInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterCatalogInterface.DeleteCollectionCalls()) +func (mock *ClusterCatalogInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterCatalogInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterCatalogInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterCatalogInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterCatalogInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterCatalogInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterCatalogInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterCatalogInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterCatalogInterface.DeleteNamespacedCalls()) +func (mock *ClusterCatalogInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterCatalogInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterCatalogInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterCatalogInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { + if mock.GetFunc == nil { + panic("ClusterCatalogInterfaceMock.GetFunc: method is nil but ClusterCatalogInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterCatalogInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterCatalogInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterCatalogInterface.GetCalls()) +func (mock *ClusterCatalogInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterCatalogInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterCatalogInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterCatalogInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterCatalogInterfaceMock.GetNamespacedFunc: method is nil but ClusterCatalogInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterCatalogInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterCatalogInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterCatalogInterface.GetNamespacedCalls()) +func (mock *ClusterCatalogInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterCatalogInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterCatalogInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterCatalogInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { + if mock.ListFunc == nil { + panic("ClusterCatalogInterfaceMock.ListFunc: method is nil but ClusterCatalogInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterCatalogInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterCatalogInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterCatalogInterface.ListCalls()) +func (mock *ClusterCatalogInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterCatalogInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterCatalogInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterCatalogInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterCatalogInterfaceMock.ListNamespacedFunc: method is nil but ClusterCatalogInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterCatalogInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterCatalogInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterCatalogInterface.ListNamespacedCalls()) +func (mock *ClusterCatalogInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterCatalogInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterCatalogInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterCatalogInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterCatalogInterfaceMock.ObjectClientFunc: method is nil but ClusterCatalogInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterCatalogInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterCatalogInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterCatalogInterface.ObjectClientCalls()) +func (mock *ClusterCatalogInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterCatalogInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterCatalogInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterCatalogInterfaceMock) Update(in1 *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { + if mock.UpdateFunc == nil { + panic("ClusterCatalogInterfaceMock.UpdateFunc: method is nil but ClusterCatalogInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterCatalog + }{ + In1: in1, + } + lockClusterCatalogInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterCatalogInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterCatalogInterface.UpdateCalls()) +func (mock *ClusterCatalogInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterCatalog +} { + var calls []struct { + In1 *v3.ClusterCatalog + } + lockClusterCatalogInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterCatalogInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterCatalogInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterCatalogInterfaceMock.WatchFunc: method is nil but ClusterCatalogInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterCatalogInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterCatalogInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterCatalogInterface.WatchCalls()) +func (mock *ClusterCatalogInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterCatalogInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterCatalogInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterCatalogsGetterMockClusterCatalogs sync.RWMutex +) + +// Ensure, that ClusterCatalogsGetterMock does implement v31.ClusterCatalogsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterCatalogsGetter = &ClusterCatalogsGetterMock{} + +// ClusterCatalogsGetterMock is a mock implementation of v31.ClusterCatalogsGetter. +// +// func TestSomethingThatUsesClusterCatalogsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterCatalogsGetter +// mockedClusterCatalogsGetter := &ClusterCatalogsGetterMock{ +// ClusterCatalogsFunc: func(namespace string) v31.ClusterCatalogInterface { +// panic("mock out the ClusterCatalogs method") +// }, +// } +// +// // use mockedClusterCatalogsGetter in code that requires v31.ClusterCatalogsGetter +// // and then make assertions. +// +// } +type ClusterCatalogsGetterMock struct { + // ClusterCatalogsFunc mocks the ClusterCatalogs method. + ClusterCatalogsFunc func(namespace string) v31.ClusterCatalogInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterCatalogs holds details about calls to the ClusterCatalogs method. + ClusterCatalogs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterCatalogs calls ClusterCatalogsFunc. +func (mock *ClusterCatalogsGetterMock) ClusterCatalogs(namespace string) v31.ClusterCatalogInterface { + if mock.ClusterCatalogsFunc == nil { + panic("ClusterCatalogsGetterMock.ClusterCatalogsFunc: method is nil but ClusterCatalogsGetter.ClusterCatalogs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterCatalogsGetterMockClusterCatalogs.Lock() + mock.calls.ClusterCatalogs = append(mock.calls.ClusterCatalogs, callInfo) + lockClusterCatalogsGetterMockClusterCatalogs.Unlock() + return mock.ClusterCatalogsFunc(namespace) +} + +// ClusterCatalogsCalls gets all the calls that were made to ClusterCatalogs. +// Check the length with: +// +// len(mockedClusterCatalogsGetter.ClusterCatalogsCalls()) +func (mock *ClusterCatalogsGetterMock) ClusterCatalogsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterCatalogsGetterMockClusterCatalogs.RLock() + calls = mock.calls.ClusterCatalogs + lockClusterCatalogsGetterMockClusterCatalogs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_mock.go new file mode 100644 index 0000000..65efa41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterListerMockGet sync.RWMutex + lockClusterListerMockList sync.RWMutex +) + +// Ensure, that ClusterListerMock does implement v31.ClusterLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterLister = &ClusterListerMock{} + +// ClusterListerMock is a mock implementation of v31.ClusterLister. +// +// func TestSomethingThatUsesClusterLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterLister +// mockedClusterLister := &ClusterListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Cluster, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterLister in code that requires v31.ClusterLister +// // and then make assertions. +// +// } +type ClusterListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Cluster, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Cluster, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterListerMock) Get(namespace string, name string) (*v3.Cluster, error) { + if mock.GetFunc == nil { + panic("ClusterListerMock.GetFunc: method is nil but ClusterLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterLister.GetCalls()) +func (mock *ClusterListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterListerMockGet.RLock() + calls = mock.calls.Get + lockClusterListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterListerMock) List(namespace string, selector labels.Selector) ([]*v3.Cluster, error) { + if mock.ListFunc == nil { + panic("ClusterListerMock.ListFunc: method is nil but ClusterLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterLister.ListCalls()) +func (mock *ClusterListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterListerMockList.RLock() + calls = mock.calls.List + lockClusterListerMockList.RUnlock() + return calls +} + +var ( + lockClusterControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterControllerMockAddFeatureHandler sync.RWMutex + lockClusterControllerMockAddHandler sync.RWMutex + lockClusterControllerMockEnqueue sync.RWMutex + lockClusterControllerMockEnqueueAfter sync.RWMutex + lockClusterControllerMockGeneric sync.RWMutex + lockClusterControllerMockInformer sync.RWMutex + lockClusterControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterControllerMock does implement v31.ClusterController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterController = &ClusterControllerMock{} + +// ClusterControllerMock is a mock implementation of v31.ClusterController. +// +// func TestSomethingThatUsesClusterController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterController +// mockedClusterController := &ClusterControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterController in code that requires v31.ClusterController +// // and then make assertions. +// +// } +type ClusterControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterHandlerFunc + } + lockClusterControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterController.AddClusterScopedHandlerCalls()) +func (mock *ClusterControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterHandlerFunc + } + lockClusterControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterControllerMock.AddFeatureHandlerFunc: method is nil but ClusterController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterController.AddFeatureHandlerCalls()) +func (mock *ClusterControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc + } + lockClusterControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterControllerMock.AddHandlerFunc: method is nil but ClusterController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterController.AddHandlerCalls()) +func (mock *ClusterControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterHandlerFunc + } + lockClusterControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterControllerMock.EnqueueFunc: method is nil but ClusterController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterController.EnqueueCalls()) +func (mock *ClusterControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterControllerMock.EnqueueAfterFunc: method is nil but ClusterController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterController.EnqueueAfterCalls()) +func (mock *ClusterControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterControllerMock.GenericFunc: method is nil but ClusterController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterController.GenericCalls()) +func (mock *ClusterControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterControllerMock.InformerFunc: method is nil but ClusterController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterController.InformerCalls()) +func (mock *ClusterControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterControllerMock) Lister() v31.ClusterLister { + if mock.ListerFunc == nil { + panic("ClusterControllerMock.ListerFunc: method is nil but ClusterController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterController.ListerCalls()) +func (mock *ClusterControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterInterfaceMockAddHandler sync.RWMutex + lockClusterInterfaceMockAddLifecycle sync.RWMutex + lockClusterInterfaceMockController sync.RWMutex + lockClusterInterfaceMockCreate sync.RWMutex + lockClusterInterfaceMockDelete sync.RWMutex + lockClusterInterfaceMockDeleteCollection sync.RWMutex + lockClusterInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterInterfaceMockGet sync.RWMutex + lockClusterInterfaceMockGetNamespaced sync.RWMutex + lockClusterInterfaceMockList sync.RWMutex + lockClusterInterfaceMockListNamespaced sync.RWMutex + lockClusterInterfaceMockObjectClient sync.RWMutex + lockClusterInterfaceMockUpdate sync.RWMutex + lockClusterInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterInterfaceMock does implement v31.ClusterInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterInterface = &ClusterInterfaceMock{} + +// ClusterInterfaceMock is a mock implementation of v31.ClusterInterface. +// +// func TestSomethingThatUsesClusterInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterInterface +// mockedClusterInterface := &ClusterInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Cluster) (*v3.Cluster, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Cluster, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Cluster, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Cluster) (*v3.Cluster, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterInterface in code that requires v31.ClusterInterface +// // and then make assertions. +// +// } +type ClusterInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Cluster) (*v3.Cluster, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Cluster, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Cluster, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Cluster) (*v3.Cluster, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Cluster + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Cluster + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterHandlerFunc + } + lockClusterInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle + } + lockClusterInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterHandlerFunc + } + lockClusterInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterLifecycle + } + lockClusterInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterInterface.AddFeatureHandlerCalls()) +func (mock *ClusterInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterHandlerFunc + } + lockClusterInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterLifecycle + } + lockClusterInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterInterfaceMock.AddHandlerFunc: method is nil but ClusterInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterInterface.AddHandlerCalls()) +func (mock *ClusterInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterHandlerFunc + } + lockClusterInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterInterfaceMock.AddLifecycleFunc: method is nil but ClusterInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterInterface.AddLifecycleCalls()) +func (mock *ClusterInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterLifecycle + } + lockClusterInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterInterfaceMock) Controller() v31.ClusterController { + if mock.ControllerFunc == nil { + panic("ClusterInterfaceMock.ControllerFunc: method is nil but ClusterInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterInterface.ControllerCalls()) +func (mock *ClusterInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterInterfaceMock) Create(in1 *v3.Cluster) (*v3.Cluster, error) { + if mock.CreateFunc == nil { + panic("ClusterInterfaceMock.CreateFunc: method is nil but ClusterInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Cluster + }{ + In1: in1, + } + lockClusterInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterInterface.CreateCalls()) +func (mock *ClusterInterfaceMock) CreateCalls() []struct { + In1 *v3.Cluster +} { + var calls []struct { + In1 *v3.Cluster + } + lockClusterInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterInterfaceMock.DeleteFunc: method is nil but ClusterInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterInterface.DeleteCalls()) +func (mock *ClusterInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterInterfaceMock.DeleteCollectionFunc: method is nil but ClusterInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterInterface.DeleteCollectionCalls()) +func (mock *ClusterInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterInterface.DeleteNamespacedCalls()) +func (mock *ClusterInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Cluster, error) { + if mock.GetFunc == nil { + panic("ClusterInterfaceMock.GetFunc: method is nil but ClusterInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterInterface.GetCalls()) +func (mock *ClusterInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Cluster, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterInterfaceMock.GetNamespacedFunc: method is nil but ClusterInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterInterface.GetNamespacedCalls()) +func (mock *ClusterInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterList, error) { + if mock.ListFunc == nil { + panic("ClusterInterfaceMock.ListFunc: method is nil but ClusterInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterInterface.ListCalls()) +func (mock *ClusterInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterInterfaceMock.ListNamespacedFunc: method is nil but ClusterInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterInterface.ListNamespacedCalls()) +func (mock *ClusterInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterInterfaceMock.ObjectClientFunc: method is nil but ClusterInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterInterface.ObjectClientCalls()) +func (mock *ClusterInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterInterfaceMock) Update(in1 *v3.Cluster) (*v3.Cluster, error) { + if mock.UpdateFunc == nil { + panic("ClusterInterfaceMock.UpdateFunc: method is nil but ClusterInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Cluster + }{ + In1: in1, + } + lockClusterInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterInterface.UpdateCalls()) +func (mock *ClusterInterfaceMock) UpdateCalls() []struct { + In1 *v3.Cluster +} { + var calls []struct { + In1 *v3.Cluster + } + lockClusterInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterInterfaceMock.WatchFunc: method is nil but ClusterInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterInterface.WatchCalls()) +func (mock *ClusterInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClustersGetterMockClusters sync.RWMutex +) + +// Ensure, that ClustersGetterMock does implement v31.ClustersGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClustersGetter = &ClustersGetterMock{} + +// ClustersGetterMock is a mock implementation of v31.ClustersGetter. +// +// func TestSomethingThatUsesClustersGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClustersGetter +// mockedClustersGetter := &ClustersGetterMock{ +// ClustersFunc: func(namespace string) v31.ClusterInterface { +// panic("mock out the Clusters method") +// }, +// } +// +// // use mockedClustersGetter in code that requires v31.ClustersGetter +// // and then make assertions. +// +// } +type ClustersGetterMock struct { + // ClustersFunc mocks the Clusters method. + ClustersFunc func(namespace string) v31.ClusterInterface + + // calls tracks calls to the methods. + calls struct { + // Clusters holds details about calls to the Clusters method. + Clusters []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Clusters calls ClustersFunc. +func (mock *ClustersGetterMock) Clusters(namespace string) v31.ClusterInterface { + if mock.ClustersFunc == nil { + panic("ClustersGetterMock.ClustersFunc: method is nil but ClustersGetter.Clusters was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClustersGetterMockClusters.Lock() + mock.calls.Clusters = append(mock.calls.Clusters, callInfo) + lockClustersGetterMockClusters.Unlock() + return mock.ClustersFunc(namespace) +} + +// ClustersCalls gets all the calls that were made to Clusters. +// Check the length with: +// +// len(mockedClustersGetter.ClustersCalls()) +func (mock *ClustersGetterMock) ClustersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClustersGetterMockClusters.RLock() + calls = mock.calls.Clusters + lockClustersGetterMockClusters.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_registration_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_registration_token_mock.go new file mode 100644 index 0000000..2658fd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_registration_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterRegistrationTokenListerMockGet sync.RWMutex + lockClusterRegistrationTokenListerMockList sync.RWMutex +) + +// Ensure, that ClusterRegistrationTokenListerMock does implement v31.ClusterRegistrationTokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRegistrationTokenLister = &ClusterRegistrationTokenListerMock{} + +// ClusterRegistrationTokenListerMock is a mock implementation of v31.ClusterRegistrationTokenLister. +// +// func TestSomethingThatUsesClusterRegistrationTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRegistrationTokenLister +// mockedClusterRegistrationTokenLister := &ClusterRegistrationTokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterRegistrationToken, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterRegistrationToken, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterRegistrationTokenLister in code that requires v31.ClusterRegistrationTokenLister +// // and then make assertions. +// +// } +type ClusterRegistrationTokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterRegistrationToken, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterRegistrationToken, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterRegistrationTokenListerMock) Get(namespace string, name string) (*v3.ClusterRegistrationToken, error) { + if mock.GetFunc == nil { + panic("ClusterRegistrationTokenListerMock.GetFunc: method is nil but ClusterRegistrationTokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRegistrationTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRegistrationTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRegistrationTokenLister.GetCalls()) +func (mock *ClusterRegistrationTokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRegistrationTokenListerMockGet.RLock() + calls = mock.calls.Get + lockClusterRegistrationTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRegistrationTokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterRegistrationToken, error) { + if mock.ListFunc == nil { + panic("ClusterRegistrationTokenListerMock.ListFunc: method is nil but ClusterRegistrationTokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterRegistrationTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRegistrationTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRegistrationTokenLister.ListCalls()) +func (mock *ClusterRegistrationTokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterRegistrationTokenListerMockList.RLock() + calls = mock.calls.List + lockClusterRegistrationTokenListerMockList.RUnlock() + return calls +} + +var ( + lockClusterRegistrationTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRegistrationTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterRegistrationTokenControllerMockAddFeatureHandler sync.RWMutex + lockClusterRegistrationTokenControllerMockAddHandler sync.RWMutex + lockClusterRegistrationTokenControllerMockEnqueue sync.RWMutex + lockClusterRegistrationTokenControllerMockEnqueueAfter sync.RWMutex + lockClusterRegistrationTokenControllerMockGeneric sync.RWMutex + lockClusterRegistrationTokenControllerMockInformer sync.RWMutex + lockClusterRegistrationTokenControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterRegistrationTokenControllerMock does implement v31.ClusterRegistrationTokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRegistrationTokenController = &ClusterRegistrationTokenControllerMock{} + +// ClusterRegistrationTokenControllerMock is a mock implementation of v31.ClusterRegistrationTokenController. +// +// func TestSomethingThatUsesClusterRegistrationTokenController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRegistrationTokenController +// mockedClusterRegistrationTokenController := &ClusterRegistrationTokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterRegistrationTokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterRegistrationTokenController in code that requires v31.ClusterRegistrationTokenController +// // and then make assertions. +// +// } +type ClusterRegistrationTokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterRegistrationTokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterRegistrationTokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterRegistrationTokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterRegistrationTokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRegistrationTokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterRegistrationTokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRegistrationTokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRegistrationTokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRegistrationTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRegistrationTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRegistrationTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRegistrationTokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterRegistrationTokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRegistrationTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRegistrationTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.AddClusterScopedHandlerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRegistrationTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRegistrationTokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.AddFeatureHandlerFunc: method is nil but ClusterRegistrationTokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRegistrationTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRegistrationTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.AddFeatureHandlerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRegistrationTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRegistrationTokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.AddHandlerFunc: method is nil but ClusterRegistrationTokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterRegistrationTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRegistrationTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.AddHandlerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRegistrationTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterRegistrationTokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterRegistrationTokenControllerMock.EnqueueFunc: method is nil but ClusterRegistrationTokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRegistrationTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterRegistrationTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.EnqueueCalls()) +func (mock *ClusterRegistrationTokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRegistrationTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterRegistrationTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterRegistrationTokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterRegistrationTokenControllerMock.EnqueueAfterFunc: method is nil but ClusterRegistrationTokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterRegistrationTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterRegistrationTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.EnqueueAfterCalls()) +func (mock *ClusterRegistrationTokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterRegistrationTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterRegistrationTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterRegistrationTokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterRegistrationTokenControllerMock.GenericFunc: method is nil but ClusterRegistrationTokenController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterRegistrationTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterRegistrationTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.GenericCalls()) +func (mock *ClusterRegistrationTokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterRegistrationTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterRegistrationTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterRegistrationTokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.InformerFunc: method is nil but ClusterRegistrationTokenController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterRegistrationTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterRegistrationTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.InformerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterRegistrationTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterRegistrationTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterRegistrationTokenControllerMock) Lister() v31.ClusterRegistrationTokenLister { + if mock.ListerFunc == nil { + panic("ClusterRegistrationTokenControllerMock.ListerFunc: method is nil but ClusterRegistrationTokenController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterRegistrationTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterRegistrationTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterRegistrationTokenController.ListerCalls()) +func (mock *ClusterRegistrationTokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterRegistrationTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterRegistrationTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddHandler sync.RWMutex + lockClusterRegistrationTokenInterfaceMockAddLifecycle sync.RWMutex + lockClusterRegistrationTokenInterfaceMockController sync.RWMutex + lockClusterRegistrationTokenInterfaceMockCreate sync.RWMutex + lockClusterRegistrationTokenInterfaceMockDelete sync.RWMutex + lockClusterRegistrationTokenInterfaceMockDeleteCollection sync.RWMutex + lockClusterRegistrationTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterRegistrationTokenInterfaceMockGet sync.RWMutex + lockClusterRegistrationTokenInterfaceMockGetNamespaced sync.RWMutex + lockClusterRegistrationTokenInterfaceMockList sync.RWMutex + lockClusterRegistrationTokenInterfaceMockListNamespaced sync.RWMutex + lockClusterRegistrationTokenInterfaceMockObjectClient sync.RWMutex + lockClusterRegistrationTokenInterfaceMockUpdate sync.RWMutex + lockClusterRegistrationTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterRegistrationTokenInterfaceMock does implement v31.ClusterRegistrationTokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRegistrationTokenInterface = &ClusterRegistrationTokenInterfaceMock{} + +// ClusterRegistrationTokenInterfaceMock is a mock implementation of v31.ClusterRegistrationTokenInterface. +// +// func TestSomethingThatUsesClusterRegistrationTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRegistrationTokenInterface +// mockedClusterRegistrationTokenInterface := &ClusterRegistrationTokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterRegistrationTokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterRegistrationTokenInterface in code that requires v31.ClusterRegistrationTokenInterface +// // and then make assertions. +// +// } +type ClusterRegistrationTokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterRegistrationTokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterRegistrationTokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterRegistrationTokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRegistrationTokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRegistrationTokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterRegistrationToken + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterRegistrationToken + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRegistrationTokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterRegistrationTokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterRegistrationTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterRegistrationTokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRegistrationTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRegistrationTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRegistrationTokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterRegistrationTokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterRegistrationTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + lockClusterRegistrationTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterRegistrationTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterRegistrationTokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRegistrationTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRegistrationTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddFeatureHandlerCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRegistrationTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterRegistrationTokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRegistrationTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterRegistrationTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + lockClusterRegistrationTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterRegistrationTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterRegistrationTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddHandlerFunc: method is nil but ClusterRegistrationTokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterRegistrationTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRegistrationTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddHandlerCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterRegistrationTokenHandlerFunc + } + lockClusterRegistrationTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRegistrationTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterRegistrationTokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.AddLifecycleFunc: method is nil but ClusterRegistrationTokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRegistrationTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterRegistrationTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.AddLifecycleCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRegistrationTokenLifecycle + } + lockClusterRegistrationTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterRegistrationTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Controller() v31.ClusterRegistrationTokenController { + if mock.ControllerFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.ControllerFunc: method is nil but ClusterRegistrationTokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterRegistrationTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterRegistrationTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.ControllerCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterRegistrationTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterRegistrationTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Create(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + if mock.CreateFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.CreateFunc: method is nil but ClusterRegistrationTokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterRegistrationToken + }{ + In1: in1, + } + lockClusterRegistrationTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterRegistrationTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.CreateCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterRegistrationToken +} { + var calls []struct { + In1 *v3.ClusterRegistrationToken + } + lockClusterRegistrationTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterRegistrationTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.DeleteFunc: method is nil but ClusterRegistrationTokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterRegistrationTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterRegistrationTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.DeleteCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterRegistrationTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterRegistrationTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.DeleteCollectionFunc: method is nil but ClusterRegistrationTokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterRegistrationTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterRegistrationTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.DeleteCollectionCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterRegistrationTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterRegistrationTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterRegistrationTokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterRegistrationTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterRegistrationTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.DeleteNamespacedCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterRegistrationTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterRegistrationTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { + if mock.GetFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.GetFunc: method is nil but ClusterRegistrationTokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterRegistrationTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRegistrationTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.GetCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterRegistrationTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterRegistrationTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.GetNamespacedFunc: method is nil but ClusterRegistrationTokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterRegistrationTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterRegistrationTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.GetNamespacedCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterRegistrationTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterRegistrationTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { + if mock.ListFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.ListFunc: method is nil but ClusterRegistrationTokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRegistrationTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRegistrationTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.ListCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRegistrationTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterRegistrationTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.ListNamespacedFunc: method is nil but ClusterRegistrationTokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterRegistrationTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterRegistrationTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.ListNamespacedCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterRegistrationTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterRegistrationTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.ObjectClientFunc: method is nil but ClusterRegistrationTokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterRegistrationTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterRegistrationTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.ObjectClientCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterRegistrationTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterRegistrationTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Update(in1 *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + if mock.UpdateFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.UpdateFunc: method is nil but ClusterRegistrationTokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterRegistrationToken + }{ + In1: in1, + } + lockClusterRegistrationTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterRegistrationTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.UpdateCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterRegistrationToken +} { + var calls []struct { + In1 *v3.ClusterRegistrationToken + } + lockClusterRegistrationTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterRegistrationTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterRegistrationTokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterRegistrationTokenInterfaceMock.WatchFunc: method is nil but ClusterRegistrationTokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRegistrationTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterRegistrationTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterRegistrationTokenInterface.WatchCalls()) +func (mock *ClusterRegistrationTokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRegistrationTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterRegistrationTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterRegistrationTokensGetterMockClusterRegistrationTokens sync.RWMutex +) + +// Ensure, that ClusterRegistrationTokensGetterMock does implement v31.ClusterRegistrationTokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRegistrationTokensGetter = &ClusterRegistrationTokensGetterMock{} + +// ClusterRegistrationTokensGetterMock is a mock implementation of v31.ClusterRegistrationTokensGetter. +// +// func TestSomethingThatUsesClusterRegistrationTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRegistrationTokensGetter +// mockedClusterRegistrationTokensGetter := &ClusterRegistrationTokensGetterMock{ +// ClusterRegistrationTokensFunc: func(namespace string) v31.ClusterRegistrationTokenInterface { +// panic("mock out the ClusterRegistrationTokens method") +// }, +// } +// +// // use mockedClusterRegistrationTokensGetter in code that requires v31.ClusterRegistrationTokensGetter +// // and then make assertions. +// +// } +type ClusterRegistrationTokensGetterMock struct { + // ClusterRegistrationTokensFunc mocks the ClusterRegistrationTokens method. + ClusterRegistrationTokensFunc func(namespace string) v31.ClusterRegistrationTokenInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterRegistrationTokens holds details about calls to the ClusterRegistrationTokens method. + ClusterRegistrationTokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterRegistrationTokens calls ClusterRegistrationTokensFunc. +func (mock *ClusterRegistrationTokensGetterMock) ClusterRegistrationTokens(namespace string) v31.ClusterRegistrationTokenInterface { + if mock.ClusterRegistrationTokensFunc == nil { + panic("ClusterRegistrationTokensGetterMock.ClusterRegistrationTokensFunc: method is nil but ClusterRegistrationTokensGetter.ClusterRegistrationTokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterRegistrationTokensGetterMockClusterRegistrationTokens.Lock() + mock.calls.ClusterRegistrationTokens = append(mock.calls.ClusterRegistrationTokens, callInfo) + lockClusterRegistrationTokensGetterMockClusterRegistrationTokens.Unlock() + return mock.ClusterRegistrationTokensFunc(namespace) +} + +// ClusterRegistrationTokensCalls gets all the calls that were made to ClusterRegistrationTokens. +// Check the length with: +// +// len(mockedClusterRegistrationTokensGetter.ClusterRegistrationTokensCalls()) +func (mock *ClusterRegistrationTokensGetterMock) ClusterRegistrationTokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterRegistrationTokensGetterMockClusterRegistrationTokens.RLock() + calls = mock.calls.ClusterRegistrationTokens + lockClusterRegistrationTokensGetterMockClusterRegistrationTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_role_template_binding_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_role_template_binding_mock.go new file mode 100644 index 0000000..e6c7496 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_role_template_binding_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterRoleTemplateBindingListerMockGet sync.RWMutex + lockClusterRoleTemplateBindingListerMockList sync.RWMutex +) + +// Ensure, that ClusterRoleTemplateBindingListerMock does implement v31.ClusterRoleTemplateBindingLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRoleTemplateBindingLister = &ClusterRoleTemplateBindingListerMock{} + +// ClusterRoleTemplateBindingListerMock is a mock implementation of v31.ClusterRoleTemplateBindingLister. +// +// func TestSomethingThatUsesClusterRoleTemplateBindingLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRoleTemplateBindingLister +// mockedClusterRoleTemplateBindingLister := &ClusterRoleTemplateBindingListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterRoleTemplateBindingLister in code that requires v31.ClusterRoleTemplateBindingLister +// // and then make assertions. +// +// } +type ClusterRoleTemplateBindingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterRoleTemplateBinding, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterRoleTemplateBinding, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterRoleTemplateBindingListerMock) Get(namespace string, name string) (*v3.ClusterRoleTemplateBinding, error) { + if mock.GetFunc == nil { + panic("ClusterRoleTemplateBindingListerMock.GetFunc: method is nil but ClusterRoleTemplateBindingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleTemplateBindingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleTemplateBindingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingLister.GetCalls()) +func (mock *ClusterRoleTemplateBindingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleTemplateBindingListerMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleTemplateBindingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleTemplateBindingListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterRoleTemplateBinding, error) { + if mock.ListFunc == nil { + panic("ClusterRoleTemplateBindingListerMock.ListFunc: method is nil but ClusterRoleTemplateBindingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterRoleTemplateBindingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleTemplateBindingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingLister.ListCalls()) +func (mock *ClusterRoleTemplateBindingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterRoleTemplateBindingListerMockList.RLock() + calls = mock.calls.List + lockClusterRoleTemplateBindingListerMockList.RUnlock() + return calls +} + +var ( + lockClusterRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleTemplateBindingControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleTemplateBindingControllerMockAddFeatureHandler sync.RWMutex + lockClusterRoleTemplateBindingControllerMockAddHandler sync.RWMutex + lockClusterRoleTemplateBindingControllerMockEnqueue sync.RWMutex + lockClusterRoleTemplateBindingControllerMockEnqueueAfter sync.RWMutex + lockClusterRoleTemplateBindingControllerMockGeneric sync.RWMutex + lockClusterRoleTemplateBindingControllerMockInformer sync.RWMutex + lockClusterRoleTemplateBindingControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterRoleTemplateBindingControllerMock does implement v31.ClusterRoleTemplateBindingController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRoleTemplateBindingController = &ClusterRoleTemplateBindingControllerMock{} + +// ClusterRoleTemplateBindingControllerMock is a mock implementation of v31.ClusterRoleTemplateBindingController. +// +// func TestSomethingThatUsesClusterRoleTemplateBindingController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRoleTemplateBindingController +// mockedClusterRoleTemplateBindingController := &ClusterRoleTemplateBindingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterRoleTemplateBindingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterRoleTemplateBindingController in code that requires v31.ClusterRoleTemplateBindingController +// // and then make assertions. +// +// } +type ClusterRoleTemplateBindingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterRoleTemplateBindingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterRoleTemplateBindingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleTemplateBindingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleTemplateBindingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleTemplateBindingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleTemplateBindingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleTemplateBindingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.AddFeatureHandlerFunc: method is nil but ClusterRoleTemplateBindingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleTemplateBindingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleTemplateBindingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.AddFeatureHandlerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleTemplateBindingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.AddHandlerFunc: method is nil but ClusterRoleTemplateBindingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterRoleTemplateBindingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleTemplateBindingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.AddHandlerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleTemplateBindingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.EnqueueFunc: method is nil but ClusterRoleTemplateBindingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleTemplateBindingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterRoleTemplateBindingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.EnqueueCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleTemplateBindingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterRoleTemplateBindingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.EnqueueAfterFunc: method is nil but ClusterRoleTemplateBindingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterRoleTemplateBindingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterRoleTemplateBindingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.EnqueueAfterCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterRoleTemplateBindingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterRoleTemplateBindingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.GenericFunc: method is nil but ClusterRoleTemplateBindingController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterRoleTemplateBindingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterRoleTemplateBindingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.GenericCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleTemplateBindingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterRoleTemplateBindingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.InformerFunc: method is nil but ClusterRoleTemplateBindingController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterRoleTemplateBindingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterRoleTemplateBindingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.InformerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleTemplateBindingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterRoleTemplateBindingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterRoleTemplateBindingControllerMock) Lister() v31.ClusterRoleTemplateBindingLister { + if mock.ListerFunc == nil { + panic("ClusterRoleTemplateBindingControllerMock.ListerFunc: method is nil but ClusterRoleTemplateBindingController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterRoleTemplateBindingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterRoleTemplateBindingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingController.ListerCalls()) +func (mock *ClusterRoleTemplateBindingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleTemplateBindingControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterRoleTemplateBindingControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddHandler sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockAddLifecycle sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockController sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockCreate sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockDelete sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockDeleteCollection sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockGet sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockGetNamespaced sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockList sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockListNamespaced sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockObjectClient sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockUpdate sync.RWMutex + lockClusterRoleTemplateBindingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterRoleTemplateBindingInterfaceMock does implement v31.ClusterRoleTemplateBindingInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRoleTemplateBindingInterface = &ClusterRoleTemplateBindingInterfaceMock{} + +// ClusterRoleTemplateBindingInterfaceMock is a mock implementation of v31.ClusterRoleTemplateBindingInterface. +// +// func TestSomethingThatUsesClusterRoleTemplateBindingInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRoleTemplateBindingInterface +// mockedClusterRoleTemplateBindingInterface := &ClusterRoleTemplateBindingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterRoleTemplateBindingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterRoleTemplateBindingInterface in code that requires v31.ClusterRoleTemplateBindingInterface +// // and then make assertions. +// +// } +type ClusterRoleTemplateBindingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterRoleTemplateBindingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterRoleTemplateBinding + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterRoleTemplateBinding + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleTemplateBindingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterRoleTemplateBindingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleTemplateBindingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterRoleTemplateBindingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterRoleTemplateBindingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleTemplateBindingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddFeatureHandlerCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleTemplateBindingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterRoleTemplateBindingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleTemplateBindingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + lockClusterRoleTemplateBindingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterRoleTemplateBindingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterRoleTemplateBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddHandlerFunc: method is nil but ClusterRoleTemplateBindingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleTemplateBindingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddHandlerCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterRoleTemplateBindingHandlerFunc + } + lockClusterRoleTemplateBindingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleTemplateBindingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterRoleTemplateBindingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.AddLifecycleFunc: method is nil but ClusterRoleTemplateBindingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleTemplateBindingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterRoleTemplateBindingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.AddLifecycleCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterRoleTemplateBindingLifecycle + } + lockClusterRoleTemplateBindingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterRoleTemplateBindingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Controller() v31.ClusterRoleTemplateBindingController { + if mock.ControllerFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.ControllerFunc: method is nil but ClusterRoleTemplateBindingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterRoleTemplateBindingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterRoleTemplateBindingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.ControllerCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleTemplateBindingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterRoleTemplateBindingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Create(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + if mock.CreateFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.CreateFunc: method is nil but ClusterRoleTemplateBindingInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterRoleTemplateBinding + }{ + In1: in1, + } + lockClusterRoleTemplateBindingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterRoleTemplateBindingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.CreateCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterRoleTemplateBinding +} { + var calls []struct { + In1 *v3.ClusterRoleTemplateBinding + } + lockClusterRoleTemplateBindingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterRoleTemplateBindingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.DeleteFunc: method is nil but ClusterRoleTemplateBindingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterRoleTemplateBindingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterRoleTemplateBindingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.DeleteCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleTemplateBindingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterRoleTemplateBindingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.DeleteCollectionFunc: method is nil but ClusterRoleTemplateBindingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterRoleTemplateBindingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterRoleTemplateBindingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.DeleteCollectionCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterRoleTemplateBindingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterRoleTemplateBindingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterRoleTemplateBindingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterRoleTemplateBindingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterRoleTemplateBindingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.DeleteNamespacedCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleTemplateBindingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterRoleTemplateBindingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { + if mock.GetFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.GetFunc: method is nil but ClusterRoleTemplateBindingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterRoleTemplateBindingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleTemplateBindingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.GetCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterRoleTemplateBindingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleTemplateBindingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.GetNamespacedFunc: method is nil but ClusterRoleTemplateBindingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterRoleTemplateBindingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterRoleTemplateBindingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.GetNamespacedCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterRoleTemplateBindingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterRoleTemplateBindingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { + if mock.ListFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.ListFunc: method is nil but ClusterRoleTemplateBindingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleTemplateBindingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleTemplateBindingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.ListCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleTemplateBindingInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterRoleTemplateBindingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.ListNamespacedFunc: method is nil but ClusterRoleTemplateBindingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterRoleTemplateBindingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterRoleTemplateBindingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.ListNamespacedCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterRoleTemplateBindingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterRoleTemplateBindingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.ObjectClientFunc: method is nil but ClusterRoleTemplateBindingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterRoleTemplateBindingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterRoleTemplateBindingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.ObjectClientCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleTemplateBindingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterRoleTemplateBindingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Update(in1 *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + if mock.UpdateFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.UpdateFunc: method is nil but ClusterRoleTemplateBindingInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterRoleTemplateBinding + }{ + In1: in1, + } + lockClusterRoleTemplateBindingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterRoleTemplateBindingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.UpdateCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterRoleTemplateBinding +} { + var calls []struct { + In1 *v3.ClusterRoleTemplateBinding + } + lockClusterRoleTemplateBindingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterRoleTemplateBindingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterRoleTemplateBindingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterRoleTemplateBindingInterfaceMock.WatchFunc: method is nil but ClusterRoleTemplateBindingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleTemplateBindingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterRoleTemplateBindingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingInterface.WatchCalls()) +func (mock *ClusterRoleTemplateBindingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleTemplateBindingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterRoleTemplateBindingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterRoleTemplateBindingsGetterMockClusterRoleTemplateBindings sync.RWMutex +) + +// Ensure, that ClusterRoleTemplateBindingsGetterMock does implement v31.ClusterRoleTemplateBindingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterRoleTemplateBindingsGetter = &ClusterRoleTemplateBindingsGetterMock{} + +// ClusterRoleTemplateBindingsGetterMock is a mock implementation of v31.ClusterRoleTemplateBindingsGetter. +// +// func TestSomethingThatUsesClusterRoleTemplateBindingsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterRoleTemplateBindingsGetter +// mockedClusterRoleTemplateBindingsGetter := &ClusterRoleTemplateBindingsGetterMock{ +// ClusterRoleTemplateBindingsFunc: func(namespace string) v31.ClusterRoleTemplateBindingInterface { +// panic("mock out the ClusterRoleTemplateBindings method") +// }, +// } +// +// // use mockedClusterRoleTemplateBindingsGetter in code that requires v31.ClusterRoleTemplateBindingsGetter +// // and then make assertions. +// +// } +type ClusterRoleTemplateBindingsGetterMock struct { + // ClusterRoleTemplateBindingsFunc mocks the ClusterRoleTemplateBindings method. + ClusterRoleTemplateBindingsFunc func(namespace string) v31.ClusterRoleTemplateBindingInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterRoleTemplateBindings holds details about calls to the ClusterRoleTemplateBindings method. + ClusterRoleTemplateBindings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterRoleTemplateBindings calls ClusterRoleTemplateBindingsFunc. +func (mock *ClusterRoleTemplateBindingsGetterMock) ClusterRoleTemplateBindings(namespace string) v31.ClusterRoleTemplateBindingInterface { + if mock.ClusterRoleTemplateBindingsFunc == nil { + panic("ClusterRoleTemplateBindingsGetterMock.ClusterRoleTemplateBindingsFunc: method is nil but ClusterRoleTemplateBindingsGetter.ClusterRoleTemplateBindings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterRoleTemplateBindingsGetterMockClusterRoleTemplateBindings.Lock() + mock.calls.ClusterRoleTemplateBindings = append(mock.calls.ClusterRoleTemplateBindings, callInfo) + lockClusterRoleTemplateBindingsGetterMockClusterRoleTemplateBindings.Unlock() + return mock.ClusterRoleTemplateBindingsFunc(namespace) +} + +// ClusterRoleTemplateBindingsCalls gets all the calls that were made to ClusterRoleTemplateBindings. +// Check the length with: +// +// len(mockedClusterRoleTemplateBindingsGetter.ClusterRoleTemplateBindingsCalls()) +func (mock *ClusterRoleTemplateBindingsGetterMock) ClusterRoleTemplateBindingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterRoleTemplateBindingsGetterMockClusterRoleTemplateBindings.RLock() + calls = mock.calls.ClusterRoleTemplateBindings + lockClusterRoleTemplateBindingsGetterMockClusterRoleTemplateBindings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_mock.go new file mode 100644 index 0000000..8b2eb15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterTemplateListerMockGet sync.RWMutex + lockClusterTemplateListerMockList sync.RWMutex +) + +// Ensure, that ClusterTemplateListerMock does implement v31.ClusterTemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateLister = &ClusterTemplateListerMock{} + +// ClusterTemplateListerMock is a mock implementation of v31.ClusterTemplateLister. +// +// func TestSomethingThatUsesClusterTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateLister +// mockedClusterTemplateLister := &ClusterTemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterTemplate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterTemplate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterTemplateLister in code that requires v31.ClusterTemplateLister +// // and then make assertions. +// +// } +type ClusterTemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterTemplate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterTemplateListerMock) Get(namespace string, name string) (*v3.ClusterTemplate, error) { + if mock.GetFunc == nil { + panic("ClusterTemplateListerMock.GetFunc: method is nil but ClusterTemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterTemplateLister.GetCalls()) +func (mock *ClusterTemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockClusterTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterTemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterTemplate, error) { + if mock.ListFunc == nil { + panic("ClusterTemplateListerMock.ListFunc: method is nil but ClusterTemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterTemplateLister.ListCalls()) +func (mock *ClusterTemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterTemplateListerMockList.RLock() + calls = mock.calls.List + lockClusterTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockClusterTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterTemplateControllerMockAddFeatureHandler sync.RWMutex + lockClusterTemplateControllerMockAddHandler sync.RWMutex + lockClusterTemplateControllerMockEnqueue sync.RWMutex + lockClusterTemplateControllerMockEnqueueAfter sync.RWMutex + lockClusterTemplateControllerMockGeneric sync.RWMutex + lockClusterTemplateControllerMockInformer sync.RWMutex + lockClusterTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterTemplateControllerMock does implement v31.ClusterTemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateController = &ClusterTemplateControllerMock{} + +// ClusterTemplateControllerMock is a mock implementation of v31.ClusterTemplateController. +// +// func TestSomethingThatUsesClusterTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateController +// mockedClusterTemplateController := &ClusterTemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterTemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterTemplateController in code that requires v31.ClusterTemplateController +// // and then make assertions. +// +// } +type ClusterTemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterTemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterTemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterTemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterTemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterTemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterTemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterTemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterTemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterTemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterTemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterTemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterTemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterTemplateController.AddClusterScopedHandlerCalls()) +func (mock *ClusterTemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterTemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterTemplateControllerMock.AddFeatureHandlerFunc: method is nil but ClusterTemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateController.AddFeatureHandlerCalls()) +func (mock *ClusterTemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterTemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterTemplateControllerMock.AddHandlerFunc: method is nil but ClusterTemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterTemplateController.AddHandlerCalls()) +func (mock *ClusterTemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterTemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterTemplateControllerMock.EnqueueFunc: method is nil but ClusterTemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterTemplateController.EnqueueCalls()) +func (mock *ClusterTemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterTemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterTemplateControllerMock.EnqueueAfterFunc: method is nil but ClusterTemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterTemplateController.EnqueueAfterCalls()) +func (mock *ClusterTemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterTemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterTemplateControllerMock.GenericFunc: method is nil but ClusterTemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterTemplateController.GenericCalls()) +func (mock *ClusterTemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterTemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterTemplateControllerMock.InformerFunc: method is nil but ClusterTemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterTemplateController.InformerCalls()) +func (mock *ClusterTemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterTemplateControllerMock) Lister() v31.ClusterTemplateLister { + if mock.ListerFunc == nil { + panic("ClusterTemplateControllerMock.ListerFunc: method is nil but ClusterTemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterTemplateController.ListerCalls()) +func (mock *ClusterTemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterTemplateInterfaceMockAddHandler sync.RWMutex + lockClusterTemplateInterfaceMockAddLifecycle sync.RWMutex + lockClusterTemplateInterfaceMockController sync.RWMutex + lockClusterTemplateInterfaceMockCreate sync.RWMutex + lockClusterTemplateInterfaceMockDelete sync.RWMutex + lockClusterTemplateInterfaceMockDeleteCollection sync.RWMutex + lockClusterTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterTemplateInterfaceMockGet sync.RWMutex + lockClusterTemplateInterfaceMockGetNamespaced sync.RWMutex + lockClusterTemplateInterfaceMockList sync.RWMutex + lockClusterTemplateInterfaceMockListNamespaced sync.RWMutex + lockClusterTemplateInterfaceMockObjectClient sync.RWMutex + lockClusterTemplateInterfaceMockUpdate sync.RWMutex + lockClusterTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterTemplateInterfaceMock does implement v31.ClusterTemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateInterface = &ClusterTemplateInterfaceMock{} + +// ClusterTemplateInterfaceMock is a mock implementation of v31.ClusterTemplateInterface. +// +// func TestSomethingThatUsesClusterTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateInterface +// mockedClusterTemplateInterface := &ClusterTemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterTemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterTemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterTemplateInterface in code that requires v31.ClusterTemplateInterface +// // and then make assertions. +// +// } +type ClusterTemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterTemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterTemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterTemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterTemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterTemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterTemplate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterTemplate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterTemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterTemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterTemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterTemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle + } + lockClusterTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterTemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterTemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterTemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterTemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterTemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateLifecycle + } + lockClusterTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterTemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterTemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterTemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddFeatureHandlerCalls()) +func (mock *ClusterTemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterTemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterTemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterTemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterTemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateLifecycle + } + lockClusterTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterTemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterTemplateInterfaceMock.AddHandlerFunc: method is nil but ClusterTemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddHandlerCalls()) +func (mock *ClusterTemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateHandlerFunc + } + lockClusterTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterTemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterTemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterTemplateInterfaceMock.AddLifecycleFunc: method is nil but ClusterTemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateInterface.AddLifecycleCalls()) +func (mock *ClusterTemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateLifecycle + } + lockClusterTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterTemplateInterfaceMock) Controller() v31.ClusterTemplateController { + if mock.ControllerFunc == nil { + panic("ClusterTemplateInterfaceMock.ControllerFunc: method is nil but ClusterTemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterTemplateInterface.ControllerCalls()) +func (mock *ClusterTemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterTemplateInterfaceMock) Create(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { + if mock.CreateFunc == nil { + panic("ClusterTemplateInterfaceMock.CreateFunc: method is nil but ClusterTemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterTemplate + }{ + In1: in1, + } + lockClusterTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterTemplateInterface.CreateCalls()) +func (mock *ClusterTemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterTemplate +} { + var calls []struct { + In1 *v3.ClusterTemplate + } + lockClusterTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterTemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterTemplateInterfaceMock.DeleteFunc: method is nil but ClusterTemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterTemplateInterface.DeleteCalls()) +func (mock *ClusterTemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterTemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterTemplateInterfaceMock.DeleteCollectionFunc: method is nil but ClusterTemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterTemplateInterface.DeleteCollectionCalls()) +func (mock *ClusterTemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterTemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterTemplateInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterTemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateInterface.DeleteNamespacedCalls()) +func (mock *ClusterTemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterTemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { + if mock.GetFunc == nil { + panic("ClusterTemplateInterfaceMock.GetFunc: method is nil but ClusterTemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterTemplateInterface.GetCalls()) +func (mock *ClusterTemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterTemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterTemplateInterfaceMock.GetNamespacedFunc: method is nil but ClusterTemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateInterface.GetNamespacedCalls()) +func (mock *ClusterTemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterTemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { + if mock.ListFunc == nil { + panic("ClusterTemplateInterfaceMock.ListFunc: method is nil but ClusterTemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterTemplateInterface.ListCalls()) +func (mock *ClusterTemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterTemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterTemplateInterfaceMock.ListNamespacedFunc: method is nil but ClusterTemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateInterface.ListNamespacedCalls()) +func (mock *ClusterTemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterTemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterTemplateInterfaceMock.ObjectClientFunc: method is nil but ClusterTemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterTemplateInterface.ObjectClientCalls()) +func (mock *ClusterTemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterTemplateInterfaceMock) Update(in1 *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { + if mock.UpdateFunc == nil { + panic("ClusterTemplateInterfaceMock.UpdateFunc: method is nil but ClusterTemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterTemplate + }{ + In1: in1, + } + lockClusterTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterTemplateInterface.UpdateCalls()) +func (mock *ClusterTemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterTemplate +} { + var calls []struct { + In1 *v3.ClusterTemplate + } + lockClusterTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterTemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterTemplateInterfaceMock.WatchFunc: method is nil but ClusterTemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterTemplateInterface.WatchCalls()) +func (mock *ClusterTemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterTemplatesGetterMockClusterTemplates sync.RWMutex +) + +// Ensure, that ClusterTemplatesGetterMock does implement v31.ClusterTemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplatesGetter = &ClusterTemplatesGetterMock{} + +// ClusterTemplatesGetterMock is a mock implementation of v31.ClusterTemplatesGetter. +// +// func TestSomethingThatUsesClusterTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplatesGetter +// mockedClusterTemplatesGetter := &ClusterTemplatesGetterMock{ +// ClusterTemplatesFunc: func(namespace string) v31.ClusterTemplateInterface { +// panic("mock out the ClusterTemplates method") +// }, +// } +// +// // use mockedClusterTemplatesGetter in code that requires v31.ClusterTemplatesGetter +// // and then make assertions. +// +// } +type ClusterTemplatesGetterMock struct { + // ClusterTemplatesFunc mocks the ClusterTemplates method. + ClusterTemplatesFunc func(namespace string) v31.ClusterTemplateInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterTemplates holds details about calls to the ClusterTemplates method. + ClusterTemplates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterTemplates calls ClusterTemplatesFunc. +func (mock *ClusterTemplatesGetterMock) ClusterTemplates(namespace string) v31.ClusterTemplateInterface { + if mock.ClusterTemplatesFunc == nil { + panic("ClusterTemplatesGetterMock.ClusterTemplatesFunc: method is nil but ClusterTemplatesGetter.ClusterTemplates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterTemplatesGetterMockClusterTemplates.Lock() + mock.calls.ClusterTemplates = append(mock.calls.ClusterTemplates, callInfo) + lockClusterTemplatesGetterMockClusterTemplates.Unlock() + return mock.ClusterTemplatesFunc(namespace) +} + +// ClusterTemplatesCalls gets all the calls that were made to ClusterTemplates. +// Check the length with: +// +// len(mockedClusterTemplatesGetter.ClusterTemplatesCalls()) +func (mock *ClusterTemplatesGetterMock) ClusterTemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterTemplatesGetterMockClusterTemplates.RLock() + calls = mock.calls.ClusterTemplates + lockClusterTemplatesGetterMockClusterTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_revision_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_revision_mock.go new file mode 100644 index 0000000..fe6e277 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_cluster_template_revision_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterTemplateRevisionListerMockGet sync.RWMutex + lockClusterTemplateRevisionListerMockList sync.RWMutex +) + +// Ensure, that ClusterTemplateRevisionListerMock does implement v31.ClusterTemplateRevisionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateRevisionLister = &ClusterTemplateRevisionListerMock{} + +// ClusterTemplateRevisionListerMock is a mock implementation of v31.ClusterTemplateRevisionLister. +// +// func TestSomethingThatUsesClusterTemplateRevisionLister(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateRevisionLister +// mockedClusterTemplateRevisionLister := &ClusterTemplateRevisionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ClusterTemplateRevision, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ClusterTemplateRevision, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterTemplateRevisionLister in code that requires v31.ClusterTemplateRevisionLister +// // and then make assertions. +// +// } +type ClusterTemplateRevisionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ClusterTemplateRevision, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ClusterTemplateRevision, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterTemplateRevisionListerMock) Get(namespace string, name string) (*v3.ClusterTemplateRevision, error) { + if mock.GetFunc == nil { + panic("ClusterTemplateRevisionListerMock.GetFunc: method is nil but ClusterTemplateRevisionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterTemplateRevisionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterTemplateRevisionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterTemplateRevisionLister.GetCalls()) +func (mock *ClusterTemplateRevisionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterTemplateRevisionListerMockGet.RLock() + calls = mock.calls.Get + lockClusterTemplateRevisionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterTemplateRevisionListerMock) List(namespace string, selector labels.Selector) ([]*v3.ClusterTemplateRevision, error) { + if mock.ListFunc == nil { + panic("ClusterTemplateRevisionListerMock.ListFunc: method is nil but ClusterTemplateRevisionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterTemplateRevisionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterTemplateRevisionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterTemplateRevisionLister.ListCalls()) +func (mock *ClusterTemplateRevisionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterTemplateRevisionListerMockList.RLock() + calls = mock.calls.List + lockClusterTemplateRevisionListerMockList.RUnlock() + return calls +} + +var ( + lockClusterTemplateRevisionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterTemplateRevisionControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterTemplateRevisionControllerMockAddFeatureHandler sync.RWMutex + lockClusterTemplateRevisionControllerMockAddHandler sync.RWMutex + lockClusterTemplateRevisionControllerMockEnqueue sync.RWMutex + lockClusterTemplateRevisionControllerMockEnqueueAfter sync.RWMutex + lockClusterTemplateRevisionControllerMockGeneric sync.RWMutex + lockClusterTemplateRevisionControllerMockInformer sync.RWMutex + lockClusterTemplateRevisionControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterTemplateRevisionControllerMock does implement v31.ClusterTemplateRevisionController. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateRevisionController = &ClusterTemplateRevisionControllerMock{} + +// ClusterTemplateRevisionControllerMock is a mock implementation of v31.ClusterTemplateRevisionController. +// +// func TestSomethingThatUsesClusterTemplateRevisionController(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateRevisionController +// mockedClusterTemplateRevisionController := &ClusterTemplateRevisionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ClusterTemplateRevisionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterTemplateRevisionController in code that requires v31.ClusterTemplateRevisionController +// // and then make assertions. +// +// } +type ClusterTemplateRevisionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ClusterTemplateRevisionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ClusterTemplateRevisionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterTemplateRevisionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ClusterTemplateRevisionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateRevisionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ClusterTemplateRevisionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterTemplateRevisionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterTemplateRevisionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterTemplateRevisionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterTemplateRevisionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterTemplateRevisionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterTemplateRevisionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterTemplateRevisionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterTemplateRevisionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterTemplateRevisionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.AddClusterScopedHandlerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterTemplateRevisionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterTemplateRevisionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.AddFeatureHandlerFunc: method is nil but ClusterTemplateRevisionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateRevisionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterTemplateRevisionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.AddFeatureHandlerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterTemplateRevisionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterTemplateRevisionControllerMock) AddHandler(ctx context.Context, name string, handler v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.AddHandlerFunc: method is nil but ClusterTemplateRevisionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterTemplateRevisionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterTemplateRevisionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.AddHandlerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterTemplateRevisionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterTemplateRevisionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterTemplateRevisionControllerMock.EnqueueFunc: method is nil but ClusterTemplateRevisionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterTemplateRevisionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterTemplateRevisionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.EnqueueCalls()) +func (mock *ClusterTemplateRevisionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterTemplateRevisionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterTemplateRevisionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterTemplateRevisionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterTemplateRevisionControllerMock.EnqueueAfterFunc: method is nil but ClusterTemplateRevisionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterTemplateRevisionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterTemplateRevisionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.EnqueueAfterCalls()) +func (mock *ClusterTemplateRevisionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterTemplateRevisionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterTemplateRevisionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterTemplateRevisionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterTemplateRevisionControllerMock.GenericFunc: method is nil but ClusterTemplateRevisionController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterTemplateRevisionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterTemplateRevisionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.GenericCalls()) +func (mock *ClusterTemplateRevisionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateRevisionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterTemplateRevisionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterTemplateRevisionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.InformerFunc: method is nil but ClusterTemplateRevisionController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterTemplateRevisionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterTemplateRevisionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.InformerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateRevisionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterTemplateRevisionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterTemplateRevisionControllerMock) Lister() v31.ClusterTemplateRevisionLister { + if mock.ListerFunc == nil { + panic("ClusterTemplateRevisionControllerMock.ListerFunc: method is nil but ClusterTemplateRevisionController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterTemplateRevisionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterTemplateRevisionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterTemplateRevisionController.ListerCalls()) +func (mock *ClusterTemplateRevisionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateRevisionControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterTemplateRevisionControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddHandler sync.RWMutex + lockClusterTemplateRevisionInterfaceMockAddLifecycle sync.RWMutex + lockClusterTemplateRevisionInterfaceMockController sync.RWMutex + lockClusterTemplateRevisionInterfaceMockCreate sync.RWMutex + lockClusterTemplateRevisionInterfaceMockDelete sync.RWMutex + lockClusterTemplateRevisionInterfaceMockDeleteCollection sync.RWMutex + lockClusterTemplateRevisionInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterTemplateRevisionInterfaceMockGet sync.RWMutex + lockClusterTemplateRevisionInterfaceMockGetNamespaced sync.RWMutex + lockClusterTemplateRevisionInterfaceMockList sync.RWMutex + lockClusterTemplateRevisionInterfaceMockListNamespaced sync.RWMutex + lockClusterTemplateRevisionInterfaceMockObjectClient sync.RWMutex + lockClusterTemplateRevisionInterfaceMockUpdate sync.RWMutex + lockClusterTemplateRevisionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterTemplateRevisionInterfaceMock does implement v31.ClusterTemplateRevisionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateRevisionInterface = &ClusterTemplateRevisionInterfaceMock{} + +// ClusterTemplateRevisionInterfaceMock is a mock implementation of v31.ClusterTemplateRevisionInterface. +// +// func TestSomethingThatUsesClusterTemplateRevisionInterface(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateRevisionInterface +// mockedClusterTemplateRevisionInterface := &ClusterTemplateRevisionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ClusterTemplateRevisionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterTemplateRevisionInterface in code that requires v31.ClusterTemplateRevisionInterface +// // and then make assertions. +// +// } +type ClusterTemplateRevisionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ClusterTemplateRevisionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterTemplateRevisionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ClusterTemplateRevisionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateRevisionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ClusterTemplateRevisionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterTemplateRevision + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ClusterTemplateRevision + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterTemplateRevisionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterTemplateRevisionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterTemplateRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterTemplateRevisionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterTemplateRevisionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterTemplateRevisionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ClusterTemplateRevisionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterTemplateRevisionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterTemplateRevisionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + lockClusterTemplateRevisionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterTemplateRevisionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterTemplateRevisionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateRevisionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterTemplateRevisionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddFeatureHandlerCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterTemplateRevisionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterTemplateRevisionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterTemplateRevisionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterTemplateRevisionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + lockClusterTemplateRevisionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterTemplateRevisionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ClusterTemplateRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddHandlerFunc: method is nil but ClusterTemplateRevisionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterTemplateRevisionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterTemplateRevisionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddHandlerCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ClusterTemplateRevisionHandlerFunc + } + lockClusterTemplateRevisionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterTemplateRevisionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ClusterTemplateRevisionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.AddLifecycleFunc: method is nil but ClusterTemplateRevisionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterTemplateRevisionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterTemplateRevisionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.AddLifecycleCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ClusterTemplateRevisionLifecycle + } + lockClusterTemplateRevisionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterTemplateRevisionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Controller() v31.ClusterTemplateRevisionController { + if mock.ControllerFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.ControllerFunc: method is nil but ClusterTemplateRevisionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterTemplateRevisionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterTemplateRevisionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.ControllerCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateRevisionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterTemplateRevisionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Create(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + if mock.CreateFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.CreateFunc: method is nil but ClusterTemplateRevisionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ClusterTemplateRevision + }{ + In1: in1, + } + lockClusterTemplateRevisionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterTemplateRevisionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.CreateCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) CreateCalls() []struct { + In1 *v3.ClusterTemplateRevision +} { + var calls []struct { + In1 *v3.ClusterTemplateRevision + } + lockClusterTemplateRevisionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterTemplateRevisionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.DeleteFunc: method is nil but ClusterTemplateRevisionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterTemplateRevisionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterTemplateRevisionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.DeleteCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterTemplateRevisionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterTemplateRevisionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.DeleteCollectionFunc: method is nil but ClusterTemplateRevisionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterTemplateRevisionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterTemplateRevisionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.DeleteCollectionCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterTemplateRevisionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterTemplateRevisionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterTemplateRevisionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterTemplateRevisionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterTemplateRevisionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.DeleteNamespacedCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterTemplateRevisionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterTemplateRevisionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { + if mock.GetFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.GetFunc: method is nil but ClusterTemplateRevisionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterTemplateRevisionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterTemplateRevisionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.GetCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterTemplateRevisionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterTemplateRevisionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.GetNamespacedFunc: method is nil but ClusterTemplateRevisionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterTemplateRevisionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterTemplateRevisionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.GetNamespacedCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterTemplateRevisionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterTemplateRevisionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) List(opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { + if mock.ListFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.ListFunc: method is nil but ClusterTemplateRevisionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterTemplateRevisionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterTemplateRevisionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.ListCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterTemplateRevisionInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterTemplateRevisionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.ListNamespacedFunc: method is nil but ClusterTemplateRevisionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterTemplateRevisionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterTemplateRevisionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.ListNamespacedCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterTemplateRevisionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterTemplateRevisionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.ObjectClientFunc: method is nil but ClusterTemplateRevisionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterTemplateRevisionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterTemplateRevisionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.ObjectClientCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterTemplateRevisionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterTemplateRevisionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Update(in1 *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + if mock.UpdateFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.UpdateFunc: method is nil but ClusterTemplateRevisionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ClusterTemplateRevision + }{ + In1: in1, + } + lockClusterTemplateRevisionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterTemplateRevisionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.UpdateCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) UpdateCalls() []struct { + In1 *v3.ClusterTemplateRevision +} { + var calls []struct { + In1 *v3.ClusterTemplateRevision + } + lockClusterTemplateRevisionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterTemplateRevisionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterTemplateRevisionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterTemplateRevisionInterfaceMock.WatchFunc: method is nil but ClusterTemplateRevisionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterTemplateRevisionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterTemplateRevisionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterTemplateRevisionInterface.WatchCalls()) +func (mock *ClusterTemplateRevisionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterTemplateRevisionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterTemplateRevisionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterTemplateRevisionsGetterMockClusterTemplateRevisions sync.RWMutex +) + +// Ensure, that ClusterTemplateRevisionsGetterMock does implement v31.ClusterTemplateRevisionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ClusterTemplateRevisionsGetter = &ClusterTemplateRevisionsGetterMock{} + +// ClusterTemplateRevisionsGetterMock is a mock implementation of v31.ClusterTemplateRevisionsGetter. +// +// func TestSomethingThatUsesClusterTemplateRevisionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ClusterTemplateRevisionsGetter +// mockedClusterTemplateRevisionsGetter := &ClusterTemplateRevisionsGetterMock{ +// ClusterTemplateRevisionsFunc: func(namespace string) v31.ClusterTemplateRevisionInterface { +// panic("mock out the ClusterTemplateRevisions method") +// }, +// } +// +// // use mockedClusterTemplateRevisionsGetter in code that requires v31.ClusterTemplateRevisionsGetter +// // and then make assertions. +// +// } +type ClusterTemplateRevisionsGetterMock struct { + // ClusterTemplateRevisionsFunc mocks the ClusterTemplateRevisions method. + ClusterTemplateRevisionsFunc func(namespace string) v31.ClusterTemplateRevisionInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterTemplateRevisions holds details about calls to the ClusterTemplateRevisions method. + ClusterTemplateRevisions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterTemplateRevisions calls ClusterTemplateRevisionsFunc. +func (mock *ClusterTemplateRevisionsGetterMock) ClusterTemplateRevisions(namespace string) v31.ClusterTemplateRevisionInterface { + if mock.ClusterTemplateRevisionsFunc == nil { + panic("ClusterTemplateRevisionsGetterMock.ClusterTemplateRevisionsFunc: method is nil but ClusterTemplateRevisionsGetter.ClusterTemplateRevisions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterTemplateRevisionsGetterMockClusterTemplateRevisions.Lock() + mock.calls.ClusterTemplateRevisions = append(mock.calls.ClusterTemplateRevisions, callInfo) + lockClusterTemplateRevisionsGetterMockClusterTemplateRevisions.Unlock() + return mock.ClusterTemplateRevisionsFunc(namespace) +} + +// ClusterTemplateRevisionsCalls gets all the calls that were made to ClusterTemplateRevisions. +// Check the length with: +// +// len(mockedClusterTemplateRevisionsGetter.ClusterTemplateRevisionsCalls()) +func (mock *ClusterTemplateRevisionsGetterMock) ClusterTemplateRevisionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterTemplateRevisionsGetterMockClusterTemplateRevisions.RLock() + calls = mock.calls.ClusterTemplateRevisions + lockClusterTemplateRevisionsGetterMockClusterTemplateRevisions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_compose_config_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_compose_config_mock.go new file mode 100644 index 0000000..f25c198 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_compose_config_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockComposeConfigListerMockGet sync.RWMutex + lockComposeConfigListerMockList sync.RWMutex +) + +// Ensure, that ComposeConfigListerMock does implement v31.ComposeConfigLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ComposeConfigLister = &ComposeConfigListerMock{} + +// ComposeConfigListerMock is a mock implementation of v31.ComposeConfigLister. +// +// func TestSomethingThatUsesComposeConfigLister(t *testing.T) { +// +// // make and configure a mocked v31.ComposeConfigLister +// mockedComposeConfigLister := &ComposeConfigListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ComposeConfig, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ComposeConfig, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedComposeConfigLister in code that requires v31.ComposeConfigLister +// // and then make assertions. +// +// } +type ComposeConfigListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ComposeConfig, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ComposeConfig, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ComposeConfigListerMock) Get(namespace string, name string) (*v3.ComposeConfig, error) { + if mock.GetFunc == nil { + panic("ComposeConfigListerMock.GetFunc: method is nil but ComposeConfigLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockComposeConfigListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockComposeConfigListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedComposeConfigLister.GetCalls()) +func (mock *ComposeConfigListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockComposeConfigListerMockGet.RLock() + calls = mock.calls.Get + lockComposeConfigListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ComposeConfigListerMock) List(namespace string, selector labels.Selector) ([]*v3.ComposeConfig, error) { + if mock.ListFunc == nil { + panic("ComposeConfigListerMock.ListFunc: method is nil but ComposeConfigLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockComposeConfigListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockComposeConfigListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedComposeConfigLister.ListCalls()) +func (mock *ComposeConfigListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockComposeConfigListerMockList.RLock() + calls = mock.calls.List + lockComposeConfigListerMockList.RUnlock() + return calls +} + +var ( + lockComposeConfigControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockComposeConfigControllerMockAddClusterScopedHandler sync.RWMutex + lockComposeConfigControllerMockAddFeatureHandler sync.RWMutex + lockComposeConfigControllerMockAddHandler sync.RWMutex + lockComposeConfigControllerMockEnqueue sync.RWMutex + lockComposeConfigControllerMockEnqueueAfter sync.RWMutex + lockComposeConfigControllerMockGeneric sync.RWMutex + lockComposeConfigControllerMockInformer sync.RWMutex + lockComposeConfigControllerMockLister sync.RWMutex +) + +// Ensure, that ComposeConfigControllerMock does implement v31.ComposeConfigController. +// If this is not the case, regenerate this file with moq. +var _ v31.ComposeConfigController = &ComposeConfigControllerMock{} + +// ComposeConfigControllerMock is a mock implementation of v31.ComposeConfigController. +// +// func TestSomethingThatUsesComposeConfigController(t *testing.T) { +// +// // make and configure a mocked v31.ComposeConfigController +// mockedComposeConfigController := &ComposeConfigControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ComposeConfigLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedComposeConfigController in code that requires v31.ComposeConfigController +// // and then make assertions. +// +// } +type ComposeConfigControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ComposeConfigHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ComposeConfigLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ComposeConfigHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ComposeConfigHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ComposeConfigHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ComposeConfigHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ComposeConfigControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ComposeConfigControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ComposeConfigController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockComposeConfigControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockComposeConfigControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedComposeConfigController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ComposeConfigControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc + } + lockComposeConfigControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockComposeConfigControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ComposeConfigControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ComposeConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ComposeConfigControllerMock.AddClusterScopedHandlerFunc: method is nil but ComposeConfigController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockComposeConfigControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockComposeConfigControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedComposeConfigController.AddClusterScopedHandlerCalls()) +func (mock *ComposeConfigControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ComposeConfigHandlerFunc + } + lockComposeConfigControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockComposeConfigControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ComposeConfigControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ComposeConfigControllerMock.AddFeatureHandlerFunc: method is nil but ComposeConfigController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockComposeConfigControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockComposeConfigControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedComposeConfigController.AddFeatureHandlerCalls()) +func (mock *ComposeConfigControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc + } + lockComposeConfigControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockComposeConfigControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ComposeConfigControllerMock) AddHandler(ctx context.Context, name string, handler v31.ComposeConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ComposeConfigControllerMock.AddHandlerFunc: method is nil but ComposeConfigController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockComposeConfigControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockComposeConfigControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedComposeConfigController.AddHandlerCalls()) +func (mock *ComposeConfigControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ComposeConfigHandlerFunc + } + lockComposeConfigControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockComposeConfigControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ComposeConfigControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ComposeConfigControllerMock.EnqueueFunc: method is nil but ComposeConfigController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockComposeConfigControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockComposeConfigControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedComposeConfigController.EnqueueCalls()) +func (mock *ComposeConfigControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockComposeConfigControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockComposeConfigControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ComposeConfigControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ComposeConfigControllerMock.EnqueueAfterFunc: method is nil but ComposeConfigController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockComposeConfigControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockComposeConfigControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedComposeConfigController.EnqueueAfterCalls()) +func (mock *ComposeConfigControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockComposeConfigControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockComposeConfigControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ComposeConfigControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ComposeConfigControllerMock.GenericFunc: method is nil but ComposeConfigController.Generic was just called") + } + callInfo := struct { + }{} + lockComposeConfigControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockComposeConfigControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedComposeConfigController.GenericCalls()) +func (mock *ComposeConfigControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockComposeConfigControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockComposeConfigControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ComposeConfigControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ComposeConfigControllerMock.InformerFunc: method is nil but ComposeConfigController.Informer was just called") + } + callInfo := struct { + }{} + lockComposeConfigControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockComposeConfigControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedComposeConfigController.InformerCalls()) +func (mock *ComposeConfigControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockComposeConfigControllerMockInformer.RLock() + calls = mock.calls.Informer + lockComposeConfigControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ComposeConfigControllerMock) Lister() v31.ComposeConfigLister { + if mock.ListerFunc == nil { + panic("ComposeConfigControllerMock.ListerFunc: method is nil but ComposeConfigController.Lister was just called") + } + callInfo := struct { + }{} + lockComposeConfigControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockComposeConfigControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedComposeConfigController.ListerCalls()) +func (mock *ComposeConfigControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockComposeConfigControllerMockLister.RLock() + calls = mock.calls.Lister + lockComposeConfigControllerMockLister.RUnlock() + return calls +} + +var ( + lockComposeConfigInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockComposeConfigInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockComposeConfigInterfaceMockAddClusterScopedHandler sync.RWMutex + lockComposeConfigInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockComposeConfigInterfaceMockAddFeatureHandler sync.RWMutex + lockComposeConfigInterfaceMockAddFeatureLifecycle sync.RWMutex + lockComposeConfigInterfaceMockAddHandler sync.RWMutex + lockComposeConfigInterfaceMockAddLifecycle sync.RWMutex + lockComposeConfigInterfaceMockController sync.RWMutex + lockComposeConfigInterfaceMockCreate sync.RWMutex + lockComposeConfigInterfaceMockDelete sync.RWMutex + lockComposeConfigInterfaceMockDeleteCollection sync.RWMutex + lockComposeConfigInterfaceMockDeleteNamespaced sync.RWMutex + lockComposeConfigInterfaceMockGet sync.RWMutex + lockComposeConfigInterfaceMockGetNamespaced sync.RWMutex + lockComposeConfigInterfaceMockList sync.RWMutex + lockComposeConfigInterfaceMockListNamespaced sync.RWMutex + lockComposeConfigInterfaceMockObjectClient sync.RWMutex + lockComposeConfigInterfaceMockUpdate sync.RWMutex + lockComposeConfigInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ComposeConfigInterfaceMock does implement v31.ComposeConfigInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ComposeConfigInterface = &ComposeConfigInterfaceMock{} + +// ComposeConfigInterfaceMock is a mock implementation of v31.ComposeConfigInterface. +// +// func TestSomethingThatUsesComposeConfigInterface(t *testing.T) { +// +// // make and configure a mocked v31.ComposeConfigInterface +// mockedComposeConfigInterface := &ComposeConfigInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ComposeConfigLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ComposeConfigLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ComposeConfigController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ComposeConfigList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ComposeConfigList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedComposeConfigInterface in code that requires v31.ComposeConfigInterface +// // and then make assertions. +// +// } +type ComposeConfigInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ComposeConfigLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ComposeConfigHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ComposeConfigLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ComposeConfigController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ComposeConfigList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ComposeConfigList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ComposeConfigHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ComposeConfigLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ComposeConfigHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ComposeConfigLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ComposeConfigHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ComposeConfigLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ComposeConfigHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ComposeConfigLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ComposeConfig + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ComposeConfig + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ComposeConfigInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ComposeConfigInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ComposeConfigInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockComposeConfigInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockComposeConfigInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ComposeConfigInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc + } + lockComposeConfigInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockComposeConfigInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ComposeConfigInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ComposeConfigInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ComposeConfigInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockComposeConfigInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockComposeConfigInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ComposeConfigInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle + } + lockComposeConfigInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockComposeConfigInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ComposeConfigInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ComposeConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ComposeConfigInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ComposeConfigInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockComposeConfigInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockComposeConfigInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddClusterScopedHandlerCalls()) +func (mock *ComposeConfigInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ComposeConfigHandlerFunc + } + lockComposeConfigInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockComposeConfigInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ComposeConfigInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ComposeConfigLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ComposeConfigInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ComposeConfigInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockComposeConfigInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockComposeConfigInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddClusterScopedLifecycleCalls()) +func (mock *ComposeConfigInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ComposeConfigLifecycle + } + lockComposeConfigInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockComposeConfigInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ComposeConfigInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ComposeConfigInterfaceMock.AddFeatureHandlerFunc: method is nil but ComposeConfigInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockComposeConfigInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockComposeConfigInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddFeatureHandlerCalls()) +func (mock *ComposeConfigInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ComposeConfigHandlerFunc + } + lockComposeConfigInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockComposeConfigInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ComposeConfigInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ComposeConfigLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ComposeConfigInterfaceMock.AddFeatureLifecycleFunc: method is nil but ComposeConfigInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ComposeConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockComposeConfigInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockComposeConfigInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddFeatureLifecycleCalls()) +func (mock *ComposeConfigInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ComposeConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ComposeConfigLifecycle + } + lockComposeConfigInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockComposeConfigInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ComposeConfigInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ComposeConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ComposeConfigInterfaceMock.AddHandlerFunc: method is nil but ComposeConfigInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ComposeConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockComposeConfigInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockComposeConfigInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddHandlerCalls()) +func (mock *ComposeConfigInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ComposeConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ComposeConfigHandlerFunc + } + lockComposeConfigInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockComposeConfigInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ComposeConfigInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ComposeConfigLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ComposeConfigInterfaceMock.AddLifecycleFunc: method is nil but ComposeConfigInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ComposeConfigLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockComposeConfigInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockComposeConfigInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedComposeConfigInterface.AddLifecycleCalls()) +func (mock *ComposeConfigInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ComposeConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ComposeConfigLifecycle + } + lockComposeConfigInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockComposeConfigInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ComposeConfigInterfaceMock) Controller() v31.ComposeConfigController { + if mock.ControllerFunc == nil { + panic("ComposeConfigInterfaceMock.ControllerFunc: method is nil but ComposeConfigInterface.Controller was just called") + } + callInfo := struct { + }{} + lockComposeConfigInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockComposeConfigInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedComposeConfigInterface.ControllerCalls()) +func (mock *ComposeConfigInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockComposeConfigInterfaceMockController.RLock() + calls = mock.calls.Controller + lockComposeConfigInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ComposeConfigInterfaceMock) Create(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) { + if mock.CreateFunc == nil { + panic("ComposeConfigInterfaceMock.CreateFunc: method is nil but ComposeConfigInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ComposeConfig + }{ + In1: in1, + } + lockComposeConfigInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockComposeConfigInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedComposeConfigInterface.CreateCalls()) +func (mock *ComposeConfigInterfaceMock) CreateCalls() []struct { + In1 *v3.ComposeConfig +} { + var calls []struct { + In1 *v3.ComposeConfig + } + lockComposeConfigInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockComposeConfigInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ComposeConfigInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ComposeConfigInterfaceMock.DeleteFunc: method is nil but ComposeConfigInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockComposeConfigInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockComposeConfigInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedComposeConfigInterface.DeleteCalls()) +func (mock *ComposeConfigInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockComposeConfigInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockComposeConfigInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ComposeConfigInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ComposeConfigInterfaceMock.DeleteCollectionFunc: method is nil but ComposeConfigInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockComposeConfigInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockComposeConfigInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedComposeConfigInterface.DeleteCollectionCalls()) +func (mock *ComposeConfigInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockComposeConfigInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockComposeConfigInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ComposeConfigInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ComposeConfigInterfaceMock.DeleteNamespacedFunc: method is nil but ComposeConfigInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockComposeConfigInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockComposeConfigInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedComposeConfigInterface.DeleteNamespacedCalls()) +func (mock *ComposeConfigInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockComposeConfigInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockComposeConfigInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ComposeConfigInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { + if mock.GetFunc == nil { + panic("ComposeConfigInterfaceMock.GetFunc: method is nil but ComposeConfigInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockComposeConfigInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockComposeConfigInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedComposeConfigInterface.GetCalls()) +func (mock *ComposeConfigInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockComposeConfigInterfaceMockGet.RLock() + calls = mock.calls.Get + lockComposeConfigInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ComposeConfigInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { + if mock.GetNamespacedFunc == nil { + panic("ComposeConfigInterfaceMock.GetNamespacedFunc: method is nil but ComposeConfigInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockComposeConfigInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockComposeConfigInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedComposeConfigInterface.GetNamespacedCalls()) +func (mock *ComposeConfigInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockComposeConfigInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockComposeConfigInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ComposeConfigInterfaceMock) List(opts metav1.ListOptions) (*v3.ComposeConfigList, error) { + if mock.ListFunc == nil { + panic("ComposeConfigInterfaceMock.ListFunc: method is nil but ComposeConfigInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockComposeConfigInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockComposeConfigInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedComposeConfigInterface.ListCalls()) +func (mock *ComposeConfigInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockComposeConfigInterfaceMockList.RLock() + calls = mock.calls.List + lockComposeConfigInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ComposeConfigInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ComposeConfigList, error) { + if mock.ListNamespacedFunc == nil { + panic("ComposeConfigInterfaceMock.ListNamespacedFunc: method is nil but ComposeConfigInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockComposeConfigInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockComposeConfigInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedComposeConfigInterface.ListNamespacedCalls()) +func (mock *ComposeConfigInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockComposeConfigInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockComposeConfigInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ComposeConfigInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ComposeConfigInterfaceMock.ObjectClientFunc: method is nil but ComposeConfigInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockComposeConfigInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockComposeConfigInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedComposeConfigInterface.ObjectClientCalls()) +func (mock *ComposeConfigInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockComposeConfigInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockComposeConfigInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ComposeConfigInterfaceMock) Update(in1 *v3.ComposeConfig) (*v3.ComposeConfig, error) { + if mock.UpdateFunc == nil { + panic("ComposeConfigInterfaceMock.UpdateFunc: method is nil but ComposeConfigInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ComposeConfig + }{ + In1: in1, + } + lockComposeConfigInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockComposeConfigInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedComposeConfigInterface.UpdateCalls()) +func (mock *ComposeConfigInterfaceMock) UpdateCalls() []struct { + In1 *v3.ComposeConfig +} { + var calls []struct { + In1 *v3.ComposeConfig + } + lockComposeConfigInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockComposeConfigInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ComposeConfigInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ComposeConfigInterfaceMock.WatchFunc: method is nil but ComposeConfigInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockComposeConfigInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockComposeConfigInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedComposeConfigInterface.WatchCalls()) +func (mock *ComposeConfigInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockComposeConfigInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockComposeConfigInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockComposeConfigsGetterMockComposeConfigs sync.RWMutex +) + +// Ensure, that ComposeConfigsGetterMock does implement v31.ComposeConfigsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ComposeConfigsGetter = &ComposeConfigsGetterMock{} + +// ComposeConfigsGetterMock is a mock implementation of v31.ComposeConfigsGetter. +// +// func TestSomethingThatUsesComposeConfigsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ComposeConfigsGetter +// mockedComposeConfigsGetter := &ComposeConfigsGetterMock{ +// ComposeConfigsFunc: func(namespace string) v31.ComposeConfigInterface { +// panic("mock out the ComposeConfigs method") +// }, +// } +// +// // use mockedComposeConfigsGetter in code that requires v31.ComposeConfigsGetter +// // and then make assertions. +// +// } +type ComposeConfigsGetterMock struct { + // ComposeConfigsFunc mocks the ComposeConfigs method. + ComposeConfigsFunc func(namespace string) v31.ComposeConfigInterface + + // calls tracks calls to the methods. + calls struct { + // ComposeConfigs holds details about calls to the ComposeConfigs method. + ComposeConfigs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ComposeConfigs calls ComposeConfigsFunc. +func (mock *ComposeConfigsGetterMock) ComposeConfigs(namespace string) v31.ComposeConfigInterface { + if mock.ComposeConfigsFunc == nil { + panic("ComposeConfigsGetterMock.ComposeConfigsFunc: method is nil but ComposeConfigsGetter.ComposeConfigs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockComposeConfigsGetterMockComposeConfigs.Lock() + mock.calls.ComposeConfigs = append(mock.calls.ComposeConfigs, callInfo) + lockComposeConfigsGetterMockComposeConfigs.Unlock() + return mock.ComposeConfigsFunc(namespace) +} + +// ComposeConfigsCalls gets all the calls that were made to ComposeConfigs. +// Check the length with: +// +// len(mockedComposeConfigsGetter.ComposeConfigsCalls()) +func (mock *ComposeConfigsGetterMock) ComposeConfigsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockComposeConfigsGetterMockComposeConfigs.RLock() + calls = mock.calls.ComposeConfigs + lockComposeConfigsGetterMockComposeConfigs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_dynamic_schema_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_dynamic_schema_mock.go new file mode 100644 index 0000000..878837d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_dynamic_schema_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockDynamicSchemaListerMockGet sync.RWMutex + lockDynamicSchemaListerMockList sync.RWMutex +) + +// Ensure, that DynamicSchemaListerMock does implement v31.DynamicSchemaLister. +// If this is not the case, regenerate this file with moq. +var _ v31.DynamicSchemaLister = &DynamicSchemaListerMock{} + +// DynamicSchemaListerMock is a mock implementation of v31.DynamicSchemaLister. +// +// func TestSomethingThatUsesDynamicSchemaLister(t *testing.T) { +// +// // make and configure a mocked v31.DynamicSchemaLister +// mockedDynamicSchemaLister := &DynamicSchemaListerMock{ +// GetFunc: func(namespace string, name string) (*v3.DynamicSchema, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.DynamicSchema, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedDynamicSchemaLister in code that requires v31.DynamicSchemaLister +// // and then make assertions. +// +// } +type DynamicSchemaListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.DynamicSchema, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.DynamicSchema, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *DynamicSchemaListerMock) Get(namespace string, name string) (*v3.DynamicSchema, error) { + if mock.GetFunc == nil { + panic("DynamicSchemaListerMock.GetFunc: method is nil but DynamicSchemaLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDynamicSchemaListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDynamicSchemaListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDynamicSchemaLister.GetCalls()) +func (mock *DynamicSchemaListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDynamicSchemaListerMockGet.RLock() + calls = mock.calls.Get + lockDynamicSchemaListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DynamicSchemaListerMock) List(namespace string, selector labels.Selector) ([]*v3.DynamicSchema, error) { + if mock.ListFunc == nil { + panic("DynamicSchemaListerMock.ListFunc: method is nil but DynamicSchemaLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockDynamicSchemaListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDynamicSchemaListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDynamicSchemaLister.ListCalls()) +func (mock *DynamicSchemaListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockDynamicSchemaListerMockList.RLock() + calls = mock.calls.List + lockDynamicSchemaListerMockList.RUnlock() + return calls +} + +var ( + lockDynamicSchemaControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockDynamicSchemaControllerMockAddClusterScopedHandler sync.RWMutex + lockDynamicSchemaControllerMockAddFeatureHandler sync.RWMutex + lockDynamicSchemaControllerMockAddHandler sync.RWMutex + lockDynamicSchemaControllerMockEnqueue sync.RWMutex + lockDynamicSchemaControllerMockEnqueueAfter sync.RWMutex + lockDynamicSchemaControllerMockGeneric sync.RWMutex + lockDynamicSchemaControllerMockInformer sync.RWMutex + lockDynamicSchemaControllerMockLister sync.RWMutex +) + +// Ensure, that DynamicSchemaControllerMock does implement v31.DynamicSchemaController. +// If this is not the case, regenerate this file with moq. +var _ v31.DynamicSchemaController = &DynamicSchemaControllerMock{} + +// DynamicSchemaControllerMock is a mock implementation of v31.DynamicSchemaController. +// +// func TestSomethingThatUsesDynamicSchemaController(t *testing.T) { +// +// // make and configure a mocked v31.DynamicSchemaController +// mockedDynamicSchemaController := &DynamicSchemaControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.DynamicSchemaLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedDynamicSchemaController in code that requires v31.DynamicSchemaController +// // and then make assertions. +// +// } +type DynamicSchemaControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.DynamicSchemaHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.DynamicSchemaLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.DynamicSchemaHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.DynamicSchemaHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DynamicSchemaHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.DynamicSchemaHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DynamicSchemaControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DynamicSchemaControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but DynamicSchemaController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDynamicSchemaControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDynamicSchemaControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDynamicSchemaController.AddClusterScopedFeatureHandlerCalls()) +func (mock *DynamicSchemaControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDynamicSchemaControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DynamicSchemaControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.DynamicSchemaHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DynamicSchemaControllerMock.AddClusterScopedHandlerFunc: method is nil but DynamicSchemaController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDynamicSchemaControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDynamicSchemaControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDynamicSchemaController.AddClusterScopedHandlerCalls()) +func (mock *DynamicSchemaControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDynamicSchemaControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DynamicSchemaControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DynamicSchemaControllerMock.AddFeatureHandlerFunc: method is nil but DynamicSchemaController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDynamicSchemaControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDynamicSchemaControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDynamicSchemaController.AddFeatureHandlerCalls()) +func (mock *DynamicSchemaControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDynamicSchemaControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DynamicSchemaControllerMock) AddHandler(ctx context.Context, name string, handler v31.DynamicSchemaHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DynamicSchemaControllerMock.AddHandlerFunc: method is nil but DynamicSchemaController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockDynamicSchemaControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDynamicSchemaControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDynamicSchemaController.AddHandlerCalls()) +func (mock *DynamicSchemaControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDynamicSchemaControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *DynamicSchemaControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("DynamicSchemaControllerMock.EnqueueFunc: method is nil but DynamicSchemaController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDynamicSchemaControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockDynamicSchemaControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedDynamicSchemaController.EnqueueCalls()) +func (mock *DynamicSchemaControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDynamicSchemaControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockDynamicSchemaControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *DynamicSchemaControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("DynamicSchemaControllerMock.EnqueueAfterFunc: method is nil but DynamicSchemaController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockDynamicSchemaControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockDynamicSchemaControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedDynamicSchemaController.EnqueueAfterCalls()) +func (mock *DynamicSchemaControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockDynamicSchemaControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockDynamicSchemaControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *DynamicSchemaControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("DynamicSchemaControllerMock.GenericFunc: method is nil but DynamicSchemaController.Generic was just called") + } + callInfo := struct { + }{} + lockDynamicSchemaControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockDynamicSchemaControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedDynamicSchemaController.GenericCalls()) +func (mock *DynamicSchemaControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockDynamicSchemaControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockDynamicSchemaControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *DynamicSchemaControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("DynamicSchemaControllerMock.InformerFunc: method is nil but DynamicSchemaController.Informer was just called") + } + callInfo := struct { + }{} + lockDynamicSchemaControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockDynamicSchemaControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedDynamicSchemaController.InformerCalls()) +func (mock *DynamicSchemaControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockDynamicSchemaControllerMockInformer.RLock() + calls = mock.calls.Informer + lockDynamicSchemaControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *DynamicSchemaControllerMock) Lister() v31.DynamicSchemaLister { + if mock.ListerFunc == nil { + panic("DynamicSchemaControllerMock.ListerFunc: method is nil but DynamicSchemaController.Lister was just called") + } + callInfo := struct { + }{} + lockDynamicSchemaControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockDynamicSchemaControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedDynamicSchemaController.ListerCalls()) +func (mock *DynamicSchemaControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockDynamicSchemaControllerMockLister.RLock() + calls = mock.calls.Lister + lockDynamicSchemaControllerMockLister.RUnlock() + return calls +} + +var ( + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockDynamicSchemaInterfaceMockAddClusterScopedHandler sync.RWMutex + lockDynamicSchemaInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockDynamicSchemaInterfaceMockAddFeatureHandler sync.RWMutex + lockDynamicSchemaInterfaceMockAddFeatureLifecycle sync.RWMutex + lockDynamicSchemaInterfaceMockAddHandler sync.RWMutex + lockDynamicSchemaInterfaceMockAddLifecycle sync.RWMutex + lockDynamicSchemaInterfaceMockController sync.RWMutex + lockDynamicSchemaInterfaceMockCreate sync.RWMutex + lockDynamicSchemaInterfaceMockDelete sync.RWMutex + lockDynamicSchemaInterfaceMockDeleteCollection sync.RWMutex + lockDynamicSchemaInterfaceMockDeleteNamespaced sync.RWMutex + lockDynamicSchemaInterfaceMockGet sync.RWMutex + lockDynamicSchemaInterfaceMockGetNamespaced sync.RWMutex + lockDynamicSchemaInterfaceMockList sync.RWMutex + lockDynamicSchemaInterfaceMockListNamespaced sync.RWMutex + lockDynamicSchemaInterfaceMockObjectClient sync.RWMutex + lockDynamicSchemaInterfaceMockUpdate sync.RWMutex + lockDynamicSchemaInterfaceMockWatch sync.RWMutex +) + +// Ensure, that DynamicSchemaInterfaceMock does implement v31.DynamicSchemaInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.DynamicSchemaInterface = &DynamicSchemaInterfaceMock{} + +// DynamicSchemaInterfaceMock is a mock implementation of v31.DynamicSchemaInterface. +// +// func TestSomethingThatUsesDynamicSchemaInterface(t *testing.T) { +// +// // make and configure a mocked v31.DynamicSchemaInterface +// mockedDynamicSchemaInterface := &DynamicSchemaInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.DynamicSchemaLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.DynamicSchemaLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.DynamicSchemaController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedDynamicSchemaInterface in code that requires v31.DynamicSchemaInterface +// // and then make assertions. +// +// } +type DynamicSchemaInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.DynamicSchemaLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.DynamicSchemaLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.DynamicSchemaController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.DynamicSchemaList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.DynamicSchemaList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.DynamicSchemaHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DynamicSchemaLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.DynamicSchemaHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DynamicSchemaLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DynamicSchemaHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DynamicSchemaLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DynamicSchemaHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DynamicSchemaLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.DynamicSchema + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.DynamicSchema + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DynamicSchemaInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but DynamicSchemaInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("DynamicSchemaInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but DynamicSchemaInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle + } + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockDynamicSchemaInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.DynamicSchemaHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DynamicSchemaInterfaceMock.AddClusterScopedHandlerFunc: method is nil but DynamicSchemaInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDynamicSchemaInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDynamicSchemaInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddClusterScopedHandlerCalls()) +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDynamicSchemaInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.DynamicSchemaLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("DynamicSchemaInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but DynamicSchemaInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDynamicSchemaInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockDynamicSchemaInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddClusterScopedLifecycleCalls()) +func (mock *DynamicSchemaInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DynamicSchemaLifecycle + } + lockDynamicSchemaInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockDynamicSchemaInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DynamicSchemaInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DynamicSchemaInterfaceMock.AddFeatureHandlerFunc: method is nil but DynamicSchemaInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDynamicSchemaInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDynamicSchemaInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddFeatureHandlerCalls()) +func (mock *DynamicSchemaInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDynamicSchemaInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *DynamicSchemaInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.DynamicSchemaLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("DynamicSchemaInterfaceMock.AddFeatureLifecycleFunc: method is nil but DynamicSchemaInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DynamicSchemaLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockDynamicSchemaInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockDynamicSchemaInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddFeatureLifecycleCalls()) +func (mock *DynamicSchemaInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DynamicSchemaLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DynamicSchemaLifecycle + } + lockDynamicSchemaInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockDynamicSchemaInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DynamicSchemaInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.DynamicSchemaHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DynamicSchemaInterfaceMock.AddHandlerFunc: method is nil but DynamicSchemaInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.DynamicSchemaHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockDynamicSchemaInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDynamicSchemaInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddHandlerCalls()) +func (mock *DynamicSchemaInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.DynamicSchemaHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.DynamicSchemaHandlerFunc + } + lockDynamicSchemaInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDynamicSchemaInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *DynamicSchemaInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.DynamicSchemaLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("DynamicSchemaInterfaceMock.AddLifecycleFunc: method is nil but DynamicSchemaInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.DynamicSchemaLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockDynamicSchemaInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockDynamicSchemaInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.AddLifecycleCalls()) +func (mock *DynamicSchemaInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.DynamicSchemaLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.DynamicSchemaLifecycle + } + lockDynamicSchemaInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockDynamicSchemaInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *DynamicSchemaInterfaceMock) Controller() v31.DynamicSchemaController { + if mock.ControllerFunc == nil { + panic("DynamicSchemaInterfaceMock.ControllerFunc: method is nil but DynamicSchemaInterface.Controller was just called") + } + callInfo := struct { + }{} + lockDynamicSchemaInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockDynamicSchemaInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.ControllerCalls()) +func (mock *DynamicSchemaInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockDynamicSchemaInterfaceMockController.RLock() + calls = mock.calls.Controller + lockDynamicSchemaInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *DynamicSchemaInterfaceMock) Create(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) { + if mock.CreateFunc == nil { + panic("DynamicSchemaInterfaceMock.CreateFunc: method is nil but DynamicSchemaInterface.Create was just called") + } + callInfo := struct { + In1 *v3.DynamicSchema + }{ + In1: in1, + } + lockDynamicSchemaInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockDynamicSchemaInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.CreateCalls()) +func (mock *DynamicSchemaInterfaceMock) CreateCalls() []struct { + In1 *v3.DynamicSchema +} { + var calls []struct { + In1 *v3.DynamicSchema + } + lockDynamicSchemaInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockDynamicSchemaInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *DynamicSchemaInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("DynamicSchemaInterfaceMock.DeleteFunc: method is nil but DynamicSchemaInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockDynamicSchemaInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockDynamicSchemaInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.DeleteCalls()) +func (mock *DynamicSchemaInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockDynamicSchemaInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockDynamicSchemaInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *DynamicSchemaInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("DynamicSchemaInterfaceMock.DeleteCollectionFunc: method is nil but DynamicSchemaInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockDynamicSchemaInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockDynamicSchemaInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.DeleteCollectionCalls()) +func (mock *DynamicSchemaInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockDynamicSchemaInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockDynamicSchemaInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *DynamicSchemaInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("DynamicSchemaInterfaceMock.DeleteNamespacedFunc: method is nil but DynamicSchemaInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockDynamicSchemaInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockDynamicSchemaInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.DeleteNamespacedCalls()) +func (mock *DynamicSchemaInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockDynamicSchemaInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockDynamicSchemaInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *DynamicSchemaInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { + if mock.GetFunc == nil { + panic("DynamicSchemaInterfaceMock.GetFunc: method is nil but DynamicSchemaInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockDynamicSchemaInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDynamicSchemaInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.GetCalls()) +func (mock *DynamicSchemaInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockDynamicSchemaInterfaceMockGet.RLock() + calls = mock.calls.Get + lockDynamicSchemaInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *DynamicSchemaInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { + if mock.GetNamespacedFunc == nil { + panic("DynamicSchemaInterfaceMock.GetNamespacedFunc: method is nil but DynamicSchemaInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockDynamicSchemaInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockDynamicSchemaInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.GetNamespacedCalls()) +func (mock *DynamicSchemaInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockDynamicSchemaInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockDynamicSchemaInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DynamicSchemaInterfaceMock) List(opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { + if mock.ListFunc == nil { + panic("DynamicSchemaInterfaceMock.ListFunc: method is nil but DynamicSchemaInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDynamicSchemaInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDynamicSchemaInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.ListCalls()) +func (mock *DynamicSchemaInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDynamicSchemaInterfaceMockList.RLock() + calls = mock.calls.List + lockDynamicSchemaInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *DynamicSchemaInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { + if mock.ListNamespacedFunc == nil { + panic("DynamicSchemaInterfaceMock.ListNamespacedFunc: method is nil but DynamicSchemaInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockDynamicSchemaInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockDynamicSchemaInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.ListNamespacedCalls()) +func (mock *DynamicSchemaInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockDynamicSchemaInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockDynamicSchemaInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *DynamicSchemaInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("DynamicSchemaInterfaceMock.ObjectClientFunc: method is nil but DynamicSchemaInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockDynamicSchemaInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockDynamicSchemaInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.ObjectClientCalls()) +func (mock *DynamicSchemaInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockDynamicSchemaInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockDynamicSchemaInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *DynamicSchemaInterfaceMock) Update(in1 *v3.DynamicSchema) (*v3.DynamicSchema, error) { + if mock.UpdateFunc == nil { + panic("DynamicSchemaInterfaceMock.UpdateFunc: method is nil but DynamicSchemaInterface.Update was just called") + } + callInfo := struct { + In1 *v3.DynamicSchema + }{ + In1: in1, + } + lockDynamicSchemaInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockDynamicSchemaInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.UpdateCalls()) +func (mock *DynamicSchemaInterfaceMock) UpdateCalls() []struct { + In1 *v3.DynamicSchema +} { + var calls []struct { + In1 *v3.DynamicSchema + } + lockDynamicSchemaInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockDynamicSchemaInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *DynamicSchemaInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("DynamicSchemaInterfaceMock.WatchFunc: method is nil but DynamicSchemaInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDynamicSchemaInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockDynamicSchemaInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedDynamicSchemaInterface.WatchCalls()) +func (mock *DynamicSchemaInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDynamicSchemaInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockDynamicSchemaInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockDynamicSchemasGetterMockDynamicSchemas sync.RWMutex +) + +// Ensure, that DynamicSchemasGetterMock does implement v31.DynamicSchemasGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.DynamicSchemasGetter = &DynamicSchemasGetterMock{} + +// DynamicSchemasGetterMock is a mock implementation of v31.DynamicSchemasGetter. +// +// func TestSomethingThatUsesDynamicSchemasGetter(t *testing.T) { +// +// // make and configure a mocked v31.DynamicSchemasGetter +// mockedDynamicSchemasGetter := &DynamicSchemasGetterMock{ +// DynamicSchemasFunc: func(namespace string) v31.DynamicSchemaInterface { +// panic("mock out the DynamicSchemas method") +// }, +// } +// +// // use mockedDynamicSchemasGetter in code that requires v31.DynamicSchemasGetter +// // and then make assertions. +// +// } +type DynamicSchemasGetterMock struct { + // DynamicSchemasFunc mocks the DynamicSchemas method. + DynamicSchemasFunc func(namespace string) v31.DynamicSchemaInterface + + // calls tracks calls to the methods. + calls struct { + // DynamicSchemas holds details about calls to the DynamicSchemas method. + DynamicSchemas []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// DynamicSchemas calls DynamicSchemasFunc. +func (mock *DynamicSchemasGetterMock) DynamicSchemas(namespace string) v31.DynamicSchemaInterface { + if mock.DynamicSchemasFunc == nil { + panic("DynamicSchemasGetterMock.DynamicSchemasFunc: method is nil but DynamicSchemasGetter.DynamicSchemas was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockDynamicSchemasGetterMockDynamicSchemas.Lock() + mock.calls.DynamicSchemas = append(mock.calls.DynamicSchemas, callInfo) + lockDynamicSchemasGetterMockDynamicSchemas.Unlock() + return mock.DynamicSchemasFunc(namespace) +} + +// DynamicSchemasCalls gets all the calls that were made to DynamicSchemas. +// Check the length with: +// +// len(mockedDynamicSchemasGetter.DynamicSchemasCalls()) +func (mock *DynamicSchemasGetterMock) DynamicSchemasCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockDynamicSchemasGetterMockDynamicSchemas.RLock() + calls = mock.calls.DynamicSchemas + lockDynamicSchemasGetterMockDynamicSchemas.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_etcd_backup_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_etcd_backup_mock.go new file mode 100644 index 0000000..75586dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_etcd_backup_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockEtcdBackupListerMockGet sync.RWMutex + lockEtcdBackupListerMockList sync.RWMutex +) + +// Ensure, that EtcdBackupListerMock does implement v31.EtcdBackupLister. +// If this is not the case, regenerate this file with moq. +var _ v31.EtcdBackupLister = &EtcdBackupListerMock{} + +// EtcdBackupListerMock is a mock implementation of v31.EtcdBackupLister. +// +// func TestSomethingThatUsesEtcdBackupLister(t *testing.T) { +// +// // make and configure a mocked v31.EtcdBackupLister +// mockedEtcdBackupLister := &EtcdBackupListerMock{ +// GetFunc: func(namespace string, name string) (*v3.EtcdBackup, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.EtcdBackup, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedEtcdBackupLister in code that requires v31.EtcdBackupLister +// // and then make assertions. +// +// } +type EtcdBackupListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.EtcdBackup, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.EtcdBackup, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *EtcdBackupListerMock) Get(namespace string, name string) (*v3.EtcdBackup, error) { + if mock.GetFunc == nil { + panic("EtcdBackupListerMock.GetFunc: method is nil but EtcdBackupLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEtcdBackupListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEtcdBackupListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEtcdBackupLister.GetCalls()) +func (mock *EtcdBackupListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEtcdBackupListerMockGet.RLock() + calls = mock.calls.Get + lockEtcdBackupListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EtcdBackupListerMock) List(namespace string, selector labels.Selector) ([]*v3.EtcdBackup, error) { + if mock.ListFunc == nil { + panic("EtcdBackupListerMock.ListFunc: method is nil but EtcdBackupLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockEtcdBackupListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEtcdBackupListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEtcdBackupLister.ListCalls()) +func (mock *EtcdBackupListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockEtcdBackupListerMockList.RLock() + calls = mock.calls.List + lockEtcdBackupListerMockList.RUnlock() + return calls +} + +var ( + lockEtcdBackupControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockEtcdBackupControllerMockAddClusterScopedHandler sync.RWMutex + lockEtcdBackupControllerMockAddFeatureHandler sync.RWMutex + lockEtcdBackupControllerMockAddHandler sync.RWMutex + lockEtcdBackupControllerMockEnqueue sync.RWMutex + lockEtcdBackupControllerMockEnqueueAfter sync.RWMutex + lockEtcdBackupControllerMockGeneric sync.RWMutex + lockEtcdBackupControllerMockInformer sync.RWMutex + lockEtcdBackupControllerMockLister sync.RWMutex +) + +// Ensure, that EtcdBackupControllerMock does implement v31.EtcdBackupController. +// If this is not the case, regenerate this file with moq. +var _ v31.EtcdBackupController = &EtcdBackupControllerMock{} + +// EtcdBackupControllerMock is a mock implementation of v31.EtcdBackupController. +// +// func TestSomethingThatUsesEtcdBackupController(t *testing.T) { +// +// // make and configure a mocked v31.EtcdBackupController +// mockedEtcdBackupController := &EtcdBackupControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.EtcdBackupLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedEtcdBackupController in code that requires v31.EtcdBackupController +// // and then make assertions. +// +// } +type EtcdBackupControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.EtcdBackupHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.EtcdBackupLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.EtcdBackupHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.EtcdBackupHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.EtcdBackupHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.EtcdBackupHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EtcdBackupControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EtcdBackupControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but EtcdBackupController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEtcdBackupControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEtcdBackupControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEtcdBackupController.AddClusterScopedFeatureHandlerCalls()) +func (mock *EtcdBackupControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc + } + lockEtcdBackupControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEtcdBackupControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EtcdBackupControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.EtcdBackupHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EtcdBackupControllerMock.AddClusterScopedHandlerFunc: method is nil but EtcdBackupController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockEtcdBackupControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEtcdBackupControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEtcdBackupController.AddClusterScopedHandlerCalls()) +func (mock *EtcdBackupControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.EtcdBackupHandlerFunc + } + lockEtcdBackupControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEtcdBackupControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EtcdBackupControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EtcdBackupControllerMock.AddFeatureHandlerFunc: method is nil but EtcdBackupController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEtcdBackupControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEtcdBackupControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEtcdBackupController.AddFeatureHandlerCalls()) +func (mock *EtcdBackupControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc + } + lockEtcdBackupControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEtcdBackupControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EtcdBackupControllerMock) AddHandler(ctx context.Context, name string, handler v31.EtcdBackupHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EtcdBackupControllerMock.AddHandlerFunc: method is nil but EtcdBackupController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockEtcdBackupControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEtcdBackupControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEtcdBackupController.AddHandlerCalls()) +func (mock *EtcdBackupControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.EtcdBackupHandlerFunc + } + lockEtcdBackupControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEtcdBackupControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *EtcdBackupControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("EtcdBackupControllerMock.EnqueueFunc: method is nil but EtcdBackupController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockEtcdBackupControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockEtcdBackupControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedEtcdBackupController.EnqueueCalls()) +func (mock *EtcdBackupControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockEtcdBackupControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockEtcdBackupControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *EtcdBackupControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("EtcdBackupControllerMock.EnqueueAfterFunc: method is nil but EtcdBackupController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockEtcdBackupControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockEtcdBackupControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedEtcdBackupController.EnqueueAfterCalls()) +func (mock *EtcdBackupControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockEtcdBackupControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockEtcdBackupControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *EtcdBackupControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("EtcdBackupControllerMock.GenericFunc: method is nil but EtcdBackupController.Generic was just called") + } + callInfo := struct { + }{} + lockEtcdBackupControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockEtcdBackupControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedEtcdBackupController.GenericCalls()) +func (mock *EtcdBackupControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockEtcdBackupControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockEtcdBackupControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *EtcdBackupControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("EtcdBackupControllerMock.InformerFunc: method is nil but EtcdBackupController.Informer was just called") + } + callInfo := struct { + }{} + lockEtcdBackupControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockEtcdBackupControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedEtcdBackupController.InformerCalls()) +func (mock *EtcdBackupControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockEtcdBackupControllerMockInformer.RLock() + calls = mock.calls.Informer + lockEtcdBackupControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *EtcdBackupControllerMock) Lister() v31.EtcdBackupLister { + if mock.ListerFunc == nil { + panic("EtcdBackupControllerMock.ListerFunc: method is nil but EtcdBackupController.Lister was just called") + } + callInfo := struct { + }{} + lockEtcdBackupControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockEtcdBackupControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedEtcdBackupController.ListerCalls()) +func (mock *EtcdBackupControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockEtcdBackupControllerMockLister.RLock() + calls = mock.calls.Lister + lockEtcdBackupControllerMockLister.RUnlock() + return calls +} + +var ( + lockEtcdBackupInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockEtcdBackupInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockEtcdBackupInterfaceMockAddClusterScopedHandler sync.RWMutex + lockEtcdBackupInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockEtcdBackupInterfaceMockAddFeatureHandler sync.RWMutex + lockEtcdBackupInterfaceMockAddFeatureLifecycle sync.RWMutex + lockEtcdBackupInterfaceMockAddHandler sync.RWMutex + lockEtcdBackupInterfaceMockAddLifecycle sync.RWMutex + lockEtcdBackupInterfaceMockController sync.RWMutex + lockEtcdBackupInterfaceMockCreate sync.RWMutex + lockEtcdBackupInterfaceMockDelete sync.RWMutex + lockEtcdBackupInterfaceMockDeleteCollection sync.RWMutex + lockEtcdBackupInterfaceMockDeleteNamespaced sync.RWMutex + lockEtcdBackupInterfaceMockGet sync.RWMutex + lockEtcdBackupInterfaceMockGetNamespaced sync.RWMutex + lockEtcdBackupInterfaceMockList sync.RWMutex + lockEtcdBackupInterfaceMockListNamespaced sync.RWMutex + lockEtcdBackupInterfaceMockObjectClient sync.RWMutex + lockEtcdBackupInterfaceMockUpdate sync.RWMutex + lockEtcdBackupInterfaceMockWatch sync.RWMutex +) + +// Ensure, that EtcdBackupInterfaceMock does implement v31.EtcdBackupInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.EtcdBackupInterface = &EtcdBackupInterfaceMock{} + +// EtcdBackupInterfaceMock is a mock implementation of v31.EtcdBackupInterface. +// +// func TestSomethingThatUsesEtcdBackupInterface(t *testing.T) { +// +// // make and configure a mocked v31.EtcdBackupInterface +// mockedEtcdBackupInterface := &EtcdBackupInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.EtcdBackupLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.EtcdBackupLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.EtcdBackupController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.EtcdBackupList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.EtcdBackupList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedEtcdBackupInterface in code that requires v31.EtcdBackupInterface +// // and then make assertions. +// +// } +type EtcdBackupInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.EtcdBackupLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.EtcdBackupHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.EtcdBackupLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.EtcdBackupController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.EtcdBackupList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.EtcdBackupList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.EtcdBackupHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.EtcdBackupLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.EtcdBackupHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.EtcdBackupLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.EtcdBackupHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.EtcdBackupLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.EtcdBackupHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.EtcdBackupLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.EtcdBackup + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.EtcdBackup + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *EtcdBackupInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("EtcdBackupInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but EtcdBackupInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEtcdBackupInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockEtcdBackupInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *EtcdBackupInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc + } + lockEtcdBackupInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockEtcdBackupInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *EtcdBackupInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("EtcdBackupInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but EtcdBackupInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEtcdBackupInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockEtcdBackupInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *EtcdBackupInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle + } + lockEtcdBackupInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockEtcdBackupInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *EtcdBackupInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.EtcdBackupHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("EtcdBackupInterfaceMock.AddClusterScopedHandlerFunc: method is nil but EtcdBackupInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockEtcdBackupInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockEtcdBackupInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddClusterScopedHandlerCalls()) +func (mock *EtcdBackupInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.EtcdBackupHandlerFunc + } + lockEtcdBackupInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockEtcdBackupInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *EtcdBackupInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.EtcdBackupLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("EtcdBackupInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but EtcdBackupInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockEtcdBackupInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockEtcdBackupInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddClusterScopedLifecycleCalls()) +func (mock *EtcdBackupInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.EtcdBackupLifecycle + } + lockEtcdBackupInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockEtcdBackupInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *EtcdBackupInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("EtcdBackupInterfaceMock.AddFeatureHandlerFunc: method is nil but EtcdBackupInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockEtcdBackupInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockEtcdBackupInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddFeatureHandlerCalls()) +func (mock *EtcdBackupInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.EtcdBackupHandlerFunc + } + lockEtcdBackupInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockEtcdBackupInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *EtcdBackupInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.EtcdBackupLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("EtcdBackupInterfaceMock.AddFeatureLifecycleFunc: method is nil but EtcdBackupInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.EtcdBackupLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockEtcdBackupInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockEtcdBackupInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddFeatureLifecycleCalls()) +func (mock *EtcdBackupInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.EtcdBackupLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.EtcdBackupLifecycle + } + lockEtcdBackupInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockEtcdBackupInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *EtcdBackupInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.EtcdBackupHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("EtcdBackupInterfaceMock.AddHandlerFunc: method is nil but EtcdBackupInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.EtcdBackupHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockEtcdBackupInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockEtcdBackupInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddHandlerCalls()) +func (mock *EtcdBackupInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.EtcdBackupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.EtcdBackupHandlerFunc + } + lockEtcdBackupInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockEtcdBackupInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *EtcdBackupInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.EtcdBackupLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("EtcdBackupInterfaceMock.AddLifecycleFunc: method is nil but EtcdBackupInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.EtcdBackupLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockEtcdBackupInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockEtcdBackupInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedEtcdBackupInterface.AddLifecycleCalls()) +func (mock *EtcdBackupInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.EtcdBackupLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.EtcdBackupLifecycle + } + lockEtcdBackupInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockEtcdBackupInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *EtcdBackupInterfaceMock) Controller() v31.EtcdBackupController { + if mock.ControllerFunc == nil { + panic("EtcdBackupInterfaceMock.ControllerFunc: method is nil but EtcdBackupInterface.Controller was just called") + } + callInfo := struct { + }{} + lockEtcdBackupInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockEtcdBackupInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedEtcdBackupInterface.ControllerCalls()) +func (mock *EtcdBackupInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockEtcdBackupInterfaceMockController.RLock() + calls = mock.calls.Controller + lockEtcdBackupInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *EtcdBackupInterfaceMock) Create(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) { + if mock.CreateFunc == nil { + panic("EtcdBackupInterfaceMock.CreateFunc: method is nil but EtcdBackupInterface.Create was just called") + } + callInfo := struct { + In1 *v3.EtcdBackup + }{ + In1: in1, + } + lockEtcdBackupInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockEtcdBackupInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedEtcdBackupInterface.CreateCalls()) +func (mock *EtcdBackupInterfaceMock) CreateCalls() []struct { + In1 *v3.EtcdBackup +} { + var calls []struct { + In1 *v3.EtcdBackup + } + lockEtcdBackupInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockEtcdBackupInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *EtcdBackupInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("EtcdBackupInterfaceMock.DeleteFunc: method is nil but EtcdBackupInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockEtcdBackupInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockEtcdBackupInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedEtcdBackupInterface.DeleteCalls()) +func (mock *EtcdBackupInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockEtcdBackupInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockEtcdBackupInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *EtcdBackupInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("EtcdBackupInterfaceMock.DeleteCollectionFunc: method is nil but EtcdBackupInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockEtcdBackupInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockEtcdBackupInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedEtcdBackupInterface.DeleteCollectionCalls()) +func (mock *EtcdBackupInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockEtcdBackupInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockEtcdBackupInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *EtcdBackupInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("EtcdBackupInterfaceMock.DeleteNamespacedFunc: method is nil but EtcdBackupInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockEtcdBackupInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockEtcdBackupInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedEtcdBackupInterface.DeleteNamespacedCalls()) +func (mock *EtcdBackupInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockEtcdBackupInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockEtcdBackupInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *EtcdBackupInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { + if mock.GetFunc == nil { + panic("EtcdBackupInterfaceMock.GetFunc: method is nil but EtcdBackupInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockEtcdBackupInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockEtcdBackupInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedEtcdBackupInterface.GetCalls()) +func (mock *EtcdBackupInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockEtcdBackupInterfaceMockGet.RLock() + calls = mock.calls.Get + lockEtcdBackupInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *EtcdBackupInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { + if mock.GetNamespacedFunc == nil { + panic("EtcdBackupInterfaceMock.GetNamespacedFunc: method is nil but EtcdBackupInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockEtcdBackupInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockEtcdBackupInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedEtcdBackupInterface.GetNamespacedCalls()) +func (mock *EtcdBackupInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockEtcdBackupInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockEtcdBackupInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *EtcdBackupInterfaceMock) List(opts metav1.ListOptions) (*v3.EtcdBackupList, error) { + if mock.ListFunc == nil { + panic("EtcdBackupInterfaceMock.ListFunc: method is nil but EtcdBackupInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEtcdBackupInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockEtcdBackupInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedEtcdBackupInterface.ListCalls()) +func (mock *EtcdBackupInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEtcdBackupInterfaceMockList.RLock() + calls = mock.calls.List + lockEtcdBackupInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *EtcdBackupInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.EtcdBackupList, error) { + if mock.ListNamespacedFunc == nil { + panic("EtcdBackupInterfaceMock.ListNamespacedFunc: method is nil but EtcdBackupInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockEtcdBackupInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockEtcdBackupInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedEtcdBackupInterface.ListNamespacedCalls()) +func (mock *EtcdBackupInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockEtcdBackupInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockEtcdBackupInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *EtcdBackupInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("EtcdBackupInterfaceMock.ObjectClientFunc: method is nil but EtcdBackupInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockEtcdBackupInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockEtcdBackupInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedEtcdBackupInterface.ObjectClientCalls()) +func (mock *EtcdBackupInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockEtcdBackupInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockEtcdBackupInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *EtcdBackupInterfaceMock) Update(in1 *v3.EtcdBackup) (*v3.EtcdBackup, error) { + if mock.UpdateFunc == nil { + panic("EtcdBackupInterfaceMock.UpdateFunc: method is nil but EtcdBackupInterface.Update was just called") + } + callInfo := struct { + In1 *v3.EtcdBackup + }{ + In1: in1, + } + lockEtcdBackupInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockEtcdBackupInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedEtcdBackupInterface.UpdateCalls()) +func (mock *EtcdBackupInterfaceMock) UpdateCalls() []struct { + In1 *v3.EtcdBackup +} { + var calls []struct { + In1 *v3.EtcdBackup + } + lockEtcdBackupInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockEtcdBackupInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *EtcdBackupInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("EtcdBackupInterfaceMock.WatchFunc: method is nil but EtcdBackupInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockEtcdBackupInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockEtcdBackupInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedEtcdBackupInterface.WatchCalls()) +func (mock *EtcdBackupInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockEtcdBackupInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockEtcdBackupInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockEtcdBackupsGetterMockEtcdBackups sync.RWMutex +) + +// Ensure, that EtcdBackupsGetterMock does implement v31.EtcdBackupsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.EtcdBackupsGetter = &EtcdBackupsGetterMock{} + +// EtcdBackupsGetterMock is a mock implementation of v31.EtcdBackupsGetter. +// +// func TestSomethingThatUsesEtcdBackupsGetter(t *testing.T) { +// +// // make and configure a mocked v31.EtcdBackupsGetter +// mockedEtcdBackupsGetter := &EtcdBackupsGetterMock{ +// EtcdBackupsFunc: func(namespace string) v31.EtcdBackupInterface { +// panic("mock out the EtcdBackups method") +// }, +// } +// +// // use mockedEtcdBackupsGetter in code that requires v31.EtcdBackupsGetter +// // and then make assertions. +// +// } +type EtcdBackupsGetterMock struct { + // EtcdBackupsFunc mocks the EtcdBackups method. + EtcdBackupsFunc func(namespace string) v31.EtcdBackupInterface + + // calls tracks calls to the methods. + calls struct { + // EtcdBackups holds details about calls to the EtcdBackups method. + EtcdBackups []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// EtcdBackups calls EtcdBackupsFunc. +func (mock *EtcdBackupsGetterMock) EtcdBackups(namespace string) v31.EtcdBackupInterface { + if mock.EtcdBackupsFunc == nil { + panic("EtcdBackupsGetterMock.EtcdBackupsFunc: method is nil but EtcdBackupsGetter.EtcdBackups was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockEtcdBackupsGetterMockEtcdBackups.Lock() + mock.calls.EtcdBackups = append(mock.calls.EtcdBackups, callInfo) + lockEtcdBackupsGetterMockEtcdBackups.Unlock() + return mock.EtcdBackupsFunc(namespace) +} + +// EtcdBackupsCalls gets all the calls that were made to EtcdBackups. +// Check the length with: +// +// len(mockedEtcdBackupsGetter.EtcdBackupsCalls()) +func (mock *EtcdBackupsGetterMock) EtcdBackupsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockEtcdBackupsGetterMockEtcdBackups.RLock() + calls = mock.calls.EtcdBackups + lockEtcdBackupsGetterMockEtcdBackups.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_feature_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_feature_mock.go new file mode 100644 index 0000000..7084457 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_feature_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockFeatureListerMockGet sync.RWMutex + lockFeatureListerMockList sync.RWMutex +) + +// Ensure, that FeatureListerMock does implement v31.FeatureLister. +// If this is not the case, regenerate this file with moq. +var _ v31.FeatureLister = &FeatureListerMock{} + +// FeatureListerMock is a mock implementation of v31.FeatureLister. +// +// func TestSomethingThatUsesFeatureLister(t *testing.T) { +// +// // make and configure a mocked v31.FeatureLister +// mockedFeatureLister := &FeatureListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Feature, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Feature, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedFeatureLister in code that requires v31.FeatureLister +// // and then make assertions. +// +// } +type FeatureListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Feature, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Feature, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *FeatureListerMock) Get(namespace string, name string) (*v3.Feature, error) { + if mock.GetFunc == nil { + panic("FeatureListerMock.GetFunc: method is nil but FeatureLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockFeatureListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockFeatureListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedFeatureLister.GetCalls()) +func (mock *FeatureListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockFeatureListerMockGet.RLock() + calls = mock.calls.Get + lockFeatureListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *FeatureListerMock) List(namespace string, selector labels.Selector) ([]*v3.Feature, error) { + if mock.ListFunc == nil { + panic("FeatureListerMock.ListFunc: method is nil but FeatureLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockFeatureListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockFeatureListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedFeatureLister.ListCalls()) +func (mock *FeatureListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockFeatureListerMockList.RLock() + calls = mock.calls.List + lockFeatureListerMockList.RUnlock() + return calls +} + +var ( + lockFeatureControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockFeatureControllerMockAddClusterScopedHandler sync.RWMutex + lockFeatureControllerMockAddFeatureHandler sync.RWMutex + lockFeatureControllerMockAddHandler sync.RWMutex + lockFeatureControllerMockEnqueue sync.RWMutex + lockFeatureControllerMockEnqueueAfter sync.RWMutex + lockFeatureControllerMockGeneric sync.RWMutex + lockFeatureControllerMockInformer sync.RWMutex + lockFeatureControllerMockLister sync.RWMutex +) + +// Ensure, that FeatureControllerMock does implement v31.FeatureController. +// If this is not the case, regenerate this file with moq. +var _ v31.FeatureController = &FeatureControllerMock{} + +// FeatureControllerMock is a mock implementation of v31.FeatureController. +// +// func TestSomethingThatUsesFeatureController(t *testing.T) { +// +// // make and configure a mocked v31.FeatureController +// mockedFeatureController := &FeatureControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FeatureHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.FeatureHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.FeatureHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.FeatureLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedFeatureController in code that requires v31.FeatureController +// // and then make assertions. +// +// } +type FeatureControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FeatureHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.FeatureHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.FeatureHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.FeatureLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.FeatureHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.FeatureHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FeatureHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.FeatureHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *FeatureControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FeatureHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("FeatureControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but FeatureController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockFeatureControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockFeatureControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedFeatureController.AddClusterScopedFeatureHandlerCalls()) +func (mock *FeatureControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FeatureHandlerFunc + } + lockFeatureControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockFeatureControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *FeatureControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.FeatureHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("FeatureControllerMock.AddClusterScopedHandlerFunc: method is nil but FeatureController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockFeatureControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockFeatureControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedFeatureController.AddClusterScopedHandlerCalls()) +func (mock *FeatureControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FeatureHandlerFunc + } + lockFeatureControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockFeatureControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *FeatureControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("FeatureControllerMock.AddFeatureHandlerFunc: method is nil but FeatureController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockFeatureControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockFeatureControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedFeatureController.AddFeatureHandlerCalls()) +func (mock *FeatureControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc + } + lockFeatureControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockFeatureControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *FeatureControllerMock) AddHandler(ctx context.Context, name string, handler v31.FeatureHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("FeatureControllerMock.AddHandlerFunc: method is nil but FeatureController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockFeatureControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockFeatureControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedFeatureController.AddHandlerCalls()) +func (mock *FeatureControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.FeatureHandlerFunc + } + lockFeatureControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockFeatureControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *FeatureControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("FeatureControllerMock.EnqueueFunc: method is nil but FeatureController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockFeatureControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockFeatureControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedFeatureController.EnqueueCalls()) +func (mock *FeatureControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockFeatureControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockFeatureControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *FeatureControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("FeatureControllerMock.EnqueueAfterFunc: method is nil but FeatureController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockFeatureControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockFeatureControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedFeatureController.EnqueueAfterCalls()) +func (mock *FeatureControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockFeatureControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockFeatureControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *FeatureControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("FeatureControllerMock.GenericFunc: method is nil but FeatureController.Generic was just called") + } + callInfo := struct { + }{} + lockFeatureControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockFeatureControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedFeatureController.GenericCalls()) +func (mock *FeatureControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockFeatureControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockFeatureControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *FeatureControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("FeatureControllerMock.InformerFunc: method is nil but FeatureController.Informer was just called") + } + callInfo := struct { + }{} + lockFeatureControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockFeatureControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedFeatureController.InformerCalls()) +func (mock *FeatureControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockFeatureControllerMockInformer.RLock() + calls = mock.calls.Informer + lockFeatureControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *FeatureControllerMock) Lister() v31.FeatureLister { + if mock.ListerFunc == nil { + panic("FeatureControllerMock.ListerFunc: method is nil but FeatureController.Lister was just called") + } + callInfo := struct { + }{} + lockFeatureControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockFeatureControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedFeatureController.ListerCalls()) +func (mock *FeatureControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockFeatureControllerMockLister.RLock() + calls = mock.calls.Lister + lockFeatureControllerMockLister.RUnlock() + return calls +} + +var ( + lockFeatureInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockFeatureInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockFeatureInterfaceMockAddClusterScopedHandler sync.RWMutex + lockFeatureInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockFeatureInterfaceMockAddFeatureHandler sync.RWMutex + lockFeatureInterfaceMockAddFeatureLifecycle sync.RWMutex + lockFeatureInterfaceMockAddHandler sync.RWMutex + lockFeatureInterfaceMockAddLifecycle sync.RWMutex + lockFeatureInterfaceMockController sync.RWMutex + lockFeatureInterfaceMockCreate sync.RWMutex + lockFeatureInterfaceMockDelete sync.RWMutex + lockFeatureInterfaceMockDeleteCollection sync.RWMutex + lockFeatureInterfaceMockDeleteNamespaced sync.RWMutex + lockFeatureInterfaceMockGet sync.RWMutex + lockFeatureInterfaceMockGetNamespaced sync.RWMutex + lockFeatureInterfaceMockList sync.RWMutex + lockFeatureInterfaceMockListNamespaced sync.RWMutex + lockFeatureInterfaceMockObjectClient sync.RWMutex + lockFeatureInterfaceMockUpdate sync.RWMutex + lockFeatureInterfaceMockWatch sync.RWMutex +) + +// Ensure, that FeatureInterfaceMock does implement v31.FeatureInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.FeatureInterface = &FeatureInterfaceMock{} + +// FeatureInterfaceMock is a mock implementation of v31.FeatureInterface. +// +// func TestSomethingThatUsesFeatureInterface(t *testing.T) { +// +// // make and configure a mocked v31.FeatureInterface +// mockedFeatureInterface := &FeatureInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FeatureLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.FeatureLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.FeatureLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.FeatureHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.FeatureLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.FeatureController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Feature) (*v3.Feature, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Feature, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Feature, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.FeatureList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.FeatureList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Feature) (*v3.Feature, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedFeatureInterface in code that requires v31.FeatureInterface +// // and then make assertions. +// +// } +type FeatureInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FeatureLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.FeatureLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.FeatureLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.FeatureHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.FeatureLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.FeatureController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Feature) (*v3.Feature, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Feature, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Feature, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.FeatureList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.FeatureList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Feature) (*v3.Feature, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.FeatureHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FeatureLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.FeatureHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FeatureLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FeatureHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FeatureLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FeatureHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FeatureLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Feature + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Feature + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *FeatureInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("FeatureInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but FeatureInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockFeatureInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockFeatureInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedFeatureInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *FeatureInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FeatureHandlerFunc + } + lockFeatureInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockFeatureInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *FeatureInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FeatureLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("FeatureInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but FeatureInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockFeatureInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockFeatureInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedFeatureInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *FeatureInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle + } + lockFeatureInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockFeatureInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *FeatureInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.FeatureHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("FeatureInterfaceMock.AddClusterScopedHandlerFunc: method is nil but FeatureInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockFeatureInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockFeatureInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedFeatureInterface.AddClusterScopedHandlerCalls()) +func (mock *FeatureInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FeatureHandlerFunc + } + lockFeatureInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockFeatureInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *FeatureInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.FeatureLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("FeatureInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but FeatureInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockFeatureInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockFeatureInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedFeatureInterface.AddClusterScopedLifecycleCalls()) +func (mock *FeatureInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FeatureLifecycle + } + lockFeatureInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockFeatureInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *FeatureInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FeatureHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("FeatureInterfaceMock.AddFeatureHandlerFunc: method is nil but FeatureInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockFeatureInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockFeatureInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedFeatureInterface.AddFeatureHandlerCalls()) +func (mock *FeatureInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FeatureHandlerFunc + } + lockFeatureInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockFeatureInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *FeatureInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.FeatureLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("FeatureInterfaceMock.AddFeatureLifecycleFunc: method is nil but FeatureInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FeatureLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockFeatureInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockFeatureInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedFeatureInterface.AddFeatureLifecycleCalls()) +func (mock *FeatureInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FeatureLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FeatureLifecycle + } + lockFeatureInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockFeatureInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *FeatureInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.FeatureHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("FeatureInterfaceMock.AddHandlerFunc: method is nil but FeatureInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.FeatureHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockFeatureInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockFeatureInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedFeatureInterface.AddHandlerCalls()) +func (mock *FeatureInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.FeatureHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.FeatureHandlerFunc + } + lockFeatureInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockFeatureInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *FeatureInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.FeatureLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("FeatureInterfaceMock.AddLifecycleFunc: method is nil but FeatureInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.FeatureLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockFeatureInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockFeatureInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedFeatureInterface.AddLifecycleCalls()) +func (mock *FeatureInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.FeatureLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.FeatureLifecycle + } + lockFeatureInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockFeatureInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *FeatureInterfaceMock) Controller() v31.FeatureController { + if mock.ControllerFunc == nil { + panic("FeatureInterfaceMock.ControllerFunc: method is nil but FeatureInterface.Controller was just called") + } + callInfo := struct { + }{} + lockFeatureInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockFeatureInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedFeatureInterface.ControllerCalls()) +func (mock *FeatureInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockFeatureInterfaceMockController.RLock() + calls = mock.calls.Controller + lockFeatureInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *FeatureInterfaceMock) Create(in1 *v3.Feature) (*v3.Feature, error) { + if mock.CreateFunc == nil { + panic("FeatureInterfaceMock.CreateFunc: method is nil but FeatureInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Feature + }{ + In1: in1, + } + lockFeatureInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockFeatureInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedFeatureInterface.CreateCalls()) +func (mock *FeatureInterfaceMock) CreateCalls() []struct { + In1 *v3.Feature +} { + var calls []struct { + In1 *v3.Feature + } + lockFeatureInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockFeatureInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *FeatureInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("FeatureInterfaceMock.DeleteFunc: method is nil but FeatureInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockFeatureInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockFeatureInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedFeatureInterface.DeleteCalls()) +func (mock *FeatureInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockFeatureInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockFeatureInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *FeatureInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("FeatureInterfaceMock.DeleteCollectionFunc: method is nil but FeatureInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockFeatureInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockFeatureInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedFeatureInterface.DeleteCollectionCalls()) +func (mock *FeatureInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockFeatureInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockFeatureInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *FeatureInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("FeatureInterfaceMock.DeleteNamespacedFunc: method is nil but FeatureInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockFeatureInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockFeatureInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedFeatureInterface.DeleteNamespacedCalls()) +func (mock *FeatureInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockFeatureInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockFeatureInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *FeatureInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Feature, error) { + if mock.GetFunc == nil { + panic("FeatureInterfaceMock.GetFunc: method is nil but FeatureInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockFeatureInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockFeatureInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedFeatureInterface.GetCalls()) +func (mock *FeatureInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockFeatureInterfaceMockGet.RLock() + calls = mock.calls.Get + lockFeatureInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *FeatureInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Feature, error) { + if mock.GetNamespacedFunc == nil { + panic("FeatureInterfaceMock.GetNamespacedFunc: method is nil but FeatureInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockFeatureInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockFeatureInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedFeatureInterface.GetNamespacedCalls()) +func (mock *FeatureInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockFeatureInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockFeatureInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *FeatureInterfaceMock) List(opts metav1.ListOptions) (*v3.FeatureList, error) { + if mock.ListFunc == nil { + panic("FeatureInterfaceMock.ListFunc: method is nil but FeatureInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockFeatureInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockFeatureInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedFeatureInterface.ListCalls()) +func (mock *FeatureInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockFeatureInterfaceMockList.RLock() + calls = mock.calls.List + lockFeatureInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *FeatureInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FeatureList, error) { + if mock.ListNamespacedFunc == nil { + panic("FeatureInterfaceMock.ListNamespacedFunc: method is nil but FeatureInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockFeatureInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockFeatureInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedFeatureInterface.ListNamespacedCalls()) +func (mock *FeatureInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockFeatureInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockFeatureInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *FeatureInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("FeatureInterfaceMock.ObjectClientFunc: method is nil but FeatureInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockFeatureInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockFeatureInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedFeatureInterface.ObjectClientCalls()) +func (mock *FeatureInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockFeatureInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockFeatureInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *FeatureInterfaceMock) Update(in1 *v3.Feature) (*v3.Feature, error) { + if mock.UpdateFunc == nil { + panic("FeatureInterfaceMock.UpdateFunc: method is nil but FeatureInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Feature + }{ + In1: in1, + } + lockFeatureInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockFeatureInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedFeatureInterface.UpdateCalls()) +func (mock *FeatureInterfaceMock) UpdateCalls() []struct { + In1 *v3.Feature +} { + var calls []struct { + In1 *v3.Feature + } + lockFeatureInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockFeatureInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *FeatureInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("FeatureInterfaceMock.WatchFunc: method is nil but FeatureInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockFeatureInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockFeatureInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedFeatureInterface.WatchCalls()) +func (mock *FeatureInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockFeatureInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockFeatureInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockFeaturesGetterMockFeatures sync.RWMutex +) + +// Ensure, that FeaturesGetterMock does implement v31.FeaturesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.FeaturesGetter = &FeaturesGetterMock{} + +// FeaturesGetterMock is a mock implementation of v31.FeaturesGetter. +// +// func TestSomethingThatUsesFeaturesGetter(t *testing.T) { +// +// // make and configure a mocked v31.FeaturesGetter +// mockedFeaturesGetter := &FeaturesGetterMock{ +// FeaturesFunc: func(namespace string) v31.FeatureInterface { +// panic("mock out the Features method") +// }, +// } +// +// // use mockedFeaturesGetter in code that requires v31.FeaturesGetter +// // and then make assertions. +// +// } +type FeaturesGetterMock struct { + // FeaturesFunc mocks the Features method. + FeaturesFunc func(namespace string) v31.FeatureInterface + + // calls tracks calls to the methods. + calls struct { + // Features holds details about calls to the Features method. + Features []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Features calls FeaturesFunc. +func (mock *FeaturesGetterMock) Features(namespace string) v31.FeatureInterface { + if mock.FeaturesFunc == nil { + panic("FeaturesGetterMock.FeaturesFunc: method is nil but FeaturesGetter.Features was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockFeaturesGetterMockFeatures.Lock() + mock.calls.Features = append(mock.calls.Features, callInfo) + lockFeaturesGetterMockFeatures.Unlock() + return mock.FeaturesFunc(namespace) +} + +// FeaturesCalls gets all the calls that were made to Features. +// Check the length with: +// +// len(mockedFeaturesGetter.FeaturesCalls()) +func (mock *FeaturesGetterMock) FeaturesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockFeaturesGetterMockFeatures.RLock() + calls = mock.calls.Features + lockFeaturesGetterMockFeatures.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_fleet_workspace_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_fleet_workspace_mock.go new file mode 100644 index 0000000..81a7a46 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_fleet_workspace_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockFleetWorkspaceListerMockGet sync.RWMutex + lockFleetWorkspaceListerMockList sync.RWMutex +) + +// Ensure, that FleetWorkspaceListerMock does implement v31.FleetWorkspaceLister. +// If this is not the case, regenerate this file with moq. +var _ v31.FleetWorkspaceLister = &FleetWorkspaceListerMock{} + +// FleetWorkspaceListerMock is a mock implementation of v31.FleetWorkspaceLister. +// +// func TestSomethingThatUsesFleetWorkspaceLister(t *testing.T) { +// +// // make and configure a mocked v31.FleetWorkspaceLister +// mockedFleetWorkspaceLister := &FleetWorkspaceListerMock{ +// GetFunc: func(namespace string, name string) (*v3.FleetWorkspace, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.FleetWorkspace, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedFleetWorkspaceLister in code that requires v31.FleetWorkspaceLister +// // and then make assertions. +// +// } +type FleetWorkspaceListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.FleetWorkspace, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.FleetWorkspace, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *FleetWorkspaceListerMock) Get(namespace string, name string) (*v3.FleetWorkspace, error) { + if mock.GetFunc == nil { + panic("FleetWorkspaceListerMock.GetFunc: method is nil but FleetWorkspaceLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockFleetWorkspaceListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockFleetWorkspaceListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedFleetWorkspaceLister.GetCalls()) +func (mock *FleetWorkspaceListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockFleetWorkspaceListerMockGet.RLock() + calls = mock.calls.Get + lockFleetWorkspaceListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *FleetWorkspaceListerMock) List(namespace string, selector labels.Selector) ([]*v3.FleetWorkspace, error) { + if mock.ListFunc == nil { + panic("FleetWorkspaceListerMock.ListFunc: method is nil but FleetWorkspaceLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockFleetWorkspaceListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockFleetWorkspaceListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedFleetWorkspaceLister.ListCalls()) +func (mock *FleetWorkspaceListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockFleetWorkspaceListerMockList.RLock() + calls = mock.calls.List + lockFleetWorkspaceListerMockList.RUnlock() + return calls +} + +var ( + lockFleetWorkspaceControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockFleetWorkspaceControllerMockAddClusterScopedHandler sync.RWMutex + lockFleetWorkspaceControllerMockAddFeatureHandler sync.RWMutex + lockFleetWorkspaceControllerMockAddHandler sync.RWMutex + lockFleetWorkspaceControllerMockEnqueue sync.RWMutex + lockFleetWorkspaceControllerMockEnqueueAfter sync.RWMutex + lockFleetWorkspaceControllerMockGeneric sync.RWMutex + lockFleetWorkspaceControllerMockInformer sync.RWMutex + lockFleetWorkspaceControllerMockLister sync.RWMutex +) + +// Ensure, that FleetWorkspaceControllerMock does implement v31.FleetWorkspaceController. +// If this is not the case, regenerate this file with moq. +var _ v31.FleetWorkspaceController = &FleetWorkspaceControllerMock{} + +// FleetWorkspaceControllerMock is a mock implementation of v31.FleetWorkspaceController. +// +// func TestSomethingThatUsesFleetWorkspaceController(t *testing.T) { +// +// // make and configure a mocked v31.FleetWorkspaceController +// mockedFleetWorkspaceController := &FleetWorkspaceControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.FleetWorkspaceLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedFleetWorkspaceController in code that requires v31.FleetWorkspaceController +// // and then make assertions. +// +// } +type FleetWorkspaceControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.FleetWorkspaceHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.FleetWorkspaceLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.FleetWorkspaceHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.FleetWorkspaceHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FleetWorkspaceHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.FleetWorkspaceHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *FleetWorkspaceControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("FleetWorkspaceControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but FleetWorkspaceController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockFleetWorkspaceControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockFleetWorkspaceControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceController.AddClusterScopedFeatureHandlerCalls()) +func (mock *FleetWorkspaceControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockFleetWorkspaceControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *FleetWorkspaceControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.FleetWorkspaceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("FleetWorkspaceControllerMock.AddClusterScopedHandlerFunc: method is nil but FleetWorkspaceController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockFleetWorkspaceControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockFleetWorkspaceControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceController.AddClusterScopedHandlerCalls()) +func (mock *FleetWorkspaceControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockFleetWorkspaceControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *FleetWorkspaceControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("FleetWorkspaceControllerMock.AddFeatureHandlerFunc: method is nil but FleetWorkspaceController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockFleetWorkspaceControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockFleetWorkspaceControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceController.AddFeatureHandlerCalls()) +func (mock *FleetWorkspaceControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockFleetWorkspaceControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *FleetWorkspaceControllerMock) AddHandler(ctx context.Context, name string, handler v31.FleetWorkspaceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("FleetWorkspaceControllerMock.AddHandlerFunc: method is nil but FleetWorkspaceController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockFleetWorkspaceControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockFleetWorkspaceControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceController.AddHandlerCalls()) +func (mock *FleetWorkspaceControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockFleetWorkspaceControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *FleetWorkspaceControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("FleetWorkspaceControllerMock.EnqueueFunc: method is nil but FleetWorkspaceController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockFleetWorkspaceControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockFleetWorkspaceControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedFleetWorkspaceController.EnqueueCalls()) +func (mock *FleetWorkspaceControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockFleetWorkspaceControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockFleetWorkspaceControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *FleetWorkspaceControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("FleetWorkspaceControllerMock.EnqueueAfterFunc: method is nil but FleetWorkspaceController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockFleetWorkspaceControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockFleetWorkspaceControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedFleetWorkspaceController.EnqueueAfterCalls()) +func (mock *FleetWorkspaceControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockFleetWorkspaceControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockFleetWorkspaceControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *FleetWorkspaceControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("FleetWorkspaceControllerMock.GenericFunc: method is nil but FleetWorkspaceController.Generic was just called") + } + callInfo := struct { + }{} + lockFleetWorkspaceControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockFleetWorkspaceControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedFleetWorkspaceController.GenericCalls()) +func (mock *FleetWorkspaceControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockFleetWorkspaceControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockFleetWorkspaceControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *FleetWorkspaceControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("FleetWorkspaceControllerMock.InformerFunc: method is nil but FleetWorkspaceController.Informer was just called") + } + callInfo := struct { + }{} + lockFleetWorkspaceControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockFleetWorkspaceControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedFleetWorkspaceController.InformerCalls()) +func (mock *FleetWorkspaceControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockFleetWorkspaceControllerMockInformer.RLock() + calls = mock.calls.Informer + lockFleetWorkspaceControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *FleetWorkspaceControllerMock) Lister() v31.FleetWorkspaceLister { + if mock.ListerFunc == nil { + panic("FleetWorkspaceControllerMock.ListerFunc: method is nil but FleetWorkspaceController.Lister was just called") + } + callInfo := struct { + }{} + lockFleetWorkspaceControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockFleetWorkspaceControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedFleetWorkspaceController.ListerCalls()) +func (mock *FleetWorkspaceControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockFleetWorkspaceControllerMockLister.RLock() + calls = mock.calls.Lister + lockFleetWorkspaceControllerMockLister.RUnlock() + return calls +} + +var ( + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockFleetWorkspaceInterfaceMockAddClusterScopedHandler sync.RWMutex + lockFleetWorkspaceInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockFleetWorkspaceInterfaceMockAddFeatureHandler sync.RWMutex + lockFleetWorkspaceInterfaceMockAddFeatureLifecycle sync.RWMutex + lockFleetWorkspaceInterfaceMockAddHandler sync.RWMutex + lockFleetWorkspaceInterfaceMockAddLifecycle sync.RWMutex + lockFleetWorkspaceInterfaceMockController sync.RWMutex + lockFleetWorkspaceInterfaceMockCreate sync.RWMutex + lockFleetWorkspaceInterfaceMockDelete sync.RWMutex + lockFleetWorkspaceInterfaceMockDeleteCollection sync.RWMutex + lockFleetWorkspaceInterfaceMockDeleteNamespaced sync.RWMutex + lockFleetWorkspaceInterfaceMockGet sync.RWMutex + lockFleetWorkspaceInterfaceMockGetNamespaced sync.RWMutex + lockFleetWorkspaceInterfaceMockList sync.RWMutex + lockFleetWorkspaceInterfaceMockListNamespaced sync.RWMutex + lockFleetWorkspaceInterfaceMockObjectClient sync.RWMutex + lockFleetWorkspaceInterfaceMockUpdate sync.RWMutex + lockFleetWorkspaceInterfaceMockWatch sync.RWMutex +) + +// Ensure, that FleetWorkspaceInterfaceMock does implement v31.FleetWorkspaceInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.FleetWorkspaceInterface = &FleetWorkspaceInterfaceMock{} + +// FleetWorkspaceInterfaceMock is a mock implementation of v31.FleetWorkspaceInterface. +// +// func TestSomethingThatUsesFleetWorkspaceInterface(t *testing.T) { +// +// // make and configure a mocked v31.FleetWorkspaceInterface +// mockedFleetWorkspaceInterface := &FleetWorkspaceInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.FleetWorkspaceLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.FleetWorkspaceLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.FleetWorkspaceController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedFleetWorkspaceInterface in code that requires v31.FleetWorkspaceInterface +// // and then make assertions. +// +// } +type FleetWorkspaceInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.FleetWorkspaceLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.FleetWorkspaceLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.FleetWorkspaceController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.FleetWorkspaceHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FleetWorkspaceLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.FleetWorkspaceHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FleetWorkspaceLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FleetWorkspaceHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FleetWorkspaceLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.FleetWorkspaceHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.FleetWorkspaceLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.FleetWorkspace + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.FleetWorkspace + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but FleetWorkspaceInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but FleetWorkspaceInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle + } + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockFleetWorkspaceInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddClusterScopedHandlerFunc: method is nil but FleetWorkspaceInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockFleetWorkspaceInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockFleetWorkspaceInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddClusterScopedHandlerCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockFleetWorkspaceInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.FleetWorkspaceLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but FleetWorkspaceInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockFleetWorkspaceInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockFleetWorkspaceInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddClusterScopedLifecycleCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.FleetWorkspaceLifecycle + } + lockFleetWorkspaceInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockFleetWorkspaceInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *FleetWorkspaceInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddFeatureHandlerFunc: method is nil but FleetWorkspaceInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockFleetWorkspaceInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockFleetWorkspaceInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddFeatureHandlerCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockFleetWorkspaceInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *FleetWorkspaceInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.FleetWorkspaceLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddFeatureLifecycleFunc: method is nil but FleetWorkspaceInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FleetWorkspaceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockFleetWorkspaceInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockFleetWorkspaceInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddFeatureLifecycleCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FleetWorkspaceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.FleetWorkspaceLifecycle + } + lockFleetWorkspaceInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockFleetWorkspaceInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *FleetWorkspaceInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.FleetWorkspaceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddHandlerFunc: method is nil but FleetWorkspaceInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.FleetWorkspaceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockFleetWorkspaceInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockFleetWorkspaceInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddHandlerCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.FleetWorkspaceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.FleetWorkspaceHandlerFunc + } + lockFleetWorkspaceInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockFleetWorkspaceInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *FleetWorkspaceInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.FleetWorkspaceLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("FleetWorkspaceInterfaceMock.AddLifecycleFunc: method is nil but FleetWorkspaceInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.FleetWorkspaceLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockFleetWorkspaceInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockFleetWorkspaceInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.AddLifecycleCalls()) +func (mock *FleetWorkspaceInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.FleetWorkspaceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.FleetWorkspaceLifecycle + } + lockFleetWorkspaceInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockFleetWorkspaceInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *FleetWorkspaceInterfaceMock) Controller() v31.FleetWorkspaceController { + if mock.ControllerFunc == nil { + panic("FleetWorkspaceInterfaceMock.ControllerFunc: method is nil but FleetWorkspaceInterface.Controller was just called") + } + callInfo := struct { + }{} + lockFleetWorkspaceInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockFleetWorkspaceInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.ControllerCalls()) +func (mock *FleetWorkspaceInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockFleetWorkspaceInterfaceMockController.RLock() + calls = mock.calls.Controller + lockFleetWorkspaceInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *FleetWorkspaceInterfaceMock) Create(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + if mock.CreateFunc == nil { + panic("FleetWorkspaceInterfaceMock.CreateFunc: method is nil but FleetWorkspaceInterface.Create was just called") + } + callInfo := struct { + In1 *v3.FleetWorkspace + }{ + In1: in1, + } + lockFleetWorkspaceInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockFleetWorkspaceInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.CreateCalls()) +func (mock *FleetWorkspaceInterfaceMock) CreateCalls() []struct { + In1 *v3.FleetWorkspace +} { + var calls []struct { + In1 *v3.FleetWorkspace + } + lockFleetWorkspaceInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockFleetWorkspaceInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *FleetWorkspaceInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("FleetWorkspaceInterfaceMock.DeleteFunc: method is nil but FleetWorkspaceInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockFleetWorkspaceInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockFleetWorkspaceInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.DeleteCalls()) +func (mock *FleetWorkspaceInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockFleetWorkspaceInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockFleetWorkspaceInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *FleetWorkspaceInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("FleetWorkspaceInterfaceMock.DeleteCollectionFunc: method is nil but FleetWorkspaceInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockFleetWorkspaceInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockFleetWorkspaceInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.DeleteCollectionCalls()) +func (mock *FleetWorkspaceInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockFleetWorkspaceInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockFleetWorkspaceInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *FleetWorkspaceInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("FleetWorkspaceInterfaceMock.DeleteNamespacedFunc: method is nil but FleetWorkspaceInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockFleetWorkspaceInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockFleetWorkspaceInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.DeleteNamespacedCalls()) +func (mock *FleetWorkspaceInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockFleetWorkspaceInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockFleetWorkspaceInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *FleetWorkspaceInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { + if mock.GetFunc == nil { + panic("FleetWorkspaceInterfaceMock.GetFunc: method is nil but FleetWorkspaceInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockFleetWorkspaceInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockFleetWorkspaceInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.GetCalls()) +func (mock *FleetWorkspaceInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockFleetWorkspaceInterfaceMockGet.RLock() + calls = mock.calls.Get + lockFleetWorkspaceInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *FleetWorkspaceInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { + if mock.GetNamespacedFunc == nil { + panic("FleetWorkspaceInterfaceMock.GetNamespacedFunc: method is nil but FleetWorkspaceInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockFleetWorkspaceInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockFleetWorkspaceInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.GetNamespacedCalls()) +func (mock *FleetWorkspaceInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockFleetWorkspaceInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockFleetWorkspaceInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *FleetWorkspaceInterfaceMock) List(opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { + if mock.ListFunc == nil { + panic("FleetWorkspaceInterfaceMock.ListFunc: method is nil but FleetWorkspaceInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockFleetWorkspaceInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockFleetWorkspaceInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.ListCalls()) +func (mock *FleetWorkspaceInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockFleetWorkspaceInterfaceMockList.RLock() + calls = mock.calls.List + lockFleetWorkspaceInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *FleetWorkspaceInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { + if mock.ListNamespacedFunc == nil { + panic("FleetWorkspaceInterfaceMock.ListNamespacedFunc: method is nil but FleetWorkspaceInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockFleetWorkspaceInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockFleetWorkspaceInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.ListNamespacedCalls()) +func (mock *FleetWorkspaceInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockFleetWorkspaceInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockFleetWorkspaceInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *FleetWorkspaceInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("FleetWorkspaceInterfaceMock.ObjectClientFunc: method is nil but FleetWorkspaceInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockFleetWorkspaceInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockFleetWorkspaceInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.ObjectClientCalls()) +func (mock *FleetWorkspaceInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockFleetWorkspaceInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockFleetWorkspaceInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *FleetWorkspaceInterfaceMock) Update(in1 *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + if mock.UpdateFunc == nil { + panic("FleetWorkspaceInterfaceMock.UpdateFunc: method is nil but FleetWorkspaceInterface.Update was just called") + } + callInfo := struct { + In1 *v3.FleetWorkspace + }{ + In1: in1, + } + lockFleetWorkspaceInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockFleetWorkspaceInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.UpdateCalls()) +func (mock *FleetWorkspaceInterfaceMock) UpdateCalls() []struct { + In1 *v3.FleetWorkspace +} { + var calls []struct { + In1 *v3.FleetWorkspace + } + lockFleetWorkspaceInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockFleetWorkspaceInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *FleetWorkspaceInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("FleetWorkspaceInterfaceMock.WatchFunc: method is nil but FleetWorkspaceInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockFleetWorkspaceInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockFleetWorkspaceInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedFleetWorkspaceInterface.WatchCalls()) +func (mock *FleetWorkspaceInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockFleetWorkspaceInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockFleetWorkspaceInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockFleetWorkspacesGetterMockFleetWorkspaces sync.RWMutex +) + +// Ensure, that FleetWorkspacesGetterMock does implement v31.FleetWorkspacesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.FleetWorkspacesGetter = &FleetWorkspacesGetterMock{} + +// FleetWorkspacesGetterMock is a mock implementation of v31.FleetWorkspacesGetter. +// +// func TestSomethingThatUsesFleetWorkspacesGetter(t *testing.T) { +// +// // make and configure a mocked v31.FleetWorkspacesGetter +// mockedFleetWorkspacesGetter := &FleetWorkspacesGetterMock{ +// FleetWorkspacesFunc: func(namespace string) v31.FleetWorkspaceInterface { +// panic("mock out the FleetWorkspaces method") +// }, +// } +// +// // use mockedFleetWorkspacesGetter in code that requires v31.FleetWorkspacesGetter +// // and then make assertions. +// +// } +type FleetWorkspacesGetterMock struct { + // FleetWorkspacesFunc mocks the FleetWorkspaces method. + FleetWorkspacesFunc func(namespace string) v31.FleetWorkspaceInterface + + // calls tracks calls to the methods. + calls struct { + // FleetWorkspaces holds details about calls to the FleetWorkspaces method. + FleetWorkspaces []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// FleetWorkspaces calls FleetWorkspacesFunc. +func (mock *FleetWorkspacesGetterMock) FleetWorkspaces(namespace string) v31.FleetWorkspaceInterface { + if mock.FleetWorkspacesFunc == nil { + panic("FleetWorkspacesGetterMock.FleetWorkspacesFunc: method is nil but FleetWorkspacesGetter.FleetWorkspaces was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockFleetWorkspacesGetterMockFleetWorkspaces.Lock() + mock.calls.FleetWorkspaces = append(mock.calls.FleetWorkspaces, callInfo) + lockFleetWorkspacesGetterMockFleetWorkspaces.Unlock() + return mock.FleetWorkspacesFunc(namespace) +} + +// FleetWorkspacesCalls gets all the calls that were made to FleetWorkspaces. +// Check the length with: +// +// len(mockedFleetWorkspacesGetter.FleetWorkspacesCalls()) +func (mock *FleetWorkspacesGetterMock) FleetWorkspacesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockFleetWorkspacesGetterMockFleetWorkspaces.RLock() + calls = mock.calls.FleetWorkspaces + lockFleetWorkspacesGetterMockFleetWorkspaces.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_mock.go new file mode 100644 index 0000000..73ab3e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGlobalDnsListerMockGet sync.RWMutex + lockGlobalDnsListerMockList sync.RWMutex +) + +// Ensure, that GlobalDnsListerMock does implement v31.GlobalDnsLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsLister = &GlobalDnsListerMock{} + +// GlobalDnsListerMock is a mock implementation of v31.GlobalDnsLister. +// +// func TestSomethingThatUsesGlobalDnsLister(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsLister +// mockedGlobalDnsLister := &GlobalDnsListerMock{ +// GetFunc: func(namespace string, name string) (*v3.GlobalDns, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.GlobalDns, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGlobalDnsLister in code that requires v31.GlobalDnsLister +// // and then make assertions. +// +// } +type GlobalDnsListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.GlobalDns, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.GlobalDns, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GlobalDnsListerMock) Get(namespace string, name string) (*v3.GlobalDns, error) { + if mock.GetFunc == nil { + panic("GlobalDnsListerMock.GetFunc: method is nil but GlobalDnsLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalDnsListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalDnsListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalDnsLister.GetCalls()) +func (mock *GlobalDnsListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalDnsListerMockGet.RLock() + calls = mock.calls.Get + lockGlobalDnsListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalDnsListerMock) List(namespace string, selector labels.Selector) ([]*v3.GlobalDns, error) { + if mock.ListFunc == nil { + panic("GlobalDnsListerMock.ListFunc: method is nil but GlobalDnsLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGlobalDnsListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalDnsListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalDnsLister.ListCalls()) +func (mock *GlobalDnsListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGlobalDnsListerMockList.RLock() + calls = mock.calls.List + lockGlobalDnsListerMockList.RUnlock() + return calls +} + +var ( + lockGlobalDnsControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalDnsControllerMockAddClusterScopedHandler sync.RWMutex + lockGlobalDnsControllerMockAddFeatureHandler sync.RWMutex + lockGlobalDnsControllerMockAddHandler sync.RWMutex + lockGlobalDnsControllerMockEnqueue sync.RWMutex + lockGlobalDnsControllerMockEnqueueAfter sync.RWMutex + lockGlobalDnsControllerMockGeneric sync.RWMutex + lockGlobalDnsControllerMockInformer sync.RWMutex + lockGlobalDnsControllerMockLister sync.RWMutex +) + +// Ensure, that GlobalDnsControllerMock does implement v31.GlobalDnsController. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsController = &GlobalDnsControllerMock{} + +// GlobalDnsControllerMock is a mock implementation of v31.GlobalDnsController. +// +// func TestSomethingThatUsesGlobalDnsController(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsController +// mockedGlobalDnsController := &GlobalDnsControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GlobalDnsLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGlobalDnsController in code that requires v31.GlobalDnsController +// // and then make assertions. +// +// } +type GlobalDnsControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GlobalDnsHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GlobalDnsLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalDnsHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalDnsHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GlobalDnsHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalDnsControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalDnsControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalDnsController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalDnsControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalDnsControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalDnsControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc + } + lockGlobalDnsControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalDnsControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalDnsControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalDnsControllerMock.AddClusterScopedHandlerFunc: method is nil but GlobalDnsController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalDnsControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalDnsControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalDnsController.AddClusterScopedHandlerCalls()) +func (mock *GlobalDnsControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsHandlerFunc + } + lockGlobalDnsControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalDnsControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalDnsControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalDnsControllerMock.AddFeatureHandlerFunc: method is nil but GlobalDnsController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalDnsControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsController.AddFeatureHandlerCalls()) +func (mock *GlobalDnsControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc + } + lockGlobalDnsControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalDnsControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalDnsControllerMock) AddHandler(ctx context.Context, name string, handler v31.GlobalDnsHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalDnsControllerMock.AddHandlerFunc: method is nil but GlobalDnsController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGlobalDnsControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalDnsControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalDnsController.AddHandlerCalls()) +func (mock *GlobalDnsControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsHandlerFunc + } + lockGlobalDnsControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalDnsControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GlobalDnsControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GlobalDnsControllerMock.EnqueueFunc: method is nil but GlobalDnsController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalDnsControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGlobalDnsControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGlobalDnsController.EnqueueCalls()) +func (mock *GlobalDnsControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalDnsControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGlobalDnsControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GlobalDnsControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GlobalDnsControllerMock.EnqueueAfterFunc: method is nil but GlobalDnsController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGlobalDnsControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGlobalDnsControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGlobalDnsController.EnqueueAfterCalls()) +func (mock *GlobalDnsControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGlobalDnsControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGlobalDnsControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GlobalDnsControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GlobalDnsControllerMock.GenericFunc: method is nil but GlobalDnsController.Generic was just called") + } + callInfo := struct { + }{} + lockGlobalDnsControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGlobalDnsControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGlobalDnsController.GenericCalls()) +func (mock *GlobalDnsControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGlobalDnsControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GlobalDnsControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GlobalDnsControllerMock.InformerFunc: method is nil but GlobalDnsController.Informer was just called") + } + callInfo := struct { + }{} + lockGlobalDnsControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGlobalDnsControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGlobalDnsController.InformerCalls()) +func (mock *GlobalDnsControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGlobalDnsControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GlobalDnsControllerMock) Lister() v31.GlobalDnsLister { + if mock.ListerFunc == nil { + panic("GlobalDnsControllerMock.ListerFunc: method is nil but GlobalDnsController.Lister was just called") + } + callInfo := struct { + }{} + lockGlobalDnsControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGlobalDnsControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGlobalDnsController.ListerCalls()) +func (mock *GlobalDnsControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsControllerMockLister.RLock() + calls = mock.calls.Lister + lockGlobalDnsControllerMockLister.RUnlock() + return calls +} + +var ( + lockGlobalDnsInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalDnsInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGlobalDnsInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGlobalDnsInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGlobalDnsInterfaceMockAddFeatureHandler sync.RWMutex + lockGlobalDnsInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGlobalDnsInterfaceMockAddHandler sync.RWMutex + lockGlobalDnsInterfaceMockAddLifecycle sync.RWMutex + lockGlobalDnsInterfaceMockController sync.RWMutex + lockGlobalDnsInterfaceMockCreate sync.RWMutex + lockGlobalDnsInterfaceMockDelete sync.RWMutex + lockGlobalDnsInterfaceMockDeleteCollection sync.RWMutex + lockGlobalDnsInterfaceMockDeleteNamespaced sync.RWMutex + lockGlobalDnsInterfaceMockGet sync.RWMutex + lockGlobalDnsInterfaceMockGetNamespaced sync.RWMutex + lockGlobalDnsInterfaceMockList sync.RWMutex + lockGlobalDnsInterfaceMockListNamespaced sync.RWMutex + lockGlobalDnsInterfaceMockObjectClient sync.RWMutex + lockGlobalDnsInterfaceMockUpdate sync.RWMutex + lockGlobalDnsInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GlobalDnsInterfaceMock does implement v31.GlobalDnsInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsInterface = &GlobalDnsInterfaceMock{} + +// GlobalDnsInterfaceMock is a mock implementation of v31.GlobalDnsInterface. +// +// func TestSomethingThatUsesGlobalDnsInterface(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsInterface +// mockedGlobalDnsInterface := &GlobalDnsInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GlobalDnsLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GlobalDnsController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.GlobalDns) (*v3.GlobalDns, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GlobalDnsList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.GlobalDns) (*v3.GlobalDns, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGlobalDnsInterface in code that requires v31.GlobalDnsInterface +// // and then make assertions. +// +// } +type GlobalDnsInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GlobalDnsHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GlobalDnsLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GlobalDnsController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.GlobalDns) (*v3.GlobalDns, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.GlobalDns, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDns, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GlobalDnsList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.GlobalDns) (*v3.GlobalDns, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalDnsHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalDnsHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalDns + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalDns + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalDnsInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalDnsInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalDnsInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalDnsInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalDnsInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalDnsInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc + } + lockGlobalDnsInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalDnsInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GlobalDnsInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GlobalDnsInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GlobalDnsInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalDnsInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGlobalDnsInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GlobalDnsInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle + } + lockGlobalDnsInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGlobalDnsInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalDnsInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalDnsInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GlobalDnsInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalDnsInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalDnsInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddClusterScopedHandlerCalls()) +func (mock *GlobalDnsInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsHandlerFunc + } + lockGlobalDnsInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalDnsInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GlobalDnsInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GlobalDnsInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GlobalDnsInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalDnsInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGlobalDnsInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddClusterScopedLifecycleCalls()) +func (mock *GlobalDnsInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsLifecycle + } + lockGlobalDnsInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGlobalDnsInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalDnsInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalDnsInterfaceMock.AddFeatureHandlerFunc: method is nil but GlobalDnsInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalDnsInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddFeatureHandlerCalls()) +func (mock *GlobalDnsInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsHandlerFunc + } + lockGlobalDnsInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalDnsInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GlobalDnsInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GlobalDnsInterfaceMock.AddFeatureLifecycleFunc: method is nil but GlobalDnsInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalDnsInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGlobalDnsInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddFeatureLifecycleCalls()) +func (mock *GlobalDnsInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsLifecycle + } + lockGlobalDnsInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGlobalDnsInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalDnsInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GlobalDnsHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalDnsInterfaceMock.AddHandlerFunc: method is nil but GlobalDnsInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalDnsInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddHandlerCalls()) +func (mock *GlobalDnsInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsHandlerFunc + } + lockGlobalDnsInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalDnsInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GlobalDnsInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GlobalDnsLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GlobalDnsInterfaceMock.AddLifecycleFunc: method is nil but GlobalDnsInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalDnsInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGlobalDnsInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsInterface.AddLifecycleCalls()) +func (mock *GlobalDnsInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsLifecycle + } + lockGlobalDnsInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGlobalDnsInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GlobalDnsInterfaceMock) Controller() v31.GlobalDnsController { + if mock.ControllerFunc == nil { + panic("GlobalDnsInterfaceMock.ControllerFunc: method is nil but GlobalDnsInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGlobalDnsInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGlobalDnsInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGlobalDnsInterface.ControllerCalls()) +func (mock *GlobalDnsInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGlobalDnsInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GlobalDnsInterfaceMock) Create(in1 *v3.GlobalDns) (*v3.GlobalDns, error) { + if mock.CreateFunc == nil { + panic("GlobalDnsInterfaceMock.CreateFunc: method is nil but GlobalDnsInterface.Create was just called") + } + callInfo := struct { + In1 *v3.GlobalDns + }{ + In1: in1, + } + lockGlobalDnsInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGlobalDnsInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGlobalDnsInterface.CreateCalls()) +func (mock *GlobalDnsInterfaceMock) CreateCalls() []struct { + In1 *v3.GlobalDns +} { + var calls []struct { + In1 *v3.GlobalDns + } + lockGlobalDnsInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGlobalDnsInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GlobalDnsInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GlobalDnsInterfaceMock.DeleteFunc: method is nil but GlobalDnsInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGlobalDnsInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGlobalDnsInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGlobalDnsInterface.DeleteCalls()) +func (mock *GlobalDnsInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGlobalDnsInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGlobalDnsInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GlobalDnsInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GlobalDnsInterfaceMock.DeleteCollectionFunc: method is nil but GlobalDnsInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGlobalDnsInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGlobalDnsInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGlobalDnsInterface.DeleteCollectionCalls()) +func (mock *GlobalDnsInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGlobalDnsInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGlobalDnsInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GlobalDnsInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GlobalDnsInterfaceMock.DeleteNamespacedFunc: method is nil but GlobalDnsInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGlobalDnsInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGlobalDnsInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsInterface.DeleteNamespacedCalls()) +func (mock *GlobalDnsInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGlobalDnsInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGlobalDnsInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GlobalDnsInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { + if mock.GetFunc == nil { + panic("GlobalDnsInterfaceMock.GetFunc: method is nil but GlobalDnsInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGlobalDnsInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalDnsInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalDnsInterface.GetCalls()) +func (mock *GlobalDnsInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGlobalDnsInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGlobalDnsInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GlobalDnsInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { + if mock.GetNamespacedFunc == nil { + panic("GlobalDnsInterfaceMock.GetNamespacedFunc: method is nil but GlobalDnsInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGlobalDnsInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGlobalDnsInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsInterface.GetNamespacedCalls()) +func (mock *GlobalDnsInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGlobalDnsInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGlobalDnsInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalDnsInterfaceMock) List(opts metav1.ListOptions) (*v3.GlobalDnsList, error) { + if mock.ListFunc == nil { + panic("GlobalDnsInterfaceMock.ListFunc: method is nil but GlobalDnsInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalDnsInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalDnsInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalDnsInterface.ListCalls()) +func (mock *GlobalDnsInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalDnsInterfaceMockList.RLock() + calls = mock.calls.List + lockGlobalDnsInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GlobalDnsInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsList, error) { + if mock.ListNamespacedFunc == nil { + panic("GlobalDnsInterfaceMock.ListNamespacedFunc: method is nil but GlobalDnsInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGlobalDnsInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGlobalDnsInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsInterface.ListNamespacedCalls()) +func (mock *GlobalDnsInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGlobalDnsInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGlobalDnsInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GlobalDnsInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GlobalDnsInterfaceMock.ObjectClientFunc: method is nil but GlobalDnsInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGlobalDnsInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGlobalDnsInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGlobalDnsInterface.ObjectClientCalls()) +func (mock *GlobalDnsInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGlobalDnsInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GlobalDnsInterfaceMock) Update(in1 *v3.GlobalDns) (*v3.GlobalDns, error) { + if mock.UpdateFunc == nil { + panic("GlobalDnsInterfaceMock.UpdateFunc: method is nil but GlobalDnsInterface.Update was just called") + } + callInfo := struct { + In1 *v3.GlobalDns + }{ + In1: in1, + } + lockGlobalDnsInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGlobalDnsInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGlobalDnsInterface.UpdateCalls()) +func (mock *GlobalDnsInterfaceMock) UpdateCalls() []struct { + In1 *v3.GlobalDns +} { + var calls []struct { + In1 *v3.GlobalDns + } + lockGlobalDnsInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGlobalDnsInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GlobalDnsInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GlobalDnsInterfaceMock.WatchFunc: method is nil but GlobalDnsInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalDnsInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGlobalDnsInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGlobalDnsInterface.WatchCalls()) +func (mock *GlobalDnsInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalDnsInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGlobalDnsInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGlobalDnsesGetterMockGlobalDnses sync.RWMutex +) + +// Ensure, that GlobalDnsesGetterMock does implement v31.GlobalDnsesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsesGetter = &GlobalDnsesGetterMock{} + +// GlobalDnsesGetterMock is a mock implementation of v31.GlobalDnsesGetter. +// +// func TestSomethingThatUsesGlobalDnsesGetter(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsesGetter +// mockedGlobalDnsesGetter := &GlobalDnsesGetterMock{ +// GlobalDnsesFunc: func(namespace string) v31.GlobalDnsInterface { +// panic("mock out the GlobalDnses method") +// }, +// } +// +// // use mockedGlobalDnsesGetter in code that requires v31.GlobalDnsesGetter +// // and then make assertions. +// +// } +type GlobalDnsesGetterMock struct { + // GlobalDnsesFunc mocks the GlobalDnses method. + GlobalDnsesFunc func(namespace string) v31.GlobalDnsInterface + + // calls tracks calls to the methods. + calls struct { + // GlobalDnses holds details about calls to the GlobalDnses method. + GlobalDnses []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// GlobalDnses calls GlobalDnsesFunc. +func (mock *GlobalDnsesGetterMock) GlobalDnses(namespace string) v31.GlobalDnsInterface { + if mock.GlobalDnsesFunc == nil { + panic("GlobalDnsesGetterMock.GlobalDnsesFunc: method is nil but GlobalDnsesGetter.GlobalDnses was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGlobalDnsesGetterMockGlobalDnses.Lock() + mock.calls.GlobalDnses = append(mock.calls.GlobalDnses, callInfo) + lockGlobalDnsesGetterMockGlobalDnses.Unlock() + return mock.GlobalDnsesFunc(namespace) +} + +// GlobalDnsesCalls gets all the calls that were made to GlobalDnses. +// Check the length with: +// +// len(mockedGlobalDnsesGetter.GlobalDnsesCalls()) +func (mock *GlobalDnsesGetterMock) GlobalDnsesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGlobalDnsesGetterMockGlobalDnses.RLock() + calls = mock.calls.GlobalDnses + lockGlobalDnsesGetterMockGlobalDnses.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_provider_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_provider_mock.go new file mode 100644 index 0000000..cfba14d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_dns_provider_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGlobalDnsProviderListerMockGet sync.RWMutex + lockGlobalDnsProviderListerMockList sync.RWMutex +) + +// Ensure, that GlobalDnsProviderListerMock does implement v31.GlobalDnsProviderLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsProviderLister = &GlobalDnsProviderListerMock{} + +// GlobalDnsProviderListerMock is a mock implementation of v31.GlobalDnsProviderLister. +// +// func TestSomethingThatUsesGlobalDnsProviderLister(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsProviderLister +// mockedGlobalDnsProviderLister := &GlobalDnsProviderListerMock{ +// GetFunc: func(namespace string, name string) (*v3.GlobalDnsProvider, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.GlobalDnsProvider, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGlobalDnsProviderLister in code that requires v31.GlobalDnsProviderLister +// // and then make assertions. +// +// } +type GlobalDnsProviderListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.GlobalDnsProvider, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.GlobalDnsProvider, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GlobalDnsProviderListerMock) Get(namespace string, name string) (*v3.GlobalDnsProvider, error) { + if mock.GetFunc == nil { + panic("GlobalDnsProviderListerMock.GetFunc: method is nil but GlobalDnsProviderLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalDnsProviderListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalDnsProviderListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalDnsProviderLister.GetCalls()) +func (mock *GlobalDnsProviderListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalDnsProviderListerMockGet.RLock() + calls = mock.calls.Get + lockGlobalDnsProviderListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalDnsProviderListerMock) List(namespace string, selector labels.Selector) ([]*v3.GlobalDnsProvider, error) { + if mock.ListFunc == nil { + panic("GlobalDnsProviderListerMock.ListFunc: method is nil but GlobalDnsProviderLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGlobalDnsProviderListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalDnsProviderListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalDnsProviderLister.ListCalls()) +func (mock *GlobalDnsProviderListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGlobalDnsProviderListerMockList.RLock() + calls = mock.calls.List + lockGlobalDnsProviderListerMockList.RUnlock() + return calls +} + +var ( + lockGlobalDnsProviderControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalDnsProviderControllerMockAddClusterScopedHandler sync.RWMutex + lockGlobalDnsProviderControllerMockAddFeatureHandler sync.RWMutex + lockGlobalDnsProviderControllerMockAddHandler sync.RWMutex + lockGlobalDnsProviderControllerMockEnqueue sync.RWMutex + lockGlobalDnsProviderControllerMockEnqueueAfter sync.RWMutex + lockGlobalDnsProviderControllerMockGeneric sync.RWMutex + lockGlobalDnsProviderControllerMockInformer sync.RWMutex + lockGlobalDnsProviderControllerMockLister sync.RWMutex +) + +// Ensure, that GlobalDnsProviderControllerMock does implement v31.GlobalDnsProviderController. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsProviderController = &GlobalDnsProviderControllerMock{} + +// GlobalDnsProviderControllerMock is a mock implementation of v31.GlobalDnsProviderController. +// +// func TestSomethingThatUsesGlobalDnsProviderController(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsProviderController +// mockedGlobalDnsProviderController := &GlobalDnsProviderControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GlobalDnsProviderLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGlobalDnsProviderController in code that requires v31.GlobalDnsProviderController +// // and then make assertions. +// +// } +type GlobalDnsProviderControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GlobalDnsProviderHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GlobalDnsProviderLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalDnsProviderHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalDnsProviderHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsProviderHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GlobalDnsProviderHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalDnsProviderControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalDnsProviderControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalDnsProviderController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalDnsProviderControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalDnsProviderControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalDnsProviderControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalDnsProviderControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalDnsProviderControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GlobalDnsProviderHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalDnsProviderControllerMock.AddClusterScopedHandlerFunc: method is nil but GlobalDnsProviderController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalDnsProviderControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalDnsProviderControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.AddClusterScopedHandlerCalls()) +func (mock *GlobalDnsProviderControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalDnsProviderControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalDnsProviderControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalDnsProviderControllerMock.AddFeatureHandlerFunc: method is nil but GlobalDnsProviderController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsProviderControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalDnsProviderControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.AddFeatureHandlerCalls()) +func (mock *GlobalDnsProviderControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalDnsProviderControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalDnsProviderControllerMock) AddHandler(ctx context.Context, name string, handler v31.GlobalDnsProviderHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalDnsProviderControllerMock.AddHandlerFunc: method is nil but GlobalDnsProviderController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGlobalDnsProviderControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalDnsProviderControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.AddHandlerCalls()) +func (mock *GlobalDnsProviderControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalDnsProviderControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GlobalDnsProviderControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GlobalDnsProviderControllerMock.EnqueueFunc: method is nil but GlobalDnsProviderController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalDnsProviderControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGlobalDnsProviderControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.EnqueueCalls()) +func (mock *GlobalDnsProviderControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalDnsProviderControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGlobalDnsProviderControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GlobalDnsProviderControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GlobalDnsProviderControllerMock.EnqueueAfterFunc: method is nil but GlobalDnsProviderController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGlobalDnsProviderControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGlobalDnsProviderControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.EnqueueAfterCalls()) +func (mock *GlobalDnsProviderControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGlobalDnsProviderControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGlobalDnsProviderControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GlobalDnsProviderControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GlobalDnsProviderControllerMock.GenericFunc: method is nil but GlobalDnsProviderController.Generic was just called") + } + callInfo := struct { + }{} + lockGlobalDnsProviderControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGlobalDnsProviderControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.GenericCalls()) +func (mock *GlobalDnsProviderControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsProviderControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGlobalDnsProviderControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GlobalDnsProviderControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GlobalDnsProviderControllerMock.InformerFunc: method is nil but GlobalDnsProviderController.Informer was just called") + } + callInfo := struct { + }{} + lockGlobalDnsProviderControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGlobalDnsProviderControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.InformerCalls()) +func (mock *GlobalDnsProviderControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsProviderControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGlobalDnsProviderControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GlobalDnsProviderControllerMock) Lister() v31.GlobalDnsProviderLister { + if mock.ListerFunc == nil { + panic("GlobalDnsProviderControllerMock.ListerFunc: method is nil but GlobalDnsProviderController.Lister was just called") + } + callInfo := struct { + }{} + lockGlobalDnsProviderControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGlobalDnsProviderControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGlobalDnsProviderController.ListerCalls()) +func (mock *GlobalDnsProviderControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsProviderControllerMockLister.RLock() + calls = mock.calls.Lister + lockGlobalDnsProviderControllerMockLister.RUnlock() + return calls +} + +var ( + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddFeatureHandler sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddHandler sync.RWMutex + lockGlobalDnsProviderInterfaceMockAddLifecycle sync.RWMutex + lockGlobalDnsProviderInterfaceMockController sync.RWMutex + lockGlobalDnsProviderInterfaceMockCreate sync.RWMutex + lockGlobalDnsProviderInterfaceMockDelete sync.RWMutex + lockGlobalDnsProviderInterfaceMockDeleteCollection sync.RWMutex + lockGlobalDnsProviderInterfaceMockDeleteNamespaced sync.RWMutex + lockGlobalDnsProviderInterfaceMockGet sync.RWMutex + lockGlobalDnsProviderInterfaceMockGetNamespaced sync.RWMutex + lockGlobalDnsProviderInterfaceMockList sync.RWMutex + lockGlobalDnsProviderInterfaceMockListNamespaced sync.RWMutex + lockGlobalDnsProviderInterfaceMockObjectClient sync.RWMutex + lockGlobalDnsProviderInterfaceMockUpdate sync.RWMutex + lockGlobalDnsProviderInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GlobalDnsProviderInterfaceMock does implement v31.GlobalDnsProviderInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsProviderInterface = &GlobalDnsProviderInterfaceMock{} + +// GlobalDnsProviderInterfaceMock is a mock implementation of v31.GlobalDnsProviderInterface. +// +// func TestSomethingThatUsesGlobalDnsProviderInterface(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsProviderInterface +// mockedGlobalDnsProviderInterface := &GlobalDnsProviderInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsProviderLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GlobalDnsProviderLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GlobalDnsProviderController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGlobalDnsProviderInterface in code that requires v31.GlobalDnsProviderInterface +// // and then make assertions. +// +// } +type GlobalDnsProviderInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsProviderLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GlobalDnsProviderLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GlobalDnsProviderController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalDnsProviderHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsProviderLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalDnsProviderHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsProviderLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsProviderHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsProviderLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalDnsProviderHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalDnsProviderLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalDnsProvider + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalDnsProvider + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalDnsProviderInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GlobalDnsProviderInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGlobalDnsProviderInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GlobalDnsProviderInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalDnsProviderInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddClusterScopedHandlerCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalDnsProviderInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalDnsProviderLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GlobalDnsProviderInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGlobalDnsProviderInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddClusterScopedLifecycleCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalDnsProviderLifecycle + } + lockGlobalDnsProviderInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGlobalDnsProviderInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddFeatureHandlerFunc: method is nil but GlobalDnsProviderInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsProviderInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalDnsProviderInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddFeatureHandlerCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalDnsProviderInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalDnsProviderLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddFeatureLifecycleFunc: method is nil but GlobalDnsProviderInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsProviderLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalDnsProviderInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGlobalDnsProviderInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddFeatureLifecycleCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsProviderLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalDnsProviderLifecycle + } + lockGlobalDnsProviderInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGlobalDnsProviderInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GlobalDnsProviderHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddHandlerFunc: method is nil but GlobalDnsProviderInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsProviderHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGlobalDnsProviderInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalDnsProviderInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddHandlerCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsProviderHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GlobalDnsProviderHandlerFunc + } + lockGlobalDnsProviderInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalDnsProviderInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GlobalDnsProviderInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GlobalDnsProviderLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GlobalDnsProviderInterfaceMock.AddLifecycleFunc: method is nil but GlobalDnsProviderInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsProviderLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalDnsProviderInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGlobalDnsProviderInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.AddLifecycleCalls()) +func (mock *GlobalDnsProviderInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsProviderLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalDnsProviderLifecycle + } + lockGlobalDnsProviderInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGlobalDnsProviderInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GlobalDnsProviderInterfaceMock) Controller() v31.GlobalDnsProviderController { + if mock.ControllerFunc == nil { + panic("GlobalDnsProviderInterfaceMock.ControllerFunc: method is nil but GlobalDnsProviderInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGlobalDnsProviderInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGlobalDnsProviderInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.ControllerCalls()) +func (mock *GlobalDnsProviderInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsProviderInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGlobalDnsProviderInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GlobalDnsProviderInterfaceMock) Create(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { + if mock.CreateFunc == nil { + panic("GlobalDnsProviderInterfaceMock.CreateFunc: method is nil but GlobalDnsProviderInterface.Create was just called") + } + callInfo := struct { + In1 *v3.GlobalDnsProvider + }{ + In1: in1, + } + lockGlobalDnsProviderInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGlobalDnsProviderInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.CreateCalls()) +func (mock *GlobalDnsProviderInterfaceMock) CreateCalls() []struct { + In1 *v3.GlobalDnsProvider +} { + var calls []struct { + In1 *v3.GlobalDnsProvider + } + lockGlobalDnsProviderInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGlobalDnsProviderInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GlobalDnsProviderInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GlobalDnsProviderInterfaceMock.DeleteFunc: method is nil but GlobalDnsProviderInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGlobalDnsProviderInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGlobalDnsProviderInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.DeleteCalls()) +func (mock *GlobalDnsProviderInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGlobalDnsProviderInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGlobalDnsProviderInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GlobalDnsProviderInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GlobalDnsProviderInterfaceMock.DeleteCollectionFunc: method is nil but GlobalDnsProviderInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGlobalDnsProviderInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGlobalDnsProviderInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.DeleteCollectionCalls()) +func (mock *GlobalDnsProviderInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGlobalDnsProviderInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGlobalDnsProviderInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GlobalDnsProviderInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GlobalDnsProviderInterfaceMock.DeleteNamespacedFunc: method is nil but GlobalDnsProviderInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGlobalDnsProviderInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGlobalDnsProviderInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.DeleteNamespacedCalls()) +func (mock *GlobalDnsProviderInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGlobalDnsProviderInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGlobalDnsProviderInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GlobalDnsProviderInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { + if mock.GetFunc == nil { + panic("GlobalDnsProviderInterfaceMock.GetFunc: method is nil but GlobalDnsProviderInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGlobalDnsProviderInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalDnsProviderInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.GetCalls()) +func (mock *GlobalDnsProviderInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGlobalDnsProviderInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGlobalDnsProviderInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GlobalDnsProviderInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { + if mock.GetNamespacedFunc == nil { + panic("GlobalDnsProviderInterfaceMock.GetNamespacedFunc: method is nil but GlobalDnsProviderInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGlobalDnsProviderInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGlobalDnsProviderInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.GetNamespacedCalls()) +func (mock *GlobalDnsProviderInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGlobalDnsProviderInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGlobalDnsProviderInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalDnsProviderInterfaceMock) List(opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { + if mock.ListFunc == nil { + panic("GlobalDnsProviderInterfaceMock.ListFunc: method is nil but GlobalDnsProviderInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalDnsProviderInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalDnsProviderInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.ListCalls()) +func (mock *GlobalDnsProviderInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalDnsProviderInterfaceMockList.RLock() + calls = mock.calls.List + lockGlobalDnsProviderInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GlobalDnsProviderInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { + if mock.ListNamespacedFunc == nil { + panic("GlobalDnsProviderInterfaceMock.ListNamespacedFunc: method is nil but GlobalDnsProviderInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGlobalDnsProviderInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGlobalDnsProviderInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.ListNamespacedCalls()) +func (mock *GlobalDnsProviderInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGlobalDnsProviderInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGlobalDnsProviderInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GlobalDnsProviderInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GlobalDnsProviderInterfaceMock.ObjectClientFunc: method is nil but GlobalDnsProviderInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGlobalDnsProviderInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGlobalDnsProviderInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.ObjectClientCalls()) +func (mock *GlobalDnsProviderInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGlobalDnsProviderInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGlobalDnsProviderInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GlobalDnsProviderInterfaceMock) Update(in1 *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { + if mock.UpdateFunc == nil { + panic("GlobalDnsProviderInterfaceMock.UpdateFunc: method is nil but GlobalDnsProviderInterface.Update was just called") + } + callInfo := struct { + In1 *v3.GlobalDnsProvider + }{ + In1: in1, + } + lockGlobalDnsProviderInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGlobalDnsProviderInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.UpdateCalls()) +func (mock *GlobalDnsProviderInterfaceMock) UpdateCalls() []struct { + In1 *v3.GlobalDnsProvider +} { + var calls []struct { + In1 *v3.GlobalDnsProvider + } + lockGlobalDnsProviderInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGlobalDnsProviderInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GlobalDnsProviderInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GlobalDnsProviderInterfaceMock.WatchFunc: method is nil but GlobalDnsProviderInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalDnsProviderInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGlobalDnsProviderInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGlobalDnsProviderInterface.WatchCalls()) +func (mock *GlobalDnsProviderInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalDnsProviderInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGlobalDnsProviderInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGlobalDnsProvidersGetterMockGlobalDnsProviders sync.RWMutex +) + +// Ensure, that GlobalDnsProvidersGetterMock does implement v31.GlobalDnsProvidersGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalDnsProvidersGetter = &GlobalDnsProvidersGetterMock{} + +// GlobalDnsProvidersGetterMock is a mock implementation of v31.GlobalDnsProvidersGetter. +// +// func TestSomethingThatUsesGlobalDnsProvidersGetter(t *testing.T) { +// +// // make and configure a mocked v31.GlobalDnsProvidersGetter +// mockedGlobalDnsProvidersGetter := &GlobalDnsProvidersGetterMock{ +// GlobalDnsProvidersFunc: func(namespace string) v31.GlobalDnsProviderInterface { +// panic("mock out the GlobalDnsProviders method") +// }, +// } +// +// // use mockedGlobalDnsProvidersGetter in code that requires v31.GlobalDnsProvidersGetter +// // and then make assertions. +// +// } +type GlobalDnsProvidersGetterMock struct { + // GlobalDnsProvidersFunc mocks the GlobalDnsProviders method. + GlobalDnsProvidersFunc func(namespace string) v31.GlobalDnsProviderInterface + + // calls tracks calls to the methods. + calls struct { + // GlobalDnsProviders holds details about calls to the GlobalDnsProviders method. + GlobalDnsProviders []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// GlobalDnsProviders calls GlobalDnsProvidersFunc. +func (mock *GlobalDnsProvidersGetterMock) GlobalDnsProviders(namespace string) v31.GlobalDnsProviderInterface { + if mock.GlobalDnsProvidersFunc == nil { + panic("GlobalDnsProvidersGetterMock.GlobalDnsProvidersFunc: method is nil but GlobalDnsProvidersGetter.GlobalDnsProviders was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGlobalDnsProvidersGetterMockGlobalDnsProviders.Lock() + mock.calls.GlobalDnsProviders = append(mock.calls.GlobalDnsProviders, callInfo) + lockGlobalDnsProvidersGetterMockGlobalDnsProviders.Unlock() + return mock.GlobalDnsProvidersFunc(namespace) +} + +// GlobalDnsProvidersCalls gets all the calls that were made to GlobalDnsProviders. +// Check the length with: +// +// len(mockedGlobalDnsProvidersGetter.GlobalDnsProvidersCalls()) +func (mock *GlobalDnsProvidersGetterMock) GlobalDnsProvidersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGlobalDnsProvidersGetterMockGlobalDnsProviders.RLock() + calls = mock.calls.GlobalDnsProviders + lockGlobalDnsProvidersGetterMockGlobalDnsProviders.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_binding_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_binding_mock.go new file mode 100644 index 0000000..ca6d1da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_binding_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGlobalRoleBindingListerMockGet sync.RWMutex + lockGlobalRoleBindingListerMockList sync.RWMutex +) + +// Ensure, that GlobalRoleBindingListerMock does implement v31.GlobalRoleBindingLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleBindingLister = &GlobalRoleBindingListerMock{} + +// GlobalRoleBindingListerMock is a mock implementation of v31.GlobalRoleBindingLister. +// +// func TestSomethingThatUsesGlobalRoleBindingLister(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleBindingLister +// mockedGlobalRoleBindingLister := &GlobalRoleBindingListerMock{ +// GetFunc: func(namespace string, name string) (*v3.GlobalRoleBinding, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.GlobalRoleBinding, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGlobalRoleBindingLister in code that requires v31.GlobalRoleBindingLister +// // and then make assertions. +// +// } +type GlobalRoleBindingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.GlobalRoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.GlobalRoleBinding, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GlobalRoleBindingListerMock) Get(namespace string, name string) (*v3.GlobalRoleBinding, error) { + if mock.GetFunc == nil { + panic("GlobalRoleBindingListerMock.GetFunc: method is nil but GlobalRoleBindingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalRoleBindingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalRoleBindingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalRoleBindingLister.GetCalls()) +func (mock *GlobalRoleBindingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalRoleBindingListerMockGet.RLock() + calls = mock.calls.Get + lockGlobalRoleBindingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalRoleBindingListerMock) List(namespace string, selector labels.Selector) ([]*v3.GlobalRoleBinding, error) { + if mock.ListFunc == nil { + panic("GlobalRoleBindingListerMock.ListFunc: method is nil but GlobalRoleBindingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGlobalRoleBindingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalRoleBindingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalRoleBindingLister.ListCalls()) +func (mock *GlobalRoleBindingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGlobalRoleBindingListerMockList.RLock() + calls = mock.calls.List + lockGlobalRoleBindingListerMockList.RUnlock() + return calls +} + +var ( + lockGlobalRoleBindingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalRoleBindingControllerMockAddClusterScopedHandler sync.RWMutex + lockGlobalRoleBindingControllerMockAddFeatureHandler sync.RWMutex + lockGlobalRoleBindingControllerMockAddHandler sync.RWMutex + lockGlobalRoleBindingControllerMockEnqueue sync.RWMutex + lockGlobalRoleBindingControllerMockEnqueueAfter sync.RWMutex + lockGlobalRoleBindingControllerMockGeneric sync.RWMutex + lockGlobalRoleBindingControllerMockInformer sync.RWMutex + lockGlobalRoleBindingControllerMockLister sync.RWMutex +) + +// Ensure, that GlobalRoleBindingControllerMock does implement v31.GlobalRoleBindingController. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleBindingController = &GlobalRoleBindingControllerMock{} + +// GlobalRoleBindingControllerMock is a mock implementation of v31.GlobalRoleBindingController. +// +// func TestSomethingThatUsesGlobalRoleBindingController(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleBindingController +// mockedGlobalRoleBindingController := &GlobalRoleBindingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GlobalRoleBindingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGlobalRoleBindingController in code that requires v31.GlobalRoleBindingController +// // and then make assertions. +// +// } +type GlobalRoleBindingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GlobalRoleBindingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GlobalRoleBindingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalRoleBindingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalRoleBindingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleBindingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GlobalRoleBindingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalRoleBindingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalRoleBindingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalRoleBindingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalRoleBindingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalRoleBindingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalRoleBindingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalRoleBindingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalRoleBindingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalRoleBindingControllerMock.AddClusterScopedHandlerFunc: method is nil but GlobalRoleBindingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalRoleBindingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalRoleBindingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.AddClusterScopedHandlerCalls()) +func (mock *GlobalRoleBindingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalRoleBindingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalRoleBindingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalRoleBindingControllerMock.AddFeatureHandlerFunc: method is nil but GlobalRoleBindingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleBindingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalRoleBindingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.AddFeatureHandlerCalls()) +func (mock *GlobalRoleBindingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalRoleBindingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalRoleBindingControllerMock) AddHandler(ctx context.Context, name string, handler v31.GlobalRoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalRoleBindingControllerMock.AddHandlerFunc: method is nil but GlobalRoleBindingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGlobalRoleBindingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalRoleBindingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.AddHandlerCalls()) +func (mock *GlobalRoleBindingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalRoleBindingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GlobalRoleBindingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GlobalRoleBindingControllerMock.EnqueueFunc: method is nil but GlobalRoleBindingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalRoleBindingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGlobalRoleBindingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.EnqueueCalls()) +func (mock *GlobalRoleBindingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalRoleBindingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGlobalRoleBindingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GlobalRoleBindingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GlobalRoleBindingControllerMock.EnqueueAfterFunc: method is nil but GlobalRoleBindingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGlobalRoleBindingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGlobalRoleBindingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.EnqueueAfterCalls()) +func (mock *GlobalRoleBindingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGlobalRoleBindingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGlobalRoleBindingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GlobalRoleBindingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GlobalRoleBindingControllerMock.GenericFunc: method is nil but GlobalRoleBindingController.Generic was just called") + } + callInfo := struct { + }{} + lockGlobalRoleBindingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGlobalRoleBindingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.GenericCalls()) +func (mock *GlobalRoleBindingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleBindingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGlobalRoleBindingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GlobalRoleBindingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GlobalRoleBindingControllerMock.InformerFunc: method is nil but GlobalRoleBindingController.Informer was just called") + } + callInfo := struct { + }{} + lockGlobalRoleBindingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGlobalRoleBindingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.InformerCalls()) +func (mock *GlobalRoleBindingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleBindingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGlobalRoleBindingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GlobalRoleBindingControllerMock) Lister() v31.GlobalRoleBindingLister { + if mock.ListerFunc == nil { + panic("GlobalRoleBindingControllerMock.ListerFunc: method is nil but GlobalRoleBindingController.Lister was just called") + } + callInfo := struct { + }{} + lockGlobalRoleBindingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGlobalRoleBindingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGlobalRoleBindingController.ListerCalls()) +func (mock *GlobalRoleBindingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleBindingControllerMockLister.RLock() + calls = mock.calls.Lister + lockGlobalRoleBindingControllerMockLister.RUnlock() + return calls +} + +var ( + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddFeatureHandler sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddHandler sync.RWMutex + lockGlobalRoleBindingInterfaceMockAddLifecycle sync.RWMutex + lockGlobalRoleBindingInterfaceMockController sync.RWMutex + lockGlobalRoleBindingInterfaceMockCreate sync.RWMutex + lockGlobalRoleBindingInterfaceMockDelete sync.RWMutex + lockGlobalRoleBindingInterfaceMockDeleteCollection sync.RWMutex + lockGlobalRoleBindingInterfaceMockDeleteNamespaced sync.RWMutex + lockGlobalRoleBindingInterfaceMockGet sync.RWMutex + lockGlobalRoleBindingInterfaceMockGetNamespaced sync.RWMutex + lockGlobalRoleBindingInterfaceMockList sync.RWMutex + lockGlobalRoleBindingInterfaceMockListNamespaced sync.RWMutex + lockGlobalRoleBindingInterfaceMockObjectClient sync.RWMutex + lockGlobalRoleBindingInterfaceMockUpdate sync.RWMutex + lockGlobalRoleBindingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GlobalRoleBindingInterfaceMock does implement v31.GlobalRoleBindingInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleBindingInterface = &GlobalRoleBindingInterfaceMock{} + +// GlobalRoleBindingInterfaceMock is a mock implementation of v31.GlobalRoleBindingInterface. +// +// func TestSomethingThatUsesGlobalRoleBindingInterface(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleBindingInterface +// mockedGlobalRoleBindingInterface := &GlobalRoleBindingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleBindingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GlobalRoleBindingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GlobalRoleBindingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGlobalRoleBindingInterface in code that requires v31.GlobalRoleBindingInterface +// // and then make assertions. +// +// } +type GlobalRoleBindingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleBindingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GlobalRoleBindingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GlobalRoleBindingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalRoleBindingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleBindingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalRoleBindingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleBindingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleBindingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleBindingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleBindingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleBindingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalRoleBinding + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalRoleBinding + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalRoleBindingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GlobalRoleBindingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGlobalRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GlobalRoleBindingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalRoleBindingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddClusterScopedHandlerCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalRoleBindingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleBindingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GlobalRoleBindingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGlobalRoleBindingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddClusterScopedLifecycleCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleBindingLifecycle + } + lockGlobalRoleBindingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGlobalRoleBindingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddFeatureHandlerFunc: method is nil but GlobalRoleBindingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleBindingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalRoleBindingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddFeatureHandlerCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalRoleBindingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleBindingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddFeatureLifecycleFunc: method is nil but GlobalRoleBindingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalRoleBindingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGlobalRoleBindingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddFeatureLifecycleCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleBindingLifecycle + } + lockGlobalRoleBindingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGlobalRoleBindingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GlobalRoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddHandlerFunc: method is nil but GlobalRoleBindingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleBindingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalRoleBindingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddHandlerCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleBindingHandlerFunc + } + lockGlobalRoleBindingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalRoleBindingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GlobalRoleBindingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GlobalRoleBindingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GlobalRoleBindingInterfaceMock.AddLifecycleFunc: method is nil but GlobalRoleBindingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalRoleBindingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGlobalRoleBindingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.AddLifecycleCalls()) +func (mock *GlobalRoleBindingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleBindingLifecycle + } + lockGlobalRoleBindingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGlobalRoleBindingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GlobalRoleBindingInterfaceMock) Controller() v31.GlobalRoleBindingController { + if mock.ControllerFunc == nil { + panic("GlobalRoleBindingInterfaceMock.ControllerFunc: method is nil but GlobalRoleBindingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGlobalRoleBindingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGlobalRoleBindingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.ControllerCalls()) +func (mock *GlobalRoleBindingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleBindingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGlobalRoleBindingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GlobalRoleBindingInterfaceMock) Create(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { + if mock.CreateFunc == nil { + panic("GlobalRoleBindingInterfaceMock.CreateFunc: method is nil but GlobalRoleBindingInterface.Create was just called") + } + callInfo := struct { + In1 *v3.GlobalRoleBinding + }{ + In1: in1, + } + lockGlobalRoleBindingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGlobalRoleBindingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.CreateCalls()) +func (mock *GlobalRoleBindingInterfaceMock) CreateCalls() []struct { + In1 *v3.GlobalRoleBinding +} { + var calls []struct { + In1 *v3.GlobalRoleBinding + } + lockGlobalRoleBindingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGlobalRoleBindingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GlobalRoleBindingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GlobalRoleBindingInterfaceMock.DeleteFunc: method is nil but GlobalRoleBindingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGlobalRoleBindingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGlobalRoleBindingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.DeleteCalls()) +func (mock *GlobalRoleBindingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGlobalRoleBindingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGlobalRoleBindingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GlobalRoleBindingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GlobalRoleBindingInterfaceMock.DeleteCollectionFunc: method is nil but GlobalRoleBindingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGlobalRoleBindingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGlobalRoleBindingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.DeleteCollectionCalls()) +func (mock *GlobalRoleBindingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGlobalRoleBindingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGlobalRoleBindingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GlobalRoleBindingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GlobalRoleBindingInterfaceMock.DeleteNamespacedFunc: method is nil but GlobalRoleBindingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGlobalRoleBindingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGlobalRoleBindingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.DeleteNamespacedCalls()) +func (mock *GlobalRoleBindingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGlobalRoleBindingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGlobalRoleBindingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GlobalRoleBindingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { + if mock.GetFunc == nil { + panic("GlobalRoleBindingInterfaceMock.GetFunc: method is nil but GlobalRoleBindingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGlobalRoleBindingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalRoleBindingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.GetCalls()) +func (mock *GlobalRoleBindingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGlobalRoleBindingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGlobalRoleBindingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GlobalRoleBindingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { + if mock.GetNamespacedFunc == nil { + panic("GlobalRoleBindingInterfaceMock.GetNamespacedFunc: method is nil but GlobalRoleBindingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGlobalRoleBindingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGlobalRoleBindingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.GetNamespacedCalls()) +func (mock *GlobalRoleBindingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGlobalRoleBindingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGlobalRoleBindingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalRoleBindingInterfaceMock) List(opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { + if mock.ListFunc == nil { + panic("GlobalRoleBindingInterfaceMock.ListFunc: method is nil but GlobalRoleBindingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalRoleBindingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalRoleBindingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.ListCalls()) +func (mock *GlobalRoleBindingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalRoleBindingInterfaceMockList.RLock() + calls = mock.calls.List + lockGlobalRoleBindingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GlobalRoleBindingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { + if mock.ListNamespacedFunc == nil { + panic("GlobalRoleBindingInterfaceMock.ListNamespacedFunc: method is nil but GlobalRoleBindingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGlobalRoleBindingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGlobalRoleBindingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.ListNamespacedCalls()) +func (mock *GlobalRoleBindingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGlobalRoleBindingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGlobalRoleBindingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GlobalRoleBindingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GlobalRoleBindingInterfaceMock.ObjectClientFunc: method is nil but GlobalRoleBindingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGlobalRoleBindingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGlobalRoleBindingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.ObjectClientCalls()) +func (mock *GlobalRoleBindingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleBindingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGlobalRoleBindingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GlobalRoleBindingInterfaceMock) Update(in1 *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { + if mock.UpdateFunc == nil { + panic("GlobalRoleBindingInterfaceMock.UpdateFunc: method is nil but GlobalRoleBindingInterface.Update was just called") + } + callInfo := struct { + In1 *v3.GlobalRoleBinding + }{ + In1: in1, + } + lockGlobalRoleBindingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGlobalRoleBindingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.UpdateCalls()) +func (mock *GlobalRoleBindingInterfaceMock) UpdateCalls() []struct { + In1 *v3.GlobalRoleBinding +} { + var calls []struct { + In1 *v3.GlobalRoleBinding + } + lockGlobalRoleBindingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGlobalRoleBindingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GlobalRoleBindingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GlobalRoleBindingInterfaceMock.WatchFunc: method is nil but GlobalRoleBindingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalRoleBindingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGlobalRoleBindingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGlobalRoleBindingInterface.WatchCalls()) +func (mock *GlobalRoleBindingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalRoleBindingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGlobalRoleBindingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGlobalRoleBindingsGetterMockGlobalRoleBindings sync.RWMutex +) + +// Ensure, that GlobalRoleBindingsGetterMock does implement v31.GlobalRoleBindingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleBindingsGetter = &GlobalRoleBindingsGetterMock{} + +// GlobalRoleBindingsGetterMock is a mock implementation of v31.GlobalRoleBindingsGetter. +// +// func TestSomethingThatUsesGlobalRoleBindingsGetter(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleBindingsGetter +// mockedGlobalRoleBindingsGetter := &GlobalRoleBindingsGetterMock{ +// GlobalRoleBindingsFunc: func(namespace string) v31.GlobalRoleBindingInterface { +// panic("mock out the GlobalRoleBindings method") +// }, +// } +// +// // use mockedGlobalRoleBindingsGetter in code that requires v31.GlobalRoleBindingsGetter +// // and then make assertions. +// +// } +type GlobalRoleBindingsGetterMock struct { + // GlobalRoleBindingsFunc mocks the GlobalRoleBindings method. + GlobalRoleBindingsFunc func(namespace string) v31.GlobalRoleBindingInterface + + // calls tracks calls to the methods. + calls struct { + // GlobalRoleBindings holds details about calls to the GlobalRoleBindings method. + GlobalRoleBindings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// GlobalRoleBindings calls GlobalRoleBindingsFunc. +func (mock *GlobalRoleBindingsGetterMock) GlobalRoleBindings(namespace string) v31.GlobalRoleBindingInterface { + if mock.GlobalRoleBindingsFunc == nil { + panic("GlobalRoleBindingsGetterMock.GlobalRoleBindingsFunc: method is nil but GlobalRoleBindingsGetter.GlobalRoleBindings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGlobalRoleBindingsGetterMockGlobalRoleBindings.Lock() + mock.calls.GlobalRoleBindings = append(mock.calls.GlobalRoleBindings, callInfo) + lockGlobalRoleBindingsGetterMockGlobalRoleBindings.Unlock() + return mock.GlobalRoleBindingsFunc(namespace) +} + +// GlobalRoleBindingsCalls gets all the calls that were made to GlobalRoleBindings. +// Check the length with: +// +// len(mockedGlobalRoleBindingsGetter.GlobalRoleBindingsCalls()) +func (mock *GlobalRoleBindingsGetterMock) GlobalRoleBindingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGlobalRoleBindingsGetterMockGlobalRoleBindings.RLock() + calls = mock.calls.GlobalRoleBindings + lockGlobalRoleBindingsGetterMockGlobalRoleBindings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_mock.go new file mode 100644 index 0000000..d169de9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_global_role_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGlobalRoleListerMockGet sync.RWMutex + lockGlobalRoleListerMockList sync.RWMutex +) + +// Ensure, that GlobalRoleListerMock does implement v31.GlobalRoleLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleLister = &GlobalRoleListerMock{} + +// GlobalRoleListerMock is a mock implementation of v31.GlobalRoleLister. +// +// func TestSomethingThatUsesGlobalRoleLister(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleLister +// mockedGlobalRoleLister := &GlobalRoleListerMock{ +// GetFunc: func(namespace string, name string) (*v3.GlobalRole, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.GlobalRole, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGlobalRoleLister in code that requires v31.GlobalRoleLister +// // and then make assertions. +// +// } +type GlobalRoleListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.GlobalRole, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.GlobalRole, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GlobalRoleListerMock) Get(namespace string, name string) (*v3.GlobalRole, error) { + if mock.GetFunc == nil { + panic("GlobalRoleListerMock.GetFunc: method is nil but GlobalRoleLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalRoleListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalRoleListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalRoleLister.GetCalls()) +func (mock *GlobalRoleListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalRoleListerMockGet.RLock() + calls = mock.calls.Get + lockGlobalRoleListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalRoleListerMock) List(namespace string, selector labels.Selector) ([]*v3.GlobalRole, error) { + if mock.ListFunc == nil { + panic("GlobalRoleListerMock.ListFunc: method is nil but GlobalRoleLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGlobalRoleListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalRoleListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalRoleLister.ListCalls()) +func (mock *GlobalRoleListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGlobalRoleListerMockList.RLock() + calls = mock.calls.List + lockGlobalRoleListerMockList.RUnlock() + return calls +} + +var ( + lockGlobalRoleControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalRoleControllerMockAddClusterScopedHandler sync.RWMutex + lockGlobalRoleControllerMockAddFeatureHandler sync.RWMutex + lockGlobalRoleControllerMockAddHandler sync.RWMutex + lockGlobalRoleControllerMockEnqueue sync.RWMutex + lockGlobalRoleControllerMockEnqueueAfter sync.RWMutex + lockGlobalRoleControllerMockGeneric sync.RWMutex + lockGlobalRoleControllerMockInformer sync.RWMutex + lockGlobalRoleControllerMockLister sync.RWMutex +) + +// Ensure, that GlobalRoleControllerMock does implement v31.GlobalRoleController. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleController = &GlobalRoleControllerMock{} + +// GlobalRoleControllerMock is a mock implementation of v31.GlobalRoleController. +// +// func TestSomethingThatUsesGlobalRoleController(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleController +// mockedGlobalRoleController := &GlobalRoleControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GlobalRoleLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGlobalRoleController in code that requires v31.GlobalRoleController +// // and then make assertions. +// +// } +type GlobalRoleControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GlobalRoleHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GlobalRoleLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalRoleHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GlobalRoleHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GlobalRoleHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalRoleControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalRoleControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalRoleController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalRoleControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalRoleControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalRoleControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc + } + lockGlobalRoleControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalRoleControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalRoleControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GlobalRoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalRoleControllerMock.AddClusterScopedHandlerFunc: method is nil but GlobalRoleController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGlobalRoleControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalRoleControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalRoleController.AddClusterScopedHandlerCalls()) +func (mock *GlobalRoleControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GlobalRoleHandlerFunc + } + lockGlobalRoleControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalRoleControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalRoleControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalRoleControllerMock.AddFeatureHandlerFunc: method is nil but GlobalRoleController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalRoleControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleController.AddFeatureHandlerCalls()) +func (mock *GlobalRoleControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc + } + lockGlobalRoleControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalRoleControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalRoleControllerMock) AddHandler(ctx context.Context, name string, handler v31.GlobalRoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalRoleControllerMock.AddHandlerFunc: method is nil but GlobalRoleController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGlobalRoleControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalRoleControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalRoleController.AddHandlerCalls()) +func (mock *GlobalRoleControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GlobalRoleHandlerFunc + } + lockGlobalRoleControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalRoleControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GlobalRoleControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GlobalRoleControllerMock.EnqueueFunc: method is nil but GlobalRoleController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGlobalRoleControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGlobalRoleControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGlobalRoleController.EnqueueCalls()) +func (mock *GlobalRoleControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGlobalRoleControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGlobalRoleControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GlobalRoleControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GlobalRoleControllerMock.EnqueueAfterFunc: method is nil but GlobalRoleController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGlobalRoleControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGlobalRoleControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGlobalRoleController.EnqueueAfterCalls()) +func (mock *GlobalRoleControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGlobalRoleControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGlobalRoleControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GlobalRoleControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GlobalRoleControllerMock.GenericFunc: method is nil but GlobalRoleController.Generic was just called") + } + callInfo := struct { + }{} + lockGlobalRoleControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGlobalRoleControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGlobalRoleController.GenericCalls()) +func (mock *GlobalRoleControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGlobalRoleControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GlobalRoleControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GlobalRoleControllerMock.InformerFunc: method is nil but GlobalRoleController.Informer was just called") + } + callInfo := struct { + }{} + lockGlobalRoleControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGlobalRoleControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGlobalRoleController.InformerCalls()) +func (mock *GlobalRoleControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGlobalRoleControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GlobalRoleControllerMock) Lister() v31.GlobalRoleLister { + if mock.ListerFunc == nil { + panic("GlobalRoleControllerMock.ListerFunc: method is nil but GlobalRoleController.Lister was just called") + } + callInfo := struct { + }{} + lockGlobalRoleControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGlobalRoleControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGlobalRoleController.ListerCalls()) +func (mock *GlobalRoleControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleControllerMockLister.RLock() + calls = mock.calls.Lister + lockGlobalRoleControllerMockLister.RUnlock() + return calls +} + +var ( + lockGlobalRoleInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGlobalRoleInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGlobalRoleInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGlobalRoleInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGlobalRoleInterfaceMockAddFeatureHandler sync.RWMutex + lockGlobalRoleInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGlobalRoleInterfaceMockAddHandler sync.RWMutex + lockGlobalRoleInterfaceMockAddLifecycle sync.RWMutex + lockGlobalRoleInterfaceMockController sync.RWMutex + lockGlobalRoleInterfaceMockCreate sync.RWMutex + lockGlobalRoleInterfaceMockDelete sync.RWMutex + lockGlobalRoleInterfaceMockDeleteCollection sync.RWMutex + lockGlobalRoleInterfaceMockDeleteNamespaced sync.RWMutex + lockGlobalRoleInterfaceMockGet sync.RWMutex + lockGlobalRoleInterfaceMockGetNamespaced sync.RWMutex + lockGlobalRoleInterfaceMockList sync.RWMutex + lockGlobalRoleInterfaceMockListNamespaced sync.RWMutex + lockGlobalRoleInterfaceMockObjectClient sync.RWMutex + lockGlobalRoleInterfaceMockUpdate sync.RWMutex + lockGlobalRoleInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GlobalRoleInterfaceMock does implement v31.GlobalRoleInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRoleInterface = &GlobalRoleInterfaceMock{} + +// GlobalRoleInterfaceMock is a mock implementation of v31.GlobalRoleInterface. +// +// func TestSomethingThatUsesGlobalRoleInterface(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRoleInterface +// mockedGlobalRoleInterface := &GlobalRoleInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GlobalRoleLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GlobalRoleController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.GlobalRole) (*v3.GlobalRole, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GlobalRoleList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.GlobalRole) (*v3.GlobalRole, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGlobalRoleInterface in code that requires v31.GlobalRoleInterface +// // and then make assertions. +// +// } +type GlobalRoleInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GlobalRoleHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GlobalRoleLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GlobalRoleController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.GlobalRole) (*v3.GlobalRole, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.GlobalRole, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRole, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GlobalRoleList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.GlobalRole) (*v3.GlobalRole, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalRoleHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GlobalRoleHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GlobalRoleHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GlobalRoleLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalRole + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.GlobalRole + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GlobalRoleInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GlobalRoleInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GlobalRoleInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalRoleInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGlobalRoleInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GlobalRoleInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc + } + lockGlobalRoleInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGlobalRoleInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GlobalRoleInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GlobalRoleInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GlobalRoleInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalRoleInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGlobalRoleInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GlobalRoleInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle + } + lockGlobalRoleInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGlobalRoleInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GlobalRoleInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GlobalRoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GlobalRoleInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GlobalRoleInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGlobalRoleInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGlobalRoleInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddClusterScopedHandlerCalls()) +func (mock *GlobalRoleInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GlobalRoleHandlerFunc + } + lockGlobalRoleInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGlobalRoleInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GlobalRoleInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GlobalRoleLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GlobalRoleInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GlobalRoleInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGlobalRoleInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGlobalRoleInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddClusterScopedLifecycleCalls()) +func (mock *GlobalRoleInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GlobalRoleLifecycle + } + lockGlobalRoleInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGlobalRoleInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GlobalRoleInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GlobalRoleInterfaceMock.AddFeatureHandlerFunc: method is nil but GlobalRoleInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGlobalRoleInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddFeatureHandlerCalls()) +func (mock *GlobalRoleInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GlobalRoleHandlerFunc + } + lockGlobalRoleInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGlobalRoleInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GlobalRoleInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GlobalRoleLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GlobalRoleInterfaceMock.AddFeatureLifecycleFunc: method is nil but GlobalRoleInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalRoleInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGlobalRoleInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddFeatureLifecycleCalls()) +func (mock *GlobalRoleInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GlobalRoleLifecycle + } + lockGlobalRoleInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGlobalRoleInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GlobalRoleInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GlobalRoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GlobalRoleInterfaceMock.AddHandlerFunc: method is nil but GlobalRoleInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGlobalRoleInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGlobalRoleInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddHandlerCalls()) +func (mock *GlobalRoleInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GlobalRoleHandlerFunc + } + lockGlobalRoleInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGlobalRoleInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GlobalRoleInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GlobalRoleLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GlobalRoleInterfaceMock.AddLifecycleFunc: method is nil but GlobalRoleInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGlobalRoleInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGlobalRoleInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGlobalRoleInterface.AddLifecycleCalls()) +func (mock *GlobalRoleInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GlobalRoleLifecycle + } + lockGlobalRoleInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGlobalRoleInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GlobalRoleInterfaceMock) Controller() v31.GlobalRoleController { + if mock.ControllerFunc == nil { + panic("GlobalRoleInterfaceMock.ControllerFunc: method is nil but GlobalRoleInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGlobalRoleInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGlobalRoleInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGlobalRoleInterface.ControllerCalls()) +func (mock *GlobalRoleInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGlobalRoleInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GlobalRoleInterfaceMock) Create(in1 *v3.GlobalRole) (*v3.GlobalRole, error) { + if mock.CreateFunc == nil { + panic("GlobalRoleInterfaceMock.CreateFunc: method is nil but GlobalRoleInterface.Create was just called") + } + callInfo := struct { + In1 *v3.GlobalRole + }{ + In1: in1, + } + lockGlobalRoleInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGlobalRoleInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGlobalRoleInterface.CreateCalls()) +func (mock *GlobalRoleInterfaceMock) CreateCalls() []struct { + In1 *v3.GlobalRole +} { + var calls []struct { + In1 *v3.GlobalRole + } + lockGlobalRoleInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGlobalRoleInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GlobalRoleInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GlobalRoleInterfaceMock.DeleteFunc: method is nil but GlobalRoleInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGlobalRoleInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGlobalRoleInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGlobalRoleInterface.DeleteCalls()) +func (mock *GlobalRoleInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGlobalRoleInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGlobalRoleInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GlobalRoleInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GlobalRoleInterfaceMock.DeleteCollectionFunc: method is nil but GlobalRoleInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGlobalRoleInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGlobalRoleInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGlobalRoleInterface.DeleteCollectionCalls()) +func (mock *GlobalRoleInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGlobalRoleInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGlobalRoleInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GlobalRoleInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GlobalRoleInterfaceMock.DeleteNamespacedFunc: method is nil but GlobalRoleInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGlobalRoleInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGlobalRoleInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleInterface.DeleteNamespacedCalls()) +func (mock *GlobalRoleInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGlobalRoleInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGlobalRoleInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GlobalRoleInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { + if mock.GetFunc == nil { + panic("GlobalRoleInterfaceMock.GetFunc: method is nil but GlobalRoleInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGlobalRoleInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGlobalRoleInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGlobalRoleInterface.GetCalls()) +func (mock *GlobalRoleInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGlobalRoleInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGlobalRoleInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GlobalRoleInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { + if mock.GetNamespacedFunc == nil { + panic("GlobalRoleInterfaceMock.GetNamespacedFunc: method is nil but GlobalRoleInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGlobalRoleInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGlobalRoleInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleInterface.GetNamespacedCalls()) +func (mock *GlobalRoleInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGlobalRoleInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGlobalRoleInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GlobalRoleInterfaceMock) List(opts metav1.ListOptions) (*v3.GlobalRoleList, error) { + if mock.ListFunc == nil { + panic("GlobalRoleInterfaceMock.ListFunc: method is nil but GlobalRoleInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalRoleInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGlobalRoleInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGlobalRoleInterface.ListCalls()) +func (mock *GlobalRoleInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalRoleInterfaceMockList.RLock() + calls = mock.calls.List + lockGlobalRoleInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GlobalRoleInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleList, error) { + if mock.ListNamespacedFunc == nil { + panic("GlobalRoleInterfaceMock.ListNamespacedFunc: method is nil but GlobalRoleInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGlobalRoleInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGlobalRoleInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGlobalRoleInterface.ListNamespacedCalls()) +func (mock *GlobalRoleInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGlobalRoleInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGlobalRoleInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GlobalRoleInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GlobalRoleInterfaceMock.ObjectClientFunc: method is nil but GlobalRoleInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGlobalRoleInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGlobalRoleInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGlobalRoleInterface.ObjectClientCalls()) +func (mock *GlobalRoleInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGlobalRoleInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGlobalRoleInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GlobalRoleInterfaceMock) Update(in1 *v3.GlobalRole) (*v3.GlobalRole, error) { + if mock.UpdateFunc == nil { + panic("GlobalRoleInterfaceMock.UpdateFunc: method is nil but GlobalRoleInterface.Update was just called") + } + callInfo := struct { + In1 *v3.GlobalRole + }{ + In1: in1, + } + lockGlobalRoleInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGlobalRoleInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGlobalRoleInterface.UpdateCalls()) +func (mock *GlobalRoleInterfaceMock) UpdateCalls() []struct { + In1 *v3.GlobalRole +} { + var calls []struct { + In1 *v3.GlobalRole + } + lockGlobalRoleInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGlobalRoleInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GlobalRoleInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GlobalRoleInterfaceMock.WatchFunc: method is nil but GlobalRoleInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGlobalRoleInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGlobalRoleInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGlobalRoleInterface.WatchCalls()) +func (mock *GlobalRoleInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGlobalRoleInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGlobalRoleInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGlobalRolesGetterMockGlobalRoles sync.RWMutex +) + +// Ensure, that GlobalRolesGetterMock does implement v31.GlobalRolesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GlobalRolesGetter = &GlobalRolesGetterMock{} + +// GlobalRolesGetterMock is a mock implementation of v31.GlobalRolesGetter. +// +// func TestSomethingThatUsesGlobalRolesGetter(t *testing.T) { +// +// // make and configure a mocked v31.GlobalRolesGetter +// mockedGlobalRolesGetter := &GlobalRolesGetterMock{ +// GlobalRolesFunc: func(namespace string) v31.GlobalRoleInterface { +// panic("mock out the GlobalRoles method") +// }, +// } +// +// // use mockedGlobalRolesGetter in code that requires v31.GlobalRolesGetter +// // and then make assertions. +// +// } +type GlobalRolesGetterMock struct { + // GlobalRolesFunc mocks the GlobalRoles method. + GlobalRolesFunc func(namespace string) v31.GlobalRoleInterface + + // calls tracks calls to the methods. + calls struct { + // GlobalRoles holds details about calls to the GlobalRoles method. + GlobalRoles []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// GlobalRoles calls GlobalRolesFunc. +func (mock *GlobalRolesGetterMock) GlobalRoles(namespace string) v31.GlobalRoleInterface { + if mock.GlobalRolesFunc == nil { + panic("GlobalRolesGetterMock.GlobalRolesFunc: method is nil but GlobalRolesGetter.GlobalRoles was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGlobalRolesGetterMockGlobalRoles.Lock() + mock.calls.GlobalRoles = append(mock.calls.GlobalRoles, callInfo) + lockGlobalRolesGetterMockGlobalRoles.Unlock() + return mock.GlobalRolesFunc(namespace) +} + +// GlobalRolesCalls gets all the calls that were made to GlobalRoles. +// Check the length with: +// +// len(mockedGlobalRolesGetter.GlobalRolesCalls()) +func (mock *GlobalRolesGetterMock) GlobalRolesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGlobalRolesGetterMockGlobalRoles.RLock() + calls = mock.calls.GlobalRoles + lockGlobalRolesGetterMockGlobalRoles.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_member_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_member_mock.go new file mode 100644 index 0000000..e9b1696 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_member_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGroupMemberListerMockGet sync.RWMutex + lockGroupMemberListerMockList sync.RWMutex +) + +// Ensure, that GroupMemberListerMock does implement v31.GroupMemberLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupMemberLister = &GroupMemberListerMock{} + +// GroupMemberListerMock is a mock implementation of v31.GroupMemberLister. +// +// func TestSomethingThatUsesGroupMemberLister(t *testing.T) { +// +// // make and configure a mocked v31.GroupMemberLister +// mockedGroupMemberLister := &GroupMemberListerMock{ +// GetFunc: func(namespace string, name string) (*v3.GroupMember, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.GroupMember, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGroupMemberLister in code that requires v31.GroupMemberLister +// // and then make assertions. +// +// } +type GroupMemberListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.GroupMember, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.GroupMember, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GroupMemberListerMock) Get(namespace string, name string) (*v3.GroupMember, error) { + if mock.GetFunc == nil { + panic("GroupMemberListerMock.GetFunc: method is nil but GroupMemberLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGroupMemberListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGroupMemberListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGroupMemberLister.GetCalls()) +func (mock *GroupMemberListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGroupMemberListerMockGet.RLock() + calls = mock.calls.Get + lockGroupMemberListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GroupMemberListerMock) List(namespace string, selector labels.Selector) ([]*v3.GroupMember, error) { + if mock.ListFunc == nil { + panic("GroupMemberListerMock.ListFunc: method is nil but GroupMemberLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGroupMemberListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGroupMemberListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGroupMemberLister.ListCalls()) +func (mock *GroupMemberListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGroupMemberListerMockList.RLock() + calls = mock.calls.List + lockGroupMemberListerMockList.RUnlock() + return calls +} + +var ( + lockGroupMemberControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGroupMemberControllerMockAddClusterScopedHandler sync.RWMutex + lockGroupMemberControllerMockAddFeatureHandler sync.RWMutex + lockGroupMemberControllerMockAddHandler sync.RWMutex + lockGroupMemberControllerMockEnqueue sync.RWMutex + lockGroupMemberControllerMockEnqueueAfter sync.RWMutex + lockGroupMemberControllerMockGeneric sync.RWMutex + lockGroupMemberControllerMockInformer sync.RWMutex + lockGroupMemberControllerMockLister sync.RWMutex +) + +// Ensure, that GroupMemberControllerMock does implement v31.GroupMemberController. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupMemberController = &GroupMemberControllerMock{} + +// GroupMemberControllerMock is a mock implementation of v31.GroupMemberController. +// +// func TestSomethingThatUsesGroupMemberController(t *testing.T) { +// +// // make and configure a mocked v31.GroupMemberController +// mockedGroupMemberController := &GroupMemberControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupMemberHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GroupMemberHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GroupMemberHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GroupMemberLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGroupMemberController in code that requires v31.GroupMemberController +// // and then make assertions. +// +// } +type GroupMemberControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupMemberHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GroupMemberHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GroupMemberHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GroupMemberLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GroupMemberHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GroupMemberHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupMemberHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GroupMemberHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GroupMemberControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupMemberHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GroupMemberControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GroupMemberController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGroupMemberControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGroupMemberControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGroupMemberController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GroupMemberControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc + } + lockGroupMemberControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGroupMemberControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GroupMemberControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GroupMemberHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GroupMemberControllerMock.AddClusterScopedHandlerFunc: method is nil but GroupMemberController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGroupMemberControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGroupMemberControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGroupMemberController.AddClusterScopedHandlerCalls()) +func (mock *GroupMemberControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupMemberHandlerFunc + } + lockGroupMemberControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGroupMemberControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GroupMemberControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GroupMemberControllerMock.AddFeatureHandlerFunc: method is nil but GroupMemberController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGroupMemberControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGroupMemberControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGroupMemberController.AddFeatureHandlerCalls()) +func (mock *GroupMemberControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc + } + lockGroupMemberControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGroupMemberControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GroupMemberControllerMock) AddHandler(ctx context.Context, name string, handler v31.GroupMemberHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GroupMemberControllerMock.AddHandlerFunc: method is nil but GroupMemberController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGroupMemberControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGroupMemberControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGroupMemberController.AddHandlerCalls()) +func (mock *GroupMemberControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GroupMemberHandlerFunc + } + lockGroupMemberControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGroupMemberControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GroupMemberControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GroupMemberControllerMock.EnqueueFunc: method is nil but GroupMemberController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGroupMemberControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGroupMemberControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGroupMemberController.EnqueueCalls()) +func (mock *GroupMemberControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGroupMemberControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGroupMemberControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GroupMemberControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GroupMemberControllerMock.EnqueueAfterFunc: method is nil but GroupMemberController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGroupMemberControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGroupMemberControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGroupMemberController.EnqueueAfterCalls()) +func (mock *GroupMemberControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGroupMemberControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGroupMemberControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GroupMemberControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GroupMemberControllerMock.GenericFunc: method is nil but GroupMemberController.Generic was just called") + } + callInfo := struct { + }{} + lockGroupMemberControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGroupMemberControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGroupMemberController.GenericCalls()) +func (mock *GroupMemberControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGroupMemberControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGroupMemberControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GroupMemberControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GroupMemberControllerMock.InformerFunc: method is nil but GroupMemberController.Informer was just called") + } + callInfo := struct { + }{} + lockGroupMemberControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGroupMemberControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGroupMemberController.InformerCalls()) +func (mock *GroupMemberControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGroupMemberControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGroupMemberControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GroupMemberControllerMock) Lister() v31.GroupMemberLister { + if mock.ListerFunc == nil { + panic("GroupMemberControllerMock.ListerFunc: method is nil but GroupMemberController.Lister was just called") + } + callInfo := struct { + }{} + lockGroupMemberControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGroupMemberControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGroupMemberController.ListerCalls()) +func (mock *GroupMemberControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGroupMemberControllerMockLister.RLock() + calls = mock.calls.Lister + lockGroupMemberControllerMockLister.RUnlock() + return calls +} + +var ( + lockGroupMemberInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGroupMemberInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGroupMemberInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGroupMemberInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGroupMemberInterfaceMockAddFeatureHandler sync.RWMutex + lockGroupMemberInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGroupMemberInterfaceMockAddHandler sync.RWMutex + lockGroupMemberInterfaceMockAddLifecycle sync.RWMutex + lockGroupMemberInterfaceMockController sync.RWMutex + lockGroupMemberInterfaceMockCreate sync.RWMutex + lockGroupMemberInterfaceMockDelete sync.RWMutex + lockGroupMemberInterfaceMockDeleteCollection sync.RWMutex + lockGroupMemberInterfaceMockDeleteNamespaced sync.RWMutex + lockGroupMemberInterfaceMockGet sync.RWMutex + lockGroupMemberInterfaceMockGetNamespaced sync.RWMutex + lockGroupMemberInterfaceMockList sync.RWMutex + lockGroupMemberInterfaceMockListNamespaced sync.RWMutex + lockGroupMemberInterfaceMockObjectClient sync.RWMutex + lockGroupMemberInterfaceMockUpdate sync.RWMutex + lockGroupMemberInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GroupMemberInterfaceMock does implement v31.GroupMemberInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupMemberInterface = &GroupMemberInterfaceMock{} + +// GroupMemberInterfaceMock is a mock implementation of v31.GroupMemberInterface. +// +// func TestSomethingThatUsesGroupMemberInterface(t *testing.T) { +// +// // make and configure a mocked v31.GroupMemberInterface +// mockedGroupMemberInterface := &GroupMemberInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupMemberLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GroupMemberHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GroupMemberLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GroupMemberController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.GroupMember) (*v3.GroupMember, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.GroupMember, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.GroupMember, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GroupMemberList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GroupMemberList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.GroupMember) (*v3.GroupMember, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGroupMemberInterface in code that requires v31.GroupMemberInterface +// // and then make assertions. +// +// } +type GroupMemberInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupMemberLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GroupMemberHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GroupMemberLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GroupMemberController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.GroupMember) (*v3.GroupMember, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.GroupMember, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.GroupMember, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GroupMemberList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GroupMemberList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.GroupMember) (*v3.GroupMember, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GroupMemberHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupMemberLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GroupMemberHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupMemberLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupMemberHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupMemberLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupMemberHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupMemberLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.GroupMember + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.GroupMember + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GroupMemberInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GroupMemberInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GroupMemberInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGroupMemberInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGroupMemberInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GroupMemberInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc + } + lockGroupMemberInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGroupMemberInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GroupMemberInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GroupMemberInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GroupMemberInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGroupMemberInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGroupMemberInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GroupMemberInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle + } + lockGroupMemberInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGroupMemberInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GroupMemberInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupMemberHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GroupMemberInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GroupMemberInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGroupMemberInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGroupMemberInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddClusterScopedHandlerCalls()) +func (mock *GroupMemberInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupMemberHandlerFunc + } + lockGroupMemberInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGroupMemberInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GroupMemberInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GroupMemberLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GroupMemberInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GroupMemberInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGroupMemberInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGroupMemberInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddClusterScopedLifecycleCalls()) +func (mock *GroupMemberInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupMemberLifecycle + } + lockGroupMemberInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGroupMemberInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GroupMemberInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupMemberHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GroupMemberInterfaceMock.AddFeatureHandlerFunc: method is nil but GroupMemberInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGroupMemberInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGroupMemberInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddFeatureHandlerCalls()) +func (mock *GroupMemberInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupMemberHandlerFunc + } + lockGroupMemberInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGroupMemberInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GroupMemberInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupMemberLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GroupMemberInterfaceMock.AddFeatureLifecycleFunc: method is nil but GroupMemberInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupMemberLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGroupMemberInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGroupMemberInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddFeatureLifecycleCalls()) +func (mock *GroupMemberInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupMemberLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupMemberLifecycle + } + lockGroupMemberInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGroupMemberInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GroupMemberInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GroupMemberHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GroupMemberInterfaceMock.AddHandlerFunc: method is nil but GroupMemberInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GroupMemberHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGroupMemberInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGroupMemberInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddHandlerCalls()) +func (mock *GroupMemberInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GroupMemberHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GroupMemberHandlerFunc + } + lockGroupMemberInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGroupMemberInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GroupMemberInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GroupMemberLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GroupMemberInterfaceMock.AddLifecycleFunc: method is nil but GroupMemberInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GroupMemberLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGroupMemberInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGroupMemberInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGroupMemberInterface.AddLifecycleCalls()) +func (mock *GroupMemberInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GroupMemberLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GroupMemberLifecycle + } + lockGroupMemberInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGroupMemberInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GroupMemberInterfaceMock) Controller() v31.GroupMemberController { + if mock.ControllerFunc == nil { + panic("GroupMemberInterfaceMock.ControllerFunc: method is nil but GroupMemberInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGroupMemberInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGroupMemberInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGroupMemberInterface.ControllerCalls()) +func (mock *GroupMemberInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGroupMemberInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGroupMemberInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GroupMemberInterfaceMock) Create(in1 *v3.GroupMember) (*v3.GroupMember, error) { + if mock.CreateFunc == nil { + panic("GroupMemberInterfaceMock.CreateFunc: method is nil but GroupMemberInterface.Create was just called") + } + callInfo := struct { + In1 *v3.GroupMember + }{ + In1: in1, + } + lockGroupMemberInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGroupMemberInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGroupMemberInterface.CreateCalls()) +func (mock *GroupMemberInterfaceMock) CreateCalls() []struct { + In1 *v3.GroupMember +} { + var calls []struct { + In1 *v3.GroupMember + } + lockGroupMemberInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGroupMemberInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GroupMemberInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GroupMemberInterfaceMock.DeleteFunc: method is nil but GroupMemberInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGroupMemberInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGroupMemberInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGroupMemberInterface.DeleteCalls()) +func (mock *GroupMemberInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGroupMemberInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGroupMemberInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GroupMemberInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GroupMemberInterfaceMock.DeleteCollectionFunc: method is nil but GroupMemberInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGroupMemberInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGroupMemberInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGroupMemberInterface.DeleteCollectionCalls()) +func (mock *GroupMemberInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGroupMemberInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGroupMemberInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GroupMemberInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GroupMemberInterfaceMock.DeleteNamespacedFunc: method is nil but GroupMemberInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGroupMemberInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGroupMemberInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGroupMemberInterface.DeleteNamespacedCalls()) +func (mock *GroupMemberInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGroupMemberInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGroupMemberInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GroupMemberInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.GroupMember, error) { + if mock.GetFunc == nil { + panic("GroupMemberInterfaceMock.GetFunc: method is nil but GroupMemberInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGroupMemberInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGroupMemberInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGroupMemberInterface.GetCalls()) +func (mock *GroupMemberInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGroupMemberInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGroupMemberInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GroupMemberInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.GroupMember, error) { + if mock.GetNamespacedFunc == nil { + panic("GroupMemberInterfaceMock.GetNamespacedFunc: method is nil but GroupMemberInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGroupMemberInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGroupMemberInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGroupMemberInterface.GetNamespacedCalls()) +func (mock *GroupMemberInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGroupMemberInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGroupMemberInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GroupMemberInterfaceMock) List(opts metav1.ListOptions) (*v3.GroupMemberList, error) { + if mock.ListFunc == nil { + panic("GroupMemberInterfaceMock.ListFunc: method is nil but GroupMemberInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGroupMemberInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGroupMemberInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGroupMemberInterface.ListCalls()) +func (mock *GroupMemberInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGroupMemberInterfaceMockList.RLock() + calls = mock.calls.List + lockGroupMemberInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GroupMemberInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupMemberList, error) { + if mock.ListNamespacedFunc == nil { + panic("GroupMemberInterfaceMock.ListNamespacedFunc: method is nil but GroupMemberInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGroupMemberInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGroupMemberInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGroupMemberInterface.ListNamespacedCalls()) +func (mock *GroupMemberInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGroupMemberInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGroupMemberInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GroupMemberInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GroupMemberInterfaceMock.ObjectClientFunc: method is nil but GroupMemberInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGroupMemberInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGroupMemberInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGroupMemberInterface.ObjectClientCalls()) +func (mock *GroupMemberInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGroupMemberInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGroupMemberInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GroupMemberInterfaceMock) Update(in1 *v3.GroupMember) (*v3.GroupMember, error) { + if mock.UpdateFunc == nil { + panic("GroupMemberInterfaceMock.UpdateFunc: method is nil but GroupMemberInterface.Update was just called") + } + callInfo := struct { + In1 *v3.GroupMember + }{ + In1: in1, + } + lockGroupMemberInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGroupMemberInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGroupMemberInterface.UpdateCalls()) +func (mock *GroupMemberInterfaceMock) UpdateCalls() []struct { + In1 *v3.GroupMember +} { + var calls []struct { + In1 *v3.GroupMember + } + lockGroupMemberInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGroupMemberInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GroupMemberInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GroupMemberInterfaceMock.WatchFunc: method is nil but GroupMemberInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGroupMemberInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGroupMemberInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGroupMemberInterface.WatchCalls()) +func (mock *GroupMemberInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGroupMemberInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGroupMemberInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGroupMembersGetterMockGroupMembers sync.RWMutex +) + +// Ensure, that GroupMembersGetterMock does implement v31.GroupMembersGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupMembersGetter = &GroupMembersGetterMock{} + +// GroupMembersGetterMock is a mock implementation of v31.GroupMembersGetter. +// +// func TestSomethingThatUsesGroupMembersGetter(t *testing.T) { +// +// // make and configure a mocked v31.GroupMembersGetter +// mockedGroupMembersGetter := &GroupMembersGetterMock{ +// GroupMembersFunc: func(namespace string) v31.GroupMemberInterface { +// panic("mock out the GroupMembers method") +// }, +// } +// +// // use mockedGroupMembersGetter in code that requires v31.GroupMembersGetter +// // and then make assertions. +// +// } +type GroupMembersGetterMock struct { + // GroupMembersFunc mocks the GroupMembers method. + GroupMembersFunc func(namespace string) v31.GroupMemberInterface + + // calls tracks calls to the methods. + calls struct { + // GroupMembers holds details about calls to the GroupMembers method. + GroupMembers []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// GroupMembers calls GroupMembersFunc. +func (mock *GroupMembersGetterMock) GroupMembers(namespace string) v31.GroupMemberInterface { + if mock.GroupMembersFunc == nil { + panic("GroupMembersGetterMock.GroupMembersFunc: method is nil but GroupMembersGetter.GroupMembers was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGroupMembersGetterMockGroupMembers.Lock() + mock.calls.GroupMembers = append(mock.calls.GroupMembers, callInfo) + lockGroupMembersGetterMockGroupMembers.Unlock() + return mock.GroupMembersFunc(namespace) +} + +// GroupMembersCalls gets all the calls that were made to GroupMembers. +// Check the length with: +// +// len(mockedGroupMembersGetter.GroupMembersCalls()) +func (mock *GroupMembersGetterMock) GroupMembersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGroupMembersGetterMockGroupMembers.RLock() + calls = mock.calls.GroupMembers + lockGroupMembersGetterMockGroupMembers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_mock.go new file mode 100644 index 0000000..5940d50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_group_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockGroupListerMockGet sync.RWMutex + lockGroupListerMockList sync.RWMutex +) + +// Ensure, that GroupListerMock does implement v31.GroupLister. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupLister = &GroupListerMock{} + +// GroupListerMock is a mock implementation of v31.GroupLister. +// +// func TestSomethingThatUsesGroupLister(t *testing.T) { +// +// // make and configure a mocked v31.GroupLister +// mockedGroupLister := &GroupListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Group, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Group, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedGroupLister in code that requires v31.GroupLister +// // and then make assertions. +// +// } +type GroupListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Group, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Group, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *GroupListerMock) Get(namespace string, name string) (*v3.Group, error) { + if mock.GetFunc == nil { + panic("GroupListerMock.GetFunc: method is nil but GroupLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGroupListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGroupListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGroupLister.GetCalls()) +func (mock *GroupListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGroupListerMockGet.RLock() + calls = mock.calls.Get + lockGroupListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GroupListerMock) List(namespace string, selector labels.Selector) ([]*v3.Group, error) { + if mock.ListFunc == nil { + panic("GroupListerMock.ListFunc: method is nil but GroupLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockGroupListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGroupListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGroupLister.ListCalls()) +func (mock *GroupListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockGroupListerMockList.RLock() + calls = mock.calls.List + lockGroupListerMockList.RUnlock() + return calls +} + +var ( + lockGroupControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockGroupControllerMockAddClusterScopedHandler sync.RWMutex + lockGroupControllerMockAddFeatureHandler sync.RWMutex + lockGroupControllerMockAddHandler sync.RWMutex + lockGroupControllerMockEnqueue sync.RWMutex + lockGroupControllerMockEnqueueAfter sync.RWMutex + lockGroupControllerMockGeneric sync.RWMutex + lockGroupControllerMockInformer sync.RWMutex + lockGroupControllerMockLister sync.RWMutex +) + +// Ensure, that GroupControllerMock does implement v31.GroupController. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupController = &GroupControllerMock{} + +// GroupControllerMock is a mock implementation of v31.GroupController. +// +// func TestSomethingThatUsesGroupController(t *testing.T) { +// +// // make and configure a mocked v31.GroupController +// mockedGroupController := &GroupControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.GroupHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.GroupHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.GroupLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedGroupController in code that requires v31.GroupController +// // and then make assertions. +// +// } +type GroupControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.GroupHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.GroupHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.GroupLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GroupHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.GroupHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.GroupHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GroupControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.GroupHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GroupControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but GroupController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGroupControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGroupControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGroupController.AddClusterScopedFeatureHandlerCalls()) +func (mock *GroupControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.GroupHandlerFunc + } + lockGroupControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGroupControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GroupControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.GroupHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GroupControllerMock.AddClusterScopedHandlerFunc: method is nil but GroupController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockGroupControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGroupControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGroupController.AddClusterScopedHandlerCalls()) +func (mock *GroupControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.GroupHandlerFunc + } + lockGroupControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGroupControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GroupControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GroupControllerMock.AddFeatureHandlerFunc: method is nil but GroupController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGroupControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGroupControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGroupController.AddFeatureHandlerCalls()) +func (mock *GroupControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc + } + lockGroupControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGroupControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GroupControllerMock) AddHandler(ctx context.Context, name string, handler v31.GroupHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GroupControllerMock.AddHandlerFunc: method is nil but GroupController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.GroupHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockGroupControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGroupControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGroupController.AddHandlerCalls()) +func (mock *GroupControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.GroupHandlerFunc + } + lockGroupControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGroupControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *GroupControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("GroupControllerMock.EnqueueFunc: method is nil but GroupController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockGroupControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockGroupControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedGroupController.EnqueueCalls()) +func (mock *GroupControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockGroupControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockGroupControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *GroupControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("GroupControllerMock.EnqueueAfterFunc: method is nil but GroupController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockGroupControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockGroupControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedGroupController.EnqueueAfterCalls()) +func (mock *GroupControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockGroupControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockGroupControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *GroupControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("GroupControllerMock.GenericFunc: method is nil but GroupController.Generic was just called") + } + callInfo := struct { + }{} + lockGroupControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockGroupControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedGroupController.GenericCalls()) +func (mock *GroupControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockGroupControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockGroupControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *GroupControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("GroupControllerMock.InformerFunc: method is nil but GroupController.Informer was just called") + } + callInfo := struct { + }{} + lockGroupControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockGroupControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedGroupController.InformerCalls()) +func (mock *GroupControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockGroupControllerMockInformer.RLock() + calls = mock.calls.Informer + lockGroupControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *GroupControllerMock) Lister() v31.GroupLister { + if mock.ListerFunc == nil { + panic("GroupControllerMock.ListerFunc: method is nil but GroupController.Lister was just called") + } + callInfo := struct { + }{} + lockGroupControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockGroupControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedGroupController.ListerCalls()) +func (mock *GroupControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockGroupControllerMockLister.RLock() + calls = mock.calls.Lister + lockGroupControllerMockLister.RUnlock() + return calls +} + +var ( + lockGroupInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockGroupInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockGroupInterfaceMockAddClusterScopedHandler sync.RWMutex + lockGroupInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockGroupInterfaceMockAddFeatureHandler sync.RWMutex + lockGroupInterfaceMockAddFeatureLifecycle sync.RWMutex + lockGroupInterfaceMockAddHandler sync.RWMutex + lockGroupInterfaceMockAddLifecycle sync.RWMutex + lockGroupInterfaceMockController sync.RWMutex + lockGroupInterfaceMockCreate sync.RWMutex + lockGroupInterfaceMockDelete sync.RWMutex + lockGroupInterfaceMockDeleteCollection sync.RWMutex + lockGroupInterfaceMockDeleteNamespaced sync.RWMutex + lockGroupInterfaceMockGet sync.RWMutex + lockGroupInterfaceMockGetNamespaced sync.RWMutex + lockGroupInterfaceMockList sync.RWMutex + lockGroupInterfaceMockListNamespaced sync.RWMutex + lockGroupInterfaceMockObjectClient sync.RWMutex + lockGroupInterfaceMockUpdate sync.RWMutex + lockGroupInterfaceMockWatch sync.RWMutex +) + +// Ensure, that GroupInterfaceMock does implement v31.GroupInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupInterface = &GroupInterfaceMock{} + +// GroupInterfaceMock is a mock implementation of v31.GroupInterface. +// +// func TestSomethingThatUsesGroupInterface(t *testing.T) { +// +// // make and configure a mocked v31.GroupInterface +// mockedGroupInterface := &GroupInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.GroupLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.GroupHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.GroupLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.GroupController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Group) (*v3.Group, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Group, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Group, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.GroupList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.GroupList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Group) (*v3.Group, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedGroupInterface in code that requires v31.GroupInterface +// // and then make assertions. +// +// } +type GroupInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.GroupLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.GroupHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.GroupLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.GroupController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Group) (*v3.Group, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Group, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Group, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.GroupList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.GroupList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Group) (*v3.Group, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GroupHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.GroupHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.GroupHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.GroupLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Group + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Group + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *GroupInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("GroupInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but GroupInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGroupInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockGroupInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedGroupInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *GroupInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.GroupHandlerFunc + } + lockGroupInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockGroupInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *GroupInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.GroupLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("GroupInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but GroupInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGroupInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockGroupInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedGroupInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *GroupInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.GroupLifecycle + } + lockGroupInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockGroupInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *GroupInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.GroupHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("GroupInterfaceMock.AddClusterScopedHandlerFunc: method is nil but GroupInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockGroupInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockGroupInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedGroupInterface.AddClusterScopedHandlerCalls()) +func (mock *GroupInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.GroupHandlerFunc + } + lockGroupInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockGroupInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *GroupInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.GroupLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("GroupInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but GroupInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockGroupInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockGroupInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedGroupInterface.AddClusterScopedLifecycleCalls()) +func (mock *GroupInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.GroupLifecycle + } + lockGroupInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockGroupInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *GroupInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.GroupHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("GroupInterfaceMock.AddFeatureHandlerFunc: method is nil but GroupInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockGroupInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockGroupInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedGroupInterface.AddFeatureHandlerCalls()) +func (mock *GroupInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.GroupHandlerFunc + } + lockGroupInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockGroupInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *GroupInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.GroupLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("GroupInterfaceMock.AddFeatureLifecycleFunc: method is nil but GroupInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockGroupInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockGroupInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedGroupInterface.AddFeatureLifecycleCalls()) +func (mock *GroupInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.GroupLifecycle + } + lockGroupInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockGroupInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *GroupInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.GroupHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("GroupInterfaceMock.AddHandlerFunc: method is nil but GroupInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.GroupHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockGroupInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockGroupInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedGroupInterface.AddHandlerCalls()) +func (mock *GroupInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.GroupHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.GroupHandlerFunc + } + lockGroupInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockGroupInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *GroupInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.GroupLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("GroupInterfaceMock.AddLifecycleFunc: method is nil but GroupInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.GroupLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockGroupInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockGroupInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedGroupInterface.AddLifecycleCalls()) +func (mock *GroupInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.GroupLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.GroupLifecycle + } + lockGroupInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockGroupInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *GroupInterfaceMock) Controller() v31.GroupController { + if mock.ControllerFunc == nil { + panic("GroupInterfaceMock.ControllerFunc: method is nil but GroupInterface.Controller was just called") + } + callInfo := struct { + }{} + lockGroupInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockGroupInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedGroupInterface.ControllerCalls()) +func (mock *GroupInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockGroupInterfaceMockController.RLock() + calls = mock.calls.Controller + lockGroupInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *GroupInterfaceMock) Create(in1 *v3.Group) (*v3.Group, error) { + if mock.CreateFunc == nil { + panic("GroupInterfaceMock.CreateFunc: method is nil but GroupInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Group + }{ + In1: in1, + } + lockGroupInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockGroupInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedGroupInterface.CreateCalls()) +func (mock *GroupInterfaceMock) CreateCalls() []struct { + In1 *v3.Group +} { + var calls []struct { + In1 *v3.Group + } + lockGroupInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockGroupInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *GroupInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("GroupInterfaceMock.DeleteFunc: method is nil but GroupInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockGroupInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockGroupInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedGroupInterface.DeleteCalls()) +func (mock *GroupInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockGroupInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockGroupInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *GroupInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("GroupInterfaceMock.DeleteCollectionFunc: method is nil but GroupInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockGroupInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockGroupInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedGroupInterface.DeleteCollectionCalls()) +func (mock *GroupInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockGroupInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockGroupInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *GroupInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("GroupInterfaceMock.DeleteNamespacedFunc: method is nil but GroupInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockGroupInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockGroupInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedGroupInterface.DeleteNamespacedCalls()) +func (mock *GroupInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockGroupInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockGroupInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *GroupInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Group, error) { + if mock.GetFunc == nil { + panic("GroupInterfaceMock.GetFunc: method is nil but GroupInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockGroupInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockGroupInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedGroupInterface.GetCalls()) +func (mock *GroupInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockGroupInterfaceMockGet.RLock() + calls = mock.calls.Get + lockGroupInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *GroupInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Group, error) { + if mock.GetNamespacedFunc == nil { + panic("GroupInterfaceMock.GetNamespacedFunc: method is nil but GroupInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockGroupInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockGroupInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedGroupInterface.GetNamespacedCalls()) +func (mock *GroupInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockGroupInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockGroupInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *GroupInterfaceMock) List(opts metav1.ListOptions) (*v3.GroupList, error) { + if mock.ListFunc == nil { + panic("GroupInterfaceMock.ListFunc: method is nil but GroupInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGroupInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockGroupInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedGroupInterface.ListCalls()) +func (mock *GroupInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGroupInterfaceMockList.RLock() + calls = mock.calls.List + lockGroupInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *GroupInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupList, error) { + if mock.ListNamespacedFunc == nil { + panic("GroupInterfaceMock.ListNamespacedFunc: method is nil but GroupInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockGroupInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockGroupInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedGroupInterface.ListNamespacedCalls()) +func (mock *GroupInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockGroupInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockGroupInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *GroupInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("GroupInterfaceMock.ObjectClientFunc: method is nil but GroupInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockGroupInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockGroupInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedGroupInterface.ObjectClientCalls()) +func (mock *GroupInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockGroupInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockGroupInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *GroupInterfaceMock) Update(in1 *v3.Group) (*v3.Group, error) { + if mock.UpdateFunc == nil { + panic("GroupInterfaceMock.UpdateFunc: method is nil but GroupInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Group + }{ + In1: in1, + } + lockGroupInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockGroupInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedGroupInterface.UpdateCalls()) +func (mock *GroupInterfaceMock) UpdateCalls() []struct { + In1 *v3.Group +} { + var calls []struct { + In1 *v3.Group + } + lockGroupInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockGroupInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *GroupInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("GroupInterfaceMock.WatchFunc: method is nil but GroupInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockGroupInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockGroupInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedGroupInterface.WatchCalls()) +func (mock *GroupInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockGroupInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockGroupInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockGroupsGetterMockGroups sync.RWMutex +) + +// Ensure, that GroupsGetterMock does implement v31.GroupsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.GroupsGetter = &GroupsGetterMock{} + +// GroupsGetterMock is a mock implementation of v31.GroupsGetter. +// +// func TestSomethingThatUsesGroupsGetter(t *testing.T) { +// +// // make and configure a mocked v31.GroupsGetter +// mockedGroupsGetter := &GroupsGetterMock{ +// GroupsFunc: func(namespace string) v31.GroupInterface { +// panic("mock out the Groups method") +// }, +// } +// +// // use mockedGroupsGetter in code that requires v31.GroupsGetter +// // and then make assertions. +// +// } +type GroupsGetterMock struct { + // GroupsFunc mocks the Groups method. + GroupsFunc func(namespace string) v31.GroupInterface + + // calls tracks calls to the methods. + calls struct { + // Groups holds details about calls to the Groups method. + Groups []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Groups calls GroupsFunc. +func (mock *GroupsGetterMock) Groups(namespace string) v31.GroupInterface { + if mock.GroupsFunc == nil { + panic("GroupsGetterMock.GroupsFunc: method is nil but GroupsGetter.Groups was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockGroupsGetterMockGroups.Lock() + mock.calls.Groups = append(mock.calls.Groups, callInfo) + lockGroupsGetterMockGroups.Unlock() + return mock.GroupsFunc(namespace) +} + +// GroupsCalls gets all the calls that were made to Groups. +// Check the length with: +// +// len(mockedGroupsGetter.GroupsCalls()) +func (mock *GroupsGetterMock) GroupsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockGroupsGetterMockGroups.RLock() + calls = mock.calls.Groups + lockGroupsGetterMockGroups.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_kontainer_driver_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_kontainer_driver_mock.go new file mode 100644 index 0000000..9271656 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_kontainer_driver_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockKontainerDriverListerMockGet sync.RWMutex + lockKontainerDriverListerMockList sync.RWMutex +) + +// Ensure, that KontainerDriverListerMock does implement v31.KontainerDriverLister. +// If this is not the case, regenerate this file with moq. +var _ v31.KontainerDriverLister = &KontainerDriverListerMock{} + +// KontainerDriverListerMock is a mock implementation of v31.KontainerDriverLister. +// +// func TestSomethingThatUsesKontainerDriverLister(t *testing.T) { +// +// // make and configure a mocked v31.KontainerDriverLister +// mockedKontainerDriverLister := &KontainerDriverListerMock{ +// GetFunc: func(namespace string, name string) (*v3.KontainerDriver, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.KontainerDriver, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedKontainerDriverLister in code that requires v31.KontainerDriverLister +// // and then make assertions. +// +// } +type KontainerDriverListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.KontainerDriver, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.KontainerDriver, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *KontainerDriverListerMock) Get(namespace string, name string) (*v3.KontainerDriver, error) { + if mock.GetFunc == nil { + panic("KontainerDriverListerMock.GetFunc: method is nil but KontainerDriverLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockKontainerDriverListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockKontainerDriverListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedKontainerDriverLister.GetCalls()) +func (mock *KontainerDriverListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockKontainerDriverListerMockGet.RLock() + calls = mock.calls.Get + lockKontainerDriverListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *KontainerDriverListerMock) List(namespace string, selector labels.Selector) ([]*v3.KontainerDriver, error) { + if mock.ListFunc == nil { + panic("KontainerDriverListerMock.ListFunc: method is nil but KontainerDriverLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockKontainerDriverListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockKontainerDriverListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedKontainerDriverLister.ListCalls()) +func (mock *KontainerDriverListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockKontainerDriverListerMockList.RLock() + calls = mock.calls.List + lockKontainerDriverListerMockList.RUnlock() + return calls +} + +var ( + lockKontainerDriverControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockKontainerDriverControllerMockAddClusterScopedHandler sync.RWMutex + lockKontainerDriverControllerMockAddFeatureHandler sync.RWMutex + lockKontainerDriverControllerMockAddHandler sync.RWMutex + lockKontainerDriverControllerMockEnqueue sync.RWMutex + lockKontainerDriverControllerMockEnqueueAfter sync.RWMutex + lockKontainerDriverControllerMockGeneric sync.RWMutex + lockKontainerDriverControllerMockInformer sync.RWMutex + lockKontainerDriverControllerMockLister sync.RWMutex +) + +// Ensure, that KontainerDriverControllerMock does implement v31.KontainerDriverController. +// If this is not the case, regenerate this file with moq. +var _ v31.KontainerDriverController = &KontainerDriverControllerMock{} + +// KontainerDriverControllerMock is a mock implementation of v31.KontainerDriverController. +// +// func TestSomethingThatUsesKontainerDriverController(t *testing.T) { +// +// // make and configure a mocked v31.KontainerDriverController +// mockedKontainerDriverController := &KontainerDriverControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.KontainerDriverLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedKontainerDriverController in code that requires v31.KontainerDriverController +// // and then make assertions. +// +// } +type KontainerDriverControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.KontainerDriverHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.KontainerDriverLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.KontainerDriverHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.KontainerDriverHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.KontainerDriverHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.KontainerDriverHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *KontainerDriverControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("KontainerDriverControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but KontainerDriverController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockKontainerDriverControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockKontainerDriverControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedKontainerDriverController.AddClusterScopedFeatureHandlerCalls()) +func (mock *KontainerDriverControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc + } + lockKontainerDriverControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockKontainerDriverControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *KontainerDriverControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.KontainerDriverHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("KontainerDriverControllerMock.AddClusterScopedHandlerFunc: method is nil but KontainerDriverController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockKontainerDriverControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockKontainerDriverControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedKontainerDriverController.AddClusterScopedHandlerCalls()) +func (mock *KontainerDriverControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.KontainerDriverHandlerFunc + } + lockKontainerDriverControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockKontainerDriverControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *KontainerDriverControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("KontainerDriverControllerMock.AddFeatureHandlerFunc: method is nil but KontainerDriverController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockKontainerDriverControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockKontainerDriverControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedKontainerDriverController.AddFeatureHandlerCalls()) +func (mock *KontainerDriverControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc + } + lockKontainerDriverControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockKontainerDriverControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *KontainerDriverControllerMock) AddHandler(ctx context.Context, name string, handler v31.KontainerDriverHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("KontainerDriverControllerMock.AddHandlerFunc: method is nil but KontainerDriverController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockKontainerDriverControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockKontainerDriverControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedKontainerDriverController.AddHandlerCalls()) +func (mock *KontainerDriverControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.KontainerDriverHandlerFunc + } + lockKontainerDriverControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockKontainerDriverControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *KontainerDriverControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("KontainerDriverControllerMock.EnqueueFunc: method is nil but KontainerDriverController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockKontainerDriverControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockKontainerDriverControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedKontainerDriverController.EnqueueCalls()) +func (mock *KontainerDriverControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockKontainerDriverControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockKontainerDriverControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *KontainerDriverControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("KontainerDriverControllerMock.EnqueueAfterFunc: method is nil but KontainerDriverController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockKontainerDriverControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockKontainerDriverControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedKontainerDriverController.EnqueueAfterCalls()) +func (mock *KontainerDriverControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockKontainerDriverControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockKontainerDriverControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *KontainerDriverControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("KontainerDriverControllerMock.GenericFunc: method is nil but KontainerDriverController.Generic was just called") + } + callInfo := struct { + }{} + lockKontainerDriverControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockKontainerDriverControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedKontainerDriverController.GenericCalls()) +func (mock *KontainerDriverControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockKontainerDriverControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockKontainerDriverControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *KontainerDriverControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("KontainerDriverControllerMock.InformerFunc: method is nil but KontainerDriverController.Informer was just called") + } + callInfo := struct { + }{} + lockKontainerDriverControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockKontainerDriverControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedKontainerDriverController.InformerCalls()) +func (mock *KontainerDriverControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockKontainerDriverControllerMockInformer.RLock() + calls = mock.calls.Informer + lockKontainerDriverControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *KontainerDriverControllerMock) Lister() v31.KontainerDriverLister { + if mock.ListerFunc == nil { + panic("KontainerDriverControllerMock.ListerFunc: method is nil but KontainerDriverController.Lister was just called") + } + callInfo := struct { + }{} + lockKontainerDriverControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockKontainerDriverControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedKontainerDriverController.ListerCalls()) +func (mock *KontainerDriverControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockKontainerDriverControllerMockLister.RLock() + calls = mock.calls.Lister + lockKontainerDriverControllerMockLister.RUnlock() + return calls +} + +var ( + lockKontainerDriverInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockKontainerDriverInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockKontainerDriverInterfaceMockAddClusterScopedHandler sync.RWMutex + lockKontainerDriverInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockKontainerDriverInterfaceMockAddFeatureHandler sync.RWMutex + lockKontainerDriverInterfaceMockAddFeatureLifecycle sync.RWMutex + lockKontainerDriverInterfaceMockAddHandler sync.RWMutex + lockKontainerDriverInterfaceMockAddLifecycle sync.RWMutex + lockKontainerDriverInterfaceMockController sync.RWMutex + lockKontainerDriverInterfaceMockCreate sync.RWMutex + lockKontainerDriverInterfaceMockDelete sync.RWMutex + lockKontainerDriverInterfaceMockDeleteCollection sync.RWMutex + lockKontainerDriverInterfaceMockDeleteNamespaced sync.RWMutex + lockKontainerDriverInterfaceMockGet sync.RWMutex + lockKontainerDriverInterfaceMockGetNamespaced sync.RWMutex + lockKontainerDriverInterfaceMockList sync.RWMutex + lockKontainerDriverInterfaceMockListNamespaced sync.RWMutex + lockKontainerDriverInterfaceMockObjectClient sync.RWMutex + lockKontainerDriverInterfaceMockUpdate sync.RWMutex + lockKontainerDriverInterfaceMockWatch sync.RWMutex +) + +// Ensure, that KontainerDriverInterfaceMock does implement v31.KontainerDriverInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.KontainerDriverInterface = &KontainerDriverInterfaceMock{} + +// KontainerDriverInterfaceMock is a mock implementation of v31.KontainerDriverInterface. +// +// func TestSomethingThatUsesKontainerDriverInterface(t *testing.T) { +// +// // make and configure a mocked v31.KontainerDriverInterface +// mockedKontainerDriverInterface := &KontainerDriverInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.KontainerDriverLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.KontainerDriverLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.KontainerDriverController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.KontainerDriverList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.KontainerDriverList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedKontainerDriverInterface in code that requires v31.KontainerDriverInterface +// // and then make assertions. +// +// } +type KontainerDriverInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.KontainerDriverLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.KontainerDriverHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.KontainerDriverLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.KontainerDriverController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.KontainerDriverList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.KontainerDriverList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.KontainerDriverHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.KontainerDriverLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.KontainerDriverHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.KontainerDriverLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.KontainerDriverHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.KontainerDriverLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.KontainerDriverHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.KontainerDriverLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.KontainerDriver + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.KontainerDriver + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *KontainerDriverInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("KontainerDriverInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but KontainerDriverInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockKontainerDriverInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockKontainerDriverInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *KontainerDriverInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc + } + lockKontainerDriverInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockKontainerDriverInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *KontainerDriverInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("KontainerDriverInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but KontainerDriverInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockKontainerDriverInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockKontainerDriverInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *KontainerDriverInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle + } + lockKontainerDriverInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockKontainerDriverInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *KontainerDriverInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.KontainerDriverHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("KontainerDriverInterfaceMock.AddClusterScopedHandlerFunc: method is nil but KontainerDriverInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockKontainerDriverInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockKontainerDriverInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddClusterScopedHandlerCalls()) +func (mock *KontainerDriverInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.KontainerDriverHandlerFunc + } + lockKontainerDriverInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockKontainerDriverInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *KontainerDriverInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.KontainerDriverLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("KontainerDriverInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but KontainerDriverInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockKontainerDriverInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockKontainerDriverInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddClusterScopedLifecycleCalls()) +func (mock *KontainerDriverInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.KontainerDriverLifecycle + } + lockKontainerDriverInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockKontainerDriverInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *KontainerDriverInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("KontainerDriverInterfaceMock.AddFeatureHandlerFunc: method is nil but KontainerDriverInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockKontainerDriverInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockKontainerDriverInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddFeatureHandlerCalls()) +func (mock *KontainerDriverInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.KontainerDriverHandlerFunc + } + lockKontainerDriverInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockKontainerDriverInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *KontainerDriverInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.KontainerDriverLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("KontainerDriverInterfaceMock.AddFeatureLifecycleFunc: method is nil but KontainerDriverInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.KontainerDriverLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockKontainerDriverInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockKontainerDriverInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddFeatureLifecycleCalls()) +func (mock *KontainerDriverInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.KontainerDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.KontainerDriverLifecycle + } + lockKontainerDriverInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockKontainerDriverInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *KontainerDriverInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.KontainerDriverHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("KontainerDriverInterfaceMock.AddHandlerFunc: method is nil but KontainerDriverInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.KontainerDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockKontainerDriverInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockKontainerDriverInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddHandlerCalls()) +func (mock *KontainerDriverInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.KontainerDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.KontainerDriverHandlerFunc + } + lockKontainerDriverInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockKontainerDriverInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *KontainerDriverInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.KontainerDriverLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("KontainerDriverInterfaceMock.AddLifecycleFunc: method is nil but KontainerDriverInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.KontainerDriverLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockKontainerDriverInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockKontainerDriverInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedKontainerDriverInterface.AddLifecycleCalls()) +func (mock *KontainerDriverInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.KontainerDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.KontainerDriverLifecycle + } + lockKontainerDriverInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockKontainerDriverInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *KontainerDriverInterfaceMock) Controller() v31.KontainerDriverController { + if mock.ControllerFunc == nil { + panic("KontainerDriverInterfaceMock.ControllerFunc: method is nil but KontainerDriverInterface.Controller was just called") + } + callInfo := struct { + }{} + lockKontainerDriverInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockKontainerDriverInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedKontainerDriverInterface.ControllerCalls()) +func (mock *KontainerDriverInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockKontainerDriverInterfaceMockController.RLock() + calls = mock.calls.Controller + lockKontainerDriverInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *KontainerDriverInterfaceMock) Create(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) { + if mock.CreateFunc == nil { + panic("KontainerDriverInterfaceMock.CreateFunc: method is nil but KontainerDriverInterface.Create was just called") + } + callInfo := struct { + In1 *v3.KontainerDriver + }{ + In1: in1, + } + lockKontainerDriverInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockKontainerDriverInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedKontainerDriverInterface.CreateCalls()) +func (mock *KontainerDriverInterfaceMock) CreateCalls() []struct { + In1 *v3.KontainerDriver +} { + var calls []struct { + In1 *v3.KontainerDriver + } + lockKontainerDriverInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockKontainerDriverInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *KontainerDriverInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("KontainerDriverInterfaceMock.DeleteFunc: method is nil but KontainerDriverInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockKontainerDriverInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockKontainerDriverInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedKontainerDriverInterface.DeleteCalls()) +func (mock *KontainerDriverInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockKontainerDriverInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockKontainerDriverInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *KontainerDriverInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("KontainerDriverInterfaceMock.DeleteCollectionFunc: method is nil but KontainerDriverInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockKontainerDriverInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockKontainerDriverInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedKontainerDriverInterface.DeleteCollectionCalls()) +func (mock *KontainerDriverInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockKontainerDriverInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockKontainerDriverInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *KontainerDriverInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("KontainerDriverInterfaceMock.DeleteNamespacedFunc: method is nil but KontainerDriverInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockKontainerDriverInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockKontainerDriverInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedKontainerDriverInterface.DeleteNamespacedCalls()) +func (mock *KontainerDriverInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockKontainerDriverInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockKontainerDriverInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *KontainerDriverInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { + if mock.GetFunc == nil { + panic("KontainerDriverInterfaceMock.GetFunc: method is nil but KontainerDriverInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockKontainerDriverInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockKontainerDriverInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedKontainerDriverInterface.GetCalls()) +func (mock *KontainerDriverInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockKontainerDriverInterfaceMockGet.RLock() + calls = mock.calls.Get + lockKontainerDriverInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *KontainerDriverInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { + if mock.GetNamespacedFunc == nil { + panic("KontainerDriverInterfaceMock.GetNamespacedFunc: method is nil but KontainerDriverInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockKontainerDriverInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockKontainerDriverInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedKontainerDriverInterface.GetNamespacedCalls()) +func (mock *KontainerDriverInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockKontainerDriverInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockKontainerDriverInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *KontainerDriverInterfaceMock) List(opts metav1.ListOptions) (*v3.KontainerDriverList, error) { + if mock.ListFunc == nil { + panic("KontainerDriverInterfaceMock.ListFunc: method is nil but KontainerDriverInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockKontainerDriverInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockKontainerDriverInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedKontainerDriverInterface.ListCalls()) +func (mock *KontainerDriverInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockKontainerDriverInterfaceMockList.RLock() + calls = mock.calls.List + lockKontainerDriverInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *KontainerDriverInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.KontainerDriverList, error) { + if mock.ListNamespacedFunc == nil { + panic("KontainerDriverInterfaceMock.ListNamespacedFunc: method is nil but KontainerDriverInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockKontainerDriverInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockKontainerDriverInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedKontainerDriverInterface.ListNamespacedCalls()) +func (mock *KontainerDriverInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockKontainerDriverInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockKontainerDriverInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *KontainerDriverInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("KontainerDriverInterfaceMock.ObjectClientFunc: method is nil but KontainerDriverInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockKontainerDriverInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockKontainerDriverInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedKontainerDriverInterface.ObjectClientCalls()) +func (mock *KontainerDriverInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockKontainerDriverInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockKontainerDriverInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *KontainerDriverInterfaceMock) Update(in1 *v3.KontainerDriver) (*v3.KontainerDriver, error) { + if mock.UpdateFunc == nil { + panic("KontainerDriverInterfaceMock.UpdateFunc: method is nil but KontainerDriverInterface.Update was just called") + } + callInfo := struct { + In1 *v3.KontainerDriver + }{ + In1: in1, + } + lockKontainerDriverInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockKontainerDriverInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedKontainerDriverInterface.UpdateCalls()) +func (mock *KontainerDriverInterfaceMock) UpdateCalls() []struct { + In1 *v3.KontainerDriver +} { + var calls []struct { + In1 *v3.KontainerDriver + } + lockKontainerDriverInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockKontainerDriverInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *KontainerDriverInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("KontainerDriverInterfaceMock.WatchFunc: method is nil but KontainerDriverInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockKontainerDriverInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockKontainerDriverInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedKontainerDriverInterface.WatchCalls()) +func (mock *KontainerDriverInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockKontainerDriverInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockKontainerDriverInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockKontainerDriversGetterMockKontainerDrivers sync.RWMutex +) + +// Ensure, that KontainerDriversGetterMock does implement v31.KontainerDriversGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.KontainerDriversGetter = &KontainerDriversGetterMock{} + +// KontainerDriversGetterMock is a mock implementation of v31.KontainerDriversGetter. +// +// func TestSomethingThatUsesKontainerDriversGetter(t *testing.T) { +// +// // make and configure a mocked v31.KontainerDriversGetter +// mockedKontainerDriversGetter := &KontainerDriversGetterMock{ +// KontainerDriversFunc: func(namespace string) v31.KontainerDriverInterface { +// panic("mock out the KontainerDrivers method") +// }, +// } +// +// // use mockedKontainerDriversGetter in code that requires v31.KontainerDriversGetter +// // and then make assertions. +// +// } +type KontainerDriversGetterMock struct { + // KontainerDriversFunc mocks the KontainerDrivers method. + KontainerDriversFunc func(namespace string) v31.KontainerDriverInterface + + // calls tracks calls to the methods. + calls struct { + // KontainerDrivers holds details about calls to the KontainerDrivers method. + KontainerDrivers []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// KontainerDrivers calls KontainerDriversFunc. +func (mock *KontainerDriversGetterMock) KontainerDrivers(namespace string) v31.KontainerDriverInterface { + if mock.KontainerDriversFunc == nil { + panic("KontainerDriversGetterMock.KontainerDriversFunc: method is nil but KontainerDriversGetter.KontainerDrivers was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockKontainerDriversGetterMockKontainerDrivers.Lock() + mock.calls.KontainerDrivers = append(mock.calls.KontainerDrivers, callInfo) + lockKontainerDriversGetterMockKontainerDrivers.Unlock() + return mock.KontainerDriversFunc(namespace) +} + +// KontainerDriversCalls gets all the calls that were made to KontainerDrivers. +// Check the length with: +// +// len(mockedKontainerDriversGetter.KontainerDriversCalls()) +func (mock *KontainerDriversGetterMock) KontainerDriversCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockKontainerDriversGetterMockKontainerDrivers.RLock() + calls = mock.calls.KontainerDrivers + lockKontainerDriversGetterMockKontainerDrivers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_ldap_config_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_ldap_config_mock.go new file mode 100644 index 0000000..920e963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_ldap_config_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockLdapConfigListerMockGet sync.RWMutex + lockLdapConfigListerMockList sync.RWMutex +) + +// Ensure, that LdapConfigListerMock does implement v31.LdapConfigLister. +// If this is not the case, regenerate this file with moq. +var _ v31.LdapConfigLister = &LdapConfigListerMock{} + +// LdapConfigListerMock is a mock implementation of v31.LdapConfigLister. +// +// func TestSomethingThatUsesLdapConfigLister(t *testing.T) { +// +// // make and configure a mocked v31.LdapConfigLister +// mockedLdapConfigLister := &LdapConfigListerMock{ +// GetFunc: func(namespace string, name string) (*v3.LdapConfig, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.LdapConfig, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedLdapConfigLister in code that requires v31.LdapConfigLister +// // and then make assertions. +// +// } +type LdapConfigListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.LdapConfig, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.LdapConfig, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *LdapConfigListerMock) Get(namespace string, name string) (*v3.LdapConfig, error) { + if mock.GetFunc == nil { + panic("LdapConfigListerMock.GetFunc: method is nil but LdapConfigLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockLdapConfigListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockLdapConfigListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedLdapConfigLister.GetCalls()) +func (mock *LdapConfigListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockLdapConfigListerMockGet.RLock() + calls = mock.calls.Get + lockLdapConfigListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *LdapConfigListerMock) List(namespace string, selector labels.Selector) ([]*v3.LdapConfig, error) { + if mock.ListFunc == nil { + panic("LdapConfigListerMock.ListFunc: method is nil but LdapConfigLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockLdapConfigListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockLdapConfigListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedLdapConfigLister.ListCalls()) +func (mock *LdapConfigListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockLdapConfigListerMockList.RLock() + calls = mock.calls.List + lockLdapConfigListerMockList.RUnlock() + return calls +} + +var ( + lockLdapConfigControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockLdapConfigControllerMockAddClusterScopedHandler sync.RWMutex + lockLdapConfigControllerMockAddFeatureHandler sync.RWMutex + lockLdapConfigControllerMockAddHandler sync.RWMutex + lockLdapConfigControllerMockEnqueue sync.RWMutex + lockLdapConfigControllerMockEnqueueAfter sync.RWMutex + lockLdapConfigControllerMockGeneric sync.RWMutex + lockLdapConfigControllerMockInformer sync.RWMutex + lockLdapConfigControllerMockLister sync.RWMutex +) + +// Ensure, that LdapConfigControllerMock does implement v31.LdapConfigController. +// If this is not the case, regenerate this file with moq. +var _ v31.LdapConfigController = &LdapConfigControllerMock{} + +// LdapConfigControllerMock is a mock implementation of v31.LdapConfigController. +// +// func TestSomethingThatUsesLdapConfigController(t *testing.T) { +// +// // make and configure a mocked v31.LdapConfigController +// mockedLdapConfigController := &LdapConfigControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.LdapConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.LdapConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.LdapConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.LdapConfigLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedLdapConfigController in code that requires v31.LdapConfigController +// // and then make assertions. +// +// } +type LdapConfigControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.LdapConfigHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.LdapConfigHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.LdapConfigHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.LdapConfigLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.LdapConfigHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.LdapConfigHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.LdapConfigHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.LdapConfigHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *LdapConfigControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.LdapConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("LdapConfigControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but LdapConfigController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockLdapConfigControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockLdapConfigControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedLdapConfigController.AddClusterScopedFeatureHandlerCalls()) +func (mock *LdapConfigControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc + } + lockLdapConfigControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockLdapConfigControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *LdapConfigControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.LdapConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("LdapConfigControllerMock.AddClusterScopedHandlerFunc: method is nil but LdapConfigController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockLdapConfigControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockLdapConfigControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedLdapConfigController.AddClusterScopedHandlerCalls()) +func (mock *LdapConfigControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.LdapConfigHandlerFunc + } + lockLdapConfigControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockLdapConfigControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *LdapConfigControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("LdapConfigControllerMock.AddFeatureHandlerFunc: method is nil but LdapConfigController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockLdapConfigControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockLdapConfigControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedLdapConfigController.AddFeatureHandlerCalls()) +func (mock *LdapConfigControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc + } + lockLdapConfigControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockLdapConfigControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *LdapConfigControllerMock) AddHandler(ctx context.Context, name string, handler v31.LdapConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("LdapConfigControllerMock.AddHandlerFunc: method is nil but LdapConfigController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockLdapConfigControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockLdapConfigControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedLdapConfigController.AddHandlerCalls()) +func (mock *LdapConfigControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.LdapConfigHandlerFunc + } + lockLdapConfigControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockLdapConfigControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *LdapConfigControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("LdapConfigControllerMock.EnqueueFunc: method is nil but LdapConfigController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockLdapConfigControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockLdapConfigControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedLdapConfigController.EnqueueCalls()) +func (mock *LdapConfigControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockLdapConfigControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockLdapConfigControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *LdapConfigControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("LdapConfigControllerMock.EnqueueAfterFunc: method is nil but LdapConfigController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockLdapConfigControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockLdapConfigControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedLdapConfigController.EnqueueAfterCalls()) +func (mock *LdapConfigControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockLdapConfigControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockLdapConfigControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *LdapConfigControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("LdapConfigControllerMock.GenericFunc: method is nil but LdapConfigController.Generic was just called") + } + callInfo := struct { + }{} + lockLdapConfigControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockLdapConfigControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedLdapConfigController.GenericCalls()) +func (mock *LdapConfigControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockLdapConfigControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockLdapConfigControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *LdapConfigControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("LdapConfigControllerMock.InformerFunc: method is nil but LdapConfigController.Informer was just called") + } + callInfo := struct { + }{} + lockLdapConfigControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockLdapConfigControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedLdapConfigController.InformerCalls()) +func (mock *LdapConfigControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockLdapConfigControllerMockInformer.RLock() + calls = mock.calls.Informer + lockLdapConfigControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *LdapConfigControllerMock) Lister() v31.LdapConfigLister { + if mock.ListerFunc == nil { + panic("LdapConfigControllerMock.ListerFunc: method is nil but LdapConfigController.Lister was just called") + } + callInfo := struct { + }{} + lockLdapConfigControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockLdapConfigControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedLdapConfigController.ListerCalls()) +func (mock *LdapConfigControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockLdapConfigControllerMockLister.RLock() + calls = mock.calls.Lister + lockLdapConfigControllerMockLister.RUnlock() + return calls +} + +var ( + lockLdapConfigInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockLdapConfigInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockLdapConfigInterfaceMockAddClusterScopedHandler sync.RWMutex + lockLdapConfigInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockLdapConfigInterfaceMockAddFeatureHandler sync.RWMutex + lockLdapConfigInterfaceMockAddFeatureLifecycle sync.RWMutex + lockLdapConfigInterfaceMockAddHandler sync.RWMutex + lockLdapConfigInterfaceMockAddLifecycle sync.RWMutex + lockLdapConfigInterfaceMockController sync.RWMutex + lockLdapConfigInterfaceMockCreate sync.RWMutex + lockLdapConfigInterfaceMockDelete sync.RWMutex + lockLdapConfigInterfaceMockDeleteCollection sync.RWMutex + lockLdapConfigInterfaceMockDeleteNamespaced sync.RWMutex + lockLdapConfigInterfaceMockGet sync.RWMutex + lockLdapConfigInterfaceMockGetNamespaced sync.RWMutex + lockLdapConfigInterfaceMockList sync.RWMutex + lockLdapConfigInterfaceMockListNamespaced sync.RWMutex + lockLdapConfigInterfaceMockObjectClient sync.RWMutex + lockLdapConfigInterfaceMockUpdate sync.RWMutex + lockLdapConfigInterfaceMockWatch sync.RWMutex +) + +// Ensure, that LdapConfigInterfaceMock does implement v31.LdapConfigInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.LdapConfigInterface = &LdapConfigInterfaceMock{} + +// LdapConfigInterfaceMock is a mock implementation of v31.LdapConfigInterface. +// +// func TestSomethingThatUsesLdapConfigInterface(t *testing.T) { +// +// // make and configure a mocked v31.LdapConfigInterface +// mockedLdapConfigInterface := &LdapConfigInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.LdapConfigLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.LdapConfigHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.LdapConfigLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.LdapConfigController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.LdapConfig) (*v3.LdapConfig, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.LdapConfigList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.LdapConfigList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.LdapConfig) (*v3.LdapConfig, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedLdapConfigInterface in code that requires v31.LdapConfigInterface +// // and then make assertions. +// +// } +type LdapConfigInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.LdapConfigLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.LdapConfigHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.LdapConfigLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.LdapConfigController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.LdapConfig) (*v3.LdapConfig, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.LdapConfig, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.LdapConfig, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.LdapConfigList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.LdapConfigList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.LdapConfig) (*v3.LdapConfig, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.LdapConfigHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.LdapConfigLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.LdapConfigHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.LdapConfigLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.LdapConfigHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.LdapConfigLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.LdapConfigHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.LdapConfigLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.LdapConfig + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.LdapConfig + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *LdapConfigInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("LdapConfigInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but LdapConfigInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockLdapConfigInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockLdapConfigInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *LdapConfigInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc + } + lockLdapConfigInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockLdapConfigInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *LdapConfigInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("LdapConfigInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but LdapConfigInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockLdapConfigInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockLdapConfigInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *LdapConfigInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle + } + lockLdapConfigInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockLdapConfigInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *LdapConfigInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.LdapConfigHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("LdapConfigInterfaceMock.AddClusterScopedHandlerFunc: method is nil but LdapConfigInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockLdapConfigInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockLdapConfigInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddClusterScopedHandlerCalls()) +func (mock *LdapConfigInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.LdapConfigHandlerFunc + } + lockLdapConfigInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockLdapConfigInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *LdapConfigInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.LdapConfigLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("LdapConfigInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but LdapConfigInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockLdapConfigInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockLdapConfigInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddClusterScopedLifecycleCalls()) +func (mock *LdapConfigInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.LdapConfigLifecycle + } + lockLdapConfigInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockLdapConfigInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *LdapConfigInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.LdapConfigHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("LdapConfigInterfaceMock.AddFeatureHandlerFunc: method is nil but LdapConfigInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockLdapConfigInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockLdapConfigInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddFeatureHandlerCalls()) +func (mock *LdapConfigInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.LdapConfigHandlerFunc + } + lockLdapConfigInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockLdapConfigInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *LdapConfigInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.LdapConfigLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("LdapConfigInterfaceMock.AddFeatureLifecycleFunc: method is nil but LdapConfigInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.LdapConfigLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockLdapConfigInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockLdapConfigInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddFeatureLifecycleCalls()) +func (mock *LdapConfigInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.LdapConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.LdapConfigLifecycle + } + lockLdapConfigInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockLdapConfigInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *LdapConfigInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.LdapConfigHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("LdapConfigInterfaceMock.AddHandlerFunc: method is nil but LdapConfigInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.LdapConfigHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockLdapConfigInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockLdapConfigInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddHandlerCalls()) +func (mock *LdapConfigInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.LdapConfigHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.LdapConfigHandlerFunc + } + lockLdapConfigInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockLdapConfigInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *LdapConfigInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.LdapConfigLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("LdapConfigInterfaceMock.AddLifecycleFunc: method is nil but LdapConfigInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.LdapConfigLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockLdapConfigInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockLdapConfigInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedLdapConfigInterface.AddLifecycleCalls()) +func (mock *LdapConfigInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.LdapConfigLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.LdapConfigLifecycle + } + lockLdapConfigInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockLdapConfigInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *LdapConfigInterfaceMock) Controller() v31.LdapConfigController { + if mock.ControllerFunc == nil { + panic("LdapConfigInterfaceMock.ControllerFunc: method is nil but LdapConfigInterface.Controller was just called") + } + callInfo := struct { + }{} + lockLdapConfigInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockLdapConfigInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedLdapConfigInterface.ControllerCalls()) +func (mock *LdapConfigInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockLdapConfigInterfaceMockController.RLock() + calls = mock.calls.Controller + lockLdapConfigInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *LdapConfigInterfaceMock) Create(in1 *v3.LdapConfig) (*v3.LdapConfig, error) { + if mock.CreateFunc == nil { + panic("LdapConfigInterfaceMock.CreateFunc: method is nil but LdapConfigInterface.Create was just called") + } + callInfo := struct { + In1 *v3.LdapConfig + }{ + In1: in1, + } + lockLdapConfigInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockLdapConfigInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedLdapConfigInterface.CreateCalls()) +func (mock *LdapConfigInterfaceMock) CreateCalls() []struct { + In1 *v3.LdapConfig +} { + var calls []struct { + In1 *v3.LdapConfig + } + lockLdapConfigInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockLdapConfigInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *LdapConfigInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("LdapConfigInterfaceMock.DeleteFunc: method is nil but LdapConfigInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockLdapConfigInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockLdapConfigInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedLdapConfigInterface.DeleteCalls()) +func (mock *LdapConfigInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockLdapConfigInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockLdapConfigInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *LdapConfigInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("LdapConfigInterfaceMock.DeleteCollectionFunc: method is nil but LdapConfigInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockLdapConfigInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockLdapConfigInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedLdapConfigInterface.DeleteCollectionCalls()) +func (mock *LdapConfigInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockLdapConfigInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockLdapConfigInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *LdapConfigInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("LdapConfigInterfaceMock.DeleteNamespacedFunc: method is nil but LdapConfigInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockLdapConfigInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockLdapConfigInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedLdapConfigInterface.DeleteNamespacedCalls()) +func (mock *LdapConfigInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockLdapConfigInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockLdapConfigInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *LdapConfigInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { + if mock.GetFunc == nil { + panic("LdapConfigInterfaceMock.GetFunc: method is nil but LdapConfigInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockLdapConfigInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockLdapConfigInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedLdapConfigInterface.GetCalls()) +func (mock *LdapConfigInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockLdapConfigInterfaceMockGet.RLock() + calls = mock.calls.Get + lockLdapConfigInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *LdapConfigInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { + if mock.GetNamespacedFunc == nil { + panic("LdapConfigInterfaceMock.GetNamespacedFunc: method is nil but LdapConfigInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockLdapConfigInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockLdapConfigInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedLdapConfigInterface.GetNamespacedCalls()) +func (mock *LdapConfigInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockLdapConfigInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockLdapConfigInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *LdapConfigInterfaceMock) List(opts metav1.ListOptions) (*v3.LdapConfigList, error) { + if mock.ListFunc == nil { + panic("LdapConfigInterfaceMock.ListFunc: method is nil but LdapConfigInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockLdapConfigInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockLdapConfigInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedLdapConfigInterface.ListCalls()) +func (mock *LdapConfigInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockLdapConfigInterfaceMockList.RLock() + calls = mock.calls.List + lockLdapConfigInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *LdapConfigInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.LdapConfigList, error) { + if mock.ListNamespacedFunc == nil { + panic("LdapConfigInterfaceMock.ListNamespacedFunc: method is nil but LdapConfigInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockLdapConfigInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockLdapConfigInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedLdapConfigInterface.ListNamespacedCalls()) +func (mock *LdapConfigInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockLdapConfigInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockLdapConfigInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *LdapConfigInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("LdapConfigInterfaceMock.ObjectClientFunc: method is nil but LdapConfigInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockLdapConfigInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockLdapConfigInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedLdapConfigInterface.ObjectClientCalls()) +func (mock *LdapConfigInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockLdapConfigInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockLdapConfigInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *LdapConfigInterfaceMock) Update(in1 *v3.LdapConfig) (*v3.LdapConfig, error) { + if mock.UpdateFunc == nil { + panic("LdapConfigInterfaceMock.UpdateFunc: method is nil but LdapConfigInterface.Update was just called") + } + callInfo := struct { + In1 *v3.LdapConfig + }{ + In1: in1, + } + lockLdapConfigInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockLdapConfigInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedLdapConfigInterface.UpdateCalls()) +func (mock *LdapConfigInterfaceMock) UpdateCalls() []struct { + In1 *v3.LdapConfig +} { + var calls []struct { + In1 *v3.LdapConfig + } + lockLdapConfigInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockLdapConfigInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *LdapConfigInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("LdapConfigInterfaceMock.WatchFunc: method is nil but LdapConfigInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockLdapConfigInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockLdapConfigInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedLdapConfigInterface.WatchCalls()) +func (mock *LdapConfigInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockLdapConfigInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockLdapConfigInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockLdapConfigsGetterMockLdapConfigs sync.RWMutex +) + +// Ensure, that LdapConfigsGetterMock does implement v31.LdapConfigsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.LdapConfigsGetter = &LdapConfigsGetterMock{} + +// LdapConfigsGetterMock is a mock implementation of v31.LdapConfigsGetter. +// +// func TestSomethingThatUsesLdapConfigsGetter(t *testing.T) { +// +// // make and configure a mocked v31.LdapConfigsGetter +// mockedLdapConfigsGetter := &LdapConfigsGetterMock{ +// LdapConfigsFunc: func(namespace string) v31.LdapConfigInterface { +// panic("mock out the LdapConfigs method") +// }, +// } +// +// // use mockedLdapConfigsGetter in code that requires v31.LdapConfigsGetter +// // and then make assertions. +// +// } +type LdapConfigsGetterMock struct { + // LdapConfigsFunc mocks the LdapConfigs method. + LdapConfigsFunc func(namespace string) v31.LdapConfigInterface + + // calls tracks calls to the methods. + calls struct { + // LdapConfigs holds details about calls to the LdapConfigs method. + LdapConfigs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// LdapConfigs calls LdapConfigsFunc. +func (mock *LdapConfigsGetterMock) LdapConfigs(namespace string) v31.LdapConfigInterface { + if mock.LdapConfigsFunc == nil { + panic("LdapConfigsGetterMock.LdapConfigsFunc: method is nil but LdapConfigsGetter.LdapConfigs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockLdapConfigsGetterMockLdapConfigs.Lock() + mock.calls.LdapConfigs = append(mock.calls.LdapConfigs, callInfo) + lockLdapConfigsGetterMockLdapConfigs.Unlock() + return mock.LdapConfigsFunc(namespace) +} + +// LdapConfigsCalls gets all the calls that were made to LdapConfigs. +// Check the length with: +// +// len(mockedLdapConfigsGetter.LdapConfigsCalls()) +func (mock *LdapConfigsGetterMock) LdapConfigsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockLdapConfigsGetterMockLdapConfigs.RLock() + calls = mock.calls.LdapConfigs + lockLdapConfigsGetterMockLdapConfigs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_mock.go new file mode 100644 index 0000000..d5a6a1f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockMultiClusterAppListerMockGet sync.RWMutex + lockMultiClusterAppListerMockList sync.RWMutex +) + +// Ensure, that MultiClusterAppListerMock does implement v31.MultiClusterAppLister. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppLister = &MultiClusterAppListerMock{} + +// MultiClusterAppListerMock is a mock implementation of v31.MultiClusterAppLister. +// +// func TestSomethingThatUsesMultiClusterAppLister(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppLister +// mockedMultiClusterAppLister := &MultiClusterAppListerMock{ +// GetFunc: func(namespace string, name string) (*v3.MultiClusterApp, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.MultiClusterApp, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedMultiClusterAppLister in code that requires v31.MultiClusterAppLister +// // and then make assertions. +// +// } +type MultiClusterAppListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.MultiClusterApp, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.MultiClusterApp, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *MultiClusterAppListerMock) Get(namespace string, name string) (*v3.MultiClusterApp, error) { + if mock.GetFunc == nil { + panic("MultiClusterAppListerMock.GetFunc: method is nil but MultiClusterAppLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockMultiClusterAppListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockMultiClusterAppListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedMultiClusterAppLister.GetCalls()) +func (mock *MultiClusterAppListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockMultiClusterAppListerMockGet.RLock() + calls = mock.calls.Get + lockMultiClusterAppListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *MultiClusterAppListerMock) List(namespace string, selector labels.Selector) ([]*v3.MultiClusterApp, error) { + if mock.ListFunc == nil { + panic("MultiClusterAppListerMock.ListFunc: method is nil but MultiClusterAppLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockMultiClusterAppListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockMultiClusterAppListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedMultiClusterAppLister.ListCalls()) +func (mock *MultiClusterAppListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockMultiClusterAppListerMockList.RLock() + calls = mock.calls.List + lockMultiClusterAppListerMockList.RUnlock() + return calls +} + +var ( + lockMultiClusterAppControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockMultiClusterAppControllerMockAddClusterScopedHandler sync.RWMutex + lockMultiClusterAppControllerMockAddFeatureHandler sync.RWMutex + lockMultiClusterAppControllerMockAddHandler sync.RWMutex + lockMultiClusterAppControllerMockEnqueue sync.RWMutex + lockMultiClusterAppControllerMockEnqueueAfter sync.RWMutex + lockMultiClusterAppControllerMockGeneric sync.RWMutex + lockMultiClusterAppControllerMockInformer sync.RWMutex + lockMultiClusterAppControllerMockLister sync.RWMutex +) + +// Ensure, that MultiClusterAppControllerMock does implement v31.MultiClusterAppController. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppController = &MultiClusterAppControllerMock{} + +// MultiClusterAppControllerMock is a mock implementation of v31.MultiClusterAppController. +// +// func TestSomethingThatUsesMultiClusterAppController(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppController +// mockedMultiClusterAppController := &MultiClusterAppControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.MultiClusterAppLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedMultiClusterAppController in code that requires v31.MultiClusterAppController +// // and then make assertions. +// +// } +type MultiClusterAppControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.MultiClusterAppHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.MultiClusterAppLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.MultiClusterAppHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.MultiClusterAppHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.MultiClusterAppHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *MultiClusterAppControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("MultiClusterAppControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but MultiClusterAppController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockMultiClusterAppControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockMultiClusterAppControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppController.AddClusterScopedFeatureHandlerCalls()) +func (mock *MultiClusterAppControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockMultiClusterAppControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *MultiClusterAppControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("MultiClusterAppControllerMock.AddClusterScopedHandlerFunc: method is nil but MultiClusterAppController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockMultiClusterAppControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockMultiClusterAppControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedMultiClusterAppController.AddClusterScopedHandlerCalls()) +func (mock *MultiClusterAppControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockMultiClusterAppControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *MultiClusterAppControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("MultiClusterAppControllerMock.AddFeatureHandlerFunc: method is nil but MultiClusterAppController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockMultiClusterAppControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppController.AddFeatureHandlerCalls()) +func (mock *MultiClusterAppControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockMultiClusterAppControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *MultiClusterAppControllerMock) AddHandler(ctx context.Context, name string, handler v31.MultiClusterAppHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("MultiClusterAppControllerMock.AddHandlerFunc: method is nil but MultiClusterAppController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockMultiClusterAppControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockMultiClusterAppControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedMultiClusterAppController.AddHandlerCalls()) +func (mock *MultiClusterAppControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockMultiClusterAppControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *MultiClusterAppControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("MultiClusterAppControllerMock.EnqueueFunc: method is nil but MultiClusterAppController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockMultiClusterAppControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockMultiClusterAppControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedMultiClusterAppController.EnqueueCalls()) +func (mock *MultiClusterAppControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockMultiClusterAppControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockMultiClusterAppControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *MultiClusterAppControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("MultiClusterAppControllerMock.EnqueueAfterFunc: method is nil but MultiClusterAppController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockMultiClusterAppControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockMultiClusterAppControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedMultiClusterAppController.EnqueueAfterCalls()) +func (mock *MultiClusterAppControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockMultiClusterAppControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockMultiClusterAppControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *MultiClusterAppControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("MultiClusterAppControllerMock.GenericFunc: method is nil but MultiClusterAppController.Generic was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockMultiClusterAppControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedMultiClusterAppController.GenericCalls()) +func (mock *MultiClusterAppControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockMultiClusterAppControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *MultiClusterAppControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("MultiClusterAppControllerMock.InformerFunc: method is nil but MultiClusterAppController.Informer was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockMultiClusterAppControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedMultiClusterAppController.InformerCalls()) +func (mock *MultiClusterAppControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppControllerMockInformer.RLock() + calls = mock.calls.Informer + lockMultiClusterAppControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *MultiClusterAppControllerMock) Lister() v31.MultiClusterAppLister { + if mock.ListerFunc == nil { + panic("MultiClusterAppControllerMock.ListerFunc: method is nil but MultiClusterAppController.Lister was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockMultiClusterAppControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedMultiClusterAppController.ListerCalls()) +func (mock *MultiClusterAppControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppControllerMockLister.RLock() + calls = mock.calls.Lister + lockMultiClusterAppControllerMockLister.RUnlock() + return calls +} + +var ( + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockMultiClusterAppInterfaceMockAddClusterScopedHandler sync.RWMutex + lockMultiClusterAppInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockMultiClusterAppInterfaceMockAddFeatureHandler sync.RWMutex + lockMultiClusterAppInterfaceMockAddFeatureLifecycle sync.RWMutex + lockMultiClusterAppInterfaceMockAddHandler sync.RWMutex + lockMultiClusterAppInterfaceMockAddLifecycle sync.RWMutex + lockMultiClusterAppInterfaceMockController sync.RWMutex + lockMultiClusterAppInterfaceMockCreate sync.RWMutex + lockMultiClusterAppInterfaceMockDelete sync.RWMutex + lockMultiClusterAppInterfaceMockDeleteCollection sync.RWMutex + lockMultiClusterAppInterfaceMockDeleteNamespaced sync.RWMutex + lockMultiClusterAppInterfaceMockGet sync.RWMutex + lockMultiClusterAppInterfaceMockGetNamespaced sync.RWMutex + lockMultiClusterAppInterfaceMockList sync.RWMutex + lockMultiClusterAppInterfaceMockListNamespaced sync.RWMutex + lockMultiClusterAppInterfaceMockObjectClient sync.RWMutex + lockMultiClusterAppInterfaceMockUpdate sync.RWMutex + lockMultiClusterAppInterfaceMockWatch sync.RWMutex +) + +// Ensure, that MultiClusterAppInterfaceMock does implement v31.MultiClusterAppInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppInterface = &MultiClusterAppInterfaceMock{} + +// MultiClusterAppInterfaceMock is a mock implementation of v31.MultiClusterAppInterface. +// +// func TestSomethingThatUsesMultiClusterAppInterface(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppInterface +// mockedMultiClusterAppInterface := &MultiClusterAppInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.MultiClusterAppLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.MultiClusterAppController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedMultiClusterAppInterface in code that requires v31.MultiClusterAppInterface +// // and then make assertions. +// +// } +type MultiClusterAppInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.MultiClusterAppLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.MultiClusterAppController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.MultiClusterAppList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.MultiClusterAppHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.MultiClusterAppHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.MultiClusterApp + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.MultiClusterApp + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("MultiClusterAppInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but MultiClusterAppInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("MultiClusterAppInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but MultiClusterAppInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle + } + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockMultiClusterAppInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("MultiClusterAppInterfaceMock.AddClusterScopedHandlerFunc: method is nil but MultiClusterAppInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockMultiClusterAppInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockMultiClusterAppInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddClusterScopedHandlerCalls()) +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockMultiClusterAppInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("MultiClusterAppInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but MultiClusterAppInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockMultiClusterAppInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockMultiClusterAppInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddClusterScopedLifecycleCalls()) +func (mock *MultiClusterAppInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppLifecycle + } + lockMultiClusterAppInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockMultiClusterAppInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *MultiClusterAppInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("MultiClusterAppInterfaceMock.AddFeatureHandlerFunc: method is nil but MultiClusterAppInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockMultiClusterAppInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddFeatureHandlerCalls()) +func (mock *MultiClusterAppInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockMultiClusterAppInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *MultiClusterAppInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("MultiClusterAppInterfaceMock.AddFeatureLifecycleFunc: method is nil but MultiClusterAppInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockMultiClusterAppInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockMultiClusterAppInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddFeatureLifecycleCalls()) +func (mock *MultiClusterAppInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppLifecycle + } + lockMultiClusterAppInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockMultiClusterAppInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *MultiClusterAppInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("MultiClusterAppInterfaceMock.AddHandlerFunc: method is nil but MultiClusterAppInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockMultiClusterAppInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddHandlerCalls()) +func (mock *MultiClusterAppInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppHandlerFunc + } + lockMultiClusterAppInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockMultiClusterAppInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *MultiClusterAppInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.MultiClusterAppLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("MultiClusterAppInterfaceMock.AddLifecycleFunc: method is nil but MultiClusterAppInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockMultiClusterAppInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockMultiClusterAppInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.AddLifecycleCalls()) +func (mock *MultiClusterAppInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppLifecycle + } + lockMultiClusterAppInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockMultiClusterAppInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *MultiClusterAppInterfaceMock) Controller() v31.MultiClusterAppController { + if mock.ControllerFunc == nil { + panic("MultiClusterAppInterfaceMock.ControllerFunc: method is nil but MultiClusterAppInterface.Controller was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockMultiClusterAppInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.ControllerCalls()) +func (mock *MultiClusterAppInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppInterfaceMockController.RLock() + calls = mock.calls.Controller + lockMultiClusterAppInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *MultiClusterAppInterfaceMock) Create(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + if mock.CreateFunc == nil { + panic("MultiClusterAppInterfaceMock.CreateFunc: method is nil but MultiClusterAppInterface.Create was just called") + } + callInfo := struct { + In1 *v3.MultiClusterApp + }{ + In1: in1, + } + lockMultiClusterAppInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockMultiClusterAppInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.CreateCalls()) +func (mock *MultiClusterAppInterfaceMock) CreateCalls() []struct { + In1 *v3.MultiClusterApp +} { + var calls []struct { + In1 *v3.MultiClusterApp + } + lockMultiClusterAppInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockMultiClusterAppInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *MultiClusterAppInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("MultiClusterAppInterfaceMock.DeleteFunc: method is nil but MultiClusterAppInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockMultiClusterAppInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockMultiClusterAppInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.DeleteCalls()) +func (mock *MultiClusterAppInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockMultiClusterAppInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockMultiClusterAppInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *MultiClusterAppInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("MultiClusterAppInterfaceMock.DeleteCollectionFunc: method is nil but MultiClusterAppInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockMultiClusterAppInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockMultiClusterAppInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.DeleteCollectionCalls()) +func (mock *MultiClusterAppInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockMultiClusterAppInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockMultiClusterAppInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *MultiClusterAppInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("MultiClusterAppInterfaceMock.DeleteNamespacedFunc: method is nil but MultiClusterAppInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockMultiClusterAppInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockMultiClusterAppInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.DeleteNamespacedCalls()) +func (mock *MultiClusterAppInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockMultiClusterAppInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockMultiClusterAppInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *MultiClusterAppInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { + if mock.GetFunc == nil { + panic("MultiClusterAppInterfaceMock.GetFunc: method is nil but MultiClusterAppInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockMultiClusterAppInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockMultiClusterAppInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.GetCalls()) +func (mock *MultiClusterAppInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockMultiClusterAppInterfaceMockGet.RLock() + calls = mock.calls.Get + lockMultiClusterAppInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *MultiClusterAppInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { + if mock.GetNamespacedFunc == nil { + panic("MultiClusterAppInterfaceMock.GetNamespacedFunc: method is nil but MultiClusterAppInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockMultiClusterAppInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockMultiClusterAppInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.GetNamespacedCalls()) +func (mock *MultiClusterAppInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockMultiClusterAppInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockMultiClusterAppInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *MultiClusterAppInterfaceMock) List(opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { + if mock.ListFunc == nil { + panic("MultiClusterAppInterfaceMock.ListFunc: method is nil but MultiClusterAppInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockMultiClusterAppInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockMultiClusterAppInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.ListCalls()) +func (mock *MultiClusterAppInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockMultiClusterAppInterfaceMockList.RLock() + calls = mock.calls.List + lockMultiClusterAppInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *MultiClusterAppInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { + if mock.ListNamespacedFunc == nil { + panic("MultiClusterAppInterfaceMock.ListNamespacedFunc: method is nil but MultiClusterAppInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockMultiClusterAppInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockMultiClusterAppInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.ListNamespacedCalls()) +func (mock *MultiClusterAppInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockMultiClusterAppInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockMultiClusterAppInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *MultiClusterAppInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("MultiClusterAppInterfaceMock.ObjectClientFunc: method is nil but MultiClusterAppInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockMultiClusterAppInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.ObjectClientCalls()) +func (mock *MultiClusterAppInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockMultiClusterAppInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *MultiClusterAppInterfaceMock) Update(in1 *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + if mock.UpdateFunc == nil { + panic("MultiClusterAppInterfaceMock.UpdateFunc: method is nil but MultiClusterAppInterface.Update was just called") + } + callInfo := struct { + In1 *v3.MultiClusterApp + }{ + In1: in1, + } + lockMultiClusterAppInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockMultiClusterAppInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.UpdateCalls()) +func (mock *MultiClusterAppInterfaceMock) UpdateCalls() []struct { + In1 *v3.MultiClusterApp +} { + var calls []struct { + In1 *v3.MultiClusterApp + } + lockMultiClusterAppInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockMultiClusterAppInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *MultiClusterAppInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("MultiClusterAppInterfaceMock.WatchFunc: method is nil but MultiClusterAppInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockMultiClusterAppInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockMultiClusterAppInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedMultiClusterAppInterface.WatchCalls()) +func (mock *MultiClusterAppInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockMultiClusterAppInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockMultiClusterAppInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockMultiClusterAppsGetterMockMultiClusterApps sync.RWMutex +) + +// Ensure, that MultiClusterAppsGetterMock does implement v31.MultiClusterAppsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppsGetter = &MultiClusterAppsGetterMock{} + +// MultiClusterAppsGetterMock is a mock implementation of v31.MultiClusterAppsGetter. +// +// func TestSomethingThatUsesMultiClusterAppsGetter(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppsGetter +// mockedMultiClusterAppsGetter := &MultiClusterAppsGetterMock{ +// MultiClusterAppsFunc: func(namespace string) v31.MultiClusterAppInterface { +// panic("mock out the MultiClusterApps method") +// }, +// } +// +// // use mockedMultiClusterAppsGetter in code that requires v31.MultiClusterAppsGetter +// // and then make assertions. +// +// } +type MultiClusterAppsGetterMock struct { + // MultiClusterAppsFunc mocks the MultiClusterApps method. + MultiClusterAppsFunc func(namespace string) v31.MultiClusterAppInterface + + // calls tracks calls to the methods. + calls struct { + // MultiClusterApps holds details about calls to the MultiClusterApps method. + MultiClusterApps []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// MultiClusterApps calls MultiClusterAppsFunc. +func (mock *MultiClusterAppsGetterMock) MultiClusterApps(namespace string) v31.MultiClusterAppInterface { + if mock.MultiClusterAppsFunc == nil { + panic("MultiClusterAppsGetterMock.MultiClusterAppsFunc: method is nil but MultiClusterAppsGetter.MultiClusterApps was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockMultiClusterAppsGetterMockMultiClusterApps.Lock() + mock.calls.MultiClusterApps = append(mock.calls.MultiClusterApps, callInfo) + lockMultiClusterAppsGetterMockMultiClusterApps.Unlock() + return mock.MultiClusterAppsFunc(namespace) +} + +// MultiClusterAppsCalls gets all the calls that were made to MultiClusterApps. +// Check the length with: +// +// len(mockedMultiClusterAppsGetter.MultiClusterAppsCalls()) +func (mock *MultiClusterAppsGetterMock) MultiClusterAppsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockMultiClusterAppsGetterMockMultiClusterApps.RLock() + calls = mock.calls.MultiClusterApps + lockMultiClusterAppsGetterMockMultiClusterApps.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_revision_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_revision_mock.go new file mode 100644 index 0000000..9ab2e91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_multi_cluster_app_revision_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockMultiClusterAppRevisionListerMockGet sync.RWMutex + lockMultiClusterAppRevisionListerMockList sync.RWMutex +) + +// Ensure, that MultiClusterAppRevisionListerMock does implement v31.MultiClusterAppRevisionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppRevisionLister = &MultiClusterAppRevisionListerMock{} + +// MultiClusterAppRevisionListerMock is a mock implementation of v31.MultiClusterAppRevisionLister. +// +// func TestSomethingThatUsesMultiClusterAppRevisionLister(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppRevisionLister +// mockedMultiClusterAppRevisionLister := &MultiClusterAppRevisionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.MultiClusterAppRevision, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.MultiClusterAppRevision, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedMultiClusterAppRevisionLister in code that requires v31.MultiClusterAppRevisionLister +// // and then make assertions. +// +// } +type MultiClusterAppRevisionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.MultiClusterAppRevision, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.MultiClusterAppRevision, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *MultiClusterAppRevisionListerMock) Get(namespace string, name string) (*v3.MultiClusterAppRevision, error) { + if mock.GetFunc == nil { + panic("MultiClusterAppRevisionListerMock.GetFunc: method is nil but MultiClusterAppRevisionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockMultiClusterAppRevisionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockMultiClusterAppRevisionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionLister.GetCalls()) +func (mock *MultiClusterAppRevisionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockMultiClusterAppRevisionListerMockGet.RLock() + calls = mock.calls.Get + lockMultiClusterAppRevisionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *MultiClusterAppRevisionListerMock) List(namespace string, selector labels.Selector) ([]*v3.MultiClusterAppRevision, error) { + if mock.ListFunc == nil { + panic("MultiClusterAppRevisionListerMock.ListFunc: method is nil but MultiClusterAppRevisionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockMultiClusterAppRevisionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockMultiClusterAppRevisionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionLister.ListCalls()) +func (mock *MultiClusterAppRevisionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockMultiClusterAppRevisionListerMockList.RLock() + calls = mock.calls.List + lockMultiClusterAppRevisionListerMockList.RUnlock() + return calls +} + +var ( + lockMultiClusterAppRevisionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockMultiClusterAppRevisionControllerMockAddClusterScopedHandler sync.RWMutex + lockMultiClusterAppRevisionControllerMockAddFeatureHandler sync.RWMutex + lockMultiClusterAppRevisionControllerMockAddHandler sync.RWMutex + lockMultiClusterAppRevisionControllerMockEnqueue sync.RWMutex + lockMultiClusterAppRevisionControllerMockEnqueueAfter sync.RWMutex + lockMultiClusterAppRevisionControllerMockGeneric sync.RWMutex + lockMultiClusterAppRevisionControllerMockInformer sync.RWMutex + lockMultiClusterAppRevisionControllerMockLister sync.RWMutex +) + +// Ensure, that MultiClusterAppRevisionControllerMock does implement v31.MultiClusterAppRevisionController. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppRevisionController = &MultiClusterAppRevisionControllerMock{} + +// MultiClusterAppRevisionControllerMock is a mock implementation of v31.MultiClusterAppRevisionController. +// +// func TestSomethingThatUsesMultiClusterAppRevisionController(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppRevisionController +// mockedMultiClusterAppRevisionController := &MultiClusterAppRevisionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.MultiClusterAppRevisionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedMultiClusterAppRevisionController in code that requires v31.MultiClusterAppRevisionController +// // and then make assertions. +// +// } +type MultiClusterAppRevisionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.MultiClusterAppRevisionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.MultiClusterAppRevisionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.MultiClusterAppRevisionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.MultiClusterAppRevisionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppRevisionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.MultiClusterAppRevisionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *MultiClusterAppRevisionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but MultiClusterAppRevisionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockMultiClusterAppRevisionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockMultiClusterAppRevisionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockMultiClusterAppRevisionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *MultiClusterAppRevisionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.AddClusterScopedHandlerFunc: method is nil but MultiClusterAppRevisionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockMultiClusterAppRevisionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockMultiClusterAppRevisionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.AddClusterScopedHandlerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockMultiClusterAppRevisionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *MultiClusterAppRevisionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.AddFeatureHandlerFunc: method is nil but MultiClusterAppRevisionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppRevisionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockMultiClusterAppRevisionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.AddFeatureHandlerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockMultiClusterAppRevisionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *MultiClusterAppRevisionControllerMock) AddHandler(ctx context.Context, name string, handler v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.AddHandlerFunc: method is nil but MultiClusterAppRevisionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockMultiClusterAppRevisionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockMultiClusterAppRevisionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.AddHandlerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockMultiClusterAppRevisionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *MultiClusterAppRevisionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("MultiClusterAppRevisionControllerMock.EnqueueFunc: method is nil but MultiClusterAppRevisionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockMultiClusterAppRevisionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockMultiClusterAppRevisionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.EnqueueCalls()) +func (mock *MultiClusterAppRevisionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockMultiClusterAppRevisionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockMultiClusterAppRevisionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *MultiClusterAppRevisionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("MultiClusterAppRevisionControllerMock.EnqueueAfterFunc: method is nil but MultiClusterAppRevisionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockMultiClusterAppRevisionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockMultiClusterAppRevisionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.EnqueueAfterCalls()) +func (mock *MultiClusterAppRevisionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockMultiClusterAppRevisionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockMultiClusterAppRevisionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *MultiClusterAppRevisionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("MultiClusterAppRevisionControllerMock.GenericFunc: method is nil but MultiClusterAppRevisionController.Generic was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppRevisionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockMultiClusterAppRevisionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.GenericCalls()) +func (mock *MultiClusterAppRevisionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppRevisionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockMultiClusterAppRevisionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *MultiClusterAppRevisionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.InformerFunc: method is nil but MultiClusterAppRevisionController.Informer was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppRevisionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockMultiClusterAppRevisionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.InformerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppRevisionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockMultiClusterAppRevisionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *MultiClusterAppRevisionControllerMock) Lister() v31.MultiClusterAppRevisionLister { + if mock.ListerFunc == nil { + panic("MultiClusterAppRevisionControllerMock.ListerFunc: method is nil but MultiClusterAppRevisionController.Lister was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppRevisionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockMultiClusterAppRevisionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionController.ListerCalls()) +func (mock *MultiClusterAppRevisionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppRevisionControllerMockLister.RLock() + calls = mock.calls.Lister + lockMultiClusterAppRevisionControllerMockLister.RUnlock() + return calls +} + +var ( + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddFeatureHandler sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddHandler sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockAddLifecycle sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockController sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockCreate sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockDelete sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockDeleteCollection sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockDeleteNamespaced sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockGet sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockGetNamespaced sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockList sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockListNamespaced sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockObjectClient sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockUpdate sync.RWMutex + lockMultiClusterAppRevisionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that MultiClusterAppRevisionInterfaceMock does implement v31.MultiClusterAppRevisionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppRevisionInterface = &MultiClusterAppRevisionInterfaceMock{} + +// MultiClusterAppRevisionInterfaceMock is a mock implementation of v31.MultiClusterAppRevisionInterface. +// +// func TestSomethingThatUsesMultiClusterAppRevisionInterface(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppRevisionInterface +// mockedMultiClusterAppRevisionInterface := &MultiClusterAppRevisionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.MultiClusterAppRevisionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedMultiClusterAppRevisionInterface in code that requires v31.MultiClusterAppRevisionInterface +// // and then make assertions. +// +// } +type MultiClusterAppRevisionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.MultiClusterAppRevisionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.MultiClusterAppRevisionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.MultiClusterAppRevisionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppRevisionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.MultiClusterAppRevisionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.MultiClusterAppRevision + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.MultiClusterAppRevision + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but MultiClusterAppRevisionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but MultiClusterAppRevisionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but MultiClusterAppRevisionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddClusterScopedHandlerCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.MultiClusterAppRevisionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but MultiClusterAppRevisionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddClusterScopedLifecycleCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockMultiClusterAppRevisionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddFeatureHandlerFunc: method is nil but MultiClusterAppRevisionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppRevisionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddFeatureHandlerCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockMultiClusterAppRevisionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddFeatureLifecycleFunc: method is nil but MultiClusterAppRevisionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockMultiClusterAppRevisionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddFeatureLifecycleCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + lockMultiClusterAppRevisionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockMultiClusterAppRevisionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.MultiClusterAppRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddHandlerFunc: method is nil but MultiClusterAppRevisionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockMultiClusterAppRevisionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddHandlerCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.MultiClusterAppRevisionHandlerFunc + } + lockMultiClusterAppRevisionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockMultiClusterAppRevisionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.MultiClusterAppRevisionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.AddLifecycleFunc: method is nil but MultiClusterAppRevisionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockMultiClusterAppRevisionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockMultiClusterAppRevisionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.AddLifecycleCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.MultiClusterAppRevisionLifecycle + } + lockMultiClusterAppRevisionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockMultiClusterAppRevisionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Controller() v31.MultiClusterAppRevisionController { + if mock.ControllerFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.ControllerFunc: method is nil but MultiClusterAppRevisionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppRevisionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockMultiClusterAppRevisionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.ControllerCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppRevisionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockMultiClusterAppRevisionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Create(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { + if mock.CreateFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.CreateFunc: method is nil but MultiClusterAppRevisionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.MultiClusterAppRevision + }{ + In1: in1, + } + lockMultiClusterAppRevisionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockMultiClusterAppRevisionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.CreateCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) CreateCalls() []struct { + In1 *v3.MultiClusterAppRevision +} { + var calls []struct { + In1 *v3.MultiClusterAppRevision + } + lockMultiClusterAppRevisionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockMultiClusterAppRevisionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.DeleteFunc: method is nil but MultiClusterAppRevisionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockMultiClusterAppRevisionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockMultiClusterAppRevisionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.DeleteCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockMultiClusterAppRevisionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockMultiClusterAppRevisionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.DeleteCollectionFunc: method is nil but MultiClusterAppRevisionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockMultiClusterAppRevisionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockMultiClusterAppRevisionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.DeleteCollectionCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockMultiClusterAppRevisionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockMultiClusterAppRevisionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.DeleteNamespacedFunc: method is nil but MultiClusterAppRevisionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockMultiClusterAppRevisionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockMultiClusterAppRevisionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.DeleteNamespacedCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockMultiClusterAppRevisionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockMultiClusterAppRevisionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { + if mock.GetFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.GetFunc: method is nil but MultiClusterAppRevisionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockMultiClusterAppRevisionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockMultiClusterAppRevisionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.GetCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockMultiClusterAppRevisionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockMultiClusterAppRevisionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { + if mock.GetNamespacedFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.GetNamespacedFunc: method is nil but MultiClusterAppRevisionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockMultiClusterAppRevisionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockMultiClusterAppRevisionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.GetNamespacedCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockMultiClusterAppRevisionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockMultiClusterAppRevisionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) List(opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { + if mock.ListFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.ListFunc: method is nil but MultiClusterAppRevisionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockMultiClusterAppRevisionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockMultiClusterAppRevisionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.ListCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockMultiClusterAppRevisionInterfaceMockList.RLock() + calls = mock.calls.List + lockMultiClusterAppRevisionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { + if mock.ListNamespacedFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.ListNamespacedFunc: method is nil but MultiClusterAppRevisionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockMultiClusterAppRevisionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockMultiClusterAppRevisionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.ListNamespacedCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockMultiClusterAppRevisionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockMultiClusterAppRevisionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.ObjectClientFunc: method is nil but MultiClusterAppRevisionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockMultiClusterAppRevisionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockMultiClusterAppRevisionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.ObjectClientCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockMultiClusterAppRevisionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockMultiClusterAppRevisionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Update(in1 *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { + if mock.UpdateFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.UpdateFunc: method is nil but MultiClusterAppRevisionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.MultiClusterAppRevision + }{ + In1: in1, + } + lockMultiClusterAppRevisionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockMultiClusterAppRevisionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.UpdateCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) UpdateCalls() []struct { + In1 *v3.MultiClusterAppRevision +} { + var calls []struct { + In1 *v3.MultiClusterAppRevision + } + lockMultiClusterAppRevisionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockMultiClusterAppRevisionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *MultiClusterAppRevisionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("MultiClusterAppRevisionInterfaceMock.WatchFunc: method is nil but MultiClusterAppRevisionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockMultiClusterAppRevisionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockMultiClusterAppRevisionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionInterface.WatchCalls()) +func (mock *MultiClusterAppRevisionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockMultiClusterAppRevisionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockMultiClusterAppRevisionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockMultiClusterAppRevisionsGetterMockMultiClusterAppRevisions sync.RWMutex +) + +// Ensure, that MultiClusterAppRevisionsGetterMock does implement v31.MultiClusterAppRevisionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.MultiClusterAppRevisionsGetter = &MultiClusterAppRevisionsGetterMock{} + +// MultiClusterAppRevisionsGetterMock is a mock implementation of v31.MultiClusterAppRevisionsGetter. +// +// func TestSomethingThatUsesMultiClusterAppRevisionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.MultiClusterAppRevisionsGetter +// mockedMultiClusterAppRevisionsGetter := &MultiClusterAppRevisionsGetterMock{ +// MultiClusterAppRevisionsFunc: func(namespace string) v31.MultiClusterAppRevisionInterface { +// panic("mock out the MultiClusterAppRevisions method") +// }, +// } +// +// // use mockedMultiClusterAppRevisionsGetter in code that requires v31.MultiClusterAppRevisionsGetter +// // and then make assertions. +// +// } +type MultiClusterAppRevisionsGetterMock struct { + // MultiClusterAppRevisionsFunc mocks the MultiClusterAppRevisions method. + MultiClusterAppRevisionsFunc func(namespace string) v31.MultiClusterAppRevisionInterface + + // calls tracks calls to the methods. + calls struct { + // MultiClusterAppRevisions holds details about calls to the MultiClusterAppRevisions method. + MultiClusterAppRevisions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// MultiClusterAppRevisions calls MultiClusterAppRevisionsFunc. +func (mock *MultiClusterAppRevisionsGetterMock) MultiClusterAppRevisions(namespace string) v31.MultiClusterAppRevisionInterface { + if mock.MultiClusterAppRevisionsFunc == nil { + panic("MultiClusterAppRevisionsGetterMock.MultiClusterAppRevisionsFunc: method is nil but MultiClusterAppRevisionsGetter.MultiClusterAppRevisions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockMultiClusterAppRevisionsGetterMockMultiClusterAppRevisions.Lock() + mock.calls.MultiClusterAppRevisions = append(mock.calls.MultiClusterAppRevisions, callInfo) + lockMultiClusterAppRevisionsGetterMockMultiClusterAppRevisions.Unlock() + return mock.MultiClusterAppRevisionsFunc(namespace) +} + +// MultiClusterAppRevisionsCalls gets all the calls that were made to MultiClusterAppRevisions. +// Check the length with: +// +// len(mockedMultiClusterAppRevisionsGetter.MultiClusterAppRevisionsCalls()) +func (mock *MultiClusterAppRevisionsGetterMock) MultiClusterAppRevisionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockMultiClusterAppRevisionsGetterMockMultiClusterAppRevisions.RLock() + calls = mock.calls.MultiClusterAppRevisions + lockMultiClusterAppRevisionsGetterMockMultiClusterAppRevisions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_driver_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_driver_mock.go new file mode 100644 index 0000000..8738d87 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_driver_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNodeDriverListerMockGet sync.RWMutex + lockNodeDriverListerMockList sync.RWMutex +) + +// Ensure, that NodeDriverListerMock does implement v31.NodeDriverLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeDriverLister = &NodeDriverListerMock{} + +// NodeDriverListerMock is a mock implementation of v31.NodeDriverLister. +// +// func TestSomethingThatUsesNodeDriverLister(t *testing.T) { +// +// // make and configure a mocked v31.NodeDriverLister +// mockedNodeDriverLister := &NodeDriverListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NodeDriver, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NodeDriver, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNodeDriverLister in code that requires v31.NodeDriverLister +// // and then make assertions. +// +// } +type NodeDriverListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NodeDriver, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NodeDriver, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NodeDriverListerMock) Get(namespace string, name string) (*v3.NodeDriver, error) { + if mock.GetFunc == nil { + panic("NodeDriverListerMock.GetFunc: method is nil but NodeDriverLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeDriverListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeDriverListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeDriverLister.GetCalls()) +func (mock *NodeDriverListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeDriverListerMockGet.RLock() + calls = mock.calls.Get + lockNodeDriverListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeDriverListerMock) List(namespace string, selector labels.Selector) ([]*v3.NodeDriver, error) { + if mock.ListFunc == nil { + panic("NodeDriverListerMock.ListFunc: method is nil but NodeDriverLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNodeDriverListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeDriverListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeDriverLister.ListCalls()) +func (mock *NodeDriverListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNodeDriverListerMockList.RLock() + calls = mock.calls.List + lockNodeDriverListerMockList.RUnlock() + return calls +} + +var ( + lockNodeDriverControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeDriverControllerMockAddClusterScopedHandler sync.RWMutex + lockNodeDriverControllerMockAddFeatureHandler sync.RWMutex + lockNodeDriverControllerMockAddHandler sync.RWMutex + lockNodeDriverControllerMockEnqueue sync.RWMutex + lockNodeDriverControllerMockEnqueueAfter sync.RWMutex + lockNodeDriverControllerMockGeneric sync.RWMutex + lockNodeDriverControllerMockInformer sync.RWMutex + lockNodeDriverControllerMockLister sync.RWMutex +) + +// Ensure, that NodeDriverControllerMock does implement v31.NodeDriverController. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeDriverController = &NodeDriverControllerMock{} + +// NodeDriverControllerMock is a mock implementation of v31.NodeDriverController. +// +// func TestSomethingThatUsesNodeDriverController(t *testing.T) { +// +// // make and configure a mocked v31.NodeDriverController +// mockedNodeDriverController := &NodeDriverControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeDriverHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NodeDriverHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NodeDriverHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NodeDriverLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNodeDriverController in code that requires v31.NodeDriverController +// // and then make assertions. +// +// } +type NodeDriverControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeDriverHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NodeDriverHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NodeDriverHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NodeDriverLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeDriverHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeDriverHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeDriverHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NodeDriverHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeDriverControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeDriverHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeDriverControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeDriverController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeDriverControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeDriverControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeDriverController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeDriverControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc + } + lockNodeDriverControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeDriverControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeDriverControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NodeDriverHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeDriverControllerMock.AddClusterScopedHandlerFunc: method is nil but NodeDriverController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeDriverControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeDriverControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeDriverController.AddClusterScopedHandlerCalls()) +func (mock *NodeDriverControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeDriverHandlerFunc + } + lockNodeDriverControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeDriverControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeDriverControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeDriverControllerMock.AddFeatureHandlerFunc: method is nil but NodeDriverController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeDriverControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeDriverControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeDriverController.AddFeatureHandlerCalls()) +func (mock *NodeDriverControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc + } + lockNodeDriverControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeDriverControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeDriverControllerMock) AddHandler(ctx context.Context, name string, handler v31.NodeDriverHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeDriverControllerMock.AddHandlerFunc: method is nil but NodeDriverController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNodeDriverControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeDriverControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeDriverController.AddHandlerCalls()) +func (mock *NodeDriverControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NodeDriverHandlerFunc + } + lockNodeDriverControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeDriverControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NodeDriverControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NodeDriverControllerMock.EnqueueFunc: method is nil but NodeDriverController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeDriverControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNodeDriverControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNodeDriverController.EnqueueCalls()) +func (mock *NodeDriverControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeDriverControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNodeDriverControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NodeDriverControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NodeDriverControllerMock.EnqueueAfterFunc: method is nil but NodeDriverController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNodeDriverControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNodeDriverControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNodeDriverController.EnqueueAfterCalls()) +func (mock *NodeDriverControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNodeDriverControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNodeDriverControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NodeDriverControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NodeDriverControllerMock.GenericFunc: method is nil but NodeDriverController.Generic was just called") + } + callInfo := struct { + }{} + lockNodeDriverControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNodeDriverControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNodeDriverController.GenericCalls()) +func (mock *NodeDriverControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNodeDriverControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNodeDriverControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NodeDriverControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NodeDriverControllerMock.InformerFunc: method is nil but NodeDriverController.Informer was just called") + } + callInfo := struct { + }{} + lockNodeDriverControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNodeDriverControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNodeDriverController.InformerCalls()) +func (mock *NodeDriverControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNodeDriverControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNodeDriverControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NodeDriverControllerMock) Lister() v31.NodeDriverLister { + if mock.ListerFunc == nil { + panic("NodeDriverControllerMock.ListerFunc: method is nil but NodeDriverController.Lister was just called") + } + callInfo := struct { + }{} + lockNodeDriverControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNodeDriverControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNodeDriverController.ListerCalls()) +func (mock *NodeDriverControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNodeDriverControllerMockLister.RLock() + calls = mock.calls.Lister + lockNodeDriverControllerMockLister.RUnlock() + return calls +} + +var ( + lockNodeDriverInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeDriverInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNodeDriverInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNodeDriverInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNodeDriverInterfaceMockAddFeatureHandler sync.RWMutex + lockNodeDriverInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNodeDriverInterfaceMockAddHandler sync.RWMutex + lockNodeDriverInterfaceMockAddLifecycle sync.RWMutex + lockNodeDriverInterfaceMockController sync.RWMutex + lockNodeDriverInterfaceMockCreate sync.RWMutex + lockNodeDriverInterfaceMockDelete sync.RWMutex + lockNodeDriverInterfaceMockDeleteCollection sync.RWMutex + lockNodeDriverInterfaceMockDeleteNamespaced sync.RWMutex + lockNodeDriverInterfaceMockGet sync.RWMutex + lockNodeDriverInterfaceMockGetNamespaced sync.RWMutex + lockNodeDriverInterfaceMockList sync.RWMutex + lockNodeDriverInterfaceMockListNamespaced sync.RWMutex + lockNodeDriverInterfaceMockObjectClient sync.RWMutex + lockNodeDriverInterfaceMockUpdate sync.RWMutex + lockNodeDriverInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NodeDriverInterfaceMock does implement v31.NodeDriverInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeDriverInterface = &NodeDriverInterfaceMock{} + +// NodeDriverInterfaceMock is a mock implementation of v31.NodeDriverInterface. +// +// func TestSomethingThatUsesNodeDriverInterface(t *testing.T) { +// +// // make and configure a mocked v31.NodeDriverInterface +// mockedNodeDriverInterface := &NodeDriverInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeDriverLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NodeDriverHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NodeDriverLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NodeDriverController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NodeDriver) (*v3.NodeDriver, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NodeDriverList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NodeDriverList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NodeDriver) (*v3.NodeDriver, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNodeDriverInterface in code that requires v31.NodeDriverInterface +// // and then make assertions. +// +// } +type NodeDriverInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeDriverLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NodeDriverHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NodeDriverLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NodeDriverController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NodeDriver) (*v3.NodeDriver, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NodeDriver, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NodeDriver, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NodeDriverList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NodeDriverList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NodeDriver) (*v3.NodeDriver, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeDriverHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeDriverLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeDriverHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeDriverLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeDriverHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeDriverLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeDriverHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeDriverLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NodeDriver + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NodeDriver + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeDriverInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeDriverInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeDriverInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeDriverInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeDriverInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeDriverInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc + } + lockNodeDriverInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeDriverInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NodeDriverInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NodeDriverInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NodeDriverInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeDriverInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNodeDriverInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NodeDriverInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle + } + lockNodeDriverInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNodeDriverInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeDriverInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeDriverHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeDriverInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NodeDriverInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeDriverInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeDriverInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddClusterScopedHandlerCalls()) +func (mock *NodeDriverInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeDriverHandlerFunc + } + lockNodeDriverInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeDriverInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NodeDriverInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NodeDriverLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NodeDriverInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NodeDriverInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeDriverInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNodeDriverInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddClusterScopedLifecycleCalls()) +func (mock *NodeDriverInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeDriverLifecycle + } + lockNodeDriverInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNodeDriverInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeDriverInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeDriverHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeDriverInterfaceMock.AddFeatureHandlerFunc: method is nil but NodeDriverInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeDriverInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeDriverInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddFeatureHandlerCalls()) +func (mock *NodeDriverInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeDriverHandlerFunc + } + lockNodeDriverInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeDriverInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NodeDriverInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeDriverLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NodeDriverInterfaceMock.AddFeatureLifecycleFunc: method is nil but NodeDriverInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeDriverLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNodeDriverInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNodeDriverInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddFeatureLifecycleCalls()) +func (mock *NodeDriverInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeDriverLifecycle + } + lockNodeDriverInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNodeDriverInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeDriverInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NodeDriverHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeDriverInterfaceMock.AddHandlerFunc: method is nil but NodeDriverInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NodeDriverHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNodeDriverInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeDriverInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddHandlerCalls()) +func (mock *NodeDriverInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NodeDriverHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NodeDriverHandlerFunc + } + lockNodeDriverInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeDriverInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NodeDriverInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NodeDriverLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NodeDriverInterfaceMock.AddLifecycleFunc: method is nil but NodeDriverInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NodeDriverLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNodeDriverInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNodeDriverInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNodeDriverInterface.AddLifecycleCalls()) +func (mock *NodeDriverInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeDriverLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeDriverLifecycle + } + lockNodeDriverInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNodeDriverInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NodeDriverInterfaceMock) Controller() v31.NodeDriverController { + if mock.ControllerFunc == nil { + panic("NodeDriverInterfaceMock.ControllerFunc: method is nil but NodeDriverInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNodeDriverInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNodeDriverInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNodeDriverInterface.ControllerCalls()) +func (mock *NodeDriverInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNodeDriverInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNodeDriverInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NodeDriverInterfaceMock) Create(in1 *v3.NodeDriver) (*v3.NodeDriver, error) { + if mock.CreateFunc == nil { + panic("NodeDriverInterfaceMock.CreateFunc: method is nil but NodeDriverInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NodeDriver + }{ + In1: in1, + } + lockNodeDriverInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNodeDriverInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNodeDriverInterface.CreateCalls()) +func (mock *NodeDriverInterfaceMock) CreateCalls() []struct { + In1 *v3.NodeDriver +} { + var calls []struct { + In1 *v3.NodeDriver + } + lockNodeDriverInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNodeDriverInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NodeDriverInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NodeDriverInterfaceMock.DeleteFunc: method is nil but NodeDriverInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNodeDriverInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNodeDriverInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNodeDriverInterface.DeleteCalls()) +func (mock *NodeDriverInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNodeDriverInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNodeDriverInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NodeDriverInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NodeDriverInterfaceMock.DeleteCollectionFunc: method is nil but NodeDriverInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNodeDriverInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNodeDriverInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNodeDriverInterface.DeleteCollectionCalls()) +func (mock *NodeDriverInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNodeDriverInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNodeDriverInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NodeDriverInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NodeDriverInterfaceMock.DeleteNamespacedFunc: method is nil but NodeDriverInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNodeDriverInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNodeDriverInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNodeDriverInterface.DeleteNamespacedCalls()) +func (mock *NodeDriverInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNodeDriverInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNodeDriverInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NodeDriverInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { + if mock.GetFunc == nil { + panic("NodeDriverInterfaceMock.GetFunc: method is nil but NodeDriverInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNodeDriverInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeDriverInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeDriverInterface.GetCalls()) +func (mock *NodeDriverInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNodeDriverInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNodeDriverInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NodeDriverInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { + if mock.GetNamespacedFunc == nil { + panic("NodeDriverInterfaceMock.GetNamespacedFunc: method is nil but NodeDriverInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNodeDriverInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNodeDriverInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNodeDriverInterface.GetNamespacedCalls()) +func (mock *NodeDriverInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNodeDriverInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNodeDriverInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeDriverInterfaceMock) List(opts metav1.ListOptions) (*v3.NodeDriverList, error) { + if mock.ListFunc == nil { + panic("NodeDriverInterfaceMock.ListFunc: method is nil but NodeDriverInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeDriverInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeDriverInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeDriverInterface.ListCalls()) +func (mock *NodeDriverInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeDriverInterfaceMockList.RLock() + calls = mock.calls.List + lockNodeDriverInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NodeDriverInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeDriverList, error) { + if mock.ListNamespacedFunc == nil { + panic("NodeDriverInterfaceMock.ListNamespacedFunc: method is nil but NodeDriverInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNodeDriverInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNodeDriverInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNodeDriverInterface.ListNamespacedCalls()) +func (mock *NodeDriverInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNodeDriverInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNodeDriverInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NodeDriverInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NodeDriverInterfaceMock.ObjectClientFunc: method is nil but NodeDriverInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNodeDriverInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNodeDriverInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNodeDriverInterface.ObjectClientCalls()) +func (mock *NodeDriverInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNodeDriverInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNodeDriverInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NodeDriverInterfaceMock) Update(in1 *v3.NodeDriver) (*v3.NodeDriver, error) { + if mock.UpdateFunc == nil { + panic("NodeDriverInterfaceMock.UpdateFunc: method is nil but NodeDriverInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NodeDriver + }{ + In1: in1, + } + lockNodeDriverInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNodeDriverInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNodeDriverInterface.UpdateCalls()) +func (mock *NodeDriverInterfaceMock) UpdateCalls() []struct { + In1 *v3.NodeDriver +} { + var calls []struct { + In1 *v3.NodeDriver + } + lockNodeDriverInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNodeDriverInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NodeDriverInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NodeDriverInterfaceMock.WatchFunc: method is nil but NodeDriverInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeDriverInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNodeDriverInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNodeDriverInterface.WatchCalls()) +func (mock *NodeDriverInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeDriverInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNodeDriverInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNodeDriversGetterMockNodeDrivers sync.RWMutex +) + +// Ensure, that NodeDriversGetterMock does implement v31.NodeDriversGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeDriversGetter = &NodeDriversGetterMock{} + +// NodeDriversGetterMock is a mock implementation of v31.NodeDriversGetter. +// +// func TestSomethingThatUsesNodeDriversGetter(t *testing.T) { +// +// // make and configure a mocked v31.NodeDriversGetter +// mockedNodeDriversGetter := &NodeDriversGetterMock{ +// NodeDriversFunc: func(namespace string) v31.NodeDriverInterface { +// panic("mock out the NodeDrivers method") +// }, +// } +// +// // use mockedNodeDriversGetter in code that requires v31.NodeDriversGetter +// // and then make assertions. +// +// } +type NodeDriversGetterMock struct { + // NodeDriversFunc mocks the NodeDrivers method. + NodeDriversFunc func(namespace string) v31.NodeDriverInterface + + // calls tracks calls to the methods. + calls struct { + // NodeDrivers holds details about calls to the NodeDrivers method. + NodeDrivers []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NodeDrivers calls NodeDriversFunc. +func (mock *NodeDriversGetterMock) NodeDrivers(namespace string) v31.NodeDriverInterface { + if mock.NodeDriversFunc == nil { + panic("NodeDriversGetterMock.NodeDriversFunc: method is nil but NodeDriversGetter.NodeDrivers was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNodeDriversGetterMockNodeDrivers.Lock() + mock.calls.NodeDrivers = append(mock.calls.NodeDrivers, callInfo) + lockNodeDriversGetterMockNodeDrivers.Unlock() + return mock.NodeDriversFunc(namespace) +} + +// NodeDriversCalls gets all the calls that were made to NodeDrivers. +// Check the length with: +// +// len(mockedNodeDriversGetter.NodeDriversCalls()) +func (mock *NodeDriversGetterMock) NodeDriversCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNodeDriversGetterMockNodeDrivers.RLock() + calls = mock.calls.NodeDrivers + lockNodeDriversGetterMockNodeDrivers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_mock.go new file mode 100644 index 0000000..704fa2b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNodeListerMockGet sync.RWMutex + lockNodeListerMockList sync.RWMutex +) + +// Ensure, that NodeListerMock does implement v31.NodeLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeLister = &NodeListerMock{} + +// NodeListerMock is a mock implementation of v31.NodeLister. +// +// func TestSomethingThatUsesNodeLister(t *testing.T) { +// +// // make and configure a mocked v31.NodeLister +// mockedNodeLister := &NodeListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Node, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Node, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNodeLister in code that requires v31.NodeLister +// // and then make assertions. +// +// } +type NodeListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Node, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Node, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NodeListerMock) Get(namespace string, name string) (*v3.Node, error) { + if mock.GetFunc == nil { + panic("NodeListerMock.GetFunc: method is nil but NodeLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeLister.GetCalls()) +func (mock *NodeListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeListerMockGet.RLock() + calls = mock.calls.Get + lockNodeListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeListerMock) List(namespace string, selector labels.Selector) ([]*v3.Node, error) { + if mock.ListFunc == nil { + panic("NodeListerMock.ListFunc: method is nil but NodeLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNodeListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeLister.ListCalls()) +func (mock *NodeListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNodeListerMockList.RLock() + calls = mock.calls.List + lockNodeListerMockList.RUnlock() + return calls +} + +var ( + lockNodeControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeControllerMockAddClusterScopedHandler sync.RWMutex + lockNodeControllerMockAddFeatureHandler sync.RWMutex + lockNodeControllerMockAddHandler sync.RWMutex + lockNodeControllerMockEnqueue sync.RWMutex + lockNodeControllerMockEnqueueAfter sync.RWMutex + lockNodeControllerMockGeneric sync.RWMutex + lockNodeControllerMockInformer sync.RWMutex + lockNodeControllerMockLister sync.RWMutex +) + +// Ensure, that NodeControllerMock does implement v31.NodeController. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeController = &NodeControllerMock{} + +// NodeControllerMock is a mock implementation of v31.NodeController. +// +// func TestSomethingThatUsesNodeController(t *testing.T) { +// +// // make and configure a mocked v31.NodeController +// mockedNodeController := &NodeControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NodeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NodeLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNodeController in code that requires v31.NodeController +// // and then make assertions. +// +// } +type NodeControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NodeHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NodeHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NodeLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NodeHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeHandlerFunc + } + lockNodeControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NodeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeControllerMock.AddClusterScopedHandlerFunc: method is nil but NodeController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeController.AddClusterScopedHandlerCalls()) +func (mock *NodeControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeHandlerFunc + } + lockNodeControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeControllerMock.AddFeatureHandlerFunc: method is nil but NodeController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeController.AddFeatureHandlerCalls()) +func (mock *NodeControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc + } + lockNodeControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeControllerMock) AddHandler(ctx context.Context, name string, handler v31.NodeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeControllerMock.AddHandlerFunc: method is nil but NodeController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNodeControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeController.AddHandlerCalls()) +func (mock *NodeControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NodeHandlerFunc + } + lockNodeControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NodeControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NodeControllerMock.EnqueueFunc: method is nil but NodeController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNodeControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNodeController.EnqueueCalls()) +func (mock *NodeControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNodeControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NodeControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NodeControllerMock.EnqueueAfterFunc: method is nil but NodeController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNodeControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNodeControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNodeController.EnqueueAfterCalls()) +func (mock *NodeControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNodeControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNodeControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NodeControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NodeControllerMock.GenericFunc: method is nil but NodeController.Generic was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNodeControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNodeController.GenericCalls()) +func (mock *NodeControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNodeControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NodeControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NodeControllerMock.InformerFunc: method is nil but NodeController.Informer was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNodeControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNodeController.InformerCalls()) +func (mock *NodeControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNodeControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NodeControllerMock) Lister() v31.NodeLister { + if mock.ListerFunc == nil { + panic("NodeControllerMock.ListerFunc: method is nil but NodeController.Lister was just called") + } + callInfo := struct { + }{} + lockNodeControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNodeControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNodeController.ListerCalls()) +func (mock *NodeControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNodeControllerMockLister.RLock() + calls = mock.calls.Lister + lockNodeControllerMockLister.RUnlock() + return calls +} + +var ( + lockNodeInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNodeInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNodeInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNodeInterfaceMockAddFeatureHandler sync.RWMutex + lockNodeInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNodeInterfaceMockAddHandler sync.RWMutex + lockNodeInterfaceMockAddLifecycle sync.RWMutex + lockNodeInterfaceMockController sync.RWMutex + lockNodeInterfaceMockCreate sync.RWMutex + lockNodeInterfaceMockDelete sync.RWMutex + lockNodeInterfaceMockDeleteCollection sync.RWMutex + lockNodeInterfaceMockDeleteNamespaced sync.RWMutex + lockNodeInterfaceMockGet sync.RWMutex + lockNodeInterfaceMockGetNamespaced sync.RWMutex + lockNodeInterfaceMockList sync.RWMutex + lockNodeInterfaceMockListNamespaced sync.RWMutex + lockNodeInterfaceMockObjectClient sync.RWMutex + lockNodeInterfaceMockUpdate sync.RWMutex + lockNodeInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NodeInterfaceMock does implement v31.NodeInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeInterface = &NodeInterfaceMock{} + +// NodeInterfaceMock is a mock implementation of v31.NodeInterface. +// +// func TestSomethingThatUsesNodeInterface(t *testing.T) { +// +// // make and configure a mocked v31.NodeInterface +// mockedNodeInterface := &NodeInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NodeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NodeLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NodeController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Node) (*v3.Node, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Node, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Node, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NodeList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NodeList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Node) (*v3.Node, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNodeInterface in code that requires v31.NodeInterface +// // and then make assertions. +// +// } +type NodeInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NodeHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NodeLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NodeController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Node) (*v3.Node, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Node, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Node, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NodeList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NodeList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Node) (*v3.Node, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Node + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Node + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeHandlerFunc + } + lockNodeInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NodeInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NodeInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeLifecycle + } + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNodeInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NodeInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedHandlerCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeHandlerFunc + } + lockNodeInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NodeInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NodeLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NodeInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NodeInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNodeInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddClusterScopedLifecycleCalls()) +func (mock *NodeInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeLifecycle + } + lockNodeInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNodeInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeInterfaceMock.AddFeatureHandlerFunc: method is nil but NodeInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddFeatureHandlerCalls()) +func (mock *NodeInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeHandlerFunc + } + lockNodeInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NodeInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NodeInterfaceMock.AddFeatureLifecycleFunc: method is nil but NodeInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNodeInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddFeatureLifecycleCalls()) +func (mock *NodeInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeLifecycle + } + lockNodeInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNodeInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NodeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeInterfaceMock.AddHandlerFunc: method is nil but NodeInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NodeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNodeInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeInterface.AddHandlerCalls()) +func (mock *NodeInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NodeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NodeHandlerFunc + } + lockNodeInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NodeInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NodeLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NodeInterfaceMock.AddLifecycleFunc: method is nil but NodeInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NodeLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNodeInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNodeInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNodeInterface.AddLifecycleCalls()) +func (mock *NodeInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeLifecycle + } + lockNodeInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNodeInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NodeInterfaceMock) Controller() v31.NodeController { + if mock.ControllerFunc == nil { + panic("NodeInterfaceMock.ControllerFunc: method is nil but NodeInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNodeInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNodeInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNodeInterface.ControllerCalls()) +func (mock *NodeInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNodeInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNodeInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NodeInterfaceMock) Create(in1 *v3.Node) (*v3.Node, error) { + if mock.CreateFunc == nil { + panic("NodeInterfaceMock.CreateFunc: method is nil but NodeInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Node + }{ + In1: in1, + } + lockNodeInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNodeInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNodeInterface.CreateCalls()) +func (mock *NodeInterfaceMock) CreateCalls() []struct { + In1 *v3.Node +} { + var calls []struct { + In1 *v3.Node + } + lockNodeInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNodeInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NodeInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NodeInterfaceMock.DeleteFunc: method is nil but NodeInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNodeInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNodeInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNodeInterface.DeleteCalls()) +func (mock *NodeInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNodeInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNodeInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NodeInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NodeInterfaceMock.DeleteCollectionFunc: method is nil but NodeInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNodeInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNodeInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNodeInterface.DeleteCollectionCalls()) +func (mock *NodeInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNodeInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNodeInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NodeInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NodeInterfaceMock.DeleteNamespacedFunc: method is nil but NodeInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNodeInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNodeInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.DeleteNamespacedCalls()) +func (mock *NodeInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNodeInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNodeInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NodeInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Node, error) { + if mock.GetFunc == nil { + panic("NodeInterfaceMock.GetFunc: method is nil but NodeInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNodeInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeInterface.GetCalls()) +func (mock *NodeInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNodeInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNodeInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NodeInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Node, error) { + if mock.GetNamespacedFunc == nil { + panic("NodeInterfaceMock.GetNamespacedFunc: method is nil but NodeInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNodeInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNodeInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.GetNamespacedCalls()) +func (mock *NodeInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNodeInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNodeInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeInterfaceMock) List(opts metav1.ListOptions) (*v3.NodeList, error) { + if mock.ListFunc == nil { + panic("NodeInterfaceMock.ListFunc: method is nil but NodeInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeInterface.ListCalls()) +func (mock *NodeInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeInterfaceMockList.RLock() + calls = mock.calls.List + lockNodeInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NodeInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeList, error) { + if mock.ListNamespacedFunc == nil { + panic("NodeInterfaceMock.ListNamespacedFunc: method is nil but NodeInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNodeInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNodeInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNodeInterface.ListNamespacedCalls()) +func (mock *NodeInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNodeInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNodeInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NodeInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NodeInterfaceMock.ObjectClientFunc: method is nil but NodeInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNodeInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNodeInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNodeInterface.ObjectClientCalls()) +func (mock *NodeInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNodeInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNodeInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NodeInterfaceMock) Update(in1 *v3.Node) (*v3.Node, error) { + if mock.UpdateFunc == nil { + panic("NodeInterfaceMock.UpdateFunc: method is nil but NodeInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Node + }{ + In1: in1, + } + lockNodeInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNodeInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNodeInterface.UpdateCalls()) +func (mock *NodeInterfaceMock) UpdateCalls() []struct { + In1 *v3.Node +} { + var calls []struct { + In1 *v3.Node + } + lockNodeInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNodeInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NodeInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NodeInterfaceMock.WatchFunc: method is nil but NodeInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNodeInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNodeInterface.WatchCalls()) +func (mock *NodeInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNodeInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNodesGetterMockNodes sync.RWMutex +) + +// Ensure, that NodesGetterMock does implement v31.NodesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NodesGetter = &NodesGetterMock{} + +// NodesGetterMock is a mock implementation of v31.NodesGetter. +// +// func TestSomethingThatUsesNodesGetter(t *testing.T) { +// +// // make and configure a mocked v31.NodesGetter +// mockedNodesGetter := &NodesGetterMock{ +// NodesFunc: func(namespace string) v31.NodeInterface { +// panic("mock out the Nodes method") +// }, +// } +// +// // use mockedNodesGetter in code that requires v31.NodesGetter +// // and then make assertions. +// +// } +type NodesGetterMock struct { + // NodesFunc mocks the Nodes method. + NodesFunc func(namespace string) v31.NodeInterface + + // calls tracks calls to the methods. + calls struct { + // Nodes holds details about calls to the Nodes method. + Nodes []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Nodes calls NodesFunc. +func (mock *NodesGetterMock) Nodes(namespace string) v31.NodeInterface { + if mock.NodesFunc == nil { + panic("NodesGetterMock.NodesFunc: method is nil but NodesGetter.Nodes was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNodesGetterMockNodes.Lock() + mock.calls.Nodes = append(mock.calls.Nodes, callInfo) + lockNodesGetterMockNodes.Unlock() + return mock.NodesFunc(namespace) +} + +// NodesCalls gets all the calls that were made to Nodes. +// Check the length with: +// +// len(mockedNodesGetter.NodesCalls()) +func (mock *NodesGetterMock) NodesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNodesGetterMockNodes.RLock() + calls = mock.calls.Nodes + lockNodesGetterMockNodes.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_pool_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_pool_mock.go new file mode 100644 index 0000000..527fe23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_pool_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNodePoolListerMockGet sync.RWMutex + lockNodePoolListerMockList sync.RWMutex +) + +// Ensure, that NodePoolListerMock does implement v31.NodePoolLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NodePoolLister = &NodePoolListerMock{} + +// NodePoolListerMock is a mock implementation of v31.NodePoolLister. +// +// func TestSomethingThatUsesNodePoolLister(t *testing.T) { +// +// // make and configure a mocked v31.NodePoolLister +// mockedNodePoolLister := &NodePoolListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NodePool, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NodePool, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNodePoolLister in code that requires v31.NodePoolLister +// // and then make assertions. +// +// } +type NodePoolListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NodePool, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NodePool, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NodePoolListerMock) Get(namespace string, name string) (*v3.NodePool, error) { + if mock.GetFunc == nil { + panic("NodePoolListerMock.GetFunc: method is nil but NodePoolLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodePoolListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodePoolListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodePoolLister.GetCalls()) +func (mock *NodePoolListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodePoolListerMockGet.RLock() + calls = mock.calls.Get + lockNodePoolListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodePoolListerMock) List(namespace string, selector labels.Selector) ([]*v3.NodePool, error) { + if mock.ListFunc == nil { + panic("NodePoolListerMock.ListFunc: method is nil but NodePoolLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNodePoolListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodePoolListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodePoolLister.ListCalls()) +func (mock *NodePoolListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNodePoolListerMockList.RLock() + calls = mock.calls.List + lockNodePoolListerMockList.RUnlock() + return calls +} + +var ( + lockNodePoolControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodePoolControllerMockAddClusterScopedHandler sync.RWMutex + lockNodePoolControllerMockAddFeatureHandler sync.RWMutex + lockNodePoolControllerMockAddHandler sync.RWMutex + lockNodePoolControllerMockEnqueue sync.RWMutex + lockNodePoolControllerMockEnqueueAfter sync.RWMutex + lockNodePoolControllerMockGeneric sync.RWMutex + lockNodePoolControllerMockInformer sync.RWMutex + lockNodePoolControllerMockLister sync.RWMutex +) + +// Ensure, that NodePoolControllerMock does implement v31.NodePoolController. +// If this is not the case, regenerate this file with moq. +var _ v31.NodePoolController = &NodePoolControllerMock{} + +// NodePoolControllerMock is a mock implementation of v31.NodePoolController. +// +// func TestSomethingThatUsesNodePoolController(t *testing.T) { +// +// // make and configure a mocked v31.NodePoolController +// mockedNodePoolController := &NodePoolControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodePoolHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NodePoolHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NodePoolHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NodePoolLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNodePoolController in code that requires v31.NodePoolController +// // and then make assertions. +// +// } +type NodePoolControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodePoolHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NodePoolHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NodePoolHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NodePoolLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodePoolHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodePoolHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodePoolHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NodePoolHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodePoolControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodePoolHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodePoolControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodePoolController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodePoolControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodePoolControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodePoolController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodePoolControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc + } + lockNodePoolControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodePoolControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodePoolControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NodePoolHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodePoolControllerMock.AddClusterScopedHandlerFunc: method is nil but NodePoolController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodePoolControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodePoolControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodePoolController.AddClusterScopedHandlerCalls()) +func (mock *NodePoolControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodePoolHandlerFunc + } + lockNodePoolControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodePoolControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodePoolControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodePoolControllerMock.AddFeatureHandlerFunc: method is nil but NodePoolController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodePoolControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodePoolControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodePoolController.AddFeatureHandlerCalls()) +func (mock *NodePoolControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc + } + lockNodePoolControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodePoolControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodePoolControllerMock) AddHandler(ctx context.Context, name string, handler v31.NodePoolHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodePoolControllerMock.AddHandlerFunc: method is nil but NodePoolController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNodePoolControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodePoolControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodePoolController.AddHandlerCalls()) +func (mock *NodePoolControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NodePoolHandlerFunc + } + lockNodePoolControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodePoolControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NodePoolControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NodePoolControllerMock.EnqueueFunc: method is nil but NodePoolController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodePoolControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNodePoolControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNodePoolController.EnqueueCalls()) +func (mock *NodePoolControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodePoolControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNodePoolControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NodePoolControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NodePoolControllerMock.EnqueueAfterFunc: method is nil but NodePoolController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNodePoolControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNodePoolControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNodePoolController.EnqueueAfterCalls()) +func (mock *NodePoolControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNodePoolControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNodePoolControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NodePoolControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NodePoolControllerMock.GenericFunc: method is nil but NodePoolController.Generic was just called") + } + callInfo := struct { + }{} + lockNodePoolControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNodePoolControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNodePoolController.GenericCalls()) +func (mock *NodePoolControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNodePoolControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNodePoolControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NodePoolControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NodePoolControllerMock.InformerFunc: method is nil but NodePoolController.Informer was just called") + } + callInfo := struct { + }{} + lockNodePoolControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNodePoolControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNodePoolController.InformerCalls()) +func (mock *NodePoolControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNodePoolControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNodePoolControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NodePoolControllerMock) Lister() v31.NodePoolLister { + if mock.ListerFunc == nil { + panic("NodePoolControllerMock.ListerFunc: method is nil but NodePoolController.Lister was just called") + } + callInfo := struct { + }{} + lockNodePoolControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNodePoolControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNodePoolController.ListerCalls()) +func (mock *NodePoolControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNodePoolControllerMockLister.RLock() + calls = mock.calls.Lister + lockNodePoolControllerMockLister.RUnlock() + return calls +} + +var ( + lockNodePoolInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodePoolInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNodePoolInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNodePoolInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNodePoolInterfaceMockAddFeatureHandler sync.RWMutex + lockNodePoolInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNodePoolInterfaceMockAddHandler sync.RWMutex + lockNodePoolInterfaceMockAddLifecycle sync.RWMutex + lockNodePoolInterfaceMockController sync.RWMutex + lockNodePoolInterfaceMockCreate sync.RWMutex + lockNodePoolInterfaceMockDelete sync.RWMutex + lockNodePoolInterfaceMockDeleteCollection sync.RWMutex + lockNodePoolInterfaceMockDeleteNamespaced sync.RWMutex + lockNodePoolInterfaceMockGet sync.RWMutex + lockNodePoolInterfaceMockGetNamespaced sync.RWMutex + lockNodePoolInterfaceMockList sync.RWMutex + lockNodePoolInterfaceMockListNamespaced sync.RWMutex + lockNodePoolInterfaceMockObjectClient sync.RWMutex + lockNodePoolInterfaceMockUpdate sync.RWMutex + lockNodePoolInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NodePoolInterfaceMock does implement v31.NodePoolInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NodePoolInterface = &NodePoolInterfaceMock{} + +// NodePoolInterfaceMock is a mock implementation of v31.NodePoolInterface. +// +// func TestSomethingThatUsesNodePoolInterface(t *testing.T) { +// +// // make and configure a mocked v31.NodePoolInterface +// mockedNodePoolInterface := &NodePoolInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodePoolLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NodePoolLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodePoolLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NodePoolHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NodePoolLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NodePoolController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NodePool) (*v3.NodePool, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NodePool, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NodePool, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NodePoolList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NodePoolList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NodePool) (*v3.NodePool, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNodePoolInterface in code that requires v31.NodePoolInterface +// // and then make assertions. +// +// } +type NodePoolInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodePoolLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NodePoolLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodePoolLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NodePoolHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NodePoolLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NodePoolController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NodePool) (*v3.NodePool, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NodePool, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NodePool, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NodePoolList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NodePoolList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NodePool) (*v3.NodePool, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodePoolHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodePoolLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodePoolHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodePoolLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodePoolHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodePoolLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodePoolHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodePoolLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NodePool + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NodePool + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodePoolInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodePoolInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodePoolInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodePoolInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodePoolInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodePoolInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodePoolInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc + } + lockNodePoolInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodePoolInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NodePoolInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodePoolLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NodePoolInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NodePoolInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodePoolInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNodePoolInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNodePoolInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NodePoolInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle + } + lockNodePoolInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNodePoolInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodePoolInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodePoolHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodePoolInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NodePoolInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodePoolInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodePoolInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodePoolInterface.AddClusterScopedHandlerCalls()) +func (mock *NodePoolInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodePoolHandlerFunc + } + lockNodePoolInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodePoolInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NodePoolInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NodePoolLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NodePoolInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NodePoolInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodePoolInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNodePoolInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNodePoolInterface.AddClusterScopedLifecycleCalls()) +func (mock *NodePoolInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodePoolLifecycle + } + lockNodePoolInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNodePoolInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodePoolInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodePoolHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodePoolInterfaceMock.AddFeatureHandlerFunc: method is nil but NodePoolInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodePoolInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodePoolInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodePoolInterface.AddFeatureHandlerCalls()) +func (mock *NodePoolInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodePoolHandlerFunc + } + lockNodePoolInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodePoolInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NodePoolInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodePoolLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NodePoolInterfaceMock.AddFeatureLifecycleFunc: method is nil but NodePoolInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodePoolLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNodePoolInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNodePoolInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNodePoolInterface.AddFeatureLifecycleCalls()) +func (mock *NodePoolInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodePoolLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodePoolLifecycle + } + lockNodePoolInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNodePoolInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodePoolInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NodePoolHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodePoolInterfaceMock.AddHandlerFunc: method is nil but NodePoolInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NodePoolHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNodePoolInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodePoolInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodePoolInterface.AddHandlerCalls()) +func (mock *NodePoolInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NodePoolHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NodePoolHandlerFunc + } + lockNodePoolInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodePoolInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NodePoolInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NodePoolLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NodePoolInterfaceMock.AddLifecycleFunc: method is nil but NodePoolInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NodePoolLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNodePoolInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNodePoolInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNodePoolInterface.AddLifecycleCalls()) +func (mock *NodePoolInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NodePoolLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NodePoolLifecycle + } + lockNodePoolInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNodePoolInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NodePoolInterfaceMock) Controller() v31.NodePoolController { + if mock.ControllerFunc == nil { + panic("NodePoolInterfaceMock.ControllerFunc: method is nil but NodePoolInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNodePoolInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNodePoolInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNodePoolInterface.ControllerCalls()) +func (mock *NodePoolInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNodePoolInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNodePoolInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NodePoolInterfaceMock) Create(in1 *v3.NodePool) (*v3.NodePool, error) { + if mock.CreateFunc == nil { + panic("NodePoolInterfaceMock.CreateFunc: method is nil but NodePoolInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NodePool + }{ + In1: in1, + } + lockNodePoolInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNodePoolInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNodePoolInterface.CreateCalls()) +func (mock *NodePoolInterfaceMock) CreateCalls() []struct { + In1 *v3.NodePool +} { + var calls []struct { + In1 *v3.NodePool + } + lockNodePoolInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNodePoolInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NodePoolInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NodePoolInterfaceMock.DeleteFunc: method is nil but NodePoolInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNodePoolInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNodePoolInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNodePoolInterface.DeleteCalls()) +func (mock *NodePoolInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNodePoolInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNodePoolInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NodePoolInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NodePoolInterfaceMock.DeleteCollectionFunc: method is nil but NodePoolInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNodePoolInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNodePoolInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNodePoolInterface.DeleteCollectionCalls()) +func (mock *NodePoolInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNodePoolInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNodePoolInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NodePoolInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NodePoolInterfaceMock.DeleteNamespacedFunc: method is nil but NodePoolInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNodePoolInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNodePoolInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNodePoolInterface.DeleteNamespacedCalls()) +func (mock *NodePoolInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNodePoolInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNodePoolInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NodePoolInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NodePool, error) { + if mock.GetFunc == nil { + panic("NodePoolInterfaceMock.GetFunc: method is nil but NodePoolInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNodePoolInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodePoolInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodePoolInterface.GetCalls()) +func (mock *NodePoolInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNodePoolInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNodePoolInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NodePoolInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NodePool, error) { + if mock.GetNamespacedFunc == nil { + panic("NodePoolInterfaceMock.GetNamespacedFunc: method is nil but NodePoolInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNodePoolInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNodePoolInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNodePoolInterface.GetNamespacedCalls()) +func (mock *NodePoolInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNodePoolInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNodePoolInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodePoolInterfaceMock) List(opts metav1.ListOptions) (*v3.NodePoolList, error) { + if mock.ListFunc == nil { + panic("NodePoolInterfaceMock.ListFunc: method is nil but NodePoolInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodePoolInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodePoolInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodePoolInterface.ListCalls()) +func (mock *NodePoolInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodePoolInterfaceMockList.RLock() + calls = mock.calls.List + lockNodePoolInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NodePoolInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodePoolList, error) { + if mock.ListNamespacedFunc == nil { + panic("NodePoolInterfaceMock.ListNamespacedFunc: method is nil but NodePoolInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNodePoolInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNodePoolInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNodePoolInterface.ListNamespacedCalls()) +func (mock *NodePoolInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNodePoolInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNodePoolInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NodePoolInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NodePoolInterfaceMock.ObjectClientFunc: method is nil but NodePoolInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNodePoolInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNodePoolInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNodePoolInterface.ObjectClientCalls()) +func (mock *NodePoolInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNodePoolInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNodePoolInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NodePoolInterfaceMock) Update(in1 *v3.NodePool) (*v3.NodePool, error) { + if mock.UpdateFunc == nil { + panic("NodePoolInterfaceMock.UpdateFunc: method is nil but NodePoolInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NodePool + }{ + In1: in1, + } + lockNodePoolInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNodePoolInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNodePoolInterface.UpdateCalls()) +func (mock *NodePoolInterfaceMock) UpdateCalls() []struct { + In1 *v3.NodePool +} { + var calls []struct { + In1 *v3.NodePool + } + lockNodePoolInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNodePoolInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NodePoolInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NodePoolInterfaceMock.WatchFunc: method is nil but NodePoolInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodePoolInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNodePoolInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNodePoolInterface.WatchCalls()) +func (mock *NodePoolInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodePoolInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNodePoolInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNodePoolsGetterMockNodePools sync.RWMutex +) + +// Ensure, that NodePoolsGetterMock does implement v31.NodePoolsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NodePoolsGetter = &NodePoolsGetterMock{} + +// NodePoolsGetterMock is a mock implementation of v31.NodePoolsGetter. +// +// func TestSomethingThatUsesNodePoolsGetter(t *testing.T) { +// +// // make and configure a mocked v31.NodePoolsGetter +// mockedNodePoolsGetter := &NodePoolsGetterMock{ +// NodePoolsFunc: func(namespace string) v31.NodePoolInterface { +// panic("mock out the NodePools method") +// }, +// } +// +// // use mockedNodePoolsGetter in code that requires v31.NodePoolsGetter +// // and then make assertions. +// +// } +type NodePoolsGetterMock struct { + // NodePoolsFunc mocks the NodePools method. + NodePoolsFunc func(namespace string) v31.NodePoolInterface + + // calls tracks calls to the methods. + calls struct { + // NodePools holds details about calls to the NodePools method. + NodePools []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NodePools calls NodePoolsFunc. +func (mock *NodePoolsGetterMock) NodePools(namespace string) v31.NodePoolInterface { + if mock.NodePoolsFunc == nil { + panic("NodePoolsGetterMock.NodePoolsFunc: method is nil but NodePoolsGetter.NodePools was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNodePoolsGetterMockNodePools.Lock() + mock.calls.NodePools = append(mock.calls.NodePools, callInfo) + lockNodePoolsGetterMockNodePools.Unlock() + return mock.NodePoolsFunc(namespace) +} + +// NodePoolsCalls gets all the calls that were made to NodePools. +// Check the length with: +// +// len(mockedNodePoolsGetter.NodePoolsCalls()) +func (mock *NodePoolsGetterMock) NodePoolsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNodePoolsGetterMockNodePools.RLock() + calls = mock.calls.NodePools + lockNodePoolsGetterMockNodePools.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_template_mock.go new file mode 100644 index 0000000..5c45195 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_node_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNodeTemplateListerMockGet sync.RWMutex + lockNodeTemplateListerMockList sync.RWMutex +) + +// Ensure, that NodeTemplateListerMock does implement v31.NodeTemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeTemplateLister = &NodeTemplateListerMock{} + +// NodeTemplateListerMock is a mock implementation of v31.NodeTemplateLister. +// +// func TestSomethingThatUsesNodeTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.NodeTemplateLister +// mockedNodeTemplateLister := &NodeTemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NodeTemplate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NodeTemplate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNodeTemplateLister in code that requires v31.NodeTemplateLister +// // and then make assertions. +// +// } +type NodeTemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NodeTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NodeTemplate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NodeTemplateListerMock) Get(namespace string, name string) (*v3.NodeTemplate, error) { + if mock.GetFunc == nil { + panic("NodeTemplateListerMock.GetFunc: method is nil but NodeTemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeTemplateLister.GetCalls()) +func (mock *NodeTemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockNodeTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeTemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.NodeTemplate, error) { + if mock.ListFunc == nil { + panic("NodeTemplateListerMock.ListFunc: method is nil but NodeTemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNodeTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeTemplateLister.ListCalls()) +func (mock *NodeTemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNodeTemplateListerMockList.RLock() + calls = mock.calls.List + lockNodeTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockNodeTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockNodeTemplateControllerMockAddFeatureHandler sync.RWMutex + lockNodeTemplateControllerMockAddHandler sync.RWMutex + lockNodeTemplateControllerMockEnqueue sync.RWMutex + lockNodeTemplateControllerMockEnqueueAfter sync.RWMutex + lockNodeTemplateControllerMockGeneric sync.RWMutex + lockNodeTemplateControllerMockInformer sync.RWMutex + lockNodeTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that NodeTemplateControllerMock does implement v31.NodeTemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeTemplateController = &NodeTemplateControllerMock{} + +// NodeTemplateControllerMock is a mock implementation of v31.NodeTemplateController. +// +// func TestSomethingThatUsesNodeTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.NodeTemplateController +// mockedNodeTemplateController := &NodeTemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NodeTemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNodeTemplateController in code that requires v31.NodeTemplateController +// // and then make assertions. +// +// } +type NodeTemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NodeTemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NodeTemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeTemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NodeTemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeTemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NodeTemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeTemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeTemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeTemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeTemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc + } + lockNodeTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeTemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NodeTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeTemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but NodeTemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNodeTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeTemplateController.AddClusterScopedHandlerCalls()) +func (mock *NodeTemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NodeTemplateHandlerFunc + } + lockNodeTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeTemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeTemplateControllerMock.AddFeatureHandlerFunc: method is nil but NodeTemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeTemplateController.AddFeatureHandlerCalls()) +func (mock *NodeTemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc + } + lockNodeTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeTemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.NodeTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeTemplateControllerMock.AddHandlerFunc: method is nil but NodeTemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNodeTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeTemplateController.AddHandlerCalls()) +func (mock *NodeTemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NodeTemplateHandlerFunc + } + lockNodeTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NodeTemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NodeTemplateControllerMock.EnqueueFunc: method is nil but NodeTemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNodeTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNodeTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNodeTemplateController.EnqueueCalls()) +func (mock *NodeTemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNodeTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNodeTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NodeTemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NodeTemplateControllerMock.EnqueueAfterFunc: method is nil but NodeTemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNodeTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNodeTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNodeTemplateController.EnqueueAfterCalls()) +func (mock *NodeTemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNodeTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNodeTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NodeTemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NodeTemplateControllerMock.GenericFunc: method is nil but NodeTemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockNodeTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNodeTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNodeTemplateController.GenericCalls()) +func (mock *NodeTemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNodeTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNodeTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NodeTemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NodeTemplateControllerMock.InformerFunc: method is nil but NodeTemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockNodeTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNodeTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNodeTemplateController.InformerCalls()) +func (mock *NodeTemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNodeTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNodeTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NodeTemplateControllerMock) Lister() v31.NodeTemplateLister { + if mock.ListerFunc == nil { + panic("NodeTemplateControllerMock.ListerFunc: method is nil but NodeTemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockNodeTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNodeTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNodeTemplateController.ListerCalls()) +func (mock *NodeTemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNodeTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockNodeTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockNodeTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNodeTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNodeTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNodeTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNodeTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockNodeTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNodeTemplateInterfaceMockAddHandler sync.RWMutex + lockNodeTemplateInterfaceMockAddLifecycle sync.RWMutex + lockNodeTemplateInterfaceMockController sync.RWMutex + lockNodeTemplateInterfaceMockCreate sync.RWMutex + lockNodeTemplateInterfaceMockDelete sync.RWMutex + lockNodeTemplateInterfaceMockDeleteCollection sync.RWMutex + lockNodeTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockNodeTemplateInterfaceMockGet sync.RWMutex + lockNodeTemplateInterfaceMockGetNamespaced sync.RWMutex + lockNodeTemplateInterfaceMockList sync.RWMutex + lockNodeTemplateInterfaceMockListNamespaced sync.RWMutex + lockNodeTemplateInterfaceMockObjectClient sync.RWMutex + lockNodeTemplateInterfaceMockUpdate sync.RWMutex + lockNodeTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NodeTemplateInterfaceMock does implement v31.NodeTemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeTemplateInterface = &NodeTemplateInterfaceMock{} + +// NodeTemplateInterfaceMock is a mock implementation of v31.NodeTemplateInterface. +// +// func TestSomethingThatUsesNodeTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.NodeTemplateInterface +// mockedNodeTemplateInterface := &NodeTemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeTemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NodeTemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NodeTemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NodeTemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NodeTemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNodeTemplateInterface in code that requires v31.NodeTemplateInterface +// // and then make assertions. +// +// } +type NodeTemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeTemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NodeTemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NodeTemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NodeTemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NodeTemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NodeTemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeTemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeTemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NodeTemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeTemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeTemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeTemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NodeTemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NodeTemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NodeTemplate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NodeTemplate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NodeTemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NodeTemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NodeTemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNodeTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NodeTemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc + } + lockNodeTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNodeTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NodeTemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NodeTemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NodeTemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNodeTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NodeTemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle + } + lockNodeTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNodeTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NodeTemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NodeTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NodeTemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NodeTemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNodeTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNodeTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *NodeTemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NodeTemplateHandlerFunc + } + lockNodeTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNodeTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NodeTemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NodeTemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NodeTemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NodeTemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNodeTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNodeTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *NodeTemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NodeTemplateLifecycle + } + lockNodeTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNodeTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NodeTemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NodeTemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but NodeTemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNodeTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNodeTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddFeatureHandlerCalls()) +func (mock *NodeTemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NodeTemplateHandlerFunc + } + lockNodeTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNodeTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NodeTemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NodeTemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NodeTemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but NodeTemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNodeTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNodeTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *NodeTemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NodeTemplateLifecycle + } + lockNodeTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNodeTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NodeTemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NodeTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NodeTemplateInterfaceMock.AddHandlerFunc: method is nil but NodeTemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NodeTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNodeTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNodeTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddHandlerCalls()) +func (mock *NodeTemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NodeTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NodeTemplateHandlerFunc + } + lockNodeTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNodeTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NodeTemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NodeTemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NodeTemplateInterfaceMock.AddLifecycleFunc: method is nil but NodeTemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NodeTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNodeTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNodeTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNodeTemplateInterface.AddLifecycleCalls()) +func (mock *NodeTemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NodeTemplateLifecycle + } + lockNodeTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNodeTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NodeTemplateInterfaceMock) Controller() v31.NodeTemplateController { + if mock.ControllerFunc == nil { + panic("NodeTemplateInterfaceMock.ControllerFunc: method is nil but NodeTemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNodeTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNodeTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNodeTemplateInterface.ControllerCalls()) +func (mock *NodeTemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNodeTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNodeTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NodeTemplateInterfaceMock) Create(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) { + if mock.CreateFunc == nil { + panic("NodeTemplateInterfaceMock.CreateFunc: method is nil but NodeTemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NodeTemplate + }{ + In1: in1, + } + lockNodeTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNodeTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNodeTemplateInterface.CreateCalls()) +func (mock *NodeTemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.NodeTemplate +} { + var calls []struct { + In1 *v3.NodeTemplate + } + lockNodeTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNodeTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NodeTemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NodeTemplateInterfaceMock.DeleteFunc: method is nil but NodeTemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNodeTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNodeTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNodeTemplateInterface.DeleteCalls()) +func (mock *NodeTemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNodeTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNodeTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NodeTemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NodeTemplateInterfaceMock.DeleteCollectionFunc: method is nil but NodeTemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNodeTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNodeTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNodeTemplateInterface.DeleteCollectionCalls()) +func (mock *NodeTemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNodeTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNodeTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NodeTemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NodeTemplateInterfaceMock.DeleteNamespacedFunc: method is nil but NodeTemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNodeTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNodeTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNodeTemplateInterface.DeleteNamespacedCalls()) +func (mock *NodeTemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNodeTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNodeTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NodeTemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { + if mock.GetFunc == nil { + panic("NodeTemplateInterfaceMock.GetFunc: method is nil but NodeTemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNodeTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNodeTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNodeTemplateInterface.GetCalls()) +func (mock *NodeTemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNodeTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNodeTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NodeTemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { + if mock.GetNamespacedFunc == nil { + panic("NodeTemplateInterfaceMock.GetNamespacedFunc: method is nil but NodeTemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNodeTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNodeTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNodeTemplateInterface.GetNamespacedCalls()) +func (mock *NodeTemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNodeTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNodeTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NodeTemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.NodeTemplateList, error) { + if mock.ListFunc == nil { + panic("NodeTemplateInterfaceMock.ListFunc: method is nil but NodeTemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNodeTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNodeTemplateInterface.ListCalls()) +func (mock *NodeTemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockNodeTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NodeTemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeTemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("NodeTemplateInterfaceMock.ListNamespacedFunc: method is nil but NodeTemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNodeTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNodeTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNodeTemplateInterface.ListNamespacedCalls()) +func (mock *NodeTemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNodeTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNodeTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NodeTemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NodeTemplateInterfaceMock.ObjectClientFunc: method is nil but NodeTemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNodeTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNodeTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNodeTemplateInterface.ObjectClientCalls()) +func (mock *NodeTemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNodeTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNodeTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NodeTemplateInterfaceMock) Update(in1 *v3.NodeTemplate) (*v3.NodeTemplate, error) { + if mock.UpdateFunc == nil { + panic("NodeTemplateInterfaceMock.UpdateFunc: method is nil but NodeTemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NodeTemplate + }{ + In1: in1, + } + lockNodeTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNodeTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNodeTemplateInterface.UpdateCalls()) +func (mock *NodeTemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.NodeTemplate +} { + var calls []struct { + In1 *v3.NodeTemplate + } + lockNodeTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNodeTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NodeTemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NodeTemplateInterfaceMock.WatchFunc: method is nil but NodeTemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNodeTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNodeTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNodeTemplateInterface.WatchCalls()) +func (mock *NodeTemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNodeTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNodeTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNodeTemplatesGetterMockNodeTemplates sync.RWMutex +) + +// Ensure, that NodeTemplatesGetterMock does implement v31.NodeTemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NodeTemplatesGetter = &NodeTemplatesGetterMock{} + +// NodeTemplatesGetterMock is a mock implementation of v31.NodeTemplatesGetter. +// +// func TestSomethingThatUsesNodeTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.NodeTemplatesGetter +// mockedNodeTemplatesGetter := &NodeTemplatesGetterMock{ +// NodeTemplatesFunc: func(namespace string) v31.NodeTemplateInterface { +// panic("mock out the NodeTemplates method") +// }, +// } +// +// // use mockedNodeTemplatesGetter in code that requires v31.NodeTemplatesGetter +// // and then make assertions. +// +// } +type NodeTemplatesGetterMock struct { + // NodeTemplatesFunc mocks the NodeTemplates method. + NodeTemplatesFunc func(namespace string) v31.NodeTemplateInterface + + // calls tracks calls to the methods. + calls struct { + // NodeTemplates holds details about calls to the NodeTemplates method. + NodeTemplates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NodeTemplates calls NodeTemplatesFunc. +func (mock *NodeTemplatesGetterMock) NodeTemplates(namespace string) v31.NodeTemplateInterface { + if mock.NodeTemplatesFunc == nil { + panic("NodeTemplatesGetterMock.NodeTemplatesFunc: method is nil but NodeTemplatesGetter.NodeTemplates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNodeTemplatesGetterMockNodeTemplates.Lock() + mock.calls.NodeTemplates = append(mock.calls.NodeTemplates, callInfo) + lockNodeTemplatesGetterMockNodeTemplates.Unlock() + return mock.NodeTemplatesFunc(namespace) +} + +// NodeTemplatesCalls gets all the calls that were made to NodeTemplates. +// Check the length with: +// +// len(mockedNodeTemplatesGetter.NodeTemplatesCalls()) +func (mock *NodeTemplatesGetterMock) NodeTemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNodeTemplatesGetterMockNodeTemplates.RLock() + calls = mock.calls.NodeTemplates + lockNodeTemplatesGetterMockNodeTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_pod_security_admission_configuration_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_pod_security_admission_configuration_template_mock.go new file mode 100644 index 0000000..abd2c53 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_pod_security_admission_configuration_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockPodSecurityAdmissionConfigurationTemplateListerMockGet sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateListerMockList sync.RWMutex +) + +// Ensure, that PodSecurityAdmissionConfigurationTemplateListerMock does implement v31.PodSecurityAdmissionConfigurationTemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.PodSecurityAdmissionConfigurationTemplateLister = &PodSecurityAdmissionConfigurationTemplateListerMock{} + +// PodSecurityAdmissionConfigurationTemplateListerMock is a mock implementation of v31.PodSecurityAdmissionConfigurationTemplateLister. +// +// func TestSomethingThatUsesPodSecurityAdmissionConfigurationTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.PodSecurityAdmissionConfigurationTemplateLister +// mockedPodSecurityAdmissionConfigurationTemplateLister := &PodSecurityAdmissionConfigurationTemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedPodSecurityAdmissionConfigurationTemplateLister in code that requires v31.PodSecurityAdmissionConfigurationTemplateLister +// // and then make assertions. +// +// } +type PodSecurityAdmissionConfigurationTemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateListerMock) Get(namespace string, name string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.GetFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateListerMock.GetFunc: method is nil but PodSecurityAdmissionConfigurationTemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPodSecurityAdmissionConfigurationTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPodSecurityAdmissionConfigurationTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateLister.GetCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPodSecurityAdmissionConfigurationTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockPodSecurityAdmissionConfigurationTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.ListFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateListerMock.ListFunc: method is nil but PodSecurityAdmissionConfigurationTemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockPodSecurityAdmissionConfigurationTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPodSecurityAdmissionConfigurationTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateLister.ListCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockPodSecurityAdmissionConfigurationTemplateListerMockList.RLock() + calls = mock.calls.List + lockPodSecurityAdmissionConfigurationTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddFeatureHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueue sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueueAfter sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockGeneric sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockInformer sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that PodSecurityAdmissionConfigurationTemplateControllerMock does implement v31.PodSecurityAdmissionConfigurationTemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.PodSecurityAdmissionConfigurationTemplateController = &PodSecurityAdmissionConfigurationTemplateControllerMock{} + +// PodSecurityAdmissionConfigurationTemplateControllerMock is a mock implementation of v31.PodSecurityAdmissionConfigurationTemplateController. +// +// func TestSomethingThatUsesPodSecurityAdmissionConfigurationTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.PodSecurityAdmissionConfigurationTemplateController +// mockedPodSecurityAdmissionConfigurationTemplateController := &PodSecurityAdmissionConfigurationTemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.PodSecurityAdmissionConfigurationTemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedPodSecurityAdmissionConfigurationTemplateController in code that requires v31.PodSecurityAdmissionConfigurationTemplateController +// // and then make assertions. +// +// } +type PodSecurityAdmissionConfigurationTemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.PodSecurityAdmissionConfigurationTemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.AddClusterScopedHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.AddFeatureHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.AddFeatureHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.AddHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.AddHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPodSecurityAdmissionConfigurationTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.EnqueueFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.EnqueueCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.EnqueueAfterFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.EnqueueAfterCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockPodSecurityAdmissionConfigurationTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.GenericFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockPodSecurityAdmissionConfigurationTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.GenericCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockPodSecurityAdmissionConfigurationTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.InformerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockPodSecurityAdmissionConfigurationTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.InformerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockPodSecurityAdmissionConfigurationTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) Lister() v31.PodSecurityAdmissionConfigurationTemplateLister { + if mock.ListerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateControllerMock.ListerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockPodSecurityAdmissionConfigurationTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockPodSecurityAdmissionConfigurationTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateController.ListerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockPodSecurityAdmissionConfigurationTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockPodSecurityAdmissionConfigurationTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddHandler sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddLifecycle sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockController sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockCreate sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDelete sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteCollection sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGet sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGetNamespaced sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockList sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockListNamespaced sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockObjectClient sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockUpdate sync.RWMutex + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that PodSecurityAdmissionConfigurationTemplateInterfaceMock does implement v31.PodSecurityAdmissionConfigurationTemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.PodSecurityAdmissionConfigurationTemplateInterface = &PodSecurityAdmissionConfigurationTemplateInterfaceMock{} + +// PodSecurityAdmissionConfigurationTemplateInterfaceMock is a mock implementation of v31.PodSecurityAdmissionConfigurationTemplateInterface. +// +// func TestSomethingThatUsesPodSecurityAdmissionConfigurationTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.PodSecurityAdmissionConfigurationTemplateInterface +// mockedPodSecurityAdmissionConfigurationTemplateInterface := &PodSecurityAdmissionConfigurationTemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.PodSecurityAdmissionConfigurationTemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedPodSecurityAdmissionConfigurationTemplateInterface in code that requires v31.PodSecurityAdmissionConfigurationTemplateInterface +// // and then make assertions. +// +// } +type PodSecurityAdmissionConfigurationTemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.PodSecurityAdmissionConfigurationTemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.PodSecurityAdmissionConfigurationTemplate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.PodSecurityAdmissionConfigurationTemplate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddFeatureHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddHandlerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddHandlerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.PodSecurityAdmissionConfigurationTemplateHandlerFunc + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.AddLifecycleFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.AddLifecycleCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.PodSecurityAdmissionConfigurationTemplateLifecycle + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Controller() v31.PodSecurityAdmissionConfigurationTemplateController { + if mock.ControllerFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.ControllerFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.ControllerCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Create(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.CreateFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.CreateFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate + }{ + In1: in1, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.CreateCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate +} { + var calls []struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.DeleteFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.DeleteCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.DeleteCollectionFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.DeleteCollectionCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.DeleteNamespacedFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.DeleteNamespacedCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.GetFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.GetFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.GetCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.GetNamespacedFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.GetNamespacedFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.GetNamespacedCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { + if mock.ListFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.ListFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.ListCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.ListNamespacedFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.ListNamespacedCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.ObjectClientFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.ObjectClientCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Update(in1 *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + if mock.UpdateFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.UpdateFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate + }{ + In1: in1, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.UpdateCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate +} { + var calls []struct { + In1 *v3.PodSecurityAdmissionConfigurationTemplate + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplateInterfaceMock.WatchFunc: method is nil but PodSecurityAdmissionConfigurationTemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplateInterface.WatchCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockPodSecurityAdmissionConfigurationTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockPodSecurityAdmissionConfigurationTemplatesGetterMockPodSecurityAdmissionConfigurationTemplates sync.RWMutex +) + +// Ensure, that PodSecurityAdmissionConfigurationTemplatesGetterMock does implement v31.PodSecurityAdmissionConfigurationTemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.PodSecurityAdmissionConfigurationTemplatesGetter = &PodSecurityAdmissionConfigurationTemplatesGetterMock{} + +// PodSecurityAdmissionConfigurationTemplatesGetterMock is a mock implementation of v31.PodSecurityAdmissionConfigurationTemplatesGetter. +// +// func TestSomethingThatUsesPodSecurityAdmissionConfigurationTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.PodSecurityAdmissionConfigurationTemplatesGetter +// mockedPodSecurityAdmissionConfigurationTemplatesGetter := &PodSecurityAdmissionConfigurationTemplatesGetterMock{ +// PodSecurityAdmissionConfigurationTemplatesFunc: func(namespace string) v31.PodSecurityAdmissionConfigurationTemplateInterface { +// panic("mock out the PodSecurityAdmissionConfigurationTemplates method") +// }, +// } +// +// // use mockedPodSecurityAdmissionConfigurationTemplatesGetter in code that requires v31.PodSecurityAdmissionConfigurationTemplatesGetter +// // and then make assertions. +// +// } +type PodSecurityAdmissionConfigurationTemplatesGetterMock struct { + // PodSecurityAdmissionConfigurationTemplatesFunc mocks the PodSecurityAdmissionConfigurationTemplates method. + PodSecurityAdmissionConfigurationTemplatesFunc func(namespace string) v31.PodSecurityAdmissionConfigurationTemplateInterface + + // calls tracks calls to the methods. + calls struct { + // PodSecurityAdmissionConfigurationTemplates holds details about calls to the PodSecurityAdmissionConfigurationTemplates method. + PodSecurityAdmissionConfigurationTemplates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// PodSecurityAdmissionConfigurationTemplates calls PodSecurityAdmissionConfigurationTemplatesFunc. +func (mock *PodSecurityAdmissionConfigurationTemplatesGetterMock) PodSecurityAdmissionConfigurationTemplates(namespace string) v31.PodSecurityAdmissionConfigurationTemplateInterface { + if mock.PodSecurityAdmissionConfigurationTemplatesFunc == nil { + panic("PodSecurityAdmissionConfigurationTemplatesGetterMock.PodSecurityAdmissionConfigurationTemplatesFunc: method is nil but PodSecurityAdmissionConfigurationTemplatesGetter.PodSecurityAdmissionConfigurationTemplates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockPodSecurityAdmissionConfigurationTemplatesGetterMockPodSecurityAdmissionConfigurationTemplates.Lock() + mock.calls.PodSecurityAdmissionConfigurationTemplates = append(mock.calls.PodSecurityAdmissionConfigurationTemplates, callInfo) + lockPodSecurityAdmissionConfigurationTemplatesGetterMockPodSecurityAdmissionConfigurationTemplates.Unlock() + return mock.PodSecurityAdmissionConfigurationTemplatesFunc(namespace) +} + +// PodSecurityAdmissionConfigurationTemplatesCalls gets all the calls that were made to PodSecurityAdmissionConfigurationTemplates. +// Check the length with: +// +// len(mockedPodSecurityAdmissionConfigurationTemplatesGetter.PodSecurityAdmissionConfigurationTemplatesCalls()) +func (mock *PodSecurityAdmissionConfigurationTemplatesGetterMock) PodSecurityAdmissionConfigurationTemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockPodSecurityAdmissionConfigurationTemplatesGetterMockPodSecurityAdmissionConfigurationTemplates.RLock() + calls = mock.calls.PodSecurityAdmissionConfigurationTemplates + lockPodSecurityAdmissionConfigurationTemplatesGetterMockPodSecurityAdmissionConfigurationTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_preference_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_preference_mock.go new file mode 100644 index 0000000..3c4cef3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_preference_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockPreferenceListerMockGet sync.RWMutex + lockPreferenceListerMockList sync.RWMutex +) + +// Ensure, that PreferenceListerMock does implement v31.PreferenceLister. +// If this is not the case, regenerate this file with moq. +var _ v31.PreferenceLister = &PreferenceListerMock{} + +// PreferenceListerMock is a mock implementation of v31.PreferenceLister. +// +// func TestSomethingThatUsesPreferenceLister(t *testing.T) { +// +// // make and configure a mocked v31.PreferenceLister +// mockedPreferenceLister := &PreferenceListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Preference, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Preference, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedPreferenceLister in code that requires v31.PreferenceLister +// // and then make assertions. +// +// } +type PreferenceListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Preference, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Preference, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *PreferenceListerMock) Get(namespace string, name string) (*v3.Preference, error) { + if mock.GetFunc == nil { + panic("PreferenceListerMock.GetFunc: method is nil but PreferenceLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPreferenceListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPreferenceListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPreferenceLister.GetCalls()) +func (mock *PreferenceListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPreferenceListerMockGet.RLock() + calls = mock.calls.Get + lockPreferenceListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PreferenceListerMock) List(namespace string, selector labels.Selector) ([]*v3.Preference, error) { + if mock.ListFunc == nil { + panic("PreferenceListerMock.ListFunc: method is nil but PreferenceLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockPreferenceListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPreferenceListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPreferenceLister.ListCalls()) +func (mock *PreferenceListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockPreferenceListerMockList.RLock() + calls = mock.calls.List + lockPreferenceListerMockList.RUnlock() + return calls +} + +var ( + lockPreferenceControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockPreferenceControllerMockAddClusterScopedHandler sync.RWMutex + lockPreferenceControllerMockAddFeatureHandler sync.RWMutex + lockPreferenceControllerMockAddHandler sync.RWMutex + lockPreferenceControllerMockEnqueue sync.RWMutex + lockPreferenceControllerMockEnqueueAfter sync.RWMutex + lockPreferenceControllerMockGeneric sync.RWMutex + lockPreferenceControllerMockInformer sync.RWMutex + lockPreferenceControllerMockLister sync.RWMutex +) + +// Ensure, that PreferenceControllerMock does implement v31.PreferenceController. +// If this is not the case, regenerate this file with moq. +var _ v31.PreferenceController = &PreferenceControllerMock{} + +// PreferenceControllerMock is a mock implementation of v31.PreferenceController. +// +// func TestSomethingThatUsesPreferenceController(t *testing.T) { +// +// // make and configure a mocked v31.PreferenceController +// mockedPreferenceController := &PreferenceControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PreferenceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.PreferenceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.PreferenceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.PreferenceLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedPreferenceController in code that requires v31.PreferenceController +// // and then make assertions. +// +// } +type PreferenceControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PreferenceHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.PreferenceHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.PreferenceHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.PreferenceLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PreferenceHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PreferenceHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PreferenceHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.PreferenceHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PreferenceControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PreferenceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PreferenceControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but PreferenceController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPreferenceControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPreferenceControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPreferenceController.AddClusterScopedFeatureHandlerCalls()) +func (mock *PreferenceControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc + } + lockPreferenceControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPreferenceControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PreferenceControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.PreferenceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PreferenceControllerMock.AddClusterScopedHandlerFunc: method is nil but PreferenceController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPreferenceControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPreferenceControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPreferenceController.AddClusterScopedHandlerCalls()) +func (mock *PreferenceControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PreferenceHandlerFunc + } + lockPreferenceControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPreferenceControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PreferenceControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PreferenceControllerMock.AddFeatureHandlerFunc: method is nil but PreferenceController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPreferenceControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPreferenceControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPreferenceController.AddFeatureHandlerCalls()) +func (mock *PreferenceControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc + } + lockPreferenceControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPreferenceControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PreferenceControllerMock) AddHandler(ctx context.Context, name string, handler v31.PreferenceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PreferenceControllerMock.AddHandlerFunc: method is nil but PreferenceController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockPreferenceControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPreferenceControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPreferenceController.AddHandlerCalls()) +func (mock *PreferenceControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.PreferenceHandlerFunc + } + lockPreferenceControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPreferenceControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *PreferenceControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("PreferenceControllerMock.EnqueueFunc: method is nil but PreferenceController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPreferenceControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockPreferenceControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedPreferenceController.EnqueueCalls()) +func (mock *PreferenceControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPreferenceControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockPreferenceControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *PreferenceControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("PreferenceControllerMock.EnqueueAfterFunc: method is nil but PreferenceController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockPreferenceControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockPreferenceControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedPreferenceController.EnqueueAfterCalls()) +func (mock *PreferenceControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockPreferenceControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockPreferenceControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *PreferenceControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("PreferenceControllerMock.GenericFunc: method is nil but PreferenceController.Generic was just called") + } + callInfo := struct { + }{} + lockPreferenceControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockPreferenceControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedPreferenceController.GenericCalls()) +func (mock *PreferenceControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockPreferenceControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockPreferenceControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *PreferenceControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("PreferenceControllerMock.InformerFunc: method is nil but PreferenceController.Informer was just called") + } + callInfo := struct { + }{} + lockPreferenceControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockPreferenceControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedPreferenceController.InformerCalls()) +func (mock *PreferenceControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockPreferenceControllerMockInformer.RLock() + calls = mock.calls.Informer + lockPreferenceControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *PreferenceControllerMock) Lister() v31.PreferenceLister { + if mock.ListerFunc == nil { + panic("PreferenceControllerMock.ListerFunc: method is nil but PreferenceController.Lister was just called") + } + callInfo := struct { + }{} + lockPreferenceControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockPreferenceControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedPreferenceController.ListerCalls()) +func (mock *PreferenceControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockPreferenceControllerMockLister.RLock() + calls = mock.calls.Lister + lockPreferenceControllerMockLister.RUnlock() + return calls +} + +var ( + lockPreferenceInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockPreferenceInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockPreferenceInterfaceMockAddClusterScopedHandler sync.RWMutex + lockPreferenceInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockPreferenceInterfaceMockAddFeatureHandler sync.RWMutex + lockPreferenceInterfaceMockAddFeatureLifecycle sync.RWMutex + lockPreferenceInterfaceMockAddHandler sync.RWMutex + lockPreferenceInterfaceMockAddLifecycle sync.RWMutex + lockPreferenceInterfaceMockController sync.RWMutex + lockPreferenceInterfaceMockCreate sync.RWMutex + lockPreferenceInterfaceMockDelete sync.RWMutex + lockPreferenceInterfaceMockDeleteCollection sync.RWMutex + lockPreferenceInterfaceMockDeleteNamespaced sync.RWMutex + lockPreferenceInterfaceMockGet sync.RWMutex + lockPreferenceInterfaceMockGetNamespaced sync.RWMutex + lockPreferenceInterfaceMockList sync.RWMutex + lockPreferenceInterfaceMockListNamespaced sync.RWMutex + lockPreferenceInterfaceMockObjectClient sync.RWMutex + lockPreferenceInterfaceMockUpdate sync.RWMutex + lockPreferenceInterfaceMockWatch sync.RWMutex +) + +// Ensure, that PreferenceInterfaceMock does implement v31.PreferenceInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.PreferenceInterface = &PreferenceInterfaceMock{} + +// PreferenceInterfaceMock is a mock implementation of v31.PreferenceInterface. +// +// func TestSomethingThatUsesPreferenceInterface(t *testing.T) { +// +// // make and configure a mocked v31.PreferenceInterface +// mockedPreferenceInterface := &PreferenceInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PreferenceLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.PreferenceLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PreferenceLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.PreferenceHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.PreferenceLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.PreferenceController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Preference) (*v3.Preference, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Preference, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Preference, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.PreferenceList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.PreferenceList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Preference) (*v3.Preference, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedPreferenceInterface in code that requires v31.PreferenceInterface +// // and then make assertions. +// +// } +type PreferenceInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PreferenceLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.PreferenceLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PreferenceLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.PreferenceHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.PreferenceLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.PreferenceController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Preference) (*v3.Preference, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Preference, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Preference, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.PreferenceList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.PreferenceList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Preference) (*v3.Preference, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PreferenceHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PreferenceLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PreferenceHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PreferenceLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PreferenceHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PreferenceLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PreferenceHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PreferenceLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Preference + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Preference + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PreferenceInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PreferenceInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but PreferenceInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPreferenceInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPreferenceInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPreferenceInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *PreferenceInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc + } + lockPreferenceInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPreferenceInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *PreferenceInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PreferenceLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("PreferenceInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but PreferenceInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPreferenceInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockPreferenceInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedPreferenceInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *PreferenceInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle + } + lockPreferenceInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockPreferenceInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PreferenceInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.PreferenceHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PreferenceInterfaceMock.AddClusterScopedHandlerFunc: method is nil but PreferenceInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPreferenceInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPreferenceInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPreferenceInterface.AddClusterScopedHandlerCalls()) +func (mock *PreferenceInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PreferenceHandlerFunc + } + lockPreferenceInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPreferenceInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *PreferenceInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.PreferenceLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("PreferenceInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but PreferenceInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPreferenceInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockPreferenceInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedPreferenceInterface.AddClusterScopedLifecycleCalls()) +func (mock *PreferenceInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PreferenceLifecycle + } + lockPreferenceInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockPreferenceInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PreferenceInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PreferenceHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PreferenceInterfaceMock.AddFeatureHandlerFunc: method is nil but PreferenceInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPreferenceInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPreferenceInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPreferenceInterface.AddFeatureHandlerCalls()) +func (mock *PreferenceInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PreferenceHandlerFunc + } + lockPreferenceInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPreferenceInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *PreferenceInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.PreferenceLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("PreferenceInterfaceMock.AddFeatureLifecycleFunc: method is nil but PreferenceInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PreferenceLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockPreferenceInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockPreferenceInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedPreferenceInterface.AddFeatureLifecycleCalls()) +func (mock *PreferenceInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PreferenceLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PreferenceLifecycle + } + lockPreferenceInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockPreferenceInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PreferenceInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.PreferenceHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PreferenceInterfaceMock.AddHandlerFunc: method is nil but PreferenceInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.PreferenceHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockPreferenceInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPreferenceInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPreferenceInterface.AddHandlerCalls()) +func (mock *PreferenceInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.PreferenceHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.PreferenceHandlerFunc + } + lockPreferenceInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPreferenceInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *PreferenceInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.PreferenceLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("PreferenceInterfaceMock.AddLifecycleFunc: method is nil but PreferenceInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.PreferenceLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockPreferenceInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockPreferenceInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedPreferenceInterface.AddLifecycleCalls()) +func (mock *PreferenceInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.PreferenceLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.PreferenceLifecycle + } + lockPreferenceInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockPreferenceInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *PreferenceInterfaceMock) Controller() v31.PreferenceController { + if mock.ControllerFunc == nil { + panic("PreferenceInterfaceMock.ControllerFunc: method is nil but PreferenceInterface.Controller was just called") + } + callInfo := struct { + }{} + lockPreferenceInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockPreferenceInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedPreferenceInterface.ControllerCalls()) +func (mock *PreferenceInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockPreferenceInterfaceMockController.RLock() + calls = mock.calls.Controller + lockPreferenceInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *PreferenceInterfaceMock) Create(in1 *v3.Preference) (*v3.Preference, error) { + if mock.CreateFunc == nil { + panic("PreferenceInterfaceMock.CreateFunc: method is nil but PreferenceInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Preference + }{ + In1: in1, + } + lockPreferenceInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockPreferenceInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedPreferenceInterface.CreateCalls()) +func (mock *PreferenceInterfaceMock) CreateCalls() []struct { + In1 *v3.Preference +} { + var calls []struct { + In1 *v3.Preference + } + lockPreferenceInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockPreferenceInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *PreferenceInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("PreferenceInterfaceMock.DeleteFunc: method is nil but PreferenceInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockPreferenceInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockPreferenceInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedPreferenceInterface.DeleteCalls()) +func (mock *PreferenceInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockPreferenceInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockPreferenceInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *PreferenceInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("PreferenceInterfaceMock.DeleteCollectionFunc: method is nil but PreferenceInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockPreferenceInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockPreferenceInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedPreferenceInterface.DeleteCollectionCalls()) +func (mock *PreferenceInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockPreferenceInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockPreferenceInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *PreferenceInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("PreferenceInterfaceMock.DeleteNamespacedFunc: method is nil but PreferenceInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockPreferenceInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockPreferenceInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedPreferenceInterface.DeleteNamespacedCalls()) +func (mock *PreferenceInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockPreferenceInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockPreferenceInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *PreferenceInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Preference, error) { + if mock.GetFunc == nil { + panic("PreferenceInterfaceMock.GetFunc: method is nil but PreferenceInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockPreferenceInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPreferenceInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPreferenceInterface.GetCalls()) +func (mock *PreferenceInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockPreferenceInterfaceMockGet.RLock() + calls = mock.calls.Get + lockPreferenceInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *PreferenceInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Preference, error) { + if mock.GetNamespacedFunc == nil { + panic("PreferenceInterfaceMock.GetNamespacedFunc: method is nil but PreferenceInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockPreferenceInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockPreferenceInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedPreferenceInterface.GetNamespacedCalls()) +func (mock *PreferenceInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockPreferenceInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockPreferenceInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PreferenceInterfaceMock) List(opts metav1.ListOptions) (*v3.PreferenceList, error) { + if mock.ListFunc == nil { + panic("PreferenceInterfaceMock.ListFunc: method is nil but PreferenceInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPreferenceInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPreferenceInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPreferenceInterface.ListCalls()) +func (mock *PreferenceInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPreferenceInterfaceMockList.RLock() + calls = mock.calls.List + lockPreferenceInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *PreferenceInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PreferenceList, error) { + if mock.ListNamespacedFunc == nil { + panic("PreferenceInterfaceMock.ListNamespacedFunc: method is nil but PreferenceInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockPreferenceInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockPreferenceInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedPreferenceInterface.ListNamespacedCalls()) +func (mock *PreferenceInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockPreferenceInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockPreferenceInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *PreferenceInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("PreferenceInterfaceMock.ObjectClientFunc: method is nil but PreferenceInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockPreferenceInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockPreferenceInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedPreferenceInterface.ObjectClientCalls()) +func (mock *PreferenceInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockPreferenceInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockPreferenceInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *PreferenceInterfaceMock) Update(in1 *v3.Preference) (*v3.Preference, error) { + if mock.UpdateFunc == nil { + panic("PreferenceInterfaceMock.UpdateFunc: method is nil but PreferenceInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Preference + }{ + In1: in1, + } + lockPreferenceInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockPreferenceInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedPreferenceInterface.UpdateCalls()) +func (mock *PreferenceInterfaceMock) UpdateCalls() []struct { + In1 *v3.Preference +} { + var calls []struct { + In1 *v3.Preference + } + lockPreferenceInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockPreferenceInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *PreferenceInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("PreferenceInterfaceMock.WatchFunc: method is nil but PreferenceInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPreferenceInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockPreferenceInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedPreferenceInterface.WatchCalls()) +func (mock *PreferenceInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPreferenceInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockPreferenceInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockPreferencesGetterMockPreferences sync.RWMutex +) + +// Ensure, that PreferencesGetterMock does implement v31.PreferencesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.PreferencesGetter = &PreferencesGetterMock{} + +// PreferencesGetterMock is a mock implementation of v31.PreferencesGetter. +// +// func TestSomethingThatUsesPreferencesGetter(t *testing.T) { +// +// // make and configure a mocked v31.PreferencesGetter +// mockedPreferencesGetter := &PreferencesGetterMock{ +// PreferencesFunc: func(namespace string) v31.PreferenceInterface { +// panic("mock out the Preferences method") +// }, +// } +// +// // use mockedPreferencesGetter in code that requires v31.PreferencesGetter +// // and then make assertions. +// +// } +type PreferencesGetterMock struct { + // PreferencesFunc mocks the Preferences method. + PreferencesFunc func(namespace string) v31.PreferenceInterface + + // calls tracks calls to the methods. + calls struct { + // Preferences holds details about calls to the Preferences method. + Preferences []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Preferences calls PreferencesFunc. +func (mock *PreferencesGetterMock) Preferences(namespace string) v31.PreferenceInterface { + if mock.PreferencesFunc == nil { + panic("PreferencesGetterMock.PreferencesFunc: method is nil but PreferencesGetter.Preferences was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockPreferencesGetterMockPreferences.Lock() + mock.calls.Preferences = append(mock.calls.Preferences, callInfo) + lockPreferencesGetterMockPreferences.Unlock() + return mock.PreferencesFunc(namespace) +} + +// PreferencesCalls gets all the calls that were made to Preferences. +// Check the length with: +// +// len(mockedPreferencesGetter.PreferencesCalls()) +func (mock *PreferencesGetterMock) PreferencesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockPreferencesGetterMockPreferences.RLock() + calls = mock.calls.Preferences + lockPreferencesGetterMockPreferences.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_principal_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_principal_mock.go new file mode 100644 index 0000000..3d2614a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_principal_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockPrincipalListerMockGet sync.RWMutex + lockPrincipalListerMockList sync.RWMutex +) + +// Ensure, that PrincipalListerMock does implement v31.PrincipalLister. +// If this is not the case, regenerate this file with moq. +var _ v31.PrincipalLister = &PrincipalListerMock{} + +// PrincipalListerMock is a mock implementation of v31.PrincipalLister. +// +// func TestSomethingThatUsesPrincipalLister(t *testing.T) { +// +// // make and configure a mocked v31.PrincipalLister +// mockedPrincipalLister := &PrincipalListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Principal, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Principal, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedPrincipalLister in code that requires v31.PrincipalLister +// // and then make assertions. +// +// } +type PrincipalListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Principal, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Principal, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *PrincipalListerMock) Get(namespace string, name string) (*v3.Principal, error) { + if mock.GetFunc == nil { + panic("PrincipalListerMock.GetFunc: method is nil but PrincipalLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPrincipalListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPrincipalListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPrincipalLister.GetCalls()) +func (mock *PrincipalListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPrincipalListerMockGet.RLock() + calls = mock.calls.Get + lockPrincipalListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PrincipalListerMock) List(namespace string, selector labels.Selector) ([]*v3.Principal, error) { + if mock.ListFunc == nil { + panic("PrincipalListerMock.ListFunc: method is nil but PrincipalLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockPrincipalListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPrincipalListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPrincipalLister.ListCalls()) +func (mock *PrincipalListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockPrincipalListerMockList.RLock() + calls = mock.calls.List + lockPrincipalListerMockList.RUnlock() + return calls +} + +var ( + lockPrincipalControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockPrincipalControllerMockAddClusterScopedHandler sync.RWMutex + lockPrincipalControllerMockAddFeatureHandler sync.RWMutex + lockPrincipalControllerMockAddHandler sync.RWMutex + lockPrincipalControllerMockEnqueue sync.RWMutex + lockPrincipalControllerMockEnqueueAfter sync.RWMutex + lockPrincipalControllerMockGeneric sync.RWMutex + lockPrincipalControllerMockInformer sync.RWMutex + lockPrincipalControllerMockLister sync.RWMutex +) + +// Ensure, that PrincipalControllerMock does implement v31.PrincipalController. +// If this is not the case, regenerate this file with moq. +var _ v31.PrincipalController = &PrincipalControllerMock{} + +// PrincipalControllerMock is a mock implementation of v31.PrincipalController. +// +// func TestSomethingThatUsesPrincipalController(t *testing.T) { +// +// // make and configure a mocked v31.PrincipalController +// mockedPrincipalController := &PrincipalControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PrincipalHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.PrincipalHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.PrincipalHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.PrincipalLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedPrincipalController in code that requires v31.PrincipalController +// // and then make assertions. +// +// } +type PrincipalControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PrincipalHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.PrincipalHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.PrincipalHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.PrincipalLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PrincipalHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.PrincipalHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PrincipalHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.PrincipalHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PrincipalControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.PrincipalHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PrincipalControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but PrincipalController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPrincipalControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPrincipalControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPrincipalController.AddClusterScopedFeatureHandlerCalls()) +func (mock *PrincipalControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc + } + lockPrincipalControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPrincipalControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PrincipalControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.PrincipalHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PrincipalControllerMock.AddClusterScopedHandlerFunc: method is nil but PrincipalController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockPrincipalControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPrincipalControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPrincipalController.AddClusterScopedHandlerCalls()) +func (mock *PrincipalControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.PrincipalHandlerFunc + } + lockPrincipalControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPrincipalControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PrincipalControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PrincipalControllerMock.AddFeatureHandlerFunc: method is nil but PrincipalController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPrincipalControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPrincipalControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPrincipalController.AddFeatureHandlerCalls()) +func (mock *PrincipalControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc + } + lockPrincipalControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPrincipalControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PrincipalControllerMock) AddHandler(ctx context.Context, name string, handler v31.PrincipalHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PrincipalControllerMock.AddHandlerFunc: method is nil but PrincipalController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockPrincipalControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPrincipalControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPrincipalController.AddHandlerCalls()) +func (mock *PrincipalControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.PrincipalHandlerFunc + } + lockPrincipalControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPrincipalControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *PrincipalControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("PrincipalControllerMock.EnqueueFunc: method is nil but PrincipalController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockPrincipalControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockPrincipalControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedPrincipalController.EnqueueCalls()) +func (mock *PrincipalControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockPrincipalControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockPrincipalControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *PrincipalControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("PrincipalControllerMock.EnqueueAfterFunc: method is nil but PrincipalController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockPrincipalControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockPrincipalControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedPrincipalController.EnqueueAfterCalls()) +func (mock *PrincipalControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockPrincipalControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockPrincipalControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *PrincipalControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("PrincipalControllerMock.GenericFunc: method is nil but PrincipalController.Generic was just called") + } + callInfo := struct { + }{} + lockPrincipalControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockPrincipalControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedPrincipalController.GenericCalls()) +func (mock *PrincipalControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockPrincipalControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockPrincipalControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *PrincipalControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("PrincipalControllerMock.InformerFunc: method is nil but PrincipalController.Informer was just called") + } + callInfo := struct { + }{} + lockPrincipalControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockPrincipalControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedPrincipalController.InformerCalls()) +func (mock *PrincipalControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockPrincipalControllerMockInformer.RLock() + calls = mock.calls.Informer + lockPrincipalControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *PrincipalControllerMock) Lister() v31.PrincipalLister { + if mock.ListerFunc == nil { + panic("PrincipalControllerMock.ListerFunc: method is nil but PrincipalController.Lister was just called") + } + callInfo := struct { + }{} + lockPrincipalControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockPrincipalControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedPrincipalController.ListerCalls()) +func (mock *PrincipalControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockPrincipalControllerMockLister.RLock() + calls = mock.calls.Lister + lockPrincipalControllerMockLister.RUnlock() + return calls +} + +var ( + lockPrincipalInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockPrincipalInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockPrincipalInterfaceMockAddClusterScopedHandler sync.RWMutex + lockPrincipalInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockPrincipalInterfaceMockAddFeatureHandler sync.RWMutex + lockPrincipalInterfaceMockAddFeatureLifecycle sync.RWMutex + lockPrincipalInterfaceMockAddHandler sync.RWMutex + lockPrincipalInterfaceMockAddLifecycle sync.RWMutex + lockPrincipalInterfaceMockController sync.RWMutex + lockPrincipalInterfaceMockCreate sync.RWMutex + lockPrincipalInterfaceMockDelete sync.RWMutex + lockPrincipalInterfaceMockDeleteCollection sync.RWMutex + lockPrincipalInterfaceMockDeleteNamespaced sync.RWMutex + lockPrincipalInterfaceMockGet sync.RWMutex + lockPrincipalInterfaceMockGetNamespaced sync.RWMutex + lockPrincipalInterfaceMockList sync.RWMutex + lockPrincipalInterfaceMockListNamespaced sync.RWMutex + lockPrincipalInterfaceMockObjectClient sync.RWMutex + lockPrincipalInterfaceMockUpdate sync.RWMutex + lockPrincipalInterfaceMockWatch sync.RWMutex +) + +// Ensure, that PrincipalInterfaceMock does implement v31.PrincipalInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.PrincipalInterface = &PrincipalInterfaceMock{} + +// PrincipalInterfaceMock is a mock implementation of v31.PrincipalInterface. +// +// func TestSomethingThatUsesPrincipalInterface(t *testing.T) { +// +// // make and configure a mocked v31.PrincipalInterface +// mockedPrincipalInterface := &PrincipalInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PrincipalLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.PrincipalLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PrincipalLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.PrincipalHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.PrincipalLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.PrincipalController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Principal) (*v3.Principal, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Principal, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Principal, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.PrincipalList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.PrincipalList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Principal) (*v3.Principal, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedPrincipalInterface in code that requires v31.PrincipalInterface +// // and then make assertions. +// +// } +type PrincipalInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PrincipalLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.PrincipalLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.PrincipalLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.PrincipalHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.PrincipalLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.PrincipalController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Principal) (*v3.Principal, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Principal, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Principal, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.PrincipalList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.PrincipalList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Principal) (*v3.Principal, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PrincipalHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PrincipalLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.PrincipalHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PrincipalLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PrincipalHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PrincipalLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.PrincipalHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.PrincipalLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Principal + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Principal + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *PrincipalInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("PrincipalInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but PrincipalInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPrincipalInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockPrincipalInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedPrincipalInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *PrincipalInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc + } + lockPrincipalInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockPrincipalInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *PrincipalInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.PrincipalLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("PrincipalInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but PrincipalInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPrincipalInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockPrincipalInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedPrincipalInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *PrincipalInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle + } + lockPrincipalInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockPrincipalInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *PrincipalInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.PrincipalHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("PrincipalInterfaceMock.AddClusterScopedHandlerFunc: method is nil but PrincipalInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockPrincipalInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockPrincipalInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedPrincipalInterface.AddClusterScopedHandlerCalls()) +func (mock *PrincipalInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.PrincipalHandlerFunc + } + lockPrincipalInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockPrincipalInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *PrincipalInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.PrincipalLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("PrincipalInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but PrincipalInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockPrincipalInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockPrincipalInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedPrincipalInterface.AddClusterScopedLifecycleCalls()) +func (mock *PrincipalInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.PrincipalLifecycle + } + lockPrincipalInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockPrincipalInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *PrincipalInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.PrincipalHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("PrincipalInterfaceMock.AddFeatureHandlerFunc: method is nil but PrincipalInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockPrincipalInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockPrincipalInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedPrincipalInterface.AddFeatureHandlerCalls()) +func (mock *PrincipalInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.PrincipalHandlerFunc + } + lockPrincipalInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockPrincipalInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *PrincipalInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.PrincipalLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("PrincipalInterfaceMock.AddFeatureLifecycleFunc: method is nil but PrincipalInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PrincipalLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockPrincipalInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockPrincipalInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedPrincipalInterface.AddFeatureLifecycleCalls()) +func (mock *PrincipalInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PrincipalLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.PrincipalLifecycle + } + lockPrincipalInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockPrincipalInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *PrincipalInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.PrincipalHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("PrincipalInterfaceMock.AddHandlerFunc: method is nil but PrincipalInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.PrincipalHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockPrincipalInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockPrincipalInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedPrincipalInterface.AddHandlerCalls()) +func (mock *PrincipalInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.PrincipalHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.PrincipalHandlerFunc + } + lockPrincipalInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockPrincipalInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *PrincipalInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.PrincipalLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("PrincipalInterfaceMock.AddLifecycleFunc: method is nil but PrincipalInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.PrincipalLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockPrincipalInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockPrincipalInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedPrincipalInterface.AddLifecycleCalls()) +func (mock *PrincipalInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.PrincipalLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.PrincipalLifecycle + } + lockPrincipalInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockPrincipalInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *PrincipalInterfaceMock) Controller() v31.PrincipalController { + if mock.ControllerFunc == nil { + panic("PrincipalInterfaceMock.ControllerFunc: method is nil but PrincipalInterface.Controller was just called") + } + callInfo := struct { + }{} + lockPrincipalInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockPrincipalInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedPrincipalInterface.ControllerCalls()) +func (mock *PrincipalInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockPrincipalInterfaceMockController.RLock() + calls = mock.calls.Controller + lockPrincipalInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *PrincipalInterfaceMock) Create(in1 *v3.Principal) (*v3.Principal, error) { + if mock.CreateFunc == nil { + panic("PrincipalInterfaceMock.CreateFunc: method is nil but PrincipalInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Principal + }{ + In1: in1, + } + lockPrincipalInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockPrincipalInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedPrincipalInterface.CreateCalls()) +func (mock *PrincipalInterfaceMock) CreateCalls() []struct { + In1 *v3.Principal +} { + var calls []struct { + In1 *v3.Principal + } + lockPrincipalInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockPrincipalInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *PrincipalInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("PrincipalInterfaceMock.DeleteFunc: method is nil but PrincipalInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockPrincipalInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockPrincipalInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedPrincipalInterface.DeleteCalls()) +func (mock *PrincipalInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockPrincipalInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockPrincipalInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *PrincipalInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("PrincipalInterfaceMock.DeleteCollectionFunc: method is nil but PrincipalInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockPrincipalInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockPrincipalInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedPrincipalInterface.DeleteCollectionCalls()) +func (mock *PrincipalInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockPrincipalInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockPrincipalInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *PrincipalInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("PrincipalInterfaceMock.DeleteNamespacedFunc: method is nil but PrincipalInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockPrincipalInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockPrincipalInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedPrincipalInterface.DeleteNamespacedCalls()) +func (mock *PrincipalInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockPrincipalInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockPrincipalInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *PrincipalInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Principal, error) { + if mock.GetFunc == nil { + panic("PrincipalInterfaceMock.GetFunc: method is nil but PrincipalInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockPrincipalInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockPrincipalInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedPrincipalInterface.GetCalls()) +func (mock *PrincipalInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockPrincipalInterfaceMockGet.RLock() + calls = mock.calls.Get + lockPrincipalInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *PrincipalInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Principal, error) { + if mock.GetNamespacedFunc == nil { + panic("PrincipalInterfaceMock.GetNamespacedFunc: method is nil but PrincipalInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockPrincipalInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockPrincipalInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedPrincipalInterface.GetNamespacedCalls()) +func (mock *PrincipalInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockPrincipalInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockPrincipalInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *PrincipalInterfaceMock) List(opts metav1.ListOptions) (*v3.PrincipalList, error) { + if mock.ListFunc == nil { + panic("PrincipalInterfaceMock.ListFunc: method is nil but PrincipalInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPrincipalInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockPrincipalInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedPrincipalInterface.ListCalls()) +func (mock *PrincipalInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPrincipalInterfaceMockList.RLock() + calls = mock.calls.List + lockPrincipalInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *PrincipalInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PrincipalList, error) { + if mock.ListNamespacedFunc == nil { + panic("PrincipalInterfaceMock.ListNamespacedFunc: method is nil but PrincipalInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockPrincipalInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockPrincipalInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedPrincipalInterface.ListNamespacedCalls()) +func (mock *PrincipalInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockPrincipalInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockPrincipalInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *PrincipalInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("PrincipalInterfaceMock.ObjectClientFunc: method is nil but PrincipalInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockPrincipalInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockPrincipalInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedPrincipalInterface.ObjectClientCalls()) +func (mock *PrincipalInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockPrincipalInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockPrincipalInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *PrincipalInterfaceMock) Update(in1 *v3.Principal) (*v3.Principal, error) { + if mock.UpdateFunc == nil { + panic("PrincipalInterfaceMock.UpdateFunc: method is nil but PrincipalInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Principal + }{ + In1: in1, + } + lockPrincipalInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockPrincipalInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedPrincipalInterface.UpdateCalls()) +func (mock *PrincipalInterfaceMock) UpdateCalls() []struct { + In1 *v3.Principal +} { + var calls []struct { + In1 *v3.Principal + } + lockPrincipalInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockPrincipalInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *PrincipalInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("PrincipalInterfaceMock.WatchFunc: method is nil but PrincipalInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockPrincipalInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockPrincipalInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedPrincipalInterface.WatchCalls()) +func (mock *PrincipalInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockPrincipalInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockPrincipalInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockPrincipalsGetterMockPrincipals sync.RWMutex +) + +// Ensure, that PrincipalsGetterMock does implement v31.PrincipalsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.PrincipalsGetter = &PrincipalsGetterMock{} + +// PrincipalsGetterMock is a mock implementation of v31.PrincipalsGetter. +// +// func TestSomethingThatUsesPrincipalsGetter(t *testing.T) { +// +// // make and configure a mocked v31.PrincipalsGetter +// mockedPrincipalsGetter := &PrincipalsGetterMock{ +// PrincipalsFunc: func(namespace string) v31.PrincipalInterface { +// panic("mock out the Principals method") +// }, +// } +// +// // use mockedPrincipalsGetter in code that requires v31.PrincipalsGetter +// // and then make assertions. +// +// } +type PrincipalsGetterMock struct { + // PrincipalsFunc mocks the Principals method. + PrincipalsFunc func(namespace string) v31.PrincipalInterface + + // calls tracks calls to the methods. + calls struct { + // Principals holds details about calls to the Principals method. + Principals []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Principals calls PrincipalsFunc. +func (mock *PrincipalsGetterMock) Principals(namespace string) v31.PrincipalInterface { + if mock.PrincipalsFunc == nil { + panic("PrincipalsGetterMock.PrincipalsFunc: method is nil but PrincipalsGetter.Principals was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockPrincipalsGetterMockPrincipals.Lock() + mock.calls.Principals = append(mock.calls.Principals, callInfo) + lockPrincipalsGetterMockPrincipals.Unlock() + return mock.PrincipalsFunc(namespace) +} + +// PrincipalsCalls gets all the calls that were made to Principals. +// Check the length with: +// +// len(mockedPrincipalsGetter.PrincipalsCalls()) +func (mock *PrincipalsGetterMock) PrincipalsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockPrincipalsGetterMockPrincipals.RLock() + calls = mock.calls.Principals + lockPrincipalsGetterMockPrincipals.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_catalog_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_catalog_mock.go new file mode 100644 index 0000000..a13bccd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_catalog_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockProjectCatalogListerMockGet sync.RWMutex + lockProjectCatalogListerMockList sync.RWMutex +) + +// Ensure, that ProjectCatalogListerMock does implement v31.ProjectCatalogLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectCatalogLister = &ProjectCatalogListerMock{} + +// ProjectCatalogListerMock is a mock implementation of v31.ProjectCatalogLister. +// +// func TestSomethingThatUsesProjectCatalogLister(t *testing.T) { +// +// // make and configure a mocked v31.ProjectCatalogLister +// mockedProjectCatalogLister := &ProjectCatalogListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ProjectCatalog, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ProjectCatalog, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedProjectCatalogLister in code that requires v31.ProjectCatalogLister +// // and then make assertions. +// +// } +type ProjectCatalogListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ProjectCatalog, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ProjectCatalog, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ProjectCatalogListerMock) Get(namespace string, name string) (*v3.ProjectCatalog, error) { + if mock.GetFunc == nil { + panic("ProjectCatalogListerMock.GetFunc: method is nil but ProjectCatalogLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectCatalogListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectCatalogListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectCatalogLister.GetCalls()) +func (mock *ProjectCatalogListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectCatalogListerMockGet.RLock() + calls = mock.calls.Get + lockProjectCatalogListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectCatalogListerMock) List(namespace string, selector labels.Selector) ([]*v3.ProjectCatalog, error) { + if mock.ListFunc == nil { + panic("ProjectCatalogListerMock.ListFunc: method is nil but ProjectCatalogLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockProjectCatalogListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectCatalogListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectCatalogLister.ListCalls()) +func (mock *ProjectCatalogListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockProjectCatalogListerMockList.RLock() + calls = mock.calls.List + lockProjectCatalogListerMockList.RUnlock() + return calls +} + +var ( + lockProjectCatalogControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectCatalogControllerMockAddClusterScopedHandler sync.RWMutex + lockProjectCatalogControllerMockAddFeatureHandler sync.RWMutex + lockProjectCatalogControllerMockAddHandler sync.RWMutex + lockProjectCatalogControllerMockEnqueue sync.RWMutex + lockProjectCatalogControllerMockEnqueueAfter sync.RWMutex + lockProjectCatalogControllerMockGeneric sync.RWMutex + lockProjectCatalogControllerMockInformer sync.RWMutex + lockProjectCatalogControllerMockLister sync.RWMutex +) + +// Ensure, that ProjectCatalogControllerMock does implement v31.ProjectCatalogController. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectCatalogController = &ProjectCatalogControllerMock{} + +// ProjectCatalogControllerMock is a mock implementation of v31.ProjectCatalogController. +// +// func TestSomethingThatUsesProjectCatalogController(t *testing.T) { +// +// // make and configure a mocked v31.ProjectCatalogController +// mockedProjectCatalogController := &ProjectCatalogControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ProjectCatalogLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedProjectCatalogController in code that requires v31.ProjectCatalogController +// // and then make assertions. +// +// } +type ProjectCatalogControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ProjectCatalogHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ProjectCatalogLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectCatalogHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectCatalogHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectCatalogHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ProjectCatalogHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectCatalogControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectCatalogControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectCatalogController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectCatalogControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectCatalogControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectCatalogController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectCatalogControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectCatalogControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectCatalogControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ProjectCatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectCatalogControllerMock.AddClusterScopedHandlerFunc: method is nil but ProjectCatalogController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectCatalogControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectCatalogControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectCatalogController.AddClusterScopedHandlerCalls()) +func (mock *ProjectCatalogControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectCatalogControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectCatalogControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectCatalogControllerMock.AddFeatureHandlerFunc: method is nil but ProjectCatalogController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectCatalogControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectCatalogControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectCatalogController.AddFeatureHandlerCalls()) +func (mock *ProjectCatalogControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectCatalogControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectCatalogControllerMock) AddHandler(ctx context.Context, name string, handler v31.ProjectCatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectCatalogControllerMock.AddHandlerFunc: method is nil but ProjectCatalogController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockProjectCatalogControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectCatalogControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectCatalogController.AddHandlerCalls()) +func (mock *ProjectCatalogControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectCatalogControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ProjectCatalogControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ProjectCatalogControllerMock.EnqueueFunc: method is nil but ProjectCatalogController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectCatalogControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockProjectCatalogControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedProjectCatalogController.EnqueueCalls()) +func (mock *ProjectCatalogControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectCatalogControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockProjectCatalogControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ProjectCatalogControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ProjectCatalogControllerMock.EnqueueAfterFunc: method is nil but ProjectCatalogController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockProjectCatalogControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockProjectCatalogControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedProjectCatalogController.EnqueueAfterCalls()) +func (mock *ProjectCatalogControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockProjectCatalogControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockProjectCatalogControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ProjectCatalogControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ProjectCatalogControllerMock.GenericFunc: method is nil but ProjectCatalogController.Generic was just called") + } + callInfo := struct { + }{} + lockProjectCatalogControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockProjectCatalogControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedProjectCatalogController.GenericCalls()) +func (mock *ProjectCatalogControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockProjectCatalogControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockProjectCatalogControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ProjectCatalogControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ProjectCatalogControllerMock.InformerFunc: method is nil but ProjectCatalogController.Informer was just called") + } + callInfo := struct { + }{} + lockProjectCatalogControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockProjectCatalogControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedProjectCatalogController.InformerCalls()) +func (mock *ProjectCatalogControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockProjectCatalogControllerMockInformer.RLock() + calls = mock.calls.Informer + lockProjectCatalogControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ProjectCatalogControllerMock) Lister() v31.ProjectCatalogLister { + if mock.ListerFunc == nil { + panic("ProjectCatalogControllerMock.ListerFunc: method is nil but ProjectCatalogController.Lister was just called") + } + callInfo := struct { + }{} + lockProjectCatalogControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockProjectCatalogControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedProjectCatalogController.ListerCalls()) +func (mock *ProjectCatalogControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockProjectCatalogControllerMockLister.RLock() + calls = mock.calls.Lister + lockProjectCatalogControllerMockLister.RUnlock() + return calls +} + +var ( + lockProjectCatalogInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectCatalogInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockProjectCatalogInterfaceMockAddClusterScopedHandler sync.RWMutex + lockProjectCatalogInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockProjectCatalogInterfaceMockAddFeatureHandler sync.RWMutex + lockProjectCatalogInterfaceMockAddFeatureLifecycle sync.RWMutex + lockProjectCatalogInterfaceMockAddHandler sync.RWMutex + lockProjectCatalogInterfaceMockAddLifecycle sync.RWMutex + lockProjectCatalogInterfaceMockController sync.RWMutex + lockProjectCatalogInterfaceMockCreate sync.RWMutex + lockProjectCatalogInterfaceMockDelete sync.RWMutex + lockProjectCatalogInterfaceMockDeleteCollection sync.RWMutex + lockProjectCatalogInterfaceMockDeleteNamespaced sync.RWMutex + lockProjectCatalogInterfaceMockGet sync.RWMutex + lockProjectCatalogInterfaceMockGetNamespaced sync.RWMutex + lockProjectCatalogInterfaceMockList sync.RWMutex + lockProjectCatalogInterfaceMockListNamespaced sync.RWMutex + lockProjectCatalogInterfaceMockObjectClient sync.RWMutex + lockProjectCatalogInterfaceMockUpdate sync.RWMutex + lockProjectCatalogInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ProjectCatalogInterfaceMock does implement v31.ProjectCatalogInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectCatalogInterface = &ProjectCatalogInterfaceMock{} + +// ProjectCatalogInterfaceMock is a mock implementation of v31.ProjectCatalogInterface. +// +// func TestSomethingThatUsesProjectCatalogInterface(t *testing.T) { +// +// // make and configure a mocked v31.ProjectCatalogInterface +// mockedProjectCatalogInterface := &ProjectCatalogInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectCatalogLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ProjectCatalogLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ProjectCatalogController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedProjectCatalogInterface in code that requires v31.ProjectCatalogInterface +// // and then make assertions. +// +// } +type ProjectCatalogInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectCatalogLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ProjectCatalogLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ProjectCatalogController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ProjectCatalogList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ProjectCatalogList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectCatalogHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectCatalogLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectCatalogHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectCatalogLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectCatalogHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectCatalogLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectCatalogHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectCatalogLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectCatalog + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectCatalog + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectCatalogInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectCatalogInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectCatalogInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectCatalogInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectCatalogInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ProjectCatalogInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ProjectCatalogInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockProjectCatalogInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle + } + lockProjectCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockProjectCatalogInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectCatalogHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectCatalogInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ProjectCatalogInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectCatalogInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectCatalogInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddClusterScopedHandlerCalls()) +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectCatalogInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectCatalogLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ProjectCatalogInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ProjectCatalogInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectCatalogInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockProjectCatalogInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddClusterScopedLifecycleCalls()) +func (mock *ProjectCatalogInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectCatalogLifecycle + } + lockProjectCatalogInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockProjectCatalogInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectCatalogInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectCatalogInterfaceMock.AddFeatureHandlerFunc: method is nil but ProjectCatalogInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectCatalogInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectCatalogInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddFeatureHandlerCalls()) +func (mock *ProjectCatalogInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectCatalogInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ProjectCatalogInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectCatalogLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ProjectCatalogInterfaceMock.AddFeatureLifecycleFunc: method is nil but ProjectCatalogInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectCatalogLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockProjectCatalogInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockProjectCatalogInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddFeatureLifecycleCalls()) +func (mock *ProjectCatalogInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectCatalogLifecycle + } + lockProjectCatalogInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockProjectCatalogInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectCatalogInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ProjectCatalogHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectCatalogInterfaceMock.AddHandlerFunc: method is nil but ProjectCatalogInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ProjectCatalogHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockProjectCatalogInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectCatalogInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddHandlerCalls()) +func (mock *ProjectCatalogInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ProjectCatalogHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ProjectCatalogHandlerFunc + } + lockProjectCatalogInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectCatalogInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ProjectCatalogInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ProjectCatalogLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ProjectCatalogInterfaceMock.AddLifecycleFunc: method is nil but ProjectCatalogInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectCatalogLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockProjectCatalogInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockProjectCatalogInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedProjectCatalogInterface.AddLifecycleCalls()) +func (mock *ProjectCatalogInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectCatalogLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectCatalogLifecycle + } + lockProjectCatalogInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockProjectCatalogInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ProjectCatalogInterfaceMock) Controller() v31.ProjectCatalogController { + if mock.ControllerFunc == nil { + panic("ProjectCatalogInterfaceMock.ControllerFunc: method is nil but ProjectCatalogInterface.Controller was just called") + } + callInfo := struct { + }{} + lockProjectCatalogInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockProjectCatalogInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedProjectCatalogInterface.ControllerCalls()) +func (mock *ProjectCatalogInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockProjectCatalogInterfaceMockController.RLock() + calls = mock.calls.Controller + lockProjectCatalogInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ProjectCatalogInterfaceMock) Create(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { + if mock.CreateFunc == nil { + panic("ProjectCatalogInterfaceMock.CreateFunc: method is nil but ProjectCatalogInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ProjectCatalog + }{ + In1: in1, + } + lockProjectCatalogInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockProjectCatalogInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedProjectCatalogInterface.CreateCalls()) +func (mock *ProjectCatalogInterfaceMock) CreateCalls() []struct { + In1 *v3.ProjectCatalog +} { + var calls []struct { + In1 *v3.ProjectCatalog + } + lockProjectCatalogInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockProjectCatalogInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ProjectCatalogInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ProjectCatalogInterfaceMock.DeleteFunc: method is nil but ProjectCatalogInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockProjectCatalogInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockProjectCatalogInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedProjectCatalogInterface.DeleteCalls()) +func (mock *ProjectCatalogInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockProjectCatalogInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockProjectCatalogInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ProjectCatalogInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ProjectCatalogInterfaceMock.DeleteCollectionFunc: method is nil but ProjectCatalogInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockProjectCatalogInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockProjectCatalogInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedProjectCatalogInterface.DeleteCollectionCalls()) +func (mock *ProjectCatalogInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockProjectCatalogInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockProjectCatalogInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ProjectCatalogInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ProjectCatalogInterfaceMock.DeleteNamespacedFunc: method is nil but ProjectCatalogInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockProjectCatalogInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockProjectCatalogInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedProjectCatalogInterface.DeleteNamespacedCalls()) +func (mock *ProjectCatalogInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockProjectCatalogInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockProjectCatalogInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ProjectCatalogInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { + if mock.GetFunc == nil { + panic("ProjectCatalogInterfaceMock.GetFunc: method is nil but ProjectCatalogInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockProjectCatalogInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectCatalogInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectCatalogInterface.GetCalls()) +func (mock *ProjectCatalogInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockProjectCatalogInterfaceMockGet.RLock() + calls = mock.calls.Get + lockProjectCatalogInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ProjectCatalogInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { + if mock.GetNamespacedFunc == nil { + panic("ProjectCatalogInterfaceMock.GetNamespacedFunc: method is nil but ProjectCatalogInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockProjectCatalogInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockProjectCatalogInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedProjectCatalogInterface.GetNamespacedCalls()) +func (mock *ProjectCatalogInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockProjectCatalogInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockProjectCatalogInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectCatalogInterfaceMock) List(opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { + if mock.ListFunc == nil { + panic("ProjectCatalogInterfaceMock.ListFunc: method is nil but ProjectCatalogInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectCatalogInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectCatalogInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectCatalogInterface.ListCalls()) +func (mock *ProjectCatalogInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectCatalogInterfaceMockList.RLock() + calls = mock.calls.List + lockProjectCatalogInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ProjectCatalogInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { + if mock.ListNamespacedFunc == nil { + panic("ProjectCatalogInterfaceMock.ListNamespacedFunc: method is nil but ProjectCatalogInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockProjectCatalogInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockProjectCatalogInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedProjectCatalogInterface.ListNamespacedCalls()) +func (mock *ProjectCatalogInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockProjectCatalogInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockProjectCatalogInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ProjectCatalogInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ProjectCatalogInterfaceMock.ObjectClientFunc: method is nil but ProjectCatalogInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockProjectCatalogInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockProjectCatalogInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedProjectCatalogInterface.ObjectClientCalls()) +func (mock *ProjectCatalogInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockProjectCatalogInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockProjectCatalogInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ProjectCatalogInterfaceMock) Update(in1 *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { + if mock.UpdateFunc == nil { + panic("ProjectCatalogInterfaceMock.UpdateFunc: method is nil but ProjectCatalogInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ProjectCatalog + }{ + In1: in1, + } + lockProjectCatalogInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockProjectCatalogInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedProjectCatalogInterface.UpdateCalls()) +func (mock *ProjectCatalogInterfaceMock) UpdateCalls() []struct { + In1 *v3.ProjectCatalog +} { + var calls []struct { + In1 *v3.ProjectCatalog + } + lockProjectCatalogInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockProjectCatalogInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ProjectCatalogInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ProjectCatalogInterfaceMock.WatchFunc: method is nil but ProjectCatalogInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectCatalogInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockProjectCatalogInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedProjectCatalogInterface.WatchCalls()) +func (mock *ProjectCatalogInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectCatalogInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockProjectCatalogInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockProjectCatalogsGetterMockProjectCatalogs sync.RWMutex +) + +// Ensure, that ProjectCatalogsGetterMock does implement v31.ProjectCatalogsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectCatalogsGetter = &ProjectCatalogsGetterMock{} + +// ProjectCatalogsGetterMock is a mock implementation of v31.ProjectCatalogsGetter. +// +// func TestSomethingThatUsesProjectCatalogsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ProjectCatalogsGetter +// mockedProjectCatalogsGetter := &ProjectCatalogsGetterMock{ +// ProjectCatalogsFunc: func(namespace string) v31.ProjectCatalogInterface { +// panic("mock out the ProjectCatalogs method") +// }, +// } +// +// // use mockedProjectCatalogsGetter in code that requires v31.ProjectCatalogsGetter +// // and then make assertions. +// +// } +type ProjectCatalogsGetterMock struct { + // ProjectCatalogsFunc mocks the ProjectCatalogs method. + ProjectCatalogsFunc func(namespace string) v31.ProjectCatalogInterface + + // calls tracks calls to the methods. + calls struct { + // ProjectCatalogs holds details about calls to the ProjectCatalogs method. + ProjectCatalogs []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ProjectCatalogs calls ProjectCatalogsFunc. +func (mock *ProjectCatalogsGetterMock) ProjectCatalogs(namespace string) v31.ProjectCatalogInterface { + if mock.ProjectCatalogsFunc == nil { + panic("ProjectCatalogsGetterMock.ProjectCatalogsFunc: method is nil but ProjectCatalogsGetter.ProjectCatalogs was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockProjectCatalogsGetterMockProjectCatalogs.Lock() + mock.calls.ProjectCatalogs = append(mock.calls.ProjectCatalogs, callInfo) + lockProjectCatalogsGetterMockProjectCatalogs.Unlock() + return mock.ProjectCatalogsFunc(namespace) +} + +// ProjectCatalogsCalls gets all the calls that were made to ProjectCatalogs. +// Check the length with: +// +// len(mockedProjectCatalogsGetter.ProjectCatalogsCalls()) +func (mock *ProjectCatalogsGetterMock) ProjectCatalogsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockProjectCatalogsGetterMockProjectCatalogs.RLock() + calls = mock.calls.ProjectCatalogs + lockProjectCatalogsGetterMockProjectCatalogs.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_mock.go new file mode 100644 index 0000000..c3a3c91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockProjectListerMockGet sync.RWMutex + lockProjectListerMockList sync.RWMutex +) + +// Ensure, that ProjectListerMock does implement v31.ProjectLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectLister = &ProjectListerMock{} + +// ProjectListerMock is a mock implementation of v31.ProjectLister. +// +// func TestSomethingThatUsesProjectLister(t *testing.T) { +// +// // make and configure a mocked v31.ProjectLister +// mockedProjectLister := &ProjectListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Project, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Project, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedProjectLister in code that requires v31.ProjectLister +// // and then make assertions. +// +// } +type ProjectListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Project, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Project, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ProjectListerMock) Get(namespace string, name string) (*v3.Project, error) { + if mock.GetFunc == nil { + panic("ProjectListerMock.GetFunc: method is nil but ProjectLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectLister.GetCalls()) +func (mock *ProjectListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectListerMockGet.RLock() + calls = mock.calls.Get + lockProjectListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectListerMock) List(namespace string, selector labels.Selector) ([]*v3.Project, error) { + if mock.ListFunc == nil { + panic("ProjectListerMock.ListFunc: method is nil but ProjectLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockProjectListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectLister.ListCalls()) +func (mock *ProjectListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockProjectListerMockList.RLock() + calls = mock.calls.List + lockProjectListerMockList.RUnlock() + return calls +} + +var ( + lockProjectControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectControllerMockAddClusterScopedHandler sync.RWMutex + lockProjectControllerMockAddFeatureHandler sync.RWMutex + lockProjectControllerMockAddHandler sync.RWMutex + lockProjectControllerMockEnqueue sync.RWMutex + lockProjectControllerMockEnqueueAfter sync.RWMutex + lockProjectControllerMockGeneric sync.RWMutex + lockProjectControllerMockInformer sync.RWMutex + lockProjectControllerMockLister sync.RWMutex +) + +// Ensure, that ProjectControllerMock does implement v31.ProjectController. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectController = &ProjectControllerMock{} + +// ProjectControllerMock is a mock implementation of v31.ProjectController. +// +// func TestSomethingThatUsesProjectController(t *testing.T) { +// +// // make and configure a mocked v31.ProjectController +// mockedProjectController := &ProjectControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ProjectHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ProjectHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ProjectLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedProjectController in code that requires v31.ProjectController +// // and then make assertions. +// +// } +type ProjectControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ProjectHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ProjectHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ProjectLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ProjectHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectHandlerFunc + } + lockProjectControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ProjectHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectControllerMock.AddClusterScopedHandlerFunc: method is nil but ProjectController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectController.AddClusterScopedHandlerCalls()) +func (mock *ProjectControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectHandlerFunc + } + lockProjectControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectControllerMock.AddFeatureHandlerFunc: method is nil but ProjectController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectController.AddFeatureHandlerCalls()) +func (mock *ProjectControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc + } + lockProjectControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectControllerMock) AddHandler(ctx context.Context, name string, handler v31.ProjectHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectControllerMock.AddHandlerFunc: method is nil but ProjectController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockProjectControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectController.AddHandlerCalls()) +func (mock *ProjectControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ProjectHandlerFunc + } + lockProjectControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ProjectControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ProjectControllerMock.EnqueueFunc: method is nil but ProjectController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockProjectControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedProjectController.EnqueueCalls()) +func (mock *ProjectControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockProjectControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ProjectControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ProjectControllerMock.EnqueueAfterFunc: method is nil but ProjectController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockProjectControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockProjectControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedProjectController.EnqueueAfterCalls()) +func (mock *ProjectControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockProjectControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockProjectControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ProjectControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ProjectControllerMock.GenericFunc: method is nil but ProjectController.Generic was just called") + } + callInfo := struct { + }{} + lockProjectControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockProjectControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedProjectController.GenericCalls()) +func (mock *ProjectControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockProjectControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockProjectControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ProjectControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ProjectControllerMock.InformerFunc: method is nil but ProjectController.Informer was just called") + } + callInfo := struct { + }{} + lockProjectControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockProjectControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedProjectController.InformerCalls()) +func (mock *ProjectControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockProjectControllerMockInformer.RLock() + calls = mock.calls.Informer + lockProjectControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ProjectControllerMock) Lister() v31.ProjectLister { + if mock.ListerFunc == nil { + panic("ProjectControllerMock.ListerFunc: method is nil but ProjectController.Lister was just called") + } + callInfo := struct { + }{} + lockProjectControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockProjectControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedProjectController.ListerCalls()) +func (mock *ProjectControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockProjectControllerMockLister.RLock() + calls = mock.calls.Lister + lockProjectControllerMockLister.RUnlock() + return calls +} + +var ( + lockProjectInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockProjectInterfaceMockAddClusterScopedHandler sync.RWMutex + lockProjectInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockProjectInterfaceMockAddFeatureHandler sync.RWMutex + lockProjectInterfaceMockAddFeatureLifecycle sync.RWMutex + lockProjectInterfaceMockAddHandler sync.RWMutex + lockProjectInterfaceMockAddLifecycle sync.RWMutex + lockProjectInterfaceMockController sync.RWMutex + lockProjectInterfaceMockCreate sync.RWMutex + lockProjectInterfaceMockDelete sync.RWMutex + lockProjectInterfaceMockDeleteCollection sync.RWMutex + lockProjectInterfaceMockDeleteNamespaced sync.RWMutex + lockProjectInterfaceMockGet sync.RWMutex + lockProjectInterfaceMockGetNamespaced sync.RWMutex + lockProjectInterfaceMockList sync.RWMutex + lockProjectInterfaceMockListNamespaced sync.RWMutex + lockProjectInterfaceMockObjectClient sync.RWMutex + lockProjectInterfaceMockUpdate sync.RWMutex + lockProjectInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ProjectInterfaceMock does implement v31.ProjectInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectInterface = &ProjectInterfaceMock{} + +// ProjectInterfaceMock is a mock implementation of v31.ProjectInterface. +// +// func TestSomethingThatUsesProjectInterface(t *testing.T) { +// +// // make and configure a mocked v31.ProjectInterface +// mockedProjectInterface := &ProjectInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ProjectHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ProjectLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ProjectController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Project) (*v3.Project, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Project, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Project, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ProjectList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ProjectList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Project) (*v3.Project, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedProjectInterface in code that requires v31.ProjectInterface +// // and then make assertions. +// +// } +type ProjectInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ProjectHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ProjectLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ProjectController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Project) (*v3.Project, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Project, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Project, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ProjectList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ProjectList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Project) (*v3.Project, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Project + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Project + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectHandlerFunc + } + lockProjectInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ProjectInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ProjectInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ProjectInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockProjectInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ProjectInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle + } + lockProjectInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockProjectInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ProjectInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectInterface.AddClusterScopedHandlerCalls()) +func (mock *ProjectInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectHandlerFunc + } + lockProjectInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ProjectInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ProjectInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ProjectInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockProjectInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedProjectInterface.AddClusterScopedLifecycleCalls()) +func (mock *ProjectInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectLifecycle + } + lockProjectInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockProjectInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectInterfaceMock.AddFeatureHandlerFunc: method is nil but ProjectInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectInterface.AddFeatureHandlerCalls()) +func (mock *ProjectInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectHandlerFunc + } + lockProjectInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ProjectInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ProjectInterfaceMock.AddFeatureLifecycleFunc: method is nil but ProjectInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockProjectInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockProjectInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectInterface.AddFeatureLifecycleCalls()) +func (mock *ProjectInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectLifecycle + } + lockProjectInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockProjectInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ProjectHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectInterfaceMock.AddHandlerFunc: method is nil but ProjectInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ProjectHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockProjectInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectInterface.AddHandlerCalls()) +func (mock *ProjectInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ProjectHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ProjectHandlerFunc + } + lockProjectInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ProjectInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ProjectLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ProjectInterfaceMock.AddLifecycleFunc: method is nil but ProjectInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockProjectInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockProjectInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedProjectInterface.AddLifecycleCalls()) +func (mock *ProjectInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectLifecycle + } + lockProjectInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockProjectInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ProjectInterfaceMock) Controller() v31.ProjectController { + if mock.ControllerFunc == nil { + panic("ProjectInterfaceMock.ControllerFunc: method is nil but ProjectInterface.Controller was just called") + } + callInfo := struct { + }{} + lockProjectInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockProjectInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedProjectInterface.ControllerCalls()) +func (mock *ProjectInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockProjectInterfaceMockController.RLock() + calls = mock.calls.Controller + lockProjectInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ProjectInterfaceMock) Create(in1 *v3.Project) (*v3.Project, error) { + if mock.CreateFunc == nil { + panic("ProjectInterfaceMock.CreateFunc: method is nil but ProjectInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Project + }{ + In1: in1, + } + lockProjectInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockProjectInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedProjectInterface.CreateCalls()) +func (mock *ProjectInterfaceMock) CreateCalls() []struct { + In1 *v3.Project +} { + var calls []struct { + In1 *v3.Project + } + lockProjectInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockProjectInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ProjectInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ProjectInterfaceMock.DeleteFunc: method is nil but ProjectInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockProjectInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockProjectInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedProjectInterface.DeleteCalls()) +func (mock *ProjectInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockProjectInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockProjectInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ProjectInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ProjectInterfaceMock.DeleteCollectionFunc: method is nil but ProjectInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockProjectInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockProjectInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedProjectInterface.DeleteCollectionCalls()) +func (mock *ProjectInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockProjectInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockProjectInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ProjectInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ProjectInterfaceMock.DeleteNamespacedFunc: method is nil but ProjectInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockProjectInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockProjectInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedProjectInterface.DeleteNamespacedCalls()) +func (mock *ProjectInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockProjectInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockProjectInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ProjectInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Project, error) { + if mock.GetFunc == nil { + panic("ProjectInterfaceMock.GetFunc: method is nil but ProjectInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockProjectInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectInterface.GetCalls()) +func (mock *ProjectInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockProjectInterfaceMockGet.RLock() + calls = mock.calls.Get + lockProjectInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ProjectInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Project, error) { + if mock.GetNamespacedFunc == nil { + panic("ProjectInterfaceMock.GetNamespacedFunc: method is nil but ProjectInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockProjectInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockProjectInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedProjectInterface.GetNamespacedCalls()) +func (mock *ProjectInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockProjectInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockProjectInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectInterfaceMock) List(opts metav1.ListOptions) (*v3.ProjectList, error) { + if mock.ListFunc == nil { + panic("ProjectInterfaceMock.ListFunc: method is nil but ProjectInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectInterface.ListCalls()) +func (mock *ProjectInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectInterfaceMockList.RLock() + calls = mock.calls.List + lockProjectInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ProjectInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectList, error) { + if mock.ListNamespacedFunc == nil { + panic("ProjectInterfaceMock.ListNamespacedFunc: method is nil but ProjectInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockProjectInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockProjectInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedProjectInterface.ListNamespacedCalls()) +func (mock *ProjectInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockProjectInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockProjectInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ProjectInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ProjectInterfaceMock.ObjectClientFunc: method is nil but ProjectInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockProjectInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockProjectInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedProjectInterface.ObjectClientCalls()) +func (mock *ProjectInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockProjectInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockProjectInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ProjectInterfaceMock) Update(in1 *v3.Project) (*v3.Project, error) { + if mock.UpdateFunc == nil { + panic("ProjectInterfaceMock.UpdateFunc: method is nil but ProjectInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Project + }{ + In1: in1, + } + lockProjectInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockProjectInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedProjectInterface.UpdateCalls()) +func (mock *ProjectInterfaceMock) UpdateCalls() []struct { + In1 *v3.Project +} { + var calls []struct { + In1 *v3.Project + } + lockProjectInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockProjectInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ProjectInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ProjectInterfaceMock.WatchFunc: method is nil but ProjectInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockProjectInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedProjectInterface.WatchCalls()) +func (mock *ProjectInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockProjectInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockProjectsGetterMockProjects sync.RWMutex +) + +// Ensure, that ProjectsGetterMock does implement v31.ProjectsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectsGetter = &ProjectsGetterMock{} + +// ProjectsGetterMock is a mock implementation of v31.ProjectsGetter. +// +// func TestSomethingThatUsesProjectsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ProjectsGetter +// mockedProjectsGetter := &ProjectsGetterMock{ +// ProjectsFunc: func(namespace string) v31.ProjectInterface { +// panic("mock out the Projects method") +// }, +// } +// +// // use mockedProjectsGetter in code that requires v31.ProjectsGetter +// // and then make assertions. +// +// } +type ProjectsGetterMock struct { + // ProjectsFunc mocks the Projects method. + ProjectsFunc func(namespace string) v31.ProjectInterface + + // calls tracks calls to the methods. + calls struct { + // Projects holds details about calls to the Projects method. + Projects []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Projects calls ProjectsFunc. +func (mock *ProjectsGetterMock) Projects(namespace string) v31.ProjectInterface { + if mock.ProjectsFunc == nil { + panic("ProjectsGetterMock.ProjectsFunc: method is nil but ProjectsGetter.Projects was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockProjectsGetterMockProjects.Lock() + mock.calls.Projects = append(mock.calls.Projects, callInfo) + lockProjectsGetterMockProjects.Unlock() + return mock.ProjectsFunc(namespace) +} + +// ProjectsCalls gets all the calls that were made to Projects. +// Check the length with: +// +// len(mockedProjectsGetter.ProjectsCalls()) +func (mock *ProjectsGetterMock) ProjectsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockProjectsGetterMockProjects.RLock() + calls = mock.calls.Projects + lockProjectsGetterMockProjects.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_network_policy_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_network_policy_mock.go new file mode 100644 index 0000000..26371ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_network_policy_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockProjectNetworkPolicyListerMockGet sync.RWMutex + lockProjectNetworkPolicyListerMockList sync.RWMutex +) + +// Ensure, that ProjectNetworkPolicyListerMock does implement v31.ProjectNetworkPolicyLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectNetworkPolicyLister = &ProjectNetworkPolicyListerMock{} + +// ProjectNetworkPolicyListerMock is a mock implementation of v31.ProjectNetworkPolicyLister. +// +// func TestSomethingThatUsesProjectNetworkPolicyLister(t *testing.T) { +// +// // make and configure a mocked v31.ProjectNetworkPolicyLister +// mockedProjectNetworkPolicyLister := &ProjectNetworkPolicyListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ProjectNetworkPolicy, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ProjectNetworkPolicy, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedProjectNetworkPolicyLister in code that requires v31.ProjectNetworkPolicyLister +// // and then make assertions. +// +// } +type ProjectNetworkPolicyListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ProjectNetworkPolicy, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ProjectNetworkPolicy, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ProjectNetworkPolicyListerMock) Get(namespace string, name string) (*v3.ProjectNetworkPolicy, error) { + if mock.GetFunc == nil { + panic("ProjectNetworkPolicyListerMock.GetFunc: method is nil but ProjectNetworkPolicyLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectNetworkPolicyListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectNetworkPolicyListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectNetworkPolicyLister.GetCalls()) +func (mock *ProjectNetworkPolicyListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectNetworkPolicyListerMockGet.RLock() + calls = mock.calls.Get + lockProjectNetworkPolicyListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectNetworkPolicyListerMock) List(namespace string, selector labels.Selector) ([]*v3.ProjectNetworkPolicy, error) { + if mock.ListFunc == nil { + panic("ProjectNetworkPolicyListerMock.ListFunc: method is nil but ProjectNetworkPolicyLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockProjectNetworkPolicyListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectNetworkPolicyListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectNetworkPolicyLister.ListCalls()) +func (mock *ProjectNetworkPolicyListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockProjectNetworkPolicyListerMockList.RLock() + calls = mock.calls.List + lockProjectNetworkPolicyListerMockList.RUnlock() + return calls +} + +var ( + lockProjectNetworkPolicyControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectNetworkPolicyControllerMockAddClusterScopedHandler sync.RWMutex + lockProjectNetworkPolicyControllerMockAddFeatureHandler sync.RWMutex + lockProjectNetworkPolicyControllerMockAddHandler sync.RWMutex + lockProjectNetworkPolicyControllerMockEnqueue sync.RWMutex + lockProjectNetworkPolicyControllerMockEnqueueAfter sync.RWMutex + lockProjectNetworkPolicyControllerMockGeneric sync.RWMutex + lockProjectNetworkPolicyControllerMockInformer sync.RWMutex + lockProjectNetworkPolicyControllerMockLister sync.RWMutex +) + +// Ensure, that ProjectNetworkPolicyControllerMock does implement v31.ProjectNetworkPolicyController. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectNetworkPolicyController = &ProjectNetworkPolicyControllerMock{} + +// ProjectNetworkPolicyControllerMock is a mock implementation of v31.ProjectNetworkPolicyController. +// +// func TestSomethingThatUsesProjectNetworkPolicyController(t *testing.T) { +// +// // make and configure a mocked v31.ProjectNetworkPolicyController +// mockedProjectNetworkPolicyController := &ProjectNetworkPolicyControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ProjectNetworkPolicyLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedProjectNetworkPolicyController in code that requires v31.ProjectNetworkPolicyController +// // and then make assertions. +// +// } +type ProjectNetworkPolicyControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ProjectNetworkPolicyHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ProjectNetworkPolicyLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectNetworkPolicyHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectNetworkPolicyHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectNetworkPolicyHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ProjectNetworkPolicyHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectNetworkPolicyControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectNetworkPolicyController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectNetworkPolicyControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectNetworkPolicyControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectNetworkPolicyControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectNetworkPolicyControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.AddClusterScopedHandlerFunc: method is nil but ProjectNetworkPolicyController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectNetworkPolicyControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectNetworkPolicyControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.AddClusterScopedHandlerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectNetworkPolicyControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectNetworkPolicyControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.AddFeatureHandlerFunc: method is nil but ProjectNetworkPolicyController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectNetworkPolicyControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectNetworkPolicyControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.AddFeatureHandlerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectNetworkPolicyControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectNetworkPolicyControllerMock) AddHandler(ctx context.Context, name string, handler v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.AddHandlerFunc: method is nil but ProjectNetworkPolicyController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockProjectNetworkPolicyControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectNetworkPolicyControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.AddHandlerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectNetworkPolicyControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ProjectNetworkPolicyControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ProjectNetworkPolicyControllerMock.EnqueueFunc: method is nil but ProjectNetworkPolicyController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectNetworkPolicyControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockProjectNetworkPolicyControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.EnqueueCalls()) +func (mock *ProjectNetworkPolicyControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectNetworkPolicyControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockProjectNetworkPolicyControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ProjectNetworkPolicyControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ProjectNetworkPolicyControllerMock.EnqueueAfterFunc: method is nil but ProjectNetworkPolicyController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockProjectNetworkPolicyControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockProjectNetworkPolicyControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.EnqueueAfterCalls()) +func (mock *ProjectNetworkPolicyControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockProjectNetworkPolicyControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockProjectNetworkPolicyControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ProjectNetworkPolicyControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ProjectNetworkPolicyControllerMock.GenericFunc: method is nil but ProjectNetworkPolicyController.Generic was just called") + } + callInfo := struct { + }{} + lockProjectNetworkPolicyControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockProjectNetworkPolicyControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.GenericCalls()) +func (mock *ProjectNetworkPolicyControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockProjectNetworkPolicyControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockProjectNetworkPolicyControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ProjectNetworkPolicyControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.InformerFunc: method is nil but ProjectNetworkPolicyController.Informer was just called") + } + callInfo := struct { + }{} + lockProjectNetworkPolicyControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockProjectNetworkPolicyControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.InformerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockProjectNetworkPolicyControllerMockInformer.RLock() + calls = mock.calls.Informer + lockProjectNetworkPolicyControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ProjectNetworkPolicyControllerMock) Lister() v31.ProjectNetworkPolicyLister { + if mock.ListerFunc == nil { + panic("ProjectNetworkPolicyControllerMock.ListerFunc: method is nil but ProjectNetworkPolicyController.Lister was just called") + } + callInfo := struct { + }{} + lockProjectNetworkPolicyControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockProjectNetworkPolicyControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedProjectNetworkPolicyController.ListerCalls()) +func (mock *ProjectNetworkPolicyControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockProjectNetworkPolicyControllerMockLister.RLock() + calls = mock.calls.Lister + lockProjectNetworkPolicyControllerMockLister.RUnlock() + return calls +} + +var ( + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddClusterScopedHandler sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddFeatureHandler sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddFeatureLifecycle sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddHandler sync.RWMutex + lockProjectNetworkPolicyInterfaceMockAddLifecycle sync.RWMutex + lockProjectNetworkPolicyInterfaceMockController sync.RWMutex + lockProjectNetworkPolicyInterfaceMockCreate sync.RWMutex + lockProjectNetworkPolicyInterfaceMockDelete sync.RWMutex + lockProjectNetworkPolicyInterfaceMockDeleteCollection sync.RWMutex + lockProjectNetworkPolicyInterfaceMockDeleteNamespaced sync.RWMutex + lockProjectNetworkPolicyInterfaceMockGet sync.RWMutex + lockProjectNetworkPolicyInterfaceMockGetNamespaced sync.RWMutex + lockProjectNetworkPolicyInterfaceMockList sync.RWMutex + lockProjectNetworkPolicyInterfaceMockListNamespaced sync.RWMutex + lockProjectNetworkPolicyInterfaceMockObjectClient sync.RWMutex + lockProjectNetworkPolicyInterfaceMockUpdate sync.RWMutex + lockProjectNetworkPolicyInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ProjectNetworkPolicyInterfaceMock does implement v31.ProjectNetworkPolicyInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectNetworkPolicyInterface = &ProjectNetworkPolicyInterfaceMock{} + +// ProjectNetworkPolicyInterfaceMock is a mock implementation of v31.ProjectNetworkPolicyInterface. +// +// func TestSomethingThatUsesProjectNetworkPolicyInterface(t *testing.T) { +// +// // make and configure a mocked v31.ProjectNetworkPolicyInterface +// mockedProjectNetworkPolicyInterface := &ProjectNetworkPolicyInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ProjectNetworkPolicyController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedProjectNetworkPolicyInterface in code that requires v31.ProjectNetworkPolicyInterface +// // and then make assertions. +// +// } +type ProjectNetworkPolicyInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ProjectNetworkPolicyController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectNetworkPolicyHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectNetworkPolicyHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectNetworkPolicyHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectNetworkPolicyHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectNetworkPolicy + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectNetworkPolicy + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectNetworkPolicyInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ProjectNetworkPolicyInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockProjectNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ProjectNetworkPolicyInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectNetworkPolicyInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddClusterScopedHandlerCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectNetworkPolicyInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectNetworkPolicyLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ProjectNetworkPolicyInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockProjectNetworkPolicyInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddClusterScopedLifecycleCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + lockProjectNetworkPolicyInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockProjectNetworkPolicyInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddFeatureHandlerFunc: method is nil but ProjectNetworkPolicyInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectNetworkPolicyInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectNetworkPolicyInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddFeatureHandlerCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectNetworkPolicyInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddFeatureLifecycleFunc: method is nil but ProjectNetworkPolicyInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockProjectNetworkPolicyInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockProjectNetworkPolicyInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddFeatureLifecycleCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + lockProjectNetworkPolicyInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockProjectNetworkPolicyInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ProjectNetworkPolicyHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddHandlerFunc: method is nil but ProjectNetworkPolicyInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockProjectNetworkPolicyInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectNetworkPolicyInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddHandlerCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ProjectNetworkPolicyHandlerFunc + } + lockProjectNetworkPolicyInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectNetworkPolicyInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ProjectNetworkPolicyLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.AddLifecycleFunc: method is nil but ProjectNetworkPolicyInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockProjectNetworkPolicyInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockProjectNetworkPolicyInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.AddLifecycleCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectNetworkPolicyLifecycle + } + lockProjectNetworkPolicyInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockProjectNetworkPolicyInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Controller() v31.ProjectNetworkPolicyController { + if mock.ControllerFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.ControllerFunc: method is nil but ProjectNetworkPolicyInterface.Controller was just called") + } + callInfo := struct { + }{} + lockProjectNetworkPolicyInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockProjectNetworkPolicyInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.ControllerCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockProjectNetworkPolicyInterfaceMockController.RLock() + calls = mock.calls.Controller + lockProjectNetworkPolicyInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Create(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { + if mock.CreateFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.CreateFunc: method is nil but ProjectNetworkPolicyInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ProjectNetworkPolicy + }{ + In1: in1, + } + lockProjectNetworkPolicyInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockProjectNetworkPolicyInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.CreateCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) CreateCalls() []struct { + In1 *v3.ProjectNetworkPolicy +} { + var calls []struct { + In1 *v3.ProjectNetworkPolicy + } + lockProjectNetworkPolicyInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockProjectNetworkPolicyInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.DeleteFunc: method is nil but ProjectNetworkPolicyInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockProjectNetworkPolicyInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockProjectNetworkPolicyInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.DeleteCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockProjectNetworkPolicyInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockProjectNetworkPolicyInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.DeleteCollectionFunc: method is nil but ProjectNetworkPolicyInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockProjectNetworkPolicyInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockProjectNetworkPolicyInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.DeleteCollectionCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockProjectNetworkPolicyInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockProjectNetworkPolicyInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.DeleteNamespacedFunc: method is nil but ProjectNetworkPolicyInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockProjectNetworkPolicyInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockProjectNetworkPolicyInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.DeleteNamespacedCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockProjectNetworkPolicyInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockProjectNetworkPolicyInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { + if mock.GetFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.GetFunc: method is nil but ProjectNetworkPolicyInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockProjectNetworkPolicyInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectNetworkPolicyInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.GetCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockProjectNetworkPolicyInterfaceMockGet.RLock() + calls = mock.calls.Get + lockProjectNetworkPolicyInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { + if mock.GetNamespacedFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.GetNamespacedFunc: method is nil but ProjectNetworkPolicyInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockProjectNetworkPolicyInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockProjectNetworkPolicyInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.GetNamespacedCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockProjectNetworkPolicyInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockProjectNetworkPolicyInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) List(opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { + if mock.ListFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.ListFunc: method is nil but ProjectNetworkPolicyInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectNetworkPolicyInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectNetworkPolicyInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.ListCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectNetworkPolicyInterfaceMockList.RLock() + calls = mock.calls.List + lockProjectNetworkPolicyInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { + if mock.ListNamespacedFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.ListNamespacedFunc: method is nil but ProjectNetworkPolicyInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockProjectNetworkPolicyInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockProjectNetworkPolicyInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.ListNamespacedCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockProjectNetworkPolicyInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockProjectNetworkPolicyInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.ObjectClientFunc: method is nil but ProjectNetworkPolicyInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockProjectNetworkPolicyInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockProjectNetworkPolicyInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.ObjectClientCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockProjectNetworkPolicyInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockProjectNetworkPolicyInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Update(in1 *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { + if mock.UpdateFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.UpdateFunc: method is nil but ProjectNetworkPolicyInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ProjectNetworkPolicy + }{ + In1: in1, + } + lockProjectNetworkPolicyInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockProjectNetworkPolicyInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.UpdateCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) UpdateCalls() []struct { + In1 *v3.ProjectNetworkPolicy +} { + var calls []struct { + In1 *v3.ProjectNetworkPolicy + } + lockProjectNetworkPolicyInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockProjectNetworkPolicyInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ProjectNetworkPolicyInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ProjectNetworkPolicyInterfaceMock.WatchFunc: method is nil but ProjectNetworkPolicyInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectNetworkPolicyInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockProjectNetworkPolicyInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedProjectNetworkPolicyInterface.WatchCalls()) +func (mock *ProjectNetworkPolicyInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectNetworkPolicyInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockProjectNetworkPolicyInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockProjectNetworkPoliciesGetterMockProjectNetworkPolicies sync.RWMutex +) + +// Ensure, that ProjectNetworkPoliciesGetterMock does implement v31.ProjectNetworkPoliciesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectNetworkPoliciesGetter = &ProjectNetworkPoliciesGetterMock{} + +// ProjectNetworkPoliciesGetterMock is a mock implementation of v31.ProjectNetworkPoliciesGetter. +// +// func TestSomethingThatUsesProjectNetworkPoliciesGetter(t *testing.T) { +// +// // make and configure a mocked v31.ProjectNetworkPoliciesGetter +// mockedProjectNetworkPoliciesGetter := &ProjectNetworkPoliciesGetterMock{ +// ProjectNetworkPoliciesFunc: func(namespace string) v31.ProjectNetworkPolicyInterface { +// panic("mock out the ProjectNetworkPolicies method") +// }, +// } +// +// // use mockedProjectNetworkPoliciesGetter in code that requires v31.ProjectNetworkPoliciesGetter +// // and then make assertions. +// +// } +type ProjectNetworkPoliciesGetterMock struct { + // ProjectNetworkPoliciesFunc mocks the ProjectNetworkPolicies method. + ProjectNetworkPoliciesFunc func(namespace string) v31.ProjectNetworkPolicyInterface + + // calls tracks calls to the methods. + calls struct { + // ProjectNetworkPolicies holds details about calls to the ProjectNetworkPolicies method. + ProjectNetworkPolicies []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ProjectNetworkPolicies calls ProjectNetworkPoliciesFunc. +func (mock *ProjectNetworkPoliciesGetterMock) ProjectNetworkPolicies(namespace string) v31.ProjectNetworkPolicyInterface { + if mock.ProjectNetworkPoliciesFunc == nil { + panic("ProjectNetworkPoliciesGetterMock.ProjectNetworkPoliciesFunc: method is nil but ProjectNetworkPoliciesGetter.ProjectNetworkPolicies was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockProjectNetworkPoliciesGetterMockProjectNetworkPolicies.Lock() + mock.calls.ProjectNetworkPolicies = append(mock.calls.ProjectNetworkPolicies, callInfo) + lockProjectNetworkPoliciesGetterMockProjectNetworkPolicies.Unlock() + return mock.ProjectNetworkPoliciesFunc(namespace) +} + +// ProjectNetworkPoliciesCalls gets all the calls that were made to ProjectNetworkPolicies. +// Check the length with: +// +// len(mockedProjectNetworkPoliciesGetter.ProjectNetworkPoliciesCalls()) +func (mock *ProjectNetworkPoliciesGetterMock) ProjectNetworkPoliciesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockProjectNetworkPoliciesGetterMockProjectNetworkPolicies.RLock() + calls = mock.calls.ProjectNetworkPolicies + lockProjectNetworkPoliciesGetterMockProjectNetworkPolicies.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_role_template_binding_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_role_template_binding_mock.go new file mode 100644 index 0000000..8651fd4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_project_role_template_binding_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockProjectRoleTemplateBindingListerMockGet sync.RWMutex + lockProjectRoleTemplateBindingListerMockList sync.RWMutex +) + +// Ensure, that ProjectRoleTemplateBindingListerMock does implement v31.ProjectRoleTemplateBindingLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectRoleTemplateBindingLister = &ProjectRoleTemplateBindingListerMock{} + +// ProjectRoleTemplateBindingListerMock is a mock implementation of v31.ProjectRoleTemplateBindingLister. +// +// func TestSomethingThatUsesProjectRoleTemplateBindingLister(t *testing.T) { +// +// // make and configure a mocked v31.ProjectRoleTemplateBindingLister +// mockedProjectRoleTemplateBindingLister := &ProjectRoleTemplateBindingListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedProjectRoleTemplateBindingLister in code that requires v31.ProjectRoleTemplateBindingLister +// // and then make assertions. +// +// } +type ProjectRoleTemplateBindingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ProjectRoleTemplateBinding, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ProjectRoleTemplateBinding, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ProjectRoleTemplateBindingListerMock) Get(namespace string, name string) (*v3.ProjectRoleTemplateBinding, error) { + if mock.GetFunc == nil { + panic("ProjectRoleTemplateBindingListerMock.GetFunc: method is nil but ProjectRoleTemplateBindingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectRoleTemplateBindingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectRoleTemplateBindingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingLister.GetCalls()) +func (mock *ProjectRoleTemplateBindingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectRoleTemplateBindingListerMockGet.RLock() + calls = mock.calls.Get + lockProjectRoleTemplateBindingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectRoleTemplateBindingListerMock) List(namespace string, selector labels.Selector) ([]*v3.ProjectRoleTemplateBinding, error) { + if mock.ListFunc == nil { + panic("ProjectRoleTemplateBindingListerMock.ListFunc: method is nil but ProjectRoleTemplateBindingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockProjectRoleTemplateBindingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectRoleTemplateBindingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingLister.ListCalls()) +func (mock *ProjectRoleTemplateBindingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockProjectRoleTemplateBindingListerMockList.RLock() + calls = mock.calls.List + lockProjectRoleTemplateBindingListerMockList.RUnlock() + return calls +} + +var ( + lockProjectRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectRoleTemplateBindingControllerMockAddClusterScopedHandler sync.RWMutex + lockProjectRoleTemplateBindingControllerMockAddFeatureHandler sync.RWMutex + lockProjectRoleTemplateBindingControllerMockAddHandler sync.RWMutex + lockProjectRoleTemplateBindingControllerMockEnqueue sync.RWMutex + lockProjectRoleTemplateBindingControllerMockEnqueueAfter sync.RWMutex + lockProjectRoleTemplateBindingControllerMockGeneric sync.RWMutex + lockProjectRoleTemplateBindingControllerMockInformer sync.RWMutex + lockProjectRoleTemplateBindingControllerMockLister sync.RWMutex +) + +// Ensure, that ProjectRoleTemplateBindingControllerMock does implement v31.ProjectRoleTemplateBindingController. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectRoleTemplateBindingController = &ProjectRoleTemplateBindingControllerMock{} + +// ProjectRoleTemplateBindingControllerMock is a mock implementation of v31.ProjectRoleTemplateBindingController. +// +// func TestSomethingThatUsesProjectRoleTemplateBindingController(t *testing.T) { +// +// // make and configure a mocked v31.ProjectRoleTemplateBindingController +// mockedProjectRoleTemplateBindingController := &ProjectRoleTemplateBindingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ProjectRoleTemplateBindingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedProjectRoleTemplateBindingController in code that requires v31.ProjectRoleTemplateBindingController +// // and then make assertions. +// +// } +type ProjectRoleTemplateBindingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ProjectRoleTemplateBindingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ProjectRoleTemplateBindingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectRoleTemplateBindingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectRoleTemplateBindingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.AddClusterScopedHandlerFunc: method is nil but ProjectRoleTemplateBindingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockProjectRoleTemplateBindingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectRoleTemplateBindingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.AddClusterScopedHandlerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectRoleTemplateBindingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.AddFeatureHandlerFunc: method is nil but ProjectRoleTemplateBindingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectRoleTemplateBindingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectRoleTemplateBindingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.AddFeatureHandlerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectRoleTemplateBindingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) AddHandler(ctx context.Context, name string, handler v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.AddHandlerFunc: method is nil but ProjectRoleTemplateBindingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockProjectRoleTemplateBindingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectRoleTemplateBindingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.AddHandlerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectRoleTemplateBindingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.EnqueueFunc: method is nil but ProjectRoleTemplateBindingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockProjectRoleTemplateBindingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockProjectRoleTemplateBindingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.EnqueueCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockProjectRoleTemplateBindingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockProjectRoleTemplateBindingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.EnqueueAfterFunc: method is nil but ProjectRoleTemplateBindingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockProjectRoleTemplateBindingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockProjectRoleTemplateBindingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.EnqueueAfterCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockProjectRoleTemplateBindingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockProjectRoleTemplateBindingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.GenericFunc: method is nil but ProjectRoleTemplateBindingController.Generic was just called") + } + callInfo := struct { + }{} + lockProjectRoleTemplateBindingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockProjectRoleTemplateBindingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.GenericCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockProjectRoleTemplateBindingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockProjectRoleTemplateBindingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.InformerFunc: method is nil but ProjectRoleTemplateBindingController.Informer was just called") + } + callInfo := struct { + }{} + lockProjectRoleTemplateBindingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockProjectRoleTemplateBindingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.InformerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockProjectRoleTemplateBindingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockProjectRoleTemplateBindingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ProjectRoleTemplateBindingControllerMock) Lister() v31.ProjectRoleTemplateBindingLister { + if mock.ListerFunc == nil { + panic("ProjectRoleTemplateBindingControllerMock.ListerFunc: method is nil but ProjectRoleTemplateBindingController.Lister was just called") + } + callInfo := struct { + }{} + lockProjectRoleTemplateBindingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockProjectRoleTemplateBindingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingController.ListerCalls()) +func (mock *ProjectRoleTemplateBindingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockProjectRoleTemplateBindingControllerMockLister.RLock() + calls = mock.calls.Lister + lockProjectRoleTemplateBindingControllerMockLister.RUnlock() + return calls +} + +var ( + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddFeatureHandler sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddHandler sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockAddLifecycle sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockController sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockCreate sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockDelete sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockDeleteCollection sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockDeleteNamespaced sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockGet sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockGetNamespaced sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockList sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockListNamespaced sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockObjectClient sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockUpdate sync.RWMutex + lockProjectRoleTemplateBindingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ProjectRoleTemplateBindingInterfaceMock does implement v31.ProjectRoleTemplateBindingInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectRoleTemplateBindingInterface = &ProjectRoleTemplateBindingInterfaceMock{} + +// ProjectRoleTemplateBindingInterfaceMock is a mock implementation of v31.ProjectRoleTemplateBindingInterface. +// +// func TestSomethingThatUsesProjectRoleTemplateBindingInterface(t *testing.T) { +// +// // make and configure a mocked v31.ProjectRoleTemplateBindingInterface +// mockedProjectRoleTemplateBindingInterface := &ProjectRoleTemplateBindingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ProjectRoleTemplateBindingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedProjectRoleTemplateBindingInterface in code that requires v31.ProjectRoleTemplateBindingInterface +// // and then make assertions. +// +// } +type ProjectRoleTemplateBindingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ProjectRoleTemplateBindingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectRoleTemplateBinding + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ProjectRoleTemplateBinding + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ProjectRoleTemplateBindingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ProjectRoleTemplateBindingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ProjectRoleTemplateBindingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddClusterScopedHandlerCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ProjectRoleTemplateBindingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddClusterScopedLifecycleCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockProjectRoleTemplateBindingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddFeatureHandlerFunc: method is nil but ProjectRoleTemplateBindingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockProjectRoleTemplateBindingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddFeatureHandlerCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockProjectRoleTemplateBindingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddFeatureLifecycleFunc: method is nil but ProjectRoleTemplateBindingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockProjectRoleTemplateBindingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddFeatureLifecycleCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + lockProjectRoleTemplateBindingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockProjectRoleTemplateBindingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ProjectRoleTemplateBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddHandlerFunc: method is nil but ProjectRoleTemplateBindingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockProjectRoleTemplateBindingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddHandlerCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ProjectRoleTemplateBindingHandlerFunc + } + lockProjectRoleTemplateBindingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockProjectRoleTemplateBindingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ProjectRoleTemplateBindingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.AddLifecycleFunc: method is nil but ProjectRoleTemplateBindingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockProjectRoleTemplateBindingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockProjectRoleTemplateBindingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.AddLifecycleCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ProjectRoleTemplateBindingLifecycle + } + lockProjectRoleTemplateBindingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockProjectRoleTemplateBindingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Controller() v31.ProjectRoleTemplateBindingController { + if mock.ControllerFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.ControllerFunc: method is nil but ProjectRoleTemplateBindingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockProjectRoleTemplateBindingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockProjectRoleTemplateBindingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.ControllerCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockProjectRoleTemplateBindingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockProjectRoleTemplateBindingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Create(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + if mock.CreateFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.CreateFunc: method is nil but ProjectRoleTemplateBindingInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ProjectRoleTemplateBinding + }{ + In1: in1, + } + lockProjectRoleTemplateBindingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockProjectRoleTemplateBindingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.CreateCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) CreateCalls() []struct { + In1 *v3.ProjectRoleTemplateBinding +} { + var calls []struct { + In1 *v3.ProjectRoleTemplateBinding + } + lockProjectRoleTemplateBindingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockProjectRoleTemplateBindingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.DeleteFunc: method is nil but ProjectRoleTemplateBindingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockProjectRoleTemplateBindingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockProjectRoleTemplateBindingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.DeleteCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockProjectRoleTemplateBindingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockProjectRoleTemplateBindingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.DeleteCollectionFunc: method is nil but ProjectRoleTemplateBindingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockProjectRoleTemplateBindingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockProjectRoleTemplateBindingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.DeleteCollectionCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockProjectRoleTemplateBindingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockProjectRoleTemplateBindingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.DeleteNamespacedFunc: method is nil but ProjectRoleTemplateBindingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockProjectRoleTemplateBindingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockProjectRoleTemplateBindingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.DeleteNamespacedCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockProjectRoleTemplateBindingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockProjectRoleTemplateBindingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { + if mock.GetFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.GetFunc: method is nil but ProjectRoleTemplateBindingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockProjectRoleTemplateBindingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockProjectRoleTemplateBindingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.GetCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockProjectRoleTemplateBindingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockProjectRoleTemplateBindingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { + if mock.GetNamespacedFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.GetNamespacedFunc: method is nil but ProjectRoleTemplateBindingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockProjectRoleTemplateBindingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockProjectRoleTemplateBindingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.GetNamespacedCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockProjectRoleTemplateBindingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockProjectRoleTemplateBindingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) List(opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { + if mock.ListFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.ListFunc: method is nil but ProjectRoleTemplateBindingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectRoleTemplateBindingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockProjectRoleTemplateBindingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.ListCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectRoleTemplateBindingInterfaceMockList.RLock() + calls = mock.calls.List + lockProjectRoleTemplateBindingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { + if mock.ListNamespacedFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.ListNamespacedFunc: method is nil but ProjectRoleTemplateBindingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockProjectRoleTemplateBindingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockProjectRoleTemplateBindingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.ListNamespacedCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockProjectRoleTemplateBindingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockProjectRoleTemplateBindingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.ObjectClientFunc: method is nil but ProjectRoleTemplateBindingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockProjectRoleTemplateBindingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockProjectRoleTemplateBindingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.ObjectClientCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockProjectRoleTemplateBindingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockProjectRoleTemplateBindingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Update(in1 *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + if mock.UpdateFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.UpdateFunc: method is nil but ProjectRoleTemplateBindingInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ProjectRoleTemplateBinding + }{ + In1: in1, + } + lockProjectRoleTemplateBindingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockProjectRoleTemplateBindingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.UpdateCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) UpdateCalls() []struct { + In1 *v3.ProjectRoleTemplateBinding +} { + var calls []struct { + In1 *v3.ProjectRoleTemplateBinding + } + lockProjectRoleTemplateBindingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockProjectRoleTemplateBindingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ProjectRoleTemplateBindingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ProjectRoleTemplateBindingInterfaceMock.WatchFunc: method is nil but ProjectRoleTemplateBindingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockProjectRoleTemplateBindingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockProjectRoleTemplateBindingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingInterface.WatchCalls()) +func (mock *ProjectRoleTemplateBindingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockProjectRoleTemplateBindingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockProjectRoleTemplateBindingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockProjectRoleTemplateBindingsGetterMockProjectRoleTemplateBindings sync.RWMutex +) + +// Ensure, that ProjectRoleTemplateBindingsGetterMock does implement v31.ProjectRoleTemplateBindingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ProjectRoleTemplateBindingsGetter = &ProjectRoleTemplateBindingsGetterMock{} + +// ProjectRoleTemplateBindingsGetterMock is a mock implementation of v31.ProjectRoleTemplateBindingsGetter. +// +// func TestSomethingThatUsesProjectRoleTemplateBindingsGetter(t *testing.T) { +// +// // make and configure a mocked v31.ProjectRoleTemplateBindingsGetter +// mockedProjectRoleTemplateBindingsGetter := &ProjectRoleTemplateBindingsGetterMock{ +// ProjectRoleTemplateBindingsFunc: func(namespace string) v31.ProjectRoleTemplateBindingInterface { +// panic("mock out the ProjectRoleTemplateBindings method") +// }, +// } +// +// // use mockedProjectRoleTemplateBindingsGetter in code that requires v31.ProjectRoleTemplateBindingsGetter +// // and then make assertions. +// +// } +type ProjectRoleTemplateBindingsGetterMock struct { + // ProjectRoleTemplateBindingsFunc mocks the ProjectRoleTemplateBindings method. + ProjectRoleTemplateBindingsFunc func(namespace string) v31.ProjectRoleTemplateBindingInterface + + // calls tracks calls to the methods. + calls struct { + // ProjectRoleTemplateBindings holds details about calls to the ProjectRoleTemplateBindings method. + ProjectRoleTemplateBindings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ProjectRoleTemplateBindings calls ProjectRoleTemplateBindingsFunc. +func (mock *ProjectRoleTemplateBindingsGetterMock) ProjectRoleTemplateBindings(namespace string) v31.ProjectRoleTemplateBindingInterface { + if mock.ProjectRoleTemplateBindingsFunc == nil { + panic("ProjectRoleTemplateBindingsGetterMock.ProjectRoleTemplateBindingsFunc: method is nil but ProjectRoleTemplateBindingsGetter.ProjectRoleTemplateBindings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockProjectRoleTemplateBindingsGetterMockProjectRoleTemplateBindings.Lock() + mock.calls.ProjectRoleTemplateBindings = append(mock.calls.ProjectRoleTemplateBindings, callInfo) + lockProjectRoleTemplateBindingsGetterMockProjectRoleTemplateBindings.Unlock() + return mock.ProjectRoleTemplateBindingsFunc(namespace) +} + +// ProjectRoleTemplateBindingsCalls gets all the calls that were made to ProjectRoleTemplateBindings. +// Check the length with: +// +// len(mockedProjectRoleTemplateBindingsGetter.ProjectRoleTemplateBindingsCalls()) +func (mock *ProjectRoleTemplateBindingsGetterMock) ProjectRoleTemplateBindingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockProjectRoleTemplateBindingsGetterMockProjectRoleTemplateBindings.RLock() + calls = mock.calls.ProjectRoleTemplateBindings + lockProjectRoleTemplateBindingsGetterMockProjectRoleTemplateBindings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rancher_user_notification_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rancher_user_notification_mock.go new file mode 100644 index 0000000..c9bce51 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rancher_user_notification_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRancherUserNotificationListerMockGet sync.RWMutex + lockRancherUserNotificationListerMockList sync.RWMutex +) + +// Ensure, that RancherUserNotificationListerMock does implement v31.RancherUserNotificationLister. +// If this is not the case, regenerate this file with moq. +var _ v31.RancherUserNotificationLister = &RancherUserNotificationListerMock{} + +// RancherUserNotificationListerMock is a mock implementation of v31.RancherUserNotificationLister. +// +// func TestSomethingThatUsesRancherUserNotificationLister(t *testing.T) { +// +// // make and configure a mocked v31.RancherUserNotificationLister +// mockedRancherUserNotificationLister := &RancherUserNotificationListerMock{ +// GetFunc: func(namespace string, name string) (*v3.RancherUserNotification, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.RancherUserNotification, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRancherUserNotificationLister in code that requires v31.RancherUserNotificationLister +// // and then make assertions. +// +// } +type RancherUserNotificationListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.RancherUserNotification, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.RancherUserNotification, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RancherUserNotificationListerMock) Get(namespace string, name string) (*v3.RancherUserNotification, error) { + if mock.GetFunc == nil { + panic("RancherUserNotificationListerMock.GetFunc: method is nil but RancherUserNotificationLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRancherUserNotificationListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRancherUserNotificationListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRancherUserNotificationLister.GetCalls()) +func (mock *RancherUserNotificationListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRancherUserNotificationListerMockGet.RLock() + calls = mock.calls.Get + lockRancherUserNotificationListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RancherUserNotificationListerMock) List(namespace string, selector labels.Selector) ([]*v3.RancherUserNotification, error) { + if mock.ListFunc == nil { + panic("RancherUserNotificationListerMock.ListFunc: method is nil but RancherUserNotificationLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRancherUserNotificationListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRancherUserNotificationListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRancherUserNotificationLister.ListCalls()) +func (mock *RancherUserNotificationListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRancherUserNotificationListerMockList.RLock() + calls = mock.calls.List + lockRancherUserNotificationListerMockList.RUnlock() + return calls +} + +var ( + lockRancherUserNotificationControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRancherUserNotificationControllerMockAddClusterScopedHandler sync.RWMutex + lockRancherUserNotificationControllerMockAddFeatureHandler sync.RWMutex + lockRancherUserNotificationControllerMockAddHandler sync.RWMutex + lockRancherUserNotificationControllerMockEnqueue sync.RWMutex + lockRancherUserNotificationControllerMockEnqueueAfter sync.RWMutex + lockRancherUserNotificationControllerMockGeneric sync.RWMutex + lockRancherUserNotificationControllerMockInformer sync.RWMutex + lockRancherUserNotificationControllerMockLister sync.RWMutex +) + +// Ensure, that RancherUserNotificationControllerMock does implement v31.RancherUserNotificationController. +// If this is not the case, regenerate this file with moq. +var _ v31.RancherUserNotificationController = &RancherUserNotificationControllerMock{} + +// RancherUserNotificationControllerMock is a mock implementation of v31.RancherUserNotificationController. +// +// func TestSomethingThatUsesRancherUserNotificationController(t *testing.T) { +// +// // make and configure a mocked v31.RancherUserNotificationController +// mockedRancherUserNotificationController := &RancherUserNotificationControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.RancherUserNotificationLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRancherUserNotificationController in code that requires v31.RancherUserNotificationController +// // and then make assertions. +// +// } +type RancherUserNotificationControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.RancherUserNotificationHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.RancherUserNotificationLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RancherUserNotificationHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RancherUserNotificationHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RancherUserNotificationHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.RancherUserNotificationHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RancherUserNotificationControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RancherUserNotificationControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RancherUserNotificationController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRancherUserNotificationControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRancherUserNotificationControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RancherUserNotificationControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRancherUserNotificationControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RancherUserNotificationControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.RancherUserNotificationHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RancherUserNotificationControllerMock.AddClusterScopedHandlerFunc: method is nil but RancherUserNotificationController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRancherUserNotificationControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRancherUserNotificationControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationController.AddClusterScopedHandlerCalls()) +func (mock *RancherUserNotificationControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRancherUserNotificationControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RancherUserNotificationControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RancherUserNotificationControllerMock.AddFeatureHandlerFunc: method is nil but RancherUserNotificationController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRancherUserNotificationControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRancherUserNotificationControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationController.AddFeatureHandlerCalls()) +func (mock *RancherUserNotificationControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRancherUserNotificationControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RancherUserNotificationControllerMock) AddHandler(ctx context.Context, name string, handler v31.RancherUserNotificationHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RancherUserNotificationControllerMock.AddHandlerFunc: method is nil but RancherUserNotificationController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRancherUserNotificationControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRancherUserNotificationControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationController.AddHandlerCalls()) +func (mock *RancherUserNotificationControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRancherUserNotificationControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RancherUserNotificationControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RancherUserNotificationControllerMock.EnqueueFunc: method is nil but RancherUserNotificationController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRancherUserNotificationControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRancherUserNotificationControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRancherUserNotificationController.EnqueueCalls()) +func (mock *RancherUserNotificationControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRancherUserNotificationControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRancherUserNotificationControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RancherUserNotificationControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RancherUserNotificationControllerMock.EnqueueAfterFunc: method is nil but RancherUserNotificationController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRancherUserNotificationControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRancherUserNotificationControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRancherUserNotificationController.EnqueueAfterCalls()) +func (mock *RancherUserNotificationControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRancherUserNotificationControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRancherUserNotificationControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RancherUserNotificationControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RancherUserNotificationControllerMock.GenericFunc: method is nil but RancherUserNotificationController.Generic was just called") + } + callInfo := struct { + }{} + lockRancherUserNotificationControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRancherUserNotificationControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRancherUserNotificationController.GenericCalls()) +func (mock *RancherUserNotificationControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRancherUserNotificationControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRancherUserNotificationControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RancherUserNotificationControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RancherUserNotificationControllerMock.InformerFunc: method is nil but RancherUserNotificationController.Informer was just called") + } + callInfo := struct { + }{} + lockRancherUserNotificationControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRancherUserNotificationControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRancherUserNotificationController.InformerCalls()) +func (mock *RancherUserNotificationControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRancherUserNotificationControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRancherUserNotificationControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RancherUserNotificationControllerMock) Lister() v31.RancherUserNotificationLister { + if mock.ListerFunc == nil { + panic("RancherUserNotificationControllerMock.ListerFunc: method is nil but RancherUserNotificationController.Lister was just called") + } + callInfo := struct { + }{} + lockRancherUserNotificationControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRancherUserNotificationControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRancherUserNotificationController.ListerCalls()) +func (mock *RancherUserNotificationControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRancherUserNotificationControllerMockLister.RLock() + calls = mock.calls.Lister + lockRancherUserNotificationControllerMockLister.RUnlock() + return calls +} + +var ( + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRancherUserNotificationInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRancherUserNotificationInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRancherUserNotificationInterfaceMockAddFeatureHandler sync.RWMutex + lockRancherUserNotificationInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRancherUserNotificationInterfaceMockAddHandler sync.RWMutex + lockRancherUserNotificationInterfaceMockAddLifecycle sync.RWMutex + lockRancherUserNotificationInterfaceMockController sync.RWMutex + lockRancherUserNotificationInterfaceMockCreate sync.RWMutex + lockRancherUserNotificationInterfaceMockDelete sync.RWMutex + lockRancherUserNotificationInterfaceMockDeleteCollection sync.RWMutex + lockRancherUserNotificationInterfaceMockDeleteNamespaced sync.RWMutex + lockRancherUserNotificationInterfaceMockGet sync.RWMutex + lockRancherUserNotificationInterfaceMockGetNamespaced sync.RWMutex + lockRancherUserNotificationInterfaceMockList sync.RWMutex + lockRancherUserNotificationInterfaceMockListNamespaced sync.RWMutex + lockRancherUserNotificationInterfaceMockObjectClient sync.RWMutex + lockRancherUserNotificationInterfaceMockUpdate sync.RWMutex + lockRancherUserNotificationInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RancherUserNotificationInterfaceMock does implement v31.RancherUserNotificationInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.RancherUserNotificationInterface = &RancherUserNotificationInterfaceMock{} + +// RancherUserNotificationInterfaceMock is a mock implementation of v31.RancherUserNotificationInterface. +// +// func TestSomethingThatUsesRancherUserNotificationInterface(t *testing.T) { +// +// // make and configure a mocked v31.RancherUserNotificationInterface +// mockedRancherUserNotificationInterface := &RancherUserNotificationInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RancherUserNotificationLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.RancherUserNotificationLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.RancherUserNotificationController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRancherUserNotificationInterface in code that requires v31.RancherUserNotificationInterface +// // and then make assertions. +// +// } +type RancherUserNotificationInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RancherUserNotificationLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.RancherUserNotificationLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.RancherUserNotificationController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RancherUserNotificationHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RancherUserNotificationLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RancherUserNotificationHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RancherUserNotificationLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RancherUserNotificationHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RancherUserNotificationLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RancherUserNotificationHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RancherUserNotificationLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.RancherUserNotification + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.RancherUserNotification + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RancherUserNotificationInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RancherUserNotificationInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle + } + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRancherUserNotificationInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RancherUserNotificationInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRancherUserNotificationInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRancherUserNotificationInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddClusterScopedHandlerCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRancherUserNotificationInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.RancherUserNotificationLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RancherUserNotificationInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRancherUserNotificationInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRancherUserNotificationInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddClusterScopedLifecycleCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RancherUserNotificationLifecycle + } + lockRancherUserNotificationInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRancherUserNotificationInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RancherUserNotificationInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddFeatureHandlerFunc: method is nil but RancherUserNotificationInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRancherUserNotificationInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRancherUserNotificationInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddFeatureHandlerCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRancherUserNotificationInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RancherUserNotificationInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.RancherUserNotificationLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddFeatureLifecycleFunc: method is nil but RancherUserNotificationInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RancherUserNotificationLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRancherUserNotificationInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRancherUserNotificationInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddFeatureLifecycleCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RancherUserNotificationLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RancherUserNotificationLifecycle + } + lockRancherUserNotificationInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRancherUserNotificationInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RancherUserNotificationInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.RancherUserNotificationHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddHandlerFunc: method is nil but RancherUserNotificationInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.RancherUserNotificationHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRancherUserNotificationInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRancherUserNotificationInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddHandlerCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.RancherUserNotificationHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.RancherUserNotificationHandlerFunc + } + lockRancherUserNotificationInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRancherUserNotificationInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RancherUserNotificationInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.RancherUserNotificationLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RancherUserNotificationInterfaceMock.AddLifecycleFunc: method is nil but RancherUserNotificationInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.RancherUserNotificationLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRancherUserNotificationInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRancherUserNotificationInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.AddLifecycleCalls()) +func (mock *RancherUserNotificationInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.RancherUserNotificationLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.RancherUserNotificationLifecycle + } + lockRancherUserNotificationInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRancherUserNotificationInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RancherUserNotificationInterfaceMock) Controller() v31.RancherUserNotificationController { + if mock.ControllerFunc == nil { + panic("RancherUserNotificationInterfaceMock.ControllerFunc: method is nil but RancherUserNotificationInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRancherUserNotificationInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRancherUserNotificationInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.ControllerCalls()) +func (mock *RancherUserNotificationInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRancherUserNotificationInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRancherUserNotificationInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RancherUserNotificationInterfaceMock) Create(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { + if mock.CreateFunc == nil { + panic("RancherUserNotificationInterfaceMock.CreateFunc: method is nil but RancherUserNotificationInterface.Create was just called") + } + callInfo := struct { + In1 *v3.RancherUserNotification + }{ + In1: in1, + } + lockRancherUserNotificationInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRancherUserNotificationInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.CreateCalls()) +func (mock *RancherUserNotificationInterfaceMock) CreateCalls() []struct { + In1 *v3.RancherUserNotification +} { + var calls []struct { + In1 *v3.RancherUserNotification + } + lockRancherUserNotificationInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRancherUserNotificationInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RancherUserNotificationInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RancherUserNotificationInterfaceMock.DeleteFunc: method is nil but RancherUserNotificationInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRancherUserNotificationInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRancherUserNotificationInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.DeleteCalls()) +func (mock *RancherUserNotificationInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRancherUserNotificationInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRancherUserNotificationInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RancherUserNotificationInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RancherUserNotificationInterfaceMock.DeleteCollectionFunc: method is nil but RancherUserNotificationInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRancherUserNotificationInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRancherUserNotificationInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.DeleteCollectionCalls()) +func (mock *RancherUserNotificationInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRancherUserNotificationInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRancherUserNotificationInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RancherUserNotificationInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RancherUserNotificationInterfaceMock.DeleteNamespacedFunc: method is nil but RancherUserNotificationInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRancherUserNotificationInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRancherUserNotificationInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.DeleteNamespacedCalls()) +func (mock *RancherUserNotificationInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRancherUserNotificationInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRancherUserNotificationInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RancherUserNotificationInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { + if mock.GetFunc == nil { + panic("RancherUserNotificationInterfaceMock.GetFunc: method is nil but RancherUserNotificationInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRancherUserNotificationInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRancherUserNotificationInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.GetCalls()) +func (mock *RancherUserNotificationInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRancherUserNotificationInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRancherUserNotificationInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RancherUserNotificationInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { + if mock.GetNamespacedFunc == nil { + panic("RancherUserNotificationInterfaceMock.GetNamespacedFunc: method is nil but RancherUserNotificationInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRancherUserNotificationInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRancherUserNotificationInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.GetNamespacedCalls()) +func (mock *RancherUserNotificationInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRancherUserNotificationInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRancherUserNotificationInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RancherUserNotificationInterfaceMock) List(opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { + if mock.ListFunc == nil { + panic("RancherUserNotificationInterfaceMock.ListFunc: method is nil but RancherUserNotificationInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRancherUserNotificationInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRancherUserNotificationInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.ListCalls()) +func (mock *RancherUserNotificationInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRancherUserNotificationInterfaceMockList.RLock() + calls = mock.calls.List + lockRancherUserNotificationInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RancherUserNotificationInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { + if mock.ListNamespacedFunc == nil { + panic("RancherUserNotificationInterfaceMock.ListNamespacedFunc: method is nil but RancherUserNotificationInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRancherUserNotificationInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRancherUserNotificationInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.ListNamespacedCalls()) +func (mock *RancherUserNotificationInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRancherUserNotificationInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRancherUserNotificationInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RancherUserNotificationInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RancherUserNotificationInterfaceMock.ObjectClientFunc: method is nil but RancherUserNotificationInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRancherUserNotificationInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRancherUserNotificationInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.ObjectClientCalls()) +func (mock *RancherUserNotificationInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRancherUserNotificationInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRancherUserNotificationInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RancherUserNotificationInterfaceMock) Update(in1 *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { + if mock.UpdateFunc == nil { + panic("RancherUserNotificationInterfaceMock.UpdateFunc: method is nil but RancherUserNotificationInterface.Update was just called") + } + callInfo := struct { + In1 *v3.RancherUserNotification + }{ + In1: in1, + } + lockRancherUserNotificationInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRancherUserNotificationInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.UpdateCalls()) +func (mock *RancherUserNotificationInterfaceMock) UpdateCalls() []struct { + In1 *v3.RancherUserNotification +} { + var calls []struct { + In1 *v3.RancherUserNotification + } + lockRancherUserNotificationInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRancherUserNotificationInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RancherUserNotificationInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RancherUserNotificationInterfaceMock.WatchFunc: method is nil but RancherUserNotificationInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRancherUserNotificationInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRancherUserNotificationInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRancherUserNotificationInterface.WatchCalls()) +func (mock *RancherUserNotificationInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRancherUserNotificationInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRancherUserNotificationInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRancherUserNotificationsGetterMockRancherUserNotifications sync.RWMutex +) + +// Ensure, that RancherUserNotificationsGetterMock does implement v31.RancherUserNotificationsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.RancherUserNotificationsGetter = &RancherUserNotificationsGetterMock{} + +// RancherUserNotificationsGetterMock is a mock implementation of v31.RancherUserNotificationsGetter. +// +// func TestSomethingThatUsesRancherUserNotificationsGetter(t *testing.T) { +// +// // make and configure a mocked v31.RancherUserNotificationsGetter +// mockedRancherUserNotificationsGetter := &RancherUserNotificationsGetterMock{ +// RancherUserNotificationsFunc: func(namespace string) v31.RancherUserNotificationInterface { +// panic("mock out the RancherUserNotifications method") +// }, +// } +// +// // use mockedRancherUserNotificationsGetter in code that requires v31.RancherUserNotificationsGetter +// // and then make assertions. +// +// } +type RancherUserNotificationsGetterMock struct { + // RancherUserNotificationsFunc mocks the RancherUserNotifications method. + RancherUserNotificationsFunc func(namespace string) v31.RancherUserNotificationInterface + + // calls tracks calls to the methods. + calls struct { + // RancherUserNotifications holds details about calls to the RancherUserNotifications method. + RancherUserNotifications []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RancherUserNotifications calls RancherUserNotificationsFunc. +func (mock *RancherUserNotificationsGetterMock) RancherUserNotifications(namespace string) v31.RancherUserNotificationInterface { + if mock.RancherUserNotificationsFunc == nil { + panic("RancherUserNotificationsGetterMock.RancherUserNotificationsFunc: method is nil but RancherUserNotificationsGetter.RancherUserNotifications was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRancherUserNotificationsGetterMockRancherUserNotifications.Lock() + mock.calls.RancherUserNotifications = append(mock.calls.RancherUserNotifications, callInfo) + lockRancherUserNotificationsGetterMockRancherUserNotifications.Unlock() + return mock.RancherUserNotificationsFunc(namespace) +} + +// RancherUserNotificationsCalls gets all the calls that were made to RancherUserNotifications. +// Check the length with: +// +// len(mockedRancherUserNotificationsGetter.RancherUserNotificationsCalls()) +func (mock *RancherUserNotificationsGetterMock) RancherUserNotificationsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRancherUserNotificationsGetterMockRancherUserNotifications.RLock() + calls = mock.calls.RancherUserNotifications + lockRancherUserNotificationsGetterMockRancherUserNotifications.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_addon_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_addon_mock.go new file mode 100644 index 0000000..3be0cf1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_addon_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRkeAddonListerMockGet sync.RWMutex + lockRkeAddonListerMockList sync.RWMutex +) + +// Ensure, that RkeAddonListerMock does implement v31.RkeAddonLister. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeAddonLister = &RkeAddonListerMock{} + +// RkeAddonListerMock is a mock implementation of v31.RkeAddonLister. +// +// func TestSomethingThatUsesRkeAddonLister(t *testing.T) { +// +// // make and configure a mocked v31.RkeAddonLister +// mockedRkeAddonLister := &RkeAddonListerMock{ +// GetFunc: func(namespace string, name string) (*v3.RkeAddon, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.RkeAddon, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRkeAddonLister in code that requires v31.RkeAddonLister +// // and then make assertions. +// +// } +type RkeAddonListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.RkeAddon, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.RkeAddon, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RkeAddonListerMock) Get(namespace string, name string) (*v3.RkeAddon, error) { + if mock.GetFunc == nil { + panic("RkeAddonListerMock.GetFunc: method is nil but RkeAddonLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeAddonListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeAddonListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeAddonLister.GetCalls()) +func (mock *RkeAddonListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeAddonListerMockGet.RLock() + calls = mock.calls.Get + lockRkeAddonListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeAddonListerMock) List(namespace string, selector labels.Selector) ([]*v3.RkeAddon, error) { + if mock.ListFunc == nil { + panic("RkeAddonListerMock.ListFunc: method is nil but RkeAddonLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRkeAddonListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeAddonListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeAddonLister.ListCalls()) +func (mock *RkeAddonListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRkeAddonListerMockList.RLock() + calls = mock.calls.List + lockRkeAddonListerMockList.RUnlock() + return calls +} + +var ( + lockRkeAddonControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeAddonControllerMockAddClusterScopedHandler sync.RWMutex + lockRkeAddonControllerMockAddFeatureHandler sync.RWMutex + lockRkeAddonControllerMockAddHandler sync.RWMutex + lockRkeAddonControllerMockEnqueue sync.RWMutex + lockRkeAddonControllerMockEnqueueAfter sync.RWMutex + lockRkeAddonControllerMockGeneric sync.RWMutex + lockRkeAddonControllerMockInformer sync.RWMutex + lockRkeAddonControllerMockLister sync.RWMutex +) + +// Ensure, that RkeAddonControllerMock does implement v31.RkeAddonController. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeAddonController = &RkeAddonControllerMock{} + +// RkeAddonControllerMock is a mock implementation of v31.RkeAddonController. +// +// func TestSomethingThatUsesRkeAddonController(t *testing.T) { +// +// // make and configure a mocked v31.RkeAddonController +// mockedRkeAddonController := &RkeAddonControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeAddonHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.RkeAddonHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.RkeAddonHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.RkeAddonLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRkeAddonController in code that requires v31.RkeAddonController +// // and then make assertions. +// +// } +type RkeAddonControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeAddonHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.RkeAddonHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.RkeAddonHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.RkeAddonLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeAddonHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeAddonHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeAddonHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.RkeAddonHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeAddonControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeAddonHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeAddonControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeAddonController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeAddonControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeAddonControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeAddonController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeAddonControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc + } + lockRkeAddonControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeAddonControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeAddonControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.RkeAddonHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeAddonControllerMock.AddClusterScopedHandlerFunc: method is nil but RkeAddonController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeAddonControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeAddonControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeAddonController.AddClusterScopedHandlerCalls()) +func (mock *RkeAddonControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeAddonHandlerFunc + } + lockRkeAddonControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeAddonControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeAddonControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeAddonControllerMock.AddFeatureHandlerFunc: method is nil but RkeAddonController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeAddonControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeAddonControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeAddonController.AddFeatureHandlerCalls()) +func (mock *RkeAddonControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc + } + lockRkeAddonControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeAddonControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeAddonControllerMock) AddHandler(ctx context.Context, name string, handler v31.RkeAddonHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeAddonControllerMock.AddHandlerFunc: method is nil but RkeAddonController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRkeAddonControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeAddonControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeAddonController.AddHandlerCalls()) +func (mock *RkeAddonControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.RkeAddonHandlerFunc + } + lockRkeAddonControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeAddonControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RkeAddonControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RkeAddonControllerMock.EnqueueFunc: method is nil but RkeAddonController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeAddonControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRkeAddonControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRkeAddonController.EnqueueCalls()) +func (mock *RkeAddonControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeAddonControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRkeAddonControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RkeAddonControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RkeAddonControllerMock.EnqueueAfterFunc: method is nil but RkeAddonController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRkeAddonControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRkeAddonControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRkeAddonController.EnqueueAfterCalls()) +func (mock *RkeAddonControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRkeAddonControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRkeAddonControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RkeAddonControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RkeAddonControllerMock.GenericFunc: method is nil but RkeAddonController.Generic was just called") + } + callInfo := struct { + }{} + lockRkeAddonControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRkeAddonControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRkeAddonController.GenericCalls()) +func (mock *RkeAddonControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRkeAddonControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRkeAddonControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RkeAddonControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RkeAddonControllerMock.InformerFunc: method is nil but RkeAddonController.Informer was just called") + } + callInfo := struct { + }{} + lockRkeAddonControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRkeAddonControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRkeAddonController.InformerCalls()) +func (mock *RkeAddonControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRkeAddonControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRkeAddonControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RkeAddonControllerMock) Lister() v31.RkeAddonLister { + if mock.ListerFunc == nil { + panic("RkeAddonControllerMock.ListerFunc: method is nil but RkeAddonController.Lister was just called") + } + callInfo := struct { + }{} + lockRkeAddonControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRkeAddonControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRkeAddonController.ListerCalls()) +func (mock *RkeAddonControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRkeAddonControllerMockLister.RLock() + calls = mock.calls.Lister + lockRkeAddonControllerMockLister.RUnlock() + return calls +} + +var ( + lockRkeAddonInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeAddonInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRkeAddonInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRkeAddonInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRkeAddonInterfaceMockAddFeatureHandler sync.RWMutex + lockRkeAddonInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRkeAddonInterfaceMockAddHandler sync.RWMutex + lockRkeAddonInterfaceMockAddLifecycle sync.RWMutex + lockRkeAddonInterfaceMockController sync.RWMutex + lockRkeAddonInterfaceMockCreate sync.RWMutex + lockRkeAddonInterfaceMockDelete sync.RWMutex + lockRkeAddonInterfaceMockDeleteCollection sync.RWMutex + lockRkeAddonInterfaceMockDeleteNamespaced sync.RWMutex + lockRkeAddonInterfaceMockGet sync.RWMutex + lockRkeAddonInterfaceMockGetNamespaced sync.RWMutex + lockRkeAddonInterfaceMockList sync.RWMutex + lockRkeAddonInterfaceMockListNamespaced sync.RWMutex + lockRkeAddonInterfaceMockObjectClient sync.RWMutex + lockRkeAddonInterfaceMockUpdate sync.RWMutex + lockRkeAddonInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RkeAddonInterfaceMock does implement v31.RkeAddonInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeAddonInterface = &RkeAddonInterfaceMock{} + +// RkeAddonInterfaceMock is a mock implementation of v31.RkeAddonInterface. +// +// func TestSomethingThatUsesRkeAddonInterface(t *testing.T) { +// +// // make and configure a mocked v31.RkeAddonInterface +// mockedRkeAddonInterface := &RkeAddonInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeAddonLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.RkeAddonHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.RkeAddonLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.RkeAddonController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.RkeAddon) (*v3.RkeAddon, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.RkeAddonList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.RkeAddonList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.RkeAddon) (*v3.RkeAddon, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRkeAddonInterface in code that requires v31.RkeAddonInterface +// // and then make assertions. +// +// } +type RkeAddonInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeAddonLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.RkeAddonHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.RkeAddonLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.RkeAddonController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.RkeAddon) (*v3.RkeAddon, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.RkeAddon, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeAddon, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.RkeAddonList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.RkeAddonList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.RkeAddon) (*v3.RkeAddon, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeAddonHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeAddonLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeAddonHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeAddonLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeAddonHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeAddonLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeAddonHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeAddonLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.RkeAddon + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.RkeAddon + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeAddonInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeAddonInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeAddonInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeAddonInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeAddonInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeAddonInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc + } + lockRkeAddonInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeAddonInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RkeAddonInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RkeAddonInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RkeAddonInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeAddonInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRkeAddonInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RkeAddonInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle + } + lockRkeAddonInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRkeAddonInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeAddonInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeAddonHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeAddonInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RkeAddonInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeAddonInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeAddonInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddClusterScopedHandlerCalls()) +func (mock *RkeAddonInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeAddonHandlerFunc + } + lockRkeAddonInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeAddonInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RkeAddonInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.RkeAddonLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RkeAddonInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RkeAddonInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeAddonInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRkeAddonInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddClusterScopedLifecycleCalls()) +func (mock *RkeAddonInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeAddonLifecycle + } + lockRkeAddonInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRkeAddonInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeAddonInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeAddonHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeAddonInterfaceMock.AddFeatureHandlerFunc: method is nil but RkeAddonInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeAddonInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeAddonInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddFeatureHandlerCalls()) +func (mock *RkeAddonInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeAddonHandlerFunc + } + lockRkeAddonInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeAddonInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RkeAddonInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeAddonLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RkeAddonInterfaceMock.AddFeatureLifecycleFunc: method is nil but RkeAddonInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeAddonLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRkeAddonInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRkeAddonInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddFeatureLifecycleCalls()) +func (mock *RkeAddonInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeAddonLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeAddonLifecycle + } + lockRkeAddonInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRkeAddonInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeAddonInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.RkeAddonHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeAddonInterfaceMock.AddHandlerFunc: method is nil but RkeAddonInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.RkeAddonHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRkeAddonInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeAddonInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddHandlerCalls()) +func (mock *RkeAddonInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.RkeAddonHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.RkeAddonHandlerFunc + } + lockRkeAddonInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeAddonInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RkeAddonInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.RkeAddonLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RkeAddonInterfaceMock.AddLifecycleFunc: method is nil but RkeAddonInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.RkeAddonLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRkeAddonInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRkeAddonInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRkeAddonInterface.AddLifecycleCalls()) +func (mock *RkeAddonInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeAddonLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeAddonLifecycle + } + lockRkeAddonInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRkeAddonInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RkeAddonInterfaceMock) Controller() v31.RkeAddonController { + if mock.ControllerFunc == nil { + panic("RkeAddonInterfaceMock.ControllerFunc: method is nil but RkeAddonInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRkeAddonInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRkeAddonInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRkeAddonInterface.ControllerCalls()) +func (mock *RkeAddonInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRkeAddonInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRkeAddonInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RkeAddonInterfaceMock) Create(in1 *v3.RkeAddon) (*v3.RkeAddon, error) { + if mock.CreateFunc == nil { + panic("RkeAddonInterfaceMock.CreateFunc: method is nil but RkeAddonInterface.Create was just called") + } + callInfo := struct { + In1 *v3.RkeAddon + }{ + In1: in1, + } + lockRkeAddonInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRkeAddonInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRkeAddonInterface.CreateCalls()) +func (mock *RkeAddonInterfaceMock) CreateCalls() []struct { + In1 *v3.RkeAddon +} { + var calls []struct { + In1 *v3.RkeAddon + } + lockRkeAddonInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRkeAddonInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RkeAddonInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RkeAddonInterfaceMock.DeleteFunc: method is nil but RkeAddonInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRkeAddonInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRkeAddonInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRkeAddonInterface.DeleteCalls()) +func (mock *RkeAddonInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRkeAddonInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRkeAddonInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RkeAddonInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RkeAddonInterfaceMock.DeleteCollectionFunc: method is nil but RkeAddonInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRkeAddonInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRkeAddonInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRkeAddonInterface.DeleteCollectionCalls()) +func (mock *RkeAddonInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRkeAddonInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRkeAddonInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RkeAddonInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RkeAddonInterfaceMock.DeleteNamespacedFunc: method is nil but RkeAddonInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRkeAddonInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRkeAddonInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRkeAddonInterface.DeleteNamespacedCalls()) +func (mock *RkeAddonInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRkeAddonInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRkeAddonInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RkeAddonInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { + if mock.GetFunc == nil { + panic("RkeAddonInterfaceMock.GetFunc: method is nil but RkeAddonInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRkeAddonInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeAddonInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeAddonInterface.GetCalls()) +func (mock *RkeAddonInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRkeAddonInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRkeAddonInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RkeAddonInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { + if mock.GetNamespacedFunc == nil { + panic("RkeAddonInterfaceMock.GetNamespacedFunc: method is nil but RkeAddonInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRkeAddonInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRkeAddonInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRkeAddonInterface.GetNamespacedCalls()) +func (mock *RkeAddonInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRkeAddonInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRkeAddonInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeAddonInterfaceMock) List(opts metav1.ListOptions) (*v3.RkeAddonList, error) { + if mock.ListFunc == nil { + panic("RkeAddonInterfaceMock.ListFunc: method is nil but RkeAddonInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeAddonInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeAddonInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeAddonInterface.ListCalls()) +func (mock *RkeAddonInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeAddonInterfaceMockList.RLock() + calls = mock.calls.List + lockRkeAddonInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RkeAddonInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeAddonList, error) { + if mock.ListNamespacedFunc == nil { + panic("RkeAddonInterfaceMock.ListNamespacedFunc: method is nil but RkeAddonInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRkeAddonInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRkeAddonInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRkeAddonInterface.ListNamespacedCalls()) +func (mock *RkeAddonInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRkeAddonInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRkeAddonInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RkeAddonInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RkeAddonInterfaceMock.ObjectClientFunc: method is nil but RkeAddonInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRkeAddonInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRkeAddonInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRkeAddonInterface.ObjectClientCalls()) +func (mock *RkeAddonInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRkeAddonInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRkeAddonInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RkeAddonInterfaceMock) Update(in1 *v3.RkeAddon) (*v3.RkeAddon, error) { + if mock.UpdateFunc == nil { + panic("RkeAddonInterfaceMock.UpdateFunc: method is nil but RkeAddonInterface.Update was just called") + } + callInfo := struct { + In1 *v3.RkeAddon + }{ + In1: in1, + } + lockRkeAddonInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRkeAddonInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRkeAddonInterface.UpdateCalls()) +func (mock *RkeAddonInterfaceMock) UpdateCalls() []struct { + In1 *v3.RkeAddon +} { + var calls []struct { + In1 *v3.RkeAddon + } + lockRkeAddonInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRkeAddonInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RkeAddonInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RkeAddonInterfaceMock.WatchFunc: method is nil but RkeAddonInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeAddonInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRkeAddonInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRkeAddonInterface.WatchCalls()) +func (mock *RkeAddonInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeAddonInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRkeAddonInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRkeAddonsGetterMockRkeAddons sync.RWMutex +) + +// Ensure, that RkeAddonsGetterMock does implement v31.RkeAddonsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeAddonsGetter = &RkeAddonsGetterMock{} + +// RkeAddonsGetterMock is a mock implementation of v31.RkeAddonsGetter. +// +// func TestSomethingThatUsesRkeAddonsGetter(t *testing.T) { +// +// // make and configure a mocked v31.RkeAddonsGetter +// mockedRkeAddonsGetter := &RkeAddonsGetterMock{ +// RkeAddonsFunc: func(namespace string) v31.RkeAddonInterface { +// panic("mock out the RkeAddons method") +// }, +// } +// +// // use mockedRkeAddonsGetter in code that requires v31.RkeAddonsGetter +// // and then make assertions. +// +// } +type RkeAddonsGetterMock struct { + // RkeAddonsFunc mocks the RkeAddons method. + RkeAddonsFunc func(namespace string) v31.RkeAddonInterface + + // calls tracks calls to the methods. + calls struct { + // RkeAddons holds details about calls to the RkeAddons method. + RkeAddons []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RkeAddons calls RkeAddonsFunc. +func (mock *RkeAddonsGetterMock) RkeAddons(namespace string) v31.RkeAddonInterface { + if mock.RkeAddonsFunc == nil { + panic("RkeAddonsGetterMock.RkeAddonsFunc: method is nil but RkeAddonsGetter.RkeAddons was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRkeAddonsGetterMockRkeAddons.Lock() + mock.calls.RkeAddons = append(mock.calls.RkeAddons, callInfo) + lockRkeAddonsGetterMockRkeAddons.Unlock() + return mock.RkeAddonsFunc(namespace) +} + +// RkeAddonsCalls gets all the calls that were made to RkeAddons. +// Check the length with: +// +// len(mockedRkeAddonsGetter.RkeAddonsCalls()) +func (mock *RkeAddonsGetterMock) RkeAddonsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRkeAddonsGetterMockRkeAddons.RLock() + calls = mock.calls.RkeAddons + lockRkeAddonsGetterMockRkeAddons.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_service_option_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_service_option_mock.go new file mode 100644 index 0000000..b669382 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_service_option_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRkeK8sServiceOptionListerMockGet sync.RWMutex + lockRkeK8sServiceOptionListerMockList sync.RWMutex +) + +// Ensure, that RkeK8sServiceOptionListerMock does implement v31.RkeK8sServiceOptionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sServiceOptionLister = &RkeK8sServiceOptionListerMock{} + +// RkeK8sServiceOptionListerMock is a mock implementation of v31.RkeK8sServiceOptionLister. +// +// func TestSomethingThatUsesRkeK8sServiceOptionLister(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sServiceOptionLister +// mockedRkeK8sServiceOptionLister := &RkeK8sServiceOptionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.RkeK8sServiceOption, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.RkeK8sServiceOption, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRkeK8sServiceOptionLister in code that requires v31.RkeK8sServiceOptionLister +// // and then make assertions. +// +// } +type RkeK8sServiceOptionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.RkeK8sServiceOption, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.RkeK8sServiceOption, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RkeK8sServiceOptionListerMock) Get(namespace string, name string) (*v3.RkeK8sServiceOption, error) { + if mock.GetFunc == nil { + panic("RkeK8sServiceOptionListerMock.GetFunc: method is nil but RkeK8sServiceOptionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeK8sServiceOptionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeK8sServiceOptionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionLister.GetCalls()) +func (mock *RkeK8sServiceOptionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeK8sServiceOptionListerMockGet.RLock() + calls = mock.calls.Get + lockRkeK8sServiceOptionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeK8sServiceOptionListerMock) List(namespace string, selector labels.Selector) ([]*v3.RkeK8sServiceOption, error) { + if mock.ListFunc == nil { + panic("RkeK8sServiceOptionListerMock.ListFunc: method is nil but RkeK8sServiceOptionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRkeK8sServiceOptionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeK8sServiceOptionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionLister.ListCalls()) +func (mock *RkeK8sServiceOptionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRkeK8sServiceOptionListerMockList.RLock() + calls = mock.calls.List + lockRkeK8sServiceOptionListerMockList.RUnlock() + return calls +} + +var ( + lockRkeK8sServiceOptionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeK8sServiceOptionControllerMockAddClusterScopedHandler sync.RWMutex + lockRkeK8sServiceOptionControllerMockAddFeatureHandler sync.RWMutex + lockRkeK8sServiceOptionControllerMockAddHandler sync.RWMutex + lockRkeK8sServiceOptionControllerMockEnqueue sync.RWMutex + lockRkeK8sServiceOptionControllerMockEnqueueAfter sync.RWMutex + lockRkeK8sServiceOptionControllerMockGeneric sync.RWMutex + lockRkeK8sServiceOptionControllerMockInformer sync.RWMutex + lockRkeK8sServiceOptionControllerMockLister sync.RWMutex +) + +// Ensure, that RkeK8sServiceOptionControllerMock does implement v31.RkeK8sServiceOptionController. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sServiceOptionController = &RkeK8sServiceOptionControllerMock{} + +// RkeK8sServiceOptionControllerMock is a mock implementation of v31.RkeK8sServiceOptionController. +// +// func TestSomethingThatUsesRkeK8sServiceOptionController(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sServiceOptionController +// mockedRkeK8sServiceOptionController := &RkeK8sServiceOptionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.RkeK8sServiceOptionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRkeK8sServiceOptionController in code that requires v31.RkeK8sServiceOptionController +// // and then make assertions. +// +// } +type RkeK8sServiceOptionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.RkeK8sServiceOptionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.RkeK8sServiceOptionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeK8sServiceOptionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeK8sServiceOptionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sServiceOptionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.RkeK8sServiceOptionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeK8sServiceOptionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeK8sServiceOptionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeK8sServiceOptionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeK8sServiceOptionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeK8sServiceOptionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeK8sServiceOptionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.AddClusterScopedHandlerFunc: method is nil but RkeK8sServiceOptionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeK8sServiceOptionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeK8sServiceOptionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.AddClusterScopedHandlerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeK8sServiceOptionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeK8sServiceOptionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.AddFeatureHandlerFunc: method is nil but RkeK8sServiceOptionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sServiceOptionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeK8sServiceOptionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.AddFeatureHandlerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeK8sServiceOptionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeK8sServiceOptionControllerMock) AddHandler(ctx context.Context, name string, handler v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.AddHandlerFunc: method is nil but RkeK8sServiceOptionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRkeK8sServiceOptionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeK8sServiceOptionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.AddHandlerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeK8sServiceOptionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RkeK8sServiceOptionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RkeK8sServiceOptionControllerMock.EnqueueFunc: method is nil but RkeK8sServiceOptionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeK8sServiceOptionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRkeK8sServiceOptionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.EnqueueCalls()) +func (mock *RkeK8sServiceOptionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeK8sServiceOptionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRkeK8sServiceOptionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RkeK8sServiceOptionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RkeK8sServiceOptionControllerMock.EnqueueAfterFunc: method is nil but RkeK8sServiceOptionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRkeK8sServiceOptionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRkeK8sServiceOptionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.EnqueueAfterCalls()) +func (mock *RkeK8sServiceOptionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRkeK8sServiceOptionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRkeK8sServiceOptionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RkeK8sServiceOptionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RkeK8sServiceOptionControllerMock.GenericFunc: method is nil but RkeK8sServiceOptionController.Generic was just called") + } + callInfo := struct { + }{} + lockRkeK8sServiceOptionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRkeK8sServiceOptionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.GenericCalls()) +func (mock *RkeK8sServiceOptionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sServiceOptionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRkeK8sServiceOptionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RkeK8sServiceOptionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.InformerFunc: method is nil but RkeK8sServiceOptionController.Informer was just called") + } + callInfo := struct { + }{} + lockRkeK8sServiceOptionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRkeK8sServiceOptionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.InformerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sServiceOptionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRkeK8sServiceOptionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RkeK8sServiceOptionControllerMock) Lister() v31.RkeK8sServiceOptionLister { + if mock.ListerFunc == nil { + panic("RkeK8sServiceOptionControllerMock.ListerFunc: method is nil but RkeK8sServiceOptionController.Lister was just called") + } + callInfo := struct { + }{} + lockRkeK8sServiceOptionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRkeK8sServiceOptionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionController.ListerCalls()) +func (mock *RkeK8sServiceOptionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sServiceOptionControllerMockLister.RLock() + calls = mock.calls.Lister + lockRkeK8sServiceOptionControllerMockLister.RUnlock() + return calls +} + +var ( + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddFeatureHandler sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddHandler sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockAddLifecycle sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockController sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockCreate sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockDelete sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockDeleteCollection sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockDeleteNamespaced sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockGet sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockGetNamespaced sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockList sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockListNamespaced sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockObjectClient sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockUpdate sync.RWMutex + lockRkeK8sServiceOptionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RkeK8sServiceOptionInterfaceMock does implement v31.RkeK8sServiceOptionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sServiceOptionInterface = &RkeK8sServiceOptionInterfaceMock{} + +// RkeK8sServiceOptionInterfaceMock is a mock implementation of v31.RkeK8sServiceOptionInterface. +// +// func TestSomethingThatUsesRkeK8sServiceOptionInterface(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sServiceOptionInterface +// mockedRkeK8sServiceOptionInterface := &RkeK8sServiceOptionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.RkeK8sServiceOptionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRkeK8sServiceOptionInterface in code that requires v31.RkeK8sServiceOptionInterface +// // and then make assertions. +// +// } +type RkeK8sServiceOptionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.RkeK8sServiceOptionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeK8sServiceOptionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeK8sServiceOptionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sServiceOptionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sServiceOptionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.RkeK8sServiceOption + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.RkeK8sServiceOption + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeK8sServiceOptionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RkeK8sServiceOptionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RkeK8sServiceOptionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddClusterScopedHandlerCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sServiceOptionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RkeK8sServiceOptionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddClusterScopedLifecycleCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRkeK8sServiceOptionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddFeatureHandlerFunc: method is nil but RkeK8sServiceOptionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sServiceOptionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddFeatureHandlerCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeK8sServiceOptionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddFeatureLifecycleFunc: method is nil but RkeK8sServiceOptionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRkeK8sServiceOptionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddFeatureLifecycleCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + lockRkeK8sServiceOptionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRkeK8sServiceOptionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.RkeK8sServiceOptionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddHandlerFunc: method is nil but RkeK8sServiceOptionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sServiceOptionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddHandlerCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.RkeK8sServiceOptionHandlerFunc + } + lockRkeK8sServiceOptionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeK8sServiceOptionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.RkeK8sServiceOptionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.AddLifecycleFunc: method is nil but RkeK8sServiceOptionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRkeK8sServiceOptionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRkeK8sServiceOptionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.AddLifecycleCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sServiceOptionLifecycle + } + lockRkeK8sServiceOptionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRkeK8sServiceOptionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Controller() v31.RkeK8sServiceOptionController { + if mock.ControllerFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.ControllerFunc: method is nil but RkeK8sServiceOptionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRkeK8sServiceOptionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRkeK8sServiceOptionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.ControllerCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sServiceOptionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRkeK8sServiceOptionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Create(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { + if mock.CreateFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.CreateFunc: method is nil but RkeK8sServiceOptionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.RkeK8sServiceOption + }{ + In1: in1, + } + lockRkeK8sServiceOptionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRkeK8sServiceOptionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.CreateCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) CreateCalls() []struct { + In1 *v3.RkeK8sServiceOption +} { + var calls []struct { + In1 *v3.RkeK8sServiceOption + } + lockRkeK8sServiceOptionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRkeK8sServiceOptionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.DeleteFunc: method is nil but RkeK8sServiceOptionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRkeK8sServiceOptionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRkeK8sServiceOptionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.DeleteCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRkeK8sServiceOptionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRkeK8sServiceOptionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.DeleteCollectionFunc: method is nil but RkeK8sServiceOptionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRkeK8sServiceOptionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRkeK8sServiceOptionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.DeleteCollectionCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRkeK8sServiceOptionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRkeK8sServiceOptionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.DeleteNamespacedFunc: method is nil but RkeK8sServiceOptionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRkeK8sServiceOptionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRkeK8sServiceOptionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.DeleteNamespacedCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRkeK8sServiceOptionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRkeK8sServiceOptionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { + if mock.GetFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.GetFunc: method is nil but RkeK8sServiceOptionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRkeK8sServiceOptionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeK8sServiceOptionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.GetCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRkeK8sServiceOptionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRkeK8sServiceOptionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { + if mock.GetNamespacedFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.GetNamespacedFunc: method is nil but RkeK8sServiceOptionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRkeK8sServiceOptionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRkeK8sServiceOptionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.GetNamespacedCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRkeK8sServiceOptionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRkeK8sServiceOptionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) List(opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { + if mock.ListFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.ListFunc: method is nil but RkeK8sServiceOptionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeK8sServiceOptionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeK8sServiceOptionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.ListCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeK8sServiceOptionInterfaceMockList.RLock() + calls = mock.calls.List + lockRkeK8sServiceOptionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { + if mock.ListNamespacedFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.ListNamespacedFunc: method is nil but RkeK8sServiceOptionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRkeK8sServiceOptionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRkeK8sServiceOptionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.ListNamespacedCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRkeK8sServiceOptionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRkeK8sServiceOptionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.ObjectClientFunc: method is nil but RkeK8sServiceOptionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRkeK8sServiceOptionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRkeK8sServiceOptionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.ObjectClientCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sServiceOptionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRkeK8sServiceOptionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Update(in1 *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { + if mock.UpdateFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.UpdateFunc: method is nil but RkeK8sServiceOptionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.RkeK8sServiceOption + }{ + In1: in1, + } + lockRkeK8sServiceOptionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRkeK8sServiceOptionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.UpdateCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) UpdateCalls() []struct { + In1 *v3.RkeK8sServiceOption +} { + var calls []struct { + In1 *v3.RkeK8sServiceOption + } + lockRkeK8sServiceOptionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRkeK8sServiceOptionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RkeK8sServiceOptionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RkeK8sServiceOptionInterfaceMock.WatchFunc: method is nil but RkeK8sServiceOptionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeK8sServiceOptionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRkeK8sServiceOptionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionInterface.WatchCalls()) +func (mock *RkeK8sServiceOptionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeK8sServiceOptionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRkeK8sServiceOptionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRkeK8sServiceOptionsGetterMockRkeK8sServiceOptions sync.RWMutex +) + +// Ensure, that RkeK8sServiceOptionsGetterMock does implement v31.RkeK8sServiceOptionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sServiceOptionsGetter = &RkeK8sServiceOptionsGetterMock{} + +// RkeK8sServiceOptionsGetterMock is a mock implementation of v31.RkeK8sServiceOptionsGetter. +// +// func TestSomethingThatUsesRkeK8sServiceOptionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sServiceOptionsGetter +// mockedRkeK8sServiceOptionsGetter := &RkeK8sServiceOptionsGetterMock{ +// RkeK8sServiceOptionsFunc: func(namespace string) v31.RkeK8sServiceOptionInterface { +// panic("mock out the RkeK8sServiceOptions method") +// }, +// } +// +// // use mockedRkeK8sServiceOptionsGetter in code that requires v31.RkeK8sServiceOptionsGetter +// // and then make assertions. +// +// } +type RkeK8sServiceOptionsGetterMock struct { + // RkeK8sServiceOptionsFunc mocks the RkeK8sServiceOptions method. + RkeK8sServiceOptionsFunc func(namespace string) v31.RkeK8sServiceOptionInterface + + // calls tracks calls to the methods. + calls struct { + // RkeK8sServiceOptions holds details about calls to the RkeK8sServiceOptions method. + RkeK8sServiceOptions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RkeK8sServiceOptions calls RkeK8sServiceOptionsFunc. +func (mock *RkeK8sServiceOptionsGetterMock) RkeK8sServiceOptions(namespace string) v31.RkeK8sServiceOptionInterface { + if mock.RkeK8sServiceOptionsFunc == nil { + panic("RkeK8sServiceOptionsGetterMock.RkeK8sServiceOptionsFunc: method is nil but RkeK8sServiceOptionsGetter.RkeK8sServiceOptions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRkeK8sServiceOptionsGetterMockRkeK8sServiceOptions.Lock() + mock.calls.RkeK8sServiceOptions = append(mock.calls.RkeK8sServiceOptions, callInfo) + lockRkeK8sServiceOptionsGetterMockRkeK8sServiceOptions.Unlock() + return mock.RkeK8sServiceOptionsFunc(namespace) +} + +// RkeK8sServiceOptionsCalls gets all the calls that were made to RkeK8sServiceOptions. +// Check the length with: +// +// len(mockedRkeK8sServiceOptionsGetter.RkeK8sServiceOptionsCalls()) +func (mock *RkeK8sServiceOptionsGetterMock) RkeK8sServiceOptionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRkeK8sServiceOptionsGetterMockRkeK8sServiceOptions.RLock() + calls = mock.calls.RkeK8sServiceOptions + lockRkeK8sServiceOptionsGetterMockRkeK8sServiceOptions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_system_image_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_system_image_mock.go new file mode 100644 index 0000000..82a5e50 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_rke_k8s_system_image_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRkeK8sSystemImageListerMockGet sync.RWMutex + lockRkeK8sSystemImageListerMockList sync.RWMutex +) + +// Ensure, that RkeK8sSystemImageListerMock does implement v31.RkeK8sSystemImageLister. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sSystemImageLister = &RkeK8sSystemImageListerMock{} + +// RkeK8sSystemImageListerMock is a mock implementation of v31.RkeK8sSystemImageLister. +// +// func TestSomethingThatUsesRkeK8sSystemImageLister(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sSystemImageLister +// mockedRkeK8sSystemImageLister := &RkeK8sSystemImageListerMock{ +// GetFunc: func(namespace string, name string) (*v3.RkeK8sSystemImage, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.RkeK8sSystemImage, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRkeK8sSystemImageLister in code that requires v31.RkeK8sSystemImageLister +// // and then make assertions. +// +// } +type RkeK8sSystemImageListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.RkeK8sSystemImage, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.RkeK8sSystemImage, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RkeK8sSystemImageListerMock) Get(namespace string, name string) (*v3.RkeK8sSystemImage, error) { + if mock.GetFunc == nil { + panic("RkeK8sSystemImageListerMock.GetFunc: method is nil but RkeK8sSystemImageLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeK8sSystemImageListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeK8sSystemImageListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeK8sSystemImageLister.GetCalls()) +func (mock *RkeK8sSystemImageListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeK8sSystemImageListerMockGet.RLock() + calls = mock.calls.Get + lockRkeK8sSystemImageListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeK8sSystemImageListerMock) List(namespace string, selector labels.Selector) ([]*v3.RkeK8sSystemImage, error) { + if mock.ListFunc == nil { + panic("RkeK8sSystemImageListerMock.ListFunc: method is nil but RkeK8sSystemImageLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRkeK8sSystemImageListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeK8sSystemImageListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeK8sSystemImageLister.ListCalls()) +func (mock *RkeK8sSystemImageListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRkeK8sSystemImageListerMockList.RLock() + calls = mock.calls.List + lockRkeK8sSystemImageListerMockList.RUnlock() + return calls +} + +var ( + lockRkeK8sSystemImageControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeK8sSystemImageControllerMockAddClusterScopedHandler sync.RWMutex + lockRkeK8sSystemImageControllerMockAddFeatureHandler sync.RWMutex + lockRkeK8sSystemImageControllerMockAddHandler sync.RWMutex + lockRkeK8sSystemImageControllerMockEnqueue sync.RWMutex + lockRkeK8sSystemImageControllerMockEnqueueAfter sync.RWMutex + lockRkeK8sSystemImageControllerMockGeneric sync.RWMutex + lockRkeK8sSystemImageControllerMockInformer sync.RWMutex + lockRkeK8sSystemImageControllerMockLister sync.RWMutex +) + +// Ensure, that RkeK8sSystemImageControllerMock does implement v31.RkeK8sSystemImageController. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sSystemImageController = &RkeK8sSystemImageControllerMock{} + +// RkeK8sSystemImageControllerMock is a mock implementation of v31.RkeK8sSystemImageController. +// +// func TestSomethingThatUsesRkeK8sSystemImageController(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sSystemImageController +// mockedRkeK8sSystemImageController := &RkeK8sSystemImageControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.RkeK8sSystemImageLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRkeK8sSystemImageController in code that requires v31.RkeK8sSystemImageController +// // and then make assertions. +// +// } +type RkeK8sSystemImageControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.RkeK8sSystemImageHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.RkeK8sSystemImageLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeK8sSystemImageHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RkeK8sSystemImageHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sSystemImageHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.RkeK8sSystemImageHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeK8sSystemImageControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeK8sSystemImageControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeK8sSystemImageController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeK8sSystemImageControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeK8sSystemImageControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeK8sSystemImageControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeK8sSystemImageControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeK8sSystemImageControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeK8sSystemImageControllerMock.AddClusterScopedHandlerFunc: method is nil but RkeK8sSystemImageController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRkeK8sSystemImageControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeK8sSystemImageControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.AddClusterScopedHandlerCalls()) +func (mock *RkeK8sSystemImageControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeK8sSystemImageControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeK8sSystemImageControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeK8sSystemImageControllerMock.AddFeatureHandlerFunc: method is nil but RkeK8sSystemImageController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sSystemImageControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeK8sSystemImageControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.AddFeatureHandlerCalls()) +func (mock *RkeK8sSystemImageControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeK8sSystemImageControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeK8sSystemImageControllerMock) AddHandler(ctx context.Context, name string, handler v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeK8sSystemImageControllerMock.AddHandlerFunc: method is nil but RkeK8sSystemImageController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRkeK8sSystemImageControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeK8sSystemImageControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.AddHandlerCalls()) +func (mock *RkeK8sSystemImageControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeK8sSystemImageControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RkeK8sSystemImageControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RkeK8sSystemImageControllerMock.EnqueueFunc: method is nil but RkeK8sSystemImageController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRkeK8sSystemImageControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRkeK8sSystemImageControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.EnqueueCalls()) +func (mock *RkeK8sSystemImageControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRkeK8sSystemImageControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRkeK8sSystemImageControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RkeK8sSystemImageControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RkeK8sSystemImageControllerMock.EnqueueAfterFunc: method is nil but RkeK8sSystemImageController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRkeK8sSystemImageControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRkeK8sSystemImageControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.EnqueueAfterCalls()) +func (mock *RkeK8sSystemImageControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRkeK8sSystemImageControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRkeK8sSystemImageControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RkeK8sSystemImageControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RkeK8sSystemImageControllerMock.GenericFunc: method is nil but RkeK8sSystemImageController.Generic was just called") + } + callInfo := struct { + }{} + lockRkeK8sSystemImageControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRkeK8sSystemImageControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.GenericCalls()) +func (mock *RkeK8sSystemImageControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sSystemImageControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRkeK8sSystemImageControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RkeK8sSystemImageControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RkeK8sSystemImageControllerMock.InformerFunc: method is nil but RkeK8sSystemImageController.Informer was just called") + } + callInfo := struct { + }{} + lockRkeK8sSystemImageControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRkeK8sSystemImageControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.InformerCalls()) +func (mock *RkeK8sSystemImageControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sSystemImageControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRkeK8sSystemImageControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RkeK8sSystemImageControllerMock) Lister() v31.RkeK8sSystemImageLister { + if mock.ListerFunc == nil { + panic("RkeK8sSystemImageControllerMock.ListerFunc: method is nil but RkeK8sSystemImageController.Lister was just called") + } + callInfo := struct { + }{} + lockRkeK8sSystemImageControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRkeK8sSystemImageControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRkeK8sSystemImageController.ListerCalls()) +func (mock *RkeK8sSystemImageControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sSystemImageControllerMockLister.RLock() + calls = mock.calls.Lister + lockRkeK8sSystemImageControllerMockLister.RUnlock() + return calls +} + +var ( + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddFeatureHandler sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddHandler sync.RWMutex + lockRkeK8sSystemImageInterfaceMockAddLifecycle sync.RWMutex + lockRkeK8sSystemImageInterfaceMockController sync.RWMutex + lockRkeK8sSystemImageInterfaceMockCreate sync.RWMutex + lockRkeK8sSystemImageInterfaceMockDelete sync.RWMutex + lockRkeK8sSystemImageInterfaceMockDeleteCollection sync.RWMutex + lockRkeK8sSystemImageInterfaceMockDeleteNamespaced sync.RWMutex + lockRkeK8sSystemImageInterfaceMockGet sync.RWMutex + lockRkeK8sSystemImageInterfaceMockGetNamespaced sync.RWMutex + lockRkeK8sSystemImageInterfaceMockList sync.RWMutex + lockRkeK8sSystemImageInterfaceMockListNamespaced sync.RWMutex + lockRkeK8sSystemImageInterfaceMockObjectClient sync.RWMutex + lockRkeK8sSystemImageInterfaceMockUpdate sync.RWMutex + lockRkeK8sSystemImageInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RkeK8sSystemImageInterfaceMock does implement v31.RkeK8sSystemImageInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sSystemImageInterface = &RkeK8sSystemImageInterfaceMock{} + +// RkeK8sSystemImageInterfaceMock is a mock implementation of v31.RkeK8sSystemImageInterface. +// +// func TestSomethingThatUsesRkeK8sSystemImageInterface(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sSystemImageInterface +// mockedRkeK8sSystemImageInterface := &RkeK8sSystemImageInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sSystemImageLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.RkeK8sSystemImageLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.RkeK8sSystemImageController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRkeK8sSystemImageInterface in code that requires v31.RkeK8sSystemImageInterface +// // and then make assertions. +// +// } +type RkeK8sSystemImageInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sSystemImageLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.RkeK8sSystemImageLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.RkeK8sSystemImageController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeK8sSystemImageHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sSystemImageLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RkeK8sSystemImageHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sSystemImageLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sSystemImageHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sSystemImageLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RkeK8sSystemImageHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RkeK8sSystemImageLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.RkeK8sSystemImage + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.RkeK8sSystemImage + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RkeK8sSystemImageInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RkeK8sSystemImageInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRkeK8sSystemImageInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RkeK8sSystemImageInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRkeK8sSystemImageInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddClusterScopedHandlerCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRkeK8sSystemImageInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.RkeK8sSystemImageLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RkeK8sSystemImageInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRkeK8sSystemImageInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddClusterScopedLifecycleCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RkeK8sSystemImageLifecycle + } + lockRkeK8sSystemImageInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRkeK8sSystemImageInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddFeatureHandlerFunc: method is nil but RkeK8sSystemImageInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sSystemImageInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRkeK8sSystemImageInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddFeatureHandlerCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRkeK8sSystemImageInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.RkeK8sSystemImageLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddFeatureLifecycleFunc: method is nil but RkeK8sSystemImageInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRkeK8sSystemImageInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRkeK8sSystemImageInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddFeatureLifecycleCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle + } + lockRkeK8sSystemImageInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRkeK8sSystemImageInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.RkeK8sSystemImageHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddHandlerFunc: method is nil but RkeK8sSystemImageInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRkeK8sSystemImageInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRkeK8sSystemImageInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddHandlerCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.RkeK8sSystemImageHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.RkeK8sSystemImageHandlerFunc + } + lockRkeK8sSystemImageInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRkeK8sSystemImageInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RkeK8sSystemImageInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.RkeK8sSystemImageLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.AddLifecycleFunc: method is nil but RkeK8sSystemImageInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRkeK8sSystemImageInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRkeK8sSystemImageInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.AddLifecycleCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.RkeK8sSystemImageLifecycle + } + lockRkeK8sSystemImageInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRkeK8sSystemImageInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Controller() v31.RkeK8sSystemImageController { + if mock.ControllerFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.ControllerFunc: method is nil but RkeK8sSystemImageInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRkeK8sSystemImageInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRkeK8sSystemImageInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.ControllerCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sSystemImageInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRkeK8sSystemImageInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Create(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { + if mock.CreateFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.CreateFunc: method is nil but RkeK8sSystemImageInterface.Create was just called") + } + callInfo := struct { + In1 *v3.RkeK8sSystemImage + }{ + In1: in1, + } + lockRkeK8sSystemImageInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRkeK8sSystemImageInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.CreateCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) CreateCalls() []struct { + In1 *v3.RkeK8sSystemImage +} { + var calls []struct { + In1 *v3.RkeK8sSystemImage + } + lockRkeK8sSystemImageInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRkeK8sSystemImageInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.DeleteFunc: method is nil but RkeK8sSystemImageInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRkeK8sSystemImageInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRkeK8sSystemImageInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.DeleteCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRkeK8sSystemImageInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRkeK8sSystemImageInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RkeK8sSystemImageInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.DeleteCollectionFunc: method is nil but RkeK8sSystemImageInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRkeK8sSystemImageInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRkeK8sSystemImageInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.DeleteCollectionCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRkeK8sSystemImageInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRkeK8sSystemImageInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RkeK8sSystemImageInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.DeleteNamespacedFunc: method is nil but RkeK8sSystemImageInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRkeK8sSystemImageInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRkeK8sSystemImageInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.DeleteNamespacedCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRkeK8sSystemImageInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRkeK8sSystemImageInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { + if mock.GetFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.GetFunc: method is nil but RkeK8sSystemImageInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRkeK8sSystemImageInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRkeK8sSystemImageInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.GetCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRkeK8sSystemImageInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRkeK8sSystemImageInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RkeK8sSystemImageInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { + if mock.GetNamespacedFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.GetNamespacedFunc: method is nil but RkeK8sSystemImageInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRkeK8sSystemImageInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRkeK8sSystemImageInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.GetNamespacedCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRkeK8sSystemImageInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRkeK8sSystemImageInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RkeK8sSystemImageInterfaceMock) List(opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { + if mock.ListFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.ListFunc: method is nil but RkeK8sSystemImageInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeK8sSystemImageInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRkeK8sSystemImageInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.ListCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeK8sSystemImageInterfaceMockList.RLock() + calls = mock.calls.List + lockRkeK8sSystemImageInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RkeK8sSystemImageInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { + if mock.ListNamespacedFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.ListNamespacedFunc: method is nil but RkeK8sSystemImageInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRkeK8sSystemImageInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRkeK8sSystemImageInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.ListNamespacedCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRkeK8sSystemImageInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRkeK8sSystemImageInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RkeK8sSystemImageInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.ObjectClientFunc: method is nil but RkeK8sSystemImageInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRkeK8sSystemImageInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRkeK8sSystemImageInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.ObjectClientCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRkeK8sSystemImageInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRkeK8sSystemImageInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Update(in1 *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { + if mock.UpdateFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.UpdateFunc: method is nil but RkeK8sSystemImageInterface.Update was just called") + } + callInfo := struct { + In1 *v3.RkeK8sSystemImage + }{ + In1: in1, + } + lockRkeK8sSystemImageInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRkeK8sSystemImageInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.UpdateCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) UpdateCalls() []struct { + In1 *v3.RkeK8sSystemImage +} { + var calls []struct { + In1 *v3.RkeK8sSystemImage + } + lockRkeK8sSystemImageInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRkeK8sSystemImageInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RkeK8sSystemImageInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RkeK8sSystemImageInterfaceMock.WatchFunc: method is nil but RkeK8sSystemImageInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRkeK8sSystemImageInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRkeK8sSystemImageInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRkeK8sSystemImageInterface.WatchCalls()) +func (mock *RkeK8sSystemImageInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRkeK8sSystemImageInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRkeK8sSystemImageInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRkeK8sSystemImagesGetterMockRkeK8sSystemImages sync.RWMutex +) + +// Ensure, that RkeK8sSystemImagesGetterMock does implement v31.RkeK8sSystemImagesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.RkeK8sSystemImagesGetter = &RkeK8sSystemImagesGetterMock{} + +// RkeK8sSystemImagesGetterMock is a mock implementation of v31.RkeK8sSystemImagesGetter. +// +// func TestSomethingThatUsesRkeK8sSystemImagesGetter(t *testing.T) { +// +// // make and configure a mocked v31.RkeK8sSystemImagesGetter +// mockedRkeK8sSystemImagesGetter := &RkeK8sSystemImagesGetterMock{ +// RkeK8sSystemImagesFunc: func(namespace string) v31.RkeK8sSystemImageInterface { +// panic("mock out the RkeK8sSystemImages method") +// }, +// } +// +// // use mockedRkeK8sSystemImagesGetter in code that requires v31.RkeK8sSystemImagesGetter +// // and then make assertions. +// +// } +type RkeK8sSystemImagesGetterMock struct { + // RkeK8sSystemImagesFunc mocks the RkeK8sSystemImages method. + RkeK8sSystemImagesFunc func(namespace string) v31.RkeK8sSystemImageInterface + + // calls tracks calls to the methods. + calls struct { + // RkeK8sSystemImages holds details about calls to the RkeK8sSystemImages method. + RkeK8sSystemImages []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RkeK8sSystemImages calls RkeK8sSystemImagesFunc. +func (mock *RkeK8sSystemImagesGetterMock) RkeK8sSystemImages(namespace string) v31.RkeK8sSystemImageInterface { + if mock.RkeK8sSystemImagesFunc == nil { + panic("RkeK8sSystemImagesGetterMock.RkeK8sSystemImagesFunc: method is nil but RkeK8sSystemImagesGetter.RkeK8sSystemImages was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRkeK8sSystemImagesGetterMockRkeK8sSystemImages.Lock() + mock.calls.RkeK8sSystemImages = append(mock.calls.RkeK8sSystemImages, callInfo) + lockRkeK8sSystemImagesGetterMockRkeK8sSystemImages.Unlock() + return mock.RkeK8sSystemImagesFunc(namespace) +} + +// RkeK8sSystemImagesCalls gets all the calls that were made to RkeK8sSystemImages. +// Check the length with: +// +// len(mockedRkeK8sSystemImagesGetter.RkeK8sSystemImagesCalls()) +func (mock *RkeK8sSystemImagesGetterMock) RkeK8sSystemImagesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRkeK8sSystemImagesGetterMockRkeK8sSystemImages.RLock() + calls = mock.calls.RkeK8sSystemImages + lockRkeK8sSystemImagesGetterMockRkeK8sSystemImages.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_role_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_role_template_mock.go new file mode 100644 index 0000000..db58afd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_role_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRoleTemplateListerMockGet sync.RWMutex + lockRoleTemplateListerMockList sync.RWMutex +) + +// Ensure, that RoleTemplateListerMock does implement v31.RoleTemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.RoleTemplateLister = &RoleTemplateListerMock{} + +// RoleTemplateListerMock is a mock implementation of v31.RoleTemplateLister. +// +// func TestSomethingThatUsesRoleTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.RoleTemplateLister +// mockedRoleTemplateLister := &RoleTemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.RoleTemplate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRoleTemplateLister in code that requires v31.RoleTemplateLister +// // and then make assertions. +// +// } +type RoleTemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.RoleTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RoleTemplateListerMock) Get(namespace string, name string) (*v3.RoleTemplate, error) { + if mock.GetFunc == nil { + panic("RoleTemplateListerMock.GetFunc: method is nil but RoleTemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleTemplateLister.GetCalls()) +func (mock *RoleTemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockRoleTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleTemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.RoleTemplate, error) { + if mock.ListFunc == nil { + panic("RoleTemplateListerMock.ListFunc: method is nil but RoleTemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRoleTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleTemplateLister.ListCalls()) +func (mock *RoleTemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRoleTemplateListerMockList.RLock() + calls = mock.calls.List + lockRoleTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockRoleTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockRoleTemplateControllerMockAddFeatureHandler sync.RWMutex + lockRoleTemplateControllerMockAddHandler sync.RWMutex + lockRoleTemplateControllerMockEnqueue sync.RWMutex + lockRoleTemplateControllerMockEnqueueAfter sync.RWMutex + lockRoleTemplateControllerMockGeneric sync.RWMutex + lockRoleTemplateControllerMockInformer sync.RWMutex + lockRoleTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that RoleTemplateControllerMock does implement v31.RoleTemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.RoleTemplateController = &RoleTemplateControllerMock{} + +// RoleTemplateControllerMock is a mock implementation of v31.RoleTemplateController. +// +// func TestSomethingThatUsesRoleTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.RoleTemplateController +// mockedRoleTemplateController := &RoleTemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.RoleTemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRoleTemplateController in code that requires v31.RoleTemplateController +// // and then make assertions. +// +// } +type RoleTemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.RoleTemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.RoleTemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RoleTemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.RoleTemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RoleTemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.RoleTemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleTemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleTemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleTemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleTemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc + } + lockRoleTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleTemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.RoleTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleTemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but RoleTemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleTemplateController.AddClusterScopedHandlerCalls()) +func (mock *RoleTemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.RoleTemplateHandlerFunc + } + lockRoleTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleTemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleTemplateControllerMock.AddFeatureHandlerFunc: method is nil but RoleTemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleTemplateController.AddFeatureHandlerCalls()) +func (mock *RoleTemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc + } + lockRoleTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleTemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.RoleTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleTemplateControllerMock.AddHandlerFunc: method is nil but RoleTemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRoleTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleTemplateController.AddHandlerCalls()) +func (mock *RoleTemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.RoleTemplateHandlerFunc + } + lockRoleTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RoleTemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RoleTemplateControllerMock.EnqueueFunc: method is nil but RoleTemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRoleTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRoleTemplateController.EnqueueCalls()) +func (mock *RoleTemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRoleTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RoleTemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RoleTemplateControllerMock.EnqueueAfterFunc: method is nil but RoleTemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRoleTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRoleTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRoleTemplateController.EnqueueAfterCalls()) +func (mock *RoleTemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRoleTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRoleTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RoleTemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RoleTemplateControllerMock.GenericFunc: method is nil but RoleTemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockRoleTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRoleTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRoleTemplateController.GenericCalls()) +func (mock *RoleTemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRoleTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRoleTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RoleTemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RoleTemplateControllerMock.InformerFunc: method is nil but RoleTemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockRoleTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRoleTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRoleTemplateController.InformerCalls()) +func (mock *RoleTemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRoleTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRoleTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RoleTemplateControllerMock) Lister() v31.RoleTemplateLister { + if mock.ListerFunc == nil { + panic("RoleTemplateControllerMock.ListerFunc: method is nil but RoleTemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockRoleTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRoleTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRoleTemplateController.ListerCalls()) +func (mock *RoleTemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRoleTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockRoleTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockRoleTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRoleTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRoleTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRoleTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockRoleTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRoleTemplateInterfaceMockAddHandler sync.RWMutex + lockRoleTemplateInterfaceMockAddLifecycle sync.RWMutex + lockRoleTemplateInterfaceMockController sync.RWMutex + lockRoleTemplateInterfaceMockCreate sync.RWMutex + lockRoleTemplateInterfaceMockDelete sync.RWMutex + lockRoleTemplateInterfaceMockDeleteCollection sync.RWMutex + lockRoleTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockRoleTemplateInterfaceMockGet sync.RWMutex + lockRoleTemplateInterfaceMockGetNamespaced sync.RWMutex + lockRoleTemplateInterfaceMockList sync.RWMutex + lockRoleTemplateInterfaceMockListNamespaced sync.RWMutex + lockRoleTemplateInterfaceMockObjectClient sync.RWMutex + lockRoleTemplateInterfaceMockUpdate sync.RWMutex + lockRoleTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RoleTemplateInterfaceMock does implement v31.RoleTemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.RoleTemplateInterface = &RoleTemplateInterfaceMock{} + +// RoleTemplateInterfaceMock is a mock implementation of v31.RoleTemplateInterface. +// +// func TestSomethingThatUsesRoleTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.RoleTemplateInterface +// mockedRoleTemplateInterface := &RoleTemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RoleTemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.RoleTemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.RoleTemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.RoleTemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.RoleTemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRoleTemplateInterface in code that requires v31.RoleTemplateInterface +// // and then make assertions. +// +// } +type RoleTemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.RoleTemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.RoleTemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.RoleTemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.RoleTemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.RoleTemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.RoleTemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RoleTemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RoleTemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.RoleTemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RoleTemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RoleTemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RoleTemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.RoleTemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.RoleTemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.RoleTemplate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.RoleTemplate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleTemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleTemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleTemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleTemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc + } + lockRoleTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RoleTemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RoleTemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RoleTemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRoleTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RoleTemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle + } + lockRoleTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRoleTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleTemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.RoleTemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleTemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RoleTemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *RoleTemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.RoleTemplateHandlerFunc + } + lockRoleTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RoleTemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.RoleTemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RoleTemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RoleTemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRoleTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *RoleTemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.RoleTemplateLifecycle + } + lockRoleTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRoleTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleTemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleTemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but RoleTemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddFeatureHandlerCalls()) +func (mock *RoleTemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.RoleTemplateHandlerFunc + } + lockRoleTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RoleTemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.RoleTemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RoleTemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but RoleTemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RoleTemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRoleTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRoleTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *RoleTemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RoleTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.RoleTemplateLifecycle + } + lockRoleTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRoleTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleTemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.RoleTemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleTemplateInterfaceMock.AddHandlerFunc: method is nil but RoleTemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.RoleTemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRoleTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddHandlerCalls()) +func (mock *RoleTemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.RoleTemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.RoleTemplateHandlerFunc + } + lockRoleTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RoleTemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.RoleTemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RoleTemplateInterfaceMock.AddLifecycleFunc: method is nil but RoleTemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.RoleTemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRoleTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRoleTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRoleTemplateInterface.AddLifecycleCalls()) +func (mock *RoleTemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.RoleTemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.RoleTemplateLifecycle + } + lockRoleTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRoleTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RoleTemplateInterfaceMock) Controller() v31.RoleTemplateController { + if mock.ControllerFunc == nil { + panic("RoleTemplateInterfaceMock.ControllerFunc: method is nil but RoleTemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRoleTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRoleTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRoleTemplateInterface.ControllerCalls()) +func (mock *RoleTemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRoleTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRoleTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RoleTemplateInterfaceMock) Create(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) { + if mock.CreateFunc == nil { + panic("RoleTemplateInterfaceMock.CreateFunc: method is nil but RoleTemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.RoleTemplate + }{ + In1: in1, + } + lockRoleTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRoleTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRoleTemplateInterface.CreateCalls()) +func (mock *RoleTemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.RoleTemplate +} { + var calls []struct { + In1 *v3.RoleTemplate + } + lockRoleTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRoleTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RoleTemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RoleTemplateInterfaceMock.DeleteFunc: method is nil but RoleTemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRoleTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRoleTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRoleTemplateInterface.DeleteCalls()) +func (mock *RoleTemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRoleTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRoleTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RoleTemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RoleTemplateInterfaceMock.DeleteCollectionFunc: method is nil but RoleTemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRoleTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRoleTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRoleTemplateInterface.DeleteCollectionCalls()) +func (mock *RoleTemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRoleTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRoleTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RoleTemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RoleTemplateInterfaceMock.DeleteNamespacedFunc: method is nil but RoleTemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRoleTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRoleTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRoleTemplateInterface.DeleteNamespacedCalls()) +func (mock *RoleTemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRoleTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRoleTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RoleTemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { + if mock.GetFunc == nil { + panic("RoleTemplateInterfaceMock.GetFunc: method is nil but RoleTemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRoleTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleTemplateInterface.GetCalls()) +func (mock *RoleTemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRoleTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRoleTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RoleTemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { + if mock.GetNamespacedFunc == nil { + panic("RoleTemplateInterfaceMock.GetNamespacedFunc: method is nil but RoleTemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRoleTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRoleTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRoleTemplateInterface.GetNamespacedCalls()) +func (mock *RoleTemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRoleTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRoleTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleTemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.RoleTemplateList, error) { + if mock.ListFunc == nil { + panic("RoleTemplateInterfaceMock.ListFunc: method is nil but RoleTemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleTemplateInterface.ListCalls()) +func (mock *RoleTemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockRoleTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RoleTemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RoleTemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("RoleTemplateInterfaceMock.ListNamespacedFunc: method is nil but RoleTemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRoleTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRoleTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRoleTemplateInterface.ListNamespacedCalls()) +func (mock *RoleTemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRoleTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRoleTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RoleTemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RoleTemplateInterfaceMock.ObjectClientFunc: method is nil but RoleTemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRoleTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRoleTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRoleTemplateInterface.ObjectClientCalls()) +func (mock *RoleTemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRoleTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRoleTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RoleTemplateInterfaceMock) Update(in1 *v3.RoleTemplate) (*v3.RoleTemplate, error) { + if mock.UpdateFunc == nil { + panic("RoleTemplateInterfaceMock.UpdateFunc: method is nil but RoleTemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.RoleTemplate + }{ + In1: in1, + } + lockRoleTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRoleTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRoleTemplateInterface.UpdateCalls()) +func (mock *RoleTemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.RoleTemplate +} { + var calls []struct { + In1 *v3.RoleTemplate + } + lockRoleTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRoleTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RoleTemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RoleTemplateInterfaceMock.WatchFunc: method is nil but RoleTemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRoleTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRoleTemplateInterface.WatchCalls()) +func (mock *RoleTemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRoleTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRoleTemplatesGetterMockRoleTemplates sync.RWMutex +) + +// Ensure, that RoleTemplatesGetterMock does implement v31.RoleTemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.RoleTemplatesGetter = &RoleTemplatesGetterMock{} + +// RoleTemplatesGetterMock is a mock implementation of v31.RoleTemplatesGetter. +// +// func TestSomethingThatUsesRoleTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.RoleTemplatesGetter +// mockedRoleTemplatesGetter := &RoleTemplatesGetterMock{ +// RoleTemplatesFunc: func(namespace string) v31.RoleTemplateInterface { +// panic("mock out the RoleTemplates method") +// }, +// } +// +// // use mockedRoleTemplatesGetter in code that requires v31.RoleTemplatesGetter +// // and then make assertions. +// +// } +type RoleTemplatesGetterMock struct { + // RoleTemplatesFunc mocks the RoleTemplates method. + RoleTemplatesFunc func(namespace string) v31.RoleTemplateInterface + + // calls tracks calls to the methods. + calls struct { + // RoleTemplates holds details about calls to the RoleTemplates method. + RoleTemplates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RoleTemplates calls RoleTemplatesFunc. +func (mock *RoleTemplatesGetterMock) RoleTemplates(namespace string) v31.RoleTemplateInterface { + if mock.RoleTemplatesFunc == nil { + panic("RoleTemplatesGetterMock.RoleTemplatesFunc: method is nil but RoleTemplatesGetter.RoleTemplates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRoleTemplatesGetterMockRoleTemplates.Lock() + mock.calls.RoleTemplates = append(mock.calls.RoleTemplates, callInfo) + lockRoleTemplatesGetterMockRoleTemplates.Unlock() + return mock.RoleTemplatesFunc(namespace) +} + +// RoleTemplatesCalls gets all the calls that were made to RoleTemplates. +// Check the length with: +// +// len(mockedRoleTemplatesGetter.RoleTemplatesCalls()) +func (mock *RoleTemplatesGetterMock) RoleTemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRoleTemplatesGetterMockRoleTemplates.RLock() + calls = mock.calls.RoleTemplates + lockRoleTemplatesGetterMockRoleTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_saml_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_saml_token_mock.go new file mode 100644 index 0000000..8ab7505 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_saml_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockSamlTokenListerMockGet sync.RWMutex + lockSamlTokenListerMockList sync.RWMutex +) + +// Ensure, that SamlTokenListerMock does implement v31.SamlTokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.SamlTokenLister = &SamlTokenListerMock{} + +// SamlTokenListerMock is a mock implementation of v31.SamlTokenLister. +// +// func TestSomethingThatUsesSamlTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.SamlTokenLister +// mockedSamlTokenLister := &SamlTokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.SamlToken, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.SamlToken, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedSamlTokenLister in code that requires v31.SamlTokenLister +// // and then make assertions. +// +// } +type SamlTokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.SamlToken, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.SamlToken, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *SamlTokenListerMock) Get(namespace string, name string) (*v3.SamlToken, error) { + if mock.GetFunc == nil { + panic("SamlTokenListerMock.GetFunc: method is nil but SamlTokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSamlTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSamlTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSamlTokenLister.GetCalls()) +func (mock *SamlTokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSamlTokenListerMockGet.RLock() + calls = mock.calls.Get + lockSamlTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SamlTokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.SamlToken, error) { + if mock.ListFunc == nil { + panic("SamlTokenListerMock.ListFunc: method is nil but SamlTokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockSamlTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSamlTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSamlTokenLister.ListCalls()) +func (mock *SamlTokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockSamlTokenListerMockList.RLock() + calls = mock.calls.List + lockSamlTokenListerMockList.RUnlock() + return calls +} + +var ( + lockSamlTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockSamlTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockSamlTokenControllerMockAddFeatureHandler sync.RWMutex + lockSamlTokenControllerMockAddHandler sync.RWMutex + lockSamlTokenControllerMockEnqueue sync.RWMutex + lockSamlTokenControllerMockEnqueueAfter sync.RWMutex + lockSamlTokenControllerMockGeneric sync.RWMutex + lockSamlTokenControllerMockInformer sync.RWMutex + lockSamlTokenControllerMockLister sync.RWMutex +) + +// Ensure, that SamlTokenControllerMock does implement v31.SamlTokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.SamlTokenController = &SamlTokenControllerMock{} + +// SamlTokenControllerMock is a mock implementation of v31.SamlTokenController. +// +// func TestSomethingThatUsesSamlTokenController(t *testing.T) { +// +// // make and configure a mocked v31.SamlTokenController +// mockedSamlTokenController := &SamlTokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SamlTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.SamlTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.SamlTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.SamlTokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedSamlTokenController in code that requires v31.SamlTokenController +// // and then make assertions. +// +// } +type SamlTokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SamlTokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.SamlTokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.SamlTokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.SamlTokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SamlTokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SamlTokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SamlTokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.SamlTokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SamlTokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SamlTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SamlTokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but SamlTokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSamlTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSamlTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSamlTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *SamlTokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc + } + lockSamlTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSamlTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SamlTokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.SamlTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SamlTokenControllerMock.AddClusterScopedHandlerFunc: method is nil but SamlTokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSamlTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSamlTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSamlTokenController.AddClusterScopedHandlerCalls()) +func (mock *SamlTokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SamlTokenHandlerFunc + } + lockSamlTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSamlTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SamlTokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SamlTokenControllerMock.AddFeatureHandlerFunc: method is nil but SamlTokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSamlTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSamlTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSamlTokenController.AddFeatureHandlerCalls()) +func (mock *SamlTokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc + } + lockSamlTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSamlTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SamlTokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.SamlTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SamlTokenControllerMock.AddHandlerFunc: method is nil but SamlTokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockSamlTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSamlTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSamlTokenController.AddHandlerCalls()) +func (mock *SamlTokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.SamlTokenHandlerFunc + } + lockSamlTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSamlTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *SamlTokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("SamlTokenControllerMock.EnqueueFunc: method is nil but SamlTokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSamlTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockSamlTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedSamlTokenController.EnqueueCalls()) +func (mock *SamlTokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSamlTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockSamlTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *SamlTokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("SamlTokenControllerMock.EnqueueAfterFunc: method is nil but SamlTokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockSamlTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockSamlTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedSamlTokenController.EnqueueAfterCalls()) +func (mock *SamlTokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockSamlTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockSamlTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *SamlTokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("SamlTokenControllerMock.GenericFunc: method is nil but SamlTokenController.Generic was just called") + } + callInfo := struct { + }{} + lockSamlTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockSamlTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedSamlTokenController.GenericCalls()) +func (mock *SamlTokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockSamlTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockSamlTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *SamlTokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("SamlTokenControllerMock.InformerFunc: method is nil but SamlTokenController.Informer was just called") + } + callInfo := struct { + }{} + lockSamlTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockSamlTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedSamlTokenController.InformerCalls()) +func (mock *SamlTokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockSamlTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockSamlTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *SamlTokenControllerMock) Lister() v31.SamlTokenLister { + if mock.ListerFunc == nil { + panic("SamlTokenControllerMock.ListerFunc: method is nil but SamlTokenController.Lister was just called") + } + callInfo := struct { + }{} + lockSamlTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockSamlTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedSamlTokenController.ListerCalls()) +func (mock *SamlTokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockSamlTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockSamlTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockSamlTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockSamlTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockSamlTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockSamlTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockSamlTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockSamlTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockSamlTokenInterfaceMockAddHandler sync.RWMutex + lockSamlTokenInterfaceMockAddLifecycle sync.RWMutex + lockSamlTokenInterfaceMockController sync.RWMutex + lockSamlTokenInterfaceMockCreate sync.RWMutex + lockSamlTokenInterfaceMockDelete sync.RWMutex + lockSamlTokenInterfaceMockDeleteCollection sync.RWMutex + lockSamlTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockSamlTokenInterfaceMockGet sync.RWMutex + lockSamlTokenInterfaceMockGetNamespaced sync.RWMutex + lockSamlTokenInterfaceMockList sync.RWMutex + lockSamlTokenInterfaceMockListNamespaced sync.RWMutex + lockSamlTokenInterfaceMockObjectClient sync.RWMutex + lockSamlTokenInterfaceMockUpdate sync.RWMutex + lockSamlTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that SamlTokenInterfaceMock does implement v31.SamlTokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.SamlTokenInterface = &SamlTokenInterfaceMock{} + +// SamlTokenInterfaceMock is a mock implementation of v31.SamlTokenInterface. +// +// func TestSomethingThatUsesSamlTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.SamlTokenInterface +// mockedSamlTokenInterface := &SamlTokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SamlTokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.SamlTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.SamlTokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.SamlTokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.SamlToken) (*v3.SamlToken, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.SamlToken, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.SamlToken, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.SamlTokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.SamlTokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.SamlToken) (*v3.SamlToken, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedSamlTokenInterface in code that requires v31.SamlTokenInterface +// // and then make assertions. +// +// } +type SamlTokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SamlTokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.SamlTokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.SamlTokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.SamlTokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.SamlToken) (*v3.SamlToken, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.SamlToken, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.SamlToken, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.SamlTokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.SamlTokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.SamlToken) (*v3.SamlToken, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SamlTokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SamlTokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SamlTokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SamlTokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SamlTokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SamlTokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SamlTokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SamlTokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.SamlToken + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.SamlToken + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SamlTokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SamlTokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but SamlTokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSamlTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSamlTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *SamlTokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc + } + lockSamlTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSamlTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *SamlTokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("SamlTokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but SamlTokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSamlTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockSamlTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *SamlTokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle + } + lockSamlTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockSamlTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SamlTokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.SamlTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SamlTokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but SamlTokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSamlTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSamlTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *SamlTokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SamlTokenHandlerFunc + } + lockSamlTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSamlTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *SamlTokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.SamlTokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("SamlTokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but SamlTokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSamlTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockSamlTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *SamlTokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SamlTokenLifecycle + } + lockSamlTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockSamlTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SamlTokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SamlTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SamlTokenInterfaceMock.AddFeatureHandlerFunc: method is nil but SamlTokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSamlTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSamlTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddFeatureHandlerCalls()) +func (mock *SamlTokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SamlTokenHandlerFunc + } + lockSamlTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSamlTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *SamlTokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.SamlTokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("SamlTokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but SamlTokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SamlTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockSamlTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockSamlTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddFeatureLifecycleCalls()) +func (mock *SamlTokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SamlTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SamlTokenLifecycle + } + lockSamlTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockSamlTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SamlTokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.SamlTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SamlTokenInterfaceMock.AddHandlerFunc: method is nil but SamlTokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.SamlTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockSamlTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSamlTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddHandlerCalls()) +func (mock *SamlTokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.SamlTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.SamlTokenHandlerFunc + } + lockSamlTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSamlTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *SamlTokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.SamlTokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("SamlTokenInterfaceMock.AddLifecycleFunc: method is nil but SamlTokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.SamlTokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockSamlTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockSamlTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedSamlTokenInterface.AddLifecycleCalls()) +func (mock *SamlTokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.SamlTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.SamlTokenLifecycle + } + lockSamlTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockSamlTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *SamlTokenInterfaceMock) Controller() v31.SamlTokenController { + if mock.ControllerFunc == nil { + panic("SamlTokenInterfaceMock.ControllerFunc: method is nil but SamlTokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockSamlTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockSamlTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedSamlTokenInterface.ControllerCalls()) +func (mock *SamlTokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockSamlTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockSamlTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *SamlTokenInterfaceMock) Create(in1 *v3.SamlToken) (*v3.SamlToken, error) { + if mock.CreateFunc == nil { + panic("SamlTokenInterfaceMock.CreateFunc: method is nil but SamlTokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.SamlToken + }{ + In1: in1, + } + lockSamlTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockSamlTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedSamlTokenInterface.CreateCalls()) +func (mock *SamlTokenInterfaceMock) CreateCalls() []struct { + In1 *v3.SamlToken +} { + var calls []struct { + In1 *v3.SamlToken + } + lockSamlTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockSamlTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *SamlTokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("SamlTokenInterfaceMock.DeleteFunc: method is nil but SamlTokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockSamlTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockSamlTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedSamlTokenInterface.DeleteCalls()) +func (mock *SamlTokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockSamlTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockSamlTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *SamlTokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("SamlTokenInterfaceMock.DeleteCollectionFunc: method is nil but SamlTokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockSamlTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockSamlTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedSamlTokenInterface.DeleteCollectionCalls()) +func (mock *SamlTokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockSamlTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockSamlTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *SamlTokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("SamlTokenInterfaceMock.DeleteNamespacedFunc: method is nil but SamlTokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockSamlTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockSamlTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedSamlTokenInterface.DeleteNamespacedCalls()) +func (mock *SamlTokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockSamlTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockSamlTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *SamlTokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.SamlToken, error) { + if mock.GetFunc == nil { + panic("SamlTokenInterfaceMock.GetFunc: method is nil but SamlTokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockSamlTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSamlTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSamlTokenInterface.GetCalls()) +func (mock *SamlTokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockSamlTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockSamlTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *SamlTokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.SamlToken, error) { + if mock.GetNamespacedFunc == nil { + panic("SamlTokenInterfaceMock.GetNamespacedFunc: method is nil but SamlTokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockSamlTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockSamlTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedSamlTokenInterface.GetNamespacedCalls()) +func (mock *SamlTokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockSamlTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockSamlTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SamlTokenInterfaceMock) List(opts metav1.ListOptions) (*v3.SamlTokenList, error) { + if mock.ListFunc == nil { + panic("SamlTokenInterfaceMock.ListFunc: method is nil but SamlTokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSamlTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSamlTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSamlTokenInterface.ListCalls()) +func (mock *SamlTokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSamlTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockSamlTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *SamlTokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SamlTokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("SamlTokenInterfaceMock.ListNamespacedFunc: method is nil but SamlTokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockSamlTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockSamlTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedSamlTokenInterface.ListNamespacedCalls()) +func (mock *SamlTokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockSamlTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockSamlTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *SamlTokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("SamlTokenInterfaceMock.ObjectClientFunc: method is nil but SamlTokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockSamlTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockSamlTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedSamlTokenInterface.ObjectClientCalls()) +func (mock *SamlTokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockSamlTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockSamlTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *SamlTokenInterfaceMock) Update(in1 *v3.SamlToken) (*v3.SamlToken, error) { + if mock.UpdateFunc == nil { + panic("SamlTokenInterfaceMock.UpdateFunc: method is nil but SamlTokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.SamlToken + }{ + In1: in1, + } + lockSamlTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockSamlTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedSamlTokenInterface.UpdateCalls()) +func (mock *SamlTokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.SamlToken +} { + var calls []struct { + In1 *v3.SamlToken + } + lockSamlTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockSamlTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *SamlTokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("SamlTokenInterfaceMock.WatchFunc: method is nil but SamlTokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSamlTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockSamlTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedSamlTokenInterface.WatchCalls()) +func (mock *SamlTokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSamlTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockSamlTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockSamlTokensGetterMockSamlTokens sync.RWMutex +) + +// Ensure, that SamlTokensGetterMock does implement v31.SamlTokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.SamlTokensGetter = &SamlTokensGetterMock{} + +// SamlTokensGetterMock is a mock implementation of v31.SamlTokensGetter. +// +// func TestSomethingThatUsesSamlTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.SamlTokensGetter +// mockedSamlTokensGetter := &SamlTokensGetterMock{ +// SamlTokensFunc: func(namespace string) v31.SamlTokenInterface { +// panic("mock out the SamlTokens method") +// }, +// } +// +// // use mockedSamlTokensGetter in code that requires v31.SamlTokensGetter +// // and then make assertions. +// +// } +type SamlTokensGetterMock struct { + // SamlTokensFunc mocks the SamlTokens method. + SamlTokensFunc func(namespace string) v31.SamlTokenInterface + + // calls tracks calls to the methods. + calls struct { + // SamlTokens holds details about calls to the SamlTokens method. + SamlTokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// SamlTokens calls SamlTokensFunc. +func (mock *SamlTokensGetterMock) SamlTokens(namespace string) v31.SamlTokenInterface { + if mock.SamlTokensFunc == nil { + panic("SamlTokensGetterMock.SamlTokensFunc: method is nil but SamlTokensGetter.SamlTokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockSamlTokensGetterMockSamlTokens.Lock() + mock.calls.SamlTokens = append(mock.calls.SamlTokens, callInfo) + lockSamlTokensGetterMockSamlTokens.Unlock() + return mock.SamlTokensFunc(namespace) +} + +// SamlTokensCalls gets all the calls that were made to SamlTokens. +// Check the length with: +// +// len(mockedSamlTokensGetter.SamlTokensCalls()) +func (mock *SamlTokensGetterMock) SamlTokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockSamlTokensGetterMockSamlTokens.RLock() + calls = mock.calls.SamlTokens + lockSamlTokensGetterMockSamlTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_setting_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_setting_mock.go new file mode 100644 index 0000000..099bef1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_setting_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockSettingListerMockGet sync.RWMutex + lockSettingListerMockList sync.RWMutex +) + +// Ensure, that SettingListerMock does implement v31.SettingLister. +// If this is not the case, regenerate this file with moq. +var _ v31.SettingLister = &SettingListerMock{} + +// SettingListerMock is a mock implementation of v31.SettingLister. +// +// func TestSomethingThatUsesSettingLister(t *testing.T) { +// +// // make and configure a mocked v31.SettingLister +// mockedSettingLister := &SettingListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Setting, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Setting, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedSettingLister in code that requires v31.SettingLister +// // and then make assertions. +// +// } +type SettingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Setting, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Setting, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *SettingListerMock) Get(namespace string, name string) (*v3.Setting, error) { + if mock.GetFunc == nil { + panic("SettingListerMock.GetFunc: method is nil but SettingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSettingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSettingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSettingLister.GetCalls()) +func (mock *SettingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSettingListerMockGet.RLock() + calls = mock.calls.Get + lockSettingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SettingListerMock) List(namespace string, selector labels.Selector) ([]*v3.Setting, error) { + if mock.ListFunc == nil { + panic("SettingListerMock.ListFunc: method is nil but SettingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockSettingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSettingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSettingLister.ListCalls()) +func (mock *SettingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockSettingListerMockList.RLock() + calls = mock.calls.List + lockSettingListerMockList.RUnlock() + return calls +} + +var ( + lockSettingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockSettingControllerMockAddClusterScopedHandler sync.RWMutex + lockSettingControllerMockAddFeatureHandler sync.RWMutex + lockSettingControllerMockAddHandler sync.RWMutex + lockSettingControllerMockEnqueue sync.RWMutex + lockSettingControllerMockEnqueueAfter sync.RWMutex + lockSettingControllerMockGeneric sync.RWMutex + lockSettingControllerMockInformer sync.RWMutex + lockSettingControllerMockLister sync.RWMutex +) + +// Ensure, that SettingControllerMock does implement v31.SettingController. +// If this is not the case, regenerate this file with moq. +var _ v31.SettingController = &SettingControllerMock{} + +// SettingControllerMock is a mock implementation of v31.SettingController. +// +// func TestSomethingThatUsesSettingController(t *testing.T) { +// +// // make and configure a mocked v31.SettingController +// mockedSettingController := &SettingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SettingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.SettingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.SettingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.SettingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedSettingController in code that requires v31.SettingController +// // and then make assertions. +// +// } +type SettingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SettingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.SettingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.SettingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.SettingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SettingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SettingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SettingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.SettingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SettingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SettingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SettingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but SettingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SettingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSettingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSettingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSettingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *SettingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SettingHandlerFunc + } + lockSettingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSettingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SettingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.SettingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SettingControllerMock.AddClusterScopedHandlerFunc: method is nil but SettingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SettingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSettingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSettingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSettingController.AddClusterScopedHandlerCalls()) +func (mock *SettingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SettingHandlerFunc + } + lockSettingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSettingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SettingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SettingControllerMock.AddFeatureHandlerFunc: method is nil but SettingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSettingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSettingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSettingController.AddFeatureHandlerCalls()) +func (mock *SettingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc + } + lockSettingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSettingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SettingControllerMock) AddHandler(ctx context.Context, name string, handler v31.SettingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SettingControllerMock.AddHandlerFunc: method is nil but SettingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.SettingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockSettingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSettingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSettingController.AddHandlerCalls()) +func (mock *SettingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.SettingHandlerFunc + } + lockSettingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSettingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *SettingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("SettingControllerMock.EnqueueFunc: method is nil but SettingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSettingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockSettingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedSettingController.EnqueueCalls()) +func (mock *SettingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSettingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockSettingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *SettingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("SettingControllerMock.EnqueueAfterFunc: method is nil but SettingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockSettingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockSettingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedSettingController.EnqueueAfterCalls()) +func (mock *SettingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockSettingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockSettingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *SettingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("SettingControllerMock.GenericFunc: method is nil but SettingController.Generic was just called") + } + callInfo := struct { + }{} + lockSettingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockSettingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedSettingController.GenericCalls()) +func (mock *SettingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockSettingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockSettingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *SettingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("SettingControllerMock.InformerFunc: method is nil but SettingController.Informer was just called") + } + callInfo := struct { + }{} + lockSettingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockSettingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedSettingController.InformerCalls()) +func (mock *SettingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockSettingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockSettingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *SettingControllerMock) Lister() v31.SettingLister { + if mock.ListerFunc == nil { + panic("SettingControllerMock.ListerFunc: method is nil but SettingController.Lister was just called") + } + callInfo := struct { + }{} + lockSettingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockSettingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedSettingController.ListerCalls()) +func (mock *SettingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockSettingControllerMockLister.RLock() + calls = mock.calls.Lister + lockSettingControllerMockLister.RUnlock() + return calls +} + +var ( + lockSettingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockSettingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockSettingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockSettingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockSettingInterfaceMockAddFeatureHandler sync.RWMutex + lockSettingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockSettingInterfaceMockAddHandler sync.RWMutex + lockSettingInterfaceMockAddLifecycle sync.RWMutex + lockSettingInterfaceMockController sync.RWMutex + lockSettingInterfaceMockCreate sync.RWMutex + lockSettingInterfaceMockDelete sync.RWMutex + lockSettingInterfaceMockDeleteCollection sync.RWMutex + lockSettingInterfaceMockDeleteNamespaced sync.RWMutex + lockSettingInterfaceMockGet sync.RWMutex + lockSettingInterfaceMockGetNamespaced sync.RWMutex + lockSettingInterfaceMockList sync.RWMutex + lockSettingInterfaceMockListNamespaced sync.RWMutex + lockSettingInterfaceMockObjectClient sync.RWMutex + lockSettingInterfaceMockUpdate sync.RWMutex + lockSettingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that SettingInterfaceMock does implement v31.SettingInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.SettingInterface = &SettingInterfaceMock{} + +// SettingInterfaceMock is a mock implementation of v31.SettingInterface. +// +// func TestSomethingThatUsesSettingInterface(t *testing.T) { +// +// // make and configure a mocked v31.SettingInterface +// mockedSettingInterface := &SettingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SettingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.SettingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SettingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.SettingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.SettingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.SettingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Setting) (*v3.Setting, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Setting, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Setting, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.SettingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.SettingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Setting) (*v3.Setting, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedSettingInterface in code that requires v31.SettingInterface +// // and then make assertions. +// +// } +type SettingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SettingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.SettingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SettingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.SettingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.SettingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.SettingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Setting) (*v3.Setting, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Setting, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Setting, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.SettingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.SettingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Setting) (*v3.Setting, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SettingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SettingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SettingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SettingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SettingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SettingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SettingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SettingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Setting + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Setting + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SettingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SettingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but SettingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SettingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSettingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSettingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSettingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *SettingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SettingHandlerFunc + } + lockSettingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSettingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *SettingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SettingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("SettingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but SettingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SettingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSettingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockSettingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedSettingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *SettingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SettingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SettingLifecycle + } + lockSettingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockSettingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SettingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.SettingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SettingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but SettingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SettingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSettingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSettingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSettingInterface.AddClusterScopedHandlerCalls()) +func (mock *SettingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SettingHandlerFunc + } + lockSettingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSettingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *SettingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.SettingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("SettingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but SettingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SettingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSettingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockSettingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedSettingInterface.AddClusterScopedLifecycleCalls()) +func (mock *SettingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SettingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SettingLifecycle + } + lockSettingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockSettingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SettingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SettingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SettingInterfaceMock.AddFeatureHandlerFunc: method is nil but SettingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSettingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSettingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSettingInterface.AddFeatureHandlerCalls()) +func (mock *SettingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SettingHandlerFunc + } + lockSettingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSettingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *SettingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.SettingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("SettingInterfaceMock.AddFeatureLifecycleFunc: method is nil but SettingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SettingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockSettingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockSettingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedSettingInterface.AddFeatureLifecycleCalls()) +func (mock *SettingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SettingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SettingLifecycle + } + lockSettingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockSettingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SettingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.SettingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SettingInterfaceMock.AddHandlerFunc: method is nil but SettingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.SettingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockSettingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSettingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSettingInterface.AddHandlerCalls()) +func (mock *SettingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.SettingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.SettingHandlerFunc + } + lockSettingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSettingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *SettingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.SettingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("SettingInterfaceMock.AddLifecycleFunc: method is nil but SettingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.SettingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockSettingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockSettingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedSettingInterface.AddLifecycleCalls()) +func (mock *SettingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.SettingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.SettingLifecycle + } + lockSettingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockSettingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *SettingInterfaceMock) Controller() v31.SettingController { + if mock.ControllerFunc == nil { + panic("SettingInterfaceMock.ControllerFunc: method is nil but SettingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockSettingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockSettingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedSettingInterface.ControllerCalls()) +func (mock *SettingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockSettingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockSettingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *SettingInterfaceMock) Create(in1 *v3.Setting) (*v3.Setting, error) { + if mock.CreateFunc == nil { + panic("SettingInterfaceMock.CreateFunc: method is nil but SettingInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Setting + }{ + In1: in1, + } + lockSettingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockSettingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedSettingInterface.CreateCalls()) +func (mock *SettingInterfaceMock) CreateCalls() []struct { + In1 *v3.Setting +} { + var calls []struct { + In1 *v3.Setting + } + lockSettingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockSettingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *SettingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("SettingInterfaceMock.DeleteFunc: method is nil but SettingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockSettingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockSettingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedSettingInterface.DeleteCalls()) +func (mock *SettingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockSettingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockSettingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *SettingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("SettingInterfaceMock.DeleteCollectionFunc: method is nil but SettingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockSettingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockSettingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedSettingInterface.DeleteCollectionCalls()) +func (mock *SettingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockSettingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockSettingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *SettingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("SettingInterfaceMock.DeleteNamespacedFunc: method is nil but SettingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockSettingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockSettingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedSettingInterface.DeleteNamespacedCalls()) +func (mock *SettingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockSettingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockSettingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *SettingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Setting, error) { + if mock.GetFunc == nil { + panic("SettingInterfaceMock.GetFunc: method is nil but SettingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockSettingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSettingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSettingInterface.GetCalls()) +func (mock *SettingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockSettingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockSettingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *SettingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Setting, error) { + if mock.GetNamespacedFunc == nil { + panic("SettingInterfaceMock.GetNamespacedFunc: method is nil but SettingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockSettingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockSettingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedSettingInterface.GetNamespacedCalls()) +func (mock *SettingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockSettingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockSettingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SettingInterfaceMock) List(opts metav1.ListOptions) (*v3.SettingList, error) { + if mock.ListFunc == nil { + panic("SettingInterfaceMock.ListFunc: method is nil but SettingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSettingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSettingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSettingInterface.ListCalls()) +func (mock *SettingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSettingInterfaceMockList.RLock() + calls = mock.calls.List + lockSettingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *SettingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SettingList, error) { + if mock.ListNamespacedFunc == nil { + panic("SettingInterfaceMock.ListNamespacedFunc: method is nil but SettingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockSettingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockSettingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedSettingInterface.ListNamespacedCalls()) +func (mock *SettingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockSettingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockSettingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *SettingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("SettingInterfaceMock.ObjectClientFunc: method is nil but SettingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockSettingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockSettingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedSettingInterface.ObjectClientCalls()) +func (mock *SettingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockSettingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockSettingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *SettingInterfaceMock) Update(in1 *v3.Setting) (*v3.Setting, error) { + if mock.UpdateFunc == nil { + panic("SettingInterfaceMock.UpdateFunc: method is nil but SettingInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Setting + }{ + In1: in1, + } + lockSettingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockSettingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedSettingInterface.UpdateCalls()) +func (mock *SettingInterfaceMock) UpdateCalls() []struct { + In1 *v3.Setting +} { + var calls []struct { + In1 *v3.Setting + } + lockSettingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockSettingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *SettingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("SettingInterfaceMock.WatchFunc: method is nil but SettingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSettingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockSettingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedSettingInterface.WatchCalls()) +func (mock *SettingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSettingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockSettingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockSettingsGetterMockSettings sync.RWMutex +) + +// Ensure, that SettingsGetterMock does implement v31.SettingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.SettingsGetter = &SettingsGetterMock{} + +// SettingsGetterMock is a mock implementation of v31.SettingsGetter. +// +// func TestSomethingThatUsesSettingsGetter(t *testing.T) { +// +// // make and configure a mocked v31.SettingsGetter +// mockedSettingsGetter := &SettingsGetterMock{ +// SettingsFunc: func(namespace string) v31.SettingInterface { +// panic("mock out the Settings method") +// }, +// } +// +// // use mockedSettingsGetter in code that requires v31.SettingsGetter +// // and then make assertions. +// +// } +type SettingsGetterMock struct { + // SettingsFunc mocks the Settings method. + SettingsFunc func(namespace string) v31.SettingInterface + + // calls tracks calls to the methods. + calls struct { + // Settings holds details about calls to the Settings method. + Settings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Settings calls SettingsFunc. +func (mock *SettingsGetterMock) Settings(namespace string) v31.SettingInterface { + if mock.SettingsFunc == nil { + panic("SettingsGetterMock.SettingsFunc: method is nil but SettingsGetter.Settings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockSettingsGetterMockSettings.Lock() + mock.calls.Settings = append(mock.calls.Settings, callInfo) + lockSettingsGetterMockSettings.Unlock() + return mock.SettingsFunc(namespace) +} + +// SettingsCalls gets all the calls that were made to Settings. +// Check the length with: +// +// len(mockedSettingsGetter.SettingsCalls()) +func (mock *SettingsGetterMock) SettingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockSettingsGetterMockSettings.RLock() + calls = mock.calls.Settings + lockSettingsGetterMockSettings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_content_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_content_mock.go new file mode 100644 index 0000000..ee7d901 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_content_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockTemplateContentListerMockGet sync.RWMutex + lockTemplateContentListerMockList sync.RWMutex +) + +// Ensure, that TemplateContentListerMock does implement v31.TemplateContentLister. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateContentLister = &TemplateContentListerMock{} + +// TemplateContentListerMock is a mock implementation of v31.TemplateContentLister. +// +// func TestSomethingThatUsesTemplateContentLister(t *testing.T) { +// +// // make and configure a mocked v31.TemplateContentLister +// mockedTemplateContentLister := &TemplateContentListerMock{ +// GetFunc: func(namespace string, name string) (*v3.TemplateContent, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.TemplateContent, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedTemplateContentLister in code that requires v31.TemplateContentLister +// // and then make assertions. +// +// } +type TemplateContentListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.TemplateContent, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.TemplateContent, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *TemplateContentListerMock) Get(namespace string, name string) (*v3.TemplateContent, error) { + if mock.GetFunc == nil { + panic("TemplateContentListerMock.GetFunc: method is nil but TemplateContentLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateContentListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateContentListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateContentLister.GetCalls()) +func (mock *TemplateContentListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateContentListerMockGet.RLock() + calls = mock.calls.Get + lockTemplateContentListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateContentListerMock) List(namespace string, selector labels.Selector) ([]*v3.TemplateContent, error) { + if mock.ListFunc == nil { + panic("TemplateContentListerMock.ListFunc: method is nil but TemplateContentLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockTemplateContentListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateContentListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateContentLister.ListCalls()) +func (mock *TemplateContentListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockTemplateContentListerMockList.RLock() + calls = mock.calls.List + lockTemplateContentListerMockList.RUnlock() + return calls +} + +var ( + lockTemplateContentControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateContentControllerMockAddClusterScopedHandler sync.RWMutex + lockTemplateContentControllerMockAddFeatureHandler sync.RWMutex + lockTemplateContentControllerMockAddHandler sync.RWMutex + lockTemplateContentControllerMockEnqueue sync.RWMutex + lockTemplateContentControllerMockEnqueueAfter sync.RWMutex + lockTemplateContentControllerMockGeneric sync.RWMutex + lockTemplateContentControllerMockInformer sync.RWMutex + lockTemplateContentControllerMockLister sync.RWMutex +) + +// Ensure, that TemplateContentControllerMock does implement v31.TemplateContentController. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateContentController = &TemplateContentControllerMock{} + +// TemplateContentControllerMock is a mock implementation of v31.TemplateContentController. +// +// func TestSomethingThatUsesTemplateContentController(t *testing.T) { +// +// // make and configure a mocked v31.TemplateContentController +// mockedTemplateContentController := &TemplateContentControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateContentHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.TemplateContentHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.TemplateContentHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.TemplateContentLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedTemplateContentController in code that requires v31.TemplateContentController +// // and then make assertions. +// +// } +type TemplateContentControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateContentHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.TemplateContentHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.TemplateContentHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.TemplateContentLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateContentHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateContentHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateContentHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.TemplateContentHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateContentControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateContentHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateContentControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateContentController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateContentControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateContentControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateContentController.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateContentControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc + } + lockTemplateContentControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateContentControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateContentControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.TemplateContentHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateContentControllerMock.AddClusterScopedHandlerFunc: method is nil but TemplateContentController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateContentControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateContentControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateContentController.AddClusterScopedHandlerCalls()) +func (mock *TemplateContentControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateContentHandlerFunc + } + lockTemplateContentControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateContentControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateContentControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateContentControllerMock.AddFeatureHandlerFunc: method is nil but TemplateContentController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateContentControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateContentControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateContentController.AddFeatureHandlerCalls()) +func (mock *TemplateContentControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc + } + lockTemplateContentControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateContentControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateContentControllerMock) AddHandler(ctx context.Context, name string, handler v31.TemplateContentHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateContentControllerMock.AddHandlerFunc: method is nil but TemplateContentController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockTemplateContentControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateContentControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateContentController.AddHandlerCalls()) +func (mock *TemplateContentControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.TemplateContentHandlerFunc + } + lockTemplateContentControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateContentControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *TemplateContentControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("TemplateContentControllerMock.EnqueueFunc: method is nil but TemplateContentController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateContentControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockTemplateContentControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedTemplateContentController.EnqueueCalls()) +func (mock *TemplateContentControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateContentControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockTemplateContentControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *TemplateContentControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("TemplateContentControllerMock.EnqueueAfterFunc: method is nil but TemplateContentController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockTemplateContentControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockTemplateContentControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedTemplateContentController.EnqueueAfterCalls()) +func (mock *TemplateContentControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockTemplateContentControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockTemplateContentControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *TemplateContentControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("TemplateContentControllerMock.GenericFunc: method is nil but TemplateContentController.Generic was just called") + } + callInfo := struct { + }{} + lockTemplateContentControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockTemplateContentControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedTemplateContentController.GenericCalls()) +func (mock *TemplateContentControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockTemplateContentControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockTemplateContentControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *TemplateContentControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("TemplateContentControllerMock.InformerFunc: method is nil but TemplateContentController.Informer was just called") + } + callInfo := struct { + }{} + lockTemplateContentControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockTemplateContentControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedTemplateContentController.InformerCalls()) +func (mock *TemplateContentControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockTemplateContentControllerMockInformer.RLock() + calls = mock.calls.Informer + lockTemplateContentControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *TemplateContentControllerMock) Lister() v31.TemplateContentLister { + if mock.ListerFunc == nil { + panic("TemplateContentControllerMock.ListerFunc: method is nil but TemplateContentController.Lister was just called") + } + callInfo := struct { + }{} + lockTemplateContentControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockTemplateContentControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedTemplateContentController.ListerCalls()) +func (mock *TemplateContentControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockTemplateContentControllerMockLister.RLock() + calls = mock.calls.Lister + lockTemplateContentControllerMockLister.RUnlock() + return calls +} + +var ( + lockTemplateContentInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateContentInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockTemplateContentInterfaceMockAddClusterScopedHandler sync.RWMutex + lockTemplateContentInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockTemplateContentInterfaceMockAddFeatureHandler sync.RWMutex + lockTemplateContentInterfaceMockAddFeatureLifecycle sync.RWMutex + lockTemplateContentInterfaceMockAddHandler sync.RWMutex + lockTemplateContentInterfaceMockAddLifecycle sync.RWMutex + lockTemplateContentInterfaceMockController sync.RWMutex + lockTemplateContentInterfaceMockCreate sync.RWMutex + lockTemplateContentInterfaceMockDelete sync.RWMutex + lockTemplateContentInterfaceMockDeleteCollection sync.RWMutex + lockTemplateContentInterfaceMockDeleteNamespaced sync.RWMutex + lockTemplateContentInterfaceMockGet sync.RWMutex + lockTemplateContentInterfaceMockGetNamespaced sync.RWMutex + lockTemplateContentInterfaceMockList sync.RWMutex + lockTemplateContentInterfaceMockListNamespaced sync.RWMutex + lockTemplateContentInterfaceMockObjectClient sync.RWMutex + lockTemplateContentInterfaceMockUpdate sync.RWMutex + lockTemplateContentInterfaceMockWatch sync.RWMutex +) + +// Ensure, that TemplateContentInterfaceMock does implement v31.TemplateContentInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateContentInterface = &TemplateContentInterfaceMock{} + +// TemplateContentInterfaceMock is a mock implementation of v31.TemplateContentInterface. +// +// func TestSomethingThatUsesTemplateContentInterface(t *testing.T) { +// +// // make and configure a mocked v31.TemplateContentInterface +// mockedTemplateContentInterface := &TemplateContentInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateContentLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.TemplateContentHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.TemplateContentLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.TemplateContentController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.TemplateContent) (*v3.TemplateContent, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.TemplateContentList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.TemplateContentList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.TemplateContent) (*v3.TemplateContent, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedTemplateContentInterface in code that requires v31.TemplateContentInterface +// // and then make assertions. +// +// } +type TemplateContentInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateContentLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.TemplateContentHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.TemplateContentLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.TemplateContentController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.TemplateContent) (*v3.TemplateContent, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.TemplateContent, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateContent, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.TemplateContentList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.TemplateContentList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.TemplateContent) (*v3.TemplateContent, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateContentHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateContentLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateContentHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateContentLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateContentHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateContentLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateContentHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateContentLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.TemplateContent + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.TemplateContent + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateContentInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateContentInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateContentInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateContentInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateContentInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateContentInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc + } + lockTemplateContentInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateContentInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *TemplateContentInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("TemplateContentInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but TemplateContentInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateContentInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockTemplateContentInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *TemplateContentInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle + } + lockTemplateContentInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockTemplateContentInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateContentInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateContentHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateContentInterfaceMock.AddClusterScopedHandlerFunc: method is nil but TemplateContentInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateContentInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateContentInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddClusterScopedHandlerCalls()) +func (mock *TemplateContentInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateContentHandlerFunc + } + lockTemplateContentInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateContentInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *TemplateContentInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateContentLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("TemplateContentInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but TemplateContentInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateContentInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockTemplateContentInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddClusterScopedLifecycleCalls()) +func (mock *TemplateContentInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateContentLifecycle + } + lockTemplateContentInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockTemplateContentInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateContentInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateContentHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateContentInterfaceMock.AddFeatureHandlerFunc: method is nil but TemplateContentInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateContentInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateContentInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddFeatureHandlerCalls()) +func (mock *TemplateContentInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateContentHandlerFunc + } + lockTemplateContentInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateContentInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *TemplateContentInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateContentLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("TemplateContentInterfaceMock.AddFeatureLifecycleFunc: method is nil but TemplateContentInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateContentLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateContentInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockTemplateContentInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddFeatureLifecycleCalls()) +func (mock *TemplateContentInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateContentLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateContentLifecycle + } + lockTemplateContentInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockTemplateContentInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateContentInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.TemplateContentHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateContentInterfaceMock.AddHandlerFunc: method is nil but TemplateContentInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.TemplateContentHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockTemplateContentInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateContentInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddHandlerCalls()) +func (mock *TemplateContentInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.TemplateContentHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.TemplateContentHandlerFunc + } + lockTemplateContentInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateContentInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *TemplateContentInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.TemplateContentLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("TemplateContentInterfaceMock.AddLifecycleFunc: method is nil but TemplateContentInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateContentLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateContentInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockTemplateContentInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedTemplateContentInterface.AddLifecycleCalls()) +func (mock *TemplateContentInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateContentLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateContentLifecycle + } + lockTemplateContentInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockTemplateContentInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *TemplateContentInterfaceMock) Controller() v31.TemplateContentController { + if mock.ControllerFunc == nil { + panic("TemplateContentInterfaceMock.ControllerFunc: method is nil but TemplateContentInterface.Controller was just called") + } + callInfo := struct { + }{} + lockTemplateContentInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockTemplateContentInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedTemplateContentInterface.ControllerCalls()) +func (mock *TemplateContentInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockTemplateContentInterfaceMockController.RLock() + calls = mock.calls.Controller + lockTemplateContentInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *TemplateContentInterfaceMock) Create(in1 *v3.TemplateContent) (*v3.TemplateContent, error) { + if mock.CreateFunc == nil { + panic("TemplateContentInterfaceMock.CreateFunc: method is nil but TemplateContentInterface.Create was just called") + } + callInfo := struct { + In1 *v3.TemplateContent + }{ + In1: in1, + } + lockTemplateContentInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockTemplateContentInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedTemplateContentInterface.CreateCalls()) +func (mock *TemplateContentInterfaceMock) CreateCalls() []struct { + In1 *v3.TemplateContent +} { + var calls []struct { + In1 *v3.TemplateContent + } + lockTemplateContentInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockTemplateContentInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *TemplateContentInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("TemplateContentInterfaceMock.DeleteFunc: method is nil but TemplateContentInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockTemplateContentInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockTemplateContentInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedTemplateContentInterface.DeleteCalls()) +func (mock *TemplateContentInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockTemplateContentInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockTemplateContentInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *TemplateContentInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("TemplateContentInterfaceMock.DeleteCollectionFunc: method is nil but TemplateContentInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockTemplateContentInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockTemplateContentInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedTemplateContentInterface.DeleteCollectionCalls()) +func (mock *TemplateContentInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockTemplateContentInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockTemplateContentInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *TemplateContentInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("TemplateContentInterfaceMock.DeleteNamespacedFunc: method is nil but TemplateContentInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockTemplateContentInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockTemplateContentInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedTemplateContentInterface.DeleteNamespacedCalls()) +func (mock *TemplateContentInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockTemplateContentInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockTemplateContentInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *TemplateContentInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { + if mock.GetFunc == nil { + panic("TemplateContentInterfaceMock.GetFunc: method is nil but TemplateContentInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockTemplateContentInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateContentInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateContentInterface.GetCalls()) +func (mock *TemplateContentInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockTemplateContentInterfaceMockGet.RLock() + calls = mock.calls.Get + lockTemplateContentInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *TemplateContentInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { + if mock.GetNamespacedFunc == nil { + panic("TemplateContentInterfaceMock.GetNamespacedFunc: method is nil but TemplateContentInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockTemplateContentInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockTemplateContentInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedTemplateContentInterface.GetNamespacedCalls()) +func (mock *TemplateContentInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockTemplateContentInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockTemplateContentInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateContentInterfaceMock) List(opts metav1.ListOptions) (*v3.TemplateContentList, error) { + if mock.ListFunc == nil { + panic("TemplateContentInterfaceMock.ListFunc: method is nil but TemplateContentInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateContentInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateContentInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateContentInterface.ListCalls()) +func (mock *TemplateContentInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateContentInterfaceMockList.RLock() + calls = mock.calls.List + lockTemplateContentInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *TemplateContentInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateContentList, error) { + if mock.ListNamespacedFunc == nil { + panic("TemplateContentInterfaceMock.ListNamespacedFunc: method is nil but TemplateContentInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockTemplateContentInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockTemplateContentInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedTemplateContentInterface.ListNamespacedCalls()) +func (mock *TemplateContentInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockTemplateContentInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockTemplateContentInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *TemplateContentInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("TemplateContentInterfaceMock.ObjectClientFunc: method is nil but TemplateContentInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockTemplateContentInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockTemplateContentInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedTemplateContentInterface.ObjectClientCalls()) +func (mock *TemplateContentInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockTemplateContentInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockTemplateContentInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *TemplateContentInterfaceMock) Update(in1 *v3.TemplateContent) (*v3.TemplateContent, error) { + if mock.UpdateFunc == nil { + panic("TemplateContentInterfaceMock.UpdateFunc: method is nil but TemplateContentInterface.Update was just called") + } + callInfo := struct { + In1 *v3.TemplateContent + }{ + In1: in1, + } + lockTemplateContentInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockTemplateContentInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedTemplateContentInterface.UpdateCalls()) +func (mock *TemplateContentInterfaceMock) UpdateCalls() []struct { + In1 *v3.TemplateContent +} { + var calls []struct { + In1 *v3.TemplateContent + } + lockTemplateContentInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockTemplateContentInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *TemplateContentInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("TemplateContentInterfaceMock.WatchFunc: method is nil but TemplateContentInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateContentInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockTemplateContentInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedTemplateContentInterface.WatchCalls()) +func (mock *TemplateContentInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateContentInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockTemplateContentInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockTemplateContentsGetterMockTemplateContents sync.RWMutex +) + +// Ensure, that TemplateContentsGetterMock does implement v31.TemplateContentsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateContentsGetter = &TemplateContentsGetterMock{} + +// TemplateContentsGetterMock is a mock implementation of v31.TemplateContentsGetter. +// +// func TestSomethingThatUsesTemplateContentsGetter(t *testing.T) { +// +// // make and configure a mocked v31.TemplateContentsGetter +// mockedTemplateContentsGetter := &TemplateContentsGetterMock{ +// TemplateContentsFunc: func(namespace string) v31.TemplateContentInterface { +// panic("mock out the TemplateContents method") +// }, +// } +// +// // use mockedTemplateContentsGetter in code that requires v31.TemplateContentsGetter +// // and then make assertions. +// +// } +type TemplateContentsGetterMock struct { + // TemplateContentsFunc mocks the TemplateContents method. + TemplateContentsFunc func(namespace string) v31.TemplateContentInterface + + // calls tracks calls to the methods. + calls struct { + // TemplateContents holds details about calls to the TemplateContents method. + TemplateContents []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// TemplateContents calls TemplateContentsFunc. +func (mock *TemplateContentsGetterMock) TemplateContents(namespace string) v31.TemplateContentInterface { + if mock.TemplateContentsFunc == nil { + panic("TemplateContentsGetterMock.TemplateContentsFunc: method is nil but TemplateContentsGetter.TemplateContents was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockTemplateContentsGetterMockTemplateContents.Lock() + mock.calls.TemplateContents = append(mock.calls.TemplateContents, callInfo) + lockTemplateContentsGetterMockTemplateContents.Unlock() + return mock.TemplateContentsFunc(namespace) +} + +// TemplateContentsCalls gets all the calls that were made to TemplateContents. +// Check the length with: +// +// len(mockedTemplateContentsGetter.TemplateContentsCalls()) +func (mock *TemplateContentsGetterMock) TemplateContentsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockTemplateContentsGetterMockTemplateContents.RLock() + calls = mock.calls.TemplateContents + lockTemplateContentsGetterMockTemplateContents.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_mock.go new file mode 100644 index 0000000..84fc035 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockTemplateListerMockGet sync.RWMutex + lockTemplateListerMockList sync.RWMutex +) + +// Ensure, that TemplateListerMock does implement v31.TemplateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateLister = &TemplateListerMock{} + +// TemplateListerMock is a mock implementation of v31.TemplateLister. +// +// func TestSomethingThatUsesTemplateLister(t *testing.T) { +// +// // make and configure a mocked v31.TemplateLister +// mockedTemplateLister := &TemplateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Template, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Template, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedTemplateLister in code that requires v31.TemplateLister +// // and then make assertions. +// +// } +type TemplateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Template, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Template, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *TemplateListerMock) Get(namespace string, name string) (*v3.Template, error) { + if mock.GetFunc == nil { + panic("TemplateListerMock.GetFunc: method is nil but TemplateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateLister.GetCalls()) +func (mock *TemplateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateListerMockGet.RLock() + calls = mock.calls.Get + lockTemplateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateListerMock) List(namespace string, selector labels.Selector) ([]*v3.Template, error) { + if mock.ListFunc == nil { + panic("TemplateListerMock.ListFunc: method is nil but TemplateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockTemplateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateLister.ListCalls()) +func (mock *TemplateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockTemplateListerMockList.RLock() + calls = mock.calls.List + lockTemplateListerMockList.RUnlock() + return calls +} + +var ( + lockTemplateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateControllerMockAddClusterScopedHandler sync.RWMutex + lockTemplateControllerMockAddFeatureHandler sync.RWMutex + lockTemplateControllerMockAddHandler sync.RWMutex + lockTemplateControllerMockEnqueue sync.RWMutex + lockTemplateControllerMockEnqueueAfter sync.RWMutex + lockTemplateControllerMockGeneric sync.RWMutex + lockTemplateControllerMockInformer sync.RWMutex + lockTemplateControllerMockLister sync.RWMutex +) + +// Ensure, that TemplateControllerMock does implement v31.TemplateController. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateController = &TemplateControllerMock{} + +// TemplateControllerMock is a mock implementation of v31.TemplateController. +// +// func TestSomethingThatUsesTemplateController(t *testing.T) { +// +// // make and configure a mocked v31.TemplateController +// mockedTemplateController := &TemplateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.TemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.TemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.TemplateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedTemplateController in code that requires v31.TemplateController +// // and then make assertions. +// +// } +type TemplateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.TemplateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.TemplateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.TemplateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.TemplateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateHandlerFunc + } + lockTemplateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.TemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateControllerMock.AddClusterScopedHandlerFunc: method is nil but TemplateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateController.AddClusterScopedHandlerCalls()) +func (mock *TemplateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateHandlerFunc + } + lockTemplateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateControllerMock.AddFeatureHandlerFunc: method is nil but TemplateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateController.AddFeatureHandlerCalls()) +func (mock *TemplateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc + } + lockTemplateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateControllerMock) AddHandler(ctx context.Context, name string, handler v31.TemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateControllerMock.AddHandlerFunc: method is nil but TemplateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockTemplateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateController.AddHandlerCalls()) +func (mock *TemplateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.TemplateHandlerFunc + } + lockTemplateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *TemplateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("TemplateControllerMock.EnqueueFunc: method is nil but TemplateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockTemplateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedTemplateController.EnqueueCalls()) +func (mock *TemplateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockTemplateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *TemplateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("TemplateControllerMock.EnqueueAfterFunc: method is nil but TemplateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockTemplateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockTemplateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedTemplateController.EnqueueAfterCalls()) +func (mock *TemplateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockTemplateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockTemplateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *TemplateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("TemplateControllerMock.GenericFunc: method is nil but TemplateController.Generic was just called") + } + callInfo := struct { + }{} + lockTemplateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockTemplateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedTemplateController.GenericCalls()) +func (mock *TemplateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockTemplateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockTemplateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *TemplateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("TemplateControllerMock.InformerFunc: method is nil but TemplateController.Informer was just called") + } + callInfo := struct { + }{} + lockTemplateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockTemplateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedTemplateController.InformerCalls()) +func (mock *TemplateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockTemplateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockTemplateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *TemplateControllerMock) Lister() v31.TemplateLister { + if mock.ListerFunc == nil { + panic("TemplateControllerMock.ListerFunc: method is nil but TemplateController.Lister was just called") + } + callInfo := struct { + }{} + lockTemplateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockTemplateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedTemplateController.ListerCalls()) +func (mock *TemplateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockTemplateControllerMockLister.RLock() + calls = mock.calls.Lister + lockTemplateControllerMockLister.RUnlock() + return calls +} + +var ( + lockTemplateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockTemplateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockTemplateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockTemplateInterfaceMockAddFeatureHandler sync.RWMutex + lockTemplateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockTemplateInterfaceMockAddHandler sync.RWMutex + lockTemplateInterfaceMockAddLifecycle sync.RWMutex + lockTemplateInterfaceMockController sync.RWMutex + lockTemplateInterfaceMockCreate sync.RWMutex + lockTemplateInterfaceMockDelete sync.RWMutex + lockTemplateInterfaceMockDeleteCollection sync.RWMutex + lockTemplateInterfaceMockDeleteNamespaced sync.RWMutex + lockTemplateInterfaceMockGet sync.RWMutex + lockTemplateInterfaceMockGetNamespaced sync.RWMutex + lockTemplateInterfaceMockList sync.RWMutex + lockTemplateInterfaceMockListNamespaced sync.RWMutex + lockTemplateInterfaceMockObjectClient sync.RWMutex + lockTemplateInterfaceMockUpdate sync.RWMutex + lockTemplateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that TemplateInterfaceMock does implement v31.TemplateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateInterface = &TemplateInterfaceMock{} + +// TemplateInterfaceMock is a mock implementation of v31.TemplateInterface. +// +// func TestSomethingThatUsesTemplateInterface(t *testing.T) { +// +// // make and configure a mocked v31.TemplateInterface +// mockedTemplateInterface := &TemplateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.TemplateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.TemplateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.TemplateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Template) (*v3.Template, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Template, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Template, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.TemplateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.TemplateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Template) (*v3.Template, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedTemplateInterface in code that requires v31.TemplateInterface +// // and then make assertions. +// +// } +type TemplateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.TemplateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.TemplateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.TemplateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Template) (*v3.Template, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Template, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Template, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.TemplateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.TemplateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Template) (*v3.Template, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Template + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Template + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateHandlerFunc + } + lockTemplateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *TemplateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("TemplateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but TemplateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockTemplateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *TemplateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle + } + lockTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockTemplateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but TemplateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateInterface.AddClusterScopedHandlerCalls()) +func (mock *TemplateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateHandlerFunc + } + lockTemplateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *TemplateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("TemplateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but TemplateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockTemplateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedTemplateInterface.AddClusterScopedLifecycleCalls()) +func (mock *TemplateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateLifecycle + } + lockTemplateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockTemplateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateInterfaceMock.AddFeatureHandlerFunc: method is nil but TemplateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateInterface.AddFeatureHandlerCalls()) +func (mock *TemplateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateHandlerFunc + } + lockTemplateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *TemplateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("TemplateInterfaceMock.AddFeatureLifecycleFunc: method is nil but TemplateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockTemplateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateInterface.AddFeatureLifecycleCalls()) +func (mock *TemplateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateLifecycle + } + lockTemplateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockTemplateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.TemplateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateInterfaceMock.AddHandlerFunc: method is nil but TemplateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.TemplateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockTemplateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateInterface.AddHandlerCalls()) +func (mock *TemplateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.TemplateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.TemplateHandlerFunc + } + lockTemplateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *TemplateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.TemplateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("TemplateInterfaceMock.AddLifecycleFunc: method is nil but TemplateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockTemplateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedTemplateInterface.AddLifecycleCalls()) +func (mock *TemplateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateLifecycle + } + lockTemplateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockTemplateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *TemplateInterfaceMock) Controller() v31.TemplateController { + if mock.ControllerFunc == nil { + panic("TemplateInterfaceMock.ControllerFunc: method is nil but TemplateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockTemplateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockTemplateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedTemplateInterface.ControllerCalls()) +func (mock *TemplateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockTemplateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockTemplateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *TemplateInterfaceMock) Create(in1 *v3.Template) (*v3.Template, error) { + if mock.CreateFunc == nil { + panic("TemplateInterfaceMock.CreateFunc: method is nil but TemplateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Template + }{ + In1: in1, + } + lockTemplateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockTemplateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedTemplateInterface.CreateCalls()) +func (mock *TemplateInterfaceMock) CreateCalls() []struct { + In1 *v3.Template +} { + var calls []struct { + In1 *v3.Template + } + lockTemplateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockTemplateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *TemplateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("TemplateInterfaceMock.DeleteFunc: method is nil but TemplateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockTemplateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockTemplateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedTemplateInterface.DeleteCalls()) +func (mock *TemplateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockTemplateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockTemplateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *TemplateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("TemplateInterfaceMock.DeleteCollectionFunc: method is nil but TemplateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockTemplateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockTemplateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedTemplateInterface.DeleteCollectionCalls()) +func (mock *TemplateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockTemplateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockTemplateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *TemplateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("TemplateInterfaceMock.DeleteNamespacedFunc: method is nil but TemplateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockTemplateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockTemplateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedTemplateInterface.DeleteNamespacedCalls()) +func (mock *TemplateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockTemplateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockTemplateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *TemplateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Template, error) { + if mock.GetFunc == nil { + panic("TemplateInterfaceMock.GetFunc: method is nil but TemplateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockTemplateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateInterface.GetCalls()) +func (mock *TemplateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockTemplateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockTemplateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *TemplateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Template, error) { + if mock.GetNamespacedFunc == nil { + panic("TemplateInterfaceMock.GetNamespacedFunc: method is nil but TemplateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockTemplateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockTemplateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedTemplateInterface.GetNamespacedCalls()) +func (mock *TemplateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockTemplateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockTemplateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateInterfaceMock) List(opts metav1.ListOptions) (*v3.TemplateList, error) { + if mock.ListFunc == nil { + panic("TemplateInterfaceMock.ListFunc: method is nil but TemplateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateInterface.ListCalls()) +func (mock *TemplateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateInterfaceMockList.RLock() + calls = mock.calls.List + lockTemplateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *TemplateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateList, error) { + if mock.ListNamespacedFunc == nil { + panic("TemplateInterfaceMock.ListNamespacedFunc: method is nil but TemplateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockTemplateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockTemplateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedTemplateInterface.ListNamespacedCalls()) +func (mock *TemplateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockTemplateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockTemplateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *TemplateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("TemplateInterfaceMock.ObjectClientFunc: method is nil but TemplateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockTemplateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockTemplateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedTemplateInterface.ObjectClientCalls()) +func (mock *TemplateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockTemplateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockTemplateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *TemplateInterfaceMock) Update(in1 *v3.Template) (*v3.Template, error) { + if mock.UpdateFunc == nil { + panic("TemplateInterfaceMock.UpdateFunc: method is nil but TemplateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Template + }{ + In1: in1, + } + lockTemplateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockTemplateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedTemplateInterface.UpdateCalls()) +func (mock *TemplateInterfaceMock) UpdateCalls() []struct { + In1 *v3.Template +} { + var calls []struct { + In1 *v3.Template + } + lockTemplateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockTemplateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *TemplateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("TemplateInterfaceMock.WatchFunc: method is nil but TemplateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockTemplateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedTemplateInterface.WatchCalls()) +func (mock *TemplateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockTemplateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockTemplatesGetterMockTemplates sync.RWMutex +) + +// Ensure, that TemplatesGetterMock does implement v31.TemplatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplatesGetter = &TemplatesGetterMock{} + +// TemplatesGetterMock is a mock implementation of v31.TemplatesGetter. +// +// func TestSomethingThatUsesTemplatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.TemplatesGetter +// mockedTemplatesGetter := &TemplatesGetterMock{ +// TemplatesFunc: func(namespace string) v31.TemplateInterface { +// panic("mock out the Templates method") +// }, +// } +// +// // use mockedTemplatesGetter in code that requires v31.TemplatesGetter +// // and then make assertions. +// +// } +type TemplatesGetterMock struct { + // TemplatesFunc mocks the Templates method. + TemplatesFunc func(namespace string) v31.TemplateInterface + + // calls tracks calls to the methods. + calls struct { + // Templates holds details about calls to the Templates method. + Templates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Templates calls TemplatesFunc. +func (mock *TemplatesGetterMock) Templates(namespace string) v31.TemplateInterface { + if mock.TemplatesFunc == nil { + panic("TemplatesGetterMock.TemplatesFunc: method is nil but TemplatesGetter.Templates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockTemplatesGetterMockTemplates.Lock() + mock.calls.Templates = append(mock.calls.Templates, callInfo) + lockTemplatesGetterMockTemplates.Unlock() + return mock.TemplatesFunc(namespace) +} + +// TemplatesCalls gets all the calls that were made to Templates. +// Check the length with: +// +// len(mockedTemplatesGetter.TemplatesCalls()) +func (mock *TemplatesGetterMock) TemplatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockTemplatesGetterMockTemplates.RLock() + calls = mock.calls.Templates + lockTemplatesGetterMockTemplates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_version_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_version_mock.go new file mode 100644 index 0000000..55ef4dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_template_version_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockTemplateVersionListerMockGet sync.RWMutex + lockTemplateVersionListerMockList sync.RWMutex +) + +// Ensure, that TemplateVersionListerMock does implement v31.TemplateVersionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateVersionLister = &TemplateVersionListerMock{} + +// TemplateVersionListerMock is a mock implementation of v31.TemplateVersionLister. +// +// func TestSomethingThatUsesTemplateVersionLister(t *testing.T) { +// +// // make and configure a mocked v31.TemplateVersionLister +// mockedTemplateVersionLister := &TemplateVersionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.TemplateVersion, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.TemplateVersion, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedTemplateVersionLister in code that requires v31.TemplateVersionLister +// // and then make assertions. +// +// } +type TemplateVersionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.TemplateVersion, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.TemplateVersion, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *TemplateVersionListerMock) Get(namespace string, name string) (*v3.TemplateVersion, error) { + if mock.GetFunc == nil { + panic("TemplateVersionListerMock.GetFunc: method is nil but TemplateVersionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateVersionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateVersionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateVersionLister.GetCalls()) +func (mock *TemplateVersionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateVersionListerMockGet.RLock() + calls = mock.calls.Get + lockTemplateVersionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateVersionListerMock) List(namespace string, selector labels.Selector) ([]*v3.TemplateVersion, error) { + if mock.ListFunc == nil { + panic("TemplateVersionListerMock.ListFunc: method is nil but TemplateVersionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockTemplateVersionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateVersionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateVersionLister.ListCalls()) +func (mock *TemplateVersionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockTemplateVersionListerMockList.RLock() + calls = mock.calls.List + lockTemplateVersionListerMockList.RUnlock() + return calls +} + +var ( + lockTemplateVersionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateVersionControllerMockAddClusterScopedHandler sync.RWMutex + lockTemplateVersionControllerMockAddFeatureHandler sync.RWMutex + lockTemplateVersionControllerMockAddHandler sync.RWMutex + lockTemplateVersionControllerMockEnqueue sync.RWMutex + lockTemplateVersionControllerMockEnqueueAfter sync.RWMutex + lockTemplateVersionControllerMockGeneric sync.RWMutex + lockTemplateVersionControllerMockInformer sync.RWMutex + lockTemplateVersionControllerMockLister sync.RWMutex +) + +// Ensure, that TemplateVersionControllerMock does implement v31.TemplateVersionController. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateVersionController = &TemplateVersionControllerMock{} + +// TemplateVersionControllerMock is a mock implementation of v31.TemplateVersionController. +// +// func TestSomethingThatUsesTemplateVersionController(t *testing.T) { +// +// // make and configure a mocked v31.TemplateVersionController +// mockedTemplateVersionController := &TemplateVersionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.TemplateVersionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedTemplateVersionController in code that requires v31.TemplateVersionController +// // and then make assertions. +// +// } +type TemplateVersionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.TemplateVersionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.TemplateVersionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateVersionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TemplateVersionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateVersionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.TemplateVersionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateVersionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateVersionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateVersionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateVersionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateVersionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateVersionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateVersionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc + } + lockTemplateVersionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateVersionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateVersionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.TemplateVersionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateVersionControllerMock.AddClusterScopedHandlerFunc: method is nil but TemplateVersionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTemplateVersionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateVersionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateVersionController.AddClusterScopedHandlerCalls()) +func (mock *TemplateVersionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TemplateVersionHandlerFunc + } + lockTemplateVersionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateVersionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateVersionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateVersionControllerMock.AddFeatureHandlerFunc: method is nil but TemplateVersionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateVersionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateVersionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateVersionController.AddFeatureHandlerCalls()) +func (mock *TemplateVersionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc + } + lockTemplateVersionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateVersionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateVersionControllerMock) AddHandler(ctx context.Context, name string, handler v31.TemplateVersionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateVersionControllerMock.AddHandlerFunc: method is nil but TemplateVersionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockTemplateVersionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateVersionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateVersionController.AddHandlerCalls()) +func (mock *TemplateVersionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.TemplateVersionHandlerFunc + } + lockTemplateVersionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateVersionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *TemplateVersionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("TemplateVersionControllerMock.EnqueueFunc: method is nil but TemplateVersionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTemplateVersionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockTemplateVersionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedTemplateVersionController.EnqueueCalls()) +func (mock *TemplateVersionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTemplateVersionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockTemplateVersionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *TemplateVersionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("TemplateVersionControllerMock.EnqueueAfterFunc: method is nil but TemplateVersionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockTemplateVersionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockTemplateVersionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedTemplateVersionController.EnqueueAfterCalls()) +func (mock *TemplateVersionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockTemplateVersionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockTemplateVersionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *TemplateVersionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("TemplateVersionControllerMock.GenericFunc: method is nil but TemplateVersionController.Generic was just called") + } + callInfo := struct { + }{} + lockTemplateVersionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockTemplateVersionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedTemplateVersionController.GenericCalls()) +func (mock *TemplateVersionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockTemplateVersionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockTemplateVersionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *TemplateVersionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("TemplateVersionControllerMock.InformerFunc: method is nil but TemplateVersionController.Informer was just called") + } + callInfo := struct { + }{} + lockTemplateVersionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockTemplateVersionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedTemplateVersionController.InformerCalls()) +func (mock *TemplateVersionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockTemplateVersionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockTemplateVersionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *TemplateVersionControllerMock) Lister() v31.TemplateVersionLister { + if mock.ListerFunc == nil { + panic("TemplateVersionControllerMock.ListerFunc: method is nil but TemplateVersionController.Lister was just called") + } + callInfo := struct { + }{} + lockTemplateVersionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockTemplateVersionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedTemplateVersionController.ListerCalls()) +func (mock *TemplateVersionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockTemplateVersionControllerMockLister.RLock() + calls = mock.calls.Lister + lockTemplateVersionControllerMockLister.RUnlock() + return calls +} + +var ( + lockTemplateVersionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockTemplateVersionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockTemplateVersionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockTemplateVersionInterfaceMockAddFeatureHandler sync.RWMutex + lockTemplateVersionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockTemplateVersionInterfaceMockAddHandler sync.RWMutex + lockTemplateVersionInterfaceMockAddLifecycle sync.RWMutex + lockTemplateVersionInterfaceMockController sync.RWMutex + lockTemplateVersionInterfaceMockCreate sync.RWMutex + lockTemplateVersionInterfaceMockDelete sync.RWMutex + lockTemplateVersionInterfaceMockDeleteCollection sync.RWMutex + lockTemplateVersionInterfaceMockDeleteNamespaced sync.RWMutex + lockTemplateVersionInterfaceMockGet sync.RWMutex + lockTemplateVersionInterfaceMockGetNamespaced sync.RWMutex + lockTemplateVersionInterfaceMockList sync.RWMutex + lockTemplateVersionInterfaceMockListNamespaced sync.RWMutex + lockTemplateVersionInterfaceMockObjectClient sync.RWMutex + lockTemplateVersionInterfaceMockUpdate sync.RWMutex + lockTemplateVersionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that TemplateVersionInterfaceMock does implement v31.TemplateVersionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateVersionInterface = &TemplateVersionInterfaceMock{} + +// TemplateVersionInterfaceMock is a mock implementation of v31.TemplateVersionInterface. +// +// func TestSomethingThatUsesTemplateVersionInterface(t *testing.T) { +// +// // make and configure a mocked v31.TemplateVersionInterface +// mockedTemplateVersionInterface := &TemplateVersionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateVersionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.TemplateVersionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.TemplateVersionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.TemplateVersionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.TemplateVersionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedTemplateVersionInterface in code that requires v31.TemplateVersionInterface +// // and then make assertions. +// +// } +type TemplateVersionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateVersionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.TemplateVersionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.TemplateVersionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.TemplateVersionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.TemplateVersionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.TemplateVersionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateVersionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateVersionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TemplateVersionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateVersionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateVersionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateVersionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TemplateVersionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TemplateVersionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.TemplateVersion + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.TemplateVersion + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TemplateVersionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TemplateVersionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but TemplateVersionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *TemplateVersionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc + } + lockTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTemplateVersionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *TemplateVersionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("TemplateVersionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but TemplateVersionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *TemplateVersionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle + } + lockTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockTemplateVersionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TemplateVersionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.TemplateVersionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TemplateVersionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but TemplateVersionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTemplateVersionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTemplateVersionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddClusterScopedHandlerCalls()) +func (mock *TemplateVersionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TemplateVersionHandlerFunc + } + lockTemplateVersionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTemplateVersionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *TemplateVersionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.TemplateVersionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("TemplateVersionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but TemplateVersionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTemplateVersionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockTemplateVersionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddClusterScopedLifecycleCalls()) +func (mock *TemplateVersionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TemplateVersionLifecycle + } + lockTemplateVersionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockTemplateVersionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TemplateVersionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TemplateVersionInterfaceMock.AddFeatureHandlerFunc: method is nil but TemplateVersionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTemplateVersionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTemplateVersionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddFeatureHandlerCalls()) +func (mock *TemplateVersionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TemplateVersionHandlerFunc + } + lockTemplateVersionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTemplateVersionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *TemplateVersionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.TemplateVersionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("TemplateVersionInterfaceMock.AddFeatureLifecycleFunc: method is nil but TemplateVersionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateVersionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateVersionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockTemplateVersionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddFeatureLifecycleCalls()) +func (mock *TemplateVersionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TemplateVersionLifecycle + } + lockTemplateVersionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockTemplateVersionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TemplateVersionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.TemplateVersionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TemplateVersionInterfaceMock.AddHandlerFunc: method is nil but TemplateVersionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.TemplateVersionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockTemplateVersionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTemplateVersionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddHandlerCalls()) +func (mock *TemplateVersionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.TemplateVersionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.TemplateVersionHandlerFunc + } + lockTemplateVersionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTemplateVersionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *TemplateVersionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.TemplateVersionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("TemplateVersionInterfaceMock.AddLifecycleFunc: method is nil but TemplateVersionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateVersionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockTemplateVersionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockTemplateVersionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedTemplateVersionInterface.AddLifecycleCalls()) +func (mock *TemplateVersionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateVersionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.TemplateVersionLifecycle + } + lockTemplateVersionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockTemplateVersionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *TemplateVersionInterfaceMock) Controller() v31.TemplateVersionController { + if mock.ControllerFunc == nil { + panic("TemplateVersionInterfaceMock.ControllerFunc: method is nil but TemplateVersionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockTemplateVersionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockTemplateVersionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedTemplateVersionInterface.ControllerCalls()) +func (mock *TemplateVersionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockTemplateVersionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockTemplateVersionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *TemplateVersionInterfaceMock) Create(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) { + if mock.CreateFunc == nil { + panic("TemplateVersionInterfaceMock.CreateFunc: method is nil but TemplateVersionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.TemplateVersion + }{ + In1: in1, + } + lockTemplateVersionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockTemplateVersionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedTemplateVersionInterface.CreateCalls()) +func (mock *TemplateVersionInterfaceMock) CreateCalls() []struct { + In1 *v3.TemplateVersion +} { + var calls []struct { + In1 *v3.TemplateVersion + } + lockTemplateVersionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockTemplateVersionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *TemplateVersionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("TemplateVersionInterfaceMock.DeleteFunc: method is nil but TemplateVersionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockTemplateVersionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockTemplateVersionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedTemplateVersionInterface.DeleteCalls()) +func (mock *TemplateVersionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockTemplateVersionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockTemplateVersionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *TemplateVersionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("TemplateVersionInterfaceMock.DeleteCollectionFunc: method is nil but TemplateVersionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockTemplateVersionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockTemplateVersionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedTemplateVersionInterface.DeleteCollectionCalls()) +func (mock *TemplateVersionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockTemplateVersionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockTemplateVersionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *TemplateVersionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("TemplateVersionInterfaceMock.DeleteNamespacedFunc: method is nil but TemplateVersionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockTemplateVersionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockTemplateVersionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedTemplateVersionInterface.DeleteNamespacedCalls()) +func (mock *TemplateVersionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockTemplateVersionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockTemplateVersionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *TemplateVersionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { + if mock.GetFunc == nil { + panic("TemplateVersionInterfaceMock.GetFunc: method is nil but TemplateVersionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockTemplateVersionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTemplateVersionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTemplateVersionInterface.GetCalls()) +func (mock *TemplateVersionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockTemplateVersionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockTemplateVersionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *TemplateVersionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { + if mock.GetNamespacedFunc == nil { + panic("TemplateVersionInterfaceMock.GetNamespacedFunc: method is nil but TemplateVersionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockTemplateVersionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockTemplateVersionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedTemplateVersionInterface.GetNamespacedCalls()) +func (mock *TemplateVersionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockTemplateVersionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockTemplateVersionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TemplateVersionInterfaceMock) List(opts metav1.ListOptions) (*v3.TemplateVersionList, error) { + if mock.ListFunc == nil { + panic("TemplateVersionInterfaceMock.ListFunc: method is nil but TemplateVersionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateVersionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTemplateVersionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTemplateVersionInterface.ListCalls()) +func (mock *TemplateVersionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateVersionInterfaceMockList.RLock() + calls = mock.calls.List + lockTemplateVersionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *TemplateVersionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateVersionList, error) { + if mock.ListNamespacedFunc == nil { + panic("TemplateVersionInterfaceMock.ListNamespacedFunc: method is nil but TemplateVersionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockTemplateVersionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockTemplateVersionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedTemplateVersionInterface.ListNamespacedCalls()) +func (mock *TemplateVersionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockTemplateVersionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockTemplateVersionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *TemplateVersionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("TemplateVersionInterfaceMock.ObjectClientFunc: method is nil but TemplateVersionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockTemplateVersionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockTemplateVersionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedTemplateVersionInterface.ObjectClientCalls()) +func (mock *TemplateVersionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockTemplateVersionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockTemplateVersionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *TemplateVersionInterfaceMock) Update(in1 *v3.TemplateVersion) (*v3.TemplateVersion, error) { + if mock.UpdateFunc == nil { + panic("TemplateVersionInterfaceMock.UpdateFunc: method is nil but TemplateVersionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.TemplateVersion + }{ + In1: in1, + } + lockTemplateVersionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockTemplateVersionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedTemplateVersionInterface.UpdateCalls()) +func (mock *TemplateVersionInterfaceMock) UpdateCalls() []struct { + In1 *v3.TemplateVersion +} { + var calls []struct { + In1 *v3.TemplateVersion + } + lockTemplateVersionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockTemplateVersionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *TemplateVersionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("TemplateVersionInterfaceMock.WatchFunc: method is nil but TemplateVersionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTemplateVersionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockTemplateVersionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedTemplateVersionInterface.WatchCalls()) +func (mock *TemplateVersionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTemplateVersionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockTemplateVersionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockTemplateVersionsGetterMockTemplateVersions sync.RWMutex +) + +// Ensure, that TemplateVersionsGetterMock does implement v31.TemplateVersionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.TemplateVersionsGetter = &TemplateVersionsGetterMock{} + +// TemplateVersionsGetterMock is a mock implementation of v31.TemplateVersionsGetter. +// +// func TestSomethingThatUsesTemplateVersionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.TemplateVersionsGetter +// mockedTemplateVersionsGetter := &TemplateVersionsGetterMock{ +// TemplateVersionsFunc: func(namespace string) v31.TemplateVersionInterface { +// panic("mock out the TemplateVersions method") +// }, +// } +// +// // use mockedTemplateVersionsGetter in code that requires v31.TemplateVersionsGetter +// // and then make assertions. +// +// } +type TemplateVersionsGetterMock struct { + // TemplateVersionsFunc mocks the TemplateVersions method. + TemplateVersionsFunc func(namespace string) v31.TemplateVersionInterface + + // calls tracks calls to the methods. + calls struct { + // TemplateVersions holds details about calls to the TemplateVersions method. + TemplateVersions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// TemplateVersions calls TemplateVersionsFunc. +func (mock *TemplateVersionsGetterMock) TemplateVersions(namespace string) v31.TemplateVersionInterface { + if mock.TemplateVersionsFunc == nil { + panic("TemplateVersionsGetterMock.TemplateVersionsFunc: method is nil but TemplateVersionsGetter.TemplateVersions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockTemplateVersionsGetterMockTemplateVersions.Lock() + mock.calls.TemplateVersions = append(mock.calls.TemplateVersions, callInfo) + lockTemplateVersionsGetterMockTemplateVersions.Unlock() + return mock.TemplateVersionsFunc(namespace) +} + +// TemplateVersionsCalls gets all the calls that were made to TemplateVersions. +// Check the length with: +// +// len(mockedTemplateVersionsGetter.TemplateVersionsCalls()) +func (mock *TemplateVersionsGetterMock) TemplateVersionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockTemplateVersionsGetterMockTemplateVersions.RLock() + calls = mock.calls.TemplateVersions + lockTemplateVersionsGetterMockTemplateVersions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_token_mock.go new file mode 100644 index 0000000..c193728 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockTokenListerMockGet sync.RWMutex + lockTokenListerMockList sync.RWMutex +) + +// Ensure, that TokenListerMock does implement v31.TokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.TokenLister = &TokenListerMock{} + +// TokenListerMock is a mock implementation of v31.TokenLister. +// +// func TestSomethingThatUsesTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.TokenLister +// mockedTokenLister := &TokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Token, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Token, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedTokenLister in code that requires v31.TokenLister +// // and then make assertions. +// +// } +type TokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Token, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Token, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *TokenListerMock) Get(namespace string, name string) (*v3.Token, error) { + if mock.GetFunc == nil { + panic("TokenListerMock.GetFunc: method is nil but TokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTokenLister.GetCalls()) +func (mock *TokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTokenListerMockGet.RLock() + calls = mock.calls.Get + lockTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.Token, error) { + if mock.ListFunc == nil { + panic("TokenListerMock.ListFunc: method is nil but TokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTokenLister.ListCalls()) +func (mock *TokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockTokenListerMockList.RLock() + calls = mock.calls.List + lockTokenListerMockList.RUnlock() + return calls +} + +var ( + lockTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockTokenControllerMockAddFeatureHandler sync.RWMutex + lockTokenControllerMockAddHandler sync.RWMutex + lockTokenControllerMockEnqueue sync.RWMutex + lockTokenControllerMockEnqueueAfter sync.RWMutex + lockTokenControllerMockGeneric sync.RWMutex + lockTokenControllerMockInformer sync.RWMutex + lockTokenControllerMockLister sync.RWMutex +) + +// Ensure, that TokenControllerMock does implement v31.TokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.TokenController = &TokenControllerMock{} + +// TokenControllerMock is a mock implementation of v31.TokenController. +// +// func TestSomethingThatUsesTokenController(t *testing.T) { +// +// // make and configure a mocked v31.TokenController +// mockedTokenController := &TokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.TokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.TokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.TokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedTokenController in code that requires v31.TokenController +// // and then make assertions. +// +// } +type TokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.TokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.TokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.TokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.TokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.TokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.TokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but TokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *TokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.TokenHandlerFunc + } + lockTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.TokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TokenControllerMock.AddClusterScopedHandlerFunc: method is nil but TokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTokenController.AddClusterScopedHandlerCalls()) +func (mock *TokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.TokenHandlerFunc + } + lockTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TokenControllerMock.AddFeatureHandlerFunc: method is nil but TokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTokenController.AddFeatureHandlerCalls()) +func (mock *TokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc + } + lockTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.TokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TokenControllerMock.AddHandlerFunc: method is nil but TokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.TokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTokenController.AddHandlerCalls()) +func (mock *TokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.TokenHandlerFunc + } + lockTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *TokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("TokenControllerMock.EnqueueFunc: method is nil but TokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedTokenController.EnqueueCalls()) +func (mock *TokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *TokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("TokenControllerMock.EnqueueAfterFunc: method is nil but TokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedTokenController.EnqueueAfterCalls()) +func (mock *TokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *TokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("TokenControllerMock.GenericFunc: method is nil but TokenController.Generic was just called") + } + callInfo := struct { + }{} + lockTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedTokenController.GenericCalls()) +func (mock *TokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *TokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("TokenControllerMock.InformerFunc: method is nil but TokenController.Informer was just called") + } + callInfo := struct { + }{} + lockTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedTokenController.InformerCalls()) +func (mock *TokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *TokenControllerMock) Lister() v31.TokenLister { + if mock.ListerFunc == nil { + panic("TokenControllerMock.ListerFunc: method is nil but TokenController.Lister was just called") + } + callInfo := struct { + }{} + lockTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedTokenController.ListerCalls()) +func (mock *TokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockTokenInterfaceMockAddHandler sync.RWMutex + lockTokenInterfaceMockAddLifecycle sync.RWMutex + lockTokenInterfaceMockController sync.RWMutex + lockTokenInterfaceMockCreate sync.RWMutex + lockTokenInterfaceMockDelete sync.RWMutex + lockTokenInterfaceMockDeleteCollection sync.RWMutex + lockTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockTokenInterfaceMockGet sync.RWMutex + lockTokenInterfaceMockGetNamespaced sync.RWMutex + lockTokenInterfaceMockList sync.RWMutex + lockTokenInterfaceMockListNamespaced sync.RWMutex + lockTokenInterfaceMockObjectClient sync.RWMutex + lockTokenInterfaceMockUpdate sync.RWMutex + lockTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that TokenInterfaceMock does implement v31.TokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.TokenInterface = &TokenInterfaceMock{} + +// TokenInterfaceMock is a mock implementation of v31.TokenInterface. +// +// func TestSomethingThatUsesTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.TokenInterface +// mockedTokenInterface := &TokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.TokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.TokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.TokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.TokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Token) (*v3.Token, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Token, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.TokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.TokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Token) (*v3.Token, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedTokenInterface in code that requires v31.TokenInterface +// // and then make assertions. +// +// } +type TokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.TokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.TokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.TokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.TokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.TokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Token) (*v3.Token, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Token, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Token, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.TokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.TokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Token) (*v3.Token, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.TokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.TokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.TokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Token + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Token + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *TokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("TokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but TokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *TokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.TokenHandlerFunc + } + lockTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *TokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.TokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("TokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but TokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *TokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.TokenLifecycle + } + lockTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *TokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.TokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("TokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but TokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *TokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.TokenHandlerFunc + } + lockTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *TokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.TokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("TokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but TokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *TokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.TokenLifecycle + } + lockTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *TokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.TokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("TokenInterfaceMock.AddFeatureHandlerFunc: method is nil but TokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedTokenInterface.AddFeatureHandlerCalls()) +func (mock *TokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.TokenHandlerFunc + } + lockTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *TokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.TokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("TokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but TokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedTokenInterface.AddFeatureLifecycleCalls()) +func (mock *TokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.TokenLifecycle + } + lockTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *TokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.TokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("TokenInterfaceMock.AddHandlerFunc: method is nil but TokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.TokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedTokenInterface.AddHandlerCalls()) +func (mock *TokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.TokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.TokenHandlerFunc + } + lockTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *TokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.TokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("TokenInterfaceMock.AddLifecycleFunc: method is nil but TokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.TokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedTokenInterface.AddLifecycleCalls()) +func (mock *TokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.TokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.TokenLifecycle + } + lockTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *TokenInterfaceMock) Controller() v31.TokenController { + if mock.ControllerFunc == nil { + panic("TokenInterfaceMock.ControllerFunc: method is nil but TokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedTokenInterface.ControllerCalls()) +func (mock *TokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *TokenInterfaceMock) Create(in1 *v3.Token) (*v3.Token, error) { + if mock.CreateFunc == nil { + panic("TokenInterfaceMock.CreateFunc: method is nil but TokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Token + }{ + In1: in1, + } + lockTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedTokenInterface.CreateCalls()) +func (mock *TokenInterfaceMock) CreateCalls() []struct { + In1 *v3.Token +} { + var calls []struct { + In1 *v3.Token + } + lockTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *TokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("TokenInterfaceMock.DeleteFunc: method is nil but TokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedTokenInterface.DeleteCalls()) +func (mock *TokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *TokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("TokenInterfaceMock.DeleteCollectionFunc: method is nil but TokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedTokenInterface.DeleteCollectionCalls()) +func (mock *TokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *TokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("TokenInterfaceMock.DeleteNamespacedFunc: method is nil but TokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedTokenInterface.DeleteNamespacedCalls()) +func (mock *TokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *TokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Token, error) { + if mock.GetFunc == nil { + panic("TokenInterfaceMock.GetFunc: method is nil but TokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedTokenInterface.GetCalls()) +func (mock *TokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *TokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Token, error) { + if mock.GetNamespacedFunc == nil { + panic("TokenInterfaceMock.GetNamespacedFunc: method is nil but TokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedTokenInterface.GetNamespacedCalls()) +func (mock *TokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *TokenInterfaceMock) List(opts metav1.ListOptions) (*v3.TokenList, error) { + if mock.ListFunc == nil { + panic("TokenInterfaceMock.ListFunc: method is nil but TokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedTokenInterface.ListCalls()) +func (mock *TokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *TokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("TokenInterfaceMock.ListNamespacedFunc: method is nil but TokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedTokenInterface.ListNamespacedCalls()) +func (mock *TokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *TokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("TokenInterfaceMock.ObjectClientFunc: method is nil but TokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedTokenInterface.ObjectClientCalls()) +func (mock *TokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *TokenInterfaceMock) Update(in1 *v3.Token) (*v3.Token, error) { + if mock.UpdateFunc == nil { + panic("TokenInterfaceMock.UpdateFunc: method is nil but TokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Token + }{ + In1: in1, + } + lockTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedTokenInterface.UpdateCalls()) +func (mock *TokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.Token +} { + var calls []struct { + In1 *v3.Token + } + lockTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *TokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("TokenInterfaceMock.WatchFunc: method is nil but TokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedTokenInterface.WatchCalls()) +func (mock *TokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockTokensGetterMockTokens sync.RWMutex +) + +// Ensure, that TokensGetterMock does implement v31.TokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.TokensGetter = &TokensGetterMock{} + +// TokensGetterMock is a mock implementation of v31.TokensGetter. +// +// func TestSomethingThatUsesTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.TokensGetter +// mockedTokensGetter := &TokensGetterMock{ +// TokensFunc: func(namespace string) v31.TokenInterface { +// panic("mock out the Tokens method") +// }, +// } +// +// // use mockedTokensGetter in code that requires v31.TokensGetter +// // and then make assertions. +// +// } +type TokensGetterMock struct { + // TokensFunc mocks the Tokens method. + TokensFunc func(namespace string) v31.TokenInterface + + // calls tracks calls to the methods. + calls struct { + // Tokens holds details about calls to the Tokens method. + Tokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Tokens calls TokensFunc. +func (mock *TokensGetterMock) Tokens(namespace string) v31.TokenInterface { + if mock.TokensFunc == nil { + panic("TokensGetterMock.TokensFunc: method is nil but TokensGetter.Tokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockTokensGetterMockTokens.Lock() + mock.calls.Tokens = append(mock.calls.Tokens, callInfo) + lockTokensGetterMockTokens.Unlock() + return mock.TokensFunc(namespace) +} + +// TokensCalls gets all the calls that were made to Tokens. +// Check the length with: +// +// len(mockedTokensGetter.TokensCalls()) +func (mock *TokensGetterMock) TokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockTokensGetterMockTokens.RLock() + calls = mock.calls.Tokens + lockTokensGetterMockTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_attribute_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_attribute_mock.go new file mode 100644 index 0000000..68020f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_attribute_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockUserAttributeListerMockGet sync.RWMutex + lockUserAttributeListerMockList sync.RWMutex +) + +// Ensure, that UserAttributeListerMock does implement v31.UserAttributeLister. +// If this is not the case, regenerate this file with moq. +var _ v31.UserAttributeLister = &UserAttributeListerMock{} + +// UserAttributeListerMock is a mock implementation of v31.UserAttributeLister. +// +// func TestSomethingThatUsesUserAttributeLister(t *testing.T) { +// +// // make and configure a mocked v31.UserAttributeLister +// mockedUserAttributeLister := &UserAttributeListerMock{ +// GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.UserAttribute, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedUserAttributeLister in code that requires v31.UserAttributeLister +// // and then make assertions. +// +// } +type UserAttributeListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.UserAttribute, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.UserAttribute, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *UserAttributeListerMock) Get(namespace string, name string) (*v3.UserAttribute, error) { + if mock.GetFunc == nil { + panic("UserAttributeListerMock.GetFunc: method is nil but UserAttributeLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockUserAttributeListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockUserAttributeListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedUserAttributeLister.GetCalls()) +func (mock *UserAttributeListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockUserAttributeListerMockGet.RLock() + calls = mock.calls.Get + lockUserAttributeListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *UserAttributeListerMock) List(namespace string, selector labels.Selector) ([]*v3.UserAttribute, error) { + if mock.ListFunc == nil { + panic("UserAttributeListerMock.ListFunc: method is nil but UserAttributeLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockUserAttributeListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockUserAttributeListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedUserAttributeLister.ListCalls()) +func (mock *UserAttributeListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockUserAttributeListerMockList.RLock() + calls = mock.calls.List + lockUserAttributeListerMockList.RUnlock() + return calls +} + +var ( + lockUserAttributeControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockUserAttributeControllerMockAddClusterScopedHandler sync.RWMutex + lockUserAttributeControllerMockAddFeatureHandler sync.RWMutex + lockUserAttributeControllerMockAddHandler sync.RWMutex + lockUserAttributeControllerMockEnqueue sync.RWMutex + lockUserAttributeControllerMockEnqueueAfter sync.RWMutex + lockUserAttributeControllerMockGeneric sync.RWMutex + lockUserAttributeControllerMockInformer sync.RWMutex + lockUserAttributeControllerMockLister sync.RWMutex +) + +// Ensure, that UserAttributeControllerMock does implement v31.UserAttributeController. +// If this is not the case, regenerate this file with moq. +var _ v31.UserAttributeController = &UserAttributeControllerMock{} + +// UserAttributeControllerMock is a mock implementation of v31.UserAttributeController. +// +// func TestSomethingThatUsesUserAttributeController(t *testing.T) { +// +// // make and configure a mocked v31.UserAttributeController +// mockedUserAttributeController := &UserAttributeControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.UserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.UserAttributeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.UserAttributeLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedUserAttributeController in code that requires v31.UserAttributeController +// // and then make assertions. +// +// } +type UserAttributeControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserAttributeHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.UserAttributeHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.UserAttributeHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.UserAttributeLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.UserAttributeHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.UserAttributeHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserAttributeHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.UserAttributeHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *UserAttributeControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserAttributeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("UserAttributeControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but UserAttributeController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockUserAttributeControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockUserAttributeControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedUserAttributeController.AddClusterScopedFeatureHandlerCalls()) +func (mock *UserAttributeControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc + } + lockUserAttributeControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockUserAttributeControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *UserAttributeControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.UserAttributeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("UserAttributeControllerMock.AddClusterScopedHandlerFunc: method is nil but UserAttributeController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockUserAttributeControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockUserAttributeControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedUserAttributeController.AddClusterScopedHandlerCalls()) +func (mock *UserAttributeControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserAttributeHandlerFunc + } + lockUserAttributeControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockUserAttributeControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *UserAttributeControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("UserAttributeControllerMock.AddFeatureHandlerFunc: method is nil but UserAttributeController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockUserAttributeControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockUserAttributeControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedUserAttributeController.AddFeatureHandlerCalls()) +func (mock *UserAttributeControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc + } + lockUserAttributeControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockUserAttributeControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *UserAttributeControllerMock) AddHandler(ctx context.Context, name string, handler v31.UserAttributeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("UserAttributeControllerMock.AddHandlerFunc: method is nil but UserAttributeController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockUserAttributeControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockUserAttributeControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedUserAttributeController.AddHandlerCalls()) +func (mock *UserAttributeControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.UserAttributeHandlerFunc + } + lockUserAttributeControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockUserAttributeControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *UserAttributeControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("UserAttributeControllerMock.EnqueueFunc: method is nil but UserAttributeController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockUserAttributeControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockUserAttributeControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedUserAttributeController.EnqueueCalls()) +func (mock *UserAttributeControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockUserAttributeControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockUserAttributeControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *UserAttributeControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("UserAttributeControllerMock.EnqueueAfterFunc: method is nil but UserAttributeController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockUserAttributeControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockUserAttributeControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedUserAttributeController.EnqueueAfterCalls()) +func (mock *UserAttributeControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockUserAttributeControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockUserAttributeControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *UserAttributeControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("UserAttributeControllerMock.GenericFunc: method is nil but UserAttributeController.Generic was just called") + } + callInfo := struct { + }{} + lockUserAttributeControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockUserAttributeControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedUserAttributeController.GenericCalls()) +func (mock *UserAttributeControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockUserAttributeControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockUserAttributeControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *UserAttributeControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("UserAttributeControllerMock.InformerFunc: method is nil but UserAttributeController.Informer was just called") + } + callInfo := struct { + }{} + lockUserAttributeControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockUserAttributeControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedUserAttributeController.InformerCalls()) +func (mock *UserAttributeControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockUserAttributeControllerMockInformer.RLock() + calls = mock.calls.Informer + lockUserAttributeControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *UserAttributeControllerMock) Lister() v31.UserAttributeLister { + if mock.ListerFunc == nil { + panic("UserAttributeControllerMock.ListerFunc: method is nil but UserAttributeController.Lister was just called") + } + callInfo := struct { + }{} + lockUserAttributeControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockUserAttributeControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedUserAttributeController.ListerCalls()) +func (mock *UserAttributeControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockUserAttributeControllerMockLister.RLock() + calls = mock.calls.Lister + lockUserAttributeControllerMockLister.RUnlock() + return calls +} + +var ( + lockUserAttributeInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockUserAttributeInterfaceMockAddClusterScopedHandler sync.RWMutex + lockUserAttributeInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockUserAttributeInterfaceMockAddFeatureHandler sync.RWMutex + lockUserAttributeInterfaceMockAddFeatureLifecycle sync.RWMutex + lockUserAttributeInterfaceMockAddHandler sync.RWMutex + lockUserAttributeInterfaceMockAddLifecycle sync.RWMutex + lockUserAttributeInterfaceMockController sync.RWMutex + lockUserAttributeInterfaceMockCreate sync.RWMutex + lockUserAttributeInterfaceMockDelete sync.RWMutex + lockUserAttributeInterfaceMockDeleteCollection sync.RWMutex + lockUserAttributeInterfaceMockDeleteNamespaced sync.RWMutex + lockUserAttributeInterfaceMockGet sync.RWMutex + lockUserAttributeInterfaceMockGetNamespaced sync.RWMutex + lockUserAttributeInterfaceMockList sync.RWMutex + lockUserAttributeInterfaceMockListNamespaced sync.RWMutex + lockUserAttributeInterfaceMockObjectClient sync.RWMutex + lockUserAttributeInterfaceMockUpdate sync.RWMutex + lockUserAttributeInterfaceMockWatch sync.RWMutex +) + +// Ensure, that UserAttributeInterfaceMock does implement v31.UserAttributeInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.UserAttributeInterface = &UserAttributeInterfaceMock{} + +// UserAttributeInterfaceMock is a mock implementation of v31.UserAttributeInterface. +// +// func TestSomethingThatUsesUserAttributeInterface(t *testing.T) { +// +// // make and configure a mocked v31.UserAttributeInterface +// mockedUserAttributeInterface := &UserAttributeInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserAttributeLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.UserAttributeHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.UserAttributeLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.UserAttributeController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.UserAttribute) (*v3.UserAttribute, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.UserAttributeList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.UserAttributeList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.UserAttribute) (*v3.UserAttribute, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedUserAttributeInterface in code that requires v31.UserAttributeInterface +// // and then make assertions. +// +// } +type UserAttributeInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserAttributeLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.UserAttributeHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.UserAttributeLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.UserAttributeController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.UserAttribute) (*v3.UserAttribute, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.UserAttribute, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.UserAttributeList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.UserAttributeList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.UserAttribute) (*v3.UserAttribute, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.UserAttributeHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserAttributeLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.UserAttributeHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserAttributeLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserAttributeHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserAttributeLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserAttributeHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserAttributeLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.UserAttribute + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.UserAttribute + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *UserAttributeInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("UserAttributeInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but UserAttributeInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockUserAttributeInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockUserAttributeInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *UserAttributeInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc + } + lockUserAttributeInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockUserAttributeInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *UserAttributeInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("UserAttributeInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but UserAttributeInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *UserAttributeInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle + } + lockUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockUserAttributeInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *UserAttributeInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserAttributeHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("UserAttributeInterfaceMock.AddClusterScopedHandlerFunc: method is nil but UserAttributeInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockUserAttributeInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockUserAttributeInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddClusterScopedHandlerCalls()) +func (mock *UserAttributeInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserAttributeHandlerFunc + } + lockUserAttributeInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockUserAttributeInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *UserAttributeInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.UserAttributeLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("UserAttributeInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but UserAttributeInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockUserAttributeInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockUserAttributeInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddClusterScopedLifecycleCalls()) +func (mock *UserAttributeInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserAttributeLifecycle + } + lockUserAttributeInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockUserAttributeInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *UserAttributeInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserAttributeHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("UserAttributeInterfaceMock.AddFeatureHandlerFunc: method is nil but UserAttributeInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockUserAttributeInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockUserAttributeInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddFeatureHandlerCalls()) +func (mock *UserAttributeInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserAttributeHandlerFunc + } + lockUserAttributeInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockUserAttributeInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *UserAttributeInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserAttributeLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("UserAttributeInterfaceMock.AddFeatureLifecycleFunc: method is nil but UserAttributeInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserAttributeLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockUserAttributeInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockUserAttributeInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddFeatureLifecycleCalls()) +func (mock *UserAttributeInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserAttributeLifecycle + } + lockUserAttributeInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockUserAttributeInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *UserAttributeInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.UserAttributeHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("UserAttributeInterfaceMock.AddHandlerFunc: method is nil but UserAttributeInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.UserAttributeHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockUserAttributeInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockUserAttributeInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddHandlerCalls()) +func (mock *UserAttributeInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.UserAttributeHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.UserAttributeHandlerFunc + } + lockUserAttributeInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockUserAttributeInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *UserAttributeInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.UserAttributeLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("UserAttributeInterfaceMock.AddLifecycleFunc: method is nil but UserAttributeInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.UserAttributeLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockUserAttributeInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockUserAttributeInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedUserAttributeInterface.AddLifecycleCalls()) +func (mock *UserAttributeInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.UserAttributeLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.UserAttributeLifecycle + } + lockUserAttributeInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockUserAttributeInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *UserAttributeInterfaceMock) Controller() v31.UserAttributeController { + if mock.ControllerFunc == nil { + panic("UserAttributeInterfaceMock.ControllerFunc: method is nil but UserAttributeInterface.Controller was just called") + } + callInfo := struct { + }{} + lockUserAttributeInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockUserAttributeInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedUserAttributeInterface.ControllerCalls()) +func (mock *UserAttributeInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockUserAttributeInterfaceMockController.RLock() + calls = mock.calls.Controller + lockUserAttributeInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *UserAttributeInterfaceMock) Create(in1 *v3.UserAttribute) (*v3.UserAttribute, error) { + if mock.CreateFunc == nil { + panic("UserAttributeInterfaceMock.CreateFunc: method is nil but UserAttributeInterface.Create was just called") + } + callInfo := struct { + In1 *v3.UserAttribute + }{ + In1: in1, + } + lockUserAttributeInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockUserAttributeInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedUserAttributeInterface.CreateCalls()) +func (mock *UserAttributeInterfaceMock) CreateCalls() []struct { + In1 *v3.UserAttribute +} { + var calls []struct { + In1 *v3.UserAttribute + } + lockUserAttributeInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockUserAttributeInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *UserAttributeInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("UserAttributeInterfaceMock.DeleteFunc: method is nil but UserAttributeInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockUserAttributeInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockUserAttributeInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedUserAttributeInterface.DeleteCalls()) +func (mock *UserAttributeInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockUserAttributeInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockUserAttributeInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *UserAttributeInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("UserAttributeInterfaceMock.DeleteCollectionFunc: method is nil but UserAttributeInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockUserAttributeInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockUserAttributeInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedUserAttributeInterface.DeleteCollectionCalls()) +func (mock *UserAttributeInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockUserAttributeInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockUserAttributeInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *UserAttributeInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("UserAttributeInterfaceMock.DeleteNamespacedFunc: method is nil but UserAttributeInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockUserAttributeInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockUserAttributeInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedUserAttributeInterface.DeleteNamespacedCalls()) +func (mock *UserAttributeInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockUserAttributeInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockUserAttributeInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *UserAttributeInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + if mock.GetFunc == nil { + panic("UserAttributeInterfaceMock.GetFunc: method is nil but UserAttributeInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockUserAttributeInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockUserAttributeInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedUserAttributeInterface.GetCalls()) +func (mock *UserAttributeInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockUserAttributeInterfaceMockGet.RLock() + calls = mock.calls.Get + lockUserAttributeInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *UserAttributeInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + if mock.GetNamespacedFunc == nil { + panic("UserAttributeInterfaceMock.GetNamespacedFunc: method is nil but UserAttributeInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockUserAttributeInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockUserAttributeInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedUserAttributeInterface.GetNamespacedCalls()) +func (mock *UserAttributeInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockUserAttributeInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockUserAttributeInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *UserAttributeInterfaceMock) List(opts metav1.ListOptions) (*v3.UserAttributeList, error) { + if mock.ListFunc == nil { + panic("UserAttributeInterfaceMock.ListFunc: method is nil but UserAttributeInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockUserAttributeInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockUserAttributeInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedUserAttributeInterface.ListCalls()) +func (mock *UserAttributeInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockUserAttributeInterfaceMockList.RLock() + calls = mock.calls.List + lockUserAttributeInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *UserAttributeInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserAttributeList, error) { + if mock.ListNamespacedFunc == nil { + panic("UserAttributeInterfaceMock.ListNamespacedFunc: method is nil but UserAttributeInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockUserAttributeInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockUserAttributeInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedUserAttributeInterface.ListNamespacedCalls()) +func (mock *UserAttributeInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockUserAttributeInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockUserAttributeInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *UserAttributeInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("UserAttributeInterfaceMock.ObjectClientFunc: method is nil but UserAttributeInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockUserAttributeInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockUserAttributeInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedUserAttributeInterface.ObjectClientCalls()) +func (mock *UserAttributeInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockUserAttributeInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockUserAttributeInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *UserAttributeInterfaceMock) Update(in1 *v3.UserAttribute) (*v3.UserAttribute, error) { + if mock.UpdateFunc == nil { + panic("UserAttributeInterfaceMock.UpdateFunc: method is nil but UserAttributeInterface.Update was just called") + } + callInfo := struct { + In1 *v3.UserAttribute + }{ + In1: in1, + } + lockUserAttributeInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockUserAttributeInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedUserAttributeInterface.UpdateCalls()) +func (mock *UserAttributeInterfaceMock) UpdateCalls() []struct { + In1 *v3.UserAttribute +} { + var calls []struct { + In1 *v3.UserAttribute + } + lockUserAttributeInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockUserAttributeInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *UserAttributeInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("UserAttributeInterfaceMock.WatchFunc: method is nil but UserAttributeInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockUserAttributeInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockUserAttributeInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedUserAttributeInterface.WatchCalls()) +func (mock *UserAttributeInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockUserAttributeInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockUserAttributeInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockUserAttributesGetterMockUserAttributes sync.RWMutex +) + +// Ensure, that UserAttributesGetterMock does implement v31.UserAttributesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.UserAttributesGetter = &UserAttributesGetterMock{} + +// UserAttributesGetterMock is a mock implementation of v31.UserAttributesGetter. +// +// func TestSomethingThatUsesUserAttributesGetter(t *testing.T) { +// +// // make and configure a mocked v31.UserAttributesGetter +// mockedUserAttributesGetter := &UserAttributesGetterMock{ +// UserAttributesFunc: func(namespace string) v31.UserAttributeInterface { +// panic("mock out the UserAttributes method") +// }, +// } +// +// // use mockedUserAttributesGetter in code that requires v31.UserAttributesGetter +// // and then make assertions. +// +// } +type UserAttributesGetterMock struct { + // UserAttributesFunc mocks the UserAttributes method. + UserAttributesFunc func(namespace string) v31.UserAttributeInterface + + // calls tracks calls to the methods. + calls struct { + // UserAttributes holds details about calls to the UserAttributes method. + UserAttributes []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// UserAttributes calls UserAttributesFunc. +func (mock *UserAttributesGetterMock) UserAttributes(namespace string) v31.UserAttributeInterface { + if mock.UserAttributesFunc == nil { + panic("UserAttributesGetterMock.UserAttributesFunc: method is nil but UserAttributesGetter.UserAttributes was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockUserAttributesGetterMockUserAttributes.Lock() + mock.calls.UserAttributes = append(mock.calls.UserAttributes, callInfo) + lockUserAttributesGetterMockUserAttributes.Unlock() + return mock.UserAttributesFunc(namespace) +} + +// UserAttributesCalls gets all the calls that were made to UserAttributes. +// Check the length with: +// +// len(mockedUserAttributesGetter.UserAttributesCalls()) +func (mock *UserAttributesGetterMock) UserAttributesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockUserAttributesGetterMockUserAttributes.RLock() + calls = mock.calls.UserAttributes + lockUserAttributesGetterMockUserAttributes.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_mock.go new file mode 100644 index 0000000..632246c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/fakes/zz_generated_user_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockUserListerMockGet sync.RWMutex + lockUserListerMockList sync.RWMutex +) + +// Ensure, that UserListerMock does implement v31.UserLister. +// If this is not the case, regenerate this file with moq. +var _ v31.UserLister = &UserListerMock{} + +// UserListerMock is a mock implementation of v31.UserLister. +// +// func TestSomethingThatUsesUserLister(t *testing.T) { +// +// // make and configure a mocked v31.UserLister +// mockedUserLister := &UserListerMock{ +// GetFunc: func(namespace string, name string) (*v3.User, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.User, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedUserLister in code that requires v31.UserLister +// // and then make assertions. +// +// } +type UserListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.User, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.User, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *UserListerMock) Get(namespace string, name string) (*v3.User, error) { + if mock.GetFunc == nil { + panic("UserListerMock.GetFunc: method is nil but UserLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockUserListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockUserListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedUserLister.GetCalls()) +func (mock *UserListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockUserListerMockGet.RLock() + calls = mock.calls.Get + lockUserListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *UserListerMock) List(namespace string, selector labels.Selector) ([]*v3.User, error) { + if mock.ListFunc == nil { + panic("UserListerMock.ListFunc: method is nil but UserLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockUserListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockUserListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedUserLister.ListCalls()) +func (mock *UserListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockUserListerMockList.RLock() + calls = mock.calls.List + lockUserListerMockList.RUnlock() + return calls +} + +var ( + lockUserControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockUserControllerMockAddClusterScopedHandler sync.RWMutex + lockUserControllerMockAddFeatureHandler sync.RWMutex + lockUserControllerMockAddHandler sync.RWMutex + lockUserControllerMockEnqueue sync.RWMutex + lockUserControllerMockEnqueueAfter sync.RWMutex + lockUserControllerMockGeneric sync.RWMutex + lockUserControllerMockInformer sync.RWMutex + lockUserControllerMockLister sync.RWMutex +) + +// Ensure, that UserControllerMock does implement v31.UserController. +// If this is not the case, regenerate this file with moq. +var _ v31.UserController = &UserControllerMock{} + +// UserControllerMock is a mock implementation of v31.UserController. +// +// func TestSomethingThatUsesUserController(t *testing.T) { +// +// // make and configure a mocked v31.UserController +// mockedUserController := &UserControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.UserHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.UserHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.UserLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedUserController in code that requires v31.UserController +// // and then make assertions. +// +// } +type UserControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.UserHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.UserHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.UserLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.UserHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.UserHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.UserHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *UserControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.UserHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("UserControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but UserController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockUserControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockUserControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedUserController.AddClusterScopedFeatureHandlerCalls()) +func (mock *UserControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.UserHandlerFunc + } + lockUserControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockUserControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *UserControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.UserHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("UserControllerMock.AddClusterScopedHandlerFunc: method is nil but UserController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockUserControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockUserControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedUserController.AddClusterScopedHandlerCalls()) +func (mock *UserControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.UserHandlerFunc + } + lockUserControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockUserControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *UserControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("UserControllerMock.AddFeatureHandlerFunc: method is nil but UserController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockUserControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockUserControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedUserController.AddFeatureHandlerCalls()) +func (mock *UserControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc + } + lockUserControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockUserControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *UserControllerMock) AddHandler(ctx context.Context, name string, handler v31.UserHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("UserControllerMock.AddHandlerFunc: method is nil but UserController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.UserHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockUserControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockUserControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedUserController.AddHandlerCalls()) +func (mock *UserControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.UserHandlerFunc + } + lockUserControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockUserControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *UserControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("UserControllerMock.EnqueueFunc: method is nil but UserController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockUserControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockUserControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedUserController.EnqueueCalls()) +func (mock *UserControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockUserControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockUserControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *UserControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("UserControllerMock.EnqueueAfterFunc: method is nil but UserController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockUserControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockUserControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedUserController.EnqueueAfterCalls()) +func (mock *UserControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockUserControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockUserControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *UserControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("UserControllerMock.GenericFunc: method is nil but UserController.Generic was just called") + } + callInfo := struct { + }{} + lockUserControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockUserControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedUserController.GenericCalls()) +func (mock *UserControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockUserControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockUserControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *UserControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("UserControllerMock.InformerFunc: method is nil but UserController.Informer was just called") + } + callInfo := struct { + }{} + lockUserControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockUserControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedUserController.InformerCalls()) +func (mock *UserControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockUserControllerMockInformer.RLock() + calls = mock.calls.Informer + lockUserControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *UserControllerMock) Lister() v31.UserLister { + if mock.ListerFunc == nil { + panic("UserControllerMock.ListerFunc: method is nil but UserController.Lister was just called") + } + callInfo := struct { + }{} + lockUserControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockUserControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedUserController.ListerCalls()) +func (mock *UserControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockUserControllerMockLister.RLock() + calls = mock.calls.Lister + lockUserControllerMockLister.RUnlock() + return calls +} + +var ( + lockUserInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockUserInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockUserInterfaceMockAddClusterScopedHandler sync.RWMutex + lockUserInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockUserInterfaceMockAddFeatureHandler sync.RWMutex + lockUserInterfaceMockAddFeatureLifecycle sync.RWMutex + lockUserInterfaceMockAddHandler sync.RWMutex + lockUserInterfaceMockAddLifecycle sync.RWMutex + lockUserInterfaceMockController sync.RWMutex + lockUserInterfaceMockCreate sync.RWMutex + lockUserInterfaceMockDelete sync.RWMutex + lockUserInterfaceMockDeleteCollection sync.RWMutex + lockUserInterfaceMockDeleteNamespaced sync.RWMutex + lockUserInterfaceMockGet sync.RWMutex + lockUserInterfaceMockGetNamespaced sync.RWMutex + lockUserInterfaceMockList sync.RWMutex + lockUserInterfaceMockListNamespaced sync.RWMutex + lockUserInterfaceMockObjectClient sync.RWMutex + lockUserInterfaceMockUpdate sync.RWMutex + lockUserInterfaceMockWatch sync.RWMutex +) + +// Ensure, that UserInterfaceMock does implement v31.UserInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.UserInterface = &UserInterfaceMock{} + +// UserInterfaceMock is a mock implementation of v31.UserInterface. +// +// func TestSomethingThatUsesUserInterface(t *testing.T) { +// +// // make and configure a mocked v31.UserInterface +// mockedUserInterface := &UserInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.UserLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.UserHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.UserLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.UserController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.User) (*v3.User, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.User, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.User, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.UserList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.UserList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.User) (*v3.User, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedUserInterface in code that requires v31.UserInterface +// // and then make assertions. +// +// } +type UserInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.UserLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.UserHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.UserLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.UserController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.User) (*v3.User, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.User, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.User, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.UserList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.UserList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.User) (*v3.User, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.UserHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.UserHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.UserHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.UserLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.User + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.User + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *UserInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("UserInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but UserInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockUserInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockUserInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedUserInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *UserInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.UserHandlerFunc + } + lockUserInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockUserInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *UserInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.UserLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("UserInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but UserInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockUserInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockUserInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedUserInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *UserInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.UserLifecycle + } + lockUserInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockUserInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *UserInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.UserHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("UserInterfaceMock.AddClusterScopedHandlerFunc: method is nil but UserInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockUserInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockUserInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedUserInterface.AddClusterScopedHandlerCalls()) +func (mock *UserInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.UserHandlerFunc + } + lockUserInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockUserInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *UserInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.UserLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("UserInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but UserInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockUserInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockUserInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedUserInterface.AddClusterScopedLifecycleCalls()) +func (mock *UserInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.UserLifecycle + } + lockUserInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockUserInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *UserInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.UserHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("UserInterfaceMock.AddFeatureHandlerFunc: method is nil but UserInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockUserInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockUserInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedUserInterface.AddFeatureHandlerCalls()) +func (mock *UserInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.UserHandlerFunc + } + lockUserInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockUserInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *UserInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.UserLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("UserInterfaceMock.AddFeatureLifecycleFunc: method is nil but UserInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockUserInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockUserInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedUserInterface.AddFeatureLifecycleCalls()) +func (mock *UserInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.UserLifecycle + } + lockUserInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockUserInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *UserInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.UserHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("UserInterfaceMock.AddHandlerFunc: method is nil but UserInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.UserHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockUserInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockUserInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedUserInterface.AddHandlerCalls()) +func (mock *UserInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.UserHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.UserHandlerFunc + } + lockUserInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockUserInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *UserInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.UserLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("UserInterfaceMock.AddLifecycleFunc: method is nil but UserInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.UserLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockUserInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockUserInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedUserInterface.AddLifecycleCalls()) +func (mock *UserInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.UserLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.UserLifecycle + } + lockUserInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockUserInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *UserInterfaceMock) Controller() v31.UserController { + if mock.ControllerFunc == nil { + panic("UserInterfaceMock.ControllerFunc: method is nil but UserInterface.Controller was just called") + } + callInfo := struct { + }{} + lockUserInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockUserInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedUserInterface.ControllerCalls()) +func (mock *UserInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockUserInterfaceMockController.RLock() + calls = mock.calls.Controller + lockUserInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *UserInterfaceMock) Create(in1 *v3.User) (*v3.User, error) { + if mock.CreateFunc == nil { + panic("UserInterfaceMock.CreateFunc: method is nil but UserInterface.Create was just called") + } + callInfo := struct { + In1 *v3.User + }{ + In1: in1, + } + lockUserInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockUserInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedUserInterface.CreateCalls()) +func (mock *UserInterfaceMock) CreateCalls() []struct { + In1 *v3.User +} { + var calls []struct { + In1 *v3.User + } + lockUserInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockUserInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *UserInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("UserInterfaceMock.DeleteFunc: method is nil but UserInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockUserInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockUserInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedUserInterface.DeleteCalls()) +func (mock *UserInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockUserInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockUserInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *UserInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("UserInterfaceMock.DeleteCollectionFunc: method is nil but UserInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockUserInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockUserInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedUserInterface.DeleteCollectionCalls()) +func (mock *UserInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockUserInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockUserInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *UserInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("UserInterfaceMock.DeleteNamespacedFunc: method is nil but UserInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockUserInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockUserInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedUserInterface.DeleteNamespacedCalls()) +func (mock *UserInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockUserInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockUserInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *UserInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.User, error) { + if mock.GetFunc == nil { + panic("UserInterfaceMock.GetFunc: method is nil but UserInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockUserInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockUserInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedUserInterface.GetCalls()) +func (mock *UserInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockUserInterfaceMockGet.RLock() + calls = mock.calls.Get + lockUserInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *UserInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.User, error) { + if mock.GetNamespacedFunc == nil { + panic("UserInterfaceMock.GetNamespacedFunc: method is nil but UserInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockUserInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockUserInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedUserInterface.GetNamespacedCalls()) +func (mock *UserInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockUserInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockUserInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *UserInterfaceMock) List(opts metav1.ListOptions) (*v3.UserList, error) { + if mock.ListFunc == nil { + panic("UserInterfaceMock.ListFunc: method is nil but UserInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockUserInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockUserInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedUserInterface.ListCalls()) +func (mock *UserInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockUserInterfaceMockList.RLock() + calls = mock.calls.List + lockUserInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *UserInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserList, error) { + if mock.ListNamespacedFunc == nil { + panic("UserInterfaceMock.ListNamespacedFunc: method is nil but UserInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockUserInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockUserInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedUserInterface.ListNamespacedCalls()) +func (mock *UserInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockUserInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockUserInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *UserInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("UserInterfaceMock.ObjectClientFunc: method is nil but UserInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockUserInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockUserInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedUserInterface.ObjectClientCalls()) +func (mock *UserInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockUserInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockUserInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *UserInterfaceMock) Update(in1 *v3.User) (*v3.User, error) { + if mock.UpdateFunc == nil { + panic("UserInterfaceMock.UpdateFunc: method is nil but UserInterface.Update was just called") + } + callInfo := struct { + In1 *v3.User + }{ + In1: in1, + } + lockUserInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockUserInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedUserInterface.UpdateCalls()) +func (mock *UserInterfaceMock) UpdateCalls() []struct { + In1 *v3.User +} { + var calls []struct { + In1 *v3.User + } + lockUserInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockUserInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *UserInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("UserInterfaceMock.WatchFunc: method is nil but UserInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockUserInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockUserInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedUserInterface.WatchCalls()) +func (mock *UserInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockUserInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockUserInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockUsersGetterMockUsers sync.RWMutex +) + +// Ensure, that UsersGetterMock does implement v31.UsersGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.UsersGetter = &UsersGetterMock{} + +// UsersGetterMock is a mock implementation of v31.UsersGetter. +// +// func TestSomethingThatUsesUsersGetter(t *testing.T) { +// +// // make and configure a mocked v31.UsersGetter +// mockedUsersGetter := &UsersGetterMock{ +// UsersFunc: func(namespace string) v31.UserInterface { +// panic("mock out the Users method") +// }, +// } +// +// // use mockedUsersGetter in code that requires v31.UsersGetter +// // and then make assertions. +// +// } +type UsersGetterMock struct { + // UsersFunc mocks the Users method. + UsersFunc func(namespace string) v31.UserInterface + + // calls tracks calls to the methods. + calls struct { + // Users holds details about calls to the Users method. + Users []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Users calls UsersFunc. +func (mock *UsersGetterMock) Users(namespace string) v31.UserInterface { + if mock.UsersFunc == nil { + panic("UsersGetterMock.UsersFunc: method is nil but UsersGetter.Users was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockUsersGetterMockUsers.Lock() + mock.calls.Users = append(mock.calls.Users, callInfo) + lockUsersGetterMockUsers.Unlock() + return mock.UsersFunc(namespace) +} + +// UsersCalls gets all the calls that were made to Users. +// Check the length with: +// +// len(mockedUsersGetter.UsersCalls()) +func (mock *UsersGetterMock) UsersCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockUsersGetterMockUsers.RLock() + calls = mock.calls.Users + lockUsersGetterMockUsers.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_controller.go new file mode 100644 index 0000000..0c8cd09 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + AuthConfigGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "AuthConfig", + } + AuthConfigResource = metav1.APIResource{ + Name: "authconfigs", + SingularName: "authconfig", + Namespaced: false, + Kind: AuthConfigGroupVersionKind.Kind, + } + + AuthConfigGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "authconfigs", + } +) + +func init() { + resource.Put(AuthConfigGroupVersionResource) +} + +// Deprecated: use v3.AuthConfig instead +type AuthConfig = v3.AuthConfig + +func NewAuthConfig(namespace, name string, obj v3.AuthConfig) *v3.AuthConfig { + obj.APIVersion, obj.Kind = AuthConfigGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type AuthConfigHandlerFunc func(key string, obj *v3.AuthConfig) (runtime.Object, error) + +type AuthConfigChangeHandlerFunc func(obj *v3.AuthConfig) (runtime.Object, error) + +type AuthConfigLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.AuthConfig, err error) + Get(namespace, name string) (*v3.AuthConfig, error) +} + +type AuthConfigController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() AuthConfigLister + AddHandler(ctx context.Context, name string, handler AuthConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AuthConfigHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler AuthConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler AuthConfigHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type AuthConfigInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.AuthConfig) (*v3.AuthConfig, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.AuthConfig, error) + Get(name string, opts metav1.GetOptions) (*v3.AuthConfig, error) + Update(*v3.AuthConfig) (*v3.AuthConfig, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.AuthConfigList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AuthConfigList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() AuthConfigController + AddHandler(ctx context.Context, name string, sync AuthConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AuthConfigHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle AuthConfigLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AuthConfigLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AuthConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AuthConfigHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AuthConfigLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AuthConfigLifecycle) +} + +type authConfigLister struct { + ns string + controller *authConfigController +} + +func (l *authConfigLister) List(namespace string, selector labels.Selector) (ret []*v3.AuthConfig, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.AuthConfig)) + }) + return +} + +func (l *authConfigLister) Get(namespace, name string) (*v3.AuthConfig, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: AuthConfigGroupVersionKind.Group, + Resource: AuthConfigGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.AuthConfig), nil +} + +type authConfigController struct { + ns string + controller.GenericController +} + +func (c *authConfigController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *authConfigController) Lister() AuthConfigLister { + return &authConfigLister{ + ns: c.ns, + controller: c, + } +} + +func (c *authConfigController) AddHandler(ctx context.Context, name string, handler AuthConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AuthConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *authConfigController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler AuthConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AuthConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *authConfigController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler AuthConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AuthConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *authConfigController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler AuthConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AuthConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type authConfigFactory struct { +} + +func (c authConfigFactory) Object() runtime.Object { + return &v3.AuthConfig{} +} + +func (c authConfigFactory) List() runtime.Object { + return &v3.AuthConfigList{} +} + +func (s *authConfigClient) Controller() AuthConfigController { + genericController := controller.NewGenericController(s.ns, AuthConfigGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(AuthConfigGroupVersionResource, AuthConfigGroupVersionKind.Kind, false)) + + return &authConfigController{ + ns: s.ns, + GenericController: genericController, + } +} + +type authConfigClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller AuthConfigController +} + +func (s *authConfigClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *authConfigClient) Create(o *v3.AuthConfig) (*v3.AuthConfig, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) Get(name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.AuthConfig, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) Update(o *v3.AuthConfig) (*v3.AuthConfig, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) UpdateStatus(o *v3.AuthConfig) (*v3.AuthConfig, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *authConfigClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *authConfigClient) List(opts metav1.ListOptions) (*v3.AuthConfigList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.AuthConfigList), err +} + +func (s *authConfigClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AuthConfigList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.AuthConfigList), err +} + +func (s *authConfigClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *authConfigClient) Patch(o *v3.AuthConfig, patchType types.PatchType, data []byte, subresources ...string) (*v3.AuthConfig, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.AuthConfig), err +} + +func (s *authConfigClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *authConfigClient) AddHandler(ctx context.Context, name string, sync AuthConfigHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *authConfigClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AuthConfigHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *authConfigClient) AddLifecycle(ctx context.Context, name string, lifecycle AuthConfigLifecycle) { + sync := NewAuthConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *authConfigClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AuthConfigLifecycle) { + sync := NewAuthConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *authConfigClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AuthConfigHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *authConfigClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AuthConfigHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *authConfigClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AuthConfigLifecycle) { + sync := NewAuthConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *authConfigClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AuthConfigLifecycle) { + sync := NewAuthConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_lifecycle_adapter.go new file mode 100644 index 0000000..8322fa0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_auth_config_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type AuthConfigLifecycle interface { + Create(obj *v3.AuthConfig) (runtime.Object, error) + Remove(obj *v3.AuthConfig) (runtime.Object, error) + Updated(obj *v3.AuthConfig) (runtime.Object, error) +} + +type authConfigLifecycleAdapter struct { + lifecycle AuthConfigLifecycle +} + +func (w *authConfigLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *authConfigLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *authConfigLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.AuthConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *authConfigLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.AuthConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *authConfigLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.AuthConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func NewAuthConfigLifecycleAdapter(name string, clusterScoped bool, client AuthConfigInterface, l AuthConfigLifecycle) AuthConfigHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(AuthConfigGroupVersionResource) + } + adapter := &authConfigLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.AuthConfig) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_controller.go new file mode 100644 index 0000000..89454d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CatalogGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Catalog", + } + CatalogResource = metav1.APIResource{ + Name: "catalogs", + SingularName: "catalog", + Namespaced: false, + Kind: CatalogGroupVersionKind.Kind, + } + + CatalogGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "catalogs", + } +) + +func init() { + resource.Put(CatalogGroupVersionResource) +} + +// Deprecated: use v3.Catalog instead +type Catalog = v3.Catalog + +func NewCatalog(namespace, name string, obj v3.Catalog) *v3.Catalog { + obj.APIVersion, obj.Kind = CatalogGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CatalogHandlerFunc func(key string, obj *v3.Catalog) (runtime.Object, error) + +type CatalogChangeHandlerFunc func(obj *v3.Catalog) (runtime.Object, error) + +type CatalogLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Catalog, err error) + Get(namespace, name string) (*v3.Catalog, error) +} + +type CatalogController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CatalogLister + AddHandler(ctx context.Context, name string, handler CatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CatalogHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CatalogInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Catalog) (*v3.Catalog, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Catalog, error) + Get(name string, opts metav1.GetOptions) (*v3.Catalog, error) + Update(*v3.Catalog) (*v3.Catalog, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.CatalogList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CatalogController + AddHandler(ctx context.Context, name string, sync CatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CatalogLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogLifecycle) +} + +type catalogLister struct { + ns string + controller *catalogController +} + +func (l *catalogLister) List(namespace string, selector labels.Selector) (ret []*v3.Catalog, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Catalog)) + }) + return +} + +func (l *catalogLister) Get(namespace, name string) (*v3.Catalog, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CatalogGroupVersionKind.Group, + Resource: CatalogGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Catalog), nil +} + +type catalogController struct { + ns string + controller.GenericController +} + +func (c *catalogController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *catalogController) Lister() CatalogLister { + return &catalogLister{ + ns: c.ns, + controller: c, + } +} + +func (c *catalogController) AddHandler(ctx context.Context, name string, handler CatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Catalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Catalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Catalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Catalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type catalogFactory struct { +} + +func (c catalogFactory) Object() runtime.Object { + return &v3.Catalog{} +} + +func (c catalogFactory) List() runtime.Object { + return &v3.CatalogList{} +} + +func (s *catalogClient) Controller() CatalogController { + genericController := controller.NewGenericController(s.ns, CatalogGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CatalogGroupVersionResource, CatalogGroupVersionKind.Kind, false)) + + return &catalogController{ + ns: s.ns, + GenericController: genericController, + } +} + +type catalogClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CatalogController +} + +func (s *catalogClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *catalogClient) Create(o *v3.Catalog) (*v3.Catalog, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) Get(name string, opts metav1.GetOptions) (*v3.Catalog, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Catalog, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) Update(o *v3.Catalog) (*v3.Catalog, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) UpdateStatus(o *v3.Catalog) (*v3.Catalog, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *catalogClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *catalogClient) List(opts metav1.ListOptions) (*v3.CatalogList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.CatalogList), err +} + +func (s *catalogClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.CatalogList), err +} + +func (s *catalogClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *catalogClient) Patch(o *v3.Catalog, patchType types.PatchType, data []byte, subresources ...string) (*v3.Catalog, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Catalog), err +} + +func (s *catalogClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *catalogClient) AddHandler(ctx context.Context, name string, sync CatalogHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogClient) AddLifecycle(ctx context.Context, name string, lifecycle CatalogLifecycle) { + sync := NewCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogLifecycle) { + sync := NewCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *catalogClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogLifecycle) { + sync := NewCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogLifecycle) { + sync := NewCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_lifecycle_adapter.go new file mode 100644 index 0000000..ff84bab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type CatalogLifecycle interface { + Create(obj *v3.Catalog) (runtime.Object, error) + Remove(obj *v3.Catalog) (runtime.Object, error) + Updated(obj *v3.Catalog) (runtime.Object, error) +} + +type catalogLifecycleAdapter struct { + lifecycle CatalogLifecycle +} + +func (w *catalogLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *catalogLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *catalogLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Catalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Catalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Catalog)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCatalogLifecycleAdapter(name string, clusterScoped bool, client CatalogInterface, l CatalogLifecycle) CatalogHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CatalogGroupVersionResource) + } + adapter := &catalogLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Catalog) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_controller.go new file mode 100644 index 0000000..df2493a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CatalogTemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "CatalogTemplate", + } + CatalogTemplateResource = metav1.APIResource{ + Name: "catalogtemplates", + SingularName: "catalogtemplate", + Namespaced: true, + + Kind: CatalogTemplateGroupVersionKind.Kind, + } + + CatalogTemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "catalogtemplates", + } +) + +func init() { + resource.Put(CatalogTemplateGroupVersionResource) +} + +// Deprecated: use v3.CatalogTemplate instead +type CatalogTemplate = v3.CatalogTemplate + +func NewCatalogTemplate(namespace, name string, obj v3.CatalogTemplate) *v3.CatalogTemplate { + obj.APIVersion, obj.Kind = CatalogTemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CatalogTemplateHandlerFunc func(key string, obj *v3.CatalogTemplate) (runtime.Object, error) + +type CatalogTemplateChangeHandlerFunc func(obj *v3.CatalogTemplate) (runtime.Object, error) + +type CatalogTemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.CatalogTemplate, err error) + Get(namespace, name string) (*v3.CatalogTemplate, error) +} + +type CatalogTemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CatalogTemplateLister + AddHandler(ctx context.Context, name string, handler CatalogTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CatalogTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CatalogTemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CatalogTemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.CatalogTemplate) (*v3.CatalogTemplate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) + Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) + Update(*v3.CatalogTemplate) (*v3.CatalogTemplate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.CatalogTemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CatalogTemplateController + AddHandler(ctx context.Context, name string, sync CatalogTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CatalogTemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogTemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogTemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogTemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogTemplateLifecycle) +} + +type catalogTemplateLister struct { + ns string + controller *catalogTemplateController +} + +func (l *catalogTemplateLister) List(namespace string, selector labels.Selector) (ret []*v3.CatalogTemplate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.CatalogTemplate)) + }) + return +} + +func (l *catalogTemplateLister) Get(namespace, name string) (*v3.CatalogTemplate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CatalogTemplateGroupVersionKind.Group, + Resource: CatalogTemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.CatalogTemplate), nil +} + +type catalogTemplateController struct { + ns string + controller.GenericController +} + +func (c *catalogTemplateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *catalogTemplateController) Lister() CatalogTemplateLister { + return &catalogTemplateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *catalogTemplateController) AddHandler(ctx context.Context, name string, handler CatalogTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CatalogTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CatalogTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CatalogTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type catalogTemplateFactory struct { +} + +func (c catalogTemplateFactory) Object() runtime.Object { + return &v3.CatalogTemplate{} +} + +func (c catalogTemplateFactory) List() runtime.Object { + return &v3.CatalogTemplateList{} +} + +func (s *catalogTemplateClient) Controller() CatalogTemplateController { + genericController := controller.NewGenericController(s.ns, CatalogTemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CatalogTemplateGroupVersionResource, CatalogTemplateGroupVersionKind.Kind, true)) + + return &catalogTemplateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type catalogTemplateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CatalogTemplateController +} + +func (s *catalogTemplateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *catalogTemplateClient) Create(o *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) Update(o *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) UpdateStatus(o *v3.CatalogTemplate) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *catalogTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *catalogTemplateClient) List(opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.CatalogTemplateList), err +} + +func (s *catalogTemplateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.CatalogTemplateList), err +} + +func (s *catalogTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *catalogTemplateClient) Patch(o *v3.CatalogTemplate, patchType types.PatchType, data []byte, subresources ...string) (*v3.CatalogTemplate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.CatalogTemplate), err +} + +func (s *catalogTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *catalogTemplateClient) AddHandler(ctx context.Context, name string, sync CatalogTemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogTemplateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogTemplateClient) AddLifecycle(ctx context.Context, name string, lifecycle CatalogTemplateLifecycle) { + sync := NewCatalogTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogTemplateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogTemplateLifecycle) { + sync := NewCatalogTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogTemplateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogTemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogTemplateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogTemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *catalogTemplateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogTemplateLifecycle) { + sync := NewCatalogTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogTemplateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogTemplateLifecycle) { + sync := NewCatalogTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_lifecycle_adapter.go new file mode 100644 index 0000000..eeaaac6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type CatalogTemplateLifecycle interface { + Create(obj *v3.CatalogTemplate) (runtime.Object, error) + Remove(obj *v3.CatalogTemplate) (runtime.Object, error) + Updated(obj *v3.CatalogTemplate) (runtime.Object, error) +} + +type catalogTemplateLifecycleAdapter struct { + lifecycle CatalogTemplateLifecycle +} + +func (w *catalogTemplateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *catalogTemplateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *catalogTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.CatalogTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.CatalogTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.CatalogTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCatalogTemplateLifecycleAdapter(name string, clusterScoped bool, client CatalogTemplateInterface, l CatalogTemplateLifecycle) CatalogTemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CatalogTemplateGroupVersionResource) + } + adapter := &catalogTemplateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.CatalogTemplate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_controller.go new file mode 100644 index 0000000..bc22193 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CatalogTemplateVersionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "CatalogTemplateVersion", + } + CatalogTemplateVersionResource = metav1.APIResource{ + Name: "catalogtemplateversions", + SingularName: "catalogtemplateversion", + Namespaced: true, + + Kind: CatalogTemplateVersionGroupVersionKind.Kind, + } + + CatalogTemplateVersionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "catalogtemplateversions", + } +) + +func init() { + resource.Put(CatalogTemplateVersionGroupVersionResource) +} + +// Deprecated: use v3.CatalogTemplateVersion instead +type CatalogTemplateVersion = v3.CatalogTemplateVersion + +func NewCatalogTemplateVersion(namespace, name string, obj v3.CatalogTemplateVersion) *v3.CatalogTemplateVersion { + obj.APIVersion, obj.Kind = CatalogTemplateVersionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CatalogTemplateVersionHandlerFunc func(key string, obj *v3.CatalogTemplateVersion) (runtime.Object, error) + +type CatalogTemplateVersionChangeHandlerFunc func(obj *v3.CatalogTemplateVersion) (runtime.Object, error) + +type CatalogTemplateVersionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.CatalogTemplateVersion, err error) + Get(namespace, name string) (*v3.CatalogTemplateVersion, error) +} + +type CatalogTemplateVersionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CatalogTemplateVersionLister + AddHandler(ctx context.Context, name string, handler CatalogTemplateVersionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateVersionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CatalogTemplateVersionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CatalogTemplateVersionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CatalogTemplateVersionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) + Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) + Update(*v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CatalogTemplateVersionController + AddHandler(ctx context.Context, name string, sync CatalogTemplateVersionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateVersionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CatalogTemplateVersionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogTemplateVersionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogTemplateVersionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogTemplateVersionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogTemplateVersionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogTemplateVersionLifecycle) +} + +type catalogTemplateVersionLister struct { + ns string + controller *catalogTemplateVersionController +} + +func (l *catalogTemplateVersionLister) List(namespace string, selector labels.Selector) (ret []*v3.CatalogTemplateVersion, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.CatalogTemplateVersion)) + }) + return +} + +func (l *catalogTemplateVersionLister) Get(namespace, name string) (*v3.CatalogTemplateVersion, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CatalogTemplateVersionGroupVersionKind.Group, + Resource: CatalogTemplateVersionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.CatalogTemplateVersion), nil +} + +type catalogTemplateVersionController struct { + ns string + controller.GenericController +} + +func (c *catalogTemplateVersionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *catalogTemplateVersionController) Lister() CatalogTemplateVersionLister { + return &catalogTemplateVersionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *catalogTemplateVersionController) AddHandler(ctx context.Context, name string, handler CatalogTemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplateVersion); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateVersionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CatalogTemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplateVersion); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateVersionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CatalogTemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplateVersion); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *catalogTemplateVersionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CatalogTemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CatalogTemplateVersion); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type catalogTemplateVersionFactory struct { +} + +func (c catalogTemplateVersionFactory) Object() runtime.Object { + return &v3.CatalogTemplateVersion{} +} + +func (c catalogTemplateVersionFactory) List() runtime.Object { + return &v3.CatalogTemplateVersionList{} +} + +func (s *catalogTemplateVersionClient) Controller() CatalogTemplateVersionController { + genericController := controller.NewGenericController(s.ns, CatalogTemplateVersionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CatalogTemplateVersionGroupVersionResource, CatalogTemplateVersionGroupVersionKind.Kind, true)) + + return &catalogTemplateVersionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type catalogTemplateVersionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CatalogTemplateVersionController +} + +func (s *catalogTemplateVersionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *catalogTemplateVersionClient) Create(o *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) Get(name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) Update(o *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) UpdateStatus(o *v3.CatalogTemplateVersion) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *catalogTemplateVersionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *catalogTemplateVersionClient) List(opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.CatalogTemplateVersionList), err +} + +func (s *catalogTemplateVersionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CatalogTemplateVersionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.CatalogTemplateVersionList), err +} + +func (s *catalogTemplateVersionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *catalogTemplateVersionClient) Patch(o *v3.CatalogTemplateVersion, patchType types.PatchType, data []byte, subresources ...string) (*v3.CatalogTemplateVersion, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.CatalogTemplateVersion), err +} + +func (s *catalogTemplateVersionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *catalogTemplateVersionClient) AddHandler(ctx context.Context, name string, sync CatalogTemplateVersionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogTemplateVersionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CatalogTemplateVersionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogTemplateVersionClient) AddLifecycle(ctx context.Context, name string, lifecycle CatalogTemplateVersionLifecycle) { + sync := NewCatalogTemplateVersionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *catalogTemplateVersionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CatalogTemplateVersionLifecycle) { + sync := NewCatalogTemplateVersionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *catalogTemplateVersionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CatalogTemplateVersionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogTemplateVersionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CatalogTemplateVersionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *catalogTemplateVersionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CatalogTemplateVersionLifecycle) { + sync := NewCatalogTemplateVersionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *catalogTemplateVersionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CatalogTemplateVersionLifecycle) { + sync := NewCatalogTemplateVersionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_lifecycle_adapter.go new file mode 100644 index 0000000..8faa07e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_catalog_template_version_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type CatalogTemplateVersionLifecycle interface { + Create(obj *v3.CatalogTemplateVersion) (runtime.Object, error) + Remove(obj *v3.CatalogTemplateVersion) (runtime.Object, error) + Updated(obj *v3.CatalogTemplateVersion) (runtime.Object, error) +} + +type catalogTemplateVersionLifecycleAdapter struct { + lifecycle CatalogTemplateVersionLifecycle +} + +func (w *catalogTemplateVersionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *catalogTemplateVersionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *catalogTemplateVersionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.CatalogTemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogTemplateVersionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.CatalogTemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *catalogTemplateVersionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.CatalogTemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCatalogTemplateVersionLifecycleAdapter(name string, clusterScoped bool, client CatalogTemplateVersionInterface, l CatalogTemplateVersionLifecycle) CatalogTemplateVersionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CatalogTemplateVersionGroupVersionResource) + } + adapter := &catalogTemplateVersionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.CatalogTemplateVersion) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_controller.go new file mode 100644 index 0000000..547f0b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CloudCredentialGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "CloudCredential", + } + CloudCredentialResource = metav1.APIResource{ + Name: "cloudcredentials", + SingularName: "cloudcredential", + Namespaced: true, + + Kind: CloudCredentialGroupVersionKind.Kind, + } + + CloudCredentialGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "cloudcredentials", + } +) + +func init() { + resource.Put(CloudCredentialGroupVersionResource) +} + +// Deprecated: use v3.CloudCredential instead +type CloudCredential = v3.CloudCredential + +func NewCloudCredential(namespace, name string, obj v3.CloudCredential) *v3.CloudCredential { + obj.APIVersion, obj.Kind = CloudCredentialGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CloudCredentialHandlerFunc func(key string, obj *v3.CloudCredential) (runtime.Object, error) + +type CloudCredentialChangeHandlerFunc func(obj *v3.CloudCredential) (runtime.Object, error) + +type CloudCredentialLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.CloudCredential, err error) + Get(namespace, name string) (*v3.CloudCredential, error) +} + +type CloudCredentialController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CloudCredentialLister + AddHandler(ctx context.Context, name string, handler CloudCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CloudCredentialHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CloudCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CloudCredentialHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CloudCredentialInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.CloudCredential) (*v3.CloudCredential, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CloudCredential, error) + Get(name string, opts metav1.GetOptions) (*v3.CloudCredential, error) + Update(*v3.CloudCredential) (*v3.CloudCredential, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.CloudCredentialList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CloudCredentialList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CloudCredentialController + AddHandler(ctx context.Context, name string, sync CloudCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CloudCredentialHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CloudCredentialLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CloudCredentialLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CloudCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CloudCredentialHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CloudCredentialLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CloudCredentialLifecycle) +} + +type cloudCredentialLister struct { + ns string + controller *cloudCredentialController +} + +func (l *cloudCredentialLister) List(namespace string, selector labels.Selector) (ret []*v3.CloudCredential, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.CloudCredential)) + }) + return +} + +func (l *cloudCredentialLister) Get(namespace, name string) (*v3.CloudCredential, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CloudCredentialGroupVersionKind.Group, + Resource: CloudCredentialGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.CloudCredential), nil +} + +type cloudCredentialController struct { + ns string + controller.GenericController +} + +func (c *cloudCredentialController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *cloudCredentialController) Lister() CloudCredentialLister { + return &cloudCredentialLister{ + ns: c.ns, + controller: c, + } +} + +func (c *cloudCredentialController) AddHandler(ctx context.Context, name string, handler CloudCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CloudCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cloudCredentialController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CloudCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CloudCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cloudCredentialController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CloudCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CloudCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *cloudCredentialController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CloudCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.CloudCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type cloudCredentialFactory struct { +} + +func (c cloudCredentialFactory) Object() runtime.Object { + return &v3.CloudCredential{} +} + +func (c cloudCredentialFactory) List() runtime.Object { + return &v3.CloudCredentialList{} +} + +func (s *cloudCredentialClient) Controller() CloudCredentialController { + genericController := controller.NewGenericController(s.ns, CloudCredentialGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CloudCredentialGroupVersionResource, CloudCredentialGroupVersionKind.Kind, true)) + + return &cloudCredentialController{ + ns: s.ns, + GenericController: genericController, + } +} + +type cloudCredentialClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CloudCredentialController +} + +func (s *cloudCredentialClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *cloudCredentialClient) Create(o *v3.CloudCredential) (*v3.CloudCredential, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) Get(name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.CloudCredential, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) Update(o *v3.CloudCredential) (*v3.CloudCredential, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) UpdateStatus(o *v3.CloudCredential) (*v3.CloudCredential, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *cloudCredentialClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *cloudCredentialClient) List(opts metav1.ListOptions) (*v3.CloudCredentialList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.CloudCredentialList), err +} + +func (s *cloudCredentialClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CloudCredentialList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.CloudCredentialList), err +} + +func (s *cloudCredentialClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *cloudCredentialClient) Patch(o *v3.CloudCredential, patchType types.PatchType, data []byte, subresources ...string) (*v3.CloudCredential, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.CloudCredential), err +} + +func (s *cloudCredentialClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *cloudCredentialClient) AddHandler(ctx context.Context, name string, sync CloudCredentialHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *cloudCredentialClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CloudCredentialHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *cloudCredentialClient) AddLifecycle(ctx context.Context, name string, lifecycle CloudCredentialLifecycle) { + sync := NewCloudCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *cloudCredentialClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CloudCredentialLifecycle) { + sync := NewCloudCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *cloudCredentialClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CloudCredentialHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *cloudCredentialClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CloudCredentialHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *cloudCredentialClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CloudCredentialLifecycle) { + sync := NewCloudCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *cloudCredentialClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CloudCredentialLifecycle) { + sync := NewCloudCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_lifecycle_adapter.go new file mode 100644 index 0000000..2f7ff43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cloud_credential_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type CloudCredentialLifecycle interface { + Create(obj *v3.CloudCredential) (runtime.Object, error) + Remove(obj *v3.CloudCredential) (runtime.Object, error) + Updated(obj *v3.CloudCredential) (runtime.Object, error) +} + +type cloudCredentialLifecycleAdapter struct { + lifecycle CloudCredentialLifecycle +} + +func (w *cloudCredentialLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *cloudCredentialLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *cloudCredentialLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.CloudCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *cloudCredentialLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.CloudCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *cloudCredentialLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.CloudCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCloudCredentialLifecycleAdapter(name string, clusterScoped bool, client CloudCredentialInterface, l CloudCredentialLifecycle) CloudCredentialHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CloudCredentialGroupVersionResource) + } + adapter := &cloudCredentialLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.CloudCredential) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_controller.go new file mode 100644 index 0000000..ef748fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterCatalogGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterCatalog", + } + ClusterCatalogResource = metav1.APIResource{ + Name: "clustercatalogs", + SingularName: "clustercatalog", + Namespaced: true, + + Kind: ClusterCatalogGroupVersionKind.Kind, + } + + ClusterCatalogGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clustercatalogs", + } +) + +func init() { + resource.Put(ClusterCatalogGroupVersionResource) +} + +// Deprecated: use v3.ClusterCatalog instead +type ClusterCatalog = v3.ClusterCatalog + +func NewClusterCatalog(namespace, name string, obj v3.ClusterCatalog) *v3.ClusterCatalog { + obj.APIVersion, obj.Kind = ClusterCatalogGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterCatalogHandlerFunc func(key string, obj *v3.ClusterCatalog) (runtime.Object, error) + +type ClusterCatalogChangeHandlerFunc func(obj *v3.ClusterCatalog) (runtime.Object, error) + +type ClusterCatalogLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterCatalog, err error) + Get(namespace, name string) (*v3.ClusterCatalog, error) +} + +type ClusterCatalogController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterCatalogLister + AddHandler(ctx context.Context, name string, handler ClusterCatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterCatalogHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterCatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterCatalogHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterCatalogInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterCatalog) (*v3.ClusterCatalog, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) + Update(*v3.ClusterCatalog) (*v3.ClusterCatalog, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterCatalogList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterCatalogList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterCatalogController + AddHandler(ctx context.Context, name string, sync ClusterCatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterCatalogHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterCatalogLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterCatalogLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterCatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterCatalogHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterCatalogLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterCatalogLifecycle) +} + +type clusterCatalogLister struct { + ns string + controller *clusterCatalogController +} + +func (l *clusterCatalogLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterCatalog, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterCatalog)) + }) + return +} + +func (l *clusterCatalogLister) Get(namespace, name string) (*v3.ClusterCatalog, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterCatalogGroupVersionKind.Group, + Resource: ClusterCatalogGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterCatalog), nil +} + +type clusterCatalogController struct { + ns string + controller.GenericController +} + +func (c *clusterCatalogController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterCatalogController) Lister() ClusterCatalogLister { + return &clusterCatalogLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterCatalogController) AddHandler(ctx context.Context, name string, handler ClusterCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterCatalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterCatalogController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterCatalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterCatalogController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterCatalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterCatalogController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterCatalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterCatalogFactory struct { +} + +func (c clusterCatalogFactory) Object() runtime.Object { + return &v3.ClusterCatalog{} +} + +func (c clusterCatalogFactory) List() runtime.Object { + return &v3.ClusterCatalogList{} +} + +func (s *clusterCatalogClient) Controller() ClusterCatalogController { + genericController := controller.NewGenericController(s.ns, ClusterCatalogGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterCatalogGroupVersionResource, ClusterCatalogGroupVersionKind.Kind, true)) + + return &clusterCatalogController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterCatalogClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterCatalogController +} + +func (s *clusterCatalogClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterCatalogClient) Create(o *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) Update(o *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) UpdateStatus(o *v3.ClusterCatalog) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterCatalogClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterCatalogClient) List(opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterCatalogList), err +} + +func (s *clusterCatalogClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterCatalogList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterCatalogList), err +} + +func (s *clusterCatalogClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterCatalogClient) Patch(o *v3.ClusterCatalog, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterCatalog, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterCatalog), err +} + +func (s *clusterCatalogClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterCatalogClient) AddHandler(ctx context.Context, name string, sync ClusterCatalogHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterCatalogClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterCatalogHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterCatalogClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterCatalogLifecycle) { + sync := NewClusterCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterCatalogClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterCatalogLifecycle) { + sync := NewClusterCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterCatalogClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterCatalogHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterCatalogClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterCatalogHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterCatalogClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterCatalogLifecycle) { + sync := NewClusterCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterCatalogClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterCatalogLifecycle) { + sync := NewClusterCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_lifecycle_adapter.go new file mode 100644 index 0000000..f7c6af3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_catalog_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterCatalogLifecycle interface { + Create(obj *v3.ClusterCatalog) (runtime.Object, error) + Remove(obj *v3.ClusterCatalog) (runtime.Object, error) + Updated(obj *v3.ClusterCatalog) (runtime.Object, error) +} + +type clusterCatalogLifecycleAdapter struct { + lifecycle ClusterCatalogLifecycle +} + +func (w *clusterCatalogLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterCatalogLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterCatalogLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterCatalogLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterCatalogLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterCatalogLifecycleAdapter(name string, clusterScoped bool, client ClusterCatalogInterface, l ClusterCatalogLifecycle) ClusterCatalogHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterCatalogGroupVersionResource) + } + adapter := &clusterCatalogLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterCatalog) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_controller.go new file mode 100644 index 0000000..9c502a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Cluster", + } + ClusterResource = metav1.APIResource{ + Name: "clusters", + SingularName: "cluster", + Namespaced: false, + Kind: ClusterGroupVersionKind.Kind, + } + + ClusterGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusters", + } +) + +func init() { + resource.Put(ClusterGroupVersionResource) +} + +// Deprecated: use v3.Cluster instead +type Cluster = v3.Cluster + +func NewCluster(namespace, name string, obj v3.Cluster) *v3.Cluster { + obj.APIVersion, obj.Kind = ClusterGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterHandlerFunc func(key string, obj *v3.Cluster) (runtime.Object, error) + +type ClusterChangeHandlerFunc func(obj *v3.Cluster) (runtime.Object, error) + +type ClusterLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Cluster, err error) + Get(namespace, name string) (*v3.Cluster, error) +} + +type ClusterController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterLister + AddHandler(ctx context.Context, name string, handler ClusterHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Cluster) (*v3.Cluster, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Cluster, error) + Get(name string, opts metav1.GetOptions) (*v3.Cluster, error) + Update(*v3.Cluster) (*v3.Cluster, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterController + AddHandler(ctx context.Context, name string, sync ClusterHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterLifecycle) +} + +type clusterLister struct { + ns string + controller *clusterController +} + +func (l *clusterLister) List(namespace string, selector labels.Selector) (ret []*v3.Cluster, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Cluster)) + }) + return +} + +func (l *clusterLister) Get(namespace, name string) (*v3.Cluster, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterGroupVersionKind.Group, + Resource: ClusterGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Cluster), nil +} + +type clusterController struct { + ns string + controller.GenericController +} + +func (c *clusterController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterController) Lister() ClusterLister { + return &clusterLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterController) AddHandler(ctx context.Context, name string, handler ClusterHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Cluster); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Cluster); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Cluster); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Cluster); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterFactory struct { +} + +func (c clusterFactory) Object() runtime.Object { + return &v3.Cluster{} +} + +func (c clusterFactory) List() runtime.Object { + return &v3.ClusterList{} +} + +func (s *clusterClient) Controller() ClusterController { + genericController := controller.NewGenericController(s.ns, ClusterGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterGroupVersionResource, ClusterGroupVersionKind.Kind, false)) + + return &clusterController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterController +} + +func (s *clusterClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterClient) Create(o *v3.Cluster) (*v3.Cluster, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) Get(name string, opts metav1.GetOptions) (*v3.Cluster, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Cluster, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) Update(o *v3.Cluster) (*v3.Cluster, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) UpdateStatus(o *v3.Cluster) (*v3.Cluster, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterClient) List(opts metav1.ListOptions) (*v3.ClusterList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterList), err +} + +func (s *clusterClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterList), err +} + +func (s *clusterClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterClient) Patch(o *v3.Cluster, patchType types.PatchType, data []byte, subresources ...string) (*v3.Cluster, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Cluster), err +} + +func (s *clusterClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterClient) AddHandler(ctx context.Context, name string, sync ClusterHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterLifecycle) { + sync := NewClusterLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterLifecycle) { + sync := NewClusterLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterLifecycle) { + sync := NewClusterLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterLifecycle) { + sync := NewClusterLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_lifecycle_adapter.go new file mode 100644 index 0000000..4457772 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterLifecycle interface { + Create(obj *v3.Cluster) (runtime.Object, error) + Remove(obj *v3.Cluster) (runtime.Object, error) + Updated(obj *v3.Cluster) (runtime.Object, error) +} + +type clusterLifecycleAdapter struct { + lifecycle ClusterLifecycle +} + +func (w *clusterLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Cluster)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Cluster)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Cluster)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterLifecycleAdapter(name string, clusterScoped bool, client ClusterInterface, l ClusterLifecycle) ClusterHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterGroupVersionResource) + } + adapter := &clusterLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Cluster) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_controller.go new file mode 100644 index 0000000..cd77fb0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterRegistrationTokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterRegistrationToken", + } + ClusterRegistrationTokenResource = metav1.APIResource{ + Name: "clusterregistrationtokens", + SingularName: "clusterregistrationtoken", + Namespaced: true, + + Kind: ClusterRegistrationTokenGroupVersionKind.Kind, + } + + ClusterRegistrationTokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusterregistrationtokens", + } +) + +func init() { + resource.Put(ClusterRegistrationTokenGroupVersionResource) +} + +// Deprecated: use v3.ClusterRegistrationToken instead +type ClusterRegistrationToken = v3.ClusterRegistrationToken + +func NewClusterRegistrationToken(namespace, name string, obj v3.ClusterRegistrationToken) *v3.ClusterRegistrationToken { + obj.APIVersion, obj.Kind = ClusterRegistrationTokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterRegistrationTokenHandlerFunc func(key string, obj *v3.ClusterRegistrationToken) (runtime.Object, error) + +type ClusterRegistrationTokenChangeHandlerFunc func(obj *v3.ClusterRegistrationToken) (runtime.Object, error) + +type ClusterRegistrationTokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterRegistrationToken, err error) + Get(namespace, name string) (*v3.ClusterRegistrationToken, error) +} + +type ClusterRegistrationTokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterRegistrationTokenLister + AddHandler(ctx context.Context, name string, handler ClusterRegistrationTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRegistrationTokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterRegistrationTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterRegistrationTokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterRegistrationTokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) + Update(*v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterRegistrationTokenController + AddHandler(ctx context.Context, name string, sync ClusterRegistrationTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRegistrationTokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterRegistrationTokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRegistrationTokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRegistrationTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRegistrationTokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRegistrationTokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRegistrationTokenLifecycle) +} + +type clusterRegistrationTokenLister struct { + ns string + controller *clusterRegistrationTokenController +} + +func (l *clusterRegistrationTokenLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterRegistrationToken, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterRegistrationToken)) + }) + return +} + +func (l *clusterRegistrationTokenLister) Get(namespace, name string) (*v3.ClusterRegistrationToken, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterRegistrationTokenGroupVersionKind.Group, + Resource: ClusterRegistrationTokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterRegistrationToken), nil +} + +type clusterRegistrationTokenController struct { + ns string + controller.GenericController +} + +func (c *clusterRegistrationTokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterRegistrationTokenController) Lister() ClusterRegistrationTokenLister { + return &clusterRegistrationTokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterRegistrationTokenController) AddHandler(ctx context.Context, name string, handler ClusterRegistrationTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRegistrationToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRegistrationTokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterRegistrationTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRegistrationToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRegistrationTokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterRegistrationTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRegistrationToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRegistrationTokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterRegistrationTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRegistrationToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterRegistrationTokenFactory struct { +} + +func (c clusterRegistrationTokenFactory) Object() runtime.Object { + return &v3.ClusterRegistrationToken{} +} + +func (c clusterRegistrationTokenFactory) List() runtime.Object { + return &v3.ClusterRegistrationTokenList{} +} + +func (s *clusterRegistrationTokenClient) Controller() ClusterRegistrationTokenController { + genericController := controller.NewGenericController(s.ns, ClusterRegistrationTokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterRegistrationTokenGroupVersionResource, ClusterRegistrationTokenGroupVersionKind.Kind, true)) + + return &clusterRegistrationTokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterRegistrationTokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterRegistrationTokenController +} + +func (s *clusterRegistrationTokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterRegistrationTokenClient) Create(o *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) Update(o *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) UpdateStatus(o *v3.ClusterRegistrationToken) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterRegistrationTokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterRegistrationTokenClient) List(opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterRegistrationTokenList), err +} + +func (s *clusterRegistrationTokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRegistrationTokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterRegistrationTokenList), err +} + +func (s *clusterRegistrationTokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterRegistrationTokenClient) Patch(o *v3.ClusterRegistrationToken, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterRegistrationToken, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterRegistrationToken), err +} + +func (s *clusterRegistrationTokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterRegistrationTokenClient) AddHandler(ctx context.Context, name string, sync ClusterRegistrationTokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRegistrationTokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRegistrationTokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRegistrationTokenClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterRegistrationTokenLifecycle) { + sync := NewClusterRegistrationTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRegistrationTokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRegistrationTokenLifecycle) { + sync := NewClusterRegistrationTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRegistrationTokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRegistrationTokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRegistrationTokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRegistrationTokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterRegistrationTokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRegistrationTokenLifecycle) { + sync := NewClusterRegistrationTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRegistrationTokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRegistrationTokenLifecycle) { + sync := NewClusterRegistrationTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_lifecycle_adapter.go new file mode 100644 index 0000000..9e1bab3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_registration_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterRegistrationTokenLifecycle interface { + Create(obj *v3.ClusterRegistrationToken) (runtime.Object, error) + Remove(obj *v3.ClusterRegistrationToken) (runtime.Object, error) + Updated(obj *v3.ClusterRegistrationToken) (runtime.Object, error) +} + +type clusterRegistrationTokenLifecycleAdapter struct { + lifecycle ClusterRegistrationTokenLifecycle +} + +func (w *clusterRegistrationTokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterRegistrationTokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterRegistrationTokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterRegistrationToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRegistrationTokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterRegistrationToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRegistrationTokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterRegistrationToken)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterRegistrationTokenLifecycleAdapter(name string, clusterScoped bool, client ClusterRegistrationTokenInterface, l ClusterRegistrationTokenLifecycle) ClusterRegistrationTokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterRegistrationTokenGroupVersionResource) + } + adapter := &clusterRegistrationTokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterRegistrationToken) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_controller.go new file mode 100644 index 0000000..598a9ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterRoleTemplateBindingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterRoleTemplateBinding", + } + ClusterRoleTemplateBindingResource = metav1.APIResource{ + Name: "clusterroletemplatebindings", + SingularName: "clusterroletemplatebinding", + Namespaced: true, + + Kind: ClusterRoleTemplateBindingGroupVersionKind.Kind, + } + + ClusterRoleTemplateBindingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusterroletemplatebindings", + } +) + +func init() { + resource.Put(ClusterRoleTemplateBindingGroupVersionResource) +} + +// Deprecated: use v3.ClusterRoleTemplateBinding instead +type ClusterRoleTemplateBinding = v3.ClusterRoleTemplateBinding + +func NewClusterRoleTemplateBinding(namespace, name string, obj v3.ClusterRoleTemplateBinding) *v3.ClusterRoleTemplateBinding { + obj.APIVersion, obj.Kind = ClusterRoleTemplateBindingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterRoleTemplateBindingHandlerFunc func(key string, obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) + +type ClusterRoleTemplateBindingChangeHandlerFunc func(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) + +type ClusterRoleTemplateBindingLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterRoleTemplateBinding, err error) + Get(namespace, name string) (*v3.ClusterRoleTemplateBinding, error) +} + +type ClusterRoleTemplateBindingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterRoleTemplateBindingLister + AddHandler(ctx context.Context, name string, handler ClusterRoleTemplateBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleTemplateBindingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterRoleTemplateBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterRoleTemplateBindingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterRoleTemplateBindingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) + Update(*v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterRoleTemplateBindingController + AddHandler(ctx context.Context, name string, sync ClusterRoleTemplateBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleTemplateBindingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleTemplateBindingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleTemplateBindingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleTemplateBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleTemplateBindingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleTemplateBindingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleTemplateBindingLifecycle) +} + +type clusterRoleTemplateBindingLister struct { + ns string + controller *clusterRoleTemplateBindingController +} + +func (l *clusterRoleTemplateBindingLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterRoleTemplateBinding, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterRoleTemplateBinding)) + }) + return +} + +func (l *clusterRoleTemplateBindingLister) Get(namespace, name string) (*v3.ClusterRoleTemplateBinding, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterRoleTemplateBindingGroupVersionKind.Group, + Resource: ClusterRoleTemplateBindingGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterRoleTemplateBinding), nil +} + +type clusterRoleTemplateBindingController struct { + ns string + controller.GenericController +} + +func (c *clusterRoleTemplateBindingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterRoleTemplateBindingController) Lister() ClusterRoleTemplateBindingLister { + return &clusterRoleTemplateBindingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterRoleTemplateBindingController) AddHandler(ctx context.Context, name string, handler ClusterRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRoleTemplateBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleTemplateBindingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRoleTemplateBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleTemplateBindingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRoleTemplateBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleTemplateBindingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterRoleTemplateBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterRoleTemplateBindingFactory struct { +} + +func (c clusterRoleTemplateBindingFactory) Object() runtime.Object { + return &v3.ClusterRoleTemplateBinding{} +} + +func (c clusterRoleTemplateBindingFactory) List() runtime.Object { + return &v3.ClusterRoleTemplateBindingList{} +} + +func (s *clusterRoleTemplateBindingClient) Controller() ClusterRoleTemplateBindingController { + genericController := controller.NewGenericController(s.ns, ClusterRoleTemplateBindingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterRoleTemplateBindingGroupVersionResource, ClusterRoleTemplateBindingGroupVersionKind.Kind, true)) + + return &clusterRoleTemplateBindingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterRoleTemplateBindingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterRoleTemplateBindingController +} + +func (s *clusterRoleTemplateBindingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterRoleTemplateBindingClient) Create(o *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) Update(o *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) UpdateStatus(o *v3.ClusterRoleTemplateBinding) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterRoleTemplateBindingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterRoleTemplateBindingClient) List(opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterRoleTemplateBindingList), err +} + +func (s *clusterRoleTemplateBindingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterRoleTemplateBindingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterRoleTemplateBindingList), err +} + +func (s *clusterRoleTemplateBindingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterRoleTemplateBindingClient) Patch(o *v3.ClusterRoleTemplateBinding, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterRoleTemplateBinding, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterRoleTemplateBinding), err +} + +func (s *clusterRoleTemplateBindingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterRoleTemplateBindingClient) AddHandler(ctx context.Context, name string, sync ClusterRoleTemplateBindingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleTemplateBindingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleTemplateBindingLifecycle) { + sync := NewClusterRoleTemplateBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleTemplateBindingLifecycle) { + sync := NewClusterRoleTemplateBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleTemplateBindingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleTemplateBindingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleTemplateBindingLifecycle) { + sync := NewClusterRoleTemplateBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleTemplateBindingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleTemplateBindingLifecycle) { + sync := NewClusterRoleTemplateBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_lifecycle_adapter.go new file mode 100644 index 0000000..5615571 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_role_template_binding_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterRoleTemplateBindingLifecycle interface { + Create(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) + Remove(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) + Updated(obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) +} + +type clusterRoleTemplateBindingLifecycleAdapter struct { + lifecycle ClusterRoleTemplateBindingLifecycle +} + +func (w *clusterRoleTemplateBindingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterRoleTemplateBindingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterRoleTemplateBindingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleTemplateBindingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleTemplateBindingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterRoleTemplateBindingLifecycleAdapter(name string, clusterScoped bool, client ClusterRoleTemplateBindingInterface, l ClusterRoleTemplateBindingLifecycle) ClusterRoleTemplateBindingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterRoleTemplateBindingGroupVersionResource) + } + adapter := &clusterRoleTemplateBindingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterRoleTemplateBinding) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_controller.go new file mode 100644 index 0000000..a404fd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterTemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterTemplate", + } + ClusterTemplateResource = metav1.APIResource{ + Name: "clustertemplates", + SingularName: "clustertemplate", + Namespaced: true, + + Kind: ClusterTemplateGroupVersionKind.Kind, + } + + ClusterTemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clustertemplates", + } +) + +func init() { + resource.Put(ClusterTemplateGroupVersionResource) +} + +// Deprecated: use v3.ClusterTemplate instead +type ClusterTemplate = v3.ClusterTemplate + +func NewClusterTemplate(namespace, name string, obj v3.ClusterTemplate) *v3.ClusterTemplate { + obj.APIVersion, obj.Kind = ClusterTemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterTemplateHandlerFunc func(key string, obj *v3.ClusterTemplate) (runtime.Object, error) + +type ClusterTemplateChangeHandlerFunc func(obj *v3.ClusterTemplate) (runtime.Object, error) + +type ClusterTemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterTemplate, err error) + Get(namespace, name string) (*v3.ClusterTemplate, error) +} + +type ClusterTemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterTemplateLister + AddHandler(ctx context.Context, name string, handler ClusterTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterTemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterTemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterTemplate) (*v3.ClusterTemplate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) + Update(*v3.ClusterTemplate) (*v3.ClusterTemplate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterTemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterTemplateController + AddHandler(ctx context.Context, name string, sync ClusterTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterTemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterTemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterTemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterTemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterTemplateLifecycle) +} + +type clusterTemplateLister struct { + ns string + controller *clusterTemplateController +} + +func (l *clusterTemplateLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterTemplate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterTemplate)) + }) + return +} + +func (l *clusterTemplateLister) Get(namespace, name string) (*v3.ClusterTemplate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterTemplateGroupVersionKind.Group, + Resource: ClusterTemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterTemplate), nil +} + +type clusterTemplateController struct { + ns string + controller.GenericController +} + +func (c *clusterTemplateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterTemplateController) Lister() ClusterTemplateLister { + return &clusterTemplateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterTemplateController) AddHandler(ctx context.Context, name string, handler ClusterTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterTemplateFactory struct { +} + +func (c clusterTemplateFactory) Object() runtime.Object { + return &v3.ClusterTemplate{} +} + +func (c clusterTemplateFactory) List() runtime.Object { + return &v3.ClusterTemplateList{} +} + +func (s *clusterTemplateClient) Controller() ClusterTemplateController { + genericController := controller.NewGenericController(s.ns, ClusterTemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterTemplateGroupVersionResource, ClusterTemplateGroupVersionKind.Kind, true)) + + return &clusterTemplateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterTemplateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterTemplateController +} + +func (s *clusterTemplateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterTemplateClient) Create(o *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) Update(o *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) UpdateStatus(o *v3.ClusterTemplate) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterTemplateClient) List(opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterTemplateList), err +} + +func (s *clusterTemplateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterTemplateList), err +} + +func (s *clusterTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterTemplateClient) Patch(o *v3.ClusterTemplate, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterTemplate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterTemplate), err +} + +func (s *clusterTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterTemplateClient) AddHandler(ctx context.Context, name string, sync ClusterTemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterTemplateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterTemplateClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterTemplateLifecycle) { + sync := NewClusterTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterTemplateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterTemplateLifecycle) { + sync := NewClusterTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterTemplateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterTemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterTemplateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterTemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterTemplateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterTemplateLifecycle) { + sync := NewClusterTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterTemplateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterTemplateLifecycle) { + sync := NewClusterTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_lifecycle_adapter.go new file mode 100644 index 0000000..7962e7f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterTemplateLifecycle interface { + Create(obj *v3.ClusterTemplate) (runtime.Object, error) + Remove(obj *v3.ClusterTemplate) (runtime.Object, error) + Updated(obj *v3.ClusterTemplate) (runtime.Object, error) +} + +type clusterTemplateLifecycleAdapter struct { + lifecycle ClusterTemplateLifecycle +} + +func (w *clusterTemplateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterTemplateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterTemplateLifecycleAdapter(name string, clusterScoped bool, client ClusterTemplateInterface, l ClusterTemplateLifecycle) ClusterTemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterTemplateGroupVersionResource) + } + adapter := &clusterTemplateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterTemplate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_controller.go new file mode 100644 index 0000000..9bf1b21 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterTemplateRevisionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterTemplateRevision", + } + ClusterTemplateRevisionResource = metav1.APIResource{ + Name: "clustertemplaterevisions", + SingularName: "clustertemplaterevision", + Namespaced: true, + + Kind: ClusterTemplateRevisionGroupVersionKind.Kind, + } + + ClusterTemplateRevisionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clustertemplaterevisions", + } +) + +func init() { + resource.Put(ClusterTemplateRevisionGroupVersionResource) +} + +// Deprecated: use v3.ClusterTemplateRevision instead +type ClusterTemplateRevision = v3.ClusterTemplateRevision + +func NewClusterTemplateRevision(namespace, name string, obj v3.ClusterTemplateRevision) *v3.ClusterTemplateRevision { + obj.APIVersion, obj.Kind = ClusterTemplateRevisionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterTemplateRevisionHandlerFunc func(key string, obj *v3.ClusterTemplateRevision) (runtime.Object, error) + +type ClusterTemplateRevisionChangeHandlerFunc func(obj *v3.ClusterTemplateRevision) (runtime.Object, error) + +type ClusterTemplateRevisionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ClusterTemplateRevision, err error) + Get(namespace, name string) (*v3.ClusterTemplateRevision, error) +} + +type ClusterTemplateRevisionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterTemplateRevisionLister + AddHandler(ctx context.Context, name string, handler ClusterTemplateRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateRevisionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterTemplateRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterTemplateRevisionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterTemplateRevisionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) + Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) + Update(*v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterTemplateRevisionController + AddHandler(ctx context.Context, name string, sync ClusterTemplateRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateRevisionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterTemplateRevisionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterTemplateRevisionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterTemplateRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterTemplateRevisionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterTemplateRevisionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterTemplateRevisionLifecycle) +} + +type clusterTemplateRevisionLister struct { + ns string + controller *clusterTemplateRevisionController +} + +func (l *clusterTemplateRevisionLister) List(namespace string, selector labels.Selector) (ret []*v3.ClusterTemplateRevision, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ClusterTemplateRevision)) + }) + return +} + +func (l *clusterTemplateRevisionLister) Get(namespace, name string) (*v3.ClusterTemplateRevision, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterTemplateRevisionGroupVersionKind.Group, + Resource: ClusterTemplateRevisionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ClusterTemplateRevision), nil +} + +type clusterTemplateRevisionController struct { + ns string + controller.GenericController +} + +func (c *clusterTemplateRevisionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterTemplateRevisionController) Lister() ClusterTemplateRevisionLister { + return &clusterTemplateRevisionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterTemplateRevisionController) AddHandler(ctx context.Context, name string, handler ClusterTemplateRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplateRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateRevisionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterTemplateRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplateRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateRevisionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterTemplateRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplateRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterTemplateRevisionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterTemplateRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ClusterTemplateRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterTemplateRevisionFactory struct { +} + +func (c clusterTemplateRevisionFactory) Object() runtime.Object { + return &v3.ClusterTemplateRevision{} +} + +func (c clusterTemplateRevisionFactory) List() runtime.Object { + return &v3.ClusterTemplateRevisionList{} +} + +func (s *clusterTemplateRevisionClient) Controller() ClusterTemplateRevisionController { + genericController := controller.NewGenericController(s.ns, ClusterTemplateRevisionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterTemplateRevisionGroupVersionResource, ClusterTemplateRevisionGroupVersionKind.Kind, true)) + + return &clusterTemplateRevisionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterTemplateRevisionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterTemplateRevisionController +} + +func (s *clusterTemplateRevisionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterTemplateRevisionClient) Create(o *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) Get(name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) Update(o *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) UpdateStatus(o *v3.ClusterTemplateRevision) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterTemplateRevisionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterTemplateRevisionClient) List(opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ClusterTemplateRevisionList), err +} + +func (s *clusterTemplateRevisionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ClusterTemplateRevisionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ClusterTemplateRevisionList), err +} + +func (s *clusterTemplateRevisionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterTemplateRevisionClient) Patch(o *v3.ClusterTemplateRevision, patchType types.PatchType, data []byte, subresources ...string) (*v3.ClusterTemplateRevision, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ClusterTemplateRevision), err +} + +func (s *clusterTemplateRevisionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterTemplateRevisionClient) AddHandler(ctx context.Context, name string, sync ClusterTemplateRevisionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterTemplateRevisionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterTemplateRevisionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterTemplateRevisionClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterTemplateRevisionLifecycle) { + sync := NewClusterTemplateRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterTemplateRevisionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterTemplateRevisionLifecycle) { + sync := NewClusterTemplateRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterTemplateRevisionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterTemplateRevisionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterTemplateRevisionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterTemplateRevisionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterTemplateRevisionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterTemplateRevisionLifecycle) { + sync := NewClusterTemplateRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterTemplateRevisionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterTemplateRevisionLifecycle) { + sync := NewClusterTemplateRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_lifecycle_adapter.go new file mode 100644 index 0000000..0e60052 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_cluster_template_revision_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterTemplateRevisionLifecycle interface { + Create(obj *v3.ClusterTemplateRevision) (runtime.Object, error) + Remove(obj *v3.ClusterTemplateRevision) (runtime.Object, error) + Updated(obj *v3.ClusterTemplateRevision) (runtime.Object, error) +} + +type clusterTemplateRevisionLifecycleAdapter struct { + lifecycle ClusterTemplateRevisionLifecycle +} + +func (w *clusterTemplateRevisionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterTemplateRevisionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterTemplateRevisionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ClusterTemplateRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterTemplateRevisionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ClusterTemplateRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterTemplateRevisionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ClusterTemplateRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterTemplateRevisionLifecycleAdapter(name string, clusterScoped bool, client ClusterTemplateRevisionInterface, l ClusterTemplateRevisionLifecycle) ClusterTemplateRevisionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterTemplateRevisionGroupVersionResource) + } + adapter := &clusterTemplateRevisionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ClusterTemplateRevision) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_controller.go new file mode 100644 index 0000000..20ac331 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ComposeConfigGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ComposeConfig", + } + ComposeConfigResource = metav1.APIResource{ + Name: "composeconfigs", + SingularName: "composeconfig", + Namespaced: false, + Kind: ComposeConfigGroupVersionKind.Kind, + } + + ComposeConfigGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "composeconfigs", + } +) + +func init() { + resource.Put(ComposeConfigGroupVersionResource) +} + +// Deprecated: use v3.ComposeConfig instead +type ComposeConfig = v3.ComposeConfig + +func NewComposeConfig(namespace, name string, obj v3.ComposeConfig) *v3.ComposeConfig { + obj.APIVersion, obj.Kind = ComposeConfigGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ComposeConfigHandlerFunc func(key string, obj *v3.ComposeConfig) (runtime.Object, error) + +type ComposeConfigChangeHandlerFunc func(obj *v3.ComposeConfig) (runtime.Object, error) + +type ComposeConfigLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ComposeConfig, err error) + Get(namespace, name string) (*v3.ComposeConfig, error) +} + +type ComposeConfigController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ComposeConfigLister + AddHandler(ctx context.Context, name string, handler ComposeConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComposeConfigHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ComposeConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ComposeConfigHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ComposeConfigInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ComposeConfig) (*v3.ComposeConfig, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) + Get(name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) + Update(*v3.ComposeConfig) (*v3.ComposeConfig, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ComposeConfigList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ComposeConfigList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ComposeConfigController + AddHandler(ctx context.Context, name string, sync ComposeConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComposeConfigHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ComposeConfigLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ComposeConfigLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ComposeConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ComposeConfigHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ComposeConfigLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ComposeConfigLifecycle) +} + +type composeConfigLister struct { + ns string + controller *composeConfigController +} + +func (l *composeConfigLister) List(namespace string, selector labels.Selector) (ret []*v3.ComposeConfig, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ComposeConfig)) + }) + return +} + +func (l *composeConfigLister) Get(namespace, name string) (*v3.ComposeConfig, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ComposeConfigGroupVersionKind.Group, + Resource: ComposeConfigGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ComposeConfig), nil +} + +type composeConfigController struct { + ns string + controller.GenericController +} + +func (c *composeConfigController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *composeConfigController) Lister() ComposeConfigLister { + return &composeConfigLister{ + ns: c.ns, + controller: c, + } +} + +func (c *composeConfigController) AddHandler(ctx context.Context, name string, handler ComposeConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ComposeConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *composeConfigController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ComposeConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ComposeConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *composeConfigController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ComposeConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ComposeConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *composeConfigController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ComposeConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ComposeConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type composeConfigFactory struct { +} + +func (c composeConfigFactory) Object() runtime.Object { + return &v3.ComposeConfig{} +} + +func (c composeConfigFactory) List() runtime.Object { + return &v3.ComposeConfigList{} +} + +func (s *composeConfigClient) Controller() ComposeConfigController { + genericController := controller.NewGenericController(s.ns, ComposeConfigGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ComposeConfigGroupVersionResource, ComposeConfigGroupVersionKind.Kind, false)) + + return &composeConfigController{ + ns: s.ns, + GenericController: genericController, + } +} + +type composeConfigClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ComposeConfigController +} + +func (s *composeConfigClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *composeConfigClient) Create(o *v3.ComposeConfig) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) Get(name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) Update(o *v3.ComposeConfig) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) UpdateStatus(o *v3.ComposeConfig) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *composeConfigClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *composeConfigClient) List(opts metav1.ListOptions) (*v3.ComposeConfigList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ComposeConfigList), err +} + +func (s *composeConfigClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ComposeConfigList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ComposeConfigList), err +} + +func (s *composeConfigClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *composeConfigClient) Patch(o *v3.ComposeConfig, patchType types.PatchType, data []byte, subresources ...string) (*v3.ComposeConfig, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ComposeConfig), err +} + +func (s *composeConfigClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *composeConfigClient) AddHandler(ctx context.Context, name string, sync ComposeConfigHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *composeConfigClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ComposeConfigHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *composeConfigClient) AddLifecycle(ctx context.Context, name string, lifecycle ComposeConfigLifecycle) { + sync := NewComposeConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *composeConfigClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ComposeConfigLifecycle) { + sync := NewComposeConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *composeConfigClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ComposeConfigHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *composeConfigClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ComposeConfigHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *composeConfigClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ComposeConfigLifecycle) { + sync := NewComposeConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *composeConfigClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ComposeConfigLifecycle) { + sync := NewComposeConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_lifecycle_adapter.go new file mode 100644 index 0000000..fac295c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_compose_config_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ComposeConfigLifecycle interface { + Create(obj *v3.ComposeConfig) (runtime.Object, error) + Remove(obj *v3.ComposeConfig) (runtime.Object, error) + Updated(obj *v3.ComposeConfig) (runtime.Object, error) +} + +type composeConfigLifecycleAdapter struct { + lifecycle ComposeConfigLifecycle +} + +func (w *composeConfigLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *composeConfigLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *composeConfigLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ComposeConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *composeConfigLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ComposeConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *composeConfigLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ComposeConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func NewComposeConfigLifecycleAdapter(name string, clusterScoped bool, client ComposeConfigInterface, l ComposeConfigLifecycle) ComposeConfigHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ComposeConfigGroupVersionResource) + } + adapter := &composeConfigLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ComposeConfig) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_controller.go new file mode 100644 index 0000000..23d337a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + DynamicSchemaGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "DynamicSchema", + } + DynamicSchemaResource = metav1.APIResource{ + Name: "dynamicschemas", + SingularName: "dynamicschema", + Namespaced: false, + Kind: DynamicSchemaGroupVersionKind.Kind, + } + + DynamicSchemaGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "dynamicschemas", + } +) + +func init() { + resource.Put(DynamicSchemaGroupVersionResource) +} + +// Deprecated: use v3.DynamicSchema instead +type DynamicSchema = v3.DynamicSchema + +func NewDynamicSchema(namespace, name string, obj v3.DynamicSchema) *v3.DynamicSchema { + obj.APIVersion, obj.Kind = DynamicSchemaGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type DynamicSchemaHandlerFunc func(key string, obj *v3.DynamicSchema) (runtime.Object, error) + +type DynamicSchemaChangeHandlerFunc func(obj *v3.DynamicSchema) (runtime.Object, error) + +type DynamicSchemaLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.DynamicSchema, err error) + Get(namespace, name string) (*v3.DynamicSchema, error) +} + +type DynamicSchemaController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() DynamicSchemaLister + AddHandler(ctx context.Context, name string, handler DynamicSchemaHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DynamicSchemaHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler DynamicSchemaHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler DynamicSchemaHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type DynamicSchemaInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.DynamicSchema) (*v3.DynamicSchema, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) + Get(name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) + Update(*v3.DynamicSchema) (*v3.DynamicSchema, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.DynamicSchemaList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DynamicSchemaList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() DynamicSchemaController + AddHandler(ctx context.Context, name string, sync DynamicSchemaHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DynamicSchemaHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle DynamicSchemaLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DynamicSchemaLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DynamicSchemaHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DynamicSchemaHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DynamicSchemaLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DynamicSchemaLifecycle) +} + +type dynamicSchemaLister struct { + ns string + controller *dynamicSchemaController +} + +func (l *dynamicSchemaLister) List(namespace string, selector labels.Selector) (ret []*v3.DynamicSchema, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.DynamicSchema)) + }) + return +} + +func (l *dynamicSchemaLister) Get(namespace, name string) (*v3.DynamicSchema, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: DynamicSchemaGroupVersionKind.Group, + Resource: DynamicSchemaGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.DynamicSchema), nil +} + +type dynamicSchemaController struct { + ns string + controller.GenericController +} + +func (c *dynamicSchemaController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *dynamicSchemaController) Lister() DynamicSchemaLister { + return &dynamicSchemaLister{ + ns: c.ns, + controller: c, + } +} + +func (c *dynamicSchemaController) AddHandler(ctx context.Context, name string, handler DynamicSchemaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DynamicSchema); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dynamicSchemaController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler DynamicSchemaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DynamicSchema); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dynamicSchemaController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler DynamicSchemaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DynamicSchema); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dynamicSchemaController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler DynamicSchemaHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DynamicSchema); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type dynamicSchemaFactory struct { +} + +func (c dynamicSchemaFactory) Object() runtime.Object { + return &v3.DynamicSchema{} +} + +func (c dynamicSchemaFactory) List() runtime.Object { + return &v3.DynamicSchemaList{} +} + +func (s *dynamicSchemaClient) Controller() DynamicSchemaController { + genericController := controller.NewGenericController(s.ns, DynamicSchemaGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(DynamicSchemaGroupVersionResource, DynamicSchemaGroupVersionKind.Kind, false)) + + return &dynamicSchemaController{ + ns: s.ns, + GenericController: genericController, + } +} + +type dynamicSchemaClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller DynamicSchemaController +} + +func (s *dynamicSchemaClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *dynamicSchemaClient) Create(o *v3.DynamicSchema) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) Get(name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) Update(o *v3.DynamicSchema) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) UpdateStatus(o *v3.DynamicSchema) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *dynamicSchemaClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *dynamicSchemaClient) List(opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.DynamicSchemaList), err +} + +func (s *dynamicSchemaClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DynamicSchemaList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.DynamicSchemaList), err +} + +func (s *dynamicSchemaClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *dynamicSchemaClient) Patch(o *v3.DynamicSchema, patchType types.PatchType, data []byte, subresources ...string) (*v3.DynamicSchema, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.DynamicSchema), err +} + +func (s *dynamicSchemaClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *dynamicSchemaClient) AddHandler(ctx context.Context, name string, sync DynamicSchemaHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *dynamicSchemaClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DynamicSchemaHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *dynamicSchemaClient) AddLifecycle(ctx context.Context, name string, lifecycle DynamicSchemaLifecycle) { + sync := NewDynamicSchemaLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *dynamicSchemaClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DynamicSchemaLifecycle) { + sync := NewDynamicSchemaLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *dynamicSchemaClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DynamicSchemaHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *dynamicSchemaClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DynamicSchemaHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *dynamicSchemaClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DynamicSchemaLifecycle) { + sync := NewDynamicSchemaLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *dynamicSchemaClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DynamicSchemaLifecycle) { + sync := NewDynamicSchemaLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_lifecycle_adapter.go new file mode 100644 index 0000000..0f77148 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_dynamic_schema_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type DynamicSchemaLifecycle interface { + Create(obj *v3.DynamicSchema) (runtime.Object, error) + Remove(obj *v3.DynamicSchema) (runtime.Object, error) + Updated(obj *v3.DynamicSchema) (runtime.Object, error) +} + +type dynamicSchemaLifecycleAdapter struct { + lifecycle DynamicSchemaLifecycle +} + +func (w *dynamicSchemaLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *dynamicSchemaLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *dynamicSchemaLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.DynamicSchema)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *dynamicSchemaLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.DynamicSchema)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *dynamicSchemaLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.DynamicSchema)) + if o == nil { + return nil, err + } + return o, err +} + +func NewDynamicSchemaLifecycleAdapter(name string, clusterScoped bool, client DynamicSchemaInterface, l DynamicSchemaLifecycle) DynamicSchemaHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(DynamicSchemaGroupVersionResource) + } + adapter := &dynamicSchemaLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.DynamicSchema) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_controller.go new file mode 100644 index 0000000..b9ab9e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + EtcdBackupGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "EtcdBackup", + } + EtcdBackupResource = metav1.APIResource{ + Name: "etcdbackups", + SingularName: "etcdbackup", + Namespaced: true, + + Kind: EtcdBackupGroupVersionKind.Kind, + } + + EtcdBackupGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "etcdbackups", + } +) + +func init() { + resource.Put(EtcdBackupGroupVersionResource) +} + +// Deprecated: use v3.EtcdBackup instead +type EtcdBackup = v3.EtcdBackup + +func NewEtcdBackup(namespace, name string, obj v3.EtcdBackup) *v3.EtcdBackup { + obj.APIVersion, obj.Kind = EtcdBackupGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type EtcdBackupHandlerFunc func(key string, obj *v3.EtcdBackup) (runtime.Object, error) + +type EtcdBackupChangeHandlerFunc func(obj *v3.EtcdBackup) (runtime.Object, error) + +type EtcdBackupLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.EtcdBackup, err error) + Get(namespace, name string) (*v3.EtcdBackup, error) +} + +type EtcdBackupController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() EtcdBackupLister + AddHandler(ctx context.Context, name string, handler EtcdBackupHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EtcdBackupHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler EtcdBackupHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler EtcdBackupHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type EtcdBackupInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.EtcdBackup) (*v3.EtcdBackup, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) + Get(name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) + Update(*v3.EtcdBackup) (*v3.EtcdBackup, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.EtcdBackupList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.EtcdBackupList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() EtcdBackupController + AddHandler(ctx context.Context, name string, sync EtcdBackupHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EtcdBackupHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle EtcdBackupLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EtcdBackupLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EtcdBackupHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EtcdBackupHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EtcdBackupLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EtcdBackupLifecycle) +} + +type etcdBackupLister struct { + ns string + controller *etcdBackupController +} + +func (l *etcdBackupLister) List(namespace string, selector labels.Selector) (ret []*v3.EtcdBackup, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.EtcdBackup)) + }) + return +} + +func (l *etcdBackupLister) Get(namespace, name string) (*v3.EtcdBackup, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: EtcdBackupGroupVersionKind.Group, + Resource: EtcdBackupGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.EtcdBackup), nil +} + +type etcdBackupController struct { + ns string + controller.GenericController +} + +func (c *etcdBackupController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *etcdBackupController) Lister() EtcdBackupLister { + return &etcdBackupLister{ + ns: c.ns, + controller: c, + } +} + +func (c *etcdBackupController) AddHandler(ctx context.Context, name string, handler EtcdBackupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.EtcdBackup); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *etcdBackupController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler EtcdBackupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.EtcdBackup); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *etcdBackupController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler EtcdBackupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.EtcdBackup); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *etcdBackupController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler EtcdBackupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.EtcdBackup); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type etcdBackupFactory struct { +} + +func (c etcdBackupFactory) Object() runtime.Object { + return &v3.EtcdBackup{} +} + +func (c etcdBackupFactory) List() runtime.Object { + return &v3.EtcdBackupList{} +} + +func (s *etcdBackupClient) Controller() EtcdBackupController { + genericController := controller.NewGenericController(s.ns, EtcdBackupGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(EtcdBackupGroupVersionResource, EtcdBackupGroupVersionKind.Kind, true)) + + return &etcdBackupController{ + ns: s.ns, + GenericController: genericController, + } +} + +type etcdBackupClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller EtcdBackupController +} + +func (s *etcdBackupClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *etcdBackupClient) Create(o *v3.EtcdBackup) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) Get(name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) Update(o *v3.EtcdBackup) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) UpdateStatus(o *v3.EtcdBackup) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *etcdBackupClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *etcdBackupClient) List(opts metav1.ListOptions) (*v3.EtcdBackupList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.EtcdBackupList), err +} + +func (s *etcdBackupClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.EtcdBackupList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.EtcdBackupList), err +} + +func (s *etcdBackupClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *etcdBackupClient) Patch(o *v3.EtcdBackup, patchType types.PatchType, data []byte, subresources ...string) (*v3.EtcdBackup, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.EtcdBackup), err +} + +func (s *etcdBackupClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *etcdBackupClient) AddHandler(ctx context.Context, name string, sync EtcdBackupHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *etcdBackupClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync EtcdBackupHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *etcdBackupClient) AddLifecycle(ctx context.Context, name string, lifecycle EtcdBackupLifecycle) { + sync := NewEtcdBackupLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *etcdBackupClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle EtcdBackupLifecycle) { + sync := NewEtcdBackupLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *etcdBackupClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync EtcdBackupHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *etcdBackupClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync EtcdBackupHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *etcdBackupClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle EtcdBackupLifecycle) { + sync := NewEtcdBackupLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *etcdBackupClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle EtcdBackupLifecycle) { + sync := NewEtcdBackupLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_lifecycle_adapter.go new file mode 100644 index 0000000..389d6c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_etcd_backup_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type EtcdBackupLifecycle interface { + Create(obj *v3.EtcdBackup) (runtime.Object, error) + Remove(obj *v3.EtcdBackup) (runtime.Object, error) + Updated(obj *v3.EtcdBackup) (runtime.Object, error) +} + +type etcdBackupLifecycleAdapter struct { + lifecycle EtcdBackupLifecycle +} + +func (w *etcdBackupLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *etcdBackupLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *etcdBackupLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.EtcdBackup)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *etcdBackupLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.EtcdBackup)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *etcdBackupLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.EtcdBackup)) + if o == nil { + return nil, err + } + return o, err +} + +func NewEtcdBackupLifecycleAdapter(name string, clusterScoped bool, client EtcdBackupInterface, l EtcdBackupLifecycle) EtcdBackupHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(EtcdBackupGroupVersionResource) + } + adapter := &etcdBackupLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.EtcdBackup) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_controller.go new file mode 100644 index 0000000..219abee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + FeatureGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Feature", + } + FeatureResource = metav1.APIResource{ + Name: "features", + SingularName: "feature", + Namespaced: false, + Kind: FeatureGroupVersionKind.Kind, + } + + FeatureGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "features", + } +) + +func init() { + resource.Put(FeatureGroupVersionResource) +} + +// Deprecated: use v3.Feature instead +type Feature = v3.Feature + +func NewFeature(namespace, name string, obj v3.Feature) *v3.Feature { + obj.APIVersion, obj.Kind = FeatureGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type FeatureHandlerFunc func(key string, obj *v3.Feature) (runtime.Object, error) + +type FeatureChangeHandlerFunc func(obj *v3.Feature) (runtime.Object, error) + +type FeatureLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Feature, err error) + Get(namespace, name string) (*v3.Feature, error) +} + +type FeatureController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() FeatureLister + AddHandler(ctx context.Context, name string, handler FeatureHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FeatureHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler FeatureHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler FeatureHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type FeatureInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Feature) (*v3.Feature, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Feature, error) + Get(name string, opts metav1.GetOptions) (*v3.Feature, error) + Update(*v3.Feature) (*v3.Feature, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.FeatureList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FeatureList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() FeatureController + AddHandler(ctx context.Context, name string, sync FeatureHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FeatureHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle FeatureLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle FeatureLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync FeatureHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync FeatureHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle FeatureLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle FeatureLifecycle) +} + +type featureLister struct { + ns string + controller *featureController +} + +func (l *featureLister) List(namespace string, selector labels.Selector) (ret []*v3.Feature, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Feature)) + }) + return +} + +func (l *featureLister) Get(namespace, name string) (*v3.Feature, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: FeatureGroupVersionKind.Group, + Resource: FeatureGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Feature), nil +} + +type featureController struct { + ns string + controller.GenericController +} + +func (c *featureController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *featureController) Lister() FeatureLister { + return &featureLister{ + ns: c.ns, + controller: c, + } +} + +func (c *featureController) AddHandler(ctx context.Context, name string, handler FeatureHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Feature); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *featureController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler FeatureHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Feature); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *featureController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler FeatureHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Feature); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *featureController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler FeatureHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Feature); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type featureFactory struct { +} + +func (c featureFactory) Object() runtime.Object { + return &v3.Feature{} +} + +func (c featureFactory) List() runtime.Object { + return &v3.FeatureList{} +} + +func (s *featureClient) Controller() FeatureController { + genericController := controller.NewGenericController(s.ns, FeatureGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(FeatureGroupVersionResource, FeatureGroupVersionKind.Kind, false)) + + return &featureController{ + ns: s.ns, + GenericController: genericController, + } +} + +type featureClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller FeatureController +} + +func (s *featureClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *featureClient) Create(o *v3.Feature) (*v3.Feature, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Feature), err +} + +func (s *featureClient) Get(name string, opts metav1.GetOptions) (*v3.Feature, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Feature), err +} + +func (s *featureClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Feature, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Feature), err +} + +func (s *featureClient) Update(o *v3.Feature) (*v3.Feature, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Feature), err +} + +func (s *featureClient) UpdateStatus(o *v3.Feature) (*v3.Feature, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Feature), err +} + +func (s *featureClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *featureClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *featureClient) List(opts metav1.ListOptions) (*v3.FeatureList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.FeatureList), err +} + +func (s *featureClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FeatureList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.FeatureList), err +} + +func (s *featureClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *featureClient) Patch(o *v3.Feature, patchType types.PatchType, data []byte, subresources ...string) (*v3.Feature, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Feature), err +} + +func (s *featureClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *featureClient) AddHandler(ctx context.Context, name string, sync FeatureHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *featureClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FeatureHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *featureClient) AddLifecycle(ctx context.Context, name string, lifecycle FeatureLifecycle) { + sync := NewFeatureLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *featureClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle FeatureLifecycle) { + sync := NewFeatureLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *featureClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync FeatureHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *featureClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync FeatureHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *featureClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle FeatureLifecycle) { + sync := NewFeatureLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *featureClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle FeatureLifecycle) { + sync := NewFeatureLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_lifecycle_adapter.go new file mode 100644 index 0000000..1d0a4cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_feature_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type FeatureLifecycle interface { + Create(obj *v3.Feature) (runtime.Object, error) + Remove(obj *v3.Feature) (runtime.Object, error) + Updated(obj *v3.Feature) (runtime.Object, error) +} + +type featureLifecycleAdapter struct { + lifecycle FeatureLifecycle +} + +func (w *featureLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *featureLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *featureLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Feature)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *featureLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Feature)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *featureLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Feature)) + if o == nil { + return nil, err + } + return o, err +} + +func NewFeatureLifecycleAdapter(name string, clusterScoped bool, client FeatureInterface, l FeatureLifecycle) FeatureHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(FeatureGroupVersionResource) + } + adapter := &featureLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Feature) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_controller.go new file mode 100644 index 0000000..6493aa3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + FleetWorkspaceGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "FleetWorkspace", + } + FleetWorkspaceResource = metav1.APIResource{ + Name: "fleetworkspaces", + SingularName: "fleetworkspace", + Namespaced: false, + Kind: FleetWorkspaceGroupVersionKind.Kind, + } + + FleetWorkspaceGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "fleetworkspaces", + } +) + +func init() { + resource.Put(FleetWorkspaceGroupVersionResource) +} + +// Deprecated: use v3.FleetWorkspace instead +type FleetWorkspace = v3.FleetWorkspace + +func NewFleetWorkspace(namespace, name string, obj v3.FleetWorkspace) *v3.FleetWorkspace { + obj.APIVersion, obj.Kind = FleetWorkspaceGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type FleetWorkspaceHandlerFunc func(key string, obj *v3.FleetWorkspace) (runtime.Object, error) + +type FleetWorkspaceChangeHandlerFunc func(obj *v3.FleetWorkspace) (runtime.Object, error) + +type FleetWorkspaceLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.FleetWorkspace, err error) + Get(namespace, name string) (*v3.FleetWorkspace, error) +} + +type FleetWorkspaceController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() FleetWorkspaceLister + AddHandler(ctx context.Context, name string, handler FleetWorkspaceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FleetWorkspaceHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler FleetWorkspaceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler FleetWorkspaceHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type FleetWorkspaceInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.FleetWorkspace) (*v3.FleetWorkspace, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) + Get(name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) + Update(*v3.FleetWorkspace) (*v3.FleetWorkspace, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() FleetWorkspaceController + AddHandler(ctx context.Context, name string, sync FleetWorkspaceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FleetWorkspaceHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle FleetWorkspaceLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle FleetWorkspaceLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync FleetWorkspaceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync FleetWorkspaceHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle FleetWorkspaceLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle FleetWorkspaceLifecycle) +} + +type fleetWorkspaceLister struct { + ns string + controller *fleetWorkspaceController +} + +func (l *fleetWorkspaceLister) List(namespace string, selector labels.Selector) (ret []*v3.FleetWorkspace, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.FleetWorkspace)) + }) + return +} + +func (l *fleetWorkspaceLister) Get(namespace, name string) (*v3.FleetWorkspace, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: FleetWorkspaceGroupVersionKind.Group, + Resource: FleetWorkspaceGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.FleetWorkspace), nil +} + +type fleetWorkspaceController struct { + ns string + controller.GenericController +} + +func (c *fleetWorkspaceController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *fleetWorkspaceController) Lister() FleetWorkspaceLister { + return &fleetWorkspaceLister{ + ns: c.ns, + controller: c, + } +} + +func (c *fleetWorkspaceController) AddHandler(ctx context.Context, name string, handler FleetWorkspaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.FleetWorkspace); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *fleetWorkspaceController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler FleetWorkspaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.FleetWorkspace); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *fleetWorkspaceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler FleetWorkspaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.FleetWorkspace); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *fleetWorkspaceController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler FleetWorkspaceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.FleetWorkspace); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type fleetWorkspaceFactory struct { +} + +func (c fleetWorkspaceFactory) Object() runtime.Object { + return &v3.FleetWorkspace{} +} + +func (c fleetWorkspaceFactory) List() runtime.Object { + return &v3.FleetWorkspaceList{} +} + +func (s *fleetWorkspaceClient) Controller() FleetWorkspaceController { + genericController := controller.NewGenericController(s.ns, FleetWorkspaceGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(FleetWorkspaceGroupVersionResource, FleetWorkspaceGroupVersionKind.Kind, false)) + + return &fleetWorkspaceController{ + ns: s.ns, + GenericController: genericController, + } +} + +type fleetWorkspaceClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller FleetWorkspaceController +} + +func (s *fleetWorkspaceClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *fleetWorkspaceClient) Create(o *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) Get(name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) Update(o *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) UpdateStatus(o *v3.FleetWorkspace) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *fleetWorkspaceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *fleetWorkspaceClient) List(opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.FleetWorkspaceList), err +} + +func (s *fleetWorkspaceClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.FleetWorkspaceList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.FleetWorkspaceList), err +} + +func (s *fleetWorkspaceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *fleetWorkspaceClient) Patch(o *v3.FleetWorkspace, patchType types.PatchType, data []byte, subresources ...string) (*v3.FleetWorkspace, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.FleetWorkspace), err +} + +func (s *fleetWorkspaceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *fleetWorkspaceClient) AddHandler(ctx context.Context, name string, sync FleetWorkspaceHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *fleetWorkspaceClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync FleetWorkspaceHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *fleetWorkspaceClient) AddLifecycle(ctx context.Context, name string, lifecycle FleetWorkspaceLifecycle) { + sync := NewFleetWorkspaceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *fleetWorkspaceClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle FleetWorkspaceLifecycle) { + sync := NewFleetWorkspaceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *fleetWorkspaceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync FleetWorkspaceHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *fleetWorkspaceClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync FleetWorkspaceHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *fleetWorkspaceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle FleetWorkspaceLifecycle) { + sync := NewFleetWorkspaceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *fleetWorkspaceClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle FleetWorkspaceLifecycle) { + sync := NewFleetWorkspaceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_lifecycle_adapter.go new file mode 100644 index 0000000..a027b27 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_fleet_workspace_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type FleetWorkspaceLifecycle interface { + Create(obj *v3.FleetWorkspace) (runtime.Object, error) + Remove(obj *v3.FleetWorkspace) (runtime.Object, error) + Updated(obj *v3.FleetWorkspace) (runtime.Object, error) +} + +type fleetWorkspaceLifecycleAdapter struct { + lifecycle FleetWorkspaceLifecycle +} + +func (w *fleetWorkspaceLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *fleetWorkspaceLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *fleetWorkspaceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.FleetWorkspace)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *fleetWorkspaceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.FleetWorkspace)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *fleetWorkspaceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.FleetWorkspace)) + if o == nil { + return nil, err + } + return o, err +} + +func NewFleetWorkspaceLifecycleAdapter(name string, clusterScoped bool, client FleetWorkspaceInterface, l FleetWorkspaceLifecycle) FleetWorkspaceHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(FleetWorkspaceGroupVersionResource) + } + adapter := &fleetWorkspaceLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.FleetWorkspace) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_controller.go new file mode 100644 index 0000000..186a9d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GlobalDnsGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "GlobalDns", + } + GlobalDnsResource = metav1.APIResource{ + Name: "globaldnses", + SingularName: "globaldns", + Namespaced: true, + + Kind: GlobalDnsGroupVersionKind.Kind, + } + + GlobalDnsGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "globaldnses", + } +) + +func init() { + resource.Put(GlobalDnsGroupVersionResource) +} + +// Deprecated: use v3.GlobalDns instead +type GlobalDns = v3.GlobalDns + +func NewGlobalDns(namespace, name string, obj v3.GlobalDns) *v3.GlobalDns { + obj.APIVersion, obj.Kind = GlobalDnsGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GlobalDnsHandlerFunc func(key string, obj *v3.GlobalDns) (runtime.Object, error) + +type GlobalDnsChangeHandlerFunc func(obj *v3.GlobalDns) (runtime.Object, error) + +type GlobalDnsLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.GlobalDns, err error) + Get(namespace, name string) (*v3.GlobalDns, error) +} + +type GlobalDnsController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GlobalDnsLister + AddHandler(ctx context.Context, name string, handler GlobalDnsHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GlobalDnsHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GlobalDnsHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GlobalDnsInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.GlobalDns) (*v3.GlobalDns, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalDns, error) + Get(name string, opts metav1.GetOptions) (*v3.GlobalDns, error) + Update(*v3.GlobalDns) (*v3.GlobalDns, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GlobalDnsList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GlobalDnsController + AddHandler(ctx context.Context, name string, sync GlobalDnsHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GlobalDnsLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalDnsLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalDnsHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalDnsHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalDnsLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalDnsLifecycle) +} + +type globalDnsLister struct { + ns string + controller *globalDnsController +} + +func (l *globalDnsLister) List(namespace string, selector labels.Selector) (ret []*v3.GlobalDns, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.GlobalDns)) + }) + return +} + +func (l *globalDnsLister) Get(namespace, name string) (*v3.GlobalDns, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GlobalDnsGroupVersionKind.Group, + Resource: GlobalDnsGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.GlobalDns), nil +} + +type globalDnsController struct { + ns string + controller.GenericController +} + +func (c *globalDnsController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *globalDnsController) Lister() GlobalDnsLister { + return &globalDnsLister{ + ns: c.ns, + controller: c, + } +} + +func (c *globalDnsController) AddHandler(ctx context.Context, name string, handler GlobalDnsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDns); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GlobalDnsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDns); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GlobalDnsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDns); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GlobalDnsHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDns); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type globalDnsFactory struct { +} + +func (c globalDnsFactory) Object() runtime.Object { + return &v3.GlobalDns{} +} + +func (c globalDnsFactory) List() runtime.Object { + return &v3.GlobalDnsList{} +} + +func (s *globalDnsClient) Controller() GlobalDnsController { + genericController := controller.NewGenericController(s.ns, GlobalDnsGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GlobalDnsGroupVersionResource, GlobalDnsGroupVersionKind.Kind, true)) + + return &globalDnsController{ + ns: s.ns, + GenericController: genericController, + } +} + +type globalDnsClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GlobalDnsController +} + +func (s *globalDnsClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *globalDnsClient) Create(o *v3.GlobalDns) (*v3.GlobalDns, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) Get(name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalDns, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) Update(o *v3.GlobalDns) (*v3.GlobalDns, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) UpdateStatus(o *v3.GlobalDns) (*v3.GlobalDns, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *globalDnsClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *globalDnsClient) List(opts metav1.ListOptions) (*v3.GlobalDnsList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GlobalDnsList), err +} + +func (s *globalDnsClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GlobalDnsList), err +} + +func (s *globalDnsClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *globalDnsClient) Patch(o *v3.GlobalDns, patchType types.PatchType, data []byte, subresources ...string) (*v3.GlobalDns, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.GlobalDns), err +} + +func (s *globalDnsClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *globalDnsClient) AddHandler(ctx context.Context, name string, sync GlobalDnsHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalDnsClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalDnsClient) AddLifecycle(ctx context.Context, name string, lifecycle GlobalDnsLifecycle) { + sync := NewGlobalDnsLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalDnsClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalDnsLifecycle) { + sync := NewGlobalDnsLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalDnsClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalDnsHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalDnsClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalDnsHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *globalDnsClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalDnsLifecycle) { + sync := NewGlobalDnsLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalDnsClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalDnsLifecycle) { + sync := NewGlobalDnsLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_lifecycle_adapter.go new file mode 100644 index 0000000..bba1da1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GlobalDnsLifecycle interface { + Create(obj *v3.GlobalDns) (runtime.Object, error) + Remove(obj *v3.GlobalDns) (runtime.Object, error) + Updated(obj *v3.GlobalDns) (runtime.Object, error) +} + +type globalDnsLifecycleAdapter struct { + lifecycle GlobalDnsLifecycle +} + +func (w *globalDnsLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *globalDnsLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *globalDnsLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.GlobalDns)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalDnsLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.GlobalDns)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalDnsLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.GlobalDns)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGlobalDnsLifecycleAdapter(name string, clusterScoped bool, client GlobalDnsInterface, l GlobalDnsLifecycle) GlobalDnsHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GlobalDnsGroupVersionResource) + } + adapter := &globalDnsLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.GlobalDns) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_controller.go new file mode 100644 index 0000000..5b15167 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GlobalDnsProviderGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "GlobalDnsProvider", + } + GlobalDnsProviderResource = metav1.APIResource{ + Name: "globaldnsproviders", + SingularName: "globaldnsprovider", + Namespaced: true, + + Kind: GlobalDnsProviderGroupVersionKind.Kind, + } + + GlobalDnsProviderGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "globaldnsproviders", + } +) + +func init() { + resource.Put(GlobalDnsProviderGroupVersionResource) +} + +// Deprecated: use v3.GlobalDnsProvider instead +type GlobalDnsProvider = v3.GlobalDnsProvider + +func NewGlobalDnsProvider(namespace, name string, obj v3.GlobalDnsProvider) *v3.GlobalDnsProvider { + obj.APIVersion, obj.Kind = GlobalDnsProviderGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GlobalDnsProviderHandlerFunc func(key string, obj *v3.GlobalDnsProvider) (runtime.Object, error) + +type GlobalDnsProviderChangeHandlerFunc func(obj *v3.GlobalDnsProvider) (runtime.Object, error) + +type GlobalDnsProviderLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.GlobalDnsProvider, err error) + Get(namespace, name string) (*v3.GlobalDnsProvider, error) +} + +type GlobalDnsProviderController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GlobalDnsProviderLister + AddHandler(ctx context.Context, name string, handler GlobalDnsProviderHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsProviderHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GlobalDnsProviderHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GlobalDnsProviderHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GlobalDnsProviderInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) + Get(name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) + Update(*v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GlobalDnsProviderController + AddHandler(ctx context.Context, name string, sync GlobalDnsProviderHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsProviderHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GlobalDnsProviderLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalDnsProviderLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalDnsProviderHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalDnsProviderHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalDnsProviderLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalDnsProviderLifecycle) +} + +type globalDnsProviderLister struct { + ns string + controller *globalDnsProviderController +} + +func (l *globalDnsProviderLister) List(namespace string, selector labels.Selector) (ret []*v3.GlobalDnsProvider, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.GlobalDnsProvider)) + }) + return +} + +func (l *globalDnsProviderLister) Get(namespace, name string) (*v3.GlobalDnsProvider, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GlobalDnsProviderGroupVersionKind.Group, + Resource: GlobalDnsProviderGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.GlobalDnsProvider), nil +} + +type globalDnsProviderController struct { + ns string + controller.GenericController +} + +func (c *globalDnsProviderController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *globalDnsProviderController) Lister() GlobalDnsProviderLister { + return &globalDnsProviderLister{ + ns: c.ns, + controller: c, + } +} + +func (c *globalDnsProviderController) AddHandler(ctx context.Context, name string, handler GlobalDnsProviderHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDnsProvider); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsProviderController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GlobalDnsProviderHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDnsProvider); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsProviderController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GlobalDnsProviderHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDnsProvider); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalDnsProviderController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GlobalDnsProviderHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalDnsProvider); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type globalDnsProviderFactory struct { +} + +func (c globalDnsProviderFactory) Object() runtime.Object { + return &v3.GlobalDnsProvider{} +} + +func (c globalDnsProviderFactory) List() runtime.Object { + return &v3.GlobalDnsProviderList{} +} + +func (s *globalDnsProviderClient) Controller() GlobalDnsProviderController { + genericController := controller.NewGenericController(s.ns, GlobalDnsProviderGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GlobalDnsProviderGroupVersionResource, GlobalDnsProviderGroupVersionKind.Kind, true)) + + return &globalDnsProviderController{ + ns: s.ns, + GenericController: genericController, + } +} + +type globalDnsProviderClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GlobalDnsProviderController +} + +func (s *globalDnsProviderClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *globalDnsProviderClient) Create(o *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) Get(name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) Update(o *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) UpdateStatus(o *v3.GlobalDnsProvider) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *globalDnsProviderClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *globalDnsProviderClient) List(opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GlobalDnsProviderList), err +} + +func (s *globalDnsProviderClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalDnsProviderList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GlobalDnsProviderList), err +} + +func (s *globalDnsProviderClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *globalDnsProviderClient) Patch(o *v3.GlobalDnsProvider, patchType types.PatchType, data []byte, subresources ...string) (*v3.GlobalDnsProvider, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.GlobalDnsProvider), err +} + +func (s *globalDnsProviderClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *globalDnsProviderClient) AddHandler(ctx context.Context, name string, sync GlobalDnsProviderHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalDnsProviderClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalDnsProviderHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalDnsProviderClient) AddLifecycle(ctx context.Context, name string, lifecycle GlobalDnsProviderLifecycle) { + sync := NewGlobalDnsProviderLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalDnsProviderClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalDnsProviderLifecycle) { + sync := NewGlobalDnsProviderLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalDnsProviderClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalDnsProviderHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalDnsProviderClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalDnsProviderHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *globalDnsProviderClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalDnsProviderLifecycle) { + sync := NewGlobalDnsProviderLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalDnsProviderClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalDnsProviderLifecycle) { + sync := NewGlobalDnsProviderLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_lifecycle_adapter.go new file mode 100644 index 0000000..688b9ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_dns_provider_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GlobalDnsProviderLifecycle interface { + Create(obj *v3.GlobalDnsProvider) (runtime.Object, error) + Remove(obj *v3.GlobalDnsProvider) (runtime.Object, error) + Updated(obj *v3.GlobalDnsProvider) (runtime.Object, error) +} + +type globalDnsProviderLifecycleAdapter struct { + lifecycle GlobalDnsProviderLifecycle +} + +func (w *globalDnsProviderLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *globalDnsProviderLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *globalDnsProviderLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.GlobalDnsProvider)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalDnsProviderLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.GlobalDnsProvider)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalDnsProviderLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.GlobalDnsProvider)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGlobalDnsProviderLifecycleAdapter(name string, clusterScoped bool, client GlobalDnsProviderInterface, l GlobalDnsProviderLifecycle) GlobalDnsProviderHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GlobalDnsProviderGroupVersionResource) + } + adapter := &globalDnsProviderLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.GlobalDnsProvider) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_controller.go new file mode 100644 index 0000000..3f14287 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GlobalRoleBindingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "GlobalRoleBinding", + } + GlobalRoleBindingResource = metav1.APIResource{ + Name: "globalrolebindings", + SingularName: "globalrolebinding", + Namespaced: false, + Kind: GlobalRoleBindingGroupVersionKind.Kind, + } + + GlobalRoleBindingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "globalrolebindings", + } +) + +func init() { + resource.Put(GlobalRoleBindingGroupVersionResource) +} + +// Deprecated: use v3.GlobalRoleBinding instead +type GlobalRoleBinding = v3.GlobalRoleBinding + +func NewGlobalRoleBinding(namespace, name string, obj v3.GlobalRoleBinding) *v3.GlobalRoleBinding { + obj.APIVersion, obj.Kind = GlobalRoleBindingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GlobalRoleBindingHandlerFunc func(key string, obj *v3.GlobalRoleBinding) (runtime.Object, error) + +type GlobalRoleBindingChangeHandlerFunc func(obj *v3.GlobalRoleBinding) (runtime.Object, error) + +type GlobalRoleBindingLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.GlobalRoleBinding, err error) + Get(namespace, name string) (*v3.GlobalRoleBinding, error) +} + +type GlobalRoleBindingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GlobalRoleBindingLister + AddHandler(ctx context.Context, name string, handler GlobalRoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleBindingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GlobalRoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GlobalRoleBindingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GlobalRoleBindingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) + Get(name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) + Update(*v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GlobalRoleBindingController + AddHandler(ctx context.Context, name string, sync GlobalRoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleBindingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GlobalRoleBindingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalRoleBindingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalRoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalRoleBindingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalRoleBindingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalRoleBindingLifecycle) +} + +type globalRoleBindingLister struct { + ns string + controller *globalRoleBindingController +} + +func (l *globalRoleBindingLister) List(namespace string, selector labels.Selector) (ret []*v3.GlobalRoleBinding, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.GlobalRoleBinding)) + }) + return +} + +func (l *globalRoleBindingLister) Get(namespace, name string) (*v3.GlobalRoleBinding, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GlobalRoleBindingGroupVersionKind.Group, + Resource: GlobalRoleBindingGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.GlobalRoleBinding), nil +} + +type globalRoleBindingController struct { + ns string + controller.GenericController +} + +func (c *globalRoleBindingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *globalRoleBindingController) Lister() GlobalRoleBindingLister { + return &globalRoleBindingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *globalRoleBindingController) AddHandler(ctx context.Context, name string, handler GlobalRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleBindingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GlobalRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleBindingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GlobalRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleBindingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GlobalRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type globalRoleBindingFactory struct { +} + +func (c globalRoleBindingFactory) Object() runtime.Object { + return &v3.GlobalRoleBinding{} +} + +func (c globalRoleBindingFactory) List() runtime.Object { + return &v3.GlobalRoleBindingList{} +} + +func (s *globalRoleBindingClient) Controller() GlobalRoleBindingController { + genericController := controller.NewGenericController(s.ns, GlobalRoleBindingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GlobalRoleBindingGroupVersionResource, GlobalRoleBindingGroupVersionKind.Kind, false)) + + return &globalRoleBindingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type globalRoleBindingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GlobalRoleBindingController +} + +func (s *globalRoleBindingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *globalRoleBindingClient) Create(o *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) Get(name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) Update(o *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) UpdateStatus(o *v3.GlobalRoleBinding) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *globalRoleBindingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *globalRoleBindingClient) List(opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GlobalRoleBindingList), err +} + +func (s *globalRoleBindingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleBindingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GlobalRoleBindingList), err +} + +func (s *globalRoleBindingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *globalRoleBindingClient) Patch(o *v3.GlobalRoleBinding, patchType types.PatchType, data []byte, subresources ...string) (*v3.GlobalRoleBinding, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.GlobalRoleBinding), err +} + +func (s *globalRoleBindingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *globalRoleBindingClient) AddHandler(ctx context.Context, name string, sync GlobalRoleBindingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalRoleBindingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleBindingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalRoleBindingClient) AddLifecycle(ctx context.Context, name string, lifecycle GlobalRoleBindingLifecycle) { + sync := NewGlobalRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalRoleBindingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalRoleBindingLifecycle) { + sync := NewGlobalRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalRoleBindingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalRoleBindingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalRoleBindingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalRoleBindingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *globalRoleBindingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalRoleBindingLifecycle) { + sync := NewGlobalRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalRoleBindingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalRoleBindingLifecycle) { + sync := NewGlobalRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_lifecycle_adapter.go new file mode 100644 index 0000000..7cb9dac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_binding_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GlobalRoleBindingLifecycle interface { + Create(obj *v3.GlobalRoleBinding) (runtime.Object, error) + Remove(obj *v3.GlobalRoleBinding) (runtime.Object, error) + Updated(obj *v3.GlobalRoleBinding) (runtime.Object, error) +} + +type globalRoleBindingLifecycleAdapter struct { + lifecycle GlobalRoleBindingLifecycle +} + +func (w *globalRoleBindingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *globalRoleBindingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *globalRoleBindingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.GlobalRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalRoleBindingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.GlobalRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalRoleBindingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.GlobalRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGlobalRoleBindingLifecycleAdapter(name string, clusterScoped bool, client GlobalRoleBindingInterface, l GlobalRoleBindingLifecycle) GlobalRoleBindingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GlobalRoleBindingGroupVersionResource) + } + adapter := &globalRoleBindingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.GlobalRoleBinding) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_controller.go new file mode 100644 index 0000000..c0faf3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GlobalRoleGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "GlobalRole", + } + GlobalRoleResource = metav1.APIResource{ + Name: "globalroles", + SingularName: "globalrole", + Namespaced: false, + Kind: GlobalRoleGroupVersionKind.Kind, + } + + GlobalRoleGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "globalroles", + } +) + +func init() { + resource.Put(GlobalRoleGroupVersionResource) +} + +// Deprecated: use v3.GlobalRole instead +type GlobalRole = v3.GlobalRole + +func NewGlobalRole(namespace, name string, obj v3.GlobalRole) *v3.GlobalRole { + obj.APIVersion, obj.Kind = GlobalRoleGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GlobalRoleHandlerFunc func(key string, obj *v3.GlobalRole) (runtime.Object, error) + +type GlobalRoleChangeHandlerFunc func(obj *v3.GlobalRole) (runtime.Object, error) + +type GlobalRoleLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.GlobalRole, err error) + Get(namespace, name string) (*v3.GlobalRole, error) +} + +type GlobalRoleController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GlobalRoleLister + AddHandler(ctx context.Context, name string, handler GlobalRoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GlobalRoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GlobalRoleHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GlobalRoleInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.GlobalRole) (*v3.GlobalRole, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalRole, error) + Get(name string, opts metav1.GetOptions) (*v3.GlobalRole, error) + Update(*v3.GlobalRole) (*v3.GlobalRole, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GlobalRoleList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GlobalRoleController + AddHandler(ctx context.Context, name string, sync GlobalRoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GlobalRoleLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalRoleLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalRoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalRoleHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalRoleLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalRoleLifecycle) +} + +type globalRoleLister struct { + ns string + controller *globalRoleController +} + +func (l *globalRoleLister) List(namespace string, selector labels.Selector) (ret []*v3.GlobalRole, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.GlobalRole)) + }) + return +} + +func (l *globalRoleLister) Get(namespace, name string) (*v3.GlobalRole, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GlobalRoleGroupVersionKind.Group, + Resource: GlobalRoleGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.GlobalRole), nil +} + +type globalRoleController struct { + ns string + controller.GenericController +} + +func (c *globalRoleController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *globalRoleController) Lister() GlobalRoleLister { + return &globalRoleLister{ + ns: c.ns, + controller: c, + } +} + +func (c *globalRoleController) AddHandler(ctx context.Context, name string, handler GlobalRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRole); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GlobalRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRole); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GlobalRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRole); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *globalRoleController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GlobalRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GlobalRole); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type globalRoleFactory struct { +} + +func (c globalRoleFactory) Object() runtime.Object { + return &v3.GlobalRole{} +} + +func (c globalRoleFactory) List() runtime.Object { + return &v3.GlobalRoleList{} +} + +func (s *globalRoleClient) Controller() GlobalRoleController { + genericController := controller.NewGenericController(s.ns, GlobalRoleGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GlobalRoleGroupVersionResource, GlobalRoleGroupVersionKind.Kind, false)) + + return &globalRoleController{ + ns: s.ns, + GenericController: genericController, + } +} + +type globalRoleClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GlobalRoleController +} + +func (s *globalRoleClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *globalRoleClient) Create(o *v3.GlobalRole) (*v3.GlobalRole, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) Get(name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GlobalRole, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) Update(o *v3.GlobalRole) (*v3.GlobalRole, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) UpdateStatus(o *v3.GlobalRole) (*v3.GlobalRole, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *globalRoleClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *globalRoleClient) List(opts metav1.ListOptions) (*v3.GlobalRoleList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GlobalRoleList), err +} + +func (s *globalRoleClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GlobalRoleList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GlobalRoleList), err +} + +func (s *globalRoleClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *globalRoleClient) Patch(o *v3.GlobalRole, patchType types.PatchType, data []byte, subresources ...string) (*v3.GlobalRole, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.GlobalRole), err +} + +func (s *globalRoleClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *globalRoleClient) AddHandler(ctx context.Context, name string, sync GlobalRoleHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalRoleClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GlobalRoleHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalRoleClient) AddLifecycle(ctx context.Context, name string, lifecycle GlobalRoleLifecycle) { + sync := NewGlobalRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *globalRoleClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GlobalRoleLifecycle) { + sync := NewGlobalRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *globalRoleClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GlobalRoleHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalRoleClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GlobalRoleHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *globalRoleClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GlobalRoleLifecycle) { + sync := NewGlobalRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *globalRoleClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GlobalRoleLifecycle) { + sync := NewGlobalRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_lifecycle_adapter.go new file mode 100644 index 0000000..f3eded5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_global_role_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GlobalRoleLifecycle interface { + Create(obj *v3.GlobalRole) (runtime.Object, error) + Remove(obj *v3.GlobalRole) (runtime.Object, error) + Updated(obj *v3.GlobalRole) (runtime.Object, error) +} + +type globalRoleLifecycleAdapter struct { + lifecycle GlobalRoleLifecycle +} + +func (w *globalRoleLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *globalRoleLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *globalRoleLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.GlobalRole)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalRoleLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.GlobalRole)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *globalRoleLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.GlobalRole)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGlobalRoleLifecycleAdapter(name string, clusterScoped bool, client GlobalRoleInterface, l GlobalRoleLifecycle) GlobalRoleHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GlobalRoleGroupVersionResource) + } + adapter := &globalRoleLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.GlobalRole) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_controller.go new file mode 100644 index 0000000..ad339a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GroupGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Group", + } + GroupResource = metav1.APIResource{ + Name: "groups", + SingularName: "group", + Namespaced: false, + Kind: GroupGroupVersionKind.Kind, + } + + GroupGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "groups", + } +) + +func init() { + resource.Put(GroupGroupVersionResource) +} + +// Deprecated: use v3.Group instead +type Group = v3.Group + +func NewGroup(namespace, name string, obj v3.Group) *v3.Group { + obj.APIVersion, obj.Kind = GroupGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GroupHandlerFunc func(key string, obj *v3.Group) (runtime.Object, error) + +type GroupChangeHandlerFunc func(obj *v3.Group) (runtime.Object, error) + +type GroupLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Group, err error) + Get(namespace, name string) (*v3.Group, error) +} + +type GroupController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GroupLister + AddHandler(ctx context.Context, name string, handler GroupHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GroupHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GroupHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GroupInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Group) (*v3.Group, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Group, error) + Get(name string, opts metav1.GetOptions) (*v3.Group, error) + Update(*v3.Group) (*v3.Group, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GroupList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GroupController + AddHandler(ctx context.Context, name string, sync GroupHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GroupLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GroupLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GroupHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GroupHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GroupLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GroupLifecycle) +} + +type groupLister struct { + ns string + controller *groupController +} + +func (l *groupLister) List(namespace string, selector labels.Selector) (ret []*v3.Group, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Group)) + }) + return +} + +func (l *groupLister) Get(namespace, name string) (*v3.Group, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GroupGroupVersionKind.Group, + Resource: GroupGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Group), nil +} + +type groupController struct { + ns string + controller.GenericController +} + +func (c *groupController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *groupController) Lister() GroupLister { + return &groupLister{ + ns: c.ns, + controller: c, + } +} + +func (c *groupController) AddHandler(ctx context.Context, name string, handler GroupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Group); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GroupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Group); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GroupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Group); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GroupHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Group); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type groupFactory struct { +} + +func (c groupFactory) Object() runtime.Object { + return &v3.Group{} +} + +func (c groupFactory) List() runtime.Object { + return &v3.GroupList{} +} + +func (s *groupClient) Controller() GroupController { + genericController := controller.NewGenericController(s.ns, GroupGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GroupGroupVersionResource, GroupGroupVersionKind.Kind, false)) + + return &groupController{ + ns: s.ns, + GenericController: genericController, + } +} + +type groupClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GroupController +} + +func (s *groupClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *groupClient) Create(o *v3.Group) (*v3.Group, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Group), err +} + +func (s *groupClient) Get(name string, opts metav1.GetOptions) (*v3.Group, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Group), err +} + +func (s *groupClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Group, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Group), err +} + +func (s *groupClient) Update(o *v3.Group) (*v3.Group, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Group), err +} + +func (s *groupClient) UpdateStatus(o *v3.Group) (*v3.Group, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Group), err +} + +func (s *groupClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *groupClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *groupClient) List(opts metav1.ListOptions) (*v3.GroupList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GroupList), err +} + +func (s *groupClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GroupList), err +} + +func (s *groupClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *groupClient) Patch(o *v3.Group, patchType types.PatchType, data []byte, subresources ...string) (*v3.Group, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Group), err +} + +func (s *groupClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *groupClient) AddHandler(ctx context.Context, name string, sync GroupHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *groupClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *groupClient) AddLifecycle(ctx context.Context, name string, lifecycle GroupLifecycle) { + sync := NewGroupLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *groupClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GroupLifecycle) { + sync := NewGroupLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *groupClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GroupHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *groupClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GroupHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *groupClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GroupLifecycle) { + sync := NewGroupLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *groupClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GroupLifecycle) { + sync := NewGroupLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_lifecycle_adapter.go new file mode 100644 index 0000000..51d2593 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GroupLifecycle interface { + Create(obj *v3.Group) (runtime.Object, error) + Remove(obj *v3.Group) (runtime.Object, error) + Updated(obj *v3.Group) (runtime.Object, error) +} + +type groupLifecycleAdapter struct { + lifecycle GroupLifecycle +} + +func (w *groupLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *groupLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *groupLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Group)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *groupLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Group)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *groupLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Group)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGroupLifecycleAdapter(name string, clusterScoped bool, client GroupInterface, l GroupLifecycle) GroupHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GroupGroupVersionResource) + } + adapter := &groupLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Group) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_controller.go new file mode 100644 index 0000000..54ecacd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + GroupMemberGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "GroupMember", + } + GroupMemberResource = metav1.APIResource{ + Name: "groupmembers", + SingularName: "groupmember", + Namespaced: false, + Kind: GroupMemberGroupVersionKind.Kind, + } + + GroupMemberGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "groupmembers", + } +) + +func init() { + resource.Put(GroupMemberGroupVersionResource) +} + +// Deprecated: use v3.GroupMember instead +type GroupMember = v3.GroupMember + +func NewGroupMember(namespace, name string, obj v3.GroupMember) *v3.GroupMember { + obj.APIVersion, obj.Kind = GroupMemberGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type GroupMemberHandlerFunc func(key string, obj *v3.GroupMember) (runtime.Object, error) + +type GroupMemberChangeHandlerFunc func(obj *v3.GroupMember) (runtime.Object, error) + +type GroupMemberLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.GroupMember, err error) + Get(namespace, name string) (*v3.GroupMember, error) +} + +type GroupMemberController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() GroupMemberLister + AddHandler(ctx context.Context, name string, handler GroupMemberHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupMemberHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler GroupMemberHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler GroupMemberHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type GroupMemberInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.GroupMember) (*v3.GroupMember, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GroupMember, error) + Get(name string, opts metav1.GetOptions) (*v3.GroupMember, error) + Update(*v3.GroupMember) (*v3.GroupMember, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.GroupMemberList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupMemberList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() GroupMemberController + AddHandler(ctx context.Context, name string, sync GroupMemberHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupMemberHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle GroupMemberLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GroupMemberLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GroupMemberHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GroupMemberHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GroupMemberLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GroupMemberLifecycle) +} + +type groupMemberLister struct { + ns string + controller *groupMemberController +} + +func (l *groupMemberLister) List(namespace string, selector labels.Selector) (ret []*v3.GroupMember, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.GroupMember)) + }) + return +} + +func (l *groupMemberLister) Get(namespace, name string) (*v3.GroupMember, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: GroupMemberGroupVersionKind.Group, + Resource: GroupMemberGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.GroupMember), nil +} + +type groupMemberController struct { + ns string + controller.GenericController +} + +func (c *groupMemberController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *groupMemberController) Lister() GroupMemberLister { + return &groupMemberLister{ + ns: c.ns, + controller: c, + } +} + +func (c *groupMemberController) AddHandler(ctx context.Context, name string, handler GroupMemberHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GroupMember); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupMemberController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler GroupMemberHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GroupMember); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupMemberController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler GroupMemberHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GroupMember); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *groupMemberController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler GroupMemberHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.GroupMember); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type groupMemberFactory struct { +} + +func (c groupMemberFactory) Object() runtime.Object { + return &v3.GroupMember{} +} + +func (c groupMemberFactory) List() runtime.Object { + return &v3.GroupMemberList{} +} + +func (s *groupMemberClient) Controller() GroupMemberController { + genericController := controller.NewGenericController(s.ns, GroupMemberGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(GroupMemberGroupVersionResource, GroupMemberGroupVersionKind.Kind, false)) + + return &groupMemberController{ + ns: s.ns, + GenericController: genericController, + } +} + +type groupMemberClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller GroupMemberController +} + +func (s *groupMemberClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *groupMemberClient) Create(o *v3.GroupMember) (*v3.GroupMember, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) Get(name string, opts metav1.GetOptions) (*v3.GroupMember, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.GroupMember, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) Update(o *v3.GroupMember) (*v3.GroupMember, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) UpdateStatus(o *v3.GroupMember) (*v3.GroupMember, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *groupMemberClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *groupMemberClient) List(opts metav1.ListOptions) (*v3.GroupMemberList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.GroupMemberList), err +} + +func (s *groupMemberClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.GroupMemberList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.GroupMemberList), err +} + +func (s *groupMemberClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *groupMemberClient) Patch(o *v3.GroupMember, patchType types.PatchType, data []byte, subresources ...string) (*v3.GroupMember, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.GroupMember), err +} + +func (s *groupMemberClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *groupMemberClient) AddHandler(ctx context.Context, name string, sync GroupMemberHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *groupMemberClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync GroupMemberHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *groupMemberClient) AddLifecycle(ctx context.Context, name string, lifecycle GroupMemberLifecycle) { + sync := NewGroupMemberLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *groupMemberClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle GroupMemberLifecycle) { + sync := NewGroupMemberLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *groupMemberClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync GroupMemberHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *groupMemberClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync GroupMemberHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *groupMemberClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle GroupMemberLifecycle) { + sync := NewGroupMemberLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *groupMemberClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle GroupMemberLifecycle) { + sync := NewGroupMemberLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_lifecycle_adapter.go new file mode 100644 index 0000000..37dd783 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_group_member_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type GroupMemberLifecycle interface { + Create(obj *v3.GroupMember) (runtime.Object, error) + Remove(obj *v3.GroupMember) (runtime.Object, error) + Updated(obj *v3.GroupMember) (runtime.Object, error) +} + +type groupMemberLifecycleAdapter struct { + lifecycle GroupMemberLifecycle +} + +func (w *groupMemberLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *groupMemberLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *groupMemberLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.GroupMember)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *groupMemberLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.GroupMember)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *groupMemberLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.GroupMember)) + if o == nil { + return nil, err + } + return o, err +} + +func NewGroupMemberLifecycleAdapter(name string, clusterScoped bool, client GroupMemberInterface, l GroupMemberLifecycle) GroupMemberHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(GroupMemberGroupVersionResource) + } + adapter := &groupMemberLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.GroupMember) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_k8s_client.go new file mode 100644 index 0000000..64df8a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_k8s_client.go @@ -0,0 +1,798 @@ +package v3 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + NodePoolsGetter + NodesGetter + NodeDriversGetter + NodeTemplatesGetter + PodSecurityAdmissionConfigurationTemplatesGetter + ProjectsGetter + GlobalRolesGetter + GlobalRoleBindingsGetter + RoleTemplatesGetter + ClusterRoleTemplateBindingsGetter + ProjectRoleTemplateBindingsGetter + ClustersGetter + ClusterRegistrationTokensGetter + CatalogsGetter + TemplatesGetter + CatalogTemplatesGetter + CatalogTemplateVersionsGetter + TemplateVersionsGetter + TemplateContentsGetter + GroupsGetter + GroupMembersGetter + SamlTokensGetter + PrincipalsGetter + UsersGetter + AuthConfigsGetter + LdapConfigsGetter + TokensGetter + DynamicSchemasGetter + PreferencesGetter + UserAttributesGetter + ProjectNetworkPoliciesGetter + SettingsGetter + FeaturesGetter + ComposeConfigsGetter + ProjectCatalogsGetter + ClusterCatalogsGetter + MultiClusterAppsGetter + MultiClusterAppRevisionsGetter + GlobalDnsesGetter + GlobalDnsProvidersGetter + KontainerDriversGetter + EtcdBackupsGetter + CloudCredentialsGetter + ClusterTemplatesGetter + ClusterTemplateRevisionsGetter + RkeK8sSystemImagesGetter + RkeK8sServiceOptionsGetter + RkeAddonsGetter + FleetWorkspacesGetter + RancherUserNotificationsGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v3.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type NodePoolsGetter interface { + NodePools(namespace string) NodePoolInterface +} + +func (c *Client) NodePools(namespace string) NodePoolInterface { + sharedClient := c.clientFactory.ForResourceKind(NodePoolGroupVersionResource, NodePoolGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NodePoolResource, NodePoolGroupVersionKind, nodePoolFactory{}) + return &nodePoolClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NodesGetter interface { + Nodes(namespace string) NodeInterface +} + +func (c *Client) Nodes(namespace string) NodeInterface { + sharedClient := c.clientFactory.ForResourceKind(NodeGroupVersionResource, NodeGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NodeResource, NodeGroupVersionKind, nodeFactory{}) + return &nodeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NodeDriversGetter interface { + NodeDrivers(namespace string) NodeDriverInterface +} + +func (c *Client) NodeDrivers(namespace string) NodeDriverInterface { + sharedClient := c.clientFactory.ForResourceKind(NodeDriverGroupVersionResource, NodeDriverGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NodeDriverResource, NodeDriverGroupVersionKind, nodeDriverFactory{}) + return &nodeDriverClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NodeTemplatesGetter interface { + NodeTemplates(namespace string) NodeTemplateInterface +} + +func (c *Client) NodeTemplates(namespace string) NodeTemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(NodeTemplateGroupVersionResource, NodeTemplateGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NodeTemplateResource, NodeTemplateGroupVersionKind, nodeTemplateFactory{}) + return &nodeTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PodSecurityAdmissionConfigurationTemplatesGetter interface { + PodSecurityAdmissionConfigurationTemplates(namespace string) PodSecurityAdmissionConfigurationTemplateInterface +} + +func (c *Client) PodSecurityAdmissionConfigurationTemplates(namespace string) PodSecurityAdmissionConfigurationTemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(PodSecurityAdmissionConfigurationTemplateGroupVersionResource, PodSecurityAdmissionConfigurationTemplateGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &PodSecurityAdmissionConfigurationTemplateResource, PodSecurityAdmissionConfigurationTemplateGroupVersionKind, podSecurityAdmissionConfigurationTemplateFactory{}) + return &podSecurityAdmissionConfigurationTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ProjectsGetter interface { + Projects(namespace string) ProjectInterface +} + +func (c *Client) Projects(namespace string) ProjectInterface { + sharedClient := c.clientFactory.ForResourceKind(ProjectGroupVersionResource, ProjectGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ProjectResource, ProjectGroupVersionKind, projectFactory{}) + return &projectClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GlobalRolesGetter interface { + GlobalRoles(namespace string) GlobalRoleInterface +} + +func (c *Client) GlobalRoles(namespace string) GlobalRoleInterface { + sharedClient := c.clientFactory.ForResourceKind(GlobalRoleGroupVersionResource, GlobalRoleGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GlobalRoleResource, GlobalRoleGroupVersionKind, globalRoleFactory{}) + return &globalRoleClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GlobalRoleBindingsGetter interface { + GlobalRoleBindings(namespace string) GlobalRoleBindingInterface +} + +func (c *Client) GlobalRoleBindings(namespace string) GlobalRoleBindingInterface { + sharedClient := c.clientFactory.ForResourceKind(GlobalRoleBindingGroupVersionResource, GlobalRoleBindingGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GlobalRoleBindingResource, GlobalRoleBindingGroupVersionKind, globalRoleBindingFactory{}) + return &globalRoleBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RoleTemplatesGetter interface { + RoleTemplates(namespace string) RoleTemplateInterface +} + +func (c *Client) RoleTemplates(namespace string) RoleTemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(RoleTemplateGroupVersionResource, RoleTemplateGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RoleTemplateResource, RoleTemplateGroupVersionKind, roleTemplateFactory{}) + return &roleTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterRoleTemplateBindingsGetter interface { + ClusterRoleTemplateBindings(namespace string) ClusterRoleTemplateBindingInterface +} + +func (c *Client) ClusterRoleTemplateBindings(namespace string) ClusterRoleTemplateBindingInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterRoleTemplateBindingGroupVersionResource, ClusterRoleTemplateBindingGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterRoleTemplateBindingResource, ClusterRoleTemplateBindingGroupVersionKind, clusterRoleTemplateBindingFactory{}) + return &clusterRoleTemplateBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ProjectRoleTemplateBindingsGetter interface { + ProjectRoleTemplateBindings(namespace string) ProjectRoleTemplateBindingInterface +} + +func (c *Client) ProjectRoleTemplateBindings(namespace string) ProjectRoleTemplateBindingInterface { + sharedClient := c.clientFactory.ForResourceKind(ProjectRoleTemplateBindingGroupVersionResource, ProjectRoleTemplateBindingGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ProjectRoleTemplateBindingResource, ProjectRoleTemplateBindingGroupVersionKind, projectRoleTemplateBindingFactory{}) + return &projectRoleTemplateBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClustersGetter interface { + Clusters(namespace string) ClusterInterface +} + +func (c *Client) Clusters(namespace string) ClusterInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterGroupVersionResource, ClusterGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterResource, ClusterGroupVersionKind, clusterFactory{}) + return &clusterClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterRegistrationTokensGetter interface { + ClusterRegistrationTokens(namespace string) ClusterRegistrationTokenInterface +} + +func (c *Client) ClusterRegistrationTokens(namespace string) ClusterRegistrationTokenInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterRegistrationTokenGroupVersionResource, ClusterRegistrationTokenGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterRegistrationTokenResource, ClusterRegistrationTokenGroupVersionKind, clusterRegistrationTokenFactory{}) + return &clusterRegistrationTokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CatalogsGetter interface { + Catalogs(namespace string) CatalogInterface +} + +func (c *Client) Catalogs(namespace string) CatalogInterface { + sharedClient := c.clientFactory.ForResourceKind(CatalogGroupVersionResource, CatalogGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CatalogResource, CatalogGroupVersionKind, catalogFactory{}) + return &catalogClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type TemplatesGetter interface { + Templates(namespace string) TemplateInterface +} + +func (c *Client) Templates(namespace string) TemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(TemplateGroupVersionResource, TemplateGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &TemplateResource, TemplateGroupVersionKind, templateFactory{}) + return &templateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CatalogTemplatesGetter interface { + CatalogTemplates(namespace string) CatalogTemplateInterface +} + +func (c *Client) CatalogTemplates(namespace string) CatalogTemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(CatalogTemplateGroupVersionResource, CatalogTemplateGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CatalogTemplateResource, CatalogTemplateGroupVersionKind, catalogTemplateFactory{}) + return &catalogTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CatalogTemplateVersionsGetter interface { + CatalogTemplateVersions(namespace string) CatalogTemplateVersionInterface +} + +func (c *Client) CatalogTemplateVersions(namespace string) CatalogTemplateVersionInterface { + sharedClient := c.clientFactory.ForResourceKind(CatalogTemplateVersionGroupVersionResource, CatalogTemplateVersionGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CatalogTemplateVersionResource, CatalogTemplateVersionGroupVersionKind, catalogTemplateVersionFactory{}) + return &catalogTemplateVersionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type TemplateVersionsGetter interface { + TemplateVersions(namespace string) TemplateVersionInterface +} + +func (c *Client) TemplateVersions(namespace string) TemplateVersionInterface { + sharedClient := c.clientFactory.ForResourceKind(TemplateVersionGroupVersionResource, TemplateVersionGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &TemplateVersionResource, TemplateVersionGroupVersionKind, templateVersionFactory{}) + return &templateVersionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type TemplateContentsGetter interface { + TemplateContents(namespace string) TemplateContentInterface +} + +func (c *Client) TemplateContents(namespace string) TemplateContentInterface { + sharedClient := c.clientFactory.ForResourceKind(TemplateContentGroupVersionResource, TemplateContentGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &TemplateContentResource, TemplateContentGroupVersionKind, templateContentFactory{}) + return &templateContentClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GroupsGetter interface { + Groups(namespace string) GroupInterface +} + +func (c *Client) Groups(namespace string) GroupInterface { + sharedClient := c.clientFactory.ForResourceKind(GroupGroupVersionResource, GroupGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GroupResource, GroupGroupVersionKind, groupFactory{}) + return &groupClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GroupMembersGetter interface { + GroupMembers(namespace string) GroupMemberInterface +} + +func (c *Client) GroupMembers(namespace string) GroupMemberInterface { + sharedClient := c.clientFactory.ForResourceKind(GroupMemberGroupVersionResource, GroupMemberGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GroupMemberResource, GroupMemberGroupVersionKind, groupMemberFactory{}) + return &groupMemberClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type SamlTokensGetter interface { + SamlTokens(namespace string) SamlTokenInterface +} + +func (c *Client) SamlTokens(namespace string) SamlTokenInterface { + sharedClient := c.clientFactory.ForResourceKind(SamlTokenGroupVersionResource, SamlTokenGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &SamlTokenResource, SamlTokenGroupVersionKind, samlTokenFactory{}) + return &samlTokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PrincipalsGetter interface { + Principals(namespace string) PrincipalInterface +} + +func (c *Client) Principals(namespace string) PrincipalInterface { + sharedClient := c.clientFactory.ForResourceKind(PrincipalGroupVersionResource, PrincipalGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &PrincipalResource, PrincipalGroupVersionKind, principalFactory{}) + return &principalClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type UsersGetter interface { + Users(namespace string) UserInterface +} + +func (c *Client) Users(namespace string) UserInterface { + sharedClient := c.clientFactory.ForResourceKind(UserGroupVersionResource, UserGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &UserResource, UserGroupVersionKind, userFactory{}) + return &userClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type AuthConfigsGetter interface { + AuthConfigs(namespace string) AuthConfigInterface +} + +func (c *Client) AuthConfigs(namespace string) AuthConfigInterface { + sharedClient := c.clientFactory.ForResourceKind(AuthConfigGroupVersionResource, AuthConfigGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &AuthConfigResource, AuthConfigGroupVersionKind, authConfigFactory{}) + return &authConfigClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type LdapConfigsGetter interface { + LdapConfigs(namespace string) LdapConfigInterface +} + +func (c *Client) LdapConfigs(namespace string) LdapConfigInterface { + sharedClient := c.clientFactory.ForResourceKind(LdapConfigGroupVersionResource, LdapConfigGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &LdapConfigResource, LdapConfigGroupVersionKind, ldapConfigFactory{}) + return &ldapConfigClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type TokensGetter interface { + Tokens(namespace string) TokenInterface +} + +func (c *Client) Tokens(namespace string) TokenInterface { + sharedClient := c.clientFactory.ForResourceKind(TokenGroupVersionResource, TokenGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &TokenResource, TokenGroupVersionKind, tokenFactory{}) + return &tokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type DynamicSchemasGetter interface { + DynamicSchemas(namespace string) DynamicSchemaInterface +} + +func (c *Client) DynamicSchemas(namespace string) DynamicSchemaInterface { + sharedClient := c.clientFactory.ForResourceKind(DynamicSchemaGroupVersionResource, DynamicSchemaGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &DynamicSchemaResource, DynamicSchemaGroupVersionKind, dynamicSchemaFactory{}) + return &dynamicSchemaClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type PreferencesGetter interface { + Preferences(namespace string) PreferenceInterface +} + +func (c *Client) Preferences(namespace string) PreferenceInterface { + sharedClient := c.clientFactory.ForResourceKind(PreferenceGroupVersionResource, PreferenceGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &PreferenceResource, PreferenceGroupVersionKind, preferenceFactory{}) + return &preferenceClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type UserAttributesGetter interface { + UserAttributes(namespace string) UserAttributeInterface +} + +func (c *Client) UserAttributes(namespace string) UserAttributeInterface { + sharedClient := c.clientFactory.ForResourceKind(UserAttributeGroupVersionResource, UserAttributeGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &UserAttributeResource, UserAttributeGroupVersionKind, userAttributeFactory{}) + return &userAttributeClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ProjectNetworkPoliciesGetter interface { + ProjectNetworkPolicies(namespace string) ProjectNetworkPolicyInterface +} + +func (c *Client) ProjectNetworkPolicies(namespace string) ProjectNetworkPolicyInterface { + sharedClient := c.clientFactory.ForResourceKind(ProjectNetworkPolicyGroupVersionResource, ProjectNetworkPolicyGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ProjectNetworkPolicyResource, ProjectNetworkPolicyGroupVersionKind, projectNetworkPolicyFactory{}) + return &projectNetworkPolicyClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type SettingsGetter interface { + Settings(namespace string) SettingInterface +} + +func (c *Client) Settings(namespace string) SettingInterface { + sharedClient := c.clientFactory.ForResourceKind(SettingGroupVersionResource, SettingGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &SettingResource, SettingGroupVersionKind, settingFactory{}) + return &settingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type FeaturesGetter interface { + Features(namespace string) FeatureInterface +} + +func (c *Client) Features(namespace string) FeatureInterface { + sharedClient := c.clientFactory.ForResourceKind(FeatureGroupVersionResource, FeatureGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &FeatureResource, FeatureGroupVersionKind, featureFactory{}) + return &featureClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ComposeConfigsGetter interface { + ComposeConfigs(namespace string) ComposeConfigInterface +} + +func (c *Client) ComposeConfigs(namespace string) ComposeConfigInterface { + sharedClient := c.clientFactory.ForResourceKind(ComposeConfigGroupVersionResource, ComposeConfigGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ComposeConfigResource, ComposeConfigGroupVersionKind, composeConfigFactory{}) + return &composeConfigClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ProjectCatalogsGetter interface { + ProjectCatalogs(namespace string) ProjectCatalogInterface +} + +func (c *Client) ProjectCatalogs(namespace string) ProjectCatalogInterface { + sharedClient := c.clientFactory.ForResourceKind(ProjectCatalogGroupVersionResource, ProjectCatalogGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ProjectCatalogResource, ProjectCatalogGroupVersionKind, projectCatalogFactory{}) + return &projectCatalogClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterCatalogsGetter interface { + ClusterCatalogs(namespace string) ClusterCatalogInterface +} + +func (c *Client) ClusterCatalogs(namespace string) ClusterCatalogInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterCatalogGroupVersionResource, ClusterCatalogGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterCatalogResource, ClusterCatalogGroupVersionKind, clusterCatalogFactory{}) + return &clusterCatalogClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type MultiClusterAppsGetter interface { + MultiClusterApps(namespace string) MultiClusterAppInterface +} + +func (c *Client) MultiClusterApps(namespace string) MultiClusterAppInterface { + sharedClient := c.clientFactory.ForResourceKind(MultiClusterAppGroupVersionResource, MultiClusterAppGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &MultiClusterAppResource, MultiClusterAppGroupVersionKind, multiClusterAppFactory{}) + return &multiClusterAppClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type MultiClusterAppRevisionsGetter interface { + MultiClusterAppRevisions(namespace string) MultiClusterAppRevisionInterface +} + +func (c *Client) MultiClusterAppRevisions(namespace string) MultiClusterAppRevisionInterface { + sharedClient := c.clientFactory.ForResourceKind(MultiClusterAppRevisionGroupVersionResource, MultiClusterAppRevisionGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &MultiClusterAppRevisionResource, MultiClusterAppRevisionGroupVersionKind, multiClusterAppRevisionFactory{}) + return &multiClusterAppRevisionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GlobalDnsesGetter interface { + GlobalDnses(namespace string) GlobalDnsInterface +} + +func (c *Client) GlobalDnses(namespace string) GlobalDnsInterface { + sharedClient := c.clientFactory.ForResourceKind(GlobalDnsGroupVersionResource, GlobalDnsGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GlobalDnsResource, GlobalDnsGroupVersionKind, globalDnsFactory{}) + return &globalDnsClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type GlobalDnsProvidersGetter interface { + GlobalDnsProviders(namespace string) GlobalDnsProviderInterface +} + +func (c *Client) GlobalDnsProviders(namespace string) GlobalDnsProviderInterface { + sharedClient := c.clientFactory.ForResourceKind(GlobalDnsProviderGroupVersionResource, GlobalDnsProviderGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &GlobalDnsProviderResource, GlobalDnsProviderGroupVersionKind, globalDnsProviderFactory{}) + return &globalDnsProviderClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type KontainerDriversGetter interface { + KontainerDrivers(namespace string) KontainerDriverInterface +} + +func (c *Client) KontainerDrivers(namespace string) KontainerDriverInterface { + sharedClient := c.clientFactory.ForResourceKind(KontainerDriverGroupVersionResource, KontainerDriverGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &KontainerDriverResource, KontainerDriverGroupVersionKind, kontainerDriverFactory{}) + return &kontainerDriverClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type EtcdBackupsGetter interface { + EtcdBackups(namespace string) EtcdBackupInterface +} + +func (c *Client) EtcdBackups(namespace string) EtcdBackupInterface { + sharedClient := c.clientFactory.ForResourceKind(EtcdBackupGroupVersionResource, EtcdBackupGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &EtcdBackupResource, EtcdBackupGroupVersionKind, etcdBackupFactory{}) + return &etcdBackupClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CloudCredentialsGetter interface { + CloudCredentials(namespace string) CloudCredentialInterface +} + +func (c *Client) CloudCredentials(namespace string) CloudCredentialInterface { + sharedClient := c.clientFactory.ForResourceKind(CloudCredentialGroupVersionResource, CloudCredentialGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CloudCredentialResource, CloudCredentialGroupVersionKind, cloudCredentialFactory{}) + return &cloudCredentialClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterTemplatesGetter interface { + ClusterTemplates(namespace string) ClusterTemplateInterface +} + +func (c *Client) ClusterTemplates(namespace string) ClusterTemplateInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterTemplateGroupVersionResource, ClusterTemplateGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterTemplateResource, ClusterTemplateGroupVersionKind, clusterTemplateFactory{}) + return &clusterTemplateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterTemplateRevisionsGetter interface { + ClusterTemplateRevisions(namespace string) ClusterTemplateRevisionInterface +} + +func (c *Client) ClusterTemplateRevisions(namespace string) ClusterTemplateRevisionInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterTemplateRevisionGroupVersionResource, ClusterTemplateRevisionGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterTemplateRevisionResource, ClusterTemplateRevisionGroupVersionKind, clusterTemplateRevisionFactory{}) + return &clusterTemplateRevisionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RkeK8sSystemImagesGetter interface { + RkeK8sSystemImages(namespace string) RkeK8sSystemImageInterface +} + +func (c *Client) RkeK8sSystemImages(namespace string) RkeK8sSystemImageInterface { + sharedClient := c.clientFactory.ForResourceKind(RkeK8sSystemImageGroupVersionResource, RkeK8sSystemImageGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RkeK8sSystemImageResource, RkeK8sSystemImageGroupVersionKind, rkeK8sSystemImageFactory{}) + return &rkeK8sSystemImageClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RkeK8sServiceOptionsGetter interface { + RkeK8sServiceOptions(namespace string) RkeK8sServiceOptionInterface +} + +func (c *Client) RkeK8sServiceOptions(namespace string) RkeK8sServiceOptionInterface { + sharedClient := c.clientFactory.ForResourceKind(RkeK8sServiceOptionGroupVersionResource, RkeK8sServiceOptionGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RkeK8sServiceOptionResource, RkeK8sServiceOptionGroupVersionKind, rkeK8sServiceOptionFactory{}) + return &rkeK8sServiceOptionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RkeAddonsGetter interface { + RkeAddons(namespace string) RkeAddonInterface +} + +func (c *Client) RkeAddons(namespace string) RkeAddonInterface { + sharedClient := c.clientFactory.ForResourceKind(RkeAddonGroupVersionResource, RkeAddonGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RkeAddonResource, RkeAddonGroupVersionKind, rkeAddonFactory{}) + return &rkeAddonClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type FleetWorkspacesGetter interface { + FleetWorkspaces(namespace string) FleetWorkspaceInterface +} + +func (c *Client) FleetWorkspaces(namespace string) FleetWorkspaceInterface { + sharedClient := c.clientFactory.ForResourceKind(FleetWorkspaceGroupVersionResource, FleetWorkspaceGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &FleetWorkspaceResource, FleetWorkspaceGroupVersionKind, fleetWorkspaceFactory{}) + return &fleetWorkspaceClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RancherUserNotificationsGetter interface { + RancherUserNotifications(namespace string) RancherUserNotificationInterface +} + +func (c *Client) RancherUserNotifications(namespace string) RancherUserNotificationInterface { + sharedClient := c.clientFactory.ForResourceKind(RancherUserNotificationGroupVersionResource, RancherUserNotificationGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RancherUserNotificationResource, RancherUserNotificationGroupVersionKind, rancherUserNotificationFactory{}) + return &rancherUserNotificationClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_controller.go new file mode 100644 index 0000000..177abef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + KontainerDriverGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "KontainerDriver", + } + KontainerDriverResource = metav1.APIResource{ + Name: "kontainerdrivers", + SingularName: "kontainerdriver", + Namespaced: false, + Kind: KontainerDriverGroupVersionKind.Kind, + } + + KontainerDriverGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "kontainerdrivers", + } +) + +func init() { + resource.Put(KontainerDriverGroupVersionResource) +} + +// Deprecated: use v3.KontainerDriver instead +type KontainerDriver = v3.KontainerDriver + +func NewKontainerDriver(namespace, name string, obj v3.KontainerDriver) *v3.KontainerDriver { + obj.APIVersion, obj.Kind = KontainerDriverGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type KontainerDriverHandlerFunc func(key string, obj *v3.KontainerDriver) (runtime.Object, error) + +type KontainerDriverChangeHandlerFunc func(obj *v3.KontainerDriver) (runtime.Object, error) + +type KontainerDriverLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.KontainerDriver, err error) + Get(namespace, name string) (*v3.KontainerDriver, error) +} + +type KontainerDriverController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() KontainerDriverLister + AddHandler(ctx context.Context, name string, handler KontainerDriverHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync KontainerDriverHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler KontainerDriverHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler KontainerDriverHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type KontainerDriverInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.KontainerDriver) (*v3.KontainerDriver, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) + Get(name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) + Update(*v3.KontainerDriver) (*v3.KontainerDriver, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.KontainerDriverList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.KontainerDriverList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() KontainerDriverController + AddHandler(ctx context.Context, name string, sync KontainerDriverHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync KontainerDriverHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle KontainerDriverLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle KontainerDriverLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync KontainerDriverHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync KontainerDriverHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle KontainerDriverLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle KontainerDriverLifecycle) +} + +type kontainerDriverLister struct { + ns string + controller *kontainerDriverController +} + +func (l *kontainerDriverLister) List(namespace string, selector labels.Selector) (ret []*v3.KontainerDriver, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.KontainerDriver)) + }) + return +} + +func (l *kontainerDriverLister) Get(namespace, name string) (*v3.KontainerDriver, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: KontainerDriverGroupVersionKind.Group, + Resource: KontainerDriverGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.KontainerDriver), nil +} + +type kontainerDriverController struct { + ns string + controller.GenericController +} + +func (c *kontainerDriverController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *kontainerDriverController) Lister() KontainerDriverLister { + return &kontainerDriverLister{ + ns: c.ns, + controller: c, + } +} + +func (c *kontainerDriverController) AddHandler(ctx context.Context, name string, handler KontainerDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.KontainerDriver); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *kontainerDriverController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler KontainerDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.KontainerDriver); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *kontainerDriverController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler KontainerDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.KontainerDriver); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *kontainerDriverController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler KontainerDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.KontainerDriver); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type kontainerDriverFactory struct { +} + +func (c kontainerDriverFactory) Object() runtime.Object { + return &v3.KontainerDriver{} +} + +func (c kontainerDriverFactory) List() runtime.Object { + return &v3.KontainerDriverList{} +} + +func (s *kontainerDriverClient) Controller() KontainerDriverController { + genericController := controller.NewGenericController(s.ns, KontainerDriverGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(KontainerDriverGroupVersionResource, KontainerDriverGroupVersionKind.Kind, false)) + + return &kontainerDriverController{ + ns: s.ns, + GenericController: genericController, + } +} + +type kontainerDriverClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller KontainerDriverController +} + +func (s *kontainerDriverClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *kontainerDriverClient) Create(o *v3.KontainerDriver) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) Get(name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) Update(o *v3.KontainerDriver) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) UpdateStatus(o *v3.KontainerDriver) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *kontainerDriverClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *kontainerDriverClient) List(opts metav1.ListOptions) (*v3.KontainerDriverList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.KontainerDriverList), err +} + +func (s *kontainerDriverClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.KontainerDriverList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.KontainerDriverList), err +} + +func (s *kontainerDriverClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *kontainerDriverClient) Patch(o *v3.KontainerDriver, patchType types.PatchType, data []byte, subresources ...string) (*v3.KontainerDriver, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.KontainerDriver), err +} + +func (s *kontainerDriverClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *kontainerDriverClient) AddHandler(ctx context.Context, name string, sync KontainerDriverHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *kontainerDriverClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync KontainerDriverHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *kontainerDriverClient) AddLifecycle(ctx context.Context, name string, lifecycle KontainerDriverLifecycle) { + sync := NewKontainerDriverLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *kontainerDriverClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle KontainerDriverLifecycle) { + sync := NewKontainerDriverLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *kontainerDriverClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync KontainerDriverHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *kontainerDriverClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync KontainerDriverHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *kontainerDriverClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle KontainerDriverLifecycle) { + sync := NewKontainerDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *kontainerDriverClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle KontainerDriverLifecycle) { + sync := NewKontainerDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_lifecycle_adapter.go new file mode 100644 index 0000000..12e8dea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_kontainer_driver_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type KontainerDriverLifecycle interface { + Create(obj *v3.KontainerDriver) (runtime.Object, error) + Remove(obj *v3.KontainerDriver) (runtime.Object, error) + Updated(obj *v3.KontainerDriver) (runtime.Object, error) +} + +type kontainerDriverLifecycleAdapter struct { + lifecycle KontainerDriverLifecycle +} + +func (w *kontainerDriverLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *kontainerDriverLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *kontainerDriverLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.KontainerDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *kontainerDriverLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.KontainerDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *kontainerDriverLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.KontainerDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func NewKontainerDriverLifecycleAdapter(name string, clusterScoped bool, client KontainerDriverInterface, l KontainerDriverLifecycle) KontainerDriverHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(KontainerDriverGroupVersionResource) + } + adapter := &kontainerDriverLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.KontainerDriver) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_controller.go new file mode 100644 index 0000000..4c8ce2a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + LdapConfigGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "LdapConfig", + } + LdapConfigResource = metav1.APIResource{ + Name: "ldapconfigs", + SingularName: "ldapconfig", + Namespaced: false, + Kind: LdapConfigGroupVersionKind.Kind, + } + + LdapConfigGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "ldapconfigs", + } +) + +func init() { + resource.Put(LdapConfigGroupVersionResource) +} + +// Deprecated: use v3.LdapConfig instead +type LdapConfig = v3.LdapConfig + +func NewLdapConfig(namespace, name string, obj v3.LdapConfig) *v3.LdapConfig { + obj.APIVersion, obj.Kind = LdapConfigGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type LdapConfigHandlerFunc func(key string, obj *v3.LdapConfig) (runtime.Object, error) + +type LdapConfigChangeHandlerFunc func(obj *v3.LdapConfig) (runtime.Object, error) + +type LdapConfigLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.LdapConfig, err error) + Get(namespace, name string) (*v3.LdapConfig, error) +} + +type LdapConfigController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() LdapConfigLister + AddHandler(ctx context.Context, name string, handler LdapConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LdapConfigHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler LdapConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler LdapConfigHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type LdapConfigInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.LdapConfig) (*v3.LdapConfig, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.LdapConfig, error) + Get(name string, opts metav1.GetOptions) (*v3.LdapConfig, error) + Update(*v3.LdapConfig) (*v3.LdapConfig, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.LdapConfigList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.LdapConfigList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() LdapConfigController + AddHandler(ctx context.Context, name string, sync LdapConfigHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LdapConfigHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle LdapConfigLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle LdapConfigLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync LdapConfigHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync LdapConfigHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle LdapConfigLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle LdapConfigLifecycle) +} + +type ldapConfigLister struct { + ns string + controller *ldapConfigController +} + +func (l *ldapConfigLister) List(namespace string, selector labels.Selector) (ret []*v3.LdapConfig, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.LdapConfig)) + }) + return +} + +func (l *ldapConfigLister) Get(namespace, name string) (*v3.LdapConfig, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: LdapConfigGroupVersionKind.Group, + Resource: LdapConfigGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.LdapConfig), nil +} + +type ldapConfigController struct { + ns string + controller.GenericController +} + +func (c *ldapConfigController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *ldapConfigController) Lister() LdapConfigLister { + return &ldapConfigLister{ + ns: c.ns, + controller: c, + } +} + +func (c *ldapConfigController) AddHandler(ctx context.Context, name string, handler LdapConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.LdapConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ldapConfigController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler LdapConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.LdapConfig); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ldapConfigController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler LdapConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.LdapConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ldapConfigController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler LdapConfigHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.LdapConfig); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type ldapConfigFactory struct { +} + +func (c ldapConfigFactory) Object() runtime.Object { + return &v3.LdapConfig{} +} + +func (c ldapConfigFactory) List() runtime.Object { + return &v3.LdapConfigList{} +} + +func (s *ldapConfigClient) Controller() LdapConfigController { + genericController := controller.NewGenericController(s.ns, LdapConfigGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(LdapConfigGroupVersionResource, LdapConfigGroupVersionKind.Kind, false)) + + return &ldapConfigController{ + ns: s.ns, + GenericController: genericController, + } +} + +type ldapConfigClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller LdapConfigController +} + +func (s *ldapConfigClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *ldapConfigClient) Create(o *v3.LdapConfig) (*v3.LdapConfig, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) Get(name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.LdapConfig, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) Update(o *v3.LdapConfig) (*v3.LdapConfig, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) UpdateStatus(o *v3.LdapConfig) (*v3.LdapConfig, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *ldapConfigClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *ldapConfigClient) List(opts metav1.ListOptions) (*v3.LdapConfigList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.LdapConfigList), err +} + +func (s *ldapConfigClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.LdapConfigList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.LdapConfigList), err +} + +func (s *ldapConfigClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *ldapConfigClient) Patch(o *v3.LdapConfig, patchType types.PatchType, data []byte, subresources ...string) (*v3.LdapConfig, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.LdapConfig), err +} + +func (s *ldapConfigClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *ldapConfigClient) AddHandler(ctx context.Context, name string, sync LdapConfigHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ldapConfigClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync LdapConfigHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ldapConfigClient) AddLifecycle(ctx context.Context, name string, lifecycle LdapConfigLifecycle) { + sync := NewLdapConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ldapConfigClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle LdapConfigLifecycle) { + sync := NewLdapConfigLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ldapConfigClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync LdapConfigHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ldapConfigClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync LdapConfigHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *ldapConfigClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle LdapConfigLifecycle) { + sync := NewLdapConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ldapConfigClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle LdapConfigLifecycle) { + sync := NewLdapConfigLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_lifecycle_adapter.go new file mode 100644 index 0000000..7df177f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_ldap_config_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type LdapConfigLifecycle interface { + Create(obj *v3.LdapConfig) (runtime.Object, error) + Remove(obj *v3.LdapConfig) (runtime.Object, error) + Updated(obj *v3.LdapConfig) (runtime.Object, error) +} + +type ldapConfigLifecycleAdapter struct { + lifecycle LdapConfigLifecycle +} + +func (w *ldapConfigLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *ldapConfigLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *ldapConfigLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.LdapConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ldapConfigLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.LdapConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ldapConfigLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.LdapConfig)) + if o == nil { + return nil, err + } + return o, err +} + +func NewLdapConfigLifecycleAdapter(name string, clusterScoped bool, client LdapConfigInterface, l LdapConfigLifecycle) LdapConfigHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(LdapConfigGroupVersionResource) + } + adapter := &ldapConfigLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.LdapConfig) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_controller.go new file mode 100644 index 0000000..c548c44 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + MultiClusterAppGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "MultiClusterApp", + } + MultiClusterAppResource = metav1.APIResource{ + Name: "multiclusterapps", + SingularName: "multiclusterapp", + Namespaced: true, + + Kind: MultiClusterAppGroupVersionKind.Kind, + } + + MultiClusterAppGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "multiclusterapps", + } +) + +func init() { + resource.Put(MultiClusterAppGroupVersionResource) +} + +// Deprecated: use v3.MultiClusterApp instead +type MultiClusterApp = v3.MultiClusterApp + +func NewMultiClusterApp(namespace, name string, obj v3.MultiClusterApp) *v3.MultiClusterApp { + obj.APIVersion, obj.Kind = MultiClusterAppGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type MultiClusterAppHandlerFunc func(key string, obj *v3.MultiClusterApp) (runtime.Object, error) + +type MultiClusterAppChangeHandlerFunc func(obj *v3.MultiClusterApp) (runtime.Object, error) + +type MultiClusterAppLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.MultiClusterApp, err error) + Get(namespace, name string) (*v3.MultiClusterApp, error) +} + +type MultiClusterAppController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() MultiClusterAppLister + AddHandler(ctx context.Context, name string, handler MultiClusterAppHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler MultiClusterAppHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler MultiClusterAppHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type MultiClusterAppInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.MultiClusterApp) (*v3.MultiClusterApp, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) + Get(name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) + Update(*v3.MultiClusterApp) (*v3.MultiClusterApp, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.MultiClusterAppList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() MultiClusterAppController + AddHandler(ctx context.Context, name string, sync MultiClusterAppHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle MultiClusterAppLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle MultiClusterAppLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync MultiClusterAppHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync MultiClusterAppHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle MultiClusterAppLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle MultiClusterAppLifecycle) +} + +type multiClusterAppLister struct { + ns string + controller *multiClusterAppController +} + +func (l *multiClusterAppLister) List(namespace string, selector labels.Selector) (ret []*v3.MultiClusterApp, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.MultiClusterApp)) + }) + return +} + +func (l *multiClusterAppLister) Get(namespace, name string) (*v3.MultiClusterApp, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: MultiClusterAppGroupVersionKind.Group, + Resource: MultiClusterAppGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.MultiClusterApp), nil +} + +type multiClusterAppController struct { + ns string + controller.GenericController +} + +func (c *multiClusterAppController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *multiClusterAppController) Lister() MultiClusterAppLister { + return &multiClusterAppLister{ + ns: c.ns, + controller: c, + } +} + +func (c *multiClusterAppController) AddHandler(ctx context.Context, name string, handler MultiClusterAppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterApp); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler MultiClusterAppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterApp); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler MultiClusterAppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterApp); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler MultiClusterAppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterApp); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type multiClusterAppFactory struct { +} + +func (c multiClusterAppFactory) Object() runtime.Object { + return &v3.MultiClusterApp{} +} + +func (c multiClusterAppFactory) List() runtime.Object { + return &v3.MultiClusterAppList{} +} + +func (s *multiClusterAppClient) Controller() MultiClusterAppController { + genericController := controller.NewGenericController(s.ns, MultiClusterAppGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(MultiClusterAppGroupVersionResource, MultiClusterAppGroupVersionKind.Kind, true)) + + return &multiClusterAppController{ + ns: s.ns, + GenericController: genericController, + } +} + +type multiClusterAppClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller MultiClusterAppController +} + +func (s *multiClusterAppClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *multiClusterAppClient) Create(o *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) Get(name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) Update(o *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) UpdateStatus(o *v3.MultiClusterApp) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *multiClusterAppClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *multiClusterAppClient) List(opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.MultiClusterAppList), err +} + +func (s *multiClusterAppClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.MultiClusterAppList), err +} + +func (s *multiClusterAppClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *multiClusterAppClient) Patch(o *v3.MultiClusterApp, patchType types.PatchType, data []byte, subresources ...string) (*v3.MultiClusterApp, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.MultiClusterApp), err +} + +func (s *multiClusterAppClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *multiClusterAppClient) AddHandler(ctx context.Context, name string, sync MultiClusterAppHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *multiClusterAppClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *multiClusterAppClient) AddLifecycle(ctx context.Context, name string, lifecycle MultiClusterAppLifecycle) { + sync := NewMultiClusterAppLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *multiClusterAppClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle MultiClusterAppLifecycle) { + sync := NewMultiClusterAppLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *multiClusterAppClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync MultiClusterAppHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *multiClusterAppClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync MultiClusterAppHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *multiClusterAppClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle MultiClusterAppLifecycle) { + sync := NewMultiClusterAppLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *multiClusterAppClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle MultiClusterAppLifecycle) { + sync := NewMultiClusterAppLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_lifecycle_adapter.go new file mode 100644 index 0000000..804f247 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type MultiClusterAppLifecycle interface { + Create(obj *v3.MultiClusterApp) (runtime.Object, error) + Remove(obj *v3.MultiClusterApp) (runtime.Object, error) + Updated(obj *v3.MultiClusterApp) (runtime.Object, error) +} + +type multiClusterAppLifecycleAdapter struct { + lifecycle MultiClusterAppLifecycle +} + +func (w *multiClusterAppLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *multiClusterAppLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *multiClusterAppLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.MultiClusterApp)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *multiClusterAppLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.MultiClusterApp)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *multiClusterAppLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.MultiClusterApp)) + if o == nil { + return nil, err + } + return o, err +} + +func NewMultiClusterAppLifecycleAdapter(name string, clusterScoped bool, client MultiClusterAppInterface, l MultiClusterAppLifecycle) MultiClusterAppHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(MultiClusterAppGroupVersionResource) + } + adapter := &multiClusterAppLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.MultiClusterApp) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_controller.go new file mode 100644 index 0000000..c11acff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + MultiClusterAppRevisionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "MultiClusterAppRevision", + } + MultiClusterAppRevisionResource = metav1.APIResource{ + Name: "multiclusterapprevisions", + SingularName: "multiclusterapprevision", + Namespaced: true, + + Kind: MultiClusterAppRevisionGroupVersionKind.Kind, + } + + MultiClusterAppRevisionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "multiclusterapprevisions", + } +) + +func init() { + resource.Put(MultiClusterAppRevisionGroupVersionResource) +} + +// Deprecated: use v3.MultiClusterAppRevision instead +type MultiClusterAppRevision = v3.MultiClusterAppRevision + +func NewMultiClusterAppRevision(namespace, name string, obj v3.MultiClusterAppRevision) *v3.MultiClusterAppRevision { + obj.APIVersion, obj.Kind = MultiClusterAppRevisionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type MultiClusterAppRevisionHandlerFunc func(key string, obj *v3.MultiClusterAppRevision) (runtime.Object, error) + +type MultiClusterAppRevisionChangeHandlerFunc func(obj *v3.MultiClusterAppRevision) (runtime.Object, error) + +type MultiClusterAppRevisionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.MultiClusterAppRevision, err error) + Get(namespace, name string) (*v3.MultiClusterAppRevision, error) +} + +type MultiClusterAppRevisionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() MultiClusterAppRevisionLister + AddHandler(ctx context.Context, name string, handler MultiClusterAppRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppRevisionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler MultiClusterAppRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler MultiClusterAppRevisionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type MultiClusterAppRevisionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) + Get(name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) + Update(*v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() MultiClusterAppRevisionController + AddHandler(ctx context.Context, name string, sync MultiClusterAppRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppRevisionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle MultiClusterAppRevisionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle MultiClusterAppRevisionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync MultiClusterAppRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync MultiClusterAppRevisionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle MultiClusterAppRevisionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle MultiClusterAppRevisionLifecycle) +} + +type multiClusterAppRevisionLister struct { + ns string + controller *multiClusterAppRevisionController +} + +func (l *multiClusterAppRevisionLister) List(namespace string, selector labels.Selector) (ret []*v3.MultiClusterAppRevision, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.MultiClusterAppRevision)) + }) + return +} + +func (l *multiClusterAppRevisionLister) Get(namespace, name string) (*v3.MultiClusterAppRevision, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: MultiClusterAppRevisionGroupVersionKind.Group, + Resource: MultiClusterAppRevisionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.MultiClusterAppRevision), nil +} + +type multiClusterAppRevisionController struct { + ns string + controller.GenericController +} + +func (c *multiClusterAppRevisionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *multiClusterAppRevisionController) Lister() MultiClusterAppRevisionLister { + return &multiClusterAppRevisionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *multiClusterAppRevisionController) AddHandler(ctx context.Context, name string, handler MultiClusterAppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterAppRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppRevisionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler MultiClusterAppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterAppRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppRevisionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler MultiClusterAppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterAppRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *multiClusterAppRevisionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler MultiClusterAppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.MultiClusterAppRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type multiClusterAppRevisionFactory struct { +} + +func (c multiClusterAppRevisionFactory) Object() runtime.Object { + return &v3.MultiClusterAppRevision{} +} + +func (c multiClusterAppRevisionFactory) List() runtime.Object { + return &v3.MultiClusterAppRevisionList{} +} + +func (s *multiClusterAppRevisionClient) Controller() MultiClusterAppRevisionController { + genericController := controller.NewGenericController(s.ns, MultiClusterAppRevisionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(MultiClusterAppRevisionGroupVersionResource, MultiClusterAppRevisionGroupVersionKind.Kind, true)) + + return &multiClusterAppRevisionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type multiClusterAppRevisionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller MultiClusterAppRevisionController +} + +func (s *multiClusterAppRevisionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *multiClusterAppRevisionClient) Create(o *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) Get(name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) Update(o *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) UpdateStatus(o *v3.MultiClusterAppRevision) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *multiClusterAppRevisionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *multiClusterAppRevisionClient) List(opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.MultiClusterAppRevisionList), err +} + +func (s *multiClusterAppRevisionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.MultiClusterAppRevisionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.MultiClusterAppRevisionList), err +} + +func (s *multiClusterAppRevisionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *multiClusterAppRevisionClient) Patch(o *v3.MultiClusterAppRevision, patchType types.PatchType, data []byte, subresources ...string) (*v3.MultiClusterAppRevision, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.MultiClusterAppRevision), err +} + +func (s *multiClusterAppRevisionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *multiClusterAppRevisionClient) AddHandler(ctx context.Context, name string, sync MultiClusterAppRevisionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *multiClusterAppRevisionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync MultiClusterAppRevisionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *multiClusterAppRevisionClient) AddLifecycle(ctx context.Context, name string, lifecycle MultiClusterAppRevisionLifecycle) { + sync := NewMultiClusterAppRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *multiClusterAppRevisionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle MultiClusterAppRevisionLifecycle) { + sync := NewMultiClusterAppRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *multiClusterAppRevisionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync MultiClusterAppRevisionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *multiClusterAppRevisionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync MultiClusterAppRevisionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *multiClusterAppRevisionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle MultiClusterAppRevisionLifecycle) { + sync := NewMultiClusterAppRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *multiClusterAppRevisionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle MultiClusterAppRevisionLifecycle) { + sync := NewMultiClusterAppRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_lifecycle_adapter.go new file mode 100644 index 0000000..503c026 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_multi_cluster_app_revision_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type MultiClusterAppRevisionLifecycle interface { + Create(obj *v3.MultiClusterAppRevision) (runtime.Object, error) + Remove(obj *v3.MultiClusterAppRevision) (runtime.Object, error) + Updated(obj *v3.MultiClusterAppRevision) (runtime.Object, error) +} + +type multiClusterAppRevisionLifecycleAdapter struct { + lifecycle MultiClusterAppRevisionLifecycle +} + +func (w *multiClusterAppRevisionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *multiClusterAppRevisionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *multiClusterAppRevisionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.MultiClusterAppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *multiClusterAppRevisionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.MultiClusterAppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *multiClusterAppRevisionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.MultiClusterAppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func NewMultiClusterAppRevisionLifecycleAdapter(name string, clusterScoped bool, client MultiClusterAppRevisionInterface, l MultiClusterAppRevisionLifecycle) MultiClusterAppRevisionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(MultiClusterAppRevisionGroupVersionResource) + } + adapter := &multiClusterAppRevisionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.MultiClusterAppRevision) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_controller.go new file mode 100644 index 0000000..577e284 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NodeGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Node", + } + NodeResource = metav1.APIResource{ + Name: "nodes", + SingularName: "node", + Namespaced: true, + + Kind: NodeGroupVersionKind.Kind, + } + + NodeGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "nodes", + } +) + +func init() { + resource.Put(NodeGroupVersionResource) +} + +// Deprecated: use v3.Node instead +type Node = v3.Node + +func NewNode(namespace, name string, obj v3.Node) *v3.Node { + obj.APIVersion, obj.Kind = NodeGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NodeHandlerFunc func(key string, obj *v3.Node) (runtime.Object, error) + +type NodeChangeHandlerFunc func(obj *v3.Node) (runtime.Object, error) + +type NodeLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Node, err error) + Get(namespace, name string) (*v3.Node, error) +} + +type NodeController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NodeLister + AddHandler(ctx context.Context, name string, handler NodeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NodeHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NodeInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Node) (*v3.Node, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Node, error) + Get(name string, opts metav1.GetOptions) (*v3.Node, error) + Update(*v3.Node) (*v3.Node, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NodeList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NodeController + AddHandler(ctx context.Context, name string, sync NodeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeLifecycle) +} + +type nodeLister struct { + ns string + controller *nodeController +} + +func (l *nodeLister) List(namespace string, selector labels.Selector) (ret []*v3.Node, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Node)) + }) + return +} + +func (l *nodeLister) Get(namespace, name string) (*v3.Node, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NodeGroupVersionKind.Group, + Resource: NodeGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Node), nil +} + +type nodeController struct { + ns string + controller.GenericController +} + +func (c *nodeController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *nodeController) Lister() NodeLister { + return &nodeLister{ + ns: c.ns, + controller: c, + } +} + +func (c *nodeController) AddHandler(ctx context.Context, name string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Node); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Node); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Node); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NodeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Node); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type nodeFactory struct { +} + +func (c nodeFactory) Object() runtime.Object { + return &v3.Node{} +} + +func (c nodeFactory) List() runtime.Object { + return &v3.NodeList{} +} + +func (s *nodeClient) Controller() NodeController { + genericController := controller.NewGenericController(s.ns, NodeGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NodeGroupVersionResource, NodeGroupVersionKind.Kind, true)) + + return &nodeController{ + ns: s.ns, + GenericController: genericController, + } +} + +type nodeClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NodeController +} + +func (s *nodeClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *nodeClient) Create(o *v3.Node) (*v3.Node, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Node), err +} + +func (s *nodeClient) Get(name string, opts metav1.GetOptions) (*v3.Node, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Node), err +} + +func (s *nodeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Node, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Node), err +} + +func (s *nodeClient) Update(o *v3.Node) (*v3.Node, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Node), err +} + +func (s *nodeClient) UpdateStatus(o *v3.Node) (*v3.Node, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Node), err +} + +func (s *nodeClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *nodeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *nodeClient) List(opts metav1.ListOptions) (*v3.NodeList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NodeList), err +} + +func (s *nodeClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NodeList), err +} + +func (s *nodeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *nodeClient) Patch(o *v3.Node, patchType types.PatchType, data []byte, subresources ...string) (*v3.Node, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Node), err +} + +func (s *nodeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *nodeClient) AddHandler(ctx context.Context, name string, sync NodeHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeClient) AddLifecycle(ctx context.Context, name string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeLifecycle) { + sync := NewNodeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_controller.go new file mode 100644 index 0000000..5c544a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NodeDriverGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NodeDriver", + } + NodeDriverResource = metav1.APIResource{ + Name: "nodedrivers", + SingularName: "nodedriver", + Namespaced: false, + Kind: NodeDriverGroupVersionKind.Kind, + } + + NodeDriverGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "nodedrivers", + } +) + +func init() { + resource.Put(NodeDriverGroupVersionResource) +} + +// Deprecated: use v3.NodeDriver instead +type NodeDriver = v3.NodeDriver + +func NewNodeDriver(namespace, name string, obj v3.NodeDriver) *v3.NodeDriver { + obj.APIVersion, obj.Kind = NodeDriverGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NodeDriverHandlerFunc func(key string, obj *v3.NodeDriver) (runtime.Object, error) + +type NodeDriverChangeHandlerFunc func(obj *v3.NodeDriver) (runtime.Object, error) + +type NodeDriverLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NodeDriver, err error) + Get(namespace, name string) (*v3.NodeDriver, error) +} + +type NodeDriverController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NodeDriverLister + AddHandler(ctx context.Context, name string, handler NodeDriverHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeDriverHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodeDriverHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NodeDriverHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NodeDriverInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NodeDriver) (*v3.NodeDriver, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodeDriver, error) + Get(name string, opts metav1.GetOptions) (*v3.NodeDriver, error) + Update(*v3.NodeDriver) (*v3.NodeDriver, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NodeDriverList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeDriverList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NodeDriverController + AddHandler(ctx context.Context, name string, sync NodeDriverHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeDriverHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NodeDriverLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeDriverLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeDriverHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeDriverHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeDriverLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeDriverLifecycle) +} + +type nodeDriverLister struct { + ns string + controller *nodeDriverController +} + +func (l *nodeDriverLister) List(namespace string, selector labels.Selector) (ret []*v3.NodeDriver, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NodeDriver)) + }) + return +} + +func (l *nodeDriverLister) Get(namespace, name string) (*v3.NodeDriver, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NodeDriverGroupVersionKind.Group, + Resource: NodeDriverGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NodeDriver), nil +} + +type nodeDriverController struct { + ns string + controller.GenericController +} + +func (c *nodeDriverController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *nodeDriverController) Lister() NodeDriverLister { + return &nodeDriverLister{ + ns: c.ns, + controller: c, + } +} + +func (c *nodeDriverController) AddHandler(ctx context.Context, name string, handler NodeDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeDriver); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeDriverController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NodeDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeDriver); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeDriverController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodeDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeDriver); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeDriverController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NodeDriverHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeDriver); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type nodeDriverFactory struct { +} + +func (c nodeDriverFactory) Object() runtime.Object { + return &v3.NodeDriver{} +} + +func (c nodeDriverFactory) List() runtime.Object { + return &v3.NodeDriverList{} +} + +func (s *nodeDriverClient) Controller() NodeDriverController { + genericController := controller.NewGenericController(s.ns, NodeDriverGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NodeDriverGroupVersionResource, NodeDriverGroupVersionKind.Kind, false)) + + return &nodeDriverController{ + ns: s.ns, + GenericController: genericController, + } +} + +type nodeDriverClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NodeDriverController +} + +func (s *nodeDriverClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *nodeDriverClient) Create(o *v3.NodeDriver) (*v3.NodeDriver, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) Get(name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodeDriver, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) Update(o *v3.NodeDriver) (*v3.NodeDriver, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) UpdateStatus(o *v3.NodeDriver) (*v3.NodeDriver, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *nodeDriverClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *nodeDriverClient) List(opts metav1.ListOptions) (*v3.NodeDriverList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NodeDriverList), err +} + +func (s *nodeDriverClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeDriverList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NodeDriverList), err +} + +func (s *nodeDriverClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *nodeDriverClient) Patch(o *v3.NodeDriver, patchType types.PatchType, data []byte, subresources ...string) (*v3.NodeDriver, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NodeDriver), err +} + +func (s *nodeDriverClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *nodeDriverClient) AddHandler(ctx context.Context, name string, sync NodeDriverHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeDriverClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeDriverHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeDriverClient) AddLifecycle(ctx context.Context, name string, lifecycle NodeDriverLifecycle) { + sync := NewNodeDriverLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeDriverClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeDriverLifecycle) { + sync := NewNodeDriverLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeDriverClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeDriverHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeDriverClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeDriverHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *nodeDriverClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeDriverLifecycle) { + sync := NewNodeDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeDriverClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeDriverLifecycle) { + sync := NewNodeDriverLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_lifecycle_adapter.go new file mode 100644 index 0000000..9a2dfc8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_driver_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NodeDriverLifecycle interface { + Create(obj *v3.NodeDriver) (runtime.Object, error) + Remove(obj *v3.NodeDriver) (runtime.Object, error) + Updated(obj *v3.NodeDriver) (runtime.Object, error) +} + +type nodeDriverLifecycleAdapter struct { + lifecycle NodeDriverLifecycle +} + +func (w *nodeDriverLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *nodeDriverLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *nodeDriverLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NodeDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeDriverLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NodeDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeDriverLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NodeDriver)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNodeDriverLifecycleAdapter(name string, clusterScoped bool, client NodeDriverInterface, l NodeDriverLifecycle) NodeDriverHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NodeDriverGroupVersionResource) + } + adapter := &nodeDriverLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NodeDriver) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_lifecycle_adapter.go new file mode 100644 index 0000000..882922d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NodeLifecycle interface { + Create(obj *v3.Node) (runtime.Object, error) + Remove(obj *v3.Node) (runtime.Object, error) + Updated(obj *v3.Node) (runtime.Object, error) +} + +type nodeLifecycleAdapter struct { + lifecycle NodeLifecycle +} + +func (w *nodeLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *nodeLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *nodeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Node)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNodeLifecycleAdapter(name string, clusterScoped bool, client NodeInterface, l NodeLifecycle) NodeHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NodeGroupVersionResource) + } + adapter := &nodeLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Node) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_controller.go new file mode 100644 index 0000000..4b5f372 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NodePoolGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NodePool", + } + NodePoolResource = metav1.APIResource{ + Name: "nodepools", + SingularName: "nodepool", + Namespaced: true, + + Kind: NodePoolGroupVersionKind.Kind, + } + + NodePoolGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "nodepools", + } +) + +func init() { + resource.Put(NodePoolGroupVersionResource) +} + +// Deprecated: use v3.NodePool instead +type NodePool = v3.NodePool + +func NewNodePool(namespace, name string, obj v3.NodePool) *v3.NodePool { + obj.APIVersion, obj.Kind = NodePoolGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NodePoolHandlerFunc func(key string, obj *v3.NodePool) (runtime.Object, error) + +type NodePoolChangeHandlerFunc func(obj *v3.NodePool) (runtime.Object, error) + +type NodePoolLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NodePool, err error) + Get(namespace, name string) (*v3.NodePool, error) +} + +type NodePoolController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NodePoolLister + AddHandler(ctx context.Context, name string, handler NodePoolHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodePoolHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodePoolHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NodePoolHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NodePoolInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NodePool) (*v3.NodePool, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodePool, error) + Get(name string, opts metav1.GetOptions) (*v3.NodePool, error) + Update(*v3.NodePool) (*v3.NodePool, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NodePoolList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodePoolList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NodePoolController + AddHandler(ctx context.Context, name string, sync NodePoolHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodePoolHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NodePoolLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodePoolLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodePoolHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodePoolHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodePoolLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodePoolLifecycle) +} + +type nodePoolLister struct { + ns string + controller *nodePoolController +} + +func (l *nodePoolLister) List(namespace string, selector labels.Selector) (ret []*v3.NodePool, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NodePool)) + }) + return +} + +func (l *nodePoolLister) Get(namespace, name string) (*v3.NodePool, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NodePoolGroupVersionKind.Group, + Resource: NodePoolGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NodePool), nil +} + +type nodePoolController struct { + ns string + controller.GenericController +} + +func (c *nodePoolController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *nodePoolController) Lister() NodePoolLister { + return &nodePoolLister{ + ns: c.ns, + controller: c, + } +} + +func (c *nodePoolController) AddHandler(ctx context.Context, name string, handler NodePoolHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodePool); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodePoolController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NodePoolHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodePool); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodePoolController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodePoolHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodePool); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodePoolController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NodePoolHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodePool); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type nodePoolFactory struct { +} + +func (c nodePoolFactory) Object() runtime.Object { + return &v3.NodePool{} +} + +func (c nodePoolFactory) List() runtime.Object { + return &v3.NodePoolList{} +} + +func (s *nodePoolClient) Controller() NodePoolController { + genericController := controller.NewGenericController(s.ns, NodePoolGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NodePoolGroupVersionResource, NodePoolGroupVersionKind.Kind, true)) + + return &nodePoolController{ + ns: s.ns, + GenericController: genericController, + } +} + +type nodePoolClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NodePoolController +} + +func (s *nodePoolClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *nodePoolClient) Create(o *v3.NodePool) (*v3.NodePool, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) Get(name string, opts metav1.GetOptions) (*v3.NodePool, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodePool, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) Update(o *v3.NodePool) (*v3.NodePool, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) UpdateStatus(o *v3.NodePool) (*v3.NodePool, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *nodePoolClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *nodePoolClient) List(opts metav1.ListOptions) (*v3.NodePoolList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NodePoolList), err +} + +func (s *nodePoolClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodePoolList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NodePoolList), err +} + +func (s *nodePoolClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *nodePoolClient) Patch(o *v3.NodePool, patchType types.PatchType, data []byte, subresources ...string) (*v3.NodePool, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NodePool), err +} + +func (s *nodePoolClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *nodePoolClient) AddHandler(ctx context.Context, name string, sync NodePoolHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodePoolClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodePoolHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodePoolClient) AddLifecycle(ctx context.Context, name string, lifecycle NodePoolLifecycle) { + sync := NewNodePoolLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodePoolClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodePoolLifecycle) { + sync := NewNodePoolLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodePoolClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodePoolHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodePoolClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodePoolHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *nodePoolClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodePoolLifecycle) { + sync := NewNodePoolLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodePoolClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodePoolLifecycle) { + sync := NewNodePoolLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_lifecycle_adapter.go new file mode 100644 index 0000000..94d3622 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_pool_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NodePoolLifecycle interface { + Create(obj *v3.NodePool) (runtime.Object, error) + Remove(obj *v3.NodePool) (runtime.Object, error) + Updated(obj *v3.NodePool) (runtime.Object, error) +} + +type nodePoolLifecycleAdapter struct { + lifecycle NodePoolLifecycle +} + +func (w *nodePoolLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *nodePoolLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *nodePoolLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NodePool)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodePoolLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NodePool)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodePoolLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NodePool)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNodePoolLifecycleAdapter(name string, clusterScoped bool, client NodePoolInterface, l NodePoolLifecycle) NodePoolHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NodePoolGroupVersionResource) + } + adapter := &nodePoolLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NodePool) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_controller.go new file mode 100644 index 0000000..845177d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NodeTemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NodeTemplate", + } + NodeTemplateResource = metav1.APIResource{ + Name: "nodetemplates", + SingularName: "nodetemplate", + Namespaced: true, + + Kind: NodeTemplateGroupVersionKind.Kind, + } + + NodeTemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "nodetemplates", + } +) + +func init() { + resource.Put(NodeTemplateGroupVersionResource) +} + +// Deprecated: use v3.NodeTemplate instead +type NodeTemplate = v3.NodeTemplate + +func NewNodeTemplate(namespace, name string, obj v3.NodeTemplate) *v3.NodeTemplate { + obj.APIVersion, obj.Kind = NodeTemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NodeTemplateHandlerFunc func(key string, obj *v3.NodeTemplate) (runtime.Object, error) + +type NodeTemplateChangeHandlerFunc func(obj *v3.NodeTemplate) (runtime.Object, error) + +type NodeTemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NodeTemplate, err error) + Get(namespace, name string) (*v3.NodeTemplate, error) +} + +type NodeTemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NodeTemplateLister + AddHandler(ctx context.Context, name string, handler NodeTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeTemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NodeTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NodeTemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NodeTemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NodeTemplate) (*v3.NodeTemplate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) + Get(name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) + Update(*v3.NodeTemplate) (*v3.NodeTemplate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NodeTemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeTemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NodeTemplateController + AddHandler(ctx context.Context, name string, sync NodeTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeTemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NodeTemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeTemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeTemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeTemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeTemplateLifecycle) +} + +type nodeTemplateLister struct { + ns string + controller *nodeTemplateController +} + +func (l *nodeTemplateLister) List(namespace string, selector labels.Selector) (ret []*v3.NodeTemplate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NodeTemplate)) + }) + return +} + +func (l *nodeTemplateLister) Get(namespace, name string) (*v3.NodeTemplate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NodeTemplateGroupVersionKind.Group, + Resource: NodeTemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NodeTemplate), nil +} + +type nodeTemplateController struct { + ns string + controller.GenericController +} + +func (c *nodeTemplateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *nodeTemplateController) Lister() NodeTemplateLister { + return &nodeTemplateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *nodeTemplateController) AddHandler(ctx context.Context, name string, handler NodeTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeTemplateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NodeTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeTemplateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NodeTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *nodeTemplateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NodeTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NodeTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type nodeTemplateFactory struct { +} + +func (c nodeTemplateFactory) Object() runtime.Object { + return &v3.NodeTemplate{} +} + +func (c nodeTemplateFactory) List() runtime.Object { + return &v3.NodeTemplateList{} +} + +func (s *nodeTemplateClient) Controller() NodeTemplateController { + genericController := controller.NewGenericController(s.ns, NodeTemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NodeTemplateGroupVersionResource, NodeTemplateGroupVersionKind.Kind, true)) + + return &nodeTemplateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type nodeTemplateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NodeTemplateController +} + +func (s *nodeTemplateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *nodeTemplateClient) Create(o *v3.NodeTemplate) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) Get(name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) Update(o *v3.NodeTemplate) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) UpdateStatus(o *v3.NodeTemplate) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *nodeTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *nodeTemplateClient) List(opts metav1.ListOptions) (*v3.NodeTemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NodeTemplateList), err +} + +func (s *nodeTemplateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NodeTemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NodeTemplateList), err +} + +func (s *nodeTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *nodeTemplateClient) Patch(o *v3.NodeTemplate, patchType types.PatchType, data []byte, subresources ...string) (*v3.NodeTemplate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NodeTemplate), err +} + +func (s *nodeTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *nodeTemplateClient) AddHandler(ctx context.Context, name string, sync NodeTemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeTemplateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NodeTemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeTemplateClient) AddLifecycle(ctx context.Context, name string, lifecycle NodeTemplateLifecycle) { + sync := NewNodeTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *nodeTemplateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NodeTemplateLifecycle) { + sync := NewNodeTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *nodeTemplateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NodeTemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeTemplateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NodeTemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *nodeTemplateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NodeTemplateLifecycle) { + sync := NewNodeTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *nodeTemplateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NodeTemplateLifecycle) { + sync := NewNodeTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_lifecycle_adapter.go new file mode 100644 index 0000000..33aced7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_node_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NodeTemplateLifecycle interface { + Create(obj *v3.NodeTemplate) (runtime.Object, error) + Remove(obj *v3.NodeTemplate) (runtime.Object, error) + Updated(obj *v3.NodeTemplate) (runtime.Object, error) +} + +type nodeTemplateLifecycleAdapter struct { + lifecycle NodeTemplateLifecycle +} + +func (w *nodeTemplateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *nodeTemplateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *nodeTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NodeTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NodeTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *nodeTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NodeTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNodeTemplateLifecycleAdapter(name string, clusterScoped bool, client NodeTemplateInterface, l NodeTemplateLifecycle) NodeTemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NodeTemplateGroupVersionResource) + } + adapter := &nodeTemplateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NodeTemplate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_controller.go new file mode 100644 index 0000000..8f74e8b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + PodSecurityAdmissionConfigurationTemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "PodSecurityAdmissionConfigurationTemplate", + } + PodSecurityAdmissionConfigurationTemplateResource = metav1.APIResource{ + Name: "podsecurityadmissionconfigurationtemplates", + SingularName: "podsecurityadmissionconfigurationtemplate", + Namespaced: false, + Kind: PodSecurityAdmissionConfigurationTemplateGroupVersionKind.Kind, + } + + PodSecurityAdmissionConfigurationTemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "podsecurityadmissionconfigurationtemplates", + } +) + +func init() { + resource.Put(PodSecurityAdmissionConfigurationTemplateGroupVersionResource) +} + +// Deprecated: use v3.PodSecurityAdmissionConfigurationTemplate instead +type PodSecurityAdmissionConfigurationTemplate = v3.PodSecurityAdmissionConfigurationTemplate + +func NewPodSecurityAdmissionConfigurationTemplate(namespace, name string, obj v3.PodSecurityAdmissionConfigurationTemplate) *v3.PodSecurityAdmissionConfigurationTemplate { + obj.APIVersion, obj.Kind = PodSecurityAdmissionConfigurationTemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type PodSecurityAdmissionConfigurationTemplateHandlerFunc func(key string, obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) + +type PodSecurityAdmissionConfigurationTemplateChangeHandlerFunc func(obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) + +type PodSecurityAdmissionConfigurationTemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.PodSecurityAdmissionConfigurationTemplate, err error) + Get(namespace, name string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) +} + +type PodSecurityAdmissionConfigurationTemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() PodSecurityAdmissionConfigurationTemplateLister + AddHandler(ctx context.Context, name string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type PodSecurityAdmissionConfigurationTemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + Get(name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + Update(*v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() PodSecurityAdmissionConfigurationTemplateController + AddHandler(ctx context.Context, name string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) +} + +type podSecurityAdmissionConfigurationTemplateLister struct { + ns string + controller *podSecurityAdmissionConfigurationTemplateController +} + +func (l *podSecurityAdmissionConfigurationTemplateLister) List(namespace string, selector labels.Selector) (ret []*v3.PodSecurityAdmissionConfigurationTemplate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.PodSecurityAdmissionConfigurationTemplate)) + }) + return +} + +func (l *podSecurityAdmissionConfigurationTemplateLister) Get(namespace, name string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: PodSecurityAdmissionConfigurationTemplateGroupVersionKind.Group, + Resource: PodSecurityAdmissionConfigurationTemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), nil +} + +type podSecurityAdmissionConfigurationTemplateController struct { + ns string + controller.GenericController +} + +func (c *podSecurityAdmissionConfigurationTemplateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *podSecurityAdmissionConfigurationTemplateController) Lister() PodSecurityAdmissionConfigurationTemplateLister { + return &podSecurityAdmissionConfigurationTemplateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *podSecurityAdmissionConfigurationTemplateController) AddHandler(ctx context.Context, name string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.PodSecurityAdmissionConfigurationTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podSecurityAdmissionConfigurationTemplateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.PodSecurityAdmissionConfigurationTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podSecurityAdmissionConfigurationTemplateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.PodSecurityAdmissionConfigurationTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *podSecurityAdmissionConfigurationTemplateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.PodSecurityAdmissionConfigurationTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type podSecurityAdmissionConfigurationTemplateFactory struct { +} + +func (c podSecurityAdmissionConfigurationTemplateFactory) Object() runtime.Object { + return &v3.PodSecurityAdmissionConfigurationTemplate{} +} + +func (c podSecurityAdmissionConfigurationTemplateFactory) List() runtime.Object { + return &v3.PodSecurityAdmissionConfigurationTemplateList{} +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Controller() PodSecurityAdmissionConfigurationTemplateController { + genericController := controller.NewGenericController(s.ns, PodSecurityAdmissionConfigurationTemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(PodSecurityAdmissionConfigurationTemplateGroupVersionResource, PodSecurityAdmissionConfigurationTemplateGroupVersionKind.Kind, false)) + + return &podSecurityAdmissionConfigurationTemplateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type podSecurityAdmissionConfigurationTemplateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller PodSecurityAdmissionConfigurationTemplateController +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Create(o *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Get(name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Update(o *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) UpdateStatus(o *v3.PodSecurityAdmissionConfigurationTemplate) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) List(opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplateList), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PodSecurityAdmissionConfigurationTemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplateList), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *podSecurityAdmissionConfigurationTemplateClient) Patch(o *v3.PodSecurityAdmissionConfigurationTemplate, patchType types.PatchType, data []byte, subresources ...string) (*v3.PodSecurityAdmissionConfigurationTemplate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.PodSecurityAdmissionConfigurationTemplate), err +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddHandler(ctx context.Context, name string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddLifecycle(ctx context.Context, name string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) { + sync := NewPodSecurityAdmissionConfigurationTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) { + sync := NewPodSecurityAdmissionConfigurationTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PodSecurityAdmissionConfigurationTemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) { + sync := NewPodSecurityAdmissionConfigurationTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *podSecurityAdmissionConfigurationTemplateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle) { + sync := NewPodSecurityAdmissionConfigurationTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_lifecycle_adapter.go new file mode 100644 index 0000000..8cc5d87 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_pod_security_admission_configuration_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type PodSecurityAdmissionConfigurationTemplateLifecycle interface { + Create(obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) + Remove(obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) + Updated(obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) +} + +type podSecurityAdmissionConfigurationTemplateLifecycleAdapter struct { + lifecycle PodSecurityAdmissionConfigurationTemplateLifecycle +} + +func (w *podSecurityAdmissionConfigurationTemplateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *podSecurityAdmissionConfigurationTemplateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *podSecurityAdmissionConfigurationTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.PodSecurityAdmissionConfigurationTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *podSecurityAdmissionConfigurationTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.PodSecurityAdmissionConfigurationTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *podSecurityAdmissionConfigurationTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.PodSecurityAdmissionConfigurationTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewPodSecurityAdmissionConfigurationTemplateLifecycleAdapter(name string, clusterScoped bool, client PodSecurityAdmissionConfigurationTemplateInterface, l PodSecurityAdmissionConfigurationTemplateLifecycle) PodSecurityAdmissionConfigurationTemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(PodSecurityAdmissionConfigurationTemplateGroupVersionResource) + } + adapter := &podSecurityAdmissionConfigurationTemplateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.PodSecurityAdmissionConfigurationTemplate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_controller.go new file mode 100644 index 0000000..de3c27d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + PreferenceGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Preference", + } + PreferenceResource = metav1.APIResource{ + Name: "preferences", + SingularName: "preference", + Namespaced: true, + + Kind: PreferenceGroupVersionKind.Kind, + } + + PreferenceGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "preferences", + } +) + +func init() { + resource.Put(PreferenceGroupVersionResource) +} + +// Deprecated: use v3.Preference instead +type Preference = v3.Preference + +func NewPreference(namespace, name string, obj v3.Preference) *v3.Preference { + obj.APIVersion, obj.Kind = PreferenceGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type PreferenceHandlerFunc func(key string, obj *v3.Preference) (runtime.Object, error) + +type PreferenceChangeHandlerFunc func(obj *v3.Preference) (runtime.Object, error) + +type PreferenceLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Preference, err error) + Get(namespace, name string) (*v3.Preference, error) +} + +type PreferenceController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() PreferenceLister + AddHandler(ctx context.Context, name string, handler PreferenceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PreferenceHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PreferenceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler PreferenceHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type PreferenceInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Preference) (*v3.Preference, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Preference, error) + Get(name string, opts metav1.GetOptions) (*v3.Preference, error) + Update(*v3.Preference) (*v3.Preference, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.PreferenceList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PreferenceList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() PreferenceController + AddHandler(ctx context.Context, name string, sync PreferenceHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PreferenceHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle PreferenceLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PreferenceLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PreferenceHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PreferenceHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PreferenceLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PreferenceLifecycle) +} + +type preferenceLister struct { + ns string + controller *preferenceController +} + +func (l *preferenceLister) List(namespace string, selector labels.Selector) (ret []*v3.Preference, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Preference)) + }) + return +} + +func (l *preferenceLister) Get(namespace, name string) (*v3.Preference, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: PreferenceGroupVersionKind.Group, + Resource: PreferenceGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Preference), nil +} + +type preferenceController struct { + ns string + controller.GenericController +} + +func (c *preferenceController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *preferenceController) Lister() PreferenceLister { + return &preferenceLister{ + ns: c.ns, + controller: c, + } +} + +func (c *preferenceController) AddHandler(ctx context.Context, name string, handler PreferenceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Preference); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *preferenceController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler PreferenceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Preference); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *preferenceController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PreferenceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Preference); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *preferenceController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler PreferenceHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Preference); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type preferenceFactory struct { +} + +func (c preferenceFactory) Object() runtime.Object { + return &v3.Preference{} +} + +func (c preferenceFactory) List() runtime.Object { + return &v3.PreferenceList{} +} + +func (s *preferenceClient) Controller() PreferenceController { + genericController := controller.NewGenericController(s.ns, PreferenceGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(PreferenceGroupVersionResource, PreferenceGroupVersionKind.Kind, true)) + + return &preferenceController{ + ns: s.ns, + GenericController: genericController, + } +} + +type preferenceClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller PreferenceController +} + +func (s *preferenceClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *preferenceClient) Create(o *v3.Preference) (*v3.Preference, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) Get(name string, opts metav1.GetOptions) (*v3.Preference, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Preference, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) Update(o *v3.Preference) (*v3.Preference, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) UpdateStatus(o *v3.Preference) (*v3.Preference, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *preferenceClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *preferenceClient) List(opts metav1.ListOptions) (*v3.PreferenceList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.PreferenceList), err +} + +func (s *preferenceClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PreferenceList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.PreferenceList), err +} + +func (s *preferenceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *preferenceClient) Patch(o *v3.Preference, patchType types.PatchType, data []byte, subresources ...string) (*v3.Preference, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Preference), err +} + +func (s *preferenceClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *preferenceClient) AddHandler(ctx context.Context, name string, sync PreferenceHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *preferenceClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PreferenceHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *preferenceClient) AddLifecycle(ctx context.Context, name string, lifecycle PreferenceLifecycle) { + sync := NewPreferenceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *preferenceClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PreferenceLifecycle) { + sync := NewPreferenceLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *preferenceClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PreferenceHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *preferenceClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PreferenceHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *preferenceClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PreferenceLifecycle) { + sync := NewPreferenceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *preferenceClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PreferenceLifecycle) { + sync := NewPreferenceLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_lifecycle_adapter.go new file mode 100644 index 0000000..ba62be8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_preference_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type PreferenceLifecycle interface { + Create(obj *v3.Preference) (runtime.Object, error) + Remove(obj *v3.Preference) (runtime.Object, error) + Updated(obj *v3.Preference) (runtime.Object, error) +} + +type preferenceLifecycleAdapter struct { + lifecycle PreferenceLifecycle +} + +func (w *preferenceLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *preferenceLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *preferenceLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Preference)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *preferenceLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Preference)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *preferenceLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Preference)) + if o == nil { + return nil, err + } + return o, err +} + +func NewPreferenceLifecycleAdapter(name string, clusterScoped bool, client PreferenceInterface, l PreferenceLifecycle) PreferenceHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(PreferenceGroupVersionResource) + } + adapter := &preferenceLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Preference) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_controller.go new file mode 100644 index 0000000..f310a67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + PrincipalGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Principal", + } + PrincipalResource = metav1.APIResource{ + Name: "principals", + SingularName: "principal", + Namespaced: false, + Kind: PrincipalGroupVersionKind.Kind, + } + + PrincipalGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "principals", + } +) + +func init() { + resource.Put(PrincipalGroupVersionResource) +} + +// Deprecated: use v3.Principal instead +type Principal = v3.Principal + +func NewPrincipal(namespace, name string, obj v3.Principal) *v3.Principal { + obj.APIVersion, obj.Kind = PrincipalGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type PrincipalHandlerFunc func(key string, obj *v3.Principal) (runtime.Object, error) + +type PrincipalChangeHandlerFunc func(obj *v3.Principal) (runtime.Object, error) + +type PrincipalLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Principal, err error) + Get(namespace, name string) (*v3.Principal, error) +} + +type PrincipalController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() PrincipalLister + AddHandler(ctx context.Context, name string, handler PrincipalHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PrincipalHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler PrincipalHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler PrincipalHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type PrincipalInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Principal) (*v3.Principal, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Principal, error) + Get(name string, opts metav1.GetOptions) (*v3.Principal, error) + Update(*v3.Principal) (*v3.Principal, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.PrincipalList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PrincipalList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() PrincipalController + AddHandler(ctx context.Context, name string, sync PrincipalHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PrincipalHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle PrincipalLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PrincipalLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PrincipalHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PrincipalHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PrincipalLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PrincipalLifecycle) +} + +type principalLister struct { + ns string + controller *principalController +} + +func (l *principalLister) List(namespace string, selector labels.Selector) (ret []*v3.Principal, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Principal)) + }) + return +} + +func (l *principalLister) Get(namespace, name string) (*v3.Principal, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: PrincipalGroupVersionKind.Group, + Resource: PrincipalGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Principal), nil +} + +type principalController struct { + ns string + controller.GenericController +} + +func (c *principalController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *principalController) Lister() PrincipalLister { + return &principalLister{ + ns: c.ns, + controller: c, + } +} + +func (c *principalController) AddHandler(ctx context.Context, name string, handler PrincipalHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Principal); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *principalController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler PrincipalHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Principal); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *principalController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler PrincipalHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Principal); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *principalController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler PrincipalHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Principal); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type principalFactory struct { +} + +func (c principalFactory) Object() runtime.Object { + return &v3.Principal{} +} + +func (c principalFactory) List() runtime.Object { + return &v3.PrincipalList{} +} + +func (s *principalClient) Controller() PrincipalController { + genericController := controller.NewGenericController(s.ns, PrincipalGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(PrincipalGroupVersionResource, PrincipalGroupVersionKind.Kind, false)) + + return &principalController{ + ns: s.ns, + GenericController: genericController, + } +} + +type principalClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller PrincipalController +} + +func (s *principalClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *principalClient) Create(o *v3.Principal) (*v3.Principal, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Principal), err +} + +func (s *principalClient) Get(name string, opts metav1.GetOptions) (*v3.Principal, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Principal), err +} + +func (s *principalClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Principal, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Principal), err +} + +func (s *principalClient) Update(o *v3.Principal) (*v3.Principal, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Principal), err +} + +func (s *principalClient) UpdateStatus(o *v3.Principal) (*v3.Principal, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Principal), err +} + +func (s *principalClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *principalClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *principalClient) List(opts metav1.ListOptions) (*v3.PrincipalList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.PrincipalList), err +} + +func (s *principalClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.PrincipalList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.PrincipalList), err +} + +func (s *principalClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *principalClient) Patch(o *v3.Principal, patchType types.PatchType, data []byte, subresources ...string) (*v3.Principal, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Principal), err +} + +func (s *principalClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *principalClient) AddHandler(ctx context.Context, name string, sync PrincipalHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *principalClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync PrincipalHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *principalClient) AddLifecycle(ctx context.Context, name string, lifecycle PrincipalLifecycle) { + sync := NewPrincipalLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *principalClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle PrincipalLifecycle) { + sync := NewPrincipalLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *principalClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync PrincipalHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *principalClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync PrincipalHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *principalClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle PrincipalLifecycle) { + sync := NewPrincipalLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *principalClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle PrincipalLifecycle) { + sync := NewPrincipalLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_lifecycle_adapter.go new file mode 100644 index 0000000..a351d20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_principal_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type PrincipalLifecycle interface { + Create(obj *v3.Principal) (runtime.Object, error) + Remove(obj *v3.Principal) (runtime.Object, error) + Updated(obj *v3.Principal) (runtime.Object, error) +} + +type principalLifecycleAdapter struct { + lifecycle PrincipalLifecycle +} + +func (w *principalLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *principalLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *principalLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Principal)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *principalLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Principal)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *principalLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Principal)) + if o == nil { + return nil, err + } + return o, err +} + +func NewPrincipalLifecycleAdapter(name string, clusterScoped bool, client PrincipalInterface, l PrincipalLifecycle) PrincipalHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(PrincipalGroupVersionResource) + } + adapter := &principalLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Principal) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_controller.go new file mode 100644 index 0000000..142555e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ProjectCatalogGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ProjectCatalog", + } + ProjectCatalogResource = metav1.APIResource{ + Name: "projectcatalogs", + SingularName: "projectcatalog", + Namespaced: true, + + Kind: ProjectCatalogGroupVersionKind.Kind, + } + + ProjectCatalogGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "projectcatalogs", + } +) + +func init() { + resource.Put(ProjectCatalogGroupVersionResource) +} + +// Deprecated: use v3.ProjectCatalog instead +type ProjectCatalog = v3.ProjectCatalog + +func NewProjectCatalog(namespace, name string, obj v3.ProjectCatalog) *v3.ProjectCatalog { + obj.APIVersion, obj.Kind = ProjectCatalogGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ProjectCatalogHandlerFunc func(key string, obj *v3.ProjectCatalog) (runtime.Object, error) + +type ProjectCatalogChangeHandlerFunc func(obj *v3.ProjectCatalog) (runtime.Object, error) + +type ProjectCatalogLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ProjectCatalog, err error) + Get(namespace, name string) (*v3.ProjectCatalog, error) +} + +type ProjectCatalogController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ProjectCatalogLister + AddHandler(ctx context.Context, name string, handler ProjectCatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectCatalogHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ProjectCatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ProjectCatalogHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ProjectCatalogInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ProjectCatalog) (*v3.ProjectCatalog, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) + Get(name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) + Update(*v3.ProjectCatalog) (*v3.ProjectCatalog, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ProjectCatalogList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectCatalogList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ProjectCatalogController + AddHandler(ctx context.Context, name string, sync ProjectCatalogHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectCatalogHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ProjectCatalogLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectCatalogLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectCatalogHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectCatalogHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectCatalogLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectCatalogLifecycle) +} + +type projectCatalogLister struct { + ns string + controller *projectCatalogController +} + +func (l *projectCatalogLister) List(namespace string, selector labels.Selector) (ret []*v3.ProjectCatalog, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ProjectCatalog)) + }) + return +} + +func (l *projectCatalogLister) Get(namespace, name string) (*v3.ProjectCatalog, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ProjectCatalogGroupVersionKind.Group, + Resource: ProjectCatalogGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ProjectCatalog), nil +} + +type projectCatalogController struct { + ns string + controller.GenericController +} + +func (c *projectCatalogController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *projectCatalogController) Lister() ProjectCatalogLister { + return &projectCatalogLister{ + ns: c.ns, + controller: c, + } +} + +func (c *projectCatalogController) AddHandler(ctx context.Context, name string, handler ProjectCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectCatalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectCatalogController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ProjectCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectCatalog); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectCatalogController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ProjectCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectCatalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectCatalogController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ProjectCatalogHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectCatalog); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type projectCatalogFactory struct { +} + +func (c projectCatalogFactory) Object() runtime.Object { + return &v3.ProjectCatalog{} +} + +func (c projectCatalogFactory) List() runtime.Object { + return &v3.ProjectCatalogList{} +} + +func (s *projectCatalogClient) Controller() ProjectCatalogController { + genericController := controller.NewGenericController(s.ns, ProjectCatalogGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ProjectCatalogGroupVersionResource, ProjectCatalogGroupVersionKind.Kind, true)) + + return &projectCatalogController{ + ns: s.ns, + GenericController: genericController, + } +} + +type projectCatalogClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ProjectCatalogController +} + +func (s *projectCatalogClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *projectCatalogClient) Create(o *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) Get(name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) Update(o *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) UpdateStatus(o *v3.ProjectCatalog) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *projectCatalogClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *projectCatalogClient) List(opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ProjectCatalogList), err +} + +func (s *projectCatalogClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectCatalogList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ProjectCatalogList), err +} + +func (s *projectCatalogClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *projectCatalogClient) Patch(o *v3.ProjectCatalog, patchType types.PatchType, data []byte, subresources ...string) (*v3.ProjectCatalog, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ProjectCatalog), err +} + +func (s *projectCatalogClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *projectCatalogClient) AddHandler(ctx context.Context, name string, sync ProjectCatalogHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectCatalogClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectCatalogHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectCatalogClient) AddLifecycle(ctx context.Context, name string, lifecycle ProjectCatalogLifecycle) { + sync := NewProjectCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectCatalogClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectCatalogLifecycle) { + sync := NewProjectCatalogLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectCatalogClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectCatalogHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectCatalogClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectCatalogHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *projectCatalogClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectCatalogLifecycle) { + sync := NewProjectCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectCatalogClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectCatalogLifecycle) { + sync := NewProjectCatalogLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_lifecycle_adapter.go new file mode 100644 index 0000000..d2849cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_catalog_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ProjectCatalogLifecycle interface { + Create(obj *v3.ProjectCatalog) (runtime.Object, error) + Remove(obj *v3.ProjectCatalog) (runtime.Object, error) + Updated(obj *v3.ProjectCatalog) (runtime.Object, error) +} + +type projectCatalogLifecycleAdapter struct { + lifecycle ProjectCatalogLifecycle +} + +func (w *projectCatalogLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *projectCatalogLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *projectCatalogLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ProjectCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectCatalogLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ProjectCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectCatalogLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ProjectCatalog)) + if o == nil { + return nil, err + } + return o, err +} + +func NewProjectCatalogLifecycleAdapter(name string, clusterScoped bool, client ProjectCatalogInterface, l ProjectCatalogLifecycle) ProjectCatalogHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ProjectCatalogGroupVersionResource) + } + adapter := &projectCatalogLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ProjectCatalog) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_controller.go new file mode 100644 index 0000000..82ac809 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ProjectGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Project", + } + ProjectResource = metav1.APIResource{ + Name: "projects", + SingularName: "project", + Namespaced: true, + + Kind: ProjectGroupVersionKind.Kind, + } + + ProjectGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "projects", + } +) + +func init() { + resource.Put(ProjectGroupVersionResource) +} + +// Deprecated: use v3.Project instead +type Project = v3.Project + +func NewProject(namespace, name string, obj v3.Project) *v3.Project { + obj.APIVersion, obj.Kind = ProjectGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ProjectHandlerFunc func(key string, obj *v3.Project) (runtime.Object, error) + +type ProjectChangeHandlerFunc func(obj *v3.Project) (runtime.Object, error) + +type ProjectLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Project, err error) + Get(namespace, name string) (*v3.Project, error) +} + +type ProjectController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ProjectLister + AddHandler(ctx context.Context, name string, handler ProjectHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ProjectHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ProjectHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ProjectInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Project) (*v3.Project, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Project, error) + Get(name string, opts metav1.GetOptions) (*v3.Project, error) + Update(*v3.Project) (*v3.Project, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ProjectList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ProjectController + AddHandler(ctx context.Context, name string, sync ProjectHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ProjectLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectLifecycle) +} + +type projectLister struct { + ns string + controller *projectController +} + +func (l *projectLister) List(namespace string, selector labels.Selector) (ret []*v3.Project, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Project)) + }) + return +} + +func (l *projectLister) Get(namespace, name string) (*v3.Project, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ProjectGroupVersionKind.Group, + Resource: ProjectGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Project), nil +} + +type projectController struct { + ns string + controller.GenericController +} + +func (c *projectController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *projectController) Lister() ProjectLister { + return &projectLister{ + ns: c.ns, + controller: c, + } +} + +func (c *projectController) AddHandler(ctx context.Context, name string, handler ProjectHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Project); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ProjectHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Project); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ProjectHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Project); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ProjectHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Project); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type projectFactory struct { +} + +func (c projectFactory) Object() runtime.Object { + return &v3.Project{} +} + +func (c projectFactory) List() runtime.Object { + return &v3.ProjectList{} +} + +func (s *projectClient) Controller() ProjectController { + genericController := controller.NewGenericController(s.ns, ProjectGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ProjectGroupVersionResource, ProjectGroupVersionKind.Kind, true)) + + return &projectController{ + ns: s.ns, + GenericController: genericController, + } +} + +type projectClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ProjectController +} + +func (s *projectClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *projectClient) Create(o *v3.Project) (*v3.Project, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Project), err +} + +func (s *projectClient) Get(name string, opts metav1.GetOptions) (*v3.Project, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Project), err +} + +func (s *projectClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Project, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Project), err +} + +func (s *projectClient) Update(o *v3.Project) (*v3.Project, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Project), err +} + +func (s *projectClient) UpdateStatus(o *v3.Project) (*v3.Project, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Project), err +} + +func (s *projectClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *projectClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *projectClient) List(opts metav1.ListOptions) (*v3.ProjectList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ProjectList), err +} + +func (s *projectClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ProjectList), err +} + +func (s *projectClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *projectClient) Patch(o *v3.Project, patchType types.PatchType, data []byte, subresources ...string) (*v3.Project, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Project), err +} + +func (s *projectClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *projectClient) AddHandler(ctx context.Context, name string, sync ProjectHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectClient) AddLifecycle(ctx context.Context, name string, lifecycle ProjectLifecycle) { + sync := NewProjectLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectLifecycle) { + sync := NewProjectLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *projectClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectLifecycle) { + sync := NewProjectLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectLifecycle) { + sync := NewProjectLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_lifecycle_adapter.go new file mode 100644 index 0000000..acbbd5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ProjectLifecycle interface { + Create(obj *v3.Project) (runtime.Object, error) + Remove(obj *v3.Project) (runtime.Object, error) + Updated(obj *v3.Project) (runtime.Object, error) +} + +type projectLifecycleAdapter struct { + lifecycle ProjectLifecycle +} + +func (w *projectLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *projectLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *projectLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Project)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Project)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Project)) + if o == nil { + return nil, err + } + return o, err +} + +func NewProjectLifecycleAdapter(name string, clusterScoped bool, client ProjectInterface, l ProjectLifecycle) ProjectHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ProjectGroupVersionResource) + } + adapter := &projectLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Project) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_controller.go new file mode 100644 index 0000000..08ec642 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ProjectNetworkPolicyGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ProjectNetworkPolicy", + } + ProjectNetworkPolicyResource = metav1.APIResource{ + Name: "projectnetworkpolicies", + SingularName: "projectnetworkpolicy", + Namespaced: true, + + Kind: ProjectNetworkPolicyGroupVersionKind.Kind, + } + + ProjectNetworkPolicyGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "projectnetworkpolicies", + } +) + +func init() { + resource.Put(ProjectNetworkPolicyGroupVersionResource) +} + +// Deprecated: use v3.ProjectNetworkPolicy instead +type ProjectNetworkPolicy = v3.ProjectNetworkPolicy + +func NewProjectNetworkPolicy(namespace, name string, obj v3.ProjectNetworkPolicy) *v3.ProjectNetworkPolicy { + obj.APIVersion, obj.Kind = ProjectNetworkPolicyGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ProjectNetworkPolicyHandlerFunc func(key string, obj *v3.ProjectNetworkPolicy) (runtime.Object, error) + +type ProjectNetworkPolicyChangeHandlerFunc func(obj *v3.ProjectNetworkPolicy) (runtime.Object, error) + +type ProjectNetworkPolicyLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ProjectNetworkPolicy, err error) + Get(namespace, name string) (*v3.ProjectNetworkPolicy, error) +} + +type ProjectNetworkPolicyController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ProjectNetworkPolicyLister + AddHandler(ctx context.Context, name string, handler ProjectNetworkPolicyHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectNetworkPolicyHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ProjectNetworkPolicyHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ProjectNetworkPolicyHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ProjectNetworkPolicyInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) + Get(name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) + Update(*v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ProjectNetworkPolicyController + AddHandler(ctx context.Context, name string, sync ProjectNetworkPolicyHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectNetworkPolicyHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ProjectNetworkPolicyLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectNetworkPolicyLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectNetworkPolicyHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectNetworkPolicyHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectNetworkPolicyLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectNetworkPolicyLifecycle) +} + +type projectNetworkPolicyLister struct { + ns string + controller *projectNetworkPolicyController +} + +func (l *projectNetworkPolicyLister) List(namespace string, selector labels.Selector) (ret []*v3.ProjectNetworkPolicy, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ProjectNetworkPolicy)) + }) + return +} + +func (l *projectNetworkPolicyLister) Get(namespace, name string) (*v3.ProjectNetworkPolicy, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ProjectNetworkPolicyGroupVersionKind.Group, + Resource: ProjectNetworkPolicyGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ProjectNetworkPolicy), nil +} + +type projectNetworkPolicyController struct { + ns string + controller.GenericController +} + +func (c *projectNetworkPolicyController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *projectNetworkPolicyController) Lister() ProjectNetworkPolicyLister { + return &projectNetworkPolicyLister{ + ns: c.ns, + controller: c, + } +} + +func (c *projectNetworkPolicyController) AddHandler(ctx context.Context, name string, handler ProjectNetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectNetworkPolicy); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectNetworkPolicyController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ProjectNetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectNetworkPolicy); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectNetworkPolicyController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ProjectNetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectNetworkPolicy); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectNetworkPolicyController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ProjectNetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectNetworkPolicy); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type projectNetworkPolicyFactory struct { +} + +func (c projectNetworkPolicyFactory) Object() runtime.Object { + return &v3.ProjectNetworkPolicy{} +} + +func (c projectNetworkPolicyFactory) List() runtime.Object { + return &v3.ProjectNetworkPolicyList{} +} + +func (s *projectNetworkPolicyClient) Controller() ProjectNetworkPolicyController { + genericController := controller.NewGenericController(s.ns, ProjectNetworkPolicyGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ProjectNetworkPolicyGroupVersionResource, ProjectNetworkPolicyGroupVersionKind.Kind, true)) + + return &projectNetworkPolicyController{ + ns: s.ns, + GenericController: genericController, + } +} + +type projectNetworkPolicyClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ProjectNetworkPolicyController +} + +func (s *projectNetworkPolicyClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *projectNetworkPolicyClient) Create(o *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) Get(name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) Update(o *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) UpdateStatus(o *v3.ProjectNetworkPolicy) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *projectNetworkPolicyClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *projectNetworkPolicyClient) List(opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ProjectNetworkPolicyList), err +} + +func (s *projectNetworkPolicyClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectNetworkPolicyList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ProjectNetworkPolicyList), err +} + +func (s *projectNetworkPolicyClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *projectNetworkPolicyClient) Patch(o *v3.ProjectNetworkPolicy, patchType types.PatchType, data []byte, subresources ...string) (*v3.ProjectNetworkPolicy, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ProjectNetworkPolicy), err +} + +func (s *projectNetworkPolicyClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *projectNetworkPolicyClient) AddHandler(ctx context.Context, name string, sync ProjectNetworkPolicyHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectNetworkPolicyClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectNetworkPolicyHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectNetworkPolicyClient) AddLifecycle(ctx context.Context, name string, lifecycle ProjectNetworkPolicyLifecycle) { + sync := NewProjectNetworkPolicyLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectNetworkPolicyClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectNetworkPolicyLifecycle) { + sync := NewProjectNetworkPolicyLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectNetworkPolicyClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectNetworkPolicyHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectNetworkPolicyClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectNetworkPolicyHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *projectNetworkPolicyClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectNetworkPolicyLifecycle) { + sync := NewProjectNetworkPolicyLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectNetworkPolicyClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectNetworkPolicyLifecycle) { + sync := NewProjectNetworkPolicyLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_lifecycle_adapter.go new file mode 100644 index 0000000..137a1eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_network_policy_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ProjectNetworkPolicyLifecycle interface { + Create(obj *v3.ProjectNetworkPolicy) (runtime.Object, error) + Remove(obj *v3.ProjectNetworkPolicy) (runtime.Object, error) + Updated(obj *v3.ProjectNetworkPolicy) (runtime.Object, error) +} + +type projectNetworkPolicyLifecycleAdapter struct { + lifecycle ProjectNetworkPolicyLifecycle +} + +func (w *projectNetworkPolicyLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *projectNetworkPolicyLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *projectNetworkPolicyLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ProjectNetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectNetworkPolicyLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ProjectNetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectNetworkPolicyLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ProjectNetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func NewProjectNetworkPolicyLifecycleAdapter(name string, clusterScoped bool, client ProjectNetworkPolicyInterface, l ProjectNetworkPolicyLifecycle) ProjectNetworkPolicyHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ProjectNetworkPolicyGroupVersionResource) + } + adapter := &projectNetworkPolicyLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ProjectNetworkPolicy) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_controller.go new file mode 100644 index 0000000..ce700e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ProjectRoleTemplateBindingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ProjectRoleTemplateBinding", + } + ProjectRoleTemplateBindingResource = metav1.APIResource{ + Name: "projectroletemplatebindings", + SingularName: "projectroletemplatebinding", + Namespaced: true, + + Kind: ProjectRoleTemplateBindingGroupVersionKind.Kind, + } + + ProjectRoleTemplateBindingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "projectroletemplatebindings", + } +) + +func init() { + resource.Put(ProjectRoleTemplateBindingGroupVersionResource) +} + +// Deprecated: use v3.ProjectRoleTemplateBinding instead +type ProjectRoleTemplateBinding = v3.ProjectRoleTemplateBinding + +func NewProjectRoleTemplateBinding(namespace, name string, obj v3.ProjectRoleTemplateBinding) *v3.ProjectRoleTemplateBinding { + obj.APIVersion, obj.Kind = ProjectRoleTemplateBindingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ProjectRoleTemplateBindingHandlerFunc func(key string, obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) + +type ProjectRoleTemplateBindingChangeHandlerFunc func(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) + +type ProjectRoleTemplateBindingLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ProjectRoleTemplateBinding, err error) + Get(namespace, name string) (*v3.ProjectRoleTemplateBinding, error) +} + +type ProjectRoleTemplateBindingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ProjectRoleTemplateBindingLister + AddHandler(ctx context.Context, name string, handler ProjectRoleTemplateBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectRoleTemplateBindingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ProjectRoleTemplateBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ProjectRoleTemplateBindingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ProjectRoleTemplateBindingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) + Get(name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) + Update(*v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ProjectRoleTemplateBindingController + AddHandler(ctx context.Context, name string, sync ProjectRoleTemplateBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectRoleTemplateBindingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ProjectRoleTemplateBindingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectRoleTemplateBindingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectRoleTemplateBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectRoleTemplateBindingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectRoleTemplateBindingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectRoleTemplateBindingLifecycle) +} + +type projectRoleTemplateBindingLister struct { + ns string + controller *projectRoleTemplateBindingController +} + +func (l *projectRoleTemplateBindingLister) List(namespace string, selector labels.Selector) (ret []*v3.ProjectRoleTemplateBinding, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ProjectRoleTemplateBinding)) + }) + return +} + +func (l *projectRoleTemplateBindingLister) Get(namespace, name string) (*v3.ProjectRoleTemplateBinding, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ProjectRoleTemplateBindingGroupVersionKind.Group, + Resource: ProjectRoleTemplateBindingGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ProjectRoleTemplateBinding), nil +} + +type projectRoleTemplateBindingController struct { + ns string + controller.GenericController +} + +func (c *projectRoleTemplateBindingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *projectRoleTemplateBindingController) Lister() ProjectRoleTemplateBindingLister { + return &projectRoleTemplateBindingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *projectRoleTemplateBindingController) AddHandler(ctx context.Context, name string, handler ProjectRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectRoleTemplateBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectRoleTemplateBindingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ProjectRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectRoleTemplateBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectRoleTemplateBindingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ProjectRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectRoleTemplateBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *projectRoleTemplateBindingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ProjectRoleTemplateBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ProjectRoleTemplateBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type projectRoleTemplateBindingFactory struct { +} + +func (c projectRoleTemplateBindingFactory) Object() runtime.Object { + return &v3.ProjectRoleTemplateBinding{} +} + +func (c projectRoleTemplateBindingFactory) List() runtime.Object { + return &v3.ProjectRoleTemplateBindingList{} +} + +func (s *projectRoleTemplateBindingClient) Controller() ProjectRoleTemplateBindingController { + genericController := controller.NewGenericController(s.ns, ProjectRoleTemplateBindingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ProjectRoleTemplateBindingGroupVersionResource, ProjectRoleTemplateBindingGroupVersionKind.Kind, true)) + + return &projectRoleTemplateBindingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type projectRoleTemplateBindingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ProjectRoleTemplateBindingController +} + +func (s *projectRoleTemplateBindingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *projectRoleTemplateBindingClient) Create(o *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) Get(name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) Update(o *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) UpdateStatus(o *v3.ProjectRoleTemplateBinding) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *projectRoleTemplateBindingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *projectRoleTemplateBindingClient) List(opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ProjectRoleTemplateBindingList), err +} + +func (s *projectRoleTemplateBindingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ProjectRoleTemplateBindingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ProjectRoleTemplateBindingList), err +} + +func (s *projectRoleTemplateBindingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *projectRoleTemplateBindingClient) Patch(o *v3.ProjectRoleTemplateBinding, patchType types.PatchType, data []byte, subresources ...string) (*v3.ProjectRoleTemplateBinding, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ProjectRoleTemplateBinding), err +} + +func (s *projectRoleTemplateBindingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *projectRoleTemplateBindingClient) AddHandler(ctx context.Context, name string, sync ProjectRoleTemplateBindingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectRoleTemplateBindingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ProjectRoleTemplateBindingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectRoleTemplateBindingClient) AddLifecycle(ctx context.Context, name string, lifecycle ProjectRoleTemplateBindingLifecycle) { + sync := NewProjectRoleTemplateBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *projectRoleTemplateBindingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ProjectRoleTemplateBindingLifecycle) { + sync := NewProjectRoleTemplateBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *projectRoleTemplateBindingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ProjectRoleTemplateBindingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectRoleTemplateBindingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ProjectRoleTemplateBindingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *projectRoleTemplateBindingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ProjectRoleTemplateBindingLifecycle) { + sync := NewProjectRoleTemplateBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *projectRoleTemplateBindingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ProjectRoleTemplateBindingLifecycle) { + sync := NewProjectRoleTemplateBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_lifecycle_adapter.go new file mode 100644 index 0000000..4742330 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_project_role_template_binding_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ProjectRoleTemplateBindingLifecycle interface { + Create(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) + Remove(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) + Updated(obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) +} + +type projectRoleTemplateBindingLifecycleAdapter struct { + lifecycle ProjectRoleTemplateBindingLifecycle +} + +func (w *projectRoleTemplateBindingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *projectRoleTemplateBindingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *projectRoleTemplateBindingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ProjectRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectRoleTemplateBindingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ProjectRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *projectRoleTemplateBindingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ProjectRoleTemplateBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func NewProjectRoleTemplateBindingLifecycleAdapter(name string, clusterScoped bool, client ProjectRoleTemplateBindingInterface, l ProjectRoleTemplateBindingLifecycle) ProjectRoleTemplateBindingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ProjectRoleTemplateBindingGroupVersionResource) + } + adapter := &projectRoleTemplateBindingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ProjectRoleTemplateBinding) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_controller.go new file mode 100644 index 0000000..56a057f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RancherUserNotificationGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RancherUserNotification", + } + RancherUserNotificationResource = metav1.APIResource{ + Name: "rancherusernotifications", + SingularName: "rancherusernotification", + Namespaced: false, + Kind: RancherUserNotificationGroupVersionKind.Kind, + } + + RancherUserNotificationGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "rancherusernotifications", + } +) + +func init() { + resource.Put(RancherUserNotificationGroupVersionResource) +} + +// Deprecated: use v3.RancherUserNotification instead +type RancherUserNotification = v3.RancherUserNotification + +func NewRancherUserNotification(namespace, name string, obj v3.RancherUserNotification) *v3.RancherUserNotification { + obj.APIVersion, obj.Kind = RancherUserNotificationGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RancherUserNotificationHandlerFunc func(key string, obj *v3.RancherUserNotification) (runtime.Object, error) + +type RancherUserNotificationChangeHandlerFunc func(obj *v3.RancherUserNotification) (runtime.Object, error) + +type RancherUserNotificationLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.RancherUserNotification, err error) + Get(namespace, name string) (*v3.RancherUserNotification, error) +} + +type RancherUserNotificationController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RancherUserNotificationLister + AddHandler(ctx context.Context, name string, handler RancherUserNotificationHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RancherUserNotificationHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RancherUserNotificationHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RancherUserNotificationHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RancherUserNotificationInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.RancherUserNotification) (*v3.RancherUserNotification, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) + Get(name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) + Update(*v3.RancherUserNotification) (*v3.RancherUserNotification, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RancherUserNotificationController + AddHandler(ctx context.Context, name string, sync RancherUserNotificationHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RancherUserNotificationHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RancherUserNotificationLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RancherUserNotificationLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RancherUserNotificationHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RancherUserNotificationHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RancherUserNotificationLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RancherUserNotificationLifecycle) +} + +type rancherUserNotificationLister struct { + ns string + controller *rancherUserNotificationController +} + +func (l *rancherUserNotificationLister) List(namespace string, selector labels.Selector) (ret []*v3.RancherUserNotification, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.RancherUserNotification)) + }) + return +} + +func (l *rancherUserNotificationLister) Get(namespace, name string) (*v3.RancherUserNotification, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RancherUserNotificationGroupVersionKind.Group, + Resource: RancherUserNotificationGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.RancherUserNotification), nil +} + +type rancherUserNotificationController struct { + ns string + controller.GenericController +} + +func (c *rancherUserNotificationController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *rancherUserNotificationController) Lister() RancherUserNotificationLister { + return &rancherUserNotificationLister{ + ns: c.ns, + controller: c, + } +} + +func (c *rancherUserNotificationController) AddHandler(ctx context.Context, name string, handler RancherUserNotificationHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RancherUserNotification); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rancherUserNotificationController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RancherUserNotificationHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RancherUserNotification); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rancherUserNotificationController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RancherUserNotificationHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RancherUserNotification); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rancherUserNotificationController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RancherUserNotificationHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RancherUserNotification); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type rancherUserNotificationFactory struct { +} + +func (c rancherUserNotificationFactory) Object() runtime.Object { + return &v3.RancherUserNotification{} +} + +func (c rancherUserNotificationFactory) List() runtime.Object { + return &v3.RancherUserNotificationList{} +} + +func (s *rancherUserNotificationClient) Controller() RancherUserNotificationController { + genericController := controller.NewGenericController(s.ns, RancherUserNotificationGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RancherUserNotificationGroupVersionResource, RancherUserNotificationGroupVersionKind.Kind, false)) + + return &rancherUserNotificationController{ + ns: s.ns, + GenericController: genericController, + } +} + +type rancherUserNotificationClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RancherUserNotificationController +} + +func (s *rancherUserNotificationClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *rancherUserNotificationClient) Create(o *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) Get(name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) Update(o *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) UpdateStatus(o *v3.RancherUserNotification) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *rancherUserNotificationClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *rancherUserNotificationClient) List(opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.RancherUserNotificationList), err +} + +func (s *rancherUserNotificationClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RancherUserNotificationList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.RancherUserNotificationList), err +} + +func (s *rancherUserNotificationClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *rancherUserNotificationClient) Patch(o *v3.RancherUserNotification, patchType types.PatchType, data []byte, subresources ...string) (*v3.RancherUserNotification, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.RancherUserNotification), err +} + +func (s *rancherUserNotificationClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *rancherUserNotificationClient) AddHandler(ctx context.Context, name string, sync RancherUserNotificationHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rancherUserNotificationClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RancherUserNotificationHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rancherUserNotificationClient) AddLifecycle(ctx context.Context, name string, lifecycle RancherUserNotificationLifecycle) { + sync := NewRancherUserNotificationLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rancherUserNotificationClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RancherUserNotificationLifecycle) { + sync := NewRancherUserNotificationLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rancherUserNotificationClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RancherUserNotificationHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rancherUserNotificationClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RancherUserNotificationHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *rancherUserNotificationClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RancherUserNotificationLifecycle) { + sync := NewRancherUserNotificationLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rancherUserNotificationClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RancherUserNotificationLifecycle) { + sync := NewRancherUserNotificationLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_lifecycle_adapter.go new file mode 100644 index 0000000..a9b2b6c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rancher_user_notification_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type RancherUserNotificationLifecycle interface { + Create(obj *v3.RancherUserNotification) (runtime.Object, error) + Remove(obj *v3.RancherUserNotification) (runtime.Object, error) + Updated(obj *v3.RancherUserNotification) (runtime.Object, error) +} + +type rancherUserNotificationLifecycleAdapter struct { + lifecycle RancherUserNotificationLifecycle +} + +func (w *rancherUserNotificationLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *rancherUserNotificationLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *rancherUserNotificationLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.RancherUserNotification)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rancherUserNotificationLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.RancherUserNotification)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rancherUserNotificationLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.RancherUserNotification)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRancherUserNotificationLifecycleAdapter(name string, clusterScoped bool, client RancherUserNotificationInterface, l RancherUserNotificationLifecycle) RancherUserNotificationHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RancherUserNotificationGroupVersionResource) + } + adapter := &rancherUserNotificationLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.RancherUserNotification) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_controller.go new file mode 100644 index 0000000..ce1c1c4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RkeAddonGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RkeAddon", + } + RkeAddonResource = metav1.APIResource{ + Name: "rkeaddons", + SingularName: "rkeaddon", + Namespaced: true, + + Kind: RkeAddonGroupVersionKind.Kind, + } + + RkeAddonGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "rkeaddons", + } +) + +func init() { + resource.Put(RkeAddonGroupVersionResource) +} + +// Deprecated: use v3.RkeAddon instead +type RkeAddon = v3.RkeAddon + +func NewRkeAddon(namespace, name string, obj v3.RkeAddon) *v3.RkeAddon { + obj.APIVersion, obj.Kind = RkeAddonGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RkeAddonHandlerFunc func(key string, obj *v3.RkeAddon) (runtime.Object, error) + +type RkeAddonChangeHandlerFunc func(obj *v3.RkeAddon) (runtime.Object, error) + +type RkeAddonLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.RkeAddon, err error) + Get(namespace, name string) (*v3.RkeAddon, error) +} + +type RkeAddonController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RkeAddonLister + AddHandler(ctx context.Context, name string, handler RkeAddonHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeAddonHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RkeAddonHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RkeAddonHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RkeAddonInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.RkeAddon) (*v3.RkeAddon, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeAddon, error) + Get(name string, opts metav1.GetOptions) (*v3.RkeAddon, error) + Update(*v3.RkeAddon) (*v3.RkeAddon, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.RkeAddonList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeAddonList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RkeAddonController + AddHandler(ctx context.Context, name string, sync RkeAddonHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeAddonHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RkeAddonLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeAddonLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeAddonHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeAddonHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeAddonLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeAddonLifecycle) +} + +type rkeAddonLister struct { + ns string + controller *rkeAddonController +} + +func (l *rkeAddonLister) List(namespace string, selector labels.Selector) (ret []*v3.RkeAddon, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.RkeAddon)) + }) + return +} + +func (l *rkeAddonLister) Get(namespace, name string) (*v3.RkeAddon, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RkeAddonGroupVersionKind.Group, + Resource: RkeAddonGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.RkeAddon), nil +} + +type rkeAddonController struct { + ns string + controller.GenericController +} + +func (c *rkeAddonController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *rkeAddonController) Lister() RkeAddonLister { + return &rkeAddonLister{ + ns: c.ns, + controller: c, + } +} + +func (c *rkeAddonController) AddHandler(ctx context.Context, name string, handler RkeAddonHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeAddon); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeAddonController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RkeAddonHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeAddon); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeAddonController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RkeAddonHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeAddon); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeAddonController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RkeAddonHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeAddon); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type rkeAddonFactory struct { +} + +func (c rkeAddonFactory) Object() runtime.Object { + return &v3.RkeAddon{} +} + +func (c rkeAddonFactory) List() runtime.Object { + return &v3.RkeAddonList{} +} + +func (s *rkeAddonClient) Controller() RkeAddonController { + genericController := controller.NewGenericController(s.ns, RkeAddonGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RkeAddonGroupVersionResource, RkeAddonGroupVersionKind.Kind, true)) + + return &rkeAddonController{ + ns: s.ns, + GenericController: genericController, + } +} + +type rkeAddonClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RkeAddonController +} + +func (s *rkeAddonClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *rkeAddonClient) Create(o *v3.RkeAddon) (*v3.RkeAddon, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) Get(name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeAddon, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) Update(o *v3.RkeAddon) (*v3.RkeAddon, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) UpdateStatus(o *v3.RkeAddon) (*v3.RkeAddon, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *rkeAddonClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *rkeAddonClient) List(opts metav1.ListOptions) (*v3.RkeAddonList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.RkeAddonList), err +} + +func (s *rkeAddonClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeAddonList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.RkeAddonList), err +} + +func (s *rkeAddonClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *rkeAddonClient) Patch(o *v3.RkeAddon, patchType types.PatchType, data []byte, subresources ...string) (*v3.RkeAddon, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.RkeAddon), err +} + +func (s *rkeAddonClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *rkeAddonClient) AddHandler(ctx context.Context, name string, sync RkeAddonHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeAddonClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeAddonHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeAddonClient) AddLifecycle(ctx context.Context, name string, lifecycle RkeAddonLifecycle) { + sync := NewRkeAddonLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeAddonClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeAddonLifecycle) { + sync := NewRkeAddonLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeAddonClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeAddonHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeAddonClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeAddonHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *rkeAddonClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeAddonLifecycle) { + sync := NewRkeAddonLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeAddonClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeAddonLifecycle) { + sync := NewRkeAddonLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_lifecycle_adapter.go new file mode 100644 index 0000000..c7d1576 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_addon_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type RkeAddonLifecycle interface { + Create(obj *v3.RkeAddon) (runtime.Object, error) + Remove(obj *v3.RkeAddon) (runtime.Object, error) + Updated(obj *v3.RkeAddon) (runtime.Object, error) +} + +type rkeAddonLifecycleAdapter struct { + lifecycle RkeAddonLifecycle +} + +func (w *rkeAddonLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *rkeAddonLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *rkeAddonLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.RkeAddon)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeAddonLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.RkeAddon)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeAddonLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.RkeAddon)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRkeAddonLifecycleAdapter(name string, clusterScoped bool, client RkeAddonInterface, l RkeAddonLifecycle) RkeAddonHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RkeAddonGroupVersionResource) + } + adapter := &rkeAddonLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.RkeAddon) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_controller.go new file mode 100644 index 0000000..b5dda77 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RkeK8sServiceOptionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RkeK8sServiceOption", + } + RkeK8sServiceOptionResource = metav1.APIResource{ + Name: "rkek8sserviceoptions", + SingularName: "rkek8sserviceoption", + Namespaced: true, + + Kind: RkeK8sServiceOptionGroupVersionKind.Kind, + } + + RkeK8sServiceOptionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "rkek8sserviceoptions", + } +) + +func init() { + resource.Put(RkeK8sServiceOptionGroupVersionResource) +} + +// Deprecated: use v3.RkeK8sServiceOption instead +type RkeK8sServiceOption = v3.RkeK8sServiceOption + +func NewRkeK8sServiceOption(namespace, name string, obj v3.RkeK8sServiceOption) *v3.RkeK8sServiceOption { + obj.APIVersion, obj.Kind = RkeK8sServiceOptionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RkeK8sServiceOptionHandlerFunc func(key string, obj *v3.RkeK8sServiceOption) (runtime.Object, error) + +type RkeK8sServiceOptionChangeHandlerFunc func(obj *v3.RkeK8sServiceOption) (runtime.Object, error) + +type RkeK8sServiceOptionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.RkeK8sServiceOption, err error) + Get(namespace, name string) (*v3.RkeK8sServiceOption, error) +} + +type RkeK8sServiceOptionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RkeK8sServiceOptionLister + AddHandler(ctx context.Context, name string, handler RkeK8sServiceOptionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sServiceOptionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RkeK8sServiceOptionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RkeK8sServiceOptionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RkeK8sServiceOptionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) + Get(name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) + Update(*v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RkeK8sServiceOptionController + AddHandler(ctx context.Context, name string, sync RkeK8sServiceOptionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sServiceOptionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RkeK8sServiceOptionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeK8sServiceOptionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeK8sServiceOptionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeK8sServiceOptionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeK8sServiceOptionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeK8sServiceOptionLifecycle) +} + +type rkeK8sServiceOptionLister struct { + ns string + controller *rkeK8sServiceOptionController +} + +func (l *rkeK8sServiceOptionLister) List(namespace string, selector labels.Selector) (ret []*v3.RkeK8sServiceOption, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.RkeK8sServiceOption)) + }) + return +} + +func (l *rkeK8sServiceOptionLister) Get(namespace, name string) (*v3.RkeK8sServiceOption, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RkeK8sServiceOptionGroupVersionKind.Group, + Resource: RkeK8sServiceOptionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.RkeK8sServiceOption), nil +} + +type rkeK8sServiceOptionController struct { + ns string + controller.GenericController +} + +func (c *rkeK8sServiceOptionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *rkeK8sServiceOptionController) Lister() RkeK8sServiceOptionLister { + return &rkeK8sServiceOptionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *rkeK8sServiceOptionController) AddHandler(ctx context.Context, name string, handler RkeK8sServiceOptionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sServiceOption); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sServiceOptionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RkeK8sServiceOptionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sServiceOption); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sServiceOptionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RkeK8sServiceOptionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sServiceOption); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sServiceOptionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RkeK8sServiceOptionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sServiceOption); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type rkeK8sServiceOptionFactory struct { +} + +func (c rkeK8sServiceOptionFactory) Object() runtime.Object { + return &v3.RkeK8sServiceOption{} +} + +func (c rkeK8sServiceOptionFactory) List() runtime.Object { + return &v3.RkeK8sServiceOptionList{} +} + +func (s *rkeK8sServiceOptionClient) Controller() RkeK8sServiceOptionController { + genericController := controller.NewGenericController(s.ns, RkeK8sServiceOptionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RkeK8sServiceOptionGroupVersionResource, RkeK8sServiceOptionGroupVersionKind.Kind, true)) + + return &rkeK8sServiceOptionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type rkeK8sServiceOptionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RkeK8sServiceOptionController +} + +func (s *rkeK8sServiceOptionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *rkeK8sServiceOptionClient) Create(o *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) Get(name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) Update(o *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) UpdateStatus(o *v3.RkeK8sServiceOption) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *rkeK8sServiceOptionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *rkeK8sServiceOptionClient) List(opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.RkeK8sServiceOptionList), err +} + +func (s *rkeK8sServiceOptionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sServiceOptionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.RkeK8sServiceOptionList), err +} + +func (s *rkeK8sServiceOptionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *rkeK8sServiceOptionClient) Patch(o *v3.RkeK8sServiceOption, patchType types.PatchType, data []byte, subresources ...string) (*v3.RkeK8sServiceOption, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.RkeK8sServiceOption), err +} + +func (s *rkeK8sServiceOptionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *rkeK8sServiceOptionClient) AddHandler(ctx context.Context, name string, sync RkeK8sServiceOptionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeK8sServiceOptionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sServiceOptionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeK8sServiceOptionClient) AddLifecycle(ctx context.Context, name string, lifecycle RkeK8sServiceOptionLifecycle) { + sync := NewRkeK8sServiceOptionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeK8sServiceOptionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeK8sServiceOptionLifecycle) { + sync := NewRkeK8sServiceOptionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeK8sServiceOptionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeK8sServiceOptionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeK8sServiceOptionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeK8sServiceOptionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *rkeK8sServiceOptionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeK8sServiceOptionLifecycle) { + sync := NewRkeK8sServiceOptionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeK8sServiceOptionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeK8sServiceOptionLifecycle) { + sync := NewRkeK8sServiceOptionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_lifecycle_adapter.go new file mode 100644 index 0000000..964cf65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_service_option_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type RkeK8sServiceOptionLifecycle interface { + Create(obj *v3.RkeK8sServiceOption) (runtime.Object, error) + Remove(obj *v3.RkeK8sServiceOption) (runtime.Object, error) + Updated(obj *v3.RkeK8sServiceOption) (runtime.Object, error) +} + +type rkeK8sServiceOptionLifecycleAdapter struct { + lifecycle RkeK8sServiceOptionLifecycle +} + +func (w *rkeK8sServiceOptionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *rkeK8sServiceOptionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *rkeK8sServiceOptionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.RkeK8sServiceOption)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeK8sServiceOptionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.RkeK8sServiceOption)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeK8sServiceOptionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.RkeK8sServiceOption)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRkeK8sServiceOptionLifecycleAdapter(name string, clusterScoped bool, client RkeK8sServiceOptionInterface, l RkeK8sServiceOptionLifecycle) RkeK8sServiceOptionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RkeK8sServiceOptionGroupVersionResource) + } + adapter := &rkeK8sServiceOptionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.RkeK8sServiceOption) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_controller.go new file mode 100644 index 0000000..875ea23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RkeK8sSystemImageGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RkeK8sSystemImage", + } + RkeK8sSystemImageResource = metav1.APIResource{ + Name: "rkek8ssystemimages", + SingularName: "rkek8ssystemimage", + Namespaced: true, + + Kind: RkeK8sSystemImageGroupVersionKind.Kind, + } + + RkeK8sSystemImageGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "rkek8ssystemimages", + } +) + +func init() { + resource.Put(RkeK8sSystemImageGroupVersionResource) +} + +// Deprecated: use v3.RkeK8sSystemImage instead +type RkeK8sSystemImage = v3.RkeK8sSystemImage + +func NewRkeK8sSystemImage(namespace, name string, obj v3.RkeK8sSystemImage) *v3.RkeK8sSystemImage { + obj.APIVersion, obj.Kind = RkeK8sSystemImageGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RkeK8sSystemImageHandlerFunc func(key string, obj *v3.RkeK8sSystemImage) (runtime.Object, error) + +type RkeK8sSystemImageChangeHandlerFunc func(obj *v3.RkeK8sSystemImage) (runtime.Object, error) + +type RkeK8sSystemImageLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.RkeK8sSystemImage, err error) + Get(namespace, name string) (*v3.RkeK8sSystemImage, error) +} + +type RkeK8sSystemImageController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RkeK8sSystemImageLister + AddHandler(ctx context.Context, name string, handler RkeK8sSystemImageHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sSystemImageHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RkeK8sSystemImageHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RkeK8sSystemImageHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RkeK8sSystemImageInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) + Get(name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) + Update(*v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RkeK8sSystemImageController + AddHandler(ctx context.Context, name string, sync RkeK8sSystemImageHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sSystemImageHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RkeK8sSystemImageLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeK8sSystemImageLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeK8sSystemImageHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeK8sSystemImageHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeK8sSystemImageLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeK8sSystemImageLifecycle) +} + +type rkeK8sSystemImageLister struct { + ns string + controller *rkeK8sSystemImageController +} + +func (l *rkeK8sSystemImageLister) List(namespace string, selector labels.Selector) (ret []*v3.RkeK8sSystemImage, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.RkeK8sSystemImage)) + }) + return +} + +func (l *rkeK8sSystemImageLister) Get(namespace, name string) (*v3.RkeK8sSystemImage, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RkeK8sSystemImageGroupVersionKind.Group, + Resource: RkeK8sSystemImageGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.RkeK8sSystemImage), nil +} + +type rkeK8sSystemImageController struct { + ns string + controller.GenericController +} + +func (c *rkeK8sSystemImageController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *rkeK8sSystemImageController) Lister() RkeK8sSystemImageLister { + return &rkeK8sSystemImageLister{ + ns: c.ns, + controller: c, + } +} + +func (c *rkeK8sSystemImageController) AddHandler(ctx context.Context, name string, handler RkeK8sSystemImageHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sSystemImage); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sSystemImageController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RkeK8sSystemImageHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sSystemImage); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sSystemImageController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RkeK8sSystemImageHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sSystemImage); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *rkeK8sSystemImageController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RkeK8sSystemImageHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RkeK8sSystemImage); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type rkeK8sSystemImageFactory struct { +} + +func (c rkeK8sSystemImageFactory) Object() runtime.Object { + return &v3.RkeK8sSystemImage{} +} + +func (c rkeK8sSystemImageFactory) List() runtime.Object { + return &v3.RkeK8sSystemImageList{} +} + +func (s *rkeK8sSystemImageClient) Controller() RkeK8sSystemImageController { + genericController := controller.NewGenericController(s.ns, RkeK8sSystemImageGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RkeK8sSystemImageGroupVersionResource, RkeK8sSystemImageGroupVersionKind.Kind, true)) + + return &rkeK8sSystemImageController{ + ns: s.ns, + GenericController: genericController, + } +} + +type rkeK8sSystemImageClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RkeK8sSystemImageController +} + +func (s *rkeK8sSystemImageClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *rkeK8sSystemImageClient) Create(o *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) Get(name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) Update(o *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) UpdateStatus(o *v3.RkeK8sSystemImage) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *rkeK8sSystemImageClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *rkeK8sSystemImageClient) List(opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.RkeK8sSystemImageList), err +} + +func (s *rkeK8sSystemImageClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RkeK8sSystemImageList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.RkeK8sSystemImageList), err +} + +func (s *rkeK8sSystemImageClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *rkeK8sSystemImageClient) Patch(o *v3.RkeK8sSystemImage, patchType types.PatchType, data []byte, subresources ...string) (*v3.RkeK8sSystemImage, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.RkeK8sSystemImage), err +} + +func (s *rkeK8sSystemImageClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *rkeK8sSystemImageClient) AddHandler(ctx context.Context, name string, sync RkeK8sSystemImageHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeK8sSystemImageClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RkeK8sSystemImageHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeK8sSystemImageClient) AddLifecycle(ctx context.Context, name string, lifecycle RkeK8sSystemImageLifecycle) { + sync := NewRkeK8sSystemImageLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *rkeK8sSystemImageClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RkeK8sSystemImageLifecycle) { + sync := NewRkeK8sSystemImageLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *rkeK8sSystemImageClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RkeK8sSystemImageHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeK8sSystemImageClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RkeK8sSystemImageHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *rkeK8sSystemImageClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RkeK8sSystemImageLifecycle) { + sync := NewRkeK8sSystemImageLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *rkeK8sSystemImageClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RkeK8sSystemImageLifecycle) { + sync := NewRkeK8sSystemImageLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_lifecycle_adapter.go new file mode 100644 index 0000000..8d4610e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_rke_k8s_system_image_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type RkeK8sSystemImageLifecycle interface { + Create(obj *v3.RkeK8sSystemImage) (runtime.Object, error) + Remove(obj *v3.RkeK8sSystemImage) (runtime.Object, error) + Updated(obj *v3.RkeK8sSystemImage) (runtime.Object, error) +} + +type rkeK8sSystemImageLifecycleAdapter struct { + lifecycle RkeK8sSystemImageLifecycle +} + +func (w *rkeK8sSystemImageLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *rkeK8sSystemImageLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *rkeK8sSystemImageLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.RkeK8sSystemImage)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeK8sSystemImageLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.RkeK8sSystemImage)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *rkeK8sSystemImageLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.RkeK8sSystemImage)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRkeK8sSystemImageLifecycleAdapter(name string, clusterScoped bool, client RkeK8sSystemImageInterface, l RkeK8sSystemImageLifecycle) RkeK8sSystemImageHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RkeK8sSystemImageGroupVersionResource) + } + adapter := &rkeK8sSystemImageLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.RkeK8sSystemImage) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_controller.go new file mode 100644 index 0000000..178463a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RoleTemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RoleTemplate", + } + RoleTemplateResource = metav1.APIResource{ + Name: "roletemplates", + SingularName: "roletemplate", + Namespaced: false, + Kind: RoleTemplateGroupVersionKind.Kind, + } + + RoleTemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "roletemplates", + } +) + +func init() { + resource.Put(RoleTemplateGroupVersionResource) +} + +// Deprecated: use v3.RoleTemplate instead +type RoleTemplate = v3.RoleTemplate + +func NewRoleTemplate(namespace, name string, obj v3.RoleTemplate) *v3.RoleTemplate { + obj.APIVersion, obj.Kind = RoleTemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RoleTemplateHandlerFunc func(key string, obj *v3.RoleTemplate) (runtime.Object, error) + +type RoleTemplateChangeHandlerFunc func(obj *v3.RoleTemplate) (runtime.Object, error) + +type RoleTemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.RoleTemplate, err error) + Get(namespace, name string) (*v3.RoleTemplate, error) +} + +type RoleTemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RoleTemplateLister + AddHandler(ctx context.Context, name string, handler RoleTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleTemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RoleTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RoleTemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RoleTemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.RoleTemplate) (*v3.RoleTemplate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) + Get(name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) + Update(*v3.RoleTemplate) (*v3.RoleTemplate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.RoleTemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RoleTemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RoleTemplateController + AddHandler(ctx context.Context, name string, sync RoleTemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleTemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RoleTemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleTemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleTemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleTemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleTemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleTemplateLifecycle) +} + +type roleTemplateLister struct { + ns string + controller *roleTemplateController +} + +func (l *roleTemplateLister) List(namespace string, selector labels.Selector) (ret []*v3.RoleTemplate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.RoleTemplate)) + }) + return +} + +func (l *roleTemplateLister) Get(namespace, name string) (*v3.RoleTemplate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RoleTemplateGroupVersionKind.Group, + Resource: RoleTemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.RoleTemplate), nil +} + +type roleTemplateController struct { + ns string + controller.GenericController +} + +func (c *roleTemplateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *roleTemplateController) Lister() RoleTemplateLister { + return &roleTemplateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *roleTemplateController) AddHandler(ctx context.Context, name string, handler RoleTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RoleTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleTemplateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RoleTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RoleTemplate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleTemplateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RoleTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RoleTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleTemplateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RoleTemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.RoleTemplate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type roleTemplateFactory struct { +} + +func (c roleTemplateFactory) Object() runtime.Object { + return &v3.RoleTemplate{} +} + +func (c roleTemplateFactory) List() runtime.Object { + return &v3.RoleTemplateList{} +} + +func (s *roleTemplateClient) Controller() RoleTemplateController { + genericController := controller.NewGenericController(s.ns, RoleTemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RoleTemplateGroupVersionResource, RoleTemplateGroupVersionKind.Kind, false)) + + return &roleTemplateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type roleTemplateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RoleTemplateController +} + +func (s *roleTemplateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *roleTemplateClient) Create(o *v3.RoleTemplate) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) Get(name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) Update(o *v3.RoleTemplate) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) UpdateStatus(o *v3.RoleTemplate) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *roleTemplateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *roleTemplateClient) List(opts metav1.ListOptions) (*v3.RoleTemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.RoleTemplateList), err +} + +func (s *roleTemplateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.RoleTemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.RoleTemplateList), err +} + +func (s *roleTemplateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *roleTemplateClient) Patch(o *v3.RoleTemplate, patchType types.PatchType, data []byte, subresources ...string) (*v3.RoleTemplate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.RoleTemplate), err +} + +func (s *roleTemplateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *roleTemplateClient) AddHandler(ctx context.Context, name string, sync RoleTemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleTemplateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleTemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleTemplateClient) AddLifecycle(ctx context.Context, name string, lifecycle RoleTemplateLifecycle) { + sync := NewRoleTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleTemplateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleTemplateLifecycle) { + sync := NewRoleTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleTemplateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleTemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleTemplateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleTemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *roleTemplateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleTemplateLifecycle) { + sync := NewRoleTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleTemplateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleTemplateLifecycle) { + sync := NewRoleTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_lifecycle_adapter.go new file mode 100644 index 0000000..79e12bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_role_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type RoleTemplateLifecycle interface { + Create(obj *v3.RoleTemplate) (runtime.Object, error) + Remove(obj *v3.RoleTemplate) (runtime.Object, error) + Updated(obj *v3.RoleTemplate) (runtime.Object, error) +} + +type roleTemplateLifecycleAdapter struct { + lifecycle RoleTemplateLifecycle +} + +func (w *roleTemplateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *roleTemplateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *roleTemplateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.RoleTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleTemplateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.RoleTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleTemplateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.RoleTemplate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRoleTemplateLifecycleAdapter(name string, clusterScoped bool, client RoleTemplateInterface, l RoleTemplateLifecycle) RoleTemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RoleTemplateGroupVersionResource) + } + adapter := &roleTemplateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.RoleTemplate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_controller.go new file mode 100644 index 0000000..db7652f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + SamlTokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "SamlToken", + } + SamlTokenResource = metav1.APIResource{ + Name: "samltokens", + SingularName: "samltoken", + Namespaced: true, + + Kind: SamlTokenGroupVersionKind.Kind, + } + + SamlTokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "samltokens", + } +) + +func init() { + resource.Put(SamlTokenGroupVersionResource) +} + +// Deprecated: use v3.SamlToken instead +type SamlToken = v3.SamlToken + +func NewSamlToken(namespace, name string, obj v3.SamlToken) *v3.SamlToken { + obj.APIVersion, obj.Kind = SamlTokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type SamlTokenHandlerFunc func(key string, obj *v3.SamlToken) (runtime.Object, error) + +type SamlTokenChangeHandlerFunc func(obj *v3.SamlToken) (runtime.Object, error) + +type SamlTokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.SamlToken, err error) + Get(namespace, name string) (*v3.SamlToken, error) +} + +type SamlTokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() SamlTokenLister + AddHandler(ctx context.Context, name string, handler SamlTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SamlTokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler SamlTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler SamlTokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type SamlTokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.SamlToken) (*v3.SamlToken, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.SamlToken, error) + Get(name string, opts metav1.GetOptions) (*v3.SamlToken, error) + Update(*v3.SamlToken) (*v3.SamlToken, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.SamlTokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SamlTokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() SamlTokenController + AddHandler(ctx context.Context, name string, sync SamlTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SamlTokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle SamlTokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SamlTokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SamlTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SamlTokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SamlTokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SamlTokenLifecycle) +} + +type samlTokenLister struct { + ns string + controller *samlTokenController +} + +func (l *samlTokenLister) List(namespace string, selector labels.Selector) (ret []*v3.SamlToken, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.SamlToken)) + }) + return +} + +func (l *samlTokenLister) Get(namespace, name string) (*v3.SamlToken, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: SamlTokenGroupVersionKind.Group, + Resource: SamlTokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.SamlToken), nil +} + +type samlTokenController struct { + ns string + controller.GenericController +} + +func (c *samlTokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *samlTokenController) Lister() SamlTokenLister { + return &samlTokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *samlTokenController) AddHandler(ctx context.Context, name string, handler SamlTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SamlToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *samlTokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler SamlTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SamlToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *samlTokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler SamlTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SamlToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *samlTokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler SamlTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SamlToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type samlTokenFactory struct { +} + +func (c samlTokenFactory) Object() runtime.Object { + return &v3.SamlToken{} +} + +func (c samlTokenFactory) List() runtime.Object { + return &v3.SamlTokenList{} +} + +func (s *samlTokenClient) Controller() SamlTokenController { + genericController := controller.NewGenericController(s.ns, SamlTokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(SamlTokenGroupVersionResource, SamlTokenGroupVersionKind.Kind, true)) + + return &samlTokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type samlTokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller SamlTokenController +} + +func (s *samlTokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *samlTokenClient) Create(o *v3.SamlToken) (*v3.SamlToken, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) Get(name string, opts metav1.GetOptions) (*v3.SamlToken, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.SamlToken, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) Update(o *v3.SamlToken) (*v3.SamlToken, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) UpdateStatus(o *v3.SamlToken) (*v3.SamlToken, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *samlTokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *samlTokenClient) List(opts metav1.ListOptions) (*v3.SamlTokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.SamlTokenList), err +} + +func (s *samlTokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SamlTokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.SamlTokenList), err +} + +func (s *samlTokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *samlTokenClient) Patch(o *v3.SamlToken, patchType types.PatchType, data []byte, subresources ...string) (*v3.SamlToken, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.SamlToken), err +} + +func (s *samlTokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *samlTokenClient) AddHandler(ctx context.Context, name string, sync SamlTokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *samlTokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SamlTokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *samlTokenClient) AddLifecycle(ctx context.Context, name string, lifecycle SamlTokenLifecycle) { + sync := NewSamlTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *samlTokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SamlTokenLifecycle) { + sync := NewSamlTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *samlTokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SamlTokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *samlTokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SamlTokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *samlTokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SamlTokenLifecycle) { + sync := NewSamlTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *samlTokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SamlTokenLifecycle) { + sync := NewSamlTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_lifecycle_adapter.go new file mode 100644 index 0000000..756f741 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_saml_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type SamlTokenLifecycle interface { + Create(obj *v3.SamlToken) (runtime.Object, error) + Remove(obj *v3.SamlToken) (runtime.Object, error) + Updated(obj *v3.SamlToken) (runtime.Object, error) +} + +type samlTokenLifecycleAdapter struct { + lifecycle SamlTokenLifecycle +} + +func (w *samlTokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *samlTokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *samlTokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.SamlToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *samlTokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.SamlToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *samlTokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.SamlToken)) + if o == nil { + return nil, err + } + return o, err +} + +func NewSamlTokenLifecycleAdapter(name string, clusterScoped bool, client SamlTokenInterface, l SamlTokenLifecycle) SamlTokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(SamlTokenGroupVersionResource) + } + adapter := &samlTokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.SamlToken) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_scheme.go new file mode 100644 index 0000000..517a15d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "management.cattle.io" + Version = "v3" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_controller.go new file mode 100644 index 0000000..c5968c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + SettingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Setting", + } + SettingResource = metav1.APIResource{ + Name: "settings", + SingularName: "setting", + Namespaced: false, + Kind: SettingGroupVersionKind.Kind, + } + + SettingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "settings", + } +) + +func init() { + resource.Put(SettingGroupVersionResource) +} + +// Deprecated: use v3.Setting instead +type Setting = v3.Setting + +func NewSetting(namespace, name string, obj v3.Setting) *v3.Setting { + obj.APIVersion, obj.Kind = SettingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type SettingHandlerFunc func(key string, obj *v3.Setting) (runtime.Object, error) + +type SettingChangeHandlerFunc func(obj *v3.Setting) (runtime.Object, error) + +type SettingLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Setting, err error) + Get(namespace, name string) (*v3.Setting, error) +} + +type SettingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() SettingLister + AddHandler(ctx context.Context, name string, handler SettingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SettingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler SettingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler SettingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type SettingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Setting) (*v3.Setting, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Setting, error) + Get(name string, opts metav1.GetOptions) (*v3.Setting, error) + Update(*v3.Setting) (*v3.Setting, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.SettingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SettingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() SettingController + AddHandler(ctx context.Context, name string, sync SettingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SettingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle SettingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SettingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SettingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SettingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SettingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SettingLifecycle) +} + +type settingLister struct { + ns string + controller *settingController +} + +func (l *settingLister) List(namespace string, selector labels.Selector) (ret []*v3.Setting, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Setting)) + }) + return +} + +func (l *settingLister) Get(namespace, name string) (*v3.Setting, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: SettingGroupVersionKind.Group, + Resource: SettingGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Setting), nil +} + +type settingController struct { + ns string + controller.GenericController +} + +func (c *settingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *settingController) Lister() SettingLister { + return &settingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *settingController) AddHandler(ctx context.Context, name string, handler SettingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Setting); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *settingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler SettingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Setting); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *settingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler SettingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Setting); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *settingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler SettingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Setting); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type settingFactory struct { +} + +func (c settingFactory) Object() runtime.Object { + return &v3.Setting{} +} + +func (c settingFactory) List() runtime.Object { + return &v3.SettingList{} +} + +func (s *settingClient) Controller() SettingController { + genericController := controller.NewGenericController(s.ns, SettingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(SettingGroupVersionResource, SettingGroupVersionKind.Kind, false)) + + return &settingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type settingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller SettingController +} + +func (s *settingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *settingClient) Create(o *v3.Setting) (*v3.Setting, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Setting), err +} + +func (s *settingClient) Get(name string, opts metav1.GetOptions) (*v3.Setting, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Setting), err +} + +func (s *settingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Setting, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Setting), err +} + +func (s *settingClient) Update(o *v3.Setting) (*v3.Setting, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Setting), err +} + +func (s *settingClient) UpdateStatus(o *v3.Setting) (*v3.Setting, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Setting), err +} + +func (s *settingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *settingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *settingClient) List(opts metav1.ListOptions) (*v3.SettingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.SettingList), err +} + +func (s *settingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SettingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.SettingList), err +} + +func (s *settingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *settingClient) Patch(o *v3.Setting, patchType types.PatchType, data []byte, subresources ...string) (*v3.Setting, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Setting), err +} + +func (s *settingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *settingClient) AddHandler(ctx context.Context, name string, sync SettingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *settingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SettingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *settingClient) AddLifecycle(ctx context.Context, name string, lifecycle SettingLifecycle) { + sync := NewSettingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *settingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SettingLifecycle) { + sync := NewSettingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *settingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SettingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *settingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SettingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *settingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SettingLifecycle) { + sync := NewSettingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *settingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SettingLifecycle) { + sync := NewSettingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_lifecycle_adapter.go new file mode 100644 index 0000000..60a8465 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_setting_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type SettingLifecycle interface { + Create(obj *v3.Setting) (runtime.Object, error) + Remove(obj *v3.Setting) (runtime.Object, error) + Updated(obj *v3.Setting) (runtime.Object, error) +} + +type settingLifecycleAdapter struct { + lifecycle SettingLifecycle +} + +func (w *settingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *settingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *settingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Setting)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *settingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Setting)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *settingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Setting)) + if o == nil { + return nil, err + } + return o, err +} + +func NewSettingLifecycleAdapter(name string, clusterScoped bool, client SettingInterface, l SettingLifecycle) SettingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(SettingGroupVersionResource) + } + adapter := &settingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Setting) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_controller.go new file mode 100644 index 0000000..1fc1f6f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + TemplateContentGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "TemplateContent", + } + TemplateContentResource = metav1.APIResource{ + Name: "templatecontents", + SingularName: "templatecontent", + Namespaced: false, + Kind: TemplateContentGroupVersionKind.Kind, + } + + TemplateContentGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "templatecontents", + } +) + +func init() { + resource.Put(TemplateContentGroupVersionResource) +} + +// Deprecated: use v3.TemplateContent instead +type TemplateContent = v3.TemplateContent + +func NewTemplateContent(namespace, name string, obj v3.TemplateContent) *v3.TemplateContent { + obj.APIVersion, obj.Kind = TemplateContentGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type TemplateContentHandlerFunc func(key string, obj *v3.TemplateContent) (runtime.Object, error) + +type TemplateContentChangeHandlerFunc func(obj *v3.TemplateContent) (runtime.Object, error) + +type TemplateContentLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.TemplateContent, err error) + Get(namespace, name string) (*v3.TemplateContent, error) +} + +type TemplateContentController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() TemplateContentLister + AddHandler(ctx context.Context, name string, handler TemplateContentHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateContentHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler TemplateContentHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler TemplateContentHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type TemplateContentInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.TemplateContent) (*v3.TemplateContent, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.TemplateContent, error) + Get(name string, opts metav1.GetOptions) (*v3.TemplateContent, error) + Update(*v3.TemplateContent) (*v3.TemplateContent, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.TemplateContentList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateContentList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() TemplateContentController + AddHandler(ctx context.Context, name string, sync TemplateContentHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateContentHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle TemplateContentLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateContentLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateContentHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateContentHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateContentLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateContentLifecycle) +} + +type templateContentLister struct { + ns string + controller *templateContentController +} + +func (l *templateContentLister) List(namespace string, selector labels.Selector) (ret []*v3.TemplateContent, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.TemplateContent)) + }) + return +} + +func (l *templateContentLister) Get(namespace, name string) (*v3.TemplateContent, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: TemplateContentGroupVersionKind.Group, + Resource: TemplateContentGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.TemplateContent), nil +} + +type templateContentController struct { + ns string + controller.GenericController +} + +func (c *templateContentController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *templateContentController) Lister() TemplateContentLister { + return &templateContentLister{ + ns: c.ns, + controller: c, + } +} + +func (c *templateContentController) AddHandler(ctx context.Context, name string, handler TemplateContentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateContent); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateContentController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler TemplateContentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateContent); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateContentController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler TemplateContentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateContent); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateContentController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler TemplateContentHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateContent); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type templateContentFactory struct { +} + +func (c templateContentFactory) Object() runtime.Object { + return &v3.TemplateContent{} +} + +func (c templateContentFactory) List() runtime.Object { + return &v3.TemplateContentList{} +} + +func (s *templateContentClient) Controller() TemplateContentController { + genericController := controller.NewGenericController(s.ns, TemplateContentGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(TemplateContentGroupVersionResource, TemplateContentGroupVersionKind.Kind, false)) + + return &templateContentController{ + ns: s.ns, + GenericController: genericController, + } +} + +type templateContentClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller TemplateContentController +} + +func (s *templateContentClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *templateContentClient) Create(o *v3.TemplateContent) (*v3.TemplateContent, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) Get(name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.TemplateContent, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) Update(o *v3.TemplateContent) (*v3.TemplateContent, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) UpdateStatus(o *v3.TemplateContent) (*v3.TemplateContent, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *templateContentClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *templateContentClient) List(opts metav1.ListOptions) (*v3.TemplateContentList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.TemplateContentList), err +} + +func (s *templateContentClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateContentList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.TemplateContentList), err +} + +func (s *templateContentClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *templateContentClient) Patch(o *v3.TemplateContent, patchType types.PatchType, data []byte, subresources ...string) (*v3.TemplateContent, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.TemplateContent), err +} + +func (s *templateContentClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *templateContentClient) AddHandler(ctx context.Context, name string, sync TemplateContentHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateContentClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateContentHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateContentClient) AddLifecycle(ctx context.Context, name string, lifecycle TemplateContentLifecycle) { + sync := NewTemplateContentLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateContentClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateContentLifecycle) { + sync := NewTemplateContentLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateContentClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateContentHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateContentClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateContentHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *templateContentClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateContentLifecycle) { + sync := NewTemplateContentLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateContentClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateContentLifecycle) { + sync := NewTemplateContentLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_lifecycle_adapter.go new file mode 100644 index 0000000..e5c563f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_content_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type TemplateContentLifecycle interface { + Create(obj *v3.TemplateContent) (runtime.Object, error) + Remove(obj *v3.TemplateContent) (runtime.Object, error) + Updated(obj *v3.TemplateContent) (runtime.Object, error) +} + +type templateContentLifecycleAdapter struct { + lifecycle TemplateContentLifecycle +} + +func (w *templateContentLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *templateContentLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *templateContentLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.TemplateContent)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateContentLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.TemplateContent)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateContentLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.TemplateContent)) + if o == nil { + return nil, err + } + return o, err +} + +func NewTemplateContentLifecycleAdapter(name string, clusterScoped bool, client TemplateContentInterface, l TemplateContentLifecycle) TemplateContentHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(TemplateContentGroupVersionResource) + } + adapter := &templateContentLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.TemplateContent) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_controller.go new file mode 100644 index 0000000..164d778 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + TemplateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Template", + } + TemplateResource = metav1.APIResource{ + Name: "templates", + SingularName: "template", + Namespaced: false, + Kind: TemplateGroupVersionKind.Kind, + } + + TemplateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "templates", + } +) + +func init() { + resource.Put(TemplateGroupVersionResource) +} + +// Deprecated: use v3.Template instead +type Template = v3.Template + +func NewTemplate(namespace, name string, obj v3.Template) *v3.Template { + obj.APIVersion, obj.Kind = TemplateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type TemplateHandlerFunc func(key string, obj *v3.Template) (runtime.Object, error) + +type TemplateChangeHandlerFunc func(obj *v3.Template) (runtime.Object, error) + +type TemplateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Template, err error) + Get(namespace, name string) (*v3.Template, error) +} + +type TemplateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() TemplateLister + AddHandler(ctx context.Context, name string, handler TemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler TemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler TemplateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type TemplateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Template) (*v3.Template, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Template, error) + Get(name string, opts metav1.GetOptions) (*v3.Template, error) + Update(*v3.Template) (*v3.Template, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.TemplateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() TemplateController + AddHandler(ctx context.Context, name string, sync TemplateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle TemplateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateLifecycle) +} + +type templateLister struct { + ns string + controller *templateController +} + +func (l *templateLister) List(namespace string, selector labels.Selector) (ret []*v3.Template, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Template)) + }) + return +} + +func (l *templateLister) Get(namespace, name string) (*v3.Template, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: TemplateGroupVersionKind.Group, + Resource: TemplateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Template), nil +} + +type templateController struct { + ns string + controller.GenericController +} + +func (c *templateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *templateController) Lister() TemplateLister { + return &templateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *templateController) AddHandler(ctx context.Context, name string, handler TemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Template); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler TemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Template); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler TemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Template); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler TemplateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Template); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type templateFactory struct { +} + +func (c templateFactory) Object() runtime.Object { + return &v3.Template{} +} + +func (c templateFactory) List() runtime.Object { + return &v3.TemplateList{} +} + +func (s *templateClient) Controller() TemplateController { + genericController := controller.NewGenericController(s.ns, TemplateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(TemplateGroupVersionResource, TemplateGroupVersionKind.Kind, false)) + + return &templateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type templateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller TemplateController +} + +func (s *templateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *templateClient) Create(o *v3.Template) (*v3.Template, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Template), err +} + +func (s *templateClient) Get(name string, opts metav1.GetOptions) (*v3.Template, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Template), err +} + +func (s *templateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Template, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Template), err +} + +func (s *templateClient) Update(o *v3.Template) (*v3.Template, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Template), err +} + +func (s *templateClient) UpdateStatus(o *v3.Template) (*v3.Template, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Template), err +} + +func (s *templateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *templateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *templateClient) List(opts metav1.ListOptions) (*v3.TemplateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.TemplateList), err +} + +func (s *templateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.TemplateList), err +} + +func (s *templateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *templateClient) Patch(o *v3.Template, patchType types.PatchType, data []byte, subresources ...string) (*v3.Template, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Template), err +} + +func (s *templateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *templateClient) AddHandler(ctx context.Context, name string, sync TemplateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateClient) AddLifecycle(ctx context.Context, name string, lifecycle TemplateLifecycle) { + sync := NewTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateLifecycle) { + sync := NewTemplateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *templateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateLifecycle) { + sync := NewTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateLifecycle) { + sync := NewTemplateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_lifecycle_adapter.go new file mode 100644 index 0000000..557a3e5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type TemplateLifecycle interface { + Create(obj *v3.Template) (runtime.Object, error) + Remove(obj *v3.Template) (runtime.Object, error) + Updated(obj *v3.Template) (runtime.Object, error) +} + +type templateLifecycleAdapter struct { + lifecycle TemplateLifecycle +} + +func (w *templateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *templateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *templateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Template)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Template)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Template)) + if o == nil { + return nil, err + } + return o, err +} + +func NewTemplateLifecycleAdapter(name string, clusterScoped bool, client TemplateInterface, l TemplateLifecycle) TemplateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(TemplateGroupVersionResource) + } + adapter := &templateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Template) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_controller.go new file mode 100644 index 0000000..d818e3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + TemplateVersionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "TemplateVersion", + } + TemplateVersionResource = metav1.APIResource{ + Name: "templateversions", + SingularName: "templateversion", + Namespaced: false, + Kind: TemplateVersionGroupVersionKind.Kind, + } + + TemplateVersionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "templateversions", + } +) + +func init() { + resource.Put(TemplateVersionGroupVersionResource) +} + +// Deprecated: use v3.TemplateVersion instead +type TemplateVersion = v3.TemplateVersion + +func NewTemplateVersion(namespace, name string, obj v3.TemplateVersion) *v3.TemplateVersion { + obj.APIVersion, obj.Kind = TemplateVersionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type TemplateVersionHandlerFunc func(key string, obj *v3.TemplateVersion) (runtime.Object, error) + +type TemplateVersionChangeHandlerFunc func(obj *v3.TemplateVersion) (runtime.Object, error) + +type TemplateVersionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.TemplateVersion, err error) + Get(namespace, name string) (*v3.TemplateVersion, error) +} + +type TemplateVersionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() TemplateVersionLister + AddHandler(ctx context.Context, name string, handler TemplateVersionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateVersionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler TemplateVersionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler TemplateVersionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type TemplateVersionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.TemplateVersion) (*v3.TemplateVersion, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) + Get(name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) + Update(*v3.TemplateVersion) (*v3.TemplateVersion, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.TemplateVersionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateVersionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() TemplateVersionController + AddHandler(ctx context.Context, name string, sync TemplateVersionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateVersionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle TemplateVersionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateVersionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateVersionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateVersionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateVersionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateVersionLifecycle) +} + +type templateVersionLister struct { + ns string + controller *templateVersionController +} + +func (l *templateVersionLister) List(namespace string, selector labels.Selector) (ret []*v3.TemplateVersion, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.TemplateVersion)) + }) + return +} + +func (l *templateVersionLister) Get(namespace, name string) (*v3.TemplateVersion, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: TemplateVersionGroupVersionKind.Group, + Resource: TemplateVersionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.TemplateVersion), nil +} + +type templateVersionController struct { + ns string + controller.GenericController +} + +func (c *templateVersionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *templateVersionController) Lister() TemplateVersionLister { + return &templateVersionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *templateVersionController) AddHandler(ctx context.Context, name string, handler TemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateVersion); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateVersionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler TemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateVersion); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateVersionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler TemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateVersion); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *templateVersionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler TemplateVersionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.TemplateVersion); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type templateVersionFactory struct { +} + +func (c templateVersionFactory) Object() runtime.Object { + return &v3.TemplateVersion{} +} + +func (c templateVersionFactory) List() runtime.Object { + return &v3.TemplateVersionList{} +} + +func (s *templateVersionClient) Controller() TemplateVersionController { + genericController := controller.NewGenericController(s.ns, TemplateVersionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(TemplateVersionGroupVersionResource, TemplateVersionGroupVersionKind.Kind, false)) + + return &templateVersionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type templateVersionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller TemplateVersionController +} + +func (s *templateVersionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *templateVersionClient) Create(o *v3.TemplateVersion) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) Get(name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) Update(o *v3.TemplateVersion) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) UpdateStatus(o *v3.TemplateVersion) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *templateVersionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *templateVersionClient) List(opts metav1.ListOptions) (*v3.TemplateVersionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.TemplateVersionList), err +} + +func (s *templateVersionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TemplateVersionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.TemplateVersionList), err +} + +func (s *templateVersionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *templateVersionClient) Patch(o *v3.TemplateVersion, patchType types.PatchType, data []byte, subresources ...string) (*v3.TemplateVersion, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.TemplateVersion), err +} + +func (s *templateVersionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *templateVersionClient) AddHandler(ctx context.Context, name string, sync TemplateVersionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateVersionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TemplateVersionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateVersionClient) AddLifecycle(ctx context.Context, name string, lifecycle TemplateVersionLifecycle) { + sync := NewTemplateVersionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *templateVersionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TemplateVersionLifecycle) { + sync := NewTemplateVersionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *templateVersionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TemplateVersionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateVersionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TemplateVersionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *templateVersionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TemplateVersionLifecycle) { + sync := NewTemplateVersionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *templateVersionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TemplateVersionLifecycle) { + sync := NewTemplateVersionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_lifecycle_adapter.go new file mode 100644 index 0000000..1bffaf2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_template_version_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type TemplateVersionLifecycle interface { + Create(obj *v3.TemplateVersion) (runtime.Object, error) + Remove(obj *v3.TemplateVersion) (runtime.Object, error) + Updated(obj *v3.TemplateVersion) (runtime.Object, error) +} + +type templateVersionLifecycleAdapter struct { + lifecycle TemplateVersionLifecycle +} + +func (w *templateVersionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *templateVersionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *templateVersionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.TemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateVersionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.TemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *templateVersionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.TemplateVersion)) + if o == nil { + return nil, err + } + return o, err +} + +func NewTemplateVersionLifecycleAdapter(name string, clusterScoped bool, client TemplateVersionInterface, l TemplateVersionLifecycle) TemplateVersionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(TemplateVersionGroupVersionResource) + } + adapter := &templateVersionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.TemplateVersion) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_controller.go new file mode 100644 index 0000000..9797b09 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + TokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Token", + } + TokenResource = metav1.APIResource{ + Name: "tokens", + SingularName: "token", + Namespaced: false, + Kind: TokenGroupVersionKind.Kind, + } + + TokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "tokens", + } +) + +func init() { + resource.Put(TokenGroupVersionResource) +} + +// Deprecated: use v3.Token instead +type Token = v3.Token + +func NewToken(namespace, name string, obj v3.Token) *v3.Token { + obj.APIVersion, obj.Kind = TokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type TokenHandlerFunc func(key string, obj *v3.Token) (runtime.Object, error) + +type TokenChangeHandlerFunc func(obj *v3.Token) (runtime.Object, error) + +type TokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Token, err error) + Get(namespace, name string) (*v3.Token, error) +} + +type TokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() TokenLister + AddHandler(ctx context.Context, name string, handler TokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler TokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler TokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type TokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Token) (*v3.Token, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Token, error) + Get(name string, opts metav1.GetOptions) (*v3.Token, error) + Update(*v3.Token) (*v3.Token, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.TokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() TokenController + AddHandler(ctx context.Context, name string, sync TokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle TokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TokenLifecycle) +} + +type tokenLister struct { + ns string + controller *tokenController +} + +func (l *tokenLister) List(namespace string, selector labels.Selector) (ret []*v3.Token, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Token)) + }) + return +} + +func (l *tokenLister) Get(namespace, name string) (*v3.Token, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: TokenGroupVersionKind.Group, + Resource: TokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Token), nil +} + +type tokenController struct { + ns string + controller.GenericController +} + +func (c *tokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *tokenController) Lister() TokenLister { + return &tokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *tokenController) AddHandler(ctx context.Context, name string, handler TokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Token); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *tokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler TokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Token); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *tokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler TokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Token); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *tokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler TokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Token); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type tokenFactory struct { +} + +func (c tokenFactory) Object() runtime.Object { + return &v3.Token{} +} + +func (c tokenFactory) List() runtime.Object { + return &v3.TokenList{} +} + +func (s *tokenClient) Controller() TokenController { + genericController := controller.NewGenericController(s.ns, TokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(TokenGroupVersionResource, TokenGroupVersionKind.Kind, false)) + + return &tokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type tokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller TokenController +} + +func (s *tokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *tokenClient) Create(o *v3.Token) (*v3.Token, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Token), err +} + +func (s *tokenClient) Get(name string, opts metav1.GetOptions) (*v3.Token, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Token), err +} + +func (s *tokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Token, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Token), err +} + +func (s *tokenClient) Update(o *v3.Token) (*v3.Token, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Token), err +} + +func (s *tokenClient) UpdateStatus(o *v3.Token) (*v3.Token, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Token), err +} + +func (s *tokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *tokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *tokenClient) List(opts metav1.ListOptions) (*v3.TokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.TokenList), err +} + +func (s *tokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.TokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.TokenList), err +} + +func (s *tokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *tokenClient) Patch(o *v3.Token, patchType types.PatchType, data []byte, subresources ...string) (*v3.Token, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Token), err +} + +func (s *tokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *tokenClient) AddHandler(ctx context.Context, name string, sync TokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *tokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync TokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *tokenClient) AddLifecycle(ctx context.Context, name string, lifecycle TokenLifecycle) { + sync := NewTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *tokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle TokenLifecycle) { + sync := NewTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *tokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync TokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *tokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync TokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *tokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle TokenLifecycle) { + sync := NewTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *tokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle TokenLifecycle) { + sync := NewTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_lifecycle_adapter.go new file mode 100644 index 0000000..9adaf0b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type TokenLifecycle interface { + Create(obj *v3.Token) (runtime.Object, error) + Remove(obj *v3.Token) (runtime.Object, error) + Updated(obj *v3.Token) (runtime.Object, error) +} + +type tokenLifecycleAdapter struct { + lifecycle TokenLifecycle +} + +func (w *tokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *tokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *tokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Token)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *tokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Token)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *tokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Token)) + if o == nil { + return nil, err + } + return o, err +} + +func NewTokenLifecycleAdapter(name string, clusterScoped bool, client TokenInterface, l TokenLifecycle) TokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(TokenGroupVersionResource) + } + adapter := &tokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Token) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_controller.go new file mode 100644 index 0000000..52bc0d0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + UserAttributeGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "UserAttribute", + } + UserAttributeResource = metav1.APIResource{ + Name: "userattributes", + SingularName: "userattribute", + Namespaced: false, + Kind: UserAttributeGroupVersionKind.Kind, + } + + UserAttributeGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "userattributes", + } +) + +func init() { + resource.Put(UserAttributeGroupVersionResource) +} + +// Deprecated: use v3.UserAttribute instead +type UserAttribute = v3.UserAttribute + +func NewUserAttribute(namespace, name string, obj v3.UserAttribute) *v3.UserAttribute { + obj.APIVersion, obj.Kind = UserAttributeGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type UserAttributeHandlerFunc func(key string, obj *v3.UserAttribute) (runtime.Object, error) + +type UserAttributeChangeHandlerFunc func(obj *v3.UserAttribute) (runtime.Object, error) + +type UserAttributeLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.UserAttribute, err error) + Get(namespace, name string) (*v3.UserAttribute, error) +} + +type UserAttributeController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() UserAttributeLister + AddHandler(ctx context.Context, name string, handler UserAttributeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserAttributeHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler UserAttributeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler UserAttributeHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type UserAttributeInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.UserAttribute) (*v3.UserAttribute, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.UserAttribute, error) + Get(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) + Update(*v3.UserAttribute) (*v3.UserAttribute, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.UserAttributeList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserAttributeList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() UserAttributeController + AddHandler(ctx context.Context, name string, sync UserAttributeHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserAttributeHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle UserAttributeLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle UserAttributeLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync UserAttributeHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync UserAttributeHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle UserAttributeLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle UserAttributeLifecycle) +} + +type userAttributeLister struct { + ns string + controller *userAttributeController +} + +func (l *userAttributeLister) List(namespace string, selector labels.Selector) (ret []*v3.UserAttribute, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.UserAttribute)) + }) + return +} + +func (l *userAttributeLister) Get(namespace, name string) (*v3.UserAttribute, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: UserAttributeGroupVersionKind.Group, + Resource: UserAttributeGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.UserAttribute), nil +} + +type userAttributeController struct { + ns string + controller.GenericController +} + +func (c *userAttributeController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *userAttributeController) Lister() UserAttributeLister { + return &userAttributeLister{ + ns: c.ns, + controller: c, + } +} + +func (c *userAttributeController) AddHandler(ctx context.Context, name string, handler UserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.UserAttribute); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userAttributeController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler UserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.UserAttribute); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userAttributeController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler UserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.UserAttribute); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userAttributeController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler UserAttributeHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.UserAttribute); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type userAttributeFactory struct { +} + +func (c userAttributeFactory) Object() runtime.Object { + return &v3.UserAttribute{} +} + +func (c userAttributeFactory) List() runtime.Object { + return &v3.UserAttributeList{} +} + +func (s *userAttributeClient) Controller() UserAttributeController { + genericController := controller.NewGenericController(s.ns, UserAttributeGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(UserAttributeGroupVersionResource, UserAttributeGroupVersionKind.Kind, false)) + + return &userAttributeController{ + ns: s.ns, + GenericController: genericController, + } +} + +type userAttributeClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller UserAttributeController +} + +func (s *userAttributeClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *userAttributeClient) Create(o *v3.UserAttribute) (*v3.UserAttribute, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) Get(name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.UserAttribute, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) Update(o *v3.UserAttribute) (*v3.UserAttribute, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) UpdateStatus(o *v3.UserAttribute) (*v3.UserAttribute, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *userAttributeClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *userAttributeClient) List(opts metav1.ListOptions) (*v3.UserAttributeList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.UserAttributeList), err +} + +func (s *userAttributeClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserAttributeList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.UserAttributeList), err +} + +func (s *userAttributeClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *userAttributeClient) Patch(o *v3.UserAttribute, patchType types.PatchType, data []byte, subresources ...string) (*v3.UserAttribute, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.UserAttribute), err +} + +func (s *userAttributeClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *userAttributeClient) AddHandler(ctx context.Context, name string, sync UserAttributeHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *userAttributeClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserAttributeHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *userAttributeClient) AddLifecycle(ctx context.Context, name string, lifecycle UserAttributeLifecycle) { + sync := NewUserAttributeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *userAttributeClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle UserAttributeLifecycle) { + sync := NewUserAttributeLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *userAttributeClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync UserAttributeHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *userAttributeClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync UserAttributeHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *userAttributeClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle UserAttributeLifecycle) { + sync := NewUserAttributeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *userAttributeClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle UserAttributeLifecycle) { + sync := NewUserAttributeLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_lifecycle_adapter.go new file mode 100644 index 0000000..121e558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_attribute_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type UserAttributeLifecycle interface { + Create(obj *v3.UserAttribute) (runtime.Object, error) + Remove(obj *v3.UserAttribute) (runtime.Object, error) + Updated(obj *v3.UserAttribute) (runtime.Object, error) +} + +type userAttributeLifecycleAdapter struct { + lifecycle UserAttributeLifecycle +} + +func (w *userAttributeLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *userAttributeLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *userAttributeLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.UserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *userAttributeLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.UserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *userAttributeLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.UserAttribute)) + if o == nil { + return nil, err + } + return o, err +} + +func NewUserAttributeLifecycleAdapter(name string, clusterScoped bool, client UserAttributeInterface, l UserAttributeLifecycle) UserAttributeHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(UserAttributeGroupVersionResource) + } + adapter := &userAttributeLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.UserAttribute) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_controller.go new file mode 100644 index 0000000..c62ca00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_controller.go @@ -0,0 +1,325 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + UserGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "User", + } + UserResource = metav1.APIResource{ + Name: "users", + SingularName: "user", + Namespaced: false, + Kind: UserGroupVersionKind.Kind, + } + + UserGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "users", + } +) + +func init() { + resource.Put(UserGroupVersionResource) +} + +// Deprecated: use v3.User instead +type User = v3.User + +func NewUser(namespace, name string, obj v3.User) *v3.User { + obj.APIVersion, obj.Kind = UserGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type UserHandlerFunc func(key string, obj *v3.User) (runtime.Object, error) + +type UserChangeHandlerFunc func(obj *v3.User) (runtime.Object, error) + +type UserLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.User, err error) + Get(namespace, name string) (*v3.User, error) +} + +type UserController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() UserLister + AddHandler(ctx context.Context, name string, handler UserHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler UserHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler UserHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type UserInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.User) (*v3.User, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.User, error) + Get(name string, opts metav1.GetOptions) (*v3.User, error) + Update(*v3.User) (*v3.User, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.UserList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() UserController + AddHandler(ctx context.Context, name string, sync UserHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle UserLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle UserLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync UserHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync UserHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle UserLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle UserLifecycle) +} + +type userLister struct { + ns string + controller *userController +} + +func (l *userLister) List(namespace string, selector labels.Selector) (ret []*v3.User, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.User)) + }) + return +} + +func (l *userLister) Get(namespace, name string) (*v3.User, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: UserGroupVersionKind.Group, + Resource: UserGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.User), nil +} + +type userController struct { + ns string + controller.GenericController +} + +func (c *userController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *userController) Lister() UserLister { + return &userLister{ + ns: c.ns, + controller: c, + } +} + +func (c *userController) AddHandler(ctx context.Context, name string, handler UserHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.User); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler UserHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.User); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler UserHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.User); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *userController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler UserHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.User); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type userFactory struct { +} + +func (c userFactory) Object() runtime.Object { + return &v3.User{} +} + +func (c userFactory) List() runtime.Object { + return &v3.UserList{} +} + +func (s *userClient) Controller() UserController { + genericController := controller.NewGenericController(s.ns, UserGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(UserGroupVersionResource, UserGroupVersionKind.Kind, false)) + + return &userController{ + ns: s.ns, + GenericController: genericController, + } +} + +type userClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller UserController +} + +func (s *userClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *userClient) Create(o *v3.User) (*v3.User, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.User), err +} + +func (s *userClient) Get(name string, opts metav1.GetOptions) (*v3.User, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.User), err +} + +func (s *userClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.User, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.User), err +} + +func (s *userClient) Update(o *v3.User) (*v3.User, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.User), err +} + +func (s *userClient) UpdateStatus(o *v3.User) (*v3.User, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.User), err +} + +func (s *userClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *userClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *userClient) List(opts metav1.ListOptions) (*v3.UserList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.UserList), err +} + +func (s *userClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.UserList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.UserList), err +} + +func (s *userClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *userClient) Patch(o *v3.User, patchType types.PatchType, data []byte, subresources ...string) (*v3.User, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.User), err +} + +func (s *userClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *userClient) AddHandler(ctx context.Context, name string, sync UserHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *userClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync UserHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *userClient) AddLifecycle(ctx context.Context, name string, lifecycle UserLifecycle) { + sync := NewUserLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *userClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle UserLifecycle) { + sync := NewUserLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *userClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync UserHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *userClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync UserHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *userClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle UserLifecycle) { + sync := NewUserLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *userClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle UserLifecycle) { + sync := NewUserLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_lifecycle_adapter.go new file mode 100644 index 0000000..1e68c74 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/management.cattle.io/v3/zz_generated_user_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type UserLifecycle interface { + Create(obj *v3.User) (runtime.Object, error) + Remove(obj *v3.User) (runtime.Object, error) + Updated(obj *v3.User) (runtime.Object, error) +} + +type userLifecycleAdapter struct { + lifecycle UserLifecycle +} + +func (w *userLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *userLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *userLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.User)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *userLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.User)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *userLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.User)) + if o == nil { + return nil, err + } + return o, err +} + +func NewUserLifecycleAdapter(name string, clusterScoped bool, client UserInterface, l UserLifecycle) UserHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(UserGroupVersionResource) + } + adapter := &userLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.User) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_ingress_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_ingress_mock.go new file mode 100644 index 0000000..f5972e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_ingress_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + v1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockIngressListerMockGet sync.RWMutex + lockIngressListerMockList sync.RWMutex +) + +// Ensure, that IngressListerMock does implement v11.IngressLister. +// If this is not the case, regenerate this file with moq. +var _ v11.IngressLister = &IngressListerMock{} + +// IngressListerMock is a mock implementation of v11.IngressLister. +// +// func TestSomethingThatUsesIngressLister(t *testing.T) { +// +// // make and configure a mocked v11.IngressLister +// mockedIngressLister := &IngressListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Ingress, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Ingress, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedIngressLister in code that requires v11.IngressLister +// // and then make assertions. +// +// } +type IngressListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Ingress, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Ingress, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *IngressListerMock) Get(namespace string, name string) (*v1.Ingress, error) { + if mock.GetFunc == nil { + panic("IngressListerMock.GetFunc: method is nil but IngressLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockIngressListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockIngressListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedIngressLister.GetCalls()) +func (mock *IngressListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockIngressListerMockGet.RLock() + calls = mock.calls.Get + lockIngressListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *IngressListerMock) List(namespace string, selector labels.Selector) ([]*v1.Ingress, error) { + if mock.ListFunc == nil { + panic("IngressListerMock.ListFunc: method is nil but IngressLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockIngressListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockIngressListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedIngressLister.ListCalls()) +func (mock *IngressListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockIngressListerMockList.RLock() + calls = mock.calls.List + lockIngressListerMockList.RUnlock() + return calls +} + +var ( + lockIngressControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockIngressControllerMockAddClusterScopedHandler sync.RWMutex + lockIngressControllerMockAddFeatureHandler sync.RWMutex + lockIngressControllerMockAddHandler sync.RWMutex + lockIngressControllerMockEnqueue sync.RWMutex + lockIngressControllerMockEnqueueAfter sync.RWMutex + lockIngressControllerMockGeneric sync.RWMutex + lockIngressControllerMockInformer sync.RWMutex + lockIngressControllerMockLister sync.RWMutex +) + +// Ensure, that IngressControllerMock does implement v11.IngressController. +// If this is not the case, regenerate this file with moq. +var _ v11.IngressController = &IngressControllerMock{} + +// IngressControllerMock is a mock implementation of v11.IngressController. +// +// func TestSomethingThatUsesIngressController(t *testing.T) { +// +// // make and configure a mocked v11.IngressController +// mockedIngressController := &IngressControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.IngressHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.IngressLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedIngressController in code that requires v11.IngressController +// // and then make assertions. +// +// } +type IngressControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.IngressHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.IngressHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.IngressHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.IngressLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.IngressHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.IngressHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.IngressHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.IngressHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *IngressControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.IngressHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("IngressControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but IngressController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockIngressControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockIngressControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedIngressController.AddClusterScopedFeatureHandlerCalls()) +func (mock *IngressControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.IngressHandlerFunc + } + lockIngressControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockIngressControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *IngressControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.IngressHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("IngressControllerMock.AddClusterScopedHandlerFunc: method is nil but IngressController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockIngressControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockIngressControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedIngressController.AddClusterScopedHandlerCalls()) +func (mock *IngressControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.IngressHandlerFunc + } + lockIngressControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockIngressControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *IngressControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("IngressControllerMock.AddFeatureHandlerFunc: method is nil but IngressController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockIngressControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockIngressControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedIngressController.AddFeatureHandlerCalls()) +func (mock *IngressControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc + } + lockIngressControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockIngressControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *IngressControllerMock) AddHandler(ctx context.Context, name string, handler v11.IngressHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("IngressControllerMock.AddHandlerFunc: method is nil but IngressController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockIngressControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockIngressControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedIngressController.AddHandlerCalls()) +func (mock *IngressControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.IngressHandlerFunc + } + lockIngressControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockIngressControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *IngressControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("IngressControllerMock.EnqueueFunc: method is nil but IngressController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockIngressControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockIngressControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedIngressController.EnqueueCalls()) +func (mock *IngressControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockIngressControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockIngressControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *IngressControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("IngressControllerMock.EnqueueAfterFunc: method is nil but IngressController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockIngressControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockIngressControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedIngressController.EnqueueAfterCalls()) +func (mock *IngressControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockIngressControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockIngressControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *IngressControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("IngressControllerMock.GenericFunc: method is nil but IngressController.Generic was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockIngressControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedIngressController.GenericCalls()) +func (mock *IngressControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockIngressControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *IngressControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("IngressControllerMock.InformerFunc: method is nil but IngressController.Informer was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockIngressControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedIngressController.InformerCalls()) +func (mock *IngressControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockInformer.RLock() + calls = mock.calls.Informer + lockIngressControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *IngressControllerMock) Lister() v11.IngressLister { + if mock.ListerFunc == nil { + panic("IngressControllerMock.ListerFunc: method is nil but IngressController.Lister was just called") + } + callInfo := struct { + }{} + lockIngressControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockIngressControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedIngressController.ListerCalls()) +func (mock *IngressControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockIngressControllerMockLister.RLock() + calls = mock.calls.Lister + lockIngressControllerMockLister.RUnlock() + return calls +} + +var ( + lockIngressInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockIngressInterfaceMockAddClusterScopedHandler sync.RWMutex + lockIngressInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockIngressInterfaceMockAddFeatureHandler sync.RWMutex + lockIngressInterfaceMockAddFeatureLifecycle sync.RWMutex + lockIngressInterfaceMockAddHandler sync.RWMutex + lockIngressInterfaceMockAddLifecycle sync.RWMutex + lockIngressInterfaceMockController sync.RWMutex + lockIngressInterfaceMockCreate sync.RWMutex + lockIngressInterfaceMockDelete sync.RWMutex + lockIngressInterfaceMockDeleteCollection sync.RWMutex + lockIngressInterfaceMockDeleteNamespaced sync.RWMutex + lockIngressInterfaceMockGet sync.RWMutex + lockIngressInterfaceMockGetNamespaced sync.RWMutex + lockIngressInterfaceMockList sync.RWMutex + lockIngressInterfaceMockListNamespaced sync.RWMutex + lockIngressInterfaceMockObjectClient sync.RWMutex + lockIngressInterfaceMockUpdate sync.RWMutex + lockIngressInterfaceMockWatch sync.RWMutex +) + +// Ensure, that IngressInterfaceMock does implement v11.IngressInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.IngressInterface = &IngressInterfaceMock{} + +// IngressInterfaceMock is a mock implementation of v11.IngressInterface. +// +// func TestSomethingThatUsesIngressInterface(t *testing.T) { +// +// // make and configure a mocked v11.IngressInterface +// mockedIngressInterface := &IngressInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.IngressLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.IngressLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.IngressLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.IngressHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.IngressLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.IngressController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Ingress) (*v1.Ingress, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Ingress, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Ingress, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.IngressList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.IngressList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Ingress) (*v1.Ingress, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedIngressInterface in code that requires v11.IngressInterface +// // and then make assertions. +// +// } +type IngressInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.IngressLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.IngressLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.IngressLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.IngressHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.IngressLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.IngressController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Ingress) (*v1.Ingress, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Ingress, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Ingress, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.IngressList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.IngressList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Ingress) (*v1.Ingress, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.IngressHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.IngressLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.IngressHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.IngressLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.IngressHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.IngressLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.IngressHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.IngressLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Ingress + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Ingress + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *IngressInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but IngressInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockIngressInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.IngressHandlerFunc + } + lockIngressInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockIngressInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *IngressInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.IngressLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but IngressInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.IngressLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.IngressLifecycle + } + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockIngressInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *IngressInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.IngressHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedHandlerFunc: method is nil but IngressInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockIngressInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedHandlerCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.IngressHandlerFunc + } + lockIngressInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockIngressInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *IngressInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.IngressLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("IngressInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but IngressInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.IngressLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockIngressInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddClusterScopedLifecycleCalls()) +func (mock *IngressInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.IngressLifecycle + } + lockIngressInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockIngressInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *IngressInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.IngressHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("IngressInterfaceMock.AddFeatureHandlerFunc: method is nil but IngressInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockIngressInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddFeatureHandlerCalls()) +func (mock *IngressInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.IngressHandlerFunc + } + lockIngressInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockIngressInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *IngressInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.IngressLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("IngressInterfaceMock.AddFeatureLifecycleFunc: method is nil but IngressInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.IngressLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockIngressInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddFeatureLifecycleCalls()) +func (mock *IngressInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.IngressLifecycle + } + lockIngressInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockIngressInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *IngressInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.IngressHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("IngressInterfaceMock.AddHandlerFunc: method is nil but IngressInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.IngressHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockIngressInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockIngressInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedIngressInterface.AddHandlerCalls()) +func (mock *IngressInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.IngressHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.IngressHandlerFunc + } + lockIngressInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockIngressInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *IngressInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.IngressLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("IngressInterfaceMock.AddLifecycleFunc: method is nil but IngressInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.IngressLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockIngressInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockIngressInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedIngressInterface.AddLifecycleCalls()) +func (mock *IngressInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.IngressLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.IngressLifecycle + } + lockIngressInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockIngressInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *IngressInterfaceMock) Controller() v11.IngressController { + if mock.ControllerFunc == nil { + panic("IngressInterfaceMock.ControllerFunc: method is nil but IngressInterface.Controller was just called") + } + callInfo := struct { + }{} + lockIngressInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockIngressInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedIngressInterface.ControllerCalls()) +func (mock *IngressInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockIngressInterfaceMockController.RLock() + calls = mock.calls.Controller + lockIngressInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *IngressInterfaceMock) Create(in1 *v1.Ingress) (*v1.Ingress, error) { + if mock.CreateFunc == nil { + panic("IngressInterfaceMock.CreateFunc: method is nil but IngressInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Ingress + }{ + In1: in1, + } + lockIngressInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockIngressInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedIngressInterface.CreateCalls()) +func (mock *IngressInterfaceMock) CreateCalls() []struct { + In1 *v1.Ingress +} { + var calls []struct { + In1 *v1.Ingress + } + lockIngressInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockIngressInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *IngressInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("IngressInterfaceMock.DeleteFunc: method is nil but IngressInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockIngressInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockIngressInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedIngressInterface.DeleteCalls()) +func (mock *IngressInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockIngressInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockIngressInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *IngressInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("IngressInterfaceMock.DeleteCollectionFunc: method is nil but IngressInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockIngressInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockIngressInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedIngressInterface.DeleteCollectionCalls()) +func (mock *IngressInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockIngressInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockIngressInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *IngressInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("IngressInterfaceMock.DeleteNamespacedFunc: method is nil but IngressInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockIngressInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockIngressInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.DeleteNamespacedCalls()) +func (mock *IngressInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockIngressInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockIngressInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *IngressInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Ingress, error) { + if mock.GetFunc == nil { + panic("IngressInterfaceMock.GetFunc: method is nil but IngressInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockIngressInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockIngressInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedIngressInterface.GetCalls()) +func (mock *IngressInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockIngressInterfaceMockGet.RLock() + calls = mock.calls.Get + lockIngressInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *IngressInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Ingress, error) { + if mock.GetNamespacedFunc == nil { + panic("IngressInterfaceMock.GetNamespacedFunc: method is nil but IngressInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockIngressInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockIngressInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.GetNamespacedCalls()) +func (mock *IngressInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockIngressInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockIngressInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *IngressInterfaceMock) List(opts metav1.ListOptions) (*v1.IngressList, error) { + if mock.ListFunc == nil { + panic("IngressInterfaceMock.ListFunc: method is nil but IngressInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockIngressInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockIngressInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedIngressInterface.ListCalls()) +func (mock *IngressInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockIngressInterfaceMockList.RLock() + calls = mock.calls.List + lockIngressInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *IngressInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.IngressList, error) { + if mock.ListNamespacedFunc == nil { + panic("IngressInterfaceMock.ListNamespacedFunc: method is nil but IngressInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockIngressInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockIngressInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedIngressInterface.ListNamespacedCalls()) +func (mock *IngressInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockIngressInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockIngressInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *IngressInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("IngressInterfaceMock.ObjectClientFunc: method is nil but IngressInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockIngressInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockIngressInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedIngressInterface.ObjectClientCalls()) +func (mock *IngressInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockIngressInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockIngressInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *IngressInterfaceMock) Update(in1 *v1.Ingress) (*v1.Ingress, error) { + if mock.UpdateFunc == nil { + panic("IngressInterfaceMock.UpdateFunc: method is nil but IngressInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Ingress + }{ + In1: in1, + } + lockIngressInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockIngressInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedIngressInterface.UpdateCalls()) +func (mock *IngressInterfaceMock) UpdateCalls() []struct { + In1 *v1.Ingress +} { + var calls []struct { + In1 *v1.Ingress + } + lockIngressInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockIngressInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *IngressInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("IngressInterfaceMock.WatchFunc: method is nil but IngressInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockIngressInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockIngressInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedIngressInterface.WatchCalls()) +func (mock *IngressInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockIngressInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockIngressInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockIngressesGetterMockIngresses sync.RWMutex +) + +// Ensure, that IngressesGetterMock does implement v11.IngressesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.IngressesGetter = &IngressesGetterMock{} + +// IngressesGetterMock is a mock implementation of v11.IngressesGetter. +// +// func TestSomethingThatUsesIngressesGetter(t *testing.T) { +// +// // make and configure a mocked v11.IngressesGetter +// mockedIngressesGetter := &IngressesGetterMock{ +// IngressesFunc: func(namespace string) v11.IngressInterface { +// panic("mock out the Ingresses method") +// }, +// } +// +// // use mockedIngressesGetter in code that requires v11.IngressesGetter +// // and then make assertions. +// +// } +type IngressesGetterMock struct { + // IngressesFunc mocks the Ingresses method. + IngressesFunc func(namespace string) v11.IngressInterface + + // calls tracks calls to the methods. + calls struct { + // Ingresses holds details about calls to the Ingresses method. + Ingresses []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Ingresses calls IngressesFunc. +func (mock *IngressesGetterMock) Ingresses(namespace string) v11.IngressInterface { + if mock.IngressesFunc == nil { + panic("IngressesGetterMock.IngressesFunc: method is nil but IngressesGetter.Ingresses was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockIngressesGetterMockIngresses.Lock() + mock.calls.Ingresses = append(mock.calls.Ingresses, callInfo) + lockIngressesGetterMockIngresses.Unlock() + return mock.IngressesFunc(namespace) +} + +// IngressesCalls gets all the calls that were made to Ingresses. +// Check the length with: +// +// len(mockedIngressesGetter.IngressesCalls()) +func (mock *IngressesGetterMock) IngressesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockIngressesGetterMockIngresses.RLock() + calls = mock.calls.Ingresses + lockIngressesGetterMockIngresses.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_network_policy_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_network_policy_mock.go new file mode 100644 index 0000000..1e3d010 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/fakes/zz_generated_network_policy_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + v1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNetworkPolicyListerMockGet sync.RWMutex + lockNetworkPolicyListerMockList sync.RWMutex +) + +// Ensure, that NetworkPolicyListerMock does implement v11.NetworkPolicyLister. +// If this is not the case, regenerate this file with moq. +var _ v11.NetworkPolicyLister = &NetworkPolicyListerMock{} + +// NetworkPolicyListerMock is a mock implementation of v11.NetworkPolicyLister. +// +// func TestSomethingThatUsesNetworkPolicyLister(t *testing.T) { +// +// // make and configure a mocked v11.NetworkPolicyLister +// mockedNetworkPolicyLister := &NetworkPolicyListerMock{ +// GetFunc: func(namespace string, name string) (*v1.NetworkPolicy, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.NetworkPolicy, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNetworkPolicyLister in code that requires v11.NetworkPolicyLister +// // and then make assertions. +// +// } +type NetworkPolicyListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.NetworkPolicy, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.NetworkPolicy, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NetworkPolicyListerMock) Get(namespace string, name string) (*v1.NetworkPolicy, error) { + if mock.GetFunc == nil { + panic("NetworkPolicyListerMock.GetFunc: method is nil but NetworkPolicyLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNetworkPolicyListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNetworkPolicyListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNetworkPolicyLister.GetCalls()) +func (mock *NetworkPolicyListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNetworkPolicyListerMockGet.RLock() + calls = mock.calls.Get + lockNetworkPolicyListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NetworkPolicyListerMock) List(namespace string, selector labels.Selector) ([]*v1.NetworkPolicy, error) { + if mock.ListFunc == nil { + panic("NetworkPolicyListerMock.ListFunc: method is nil but NetworkPolicyLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNetworkPolicyListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNetworkPolicyListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNetworkPolicyLister.ListCalls()) +func (mock *NetworkPolicyListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNetworkPolicyListerMockList.RLock() + calls = mock.calls.List + lockNetworkPolicyListerMockList.RUnlock() + return calls +} + +var ( + lockNetworkPolicyControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNetworkPolicyControllerMockAddClusterScopedHandler sync.RWMutex + lockNetworkPolicyControllerMockAddFeatureHandler sync.RWMutex + lockNetworkPolicyControllerMockAddHandler sync.RWMutex + lockNetworkPolicyControllerMockEnqueue sync.RWMutex + lockNetworkPolicyControllerMockEnqueueAfter sync.RWMutex + lockNetworkPolicyControllerMockGeneric sync.RWMutex + lockNetworkPolicyControllerMockInformer sync.RWMutex + lockNetworkPolicyControllerMockLister sync.RWMutex +) + +// Ensure, that NetworkPolicyControllerMock does implement v11.NetworkPolicyController. +// If this is not the case, regenerate this file with moq. +var _ v11.NetworkPolicyController = &NetworkPolicyControllerMock{} + +// NetworkPolicyControllerMock is a mock implementation of v11.NetworkPolicyController. +// +// func TestSomethingThatUsesNetworkPolicyController(t *testing.T) { +// +// // make and configure a mocked v11.NetworkPolicyController +// mockedNetworkPolicyController := &NetworkPolicyControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.NetworkPolicyLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNetworkPolicyController in code that requires v11.NetworkPolicyController +// // and then make assertions. +// +// } +type NetworkPolicyControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.NetworkPolicyHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.NetworkPolicyLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NetworkPolicyHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.NetworkPolicyHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NetworkPolicyHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.NetworkPolicyHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NetworkPolicyControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NetworkPolicyControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NetworkPolicyController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNetworkPolicyControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNetworkPolicyControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNetworkPolicyController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NetworkPolicyControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNetworkPolicyControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NetworkPolicyControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.NetworkPolicyHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NetworkPolicyControllerMock.AddClusterScopedHandlerFunc: method is nil but NetworkPolicyController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNetworkPolicyControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNetworkPolicyControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNetworkPolicyController.AddClusterScopedHandlerCalls()) +func (mock *NetworkPolicyControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNetworkPolicyControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NetworkPolicyControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NetworkPolicyControllerMock.AddFeatureHandlerFunc: method is nil but NetworkPolicyController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNetworkPolicyControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNetworkPolicyControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNetworkPolicyController.AddFeatureHandlerCalls()) +func (mock *NetworkPolicyControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNetworkPolicyControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NetworkPolicyControllerMock) AddHandler(ctx context.Context, name string, handler v11.NetworkPolicyHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NetworkPolicyControllerMock.AddHandlerFunc: method is nil but NetworkPolicyController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNetworkPolicyControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNetworkPolicyControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNetworkPolicyController.AddHandlerCalls()) +func (mock *NetworkPolicyControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNetworkPolicyControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NetworkPolicyControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NetworkPolicyControllerMock.EnqueueFunc: method is nil but NetworkPolicyController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNetworkPolicyControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNetworkPolicyControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNetworkPolicyController.EnqueueCalls()) +func (mock *NetworkPolicyControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNetworkPolicyControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNetworkPolicyControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NetworkPolicyControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NetworkPolicyControllerMock.EnqueueAfterFunc: method is nil but NetworkPolicyController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNetworkPolicyControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNetworkPolicyControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNetworkPolicyController.EnqueueAfterCalls()) +func (mock *NetworkPolicyControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNetworkPolicyControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNetworkPolicyControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NetworkPolicyControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NetworkPolicyControllerMock.GenericFunc: method is nil but NetworkPolicyController.Generic was just called") + } + callInfo := struct { + }{} + lockNetworkPolicyControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNetworkPolicyControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNetworkPolicyController.GenericCalls()) +func (mock *NetworkPolicyControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNetworkPolicyControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNetworkPolicyControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NetworkPolicyControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NetworkPolicyControllerMock.InformerFunc: method is nil but NetworkPolicyController.Informer was just called") + } + callInfo := struct { + }{} + lockNetworkPolicyControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNetworkPolicyControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNetworkPolicyController.InformerCalls()) +func (mock *NetworkPolicyControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNetworkPolicyControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNetworkPolicyControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NetworkPolicyControllerMock) Lister() v11.NetworkPolicyLister { + if mock.ListerFunc == nil { + panic("NetworkPolicyControllerMock.ListerFunc: method is nil but NetworkPolicyController.Lister was just called") + } + callInfo := struct { + }{} + lockNetworkPolicyControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNetworkPolicyControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNetworkPolicyController.ListerCalls()) +func (mock *NetworkPolicyControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNetworkPolicyControllerMockLister.RLock() + calls = mock.calls.Lister + lockNetworkPolicyControllerMockLister.RUnlock() + return calls +} + +var ( + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNetworkPolicyInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNetworkPolicyInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNetworkPolicyInterfaceMockAddFeatureHandler sync.RWMutex + lockNetworkPolicyInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNetworkPolicyInterfaceMockAddHandler sync.RWMutex + lockNetworkPolicyInterfaceMockAddLifecycle sync.RWMutex + lockNetworkPolicyInterfaceMockController sync.RWMutex + lockNetworkPolicyInterfaceMockCreate sync.RWMutex + lockNetworkPolicyInterfaceMockDelete sync.RWMutex + lockNetworkPolicyInterfaceMockDeleteCollection sync.RWMutex + lockNetworkPolicyInterfaceMockDeleteNamespaced sync.RWMutex + lockNetworkPolicyInterfaceMockGet sync.RWMutex + lockNetworkPolicyInterfaceMockGetNamespaced sync.RWMutex + lockNetworkPolicyInterfaceMockList sync.RWMutex + lockNetworkPolicyInterfaceMockListNamespaced sync.RWMutex + lockNetworkPolicyInterfaceMockObjectClient sync.RWMutex + lockNetworkPolicyInterfaceMockUpdate sync.RWMutex + lockNetworkPolicyInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NetworkPolicyInterfaceMock does implement v11.NetworkPolicyInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.NetworkPolicyInterface = &NetworkPolicyInterfaceMock{} + +// NetworkPolicyInterfaceMock is a mock implementation of v11.NetworkPolicyInterface. +// +// func TestSomethingThatUsesNetworkPolicyInterface(t *testing.T) { +// +// // make and configure a mocked v11.NetworkPolicyInterface +// mockedNetworkPolicyInterface := &NetworkPolicyInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NetworkPolicyLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.NetworkPolicyLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.NetworkPolicyController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNetworkPolicyInterface in code that requires v11.NetworkPolicyInterface +// // and then make assertions. +// +// } +type NetworkPolicyInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.NetworkPolicyLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.NetworkPolicyLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.NetworkPolicyController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.NetworkPolicyList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.NetworkPolicyList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NetworkPolicyHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NetworkPolicyLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.NetworkPolicyHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NetworkPolicyLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NetworkPolicyHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NetworkPolicyLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.NetworkPolicyHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.NetworkPolicyLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.NetworkPolicy + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.NetworkPolicy + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NetworkPolicyInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NetworkPolicyInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NetworkPolicyInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NetworkPolicyInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle + } + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNetworkPolicyInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.NetworkPolicyHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NetworkPolicyInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NetworkPolicyInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNetworkPolicyInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNetworkPolicyInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddClusterScopedHandlerCalls()) +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNetworkPolicyInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.NetworkPolicyLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NetworkPolicyInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NetworkPolicyInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNetworkPolicyInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNetworkPolicyInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddClusterScopedLifecycleCalls()) +func (mock *NetworkPolicyInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.NetworkPolicyLifecycle + } + lockNetworkPolicyInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNetworkPolicyInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NetworkPolicyInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NetworkPolicyInterfaceMock.AddFeatureHandlerFunc: method is nil but NetworkPolicyInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNetworkPolicyInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNetworkPolicyInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddFeatureHandlerCalls()) +func (mock *NetworkPolicyInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNetworkPolicyInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NetworkPolicyInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.NetworkPolicyLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NetworkPolicyInterfaceMock.AddFeatureLifecycleFunc: method is nil but NetworkPolicyInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NetworkPolicyLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNetworkPolicyInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNetworkPolicyInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddFeatureLifecycleCalls()) +func (mock *NetworkPolicyInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.NetworkPolicyLifecycle + } + lockNetworkPolicyInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNetworkPolicyInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NetworkPolicyInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.NetworkPolicyHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NetworkPolicyInterfaceMock.AddHandlerFunc: method is nil but NetworkPolicyInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.NetworkPolicyHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNetworkPolicyInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNetworkPolicyInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddHandlerCalls()) +func (mock *NetworkPolicyInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.NetworkPolicyHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.NetworkPolicyHandlerFunc + } + lockNetworkPolicyInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNetworkPolicyInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NetworkPolicyInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.NetworkPolicyLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NetworkPolicyInterfaceMock.AddLifecycleFunc: method is nil but NetworkPolicyInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.NetworkPolicyLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNetworkPolicyInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNetworkPolicyInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.AddLifecycleCalls()) +func (mock *NetworkPolicyInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.NetworkPolicyLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.NetworkPolicyLifecycle + } + lockNetworkPolicyInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNetworkPolicyInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NetworkPolicyInterfaceMock) Controller() v11.NetworkPolicyController { + if mock.ControllerFunc == nil { + panic("NetworkPolicyInterfaceMock.ControllerFunc: method is nil but NetworkPolicyInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNetworkPolicyInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNetworkPolicyInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.ControllerCalls()) +func (mock *NetworkPolicyInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNetworkPolicyInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNetworkPolicyInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NetworkPolicyInterfaceMock) Create(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { + if mock.CreateFunc == nil { + panic("NetworkPolicyInterfaceMock.CreateFunc: method is nil but NetworkPolicyInterface.Create was just called") + } + callInfo := struct { + In1 *v1.NetworkPolicy + }{ + In1: in1, + } + lockNetworkPolicyInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNetworkPolicyInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.CreateCalls()) +func (mock *NetworkPolicyInterfaceMock) CreateCalls() []struct { + In1 *v1.NetworkPolicy +} { + var calls []struct { + In1 *v1.NetworkPolicy + } + lockNetworkPolicyInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNetworkPolicyInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NetworkPolicyInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NetworkPolicyInterfaceMock.DeleteFunc: method is nil but NetworkPolicyInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNetworkPolicyInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNetworkPolicyInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.DeleteCalls()) +func (mock *NetworkPolicyInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNetworkPolicyInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNetworkPolicyInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NetworkPolicyInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NetworkPolicyInterfaceMock.DeleteCollectionFunc: method is nil but NetworkPolicyInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNetworkPolicyInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNetworkPolicyInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.DeleteCollectionCalls()) +func (mock *NetworkPolicyInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNetworkPolicyInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNetworkPolicyInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NetworkPolicyInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NetworkPolicyInterfaceMock.DeleteNamespacedFunc: method is nil but NetworkPolicyInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNetworkPolicyInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNetworkPolicyInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.DeleteNamespacedCalls()) +func (mock *NetworkPolicyInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNetworkPolicyInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNetworkPolicyInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NetworkPolicyInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { + if mock.GetFunc == nil { + panic("NetworkPolicyInterfaceMock.GetFunc: method is nil but NetworkPolicyInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNetworkPolicyInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNetworkPolicyInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.GetCalls()) +func (mock *NetworkPolicyInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNetworkPolicyInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNetworkPolicyInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NetworkPolicyInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { + if mock.GetNamespacedFunc == nil { + panic("NetworkPolicyInterfaceMock.GetNamespacedFunc: method is nil but NetworkPolicyInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNetworkPolicyInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNetworkPolicyInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.GetNamespacedCalls()) +func (mock *NetworkPolicyInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNetworkPolicyInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNetworkPolicyInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NetworkPolicyInterfaceMock) List(opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { + if mock.ListFunc == nil { + panic("NetworkPolicyInterfaceMock.ListFunc: method is nil but NetworkPolicyInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNetworkPolicyInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNetworkPolicyInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.ListCalls()) +func (mock *NetworkPolicyInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNetworkPolicyInterfaceMockList.RLock() + calls = mock.calls.List + lockNetworkPolicyInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NetworkPolicyInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { + if mock.ListNamespacedFunc == nil { + panic("NetworkPolicyInterfaceMock.ListNamespacedFunc: method is nil but NetworkPolicyInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNetworkPolicyInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNetworkPolicyInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.ListNamespacedCalls()) +func (mock *NetworkPolicyInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNetworkPolicyInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNetworkPolicyInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NetworkPolicyInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NetworkPolicyInterfaceMock.ObjectClientFunc: method is nil but NetworkPolicyInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNetworkPolicyInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNetworkPolicyInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.ObjectClientCalls()) +func (mock *NetworkPolicyInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNetworkPolicyInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNetworkPolicyInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NetworkPolicyInterfaceMock) Update(in1 *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { + if mock.UpdateFunc == nil { + panic("NetworkPolicyInterfaceMock.UpdateFunc: method is nil but NetworkPolicyInterface.Update was just called") + } + callInfo := struct { + In1 *v1.NetworkPolicy + }{ + In1: in1, + } + lockNetworkPolicyInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNetworkPolicyInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.UpdateCalls()) +func (mock *NetworkPolicyInterfaceMock) UpdateCalls() []struct { + In1 *v1.NetworkPolicy +} { + var calls []struct { + In1 *v1.NetworkPolicy + } + lockNetworkPolicyInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNetworkPolicyInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NetworkPolicyInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NetworkPolicyInterfaceMock.WatchFunc: method is nil but NetworkPolicyInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNetworkPolicyInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNetworkPolicyInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNetworkPolicyInterface.WatchCalls()) +func (mock *NetworkPolicyInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNetworkPolicyInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNetworkPolicyInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNetworkPoliciesGetterMockNetworkPolicies sync.RWMutex +) + +// Ensure, that NetworkPoliciesGetterMock does implement v11.NetworkPoliciesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.NetworkPoliciesGetter = &NetworkPoliciesGetterMock{} + +// NetworkPoliciesGetterMock is a mock implementation of v11.NetworkPoliciesGetter. +// +// func TestSomethingThatUsesNetworkPoliciesGetter(t *testing.T) { +// +// // make and configure a mocked v11.NetworkPoliciesGetter +// mockedNetworkPoliciesGetter := &NetworkPoliciesGetterMock{ +// NetworkPoliciesFunc: func(namespace string) v11.NetworkPolicyInterface { +// panic("mock out the NetworkPolicies method") +// }, +// } +// +// // use mockedNetworkPoliciesGetter in code that requires v11.NetworkPoliciesGetter +// // and then make assertions. +// +// } +type NetworkPoliciesGetterMock struct { + // NetworkPoliciesFunc mocks the NetworkPolicies method. + NetworkPoliciesFunc func(namespace string) v11.NetworkPolicyInterface + + // calls tracks calls to the methods. + calls struct { + // NetworkPolicies holds details about calls to the NetworkPolicies method. + NetworkPolicies []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NetworkPolicies calls NetworkPoliciesFunc. +func (mock *NetworkPoliciesGetterMock) NetworkPolicies(namespace string) v11.NetworkPolicyInterface { + if mock.NetworkPoliciesFunc == nil { + panic("NetworkPoliciesGetterMock.NetworkPoliciesFunc: method is nil but NetworkPoliciesGetter.NetworkPolicies was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNetworkPoliciesGetterMockNetworkPolicies.Lock() + mock.calls.NetworkPolicies = append(mock.calls.NetworkPolicies, callInfo) + lockNetworkPoliciesGetterMockNetworkPolicies.Unlock() + return mock.NetworkPoliciesFunc(namespace) +} + +// NetworkPoliciesCalls gets all the calls that were made to NetworkPolicies. +// Check the length with: +// +// len(mockedNetworkPoliciesGetter.NetworkPoliciesCalls()) +func (mock *NetworkPoliciesGetterMock) NetworkPoliciesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNetworkPoliciesGetterMockNetworkPolicies.RLock() + calls = mock.calls.NetworkPolicies + lockNetworkPoliciesGetterMockNetworkPolicies.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_controller.go new file mode 100644 index 0000000..cf27872 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + IngressGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Ingress", + } + IngressResource = metav1.APIResource{ + Name: "ingresses", + SingularName: "ingress", + Namespaced: true, + + Kind: IngressGroupVersionKind.Kind, + } + + IngressGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "ingresses", + } +) + +func init() { + resource.Put(IngressGroupVersionResource) +} + +// Deprecated: use v1.Ingress instead +type Ingress = v1.Ingress + +func NewIngress(namespace, name string, obj v1.Ingress) *v1.Ingress { + obj.APIVersion, obj.Kind = IngressGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type IngressHandlerFunc func(key string, obj *v1.Ingress) (runtime.Object, error) + +type IngressChangeHandlerFunc func(obj *v1.Ingress) (runtime.Object, error) + +type IngressLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Ingress, err error) + Get(namespace, name string) (*v1.Ingress, error) +} + +type IngressController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() IngressLister + AddHandler(ctx context.Context, name string, handler IngressHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler IngressHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler IngressHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type IngressInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Ingress) (*v1.Ingress, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Ingress, error) + Get(name string, opts metav1.GetOptions) (*v1.Ingress, error) + Update(*v1.Ingress) (*v1.Ingress, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.IngressList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.IngressList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() IngressController + AddHandler(ctx context.Context, name string, sync IngressHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle IngressLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle IngressLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync IngressHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync IngressHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle IngressLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle IngressLifecycle) +} + +type ingressLister struct { + ns string + controller *ingressController +} + +func (l *ingressLister) List(namespace string, selector labels.Selector) (ret []*v1.Ingress, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Ingress)) + }) + return +} + +func (l *ingressLister) Get(namespace, name string) (*v1.Ingress, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: IngressGroupVersionKind.Group, + Resource: IngressGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Ingress), nil +} + +type ingressController struct { + ns string + controller.GenericController +} + +func (c *ingressController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *ingressController) Lister() IngressLister { + return &ingressLister{ + ns: c.ns, + controller: c, + } +} + +func (c *ingressController) AddHandler(ctx context.Context, name string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Ingress); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Ingress); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Ingress); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *ingressController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler IngressHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Ingress); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type ingressFactory struct { +} + +func (c ingressFactory) Object() runtime.Object { + return &v1.Ingress{} +} + +func (c ingressFactory) List() runtime.Object { + return &v1.IngressList{} +} + +func (s *ingressClient) Controller() IngressController { + genericController := controller.NewGenericController(s.ns, IngressGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(IngressGroupVersionResource, IngressGroupVersionKind.Kind, true)) + + return &ingressController{ + ns: s.ns, + GenericController: genericController, + } +} + +type ingressClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller IngressController +} + +func (s *ingressClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *ingressClient) Create(o *v1.Ingress) (*v1.Ingress, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) Get(name string, opts metav1.GetOptions) (*v1.Ingress, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Ingress, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) Update(o *v1.Ingress) (*v1.Ingress, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) UpdateStatus(o *v1.Ingress) (*v1.Ingress, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *ingressClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *ingressClient) List(opts metav1.ListOptions) (*v1.IngressList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.IngressList), err +} + +func (s *ingressClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.IngressList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.IngressList), err +} + +func (s *ingressClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *ingressClient) Patch(o *v1.Ingress, patchType types.PatchType, data []byte, subresources ...string) (*v1.Ingress, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Ingress), err +} + +func (s *ingressClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *ingressClient) AddHandler(ctx context.Context, name string, sync IngressHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ingressClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync IngressHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ingressClient) AddLifecycle(ctx context.Context, name string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *ingressClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *ingressClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync IngressHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync IngressHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *ingressClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle IngressLifecycle) { + sync := NewIngressLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_lifecycle_adapter.go new file mode 100644 index 0000000..9de75bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_ingress_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type IngressLifecycle interface { + Create(obj *v1.Ingress) (runtime.Object, error) + Remove(obj *v1.Ingress) (runtime.Object, error) + Updated(obj *v1.Ingress) (runtime.Object, error) +} + +type ingressLifecycleAdapter struct { + lifecycle IngressLifecycle +} + +func (w *ingressLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *ingressLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *ingressLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ingressLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *ingressLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Ingress)) + if o == nil { + return nil, err + } + return o, err +} + +func NewIngressLifecycleAdapter(name string, clusterScoped bool, client IngressInterface, l IngressLifecycle) IngressHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(IngressGroupVersionResource) + } + adapter := &ingressLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Ingress) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..c75ff4d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_k8s_client.go @@ -0,0 +1,78 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + NetworkPoliciesGetter + IngressesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type NetworkPoliciesGetter interface { + NetworkPolicies(namespace string) NetworkPolicyInterface +} + +func (c *Client) NetworkPolicies(namespace string) NetworkPolicyInterface { + sharedClient := c.clientFactory.ForResourceKind(NetworkPolicyGroupVersionResource, NetworkPolicyGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NetworkPolicyResource, NetworkPolicyGroupVersionKind, networkPolicyFactory{}) + return &networkPolicyClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type IngressesGetter interface { + Ingresses(namespace string) IngressInterface +} + +func (c *Client) Ingresses(namespace string) IngressInterface { + sharedClient := c.clientFactory.ForResourceKind(IngressGroupVersionResource, IngressGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &IngressResource, IngressGroupVersionKind, ingressFactory{}) + return &ingressClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_controller.go new file mode 100644 index 0000000..a97ae20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NetworkPolicyGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NetworkPolicy", + } + NetworkPolicyResource = metav1.APIResource{ + Name: "networkpolicies", + SingularName: "networkpolicy", + Namespaced: true, + + Kind: NetworkPolicyGroupVersionKind.Kind, + } + + NetworkPolicyGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "networkpolicies", + } +) + +func init() { + resource.Put(NetworkPolicyGroupVersionResource) +} + +// Deprecated: use v1.NetworkPolicy instead +type NetworkPolicy = v1.NetworkPolicy + +func NewNetworkPolicy(namespace, name string, obj v1.NetworkPolicy) *v1.NetworkPolicy { + obj.APIVersion, obj.Kind = NetworkPolicyGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NetworkPolicyHandlerFunc func(key string, obj *v1.NetworkPolicy) (runtime.Object, error) + +type NetworkPolicyChangeHandlerFunc func(obj *v1.NetworkPolicy) (runtime.Object, error) + +type NetworkPolicyLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.NetworkPolicy, err error) + Get(namespace, name string) (*v1.NetworkPolicy, error) +} + +type NetworkPolicyController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NetworkPolicyLister + AddHandler(ctx context.Context, name string, handler NetworkPolicyHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NetworkPolicyHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NetworkPolicyHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NetworkPolicyHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NetworkPolicyInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.NetworkPolicy) (*v1.NetworkPolicy, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) + Get(name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) + Update(*v1.NetworkPolicy) (*v1.NetworkPolicy, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.NetworkPolicyList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NetworkPolicyList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NetworkPolicyController + AddHandler(ctx context.Context, name string, sync NetworkPolicyHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NetworkPolicyHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NetworkPolicyLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NetworkPolicyLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NetworkPolicyHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NetworkPolicyHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NetworkPolicyLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NetworkPolicyLifecycle) +} + +type networkPolicyLister struct { + ns string + controller *networkPolicyController +} + +func (l *networkPolicyLister) List(namespace string, selector labels.Selector) (ret []*v1.NetworkPolicy, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.NetworkPolicy)) + }) + return +} + +func (l *networkPolicyLister) Get(namespace, name string) (*v1.NetworkPolicy, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NetworkPolicyGroupVersionKind.Group, + Resource: NetworkPolicyGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.NetworkPolicy), nil +} + +type networkPolicyController struct { + ns string + controller.GenericController +} + +func (c *networkPolicyController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *networkPolicyController) Lister() NetworkPolicyLister { + return &networkPolicyLister{ + ns: c.ns, + controller: c, + } +} + +func (c *networkPolicyController) AddHandler(ctx context.Context, name string, handler NetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.NetworkPolicy); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *networkPolicyController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.NetworkPolicy); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *networkPolicyController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.NetworkPolicy); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *networkPolicyController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NetworkPolicyHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.NetworkPolicy); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type networkPolicyFactory struct { +} + +func (c networkPolicyFactory) Object() runtime.Object { + return &v1.NetworkPolicy{} +} + +func (c networkPolicyFactory) List() runtime.Object { + return &v1.NetworkPolicyList{} +} + +func (s *networkPolicyClient) Controller() NetworkPolicyController { + genericController := controller.NewGenericController(s.ns, NetworkPolicyGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NetworkPolicyGroupVersionResource, NetworkPolicyGroupVersionKind.Kind, true)) + + return &networkPolicyController{ + ns: s.ns, + GenericController: genericController, + } +} + +type networkPolicyClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NetworkPolicyController +} + +func (s *networkPolicyClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *networkPolicyClient) Create(o *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) Get(name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) Update(o *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) UpdateStatus(o *v1.NetworkPolicy) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *networkPolicyClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *networkPolicyClient) List(opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.NetworkPolicyList), err +} + +func (s *networkPolicyClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.NetworkPolicyList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.NetworkPolicyList), err +} + +func (s *networkPolicyClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *networkPolicyClient) Patch(o *v1.NetworkPolicy, patchType types.PatchType, data []byte, subresources ...string) (*v1.NetworkPolicy, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.NetworkPolicy), err +} + +func (s *networkPolicyClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *networkPolicyClient) AddHandler(ctx context.Context, name string, sync NetworkPolicyHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *networkPolicyClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NetworkPolicyHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *networkPolicyClient) AddLifecycle(ctx context.Context, name string, lifecycle NetworkPolicyLifecycle) { + sync := NewNetworkPolicyLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *networkPolicyClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NetworkPolicyLifecycle) { + sync := NewNetworkPolicyLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *networkPolicyClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NetworkPolicyHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *networkPolicyClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NetworkPolicyHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *networkPolicyClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NetworkPolicyLifecycle) { + sync := NewNetworkPolicyLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *networkPolicyClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NetworkPolicyLifecycle) { + sync := NewNetworkPolicyLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_lifecycle_adapter.go new file mode 100644 index 0000000..dd41df8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_network_policy_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type NetworkPolicyLifecycle interface { + Create(obj *v1.NetworkPolicy) (runtime.Object, error) + Remove(obj *v1.NetworkPolicy) (runtime.Object, error) + Updated(obj *v1.NetworkPolicy) (runtime.Object, error) +} + +type networkPolicyLifecycleAdapter struct { + lifecycle NetworkPolicyLifecycle +} + +func (w *networkPolicyLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *networkPolicyLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *networkPolicyLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.NetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *networkPolicyLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.NetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *networkPolicyLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.NetworkPolicy)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNetworkPolicyLifecycleAdapter(name string, clusterScoped bool, client NetworkPolicyInterface, l NetworkPolicyLifecycle) NetworkPolicyHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NetworkPolicyGroupVersionResource) + } + adapter := &networkPolicyLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.NetworkPolicy) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_scheme.go new file mode 100644 index 0000000..5d7413c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/networking.k8s.io/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "networking.k8s.io" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_mock.go new file mode 100644 index 0000000..4398b78 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockAppListerMockGet sync.RWMutex + lockAppListerMockList sync.RWMutex +) + +// Ensure, that AppListerMock does implement v31.AppLister. +// If this is not the case, regenerate this file with moq. +var _ v31.AppLister = &AppListerMock{} + +// AppListerMock is a mock implementation of v31.AppLister. +// +// func TestSomethingThatUsesAppLister(t *testing.T) { +// +// // make and configure a mocked v31.AppLister +// mockedAppLister := &AppListerMock{ +// GetFunc: func(namespace string, name string) (*v3.App, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.App, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedAppLister in code that requires v31.AppLister +// // and then make assertions. +// +// } +type AppListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.App, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.App, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *AppListerMock) Get(namespace string, name string) (*v3.App, error) { + if mock.GetFunc == nil { + panic("AppListerMock.GetFunc: method is nil but AppLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAppListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAppListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAppLister.GetCalls()) +func (mock *AppListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAppListerMockGet.RLock() + calls = mock.calls.Get + lockAppListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AppListerMock) List(namespace string, selector labels.Selector) ([]*v3.App, error) { + if mock.ListFunc == nil { + panic("AppListerMock.ListFunc: method is nil but AppLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockAppListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAppListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAppLister.ListCalls()) +func (mock *AppListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockAppListerMockList.RLock() + calls = mock.calls.List + lockAppListerMockList.RUnlock() + return calls +} + +var ( + lockAppControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockAppControllerMockAddClusterScopedHandler sync.RWMutex + lockAppControllerMockAddFeatureHandler sync.RWMutex + lockAppControllerMockAddHandler sync.RWMutex + lockAppControllerMockEnqueue sync.RWMutex + lockAppControllerMockEnqueueAfter sync.RWMutex + lockAppControllerMockGeneric sync.RWMutex + lockAppControllerMockInformer sync.RWMutex + lockAppControllerMockLister sync.RWMutex +) + +// Ensure, that AppControllerMock does implement v31.AppController. +// If this is not the case, regenerate this file with moq. +var _ v31.AppController = &AppControllerMock{} + +// AppControllerMock is a mock implementation of v31.AppController. +// +// func TestSomethingThatUsesAppController(t *testing.T) { +// +// // make and configure a mocked v31.AppController +// mockedAppController := &AppControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.AppHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.AppHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.AppLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedAppController in code that requires v31.AppController +// // and then make assertions. +// +// } +type AppControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.AppHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.AppHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.AppLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AppHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AppHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.AppHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AppControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AppControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but AppController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAppControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAppControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAppController.AddClusterScopedFeatureHandlerCalls()) +func (mock *AppControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppHandlerFunc + } + lockAppControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAppControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AppControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.AppHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AppControllerMock.AddClusterScopedHandlerFunc: method is nil but AppController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAppControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAppControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAppController.AddClusterScopedHandlerCalls()) +func (mock *AppControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppHandlerFunc + } + lockAppControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAppControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AppControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AppControllerMock.AddFeatureHandlerFunc: method is nil but AppController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAppControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAppControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAppController.AddFeatureHandlerCalls()) +func (mock *AppControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc + } + lockAppControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAppControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AppControllerMock) AddHandler(ctx context.Context, name string, handler v31.AppHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AppControllerMock.AddHandlerFunc: method is nil but AppController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.AppHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockAppControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAppControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAppController.AddHandlerCalls()) +func (mock *AppControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.AppHandlerFunc + } + lockAppControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAppControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *AppControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("AppControllerMock.EnqueueFunc: method is nil but AppController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAppControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockAppControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedAppController.EnqueueCalls()) +func (mock *AppControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAppControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockAppControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *AppControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("AppControllerMock.EnqueueAfterFunc: method is nil but AppController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockAppControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockAppControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedAppController.EnqueueAfterCalls()) +func (mock *AppControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockAppControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockAppControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *AppControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("AppControllerMock.GenericFunc: method is nil but AppController.Generic was just called") + } + callInfo := struct { + }{} + lockAppControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockAppControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedAppController.GenericCalls()) +func (mock *AppControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockAppControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockAppControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *AppControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("AppControllerMock.InformerFunc: method is nil but AppController.Informer was just called") + } + callInfo := struct { + }{} + lockAppControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockAppControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedAppController.InformerCalls()) +func (mock *AppControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockAppControllerMockInformer.RLock() + calls = mock.calls.Informer + lockAppControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *AppControllerMock) Lister() v31.AppLister { + if mock.ListerFunc == nil { + panic("AppControllerMock.ListerFunc: method is nil but AppController.Lister was just called") + } + callInfo := struct { + }{} + lockAppControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockAppControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedAppController.ListerCalls()) +func (mock *AppControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockAppControllerMockLister.RLock() + calls = mock.calls.Lister + lockAppControllerMockLister.RUnlock() + return calls +} + +var ( + lockAppInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockAppInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockAppInterfaceMockAddClusterScopedHandler sync.RWMutex + lockAppInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockAppInterfaceMockAddFeatureHandler sync.RWMutex + lockAppInterfaceMockAddFeatureLifecycle sync.RWMutex + lockAppInterfaceMockAddHandler sync.RWMutex + lockAppInterfaceMockAddLifecycle sync.RWMutex + lockAppInterfaceMockController sync.RWMutex + lockAppInterfaceMockCreate sync.RWMutex + lockAppInterfaceMockDelete sync.RWMutex + lockAppInterfaceMockDeleteCollection sync.RWMutex + lockAppInterfaceMockDeleteNamespaced sync.RWMutex + lockAppInterfaceMockGet sync.RWMutex + lockAppInterfaceMockGetNamespaced sync.RWMutex + lockAppInterfaceMockList sync.RWMutex + lockAppInterfaceMockListNamespaced sync.RWMutex + lockAppInterfaceMockObjectClient sync.RWMutex + lockAppInterfaceMockUpdate sync.RWMutex + lockAppInterfaceMockWatch sync.RWMutex +) + +// Ensure, that AppInterfaceMock does implement v31.AppInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.AppInterface = &AppInterfaceMock{} + +// AppInterfaceMock is a mock implementation of v31.AppInterface. +// +// func TestSomethingThatUsesAppInterface(t *testing.T) { +// +// // make and configure a mocked v31.AppInterface +// mockedAppInterface := &AppInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.AppLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.AppHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.AppLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.AppController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.App) (*v3.App, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.App, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.App, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.AppList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.AppList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.App) (*v3.App, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedAppInterface in code that requires v31.AppInterface +// // and then make assertions. +// +// } +type AppInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.AppLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.AppHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.AppLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.AppController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.App) (*v3.App, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.App, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.App, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.AppList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.AppList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.App) (*v3.App, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AppHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AppHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.App + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.App + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AppInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AppInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but AppInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAppInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAppInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAppInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *AppInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppHandlerFunc + } + lockAppInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAppInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *AppInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("AppInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but AppInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAppInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockAppInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedAppInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *AppInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppLifecycle + } + lockAppInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockAppInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AppInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AppInterfaceMock.AddClusterScopedHandlerFunc: method is nil but AppInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAppInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAppInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAppInterface.AddClusterScopedHandlerCalls()) +func (mock *AppInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppHandlerFunc + } + lockAppInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAppInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *AppInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.AppLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("AppInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but AppInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAppInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockAppInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedAppInterface.AddClusterScopedLifecycleCalls()) +func (mock *AppInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppLifecycle + } + lockAppInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockAppInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AppInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AppInterfaceMock.AddFeatureHandlerFunc: method is nil but AppInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAppInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAppInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAppInterface.AddFeatureHandlerCalls()) +func (mock *AppInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppHandlerFunc + } + lockAppInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAppInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *AppInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("AppInterfaceMock.AddFeatureLifecycleFunc: method is nil but AppInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockAppInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockAppInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedAppInterface.AddFeatureLifecycleCalls()) +func (mock *AppInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppLifecycle + } + lockAppInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockAppInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AppInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.AppHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AppInterfaceMock.AddHandlerFunc: method is nil but AppInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.AppHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockAppInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAppInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAppInterface.AddHandlerCalls()) +func (mock *AppInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.AppHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.AppHandlerFunc + } + lockAppInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAppInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *AppInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.AppLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("AppInterfaceMock.AddLifecycleFunc: method is nil but AppInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.AppLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockAppInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockAppInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedAppInterface.AddLifecycleCalls()) +func (mock *AppInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.AppLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.AppLifecycle + } + lockAppInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockAppInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *AppInterfaceMock) Controller() v31.AppController { + if mock.ControllerFunc == nil { + panic("AppInterfaceMock.ControllerFunc: method is nil but AppInterface.Controller was just called") + } + callInfo := struct { + }{} + lockAppInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockAppInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedAppInterface.ControllerCalls()) +func (mock *AppInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockAppInterfaceMockController.RLock() + calls = mock.calls.Controller + lockAppInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *AppInterfaceMock) Create(in1 *v3.App) (*v3.App, error) { + if mock.CreateFunc == nil { + panic("AppInterfaceMock.CreateFunc: method is nil but AppInterface.Create was just called") + } + callInfo := struct { + In1 *v3.App + }{ + In1: in1, + } + lockAppInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockAppInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedAppInterface.CreateCalls()) +func (mock *AppInterfaceMock) CreateCalls() []struct { + In1 *v3.App +} { + var calls []struct { + In1 *v3.App + } + lockAppInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockAppInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *AppInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("AppInterfaceMock.DeleteFunc: method is nil but AppInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockAppInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockAppInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedAppInterface.DeleteCalls()) +func (mock *AppInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockAppInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockAppInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *AppInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("AppInterfaceMock.DeleteCollectionFunc: method is nil but AppInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockAppInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockAppInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedAppInterface.DeleteCollectionCalls()) +func (mock *AppInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockAppInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockAppInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *AppInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("AppInterfaceMock.DeleteNamespacedFunc: method is nil but AppInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockAppInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockAppInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedAppInterface.DeleteNamespacedCalls()) +func (mock *AppInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockAppInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockAppInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *AppInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.App, error) { + if mock.GetFunc == nil { + panic("AppInterfaceMock.GetFunc: method is nil but AppInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockAppInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAppInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAppInterface.GetCalls()) +func (mock *AppInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockAppInterfaceMockGet.RLock() + calls = mock.calls.Get + lockAppInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *AppInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.App, error) { + if mock.GetNamespacedFunc == nil { + panic("AppInterfaceMock.GetNamespacedFunc: method is nil but AppInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockAppInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockAppInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedAppInterface.GetNamespacedCalls()) +func (mock *AppInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockAppInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockAppInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AppInterfaceMock) List(opts metav1.ListOptions) (*v3.AppList, error) { + if mock.ListFunc == nil { + panic("AppInterfaceMock.ListFunc: method is nil but AppInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAppInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAppInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAppInterface.ListCalls()) +func (mock *AppInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAppInterfaceMockList.RLock() + calls = mock.calls.List + lockAppInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *AppInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppList, error) { + if mock.ListNamespacedFunc == nil { + panic("AppInterfaceMock.ListNamespacedFunc: method is nil but AppInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockAppInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockAppInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedAppInterface.ListNamespacedCalls()) +func (mock *AppInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockAppInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockAppInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *AppInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("AppInterfaceMock.ObjectClientFunc: method is nil but AppInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockAppInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockAppInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedAppInterface.ObjectClientCalls()) +func (mock *AppInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockAppInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockAppInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *AppInterfaceMock) Update(in1 *v3.App) (*v3.App, error) { + if mock.UpdateFunc == nil { + panic("AppInterfaceMock.UpdateFunc: method is nil but AppInterface.Update was just called") + } + callInfo := struct { + In1 *v3.App + }{ + In1: in1, + } + lockAppInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockAppInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedAppInterface.UpdateCalls()) +func (mock *AppInterfaceMock) UpdateCalls() []struct { + In1 *v3.App +} { + var calls []struct { + In1 *v3.App + } + lockAppInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockAppInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *AppInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("AppInterfaceMock.WatchFunc: method is nil but AppInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAppInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockAppInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedAppInterface.WatchCalls()) +func (mock *AppInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAppInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockAppInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockAppsGetterMockApps sync.RWMutex +) + +// Ensure, that AppsGetterMock does implement v31.AppsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.AppsGetter = &AppsGetterMock{} + +// AppsGetterMock is a mock implementation of v31.AppsGetter. +// +// func TestSomethingThatUsesAppsGetter(t *testing.T) { +// +// // make and configure a mocked v31.AppsGetter +// mockedAppsGetter := &AppsGetterMock{ +// AppsFunc: func(namespace string) v31.AppInterface { +// panic("mock out the Apps method") +// }, +// } +// +// // use mockedAppsGetter in code that requires v31.AppsGetter +// // and then make assertions. +// +// } +type AppsGetterMock struct { + // AppsFunc mocks the Apps method. + AppsFunc func(namespace string) v31.AppInterface + + // calls tracks calls to the methods. + calls struct { + // Apps holds details about calls to the Apps method. + Apps []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Apps calls AppsFunc. +func (mock *AppsGetterMock) Apps(namespace string) v31.AppInterface { + if mock.AppsFunc == nil { + panic("AppsGetterMock.AppsFunc: method is nil but AppsGetter.Apps was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockAppsGetterMockApps.Lock() + mock.calls.Apps = append(mock.calls.Apps, callInfo) + lockAppsGetterMockApps.Unlock() + return mock.AppsFunc(namespace) +} + +// AppsCalls gets all the calls that were made to Apps. +// Check the length with: +// +// len(mockedAppsGetter.AppsCalls()) +func (mock *AppsGetterMock) AppsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockAppsGetterMockApps.RLock() + calls = mock.calls.Apps + lockAppsGetterMockApps.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_revision_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_revision_mock.go new file mode 100644 index 0000000..e43beb7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_app_revision_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockAppRevisionListerMockGet sync.RWMutex + lockAppRevisionListerMockList sync.RWMutex +) + +// Ensure, that AppRevisionListerMock does implement v31.AppRevisionLister. +// If this is not the case, regenerate this file with moq. +var _ v31.AppRevisionLister = &AppRevisionListerMock{} + +// AppRevisionListerMock is a mock implementation of v31.AppRevisionLister. +// +// func TestSomethingThatUsesAppRevisionLister(t *testing.T) { +// +// // make and configure a mocked v31.AppRevisionLister +// mockedAppRevisionLister := &AppRevisionListerMock{ +// GetFunc: func(namespace string, name string) (*v3.AppRevision, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.AppRevision, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedAppRevisionLister in code that requires v31.AppRevisionLister +// // and then make assertions. +// +// } +type AppRevisionListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.AppRevision, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.AppRevision, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *AppRevisionListerMock) Get(namespace string, name string) (*v3.AppRevision, error) { + if mock.GetFunc == nil { + panic("AppRevisionListerMock.GetFunc: method is nil but AppRevisionLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAppRevisionListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAppRevisionListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAppRevisionLister.GetCalls()) +func (mock *AppRevisionListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAppRevisionListerMockGet.RLock() + calls = mock.calls.Get + lockAppRevisionListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AppRevisionListerMock) List(namespace string, selector labels.Selector) ([]*v3.AppRevision, error) { + if mock.ListFunc == nil { + panic("AppRevisionListerMock.ListFunc: method is nil but AppRevisionLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockAppRevisionListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAppRevisionListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAppRevisionLister.ListCalls()) +func (mock *AppRevisionListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockAppRevisionListerMockList.RLock() + calls = mock.calls.List + lockAppRevisionListerMockList.RUnlock() + return calls +} + +var ( + lockAppRevisionControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockAppRevisionControllerMockAddClusterScopedHandler sync.RWMutex + lockAppRevisionControllerMockAddFeatureHandler sync.RWMutex + lockAppRevisionControllerMockAddHandler sync.RWMutex + lockAppRevisionControllerMockEnqueue sync.RWMutex + lockAppRevisionControllerMockEnqueueAfter sync.RWMutex + lockAppRevisionControllerMockGeneric sync.RWMutex + lockAppRevisionControllerMockInformer sync.RWMutex + lockAppRevisionControllerMockLister sync.RWMutex +) + +// Ensure, that AppRevisionControllerMock does implement v31.AppRevisionController. +// If this is not the case, regenerate this file with moq. +var _ v31.AppRevisionController = &AppRevisionControllerMock{} + +// AppRevisionControllerMock is a mock implementation of v31.AppRevisionController. +// +// func TestSomethingThatUsesAppRevisionController(t *testing.T) { +// +// // make and configure a mocked v31.AppRevisionController +// mockedAppRevisionController := &AppRevisionControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.AppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.AppRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.AppRevisionLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedAppRevisionController in code that requires v31.AppRevisionController +// // and then make assertions. +// +// } +type AppRevisionControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppRevisionHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.AppRevisionHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.AppRevisionHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.AppRevisionLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AppRevisionHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.AppRevisionHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppRevisionHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.AppRevisionHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AppRevisionControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.AppRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AppRevisionControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but AppRevisionController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAppRevisionControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAppRevisionControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAppRevisionController.AddClusterScopedFeatureHandlerCalls()) +func (mock *AppRevisionControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc + } + lockAppRevisionControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAppRevisionControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AppRevisionControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.AppRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AppRevisionControllerMock.AddClusterScopedHandlerFunc: method is nil but AppRevisionController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockAppRevisionControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAppRevisionControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAppRevisionController.AddClusterScopedHandlerCalls()) +func (mock *AppRevisionControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.AppRevisionHandlerFunc + } + lockAppRevisionControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAppRevisionControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AppRevisionControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AppRevisionControllerMock.AddFeatureHandlerFunc: method is nil but AppRevisionController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAppRevisionControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAppRevisionControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAppRevisionController.AddFeatureHandlerCalls()) +func (mock *AppRevisionControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc + } + lockAppRevisionControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAppRevisionControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AppRevisionControllerMock) AddHandler(ctx context.Context, name string, handler v31.AppRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AppRevisionControllerMock.AddHandlerFunc: method is nil but AppRevisionController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockAppRevisionControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAppRevisionControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAppRevisionController.AddHandlerCalls()) +func (mock *AppRevisionControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.AppRevisionHandlerFunc + } + lockAppRevisionControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAppRevisionControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *AppRevisionControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("AppRevisionControllerMock.EnqueueFunc: method is nil but AppRevisionController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockAppRevisionControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockAppRevisionControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedAppRevisionController.EnqueueCalls()) +func (mock *AppRevisionControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockAppRevisionControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockAppRevisionControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *AppRevisionControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("AppRevisionControllerMock.EnqueueAfterFunc: method is nil but AppRevisionController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockAppRevisionControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockAppRevisionControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedAppRevisionController.EnqueueAfterCalls()) +func (mock *AppRevisionControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockAppRevisionControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockAppRevisionControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *AppRevisionControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("AppRevisionControllerMock.GenericFunc: method is nil but AppRevisionController.Generic was just called") + } + callInfo := struct { + }{} + lockAppRevisionControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockAppRevisionControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedAppRevisionController.GenericCalls()) +func (mock *AppRevisionControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockAppRevisionControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockAppRevisionControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *AppRevisionControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("AppRevisionControllerMock.InformerFunc: method is nil but AppRevisionController.Informer was just called") + } + callInfo := struct { + }{} + lockAppRevisionControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockAppRevisionControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedAppRevisionController.InformerCalls()) +func (mock *AppRevisionControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockAppRevisionControllerMockInformer.RLock() + calls = mock.calls.Informer + lockAppRevisionControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *AppRevisionControllerMock) Lister() v31.AppRevisionLister { + if mock.ListerFunc == nil { + panic("AppRevisionControllerMock.ListerFunc: method is nil but AppRevisionController.Lister was just called") + } + callInfo := struct { + }{} + lockAppRevisionControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockAppRevisionControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedAppRevisionController.ListerCalls()) +func (mock *AppRevisionControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockAppRevisionControllerMockLister.RLock() + calls = mock.calls.Lister + lockAppRevisionControllerMockLister.RUnlock() + return calls +} + +var ( + lockAppRevisionInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockAppRevisionInterfaceMockAddClusterScopedHandler sync.RWMutex + lockAppRevisionInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockAppRevisionInterfaceMockAddFeatureHandler sync.RWMutex + lockAppRevisionInterfaceMockAddFeatureLifecycle sync.RWMutex + lockAppRevisionInterfaceMockAddHandler sync.RWMutex + lockAppRevisionInterfaceMockAddLifecycle sync.RWMutex + lockAppRevisionInterfaceMockController sync.RWMutex + lockAppRevisionInterfaceMockCreate sync.RWMutex + lockAppRevisionInterfaceMockDelete sync.RWMutex + lockAppRevisionInterfaceMockDeleteCollection sync.RWMutex + lockAppRevisionInterfaceMockDeleteNamespaced sync.RWMutex + lockAppRevisionInterfaceMockGet sync.RWMutex + lockAppRevisionInterfaceMockGetNamespaced sync.RWMutex + lockAppRevisionInterfaceMockList sync.RWMutex + lockAppRevisionInterfaceMockListNamespaced sync.RWMutex + lockAppRevisionInterfaceMockObjectClient sync.RWMutex + lockAppRevisionInterfaceMockUpdate sync.RWMutex + lockAppRevisionInterfaceMockWatch sync.RWMutex +) + +// Ensure, that AppRevisionInterfaceMock does implement v31.AppRevisionInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.AppRevisionInterface = &AppRevisionInterfaceMock{} + +// AppRevisionInterfaceMock is a mock implementation of v31.AppRevisionInterface. +// +// func TestSomethingThatUsesAppRevisionInterface(t *testing.T) { +// +// // make and configure a mocked v31.AppRevisionInterface +// mockedAppRevisionInterface := &AppRevisionInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppRevisionLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.AppRevisionHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.AppRevisionLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.AppRevisionController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.AppRevision) (*v3.AppRevision, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.AppRevision, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.AppRevision, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.AppRevisionList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.AppRevisionList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.AppRevision) (*v3.AppRevision, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedAppRevisionInterface in code that requires v31.AppRevisionInterface +// // and then make assertions. +// +// } +type AppRevisionInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppRevisionLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.AppRevisionHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.AppRevisionLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.AppRevisionController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.AppRevision) (*v3.AppRevision, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.AppRevision, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.AppRevision, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.AppRevisionList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.AppRevisionList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.AppRevision) (*v3.AppRevision, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AppRevisionHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppRevisionLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.AppRevisionHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppRevisionLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppRevisionHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppRevisionLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.AppRevisionHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.AppRevisionLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.AppRevision + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.AppRevision + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *AppRevisionInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("AppRevisionInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but AppRevisionInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAppRevisionInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockAppRevisionInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *AppRevisionInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc + } + lockAppRevisionInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockAppRevisionInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *AppRevisionInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("AppRevisionInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but AppRevisionInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *AppRevisionInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle + } + lockAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockAppRevisionInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *AppRevisionInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.AppRevisionHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("AppRevisionInterfaceMock.AddClusterScopedHandlerFunc: method is nil but AppRevisionInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockAppRevisionInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockAppRevisionInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddClusterScopedHandlerCalls()) +func (mock *AppRevisionInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.AppRevisionHandlerFunc + } + lockAppRevisionInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockAppRevisionInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *AppRevisionInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.AppRevisionLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("AppRevisionInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but AppRevisionInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockAppRevisionInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockAppRevisionInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddClusterScopedLifecycleCalls()) +func (mock *AppRevisionInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.AppRevisionLifecycle + } + lockAppRevisionInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockAppRevisionInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *AppRevisionInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.AppRevisionHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("AppRevisionInterfaceMock.AddFeatureHandlerFunc: method is nil but AppRevisionInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockAppRevisionInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockAppRevisionInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddFeatureHandlerCalls()) +func (mock *AppRevisionInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.AppRevisionHandlerFunc + } + lockAppRevisionInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockAppRevisionInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *AppRevisionInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.AppRevisionLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("AppRevisionInterfaceMock.AddFeatureLifecycleFunc: method is nil but AppRevisionInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppRevisionLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockAppRevisionInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockAppRevisionInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddFeatureLifecycleCalls()) +func (mock *AppRevisionInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.AppRevisionLifecycle + } + lockAppRevisionInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockAppRevisionInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *AppRevisionInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.AppRevisionHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("AppRevisionInterfaceMock.AddHandlerFunc: method is nil but AppRevisionInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.AppRevisionHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockAppRevisionInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockAppRevisionInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddHandlerCalls()) +func (mock *AppRevisionInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.AppRevisionHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.AppRevisionHandlerFunc + } + lockAppRevisionInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockAppRevisionInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *AppRevisionInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.AppRevisionLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("AppRevisionInterfaceMock.AddLifecycleFunc: method is nil but AppRevisionInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.AppRevisionLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockAppRevisionInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockAppRevisionInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedAppRevisionInterface.AddLifecycleCalls()) +func (mock *AppRevisionInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.AppRevisionLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.AppRevisionLifecycle + } + lockAppRevisionInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockAppRevisionInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *AppRevisionInterfaceMock) Controller() v31.AppRevisionController { + if mock.ControllerFunc == nil { + panic("AppRevisionInterfaceMock.ControllerFunc: method is nil but AppRevisionInterface.Controller was just called") + } + callInfo := struct { + }{} + lockAppRevisionInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockAppRevisionInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedAppRevisionInterface.ControllerCalls()) +func (mock *AppRevisionInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockAppRevisionInterfaceMockController.RLock() + calls = mock.calls.Controller + lockAppRevisionInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *AppRevisionInterfaceMock) Create(in1 *v3.AppRevision) (*v3.AppRevision, error) { + if mock.CreateFunc == nil { + panic("AppRevisionInterfaceMock.CreateFunc: method is nil but AppRevisionInterface.Create was just called") + } + callInfo := struct { + In1 *v3.AppRevision + }{ + In1: in1, + } + lockAppRevisionInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockAppRevisionInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedAppRevisionInterface.CreateCalls()) +func (mock *AppRevisionInterfaceMock) CreateCalls() []struct { + In1 *v3.AppRevision +} { + var calls []struct { + In1 *v3.AppRevision + } + lockAppRevisionInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockAppRevisionInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *AppRevisionInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("AppRevisionInterfaceMock.DeleteFunc: method is nil but AppRevisionInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockAppRevisionInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockAppRevisionInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedAppRevisionInterface.DeleteCalls()) +func (mock *AppRevisionInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockAppRevisionInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockAppRevisionInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *AppRevisionInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("AppRevisionInterfaceMock.DeleteCollectionFunc: method is nil but AppRevisionInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockAppRevisionInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockAppRevisionInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedAppRevisionInterface.DeleteCollectionCalls()) +func (mock *AppRevisionInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockAppRevisionInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockAppRevisionInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *AppRevisionInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("AppRevisionInterfaceMock.DeleteNamespacedFunc: method is nil but AppRevisionInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockAppRevisionInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockAppRevisionInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedAppRevisionInterface.DeleteNamespacedCalls()) +func (mock *AppRevisionInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockAppRevisionInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockAppRevisionInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *AppRevisionInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.AppRevision, error) { + if mock.GetFunc == nil { + panic("AppRevisionInterfaceMock.GetFunc: method is nil but AppRevisionInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockAppRevisionInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockAppRevisionInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedAppRevisionInterface.GetCalls()) +func (mock *AppRevisionInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockAppRevisionInterfaceMockGet.RLock() + calls = mock.calls.Get + lockAppRevisionInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *AppRevisionInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.AppRevision, error) { + if mock.GetNamespacedFunc == nil { + panic("AppRevisionInterfaceMock.GetNamespacedFunc: method is nil but AppRevisionInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockAppRevisionInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockAppRevisionInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedAppRevisionInterface.GetNamespacedCalls()) +func (mock *AppRevisionInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockAppRevisionInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockAppRevisionInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *AppRevisionInterfaceMock) List(opts metav1.ListOptions) (*v3.AppRevisionList, error) { + if mock.ListFunc == nil { + panic("AppRevisionInterfaceMock.ListFunc: method is nil but AppRevisionInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAppRevisionInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockAppRevisionInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedAppRevisionInterface.ListCalls()) +func (mock *AppRevisionInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAppRevisionInterfaceMockList.RLock() + calls = mock.calls.List + lockAppRevisionInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *AppRevisionInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppRevisionList, error) { + if mock.ListNamespacedFunc == nil { + panic("AppRevisionInterfaceMock.ListNamespacedFunc: method is nil but AppRevisionInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockAppRevisionInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockAppRevisionInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedAppRevisionInterface.ListNamespacedCalls()) +func (mock *AppRevisionInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockAppRevisionInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockAppRevisionInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *AppRevisionInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("AppRevisionInterfaceMock.ObjectClientFunc: method is nil but AppRevisionInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockAppRevisionInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockAppRevisionInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedAppRevisionInterface.ObjectClientCalls()) +func (mock *AppRevisionInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockAppRevisionInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockAppRevisionInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *AppRevisionInterfaceMock) Update(in1 *v3.AppRevision) (*v3.AppRevision, error) { + if mock.UpdateFunc == nil { + panic("AppRevisionInterfaceMock.UpdateFunc: method is nil but AppRevisionInterface.Update was just called") + } + callInfo := struct { + In1 *v3.AppRevision + }{ + In1: in1, + } + lockAppRevisionInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockAppRevisionInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedAppRevisionInterface.UpdateCalls()) +func (mock *AppRevisionInterfaceMock) UpdateCalls() []struct { + In1 *v3.AppRevision +} { + var calls []struct { + In1 *v3.AppRevision + } + lockAppRevisionInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockAppRevisionInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *AppRevisionInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("AppRevisionInterfaceMock.WatchFunc: method is nil but AppRevisionInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockAppRevisionInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockAppRevisionInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedAppRevisionInterface.WatchCalls()) +func (mock *AppRevisionInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockAppRevisionInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockAppRevisionInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockAppRevisionsGetterMockAppRevisions sync.RWMutex +) + +// Ensure, that AppRevisionsGetterMock does implement v31.AppRevisionsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.AppRevisionsGetter = &AppRevisionsGetterMock{} + +// AppRevisionsGetterMock is a mock implementation of v31.AppRevisionsGetter. +// +// func TestSomethingThatUsesAppRevisionsGetter(t *testing.T) { +// +// // make and configure a mocked v31.AppRevisionsGetter +// mockedAppRevisionsGetter := &AppRevisionsGetterMock{ +// AppRevisionsFunc: func(namespace string) v31.AppRevisionInterface { +// panic("mock out the AppRevisions method") +// }, +// } +// +// // use mockedAppRevisionsGetter in code that requires v31.AppRevisionsGetter +// // and then make assertions. +// +// } +type AppRevisionsGetterMock struct { + // AppRevisionsFunc mocks the AppRevisions method. + AppRevisionsFunc func(namespace string) v31.AppRevisionInterface + + // calls tracks calls to the methods. + calls struct { + // AppRevisions holds details about calls to the AppRevisions method. + AppRevisions []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// AppRevisions calls AppRevisionsFunc. +func (mock *AppRevisionsGetterMock) AppRevisions(namespace string) v31.AppRevisionInterface { + if mock.AppRevisionsFunc == nil { + panic("AppRevisionsGetterMock.AppRevisionsFunc: method is nil but AppRevisionsGetter.AppRevisions was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockAppRevisionsGetterMockAppRevisions.Lock() + mock.calls.AppRevisions = append(mock.calls.AppRevisions, callInfo) + lockAppRevisionsGetterMockAppRevisions.Unlock() + return mock.AppRevisionsFunc(namespace) +} + +// AppRevisionsCalls gets all the calls that were made to AppRevisions. +// Check the length with: +// +// len(mockedAppRevisionsGetter.AppRevisionsCalls()) +func (mock *AppRevisionsGetterMock) AppRevisionsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockAppRevisionsGetterMockAppRevisions.RLock() + calls = mock.calls.AppRevisions + lockAppRevisionsGetterMockAppRevisions.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_basic_auth_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_basic_auth_mock.go new file mode 100644 index 0000000..38e6d16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_basic_auth_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockBasicAuthListerMockGet sync.RWMutex + lockBasicAuthListerMockList sync.RWMutex +) + +// Ensure, that BasicAuthListerMock does implement v31.BasicAuthLister. +// If this is not the case, regenerate this file with moq. +var _ v31.BasicAuthLister = &BasicAuthListerMock{} + +// BasicAuthListerMock is a mock implementation of v31.BasicAuthLister. +// +// func TestSomethingThatUsesBasicAuthLister(t *testing.T) { +// +// // make and configure a mocked v31.BasicAuthLister +// mockedBasicAuthLister := &BasicAuthListerMock{ +// GetFunc: func(namespace string, name string) (*v3.BasicAuth, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.BasicAuth, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedBasicAuthLister in code that requires v31.BasicAuthLister +// // and then make assertions. +// +// } +type BasicAuthListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.BasicAuth, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.BasicAuth, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *BasicAuthListerMock) Get(namespace string, name string) (*v3.BasicAuth, error) { + if mock.GetFunc == nil { + panic("BasicAuthListerMock.GetFunc: method is nil but BasicAuthLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockBasicAuthListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockBasicAuthListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedBasicAuthLister.GetCalls()) +func (mock *BasicAuthListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockBasicAuthListerMockGet.RLock() + calls = mock.calls.Get + lockBasicAuthListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *BasicAuthListerMock) List(namespace string, selector labels.Selector) ([]*v3.BasicAuth, error) { + if mock.ListFunc == nil { + panic("BasicAuthListerMock.ListFunc: method is nil but BasicAuthLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockBasicAuthListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockBasicAuthListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedBasicAuthLister.ListCalls()) +func (mock *BasicAuthListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockBasicAuthListerMockList.RLock() + calls = mock.calls.List + lockBasicAuthListerMockList.RUnlock() + return calls +} + +var ( + lockBasicAuthControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockBasicAuthControllerMockAddClusterScopedHandler sync.RWMutex + lockBasicAuthControllerMockAddFeatureHandler sync.RWMutex + lockBasicAuthControllerMockAddHandler sync.RWMutex + lockBasicAuthControllerMockEnqueue sync.RWMutex + lockBasicAuthControllerMockEnqueueAfter sync.RWMutex + lockBasicAuthControllerMockGeneric sync.RWMutex + lockBasicAuthControllerMockInformer sync.RWMutex + lockBasicAuthControllerMockLister sync.RWMutex +) + +// Ensure, that BasicAuthControllerMock does implement v31.BasicAuthController. +// If this is not the case, regenerate this file with moq. +var _ v31.BasicAuthController = &BasicAuthControllerMock{} + +// BasicAuthControllerMock is a mock implementation of v31.BasicAuthController. +// +// func TestSomethingThatUsesBasicAuthController(t *testing.T) { +// +// // make and configure a mocked v31.BasicAuthController +// mockedBasicAuthController := &BasicAuthControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.BasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.BasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.BasicAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.BasicAuthLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedBasicAuthController in code that requires v31.BasicAuthController +// // and then make assertions. +// +// } +type BasicAuthControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.BasicAuthHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.BasicAuthHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.BasicAuthHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.BasicAuthLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.BasicAuthHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.BasicAuthHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.BasicAuthHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.BasicAuthHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *BasicAuthControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.BasicAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("BasicAuthControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but BasicAuthController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockBasicAuthControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockBasicAuthControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedBasicAuthController.AddClusterScopedFeatureHandlerCalls()) +func (mock *BasicAuthControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc + } + lockBasicAuthControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockBasicAuthControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *BasicAuthControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.BasicAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("BasicAuthControllerMock.AddClusterScopedHandlerFunc: method is nil but BasicAuthController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockBasicAuthControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockBasicAuthControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedBasicAuthController.AddClusterScopedHandlerCalls()) +func (mock *BasicAuthControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.BasicAuthHandlerFunc + } + lockBasicAuthControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockBasicAuthControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *BasicAuthControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("BasicAuthControllerMock.AddFeatureHandlerFunc: method is nil but BasicAuthController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockBasicAuthControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockBasicAuthControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedBasicAuthController.AddFeatureHandlerCalls()) +func (mock *BasicAuthControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc + } + lockBasicAuthControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockBasicAuthControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *BasicAuthControllerMock) AddHandler(ctx context.Context, name string, handler v31.BasicAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("BasicAuthControllerMock.AddHandlerFunc: method is nil but BasicAuthController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockBasicAuthControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockBasicAuthControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedBasicAuthController.AddHandlerCalls()) +func (mock *BasicAuthControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.BasicAuthHandlerFunc + } + lockBasicAuthControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockBasicAuthControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *BasicAuthControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("BasicAuthControllerMock.EnqueueFunc: method is nil but BasicAuthController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockBasicAuthControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockBasicAuthControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedBasicAuthController.EnqueueCalls()) +func (mock *BasicAuthControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockBasicAuthControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockBasicAuthControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *BasicAuthControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("BasicAuthControllerMock.EnqueueAfterFunc: method is nil but BasicAuthController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockBasicAuthControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockBasicAuthControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedBasicAuthController.EnqueueAfterCalls()) +func (mock *BasicAuthControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockBasicAuthControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockBasicAuthControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *BasicAuthControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("BasicAuthControllerMock.GenericFunc: method is nil but BasicAuthController.Generic was just called") + } + callInfo := struct { + }{} + lockBasicAuthControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockBasicAuthControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedBasicAuthController.GenericCalls()) +func (mock *BasicAuthControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockBasicAuthControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockBasicAuthControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *BasicAuthControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("BasicAuthControllerMock.InformerFunc: method is nil but BasicAuthController.Informer was just called") + } + callInfo := struct { + }{} + lockBasicAuthControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockBasicAuthControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedBasicAuthController.InformerCalls()) +func (mock *BasicAuthControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockBasicAuthControllerMockInformer.RLock() + calls = mock.calls.Informer + lockBasicAuthControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *BasicAuthControllerMock) Lister() v31.BasicAuthLister { + if mock.ListerFunc == nil { + panic("BasicAuthControllerMock.ListerFunc: method is nil but BasicAuthController.Lister was just called") + } + callInfo := struct { + }{} + lockBasicAuthControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockBasicAuthControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedBasicAuthController.ListerCalls()) +func (mock *BasicAuthControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockBasicAuthControllerMockLister.RLock() + calls = mock.calls.Lister + lockBasicAuthControllerMockLister.RUnlock() + return calls +} + +var ( + lockBasicAuthInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockBasicAuthInterfaceMockAddClusterScopedHandler sync.RWMutex + lockBasicAuthInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockBasicAuthInterfaceMockAddFeatureHandler sync.RWMutex + lockBasicAuthInterfaceMockAddFeatureLifecycle sync.RWMutex + lockBasicAuthInterfaceMockAddHandler sync.RWMutex + lockBasicAuthInterfaceMockAddLifecycle sync.RWMutex + lockBasicAuthInterfaceMockController sync.RWMutex + lockBasicAuthInterfaceMockCreate sync.RWMutex + lockBasicAuthInterfaceMockDelete sync.RWMutex + lockBasicAuthInterfaceMockDeleteCollection sync.RWMutex + lockBasicAuthInterfaceMockDeleteNamespaced sync.RWMutex + lockBasicAuthInterfaceMockGet sync.RWMutex + lockBasicAuthInterfaceMockGetNamespaced sync.RWMutex + lockBasicAuthInterfaceMockList sync.RWMutex + lockBasicAuthInterfaceMockListNamespaced sync.RWMutex + lockBasicAuthInterfaceMockObjectClient sync.RWMutex + lockBasicAuthInterfaceMockUpdate sync.RWMutex + lockBasicAuthInterfaceMockWatch sync.RWMutex +) + +// Ensure, that BasicAuthInterfaceMock does implement v31.BasicAuthInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.BasicAuthInterface = &BasicAuthInterfaceMock{} + +// BasicAuthInterfaceMock is a mock implementation of v31.BasicAuthInterface. +// +// func TestSomethingThatUsesBasicAuthInterface(t *testing.T) { +// +// // make and configure a mocked v31.BasicAuthInterface +// mockedBasicAuthInterface := &BasicAuthInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.BasicAuthLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.BasicAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.BasicAuthLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.BasicAuthController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.BasicAuth) (*v3.BasicAuth, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.BasicAuthList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.BasicAuthList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.BasicAuth) (*v3.BasicAuth, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedBasicAuthInterface in code that requires v31.BasicAuthInterface +// // and then make assertions. +// +// } +type BasicAuthInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.BasicAuthLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.BasicAuthHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.BasicAuthLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.BasicAuthController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.BasicAuth) (*v3.BasicAuth, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.BasicAuth, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.BasicAuth, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.BasicAuthList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.BasicAuthList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.BasicAuth) (*v3.BasicAuth, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.BasicAuthHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.BasicAuthLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.BasicAuthHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.BasicAuthLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.BasicAuthHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.BasicAuthLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.BasicAuthHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.BasicAuthLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.BasicAuth + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.BasicAuth + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *BasicAuthInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("BasicAuthInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but BasicAuthInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockBasicAuthInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockBasicAuthInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *BasicAuthInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc + } + lockBasicAuthInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockBasicAuthInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *BasicAuthInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("BasicAuthInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but BasicAuthInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *BasicAuthInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle + } + lockBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *BasicAuthInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.BasicAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("BasicAuthInterfaceMock.AddClusterScopedHandlerFunc: method is nil but BasicAuthInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockBasicAuthInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockBasicAuthInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddClusterScopedHandlerCalls()) +func (mock *BasicAuthInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.BasicAuthHandlerFunc + } + lockBasicAuthInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockBasicAuthInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *BasicAuthInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.BasicAuthLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("BasicAuthInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but BasicAuthInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockBasicAuthInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockBasicAuthInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddClusterScopedLifecycleCalls()) +func (mock *BasicAuthInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.BasicAuthLifecycle + } + lockBasicAuthInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockBasicAuthInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *BasicAuthInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.BasicAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("BasicAuthInterfaceMock.AddFeatureHandlerFunc: method is nil but BasicAuthInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockBasicAuthInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockBasicAuthInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddFeatureHandlerCalls()) +func (mock *BasicAuthInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.BasicAuthHandlerFunc + } + lockBasicAuthInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockBasicAuthInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *BasicAuthInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.BasicAuthLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("BasicAuthInterfaceMock.AddFeatureLifecycleFunc: method is nil but BasicAuthInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.BasicAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockBasicAuthInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockBasicAuthInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddFeatureLifecycleCalls()) +func (mock *BasicAuthInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.BasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.BasicAuthLifecycle + } + lockBasicAuthInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockBasicAuthInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *BasicAuthInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.BasicAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("BasicAuthInterfaceMock.AddHandlerFunc: method is nil but BasicAuthInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.BasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockBasicAuthInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockBasicAuthInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddHandlerCalls()) +func (mock *BasicAuthInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.BasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.BasicAuthHandlerFunc + } + lockBasicAuthInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockBasicAuthInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *BasicAuthInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.BasicAuthLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("BasicAuthInterfaceMock.AddLifecycleFunc: method is nil but BasicAuthInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.BasicAuthLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockBasicAuthInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockBasicAuthInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedBasicAuthInterface.AddLifecycleCalls()) +func (mock *BasicAuthInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.BasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.BasicAuthLifecycle + } + lockBasicAuthInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockBasicAuthInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *BasicAuthInterfaceMock) Controller() v31.BasicAuthController { + if mock.ControllerFunc == nil { + panic("BasicAuthInterfaceMock.ControllerFunc: method is nil but BasicAuthInterface.Controller was just called") + } + callInfo := struct { + }{} + lockBasicAuthInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockBasicAuthInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedBasicAuthInterface.ControllerCalls()) +func (mock *BasicAuthInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockBasicAuthInterfaceMockController.RLock() + calls = mock.calls.Controller + lockBasicAuthInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *BasicAuthInterfaceMock) Create(in1 *v3.BasicAuth) (*v3.BasicAuth, error) { + if mock.CreateFunc == nil { + panic("BasicAuthInterfaceMock.CreateFunc: method is nil but BasicAuthInterface.Create was just called") + } + callInfo := struct { + In1 *v3.BasicAuth + }{ + In1: in1, + } + lockBasicAuthInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockBasicAuthInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedBasicAuthInterface.CreateCalls()) +func (mock *BasicAuthInterfaceMock) CreateCalls() []struct { + In1 *v3.BasicAuth +} { + var calls []struct { + In1 *v3.BasicAuth + } + lockBasicAuthInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockBasicAuthInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *BasicAuthInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("BasicAuthInterfaceMock.DeleteFunc: method is nil but BasicAuthInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockBasicAuthInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockBasicAuthInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedBasicAuthInterface.DeleteCalls()) +func (mock *BasicAuthInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockBasicAuthInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockBasicAuthInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *BasicAuthInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("BasicAuthInterfaceMock.DeleteCollectionFunc: method is nil but BasicAuthInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockBasicAuthInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockBasicAuthInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedBasicAuthInterface.DeleteCollectionCalls()) +func (mock *BasicAuthInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockBasicAuthInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockBasicAuthInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *BasicAuthInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("BasicAuthInterfaceMock.DeleteNamespacedFunc: method is nil but BasicAuthInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockBasicAuthInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockBasicAuthInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedBasicAuthInterface.DeleteNamespacedCalls()) +func (mock *BasicAuthInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockBasicAuthInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockBasicAuthInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *BasicAuthInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { + if mock.GetFunc == nil { + panic("BasicAuthInterfaceMock.GetFunc: method is nil but BasicAuthInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockBasicAuthInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockBasicAuthInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedBasicAuthInterface.GetCalls()) +func (mock *BasicAuthInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockBasicAuthInterfaceMockGet.RLock() + calls = mock.calls.Get + lockBasicAuthInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *BasicAuthInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { + if mock.GetNamespacedFunc == nil { + panic("BasicAuthInterfaceMock.GetNamespacedFunc: method is nil but BasicAuthInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockBasicAuthInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockBasicAuthInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedBasicAuthInterface.GetNamespacedCalls()) +func (mock *BasicAuthInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockBasicAuthInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockBasicAuthInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *BasicAuthInterfaceMock) List(opts metav1.ListOptions) (*v3.BasicAuthList, error) { + if mock.ListFunc == nil { + panic("BasicAuthInterfaceMock.ListFunc: method is nil but BasicAuthInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockBasicAuthInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockBasicAuthInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedBasicAuthInterface.ListCalls()) +func (mock *BasicAuthInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockBasicAuthInterfaceMockList.RLock() + calls = mock.calls.List + lockBasicAuthInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *BasicAuthInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.BasicAuthList, error) { + if mock.ListNamespacedFunc == nil { + panic("BasicAuthInterfaceMock.ListNamespacedFunc: method is nil but BasicAuthInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockBasicAuthInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockBasicAuthInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedBasicAuthInterface.ListNamespacedCalls()) +func (mock *BasicAuthInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockBasicAuthInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockBasicAuthInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *BasicAuthInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("BasicAuthInterfaceMock.ObjectClientFunc: method is nil but BasicAuthInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockBasicAuthInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockBasicAuthInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedBasicAuthInterface.ObjectClientCalls()) +func (mock *BasicAuthInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockBasicAuthInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockBasicAuthInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *BasicAuthInterfaceMock) Update(in1 *v3.BasicAuth) (*v3.BasicAuth, error) { + if mock.UpdateFunc == nil { + panic("BasicAuthInterfaceMock.UpdateFunc: method is nil but BasicAuthInterface.Update was just called") + } + callInfo := struct { + In1 *v3.BasicAuth + }{ + In1: in1, + } + lockBasicAuthInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockBasicAuthInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedBasicAuthInterface.UpdateCalls()) +func (mock *BasicAuthInterfaceMock) UpdateCalls() []struct { + In1 *v3.BasicAuth +} { + var calls []struct { + In1 *v3.BasicAuth + } + lockBasicAuthInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockBasicAuthInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *BasicAuthInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("BasicAuthInterfaceMock.WatchFunc: method is nil but BasicAuthInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockBasicAuthInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockBasicAuthInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedBasicAuthInterface.WatchCalls()) +func (mock *BasicAuthInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockBasicAuthInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockBasicAuthInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockBasicAuthsGetterMockBasicAuths sync.RWMutex +) + +// Ensure, that BasicAuthsGetterMock does implement v31.BasicAuthsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.BasicAuthsGetter = &BasicAuthsGetterMock{} + +// BasicAuthsGetterMock is a mock implementation of v31.BasicAuthsGetter. +// +// func TestSomethingThatUsesBasicAuthsGetter(t *testing.T) { +// +// // make and configure a mocked v31.BasicAuthsGetter +// mockedBasicAuthsGetter := &BasicAuthsGetterMock{ +// BasicAuthsFunc: func(namespace string) v31.BasicAuthInterface { +// panic("mock out the BasicAuths method") +// }, +// } +// +// // use mockedBasicAuthsGetter in code that requires v31.BasicAuthsGetter +// // and then make assertions. +// +// } +type BasicAuthsGetterMock struct { + // BasicAuthsFunc mocks the BasicAuths method. + BasicAuthsFunc func(namespace string) v31.BasicAuthInterface + + // calls tracks calls to the methods. + calls struct { + // BasicAuths holds details about calls to the BasicAuths method. + BasicAuths []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// BasicAuths calls BasicAuthsFunc. +func (mock *BasicAuthsGetterMock) BasicAuths(namespace string) v31.BasicAuthInterface { + if mock.BasicAuthsFunc == nil { + panic("BasicAuthsGetterMock.BasicAuthsFunc: method is nil but BasicAuthsGetter.BasicAuths was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockBasicAuthsGetterMockBasicAuths.Lock() + mock.calls.BasicAuths = append(mock.calls.BasicAuths, callInfo) + lockBasicAuthsGetterMockBasicAuths.Unlock() + return mock.BasicAuthsFunc(namespace) +} + +// BasicAuthsCalls gets all the calls that were made to BasicAuths. +// Check the length with: +// +// len(mockedBasicAuthsGetter.BasicAuthsCalls()) +func (mock *BasicAuthsGetterMock) BasicAuthsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockBasicAuthsGetterMockBasicAuths.RLock() + calls = mock.calls.BasicAuths + lockBasicAuthsGetterMockBasicAuths.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_certificate_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_certificate_mock.go new file mode 100644 index 0000000..14e1780 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_certificate_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockCertificateListerMockGet sync.RWMutex + lockCertificateListerMockList sync.RWMutex +) + +// Ensure, that CertificateListerMock does implement v31.CertificateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.CertificateLister = &CertificateListerMock{} + +// CertificateListerMock is a mock implementation of v31.CertificateLister. +// +// func TestSomethingThatUsesCertificateLister(t *testing.T) { +// +// // make and configure a mocked v31.CertificateLister +// mockedCertificateLister := &CertificateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Certificate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Certificate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedCertificateLister in code that requires v31.CertificateLister +// // and then make assertions. +// +// } +type CertificateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Certificate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Certificate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *CertificateListerMock) Get(namespace string, name string) (*v3.Certificate, error) { + if mock.GetFunc == nil { + panic("CertificateListerMock.GetFunc: method is nil but CertificateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCertificateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCertificateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCertificateLister.GetCalls()) +func (mock *CertificateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCertificateListerMockGet.RLock() + calls = mock.calls.Get + lockCertificateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CertificateListerMock) List(namespace string, selector labels.Selector) ([]*v3.Certificate, error) { + if mock.ListFunc == nil { + panic("CertificateListerMock.ListFunc: method is nil but CertificateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockCertificateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCertificateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCertificateLister.ListCalls()) +func (mock *CertificateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockCertificateListerMockList.RLock() + calls = mock.calls.List + lockCertificateListerMockList.RUnlock() + return calls +} + +var ( + lockCertificateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockCertificateControllerMockAddClusterScopedHandler sync.RWMutex + lockCertificateControllerMockAddFeatureHandler sync.RWMutex + lockCertificateControllerMockAddHandler sync.RWMutex + lockCertificateControllerMockEnqueue sync.RWMutex + lockCertificateControllerMockEnqueueAfter sync.RWMutex + lockCertificateControllerMockGeneric sync.RWMutex + lockCertificateControllerMockInformer sync.RWMutex + lockCertificateControllerMockLister sync.RWMutex +) + +// Ensure, that CertificateControllerMock does implement v31.CertificateController. +// If this is not the case, regenerate this file with moq. +var _ v31.CertificateController = &CertificateControllerMock{} + +// CertificateControllerMock is a mock implementation of v31.CertificateController. +// +// func TestSomethingThatUsesCertificateController(t *testing.T) { +// +// // make and configure a mocked v31.CertificateController +// mockedCertificateController := &CertificateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CertificateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.CertificateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.CertificateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.CertificateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedCertificateController in code that requires v31.CertificateController +// // and then make assertions. +// +// } +type CertificateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CertificateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.CertificateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.CertificateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.CertificateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CertificateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.CertificateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CertificateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.CertificateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CertificateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.CertificateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CertificateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but CertificateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCertificateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCertificateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCertificateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *CertificateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.CertificateHandlerFunc + } + lockCertificateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCertificateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CertificateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.CertificateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CertificateControllerMock.AddClusterScopedHandlerFunc: method is nil but CertificateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockCertificateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCertificateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCertificateController.AddClusterScopedHandlerCalls()) +func (mock *CertificateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.CertificateHandlerFunc + } + lockCertificateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCertificateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CertificateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CertificateControllerMock.AddFeatureHandlerFunc: method is nil but CertificateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCertificateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCertificateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCertificateController.AddFeatureHandlerCalls()) +func (mock *CertificateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc + } + lockCertificateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCertificateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CertificateControllerMock) AddHandler(ctx context.Context, name string, handler v31.CertificateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CertificateControllerMock.AddHandlerFunc: method is nil but CertificateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockCertificateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCertificateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCertificateController.AddHandlerCalls()) +func (mock *CertificateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.CertificateHandlerFunc + } + lockCertificateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCertificateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *CertificateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("CertificateControllerMock.EnqueueFunc: method is nil but CertificateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockCertificateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockCertificateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedCertificateController.EnqueueCalls()) +func (mock *CertificateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockCertificateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockCertificateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *CertificateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("CertificateControllerMock.EnqueueAfterFunc: method is nil but CertificateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockCertificateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockCertificateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedCertificateController.EnqueueAfterCalls()) +func (mock *CertificateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockCertificateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockCertificateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *CertificateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("CertificateControllerMock.GenericFunc: method is nil but CertificateController.Generic was just called") + } + callInfo := struct { + }{} + lockCertificateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockCertificateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedCertificateController.GenericCalls()) +func (mock *CertificateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockCertificateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockCertificateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *CertificateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("CertificateControllerMock.InformerFunc: method is nil but CertificateController.Informer was just called") + } + callInfo := struct { + }{} + lockCertificateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockCertificateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedCertificateController.InformerCalls()) +func (mock *CertificateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockCertificateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockCertificateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *CertificateControllerMock) Lister() v31.CertificateLister { + if mock.ListerFunc == nil { + panic("CertificateControllerMock.ListerFunc: method is nil but CertificateController.Lister was just called") + } + callInfo := struct { + }{} + lockCertificateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockCertificateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedCertificateController.ListerCalls()) +func (mock *CertificateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockCertificateControllerMockLister.RLock() + calls = mock.calls.Lister + lockCertificateControllerMockLister.RUnlock() + return calls +} + +var ( + lockCertificateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockCertificateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockCertificateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockCertificateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockCertificateInterfaceMockAddFeatureHandler sync.RWMutex + lockCertificateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockCertificateInterfaceMockAddHandler sync.RWMutex + lockCertificateInterfaceMockAddLifecycle sync.RWMutex + lockCertificateInterfaceMockController sync.RWMutex + lockCertificateInterfaceMockCreate sync.RWMutex + lockCertificateInterfaceMockDelete sync.RWMutex + lockCertificateInterfaceMockDeleteCollection sync.RWMutex + lockCertificateInterfaceMockDeleteNamespaced sync.RWMutex + lockCertificateInterfaceMockGet sync.RWMutex + lockCertificateInterfaceMockGetNamespaced sync.RWMutex + lockCertificateInterfaceMockList sync.RWMutex + lockCertificateInterfaceMockListNamespaced sync.RWMutex + lockCertificateInterfaceMockObjectClient sync.RWMutex + lockCertificateInterfaceMockUpdate sync.RWMutex + lockCertificateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that CertificateInterfaceMock does implement v31.CertificateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.CertificateInterface = &CertificateInterfaceMock{} + +// CertificateInterfaceMock is a mock implementation of v31.CertificateInterface. +// +// func TestSomethingThatUsesCertificateInterface(t *testing.T) { +// +// // make and configure a mocked v31.CertificateInterface +// mockedCertificateInterface := &CertificateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CertificateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.CertificateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CertificateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.CertificateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.CertificateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.CertificateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Certificate) (*v3.Certificate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Certificate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Certificate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.CertificateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.CertificateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Certificate) (*v3.Certificate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedCertificateInterface in code that requires v31.CertificateInterface +// // and then make assertions. +// +// } +type CertificateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CertificateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.CertificateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.CertificateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.CertificateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.CertificateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.CertificateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Certificate) (*v3.Certificate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Certificate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Certificate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.CertificateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.CertificateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Certificate) (*v3.Certificate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CertificateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CertificateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.CertificateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CertificateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CertificateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CertificateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.CertificateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.CertificateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Certificate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Certificate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *CertificateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("CertificateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but CertificateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCertificateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockCertificateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedCertificateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *CertificateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.CertificateHandlerFunc + } + lockCertificateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockCertificateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *CertificateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.CertificateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("CertificateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but CertificateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCertificateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockCertificateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedCertificateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *CertificateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle + } + lockCertificateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockCertificateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *CertificateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.CertificateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("CertificateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but CertificateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockCertificateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockCertificateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedCertificateInterface.AddClusterScopedHandlerCalls()) +func (mock *CertificateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.CertificateHandlerFunc + } + lockCertificateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockCertificateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *CertificateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.CertificateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("CertificateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but CertificateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockCertificateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockCertificateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedCertificateInterface.AddClusterScopedLifecycleCalls()) +func (mock *CertificateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.CertificateLifecycle + } + lockCertificateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockCertificateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *CertificateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.CertificateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("CertificateInterfaceMock.AddFeatureHandlerFunc: method is nil but CertificateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockCertificateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockCertificateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedCertificateInterface.AddFeatureHandlerCalls()) +func (mock *CertificateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.CertificateHandlerFunc + } + lockCertificateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockCertificateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *CertificateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.CertificateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("CertificateInterfaceMock.AddFeatureLifecycleFunc: method is nil but CertificateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CertificateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockCertificateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockCertificateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedCertificateInterface.AddFeatureLifecycleCalls()) +func (mock *CertificateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.CertificateLifecycle + } + lockCertificateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockCertificateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *CertificateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.CertificateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("CertificateInterfaceMock.AddHandlerFunc: method is nil but CertificateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.CertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockCertificateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockCertificateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedCertificateInterface.AddHandlerCalls()) +func (mock *CertificateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.CertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.CertificateHandlerFunc + } + lockCertificateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockCertificateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *CertificateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.CertificateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("CertificateInterfaceMock.AddLifecycleFunc: method is nil but CertificateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.CertificateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockCertificateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockCertificateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedCertificateInterface.AddLifecycleCalls()) +func (mock *CertificateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.CertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.CertificateLifecycle + } + lockCertificateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockCertificateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *CertificateInterfaceMock) Controller() v31.CertificateController { + if mock.ControllerFunc == nil { + panic("CertificateInterfaceMock.ControllerFunc: method is nil but CertificateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockCertificateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockCertificateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedCertificateInterface.ControllerCalls()) +func (mock *CertificateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockCertificateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockCertificateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *CertificateInterfaceMock) Create(in1 *v3.Certificate) (*v3.Certificate, error) { + if mock.CreateFunc == nil { + panic("CertificateInterfaceMock.CreateFunc: method is nil but CertificateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Certificate + }{ + In1: in1, + } + lockCertificateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockCertificateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedCertificateInterface.CreateCalls()) +func (mock *CertificateInterfaceMock) CreateCalls() []struct { + In1 *v3.Certificate +} { + var calls []struct { + In1 *v3.Certificate + } + lockCertificateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockCertificateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *CertificateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("CertificateInterfaceMock.DeleteFunc: method is nil but CertificateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockCertificateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockCertificateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedCertificateInterface.DeleteCalls()) +func (mock *CertificateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockCertificateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockCertificateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *CertificateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("CertificateInterfaceMock.DeleteCollectionFunc: method is nil but CertificateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockCertificateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockCertificateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedCertificateInterface.DeleteCollectionCalls()) +func (mock *CertificateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockCertificateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockCertificateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *CertificateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("CertificateInterfaceMock.DeleteNamespacedFunc: method is nil but CertificateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockCertificateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockCertificateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedCertificateInterface.DeleteNamespacedCalls()) +func (mock *CertificateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockCertificateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockCertificateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *CertificateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Certificate, error) { + if mock.GetFunc == nil { + panic("CertificateInterfaceMock.GetFunc: method is nil but CertificateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockCertificateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockCertificateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedCertificateInterface.GetCalls()) +func (mock *CertificateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockCertificateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockCertificateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *CertificateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Certificate, error) { + if mock.GetNamespacedFunc == nil { + panic("CertificateInterfaceMock.GetNamespacedFunc: method is nil but CertificateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockCertificateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockCertificateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedCertificateInterface.GetNamespacedCalls()) +func (mock *CertificateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockCertificateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockCertificateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *CertificateInterfaceMock) List(opts metav1.ListOptions) (*v3.CertificateList, error) { + if mock.ListFunc == nil { + panic("CertificateInterfaceMock.ListFunc: method is nil but CertificateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCertificateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockCertificateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedCertificateInterface.ListCalls()) +func (mock *CertificateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCertificateInterfaceMockList.RLock() + calls = mock.calls.List + lockCertificateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *CertificateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CertificateList, error) { + if mock.ListNamespacedFunc == nil { + panic("CertificateInterfaceMock.ListNamespacedFunc: method is nil but CertificateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockCertificateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockCertificateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedCertificateInterface.ListNamespacedCalls()) +func (mock *CertificateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockCertificateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockCertificateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *CertificateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("CertificateInterfaceMock.ObjectClientFunc: method is nil but CertificateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockCertificateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockCertificateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedCertificateInterface.ObjectClientCalls()) +func (mock *CertificateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockCertificateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockCertificateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *CertificateInterfaceMock) Update(in1 *v3.Certificate) (*v3.Certificate, error) { + if mock.UpdateFunc == nil { + panic("CertificateInterfaceMock.UpdateFunc: method is nil but CertificateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Certificate + }{ + In1: in1, + } + lockCertificateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockCertificateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedCertificateInterface.UpdateCalls()) +func (mock *CertificateInterfaceMock) UpdateCalls() []struct { + In1 *v3.Certificate +} { + var calls []struct { + In1 *v3.Certificate + } + lockCertificateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockCertificateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *CertificateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("CertificateInterfaceMock.WatchFunc: method is nil but CertificateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockCertificateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockCertificateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedCertificateInterface.WatchCalls()) +func (mock *CertificateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockCertificateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockCertificateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockCertificatesGetterMockCertificates sync.RWMutex +) + +// Ensure, that CertificatesGetterMock does implement v31.CertificatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.CertificatesGetter = &CertificatesGetterMock{} + +// CertificatesGetterMock is a mock implementation of v31.CertificatesGetter. +// +// func TestSomethingThatUsesCertificatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.CertificatesGetter +// mockedCertificatesGetter := &CertificatesGetterMock{ +// CertificatesFunc: func(namespace string) v31.CertificateInterface { +// panic("mock out the Certificates method") +// }, +// } +// +// // use mockedCertificatesGetter in code that requires v31.CertificatesGetter +// // and then make assertions. +// +// } +type CertificatesGetterMock struct { + // CertificatesFunc mocks the Certificates method. + CertificatesFunc func(namespace string) v31.CertificateInterface + + // calls tracks calls to the methods. + calls struct { + // Certificates holds details about calls to the Certificates method. + Certificates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Certificates calls CertificatesFunc. +func (mock *CertificatesGetterMock) Certificates(namespace string) v31.CertificateInterface { + if mock.CertificatesFunc == nil { + panic("CertificatesGetterMock.CertificatesFunc: method is nil but CertificatesGetter.Certificates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockCertificatesGetterMockCertificates.Lock() + mock.calls.Certificates = append(mock.calls.Certificates, callInfo) + lockCertificatesGetterMockCertificates.Unlock() + return mock.CertificatesFunc(namespace) +} + +// CertificatesCalls gets all the calls that were made to Certificates. +// Check the length with: +// +// len(mockedCertificatesGetter.CertificatesCalls()) +func (mock *CertificatesGetterMock) CertificatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockCertificatesGetterMockCertificates.RLock() + calls = mock.calls.Certificates + lockCertificatesGetterMockCertificates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_docker_credential_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_docker_credential_mock.go new file mode 100644 index 0000000..99da7d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_docker_credential_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockDockerCredentialListerMockGet sync.RWMutex + lockDockerCredentialListerMockList sync.RWMutex +) + +// Ensure, that DockerCredentialListerMock does implement v31.DockerCredentialLister. +// If this is not the case, regenerate this file with moq. +var _ v31.DockerCredentialLister = &DockerCredentialListerMock{} + +// DockerCredentialListerMock is a mock implementation of v31.DockerCredentialLister. +// +// func TestSomethingThatUsesDockerCredentialLister(t *testing.T) { +// +// // make and configure a mocked v31.DockerCredentialLister +// mockedDockerCredentialLister := &DockerCredentialListerMock{ +// GetFunc: func(namespace string, name string) (*v3.DockerCredential, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.DockerCredential, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedDockerCredentialLister in code that requires v31.DockerCredentialLister +// // and then make assertions. +// +// } +type DockerCredentialListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.DockerCredential, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.DockerCredential, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *DockerCredentialListerMock) Get(namespace string, name string) (*v3.DockerCredential, error) { + if mock.GetFunc == nil { + panic("DockerCredentialListerMock.GetFunc: method is nil but DockerCredentialLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDockerCredentialListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDockerCredentialListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDockerCredentialLister.GetCalls()) +func (mock *DockerCredentialListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDockerCredentialListerMockGet.RLock() + calls = mock.calls.Get + lockDockerCredentialListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DockerCredentialListerMock) List(namespace string, selector labels.Selector) ([]*v3.DockerCredential, error) { + if mock.ListFunc == nil { + panic("DockerCredentialListerMock.ListFunc: method is nil but DockerCredentialLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockDockerCredentialListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDockerCredentialListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDockerCredentialLister.ListCalls()) +func (mock *DockerCredentialListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockDockerCredentialListerMockList.RLock() + calls = mock.calls.List + lockDockerCredentialListerMockList.RUnlock() + return calls +} + +var ( + lockDockerCredentialControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockDockerCredentialControllerMockAddClusterScopedHandler sync.RWMutex + lockDockerCredentialControllerMockAddFeatureHandler sync.RWMutex + lockDockerCredentialControllerMockAddHandler sync.RWMutex + lockDockerCredentialControllerMockEnqueue sync.RWMutex + lockDockerCredentialControllerMockEnqueueAfter sync.RWMutex + lockDockerCredentialControllerMockGeneric sync.RWMutex + lockDockerCredentialControllerMockInformer sync.RWMutex + lockDockerCredentialControllerMockLister sync.RWMutex +) + +// Ensure, that DockerCredentialControllerMock does implement v31.DockerCredentialController. +// If this is not the case, regenerate this file with moq. +var _ v31.DockerCredentialController = &DockerCredentialControllerMock{} + +// DockerCredentialControllerMock is a mock implementation of v31.DockerCredentialController. +// +// func TestSomethingThatUsesDockerCredentialController(t *testing.T) { +// +// // make and configure a mocked v31.DockerCredentialController +// mockedDockerCredentialController := &DockerCredentialControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.DockerCredentialLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedDockerCredentialController in code that requires v31.DockerCredentialController +// // and then make assertions. +// +// } +type DockerCredentialControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.DockerCredentialHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.DockerCredentialLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.DockerCredentialHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.DockerCredentialHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DockerCredentialHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.DockerCredentialHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DockerCredentialControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DockerCredentialControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but DockerCredentialController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDockerCredentialControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDockerCredentialControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDockerCredentialController.AddClusterScopedFeatureHandlerCalls()) +func (mock *DockerCredentialControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc + } + lockDockerCredentialControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDockerCredentialControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DockerCredentialControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.DockerCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DockerCredentialControllerMock.AddClusterScopedHandlerFunc: method is nil but DockerCredentialController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockDockerCredentialControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDockerCredentialControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDockerCredentialController.AddClusterScopedHandlerCalls()) +func (mock *DockerCredentialControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.DockerCredentialHandlerFunc + } + lockDockerCredentialControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDockerCredentialControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DockerCredentialControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DockerCredentialControllerMock.AddFeatureHandlerFunc: method is nil but DockerCredentialController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDockerCredentialControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDockerCredentialControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDockerCredentialController.AddFeatureHandlerCalls()) +func (mock *DockerCredentialControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc + } + lockDockerCredentialControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDockerCredentialControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DockerCredentialControllerMock) AddHandler(ctx context.Context, name string, handler v31.DockerCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DockerCredentialControllerMock.AddHandlerFunc: method is nil but DockerCredentialController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockDockerCredentialControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDockerCredentialControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDockerCredentialController.AddHandlerCalls()) +func (mock *DockerCredentialControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.DockerCredentialHandlerFunc + } + lockDockerCredentialControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDockerCredentialControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *DockerCredentialControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("DockerCredentialControllerMock.EnqueueFunc: method is nil but DockerCredentialController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockDockerCredentialControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockDockerCredentialControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedDockerCredentialController.EnqueueCalls()) +func (mock *DockerCredentialControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockDockerCredentialControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockDockerCredentialControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *DockerCredentialControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("DockerCredentialControllerMock.EnqueueAfterFunc: method is nil but DockerCredentialController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockDockerCredentialControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockDockerCredentialControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedDockerCredentialController.EnqueueAfterCalls()) +func (mock *DockerCredentialControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockDockerCredentialControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockDockerCredentialControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *DockerCredentialControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("DockerCredentialControllerMock.GenericFunc: method is nil but DockerCredentialController.Generic was just called") + } + callInfo := struct { + }{} + lockDockerCredentialControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockDockerCredentialControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedDockerCredentialController.GenericCalls()) +func (mock *DockerCredentialControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockDockerCredentialControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockDockerCredentialControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *DockerCredentialControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("DockerCredentialControllerMock.InformerFunc: method is nil but DockerCredentialController.Informer was just called") + } + callInfo := struct { + }{} + lockDockerCredentialControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockDockerCredentialControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedDockerCredentialController.InformerCalls()) +func (mock *DockerCredentialControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockDockerCredentialControllerMockInformer.RLock() + calls = mock.calls.Informer + lockDockerCredentialControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *DockerCredentialControllerMock) Lister() v31.DockerCredentialLister { + if mock.ListerFunc == nil { + panic("DockerCredentialControllerMock.ListerFunc: method is nil but DockerCredentialController.Lister was just called") + } + callInfo := struct { + }{} + lockDockerCredentialControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockDockerCredentialControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedDockerCredentialController.ListerCalls()) +func (mock *DockerCredentialControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockDockerCredentialControllerMockLister.RLock() + calls = mock.calls.Lister + lockDockerCredentialControllerMockLister.RUnlock() + return calls +} + +var ( + lockDockerCredentialInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockDockerCredentialInterfaceMockAddClusterScopedHandler sync.RWMutex + lockDockerCredentialInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockDockerCredentialInterfaceMockAddFeatureHandler sync.RWMutex + lockDockerCredentialInterfaceMockAddFeatureLifecycle sync.RWMutex + lockDockerCredentialInterfaceMockAddHandler sync.RWMutex + lockDockerCredentialInterfaceMockAddLifecycle sync.RWMutex + lockDockerCredentialInterfaceMockController sync.RWMutex + lockDockerCredentialInterfaceMockCreate sync.RWMutex + lockDockerCredentialInterfaceMockDelete sync.RWMutex + lockDockerCredentialInterfaceMockDeleteCollection sync.RWMutex + lockDockerCredentialInterfaceMockDeleteNamespaced sync.RWMutex + lockDockerCredentialInterfaceMockGet sync.RWMutex + lockDockerCredentialInterfaceMockGetNamespaced sync.RWMutex + lockDockerCredentialInterfaceMockList sync.RWMutex + lockDockerCredentialInterfaceMockListNamespaced sync.RWMutex + lockDockerCredentialInterfaceMockObjectClient sync.RWMutex + lockDockerCredentialInterfaceMockUpdate sync.RWMutex + lockDockerCredentialInterfaceMockWatch sync.RWMutex +) + +// Ensure, that DockerCredentialInterfaceMock does implement v31.DockerCredentialInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.DockerCredentialInterface = &DockerCredentialInterfaceMock{} + +// DockerCredentialInterfaceMock is a mock implementation of v31.DockerCredentialInterface. +// +// func TestSomethingThatUsesDockerCredentialInterface(t *testing.T) { +// +// // make and configure a mocked v31.DockerCredentialInterface +// mockedDockerCredentialInterface := &DockerCredentialInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.DockerCredentialLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.DockerCredentialLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.DockerCredentialController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.DockerCredential) (*v3.DockerCredential, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.DockerCredentialList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.DockerCredentialList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.DockerCredential) (*v3.DockerCredential, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedDockerCredentialInterface in code that requires v31.DockerCredentialInterface +// // and then make assertions. +// +// } +type DockerCredentialInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.DockerCredentialLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.DockerCredentialHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.DockerCredentialLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.DockerCredentialController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.DockerCredential) (*v3.DockerCredential, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.DockerCredential, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.DockerCredential, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.DockerCredentialList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.DockerCredentialList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.DockerCredential) (*v3.DockerCredential, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.DockerCredentialHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DockerCredentialLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.DockerCredentialHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DockerCredentialLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DockerCredentialHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DockerCredentialLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.DockerCredentialHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.DockerCredentialLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.DockerCredential + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.DockerCredential + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *DockerCredentialInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("DockerCredentialInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but DockerCredentialInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *DockerCredentialInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc + } + lockDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *DockerCredentialInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("DockerCredentialInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but DockerCredentialInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *DockerCredentialInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle + } + lockDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *DockerCredentialInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.DockerCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("DockerCredentialInterfaceMock.AddClusterScopedHandlerFunc: method is nil but DockerCredentialInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockDockerCredentialInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockDockerCredentialInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddClusterScopedHandlerCalls()) +func (mock *DockerCredentialInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.DockerCredentialHandlerFunc + } + lockDockerCredentialInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockDockerCredentialInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *DockerCredentialInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.DockerCredentialLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("DockerCredentialInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but DockerCredentialInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockDockerCredentialInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockDockerCredentialInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddClusterScopedLifecycleCalls()) +func (mock *DockerCredentialInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.DockerCredentialLifecycle + } + lockDockerCredentialInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockDockerCredentialInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *DockerCredentialInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("DockerCredentialInterfaceMock.AddFeatureHandlerFunc: method is nil but DockerCredentialInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockDockerCredentialInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockDockerCredentialInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddFeatureHandlerCalls()) +func (mock *DockerCredentialInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.DockerCredentialHandlerFunc + } + lockDockerCredentialInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockDockerCredentialInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *DockerCredentialInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.DockerCredentialLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("DockerCredentialInterfaceMock.AddFeatureLifecycleFunc: method is nil but DockerCredentialInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DockerCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockDockerCredentialInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockDockerCredentialInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddFeatureLifecycleCalls()) +func (mock *DockerCredentialInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.DockerCredentialLifecycle + } + lockDockerCredentialInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockDockerCredentialInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *DockerCredentialInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.DockerCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("DockerCredentialInterfaceMock.AddHandlerFunc: method is nil but DockerCredentialInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.DockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockDockerCredentialInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockDockerCredentialInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddHandlerCalls()) +func (mock *DockerCredentialInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.DockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.DockerCredentialHandlerFunc + } + lockDockerCredentialInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockDockerCredentialInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *DockerCredentialInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.DockerCredentialLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("DockerCredentialInterfaceMock.AddLifecycleFunc: method is nil but DockerCredentialInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.DockerCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockDockerCredentialInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockDockerCredentialInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedDockerCredentialInterface.AddLifecycleCalls()) +func (mock *DockerCredentialInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.DockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.DockerCredentialLifecycle + } + lockDockerCredentialInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockDockerCredentialInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *DockerCredentialInterfaceMock) Controller() v31.DockerCredentialController { + if mock.ControllerFunc == nil { + panic("DockerCredentialInterfaceMock.ControllerFunc: method is nil but DockerCredentialInterface.Controller was just called") + } + callInfo := struct { + }{} + lockDockerCredentialInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockDockerCredentialInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedDockerCredentialInterface.ControllerCalls()) +func (mock *DockerCredentialInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockDockerCredentialInterfaceMockController.RLock() + calls = mock.calls.Controller + lockDockerCredentialInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *DockerCredentialInterfaceMock) Create(in1 *v3.DockerCredential) (*v3.DockerCredential, error) { + if mock.CreateFunc == nil { + panic("DockerCredentialInterfaceMock.CreateFunc: method is nil but DockerCredentialInterface.Create was just called") + } + callInfo := struct { + In1 *v3.DockerCredential + }{ + In1: in1, + } + lockDockerCredentialInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockDockerCredentialInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedDockerCredentialInterface.CreateCalls()) +func (mock *DockerCredentialInterfaceMock) CreateCalls() []struct { + In1 *v3.DockerCredential +} { + var calls []struct { + In1 *v3.DockerCredential + } + lockDockerCredentialInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockDockerCredentialInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *DockerCredentialInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("DockerCredentialInterfaceMock.DeleteFunc: method is nil but DockerCredentialInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockDockerCredentialInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockDockerCredentialInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedDockerCredentialInterface.DeleteCalls()) +func (mock *DockerCredentialInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockDockerCredentialInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockDockerCredentialInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *DockerCredentialInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("DockerCredentialInterfaceMock.DeleteCollectionFunc: method is nil but DockerCredentialInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockDockerCredentialInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockDockerCredentialInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedDockerCredentialInterface.DeleteCollectionCalls()) +func (mock *DockerCredentialInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockDockerCredentialInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockDockerCredentialInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *DockerCredentialInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("DockerCredentialInterfaceMock.DeleteNamespacedFunc: method is nil but DockerCredentialInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockDockerCredentialInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockDockerCredentialInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedDockerCredentialInterface.DeleteNamespacedCalls()) +func (mock *DockerCredentialInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockDockerCredentialInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockDockerCredentialInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *DockerCredentialInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { + if mock.GetFunc == nil { + panic("DockerCredentialInterfaceMock.GetFunc: method is nil but DockerCredentialInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockDockerCredentialInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockDockerCredentialInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedDockerCredentialInterface.GetCalls()) +func (mock *DockerCredentialInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockDockerCredentialInterfaceMockGet.RLock() + calls = mock.calls.Get + lockDockerCredentialInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *DockerCredentialInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { + if mock.GetNamespacedFunc == nil { + panic("DockerCredentialInterfaceMock.GetNamespacedFunc: method is nil but DockerCredentialInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockDockerCredentialInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockDockerCredentialInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedDockerCredentialInterface.GetNamespacedCalls()) +func (mock *DockerCredentialInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockDockerCredentialInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockDockerCredentialInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *DockerCredentialInterfaceMock) List(opts metav1.ListOptions) (*v3.DockerCredentialList, error) { + if mock.ListFunc == nil { + panic("DockerCredentialInterfaceMock.ListFunc: method is nil but DockerCredentialInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDockerCredentialInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockDockerCredentialInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedDockerCredentialInterface.ListCalls()) +func (mock *DockerCredentialInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDockerCredentialInterfaceMockList.RLock() + calls = mock.calls.List + lockDockerCredentialInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *DockerCredentialInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DockerCredentialList, error) { + if mock.ListNamespacedFunc == nil { + panic("DockerCredentialInterfaceMock.ListNamespacedFunc: method is nil but DockerCredentialInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockDockerCredentialInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockDockerCredentialInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedDockerCredentialInterface.ListNamespacedCalls()) +func (mock *DockerCredentialInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockDockerCredentialInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockDockerCredentialInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *DockerCredentialInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("DockerCredentialInterfaceMock.ObjectClientFunc: method is nil but DockerCredentialInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockDockerCredentialInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockDockerCredentialInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedDockerCredentialInterface.ObjectClientCalls()) +func (mock *DockerCredentialInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockDockerCredentialInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockDockerCredentialInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *DockerCredentialInterfaceMock) Update(in1 *v3.DockerCredential) (*v3.DockerCredential, error) { + if mock.UpdateFunc == nil { + panic("DockerCredentialInterfaceMock.UpdateFunc: method is nil but DockerCredentialInterface.Update was just called") + } + callInfo := struct { + In1 *v3.DockerCredential + }{ + In1: in1, + } + lockDockerCredentialInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockDockerCredentialInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedDockerCredentialInterface.UpdateCalls()) +func (mock *DockerCredentialInterfaceMock) UpdateCalls() []struct { + In1 *v3.DockerCredential +} { + var calls []struct { + In1 *v3.DockerCredential + } + lockDockerCredentialInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockDockerCredentialInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *DockerCredentialInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("DockerCredentialInterfaceMock.WatchFunc: method is nil but DockerCredentialInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockDockerCredentialInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockDockerCredentialInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedDockerCredentialInterface.WatchCalls()) +func (mock *DockerCredentialInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockDockerCredentialInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockDockerCredentialInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockDockerCredentialsGetterMockDockerCredentials sync.RWMutex +) + +// Ensure, that DockerCredentialsGetterMock does implement v31.DockerCredentialsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.DockerCredentialsGetter = &DockerCredentialsGetterMock{} + +// DockerCredentialsGetterMock is a mock implementation of v31.DockerCredentialsGetter. +// +// func TestSomethingThatUsesDockerCredentialsGetter(t *testing.T) { +// +// // make and configure a mocked v31.DockerCredentialsGetter +// mockedDockerCredentialsGetter := &DockerCredentialsGetterMock{ +// DockerCredentialsFunc: func(namespace string) v31.DockerCredentialInterface { +// panic("mock out the DockerCredentials method") +// }, +// } +// +// // use mockedDockerCredentialsGetter in code that requires v31.DockerCredentialsGetter +// // and then make assertions. +// +// } +type DockerCredentialsGetterMock struct { + // DockerCredentialsFunc mocks the DockerCredentials method. + DockerCredentialsFunc func(namespace string) v31.DockerCredentialInterface + + // calls tracks calls to the methods. + calls struct { + // DockerCredentials holds details about calls to the DockerCredentials method. + DockerCredentials []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// DockerCredentials calls DockerCredentialsFunc. +func (mock *DockerCredentialsGetterMock) DockerCredentials(namespace string) v31.DockerCredentialInterface { + if mock.DockerCredentialsFunc == nil { + panic("DockerCredentialsGetterMock.DockerCredentialsFunc: method is nil but DockerCredentialsGetter.DockerCredentials was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockDockerCredentialsGetterMockDockerCredentials.Lock() + mock.calls.DockerCredentials = append(mock.calls.DockerCredentials, callInfo) + lockDockerCredentialsGetterMockDockerCredentials.Unlock() + return mock.DockerCredentialsFunc(namespace) +} + +// DockerCredentialsCalls gets all the calls that were made to DockerCredentials. +// Check the length with: +// +// len(mockedDockerCredentialsGetter.DockerCredentialsCalls()) +func (mock *DockerCredentialsGetterMock) DockerCredentialsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockDockerCredentialsGetterMockDockerCredentials.RLock() + calls = mock.calls.DockerCredentials + lockDockerCredentialsGetterMockDockerCredentials.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_basic_auth_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_basic_auth_mock.go new file mode 100644 index 0000000..6b9626a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_basic_auth_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespacedBasicAuthListerMockGet sync.RWMutex + lockNamespacedBasicAuthListerMockList sync.RWMutex +) + +// Ensure, that NamespacedBasicAuthListerMock does implement v31.NamespacedBasicAuthLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedBasicAuthLister = &NamespacedBasicAuthListerMock{} + +// NamespacedBasicAuthListerMock is a mock implementation of v31.NamespacedBasicAuthLister. +// +// func TestSomethingThatUsesNamespacedBasicAuthLister(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedBasicAuthLister +// mockedNamespacedBasicAuthLister := &NamespacedBasicAuthListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NamespacedBasicAuth, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NamespacedBasicAuth, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespacedBasicAuthLister in code that requires v31.NamespacedBasicAuthLister +// // and then make assertions. +// +// } +type NamespacedBasicAuthListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NamespacedBasicAuth, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NamespacedBasicAuth, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespacedBasicAuthListerMock) Get(namespace string, name string) (*v3.NamespacedBasicAuth, error) { + if mock.GetFunc == nil { + panic("NamespacedBasicAuthListerMock.GetFunc: method is nil but NamespacedBasicAuthLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedBasicAuthListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedBasicAuthListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedBasicAuthLister.GetCalls()) +func (mock *NamespacedBasicAuthListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedBasicAuthListerMockGet.RLock() + calls = mock.calls.Get + lockNamespacedBasicAuthListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedBasicAuthListerMock) List(namespace string, selector labels.Selector) ([]*v3.NamespacedBasicAuth, error) { + if mock.ListFunc == nil { + panic("NamespacedBasicAuthListerMock.ListFunc: method is nil but NamespacedBasicAuthLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespacedBasicAuthListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedBasicAuthListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedBasicAuthLister.ListCalls()) +func (mock *NamespacedBasicAuthListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespacedBasicAuthListerMockList.RLock() + calls = mock.calls.List + lockNamespacedBasicAuthListerMockList.RUnlock() + return calls +} + +var ( + lockNamespacedBasicAuthControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedBasicAuthControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespacedBasicAuthControllerMockAddFeatureHandler sync.RWMutex + lockNamespacedBasicAuthControllerMockAddHandler sync.RWMutex + lockNamespacedBasicAuthControllerMockEnqueue sync.RWMutex + lockNamespacedBasicAuthControllerMockEnqueueAfter sync.RWMutex + lockNamespacedBasicAuthControllerMockGeneric sync.RWMutex + lockNamespacedBasicAuthControllerMockInformer sync.RWMutex + lockNamespacedBasicAuthControllerMockLister sync.RWMutex +) + +// Ensure, that NamespacedBasicAuthControllerMock does implement v31.NamespacedBasicAuthController. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedBasicAuthController = &NamespacedBasicAuthControllerMock{} + +// NamespacedBasicAuthControllerMock is a mock implementation of v31.NamespacedBasicAuthController. +// +// func TestSomethingThatUsesNamespacedBasicAuthController(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedBasicAuthController +// mockedNamespacedBasicAuthController := &NamespacedBasicAuthControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NamespacedBasicAuthLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespacedBasicAuthController in code that requires v31.NamespacedBasicAuthController +// // and then make assertions. +// +// } +type NamespacedBasicAuthControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NamespacedBasicAuthHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NamespacedBasicAuthLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedBasicAuthHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedBasicAuthHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedBasicAuthHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NamespacedBasicAuthHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedBasicAuthControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedBasicAuthControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedBasicAuthController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedBasicAuthControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedBasicAuthControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedBasicAuthControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedBasicAuthControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedBasicAuthControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedBasicAuthControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespacedBasicAuthController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedBasicAuthControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedBasicAuthControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.AddClusterScopedHandlerCalls()) +func (mock *NamespacedBasicAuthControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedBasicAuthControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedBasicAuthControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedBasicAuthControllerMock.AddFeatureHandlerFunc: method is nil but NamespacedBasicAuthController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedBasicAuthControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedBasicAuthControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.AddFeatureHandlerCalls()) +func (mock *NamespacedBasicAuthControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedBasicAuthControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedBasicAuthControllerMock) AddHandler(ctx context.Context, name string, handler v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedBasicAuthControllerMock.AddHandlerFunc: method is nil but NamespacedBasicAuthController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespacedBasicAuthControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedBasicAuthControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.AddHandlerCalls()) +func (mock *NamespacedBasicAuthControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedBasicAuthControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespacedBasicAuthControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespacedBasicAuthControllerMock.EnqueueFunc: method is nil but NamespacedBasicAuthController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedBasicAuthControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespacedBasicAuthControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.EnqueueCalls()) +func (mock *NamespacedBasicAuthControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedBasicAuthControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespacedBasicAuthControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespacedBasicAuthControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespacedBasicAuthControllerMock.EnqueueAfterFunc: method is nil but NamespacedBasicAuthController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespacedBasicAuthControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespacedBasicAuthControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.EnqueueAfterCalls()) +func (mock *NamespacedBasicAuthControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespacedBasicAuthControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespacedBasicAuthControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespacedBasicAuthControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespacedBasicAuthControllerMock.GenericFunc: method is nil but NamespacedBasicAuthController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespacedBasicAuthControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespacedBasicAuthControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.GenericCalls()) +func (mock *NamespacedBasicAuthControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespacedBasicAuthControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespacedBasicAuthControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespacedBasicAuthControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespacedBasicAuthControllerMock.InformerFunc: method is nil but NamespacedBasicAuthController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespacedBasicAuthControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespacedBasicAuthControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.InformerCalls()) +func (mock *NamespacedBasicAuthControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedBasicAuthControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespacedBasicAuthControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespacedBasicAuthControllerMock) Lister() v31.NamespacedBasicAuthLister { + if mock.ListerFunc == nil { + panic("NamespacedBasicAuthControllerMock.ListerFunc: method is nil but NamespacedBasicAuthController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespacedBasicAuthControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespacedBasicAuthControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespacedBasicAuthController.ListerCalls()) +func (mock *NamespacedBasicAuthControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedBasicAuthControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespacedBasicAuthControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddHandler sync.RWMutex + lockNamespacedBasicAuthInterfaceMockAddLifecycle sync.RWMutex + lockNamespacedBasicAuthInterfaceMockController sync.RWMutex + lockNamespacedBasicAuthInterfaceMockCreate sync.RWMutex + lockNamespacedBasicAuthInterfaceMockDelete sync.RWMutex + lockNamespacedBasicAuthInterfaceMockDeleteCollection sync.RWMutex + lockNamespacedBasicAuthInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespacedBasicAuthInterfaceMockGet sync.RWMutex + lockNamespacedBasicAuthInterfaceMockGetNamespaced sync.RWMutex + lockNamespacedBasicAuthInterfaceMockList sync.RWMutex + lockNamespacedBasicAuthInterfaceMockListNamespaced sync.RWMutex + lockNamespacedBasicAuthInterfaceMockObjectClient sync.RWMutex + lockNamespacedBasicAuthInterfaceMockUpdate sync.RWMutex + lockNamespacedBasicAuthInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespacedBasicAuthInterfaceMock does implement v31.NamespacedBasicAuthInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedBasicAuthInterface = &NamespacedBasicAuthInterfaceMock{} + +// NamespacedBasicAuthInterfaceMock is a mock implementation of v31.NamespacedBasicAuthInterface. +// +// func TestSomethingThatUsesNamespacedBasicAuthInterface(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedBasicAuthInterface +// mockedNamespacedBasicAuthInterface := &NamespacedBasicAuthInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedBasicAuthLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NamespacedBasicAuthLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NamespacedBasicAuthController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespacedBasicAuthInterface in code that requires v31.NamespacedBasicAuthInterface +// // and then make assertions. +// +// } +type NamespacedBasicAuthInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedBasicAuthLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NamespacedBasicAuthLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NamespacedBasicAuthController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedBasicAuthHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedBasicAuthLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedBasicAuthHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedBasicAuthLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedBasicAuthHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedBasicAuthLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedBasicAuthHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedBasicAuthLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedBasicAuth + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedBasicAuth + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedBasicAuthInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespacedBasicAuthInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespacedBasicAuthInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespacedBasicAuthInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedBasicAuthInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedBasicAuthInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedBasicAuthLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespacedBasicAuthInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespacedBasicAuthInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedBasicAuthLifecycle + } + lockNamespacedBasicAuthInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespacedBasicAuthInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespacedBasicAuthInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedBasicAuthInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedBasicAuthInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddFeatureHandlerCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedBasicAuthInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedBasicAuthLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespacedBasicAuthInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedBasicAuthInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespacedBasicAuthInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddFeatureLifecycleCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle + } + lockNamespacedBasicAuthInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespacedBasicAuthInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NamespacedBasicAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddHandlerFunc: method is nil but NamespacedBasicAuthInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedBasicAuthInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedBasicAuthInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddHandlerCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NamespacedBasicAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NamespacedBasicAuthHandlerFunc + } + lockNamespacedBasicAuthInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedBasicAuthInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespacedBasicAuthInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NamespacedBasicAuthLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.AddLifecycleFunc: method is nil but NamespacedBasicAuthInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedBasicAuthInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespacedBasicAuthInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.AddLifecycleCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedBasicAuthLifecycle + } + lockNamespacedBasicAuthInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespacedBasicAuthInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Controller() v31.NamespacedBasicAuthController { + if mock.ControllerFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.ControllerFunc: method is nil but NamespacedBasicAuthInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespacedBasicAuthInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespacedBasicAuthInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.ControllerCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedBasicAuthInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespacedBasicAuthInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Create(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { + if mock.CreateFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.CreateFunc: method is nil but NamespacedBasicAuthInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NamespacedBasicAuth + }{ + In1: in1, + } + lockNamespacedBasicAuthInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespacedBasicAuthInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.CreateCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) CreateCalls() []struct { + In1 *v3.NamespacedBasicAuth +} { + var calls []struct { + In1 *v3.NamespacedBasicAuth + } + lockNamespacedBasicAuthInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespacedBasicAuthInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.DeleteFunc: method is nil but NamespacedBasicAuthInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespacedBasicAuthInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespacedBasicAuthInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.DeleteCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespacedBasicAuthInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespacedBasicAuthInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespacedBasicAuthInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.DeleteCollectionFunc: method is nil but NamespacedBasicAuthInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespacedBasicAuthInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespacedBasicAuthInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.DeleteCollectionCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespacedBasicAuthInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespacedBasicAuthInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespacedBasicAuthInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.DeleteNamespacedFunc: method is nil but NamespacedBasicAuthInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespacedBasicAuthInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespacedBasicAuthInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.DeleteNamespacedCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespacedBasicAuthInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespacedBasicAuthInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { + if mock.GetFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.GetFunc: method is nil but NamespacedBasicAuthInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespacedBasicAuthInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedBasicAuthInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.GetCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespacedBasicAuthInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespacedBasicAuthInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespacedBasicAuthInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.GetNamespacedFunc: method is nil but NamespacedBasicAuthInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespacedBasicAuthInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespacedBasicAuthInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.GetNamespacedCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespacedBasicAuthInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespacedBasicAuthInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedBasicAuthInterfaceMock) List(opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { + if mock.ListFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.ListFunc: method is nil but NamespacedBasicAuthInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedBasicAuthInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedBasicAuthInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.ListCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedBasicAuthInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespacedBasicAuthInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespacedBasicAuthInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.ListNamespacedFunc: method is nil but NamespacedBasicAuthInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespacedBasicAuthInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespacedBasicAuthInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.ListNamespacedCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespacedBasicAuthInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespacedBasicAuthInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespacedBasicAuthInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.ObjectClientFunc: method is nil but NamespacedBasicAuthInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespacedBasicAuthInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespacedBasicAuthInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.ObjectClientCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespacedBasicAuthInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespacedBasicAuthInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Update(in1 *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { + if mock.UpdateFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.UpdateFunc: method is nil but NamespacedBasicAuthInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NamespacedBasicAuth + }{ + In1: in1, + } + lockNamespacedBasicAuthInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespacedBasicAuthInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.UpdateCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) UpdateCalls() []struct { + In1 *v3.NamespacedBasicAuth +} { + var calls []struct { + In1 *v3.NamespacedBasicAuth + } + lockNamespacedBasicAuthInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespacedBasicAuthInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespacedBasicAuthInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespacedBasicAuthInterfaceMock.WatchFunc: method is nil but NamespacedBasicAuthInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedBasicAuthInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespacedBasicAuthInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespacedBasicAuthInterface.WatchCalls()) +func (mock *NamespacedBasicAuthInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedBasicAuthInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespacedBasicAuthInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacedBasicAuthsGetterMockNamespacedBasicAuths sync.RWMutex +) + +// Ensure, that NamespacedBasicAuthsGetterMock does implement v31.NamespacedBasicAuthsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedBasicAuthsGetter = &NamespacedBasicAuthsGetterMock{} + +// NamespacedBasicAuthsGetterMock is a mock implementation of v31.NamespacedBasicAuthsGetter. +// +// func TestSomethingThatUsesNamespacedBasicAuthsGetter(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedBasicAuthsGetter +// mockedNamespacedBasicAuthsGetter := &NamespacedBasicAuthsGetterMock{ +// NamespacedBasicAuthsFunc: func(namespace string) v31.NamespacedBasicAuthInterface { +// panic("mock out the NamespacedBasicAuths method") +// }, +// } +// +// // use mockedNamespacedBasicAuthsGetter in code that requires v31.NamespacedBasicAuthsGetter +// // and then make assertions. +// +// } +type NamespacedBasicAuthsGetterMock struct { + // NamespacedBasicAuthsFunc mocks the NamespacedBasicAuths method. + NamespacedBasicAuthsFunc func(namespace string) v31.NamespacedBasicAuthInterface + + // calls tracks calls to the methods. + calls struct { + // NamespacedBasicAuths holds details about calls to the NamespacedBasicAuths method. + NamespacedBasicAuths []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NamespacedBasicAuths calls NamespacedBasicAuthsFunc. +func (mock *NamespacedBasicAuthsGetterMock) NamespacedBasicAuths(namespace string) v31.NamespacedBasicAuthInterface { + if mock.NamespacedBasicAuthsFunc == nil { + panic("NamespacedBasicAuthsGetterMock.NamespacedBasicAuthsFunc: method is nil but NamespacedBasicAuthsGetter.NamespacedBasicAuths was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacedBasicAuthsGetterMockNamespacedBasicAuths.Lock() + mock.calls.NamespacedBasicAuths = append(mock.calls.NamespacedBasicAuths, callInfo) + lockNamespacedBasicAuthsGetterMockNamespacedBasicAuths.Unlock() + return mock.NamespacedBasicAuthsFunc(namespace) +} + +// NamespacedBasicAuthsCalls gets all the calls that were made to NamespacedBasicAuths. +// Check the length with: +// +// len(mockedNamespacedBasicAuthsGetter.NamespacedBasicAuthsCalls()) +func (mock *NamespacedBasicAuthsGetterMock) NamespacedBasicAuthsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacedBasicAuthsGetterMockNamespacedBasicAuths.RLock() + calls = mock.calls.NamespacedBasicAuths + lockNamespacedBasicAuthsGetterMockNamespacedBasicAuths.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_certificate_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_certificate_mock.go new file mode 100644 index 0000000..fe3c53d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_certificate_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespacedCertificateListerMockGet sync.RWMutex + lockNamespacedCertificateListerMockList sync.RWMutex +) + +// Ensure, that NamespacedCertificateListerMock does implement v31.NamespacedCertificateLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedCertificateLister = &NamespacedCertificateListerMock{} + +// NamespacedCertificateListerMock is a mock implementation of v31.NamespacedCertificateLister. +// +// func TestSomethingThatUsesNamespacedCertificateLister(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedCertificateLister +// mockedNamespacedCertificateLister := &NamespacedCertificateListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NamespacedCertificate, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NamespacedCertificate, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespacedCertificateLister in code that requires v31.NamespacedCertificateLister +// // and then make assertions. +// +// } +type NamespacedCertificateListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NamespacedCertificate, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NamespacedCertificate, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespacedCertificateListerMock) Get(namespace string, name string) (*v3.NamespacedCertificate, error) { + if mock.GetFunc == nil { + panic("NamespacedCertificateListerMock.GetFunc: method is nil but NamespacedCertificateLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedCertificateListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedCertificateListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedCertificateLister.GetCalls()) +func (mock *NamespacedCertificateListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedCertificateListerMockGet.RLock() + calls = mock.calls.Get + lockNamespacedCertificateListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedCertificateListerMock) List(namespace string, selector labels.Selector) ([]*v3.NamespacedCertificate, error) { + if mock.ListFunc == nil { + panic("NamespacedCertificateListerMock.ListFunc: method is nil but NamespacedCertificateLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespacedCertificateListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedCertificateListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedCertificateLister.ListCalls()) +func (mock *NamespacedCertificateListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespacedCertificateListerMockList.RLock() + calls = mock.calls.List + lockNamespacedCertificateListerMockList.RUnlock() + return calls +} + +var ( + lockNamespacedCertificateControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedCertificateControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespacedCertificateControllerMockAddFeatureHandler sync.RWMutex + lockNamespacedCertificateControllerMockAddHandler sync.RWMutex + lockNamespacedCertificateControllerMockEnqueue sync.RWMutex + lockNamespacedCertificateControllerMockEnqueueAfter sync.RWMutex + lockNamespacedCertificateControllerMockGeneric sync.RWMutex + lockNamespacedCertificateControllerMockInformer sync.RWMutex + lockNamespacedCertificateControllerMockLister sync.RWMutex +) + +// Ensure, that NamespacedCertificateControllerMock does implement v31.NamespacedCertificateController. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedCertificateController = &NamespacedCertificateControllerMock{} + +// NamespacedCertificateControllerMock is a mock implementation of v31.NamespacedCertificateController. +// +// func TestSomethingThatUsesNamespacedCertificateController(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedCertificateController +// mockedNamespacedCertificateController := &NamespacedCertificateControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NamespacedCertificateLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespacedCertificateController in code that requires v31.NamespacedCertificateController +// // and then make assertions. +// +// } +type NamespacedCertificateControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NamespacedCertificateHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NamespacedCertificateLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedCertificateHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedCertificateHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedCertificateHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NamespacedCertificateHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedCertificateControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedCertificateControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedCertificateController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedCertificateControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedCertificateControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedCertificateControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedCertificateControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedCertificateControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NamespacedCertificateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedCertificateControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespacedCertificateController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedCertificateControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedCertificateControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateController.AddClusterScopedHandlerCalls()) +func (mock *NamespacedCertificateControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedCertificateControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedCertificateControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedCertificateControllerMock.AddFeatureHandlerFunc: method is nil but NamespacedCertificateController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedCertificateControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedCertificateControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateController.AddFeatureHandlerCalls()) +func (mock *NamespacedCertificateControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedCertificateControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedCertificateControllerMock) AddHandler(ctx context.Context, name string, handler v31.NamespacedCertificateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedCertificateControllerMock.AddHandlerFunc: method is nil but NamespacedCertificateController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespacedCertificateControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedCertificateControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateController.AddHandlerCalls()) +func (mock *NamespacedCertificateControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedCertificateControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespacedCertificateControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespacedCertificateControllerMock.EnqueueFunc: method is nil but NamespacedCertificateController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedCertificateControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespacedCertificateControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespacedCertificateController.EnqueueCalls()) +func (mock *NamespacedCertificateControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedCertificateControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespacedCertificateControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespacedCertificateControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespacedCertificateControllerMock.EnqueueAfterFunc: method is nil but NamespacedCertificateController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespacedCertificateControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespacedCertificateControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespacedCertificateController.EnqueueAfterCalls()) +func (mock *NamespacedCertificateControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespacedCertificateControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespacedCertificateControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespacedCertificateControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespacedCertificateControllerMock.GenericFunc: method is nil but NamespacedCertificateController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespacedCertificateControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespacedCertificateControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespacedCertificateController.GenericCalls()) +func (mock *NamespacedCertificateControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespacedCertificateControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespacedCertificateControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespacedCertificateControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespacedCertificateControllerMock.InformerFunc: method is nil but NamespacedCertificateController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespacedCertificateControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespacedCertificateControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespacedCertificateController.InformerCalls()) +func (mock *NamespacedCertificateControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedCertificateControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespacedCertificateControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespacedCertificateControllerMock) Lister() v31.NamespacedCertificateLister { + if mock.ListerFunc == nil { + panic("NamespacedCertificateControllerMock.ListerFunc: method is nil but NamespacedCertificateController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespacedCertificateControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespacedCertificateControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespacedCertificateController.ListerCalls()) +func (mock *NamespacedCertificateControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedCertificateControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespacedCertificateControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespacedCertificateInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespacedCertificateInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespacedCertificateInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespacedCertificateInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespacedCertificateInterfaceMockAddHandler sync.RWMutex + lockNamespacedCertificateInterfaceMockAddLifecycle sync.RWMutex + lockNamespacedCertificateInterfaceMockController sync.RWMutex + lockNamespacedCertificateInterfaceMockCreate sync.RWMutex + lockNamespacedCertificateInterfaceMockDelete sync.RWMutex + lockNamespacedCertificateInterfaceMockDeleteCollection sync.RWMutex + lockNamespacedCertificateInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespacedCertificateInterfaceMockGet sync.RWMutex + lockNamespacedCertificateInterfaceMockGetNamespaced sync.RWMutex + lockNamespacedCertificateInterfaceMockList sync.RWMutex + lockNamespacedCertificateInterfaceMockListNamespaced sync.RWMutex + lockNamespacedCertificateInterfaceMockObjectClient sync.RWMutex + lockNamespacedCertificateInterfaceMockUpdate sync.RWMutex + lockNamespacedCertificateInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespacedCertificateInterfaceMock does implement v31.NamespacedCertificateInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedCertificateInterface = &NamespacedCertificateInterfaceMock{} + +// NamespacedCertificateInterfaceMock is a mock implementation of v31.NamespacedCertificateInterface. +// +// func TestSomethingThatUsesNamespacedCertificateInterface(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedCertificateInterface +// mockedNamespacedCertificateInterface := &NamespacedCertificateInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedCertificateLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NamespacedCertificateLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NamespacedCertificateController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespacedCertificateInterface in code that requires v31.NamespacedCertificateInterface +// // and then make assertions. +// +// } +type NamespacedCertificateInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedCertificateLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NamespacedCertificateLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NamespacedCertificateController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedCertificateHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedCertificateLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedCertificateHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedCertificateLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedCertificateHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedCertificateLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedCertificateHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedCertificateLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedCertificate + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedCertificate + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedCertificateInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespacedCertificateInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle + } + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespacedCertificateInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespacedCertificateInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedCertificateInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedCertificateInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedCertificateInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedCertificateLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespacedCertificateInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedCertificateInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespacedCertificateInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedCertificateLifecycle + } + lockNamespacedCertificateInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespacedCertificateInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedCertificateInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespacedCertificateInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedCertificateInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedCertificateInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddFeatureHandlerCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedCertificateInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespacedCertificateInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedCertificateLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespacedCertificateInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedCertificateLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedCertificateInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespacedCertificateInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddFeatureLifecycleCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedCertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedCertificateLifecycle + } + lockNamespacedCertificateInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespacedCertificateInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedCertificateInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NamespacedCertificateHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddHandlerFunc: method is nil but NamespacedCertificateInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NamespacedCertificateHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedCertificateInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedCertificateInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddHandlerCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NamespacedCertificateHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NamespacedCertificateHandlerFunc + } + lockNamespacedCertificateInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedCertificateInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespacedCertificateInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NamespacedCertificateLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespacedCertificateInterfaceMock.AddLifecycleFunc: method is nil but NamespacedCertificateInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedCertificateLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedCertificateInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespacedCertificateInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.AddLifecycleCalls()) +func (mock *NamespacedCertificateInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedCertificateLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedCertificateLifecycle + } + lockNamespacedCertificateInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespacedCertificateInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespacedCertificateInterfaceMock) Controller() v31.NamespacedCertificateController { + if mock.ControllerFunc == nil { + panic("NamespacedCertificateInterfaceMock.ControllerFunc: method is nil but NamespacedCertificateInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespacedCertificateInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespacedCertificateInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.ControllerCalls()) +func (mock *NamespacedCertificateInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedCertificateInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespacedCertificateInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespacedCertificateInterfaceMock) Create(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { + if mock.CreateFunc == nil { + panic("NamespacedCertificateInterfaceMock.CreateFunc: method is nil but NamespacedCertificateInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NamespacedCertificate + }{ + In1: in1, + } + lockNamespacedCertificateInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespacedCertificateInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.CreateCalls()) +func (mock *NamespacedCertificateInterfaceMock) CreateCalls() []struct { + In1 *v3.NamespacedCertificate +} { + var calls []struct { + In1 *v3.NamespacedCertificate + } + lockNamespacedCertificateInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespacedCertificateInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespacedCertificateInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespacedCertificateInterfaceMock.DeleteFunc: method is nil but NamespacedCertificateInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespacedCertificateInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespacedCertificateInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.DeleteCalls()) +func (mock *NamespacedCertificateInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespacedCertificateInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespacedCertificateInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespacedCertificateInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespacedCertificateInterfaceMock.DeleteCollectionFunc: method is nil but NamespacedCertificateInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespacedCertificateInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespacedCertificateInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.DeleteCollectionCalls()) +func (mock *NamespacedCertificateInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespacedCertificateInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespacedCertificateInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespacedCertificateInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespacedCertificateInterfaceMock.DeleteNamespacedFunc: method is nil but NamespacedCertificateInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespacedCertificateInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespacedCertificateInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.DeleteNamespacedCalls()) +func (mock *NamespacedCertificateInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespacedCertificateInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespacedCertificateInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespacedCertificateInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { + if mock.GetFunc == nil { + panic("NamespacedCertificateInterfaceMock.GetFunc: method is nil but NamespacedCertificateInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespacedCertificateInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedCertificateInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.GetCalls()) +func (mock *NamespacedCertificateInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespacedCertificateInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespacedCertificateInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespacedCertificateInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespacedCertificateInterfaceMock.GetNamespacedFunc: method is nil but NamespacedCertificateInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespacedCertificateInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespacedCertificateInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.GetNamespacedCalls()) +func (mock *NamespacedCertificateInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespacedCertificateInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespacedCertificateInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedCertificateInterfaceMock) List(opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { + if mock.ListFunc == nil { + panic("NamespacedCertificateInterfaceMock.ListFunc: method is nil but NamespacedCertificateInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedCertificateInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedCertificateInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.ListCalls()) +func (mock *NamespacedCertificateInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedCertificateInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespacedCertificateInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespacedCertificateInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespacedCertificateInterfaceMock.ListNamespacedFunc: method is nil but NamespacedCertificateInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespacedCertificateInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespacedCertificateInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.ListNamespacedCalls()) +func (mock *NamespacedCertificateInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespacedCertificateInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespacedCertificateInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespacedCertificateInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespacedCertificateInterfaceMock.ObjectClientFunc: method is nil but NamespacedCertificateInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespacedCertificateInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespacedCertificateInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.ObjectClientCalls()) +func (mock *NamespacedCertificateInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespacedCertificateInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespacedCertificateInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespacedCertificateInterfaceMock) Update(in1 *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { + if mock.UpdateFunc == nil { + panic("NamespacedCertificateInterfaceMock.UpdateFunc: method is nil but NamespacedCertificateInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NamespacedCertificate + }{ + In1: in1, + } + lockNamespacedCertificateInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespacedCertificateInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.UpdateCalls()) +func (mock *NamespacedCertificateInterfaceMock) UpdateCalls() []struct { + In1 *v3.NamespacedCertificate +} { + var calls []struct { + In1 *v3.NamespacedCertificate + } + lockNamespacedCertificateInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespacedCertificateInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespacedCertificateInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespacedCertificateInterfaceMock.WatchFunc: method is nil but NamespacedCertificateInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedCertificateInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespacedCertificateInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespacedCertificateInterface.WatchCalls()) +func (mock *NamespacedCertificateInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedCertificateInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespacedCertificateInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacedCertificatesGetterMockNamespacedCertificates sync.RWMutex +) + +// Ensure, that NamespacedCertificatesGetterMock does implement v31.NamespacedCertificatesGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedCertificatesGetter = &NamespacedCertificatesGetterMock{} + +// NamespacedCertificatesGetterMock is a mock implementation of v31.NamespacedCertificatesGetter. +// +// func TestSomethingThatUsesNamespacedCertificatesGetter(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedCertificatesGetter +// mockedNamespacedCertificatesGetter := &NamespacedCertificatesGetterMock{ +// NamespacedCertificatesFunc: func(namespace string) v31.NamespacedCertificateInterface { +// panic("mock out the NamespacedCertificates method") +// }, +// } +// +// // use mockedNamespacedCertificatesGetter in code that requires v31.NamespacedCertificatesGetter +// // and then make assertions. +// +// } +type NamespacedCertificatesGetterMock struct { + // NamespacedCertificatesFunc mocks the NamespacedCertificates method. + NamespacedCertificatesFunc func(namespace string) v31.NamespacedCertificateInterface + + // calls tracks calls to the methods. + calls struct { + // NamespacedCertificates holds details about calls to the NamespacedCertificates method. + NamespacedCertificates []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NamespacedCertificates calls NamespacedCertificatesFunc. +func (mock *NamespacedCertificatesGetterMock) NamespacedCertificates(namespace string) v31.NamespacedCertificateInterface { + if mock.NamespacedCertificatesFunc == nil { + panic("NamespacedCertificatesGetterMock.NamespacedCertificatesFunc: method is nil but NamespacedCertificatesGetter.NamespacedCertificates was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacedCertificatesGetterMockNamespacedCertificates.Lock() + mock.calls.NamespacedCertificates = append(mock.calls.NamespacedCertificates, callInfo) + lockNamespacedCertificatesGetterMockNamespacedCertificates.Unlock() + return mock.NamespacedCertificatesFunc(namespace) +} + +// NamespacedCertificatesCalls gets all the calls that were made to NamespacedCertificates. +// Check the length with: +// +// len(mockedNamespacedCertificatesGetter.NamespacedCertificatesCalls()) +func (mock *NamespacedCertificatesGetterMock) NamespacedCertificatesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacedCertificatesGetterMockNamespacedCertificates.RLock() + calls = mock.calls.NamespacedCertificates + lockNamespacedCertificatesGetterMockNamespacedCertificates.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_docker_credential_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_docker_credential_mock.go new file mode 100644 index 0000000..71c2e5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_docker_credential_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespacedDockerCredentialListerMockGet sync.RWMutex + lockNamespacedDockerCredentialListerMockList sync.RWMutex +) + +// Ensure, that NamespacedDockerCredentialListerMock does implement v31.NamespacedDockerCredentialLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedDockerCredentialLister = &NamespacedDockerCredentialListerMock{} + +// NamespacedDockerCredentialListerMock is a mock implementation of v31.NamespacedDockerCredentialLister. +// +// func TestSomethingThatUsesNamespacedDockerCredentialLister(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedDockerCredentialLister +// mockedNamespacedDockerCredentialLister := &NamespacedDockerCredentialListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NamespacedDockerCredential, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NamespacedDockerCredential, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespacedDockerCredentialLister in code that requires v31.NamespacedDockerCredentialLister +// // and then make assertions. +// +// } +type NamespacedDockerCredentialListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NamespacedDockerCredential, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NamespacedDockerCredential, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespacedDockerCredentialListerMock) Get(namespace string, name string) (*v3.NamespacedDockerCredential, error) { + if mock.GetFunc == nil { + panic("NamespacedDockerCredentialListerMock.GetFunc: method is nil but NamespacedDockerCredentialLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedDockerCredentialListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedDockerCredentialListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialLister.GetCalls()) +func (mock *NamespacedDockerCredentialListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedDockerCredentialListerMockGet.RLock() + calls = mock.calls.Get + lockNamespacedDockerCredentialListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedDockerCredentialListerMock) List(namespace string, selector labels.Selector) ([]*v3.NamespacedDockerCredential, error) { + if mock.ListFunc == nil { + panic("NamespacedDockerCredentialListerMock.ListFunc: method is nil but NamespacedDockerCredentialLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespacedDockerCredentialListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedDockerCredentialListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialLister.ListCalls()) +func (mock *NamespacedDockerCredentialListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespacedDockerCredentialListerMockList.RLock() + calls = mock.calls.List + lockNamespacedDockerCredentialListerMockList.RUnlock() + return calls +} + +var ( + lockNamespacedDockerCredentialControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedDockerCredentialControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespacedDockerCredentialControllerMockAddFeatureHandler sync.RWMutex + lockNamespacedDockerCredentialControllerMockAddHandler sync.RWMutex + lockNamespacedDockerCredentialControllerMockEnqueue sync.RWMutex + lockNamespacedDockerCredentialControllerMockEnqueueAfter sync.RWMutex + lockNamespacedDockerCredentialControllerMockGeneric sync.RWMutex + lockNamespacedDockerCredentialControllerMockInformer sync.RWMutex + lockNamespacedDockerCredentialControllerMockLister sync.RWMutex +) + +// Ensure, that NamespacedDockerCredentialControllerMock does implement v31.NamespacedDockerCredentialController. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedDockerCredentialController = &NamespacedDockerCredentialControllerMock{} + +// NamespacedDockerCredentialControllerMock is a mock implementation of v31.NamespacedDockerCredentialController. +// +// func TestSomethingThatUsesNamespacedDockerCredentialController(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedDockerCredentialController +// mockedNamespacedDockerCredentialController := &NamespacedDockerCredentialControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NamespacedDockerCredentialLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespacedDockerCredentialController in code that requires v31.NamespacedDockerCredentialController +// // and then make assertions. +// +// } +type NamespacedDockerCredentialControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NamespacedDockerCredentialHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NamespacedDockerCredentialLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedDockerCredentialHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedDockerCredentialHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedDockerCredentialHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NamespacedDockerCredentialHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedDockerCredentialControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedDockerCredentialController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedDockerCredentialControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedDockerCredentialControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedDockerCredentialControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedDockerCredentialControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespacedDockerCredentialController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedDockerCredentialControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedDockerCredentialControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.AddClusterScopedHandlerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedDockerCredentialControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedDockerCredentialControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.AddFeatureHandlerFunc: method is nil but NamespacedDockerCredentialController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedDockerCredentialControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedDockerCredentialControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.AddFeatureHandlerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedDockerCredentialControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedDockerCredentialControllerMock) AddHandler(ctx context.Context, name string, handler v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.AddHandlerFunc: method is nil but NamespacedDockerCredentialController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespacedDockerCredentialControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedDockerCredentialControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.AddHandlerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedDockerCredentialControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespacedDockerCredentialControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespacedDockerCredentialControllerMock.EnqueueFunc: method is nil but NamespacedDockerCredentialController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedDockerCredentialControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespacedDockerCredentialControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.EnqueueCalls()) +func (mock *NamespacedDockerCredentialControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedDockerCredentialControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespacedDockerCredentialControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespacedDockerCredentialControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespacedDockerCredentialControllerMock.EnqueueAfterFunc: method is nil but NamespacedDockerCredentialController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespacedDockerCredentialControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespacedDockerCredentialControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.EnqueueAfterCalls()) +func (mock *NamespacedDockerCredentialControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespacedDockerCredentialControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespacedDockerCredentialControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespacedDockerCredentialControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespacedDockerCredentialControllerMock.GenericFunc: method is nil but NamespacedDockerCredentialController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespacedDockerCredentialControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespacedDockerCredentialControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.GenericCalls()) +func (mock *NamespacedDockerCredentialControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespacedDockerCredentialControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespacedDockerCredentialControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespacedDockerCredentialControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.InformerFunc: method is nil but NamespacedDockerCredentialController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespacedDockerCredentialControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespacedDockerCredentialControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.InformerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedDockerCredentialControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespacedDockerCredentialControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespacedDockerCredentialControllerMock) Lister() v31.NamespacedDockerCredentialLister { + if mock.ListerFunc == nil { + panic("NamespacedDockerCredentialControllerMock.ListerFunc: method is nil but NamespacedDockerCredentialController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespacedDockerCredentialControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespacedDockerCredentialControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialController.ListerCalls()) +func (mock *NamespacedDockerCredentialControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedDockerCredentialControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespacedDockerCredentialControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddHandler sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockAddLifecycle sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockController sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockCreate sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockDelete sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockDeleteCollection sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockGet sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockGetNamespaced sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockList sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockListNamespaced sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockObjectClient sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockUpdate sync.RWMutex + lockNamespacedDockerCredentialInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespacedDockerCredentialInterfaceMock does implement v31.NamespacedDockerCredentialInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedDockerCredentialInterface = &NamespacedDockerCredentialInterfaceMock{} + +// NamespacedDockerCredentialInterfaceMock is a mock implementation of v31.NamespacedDockerCredentialInterface. +// +// func TestSomethingThatUsesNamespacedDockerCredentialInterface(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedDockerCredentialInterface +// mockedNamespacedDockerCredentialInterface := &NamespacedDockerCredentialInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NamespacedDockerCredentialController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespacedDockerCredentialInterface in code that requires v31.NamespacedDockerCredentialInterface +// // and then make assertions. +// +// } +type NamespacedDockerCredentialInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NamespacedDockerCredentialController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedDockerCredentialHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedDockerCredentialHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedDockerCredentialHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedDockerCredentialHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedDockerCredential + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedDockerCredential + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedDockerCredentialInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespacedDockerCredentialInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespacedDockerCredentialInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedDockerCredentialLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespacedDockerCredentialInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespacedDockerCredentialInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespacedDockerCredentialInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedDockerCredentialInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddFeatureHandlerCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedDockerCredentialInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespacedDockerCredentialInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedDockerCredentialInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddFeatureLifecycleCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + lockNamespacedDockerCredentialInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespacedDockerCredentialInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NamespacedDockerCredentialHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddHandlerFunc: method is nil but NamespacedDockerCredentialInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedDockerCredentialInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddHandlerCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NamespacedDockerCredentialHandlerFunc + } + lockNamespacedDockerCredentialInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedDockerCredentialInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NamespacedDockerCredentialLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.AddLifecycleFunc: method is nil but NamespacedDockerCredentialInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedDockerCredentialInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespacedDockerCredentialInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.AddLifecycleCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedDockerCredentialLifecycle + } + lockNamespacedDockerCredentialInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespacedDockerCredentialInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Controller() v31.NamespacedDockerCredentialController { + if mock.ControllerFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.ControllerFunc: method is nil but NamespacedDockerCredentialInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespacedDockerCredentialInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespacedDockerCredentialInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.ControllerCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedDockerCredentialInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespacedDockerCredentialInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Create(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { + if mock.CreateFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.CreateFunc: method is nil but NamespacedDockerCredentialInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NamespacedDockerCredential + }{ + In1: in1, + } + lockNamespacedDockerCredentialInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespacedDockerCredentialInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.CreateCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) CreateCalls() []struct { + In1 *v3.NamespacedDockerCredential +} { + var calls []struct { + In1 *v3.NamespacedDockerCredential + } + lockNamespacedDockerCredentialInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespacedDockerCredentialInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.DeleteFunc: method is nil but NamespacedDockerCredentialInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespacedDockerCredentialInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespacedDockerCredentialInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.DeleteCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespacedDockerCredentialInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespacedDockerCredentialInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.DeleteCollectionFunc: method is nil but NamespacedDockerCredentialInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespacedDockerCredentialInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespacedDockerCredentialInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.DeleteCollectionCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespacedDockerCredentialInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespacedDockerCredentialInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.DeleteNamespacedFunc: method is nil but NamespacedDockerCredentialInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespacedDockerCredentialInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespacedDockerCredentialInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.DeleteNamespacedCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespacedDockerCredentialInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespacedDockerCredentialInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { + if mock.GetFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.GetFunc: method is nil but NamespacedDockerCredentialInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespacedDockerCredentialInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedDockerCredentialInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.GetCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespacedDockerCredentialInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespacedDockerCredentialInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.GetNamespacedFunc: method is nil but NamespacedDockerCredentialInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespacedDockerCredentialInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespacedDockerCredentialInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.GetNamespacedCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespacedDockerCredentialInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespacedDockerCredentialInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) List(opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { + if mock.ListFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.ListFunc: method is nil but NamespacedDockerCredentialInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedDockerCredentialInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedDockerCredentialInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.ListCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedDockerCredentialInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespacedDockerCredentialInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.ListNamespacedFunc: method is nil but NamespacedDockerCredentialInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespacedDockerCredentialInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespacedDockerCredentialInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.ListNamespacedCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespacedDockerCredentialInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespacedDockerCredentialInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.ObjectClientFunc: method is nil but NamespacedDockerCredentialInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespacedDockerCredentialInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespacedDockerCredentialInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.ObjectClientCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespacedDockerCredentialInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespacedDockerCredentialInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Update(in1 *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { + if mock.UpdateFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.UpdateFunc: method is nil but NamespacedDockerCredentialInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NamespacedDockerCredential + }{ + In1: in1, + } + lockNamespacedDockerCredentialInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespacedDockerCredentialInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.UpdateCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) UpdateCalls() []struct { + In1 *v3.NamespacedDockerCredential +} { + var calls []struct { + In1 *v3.NamespacedDockerCredential + } + lockNamespacedDockerCredentialInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespacedDockerCredentialInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespacedDockerCredentialInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespacedDockerCredentialInterfaceMock.WatchFunc: method is nil but NamespacedDockerCredentialInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedDockerCredentialInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespacedDockerCredentialInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialInterface.WatchCalls()) +func (mock *NamespacedDockerCredentialInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedDockerCredentialInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespacedDockerCredentialInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacedDockerCredentialsGetterMockNamespacedDockerCredentials sync.RWMutex +) + +// Ensure, that NamespacedDockerCredentialsGetterMock does implement v31.NamespacedDockerCredentialsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedDockerCredentialsGetter = &NamespacedDockerCredentialsGetterMock{} + +// NamespacedDockerCredentialsGetterMock is a mock implementation of v31.NamespacedDockerCredentialsGetter. +// +// func TestSomethingThatUsesNamespacedDockerCredentialsGetter(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedDockerCredentialsGetter +// mockedNamespacedDockerCredentialsGetter := &NamespacedDockerCredentialsGetterMock{ +// NamespacedDockerCredentialsFunc: func(namespace string) v31.NamespacedDockerCredentialInterface { +// panic("mock out the NamespacedDockerCredentials method") +// }, +// } +// +// // use mockedNamespacedDockerCredentialsGetter in code that requires v31.NamespacedDockerCredentialsGetter +// // and then make assertions. +// +// } +type NamespacedDockerCredentialsGetterMock struct { + // NamespacedDockerCredentialsFunc mocks the NamespacedDockerCredentials method. + NamespacedDockerCredentialsFunc func(namespace string) v31.NamespacedDockerCredentialInterface + + // calls tracks calls to the methods. + calls struct { + // NamespacedDockerCredentials holds details about calls to the NamespacedDockerCredentials method. + NamespacedDockerCredentials []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NamespacedDockerCredentials calls NamespacedDockerCredentialsFunc. +func (mock *NamespacedDockerCredentialsGetterMock) NamespacedDockerCredentials(namespace string) v31.NamespacedDockerCredentialInterface { + if mock.NamespacedDockerCredentialsFunc == nil { + panic("NamespacedDockerCredentialsGetterMock.NamespacedDockerCredentialsFunc: method is nil but NamespacedDockerCredentialsGetter.NamespacedDockerCredentials was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacedDockerCredentialsGetterMockNamespacedDockerCredentials.Lock() + mock.calls.NamespacedDockerCredentials = append(mock.calls.NamespacedDockerCredentials, callInfo) + lockNamespacedDockerCredentialsGetterMockNamespacedDockerCredentials.Unlock() + return mock.NamespacedDockerCredentialsFunc(namespace) +} + +// NamespacedDockerCredentialsCalls gets all the calls that were made to NamespacedDockerCredentials. +// Check the length with: +// +// len(mockedNamespacedDockerCredentialsGetter.NamespacedDockerCredentialsCalls()) +func (mock *NamespacedDockerCredentialsGetterMock) NamespacedDockerCredentialsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacedDockerCredentialsGetterMockNamespacedDockerCredentials.RLock() + calls = mock.calls.NamespacedDockerCredentials + lockNamespacedDockerCredentialsGetterMockNamespacedDockerCredentials.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_service_account_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_service_account_token_mock.go new file mode 100644 index 0000000..08a033f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_service_account_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespacedServiceAccountTokenListerMockGet sync.RWMutex + lockNamespacedServiceAccountTokenListerMockList sync.RWMutex +) + +// Ensure, that NamespacedServiceAccountTokenListerMock does implement v31.NamespacedServiceAccountTokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedServiceAccountTokenLister = &NamespacedServiceAccountTokenListerMock{} + +// NamespacedServiceAccountTokenListerMock is a mock implementation of v31.NamespacedServiceAccountTokenLister. +// +// func TestSomethingThatUsesNamespacedServiceAccountTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedServiceAccountTokenLister +// mockedNamespacedServiceAccountTokenLister := &NamespacedServiceAccountTokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespacedServiceAccountTokenLister in code that requires v31.NamespacedServiceAccountTokenLister +// // and then make assertions. +// +// } +type NamespacedServiceAccountTokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NamespacedServiceAccountToken, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NamespacedServiceAccountToken, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespacedServiceAccountTokenListerMock) Get(namespace string, name string) (*v3.NamespacedServiceAccountToken, error) { + if mock.GetFunc == nil { + panic("NamespacedServiceAccountTokenListerMock.GetFunc: method is nil but NamespacedServiceAccountTokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedServiceAccountTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedServiceAccountTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenLister.GetCalls()) +func (mock *NamespacedServiceAccountTokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedServiceAccountTokenListerMockGet.RLock() + calls = mock.calls.Get + lockNamespacedServiceAccountTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedServiceAccountTokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.NamespacedServiceAccountToken, error) { + if mock.ListFunc == nil { + panic("NamespacedServiceAccountTokenListerMock.ListFunc: method is nil but NamespacedServiceAccountTokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespacedServiceAccountTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedServiceAccountTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenLister.ListCalls()) +func (mock *NamespacedServiceAccountTokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespacedServiceAccountTokenListerMockList.RLock() + calls = mock.calls.List + lockNamespacedServiceAccountTokenListerMockList.RUnlock() + return calls +} + +var ( + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockAddFeatureHandler sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockAddHandler sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockEnqueue sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockEnqueueAfter sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockGeneric sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockInformer sync.RWMutex + lockNamespacedServiceAccountTokenControllerMockLister sync.RWMutex +) + +// Ensure, that NamespacedServiceAccountTokenControllerMock does implement v31.NamespacedServiceAccountTokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedServiceAccountTokenController = &NamespacedServiceAccountTokenControllerMock{} + +// NamespacedServiceAccountTokenControllerMock is a mock implementation of v31.NamespacedServiceAccountTokenController. +// +// func TestSomethingThatUsesNamespacedServiceAccountTokenController(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedServiceAccountTokenController +// mockedNamespacedServiceAccountTokenController := &NamespacedServiceAccountTokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NamespacedServiceAccountTokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespacedServiceAccountTokenController in code that requires v31.NamespacedServiceAccountTokenController +// // and then make assertions. +// +// } +type NamespacedServiceAccountTokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NamespacedServiceAccountTokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NamespacedServiceAccountTokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedServiceAccountTokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespacedServiceAccountTokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.AddClusterScopedHandlerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedServiceAccountTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.AddFeatureHandlerFunc: method is nil but NamespacedServiceAccountTokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedServiceAccountTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedServiceAccountTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.AddFeatureHandlerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedServiceAccountTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.AddHandlerFunc: method is nil but NamespacedServiceAccountTokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespacedServiceAccountTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedServiceAccountTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.AddHandlerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedServiceAccountTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.EnqueueFunc: method is nil but NamespacedServiceAccountTokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedServiceAccountTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespacedServiceAccountTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.EnqueueCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedServiceAccountTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespacedServiceAccountTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.EnqueueAfterFunc: method is nil but NamespacedServiceAccountTokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespacedServiceAccountTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespacedServiceAccountTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.EnqueueAfterCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespacedServiceAccountTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespacedServiceAccountTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.GenericFunc: method is nil but NamespacedServiceAccountTokenController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespacedServiceAccountTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespacedServiceAccountTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.GenericCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespacedServiceAccountTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespacedServiceAccountTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.InformerFunc: method is nil but NamespacedServiceAccountTokenController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespacedServiceAccountTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespacedServiceAccountTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.InformerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedServiceAccountTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespacedServiceAccountTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespacedServiceAccountTokenControllerMock) Lister() v31.NamespacedServiceAccountTokenLister { + if mock.ListerFunc == nil { + panic("NamespacedServiceAccountTokenControllerMock.ListerFunc: method is nil but NamespacedServiceAccountTokenController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespacedServiceAccountTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespacedServiceAccountTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenController.ListerCalls()) +func (mock *NamespacedServiceAccountTokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedServiceAccountTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespacedServiceAccountTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddHandler sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockAddLifecycle sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockController sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockCreate sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockDelete sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockDeleteCollection sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockGet sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockGetNamespaced sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockList sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockListNamespaced sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockObjectClient sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockUpdate sync.RWMutex + lockNamespacedServiceAccountTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespacedServiceAccountTokenInterfaceMock does implement v31.NamespacedServiceAccountTokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedServiceAccountTokenInterface = &NamespacedServiceAccountTokenInterfaceMock{} + +// NamespacedServiceAccountTokenInterfaceMock is a mock implementation of v31.NamespacedServiceAccountTokenInterface. +// +// func TestSomethingThatUsesNamespacedServiceAccountTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedServiceAccountTokenInterface +// mockedNamespacedServiceAccountTokenInterface := &NamespacedServiceAccountTokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NamespacedServiceAccountTokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespacedServiceAccountTokenInterface in code that requires v31.NamespacedServiceAccountTokenInterface +// // and then make assertions. +// +// } +type NamespacedServiceAccountTokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NamespacedServiceAccountTokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedServiceAccountToken + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedServiceAccountToken + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedServiceAccountTokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespacedServiceAccountTokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespacedServiceAccountTokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespacedServiceAccountTokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespacedServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespacedServiceAccountTokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddFeatureHandlerCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespacedServiceAccountTokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddFeatureLifecycleCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespacedServiceAccountTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NamespacedServiceAccountTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddHandlerFunc: method is nil but NamespacedServiceAccountTokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedServiceAccountTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddHandlerCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NamespacedServiceAccountTokenHandlerFunc + } + lockNamespacedServiceAccountTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedServiceAccountTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NamespacedServiceAccountTokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.AddLifecycleFunc: method is nil but NamespacedServiceAccountTokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedServiceAccountTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.AddLifecycleCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedServiceAccountTokenLifecycle + } + lockNamespacedServiceAccountTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespacedServiceAccountTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Controller() v31.NamespacedServiceAccountTokenController { + if mock.ControllerFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.ControllerFunc: method is nil but NamespacedServiceAccountTokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespacedServiceAccountTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.ControllerCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedServiceAccountTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespacedServiceAccountTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Create(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { + if mock.CreateFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.CreateFunc: method is nil but NamespacedServiceAccountTokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NamespacedServiceAccountToken + }{ + In1: in1, + } + lockNamespacedServiceAccountTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.CreateCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) CreateCalls() []struct { + In1 *v3.NamespacedServiceAccountToken +} { + var calls []struct { + In1 *v3.NamespacedServiceAccountToken + } + lockNamespacedServiceAccountTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespacedServiceAccountTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.DeleteFunc: method is nil but NamespacedServiceAccountTokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespacedServiceAccountTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.DeleteCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespacedServiceAccountTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespacedServiceAccountTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.DeleteCollectionFunc: method is nil but NamespacedServiceAccountTokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespacedServiceAccountTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.DeleteCollectionCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespacedServiceAccountTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespacedServiceAccountTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.DeleteNamespacedFunc: method is nil but NamespacedServiceAccountTokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespacedServiceAccountTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.DeleteNamespacedCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespacedServiceAccountTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespacedServiceAccountTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { + if mock.GetFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.GetFunc: method is nil but NamespacedServiceAccountTokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespacedServiceAccountTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.GetCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespacedServiceAccountTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespacedServiceAccountTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.GetNamespacedFunc: method is nil but NamespacedServiceAccountTokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespacedServiceAccountTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.GetNamespacedCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespacedServiceAccountTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespacedServiceAccountTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) List(opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { + if mock.ListFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.ListFunc: method is nil but NamespacedServiceAccountTokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedServiceAccountTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.ListCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedServiceAccountTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespacedServiceAccountTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.ListNamespacedFunc: method is nil but NamespacedServiceAccountTokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespacedServiceAccountTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.ListNamespacedCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespacedServiceAccountTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespacedServiceAccountTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.ObjectClientFunc: method is nil but NamespacedServiceAccountTokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespacedServiceAccountTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.ObjectClientCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespacedServiceAccountTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespacedServiceAccountTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Update(in1 *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { + if mock.UpdateFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.UpdateFunc: method is nil but NamespacedServiceAccountTokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NamespacedServiceAccountToken + }{ + In1: in1, + } + lockNamespacedServiceAccountTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.UpdateCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.NamespacedServiceAccountToken +} { + var calls []struct { + In1 *v3.NamespacedServiceAccountToken + } + lockNamespacedServiceAccountTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespacedServiceAccountTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespacedServiceAccountTokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespacedServiceAccountTokenInterfaceMock.WatchFunc: method is nil but NamespacedServiceAccountTokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedServiceAccountTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespacedServiceAccountTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokenInterface.WatchCalls()) +func (mock *NamespacedServiceAccountTokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedServiceAccountTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespacedServiceAccountTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacedServiceAccountTokensGetterMockNamespacedServiceAccountTokens sync.RWMutex +) + +// Ensure, that NamespacedServiceAccountTokensGetterMock does implement v31.NamespacedServiceAccountTokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedServiceAccountTokensGetter = &NamespacedServiceAccountTokensGetterMock{} + +// NamespacedServiceAccountTokensGetterMock is a mock implementation of v31.NamespacedServiceAccountTokensGetter. +// +// func TestSomethingThatUsesNamespacedServiceAccountTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedServiceAccountTokensGetter +// mockedNamespacedServiceAccountTokensGetter := &NamespacedServiceAccountTokensGetterMock{ +// NamespacedServiceAccountTokensFunc: func(namespace string) v31.NamespacedServiceAccountTokenInterface { +// panic("mock out the NamespacedServiceAccountTokens method") +// }, +// } +// +// // use mockedNamespacedServiceAccountTokensGetter in code that requires v31.NamespacedServiceAccountTokensGetter +// // and then make assertions. +// +// } +type NamespacedServiceAccountTokensGetterMock struct { + // NamespacedServiceAccountTokensFunc mocks the NamespacedServiceAccountTokens method. + NamespacedServiceAccountTokensFunc func(namespace string) v31.NamespacedServiceAccountTokenInterface + + // calls tracks calls to the methods. + calls struct { + // NamespacedServiceAccountTokens holds details about calls to the NamespacedServiceAccountTokens method. + NamespacedServiceAccountTokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NamespacedServiceAccountTokens calls NamespacedServiceAccountTokensFunc. +func (mock *NamespacedServiceAccountTokensGetterMock) NamespacedServiceAccountTokens(namespace string) v31.NamespacedServiceAccountTokenInterface { + if mock.NamespacedServiceAccountTokensFunc == nil { + panic("NamespacedServiceAccountTokensGetterMock.NamespacedServiceAccountTokensFunc: method is nil but NamespacedServiceAccountTokensGetter.NamespacedServiceAccountTokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacedServiceAccountTokensGetterMockNamespacedServiceAccountTokens.Lock() + mock.calls.NamespacedServiceAccountTokens = append(mock.calls.NamespacedServiceAccountTokens, callInfo) + lockNamespacedServiceAccountTokensGetterMockNamespacedServiceAccountTokens.Unlock() + return mock.NamespacedServiceAccountTokensFunc(namespace) +} + +// NamespacedServiceAccountTokensCalls gets all the calls that were made to NamespacedServiceAccountTokens. +// Check the length with: +// +// len(mockedNamespacedServiceAccountTokensGetter.NamespacedServiceAccountTokensCalls()) +func (mock *NamespacedServiceAccountTokensGetterMock) NamespacedServiceAccountTokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacedServiceAccountTokensGetterMockNamespacedServiceAccountTokens.RLock() + calls = mock.calls.NamespacedServiceAccountTokens + lockNamespacedServiceAccountTokensGetterMockNamespacedServiceAccountTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_ssh_auth_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_ssh_auth_mock.go new file mode 100644 index 0000000..74b204b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_namespaced_ssh_auth_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockNamespacedSSHAuthListerMockGet sync.RWMutex + lockNamespacedSSHAuthListerMockList sync.RWMutex +) + +// Ensure, that NamespacedSSHAuthListerMock does implement v31.NamespacedSSHAuthLister. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedSSHAuthLister = &NamespacedSSHAuthListerMock{} + +// NamespacedSSHAuthListerMock is a mock implementation of v31.NamespacedSSHAuthLister. +// +// func TestSomethingThatUsesNamespacedSSHAuthLister(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedSSHAuthLister +// mockedNamespacedSSHAuthLister := &NamespacedSSHAuthListerMock{ +// GetFunc: func(namespace string, name string) (*v3.NamespacedSSHAuth, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.NamespacedSSHAuth, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedNamespacedSSHAuthLister in code that requires v31.NamespacedSSHAuthLister +// // and then make assertions. +// +// } +type NamespacedSSHAuthListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.NamespacedSSHAuth, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.NamespacedSSHAuth, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *NamespacedSSHAuthListerMock) Get(namespace string, name string) (*v3.NamespacedSSHAuth, error) { + if mock.GetFunc == nil { + panic("NamespacedSSHAuthListerMock.GetFunc: method is nil but NamespacedSSHAuthLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedSSHAuthListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedSSHAuthListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedSSHAuthLister.GetCalls()) +func (mock *NamespacedSSHAuthListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedSSHAuthListerMockGet.RLock() + calls = mock.calls.Get + lockNamespacedSSHAuthListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedSSHAuthListerMock) List(namespace string, selector labels.Selector) ([]*v3.NamespacedSSHAuth, error) { + if mock.ListFunc == nil { + panic("NamespacedSSHAuthListerMock.ListFunc: method is nil but NamespacedSSHAuthLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockNamespacedSSHAuthListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedSSHAuthListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedSSHAuthLister.ListCalls()) +func (mock *NamespacedSSHAuthListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockNamespacedSSHAuthListerMockList.RLock() + calls = mock.calls.List + lockNamespacedSSHAuthListerMockList.RUnlock() + return calls +} + +var ( + lockNamespacedSSHAuthControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedSSHAuthControllerMockAddClusterScopedHandler sync.RWMutex + lockNamespacedSSHAuthControllerMockAddFeatureHandler sync.RWMutex + lockNamespacedSSHAuthControllerMockAddHandler sync.RWMutex + lockNamespacedSSHAuthControllerMockEnqueue sync.RWMutex + lockNamespacedSSHAuthControllerMockEnqueueAfter sync.RWMutex + lockNamespacedSSHAuthControllerMockGeneric sync.RWMutex + lockNamespacedSSHAuthControllerMockInformer sync.RWMutex + lockNamespacedSSHAuthControllerMockLister sync.RWMutex +) + +// Ensure, that NamespacedSSHAuthControllerMock does implement v31.NamespacedSSHAuthController. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedSSHAuthController = &NamespacedSSHAuthControllerMock{} + +// NamespacedSSHAuthControllerMock is a mock implementation of v31.NamespacedSSHAuthController. +// +// func TestSomethingThatUsesNamespacedSSHAuthController(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedSSHAuthController +// mockedNamespacedSSHAuthController := &NamespacedSSHAuthControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.NamespacedSSHAuthLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedNamespacedSSHAuthController in code that requires v31.NamespacedSSHAuthController +// // and then make assertions. +// +// } +type NamespacedSSHAuthControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.NamespacedSSHAuthHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.NamespacedSSHAuthLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedSSHAuthHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.NamespacedSSHAuthHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedSSHAuthHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.NamespacedSSHAuthHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedSSHAuthControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedSSHAuthControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedSSHAuthController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedSSHAuthControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedSSHAuthControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedSSHAuthControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedSSHAuthControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedSSHAuthControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedSSHAuthControllerMock.AddClusterScopedHandlerFunc: method is nil but NamespacedSSHAuthController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockNamespacedSSHAuthControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedSSHAuthControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.AddClusterScopedHandlerCalls()) +func (mock *NamespacedSSHAuthControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedSSHAuthControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedSSHAuthControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedSSHAuthControllerMock.AddFeatureHandlerFunc: method is nil but NamespacedSSHAuthController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedSSHAuthControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedSSHAuthControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.AddFeatureHandlerCalls()) +func (mock *NamespacedSSHAuthControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedSSHAuthControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedSSHAuthControllerMock) AddHandler(ctx context.Context, name string, handler v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedSSHAuthControllerMock.AddHandlerFunc: method is nil but NamespacedSSHAuthController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockNamespacedSSHAuthControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedSSHAuthControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.AddHandlerCalls()) +func (mock *NamespacedSSHAuthControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedSSHAuthControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *NamespacedSSHAuthControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("NamespacedSSHAuthControllerMock.EnqueueFunc: method is nil but NamespacedSSHAuthController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockNamespacedSSHAuthControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockNamespacedSSHAuthControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.EnqueueCalls()) +func (mock *NamespacedSSHAuthControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockNamespacedSSHAuthControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockNamespacedSSHAuthControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *NamespacedSSHAuthControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("NamespacedSSHAuthControllerMock.EnqueueAfterFunc: method is nil but NamespacedSSHAuthController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockNamespacedSSHAuthControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockNamespacedSSHAuthControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.EnqueueAfterCalls()) +func (mock *NamespacedSSHAuthControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockNamespacedSSHAuthControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockNamespacedSSHAuthControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *NamespacedSSHAuthControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("NamespacedSSHAuthControllerMock.GenericFunc: method is nil but NamespacedSSHAuthController.Generic was just called") + } + callInfo := struct { + }{} + lockNamespacedSSHAuthControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockNamespacedSSHAuthControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.GenericCalls()) +func (mock *NamespacedSSHAuthControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockNamespacedSSHAuthControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockNamespacedSSHAuthControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *NamespacedSSHAuthControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("NamespacedSSHAuthControllerMock.InformerFunc: method is nil but NamespacedSSHAuthController.Informer was just called") + } + callInfo := struct { + }{} + lockNamespacedSSHAuthControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockNamespacedSSHAuthControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.InformerCalls()) +func (mock *NamespacedSSHAuthControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedSSHAuthControllerMockInformer.RLock() + calls = mock.calls.Informer + lockNamespacedSSHAuthControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *NamespacedSSHAuthControllerMock) Lister() v31.NamespacedSSHAuthLister { + if mock.ListerFunc == nil { + panic("NamespacedSSHAuthControllerMock.ListerFunc: method is nil but NamespacedSSHAuthController.Lister was just called") + } + callInfo := struct { + }{} + lockNamespacedSSHAuthControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockNamespacedSSHAuthControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedNamespacedSSHAuthController.ListerCalls()) +func (mock *NamespacedSSHAuthControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedSSHAuthControllerMockLister.RLock() + calls = mock.calls.Lister + lockNamespacedSSHAuthControllerMockLister.RUnlock() + return calls +} + +var ( + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddClusterScopedHandler sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddFeatureHandler sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddFeatureLifecycle sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddHandler sync.RWMutex + lockNamespacedSSHAuthInterfaceMockAddLifecycle sync.RWMutex + lockNamespacedSSHAuthInterfaceMockController sync.RWMutex + lockNamespacedSSHAuthInterfaceMockCreate sync.RWMutex + lockNamespacedSSHAuthInterfaceMockDelete sync.RWMutex + lockNamespacedSSHAuthInterfaceMockDeleteCollection sync.RWMutex + lockNamespacedSSHAuthInterfaceMockDeleteNamespaced sync.RWMutex + lockNamespacedSSHAuthInterfaceMockGet sync.RWMutex + lockNamespacedSSHAuthInterfaceMockGetNamespaced sync.RWMutex + lockNamespacedSSHAuthInterfaceMockList sync.RWMutex + lockNamespacedSSHAuthInterfaceMockListNamespaced sync.RWMutex + lockNamespacedSSHAuthInterfaceMockObjectClient sync.RWMutex + lockNamespacedSSHAuthInterfaceMockUpdate sync.RWMutex + lockNamespacedSSHAuthInterfaceMockWatch sync.RWMutex +) + +// Ensure, that NamespacedSSHAuthInterfaceMock does implement v31.NamespacedSSHAuthInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedSSHAuthInterface = &NamespacedSSHAuthInterfaceMock{} + +// NamespacedSSHAuthInterfaceMock is a mock implementation of v31.NamespacedSSHAuthInterface. +// +// func TestSomethingThatUsesNamespacedSSHAuthInterface(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedSSHAuthInterface +// mockedNamespacedSSHAuthInterface := &NamespacedSSHAuthInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedSSHAuthLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.NamespacedSSHAuthLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.NamespacedSSHAuthController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedNamespacedSSHAuthInterface in code that requires v31.NamespacedSSHAuthInterface +// // and then make assertions. +// +// } +type NamespacedSSHAuthInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedSSHAuthLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.NamespacedSSHAuthLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.NamespacedSSHAuthController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedSSHAuthHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedSSHAuthLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.NamespacedSSHAuthHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedSSHAuthLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedSSHAuthHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedSSHAuthLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.NamespacedSSHAuthHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.NamespacedSSHAuthLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedSSHAuth + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.NamespacedSSHAuth + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but NamespacedSSHAuthInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but NamespacedSSHAuthInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockNamespacedSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddClusterScopedHandlerFunc: method is nil but NamespacedSSHAuthInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockNamespacedSSHAuthInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddClusterScopedHandlerCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockNamespacedSSHAuthInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.NamespacedSSHAuthLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but NamespacedSSHAuthInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockNamespacedSSHAuthInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddClusterScopedLifecycleCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.NamespacedSSHAuthLifecycle + } + lockNamespacedSSHAuthInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockNamespacedSSHAuthInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddFeatureHandlerFunc: method is nil but NamespacedSSHAuthInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedSSHAuthInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockNamespacedSSHAuthInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddFeatureHandlerCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockNamespacedSSHAuthInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.NamespacedSSHAuthLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddFeatureLifecycleFunc: method is nil but NamespacedSSHAuthInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedSSHAuthInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockNamespacedSSHAuthInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddFeatureLifecycleCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle + } + lockNamespacedSSHAuthInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockNamespacedSSHAuthInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.NamespacedSSHAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddHandlerFunc: method is nil but NamespacedSSHAuthInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockNamespacedSSHAuthInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockNamespacedSSHAuthInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddHandlerCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.NamespacedSSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.NamespacedSSHAuthHandlerFunc + } + lockNamespacedSSHAuthInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockNamespacedSSHAuthInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *NamespacedSSHAuthInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.NamespacedSSHAuthLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.AddLifecycleFunc: method is nil but NamespacedSSHAuthInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockNamespacedSSHAuthInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockNamespacedSSHAuthInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.AddLifecycleCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.NamespacedSSHAuthLifecycle + } + lockNamespacedSSHAuthInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockNamespacedSSHAuthInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Controller() v31.NamespacedSSHAuthController { + if mock.ControllerFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.ControllerFunc: method is nil but NamespacedSSHAuthInterface.Controller was just called") + } + callInfo := struct { + }{} + lockNamespacedSSHAuthInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockNamespacedSSHAuthInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.ControllerCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockNamespacedSSHAuthInterfaceMockController.RLock() + calls = mock.calls.Controller + lockNamespacedSSHAuthInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Create(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { + if mock.CreateFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.CreateFunc: method is nil but NamespacedSSHAuthInterface.Create was just called") + } + callInfo := struct { + In1 *v3.NamespacedSSHAuth + }{ + In1: in1, + } + lockNamespacedSSHAuthInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockNamespacedSSHAuthInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.CreateCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) CreateCalls() []struct { + In1 *v3.NamespacedSSHAuth +} { + var calls []struct { + In1 *v3.NamespacedSSHAuth + } + lockNamespacedSSHAuthInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockNamespacedSSHAuthInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.DeleteFunc: method is nil but NamespacedSSHAuthInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockNamespacedSSHAuthInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockNamespacedSSHAuthInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.DeleteCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockNamespacedSSHAuthInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockNamespacedSSHAuthInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *NamespacedSSHAuthInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.DeleteCollectionFunc: method is nil but NamespacedSSHAuthInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockNamespacedSSHAuthInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockNamespacedSSHAuthInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.DeleteCollectionCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockNamespacedSSHAuthInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockNamespacedSSHAuthInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *NamespacedSSHAuthInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.DeleteNamespacedFunc: method is nil but NamespacedSSHAuthInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockNamespacedSSHAuthInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockNamespacedSSHAuthInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.DeleteNamespacedCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockNamespacedSSHAuthInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockNamespacedSSHAuthInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { + if mock.GetFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.GetFunc: method is nil but NamespacedSSHAuthInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockNamespacedSSHAuthInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockNamespacedSSHAuthInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.GetCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockNamespacedSSHAuthInterfaceMockGet.RLock() + calls = mock.calls.Get + lockNamespacedSSHAuthInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *NamespacedSSHAuthInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { + if mock.GetNamespacedFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.GetNamespacedFunc: method is nil but NamespacedSSHAuthInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockNamespacedSSHAuthInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockNamespacedSSHAuthInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.GetNamespacedCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockNamespacedSSHAuthInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockNamespacedSSHAuthInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *NamespacedSSHAuthInterfaceMock) List(opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { + if mock.ListFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.ListFunc: method is nil but NamespacedSSHAuthInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedSSHAuthInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockNamespacedSSHAuthInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.ListCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedSSHAuthInterfaceMockList.RLock() + calls = mock.calls.List + lockNamespacedSSHAuthInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *NamespacedSSHAuthInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { + if mock.ListNamespacedFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.ListNamespacedFunc: method is nil but NamespacedSSHAuthInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockNamespacedSSHAuthInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockNamespacedSSHAuthInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.ListNamespacedCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockNamespacedSSHAuthInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockNamespacedSSHAuthInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *NamespacedSSHAuthInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.ObjectClientFunc: method is nil but NamespacedSSHAuthInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockNamespacedSSHAuthInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockNamespacedSSHAuthInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.ObjectClientCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockNamespacedSSHAuthInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockNamespacedSSHAuthInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Update(in1 *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { + if mock.UpdateFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.UpdateFunc: method is nil but NamespacedSSHAuthInterface.Update was just called") + } + callInfo := struct { + In1 *v3.NamespacedSSHAuth + }{ + In1: in1, + } + lockNamespacedSSHAuthInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockNamespacedSSHAuthInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.UpdateCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) UpdateCalls() []struct { + In1 *v3.NamespacedSSHAuth +} { + var calls []struct { + In1 *v3.NamespacedSSHAuth + } + lockNamespacedSSHAuthInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockNamespacedSSHAuthInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *NamespacedSSHAuthInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("NamespacedSSHAuthInterfaceMock.WatchFunc: method is nil but NamespacedSSHAuthInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockNamespacedSSHAuthInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockNamespacedSSHAuthInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedNamespacedSSHAuthInterface.WatchCalls()) +func (mock *NamespacedSSHAuthInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockNamespacedSSHAuthInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockNamespacedSSHAuthInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockNamespacedSSHAuthsGetterMockNamespacedSSHAuths sync.RWMutex +) + +// Ensure, that NamespacedSSHAuthsGetterMock does implement v31.NamespacedSSHAuthsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.NamespacedSSHAuthsGetter = &NamespacedSSHAuthsGetterMock{} + +// NamespacedSSHAuthsGetterMock is a mock implementation of v31.NamespacedSSHAuthsGetter. +// +// func TestSomethingThatUsesNamespacedSSHAuthsGetter(t *testing.T) { +// +// // make and configure a mocked v31.NamespacedSSHAuthsGetter +// mockedNamespacedSSHAuthsGetter := &NamespacedSSHAuthsGetterMock{ +// NamespacedSSHAuthsFunc: func(namespace string) v31.NamespacedSSHAuthInterface { +// panic("mock out the NamespacedSSHAuths method") +// }, +// } +// +// // use mockedNamespacedSSHAuthsGetter in code that requires v31.NamespacedSSHAuthsGetter +// // and then make assertions. +// +// } +type NamespacedSSHAuthsGetterMock struct { + // NamespacedSSHAuthsFunc mocks the NamespacedSSHAuths method. + NamespacedSSHAuthsFunc func(namespace string) v31.NamespacedSSHAuthInterface + + // calls tracks calls to the methods. + calls struct { + // NamespacedSSHAuths holds details about calls to the NamespacedSSHAuths method. + NamespacedSSHAuths []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// NamespacedSSHAuths calls NamespacedSSHAuthsFunc. +func (mock *NamespacedSSHAuthsGetterMock) NamespacedSSHAuths(namespace string) v31.NamespacedSSHAuthInterface { + if mock.NamespacedSSHAuthsFunc == nil { + panic("NamespacedSSHAuthsGetterMock.NamespacedSSHAuthsFunc: method is nil but NamespacedSSHAuthsGetter.NamespacedSSHAuths was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockNamespacedSSHAuthsGetterMockNamespacedSSHAuths.Lock() + mock.calls.NamespacedSSHAuths = append(mock.calls.NamespacedSSHAuths, callInfo) + lockNamespacedSSHAuthsGetterMockNamespacedSSHAuths.Unlock() + return mock.NamespacedSSHAuthsFunc(namespace) +} + +// NamespacedSSHAuthsCalls gets all the calls that were made to NamespacedSSHAuths. +// Check the length with: +// +// len(mockedNamespacedSSHAuthsGetter.NamespacedSSHAuthsCalls()) +func (mock *NamespacedSSHAuthsGetterMock) NamespacedSSHAuthsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockNamespacedSSHAuthsGetterMockNamespacedSSHAuths.RLock() + calls = mock.calls.NamespacedSSHAuths + lockNamespacedSSHAuthsGetterMockNamespacedSSHAuths.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_service_account_token_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_service_account_token_mock.go new file mode 100644 index 0000000..098d098 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_service_account_token_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockServiceAccountTokenListerMockGet sync.RWMutex + lockServiceAccountTokenListerMockList sync.RWMutex +) + +// Ensure, that ServiceAccountTokenListerMock does implement v31.ServiceAccountTokenLister. +// If this is not the case, regenerate this file with moq. +var _ v31.ServiceAccountTokenLister = &ServiceAccountTokenListerMock{} + +// ServiceAccountTokenListerMock is a mock implementation of v31.ServiceAccountTokenLister. +// +// func TestSomethingThatUsesServiceAccountTokenLister(t *testing.T) { +// +// // make and configure a mocked v31.ServiceAccountTokenLister +// mockedServiceAccountTokenLister := &ServiceAccountTokenListerMock{ +// GetFunc: func(namespace string, name string) (*v3.ServiceAccountToken, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.ServiceAccountToken, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedServiceAccountTokenLister in code that requires v31.ServiceAccountTokenLister +// // and then make assertions. +// +// } +type ServiceAccountTokenListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.ServiceAccountToken, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.ServiceAccountToken, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ServiceAccountTokenListerMock) Get(namespace string, name string) (*v3.ServiceAccountToken, error) { + if mock.GetFunc == nil { + panic("ServiceAccountTokenListerMock.GetFunc: method is nil but ServiceAccountTokenLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceAccountTokenListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceAccountTokenListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceAccountTokenLister.GetCalls()) +func (mock *ServiceAccountTokenListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceAccountTokenListerMockGet.RLock() + calls = mock.calls.Get + lockServiceAccountTokenListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceAccountTokenListerMock) List(namespace string, selector labels.Selector) ([]*v3.ServiceAccountToken, error) { + if mock.ListFunc == nil { + panic("ServiceAccountTokenListerMock.ListFunc: method is nil but ServiceAccountTokenLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockServiceAccountTokenListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceAccountTokenListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceAccountTokenLister.ListCalls()) +func (mock *ServiceAccountTokenListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockServiceAccountTokenListerMockList.RLock() + calls = mock.calls.List + lockServiceAccountTokenListerMockList.RUnlock() + return calls +} + +var ( + lockServiceAccountTokenControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceAccountTokenControllerMockAddClusterScopedHandler sync.RWMutex + lockServiceAccountTokenControllerMockAddFeatureHandler sync.RWMutex + lockServiceAccountTokenControllerMockAddHandler sync.RWMutex + lockServiceAccountTokenControllerMockEnqueue sync.RWMutex + lockServiceAccountTokenControllerMockEnqueueAfter sync.RWMutex + lockServiceAccountTokenControllerMockGeneric sync.RWMutex + lockServiceAccountTokenControllerMockInformer sync.RWMutex + lockServiceAccountTokenControllerMockLister sync.RWMutex +) + +// Ensure, that ServiceAccountTokenControllerMock does implement v31.ServiceAccountTokenController. +// If this is not the case, regenerate this file with moq. +var _ v31.ServiceAccountTokenController = &ServiceAccountTokenControllerMock{} + +// ServiceAccountTokenControllerMock is a mock implementation of v31.ServiceAccountTokenController. +// +// func TestSomethingThatUsesServiceAccountTokenController(t *testing.T) { +// +// // make and configure a mocked v31.ServiceAccountTokenController +// mockedServiceAccountTokenController := &ServiceAccountTokenControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.ServiceAccountTokenLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedServiceAccountTokenController in code that requires v31.ServiceAccountTokenController +// // and then make assertions. +// +// } +type ServiceAccountTokenControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.ServiceAccountTokenHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.ServiceAccountTokenLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ServiceAccountTokenHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.ServiceAccountTokenHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ServiceAccountTokenHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.ServiceAccountTokenHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceAccountTokenControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceAccountTokenControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceAccountTokenController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceAccountTokenControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceAccountTokenControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceAccountTokenControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.ServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceAccountTokenControllerMock.AddClusterScopedHandlerFunc: method is nil but ServiceAccountTokenController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockServiceAccountTokenControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceAccountTokenControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenController.AddClusterScopedHandlerCalls()) +func (mock *ServiceAccountTokenControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceAccountTokenControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceAccountTokenControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceAccountTokenControllerMock.AddFeatureHandlerFunc: method is nil but ServiceAccountTokenController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountTokenControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceAccountTokenControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenController.AddFeatureHandlerCalls()) +func (mock *ServiceAccountTokenControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceAccountTokenControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceAccountTokenControllerMock) AddHandler(ctx context.Context, name string, handler v31.ServiceAccountTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceAccountTokenControllerMock.AddHandlerFunc: method is nil but ServiceAccountTokenController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockServiceAccountTokenControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceAccountTokenControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenController.AddHandlerCalls()) +func (mock *ServiceAccountTokenControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceAccountTokenControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ServiceAccountTokenControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ServiceAccountTokenControllerMock.EnqueueFunc: method is nil but ServiceAccountTokenController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockServiceAccountTokenControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockServiceAccountTokenControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedServiceAccountTokenController.EnqueueCalls()) +func (mock *ServiceAccountTokenControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockServiceAccountTokenControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockServiceAccountTokenControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ServiceAccountTokenControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ServiceAccountTokenControllerMock.EnqueueAfterFunc: method is nil but ServiceAccountTokenController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockServiceAccountTokenControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockServiceAccountTokenControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedServiceAccountTokenController.EnqueueAfterCalls()) +func (mock *ServiceAccountTokenControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockServiceAccountTokenControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockServiceAccountTokenControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ServiceAccountTokenControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ServiceAccountTokenControllerMock.GenericFunc: method is nil but ServiceAccountTokenController.Generic was just called") + } + callInfo := struct { + }{} + lockServiceAccountTokenControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockServiceAccountTokenControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedServiceAccountTokenController.GenericCalls()) +func (mock *ServiceAccountTokenControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountTokenControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockServiceAccountTokenControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ServiceAccountTokenControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ServiceAccountTokenControllerMock.InformerFunc: method is nil but ServiceAccountTokenController.Informer was just called") + } + callInfo := struct { + }{} + lockServiceAccountTokenControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockServiceAccountTokenControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedServiceAccountTokenController.InformerCalls()) +func (mock *ServiceAccountTokenControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountTokenControllerMockInformer.RLock() + calls = mock.calls.Informer + lockServiceAccountTokenControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ServiceAccountTokenControllerMock) Lister() v31.ServiceAccountTokenLister { + if mock.ListerFunc == nil { + panic("ServiceAccountTokenControllerMock.ListerFunc: method is nil but ServiceAccountTokenController.Lister was just called") + } + callInfo := struct { + }{} + lockServiceAccountTokenControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockServiceAccountTokenControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedServiceAccountTokenController.ListerCalls()) +func (mock *ServiceAccountTokenControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountTokenControllerMockLister.RLock() + calls = mock.calls.Lister + lockServiceAccountTokenControllerMockLister.RUnlock() + return calls +} + +var ( + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockServiceAccountTokenInterfaceMockAddClusterScopedHandler sync.RWMutex + lockServiceAccountTokenInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockServiceAccountTokenInterfaceMockAddFeatureHandler sync.RWMutex + lockServiceAccountTokenInterfaceMockAddFeatureLifecycle sync.RWMutex + lockServiceAccountTokenInterfaceMockAddHandler sync.RWMutex + lockServiceAccountTokenInterfaceMockAddLifecycle sync.RWMutex + lockServiceAccountTokenInterfaceMockController sync.RWMutex + lockServiceAccountTokenInterfaceMockCreate sync.RWMutex + lockServiceAccountTokenInterfaceMockDelete sync.RWMutex + lockServiceAccountTokenInterfaceMockDeleteCollection sync.RWMutex + lockServiceAccountTokenInterfaceMockDeleteNamespaced sync.RWMutex + lockServiceAccountTokenInterfaceMockGet sync.RWMutex + lockServiceAccountTokenInterfaceMockGetNamespaced sync.RWMutex + lockServiceAccountTokenInterfaceMockList sync.RWMutex + lockServiceAccountTokenInterfaceMockListNamespaced sync.RWMutex + lockServiceAccountTokenInterfaceMockObjectClient sync.RWMutex + lockServiceAccountTokenInterfaceMockUpdate sync.RWMutex + lockServiceAccountTokenInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ServiceAccountTokenInterfaceMock does implement v31.ServiceAccountTokenInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.ServiceAccountTokenInterface = &ServiceAccountTokenInterfaceMock{} + +// ServiceAccountTokenInterfaceMock is a mock implementation of v31.ServiceAccountTokenInterface. +// +// func TestSomethingThatUsesServiceAccountTokenInterface(t *testing.T) { +// +// // make and configure a mocked v31.ServiceAccountTokenInterface +// mockedServiceAccountTokenInterface := &ServiceAccountTokenInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ServiceAccountTokenLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.ServiceAccountTokenLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.ServiceAccountTokenController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedServiceAccountTokenInterface in code that requires v31.ServiceAccountTokenInterface +// // and then make assertions. +// +// } +type ServiceAccountTokenInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.ServiceAccountTokenLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.ServiceAccountTokenLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.ServiceAccountTokenController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ServiceAccountTokenHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ServiceAccountTokenLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.ServiceAccountTokenHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ServiceAccountTokenLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ServiceAccountTokenHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ServiceAccountTokenLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.ServiceAccountTokenHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.ServiceAccountTokenLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.ServiceAccountToken + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.ServiceAccountToken + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ServiceAccountTokenInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ServiceAccountTokenInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle + } + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockServiceAccountTokenInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ServiceAccountTokenInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockServiceAccountTokenInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockServiceAccountTokenInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddClusterScopedHandlerCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockServiceAccountTokenInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.ServiceAccountTokenLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ServiceAccountTokenInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddClusterScopedLifecycleCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.ServiceAccountTokenLifecycle + } + lockServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockServiceAccountTokenInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddFeatureHandlerFunc: method is nil but ServiceAccountTokenInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountTokenInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockServiceAccountTokenInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddFeatureHandlerCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockServiceAccountTokenInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.ServiceAccountTokenLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddFeatureLifecycleFunc: method is nil but ServiceAccountTokenInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockServiceAccountTokenInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockServiceAccountTokenInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddFeatureLifecycleCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.ServiceAccountTokenLifecycle + } + lockServiceAccountTokenInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockServiceAccountTokenInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.ServiceAccountTokenHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddHandlerFunc: method is nil but ServiceAccountTokenInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.ServiceAccountTokenHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockServiceAccountTokenInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockServiceAccountTokenInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddHandlerCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.ServiceAccountTokenHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.ServiceAccountTokenHandlerFunc + } + lockServiceAccountTokenInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockServiceAccountTokenInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ServiceAccountTokenInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.ServiceAccountTokenLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ServiceAccountTokenInterfaceMock.AddLifecycleFunc: method is nil but ServiceAccountTokenInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.ServiceAccountTokenLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockServiceAccountTokenInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockServiceAccountTokenInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.AddLifecycleCalls()) +func (mock *ServiceAccountTokenInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.ServiceAccountTokenLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.ServiceAccountTokenLifecycle + } + lockServiceAccountTokenInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockServiceAccountTokenInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ServiceAccountTokenInterfaceMock) Controller() v31.ServiceAccountTokenController { + if mock.ControllerFunc == nil { + panic("ServiceAccountTokenInterfaceMock.ControllerFunc: method is nil but ServiceAccountTokenInterface.Controller was just called") + } + callInfo := struct { + }{} + lockServiceAccountTokenInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockServiceAccountTokenInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.ControllerCalls()) +func (mock *ServiceAccountTokenInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountTokenInterfaceMockController.RLock() + calls = mock.calls.Controller + lockServiceAccountTokenInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ServiceAccountTokenInterfaceMock) Create(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { + if mock.CreateFunc == nil { + panic("ServiceAccountTokenInterfaceMock.CreateFunc: method is nil but ServiceAccountTokenInterface.Create was just called") + } + callInfo := struct { + In1 *v3.ServiceAccountToken + }{ + In1: in1, + } + lockServiceAccountTokenInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockServiceAccountTokenInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.CreateCalls()) +func (mock *ServiceAccountTokenInterfaceMock) CreateCalls() []struct { + In1 *v3.ServiceAccountToken +} { + var calls []struct { + In1 *v3.ServiceAccountToken + } + lockServiceAccountTokenInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockServiceAccountTokenInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ServiceAccountTokenInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ServiceAccountTokenInterfaceMock.DeleteFunc: method is nil but ServiceAccountTokenInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockServiceAccountTokenInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockServiceAccountTokenInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.DeleteCalls()) +func (mock *ServiceAccountTokenInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockServiceAccountTokenInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockServiceAccountTokenInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ServiceAccountTokenInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ServiceAccountTokenInterfaceMock.DeleteCollectionFunc: method is nil but ServiceAccountTokenInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockServiceAccountTokenInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockServiceAccountTokenInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.DeleteCollectionCalls()) +func (mock *ServiceAccountTokenInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockServiceAccountTokenInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockServiceAccountTokenInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ServiceAccountTokenInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ServiceAccountTokenInterfaceMock.DeleteNamespacedFunc: method is nil but ServiceAccountTokenInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockServiceAccountTokenInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockServiceAccountTokenInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.DeleteNamespacedCalls()) +func (mock *ServiceAccountTokenInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockServiceAccountTokenInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockServiceAccountTokenInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ServiceAccountTokenInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { + if mock.GetFunc == nil { + panic("ServiceAccountTokenInterfaceMock.GetFunc: method is nil but ServiceAccountTokenInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockServiceAccountTokenInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockServiceAccountTokenInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.GetCalls()) +func (mock *ServiceAccountTokenInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockServiceAccountTokenInterfaceMockGet.RLock() + calls = mock.calls.Get + lockServiceAccountTokenInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ServiceAccountTokenInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { + if mock.GetNamespacedFunc == nil { + panic("ServiceAccountTokenInterfaceMock.GetNamespacedFunc: method is nil but ServiceAccountTokenInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockServiceAccountTokenInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockServiceAccountTokenInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.GetNamespacedCalls()) +func (mock *ServiceAccountTokenInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockServiceAccountTokenInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockServiceAccountTokenInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ServiceAccountTokenInterfaceMock) List(opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { + if mock.ListFunc == nil { + panic("ServiceAccountTokenInterfaceMock.ListFunc: method is nil but ServiceAccountTokenInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceAccountTokenInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockServiceAccountTokenInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.ListCalls()) +func (mock *ServiceAccountTokenInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceAccountTokenInterfaceMockList.RLock() + calls = mock.calls.List + lockServiceAccountTokenInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ServiceAccountTokenInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { + if mock.ListNamespacedFunc == nil { + panic("ServiceAccountTokenInterfaceMock.ListNamespacedFunc: method is nil but ServiceAccountTokenInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockServiceAccountTokenInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockServiceAccountTokenInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.ListNamespacedCalls()) +func (mock *ServiceAccountTokenInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockServiceAccountTokenInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockServiceAccountTokenInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ServiceAccountTokenInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ServiceAccountTokenInterfaceMock.ObjectClientFunc: method is nil but ServiceAccountTokenInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockServiceAccountTokenInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockServiceAccountTokenInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.ObjectClientCalls()) +func (mock *ServiceAccountTokenInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockServiceAccountTokenInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockServiceAccountTokenInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ServiceAccountTokenInterfaceMock) Update(in1 *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { + if mock.UpdateFunc == nil { + panic("ServiceAccountTokenInterfaceMock.UpdateFunc: method is nil but ServiceAccountTokenInterface.Update was just called") + } + callInfo := struct { + In1 *v3.ServiceAccountToken + }{ + In1: in1, + } + lockServiceAccountTokenInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockServiceAccountTokenInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.UpdateCalls()) +func (mock *ServiceAccountTokenInterfaceMock) UpdateCalls() []struct { + In1 *v3.ServiceAccountToken +} { + var calls []struct { + In1 *v3.ServiceAccountToken + } + lockServiceAccountTokenInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockServiceAccountTokenInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ServiceAccountTokenInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ServiceAccountTokenInterfaceMock.WatchFunc: method is nil but ServiceAccountTokenInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockServiceAccountTokenInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockServiceAccountTokenInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedServiceAccountTokenInterface.WatchCalls()) +func (mock *ServiceAccountTokenInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockServiceAccountTokenInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockServiceAccountTokenInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockServiceAccountTokensGetterMockServiceAccountTokens sync.RWMutex +) + +// Ensure, that ServiceAccountTokensGetterMock does implement v31.ServiceAccountTokensGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.ServiceAccountTokensGetter = &ServiceAccountTokensGetterMock{} + +// ServiceAccountTokensGetterMock is a mock implementation of v31.ServiceAccountTokensGetter. +// +// func TestSomethingThatUsesServiceAccountTokensGetter(t *testing.T) { +// +// // make and configure a mocked v31.ServiceAccountTokensGetter +// mockedServiceAccountTokensGetter := &ServiceAccountTokensGetterMock{ +// ServiceAccountTokensFunc: func(namespace string) v31.ServiceAccountTokenInterface { +// panic("mock out the ServiceAccountTokens method") +// }, +// } +// +// // use mockedServiceAccountTokensGetter in code that requires v31.ServiceAccountTokensGetter +// // and then make assertions. +// +// } +type ServiceAccountTokensGetterMock struct { + // ServiceAccountTokensFunc mocks the ServiceAccountTokens method. + ServiceAccountTokensFunc func(namespace string) v31.ServiceAccountTokenInterface + + // calls tracks calls to the methods. + calls struct { + // ServiceAccountTokens holds details about calls to the ServiceAccountTokens method. + ServiceAccountTokens []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ServiceAccountTokens calls ServiceAccountTokensFunc. +func (mock *ServiceAccountTokensGetterMock) ServiceAccountTokens(namespace string) v31.ServiceAccountTokenInterface { + if mock.ServiceAccountTokensFunc == nil { + panic("ServiceAccountTokensGetterMock.ServiceAccountTokensFunc: method is nil but ServiceAccountTokensGetter.ServiceAccountTokens was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockServiceAccountTokensGetterMockServiceAccountTokens.Lock() + mock.calls.ServiceAccountTokens = append(mock.calls.ServiceAccountTokens, callInfo) + lockServiceAccountTokensGetterMockServiceAccountTokens.Unlock() + return mock.ServiceAccountTokensFunc(namespace) +} + +// ServiceAccountTokensCalls gets all the calls that were made to ServiceAccountTokens. +// Check the length with: +// +// len(mockedServiceAccountTokensGetter.ServiceAccountTokensCalls()) +func (mock *ServiceAccountTokensGetterMock) ServiceAccountTokensCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockServiceAccountTokensGetterMockServiceAccountTokens.RLock() + calls = mock.calls.ServiceAccountTokens + lockServiceAccountTokensGetterMockServiceAccountTokens.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_ssh_auth_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_ssh_auth_mock.go new file mode 100644 index 0000000..46f9e1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_ssh_auth_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockSSHAuthListerMockGet sync.RWMutex + lockSSHAuthListerMockList sync.RWMutex +) + +// Ensure, that SSHAuthListerMock does implement v31.SSHAuthLister. +// If this is not the case, regenerate this file with moq. +var _ v31.SSHAuthLister = &SSHAuthListerMock{} + +// SSHAuthListerMock is a mock implementation of v31.SSHAuthLister. +// +// func TestSomethingThatUsesSSHAuthLister(t *testing.T) { +// +// // make and configure a mocked v31.SSHAuthLister +// mockedSSHAuthLister := &SSHAuthListerMock{ +// GetFunc: func(namespace string, name string) (*v3.SSHAuth, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.SSHAuth, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedSSHAuthLister in code that requires v31.SSHAuthLister +// // and then make assertions. +// +// } +type SSHAuthListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.SSHAuth, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.SSHAuth, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *SSHAuthListerMock) Get(namespace string, name string) (*v3.SSHAuth, error) { + if mock.GetFunc == nil { + panic("SSHAuthListerMock.GetFunc: method is nil but SSHAuthLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSSHAuthListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSSHAuthListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSSHAuthLister.GetCalls()) +func (mock *SSHAuthListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSSHAuthListerMockGet.RLock() + calls = mock.calls.Get + lockSSHAuthListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SSHAuthListerMock) List(namespace string, selector labels.Selector) ([]*v3.SSHAuth, error) { + if mock.ListFunc == nil { + panic("SSHAuthListerMock.ListFunc: method is nil but SSHAuthLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockSSHAuthListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSSHAuthListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSSHAuthLister.ListCalls()) +func (mock *SSHAuthListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockSSHAuthListerMockList.RLock() + calls = mock.calls.List + lockSSHAuthListerMockList.RUnlock() + return calls +} + +var ( + lockSSHAuthControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockSSHAuthControllerMockAddClusterScopedHandler sync.RWMutex + lockSSHAuthControllerMockAddFeatureHandler sync.RWMutex + lockSSHAuthControllerMockAddHandler sync.RWMutex + lockSSHAuthControllerMockEnqueue sync.RWMutex + lockSSHAuthControllerMockEnqueueAfter sync.RWMutex + lockSSHAuthControllerMockGeneric sync.RWMutex + lockSSHAuthControllerMockInformer sync.RWMutex + lockSSHAuthControllerMockLister sync.RWMutex +) + +// Ensure, that SSHAuthControllerMock does implement v31.SSHAuthController. +// If this is not the case, regenerate this file with moq. +var _ v31.SSHAuthController = &SSHAuthControllerMock{} + +// SSHAuthControllerMock is a mock implementation of v31.SSHAuthController. +// +// func TestSomethingThatUsesSSHAuthController(t *testing.T) { +// +// // make and configure a mocked v31.SSHAuthController +// mockedSSHAuthController := &SSHAuthControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.SSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.SSHAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.SSHAuthLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedSSHAuthController in code that requires v31.SSHAuthController +// // and then make assertions. +// +// } +type SSHAuthControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SSHAuthHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.SSHAuthHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.SSHAuthHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.SSHAuthLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SSHAuthHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.SSHAuthHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SSHAuthHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.SSHAuthHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SSHAuthControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.SSHAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SSHAuthControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but SSHAuthController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSSHAuthControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSSHAuthControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSSHAuthController.AddClusterScopedFeatureHandlerCalls()) +func (mock *SSHAuthControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc + } + lockSSHAuthControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSSHAuthControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SSHAuthControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.SSHAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SSHAuthControllerMock.AddClusterScopedHandlerFunc: method is nil but SSHAuthController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockSSHAuthControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSSHAuthControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSSHAuthController.AddClusterScopedHandlerCalls()) +func (mock *SSHAuthControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.SSHAuthHandlerFunc + } + lockSSHAuthControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSSHAuthControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SSHAuthControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SSHAuthControllerMock.AddFeatureHandlerFunc: method is nil but SSHAuthController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSSHAuthControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSSHAuthControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSSHAuthController.AddFeatureHandlerCalls()) +func (mock *SSHAuthControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc + } + lockSSHAuthControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSSHAuthControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SSHAuthControllerMock) AddHandler(ctx context.Context, name string, handler v31.SSHAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SSHAuthControllerMock.AddHandlerFunc: method is nil but SSHAuthController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockSSHAuthControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSSHAuthControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSSHAuthController.AddHandlerCalls()) +func (mock *SSHAuthControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.SSHAuthHandlerFunc + } + lockSSHAuthControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSSHAuthControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *SSHAuthControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("SSHAuthControllerMock.EnqueueFunc: method is nil but SSHAuthController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockSSHAuthControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockSSHAuthControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedSSHAuthController.EnqueueCalls()) +func (mock *SSHAuthControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockSSHAuthControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockSSHAuthControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *SSHAuthControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("SSHAuthControllerMock.EnqueueAfterFunc: method is nil but SSHAuthController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockSSHAuthControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockSSHAuthControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedSSHAuthController.EnqueueAfterCalls()) +func (mock *SSHAuthControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockSSHAuthControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockSSHAuthControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *SSHAuthControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("SSHAuthControllerMock.GenericFunc: method is nil but SSHAuthController.Generic was just called") + } + callInfo := struct { + }{} + lockSSHAuthControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockSSHAuthControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedSSHAuthController.GenericCalls()) +func (mock *SSHAuthControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockSSHAuthControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockSSHAuthControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *SSHAuthControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("SSHAuthControllerMock.InformerFunc: method is nil but SSHAuthController.Informer was just called") + } + callInfo := struct { + }{} + lockSSHAuthControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockSSHAuthControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedSSHAuthController.InformerCalls()) +func (mock *SSHAuthControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockSSHAuthControllerMockInformer.RLock() + calls = mock.calls.Informer + lockSSHAuthControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *SSHAuthControllerMock) Lister() v31.SSHAuthLister { + if mock.ListerFunc == nil { + panic("SSHAuthControllerMock.ListerFunc: method is nil but SSHAuthController.Lister was just called") + } + callInfo := struct { + }{} + lockSSHAuthControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockSSHAuthControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedSSHAuthController.ListerCalls()) +func (mock *SSHAuthControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockSSHAuthControllerMockLister.RLock() + calls = mock.calls.Lister + lockSSHAuthControllerMockLister.RUnlock() + return calls +} + +var ( + lockSSHAuthInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockSSHAuthInterfaceMockAddClusterScopedHandler sync.RWMutex + lockSSHAuthInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockSSHAuthInterfaceMockAddFeatureHandler sync.RWMutex + lockSSHAuthInterfaceMockAddFeatureLifecycle sync.RWMutex + lockSSHAuthInterfaceMockAddHandler sync.RWMutex + lockSSHAuthInterfaceMockAddLifecycle sync.RWMutex + lockSSHAuthInterfaceMockController sync.RWMutex + lockSSHAuthInterfaceMockCreate sync.RWMutex + lockSSHAuthInterfaceMockDelete sync.RWMutex + lockSSHAuthInterfaceMockDeleteCollection sync.RWMutex + lockSSHAuthInterfaceMockDeleteNamespaced sync.RWMutex + lockSSHAuthInterfaceMockGet sync.RWMutex + lockSSHAuthInterfaceMockGetNamespaced sync.RWMutex + lockSSHAuthInterfaceMockList sync.RWMutex + lockSSHAuthInterfaceMockListNamespaced sync.RWMutex + lockSSHAuthInterfaceMockObjectClient sync.RWMutex + lockSSHAuthInterfaceMockUpdate sync.RWMutex + lockSSHAuthInterfaceMockWatch sync.RWMutex +) + +// Ensure, that SSHAuthInterfaceMock does implement v31.SSHAuthInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.SSHAuthInterface = &SSHAuthInterfaceMock{} + +// SSHAuthInterfaceMock is a mock implementation of v31.SSHAuthInterface. +// +// func TestSomethingThatUsesSSHAuthInterface(t *testing.T) { +// +// // make and configure a mocked v31.SSHAuthInterface +// mockedSSHAuthInterface := &SSHAuthInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SSHAuthLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.SSHAuthHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.SSHAuthLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.SSHAuthController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.SSHAuth) (*v3.SSHAuth, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.SSHAuthList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.SSHAuthList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.SSHAuth) (*v3.SSHAuth, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedSSHAuthInterface in code that requires v31.SSHAuthInterface +// // and then make assertions. +// +// } +type SSHAuthInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.SSHAuthLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.SSHAuthHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.SSHAuthLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.SSHAuthController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.SSHAuth) (*v3.SSHAuth, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.SSHAuth, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.SSHAuth, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.SSHAuthList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.SSHAuthList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.SSHAuth) (*v3.SSHAuth, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SSHAuthHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SSHAuthLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.SSHAuthHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SSHAuthLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SSHAuthHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SSHAuthLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.SSHAuthHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.SSHAuthLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.SSHAuth + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.SSHAuth + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *SSHAuthInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("SSHAuthInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but SSHAuthInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSSHAuthInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockSSHAuthInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *SSHAuthInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc + } + lockSSHAuthInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockSSHAuthInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *SSHAuthInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("SSHAuthInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but SSHAuthInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *SSHAuthInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle + } + lockSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockSSHAuthInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *SSHAuthInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.SSHAuthHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("SSHAuthInterfaceMock.AddClusterScopedHandlerFunc: method is nil but SSHAuthInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockSSHAuthInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockSSHAuthInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddClusterScopedHandlerCalls()) +func (mock *SSHAuthInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.SSHAuthHandlerFunc + } + lockSSHAuthInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockSSHAuthInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *SSHAuthInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.SSHAuthLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("SSHAuthInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but SSHAuthInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockSSHAuthInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockSSHAuthInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddClusterScopedLifecycleCalls()) +func (mock *SSHAuthInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.SSHAuthLifecycle + } + lockSSHAuthInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockSSHAuthInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *SSHAuthInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.SSHAuthHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("SSHAuthInterfaceMock.AddFeatureHandlerFunc: method is nil but SSHAuthInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockSSHAuthInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockSSHAuthInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddFeatureHandlerCalls()) +func (mock *SSHAuthInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.SSHAuthHandlerFunc + } + lockSSHAuthInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockSSHAuthInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *SSHAuthInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.SSHAuthLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("SSHAuthInterfaceMock.AddFeatureLifecycleFunc: method is nil but SSHAuthInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SSHAuthLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockSSHAuthInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockSSHAuthInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddFeatureLifecycleCalls()) +func (mock *SSHAuthInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.SSHAuthLifecycle + } + lockSSHAuthInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockSSHAuthInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *SSHAuthInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.SSHAuthHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("SSHAuthInterfaceMock.AddHandlerFunc: method is nil but SSHAuthInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.SSHAuthHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockSSHAuthInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockSSHAuthInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddHandlerCalls()) +func (mock *SSHAuthInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.SSHAuthHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.SSHAuthHandlerFunc + } + lockSSHAuthInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockSSHAuthInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *SSHAuthInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.SSHAuthLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("SSHAuthInterfaceMock.AddLifecycleFunc: method is nil but SSHAuthInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.SSHAuthLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockSSHAuthInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockSSHAuthInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedSSHAuthInterface.AddLifecycleCalls()) +func (mock *SSHAuthInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.SSHAuthLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.SSHAuthLifecycle + } + lockSSHAuthInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockSSHAuthInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *SSHAuthInterfaceMock) Controller() v31.SSHAuthController { + if mock.ControllerFunc == nil { + panic("SSHAuthInterfaceMock.ControllerFunc: method is nil but SSHAuthInterface.Controller was just called") + } + callInfo := struct { + }{} + lockSSHAuthInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockSSHAuthInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedSSHAuthInterface.ControllerCalls()) +func (mock *SSHAuthInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockSSHAuthInterfaceMockController.RLock() + calls = mock.calls.Controller + lockSSHAuthInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *SSHAuthInterfaceMock) Create(in1 *v3.SSHAuth) (*v3.SSHAuth, error) { + if mock.CreateFunc == nil { + panic("SSHAuthInterfaceMock.CreateFunc: method is nil but SSHAuthInterface.Create was just called") + } + callInfo := struct { + In1 *v3.SSHAuth + }{ + In1: in1, + } + lockSSHAuthInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockSSHAuthInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedSSHAuthInterface.CreateCalls()) +func (mock *SSHAuthInterfaceMock) CreateCalls() []struct { + In1 *v3.SSHAuth +} { + var calls []struct { + In1 *v3.SSHAuth + } + lockSSHAuthInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockSSHAuthInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *SSHAuthInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("SSHAuthInterfaceMock.DeleteFunc: method is nil but SSHAuthInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockSSHAuthInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockSSHAuthInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedSSHAuthInterface.DeleteCalls()) +func (mock *SSHAuthInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockSSHAuthInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockSSHAuthInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *SSHAuthInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("SSHAuthInterfaceMock.DeleteCollectionFunc: method is nil but SSHAuthInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockSSHAuthInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockSSHAuthInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedSSHAuthInterface.DeleteCollectionCalls()) +func (mock *SSHAuthInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockSSHAuthInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockSSHAuthInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *SSHAuthInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("SSHAuthInterfaceMock.DeleteNamespacedFunc: method is nil but SSHAuthInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockSSHAuthInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockSSHAuthInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedSSHAuthInterface.DeleteNamespacedCalls()) +func (mock *SSHAuthInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockSSHAuthInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockSSHAuthInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *SSHAuthInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { + if mock.GetFunc == nil { + panic("SSHAuthInterfaceMock.GetFunc: method is nil but SSHAuthInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockSSHAuthInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockSSHAuthInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedSSHAuthInterface.GetCalls()) +func (mock *SSHAuthInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockSSHAuthInterfaceMockGet.RLock() + calls = mock.calls.Get + lockSSHAuthInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *SSHAuthInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { + if mock.GetNamespacedFunc == nil { + panic("SSHAuthInterfaceMock.GetNamespacedFunc: method is nil but SSHAuthInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockSSHAuthInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockSSHAuthInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedSSHAuthInterface.GetNamespacedCalls()) +func (mock *SSHAuthInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockSSHAuthInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockSSHAuthInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *SSHAuthInterfaceMock) List(opts metav1.ListOptions) (*v3.SSHAuthList, error) { + if mock.ListFunc == nil { + panic("SSHAuthInterfaceMock.ListFunc: method is nil but SSHAuthInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSSHAuthInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockSSHAuthInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedSSHAuthInterface.ListCalls()) +func (mock *SSHAuthInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSSHAuthInterfaceMockList.RLock() + calls = mock.calls.List + lockSSHAuthInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *SSHAuthInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SSHAuthList, error) { + if mock.ListNamespacedFunc == nil { + panic("SSHAuthInterfaceMock.ListNamespacedFunc: method is nil but SSHAuthInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockSSHAuthInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockSSHAuthInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedSSHAuthInterface.ListNamespacedCalls()) +func (mock *SSHAuthInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockSSHAuthInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockSSHAuthInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *SSHAuthInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("SSHAuthInterfaceMock.ObjectClientFunc: method is nil but SSHAuthInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockSSHAuthInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockSSHAuthInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedSSHAuthInterface.ObjectClientCalls()) +func (mock *SSHAuthInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockSSHAuthInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockSSHAuthInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *SSHAuthInterfaceMock) Update(in1 *v3.SSHAuth) (*v3.SSHAuth, error) { + if mock.UpdateFunc == nil { + panic("SSHAuthInterfaceMock.UpdateFunc: method is nil but SSHAuthInterface.Update was just called") + } + callInfo := struct { + In1 *v3.SSHAuth + }{ + In1: in1, + } + lockSSHAuthInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockSSHAuthInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedSSHAuthInterface.UpdateCalls()) +func (mock *SSHAuthInterfaceMock) UpdateCalls() []struct { + In1 *v3.SSHAuth +} { + var calls []struct { + In1 *v3.SSHAuth + } + lockSSHAuthInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockSSHAuthInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *SSHAuthInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("SSHAuthInterfaceMock.WatchFunc: method is nil but SSHAuthInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockSSHAuthInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockSSHAuthInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedSSHAuthInterface.WatchCalls()) +func (mock *SSHAuthInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockSSHAuthInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockSSHAuthInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockSSHAuthsGetterMockSSHAuths sync.RWMutex +) + +// Ensure, that SSHAuthsGetterMock does implement v31.SSHAuthsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.SSHAuthsGetter = &SSHAuthsGetterMock{} + +// SSHAuthsGetterMock is a mock implementation of v31.SSHAuthsGetter. +// +// func TestSomethingThatUsesSSHAuthsGetter(t *testing.T) { +// +// // make and configure a mocked v31.SSHAuthsGetter +// mockedSSHAuthsGetter := &SSHAuthsGetterMock{ +// SSHAuthsFunc: func(namespace string) v31.SSHAuthInterface { +// panic("mock out the SSHAuths method") +// }, +// } +// +// // use mockedSSHAuthsGetter in code that requires v31.SSHAuthsGetter +// // and then make assertions. +// +// } +type SSHAuthsGetterMock struct { + // SSHAuthsFunc mocks the SSHAuths method. + SSHAuthsFunc func(namespace string) v31.SSHAuthInterface + + // calls tracks calls to the methods. + calls struct { + // SSHAuths holds details about calls to the SSHAuths method. + SSHAuths []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// SSHAuths calls SSHAuthsFunc. +func (mock *SSHAuthsGetterMock) SSHAuths(namespace string) v31.SSHAuthInterface { + if mock.SSHAuthsFunc == nil { + panic("SSHAuthsGetterMock.SSHAuthsFunc: method is nil but SSHAuthsGetter.SSHAuths was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockSSHAuthsGetterMockSSHAuths.Lock() + mock.calls.SSHAuths = append(mock.calls.SSHAuths, callInfo) + lockSSHAuthsGetterMockSSHAuths.Unlock() + return mock.SSHAuthsFunc(namespace) +} + +// SSHAuthsCalls gets all the calls that were made to SSHAuths. +// Check the length with: +// +// len(mockedSSHAuthsGetter.SSHAuthsCalls()) +func (mock *SSHAuthsGetterMock) SSHAuthsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockSSHAuthsGetterMockSSHAuths.RLock() + calls = mock.calls.SSHAuths + lockSSHAuthsGetterMockSSHAuths.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_workload_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_workload_mock.go new file mode 100644 index 0000000..dd6d250 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/fakes/zz_generated_workload_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v31 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockWorkloadListerMockGet sync.RWMutex + lockWorkloadListerMockList sync.RWMutex +) + +// Ensure, that WorkloadListerMock does implement v31.WorkloadLister. +// If this is not the case, regenerate this file with moq. +var _ v31.WorkloadLister = &WorkloadListerMock{} + +// WorkloadListerMock is a mock implementation of v31.WorkloadLister. +// +// func TestSomethingThatUsesWorkloadLister(t *testing.T) { +// +// // make and configure a mocked v31.WorkloadLister +// mockedWorkloadLister := &WorkloadListerMock{ +// GetFunc: func(namespace string, name string) (*v3.Workload, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v3.Workload, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedWorkloadLister in code that requires v31.WorkloadLister +// // and then make assertions. +// +// } +type WorkloadListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v3.Workload, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v3.Workload, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *WorkloadListerMock) Get(namespace string, name string) (*v3.Workload, error) { + if mock.GetFunc == nil { + panic("WorkloadListerMock.GetFunc: method is nil but WorkloadLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockWorkloadListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockWorkloadListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedWorkloadLister.GetCalls()) +func (mock *WorkloadListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockWorkloadListerMockGet.RLock() + calls = mock.calls.Get + lockWorkloadListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *WorkloadListerMock) List(namespace string, selector labels.Selector) ([]*v3.Workload, error) { + if mock.ListFunc == nil { + panic("WorkloadListerMock.ListFunc: method is nil but WorkloadLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockWorkloadListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockWorkloadListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedWorkloadLister.ListCalls()) +func (mock *WorkloadListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockWorkloadListerMockList.RLock() + calls = mock.calls.List + lockWorkloadListerMockList.RUnlock() + return calls +} + +var ( + lockWorkloadControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockWorkloadControllerMockAddClusterScopedHandler sync.RWMutex + lockWorkloadControllerMockAddFeatureHandler sync.RWMutex + lockWorkloadControllerMockAddHandler sync.RWMutex + lockWorkloadControllerMockEnqueue sync.RWMutex + lockWorkloadControllerMockEnqueueAfter sync.RWMutex + lockWorkloadControllerMockGeneric sync.RWMutex + lockWorkloadControllerMockInformer sync.RWMutex + lockWorkloadControllerMockLister sync.RWMutex +) + +// Ensure, that WorkloadControllerMock does implement v31.WorkloadController. +// If this is not the case, regenerate this file with moq. +var _ v31.WorkloadController = &WorkloadControllerMock{} + +// WorkloadControllerMock is a mock implementation of v31.WorkloadController. +// +// func TestSomethingThatUsesWorkloadController(t *testing.T) { +// +// // make and configure a mocked v31.WorkloadController +// mockedWorkloadController := &WorkloadControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.WorkloadHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v31.WorkloadHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v31.WorkloadHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v31.WorkloadLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedWorkloadController in code that requires v31.WorkloadController +// // and then make assertions. +// +// } +type WorkloadControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.WorkloadHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v31.WorkloadHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v31.WorkloadHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v31.WorkloadLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.WorkloadHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v31.WorkloadHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.WorkloadHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v31.WorkloadHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *WorkloadControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v31.WorkloadHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("WorkloadControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but WorkloadController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockWorkloadControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockWorkloadControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedWorkloadController.AddClusterScopedFeatureHandlerCalls()) +func (mock *WorkloadControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc + } + lockWorkloadControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockWorkloadControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *WorkloadControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v31.WorkloadHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("WorkloadControllerMock.AddClusterScopedHandlerFunc: method is nil but WorkloadController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockWorkloadControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockWorkloadControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedWorkloadController.AddClusterScopedHandlerCalls()) +func (mock *WorkloadControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v31.WorkloadHandlerFunc + } + lockWorkloadControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockWorkloadControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *WorkloadControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("WorkloadControllerMock.AddFeatureHandlerFunc: method is nil but WorkloadController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockWorkloadControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockWorkloadControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedWorkloadController.AddFeatureHandlerCalls()) +func (mock *WorkloadControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc + } + lockWorkloadControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockWorkloadControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *WorkloadControllerMock) AddHandler(ctx context.Context, name string, handler v31.WorkloadHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("WorkloadControllerMock.AddHandlerFunc: method is nil but WorkloadController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockWorkloadControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockWorkloadControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedWorkloadController.AddHandlerCalls()) +func (mock *WorkloadControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v31.WorkloadHandlerFunc + } + lockWorkloadControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockWorkloadControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *WorkloadControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("WorkloadControllerMock.EnqueueFunc: method is nil but WorkloadController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockWorkloadControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockWorkloadControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedWorkloadController.EnqueueCalls()) +func (mock *WorkloadControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockWorkloadControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockWorkloadControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *WorkloadControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("WorkloadControllerMock.EnqueueAfterFunc: method is nil but WorkloadController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockWorkloadControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockWorkloadControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedWorkloadController.EnqueueAfterCalls()) +func (mock *WorkloadControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockWorkloadControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockWorkloadControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *WorkloadControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("WorkloadControllerMock.GenericFunc: method is nil but WorkloadController.Generic was just called") + } + callInfo := struct { + }{} + lockWorkloadControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockWorkloadControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedWorkloadController.GenericCalls()) +func (mock *WorkloadControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockWorkloadControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockWorkloadControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *WorkloadControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("WorkloadControllerMock.InformerFunc: method is nil but WorkloadController.Informer was just called") + } + callInfo := struct { + }{} + lockWorkloadControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockWorkloadControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedWorkloadController.InformerCalls()) +func (mock *WorkloadControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockWorkloadControllerMockInformer.RLock() + calls = mock.calls.Informer + lockWorkloadControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *WorkloadControllerMock) Lister() v31.WorkloadLister { + if mock.ListerFunc == nil { + panic("WorkloadControllerMock.ListerFunc: method is nil but WorkloadController.Lister was just called") + } + callInfo := struct { + }{} + lockWorkloadControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockWorkloadControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedWorkloadController.ListerCalls()) +func (mock *WorkloadControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockWorkloadControllerMockLister.RLock() + calls = mock.calls.Lister + lockWorkloadControllerMockLister.RUnlock() + return calls +} + +var ( + lockWorkloadInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockWorkloadInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockWorkloadInterfaceMockAddClusterScopedHandler sync.RWMutex + lockWorkloadInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockWorkloadInterfaceMockAddFeatureHandler sync.RWMutex + lockWorkloadInterfaceMockAddFeatureLifecycle sync.RWMutex + lockWorkloadInterfaceMockAddHandler sync.RWMutex + lockWorkloadInterfaceMockAddLifecycle sync.RWMutex + lockWorkloadInterfaceMockController sync.RWMutex + lockWorkloadInterfaceMockCreate sync.RWMutex + lockWorkloadInterfaceMockDelete sync.RWMutex + lockWorkloadInterfaceMockDeleteCollection sync.RWMutex + lockWorkloadInterfaceMockDeleteNamespaced sync.RWMutex + lockWorkloadInterfaceMockGet sync.RWMutex + lockWorkloadInterfaceMockGetNamespaced sync.RWMutex + lockWorkloadInterfaceMockList sync.RWMutex + lockWorkloadInterfaceMockListNamespaced sync.RWMutex + lockWorkloadInterfaceMockObjectClient sync.RWMutex + lockWorkloadInterfaceMockUpdate sync.RWMutex + lockWorkloadInterfaceMockWatch sync.RWMutex +) + +// Ensure, that WorkloadInterfaceMock does implement v31.WorkloadInterface. +// If this is not the case, regenerate this file with moq. +var _ v31.WorkloadInterface = &WorkloadInterfaceMock{} + +// WorkloadInterfaceMock is a mock implementation of v31.WorkloadInterface. +// +// func TestSomethingThatUsesWorkloadInterface(t *testing.T) { +// +// // make and configure a mocked v31.WorkloadInterface +// mockedWorkloadInterface := &WorkloadInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.WorkloadLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v31.WorkloadLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v31.WorkloadLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v31.WorkloadHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v31.WorkloadLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v31.WorkloadController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v3.Workload) (*v3.Workload, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v3.Workload, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v3.Workload, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v3.WorkloadList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v3.WorkloadList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v3.Workload) (*v3.Workload, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedWorkloadInterface in code that requires v31.WorkloadInterface +// // and then make assertions. +// +// } +type WorkloadInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.WorkloadLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v31.WorkloadLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v31.WorkloadLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v31.WorkloadHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v31.WorkloadLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v31.WorkloadController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v3.Workload) (*v3.Workload, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v3.Workload, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v3.Workload, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v3.WorkloadList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v3.WorkloadList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v3.Workload) (*v3.Workload, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.WorkloadHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.WorkloadLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v31.WorkloadHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.WorkloadLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.WorkloadHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.WorkloadLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v31.WorkloadHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v31.WorkloadLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v3.Workload + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v3.Workload + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *WorkloadInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("WorkloadInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but WorkloadInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockWorkloadInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockWorkloadInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedWorkloadInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *WorkloadInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc + } + lockWorkloadInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockWorkloadInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *WorkloadInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v31.WorkloadLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("WorkloadInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but WorkloadInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockWorkloadInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockWorkloadInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedWorkloadInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *WorkloadInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle + } + lockWorkloadInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockWorkloadInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *WorkloadInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v31.WorkloadHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("WorkloadInterfaceMock.AddClusterScopedHandlerFunc: method is nil but WorkloadInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockWorkloadInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockWorkloadInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedWorkloadInterface.AddClusterScopedHandlerCalls()) +func (mock *WorkloadInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v31.WorkloadHandlerFunc + } + lockWorkloadInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockWorkloadInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *WorkloadInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v31.WorkloadLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("WorkloadInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but WorkloadInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockWorkloadInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockWorkloadInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedWorkloadInterface.AddClusterScopedLifecycleCalls()) +func (mock *WorkloadInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v31.WorkloadLifecycle + } + lockWorkloadInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockWorkloadInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *WorkloadInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v31.WorkloadHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("WorkloadInterfaceMock.AddFeatureHandlerFunc: method is nil but WorkloadInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockWorkloadInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockWorkloadInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedWorkloadInterface.AddFeatureHandlerCalls()) +func (mock *WorkloadInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v31.WorkloadHandlerFunc + } + lockWorkloadInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockWorkloadInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *WorkloadInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v31.WorkloadLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("WorkloadInterfaceMock.AddFeatureLifecycleFunc: method is nil but WorkloadInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.WorkloadLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockWorkloadInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockWorkloadInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedWorkloadInterface.AddFeatureLifecycleCalls()) +func (mock *WorkloadInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.WorkloadLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v31.WorkloadLifecycle + } + lockWorkloadInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockWorkloadInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *WorkloadInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v31.WorkloadHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("WorkloadInterfaceMock.AddHandlerFunc: method is nil but WorkloadInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v31.WorkloadHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockWorkloadInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockWorkloadInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedWorkloadInterface.AddHandlerCalls()) +func (mock *WorkloadInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v31.WorkloadHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v31.WorkloadHandlerFunc + } + lockWorkloadInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockWorkloadInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *WorkloadInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v31.WorkloadLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("WorkloadInterfaceMock.AddLifecycleFunc: method is nil but WorkloadInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v31.WorkloadLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockWorkloadInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockWorkloadInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedWorkloadInterface.AddLifecycleCalls()) +func (mock *WorkloadInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v31.WorkloadLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v31.WorkloadLifecycle + } + lockWorkloadInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockWorkloadInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *WorkloadInterfaceMock) Controller() v31.WorkloadController { + if mock.ControllerFunc == nil { + panic("WorkloadInterfaceMock.ControllerFunc: method is nil but WorkloadInterface.Controller was just called") + } + callInfo := struct { + }{} + lockWorkloadInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockWorkloadInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedWorkloadInterface.ControllerCalls()) +func (mock *WorkloadInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockWorkloadInterfaceMockController.RLock() + calls = mock.calls.Controller + lockWorkloadInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *WorkloadInterfaceMock) Create(in1 *v3.Workload) (*v3.Workload, error) { + if mock.CreateFunc == nil { + panic("WorkloadInterfaceMock.CreateFunc: method is nil but WorkloadInterface.Create was just called") + } + callInfo := struct { + In1 *v3.Workload + }{ + In1: in1, + } + lockWorkloadInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockWorkloadInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedWorkloadInterface.CreateCalls()) +func (mock *WorkloadInterfaceMock) CreateCalls() []struct { + In1 *v3.Workload +} { + var calls []struct { + In1 *v3.Workload + } + lockWorkloadInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockWorkloadInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *WorkloadInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("WorkloadInterfaceMock.DeleteFunc: method is nil but WorkloadInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockWorkloadInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockWorkloadInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedWorkloadInterface.DeleteCalls()) +func (mock *WorkloadInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockWorkloadInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockWorkloadInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *WorkloadInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("WorkloadInterfaceMock.DeleteCollectionFunc: method is nil but WorkloadInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockWorkloadInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockWorkloadInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedWorkloadInterface.DeleteCollectionCalls()) +func (mock *WorkloadInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockWorkloadInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockWorkloadInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *WorkloadInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("WorkloadInterfaceMock.DeleteNamespacedFunc: method is nil but WorkloadInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockWorkloadInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockWorkloadInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedWorkloadInterface.DeleteNamespacedCalls()) +func (mock *WorkloadInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockWorkloadInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockWorkloadInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *WorkloadInterfaceMock) Get(name string, opts metav1.GetOptions) (*v3.Workload, error) { + if mock.GetFunc == nil { + panic("WorkloadInterfaceMock.GetFunc: method is nil but WorkloadInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockWorkloadInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockWorkloadInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedWorkloadInterface.GetCalls()) +func (mock *WorkloadInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockWorkloadInterfaceMockGet.RLock() + calls = mock.calls.Get + lockWorkloadInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *WorkloadInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v3.Workload, error) { + if mock.GetNamespacedFunc == nil { + panic("WorkloadInterfaceMock.GetNamespacedFunc: method is nil but WorkloadInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockWorkloadInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockWorkloadInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedWorkloadInterface.GetNamespacedCalls()) +func (mock *WorkloadInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockWorkloadInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockWorkloadInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *WorkloadInterfaceMock) List(opts metav1.ListOptions) (*v3.WorkloadList, error) { + if mock.ListFunc == nil { + panic("WorkloadInterfaceMock.ListFunc: method is nil but WorkloadInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockWorkloadInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockWorkloadInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedWorkloadInterface.ListCalls()) +func (mock *WorkloadInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockWorkloadInterfaceMockList.RLock() + calls = mock.calls.List + lockWorkloadInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *WorkloadInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.WorkloadList, error) { + if mock.ListNamespacedFunc == nil { + panic("WorkloadInterfaceMock.ListNamespacedFunc: method is nil but WorkloadInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockWorkloadInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockWorkloadInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedWorkloadInterface.ListNamespacedCalls()) +func (mock *WorkloadInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockWorkloadInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockWorkloadInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *WorkloadInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("WorkloadInterfaceMock.ObjectClientFunc: method is nil but WorkloadInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockWorkloadInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockWorkloadInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedWorkloadInterface.ObjectClientCalls()) +func (mock *WorkloadInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockWorkloadInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockWorkloadInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *WorkloadInterfaceMock) Update(in1 *v3.Workload) (*v3.Workload, error) { + if mock.UpdateFunc == nil { + panic("WorkloadInterfaceMock.UpdateFunc: method is nil but WorkloadInterface.Update was just called") + } + callInfo := struct { + In1 *v3.Workload + }{ + In1: in1, + } + lockWorkloadInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockWorkloadInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedWorkloadInterface.UpdateCalls()) +func (mock *WorkloadInterfaceMock) UpdateCalls() []struct { + In1 *v3.Workload +} { + var calls []struct { + In1 *v3.Workload + } + lockWorkloadInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockWorkloadInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *WorkloadInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("WorkloadInterfaceMock.WatchFunc: method is nil but WorkloadInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockWorkloadInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockWorkloadInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedWorkloadInterface.WatchCalls()) +func (mock *WorkloadInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockWorkloadInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockWorkloadInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockWorkloadsGetterMockWorkloads sync.RWMutex +) + +// Ensure, that WorkloadsGetterMock does implement v31.WorkloadsGetter. +// If this is not the case, regenerate this file with moq. +var _ v31.WorkloadsGetter = &WorkloadsGetterMock{} + +// WorkloadsGetterMock is a mock implementation of v31.WorkloadsGetter. +// +// func TestSomethingThatUsesWorkloadsGetter(t *testing.T) { +// +// // make and configure a mocked v31.WorkloadsGetter +// mockedWorkloadsGetter := &WorkloadsGetterMock{ +// WorkloadsFunc: func(namespace string) v31.WorkloadInterface { +// panic("mock out the Workloads method") +// }, +// } +// +// // use mockedWorkloadsGetter in code that requires v31.WorkloadsGetter +// // and then make assertions. +// +// } +type WorkloadsGetterMock struct { + // WorkloadsFunc mocks the Workloads method. + WorkloadsFunc func(namespace string) v31.WorkloadInterface + + // calls tracks calls to the methods. + calls struct { + // Workloads holds details about calls to the Workloads method. + Workloads []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Workloads calls WorkloadsFunc. +func (mock *WorkloadsGetterMock) Workloads(namespace string) v31.WorkloadInterface { + if mock.WorkloadsFunc == nil { + panic("WorkloadsGetterMock.WorkloadsFunc: method is nil but WorkloadsGetter.Workloads was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockWorkloadsGetterMockWorkloads.Lock() + mock.calls.Workloads = append(mock.calls.Workloads, callInfo) + lockWorkloadsGetterMockWorkloads.Unlock() + return mock.WorkloadsFunc(namespace) +} + +// WorkloadsCalls gets all the calls that were made to Workloads. +// Check the length with: +// +// len(mockedWorkloadsGetter.WorkloadsCalls()) +func (mock *WorkloadsGetterMock) WorkloadsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockWorkloadsGetterMockWorkloads.RLock() + calls = mock.calls.Workloads + lockWorkloadsGetterMockWorkloads.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_controller.go new file mode 100644 index 0000000..41a21ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + AppGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "App", + } + AppResource = metav1.APIResource{ + Name: "apps", + SingularName: "app", + Namespaced: true, + + Kind: AppGroupVersionKind.Kind, + } + + AppGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "apps", + } +) + +func init() { + resource.Put(AppGroupVersionResource) +} + +// Deprecated: use v3.App instead +type App = v3.App + +func NewApp(namespace, name string, obj v3.App) *v3.App { + obj.APIVersion, obj.Kind = AppGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type AppHandlerFunc func(key string, obj *v3.App) (runtime.Object, error) + +type AppChangeHandlerFunc func(obj *v3.App) (runtime.Object, error) + +type AppLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.App, err error) + Get(namespace, name string) (*v3.App, error) +} + +type AppController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() AppLister + AddHandler(ctx context.Context, name string, handler AppHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler AppHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler AppHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type AppInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.App) (*v3.App, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.App, error) + Get(name string, opts metav1.GetOptions) (*v3.App, error) + Update(*v3.App) (*v3.App, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.AppList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() AppController + AddHandler(ctx context.Context, name string, sync AppHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle AppLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AppLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AppHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AppHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AppLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AppLifecycle) +} + +type appLister struct { + ns string + controller *appController +} + +func (l *appLister) List(namespace string, selector labels.Selector) (ret []*v3.App, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.App)) + }) + return +} + +func (l *appLister) Get(namespace, name string) (*v3.App, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: AppGroupVersionKind.Group, + Resource: AppGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.App), nil +} + +type appController struct { + ns string + controller.GenericController +} + +func (c *appController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *appController) Lister() AppLister { + return &appLister{ + ns: c.ns, + controller: c, + } +} + +func (c *appController) AddHandler(ctx context.Context, name string, handler AppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.App); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler AppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.App); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler AppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.App); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler AppHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.App); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type appFactory struct { +} + +func (c appFactory) Object() runtime.Object { + return &v3.App{} +} + +func (c appFactory) List() runtime.Object { + return &v3.AppList{} +} + +func (s *appClient) Controller() AppController { + genericController := controller.NewGenericController(s.ns, AppGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(AppGroupVersionResource, AppGroupVersionKind.Kind, true)) + + return &appController{ + ns: s.ns, + GenericController: genericController, + } +} + +type appClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller AppController +} + +func (s *appClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *appClient) Create(o *v3.App) (*v3.App, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.App), err +} + +func (s *appClient) Get(name string, opts metav1.GetOptions) (*v3.App, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.App), err +} + +func (s *appClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.App, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.App), err +} + +func (s *appClient) Update(o *v3.App) (*v3.App, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.App), err +} + +func (s *appClient) UpdateStatus(o *v3.App) (*v3.App, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.App), err +} + +func (s *appClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *appClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *appClient) List(opts metav1.ListOptions) (*v3.AppList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.AppList), err +} + +func (s *appClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.AppList), err +} + +func (s *appClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *appClient) Patch(o *v3.App, patchType types.PatchType, data []byte, subresources ...string) (*v3.App, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.App), err +} + +func (s *appClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *appClient) AddHandler(ctx context.Context, name string, sync AppHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *appClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *appClient) AddLifecycle(ctx context.Context, name string, lifecycle AppLifecycle) { + sync := NewAppLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *appClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AppLifecycle) { + sync := NewAppLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *appClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AppHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *appClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AppHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *appClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AppLifecycle) { + sync := NewAppLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *appClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AppLifecycle) { + sync := NewAppLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_lifecycle_adapter.go new file mode 100644 index 0000000..83e3d7d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type AppLifecycle interface { + Create(obj *v3.App) (runtime.Object, error) + Remove(obj *v3.App) (runtime.Object, error) + Updated(obj *v3.App) (runtime.Object, error) +} + +type appLifecycleAdapter struct { + lifecycle AppLifecycle +} + +func (w *appLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *appLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *appLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.App)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *appLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.App)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *appLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.App)) + if o == nil { + return nil, err + } + return o, err +} + +func NewAppLifecycleAdapter(name string, clusterScoped bool, client AppInterface, l AppLifecycle) AppHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(AppGroupVersionResource) + } + adapter := &appLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.App) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_controller.go new file mode 100644 index 0000000..8e8d0f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + AppRevisionGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "AppRevision", + } + AppRevisionResource = metav1.APIResource{ + Name: "apprevisions", + SingularName: "apprevision", + Namespaced: true, + + Kind: AppRevisionGroupVersionKind.Kind, + } + + AppRevisionGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "apprevisions", + } +) + +func init() { + resource.Put(AppRevisionGroupVersionResource) +} + +// Deprecated: use v3.AppRevision instead +type AppRevision = v3.AppRevision + +func NewAppRevision(namespace, name string, obj v3.AppRevision) *v3.AppRevision { + obj.APIVersion, obj.Kind = AppRevisionGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type AppRevisionHandlerFunc func(key string, obj *v3.AppRevision) (runtime.Object, error) + +type AppRevisionChangeHandlerFunc func(obj *v3.AppRevision) (runtime.Object, error) + +type AppRevisionLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.AppRevision, err error) + Get(namespace, name string) (*v3.AppRevision, error) +} + +type AppRevisionController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() AppRevisionLister + AddHandler(ctx context.Context, name string, handler AppRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppRevisionHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler AppRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler AppRevisionHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type AppRevisionInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.AppRevision) (*v3.AppRevision, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.AppRevision, error) + Get(name string, opts metav1.GetOptions) (*v3.AppRevision, error) + Update(*v3.AppRevision) (*v3.AppRevision, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.AppRevisionList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppRevisionList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() AppRevisionController + AddHandler(ctx context.Context, name string, sync AppRevisionHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppRevisionHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle AppRevisionLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AppRevisionLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AppRevisionHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AppRevisionHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AppRevisionLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AppRevisionLifecycle) +} + +type appRevisionLister struct { + ns string + controller *appRevisionController +} + +func (l *appRevisionLister) List(namespace string, selector labels.Selector) (ret []*v3.AppRevision, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.AppRevision)) + }) + return +} + +func (l *appRevisionLister) Get(namespace, name string) (*v3.AppRevision, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: AppRevisionGroupVersionKind.Group, + Resource: AppRevisionGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.AppRevision), nil +} + +type appRevisionController struct { + ns string + controller.GenericController +} + +func (c *appRevisionController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *appRevisionController) Lister() AppRevisionLister { + return &appRevisionLister{ + ns: c.ns, + controller: c, + } +} + +func (c *appRevisionController) AddHandler(ctx context.Context, name string, handler AppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AppRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appRevisionController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler AppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AppRevision); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appRevisionController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler AppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AppRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *appRevisionController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler AppRevisionHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.AppRevision); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type appRevisionFactory struct { +} + +func (c appRevisionFactory) Object() runtime.Object { + return &v3.AppRevision{} +} + +func (c appRevisionFactory) List() runtime.Object { + return &v3.AppRevisionList{} +} + +func (s *appRevisionClient) Controller() AppRevisionController { + genericController := controller.NewGenericController(s.ns, AppRevisionGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(AppRevisionGroupVersionResource, AppRevisionGroupVersionKind.Kind, true)) + + return &appRevisionController{ + ns: s.ns, + GenericController: genericController, + } +} + +type appRevisionClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller AppRevisionController +} + +func (s *appRevisionClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *appRevisionClient) Create(o *v3.AppRevision) (*v3.AppRevision, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) Get(name string, opts metav1.GetOptions) (*v3.AppRevision, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.AppRevision, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) Update(o *v3.AppRevision) (*v3.AppRevision, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) UpdateStatus(o *v3.AppRevision) (*v3.AppRevision, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *appRevisionClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *appRevisionClient) List(opts metav1.ListOptions) (*v3.AppRevisionList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.AppRevisionList), err +} + +func (s *appRevisionClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.AppRevisionList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.AppRevisionList), err +} + +func (s *appRevisionClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *appRevisionClient) Patch(o *v3.AppRevision, patchType types.PatchType, data []byte, subresources ...string) (*v3.AppRevision, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.AppRevision), err +} + +func (s *appRevisionClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *appRevisionClient) AddHandler(ctx context.Context, name string, sync AppRevisionHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *appRevisionClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync AppRevisionHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *appRevisionClient) AddLifecycle(ctx context.Context, name string, lifecycle AppRevisionLifecycle) { + sync := NewAppRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *appRevisionClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle AppRevisionLifecycle) { + sync := NewAppRevisionLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *appRevisionClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync AppRevisionHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *appRevisionClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync AppRevisionHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *appRevisionClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle AppRevisionLifecycle) { + sync := NewAppRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *appRevisionClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle AppRevisionLifecycle) { + sync := NewAppRevisionLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_lifecycle_adapter.go new file mode 100644 index 0000000..a136ac7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_app_revision_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type AppRevisionLifecycle interface { + Create(obj *v3.AppRevision) (runtime.Object, error) + Remove(obj *v3.AppRevision) (runtime.Object, error) + Updated(obj *v3.AppRevision) (runtime.Object, error) +} + +type appRevisionLifecycleAdapter struct { + lifecycle AppRevisionLifecycle +} + +func (w *appRevisionLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *appRevisionLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *appRevisionLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.AppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *appRevisionLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.AppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *appRevisionLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.AppRevision)) + if o == nil { + return nil, err + } + return o, err +} + +func NewAppRevisionLifecycleAdapter(name string, clusterScoped bool, client AppRevisionInterface, l AppRevisionLifecycle) AppRevisionHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(AppRevisionGroupVersionResource) + } + adapter := &appRevisionLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.AppRevision) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_controller.go new file mode 100644 index 0000000..30334c0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + BasicAuthGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "BasicAuth", + } + BasicAuthResource = metav1.APIResource{ + Name: "basicauths", + SingularName: "basicauth", + Namespaced: true, + + Kind: BasicAuthGroupVersionKind.Kind, + } + + BasicAuthGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "basicauths", + } +) + +func init() { + resource.Put(BasicAuthGroupVersionResource) +} + +// Deprecated: use v3.BasicAuth instead +type BasicAuth = v3.BasicAuth + +func NewBasicAuth(namespace, name string, obj v3.BasicAuth) *v3.BasicAuth { + obj.APIVersion, obj.Kind = BasicAuthGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type BasicAuthHandlerFunc func(key string, obj *v3.BasicAuth) (runtime.Object, error) + +type BasicAuthChangeHandlerFunc func(obj *v3.BasicAuth) (runtime.Object, error) + +type BasicAuthLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.BasicAuth, err error) + Get(namespace, name string) (*v3.BasicAuth, error) +} + +type BasicAuthController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() BasicAuthLister + AddHandler(ctx context.Context, name string, handler BasicAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync BasicAuthHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler BasicAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler BasicAuthHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type BasicAuthInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.BasicAuth) (*v3.BasicAuth, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.BasicAuth, error) + Get(name string, opts metav1.GetOptions) (*v3.BasicAuth, error) + Update(*v3.BasicAuth) (*v3.BasicAuth, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.BasicAuthList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.BasicAuthList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() BasicAuthController + AddHandler(ctx context.Context, name string, sync BasicAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync BasicAuthHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle BasicAuthLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle BasicAuthLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync BasicAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync BasicAuthHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle BasicAuthLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle BasicAuthLifecycle) +} + +type basicAuthLister struct { + ns string + controller *basicAuthController +} + +func (l *basicAuthLister) List(namespace string, selector labels.Selector) (ret []*v3.BasicAuth, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.BasicAuth)) + }) + return +} + +func (l *basicAuthLister) Get(namespace, name string) (*v3.BasicAuth, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: BasicAuthGroupVersionKind.Group, + Resource: BasicAuthGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.BasicAuth), nil +} + +type basicAuthController struct { + ns string + controller.GenericController +} + +func (c *basicAuthController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *basicAuthController) Lister() BasicAuthLister { + return &basicAuthLister{ + ns: c.ns, + controller: c, + } +} + +func (c *basicAuthController) AddHandler(ctx context.Context, name string, handler BasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.BasicAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *basicAuthController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler BasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.BasicAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *basicAuthController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler BasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.BasicAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *basicAuthController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler BasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.BasicAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type basicAuthFactory struct { +} + +func (c basicAuthFactory) Object() runtime.Object { + return &v3.BasicAuth{} +} + +func (c basicAuthFactory) List() runtime.Object { + return &v3.BasicAuthList{} +} + +func (s *basicAuthClient) Controller() BasicAuthController { + genericController := controller.NewGenericController(s.ns, BasicAuthGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(BasicAuthGroupVersionResource, BasicAuthGroupVersionKind.Kind, true)) + + return &basicAuthController{ + ns: s.ns, + GenericController: genericController, + } +} + +type basicAuthClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller BasicAuthController +} + +func (s *basicAuthClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *basicAuthClient) Create(o *v3.BasicAuth) (*v3.BasicAuth, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) Get(name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.BasicAuth, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) Update(o *v3.BasicAuth) (*v3.BasicAuth, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) UpdateStatus(o *v3.BasicAuth) (*v3.BasicAuth, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *basicAuthClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *basicAuthClient) List(opts metav1.ListOptions) (*v3.BasicAuthList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.BasicAuthList), err +} + +func (s *basicAuthClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.BasicAuthList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.BasicAuthList), err +} + +func (s *basicAuthClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *basicAuthClient) Patch(o *v3.BasicAuth, patchType types.PatchType, data []byte, subresources ...string) (*v3.BasicAuth, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.BasicAuth), err +} + +func (s *basicAuthClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *basicAuthClient) AddHandler(ctx context.Context, name string, sync BasicAuthHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *basicAuthClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync BasicAuthHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *basicAuthClient) AddLifecycle(ctx context.Context, name string, lifecycle BasicAuthLifecycle) { + sync := NewBasicAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *basicAuthClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle BasicAuthLifecycle) { + sync := NewBasicAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *basicAuthClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync BasicAuthHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *basicAuthClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync BasicAuthHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *basicAuthClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle BasicAuthLifecycle) { + sync := NewBasicAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *basicAuthClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle BasicAuthLifecycle) { + sync := NewBasicAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_lifecycle_adapter.go new file mode 100644 index 0000000..adc01e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_basic_auth_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type BasicAuthLifecycle interface { + Create(obj *v3.BasicAuth) (runtime.Object, error) + Remove(obj *v3.BasicAuth) (runtime.Object, error) + Updated(obj *v3.BasicAuth) (runtime.Object, error) +} + +type basicAuthLifecycleAdapter struct { + lifecycle BasicAuthLifecycle +} + +func (w *basicAuthLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *basicAuthLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *basicAuthLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.BasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *basicAuthLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.BasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *basicAuthLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.BasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func NewBasicAuthLifecycleAdapter(name string, clusterScoped bool, client BasicAuthInterface, l BasicAuthLifecycle) BasicAuthHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(BasicAuthGroupVersionResource) + } + adapter := &basicAuthLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.BasicAuth) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_controller.go new file mode 100644 index 0000000..3cc3ff3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + CertificateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Certificate", + } + CertificateResource = metav1.APIResource{ + Name: "certificates", + SingularName: "certificate", + Namespaced: true, + + Kind: CertificateGroupVersionKind.Kind, + } + + CertificateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "certificates", + } +) + +func init() { + resource.Put(CertificateGroupVersionResource) +} + +// Deprecated: use v3.Certificate instead +type Certificate = v3.Certificate + +func NewCertificate(namespace, name string, obj v3.Certificate) *v3.Certificate { + obj.APIVersion, obj.Kind = CertificateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type CertificateHandlerFunc func(key string, obj *v3.Certificate) (runtime.Object, error) + +type CertificateChangeHandlerFunc func(obj *v3.Certificate) (runtime.Object, error) + +type CertificateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Certificate, err error) + Get(namespace, name string) (*v3.Certificate, error) +} + +type CertificateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() CertificateLister + AddHandler(ctx context.Context, name string, handler CertificateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CertificateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler CertificateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler CertificateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type CertificateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Certificate) (*v3.Certificate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Certificate, error) + Get(name string, opts metav1.GetOptions) (*v3.Certificate, error) + Update(*v3.Certificate) (*v3.Certificate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.CertificateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CertificateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() CertificateController + AddHandler(ctx context.Context, name string, sync CertificateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CertificateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle CertificateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CertificateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CertificateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CertificateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CertificateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CertificateLifecycle) +} + +type certificateLister struct { + ns string + controller *certificateController +} + +func (l *certificateLister) List(namespace string, selector labels.Selector) (ret []*v3.Certificate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Certificate)) + }) + return +} + +func (l *certificateLister) Get(namespace, name string) (*v3.Certificate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: CertificateGroupVersionKind.Group, + Resource: CertificateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Certificate), nil +} + +type certificateController struct { + ns string + controller.GenericController +} + +func (c *certificateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *certificateController) Lister() CertificateLister { + return &certificateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *certificateController) AddHandler(ctx context.Context, name string, handler CertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Certificate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *certificateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler CertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Certificate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *certificateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler CertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Certificate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *certificateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler CertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Certificate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type certificateFactory struct { +} + +func (c certificateFactory) Object() runtime.Object { + return &v3.Certificate{} +} + +func (c certificateFactory) List() runtime.Object { + return &v3.CertificateList{} +} + +func (s *certificateClient) Controller() CertificateController { + genericController := controller.NewGenericController(s.ns, CertificateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(CertificateGroupVersionResource, CertificateGroupVersionKind.Kind, true)) + + return &certificateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type certificateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller CertificateController +} + +func (s *certificateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *certificateClient) Create(o *v3.Certificate) (*v3.Certificate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) Get(name string, opts metav1.GetOptions) (*v3.Certificate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Certificate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) Update(o *v3.Certificate) (*v3.Certificate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) UpdateStatus(o *v3.Certificate) (*v3.Certificate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *certificateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *certificateClient) List(opts metav1.ListOptions) (*v3.CertificateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.CertificateList), err +} + +func (s *certificateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.CertificateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.CertificateList), err +} + +func (s *certificateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *certificateClient) Patch(o *v3.Certificate, patchType types.PatchType, data []byte, subresources ...string) (*v3.Certificate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Certificate), err +} + +func (s *certificateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *certificateClient) AddHandler(ctx context.Context, name string, sync CertificateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *certificateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync CertificateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *certificateClient) AddLifecycle(ctx context.Context, name string, lifecycle CertificateLifecycle) { + sync := NewCertificateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *certificateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle CertificateLifecycle) { + sync := NewCertificateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *certificateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync CertificateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *certificateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync CertificateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *certificateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle CertificateLifecycle) { + sync := NewCertificateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *certificateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle CertificateLifecycle) { + sync := NewCertificateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_lifecycle_adapter.go new file mode 100644 index 0000000..132d920 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_certificate_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type CertificateLifecycle interface { + Create(obj *v3.Certificate) (runtime.Object, error) + Remove(obj *v3.Certificate) (runtime.Object, error) + Updated(obj *v3.Certificate) (runtime.Object, error) +} + +type certificateLifecycleAdapter struct { + lifecycle CertificateLifecycle +} + +func (w *certificateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *certificateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *certificateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Certificate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *certificateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Certificate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *certificateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Certificate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewCertificateLifecycleAdapter(name string, clusterScoped bool, client CertificateInterface, l CertificateLifecycle) CertificateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(CertificateGroupVersionResource) + } + adapter := &certificateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Certificate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_controller.go new file mode 100644 index 0000000..509b932 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + DockerCredentialGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "DockerCredential", + } + DockerCredentialResource = metav1.APIResource{ + Name: "dockercredentials", + SingularName: "dockercredential", + Namespaced: true, + + Kind: DockerCredentialGroupVersionKind.Kind, + } + + DockerCredentialGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "dockercredentials", + } +) + +func init() { + resource.Put(DockerCredentialGroupVersionResource) +} + +// Deprecated: use v3.DockerCredential instead +type DockerCredential = v3.DockerCredential + +func NewDockerCredential(namespace, name string, obj v3.DockerCredential) *v3.DockerCredential { + obj.APIVersion, obj.Kind = DockerCredentialGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type DockerCredentialHandlerFunc func(key string, obj *v3.DockerCredential) (runtime.Object, error) + +type DockerCredentialChangeHandlerFunc func(obj *v3.DockerCredential) (runtime.Object, error) + +type DockerCredentialLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.DockerCredential, err error) + Get(namespace, name string) (*v3.DockerCredential, error) +} + +type DockerCredentialController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() DockerCredentialLister + AddHandler(ctx context.Context, name string, handler DockerCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DockerCredentialHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler DockerCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler DockerCredentialHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type DockerCredentialInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.DockerCredential) (*v3.DockerCredential, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.DockerCredential, error) + Get(name string, opts metav1.GetOptions) (*v3.DockerCredential, error) + Update(*v3.DockerCredential) (*v3.DockerCredential, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.DockerCredentialList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DockerCredentialList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() DockerCredentialController + AddHandler(ctx context.Context, name string, sync DockerCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DockerCredentialHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle DockerCredentialLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DockerCredentialLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DockerCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DockerCredentialHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DockerCredentialLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DockerCredentialLifecycle) +} + +type dockerCredentialLister struct { + ns string + controller *dockerCredentialController +} + +func (l *dockerCredentialLister) List(namespace string, selector labels.Selector) (ret []*v3.DockerCredential, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.DockerCredential)) + }) + return +} + +func (l *dockerCredentialLister) Get(namespace, name string) (*v3.DockerCredential, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: DockerCredentialGroupVersionKind.Group, + Resource: DockerCredentialGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.DockerCredential), nil +} + +type dockerCredentialController struct { + ns string + controller.GenericController +} + +func (c *dockerCredentialController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *dockerCredentialController) Lister() DockerCredentialLister { + return &dockerCredentialLister{ + ns: c.ns, + controller: c, + } +} + +func (c *dockerCredentialController) AddHandler(ctx context.Context, name string, handler DockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DockerCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dockerCredentialController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler DockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DockerCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dockerCredentialController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler DockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DockerCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *dockerCredentialController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler DockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.DockerCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type dockerCredentialFactory struct { +} + +func (c dockerCredentialFactory) Object() runtime.Object { + return &v3.DockerCredential{} +} + +func (c dockerCredentialFactory) List() runtime.Object { + return &v3.DockerCredentialList{} +} + +func (s *dockerCredentialClient) Controller() DockerCredentialController { + genericController := controller.NewGenericController(s.ns, DockerCredentialGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(DockerCredentialGroupVersionResource, DockerCredentialGroupVersionKind.Kind, true)) + + return &dockerCredentialController{ + ns: s.ns, + GenericController: genericController, + } +} + +type dockerCredentialClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller DockerCredentialController +} + +func (s *dockerCredentialClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *dockerCredentialClient) Create(o *v3.DockerCredential) (*v3.DockerCredential, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) Get(name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.DockerCredential, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) Update(o *v3.DockerCredential) (*v3.DockerCredential, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) UpdateStatus(o *v3.DockerCredential) (*v3.DockerCredential, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *dockerCredentialClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *dockerCredentialClient) List(opts metav1.ListOptions) (*v3.DockerCredentialList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.DockerCredentialList), err +} + +func (s *dockerCredentialClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.DockerCredentialList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.DockerCredentialList), err +} + +func (s *dockerCredentialClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *dockerCredentialClient) Patch(o *v3.DockerCredential, patchType types.PatchType, data []byte, subresources ...string) (*v3.DockerCredential, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.DockerCredential), err +} + +func (s *dockerCredentialClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *dockerCredentialClient) AddHandler(ctx context.Context, name string, sync DockerCredentialHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *dockerCredentialClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync DockerCredentialHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *dockerCredentialClient) AddLifecycle(ctx context.Context, name string, lifecycle DockerCredentialLifecycle) { + sync := NewDockerCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *dockerCredentialClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle DockerCredentialLifecycle) { + sync := NewDockerCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *dockerCredentialClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync DockerCredentialHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *dockerCredentialClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync DockerCredentialHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *dockerCredentialClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle DockerCredentialLifecycle) { + sync := NewDockerCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *dockerCredentialClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle DockerCredentialLifecycle) { + sync := NewDockerCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_lifecycle_adapter.go new file mode 100644 index 0000000..a3ba94c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_docker_credential_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type DockerCredentialLifecycle interface { + Create(obj *v3.DockerCredential) (runtime.Object, error) + Remove(obj *v3.DockerCredential) (runtime.Object, error) + Updated(obj *v3.DockerCredential) (runtime.Object, error) +} + +type dockerCredentialLifecycleAdapter struct { + lifecycle DockerCredentialLifecycle +} + +func (w *dockerCredentialLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *dockerCredentialLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *dockerCredentialLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.DockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *dockerCredentialLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.DockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *dockerCredentialLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.DockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func NewDockerCredentialLifecycleAdapter(name string, clusterScoped bool, client DockerCredentialInterface, l DockerCredentialLifecycle) DockerCredentialHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(DockerCredentialGroupVersionResource) + } + adapter := &dockerCredentialLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.DockerCredential) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_k8s_client.go new file mode 100644 index 0000000..ff46dd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_k8s_client.go @@ -0,0 +1,243 @@ +package v3 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + ServiceAccountTokensGetter + DockerCredentialsGetter + CertificatesGetter + BasicAuthsGetter + SSHAuthsGetter + NamespacedServiceAccountTokensGetter + NamespacedDockerCredentialsGetter + NamespacedCertificatesGetter + NamespacedBasicAuthsGetter + NamespacedSSHAuthsGetter + WorkloadsGetter + AppsGetter + AppRevisionsGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v3.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type ServiceAccountTokensGetter interface { + ServiceAccountTokens(namespace string) ServiceAccountTokenInterface +} + +func (c *Client) ServiceAccountTokens(namespace string) ServiceAccountTokenInterface { + sharedClient := c.clientFactory.ForResourceKind(ServiceAccountTokenGroupVersionResource, ServiceAccountTokenGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ServiceAccountTokenResource, ServiceAccountTokenGroupVersionKind, serviceAccountTokenFactory{}) + return &serviceAccountTokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type DockerCredentialsGetter interface { + DockerCredentials(namespace string) DockerCredentialInterface +} + +func (c *Client) DockerCredentials(namespace string) DockerCredentialInterface { + sharedClient := c.clientFactory.ForResourceKind(DockerCredentialGroupVersionResource, DockerCredentialGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &DockerCredentialResource, DockerCredentialGroupVersionKind, dockerCredentialFactory{}) + return &dockerCredentialClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type CertificatesGetter interface { + Certificates(namespace string) CertificateInterface +} + +func (c *Client) Certificates(namespace string) CertificateInterface { + sharedClient := c.clientFactory.ForResourceKind(CertificateGroupVersionResource, CertificateGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &CertificateResource, CertificateGroupVersionKind, certificateFactory{}) + return &certificateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type BasicAuthsGetter interface { + BasicAuths(namespace string) BasicAuthInterface +} + +func (c *Client) BasicAuths(namespace string) BasicAuthInterface { + sharedClient := c.clientFactory.ForResourceKind(BasicAuthGroupVersionResource, BasicAuthGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &BasicAuthResource, BasicAuthGroupVersionKind, basicAuthFactory{}) + return &basicAuthClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type SSHAuthsGetter interface { + SSHAuths(namespace string) SSHAuthInterface +} + +func (c *Client) SSHAuths(namespace string) SSHAuthInterface { + sharedClient := c.clientFactory.ForResourceKind(SSHAuthGroupVersionResource, SSHAuthGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &SSHAuthResource, SSHAuthGroupVersionKind, sshAuthFactory{}) + return &sshAuthClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacedServiceAccountTokensGetter interface { + NamespacedServiceAccountTokens(namespace string) NamespacedServiceAccountTokenInterface +} + +func (c *Client) NamespacedServiceAccountTokens(namespace string) NamespacedServiceAccountTokenInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespacedServiceAccountTokenGroupVersionResource, NamespacedServiceAccountTokenGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespacedServiceAccountTokenResource, NamespacedServiceAccountTokenGroupVersionKind, namespacedServiceAccountTokenFactory{}) + return &namespacedServiceAccountTokenClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacedDockerCredentialsGetter interface { + NamespacedDockerCredentials(namespace string) NamespacedDockerCredentialInterface +} + +func (c *Client) NamespacedDockerCredentials(namespace string) NamespacedDockerCredentialInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespacedDockerCredentialGroupVersionResource, NamespacedDockerCredentialGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespacedDockerCredentialResource, NamespacedDockerCredentialGroupVersionKind, namespacedDockerCredentialFactory{}) + return &namespacedDockerCredentialClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacedCertificatesGetter interface { + NamespacedCertificates(namespace string) NamespacedCertificateInterface +} + +func (c *Client) NamespacedCertificates(namespace string) NamespacedCertificateInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespacedCertificateGroupVersionResource, NamespacedCertificateGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespacedCertificateResource, NamespacedCertificateGroupVersionKind, namespacedCertificateFactory{}) + return &namespacedCertificateClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacedBasicAuthsGetter interface { + NamespacedBasicAuths(namespace string) NamespacedBasicAuthInterface +} + +func (c *Client) NamespacedBasicAuths(namespace string) NamespacedBasicAuthInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespacedBasicAuthGroupVersionResource, NamespacedBasicAuthGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespacedBasicAuthResource, NamespacedBasicAuthGroupVersionKind, namespacedBasicAuthFactory{}) + return &namespacedBasicAuthClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type NamespacedSSHAuthsGetter interface { + NamespacedSSHAuths(namespace string) NamespacedSSHAuthInterface +} + +func (c *Client) NamespacedSSHAuths(namespace string) NamespacedSSHAuthInterface { + sharedClient := c.clientFactory.ForResourceKind(NamespacedSSHAuthGroupVersionResource, NamespacedSSHAuthGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &NamespacedSSHAuthResource, NamespacedSSHAuthGroupVersionKind, namespacedSshAuthFactory{}) + return &namespacedSshAuthClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type WorkloadsGetter interface { + Workloads(namespace string) WorkloadInterface +} + +func (c *Client) Workloads(namespace string) WorkloadInterface { + sharedClient := c.clientFactory.ForResourceKind(WorkloadGroupVersionResource, WorkloadGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &WorkloadResource, WorkloadGroupVersionKind, workloadFactory{}) + return &workloadClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type AppsGetter interface { + Apps(namespace string) AppInterface +} + +func (c *Client) Apps(namespace string) AppInterface { + sharedClient := c.clientFactory.ForResourceKind(AppGroupVersionResource, AppGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &AppResource, AppGroupVersionKind, appFactory{}) + return &appClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type AppRevisionsGetter interface { + AppRevisions(namespace string) AppRevisionInterface +} + +func (c *Client) AppRevisions(namespace string) AppRevisionInterface { + sharedClient := c.clientFactory.ForResourceKind(AppRevisionGroupVersionResource, AppRevisionGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &AppRevisionResource, AppRevisionGroupVersionKind, appRevisionFactory{}) + return &appRevisionClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_controller.go new file mode 100644 index 0000000..52b8718 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespacedBasicAuthGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NamespacedBasicAuth", + } + NamespacedBasicAuthResource = metav1.APIResource{ + Name: "namespacedbasicauths", + SingularName: "namespacedbasicauth", + Namespaced: true, + + Kind: NamespacedBasicAuthGroupVersionKind.Kind, + } + + NamespacedBasicAuthGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespacedbasicauths", + } +) + +func init() { + resource.Put(NamespacedBasicAuthGroupVersionResource) +} + +// Deprecated: use v3.NamespacedBasicAuth instead +type NamespacedBasicAuth = v3.NamespacedBasicAuth + +func NewNamespacedBasicAuth(namespace, name string, obj v3.NamespacedBasicAuth) *v3.NamespacedBasicAuth { + obj.APIVersion, obj.Kind = NamespacedBasicAuthGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespacedBasicAuthHandlerFunc func(key string, obj *v3.NamespacedBasicAuth) (runtime.Object, error) + +type NamespacedBasicAuthChangeHandlerFunc func(obj *v3.NamespacedBasicAuth) (runtime.Object, error) + +type NamespacedBasicAuthLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NamespacedBasicAuth, err error) + Get(namespace, name string) (*v3.NamespacedBasicAuth, error) +} + +type NamespacedBasicAuthController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespacedBasicAuthLister + AddHandler(ctx context.Context, name string, handler NamespacedBasicAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedBasicAuthHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespacedBasicAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespacedBasicAuthHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespacedBasicAuthInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) + Get(name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) + Update(*v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespacedBasicAuthController + AddHandler(ctx context.Context, name string, sync NamespacedBasicAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedBasicAuthHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespacedBasicAuthLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedBasicAuthLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedBasicAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedBasicAuthHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedBasicAuthLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedBasicAuthLifecycle) +} + +type namespacedBasicAuthLister struct { + ns string + controller *namespacedBasicAuthController +} + +func (l *namespacedBasicAuthLister) List(namespace string, selector labels.Selector) (ret []*v3.NamespacedBasicAuth, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NamespacedBasicAuth)) + }) + return +} + +func (l *namespacedBasicAuthLister) Get(namespace, name string) (*v3.NamespacedBasicAuth, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespacedBasicAuthGroupVersionKind.Group, + Resource: NamespacedBasicAuthGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NamespacedBasicAuth), nil +} + +type namespacedBasicAuthController struct { + ns string + controller.GenericController +} + +func (c *namespacedBasicAuthController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespacedBasicAuthController) Lister() NamespacedBasicAuthLister { + return &namespacedBasicAuthLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespacedBasicAuthController) AddHandler(ctx context.Context, name string, handler NamespacedBasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedBasicAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedBasicAuthController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespacedBasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedBasicAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedBasicAuthController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespacedBasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedBasicAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedBasicAuthController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespacedBasicAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedBasicAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespacedBasicAuthFactory struct { +} + +func (c namespacedBasicAuthFactory) Object() runtime.Object { + return &v3.NamespacedBasicAuth{} +} + +func (c namespacedBasicAuthFactory) List() runtime.Object { + return &v3.NamespacedBasicAuthList{} +} + +func (s *namespacedBasicAuthClient) Controller() NamespacedBasicAuthController { + genericController := controller.NewGenericController(s.ns, NamespacedBasicAuthGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespacedBasicAuthGroupVersionResource, NamespacedBasicAuthGroupVersionKind.Kind, true)) + + return &namespacedBasicAuthController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespacedBasicAuthClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespacedBasicAuthController +} + +func (s *namespacedBasicAuthClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespacedBasicAuthClient) Create(o *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) Get(name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) Update(o *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) UpdateStatus(o *v3.NamespacedBasicAuth) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespacedBasicAuthClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespacedBasicAuthClient) List(opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NamespacedBasicAuthList), err +} + +func (s *namespacedBasicAuthClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedBasicAuthList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NamespacedBasicAuthList), err +} + +func (s *namespacedBasicAuthClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespacedBasicAuthClient) Patch(o *v3.NamespacedBasicAuth, patchType types.PatchType, data []byte, subresources ...string) (*v3.NamespacedBasicAuth, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NamespacedBasicAuth), err +} + +func (s *namespacedBasicAuthClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespacedBasicAuthClient) AddHandler(ctx context.Context, name string, sync NamespacedBasicAuthHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedBasicAuthClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedBasicAuthHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedBasicAuthClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespacedBasicAuthLifecycle) { + sync := NewNamespacedBasicAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedBasicAuthClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedBasicAuthLifecycle) { + sync := NewNamespacedBasicAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedBasicAuthClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedBasicAuthHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedBasicAuthClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedBasicAuthHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespacedBasicAuthClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedBasicAuthLifecycle) { + sync := NewNamespacedBasicAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedBasicAuthClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedBasicAuthLifecycle) { + sync := NewNamespacedBasicAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_lifecycle_adapter.go new file mode 100644 index 0000000..0c68f31 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_basic_auth_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespacedBasicAuthLifecycle interface { + Create(obj *v3.NamespacedBasicAuth) (runtime.Object, error) + Remove(obj *v3.NamespacedBasicAuth) (runtime.Object, error) + Updated(obj *v3.NamespacedBasicAuth) (runtime.Object, error) +} + +type namespacedBasicAuthLifecycleAdapter struct { + lifecycle NamespacedBasicAuthLifecycle +} + +func (w *namespacedBasicAuthLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespacedBasicAuthLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespacedBasicAuthLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NamespacedBasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedBasicAuthLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NamespacedBasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedBasicAuthLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NamespacedBasicAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespacedBasicAuthLifecycleAdapter(name string, clusterScoped bool, client NamespacedBasicAuthInterface, l NamespacedBasicAuthLifecycle) NamespacedBasicAuthHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespacedBasicAuthGroupVersionResource) + } + adapter := &namespacedBasicAuthLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NamespacedBasicAuth) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_controller.go new file mode 100644 index 0000000..bb85323 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespacedCertificateGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NamespacedCertificate", + } + NamespacedCertificateResource = metav1.APIResource{ + Name: "namespacedcertificates", + SingularName: "namespacedcertificate", + Namespaced: true, + + Kind: NamespacedCertificateGroupVersionKind.Kind, + } + + NamespacedCertificateGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespacedcertificates", + } +) + +func init() { + resource.Put(NamespacedCertificateGroupVersionResource) +} + +// Deprecated: use v3.NamespacedCertificate instead +type NamespacedCertificate = v3.NamespacedCertificate + +func NewNamespacedCertificate(namespace, name string, obj v3.NamespacedCertificate) *v3.NamespacedCertificate { + obj.APIVersion, obj.Kind = NamespacedCertificateGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespacedCertificateHandlerFunc func(key string, obj *v3.NamespacedCertificate) (runtime.Object, error) + +type NamespacedCertificateChangeHandlerFunc func(obj *v3.NamespacedCertificate) (runtime.Object, error) + +type NamespacedCertificateLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NamespacedCertificate, err error) + Get(namespace, name string) (*v3.NamespacedCertificate, error) +} + +type NamespacedCertificateController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespacedCertificateLister + AddHandler(ctx context.Context, name string, handler NamespacedCertificateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedCertificateHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespacedCertificateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespacedCertificateHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespacedCertificateInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) + Get(name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) + Update(*v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespacedCertificateController + AddHandler(ctx context.Context, name string, sync NamespacedCertificateHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedCertificateHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespacedCertificateLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedCertificateLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedCertificateHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedCertificateHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedCertificateLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedCertificateLifecycle) +} + +type namespacedCertificateLister struct { + ns string + controller *namespacedCertificateController +} + +func (l *namespacedCertificateLister) List(namespace string, selector labels.Selector) (ret []*v3.NamespacedCertificate, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NamespacedCertificate)) + }) + return +} + +func (l *namespacedCertificateLister) Get(namespace, name string) (*v3.NamespacedCertificate, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespacedCertificateGroupVersionKind.Group, + Resource: NamespacedCertificateGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NamespacedCertificate), nil +} + +type namespacedCertificateController struct { + ns string + controller.GenericController +} + +func (c *namespacedCertificateController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespacedCertificateController) Lister() NamespacedCertificateLister { + return &namespacedCertificateLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespacedCertificateController) AddHandler(ctx context.Context, name string, handler NamespacedCertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedCertificate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedCertificateController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespacedCertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedCertificate); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedCertificateController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespacedCertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedCertificate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedCertificateController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespacedCertificateHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedCertificate); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespacedCertificateFactory struct { +} + +func (c namespacedCertificateFactory) Object() runtime.Object { + return &v3.NamespacedCertificate{} +} + +func (c namespacedCertificateFactory) List() runtime.Object { + return &v3.NamespacedCertificateList{} +} + +func (s *namespacedCertificateClient) Controller() NamespacedCertificateController { + genericController := controller.NewGenericController(s.ns, NamespacedCertificateGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespacedCertificateGroupVersionResource, NamespacedCertificateGroupVersionKind.Kind, true)) + + return &namespacedCertificateController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespacedCertificateClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespacedCertificateController +} + +func (s *namespacedCertificateClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespacedCertificateClient) Create(o *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) Get(name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) Update(o *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) UpdateStatus(o *v3.NamespacedCertificate) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespacedCertificateClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespacedCertificateClient) List(opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NamespacedCertificateList), err +} + +func (s *namespacedCertificateClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedCertificateList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NamespacedCertificateList), err +} + +func (s *namespacedCertificateClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespacedCertificateClient) Patch(o *v3.NamespacedCertificate, patchType types.PatchType, data []byte, subresources ...string) (*v3.NamespacedCertificate, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NamespacedCertificate), err +} + +func (s *namespacedCertificateClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespacedCertificateClient) AddHandler(ctx context.Context, name string, sync NamespacedCertificateHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedCertificateClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedCertificateHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedCertificateClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespacedCertificateLifecycle) { + sync := NewNamespacedCertificateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedCertificateClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedCertificateLifecycle) { + sync := NewNamespacedCertificateLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedCertificateClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedCertificateHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedCertificateClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedCertificateHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespacedCertificateClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedCertificateLifecycle) { + sync := NewNamespacedCertificateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedCertificateClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedCertificateLifecycle) { + sync := NewNamespacedCertificateLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_lifecycle_adapter.go new file mode 100644 index 0000000..4546543 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_certificate_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespacedCertificateLifecycle interface { + Create(obj *v3.NamespacedCertificate) (runtime.Object, error) + Remove(obj *v3.NamespacedCertificate) (runtime.Object, error) + Updated(obj *v3.NamespacedCertificate) (runtime.Object, error) +} + +type namespacedCertificateLifecycleAdapter struct { + lifecycle NamespacedCertificateLifecycle +} + +func (w *namespacedCertificateLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespacedCertificateLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespacedCertificateLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NamespacedCertificate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedCertificateLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NamespacedCertificate)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedCertificateLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NamespacedCertificate)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespacedCertificateLifecycleAdapter(name string, clusterScoped bool, client NamespacedCertificateInterface, l NamespacedCertificateLifecycle) NamespacedCertificateHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespacedCertificateGroupVersionResource) + } + adapter := &namespacedCertificateLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NamespacedCertificate) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_controller.go new file mode 100644 index 0000000..dc6f242 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespacedDockerCredentialGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NamespacedDockerCredential", + } + NamespacedDockerCredentialResource = metav1.APIResource{ + Name: "namespaceddockercredentials", + SingularName: "namespaceddockercredential", + Namespaced: true, + + Kind: NamespacedDockerCredentialGroupVersionKind.Kind, + } + + NamespacedDockerCredentialGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespaceddockercredentials", + } +) + +func init() { + resource.Put(NamespacedDockerCredentialGroupVersionResource) +} + +// Deprecated: use v3.NamespacedDockerCredential instead +type NamespacedDockerCredential = v3.NamespacedDockerCredential + +func NewNamespacedDockerCredential(namespace, name string, obj v3.NamespacedDockerCredential) *v3.NamespacedDockerCredential { + obj.APIVersion, obj.Kind = NamespacedDockerCredentialGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespacedDockerCredentialHandlerFunc func(key string, obj *v3.NamespacedDockerCredential) (runtime.Object, error) + +type NamespacedDockerCredentialChangeHandlerFunc func(obj *v3.NamespacedDockerCredential) (runtime.Object, error) + +type NamespacedDockerCredentialLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NamespacedDockerCredential, err error) + Get(namespace, name string) (*v3.NamespacedDockerCredential, error) +} + +type NamespacedDockerCredentialController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespacedDockerCredentialLister + AddHandler(ctx context.Context, name string, handler NamespacedDockerCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedDockerCredentialHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespacedDockerCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespacedDockerCredentialHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespacedDockerCredentialInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) + Get(name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) + Update(*v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespacedDockerCredentialController + AddHandler(ctx context.Context, name string, sync NamespacedDockerCredentialHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedDockerCredentialHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespacedDockerCredentialLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedDockerCredentialLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedDockerCredentialHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedDockerCredentialHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedDockerCredentialLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedDockerCredentialLifecycle) +} + +type namespacedDockerCredentialLister struct { + ns string + controller *namespacedDockerCredentialController +} + +func (l *namespacedDockerCredentialLister) List(namespace string, selector labels.Selector) (ret []*v3.NamespacedDockerCredential, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NamespacedDockerCredential)) + }) + return +} + +func (l *namespacedDockerCredentialLister) Get(namespace, name string) (*v3.NamespacedDockerCredential, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespacedDockerCredentialGroupVersionKind.Group, + Resource: NamespacedDockerCredentialGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NamespacedDockerCredential), nil +} + +type namespacedDockerCredentialController struct { + ns string + controller.GenericController +} + +func (c *namespacedDockerCredentialController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespacedDockerCredentialController) Lister() NamespacedDockerCredentialLister { + return &namespacedDockerCredentialLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespacedDockerCredentialController) AddHandler(ctx context.Context, name string, handler NamespacedDockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedDockerCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedDockerCredentialController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespacedDockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedDockerCredential); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedDockerCredentialController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespacedDockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedDockerCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedDockerCredentialController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespacedDockerCredentialHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedDockerCredential); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespacedDockerCredentialFactory struct { +} + +func (c namespacedDockerCredentialFactory) Object() runtime.Object { + return &v3.NamespacedDockerCredential{} +} + +func (c namespacedDockerCredentialFactory) List() runtime.Object { + return &v3.NamespacedDockerCredentialList{} +} + +func (s *namespacedDockerCredentialClient) Controller() NamespacedDockerCredentialController { + genericController := controller.NewGenericController(s.ns, NamespacedDockerCredentialGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespacedDockerCredentialGroupVersionResource, NamespacedDockerCredentialGroupVersionKind.Kind, true)) + + return &namespacedDockerCredentialController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespacedDockerCredentialClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespacedDockerCredentialController +} + +func (s *namespacedDockerCredentialClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespacedDockerCredentialClient) Create(o *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) Get(name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) Update(o *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) UpdateStatus(o *v3.NamespacedDockerCredential) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespacedDockerCredentialClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespacedDockerCredentialClient) List(opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NamespacedDockerCredentialList), err +} + +func (s *namespacedDockerCredentialClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedDockerCredentialList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NamespacedDockerCredentialList), err +} + +func (s *namespacedDockerCredentialClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespacedDockerCredentialClient) Patch(o *v3.NamespacedDockerCredential, patchType types.PatchType, data []byte, subresources ...string) (*v3.NamespacedDockerCredential, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NamespacedDockerCredential), err +} + +func (s *namespacedDockerCredentialClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespacedDockerCredentialClient) AddHandler(ctx context.Context, name string, sync NamespacedDockerCredentialHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedDockerCredentialClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedDockerCredentialHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedDockerCredentialClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespacedDockerCredentialLifecycle) { + sync := NewNamespacedDockerCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedDockerCredentialClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedDockerCredentialLifecycle) { + sync := NewNamespacedDockerCredentialLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedDockerCredentialClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedDockerCredentialHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedDockerCredentialClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedDockerCredentialHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespacedDockerCredentialClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedDockerCredentialLifecycle) { + sync := NewNamespacedDockerCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedDockerCredentialClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedDockerCredentialLifecycle) { + sync := NewNamespacedDockerCredentialLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_lifecycle_adapter.go new file mode 100644 index 0000000..0268c7c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_docker_credential_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespacedDockerCredentialLifecycle interface { + Create(obj *v3.NamespacedDockerCredential) (runtime.Object, error) + Remove(obj *v3.NamespacedDockerCredential) (runtime.Object, error) + Updated(obj *v3.NamespacedDockerCredential) (runtime.Object, error) +} + +type namespacedDockerCredentialLifecycleAdapter struct { + lifecycle NamespacedDockerCredentialLifecycle +} + +func (w *namespacedDockerCredentialLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespacedDockerCredentialLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespacedDockerCredentialLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NamespacedDockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedDockerCredentialLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NamespacedDockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedDockerCredentialLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NamespacedDockerCredential)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespacedDockerCredentialLifecycleAdapter(name string, clusterScoped bool, client NamespacedDockerCredentialInterface, l NamespacedDockerCredentialLifecycle) NamespacedDockerCredentialHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespacedDockerCredentialGroupVersionResource) + } + adapter := &namespacedDockerCredentialLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NamespacedDockerCredential) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_controller.go new file mode 100644 index 0000000..625d5b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespacedServiceAccountTokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NamespacedServiceAccountToken", + } + NamespacedServiceAccountTokenResource = metav1.APIResource{ + Name: "namespacedserviceaccounttokens", + SingularName: "namespacedserviceaccounttoken", + Namespaced: true, + + Kind: NamespacedServiceAccountTokenGroupVersionKind.Kind, + } + + NamespacedServiceAccountTokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespacedserviceaccounttokens", + } +) + +func init() { + resource.Put(NamespacedServiceAccountTokenGroupVersionResource) +} + +// Deprecated: use v3.NamespacedServiceAccountToken instead +type NamespacedServiceAccountToken = v3.NamespacedServiceAccountToken + +func NewNamespacedServiceAccountToken(namespace, name string, obj v3.NamespacedServiceAccountToken) *v3.NamespacedServiceAccountToken { + obj.APIVersion, obj.Kind = NamespacedServiceAccountTokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespacedServiceAccountTokenHandlerFunc func(key string, obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) + +type NamespacedServiceAccountTokenChangeHandlerFunc func(obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) + +type NamespacedServiceAccountTokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NamespacedServiceAccountToken, err error) + Get(namespace, name string) (*v3.NamespacedServiceAccountToken, error) +} + +type NamespacedServiceAccountTokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespacedServiceAccountTokenLister + AddHandler(ctx context.Context, name string, handler NamespacedServiceAccountTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedServiceAccountTokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespacedServiceAccountTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespacedServiceAccountTokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespacedServiceAccountTokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) + Get(name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) + Update(*v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespacedServiceAccountTokenController + AddHandler(ctx context.Context, name string, sync NamespacedServiceAccountTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedServiceAccountTokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespacedServiceAccountTokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedServiceAccountTokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedServiceAccountTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedServiceAccountTokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedServiceAccountTokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedServiceAccountTokenLifecycle) +} + +type namespacedServiceAccountTokenLister struct { + ns string + controller *namespacedServiceAccountTokenController +} + +func (l *namespacedServiceAccountTokenLister) List(namespace string, selector labels.Selector) (ret []*v3.NamespacedServiceAccountToken, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NamespacedServiceAccountToken)) + }) + return +} + +func (l *namespacedServiceAccountTokenLister) Get(namespace, name string) (*v3.NamespacedServiceAccountToken, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespacedServiceAccountTokenGroupVersionKind.Group, + Resource: NamespacedServiceAccountTokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NamespacedServiceAccountToken), nil +} + +type namespacedServiceAccountTokenController struct { + ns string + controller.GenericController +} + +func (c *namespacedServiceAccountTokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespacedServiceAccountTokenController) Lister() NamespacedServiceAccountTokenLister { + return &namespacedServiceAccountTokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespacedServiceAccountTokenController) AddHandler(ctx context.Context, name string, handler NamespacedServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedServiceAccountToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedServiceAccountTokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespacedServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedServiceAccountToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedServiceAccountTokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespacedServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedServiceAccountToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedServiceAccountTokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespacedServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedServiceAccountToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespacedServiceAccountTokenFactory struct { +} + +func (c namespacedServiceAccountTokenFactory) Object() runtime.Object { + return &v3.NamespacedServiceAccountToken{} +} + +func (c namespacedServiceAccountTokenFactory) List() runtime.Object { + return &v3.NamespacedServiceAccountTokenList{} +} + +func (s *namespacedServiceAccountTokenClient) Controller() NamespacedServiceAccountTokenController { + genericController := controller.NewGenericController(s.ns, NamespacedServiceAccountTokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespacedServiceAccountTokenGroupVersionResource, NamespacedServiceAccountTokenGroupVersionKind.Kind, true)) + + return &namespacedServiceAccountTokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespacedServiceAccountTokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespacedServiceAccountTokenController +} + +func (s *namespacedServiceAccountTokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespacedServiceAccountTokenClient) Create(o *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) Get(name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) Update(o *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) UpdateStatus(o *v3.NamespacedServiceAccountToken) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespacedServiceAccountTokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespacedServiceAccountTokenClient) List(opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NamespacedServiceAccountTokenList), err +} + +func (s *namespacedServiceAccountTokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedServiceAccountTokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NamespacedServiceAccountTokenList), err +} + +func (s *namespacedServiceAccountTokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespacedServiceAccountTokenClient) Patch(o *v3.NamespacedServiceAccountToken, patchType types.PatchType, data []byte, subresources ...string) (*v3.NamespacedServiceAccountToken, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NamespacedServiceAccountToken), err +} + +func (s *namespacedServiceAccountTokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespacedServiceAccountTokenClient) AddHandler(ctx context.Context, name string, sync NamespacedServiceAccountTokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedServiceAccountTokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespacedServiceAccountTokenLifecycle) { + sync := NewNamespacedServiceAccountTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedServiceAccountTokenLifecycle) { + sync := NewNamespacedServiceAccountTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedServiceAccountTokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedServiceAccountTokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedServiceAccountTokenLifecycle) { + sync := NewNamespacedServiceAccountTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedServiceAccountTokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedServiceAccountTokenLifecycle) { + sync := NewNamespacedServiceAccountTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_lifecycle_adapter.go new file mode 100644 index 0000000..0bc4d3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_service_account_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespacedServiceAccountTokenLifecycle interface { + Create(obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) + Remove(obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) + Updated(obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) +} + +type namespacedServiceAccountTokenLifecycleAdapter struct { + lifecycle NamespacedServiceAccountTokenLifecycle +} + +func (w *namespacedServiceAccountTokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespacedServiceAccountTokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespacedServiceAccountTokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NamespacedServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedServiceAccountTokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NamespacedServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedServiceAccountTokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NamespacedServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespacedServiceAccountTokenLifecycleAdapter(name string, clusterScoped bool, client NamespacedServiceAccountTokenInterface, l NamespacedServiceAccountTokenLifecycle) NamespacedServiceAccountTokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespacedServiceAccountTokenGroupVersionResource) + } + adapter := &namespacedServiceAccountTokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NamespacedServiceAccountToken) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_controller.go new file mode 100644 index 0000000..3101b5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + NamespacedSSHAuthGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "NamespacedSSHAuth", + } + NamespacedSSHAuthResource = metav1.APIResource{ + Name: "namespacedsshauths", + SingularName: "namespacedsshauth", + Namespaced: true, + + Kind: NamespacedSSHAuthGroupVersionKind.Kind, + } + + NamespacedSSHAuthGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "namespacedsshauths", + } +) + +func init() { + resource.Put(NamespacedSSHAuthGroupVersionResource) +} + +// Deprecated: use v3.NamespacedSSHAuth instead +type NamespacedSSHAuth = v3.NamespacedSSHAuth + +func NewNamespacedSSHAuth(namespace, name string, obj v3.NamespacedSSHAuth) *v3.NamespacedSSHAuth { + obj.APIVersion, obj.Kind = NamespacedSSHAuthGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type NamespacedSSHAuthHandlerFunc func(key string, obj *v3.NamespacedSSHAuth) (runtime.Object, error) + +type NamespacedSSHAuthChangeHandlerFunc func(obj *v3.NamespacedSSHAuth) (runtime.Object, error) + +type NamespacedSSHAuthLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.NamespacedSSHAuth, err error) + Get(namespace, name string) (*v3.NamespacedSSHAuth, error) +} + +type NamespacedSSHAuthController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() NamespacedSSHAuthLister + AddHandler(ctx context.Context, name string, handler NamespacedSSHAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedSSHAuthHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler NamespacedSSHAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler NamespacedSSHAuthHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type NamespacedSSHAuthInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) + Get(name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) + Update(*v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() NamespacedSSHAuthController + AddHandler(ctx context.Context, name string, sync NamespacedSSHAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedSSHAuthHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle NamespacedSSHAuthLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedSSHAuthLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedSSHAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedSSHAuthHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedSSHAuthLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedSSHAuthLifecycle) +} + +type namespacedSshAuthLister struct { + ns string + controller *namespacedSshAuthController +} + +func (l *namespacedSshAuthLister) List(namespace string, selector labels.Selector) (ret []*v3.NamespacedSSHAuth, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.NamespacedSSHAuth)) + }) + return +} + +func (l *namespacedSshAuthLister) Get(namespace, name string) (*v3.NamespacedSSHAuth, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: NamespacedSSHAuthGroupVersionKind.Group, + Resource: NamespacedSSHAuthGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.NamespacedSSHAuth), nil +} + +type namespacedSshAuthController struct { + ns string + controller.GenericController +} + +func (c *namespacedSshAuthController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *namespacedSshAuthController) Lister() NamespacedSSHAuthLister { + return &namespacedSshAuthLister{ + ns: c.ns, + controller: c, + } +} + +func (c *namespacedSshAuthController) AddHandler(ctx context.Context, name string, handler NamespacedSSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedSSHAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedSshAuthController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler NamespacedSSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedSSHAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedSshAuthController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler NamespacedSSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedSSHAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *namespacedSshAuthController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler NamespacedSSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.NamespacedSSHAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type namespacedSshAuthFactory struct { +} + +func (c namespacedSshAuthFactory) Object() runtime.Object { + return &v3.NamespacedSSHAuth{} +} + +func (c namespacedSshAuthFactory) List() runtime.Object { + return &v3.NamespacedSSHAuthList{} +} + +func (s *namespacedSshAuthClient) Controller() NamespacedSSHAuthController { + genericController := controller.NewGenericController(s.ns, NamespacedSSHAuthGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(NamespacedSSHAuthGroupVersionResource, NamespacedSSHAuthGroupVersionKind.Kind, true)) + + return &namespacedSshAuthController{ + ns: s.ns, + GenericController: genericController, + } +} + +type namespacedSshAuthClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller NamespacedSSHAuthController +} + +func (s *namespacedSshAuthClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *namespacedSshAuthClient) Create(o *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) Get(name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) Update(o *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) UpdateStatus(o *v3.NamespacedSSHAuth) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *namespacedSshAuthClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *namespacedSshAuthClient) List(opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.NamespacedSSHAuthList), err +} + +func (s *namespacedSshAuthClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.NamespacedSSHAuthList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.NamespacedSSHAuthList), err +} + +func (s *namespacedSshAuthClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *namespacedSshAuthClient) Patch(o *v3.NamespacedSSHAuth, patchType types.PatchType, data []byte, subresources ...string) (*v3.NamespacedSSHAuth, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.NamespacedSSHAuth), err +} + +func (s *namespacedSshAuthClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *namespacedSshAuthClient) AddHandler(ctx context.Context, name string, sync NamespacedSSHAuthHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedSshAuthClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync NamespacedSSHAuthHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedSshAuthClient) AddLifecycle(ctx context.Context, name string, lifecycle NamespacedSSHAuthLifecycle) { + sync := NewNamespacedSSHAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *namespacedSshAuthClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle NamespacedSSHAuthLifecycle) { + sync := NewNamespacedSSHAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *namespacedSshAuthClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync NamespacedSSHAuthHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedSshAuthClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync NamespacedSSHAuthHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *namespacedSshAuthClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle NamespacedSSHAuthLifecycle) { + sync := NewNamespacedSSHAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *namespacedSshAuthClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle NamespacedSSHAuthLifecycle) { + sync := NewNamespacedSSHAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_lifecycle_adapter.go new file mode 100644 index 0000000..7b12b4b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_namespaced_ssh_auth_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type NamespacedSSHAuthLifecycle interface { + Create(obj *v3.NamespacedSSHAuth) (runtime.Object, error) + Remove(obj *v3.NamespacedSSHAuth) (runtime.Object, error) + Updated(obj *v3.NamespacedSSHAuth) (runtime.Object, error) +} + +type namespacedSshAuthLifecycleAdapter struct { + lifecycle NamespacedSSHAuthLifecycle +} + +func (w *namespacedSshAuthLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *namespacedSshAuthLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *namespacedSshAuthLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.NamespacedSSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedSshAuthLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.NamespacedSSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *namespacedSshAuthLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.NamespacedSSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func NewNamespacedSSHAuthLifecycleAdapter(name string, clusterScoped bool, client NamespacedSSHAuthInterface, l NamespacedSSHAuthLifecycle) NamespacedSSHAuthHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(NamespacedSSHAuthGroupVersionResource) + } + adapter := &namespacedSshAuthLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.NamespacedSSHAuth) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_scheme.go new file mode 100644 index 0000000..12e4100 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "project.cattle.io" + Version = "v3" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_controller.go new file mode 100644 index 0000000..07c8dcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ServiceAccountTokenGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ServiceAccountToken", + } + ServiceAccountTokenResource = metav1.APIResource{ + Name: "serviceaccounttokens", + SingularName: "serviceaccounttoken", + Namespaced: true, + + Kind: ServiceAccountTokenGroupVersionKind.Kind, + } + + ServiceAccountTokenGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "serviceaccounttokens", + } +) + +func init() { + resource.Put(ServiceAccountTokenGroupVersionResource) +} + +// Deprecated: use v3.ServiceAccountToken instead +type ServiceAccountToken = v3.ServiceAccountToken + +func NewServiceAccountToken(namespace, name string, obj v3.ServiceAccountToken) *v3.ServiceAccountToken { + obj.APIVersion, obj.Kind = ServiceAccountTokenGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ServiceAccountTokenHandlerFunc func(key string, obj *v3.ServiceAccountToken) (runtime.Object, error) + +type ServiceAccountTokenChangeHandlerFunc func(obj *v3.ServiceAccountToken) (runtime.Object, error) + +type ServiceAccountTokenLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.ServiceAccountToken, err error) + Get(namespace, name string) (*v3.ServiceAccountToken, error) +} + +type ServiceAccountTokenController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ServiceAccountTokenLister + AddHandler(ctx context.Context, name string, handler ServiceAccountTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountTokenHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ServiceAccountTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ServiceAccountTokenHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ServiceAccountTokenInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) + Get(name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) + Update(*v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ServiceAccountTokenController + AddHandler(ctx context.Context, name string, sync ServiceAccountTokenHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountTokenHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ServiceAccountTokenLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceAccountTokenLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceAccountTokenHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceAccountTokenHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceAccountTokenLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceAccountTokenLifecycle) +} + +type serviceAccountTokenLister struct { + ns string + controller *serviceAccountTokenController +} + +func (l *serviceAccountTokenLister) List(namespace string, selector labels.Selector) (ret []*v3.ServiceAccountToken, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.ServiceAccountToken)) + }) + return +} + +func (l *serviceAccountTokenLister) Get(namespace, name string) (*v3.ServiceAccountToken, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ServiceAccountTokenGroupVersionKind.Group, + Resource: ServiceAccountTokenGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.ServiceAccountToken), nil +} + +type serviceAccountTokenController struct { + ns string + controller.GenericController +} + +func (c *serviceAccountTokenController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *serviceAccountTokenController) Lister() ServiceAccountTokenLister { + return &serviceAccountTokenLister{ + ns: c.ns, + controller: c, + } +} + +func (c *serviceAccountTokenController) AddHandler(ctx context.Context, name string, handler ServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ServiceAccountToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountTokenController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ServiceAccountToken); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountTokenController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ServiceAccountToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *serviceAccountTokenController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ServiceAccountTokenHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.ServiceAccountToken); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type serviceAccountTokenFactory struct { +} + +func (c serviceAccountTokenFactory) Object() runtime.Object { + return &v3.ServiceAccountToken{} +} + +func (c serviceAccountTokenFactory) List() runtime.Object { + return &v3.ServiceAccountTokenList{} +} + +func (s *serviceAccountTokenClient) Controller() ServiceAccountTokenController { + genericController := controller.NewGenericController(s.ns, ServiceAccountTokenGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ServiceAccountTokenGroupVersionResource, ServiceAccountTokenGroupVersionKind.Kind, true)) + + return &serviceAccountTokenController{ + ns: s.ns, + GenericController: genericController, + } +} + +type serviceAccountTokenClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ServiceAccountTokenController +} + +func (s *serviceAccountTokenClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *serviceAccountTokenClient) Create(o *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) Get(name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) Update(o *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) UpdateStatus(o *v3.ServiceAccountToken) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *serviceAccountTokenClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *serviceAccountTokenClient) List(opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.ServiceAccountTokenList), err +} + +func (s *serviceAccountTokenClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.ServiceAccountTokenList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.ServiceAccountTokenList), err +} + +func (s *serviceAccountTokenClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *serviceAccountTokenClient) Patch(o *v3.ServiceAccountToken, patchType types.PatchType, data []byte, subresources ...string) (*v3.ServiceAccountToken, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.ServiceAccountToken), err +} + +func (s *serviceAccountTokenClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *serviceAccountTokenClient) AddHandler(ctx context.Context, name string, sync ServiceAccountTokenHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceAccountTokenClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ServiceAccountTokenHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceAccountTokenClient) AddLifecycle(ctx context.Context, name string, lifecycle ServiceAccountTokenLifecycle) { + sync := NewServiceAccountTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *serviceAccountTokenClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ServiceAccountTokenLifecycle) { + sync := NewServiceAccountTokenLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *serviceAccountTokenClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ServiceAccountTokenHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceAccountTokenClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ServiceAccountTokenHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *serviceAccountTokenClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ServiceAccountTokenLifecycle) { + sync := NewServiceAccountTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *serviceAccountTokenClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ServiceAccountTokenLifecycle) { + sync := NewServiceAccountTokenLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_lifecycle_adapter.go new file mode 100644 index 0000000..f7da110 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_service_account_token_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type ServiceAccountTokenLifecycle interface { + Create(obj *v3.ServiceAccountToken) (runtime.Object, error) + Remove(obj *v3.ServiceAccountToken) (runtime.Object, error) + Updated(obj *v3.ServiceAccountToken) (runtime.Object, error) +} + +type serviceAccountTokenLifecycleAdapter struct { + lifecycle ServiceAccountTokenLifecycle +} + +func (w *serviceAccountTokenLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *serviceAccountTokenLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *serviceAccountTokenLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.ServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceAccountTokenLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.ServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *serviceAccountTokenLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.ServiceAccountToken)) + if o == nil { + return nil, err + } + return o, err +} + +func NewServiceAccountTokenLifecycleAdapter(name string, clusterScoped bool, client ServiceAccountTokenInterface, l ServiceAccountTokenLifecycle) ServiceAccountTokenHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ServiceAccountTokenGroupVersionResource) + } + adapter := &serviceAccountTokenLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.ServiceAccountToken) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_controller.go new file mode 100644 index 0000000..30ac53a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + SSHAuthGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "SSHAuth", + } + SSHAuthResource = metav1.APIResource{ + Name: "sshauths", + SingularName: "sshauth", + Namespaced: true, + + Kind: SSHAuthGroupVersionKind.Kind, + } + + SSHAuthGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "sshauths", + } +) + +func init() { + resource.Put(SSHAuthGroupVersionResource) +} + +// Deprecated: use v3.SSHAuth instead +type SSHAuth = v3.SSHAuth + +func NewSSHAuth(namespace, name string, obj v3.SSHAuth) *v3.SSHAuth { + obj.APIVersion, obj.Kind = SSHAuthGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type SSHAuthHandlerFunc func(key string, obj *v3.SSHAuth) (runtime.Object, error) + +type SSHAuthChangeHandlerFunc func(obj *v3.SSHAuth) (runtime.Object, error) + +type SSHAuthLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.SSHAuth, err error) + Get(namespace, name string) (*v3.SSHAuth, error) +} + +type SSHAuthController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() SSHAuthLister + AddHandler(ctx context.Context, name string, handler SSHAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SSHAuthHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler SSHAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler SSHAuthHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type SSHAuthInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.SSHAuth) (*v3.SSHAuth, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.SSHAuth, error) + Get(name string, opts metav1.GetOptions) (*v3.SSHAuth, error) + Update(*v3.SSHAuth) (*v3.SSHAuth, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.SSHAuthList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SSHAuthList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() SSHAuthController + AddHandler(ctx context.Context, name string, sync SSHAuthHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SSHAuthHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle SSHAuthLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SSHAuthLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SSHAuthHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SSHAuthHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SSHAuthLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SSHAuthLifecycle) +} + +type sshAuthLister struct { + ns string + controller *sshAuthController +} + +func (l *sshAuthLister) List(namespace string, selector labels.Selector) (ret []*v3.SSHAuth, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.SSHAuth)) + }) + return +} + +func (l *sshAuthLister) Get(namespace, name string) (*v3.SSHAuth, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: SSHAuthGroupVersionKind.Group, + Resource: SSHAuthGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.SSHAuth), nil +} + +type sshAuthController struct { + ns string + controller.GenericController +} + +func (c *sshAuthController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *sshAuthController) Lister() SSHAuthLister { + return &sshAuthLister{ + ns: c.ns, + controller: c, + } +} + +func (c *sshAuthController) AddHandler(ctx context.Context, name string, handler SSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SSHAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *sshAuthController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler SSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SSHAuth); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *sshAuthController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler SSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SSHAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *sshAuthController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler SSHAuthHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.SSHAuth); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type sshAuthFactory struct { +} + +func (c sshAuthFactory) Object() runtime.Object { + return &v3.SSHAuth{} +} + +func (c sshAuthFactory) List() runtime.Object { + return &v3.SSHAuthList{} +} + +func (s *sshAuthClient) Controller() SSHAuthController { + genericController := controller.NewGenericController(s.ns, SSHAuthGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(SSHAuthGroupVersionResource, SSHAuthGroupVersionKind.Kind, true)) + + return &sshAuthController{ + ns: s.ns, + GenericController: genericController, + } +} + +type sshAuthClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller SSHAuthController +} + +func (s *sshAuthClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *sshAuthClient) Create(o *v3.SSHAuth) (*v3.SSHAuth, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) Get(name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.SSHAuth, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) Update(o *v3.SSHAuth) (*v3.SSHAuth, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) UpdateStatus(o *v3.SSHAuth) (*v3.SSHAuth, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *sshAuthClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *sshAuthClient) List(opts metav1.ListOptions) (*v3.SSHAuthList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.SSHAuthList), err +} + +func (s *sshAuthClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.SSHAuthList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.SSHAuthList), err +} + +func (s *sshAuthClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *sshAuthClient) Patch(o *v3.SSHAuth, patchType types.PatchType, data []byte, subresources ...string) (*v3.SSHAuth, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.SSHAuth), err +} + +func (s *sshAuthClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *sshAuthClient) AddHandler(ctx context.Context, name string, sync SSHAuthHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *sshAuthClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync SSHAuthHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *sshAuthClient) AddLifecycle(ctx context.Context, name string, lifecycle SSHAuthLifecycle) { + sync := NewSSHAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *sshAuthClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle SSHAuthLifecycle) { + sync := NewSSHAuthLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *sshAuthClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync SSHAuthHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *sshAuthClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync SSHAuthHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *sshAuthClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle SSHAuthLifecycle) { + sync := NewSSHAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *sshAuthClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle SSHAuthLifecycle) { + sync := NewSSHAuthLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_lifecycle_adapter.go new file mode 100644 index 0000000..6bc9854 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_ssh_auth_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type SSHAuthLifecycle interface { + Create(obj *v3.SSHAuth) (runtime.Object, error) + Remove(obj *v3.SSHAuth) (runtime.Object, error) + Updated(obj *v3.SSHAuth) (runtime.Object, error) +} + +type sshAuthLifecycleAdapter struct { + lifecycle SSHAuthLifecycle +} + +func (w *sshAuthLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *sshAuthLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *sshAuthLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.SSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *sshAuthLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.SSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *sshAuthLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.SSHAuth)) + if o == nil { + return nil, err + } + return o, err +} + +func NewSSHAuthLifecycleAdapter(name string, clusterScoped bool, client SSHAuthInterface, l SSHAuthLifecycle) SSHAuthHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(SSHAuthGroupVersionResource) + } + adapter := &sshAuthLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.SSHAuth) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_controller.go new file mode 100644 index 0000000..5c4b39a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_controller.go @@ -0,0 +1,326 @@ +package v3 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + WorkloadGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Workload", + } + WorkloadResource = metav1.APIResource{ + Name: "workloads", + SingularName: "workload", + Namespaced: true, + + Kind: WorkloadGroupVersionKind.Kind, + } + + WorkloadGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "workloads", + } +) + +func init() { + resource.Put(WorkloadGroupVersionResource) +} + +// Deprecated: use v3.Workload instead +type Workload = v3.Workload + +func NewWorkload(namespace, name string, obj v3.Workload) *v3.Workload { + obj.APIVersion, obj.Kind = WorkloadGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type WorkloadHandlerFunc func(key string, obj *v3.Workload) (runtime.Object, error) + +type WorkloadChangeHandlerFunc func(obj *v3.Workload) (runtime.Object, error) + +type WorkloadLister interface { + List(namespace string, selector labels.Selector) (ret []*v3.Workload, err error) + Get(namespace, name string) (*v3.Workload, error) +} + +type WorkloadController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() WorkloadLister + AddHandler(ctx context.Context, name string, handler WorkloadHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync WorkloadHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler WorkloadHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler WorkloadHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type WorkloadInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v3.Workload) (*v3.Workload, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Workload, error) + Get(name string, opts metav1.GetOptions) (*v3.Workload, error) + Update(*v3.Workload) (*v3.Workload, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v3.WorkloadList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.WorkloadList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() WorkloadController + AddHandler(ctx context.Context, name string, sync WorkloadHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync WorkloadHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle WorkloadLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle WorkloadLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync WorkloadHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync WorkloadHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle WorkloadLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle WorkloadLifecycle) +} + +type workloadLister struct { + ns string + controller *workloadController +} + +func (l *workloadLister) List(namespace string, selector labels.Selector) (ret []*v3.Workload, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v3.Workload)) + }) + return +} + +func (l *workloadLister) Get(namespace, name string) (*v3.Workload, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: WorkloadGroupVersionKind.Group, + Resource: WorkloadGroupVersionResource.Resource, + }, key) + } + return obj.(*v3.Workload), nil +} + +type workloadController struct { + ns string + controller.GenericController +} + +func (c *workloadController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *workloadController) Lister() WorkloadLister { + return &workloadLister{ + ns: c.ns, + controller: c, + } +} + +func (c *workloadController) AddHandler(ctx context.Context, name string, handler WorkloadHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Workload); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *workloadController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler WorkloadHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Workload); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *workloadController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler WorkloadHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Workload); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *workloadController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler WorkloadHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v3.Workload); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type workloadFactory struct { +} + +func (c workloadFactory) Object() runtime.Object { + return &v3.Workload{} +} + +func (c workloadFactory) List() runtime.Object { + return &v3.WorkloadList{} +} + +func (s *workloadClient) Controller() WorkloadController { + genericController := controller.NewGenericController(s.ns, WorkloadGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(WorkloadGroupVersionResource, WorkloadGroupVersionKind.Kind, true)) + + return &workloadController{ + ns: s.ns, + GenericController: genericController, + } +} + +type workloadClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller WorkloadController +} + +func (s *workloadClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *workloadClient) Create(o *v3.Workload) (*v3.Workload, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) Get(name string, opts metav1.GetOptions) (*v3.Workload, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v3.Workload, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) Update(o *v3.Workload) (*v3.Workload, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) UpdateStatus(o *v3.Workload) (*v3.Workload, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *workloadClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *workloadClient) List(opts metav1.ListOptions) (*v3.WorkloadList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v3.WorkloadList), err +} + +func (s *workloadClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v3.WorkloadList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v3.WorkloadList), err +} + +func (s *workloadClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *workloadClient) Patch(o *v3.Workload, patchType types.PatchType, data []byte, subresources ...string) (*v3.Workload, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v3.Workload), err +} + +func (s *workloadClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *workloadClient) AddHandler(ctx context.Context, name string, sync WorkloadHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *workloadClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync WorkloadHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *workloadClient) AddLifecycle(ctx context.Context, name string, lifecycle WorkloadLifecycle) { + sync := NewWorkloadLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *workloadClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle WorkloadLifecycle) { + sync := NewWorkloadLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *workloadClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync WorkloadHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *workloadClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync WorkloadHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *workloadClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle WorkloadLifecycle) { + sync := NewWorkloadLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *workloadClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle WorkloadLifecycle) { + sync := NewWorkloadLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_lifecycle_adapter.go new file mode 100644 index 0000000..879db89 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/project.cattle.io/v3/zz_generated_workload_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v3 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "k8s.io/apimachinery/pkg/runtime" +) + +type WorkloadLifecycle interface { + Create(obj *v3.Workload) (runtime.Object, error) + Remove(obj *v3.Workload) (runtime.Object, error) + Updated(obj *v3.Workload) (runtime.Object, error) +} + +type workloadLifecycleAdapter struct { + lifecycle WorkloadLifecycle +} + +func (w *workloadLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *workloadLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *workloadLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v3.Workload)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *workloadLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v3.Workload)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *workloadLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v3.Workload)) + if o == nil { + return nil, err + } + return o, err +} + +func NewWorkloadLifecycleAdapter(name string, clusterScoped bool, client WorkloadInterface, l WorkloadLifecycle) WorkloadHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(WorkloadGroupVersionResource) + } + adapter := &workloadLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v3.Workload) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_binding_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_binding_mock.go new file mode 100644 index 0000000..e8b64d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_binding_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterRoleBindingListerMockGet sync.RWMutex + lockClusterRoleBindingListerMockList sync.RWMutex +) + +// Ensure, that ClusterRoleBindingListerMock does implement v11.ClusterRoleBindingLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleBindingLister = &ClusterRoleBindingListerMock{} + +// ClusterRoleBindingListerMock is a mock implementation of v11.ClusterRoleBindingLister. +// +// func TestSomethingThatUsesClusterRoleBindingLister(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleBindingLister +// mockedClusterRoleBindingLister := &ClusterRoleBindingListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ClusterRoleBinding, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ClusterRoleBinding, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterRoleBindingLister in code that requires v11.ClusterRoleBindingLister +// // and then make assertions. +// +// } +type ClusterRoleBindingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ClusterRoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ClusterRoleBinding, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterRoleBindingListerMock) Get(namespace string, name string) (*v1.ClusterRoleBinding, error) { + if mock.GetFunc == nil { + panic("ClusterRoleBindingListerMock.GetFunc: method is nil but ClusterRoleBindingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleBindingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleBindingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleBindingLister.GetCalls()) +func (mock *ClusterRoleBindingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleBindingListerMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleBindingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleBindingListerMock) List(namespace string, selector labels.Selector) ([]*v1.ClusterRoleBinding, error) { + if mock.ListFunc == nil { + panic("ClusterRoleBindingListerMock.ListFunc: method is nil but ClusterRoleBindingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterRoleBindingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleBindingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleBindingLister.ListCalls()) +func (mock *ClusterRoleBindingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterRoleBindingListerMockList.RLock() + calls = mock.calls.List + lockClusterRoleBindingListerMockList.RUnlock() + return calls +} + +var ( + lockClusterRoleBindingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleBindingControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleBindingControllerMockAddFeatureHandler sync.RWMutex + lockClusterRoleBindingControllerMockAddHandler sync.RWMutex + lockClusterRoleBindingControllerMockEnqueue sync.RWMutex + lockClusterRoleBindingControllerMockEnqueueAfter sync.RWMutex + lockClusterRoleBindingControllerMockGeneric sync.RWMutex + lockClusterRoleBindingControllerMockInformer sync.RWMutex + lockClusterRoleBindingControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterRoleBindingControllerMock does implement v11.ClusterRoleBindingController. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleBindingController = &ClusterRoleBindingControllerMock{} + +// ClusterRoleBindingControllerMock is a mock implementation of v11.ClusterRoleBindingController. +// +// func TestSomethingThatUsesClusterRoleBindingController(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleBindingController +// mockedClusterRoleBindingController := &ClusterRoleBindingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ClusterRoleBindingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterRoleBindingController in code that requires v11.ClusterRoleBindingController +// // and then make assertions. +// +// } +type ClusterRoleBindingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ClusterRoleBindingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ClusterRoleBindingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ClusterRoleBindingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ClusterRoleBindingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleBindingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ClusterRoleBindingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleBindingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleBindingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleBindingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleBindingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleBindingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleBindingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleBindingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleBindingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleBindingControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleBindingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleBindingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleBindingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingController.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleBindingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleBindingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleBindingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleBindingControllerMock.AddFeatureHandlerFunc: method is nil but ClusterRoleBindingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleBindingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleBindingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingController.AddFeatureHandlerCalls()) +func (mock *ClusterRoleBindingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleBindingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleBindingControllerMock) AddHandler(ctx context.Context, name string, handler v11.ClusterRoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleBindingControllerMock.AddHandlerFunc: method is nil but ClusterRoleBindingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterRoleBindingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleBindingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingController.AddHandlerCalls()) +func (mock *ClusterRoleBindingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleBindingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterRoleBindingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterRoleBindingControllerMock.EnqueueFunc: method is nil but ClusterRoleBindingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleBindingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterRoleBindingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterRoleBindingController.EnqueueCalls()) +func (mock *ClusterRoleBindingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleBindingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterRoleBindingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterRoleBindingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterRoleBindingControllerMock.EnqueueAfterFunc: method is nil but ClusterRoleBindingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterRoleBindingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterRoleBindingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterRoleBindingController.EnqueueAfterCalls()) +func (mock *ClusterRoleBindingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterRoleBindingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterRoleBindingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterRoleBindingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterRoleBindingControllerMock.GenericFunc: method is nil but ClusterRoleBindingController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterRoleBindingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterRoleBindingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterRoleBindingController.GenericCalls()) +func (mock *ClusterRoleBindingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleBindingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterRoleBindingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterRoleBindingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterRoleBindingControllerMock.InformerFunc: method is nil but ClusterRoleBindingController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterRoleBindingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterRoleBindingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterRoleBindingController.InformerCalls()) +func (mock *ClusterRoleBindingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleBindingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterRoleBindingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterRoleBindingControllerMock) Lister() v11.ClusterRoleBindingLister { + if mock.ListerFunc == nil { + panic("ClusterRoleBindingControllerMock.ListerFunc: method is nil but ClusterRoleBindingController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterRoleBindingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterRoleBindingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterRoleBindingController.ListerCalls()) +func (mock *ClusterRoleBindingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleBindingControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterRoleBindingControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterRoleBindingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleBindingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterRoleBindingInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterRoleBindingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterRoleBindingInterfaceMockAddHandler sync.RWMutex + lockClusterRoleBindingInterfaceMockAddLifecycle sync.RWMutex + lockClusterRoleBindingInterfaceMockController sync.RWMutex + lockClusterRoleBindingInterfaceMockCreate sync.RWMutex + lockClusterRoleBindingInterfaceMockDelete sync.RWMutex + lockClusterRoleBindingInterfaceMockDeleteCollection sync.RWMutex + lockClusterRoleBindingInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterRoleBindingInterfaceMockGet sync.RWMutex + lockClusterRoleBindingInterfaceMockGetNamespaced sync.RWMutex + lockClusterRoleBindingInterfaceMockList sync.RWMutex + lockClusterRoleBindingInterfaceMockListNamespaced sync.RWMutex + lockClusterRoleBindingInterfaceMockObjectClient sync.RWMutex + lockClusterRoleBindingInterfaceMockUpdate sync.RWMutex + lockClusterRoleBindingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterRoleBindingInterfaceMock does implement v11.ClusterRoleBindingInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleBindingInterface = &ClusterRoleBindingInterfaceMock{} + +// ClusterRoleBindingInterfaceMock is a mock implementation of v11.ClusterRoleBindingInterface. +// +// func TestSomethingThatUsesClusterRoleBindingInterface(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleBindingInterface +// mockedClusterRoleBindingInterface := &ClusterRoleBindingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleBindingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ClusterRoleBindingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ClusterRoleBindingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterRoleBindingInterface in code that requires v11.ClusterRoleBindingInterface +// // and then make assertions. +// +// } +type ClusterRoleBindingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleBindingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ClusterRoleBindingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ClusterRoleBindingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ClusterRoleBindingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleBindingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ClusterRoleBindingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleBindingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleBindingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleBindingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleBindingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleBindingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ClusterRoleBinding + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ClusterRoleBinding + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleBindingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterRoleBindingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle + } + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleBindingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleBindingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleBindingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleBindingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleBindingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterRoleBindingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleBindingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterRoleBindingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleBindingLifecycle + } + lockClusterRoleBindingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterRoleBindingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterRoleBindingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleBindingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleBindingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddFeatureHandlerCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleBindingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleBindingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterRoleBindingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleBindingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterRoleBindingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleBindingLifecycle + } + lockClusterRoleBindingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterRoleBindingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ClusterRoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddHandlerFunc: method is nil but ClusterRoleBindingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleBindingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleBindingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddHandlerCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleBindingHandlerFunc + } + lockClusterRoleBindingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleBindingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterRoleBindingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ClusterRoleBindingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterRoleBindingInterfaceMock.AddLifecycleFunc: method is nil but ClusterRoleBindingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleBindingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterRoleBindingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.AddLifecycleCalls()) +func (mock *ClusterRoleBindingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleBindingLifecycle + } + lockClusterRoleBindingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterRoleBindingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterRoleBindingInterfaceMock) Controller() v11.ClusterRoleBindingController { + if mock.ControllerFunc == nil { + panic("ClusterRoleBindingInterfaceMock.ControllerFunc: method is nil but ClusterRoleBindingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterRoleBindingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterRoleBindingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.ControllerCalls()) +func (mock *ClusterRoleBindingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleBindingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterRoleBindingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterRoleBindingInterfaceMock) Create(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { + if mock.CreateFunc == nil { + panic("ClusterRoleBindingInterfaceMock.CreateFunc: method is nil but ClusterRoleBindingInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ClusterRoleBinding + }{ + In1: in1, + } + lockClusterRoleBindingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterRoleBindingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.CreateCalls()) +func (mock *ClusterRoleBindingInterfaceMock) CreateCalls() []struct { + In1 *v1.ClusterRoleBinding +} { + var calls []struct { + In1 *v1.ClusterRoleBinding + } + lockClusterRoleBindingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterRoleBindingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterRoleBindingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterRoleBindingInterfaceMock.DeleteFunc: method is nil but ClusterRoleBindingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterRoleBindingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterRoleBindingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.DeleteCalls()) +func (mock *ClusterRoleBindingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleBindingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterRoleBindingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterRoleBindingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterRoleBindingInterfaceMock.DeleteCollectionFunc: method is nil but ClusterRoleBindingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterRoleBindingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterRoleBindingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.DeleteCollectionCalls()) +func (mock *ClusterRoleBindingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterRoleBindingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterRoleBindingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterRoleBindingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterRoleBindingInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterRoleBindingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterRoleBindingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterRoleBindingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.DeleteNamespacedCalls()) +func (mock *ClusterRoleBindingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleBindingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterRoleBindingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterRoleBindingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { + if mock.GetFunc == nil { + panic("ClusterRoleBindingInterfaceMock.GetFunc: method is nil but ClusterRoleBindingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterRoleBindingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleBindingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.GetCalls()) +func (mock *ClusterRoleBindingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterRoleBindingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleBindingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterRoleBindingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterRoleBindingInterfaceMock.GetNamespacedFunc: method is nil but ClusterRoleBindingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterRoleBindingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterRoleBindingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.GetNamespacedCalls()) +func (mock *ClusterRoleBindingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterRoleBindingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterRoleBindingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleBindingInterfaceMock) List(opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { + if mock.ListFunc == nil { + panic("ClusterRoleBindingInterfaceMock.ListFunc: method is nil but ClusterRoleBindingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleBindingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleBindingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.ListCalls()) +func (mock *ClusterRoleBindingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleBindingInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterRoleBindingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterRoleBindingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterRoleBindingInterfaceMock.ListNamespacedFunc: method is nil but ClusterRoleBindingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterRoleBindingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterRoleBindingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.ListNamespacedCalls()) +func (mock *ClusterRoleBindingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterRoleBindingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterRoleBindingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterRoleBindingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterRoleBindingInterfaceMock.ObjectClientFunc: method is nil but ClusterRoleBindingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterRoleBindingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterRoleBindingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.ObjectClientCalls()) +func (mock *ClusterRoleBindingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleBindingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterRoleBindingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterRoleBindingInterfaceMock) Update(in1 *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { + if mock.UpdateFunc == nil { + panic("ClusterRoleBindingInterfaceMock.UpdateFunc: method is nil but ClusterRoleBindingInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ClusterRoleBinding + }{ + In1: in1, + } + lockClusterRoleBindingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterRoleBindingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.UpdateCalls()) +func (mock *ClusterRoleBindingInterfaceMock) UpdateCalls() []struct { + In1 *v1.ClusterRoleBinding +} { + var calls []struct { + In1 *v1.ClusterRoleBinding + } + lockClusterRoleBindingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterRoleBindingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterRoleBindingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterRoleBindingInterfaceMock.WatchFunc: method is nil but ClusterRoleBindingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleBindingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterRoleBindingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterRoleBindingInterface.WatchCalls()) +func (mock *ClusterRoleBindingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleBindingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterRoleBindingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterRoleBindingsGetterMockClusterRoleBindings sync.RWMutex +) + +// Ensure, that ClusterRoleBindingsGetterMock does implement v11.ClusterRoleBindingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleBindingsGetter = &ClusterRoleBindingsGetterMock{} + +// ClusterRoleBindingsGetterMock is a mock implementation of v11.ClusterRoleBindingsGetter. +// +// func TestSomethingThatUsesClusterRoleBindingsGetter(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleBindingsGetter +// mockedClusterRoleBindingsGetter := &ClusterRoleBindingsGetterMock{ +// ClusterRoleBindingsFunc: func(namespace string) v11.ClusterRoleBindingInterface { +// panic("mock out the ClusterRoleBindings method") +// }, +// } +// +// // use mockedClusterRoleBindingsGetter in code that requires v11.ClusterRoleBindingsGetter +// // and then make assertions. +// +// } +type ClusterRoleBindingsGetterMock struct { + // ClusterRoleBindingsFunc mocks the ClusterRoleBindings method. + ClusterRoleBindingsFunc func(namespace string) v11.ClusterRoleBindingInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterRoleBindings holds details about calls to the ClusterRoleBindings method. + ClusterRoleBindings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterRoleBindings calls ClusterRoleBindingsFunc. +func (mock *ClusterRoleBindingsGetterMock) ClusterRoleBindings(namespace string) v11.ClusterRoleBindingInterface { + if mock.ClusterRoleBindingsFunc == nil { + panic("ClusterRoleBindingsGetterMock.ClusterRoleBindingsFunc: method is nil but ClusterRoleBindingsGetter.ClusterRoleBindings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterRoleBindingsGetterMockClusterRoleBindings.Lock() + mock.calls.ClusterRoleBindings = append(mock.calls.ClusterRoleBindings, callInfo) + lockClusterRoleBindingsGetterMockClusterRoleBindings.Unlock() + return mock.ClusterRoleBindingsFunc(namespace) +} + +// ClusterRoleBindingsCalls gets all the calls that were made to ClusterRoleBindings. +// Check the length with: +// +// len(mockedClusterRoleBindingsGetter.ClusterRoleBindingsCalls()) +func (mock *ClusterRoleBindingsGetterMock) ClusterRoleBindingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterRoleBindingsGetterMockClusterRoleBindings.RLock() + calls = mock.calls.ClusterRoleBindings + lockClusterRoleBindingsGetterMockClusterRoleBindings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_mock.go new file mode 100644 index 0000000..b4e222f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_cluster_role_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockClusterRoleListerMockGet sync.RWMutex + lockClusterRoleListerMockList sync.RWMutex +) + +// Ensure, that ClusterRoleListerMock does implement v11.ClusterRoleLister. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleLister = &ClusterRoleListerMock{} + +// ClusterRoleListerMock is a mock implementation of v11.ClusterRoleLister. +// +// func TestSomethingThatUsesClusterRoleLister(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleLister +// mockedClusterRoleLister := &ClusterRoleListerMock{ +// GetFunc: func(namespace string, name string) (*v1.ClusterRole, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.ClusterRole, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedClusterRoleLister in code that requires v11.ClusterRoleLister +// // and then make assertions. +// +// } +type ClusterRoleListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.ClusterRole, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.ClusterRole, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *ClusterRoleListerMock) Get(namespace string, name string) (*v1.ClusterRole, error) { + if mock.GetFunc == nil { + panic("ClusterRoleListerMock.GetFunc: method is nil but ClusterRoleLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleLister.GetCalls()) +func (mock *ClusterRoleListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleListerMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleListerMock) List(namespace string, selector labels.Selector) ([]*v1.ClusterRole, error) { + if mock.ListFunc == nil { + panic("ClusterRoleListerMock.ListFunc: method is nil but ClusterRoleLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockClusterRoleListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleLister.ListCalls()) +func (mock *ClusterRoleListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockClusterRoleListerMockList.RLock() + calls = mock.calls.List + lockClusterRoleListerMockList.RUnlock() + return calls +} + +var ( + lockClusterRoleControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleControllerMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleControllerMockAddFeatureHandler sync.RWMutex + lockClusterRoleControllerMockAddHandler sync.RWMutex + lockClusterRoleControllerMockEnqueue sync.RWMutex + lockClusterRoleControllerMockEnqueueAfter sync.RWMutex + lockClusterRoleControllerMockGeneric sync.RWMutex + lockClusterRoleControllerMockInformer sync.RWMutex + lockClusterRoleControllerMockLister sync.RWMutex +) + +// Ensure, that ClusterRoleControllerMock does implement v11.ClusterRoleController. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleController = &ClusterRoleControllerMock{} + +// ClusterRoleControllerMock is a mock implementation of v11.ClusterRoleController. +// +// func TestSomethingThatUsesClusterRoleController(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleController +// mockedClusterRoleController := &ClusterRoleControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.ClusterRoleLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedClusterRoleController in code that requires v11.ClusterRoleController +// // and then make assertions. +// +// } +type ClusterRoleControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.ClusterRoleHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.ClusterRoleLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ClusterRoleHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.ClusterRoleHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.ClusterRoleHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleController.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc + } + lockClusterRoleControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.ClusterRoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleControllerMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockClusterRoleControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleController.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.ClusterRoleHandlerFunc + } + lockClusterRoleControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleControllerMock.AddFeatureHandlerFunc: method is nil but ClusterRoleController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleController.AddFeatureHandlerCalls()) +func (mock *ClusterRoleControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc + } + lockClusterRoleControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleControllerMock) AddHandler(ctx context.Context, name string, handler v11.ClusterRoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleControllerMock.AddHandlerFunc: method is nil but ClusterRoleController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockClusterRoleControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleController.AddHandlerCalls()) +func (mock *ClusterRoleControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.ClusterRoleHandlerFunc + } + lockClusterRoleControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *ClusterRoleControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("ClusterRoleControllerMock.EnqueueFunc: method is nil but ClusterRoleController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockClusterRoleControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockClusterRoleControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedClusterRoleController.EnqueueCalls()) +func (mock *ClusterRoleControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockClusterRoleControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockClusterRoleControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *ClusterRoleControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("ClusterRoleControllerMock.EnqueueAfterFunc: method is nil but ClusterRoleController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockClusterRoleControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockClusterRoleControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedClusterRoleController.EnqueueAfterCalls()) +func (mock *ClusterRoleControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockClusterRoleControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockClusterRoleControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *ClusterRoleControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("ClusterRoleControllerMock.GenericFunc: method is nil but ClusterRoleController.Generic was just called") + } + callInfo := struct { + }{} + lockClusterRoleControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockClusterRoleControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedClusterRoleController.GenericCalls()) +func (mock *ClusterRoleControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockClusterRoleControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *ClusterRoleControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("ClusterRoleControllerMock.InformerFunc: method is nil but ClusterRoleController.Informer was just called") + } + callInfo := struct { + }{} + lockClusterRoleControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockClusterRoleControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedClusterRoleController.InformerCalls()) +func (mock *ClusterRoleControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleControllerMockInformer.RLock() + calls = mock.calls.Informer + lockClusterRoleControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *ClusterRoleControllerMock) Lister() v11.ClusterRoleLister { + if mock.ListerFunc == nil { + panic("ClusterRoleControllerMock.ListerFunc: method is nil but ClusterRoleController.Lister was just called") + } + callInfo := struct { + }{} + lockClusterRoleControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockClusterRoleControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedClusterRoleController.ListerCalls()) +func (mock *ClusterRoleControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleControllerMockLister.RLock() + calls = mock.calls.Lister + lockClusterRoleControllerMockLister.RUnlock() + return calls +} + +var ( + lockClusterRoleInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockClusterRoleInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockClusterRoleInterfaceMockAddClusterScopedHandler sync.RWMutex + lockClusterRoleInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockClusterRoleInterfaceMockAddFeatureHandler sync.RWMutex + lockClusterRoleInterfaceMockAddFeatureLifecycle sync.RWMutex + lockClusterRoleInterfaceMockAddHandler sync.RWMutex + lockClusterRoleInterfaceMockAddLifecycle sync.RWMutex + lockClusterRoleInterfaceMockController sync.RWMutex + lockClusterRoleInterfaceMockCreate sync.RWMutex + lockClusterRoleInterfaceMockDelete sync.RWMutex + lockClusterRoleInterfaceMockDeleteCollection sync.RWMutex + lockClusterRoleInterfaceMockDeleteNamespaced sync.RWMutex + lockClusterRoleInterfaceMockGet sync.RWMutex + lockClusterRoleInterfaceMockGetNamespaced sync.RWMutex + lockClusterRoleInterfaceMockList sync.RWMutex + lockClusterRoleInterfaceMockListNamespaced sync.RWMutex + lockClusterRoleInterfaceMockObjectClient sync.RWMutex + lockClusterRoleInterfaceMockUpdate sync.RWMutex + lockClusterRoleInterfaceMockWatch sync.RWMutex +) + +// Ensure, that ClusterRoleInterfaceMock does implement v11.ClusterRoleInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRoleInterface = &ClusterRoleInterfaceMock{} + +// ClusterRoleInterfaceMock is a mock implementation of v11.ClusterRoleInterface. +// +// func TestSomethingThatUsesClusterRoleInterface(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRoleInterface +// mockedClusterRoleInterface := &ClusterRoleInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.ClusterRoleLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.ClusterRoleController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.ClusterRoleList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedClusterRoleInterface in code that requires v11.ClusterRoleInterface +// // and then make assertions. +// +// } +type ClusterRoleInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.ClusterRoleHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.ClusterRoleLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.ClusterRoleController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRole, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.ClusterRoleList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.ClusterRole) (*v1.ClusterRole, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ClusterRoleHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.ClusterRoleHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.ClusterRoleHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.ClusterRoleLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.ClusterRole + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.ClusterRole + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *ClusterRoleInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("ClusterRoleInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but ClusterRoleInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockClusterRoleInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *ClusterRoleInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc + } + lockClusterRoleInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockClusterRoleInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *ClusterRoleInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("ClusterRoleInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but ClusterRoleInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockClusterRoleInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *ClusterRoleInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle + } + lockClusterRoleInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockClusterRoleInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *ClusterRoleInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.ClusterRoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("ClusterRoleInterfaceMock.AddClusterScopedHandlerFunc: method is nil but ClusterRoleInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockClusterRoleInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockClusterRoleInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddClusterScopedHandlerCalls()) +func (mock *ClusterRoleInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.ClusterRoleHandlerFunc + } + lockClusterRoleInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockClusterRoleInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *ClusterRoleInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.ClusterRoleLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("ClusterRoleInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but ClusterRoleInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockClusterRoleInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockClusterRoleInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddClusterScopedLifecycleCalls()) +func (mock *ClusterRoleInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.ClusterRoleLifecycle + } + lockClusterRoleInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockClusterRoleInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *ClusterRoleInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("ClusterRoleInterfaceMock.AddFeatureHandlerFunc: method is nil but ClusterRoleInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockClusterRoleInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddFeatureHandlerCalls()) +func (mock *ClusterRoleInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.ClusterRoleHandlerFunc + } + lockClusterRoleInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockClusterRoleInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *ClusterRoleInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.ClusterRoleLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("ClusterRoleInterfaceMock.AddFeatureLifecycleFunc: method is nil but ClusterRoleInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockClusterRoleInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddFeatureLifecycleCalls()) +func (mock *ClusterRoleInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.ClusterRoleLifecycle + } + lockClusterRoleInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockClusterRoleInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *ClusterRoleInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.ClusterRoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("ClusterRoleInterfaceMock.AddHandlerFunc: method is nil but ClusterRoleInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockClusterRoleInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockClusterRoleInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddHandlerCalls()) +func (mock *ClusterRoleInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.ClusterRoleHandlerFunc + } + lockClusterRoleInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockClusterRoleInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *ClusterRoleInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.ClusterRoleLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("ClusterRoleInterfaceMock.AddLifecycleFunc: method is nil but ClusterRoleInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockClusterRoleInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockClusterRoleInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedClusterRoleInterface.AddLifecycleCalls()) +func (mock *ClusterRoleInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.ClusterRoleLifecycle + } + lockClusterRoleInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockClusterRoleInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *ClusterRoleInterfaceMock) Controller() v11.ClusterRoleController { + if mock.ControllerFunc == nil { + panic("ClusterRoleInterfaceMock.ControllerFunc: method is nil but ClusterRoleInterface.Controller was just called") + } + callInfo := struct { + }{} + lockClusterRoleInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockClusterRoleInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedClusterRoleInterface.ControllerCalls()) +func (mock *ClusterRoleInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleInterfaceMockController.RLock() + calls = mock.calls.Controller + lockClusterRoleInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *ClusterRoleInterfaceMock) Create(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { + if mock.CreateFunc == nil { + panic("ClusterRoleInterfaceMock.CreateFunc: method is nil but ClusterRoleInterface.Create was just called") + } + callInfo := struct { + In1 *v1.ClusterRole + }{ + In1: in1, + } + lockClusterRoleInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockClusterRoleInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedClusterRoleInterface.CreateCalls()) +func (mock *ClusterRoleInterfaceMock) CreateCalls() []struct { + In1 *v1.ClusterRole +} { + var calls []struct { + In1 *v1.ClusterRole + } + lockClusterRoleInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockClusterRoleInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *ClusterRoleInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("ClusterRoleInterfaceMock.DeleteFunc: method is nil but ClusterRoleInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockClusterRoleInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockClusterRoleInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedClusterRoleInterface.DeleteCalls()) +func (mock *ClusterRoleInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockClusterRoleInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *ClusterRoleInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("ClusterRoleInterfaceMock.DeleteCollectionFunc: method is nil but ClusterRoleInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockClusterRoleInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockClusterRoleInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedClusterRoleInterface.DeleteCollectionCalls()) +func (mock *ClusterRoleInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockClusterRoleInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockClusterRoleInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *ClusterRoleInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("ClusterRoleInterfaceMock.DeleteNamespacedFunc: method is nil but ClusterRoleInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockClusterRoleInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockClusterRoleInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedClusterRoleInterface.DeleteNamespacedCalls()) +func (mock *ClusterRoleInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockClusterRoleInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockClusterRoleInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *ClusterRoleInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { + if mock.GetFunc == nil { + panic("ClusterRoleInterfaceMock.GetFunc: method is nil but ClusterRoleInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockClusterRoleInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockClusterRoleInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedClusterRoleInterface.GetCalls()) +func (mock *ClusterRoleInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockClusterRoleInterfaceMockGet.RLock() + calls = mock.calls.Get + lockClusterRoleInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *ClusterRoleInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { + if mock.GetNamespacedFunc == nil { + panic("ClusterRoleInterfaceMock.GetNamespacedFunc: method is nil but ClusterRoleInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockClusterRoleInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockClusterRoleInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedClusterRoleInterface.GetNamespacedCalls()) +func (mock *ClusterRoleInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockClusterRoleInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockClusterRoleInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *ClusterRoleInterfaceMock) List(opts metav1.ListOptions) (*v1.ClusterRoleList, error) { + if mock.ListFunc == nil { + panic("ClusterRoleInterfaceMock.ListFunc: method is nil but ClusterRoleInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockClusterRoleInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedClusterRoleInterface.ListCalls()) +func (mock *ClusterRoleInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleInterfaceMockList.RLock() + calls = mock.calls.List + lockClusterRoleInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *ClusterRoleInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleList, error) { + if mock.ListNamespacedFunc == nil { + panic("ClusterRoleInterfaceMock.ListNamespacedFunc: method is nil but ClusterRoleInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockClusterRoleInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockClusterRoleInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedClusterRoleInterface.ListNamespacedCalls()) +func (mock *ClusterRoleInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockClusterRoleInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockClusterRoleInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *ClusterRoleInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("ClusterRoleInterfaceMock.ObjectClientFunc: method is nil but ClusterRoleInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockClusterRoleInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockClusterRoleInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedClusterRoleInterface.ObjectClientCalls()) +func (mock *ClusterRoleInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockClusterRoleInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockClusterRoleInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *ClusterRoleInterfaceMock) Update(in1 *v1.ClusterRole) (*v1.ClusterRole, error) { + if mock.UpdateFunc == nil { + panic("ClusterRoleInterfaceMock.UpdateFunc: method is nil but ClusterRoleInterface.Update was just called") + } + callInfo := struct { + In1 *v1.ClusterRole + }{ + In1: in1, + } + lockClusterRoleInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockClusterRoleInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedClusterRoleInterface.UpdateCalls()) +func (mock *ClusterRoleInterfaceMock) UpdateCalls() []struct { + In1 *v1.ClusterRole +} { + var calls []struct { + In1 *v1.ClusterRole + } + lockClusterRoleInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockClusterRoleInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *ClusterRoleInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("ClusterRoleInterfaceMock.WatchFunc: method is nil but ClusterRoleInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockClusterRoleInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockClusterRoleInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedClusterRoleInterface.WatchCalls()) +func (mock *ClusterRoleInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockClusterRoleInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockClusterRoleInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockClusterRolesGetterMockClusterRoles sync.RWMutex +) + +// Ensure, that ClusterRolesGetterMock does implement v11.ClusterRolesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.ClusterRolesGetter = &ClusterRolesGetterMock{} + +// ClusterRolesGetterMock is a mock implementation of v11.ClusterRolesGetter. +// +// func TestSomethingThatUsesClusterRolesGetter(t *testing.T) { +// +// // make and configure a mocked v11.ClusterRolesGetter +// mockedClusterRolesGetter := &ClusterRolesGetterMock{ +// ClusterRolesFunc: func(namespace string) v11.ClusterRoleInterface { +// panic("mock out the ClusterRoles method") +// }, +// } +// +// // use mockedClusterRolesGetter in code that requires v11.ClusterRolesGetter +// // and then make assertions. +// +// } +type ClusterRolesGetterMock struct { + // ClusterRolesFunc mocks the ClusterRoles method. + ClusterRolesFunc func(namespace string) v11.ClusterRoleInterface + + // calls tracks calls to the methods. + calls struct { + // ClusterRoles holds details about calls to the ClusterRoles method. + ClusterRoles []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// ClusterRoles calls ClusterRolesFunc. +func (mock *ClusterRolesGetterMock) ClusterRoles(namespace string) v11.ClusterRoleInterface { + if mock.ClusterRolesFunc == nil { + panic("ClusterRolesGetterMock.ClusterRolesFunc: method is nil but ClusterRolesGetter.ClusterRoles was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockClusterRolesGetterMockClusterRoles.Lock() + mock.calls.ClusterRoles = append(mock.calls.ClusterRoles, callInfo) + lockClusterRolesGetterMockClusterRoles.Unlock() + return mock.ClusterRolesFunc(namespace) +} + +// ClusterRolesCalls gets all the calls that were made to ClusterRoles. +// Check the length with: +// +// len(mockedClusterRolesGetter.ClusterRolesCalls()) +func (mock *ClusterRolesGetterMock) ClusterRolesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockClusterRolesGetterMockClusterRoles.RLock() + calls = mock.calls.ClusterRoles + lockClusterRolesGetterMockClusterRoles.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_binding_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_binding_mock.go new file mode 100644 index 0000000..2a5b322 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_binding_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRoleBindingListerMockGet sync.RWMutex + lockRoleBindingListerMockList sync.RWMutex +) + +// Ensure, that RoleBindingListerMock does implement v11.RoleBindingLister. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleBindingLister = &RoleBindingListerMock{} + +// RoleBindingListerMock is a mock implementation of v11.RoleBindingLister. +// +// func TestSomethingThatUsesRoleBindingLister(t *testing.T) { +// +// // make and configure a mocked v11.RoleBindingLister +// mockedRoleBindingLister := &RoleBindingListerMock{ +// GetFunc: func(namespace string, name string) (*v1.RoleBinding, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.RoleBinding, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRoleBindingLister in code that requires v11.RoleBindingLister +// // and then make assertions. +// +// } +type RoleBindingListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.RoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.RoleBinding, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RoleBindingListerMock) Get(namespace string, name string) (*v1.RoleBinding, error) { + if mock.GetFunc == nil { + panic("RoleBindingListerMock.GetFunc: method is nil but RoleBindingLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleBindingListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleBindingListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleBindingLister.GetCalls()) +func (mock *RoleBindingListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleBindingListerMockGet.RLock() + calls = mock.calls.Get + lockRoleBindingListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleBindingListerMock) List(namespace string, selector labels.Selector) ([]*v1.RoleBinding, error) { + if mock.ListFunc == nil { + panic("RoleBindingListerMock.ListFunc: method is nil but RoleBindingLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRoleBindingListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleBindingListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleBindingLister.ListCalls()) +func (mock *RoleBindingListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRoleBindingListerMockList.RLock() + calls = mock.calls.List + lockRoleBindingListerMockList.RUnlock() + return calls +} + +var ( + lockRoleBindingControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleBindingControllerMockAddClusterScopedHandler sync.RWMutex + lockRoleBindingControllerMockAddFeatureHandler sync.RWMutex + lockRoleBindingControllerMockAddHandler sync.RWMutex + lockRoleBindingControllerMockEnqueue sync.RWMutex + lockRoleBindingControllerMockEnqueueAfter sync.RWMutex + lockRoleBindingControllerMockGeneric sync.RWMutex + lockRoleBindingControllerMockInformer sync.RWMutex + lockRoleBindingControllerMockLister sync.RWMutex +) + +// Ensure, that RoleBindingControllerMock does implement v11.RoleBindingController. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleBindingController = &RoleBindingControllerMock{} + +// RoleBindingControllerMock is a mock implementation of v11.RoleBindingController. +// +// func TestSomethingThatUsesRoleBindingController(t *testing.T) { +// +// // make and configure a mocked v11.RoleBindingController +// mockedRoleBindingController := &RoleBindingControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.RoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.RoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.RoleBindingLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRoleBindingController in code that requires v11.RoleBindingController +// // and then make assertions. +// +// } +type RoleBindingControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleBindingHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.RoleBindingHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.RoleBindingHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.RoleBindingLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.RoleBindingHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.RoleBindingHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleBindingHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.RoleBindingHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleBindingControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleBindingControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleBindingController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleBindingControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleBindingControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleBindingController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleBindingControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc + } + lockRoleBindingControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleBindingControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleBindingControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.RoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleBindingControllerMock.AddClusterScopedHandlerFunc: method is nil but RoleBindingController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleBindingControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleBindingControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleBindingController.AddClusterScopedHandlerCalls()) +func (mock *RoleBindingControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleBindingHandlerFunc + } + lockRoleBindingControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleBindingControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleBindingControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleBindingControllerMock.AddFeatureHandlerFunc: method is nil but RoleBindingController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleBindingControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleBindingControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleBindingController.AddFeatureHandlerCalls()) +func (mock *RoleBindingControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc + } + lockRoleBindingControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleBindingControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleBindingControllerMock) AddHandler(ctx context.Context, name string, handler v11.RoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleBindingControllerMock.AddHandlerFunc: method is nil but RoleBindingController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRoleBindingControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleBindingControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleBindingController.AddHandlerCalls()) +func (mock *RoleBindingControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.RoleBindingHandlerFunc + } + lockRoleBindingControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleBindingControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RoleBindingControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RoleBindingControllerMock.EnqueueFunc: method is nil but RoleBindingController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleBindingControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRoleBindingControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRoleBindingController.EnqueueCalls()) +func (mock *RoleBindingControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleBindingControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRoleBindingControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RoleBindingControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RoleBindingControllerMock.EnqueueAfterFunc: method is nil but RoleBindingController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRoleBindingControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRoleBindingControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRoleBindingController.EnqueueAfterCalls()) +func (mock *RoleBindingControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRoleBindingControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRoleBindingControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RoleBindingControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RoleBindingControllerMock.GenericFunc: method is nil but RoleBindingController.Generic was just called") + } + callInfo := struct { + }{} + lockRoleBindingControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRoleBindingControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRoleBindingController.GenericCalls()) +func (mock *RoleBindingControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRoleBindingControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRoleBindingControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RoleBindingControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RoleBindingControllerMock.InformerFunc: method is nil but RoleBindingController.Informer was just called") + } + callInfo := struct { + }{} + lockRoleBindingControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRoleBindingControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRoleBindingController.InformerCalls()) +func (mock *RoleBindingControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRoleBindingControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRoleBindingControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RoleBindingControllerMock) Lister() v11.RoleBindingLister { + if mock.ListerFunc == nil { + panic("RoleBindingControllerMock.ListerFunc: method is nil but RoleBindingController.Lister was just called") + } + callInfo := struct { + }{} + lockRoleBindingControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRoleBindingControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRoleBindingController.ListerCalls()) +func (mock *RoleBindingControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRoleBindingControllerMockLister.RLock() + calls = mock.calls.Lister + lockRoleBindingControllerMockLister.RUnlock() + return calls +} + +var ( + lockRoleBindingInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRoleBindingInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRoleBindingInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRoleBindingInterfaceMockAddFeatureHandler sync.RWMutex + lockRoleBindingInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRoleBindingInterfaceMockAddHandler sync.RWMutex + lockRoleBindingInterfaceMockAddLifecycle sync.RWMutex + lockRoleBindingInterfaceMockController sync.RWMutex + lockRoleBindingInterfaceMockCreate sync.RWMutex + lockRoleBindingInterfaceMockDelete sync.RWMutex + lockRoleBindingInterfaceMockDeleteCollection sync.RWMutex + lockRoleBindingInterfaceMockDeleteNamespaced sync.RWMutex + lockRoleBindingInterfaceMockGet sync.RWMutex + lockRoleBindingInterfaceMockGetNamespaced sync.RWMutex + lockRoleBindingInterfaceMockList sync.RWMutex + lockRoleBindingInterfaceMockListNamespaced sync.RWMutex + lockRoleBindingInterfaceMockObjectClient sync.RWMutex + lockRoleBindingInterfaceMockUpdate sync.RWMutex + lockRoleBindingInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RoleBindingInterfaceMock does implement v11.RoleBindingInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleBindingInterface = &RoleBindingInterfaceMock{} + +// RoleBindingInterfaceMock is a mock implementation of v11.RoleBindingInterface. +// +// func TestSomethingThatUsesRoleBindingInterface(t *testing.T) { +// +// // make and configure a mocked v11.RoleBindingInterface +// mockedRoleBindingInterface := &RoleBindingInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleBindingLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.RoleBindingHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.RoleBindingLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.RoleBindingController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.RoleBinding) (*v1.RoleBinding, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.RoleBindingList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.RoleBindingList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.RoleBinding) (*v1.RoleBinding, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRoleBindingInterface in code that requires v11.RoleBindingInterface +// // and then make assertions. +// +// } +type RoleBindingInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleBindingLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.RoleBindingHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.RoleBindingLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.RoleBindingController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.RoleBinding) (*v1.RoleBinding, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.RoleBinding, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.RoleBinding, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.RoleBindingList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.RoleBindingList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.RoleBinding) (*v1.RoleBinding, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.RoleBindingHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleBindingLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.RoleBindingHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleBindingLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleBindingHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleBindingLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleBindingHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleBindingLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.RoleBinding + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.RoleBinding + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleBindingInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleBindingInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleBindingInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleBindingInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleBindingInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc + } + lockRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleBindingInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RoleBindingInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RoleBindingInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RoleBindingInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RoleBindingInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle + } + lockRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRoleBindingInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleBindingInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleBindingHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleBindingInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RoleBindingInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleBindingInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleBindingInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddClusterScopedHandlerCalls()) +func (mock *RoleBindingInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleBindingHandlerFunc + } + lockRoleBindingInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleBindingInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RoleBindingInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.RoleBindingLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RoleBindingInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RoleBindingInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleBindingInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRoleBindingInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddClusterScopedLifecycleCalls()) +func (mock *RoleBindingInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleBindingLifecycle + } + lockRoleBindingInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRoleBindingInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleBindingInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleBindingHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleBindingInterfaceMock.AddFeatureHandlerFunc: method is nil but RoleBindingInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleBindingInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleBindingInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddFeatureHandlerCalls()) +func (mock *RoleBindingInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleBindingHandlerFunc + } + lockRoleBindingInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleBindingInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RoleBindingInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleBindingLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RoleBindingInterfaceMock.AddFeatureLifecycleFunc: method is nil but RoleBindingInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleBindingLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRoleBindingInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRoleBindingInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddFeatureLifecycleCalls()) +func (mock *RoleBindingInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleBindingLifecycle + } + lockRoleBindingInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRoleBindingInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleBindingInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.RoleBindingHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleBindingInterfaceMock.AddHandlerFunc: method is nil but RoleBindingInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.RoleBindingHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRoleBindingInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleBindingInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddHandlerCalls()) +func (mock *RoleBindingInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.RoleBindingHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.RoleBindingHandlerFunc + } + lockRoleBindingInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleBindingInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RoleBindingInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.RoleBindingLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RoleBindingInterfaceMock.AddLifecycleFunc: method is nil but RoleBindingInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.RoleBindingLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRoleBindingInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRoleBindingInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRoleBindingInterface.AddLifecycleCalls()) +func (mock *RoleBindingInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.RoleBindingLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.RoleBindingLifecycle + } + lockRoleBindingInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRoleBindingInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RoleBindingInterfaceMock) Controller() v11.RoleBindingController { + if mock.ControllerFunc == nil { + panic("RoleBindingInterfaceMock.ControllerFunc: method is nil but RoleBindingInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRoleBindingInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRoleBindingInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRoleBindingInterface.ControllerCalls()) +func (mock *RoleBindingInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRoleBindingInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRoleBindingInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RoleBindingInterfaceMock) Create(in1 *v1.RoleBinding) (*v1.RoleBinding, error) { + if mock.CreateFunc == nil { + panic("RoleBindingInterfaceMock.CreateFunc: method is nil but RoleBindingInterface.Create was just called") + } + callInfo := struct { + In1 *v1.RoleBinding + }{ + In1: in1, + } + lockRoleBindingInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRoleBindingInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRoleBindingInterface.CreateCalls()) +func (mock *RoleBindingInterfaceMock) CreateCalls() []struct { + In1 *v1.RoleBinding +} { + var calls []struct { + In1 *v1.RoleBinding + } + lockRoleBindingInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRoleBindingInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RoleBindingInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RoleBindingInterfaceMock.DeleteFunc: method is nil but RoleBindingInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRoleBindingInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRoleBindingInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRoleBindingInterface.DeleteCalls()) +func (mock *RoleBindingInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRoleBindingInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRoleBindingInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RoleBindingInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RoleBindingInterfaceMock.DeleteCollectionFunc: method is nil but RoleBindingInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRoleBindingInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRoleBindingInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRoleBindingInterface.DeleteCollectionCalls()) +func (mock *RoleBindingInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRoleBindingInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRoleBindingInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RoleBindingInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RoleBindingInterfaceMock.DeleteNamespacedFunc: method is nil but RoleBindingInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRoleBindingInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRoleBindingInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRoleBindingInterface.DeleteNamespacedCalls()) +func (mock *RoleBindingInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRoleBindingInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRoleBindingInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RoleBindingInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { + if mock.GetFunc == nil { + panic("RoleBindingInterfaceMock.GetFunc: method is nil but RoleBindingInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRoleBindingInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleBindingInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleBindingInterface.GetCalls()) +func (mock *RoleBindingInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRoleBindingInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRoleBindingInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RoleBindingInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { + if mock.GetNamespacedFunc == nil { + panic("RoleBindingInterfaceMock.GetNamespacedFunc: method is nil but RoleBindingInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRoleBindingInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRoleBindingInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRoleBindingInterface.GetNamespacedCalls()) +func (mock *RoleBindingInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRoleBindingInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRoleBindingInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleBindingInterfaceMock) List(opts metav1.ListOptions) (*v1.RoleBindingList, error) { + if mock.ListFunc == nil { + panic("RoleBindingInterfaceMock.ListFunc: method is nil but RoleBindingInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleBindingInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleBindingInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleBindingInterface.ListCalls()) +func (mock *RoleBindingInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleBindingInterfaceMockList.RLock() + calls = mock.calls.List + lockRoleBindingInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RoleBindingInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleBindingList, error) { + if mock.ListNamespacedFunc == nil { + panic("RoleBindingInterfaceMock.ListNamespacedFunc: method is nil but RoleBindingInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRoleBindingInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRoleBindingInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRoleBindingInterface.ListNamespacedCalls()) +func (mock *RoleBindingInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRoleBindingInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRoleBindingInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RoleBindingInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RoleBindingInterfaceMock.ObjectClientFunc: method is nil but RoleBindingInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRoleBindingInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRoleBindingInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRoleBindingInterface.ObjectClientCalls()) +func (mock *RoleBindingInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRoleBindingInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRoleBindingInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RoleBindingInterfaceMock) Update(in1 *v1.RoleBinding) (*v1.RoleBinding, error) { + if mock.UpdateFunc == nil { + panic("RoleBindingInterfaceMock.UpdateFunc: method is nil but RoleBindingInterface.Update was just called") + } + callInfo := struct { + In1 *v1.RoleBinding + }{ + In1: in1, + } + lockRoleBindingInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRoleBindingInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRoleBindingInterface.UpdateCalls()) +func (mock *RoleBindingInterfaceMock) UpdateCalls() []struct { + In1 *v1.RoleBinding +} { + var calls []struct { + In1 *v1.RoleBinding + } + lockRoleBindingInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRoleBindingInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RoleBindingInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RoleBindingInterfaceMock.WatchFunc: method is nil but RoleBindingInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleBindingInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRoleBindingInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRoleBindingInterface.WatchCalls()) +func (mock *RoleBindingInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleBindingInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRoleBindingInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRoleBindingsGetterMockRoleBindings sync.RWMutex +) + +// Ensure, that RoleBindingsGetterMock does implement v11.RoleBindingsGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleBindingsGetter = &RoleBindingsGetterMock{} + +// RoleBindingsGetterMock is a mock implementation of v11.RoleBindingsGetter. +// +// func TestSomethingThatUsesRoleBindingsGetter(t *testing.T) { +// +// // make and configure a mocked v11.RoleBindingsGetter +// mockedRoleBindingsGetter := &RoleBindingsGetterMock{ +// RoleBindingsFunc: func(namespace string) v11.RoleBindingInterface { +// panic("mock out the RoleBindings method") +// }, +// } +// +// // use mockedRoleBindingsGetter in code that requires v11.RoleBindingsGetter +// // and then make assertions. +// +// } +type RoleBindingsGetterMock struct { + // RoleBindingsFunc mocks the RoleBindings method. + RoleBindingsFunc func(namespace string) v11.RoleBindingInterface + + // calls tracks calls to the methods. + calls struct { + // RoleBindings holds details about calls to the RoleBindings method. + RoleBindings []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// RoleBindings calls RoleBindingsFunc. +func (mock *RoleBindingsGetterMock) RoleBindings(namespace string) v11.RoleBindingInterface { + if mock.RoleBindingsFunc == nil { + panic("RoleBindingsGetterMock.RoleBindingsFunc: method is nil but RoleBindingsGetter.RoleBindings was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRoleBindingsGetterMockRoleBindings.Lock() + mock.calls.RoleBindings = append(mock.calls.RoleBindings, callInfo) + lockRoleBindingsGetterMockRoleBindings.Unlock() + return mock.RoleBindingsFunc(namespace) +} + +// RoleBindingsCalls gets all the calls that were made to RoleBindings. +// Check the length with: +// +// len(mockedRoleBindingsGetter.RoleBindingsCalls()) +func (mock *RoleBindingsGetterMock) RoleBindingsCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRoleBindingsGetterMockRoleBindings.RLock() + calls = mock.calls.RoleBindings + lockRoleBindingsGetterMockRoleBindings.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_mock.go new file mode 100644 index 0000000..8aba75a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/fakes/zz_generated_role_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + v1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockRoleListerMockGet sync.RWMutex + lockRoleListerMockList sync.RWMutex +) + +// Ensure, that RoleListerMock does implement v11.RoleLister. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleLister = &RoleListerMock{} + +// RoleListerMock is a mock implementation of v11.RoleLister. +// +// func TestSomethingThatUsesRoleLister(t *testing.T) { +// +// // make and configure a mocked v11.RoleLister +// mockedRoleLister := &RoleListerMock{ +// GetFunc: func(namespace string, name string) (*v1.Role, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.Role, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedRoleLister in code that requires v11.RoleLister +// // and then make assertions. +// +// } +type RoleListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.Role, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.Role, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *RoleListerMock) Get(namespace string, name string) (*v1.Role, error) { + if mock.GetFunc == nil { + panic("RoleListerMock.GetFunc: method is nil but RoleLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleLister.GetCalls()) +func (mock *RoleListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleListerMockGet.RLock() + calls = mock.calls.Get + lockRoleListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleListerMock) List(namespace string, selector labels.Selector) ([]*v1.Role, error) { + if mock.ListFunc == nil { + panic("RoleListerMock.ListFunc: method is nil but RoleLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockRoleListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleLister.ListCalls()) +func (mock *RoleListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockRoleListerMockList.RLock() + calls = mock.calls.List + lockRoleListerMockList.RUnlock() + return calls +} + +var ( + lockRoleControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleControllerMockAddClusterScopedHandler sync.RWMutex + lockRoleControllerMockAddFeatureHandler sync.RWMutex + lockRoleControllerMockAddHandler sync.RWMutex + lockRoleControllerMockEnqueue sync.RWMutex + lockRoleControllerMockEnqueueAfter sync.RWMutex + lockRoleControllerMockGeneric sync.RWMutex + lockRoleControllerMockInformer sync.RWMutex + lockRoleControllerMockLister sync.RWMutex +) + +// Ensure, that RoleControllerMock does implement v11.RoleController. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleController = &RoleControllerMock{} + +// RoleControllerMock is a mock implementation of v11.RoleController. +// +// func TestSomethingThatUsesRoleController(t *testing.T) { +// +// // make and configure a mocked v11.RoleController +// mockedRoleController := &RoleControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.RoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.RoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.RoleLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedRoleController in code that requires v11.RoleController +// // and then make assertions. +// +// } +type RoleControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.RoleHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.RoleHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.RoleLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.RoleHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.RoleHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.RoleHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.RoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleController.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.RoleHandlerFunc + } + lockRoleControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.RoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleControllerMock.AddClusterScopedHandlerFunc: method is nil but RoleController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockRoleControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleController.AddClusterScopedHandlerCalls()) +func (mock *RoleControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.RoleHandlerFunc + } + lockRoleControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleControllerMock.AddFeatureHandlerFunc: method is nil but RoleController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleController.AddFeatureHandlerCalls()) +func (mock *RoleControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc + } + lockRoleControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleControllerMock) AddHandler(ctx context.Context, name string, handler v11.RoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleControllerMock.AddHandlerFunc: method is nil but RoleController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.RoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockRoleControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleController.AddHandlerCalls()) +func (mock *RoleControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.RoleHandlerFunc + } + lockRoleControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *RoleControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("RoleControllerMock.EnqueueFunc: method is nil but RoleController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockRoleControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockRoleControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedRoleController.EnqueueCalls()) +func (mock *RoleControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockRoleControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockRoleControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *RoleControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("RoleControllerMock.EnqueueAfterFunc: method is nil but RoleController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockRoleControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockRoleControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedRoleController.EnqueueAfterCalls()) +func (mock *RoleControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockRoleControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockRoleControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *RoleControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("RoleControllerMock.GenericFunc: method is nil but RoleController.Generic was just called") + } + callInfo := struct { + }{} + lockRoleControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockRoleControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedRoleController.GenericCalls()) +func (mock *RoleControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockRoleControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockRoleControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *RoleControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("RoleControllerMock.InformerFunc: method is nil but RoleController.Informer was just called") + } + callInfo := struct { + }{} + lockRoleControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockRoleControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedRoleController.InformerCalls()) +func (mock *RoleControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockRoleControllerMockInformer.RLock() + calls = mock.calls.Informer + lockRoleControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *RoleControllerMock) Lister() v11.RoleLister { + if mock.ListerFunc == nil { + panic("RoleControllerMock.ListerFunc: method is nil but RoleController.Lister was just called") + } + callInfo := struct { + }{} + lockRoleControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockRoleControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedRoleController.ListerCalls()) +func (mock *RoleControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockRoleControllerMockLister.RLock() + calls = mock.calls.Lister + lockRoleControllerMockLister.RUnlock() + return calls +} + +var ( + lockRoleInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockRoleInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockRoleInterfaceMockAddClusterScopedHandler sync.RWMutex + lockRoleInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockRoleInterfaceMockAddFeatureHandler sync.RWMutex + lockRoleInterfaceMockAddFeatureLifecycle sync.RWMutex + lockRoleInterfaceMockAddHandler sync.RWMutex + lockRoleInterfaceMockAddLifecycle sync.RWMutex + lockRoleInterfaceMockController sync.RWMutex + lockRoleInterfaceMockCreate sync.RWMutex + lockRoleInterfaceMockDelete sync.RWMutex + lockRoleInterfaceMockDeleteCollection sync.RWMutex + lockRoleInterfaceMockDeleteNamespaced sync.RWMutex + lockRoleInterfaceMockGet sync.RWMutex + lockRoleInterfaceMockGetNamespaced sync.RWMutex + lockRoleInterfaceMockList sync.RWMutex + lockRoleInterfaceMockListNamespaced sync.RWMutex + lockRoleInterfaceMockObjectClient sync.RWMutex + lockRoleInterfaceMockUpdate sync.RWMutex + lockRoleInterfaceMockWatch sync.RWMutex +) + +// Ensure, that RoleInterfaceMock does implement v11.RoleInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.RoleInterface = &RoleInterfaceMock{} + +// RoleInterfaceMock is a mock implementation of v11.RoleInterface. +// +// func TestSomethingThatUsesRoleInterface(t *testing.T) { +// +// // make and configure a mocked v11.RoleInterface +// mockedRoleInterface := &RoleInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.RoleLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.RoleHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.RoleLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.RoleController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.Role) (*v1.Role, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.Role, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.Role, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.RoleList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.RoleList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.Role) (*v1.Role, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedRoleInterface in code that requires v11.RoleInterface +// // and then make assertions. +// +// } +type RoleInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.RoleLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.RoleHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.RoleLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.RoleController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.Role) (*v1.Role, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.Role, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.Role, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.RoleList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.RoleList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.Role) (*v1.Role, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.RoleHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.RoleHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.RoleHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.RoleLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.Role + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.Role + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *RoleInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("RoleInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but RoleInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockRoleInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedRoleInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *RoleInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.RoleHandlerFunc + } + lockRoleInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockRoleInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *RoleInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.RoleLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("RoleInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but RoleInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockRoleInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *RoleInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.RoleLifecycle + } + lockRoleInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockRoleInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *RoleInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.RoleHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("RoleInterfaceMock.AddClusterScopedHandlerFunc: method is nil but RoleInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockRoleInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockRoleInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedRoleInterface.AddClusterScopedHandlerCalls()) +func (mock *RoleInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.RoleHandlerFunc + } + lockRoleInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockRoleInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *RoleInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.RoleLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("RoleInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but RoleInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockRoleInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockRoleInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedRoleInterface.AddClusterScopedLifecycleCalls()) +func (mock *RoleInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.RoleLifecycle + } + lockRoleInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockRoleInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *RoleInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.RoleHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("RoleInterfaceMock.AddFeatureHandlerFunc: method is nil but RoleInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockRoleInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockRoleInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedRoleInterface.AddFeatureHandlerCalls()) +func (mock *RoleInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.RoleHandlerFunc + } + lockRoleInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockRoleInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *RoleInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.RoleLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("RoleInterfaceMock.AddFeatureLifecycleFunc: method is nil but RoleInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockRoleInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockRoleInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedRoleInterface.AddFeatureLifecycleCalls()) +func (mock *RoleInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.RoleLifecycle + } + lockRoleInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockRoleInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *RoleInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.RoleHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("RoleInterfaceMock.AddHandlerFunc: method is nil but RoleInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.RoleHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockRoleInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockRoleInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedRoleInterface.AddHandlerCalls()) +func (mock *RoleInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.RoleHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.RoleHandlerFunc + } + lockRoleInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockRoleInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *RoleInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.RoleLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("RoleInterfaceMock.AddLifecycleFunc: method is nil but RoleInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.RoleLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockRoleInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockRoleInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedRoleInterface.AddLifecycleCalls()) +func (mock *RoleInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.RoleLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.RoleLifecycle + } + lockRoleInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockRoleInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *RoleInterfaceMock) Controller() v11.RoleController { + if mock.ControllerFunc == nil { + panic("RoleInterfaceMock.ControllerFunc: method is nil but RoleInterface.Controller was just called") + } + callInfo := struct { + }{} + lockRoleInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockRoleInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedRoleInterface.ControllerCalls()) +func (mock *RoleInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockRoleInterfaceMockController.RLock() + calls = mock.calls.Controller + lockRoleInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *RoleInterfaceMock) Create(in1 *v1.Role) (*v1.Role, error) { + if mock.CreateFunc == nil { + panic("RoleInterfaceMock.CreateFunc: method is nil but RoleInterface.Create was just called") + } + callInfo := struct { + In1 *v1.Role + }{ + In1: in1, + } + lockRoleInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockRoleInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedRoleInterface.CreateCalls()) +func (mock *RoleInterfaceMock) CreateCalls() []struct { + In1 *v1.Role +} { + var calls []struct { + In1 *v1.Role + } + lockRoleInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockRoleInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *RoleInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("RoleInterfaceMock.DeleteFunc: method is nil but RoleInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockRoleInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockRoleInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedRoleInterface.DeleteCalls()) +func (mock *RoleInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockRoleInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockRoleInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *RoleInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("RoleInterfaceMock.DeleteCollectionFunc: method is nil but RoleInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockRoleInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockRoleInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedRoleInterface.DeleteCollectionCalls()) +func (mock *RoleInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockRoleInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockRoleInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *RoleInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("RoleInterfaceMock.DeleteNamespacedFunc: method is nil but RoleInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockRoleInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockRoleInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedRoleInterface.DeleteNamespacedCalls()) +func (mock *RoleInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockRoleInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockRoleInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *RoleInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.Role, error) { + if mock.GetFunc == nil { + panic("RoleInterfaceMock.GetFunc: method is nil but RoleInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockRoleInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockRoleInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedRoleInterface.GetCalls()) +func (mock *RoleInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockRoleInterfaceMockGet.RLock() + calls = mock.calls.Get + lockRoleInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *RoleInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.Role, error) { + if mock.GetNamespacedFunc == nil { + panic("RoleInterfaceMock.GetNamespacedFunc: method is nil but RoleInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockRoleInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockRoleInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedRoleInterface.GetNamespacedCalls()) +func (mock *RoleInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockRoleInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockRoleInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *RoleInterfaceMock) List(opts metav1.ListOptions) (*v1.RoleList, error) { + if mock.ListFunc == nil { + panic("RoleInterfaceMock.ListFunc: method is nil but RoleInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockRoleInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedRoleInterface.ListCalls()) +func (mock *RoleInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleInterfaceMockList.RLock() + calls = mock.calls.List + lockRoleInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *RoleInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleList, error) { + if mock.ListNamespacedFunc == nil { + panic("RoleInterfaceMock.ListNamespacedFunc: method is nil but RoleInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockRoleInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockRoleInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedRoleInterface.ListNamespacedCalls()) +func (mock *RoleInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockRoleInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockRoleInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *RoleInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("RoleInterfaceMock.ObjectClientFunc: method is nil but RoleInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockRoleInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockRoleInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedRoleInterface.ObjectClientCalls()) +func (mock *RoleInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockRoleInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockRoleInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *RoleInterfaceMock) Update(in1 *v1.Role) (*v1.Role, error) { + if mock.UpdateFunc == nil { + panic("RoleInterfaceMock.UpdateFunc: method is nil but RoleInterface.Update was just called") + } + callInfo := struct { + In1 *v1.Role + }{ + In1: in1, + } + lockRoleInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockRoleInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedRoleInterface.UpdateCalls()) +func (mock *RoleInterfaceMock) UpdateCalls() []struct { + In1 *v1.Role +} { + var calls []struct { + In1 *v1.Role + } + lockRoleInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockRoleInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *RoleInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("RoleInterfaceMock.WatchFunc: method is nil but RoleInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockRoleInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockRoleInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedRoleInterface.WatchCalls()) +func (mock *RoleInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockRoleInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockRoleInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockRolesGetterMockRoles sync.RWMutex +) + +// Ensure, that RolesGetterMock does implement v11.RolesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.RolesGetter = &RolesGetterMock{} + +// RolesGetterMock is a mock implementation of v11.RolesGetter. +// +// func TestSomethingThatUsesRolesGetter(t *testing.T) { +// +// // make and configure a mocked v11.RolesGetter +// mockedRolesGetter := &RolesGetterMock{ +// RolesFunc: func(namespace string) v11.RoleInterface { +// panic("mock out the Roles method") +// }, +// } +// +// // use mockedRolesGetter in code that requires v11.RolesGetter +// // and then make assertions. +// +// } +type RolesGetterMock struct { + // RolesFunc mocks the Roles method. + RolesFunc func(namespace string) v11.RoleInterface + + // calls tracks calls to the methods. + calls struct { + // Roles holds details about calls to the Roles method. + Roles []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// Roles calls RolesFunc. +func (mock *RolesGetterMock) Roles(namespace string) v11.RoleInterface { + if mock.RolesFunc == nil { + panic("RolesGetterMock.RolesFunc: method is nil but RolesGetter.Roles was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockRolesGetterMockRoles.Lock() + mock.calls.Roles = append(mock.calls.Roles, callInfo) + lockRolesGetterMockRoles.Unlock() + return mock.RolesFunc(namespace) +} + +// RolesCalls gets all the calls that were made to Roles. +// Check the length with: +// +// len(mockedRolesGetter.RolesCalls()) +func (mock *RolesGetterMock) RolesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockRolesGetterMockRoles.RLock() + calls = mock.calls.Roles + lockRolesGetterMockRoles.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_controller.go new file mode 100644 index 0000000..59e5261 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterRoleBindingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterRoleBinding", + } + ClusterRoleBindingResource = metav1.APIResource{ + Name: "clusterrolebindings", + SingularName: "clusterrolebinding", + Namespaced: false, + Kind: ClusterRoleBindingGroupVersionKind.Kind, + } + + ClusterRoleBindingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusterrolebindings", + } +) + +func init() { + resource.Put(ClusterRoleBindingGroupVersionResource) +} + +// Deprecated: use v1.ClusterRoleBinding instead +type ClusterRoleBinding = v1.ClusterRoleBinding + +func NewClusterRoleBinding(namespace, name string, obj v1.ClusterRoleBinding) *v1.ClusterRoleBinding { + obj.APIVersion, obj.Kind = ClusterRoleBindingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterRoleBindingHandlerFunc func(key string, obj *v1.ClusterRoleBinding) (runtime.Object, error) + +type ClusterRoleBindingChangeHandlerFunc func(obj *v1.ClusterRoleBinding) (runtime.Object, error) + +type ClusterRoleBindingLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ClusterRoleBinding, err error) + Get(namespace, name string) (*v1.ClusterRoleBinding, error) +} + +type ClusterRoleBindingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterRoleBindingLister + AddHandler(ctx context.Context, name string, handler ClusterRoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleBindingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterRoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterRoleBindingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterRoleBindingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) + Get(name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) + Update(*v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterRoleBindingController + AddHandler(ctx context.Context, name string, sync ClusterRoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleBindingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleBindingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleBindingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleBindingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleBindingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleBindingLifecycle) +} + +type clusterRoleBindingLister struct { + ns string + controller *clusterRoleBindingController +} + +func (l *clusterRoleBindingLister) List(namespace string, selector labels.Selector) (ret []*v1.ClusterRoleBinding, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ClusterRoleBinding)) + }) + return +} + +func (l *clusterRoleBindingLister) Get(namespace, name string) (*v1.ClusterRoleBinding, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterRoleBindingGroupVersionKind.Group, + Resource: ClusterRoleBindingGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ClusterRoleBinding), nil +} + +type clusterRoleBindingController struct { + ns string + controller.GenericController +} + +func (c *clusterRoleBindingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterRoleBindingController) Lister() ClusterRoleBindingLister { + return &clusterRoleBindingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterRoleBindingController) AddHandler(ctx context.Context, name string, handler ClusterRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleBindingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleBindingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleBindingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterRoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterRoleBindingFactory struct { +} + +func (c clusterRoleBindingFactory) Object() runtime.Object { + return &v1.ClusterRoleBinding{} +} + +func (c clusterRoleBindingFactory) List() runtime.Object { + return &v1.ClusterRoleBindingList{} +} + +func (s *clusterRoleBindingClient) Controller() ClusterRoleBindingController { + genericController := controller.NewGenericController(s.ns, ClusterRoleBindingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterRoleBindingGroupVersionResource, ClusterRoleBindingGroupVersionKind.Kind, false)) + + return &clusterRoleBindingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterRoleBindingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterRoleBindingController +} + +func (s *clusterRoleBindingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterRoleBindingClient) Create(o *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) Get(name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) Update(o *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) UpdateStatus(o *v1.ClusterRoleBinding) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterRoleBindingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterRoleBindingClient) List(opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ClusterRoleBindingList), err +} + +func (s *clusterRoleBindingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleBindingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ClusterRoleBindingList), err +} + +func (s *clusterRoleBindingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterRoleBindingClient) Patch(o *v1.ClusterRoleBinding, patchType types.PatchType, data []byte, subresources ...string) (*v1.ClusterRoleBinding, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ClusterRoleBinding), err +} + +func (s *clusterRoleBindingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterRoleBindingClient) AddHandler(ctx context.Context, name string, sync ClusterRoleBindingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleBindingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleBindingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleBindingClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleBindingLifecycle) { + sync := NewClusterRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleBindingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleBindingLifecycle) { + sync := NewClusterRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleBindingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleBindingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleBindingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleBindingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterRoleBindingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleBindingLifecycle) { + sync := NewClusterRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleBindingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleBindingLifecycle) { + sync := NewClusterRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_lifecycle_adapter.go new file mode 100644 index 0000000..8575bf7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_binding_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterRoleBindingLifecycle interface { + Create(obj *v1.ClusterRoleBinding) (runtime.Object, error) + Remove(obj *v1.ClusterRoleBinding) (runtime.Object, error) + Updated(obj *v1.ClusterRoleBinding) (runtime.Object, error) +} + +type clusterRoleBindingLifecycleAdapter struct { + lifecycle ClusterRoleBindingLifecycle +} + +func (w *clusterRoleBindingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterRoleBindingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterRoleBindingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ClusterRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleBindingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ClusterRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleBindingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ClusterRoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterRoleBindingLifecycleAdapter(name string, clusterScoped bool, client ClusterRoleBindingInterface, l ClusterRoleBindingLifecycle) ClusterRoleBindingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterRoleBindingGroupVersionResource) + } + adapter := &clusterRoleBindingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ClusterRoleBinding) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_controller.go new file mode 100644 index 0000000..4144fa4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + ClusterRoleGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "ClusterRole", + } + ClusterRoleResource = metav1.APIResource{ + Name: "clusterroles", + SingularName: "clusterrole", + Namespaced: false, + Kind: ClusterRoleGroupVersionKind.Kind, + } + + ClusterRoleGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "clusterroles", + } +) + +func init() { + resource.Put(ClusterRoleGroupVersionResource) +} + +// Deprecated: use v1.ClusterRole instead +type ClusterRole = v1.ClusterRole + +func NewClusterRole(namespace, name string, obj v1.ClusterRole) *v1.ClusterRole { + obj.APIVersion, obj.Kind = ClusterRoleGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type ClusterRoleHandlerFunc func(key string, obj *v1.ClusterRole) (runtime.Object, error) + +type ClusterRoleChangeHandlerFunc func(obj *v1.ClusterRole) (runtime.Object, error) + +type ClusterRoleLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.ClusterRole, err error) + Get(namespace, name string) (*v1.ClusterRole, error) +} + +type ClusterRoleController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() ClusterRoleLister + AddHandler(ctx context.Context, name string, handler ClusterRoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler ClusterRoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler ClusterRoleHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type ClusterRoleInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.ClusterRole) (*v1.ClusterRole, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ClusterRole, error) + Get(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) + Update(*v1.ClusterRole) (*v1.ClusterRole, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.ClusterRoleList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() ClusterRoleController + AddHandler(ctx context.Context, name string, sync ClusterRoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleLifecycle) +} + +type clusterRoleLister struct { + ns string + controller *clusterRoleController +} + +func (l *clusterRoleLister) List(namespace string, selector labels.Selector) (ret []*v1.ClusterRole, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.ClusterRole)) + }) + return +} + +func (l *clusterRoleLister) Get(namespace, name string) (*v1.ClusterRole, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: ClusterRoleGroupVersionKind.Group, + Resource: ClusterRoleGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.ClusterRole), nil +} + +type clusterRoleController struct { + ns string + controller.GenericController +} + +func (c *clusterRoleController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *clusterRoleController) Lister() ClusterRoleLister { + return &clusterRoleLister{ + ns: c.ns, + controller: c, + } +} + +func (c *clusterRoleController) AddHandler(ctx context.Context, name string, handler ClusterRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRole); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler ClusterRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRole); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler ClusterRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRole); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *clusterRoleController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler ClusterRoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.ClusterRole); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type clusterRoleFactory struct { +} + +func (c clusterRoleFactory) Object() runtime.Object { + return &v1.ClusterRole{} +} + +func (c clusterRoleFactory) List() runtime.Object { + return &v1.ClusterRoleList{} +} + +func (s *clusterRoleClient) Controller() ClusterRoleController { + genericController := controller.NewGenericController(s.ns, ClusterRoleGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(ClusterRoleGroupVersionResource, ClusterRoleGroupVersionKind.Kind, false)) + + return &clusterRoleController{ + ns: s.ns, + GenericController: genericController, + } +} + +type clusterRoleClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller ClusterRoleController +} + +func (s *clusterRoleClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *clusterRoleClient) Create(o *v1.ClusterRole) (*v1.ClusterRole, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) Get(name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.ClusterRole, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) Update(o *v1.ClusterRole) (*v1.ClusterRole, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) UpdateStatus(o *v1.ClusterRole) (*v1.ClusterRole, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *clusterRoleClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *clusterRoleClient) List(opts metav1.ListOptions) (*v1.ClusterRoleList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.ClusterRoleList), err +} + +func (s *clusterRoleClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.ClusterRoleList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.ClusterRoleList), err +} + +func (s *clusterRoleClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *clusterRoleClient) Patch(o *v1.ClusterRole, patchType types.PatchType, data []byte, subresources ...string) (*v1.ClusterRole, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.ClusterRole), err +} + +func (s *clusterRoleClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *clusterRoleClient) AddHandler(ctx context.Context, name string, sync ClusterRoleHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync ClusterRoleHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleClient) AddLifecycle(ctx context.Context, name string, lifecycle ClusterRoleLifecycle) { + sync := NewClusterRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *clusterRoleClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle ClusterRoleLifecycle) { + sync := NewClusterRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *clusterRoleClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync ClusterRoleHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync ClusterRoleHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *clusterRoleClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle ClusterRoleLifecycle) { + sync := NewClusterRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *clusterRoleClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle ClusterRoleLifecycle) { + sync := NewClusterRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_lifecycle_adapter.go new file mode 100644 index 0000000..bbfac53 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_cluster_role_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ClusterRoleLifecycle interface { + Create(obj *v1.ClusterRole) (runtime.Object, error) + Remove(obj *v1.ClusterRole) (runtime.Object, error) + Updated(obj *v1.ClusterRole) (runtime.Object, error) +} + +type clusterRoleLifecycleAdapter struct { + lifecycle ClusterRoleLifecycle +} + +func (w *clusterRoleLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *clusterRoleLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *clusterRoleLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.ClusterRole)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.ClusterRole)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *clusterRoleLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.ClusterRole)) + if o == nil { + return nil, err + } + return o, err +} + +func NewClusterRoleLifecycleAdapter(name string, clusterScoped bool, client ClusterRoleInterface, l ClusterRoleLifecycle) ClusterRoleHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(ClusterRoleGroupVersionResource) + } + adapter := &clusterRoleLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.ClusterRole) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..1357533 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_k8s_client.go @@ -0,0 +1,108 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + ClusterRoleBindingsGetter + ClusterRolesGetter + RoleBindingsGetter + RolesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type ClusterRoleBindingsGetter interface { + ClusterRoleBindings(namespace string) ClusterRoleBindingInterface +} + +func (c *Client) ClusterRoleBindings(namespace string) ClusterRoleBindingInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterRoleBindingGroupVersionResource, ClusterRoleBindingGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterRoleBindingResource, ClusterRoleBindingGroupVersionKind, clusterRoleBindingFactory{}) + return &clusterRoleBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type ClusterRolesGetter interface { + ClusterRoles(namespace string) ClusterRoleInterface +} + +func (c *Client) ClusterRoles(namespace string) ClusterRoleInterface { + sharedClient := c.clientFactory.ForResourceKind(ClusterRoleGroupVersionResource, ClusterRoleGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &ClusterRoleResource, ClusterRoleGroupVersionKind, clusterRoleFactory{}) + return &clusterRoleClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RoleBindingsGetter interface { + RoleBindings(namespace string) RoleBindingInterface +} + +func (c *Client) RoleBindings(namespace string) RoleBindingInterface { + sharedClient := c.clientFactory.ForResourceKind(RoleBindingGroupVersionResource, RoleBindingGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RoleBindingResource, RoleBindingGroupVersionKind, roleBindingFactory{}) + return &roleBindingClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} + +type RolesGetter interface { + Roles(namespace string) RoleInterface +} + +func (c *Client) Roles(namespace string) RoleInterface { + sharedClient := c.clientFactory.ForResourceKind(RoleGroupVersionResource, RoleGroupVersionKind.Kind, true) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &RoleResource, RoleGroupVersionKind, roleFactory{}) + return &roleClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_controller.go new file mode 100644 index 0000000..6d028ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RoleBindingGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "RoleBinding", + } + RoleBindingResource = metav1.APIResource{ + Name: "rolebindings", + SingularName: "rolebinding", + Namespaced: true, + + Kind: RoleBindingGroupVersionKind.Kind, + } + + RoleBindingGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "rolebindings", + } +) + +func init() { + resource.Put(RoleBindingGroupVersionResource) +} + +// Deprecated: use v1.RoleBinding instead +type RoleBinding = v1.RoleBinding + +func NewRoleBinding(namespace, name string, obj v1.RoleBinding) *v1.RoleBinding { + obj.APIVersion, obj.Kind = RoleBindingGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RoleBindingHandlerFunc func(key string, obj *v1.RoleBinding) (runtime.Object, error) + +type RoleBindingChangeHandlerFunc func(obj *v1.RoleBinding) (runtime.Object, error) + +type RoleBindingLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.RoleBinding, err error) + Get(namespace, name string) (*v1.RoleBinding, error) +} + +type RoleBindingController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RoleBindingLister + AddHandler(ctx context.Context, name string, handler RoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleBindingHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RoleBindingHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RoleBindingInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.RoleBinding) (*v1.RoleBinding, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.RoleBinding, error) + Get(name string, opts metav1.GetOptions) (*v1.RoleBinding, error) + Update(*v1.RoleBinding) (*v1.RoleBinding, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.RoleBindingList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleBindingList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RoleBindingController + AddHandler(ctx context.Context, name string, sync RoleBindingHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleBindingHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RoleBindingLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleBindingLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleBindingHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleBindingHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleBindingLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleBindingLifecycle) +} + +type roleBindingLister struct { + ns string + controller *roleBindingController +} + +func (l *roleBindingLister) List(namespace string, selector labels.Selector) (ret []*v1.RoleBinding, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.RoleBinding)) + }) + return +} + +func (l *roleBindingLister) Get(namespace, name string) (*v1.RoleBinding, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RoleBindingGroupVersionKind.Group, + Resource: RoleBindingGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.RoleBinding), nil +} + +type roleBindingController struct { + ns string + controller.GenericController +} + +func (c *roleBindingController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *roleBindingController) Lister() RoleBindingLister { + return &roleBindingLister{ + ns: c.ns, + controller: c, + } +} + +func (c *roleBindingController) AddHandler(ctx context.Context, name string, handler RoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.RoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleBindingController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.RoleBinding); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleBindingController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.RoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleBindingController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RoleBindingHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.RoleBinding); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type roleBindingFactory struct { +} + +func (c roleBindingFactory) Object() runtime.Object { + return &v1.RoleBinding{} +} + +func (c roleBindingFactory) List() runtime.Object { + return &v1.RoleBindingList{} +} + +func (s *roleBindingClient) Controller() RoleBindingController { + genericController := controller.NewGenericController(s.ns, RoleBindingGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RoleBindingGroupVersionResource, RoleBindingGroupVersionKind.Kind, true)) + + return &roleBindingController{ + ns: s.ns, + GenericController: genericController, + } +} + +type roleBindingClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RoleBindingController +} + +func (s *roleBindingClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *roleBindingClient) Create(o *v1.RoleBinding) (*v1.RoleBinding, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) Get(name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.RoleBinding, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) Update(o *v1.RoleBinding) (*v1.RoleBinding, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) UpdateStatus(o *v1.RoleBinding) (*v1.RoleBinding, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *roleBindingClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *roleBindingClient) List(opts metav1.ListOptions) (*v1.RoleBindingList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.RoleBindingList), err +} + +func (s *roleBindingClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleBindingList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.RoleBindingList), err +} + +func (s *roleBindingClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *roleBindingClient) Patch(o *v1.RoleBinding, patchType types.PatchType, data []byte, subresources ...string) (*v1.RoleBinding, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.RoleBinding), err +} + +func (s *roleBindingClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *roleBindingClient) AddHandler(ctx context.Context, name string, sync RoleBindingHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleBindingClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleBindingHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleBindingClient) AddLifecycle(ctx context.Context, name string, lifecycle RoleBindingLifecycle) { + sync := NewRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleBindingClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleBindingLifecycle) { + sync := NewRoleBindingLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleBindingClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleBindingHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleBindingClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleBindingHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *roleBindingClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleBindingLifecycle) { + sync := NewRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleBindingClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleBindingLifecycle) { + sync := NewRoleBindingLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_lifecycle_adapter.go new file mode 100644 index 0000000..e7bbba4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_binding_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type RoleBindingLifecycle interface { + Create(obj *v1.RoleBinding) (runtime.Object, error) + Remove(obj *v1.RoleBinding) (runtime.Object, error) + Updated(obj *v1.RoleBinding) (runtime.Object, error) +} + +type roleBindingLifecycleAdapter struct { + lifecycle RoleBindingLifecycle +} + +func (w *roleBindingLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *roleBindingLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *roleBindingLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.RoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleBindingLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.RoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleBindingLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.RoleBinding)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRoleBindingLifecycleAdapter(name string, clusterScoped bool, client RoleBindingInterface, l RoleBindingLifecycle) RoleBindingHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RoleBindingGroupVersionResource) + } + adapter := &roleBindingLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.RoleBinding) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_controller.go new file mode 100644 index 0000000..aa6d369 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_controller.go @@ -0,0 +1,326 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + RoleGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "Role", + } + RoleResource = metav1.APIResource{ + Name: "roles", + SingularName: "role", + Namespaced: true, + + Kind: RoleGroupVersionKind.Kind, + } + + RoleGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "roles", + } +) + +func init() { + resource.Put(RoleGroupVersionResource) +} + +// Deprecated: use v1.Role instead +type Role = v1.Role + +func NewRole(namespace, name string, obj v1.Role) *v1.Role { + obj.APIVersion, obj.Kind = RoleGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type RoleHandlerFunc func(key string, obj *v1.Role) (runtime.Object, error) + +type RoleChangeHandlerFunc func(obj *v1.Role) (runtime.Object, error) + +type RoleLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.Role, err error) + Get(namespace, name string) (*v1.Role, error) +} + +type RoleController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() RoleLister + AddHandler(ctx context.Context, name string, handler RoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler RoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler RoleHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type RoleInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.Role) (*v1.Role, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Role, error) + Get(name string, opts metav1.GetOptions) (*v1.Role, error) + Update(*v1.Role) (*v1.Role, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.RoleList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() RoleController + AddHandler(ctx context.Context, name string, sync RoleHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle RoleLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleLifecycle) +} + +type roleLister struct { + ns string + controller *roleController +} + +func (l *roleLister) List(namespace string, selector labels.Selector) (ret []*v1.Role, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.Role)) + }) + return +} + +func (l *roleLister) Get(namespace, name string) (*v1.Role, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: RoleGroupVersionKind.Group, + Resource: RoleGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.Role), nil +} + +type roleController struct { + ns string + controller.GenericController +} + +func (c *roleController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *roleController) Lister() RoleLister { + return &roleLister{ + ns: c.ns, + controller: c, + } +} + +func (c *roleController) AddHandler(ctx context.Context, name string, handler RoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Role); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler RoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Role); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler RoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Role); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *roleController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler RoleHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.Role); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type roleFactory struct { +} + +func (c roleFactory) Object() runtime.Object { + return &v1.Role{} +} + +func (c roleFactory) List() runtime.Object { + return &v1.RoleList{} +} + +func (s *roleClient) Controller() RoleController { + genericController := controller.NewGenericController(s.ns, RoleGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(RoleGroupVersionResource, RoleGroupVersionKind.Kind, true)) + + return &roleController{ + ns: s.ns, + GenericController: genericController, + } +} + +type roleClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller RoleController +} + +func (s *roleClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *roleClient) Create(o *v1.Role) (*v1.Role, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.Role), err +} + +func (s *roleClient) Get(name string, opts metav1.GetOptions) (*v1.Role, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.Role), err +} + +func (s *roleClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.Role, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.Role), err +} + +func (s *roleClient) Update(o *v1.Role) (*v1.Role, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.Role), err +} + +func (s *roleClient) UpdateStatus(o *v1.Role) (*v1.Role, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.Role), err +} + +func (s *roleClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *roleClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *roleClient) List(opts metav1.ListOptions) (*v1.RoleList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.RoleList), err +} + +func (s *roleClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.RoleList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.RoleList), err +} + +func (s *roleClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *roleClient) Patch(o *v1.Role, patchType types.PatchType, data []byte, subresources ...string) (*v1.Role, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.Role), err +} + +func (s *roleClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *roleClient) AddHandler(ctx context.Context, name string, sync RoleHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync RoleHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleClient) AddLifecycle(ctx context.Context, name string, lifecycle RoleLifecycle) { + sync := NewRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *roleClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle RoleLifecycle) { + sync := NewRoleLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *roleClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync RoleHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync RoleHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *roleClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle RoleLifecycle) { + sync := NewRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *roleClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle RoleLifecycle) { + sync := NewRoleLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_lifecycle_adapter.go new file mode 100644 index 0000000..a805491 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_role_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type RoleLifecycle interface { + Create(obj *v1.Role) (runtime.Object, error) + Remove(obj *v1.Role) (runtime.Object, error) + Updated(obj *v1.Role) (runtime.Object, error) +} + +type roleLifecycleAdapter struct { + lifecycle RoleLifecycle +} + +func (w *roleLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *roleLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *roleLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.Role)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.Role)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *roleLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.Role)) + if o == nil { + return nil, err + } + return o, err +} + +func NewRoleLifecycleAdapter(name string, clusterScoped bool, client RoleInterface, l RoleLifecycle) RoleHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(RoleGroupVersionResource) + } + adapter := &roleLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.Role) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_scheme.go new file mode 100644 index 0000000..a43ea12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/rbac.authorization.k8s.io/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "rbac.authorization.k8s.io" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/fakes/zz_generated_storage_class_mock.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/fakes/zz_generated_storage_class_mock.go new file mode 100644 index 0000000..a94d659 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/fakes/zz_generated_storage_class_mock.go @@ -0,0 +1,1786 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fakes + +import ( + "context" + "sync" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + v11 "github.com/rancher/rancher/pkg/generated/norman/storage.k8s.io/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + lockStorageClassListerMockGet sync.RWMutex + lockStorageClassListerMockList sync.RWMutex +) + +// Ensure, that StorageClassListerMock does implement v11.StorageClassLister. +// If this is not the case, regenerate this file with moq. +var _ v11.StorageClassLister = &StorageClassListerMock{} + +// StorageClassListerMock is a mock implementation of v11.StorageClassLister. +// +// func TestSomethingThatUsesStorageClassLister(t *testing.T) { +// +// // make and configure a mocked v11.StorageClassLister +// mockedStorageClassLister := &StorageClassListerMock{ +// GetFunc: func(namespace string, name string) (*v1.StorageClass, error) { +// panic("mock out the Get method") +// }, +// ListFunc: func(namespace string, selector labels.Selector) ([]*v1.StorageClass, error) { +// panic("mock out the List method") +// }, +// } +// +// // use mockedStorageClassLister in code that requires v11.StorageClassLister +// // and then make assertions. +// +// } +type StorageClassListerMock struct { + // GetFunc mocks the Get method. + GetFunc func(namespace string, name string) (*v1.StorageClass, error) + + // ListFunc mocks the List method. + ListFunc func(namespace string, selector labels.Selector) ([]*v1.StorageClass, error) + + // calls tracks calls to the methods. + calls struct { + // Get holds details about calls to the Get method. + Get []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // List holds details about calls to the List method. + List []struct { + // Namespace is the namespace argument value. + Namespace string + // Selector is the selector argument value. + Selector labels.Selector + } + } +} + +// Get calls GetFunc. +func (mock *StorageClassListerMock) Get(namespace string, name string) (*v1.StorageClass, error) { + if mock.GetFunc == nil { + panic("StorageClassListerMock.GetFunc: method is nil but StorageClassLister.Get was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockStorageClassListerMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockStorageClassListerMockGet.Unlock() + return mock.GetFunc(namespace, name) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedStorageClassLister.GetCalls()) +func (mock *StorageClassListerMock) GetCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockStorageClassListerMockGet.RLock() + calls = mock.calls.Get + lockStorageClassListerMockGet.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *StorageClassListerMock) List(namespace string, selector labels.Selector) ([]*v1.StorageClass, error) { + if mock.ListFunc == nil { + panic("StorageClassListerMock.ListFunc: method is nil but StorageClassLister.List was just called") + } + callInfo := struct { + Namespace string + Selector labels.Selector + }{ + Namespace: namespace, + Selector: selector, + } + lockStorageClassListerMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockStorageClassListerMockList.Unlock() + return mock.ListFunc(namespace, selector) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedStorageClassLister.ListCalls()) +func (mock *StorageClassListerMock) ListCalls() []struct { + Namespace string + Selector labels.Selector +} { + var calls []struct { + Namespace string + Selector labels.Selector + } + lockStorageClassListerMockList.RLock() + calls = mock.calls.List + lockStorageClassListerMockList.RUnlock() + return calls +} + +var ( + lockStorageClassControllerMockAddClusterScopedFeatureHandler sync.RWMutex + lockStorageClassControllerMockAddClusterScopedHandler sync.RWMutex + lockStorageClassControllerMockAddFeatureHandler sync.RWMutex + lockStorageClassControllerMockAddHandler sync.RWMutex + lockStorageClassControllerMockEnqueue sync.RWMutex + lockStorageClassControllerMockEnqueueAfter sync.RWMutex + lockStorageClassControllerMockGeneric sync.RWMutex + lockStorageClassControllerMockInformer sync.RWMutex + lockStorageClassControllerMockLister sync.RWMutex +) + +// Ensure, that StorageClassControllerMock does implement v11.StorageClassController. +// If this is not the case, regenerate this file with moq. +var _ v11.StorageClassController = &StorageClassControllerMock{} + +// StorageClassControllerMock is a mock implementation of v11.StorageClassController. +// +// func TestSomethingThatUsesStorageClassController(t *testing.T) { +// +// // make and configure a mocked v11.StorageClassController +// mockedStorageClassController := &StorageClassControllerMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StorageClassHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, handler v11.StorageClassHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, handler v11.StorageClassHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// EnqueueFunc: func(namespace string, name string) { +// panic("mock out the Enqueue method") +// }, +// EnqueueAfterFunc: func(namespace string, name string, after time.Duration) { +// panic("mock out the EnqueueAfter method") +// }, +// GenericFunc: func() controller.GenericController { +// panic("mock out the Generic method") +// }, +// InformerFunc: func() cache.SharedIndexInformer { +// panic("mock out the Informer method") +// }, +// ListerFunc: func() v11.StorageClassLister { +// panic("mock out the Lister method") +// }, +// } +// +// // use mockedStorageClassController in code that requires v11.StorageClassController +// // and then make assertions. +// +// } +type StorageClassControllerMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StorageClassHandlerFunc) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, handler v11.StorageClassHandlerFunc) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, handler v11.StorageClassHandlerFunc) + + // EnqueueFunc mocks the Enqueue method. + EnqueueFunc func(namespace string, name string) + + // EnqueueAfterFunc mocks the EnqueueAfter method. + EnqueueAfterFunc func(namespace string, name string, after time.Duration) + + // GenericFunc mocks the Generic method. + GenericFunc func() controller.GenericController + + // InformerFunc mocks the Informer method. + InformerFunc func() cache.SharedIndexInformer + + // ListerFunc mocks the Lister method. + ListerFunc func() v11.StorageClassLister + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.StorageClassHandlerFunc + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Handler is the handler argument value. + Handler v11.StorageClassHandlerFunc + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StorageClassHandlerFunc + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Handler is the handler argument value. + Handler v11.StorageClassHandlerFunc + } + // Enqueue holds details about calls to the Enqueue method. + Enqueue []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + } + // EnqueueAfter holds details about calls to the EnqueueAfter method. + EnqueueAfter []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // After is the after argument value. + After time.Duration + } + // Generic holds details about calls to the Generic method. + Generic []struct { + } + // Informer holds details about calls to the Informer method. + Informer []struct { + } + // Lister holds details about calls to the Lister method. + Lister []struct { + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *StorageClassControllerMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, handler v11.StorageClassHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("StorageClassControllerMock.AddClusterScopedFeatureHandlerFunc: method is nil but StorageClassController.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockStorageClassControllerMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockStorageClassControllerMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, handler) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedStorageClassController.AddClusterScopedFeatureHandlerCalls()) +func (mock *StorageClassControllerMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc + } + lockStorageClassControllerMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockStorageClassControllerMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *StorageClassControllerMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, handler v11.StorageClassHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("StorageClassControllerMock.AddClusterScopedHandlerFunc: method is nil but StorageClassController.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Handler: handler, + } + lockStorageClassControllerMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockStorageClassControllerMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, handler) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedStorageClassController.AddClusterScopedHandlerCalls()) +func (mock *StorageClassControllerMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Handler v11.StorageClassHandlerFunc + } + lockStorageClassControllerMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockStorageClassControllerMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *StorageClassControllerMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("StorageClassControllerMock.AddFeatureHandlerFunc: method is nil but StorageClassController.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockStorageClassControllerMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockStorageClassControllerMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedStorageClassController.AddFeatureHandlerCalls()) +func (mock *StorageClassControllerMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc + } + lockStorageClassControllerMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockStorageClassControllerMockAddFeatureHandler.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *StorageClassControllerMock) AddHandler(ctx context.Context, name string, handler v11.StorageClassHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("StorageClassControllerMock.AddHandlerFunc: method is nil but StorageClassController.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Handler v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Name: name, + Handler: handler, + } + lockStorageClassControllerMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockStorageClassControllerMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, handler) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedStorageClassController.AddHandlerCalls()) +func (mock *StorageClassControllerMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Handler v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Handler v11.StorageClassHandlerFunc + } + lockStorageClassControllerMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockStorageClassControllerMockAddHandler.RUnlock() + return calls +} + +// Enqueue calls EnqueueFunc. +func (mock *StorageClassControllerMock) Enqueue(namespace string, name string) { + if mock.EnqueueFunc == nil { + panic("StorageClassControllerMock.EnqueueFunc: method is nil but StorageClassController.Enqueue was just called") + } + callInfo := struct { + Namespace string + Name string + }{ + Namespace: namespace, + Name: name, + } + lockStorageClassControllerMockEnqueue.Lock() + mock.calls.Enqueue = append(mock.calls.Enqueue, callInfo) + lockStorageClassControllerMockEnqueue.Unlock() + mock.EnqueueFunc(namespace, name) +} + +// EnqueueCalls gets all the calls that were made to Enqueue. +// Check the length with: +// +// len(mockedStorageClassController.EnqueueCalls()) +func (mock *StorageClassControllerMock) EnqueueCalls() []struct { + Namespace string + Name string +} { + var calls []struct { + Namespace string + Name string + } + lockStorageClassControllerMockEnqueue.RLock() + calls = mock.calls.Enqueue + lockStorageClassControllerMockEnqueue.RUnlock() + return calls +} + +// EnqueueAfter calls EnqueueAfterFunc. +func (mock *StorageClassControllerMock) EnqueueAfter(namespace string, name string, after time.Duration) { + if mock.EnqueueAfterFunc == nil { + panic("StorageClassControllerMock.EnqueueAfterFunc: method is nil but StorageClassController.EnqueueAfter was just called") + } + callInfo := struct { + Namespace string + Name string + After time.Duration + }{ + Namespace: namespace, + Name: name, + After: after, + } + lockStorageClassControllerMockEnqueueAfter.Lock() + mock.calls.EnqueueAfter = append(mock.calls.EnqueueAfter, callInfo) + lockStorageClassControllerMockEnqueueAfter.Unlock() + mock.EnqueueAfterFunc(namespace, name, after) +} + +// EnqueueAfterCalls gets all the calls that were made to EnqueueAfter. +// Check the length with: +// +// len(mockedStorageClassController.EnqueueAfterCalls()) +func (mock *StorageClassControllerMock) EnqueueAfterCalls() []struct { + Namespace string + Name string + After time.Duration +} { + var calls []struct { + Namespace string + Name string + After time.Duration + } + lockStorageClassControllerMockEnqueueAfter.RLock() + calls = mock.calls.EnqueueAfter + lockStorageClassControllerMockEnqueueAfter.RUnlock() + return calls +} + +// Generic calls GenericFunc. +func (mock *StorageClassControllerMock) Generic() controller.GenericController { + if mock.GenericFunc == nil { + panic("StorageClassControllerMock.GenericFunc: method is nil but StorageClassController.Generic was just called") + } + callInfo := struct { + }{} + lockStorageClassControllerMockGeneric.Lock() + mock.calls.Generic = append(mock.calls.Generic, callInfo) + lockStorageClassControllerMockGeneric.Unlock() + return mock.GenericFunc() +} + +// GenericCalls gets all the calls that were made to Generic. +// Check the length with: +// +// len(mockedStorageClassController.GenericCalls()) +func (mock *StorageClassControllerMock) GenericCalls() []struct { +} { + var calls []struct { + } + lockStorageClassControllerMockGeneric.RLock() + calls = mock.calls.Generic + lockStorageClassControllerMockGeneric.RUnlock() + return calls +} + +// Informer calls InformerFunc. +func (mock *StorageClassControllerMock) Informer() cache.SharedIndexInformer { + if mock.InformerFunc == nil { + panic("StorageClassControllerMock.InformerFunc: method is nil but StorageClassController.Informer was just called") + } + callInfo := struct { + }{} + lockStorageClassControllerMockInformer.Lock() + mock.calls.Informer = append(mock.calls.Informer, callInfo) + lockStorageClassControllerMockInformer.Unlock() + return mock.InformerFunc() +} + +// InformerCalls gets all the calls that were made to Informer. +// Check the length with: +// +// len(mockedStorageClassController.InformerCalls()) +func (mock *StorageClassControllerMock) InformerCalls() []struct { +} { + var calls []struct { + } + lockStorageClassControllerMockInformer.RLock() + calls = mock.calls.Informer + lockStorageClassControllerMockInformer.RUnlock() + return calls +} + +// Lister calls ListerFunc. +func (mock *StorageClassControllerMock) Lister() v11.StorageClassLister { + if mock.ListerFunc == nil { + panic("StorageClassControllerMock.ListerFunc: method is nil but StorageClassController.Lister was just called") + } + callInfo := struct { + }{} + lockStorageClassControllerMockLister.Lock() + mock.calls.Lister = append(mock.calls.Lister, callInfo) + lockStorageClassControllerMockLister.Unlock() + return mock.ListerFunc() +} + +// ListerCalls gets all the calls that were made to Lister. +// Check the length with: +// +// len(mockedStorageClassController.ListerCalls()) +func (mock *StorageClassControllerMock) ListerCalls() []struct { +} { + var calls []struct { + } + lockStorageClassControllerMockLister.RLock() + calls = mock.calls.Lister + lockStorageClassControllerMockLister.RUnlock() + return calls +} + +var ( + lockStorageClassInterfaceMockAddClusterScopedFeatureHandler sync.RWMutex + lockStorageClassInterfaceMockAddClusterScopedFeatureLifecycle sync.RWMutex + lockStorageClassInterfaceMockAddClusterScopedHandler sync.RWMutex + lockStorageClassInterfaceMockAddClusterScopedLifecycle sync.RWMutex + lockStorageClassInterfaceMockAddFeatureHandler sync.RWMutex + lockStorageClassInterfaceMockAddFeatureLifecycle sync.RWMutex + lockStorageClassInterfaceMockAddHandler sync.RWMutex + lockStorageClassInterfaceMockAddLifecycle sync.RWMutex + lockStorageClassInterfaceMockController sync.RWMutex + lockStorageClassInterfaceMockCreate sync.RWMutex + lockStorageClassInterfaceMockDelete sync.RWMutex + lockStorageClassInterfaceMockDeleteCollection sync.RWMutex + lockStorageClassInterfaceMockDeleteNamespaced sync.RWMutex + lockStorageClassInterfaceMockGet sync.RWMutex + lockStorageClassInterfaceMockGetNamespaced sync.RWMutex + lockStorageClassInterfaceMockList sync.RWMutex + lockStorageClassInterfaceMockListNamespaced sync.RWMutex + lockStorageClassInterfaceMockObjectClient sync.RWMutex + lockStorageClassInterfaceMockUpdate sync.RWMutex + lockStorageClassInterfaceMockWatch sync.RWMutex +) + +// Ensure, that StorageClassInterfaceMock does implement v11.StorageClassInterface. +// If this is not the case, regenerate this file with moq. +var _ v11.StorageClassInterface = &StorageClassInterfaceMock{} + +// StorageClassInterfaceMock is a mock implementation of v11.StorageClassInterface. +// +// func TestSomethingThatUsesStorageClassInterface(t *testing.T) { +// +// // make and configure a mocked v11.StorageClassInterface +// mockedStorageClassInterface := &StorageClassInterfaceMock{ +// AddClusterScopedFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) { +// panic("mock out the AddClusterScopedFeatureHandler method") +// }, +// AddClusterScopedFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StorageClassLifecycle) { +// panic("mock out the AddClusterScopedFeatureLifecycle method") +// }, +// AddClusterScopedHandlerFunc: func(ctx context.Context, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) { +// panic("mock out the AddClusterScopedHandler method") +// }, +// AddClusterScopedLifecycleFunc: func(ctx context.Context, name string, clusterName string, lifecycle v11.StorageClassLifecycle) { +// panic("mock out the AddClusterScopedLifecycle method") +// }, +// AddFeatureHandlerFunc: func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) { +// panic("mock out the AddFeatureHandler method") +// }, +// AddFeatureLifecycleFunc: func(ctx context.Context, enabled func() bool, name string, lifecycle v11.StorageClassLifecycle) { +// panic("mock out the AddFeatureLifecycle method") +// }, +// AddHandlerFunc: func(ctx context.Context, name string, syncMoqParam v11.StorageClassHandlerFunc) { +// panic("mock out the AddHandler method") +// }, +// AddLifecycleFunc: func(ctx context.Context, name string, lifecycle v11.StorageClassLifecycle) { +// panic("mock out the AddLifecycle method") +// }, +// ControllerFunc: func() v11.StorageClassController { +// panic("mock out the Controller method") +// }, +// CreateFunc: func(in1 *v1.StorageClass) (*v1.StorageClass, error) { +// panic("mock out the Create method") +// }, +// DeleteFunc: func(name string, options *metav1.DeleteOptions) error { +// panic("mock out the Delete method") +// }, +// DeleteCollectionFunc: func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { +// panic("mock out the DeleteCollection method") +// }, +// DeleteNamespacedFunc: func(namespace string, name string, options *metav1.DeleteOptions) error { +// panic("mock out the DeleteNamespaced method") +// }, +// GetFunc: func(name string, opts metav1.GetOptions) (*v1.StorageClass, error) { +// panic("mock out the Get method") +// }, +// GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*v1.StorageClass, error) { +// panic("mock out the GetNamespaced method") +// }, +// ListFunc: func(opts metav1.ListOptions) (*v1.StorageClassList, error) { +// panic("mock out the List method") +// }, +// ListNamespacedFunc: func(namespace string, opts metav1.ListOptions) (*v1.StorageClassList, error) { +// panic("mock out the ListNamespaced method") +// }, +// ObjectClientFunc: func() *objectclient.ObjectClient { +// panic("mock out the ObjectClient method") +// }, +// UpdateFunc: func(in1 *v1.StorageClass) (*v1.StorageClass, error) { +// panic("mock out the Update method") +// }, +// WatchFunc: func(opts metav1.ListOptions) (watch.Interface, error) { +// panic("mock out the Watch method") +// }, +// } +// +// // use mockedStorageClassInterface in code that requires v11.StorageClassInterface +// // and then make assertions. +// +// } +type StorageClassInterfaceMock struct { + // AddClusterScopedFeatureHandlerFunc mocks the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) + + // AddClusterScopedFeatureLifecycleFunc mocks the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StorageClassLifecycle) + + // AddClusterScopedHandlerFunc mocks the AddClusterScopedHandler method. + AddClusterScopedHandlerFunc func(ctx context.Context, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) + + // AddClusterScopedLifecycleFunc mocks the AddClusterScopedLifecycle method. + AddClusterScopedLifecycleFunc func(ctx context.Context, name string, clusterName string, lifecycle v11.StorageClassLifecycle) + + // AddFeatureHandlerFunc mocks the AddFeatureHandler method. + AddFeatureHandlerFunc func(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) + + // AddFeatureLifecycleFunc mocks the AddFeatureLifecycle method. + AddFeatureLifecycleFunc func(ctx context.Context, enabled func() bool, name string, lifecycle v11.StorageClassLifecycle) + + // AddHandlerFunc mocks the AddHandler method. + AddHandlerFunc func(ctx context.Context, name string, syncMoqParam v11.StorageClassHandlerFunc) + + // AddLifecycleFunc mocks the AddLifecycle method. + AddLifecycleFunc func(ctx context.Context, name string, lifecycle v11.StorageClassLifecycle) + + // ControllerFunc mocks the Controller method. + ControllerFunc func() v11.StorageClassController + + // CreateFunc mocks the Create method. + CreateFunc func(in1 *v1.StorageClass) (*v1.StorageClass, error) + + // DeleteFunc mocks the Delete method. + DeleteFunc func(name string, options *metav1.DeleteOptions) error + + // DeleteCollectionFunc mocks the DeleteCollection method. + DeleteCollectionFunc func(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + + // DeleteNamespacedFunc mocks the DeleteNamespaced method. + DeleteNamespacedFunc func(namespace string, name string, options *metav1.DeleteOptions) error + + // GetFunc mocks the Get method. + GetFunc func(name string, opts metav1.GetOptions) (*v1.StorageClass, error) + + // GetNamespacedFunc mocks the GetNamespaced method. + GetNamespacedFunc func(namespace string, name string, opts metav1.GetOptions) (*v1.StorageClass, error) + + // ListFunc mocks the List method. + ListFunc func(opts metav1.ListOptions) (*v1.StorageClassList, error) + + // ListNamespacedFunc mocks the ListNamespaced method. + ListNamespacedFunc func(namespace string, opts metav1.ListOptions) (*v1.StorageClassList, error) + + // ObjectClientFunc mocks the ObjectClient method. + ObjectClientFunc func() *objectclient.ObjectClient + + // UpdateFunc mocks the Update method. + UpdateFunc func(in1 *v1.StorageClass) (*v1.StorageClass, error) + + // WatchFunc mocks the Watch method. + WatchFunc func(opts metav1.ListOptions) (watch.Interface, error) + + // calls tracks calls to the methods. + calls struct { + // AddClusterScopedFeatureHandler holds details about calls to the AddClusterScopedFeatureHandler method. + AddClusterScopedFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.StorageClassHandlerFunc + } + // AddClusterScopedFeatureLifecycle holds details about calls to the AddClusterScopedFeatureLifecycle method. + AddClusterScopedFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StorageClassLifecycle + } + // AddClusterScopedHandler holds details about calls to the AddClusterScopedHandler method. + AddClusterScopedHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Sync is the sync argument value. + Sync v11.StorageClassHandlerFunc + } + // AddClusterScopedLifecycle holds details about calls to the AddClusterScopedLifecycle method. + AddClusterScopedLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // ClusterName is the clusterName argument value. + ClusterName string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StorageClassLifecycle + } + // AddFeatureHandler holds details about calls to the AddFeatureHandler method. + AddFeatureHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StorageClassHandlerFunc + } + // AddFeatureLifecycle holds details about calls to the AddFeatureLifecycle method. + AddFeatureLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Enabled is the enabled argument value. + Enabled func() bool + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StorageClassLifecycle + } + // AddHandler holds details about calls to the AddHandler method. + AddHandler []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Sync is the sync argument value. + Sync v11.StorageClassHandlerFunc + } + // AddLifecycle holds details about calls to the AddLifecycle method. + AddLifecycle []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // Name is the name argument value. + Name string + // Lifecycle is the lifecycle argument value. + Lifecycle v11.StorageClassLifecycle + } + // Controller holds details about calls to the Controller method. + Controller []struct { + } + // Create holds details about calls to the Create method. + Create []struct { + // In1 is the in1 argument value. + In1 *v1.StorageClass + } + // Delete holds details about calls to the Delete method. + Delete []struct { + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // DeleteCollection holds details about calls to the DeleteCollection method. + DeleteCollection []struct { + // DeleteOpts is the deleteOpts argument value. + DeleteOpts *metav1.DeleteOptions + // ListOpts is the listOpts argument value. + ListOpts metav1.ListOptions + } + // DeleteNamespaced holds details about calls to the DeleteNamespaced method. + DeleteNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Options is the options argument value. + Options *metav1.DeleteOptions + } + // Get holds details about calls to the Get method. + Get []struct { + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // GetNamespaced holds details about calls to the GetNamespaced method. + GetNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Name is the name argument value. + Name string + // Opts is the opts argument value. + Opts metav1.GetOptions + } + // List holds details about calls to the List method. + List []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ListNamespaced holds details about calls to the ListNamespaced method. + ListNamespaced []struct { + // Namespace is the namespace argument value. + Namespace string + // Opts is the opts argument value. + Opts metav1.ListOptions + } + // ObjectClient holds details about calls to the ObjectClient method. + ObjectClient []struct { + } + // Update holds details about calls to the Update method. + Update []struct { + // In1 is the in1 argument value. + In1 *v1.StorageClass + } + // Watch holds details about calls to the Watch method. + Watch []struct { + // Opts is the opts argument value. + Opts metav1.ListOptions + } + } +} + +// AddClusterScopedFeatureHandler calls AddClusterScopedFeatureHandlerFunc. +func (mock *StorageClassInterfaceMock) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) { + if mock.AddClusterScopedFeatureHandlerFunc == nil { + panic("StorageClassInterfaceMock.AddClusterScopedFeatureHandlerFunc: method is nil but StorageClassInterface.AddClusterScopedFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockStorageClassInterfaceMockAddClusterScopedFeatureHandler.Lock() + mock.calls.AddClusterScopedFeatureHandler = append(mock.calls.AddClusterScopedFeatureHandler, callInfo) + lockStorageClassInterfaceMockAddClusterScopedFeatureHandler.Unlock() + mock.AddClusterScopedFeatureHandlerFunc(ctx, enabled, name, clusterName, syncMoqParam) +} + +// AddClusterScopedFeatureHandlerCalls gets all the calls that were made to AddClusterScopedFeatureHandler. +// Check the length with: +// +// len(mockedStorageClassInterface.AddClusterScopedFeatureHandlerCalls()) +func (mock *StorageClassInterfaceMock) AddClusterScopedFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc + } + lockStorageClassInterfaceMockAddClusterScopedFeatureHandler.RLock() + calls = mock.calls.AddClusterScopedFeatureHandler + lockStorageClassInterfaceMockAddClusterScopedFeatureHandler.RUnlock() + return calls +} + +// AddClusterScopedFeatureLifecycle calls AddClusterScopedFeatureLifecycleFunc. +func (mock *StorageClassInterfaceMock) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name string, clusterName string, lifecycle v11.StorageClassLifecycle) { + if mock.AddClusterScopedFeatureLifecycleFunc == nil { + panic("StorageClassInterfaceMock.AddClusterScopedFeatureLifecycleFunc: method is nil but StorageClassInterface.AddClusterScopedFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockStorageClassInterfaceMockAddClusterScopedFeatureLifecycle.Lock() + mock.calls.AddClusterScopedFeatureLifecycle = append(mock.calls.AddClusterScopedFeatureLifecycle, callInfo) + lockStorageClassInterfaceMockAddClusterScopedFeatureLifecycle.Unlock() + mock.AddClusterScopedFeatureLifecycleFunc(ctx, enabled, name, clusterName, lifecycle) +} + +// AddClusterScopedFeatureLifecycleCalls gets all the calls that were made to AddClusterScopedFeatureLifecycle. +// Check the length with: +// +// len(mockedStorageClassInterface.AddClusterScopedFeatureLifecycleCalls()) +func (mock *StorageClassInterfaceMock) AddClusterScopedFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle + } + lockStorageClassInterfaceMockAddClusterScopedFeatureLifecycle.RLock() + calls = mock.calls.AddClusterScopedFeatureLifecycle + lockStorageClassInterfaceMockAddClusterScopedFeatureLifecycle.RUnlock() + return calls +} + +// AddClusterScopedHandler calls AddClusterScopedHandlerFunc. +func (mock *StorageClassInterfaceMock) AddClusterScopedHandler(ctx context.Context, name string, clusterName string, syncMoqParam v11.StorageClassHandlerFunc) { + if mock.AddClusterScopedHandlerFunc == nil { + panic("StorageClassInterfaceMock.AddClusterScopedHandlerFunc: method is nil but StorageClassInterface.AddClusterScopedHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Sync: syncMoqParam, + } + lockStorageClassInterfaceMockAddClusterScopedHandler.Lock() + mock.calls.AddClusterScopedHandler = append(mock.calls.AddClusterScopedHandler, callInfo) + lockStorageClassInterfaceMockAddClusterScopedHandler.Unlock() + mock.AddClusterScopedHandlerFunc(ctx, name, clusterName, syncMoqParam) +} + +// AddClusterScopedHandlerCalls gets all the calls that were made to AddClusterScopedHandler. +// Check the length with: +// +// len(mockedStorageClassInterface.AddClusterScopedHandlerCalls()) +func (mock *StorageClassInterfaceMock) AddClusterScopedHandlerCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Sync v11.StorageClassHandlerFunc + } + lockStorageClassInterfaceMockAddClusterScopedHandler.RLock() + calls = mock.calls.AddClusterScopedHandler + lockStorageClassInterfaceMockAddClusterScopedHandler.RUnlock() + return calls +} + +// AddClusterScopedLifecycle calls AddClusterScopedLifecycleFunc. +func (mock *StorageClassInterfaceMock) AddClusterScopedLifecycle(ctx context.Context, name string, clusterName string, lifecycle v11.StorageClassLifecycle) { + if mock.AddClusterScopedLifecycleFunc == nil { + panic("StorageClassInterfaceMock.AddClusterScopedLifecycleFunc: method is nil but StorageClassInterface.AddClusterScopedLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle + }{ + Ctx: ctx, + Name: name, + ClusterName: clusterName, + Lifecycle: lifecycle, + } + lockStorageClassInterfaceMockAddClusterScopedLifecycle.Lock() + mock.calls.AddClusterScopedLifecycle = append(mock.calls.AddClusterScopedLifecycle, callInfo) + lockStorageClassInterfaceMockAddClusterScopedLifecycle.Unlock() + mock.AddClusterScopedLifecycleFunc(ctx, name, clusterName, lifecycle) +} + +// AddClusterScopedLifecycleCalls gets all the calls that were made to AddClusterScopedLifecycle. +// Check the length with: +// +// len(mockedStorageClassInterface.AddClusterScopedLifecycleCalls()) +func (mock *StorageClassInterfaceMock) AddClusterScopedLifecycleCalls() []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + ClusterName string + Lifecycle v11.StorageClassLifecycle + } + lockStorageClassInterfaceMockAddClusterScopedLifecycle.RLock() + calls = mock.calls.AddClusterScopedLifecycle + lockStorageClassInterfaceMockAddClusterScopedLifecycle.RUnlock() + return calls +} + +// AddFeatureHandler calls AddFeatureHandlerFunc. +func (mock *StorageClassInterfaceMock) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, syncMoqParam v11.StorageClassHandlerFunc) { + if mock.AddFeatureHandlerFunc == nil { + panic("StorageClassInterfaceMock.AddFeatureHandlerFunc: method is nil but StorageClassInterface.AddFeatureHandler was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Sync: syncMoqParam, + } + lockStorageClassInterfaceMockAddFeatureHandler.Lock() + mock.calls.AddFeatureHandler = append(mock.calls.AddFeatureHandler, callInfo) + lockStorageClassInterfaceMockAddFeatureHandler.Unlock() + mock.AddFeatureHandlerFunc(ctx, enabled, name, syncMoqParam) +} + +// AddFeatureHandlerCalls gets all the calls that were made to AddFeatureHandler. +// Check the length with: +// +// len(mockedStorageClassInterface.AddFeatureHandlerCalls()) +func (mock *StorageClassInterfaceMock) AddFeatureHandlerCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Sync v11.StorageClassHandlerFunc + } + lockStorageClassInterfaceMockAddFeatureHandler.RLock() + calls = mock.calls.AddFeatureHandler + lockStorageClassInterfaceMockAddFeatureHandler.RUnlock() + return calls +} + +// AddFeatureLifecycle calls AddFeatureLifecycleFunc. +func (mock *StorageClassInterfaceMock) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle v11.StorageClassLifecycle) { + if mock.AddFeatureLifecycleFunc == nil { + panic("StorageClassInterfaceMock.AddFeatureLifecycleFunc: method is nil but StorageClassInterface.AddFeatureLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StorageClassLifecycle + }{ + Ctx: ctx, + Enabled: enabled, + Name: name, + Lifecycle: lifecycle, + } + lockStorageClassInterfaceMockAddFeatureLifecycle.Lock() + mock.calls.AddFeatureLifecycle = append(mock.calls.AddFeatureLifecycle, callInfo) + lockStorageClassInterfaceMockAddFeatureLifecycle.Unlock() + mock.AddFeatureLifecycleFunc(ctx, enabled, name, lifecycle) +} + +// AddFeatureLifecycleCalls gets all the calls that were made to AddFeatureLifecycle. +// Check the length with: +// +// len(mockedStorageClassInterface.AddFeatureLifecycleCalls()) +func (mock *StorageClassInterfaceMock) AddFeatureLifecycleCalls() []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StorageClassLifecycle +} { + var calls []struct { + Ctx context.Context + Enabled func() bool + Name string + Lifecycle v11.StorageClassLifecycle + } + lockStorageClassInterfaceMockAddFeatureLifecycle.RLock() + calls = mock.calls.AddFeatureLifecycle + lockStorageClassInterfaceMockAddFeatureLifecycle.RUnlock() + return calls +} + +// AddHandler calls AddHandlerFunc. +func (mock *StorageClassInterfaceMock) AddHandler(ctx context.Context, name string, syncMoqParam v11.StorageClassHandlerFunc) { + if mock.AddHandlerFunc == nil { + panic("StorageClassInterfaceMock.AddHandlerFunc: method is nil but StorageClassInterface.AddHandler was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Sync v11.StorageClassHandlerFunc + }{ + Ctx: ctx, + Name: name, + Sync: syncMoqParam, + } + lockStorageClassInterfaceMockAddHandler.Lock() + mock.calls.AddHandler = append(mock.calls.AddHandler, callInfo) + lockStorageClassInterfaceMockAddHandler.Unlock() + mock.AddHandlerFunc(ctx, name, syncMoqParam) +} + +// AddHandlerCalls gets all the calls that were made to AddHandler. +// Check the length with: +// +// len(mockedStorageClassInterface.AddHandlerCalls()) +func (mock *StorageClassInterfaceMock) AddHandlerCalls() []struct { + Ctx context.Context + Name string + Sync v11.StorageClassHandlerFunc +} { + var calls []struct { + Ctx context.Context + Name string + Sync v11.StorageClassHandlerFunc + } + lockStorageClassInterfaceMockAddHandler.RLock() + calls = mock.calls.AddHandler + lockStorageClassInterfaceMockAddHandler.RUnlock() + return calls +} + +// AddLifecycle calls AddLifecycleFunc. +func (mock *StorageClassInterfaceMock) AddLifecycle(ctx context.Context, name string, lifecycle v11.StorageClassLifecycle) { + if mock.AddLifecycleFunc == nil { + panic("StorageClassInterfaceMock.AddLifecycleFunc: method is nil but StorageClassInterface.AddLifecycle was just called") + } + callInfo := struct { + Ctx context.Context + Name string + Lifecycle v11.StorageClassLifecycle + }{ + Ctx: ctx, + Name: name, + Lifecycle: lifecycle, + } + lockStorageClassInterfaceMockAddLifecycle.Lock() + mock.calls.AddLifecycle = append(mock.calls.AddLifecycle, callInfo) + lockStorageClassInterfaceMockAddLifecycle.Unlock() + mock.AddLifecycleFunc(ctx, name, lifecycle) +} + +// AddLifecycleCalls gets all the calls that were made to AddLifecycle. +// Check the length with: +// +// len(mockedStorageClassInterface.AddLifecycleCalls()) +func (mock *StorageClassInterfaceMock) AddLifecycleCalls() []struct { + Ctx context.Context + Name string + Lifecycle v11.StorageClassLifecycle +} { + var calls []struct { + Ctx context.Context + Name string + Lifecycle v11.StorageClassLifecycle + } + lockStorageClassInterfaceMockAddLifecycle.RLock() + calls = mock.calls.AddLifecycle + lockStorageClassInterfaceMockAddLifecycle.RUnlock() + return calls +} + +// Controller calls ControllerFunc. +func (mock *StorageClassInterfaceMock) Controller() v11.StorageClassController { + if mock.ControllerFunc == nil { + panic("StorageClassInterfaceMock.ControllerFunc: method is nil but StorageClassInterface.Controller was just called") + } + callInfo := struct { + }{} + lockStorageClassInterfaceMockController.Lock() + mock.calls.Controller = append(mock.calls.Controller, callInfo) + lockStorageClassInterfaceMockController.Unlock() + return mock.ControllerFunc() +} + +// ControllerCalls gets all the calls that were made to Controller. +// Check the length with: +// +// len(mockedStorageClassInterface.ControllerCalls()) +func (mock *StorageClassInterfaceMock) ControllerCalls() []struct { +} { + var calls []struct { + } + lockStorageClassInterfaceMockController.RLock() + calls = mock.calls.Controller + lockStorageClassInterfaceMockController.RUnlock() + return calls +} + +// Create calls CreateFunc. +func (mock *StorageClassInterfaceMock) Create(in1 *v1.StorageClass) (*v1.StorageClass, error) { + if mock.CreateFunc == nil { + panic("StorageClassInterfaceMock.CreateFunc: method is nil but StorageClassInterface.Create was just called") + } + callInfo := struct { + In1 *v1.StorageClass + }{ + In1: in1, + } + lockStorageClassInterfaceMockCreate.Lock() + mock.calls.Create = append(mock.calls.Create, callInfo) + lockStorageClassInterfaceMockCreate.Unlock() + return mock.CreateFunc(in1) +} + +// CreateCalls gets all the calls that were made to Create. +// Check the length with: +// +// len(mockedStorageClassInterface.CreateCalls()) +func (mock *StorageClassInterfaceMock) CreateCalls() []struct { + In1 *v1.StorageClass +} { + var calls []struct { + In1 *v1.StorageClass + } + lockStorageClassInterfaceMockCreate.RLock() + calls = mock.calls.Create + lockStorageClassInterfaceMockCreate.RUnlock() + return calls +} + +// Delete calls DeleteFunc. +func (mock *StorageClassInterfaceMock) Delete(name string, options *metav1.DeleteOptions) error { + if mock.DeleteFunc == nil { + panic("StorageClassInterfaceMock.DeleteFunc: method is nil but StorageClassInterface.Delete was just called") + } + callInfo := struct { + Name string + Options *metav1.DeleteOptions + }{ + Name: name, + Options: options, + } + lockStorageClassInterfaceMockDelete.Lock() + mock.calls.Delete = append(mock.calls.Delete, callInfo) + lockStorageClassInterfaceMockDelete.Unlock() + return mock.DeleteFunc(name, options) +} + +// DeleteCalls gets all the calls that were made to Delete. +// Check the length with: +// +// len(mockedStorageClassInterface.DeleteCalls()) +func (mock *StorageClassInterfaceMock) DeleteCalls() []struct { + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Name string + Options *metav1.DeleteOptions + } + lockStorageClassInterfaceMockDelete.RLock() + calls = mock.calls.Delete + lockStorageClassInterfaceMockDelete.RUnlock() + return calls +} + +// DeleteCollection calls DeleteCollectionFunc. +func (mock *StorageClassInterfaceMock) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + if mock.DeleteCollectionFunc == nil { + panic("StorageClassInterfaceMock.DeleteCollectionFunc: method is nil but StorageClassInterface.DeleteCollection was just called") + } + callInfo := struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + }{ + DeleteOpts: deleteOpts, + ListOpts: listOpts, + } + lockStorageClassInterfaceMockDeleteCollection.Lock() + mock.calls.DeleteCollection = append(mock.calls.DeleteCollection, callInfo) + lockStorageClassInterfaceMockDeleteCollection.Unlock() + return mock.DeleteCollectionFunc(deleteOpts, listOpts) +} + +// DeleteCollectionCalls gets all the calls that were made to DeleteCollection. +// Check the length with: +// +// len(mockedStorageClassInterface.DeleteCollectionCalls()) +func (mock *StorageClassInterfaceMock) DeleteCollectionCalls() []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions +} { + var calls []struct { + DeleteOpts *metav1.DeleteOptions + ListOpts metav1.ListOptions + } + lockStorageClassInterfaceMockDeleteCollection.RLock() + calls = mock.calls.DeleteCollection + lockStorageClassInterfaceMockDeleteCollection.RUnlock() + return calls +} + +// DeleteNamespaced calls DeleteNamespacedFunc. +func (mock *StorageClassInterfaceMock) DeleteNamespaced(namespace string, name string, options *metav1.DeleteOptions) error { + if mock.DeleteNamespacedFunc == nil { + panic("StorageClassInterfaceMock.DeleteNamespacedFunc: method is nil but StorageClassInterface.DeleteNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Options *metav1.DeleteOptions + }{ + Namespace: namespace, + Name: name, + Options: options, + } + lockStorageClassInterfaceMockDeleteNamespaced.Lock() + mock.calls.DeleteNamespaced = append(mock.calls.DeleteNamespaced, callInfo) + lockStorageClassInterfaceMockDeleteNamespaced.Unlock() + return mock.DeleteNamespacedFunc(namespace, name, options) +} + +// DeleteNamespacedCalls gets all the calls that were made to DeleteNamespaced. +// Check the length with: +// +// len(mockedStorageClassInterface.DeleteNamespacedCalls()) +func (mock *StorageClassInterfaceMock) DeleteNamespacedCalls() []struct { + Namespace string + Name string + Options *metav1.DeleteOptions +} { + var calls []struct { + Namespace string + Name string + Options *metav1.DeleteOptions + } + lockStorageClassInterfaceMockDeleteNamespaced.RLock() + calls = mock.calls.DeleteNamespaced + lockStorageClassInterfaceMockDeleteNamespaced.RUnlock() + return calls +} + +// Get calls GetFunc. +func (mock *StorageClassInterfaceMock) Get(name string, opts metav1.GetOptions) (*v1.StorageClass, error) { + if mock.GetFunc == nil { + panic("StorageClassInterfaceMock.GetFunc: method is nil but StorageClassInterface.Get was just called") + } + callInfo := struct { + Name string + Opts metav1.GetOptions + }{ + Name: name, + Opts: opts, + } + lockStorageClassInterfaceMockGet.Lock() + mock.calls.Get = append(mock.calls.Get, callInfo) + lockStorageClassInterfaceMockGet.Unlock() + return mock.GetFunc(name, opts) +} + +// GetCalls gets all the calls that were made to Get. +// Check the length with: +// +// len(mockedStorageClassInterface.GetCalls()) +func (mock *StorageClassInterfaceMock) GetCalls() []struct { + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Name string + Opts metav1.GetOptions + } + lockStorageClassInterfaceMockGet.RLock() + calls = mock.calls.Get + lockStorageClassInterfaceMockGet.RUnlock() + return calls +} + +// GetNamespaced calls GetNamespacedFunc. +func (mock *StorageClassInterfaceMock) GetNamespaced(namespace string, name string, opts metav1.GetOptions) (*v1.StorageClass, error) { + if mock.GetNamespacedFunc == nil { + panic("StorageClassInterfaceMock.GetNamespacedFunc: method is nil but StorageClassInterface.GetNamespaced was just called") + } + callInfo := struct { + Namespace string + Name string + Opts metav1.GetOptions + }{ + Namespace: namespace, + Name: name, + Opts: opts, + } + lockStorageClassInterfaceMockGetNamespaced.Lock() + mock.calls.GetNamespaced = append(mock.calls.GetNamespaced, callInfo) + lockStorageClassInterfaceMockGetNamespaced.Unlock() + return mock.GetNamespacedFunc(namespace, name, opts) +} + +// GetNamespacedCalls gets all the calls that were made to GetNamespaced. +// Check the length with: +// +// len(mockedStorageClassInterface.GetNamespacedCalls()) +func (mock *StorageClassInterfaceMock) GetNamespacedCalls() []struct { + Namespace string + Name string + Opts metav1.GetOptions +} { + var calls []struct { + Namespace string + Name string + Opts metav1.GetOptions + } + lockStorageClassInterfaceMockGetNamespaced.RLock() + calls = mock.calls.GetNamespaced + lockStorageClassInterfaceMockGetNamespaced.RUnlock() + return calls +} + +// List calls ListFunc. +func (mock *StorageClassInterfaceMock) List(opts metav1.ListOptions) (*v1.StorageClassList, error) { + if mock.ListFunc == nil { + panic("StorageClassInterfaceMock.ListFunc: method is nil but StorageClassInterface.List was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockStorageClassInterfaceMockList.Lock() + mock.calls.List = append(mock.calls.List, callInfo) + lockStorageClassInterfaceMockList.Unlock() + return mock.ListFunc(opts) +} + +// ListCalls gets all the calls that were made to List. +// Check the length with: +// +// len(mockedStorageClassInterface.ListCalls()) +func (mock *StorageClassInterfaceMock) ListCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockStorageClassInterfaceMockList.RLock() + calls = mock.calls.List + lockStorageClassInterfaceMockList.RUnlock() + return calls +} + +// ListNamespaced calls ListNamespacedFunc. +func (mock *StorageClassInterfaceMock) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StorageClassList, error) { + if mock.ListNamespacedFunc == nil { + panic("StorageClassInterfaceMock.ListNamespacedFunc: method is nil but StorageClassInterface.ListNamespaced was just called") + } + callInfo := struct { + Namespace string + Opts metav1.ListOptions + }{ + Namespace: namespace, + Opts: opts, + } + lockStorageClassInterfaceMockListNamespaced.Lock() + mock.calls.ListNamespaced = append(mock.calls.ListNamespaced, callInfo) + lockStorageClassInterfaceMockListNamespaced.Unlock() + return mock.ListNamespacedFunc(namespace, opts) +} + +// ListNamespacedCalls gets all the calls that were made to ListNamespaced. +// Check the length with: +// +// len(mockedStorageClassInterface.ListNamespacedCalls()) +func (mock *StorageClassInterfaceMock) ListNamespacedCalls() []struct { + Namespace string + Opts metav1.ListOptions +} { + var calls []struct { + Namespace string + Opts metav1.ListOptions + } + lockStorageClassInterfaceMockListNamespaced.RLock() + calls = mock.calls.ListNamespaced + lockStorageClassInterfaceMockListNamespaced.RUnlock() + return calls +} + +// ObjectClient calls ObjectClientFunc. +func (mock *StorageClassInterfaceMock) ObjectClient() *objectclient.ObjectClient { + if mock.ObjectClientFunc == nil { + panic("StorageClassInterfaceMock.ObjectClientFunc: method is nil but StorageClassInterface.ObjectClient was just called") + } + callInfo := struct { + }{} + lockStorageClassInterfaceMockObjectClient.Lock() + mock.calls.ObjectClient = append(mock.calls.ObjectClient, callInfo) + lockStorageClassInterfaceMockObjectClient.Unlock() + return mock.ObjectClientFunc() +} + +// ObjectClientCalls gets all the calls that were made to ObjectClient. +// Check the length with: +// +// len(mockedStorageClassInterface.ObjectClientCalls()) +func (mock *StorageClassInterfaceMock) ObjectClientCalls() []struct { +} { + var calls []struct { + } + lockStorageClassInterfaceMockObjectClient.RLock() + calls = mock.calls.ObjectClient + lockStorageClassInterfaceMockObjectClient.RUnlock() + return calls +} + +// Update calls UpdateFunc. +func (mock *StorageClassInterfaceMock) Update(in1 *v1.StorageClass) (*v1.StorageClass, error) { + if mock.UpdateFunc == nil { + panic("StorageClassInterfaceMock.UpdateFunc: method is nil but StorageClassInterface.Update was just called") + } + callInfo := struct { + In1 *v1.StorageClass + }{ + In1: in1, + } + lockStorageClassInterfaceMockUpdate.Lock() + mock.calls.Update = append(mock.calls.Update, callInfo) + lockStorageClassInterfaceMockUpdate.Unlock() + return mock.UpdateFunc(in1) +} + +// UpdateCalls gets all the calls that were made to Update. +// Check the length with: +// +// len(mockedStorageClassInterface.UpdateCalls()) +func (mock *StorageClassInterfaceMock) UpdateCalls() []struct { + In1 *v1.StorageClass +} { + var calls []struct { + In1 *v1.StorageClass + } + lockStorageClassInterfaceMockUpdate.RLock() + calls = mock.calls.Update + lockStorageClassInterfaceMockUpdate.RUnlock() + return calls +} + +// Watch calls WatchFunc. +func (mock *StorageClassInterfaceMock) Watch(opts metav1.ListOptions) (watch.Interface, error) { + if mock.WatchFunc == nil { + panic("StorageClassInterfaceMock.WatchFunc: method is nil but StorageClassInterface.Watch was just called") + } + callInfo := struct { + Opts metav1.ListOptions + }{ + Opts: opts, + } + lockStorageClassInterfaceMockWatch.Lock() + mock.calls.Watch = append(mock.calls.Watch, callInfo) + lockStorageClassInterfaceMockWatch.Unlock() + return mock.WatchFunc(opts) +} + +// WatchCalls gets all the calls that were made to Watch. +// Check the length with: +// +// len(mockedStorageClassInterface.WatchCalls()) +func (mock *StorageClassInterfaceMock) WatchCalls() []struct { + Opts metav1.ListOptions +} { + var calls []struct { + Opts metav1.ListOptions + } + lockStorageClassInterfaceMockWatch.RLock() + calls = mock.calls.Watch + lockStorageClassInterfaceMockWatch.RUnlock() + return calls +} + +var ( + lockStorageClassesGetterMockStorageClasses sync.RWMutex +) + +// Ensure, that StorageClassesGetterMock does implement v11.StorageClassesGetter. +// If this is not the case, regenerate this file with moq. +var _ v11.StorageClassesGetter = &StorageClassesGetterMock{} + +// StorageClassesGetterMock is a mock implementation of v11.StorageClassesGetter. +// +// func TestSomethingThatUsesStorageClassesGetter(t *testing.T) { +// +// // make and configure a mocked v11.StorageClassesGetter +// mockedStorageClassesGetter := &StorageClassesGetterMock{ +// StorageClassesFunc: func(namespace string) v11.StorageClassInterface { +// panic("mock out the StorageClasses method") +// }, +// } +// +// // use mockedStorageClassesGetter in code that requires v11.StorageClassesGetter +// // and then make assertions. +// +// } +type StorageClassesGetterMock struct { + // StorageClassesFunc mocks the StorageClasses method. + StorageClassesFunc func(namespace string) v11.StorageClassInterface + + // calls tracks calls to the methods. + calls struct { + // StorageClasses holds details about calls to the StorageClasses method. + StorageClasses []struct { + // Namespace is the namespace argument value. + Namespace string + } + } +} + +// StorageClasses calls StorageClassesFunc. +func (mock *StorageClassesGetterMock) StorageClasses(namespace string) v11.StorageClassInterface { + if mock.StorageClassesFunc == nil { + panic("StorageClassesGetterMock.StorageClassesFunc: method is nil but StorageClassesGetter.StorageClasses was just called") + } + callInfo := struct { + Namespace string + }{ + Namespace: namespace, + } + lockStorageClassesGetterMockStorageClasses.Lock() + mock.calls.StorageClasses = append(mock.calls.StorageClasses, callInfo) + lockStorageClassesGetterMockStorageClasses.Unlock() + return mock.StorageClassesFunc(namespace) +} + +// StorageClassesCalls gets all the calls that were made to StorageClasses. +// Check the length with: +// +// len(mockedStorageClassesGetter.StorageClassesCalls()) +func (mock *StorageClassesGetterMock) StorageClassesCalls() []struct { + Namespace string +} { + var calls []struct { + Namespace string + } + lockStorageClassesGetterMockStorageClasses.RLock() + calls = mock.calls.StorageClasses + lockStorageClassesGetterMockStorageClasses.RUnlock() + return calls +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_k8s_client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_k8s_client.go new file mode 100644 index 0000000..cbc0ab1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_k8s_client.go @@ -0,0 +1,63 @@ +package v1 + +import ( + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/generator" + "github.com/rancher/norman/objectclient" + "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" +) + +type Interface interface { + StorageClassesGetter +} + +type Client struct { + controllerFactory controller.SharedControllerFactory + clientFactory client.SharedClientFactory +} + +func NewForConfig(cfg rest.Config) (Interface, error) { + scheme := runtime.NewScheme() + if err := v1.AddToScheme(scheme); err != nil { + return nil, err + } + sharedOpts := &controller.SharedControllerFactoryOptions{ + SyncOnlyChangedObjects: generator.SyncOnlyChangedObjects(), + } + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(&cfg, scheme, sharedOpts) + if err != nil { + return nil, err + } + return NewFromControllerFactory(controllerFactory), nil +} + +func NewFromControllerFactory(factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: factory.SharedCacheFactory().SharedClientFactory(), + } +} + +func NewFromControllerFactoryWithAgent(userAgent string, factory controller.SharedControllerFactory) Interface { + return &Client{ + controllerFactory: factory, + clientFactory: client.NewSharedClientFactoryWithAgent(userAgent, factory.SharedCacheFactory().SharedClientFactory()), + } +} + +type StorageClassesGetter interface { + StorageClasses(namespace string) StorageClassInterface +} + +func (c *Client) StorageClasses(namespace string) StorageClassInterface { + sharedClient := c.clientFactory.ForResourceKind(StorageClassGroupVersionResource, StorageClassGroupVersionKind.Kind, false) + objectClient := objectclient.NewObjectClient(namespace, sharedClient, &StorageClassResource, StorageClassGroupVersionKind, storageClassFactory{}) + return &storageClassClient{ + ns: namespace, + client: c, + objectClient: objectClient, + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_scheme.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_scheme.go new file mode 100644 index 0000000..8e55ae1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_scheme.go @@ -0,0 +1,23 @@ +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +const ( + GroupName = "storage.k8s.io" + Version = "v1" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_controller.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_controller.go new file mode 100644 index 0000000..9c480a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_controller.go @@ -0,0 +1,325 @@ +package v1 + +import ( + "context" + "time" + + "github.com/rancher/norman/controller" + "github.com/rancher/norman/objectclient" + "github.com/rancher/norman/resource" + "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" +) + +var ( + StorageClassGroupVersionKind = schema.GroupVersionKind{ + Version: Version, + Group: GroupName, + Kind: "StorageClass", + } + StorageClassResource = metav1.APIResource{ + Name: "storageclasses", + SingularName: "storageclass", + Namespaced: false, + Kind: StorageClassGroupVersionKind.Kind, + } + + StorageClassGroupVersionResource = schema.GroupVersionResource{ + Group: GroupName, + Version: Version, + Resource: "storageclasses", + } +) + +func init() { + resource.Put(StorageClassGroupVersionResource) +} + +// Deprecated: use v1.StorageClass instead +type StorageClass = v1.StorageClass + +func NewStorageClass(namespace, name string, obj v1.StorageClass) *v1.StorageClass { + obj.APIVersion, obj.Kind = StorageClassGroupVersionKind.ToAPIVersionAndKind() + obj.Name = name + obj.Namespace = namespace + return &obj +} + +type StorageClassHandlerFunc func(key string, obj *v1.StorageClass) (runtime.Object, error) + +type StorageClassChangeHandlerFunc func(obj *v1.StorageClass) (runtime.Object, error) + +type StorageClassLister interface { + List(namespace string, selector labels.Selector) (ret []*v1.StorageClass, err error) + Get(namespace, name string) (*v1.StorageClass, error) +} + +type StorageClassController interface { + Generic() controller.GenericController + Informer() cache.SharedIndexInformer + Lister() StorageClassLister + AddHandler(ctx context.Context, name string, handler StorageClassHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StorageClassHandlerFunc) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, handler StorageClassHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, handler StorageClassHandlerFunc) + Enqueue(namespace, name string) + EnqueueAfter(namespace, name string, after time.Duration) +} + +type StorageClassInterface interface { + ObjectClient() *objectclient.ObjectClient + Create(*v1.StorageClass) (*v1.StorageClass, error) + GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.StorageClass, error) + Get(name string, opts metav1.GetOptions) (*v1.StorageClass, error) + Update(*v1.StorageClass) (*v1.StorageClass, error) + Delete(name string, options *metav1.DeleteOptions) error + DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error + List(opts metav1.ListOptions) (*v1.StorageClassList, error) + ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StorageClassList, error) + Watch(opts metav1.ListOptions) (watch.Interface, error) + DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error + Controller() StorageClassController + AddHandler(ctx context.Context, name string, sync StorageClassHandlerFunc) + AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StorageClassHandlerFunc) + AddLifecycle(ctx context.Context, name string, lifecycle StorageClassLifecycle) + AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle StorageClassLifecycle) + AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync StorageClassHandlerFunc) + AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync StorageClassHandlerFunc) + AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle StorageClassLifecycle) + AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle StorageClassLifecycle) +} + +type storageClassLister struct { + ns string + controller *storageClassController +} + +func (l *storageClassLister) List(namespace string, selector labels.Selector) (ret []*v1.StorageClass, err error) { + if namespace == "" { + namespace = l.ns + } + err = cache.ListAllByNamespace(l.controller.Informer().GetIndexer(), namespace, selector, func(obj interface{}) { + ret = append(ret, obj.(*v1.StorageClass)) + }) + return +} + +func (l *storageClassLister) Get(namespace, name string) (*v1.StorageClass, error) { + var key string + if namespace != "" { + key = namespace + "/" + name + } else { + key = name + } + obj, exists, err := l.controller.Informer().GetIndexer().GetByKey(key) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(schema.GroupResource{ + Group: StorageClassGroupVersionKind.Group, + Resource: StorageClassGroupVersionResource.Resource, + }, key) + } + return obj.(*v1.StorageClass), nil +} + +type storageClassController struct { + ns string + controller.GenericController +} + +func (c *storageClassController) Generic() controller.GenericController { + return c.GenericController +} + +func (c *storageClassController) Lister() StorageClassLister { + return &storageClassLister{ + ns: c.ns, + controller: c, + } +} + +func (c *storageClassController) AddHandler(ctx context.Context, name string, handler StorageClassHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StorageClass); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *storageClassController) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, handler StorageClassHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StorageClass); ok { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *storageClassController) AddClusterScopedHandler(ctx context.Context, name, cluster string, handler StorageClassHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StorageClass); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +func (c *storageClassController) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, cluster string, handler StorageClassHandlerFunc) { + c.GenericController.AddHandler(ctx, name, func(key string, obj interface{}) (interface{}, error) { + if !enabled() { + return nil, nil + } else if obj == nil { + return handler(key, nil) + } else if v, ok := obj.(*v1.StorageClass); ok && controller.ObjectInCluster(cluster, obj) { + return handler(key, v) + } else { + return nil, nil + } + }) +} + +type storageClassFactory struct { +} + +func (c storageClassFactory) Object() runtime.Object { + return &v1.StorageClass{} +} + +func (c storageClassFactory) List() runtime.Object { + return &v1.StorageClassList{} +} + +func (s *storageClassClient) Controller() StorageClassController { + genericController := controller.NewGenericController(s.ns, StorageClassGroupVersionKind.Kind+"Controller", + s.client.controllerFactory.ForResourceKind(StorageClassGroupVersionResource, StorageClassGroupVersionKind.Kind, false)) + + return &storageClassController{ + ns: s.ns, + GenericController: genericController, + } +} + +type storageClassClient struct { + client *Client + ns string + objectClient *objectclient.ObjectClient + controller StorageClassController +} + +func (s *storageClassClient) ObjectClient() *objectclient.ObjectClient { + return s.objectClient +} + +func (s *storageClassClient) Create(o *v1.StorageClass) (*v1.StorageClass, error) { + obj, err := s.objectClient.Create(o) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) Get(name string, opts metav1.GetOptions) (*v1.StorageClass, error) { + obj, err := s.objectClient.Get(name, opts) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) GetNamespaced(namespace, name string, opts metav1.GetOptions) (*v1.StorageClass, error) { + obj, err := s.objectClient.GetNamespaced(namespace, name, opts) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) Update(o *v1.StorageClass) (*v1.StorageClass, error) { + obj, err := s.objectClient.Update(o.Name, o) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) UpdateStatus(o *v1.StorageClass) (*v1.StorageClass, error) { + obj, err := s.objectClient.UpdateStatus(o.Name, o) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) Delete(name string, options *metav1.DeleteOptions) error { + return s.objectClient.Delete(name, options) +} + +func (s *storageClassClient) DeleteNamespaced(namespace, name string, options *metav1.DeleteOptions) error { + return s.objectClient.DeleteNamespaced(namespace, name, options) +} + +func (s *storageClassClient) List(opts metav1.ListOptions) (*v1.StorageClassList, error) { + obj, err := s.objectClient.List(opts) + return obj.(*v1.StorageClassList), err +} + +func (s *storageClassClient) ListNamespaced(namespace string, opts metav1.ListOptions) (*v1.StorageClassList, error) { + obj, err := s.objectClient.ListNamespaced(namespace, opts) + return obj.(*v1.StorageClassList), err +} + +func (s *storageClassClient) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return s.objectClient.Watch(opts) +} + +// Patch applies the patch and returns the patched deployment. +func (s *storageClassClient) Patch(o *v1.StorageClass, patchType types.PatchType, data []byte, subresources ...string) (*v1.StorageClass, error) { + obj, err := s.objectClient.Patch(o.Name, o, patchType, data, subresources...) + return obj.(*v1.StorageClass), err +} + +func (s *storageClassClient) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error { + return s.objectClient.DeleteCollection(deleteOpts, listOpts) +} + +func (s *storageClassClient) AddHandler(ctx context.Context, name string, sync StorageClassHandlerFunc) { + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *storageClassClient) AddFeatureHandler(ctx context.Context, enabled func() bool, name string, sync StorageClassHandlerFunc) { + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *storageClassClient) AddLifecycle(ctx context.Context, name string, lifecycle StorageClassLifecycle) { + sync := NewStorageClassLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddHandler(ctx, name, sync) +} + +func (s *storageClassClient) AddFeatureLifecycle(ctx context.Context, enabled func() bool, name string, lifecycle StorageClassLifecycle) { + sync := NewStorageClassLifecycleAdapter(name, false, s, lifecycle) + s.Controller().AddFeatureHandler(ctx, enabled, name, sync) +} + +func (s *storageClassClient) AddClusterScopedHandler(ctx context.Context, name, clusterName string, sync StorageClassHandlerFunc) { + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *storageClassClient) AddClusterScopedFeatureHandler(ctx context.Context, enabled func() bool, name, clusterName string, sync StorageClassHandlerFunc) { + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} + +func (s *storageClassClient) AddClusterScopedLifecycle(ctx context.Context, name, clusterName string, lifecycle StorageClassLifecycle) { + sync := NewStorageClassLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedHandler(ctx, name, clusterName, sync) +} + +func (s *storageClassClient) AddClusterScopedFeatureLifecycle(ctx context.Context, enabled func() bool, name, clusterName string, lifecycle StorageClassLifecycle) { + sync := NewStorageClassLifecycleAdapter(name+"_"+clusterName, true, s, lifecycle) + s.Controller().AddClusterScopedFeatureHandler(ctx, enabled, name, clusterName, sync) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_lifecycle_adapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_lifecycle_adapter.go new file mode 100644 index 0000000..db5f9c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/generated/norman/storage.k8s.io/v1/zz_generated_storage_class_lifecycle_adapter.go @@ -0,0 +1,67 @@ +package v1 + +import ( + "github.com/rancher/norman/lifecycle" + "github.com/rancher/norman/resource" + "k8s.io/api/storage/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type StorageClassLifecycle interface { + Create(obj *v1.StorageClass) (runtime.Object, error) + Remove(obj *v1.StorageClass) (runtime.Object, error) + Updated(obj *v1.StorageClass) (runtime.Object, error) +} + +type storageClassLifecycleAdapter struct { + lifecycle StorageClassLifecycle +} + +func (w *storageClassLifecycleAdapter) HasCreate() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasCreate() +} + +func (w *storageClassLifecycleAdapter) HasFinalize() bool { + o, ok := w.lifecycle.(lifecycle.ObjectLifecycleCondition) + return !ok || o.HasFinalize() +} + +func (w *storageClassLifecycleAdapter) Create(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Create(obj.(*v1.StorageClass)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *storageClassLifecycleAdapter) Finalize(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Remove(obj.(*v1.StorageClass)) + if o == nil { + return nil, err + } + return o, err +} + +func (w *storageClassLifecycleAdapter) Updated(obj runtime.Object) (runtime.Object, error) { + o, err := w.lifecycle.Updated(obj.(*v1.StorageClass)) + if o == nil { + return nil, err + } + return o, err +} + +func NewStorageClassLifecycleAdapter(name string, clusterScoped bool, client StorageClassInterface, l StorageClassLifecycle) StorageClassHandlerFunc { + if clusterScoped { + resource.PutClusterScoped(StorageClassGroupVersionResource) + } + adapter := &storageClassLifecycleAdapter{lifecycle: l} + syncFn := lifecycle.NewObjectLifecycleAdapter(name, clusterScoped, adapter, client.ObjectClient()) + return func(key string, obj *v1.StorageClass) (runtime.Object, error) { + newObj, err := syncFn(key, obj) + if o, ok := newObj.(runtime.Object); ok { + return o, err + } + return nil, err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git.go new file mode 100644 index 0000000..815eae7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git.go @@ -0,0 +1,97 @@ +package git + +import ( + "bytes" + "fmt" + "net/url" + "os/exec" + "regexp" + "strings" + + "github.com/pkg/errors" +) + +var ( + controlChars = regexp.MustCompile("[[:cntrl:]]") + controlEncoded = regexp.MustCompile("%[0-1][0-9,a-f,A-F]") +) + +func Clone(path, url, branch string) error { + if err := ValidateURL(url); err != nil { + return err + } + return runcmd("git", "clone", "-b", branch, "--single-branch", "--", url, path) +} + +func Update(path, commit string) error { + if err := runcmd("git", "-C", path, "fetch"); err != nil { + return err + } + return runcmd("git", "-C", path, "checkout", commit) +} + +func HeadCommit(path string) (string, error) { + cmd := exec.Command("git", "-C", path, "rev-parse", "HEAD") + output, err := cmd.Output() + return strings.Trim(string(output), "\n"), err +} + +func RemoteBranchHeadCommit(url, branch string) (string, error) { + if err := ValidateURL(url); err != nil { + return "", err + } + cmd := exec.Command("git", "ls-remote", "--", url, branch) + output, err := cmd.CombinedOutput() + if err != nil { + return "", errors.Wrap(err, string(output)) + } + parts := strings.Split(string(output), "\t") + if len(parts) > 0 && len(parts[0]) > 0 { + return parts[0], nil + } + return "", fmt.Errorf("no commit found for url %s branch %s", branch, url) +} + +func IsValid(url string) bool { + if err := ValidateURL(url); err != nil { + return false + } + err := runcmd("git", "ls-remote", "--", url) + return err == nil +} + +func runcmd(name string, arg ...string) error { + cmd := exec.Command(name, arg...) + bufErr := &bytes.Buffer{} + cmd.Stderr = bufErr + if err := cmd.Run(); err != nil { + return errors.Wrap(err, bufErr.String()) + } + return nil +} + +// FormatURL generates request url if is a private catalog +func FormatURL(pathURL, username, password string) string { + if len(username) > 0 && len(password) > 0 { + if u, err := url.Parse(pathURL); err == nil { + u.User = url.UserPassword(username, password) + return u.String() + } + } + return pathURL +} + +func CloneWithDepth(path, url, branch string, depth int) error { + if err := ValidateURL(url); err != nil { + return err + } + return runcmd("git", "clone", "-b", branch, "--single-branch", fmt.Sprintf("--depth=%v", depth), "--", url, path) +} + +func ValidateURL(pathURL string) error { + // Don't allow a URL containing control characters, standard or url-encoded + if controlChars.FindStringIndex(pathURL) != nil || controlEncoded.FindStringIndex(pathURL) != nil { + return errors.New("Invalid characters in url") + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git_test.go new file mode 100644 index 0000000..01586d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/git/git_test.go @@ -0,0 +1,311 @@ +package git + +import ( + "fmt" + "io" + "os" + "path/filepath" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" +) + +const fakeCommit = "9p8pvpkuorqgf7lq9nrhyp3cc0xh5wejf2g5z1s6" +const validUrl = "git@github.com:rancher/rancher.git" +const invalidUrl = "%1A invalid not real url" +const testPath = "pkg/git/git_test.go" + +func TestClone(t *testing.T) { + tests := []struct { + name string + url string + commandOutput string + commandExitCode int + wantErr bool + }{ + { + name: "basic clone", + url: validUrl, + commandOutput: "", + commandExitCode: 0, + wantErr: false, + }, + { + name: "clone, invalid url", + url: invalidUrl, + commandOutput: "", + commandExitCode: 0, + wantErr: true, + }, + { + name: "valid url command failed", + url: validUrl, + commandOutput: "no such repo", + commandExitCode: -128, + wantErr: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + setTestOutput(t, test.commandOutput) + setTestExitCode(t, test.commandExitCode) + err := setMockGitExecutable(t) + assert.NoError(t, err, "got error when setting up mock git executable") + err = Clone("rancher", test.url, "main") + if test.wantErr { + assert.Error(t, err, "expected an error but did not get one") + } else { + assert.NoError(t, err, "got an error but did not expect one") + } + }) + } +} + +func TestRemoteBranchHeadCommit(t *testing.T) { + tests := []struct { + name string + url string + branch string + commandOutput string + commandExitCode int + wantErr bool + desiredOutput string + }{ + { + name: "basic remote", + url: validUrl, + branch: "master", + commandOutput: fakeCommit + "\t" + "refs/head/master", + commandExitCode: 0, + wantErr: false, + desiredOutput: fakeCommit, + }, + { + name: "invalid url", + url: invalidUrl, + branch: "master", + commandOutput: "Function not expected to be called", + commandExitCode: 0, + wantErr: true, + desiredOutput: "", + }, + { + name: "command fails", + url: validUrl, + branch: "master", + commandOutput: "failed to run command", + commandExitCode: -1, + wantErr: true, + desiredOutput: "", + }, + { + name: "bad data returned from command", + url: validUrl, + branch: "master", + commandOutput: "", + commandExitCode: 0, + wantErr: true, + desiredOutput: "", + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + setTestOutput(t, test.commandOutput) + setTestExitCode(t, test.commandExitCode) + err := setMockGitExecutable(t) + assert.NoError(t, err, "got error when setting up mock git executable") + output, err := RemoteBranchHeadCommit(test.url, test.branch) + if test.wantErr { + assert.Error(t, err, "expected an error but did not get one") + } else { + assert.NoError(t, err, "got an error but did not expect one") + } + assert.Equal(t, test.desiredOutput, output, "output was not as expected") + }) + } +} + +func TestIsValid(t *testing.T) { + tests := []struct { + name string + url string + commandOutput string + commandExitCode int + wantOutput bool + }{ + { + name: "valid url", + url: validUrl, + commandOutput: fakeCommit + "\t" + "refs/head/master", + commandExitCode: 0, + wantOutput: true, + }, + { + name: "valid url, failed command", + url: validUrl, + commandOutput: "ref unavailable", + commandExitCode: -1, + wantOutput: false, + }, + { + name: "invalid url, bad characters", + url: invalidUrl, + commandOutput: "Function not expected to be called", + commandExitCode: 0, + wantOutput: false, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + setTestOutput(t, test.commandOutput) + setTestExitCode(t, test.commandExitCode) + err := setMockGitExecutable(t) + assert.NoError(t, err, "got error when setting up mock git executable") + isValid := IsValid(test.url) + assert.Equal(t, test.wantOutput, isValid, "did not get expected output") + }) + } +} + +func TestCloneWithDepth(t *testing.T) { + tests := []struct { + name string + path string + url string + branch string + depth int + commandOutput string + commandExitCode int + wantError bool + }{ + { + name: "basic clone", + path: "rancher", + url: validUrl, + branch: "master", + depth: 1, + commandExitCode: 0, + commandOutput: "cloning into repo", + wantError: false, + }, + { + name: "invalid url", + path: "rancher", + url: invalidUrl, + branch: "master", + depth: 1, + commandExitCode: 0, + commandOutput: "Function not expected to be called", + wantError: true, + }, + { + name: "command error", + path: "rancher", + url: validUrl, + branch: "master", + depth: 1, + commandOutput: "could not run command", + commandExitCode: -1, + wantError: true, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + setTestOutput(t, test.commandOutput) + setTestExitCode(t, test.commandExitCode) + err := setMockGitExecutable(t) + assert.NoError(t, err, "got error when setting up mock git executable") + err = CloneWithDepth(test.path, test.url, test.branch, test.depth) + if test.wantError { + assert.Errorf(t, err, "wanted an error but did not get one") + } else { + assert.NoError(t, err, "got an error but did not want one") + } + }) + } +} + +// Function used when you need control of test main for various reasons (see pkg/git/git_test.go for an example of +// mocking calls to os.Exec) +func TestMain(m *testing.M) { + // the path to your test. You should set this in your individual test so that you don't impact the behavior of + // other's tests + testPath := os.Getenv("TEST_PATH") + switch testPath { + case "": + os.Exit(m.Run()) + case "pkg/git/git_test.go": + mockGitTestBehavior() + default: + fmt.Printf("Undefined behavior for TEST_PATH of %s", testPath) + os.Exit(-1) + } +} + +// mockGitTestBehavior provides mocks for pkg/git/git_test.go +func mockGitTestBehavior() { + testOutput := os.Getenv("TEST_OUTPUT") + testExitCode := os.Getenv("TEST_EXIT_CODE") + exitCode, err := strconv.Atoi(testExitCode) + if err != nil { + _, logErr := fmt.Fprintf(os.Stderr, "Unable to convert %s to an int - exit code must be an int", testExitCode) + if logErr != nil { + fmt.Printf("unable to write to stderr %s", logErr) + os.Exit(-2) + } + os.Exit(-1) + } + if exitCode != 0 { + // non 0 exit code indicates and error, so send requested output to stderr + _, err = fmt.Fprint(os.Stderr, testOutput) + if err != nil { + fmt.Printf("unable to print to stderr %s \n", err) + } + } else { + fmt.Print(testOutput) + } + os.Exit(exitCode) +} + +// setMockExecutable copies the test executable and adds it to PATH as git, so that when os.Exec calls out for git, +// it interacts with the behavior defined in main_test.go +func setMockGitExecutable(t *testing.T) error { + t.Setenv("TEST_PATH", testPath) + mainExec, err := os.Executable() + if err != nil { + return err + } + // add the temp directory of the test to the path, so that the mock git executable can be discovered + tempDir := t.TempDir() + path := os.Getenv("PATH") + t.Setenv("PATH", tempDir+string(os.PathListSeparator)+path) + // copy the main test executable to the new temp directory under the name of git + testExecFile, err := os.Open(mainExec) + defer testExecFile.Close() + if err != nil { + return err + } + testGitExec, err := os.Create(filepath.Join(tempDir, "git")) + defer testGitExec.Close() + if err != nil { + return err + } + _, err = io.Copy(testGitExec, testExecFile) + if err != nil { + return err + } + return os.Chmod(testGitExec.Name(), 755) +} + +func setTestOutput(t *testing.T, output string) { + t.Setenv("TEST_OUTPUT", output) +} + +func setTestExitCode(t *testing.T, code int) { + t.Setenv("TEST_EXIT_CODE", strconv.Itoa(code)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm.go new file mode 100644 index 0000000..cbec664 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm.go @@ -0,0 +1,659 @@ +package helm + +import ( + "archive/tar" + "compress/gzip" + "crypto/md5" + "encoding/binary" + "encoding/hex" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "os" + "path" + "path/filepath" + "sort" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/git" + + "github.com/rancher/norman/controller" + mgmtv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + nsutil "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + + "github.com/blang/semver" + "github.com/moby/locker" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +var ( + httpTimeout = time.Second * 30 + httpClient = &http.Client{ + Timeout: httpTimeout, + } + uuid = settings.InstallUUID.Get() + Locker = locker.New() + CatalogCache = filepath.Join("management-state", "catalog-cache") + IconCache = filepath.Join(CatalogCache, ".icon-cache") + InternalCatalog = filepath.Join("..", "rancher-data", "local-catalogs") +) + +type Helm struct { + LocalPath string + IconPath string + catalogName string + Hash string + Kind string + url string + branch string + username string + password string + lastCommit string +} + +func (h *Helm) lock() { + Locker.Lock(h.Hash) +} + +func (h *Helm) unlock() { + Locker.Unlock(h.Hash) +} + +func (h *Helm) lockAndVerifyCachePath() error { + h.lock() + if _, err := os.Stat(h.LocalPath); os.IsNotExist(err) { + return err + } + if _, err := os.Stat(h.IconPath); os.IsNotExist(err) { + return err + } + return nil +} + +func (h *Helm) request(pathURL string) (*http.Response, error) { + baseEndpoint, err := url.Parse(pathURL) + if err != nil { + return nil, err + } + if !baseEndpoint.IsAbs() { + helmURLstring := h.url + if !strings.HasSuffix(helmURLstring, "/") { + helmURLstring = helmURLstring + "/" + } + helmURL, err := url.Parse(helmURLstring) + if err != nil { + return nil, err + } + baseEndpoint = helmURL.ResolveReference(baseEndpoint) + } + + if err := git.ValidateURL(baseEndpoint.String()); err != nil { + return nil, err + } + + if len(h.username) > 0 && len(h.password) > 0 { + baseEndpoint.User = url.UserPassword(h.username, h.password) + } + req, err := http.NewRequest(http.MethodGet, baseEndpoint.String(), nil) + if err != nil { + return nil, err + } + return httpClient.Do(req) +} + +func (h *Helm) downloadIndex(indexURL string) (*RepoIndex, error) { + indexURL = strings.TrimSuffix(indexURL, "/") + indexURL = indexURL + "/index.yaml" + resp, err := h.request(indexURL) + if err != nil { + if e, ok := err.(net.Error); ok && e.Timeout() { + return nil, errors.Errorf("Timeout in HTTP GET to [%s], did not respond in %s", indexURL, httpTimeout) + } + return nil, errors.Errorf("Error in HTTP GET to [%s], error: %s", indexURL, err) + } + defer resp.Body.Close() + + // only return forgot error if status code is unauthorized. + if resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusUnauthorized { + return nil, &controller.ForgetError{Err: errors.Errorf("Unexpected HTTP status code %d from [%s], expected 200", resp.StatusCode, indexURL)} + } + + if resp.StatusCode != http.StatusOK { + return nil, errors.Errorf("Unexpected HTTP status code %d from [%s], expected 200", resp.StatusCode, indexURL) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.Errorf("Error while reading response from [%s], error: %s", indexURL, err) + } + + sum := md5.Sum(body) + hash := hex.EncodeToString(sum[:]) + + helmRepoIndex := &RepoIndex{ + IndexFile: &IndexFile{}, + Hash: hash, + } + err = yaml.Unmarshal(body, helmRepoIndex.IndexFile) + if err != nil { + return nil, errors.Errorf("error unmarshalling response from [%s]", indexURL) + } + return helmRepoIndex, nil +} + +func (h *Helm) saveIndex(index *RepoIndex) error { + fileBytes, err := yaml.Marshal(index.IndexFile) + if err != nil { + return err + } + + indexPath := filepath.Join(h.LocalPath, "index.yaml") + return ioutil.WriteFile(indexPath, fileBytes, 0644) +} + +func (h *Helm) LoadIndex() (*RepoIndex, error) { + err := h.lockAndVerifyCachePath() + defer h.unlock() + if err != nil { + return nil, err + } + + indexPath := filepath.Join(h.LocalPath, "index.yaml") + + body, err := ioutil.ReadFile(indexPath) + if os.IsNotExist(err) { + return h.buildIndex() + } + if err != nil { + return nil, err + } + + sum := md5.Sum(body) + hash := hex.EncodeToString(sum[:]) + + helmRepoIndex := &RepoIndex{ + IndexFile: &IndexFile{}, + Hash: hash, + } + return helmRepoIndex, yaml.Unmarshal(body, helmRepoIndex.IndexFile) +} + +func (h *Helm) fetchTgz(helmURL string) ([]v32.File, error) { + var files []v32.File + logrus.Debugf("Helm fetching file %s", helmURL) + + resp, err := h.request(helmURL) + if err != nil || resp.StatusCode > 400 { + if e, ok := err.(net.Error); ok && e.Timeout() { + return nil, errors.Errorf("Timeout in HTTP GET to [%s], did not respond in %s", helmURL, httpTimeout) + } + if err == nil { + return nil, errors.Errorf("Error in HTTP GET of [%s], received: %s", helmURL, resp.Status) + } + return nil, errors.Errorf("Error in HTTP GET of [%s], error: %s", helmURL, err) + } + defer resp.Body.Close() + + gzf, err := gzip.NewReader(resp.Body) + if err != nil { + return nil, err + } + defer gzf.Close() + + tarReader := tar.NewReader(gzf) + for { + header, err := tarReader.Next() + if err == io.EOF { + break + } + + if err != nil { + return nil, err + } + + switch header.Typeflag { + case tar.TypeDir: + continue + case tar.TypeReg: + fallthrough + case tar.TypeRegA: + name := header.Name + contents, err := ioutil.ReadAll(tarReader) + if err != nil { + return nil, err + } + files = append(files, v32.File{ + Name: name, + Contents: string(contents), + }) + } + } + + return files, nil +} + +func (h *Helm) FetchLocalFiles(version *ChartVersion) ([]v32.File, error) { + err := h.lockAndVerifyCachePath() + defer h.unlock() + if err != nil { + return nil, err + } + + if len(version.LocalFiles) == 0 && len(version.URLs) == 0 { + return nil, errors.New("No files or urls provided for helm fetch") + } + + var files []v32.File + for _, file := range version.LocalFiles { + newFile, err := h.loadFile(version, file) + if err != nil { + return nil, err + } + files = append(files, *newFile) + } + + return files, nil +} + +func (h *Helm) loadChartFiles(versionDir, prefix string, filters []string) (map[string]string, error) { + filemap := map[string]string{} + versionPath := filepath.Join(h.LocalPath, versionDir) + err := filepath.Walk(versionPath, func(filename string, info os.FileInfo, err error) error { + if err != nil || info.IsDir() { + return err + } + + relPath, err := filepath.Rel(versionPath, filename) + if err != nil { + return err + } + name := path.Join(prefix, filepath.ToSlash(relPath)) + if !filterMatch(name, filters) { + return nil + } + + content, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + filemap[name] = string(content) + return nil + }) + return filemap, err +} + +func (h *Helm) LoadChart(templateVersion *v32.TemplateVersionSpec, filters []string) (map[string]string, error) { + err := h.lockAndVerifyCachePath() + defer h.unlock() + if err != nil { + return nil, err + } + + version := templateVersion.Version + versionDir := templateVersion.VersionDir + versionName := templateVersion.VersionName + versionURLs := templateVersion.VersionURLs + + // Read Helm files from Git repo + if versionDir != "" { + return h.loadChartFiles(versionDir, versionName, filters) + } + // Fetch Helm URLs or use cached data + if len(versionURLs) > 0 { + return h.loadChartURLs(version, versionName, versionURLs, filters) + } + + return nil, errors.New("Template version has no URLs or directory for chart to load from") +} + +func (h *Helm) fetchAndCacheURLs(versionPath, versionName string, versionURLs, filters []string) (map[string]string, error) { + filemap := map[string]string{} + files, err := h.fetchURLs(versionURLs) + if err != nil { + return nil, err + } + // existence of this file indicates the cache exists + if err := os.MkdirAll(versionPath, 0755); err != nil { + return nil, err + } + for _, file := range files { + filename, err := filepath.Rel(versionName, file.Name) + if err != nil { + return nil, err + } + fp := filepath.Join(versionPath, filename) + if err := os.MkdirAll(filepath.Dir(fp), 0755); err != nil { + return nil, err + } + if err := ioutil.WriteFile(fp, []byte(file.Contents), 0644); err != nil { + return nil, err + } + if filterMatch(file.Name, filters) { + filemap[file.Name] = file.Contents + } + } + return filemap, nil +} + +func (h *Helm) loadChartURLs(version, versionName string, versionURLs, filters []string) (map[string]string, error) { + versionDir := filepath.Join(versionName, version) + versionPath := filepath.Join(h.LocalPath, versionDir) + if _, err := os.Stat(versionPath); os.IsNotExist(err) { + return h.fetchAndCacheURLs(versionPath, versionName, versionURLs, filters) + } + return h.loadChartFiles(versionDir, versionName, filters) +} + +func filterMatch(match string, filters []string) bool { + if len(filters) == 0 { + return true + } + for _, filter := range filters { + if strings.EqualFold(match, filter) { + return true + } + } + return false +} + +func (h *Helm) fetchURLs(urls []string) ([]v32.File, error) { + var ( + errs []error + ) + for _, url := range urls { + newFiles, err := h.fetchTgz(url) + if err == nil { + return newFiles, nil + } + errs = append(errs, err) + } + return nil, errors.Errorf("Error fetching helm URLs: %v", errs) +} + +func (h *Helm) loadFile(version *ChartVersion, filename string) (*v32.File, error) { + data, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + versionPath := filepath.Join(h.LocalPath, version.Dir) + relPath, err := filepath.Rel(versionPath, filename) + if err != nil { + return nil, err + } + + return &v32.File{ + Name: path.Join(version.Name, filepath.ToSlash(relPath)), + Contents: string(data), + }, nil +} + +func (h *Helm) buildIndex() (*RepoIndex, error) { + index := &RepoIndex{ + IndexFile: &IndexFile{ + Entries: map[string]ChartVersions{}, + }, + } + + filepath.Walk(h.LocalPath, func(path string, info os.FileInfo, err error) error { + if err != nil || info.IsDir() { + return err + } + if !strings.EqualFold(info.Name(), "Chart.yaml") { + return nil + } + + version := &ChartVersion{} + content, err := ioutil.ReadFile(path) + if err != nil { + return err + } + if err := yaml.Unmarshal(content, version); err != nil { + return err + } + + dir := filepath.Dir(path) + relDir, err := filepath.Rel(h.LocalPath, dir) + if err != nil { + return err + } + version.Dir = relDir + digest := md5.New() + + filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil || info.IsDir() { + return err + } + + version.LocalFiles = append(version.LocalFiles, path) + digest.Write([]byte(path)) + + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, uint64(info.Size())) + digest.Write(b) + + binary.LittleEndian.PutUint64(b, uint64(info.ModTime().Second())) + digest.Write(b) + + return nil + }) + + version.Digest = hex.EncodeToString(digest.Sum(nil)) + index.IndexFile.Entries[version.Name] = append(index.IndexFile.Entries[version.Name], version) + + return filepath.SkipDir + }) + + for _, versions := range index.IndexFile.Entries { + sort.Slice(versions, func(i, j int) bool { + left, err := semver.ParseTolerant(versions[i].Version) + if err != nil { + return false + } + + right, err := semver.ParseTolerant(versions[j].Version) + if err != nil { + return false + } + + // reverse sort + return right.LT(left) + }) + } + + return index, nil +} + +func (h *Helm) loadCachedIcon(iconURL string) ([]byte, string, string, error) { + hashName := md5Hash(iconURL) + matches, err := filepath.Glob(filepath.Join(h.IconPath, hashName+".*")) + if err != nil { + return nil, "", "", err + } + if len(matches) != 1 { + return nil, "", "", errors.New("Multiple icon cache matches") + } + filename := matches[0] + iconBytes, err := ioutil.ReadFile(filename) + if err != nil { + return nil, "", "", err + } + cacheFile := filepath.Base(filename) + return iconBytes, cacheFile, iconURL, nil +} + +// cacheIcon create the cache data & filename from the given parameters. If extension is "" then it will craft one +func (h *Helm) cacheIcon(iconURL, extension string, iconBytes []byte) (string, error) { + if extension == "" { + extension = craftExtension(iconURL) + } + + hashName := md5Hash(iconURL) + extension + if filepath.Ext(hashName) == "" { + logrus.Debugf("No extension for: %s", hashName) + } + iconCacheFile := filepath.Join(h.IconPath, hashName) + if err := ioutil.WriteFile(iconCacheFile, iconBytes, 0644); err != nil { + return "", err + } + return hashName, nil +} + +// craftExtension attempts to parse the given iconURL to create an appropriate extension +func craftExtension(iconURL string) string { + parsedURL, err := url.Parse(iconURL) + var filename string + if err == nil { + if parsedURL.Path != "" { + filename = path.Base(parsedURL.Path) + } else { + filename = parsedURL.Host + } + } else { + logrus.Debugf("url.Parse(%s) error [%s]", iconURL, err) + parts := strings.Split(iconURL, "/") + filename = parts[len(parts)-1] + } + return filepath.Ext(filename) + +} + +func (h *Helm) iconFromFile(iconURL, versionDir string) ([]byte, string, string, error) { + filename := strings.TrimPrefix(iconURL, "file://") + iconPath := filepath.Join(h.LocalPath, versionDir) + iconFile := filepath.Join(iconPath, filename) + if !strings.HasPrefix(iconFile, h.LocalPath) { + return nil, "", "", errors.Errorf("Won't read [%s], outside of tmp path [%s]", iconFile, h.LocalPath) + } + + iconBytes, err := ioutil.ReadFile(iconFile) + if err != nil { + return nil, "", "", err + } + newPath, err := filepath.Rel(h.LocalPath, iconFile) + if err != nil { + return nil, "", "", err + } + + iconURL = "file://" + newPath + cacheFile, err := h.cacheIcon(iconURL, "", iconBytes) + if err != nil { + return nil, "", "", err + } + + return iconBytes, cacheFile, iconURL, nil +} + +func (h *Helm) fetchIcon(iconURL, versionDir string) ([]byte, string, string, error) { + if strings.HasPrefix(iconURL, "file:") { + return h.iconFromFile(iconURL, versionDir) + } + if strings.HasPrefix(iconURL, "http:") || strings.HasPrefix(iconURL, "https:") { + return nil, "", iconURL, nil + } + return nil, "", "", errors.Errorf("unknown file type [%s]", iconURL) +} + +func (h *Helm) iconFromCache(cacheFile string) ([]byte, error) { + filename := filepath.Join(h.IconPath, cacheFile) + if !strings.HasPrefix(filename, h.IconPath) { + return nil, errors.Errorf("Icon file [%s] outside of icon path [%s]", filename, h.IconPath) + } + return ioutil.ReadFile(filename) +} + +func (h *Helm) LoadIcon(cacheFile, iconURL string) ([]byte, error) { + err := h.lockAndVerifyCachePath() + defer h.unlock() + if err != nil { + return nil, err + } + + if iconBytes, err := h.iconFromCache(cacheFile); err == nil { + return iconBytes, nil + } + iconBytes, _, _, err := h.fetchIcon(iconURL, "") + return iconBytes, err +} + +func (h *Helm) Icon(versions ChartVersions) (string, string, error) { + err := h.lockAndVerifyCachePath() + defer h.unlock() + if err != nil { + return "", "", err + } + + failed := map[string]bool{} + for _, version := range versions { + if version.Icon == "" || failed[version.Icon] { + continue + } + + _, filename, url, err := h.fetchIcon(version.Icon, version.Dir) + if err != nil { + logrus.Infof("Helm icon error: %s", err) + failed[version.Icon] = true + continue + } + + return filename, url, nil + } + + // avoid catalog reload if icon fetch fails + return "", "", nil +} + +func SplitNamespaceAndName(id string) (string, string) { + parts := strings.SplitN(id, ":", 2) + if len(parts) < 2 { + return "", id + } + return parts[0], parts[1] +} + +func GetCatalog( + catalogType, namespace, catalogName string, + catalogLister v3.CatalogLister, + clusterCatalogLister v3.ClusterCatalogLister, + projectCatalogLister v3.ProjectCatalogLister, +) (*v3.Catalog, error) { + if catalogType == "" { + if namespace == "" || namespace == nsutil.GlobalNamespace { + catalogType = mgmtv3.CatalogType + } else if strings.HasPrefix(namespace, "p-") { + logrus.Warnf("Defaulting catalog type to project for [%s/%s]", namespace, catalogName) + catalogType = mgmtv3.ProjectCatalogType + } else { + logrus.Warnf("Defaulting catalog type to cluster for [%s/%s]", namespace, catalogName) + catalogType = mgmtv3.ClusterCatalogType + } + } + switch catalogType { + case mgmtv3.CatalogType: + catalog, err := catalogLister.Get("", catalogName) + if err != nil { + return nil, err + } + return catalog, nil + case mgmtv3.ClusterCatalogType: + clusterCatalog, err := clusterCatalogLister.Get(namespace, catalogName) + if err != nil { + return nil, err + } + return &clusterCatalog.Catalog, nil + case mgmtv3.ProjectCatalogType: + projectCatalog, err := projectCatalogLister.Get(namespace, catalogName) + if err != nil { + return nil, err + } + return &projectCatalog.Catalog, nil + } + return nil, errors.Errorf("Unknown catalog type in namespace [%s] and name [%s]", namespace, catalogName) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm_test.go new file mode 100644 index 0000000..6f28534 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/helm_test.go @@ -0,0 +1,48 @@ +package helm + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_craftExtension(t *testing.T) { + + tests := []struct { + name string + iconURL string + want string + }{ + { + "file case", + "file://xss.svg", + ".svg", + }, + { + "web case", + "https://raw.githubusercontent.com/JFrogDev/artifactory-dcos/master/images/jfrog_med.png", + ".png", + }, + { + "library file case", + "file://charts/cert-manager/letsencrypt-logo-horizontal.svg", + ".svg", + }, + { + "empty case", + "", + "", + }, + { + "no suffix", + "https://rawgithubusercontent.com/JFrogDev/artifactory-dcos/master/images/jfrog_med", + "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := craftExtension(tt.iconURL) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/setup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/setup.go new file mode 100644 index 0000000..b967bf9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/setup.go @@ -0,0 +1,331 @@ +package helm + +import ( + "crypto/md5" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + + "github.com/pkg/errors" + secretmigrator "github.com/rancher/rancher/pkg/controllers/management/secretmigrator/catalog" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/git" + "github.com/sirupsen/logrus" +) + +const ( + KindHelmGit = "helm:git" + KindHelmHTTP = "helm:http" + KindHelmInternal = "helm:internal" +) + +var ( + validCatalogKind = map[string]bool{ + KindHelmGit: true, + KindHelmHTTP: true, + KindHelmInternal: true, + } +) + +func New(catalog *v3.Catalog, secretLister v1.SecretLister) (*Helm, error) { + h, err := NewNoUpdate(catalog, secretLister) + if err != nil { + return nil, err + } + _, err = h.Update(false) + return h, err +} + +func NewNoUpdate(catalog *v3.Catalog, secretLister v1.SecretLister) (*Helm, error) { + if catalog == nil || catalog.Name == "" { + return nil, errors.New("Catalog is not defined for helm") + } + return newCache(catalog, secretLister) +} + +func NewForceUpdate(catalog *v3.Catalog, secretLister v1.SecretLister) (string, *Helm, error) { + h, err := NewNoUpdate(catalog, secretLister) + if err != nil { + return "", nil, err + } + commit, err := h.Update(true) + return commit, h, err +} + +func CatalogSHA256Hash(catalog *v3.Catalog) string { + u := catalog.Spec.URL + branch := catalog.Spec.Branch + username := catalog.Spec.Username + password := catalog.Spec.Password + hashBytes := sha256.Sum256([]byte(fmt.Sprintf("%s %s %s %s", u, branch, username, password))) + return hex.EncodeToString(hashBytes[:]) +} + +func newCache(catalog *v3.Catalog, secretLister v1.SecretLister) (*Helm, error) { + catalog = catalog.DeepCopy() + var err error + catalog.Spec, err = secretmigrator.AssembleCatalogCredential(catalog, secretLister) + if err != nil { + return nil, err + } + hash := CatalogSHA256Hash(catalog) + localPath := filepath.Join(CatalogCache, hash) + kind := getCatalogKind(catalog, localPath) + + if kind == KindHelmInternal { + localPath = filepath.Join(InternalCatalog, catalog.Name) + } + + return &Helm{ + LocalPath: localPath, + IconPath: filepath.Join(IconCache, hash), + catalogName: catalog.Name, + Hash: hash, + Kind: kind, + url: catalog.Spec.URL, + branch: catalog.Spec.Branch, + username: catalog.Spec.Username, + password: catalog.Spec.Password, + lastCommit: catalog.Status.Commit, + }, nil +} + +func getCatalogKind(catalog *v3.Catalog, localPath string) string { + if validCatalogKind[catalog.Spec.CatalogKind] { + return catalog.Spec.CatalogKind + } + + if _, err := os.Stat(filepath.Join(localPath, ".git", "HEAD")); !os.IsNotExist(err) { + return KindHelmGit + } + + pathURL := git.FormatURL(catalog.Spec.URL, catalog.Spec.Username, catalog.Spec.Password) + if git.IsValid(pathURL) { + return KindHelmGit + } + + return KindHelmHTTP +} + +func (h *Helm) Update(fetchLatest bool) (string, error) { + h.lock() + defer h.unlock() + commit, err := h.update(fetchLatest) + if err != nil { + return "", err + } + if err := os.MkdirAll(h.IconPath, 0755); err != nil { + return "", err + } + return commit, nil +} + +func (h *Helm) update(fetchLatest bool) (string, error) { + logrus.Debugf("Helm preparing catalog cache [%s] for update", h.catalogName) + if err := os.MkdirAll(h.LocalPath, 0755); err != nil { + return "", err + } + + var ( + commit string + err error + ) + switch h.Kind { + case KindHelmGit: + commit, err = h.updateGit(fetchLatest) + case KindHelmHTTP: + commit, err = h.updateIndex(fetchLatest) + case KindHelmInternal: + commit, err = h.updateInternal() + default: + return "", fmt.Errorf("unknown helm catalog kind [%s] for [%s]", h.Kind, h.url) + } + return commit, err +} + +func (h *Helm) updateInternal() (string, error) { + empty, err := dirEmpty(h.LocalPath) + if err != nil { + return "", errors.Wrap(err, "empty directory check failed") + } + + if empty { + return "", errors.New("local catalog directory is empty") + } + + commit, err := git.HeadCommit(h.LocalPath) + if err != nil { + err = errors.Wrap(err, "retrieving head commit failed") + } + + return commit, err +} + +func (h *Helm) updateIndex(fetchLatest bool) (string, error) { + if !fetchLatest { + return "", nil + } + + index, err := h.downloadIndex(h.url) + if err != nil { + return "", err + } + + if err := h.saveIndex(index); err != nil { + return "", err + } + logrus.Debugf("Helm updated http-helm catalog [%s]", h.url) + return index.Hash, nil +} + +func md5Hash(content string) string { + sum := md5.Sum([]byte(content)) + return hex.EncodeToString(sum[:]) +} + +func (h *Helm) updateGit(fetchLatest bool) (string, error) { + var ( + changed bool + err error + commit string + ) + + if h.branch == "" { + h.branch = "master" + } + repoURL := git.FormatURL(h.url, h.username, h.password) + + empty, err := dirEmpty(h.LocalPath) + if err != nil { + return "", errors.Wrap(err, "Empty directory check failed") + } + + if empty { + if err = git.Clone(h.LocalPath, repoURL, h.branch); err != nil { + return "", errors.Wrap(err, "Clone failed") + } + } else { + if fetchLatest || h.lastCommit == "" { + commit = fmt.Sprintf("origin/%s", h.branch) + changed, err = remoteShaChanged(repoURL, h.branch, h.lastCommit, uuid) + if err != nil { + return "", errors.Wrap(err, "Remote commit check failed") + } + } else { + commit = h.lastCommit + changed, err = localShaDiffers(h.LocalPath, h.lastCommit) + if err != nil { + return "", errors.Wrap(err, "Local commit check failed") + } + } + if changed { + if err = git.Update(h.LocalPath, commit); err != nil { + if h.username != "" && h.password != "" { + // the error string contains url which is formed using url.UserInfo.String(), + // which escapes the following characters-> '@', '/', '?' and ':' + // h.password doesn't escape these characters, so to use strings.Contains(), obtain the escaped password + userInfo := url.UserPassword(h.username, h.password) + userPwd := strings.SplitN(userInfo.String(), ":", 2) + if len(userPwd) != 2 { + return "", errors.New("error getting userinfo url") + } + pwd := userPwd[1] + if strings.Contains(err.Error(), pwd) { + errStr := strings.Replace(err.Error(), pwd+"@", "***@", 1) + err = errors.New(errStr) + } + } + return "", errors.Wrap(err, "Update failed") + } + logrus.Debugf("Helm updated git repository for catalog [%s]", h.catalogName) + } + } + + commit, err = git.HeadCommit(h.LocalPath) + if err != nil { + err = errors.Wrap(err, "Retrieving head commit failed") + } + + logrus.Debugf("Helm updated git-helm catalog [%s:%s]", repoURL, h.branch) + return commit, err +} + +func formatGitURL(endpoint, branch string) string { + formattedURL := "" + if u, err := url.Parse(endpoint); err == nil { + pathParts := strings.Split(u.Path, "/") + switch strings.Split(u.Host, ":")[0] { + case "github.com": + if len(pathParts) >= 3 { + org := pathParts[1] + repo := strings.TrimSuffix(pathParts[2], ".git") + formattedURL = fmt.Sprintf("https://api.github.com/repos/%s/%s/commits/%s", org, repo, branch) + } + case "git.rancher.io": + repo := strings.TrimSuffix(pathParts[1], ".git") + u.Path = fmt.Sprintf("/repos/%s/commits/%s", repo, branch) + formattedURL = u.String() + } + } + return formattedURL +} + +func localShaDiffers(localPath, commit string) (bool, error) { + currentCommit, err := git.HeadCommit(localPath) + return currentCommit != commit, err +} + +func remoteShaChanged(repoURL, branch, sha, uuid string) (bool, error) { + formattedURL := formatGitURL(repoURL, branch) + + if formattedURL == "" { + return true, nil + } + + req, err := http.NewRequest("GET", formattedURL, nil) + if err != nil { + logrus.Warnf("Problem creating request to check git remote sha of repo [%v]: %v", repoURL, err) + return true, nil + } + req.Header.Set("Accept", "application/vnd.github.v3.sha") + req.Header.Set("If-None-Match", fmt.Sprintf("\"%s\"", sha)) + if uuid != "" { + req.Header.Set("X-Install-Uuid", uuid) + } + resp, err := httpClient.Do(req) + if err != nil { + // Return timeout errors so caller can decide whether or not to proceed with updating the repo + if uErr, ok := err.(*url.Error); ok && uErr.Timeout() { + return false, errors.Wrapf(uErr, "Repo [%v] is not accessible", repoURL) + } + return true, nil + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusNotModified { + return false, nil + } + + return true, nil +} + +func dirEmpty(dir string) (bool, error) { + f, err := os.Open(dir) + if err != nil { + return false, err + } + defer f.Close() + + _, err = f.Readdirnames(1) + if err == io.EOF { + return true, nil + } + return false, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/types.go new file mode 100644 index 0000000..ea7fffa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/helm/types.go @@ -0,0 +1,30 @@ +package helm + +type RepoIndex struct { + IndexFile *IndexFile `json:"indexFile" yaml:"indexFile"` + Hash string `json:"hash" yaml:"hash"` +} + +type IndexFile struct { + Entries map[string]ChartVersions `json:"entries" yaml:"entries"` +} + +type ChartVersions []*ChartVersion + +type ChartVersion struct { + ChartMetadata `yaml:",inline"` + Dir string `json:"-" yaml:"-"` + LocalFiles []string `json:"-" yaml:"-"` + URLs []string `json:"urls" yaml:"urls"` + Digest string `json:"digest,omitempty" yaml:"digest,omitempty"` +} + +type ChartMetadata struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` + Sources []string `json:"sources,omitempty" yaml:"sources,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + KubeVersion string `json:"kubeVersion,omitempty" yaml:"kubeVersion,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Keywords []string `json:"keywords,omitempty" yaml:"keywords,omitempty"` + Icon string `json:"icon,omitempty" yaml:"icon,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy.go new file mode 100644 index 0000000..813b9ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy.go @@ -0,0 +1,337 @@ +package httpproxy + +import ( + "fmt" + "net/http" + "net/http/httputil" + "net/url" + "regexp" + "strings" + "time" + + prov "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/controllers/management/cluster" + provcluster "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + mgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + provv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/steve/pkg/auth" + "github.com/sirupsen/logrus" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/apiserver/pkg/authorization/authorizerfactory" + "k8s.io/apiserver/pkg/endpoints/request" +) + +const ( + ForwardProto = "X-Forwarded-Proto" + APIAuth = "X-API-Auth-Header" + CattleAuth = "X-API-CattleAuth-Header" + AuthHeader = "Authorization" + SetCookie = "Set-Cookie" + Cookie = "Cookie" + APISetCookie = "X-Api-Set-Cookie-Header" + APICookie = "X-Api-Cookie-Header" + hostRegex = "[A-Za-z0-9-]+" + CSP = "Content-Security-Policy" + XContentType = "X-Content-Type-Options" +) + +var ( + httpStart = regexp.MustCompile("^http:/([^/])") + httpsStart = regexp.MustCompile("^https:/([^/])") + badHeaders = map[string]bool{ + "host": true, + "transfer-encoding": true, + "content-length": true, + "x-api-auth-header": true, + "x-api-cattleauth-header": true, + "cf-connecting-ip": true, + "cf-ray": true, + "impersonate-user": true, + "impersonate-group": true, + } +) + +type Supplier func() []string + +type proxy struct { + prefix string + validHostsSupplier Supplier + credentials v1.SecretInterface + mgmtClustersCache mgmtv3.ClusterCache + provClustersCache provv1.ClusterCache + authorizer authorizer.Authorizer +} + +func (p *proxy) isAllowed(host string) bool { + for _, valid := range p.validHostsSupplier() { + if valid == host { + return true + } + + if strings.HasPrefix(valid, "*") && strings.HasSuffix(host, valid[1:]) { + return true + } + + if strings.Contains(valid, ".%.") || strings.HasPrefix(valid, "%.") { + r := constructRegex(valid) + if match := r.MatchString(host); match { + return true + } + } + } + + return false +} + +func NewProxy(prefix string, validHosts Supplier, scaledContext *config.ScaledContext) (http.Handler, error) { + cfg := authorizerfactory.DelegatingAuthorizerConfig{ + SubjectAccessReviewClient: scaledContext.K8sClient.AuthorizationV1(), + AllowCacheTTL: time.Second * time.Duration(settings.AuthorizationCacheTTLSeconds.GetInt()), + DenyCacheTTL: time.Second * time.Duration(settings.AuthorizationDenyCacheTTLSeconds.GetInt()), + WebhookRetryBackoff: &auth.WebhookBackoff, + } + + authorizer, err := cfg.New() + if err != nil { + return nil, err + } + + p := proxy{ + authorizer: authorizer, + prefix: prefix, + validHostsSupplier: validHosts, + credentials: scaledContext.Core.Secrets(""), + mgmtClustersCache: scaledContext.Wrangler.Mgmt.Cluster().Cache(), + provClustersCache: scaledContext.Wrangler.Provisioning.Cluster().Cache(), + } + + return &httputil.ReverseProxy{ + Director: func(req *http.Request) { + if err := p.proxy(req); err != nil { + logrus.Infof("Failed to proxy: %v", err) + } + }, + ModifyResponse: setModifiedHeaders, + }, nil +} + +func setModifiedHeaders(res *http.Response) error { + // replace set cookies + res.Header.Del(APISetCookie) + // There may be multiple set cookies + for _, setCookie := range res.Header[SetCookie] { + res.Header.Add(APISetCookie, setCookie) + } + res.Header.Del(SetCookie) + // add security headers (similar to raw.githubusercontent) + res.Header.Set(CSP, "default-src 'none'; style-src 'unsafe-inline'; sandbox") + res.Header.Set(XContentType, "nosniff") + return nil +} + +func (p *proxy) proxy(req *http.Request) error { + path := req.URL.String() + index := strings.Index(path, p.prefix) + destPath := path[index+len(p.prefix):] + + if httpsStart.MatchString(destPath) { + destPath = httpsStart.ReplaceAllString(destPath, "https://$1") + } else if httpStart.MatchString(destPath) { + destPath = httpStart.ReplaceAllString(destPath, "http://$1") + } else { + destPath = "https://" + destPath + } + + destURL, err := url.Parse(destPath) + if err != nil { + return err + } + + destURL.RawQuery = req.URL.RawQuery + + destURLHostname := destURL.Hostname() + + if !p.isAllowed(destURLHostname) { + return fmt.Errorf("invalid host: %v", destURLHostname) + } + + headerCopy := http.Header{} + + if req.TLS != nil { + headerCopy.Set(ForwardProto, "https") + } + auth := req.Header.Get(APIAuth) + cAuth := req.Header.Get(CattleAuth) + for name, value := range req.Header { + if badHeaders[strings.ToLower(name)] { + continue + } + + copy := make([]string, len(value)) + for i := range value { + copy[i] = strings.TrimPrefix(value[i], "rancher:") + } + headerCopy[name] = copy + } + + req.Host = destURLHostname + req.URL = destURL + req.Header = headerCopy + + if auth != "" { // non-empty AuthHeader is noop + req.Header.Set(AuthHeader, auth) + } else if cAuth != "" { + // setting CattleAuthHeader will replace credential id with secret data + // and generate signature + signer := newSigner(cAuth) + if signer != nil { + return signer.sign(req, p.secretGetter(req, cAuth), cAuth) + } + req.Header.Set(AuthHeader, cAuth) + } + + replaceCookies(req) + + return nil +} + +func (p *proxy) secretGetter(req *http.Request, cAuth string) SecretGetter { + clusterID := getRequestParams(cAuth)["clusterID"] + return func(namespace, name string) (*v1.Secret, error) { + user, ok := request.UserFrom(req.Context()) + if !ok { + return nil, fmt.Errorf("failed to find user") + } + decision, reason, err := p.authorizer.Authorize(req.Context(), authorizer.AttributesRecord{ + User: user, + Verb: "get", + Namespace: namespace, + APIVersion: "v1", + Resource: "secrets", + Name: name, + ResourceRequest: true, + }) + if err != nil { + return nil, err + } + unauthorizedErr := fmt.Errorf("unauthorized %s to %s/%s: %s", user.GetName(), namespace, name, reason) + if decision != authorizer.DecisionAllow { + decision, err = p.checkIndirectAccessViaCluster(req, user, clusterID, fmt.Sprintf("%s:%s", namespace, name)) + if err != nil { + return nil, err + } + if decision != authorizer.DecisionAllow { + return nil, unauthorizedErr + } + } + return p.credentials.Controller().Lister().Get(namespace, name) + } +} + +// checkIndirectAccessViaCluster checks if the user has access to the cloud credential via being owner of a cluster associated to the cloud credential. +// Currently, only EKS and provisioningv2 clusters are supported because those clusters have a cloud credential associated to them. +// GKE and AKS clusters also have cloud credential associated to them, but those are checked via specific proxies (not the meta proxy). +func (p *proxy) checkIndirectAccessViaCluster(req *http.Request, user user.Info, clusterID, credID string) (authorizer.Decision, error) { + var ( + mgmtClusters []*v3.Cluster + provClusters []*prov.Cluster + err error + ) + if clusterID == "" { + // If no clusterID is passed, then we check all clusters that the user has access to and are associated to the cloud credential. + // Both management and provisioning clusters should be checked. + mgmtClusters, err = p.mgmtClustersCache.GetByIndex(cluster.ByCloudCredential, credID) + if err != nil { + return authorizer.DecisionDeny, err + } + + provClusters, err = p.provClustersCache.GetByIndex(provcluster.ByCloudCred, credID) + if err != nil { + return authorizer.DecisionDeny, err + } + } else { + if c, err := p.mgmtClustersCache.Get(clusterID); err == nil { + mgmtClusters = []*v3.Cluster{c} + } else { + return authorizer.DecisionDeny, err + } + provClusters, err = p.provClustersCache.GetByIndex(provcluster.ByCluster, clusterID) + if err != nil { + return authorizer.DecisionDeny, err + } + } + if len(mgmtClusters)+len(provClusters) == 0 { + return authorizer.DecisionDeny, err + } + + for _, c := range mgmtClusters { + if c.Spec.EKSConfig == nil || c.Spec.EKSConfig.AmazonCredentialSecret != credID { + continue + } + + decision, err := p.checkAccessToV3ClusterWithID(req, user, c.Name) + if err == nil && decision == authorizer.DecisionAllow { + return decision, nil + } + } + + for _, c := range provClusters { + if c.Spec.CloudCredentialSecretName != credID { + continue + } + + // Check that the user has access to the management cluster associated to the provisioning cluster. + // If a user has access to the management cluster, then the user has access to the provisioning cluster. + decision, err := p.checkAccessToV3ClusterWithID(req, user, c.Status.ClusterName) + if err == nil && decision == authorizer.DecisionAllow { + return decision, nil + } + } + return authorizer.DecisionDeny, nil +} + +func (p *proxy) checkAccessToV3ClusterWithID(req *http.Request, user user.Info, clusterID string) (authorizer.Decision, error) { + decision, _, err := p.authorizer.Authorize(req.Context(), authorizer.AttributesRecord{ + User: user, + Verb: "update", + APIGroup: v3.GroupName, + APIVersion: v3.Version, + Resource: "clusters", + Name: clusterID, + ResourceRequest: true, + }) + + return decision, err +} + +func replaceCookies(req *http.Request) { + // Do not forward rancher cookies to third parties + req.Header.Del(Cookie) + // Allow client to use their own cookies with Cookie header + if cookie := req.Header.Get(APICookie); cookie != "" { + req.Header.Set(Cookie, cookie) + req.Header.Del(APICookie) + } +} + +func constructRegex(host string) *regexp.Regexp { + // incoming host "ec2.%.amazonaws.com" + // Converted to regex "^ec2\.[A-Za-z0-9-]+\.amazonaws\.com$" + parts := strings.Split(host, ".") + for i, part := range parts { + if part == "%" { + parts[i] = hostRegex + } else { + parts[i] = regexp.QuoteMeta(part) + } + } + + str := "^" + strings.Join(parts, "\\.") + "$" + + return regexp.MustCompile(str) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy_test.go new file mode 100644 index 0000000..8b0cae2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/proxy_test.go @@ -0,0 +1,224 @@ +package httpproxy + +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +// ReplaceSetCookies should rename set cookie header to api set cookie header +func TestReplaceSetCookies(t *testing.T) { + DummyRequest := &http.Response{ + Header: map[string][]string{ + SetCookie: {"test1=abc", "test2=def", "test3=ghi"}, + APISetCookie: {}, + }, + } + + setModifiedHeaders(DummyRequest) + assert.Equal(t, []string{"test1=abc", "test2=def", "test3=ghi"}, DummyRequest.Header[APISetCookie]) + assert.Equal(t, 0, len(DummyRequest.Header[SetCookie])) + assert.Equal(t, []string{"default-src 'none'; style-src 'unsafe-inline'; sandbox"}, DummyRequest.Header[CSP]) + assert.Equal(t, []string{"nosniff"}, DummyRequest.Header[XContentType]) + + DummyRequest = &http.Response{ + Header: map[string][]string{ + SetCookie: {"test1=abc", "test2=def", "test3=ghi"}, + APISetCookie: {"test4=asdf"}, + }, + } + + setModifiedHeaders(DummyRequest) + // Should delete original api set cookie + assert.Equal(t, []string{"test1=abc", "test2=def", "test3=ghi"}, DummyRequest.Header[APISetCookie]) + assert.Equal(t, 0, len(DummyRequest.Header[SetCookie])) + assert.Equal(t, []string{"default-src 'none'; style-src 'unsafe-inline'; sandbox"}, DummyRequest.Header[CSP]) + assert.Equal(t, []string{"nosniff"}, DummyRequest.Header[XContentType]) +} + +// ReplaceCookie should delete current cookie and replace it with api cookie if available +func TestReplaceCookie(t *testing.T) { + DummyRequest := &http.Request{ + Header: map[string][]string{ + "Cookie": {"abcdef"}, + }, + } + + replaceCookies(DummyRequest) + assert.Equal(t, "", DummyRequest.Header.Get(Cookie)) + assert.Equal(t, 0, len(DummyRequest.Header[Cookie])) + + DummyRequest = &http.Request{ + Header: map[string][]string{ + Cookie: {}, + APICookie: {"test1"}, + }, + } + + replaceCookies(DummyRequest) + assert.Equal(t, "test1", DummyRequest.Header.Get(Cookie)) + assert.Equal(t, "", DummyRequest.Header.Get(APICookie)) + assert.Equal(t, 1, len(DummyRequest.Header[Cookie])) + assert.Equal(t, 0, len(DummyRequest.Header[APICookie])) + + DummyRequest = &http.Request{ + Header: map[string][]string{ + Cookie: {}, + APICookie: {"test1", "test2", "test3"}, + }, + } + + replaceCookies(DummyRequest) + // Should not support multiple cookie headers + assert.Equal(t, "test1", DummyRequest.Header.Get(Cookie)) + assert.Equal(t, "", DummyRequest.Header.Get(APICookie)) + assert.Equal(t, 1, len(DummyRequest.Header[Cookie])) + assert.Equal(t, 0, len(DummyRequest.Header[APICookie])) + + DummyRequest = &http.Request{ + Header: map[string][]string{ + Cookie: {"test0"}, + APICookie: {"test1", "test2", "test3"}, + }, + } + + replaceCookies(DummyRequest) + // Original cookie should be overwritten + assert.Equal(t, "test1", DummyRequest.Header.Get(Cookie)) + assert.Equal(t, "", DummyRequest.Header.Get(APICookie)) + assert.Equal(t, 1, len(DummyRequest.Header[Cookie])) + assert.Equal(t, 0, len(DummyRequest.Header[APICookie])) + + DummyRequest = &http.Request{ + Header: map[string][]string{ + Cookie: {"test0", "test1"}, + APICookie: {"test2", "test3", "test4"}, + }, + } + + replaceCookies(DummyRequest) + // Should delete all original cookies + assert.Equal(t, "test2", DummyRequest.Header.Get(Cookie)) + assert.Equal(t, "", DummyRequest.Header.Get(APICookie)) + assert.Equal(t, 1, len(DummyRequest.Header[Cookie])) + assert.Equal(t, 0, len(DummyRequest.Header[APICookie])) + +} + +// IsAllowed should return false if exact domain is a valid host or suffix of host matches wildcard valid host +func TestIsAllowed(t *testing.T) { + dummyProxy := &proxy{ + validHostsSupplier: func() []string { + return []string{"test1.com", "test2.io", "test3.org"} + }, + } + + assert.Equal(t, false, dummyProxy.isAllowed("")) + assert.Equal(t, false, dummyProxy.isAllowed("test1.org")) + assert.Equal(t, false, dummyProxy.isAllowed("test4.com")) + assert.Equal(t, true, dummyProxy.isAllowed("test2.io")) + + dummyProxy = &proxy{ + validHostsSupplier: func() []string { + return []string{"*test1.com", "test2.io", "test3.org"} + }, + } + + assert.Equal(t, true, dummyProxy.isAllowed("123test1.com")) + assert.Equal(t, false, dummyProxy.isAllowed("123test1.io")) + + dummyProxy = &proxy{ + validHostsSupplier: func() []string { + return []string{"foo.%.alpha.com", "test2.io", "test3.org"} + }, + } + + assert.Equal(t, false, dummyProxy.isAllowed("123test1.com")) + assert.Equal(t, true, dummyProxy.isAllowed("foo.bar.alpha.com")) + assert.Equal(t, false, dummyProxy.isAllowed("foo.bar.baz.alpha.com")) +} + +func TestConstructRegex(t *testing.T) { + type test struct { + host string + whitelistItem string + found bool + description string + } + + tests := []test{ + { + host: "ec2.us-west-1.amazonaws.com", + whitelistItem: "ec2.%.amazonaws.com", + found: true, + description: "base case", + }, + { + host: "ec2.amazonaws.com", + whitelistItem: "%.amazonaws.com", + found: true, + description: "base case", + }, + { + host: "foo.ec2.amazonaws.com", + whitelistItem: "%.amazonaws.com", + found: false, + description: "base case", + }, + { + host: "ec2.us-west-1.thing.foo.amazonaws.com", + whitelistItem: "ec2.%.amazonaws.com", + found: false, + description: "addition content in the middle", + }, + { + host: "thing.us-west-1.amazonaws.com", + whitelistItem: "ec2.%.amazonaws.com", + found: false, + description: "should not match prefix", + }, + { + host: "ec2.us-west-1.amazonaws.com.cn", + whitelistItem: "ec2.%.amazonaws.com", + found: false, + description: "should not match suffix", + }, + { + host: "iam.cn-north-1.amazonaws.com.cn", + whitelistItem: "iam.%.amazonaws.com.cn", + found: true, + description: "base case", + }, + { + host: "iam.cn-north-1.thing.foo.amazonaws.com.cn", + whitelistItem: "iam.%.amazonaws.com.cn", + found: false, + description: "addition content in the middle", + }, + { + host: "thing.iam.cn-north-1.amazonaws.com.cn", + whitelistItem: "iam.%.amazonaws.com.cn", + found: false, + description: "should not match prefix", + }, + { + host: "iam.cn-north-1.amazonaws.com", + whitelistItem: "iam.%.amazonaws.com.cn", + found: false, + description: "should not match suffix", + }, + } + + for _, scenario := range tests { + r := constructRegex(scenario.whitelistItem) + match := r.MatchString(scenario.host) + assert.Equal(t, scenario.found, match, + fmt.Sprintf("failed on host %v and whitelist item %v, %v", + scenario.host, + scenario.whitelistItem, + scenario.description, + )) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign.go new file mode 100644 index 0000000..9b7d438 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign.go @@ -0,0 +1,321 @@ +package httpproxy + +import ( + "bytes" + "crypto/md5" + "crypto/rand" + "encoding/base64" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" + v4 "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/catalog/utils" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" +) + +const ( + defaultAWSRegion = "us-east-1" + defaultUSGovAWSRegion = "us-gov-west-1" + cnNorth1AWSRegion = "cn-north-1" + cnNorthwest1AWSRegion = "cn-northwest-1" +) + +// List of global services for AWS from: https://docs.aws.amazon.com/general/latest/gr/rande.html#global-endpoints +var globalAWSServices = []string{"cloudfront", "globalaccelerator", "iam", "networkmanager", "organizations", "route53", "shield", "waf"} + +var requiredHeadersForAws = map[string]bool{"host": true, + "x-amz-content-sha256": true, + "x-amz-date": true, + "x-amz-user-agent": true} + +type SecretGetter func(namespace, name string) (*v1.Secret, error) + +type Signer interface { + sign(*http.Request, SecretGetter, string) error +} + +func newSigner(auth string) Signer { + splitAuth := strings.Split(auth, " ") + switch strings.ToLower(splitAuth[0]) { + case "awsv4": + return awsv4{} + case "bearer": + return bearer{} + case "basic": + return basic{} + case "digest": + return digest{} + case "arbitrary": + return arbitrary{} + } + return nil +} + +func (br bearer) sign(req *http.Request, secrets SecretGetter, auth string) error { + data, secret, err := getAuthData(auth, secrets, []string{"passwordField", "credID"}) + if err != nil { + return err + } + req.Header.Set(AuthHeader, fmt.Sprintf("%s %s", "Bearer", secret[data["passwordField"]])) + return nil +} + +func (b basic) sign(req *http.Request, secrets SecretGetter, auth string) error { + data, secret, err := getAuthData(auth, secrets, []string{"usernameField", "passwordField", "credID"}) + if err != nil { + return err + } + key := fmt.Sprintf("%s:%s", secret[data["usernameField"]], secret[data["passwordField"]]) + encoded := base64.URLEncoding.EncodeToString([]byte(key)) + req.Header.Set(AuthHeader, fmt.Sprintf("%s %s", "Basic", encoded)) + return nil +} + +func (a awsv4) sign(req *http.Request, secrets SecretGetter, auth string) error { + _, secret, err := getAuthData(auth, secrets, []string{"credID"}) + if err != nil { + return err + } + service, region := a.getServiceAndRegion(req.URL.Host) + creds := credentials.NewStaticCredentials(secret["accessKey"], secret["secretKey"], "") + awsSigner := v4.NewSigner(creds) + var body []byte + if req.Body != nil { + body, err = ioutil.ReadAll(req.Body) + if err != nil { + return fmt.Errorf("error reading request body %v", err) + } + } + oldHeader, newHeader := http.Header{}, http.Header{} + for header, value := range req.Header { + if _, ok := requiredHeadersForAws[strings.ToLower(header)]; ok { + newHeader[header] = value + } else { + oldHeader[header] = value + } + } + req.Header = newHeader + _, err = awsSigner.Sign(req, bytes.NewReader(body), service, region, time.Now()) + if err != nil { + return err + } + for key, val := range oldHeader { + req.Header.Add(key, strings.Join(val, "")) + } + return nil +} + +func (a awsv4) getServiceAndRegion(host string) (string, string) { + service := "" + region := "" + for _, partition := range endpoints.DefaultPartitions() { + service, region = partitionServiceAndRegion(partition, host) + // Some services are global and don't have a region. If a partition returns a service + // that is global then stop processing partitions. If we carry on processing partitions + // for a global service then when new partitions are introduced the signing may break. + if service != "" && region == "" { + if utils.Contains(globalAWSServices, service) { + break + } + } + + // empty region is valid, but if one is found it should be assumed correct + if region != "" { + return service, region + } + } + if strings.EqualFold(service, "iam") { + // This conditional is meant to cover a discrepancy in the IAM service for the China regions. + // The following doc states that IAM uses a globally unique endpoint, and the default + // region "us-east-1" should be used as part of the Credential authentication parameter + // (Current backend behavior). However, using "us-east-1" with any of the China regions will throw + // the error "SignatureDoesNotMatch: Credential should be scoped to a valid region, not 'us-east-1'.". + // https://docs.aws.amazon.com/general/latest/gr/sigv4_elements.html + // + // This other doc states the region value for China services should be "cn-north-1" or "cn-northwest-1" + // including IAM (See IAM endpoints in the tables). So they need to be set manually to prevent the error + // caused by the "us-east-1" default. + // https://docs.amazonaws.cn/en_us/aws/latest/userguide/endpoints-Beijing.html + if strings.Contains(host, cnNorth1AWSRegion) { + return service, cnNorth1AWSRegion + } + if strings.Contains(host, cnNorthwest1AWSRegion) { + return service, cnNorthwest1AWSRegion + } + } + // if no region is found, global endpoint is assumed. + // https://docs.aws.amazon.com/general/latest/gr/sigv4_elements.html + if strings.Contains(host, "us-gov") { + return service, defaultUSGovAWSRegion + } + + return service, defaultAWSRegion +} + +func partitionServiceAndRegion(partition endpoints.Partition, host string) (string, string) { + service := "" + partitionServices := partition.Services() + for _, part := range strings.Split(host, ".") { + if id := partitionServices[part].ID(); id != "" { + service = id + break + } + } + + if service == "" { + return "", "" + } + + host = strings.Trim(host, service) + serviceRegions := partitionServices[service].Regions() + for _, part := range strings.Split(host, ".") { + if id := serviceRegions[part].ID(); id != "" { + return service, id + } + } + return service, "" +} + +func (d digest) sign(req *http.Request, secrets SecretGetter, auth string) error { + data, secret, err := getAuthData(auth, secrets, []string{"usernameField", "passwordField", "credID"}) + if err != nil { + return err + } + resp, err := doNewRequest(req) // request to get challenge fields from server + if err != nil { + return err + } + challengeData, err := parseChallenge(resp.Header.Get("WWW-Authenticate")) + if err != nil { + return err + } + challengeData["username"] = secret[data["usernameField"]] + challengeData["password"] = secret[data["passwordField"]] + signature, err := buildSignature(challengeData, req) + if err != nil { + return err + } + req.Header.Set(AuthHeader, fmt.Sprintf("%s %s", "Digest", signature)) + return nil +} + +func doNewRequest(req *http.Request) (*http.Response, error) { + newReq, err := http.NewRequest(req.Method, req.URL.String(), nil) + if err != nil { + return nil, err + } + newReq.Header.Set("Content-Type", "application/json") + client := http.Client{} + resp, err := client.Do(newReq) + if err != nil { + return nil, err + } + if resp.StatusCode != httperror.Unauthorized.Status { + return nil, fmt.Errorf("expected 401 status code, got %v", resp.StatusCode) + } + resp.Body.Close() + return resp, err +} + +func parseChallenge(header string) (map[string]string, error) { + if header == "" { + return nil, fmt.Errorf("failed to get WWW-Authenticate header") + } + s := strings.Trim(header, " \n\r\t") + if !strings.HasPrefix(s, "Digest ") { + return nil, fmt.Errorf("bad challenge %s", header) + } + data := map[string]string{} + s = strings.Trim(s[7:], " \n\r\t") + terms := strings.Split(s, ", ") + for _, term := range terms { + splitTerm := strings.SplitN(term, "=", 2) + data[splitTerm[0]] = strings.Trim(splitTerm[1], "\"") + } + return data, nil +} + +func formResponse(qop string, data map[string]string, req *http.Request) (string, string) { + hash1 := hash(fmt.Sprintf("%s:%s:%s", data["username"], data["realm"], data["password"])) + hash2 := hash(fmt.Sprintf("%s:%s", req.Method, req.URL.Path)) + if qop == "" { + return hash(fmt.Sprintf("%s:%s:%s", hash1, data["nonce"], hash2)), "" + + } else if qop == "auth" { + cnonce := data["cnonce"] + if cnonce == "" { + cnonce = getCnonce() + } + return hash(fmt.Sprintf("%s:%s:%08x:%s:%s:%s", + hash1, data["nonce"], 00000001, cnonce, qop, hash2)), cnonce + } + return "", "" +} + +func buildSignature(data map[string]string, req *http.Request) (string, error) { + qop, ok := data["qop"] + if ok && qop != "auth" && qop != "" { + return "", fmt.Errorf("qop not implemented %s", data["qop"]) + } + response, cnonce := formResponse(qop, data, req) + if response == "" { + return "", fmt.Errorf("error forming response qop: %s", qop) + } + auth := []string{fmt.Sprintf(`username="%s"`, data["username"])} + auth = append(auth, fmt.Sprintf(`realm="%s"`, data["realm"])) + auth = append(auth, fmt.Sprintf(`nonce="%s"`, data["nonce"])) + auth = append(auth, fmt.Sprintf(`uri="%s"`, req.URL.Path)) + auth = append(auth, fmt.Sprintf(`response="%s"`, response)) + if val, ok := data["opaque"]; ok && val != "" { + auth = append(auth, fmt.Sprintf(`opaque="%s"`, data["opaque"])) + } + if qop != "" { + auth = append(auth, fmt.Sprintf("qop=%s", qop)) + auth = append(auth, fmt.Sprintf("nc=%08x", 00000001)) + auth = append(auth, fmt.Sprintf("cnonce=%s", cnonce)) + } + return strings.Join(auth, ", "), nil +} + +func hash(field string) string { + f := md5.New() + f.Write([]byte(field)) + return hex.EncodeToString(f.Sum(nil)) +} + +func getCnonce() string { + b := make([]byte, 8) + io.ReadFull(rand.Reader, b) + return fmt.Sprintf("%x", b)[:16] +} + +func (a arbitrary) sign(req *http.Request, secrets SecretGetter, auth string) error { + data, _, err := getAuthData(auth, secrets, []string{}) + if err != nil { + return err + } + splitHeaders := strings.Split(data["headers"], ",") + for _, header := range splitHeaders { + val := strings.SplitN(header, "=", 2) + req.Header.Set(val[0], val[1]) + } + return nil +} + +type awsv4 struct{} + +type bearer struct{} + +type basic struct{} + +type digest struct{} + +type arbitrary struct{} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign_utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign_utils.go new file mode 100644 index 0000000..4bc6cdc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/httpproxy/sign_utils.go @@ -0,0 +1,71 @@ +package httpproxy + +import ( + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/wrangler/v3/pkg/kv" +) + +func getAuthData(auth string, secrets SecretGetter, fields []string) (map[string]string, map[string]string, error) { + data := getRequestParams(auth) + if !requiredFieldsExist(data, fields) { + return data, nil, fmt.Errorf("required fields %s not set", fields) + } + if data["credID"] == "" { + return data, nil, nil + } + secret, err := getCredential(data["credID"], secrets) + if err != nil { + return data, nil, err + } + return data, secret, nil +} + +func getRequestParams(auth string) map[string]string { + params := map[string]string{} + if auth != "" { + splitAuth := strings.Split(auth, " ") + for _, term := range splitAuth[1:] { + splitTerm := strings.SplitN(term, "=", 2) + params[splitTerm[0]] = splitTerm[1] + } + } + return params +} + +func requiredFieldsExist(data map[string]string, fields []string) bool { + for _, field := range fields { + if val, ok := data[field]; !ok || val == "" { + return false + } + } + return true +} + +func getCredential(credentialID string, credentials SecretGetter) (map[string]string, error) { + ns, name := kv.Split(credentialID, "/") + if name == "" { + split := strings.SplitN(credentialID, ":", 2) + if len(split) != 2 || split[0] == "" || split[1] == "" { + return nil, fmt.Errorf("invalid credential id %s", credentialID) + } + ns = namespace.GlobalNamespace + name = split[1] + } + cred, err := credentials(ns, name) + if err != nil { + return nil, err + } + ans := map[string]string{} + for key, val := range cred.Data { + splitKeys := strings.Split(key, "-") + if len(splitKeys) == 2 && strings.HasSuffix(splitKeys[0], "Config") { + ans[splitKeys[1]] = string(val) + } else { + ans[key] = string(val) + } + } + return ans, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts.go new file mode 100644 index 0000000..0cf92b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts.go @@ -0,0 +1,383 @@ +package image + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/pkg/errors" + libhelm "github.com/rancher/rancher/pkg/helm" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + "helm.sh/helm/v3/pkg/repo" +) + +const RancherVersionAnnotationKey = "catalog.cattle.io/rancher-version" + +// chartsToCheckConstraints and systemChartsToCheckConstraints define which charts and system charts should +// be checked for images and added to imageSet based on whether the given Rancher version/tag satisfies the chart's +// Rancher version constraints to allow support for multiple version lines of a chart in airgap setups. If a chart is +// not defined here, only the latest version of it will be checked for images and added if it passes the constraint. +// Note: CRD charts need to be added as well. +var chartsToCheckConstraints = map[string]struct{}{ + "rancher-istio": {}, +} +var systemChartsToCheckConstraints = map[string]struct{}{ + "rancher-monitoring": {}, +} + +// chartsToIgnoreTags and systemChartsToIgnoreTags defines the charts and system charts in which a specified +// image tag should be ignored. +var chartsToIgnoreTags = map[string]string{ + "rancher-vsphere-csi": "latest", + "rancher-vsphere-cpi": "latest", +} +var systemChartsToIgnoreTags = map[string]string{} + +type Charts struct { + Config ExportConfig +} + +// FetchImages finds all the images used by all the charts in a Rancher charts repository and adds them to imageSet. +// The images from the latest version of each chart are always added to the images set, whereas the remaining versions +// are added only if the given Rancher version/tag satisfies the chart's Rancher version constraint annotation. +func (c Charts) FetchImages(imagesSet map[string]map[string]struct{}) error { + if c.Config.ChartsPath == "" || c.Config.RancherVersion == "" { + return nil + } + index, err := repo.LoadIndexFile(filepath.Join(c.Config.ChartsPath, "index.yaml")) + if err != nil { + return err + } + // Filter index entries based on their Rancher version constraint + var filteredVersions repo.ChartVersions + for _, versions := range index.Entries { + if len(versions) == 0 { + continue + } + // Always append the latest version of the chart if it passes the constraint check + // Note: Selecting the correct latest version relies on the charts-build-scripts `make standardize` command + // sorting the versions in the index file in descending order correctly. + latestVersion := versions[0] + if isConstraintSatisfied, err := c.checkChartVersionConstraint(*latestVersion); err != nil { + return errors.Wrapf(err, "failed to check constraint of chart") + } else if isConstraintSatisfied { + filteredVersions = append(filteredVersions, latestVersion) + } + // Append the remaining versions of the chart if the chart exists in the chartsToCheckConstraints map + // and the given Rancher version satisfies the chart's Rancher version constraint annotation. + chartName := versions[0].Metadata.Name + if _, ok := chartsToCheckConstraints[chartName]; ok { + for _, version := range versions[1:] { + if isConstraintSatisfied, err := c.checkChartVersionConstraint(*version); err != nil { + return errors.Wrapf(err, "failed to check constraint of chart") + } else if isConstraintSatisfied { + filteredVersions = append(filteredVersions, version) + } + } + } + } + // Find values.yaml files in the tgz files of each chart, and check for images to add to imageSet + for _, version := range filteredVersions { + tgzPath := filepath.Join(c.Config.ChartsPath, version.URLs[0]) + versionValues, err := decodeValuesFilesInTgz(tgzPath) + if err != nil { + logrus.Info(err) + continue + } + tag, _ := chartsToIgnoreTags[version.Name] + chartNameAndVersion := fmt.Sprintf("%s:%s", version.Name, version.Version) + for _, values := range versionValues { + if err = pickImagesFromValuesMap(imagesSet, values, chartNameAndVersion, c.Config.OsType, tag); err != nil { + return err + } + } + } + return nil +} + +// checkChartVersionConstraint retrieves the value of a chart's Rancher version constraint annotation, and +// returns true if the Rancher version in the export configuration satisfies the chart's constraint, false otherwise. +// If a chart does not have a Rancher version annotation defined, this function returns false. +func (c Charts) checkChartVersionConstraint(version repo.ChartVersion) (bool, error) { + if constraintStr, ok := version.Annotations[RancherVersionAnnotationKey]; ok { + return compareRancherVersionToConstraint(c.Config.RancherVersion, constraintStr) + } + return false, nil +} + +type SystemCharts struct { + Config ExportConfig +} + +type Questions struct { + RancherMinVersion string `yaml:"rancher_min_version"` + RancherMaxVersion string `yaml:"rancher_max_version"` +} + +// FetchImages finds all the images used by all the charts in a Rancher system charts repository and adds them to imageSet. +// The images from the latest version of each chart are always added to the images set, whereas the remaining versions +// are added only if the given Rancher version/tag satisfies the chart's Rancher version constraint defined in its questions file. +func (sc SystemCharts) FetchImages(imagesSet map[string]map[string]struct{}) error { + if sc.Config.SystemChartsPath == "" || sc.Config.RancherVersion == "" { + return nil + } + // Load system charts virtual index + helm := libhelm.Helm{ + LocalPath: sc.Config.SystemChartsPath, + IconPath: sc.Config.SystemChartsPath, + Hash: "", + } + virtualIndex, err := helm.LoadIndex() + if err != nil { + return errors.Wrapf(err, "failed to load system charts index") + } + // Filter index entries based on their Rancher version constraint + var filteredVersions libhelm.ChartVersions + for _, versions := range virtualIndex.IndexFile.Entries { + if len(versions) == 0 { + continue + } + // Always append the latest version of the chart unless it has been intentionally hidden with constraints + latestVersion := versions[0] + if isConstraintSatisfied, err := sc.checkChartVersionConstraint(*latestVersion); err != nil { + return errors.Wrapf(err, "failed to filter chart versions") + } else if isConstraintSatisfied { + filteredVersions = append(filteredVersions, latestVersion) + } + // Append the remaining versions of the chart if the chart exists in the systemChartsToCheckConstraints map + // and the given Rancher version satisfies the chart's Rancher version constraint defined in its questions file + chartName := versions[0].ChartMetadata.Name + if _, ok := systemChartsToCheckConstraints[chartName]; ok { + for _, version := range versions[1:] { + if isConstraintSatisfied, err := sc.checkChartVersionConstraint(*version); err != nil { + return errors.Wrapf(err, "failed to filter chart versions") + } else if isConstraintSatisfied { + filteredVersions = append(filteredVersions, version) + } + } + } + } + // Find values.yaml files in each chart's local files, and check for images to add to imageSet + for _, version := range filteredVersions { + for _, file := range version.LocalFiles { + if !isValuesFile(file) { + continue + } + values, err := decodeValuesFile(file) + if err != nil { + return err + } + tag, _ := systemChartsToIgnoreTags[version.Name] + chartNameAndVersion := fmt.Sprintf("%s:%s", version.Name, version.Version) + if err = pickImagesFromValuesMap(imagesSet, values, chartNameAndVersion, sc.Config.OsType, tag); err != nil { + return err + } + } + } + return nil +} + +// checkChartVersionConstraint retrieves the value of a chart's Rancher version defined in its questions file, and +// returns true if the Rancher version in the export configuration satisfies the chart's constraint, false otherwise. +// If a chart does not have a Rancher version constraint defined, this function returns false. +func (sc SystemCharts) checkChartVersionConstraint(version libhelm.ChartVersion) (bool, error) { + questionsPath := filepath.Join(sc.Config.SystemChartsPath, version.Dir, "questions.yaml") + questions, err := decodeQuestionsFile(questionsPath) + if os.IsNotExist(err) { + questionsPath = filepath.Join(sc.Config.SystemChartsPath, version.Dir, "questions.yml") + questions, err = decodeQuestionsFile(questionsPath) + } + if err != nil { + logrus.Warnf("skipping system chart, %s:%s does not have a questions file", version.ChartMetadata.Name, version.ChartMetadata.Version) + return false, nil + } + constraintStr := minMaxToConstraintStr(questions.RancherMinVersion, questions.RancherMaxVersion) + if constraintStr == "" { + return false, nil + } + return compareRancherVersionToConstraint(sc.Config.RancherVersion, constraintStr) +} + +// compareRancherVersionToConstraint returns true if the Rancher version satisfies constraintStr, false otherwise. +func compareRancherVersionToConstraint(rancherVersion, constraintStr string) (bool, error) { + if constraintStr == "" { + return false, errors.Errorf("Invalid constraint string: \"%s\"", constraintStr) + } + constraint, err := semver.NewConstraint(constraintStr) + if err != nil { + return false, err + } + rancherSemVer, err := semver.NewVersion(rancherVersion) + if err != nil { + return false, err + } + // When the exporter is ran in a dev environment, we replace the rancher version with a dev version (e.g 2.X.99). + // This breaks the semver compare logic for exporting because we use the Rancher version constraint < 2.X.99-0 in + // many of our charts and since 2.X.99 > 2.X.99-0 the comparison returns false which is not the desired behavior. + patch := rancherSemVer.Patch() + if patch == 99 { + patch = 98 + } + // All pre-release versions are removed because the semver comparison will not yield the desired behavior unless + // the constraint has a pre-release too. Since the exporter for charts can treat pre-releases and releases equally, + // is cleaner to remove it. E.g. comparing rancherVersion 2.6.4-rc1 and constraint 2.6.3 - 2.6.5 yields false because + // the versions in the contraint do not have a pre-release. This behavior comes from the semver module and is intentional. + rSemVer, err := semver.NewVersion(fmt.Sprintf("%d.%d.%d", rancherSemVer.Major(), rancherSemVer.Minor(), patch)) + if err != nil { + return false, err + } + return constraint.Check(rSemVer), nil +} + +// minMaxToConstraintStr converts min and max Rancher version strings into a constraint string +// E.g min "2.6.3" max "2.6.4" -> constraintStr "2.6.3 - 2.6.4". +func minMaxToConstraintStr(min, max string) string { + if min != "" && max != "" { + return fmt.Sprintf("%s - %s", min, max) + } + if min != "" { + return fmt.Sprintf(">= %s", min) + } + if max != "" { + return fmt.Sprintf("<= %s", max) + } + return "" +} + +// pickImagesFromValuesMap walks a values map to find images, and add them to imagesSet. +func pickImagesFromValuesMap(imagesSet map[string]map[string]struct{}, values map[interface{}]interface{}, chartNameAndVersion string, osType OSType, tagToIgnore string) error { + walkMap(values, func(inputMap map[interface{}]interface{}) { + repository, ok := inputMap["repository"].(string) + if !ok { + return + } + // No string type assertion because some charts have float typed image tags + tag, ok := inputMap["tag"] + if !ok { + return + } + if fmt.Sprintf("%v", tag) == tagToIgnore { + return + } + imageName := fmt.Sprintf("%s:%v", repository, tag) + // By default, images are added to the generic images list ("linux"). For Windows and multi-OS + // images to be considered, they must use a comma-delineated list (e.g. "os: windows", + // "os: windows,linux", and "os: linux,windows"). + osList, ok := inputMap["os"].(string) + if !ok { + if inputMap["os"] != nil { + errors.Errorf("field 'os:' for image %s contains neither a string nor nil", imageName) + } + if osType == Linux { + addSourceToImage(imagesSet, imageName, chartNameAndVersion) + return + } + } + for _, os := range strings.Split(osList, ",") { + os = strings.TrimSpace(os) + if strings.EqualFold("windows", os) && osType == Windows { + addSourceToImage(imagesSet, imageName, chartNameAndVersion) + return + } + if strings.EqualFold("linux", os) && osType == Linux { + addSourceToImage(imagesSet, imageName, chartNameAndVersion) + return + } + } + }) + return nil +} + +// decodeValueFilesInTgz reads tarball in tgzPath and returns a slice of values corresponding to values.yaml files found inside of it. +func decodeValuesFilesInTgz(tgzPath string) ([]map[interface{}]interface{}, error) { + tgz, err := os.Open(tgzPath) + if err != nil { + return nil, err + } + defer tgz.Close() + gzr, err := gzip.NewReader(tgz) + if err != nil { + return nil, err + } + defer gzr.Close() + tr := tar.NewReader(gzr) + var valuesSlice []map[interface{}]interface{} + for { + header, err := tr.Next() + switch { + case err == io.EOF: + return valuesSlice, nil + case err != nil: + return nil, err + case header.Typeflag == tar.TypeReg && isValuesFile(header.Name): + var values map[interface{}]interface{} + if err := decodeYAMLFile(tr, &values); err != nil { + return nil, err + } + valuesSlice = append(valuesSlice, values) + default: + continue + } + } +} + +// walkMap walks inputMap and calls the callback function on all map type nodes including the root node. +func walkMap(inputMap interface{}, callback func(map[interface{}]interface{})) { + switch data := inputMap.(type) { + case map[interface{}]interface{}: + callback(data) + for _, value := range data { + walkMap(value, callback) + } + case []interface{}: + for _, elem := range data { + walkMap(elem, callback) + } + } +} + +func decodeQuestionsFile(path string) (Questions, error) { + var questions Questions + file, err := os.Open(path) + if err != nil { + return Questions{}, err + } + defer file.Close() + if err := decodeYAMLFile(file, &questions); err != nil { + return Questions{}, err + } + return questions, nil +} + +func decodeValuesFile(path string) (map[interface{}]interface{}, error) { + var values map[interface{}]interface{} + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + if err := decodeYAMLFile(file, &values); err != nil { + return nil, err + } + return values, nil +} + +func decodeYAMLFile(r io.Reader, target interface{}) error { + data, err := ioutil.ReadAll(r) + if err != nil { + return err + } + return yaml.Unmarshal(data, target) +} + +func isValuesFile(path string) bool { + basename := filepath.Base(path) + return basename == "values.yaml" || basename == "values.yml" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts_test.go new file mode 100644 index 0000000..8852065 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/charts_test.go @@ -0,0 +1,195 @@ +package image + +import ( + "testing" + + assertlib "github.com/stretchr/testify/assert" +) + +func TestPickImagesFromValuesMap(t *testing.T) { + testCases := []struct { + description string + values map[interface{}]interface{} + chartNameAndVersion string + osType OSType + tagToIgnore string + expectedImagesSet map[string]map[string]struct{} + }{ + { + description: "Want linux images", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "Linux", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{ + "test-repository:1.2.3": { + "chart:0.1.2": struct{}{}, + }, + }, + }, + { + description: "Want Windows images", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "windows,linux", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Windows, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{ + "test-repository:1.2.3": { + "chart:0.1.2": struct{}{}, + }, + }, + }, + { + description: "No images of the given OS (want Windows, but images are Linux)", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "linux", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Windows, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{}, + }, + { + description: "No OS provided, default to Linux", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{ + "test-repository:1.2.3": { + "chart:0.1.2": struct{}{}, + }, + }, + }, + { + description: "Unsupported OS provided", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "unsupported-os", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{}, + }, + { + description: "Missing required information in values file", + values: map[interface{}]interface{}{}, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "", + expectedImagesSet: map[string]map[string]struct{}{}, + }, + { + description: "Ignore an non-matching tag", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "Linux", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "latest", + expectedImagesSet: map[string]map[string]struct{}{ + "test-repository:1.2.3": { + "chart:0.1.2": struct{}{}, + }, + }, + }, + { + description: "Ignore a matching tag", + values: map[interface{}]interface{}{ + "repository": "test-repository", + "tag": "1.2.3", + "os": "Linux", + }, + chartNameAndVersion: "chart:0.1.2", + osType: Linux, + tagToIgnore: "1.2.3", + expectedImagesSet: map[string]map[string]struct{}{}, + }, + } + assert := assertlib.New(t) + for _, tc := range testCases { + actualImagesSet := make(map[string]map[string]struct{}) + err := pickImagesFromValuesMap(actualImagesSet, tc.values, tc.chartNameAndVersion, tc.osType, tc.tagToIgnore) + if err != nil { + t.Errorf("unexpected error: %s", err) + } + assert.Equalf(tc.expectedImagesSet, actualImagesSet, "testcase: %s", tc.description) + } +} + +func TestMinMaxToConstraintStr(t *testing.T) { + testCases := []struct { + min string + max string + expected string + }{ + {"2.5.8", "2.6", "2.5.8 - 2.6"}, + {"2.5.8", "", ">= 2.5.8"}, + {"", "2.6", "<= 2.6"}, + {"", "", ""}, + } + assert := assertlib.New(t) + for _, tc := range testCases { + actual := minMaxToConstraintStr(tc.min, tc.max) + assert.Equal(tc.expected, actual) + } +} + +func TestCompareRancherVersionToConstraint(t *testing.T) { + testCases := []struct { + rancherVersion string + constraintStr string + expected bool + isErr bool + }{ + // Assert true + {"2.6", "<= 2.6", true, false}, + {"2.5.8", ">= 2.5.7", true, false}, + {"2.5.7", "2.5.7 - 2.5.7", true, false}, + {"2.5.7", "2.5.7-rc1 - 2.5.7", true, false}, + {"2.5.7-rc1", "2.5.6 - 2.5.8-rc1", true, false}, + {"2.5.7+up1", ">= 2.5.7-rc1", true, false}, + {"2.5.7", ">= 2.5.7-rc1", true, false}, + {"2.5.7-rc1", ">= 2.5.7-patch1", true, false}, + {"2.5.7-patch1", ">= 2.5.7-beta1", true, false}, + {"2.5.7-beta1", ">= 2.5.7-alpha1", true, false}, + {"2.5.7-alpha1", ">= 2.5.7-0", true, false}, + {"2.6.4-rc1", "2.6.3 - 2.6.5", true, false}, + // Assert false + {"2.5.7", "2.5.8-rc1 - 2.5.8-rc2", false, false}, + // Assert error + {"", "", false, true}, + {"2.5.8", "", false, true}, + // Assert Rancher version 2.6.99 is changed to 2.6.98 to handle edge case when compared against 2.6.99-0 + {"2.6.99", "2.5.99 - 2.6.99-0", true, false}, + } + assert := assertlib.New(t) + for _, tc := range testCases { + actual, err := compareRancherVersionToConstraint(tc.rancherVersion, tc.constraintStr) + if err != nil { + if tc.isErr { + assert.Error(err) + } else { + t.Errorf("unexpected error: %s", err) + } + } + assert.Equalf(tc.expected, actual, "testcase: %v", tc) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/export/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/export/main.go new file mode 100644 index 0000000..9aaf478 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/export/main.go @@ -0,0 +1,67 @@ +package main + +import ( + "log" + "os" + + img "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/image/utilities" +) + +func main() { + if len(os.Args) < 3 { + log.Fatal("\"main.go\" requires 2 arguments. Usage: go run main.go [SYSTEM_CHART_PATH] [CHART_PATH] [OPTIONAL]...") + } + + if err := run(os.Args[1], os.Args[2], os.Args[3:]); err != nil { + log.Fatal(err) + } +} + +func run(systemChartsPath, chartsPath string, imagesFromArgs []string) error { + targetsAndSources, err := utilities.GatherTargetImagesAndSources(systemChartsPath, chartsPath, imagesFromArgs) + if err != nil { + return err + } + + // create rancher-image-origins.txt. Will fail if /pkg/image/origins.go + // does not provide a mapping for each image. + err = img.GenerateImageOrigins(targetsAndSources.LinuxImagesFromArgs, targetsAndSources.TargetLinuxImages, targetsAndSources.TargetWindowsImages) + if err != nil { + return err + } + + type imageTextLists struct { + images []string + imagesAndSources []string + } + for arch, imageLists := range map[string]imageTextLists{ + "linux": {images: targetsAndSources.TargetLinuxImages, imagesAndSources: targetsAndSources.TargetLinuxImagesAndSources}, + "windows": {images: targetsAndSources.TargetWindowsImages, imagesAndSources: targetsAndSources.TargetWindowsImagesAndSources}, + } { + err = utilities.ImagesText(arch, imageLists.images) + if err != nil { + return err + } + + if err = utilities.ImagesAndSourcesText(arch, imageLists.imagesAndSources); err != nil { + return err + } + err = utilities.MirrorScript(arch, imageLists.images) + if err != nil { + return err + } + + err = utilities.SaveScript(arch, imageLists.images) + if err != nil { + return err + } + + err = utilities.LoadScript(arch, imageLists.images) + if err != nil { + return err + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions.go new file mode 100644 index 0000000..ed46726 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions.go @@ -0,0 +1,107 @@ +package image + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/Masterminds/semver/v3" +) + +type ExtensionsConfig struct { + Config ExportConfig +} + +type Release struct { + TagName string `json:"tag_name"` +} + +type GithubEndpoint struct { + URL string +} + +var ExtensionEndpoints = []GithubEndpoint{ + {URL: "https://api.github.com/repos/rancher/ui-plugin-charts/releases"}, +} + +func (e ExtensionsConfig) FetchExtensionImages(imagesSet map[string]map[string]struct{}) error { + for _, endpoint := range e.Config.GithubEndpoints { + // Parse the repository name from the URL + repoName, err := parseRepoName(endpoint.URL) + if err != nil { + return err + } + + // Fetch latest releases from GitHub API for the current endpoint + latestReleases, err := getLatestReleases(endpoint) + if err != nil { + return err + } + + // Find the latest non-RC release + latestReleaseTag := findLatestReleaseTag(latestReleases) + + if latestReleaseTag == "" { + return fmt.Errorf("no suitable release found for endpoint: %s", endpoint.URL) + } + + // Construct the image name based on the repository name and latestReleaseTag + var image string + if repoName == "rancher/ui-plugin-charts" { + image = "rancher/ui-plugin-catalog:" + latestReleaseTag + } else { + image = repoName + ":" + latestReleaseTag + } + addSourceToImage(imagesSet, image, "ui-extension") + } + + return nil +} + +// Helper function to parse the repository name from the GitHub API URL +var parseRepoName = func(url string) (string, error) { + parts := strings.Split(url, "/") + + if len(parts) < 6 || parts[0] != "https:" || parts[2] != "api.github.com" || parts[3] != "repos" { + return "", fmt.Errorf("invalid GitHub API URL format: %s", url) + } + + return parts[4] + "/" + parts[5], nil +} + +func getLatestReleases(githubURL GithubEndpoint) ([]Release, error) { + // Get the releases from GitHub API + resp, err := http.Get(githubURL.URL) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var releases []Release + decoder := json.NewDecoder(resp.Body) + if err := decoder.Decode(&releases); err != nil { + return nil, err + } + + return releases, nil +} + +func findLatestReleaseTag(releases []Release) string { + var latestReleaseTag string + latestVersion := semver.MustParse("0.0.0") + + for _, release := range releases { + // Exclude release candidates (e.g., "1.0.0-rc1") + if !strings.Contains(release.TagName, "-rc") { + version, err := semver.NewVersion(release.TagName) + + if err == nil && version.GreaterThan(latestVersion) { + latestVersion = version + latestReleaseTag = release.TagName + } + } + } + + return latestReleaseTag +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions_test.go new file mode 100644 index 0000000..f351f25 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/extensions_test.go @@ -0,0 +1,138 @@ +package image + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + assertlib "github.com/stretchr/testify/assert" +) + +func setupTestServer() *httptest.Server { + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + releases := []Release{ + {TagName: "1.0.0"}, + {TagName: "1.1.0"}, + {TagName: "1.1.0-rc1"}, + {TagName: "2.0.0-rc2"}, + {TagName: "1.1.1"}, + {TagName: "2.0.0"}, + } + _ = json.NewEncoder(rw).Encode(releases) + })) + + return server +} + +func TestParseRepoName(t *testing.T) { + assert := assertlib.New(t) + + // Test with a valid GitHub API URL + validURL := "https://api.github.com/repos/some-user/some-repo/releases" + repoName, err := parseRepoName(validURL) + assert.NoError(err) + assert.Equal("some-user/some-repo", repoName) + + // Test with an invalid GitHub API URL + invalidURL := "https://example.com/invalid/url" + _, err = parseRepoName(invalidURL) + assert.Error(err) + assert.Contains(err.Error(), "invalid GitHub API URL format") +} + +func TestGetLatestReleases(t *testing.T) { + server := setupTestServer() + defer server.Close() + + assert := assertlib.New(t) + + endpoint := GithubEndpoint{URL: server.URL} + releases, err := getLatestReleases(endpoint) + assert.NoError(err) + assert.Len(releases, 6) + assert.Equal("1.0.0", releases[0].TagName) + assert.Equal("1.1.0", releases[1].TagName) + assert.Equal("1.1.0-rc1", releases[2].TagName) + assert.Equal("2.0.0-rc2", releases[3].TagName) + assert.Equal("1.1.1", releases[4].TagName) + assert.Equal("2.0.0", releases[5].TagName) +} + +func TestFindLatestReleaseTag(t *testing.T) { + releases := []Release{ + {TagName: "1.0.0"}, + {TagName: "1.2.0-rc1"}, + {TagName: "1.1.0"}, + {TagName: "2.0.0-rc2"}, + } + + assert := assertlib.New(t) + + tag := findLatestReleaseTag(releases) + assert.Equal("1.1.0", tag) +} + +func TestFetchExtensionImages(t *testing.T) { + server := setupTestServer() + defer server.Close() + + endpoints := []GithubEndpoint{{URL: server.URL}} + exportConfig := ExportConfig{ + GithubEndpoints: endpoints, + } + extensions := ExtensionsConfig{exportConfig} + + imagesSet := map[string]map[string]struct{}{} + + // Mock the parseRepoName function to return the expected repoName + originalParseRepoName := parseRepoName + parseRepoName = func(url string) (string, error) { + return "some-org/some-repo", nil + } + defer func() { + parseRepoName = originalParseRepoName + }() + + assert := assertlib.New(t) + + err := extensions.FetchExtensionImages(imagesSet) + assert.NoError(err) + + imageKey := "some-org/some-repo:2.0.0" + assert.Contains(imagesSet, imageKey) + assert.Contains(imagesSet[imageKey], "ui-extension") +} + +func TestFetchExtensionImages_NoSuitableRelease(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + releases := []Release{ + {TagName: "1.0.0-rc1"}, + {TagName: "1.1.0-rc1"}, + } + _ = json.NewEncoder(rw).Encode(releases) + })) + defer server.Close() + + endpoints := []GithubEndpoint{{URL: server.URL}} + exportConfig := ExportConfig{ + GithubEndpoints: endpoints, + } + extensions := ExtensionsConfig{exportConfig} + + imagesSet := map[string]map[string]struct{}{} + + originalParseRepoName := parseRepoName + parseRepoName = func(url string) (string, error) { + return "some-org/some-repo", nil + } + defer func() { + parseRepoName = originalParseRepoName + }() + + assert := assertlib.New(t) + + err := extensions.FetchExtensionImages(imagesSet) + assert.Error(err) + assert.EqualError(err, "no suitable release found for endpoint: "+server.URL) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external.go new file mode 100644 index 0000000..dbffb2d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external.go @@ -0,0 +1,175 @@ +package external + +import ( + "fmt" + "io/ioutil" + "net/http" + "sort" + "strings" + + "github.com/coreos/go-semver/semver" + "github.com/rancher/rancher/pkg/controllers/management/k3sbasedupgrade" + "github.com/rancher/rancher/pkg/image" + "github.com/sirupsen/logrus" +) + +type Source string + +const ( + K3S Source = "k3s" + RKE2 Source = "rke2" +) + +func GetExternalImages(rancherVersion string, externalData map[string]interface{}, source Source, minimumKubernetesVersion *semver.Version, osType image.OSType) ([]string, error) { + if source != K3S && source != RKE2 { + return nil, fmt.Errorf("invalid source provided: %s", source) + } + + logrus.Infof("generating %s image list...", source) + externalImagesMap := make(map[string]bool) + releases, _ := externalData["releases"].([]interface{}) + + var compatibleReleases []string + + for _, release := range releases { + releaseMap, _ := release.(map[string]interface{}) + version, _ := releaseMap["version"].(string) + if version == "" { + continue + } + + // Skip the release if a minimum Kubernetes version is provided and is not met. + if minimumKubernetesVersion != nil { + versionSemVer, err := semver.NewVersion(strings.TrimPrefix(version, "v")) + if err != nil { + continue + } + if versionSemVer.LessThan(*minimumKubernetesVersion) { + continue + } + } + + if rancherVersion != "dev" { + maxVersion, _ := releaseMap["maxChannelServerVersion"].(string) + maxVersion = strings.TrimPrefix(maxVersion, "v") + if maxVersion == "" { + continue + } + minVersion, _ := releaseMap["minChannelServerVersion"].(string) + minVersion = strings.Trim(minVersion, "v") + if minVersion == "" { + continue + } + + versionGTMin, err := k3sbasedupgrade.IsNewerVersion(minVersion, rancherVersion) + if err != nil { + continue + } + if rancherVersion != minVersion && !versionGTMin { + // Rancher version not equal to or greater than minimum supported rancher version. + continue + } + + versionLTMax, err := k3sbasedupgrade.IsNewerVersion(rancherVersion, maxVersion) + if err != nil { + continue + } + if rancherVersion != maxVersion && !versionLTMax { + // Rancher version not equal to or greater than maximum supported rancher version. + continue + } + } + + logrus.Debugf("[%s] adding compatible release: %s", source, version) + compatibleReleases = append(compatibleReleases, version) + } + + if compatibleReleases == nil || len(compatibleReleases) < 1 { + logrus.Infof("skipping image generation since no compatible releases were found for version: %s", rancherVersion) + return nil, nil + } + + for _, release := range compatibleReleases { + // Registries don't allow "+", so image names will have these substituted. + upgradeImage := fmt.Sprintf("rancher/%s-upgrade:%s", source, strings.ReplaceAll(release, "+", "-")) + externalImagesMap[upgradeImage] = true + systemAgentInstallerImage := fmt.Sprintf("%s%s:%s", "rancher/system-agent-installer-", source, strings.ReplaceAll(release, "+", "-")) + externalImagesMap[systemAgentInstallerImage] = true + + images, err := downloadExternalSupportingImages(release, source, osType) + if err != nil { + logrus.Infof("could not find supporting images for %s release [%s]: %v", source, release, err) + continue + } + + supportingImages := strings.Split(images, "\n") + if supportingImages[len(supportingImages)-1] == "" { + supportingImages = supportingImages[:len(supportingImages)-1] + } + + for _, imageName := range supportingImages { + imageName = strings.TrimPrefix(imageName, "docker.io/") + externalImagesMap[imageName] = true + } + } + + var externalImages []string + for imageName := range externalImagesMap { + logrus.Debugf("[%s] adding image: %s", source, imageName) + externalImages = append(externalImages, imageName) + } + + sort.Strings(externalImages) + logrus.Infof("finished generating %s image list...", source) + return externalImages, nil +} + +// downloadExternalSupportingImages downloads the list of images used by a Source from GitHub releases. +// The osType parameter is only used by RKE2 since K3s is not currently available for Windows containers. +func downloadExternalSupportingImages(release string, source Source, osType image.OSType) (string, error) { + switch source { + case RKE2: + // FIXME: Support s390x and arm64 images lists. + // rke2 publishes a list of images for s390x but not for arm64 at the moment. + var externalImageURL string + switch osType { + case image.Linux: + externalImageURL = fmt.Sprintf("https://github.com/rancher/rke2/releases/download/%s/rke2-images-all.linux-amd64.txt", release) + case image.Windows: + externalImageURL = fmt.Sprintf("https://github.com/rancher/rke2/releases/download/%s/rke2-images.windows-amd64.txt", release) + default: + return "", fmt.Errorf("could not download external supporting images: unsupported os type %v", osType) + } + images, err := downloadExternalImageListFromURL(externalImageURL) + if err != nil { + return "", err + } + return images, nil + case K3S: + // k3s does not support Windows containers at the moment. + return downloadExternalImageListFromURL(fmt.Sprintf("https://github.com/k3s-io/k3s/releases/download/%s/k3s-images.txt", release)) + default: + // This function should never be called with an invalid source, but we will anticipate this + // error for safety. + return "", fmt.Errorf("invalid source provided for download: %s", source) + } +} + +func downloadExternalImageListFromURL(url string) (string, error) { + resp, err := http.Get(url) + if err != nil { + return "", err + } + + body, err := ioutil.ReadAll(resp.Body) + if resp.StatusCode != 200 { + return "", fmt.Errorf("failed to get url: %v", string(body)) + } + defer resp.Body.Close() + + if err != nil { + return "", err + } + + return string(body), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external_test.go new file mode 100644 index 0000000..a9afaa2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/external/external_test.go @@ -0,0 +1,263 @@ +package external + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "testing" + + "github.com/coreos/go-semver/semver" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rke/types/kdm" + "github.com/stretchr/testify/assert" +) + +const ( + k3s = "k3s" + rancherVersion = "v2.6.4" + k3sWebVersion = "v1.23.6+k3s1" + rke2WebVersion = "v1.23.6+rke2r1" + rke2 = "rke2" + rke1 = "rke1" + devKDM = "https://github.com/rancher/kontainer-driver-metadata/raw/dev-v2.6/data/data.json" + releaseKDM = "https://releases.rancher.com/kontainer-driver-metadata/release-v2.6/data.json" +) + +func TestGetExternalImages(t *testing.T) { + kubeSemVer := &semver.Version{ + Major: 1, + Minor: 21, + Patch: 0, + } + + type args struct { + rancherVersion string + externalData map[string]interface{} + source Source + minimumKubernetesVersion *semver.Version + kdmUrl string + image1 string + image2 string + image3 string + version string + } + + tests := []struct { + name string + args args + want []string + wantErr bool + }{ + { + name: "k3s-test", + args: args{ + rancherVersion: rancherVersion, + externalData: map[string]interface{}{}, + source: k3s, + version: k3sWebVersion, + minimumKubernetesVersion: kubeSemVer, + kdmUrl: devKDM, + image1: "rancher/klipper-lb:v0.3.5", + image2: "rancher/mirrored-pause:3.6", + image3: "rancher/mirrored-metrics-server:v0.5.2", + }, + wantErr: false, + }, + { + name: "rke2-test", + args: args{ + rancherVersion: rancherVersion, + externalData: map[string]interface{}{}, + source: rke2, + version: rke2WebVersion, + minimumKubernetesVersion: kubeSemVer, + kdmUrl: releaseKDM, + image1: "rancher/pause:3.6", + image2: "rancher/rke2-runtime:v1.23.6-rke2r1", + image3: "rancher/rke2-cloud-provider:v0.0.3-build20211118", + }, + wantErr: false, + }, + { + name: "rke1-test-fail", + args: args{ + rancherVersion: rancherVersion, + externalData: map[string]interface{}{}, + source: rke1, + minimumKubernetesVersion: kubeSemVer, + kdmUrl: releaseKDM, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := assert.New(t) + get, err := http.Get(tt.args.kdmUrl) + if err != nil { + t.Errorf("failed to get KDM data.json from url %v", tt.args.kdmUrl) + } + resp, err := ioutil.ReadAll(get.Body) + if err != nil { + t.Errorf("failed to read response from url %v", tt.args.kdmUrl) + } + data, err := kdm.FromData(resp) + if err != nil { + t.Error(err) + } + switch tt.args.source { + case rke2: + tt.args.externalData = data.RKE2 + case k3s: + tt.args.externalData = data.K3S + } + systemAgentInstallerImage := fmt.Sprintf("%s%s:%s", "rancher/system-agent-installer-", tt.args.source, strings.ReplaceAll(tt.args.version, "+", "-")) + + got, err := GetExternalImages(tt.args.rancherVersion, tt.args.externalData, tt.args.source, tt.args.minimumKubernetesVersion, image.Linux) + if err != nil { + a.Equal(tt.wantErr, true, "GetExternalImages() errored as expected") + } + if !tt.wantErr { + a.NotEmpty(got) + a.Contains(got, systemAgentInstallerImage) + a.Contains(got, tt.args.image1) + a.Contains(got, tt.args.image2) + a.Contains(got, tt.args.image3) + } + }) + } +} + +func Test_downloadExternalImageListFromURL(t *testing.T) { + type args struct { + url string + image1 string + image2 string + image3 string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "k3s-url", + args: args{ + url: fmt.Sprintf("https://github.com/k3s-io/k3s/releases/download/%s/k3s-images.txt", k3sWebVersion), + image1: "rancher/klipper-lb:v0.3.5", + image2: "rancher/mirrored-pause:3.6", + image3: "rancher/mirrored-metrics-server:v0.5.2", + }, + }, + { + name: "rke2-url-linux", + args: args{ + url: fmt.Sprintf("https://github.com/rancher/rke2/releases/download/%s/rke2-images-all.linux-amd64.txt", rke2WebVersion), + image1: "rancher/pause:3.6", + image2: "rancher/rke2-runtime:v1.23.6-rke2r1", + image3: "rancher/rke2-cloud-provider:v0.0.3-build20211118", + }, + }, + { + name: "rke2-url-windows", + args: args{ + url: fmt.Sprintf("https://github.com/rancher/rke2/releases/download/%s/rke2-images.windows-amd64.txt", rke2WebVersion), + image1: "docker.io/rancher/rke2-runtime:v1.23.6-rke2r1-windows-amd64", + image2: "rancher/pause:3.6-windows-1809-amd64", + image3: "rancher/pause:3.6-windows-ltsc2022-amd64", + }, + }, + { + name: "rancher-url", + args: args{ + url: fmt.Sprintf("https://github.com/rancher/rancher/releases/download/%s/rancher-images.txt", rancherVersion), + image1: "fleet-agent:v0.3.9", + image2: "rancher/system-agent-installer-rke2:v1.23.4-rke2r2", + image3: "rancher/rancher-agent:" + rancherVersion, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := assert.New(t) + got, err := downloadExternalImageListFromURL(tt.args.url) + if (err != nil) != tt.wantErr { + t.Errorf("downloadExternalImageListFromURL() error = %v, wantErr %v", err, tt.wantErr) + return + } + a.NotEmpty(got) + a.Contains(got, tt.args.image1) + a.Contains(got, tt.args.image2) + a.Contains(got, tt.args.image3) + }) + } +} + +func Test_downloadExternalSupportingImages(t *testing.T) { + type args struct { + release string + source Source + os image.OSType + image1 string + image2 string + image3 string + image4 string + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "k3s-images", + args: args{ + release: k3sWebVersion, + source: k3s, + os: image.Linux, + image1: "rancher/klipper-lb:v0.3.5", + image2: "rancher/mirrored-pause:3.6", + image3: "rancher/mirrored-coredns-coredns:1.9.1", + image4: "rancher/mirrored-metrics-server:v0.5.2", + }, + }, + { + name: "rke2-images-linux", + args: args{ + release: rke2WebVersion, + source: rke2, + os: image.Linux, + image1: "rancher/harvester-csi-driver:v0.1.3", + image2: "rancher/rke2-runtime:v1.23.6-rke2r1", + image3: "rancher/rke2-cloud-provider:v0.0.3-build20211118", + }, + }, + { + name: "rke2-images-windows", + args: args{ + release: rke2WebVersion, + source: rke2, + os: image.Windows, + image1: "rancher/rke2-runtime:v1.23.6-rke2r1-windows-amd64", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := assert.New(t) + + got, err := downloadExternalSupportingImages(url.QueryEscape(tt.args.release), tt.args.source, tt.args.os) + if err != nil { + t.Errorf("downloadExternalSupportingImages() error = %v, wantErr %v", err, tt.wantErr) + } + a.NotEmpty(got) + a.Contains(got, tt.args.image1) + a.Contains(got, tt.args.image2) + a.Contains(got, tt.args.image3) + a.Contains(got, tt.args.image4) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins.go new file mode 100644 index 0000000..f6d090f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins.go @@ -0,0 +1,356 @@ +package image + +import ( + "fmt" + "log" + "os" + "strings" +) + +// OriginMap is a mapping between images used by Rancher +// and their origin repository. This map must be updated +// when net-new images are added to Rancher or images are +// no longer used by Rancher. The keys of this map should +// mirror the images listed in rancher-images.txt. +// Some net-new images may be resolved via the check-origins script +// (dapper check-origins). + +// images should be double-checked and confirmed +// by the team which owns the image. + +var OriginMap = map[string]string{ + "aci-containers-controller": "https://github.com/noironetworks/aci-containers", + "aci-containers-host": "https://github.com/noironetworks/aci-containers", + "aks-operator": "https://github.com/rancher/aks-operator", + "backup-restore-operator": "https://github.com/rancher/backup-restore-operator", + "calico-cni": "https://github.com/rancher/calico-cni", + "cis-operator": "https://github.com/rancher/cis-operator", + "cnideploy": "https://github.com/containernetworking/plugins", + "coreos-kube-state-metrics": "https://github.com/kubernetes/kube-state-metrics", + "coreos-prometheus-config-reloader": "https://github.com/prometheus-operator/prometheus-operator/pkgs/container/prometheus-config-reloader", + "coreos-prometheus-operator": "https://github.com/prometheus-operator/prometheus-operator", + "eks-operator": "https://github.com/rancher/eks-operator", + "externalip-webhook": "https://github.com/rancher/externalip-webhook", + "flannel-cni": "https://github.com/rancher/flannel-cni", + "fleet": "https://github.com/rancher/fleet", + "fleet-agent": "https://github.com/rancher/fleet", + "fluent-bit": "https://github.com/fluent/fluent-bit", + "gbp-server": "https://github.com/noironetworks/aci-containers/tree/master/pkg/gbpserver", + "gitjob": "https://github.com/rancher/gitjob", + "gke-operator": "https://github.com/rancher/gke-operator", + "grafana-grafana": "https://github.com/grafana/grafana", + "hardened-addon-resizer": "https://github.com/rancher/image-build-addon-resizer", + "hardened-calico": "https://github.com/rancher/image-build-calico", + "hardened-cluster-autoscaler": "https://github.com/kubernetes/autoscaler", + "hardened-cni-plugins": "https://github.com/rancher/image-build-cni-plugins", + "hardened-coredns": "https://github.com/rancher/image-build-coredns", + "hardened-dns-node-cache": "https://github.com/rancher/image-build-dns-nodecache", + "hardened-etcd": "https://github.com/rancher/image-build-etcd", + "hardened-flannel": "https://github.com/rancher/image-build-flannel", + "hardened-ib-sriov-cni": "https://github.com/rancher/image-build-ib-sriov-cni", + "hardened-k8s-metrics-server": "https://github.com/rancher/image-build-k8s-metrics-server", + "hardened-kubernetes": "https://github.com/rancher/image-build-kubernetes", + "hardened-multus-cni": "https://github.com/rancher/image-build-multus", + "hardened-node-feature-discovery": "https://github.com/rancher/image-build-node-feature-discovery", + "hardened-sriov-cni": "https://github.com/rancher/image-build-sriov-cni", + "hardened-sriov-network-config-daemon": "https://github.com/openshift/sriov-network-operator/blob/master/Dockerfile.sriov-network-config-daemon", + "hardened-sriov-network-device-plugin": "https://github.com/rancher/image-build-sriov-network-device-plugin", + "hardened-sriov-network-operator": "https://github.com/rancher/image-build-sriov-operator", + "hardened-sriov-network-resources-injector": "https://github.com/rancher/image-build-sriov-network-resources-injector", + "hardened-sriov-network-webhook": "https://github.com/openshift/sriov-network-webhook", + "hardened-whereabouts": "https://github.com/rancher/image-build-whereabouts", + "harvester-cloud-provider": "https://github.com/harvester/cloud-provider-harvester", + "harvester-csi-driver": "https://github.com/harvester/harvester-csi-driver", + "helm-project-operator": "https://github.com/rancher/helm-project-operator", + "hyperkube": "https://github.com/rancher/hyperkube", + "istio-1.5-migration": "https://github.com/rancher/istio-1.5-migration", + "istio-installer": "https://github.com/rancher/istio-installer", + "istio-kubectl": "https://github.com/istio/istio", + "jimmidyson-configmap-reload": "https://github.com/jimmidyson/configmap-reload", + "k3s-upgrade": "https://github.com/rancher/k3s-upgrade", + "klipper-helm": "https://github.com/rancher/klipper-helm", + "klipper-lb": "https://github.com/rancher/klipper-lb", + "kube-api-auth": "https://github.com/rancher/kube-api-auth", + "kubectl": "https://github.com/rancher/kubectl", + "kubelet-pause": "https://github.com/kubernetes/kubernetes", + "library-nginx": "https://github.com/nginx/nginx", + "local-path-provisioner": "https://github.com/rancher/local-path-provisioner", + "longhornio-csi-attacher": "https://github.com/longhorn/longhorn", + "longhornio-csi-node-driver-registrar": "https://github.com/longhorn/node-driver-registrar", + "longhornio-csi-provisioner": "https://github.com/longhorn/longhorn", + "longhornio-csi-resizer": "https://github.com/longhorn/longhorn", + "machine": "https://github.com/rancher/machine", + "mirrored-amazon-aws-cli": "https://github.com/aws/aws-cli", + "mirrored-appscode-kubed": "https://github.com/kubeops/config-syncer", + "mirrored-banzaicloud-fluentd": "https://github.com/fluent/fluentd", + "mirrored-banzaicloud-logging-operator": "https://github.com/banzaicloud/logging-operator", + "mirrored-bci-busybox": "https://build.opensuse.org/package/show/devel:BCI:SLE-15-SP4/busybox-image", + "mirrored-bci-micro": "https://build.opensuse.org/package/show/devel:BCI:SLE-15-SP4/micro-image", + "mirrored-calico-apiserver": "https://github.com/projectcalico/calico/tree/master/apiserver", + "mirrored-calico-cni": "https://github.com/projectcalico/calico", + "mirrored-calico-csi": "https://github.com/projectcalico/calico", + "mirrored-calico-ctl": "https://github.com/projectcalico/calico/tree/master/calicoctl", + "mirrored-calico-kube-controllers": "https://github.com/projectcalico/calico/tree/master/kube-controllers", + "mirrored-calico-node": "https://github.com/projectcalico/calico/tree/master/node", + "mirrored-calico-node-driver-registrar": "https://github.com/projectcalico/calico", + "mirrored-calico-operator": "https://github.com/projectcalico/calico", + "mirrored-calico-pod2daemon-flexvol": "https://github.com/projectcalico/calico/tree/master/pod2daemon", + "mirrored-calico-typha": "https://github.com/projectcalico/calico/tree/master/typha", + "mirrored-cilium-certgen": "https://github.com/cilium/certgen", + "mirrored-cilium-cilium": "https://github.com/cilium/cilium", + "mirrored-cilium-cilium-envoy": "https://github.com/cilium/proxy", + "mirrored-cilium-cilium-etcd-operator": "https://github.com/cilium/cilium-etcd-operator", + "mirrored-cilium-clustermesh-apiserver": "https://github.com/cilium/clustermesh-apiserver", + "mirrored-cilium-hubble-relay": "https://github.com/cilium/hubble", + "mirrored-cilium-hubble-ui": "https://github.com/cilium/hubble-ui", + "mirrored-cilium-hubble-ui-backend": "https://github.com/cilium/hubble-ui", + "mirrored-cilium-kvstoremesh": "https://github.com/cilium/cilium", + "mirrored-cilium-operator-aws": "https://github.com/cilium/cilium/tree/master/pkg/aws", + "mirrored-cilium-operator-azure": "https://github.com/cilium/cilium/tree/master/pkg/azure", + "mirrored-cilium-operator-generic": "https://github.com/cilium/cilium", + "mirrored-cilium-startup-script": "https://github.com/cilium/cilium", + "mirrored-cloud-provider-vsphere-cpi-release-manager": "https://github.com/kubernetes/cloud-provider-vsphere/blob/master/cluster/images/controller-manager/Dockerfile", + "mirrored-cloud-provider-vsphere-csi-release-driver": "https://github.com/kubernetes-sigs/vsphere-csi-driver", + "mirrored-cloud-provider-vsphere-csi-release-syncer": "https://github.com/kubernetes-sigs/vsphere-csi-driver/tree/master/pkg/syncer", + "mirrored-cluster-api-controller": "https://github.com/kubernetes-sigs/cluster-api", + "mirrored-cluster-proportional-autoscaler": "https://github.com/kubernetes-sigs/cluster-proportional-autoscaler", + "mirrored-coredns-coredns": "https://github.com/coredns/coredns", + "mirrored-coreos-etcd": "https://github.com/etcd-io/etcd", + "mirrored-coreos-flannel": "https://github.com/flannel-io/flannel", + "mirrored-coreos-prometheus-config-reloader": "https://github.com/prometheus-operator/prometheus-operator/pkgs/container/prometheus-config-reloader", + "mirrored-coreos-prometheus-operator": "https://github.com/prometheus-operator/prometheus-operator", + "mirrored-curlimages-curl": "https://github.com/curl/curl-docker", + "mirrored-dexidp-dex": "https://github.com/dexidp/dex", + "mirrored-directxman12-k8s-prometheus-adapter": "https://hub.docker.com/r/directxman12/k8s-prometheus-adapter/tags", + "mirrored-elemental-operator": "https://github.com/rancher/elemental-operator", + "mirrored-elemental-seedimage-builder": "https://github.com/rancher/elemental-operator", + "mirrored-epinio-epinio-server": "https://github.com/epinio/epinio", + "mirrored-epinio-epinio-ui": "https://github.com/kubeops/config-syncer", + "mirrored-epinio-epinio-unpacker": "https://github.com/epinio/epinio", + "mirrored-flannelcni-flannel": "https://github.com/flannel-io/flannel", + "mirrored-flannel-flannel": "https://github.com/flannel-io/flannel", + "mirrored-fluent-fluent-bit": "https://github.com/fluent/fluent-bit", + "mirrored-grafana-grafana": "https://github.com/grafana/grafana", + "mirrored-grafana-grafana-image-renderer": "https://github.com/grafana/grafana-image-renderer", + "mirrored-idealista-prom2teams": "https://github.com/idealista/prom2teams", + "mirrored-ingress-nginx-kube-webhook-certgen": "https://github.com/jet/kube-webhook-certgen", + "mirrored-istio-citadel": "https://github.com/istio/istio/tree/master", + "mirrored-istio-coredns-plugin": "https://github.com/istio/istio", + "mirrored-istio-galley": "https://github.com/istio/istio", + "mirrored-istio-install-cni": "https://github.com/istio/istio", + "mirrored-istio-kubectl": "https://github.com/istio/istio", + "mirrored-istio-mixer": "https://github.com/envoyproxy/envoy", + "mirrored-istio-node-agent-k8s": "https://github.com/istio/istio/tree/master/pkg/istio-agent", + "mirrored-istio-pilot": "https://github.com/istio/istio/tree/master/pilot", + "mirrored-istio-proxyv2": "https://github.com/istio/istio/blob/master/pilot/docker/Dockerfile.proxyv2", + "mirrored-istio-sidecar_injector": "https://github.com/istio/istio/blob/1.5.9/pilot/pkg/bootstrap/sidecarinjector.go", + "mirrored-jaegertracing-all-in-one": "https://github.com/jaegertracing/jaeger/tree/main/cmd/all-in-one", + "mirrored-jetstack-cert-manager-controller": "https://github.com/cert-manager/cert-manager", + "mirrored-jimmidyson-configmap-reload": "https://github.com/jimmidyson/configmap-reload", + "mirrored-k8s-dns-dnsmasq-nanny": "https://github.com/kubernetes/dns", + "mirrored-k8s-dns-kube-dns": "https://github.com/kubernetes/dns", + "mirrored-k8s-dns-node-cache": "https://github.com/kubernetes/dns", + "mirrored-k8s-dns-sidecar": "https://github.com/kubernetes/dns", + "mirrored-k8scsi-csi-node-driver-registrar": "https://github.com/kubernetes-csi/node-driver-registrar", + "mirrored-k8scsi-csi-resizer": "https://github.com/kubernetes-csi/external-resizer", + "mirrored-k8scsi-livenessprobe": "https://github.com/kubernetes-csi/livenessprobe", + "mirrored-kiali-kiali": "https://github.com/kiali/kiali", + "mirrored-kiwigrid-k8s-sidecar": "https://github.com/kiwigrid/k8s-sidecar", + "mirrored-kube-logging-logging-operator": "https://github.com/kube-logging/logging-operator", + "mirrored-kube-rbac-proxy": "https://github.com/brancz/kube-rbac-proxy", + "mirrored-kube-state-metrics-kube-state-metrics": "https://github.com/kubernetes/kube-state-metrics", + "mirrored-kube-vip-kube-vip-iptables": "https://github.com/kube-vip/kube-vip", + "mirrored-kubernetes-external-dns": "https://github.com/kubernetes-sigs/external-dns", + "mirrored-library-busybox": "https://github.com/docker-library/busybox", + "mirrored-library-nginx": "https://github.com/docker-library/nginx", + "mirrored-library-registry": "https://github.com/docker-library/official-images", + "mirrored-library-traefik": "https://github.com/traefik/traefik-library-image", + "mirrored-longhornio-backing-image-manager": "https://github.com/longhorn/backing-image-manager", + "mirrored-longhornio-csi-attacher": "https://github.com/longhorn/external-attacher", + "mirrored-longhornio-csi-node-driver-registrar": "https://github.com/longhorn/node-driver-registrar", + "mirrored-longhornio-csi-provisioner": "https://github.com/longhorn/external-provisioner", + "mirrored-longhornio-csi-resizer": "https://github.com/longhorn/external-resizer", + "mirrored-longhornio-csi-snapshotter": "https://github.com/longhorn/external-snapshotter", + "mirrored-longhornio-livenessprobe": "https://github.com/longhorn/longhorn", + "mirrored-longhornio-longhorn-engine": "https://github.com/longhorn/longhorn-engine", + "mirrored-longhornio-longhorn-instance-manager": "https://github.com/longhorn/longhorn-instance-manager", + "mirrored-longhornio-longhorn-manager": "https://github.com/longhorn/longhorn-manager", + "mirrored-longhornio-longhorn-share-manager": "https://github.com/longhorn/longhorn-share-manager", + "mirrored-longhornio-longhorn-ui": "https://github.com/longhorn/longhorn-ui", + "mirrored-longhornio-support-bundle-kit": "https://github.com/longhorn/longhorn", + "mirrored-longhornio-openshift-origin-oauth-proxy": "https://github.com/longhorn/longhorn", + "mirrored-messagebird-sachet": "https://github.com/messagebird/sachet", + "mirrored-metrics-server": "https://github.com/kubernetes-sigs/metrics-server", + "mirrored-minio-mc": "https://github.com/minio/mc", + "mirrored-minio-minio": "https://github.com/minio/minio", + "mirrored-neuvector-controller": "https://github.com/neuvector/neuvector", + "mirrored-neuvector-enforcer": "https://github.com/neuvector/neuvector", + "mirrored-neuvector-manager": "https://github.com/neuvector/manager", + "mirrored-neuvector-scanner": "https://github.com/neuvector/scanner", + "mirrored-neuvector-updater": "https://github.com/neuvector/neuvector", + "mirrored-neuvector-prometheus-exporter": "https://github.com/neuvector/prometheus-exporter", + "mirrored-neuvector-registry-adapter": "https://github.com/neuvector/registry-adapter", + "mirrored-nginx-ingress-controller-defaultbackend": "https://github.com/rancher/ingress-nginx", + "mirrored-openpolicyagent-gatekeeper": "https://github.com/open-policy-agent/gatekeeper", + "mirrored-openpolicyagent-gatekeeper-crds": "https://github.com/open-policy-agent/gatekeeper", + "mirrored-openzipkin-zipkin": "https://github.com/openzipkin/zipkin", + "mirrored-paketobuildpacks-builder": "https://github.com/paketo-buildpacks/full-builder", + "mirrored-pause": "https://hub.docker.com/r/kubernetes/pause", + "mirrored-prom-node-exporter": "https://github.com/prometheus/node_exporter", + "mirrored-prom-prometheus": "https://github.com/prometheus/prometheus", + "mirrored-prometheus-adapter-prometheus-adapter": "https://github.com/kubernetes-sigs/prometheus-adapter", + "mirrored-prometheus-alertmanager": "https://github.com/prometheus/alertmanager", + "mirrored-prometheus-node-exporter": "https://github.com/prometheus/node_exporter", + "mirrored-prometheus-operator-prometheus-config-reloader": "https://github.com/prometheus-operator/prometheus-operator/pkgs/container/prometheus-config-reloader", + "mirrored-prometheus-operator-prometheus-operator": "https://github.com/prometheus-operator/prometheus-operator", + "mirrored-prometheus-operator-admission-webhook": "https://github.com/prometheus-operator/prometheus-operator/pkgs/container/admission-webhook", + "mirrored-prometheus-prometheus": "https://github.com/prometheus/prometheus", + "mirrored-prometheus-windows-exporter": "https://github.com/prometheus-community/windows_exporter", + "mirrored-pstauffer-curl": "https://github.com/pstauffer/docker-curl", + "mirrored-s3gw-s3gw": "https://github.com/aquarist-labs/s3gw", + "mirrored-sig-storage-csi-attacher": "https://github.com/kubernetes-csi/external-attacher", + "mirrored-sig-storage-csi-node-driver-registrar": "https://github.com/kubernetes-csi/node-driver-registrar", + "mirrored-sig-storage-csi-provisioner": "https://github.com/kubernetes-csi/external-provisioner", + "mirrored-sig-storage-csi-resizer": "https://github.com/kubernetes-csi/external-resizer", + "mirrored-sig-storage-livenessprobe": "https://github.com/kubernetes-csi/livenessprobe", + "mirrored-sig-storage-csi-snapshotter": "https://github.com/kubernetes-csi/external-snapshotter", + "mirrored-sig-storage-snapshot-controller": "https://github.com/kubernetes-csi/external-snapshotter", + "mirrored-sig-storage-snapshot-validation-webhook": "https://github.com/kubernetes-csi/external-snapshotter", + "mirrored-sigwindowstools-k8s-gmsa-webhook": "https://github.com/kubernetes-sigs/windows-gmsa/tree/master/admission-webhook", + "mirrored-sonobuoy-sonobuoy": "https://github.com/vmware-tanzu/sonobuoy", + "mirrored-thanos-thanos": "https://github.com/thanos-io/thanos", + "mirrored-thanosio-thanos": "https://github.com/thanos-io/thanos", + "nginx-ingress-controller": "https://github.com/rancher/ingress-nginx", + "mirrored-skopeo-skopeo": "https://github.com/containers/skopeo", + "openvswitch": "https://github.com/servicefractal/ovs", + "opflex": "https://github.com/noironetworks/opflex", + "opflex-server": "https://github.com/noironetworks/opflex", + "pause": "https://hub.docker.com/r/kubernetes/pause", + "prom-alertmanager": "https://github.com/prometheus/alertmanager", + "prom-node-exporter": "https://github.com/prometheus/node_exporter", + "prom-prometheus": "https://github.com/prometheus/prometheus", + "prometheus-auth": "https://github.com/rancher/prometheus-auth", + "prometheus-federator": "https://github.com/rancher/prometheus-federator", + "pushprox-client": "https://github.com/rancher/PushProx", + "pushprox-proxy": "https://github.com/rancher/PushProx", + "rancher": "https://github.com/rancher/rancher", + "rancher-agent": "https://github.com/rancher/rancher", + "rancher-csp-adapter": "https://github.com/rancher/csp-adapter", + "rancher-webhook": "https://github.com/rancher/webhook", + "rke-tools": "https://github.com/rancher/rke-tools", + "rke2-cloud-provider": "https://github.com/rancher/image-build-rke2-cloud-provider", + "rke2-runtime": "https://github.com/rancher/rke2", + "rke2-upgrade": "https://github.com/rancher/rke2-upgrade", + "security-scan": "https://github.com/rancher/security-scan", + "shell": "https://github.com/rancher/shell", + "system-agent": "https://github.com/rancher/system-agent", + "system-agent-installer-k3s": "https://github.com/rancher/system-agent-installer-k3s", + "system-agent-installer-rke2": "https://github.com/rancher/system-agent-installer-rke2", + "system-upgrade-controller": "https://github.com/rancher/system-upgrade-controller", + "tekton-utils": "https://github.com/rancher/build-tekton", + "thanosio-thanos": "https://github.com/thanos-io/thanos", + "ui-plugin-operator": "https://github.com/rancher/ui-plugin-operator", + "ui-plugin-catalog": "https://github.com/rancher/ui-plugin-charts", + "weave-kube": "https://github.com/weaveworks-experiments/weave-kube", + "weave-npc": "https://github.com/weaveworks/weave", + "webhook-receiver": "https://github.com/rancher/webhook-receiver", + "windows_exporter-package": "https://github.com/rancher/windows_exporter-package", + "wins": "https://github.com/rancher/wins", + "wmi_exporter-package": "https://github.com/rancher/wmi_exporter-package", +} + +const ( + imageOriginFileName = "rancher-images-origins.txt" +) + +// GenerateImageOrigins looks through all target images gathered from KDM/Charts and +// ensures that they are covered by the OriginMap. If so, a file titled `rancher-image-origins.txt` will be written, +// containing a space delimited list of un-versioned images and their source code repository. +func GenerateImageOrigins(linuxImagesFromArgs, targetImages, targetWindowsImages []string) error { + log.Printf("building %s", imageOriginFileName) + + allImages := GetAllUniqueImages(linuxImagesFromArgs, targetImages, targetWindowsImages) + + // if any image does not have a source + // declared, or if a net-new image has been + // added via KDM or charts and is not + // included in the OriginMap + // then we cannot continue as the + // artifact would be incomplete. + if UnknownImages := GatherUnknownImages(allImages); len(UnknownImages) > 0 { + return fmt.Errorf("[ERROR] not all images have a source code origin defined. Please provide origin URL's within rancher/pkg/image/origins.go for the following images: \n%s", UnknownImages) + } + + // format file + fileContents := "" + for k, v := range OriginMap { + fileContents = fileContents + k + " " + v + "\n" + } + + originsFile, err := os.Create(imageOriginFileName) + if err != nil { + return fmt.Errorf("could not create %s file: %w", imageOriginFileName, err) + } + + originsFile.Chmod(0755) + originsFile.WriteString(fileContents) + return originsFile.Close() +} + +// GetAllUniqueImages looks through all the images gathered from KDM/Charts +// and returns a list of unique images, ignoring the image version +func GetAllUniqueImages(images ...[]string) []string { + var allImages []string + for _, imagesSlice := range images { + allImages = append(allImages, UniqueTargetImages(imagesSlice)...) + } + return allImages +} + +// GatherUnknownImages compares all images gathered from KDM and charts +// against the current OriginMap and finds repositories which are not currently +// included in the OriginMap. +func GatherUnknownImages(allImages []string) string { + // compare all known images with images gathered + // from KDM / Charts to detect images missing from OriginsMap. + var unknownImages string + for _, e := range allImages { + url, ok := OriginMap[e] + if !ok || url == "" || url == "unknown" { + unknownImages = unknownImages + e + "\n" + } + } + return unknownImages +} + +// repoFromImage strips away the repository and version +// of a given image. +func repoFromImage(image string) string { + split := strings.Split(image, "/") + if len(split) != 2 { + return "" + } + + split = strings.Split(split[1], ":") + if len(split) != 2 { + return "" + } + + return split[0] +} + +// UniqueTargetImages finds unique images in a list of targetImages, +// ignoring the image version +func UniqueTargetImages(targetImages []string) []string { + seenImages := make(map[string]interface{}) + var uniqueImages []string + for _, e := range targetImages { + repo := repoFromImage(e) + _, ok := seenImages[repo] + if !ok && repo != "" { + seenImages[repo] = true + uniqueImages = append(uniqueImages, repo) + } + } + return uniqueImages +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins/main.go new file mode 100644 index 0000000..09a8529 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins/main.go @@ -0,0 +1,200 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "sort" + "strings" + + "github.com/rancher/rancher/pkg/image/utilities" + + img "github.com/rancher/rancher/pkg/image" +) + +// This file attempts to create an updated mapping of images used in rancher and their source code origin. +// It does so on a best-effort basis and prints the resulting map to the terminal. Rancher images which share a name +// with their base repository (such as gke-operator, which comes from github.com/rancher/gke-operator) will be +// automatically resolved. In the case where images are detected but cannot be automatically resolved, a warning +// will be printed to the console indicating such images, and the value of the image in the map will be 'unknown'. +// +// This tool can be run with the command `dapper check-origins`. + +func main() { + if err := inner(os.Args[1], os.Args[2], os.Args[3:]); err != nil { + panic(err) + } +} + +const imageNotFound = "image not found" + +func inner(systemChartsPath, chartsPath string, imagesFromArgs []string) error { + targetsAndSources, err := utilities.GatherTargetImagesAndSources(systemChartsPath, chartsPath, imagesFromArgs) + if err != nil { + return err + } + + unusedImages := CheckForImagesNoLongerBeingUsed(targetsAndSources) + if len(unusedImages) > 0 { + fmt.Println("Some images are no longer used by Rancher, please remove the following images from pkg/image/origin.go: ", unusedImages) + } + + return PrintUpdatedImageOrigins(targetsAndSources) +} + +// CheckForImagesNoLongerBeingUsed determines if /pkg/img/origins.go has keys within the map which +// are no longer relevant. If so, they should be removed from /pkg/img/origins.go so that rancher-origins.txt +// is up-to-date for the current version of Rancher. +func CheckForImagesNoLongerBeingUsed(targetsAndSources utilities.ImageTargetsAndSources) []string { + currentImages := make(map[string]interface{}) + for _, e := range img.UniqueTargetImages(targetsAndSources.LinuxImagesFromArgs) { + currentImages[e] = true + } + + for _, e := range img.UniqueTargetImages(targetsAndSources.TargetLinuxImages) { + currentImages[e] = true + } + + for _, e := range img.UniqueTargetImages(targetsAndSources.TargetWindowsImages) { + currentImages[e] = true + } + + var unusedImages []string + for k := range img.OriginMap { + _, ok := currentImages[k] + if !ok { + unusedImages = append(unusedImages, k) + } + } + + return unusedImages +} + +func PrintUpdatedImageOrigins(targetsAndSources utilities.ImageTargetsAndSources) error { + fmt.Println("Generating updated rancher-image-origins map") + + // use the existing map so that we don't + // check images which have already been resolved. + imgToURL := img.OriginMap + + // look through any images passed as arguments + err := convertImagesToRepoUrls(targetsAndSources.LinuxImagesFromArgs, imgToURL) + if err != nil { + return err + } + // look through the linux target images + err = convertImagesToRepoUrls(targetsAndSources.TargetLinuxImages, imgToURL) + if err != nil { + return err + } + // look through the windows target images + err = convertImagesToRepoUrls(targetsAndSources.TargetWindowsImages, imgToURL) + if err != nil { + return err + } + + // order images alphabetically + type sorter struct { + img string + url string + } + var sorted []sorter + for k, v := range imgToURL { + sorted = append(sorted, sorter{img: k, url: v}) + } + + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].img < sorted[j].img + }) + + x := "OriginMap = map[string]string{\n" + for _, e := range sorted { + x = x + " \"" + e.img + "\":" + " " + "\"" + e.url + "\"," + "\n" + } + x = x + "}\n" + + // print result, can be copied into pkg/image/origins.go + // to automatically update some images. + fmt.Println(x) + + // find all images that have not been resolved yet + var unknownImages string + for k, v := range imgToURL { + if v == "" || v == "unknown" { + unknownImages = unknownImages + "\n" + k + } + } + + // warn about unresolved images + // so that they may be manually resolved + if len(unknownImages) > 0 { + fmt.Println(fmt.Sprintf("[WARN] Some images do not have an origin defined, please provide origins within rancher/pkg/image/origins.go for the following images: %s", unknownImages)) + } + + return nil +} + +// convertImagesToRepoUrls attempts to resolve Rancher owned images with its origin repository. +// It does so on a best-effort basis, any gaps left by this must be covered manually +// in the OriginMap in origins.go +func convertImagesToRepoUrls(images []string, imgToURL map[string]string) error { + for _, repo := range img.UniqueTargetImages(images) { + if v, ok := imgToURL[repo]; ok && (v != "" && v != "unknown") { + continue // image is already resolved + } + switch { + case strings.Contains(repo, "mirrored"): + // mirrored images, assumes everything after 'mirrored-' + // can be directly converted into a github repository. + ownerAndRepository := strings.Split(strings.ReplaceAll(repo, "mirrored-", ""), "-") + if len(ownerAndRepository) <= 1 { + imgToURL[repo] = "unknown" + continue + } + url, err := checkURL(fmt.Sprintf("https://github.com/%s/%s", ownerAndRepository[0], strings.Join(ownerAndRepository[1:], ""))) + if err != nil && err.Error() != imageNotFound { + return fmt.Errorf("encountered HTTP error while resolving repository %s: %w", repo, err) + } + if err != nil { + url = "unknown" + } + imgToURL[repo] = url + case strings.Contains(repo, "hardened"): + // hardened images conversion, best effort + cleanRepo := strings.ReplaceAll(repo, "hardened-", "image-build-") + url, err := checkURL("https://github.com/rancher/" + cleanRepo) + if err != nil && err.Error() != imageNotFound { + return fmt.Errorf("encountered HTTP error while resolving repository %s: %w", repo, err) + } + if err != nil { + url = "unknown" + } + imgToURL[repo] = url + default: + // handle Rancher images which share + // a name with their base repository + url, err := checkURL("https://github.com/rancher/" + repo) + if err != nil && err.Error() != imageNotFound { + return fmt.Errorf("encountered HTTP error while resolving repository %s: %w", repo, err) + } + if err != nil { + url = "unknown" + } + imgToURL[repo] = url + } + } + return nil +} + +// checkURL performs a GET request against a github repository +// to determine if it exists or not. +func checkURL(url string) (string, error) { + r, err := http.Get(url) + if err != nil { + return "", err + } + if r.StatusCode != http.StatusOK { + return "", fmt.Errorf(imageNotFound) + } + return url, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins_test.go new file mode 100644 index 0000000..7cc8d01 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/origins_test.go @@ -0,0 +1,95 @@ +package image + +import "testing" + +func TestGetAllUniqueImages(t *testing.T) { + images := [][]string{ + { + "rancher/hardened-coredns:v1.8.5-build20211119", + "rancher/hardened-coredns:v1.9.1-build20220318", + "rancher/hardened-coredns:v1.9.3-build20220613", + }, + { + "rancher/hardened-kubernetes:v1.22.10-rke2r2-build20220608", + "rancher/hardened-kubernetes:v1.22.11-rke2r1-build20220616", + "rancher/hardened-kubernetes:v1.22.13-rke2r1-build20220817", + }, + } + uniqueImages := []string{ + "hardened-coredns", + "hardened-kubernetes", + } + returnedUniqueImages := GetAllUniqueImages(images...) + for i := range uniqueImages { + if uniqueImages[i] != returnedUniqueImages[i] { + t.Errorf("expected: %s, got: %s", uniqueImages, returnedUniqueImages) + t.Fail() + } + } +} + +func TestGatherUnknownImages(t *testing.T) { + fakeImages := []string{ + "fake", + "phony", + } + unknownImages := GatherUnknownImages(fakeImages) + if len(unknownImages) == 0 { + t.Errorf("failed to detect unknown images, expected empty string, got: %s", unknownImages) + t.Fail() + } +} + +func TestRepoFromImage(t *testing.T) { + image := "rancher/hardened-sriov-network-operator:v1.0.0-build20210429" + repo := "hardened-sriov-network-operator" + + returnedRepo := repoFromImage(image) + if repo != returnedRepo { + t.Errorf("expected: %s, got :%s", repo, returnedRepo) + t.Fail() + } + + badImage1 := "hardened-sriov-network-operator:v1.0.0-build20210429" + badImage2 := "rancher/hardened-sriov-network-operator" + + returnedRepo = repoFromImage(badImage1) + if returnedRepo != "" { + t.Errorf("image %s was not handled correctly, expected empty string got %s", badImage1, returnedRepo) + t.Fail() + } + + returnedRepo = repoFromImage(badImage2) + if returnedRepo != "" { + t.Errorf("image %s was not handled correctly, expected empty string got: %s", badImage2, returnedRepo) + t.Fail() + } +} + +func TestUniqueTargetImages(t *testing.T) { + targetImages := []string{ + "rancher/mirrored-calico-operator:v1.28.1", + "rancher/mirrored-calico-operator:v1.27.1", + "rancher/mirrored-calico-operator:v1.25.3", + "rancher/mirrored-calico-pod2daemon-flexvol:v3.17.2", + "rancher/mirrored-calico-pod2daemon-flexvol:v3.16.5", + "rancher/mirrored-calico-pod2daemon-flexvol:v3.13.4", + } + + uniqueImages := []string{ + "mirrored-calico-operator", + "mirrored-calico-pod2daemon-flexvol", + } + + returnedUniqueImages := UniqueTargetImages(targetImages) + for i := range uniqueImages { + if uniqueImages[i] != returnedUniqueImages[i] { + t.Fail() + break + } + } + + if t.Failed() { + t.Errorf("expected: %s, got: %s", uniqueImages, returnedUniqueImages) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve.go new file mode 100644 index 0000000..4a1f50c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve.go @@ -0,0 +1,213 @@ +package image + +import ( + "fmt" + "path" + "sort" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/pkg/errors" + util "github.com/rancher/rancher/pkg/cluster" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + rketypes "github.com/rancher/rke/types" + img "github.com/rancher/rke/types/image" +) + +// ExportConfig provides parameters you can define to configure image exporting for Rancher components +type ExportConfig struct { + RancherVersion string + OsType OSType + ChartsPath string + SystemChartsPath string + GithubEndpoints []GithubEndpoint +} + +type OSType int + +const ( + Linux OSType = iota + Windows +) + +const imageListDelimiter = "\n" + +var osTypeImageListName = map[OSType]string{ + Windows: "windows-rancher-images", + Linux: "rancher-images", +} + +// Resolve calls ResolveWithCluster passing nil into the cluster argument. +// returns the image concatenated with the URL of the system default registry. +// if there is no system default registry it will return the image +func Resolve(image string) string { + return ResolveWithCluster(image, nil) +} + +// ResolveWithCluster returns the image concatenated with the URL of the private registry specified, adding rancher/ if is a private repo. +// It will use the cluster level registry if one is found, or the system default registry if no cluster level registry is found. +// If either is not found, it returns the image. +func ResolveWithCluster(image string, cluster *v3.Cluster) string { + reg := util.GetPrivateRegistryURL(cluster) + if reg != "" && !strings.HasPrefix(image, reg) { + // Images from Dockerhub Library repo, we add rancher prefix when using private registry + if !strings.Contains(image, "/") { + image = "rancher/" + image + } + return path.Join(reg, image) + } + + return image +} + +// GetImages fetches the list of container images used in the sources provided in the exportConfig. +// Rancher charts, system charts, system images and extension images of Rancher are fetched. +// GetImages is called during runtime by Rancher catalog package which is deprecated. +// It is actually used for generation rancher-images.txt for airgap scenarios. +func GetImages(exportConfig ExportConfig, externalImages map[string][]string, imagesFromArgs []string, rkeSystemImages map[string]rketypes.RKESystemImages) ([]string, []string, error) { + imagesSet := make(map[string]map[string]struct{}) + + // fetch images from charts + charts := Charts{exportConfig} + if err := charts.FetchImages(imagesSet); err != nil { + return nil, nil, errors.Wrap(err, "failed to fetch images from charts") + } + + // fetch images from system charts + systemCharts := SystemCharts{exportConfig} + if err := systemCharts.FetchImages(imagesSet); err != nil { + return nil, nil, errors.Wrap(err, "failed to fetch images from system charts") + } + + // fetch images from system images + system := System{exportConfig} + if err := system.FetchImages(rkeSystemImages, imagesSet); err != nil { + return nil, nil, errors.Wrap(err, "failed to fetch images from system") + } + + // fetch images from extension catalog images + extensions := ExtensionsConfig{exportConfig} + if err := extensions.FetchExtensionImages(imagesSet); err != nil { + return nil, nil, errors.Wrap(err, "failed to fetch images from extensions") + } + + setRequirementImages(exportConfig.OsType, imagesSet) + + // set rancher images from args + setImages("rancher", imagesFromArgs, imagesSet) + + for source, sourceImages := range externalImages { + setImages(source, sourceImages, imagesSet) + } + + convertMirroredImages(imagesSet) + + imagesList, imagesAndSourcesList := generateImageAndSourceLists(imagesSet) + + return imagesList, imagesAndSourcesList, nil +} + +func AddImagesToImageListConfigMap(cm *v1.ConfigMap, rancherVersion, systemChartsPath string) error { + exportConfig := ExportConfig{ + SystemChartsPath: systemChartsPath, + OsType: Windows, + RancherVersion: rancherVersion, + } + windowsImages, _, err := GetImages(exportConfig, nil, []string{}, nil) + if err != nil { + return err + } + exportConfig.OsType = Linux + linuxImages, _, err := GetImages(exportConfig, nil, []string{}, nil) + if err != nil { + return err + } + cm.Data = make(map[string]string, 2) + cm.Data[osTypeImageListName[Windows]] = strings.Join(windowsImages, imageListDelimiter) + cm.Data[osTypeImageListName[Linux]] = strings.Join(linuxImages, imageListDelimiter) + return nil +} + +func ParseCatalogImageListConfigMap(cm *v1.ConfigMap) ([]string, []string) { + windowsImages := strings.Split(cm.Data[osTypeImageListName[Windows]], imageListDelimiter) + linuxImages := strings.Split(cm.Data[osTypeImageListName[Linux]], imageListDelimiter) + return windowsImages, linuxImages +} + +func IsValidSemver(version string) bool { + _, err := semver.NewVersion(version) + return err == nil +} + +func setRequirementImages(osType OSType, imagesSet map[string]map[string]struct{}) { + coreLabel := "core" + switch osType { + case Linux: + addSourceToImage(imagesSet, settings.ShellImage.Get(), coreLabel) + addSourceToImage(imagesSet, settings.MachineProvisionImage.Get(), coreLabel) + addSourceToImage(imagesSet, "rancher/mirrored-bci-busybox:15.4.11.2", coreLabel) + addSourceToImage(imagesSet, "rancher/mirrored-bci-micro:15.4.14.3", coreLabel) + } +} + +func setImages(source string, imagesFromArgs []string, imagesSet map[string]map[string]struct{}) { + for _, image := range imagesFromArgs { + addSourceToImage(imagesSet, image, source) + } +} + +func addSourceToImage(imagesSet map[string]map[string]struct{}, image string, sources ...string) { + if image == "" { + return + } + if imagesSet[image] == nil { + imagesSet[image] = make(map[string]struct{}) + } + for _, source := range sources { + imagesSet[image][source] = struct{}{} + } +} + +func convertMirroredImages(imagesSet map[string]map[string]struct{}) { + for image := range imagesSet { + convertedImage := img.Mirror(image) + if image == convertedImage { + continue + } + for source := range imagesSet[image] { + addSourceToImage(imagesSet, convertedImage, source) + } + delete(imagesSet, image) + } +} + +func generateImageAndSourceLists(imagesSet map[string]map[string]struct{}) ([]string, []string) { + var images, imagesAndSources []string + // unique + for image := range imagesSet { + images = append(images, image) + } + + // sort + sort.Slice(images, func(i, j int) bool { + return images[i] < images[j] + }) + + for _, image := range images { + imagesAndSources = append(imagesAndSources, fmt.Sprintf("%s %s", image, getSourcesList(imagesSet[image]))) + } + + return images, imagesAndSources +} + +func getSourcesList(imageSources map[string]struct{}) string { + var sources []string + + for source := range imageSources { + sources = append(sources, source) + } + sort.Strings(sources) + return strings.Join(sources, ",") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve_test.go new file mode 100644 index 0000000..400cb10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/resolve_test.go @@ -0,0 +1,333 @@ +package image + +import ( + "fmt" + "os" + "strings" + "testing" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + rketypes "github.com/rancher/rke/types" + assertlib "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestConvertMirroredImages(t *testing.T) { + testCases := []struct { + caseName string + inputRawImages map[string]map[string]struct{} + outputImagesShouldEqual map[string]map[string]struct{} + }{ + { + caseName: "normalize images", + inputRawImages: map[string]map[string]struct{}{ + "rancher/rke-tools:v0.1.48": {"system": struct{}{}}, + "rancher/rke-tools:v0.1.49": {"system": struct{}{}}, + // for mirror + "prom/prometheus:v2.0.1": {"system": struct{}{}}, + "quay.io/coreos/flannel:v1.2.3": {"system": struct{}{}}, + "gcr.io/google_containers/k8s-dns-kube-dns:1.15.0": {"system": struct{}{}}, + "test.io/test:v0.0.1": {"test": struct{}{}}, // not in mirror list + }, + outputImagesShouldEqual: map[string]map[string]struct{}{ + "rancher/coreos-flannel:v1.2.3": {"system": struct{}{}}, + "rancher/k8s-dns-kube-dns:1.15.0": {"system": struct{}{}}, + "rancher/prom-prometheus:v2.0.1": {"system": struct{}{}}, + "rancher/rke-tools:v0.1.48": {"system": struct{}{}}, + "rancher/rke-tools:v0.1.49": {"system": struct{}{}}, + "test.io/test:v0.0.1": {"test": struct{}{}}, + }, + }, + } + + assert := assertlib.New(t) + for _, cs := range testCases { + imagesSet := cs.inputRawImages + convertMirroredImages(imagesSet) + assert.Equal(cs.outputImagesShouldEqual, imagesSet) + } +} + +func TestResolveWithCluster(t *testing.T) { + if os.Getenv("CATTLE_BASE_REGISTRY") != "" { + fmt.Println("Skipping TestResolveWithCluster. Can't run the tests with CATTLE_BASE_REGISTRY set") + return + } + + clusterWithPrivateRegistry := func(s string) *v3.Cluster { + return &v3.Cluster{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{}, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{ + PrivateRegistries: []rketypes.PrivateRegistry{{ + URL: s, + }, + }, + }, + }, + }, + } + } + type input struct { + image string + CattleBaseRegistry string + cluster *v3.Cluster + } + tests := []struct { + name string + input input + expected string + }{ + { + name: "No cluster no default registry", + input: input{ + image: "imagename", + CattleBaseRegistry: "", + cluster: nil, + }, + expected: "imagename", + }, + { + name: "No cluster with default registry, image without rancher/", + input: input{ + image: "imagename", + CattleBaseRegistry: "custom-registry", + cluster: nil, + }, + expected: "custom-registry/rancher/imagename", + }, + { + name: "No cluster with default registry, image with rancher/", + input: input{ + image: "rancher/imagename", + CattleBaseRegistry: "custom-registry", + cluster: nil, + }, + expected: "custom-registry/rancher/imagename", + }, + { + name: "Cluster empty URL, no default registry", + input: input{ + image: "imagename", + CattleBaseRegistry: "", + cluster: &v3.Cluster{}, + }, + expected: "imagename", + }, + { + name: "Cluster empty URL, with default registry", + input: input{ + image: "imagename", + CattleBaseRegistry: "default-registry.com", + cluster: &v3.Cluster{}, + }, + expected: "default-registry.com/rancher/imagename", + }, + { + name: "Cluster empty URL, with default registry and rancher on image name", + input: input{ + image: "rancher/imagename", + CattleBaseRegistry: "default-registry.com", + cluster: &v3.Cluster{}, + }, + expected: "default-registry.com/rancher/imagename", + }, + { + name: "Cluster with URL, no default registry, no rancher/ on image", + input: input{ + image: "imagename", + CattleBaseRegistry: "", + cluster: clusterWithPrivateRegistry("cluster-url.com"), + }, + expected: "cluster-url.com/rancher/imagename", + }, + { + name: "Cluster with URL, no default registry, with rancher/ on image", + input: input{ + image: "imagename", + CattleBaseRegistry: "", + cluster: clusterWithPrivateRegistry("cluster-url.com"), + }, + expected: "cluster-url.com/rancher/imagename", + }, + { + name: "Cluster with URL, and default registry, no rancher/ on image", + input: input{ + image: "imagename", + CattleBaseRegistry: "registry-url", + cluster: clusterWithPrivateRegistry("cluster-url.com"), + }, + expected: "cluster-url.com/rancher/imagename", + }, + { + name: "Cluster with URL, and default registry, with rancher/ on image", + input: input{ + image: "rancher/imagename", + CattleBaseRegistry: "registry-url", + cluster: clusterWithPrivateRegistry("cluster-url.com"), + }, + expected: "cluster-url.com/rancher/imagename", + }, + } + + if err := settings.SystemDefaultRegistry.Set(""); err != nil { + t.Errorf("Failed to test TestResolveWithCluster(), unable to set SystemDefaultRegistry with the err: %v", err) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := settings.SystemDefaultRegistry.Set(tt.input.CattleBaseRegistry); err != nil { + t.Errorf("Failed to test TestResolveWithCluster(), unable to set SystemDefaultRegistry. err: %v", err) + } + assertlib.Equalf(t, tt.expected, ResolveWithCluster(tt.input.image, tt.input.cluster), "ResolveWithCluster(%v, %v)", tt.input.image, tt.input.cluster) + }) + } + + if err := settings.SystemDefaultRegistry.Set(""); err != nil { + t.Errorf("Failed to clean up TestResolveWithCluster(), unable to set SystemDefaultRegistry with the err: %v", err) + } +} + +func TestGetImages(t *testing.T) { + // Setup a httpserver + server := setupTestServer() + defer server.Close() + + // Mock the parseRepoName function to return the expected repoName + originalParseRepoName := parseRepoName + parseRepoName = func(url string) (string, error) { + return "rancher/ui-plugin-catalog", nil + } + defer func() { + parseRepoName = originalParseRepoName + }() + + tests := []struct { + name string + exportConfig ExportConfig + expected []string + notExpected []string + }{ + { + name: "exportConfig is completely empty", + exportConfig: ExportConfig{ + SystemChartsPath: "", + ChartsPath: "", + OsType: Linux, + RancherVersion: "", + GithubEndpoints: []GithubEndpoint{}, + }, + expected: []string{}, + notExpected: []string{"rancher/ui-plugin-catalog"}, + }, + { + name: "only extensions is set in exportConfig", + exportConfig: ExportConfig{ + SystemChartsPath: "", + ChartsPath: "", + OsType: Linux, + RancherVersion: "", + GithubEndpoints: []GithubEndpoint{ + {URL: server.URL}, + }, + }, + expected: []string{"rancher/ui-plugin-catalog"}, + notExpected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + imagesList, _, err := GetImages(tt.exportConfig, make(map[string][]string), []string{}, map[string]rketypes.RKESystemImages{}) + assertlib.NoError(t, err) + + for _, expected := range tt.expected { + found := false + for _, image := range imagesList { + if strings.Contains(image, expected) { + found = true + break + } + } + assertlib.True(t, found) + } + + for _, notexpected := range tt.notExpected { + found := false + for _, image := range imagesList { + if strings.Contains(image, notexpected) { + found = true + break + } + } + + assertlib.False(t, found) + } + + }) + } +} + +func TestResolve(t *testing.T) { + if os.Getenv("CATTLE_BASE_REGISTRY") != "" { + fmt.Println("Skipping TestResolve. Can't run the tests with CATTLE_BASE_REGISTRY set") + return + } + + type input struct { + image string + CattleBaseRegistry string + } + tests := []struct { + name string + input input + expected string + }{ + { + name: "No default", + input: input{ + image: "imagename", + CattleBaseRegistry: "", + }, + expected: "imagename", + }, + { + name: "Default without rancher", + input: input{ + image: "imagename", + CattleBaseRegistry: "default-registry.com", + }, + expected: "default-registry.com/rancher/imagename", + }, + { + name: "Default with rancher", + input: input{ + image: "rancher/imagename", + CattleBaseRegistry: "default-registry.com", + }, + expected: "default-registry.com/rancher/imagename", + }, + } + + if err := settings.SystemDefaultRegistry.Set(""); err != nil { + t.Errorf("Failed to test TestResolveWithCluster(), unable to clean SystemDefaultRegistry. Err: %v", err) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := settings.SystemDefaultRegistry.Set(tt.input.CattleBaseRegistry); err != nil { + t.Errorf("Failed to test TestResolveWithCluster(), unable to set SystemDefaultRegistry. Err: %v", err) + } + assertlib.Equalf(t, tt.expected, Resolve(tt.input.image), "Resolve(%v)", tt.input.image) + }) + } + + if err := settings.SystemDefaultRegistry.Set(""); err != nil { + t.Errorf("Failed to clean up TestResolve(), unable to clean SystemDefaultRegistry. Err: %v", err) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system.go new file mode 100644 index 0000000..1027019 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system.go @@ -0,0 +1,52 @@ +package image + +import ( + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rketypes "github.com/rancher/rke/types" +) + +type System struct { + Config ExportConfig +} + +func (s System) FetchImages(rkeSystemImages map[string]rketypes.RKESystemImages, imagesSet map[string]map[string]struct{}) error { + if len(rkeSystemImages) <= 0 { + return nil + } + collectionImagesList := []interface{}{rkeSystemImages} + if s.Config.OsType == Linux { + collectionImagesList = append(collectionImagesList, v32.ToolsSystemImages) + } + images, err := flatImagesFromCollections(collectionImagesList...) + if err != nil { + return err + } + for _, image := range images { + addSourceToImage(imagesSet, image, "system") + } + return nil +} + +func flatImagesFromCollections(cols ...interface{}) (images []string, err error) { + for _, col := range cols { + colObj := map[string]interface{}{} + if err := convert.ToObj(col, &colObj); err != nil { + return []string{}, err + } + images = append(images, fetchImagesFromCollection(colObj)...) + } + return images, nil +} + +func fetchImagesFromCollection(obj map[string]interface{}) (images []string) { + for _, v := range obj { + switch t := v.(type) { + case string: + images = append(images, t) + case map[string]interface{}: + images = append(images, fetchImagesFromCollection(t)...) + } + } + return images +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system_test.go new file mode 100644 index 0000000..3c644c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/system_test.go @@ -0,0 +1,101 @@ +package image + +import ( + "testing" + + rketypes "github.com/rancher/rke/types" + assertlib "github.com/stretchr/testify/assert" +) + +func TestFetchImagesFromSystem(t *testing.T) { + k8sVersion := "v1.17.9-rancher1-2" + linuxRKESystemImages := map[string]rketypes.RKESystemImages{ + k8sVersion: { + NginxProxy: "rancher/rke-tools:v0.1.63", + CoreDNS: "rancher/coredns-coredns:1.6.5", + }, + } + windowsRKESystemImages := map[string]rketypes.RKESystemImages{ + k8sVersion: { + NginxProxy: "rancher/rke-tools:v0.1.63", + WindowsPodInfraContainer: "rancher/kubelet-pause:v0.1.4", + }, + } + bothImages := []string{ + linuxRKESystemImages[k8sVersion].NginxProxy, + } + linuxImagesOnly := []string{ + linuxRKESystemImages[k8sVersion].CoreDNS, + } + windowsImagesOnly := []string{ + windowsRKESystemImages[k8sVersion].WindowsPodInfraContainer, + } + + testCases := []struct { + caseName string + inputRkeSystemImages map[string]rketypes.RKESystemImages + inputOsType OSType + outputShouldContainImages []string + outputShouldNotContain []string + }{ + { + caseName: "fetch linux images from system images", + inputRkeSystemImages: linuxRKESystemImages, + inputOsType: Linux, + outputShouldContainImages: flatStringSlice( + bothImages, + linuxImagesOnly, + ), + outputShouldNotContain: windowsImagesOnly, + }, + { + caseName: "fetch windows images from system images", + inputRkeSystemImages: windowsRKESystemImages, + inputOsType: Windows, + outputShouldContainImages: flatStringSlice( + bothImages, + windowsImagesOnly, + ), + outputShouldNotContain: linuxImagesOnly, + }, + } + + assert := assertlib.New(t) + + for _, cs := range testCases { + imagesSet := make(map[string]map[string]struct{}) + exportConfig := ExportConfig{ + OsType: cs.inputOsType, + } + systemExport := System{exportConfig} + err := systemExport.FetchImages(cs.inputRkeSystemImages, imagesSet) + images, imageSources := getImagesAndSourcesLists(imagesSet) + assert.Nilf(err, "%s, failed to fetch images from system images", cs.caseName) + assert.Subset(images, cs.outputShouldContainImages, cs.caseName) + for _, nc := range cs.outputShouldNotContain { + assert.NotContains(images, nc, cs.caseName) + } + for _, source := range imageSources { + assert.Equal("system", source) + } + } +} + +func getImagesAndSourcesLists(imagesSet map[string]map[string]struct{}) ([]string, []string) { + var images, imageSources []string + for image, sources := range imagesSet { + images = append(images, image) + for source := range sources { + imageSources = append(imageSources, source) + } + } + return images, imageSources +} + +func flatStringSlice(slices ...[]string) []string { + var ret []string + for _, s := range slices { + ret = append(ret, s...) + } + return ret +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities.go new file mode 100644 index 0000000..435de91 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities.go @@ -0,0 +1,838 @@ +package utilities + +import ( + "errors" + "fmt" + "log" + "os" + "path/filepath" + "sort" + "strings" + + "github.com/coreos/go-semver/semver" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + img "github.com/rancher/rancher/pkg/image" + ext "github.com/rancher/rancher/pkg/image/external" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rke/types/image" + "github.com/rancher/rke/types/kdm" +) + +var ( + scriptMap = map[string]string{ + "linux-save": linuxSaveScript, + "linux-load": linuxLoadScript, + "linux-mirror": linuxMirrorScript, + "windows-save": windowsSaveScript, + "windows-load": windowsLoadScript, + "windows-mirror": windowsMirrorScript, + } + scriptNameMap = map[string]string{ + "linux-save": "rancher-save-images.sh", + "linux-load": "rancher-load-images.sh", + "linux-mirror": "rancher-mirror-to-rancher-org.sh", + "windows-save": "rancher-save-images.ps1", + "windows-load": "rancher-load-images.ps1", + "windows-mirror": "rancher-mirror-to-rancher-org.ps1", + } + filenameMap = map[string]string{ + "linux": "rancher-images.txt", + "windows": "rancher-windows-images.txt", + } + sourcesFilenameMap = map[string]string{ + "linux": "rancher-images-sources.txt", + "windows": "rancher-windows-images-sources.txt", + } +) + +// ImageTargetsAndSources is an aggregate type containing +// the list of images used by Rancher for Linux and Windows, +// as well as the source of these images. +type ImageTargetsAndSources struct { + LinuxImagesFromArgs []string + TargetLinuxImages []string + TargetLinuxImagesAndSources []string + TargetWindowsImages []string + TargetWindowsImagesAndSources []string +} + +// GatherTargetImagesAndSources queries KDM, charts and system-charts to gather all the images used by Rancher and their source. +// It returns an aggregate type, ImageTargetsAndSources, which contains the images required to run Rancher on Linux and Windows, as well +// as the source of each image. +func GatherTargetImagesAndSources(systemChartsPath, chartsPath string, imagesFromArgs []string) (ImageTargetsAndSources, error) { + rancherVersion, ok := os.LookupEnv("TAG") + if !ok { + return ImageTargetsAndSources{}, fmt.Errorf("no tag defining current Rancher version, cannot gather target images and sources") + } + + if !img.IsValidSemver(rancherVersion) || strings.HasPrefix(rancherVersion, "dev") || strings.HasPrefix(rancherVersion, "master") || strings.HasSuffix(rancherVersion, "-head") { + rancherVersion = settings.RancherVersionDev + } + rancherVersion = strings.TrimPrefix(rancherVersion, "v") + + // already downloaded in dapper + b, err := os.ReadFile(filepath.Join("data.json")) + if os.IsNotExist(err) { + b, err = os.ReadFile(filepath.Join(os.Getenv("HOME"), "bin", "data.json")) + } + if err != nil { + return ImageTargetsAndSources{}, fmt.Errorf("could not read data.json: %w", err) + } + data, err := kdm.FromData(b) + if err != nil { + return ImageTargetsAndSources{}, fmt.Errorf("could not load KDM data: %w", err) + } + + linuxInfo, windowsInfo := kd.GetK8sVersionInfo( + rancherVersion, + data.K8sVersionRKESystemImages, + data.K8sVersionServiceOptions, + data.K8sVersionWindowsServiceOptions, + data.K8sVersionInfo, + ) + + var k8sVersions []string + for k := range linuxInfo.RKESystemImages { + k8sVersions = append(k8sVersions, k) + } + sort.Strings(k8sVersions) + if err := writeSliceToFile(filepath.Join(os.Getenv("HOME"), "bin", "rancher-rke-k8s-versions.txt"), k8sVersions); err != nil { + return ImageTargetsAndSources{}, fmt.Errorf("%s: %w", "could not write rancher-rke-k8s-versions.txt file", err) + } + + k8sVersion1_21_0 := &semver.Version{ + Major: 1, + Minor: 21, + Patch: 0, + } + + externalLinuxImages := make(map[string][]string) + + k3sUpgradeImages, err := ext.GetExternalImages(rancherVersion, data.K3S, ext.K3S, k8sVersion1_21_0, img.Linux) + if err != nil { + return ImageTargetsAndSources{}, fmt.Errorf("%s: %w", "could not get external images for K3s", err) + } + if k3sUpgradeImages != nil { + externalLinuxImages["k3sUpgrade"] = k3sUpgradeImages + } + + // RKE2 Provisioning will only be supported on Kubernetes v1.21+. In addition, only RKE2 + // releases corresponding to Kubernetes v1.21+ include the "rke2-images-all.linux-amd64.txt" file that we need. + rke2LinuxImages, err := ext.GetExternalImages(rancherVersion, data.RKE2, ext.RKE2, k8sVersion1_21_0, img.Linux) + if err != nil { + return ImageTargetsAndSources{}, fmt.Errorf("%s: %w", "could not get external images for RKE2", err) + + } + if rke2LinuxImages != nil { + externalLinuxImages["rke2All"] = rke2LinuxImages + } + + sort.Strings(imagesFromArgs) + winsIndex := sort.SearchStrings(imagesFromArgs, "rancher/wins") + if winsIndex > len(imagesFromArgs)-1 { + return ImageTargetsAndSources{}, fmt.Errorf("rancher/wins upgrade image not found") + } + + winsAgentUpdateImage := imagesFromArgs[winsIndex] + linuxImagesFromArgs := append(imagesFromArgs[:winsIndex], imagesFromArgs[winsIndex+1:]...) + + exportConfig := img.ExportConfig{ + SystemChartsPath: systemChartsPath, + ChartsPath: chartsPath, + OsType: img.Linux, + RancherVersion: rancherVersion, + GithubEndpoints: img.ExtensionEndpoints, + } + targetImages, targetImagesAndSources, err := img.GetImages(exportConfig, externalLinuxImages, linuxImagesFromArgs, linuxInfo.RKESystemImages) + if err != nil { + return ImageTargetsAndSources{}, err + } + + exportConfig.OsType = img.Windows + targetWindowsImages, targetWindowsImagesAndSources, err := img.GetImages(exportConfig, nil, []string{getWindowsAgentImage(), winsAgentUpdateImage}, windowsInfo.RKESystemImages) + if err != nil { + return ImageTargetsAndSources{}, err + } + + return ImageTargetsAndSources{ + LinuxImagesFromArgs: linuxImagesFromArgs, + TargetLinuxImages: targetImages, + TargetLinuxImagesAndSources: targetImagesAndSources, + TargetWindowsImages: targetWindowsImages, + TargetWindowsImagesAndSources: targetWindowsImagesAndSources, + }, nil +} + +// LoadScript produces executable files for Linux and Windows +// which will load all images used by Rancher into a given image repository. +func LoadScript(arch string, targetImages []string) error { + loadScriptName := getScriptFilename(arch, "load") + log.Printf("Creating %s\n", loadScriptName) + load, err := os.Create(loadScriptName) + if err != nil { + return err + } + defer load.Close() + load.Chmod(0755) + + fmt.Fprintf(load, getScript(arch, "load")) + return nil +} + +// SaveScript produces executable files for Linux and Windows +// which will save all the images used by Rancher using the command +// `docker save` +func SaveScript(arch string, targetImages []string) error { + filename := getScriptFilename(arch, "save") + log.Printf("Creating %s\n", filename) + save, err := os.Create(filename) + if err != nil { + return err + } + defer save.Close() + save.Chmod(0755) + + fmt.Fprintf(save, getScript(arch, "save")) + + return nil +} + +// ImagesText will produce a file containing all the images +// used by Rancher for a particular arch. +func ImagesText(arch string, targetImages []string) error { + filename := filenameMap[arch] + log.Printf("Creating %s\n", filename) + save, err := os.Create(filename) + if err != nil { + return err + } + defer save.Close() + save.Chmod(0755) + + for _, image := range saveImages(targetImages) { + err := checkImage(image) + if err != nil { + return err + } + fmt.Fprintln(save, image) + } + + return nil +} + +// ImagesAndSourcesText writes data of the format "image source1,..." to the filename +// designated for the given arch +func ImagesAndSourcesText(arch string, targetImagesAndSources []string) error { + filename := sourcesFilenameMap[arch] + log.Printf("Creating %s\n", filename) + save, err := os.Create(filename) + if err != nil { + return err + } + defer save.Close() + save.Chmod(0755) + + for _, imageAndSources := range saveImagesAndSources(targetImagesAndSources) { + if err := checkImage(strings.Split(imageAndSources, " ")[0]); err != nil { + return err + } + fmt.Fprintln(save, imageAndSources) + } + + return nil +} + +// MirrorScript creates executable files for Linux and Windows +// which will perform `docker pull`'s for each image used by Rancher +func MirrorScript(arch string, targetImages []string) error { + filename := getScriptFilename(arch, "mirror") + log.Printf("Creating %s\n", filename) + mirror, err := os.Create(filename) + if err != nil { + return err + } + defer mirror.Close() + mirror.Chmod(0755) + + scriptStarter := getScript(arch, "mirror") + fmt.Fprintf(mirror, scriptStarter) + + var saveImages []string + for _, targetImage := range targetImages { + srcImage, ok := image.Mirrors[targetImage] + if !ok { + continue + } + + saveImages = append(saveImages, targetImage) + fmt.Fprintf(mirror, "docker pull %s\n", srcImage) + if targetImage != srcImage { + fmt.Fprintf(mirror, "docker tag %s %s\n", srcImage, targetImage) + fmt.Fprintf(mirror, "docker push %s\n", targetImage) + } + } + + return nil +} + +func saveImages(targetImages []string) []string { + var saveImages []string + for _, targetImage := range targetImages { + _, ok := image.Mirrors[targetImage] + if !ok { + continue + } + + saveImages = append(saveImages, targetImage) + } + return saveImages +} + +func saveImagesAndSources(imagesAndSources []string) []string { + var saveImagesAndSources []string + for _, imageAndSources := range imagesAndSources { + targetImage := strings.Split(imageAndSources, " ")[0] + _, ok := image.Mirrors[targetImage] + if !ok { + continue + } + + saveImagesAndSources = append(saveImagesAndSources, imageAndSources) + } + return saveImagesAndSources +} + +func checkImage(image string) error { + // ignore non prefixed images, also in types (image/mirror.go) + if strings.HasPrefix(image, "weaveworks") || strings.HasPrefix(image, "noiro") { + return nil + } + imageNameTag := strings.Split(image, ":") + if len(imageNameTag) != 2 { + return fmt.Errorf("Can't extract tag from image [%s]", image) + } + if imageNameTag[1] == "" { + return fmt.Errorf("Extracted tag from image [%s] is empty", image) + } + if !strings.HasPrefix(imageNameTag[0], "rancher/") { + return fmt.Errorf("Image [%s] does not start with rancher/", image) + } + if strings.HasSuffix(imageNameTag[0], "-") { + return fmt.Errorf("Image [%s] has trailing '-', probably an error in image substitution", image) + } + return nil +} + +func writeSliceToFile(filename string, versions []string) error { + log.Printf("Creating %s\n", filename) + + dir := filepath.Dir(filename) + if err := os.MkdirAll(dir, 0755); err != nil { + return fmt.Errorf("failed to create directories: %w", err) + } + + save, err := os.Create(filename) + if err != nil { + return fmt.Errorf("failed to create file: %w", err) + } + + defer func() { + if cerr := save.Close(); cerr != nil { + err = errors.Join(err, cerr) + } + }() + + if err := save.Chmod(0755); err != nil { + return fmt.Errorf("failed to set file permissions: %w", err) + } + + for _, version := range versions { + if _, err := fmt.Fprintln(save, version); err != nil { + return fmt.Errorf("failed to write to file: %w", err) + } + } + + return nil +} + +func getWindowsAgentImage() string { + tag, ok := os.LookupEnv("TAG") + if !ok { + return "" + } + repo, ok := os.LookupEnv("REPO") + if !ok { + return "" + } + return fmt.Sprintf("%s/rancher-agent:%s", repo, tag) +} + +func getScript(arch, fileType string) string { + return scriptMap[fmt.Sprintf("%s-%s", arch, fileType)] +} + +func getScriptFilename(arch, fileType string) string { + return scriptNameMap[fmt.Sprintf("%s-%s", arch, fileType)] +} + +const ( + linuxLoadScript = `#!/bin/bash +images="rancher-images.tar.gz" +list="rancher-images.txt" +windows_image_list="" +windows_versions="1809" +source_registry="" +usage () { + echo "USAGE: $0 [--images rancher-images.tar.gz] [--source-registry index.docker.io] --registry my.registry.com:5000" + echo " [-l|--image-list path] text file with list of images; one image per line." + echo " [-i|--images path] tar.gz generated by docker save." + echo " [-r|--registry registry:port] target private registry in the registry:port format." + echo " [-s|--source-registry registry:port] source registry in the registry:port format." + echo " [--windows-image-list path] text file with list of images used in Windows. Windows image mirroring is skipped when this is empty." + echo " [--windows-versions version] Comma separated Windows versions. e.g., \"1809,ltsc2022\". (Default \"1809\")" + echo " [-h|--help] Usage message" +} + +push_manifest () { + export DOCKER_CLI_EXPERIMENTAL=enabled + manifest_list=() + for i in "${arch_list[@]}" + do + manifest_list+=("$1-${i}") + done + + echo "Preparing manifest $1, list[${arch_list[@]}]" + docker manifest create "$1" "${manifest_list[@]}" --amend + docker manifest push "$1" --purge +} + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -r|--registry) + target_registry="$2" + shift # past argument + shift # past value + ;; + -s|--source-registry) + source_registry="$2" + shift # past argument + shift # past value + ;; + -l|--image-list) + list="$2" + shift # past argument + shift # past value + ;; + -i|--images) + images="$2" + shift # past argument + shift # past value + ;; + --windows-image-list) + windows_image_list="$2" + shift # past argument + shift # past value + ;; + --windows-versions) + windows_versions="$2" + shift # past argument + shift # past value + ;; + -h|--help) + help="true" + shift + ;; + *) + usage + exit 1 + ;; + esac +done +if [[ -z "${target_registry}" ]]; then + usage + exit 1 +fi +if [[ $help ]]; then + usage + exit 0 +fi + +target_registry="${target_registry%/}/" +source_registry="${source_registry%/}" +if [ ! -z "${source_registry}" ]; then + source_registry="${source_registry}/" +fi + +docker load --input ${images} + +linux_images=() +while IFS= read -r i; do + [ -z "${i}" ] && continue + linux_images+=("${i}"); +done < "${list}" + +arch_list=() +if [[ -n "${windows_image_list}" ]]; then + IFS=',' read -r -a versions <<< "$windows_versions" + for version in "${versions[@]}" + do + arch_list+=("windows-${version}") + done + + windows_images=() + while IFS= read -r i; do + [ -z "${i}" ] && continue + windows_images+=("${i}") + done < "${windows_image_list}" + + # use manifest to publish images only used in Windows + for i in "${windows_images[@]}"; do + if [[ ! " ${linux_images[@]}" =~ " ${i}" ]]; then + case $i in + */*) + image_name="${target_registry}${i}" + ;; + *) + image_name="${target_registry}rancher/${i}" + ;; + esac + push_manifest "${image_name}" + fi + done +fi + +arch_list+=("linux-amd64") +for i in "${linux_images[@]}"; do + [ -z "${i}" ] && continue + arch_suffix="" + use_manifest=false + if [[ (-n "${windows_image_list}") && " ${windows_images[@]}" =~ " ${i}" ]]; then + # use manifest to publish images when it is used both in Linux and Windows + use_manifest=true + arch_suffix="-linux-amd64" + fi + case $i in + */*) + image_name="${target_registry}${i}" + ;; + *) + image_name="${target_registry}rancher/${i}" + ;; + esac + + docker tag "${source_registry}${i}" "${image_name}${arch_suffix}" + docker push "${image_name}${arch_suffix}" + + if $use_manifest; then + push_manifest "${image_name}" + fi +done +` + linuxSaveScript = `#!/bin/bash +list="rancher-images.txt" +images="rancher-images.tar.gz" +source_registry="" + +usage () { + echo "USAGE: $0 [--image-list rancher-images.txt] [--images rancher-images.tar.gz]" + echo " [-s|--source-registry] source registry to pull images from in registry:port format." + echo " [-l|--image-list path] text file with list of images; one image per line." + echo " [-i|--images path] tar.gz generated by docker save." + echo " [-h|--help] Usage message" +} + +POSITIONAL=() +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -i|--images) + images="$2" + shift # past argument + shift # past value + ;; + -l|--image-list) + list="$2" + shift # past argument + shift # past value + ;; + -s|--source-registry) + source_registry="$2" + shift # past argument + shift # past value + ;; + -h|--help) + help="true" + shift + ;; + *) + usage + exit 1 + ;; + esac +done + +if [[ $help ]]; then + usage + exit 0 +fi + +source_registry="${source_registry%/}" +if [ ! -z "${source_registry}" ]; then + source_registry="${source_registry}/" +fi + +pulled="" +while IFS= read -r i; do + [ -z "${i}" ] && continue + i="${source_registry}${i}" + if docker pull "${i}" > /dev/null 2>&1; then + echo "Image pull success: ${i}" + pulled="${pulled} ${i}" + else + if docker inspect "${i}" > /dev/null 2>&1; then + pulled="${pulled} ${i}" + else + echo "Image pull failed: ${i}" + fi + fi +done < "${list}" + +echo "Creating ${images} with $(echo ${pulled} | wc -w | tr -d '[:space:]') images" +docker save $(echo ${pulled}) | gzip --stdout > ${images} +` + linuxMirrorScript = "#!/bin/sh\nset -e -x\n\n" + windowsLoadScript = `$ErrorActionPreference = 'Stop' + +$script_name = $MyInvocation.InvocationName +$image_list = "rancher-windows-images.txt" +$images = "rancher-windows-images.tar.gz" +$os_release_id = $(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -ExpandProperty ReleaseId) + +$target_registry = $null +$source_registry = "" +$help = $false + +function usage { + echo "USAGE: $script_name [--images rancher-windows-images.tar.gz] [--source-registry index.docker.io] --registry my.registry.com:5000" + echo " [-l|--image-list path] text file with list of images; one image per line." + echo " [-i|--images path] tar.gz generated by docker save." + echo " [-r|--registry registry:port] target private registry in the format registry:port." + echo " [-s|--source-registry registry:port] source registry in the format registry:port." + echo " [-o|--os-release-id (1809|lstc2022|...)] release id of OS, gets detected automatically if not passed." + echo " [-h|--help] Usage message." +} + +# parse arguments +$vals = $null +for ($i = $args.Length; $i -ge 0; $i--) +{ + $arg = $args[$i] + switch -regex ($arg) + { + '^(-i|--images)$' { + $images = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-l|--image-list)$' { + $image_list = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-r|--registry)$' { + $target_registry = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-s|--source-registry)$' { + $source_registry = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-o|--os-release-id)$' { + $os_release_id = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-h|--help)$' { + $help = $true + $vals = $null + } + default { + if ($vals) { + $vals = ,$arg + $vals + } else { + $vals = @($arg) + } + } + } +} + +if ($help) +{ + usage + exit 0 +} + +if (-not $target_registry) +{ + echo "Registry address is required" + usage + exit 1 +} + +if (-not (Test-Path $images)) +{ + echo "Could not find '$images'" + usage + exit 1 +} + +docker load --input $images +if (-not $?) +{ + echo "Could not load '$images'" + exit 1 +} + +if (-not (Test-Path $image_list)) +{ + exit 0 +} + +$target_registry = $target_registry.TrimEnd("/") + "/" + +if ([string]::IsNullOrEmpty($source_registry)) +{ + $source_registry = "" +} +else +{ + $source_registry = $source_registry.TrimEnd("/") + "/" +} + +Get-Content -Force -Path $image_list | ForEach-Object { + if ($_) { + $fullname_image = ('{0}-windows-{1}' -f $_, $os_release_id) + $source_image = -join ($source_registry, $fullname_image) + + switch -regex ($fullname_image) + { + '.+/.+' { + $target_image = -join ($target_registry, $fullname_image) + echo "Tagging $target_image" + docker tag $source_image $target_image + if ($?) { + docker push $target_image + } + } + default { + $target_image = -join ($target_registry, "rancher/", $fullname_image) + echo "Tagging $target_image" + docker tag $source_image $target_image + if ($?) { + docker push $target_image + } + } + } + } +} + +` + windowsSaveScript = `$ErrorActionPreference = 'Stop' + +$script_name = $MyInvocation.InvocationName +$image_list = "rancher-windows-images.txt" +$images = "rancher-windows-images.tar.gz" +$source_registry = "" +$os_release_id = $(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' | Select-Object -ExpandProperty ReleaseId) + +$help = $false + +function usage { + echo "USAGE: $script_name [--image-list rancher-windows-images.txt] [--images rancher-windows-images.tar.gz] [--source-registry index.docker.io]" + echo " [-l|--image-list path] text file with list of images; one image per line." + echo " [-i|--images path] tar.gz generated by docker save." + echo " [-s|--source-registry registry:port] source registry to pull images from, in the registry:port format." + echo " [-o|--os-release-id (1809|ltsc2022|...)] release id of OS, gets detected automatically if not passed." + echo " [-h|--help] Usage message." +} + +# parse arguments +$vals = $null +for ($i = $args.Length; $i -ge 0; $i--) +{ + $arg = $args[$i] + switch -regex ($arg) + { + '^(-l|--image-list)$' { + $image_list = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-i|--images)$' { + $images = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-o|--os-release-id)$' { + $os_release_id = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-s|--source-registry)$' { + $source_registry = ($vals | Select-Object -First 1) + $vals = $null + } + '^(-h|--help)$' { + $help = $true + $vals = $null + } + default { + if ($vals) { + $vals = ,$arg + $vals + } else { + $vals = @($arg) + } + } + } +} + +if ($help) +{ + usage + exit 0 +} + +if (-not (Test-Path $image_list)) +{ + echo "Could not find '$image_list' file" + usage + exit 1 +} + +if ([string]::IsNullOrEmpty($source_registry)) +{ + $source_registry = "" +} +else +{ + $source_registry = $source_registry.TrimEnd("/") + "/" +} + +$fullname_images = @() +Get-Content -Force -Path $image_list | ForEach-Object { + if ($_) { + $fullname_image = ('{0}{1}-windows-{2}' -f $source_registry, $_, $os_release_id) + echo "Pulling $fullname_image" + docker pull $fullname_image + if ($?) { + $fullname_images += @($fullname_image) + } + } +} + +if (-not $fullname_images) +{ + echo "Could not save empty images to host" + echo "Please verify the images of '$image_list' existing or not" + exit 1 +} +docker save $($fullname_images) -o $images + +` + windowsMirrorScript = `` +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities_test.go new file mode 100644 index 0000000..d4d3f8d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/image/utilities/utilities_test.go @@ -0,0 +1,30 @@ +package utilities + +import ( + "testing" +) + +func TestCheckImage(t *testing.T) { + imageListAndErrorExpectations := map[string]bool{ + "weaveworks/npc:latest": false, + "noiro/test:latest": false, + "registry.suse.com/test:latest": true, + "rancher/aks-operator:latest": false, + "google/gke-operator:latest": true, // not from 'rancher/' or whitelisted + "rancher/gke-operator-:latest": true, // trailing '-' in image name + "rancher/test": true, // missing tag + "rancher/test:": true, // empty tag + } + + for k, v := range imageListAndErrorExpectations { + err := checkImage(k) + if err != nil && !v { + t.Logf("did not expect error when checking image %s", k) + t.Fail() + } + if err == nil && v { + t.Logf("expected error when checking image %s", k) + t.Fail() + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation.go new file mode 100644 index 0000000..231cd34 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation.go @@ -0,0 +1,452 @@ +// Package impersonation sets up service accounts that are permitted to act on behalf of a Rancher user on a cluster. +package impersonation + +import ( + "context" + "fmt" + "reflect" + "sort" + "time" + + authcommon "github.com/rancher/rancher/pkg/auth/providers/common" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/rancher/pkg/types/config" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/client-go/util/retry" +) + +const ( + impersonationLabel = "authz.cluster.cattle.io/impersonator" + // ImpersonationNamespace is the namespace where impersonation service accounts live. + ImpersonationNamespace = "cattle-impersonation-system" + // ImpersonationPrefix is the prefix for impersonation roles, bindings, and service accounts. + ImpersonationPrefix = "cattle-impersonation-" +) + +// Impersonator contains data for the user being impersonated. +type Impersonator struct { + user user.Info + clusterContext *config.UserContext + userLister v3.UserLister + userAttributeLister v3.UserAttributeLister + secretsCache corecontrollers.SecretCache +} + +// New creates an Impersonator from a kubernetes user.Info object and a UserContext for the cluster. +func New(userInfo user.Info, clusterContext *config.UserContext) (Impersonator, error) { + impersonator := Impersonator{ + clusterContext: clusterContext, + userLister: clusterContext.Management.Management.Users("").Controller().Lister(), + userAttributeLister: clusterContext.Management.Management.UserAttributes("").Controller().Lister(), + secretsCache: clusterContext.Corew.Secret().Cache(), + } + user, err := impersonator.getUser(userInfo) + impersonator.user = user + if err != nil { + return Impersonator{}, err + } + + return impersonator, nil +} + +// SetUpImpersonation creates a service account on a cluster with a clusterrole and clusterrolebinding allowing it to impersonate a Rancher user. +// Returns a reference to the service account, which can be used by GetToken to retrieve the account token, or an error if creating any of the resources failed. +func (i *Impersonator) SetUpImpersonation() (*corev1.ServiceAccount, error) { + rules := i.rulesForUser() + logrus.Tracef("impersonation: checking role for user %s", i.user.GetName()) + role, err := i.checkAndUpdateRole(rules) + if err != nil { + return nil, err + } + roleBinding, err := i.getRoleBinding() + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + if role != nil && roleBinding != nil { + sa, err := i.getServiceAccount() + // in case the role exists but we were interrupted before creating the service account, proceed to create resources + if err == nil || !apierrors.IsNotFound(err) { + return sa, err + } + } + logrus.Tracef("impersonation: creating impersonation namespace") + err = i.createNamespace() + if err != nil { + return nil, err + } + logrus.Tracef("impersonation: creating role for user %s", i.user.GetName()) + role, err = i.createRole(rules) + if err != nil { + return nil, err + } + logrus.Tracef("impersonation: creating service account for user %s", i.user.GetName()) + sa, err := i.createServiceAccount(role) + if err != nil { + return nil, err + } + logrus.Tracef("impersonation: creating role binding for user %s", i.user.GetName()) + err = i.createRoleBinding(role, sa) + if err != nil { + return nil, err + } + logrus.Tracef("impersonation: waiting for service account to become active for user %s", i.user.GetName()) + return i.waitForServiceAccount(sa) +} + +// GetToken accepts a service account and returns the service account's token. +func (i *Impersonator) GetToken(sa *corev1.ServiceAccount) (string, error) { + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(context.Background(), i.secretsCache, i.clusterContext.K8sClient, sa) + if err != nil { + return "", fmt.Errorf("error getting secret: %w", err) + } + token, ok := secret.Data["token"] + if !ok { + return "", fmt.Errorf("error getting token: invalid secret object") + } + return string(token), nil +} + +func (i *Impersonator) getServiceAccount() (*corev1.ServiceAccount, error) { + name := ImpersonationPrefix + i.user.GetUID() + sa, err := i.clusterContext.Core.ServiceAccounts("").Controller().Lister().Get(ImpersonationNamespace, name) + if err != nil { + if logrus.GetLevel() >= logrus.TraceLevel { + logrus.Tracef("impersonation: error getting service account %s/%s: %v", ImpersonationNamespace, name, err) + sas, debugErr := i.clusterContext.Core.ServiceAccounts("").Controller().Lister().List(ImpersonationNamespace, labels.NewSelector()) + if i.clusterContext == nil { + logrus.Tracef("impersonation: cluster context is empty") + } else { + logrus.Tracef("impersonation: using context for cluster %s", i.clusterContext.ClusterName) + } + if debugErr != nil { + logrus.Tracef("impersonation: encountered error listing cached service accounts: %v", debugErr) + } else { + logrus.Tracef("impersonation: cached service accounts: %+v", sas) + } + } + return nil, fmt.Errorf("failed to get service account: %s/%s, error: %w", ImpersonationNamespace, name, err) + } + return sa, nil +} + +func (i *Impersonator) createServiceAccount(role *rbacv1.ClusterRole) (*corev1.ServiceAccount, error) { + name := ImpersonationPrefix + i.user.GetUID() + sa, err := i.clusterContext.Core.ServiceAccounts("").Controller().Lister().Get(ImpersonationNamespace, name) + if err != nil && !apierrors.IsNotFound(err) { + return nil, fmt.Errorf("impersonation: error getting service account [%s:%s]: %w", ImpersonationNamespace, name, err) + } + if apierrors.IsNotFound(err) { + logrus.Debugf("impersonation: creating service account %s", name) + sa, err = i.clusterContext.Core.ServiceAccounts(ImpersonationNamespace).Create(&corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: map[string]string{ + impersonationLabel: "true", + }, + // Use the clusterrole as the owner for the purposes of automatic cleanup + OwnerReferences: []metav1.OwnerReference{{ + Name: role.Name, + UID: role.UID, + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRole", + }}, + }, + }) + if apierrors.IsAlreadyExists(err) { + // in case cache isn't synced yet, use raw client + sa, err = i.clusterContext.Core.ServiceAccounts(ImpersonationNamespace).Get(name, metav1.GetOptions{}) + } + if err != nil { + return nil, fmt.Errorf("impersonation: error getting service account [%s:%s]: %w", ImpersonationNamespace, name, err) + } + } + // create secret for service account if it was not automatically generated + _, err = serviceaccounttoken.EnsureSecretForServiceAccount(context.Background(), i.secretsCache, i.clusterContext.K8sClient, sa) + if err != nil { + return nil, fmt.Errorf("impersonation: error ensuring secret for service account %s: %w", name, err) + } + return sa, nil +} + +func (i *Impersonator) createNamespace() error { + _, err := i.clusterContext.Core.Namespaces("").Controller().Lister().Get("", ImpersonationNamespace) + if apierrors.IsNotFound(err) { + logrus.Debugf("impersonation: creating namespace %s", ImpersonationNamespace) + _, err = i.clusterContext.Core.Namespaces("").Create(&corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ImpersonationNamespace, + Labels: map[string]string{ + impersonationLabel: "true", + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + return nil + } + } + return err +} + +// checkAndUpdateRole checks whether the impersonation clusterrole already exists and whether it has the correct rules. +// If the role does not exist, the method returns nil for the role and createRole must be called. +// If the role does exist, the rules are updated if necessary and a reference to the role is returned. +func (i *Impersonator) checkAndUpdateRole(rules []rbacv1.PolicyRule) (*rbacv1.ClusterRole, error) { + name := ImpersonationPrefix + i.user.GetUID() + var role *rbacv1.ClusterRole + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + var err error + role, err = i.clusterContext.RBAC.ClusterRoles("").Controller().Lister().Get("", name) + if apierrors.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + if !reflect.DeepEqual(role.Rules, rules) { + role.Rules = rules + role, err = i.clusterContext.RBAC.ClusterRoles("").Update(role) + return err + } + return nil + }) + if err != nil { + return nil, err + } + + return role, nil +} + +func (i *Impersonator) createRole(rules []rbacv1.PolicyRule) (*rbacv1.ClusterRole, error) { + name := ImpersonationPrefix + i.user.GetUID() + role, err := i.clusterContext.RBAC.ClusterRoles("").Controller().Lister().Get("", name) + if apierrors.IsNotFound(err) { + logrus.Debugf("impersonation: creating role %s", name) + role, err = i.clusterContext.RBAC.ClusterRoles("").Create(&rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: ImpersonationPrefix + i.user.GetUID(), + Labels: map[string]string{ + impersonationLabel: "true", + }, + }, + Rules: rules, + AggregationRule: nil, + }) + if apierrors.IsAlreadyExists(err) { + // in case cache isn't synced yet, use raw client + return i.clusterContext.RBAC.ClusterRoles("").Get(name, metav1.GetOptions{}) + } + return role, nil + } + return role, err +} + +func (i *Impersonator) rulesForUser() []rbacv1.PolicyRule { + rules := []rbacv1.PolicyRule{{ + Verbs: []string{"impersonate"}, + APIGroups: []string{""}, + Resources: []string{"users"}, + ResourceNames: []string{i.user.GetUID()}, + }} + + if groups := i.user.GetGroups(); len(groups) > 0 { + rules = append(rules, rbacv1.PolicyRule{ + Verbs: []string{"impersonate"}, + APIGroups: []string{""}, + Resources: []string{"groups"}, + ResourceNames: groups, + }) + } + extras := i.user.GetExtra() + if principalids, ok := extras[authcommon.UserAttributePrincipalID]; ok { + rules = append(rules, rbacv1.PolicyRule{ + Verbs: []string{"impersonate"}, + APIGroups: []string{"authentication.k8s.io"}, + Resources: []string{"userextras/principalid"}, + ResourceNames: principalids, + }) + } + if usernames, ok := extras[authcommon.UserAttributeUserName]; ok { + rules = append(rules, rbacv1.PolicyRule{ + Verbs: []string{"impersonate"}, + APIGroups: []string{"authentication.k8s.io"}, + Resources: []string{"userextras/username"}, + ResourceNames: usernames, + }) + } + return rules +} + +func (i *Impersonator) getRoleBinding() (*rbacv1.ClusterRoleBinding, error) { + name := ImpersonationPrefix + i.user.GetUID() + return i.clusterContext.RBAC.ClusterRoleBindings("").Controller().Lister().Get("", name) +} + +func (i *Impersonator) createRoleBinding(role *rbacv1.ClusterRole, sa *corev1.ServiceAccount) error { + name := ImpersonationPrefix + i.user.GetUID() + _, err := i.clusterContext.RBAC.ClusterRoleBindings("").Controller().Lister().Get("", name) + if apierrors.IsNotFound(err) { + logrus.Debugf("impersonation: creating role binding %s", name) + _, err = i.clusterContext.RBAC.ClusterRoleBindings("").Create(&rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + // Use the clusterrole as the owner for the purposes of automatic cleanup + OwnerReferences: []metav1.OwnerReference{{ + Name: role.Name, + UID: role.UID, + APIVersion: "rbac.authorization.k8s.io/v1", + Kind: "ClusterRole", + }}, + Labels: map[string]string{ + impersonationLabel: "true", + }, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + APIGroup: "", + Name: sa.Name, + Namespace: sa.Namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.GroupName, + Kind: "ClusterRole", + Name: role.Name, + }, + }) + if apierrors.IsAlreadyExists(err) { + return nil + } + } + return err +} + +func (i *Impersonator) waitForServiceAccount(sa *corev1.ServiceAccount) (*corev1.ServiceAccount, error) { + logrus.Debugf("impersonation: waiting for service account %s/%s to be ready", sa.Namespace, sa.Name) + backoff := wait.Backoff{ + Duration: 200 * time.Millisecond, + Factor: 1, + Jitter: 0, + Steps: 10, + } + var ret *corev1.ServiceAccount + err := wait.ExponentialBackoff(backoff, func() (bool, error) { + var err error + ret, err = i.clusterContext.Core.ServiceAccounts("").Controller().Lister().Get(ImpersonationNamespace, sa.Name) + if apierrors.IsNotFound(err) { + return false, nil + } + if err != nil { + return false, err + } + secret, err := serviceaccounttoken.ServiceAccountSecret(context.Background(), sa, i.secretsCache.List, i.clusterContext.K8sClient.CoreV1().Secrets(sa.Namespace)) + if err != nil { + return false, err + } + if secret == nil { + return false, nil + } + if _, found := secret.Data[corev1.ServiceAccountTokenKey]; found { + return true, nil + } + return false, nil + }) + if err != nil { + if logrus.GetLevel() >= logrus.TraceLevel { + logrus.Tracef("impersonation: error waiting for service account %s/%s: %v", sa.Namespace, sa.Name, err) + sas, debugErr := i.clusterContext.Core.ServiceAccounts("").Controller().Lister().List(ImpersonationNamespace, labels.NewSelector()) + if i.clusterContext == nil { + logrus.Tracef("impersonation: cluster context is empty") + } else { + logrus.Tracef("impersonation: using context for cluster %s", i.clusterContext.ClusterName) + } + if debugErr != nil { + logrus.Tracef("impersonation: encountered error listing cached service accounts: %v", debugErr) + } else { + logrus.Tracef("impersonation: cached service accounts: %+v", sas) + } + } + return nil, fmt.Errorf("failed to get secret for service account: %s/%s, error: %w", sa.Namespace, sa.Name, err) + } + return ret, nil +} + +func (i *Impersonator) getUser(userInfo user.Info) (user.Info, error) { + u, err := i.userLister.Get("", userInfo.GetUID()) + if err != nil { + return &user.DefaultInfo{}, err + } + + groups := []string{"system:authenticated", "system:cattle:authenticated"} + extras := make(map[string][]string) + attribs, err := i.userAttributeLister.Get("", userInfo.GetUID()) + if err != nil && !apierrors.IsNotFound(err) { + return &user.DefaultInfo{}, err + } + if attribs == nil { // system users do not have userattributes, but principalid and username are on the user + // See https://github.com/rancher/rancher/blob/7ce603ea90ca656f5baa29b0149c19c8d7f73e8f/pkg/auth/requests/authenticate.go#L185-L194 + // If the extras are not in userattributes, use displayName and principalIDs from the user. + if u.DisplayName != "" { + extras[authcommon.UserAttributeUserName] = []string{u.DisplayName} + } + if len(u.PrincipalIDs) > 0 { + extras[authcommon.UserAttributePrincipalID] = u.PrincipalIDs + } + } else { // real users have groups and extras in userattributes + for _, gps := range attribs.GroupPrincipals { + for _, groupPrincipal := range gps.Items { + if !isInList(groupPrincipal.Name, groups) { + groups = append(groups, groupPrincipal.Name) + } + } + } + for _, exs := range attribs.ExtraByProvider { + if usernames, ok := exs[authcommon.UserAttributeUserName]; ok && len(usernames) > 0 { + if _, ok := extras[authcommon.UserAttributeUserName]; !ok { + extras[authcommon.UserAttributeUserName] = make([]string, 0) + } + extras[authcommon.UserAttributeUserName] = append(extras[authcommon.UserAttributeUserName], usernames...) + } + if principalids, ok := exs[authcommon.UserAttributePrincipalID]; ok && len(principalids) > 0 { + if _, ok := extras[authcommon.UserAttributePrincipalID]; !ok { + extras[authcommon.UserAttributePrincipalID] = make([]string, 0) + } + extras[authcommon.UserAttributePrincipalID] = append(extras[authcommon.UserAttributePrincipalID], principalids...) + } + } + } + // sort to make comparable + sort.Strings(groups) + if _, ok := extras[authcommon.UserAttributeUserName]; ok { + sort.Strings(extras[authcommon.UserAttributeUserName]) + } + if _, ok := extras[authcommon.UserAttributePrincipalID]; ok { + sort.Strings(extras[authcommon.UserAttributePrincipalID]) + } + + user := &user.DefaultInfo{ + UID: u.GetName(), + Name: u.Username, + Groups: groups, + Extra: extras, + } + return user, nil +} + +func isInList(item string, list []string) bool { + for _, s := range list { + if item == s { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation_test.go new file mode 100644 index 0000000..94efa59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/impersonation/impersonation_test.go @@ -0,0 +1,201 @@ +package impersonation + +import ( + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/authentication/user" +) + +func Test_getUser(t *testing.T) { + tests := []struct { + name string + userInfo user.Info + groupName string + userGetFunc func(_, _ string) (*v3.User, error) + userAttribGetFunc func(_, _ string) (*v3.UserAttribute, error) + want user.Info + }{ + { + name: "plain local user", + userInfo: &user.DefaultInfo{Name: "user-abcde"}, + userGetFunc: func(_, _ string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + DisplayName: "Default Admin", + PrincipalIDs: []string{ + "local://user-abcde", + }, + }, nil + }, + userAttribGetFunc: func(_, _ string) (*v3.UserAttribute, error) { + return nil, nil + }, + want: &user.DefaultInfo{ + UID: "user-abcde", + Name: "admin", + Groups: []string{ + "system:authenticated", + "system:cattle:authenticated", + }, + Extra: map[string][]string{ + "username": {"Default Admin"}, + "principalid": {"local://user-abcde"}, + }, + }, + }, + { + name: "local system cluster user", + userInfo: &user.DefaultInfo{Name: "u-system"}, + userGetFunc: func(_, _ string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "u-system"}, + DisplayName: "System account for Cluster c-abcde", + PrincipalIDs: []string{ + "local://u-system", + }, + }, nil + }, + userAttribGetFunc: func(_, _ string) (*v3.UserAttribute, error) { + return nil, nil + }, + want: &user.DefaultInfo{ + UID: "u-system", + Groups: []string{ + "system:authenticated", + "system:cattle:authenticated", + }, + Extra: map[string][]string{ + "username": {"System account for Cluster c-abcde"}, + "principalid": {"local://u-system"}, + }, + }, + }, + { + name: "local system nonspecific user", + userInfo: &user.DefaultInfo{Name: "u-system"}, + userGetFunc: func(_, _ string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "u-system"}, + PrincipalIDs: []string{ + "local://u-system", + }, + }, nil + }, + userAttribGetFunc: func(_, _ string) (*v3.UserAttribute, error) { + return nil, nil + }, + want: &user.DefaultInfo{ + UID: "u-system", + Groups: []string{ + "system:authenticated", + "system:cattle:authenticated", + }, + Extra: map[string][]string{ + "principalid": {"local://u-system"}, + }, + }, + }, + { + name: "multi auth provider user", + userInfo: &user.DefaultInfo{ + Name: "user-abcde", + }, + userGetFunc: func(_, _ string) (*v3.User, error) { + return &v3.User{ + ObjectMeta: metav1.ObjectMeta{Name: "user-abcde"}, + Username: "admin", + }, nil + }, + userAttribGetFunc: func(_, _ string) (*v3.UserAttribute, error) { + return &v3.UserAttribute{ + GroupPrincipals: map[string]v3.Principals{ + "github": { + Items: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "github_org://456"}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "github_org://123"}, + }, + }, + }, + "openldap": { + Items: []v3.Principal{ + { + ObjectMeta: metav1.ObjectMeta{Name: "openldap_group://cn=group1,dc=example,dc=org"}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "openldap_group://cn=group2,dc=example,dc=org"}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "openldap_group://cn=group2,dc=example,dc=org"}, + }, + }, + }, + }, + ExtraByProvider: map[string]map[string][]string{ + "github": { + "username": []string{ + "user1", + }, + "principalid": []string{ + "github_user://890", + }, + }, + "openldap": { + "username": []string{ + "admin", + }, + "principalid": []string{ + "openldap_user://uid=user1,dc=example,dc=org", + }, + }, + }, + }, nil + }, + want: &user.DefaultInfo{ + UID: "user-abcde", + Name: "admin", + Groups: []string{ + "github_org://123", + "github_org://456", + "openldap_group://cn=group1,dc=example,dc=org", + "openldap_group://cn=group2,dc=example,dc=org", + "system:authenticated", + "system:cattle:authenticated", + }, + Extra: map[string][]string{ + "username": []string{ + "admin", + "user1", + }, + "principalid": []string{ + "github_user://890", + "openldap_user://uid=user1,dc=example,dc=org", + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + impersonator := Impersonator{ + userLister: &fakes.UserListerMock{ + GetFunc: tt.userGetFunc, + }, + userAttributeLister: &fakes.UserAttributeListerMock{ + GetFunc: tt.userAttribGetFunc, + }, + } + got, err := impersonator.getUser(tt.userInfo) + assert.Nil(t, err) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper.go new file mode 100644 index 0000000..386e731 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper.go @@ -0,0 +1,421 @@ +package ingresswrapper + +import ( + "context" + "fmt" + "reflect" + + rextv1beta1 "github.com/rancher/rancher/pkg/generated/norman/extensions/v1beta1" + rnetworkingv1 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + kextv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + clientv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1" + clientv1 "k8s.io/client-go/kubernetes/typed/networking/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// Ingress is an interface with features of both metav1.Object and runtime.Object, +// and can be used whenever the metadata of a resource is needed but the actual +// spec data is not. +type Ingress interface { + client.Object +} + +// ServerSupportsIngressV1 runs a discovery query to check whether the +// networking.k8s.io/v1/Ingress resource is supported in the given cluster. +func ServerSupportsIngressV1(k8sClient kubernetes.Interface) bool { + resources, err := k8sClient.Discovery().ServerResourcesForGroupVersion("networking.k8s.io/v1") + if err != nil || resources == nil { + return false + } + for _, r := range resources.APIResources { + if r.Kind == "Ingress" { + return true + } + } + return false +} + +// CompatSyncV1 returns a controller handler for networking.k8s.io/v1/Ingress resources. +func CompatSyncV1(fn func(string, Ingress) (runtime.Object, error)) func(string, *knetworkingv1.Ingress) (runtime.Object, error) { + return func(key string, obj *knetworkingv1.Ingress) (runtime.Object, error) { return fn(key, obj) } +} + +// CompatSyncV1Beta1 returns a controller handler for extensions/v1beta1/Ingress resources. +func CompatSyncV1Beta1(fn func(string, Ingress) (runtime.Object, error)) func(string, *kextv1beta1.Ingress) (runtime.Object, error) { + return func(key string, obj *kextv1beta1.Ingress) (runtime.Object, error) { return fn(key, obj) } +} + +// ToUnstructured converts a resource Object into a unstructured map. +func ToUnstructured(o interface{}) (map[string]interface{}, error) { + obj := o.(client.Object) + // Populate GVK explicitly. See https://github.com/kubernetes/kubernetes/issues/3030 + gvks, _, err := scheme.Scheme.ObjectKinds(obj) + if err != nil { + return nil, fmt.Errorf("error finding APIVersion or Kind for ingress; %w", err) + } + for _, gvk := range gvks { + if len(gvk.Kind) == 0 { + continue + } + if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal { + continue + } + obj.GetObjectKind().SetGroupVersionKind(gvk) + break + } + return runtime.DefaultUnstructuredConverter.ToUnstructured(o) +} + +// CompatIngress is an intermediary between networking.k8s.io/v1/Ingress and +// extensions/v1beta1/Ingress. It inlines networking.k8s.io/v1/Ingress and so +// it can be handled, and its attributes accessed, in the same way a v1 Ingress +// resource would be handled. +type CompatIngress struct { + knetworkingv1.Ingress +} + +// ToCompatIngress converts a networking.k8s.io/v1/Ingress or +// extensions/v1beta1/Ingress object to a CompatIngress object. If the object +// is already a CompatIngress object, it is returned unchanged. +func ToCompatIngress(obj interface{}) (*CompatIngress, error) { + switch o := obj.(type) { + case *CompatIngress: + return o, nil + case *knetworkingv1.Ingress: + if reflect.ValueOf(o).IsNil() { + return &CompatIngress{}, nil + } + return &CompatIngress{*o}, nil + case *kextv1beta1.Ingress: + unst, err := ToUnstructured(o) + if err != nil { + return nil, err + } + spec := unst["spec"].(map[string]interface{}) + if o.Spec.Backend != nil { + spec["defaultBackend"] = map[string]interface{}{ + "service": map[string]interface{}{ + "name": o.Spec.Backend.ServiceName, + "port": map[string]interface{}{ + "number": o.Spec.Backend.ServicePort.IntVal, + }, + }, + } + delete(spec, "backend") + } + if spec["rules"] != nil { + rules := spec["rules"].([]interface{}) + for i, r := range o.Spec.Rules { + rule := rules[i].(map[string]interface{}) + if r.HTTP != nil { + for j, p := range r.HTTP.Paths { + path := map[string]interface{}{ + "path": p.Path, + "backend": map[string]interface{}{ + "service": map[string]interface{}{ + "name": p.Backend.ServiceName, + "port": map[string]interface{}{ + "number": p.Backend.ServicePort.IntVal, + }, + }, + }, + } + rule["http"].(map[string]interface{})["paths"].([]interface{})[j] = path + } + } + if rule["http"] != nil && rule["http"].(map[string]interface{})["backend"] != nil { + delete(rule["http"].(map[string]interface{})["backend"].(map[string]interface{}), "serviceName") + delete(rule["http"].(map[string]interface{})["backend"].(map[string]interface{}), "servicePort") + } + } + } + compat := CompatIngress{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(unst, &compat.Ingress) + if err != nil { + return nil, err + } + return &compat, nil + default: + return nil, fmt.Errorf("unexpected ingress type: %T", o) + } +} + +// ToIngressV1FromCompat converts a CompatIngress object to a networking.k8s.io/v1/Ingress object. +func ToIngressV1FromCompat(obj *CompatIngress) (*knetworkingv1.Ingress, error) { + unst, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + ingress := knetworkingv1.Ingress{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(unst["ingress"].(map[string]interface{}), &ingress) + if err != nil { + return nil, fmt.Errorf("error converting CompatIngress to networking.k8s.io/v1/Ingress: %w", err) + } + return &ingress, nil +} + +// ToIngressV1Beta1FromCompat converts a CompatIngress object to an extensions/v1beta1/Ingress object. +func ToIngressV1Beta1FromCompat(obj *CompatIngress) (*kextv1beta1.Ingress, error) { + unst, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + spec := unst["ingress"].(map[string]interface{})["spec"].(map[string]interface{}) + if spec["defaultBackend"] != nil { + spec["backend"] = map[string]interface{}{ + "serviceName": obj.Spec.DefaultBackend.Service.Name, + "servicePort": intstr.IntOrString{ + IntVal: obj.Spec.DefaultBackend.Service.Port.Number, + }, + } + } + delete(spec, "defaultBackend") + if spec["rules"] != nil { + rules := spec["rules"].([]interface{}) + for i, r := range obj.Spec.Rules { + rule := rules[i].(map[string]interface{}) + if r.HTTP != nil { + for j, p := range r.HTTP.Paths { + backend := map[string]interface{}{ + "serviceName": p.Backend.Service.Name, + "servicePort": intstr.IntOrString{ + IntVal: p.Backend.Service.Port.Number, + }, + } + rule["http"].(map[string]interface{})["paths"].([]interface{})[j].(map[string]interface{})["backend"] = backend + } + } + } + } + ingress := kextv1beta1.Ingress{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(unst["ingress"].(map[string]interface{}), &ingress) + if err != nil { + return nil, fmt.Errorf("error converting CompatIngress to extensions/v1beta1/Ingress: %w", err) + } + return &ingress, nil +} + +// CompatInterface is a wrapper for the norman interfaces for +// networking.k8s.io/v1/Ingress and extensions/v1beta1/Ingress. +type CompatInterface struct { + ingressInterface rnetworkingv1.IngressInterface + ingressLegacyInterface rextv1beta1.IngressInterface + ServerSupportsIngressV1 bool +} + +// NewCompatInterface initializes either a networking.k8s.io/v1/Ingress client +// or an extensions/v1beta1 client and returns a CompatInterface. +func NewCompatInterface(networkingAPI rnetworkingv1.Interface, extensionsAPI rextv1beta1.Interface, k8sClient kubernetes.Interface) CompatInterface { + c := CompatInterface{ + ServerSupportsIngressV1: ServerSupportsIngressV1(k8sClient), + } + if c.ServerSupportsIngressV1 { + c.ingressInterface = networkingAPI.Ingresses("") + return c + } + c.ingressLegacyInterface = extensionsAPI.Ingresses("") + return c +} + +// Update calls the Update method for the active ingress interface. +func (i *CompatInterface) Update(ingress Ingress) (runtime.Object, error) { + obj := ingress.(*CompatIngress) + if i.ServerSupportsIngressV1 { + toUpdate, err := ToIngressV1FromCompat(obj) + if err != nil { + return toUpdate, err + } + return i.ingressInterface.Update(toUpdate) + } + toUpdate, err := ToIngressV1Beta1FromCompat(obj) + if err != nil { + return toUpdate, err + } + return i.ingressLegacyInterface.Update(toUpdate) +} + +// CompatLister is a wrapper for the norman listers for +// networking.k8s.io/v1/Ingress and extensions/v1beta1/Ingress. +type CompatLister struct { + ingressLister rnetworkingv1.IngressLister + ingressLegacyLister rextv1beta1.IngressLister + ServerSupportsIngressV1 bool +} + +// NewCompatLister initializes either a networking.k8s.io/v1/Ingress watch or +// an extensions/v1beta1/Ingress watch and returns a CompatLister. +func NewCompatLister(networkingAPI rnetworkingv1.Interface, extensionsAPI rextv1beta1.Interface, k8sClient kubernetes.Interface) CompatLister { + c := CompatLister{ + ServerSupportsIngressV1: ServerSupportsIngressV1(k8sClient), + } + if c.ServerSupportsIngressV1 { + c.ingressLister = networkingAPI.Ingresses("").Controller().Lister() + return c + } + c.ingressLegacyLister = extensionsAPI.Ingresses("").Controller().Lister() + return c +} + +// List calls the List method for the active ingress lister. +func (l *CompatLister) List(namespace string, selector labels.Selector) ([]*CompatIngress, error) { + var list []*CompatIngress + if l.ServerSupportsIngressV1 { + ingresses, err := l.ingressLister.List(namespace, selector) + if err != nil { + return list, err + } + for _, i := range ingresses { + ingressCompat, err := ToCompatIngress(i) + if err != nil { + return list, err + } + list = append(list, ingressCompat) + } + return list, nil + } + ingresses, err := l.ingressLegacyLister.List(namespace, selector) + if err != nil { + return list, err + } + for _, i := range ingresses { + ingressCompat, err := ToCompatIngress(i) + if err != nil { + return list, err + } + list = append(list, ingressCompat) + } + return list, nil +} + +// CompatClient is a wrapper for the client-go networking.k8s.io/v1/Ingress and +// extensions/v1beta1/Ingress clients. +type CompatClient struct { + ingressClient clientv1.IngressInterface + ingressLegacyClient clientv1beta1.IngressInterface + ServerSupportsIngressV1 bool +} + +// NewCompatClient initializes either a networking.k8s.io/v1/Ingress client-go client or +// an extensions/v1beta1/Ingress client-go client and returns a CompatClient. +func NewCompatClient(k8sClient kubernetes.Interface, namespace string) CompatClient { + c := CompatClient{ + ServerSupportsIngressV1: ServerSupportsIngressV1(k8sClient), + } + if c.ServerSupportsIngressV1 { + c.ingressClient = k8sClient.NetworkingV1().Ingresses(namespace) + return c + } + c.ingressLegacyClient = k8sClient.ExtensionsV1beta1().Ingresses(namespace) + return c +} + +// Get calls the Get method for the active ingress client. +func (c *CompatClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*CompatIngress, error) { + if c.ServerSupportsIngressV1 { + ret, err := c.ingressClient.Get(ctx, name, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) + } + ret, err := c.ingressLegacyClient.Get(ctx, name, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) +} + +// Create calls the Create method for the active ingress client. +func (c *CompatClient) Create(ctx context.Context, ingress Ingress, opts metav1.CreateOptions) (*CompatIngress, error) { + if c.ServerSupportsIngressV1 { + ret, err := c.ingressClient.Create(ctx, ingress.(*knetworkingv1.Ingress), opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) + } + ret, err := c.ingressLegacyClient.Create(ctx, ingress.(*kextv1beta1.Ingress), opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) +} + +// UpdateStatus calls the UpdateStatus method for the active ingress client. +func (c *CompatClient) UpdateStatus(ctx context.Context, ingress Ingress, opts metav1.UpdateOptions) (*CompatIngress, error) { + if c.ServerSupportsIngressV1 { + var toUpdate *knetworkingv1.Ingress + if o, ok := ingress.(*CompatIngress); ok { + var err error + toUpdate, err = ToIngressV1FromCompat(o) + if err != nil { + return nil, err + } + } else { + toUpdate = ingress.(*knetworkingv1.Ingress) + } + ret, err := c.ingressClient.UpdateStatus(ctx, toUpdate, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) + } + var toUpdate *kextv1beta1.Ingress + if o, ok := ingress.(*CompatIngress); ok { + var err error + toUpdate, err = ToIngressV1Beta1FromCompat(o) + if err != nil { + return nil, err + } + } else { + toUpdate = ingress.(*kextv1beta1.Ingress) + } + ret, err := c.ingressLegacyClient.UpdateStatus(ctx, toUpdate, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) +} + +// Update calls the Update method for the active ingress client. +func (c *CompatClient) Update(ctx context.Context, ingress Ingress, opts metav1.UpdateOptions) (*CompatIngress, error) { + if c.ServerSupportsIngressV1 { + var toUpdate *knetworkingv1.Ingress + if o, ok := ingress.(*CompatIngress); ok { + var err error + toUpdate, err = ToIngressV1FromCompat(o) + if err != nil { + return nil, err + } + } else { + toUpdate = ingress.(*knetworkingv1.Ingress) + } + ret, err := c.ingressClient.Update(ctx, toUpdate, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) + } + var toUpdate *kextv1beta1.Ingress + if o, ok := ingress.(*CompatIngress); ok { + var err error + toUpdate, err = ToIngressV1Beta1FromCompat(o) + if err != nil { + return nil, err + } + } else { + toUpdate = ingress.(*kextv1beta1.Ingress) + } + ret, err := c.ingressLegacyClient.Update(ctx, toUpdate, opts) + if err != nil { + return nil, err + } + return ToCompatIngress(ret) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper_test.go new file mode 100644 index 0000000..12344e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ingresswrapper/ingresswrapper_test.go @@ -0,0 +1,493 @@ +package ingresswrapper + +import ( + "context" + "testing" + + rextv1beta1 "github.com/rancher/rancher/pkg/generated/norman/extensions/v1beta1" + rextv1beta1fakes "github.com/rancher/rancher/pkg/generated/norman/extensions/v1beta1/fakes" + rnetworkingv1 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + rnetworkingv1fakes "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1/fakes" + "github.com/stretchr/testify/assert" + kextv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/intstr" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/kubernetes/fake" +) + +func TestServerSupportsIngressV1(t *testing.T) { + tests := []struct { + name string + discoveryResources []*metav1.APIResourceList + want bool + }{ + { + name: "supports v1 only", + discoveryResources: []*metav1.APIResourceList{ + { + GroupVersion: "networking.k8s.io/v1", + APIResources: []metav1.APIResource{ + { + Kind: "Ingress", + }, + }, + }, + }, + want: true, + }, + { + name: "supports v1beta1 only", + discoveryResources: []*metav1.APIResourceList{ + { + GroupVersion: "extensions/v1beta1", + APIResources: []metav1.APIResource{ + { + Kind: "Ingress", + }, + }, + }, + }, + want: false, + }, + { + name: "supports v1 and v1beta1", + discoveryResources: []*metav1.APIResourceList{ + { + GroupVersion: "extensions/v1beta1", + APIResources: []metav1.APIResource{ + { + Kind: "Ingress", + }, + }, + }, + { + GroupVersion: "networking.k8s.io/v1", + APIResources: []metav1.APIResource{ + { + Kind: "Ingress", + }, + }, + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clientset := fake.NewSimpleClientset() + clientset.Discovery().(*fakediscovery.FakeDiscovery).Resources = tt.discoveryResources + got := ServerSupportsIngressV1(clientset) + assert.Equal(t, tt.want, got) + }) + } +} + +var pathTypeExact = knetworkingv1.PathTypeExact +var ingressV1Spec = knetworkingv1.IngressSpec{ + DefaultBackend: &knetworkingv1.IngressBackend{ + Service: &knetworkingv1.IngressServiceBackend{ + Name: "defaultService", + Port: knetworkingv1.ServiceBackendPort{ + Name: "defaultPort", + Number: 333, + }, + }, + }, + TLS: []knetworkingv1.IngressTLS{ + { + Hosts: []string{ + "foo.com", + "www.foo.com", + }, + }, + }, + Rules: []knetworkingv1.IngressRule{ + { + Host: "bar.com", + IngressRuleValue: knetworkingv1.IngressRuleValue{ + HTTP: &knetworkingv1.HTTPIngressRuleValue{ + Paths: []knetworkingv1.HTTPIngressPath{ + { + Path: "/test", + PathType: &pathTypeExact, + Backend: knetworkingv1.IngressBackend{ + Service: &knetworkingv1.IngressServiceBackend{ + Name: "barService", + Port: knetworkingv1.ServiceBackendPort{ + Name: "barPort", + Number: 444, + }, + }, + }, + }, + }, + }, + }, + }, + }, +} + +var ingressBetaSpec = kextv1beta1.IngressSpec{ + Backend: &kextv1beta1.IngressBackend{ + ServiceName: "defaultBetaService", + ServicePort: intstr.IntOrString{ + IntVal: 555, + }, + }, + TLS: []kextv1beta1.IngressTLS{ + { + Hosts: []string{ + "ftp.foo.com", + }, + }, + }, + Rules: []kextv1beta1.IngressRule{ + { + Host: "baz.com", + IngressRuleValue: kextv1beta1.IngressRuleValue{ + HTTP: &kextv1beta1.HTTPIngressRuleValue{ + Paths: []kextv1beta1.HTTPIngressPath{ + { + Path: "/test/v1beta1", + Backend: kextv1beta1.IngressBackend{ + ServiceName: "specificBetaService", + ServicePort: intstr.IntOrString{ + IntVal: 666, + }, + }, + }, + }, + }, + }, + }, + }, +} + +var convertedSpec = knetworkingv1.IngressSpec{ + DefaultBackend: &knetworkingv1.IngressBackend{ + Service: &knetworkingv1.IngressServiceBackend{ + Name: "defaultBetaService", + Port: knetworkingv1.ServiceBackendPort{ + Number: 555, + }, + }, + }, + TLS: []knetworkingv1.IngressTLS{ + { + Hosts: []string{ + "ftp.foo.com", + }, + }, + }, + Rules: []knetworkingv1.IngressRule{ + { + Host: "baz.com", + IngressRuleValue: knetworkingv1.IngressRuleValue{ + HTTP: &knetworkingv1.HTTPIngressRuleValue{ + Paths: []knetworkingv1.HTTPIngressPath{ + { + Path: "/test/v1beta1", + Backend: knetworkingv1.IngressBackend{ + Service: &knetworkingv1.IngressServiceBackend{ + Name: "specificBetaService", + Port: knetworkingv1.ServiceBackendPort{ + Number: 666, + }, + }, + }, + }, + }, + }, + }, + }, + }, +} + +func TestToCompatIngress(t *testing.T) { + tests := []struct { + name string + obj interface{} + want *CompatIngress + wantErr bool + }{ + { + name: "CompatIngress", + obj: &CompatIngress{}, + want: &CompatIngress{}, + wantErr: false, + }, + { + name: "networking.k8s.io/v1/Ingress", + obj: &knetworkingv1.Ingress{ + Spec: ingressV1Spec, + }, + want: &CompatIngress{ + Ingress: knetworkingv1.Ingress{ + Spec: ingressV1Spec, + }, + }, + wantErr: false, + }, + { + name: "extensions/v1beta1/Ingress", + obj: &kextv1beta1.Ingress{ + Spec: ingressBetaSpec, + }, + want: &CompatIngress{ + Ingress: knetworkingv1.Ingress{ + TypeMeta: metav1.TypeMeta{ + Kind: "Ingress", + APIVersion: "extensions/v1beta1", + }, + Spec: convertedSpec, + }, + }, + wantErr: false, + }, + { + name: "invalid object", + obj: struct{}{}, + want: &CompatIngress{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ToCompatIngress(tt.obj) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.Equal(t, *tt.want, *got) + assert.Nil(t, err) + } + }) + } +} + +func TestToIngressV1FromCompat(t *testing.T) { + tests := []struct { + name string + obj *CompatIngress + want *knetworkingv1.Ingress + }{ + { + name: "empty CompatIngress", + obj: &CompatIngress{}, + want: &knetworkingv1.Ingress{}, + }, + { + name: "full CompatIngress", + obj: &CompatIngress{ + Ingress: knetworkingv1.Ingress{ + Spec: ingressV1Spec, + }, + }, + want: &knetworkingv1.Ingress{ + Spec: ingressV1Spec, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, _ := ToIngressV1FromCompat(tt.obj) + assert.Equal(t, *tt.want, *got) + }) + } +} + +func TestToIngressV1Beta1FromCompat(t *testing.T) { + tests := []struct { + name string + obj *CompatIngress + want *kextv1beta1.Ingress + wantErr bool + }{ + { + name: "empty CompatIngress", + obj: &CompatIngress{}, + want: &kextv1beta1.Ingress{}, + }, + { + name: "full CompatIngress", + obj: &CompatIngress{knetworkingv1.Ingress{ + Spec: convertedSpec, + }}, + want: &kextv1beta1.Ingress{ + Spec: ingressBetaSpec, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, _ := ToIngressV1Beta1FromCompat(tt.obj) + assert.Equal(t, *tt.want, *got) + }) + } +} + +func TestCompatReverse(t *testing.T) { + tests := []struct { + name string + obj interface{} + }{ + { + name: "reverse networking.k8s.io/v1", + obj: &knetworkingv1.Ingress{ + Spec: ingressV1Spec, + }, + }, + { + name: "reverse extensionsv1/v1beta1", + obj: &kextv1beta1.Ingress{ + Spec: ingressBetaSpec, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + compat, _ := ToCompatIngress(tt.obj) + switch o := tt.obj.(type) { + case *knetworkingv1.Ingress: + got, _ := ToIngressV1FromCompat(compat) + assert.Equal(t, *o, *got) + case *kextv1beta1.Ingress: + got, _ := ToIngressV1Beta1FromCompat(compat) + assert.Equal(t, *o, *got) + } + }) + } +} + +func TestCompatInterface(t *testing.T) { + var v1called int + var v1beta1called int + tests := []struct { + name string + compatInterface CompatInterface + v1calls int + v1beta1calls int + }{ + { + name: "update networking.k8s.io/v1/Ingress", + compatInterface: CompatInterface{ + ingressInterface: &rnetworkingv1fakes.IngressInterfaceMock{ + UpdateFunc: func(*rnetworkingv1.Ingress) (*rnetworkingv1.Ingress, error) { + v1called += 1 + return nil, nil + }, + }, + ServerSupportsIngressV1: true, + }, + v1calls: 1, + }, + { + name: "update extensions/v1/Ingress", + compatInterface: CompatInterface{ + ingressLegacyInterface: &rextv1beta1fakes.IngressInterfaceMock{ + UpdateFunc: func(*rextv1beta1.Ingress) (*rextv1beta1.Ingress, error) { + v1beta1called += 1 + return nil, nil + }, + }, + ServerSupportsIngressV1: false, + }, + v1beta1calls: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _ = tt.compatInterface.Update(&CompatIngress{}) + assert.Equal(t, tt.v1calls, v1called) + assert.Equal(t, tt.v1beta1calls, v1beta1called) + v1called = 0 + v1beta1called = 0 + }) + } +} + +func TestCompatLister(t *testing.T) { + var v1called int + var v1beta1called int + tests := []struct { + name string + compatLister CompatLister + v1calls int + v1beta1calls int + }{ + { + name: "list networking.k8s.io/v1/Ingress", + compatLister: CompatLister{ + ingressLister: &rnetworkingv1fakes.IngressListerMock{ + ListFunc: func(string, labels.Selector) ([]*rnetworkingv1.Ingress, error) { + v1called += 1 + return nil, nil + }, + }, + ServerSupportsIngressV1: true, + }, + v1calls: 1, + }, + { + name: "list extensions/v1/Ingress", + compatLister: CompatLister{ + ingressLegacyLister: &rextv1beta1fakes.IngressListerMock{ + ListFunc: func(string, labels.Selector) ([]*rextv1beta1.Ingress, error) { + v1beta1called += 1 + return nil, nil + }, + }, + ServerSupportsIngressV1: false, + }, + v1beta1calls: 1, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, _ = tt.compatLister.List("", labels.NewSelector()) + assert.Equal(t, tt.v1calls, v1called) + assert.Equal(t, tt.v1beta1calls, v1beta1called) + v1called = 0 + v1beta1called = 0 + }) + } +} + +func TestCompatClient(t *testing.T) { + tests := []struct { + name string + compatClient CompatClient + obj Ingress + }{ + { + name: "list networking.k8s.io/v1/Ingress", + compatClient: CompatClient{ + ingressClient: fake.NewSimpleClientset(&knetworkingv1.Ingress{ObjectMeta: metav1.ObjectMeta{Name: "test"}}).NetworkingV1().Ingresses(""), + ServerSupportsIngressV1: true, + }, + obj: &knetworkingv1.Ingress{}, + }, + { + name: "list extensions/v1/Ingress", + compatClient: CompatClient{ + ingressLegacyClient: fake.NewSimpleClientset(&kextv1beta1.Ingress{ObjectMeta: metav1.ObjectMeta{Name: "test"}}).ExtensionsV1beta1().Ingresses(""), + ServerSupportsIngressV1: false, + }, + obj: &kextv1beta1.Ingress{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := tt.compatClient.Get(context.Background(), "test", metav1.GetOptions{}) + assert.NoError(t, err) + _, err = tt.compatClient.Create(context.Background(), tt.obj, metav1.CreateOptions{}) + assert.NoError(t, err) + _, err = tt.compatClient.UpdateStatus(context.Background(), tt.obj, metav1.UpdateOptions{}) + assert.NoError(t, err) + _, err = tt.compatClient.Update(context.Background(), tt.obj, metav1.UpdateOptions{}) + assert.NoError(t, err) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer.go new file mode 100644 index 0000000..551e949 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer.go @@ -0,0 +1,85 @@ +package jailer + +import ( + "context" + "os" + "os/exec" + "path" + "strconv" + "strings" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/rancher/rancher/pkg/settings" + "github.com/sirupsen/logrus" +) + +const BaseJailPath = "/opt/jail" + +var lock = sync.Mutex{} + +// CreateJail sets up the named directory for use with chroot +func CreateJail(name string) error { + if os.Getenv("CATTLE_DEV_MODE") != "" { + return os.MkdirAll(path.Join(BaseJailPath, name), 0700) + } + + logrus.Debugf("CreateJail: called for [%s]", name) + lock.Lock() + defer lock.Unlock() + + jailPath := path.Join(BaseJailPath, name) + + logrus.Debugf("CreateJail: jailPath is [%s]", jailPath) + // Check for the done file, if that exists the jail is ready to be used + _, err := os.Stat(path.Join(jailPath, "done")) + if err == nil { + logrus.Debugf("CreateJail: done file found at [%s], jail is ready", path.Join(jailPath, "done")) + return nil + } + + // If the base dir exists without the done file rebuild the directory + _, err = os.Stat(jailPath) + if err == nil { + logrus.Debugf("CreateJail: basedir for jail exists but no done file found, removing jailPath [%s]", jailPath) + if err := os.RemoveAll(jailPath); err != nil { + return err + } + + } + + t := settings.JailerTimeout.Get() + timeout, err := strconv.Atoi(t) + if err != nil { + timeout = 60 + logrus.Warnf("error converting jailer-timeout setting to int, using default of 60 seconds - error: [%v]", err) + } + + logrus.Debugf("CreateJail: Running script to create jail for [%s]", name) + + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) + defer cancel() + + cmd := exec.CommandContext(ctx, "/usr/bin/jailer.sh", name) + out, err := cmd.CombinedOutput() + if len(out) > 0 { + logrus.Tracef("CreateJail: output from jail script for [%s]: [%v]", name, string(out)) + } else { + logrus.Tracef("CreateJail: no output from jail script for [%s]", name) + } + if err != nil { + if strings.HasSuffix(err.Error(), "signal: killed") { + return errors.WithMessage(err, "error running the jail command: timed out waiting for the script to complete") + } + return errors.WithMessage(err, "error running the jail command") + } + return nil +} + +func getWhitelistedEnvVars(envvars []string) []string { + settings.IterateWhitelistedEnvVars(func(name, value string) { + envvars = append(envvars, name+"="+value) + }) + return envvars +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_linux.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_linux.go new file mode 100644 index 0000000..5f71f06 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_linux.go @@ -0,0 +1,56 @@ +package jailer + +import ( + "os" + "os/exec" + "os/user" + "strconv" + "syscall" + + "github.com/pkg/errors" +) + +func JailCommand(cmd *exec.Cmd, jailPath string) (*exec.Cmd, error) { + if os.Getenv("CATTLE_DEV_MODE") != "" { + return cmd, nil + } + + cred, err := getUserCred() + if err != nil { + return nil, errors.WithMessage(err, "get user cred error") + } + + cmd.SysProcAttr = &syscall.SysProcAttr{} + cmd.SysProcAttr.Credential = cred + cmd.SysProcAttr.Chroot = jailPath + cmd.Env = getWhitelistedEnvVars(cmd.Env) + cmd.Env = append(cmd.Env, "PWD=/") + cmd.Dir = "/" + return cmd, nil +} + +// getUserCred looks up the user and provides it in syscall.Credential +func getUserCred() (*syscall.Credential, error) { + u, err := user.Current() + if err != nil { + uID := os.Getuid() + u, err = user.LookupId(strconv.Itoa(uID)) + if err != nil { + return nil, err + } + } + + i, err := strconv.ParseUint(u.Uid, 10, 32) + if err != nil { + return nil, err + } + uid := uint32(i) + + i, err = strconv.ParseUint(u.Gid, 10, 32) + if err != nil { + return nil, err + } + gid := uint32(i) + + return &syscall.Credential{Uid: uid, Gid: gid}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_nolinux.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_nolinux.go new file mode 100644 index 0000000..41ae2a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_nolinux.go @@ -0,0 +1,16 @@ +//go:build !linux +// +build !linux + +package jailer + +import ( + "os/exec" + "runtime" + + "github.com/sirupsen/logrus" +) + +func JailCommand(cmd *exec.Cmd, jailPath string) (*exec.Cmd, error) { + logrus.Warnf("not jailing command %v, unsupported on %s", cmd.Args, runtime.GOOS) + return cmd, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_test.go new file mode 100644 index 0000000..12dc8fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/jailer/jailer_test.go @@ -0,0 +1,46 @@ +package jailer + +import ( + "os" + "testing" + + "github.com/rancher/rancher/pkg/settings" + "github.com/stretchr/testify/assert" +) + +func Test_WhitelistEnvvars(t *testing.T) { + settings.WhitelistEnvironmentVars.Set("ENVVAR_FOO") + defer os.Unsetenv("ENVVAR_FOO") + + type testCase struct { + input []string + expected []string + envValue string + } + + testCases := []testCase{ + // Base case, nothing goes in, no env set, nothing comes out + { + envValue: "", + input: []string{}, + expected: []string{}, + }, + { + envValue: "BAR", + input: []string{}, + expected: []string{"ENVVAR_FOO=BAR"}, + }, + { + envValue: "ALPHA", + input: []string{"BAZ=FOOBAZ"}, + expected: []string{"BAZ=FOOBAZ", "ENVVAR_FOO=ALPHA"}, + }, + } + + for _, tc := range testCases { + os.Setenv("ENVVAR_FOO", tc.envValue) + envs := getWhitelistedEnvVars(tc.input) + assert.Equal(t, envs, tc.expected) + } + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8slookup/lookup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8slookup/lookup.go new file mode 100644 index 0000000..07a73bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8slookup/lookup.go @@ -0,0 +1,45 @@ +package k8slookup + +import ( + "net/http" + + "github.com/rancher/norman/api/access" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/clusterrouter" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + schema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" +) + +func New(context *config.ScaledContext, validate bool) clusterrouter.ClusterLookup { + return &lookup{ + clusterLister: context.Management.Clusters("").Controller().Lister(), + schemas: context.Schemas, + validate: validate, + } +} + +type lookup struct { + clusterLister v3.ClusterLister + schemas *types.Schemas + validate bool +} + +func (l *lookup) Lookup(req *http.Request) (*v3.Cluster, error) { + apiContext := types.NewAPIContext(req, nil, l.schemas) + clusterID := clusterrouter.GetClusterID(req) + if clusterID == "" { + return nil, httperror.NewAPIError(httperror.NotFound, "failed to find cluster") + } + + if l.validate { + // check access + if err := access.ByID(apiContext, &schema.Version, client.ClusterType, clusterID, &client.Cluster{}); err != nil { + return nil, err + } + } + + return l.clusterLister.Get("", clusterID) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8sproxy/k8s_proxy.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8sproxy/k8s_proxy.go new file mode 100644 index 0000000..8747e07 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/k8sproxy/k8s_proxy.go @@ -0,0 +1,17 @@ +package k8sproxy + +import ( + "net/http" + + "github.com/rancher/rancher/pkg/clusterrouter" + "github.com/rancher/rancher/pkg/clusterrouter/proxy" + "github.com/rancher/rancher/pkg/k8slookup" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/dialer" +) + +func New(scaledContext *config.ScaledContext, dialer dialer.Factory, clusterContextGetter proxy.ClusterContextGetter) http.Handler { + return clusterrouter.New(&scaledContext.RESTConfig, k8slookup.New(scaledContext, true), dialer, + scaledContext.Management.Clusters("").Controller().Lister(), + clusterContextGetter) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kontainerdriver/driver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kontainerdriver/driver.go new file mode 100644 index 0000000..8d552c4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kontainerdriver/driver.go @@ -0,0 +1,41 @@ +package kontainerdriver + +import ( + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" +) + +func GetDriver(cluster *v3.Cluster, driverLister v3.KontainerDriverLister) (string, error) { + var driver *v3.KontainerDriver + var err error + + if cluster.Spec.GenericEngineConfig != nil { + kontainerDriverName := (*cluster.Spec.GenericEngineConfig)["driverName"].(string) + driver, err = driverLister.Get("", kontainerDriverName) + if err != nil { + return "", err + } + } + + if cluster.Spec.AKSConfig != nil { + return apimgmtv3.ClusterDriverAKS, nil + } + + if cluster.Spec.EKSConfig != nil { + return apimgmtv3.ClusterDriverEKS, nil + } + + if cluster.Spec.GKEConfig != nil { + return apimgmtv3.ClusterDriverGKE, nil + } + + if cluster.Spec.RancherKubernetesEngineConfig != nil { + return apimgmtv3.ClusterDriverRKE, nil + } + + if driver == nil { + return "", nil + } + + return driver.Status.DisplayName, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/kubeconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/kubeconfig.go new file mode 100644 index 0000000..b67d549 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/kubeconfig.go @@ -0,0 +1,166 @@ +package kubeconfig + +import ( + "bytes" + "encoding/base64" + "fmt" + "regexp" + "strings" + + managementv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/node" + "github.com/rancher/rancher/pkg/settings" +) + +const ( + certDelim = "\\\n " + firstLen = 49 +) + +var ( + splitRegexp = regexp.MustCompile(`\S{1,76}`) +) + +type kubeNode struct { + ClusterName string + Server string + Cert string + User string +} + +type data struct { + ClusterName string + Host string + ClusterID string + Cert string + User string + Username string + Password string + Token string + EndpointEnabled bool + Nodes []kubeNode +} + +func ForBasic(host, username, password string) (string, error) { + data := &data{ + ClusterName: "cluster", + Host: host, + Cert: caCertString(), + User: username, + Username: username, + Password: password, + } + + if data.ClusterName == "" { + data.ClusterName = data.ClusterID + } + + buf := &bytes.Buffer{} + err := basicTemplate.Execute(buf, data) + return buf.String(), err +} + +func formatCertString(certData string) string { + buf := &bytes.Buffer{} + if len(certData) > firstLen { + buf.WriteString(certData[:firstLen]) + certData = certData[firstLen:] + } else { + return certData + } + + for _, part := range splitRegexp.FindAllStringSubmatch(certData, -1) { + buf.WriteString(certDelim) + buf.WriteString(part[0]) + } + + return buf.String() +} + +func caCertString() string { + certData := settings.CACerts.Get() + if certData == "" { + return "" + } + certData = base64.StdEncoding.EncodeToString([]byte(certData)) + return formatCertString(certData) +} + +func getDefaultNode(clusterName, clusterID, host string) kubeNode { + return kubeNode{ + Server: fmt.Sprintf("https://%s/k8s/clusters/%s", host, clusterID), + Cert: caCertString(), + ClusterName: clusterName, + User: clusterName, + } +} + +func ForTokenBased(clusterName, clusterID, host, token string) (string, error) { + data := &data{ + ClusterName: clusterName, + ClusterID: clusterID, + Host: host, + Cert: caCertString(), + User: clusterName, + Token: token, + Nodes: []kubeNode{getDefaultNode(clusterName, clusterID, host)}, + EndpointEnabled: false, + } + + if data.ClusterName == "" { + data.ClusterName = data.ClusterID + } + + buf := &bytes.Buffer{} + err := tokenTemplate.Execute(buf, data) + return buf.String(), err +} + +func ForClusterTokenBased(cluster *managementv3.Cluster, nodes []*mgmtv3.Node, clusterID, host, token string) (string, error) { + clusterName := cluster.Name + if clusterName == "" { + clusterName = clusterID + } + + nodesForConfig := []kubeNode{getDefaultNode(clusterName, clusterID, host)} + + if cluster.LocalClusterAuthEndpoint.FQDN != "" { + fqdnCACerts := base64.StdEncoding.EncodeToString([]byte(cluster.LocalClusterAuthEndpoint.CACerts)) + clusterNode := kubeNode{ + ClusterName: clusterName + "-fqdn", + Server: "https://" + cluster.LocalClusterAuthEndpoint.FQDN, + Cert: formatCertString(fqdnCACerts), + User: clusterName, + } + nodesForConfig = append(nodesForConfig, clusterNode) + } else { + for _, n := range nodes { + if n.Spec.ControlPlane { + nodeName := clusterName + "-" + strings.TrimPrefix(n.Spec.RequestedHostname, clusterName+"-") + clusterNode := kubeNode{ + ClusterName: nodeName, + Server: "https://" + node.GetEndpointNodeIP(n) + ":6443", + Cert: formatCertString(cluster.CACert), + User: clusterName, + } + nodesForConfig = append(nodesForConfig, clusterNode) + } + } + } + + data := &data{ + ClusterName: clusterName, + ClusterID: clusterID, + Host: host, + Cert: caCertString(), + User: clusterName, + Token: token, + Nodes: nodesForConfig, + EndpointEnabled: true, + } + + buf := &bytes.Buffer{} + err := tokenTemplate.Execute(buf, data) + return buf.String(), err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/templates.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/templates.go new file mode 100644 index 0000000..cf57bbb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubeconfig/templates.go @@ -0,0 +1,74 @@ +package kubeconfig + +import "html/template" + +const ( + tokenTemplateText = `apiVersion: v1 +kind: Config +clusters: +{{- range .Nodes}} +- name: "{{.ClusterName}}" + cluster: + server: "{{.Server}}" +{{- if ne .Cert "" }} + certificate-authority-data: "{{.Cert}}" +{{- end }} +{{- end}} + +users: +- name: "{{.User}}" + user: +{{- if .Token }} + token: "{{.Token}}" +{{ else }} + exec: + apiVersion: client.authentication.k8s.io/v1beta1 + args: + - token + - --server={{.Host}} + - --user={{.User}} +{{- if .EndpointEnabled }} + - --cluster={{.ClusterID}} +{{- end }} + command: rancher +{{- end }} + +contexts: +{{- range .Nodes}} +- name: "{{.ClusterName}}" + context: + user: "{{.User}}" + cluster: "{{.ClusterName}}" +{{- end}} + +current-context: "{{.ClusterName}}" +` + + basicTemplateText = `apiVersion: v1 +kind: Config +clusters: +- name: "{{.ClusterName}}" + cluster: + server: "https://{{.Host}}" + api-version: v1 + +users: +- name: "{{.User}}" + user: + username: "{{.Username}}" + password: "{{.Password}}" + +contexts: +- name: "{{.ClusterName}}" + context: + user: "{{.User}}" + cluster: "{{.ClusterName}}" + +current-context: "{{.ClusterName}}" +` +) + +var ( + basicTemplate = template.Must(template.New("basicTemplate").Parse(basicTemplateText)) + tokenTemplate = template.Must(template.New("tokenTemplate").Parse(tokenTemplateText)) +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubectl/kubectl.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubectl/kubectl.go new file mode 100644 index 0000000..f6baae8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/kubectl/kubectl.go @@ -0,0 +1,167 @@ +package kubectl + +import ( + "context" + "io/ioutil" + "os" + "os/exec" + "strings" + + "fmt" + + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" +) + +const ( + tmpDir = "./management-state/tmp" +) + +func Apply(yaml []byte, kubeConfig *clientcmdapi.Config) ([]byte, error) { + kubeConfigFile, yamlFile, err := writeData(kubeConfig, yaml) + defer cleanup(kubeConfigFile, yamlFile) + if err != nil { + return nil, err + } + cmd := exec.Command("kubectl", + "--kubeconfig", + kubeConfigFile.Name(), + "apply", + "-f", + yamlFile.Name()) + return runWithHTTP2(cmd) +} + +func ApplyWithNamespace(yaml []byte, namespace string, kubeConfig *clientcmdapi.Config) ([]byte, error) { + kubeConfigFile, yamlFile, err := writeData(kubeConfig, yaml) + defer cleanup(kubeConfigFile, yamlFile) + if err != nil { + return nil, err + } + cmd := exec.Command("kubectl", + "--kubeconfig", + kubeConfigFile.Name(), + "-n", + namespace, + "apply", + "-f", + yamlFile.Name()) + return runWithHTTP2(cmd) +} + +func RolloutStatusWithNamespace(namespace, name, timeout string, kubeConfig *clientcmdapi.Config) ([]byte, error) { + kubeConfigFile, err := writeKubeConfig(kubeConfig) + defer cleanup(kubeConfigFile) + if err != nil { + return nil, err + } + cmd := exec.Command("kubectl", + "--kubeconfig", + kubeConfigFile.Name(), + "-n", + namespace, + "rollout", + "status", + name, + "--timeout", + timeout) + return runWithHTTP2(cmd) +} + +func Delete(yaml []byte, kubeConfig *clientcmdapi.Config) ([]byte, error) { + kubeConfigFile, yamlFile, err := writeData(kubeConfig, yaml) + defer cleanup(kubeConfigFile, yamlFile) + if err != nil { + return nil, err + } + cmd := exec.Command("kubectl", + "--kubeconfig", + kubeConfigFile.Name(), + "delete", + "-f", + yamlFile.Name()) + return runWithHTTP2(cmd) +} + +func Drain(ctx context.Context, kubeConfig *clientcmdapi.Config, nodeName string, args []string) ([]byte, string, error) { + kubeConfigFile, err := writeKubeConfig(kubeConfig) + defer cleanup(kubeConfigFile) + if err != nil { + return nil, "", err + } + cmd := exec.CommandContext(ctx, "kubectl", + "--kubeconfig", + kubeConfigFile.Name(), + "drain", + nodeName) + cmd.Args = append(cmd.Args, args...) + output, err := runWithHTTP2(cmd) + return output, fmt.Sprint(cmd.Stderr), err +} + +func cleanup(files ...*os.File) { + for _, file := range files { + if file == nil { + continue + } + os.Remove(file.Name()) + } +} + +func writeData(kubeConfig *clientcmdapi.Config, yaml []byte) (*os.File, *os.File, error) { + kubeConfigFile, err := writeKubeConfig(kubeConfig) + if err != nil { + return kubeConfigFile, nil, err + } + yamlFile, err := writeYAMLFile(yaml) + return kubeConfigFile, yamlFile, err +} + +func writeYAMLFile(yaml []byte) (*os.File, error) { + yamlFile, err := tempFile("yaml-") + if err != nil { + return nil, err + } + if err := ioutil.WriteFile(yamlFile.Name(), yaml, 0600); err != nil { + return nil, err + } + return yamlFile, nil +} + +func writeKubeConfig(kubeConfig *clientcmdapi.Config) (*os.File, error) { + kubeConfigFile, err := tempFile("kubeconfig-") + if err != nil { + return nil, err + } + if err := clientcmd.WriteToFile(*kubeConfig, kubeConfigFile.Name()); err != nil { + return nil, err + } + return kubeConfigFile, nil +} + +func tempFile(prefix string) (*os.File, error) { + if _, err := os.Stat(tmpDir); os.IsNotExist(err) { + if err = os.MkdirAll(tmpDir, 0755); err != nil { + return nil, err + } + } + + f, err := ioutil.TempFile(tmpDir, prefix) + if err != nil { + return nil, err + } + + return f, f.Close() +} + +func runWithHTTP2(cmd *exec.Cmd) ([]byte, error) { + var newEnv []string + for _, env := range os.Environ() { + if strings.HasPrefix(env, "DISABLE_HTTP2") { + continue + } + newEnv = append(newEnv, env) + } + cmd.Env = newEnv + return cmd.CombinedOutput() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/rke.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/rke.go new file mode 100644 index 0000000..2a7f5b0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/rke.go @@ -0,0 +1,41 @@ +package librke + +import ( + "context" + + "github.com/docker/docker/api/types" + "github.com/rancher/norman/types/convert" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rke/cluster" + "github.com/rancher/rke/pki" + rketypes "github.com/rancher/rke/types" +) + +type rke struct { +} + +func (*rke) GenerateRKENodeCerts(ctx context.Context, rkeConfig rketypes.RancherKubernetesEngineConfig, nodeAddress string, certBundle map[string]pki.CertificatePKI) map[string]pki.CertificatePKI { + return pki.GenerateRKENodeCerts(ctx, rkeConfig, nodeAddress, certBundle) +} + +func (*rke) GenerateCerts(config *rketypes.RancherKubernetesEngineConfig) (map[string]pki.CertificatePKI, error) { + return pki.GenerateRKECerts(context.Background(), *config, "", "") +} + +func (*rke) GeneratePlan(ctx context.Context, rkeConfig *rketypes.RancherKubernetesEngineConfig, dockerInfo map[string]types.Info, data map[string]interface{}) (rketypes.RKEPlan, error) { + return cluster.GeneratePlan(ctx, rkeConfig.DeepCopy(), dockerInfo, data) +} + +func GetDockerInfo(node *v3.Node) (map[string]types.Info, error) { + infos := map[string]types.Info{} + if node.Status.DockerInfo != nil { + dockerInfo := types.Info{} + err := convert.ToObj(node.Status.DockerInfo, &dockerInfo) + if err != nil { + return nil, err + } + infos[node.Status.NodeConfig.Address] = dockerInfo + } + + return infos, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/types.go new file mode 100644 index 0000000..4d3ff0c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/librke/types.go @@ -0,0 +1,20 @@ +package librke + +import ( + "context" + + rketypes "github.com/rancher/rke/types" + + "github.com/docker/docker/api/types" + "github.com/rancher/rke/pki" +) + +type RKE interface { + GenerateRKENodeCerts(ctx context.Context, rkeConfig rketypes.RancherKubernetesEngineConfig, nodeAddress string, certBundle map[string]pki.CertificatePKI) map[string]pki.CertificatePKI + GenerateCerts(config *rketypes.RancherKubernetesEngineConfig) (map[string]pki.CertificatePKI, error) + GeneratePlan(ctx context.Context, rkeConfig *rketypes.RancherKubernetesEngineConfig, dockerInfo map[string]types.Info, data map[string]interface{}) (rketypes.RKEPlan, error) +} + +func New() RKE { + return (*rke)(nil) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/logserver/server.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/logserver/server.go new file mode 100644 index 0000000..64ae6f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/logserver/server.go @@ -0,0 +1,71 @@ +package logserver + +import ( + "fmt" + "net" + "net/http" + "os" + + "github.com/sirupsen/logrus" +) + +var ( + DefaultSocketLocation = "/tmp/log.sock" +) + +// Server structure is used to the store backend information +type Server struct { + SocketLocation string + Debug bool +} + +// StartServerWithDefaults starts the server with default values +func StartServerWithDefaults() { + s := Server{ + SocketLocation: DefaultSocketLocation, + } + s.Start() +} + +// Start the server +func (s *Server) Start() { + os.Remove(s.SocketLocation) + go s.ListenAndServe() +} + +// ListenAndServe is used to setup handlers and +// start listening on the specified location +func (s *Server) ListenAndServe() error { + logrus.Infof("Listening on %s", s.SocketLocation) + server := http.Server{} + http.HandleFunc("/v1/loglevel", s.loglevel) + socketListener, err := net.Listen("unix", s.SocketLocation) + if err != nil { + return err + } + return server.Serve(socketListener) +} + +func (s *Server) loglevel(rw http.ResponseWriter, req *http.Request) { + // curl -X POST -d "level=debug" localhost:12345/v1/loglevel + logrus.Debugf("Received loglevel request") + if req.Method == http.MethodGet { + level := logrus.GetLevel().String() + rw.Write([]byte(fmt.Sprintf("%s\n", level))) + } + + if req.Method == http.MethodPost { + if err := req.ParseForm(); err != nil { + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte(fmt.Sprintf("Failed to parse form: %v\n", err))) + } + level, err := logrus.ParseLevel(req.Form.Get("level")) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte(fmt.Sprintf("Failed to parse loglevel: %v\n", err))) + } else { + logrus.SetLevel(level) + rw.Write([]byte("OK\n")) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/managedcharts/cspadapter/cspadapter.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/managedcharts/cspadapter/cspadapter.go new file mode 100644 index 0000000..768875c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/managedcharts/cspadapter/cspadapter.go @@ -0,0 +1,59 @@ +// Package cspadapter provides utilities which can help discover if the csp adapter chart is installed, +// for either the original Managed License Offering (MLO) or new Pay-As-You-Go (PAYG) licensing. +package cspadapter + +import ( + "errors" + + "github.com/sirupsen/logrus" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/release" + "k8s.io/cli-runtime/pkg/genericclioptions" +) + +const ( + // MLOChartNamespace is the namespace that we expect the adapter to be installed in, + // for the original Managed License Offering (MLO) licensing + MLOChartNamespace = "cattle-csp-adapter-system" + // MLOChartName is the name of the csp adapter chart for MLO licensing. + MLOChartName = "rancher-csp-adapter" + // PAYGChartNamespace is the namespace that we expect the adapter to be installed in, + // for the new Pay-As-You-Go (PAYG) license offering + PAYGChartNamespace = "cattle-csp-billing-adapter-system" + // PAYGChartName is the name of the csp adapter chart for PAYG licensing. + PAYGChartName = "rancher-csp-billing-adapter" +) + +// ErrNotFound indicates that the adapter was not found to be installed +var ErrNotFound = errors.New("NotFound") + +// ChartUtil provides methods to interact with the cspadapter chart and releases derived form the chart +type ChartUtil struct { + restClientGetter genericclioptions.RESTClientGetter +} + +// NewChartUtil creates a ChartUtil using a RESTClientGetter - this will be used for helm calls to k8s +func NewChartUtil(clientGetter genericclioptions.RESTClientGetter) *ChartUtil { + return &ChartUtil{ + restClientGetter: clientGetter, + } +} + +// GetRelease finds the release for the CSP adapter for a given offering. If not found, returns nil, ErrNotFound. +func (c *ChartUtil) GetRelease(chartNamespace string, chartName string) (*release.Release, error) { + cfg := &action.Configuration{} + if err := cfg.Init(c.restClientGetter, chartNamespace, "", logrus.Infof); err != nil { + return nil, err + } + l := action.NewList(cfg) + releases, err := l.Run() + if err != nil { + return nil, err + } + for _, helmRelease := range releases { + if helmRelease.Chart.Name() == chartName { + return helmRelease, nil + } + } + return nil, ErrNotFound +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/garbagecollector.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/garbagecollector.go new file mode 100644 index 0000000..b995435 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/garbagecollector.go @@ -0,0 +1,185 @@ +package metrics + +import ( + "reflect" + "strings" + + "github.com/prometheus/client_golang/prometheus" + dto "github.com/prometheus/client_model/go" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + rm "github.com/rancher/remotedialer/metrics" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" +) + +var ( + targetMetricsByNameForClientKey = []interface{}{ + rm.TotalAddWS, rm.TotalRemoveWS, rm.TotalAddConnectionsForWS, rm.TotalRemoveConnectionsForWS, + rm.TotalTransmitBytesOnWS, rm.TotalTransmitErrorBytesOnWS, rm.TotalReceiveBytesOnWS, + } + + targetMetricsByIPForPeer = []interface{}{ + rm.TotalAddPeerAttempt, rm.TotalPeerConnected, rm.TotalPeerDisConnected, + } +) + +type metricGarbageCollector struct { + clusterLister v3.ClusterLister + nodeLister v3.NodeLister + endpointLister v1.EndpointsLister +} + +func (gc *metricGarbageCollector) metricGarbageCollection() { + logrus.Debugf("[metrics-garbage-collector] Start") + + isClusterMode := settings.Namespace.Get() != "" && settings.PeerServices.Get() != "" + + // Existing resources + observedResourceNames := map[string]bool{} + // Exisiting Metrics Labels + observedLabelsMap := map[string]map[interface{}][]map[string]string{} + + // Get Clusters + clusters, err := gc.clusterLister.List("", labels.Everything()) + if err != nil { + logrus.Errorf("[metrics-garbage-collector] failed to list clusters: %s", err) + return + } + for _, cluster := range clusters { + if _, ok := observedResourceNames[cluster.Name]; !ok { + observedResourceNames[cluster.Name] = true + } + } + // Get Nodes + nodes, err := gc.nodeLister.List("", labels.Everything()) + if err != nil { + logrus.Errorf("[metrics-garbage-collector] failed to list nodes: %s", err) + } + for _, node := range nodes { + if _, ok := observedResourceNames[node.Namespace+":"+node.Name]; !ok { + observedResourceNames[node.Namespace+":"+node.Name] = true + } + } + // Get Endpoints + if isClusterMode { + endpoints, err := gc.endpointLister.List(settings.Namespace.Get(), labels.Everything()) + if err != nil { + logrus.Errorf("[metrics-garbage-collector] failed to list endpoints: %s", err) + } + for _, svc := range strings.Split(settings.PeerServices.Get(), ",") { + for _, e := range endpoints { + // If Endpoint is associated with PeerServices service + if e.Name == strings.TrimSpace(svc) { + for _, subset := range e.Subsets { + for _, addr := range subset.Addresses { + observedResourceNames[addr.IP] = true + } + } + } + } + } + } + + buildObservedLabelMaps(targetMetricsByNameForClientKey, "clientkey", observedLabelsMap) + buildObservedLabelMaps(targetMetricsByIPForPeer, "peer", observedLabelsMap) + buildObservedLabelMaps([]interface{}{clusterOwner}, "cluster", observedLabelsMap) + + removedCount := removeMetricsForDeletedResource(observedLabelsMap, observedResourceNames) + + logrus.Debugf("[metrics-garbage-collector] Finished - removed %d items", removedCount) +} + +func buildObservedLabelMaps(collectors []interface{}, targetLabel string, observedLabels map[string]map[interface{}][]map[string]string) int { + // Example of the map structure of observedLabels: + // { + // "c-fz6fq": { + // collectorA: [ {"clientkey": "c-fz6fq", "peer": "false"}, ], + // collectorB: [ {"clientkey": "c-fz6fq", "peer": "false"}, ], + // }, + // "": { + // } + // } + count := 0 + for _, collector := range collectors { + metricChan := make(chan prometheus.Metric) + metricFrame := &dto.Metric{} + go func() { collector.(prometheus.Collector).Collect(metricChan); close(metricChan) }() + for metric := range metricChan { + metric.Write(metricFrame) + for _, label := range metricFrame.Label { + if label.GetName() == targetLabel { + // Initialize data structure + if observedLabels[label.GetValue()] == nil { + newCollectorMap := map[interface{}][]map[string]string{} + newLabelList := []map[string]string{} + observedLabels[label.GetValue()] = newCollectorMap + observedLabels[label.GetValue()][collector] = newLabelList + } + metricLabelMap := metrcisLabelToMap(metricFrame) + newLabels := appendIfLabelIsNotInList(metricLabelMap, observedLabels[label.GetValue()][collector]) + observedLabels[label.GetValue()][collector] = newLabels + count++ + } + } + } + } + return count +} + +func removeMetricsForDeletedResource(observedMetrics map[string]map[interface{}][]map[string]string, observedResources map[string]bool) int { + removedCount := 0 + for m, collectors := range observedMetrics { + // resource still exists + if _, ok := observedResources[m]; ok { + continue + } + logrus.Infof("[metrics-garbage-collector] remove metrics related to %s", m) + // resource doesn't exist, delete all related metrics + for collector, labels := range collectors { + for _, label := range labels { + switch v := collector.(type) { + case *prometheus.CounterVec: + if v.Delete(label) { + removedCount++ + } else { + logrus.Errorf("[metrics-garbage-collector] failed to delete %T metrics related to %s: %v", v, m, label) + } + case *prometheus.GaugeVec: + if v.Delete(label) { + removedCount++ + } else { + logrus.Errorf("[metrics-garbage-collector] failed to delete %T metrics related to %s: %v", v, m, label) + } + default: + logrus.Errorf("[metrics-garbage-collector] saw unknown Metric definition %T", v) + } + } + + } + } + return removedCount +} + +func appendIfLabelIsNotInList(targetLabel map[string]string, labelList []map[string]string) []map[string]string { + found := false + for _, label := range labelList { + if reflect.DeepEqual(targetLabel, label) { + found = true + break + } + } + if !found { + labelList = append(labelList, targetLabel) + } + return labelList +} + +func metrcisLabelToMap(m *dto.Metric) map[string]string { + result := map[string]string{} + for _, label := range m.Label { + result[label.GetName()] = label.GetValue() + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/metrics.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/metrics.go new file mode 100644 index 0000000..db5ed42 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/metrics.go @@ -0,0 +1,267 @@ +package metrics + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "time" + + "github.com/gorilla/mux" + "github.com/prometheus/client_golang/prometheus" + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/pkg/auth/util" + "github.com/rancher/rancher/pkg/clustermanager" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/wrangler/v3/pkg/ticker" + authV1 "k8s.io/api/authorization/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes" +) + +var ( + prometheusMetrics = false + + gcInterval = time.Duration(60 * time.Second) + + clusterOwner = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Subsystem: "cluster_manager", + Name: "cluster_owner", + Help: "Set a cluster owner to determine which Rancher server is running a clusters controllers", + }, + []string{"cluster", "owner"}, + ) +) + +type metricsHandler struct { + clusterManager *clustermanager.Manager + k8sClient kubernetes.Interface + next http.Handler +} + +type ClusterCounts struct { + AppRevisions int `json:"appRevisions"` + CatalogTemplateVersions int `json:"catalogTemplateVersions"` + Projects int `json:"projects"` + ConfigMaps int `json:"configMaps"` + Secrets int `json:"secrets"` + Namespaces int `json:"namespaces"` + Nodes int `json:"nodes"` + RoleBindings int `json:"roleBindings"` + ClusterRoleBindings int `json:"clusterRoleBindings"` +} + +func NewMetricsHandler(scaledContext *config.ScaledContext, clusterManager *clustermanager.Manager, handler http.Handler) http.Handler { + return &metricsHandler{ + clusterManager: clusterManager, + k8sClient: scaledContext.K8sClient, + next: handler, + } +} + +func (h *metricsHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + var reqGroup []string + if g, ok := req.Header["Impersonate-Group"]; ok { + reqGroup = g + } + + review := authV1.SubjectAccessReview{ + Spec: authV1.SubjectAccessReviewSpec{ + User: req.Header.Get("Impersonate-User"), + Groups: reqGroup, + ResourceAttributes: &authV1.ResourceAttributes{ + Verb: "get", + Resource: "ranchermetrics", + Group: "management.cattle.io", + }, + }, + } + + result, err := h.k8sClient.AuthorizationV1().SubjectAccessReviews().Create(req.Context(), &review, metav1.CreateOptions{}) + if err != nil { + util.ReturnHTTPError(rw, req, 500, err.Error()) + return + } + + if !result.Status.Allowed { + util.ReturnHTTPError(rw, req, 401, "Unauthorized") + return + } + + if id := mux.Vars(req)["clusterID"]; id != "" { + h.getClusterObjectCount(id, rw, req) + return + } + + h.next.ServeHTTP(rw, req) +} + +// getClusterObjectCount uses the caches to get the number of items in a cluster and return a json blob with this +// information. The count is based off the cluster itself and where the object lives, not the count as you would +// see through the UI. For example projects only live in the management cluster so the count would only be displayed +// if getting 'local'. The count would show as 0 for a downstream cluster since the CR that backs the project only +// lives in management. +func (h *metricsHandler) getClusterObjectCount(clusterID string, rw http.ResponseWriter, req *http.Request) { + cluster, err := h.clusterManager.UserContext(clusterID) + if err != nil { + var ( + normanError *httperror.APIError + k8sError *k8serrors.StatusError + code int + message string + ) + + if errors.As(err, &normanError) { + code = normanError.Code.Status + message = normanError.Message + } else if errors.As(err, &k8sError) { + code = int(k8sError.ErrStatus.Code) + message = k8sError.Error() + } + util.ReturnHTTPError(rw, req, code, message) + return + } + + var cc ClusterCounts + labelSelector := labels.NewSelector() + + ar, err := cluster.Project.AppRevisions(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.AppRevisions = len(ar) + + // None of these resources are pushed downstream to a user cluster so we can only count them in the management cluster. + if clusterID == "local" { + ctv, err := cluster.Management.Management.CatalogTemplateVersions(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.CatalogTemplateVersions = len(ctv) + + projects, err := cluster.Management.Management.Projects(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.Projects = len(projects) + } + + cf, err := cluster.Core.ConfigMaps(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.ConfigMaps = len(cf) + + s, err := cluster.Core.Secrets(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.Secrets = len(s) + + ns, err := cluster.Core.Namespaces(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.Namespaces = len(ns) + + nodes, err := cluster.Core.Nodes(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.Nodes = len(nodes) + + rb, err := cluster.RBAC.RoleBindings(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.RoleBindings = len(rb) + + crb, err := cluster.RBAC.ClusterRoleBindings(metav1.NamespaceAll).Controller().Lister().List(metav1.NamespaceAll, labelSelector) + if err != nil { + returnK8serror(err, rw, req) + return + } + cc.ClusterRoleBindings = len(crb) + + js, err := json.Marshal(cc) + if err != nil { + util.ReturnHTTPError(rw, req, 500, err.Error()) + return + } + + rw.Header().Set("Content-Type", "application/json") + rw.Write(js) +} + +// returnK8serror attempts to respond using the k8s error and its code/message +func returnK8serror(err error, rw http.ResponseWriter, req *http.Request) { + var k8sError *k8serrors.StatusError + if errors.As(err, &k8sError) { + util.ReturnHTTPError(rw, req, int(k8sError.ErrStatus.Code), k8sError.Error()) + return + } + // Well, it wasn't a k8s error, give it back + util.ReturnHTTPError(rw, req, 500, err.Error()) +} + +func Register(ctx context.Context, scaledContext *config.ScaledContext) { + prometheusMetrics = true + + // Cluster Owner + prometheus.MustRegister(clusterOwner) + + // node and node core metrics + prometheus.MustRegister(numNodes) + prometheus.MustRegister(numCores) + + gc := metricGarbageCollector{ + clusterLister: scaledContext.Management.Clusters("").Controller().Lister(), + nodeLister: scaledContext.Management.Nodes("").Controller().Lister(), + endpointLister: scaledContext.Core.Endpoints(settings.Namespace.Get()).Controller().Lister(), + } + + nm := &nodeMetrics{ + nodeCache: scaledContext.Wrangler.Mgmt.Node().Cache(), + clusterCache: scaledContext.Wrangler.Mgmt.Cluster().Cache(), + } + + go func(ctx context.Context) { + for range ticker.Context(ctx, gcInterval) { + gc.metricGarbageCollection() + } + }(ctx) + + go nm.collect(ctx) +} + +func SetClusterOwner(id, clusterID string) { + if prometheusMetrics { + clusterOwner.With( + prometheus.Labels{ + "cluster": clusterID, + "owner": id, + }).Set(float64(1)) + } +} + +func UnsetClusterOwner(id, clusterID string) { + if prometheusMetrics { + clusterOwner.With( + prometheus.Labels{ + "cluster": clusterID, + "owner": id, + }).Set(float64(0)) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/node.go new file mode 100644 index 0000000..cb729f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/metrics/node.go @@ -0,0 +1,184 @@ +package metrics + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/prometheus/client_golang/prometheus" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + nodeProviderLabel = "provider" + nodeClusterIDLabel = "cluster_id" + nodeIsActiveLabel = "is_active" +) + +var ( + nodeLabels = []string{nodeProviderLabel, nodeClusterIDLabel, nodeIsActiveLabel} + numNodes = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Subsystem: "cluster_manager", + Name: "nodes", + Help: "Number of nodes in rancher managed clusters", + }, nodeLabels, + ) + numCores = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Subsystem: "cluster_manager", + Name: "node_cores", + Help: "Number of node cores in rancher managed clusters", + }, nodeLabels, + ) +) + +const ( + reportInterval = time.Duration(15 * time.Second) + logPrefix = "[prometheus-node-metrics]" +) + +type nodeMetrics struct { + nodeCache mgmtcontrollers.NodeCache + clusterCache mgmtcontrollers.ClusterCache +} + +func (m *nodeMetrics) collect(ctx context.Context) { + for range ticker.Context(ctx, reportInterval) { + logrus.Debugf("%s collecting nodes to report metrics", logPrefix) + + nodes, err := m.nodeCache.List("", labels.Everything()) + if err != nil { + logrus.Errorf("%s couldn't list v3.Nodes: %v", logPrefix, err) + continue + } + + var infos []*nodeInfo + for _, node := range nodes { + info, err := m.getNodeInfo(node) + if err != nil { + logrus.Debugf("%s could not determine node info: %v", logPrefix, err) + continue + } + infos = append(infos, info) + } + + setMetrics(infos) + } + + logrus.Debugf("%s context cancelled, exiting", logPrefix) +} + +type nodeLabelValues struct { + provider string + clusterID string + isActive bool +} + +type nodeInfo struct { + coreCount int + labelValues nodeLabelValues +} + +const ( + unknownProvider = "unknown" +) + +// getNodeInfo uses the v3.Node object and it's corresponding v3.Cluster object to get metric info for a node +func (m *nodeMetrics) getNodeInfo(node *v3.Node) (*nodeInfo, error) { + cluster, err := m.clusterCache.Get(node.ObjClusterName()) + if err != nil { + return nil, fmt.Errorf("error getting cluster %s for node %s, %v", node.ObjClusterName(), node.Name, err) + } + if cluster == nil { + return nil, fmt.Errorf("could not get associated cluster for node: %s/%s", node.Namespace, node.Name) + } + if cluster.DeletionTimestamp != nil { + return nil, fmt.Errorf("associated cluster for node: %s/%s is being deleted", node.Namespace, node.Name) + } + + // a node is considered to be active if it is ready and it belongs to a ready cluster + isActive := v32.ClusterConditionReady.IsTrue(cluster) && v32.NodeConditionReady.IsTrue(node) + + provider := cluster.Status.Provider + if provider == "" { + provider = unknownProvider + } + + return &nodeInfo{ + coreCount: getNodeCoreCount(node), + labelValues: nodeLabelValues{ + clusterID: node.ObjClusterName(), + provider: provider, + isActive: isActive, + }, + }, nil +} + +func getNodeCoreCount(node *v3.Node) int { + nodeCap := node.Status.InternalNodeStatus.Capacity + if nodeCap == nil || nodeCap.Cpu() == nil { + return 0 + } + + cores, ok := nodeCap.Cpu().AsInt64() + if !ok { + return 0 + } + + return int(cores) +} + +// setMetrics uses a slice of nodeInfo to set prometheus metrics for nodes and node cores +func setMetrics(infos []*nodeInfo) { + // count nodes and node cores, bucketed by label values + nodeGauges := make(map[nodeLabelValues]int, 0) + nodeCoreGauges := make(map[nodeLabelValues]int, 0) + for _, info := range infos { + key := info.labelValues + _, ok := nodeGauges[key] + if !ok { + nodeGauges[key] = 1 + } else { + nodeGauges[key]++ + } + + cores, ok := nodeCoreGauges[key] + if !ok { + nodeCoreGauges[key] = info.coreCount + } else { + nodeCoreGauges[key] = cores + info.coreCount + } + } + + // there could be leftover metrics from previous calls to this method, so we need to clear + // the metrics just before we set them for the current node info + numNodes.Reset() + numCores.Reset() + + // use the built nodeGagues map to update prometheus metrics for nodes + for k, v := range nodeGauges { + l := prometheus.Labels{ + nodeProviderLabel: k.provider, + nodeClusterIDLabel: k.clusterID, + nodeIsActiveLabel: strconv.FormatBool(k.isActive), + } + numNodes.With(l).Set(float64(v)) + } + + // use the build nodeCoreGauges map to update prometheus metrics for node cores + for k, v := range nodeCoreGauges { + l := prometheus.Labels{ + nodeProviderLabel: k.provider, + nodeClusterIDLabel: k.clusterID, + nodeIsActiveLabel: strconv.FormatBool(k.isActive), + } + numCores.With(l).Set(float64(v)) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/monitoring/monitoring.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/monitoring/monitoring.go new file mode 100644 index 0000000..06918cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/monitoring/monitoring.go @@ -0,0 +1,95 @@ +package monitoring + +import ( + "fmt" + + "github.com/rancher/norman/types" +) + +type AppLevel string + +const ( + cattleNamespaceName = "cattle-prometheus" +) + +const ( + // The names of App + projectLevelAppName = "project-monitoring" + clusterLevelAlertManagerAppName = "cluster-alerting" + + // The headless service name of Prometheus + alertManagerHeadlessServiceName = "alertmanager-operated" + + //CattlePrometheusRuleLabelKey The label info of PrometheusRule + CattlePrometheusRuleLabelKey = "source" + CattleAlertingPrometheusRuleLabelValue = "rancher-alert" + RancherMonitoringTemplateName = "system-library-rancher-monitoring" +) + +var ( + APIVersion = types.APIVersion{ + Version: "v1", + Group: "monitoring.coreos.com", + Path: "/v3/project", + } +) + +func ClusterAlertManagerInfo() (appName, appTargetNamespace string) { + return clusterLevelAlertManagerAppName, cattleNamespaceName +} + +func ProjectMonitoringInfo(projectName string) (appName, appTargetNamespace string) { + return projectLevelAppName, fmt.Sprintf("%s-%s", cattleNamespaceName, projectName) +} + +func ClusterAlertManagerEndpoint() (headlessServiceName, namespace, port string) { + return alertManagerHeadlessServiceName, cattleNamespaceName, "9093" +} + +/* +OverwriteAppAnswersAndCatalogID Usage +## special key prefix +_tpl- [priority low] -> regex ${value} = ${middle-prefix}#(${root1,root2,...}), then generate ${root*}.${middle-prefix} as prefix-key + +## example + +### input + + key | value + +----------------------------------------------------------------------------------------------- +_tpl-Node_Selector | nodeSelector#(prometheus,grafana,exporter-kube-state) +_tpl-Storage_Class | persistence#(prometheus,grafana) +----------------------------------------------------------------------------------------------- +prometheus.retention | 360h +exporter-node.ports.metrics.port | 9100 +grafana.persistence.enabled | false +nodeSelector.region | region-a +nodeSelector.zone | zone-b +persistence.enabled | true +persistence.storageClass | default +persistence.accessMode | ReadWriteOnce +persistence.size | 50Gi + +### output + + key | value + +----------------------------------------------------------------------------------------------- +prometheus.retention | 360h +exporter-node.ports.metrics.port | 9100 +prometheus.nodeSelector.region | region-a +prometheus.nodeSelector.zone | zone-b +grafana.nodeSelector.region | region-a +grafana.nodeSelector.zone | zone-b +exporter-kube-state.nodeSelector.region | region-a +exporter-kube-state.nodeSelector.zone | zone-b +prometheus.persistence.enabled | true +prometheus.persistence.storageClass | default +prometheus.persistence.accessMode | ReadWriteOnce +prometheus.persistence.size | 50Gi +grafana.persistence.enabled | false // can't overwrite by low priority +grafana.persistence.storageClass | default +grafana.persistence.accessMode | ReadWriteOnce +grafana.persistence.size | 50Gi +*/ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/app.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/app.go new file mode 100644 index 0000000..00cb9a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/app.go @@ -0,0 +1,232 @@ +package multiclustermanager + +import ( + "context" + "net/http" + "os" + "sync" + "time" + + "github.com/rancher/rancher/pkg/agent/clean/adunmigration" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/rancher/rancher/pkg/auth/providerrefresh" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/catalog/manager" + "github.com/rancher/rancher/pkg/clustermanager" + managementController "github.com/rancher/rancher/pkg/controllers/management" + "github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher" + managementcrds "github.com/rancher/rancher/pkg/crds/management" + "github.com/rancher/rancher/pkg/cron" + managementdata "github.com/rancher/rancher/pkg/data/management" + "github.com/rancher/rancher/pkg/dialer" + "github.com/rancher/rancher/pkg/jailer" + "github.com/rancher/rancher/pkg/metrics" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/systemtokens" + "github.com/rancher/rancher/pkg/telemetry" + "github.com/rancher/rancher/pkg/tunnelserver/mcmauthorizer" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" +) + +type Options struct { + LocalClusterEnabled bool + RemoveLocalCluster bool + Embedded bool + HTTPSListenPort int + Debug bool + Trace bool +} + +type mcm struct { + ScaledContext *config.ScaledContext + clusterManager *clustermanager.Manager + router func(http.Handler) http.Handler + wranglerContext *wrangler.Context + localClusterEnabled bool + removeLocalCluster bool + embedded bool + httpsListenPort int + + startedChan chan struct{} + startLock sync.Mutex +} + +func BuildScaledContext(ctx context.Context, wranglerContext *wrangler.Context, cfg *Options) (*config.ScaledContext, + *clustermanager.Manager, *mcmauthorizer.Authorizer, error) { + scaledContext, err := config.NewScaledContext(*wranglerContext.RESTConfig, &config.ScaleContextOptions{ + ControllerFactory: wranglerContext.ControllerFactory, + }) + if err != nil { + return nil, nil, nil, err + } + + scaledContext.Wrangler = wranglerContext + + scaledContext.CatalogManager = manager.New(scaledContext.Management, scaledContext.Project, scaledContext.Core) + + if err := managementcrds.Create(ctx, wranglerContext.RESTConfig); err != nil { + return nil, nil, nil, err + } + + dialerFactory, err := dialer.NewFactory(scaledContext, wranglerContext) + if err != nil { + return nil, nil, nil, err + } + scaledContext.Dialer = dialerFactory + + userManager, err := common.NewUserManager(scaledContext) + if err != nil { + return nil, nil, nil, err + } + + scaledContext.UserManager = userManager + scaledContext.RunContext = ctx + + systemTokens := systemtokens.NewSystemTokensFromScale(scaledContext) + scaledContext.SystemTokens = systemTokens + + manager := clustermanager.NewManager(cfg.HTTPSListenPort, scaledContext, wranglerContext.ASL) + + scaledContext.AccessControl = manager + scaledContext.ClientGetter = manager + + authorizer := mcmauthorizer.NewAuthorizer(scaledContext) + wranglerContext.TunnelAuthorizer.Add(authorizer.AuthorizeTunnel) + scaledContext.PeerManager = wranglerContext.PeerManager + + return scaledContext, manager, authorizer, nil +} + +func newMCM(ctx context.Context, wranglerContext *wrangler.Context, cfg *Options) (*mcm, error) { + scaledContext, clusterManager, tunnelAuthorizer, err := BuildScaledContext(ctx, wranglerContext, cfg) + if err != nil { + return nil, err + } + + router, err := router(ctx, cfg.LocalClusterEnabled, tunnelAuthorizer, scaledContext, clusterManager) + if err != nil { + return nil, err + } + + if os.Getenv("CATTLE_PROMETHEUS_METRICS") == "true" { + metrics.Register(ctx, scaledContext) + } + + mcm := &mcm{ + router: router, + ScaledContext: scaledContext, + clusterManager: clusterManager, + wranglerContext: wranglerContext, + localClusterEnabled: cfg.LocalClusterEnabled, + removeLocalCluster: cfg.RemoveLocalCluster, + embedded: cfg.Embedded, + httpsListenPort: cfg.HTTPSListenPort, + startedChan: make(chan struct{}), + } + + go func() { + <-ctx.Done() + mcm.started(ctx) + }() + + return mcm, nil +} + +func (m *mcm) started(ctx context.Context) { + m.startLock.Lock() + defer m.startLock.Unlock() + select { + case <-m.startedChan: + default: + close(m.startedChan) + } +} + +func (m *mcm) Wait(ctx context.Context) { + select { + case <-m.startedChan: + for { + if _, err := m.wranglerContext.Core.Namespace().Get(namespace.GlobalNamespace, metav1.GetOptions{}); err == nil { + return + } + logrus.Infof("Waiting for initial data to be populated") + time.Sleep(2 * time.Second) + } + case <-ctx.Done(): + } +} + +func (m *mcm) NormanSchemas() *types.Schemas { + <-m.startedChan + return m.ScaledContext.Schemas +} + +func (m *mcm) Middleware(next http.Handler) http.Handler { + return m.router(next) +} + +func (m *mcm) Start(ctx context.Context) error { + var ( + management *config.ManagementContext + ) + + if dm := os.Getenv("CATTLE_DEV_MODE"); dm == "" { + if err := jailer.CreateJail("driver-jail"); err != nil { + return err + } + + if err := cron.StartJailSyncCron(m.ScaledContext); err != nil { + return err + } + } + + m.wranglerContext.OnLeader(func(ctx context.Context) error { + err := m.wranglerContext.StartWithTransaction(ctx, func(ctx context.Context) error { + var ( + err error + ) + + management, err = m.ScaledContext.NewManagementContext() + if err != nil { + return errors.Wrap(err, "failed to create management context") + } + + if err := managementdata.Add(ctx, m.wranglerContext, management); err != nil { + return errors.Wrap(err, "failed to add management data") + } + + managementController.Register(ctx, management, m.ScaledContext.ClientGetter.(*clustermanager.Manager), m.wranglerContext) + if err := managementController.RegisterWrangler(ctx, m.wranglerContext, management, m.ScaledContext.ClientGetter.(*clustermanager.Manager)); err != nil { + return errors.Wrap(err, "failed to register wrangler controllers") + } + return nil + }) + if err != nil { + return err + } + + if err := telemetry.Start(ctx, m.httpsListenPort, m.ScaledContext); err != nil { + return errors.Wrap(err, "failed to telemetry") + } + + go adunmigration.UnmigrateAdGUIDUsersOnce(m.ScaledContext) + tokens.StartPurgeDaemon(ctx, management) + providerrefresh.StartRefreshDaemon(ctx, m.ScaledContext, management) + managementdata.CleanupOrphanedSystemUsers(ctx, management) + clusterupstreamrefresher.MigrateEksRefreshCronSetting(m.wranglerContext) + go managementdata.CleanupDuplicateBindings(m.ScaledContext, m.wranglerContext) + go managementdata.CleanupOrphanBindings(m.ScaledContext, m.wranglerContext) + + logrus.Infof("Rancher startup complete") + return nil + }) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/deferred.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/deferred.go new file mode 100644 index 0000000..dd654e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/deferred.go @@ -0,0 +1,141 @@ +package multiclustermanager + +import ( + "context" + "fmt" + "net" + "net/http" + "sync" + "time" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/wrangler" + "k8s.io/client-go/kubernetes" +) + +type DeferredServer struct { + sync.RWMutex + + wrangler *wrangler.Context + opts *Options + mcm *mcm +} + +func NewDeferredServer(wrangler *wrangler.Context, opts *Options) *DeferredServer { + return &DeferredServer{ + wrangler: wrangler, + opts: opts, + } +} + +func (s *DeferredServer) Wait(ctx context.Context) { + if !features.MCM.Enabled() { + return + } + for { + s.Lock() + if s.mcm == nil { + s.Unlock() + select { + case <-time.After(500 * time.Millisecond): + continue + case <-ctx.Done(): + return + } + } + s.Unlock() + s.mcm.Wait(ctx) + break + } +} + +func (s *DeferredServer) NormanSchemas() *types.Schemas { + mcm := s.getMCM() + if mcm == nil { + return nil + } + return mcm.NormanSchemas() +} + +func (s *DeferredServer) Start(ctx context.Context) error { + s.Lock() + defer s.Unlock() + + if s.mcm != nil { + return nil + } + + var ( + mcm *mcm + err error + ) + + err = s.wrangler.StartWithTransaction(ctx, func(ctx context.Context) error { + mcm, err = newMCM(ctx, s.wrangler, s.opts) + if err != nil { + return err + } + + return mcm.Start(ctx) + }) + if mcm != nil { + // always start, even on error + mcm.started(ctx) + } + if err != nil { + return err + } + + s.mcm = mcm + go func() { + <-ctx.Done() + s.Lock() + defer s.Unlock() + s.mcm = nil + }() + return nil +} + +func (s *DeferredServer) getMCM() *mcm { + s.RLock() + defer s.RUnlock() + return s.mcm +} + +func (s *DeferredServer) Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + mcm := s.getMCM() + if mcm == nil { + next.ServeHTTP(rw, req) + return + } + mcm.Middleware(next).ServeHTTP(rw, req) + }) +} + +func (s *DeferredServer) ClusterDialer(clusterID string) func(ctx context.Context, network, address string) (net.Conn, error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + mcm := s.getMCM() + if mcm == nil { + return nil, fmt.Errorf("failed to find cluster %s", clusterID) + } + dialer, err := mcm.ScaledContext.Dialer.ClusterDialer(clusterID, true) + if err != nil { + return nil, err + } + return dialer(ctx, network, address) + } +} + +func (s *DeferredServer) K8sClient(clusterName string) (kubernetes.Interface, error) { + mcm := s.getMCM() + if mcm == nil { + return nil, nil + } + clusterContext, err := mcm.clusterManager.UserContextNoControllers(clusterName) + if err != nil { + return nil, err + } + return clusterContext.K8sClient, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/routes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/routes.go new file mode 100644 index 0000000..4b00196 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/routes.go @@ -0,0 +1,150 @@ +package multiclustermanager + +import ( + "context" + "net/http" + + "github.com/gorilla/mux" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/rancher/apiserver/pkg/parse" + "github.com/rancher/rancher/pkg/api/norman" + "github.com/rancher/rancher/pkg/api/norman/customization/aks" + "github.com/rancher/rancher/pkg/api/norman/customization/clusterregistrationtokens" + "github.com/rancher/rancher/pkg/api/norman/customization/gke" + "github.com/rancher/rancher/pkg/api/norman/customization/oci" + "github.com/rancher/rancher/pkg/api/norman/customization/vsphere" + managementapi "github.com/rancher/rancher/pkg/api/norman/server" + "github.com/rancher/rancher/pkg/api/steve/supportconfigs" + "github.com/rancher/rancher/pkg/auth/providers/publicapi" + "github.com/rancher/rancher/pkg/auth/providers/saml" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/auth/requests/sar" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/auth/webhook" + "github.com/rancher/rancher/pkg/channelserver" + "github.com/rancher/rancher/pkg/clustermanager" + rancherdialer "github.com/rancher/rancher/pkg/dialer" + "github.com/rancher/rancher/pkg/httpproxy" + k8sProxyPkg "github.com/rancher/rancher/pkg/k8sproxy" + "github.com/rancher/rancher/pkg/metrics" + "github.com/rancher/rancher/pkg/multiclustermanager/whitelist" + "github.com/rancher/rancher/pkg/rbac" + "github.com/rancher/rancher/pkg/rkenodeconfigserver" + "github.com/rancher/rancher/pkg/telemetry" + "github.com/rancher/rancher/pkg/tunnelserver/mcmauthorizer" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/version" + "github.com/rancher/steve/pkg/auth" +) + +func router(ctx context.Context, localClusterEnabled bool, tunnelAuthorizer *mcmauthorizer.Authorizer, scaledContext *config.ScaledContext, clusterManager *clustermanager.Manager) (func(http.Handler) http.Handler, error) { + var ( + k8sProxy = k8sProxyPkg.New(scaledContext, scaledContext.Dialer, clusterManager) + connectHandler = scaledContext.Dialer.(*rancherdialer.Factory).TunnelServer + connectConfigHandler = rkenodeconfigserver.Handler(tunnelAuthorizer, scaledContext) + clusterImport = clusterregistrationtokens.ClusterImport{Clusters: scaledContext.Management.Clusters("")} + ) + + tokenAPI, err := tokens.NewAPIHandler(ctx, scaledContext, norman.ConfigureAPIUI) + if err != nil { + return nil, err + } + + publicAPI, err := publicapi.NewHandler(ctx, scaledContext, norman.ConfigureAPIUI) + if err != nil { + return nil, err + } + + managementAPI, err := managementapi.New(ctx, scaledContext, clusterManager, k8sProxy, localClusterEnabled) + if err != nil { + return nil, err + } + + metaProxy, err := httpproxy.NewProxy("/proxy/", whitelist.Proxy.Get, scaledContext) + if err != nil { + return nil, err + } + + metricsHandler := metrics.NewMetricsHandler(scaledContext, clusterManager, promhttp.Handler()) + + channelserver := channelserver.NewHandler(ctx) + + supportConfigGenerator := supportconfigs.NewHandler(scaledContext) + // Unauthenticated routes + unauthed := mux.NewRouter() + unauthed.UseEncodedPath() + + unauthed.Path("/").MatcherFunc(parse.MatchNotBrowser).Handler(managementAPI) + unauthed.Handle("/v3/connect/config", connectConfigHandler) + unauthed.Handle("/v3/connect", connectHandler) + unauthed.Handle("/v3/connect/register", connectHandler) + unauthed.Handle("/v3/import/{token}_{clusterId}.yaml", http.HandlerFunc(clusterImport.ClusterImportHandler)) + unauthed.Handle("/v3/settings/cacerts", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/first-login", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/ui-banners", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/ui-issues", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/ui-pl", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/ui-brand", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/v3/settings/ui-default-landing", managementAPI).MatcherFunc(onlyGet) + unauthed.Handle("/rancherversion", version.NewVersionHandler()) + unauthed.PathPrefix("/v1-{prefix}-release/channel").Handler(channelserver) + unauthed.PathPrefix("/v1-{prefix}-release/release").Handler(channelserver) + unauthed.PathPrefix("/v1-saml").Handler(saml.AuthHandler()) + unauthed.PathPrefix("/v3-public").Handler(publicAPI) + + // Authenticated routes + impersonatingAuth := auth.ToMiddleware(requests.NewImpersonatingAuth(sar.NewSubjectAccessReview(clusterManager))) + saAuth := auth.ToMiddleware(requests.NewServiceAccountAuth(scaledContext, clustermanager.ToRESTConfig)) + accessControlHandler := rbac.NewAccessControlHandler() + + saauthed := mux.NewRouter() + saauthed.UseEncodedPath() + saauthed.PathPrefix("/k8s/clusters/{clusterID}").Handler(k8sProxy) + saauthed.Use(mux.MiddlewareFunc(saAuth.Chain(impersonatingAuth))) + saauthed.Use(mux.MiddlewareFunc(accessControlHandler)) + saauthed.Use(requests.NewAuthenticatedFilter) + + authed := mux.NewRouter() + authed.UseEncodedPath() + + authed.Use(mux.MiddlewareFunc(impersonatingAuth)) + authed.Use(mux.MiddlewareFunc(accessControlHandler)) + authed.Use(requests.NewAuthenticatedFilter) + + authed.Path("/meta/{resource:aks.+}").Handler(aks.NewAKSHandler(scaledContext)) + authed.Path("/meta/{resource:gke.+}").Handler(gke.NewGKEHandler(scaledContext)) + authed.Path("/meta/oci/{resource}").Handler(oci.NewOCIHandler(scaledContext)) + authed.Path("/meta/vsphere/{field}").Handler(vsphere.NewVsphereHandler(scaledContext)) + authed.Path("/v3/tokenreview").Methods(http.MethodPost).Handler(&webhook.TokenReviewer{}) + authed.Path("/metrics/{clusterID}").Handler(metricsHandler) + authed.Path(supportconfigs.Endpoint).Handler(&supportConfigGenerator) + authed.PathPrefix("/meta/proxy").Handler(metaProxy) + authed.PathPrefix("/v1-telemetry").Handler(telemetry.NewProxy()) + authed.PathPrefix("/v3/identit").Handler(tokenAPI) + authed.PathPrefix("/v3/token").Handler(tokenAPI) + authed.PathPrefix("/v3").Handler(managementAPI) + + // Metrics authenticated route + metricsAuthed := mux.NewRouter() + metricsAuthed.UseEncodedPath() + tokenReviewAuth := auth.ToMiddleware(requests.NewTokenReviewAuth(scaledContext.K8sClient.AuthenticationV1())) + metricsAuthed.Use(mux.MiddlewareFunc(tokenReviewAuth.Chain(impersonatingAuth))) + metricsAuthed.Use(mux.MiddlewareFunc(accessControlHandler)) + metricsAuthed.Use(requests.NewAuthenticatedFilter) + + metricsAuthed.Path("/metrics").Handler(metricsHandler) + + unauthed.NotFoundHandler = saauthed + saauthed.NotFoundHandler = authed + authed.NotFoundHandler = metricsAuthed + + return func(next http.Handler) http.Handler { + metricsAuthed.NotFoundHandler = next + return unauthed + }, nil +} + +// onlyGet will match only GET but will not return a 405 like route.Methods and instead just not match +func onlyGet(req *http.Request, m *mux.RouteMatch) bool { + return req.Method == http.MethodGet +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/whitelist/whitelist.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/whitelist/whitelist.go new file mode 100644 index 0000000..d06f88c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/multiclustermanager/whitelist/whitelist.go @@ -0,0 +1,43 @@ +package whitelist + +import ( + "strings" + "sync" + + "github.com/rancher/rancher/pkg/settings" +) + +var ( + Proxy = ProxyAcceptList{ + RWMutex: sync.RWMutex{}, + accept: map[string]bool{}, + } +) + +type ProxyAcceptList struct { + sync.RWMutex + accept map[string]bool +} + +func (p *ProxyAcceptList) Get() []string { + p.RLock() + defer p.RUnlock() + v := settings.WhitelistDomain.Get() + r := strings.Split(v, ",") + for k := range p.accept { + r = append(r, k) + } + return r +} + +func (p *ProxyAcceptList) Add(key string) { + p.Lock() + defer p.Unlock() + p.accept[key] = true +} + +func (p *ProxyAcceptList) Rm(key string) { + p.Lock() + defer p.Unlock() + delete(p.accept, key) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace.go new file mode 100644 index 0000000..263b0ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace.go @@ -0,0 +1,18 @@ +package namespace + +import v1 "k8s.io/api/core/v1" + +var projectIDAnnotation = "field.cattle.io/projectId" + +func NsByProjectID(obj interface{}) ([]string, error) { + ns, ok := obj.(*v1.Namespace) + if !ok { + return []string{}, nil + } + + if id, ok := ns.Annotations[projectIDAnnotation]; ok { + return []string{id}, nil + } + + return []string{}, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace_utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace_utils.go new file mode 100644 index 0000000..b3c947e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/namespace/namespace_utils.go @@ -0,0 +1,121 @@ +package namespace + +import ( + "encoding/json" + "time" + + v1 "k8s.io/api/core/v1" +) + +const ( + statusAnn = "cattle.io/status" + System = "cattle-system" + UIPluginNamespace = "cattle-ui-plugin-system" + GlobalNamespace = "cattle-global-data" + NodeTemplateGlobalNamespace = "cattle-global-nt" + ProvisioningCAPINamespace = "cattle-provisioning-capi-system" +) + +func SetNamespaceCondition(namespace *v1.Namespace, d time.Duration, conditionType string, conditionStatus bool, message string) error { + annotations := namespace.ObjectMeta.Annotations + if annotations == nil { + annotations = map[string]string{} + } + ann := annotations[statusAnn] + conditionStatusStr := "False" + if conditionStatus { + conditionStatusStr = "True" + } + bAnn, err := GenerateConditionAnnotation(ann, d, conditionType, conditionStatusStr, message) + if err != nil { + return err + } + annotations[statusAnn] = bAnn + + namespace.ObjectMeta.Annotations = annotations + + return nil +} + +func GenerateConditionAnnotation(ann string, d time.Duration, conditionType string, conditionStatus string, message string) (string, error) { + status := &status{} + if ann != "" { + err := json.Unmarshal([]byte(ann), status) + if err != nil { + return "", err + } + } + if status.Conditions == nil { + status.Conditions = []condition{} + } + + var idx int + found := false + for i, c := range status.Conditions { + if c.Type == conditionType { + idx = i + found = true + break + } + } + + conditionMessage := "" + if conditionStatus != "True" { + conditionMessage = message + } + + cond := condition{ + Type: conditionType, + Status: conditionStatus, + Message: conditionMessage, + LastUpdateTime: time.Now().Add(d).Format(time.RFC3339), + } + + if found { + status.Conditions[idx] = cond + } else { + status.Conditions = append(status.Conditions, cond) + } + + bAnn, err := json.Marshal(status) + if err != nil { + return "", err + } + return string(bAnn), nil +} + +func IsNamespaceConditionSet(namespace *v1.Namespace, conditionType string, conditionStatus bool) (bool, error) { + if namespace.ObjectMeta.Annotations == nil { + return false, nil + } + ann := namespace.ObjectMeta.Annotations[statusAnn] + if ann == "" { + return false, nil + } + status := &status{} + err := json.Unmarshal([]byte(ann), status) + if err != nil { + return false, err + } + conditionStatusStr := "False" + if conditionStatus { + conditionStatusStr = "True" + } + for _, c := range status.Conditions { + if c.Type == conditionType && c.Status == conditionStatusStr { + return true, nil + } + } + return false, nil +} + +type status struct { + Conditions []condition +} + +type condition struct { + Type string + Status string + Message string + LastUpdateTime string +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node.go new file mode 100644 index 0000000..d9cc025 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node.go @@ -0,0 +1,286 @@ +package node + +import ( + "fmt" + + "github.com/rancher/norman/types/convert" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + rkeservices "github.com/rancher/rke/services" + rketypes "github.com/rancher/rke/types" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + externalAddressAnnotation = "rke.cattle.io/external-ip" + LabelNodeName = "management.cattle.io/nodename" + nodeStatusLabel = "cattle.rancher.io/node-status" +) + +func GetNodeName(machine *v3.Node) string { + if machine.Status.NodeName != "" { + return machine.Status.NodeName + } + // to handle the case when machine was provisioned first + if machine.Status.NodeConfig != nil { + if machine.Status.NodeConfig.HostnameOverride != "" { + return machine.Status.NodeConfig.HostnameOverride + } + } + return "" +} + +func IgnoreNode(name string, labels map[string]string) bool { + ignoreName := settings.IgnoreNodeName.Get() + if name == ignoreName { + return true + } + + if labels == nil { + return false + } + value, ok := labels[nodeStatusLabel] + return ok && value == "ignore" +} + +// IsNodeForNode returns true if node names or addresses are equal +func IsNodeForNode(node *corev1.Node, machine *v3.Node) bool { + nodeName := GetNodeName(machine) + if nodeName == node.Name { + return true + } + + machineAddress := "" + if machine.Status.NodeConfig != nil { + if machine.Status.NodeConfig.InternalAddress == "" { + // rke defaults internal address to address + machineAddress = machine.Status.NodeConfig.Address + } else { + machineAddress = machine.Status.NodeConfig.InternalAddress + } + } + + if machineAddress == "" { + return false + } + + if machineAddress == GetNodeInternalAddress(node) { + return true + } + + return false +} + +func GetNodeInternalAddress(node *corev1.Node) string { + for _, address := range node.Status.Addresses { + if address.Type == corev1.NodeInternalIP { + return address.Address + } + } + return "" +} + +func GetEndpointV1NodeIP(node *v1.Node) string { + externalIP := "" + internalIP := "" + for _, ip := range node.Status.Addresses { + if ip.Type == "ExternalIP" && ip.Address != "" { + externalIP = ip.Address + break + } else if ip.Type == "InternalIP" && ip.Address != "" { + internalIP = ip.Address + } + } + if externalIP != "" { + return externalIP + } + if node.Annotations != nil { + externalIP = node.Annotations[externalAddressAnnotation] + if externalIP != "" { + return externalIP + } + } + return internalIP +} + +func GetEndpointNodeIP(node *v3.Node) string { + externalIP := "" + internalIP := "" + for _, ip := range node.Status.InternalNodeStatus.Addresses { + if ip.Type == "ExternalIP" && ip.Address != "" { + externalIP = ip.Address + break + } else if ip.Type == "InternalIP" && ip.Address != "" { + internalIP = ip.Address + } + } + if externalIP != "" { + return externalIP + } + if node.Annotations != nil { + externalIP = node.Status.NodeAnnotations[externalAddressAnnotation] + if externalIP != "" { + return externalIP + } + } + return internalIP +} + +func GetNodeByNodeName(nodes []*v3.Node, nodeName string) *v3.Node { + for _, m := range nodes { + if GetNodeName(m) == nodeName { + return m + } + } + return nil +} + +func GetNodeForMachine(machine *v3.Node, nodeLister v1.NodeLister) (*corev1.Node, error) { + nodeName := "" + if machine.Labels != nil { + nodeName = machine.Labels[LabelNodeName] + } + var nodes []*corev1.Node + var err error + if nodeName != "" { + var node *corev1.Node + node, err = nodeLister.Get("", nodeName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + + } + if node != nil { + nodes = append(nodes, node) + } + } + + if len(nodes) == 0 { + nodes, err = nodeLister.List("", labels.NewSelector()) + if err != nil { + return nil, err + } + } + + for _, n := range nodes { + if IsNodeForNode(n, machine) { + return n, nil + } + } + + return nil, nil +} + +func GetMachineForNode(node *corev1.Node, clusterNamespace string, machineLister v3.NodeLister) (*v3.Node, error) { + labelsSearchSet := labels.Set{LabelNodeName: node.Name} + machines, err := machineLister.List(clusterNamespace, labels.SelectorFromSet(labelsSearchSet)) + if err != nil { + return nil, err + } + if len(machines) == 0 { + machines, err = machineLister.List(clusterNamespace, labels.NewSelector()) + if err != nil { + return nil, err + } + } + for _, machine := range machines { + if IsNodeForNode(node, machine) { + return machine, nil + } + } + return nil, nil +} + +func IsNodeReady(node *v1.Node) bool { + for _, cond := range node.Status.Conditions { + if cond.Type == corev1.NodeReady { + return cond.Status == corev1.ConditionTrue + } + } + return false +} + +func IsMachineReady(machine *v3.Node) bool { + for _, cond := range machine.Status.InternalNodeStatus.Conditions { + if cond.Type == corev1.NodeReady { + return cond.Status == corev1.ConditionTrue + } + } + return false +} + +func DrainBeforeDelete(node *v3.Node, cluster *v3.Cluster, nodePool *v3.NodePool) bool { + if node.Status.NodeConfig == nil { + return false + } + // never drain an etcd node, you will regret it + if IsEtcd(node.Status.NodeConfig) { + return false + } + + // vsphere nodes with cloud providers need to be drained to unmount vmdk files as vsphere deletes them automatically + if nil != cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider { + return true + } + + if nodePool != nil && nodePool.Spec.DrainBeforeDelete { + return true + } + + return false +} + +func IsEtcd(node *rketypes.RKEConfigNode) bool { + roles := node.Role + for _, role := range roles { + if role == rkeservices.ETCDRole { + return true + } + } + return false +} + +func IsControlPlane(node *rketypes.RKEConfigNode) bool { + for _, role := range node.Role { + if role == rkeservices.ControlRole { + return true + } + } + return false +} + +func IsWorker(node *rketypes.RKEConfigNode) bool { + roles := node.Role + for _, role := range roles { + if role == rkeservices.WorkerRole { + return true + } + } + return false +} + +func IsNonWorker(node *rketypes.RKEConfigNode) bool { + return IsControlPlane(node) || IsEtcd(node) +} + +func GetDrainFlags(node *v3.Node) []string { + input := node.Spec.NodeDrainInput + if input == nil { + return []string{} + } + + var ignoreDaemonSets bool + if input.IgnoreDaemonSets == nil { + ignoreDaemonSets = true + } else { + ignoreDaemonSets = *input.IgnoreDaemonSets + } + return []string{ + fmt.Sprintf("--delete-local-data=%v", input.DeleteLocalData), + fmt.Sprintf("--force=%v", input.Force), + fmt.Sprintf("--grace-period=%v", input.GracePeriod), + fmt.Sprintf("--ignore-daemonsets=%v", ignoreDaemonSets), + fmt.Sprintf("--timeout=%s", convert.ToString(input.Timeout)+"s")} +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node_test.go new file mode 100644 index 0000000..a15075d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/node/node_test.go @@ -0,0 +1,114 @@ +package node + +import ( + "testing" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestIsNodeForNode(t *testing.T) { + + tests := []struct { + name string + node *corev1.Node + machine *v3.Node + want bool + }{ + { + name: "no node config", + node: &corev1.Node{ + ObjectMeta: v1.ObjectMeta{ + Name: "not nil", + }, + Spec: corev1.NodeSpec{}, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + { + Type: corev1.NodeInternalIP, + Address: "1.2.3.4.5", + }, + }, + }, + }, + machine: &v3.Node{ + Status: v32.NodeStatus{ + NodeConfig: &rketypes.RKEConfigNode{}, + NodeName: "", + }, + }, + want: false, + }, + { + name: "Node == Machine (internal address)", + node: &corev1.Node{ + ObjectMeta: v1.ObjectMeta{ + Name: "Node1", + }, + Spec: corev1.NodeSpec{}, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + { + Type: corev1.NodeInternalIP, + Address: "1.2.3.4.5", + }, + }, + }, + }, + machine: &v3.Node{ + Namespaced: types.Namespaced{}, + Spec: v32.NodeSpec{}, + Status: v32.NodeStatus{ + NodeName: "NotNode1", + Conditions: nil, + NodeConfig: &rketypes.RKEConfigNode{ + Address: "1.2.3.4.5", + Port: "", + InternalAddress: "", + }, + }, + }, + want: true, + }, + { + name: "Node == Machine (internal address != nil) ", + node: &corev1.Node{ + ObjectMeta: v1.ObjectMeta{ + Name: "Node1", + }, + Status: corev1.NodeStatus{ + Addresses: []corev1.NodeAddress{ + { + Type: corev1.NodeInternalIP, + Address: "1.2.3.4.5", + }, + }, + }, + }, + machine: &v3.Node{ + Namespaced: types.Namespaced{}, + Spec: v32.NodeSpec{}, + Status: v32.NodeStatus{ + NodeName: "NotNode1", + NodeConfig: &rketypes.RKEConfigNode{ + Address: "1.2.3.4.5", + Port: "", + InternalAddress: "", + }, + }, + }, + want: true, + }, + } + for _, tt := range tests { + + result := IsNodeForNode(tt.node, tt.machine) + assert.Equal(t, tt.want, result) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/archive.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/archive.go new file mode 100644 index 0000000..829f1dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/archive.go @@ -0,0 +1,251 @@ +package nodeconfig + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + "crypto/tls" + "crypto/x509" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +type TLSConfig struct { + Certificate, CA, Key []byte + Address string +} + +func (t *TLSConfig) ToConfig() (*tls.Config, error) { + cert, err := tls.X509KeyPair(t.Certificate, t.Key) + if err != nil { + return nil, errors.Wrap(err, "failed to load cert") + } + + // Verify client certificates against a CA? + certPool := x509.NewCertPool() + certPool.AppendCertsFromPEM(t.CA) + + return &tls.Config{ + NextProtos: []string{"http/1.1"}, + MinVersion: tls.VersionTLS10, + Certificates: []tls.Certificate{cert}, + RootCAs: certPool, + }, nil +} + +func ExtractConfigJSON(extractedConfig string) (map[string]interface{}, error) { + result := map[string]interface{}{} + + configBytes, err := base64.StdEncoding.DecodeString(extractedConfig) + if err != nil { + return nil, fmt.Errorf("error reinitializing config (base64.DecodeString): %v", err) + } + + gzipReader, err := gzip.NewReader(bytes.NewReader(configBytes)) + if err != nil { + return nil, err + } + tarReader := tar.NewReader(gzipReader) + + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + return result, nil + } + return nil, fmt.Errorf("error reinitializing config (tarRead.Next): %v", err) + } + + info := header.FileInfo() + if info.IsDir() { + continue + } + + filename := header.Name + if strings.Contains(filename, "/machines/") && strings.HasSuffix(filename, "/config.json") { + buf := &bytes.Buffer{} + _, err = io.Copy(buf, tarReader) + if err != nil { + return nil, fmt.Errorf("error reinitializing config (Copy): %v", err) + } + + if err := json.Unmarshal(buf.Bytes(), &result); err != nil { + return nil, errors.Wrap(err, "failed to read config.json") + } + } + } +} + +func extractTLS(extractedConfig string) (*TLSConfig, error) { + result := &TLSConfig{} + + configBytes, err := base64.StdEncoding.DecodeString(extractedConfig) + if err != nil { + return nil, fmt.Errorf("error reinitializing config (base64.DecodeString): %v", err) + } + + gzipReader, err := gzip.NewReader(bytes.NewReader(configBytes)) + if err != nil { + return nil, err + } + tarReader := tar.NewReader(gzipReader) + + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + return result, nil + } + return nil, fmt.Errorf("error reinitializing config (tarRead.Next): %v", err) + } + + info := header.FileInfo() + if info.IsDir() { + continue + } + + filename := header.Name + buf := &bytes.Buffer{} + + _, err = io.Copy(buf, tarReader) + if err != nil { + return nil, fmt.Errorf("error reinitializing config (Copy): %v", err) + } + + if strings.Contains(filename, "/machines/") { + if strings.HasSuffix(filename, "/key.pem") { + result.Key = buf.Bytes() + } else if strings.HasSuffix(filename, "/cert.pem") { + result.Certificate = buf.Bytes() + } else if strings.HasSuffix(filename, "/ca.pem") { + result.CA = buf.Bytes() + } else if strings.HasSuffix(filename, "/config.json") { + data := map[string]interface{}{} + if err := json.Unmarshal(buf.Bytes(), &data); err != nil { + return nil, errors.Wrap(err, "failed to read config.json") + } + data, _ = data["Driver"].(map[string]interface{}) + result.Address, _ = data["IPAddress"].(string) + if result.Address != "" { + result.Address += ":2376" + } + } + } + } +} + +func extractConfig(baseDir, extractedConfig string) error { + baseDir = filepath.Dir(baseDir) + configBytes, err := base64.StdEncoding.DecodeString(extractedConfig) + if err != nil { + return fmt.Errorf("error reinitializing config (base64.DecodeString). Config Dir: %v. Error: %v", baseDir, err) + } + + gzipReader, err := gzip.NewReader(bytes.NewReader(configBytes)) + if err != nil { + return err + } + tarReader := tar.NewReader(gzipReader) + + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + return nil + } + return fmt.Errorf("error reinitializing config (tarRead.Next). Config Dir: %v. Error: %v", baseDir, err) + } + + filename := header.Name + filePath := filepath.Join(baseDir, filename) + logrus.Debugf("Extracting %v", filePath) + + info := header.FileInfo() + if info.IsDir() { + err = os.MkdirAll(filePath, os.FileMode(header.Mode)) + if err != nil { + return fmt.Errorf("error reinitializing config (Mkdirall). Config Dir: %v. Dir: %v. Error: %v", baseDir, info.Name(), err) + } + continue + } + + file, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode()) + if err != nil { + return fmt.Errorf("error reinitializing config (OpenFile). Config Dir: %v. File: %v. Error: %v", baseDir, info.Name(), err) + } + + _, err = io.Copy(file, tarReader) + file.Close() + if err != nil { + return fmt.Errorf("error reinitializing config (Copy). Config Dir: %v. File: %v. Error: %v", baseDir, info.Name(), err) + } + } +} + +func compressConfig(baseDir string) (string, error) { + // create the tar.gz file + destFile := &bytes.Buffer{} + + fileWriter := gzip.NewWriter(destFile) + tarfileWriter := tar.NewWriter(fileWriter) + + if err := addDirToArchive(baseDir, tarfileWriter); err != nil { + return "", err + } + + tarfileWriter.Close() + fileWriter.Close() + + return base64.StdEncoding.EncodeToString(destFile.Bytes()), nil +} + +func addDirToArchive(source string, tarfileWriter *tar.Writer) error { + baseDir := filepath.Base(source) + + return filepath.Walk(source, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if path == source || strings.HasSuffix(info.Name(), ".iso") || + strings.HasSuffix(info.Name(), ".tar.gz") || + strings.HasSuffix(info.Name(), ".vmdk") || + strings.HasSuffix(info.Name(), ".img") { + return nil + } + + header, err := tar.FileInfoHeader(info, info.Name()) + if err != nil { + return err + } + + header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) + + if err := tarfileWriter.WriteHeader(header); err != nil { + return err + } + + if info.IsDir() { + return nil + } + + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + _, err = io.Copy(tarfileWriter, file) + return err + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/config.go new file mode 100644 index 0000000..222b406 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/nodeconfig/config.go @@ -0,0 +1,313 @@ +package nodeconfig + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/encryptedstore" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/jailer" + "github.com/sirupsen/logrus" + k8serror "k8s.io/apimachinery/pkg/api/errors" +) + +const ( + configKey = "extractedConfig" + driverKey = "driverConfig" + defaultCattleHome = "./management-state" +) + +type NodeConfig struct { + store *encryptedstore.GenericEncryptedStore + fullMachinePath string + jailDir string + id string + cm map[string]string +} + +func NewStore(namespaceInterface v1.NamespaceInterface, secretsGetter v1.SecretsGetter) (*encryptedstore.GenericEncryptedStore, error) { + return encryptedstore.NewGenericEncryptedStore("mc-", "", namespaceInterface, secretsGetter) +} + +func NewNodeConfig(store *encryptedstore.GenericEncryptedStore, node *v3.Node) (*NodeConfig, error) { + jailDir, fullMachinePath, err := buildBaseHostDir(node.Spec.RequestedHostname, node.Namespace) + if err != nil { + return nil, err + } + logrus.Debugf("Created node storage directory %s", fullMachinePath) + + return &NodeConfig{ + store: store, + id: node.Name, + fullMachinePath: fullMachinePath, + jailDir: jailDir, + }, nil +} + +func (m *NodeConfig) SetDriverConfig(config string) error { + if err := m.loadConfig(); err != nil { + return err + } + m.cm[driverKey] = config + return nil +} + +func (m *NodeConfig) DriverConfig() (string, error) { + if err := m.loadConfig(); err != nil { + return "", err + } + return m.cm[driverKey], nil +} + +func (m *NodeConfig) SSHUser() (string, error) { + if err := m.loadConfig(); err != nil { + return "", err + } + data := map[string]interface{}{} + if err := json.Unmarshal([]byte(m.cm[driverKey]), &data); err != nil { + return "", err + } + user, _ := data["sshUser"].(string) + if user == "" { + user = "root" + } + return user, nil +} + +func (m *NodeConfig) Dir() string { + return m.jailDir +} + +func (m *NodeConfig) FullDir() string { + return m.fullMachinePath +} + +func (m *NodeConfig) Cleanup() error { + logrus.Debugf("Cleaning up [%s]", m.fullMachinePath) + return os.RemoveAll(m.fullMachinePath) +} + +func (m *NodeConfig) Remove() error { + _ = m.Cleanup() + logrus.Debugf("Removing [%v]", m.id) + return m.store.Remove(m.id) +} + +func (m *NodeConfig) TLSConfig() (*TLSConfig, error) { + if err := m.loadConfig(); err != nil { + return nil, err + } + return extractTLS(m.cm[configKey]) +} + +func (m *NodeConfig) SSHKeyPath() (string, error) { + config, err := m.getConfig() + if err != nil { + return "", err + } + + return convert.ToString(values.GetValueN(config, "Driver", "SSHKeyPath")), nil +} + +func (m *NodeConfig) IP() (string, error) { + config, err := m.getConfig() + if err != nil { + return "", err + } + + return convert.ToString(values.GetValueN(config, "Driver", "IPAddress")), nil +} + +func (m *NodeConfig) InternalIP() (string, error) { + config, err := m.getConfig() + if err != nil { + return "", err + } + + return convert.ToString(values.GetValueN(config, "Driver", "PrivateIPAddress")), nil +} + +func (m *NodeConfig) Save() error { + extractedConfig, err := compressConfig(m.fullMachinePath) + if err != nil { + return err + } + + if err = m.loadConfig(); err != nil { + return err + } + + if m.cm[configKey] == extractedConfig { + return nil + } + + m.cm[configKey] = extractedConfig + + if err = m.store.Set(m.id, m.cm); err != nil { + m.cm = nil + return err + } + + return nil +} + +func (m *NodeConfig) Restore() error { + if err := m.loadConfig(); err != nil { + return err + } + + data := m.cm[configKey] + if data == "" { + return nil + } + + return extractConfig(m.fullMachinePath, data) +} + +// UpdateAmazonAuth updates the machine config.json file on disk with the most +// recent version of creds from the cloud credential +// This code should not be updated or duplicated - it should be deleted once +// https://github.com/rancher/rancher/issues/24541 is implemented +func (m *NodeConfig) UpdateAmazonAuth(rawConfig interface{}) (bool, error) { + var update bool + c := convert.ToMapInterface(rawConfig) + + machines := filepath.Join(m.fullMachinePath, "machines") + logrus.Debugf("[UpdateAmazonAuth] machine path %v", machines) + files, err := ioutil.ReadDir(machines) + if err != nil { + // There aren't any machines, nothing to update + if os.IsNotExist(err) { + return update, nil + } + return update, err + } + + for _, file := range files { + if file.IsDir() { + configPath := filepath.Join(machines, file.Name(), "config.json") + b, err := os.ReadFile(configPath) + if err != nil { + if os.IsNotExist(err) { + // config.json doesn't exist, no changes needed + continue + } + return update, err + } + + logrus.Debugf("[UpdateAmazonAuth] config file found, path %v", configPath) + + result := make(map[string]interface{}) + + if err := json.Unmarshal(b, &result); err != nil { + return update, errors.Wrap(err, "error unmarshaling machine config") + } + + if _, ok := result["Driver"]; !ok { + logrus.Debug("[UpdateAmazonAuth] config file does not have Data key") + // No Driver config so no changes to be made + continue + } + + driverConfig := convert.ToMapInterface(result["Driver"]) + + if _, ok := driverConfig["AccessKey"]; ok { + if driverConfig["AccessKey"] != c["accessKey"] { + logrus.Debug("[UpdateAmazonAuth] update access key") + driverConfig["AccessKey"] = c["accessKey"] + update = true + } + } + + if _, ok := driverConfig["SecretKey"]; ok { + if driverConfig["SecretKey"] != c["secretKey"] { + logrus.Debug("[UpdateAmazonAuth] update secret key") + driverConfig["SecretKey"] = c["secretKey"] + update = true + } + + } + + if update { + result["Driver"] = driverConfig + + out, err := json.Marshal(result) + if err != nil { + return update, errors.WithMessage(err, "error marshaling new machine config") + } + + if err := os.WriteFile(configPath, out, 0600); err != nil { + return update, errors.WithMessage(err, "error writing new machine config") + } + } + + } + } + + return update, nil +} + +func (m *NodeConfig) loadConfig() error { + if m.cm != nil { + return nil + } + + cm, err := m.getConfigMap() + if err != nil { + return err + } + + if cm == nil { + cm = map[string]string{} + } + + m.cm = cm + return nil +} + +func (m *NodeConfig) getConfigMap() (map[string]string, error) { + configMap, err := m.store.Get(m.id) + if k8serror.IsNotFound(err) { + return nil, nil + } + if err != nil { + return nil, err + } + + return configMap, nil +} + +func (m *NodeConfig) getConfig() (map[string]interface{}, error) { + if err := m.loadConfig(); err != nil { + return nil, err + } + + data := m.cm[configKey] + if data == "" { + return nil, nil + } + + return ExtractConfigJSON(data) +} + +func buildBaseHostDir(nodeName string, clusterID string) (string, string, error) { + var fullMachinePath string + var jailDir string + + suffix := filepath.Join("node", "nodes", nodeName) + if dm := os.Getenv("CATTLE_DEV_MODE"); dm != "" { + fullMachinePath = filepath.Join(defaultCattleHome, suffix) + jailDir = fullMachinePath + } else { + fullMachinePath = filepath.Join(jailer.BaseJailPath, clusterID, "management-state", suffix) + jailDir = filepath.Join("/management-state", suffix) + } + + return jailDir, fullMachinePath, os.MkdirAll(fullMachinePath, 0740) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/peermanager/peermanager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/peermanager/peermanager.go new file mode 100644 index 0000000..b71a1a6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/peermanager/peermanager.go @@ -0,0 +1,15 @@ +package peermanager + +type Peers struct { + SelfID string + IDs []string + Ready bool + Leader bool +} + +type PeerManager interface { + IsLeader() bool + Leader() + AddListener(l chan<- Peers) + RemoveListener(l chan<- Peers) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/project/project.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/project/project.go new file mode 100644 index 0000000..98d0da1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/project/project.go @@ -0,0 +1,35 @@ +package project + +import ( + mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + + "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/labels" +) + +const ( + System = "System" + Default = "Default" +) + +const ( + SystemImageVersionAnn = "field.cattle.io/systemImageVersion" + ProjectIDAnn = "field.cattle.io/projectId" +) + +var ( + SystemProjectLabel = map[string]string{"authz.management.cattle.io/system-project": "true"} +) + +func GetSystemProject(clusterName string, projectLister mgmtv3.ProjectLister) (*mgmtv3.Project, error) { + projects, err := projectLister.List(clusterName, labels.Set(SystemProjectLabel).AsSelector()) + if err != nil { + return nil, errors.Wrapf(err, "list project failed") + } + + if len(projects) == 0 { + return nil, errors.New("can't find system project") + } + + return projects[0], nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/image/resolve.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/image/resolve.go new file mode 100644 index 0000000..254a735 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/image/resolve.go @@ -0,0 +1,101 @@ +package image + +import ( + "path" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/settings" +) + +func ResolveWithControlPlane(image string, cp *rkev1.RKEControlPlane) string { + return resolve(GetPrivateRepoURLFromControlPlane(cp), image) +} + +func ResolveWithCluster(image string, cluster *v1.Cluster) string { + return resolve(GetPrivateRepoURLFromCluster(cluster), image) +} + +func resolve(reg, image string) string { + if reg != "" && !strings.HasPrefix(image, reg) { + //Images from Dockerhub Library repo, we add rancher prefix when using private registry + if !strings.Contains(image, "/") { + image = "rancher/" + image + } + return path.Join(reg, image) + } + + return image +} + +// GetPrivateRepoSecretFromCluster returns the name of the secret containing the credentials for the cluster level system-default-registry. +func GetPrivateRepoSecretFromCluster(cluster *v1.Cluster) string { + if cluster != nil && cluster.Spec.RKEConfig != nil && cluster.Spec.RKEConfig.Registries != nil { + return cluster.Spec.RKEConfig.Registries.Configs[GetPrivateRepoURLFromCluster(cluster)].AuthConfigSecretName + } + return "" // don't return settings.SystemDefaultRegistry.Get() as the global system-default-registry requires no auth +} + +// GetPrivateRepoURLFromCluster returns the system-default-registry URL from either the clusters +// machineGlobalConfig, or one of its machineSelectorConfig's which has no label selectors. +// If no cluster level system-default-registry is configured, it will return the global system-default-registry. +func GetPrivateRepoURLFromCluster(cluster *v1.Cluster) string { + if cluster != nil && cluster.Spec.RKEConfig != nil { + return getPrivateRepoURL(cluster.Spec.RKEConfig.MachineGlobalConfig, cluster.Spec.RKEConfig.MachineSelectorConfig) + } + + return settings.SystemDefaultRegistry.Get() +} + +// GetPrivateRepoURLFromControlPlane returns the system-default-registry URL from either the control planes +// machineGlobalConfig, or one of its machineSelectorConfig's which has no label selectors. +// If no cluster level system-default-registry is configured, it will return the global system-default-registry. +func GetPrivateRepoURLFromControlPlane(cp *rkev1.RKEControlPlane) string { + if cp != nil { + return getPrivateRepoURL(cp.Spec.MachineGlobalConfig, cp.Spec.MachineSelectorConfig) + } + + return settings.SystemDefaultRegistry.Get() +} + +func getPrivateRepoURL(machineGlobalConfig rkev1.GenericMap, machineSelectorConfig []rkev1.RKESystemConfig) string { + for key, val := range machineGlobalConfig.Data { + if val, ok := val.(string); ok && key == "system-default-registry" { + return val + } + } + + for _, config := range machineSelectorConfig { + if registryVal, ok := config.Config.Data["system-default-registry"]; config.MachineLabelSelector == nil && ok { + if registry, ok := registryVal.(string); ok { + return registry + } + } + } + + return settings.SystemDefaultRegistry.Get() +} + +func GetDesiredAgentImage(cp *rkev1.RKEControlPlane, mgmtCluster *v3.Cluster) string { + desiredAgent := mgmtCluster.Spec.DesiredAgentImage + if mgmtCluster.Spec.AgentImageOverride != "" { + desiredAgent = mgmtCluster.Spec.AgentImageOverride + } + if desiredAgent == "" || desiredAgent == "fixed" { + desiredAgent = ResolveWithControlPlane(settings.AgentImage.Get(), cp) + } + return desiredAgent +} + +func GetDesiredAuthImage(cp *rkev1.RKEControlPlane, mgmtCluster *v3.Cluster) string { + var desiredAuth string + if mgmtCluster.Spec.LocalClusterAuthEndpoint.Enabled { + desiredAuth = mgmtCluster.Spec.DesiredAuthImage + if desiredAuth == "" || desiredAuth == "fixed" { + desiredAuth = ResolveWithControlPlane(settings.AuthImage.Get(), cp) + } + } + return desiredAuth +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager.go new file mode 100644 index 0000000..85fb2a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager.go @@ -0,0 +1,425 @@ +package kubeconfig + +import ( + "bytes" + "crypto/rand" + "crypto/sha256" + "encoding/base32" + "encoding/base64" + "errors" + "fmt" + "strings" + + "github.com/moby/locker" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/auth/tokens/hashers" + "github.com/rancher/rancher/pkg/features" + mgmtcontrollers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/wrangler" + appcontroller "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + userIDLabel = "authn.management.cattle.io/token-userId" + tokenKindLabel = "authn.management.cattle.io/kind" + + hashFormat = "$%d:%s:%s" // $version:salt:hash -> $1:abc:def + Version = 2 +) + +type Manager struct { + deploymentCache appcontroller.DeploymentCache + daemonsetCache appcontroller.DaemonSetCache + tokens mgmtcontrollers.TokenClient + tokensCache mgmtcontrollers.TokenCache + userCache mgmtcontrollers.UserCache + users mgmtcontrollers.UserClient + secretCache corecontrollers.SecretCache + secrets corecontrollers.SecretClient + kubeConfigLocker locker.Locker +} + +func New(clients *wrangler.Context) *Manager { + return &Manager{ + deploymentCache: clients.Apps.Deployment().Cache(), + daemonsetCache: clients.Apps.DaemonSet().Cache(), + tokens: clients.Mgmt.Token(), + tokensCache: clients.Mgmt.Token().Cache(), + userCache: clients.Mgmt.User().Cache(), + users: clients.Mgmt.User(), + secretCache: clients.Core.Secret().Cache(), + secrets: clients.Core.Secret(), + } +} + +func getKubeConfigSecretName(clusterName string) string { + return clusterName + "-kubeconfig" +} + +func (m *Manager) getToken(clusterNamespace, clusterName string) (string, error) { + kubeConfigSecretName := getKubeConfigSecretName(clusterName) + if token, err := m.getSavedToken(clusterNamespace, kubeConfigSecretName); err != nil || token != "" { + return token, err + } + + // Need to be careful about caches being out of sync since we are dealing with multiple objects that + // arent eventually consistent (because we delete and create the token for the user) + if token, err := m.getSavedTokenNoCache(clusterNamespace, kubeConfigSecretName); err != nil || token != "" { + return token, err + } + + userName, err := m.EnsureUser(clusterNamespace, clusterName) + if err != nil { + return "", err + } + + return m.createUserToken(userName) +} + +// getCachedToken retrieves the token for a given cluster without manipulating the token itself. This function is +// primary to ensure the kubeconfig for a cluster remains valid. +func (m *Manager) getCachedToken(clusterNamespace, clusterName string) (string, *v3.Token, error) { + _, userName := getPrincipalAndUserName(clusterNamespace, clusterName) + token, err := m.tokensCache.Get(userName) + if err != nil { + return "", nil, err + } + return userName, token, nil +} + +func getPrincipalAndUserName(clusterNamespace, clusterName string) (string, string) { + principalID := getPrincipalID(clusterNamespace, clusterName) + return principalID, getUserNameForPrincipal(principalID) +} + +func (m *Manager) EnsureUser(clusterNamespace, clusterName string) (string, error) { + principalID, userName := getPrincipalAndUserName(clusterNamespace, clusterName) + return userName, m.createUser(principalID, userName) +} + +func (m *Manager) DeleteUser(clusterNamespace, clusterName string) error { + return m.deleteUser(getUserNameForPrincipal(getPrincipalID(clusterNamespace, clusterName))) +} + +func getUserNameForPrincipal(principal string) string { + hasher := sha256.New() + hasher.Write([]byte(principal)) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + return "u-" + strings.ToLower(sha) +} + +func labelsForUser(principalID string) map[string]string { + encodedPrincipalID := base32.HexEncoding.WithPadding(base32.NoPadding).EncodeToString([]byte(principalID)) + if len(encodedPrincipalID) > 63 { + encodedPrincipalID = encodedPrincipalID[:63] + } + return map[string]string{ + encodedPrincipalID: "hashed-principal-name", + } +} + +func (m *Manager) getSavedToken(kubeConfigNamespace, kubeConfigName string) (string, error) { + secret, err := m.secretCache.Get(kubeConfigNamespace, kubeConfigName) + if apierror.IsNotFound(err) { + return "", nil + } else if err != nil { + return "", err + } + return string(secret.Data["token"]), nil +} + +func (m *Manager) getSavedTokenNoCache(kubeConfigNamespace, kubeConfigName string) (string, error) { + secret, err := m.secrets.Get(kubeConfigNamespace, kubeConfigName, metav1.GetOptions{}) + if apierror.IsNotFound(err) { + return "", nil + } else if err != nil { + return "", err + } + return string(secret.Data["token"]), nil +} + +func getPrincipalID(clusterNamespace, clusterName string) string { + return fmt.Sprintf("system://provisioning/%s/%s", clusterNamespace, clusterName) +} + +func (m *Manager) createUser(principalID, userName string) error { + _, err := m.userCache.Get(userName) + if apierror.IsNotFound(err) { + _, err = m.users.Create(&v3.User{ + ObjectMeta: metav1.ObjectMeta{ + Name: userName, + Labels: labelsForUser(principalID), + }, + PrincipalIDs: []string{ + principalID, + }, + }) + } + return err +} + +func (m *Manager) deleteUser(userName string) error { + if err := m.users.Delete(userName, nil); err != nil && !apierror.IsNotFound(err) { + return err + } + return nil +} + +func (m *Manager) createUserToken(userName string) (string, error) { + _, err := m.tokens.Get(userName, metav1.GetOptions{}) + if err == nil { + err = m.tokens.Delete(userName, nil) + } + if err != nil && !apierror.IsNotFound(err) { + return "", err + } + + tokenValue, err := randomtoken.Generate() + if err != nil { + return "", fmt.Errorf("failed to generate token key: %w", err) + } + + token := &v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + Name: userName, + Labels: map[string]string{ + userIDLabel: userName, + tokenKindLabel: "provisioning", + }, + Annotations: map[string]string{}, + }, + UserID: userName, + AuthProvider: "local", + IsDerived: true, + Token: tokenValue, + } + + if features.TokenHashing.Enabled() { + err := tokens.ConvertTokenKeyToHash(token) + if err != nil { + return "", fmt.Errorf("unable to hash token: %w", err) + } + } + + _, err = m.tokens.Create(token) + return fmt.Sprintf("%s:%s", userName, tokenValue), err +} + +func createSHA256Hash(secretKey string) (string, error) { + salt := make([]byte, 8) + _, err := rand.Read(salt) + if err != nil { + return "", err + } + hash := sha256.Sum256([]byte(fmt.Sprintf("%s%s", salt, secretKey))) + encSalt := base64.RawStdEncoding.EncodeToString(salt) + encKey := base64.RawStdEncoding.EncodeToString(hash[:]) + return fmt.Sprintf(hashFormat, Version, encSalt, encKey), nil +} + +func (m *Manager) GetCRTBForClusterOwner(cluster *v1.Cluster, status v1.ClusterStatus) (*v3.ClusterRoleTemplateBinding, error) { + if status.ClusterName == "" { + return nil, fmt.Errorf("management cluster is not assigned to v1.Cluster") + } + principalID := getPrincipalID(cluster.Namespace, cluster.Name) + userName := getUserNameForPrincipal(principalID) + return &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: name.SafeConcatName(status.ClusterName, cluster.Namespace, "owner"), + Namespace: status.ClusterName, + }, + ClusterName: status.ClusterName, + UserName: userName, + UserPrincipalName: principalID, + RoleTemplateName: "cluster-owner", + }, nil +} + +// kubeConfigValid accepts a kubeconfig and corresponding data, and validates that the kubeconfig is valid for the +// cluster in question. It returns two booleans, the first of which is whether an error occurred parsing the kubeconfig +// or retrieving information related to the kubeconfig, and the second which indicates whether the kubeconfig is valid. +func (m *Manager) kubeConfigValid(kcData []byte, cluster *v1.Cluster, currentServerURL, currentServerCA, currentManagementClusterName string, secretLabels map[string]string) (bool, bool) { + if len(kcData) == 0 { + return true, false + } + kc, err := clientcmd.Load(kcData) + if err != nil { + logrus.Errorf("error while loading kubeconfig in kubeconfigmanager for validation: %v", err) + return true, false + } + var serverURL, managementCluster string + splitServer := strings.Split(kc.Clusters["cluster"].Server, "/k8s/clusters/") + if len(splitServer) != 2 { + return true, false + } + + serverURL = splitServer[0] + managementCluster = splitServer[1] + logrus.Tracef("[kubeconfigmanager] cluster %s/%s: parsed serverURL: %s and managementServer: %s from existing kubeconfig", cluster.Namespace, cluster.Name, serverURL, managementCluster) + + userName, token, err := m.getCachedToken(cluster.Namespace, cluster.Name) + if err != nil { + logrus.Errorf("error while retrieving cached token in kubeconfigmanager for validation: %v", err) + return true, false + } + + tokenMatches := fmt.Sprintf("%s:%s", userName, token.Token) == kc.AuthInfos["user"].Token + if token.Annotations[tokens.TokenHashed] == "true" { + // if tokenHashing is enabled, the stored token will be hashed. So we instead make sure it's up-to-date by checking if the token is valid for the hash + hasher, err := hashers.GetHasherForHash(token.Token) + if err != nil { + logrus.Errorf("[kubeconfigmanager] error when retrieving hasher for token hash, %s", err.Error()) + return true, false + } + _, tokenKey := tokens.SplitTokenParts(kc.AuthInfos["user"].Token) + err = hasher.VerifyHash(token.Token, tokenKey) + tokenMatches = err == nil + } + + // Check if the required CAPI cluster label is present in the secretLabels map + capiClusterLabelValue, labelPresent := secretLabels[capi.ClusterNameLabel] + if !labelPresent || capiClusterLabelValue != cluster.Name { + logrus.Tracef("[kubeconfigmanager] cluster %s/%s: kubeconfig secret failed validation due to missing or incorrect label", cluster.Namespace, cluster.Name) + return false, false + } + + if serverURL != currentServerURL || !bytes.Equal([]byte(strings.TrimSpace(currentServerCA)), kc.Clusters["cluster"].CertificateAuthorityData) || managementCluster != currentManagementClusterName || !tokenMatches { + logrus.Tracef("[kubeconfigmanager] cluster %s/%s: kubeconfig secret failed validation, did not match provided data", cluster.Namespace, cluster.Name) + return false, false + } + logrus.Tracef("[kubeconfigmanager] cluster %s/%s: kubeconfig secret passed validation", cluster.Namespace, cluster.Name) + return false, true +} + +func (m *Manager) getKubeConfigData(cluster *v1.Cluster, secretName, managementClusterName string) (map[string][]byte, error) { + serverURL, cacert := settings.InternalServerURL.Get(), settings.InternalCACerts.Get() + if serverURL == "" { + return nil, errors.New("server url is missing, can't generate kubeconfig for fleet import cluster") + } + + secret, err := m.secretCache.Get(cluster.Namespace, secretName) + if err == nil { + retrievalError, isValid := m.kubeConfigValid(secret.Data["value"], cluster, serverURL, cacert, managementClusterName, secret.Labels) + if (!retrievalError && !isValid) || secret.Data == nil || secret.Data["token"] == nil || len(secret.OwnerReferences) == 0 { + logrus.Infof("[kubeconfigmanager] deleting kubeconfig secret for cluster %s/%s", cluster.Namespace, cluster.Name) + // Check if we require a new secret based on the token value and annotation(s). We delete the old secret since it may contain + // annotations, owner references, etc. that are out of date. We will then continue to create the new secret. + if err := m.secrets.Delete(cluster.Namespace, secretName, &metav1.DeleteOptions{}); err != nil && !apierror.IsNotFound(err) { + return nil, err + } + } else { + return secret.Data, nil + } + } else if !apierror.IsNotFound(err) { + return nil, err + } + + lockID := cluster.Namespace + "/" + cluster.Name + m.kubeConfigLocker.Lock(lockID) + defer m.kubeConfigLocker.Unlock(lockID) + + secret, err = m.secrets.Get(cluster.Namespace, secretName, metav1.GetOptions{}) + if err == nil { + return secret.Data, nil + } + + tokenValue, err := m.getToken(cluster.Namespace, cluster.Name) + if err != nil { + return nil, err + } + + data, err := clientcmd.Write(clientcmdapi.Config{ + Clusters: map[string]*clientcmdapi.Cluster{ + "cluster": { + Server: fmt.Sprintf("%s/k8s/clusters/%s", serverURL, managementClusterName), + CertificateAuthorityData: []byte(strings.TrimSpace(cacert)), + }, + }, + AuthInfos: map[string]*clientcmdapi.AuthInfo{ + "user": { + Token: tokenValue, + }, + }, + Contexts: map[string]*clientcmdapi.Context{ + "default": { + Cluster: "cluster", + AuthInfo: "user", + }, + }, + CurrentContext: "default", + }) + if err != nil { + return nil, err + } + + secret, err = m.secrets.Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Namespace, + Name: secretName, + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: v1.SchemeGroupVersion.String(), + Kind: "Cluster", + Name: cluster.Name, + UID: cluster.UID, + }}, + Labels: map[string]string{ + capi.ClusterNameLabel: cluster.Name, + }, + }, + Data: map[string][]byte{ + "value": data, + "token": []byte(tokenValue), + }, + }) + if err != nil { + return nil, err + } + + return secret.Data, nil +} + +func (m *Manager) GetRESTConfig(cluster *v1.Cluster, status v1.ClusterStatus) (*rest.Config, error) { + secret, err := m.GetKubeConfig(cluster, status) + if err != nil { + return nil, err + } + + return clientcmd.RESTConfigFromKubeConfig(secret.Data["value"]) +} + +func (m *Manager) GetKubeConfig(cluster *v1.Cluster, status v1.ClusterStatus) (*corev1.Secret, error) { + if cluster.Spec.ClusterAPIConfig != nil { + return m.secretCache.Get(cluster.Namespace, getKubeConfigSecretName(cluster.Spec.ClusterAPIConfig.ClusterName)) + } + + var ( + secretName = getKubeConfigSecretName(cluster.Name) + ) + + data, err := m.getKubeConfigData(cluster, secretName, status.ClusterName) + if err != nil { + return nil, err + } + + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: cluster.Namespace, + Name: secretName, + }, + Data: data, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager_test.go new file mode 100644 index 0000000..71f4b0b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/kubeconfig/manager_test.go @@ -0,0 +1,460 @@ +package kubeconfig + +import ( + "fmt" + "testing" + + "github.com/golang/mock/gomock" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/require" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "k8s.io/utils/pointer" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + tokenKey = "cccccccccccccccccccccccccccccccccccccccccccccccccccccc" + invalidTokenKey = "dddddddddddddddddddddddddddddddddddddddddddddddddddddd" + badHashVersionTokenKey = "$-1:jwvzsLqh6Rg:FyeWbQuUt6VEMhQOe5J1kXPf0D4H9MRjub0aNaGzyx8" +) + +func Test_kubeConfigValid(t *testing.T) { + type kubeconfigData struct { + serverURL string + serverCA string + clusterName string + token string + } + + hashToken := func(token *v3.Token, useBadHashVersion bool) *v3.Token { + features.TokenHashing.Set(true) + newToken := token.DeepCopy() + err := tokens.ConvertTokenKeyToHash(newToken) + if useBadHashVersion { + // ConvertTokenKeyToHash also adds an annotation, so we want to do this after that call + newToken.Token = badHashVersionTokenKey + } + require.NoError(t, err, "error when hashing token") + // test only requires an individual token to be hashed + features.TokenHashing.Set(false) + return newToken + } + cluster := v1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "c-m-1234xyz", + Namespace: "fleet-default", + }, + } + + token := v3.Token{ + ObjectMeta: metav1.ObjectMeta{ + // name of the token for the above cluster as calculated by getPrincipalAndUserName + Name: "u-fngwm5ys7g", + }, + Token: tokenKey, + UserID: "test-user", + Enabled: pointer.Bool(true), + } + + tests := []struct { + name string + currentData *kubeconfigData + wantData *kubeconfigData + cluster *v1.Cluster + storedToken *v3.Token + secretLabels map[string]string + + invalidServerURL bool + invalidKubeconfig bool + tokenCacheError error + + wantError bool + wantValid bool + }{ + { + name: "kubeconfig up to date", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: true, + }, + { + name: "kubeconfig up to date, hashed token", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: hashToken(&token, false), + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: true, + }, + { + name: "kubeconfig bad token", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, invalidTokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: false, + }, + { + name: "kubeconfig bad token, token hashing enabled", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, invalidTokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: hashToken(&token, false), + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: false, + }, + { + name: "changed server url", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.new.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: false, + }, + { + name: "changed server CA", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "XYZ", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: false, + }, + { + name: "changed cluster name", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: false, + }, + { + name: "empty kubeconfig data", + currentData: nil, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: true, + wantValid: false, + }, + { + name: "current kubeconfig invalid", + currentData: nil, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + invalidKubeconfig: true, + + wantError: true, + wantValid: false, + }, + { + name: "CAPI cluster label is set correctly", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: false, + wantValid: true, + }, + { + name: "CAPI cluster label is set incorrectly", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "random-cluster-name", + }, + + wantError: false, + wantValid: false, + }, + { + name: "CAPI cluster label is missing", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + token: fmt.Sprintf("%s:%s", token.Name, tokenKey), + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234xyz", + }, + storedToken: &token, + cluster: &cluster, + invalidKubeconfig: true, + secretLabels: map[string]string{}, + + wantError: false, + wantValid: false, + }, + { + name: "invalid server url", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + storedToken: &token, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + invalidServerURL: true, + + wantError: true, + wantValid: false, + }, + { + name: "invalid hash version on stored token", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + storedToken: hashToken(&token, true), + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + + wantError: true, + wantValid: false, + }, + { + name: "unable to get stored token", + currentData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + wantData: &kubeconfigData{ + serverURL: "https://test.cluster.io", + serverCA: "ABC", + clusterName: "c-1234abc", + }, + cluster: &cluster, + secretLabels: map[string]string{ + capi.ClusterNameLabel: "c-m-1234xyz", + }, + tokenCacheError: fmt.Errorf("server unavailable"), + + wantError: true, + wantValid: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var kcData []byte + if test.currentData != nil { + var err error + var serverURL string + if test.invalidServerURL { + serverURL = test.currentData.serverURL + } else { + serverURL = fmt.Sprintf("%s/k8s/clusters/%s", test.currentData.serverURL, test.currentData.clusterName) + } + config := clientcmdapi.Config{ + Clusters: map[string]*clientcmdapi.Cluster{ + "cluster": { + Server: serverURL, + CertificateAuthorityData: []byte(test.currentData.serverCA), + }, + }, + AuthInfos: map[string]*clientcmdapi.AuthInfo{ + "user": { + Token: test.currentData.token, + }, + }, + Contexts: map[string]*clientcmdapi.Context{ + "default": { + Cluster: "cluster", + AuthInfo: "user", + }, + }, + CurrentContext: "default", + } + kcData, err = clientcmd.Write(config) + require.NoError(t, err, "error when writing kubeconfig for test setup") + + } else if test.invalidKubeconfig { + kcData = []byte{'a'} + } + + ctrl := gomock.NewController(t) + mockCache := fake.NewMockNonNamespacedCacheInterface[*v3.Token](ctrl) + + mockCache.EXPECT().Get(gomock.Any()).AnyTimes().DoAndReturn(func(name string) (*v3.Token, error) { + if test.storedToken != nil && name == test.storedToken.Name { + return test.storedToken, nil + } + if test.tokenCacheError != nil { + return nil, test.tokenCacheError + } + return nil, apierrors.NewNotFound(schema.GroupResource{Group: "management.cattle.io", Resource: "Token"}, name) + + }) + m := Manager{ + tokensCache: mockCache, + } + isError, isValid := m.kubeConfigValid(kcData, test.cluster, test.wantData.serverURL, test.wantData.serverCA, test.wantData.clusterName, test.secretLabels) + require.Equal(t, test.wantError, isError) + require.Equal(t, test.wantValid, isValid) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/systeminfo/systeminfo.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/systeminfo/systeminfo.go new file mode 100644 index 0000000..c51a49b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/provisioningv2/systeminfo/systeminfo.go @@ -0,0 +1,51 @@ +package systeminfo + +import ( + "fmt" + + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + fleetv1alpha1 "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/sirupsen/logrus" +) + +type Retriever struct { + fleetClusterCache fleetv1alpha1.ClusterCache +} + +// NewRetriever returns a new instance of the systeminfo.Retriever +func NewRetriever(clients *wrangler.Context) *Retriever { + if clients == nil { + return nil + } + return &Retriever{ + fleetClusterCache: clients.Fleet.Cluster().Cache(), + } +} + +// GetSystemPodLabelSelectors returns a slice of strings that contains system pod label selectors in the format of namespace:labelSelector, delimited by : +func (r *Retriever) GetSystemPodLabelSelectors(controlPlane *v1.RKEControlPlane) []string { + if controlPlane == nil { + return []string{} + } + labelSelectors := []string{ + "cattle-system:app=cattle-cluster-agent", // See pkg/systemtemplate/template.go -- notably hard coded namespace as the systemtemplate is hard coded (as of 05/11/2023) + "cattle-system:app=kube-api-auth", // See pkg/systemtemplate/template.go -- notably hard coded namespace as the systemtemplate is hard coded @ Line 402 & 407 (as of 05/11/2023) + fmt.Sprintf("%s:app=rancher-webhook", namespace.System), // See pkg/controllers/dashboard/systemcharts/controller.go Line 115= + "cattle-system:upgrade.cattle.io/controller=system-upgrade-controller", // See: https://github.com/rancher/charts/blob/872076dc31642eaa9d2a781a08069d2fc2436f9b/charts/system-upgrade-controller/102.0.0%2Bup0.4.0/templates/deployment.yaml#L5 + } + + fc, err := r.fleetClusterCache.Get(controlPlane.Namespace, controlPlane.Name) + if err != nil { + logrus.Errorf("error retrieving fleet cluster %s/%s: %v", controlPlane.Namespace, controlPlane.Name, err) + // Don't return here so we don't erroneously block pod cleanup + } else { + cfsNamespace := "cattle-fleet-system" + if fc.Spec.AgentNamespace != "" { + cfsNamespace = fc.Spec.AgentNamespace + } + labelSelectors = append(labelSelectors, fmt.Sprintf("%s:app=fleet-agent", cfsNamespace)) + } + return labelSelectors +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/migrations.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/migrations.go new file mode 100644 index 0000000..11be8c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/migrations.go @@ -0,0 +1,662 @@ +package rancher + +import ( + "encoding/json" + "fmt" + "strings" + + "github.com/mcuadros/go-version" + "github.com/rancher/norman/condition" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/auth/tokens" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + "github.com/rancher/rancher/pkg/features" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + rancherversion "github.com/rancher/rancher/pkg/version" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/data" + "github.com/rancher/wrangler/v3/pkg/data/convert" + controllerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/summary" + "github.com/sirupsen/logrus" + "golang.org/x/mod/semver" + v1 "k8s.io/api/core/v1" + k8serror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/util/retry" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ( + cattleNamespace = "cattle-system" + forceUpgradeLogoutConfig = "forceupgradelogout" + forceLocalSystemAndDefaultProjectCreation = "forcelocalprojectcreation" + forceSystemNamespacesAssignment = "forcesystemnamespaceassignment" + migrateFromMachineToPlanSecret = "migratefrommachinetoplanesecret" + migrateEncryptionKeyRotationLeaderToStatus = "migrateencryptionkeyrotationleadertostatus" + migrateDynamicSchemaToMachinePools = "migratedynamicschematomachinepools" + migrateRKEClusterState = "migraterkeclusterstate" + migrateSystemAgentVarDirToDataDirectory = "migratesystemagentvardirtodatadirectory" + rancherVersionKey = "rancherVersion" + projectsCreatedKey = "projectsCreated" + namespacesAssignedKey = "namespacesAssigned" + capiMigratedKey = "capiMigrated" + encryptionKeyRotationStatusMigratedKey = "encryptionKeyRotationStatusMigrated" + dynamicSchemaMachinePoolsMigratedKey = "dynamicSchemaMachinePoolsMigrated" + rkeClustersAnnotatedForMigrationKey = "rkeClustersAnnotatedForMigration" + systemAgentVarDirMigratedKey = "systemAgentVarDirMigrated" +) + +func runMigrations(wranglerContext *wrangler.Context) error { + if err := forceUpgradeLogout(wranglerContext.Core.ConfigMap(), wranglerContext.Mgmt.Token(), "v2.6.0"); err != nil { + return err + } + + if err := forceSystemAndDefaultProjectCreation(wranglerContext.Core.ConfigMap(), wranglerContext.Mgmt.Cluster()); err != nil { + return err + } + + if features.MCM.Enabled() { + if err := forceSystemNamespaceAssignment(wranglerContext.Core.ConfigMap(), wranglerContext.Mgmt.Project()); err != nil { + return err + } + } + + if features.RKE2.Enabled() { + // must migrate system agent data directory first, since update requests will be rejected by webhook if + // "CATTLE_AGENT_VAR_DIR" is set within AgentEnvVars. + if err := migrateSystemAgentDataDirectory(wranglerContext); err != nil { + return err + } + if err := migrateCAPIMachineLabelsAndAnnotationsToPlanSecret(wranglerContext); err != nil { + return err + } + if err := migrateEncryptionKeyRotationLeader(wranglerContext); err != nil { + return err + } + if err := migrateMachinePoolsDynamicSchemaLabel(wranglerContext); err != nil { + return err + } + } + + return migrateRKEClusterStates(wranglerContext) +} + +func getConfigMap(configMapController controllerv1.ConfigMapController, configMapName string) (*v1.ConfigMap, error) { + cm, err := configMapController.Cache().Get(cattleNamespace, configMapName) + if err != nil && !k8serror.IsNotFound(err) { + return nil, err + } + + // if this is the first ever migration initialize the configmap + if cm == nil { + cm = &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + Namespace: cattleNamespace, + }, + Data: make(map[string]string, 1), + } + } + + // we do not migrate in development environments + if rancherversion.Version == "dev" { + return nil, nil + } + + return cm, nil +} + +func createOrUpdateConfigMap(configMapClient controllerv1.ConfigMapClient, cm *v1.ConfigMap) error { + var err error + if cm.ObjectMeta.GetResourceVersion() != "" { + _, err = configMapClient.Update(cm) + } else { + _, err = configMapClient.Create(cm) + } + + return err +} + +// forceUpgradeLogout will delete all dashboard tokens forcing a logout. This is useful when there is a major frontend +// upgrade and we want all users to be sent to a central point. This function will check for the `forceUpgradeLogoutConfig` +// configuration map and only run if the last migrated version is lower than the given `migrationVersion`. +func forceUpgradeLogout(configMapController controllerv1.ConfigMapController, tokenController v3.TokenController, migrationVersion string) error { + cm, err := getConfigMap(configMapController, forceUpgradeLogoutConfig) + if err != nil || cm == nil { + return err + } + + // if no last migration is found we always run force logout + if lastMigration, ok := cm.Data[rancherVersionKey]; ok { + + // if a valid sem ver is found we only migrate if the version is less than the target version + if semver.IsValid(lastMigration) && semver.IsValid(rancherversion.Version) && version.Compare(migrationVersion, lastMigration, "<=") { + return nil + } + + // if an unknown format is given we migrate any time the current version does not equal the last migration + if lastMigration == rancherversion.Version { + return nil + } + } + + logrus.Infof("Detected %s upgrade, forcing logout for all web users", migrationVersion) + + // list all tokens that were created for the dashboard + allTokens, err := tokenController.Cache().List(labels.SelectorFromSet(labels.Set{tokens.TokenKindLabel: "session"})) + if err != nil { + logrus.Error("Failed to list tokens for upgrade forced logout") + return err + } + + // log out all the dashboard users forcing them to be redirected to the login page + for _, token := range allTokens { + err = tokenController.Delete(token.ObjectMeta.Name, &metav1.DeleteOptions{}) + if err != nil && !k8serror.IsNotFound(err) { + logrus.Errorf("Failed to delete token [%s] for upgrade forced logout", token.Name) + } + } + + cm.Data[rancherVersionKey] = rancherversion.Version + return createOrUpdateConfigMap(configMapController, cm) +} + +// forceSystemAndDefaultProjectCreation will set the corresponding conditions on the local cluster object, +// if it exists, to Unknown. This will force the corresponding controller to check that the projects exist +// and create them, if necessary. +func forceSystemAndDefaultProjectCreation(configMapController controllerv1.ConfigMapController, clusterClient v3.ClusterClient) error { + cm, err := getConfigMap(configMapController, forceLocalSystemAndDefaultProjectCreation) + if err != nil || cm == nil { + return err + } + + if cm.Data[projectsCreatedKey] == "true" { + return nil + } + + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + localCluster, err := clusterClient.Get("local", metav1.GetOptions{}) + if err != nil { + if k8serror.IsNotFound(err) { + return nil + } + return err + } + + v32.ClusterConditionDefaultProjectCreated.Unknown(localCluster) + v32.ClusterConditionSystemProjectCreated.Unknown(localCluster) + + _, err = clusterClient.Update(localCluster) + return err + }); err != nil { + return err + } + + cm.Data[projectsCreatedKey] = "true" + return createOrUpdateConfigMap(configMapController, cm) +} + +func forceSystemNamespaceAssignment(configMapController controllerv1.ConfigMapController, projectClient v3.ProjectClient) error { + cm, err := getConfigMap(configMapController, forceSystemNamespacesAssignment) + if err != nil || cm == nil { + return err + } + + if cm.Data[namespacesAssignedKey] == rancherversion.Version { + return nil + } + + err = applyProjectConditionForNamespaceAssignment("authz.management.cattle.io/system-project=true", v32.ProjectConditionSystemNamespacesAssigned, projectClient) + if err != nil { + return err + } + err = applyProjectConditionForNamespaceAssignment("authz.management.cattle.io/default-project=true", v32.ProjectConditionDefaultNamespacesAssigned, projectClient) + if err != nil { + return err + } + + cm.Data[namespacesAssignedKey] = rancherversion.Version + return createOrUpdateConfigMap(configMapController, cm) +} + +func applyProjectConditionForNamespaceAssignment(label string, condition condition.Cond, projectClient v3.ProjectClient) error { + projects, err := projectClient.List("", metav1.ListOptions{LabelSelector: label}) + if err != nil { + return err + } + + for i := range projects.Items { + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + p := &projects.Items[i] + p, err = projectClient.Get(p.Namespace, p.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + condition.Unknown(p) + _, err = projectClient.Update(p) + return err + }); err != nil { + return err + } + } + return nil +} + +// migrateRKEClusterStates sets the `RKEForceUpdate` annotation on all management cluster objects for +// RKE-provisioned clusters. +func migrateRKEClusterStates(w *wrangler.Context) error { + cm, err := getConfigMap(w.Core.ConfigMap(), migrateRKEClusterState) + if err != nil { + return fmt.Errorf("error getting configmap %s: %w", migrateRKEClusterState, err) + } else if cm == nil { + return nil + } + + // Check if this migration has already run. + if cm.Data[rkeClustersAnnotatedForMigrationKey] == "true" { + return nil + } + + // Collect all RKE clusters that need migration. + mgmtClusters, err := w.Mgmt.Cluster().List(metav1.ListOptions{}) + if err != nil { + return fmt.Errorf("error listing management clusters: %w", err) + } + + // Mark all RKE clusters for migration. + for _, cluster := range mgmtClusters.Items { + // Skip this cluster if it's not RKE-provisioned. + if cluster.Spec.RancherKubernetesEngineConfig == nil { + continue + } + + // Retry the cluster object status update on conflict in case something else is updating it at the same time. + if err = retry.RetryOnConflict(retry.DefaultBackoff, func() error { + c, err := w.Mgmt.Cluster().Get(cluster.Name, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("error getting cluster %s: %w", cluster.Name, err) + } + + clusterCopy := c.DeepCopy() + clusterCopy.Annotations[clusterprovisioner.RKEForceUpdate] = "true" + + if _, err = w.Mgmt.Cluster().Update(clusterCopy); err != nil { + return fmt.Errorf("error updating cluster %s: %w", cluster.Name, err) + } + + return nil + }); err != nil { + logrus.Errorf("error updating annotation for cluster %s: %s", cluster.Name, err) + return err + } + } + + cm.Data = map[string]string{ + rkeClustersAnnotatedForMigrationKey: "true", + } + + // Update the configmap that indicates that this migration is complete. + if err := retry.OnError(retry.DefaultBackoff, func(err error) bool { + // Retry all errors. + return true + }, func() error { + return createOrUpdateConfigMap(w.Core.ConfigMap(), cm) + }); err != nil { + return fmt.Errorf("error updating configmap %s: %w", cm.Name, err) + } + + return nil +} + +func migrateCAPIMachineLabelsAndAnnotationsToPlanSecret(w *wrangler.Context) error { + cm, err := getConfigMap(w.Core.ConfigMap(), migrateFromMachineToPlanSecret) + if err != nil || cm == nil { + return err + } + + if cm.Data[capiMigratedKey] == "true" { + return nil + } + + mgmtClusters, err := w.Mgmt.Cluster().List(metav1.ListOptions{}) + if err != nil { + return err + } + + bootstrapLabelExcludes := map[string]struct{}{ + capr.InitNodeMachineIDLabel: {}, + capr.InitNodeLabel: {}, + } + + boostrapAnnotationExcludes := map[string]struct{}{ + capr.DrainAnnotation: {}, + capr.DrainDoneAnnotation: {}, + capr.JoinURLAnnotation: {}, + capr.PostDrainAnnotation: {}, + capr.PreDrainAnnotation: {}, + capr.UnCordonAnnotation: {}, + } + + for _, mgmtCluster := range mgmtClusters.Items { + provClusters, err := w.Provisioning.Cluster().List(mgmtCluster.Spec.FleetWorkspaceName, metav1.ListOptions{}) + if k8serror.IsNotFound(err) || len(provClusters.Items) == 0 { + continue + } else if err != nil { + return err + } + + for _, provCluster := range provClusters.Items { + machines, err := w.CAPI.Machine().List(provCluster.Namespace, metav1.ListOptions{LabelSelector: labels.Set{capi.ClusterNameLabel: provCluster.Name}.String()}) + if err != nil { + return err + } + + otherMachines, err := w.CAPI.Machine().List(provCluster.Namespace, metav1.ListOptions{LabelSelector: labels.Set{capr.ClusterNameLabel: provCluster.Name}.String()}) + if err != nil { + return err + } + + allMachines := append(machines.Items, otherMachines.Items...) + + for _, machine := range allMachines { + if machine.Spec.Bootstrap.ConfigRef == nil || machine.Spec.Bootstrap.ConfigRef.APIVersion != capr.RKEAPIVersion { + continue + } + + planSecrets, err := w.Core.Secret().List(machine.Namespace, metav1.ListOptions{LabelSelector: labels.Set{capr.MachineNameLabel: machine.Name}.String()}) + if err != nil { + return err + } + if len(planSecrets.Items) == 0 { + continue + } + + for _, secret := range planSecrets.Items { + if err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + secret, err := w.Core.Secret().Get(secret.Namespace, secret.Name, metav1.GetOptions{}) + if err != nil { + return err + } + + secret = secret.DeepCopy() + capr.CopyMap(secret.Labels, machine.Labels) + capr.CopyMap(secret.Annotations, machine.Annotations) + _, err = w.Core.Secret().Update(secret) + return err + }); err != nil { + return err + } + } + + if err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + bootstrap, err := w.RKE.RKEBootstrap().Get(machine.Spec.Bootstrap.ConfigRef.Namespace, machine.Spec.Bootstrap.ConfigRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } + bootstrap = bootstrap.DeepCopy() + capr.CopyMapWithExcludes(bootstrap.Labels, machine.Labels, bootstrapLabelExcludes) + capr.CopyMapWithExcludes(bootstrap.Annotations, machine.Annotations, boostrapAnnotationExcludes) + if bootstrap.Spec.ClusterName == "" { + // If the bootstrap spec cluster name is blank, we need to update the bootstrap spec to the correct value + // This is to handle old rkebootstrap objects for unmanaged clusters that did not have the spec properly set + if v, ok := bootstrap.Labels[capi.ClusterNameLabel]; ok && v != "" { + bootstrap.Spec.ClusterName = v + } + } + _, err = w.RKE.RKEBootstrap().Update(bootstrap) + return err + }); err != nil { + return err + } + + if machine.Spec.InfrastructureRef.APIVersion == capr.RKEAPIVersion || machine.Spec.InfrastructureRef.APIVersion == capr.RKEMachineAPIVersion { + gv, err := schema.ParseGroupVersion(machine.Spec.InfrastructureRef.APIVersion) + if err != nil { + // This error should not occur because RKEAPIVersion and RKEMachineAPIVersion are valid + continue + } + + gvk := schema.GroupVersionKind{ + Group: gv.Group, + Version: gv.Version, + Kind: machine.Spec.InfrastructureRef.Kind, + } + if err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + infraMachine, err := w.Dynamic.Get(gvk, machine.Spec.InfrastructureRef.Namespace, machine.Spec.InfrastructureRef.Name) + if err != nil { + return err + } + + d, err := data.Convert(infraMachine.DeepCopyObject()) + if err != nil { + return err + } + + if changed, err := insertOrUpdateCondition(d, summary.NewCondition("Ready", "True", "", "")); err != nil { + return err + } else if changed { + _, err = w.Dynamic.UpdateStatus(&unstructured.Unstructured{Object: d}) + return err + } + return err + }); err != nil { + return err + } + } + } + } + } + + cm.Data[capiMigratedKey] = "true" + return createOrUpdateConfigMap(w.Core.ConfigMap(), cm) +} + +func migrateEncryptionKeyRotationLeader(w *wrangler.Context) error { + cm, err := getConfigMap(w.Core.ConfigMap(), migrateEncryptionKeyRotationLeaderToStatus) + if err != nil || cm == nil { + return err + } + + if cm.Data[encryptionKeyRotationStatusMigratedKey] == "true" { + return nil + } + + mgmtClusters, err := w.Mgmt.Cluster().List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, mgmtCluster := range mgmtClusters.Items { + if err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + cp, err := w.RKE.RKEControlPlane().Get(mgmtCluster.Spec.FleetWorkspaceName, mgmtCluster.Name, metav1.GetOptions{}) + if k8serror.IsNotFound(err) { + return nil + } + if err != nil { + return err + } + leader := cp.Annotations["rke.cattle.io/encrypt-key-rotation-leader"] + if leader == "" { + return nil + } + cp = cp.DeepCopy() + cp.Status.RotateEncryptionKeysLeader = leader + cp, err = w.RKE.RKEControlPlane().UpdateStatus(cp) + if err != nil { + return err + } + cp = cp.DeepCopy() + delete(cp.Annotations, "rke.cattle.io/encrypt-key-rotation-leader") + cp, err = w.RKE.RKEControlPlane().Update(cp) + if err != nil { + return err + } + return nil + }); err != nil { + return err + } + } + + cm.Data[encryptionKeyRotationStatusMigratedKey] = "true" + return createOrUpdateConfigMap(w.Core.ConfigMap(), cm) +} + +func migrateMachinePoolsDynamicSchemaLabel(w *wrangler.Context) error { + cm, err := getConfigMap(w.Core.ConfigMap(), migrateDynamicSchemaToMachinePools) + if err != nil || cm == nil { + return err + } + + if cm.Data[dynamicSchemaMachinePoolsMigratedKey] == "true" { + return nil + } + + mgmtClusters, err := w.Mgmt.Cluster().List(metav1.ListOptions{}) + if err != nil { + return err + } + + for _, mgmtCluster := range mgmtClusters.Items { + provClusters, err := w.Provisioning.Cluster().List(mgmtCluster.Spec.FleetWorkspaceName, metav1.ListOptions{}) + if k8serror.IsNotFound(err) || len(provClusters.Items) == 0 { + continue + } else if err != nil { + return err + } + for _, provCluster := range provClusters.Items { + if provCluster.Spec.RKEConfig == nil { + continue + } + if err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + cluster, err := w.Provisioning.Cluster().Get(provCluster.Namespace, provCluster.Name, metav1.GetOptions{}) + if k8serror.IsNotFound(err) { + return nil + } else if err != nil { + return err + } + cluster = cluster.DeepCopy() + // search for machine pools without the `dynamic-schema-spec` annotation and apply it + for i, machinePool := range cluster.Spec.RKEConfig.MachinePools { + var spec v32.DynamicSchemaSpec + if machinePool.DynamicSchemaSpec != "" && json.Unmarshal([]byte(machinePool.DynamicSchemaSpec), &spec) == nil { + continue + } + nodeConfig := machinePool.NodeConfig + if nodeConfig == nil { + return fmt.Errorf("machine pool node config must not be nil") + } + apiVersion := nodeConfig.APIVersion + if apiVersion != capr.DefaultMachineConfigAPIVersion && apiVersion != "" { + continue + } + ds, err := w.Mgmt.DynamicSchema().Get(strings.ToLower(nodeConfig.Kind), metav1.GetOptions{}) + if err != nil { + return err + } + specJSON, err := json.Marshal(ds.Spec) + if err != nil { + return err + } + cluster.Spec.RKEConfig.MachinePools[i].DynamicSchemaSpec = string(specJSON) + } + _, err = w.Provisioning.Cluster().Update(cluster) + if err != nil { + return err + } + return nil + }); err != nil { + return err + } + } + } + + cm.Data[dynamicSchemaMachinePoolsMigratedKey] = "true" + return createOrUpdateConfigMap(w.Core.ConfigMap(), cm) +} + +func migrateSystemAgentDataDirectory(w *wrangler.Context) error { + cm, err := getConfigMap(w.Core.ConfigMap(), migrateSystemAgentVarDirToDataDirectory) + if err != nil || cm == nil { + return err + } + + if cm.Data[systemAgentVarDirMigratedKey] == "true" { + return nil + } + + provClusters, err := w.Provisioning.Cluster().List("", metav1.ListOptions{}) + if err != nil { + return err + } + + for _, cluster := range provClusters.Items { + systemAgentDataDir := "" + envVars := make([]rkev1.EnvVar, 0, len(cluster.Spec.AgentEnvVars)) + for _, e := range cluster.Spec.AgentEnvVars { + if e.Name == capr.SystemAgentDataDirEnvVar { + // don't break, the webhook allows duplicate entries and the last one would have been the effective data dir + systemAgentDataDir = e.Value + } else { + envVars = append(envVars, e) + } + } + if systemAgentDataDir == "" { + continue + } + + cluster = *cluster.DeepCopy() + cluster.Spec.AgentEnvVars = envVars + cluster.Spec.RKEConfig.DataDirectories.SystemAgent = systemAgentDataDir + _, err = w.Provisioning.Cluster().Update(&cluster) + if err != nil { + return err + } + } + + cm.Data[systemAgentVarDirMigratedKey] = "true" + return createOrUpdateConfigMap(w.Core.ConfigMap(), cm) +} + +func insertOrUpdateCondition(d data.Object, desiredCondition summary.Condition) (bool, error) { + for _, cond := range summary.GetUnstructuredConditions(d) { + if desiredCondition.Equals(cond) { + return false, nil + } + } + + // The conditions must be converted to a map so that DeepCopyJSONValue will + // recognize it as a map instead of a data.Object. + newCond, err := convert.EncodeToMap(desiredCondition.Object) + if err != nil { + return false, err + } + + dConditions := d.Slice("status", "conditions") + conditions := make([]interface{}, len(dConditions)) + found := false + for i, cond := range dConditions { + if cond.String("type") == desiredCondition.Type() { + conditions[i] = newCond + found = true + } else { + conditions[i], err = convert.EncodeToMap(cond) + if err != nil { + return false, err + } + } + } + + if !found { + conditions = append(conditions, newCond) + } + d.SetNested(conditions, "status", "conditions") + + return true, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/rancher.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/rancher.go new file mode 100644 index 0000000..9556615 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rancher/rancher.go @@ -0,0 +1,596 @@ +package rancher + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + "strings" + "time" + + "github.com/Masterminds/semver/v3" + responsewriter "github.com/rancher/apiserver/pkg/middleware" + "github.com/rancher/rancher/pkg/api/norman/customization/kontainerdriver" + steveapi "github.com/rancher/rancher/pkg/api/steve" + "github.com/rancher/rancher/pkg/api/steve/aggregation" + "github.com/rancher/rancher/pkg/api/steve/proxy" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth" + "github.com/rancher/rancher/pkg/auth/audit" + "github.com/rancher/rancher/pkg/auth/requests" + "github.com/rancher/rancher/pkg/controllers/dashboard" + "github.com/rancher/rancher/pkg/controllers/dashboard/apiservice" + "github.com/rancher/rancher/pkg/controllers/dashboard/plugin" + "github.com/rancher/rancher/pkg/controllers/dashboardapi" + managementauth "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/rancher/pkg/controllers/nodedriver" + provisioningv2 "github.com/rancher/rancher/pkg/controllers/provisioningv2/cluster" + "github.com/rancher/rancher/pkg/crds" + dashboardcrds "github.com/rancher/rancher/pkg/crds/dashboard" + dashboarddata "github.com/rancher/rancher/pkg/data/dashboard" + "github.com/rancher/rancher/pkg/features" + mgmntv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/multiclustermanager" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/tls" + "github.com/rancher/rancher/pkg/ui" + "github.com/rancher/rancher/pkg/websocket" + "github.com/rancher/rancher/pkg/wrangler" + aggregation2 "github.com/rancher/steve/pkg/aggregation" + steveauth "github.com/rancher/steve/pkg/auth" + steveserver "github.com/rancher/steve/pkg/server" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/k8scheck" + "github.com/rancher/wrangler/v3/pkg/unstructured" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" + v1 "k8s.io/api/core/v1" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + k8serror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" + k8dynamic "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/util/retry" +) + +const encryptionConfigUpdate = "provisioner.cattle.io/encrypt-migrated" + +type Options struct { + ACMEDomains cli.StringSlice + AddLocal string + Embedded bool + BindHost string + HTTPListenPort int + HTTPSListenPort int + K8sMode string + Debug bool + Trace bool + NoCACerts bool + AuditLogPath string + AuditLogMaxage int + AuditLogMaxsize int + AuditLogMaxbackup int + AuditLevel int + Features string + ClusterRegistry string +} + +type Rancher struct { + Auth steveauth.Middleware + Handler http.Handler + Wrangler *wrangler.Context + Steve *steveserver.Server + + auditLog *audit.LogWriter + authServer *auth.Server + opts *Options +} + +func New(ctx context.Context, clientConfg clientcmd.ClientConfig, opts *Options) (*Rancher, error) { + var ( + authServer *auth.Server + ) + + if opts == nil { + opts = &Options{} + } + + restConfig, err := clientConfg.ClientConfig() + if err != nil { + return nil, err + } + + restConfig, err = setupAndValidationRESTConfig(ctx, restConfig) + if err != nil { + return nil, err + } + + // Run the encryption migration before any controllers run otherwise the fields will be dropped + if err := migrateEncryptionConfig(ctx, restConfig); err != nil { + return nil, err + } + + wranglerContext, err := wrangler.NewContext(ctx, clientConfg, restConfig) + if err != nil { + return nil, err + } + + if err := dashboarddata.EarlyData(ctx, wranglerContext.K8s); err != nil { + return nil, err + } + + if opts.Embedded { + if err := setupRancherService(ctx, restConfig, opts.HTTPSListenPort); err != nil { + return nil, err + } + if err := bumpRancherWebhookIfNecessary(ctx, restConfig); err != nil { + return nil, err + } + } + + wranglerContext.MultiClusterManager = newMCM(wranglerContext, opts) + + // Initialize Features as early as possible + if err := dashboardcrds.CreateFeatureCRD(ctx, restConfig); err != nil { + return nil, err + } + + if err := features.MigrateFeatures(wranglerContext.Mgmt.Feature(), wranglerContext.CRD.CustomResourceDefinition(), wranglerContext.Mgmt.Cluster()); err != nil { + return nil, fmt.Errorf("migrating features: %w", err) + } + features.InitializeFeatures(wranglerContext.Mgmt.Feature(), opts.Features) + + kontainerdriver.RegisterIndexers(wranglerContext) + managementauth.RegisterWranglerIndexers(wranglerContext) + + if features.ProvisioningV2.Enabled() { + // ensure indexers are registered for all replicas + provisioningv2.RegisterIndexers(wranglerContext) + } + + clientSet, err := clientset.NewForConfig(restConfig) + if err != nil { + return nil, fmt.Errorf("failed to create new clientset: %w", err) + } + + // ensure migrated CRDs + if err := crds.EnsureRequired(ctx, clientSet.ApiextensionsV1().CustomResourceDefinitions()); err != nil { + return nil, fmt.Errorf("failed to ensure CRDs: %w", err) + } + + // install all non migrated CRDs + if err := dashboardcrds.Create(ctx, restConfig); err != nil { + return nil, fmt.Errorf("failed to create CRDs: %w", err) + } + + if features.MCM.Enabled() && !features.Fleet.Enabled() { + logrus.Info("fleet can't be turned off when MCM is enabled. Turning on fleet feature") + if err := features.SetFeature(wranglerContext.Mgmt.Feature(), features.Fleet.Name(), true); err != nil { + return nil, err + } + } + + if features.Auth.Enabled() { + authServer, err = auth.NewServer(ctx, restConfig) + if err != nil { + return nil, err + } + } else { + authServer, err = auth.NewAlwaysAdmin() + if err != nil { + return nil, err + } + } + + steveControllers, err := steveserver.NewController(restConfig, &generic.FactoryOptions{SharedControllerFactory: wranglerContext.SharedControllerFactory}) + if err != nil { + return nil, err + } + + steve, err := steveserver.New(ctx, restConfig, &steveserver.Options{ + ServerVersion: settings.ServerVersion.Get(), + Controllers: steveControllers, + AccessSetLookup: wranglerContext.ASL, + AuthMiddleware: steveauth.ExistingContext, + Next: ui.New(wranglerContext.Mgmt.Preference().Cache(), wranglerContext.Mgmt.ClusterRegistrationToken().Cache()), + ClusterRegistry: opts.ClusterRegistry, + SQLCache: features.UISQLCache.Enabled(), + }) + if err != nil { + return nil, err + } + + clusterProxy, err := proxy.NewProxyMiddleware(wranglerContext.K8s.AuthorizationV1(), + wranglerContext.TunnelServer.Dialer, + wranglerContext.Mgmt.Cluster().Cache(), + localClusterEnabled(opts), + steve, + ) + if err != nil { + return nil, err + } + + additionalAPIPreMCM := steveapi.AdditionalAPIsPreMCM(wranglerContext) + additionalAPI, err := steveapi.AdditionalAPIs(ctx, wranglerContext, steve) + if err != nil { + return nil, err + } + + auditLogWriter := audit.NewLogWriter(opts.AuditLogPath, audit.Level(opts.AuditLevel), opts.AuditLogMaxage, opts.AuditLogMaxbackup, opts.AuditLogMaxsize) + auditFilter, err := audit.NewAuditLogMiddleware(auditLogWriter) + if err != nil { + return nil, err + } + aggregationMiddleware := aggregation.NewMiddleware(ctx, wranglerContext.Mgmt.APIService(), wranglerContext.TunnelServer) + + return &Rancher{ + Auth: authServer.Authenticator.Chain( + auditFilter), + Handler: responsewriter.Chain{ + auth.SetXAPICattleAuthHeader, + responsewriter.ContentTypeOptions, + responsewriter.NoCache, + websocket.NewWebsocketHandler, + proxy.RewriteLocalCluster, + clusterProxy, + aggregationMiddleware, + additionalAPIPreMCM, + wranglerContext.MultiClusterManager.Middleware, + authServer.Management, + additionalAPI, + requests.NewRequireAuthenticatedFilter("/v1/", "/v1/management.cattle.io.setting"), + }.Handler(steve), + Wrangler: wranglerContext, + Steve: steve, + auditLog: auditLogWriter, + authServer: authServer, + opts: opts, + }, nil +} + +func (r *Rancher) Start(ctx context.Context) error { + if err := dashboardapi.Register(ctx, r.Wrangler); err != nil { + return err + } + + if err := steveapi.Setup(ctx, r.Steve, r.Wrangler); err != nil { + return err + } + if features.UIExtension.Enabled() { + plugin.Register(ctx, r.Wrangler) + } + + if features.MCM.Enabled() { + // Registers handlers for all rancher replicas running in the local cluster, but not downstream agents + nodedriver.Register(ctx, r.Wrangler) + if err := r.Wrangler.MultiClusterManager.Start(ctx); err != nil { + return err + } + } + + r.Wrangler.OnLeader(func(ctx context.Context) error { + if err := dashboarddata.Add(ctx, r.Wrangler, localClusterEnabled(r.opts), r.opts.AddLocal == "false", r.opts.Embedded); err != nil { + return err + } + if err := r.Wrangler.StartWithTransaction(ctx, func(ctx context.Context) error { + return dashboard.Register(ctx, r.Wrangler, r.opts.Embedded, r.opts.ClusterRegistry) + }); err != nil { + return err + } + + return runMigrations(r.Wrangler) + }) + + if err := r.authServer.Start(ctx, false); err != nil { + return err + } + + r.Wrangler.OnLeader(r.authServer.OnLeader) + r.auditLog.Start(ctx) + + return r.Wrangler.Start(ctx) +} + +func (r *Rancher) ListenAndServe(ctx context.Context) error { + if err := r.Start(ctx); err != nil { + return err + } + + r.Wrangler.MultiClusterManager.Wait(ctx) + + r.startAggregation(ctx) + go r.Steve.StartAggregation(ctx) + if err := tls.ListenAndServe(ctx, r.Wrangler.RESTConfig, + r.Auth(r.Handler), + r.opts.BindHost, + r.opts.HTTPSListenPort, + r.opts.HTTPListenPort, + r.opts.ACMEDomains, + r.opts.NoCACerts); err != nil { + return err + } + + <-ctx.Done() + return ctx.Err() +} + +func (r *Rancher) startAggregation(ctx context.Context) { + aggregation2.Watch(ctx, r.Wrangler.Core.Secret(), namespace.System, "stv-aggregation", r.Handler) +} + +func newMCM(wrangler *wrangler.Context, opts *Options) wrangler.MultiClusterManager { + return multiclustermanager.NewDeferredServer(wrangler, &multiclustermanager.Options{ + RemoveLocalCluster: opts.AddLocal == "false", + LocalClusterEnabled: localClusterEnabled(opts), + Embedded: opts.Embedded, + HTTPSListenPort: opts.HTTPSListenPort, + Debug: opts.Debug, + Trace: opts.Trace, + }) +} + +func setupAndValidationRESTConfig(ctx context.Context, restConfig *rest.Config) (*rest.Config, error) { + restConfig = steveserver.RestConfigDefaults(restConfig) + return restConfig, k8scheck.Wait(ctx, *restConfig) +} + +func localClusterEnabled(opts *Options) bool { + if opts.AddLocal == "true" || opts.AddLocal == "auto" { + return true + } + return false +} + +// setupRancherService will ensure that a Rancher service with a custom endpoint exists that will be used +// to access Rancher +func setupRancherService(ctx context.Context, restConfig *rest.Config, httpsListenPort int) error { + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("error setting up kubernetes clientset while setting up rancher service: %w", err) + } + + service := v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: apiservice.RancherServiceName, + Namespace: namespace.System, + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Protocol: v1.ProtocolTCP, + Port: 443, + TargetPort: intstr.FromInt(httpsListenPort + 1), + }, + }, + }, + } + + refreshService := false + + s, err := clientset.CoreV1().Services(namespace.System).Get(ctx, apiservice.RancherServiceName, metav1.GetOptions{}) + if err != nil { + if k8serror.IsNotFound(err) { + refreshService = true + } else { + return fmt.Errorf("error looking for rancher service: %w", err) + } + } else { + if s.Spec.String() != service.Spec.String() { + refreshService = true + } + } + + if refreshService { + logrus.Debugf("setupRancherService refreshing service") + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if s, err := clientset.CoreV1().Services(namespace.System).Get(ctx, apiservice.RancherServiceName, metav1.GetOptions{}); err != nil { + if k8serror.IsNotFound(err) { + if _, err := clientset.CoreV1().Services(namespace.System).Create(ctx, &service, metav1.CreateOptions{}); err != nil { + return err + } + } else { + return err + } + } else { + s.Spec.Ports = service.Spec.Ports + if _, err := clientset.CoreV1().Services(namespace.System).Update(ctx, s, metav1.UpdateOptions{}); err != nil { + return err + } + } + return nil + }); err != nil { + return fmt.Errorf("setupRancherService error refreshing service: %w", err) + } + } + + ip, err := net.ChooseHostInterface() + if err != nil { + return fmt.Errorf("setupRancherService error getting host IP while setting up rancher service: %w", err) + } + + endpoint := v1.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: apiservice.RancherServiceName, + Namespace: namespace.System, + }, + Subsets: []v1.EndpointSubset{ + { + Addresses: []v1.EndpointAddress{ + { + IP: ip.String(), + }, + }, + Ports: []v1.EndpointPort{ + { + Port: int32(httpsListenPort + 1), + }, + }, + }, + }, + } + + refreshEndpoint := false + e, err := clientset.CoreV1().Endpoints(namespace.System).Get(ctx, apiservice.RancherServiceName, metav1.GetOptions{}) + if err != nil { + if k8serror.IsNotFound(err) { + refreshEndpoint = true + } else { + return fmt.Errorf("error looking for rancher endpoint while setting up rancher service: %w", err) + } + } else { + if e.Subsets[0].String() != endpoint.Subsets[0].String() && len(e.Subsets) != 1 { + logrus.Debugf("setupRancherService subsets did not match, refreshing endpoint (%s vs %s)", e.Subsets[0].String(), endpoint.String()) + refreshEndpoint = true + } + } + + if refreshEndpoint { + logrus.Debugf("setupRancherService refreshing endpoint") + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + if e, err := clientset.CoreV1().Endpoints(namespace.System).Get(ctx, apiservice.RancherServiceName, metav1.GetOptions{}); err != nil { + if k8serror.IsNotFound(err) { + if _, err := clientset.CoreV1().Endpoints(namespace.System).Create(ctx, &endpoint, metav1.CreateOptions{}); err != nil { + return err + } + } else { + return err + } + } else { + e.Subsets = endpoint.Subsets + if _, err := clientset.CoreV1().Endpoints(namespace.System).Update(ctx, e, metav1.UpdateOptions{}); err != nil { + return err + } + } + return nil + }); err != nil { + return fmt.Errorf("setupRancherService error refreshing endpoint: %w", err) + } + } + return nil +} + +// bumpRancherServiceVersion bumps the version of rancher-webhook if it is detected that the version is less than +// v0.2.2-alpha1. This is because the version of rancher-webhook less than v0.2.2-alpha1 does not support Kubernetes v1.22+ +// This should only be called when Rancher is run in a Docker container because the Kubernetes version and Rancher version +// are bumped at the same time. In a Kubernetes cluster, usually the Rancher version is bumped when the cluster is upgraded. +func bumpRancherWebhookIfNecessary(ctx context.Context, restConfig *rest.Config) error { + v := os.Getenv("CATTLE_RANCHER_WEBHOOK_VERSION") + webhookVersionParts := strings.Split(v, "+up") + if len(webhookVersionParts) != 2 { + return nil + } else if !strings.HasPrefix(webhookVersionParts[1], "v") { + webhookVersionParts[1] = "v" + webhookVersionParts[1] + } + + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return fmt.Errorf("error setting up kubernetes clientset: %w", err) + } + + rancherWebhookDeployment, err := clientset.AppsV1().Deployments(namespace.System).Get(ctx, "rancher-webhook", metav1.GetOptions{}) + if err != nil { + if k8serror.IsNotFound(err) { + return nil + } + return err + } + + for i, c := range rancherWebhookDeployment.Spec.Template.Spec.Containers { + imageVersionParts := strings.Split(c.Image, ":") + if c.Name != "rancher-webhook" || len(imageVersionParts) != 2 { + continue + } + + semVer, err := semver.NewVersion(strings.TrimPrefix(imageVersionParts[1], "v")) + if err != nil { + continue + } + if semVer.LessThan(semver.MustParse("0.2.2-alpha1")) { + rancherWebhookDeployment = rancherWebhookDeployment.DeepCopy() + c.Image = fmt.Sprintf("%s:%s", imageVersionParts[0], webhookVersionParts[1]) + rancherWebhookDeployment.Spec.Template.Spec.Containers[i] = c + + _, err = clientset.AppsV1().Deployments(namespace.System).Update(ctx, rancherWebhookDeployment, metav1.UpdateOptions{}) + return err + } + } + + return nil +} + +// migrateEncryptionConfig uses the dynamic client to get all clusters and then marshals them through the +// standard go JSON package using the updated backing structs in RKE that include JSON tags. The k8s JSON +// tools are strict with casing so the fields would be dropped before getting saved back in the proper casing +// if any controller touches the cluster first. See https://github.com/rancher/rancher/issues/31385 +func migrateEncryptionConfig(ctx context.Context, restConfig *rest.Config) error { + dynamicClient, err := k8dynamic.NewForConfig(restConfig) + if err != nil { + return err + } + clusterDynamicClient := dynamicClient.Resource(mgmntv3.ClusterGroupVersionResource) + + clusters, err := clusterDynamicClient.List(ctx, metav1.ListOptions{}) + if err != nil { + if !k8serror.IsNotFound(err) { + return err + } + // IsNotFound error means the CRD type doesn't exist in the cluster, indicating this is the first Rancher startup + return nil + } + + var allErrors error + + for _, c := range clusters.Items { + err := wait.PollImmediateInfinite(100*time.Millisecond, func() (bool, error) { + rawDynamicCluster, err := clusterDynamicClient.Get(ctx, c.GetName(), metav1.GetOptions{}) + if err != nil { + return false, err + } + + annotations := rawDynamicCluster.GetAnnotations() + if annotations != nil && annotations[encryptionConfigUpdate] == "true" { + return true, nil + } + + clusterBytes, err := rawDynamicCluster.MarshalJSON() + if err != nil { + return false, fmt.Errorf("error trying to Marshal dynamic cluster: %w", err) + } + + var cluster *v3.Cluster + + if err := json.Unmarshal(clusterBytes, &cluster); err != nil { + return false, fmt.Errorf("error trying to Unmarshal dynamicCluster into v3 cluster: %w", err) + } + + if cluster.Annotations == nil { + cluster.Annotations = make(map[string]string) + } + cluster.Annotations[encryptionConfigUpdate] = "true" + + u, err := unstructured.ToUnstructured(cluster) + if err != nil { + return false, err + } + + _, err = clusterDynamicClient.Update(ctx, u, metav1.UpdateOptions{}) + if err == nil { + return true, nil + } + if k8serror.IsConflict(err) || k8serror.IsServiceUnavailable(err) || k8serror.IsInternalError(err) { + return false, nil + } + return false, err + }) + allErrors = errors.Join(err, allErrors) + } + return allErrors +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/access_control.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/access_control.go new file mode 100644 index 0000000..b89294e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/access_control.go @@ -0,0 +1,39 @@ +package rbac + +import ( + "context" + + "github.com/rancher/norman/types" + "github.com/rancher/steve/pkg/accesscontrol" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" +) + +func NewAccessControl(ctx context.Context, clusterName string, rbacClient v1.Interface) types.AccessControl { + asl := accesscontrol.NewAccessStore(ctx, true, rbacClient) + return NewAccessControlWithASL(clusterName, asl) +} + +func NewAccessControlWithASL(clusterName string, asl accesscontrol.AccessSetLookup) types.AccessControl { + return newContextBased(func(ctx *types.APIContext) (types.AccessControl, bool) { + cache, ok := ctx.Request.Context().Value(contextKey{}).(*accessControlCache) + if !ok { + return nil, false + } + + cache.RLock() + ac, ok := cache.cache[clusterName] + if ok { + if u, ok := ac.(*userCachedAccess); !ok || !u.Expired() { + cache.RUnlock() + return ac, true + } + } + cache.RUnlock() + + cache.Lock() + defer cache.Unlock() + ac = newUserLookupAccess(ctx, asl) + cache.cache[clusterName] = ac + return ac, true + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common.go new file mode 100644 index 0000000..dbda6f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common.go @@ -0,0 +1,294 @@ +package rbac + +import ( + "crypto/sha256" + "encoding/base32" + "strings" + + "github.com/pkg/errors" + "github.com/rancher/norman/types" + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + v32 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + k8srbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + wranglerName "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + NamespaceID = "namespaceId" + ProjectID = "projectId" + ClusterID = "clusterId" + GlobalAdmin = "admin" + GlobalRestrictedAdmin = "restricted-admin" + ClusterCRDsClusterRole = "cluster-crd-clusterRole" + RestrictedAdminClusterRoleBinding = "restricted-admin-rb-cluster" + ProjectCRDsClusterRole = "project-crd-clusterRole" + RestrictedAdminProjectRoleBinding = "restricted-admin-rb-project" + RestrictedAdminCRForClusters = "restricted-admin-cr-clusters" + RestrictedAdminCRBForClusters = "restricted-admin-crb-clusters" +) + +// BuildSubjectFromRTB This function will generate +// PRTB and CRTB to the subject with user, group +// or service account +func BuildSubjectFromRTB(object metav1.Object) (rbacv1.Subject, error) { + var userName, groupPrincipalName, groupName, name, kind, sa, namespace string + switch rtb := object.(type) { + case *v3.ProjectRoleTemplateBinding: + userName = rtb.UserName + groupPrincipalName = rtb.GroupPrincipalName + groupName = rtb.GroupName + sa = rtb.ServiceAccount + case *v3.ClusterRoleTemplateBinding: + userName = rtb.UserName + groupPrincipalName = rtb.GroupPrincipalName + groupName = rtb.GroupName + default: + objectName := "" + if object != nil { + objectName = object.GetName() + } + return rbacv1.Subject{}, errors.Errorf("unrecognized roleTemplateBinding type: %v", objectName) + } + + if userName != "" { + name = userName + kind = "User" + } + + if groupPrincipalName != "" { + if name != "" { + return rbacv1.Subject{}, errors.Errorf("roletemplatebinding has more than one subject fields set: %v", object.GetName()) + } + name = groupPrincipalName + kind = "Group" + } + + if groupName != "" { + if name != "" { + return rbacv1.Subject{}, errors.Errorf("roletemplatebinding has more than one subject fields set: %v", object.GetName()) + } + name = groupName + kind = "Group" + } + + if sa != "" { + parts := strings.SplitN(sa, ":", 2) + if len(parts) < 2 { + return rbacv1.Subject{}, errors.Errorf("service account %s of projectroletemplatebinding is invalid: %v", sa, object.GetName()) + } + namespace = parts[0] + name = parts[1] + kind = "ServiceAccount" + } + + if name == "" { + return rbacv1.Subject{}, errors.Errorf("roletemplatebinding doesn't have any subject fields set: %v", object.GetName()) + } + + // apiGroup default for both User and Group + apiGroup := "rbac.authorization.k8s.io" + + if kind == "ServiceAccount" { + // ServiceAccount default is empty string + apiGroup = "" + } + return rbacv1.Subject{ + Namespace: namespace, + Kind: kind, + Name: name, + APIGroup: apiGroup, + }, nil +} + +func GrbCRBName(grb *v3.GlobalRoleBinding) string { + var prefix string + if grb.GlobalRoleName == GlobalAdmin { + prefix = "globaladmin-" + } else { + prefix = "globalrestrictedadmin-" + } + return prefix + GetGRBTargetKey(grb) +} + +// GetGRBSubject creates and returns a subject that is +// determined by inspecting the the GRB's target fields +func GetGRBSubject(grb *v3.GlobalRoleBinding) rbacv1.Subject { + kind := "User" + name := grb.UserName + if name == "" && grb.GroupPrincipalName != "" { + kind = "Group" + name = grb.GroupPrincipalName + } + + return rbacv1.Subject{ + Kind: kind, + Name: name, + APIGroup: rbacv1.GroupName, + } +} + +// getGRBTargetKey returns a key that uniquely identifies the given GRB's target. +// If a user is being targeted, then the user's name is returned. +// Otherwise, the group principal name is converted to a valid user string and +// is returned. +func GetGRBTargetKey(grb *v3.GlobalRoleBinding) string { + name := grb.UserName + + if name == "" { + hasher := sha256.New() + hasher.Write([]byte(grb.GroupPrincipalName)) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + name = "u-" + strings.ToLower(sha) + } + return name +} + +// Returns object with available information to check against users permissions, used in combination with CanDo +func ObjFromContext(apiContext *types.APIContext, resource *types.RawResource) map[string]interface{} { + var obj map[string]interface{} + if resource != nil && resource.Values["id"] != nil { + obj = resource.Values + } + if obj == nil { + obj = map[string]interface{}{ + "id": apiContext.ID, + } + // collection endpoint without id needs to know which cluster-namespace for rbac check + if apiContext.Query.Get(ClusterID) != "" { + obj[NamespaceID] = apiContext.Query.Get(ClusterID) + } + if apiContext.Query.Get(ProjectID) != "" { + _, obj[NamespaceID] = ref.Parse(apiContext.Query.Get(ProjectID)) + } + } + return obj +} + +func TypeFromContext(apiContext *types.APIContext, resource *types.RawResource) string { + if resource == nil { + return apiContext.Type + } + return resource.Type +} + +func GetRTBLabel(objMeta metav1.ObjectMeta) string { + return wranglerName.SafeConcatName(objMeta.Namespace + "_" + objMeta.Name) +} + +// NameForRoleBinding returns a deterministic name for a RoleBinding with the provided namespace, roleName, and subject +func NameForRoleBinding(namespace string, role rbacv1.RoleRef, subject rbacv1.Subject) string { + var name strings.Builder + name.WriteString("rb-") + name.WriteString(getBindingHash(namespace, role, subject)) + nm := name.String() + logrus.Debugf("RoleBinding with namespace=%s role.kind=%s role.name=%s subject.kind=%s subject.name=%s has name: %s", namespace, role.Kind, role.Name, subject.Kind, subject.Name, nm) + return nm +} + +// NameForClusterRoleBinding returns a deterministic name for a ClusterRoleBinding with the provided roleName and subject +func NameForClusterRoleBinding(role rbacv1.RoleRef, subject rbacv1.Subject) string { + var name strings.Builder + name.WriteString("crb-") + name.WriteString(getBindingHash("", role, subject)) + nm := name.String() + logrus.Debugf("ClusterRoleBinding with role.kind=%s role.name=%s subject.kind=%s subject.name=%s has name: %s", role.Kind, role.Name, subject.Kind, subject.Name, nm) + return nm +} + +// getBindingHash returns a hash created from the passed in arguments +// uses base32 encoding for hash, since all characters in encoding scheme are valid in k8s resource names +// probability of collision is: 1/32^10 == 1/(2^5)^10 == 1/2^50 (sufficiently low) +func getBindingHash(namespace string, role rbacv1.RoleRef, subject rbacv1.Subject) string { + var input strings.Builder + input.WriteString(namespace) + input.WriteString(role.Kind) + input.WriteString(role.Name) + input.WriteString(subject.Kind) + input.WriteString(subject.Name) + + hasher := sha256.New() + hasher.Write([]byte(input.String())) + digest := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil)) + return strings.ToLower(digest[:10]) +} + +// RulesFromTemplate gets all rules from the template and all referenced templates +func RulesFromTemplate(clusterRoles k8srbacv1.ClusterRoleCache, roleTemplates v32.RoleTemplateCache, rt *v3.RoleTemplate) ([]rbacv1.PolicyRule, error) { + var rules []rbacv1.PolicyRule + var err error + templatesSeen := make(map[string]bool) + + // Kickoff gathering rules + rules, err = gatherRules(clusterRoles, roleTemplates, rt, rules, templatesSeen) + if err != nil { + return rules, err + } + return rules, nil +} + +// gatherRules appends the rules from current template and does a recursive call to get all inherited roles referenced +func gatherRules(clusterRoles k8srbacv1.ClusterRoleCache, roleTemplates v32.RoleTemplateCache, rt *v3.RoleTemplate, rules []rbacv1.PolicyRule, seen map[string]bool) ([]rbacv1.PolicyRule, error) { + seen[rt.Name] = true + + if rt.External { + if rt.ExternalRules != nil { + rules = append(rules, rt.ExternalRules...) + } else if rt.Context == "cluster" { + cr, err := clusterRoles.Get(rt.Name) + if err != nil { + return nil, err + } + rules = append(rules, cr.Rules...) + } + } + + rules = append(rules, rt.Rules...) + + for _, r := range rt.RoleTemplateNames { + // If we have already seen the roleTemplate, skip it + if seen[r] { + continue + } + next, err := roleTemplates.Get(r) + if err != nil { + return nil, err + } + rules, err = gatherRules(clusterRoles, roleTemplates, next, rules, seen) + if err != nil { + return nil, err + } + } + return rules, nil +} + +func ProvisioningClusterAdminName(cluster *provv1.Cluster) string { + return wranglerName.SafeConcatName("crt", cluster.Name, "cluster-owner") +} + +func RuleGivesResourceAccess(rule rbacv1.PolicyRule, resourceName string) bool { + if !isRuleInTargetAPIGroup(rule) { + // if we don't list the target api group, don't bother looking for the resources + return false + } + for _, resource := range rule.Resources { + if resource == resourceName || resource == "*" { + return true + } + } + return false +} + +func isRuleInTargetAPIGroup(rule rbacv1.PolicyRule) bool { + for _, group := range rule.APIGroups { + if group == mgmt.GroupName || group == "*" { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common_test.go new file mode 100644 index 0000000..078431e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/common_test.go @@ -0,0 +1,260 @@ +package rbac + +import ( + "fmt" + "reflect" + "strings" + "testing" + + "github.com/rancher/norman/types" + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_BuildSubjectFromRTB(t *testing.T) { + type testCase struct { + from metav1.Object + to rbacv1.Subject + iserr bool + } + + userSubject := rbacv1.Subject{ + Kind: "User", + Name: "tmp-user", + APIGroup: "rbac.authorization.k8s.io", + } + + groupSubject := rbacv1.Subject{ + Kind: "Group", + Name: "tmp-group", + APIGroup: "rbac.authorization.k8s.io", + } + + saSubject := rbacv1.Subject{ + Kind: "ServiceAccount", + Name: "tmp-sa", + Namespace: "tmp-namespace", + APIGroup: "", + } + + testCases := []testCase{ + testCase{ + from: nil, + iserr: true, + }, + testCase{ + from: &v3.ProjectRoleTemplateBinding{ + UserName: userSubject.Name, + }, + to: userSubject, + }, + testCase{ + from: &v3.ProjectRoleTemplateBinding{ + GroupName: groupSubject.Name, + }, + to: groupSubject, + }, + testCase{ + from: &v3.ProjectRoleTemplateBinding{ + ServiceAccount: fmt.Sprintf("%s:%s", saSubject.Namespace, saSubject.Name), + }, + to: saSubject, + }, + testCase{ + from: &v3.ClusterRoleTemplateBinding{ + UserName: userSubject.Name, + }, + to: userSubject, + }, + testCase{ + from: &v3.ClusterRoleTemplateBinding{ + GroupName: groupSubject.Name, + }, + to: groupSubject, + }, + testCase{ + from: &v3.ProjectRoleTemplateBinding{ + ServiceAccount: "wrong-format", + }, + iserr: true, + }, + } + + for _, tcase := range testCases { + output, err := BuildSubjectFromRTB(tcase.from) + if tcase.iserr && err == nil { + t.Errorf("roletemplatebinding %v should return error", tcase.from) + } else if !tcase.iserr && !reflect.DeepEqual(tcase.to, output) { + t.Errorf("the subject %v from roletemplatebinding %v is mismatched, expect %v", output, tcase.from, tcase.to) + } + } +} + +func Test_TypeFromContext(t *testing.T) { + type testCase struct { + apiContext *types.APIContext + resource *types.RawResource + expectedType string + } + + testCases := []testCase{ + { + apiContext: &types.APIContext{ + Type: "catalog", + }, + resource: nil, + expectedType: "catalog", + }, + { + apiContext: &types.APIContext{ + Type: "subscribe", + }, + resource: &types.RawResource{ + Type: "catalog", + }, + expectedType: "catalog", + }, + } + + for _, tcase := range testCases { + outputType := TypeFromContext(tcase.apiContext, tcase.resource) + if tcase.expectedType != outputType { + t.Errorf("resource type %s is mismatched, expect %s", outputType, tcase.expectedType) + } + } +} + +func Test_RuleGivesResourceAccess(t *testing.T) { + type testCase struct { + rule rbacv1.PolicyRule + resourceName string + expected bool + } + createTestCase := func(apiGroup string, ruleResource string, requestResource string, outcome bool) testCase { + return testCase{ + rule: rbacv1.PolicyRule{ + APIGroups: []string{ + apiGroup, + }, + Verbs: []string{ + "*", + }, + Resources: []string{ + ruleResource, + }, + }, + resourceName: requestResource, + expected: outcome, + } + } + + createMultiGroupResourceTestCase := func(apiGroups []string, resources []string, requestResource string, outcome bool) testCase { + return testCase{ + rule: rbacv1.PolicyRule{ + APIGroups: apiGroups, + Verbs: []string{ + "*", + }, + Resources: resources, + }, + resourceName: requestResource, + expected: outcome, + } + } + + testCases := []testCase{ + createTestCase("*", "test", "test", true), + createTestCase("*", "test", "nottest", false), + createTestCase("*", "*", "test", true), + createTestCase(mgmt.GroupName, "test", "test", true), + createTestCase(mgmt.GroupName, "test", "nottest", false), + createTestCase(mgmt.GroupName, "*", "test", true), + createTestCase("fake.company.io", "test", "test", false), + createTestCase("fake.company.io", "test", "nottest", false), + createTestCase("fake.company.io", "*", "nottest", false), + createMultiGroupResourceTestCase([]string{"fake.company.io", mgmt.GroupName}, []string{"test"}, "test", true), + createMultiGroupResourceTestCase([]string{"fake.company.io", mgmt.GroupName}, []string{"test"}, "nottest", false), + createMultiGroupResourceTestCase([]string{"fake.company.io", mgmt.GroupName}, []string{"*"}, "test", true), + createMultiGroupResourceTestCase([]string{"fake.company.io", mgmt.GroupName}, []string{"nottest", "test"}, "test", true), + createMultiGroupResourceTestCase([]string{"fake.company.io", "*"}, []string{"nottest", "test"}, "test", true), + createMultiGroupResourceTestCase([]string{"fake.company.io", "*"}, []string{"nottest", "test"}, "supertest", false), + createMultiGroupResourceTestCase([]string{"fake.company.io", "faker.company.io"}, []string{"nottest", "test"}, "test", false), + } + + for _, tcase := range testCases { + givesAccess := RuleGivesResourceAccess(tcase.rule, tcase.resourceName) + if tcase.expected != givesAccess { + t.Errorf("got %t, expected %t, for rule %v resource %v", givesAccess, tcase.expected, tcase.rule, tcase.resourceName) + } + } +} + +func TestGetRTBLabel(t *testing.T) { + t.Parallel() + tests := []struct { + name string + metadata metav1.ObjectMeta + output string + }{ + { + name: "empty strings for name and namespace", + metadata: metav1.ObjectMeta{ + Name: "", + Namespace: "", + }, + output: "_", + }, + { + name: "short name and namespace", + metadata: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + output: "default_foo", + }, + { + name: "longer name with whole string being shorter than 63 characters", + metadata: metav1.ObjectMeta{ + Name: strings.Repeat("rottweiler", 5), + Namespace: "default", + }, + output: "default_rottweilerrottweilerrottweilerrottweilerrottweiler", + }, + { + name: "longer name with whole string being longer than 63 characters", + metadata: metav1.ObjectMeta{ + Name: strings.Repeat("rottweiler", 10), + Namespace: "default", + }, + output: "default_rottweilerrottweilerrottweilerrottweilerrottweile-c4636", + }, + { + name: "longer namespace with whole string being shorter than 63 characters", + metadata: metav1.ObjectMeta{ + Name: "rottweiler", + Namespace: strings.Repeat("default", 5), + }, + output: "defaultdefaultdefaultdefaultdefault_rottweiler", + }, + { + name: "longer namespace with whole string being longer than 63 characters", + metadata: metav1.ObjectMeta{ + Name: "rottweiler", + Namespace: strings.Repeat("default", 8), + }, + output: "defaultdefaultdefaultdefaultdefaultdefaultdefaultdefault-829c4a", + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + if got := GetRTBLabel(test.metadata); got != test.output { + t.Errorf("expected %s, but got %s", test.output, got) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/context_access_control.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/context_access_control.go new file mode 100644 index 0000000..8e917ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/context_access_control.go @@ -0,0 +1,95 @@ +package rbac + +import ( + "github.com/rancher/norman/authorization" + "github.com/rancher/norman/types" +) + +type contextKey struct{} + +type contextBased struct { + all authorization.AllAccess + lookup contextLookup +} + +type contextLookup func(ctx *types.APIContext) (types.AccessControl, bool) + +func newContextBased(lookup contextLookup) types.AccessControl { + return &contextBased{ + lookup: lookup, + } +} + +func (c *contextBased) Expire(apiContext *types.APIContext, schema *types.Schema) { + ac, ok := c.lookup(apiContext) + if !ok { + return + } + if e, ok := ac.(types.Expire); ok { + e.Expire(apiContext, schema) + } +} + +func (c *contextBased) CanCreate(apiContext *types.APIContext, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanCreate(apiContext, schema) + } + return c.all.CanCreate(apiContext, schema) +} + +func (c *contextBased) CanList(apiContext *types.APIContext, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanList(apiContext, schema) + } + return c.all.CanList(apiContext, schema) +} + +func (c *contextBased) CanGet(apiContext *types.APIContext, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanGet(apiContext, schema) + } + return c.all.CanGet(apiContext, schema) +} + +func (c *contextBased) CanUpdate(apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanUpdate(apiContext, obj, schema) + } + return c.all.CanUpdate(apiContext, obj, schema) +} + +func (c *contextBased) CanDelete(apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanDelete(apiContext, obj, schema) + } + return c.all.CanDelete(apiContext, obj, schema) +} + +func (c *contextBased) CanDo(apiGroup, resource, verb string, apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + ac, ok := c.lookup(apiContext) + if ok { + return ac.CanDo(apiGroup, resource, verb, apiContext, obj, schema) + } + return c.all.CanDo(apiGroup, resource, verb, apiContext, obj, schema) +} + +func (c *contextBased) Filter(apiContext *types.APIContext, schema *types.Schema, obj map[string]interface{}, context map[string]string) map[string]interface{} { + ac, ok := c.lookup(apiContext) + if ok { + return ac.Filter(apiContext, schema, obj, context) + } + return obj +} + +func (c *contextBased) FilterList(apiContext *types.APIContext, schema *types.Schema, obj []map[string]interface{}, context map[string]string) []map[string]interface{} { + ac, ok := c.lookup(apiContext) + if ok { + return ac.FilterList(apiContext, schema, obj, context) + } + return obj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/user_based.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/user_based.go new file mode 100644 index 0000000..b567c7c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rbac/user_based.go @@ -0,0 +1,146 @@ +package rbac + +import ( + "context" + "fmt" + "net/http" + "strings" + "sync" + + "github.com/rancher/norman/authorization" + "github.com/rancher/norman/httperror" + "github.com/rancher/norman/types" + "github.com/rancher/steve/pkg/accesscontrol" + "github.com/rancher/steve/pkg/auth" + schema2 "k8s.io/apimachinery/pkg/runtime/schema" + user2 "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/client-go/transport" +) + +type accessControlCache struct { + sync.RWMutex + cache map[string]types.AccessControl +} + +func NewAccessControlHandler() auth.Middleware { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + val := &accessControlCache{ + cache: map[string]types.AccessControl{}, + } + ctx := context.WithValue(req.Context(), contextKey{}, val) + req = req.WithContext(ctx) + next.ServeHTTP(rw, req) + }) + } +} + +func newUserLookupAccess(ctx *types.APIContext, accessStore accesscontrol.AccessSetLookup) types.AccessControl { + userName := ctx.Request.Header.Get(transport.ImpersonateUserHeader) + groups := ctx.Request.Header[transport.ImpersonateGroupHeader] + user := &user2.DefaultInfo{ + Name: userName, + Groups: groups, + } + accessSet := accessStore.AccessFor(user) + return &userCachedAccess{ + access: accessSet, + } +} + +type userCachedAccess struct { + authorization.AllAccess + expired bool + access *accesscontrol.AccessSet +} + +func (a *userCachedAccess) Expire(apiContext *types.APIContext, schema *types.Schema) { + a.expired = true +} + +func (a *userCachedAccess) Expired() bool { + return a.expired +} + +func (a *userCachedAccess) CanDo(apiGroup, resource, verb string, apiContext *types.APIContext, obj map[string]interface{}, schema *types.Schema) error { + name, ns := getNameAndNS(obj) + if !a.access.Grants(verb, schema2.GroupResource{ + Group: apiGroup, + Resource: resource, + }, ns, name) { + return httperror.NewAPIError(httperror.PermissionDenied, fmt.Sprintf("can not %v %v ", verb, schema.ID)) + } + return nil +} + +func (a *userCachedAccess) FilterList(apiContext *types.APIContext, schema *types.Schema, objs []map[string]interface{}, context map[string]string) []map[string]interface{} { + apiGroup := context["apiGroup"] + resource := context["resource"] + + if resource == "" { + return objs + } + + if len(objs) == 0 { + return objs + } + + gr := schema2.GroupResource{ + Group: apiGroup, + Resource: resource, + } + + result := make([]map[string]interface{}, 0, len(objs)) + for _, obj := range objs { + name, ns := getNameAndNS(obj) + if a.access.Grants("list", gr, ns, name) || a.access.Grants("get", gr, ns, name) { + result = append(result, obj) + } + } + return result +} + +func (a *userCachedAccess) Filter(apiContext *types.APIContext, schema *types.Schema, obj map[string]interface{}, context map[string]string) map[string]interface{} { + apiGroup := context["apiGroup"] + resource := context["resource"] + + if resource == "" { + return obj + } + + name, ns := getNameAndNS(obj) + if a.access.Grants("list", schema2.GroupResource{ + Group: apiGroup, + Resource: resource, + }, ns, name) { + return obj + } + + if a.access.Grants("get", schema2.GroupResource{ + Group: apiGroup, + Resource: resource, + }, ns, name) { + return obj + } + + return nil +} + +func getNameAndNS(obj map[string]interface{}) (string, string) { + var id string + var namespace string + + if obj != nil { + id, _ = obj["id"].(string) + namespace, _ = obj["namespaceId"].(string) + if namespace == "" { + pieces := strings.Split(id, ":") + if len(pieces) == 2 { + namespace = pieces[0] + } + } + } + + id = strings.TrimPrefix(id, namespace+":") + return id, namespace +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ref/parse.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ref/parse.go new file mode 100644 index 0000000..25500ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ref/parse.go @@ -0,0 +1,38 @@ +package ref + +import ( + "fmt" + "strings" + + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" +) + +var NodeNotFound = "can not build dialer to" + +func IsNodeNotFound(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), NodeNotFound) +} + +func FromStrings(namespace, name string) string { + return fmt.Sprintf("%s:%s", namespace, name) +} + +func Ref(obj runtime.Object) string { + objMeta, _ := meta.Accessor(obj) + if objMeta.GetNamespace() == "" { + return objMeta.GetName() + } + return FromStrings(objMeta.GetNamespace(), objMeta.GetName()) +} + +func Parse(ref string) (namespace string, name string) { + parts := strings.SplitN(ref, ":", 2) + if len(parts) == 1 { + return "", parts[0] + } + return parts[0], parts[1] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcelink/resourcelink.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcelink/resourcelink.go new file mode 100644 index 0000000..e8cdbcb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcelink/resourcelink.go @@ -0,0 +1,14 @@ +package resourcelink + +var ExportResourcePrefixMappings = map[string]string{ + "pods": "api/v1", + "configmaps": "api/v1", + "services": "api/v1", + "replicationcontrollers": "api/v1", + "deployments": "apis/apps/v1", + "daemonsets": "apis/apps/v1", + "replicasets": "apis/apps/v1", + "statefulsets": "apis/apps/v1", + "jobs": "apis/batch/v1", + "cronjobs": "apis/batch/v1beta1", +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcequota/quota_validate.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcequota/quota_validate.go new file mode 100644 index 0000000..2b7eec3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/resourcequota/quota_validate.go @@ -0,0 +1,74 @@ +package resourcequota + +import ( + "sync" + "time" + + "github.com/rancher/norman/types/convert" + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + api "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/cache" + quota "k8s.io/apiserver/pkg/quota/v1" +) + +var ( + projectLockCache = cache.NewLRUExpireCache(1000) +) + +func GetProjectLock(projectID string) *sync.Mutex { + val, ok := projectLockCache.Get(projectID) + if !ok { + projectLockCache.Add(projectID, &sync.Mutex{}, time.Hour) + val, _ = projectLockCache.Get(projectID) + } + mu := val.(*sync.Mutex) + return mu +} + +func IsQuotaFit(nsLimit *v32.ResourceQuotaLimit, nsLimits []*v32.ResourceQuotaLimit, projectLimit *v32.ResourceQuotaLimit) (bool, api.ResourceList, error) { + nssResourceList := api.ResourceList{} + nsResourceList, err := ConvertLimitToResourceList(nsLimit) + if err != nil { + return false, nil, err + } + nssResourceList = quota.Add(nssResourceList, nsResourceList) + + for _, nsLimit := range nsLimits { + nsResourceList, err := ConvertLimitToResourceList(nsLimit) + if err != nil { + return false, nil, err + } + nssResourceList = quota.Add(nssResourceList, nsResourceList) + } + + projectResourceList, err := ConvertLimitToResourceList(projectLimit) + if err != nil { + return false, nil, err + } + + _, exceeded := quota.LessThanOrEqual(nssResourceList, projectResourceList) + // Include resources with negative values among exceeded resources. + exceeded = append(exceeded, quota.IsNegative(nsResourceList)...) + if len(exceeded) == 0 { + return true, nil, nil + } + failedHard := quota.Mask(nssResourceList, exceeded) + return false, failedHard, nil +} + +func ConvertLimitToResourceList(limit *v32.ResourceQuotaLimit) (api.ResourceList, error) { + toReturn := api.ResourceList{} + converted, err := convert.EncodeToMap(limit) + if err != nil { + return nil, err + } + for key, value := range converted { + q, err := resource.ParseQuantity(convert.ToString(value)) + if err != nil { + return nil, err + } + toReturn[api.ResourceName(key)] = q + } + return toReturn, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs.go new file mode 100644 index 0000000..bdbc5bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs.go @@ -0,0 +1,290 @@ +package rkecerts + +import ( + "bytes" + "crypto/md5" + "crypto/rsa" + "crypto/x509" + "io/ioutil" + "os" + "path/filepath" + + rketypes "github.com/rancher/rke/types" + + "context" + + "fmt" + "reflect" + "sort" + "strings" + "time" + + "github.com/ghodss/yaml" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/kontainer-engine/drivers/rke/rkecerts" + "github.com/rancher/rancher/pkg/librke" + "github.com/rancher/rke/pki" + "github.com/rancher/rke/pki/cert" + "github.com/sirupsen/logrus" + k8sclientv1 "k8s.io/client-go/tools/clientcmd/api/v1" +) + +const ( + bundleFile = "./management-state/certs/bundle.json" +) + +type Bundle struct { + certs map[string]pki.CertificatePKI +} + +func NewBundle(certs map[string]pki.CertificatePKI) *Bundle { + return &Bundle{ + certs: certs, + } +} + +func Unmarshal(input string) (*Bundle, error) { + certs, err := rkecerts.LoadString(input) + return NewBundle(certs), err +} + +func (b *Bundle) Certs() map[string]pki.CertificatePKI { + return b.certs +} + +func LoadLocal() (*Bundle, error) { + f, err := os.Open(bundleFile) + if err != nil { + return nil, err + } + defer f.Close() + + certMap, err := rkecerts.Load(f) + if err != nil { + return nil, err + } + return NewBundle(certMap), nil +} + +func Generate(config *rketypes.RancherKubernetesEngineConfig) (*Bundle, error) { + certs, err := librke.New().GenerateCerts(config) + if err != nil { + return nil, err + } + + return &Bundle{ + certs: certs, + }, nil +} + +// SafeMarshal removes the kube-ca cert key and keyPEM from the cert bundle before marshalling +func (b *Bundle) SafeMarshal() (string, error) { + output := &bytes.Buffer{} + certs := b.certs + if caCert, ok := certs[pki.CACertName]; ok { + caCert.Key = nil + caCert.KeyPEM = "" + certs[pki.CACertName] = caCert + } + err := rkecerts.Save(certs, output) + return output.String(), err + +} + +func (b *Bundle) ForNode(config *rketypes.RancherKubernetesEngineConfig, nodeAddress string) *Bundle { + certs := librke.New().GenerateRKENodeCerts(context.Background(), *config, nodeAddress, b.certs) + return &Bundle{ + certs: certs, + } +} + +func (b *Bundle) ForWindowsNode(rkeconfig *rketypes.RancherKubernetesEngineConfig, nodeAddress string) *Bundle { + nb := b.ForNode(rkeconfig, nodeAddress) + + certs := make(map[string]pki.CertificatePKI, len(nb.certs)) + for key, cert := range nb.certs { + if len(cert.Config) != 0 { + config := &k8sclientv1.Config{} + + if err := yaml.Unmarshal([]byte(cert.Config), config); err == nil { + clusterAmount := len(config.Clusters) + for i := 0; i < clusterAmount; i++ { + cluster := &config.Clusters[i].Cluster + + if len(cluster.CertificateAuthority) != 0 { + if rkeconfig.WindowsPrefixPath != "" { + cluster.CertificateAuthority = rkeconfig.WindowsPrefixPath + cluster.CertificateAuthority + } else { + cluster.CertificateAuthority = "c:" + cluster.CertificateAuthority + } + } + } + + authInfoAmount := len(config.AuthInfos) + for i := 0; i < authInfoAmount; i++ { + authInfo := &config.AuthInfos[i].AuthInfo + + if len(authInfo.ClientCertificate) != 0 { + if rkeconfig.WindowsPrefixPath != "" { + authInfo.ClientCertificate = rkeconfig.WindowsPrefixPath + authInfo.ClientCertificate + } else { + authInfo.ClientCertificate = "c:" + authInfo.ClientCertificate + } + } + + if len(authInfo.ClientKey) != 0 { + if rkeconfig.WindowsPrefixPath != "" { + authInfo.ClientKey = rkeconfig.WindowsPrefixPath + authInfo.ClientKey + + } else { + authInfo.ClientKey = "c:" + authInfo.ClientKey + } + } + } + + if configYamlBytes, err := yaml.Marshal(config); err == nil { + cert.Config = string(configYamlBytes) + } + } + } + + certs[key] = cert + } + + return &Bundle{ + certs: certs, + } +} + +func (b *Bundle) SaveLocal() error { + bundlePath := filepath.Dir(bundleFile) + if err := os.MkdirAll(bundlePath, 0700); err != nil { + return err + } + + f, err := ioutil.TempFile(bundlePath, "bundle-") + if err != nil { + return err + } + defer f.Close() + defer os.Remove(f.Name()) + + if err := rkecerts.Save(b.certs, f); err != nil { + return err + } + + if err := f.Close(); err != nil { + return err + } + + return os.Rename(f.Name(), bundleFile) +} + +func (b *Bundle) KubeConfig() string { + return b.certs["kube-admin"].ConfigPath +} + +func (b *Bundle) Explode() error { + f := &fileWriter{} + + for _, item := range b.certs { + f.write(item.Path, nil, item.Certificate, nil) + f.write(item.ConfigPath, []byte(item.Config), nil, nil) + f.write(item.KeyPath, nil, nil, item.Key) + } + + return f.err() +} + +func (b *Bundle) Changed() bool { + var newCertPEM string + for _, item := range b.certs { + // Skip empty kube-kubelet certificates that are created for other workers + if item.Name == "" { + continue + } + oldCertPEM, err := ioutil.ReadFile(item.Path) + if err != nil { + logrus.Warnf("Unable to read certificate %s: %v", item.Name, err) + return false + } + if item.Certificate != nil { + newCertPEM = string(cert.EncodeCertPEM(item.Certificate)) + } + + // kube-kubelet certificates will always be different as they are created on-demand, we need to limit replacing them only if its absolutely necessary + if strings.HasPrefix(item.Name, "kube-kubelet") { + // Check if expired + oldCertX509, err := cert.ParseCertsPEM(oldCertPEM) + if err != nil { + logrus.Errorf("Error parsing old certificate PEM for [%s]: %v", item.Name, err) + } + now := time.Now() + if len(oldCertX509) > 0 { + if now.After(oldCertX509[0].NotAfter) { + logrus.Infof("Bundle changed: now [%v] is after certificate NotAfter [%v] for certificate [%s]", now, oldCertX509[0].NotAfter, item.Name) + return true + } + } + // Check if AltNames changed + if newCertPEM != "" { + newCertX509, err := cert.ParseCertsPEM([]byte(newCertPEM)) + if err != nil { + logrus.Errorf("Error parsing new certificate PEM for [%s]: %v", item.Name, err) + } + if len(newCertX509) > 0 { + sort.Strings(oldCertX509[0].DNSNames) + sort.Strings(newCertX509[0].DNSNames) + if !reflect.DeepEqual(oldCertX509[0].DNSNames, newCertX509[0].DNSNames) || !pki.DeepEqualIPsAltNames(oldCertX509[0].IPAddresses, newCertX509[0].IPAddresses) { + logrus.Infof("Bundle changed: DNSNames and/or IPAddresses changed for certificate [%s]: oldCert.DNSNames %v, newCert.DNSNames %v, oldCert.IPAddresses %v, newCert.IPAddresses %v", item.Name, oldCertX509[0].DNSNames, newCertX509[0].DNSNames, oldCertX509[0].IPAddresses, newCertX509[0].IPAddresses) + return true + } + } + } + continue + } + oldCertChecksum := fmt.Sprintf("%x", md5.Sum([]byte(oldCertPEM))) + newCertChecksum := fmt.Sprintf("%x", md5.Sum([]byte(newCertPEM))) + + if oldCertChecksum != newCertChecksum { + logrus.Infof("Certificate checksum changed (old: [%s], new [%s]) for [%s]", oldCertChecksum, newCertChecksum, item.Name) + return true + } + } + return false +} + +type fileWriter struct { + errs []error +} + +func (f *fileWriter) write(path string, content []byte, x509cert *x509.Certificate, key *rsa.PrivateKey) { + if x509cert != nil { + content = cert.EncodeCertPEM(x509cert) + } + + if key != nil { + content = cert.EncodePrivateKeyPEM(key) + } + + if path == "" || len(content) == 0 { + return + } + + existing, err := ioutil.ReadFile(path) + if err == nil && bytes.Equal(existing, content) { + return + } + + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0700); err != nil { + f.errs = append(f.errs, err) + } + if err := ioutil.WriteFile(path, content, 0600); err != nil { + f.errs = append(f.errs, err) + } +} + +func (f *fileWriter) err() error { + return types.NewErrors(f.errs...) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs_test.go new file mode 100644 index 0000000..c097d7b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/certs_test.go @@ -0,0 +1,52 @@ +package rkecerts + +import ( + "crypto/rand" + "crypto/rsa" + "testing" + + "github.com/rancher/rke/pki" + "github.com/stretchr/testify/assert" +) + +func TestBundle_SafeMarshal(t *testing.T) { + + rsaKey, err := rsa.GenerateKey(rand.Reader, 12) + if err != nil { + t.Fatal(err) + } + tests := []struct { + name string + certs map[string]pki.CertificatePKI + want string + wantErr bool + }{ + {"base", + map[string]pki.CertificatePKI{ + + pki.CACertName: { + Key: rsaKey, + KeyPEM: `PRETENDBASE64_TOBEREMOVED=`, + Name: "test", + KeyEnvName: "TEST_ENV", + KeyPath: "test", + }}, + `{"kube-ca":{"certificatePEM":"","keyPEM":"","config":"","name":"test","commonName":"","ouName":"","envName":"","path":"","keyEnvName":"TEST_ENV","keyPath":"test","configEnvName":"","configPath":"","CertPEM":"","KeyPEM":""}}` + "\n", + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := &Bundle{ + certs: tt.certs, + } + got, err := b.SafeMarshal() + if (err != nil) != tt.wantErr { + t.Errorf("SafeMarshal() error = %v, wantErr %v", err, tt.wantErr) + return + } + + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration.go new file mode 100644 index 0000000..ef8871f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration.go @@ -0,0 +1,60 @@ +package rkecerts + +import ( + "encoding/json" + "errors" + "strings" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rkeCluster "github.com/rancher/rke/cluster" + "github.com/rancher/rke/pki" + "github.com/rancher/rke/pki/cert" + v1 "k8s.io/api/core/v1" +) + +func CleanCertificateBundle(certs map[string]pki.CertificatePKI) { + for name := range certs { + if strings.Contains(name, "token") || strings.Contains(name, "header") || strings.Contains(name, "admin") { + delete(certs, name) + } + } +} + +func GetCertExpiration(c string) (v32.CertExpiration, error) { + date, err := GetCertExpirationDate(c) + if err != nil { + return v32.CertExpiration{}, err + } + return v32.CertExpiration{ + ExpirationDate: date.Format(time.RFC3339), + }, nil +} + +func GetCertExpirationDate(c string) (*time.Time, error) { + certs, err := cert.ParseCertsPEM([]byte(c)) + if err != nil { + return nil, err + } + if len(certs) == 0 { + return nil, errors.New("no valid certs found") + } + return &certs[0].NotAfter, nil +} + +func CertBundleFromConfig(cm *v1.ConfigMap) (map[string]pki.CertificatePKI, error) { + if cm == nil { + return nil, errors.New("full-cluster-state configmap not found") + } + rawCerts, ok := cm.Data[rkeCluster.FullStateConfigMapName] + if !ok { + return nil, errors.New("full-cluster-state configmap does not contain data") + } + rkeFullState := &rkeCluster.FullState{} + err := json.Unmarshal([]byte(rawCerts), rkeFullState) + if err != nil { + return nil, err + } + return rkeFullState.CurrentState.CertificatesBundle, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration_test.go new file mode 100644 index 0000000..94c9174 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkecerts/expiration_test.go @@ -0,0 +1,117 @@ +package rkecerts + +import ( + "fmt" + "reflect" + "strings" + "testing" + "time" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + rkeCluster "github.com/rancher/rke/cluster" + "github.com/rancher/rke/pki" + v1 "k8s.io/api/core/v1" +) + +var exampleCert = "-----BEGIN CERTIFICATE-----\nMIICpDCCAYwCCQCPcjBFQaNrJjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls\nb2NhbGhvc3QwHhcNMjAwMjI1MTYxMDAxWhcNMjEwMjI0MTYxMDAxWjAUMRIwEAYD\nVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDj\nPcg9ksAr44psuf0SHwFQC6GceTNHggKZDAqADlhFCZ9P5kb+JUJJ86u08LLDSBDF\nl0EsQSPbmCJmr7mnUf7byBBC8/5pTiZXIHM7VUhjL5Ooq8D9xbylTah8fMmcQbdc\nv8RffbHIpQ7oEHrpfEdv8FeIdpQEdiCVzZBV6LX/Cw5YkJvAx4P/E7Kf2c99YGeP\nmRxI94vThrd3mtFCzyyXgrW1wUtbBipFC/y0vpVhCceDAWThQeSF6ZwjxXOjUqvC\netME1jwnnn7al2GmbcfhY8sx73EQwbQI+Kn5sul+oixRHFL4XFZIWCYe2YXJ2dpC\n7SxF+844YT4fEyItEG83AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAErzQ7eS1rB8\nOx/we9yC3X3z+5V0cH91tyXvGrVYJuWN+kdv/bQP0Gu+Fvk+82jHcoQS8hRn77t+\noyfph/lk8WicsllVud06Z7K16akxzBtSUahkw38UuVxuQ8U5ZuH5JkyZVcRyq210\nR3sn5U9gxFZ3zISfWhZI8EXU/K7IB03Bv3HG0uZwRpI8w5O6jC9vD2hoFHPpqlTQ\nfVpQjALKswZWdN5Dm7YP9JpUjWrl6lFmkE2cpj+F0cZHIgWupsBgVT7WwRUGgZPN\nstf+yTf2og2fVciZuopzfMhk545Zwye7CUseOP6YOeWKnm/UbR314fKX7Rum1saM\nbVQypIiA8ds=\n-----END CERTIFICATE-----\n" + +func TestGetCertExpirationDate(t *testing.T) { + tests := []struct { + name string + cert string + want time.Time + wantErr bool + }{ + { + name: "return correct date", + cert: exampleCert, + want: time.Date(2021, 02, 24, 16, 10, 01, 0, time.UTC), + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetCertExpirationDate(tt.cert) + if (err != nil) != tt.wantErr { + t.Errorf("GetCertExpirationDate() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.want.Equal(*got) { + t.Errorf("GetCertExpirationDate() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetCertExpiration(t *testing.T) { + tests := []struct { + name string + cert string + want v32.CertExpiration + wantErr bool + }{ + { + name: "valid cert", + cert: exampleCert, + want: v32.CertExpiration{ + ExpirationDate: "2021-02-24T16:10:01Z", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetCertExpiration(tt.cert) + if (err != nil) != tt.wantErr { + t.Errorf("GetCertExpiration() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetCertExpiration() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestCertBundleFromConfig(t *testing.T) { + tests := []struct { + name string + configMap v1.ConfigMap + want map[string]pki.CertificatePKI + wantErr bool + }{ + { + name: "valid configmap", + configMap: v1.ConfigMap{ + Data: map[string]string{ + rkeCluster.FullStateConfigMapName: fmt.Sprintf("{\"currentState\":{\"certificatesBundle\":{\"kube-admin\":{\"certificatePEM\":\"%s\"}}}}", strings.Replace(exampleCert, "\n", `\n`, -1)), + }, + }, + want: map[string]pki.CertificatePKI{ + "kube-admin": pki.CertificatePKI{ + CertificatePEM: exampleCert, + }, + }, + wantErr: false, + }, + { + name: "invalid configmap", + configMap: v1.ConfigMap{}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CertBundleFromConfig(&tt.configMap) + if (err != nil) != tt.wantErr { + t.Errorf("CertBundleFromConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("CertBundleFromConfig() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkedialerfactory/rke_dialer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkedialerfactory/rke_dialer.go new file mode 100644 index 0000000..2a91e0c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkedialerfactory/rke_dialer.go @@ -0,0 +1,99 @@ +package rkedialerfactory + +import ( + "context" + "fmt" + "net" + "net/http" + "strings" + + "github.com/rancher/norman/types/slice" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rke/hosts" + rketypes "github.com/rancher/rke/types" + "k8s.io/client-go/transport" +) + +type RKEDialerFactory struct { + Factory dialer.Factory + Docker bool + Ctx context.Context +} + +func (t *RKEDialerFactory) Build(h *hosts.Host) (func(network, address string) (net.Conn, error), error) { + if h.NodeName == "" { + return hosts.SSHFactory(h) + } + + parts := strings.SplitN(h.NodeName, ":", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("invalid name reference %s", h.NodeName) + } + + if t.Docker { + return func(network, address string) (net.Conn, error) { + d, err := t.Factory.DockerDialer(parts[0], parts[1]) + if err != nil { + return nil, err + } + return d(t.Ctx, network, address) + }, nil + } + return func(network, address string) (net.Conn, error) { + d, err := t.Factory.NodeDialer(parts[0], parts[1]) + if err != nil { + return nil, err + } + return d(t.Ctx, network, address) + }, nil +} + +func (t *RKEDialerFactory) WrapTransport(config *rketypes.RancherKubernetesEngineConfig) transport.WrapperFunc { + translateAddress := map[string]string{} + + for _, node := range config.Nodes { + if !slice.ContainsString(node.Role, "controlplane") { + continue + } + if node.InternalAddress != "" && node.Address != "" { + translateAddress[node.Address] = node.InternalAddress + } + } + + for _, node := range config.Nodes { + if !slice.ContainsString(node.Role, "controlplane") { + continue + } + + ns, n := ref.Parse(node.NodeName) + dialer, err := t.Factory.NodeDialer(ns, n) + if dialer == nil || err != nil { + continue + } + + return func(rt http.RoundTripper) http.RoundTripper { + if ht, ok := rt.(*http.Transport); ok { + ht.DialContext = nil + ht.DialTLS = nil + ht.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) { + ip, _, _ := net.SplitHostPort(address) + if privateIP, ok := translateAddress[ip]; ok { + address = strings.Replace(address, ip, privateIP, 1) + } + conn, err := dialer(ctx, network, address) + if ref.IsNodeNotFound(err) { + clusterDialer, dialerErr := t.Factory.ClusterDialer(ns, true) + if dialerErr == nil { + return clusterDialer(ctx, network, address) + } + } + return conn, err + } + } + return rt + } + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates.go new file mode 100644 index 0000000..675c5f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates.go @@ -0,0 +1,66 @@ +package rkenodeconfigclient + +import ( + "crypto/tls" + "crypto/x509" + "time" + + "github.com/sirupsen/logrus" +) + +const kubeletCertValidityLimit = time.Hour * 72 + +func kubeletCertificateNeedsRegeneration(ipAddress, currentHostname string, cert tls.Certificate, currentTime time.Time) (bool, error) { + if len(cert.Certificate) == 0 { + return true, nil + } + + parsedCert, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return false, err + } + + if !certificateIncludesHostname(currentHostname, parsedCert) { + logrus.Tracef("certificate does not include current hostname, requesting new certificate") + return true, nil + } + + if certificateIsExpiring(parsedCert, currentTime) { + logrus.Tracef("certificate is expiring soon, requesting new certificate") + return true, nil + } + + if !certificateIncludesCurrentIP(ipAddress, parsedCert) { + logrus.Tracef("certificate does not include current IP address, requesting new certificate") + return true, nil + } + + return false, nil +} + +// certificateIsExpiring checks if the passed certificate will expire within +// the kubeletCertValidityLimit +func certificateIsExpiring(cert *x509.Certificate, currentTime time.Time) bool { + return cert.NotAfter.Sub(currentTime) < kubeletCertValidityLimit +} + +// certificateIncludesHostname checks that the passed certificate includes +// the provided hostname in its SAN list +func certificateIncludesHostname(hostname string, cert *x509.Certificate) bool { + for _, name := range cert.DNSNames { + if name == hostname { + return true + } + } + return false +} + +// certificateIncludesCurrentIP checks that the passed certificate includes the provided IP address +func certificateIncludesCurrentIP(ipAddress string, cert *x509.Certificate) bool { + for _, ip := range cert.IPAddresses { + if ipAddress == ip.String() { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates_test.go new file mode 100644 index 0000000..b560a04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/certificates_test.go @@ -0,0 +1,219 @@ +package rkenodeconfigclient + +import ( + "bytes" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "math/big" + "net" + "testing" + "time" + + "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" +) + +func TestFindCommandValue(t *testing.T) { + commands := []string{ + "--hostname=test.com", + "--tls-cert-file=a-test-value", + "---abc=123", + } + + type testcase struct { + testName string + flag string + value string + } + + tests := []testcase{ + { + testName: "successfully find flag in command arguments", + value: "a-test-value", + flag: "--tls-cert-file", + }, + { + testName: "unsuccessfully find flag in command arguments", + value: "", + flag: "--not-a-flag", + }, + } + + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + v := findCommandValue(tc.flag, commands) + if v != tc.value { + t.Logf("wanted %s, got %s", tc.value, v) + t.Fail() + } + }) + } +} + +func TestGetKubeletCertificateFilesFromProcess(t *testing.T) { + + type testcase struct { + testName string + processes map[string]types.Process + privateKeyFileValue string + tlsCertFileValue string + want bool + } + + testCases := []testcase{ + { + testName: "successfully find kubelet arg", + processes: map[string]types.Process{ + "kubelet": { + // rancher actually passes all args in the 'Command' field, since + // we use the entrypoint.sh file + Command: []string{ + "--tls-private-key-file=/etc/kubernetes/ssl/a-private-key.pem", + "--tls-cert-file=/etc/kubernetes/ssl/a-private.pem", + }, + }, + "not-kubelet": {}, + }, + privateKeyFileValue: "/etc/kubernetes/ssl/a-private-key.pem", + tlsCertFileValue: "/etc/kubernetes/ssl/a-private.pem", + want: true, + }, + { + testName: "unsuccessfully find kubelet arg", + processes: map[string]types.Process{ + "kubelet": { + // rancher actually passes all args in the 'Command' field, since + // we use the entrypoint.sh file + Command: []string{}, + }, + "not-kubelet": {}, + }, + privateKeyFileValue: "a-private-key.pem", + tlsCertFileValue: "a-private.pem", + want: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + privateKeyFileName, tlsCertFileName := getKubeletCertificateFilesFromProcess(tc.processes) + if (privateKeyFileName != tc.privateKeyFileValue || tlsCertFileName != tc.tlsCertFileValue) && tc.want { + t.Logf("wanted %s %s, got %s %s ", tc.tlsCertFileValue, tc.privateKeyFileValue, tlsCertFileName, privateKeyFileName) + t.Fail() + } + }) + } +} + +func TestKubeletCertificateNeedsRegeneration(t *testing.T) { + + correctIPAddress := "167.71.188.113" + correctHostName := "cert-test1" + testCertExpiryTime := time.Now().AddDate(10, 0, 3) + + type testcase struct { + testName string + testIPAddress string + testHostName string + testTime time.Time + want bool + } + + testCases := []testcase{ + { + testName: "All Cert Properties Are Valid", + testIPAddress: correctIPAddress, + testHostName: correctHostName, + testTime: time.Now(), + want: false, + }, + { + testName: "Cert Contains Invalid IP Address", + testIPAddress: "192.168.1.1", + testHostName: correctHostName, + testTime: time.Now(), + want: true, + }, + { + testName: "Cert Contains Invalid Hostname", + testIPAddress: correctIPAddress, + testHostName: "different-hostname", + testTime: time.Now(), + want: true, + }, + { + testName: "Cert Will Expire In Less Than Three Days", + testIPAddress: correctIPAddress, + testHostName: correctHostName, + testTime: time.Now().AddDate(10, 0, 1), // ~ 48 hours until expiry + want: true, + }, + } + t.Log("generating test certificate...") + testCert, err := createTestCert([]net.IP{net.ParseIP(correctIPAddress)}, []string{correctHostName}, testCertExpiryTime) + assert.Equal(t, nil, err) + t.Log("successfully generated test certificate") + for _, c := range testCases { + t.Run(c.testName, func(t *testing.T) { + got, err := kubeletCertificateNeedsRegeneration(c.testIPAddress, c.testHostName, testCert, c.testTime) + assert.Equal(t, nil, err) + assert.Equal(t, c.want, got) + }) + } +} + +// createTestCert creates a self-signed certificate for use in tests, it incorporates the given ipAddress's, hostNames, and expiry time +func createTestCert(ipAddress []net.IP, hostname []string, notAfter time.Time) (tls.Certificate, error) { + cert := &x509.Certificate{ + SerialNumber: big.NewInt(2022), + Subject: pkix.Name{ + Organization: []string{"Rancher"}, + Country: []string{"US"}, + Province: []string{""}, + Locality: []string{"Green Pastures"}, + StreetAddress: []string{"123 Cattle Drive"}, + PostalCode: []string{"94016"}, + }, + NotBefore: time.Now(), + NotAfter: notAfter, + KeyUsage: x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + SubjectKeyId: []byte{5, 4, 1, 6, 8}, + DNSNames: hostname, + IPAddresses: ipAddress, + } + + certPriv, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return tls.Certificate{}, err + } + privKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return tls.Certificate{}, err + } + certBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &certPriv.PublicKey, privKey) + if err != nil { + return tls.Certificate{}, err + } + + certPem := new(bytes.Buffer) + certPrivPem := new(bytes.Buffer) + if err = pem.Encode(certPem, &pem.Block{ + Type: "CERTIFICATE", + Bytes: certBytes, + }); err != nil { + return tls.Certificate{}, err + } + if err = pem.Encode(certPrivPem, &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(certPriv), + }); err != nil { + return tls.Certificate{}, err + } + + return tls.X509KeyPair(certPem.Bytes(), certPrivPem.Bytes()) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/client.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/client.go new file mode 100644 index 0000000..1154295 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigclient/client.go @@ -0,0 +1,244 @@ +package rkenodeconfigclient + +import ( + "context" + "crypto/tls" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "os" + "regexp" + "strings" + "time" + + "github.com/rancher/rancher/pkg/agent/node" + "github.com/rancher/rancher/pkg/rkenodeconfigserver" + "github.com/rancher/rancher/pkg/rkeworker" + "github.com/rancher/rke/types" + "github.com/sirupsen/logrus" +) + +const ( + Params = "X-API-Tunnel-Params" +) + +var ( + nodeNotFoundRegexp = regexp.MustCompile(`^node\.management\.cattle\.io.*not found$`) + clusterNotFoundRegexp = regexp.MustCompile(`^cluster.*not found$`) +) + +type ErrNodeOrClusterNotFound struct { + msg string + occursType string +} + +func (e *ErrNodeOrClusterNotFound) Error() string { + return e.msg +} + +func (e *ErrNodeOrClusterNotFound) ErrorOccursType() string { + return e.occursType +} + +func newErrNodeOrClusterNotFound(msg, occursType string) *ErrNodeOrClusterNotFound { + return &ErrNodeOrClusterNotFound{ + msg, + occursType, + } +} + +// ConfigClient executes a GET request against the rancher servers node-server API in an attempt to get the most recent node-config. +// It continues to do so until a node-config is returned within the response body, or the retry limit of 3 attempts is exceeded. Upon +// receiving a valid node-config this function inspects any kubelet serving certificates present on the host to determine if they need to be refreshed. +// If kubelet certificates need to be regenerated, a second GET request will be made so that the node config holds valid certificates. Once all kubelet certificates +// are deemed valid, ConfigClient will execute the node config, writing files and executing processes as directed. The passed +// url and header values are used when crafting the GET request, and the writeCertOnly parameter is used to denote if the agent should disregard +// all aspects of the received node-config except any delivered certificates. Upon a successful execution of the node config, this function +// will return a polling interval which should be used to query the rancher server for the next node-config and any encountered errors. +func ConfigClient(ctx context.Context, client *http.Client, url string, header http.Header, writeCertOnly bool) (int, error) { + // try a few more times because there is a delay after registering a new node + nodeOrClusterNotFoundRetryLimit := 3 + interval := 120 + requestedRenewedCert := false + for { + nc, err := getConfig(client, url, header) + if err != nil { + if _, ok := err.(*ErrNodeOrClusterNotFound); ok { + if nodeOrClusterNotFoundRetryLimit < 1 { + // return the error if the node cannot connect to server or remove from a cluster + return interval, err + } + + nodeOrClusterNotFoundRetryLimit-- + } + + logrus.Warnf("Error while getting agent config: %v", err) + time.Sleep(5 * time.Second) + continue + } + + if nc != nil { + + // if a cert file and key file are passed to the kubelet + // then we need to ensure they are valid, otherwise we can safely skip the check + certFile, keyFile := getKubeletCertificateFilesFromProcess(nc.Processes) + if certFile != "" && keyFile != "" { + logrus.Debugf("agent detected certificate arguments within kubelet process, checking kubelet certificate validity") + // check to see if we need a new kubelet certificate + kubeletCertNeedsRegen, err := kubeletNeedsNewCertificate(nc) + if err != nil { + return interval, err + } + + if kubeletCertNeedsRegen && !requestedRenewedCert { + // add to the header and run getConfig again, so we get a new cert + // we should only do this at most once per call to ConfigClient + header.Set(rkenodeconfigserver.RegenerateKubeletCertificate, "true") + logrus.Debugf("Requesting kubelet certificate regeneration") + requestedRenewedCert = true + continue + } + } + + header.Set(rkenodeconfigserver.RegenerateKubeletCertificate, "false") + requestedRenewedCert = false + + // Logging at trace level as NodeConfig may contain sensitive data + logrus.Tracef("Get agent config: %#v", nc) + if nc.AgentCheckInterval != 0 { + interval = nc.AgentCheckInterval + } + + err = rkeworker.ExecutePlan(ctx, nc, writeCertOnly) + if err != nil { + return interval, err + } + + /* server sends non-zero nodeVersion when node is upgrading (node.Status.AppliedVersion != cluster.Status.NodeVersion) + ExecutePlan doesn't update processes if writeCertOnly, shouldn't consider this an upgrade */ + if nc.NodeVersion != 0 && !writeCertOnly { + // reply back with nodeVersion + params := node.Params() + params["nodeVersion"] = nc.NodeVersion + + bytes, err := json.Marshal(params) + if err != nil { + return interval, err + } + + headerCopy := http.Header{} + for k, v := range header { + headerCopy[k] = v + } + headerCopy[Params] = []string{base64.StdEncoding.EncodeToString(bytes)} + header = headerCopy + + continue + } + + return interval, err + } + + logrus.Infof("Waiting for node to register. Either cluster is not ready for registering, cluster is currently provisioning, or etcd, controlplane and worker node have to be registered") + time.Sleep(2 * time.Second) + } +} + +func getConfig(client *http.Client, url string, header http.Header) (*rkeworker.NodeConfig, error) { + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + return nil, err + } + + for k, v := range header { + req.Header[k] = v + } + + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode == http.StatusServiceUnavailable { + return nil, nil + } + + if resp.StatusCode == http.StatusNotFound { + return &rkeworker.NodeConfig{}, nil + } + + if resp.StatusCode != http.StatusOK { + respBytes, _ := ioutil.ReadAll(resp.Body) + errMsg := fmt.Sprintf("invalid response %d: %s", resp.StatusCode, string(respBytes)) + + if nodeNotFoundRegexp.Match(respBytes) { + return nil, newErrNodeOrClusterNotFound(errMsg, "node") + } else if clusterNotFoundRegexp.Match(respBytes) { + return nil, newErrNodeOrClusterNotFound(errMsg, "cluster") + } + + return nil, errors.New(errMsg) + } + + nc := &rkeworker.NodeConfig{} + return nc, json.NewDecoder(resp.Body).Decode(nc) +} + +// getKubeletCertificateFilesFromProcess finds the tls-private-key-file and tls-cert-file values from +// the kubelet process so that they may be used to determine the validity of the kubelet certificates stored +// on the host. +func getKubeletCertificateFilesFromProcess(processes map[string]types.Process) (string, string) { + proc, ok := processes["kubelet"] + if !ok { + return "", "" + } + + return findCommandValue("--tls-private-key-file", proc.Command), findCommandValue("--tls-cert-file", proc.Command) +} + +// findCommandValue iterates over a list of process flags and returns the value of +// the specified flag, stripping the flag name and the '=' sign. If the flag +// cannot be found in the list of flags, an empty string is returned. +func findCommandValue(flag string, commandsFlags []string) string { + for _, cmd := range commandsFlags { + if strings.HasPrefix(cmd, flag) { + valueWithEqual := strings.TrimPrefix(cmd, flag) + value := strings.TrimPrefix(valueWithEqual, "=") + return value + } + } + return "" +} + +// kubeletNeedsNewCertificate will set the +// 'RegenerateKubeletCertificate' header field to true if +// a) the kubelet serving certificate does not exist +// b) the certificate will expire in 72 hours +// c) the certificate does not accurately represent the current IP address and Hostname of the node +// +// While the agent may denote it needs a new kubelet certificate +// in its connection request, a new certificate will only be +// delivered by Rancher if the generate_serving_certificate property +// is set to 'true' for the clusters kubelet service. +func kubeletNeedsNewCertificate(nc *rkeworker.NodeConfig) (bool, error) { + kubeletCertKeyFile, kubeletCertFile := getKubeletCertificateFilesFromProcess(nc.Processes) + if kubeletCertFile == "" || kubeletCertKeyFile == "" { + return true, nil + } + + cert, err := tls.LoadX509KeyPair(kubeletCertFile, kubeletCertKeyFile) + if err != nil && !strings.Contains(err.Error(), "no such file") { + return true, err + } + + needsRegen, err := kubeletCertificateNeedsRegeneration(os.Getenv("CATTLE_ADDRESS"), os.Getenv("CATTLE_NODE_NAME"), cert, time.Now()) + if err != nil { + return true, err + } + + return needsRegen, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/lookup.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/lookup.go new file mode 100644 index 0000000..5e4f62d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/lookup.go @@ -0,0 +1,56 @@ +package rkenodeconfigserver + +import ( + "fmt" + + "github.com/rancher/rancher/pkg/controllers/management/clusterprovisioner" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/kontainer-engine/cluster" + kecerts "github.com/rancher/rancher/pkg/kontainer-engine/drivers/rke/rkecerts" + "github.com/rancher/rancher/pkg/rkecerts" + "github.com/rancher/rke/pki" +) + +type BundleLookup struct { + engineStore cluster.PersistentStore +} + +func NewLookup(namespaces v1.NamespaceInterface, secrets v1.SecretsGetter) *BundleLookup { + return &BundleLookup{ + engineStore: clusterprovisioner.NewPersistentStore(namespaces, secrets), + } +} + +func (r *BundleLookup) Lookup(cluster *v3.Cluster) (*rkecerts.Bundle, error) { + c, err := r.engineStore.Get(cluster.Name) + if err != nil { + return nil, err + } + + certs, ok := c.Metadata["Certs"] + if !ok { + return nil, fmt.Errorf("waiting for certs to be generated for cluster %s", cluster.Name) + } + + certMap, err := kecerts.LoadString(certs) + if err != nil { + return nil, err + } + + newCertMap := map[string]pki.CertificatePKI{} + for k, v := range certMap { + if v.Config != "" { + v.ConfigPath = pki.GetConfigPath(k) + } + if v.Key != nil { + v.KeyPath = pki.GetKeyPath(k) + } + if v.Certificate != nil { + v.Path = pki.GetCertPath(k) + } + newCertMap[k] = v + } + + return rkecerts.NewBundle(newCertMap), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver.go new file mode 100644 index 0000000..b6b18af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver.go @@ -0,0 +1,409 @@ +package rkenodeconfigserver + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/dashboard/clusterregistrationtoken" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/tunnelserver/mcmauthorizer" + "github.com/rancher/rke/hosts" + + rketypes "github.com/rancher/rke/types" + + "github.com/pkg/errors" + util "github.com/rancher/rancher/pkg/cluster" + kd "github.com/rancher/rancher/pkg/controllers/management/kontainerdrivermetadata" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/librke" + "github.com/rancher/rancher/pkg/rkeworker" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/systemaccount" + "github.com/rancher/rancher/pkg/taints" + "github.com/rancher/rancher/pkg/types/config" + rkepki "github.com/rancher/rke/pki" + rkeservices "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +const ( + DefaultAgentCheckInterval = 120 + AgentCheckIntervalDuringUpgrade = 35 + AgentCheckIntervalDuringCreate = 15 + + // RegenerateKubeletCertificate is a header field included by the + // node agent which denotes that a new kubelet serving certificate + // should be generated for the downstream node. Its value is a + // string representing a boolean ('true' || 'false'). While the + // agent may request a new serving certificate, one should only be + // provided if the kubelet service field `generate_serving_certificate` + // is set to 'true'. + RegenerateKubeletCertificate = "Regenerate-Kubelet-Certificate" +) + +type RKENodeConfigServer struct { + auth *mcmauthorizer.Authorizer + lookup *BundleLookup + systemAccountManager *systemaccount.Manager + serviceOptionsLister v3.RkeK8sServiceOptionLister + serviceOptions v3.RkeK8sServiceOptionInterface + sysImagesLister v3.RkeK8sSystemImageLister + sysImages v3.RkeK8sSystemImageInterface + nodes v3.NodeInterface +} + +func Handler(auth *mcmauthorizer.Authorizer, scaledContext *config.ScaledContext) http.Handler { + return &RKENodeConfigServer{ + auth: auth, + lookup: NewLookup(scaledContext.Core.Namespaces(""), scaledContext.Core), + systemAccountManager: systemaccount.NewManagerFromScale(scaledContext), + serviceOptionsLister: scaledContext.Management.RkeK8sServiceOptions("").Controller().Lister(), + serviceOptions: scaledContext.Management.RkeK8sServiceOptions(""), + sysImagesLister: scaledContext.Management.RkeK8sSystemImages("").Controller().Lister(), + sysImages: scaledContext.Management.RkeK8sSystemImages(""), + nodes: scaledContext.Management.Nodes(""), + } +} + +func (n *RKENodeConfigServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + // 404 tells the client to continue without plan + // 5xx tells the client to try again later for plan + + client, ok, err := n.auth.Authorize(req) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte(err.Error())) + return + } + + if !ok { + rw.WriteHeader(http.StatusUnauthorized) + return + } + + if client.Node == nil { + rw.WriteHeader(http.StatusNotFound) + return + } + + if client.Cluster.Status.Driver == "" { + rw.WriteHeader(http.StatusServiceUnavailable) + return + } + + if client.Cluster.Status.Driver != v32.ClusterDriverRKE { + rw.WriteHeader(http.StatusNotFound) + return + } + + if client.Node.Status.NodeConfig == nil { + rw.WriteHeader(http.StatusServiceUnavailable) + return + } + + if client.Cluster.Status.AppliedSpec.RancherKubernetesEngineConfig == nil { + rw.WriteHeader(http.StatusServiceUnavailable) + return + } + + var nodeConfig *rkeworker.NodeConfig + if IsNonWorker(client.Node.Status.NodeConfig.Role) { + nodeConfig, err = n.nonWorkerConfig(req.Context(), client.Cluster, client.Node) + } else { + if client.NodeVersion != 0 { + logrus.Debugf("cluster [%s] worker-upgrade: received node-version [%v] for node [%s]", client.Cluster.Name, + client.NodeVersion, client.Node.Name) + + if client.Node.Status.AppliedNodeVersion != client.NodeVersion { + nodeCopy := client.Node.DeepCopy() + logrus.Infof("cluster [%s] worker-upgrade: updating node [%s] with node-version %v", client.Cluster.Name, + client.Node.Name, client.NodeVersion) + + nodeCopy.Status.AppliedNodeVersion = client.NodeVersion + + _, err = n.nodes.Update(nodeCopy) + if err != nil { + logrus.Infof("cluster [%s] worker-upgrade: error updating node [%s] with node-version [%v]: %v", client.Cluster.Name, + client.Node.Name, client.NodeVersion, err) + } + } + } + + nodeConfig, err = n.nodeConfig(req.Context(), client.Cluster, client.Node, req.Header.Get(strings.ToLower(RegenerateKubeletCertificate)) == "true") + } + + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + rw.Write([]byte("Failed to construct node config. Error: " + err.Error())) + return + } + + rw.Header().Set("Content-Type", "application/json") + + if err := json.NewEncoder(rw).Encode(nodeConfig); err != nil { + logrus.Errorf("failed to write nodeConfig to agent: %v", err) + } +} + +func IsNonWorker(roles []string) bool { + for _, role := range roles { + if role == rkeservices.ETCDRole { + return true + } + if role == rkeservices.ControlRole { + return true + } + } + return false +} + +func (n *RKENodeConfigServer) nonWorkerConfig(ctx context.Context, cluster *v3.Cluster, node *v3.Node) (*rkeworker.NodeConfig, error) { + nodePlan := node.Status.NodePlan + nc := &rkeworker.NodeConfig{ + ClusterName: cluster.Name, + } + + if nodePlan == nil { + logrus.Tracef("cluster [%s]: node [%s] doesn't have node plan yet", cluster.Name, node.Name) + nc.AgentCheckInterval = AgentCheckIntervalDuringCreate + return nc, nil + } + + nc.Processes = nodePlan.Plan.Processes + nc.AgentCheckInterval = nodePlan.AgentCheckInterval + + return nc, nil +} + +func (n *RKENodeConfigServer) nodeConfig(ctx context.Context, cluster *v3.Cluster, node *v3.Node, agentNeedsNewKubeletCertificate bool) (*rkeworker.NodeConfig, error) { + status := cluster.Status.AppliedSpec.DeepCopy() + rkeConfig := status.RancherKubernetesEngineConfig + + nodePlan := node.Status.NodePlan + hostAddress := node.Status.NodeConfig.Address + + nc := &rkeworker.NodeConfig{ + ClusterName: cluster.Name, + } + + if nodePlan == nil { + logrus.Tracef("cluster [%s]: node [%s] %s doesn't have node plan yet", cluster.Name, node.Name, hostAddress) + nc.AgentCheckInterval = AgentCheckIntervalDuringCreate + return nc, nil + } + + infos, err := librke.GetDockerInfo(node) + if err != nil { + return nil, err + } + + bundle, err := n.lookup.Lookup(cluster) + if err != nil { + return nil, err + } + + hostDockerInfo := infos[hostAddress] + if hostDockerInfo.OSType == "windows" { // compatible with Windows + bundle = bundle.ForWindowsNode(rkeConfig, hostAddress) + } else { + bundle = bundle.ForNode(rkeConfig, hostAddress) + } + + if rkepki.IsKubeletGenerateServingCertificateEnabledinConfig(rkeConfig) && agentNeedsNewKubeletCertificate { + logrus.Debugf("nodeConfig: node agent has requested new kubelet certificate and VerifyKubeletCAEnabled is true, generating kubelet certificate for [%s]", hostAddress) + err := GenerateKubeletServingCertForNode(bundle.Certs(), node) + if err != nil { + return nil, errors.Wrapf(err, "failed to generate kubelet certificate") + } + } + certString, err := bundle.SafeMarshal() + if err != nil { + return nil, errors.Wrapf(err, "failed to marshal certificates bundle") + } + nc.Certs = certString + np := nodePlan.Plan + nc.Processes = np.Processes + nc.Files = np.Files + if nodePlan.AgentCheckInterval != 0 { + nc.AgentCheckInterval = nodePlan.AgentCheckInterval + } + + if node.Status.AppliedNodeVersion != cluster.Status.NodeVersion { + if nodePlan.Version == cluster.Status.NodeVersion { + nc.NodeVersion = cluster.Status.NodeVersion + logrus.Infof("cluster [%s] worker-upgrade: sending node-version for node [%s] version %v", cluster.Name, node.Status.NodeName, nc.NodeVersion) + } else if v32.ClusterConditionUpgraded.IsUnknown(cluster) { + if nc.AgentCheckInterval != AgentCheckIntervalDuringUpgrade { + nodeCopy := node.DeepCopy() + nodeCopy.Status.NodePlan.AgentCheckInterval = AgentCheckIntervalDuringUpgrade + + n.nodes.Update(nodeCopy) + + logrus.Infof("cluster [%s] worker-upgrade: updating [%s] with agent-interval [%v]", cluster.Name, node.Status.NodeName, AgentCheckIntervalDuringUpgrade) + nc.AgentCheckInterval = AgentCheckIntervalDuringUpgrade + } + } + } + return nc, nil +} + +func GenerateKubeletServingCertForNode(certs map[string]rkepki.CertificatePKI, node *v3.Node) error { + caCrt := certs[rkepki.CACertName].Certificate + caKey := certs[rkepki.CACertName].Key + if caCrt == nil || caKey == nil { + return fmt.Errorf("CA Certificate or Key is empty") + } + + nodeAsHost := &hosts.Host{RKEConfigNode: *node.Status.NodeConfig} + kubeletName := rkepki.GetCrtNameForHost(nodeAsHost, rkepki.KubeletCertName) + + altNames := rkepki.GetIPHostAltnamesForHost(nodeAsHost) + + serviceKey := certs[kubeletName].Key + newCrt, newKey, err := rkepki.GenerateSignedCertAndKey(caCrt, caKey, true, kubeletName, altNames, serviceKey, nil) + if err != nil { + return err + } + certs[kubeletName] = rkepki.ToCertObject(kubeletName, "", "", newCrt, newKey, nil) + return nil +} + +func FilterHostForSpec(spec *rketypes.RancherKubernetesEngineConfig, n *v3.Node) { + nodeList := make([]rketypes.RKEConfigNode, 0) + for _, node := range spec.Nodes { + if IsNonWorker(node.Role) || node.NodeName == n.Status.NodeConfig.NodeName { + nodeList = append(nodeList, node) + } + } + spec.Nodes = nodeList +} + +func AugmentProcesses(token string, processes map[string]rketypes.Process, worker bool, nodeName string, + cluster *v3.Cluster, secretLister v1.SecretLister) (map[string]rketypes.Process, error) { + var shared bool + +OuterLoop: + for _, process := range processes { + for _, bind := range process.Binds { + parts := strings.Split(bind, ":") + if len(parts) > 2 && strings.Contains(parts[2], "shared") { + shared = true + break OuterLoop + } + } + } + + if shared { + agentImage := settings.AgentImage.Get() + nodeCommand, err := clusterregistrationtoken.ShareMntCommand(nodeName, token, cluster) + if err != nil { + return nil, err + } + _, privateRegistryConfig, _ := util.GeneratePrivateRegistryEncodedDockerConfig(cluster, secretLister) + processes["share-mnt"] = rketypes.Process{ + Name: "share-mnt", + Args: nodeCommand, + Image: image.ResolveWithCluster(agentImage, cluster), + Binds: []string{ + "/var/run:/var/run", + "/etc/kubernetes:/etc/kubernetes", + }, + NetworkMode: "host", + RestartPolicy: "always", + Privileged: true, + ImageRegistryAuthConfig: privateRegistryConfig, + } + } + + if worker { + // not sure if we really need this anymore + delete(processes, "etcd") + } else { + if p, ok := processes["share-mnt"]; ok { + processes = map[string]rketypes.Process{ + "share-mnt": p, + } + } else { + processes = nil + } + } + + for _, p := range processes { + for i, bind := range p.Binds { + parts := strings.Split(bind, ":") + if len(parts) > 1 && parts[1] == "/etc/kubernetes" { + parts[0] = parts[1] + p.Binds[i] = strings.Join(parts, ":") + } + } + } + + return processes, nil +} + +func EnhanceWindowsProcesses(processes map[string]rketypes.Process) map[string]rketypes.Process { + newProcesses := make(map[string]rketypes.Process, len(processes)) + for k, p := range processes { + p.Binds = append(p.Binds, + "//./pipe/rancher_wins://./pipe/rancher_wins", + ) + newProcesses[k] = p + } + + return newProcesses +} + +func AppendTaintsToKubeletArgs(processes map[string]rketypes.Process, nodeConfigTaints []rketypes.RKETaint) map[string]rketypes.Process { + if kubelet, ok := processes["kubelet"]; ok && len(nodeConfigTaints) != 0 { + initialTaints := taints.GetTaintsFromStrings(taints.GetStringsFromRKETaint(nodeConfigTaints)) + var currentTaints []corev1.Taint + foundArgs := "" + for i, arg := range kubelet.Command { + if strings.HasPrefix(arg, "--register-with-taints=") { + foundArgs = strings.TrimPrefix(arg, "--register-with-taints=") + kubelet.Command = append(kubelet.Command[:i], kubelet.Command[i+1:]...) + break + } + } + if foundArgs != "" { + currentTaints = taints.GetTaintsFromStrings(strings.Split(foundArgs, ",")) + } + + // The initial taints are from node pool and node template. They should override the taints from kubelet args. + mergedTaints := taints.MergeTaints(currentTaints, initialTaints) + + taintArgs := fmt.Sprintf("--register-with-taints=%s", strings.Join(taints.GetStringsFromTaint(mergedTaints), ",")) + kubelet.Command = append(kubelet.Command, taintArgs) + processes["kubelet"] = kubelet + } + return processes +} + +func (n *RKENodeConfigServer) getServiceOptions(k8sVersion string, osType string) (map[string]interface{}, error) { + data := map[string]interface{}{} + svcOptions, err := kd.GetRKEK8sServiceOptions(k8sVersion, n.serviceOptionsLister, n.serviceOptions, n.sysImagesLister, n.sysImages, kd.Linux) + if err != nil { + logrus.Errorf("getK8sServiceOptions: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptions != nil { + data["k8s-service-options"] = svcOptions + } + if osType == "windows" { + svcOptionsWindows, err := kd.GetRKEK8sServiceOptions(k8sVersion, n.serviceOptionsLister, n.serviceOptions, n.sysImagesLister, n.sysImages, kd.Windows) + if err != nil { + logrus.Errorf("getK8sServiceOptionsWindows: k8sVersion %s [%v]", k8sVersion, err) + return data, err + } + if svcOptionsWindows != nil { + data["k8s-windows-service-options"] = svcOptionsWindows + } + } + return data, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver_test.go new file mode 100644 index 0000000..a78cdbc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkenodeconfigserver/nodeserver_test.go @@ -0,0 +1,114 @@ +package rkenodeconfigserver + +import ( + "strings" + "testing" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/taints" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" +) + +func TestAppendKubeletArgs(t *testing.T) { + type testCase struct { + name string + currentCommand []string + taints []rketypes.RKETaint + expectedTaintSet map[string]struct{} + } + testCases := []testCase{ + testCase{ + name: "taints args not exists", + currentCommand: []string{"kubelet", "--register-node"}, + taints: []rketypes.RKETaint{ + rketypes.RKETaint{ + Key: "test1", + Value: "value1", + Effect: v1.TaintEffectNoSchedule, + }, + rketypes.RKETaint{ + Key: "test2", + Value: "value2", + Effect: v1.TaintEffectNoSchedule, + }, + }, + expectedTaintSet: map[string]struct{}{ + "test1=value1:NoSchedule": struct{}{}, + "test2=value2:NoSchedule": struct{}{}, + }, + }, + testCase{ + name: "taints args exists", + currentCommand: []string{"kubelet", "--register-node", "--register-with-taints=node-role.kubernetes.io/controlplane=true:NoSchedule"}, + taints: []rketypes.RKETaint{ + rketypes.RKETaint{ + Key: "test1", + Value: "value1", + Effect: v1.TaintEffectNoSchedule, + }, + }, + expectedTaintSet: map[string]struct{}{ + "node-role.kubernetes.io/controlplane=true:NoSchedule": struct{}{}, + "test1=value1:NoSchedule": struct{}{}, + }, + }, + } + for _, tc := range testCases { + processes := getKubeletProcess(tc.currentCommand) + afterAppend := AppendTaintsToKubeletArgs(processes, tc.taints) + appendedCommand := getCommandFromProcesses(afterAppend) + assert.Equal(t, tc.expectedTaintSet, appendedCommand, "", "") + } +} + +func TestShareMntArgs(t *testing.T) { + augmentedProcesses := getAugmentedKubeletProcesses() + args := augmentedProcesses["share-mnt"].Args + // args are agent call params, by default, arg count is 8 with ca it's 9 + assert.Equal(t, 8, len(args), "default args count for share-mnt should 8") +} + +func getKubeletProcess(commands []string) map[string]rketypes.Process { + return map[string]rketypes.Process{ + "kubelet": rketypes.Process{ + Name: "kubelet", + Command: commands, + }, + } +} + +func getAugmentedKubeletProcesses() map[string]rketypes.Process { + var cluster v3.Cluster + command := []string{"dummy"} + binds := []string{"/var/lib/kubelet:/var/lib/kubelet:shared,z", "/var/lib/rancher:/var/lib/rancher:shared,z"} + processes := map[string]rketypes.Process{ + "kubelet": rketypes.Process{ + Name: "kubelet", + Command: command, + Binds: binds, + }, + } + + processes, _ = AugmentProcesses("token", processes, true, "dummynode", &cluster, nil) + return processes +} + +func getCommandFromProcesses(processes map[string]rketypes.Process) map[string]struct{} { + kubelet, ok := processes["kubelet"] + if !ok { + return nil + } + rtn := map[string]struct{}{} + var tmp map[string]int + for _, command := range kubelet.Command { + if strings.HasPrefix(command, "--register-with-taints=") { + tmp = taints.GetTaintSet(taints.GetTaintsFromStrings(strings.Split(strings.TrimPrefix(command, "--register-with-taints="), ","))) + } + } + for key := range tmp { + rtn[key] = struct{}{} + } + return rtn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/docker.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/docker.go new file mode 100644 index 0000000..4e50a1c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/docker.go @@ -0,0 +1,470 @@ +package rkeworker + +import ( + "context" + "fmt" + "io" + "os" + "path/filepath" + "reflect" + "runtime" + "strings" + "time" + + rketypes "github.com/rancher/rke/types" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" + "github.com/docker/go-connections/nat" + "github.com/rancher/rke/hosts" + "github.com/rancher/rke/services" + "github.com/sirupsen/logrus" +) + +const ( + RKEContainerNameLabel = "io.rancher.rke.container.name" + CattleProcessNameLabel = "io.cattle.process.name" + ShareMntContainerName = "share-mnt" + DummyK8sVersion = "v1.22.0-rancher1" +) + +type NodeConfig struct { + ClusterName string `json:"clusterName"` + Certs string `json:"certs"` + Processes map[string]rketypes.Process `json:"processes"` + Files []rketypes.File `json:"files"` + NodeVersion int `json:"nodeVersion"` + AgentCheckInterval int `json:"agentCheckInterval"` +} + +func runProcess(ctx context.Context, name string, p rketypes.Process, start, forceRestart bool) error { + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + args := filters.NewArgs() + args.Add("label", RKEContainerNameLabel+"="+name) + // to handle upgrades of containers created in v2.0.x + oldArgs := filters.NewArgs() + oldArgs.Add("label", CattleProcessNameLabel+"="+name) + + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + return err + } + oldContainers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: oldArgs, + }) + if err != nil { + return err + } + containers = append(containers, oldContainers...) + var matchedContainers []types.Container + for _, container := range containers { + changed, err := changed(ctx, c, p, container) + if err != nil { + return err + } + + if changed { + err := remove(ctx, c, container.ID) + if err != nil { + return err + } + } else { + matchedContainers = append(matchedContainers, container) + if forceRestart { + if err := restart(ctx, c, container.ID); err != nil { + return err + } + } + } + } + for i := 1; i < len(matchedContainers); i++ { + if err := remove(ctx, c, matchedContainers[i].ID); err != nil { + return err + } + } + + if len(matchedContainers) > 0 { + inspect, err := c.ContainerInspect(ctx, matchedContainers[0].ID) + if err != nil { + return err + } + + // share-mnt does not need to be in running state/does not have to be restarted if it ran successfully + if strings.Contains(name, ShareMntContainerName) { + if inspect.State != nil && inspect.State.Status == "exited" && inspect.State.ExitCode == 0 { + return nil + } + } + // ignore service-sidekick if it is present (other containers just use the volumes) + if strings.Contains(name, services.SidekickContainerName) { + return nil + } + + // if container is running, no need to start and run log linker + if inspect.State != nil && inspect.State.Status == "running" { + return nil + } + + c.ContainerStart(ctx, matchedContainers[0].ID, types.ContainerStartOptions{}) + // Both ShareMntContainerName & services.SidekickContainerName are caught before here, we just never need to run it for those containers + if !strings.Contains(name, ShareMntContainerName) && !strings.Contains(name, services.SidekickContainerName) { + runLogLinker(ctx, c, name, p) + } + return nil + } + + // Host is used to determine if selinux is enabled in the Docker daemon, but this is not needed for workers as the components sharing files in service-sidekick all run as privileged + emptyHost := hosts.Host{} + // We pass a dummy k8s version as the function requires it since introducing not rewriting SELinux labels on binds starting with k8s v1.22 + // But as the binds are already properly prepared, this has no other meaning than making sure the function can be used with required parameters + config, hostConfig, _ := services.GetProcessConfig(p, &emptyHost, DummyK8sVersion) + if config.Labels == nil { + config.Labels = map[string]string{} + } + config.Labels[RKEContainerNameLabel] = name + + newContainer, err := c.ContainerCreate(ctx, config, hostConfig, nil, nil, name) + if client.IsErrNotFound(err) { + var output io.ReadCloser + imagePullOptions := types.ImagePullOptions{} + if p.ImageRegistryAuthConfig != "" { + imagePullOptions.RegistryAuth = p.ImageRegistryAuthConfig + imagePullOptions.PrivilegeFunc = func() (string, error) { return p.ImageRegistryAuthConfig, nil } + } + output, err = c.ImagePull(ctx, config.Image, imagePullOptions) + if err != nil { + return err + } + defer output.Close() + io.Copy(logrus.StandardLogger().Writer(), output) + newContainer, err = c.ContainerCreate(ctx, config, hostConfig, nil, nil, name) + } + if err == nil && start { + if err := c.ContainerStart(ctx, newContainer.ID, types.ContainerStartOptions{}); err != nil { + return err + } + if !strings.Contains(name, ShareMntContainerName) { + return runLogLinker(ctx, c, name, p) + } + return nil + } + return err +} + +func remove(ctx context.Context, c *client.Client, id string) error { + return c.ContainerRemove(ctx, id, types.ContainerRemoveOptions{ + Force: true, + RemoveVolumes: true, + }) +} + +func restart(ctx context.Context, c *client.Client, id string) error { + timeoutDuration := 10 * time.Second + return c.ContainerRestart(ctx, id, &timeoutDuration) +} + +func changed(ctx context.Context, c *client.Client, expectedProcess rketypes.Process, container types.Container) (bool, error) { + actualDockerInspect, err := c.ContainerInspect(ctx, container.ID) + if err != nil { + return false, err + } + defaultDockerInspect, _, err := c.ImageInspectWithRaw(ctx, actualDockerInspect.Image) + if err != nil { + return false, err + } + actualProcess := rketypes.Process{ + Command: actualDockerInspect.Config.Entrypoint, + Args: actualDockerInspect.Config.Cmd, + Env: actualDockerInspect.Config.Env, + Image: actualDockerInspect.Config.Image, + Binds: actualDockerInspect.HostConfig.Binds, + NetworkMode: string(actualDockerInspect.HostConfig.NetworkMode), + PidMode: string(actualDockerInspect.HostConfig.PidMode), + Privileged: actualDockerInspect.HostConfig.Privileged, + VolumesFrom: actualDockerInspect.HostConfig.VolumesFrom, + Labels: actualDockerInspect.Config.Labels, + } + + if len(expectedProcess.Command) == 0 { + expectedProcess.Command = actualProcess.Command + } + if len(expectedProcess.Args) == 0 { + expectedProcess.Args = actualProcess.Args + } + if len(expectedProcess.Env) == 0 { + expectedProcess.Env = actualProcess.Env + } + if expectedProcess.NetworkMode == "" { + expectedProcess.NetworkMode = actualProcess.NetworkMode + } + if expectedProcess.PidMode == "" { + expectedProcess.PidMode = actualProcess.PidMode + } + if len(expectedProcess.Labels) == 0 { + expectedProcess.Labels = actualProcess.Labels + } + + // Don't detect changes on these fields + actualProcess.Name = expectedProcess.Name + actualProcess.HealthCheck.URL = expectedProcess.HealthCheck.URL + actualProcess.RestartPolicy = expectedProcess.RestartPolicy + actualProcess.ImageRegistryAuthConfig = expectedProcess.ImageRegistryAuthConfig + + changed := false + t := reflect.TypeOf(actualProcess) + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Name == "Command" { + leftMap := sliceToMap(expectedProcess.Command) + rightMap := sliceToMap(actualProcess.Command) + + if reflect.DeepEqual(leftMap, rightMap) { + continue + } + } else if f.Name == "Env" { + expectedEnvs := make(map[string]string, 8) + for _, env := range defaultDockerInspect.Config.Env { + es := strings.SplitN(env, "=", 2) + if len(es) == 2 { + expectedEnvs[es[0]] = es[1] + } + } + for _, env := range expectedProcess.Env { + es := strings.SplitN(env, "=", 2) + if len(es) == 2 { + expectedEnvs[es[0]] = es[1] + } else { + expectedEnvs[es[0]] = "_host_related_env_" + } + } + + actualEnvs := make(map[string]string, 8) + for _, env := range actualProcess.Env { + es := strings.SplitN(env, "=", 2) + if len(es) == 2 { + actualEnvs[es[0]] = es[1] + } + } + + isNothingChange := true + for expectedEnvName, expectedEnvVal := range expectedEnvs { + if expectedEnvVal == "_host_related_env_" { + continue + } + + if expectedEnvVal != actualEnvs[expectedEnvName] { + isNothingChange = false + break + } + } + if isNothingChange { + continue + } + } else if f.Name == "Labels" { + processLabels := make(map[string]string) + for k, v := range defaultDockerInspect.Config.Labels { + processLabels[k] = v + } + for k, v := range expectedProcess.Labels { + processLabels[k] = v + } + + if reflect.DeepEqual(processLabels, actualProcess.Labels) { + continue + } + } else if f.Name == "Publish" { + expectedExposedPortSet, expectedBindings, err := nat.ParsePortSpecs(reflect.ValueOf(expectedProcess).Field(i).Interface().([]string)) + if err != nil { + return false, err + } + expectedExposedPorts := natPortSetToSlice(expectedExposedPortSet) + nat.SortPortMap(expectedExposedPorts, expectedBindings) + + actualExposedPortSet := make(map[nat.Port]struct{}, 0) + actualBindings := actualDockerInspect.HostConfig.PortBindings + for port := range actualBindings { + if _, exists := actualExposedPortSet[port]; !exists { + actualExposedPortSet[port] = struct{}{} + } + } + actualExposedPorts := natPortSetToSlice(actualExposedPortSet) + nat.SortPortMap(actualExposedPorts, actualBindings) + + if reflect.DeepEqual(actualBindings, nat.PortMap(expectedBindings)) { + continue + } + } + + left := reflect.ValueOf(actualProcess).Field(i).Interface() + right := reflect.ValueOf(expectedProcess).Field(i).Interface() + if !reflect.DeepEqual(left, right) { + logrus.Infof("For process %s, %s has changed from %v to %v", expectedProcess.Name, f.Name, left, right) + changed = true + } + } + + return changed, nil +} + +func sliceToMap(args []string) map[string]bool { + result := map[string]bool{} + for _, arg := range args { + result[arg] = true + } + return result +} + +func natPortSetToSlice(args map[nat.Port]struct{}) []nat.Port { + result := make([]nat.Port, 0, len(args)) + for arg := range args { + result = append(result, arg) + } + return result +} + +func runLogLinker(ctx context.Context, c *client.Client, containerName string, p rketypes.Process) error { + inspect, err := c.ContainerInspect(ctx, containerName) + if err != nil { + return err + } + containerID := inspect.ID + containerLogPath := inspect.LogPath + containerLogLink := fmt.Sprintf("%s/%s_%s.log", hosts.RKELogsPath, containerName, containerID) + logLinkerName := fmt.Sprintf("%s-%s", services.LogLinkContainerName, containerName) + config := &container.Config{ + Image: p.Image, + Entrypoint: []string{ + "sh", + "-c", + fmt.Sprintf("mkdir -p %s ; ln -s %s %s", hosts.RKELogsPath, containerLogPath, containerLogLink), + }, + } + if runtime.GOOS == "windows" { // compatible with Windows + config = &container.Config{ + Image: p.Image, + Entrypoint: []string{ + "pwsh", "-NoLogo", "-NonInteractive", "-Command", + fmt.Sprintf(`& {$d="%s"; $t="%s"; $p="%s"; if (-not (Test-Path -PathType Container -Path $d)) {New-Item -ItemType Directory -Path $d -ErrorAction Ignore | Out-Null;} if (-not (Test-Path -PathType Leaf -Path $p)) {New-Item -ItemType SymbolicLink -Target $t -Path $p | Out-Null;}}`, + filepath.Join("c:/", hosts.RKELogsPath), + containerLogPath, + filepath.Join("c:/", containerLogLink), + ), + }, + } + } + hostConfig := &container.HostConfig{ + Binds: []string{ + "/var/lib:/var/lib", + }, + Privileged: true, + NetworkMode: "none", + } + if runtime.GOOS == "windows" { // compatible with Windows + hostConfig = &container.HostConfig{ + Binds: []string{ + // symbolic link source: docker container logs location + "c:\\ProgramData:c:\\ProgramData", + // symbolic link target + fmt.Sprintf("%svar\\lib:c:\\var\\lib", getWindowsPrefixPath()), + }, + + NetworkMode: "none", + } + } + // remove log linker if its already exists + remove(ctx, c, logLinkerName) + + /* + the following logic is as same as `docker run --rm` + */ + newContainer, err := c.ContainerCreate(ctx, config, hostConfig, nil, nil, logLinkerName) + if err != nil { + return err + } + statusC := waitContainerExit(ctx, c, newContainer.ID) + if err := c.ContainerStart(ctx, newContainer.ID, types.ContainerStartOptions{}); err != nil { + return err + } + status := <-statusC + if err := status.error(); err != nil { + return err + } + return remove(ctx, c, logLinkerName) +} + +func waitContainerExit(rootCtx context.Context, dockerCli *client.Client, containerID string) <-chan containerWaitingStatus { + resultC, errC := dockerCli.ContainerWait(rootCtx, containerID, container.WaitConditionNextExit) + + statusC := make(chan containerWaitingStatus) + go func(ctx context.Context) { + select { + case result := <-resultC: + if result.Error != nil { + statusC <- containerWaitingStatus{ + code: 125, + cause: fmt.Errorf(result.Error.Message), + } + } else { + statusC <- containerWaitingStatus{ + code: int(result.StatusCode), + } + } + case err := <-errC: + statusC <- containerWaitingStatus{ + code: 125, + cause: err, + } + } + }(rootCtx) + + return statusC +} + +type containerWaitingStatus struct { + code int + cause error +} + +func (s containerWaitingStatus) error() error { + if s.code != 0 { + if s.cause != nil { + return s.cause + } + + return fmt.Errorf("exit code %d", s.code) + } + + return nil +} + +func getWindowsPrefixPath() string { + p := os.Getenv("CATTLE_PREFIX_PATH") + if p == "" { + return "c:\\" + } + + // clean backslashes added from encoding + var new []string + + // squash multi backslashes + sp := strings.Split(p, "\\") + for _, v := range sp { + if v != "" { + new = append(new, v) + } + } + + new = append(new, "") // always add trailing slash + return strings.Join(new, "\\") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/execute.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/execute.go new file mode 100644 index 0000000..1d1f640 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/rkeworker/execute.go @@ -0,0 +1,96 @@ +package rkeworker + +import ( + "bytes" + "context" + "encoding/base64" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/rkecerts" + "github.com/sirupsen/logrus" +) + +func ExecutePlan(ctx context.Context, nodeConfig *NodeConfig, writeCertOnly bool) error { + var bundleChanged bool + if nodeConfig.Certs != "" { + bundle, err := rkecerts.Unmarshal(nodeConfig.Certs) + if err != nil { + return err + } + bundleChanged = bundle.Changed() + if err := bundle.Explode(); err != nil { + return err + } + } + + f := fileWriter{} + for _, file := range nodeConfig.Files { + logrus.Debugf("writing file %s", file.Name) + f.write(file.Name, file.Contents) + } + if writeCertOnly { + logrus.Debug("writing certificates only, no need to continue executing plan") + return nil + } + + for name, process := range nodeConfig.Processes { + if strings.Contains(name, "sidekick") || strings.Contains(name, "share-mnt") { + // windows dockerfile VOLUME declaration must to satisfy one of them: + // - a non-existing or empty directory + // - a drive other than C: + // so we could use a script to **start** the container to put expected resources into the "shared" directory, + // like the action of `/usr/bin/sidecar.ps1` for windows rke-tools container + if err := runProcess(ctx, name, process, runtime.GOOS == "windows", false); err != nil { + return err + } + } + } + + for name, process := range nodeConfig.Processes { + if !strings.Contains(name, "sidekick") { + if err := runProcess(ctx, name, process, true, bundleChanged); err != nil { + return err + } + } + } + + return nil +} + +type fileWriter struct { + errs []error +} + +func (f *fileWriter) write(path string, base64Content string) { + if path == "" { + return + } + + content, err := base64.StdEncoding.DecodeString(base64Content) + if err != nil { + f.errs = append(f.errs, err) + return + } + + existing, err := ioutil.ReadFile(path) + if err == nil && bytes.Equal(existing, content) { + return + } + + dir := filepath.Dir(path) + if err := os.MkdirAll(dir, 0700); err != nil { + f.errs = append(f.errs, err) + } + if err := ioutil.WriteFile(path, content, 0600); err != nil { + f.errs = append(f.errs, err) + } +} + +func (f *fileWriter) err() error { + return types.NewErrors(f.errs...) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/schema.go new file mode 100644 index 0000000..41a6a3a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/schema.go @@ -0,0 +1,148 @@ +package schema + +import ( + "reflect" + "strings" + + "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapper" + v3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + "github.com/rancher/rancher/pkg/schemas/factory" + v1 "k8s.io/api/core/v1" + storagev1 "k8s.io/api/storage/v1" + apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" +) + +var ( + Version = types.APIVersion{ + Version: "v3", + Group: "cluster.cattle.io", + Path: "/v3/cluster", + SubContext: true, + SubContextSchema: "/v3/schemas/cluster", + } + + Schemas = factory.Schemas(&Version). + Init(namespaceTypes). + Init(persistentVolumeTypes). + Init(storageClassTypes). + Init(tokens). + Init(apiServiceTypes) +) + +func namespaceTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.NamespaceSpec{}, + &m.Drop{Field: "finalizers"}, + ). + AddMapperForType(&Version, v1.Namespace{}, + &m.AnnotationField{Field: "description"}, + &m.AnnotationField{Field: "projectId"}, + &m.AnnotationField{Field: "resourceQuota", Object: true}, + &m.AnnotationField{Field: "containerDefaultResourceLimit", Object: true}, + &m.Drop{Field: "status"}, + ). + MustImport(&Version, NamespaceResourceQuota{}). + MustImport(&Version, ContainerResourceLimit{}). + MustImport(&Version, v1.Namespace{}, struct { + Description string `json:"description"` + ProjectID string `norman:"type=reference[/v3/schemas/project],noupdate"` + ResourceQuota string `json:"resourceQuota,omitempty" norman:"type=namespaceResourceQuota"` + ContainerDefaultResourceLimit string `json:"containerDefaultResourceLimit,omitempty" norman:"type=containerResourceLimit"` + }{}). + MustImport(&Version, NamespaceMove{}). + MustImportAndCustomize(&Version, v1.Namespace{}, func(schema *types.Schema) { + schema.ResourceActions["move"] = types.Action{ + Input: "namespaceMove", + } + }) +} + +func persistentVolumeTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.PersistentVolume{}, + &m.AnnotationField{Field: "description"}, + ). + AddMapperForType(&Version, v1.HostPathVolumeSource{}, + m.Move{From: "type", To: "kind"}, + m.Enum{ + Options: []string{ + "DirectoryOrCreate", + "Directory", + "FileOrCreate", + "File", + "Socket", + "CharDevice", + "BlockDevice", + }, + Field: "kind", + }, + ). + MustImport(&Version, v1.PersistentVolumeSpec{}, struct { + StorageClassName *string `json:"storageClassName,omitempty" norman:"type=reference[storageClass]"` + }{}). + MustImport(&Version, v1.PersistentVolume{}, struct { + Description string `json:"description"` + }{}). + MustImportAndCustomize(&Version, v1.PersistentVolume{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "hostname" + field.Nullable = false + field.Required = true + return field + }) + schema.MustCustomizeField("volumeMode", func(field types.Field) types.Field { + field.Update = false + return field + }) + // All fields of PersistentVolumeSource are immutable + val := reflect.ValueOf(v1.PersistentVolumeSource{}) + for i := 0; i < val.Type().NumField(); i++ { + if tag, ok := val.Type().Field(i).Tag.Lookup("json"); ok { + name := strings.Split(tag, ",")[0] + schema.MustCustomizeField(name, func(field types.Field) types.Field { + field.Update = false + return field + }) + pvSchema := schemas.Schema(&Version, val.Type().Field(i).Type.String()[4:]) + for name := range pvSchema.ResourceFields { + pvSchema.MustCustomizeField(name, func(field types.Field) types.Field { + field.Update = false + return field + }) + } + } + } + }) +} + +func storageClassTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, storagev1.StorageClass{}, + &m.AnnotationField{Field: "description"}, + ). + MustImport(&Version, storagev1.StorageClass{}, struct { + Description string `json:"description"` + ReclaimPolicy string `json:"reclaimPolicy,omitempty" norman:"type=enum,options=Recycle|Delete|Retain"` + }{}) +} + +func tokens(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImportAndCustomize(&Version, v3.ClusterAuthToken{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + }). + MustImportAndCustomize(&Version, v3.ClusterUserAttribute{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + }) +} + +func apiServiceTypes(Schemas *types.Schemas) *types.Schemas { + return Schemas. + AddMapperForType(&Version, apiregistrationv1.APIService{}, + &m.Embed{Field: "status"}, + ). + MustImport(&Version, apiregistrationv1.APIService{}) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/types.go new file mode 100644 index 0000000..0e99718 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/cluster.cattle.io/v3/types.go @@ -0,0 +1,58 @@ +package schema + +type NodeInfo struct { + CPU CPUInfo + Memory MemoryInfo + OS OSInfo + Kubernetes KubernetesInfo +} + +type CPUInfo struct { + Count int64 +} + +type MemoryInfo struct { + MemTotalKiB int64 +} + +type OSInfo struct { + DockerVersion string + KernelVersion string + OperatingSystem string +} + +type KubernetesInfo struct { + KubeletVersion string + KubeProxyVersion string +} + +type NamespaceResourceQuota struct { + Limit ResourceQuotaLimit `json:"limit,omitempty"` +} + +type ResourceQuotaLimit struct { + Pods string `json:"pods,omitempty"` + Services string `json:"services,omitempty"` + ReplicationControllers string `json:"replicationControllers,omitempty"` + Secrets string `json:"secrets,omitempty"` + ConfigMaps string `json:"configMaps,omitempty"` + PersistentVolumeClaims string `json:"persistentVolumeClaims,omitempty"` + ServicesNodePorts string `json:"servicesNodePorts,omitempty"` + ServicesLoadBalancers string `json:"servicesLoadBalancers,omitempty"` + RequestsCPU string `json:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty"` + RequestsStorage string `json:"requestsStorage,omitempty"` + LimitsCPU string `json:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty"` +} + +type NamespaceMove struct { + ProjectID string `json:"projectId,omitempty"` +} + +type ContainerResourceLimit struct { + RequestsCPU string `json:"requestsCpu,omitempty"` + RequestsMemory string `json:"requestsMemory,omitempty"` + LimitsCPU string `json:"limitsCpu,omitempty"` + LimitsMemory string `json:"limitsMemory,omitempty"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/factory/schemas.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/factory/schemas.go new file mode 100644 index 0000000..7aaa46f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/factory/schemas.go @@ -0,0 +1,32 @@ +package factory + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/factory" + m "github.com/rancher/norman/types/mapper" + "github.com/rancher/rancher/pkg/schemas/mapper" +) + +func Schemas(version *types.APIVersion) *types.Schemas { + schemas := factory.Schemas(version) + baseFunc := schemas.DefaultMappers + schemas.DefaultMappers = func() []types.Mapper { + mappers := append([]types.Mapper{ + &mapper.Status{}, + }, baseFunc()...) + mappers = append(mappers, &m.Scope{ + If: types.NamespaceScope, + Mappers: []types.Mapper{ + &mapper.NamespaceIDMapper{}, + }, + }, &mapper.NamespaceReference{ + VersionPath: "/v3/project", + }) + return mappers + } + basePostFunc := schemas.DefaultPostMappers + schemas.DefaultPostMappers = func() []types.Mapper { + return append(basePostFunc(), &mapper.Creator{}) + } + return schemas +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/schema.go new file mode 100644 index 0000000..22ddc9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/schema.go @@ -0,0 +1,848 @@ +package schema + +import ( + "net/http" + + rketypes "github.com/rancher/rke/types" + + "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapper" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/schemas/factory" + "github.com/rancher/rancher/pkg/schemas/mapper" + v1 "k8s.io/api/core/v1" + "k8s.io/apiserver/pkg/apis/apiserver" +) + +var ( + Version = types.APIVersion{ + Version: "v3", + Group: "management.cattle.io", + Path: "/v3", + } + + AuthSchemas = factory.Schemas(&Version). + Init(authnTypes). + Init(tokens). + Init(userTypes) + + Schemas = factory.Schemas(&Version). + Init(nativeNodeTypes). + Init(nodeTypes). + Init(podSecurityAdmissionTypes). + Init(authzTypes). + Init(clusterTypes). + Init(catalogTypes). + Init(authnTypes). + Init(tokens). + Init(schemaTypes). + Init(userTypes). + Init(projectNetworkPolicyTypes). + Init(globalTypes). + Init(rkeTypes). + Init(composeType). + Init(projectCatalogTypes). + Init(clusterCatalogTypes). + Init(multiClusterAppTypes). + Init(globalDNSTypes). + Init(kontainerTypes). + Init(etcdBackupTypes). + Init(credTypes). + Init(mgmtSecretTypes). + Init(clusterTemplateTypes). + Init(driverMetadataTypes). + Init(encryptionTypes). + Init(fleetTypes). + Init(notificationTypes) + + TokenSchemas = factory.Schemas(&Version). + Init(tokens) +) + +func fleetTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, v3.FleetWorkspace{}) +} + +func rkeTypes(schemas *types.Schemas) *types.Schemas { + return schemas.AddMapperForType(&Version, rketypes.BaseService{}, m.Drop{Field: "image"}). + AddMapperForType(&Version, v1.Taint{}, + m.Enum{Field: "effect", Options: []string{ + string(v1.TaintEffectNoSchedule), + string(v1.TaintEffectPreferNoSchedule), + string(v1.TaintEffectNoExecute), + }}, + m.Required{Fields: []string{ + "effect", + "value", + "key", + }}, + m.ReadOnly{Field: "timeAdded"}, + ). + MustImport(&Version, rketypes.ExtraEnv{}). + MustImport(&Version, rketypes.ExtraVolume{}). + MustImport(&Version, rketypes.ExtraVolumeMount{}). + MustImport(&Version, rketypes.LinearAutoscalerParams{}). + MustImport(&Version, rketypes.DeploymentStrategy{}). + MustImport(&Version, rketypes.DaemonSetUpdateStrategy{}) +} + +func schemaTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImport(&Version, v3.DynamicSchema{}) +} + +func credTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.CloudCredential{}, + &m.DisplayName{}, + &mapper.CredentialMapper{}, + &m.AnnotationField{Field: "name"}, + &m.AnnotationField{Field: "description"}, + &m.Drop{Field: "namespaceId"}). + MustImport(&Version, v3.CloudCredential{}) +} + +func mgmtSecretTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImportAndCustomize(&Version, v1.Secret{}, func(schema *types.Schema) { + schema.ID = "managementSecret" + schema.PluralName = "managementSecrets" + schema.CodeName = "ManagementSecret" + schema.CodeNamePlural = "ManagementSecrets" + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "hostname" + field.Nullable = false + field.Required = true + return field + }) + }) +} + +func driverMetadataTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.RkeK8sSystemImage{}, m.Drop{Field: "namespaceId"}). + AddMapperForType(&Version, v3.RkeK8sServiceOption{}, m.Drop{Field: "namespaceId"}). + AddMapperForType(&Version, v3.RkeAddon{}, m.Drop{Field: "namespaceId"}). + MustImport(&Version, v3.RkeK8sSystemImage{}). + MustImport(&Version, v3.RkeK8sServiceOption{}). + MustImport(&Version, v3.RkeAddon{}) +} + +func catalogTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.Catalog{}, + &m.Move{From: "catalogKind", To: "kind"}, + &m.Embed{Field: "status"}, + &m.Drop{Field: "helmVersionCommits"}, + ). + MustImport(&Version, v3.CatalogRefresh{}). + MustImportAndCustomize(&Version, v3.Catalog{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + schema.CollectionActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + }). + AddMapperForType(&Version, v3.Template{}, + m.DisplayName{}, + ). + MustImport(&Version, v3.Template{}, struct { + VersionLinks map[string]string + }{}). + AddMapperForType(&Version, v3.CatalogTemplate{}, + m.DisplayName{}, + m.Drop{Field: "namespaceId"}, + ). + MustImport(&Version, v3.CatalogTemplate{}, struct { + VersionLinks map[string]string + }{}). + AddMapperForType(&Version, v3.CatalogTemplateVersion{}, + m.Drop{Field: "namespaceId"}, + ). + MustImport(&Version, v3.CatalogTemplateVersion{}). + MustImport(&Version, v3.TemplateVersion{}). + MustImport(&Version, v3.TemplateContent{}) +} + +func nativeNodeTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + TypeName("internalNodeStatus", v1.NodeStatus{}). + TypeName("internalNodeSpec", v1.NodeSpec{}). + AddMapperForType(&Version, v1.NodeStatus{}, + &mapper.NodeAddressMapper{}, + &mapper.OSInfo{}, + &m.Drop{Field: "addresses"}, + &m.Drop{Field: "daemonEndpoints"}, + &m.Drop{Field: "images"}, + &m.Drop{Field: "nodeInfo"}, + &m.Move{From: "conditions", To: "nodeConditions"}, + &m.Drop{Field: "phase"}, + &m.SliceToMap{Field: "volumesAttached", Key: "devicePath"}, + ). + AddMapperForType(&Version, v1.NodeSpec{}, + &m.Drop{Field: "externalID"}, + &m.Drop{Field: "configSource"}, + &m.Move{From: "providerID", To: "providerId"}, + &m.Move{From: "podCIDR", To: "podCidr"}, + &m.Move{From: "podCIDRs", To: "podCidrs"}, + m.Access{Fields: map[string]string{ + "podCidr": "r", + "podCidrs": "r", + "providerId": "r", + "taints": "ru", + "unschedulable": "ru", + }}). + AddMapperForType(&Version, v1.Node{}, + &mapper.NodeAddressAnnotationMapper{}). + MustImportAndCustomize(&Version, v1.NodeSpec{}, func(schema *types.Schema) { + schema.CodeName = "InternalNodeSpec" + schema.CodeNamePlural = "InternalNodeSpecs" + }). + MustImportAndCustomize(&Version, v1.NodeStatus{}, func(schema *types.Schema) { + schema.CodeName = "InternalNodeStatus" + schema.CodeNamePlural = "InternalNodeStatuses" + }, struct { + IPAddress string + ExternalIPAddress string `json:"externalIpAddress,omitempty"` + Hostname string + Info NodeInfo + }{}) +} + +func clusterTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.Cluster{}, + &m.Embed{Field: "status"}, + mapper.NewDropFromSchema("genericEngineConfig"), + mapper.NewDropFromSchema("googleKubernetesEngineConfig"), + mapper.NewDropFromSchema("azureKubernetesServiceConfig"), + mapper.NewDropFromSchema("amazonElasticContainerServiceConfig"), + m.DisplayName{}, + ). + AddMapperForType(&Version, v3.ClusterStatus{}, + m.Drop{Field: "serviceAccountToken"}, + ). + AddMapperForType(&Version, v3.ClusterRegistrationToken{}, + &m.Embed{Field: "status"}, + ). + AddMapperForType(&Version, rketypes.RancherKubernetesEngineConfig{}, + m.Drop{Field: "systemImages"}, + ). + MustImport(&Version, v3.Cluster{}). + MustImport(&Version, v3.ClusterRegistrationToken{}). + MustImport(&Version, v3.GenerateKubeConfigOutput{}). + MustImport(&Version, v3.ImportClusterYamlInput{}). + MustImport(&Version, v3.RotateCertificateInput{}). + MustImport(&Version, v3.RotateCertificateOutput{}). + MustImport(&Version, v3.RotateEncryptionKeyOutput{}). + MustImport(&Version, v3.ImportYamlOutput{}). + MustImport(&Version, v3.ExportOutput{}). + MustImport(&Version, v3.RestoreFromEtcdBackupInput{}). + MustImport(&Version, v3.SaveAsTemplateInput{}). + MustImport(&Version, v3.SaveAsTemplateOutput{}). + AddMapperForType(&Version, v1.EnvVar{}, + &m.Move{ + From: "envVar", + To: "agentEnvVar", + }). + MustImportAndCustomize(&Version, rketypes.ETCDService{}, func(schema *types.Schema) { + schema.MustCustomizeField("extraArgs", func(field types.Field) types.Field { + field.Default = map[string]interface{}{ + "election-timeout": "5000", + "heartbeat-interval": "500"} + return field + }) + }). + MustImportAndCustomize(&Version, v3.Cluster{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabel" + field.Nullable = true + field.Required = false + return field + }) + schema.ResourceActions[v3.ClusterActionGenerateKubeconfig] = types.Action{ + Output: "generateKubeConfigOutput", + } + schema.ResourceActions[v3.ClusterActionImportYaml] = types.Action{ + Input: "importClusterYamlInput", + Output: "importYamlOutput", + } + schema.ResourceActions[v3.ClusterActionExportYaml] = types.Action{ + Output: "exportOutput", + } + schema.ResourceActions[v3.ClusterActionBackupEtcd] = types.Action{} + schema.ResourceActions[v3.ClusterActionRestoreFromEtcdBackup] = types.Action{ + Input: "restoreFromEtcdBackupInput", + } + schema.ResourceActions[v3.ClusterActionRotateCertificates] = types.Action{ + Input: "rotateCertificateInput", + Output: "rotateCertificateOutput", + } + schema.ResourceActions[v3.ClusterActionRotateEncryptionKey] = types.Action{ + Output: "rotateEncryptionKeyOutput", + } + schema.ResourceActions[v3.ClusterActionSaveAsTemplate] = types.Action{ + Input: "saveAsTemplateInput", + Output: "saveAsTemplateOutput", + } + }) +} + +func podSecurityAdmissionTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, v3.PodSecurityAdmissionConfigurationTemplate{}) +} + +func authzTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImport(&Version, v3.ProjectStatus{}). + AddMapperForType(&Version, v3.Project{}, + m.DisplayName{}, + &m.Embed{Field: "status"}, + ). + AddMapperForType(&Version, v3.GlobalRole{}, m.DisplayName{}). + AddMapperForType(&Version, v3.RoleTemplate{}, m.DisplayName{}). + AddMapperForType(&Version, v3.ProjectRoleTemplateBinding{}, + &mapper.NamespaceIDMapper{}, + ). + MustImport(&Version, v3.ImportYamlOutput{}). + MustImportAndCustomize(&Version, v3.Project{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "exportYaml": {}, + } + }). + MustImportAndCustomize(&Version, v3.GlobalRole{}, func(s *types.Schema) { + s.MustCustomizeField("status", func(field types.Field) types.Field { + field.Nullable = false + return field + }) + }). + MustImport(&Version, v3.GlobalRoleBinding{}). + MustImport(&Version, v3.RoleTemplate{}). + MustImport(&Version, v3.ClusterRoleTemplateBinding{}). + MustImport(&Version, v3.ProjectRoleTemplateBinding{}). + MustImport(&Version, v3.GlobalRoleBinding{}) +} + +func nodeTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.NodeSpec{}, &m.Embed{Field: "internalNodeSpec"}). + AddMapperForType(&Version, v3.NodeStatus{}, + &m.Drop{Field: "nodeTemplateSpec"}, + &m.Embed{Field: "internalNodeStatus"}, + &m.Drop{Field: "config"}, + &m.SliceMerge{From: []string{"conditions", "nodeConditions"}, To: "conditions"}). + AddMapperForType(&Version, v3.Node{}, + &m.Embed{Field: "status"}, + &m.Move{From: "rkeNode/user", To: "sshUser"}, + &m.ReadOnly{Field: "sshUser"}, + &m.Drop{Field: "rkeNode"}, + &m.Drop{Field: "labels"}, + &m.Drop{Field: "annotations"}, + &m.Move{From: "nodeLabels", To: "labels"}, + &m.Move{From: "nodeAnnotations", To: "annotations"}, + &m.Drop{Field: "desiredNodeTaints"}, + &m.Drop{Field: "metadataUpdate"}, + &m.Drop{Field: "updateTaintsFromAPI"}, + &m.Drop{Field: "desiredNodeUnschedulable"}, + &m.Drop{Field: "nodeDrainInput"}, + &m.AnnotationField{Field: "publicEndpoints", List: true}, + m.Copy{From: "namespaceId", To: "clusterName"}, + m.DisplayName{}). + AddMapperForType(&Version, v3.NodeDriver{}, m.DisplayName{}). + AddMapperForType(&Version, v3.NodeTemplate{}, m.DisplayName{}). + MustImport(&Version, v3.PublicEndpoint{}). + MustImportAndCustomize(&Version, v3.NodePool{}, func(schema *types.Schema) { + schema.ResourceFields["driver"] = types.Field{ + Type: "string", + CodeName: "Driver", + Create: false, + Update: false, + } + }). + MustImport(&Version, v3.NodeDrainInput{}). + MustImportAndCustomize(&Version, v3.Node{}, func(schema *types.Schema) { + labelField := schema.ResourceFields["labels"] + labelField.Create = true + labelField.Update = true + schema.ResourceFields["labels"] = labelField + annotationField := schema.ResourceFields["annotations"] + annotationField.Create = true + annotationField.Update = true + schema.ResourceFields["annotations"] = annotationField + unschedulable := schema.ResourceFields["unschedulable"] + unschedulable.Create = false + unschedulable.Update = false + schema.ResourceFields["unschedulable"] = unschedulable + clusterField := schema.ResourceFields["clusterId"] + clusterField.Type = "reference[cluster]" + schema.ResourceFields["clusterId"] = clusterField + schema.ResourceActions["cordon"] = types.Action{} + schema.ResourceActions["uncordon"] = types.Action{} + schema.ResourceActions["stopDrain"] = types.Action{} + schema.ResourceActions["scaledown"] = types.Action{} + schema.ResourceActions["drain"] = types.Action{ + Input: "nodeDrainInput", + } + }, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + }{}). + MustImportAndCustomize(&Version, v3.NodeDriver{}, func(schema *types.Schema) { + schema.ResourceActions["activate"] = types.Action{ + Output: "nodeDriver", + } + schema.ResourceActions["deactivate"] = types.Action{ + Output: "nodeDriver", + } + }). + MustImportAndCustomize(&Version, v3.NodeTemplate{}, func(schema *types.Schema) { + delete(schema.ResourceFields, "namespaceId") + }) +} + +func tokens(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImportAndCustomize(&Version, v3.Token{}, func(schema *types.Schema) { + schema.CollectionActions = map[string]types.Action{ + "logout": {}, + } + }) +} + +func authnTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.User{}, m.DisplayName{}, + &m.Embed{Field: "status"}). + AddMapperForType(&Version, v3.Group{}, m.DisplayName{}). + MustImport(&Version, v3.Group{}). + MustImport(&Version, v3.GroupMember{}). + MustImport(&Version, v3.SamlToken{}). + AddMapperForType(&Version, v3.Principal{}, m.DisplayName{}). + MustImportAndCustomize(&Version, v3.Principal{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{http.MethodGet} + schema.ResourceMethods = []string{http.MethodGet} + schema.CollectionActions = map[string]types.Action{ + "search": { + Input: "searchPrincipalsInput", + Output: "collection", + }, + } + }). + MustImport(&Version, v3.SearchPrincipalsInput{}). + MustImport(&Version, v3.ChangePasswordInput{}). + MustImport(&Version, v3.SetPasswordInput{}). + MustImportAndCustomize(&Version, v3.User{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "setpassword": { + Input: "setPasswordInput", + Output: "user", + }, + "refreshauthprovideraccess": {}, + } + schema.CollectionActions = map[string]types.Action{ + "changepassword": { + Input: "changePasswordInput", + }, + "refreshauthprovideraccess": {}, + } + }). + MustImportAndCustomize(&Version, v3.AuthConfig{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{http.MethodGet} + }). + // Local Config + MustImportAndCustomize(&Version, v3.LocalConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + //Github Config + MustImportAndCustomize(&Version, v3.GithubConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "githubConfig", + Output: "githubConfigTestOutput", + }, + "testAndApply": { + Input: "githubConfigApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.GithubConfigTestOutput{}). + MustImport(&Version, v3.GithubConfigApplyInput{}). + //AzureAD Config + MustImportAndCustomize(&Version, v3.AzureADConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "azureADConfig", + Output: "azureADConfigTestOutput", + }, + "testAndApply": { + Input: "azureADConfigApplyInput", + }, + "upgrade": {}, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.AzureADConfigTestOutput{}). + MustImport(&Version, v3.AzureADConfigApplyInput{}). + // Active Directory Config + MustImportAndCustomize(&Version, v3.ActiveDirectoryConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "testAndApply": { + Input: "activeDirectoryTestAndApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.ActiveDirectoryTestAndApplyInput{}). + // OpenLdap Config + MustImportAndCustomize(&Version, v3.OpenLdapConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "testAndApply": { + Input: "openLdapTestAndApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.OpenLdapTestAndApplyInput{}). + // FreeIpa Config + AddMapperForType(&Version, v3.FreeIpaConfig{}, m.Drop{Field: "nestedGroupMembershipEnabled"}). + MustImportAndCustomize(&Version, v3.FreeIpaConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "testAndApply": { + Input: "freeIpaTestAndApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + schema.MustCustomizeField("groupObjectClass", func(f types.Field) types.Field { + f.Default = "groupofnames" + return f + }) + schema.MustCustomizeField("userNameAttribute", func(f types.Field) types.Field { + f.Default = "givenName" + return f + }) + schema.MustCustomizeField("userObjectClass", func(f types.Field) types.Field { + f.Default = "inetorgperson" + return f + }) + schema.MustCustomizeField("groupDNAttribute", func(f types.Field) types.Field { + f.Default = "entrydn" + return f + }) + schema.MustCustomizeField("groupMemberUserAttribute", func(f types.Field) types.Field { + f.Default = "entrydn" + return f + }) + }). + MustImport(&Version, v3.FreeIpaTestAndApplyInput{}). + // Saml Config + // Ping-Saml Config + // KeyCloak-Saml Configs + MustImportAndCustomize(&Version, v3.PingConfig{}, configSchema). + MustImportAndCustomize(&Version, v3.ADFSConfig{}, configSchema). + MustImportAndCustomize(&Version, v3.KeyCloakConfig{}, configSchema). + MustImportAndCustomize(&Version, v3.OKTAConfig{}, configSchema). + MustImportAndCustomize(&Version, v3.ShibbolethConfig{}, configSchema). + MustImport(&Version, v3.SamlConfigTestInput{}). + MustImport(&Version, v3.SamlConfigTestOutput{}). + //GoogleOAuth Config + MustImportAndCustomize(&Version, v3.GoogleOauthConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "googleOauthConfig", + Output: "googleOauthConfigTestOutput", + }, + "testAndApply": { + Input: "googleOauthConfigApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.GoogleOauthConfigApplyInput{}). + MustImport(&Version, v3.GoogleOauthConfigTestOutput{}). + //OIDC Config + MustImportAndCustomize(&Version, v3.OIDCConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "oidcConfig", + Output: "oidcTestOutput", + }, + "testAndApply": { + Input: "oidcApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.OIDCApplyInput{}). + MustImport(&Version, v3.OIDCTestOutput{}). + MustImportAndCustomize(&Version, v3.GenericOIDCConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "genericOIDCConfig", + Output: "genericOIDCTestOutput", + }, + "testAndApply": { + Input: "genericOIDCApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }). + MustImport(&Version, v3.GenericOIDCApplyInput{}). + MustImport(&Version, v3.GenericOIDCTestOutput{}). + //KeyCloakOIDC Config + MustImportAndCustomize(&Version, v3.KeyCloakOIDCConfig{}, func(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "configureTest": { + Input: "keyCloakOidcConfig", + Output: "keyCloakOidcTestOutput", + }, + "testAndApply": { + Input: "keyCloakOidcApplyInput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} + }) +} + +func configSchema(schema *types.Schema) { + schema.BaseType = "authConfig" + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "testAndEnable": { + Input: "samlConfigTestInput", + Output: "samlConfigTestOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet, http.MethodPut} +} + +func userTypes(schema *types.Schemas) *types.Schemas { + return schema. + MustImportAndCustomize(&Version, v3.Preference{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(f types.Field) types.Field { + f.Required = true + return f + }) + schema.MustCustomizeField("namespaceId", func(f types.Field) types.Field { + f.Required = false + return f + }) + }). + MustImportAndCustomize(&Version, v3.UserAttribute{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + // UserAttribute is currently unstructured and norman is unaware of the Duration type + // which requires us to explicitly customize user retention fields + // to be treated as strings. + // The validation of these fields is done in the webhook. + // Once transitioned to the structured UserAttribute, this should be removed. + schema.MustCustomizeField("disableAfter", func(f types.Field) types.Field { + f.Type = "string" + return f + }) + schema.MustCustomizeField("deleteAfter", func(f types.Field) types.Field { + f.Type = "string" + return f + }) + }) +} + +func projectNetworkPolicyTypes(schema *types.Schemas) *types.Schemas { + return schema. + MustImportAndCustomize(&Version, v3.ProjectNetworkPolicy{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{http.MethodGet} + schema.ResourceMethods = []string{http.MethodGet} + }) +} + +func globalTypes(schema *types.Schemas) *types.Schemas { + return schema. + MustImportAndCustomize(&Version, v3.Setting{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(f types.Field) types.Field { + f.Required = true + return f + }) + }). + MustImportAndCustomize(&Version, v3.Feature{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(f types.Field) types.Field { + f.Required = true + return f + }) + }) +} + +func composeType(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, v3.ComposeConfig{}) +} + +func projectCatalogTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.ProjectCatalog{}, + &m.Move{From: "catalogKind", To: "kind"}, + &m.Embed{Field: "status"}, + &m.Drop{Field: "helmVersionCommits"}, + &mapper.NamespaceIDMapper{}). + MustImportAndCustomize(&Version, v3.ProjectCatalog{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + schema.CollectionActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + }) +} + +func clusterCatalogTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.ClusterCatalog{}, + &m.Move{From: "catalogKind", To: "kind"}, + &m.Embed{Field: "status"}, + &m.Drop{Field: "helmVersionCommits"}, + &mapper.NamespaceIDMapper{}). + MustImportAndCustomize(&Version, v3.ClusterCatalog{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + schema.CollectionActions = map[string]types.Action{ + "refresh": {Output: "catalogRefresh"}, + } + }) +} + +func multiClusterAppTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.MultiClusterApp{}, m.Drop{Field: "namespaceId"}). + AddMapperForType(&Version, v3.MultiClusterAppRevision{}, m.Drop{Field: "namespaceId"}). + AddMapperForType(&Version, v3.Member{}, m.Drop{Field: "userName"}, m.Drop{Field: "displayName"}). + MustImport(&Version, v3.MultiClusterApp{}). + MustImport(&Version, v3.Target{}). + MustImport(&Version, v3.UpgradeStrategy{}). + MustImport(&Version, v3.MultiClusterAppRollbackInput{}). + MustImport(&Version, v3.MultiClusterAppRevision{}). + MustImport(&Version, v3.UpdateMultiClusterAppTargetsInput{}). + MustImportAndCustomize(&Version, v3.MultiClusterApp{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "rollback": { + Input: "multiClusterAppRollbackInput", + }, + "addProjects": { + Input: "updateMultiClusterAppTargetsInput", + }, + "removeProjects": { + Input: "updateMultiClusterAppTargetsInput", + }, + } + }) +} + +func globalDNSTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + TypeName("globalDns", v3.GlobalDns{}). + TypeName("globalDnsProvider", v3.GlobalDnsProvider{}). + TypeName("globalDnsSpec", v3.GlobalDNSSpec{}). + TypeName("globalDnsStatus", v3.GlobalDNSStatus{}). + TypeName("globalDnsProviderSpec", v3.GlobalDNSProviderSpec{}). + MustImport(&Version, v3.UpdateGlobalDNSTargetsInput{}). + AddMapperForType(&Version, v3.GlobalDns{}, m.Drop{Field: "namespaceId"}). + AddMapperForType(&Version, v3.GlobalDnsProvider{}, m.Drop{Field: "namespaceId"}). + MustImportAndCustomize(&Version, v3.GlobalDns{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "addProjects": { + Input: "updateGlobalDNSTargetsInput", + }, + "removeProjects": { + Input: "updateGlobalDNSTargetsInput", + }, + } + }). + MustImportAndCustomize(&Version, v3.GlobalDnsProvider{}, func(schema *types.Schema) { + }) +} + +func kontainerTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v3.KontainerDriver{}, + &m.Embed{Field: "status"}, + m.DisplayName{}, + ). + MustImportAndCustomize(&Version, v3.KontainerDriver{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "activate": {}, + "deactivate": {}, + } + schema.CollectionActions = map[string]types.Action{ + "refresh": {}, + } + }) +} + +func etcdBackupTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, v3.EtcdBackup{}) +} + +func clusterTemplateTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + TypeName("clusterTemplate", v3.ClusterTemplate{}). + TypeName("clusterTemplateRevision", v3.ClusterTemplateRevision{}). + AddMapperForType(&Version, v3.ClusterTemplate{}, m.Drop{Field: "namespaceId"}, m.DisplayName{}). + AddMapperForType(&Version, v3.ClusterTemplateRevision{}, + m.Drop{Field: "namespaceId"}, + &m.Embed{Field: "status"}, + m.DisplayName{}). + MustImport(&Version, v3.ClusterTemplateQuestionsOutput{}). + MustImport(&Version, v3.ClusterTemplate{}). + MustImportAndCustomize(&Version, v3.ClusterTemplateRevision{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "disable": {}, + "enable": {}, + } + schema.CollectionActions = map[string]types.Action{ + "listquestions": { + Output: "clusterTemplateQuestionsOutput", + }, + } + }) + +} + +func encryptionTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, rketypes.SecretsEncryptionConfig{}). + MustImport(&Version, apiserver.Key{}, struct { + Secret string `norman:"type=password"` + }{}).MustImport(&Version, apiserver.KMSConfiguration{}, struct { + Timeout string + }{}) +} + +func notificationTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImport(&Version, v3.RancherUserNotification{}) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/types.go new file mode 100644 index 0000000..d0a14cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3/types.go @@ -0,0 +1,27 @@ +package schema + +type NodeInfo struct { + CPU CPUInfo + Memory MemoryInfo + OS OSInfo + Kubernetes KubernetesInfo +} + +type CPUInfo struct { + Count int64 +} + +type MemoryInfo struct { + MemTotalKiB int64 +} + +type OSInfo struct { + DockerVersion string + KernelVersion string + OperatingSystem string +} + +type KubernetesInfo struct { + KubeletVersion string + KubeProxyVersion string +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3public/public_schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3public/public_schema.go new file mode 100644 index 0000000..826770a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/management.cattle.io/v3public/public_schema.go @@ -0,0 +1,220 @@ +package schema + +import ( + "net/http" + + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/schemas/factory" +) + +var ( + PublicVersion = types.APIVersion{ + Version: "v3public", + Group: "management.cattle.io", + Path: "/v3-public", + } + + PublicSchemas = factory.Schemas(&PublicVersion). + Init(authProvidersTypes) +) + +func authProvidersTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImportAndCustomize(&PublicVersion, v3.Token{}, func(schema *types.Schema) { + // No collection methods causes the store to not create a CRD for it + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{} + }). + MustImportAndCustomize(&PublicVersion, v3.AuthToken{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{http.MethodGet, http.MethodDelete} + schema.ResourceMethods = []string{http.MethodGet, http.MethodDelete} + }). + MustImportAndCustomize(&PublicVersion, v3.AuthProvider{}, func(schema *types.Schema) { + schema.CollectionMethods = []string{http.MethodGet} + }). + // Local provider + MustImportAndCustomize(&PublicVersion, v3.LocalProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "basicLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.BasicLogin{}). + // Github provider + MustImportAndCustomize(&PublicVersion, v3.GithubProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "githubLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.GithubLogin{}). + // Google OAuth provider + MustImportAndCustomize(&PublicVersion, v3.GoogleOAuthProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "googleOauthLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.GoogleOauthLogin{}). + // Active Directory provider + MustImportAndCustomize(&PublicVersion, v3.ActiveDirectoryProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "basicLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + // Azure AD provider + MustImportAndCustomize(&PublicVersion, v3.AzureADProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "azureADLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.AzureADLogin{}). + // Saml provider + MustImportAndCustomize(&PublicVersion, v3.PingProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "samlLoginInput", + Output: "samlLoginOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImportAndCustomize(&PublicVersion, v3.ADFSProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "samlLoginInput", + Output: "samlLoginOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImportAndCustomize(&PublicVersion, v3.KeyCloakProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "samlLoginInput", + Output: "samlLoginOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImportAndCustomize(&PublicVersion, v3.OKTAProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "samlLoginInput", + Output: "samlLoginOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImportAndCustomize(&PublicVersion, v3.ShibbolethProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "samlLoginInput", + Output: "samlLoginOutput", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.SamlLoginInput{}). + MustImport(&PublicVersion, v3.SamlLoginOutput{}). + // OpenLdap provider + MustImportAndCustomize(&PublicVersion, v3.OpenLdapProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "basicLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + // FreeIpa provider + MustImportAndCustomize(&PublicVersion, v3.FreeIpaProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "basicLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + // OIDC provider + MustImportAndCustomize(&PublicVersion, v3.OIDCProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "oidcLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.OIDCLogin{}). + MustImportAndCustomize(&PublicVersion, v3.GenericOIDCProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "oidcLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.OIDCLogin{}). + // KeyCloak OIDC provider + MustImportAndCustomize(&PublicVersion, v3.KeyCloakOIDCProvider{}, func(schema *types.Schema) { + schema.BaseType = "authProvider" + schema.ResourceActions = map[string]types.Action{ + "login": { + Input: "keyCloakOidcLogin", + Output: "token", + }, + } + schema.CollectionMethods = []string{} + schema.ResourceMethods = []string{http.MethodGet} + }). + MustImport(&PublicVersion, v3.OIDCLogin{}) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_ports.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_ports.go new file mode 100644 index 0000000..8b2209e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_ports.go @@ -0,0 +1,119 @@ +package mapper + +import ( + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/mapper" + "github.com/rancher/norman/types/values" + "github.com/sirupsen/logrus" +) + +type ContainerPorts struct { +} + +func (n ContainerPorts) FromInternal(data map[string]interface{}) { + field := mapper.AnnotationField{ + Field: "ports", + List: true, + } + field.FromInternal(data) + + containers := convert.ToInterfaceSlice(data["containers"]) + annotationPorts := convert.ToInterfaceSlice(data["ports"]) + annotationsPortsMap := map[string]map[string]interface{}{} + + // process fields defined via annotations + for i := 0; i < len(annotationPorts) && i < len(containers); i++ { + container := convert.ToMapInterface(containers[i]) + if container != nil { + portsSlice := convert.ToInterfaceSlice(annotationPorts[i]) + portMap := map[string]interface{}{} + for _, port := range portsSlice { + asMap, err := convert.EncodeToMap(port) + if err != nil { + logrus.Warnf("Failed to convert container port to map %v", err) + continue + } + asMap["type"] = "/v3/project/schemas/containerPort" + name, _ := values.GetValue(asMap, "name") + portMap[convert.ToString(name)] = asMap + } + containerName, _ := values.GetValue(container, "name") + annotationsPortsMap[convert.ToString(containerName)] = portMap + } + } + + for _, container := range containers { + // iterate over container ports and see if some of them are not defined via annotation + // set kind to hostport if source port is set, and clusterip if it is not + containerMap := convert.ToMapInterface(container) + containerName, _ := values.GetValue(containerMap, "name") + portMap := annotationsPortsMap[convert.ToString(containerName)] + if portMap == nil { + portMap = map[string]interface{}{} + } + var containerPorts []interface{} + containerPortSlice := convert.ToInterfaceSlice(containerMap["ports"]) + for _, port := range containerPortSlice { + asMap, err := convert.EncodeToMap(port) + if err != nil { + logrus.Warnf("Failed to convert container port to map %v", err) + continue + } + portName, _ := values.GetValue(asMap, "name") + if annotationPort, ok := portMap[convert.ToString(portName)]; ok { + containerPorts = append(containerPorts, annotationPort) + } else { + hostPort, _ := values.GetValue(asMap, "hostPort") + if hostPort == nil { + asMap["kind"] = "ClusterIP" + } else { + asMap["sourcePort"] = hostPort + asMap["kind"] = "HostPort" + } + containerPorts = append(containerPorts, asMap) + } + } + containerMap["ports"] = containerPorts + } + +} + +func (n ContainerPorts) ToInternal(data map[string]interface{}) error { + field := mapper.AnnotationField{ + Field: "ports", + List: true, + } + + var ports []interface{} + path := []string{"containers", "{ARRAY}", "ports"} + convert.Transform(data, path, func(obj interface{}) interface{} { + if l, ok := obj.([]interface{}); ok { + for _, p := range l { + mapped, err := convert.EncodeToMap(p) + if err != nil { + logrus.Warnf("Failed to encode port: %v", err) + return obj + } + if strings.EqualFold(convert.ToString(mapped["kind"]), "HostPort") { + mapped["hostPort"] = mapped["sourcePort"] + } + } + ports = append(ports, l) + } + return obj + }) + + if len(ports) != 0 { + data["ports"] = ports + return field.ToInternal(data) + } + + return nil +} + +func (n ContainerPorts) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_probe.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_probe.go new file mode 100644 index 0000000..ed5c7b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_probe.go @@ -0,0 +1,25 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type ContainerProbeHandler struct { +} + +func (n ContainerProbeHandler) FromInternal(data map[string]interface{}) { + value := values.GetValueN(data, "tcpSocket", "port") + if !convert.IsAPIObjectEmpty(value) { + data["tcp"] = true + } +} + +func (n ContainerProbeHandler) ToInternal(data map[string]interface{}) error { + return nil +} + +func (n ContainerProbeHandler) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_status.go new file mode 100644 index 0000000..980ce06 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/container_status.go @@ -0,0 +1,105 @@ +package mapper + +import ( + "fmt" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type ContainerStatus struct { +} + +type containerState struct { + state string + message string + transitioning string + exitCode interface{} + restartCount int64 +} + +func message(m map[string]interface{}) string { + if m["message"] == nil { + return convert.ToString(m["reason"]) + } + return fmt.Sprintf("%s: %s", m["reason"], m["message"]) +} + +func checkStatus(containerStates map[string]containerState, containerStatus []map[string]interface{}) { + for _, status := range containerStatus { + name := convert.ToString(status["name"]) + restartCount, _ := convert.ToNumber(status["restartCount"]) + s := containerState{ + state: "pending", + restartCount: restartCount, + transitioning: "no", + } + for k, v := range convert.ToMapInterface(status["state"]) { + m := convert.ToMapInterface(v) + switch k { + case "terminated": + s.state = "terminated" + s.message = message(m) + s.exitCode = m["exitCode"] + if convert.ToString(s.exitCode) == "0" { + s.transitioning = "no" + } else { + s.transitioning = "error" + } + case "running": + ready := convert.ToBool(status["ready"]) + if ready { + s.state = "running" + s.transitioning = "no" + } else { + s.state = "notready" + s.transitioning = "yes" + } + case "waiting": + s.state = "waiting" + s.transitioning = "yes" + s.message = message(m) + } + } + + containerStates[name] = s + } +} + +func (n ContainerStatus) FromInternal(data map[string]interface{}) { + containerStates := map[string]containerState{} + containerStatus := convert.ToMapSlice(values.GetValueN(data, "status", "containerStatuses")) + checkStatus(containerStates, containerStatus) + + containerStatus = convert.ToMapSlice(values.GetValueN(data, "status", "initContainerStatuses")) + checkStatus(containerStates, containerStatus) + + containers := append(convert.ToMapSlice(values.GetValueN(data, "containers")), + convert.ToMapSlice(values.GetValueN(data, "initContainers"))...) + for _, container := range containers { + if container == nil { + continue + } + + name := convert.ToString(container["name"]) + state, ok := containerStates[name] + if ok { + container["state"] = state.state + container["transitioning"] = state.transitioning + container["transitioningMessage"] = state.message + container["restartCount"] = state.restartCount + container["exitCode"] = state.exitCode + } else { + container["state"] = "unknown" + } + } +} + +func (n ContainerStatus) ToInternal(data map[string]interface{}) error { + return nil +} + +func (n ContainerStatus) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/creator.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/creator.go new file mode 100644 index 0000000..e70fc4b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/creator.go @@ -0,0 +1,35 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/mapper" +) + +type Creator struct { + m types.Mapper +} + +func (c *Creator) FromInternal(data map[string]interface{}) { + if c.m != nil { + c.m.FromInternal(data) + } +} + +func (c *Creator) ToInternal(data map[string]interface{}) error { + if c.m != nil { + return c.m.ToInternal(data) + } + return nil +} + +func (c *Creator) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + if schema.CanList(nil) == nil && schema.CanCreate(nil) == nil { + schema.ResourceFields["creatorId"] = types.Field{ + Type: "reference[/v3/schemas/user]", + CodeName: "CreatorID", + } + c.m = &mapper.AnnotationField{Field: "creatorId"} + return c.m.ModifySchema(schema, schemas) + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/credentialmapper.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/credentialmapper.go new file mode 100644 index 0000000..8e426f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/credentialmapper.go @@ -0,0 +1,78 @@ +package mapper + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type CredentialMapper struct { +} + +func (s CredentialMapper) FromInternal(data map[string]interface{}) { + formatData(data) + name := convert.ToString(values.GetValueN(data, "annotations", "field.cattle.io/name")) + if name == "" { + id := convert.ToString(values.GetValueN(data, "id")) + if id != "" { + values.PutValue(data, id, "annotations", "field.cattle.io/name") + } + } + delete(data, "data") +} + +func (s CredentialMapper) ToInternal(data map[string]interface{}) error { + updateData(data) + return nil +} + +func (s CredentialMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} + +func updateData(data map[string]interface{}) { + stringData := map[string]string{} + for key, val := range data { + if val == nil { + continue + } + if strings.HasSuffix(key, "Config") { + for key2, val2 := range convert.ToMapInterface(val) { + stringData[fmt.Sprintf("%s-%s", key, key2)] = convert.ToString(val2) + } + values.PutValue(data, stringData, "stringData") + delete(data, key) + return + } + } +} + +func formatData(data map[string]interface{}) { + secretData := convert.ToMapInterface(data["data"]) + getKey := func(data map[string]interface{}) string { + for key := range data { + splitKeys := strings.Split(key, "-") + if len(splitKeys) != 2 { + continue + } + if strings.HasSuffix(splitKeys[0], "Config") { + return splitKeys[0] + } + } + return "" + } + config := getKey(secretData) + if config == "" { + return + } + for key, val := range secretData { + splitKeys := strings.Split(key, "-") + if len(splitKeys) != 2 { + continue + } + values.PutValue(data, convert.ToString(val), config, splitKeys[1]) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/cross_version_object.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/cross_version_object.go new file mode 100644 index 0000000..b4fe4bf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/cross_version_object.go @@ -0,0 +1,76 @@ +package mapper + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types/values" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" +) + +var ( + kindMap = map[string]string{ + "deployment": "Deployment", + "replicationcontroller": "ReplicationController", + "statefulset": "StatefulSet", + "daemonset": "DaemonSet", + "job": "Job", + "cronjob": "CronJob", + "replicaset": "ReplicaSet", + } + groupVersionMap = map[string]string{ + "deployment": "apps/v1beta2", + "replicationcontroller": "core/v1", + "statefulset": "apps/v1beta2", + "daemonset": "apps/v1beta2", + "job": "batch/v1", + "cronjob": "batch/v1beta1", + "replicaset": "apps/v1beta2", + } +) + +type CrossVersionObjectToWorkload struct { + Field string +} + +func (c CrossVersionObjectToWorkload) ToInternal(data map[string]interface{}) error { + obj, ok := values.GetValue(data, strings.Split(c.Field, "/")...) + if !ok { + return nil + } + workloadID := convert.ToString(obj) + parts := strings.SplitN(workloadID, ":", 3) + newObj := map[string]interface{}{ + "kind": getKind(parts[0]), + "apiVersion": groupVersionMap[parts[0]], + "name": parts[2], + } + values.PutValue(data, newObj, strings.Split(c.Field, "/")...) + return nil +} + +func (c CrossVersionObjectToWorkload) FromInternal(data map[string]interface{}) { + obj, ok := values.GetValue(data, strings.Split(c.Field, "/")...) + if !ok { + return + } + cvo := convert.ToMapInterface(obj) + ns := convert.ToString(data["namespaceId"]) + values.PutValue(data, + fmt.Sprintf("%s:%s:%s", + strings.ToLower(convert.ToString(cvo["kind"])), + ns, + convert.ToString(cvo["name"])), + strings.Split(c.Field, "/")..., + ) +} + +func (c CrossVersionObjectToWorkload) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} + +func getKind(i string) string { + return kindMap[i] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/drop_from_schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/drop_from_schema.go new file mode 100644 index 0000000..c34f0bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/drop_from_schema.go @@ -0,0 +1,23 @@ +package mapper + +import "github.com/rancher/norman/types/mapper" + +// DropFromSchema This mapper differs from the existing drop mapper in that +// it does not remove the field if it is present, only removing the field from +// the schema. This is so that fields that must be present for formatters and +// stores will be available, but not shown on the schema +type DropFromSchema struct { + mapper.Drop +} + +func NewDropFromSchema(name string) *DropFromSchema { + return &DropFromSchema{ + mapper.Drop{ + Field: name, + }, + } +} + +func (d DropFromSchema) FromInternal(data map[string]interface{}) { + // Do nothing +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/ingress_backend.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/ingress_backend.go new file mode 100644 index 0000000..0d866a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/ingress_backend.go @@ -0,0 +1,106 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +// These mappers copy data from the networking.k8s.io/v1-style Ingress fields +// to extensions/v1beta1-style Ingress fields so that when the proxy store +// serializes them into kubernetes resources, there is no loss of data and the +// objects are in the expected format for the API in use. The end result is +// that some data is duplicated on the object, but extraneous fields will be +// ignored by the proxy store. + +// IngressSpec mapper copies defaultBackend (type k8s.io/api/networking/v1.IngressBackend) +// to backend (type k8s.io/api/extensions/v1beta1.IngressBackend) on Spec. +type IngressSpec struct{} + +func (i IngressSpec) FromInternal(data map[string]interface{}) { + if _, ok := data["backend"]; ok && data["defaultBackend"] == nil { + data["defaultBackend"] = map[string]interface{}{ + "targetPort": values.GetValueN(data, "backend", "servicePort"), + "serviceId": values.GetValueN(data, "backend", "serviceName"), + } + delete(data, "backend") + } + return +} + +func (i IngressSpec) ToInternal(data map[string]interface{}) error { + if backend, ok := data["backend"]; (!ok || backend == nil) && data["defaultBackend"] != nil { + data["backend"] = map[string]interface{}{ + "servicePort": values.GetValueN(data, "defaultBackend", "targetPort"), + "serviceName": values.GetValueN(data, "defaultBackend", "serviceId"), + } + } + return nil +} + +func (i IngressSpec) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} + +// IngressBackend mapper copies service fields within +// k8s.io/api/networking/v1.IngressBackend to the equivalents in +// k8s.io/api/extensions/v1beta1.IngressBackend. +// Applies to the Spec.DefaultBackend and Spec.Rules[*].Backend. +type IngressBackend struct{} + +func (i IngressBackend) FromInternal(data map[string]interface{}) { + if data == nil { + return + } + if serviceID, ok := data["serviceId"]; !ok || serviceID == nil { + data["serviceId"] = values.GetValueN(data, "serviceName") + } + if targetPort, ok := data["targetPort"]; !ok || targetPort == nil { + if port := values.GetValueN(data, "servicePort"); port != nil { + data["targetPort"] = port + } else if port := values.GetValueN(data, "service", "port", "number"); port != nil { + data["targetPort"] = port + } else if port := values.GetValueN(data, "service", "port", "name"); port != nil { + data["targetPort"] = port + } + } +} + +func (i IngressBackend) ToInternal(data map[string]interface{}) error { + if data != nil { + serviceID := values.GetValueN(data, "serviceId") + values.PutValue(data, serviceID, "serviceName") + values.PutValue(data, serviceID, "service", "name") + port := values.GetValueN(data, "targetPort") + data["servicePort"] = port + switch port.(type) { + case int64: + values.PutValue(data, port, "service", "port", "number") + case string: + values.PutValue(data, port, "service", "port", "name") + } + } + return nil +} + +func (i IngressBackend) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} + +// IngressPath mapper applies the required pathType field to +// k8s.io/api/networking/v1.HTTPIngressPath. +type IngressPath struct{} + +func (i IngressPath) FromInternal(data map[string]interface{}) { + return +} + +func (i IngressPath) ToInternal(data map[string]interface{}) error { + if values.GetValueN(data, "pathType") == nil { + values.PutValue(data, "ImplementationSpecific", "pathType") + } + return nil +} + +func (i IngressPath) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/init_container.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/init_container.go new file mode 100644 index 0000000..ac78868 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/init_container.go @@ -0,0 +1,51 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" +) + +type InitContainerMapper struct { +} + +func (e InitContainerMapper) FromInternal(data map[string]interface{}) { + containers, _ := data["containers"].([]interface{}) + + for _, initContainer := range convert.ToMapSlice(data["initContainers"]) { + if initContainer == nil { + continue + } + initContainer["initContainer"] = true + containers = append(containers, initContainer) + } + + if data != nil { + data["containers"] = containers + } +} + +func (e InitContainerMapper) ToInternal(data map[string]interface{}) error { + var newContainers []interface{} + var newInitContainers []interface{} + + for _, container := range convert.ToMapSlice(data["containers"]) { + if convert.ToBool(container["initContainer"]) { + newInitContainers = append(newInitContainers, container) + } else { + newContainers = append(newContainers, container) + } + delete(container, "initContainer") + } + + if data != nil { + data["containers"] = newContainers + data["initContainers"] = newInitContainers + } + + return nil +} + +func (e InitContainerMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + delete(schema.ResourceFields, "initContainers") + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index.go new file mode 100644 index 0000000..0bfa22a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index.go @@ -0,0 +1,111 @@ +package mapper + +import ( + "fmt" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/definition" + "github.com/rancher/norman/types/mapper" +) + +func NewMergeListByIndexMapper(From, To string, Ignores ...string) *MergeListByIndexMapper { + rtn := MergeListByIndexMapper{ + From: From, + To: To, + Ignore: make(map[string]struct{}), + fromFields: []string{}, + } + for _, Ignore := range Ignores { + rtn.Ignore[Ignore] = struct{}{} + } + return &rtn +} + +type MergeListByIndexMapper struct { + From string + To string + Ignore map[string]struct{} + fromFields []string +} + +func (m *MergeListByIndexMapper) FromInternal(data map[string]interface{}) { + fromObj, ok := data[m.From] + if !ok { + return + } + toObj, ok := data[m.To] + if !ok { + return + } + fromList := convert.ToMapSlice(fromObj) + toList := convert.ToMapSlice(toObj) + for i := 0; i < len(fromList) && i < len(toList); i++ { + fromItem := fromList[i] + toItem := toList[i] + for key, value := range fromItem { + if _, ignore := m.Ignore[key]; ignore { + continue + } + toItem[key] = value + } + } + delete(data, m.From) +} + +func (m *MergeListByIndexMapper) ToInternal(data map[string]interface{}) error { + toObj, ok := data[m.To] + if !ok { + return nil + } + if _, ok = data[m.From]; ok { + return fmt.Errorf("field %s should not exist", m.From) + } + + toList := convert.ToMapSlice(toObj) + var fromList []map[string]interface{} + for _, toItem := range toList { + obj := make(map[string]interface{}) + for _, field := range m.fromFields { + value, ok := toItem[field] + if !ok { + continue + } + obj[field] = value + if _, ok := m.Ignore[field]; !ok { + delete(toItem, field) + } + } + fromList = append(fromList, obj) + } + data[m.From] = fromList + return nil +} + +func (m *MergeListByIndexMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + if err := mapper.ValidateField(m.From, schema); err != nil { + return err + } + + fromType := schema.ResourceFields[m.From].Type + if !definition.IsArrayType(fromType) { + return fmt.Errorf("type of field %s in schema %s is not array", m.From, schema.CodeName) + } + + fromSchema := schemas.Schema(&schema.Version, definition.SubType(fromType)) + for field := range fromSchema.ResourceFields { + m.fromFields = append(m.fromFields, field) + } + + if err := mapper.ValidateField(m.To, schema); err != nil { + return err + } + + toType := schema.ResourceFields[m.To].Type + if !definition.IsArrayType(toType) { + return fmt.Errorf("type of field %s in schema %s is not array", m.To, schema.CodeName) + } + + delete(schema.ResourceFields, m.From) + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index_test.go new file mode 100644 index 0000000..4d1b228 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/merge_list_by_index_test.go @@ -0,0 +1,38 @@ +package mapper + +import ( + "reflect" + "testing" +) + +var ( + metrics = []map[string]interface{}{ + {"type": "Resource", "resource": "abc"}, + {"type": "Object", "object": "def"}, + } + currentMetrics = []map[string]interface{}{ + {"type": "Resource", "currentResource": "tuvw"}, + {"type": "Object", "currentObject": "xyz"}, + } + origin = map[string]interface{}{ + "metrics": metrics, + "currentMetrics": currentMetrics, + } +) + +func Test_MergeList(t *testing.T) { + mapper := NewMergeListByIndexMapper("currentMetrics", "metrics", "type") + mapper.fromFields = []string{"type", "currentResource", "currentObject"} + internal := map[string]interface{}{ + "metrics": metrics, + "currentMetrics": currentMetrics, + } + mapper.FromInternal(internal) + + if err := mapper.ToInternal(internal); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(internal, origin) { + t.Fatal("merge list not match after parse") + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace.go new file mode 100644 index 0000000..883b348 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace.go @@ -0,0 +1,42 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/mapper" +) + +type NamespaceIDMapper struct { + Move *mapper.Move +} + +func (n *NamespaceIDMapper) FromInternal(data map[string]interface{}) { + if n.Move != nil { + n.Move.FromInternal(data) + } +} + +func (n *NamespaceIDMapper) ToInternal(data map[string]interface{}) error { + if n.Move != nil { + return n.Move.ToInternal(data) + } + return nil +} + +func (n *NamespaceIDMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + field, ok := schema.ResourceFields["namespace"] + if !ok { + return nil + } + + field.Type = "reference[/v3/clusters/schemas/namespace]" + field.Required = true + field.Update = false + schema.ResourceFields["namespace"] = field + + n.Move = &mapper.Move{ + From: "namespace", + To: "namespaceId", + } + + return n.Move.ModifySchema(schema, schemas) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace_reference.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace_reference.go new file mode 100644 index 0000000..428ce5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/namespace_reference.go @@ -0,0 +1,90 @@ +package mapper + +import ( + "strings" + + "fmt" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/definition" +) + +type NamespaceReference struct { + fields [][]string + VersionPath string +} + +func (n *NamespaceReference) FromInternal(data map[string]interface{}) { + namespaceID, ok := data["namespaceId"] + if ok { + for _, path := range n.fields { + convert.Transform(data, path, func(input interface{}) interface{} { + parts := strings.SplitN(convert.ToString(input), ":", 2) + if len(parts) == 2 { + return input + } + return fmt.Sprintf("%s:%v", namespaceID, input) + }) + } + } +} + +func (n *NamespaceReference) ToInternal(data map[string]interface{}) error { + namespaceID, ok := data["namespaceId"] + for _, path := range n.fields { + convert.Transform(data, path, func(input interface{}) interface{} { + parts := strings.SplitN(convert.ToString(input), ":", 2) + if len(parts) == 2 && (!ok || parts[0] == namespaceID) { + return parts[1] + } + return input + }) + } + + return nil +} + +func (n *NamespaceReference) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + _, hasNamespace := schema.ResourceFields["namespaceId"] + if schema.Version.Path != n.VersionPath || !hasNamespace { + return nil + } + n.fields = traverse(nil, schema, schemas) + return nil +} + +func traverse(prefix []string, schema *types.Schema, schemas *types.Schemas) [][]string { + var result [][]string + + for name, field := range schema.ResourceFields { + localPrefix := []string{name} + subType := field.Type + if definition.IsArrayType(field.Type) { + localPrefix = append(localPrefix, "{ARRAY}") + subType = definition.SubType(field.Type) + } else if definition.IsMapType(field.Type) { + localPrefix = append(localPrefix, "{MAP}") + subType = definition.SubType(field.Type) + } + if definition.IsReferenceType(subType) { + result = appendReference(result, prefix, localPrefix, field, schema, schemas) + continue + } + + subSchema := schemas.Schema(&schema.Version, subType) + if subSchema != nil { + result = append(result, traverse(append(prefix, localPrefix...), subSchema, schemas)...) + } + } + + return result +} + +func appendReference(result [][]string, prefix []string, name []string, field types.Field, schema *types.Schema, schemas *types.Schemas) [][]string { + targetSchema := schemas.Schema(&schema.Version, definition.SubType(field.Type)) + if targetSchema != nil && targetSchema.Scope == types.NamespaceScope { + result = append(result, append(prefix, name...)) + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/node_address.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/node_address.go new file mode 100644 index 0000000..4f1794a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/node_address.go @@ -0,0 +1,54 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +const ( + extIPField = "externalIpAddress" +) + +type NodeAddressMapper struct { +} + +func (n NodeAddressMapper) FromInternal(data map[string]interface{}) { + addresses, _ := values.GetSlice(data, "addresses") + for _, address := range addresses { + t := address["type"] + a := address["address"] + if t == "InternalIP" { + data["ipAddress"] = a + } else if t == "ExternalIP" { + data[extIPField] = a + } else if t == "Hostname" { + data["hostname"] = a + } + } +} + +func (n NodeAddressMapper) ToInternal(data map[string]interface{}) error { + return nil +} + +func (n NodeAddressMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} + +type NodeAddressAnnotationMapper struct { +} + +func (n NodeAddressAnnotationMapper) FromInternal(data map[string]interface{}) { + externalIP, ok := values.GetValue(data, "status", "nodeAnnotations", "rke.cattle.io/external-ip") + if ok { + data[extIPField] = externalIP + } +} + +func (n NodeAddressAnnotationMapper) ToInternal(data map[string]interface{}) error { + return nil +} + +func (n NodeAddressAnnotationMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info.go new file mode 100644 index 0000000..e0bffcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info.go @@ -0,0 +1,54 @@ +package mapper + +import ( + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + "k8s.io/apimachinery/pkg/api/resource" +) + +type OSInfo struct { +} + +func (o OSInfo) FromInternal(data map[string]interface{}) { + if data == nil { + return + } + cpuInfo := map[string]interface{}{} + cpuNum, err := resource.ParseQuantity(convert.ToString(values.GetValueN(data, "capacity", "cpu"))) + if err == nil { + cpuInfo["count"] = cpuNum.Value() + } + + memoryInfo := map[string]interface{}{} + kibNum, err := resource.ParseQuantity(convert.ToString(values.GetValueN(data, "capacity", "memory"))) + if err == nil { + memoryInfo["memTotalKiB"] = kibNum.Value() / 1024 + } + + osInfo := map[string]interface{}{ + "dockerVersion": strings.TrimPrefix(convert.ToString(values.GetValueN(data, "nodeInfo", "containerRuntimeVersion")), "docker://"), + "kernelVersion": values.GetValueN(data, "nodeInfo", "kernelVersion"), + "operatingSystem": values.GetValueN(data, "nodeInfo", "osImage"), + } + + data["info"] = map[string]interface{}{ + "cpu": cpuInfo, + "memory": memoryInfo, + "os": osInfo, + "kubernetes": map[string]interface{}{ + "kubeletVersion": values.GetValueN(data, "nodeInfo", "kubeletVersion"), + "kubeProxyVersion": values.GetValueN(data, "nodeInfo", "kubeletVersion"), + }, + } +} + +func (o OSInfo) ToInternal(data map[string]interface{}) error { + return nil +} + +func (o OSInfo) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info_test.go new file mode 100644 index 0000000..0227cc0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/os_info_test.go @@ -0,0 +1,73 @@ +package mapper + +import ( + "reflect" + "testing" +) + +func Test_OsInfo(t *testing.T) { + mapper := OSInfo{} + + tests := []struct { + internal map[string]interface{} + wantInfo map[string]interface{} + }{ + { + internal: map[string]interface{}{ + "capacity": map[string]interface{}{ + "cpu": "2", + "memory": "123456Ki", + }, + }, + wantInfo: map[string]interface{}{ + "cpu": map[string]interface{}{ + "count": int64(2), + }, + "memory": map[string]interface{}{ + "memTotalKiB": int64(123456), + }, + "os": map[string]interface{}{ + "dockerVersion": "", + "kernelVersion": nil, + "operatingSystem": nil, + }, + "kubernetes": map[string]interface{}{ + "kubeletVersion": nil, + "kubeProxyVersion": nil, + }, + }, + }, + { + internal: map[string]interface{}{ + "capacity": map[string]interface{}{ + "cpu": "1M", + "memory": "123456Ti", + }, + }, + wantInfo: map[string]interface{}{ + "cpu": map[string]interface{}{ + "count": int64(1000000), + }, + "memory": map[string]interface{}{ + "memTotalKiB": int64(132559870623744), + }, + "os": map[string]interface{}{ + "dockerVersion": "", + "kernelVersion": nil, + "operatingSystem": nil, + }, + "kubernetes": map[string]interface{}{ + "kubeletVersion": nil, + "kubeProxyVersion": nil, + }, + }, + }, + } + + for _, tt := range tests { + mapper.FromInternal(tt.internal) + if !reflect.DeepEqual(tt.wantInfo, tt.internal["info"]) { + t.Fatal("os info does not match after mapping") + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/persistvolumeclaim.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/persistvolumeclaim.go new file mode 100644 index 0000000..58f28e6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/persistvolumeclaim.go @@ -0,0 +1,23 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/values" +) + +type PersistVolumeClaim struct { +} + +func (p PersistVolumeClaim) FromInternal(data map[string]interface{}) { +} + +func (p PersistVolumeClaim) ToInternal(data map[string]interface{}) error { + if v, ok := values.GetValue(data, "storageClassId"); ok && v == nil { + values.PutValue(data, "", "storageClassId") + } + return nil +} + +func (p PersistVolumeClaim) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/scheduling.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/scheduling.go new file mode 100644 index 0000000..9fe6972 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/scheduling.go @@ -0,0 +1,279 @@ +package mapper + +import ( + "fmt" + "regexp" + "sort" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" + v1 "k8s.io/api/core/v1" +) + +var ( + exprRegexp = regexp.MustCompile("^(.*?)\\s*(=|!=|<|>| in | notin )\\s*(.*)$") +) + +type SchedulingMapper struct { +} + +func (s SchedulingMapper) FromInternal(data map[string]interface{}) { + defer func() { + delete(data, "nodeSelector") + delete(data, "affinity") + }() + + var requireAll []string + for key, value := range convert.ToMapInterface(data["nodeSelector"]) { + if value == "" { + requireAll = append(requireAll, key) + } else { + requireAll = append(requireAll, fmt.Sprintf("%s = %s", key, value)) + } + } + + if len(requireAll) > 0 { + values.PutValue(data, requireAll, "scheduling", "node", "requireAll") + } + + v, ok := data["affinity"] + if !ok || v == nil { + return + } + + affinity := &v1.Affinity{} + if err := convert.ToObj(v, affinity); err != nil { + return + } + + if affinity.NodeAffinity != nil { + s.nodeAffinity(data, affinity.NodeAffinity) + } +} + +func (s SchedulingMapper) nodeAffinity(data map[string]interface{}, nodeAffinity *v1.NodeAffinity) { + var requireAll []string + var requireAny []string + var preferred []string + + if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution != nil { + for _, term := range nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms { + exprs := NodeSelectorTermToStrings(term) + if len(exprs) == 0 { + continue + } + if len(requireAny) > 0 { + // Once any is set all new terms go to any + requireAny = append(requireAny, strings.Join(exprs, " && ")) + } else if len(requireAll) > 0 { + // If all is already set, we actually need to move everything to any + requireAny = append(requireAny, strings.Join(requireAll, " && ")) + requireAny = append(requireAny, strings.Join(exprs, " && ")) + requireAll = []string{} + } else { + // The first term is considered all + requireAll = exprs + } + } + } + + if nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution != nil { + sortPreferred(nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution) + for _, term := range nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution { + exprs := NodeSelectorTermToStrings(term.Preference) + preferred = append(preferred, strings.Join(exprs, " && ")) + } + } + + if len(requireAll) > 0 { + values.PutValue(data, requireAll, "scheduling", "node", "requireAll") + } + if len(requireAny) > 0 { + values.PutValue(data, requireAny, "scheduling", "node", "requireAny") + } + if len(preferred) > 0 { + values.PutValue(data, preferred, "scheduling", "node", "preferred") + } +} + +func sortPreferred(terms []v1.PreferredSchedulingTerm) { + sort.Slice(terms, func(i, j int) bool { + return terms[i].Weight > terms[j].Weight + }) +} + +func NodeSelectorTermToStrings(term v1.NodeSelectorTerm) []string { + exprs := []string{} + + for _, expr := range term.MatchExpressions { + nextExpr := "" + switch expr.Operator { + case v1.NodeSelectorOpIn: + if len(expr.Values) > 1 { + nextExpr = fmt.Sprintf("%s in (%s)", expr.Key, strings.Join(expr.Values, ", ")) + } else if len(expr.Values) == 1 { + nextExpr = fmt.Sprintf("%s = %s", expr.Key, expr.Values[0]) + } + case v1.NodeSelectorOpNotIn: + if len(expr.Values) > 1 { + nextExpr = fmt.Sprintf("%s notin (%s)", expr.Key, strings.Join(expr.Values, ", ")) + } else if len(expr.Values) == 1 { + nextExpr = fmt.Sprintf("%s != %s", expr.Key, expr.Values[0]) + } + case v1.NodeSelectorOpExists: + nextExpr = expr.Key + case v1.NodeSelectorOpDoesNotExist: + nextExpr = "!" + expr.Key + case v1.NodeSelectorOpGt: + if len(expr.Values) == 1 { + nextExpr = fmt.Sprintf("%s > %s", expr.Key, expr.Values[0]) + } + case v1.NodeSelectorOpLt: + if len(expr.Values) == 1 { + nextExpr = fmt.Sprintf("%s < %s", expr.Key, expr.Values[0]) + } + } + + if nextExpr != "" { + exprs = append(exprs, nextExpr) + } + } + + return exprs +} + +func StringsToNodeSelectorTerm(exprs []string) []v1.NodeSelectorTerm { + result := []v1.NodeSelectorTerm{} + + for _, inter := range exprs { + term := v1.NodeSelectorTerm{} + + for _, expr := range strings.Split(inter, "&&") { + groups := exprRegexp.FindStringSubmatch(expr) + selectorRequirement := v1.NodeSelectorRequirement{} + + if groups == nil { + if strings.HasPrefix(expr, "!") { + selectorRequirement.Key = strings.TrimSpace(expr[1:]) + selectorRequirement.Operator = v1.NodeSelectorOpDoesNotExist + } else { + selectorRequirement.Key = strings.TrimSpace(expr) + selectorRequirement.Operator = v1.NodeSelectorOpExists + } + } else { + selectorRequirement.Key = strings.TrimSpace(groups[1]) + selectorRequirement.Values = convert.ToValuesSlice(groups[3]) + op := strings.TrimSpace(groups[2]) + switch op { + case "=": + selectorRequirement.Operator = v1.NodeSelectorOpIn + case "!=": + selectorRequirement.Operator = v1.NodeSelectorOpNotIn + case "notin": + selectorRequirement.Operator = v1.NodeSelectorOpNotIn + case "in": + selectorRequirement.Operator = v1.NodeSelectorOpIn + case "<": + selectorRequirement.Operator = v1.NodeSelectorOpLt + case ">": + selectorRequirement.Operator = v1.NodeSelectorOpGt + } + } + + term.MatchExpressions = append(term.MatchExpressions, selectorRequirement) + } + + result = append(result, term) + } + + return result +} + +func (s SchedulingMapper) ToInternal(data map[string]interface{}) error { + defer func() { + delete(data, "scheduling") + }() + + nodeName := convert.ToString(values.GetValueN(data, "scheduling", "node", "nodeId")) + if nodeName != "" { + data["nodeName"] = nodeName + } + + requireAllV := values.GetValueN(data, "scheduling", "node", "requireAll") + requireAnyV := values.GetValueN(data, "scheduling", "node", "requireAny") + preferredV := values.GetValueN(data, "scheduling", "node", "preferred") + + if requireAllV == nil && requireAnyV == nil && preferredV == nil { + return nil + } + + requireAll := convert.ToStringSlice(requireAllV) + requireAny := convert.ToStringSlice(requireAnyV) + preferred := convert.ToStringSlice(preferredV) + + if len(requireAll) == 0 && len(requireAny) == 0 && len(preferred) == 0 { + values.PutValue(data, nil, "affinity", "nodeAffinity") + return nil + } + + nodeAffinity := v1.NodeAffinity{} + + if len(requireAll) > 0 { + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = &v1.NodeSelector{ + NodeSelectorTerms: []v1.NodeSelectorTerm{ + AggregateTerms(StringsToNodeSelectorTerm(requireAll)), + }, + } + } + + if len(requireAny) > 0 { + if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil { + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = &v1.NodeSelector{} + } + nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = StringsToNodeSelectorTerm(requireAny) + } + + if len(preferred) > 0 { + count := int32(100) + for _, term := range StringsToNodeSelectorTerm(preferred) { + nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution = append( + nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution, v1.PreferredSchedulingTerm{ + Weight: count, + Preference: term, + }) + count-- + } + } + + affinity, _ := convert.EncodeToMap(&v1.Affinity{ + NodeAffinity: &nodeAffinity, + }) + + if nodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution == nil { + values.PutValue(affinity, nil, "nodeAffinity", "preferredDuringSchedulingIgnoredDuringExecution") + } + + if nodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil { + values.PutValue(affinity, nil, "nodeAffinity", "requiredDuringSchedulingIgnoredDuringExecution") + } + + data["affinity"] = affinity + + return nil +} + +func AggregateTerms(terms []v1.NodeSelectorTerm) v1.NodeSelectorTerm { + result := v1.NodeSelectorTerm{} + for _, term := range terms { + result.MatchExpressions = append(result.MatchExpressions, term.MatchExpressions...) + } + return result +} + +func (s SchedulingMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + delete(schema.ResourceFields, "nodeSelector") + delete(schema.ResourceFields, "affinity") + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/statefulset_spec.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/statefulset_spec.go new file mode 100644 index 0000000..245758e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/statefulset_spec.go @@ -0,0 +1,19 @@ +package mapper + +import ( + "github.com/rancher/norman/types" +) + +type StatefulSetSpecMapper struct { +} + +func (s StatefulSetSpecMapper) FromInternal(data map[string]interface{}) { +} + +func (s StatefulSetSpecMapper) ToInternal(data map[string]interface{}) error { + return nil +} + +func (s StatefulSetSpecMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/status.go new file mode 100644 index 0000000..8e60d88 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/status.go @@ -0,0 +1,45 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/schemas/status" +) + +type Status struct { +} + +func (s Status) FromInternal(data map[string]interface{}) { + status.Set(data) +} + +func (s Status) ToInternal(data map[string]interface{}) error { + return nil +} + +func (s Status) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + _, hasSpec := schema.ResourceFields["spec"] + _, hasStatus := schema.ResourceFields["status"] + + if !hasSpec || !hasStatus { + return nil + } + + schema.ResourceFields["state"] = types.Field{ + CodeName: "State", + Type: "string", + } + schema.ResourceFields["transitioning"] = types.Field{ + CodeName: "Transitioning", + Type: "enum", + Options: []string{ + "yes", + "no", + "error", + }, + } + schema.ResourceFields["transitioningMessage"] = types.Field{ + CodeName: "TransitioningMessage", + Type: "string", + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/workload.go new file mode 100644 index 0000000..b270644 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/mapper/workload.go @@ -0,0 +1,29 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/values" +) + +type WorkloadAnnotations struct { +} + +func (n WorkloadAnnotations) FromInternal(data map[string]interface{}) { + v, ok := values.RemoveValue(data, "workloadAnnotations", "field.cattle.io/publicEndpoints") + if ok { + if _, ok := data["annotations"]; !ok { + data["annotations"] = map[string]interface{}{} + } + annotations := convert.ToMapInterface(data["annotations"]) + annotations["field.cattle.io/publicEndpoints"] = v + } +} + +func (n WorkloadAnnotations) ToInternal(data map[string]interface{}) error { + return nil +} + +func (n WorkloadAnnotations) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/log.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/log.go new file mode 100644 index 0000000..91e27c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/log.go @@ -0,0 +1,7 @@ +package schema + +import "github.com/sirupsen/logrus" + +var ( + log = logrus.WithField("component", "types/mapper") +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/registry_credential.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/registry_credential.go new file mode 100644 index 0000000..fa149b9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/registry_credential.go @@ -0,0 +1,53 @@ +package schema + +import ( + "encoding/base64" + "fmt" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" +) + +type RegistryCredentialMapper struct { +} + +func (e RegistryCredentialMapper) FromInternal(data map[string]interface{}) { +} + +func (e RegistryCredentialMapper) ToInternal(data map[string]interface{}) error { + if data == nil { + return nil + } + + if data["kind"] != "dockerCredential" { + return nil + } + + addAuthInfo(data) + + return nil +} + +func addAuthInfo(data map[string]interface{}) error { + + registryMap := convert.ToMapInterface(data["registries"]) + for _, regCred := range registryMap { + regCredMap := convert.ToMapInterface(regCred) + + username := convert.ToString(regCredMap["username"]) + if username == "" { + continue + } + password := convert.ToString(regCredMap["password"]) + if password == "" { + continue + } + auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) + regCredMap["auth"] = auth + } + + return nil +} +func (e RegistryCredentialMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema.go new file mode 100644 index 0000000..92c4a80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema.go @@ -0,0 +1,906 @@ +package schema + +import ( + "net/http" + + "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapper" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/schemas/factory" + "github.com/rancher/rancher/pkg/schemas/mapper" + appsv1 "k8s.io/api/apps/v1" + k8sappv1 "k8s.io/api/apps/v1" + autoscaling "k8s.io/api/autoscaling/v2" + batchv1 "k8s.io/api/batch/v1" + v1 "k8s.io/api/core/v1" + kextv1beta1 "k8s.io/api/extensions/v1beta1" + knetworkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +var ( + Version = types.APIVersion{ + Version: "v3", + Group: "project.cattle.io", + Path: "/v3/project", + SubContext: true, + SubContextSchema: "/v3/schemas/project", + } + + Schemas = factory.Schemas(&Version). + // volume before pod types. pod types uses volume things, so need to register mapper + Init(volumeTypes). + Init(configMapTypes). + Init(ingressTypes). + Init(secretTypes). + Init(serviceTypes). + Init(podTypes). + Init(deploymentTypes). + Init(replicationControllerTypes). + Init(replicaSetTypes). + Init(statefulSetTypes). + Init(daemonSetTypes). + Init(jobTypes). + Init(cronJobTypes). + Init(podTemplateSpecTypes). + Init(workloadTypes). + Init(appTypes). + Init(autoscalingTypes) +) + +func configMapTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImportAndCustomize(&Version, v1.ConfigMap{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "hostname" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}) +} + +type DeploymentConfig struct { +} + +type StatefulSetConfig struct { +} + +type ReplicaSetConfig struct { +} + +type ReplicationControllerConfig struct { +} + +type DaemonSetConfig struct { +} + +type CronJobConfig struct { +} + +type JobConfig struct { +} + +type deploymentConfigOverride struct { + DeploymentConfig DeploymentConfig +} + +type statefulSetConfigOverride struct { + StatefulSetConfig StatefulSetConfig +} + +type replicaSetConfigOverride struct { + ReplicaSetConfig ReplicaSetConfig +} + +type replicationControllerConfigOverride struct { + ReplicationControllerConfig ReplicationControllerConfig +} + +type daemonSetOverride struct { + DaemonSetConfig DaemonSetConfig +} + +type cronJobOverride struct { + CronJobConfig CronJobConfig +} + +type jobOverride struct { + JobConfig JobConfig +} + +func workloadTypes(schemas *types.Schemas) *types.Schemas { + return schemas.MustImportAndCustomize(&Version, v3.Workload{}, + func(schema *types.Schema) { + toInclude := []string{"deployment", "replicationController", "statefulSet", + "daemonSet", "job", "cronJob", "replicaSet"} + for _, name := range toInclude { + baseSchema := schemas.Schema(&Version, name) + if baseSchema == nil { + continue + } + for name, field := range baseSchema.ResourceFields { + schema.ResourceFields[name] = field + } + } + schema.ResourceActions = map[string]types.Action{ + "rollback": { + Input: "rollbackRevision", + }, + "pause": {}, + "resume": {}, + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }) +} + +func statefulSetTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, k8sappv1.StatefulSetUpdateStrategy{}, + &m.Embed{Field: "rollingUpdate"}, + m.Enum{Field: "type", Options: []string{ + "RollingUpdate", + "OnDelete", + }}, + m.Move{From: "type", To: "strategy"}, + ). + AddMapperForType(&Version, k8sappv1.StatefulSetSpec{}, + &m.Move{ + From: "replicas", + To: "scale", + }, + &m.Embed{Field: "updateStrategy"}, + &m.Enum{ + Field: "podManagementPolicy", + Options: []string{ + "OrderedReady", + "Parallel", + }, + }, + &m.BatchMove{ + From: []string{ + "partition", + "strategy", + "volumeClaimTemplates", + "serviceName", + "revisionHistoryLimit", + "podManagementPolicy", + }, + To: "statefulSetConfig", + }, + &m.Embed{Field: "template"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, k8sappv1.StatefulSet{}, + &m.Move{ + From: "status", + To: "statefulSetStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, k8sappv1.StatefulSetSpec{}, statefulSetConfigOverride{}). + MustImportAndCustomize(&Version, k8sappv1.StatefulSet{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.ResourceActions = map[string]types.Action{ + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func replicaSetTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, appsv1.ReplicaSetSpec{}, + &m.Move{ + From: "replicas", + To: "scale", + }, + &m.Move{ + From: "minReadySeconds", + To: "replicaSetConfig/minReadySeconds", + }, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, appsv1.ReplicaSet{}, + &m.Move{ + From: "status", + To: "replicaSetStatus", + }, + &m.Embed{Field: "template"}, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, appsv1.ReplicaSetSpec{}, replicaSetConfigOverride{}). + MustImportAndCustomize(&Version, appsv1.ReplicaSet{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.ResourceActions = map[string]types.Action{ + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func replicationControllerTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.ReplicationControllerSpec{}, + &m.Move{ + From: "replicas", + To: "scale", + }, + &m.Move{ + From: "minReadySeconds", + To: "replicationControllerConfig/minReadySeconds", + }, + &m.Embed{Field: "template"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, v1.ReplicationController{}, + &m.Move{ + From: "status", + To: "replicationControllerStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, v1.ReplicationControllerSpec{}, replicationControllerConfigOverride{}). + MustImportAndCustomize(&Version, v1.ReplicationController{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.CollectionMethods = []string{http.MethodGet} + schema.ResourceMethods = []string{http.MethodGet} + schema.ResourceActions = map[string]types.Action{ + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func daemonSetTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, k8sappv1.DaemonSetUpdateStrategy{}, + &m.Embed{Field: "rollingUpdate"}, + m.Enum{Field: "type", Options: []string{ + "RollingUpdate", + "OnDelete", + }}, + m.Move{From: "type", To: "strategy"}, + ). + AddMapperForType(&Version, k8sappv1.DaemonSetSpec{}, + &m.Embed{Field: "updateStrategy"}, + &m.BatchMove{ + From: []string{ + "strategy", + "maxUnavailable", + "minReadySeconds", + "revisionHistoryLimit", + }, + To: "daemonSetConfig", + }, + &m.Embed{Field: "template"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, k8sappv1.DaemonSet{}, + &m.Move{ + From: "status", + To: "daemonSetStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, k8sappv1.DaemonSetSpec{}, daemonSetOverride{}). + MustImportAndCustomize(&Version, k8sappv1.DaemonSet{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.ResourceActions = map[string]types.Action{ + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func jobTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, batchv1.JobSpec{}, + &m.BatchMove{ + From: []string{"parallelism", + "completions", + "activeDeadlineSeconds", + "backoffLimit", + "manualSelector", + }, + To: "jobConfig", + }, + &m.Embed{Field: "template"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, batchv1.Job{}, + &m.Move{ + From: "status", + To: "jobStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, batchv1.JobSpec{}, jobOverride{}). + MustImportAndCustomize(&Version, batchv1.Job{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func cronJobTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, batchv1.JobTemplateSpec{}, + &m.Move{ + From: "metadata", + To: "jobMetadata", + }, + &m.Embed{Field: "spec"}, + ). + AddMapperForType(&Version, batchv1.CronJobSpec{}, + &m.Drop{ + Field: "suspend", + }, + &m.Embed{ + Field: "jobTemplate", + }, + &m.BatchMove{ + From: []string{ + "schedule", + "startingDeadlineSeconds", + "suspend", + "successfulJobsHistoryLimit", + "failedJobsHistoryLimit", + "jobConfig", + }, + To: "cronJobConfig", + }, + &m.Enum{Field: "concurrencyPolicy", Options: []string{ + "Allow", + "Forbid", + "Replace", + }}, + &m.Move{ + From: "concurrencyPolicy", + To: "cronJobConfig/concurrencyPolicy", + }, + &m.Move{ + From: "jobMetadata/labels", + To: "cronJobConfig/jobLabels", + NoDeleteFromField: true, + }, + &m.Move{ + From: "jobMetadata/annotations", + To: "cronJobConfig/jobAnnotations", + NoDeleteFromField: true, + }, + &m.Drop{Field: "jobMetadata"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, batchv1.CronJob{}, + &m.Move{ + From: "status", + To: "cronJobStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, batchv1.CronJobSpec{}, cronJobOverride{}). + MustImport(&Version, batchv1.JobTemplateSpec{}). + MustImportAndCustomize(&Version, batchv1.CronJob{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.ResourceActions = map[string]types.Action{ + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func deploymentTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, k8sappv1.DeploymentStrategy{}, + &m.Embed{Field: "rollingUpdate", EmptyValueOk: true}, + m.Enum{Field: "type", Options: []string{ + "Recreate", + "RollingUpdate", + }}, + m.Move{From: "type", To: "strategy"}, + ). + AddMapperForType(&Version, k8sappv1.DeploymentSpec{}, + &m.Move{ + From: "strategy", + To: "upgradeStrategy", + }, + &m.Embed{Field: "upgradeStrategy"}, + &m.Move{ + From: "replicas", + To: "scale", + }, + &m.BatchMove{ + From: []string{ + "minReadySeconds", + "strategy", + "revisionHistoryLimit", + "progressDeadlineSeconds", + "maxUnavailable", + "maxSurge", + }, + To: "deploymentConfig", + }, + &m.Embed{Field: "template"}, + ). + MustImport(&Version, v3.WorkloadMetric{}). + AddMapperForType(&Version, k8sappv1.Deployment{}, + &m.Move{ + From: "status", + To: "deploymentStatus", + }, + NewWorkloadTypeMapper(), + ). + MustImport(&Version, k8sappv1.DeploymentSpec{}, deploymentConfigOverride{}). + MustImport(&Version, v3.DeploymentRollbackInput{}). + MustImportAndCustomize(&Version, k8sappv1.Deployment{}, func(schema *types.Schema) { + schema.BaseType = "workload" + schema.ResourceActions = map[string]types.Action{ + "rollback": { + Input: "deploymentRollbackInput", + }, + "pause": {}, + "resume": {}, + "redeploy": {}, + } + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric]"` + }{}) +} + +func podTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.PodTemplateSpec{}, + &m.Embed{Field: "spec"}, + ). + AddMapperForType(&Version, v1.Capabilities{}, + m.Move{From: "add", To: "capAdd"}, + m.Move{From: "drop", To: "capDrop"}, + ). + AddMapperForType(&Version, v1.PodSecurityContext{}, + m.Drop{Field: "seLinuxOptions"}, + m.Move{From: "runAsUser", To: "uid"}, + m.Move{From: "supplementalGroups", To: "gids"}, + m.Move{From: "fsGroup", To: "fsgid"}, + ). + AddMapperForType(&Version, v1.SecurityContext{}, + &m.Embed{Field: "capabilities"}, + m.Drop{Field: "seLinuxOptions"}, + m.Move{From: "readOnlyRootFilesystem", To: "readOnly"}, + m.Move{From: "runAsUser", To: "uid"}, + ). + AddMapperForType(&Version, v1.Container{}, + m.Move{From: "command", To: "entrypoint"}, + m.Move{From: "args", To: "command"}, + &m.Embed{Field: "securityContext"}, + &m.Embed{Field: "lifecycle"}, + ). + AddMapperForType(&Version, v1.ContainerPort{}, + m.Move{From: "hostIP", To: "hostIp"}, + ). + AddMapperForType(&Version, v1.LifecycleHandler{}, + mapper.ContainerProbeHandler{}). + AddMapperForType(&Version, v1.Probe{}, mapper.ContainerProbeHandler{}). + AddMapperForType(&Version, v1.LifecycleHandler{}, handlerMapper). + AddMapperForType(&Version, v1.Probe{}, handlerMapper). + AddMapperForType(&Version, v1.PodStatus{}, + m.Move{From: "hostIP", To: "nodeIp"}, + m.Move{From: "podIP", To: "podIp"}, + ). + AddMapperForType(&Version, v1.PodSpec{}, + mapper.InitContainerMapper{}, + mapper.SchedulingMapper{}, + m.Move{From: "priority", To: "scheduling/priority", DestDefined: true}, + m.Move{From: "priorityClassName", To: "scheduling/priorityClassName", DestDefined: true}, + m.Move{From: "schedulerName", To: "scheduling/scheduler", DestDefined: true}, + m.Move{From: "tolerations", To: "scheduling/tolerate", DestDefined: true}, + &m.Embed{Field: "securityContext"}, + &m.Drop{Field: "serviceAccount"}, + ). + AddMapperForType(&Version, v1.Pod{}, + &m.AnnotationField{Field: "description"}, + &m.AnnotationField{Field: "publicEndpoints", List: true}, + &m.AnnotationField{Field: "workloadMetrics", List: true}, + mapper.ContainerPorts{}, + mapper.ContainerStatus{}, + ). + // Must import handlers before Container + MustImport(&Version, v1.ContainerPort{}, struct { + Kind string `json:"kind,omitempty" norman:"type=enum,options=HostPort|NodePort|ClusterIP|LoadBalancer"` + SourcePort int `json:"sourcePort,omitempty"` + DNSName string `json:"dnsName,omitempty"` + Name string `json:"name,omitempty"` + Protocol string `json:"protocol,omitempty"` + }{}). + MustImport(&Version, v1.Capabilities{}, struct { + Add []string `norman:"type=array[enum],options=AUDIT_CONTROL|AUDIT_WRITE|BLOCK_SUSPEND|CHOWN|DAC_OVERRIDE|DAC_READ_SEARCH|FOWNER|FSETID|IPC_LOCK|IPC_OWNER|KILL|LEASE|LINUX_IMMUTABLE|MAC_ADMIN|MAC_OVERRIDE|MKNOD|NET_ADMIN|NET_BIND_SERVICE|NET_BROADCAST|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYSLOG|SYS_ADMIN|SYS_BOOT|SYS_CHROOT|SYS_MODULE|SYS_NICE|SYS_PACCT|SYS_PTRACE|SYS_RAWIO|SYS_RESOURCE|SYS_TIME|SYS_TTY_CONFIG|WAKE_ALARM|ALL"` + Drop []string `norman:"type=array[enum],options=AUDIT_CONTROL|AUDIT_WRITE|BLOCK_SUSPEND|CHOWN|DAC_OVERRIDE|DAC_READ_SEARCH|FOWNER|FSETID|IPC_LOCK|IPC_OWNER|KILL|LEASE|LINUX_IMMUTABLE|MAC_ADMIN|MAC_OVERRIDE|MKNOD|NET_ADMIN|NET_BIND_SERVICE|NET_BROADCAST|NET_RAW|SETFCAP|SETGID|SETPCAP|SETUID|SYSLOG|SYS_ADMIN|SYS_BOOT|SYS_CHROOT|SYS_MODULE|SYS_NICE|SYS_PACCT|SYS_PTRACE|SYS_RAWIO|SYS_RESOURCE|SYS_TIME|SYS_TTY_CONFIG|WAKE_ALARM|ALL"` + }{}). + MustImport(&Version, v3.PublicEndpoint{}). + MustImport(&Version, v3.WorkloadMetric{}). + MustImport(&Version, v1.LifecycleHandler{}, handlerOverride{}). + MustImport(&Version, v1.Probe{}, handlerOverride{}). + MustImport(&Version, v1.Container{}, struct { + Environment map[string]string + EnvironmentFrom []EnvironmentFrom + InitContainer bool + State string + Transitioning string + TransitioningMessage string + ExitCode *int + RestartCount int + }{}). + MustImport(&Version, v1.PodSpec{}, struct { + Scheduling *Scheduling + NodeName string `norman:"type=reference[/v3/schemas/node]"` + }{}). + MustImport(&Version, v1.Pod{}, projectOverride{}, struct { + Description string `json:"description"` + WorkloadID string `norman:"type=reference[workload]"` + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + WorkloadMetrics string `json:"workloadMetrics" norman:"type=array[workloadMetric],nocreate,noupdate"` + }{}) +} + +func serviceTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + Init(addServiceType). + Init(addDNSRecord) +} + +func addServiceType(schemas *types.Schemas) *types.Schemas { + return schemas.AddSchema(*factory.Schemas(&Version). + Init(addServiceOrDNSRecord(false)). + Schema(&Version, "service")) +} + +func addDNSRecord(schemas *types.Schemas) *types.Schemas { + return schemas. + Init(addServiceOrDNSRecord(true)) +} + +func addServiceOrDNSRecord(dns bool) types.SchemasInitFunc { + return func(schemas *types.Schemas) *types.Schemas { + if dns { + schemas = schemas. + TypeName("dnsRecord", v1.Service{}) + } + + schemas = schemas. + AddMapperForType(&Version, v1.ServiceSpec{}, + &m.Move{From: "externalName", To: "hostname"}, + &m.Move{From: "type", To: "serviceKind"}, + &m.SetValue{ + Field: "clusterIP", + IfEq: "None", + Value: nil, + }, + &m.Move{From: "clusterIP", To: "clusterIp"}, + ). + AddMapperForType(&Version, v1.Service{}, + &m.Drop{Field: "status"}, + &m.LabelField{Field: "workloadId"}, + &m.AnnotationField{Field: "description"}, + &m.AnnotationField{Field: "ipAddresses", List: true}, + &m.AnnotationField{Field: "targetWorkloadIds", List: true}, + &m.AnnotationField{Field: "targetDnsRecordIds", List: true}, + &m.AnnotationField{Field: "publicEndpoints", List: true}, + &m.Move{From: "serviceKind", To: "kind"}, + ) + + if dns { + schemas = schemas. + AddMapperForType(&Version, v1.Service{}, + &m.Drop{Field: "kind"}, + &m.Drop{Field: "externalIPs"}, + &m.Drop{Field: "externalTrafficPolicy"}, + &m.Drop{Field: "healthCheckNodePort"}, + &m.Drop{Field: "loadBalancerIP"}, + &m.Drop{Field: "loadBalancerSourceRanges"}, + &m.Drop{Field: "publishNotReadyAddresses"}, + &m.Drop{Field: "sessionAffinity"}, + &m.Drop{Field: "sessionAffinityConfig"}, + &m.Drop{Field: "loadBalancerClass"}, + &m.Drop{Field: "internalTrafficPolicy"}, + ) + } + + return schemas.MustImportAndCustomize(&Version, v1.Service{}, func(schema *types.Schema) { + if dns { + schema.CodeName = "DNSRecord" + schema.MustCustomizeField("clusterIp", func(f types.Field) types.Field { + f.Create = false + f.Update = false + return f + }) + schema.MustCustomizeField("ports", func(f types.Field) types.Field { + f.Create = false + f.Update = false + return f + }) + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "dnsLabelRestricted" + field.Nullable = false + field.Required = true + return field + }) + } + }, projectOverride{}, struct { + Description string `json:"description"` + IPAddresses []string `json:"ipAddresses"` + WorkloadID string `json:"workloadId" norman:"type=reference[workload],nocreate,noupdate"` + TargetWorkloadIDs string `json:"targetWorkloadIds" norman:"type=array[reference[workload]]"` + TargetDNSRecordIDs string `json:"targetDnsRecordIds" norman:"type=array[reference[dnsRecord]]"` + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + }{}) + } +} + +func ingressTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, knetworkingv1.HTTPIngressPath{}, + &m.Embed{Field: "backend"}, + &mapper.IngressPath{}, + ). + AddMapperForType(&Version, knetworkingv1.IngressRule{}, + &m.Embed{Field: "http"}, + ). + AddMapperForType(&Version, knetworkingv1.Ingress{}, + &m.AnnotationField{Field: "description"}, + &m.AnnotationField{Field: "publicEndpoints", List: true}, + &mapper.IngressSpec{}, + ). + AddMapperForType(&Version, knetworkingv1.IngressTLS{}, + &m.Move{From: "secretName", To: "certificateName"}, + ). + AddMapperForType(&Version, knetworkingv1.IngressBackend{}, + &m.Move{From: "service/name", To: "serviceId"}, + &mapper.IngressBackend{}, + ). + MustImportAndCustomize(&Version, knetworkingv1.IngressBackend{}, func(schema *types.Schema) { + schema.MustCustomizeField("serviceId", func(f types.Field) types.Field { + f.Type = "reference[service]" + return f + }) + }, struct { + WorkloadIDs string `json:"workloadIds" norman:"type=array[reference[workload]]"` + TargetPort intstr.IntOrString `json:"targetPort"` + }{}). + MustImport(&Version, knetworkingv1.IngressRule{}). + MustImport(&Version, knetworkingv1.IngressTLS{}, struct { + SecretName string `norman:"type=reference[certificate]"` + }{}). + MustImport(&Version, knetworkingv1.IngressSpec{}, struct { + Backend kextv1beta1.IngressBackend `json:"backend"` + }{}). + MustImportAndCustomize(&Version, knetworkingv1.Ingress{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(f types.Field) types.Field { + f.Type = "hostname" + f.Required = true + f.Nullable = false + return f + }) + }, projectOverride{}, struct { + Description string `json:"description"` + PublicEndpoints string `json:"publicEndpoints" norman:"type=array[publicEndpoint],nocreate,noupdate"` + }{}) +} + +func volumeTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.HostPathVolumeSource{}, + m.Move{From: "type", To: "kind"}, + m.Enum{ + Options: []string{ + "DirectoryOrCreate", + "Directory", + "FileOrCreate", + "File", + "Socket", + "CharDevice", + "BlockDevice", + }, + Field: "kind", + }, + ). + AddMapperForType(&Version, v1.PersistentVolumeClaimVolumeSource{}, + &m.Move{From: "claimName", To: "persistentVolumeClaimName"}, + ). + AddMapperForType(&Version, v1.VolumeMount{}, + m.Required{Fields: []string{ + "mountPath", + "name", + }}, + ). + AddMapperForType(&Version, v1.PersistentVolumeClaim{}, + mapper.PersistVolumeClaim{}, + ). + MustImport(&Version, v1.PersistentVolumeClaimVolumeSource{}, struct { + ClaimName string `norman:"type=reference[persistentVolumeClaim]"` + }{}). + MustImport(&Version, v1.SecretVolumeSource{}, struct { + }{}). + MustImport(&Version, v1.VolumeMount{}, struct { + MountPath string `json:"mountPath" norman:"required"` + }{}). + MustImport(&Version, v1.PersistentVolumeSpec{}, struct { + StorageClassName *string `json:"storageClassName,omitempty" norman:"type=reference[/v3/cluster/storageClass]"` + }{}). + MustImport(&Version, v1.PersistentVolumeClaimSpec{}, struct { + AccessModes []string `json:"accessModes,omitempty" norman:"type=array[enum],options=ReadWriteOnce|ReadOnlyMany|ReadWriteMany"` + VolumeName string `json:"volumeName,omitempty" norman:"type=reference[/v3/cluster/persistentVolume]"` + StorageClassName *string `json:"storageClassName,omitempty" norman:"type=reference[/v3/cluster/storageClass]"` + }{}). + MustImport(&Version, v1.Volume{}, struct { + }{}). + MustImportAndCustomize(&Version, v1.PersistentVolumeClaim{}, func(schema *types.Schema) { + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "hostname" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}) +} + +func appTypes(schema *types.Schemas) *types.Schemas { + return schema. + AddMapperForType(&Version, v3.App{}, &m.Embed{Field: "status"}). + MustImport(&Version, v3.AppUpgradeConfig{}). + MustImport(&Version, v3.RollbackRevision{}). + MustImportAndCustomize(&Version, v3.App{}, func(schema *types.Schema) { + schema.ResourceActions = map[string]types.Action{ + "upgrade": { + Input: "appUpgradeConfig", + }, + "rollback": { + Input: "rollbackRevision", + }, + } + }). + MustImport(&Version, v3.AppRevision{}) +} + +func podTemplateSpecTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + MustImport(&Version, v1.PodTemplateSpec{}) +} + +func NewWorkloadTypeMapper() types.Mapper { + return &types.Mappers{ + &m.Move{From: "labels", To: "workloadLabels"}, + &m.Move{From: "annotations", To: "workloadAnnotations"}, + &m.Move{From: "metadata/labels", To: "labels", NoDeleteFromField: true}, + &m.Move{From: "metadata/annotations", To: "annotations", NoDeleteFromField: true}, + &m.Drop{Field: "metadata"}, + mapper.ContainerPorts{}, + mapper.WorkloadAnnotations{}, + &m.AnnotationField{Field: "publicEndpoints", List: true}, + &m.AnnotationField{Field: "workloadMetrics", List: true}, + } +} + +func autoscalingTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, autoscaling.HorizontalPodAutoscaler{}, + &m.ChangeType{Field: "scaleTargetRef", Type: "reference[workload]"}, + &m.Move{From: "scaleTargetRef", To: "workloadId"}, + mapper.CrossVersionObjectToWorkload{Field: "workloadId"}, + &m.Required{Fields: []string{"workloadId", "maxReplicas"}}, + &m.AnnotationField{Field: "displayName"}, + &m.DisplayName{}, + &m.AnnotationField{Field: "description"}, + &m.Embed{Field: "status"}, + mapper.NewMergeListByIndexMapper("currentMetrics", "metrics", "type"), + ). + AddMapperForType(&Version, autoscaling.MetricTarget{}, + &m.Enum{Field: "type", Options: []string{"Utilization", "Value", "AverageValue"}}, + &m.Move{To: "utilization", From: "averageUtilization"}, + ). + AddMapperForType(&Version, autoscaling.MetricValueStatus{}, + &m.Move{To: "utilization", From: "averageUtilization"}, + ). + AddMapperForType(&Version, autoscaling.MetricSpec{}, + &m.Condition{Field: "type", Value: "Object", Mapper: types.Mappers{ + &m.Move{To: "target", From: "object/target", DestDefined: true, NoDeleteFromField: true}, + &m.Move{To: "metric", From: "object/metric", DestDefined: true, NoDeleteFromField: true}, + }}, + &m.Condition{Field: "type", Value: "Pods", Mapper: types.Mappers{ + &m.Move{To: "target", From: "pods/target", DestDefined: true, NoDeleteFromField: true}, + &m.Move{To: "metric", From: "pods/metric", DestDefined: true, NoDeleteFromField: true}, + }}, + &m.Condition{Field: "type", Value: "Resource", Mapper: types.Mappers{ + &m.Move{To: "metric/name", From: "resource/name", DestDefined: true, NoDeleteFromField: true}, + &m.Move{To: "target", From: "resource/target", DestDefined: true, NoDeleteFromField: true}, + }}, + &m.Condition{Field: "type", Value: "External", Mapper: types.Mappers{ + &m.Move{To: "target", From: "external/target", DestDefined: true, NoDeleteFromField: true}, + &m.Move{To: "metric", From: "external/metric", DestDefined: true, NoDeleteFromField: true}, + }}, + &m.Embed{Field: "object", Ignore: []string{"target", "metric"}}, + &m.Embed{Field: "pods", Ignore: []string{"target", "metric"}}, + &m.Embed{Field: "external", Ignore: []string{"target", "metric"}}, + &m.Embed{Field: "resource", Ignore: []string{"target", "name"}}, + &m.Embed{Field: "metric"}, + &m.Enum{Field: "type", Options: []string{"Object", "Pods", "Resource", "External"}}, + ). + MustImportAndCustomize(&Version, autoscaling.MetricSpec{}, func(s *types.Schema) { + s.CodeName = "Metric" + s.PluralName = "metrics" + s.ID = "metric" + s.CodeNamePlural = "Metrics" + }, struct { + Target autoscaling.MetricTarget `json:"target"` + Metric autoscaling.MetricIdentifier `json:"metric"` + Current autoscaling.MetricValueStatus `json:"current" norman:"nocreate,noupdate"` + }{}). + AddMapperForType(&Version, autoscaling.MetricStatus{}, + &m.Condition{Field: "type", Value: "Object", Mapper: &m.Move{To: "current", From: "object/current", DestDefined: true, NoDeleteFromField: true}}, + &m.Condition{Field: "type", Value: "Pods", Mapper: &m.Move{To: "current", From: "pods/current", DestDefined: true, NoDeleteFromField: true}}, + &m.Condition{Field: "type", Value: "Resource", Mapper: &m.Move{To: "current", From: "resource/current"}}, + &m.Condition{Field: "type", Value: "External", Mapper: &m.Move{To: "current", From: "external/current", DestDefined: true, NoDeleteFromField: true}}, + ). + MustImport(&Version, autoscaling.HorizontalPodAutoscaler{}, projectOverride{}, struct { + DisplayName string `json:"displayName,omitempty"` + Description string `json:"description,omitempty"` + }{}) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema_secrets.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema_secrets.go new file mode 100644 index 0000000..cad19e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/schema_secrets.go @@ -0,0 +1,276 @@ +package schema + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + m "github.com/rancher/norman/types/mapper" + v3 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + v1 "k8s.io/api/core/v1" +) + +func secretTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.Secret{}, + &m.AnnotationField{Field: "description"}, + m.AnnotationField{Field: "projectId", IgnoreDefinition: true}, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/service-account-token", + Value: "serviceAccountToken", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/dockercfg", + Value: "dockerCredential", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/dockerconfigjson", + Value: "dockerCredential", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/basic-auth", + Value: "basicAuth", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/ssh-auth", + Value: "sshAuth", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/ssh-auth", + Value: "sshAuth", + }, + m.SetValue{ + Field: "type", + IfEq: "kubernetes.io/tls", + Value: "certificate", + }, + &m.Move{From: "type", To: "kind"}, + m.Condition{ + Field: "kind", + Value: "sshAuth", + Mapper: types.Mappers{ + m.UntypedMove{ + From: "data/ssh-privatekey", + To: "privateKey", + }, + m.Base64{ + Field: "privateKey", + IgnoreDefinition: true, + }, + m.SetValue{ + Field: "type", + Value: "sshAuth", + IgnoreDefinition: true, + }, + m.AnnotationField{Field: "fingerprint", IgnoreDefinition: true}, + }, + }, + m.Condition{ + Field: "kind", + Value: "basicAuth", + Mapper: types.Mappers{ + m.UntypedMove{ + From: "data/username", + To: "username", + }, + m.UntypedMove{ + From: "data/password", + To: "password", + }, + m.Base64{ + Field: "username", + IgnoreDefinition: true, + }, + m.Base64{ + Field: "password", + IgnoreDefinition: true, + }, + m.SetValue{ + Field: "type", + Value: "basicAuth", + IgnoreDefinition: true, + }, + }, + }, + m.Condition{ + Field: "kind", + Value: "certificate", + Mapper: types.Mappers{ + m.UntypedMove{ + From: "data/tls.crt", + To: "certs", + }, + m.UntypedMove{ + From: "data/tls.key", + To: "key", + }, + m.Base64{ + Field: "certs", + IgnoreDefinition: true, + }, + m.Base64{ + Field: "key", + IgnoreDefinition: true, + }, + m.AnnotationField{Field: "certFingerprint", IgnoreDefinition: true}, + m.AnnotationField{Field: "cn", IgnoreDefinition: true}, + m.AnnotationField{Field: "version", IgnoreDefinition: true}, + m.AnnotationField{Field: "issuer", IgnoreDefinition: true}, + m.AnnotationField{Field: "issuedAt", IgnoreDefinition: true}, + m.AnnotationField{Field: "expiresAt", IgnoreDefinition: true}, + m.AnnotationField{Field: "algorithm", IgnoreDefinition: true}, + m.AnnotationField{Field: "serialNumber", IgnoreDefinition: true}, + m.AnnotationField{Field: "keySize", IgnoreDefinition: true}, + m.AnnotationField{Field: "subjectAlternativeNames", IgnoreDefinition: true, List: true}, + m.SetValue{ + Field: "type", + Value: "certificate", + IgnoreDefinition: true, + }, + }, + }, + m.Condition{ + Field: "kind", + Value: "dockerCredential", + Mapper: types.Mappers{ + m.Base64{ + Field: "data/.dockercfg", + IgnoreDefinition: true, + }, + m.JSONEncode{ + Field: "data/.dockercfg", + IgnoreDefinition: true, + }, + m.UntypedMove{ + From: "data/.dockercfg", + To: "registries", + }, + m.Base64{ + Field: "data/.dockerconfigjson", + IgnoreDefinition: true, + }, + m.JSONEncode{ + Field: "data/.dockerconfigjson", + IgnoreDefinition: true, + }, + m.UntypedMove{ + From: "data/.dockerconfigjson/auths", + To: "registries", + }, + m.SetValue{ + Field: "type", + Value: "dockerCredential", + IgnoreDefinition: true, + }, + }, + }, + m.Condition{ + Field: "kind", + Value: "serviceAccountToken", + Mapper: types.Mappers{ + m.UntypedMove{ + From: "annotations!kubernetes.io/service-account.name", + To: "accountName", + Separator: "!", + }, + m.UntypedMove{ + From: "annotations!kubernetes.io/service-account.uid", + To: "accountUid", + Separator: "!", + }, + m.UntypedMove{ + From: "data/ca.crt", + To: "caCrt", + }, + m.UntypedMove{ + From: "data/token", + To: "token", + }, + m.Base64{ + Field: "caCrt", + IgnoreDefinition: true, + }, + m.Base64{ + Field: "token", + IgnoreDefinition: true, + }, + m.SetValue{ + Field: "type", + Value: "serviceAccountToken", + IgnoreDefinition: true, + }, + }, + }, + ). + AddMapperForType(&Version, v1.Secret{}, RegistryCredentialMapper{}). + MustImportAndCustomize(&Version, v1.Secret{}, func(schema *types.Schema) { + schema.MustCustomizeField("kind", func(f types.Field) types.Field { + f.Options = []string{ + "Opaque", + "serviceAccountToken", + "dockerCredential", + "basicAuth", + "sshAuth", + "certificate", + } + return f + }) + schema.MustCustomizeField("name", func(field types.Field) types.Field { + field.Type = "hostname" + field.Nullable = false + field.Required = true + return field + }) + }, projectOverride{}, struct { + Description string `json:"description"` + }{}). + Init(func(schemas *types.Schemas) *types.Schemas { + return addSecretSubtypes(schemas, + v3.ServiceAccountToken{}, + v3.DockerCredential{}, + v3.Certificate{}, + v3.BasicAuth{}, + v3.SSHAuth{}) + }) +} + +func addSecretSubtypes(schemas *types.Schemas, objs ...interface{}) *types.Schemas { + namespaced := []string{"secret"} + + for _, obj := range objs { + schemas.MustImportAndCustomize(&Version, obj, func(schema *types.Schema) { + schema.BaseType = "secret" + schema.Mapper = schemas.Schema(&Version, "secret").Mapper + namespaced = append(namespaced, schema.ID) + }, projectOverride{}) + } + + for _, name := range namespaced { + baseSchema := schemas.Schema(&Version, name) + + // Make non-namespaced have namespaceId not required + newFields := map[string]types.Field{} + for name, field := range baseSchema.ResourceFields { + if name == "namespaceId" { + field.Required = false + } + newFields[name] = field + } + + schema := *baseSchema + schema.ID = "namespaced" + convert.Capitalize(schema.ID) + schema.PluralName = "namespaced" + convert.Capitalize(schema.PluralName) + schema.CodeName = "Namespaced" + schema.CodeName + schema.CodeNamePlural = "Namespaced" + schema.CodeNamePlural + schema.BaseType = "namespacedSecret" + schemas.AddSchema(schema) + + baseSchema.ResourceFields = newFields + } + + return schemas +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/types.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/types.go new file mode 100644 index 0000000..7c57c94 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/project.cattle.io/v3/types.go @@ -0,0 +1,74 @@ +package schema + +import ( + "github.com/rancher/norman/types" + m "github.com/rancher/norman/types/mapper" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + handlerMapper = &m.UnionEmbed{ + Fields: []m.UnionMapping{ + { + FieldName: "exec", + CheckFields: []string{"command"}, + }, + { + FieldName: "tcpSocket", + CheckFields: []string{"tcp", "port"}, + }, + { + FieldName: "httpGet", + CheckFields: []string{"port"}, + }, + }, + } +) + +type ScalingGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec interface{} `json:"spec"` + Status interface{} `json:"status"` +} + +type handlerOverride struct { + TCP bool +} + +type EnvironmentFrom struct { + Source string `norman:"type=enum,options=field|resource|configMap|secret"` + SourceName string + SourceKey string + Prefix string + Optional bool + TargetKey string +} + +type Scheduling struct { + Node *NodeScheduling + Tolerate []v1.Toleration + Scheduler string + Priority *int64 + PriorityClassName string +} + +type NodeScheduling struct { + NodeName string `json:"nodeName" norman:"type=reference[/v3/schemas/node]"` + RequireAll []string + RequireAny []string + Preferred []string +} + +type projectOverride struct { + types.Namespaced + ProjectID string `norman:"type=reference[/v3/schemas/project],noupdate"` +} + +type Target struct { + Addresses []string `json:"addresses"` + NotReadyAddresses []string `json:"notReadyAddresses"` + Port *int32 `json:"port"` + Protocol string `json:"protocol" norman:"type=enum,options=TCP|UDP"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/status/status.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/status/status.go new file mode 100644 index 0000000..9f57158 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/schemas/status/status.go @@ -0,0 +1,23 @@ +package status + +import ( + "strings" + + "github.com/rancher/wrangler/v3/pkg/summary" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func Set(data map[string]interface{}) { + if data == nil { + return + } + summary := summary.Summarize(&unstructured.Unstructured{Object: data}) + data["state"] = summary.State + data["transitioning"] = "no" + if summary.Error { + data["transitioning"] = "error" + } else if summary.Transitioning { + data["transitioning"] = "yes" + } + data["transitioningMessage"] = strings.Join(summary.Message, "; ") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret.go new file mode 100644 index 0000000..b9f461f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret.go @@ -0,0 +1,166 @@ +package serviceaccounttoken + +import ( + "context" + "fmt" + "time" + + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/kubernetes" + clientv1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +const ( + // ServiceAccountSecretLabel is the label used to search for the secret belonging to a service account. + ServiceAccountSecretLabel = "cattle.io/service-account.name" + + serviceAccountSecretAnnotation = "kubernetes.io/service-account.name" +) + +// secretLister is an abstraction over any kind of secret lister. +// The caller can use any cache or client it has available, whether that is from norman, wrangler, or client-go, +// as long as it can wrap it in a simplified lambda with this signature. +type secretLister func(namespace string, selector labels.Selector) ([]*v1.Secret, error) + +// EnsureSecretForServiceAccount gets or creates a service account token Secret for the provided Service Account. +// For k8s <1.24, the secret is automatically generated for the service account. For >=1.24, we need to generate it explicitly. +func EnsureSecretForServiceAccount(ctx context.Context, secretsCache corecontrollers.SecretCache, clientSet kubernetes.Interface, sa *v1.ServiceAccount) (*v1.Secret, error) { + if sa == nil { + return nil, fmt.Errorf("could not ensure secret for invalid service account") + } + secretClient := clientSet.CoreV1().Secrets(sa.Namespace) + var secretLister secretLister + if secretsCache != nil { + secretLister = secretsCache.List + } else { + secretLister = func(_ string, selector labels.Selector) ([]*v1.Secret, error) { + secretList, err := secretClient.List(ctx, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + if err != nil { + return nil, err + } + result := make([]*v1.Secret, len(secretList.Items)) + for i := range secretList.Items { + result[i] = &secretList.Items[i] + } + return result, nil + } + } + secret, err := ServiceAccountSecret(ctx, sa, secretLister, secretClient) + if err != nil { + return nil, fmt.Errorf("error looking up secret for service account [%s:%s]: %w", sa.Namespace, sa.Name, err) + } + if secret == nil { + sc := SecretTemplate(sa) + secret, err = secretClient.Create(ctx, sc, metav1.CreateOptions{}) + if err != nil { + return nil, fmt.Errorf("error ensuring secret for service account [%s:%s]: %w", sa.Namespace, sa.Name, err) + } + } + if len(secret.Data[v1.ServiceAccountTokenKey]) > 0 { + return secret, nil + } + logrus.Infof("EnsureSecretForServiceAccount: waiting for secret [%s] to be populated with token", secret.Name) + backoff := wait.Backoff{ + Duration: 2 * time.Millisecond, + Cap: 100 * time.Millisecond, + Steps: 50, + } + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + var err error + // use the secret client, rather than the secret getter, to circumvent the cache + secret, err = secretClient.Get(ctx, secret.Name, metav1.GetOptions{}) + if err != nil { + return false, fmt.Errorf("error ensuring secret for service account [%s:%s]: %w", sa.Namespace, sa.Name, err) + } + if len(secret.Data[v1.ServiceAccountTokenKey]) > 0 { + return true, nil + } + return false, nil + }) + if err != nil { + return nil, fmt.Errorf("error ensuring secret for service account [%s:%s]: %w", sa.Namespace, sa.Name, err) + } + return secret, nil +} + +// SecretTemplate generate a template of service-account-token Secret for the provided Service Account. +func SecretTemplate(sa *v1.ServiceAccount) *v1.Secret { + return &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: serviceAccountSecretPrefix(sa), + Namespace: sa.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "ServiceAccount", + Name: sa.Name, + UID: sa.UID, + }, + }, + Annotations: map[string]string{ + serviceAccountSecretAnnotation: sa.Name, + }, + Labels: map[string]string{ + ServiceAccountSecretLabel: sa.Name, + }, + }, + Type: v1.SecretTypeServiceAccountToken, + } + +} + +// serviceAccountSecretPrefix returns the prefix that will be used to generate the secret for the given service account. +func serviceAccountSecretPrefix(sa *v1.ServiceAccount) string { + return fmt.Sprintf("%s-token-", sa.Name) +} + +// ServiceAccountSecret returns the secret for the given Service Account. +// If there are more than one, it returns the first. Can return a nil secret +// and a nil error if no secret is found +func ServiceAccountSecret(ctx context.Context, sa *v1.ServiceAccount, secretLister secretLister, secretClient clientv1.SecretInterface) (*v1.Secret, error) { + if sa == nil { + return nil, fmt.Errorf("cannot get secret for nil service account") + } + secrets, err := secretLister(sa.Namespace, labels.SelectorFromSet(map[string]string{ + ServiceAccountSecretLabel: sa.Name, + })) + if err != nil { + return nil, fmt.Errorf("could not get secrets for service account: %w", err) + } + if len(secrets) < 1 { + return nil, nil + } + var result *v1.Secret + for _, s := range secrets { + if isSecretForServiceAccount(s, sa) { + if result == nil { + result = s + } + continue + } + logrus.Warnf("EnsureSecretForServiceAccount: secret [%s:%s] is invalid for service account [%s], deleting", s.Namespace, s.Name, sa.Name) + err = secretClient.Delete(ctx, s.Name, metav1.DeleteOptions{}) + if err != nil { + // we don't want to return the delete failure since the success/failure of the cleanup shouldn't affect + // the ability of the caller to use any identified, valid secret + logrus.Errorf("unable to delete secret [%s:%s]: %v", s.Namespace, s.Name, err) + } + } + return result, nil +} + +func isSecretForServiceAccount(secret *v1.Secret, sa *v1.ServiceAccount) bool { + if secret.Type != v1.SecretTypeServiceAccountToken { + return false + } + annotations := secret.Annotations + annotation := annotations[serviceAccountSecretAnnotation] + return sa.Name == annotation +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret_test.go new file mode 100644 index 0000000..527ebd2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/serviceaccounttoken/secret_test.go @@ -0,0 +1,349 @@ +package serviceaccounttoken + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/fake" + k8stesting "k8s.io/client-go/testing" +) + +func TestEnsureSecretForServiceAccount(t *testing.T) { + t.Parallel() + defaultWantSA := &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + } + defaultWantSecret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-token-abcde", + Namespace: "default", + Annotations: map[string]string{ + "kubernetes.io/service-account.name": "test", + }, + Labels: map[string]string{ + "cattle.io/service-account.name": "test", + }, + }, + Data: map[string][]byte{ + "token": []byte("abcde"), + }, + Type: v1.SecretTypeServiceAccountToken, + } + tests := []struct { + name string + sa *v1.ServiceAccount + wantSA *v1.ServiceAccount + existingSecret *v1.Secret + wantSecret *v1.Secret + wantErr bool + }{ + { + name: "service account with no secret generates secret", + sa: &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + wantSA: defaultWantSA, + wantSecret: defaultWantSecret, + }, + { + name: "service account with existing secret returns it", + sa: &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + wantSA: defaultWantSA, + existingSecret: &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-token-abcde", + Namespace: "default", + Annotations: map[string]string{ + "kubernetes.io/service-account.name": "test", + }, + Labels: map[string]string{ + "cattle.io/service-account.name": "test", + }, + }, + Data: map[string][]byte{ + "token": []byte("abcde"), + }, + Type: v1.SecretTypeServiceAccountToken, + }, + wantSecret: defaultWantSecret, + }, + { + name: "returns error for nil service account", + wantErr: true, + }, + { + name: "service account with invalid secret is updated with new secret", + sa: &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + wantSA: defaultWantSA, + wantSecret: defaultWantSecret, + }, + { + name: "secret of wrong type gets recreated", + sa: &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + wantSA: defaultWantSA, + existingSecret: &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-token-xyz", + Namespace: "default", + Annotations: map[string]string{ + "kubernetes.io/service-account.name": "test", + }, + Labels: map[string]string{ + "cattle.io/service-account.name": "test", + }, + }, + Data: map[string][]byte{ + "token": []byte("abcde"), + }, + Type: v1.SecretTypeOpaque, + }, + wantSecret: defaultWantSecret, + }, + { + name: "secret for wrong service account type gets recreated", + sa: &v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + wantSA: defaultWantSA, + existingSecret: &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-token-xyz", + Namespace: "default", + Annotations: map[string]string{ + "kubernetes.io/service-account.name": "wrong", + }, + Labels: map[string]string{ + "cattle.io/service-account.name": "wrong", + }, + }, + Data: map[string][]byte{ + "token": []byte("abcde"), + }, + Type: v1.SecretTypeServiceAccountToken, + }, + wantSecret: defaultWantSecret, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + var k8sClient *fake.Clientset + objs := []runtime.Object{} + if tt.sa != nil { + objs = append(objs, tt.sa) + } + if tt.existingSecret != nil { + objs = append(objs, tt.existingSecret) + } + k8sClient = fake.NewSimpleClientset(objs...) + k8sClient.PrependReactor("create", "secrets", + func(action k8stesting.Action) (bool, runtime.Object, error) { + ret := action.(k8stesting.CreateAction).GetObject().(*v1.Secret) + ret.ObjectMeta.Name = ret.GenerateName + "abcde" + ret.Data = map[string][]byte{ + "token": []byte("abcde"), + } + + return true, ret, nil + }, + ) + got, gotErr := EnsureSecretForServiceAccount(context.Background(), nil, k8sClient, tt.sa) + if tt.wantErr { + assert.Error(t, gotErr) + return + } + assert.NoError(t, gotErr) + assert.Equal(t, tt.wantSecret.Name, got.Name) + gotSA, _ := k8sClient.CoreV1().ServiceAccounts("default").Get(context.Background(), "test", metav1.GetOptions{}) + assert.Equal(t, tt.wantSA.Secrets, gotSA.Secrets) + assert.Equal(t, tt.sa, gotSA) + }) + } +} + +func TestServiceAccountSecret(t *testing.T) { + type testState struct { + clientset *fake.Clientset + fakeLister *fakeSecretLister + } + baseSA := v1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: "base-sa", + Namespace: "test-ns", + }, + } + validSecret := v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "base-sa-secret", + Namespace: "test-ns", + Labels: map[string]string{ + ServiceAccountSecretLabel: baseSA.Name, + }, + Annotations: map[string]string{ + serviceAccountSecretAnnotation: baseSA.Name, + }, + }, + Type: v1.SecretTypeServiceAccountToken, + } + invalidSecretType := v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "invalid-secret-type", + Namespace: "test-ns", + Labels: map[string]string{ + ServiceAccountSecretLabel: baseSA.Name, + }, + Annotations: map[string]string{ + serviceAccountSecretAnnotation: baseSA.Name, + }, + }, + Type: v1.SecretTypeOpaque, + } + invalidSecretAnnotation := v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "invalid-secret-annotation", + Namespace: "test-ns", + Labels: map[string]string{ + ServiceAccountSecretLabel: baseSA.Name, + }, + Annotations: map[string]string{ + serviceAccountSecretAnnotation: "some-other-sa", + }, + }, + Type: v1.SecretTypeOpaque, + } + tests := []struct { + name string + stateSetup func(testState) + inputSA *v1.ServiceAccount + wantSecret *v1.Secret + wantError bool + }{ + { + name: "test nil sa", + inputSA: nil, + wantError: true, + }, + { + name: "test no secrets", + inputSA: &baseSA, + wantError: false, + wantSecret: nil, + }, + { + name: "test valid secrets, first returned", + inputSA: &baseSA, + stateSetup: func(ts testState) { + validSecondSecret := validSecret.DeepCopy() + validSecondSecret.Name = "base-sa-secret-2" + ts.fakeLister.secrets = []*v1.Secret{&validSecret, validSecondSecret} + }, + wantError: false, + wantSecret: &validSecret, + }, + { + name: "test invalid secrets, none returned", + inputSA: &baseSA, + stateSetup: func(ts testState) { + ts.fakeLister.secrets = []*v1.Secret{&invalidSecretType, &invalidSecretAnnotation} + ts.clientset.Tracker().Add(&invalidSecretType) + ts.clientset.Tracker().Add(&invalidSecretAnnotation) + }, + wantError: false, + wantSecret: nil, + }, + { + name: "test invalid secrets delete failure, valid still returned", + inputSA: &baseSA, + stateSetup: func(ts testState) { + ts.fakeLister.secrets = []*v1.Secret{&invalidSecretType, &invalidSecretAnnotation, &validSecret} + ts.clientset.Tracker().Add(&invalidSecretType) + // don't add the invalid annotation secret to the state, this will cause a not-found error on delete + }, + wantError: false, + wantSecret: &validSecret, + }, + { + name: "test valid + invalid secrets, only valid returned", + inputSA: &baseSA, + stateSetup: func(ts testState) { + ts.fakeLister.secrets = []*v1.Secret{&invalidSecretType, &invalidSecretAnnotation, &validSecret} + ts.clientset.Tracker().Add(&invalidSecretType) + ts.clientset.Tracker().Add(&invalidSecretAnnotation) + }, + wantError: false, + wantSecret: &validSecret, + }, + { + name: "test secret lister error", + inputSA: &baseSA, + stateSetup: func(ts testState) { + ts.fakeLister.secrets = []*v1.Secret{&invalidSecretType, &invalidSecretAnnotation, &validSecret} + ts.fakeLister.err = fmt.Errorf("server unavailable") + }, + wantError: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + k8sClient := fake.NewSimpleClientset() + fakeLister := fakeSecretLister{} + state := testState{ + clientset: k8sClient, + fakeLister: &fakeLister, + } + if test.stateSetup != nil { + test.stateSetup(state) + } + secretsMock := state.clientset.CoreV1().Secrets("test-ns") + secret, err := ServiceAccountSecret(context.Background(), test.inputSA, state.fakeLister.list, secretsMock) + require.Equal(t, test.wantSecret, secret) + if test.wantError { + require.NotNil(t, err) + } else { + require.Nil(t, err) + } + }) + } +} + +type fakeSecretLister struct { + secrets []*v1.Secret + err error +} + +func (f *fakeSecretLister) list(namespace string, selector labels.Selector) ([]*v1.Secret, error) { + return f.secrets, f.err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/affinity.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/affinity.go new file mode 100644 index 0000000..4872947 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/affinity.go @@ -0,0 +1,126 @@ +package settings + +const ( + // ClusterAgentAffinity used to be hardcoded in the agent deployment template but is now defined here as the + // single source of truth. + ClusterAgentAffinity = `{ + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "beta.kubernetes.io/os", + "operator": "NotIn", + "values": [ + "windows" + ] + } + ] + } + ] + }, + "preferredDuringSchedulingIgnoredDuringExecution": [ + { + "weight": 100, + "preference": { + "matchExpressions": [ + { + "key": "node-role.kubernetes.io/controlplane", + "operator": "In", + "values": [ + "true" + ] + } + ] + } + }, + { + "weight": 100, + "preference": { + "matchExpressions": [ + { + "key": "node-role.kubernetes.io/control-plane", + "operator": "In", + "values": [ + "true" + ] + } + ] + } + }, + { + "weight": 100, + "preference": { + "matchExpressions": [ + { + "key": "node-role.kubernetes.io/master", + "operator": "In", + "values": [ + "true" + ] + } + ] + } + }, + { + "weight": 1, + "preference": { + "matchExpressions": [ + { + "key": "cattle.io/cluster-agent", + "operator": "In", + "values": [ + "true" + ] + } + ] + } + } + ] + }, + "podAntiAffinity": { + "preferredDuringSchedulingIgnoredDuringExecution": [ + { + "weight": 100, + "podAffinityTerm": { + "labelSelector": { + "matchExpressions": [ + { + "key": "app", + "operator": "In", + "values": [ + "cattle-cluster-agent" + ] + } + ] + }, + "topologyKey": "kubernetes.io/hostname" + } + } + ] + } +}` + // FleetAgentAffinity is hardcoded in the rancher/fleet repo in the agent manifest + // https://github.com/rancher/fleet/blob/90e33140906ba5d4931b4e1dee588854cbb300b1/pkg/agent/manifest.go#L178-L195 + FleetAgentAffinity = `{ + "nodeAffinity": { + "preferredDuringSchedulingIgnoredDuringExecution": [ + { + "weight": 1, + "preference": { + "matchExpressions": [ + { + "key": "fleet.cattle.io/agent", + "operator": "In", + "values": [ + "true" + ] + } + ] + } + } + ] + } +}` +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting.go new file mode 100644 index 0000000..2c6136e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting.go @@ -0,0 +1,569 @@ +// Package settings is used to access various server settings +package settings + +import ( + "encoding/json" + "fmt" + "os" + "regexp" + "strconv" + "strings" + + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + authsettings "github.com/rancher/rancher/pkg/auth/settings" + "github.com/rancher/rancher/pkg/buildconfig" + fleetconst "github.com/rancher/rancher/pkg/fleet" +) + +const ( + RancherVersionDev = "2.9.99" + DefaultMaxUIPluginFileSizeInBytes = 20 * 1024 * 1024 // 20MB + AgentTLSModeStrict = "strict" + AgentTLSModeSystemStore = "system-store" +) + +var ( + releasePattern = regexp.MustCompile("^v[0-9]") + settings = map[string]Setting{} + provider Provider + InjectDefaults string + + systemNamespaces = []string{ + "kube-system", + "kube-public", + "cattle-system", + "cattle-alerting", + "cattle-logging", + "cattle-prometheus", + "ingress-nginx", + "cattle-global-data", + "cattle-istio", + "kube-node-lease", + "cert-manager", + "cattle-global-nt", + "security-scan", + "cattle-fleet-system", + "cattle-fleet-local-system", + "calico-system", + "tigera-operator", + "cattle-impersonation-system", + "rancher-operator-system", + "cattle-csp-adapter-system", + "calico-apiserver", + "cattle-elemental-system", + } + + AgentImage = NewSetting("agent-image", "rancher/rancher-agent:v2.9-head") + AgentRolloutTimeout = NewSetting("agent-rollout-timeout", "300s") + AgentRolloutWait = NewSetting("agent-rollout-wait", "true") + // AgentTLSMode is translated to the environment variable STRICT_VERIFY when rendering the cluster/node agent manifests and should not be specified as a default agent setting as it has no direct effect on the agent itself. + AgentTLSMode = NewSetting("agent-tls-mode", AgentTLSModeStrict).WithDefaultOnUpgrade(AgentTLSModeSystemStore) + AuthImage = NewSetting("auth-image", v32.ToolsSystemImages.AuthSystemImages.KubeAPIAuth) + AuthorizationCacheTTLSeconds = NewSetting("authorization-cache-ttl-seconds", "10") + AuthorizationDenyCacheTTLSeconds = NewSetting("authorization-deny-cache-ttl-seconds", "10") + AzureGroupCacheSize = NewSetting("azure-group-cache-size", "10000") + CACerts = NewSetting("cacerts", "") + CLIURLDarwin = NewSetting("cli-url-darwin", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-darwin-amd64-v1.0.0-alpha8.tar.gz") + CLIURLLinux = NewSetting("cli-url-linux", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-linux-amd64-v1.0.0-alpha8.tar.gz") + CLIURLWindows = NewSetting("cli-url-windows", "https://releases.rancher.com/cli/v1.0.0-alpha8/rancher-windows-386-v1.0.0-alpha8.zip") + ClusterControllerStartCount = NewSetting("cluster-controller-start-count", "50") + EngineInstallURL = NewSetting("engine-install-url", "https://releases.rancher.com/install-docker/26.1.sh") + EngineISOURL = NewSetting("engine-iso-url", "https://releases.rancher.com/os/latest/rancheros-vmware.iso") + EngineNewestVersion = NewSetting("engine-newest-version", "v17.12.0") + EngineSupportedRange = NewSetting("engine-supported-range", "~v1.11.2 || ~v1.12.0 || ~v1.13.0 || ~v17.03.0 || ~v17.06.0 || ~v17.09.0 || ~v18.06.0 || ~v18.09.0 || ~v19.03.0 || ~v20.10.0 || ~v23.0.0 || ~v24.0.0 || ~v25.0.0 || ~v26.0.0 || ~v26.1.0") + FirstLogin = NewSetting("first-login", "true") + GlobalRegistryEnabled = NewSetting("global-registry-enabled", "false") + GithubProxyAPIURL = NewSetting("github-proxy-api-url", "https://api.github.com") + HelmVersion = NewSetting("helm-version", "dev") + HelmMaxHistory = NewSetting("helm-max-history", "10") + IngressIPDomain = NewSetting("ingress-ip-domain", "sslip.io") + InstallUUID = NewSetting("install-uuid", "") + InternalServerURL = NewSetting("internal-server-url", "") + InternalCACerts = NewSetting("internal-cacerts", "") + IsRKE = NewSetting("is-rke", "") + JailerTimeout = NewSetting("jailer-timeout", "60") + KubernetesVersion = NewSetting("k8s-version", "") + KubernetesVersionToServiceOptions = NewSetting("k8s-version-to-service-options", "") + KubernetesVersionToSystemImages = NewSetting("k8s-version-to-images", "") + KubernetesVersionsCurrent = NewSetting("k8s-versions-current", "") + KubernetesVersionsDeprecated = NewSetting("k8s-versions-deprecated", "") + KDMBranch = NewSetting("kdm-branch", "release-v2.9") + MachineVersion = NewSetting("machine-version", "dev") + Namespace = NewSetting("namespace", os.Getenv("CATTLE_NAMESPACE")) + PasswordMinLength = NewSetting("password-min-length", "12") + PeerServices = NewSetting("peer-service", os.Getenv("CATTLE_PEER_SERVICE")) + RkeVersion = NewSetting("rke-version", "") + RkeMetadataConfig = NewSetting("rke-metadata-config", getMetadataConfig()) + ServerImage = NewSetting("server-image", "rancher/rancher") + ServerURL = NewSetting("server-url", "") + ServerVersion = NewSetting("server-version", "dev") + SystemAgentVersion = NewSetting("system-agent-version", "") + WinsAgentVersion = NewSetting("wins-agent-version", "") + CSIProxyAgentVersion = NewSetting("csi-proxy-agent-version", "") + CSIProxyAgentURL = NewSetting("csi-proxy-agent-url", "https://acs-mirror.azureedge.net/csi-proxy/%[1]s/binaries/csi-proxy-%[1]s.tar.gz") + SystemAgentInstallScript = NewSetting("system-agent-install-script", "https://github.com/rancher/system-agent/releases/download/v0.3.8/install.sh") // To ensure consistency between SystemAgentInstallScript default value and CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT to utilize the local system-agent-install.sh script when both values are equal. + WinsAgentInstallScript = NewSetting("wins-agent-install-script", "https://raw.githubusercontent.com/rancher/wins/v0.4.17/install.ps1") + SystemAgentInstallerImage = NewSetting("system-agent-installer-image", "") // Defined via environment variable + SystemAgentUpgradeImage = NewSetting("system-agent-upgrade-image", "") // Defined via environment variable + WinsAgentUpgradeImage = NewSetting("wins-agent-upgrade-image", "") + SystemNamespaces = NewSetting("system-namespaces", strings.Join(systemNamespaces, ",")) + SystemUpgradeControllerChartVersion = NewSetting("system-upgrade-controller-chart-version", "") + TelemetryOpt = NewSetting("telemetry-opt", "") + TLSMinVersion = NewSetting("tls-min-version", "1.2") + TLSCiphers = NewSetting("tls-ciphers", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305") + WhitelistDomain = NewSetting("whitelist-domain", "forums.rancher.com") + WhitelistEnvironmentVars = NewSetting("whitelist-envvars", "HTTP_PROXY,HTTPS_PROXY,NO_PROXY") + AuthUserInfoResyncCron = NewSetting("auth-user-info-resync-cron", "0 0 * * *") + APIUIVersion = NewSetting("api-ui-version", "1.1.11") // Please update the CATTLE_API_UI_VERSION in package/Dockerfile when updating the version here. + RotateCertsIfExpiringInDays = NewSetting("rotate-certs-if-expiring-in-days", "7") // 7 days + ClusterTemplateEnforcement = NewSetting("cluster-template-enforcement", "false") + InitialDockerRootDir = NewSetting("initial-docker-root-dir", "/var/lib/docker") + SystemCatalog = NewSetting("system-catalog", "external") // Options are 'external' or 'bundled' + ChartDefaultBranch = NewSetting("chart-default-branch", "release-v2.9") + SystemManagedChartsOperationTimeout = NewSetting("system-managed-charts-operation-timeout", "300s") + FleetDefaultWorkspaceName = NewSetting("fleet-default-workspace-name", fleetconst.ClustersDefaultNamespace) // fleetWorkspaceName to assign to clusters with none + ShellImage = NewSetting("shell-image", buildconfig.DefaultShellVersion) + IgnoreNodeName = NewSetting("ignore-node-name", "") // nodes to ignore when syncing v1.node to v3.node + NoDefaultAdmin = NewSetting("no-default-admin", "") + RestrictedDefaultAdmin = NewSetting("restricted-default-admin", "false") // When bootstrapping the admin for the first time, give them the global role restricted-admin + AKSUpstreamRefresh = NewSetting("aks-refresh", "300") + EKSUpstreamRefresh = NewSetting("eks-refresh", "300") + GKEUpstreamRefresh = NewSetting("gke-refresh", "300") + HideLocalCluster = NewSetting("hide-local-cluster", "false") + MachineProvisionImage = NewSetting("machine-provision-image", "rancher/machine:v0.15.0-rancher116") + SystemFeatureChartRefreshSeconds = NewSetting("system-feature-chart-refresh-seconds", "21600") + ClusterAgentDefaultAffinity = NewSetting("cluster-agent-default-affinity", ClusterAgentAffinity) + FleetAgentDefaultAffinity = NewSetting("fleet-agent-default-affinity", FleetAgentAffinity) + MaxUIPluginFileByteSize = NewSetting("max-ui-plugin-file-byte-size", strconv.Itoa(DefaultMaxUIPluginFileSizeInBytes)) // Max file size in bytes for ui plugins + + Rke2DefaultVersion = NewSetting("rke2-default-version", "") + K3sDefaultVersion = NewSetting("k3s-default-version", "") + + // AuthTokenMaxTTLMinutes is the max allowable time to live for tokens. Excluding those created for UI sessions which is controlled by AuthUserSessionTTLMinutes. + AuthTokenMaxTTLMinutes = NewSetting("auth-token-max-ttl-minutes", "129600") // 90 days + + // AuthUserInfoMaxAgeSeconds represents the maximum age of a users auth tokens before an auth provider group membership sync will be performed. + AuthUserInfoMaxAgeSeconds = NewSetting("auth-user-info-max-age-seconds", "3600") // 1 hour + + // AuthUserSessionTTLMinutes represents the time to live for tokens used for login sessions in minutes. + AuthUserSessionTTLMinutes = NewSetting("auth-user-session-ttl-minutes", "960") // 16 hours + + // ChartDefaultURL represents the default URL for the system charts repo. It should only be set for test or + // debug purposes. + ChartDefaultURL = NewSetting("chart-default-url", "https://git.rancher.io/") + // DisableInactiveUserAfter is the duration a user can be inactive after which it's disabled by the user retention process. + // The value should be expressed in valid time.Duration units and truncated to a second e.g. "168h". See https://pkg.go.dev/time#ParseDuration + // DisableInactiveUserAfter should be greater than AuthUserSessionTTLMinutes. + // An empty string or a zero value means the feature is disabled. + DisableInactiveUserAfter = NewSetting("disable-inactive-user-after", "") + + // DeleteInactiveUserAfter is the duration a user can be inactive after which it's deleted by the user retention process. + // The value should be expressed in valid time.Duration units and truncated to a second e.g. "168h". See https://pkg.go.dev/time#ParseDuration + // DeleteInactiveUserAfter should be greater than AuthUserSessionTTLMinutes. + // An empty string or a zero value means the feature is disabled. + DeleteInactiveUserAfter = NewSetting("delete-inactive-user-after", "") + + // UserRetentionDryRun determines if the user retention process should actually disable and delete users. + // Valid values are "true" and "false". An empty string means "false". + UserRetentionDryRun = NewSetting("user-retention-dry-run", "false") + + // UserLastLoginDefault is used if UserAttribute.LastLogin is not set. + // The value should be a date and time truncated to a second and formatted according to RFC3339 e.g. "2023-03-01T00:00:00Z". + // If the value is an empty string or time.Time zero value this settings is not used. + UserLastLoginDefault = NewSetting("user-last-login-default", "") + + // UserRetentionCron determines how often the user retention process should run. + // The value should be a valid cron expression e.g. "0 * * * *" (every hour) + UserRetentionCron = NewSetting("user-retention-cron", "") + + // ConfigMapName name of the configmap that stores rancher configuration information. + // Deprecated: to be removed in 2.8.0 + ConfigMapName = NewSetting("config-map-name", "rancher-config") + + // CSPAdapterMinVersion is used to determine if an existing installation of the CSP adapter should be upgraded to a new version + // has no effect if the csp adapter is not installed. + CSPAdapterMinVersion = NewSetting("csp-adapter-min-version", "") + + // FleetMinVersion is the minimum version of the Fleet chart that Rancher will install. + // Deprecated in favor of FleetVersion, kept for backward compatibility purposes. + FleetMinVersion = NewSetting("fleet-min-version", "") + + // FleetVersion is the exact version of the Fleet chart that Rancher will install. + FleetVersion = NewSetting("fleet-version", "") + + // AksOperatorVersion is the exact version of the aks-operator and aks-operator-crd charts that Rancher will install. + AksOperatorVersion = NewSetting("aks-operator-version", "") + + // EksOperatorVersion is the exact version of the eks-operator and eks-operator-crd chart that Rancher will install. + EksOperatorVersion = NewSetting("eks-operator-version", "") + + // GkeOperatorVersion is the exact version of the gke-operator and gke-operator-crd chart that Rancher will install. + GkeOperatorVersion = NewSetting("gke-operator-version", "") + + // KubeconfigDefaultTokenTTLMinutes is the default time to live applied to kubeconfigs created for users. + // This setting will take effect regardless of the kubeconfig-generate-token status. + KubeconfigDefaultTokenTTLMinutes = NewSetting("kubeconfig-default-token-ttl-minutes", "43200") // 30 days + + // KubeconfigGenerateToken determines whether the UI will return a generate token with kubeconfigs. + // If set to false the kubeconfig will contain a command to login to Rancher. + KubeconfigGenerateToken = NewSetting("kubeconfig-generate-token", "true") + + // PartnerChartDefaultBranch represents the default branch for the partner charts repo. + PartnerChartDefaultBranch = NewSetting("partner-chart-default-branch", "main") + + // PartnerChartDefaultURL represents the default URL for the partner charts repo. It should only be set for test + // or debug purposes. + PartnerChartDefaultURL = NewSetting("partner-chart-default-url", "https://git.rancher.io/") + + // RancherWebhookVersion is the exact version of the webhook that Rancher will install. + RancherWebhookVersion = NewSetting("rancher-webhook-version", "") + + // RancherWebhookVersion is the exact version of the webhook that Rancher will install. + RancherProvisioningCAPIVersion = NewSetting("rancher-provisioning-capi-version", "") + + // RKE2ChartDefaultBranch represents the default branch for the RKE2 charts repo. + RKE2ChartDefaultBranch = NewSetting("rke2-chart-default-branch", "main") + + // RKE2ChartDefaultURL represents the default URL for the RKE2 charts repo. It should only be set for test or + // debug purposes. + RKE2ChartDefaultURL = NewSetting("rke2-chart-default-url", "https://git.rancher.io/") + + // SystemDefaultRegistry is the default contrainer registry used for images. + // The environmental variable "CATTLE_BASE_REGISTRY" controls the default value of this setting. + SystemDefaultRegistry = NewSetting("system-default-registry", os.Getenv("CATTLE_BASE_REGISTRY")) + + // UIBanners holds configuration to display a custom fixed banner in the header, footer, or both + UIBanners = NewSetting("ui-banners", "{}") + + // UIBrand High level 'brand' value, for example `suse`. + // Fallback env, not a user-facing setting, used to indicate if this is a Prime install + UIBrand = NewSetting("ui-brand", os.Getenv("CATTLE_BASE_UI_BRAND")) + + // UICommunityLinks displays community links in the UI. + // Deprecated in favour of UICustomLinks. + UICommunityLinks = NewSetting("ui-community-links", "true") + + // UICustomLinks Key(display text), value(url) for user customisable links to display in homepage and support pages. + UICustomLinks = NewSetting("ui-custom-links", "") + + // UIDashboardPath path within Rancher Manager where the dashboard files are found. + UIDashboardPath = NewSetting("ui-dashboard-path", "/usr/share/rancher/ui-dashboard") + + // UIDashboardIndex depends on ui-offline-preferred, use this version of the dashboard instead of the one contained in Rancher Manager. + UIDashboardIndex = NewSetting("ui-dashboard-index", "https://releases.rancher.com/dashboard/release-2.9/index.html") + + // UIDashboardHarvesterLegacyPlugin depending on ui-offline-preferred and if a Harvester Cluster does not contain it's own Harvester plugin, use this version of the plugin instead. + UIDashboardHarvesterLegacyPlugin = NewSetting("ui-dashboard-harvester-legacy-plugin", "https://releases.rancher.com/harvester-ui/plugin/harvester-1.0.3-head/harvester-1.0.3-head.umd.min.js") + + // UIDefaultLanding the default page users land on after login. + UIDefaultLanding = NewSetting("ui-default-landing", "vue") + + // UIFavicon custom favicon. + UIFavicon = NewSetting("ui-favicon", "") + + // UIFeedBackForm Ember UI specific. + UIFeedBackForm = NewSetting("ui-feedback-form", "") + + // UIIndex depends on ui-offline-preferred, use this version of the old ember UI instead of the one contained in Rancher Manager. + UIIndex = NewSetting("ui-index", "https://releases.rancher.com/ui/release-2.9/index.html") + + // UIIssues use a url address to send new 'File an Issue' reports instead of sending users to the Github issues page. + // Deprecated in favour of UICustomLinks = NewSetting("ui-custom-links", {}). + UIIssues = NewSetting("ui-issues", "") + + // UIKubernetesDefaultVersion Ember UI specific. + UIKubernetesDefaultVersion = NewSetting("ui-k8s-default-version-range", "<=1.14.x") + + // UIKubernetesSupportedVersions Ember UI specific. + UIKubernetesSupportedVersions = NewSetting("ui-k8s-supported-versions-range", ">= 1.11.0 <=1.14.x") + + // UIOfflinePreferred controls whether UI assets are served locally by the server container ('true') or from the remote URL defined in the ui-index and ui-dashboard-index settings ('false). + // The `dynamic` option will use remote assets for `-head` builds, otherwise the local assets for production builds. + UIOfflinePreferred = NewSetting("ui-offline-preferred", "dynamic") + + // UIPath path within Rancher Manager where the old ember UI files are found. + UIPath = NewSetting("ui-path", "/usr/share/rancher/ui") + + // UIPerformance experimental settings for UI functionality to improve the UX with large numbers of resources. + UIPerformance = NewSetting("ui-performance", "") + + // UIPL the vendor/company name. + UIPL = NewSetting("ui-pl", "rancher") + + // UIPrimaryColor UI primary color for branding customisation + UIPrimaryColor = NewSetting("ui-primary-color", "") + + // UILinkColor UI link color for branding customisation + UILinkColor = NewSetting("ui-link-color", "") + + // UILoginBackground the custom background in the login page. + UILoginBackgroundLight = NewSetting("ui-login-background-light", "") + UILoginBackgroundDark = NewSetting("ui-login-background-dark", "") + + // UIBanner the custom background image in the home page. + UIBannerLight = NewSetting("ui-banner-light", "") + UIBannerDark = NewSetting("ui-banner-dark", "") + + // UIExtensions - setting for configuring UI Extensions (e.g. allow users to enable/disable extensions) + UIExtensions = NewSetting("ui-extensions", "") + + // UI Settings for allowing separate configuration of page banners + UIBannerHeader = NewSetting("ui-banner-header", "") + UIBannerFooter = NewSetting("ui-banner-footer", "") + UIBannerLoginConsent = NewSetting("ui-banner-login-consent", "") + + // UIPreferred Ensure that the new Dashboard is the default UI. + UIPreferred = NewSetting("ui-preferred", "vue") + + // SkipHostedClusterChartInstallation controls whether the hosted cluster chart is installed on the server. Defaults to false. + // This setting is for development purposes only. + SkipHostedClusterChartInstallation = NewSetting("skip-hosted-cluster-chart-installation", os.Getenv("CATTLE_SKIP_HOSTED_CLUSTER_CHART_INSTALLATION")) + MachineProvisionImagePullPolicy = NewSetting("machine-provision-image-pull-policy", string(v1.PullAlways)) + + // The following settings are only used by the UI, but need to be known to Rancher so that they're not removed. + _ = NewSetting("eula-agreed", "") + _ = NewSetting("display-add-extension-repos-banner", "") + _ = NewSetting("ui-logo-light", "") + _ = NewSetting("ui-logo-dark", "") + _ = NewSetting("ui-theme", "") + _ = NewSetting("cli-version", "") + _ = NewSetting("has-support", "") + _ = NewSetting("auth-password-requirements-description", "") + _ = NewSetting("api-host", "") +) + +// FullShellImage returns the full private registry name of the rancher shell image. +func FullShellImage() string { + return PrefixPrivateRegistry(ShellImage.Get()) +} + +// PrefixPrivateRegistry prefixes the given image name with the stored private registry path. +func PrefixPrivateRegistry(image string) string { + private := SystemDefaultRegistry.Get() + if private == "" { + return image + } + return private + "/" + image +} + +// IsRelease returns true if the running server is a released version of rancher. +func IsRelease() bool { + return !strings.Contains(ServerVersion.Get(), "head") && releasePattern.MatchString(ServerVersion.Get()) +} + +func init() { + // setup auth setting + authsettings.AuthUserInfoResyncCron = AuthUserInfoResyncCron + authsettings.AuthUserSessionTTLMinutes = AuthUserSessionTTLMinutes + authsettings.AuthUserInfoMaxAgeSeconds = AuthUserInfoMaxAgeSeconds + authsettings.FirstLogin = FirstLogin + + if InjectDefaults == "" { + return + } + defaults := map[string]string{} + if err := json.Unmarshal([]byte(InjectDefaults), &defaults); err != nil { + return + } + for name, defaultValue := range defaults { + value, ok := settings[name] + if !ok { + continue + } + value.Default = defaultValue + settings[name] = value + } +} + +// Provider is an interfaced used to get and set Settings. +// NOTE: The behavior for treating unknown settings is undefined. +// A provider may choose to remove settings which it has a record of, +// but are not provided in SetAll call. +type Provider interface { + Get(name string) string + Set(name, value string) error + SetIfUnset(name, value string) error + SetAll(settings map[string]Setting) error +} + +// Setting stores information about a specific server setting. +type Setting struct { + Name string + // Default represents a value to be used in the absence of an actual Value stored in etcd on the Setting resource. + Default string + // DefaultOnUpgrade represents a desired Default value that the setting should have on upgrade from a previous minor + // or major version of Rancher. This is used for special cases where the value of the setting must stay the same + // on upgraded setups but use a new value for fresh installations for backward compatibility. + DefaultOnUpgrade string + ReadOnly bool +} + +// SetIfUnset will store the given value of the setting if it was not already stored. +func (s Setting) SetIfUnset(value string) error { + if provider == nil { + return s.Set(value) + } + return provider.SetIfUnset(s.Name, value) +} + +// Set will store the given value for the setting +func (s Setting) Set(value string) error { + if provider == nil { + s, ok := settings[s.Name] + if ok { + s.Default = value + settings[s.Name] = s + } + } else { + return provider.Set(s.Name, value) + } + return nil +} + +// Get will return the currently stored value of the setting. +func (s Setting) Get() string { + if provider == nil { + s := settings[s.Name] + return s.Default + } + return provider.Get(s.Name) +} + +// GetInt will return the currently stored value of the setting as an integer. +// If the stored value is not an integer then the default value will be returned as an integer. +// If the default value is not an integer then the function will return 0 +func (s Setting) GetInt() int { + v := s.Get() + i, err := strconv.Atoi(v) + if err == nil { + return i + } + logrus.Errorf("failed to parse setting %s=%s as int: %v", s.Name, v, err) + i, err = strconv.Atoi(s.Default) + if err != nil { + return 0 + } + return i +} + +// SetProvider will set the given provider as the global provider for all settings. +func SetProvider(p Provider) error { + if err := p.SetAll(settings); err != nil { + return err + } + provider = p + return nil +} + +// NewSetting will create and store a new server setting. +func NewSetting(name, def string) Setting { + s := Setting{ + Name: name, + Default: def, + } + settings[s.Name] = s + return s +} + +// WithDefaultOnUpgrade takes a setting and returns a new setting with the default value on upgrade set. +func (s Setting) WithDefaultOnUpgrade(defOnUpgrade string) Setting { + s.DefaultOnUpgrade = defOnUpgrade + settings[s.Name] = s + return s +} + +// GetEnvKey will return the given string formatted as a rancher environmental variable. +func GetEnvKey(key string) string { + return "CATTLE_" + strings.ToUpper(strings.Replace(key, "-", "_", -1)) +} + +func getMetadataConfig() string { + branch := KDMBranch.Get() + data := map[string]interface{}{ + "url": fmt.Sprintf("https://releases.rancher.com/kontainer-driver-metadata/%s/data.json", branch), + "refresh-interval-minutes": "1440", + } + ans, err := json.Marshal(data) + if err != nil { + logrus.Errorf("error getting metadata config %v", err) + return "" + } + return string(ans) +} + +// GetSettingByID returns a setting that is stored with the given id. +func GetSettingByID(id string) string { + if provider == nil { + s := settings[id] + return s.Default + } + return provider.Get(id) +} + +// DefaultAgentSettings will return a list of default agent settings +func DefaultAgentSettings() []Setting { + return []Setting{ + ServerVersion, + InstallUUID, + IngressIPDomain, + } +} + +// DefaultAgentSettingsAsEnvVars will return a list of default agent settings as environmental variables. +func DefaultAgentSettingsAsEnvVars() []v1.EnvVar { + defaultAgentSettings := DefaultAgentSettings() + envVars := make([]v1.EnvVar, 0, len(defaultAgentSettings)) + + for _, s := range defaultAgentSettings { + envVars = append(envVars, v1.EnvVar{ + Name: GetEnvKey(s.Name), + Value: s.Get(), + }) + } + + return envVars +} + +// GetRancherVersion will return the stored server version without the 'v' prefix. +func GetRancherVersion() string { + rancherVersion := ServerVersion.Get() + if strings.HasPrefix(rancherVersion, "dev") || strings.HasPrefix(rancherVersion, "master") || strings.HasSuffix(rancherVersion, "-head") { + return RancherVersionDev + } + return strings.TrimPrefix(rancherVersion, "v") +} + +// IterateWhitelistedEnvVars iterates over the environment variables whitelisted +// by CATTLE_WHITELIST_ENVVARS. If a variable is whitelisted but unset or empty, +// the handler function will not be called for it. +func IterateWhitelistedEnvVars(handler func(name, value string)) { + wl := WhitelistEnvironmentVars.Get() + envWhiteList := strings.Split(wl, ",") + + for _, wlVar := range envWhiteList { + wlVar = strings.TrimSpace(wlVar) + if val := os.Getenv(wlVar); val != "" { + handler(wlVar, val) + } + } +} + +// GetMachineProvisionImagePullPolicy will return the pull policy to be used on MachineProvisioning job. +// If an invalid value is set it will return the default value: v1.PullAlways +func GetMachineProvisionImagePullPolicy() v1.PullPolicy { + machineProvisionImagePullPolicy := MachineProvisionImagePullPolicy.Get() + switch v1.PullPolicy(machineProvisionImagePullPolicy) { + case v1.PullAlways: + return v1.PullAlways + case v1.PullIfNotPresent: + return v1.PullIfNotPresent + case v1.PullNever: + return v1.PullNever + default: + logrus.Warnf("failed to parse setting machine-provision-image-pull-policy value: %s defaulting to: %s", machineProvisionImagePullPolicy, v1.PullAlways) + return v1.PullAlways + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting_test.go new file mode 100644 index 0000000..9fa4e93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/settings/setting_test.go @@ -0,0 +1,188 @@ +package settings + +import ( + "encoding/json" + "fmt" + "io" + "os" + "testing" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" +) + +func TestFullShellImage(t *testing.T) { + originalShellImage := ShellImage.Get() + originalDefaultRegistry := SystemDefaultRegistry.Get() + + err := ShellImage.Set("image") + assert.NoError(t, err) + err = SystemDefaultRegistry.Set("") + assert.NoError(t, err) + assert.Equal(t, "image", FullShellImage()) + SystemDefaultRegistry.Set("prefix") + assert.Equal(t, "prefix/image", FullShellImage()) + + // Reset the settings for other tests + err = ShellImage.Set(originalShellImage) + assert.NoError(t, err) + err = SystemDefaultRegistry.Set(originalDefaultRegistry) + assert.NoError(t, err) +} + +func TestIsRelease(t *testing.T) { + inputs := map[string]bool{ + "dev": false, + "master-head": false, + "master": false, + "v2.5.2": true, + "v2": true, + "v2.0": true, + "v2.x": true, + "v2.5-head": false, + "2.5": false, + "2.5-head": false, + } + a := assert.New(t) + for key, value := range inputs { + if err := ServerVersion.Set(key); err != nil { + t.Errorf("Encountered error while setting temp version: %v\n", err) + } + result := IsRelease() + a.Equal(value, result, fmt.Sprintf("Expected value [%t] for key [%s]. Got value [%t]", value, key, result)) + } +} + +// TestSystemDefaultRegistryDefault tests that the default registry is either +// the value set by the environment variable CATTLE_BASE_REGISTRY or the build +// time value set through InjectDefaults. +func TestSystemDefaultRegistryDefault(t *testing.T) { + expect := os.Getenv("CATTLE_BASE_REGISTRY") + if InjectDefaults != "" { + defaults := map[string]string{} + if err := json.Unmarshal([]byte(InjectDefaults), &defaults); err != nil { + t.Errorf("Unable to parse InjectDefaults: %v", err) + } + + if value, ok := defaults["system-default-registry"]; ok { + expect = value + } + } + + got := SystemDefaultRegistry.Get() + if got != expect { + t.Errorf("The System Default Registry of %q is not the expected value %q", got, expect) + } +} + +// TestSystemFeatureChartRefreshSecondsDefault tests that the default refresh time is either +// the default value of 21600 seconds or the build time value set through InjectDefaults. +func TestSystemFeatureChartRefreshSecondsDefault(t *testing.T) { + expect := "21600" + if InjectDefaults != "" { + defaults := map[string]string{} + if err := json.Unmarshal([]byte(InjectDefaults), &defaults); err != nil { + t.Fatalf("Unable to parse InjectDefaults: %v", err) + } + + if value, ok := defaults["system-feature-chart-refresh-seconds"]; ok { + expect = value + } + } + + got := SystemFeatureChartRefreshSeconds.Get() + if got != expect { + t.Errorf("The System Feature Chart Refresh Seconds of %q is not the expected value %q", got, expect) + } + +} + +func TestGetMachineProvisionImagePullPolicy(t *testing.T) { + defaultLogger := logrus.StandardLogger().Out + logrus.SetOutput(io.Discard) // Done this way to avoid printing the error message during wrongValue test + defer func() { + logrus.SetOutput(defaultLogger) + }() + + testCases := []struct { + name string + input string + expected v1.PullPolicy + }{ + { + name: "Always", + input: "Always", + expected: v1.PullAlways, + }, + { + name: "Never", + input: "Never", + expected: v1.PullNever, + }, + { + name: "IfNotPresent", + input: "IfNotPresent", + expected: v1.PullIfNotPresent, + }, + { + name: "Wrong Value", + input: "wrongValue", + expected: v1.PullAlways, + }, + { + name: "Empty Value", + input: "", + expected: v1.PullAlways, + }, + } + + for _, v := range testCases { + t.Run(v.name, func(t *testing.T) { + if err := MachineProvisionImagePullPolicy.Set(v.input); err != nil { + t.Errorf("Failed to test GetMachineProvisionImagePullPolicy(), unable to set the value: %v", err) + } + got := GetMachineProvisionImagePullPolicy() + assert.Equalf(t, v.expected, got, fmt.Sprintf("test GetMachineProvisionImagePullPolicy() case: %s, input: %s failed with value: %s, expecting: %s", v.name, v.input, got, v.expected)) + }) + } +} + +func TestGetInt(t *testing.T) { + t.Parallel() + fakeIntSetting := NewSetting("int", "1") + fakeStringSetting := NewSetting("string", "one") + + err := fakeIntSetting.Set("2") + assert.NoError(t, err) + assert.Equal(t, 2, fakeIntSetting.GetInt()) + + err = fakeIntSetting.Set("two") + assert.NoError(t, err) + assert.Equal(t, 1, fakeIntSetting.GetInt()) + + err = fakeStringSetting.Set("2") + assert.NoError(t, err) + assert.Equal(t, 2, fakeStringSetting.GetInt()) + + err = fakeStringSetting.Set("two") + assert.NoError(t, err) + assert.Equal(t, 0, fakeStringSetting.GetInt()) +} + +func TestGetRancherVersion(t *testing.T) { + inputs := map[string]string{ + "dev-version": RancherVersionDev, + "master-version": RancherVersionDev, + "version-head": RancherVersionDev, + "v2.7.X": "2.7.X", + "2.7.X": "2.7.X", + } + + for key, value := range inputs { + err := ServerVersion.Set(key) + assert.NoError(t, err) + result := GetRancherVersion() + assert.Equal(t, value, result) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemaccount/systemaccount.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemaccount/systemaccount.go new file mode 100644 index 0000000..10888b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemaccount/systemaccount.go @@ -0,0 +1,183 @@ +package systemaccount + +import ( + "fmt" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/ref" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/rancher/pkg/user" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + errors2 "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + clusterOwnerRole = "cluster-owner" + projectMemberRole = "project-member" + ClusterSystemAccountPrefix = "System account for Cluster " + ProjectSystemAccountPrefix = "System account for Project " +) + +func NewManager(management *config.ManagementContext) *Manager { + return &Manager{ + userManager: management.UserManager, + systemTokens: management.SystemTokens, + crtbs: management.Management.ClusterRoleTemplateBindings(""), + crts: management.Management.ClusterRegistrationTokens(""), + prtbs: management.Management.ProjectRoleTemplateBindings(""), + prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + tokens: management.Management.Tokens(""), + users: management.Management.Users(""), + } +} + +func NewManagerFromScale(management *config.ScaledContext) *Manager { + return &Manager{ + userManager: management.UserManager, + systemTokens: management.SystemTokens, + crtbs: management.Management.ClusterRoleTemplateBindings(""), + crts: management.Management.ClusterRegistrationTokens(""), + prtbs: management.Management.ProjectRoleTemplateBindings(""), + prtbLister: management.Management.ProjectRoleTemplateBindings("").Controller().Lister(), + tokens: management.Management.Tokens(""), + tokenLister: management.Management.Tokens("").Controller().Lister(), + users: management.Management.Users(""), + } +} + +type Manager struct { + userManager user.Manager + systemTokens systemtokens.Interface + crtbs v3.ClusterRoleTemplateBindingInterface + crts v3.ClusterRegistrationTokenInterface + prtbs v3.ProjectRoleTemplateBindingInterface + prtbLister v3.ProjectRoleTemplateBindingLister + tokens v3.TokenInterface + tokenLister v3.TokenLister + users v3.UserInterface +} + +func (s *Manager) CreateSystemAccount(cluster *v3.Cluster) error { + user, err := s.GetSystemUser(cluster.Name) + if err != nil { + return err + } + + bindingName := user.Name + "-admin" + _, err = s.crtbs.GetNamespaced(cluster.Name, bindingName, v1.GetOptions{}) + if err == nil { + return nil + } + + _, err = s.crtbs.Create(&v3.ClusterRoleTemplateBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: bindingName, + Namespace: cluster.Name, + }, + ClusterName: cluster.Name, + UserName: user.Name, + RoleTemplateName: clusterOwnerRole, + }) + + return err +} + +func (s *Manager) GetSystemUser(clusterName string) (*v3.User, error) { + return s.userManager.EnsureUser(fmt.Sprintf("system://%s", clusterName), ClusterSystemAccountPrefix+clusterName) +} + +func (s *Manager) GetOrCreateSystemClusterToken(clusterName string) (string, error) { + token := "" + + crt, err := s.crts.GetNamespaced(clusterName, "system", v1.GetOptions{}) + if errors2.IsNotFound(err) { + token, err = randomtoken.Generate() + if err != nil { + return "", err + } + crt = &v3.ClusterRegistrationToken{ + ObjectMeta: v1.ObjectMeta{ + Name: "system", + Namespace: clusterName, + }, + Spec: v32.ClusterRegistrationTokenSpec{ + ClusterName: clusterName, + }, + Status: v32.ClusterRegistrationTokenStatus{ + Token: token, + }, + } + + if _, err := s.crts.Create(crt); err != nil { + return "", err + } + } else if err != nil { + return "", err + } else { + token = crt.Status.Token + } + + return token, nil +} + +func (s *Manager) GetOrCreateProjectSystemAccount(projectID string) error { + _, projectName := ref.Parse(projectID) + + u, err := s.GetProjectSystemUser(projectName) + if err != nil { + return err + } + + bindingName := u.Name + "-member" + _, err = s.prtbLister.Get(projectName, bindingName) + if err != nil { + if !errors2.IsNotFound(err) { + return err + } + // prtb does not exist in cache, attempt to create it + prtb := &v3.ProjectRoleTemplateBinding{ + ObjectMeta: v1.ObjectMeta{ + Name: bindingName, + Namespace: projectName, + }, + ProjectName: projectID, + UserName: u.Name, + RoleTemplateName: projectMemberRole, + } + if _, err := s.prtbs.Create(prtb); err != nil && !errors2.IsAlreadyExists(err) { + return err + } + } + return nil +} + +func (s *Manager) GetProjectSystemUser(projectName string) (*v3.User, error) { + return s.userManager.EnsureUser(fmt.Sprintf("system://%s", projectName), ProjectSystemAccountPrefix+projectName) +} + +func (s *Manager) CreateProjectHelmSystemToken(projectName string) (string, error) { + user, err := s.GetProjectSystemUser(projectName) + if err != nil { + return "", err + } + return s.systemTokens.EnsureSystemToken(projectName+"-helm", "Helm token for project "+projectName, "helm", user.Name, nil, true) +} + +func (s *Manager) RemoveSystemAccount(userID string) error { + u, err := s.userManager.GetUserByPrincipalID(fmt.Sprintf("system://%s", userID)) + if err != nil { + return err + } + if u == nil { + // user not found, must have been removed + return nil + } + if err := s.users.Delete(u.Name, &v1.DeleteOptions{}); err != nil && !errors2.IsNotFound(err) && !errors2.IsGone(err) { + return err + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import.go new file mode 100644 index 0000000..e925b28 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import.go @@ -0,0 +1,238 @@ +package systemtemplate + +import ( + "bytes" + "crypto/md5" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "io" + "sort" + "strings" + "text/template" + + "github.com/Masterminds/sprig/v3" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + util "github.com/rancher/rancher/pkg/cluster" + "github.com/rancher/rancher/pkg/features" + v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/image" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rke/templates" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" +) + +var ( + templateFuncMap = sprig.TxtFuncMap() + t = template.Must(template.New("import").Funcs(templateFuncMap).Parse(templateSource)) +) + +type context struct { + Features string + CAChecksum string + AgentImage string + AgentEnvVars string + AuthImage string + TokenKey string + Token string + URL string + Namespace string + URLPlain string + IsWindowsCluster bool + IsRKE bool + PrivateRegistryConfig string + Tolerations string + AppendTolerations string + Affinity string + ResourceRequirements string + ClusterRegistry string +} + +func toFeatureString(features map[string]bool) string { + buf := &strings.Builder{} + var keys []string + for k := range features { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + v := features[k] + if buf.Len() > 0 { + buf.WriteString(",") + } + buf.WriteString(k) + if v { + buf.WriteString("=true") + } else { + buf.WriteString("=false") + } + } + return buf.String() +} + +func SystemTemplate(resp io.Writer, agentImage, authImage, namespace, token, url string, isWindowsCluster bool, + cluster *apimgmtv3.Cluster, features map[string]bool, taints []corev1.Taint, secretLister v1.SecretLister) error { + var tolerations, agentEnvVars, agentAppendTolerations, agentAffinity, agentResourceRequirements string + d := md5.Sum([]byte(url + token + namespace)) + tokenKey := hex.EncodeToString(d[:])[:7] + + if authImage == "fixed" { + authImage = settings.AuthImage.Get() + } + + registryURL, registryConfig, err := util.GeneratePrivateRegistryEncodedDockerConfig(cluster, secretLister) + if err != nil { + return err + } + + if taints != nil { + tolerations = templates.ToYAML(taints) + } + + envVars := settings.DefaultAgentSettingsAsEnvVars() + if cluster != nil { + envVars = append(envVars, cluster.Spec.AgentEnvVars...) + } + + // Merge the env vars with the AgentTLSModeStrict + found := false + for _, ev := range envVars { + if ev.Name == "STRICT_VERIFY" { + found = true // The user has specified `STRICT_VERIFY`, we should not attempt to overwrite it. + } + } + if !found { + if settings.AgentTLSMode.Get() == settings.AgentTLSModeStrict { + envVars = append(envVars, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "true", + }) + } else { + envVars = append(envVars, corev1.EnvVar{ + Name: "STRICT_VERIFY", + Value: "false", + }) + } + } + + agentEnvVars = templates.ToYAML(envVars) + + if appendTolerations := util.GetClusterAgentTolerations(cluster); appendTolerations != nil { + agentAppendTolerations = templates.ToYAML(appendTolerations) + if agentAppendTolerations == "" { + return fmt.Errorf("error converting agent append tolerations to YAML") + } + } + + affinity, err := util.GetClusterAgentAffinity(cluster) + if err != nil { + return err + } + agentAffinity = templates.ToYAML(affinity) + if agentAffinity == "" { + return fmt.Errorf("error converting agent affinity to YAML") + } + + if resourceRequirements := util.GetClusterAgentResourceRequirements(cluster); resourceRequirements != nil { + agentResourceRequirements = templates.ToYAML(resourceRequirements) + if agentResourceRequirements == "" { + return fmt.Errorf("error converting agent resource requirements to YAML") + } + } + + context := &context{ + Features: toFeatureString(features), + CAChecksum: CAChecksum(), + AgentImage: agentImage, + AgentEnvVars: agentEnvVars, + AuthImage: authImage, + TokenKey: tokenKey, + Token: base64.StdEncoding.EncodeToString([]byte(token)), + URL: base64.StdEncoding.EncodeToString([]byte(url)), + Namespace: base64.StdEncoding.EncodeToString([]byte(namespace)), + URLPlain: url, + IsWindowsCluster: isWindowsCluster, + IsRKE: cluster != nil && cluster.Status.Driver == apimgmtv3.ClusterDriverRKE, + PrivateRegistryConfig: registryConfig, + Tolerations: tolerations, + AppendTolerations: agentAppendTolerations, + Affinity: agentAffinity, + ResourceRequirements: agentResourceRequirements, + ClusterRegistry: registryURL, + } + + return t.Execute(resp, context) +} + +func GetDesiredFeatures(cluster *apimgmtv3.Cluster) map[string]bool { + return map[string]bool{ + features.MCM.Name(): false, + features.MCMAgent.Name(): true, + features.Fleet.Name(): false, + features.RKE2.Name(): false, + features.ProvisioningV2.Name(): false, + features.EmbeddedClusterAPI.Name(): false, + features.UISQLCache.Name(): features.UISQLCache.Enabled(), + } +} + +func ForCluster(cluster *apimgmtv3.Cluster, token string, taints []corev1.Taint, secretLister v1.SecretLister) ([]byte, error) { + buf := &bytes.Buffer{} + err := SystemTemplate(buf, GetDesiredAgentImage(cluster), + GetDesiredAuthImage(cluster), + cluster.Name, token, settings.ServerURL.Get(), cluster.Spec.WindowsPreferedCluster, + cluster, GetDesiredFeatures(cluster), taints, secretLister) + return buf.Bytes(), err +} + +func InternalCAChecksum() string { + ca := settings.InternalCACerts.Get() + if ca != "" { + if !strings.HasSuffix(ca, "\n") { + ca += "\n" + } + digest := sha256.Sum256([]byte(ca)) + return hex.EncodeToString(digest[:]) + } + return "" +} + +func CAChecksum() string { + ca := settings.CACerts.Get() + if ca != "" { + if !strings.HasSuffix(ca, "\n") { + ca += "\n" + } + digest := sha256.Sum256([]byte(ca)) + return hex.EncodeToString(digest[:]) + } + return "" +} + +func GetDesiredAgentImage(cluster *apimgmtv3.Cluster) string { + logrus.Tracef("clusterDeploy: deployAgent called for [%s]", cluster.Name) + desiredAgent := cluster.Spec.DesiredAgentImage + if cluster.Spec.AgentImageOverride != "" { + desiredAgent = cluster.Spec.AgentImageOverride + } + if desiredAgent == "" || desiredAgent == "fixed" { + desiredAgent = image.ResolveWithCluster(settings.AgentImage.Get(), cluster) + } + logrus.Tracef("clusterDeploy: deployAgent: desiredAgent is [%s] for cluster [%s]", desiredAgent, cluster.Name) + return desiredAgent +} + +func GetDesiredAuthImage(cluster *apimgmtv3.Cluster) string { + var desiredAuth string + if cluster.Spec.LocalClusterAuthEndpoint.Enabled { + desiredAuth = cluster.Spec.DesiredAuthImage + if desiredAuth == "" || desiredAuth == "fixed" { + desiredAuth = image.ResolveWithCluster(settings.AuthImage.Get(), cluster) + } + } + logrus.Tracef("clusterDeploy: deployAgent: desiredAuth is [%s] for cluster [%s]", desiredAuth, cluster.Name) + return desiredAuth +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import_test.go new file mode 100644 index 0000000..7dac9ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/import_test.go @@ -0,0 +1,272 @@ +package systemtemplate + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "strings" + "testing" + + appsv1 "k8s.io/api/apps/v1" + rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/client-go/kubernetes/scheme" + + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + corefakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + rketypes "github.com/rancher/rke/types" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + mockSecrets = make(map[string]*corev1.Secret) +) + +func resetMockSecrets() { + mockSecrets = make(map[string]*corev1.Secret) +} + +func TestSystemTemplate_systemtemplate(t *testing.T) { + mockSecrets := map[string]*corev1.Secret{} + secretLister := &corefakes.SecretListerMock{ + GetFunc: func(namespace string, name string) (*corev1.Secret, error) { + id := fmt.Sprintf("%s:%s", namespace, name) + secret, ok := mockSecrets[fmt.Sprintf("%s:%s", namespace, name)] + if !ok { + return nil, apierror.NewNotFound(schema.GroupResource{}, id) + } + return secret.DeepCopy(), nil + }, + } + + tests := []struct { + name string + cluster *apimgmtv3.Cluster + agentImage string + authImage string + namespace string + token string + url string + isWindowsCluster bool + features map[string]bool + taints []corev1.Taint + secrets map[string]*corev1.Secret + expectedDeploymentHashes map[string]string + expectedDaemonSetHashes map[string]string + expectedClusterRoleHashes map[string]string + expectedClusterRoleBindingHashes map[string]string + expectedNamespaceHashes map[string]string + expectedServiceHashes map[string]string + expectedServiceAccountHashes map[string]string + expectedSecretHashes map[string]string + }{ + { + name: "test-rke", + cluster: &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-rke", + }, + Spec: apimgmtv3.ClusterSpec{ + ClusterSpecBase: apimgmtv3.ClusterSpecBase{ + RancherKubernetesEngineConfig: &rketypes.RancherKubernetesEngineConfig{}, + }, + }, + }, + expectedDeploymentHashes: map[string]string{ + "cattle-cluster-agent": "734cc6a47dfa564f230d39da48782e6f2ba9a55e0385aaa4d2fa7405375d8527", + }, + expectedDaemonSetHashes: map[string]string{}, + expectedClusterRoleHashes: map[string]string{ + "proxy-clusterrole-kubeapiserver": "0d28ae2947ce0c5faef85ff59169a5f65e0490552bf9cb00f29a98eb97a02a7e", + "cattle-admin": "009abecc023b1e4ac1bc35e4153ef4492b2bc66a5972df9c5617a38f587c3f42", + }, + expectedClusterRoleBindingHashes: map[string]string{ + "proxy-role-binding-kubernetes-master": "0df909395597974e60d905e9860bc0a02367bd2df74528d430c635c3f7afdeb0", + "cattle-admin-binding": "0da37cf0d4c4b4d068a3000967c4e37d11e1cecd126779633095dbe30b39c6ba", + }, + expectedNamespaceHashes: map[string]string{ + "cattle-system": "fd527fed9cae2e8b27f9610d64e9476e692a3dfde42954aeaecba450fe2b9571", + }, + expectedServiceHashes: map[string]string{ + "cattle-cluster-agent": "9512a8430f6d32f31eac6e4446724dc5a336c3d9c8147c824f2734c2f8afe792", + }, + expectedServiceAccountHashes: map[string]string{ + "cattle": "5cf160de85eaef5de9ce917130c64c23e91836920f7e9b2e2d7a8be8290079f2", + }, + expectedSecretHashes: map[string]string{ + "cattle-credentials-d41d8cd": "131d05388e50e23e5f22eb3b54676910e6ded959b3dd1333f7bc2096ee2e95e9", + }, + }, + { + name: "test-provisioned-import", + cluster: &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-prov", + }, + Spec: apimgmtv3.ClusterSpec{ + ImportedConfig: &apimgmtv3.ImportedConfig{}, + }, + }, + expectedDeploymentHashes: map[string]string{ + "cattle-cluster-agent": "734cc6a47dfa564f230d39da48782e6f2ba9a55e0385aaa4d2fa7405375d8527", + }, + expectedDaemonSetHashes: map[string]string{}, + expectedClusterRoleHashes: map[string]string{ + "proxy-clusterrole-kubeapiserver": "0d28ae2947ce0c5faef85ff59169a5f65e0490552bf9cb00f29a98eb97a02a7e", + "cattle-admin": "009abecc023b1e4ac1bc35e4153ef4492b2bc66a5972df9c5617a38f587c3f42", + }, + expectedClusterRoleBindingHashes: map[string]string{ + "proxy-role-binding-kubernetes-master": "0df909395597974e60d905e9860bc0a02367bd2df74528d430c635c3f7afdeb0", + "cattle-admin-binding": "0da37cf0d4c4b4d068a3000967c4e37d11e1cecd126779633095dbe30b39c6ba", + }, + expectedNamespaceHashes: map[string]string{ + "cattle-system": "fd527fed9cae2e8b27f9610d64e9476e692a3dfde42954aeaecba450fe2b9571", + }, + expectedServiceHashes: map[string]string{ + "cattle-cluster-agent": "9512a8430f6d32f31eac6e4446724dc5a336c3d9c8147c824f2734c2f8afe792", + }, + expectedServiceAccountHashes: map[string]string{ + "cattle": "5cf160de85eaef5de9ce917130c64c23e91836920f7e9b2e2d7a8be8290079f2", + }, + expectedSecretHashes: map[string]string{ + "cattle-credentials-d41d8cd": "131d05388e50e23e5f22eb3b54676910e6ded959b3dd1333f7bc2096ee2e95e9", + }, + }, + { + name: "test-provisioned-import-custom-agent", + cluster: &apimgmtv3.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-prov", + }, + Spec: apimgmtv3.ClusterSpec{ + ImportedConfig: &apimgmtv3.ImportedConfig{}, + }, + }, + url: "some-dummy-url", + token: "some-dummy-token", + agentImage: "my/agent:image", + expectedDeploymentHashes: map[string]string{ + "cattle-cluster-agent": "1d9554ad0e8dda26a8e4fa96879a5954a478bf9b22e2b1de4273292774390226", + }, + expectedDaemonSetHashes: map[string]string{}, + expectedClusterRoleHashes: map[string]string{ + "proxy-clusterrole-kubeapiserver": "0d28ae2947ce0c5faef85ff59169a5f65e0490552bf9cb00f29a98eb97a02a7e", + "cattle-admin": "009abecc023b1e4ac1bc35e4153ef4492b2bc66a5972df9c5617a38f587c3f42", + }, + expectedClusterRoleBindingHashes: map[string]string{ + "proxy-role-binding-kubernetes-master": "0df909395597974e60d905e9860bc0a02367bd2df74528d430c635c3f7afdeb0", + "cattle-admin-binding": "0da37cf0d4c4b4d068a3000967c4e37d11e1cecd126779633095dbe30b39c6ba", + }, + expectedNamespaceHashes: map[string]string{ + "cattle-system": "fd527fed9cae2e8b27f9610d64e9476e692a3dfde42954aeaecba450fe2b9571", + }, + expectedServiceHashes: map[string]string{ + "cattle-cluster-agent": "9512a8430f6d32f31eac6e4446724dc5a336c3d9c8147c824f2734c2f8afe792", + }, + expectedServiceAccountHashes: map[string]string{ + "cattle": "5cf160de85eaef5de9ce917130c64c23e91836920f7e9b2e2d7a8be8290079f2", + }, + expectedSecretHashes: map[string]string{ + "cattle-credentials-ea6f059": "13abfa9516b89b23f9451a71c3258a358ab68abddd6d9b661a106dc762028ada", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer resetMockSecrets() + + mockSecrets = tt.secrets + var b bytes.Buffer + err := SystemTemplate(&b, tt.agentImage, tt.authImage, tt.namespace, tt.token, tt.url, tt.isWindowsCluster, tt.cluster, tt.features, tt.taints, secretLister) + + assert.Nil(t, err) + decoder := scheme.Codecs.UniversalDeserializer() + + for _, r := range strings.Split(b.String(), "---") { + if len(r) == 0 { + continue + } + + obj, groupVersionKind, err := decoder.Decode( + []byte(r), + nil, + nil) + if err != nil { + continue + } + + switch groupVersionKind.Kind { + case "Deployment": + deployment := obj.(*appsv1.Deployment) + b, err := json.Marshal(deployment) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedDeploymentHashes[deployment.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, deployment.Name)) + case "ClusterRole": + clusterrole := obj.(*rbacv1.ClusterRole) + b, err := json.Marshal(clusterrole) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedClusterRoleHashes[clusterrole.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, clusterrole.Name)) + case "ClusterRoleBinding": + crb := obj.(*rbacv1.ClusterRoleBinding) + b, err := json.Marshal(crb) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedClusterRoleBindingHashes[crb.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, crb.Name)) + case "Namespace": + ns := obj.(*corev1.Namespace) + b, err := json.Marshal(ns) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedNamespaceHashes[ns.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, ns.Name)) + case "DaemonSet": + ds := obj.(*appsv1.DaemonSet) + b, err := json.Marshal(ds) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedDaemonSetHashes[ds.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, ds.Name)) + case "Service": + svc := obj.(*corev1.Service) + b, err := json.Marshal(svc) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedServiceHashes[svc.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, svc.Name)) + case "ServiceAccount": + svcacct := obj.(*corev1.ServiceAccount) + b, err := json.Marshal(svcacct) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedServiceAccountHashes[svcacct.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, svcacct.Name)) + case "Secret": + secret := obj.(*corev1.Secret) + b, err := json.Marshal(secret) + if err != nil { + assert.FailNow(t, err.Error()) + } + assert.Equal(t, tt.expectedSecretHashes[secret.Name], getHash(b), fmt.Sprintf("%s/%s", groupVersionKind.Kind, secret.Name)) + default: + assert.FailNow(t, fmt.Sprintf("unexpected Kind for GVK: %s", groupVersionKind.String())) + } + } + }) + } +} + +func getHash(b []byte) string { + sum := sha256.Sum256(b) + return hex.EncodeToString(sum[:]) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/template.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/template.go new file mode 100644 index 0000000..757ecb4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtemplate/template.go @@ -0,0 +1,506 @@ +package systemtemplate + +var templateSource = ` +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-clusterrole-kubeapiserver +rules: +- apiGroups: [""] + resources: + - nodes/metrics + - nodes/proxy + - nodes/stats + - nodes/log + - nodes/spec + verbs: ["get", "list", "watch", "create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-role-binding-kubernetes-master +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-clusterrole-kubeapiserver +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: kube-apiserver +--- +apiVersion: v1 +kind: Namespace +metadata: + name: cattle-system + +--- + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cattle + namespace: cattle-system + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cattle-admin-binding + namespace: cattle-system + labels: + cattle.io/creator: "norman" +subjects: +- kind: ServiceAccount + name: cattle + namespace: cattle-system +roleRef: + kind: ClusterRole + name: cattle-admin + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: cattle-credentials-{{.TokenKey}} + namespace: cattle-system +type: Opaque +data: + url: "{{.URL}}" + token: "{{.Token}}" + namespace: "{{.Namespace}}" + +--- + +{{- if .PrivateRegistryConfig}} +apiVersion: v1 +kind: Secret +metadata: + name: cattle-private-registry + namespace: cattle-system +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: "{{.PrivateRegistryConfig}}" + +--- +{{- end }} + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cattle-admin + labels: + cattle.io/creator: "norman" +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- nonResourceURLs: + - '*' + verbs: + - '*' + +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cattle-cluster-agent + namespace: cattle-system + annotations: + management.cattle.io/scale-available: "2" +spec: + selector: + matchLabels: + app: cattle-cluster-agent + template: + metadata: + labels: + app: cattle-cluster-agent + spec: + {{- if .Affinity }} + affinity: +{{ .Affinity | indent 8 }} + {{- end }} + serviceAccountName: cattle + tolerations: + {{- if .Tolerations }} + # Tolerations added based on found taints on controlplane nodes +{{ .Tolerations | indent 6 }} + {{- else }} + # No taints or no controlplane nodes found, added defaults + - effect: NoSchedule + key: node-role.kubernetes.io/controlplane + value: "true" + - effect: NoSchedule + key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + - effect: NoSchedule + key: "node-role.kubernetes.io/master" + operator: "Exists" + {{- end }} + {{- if .AppendTolerations }} +{{ .AppendTolerations | indent 6 }} + {{- end }} + containers: + - name: cluster-register + imagePullPolicy: IfNotPresent + {{- if .ResourceRequirements }} + resources: +{{ .ResourceRequirements | indent 12 }} + {{- end }} + env: + {{- if ne .Features "" }} + - name: CATTLE_FEATURES + value: "{{.Features}}" + {{- end }} + - name: CATTLE_IS_RKE + value: "{{.IsRKE}}" + - name: CATTLE_SERVER + value: "{{.URLPlain}}" + - name: CATTLE_CA_CHECKSUM + value: "{{.CAChecksum}}" + - name: CATTLE_CLUSTER + value: "true" + - name: CATTLE_K8S_MANAGED + value: "true" + - name: CATTLE_CLUSTER_REGISTRY + value: "{{.ClusterRegistry}}" + {{- if .AgentEnvVars}} +{{ .AgentEnvVars | indent 10 }} + {{- end }} + image: {{.AgentImage}} + volumeMounts: + - name: cattle-credentials + mountPath: /cattle-credentials + readOnly: true + {{- if .PrivateRegistryConfig}} + imagePullSecrets: + - name: cattle-private-registry + {{- end }} + volumes: + - name: cattle-credentials + secret: + secretName: cattle-credentials-{{.TokenKey}} + defaultMode: 320 + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 +{{ if .IsRKE }} + +--- + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: cattle-node-agent + namespace: cattle-system +spec: + selector: + matchLabels: + app: cattle-agent + template: + metadata: + labels: + app: cattle-agent + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/os + operator: NotIn + values: + - windows + hostNetwork: true + serviceAccountName: cattle + tolerations: + - operator: Exists + containers: + - name: agent + image: {{.AgentImage}} + imagePullPolicy: IfNotPresent + env: + - name: CATTLE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CATTLE_SERVER + value: "{{.URLPlain}}" + - name: CATTLE_CA_CHECKSUM + value: "{{.CAChecksum}}" + - name: CATTLE_CLUSTER + value: "false" + - name: CATTLE_K8S_MANAGED + value: "true" + - name: CATTLE_AGENT_CONNECT + value: "true" + {{- if .AgentEnvVars}} +{{ .AgentEnvVars | indent 8 }} + {{- end }} + volumeMounts: + - name: cattle-credentials + mountPath: /cattle-credentials + readOnly: true + - name: k8s-ssl + mountPath: /etc/kubernetes + - name: var-run + mountPath: /var/run + mountPropagation: HostToContainer + - name: run + mountPath: /run + mountPropagation: HostToContainer + - name: docker-certs + mountPath: /etc/docker/certs.d + securityContext: + privileged: true + {{- if .PrivateRegistryConfig}} + imagePullSecrets: + - name: cattle-private-registry + {{- end }} + volumes: + - name: k8s-ssl + hostPath: + path: /etc/kubernetes + type: DirectoryOrCreate + - name: var-run + hostPath: + path: /var/run + type: DirectoryOrCreate + - name: run + hostPath: + path: /run + type: DirectoryOrCreate + - name: cattle-credentials + secret: + secretName: cattle-credentials-{{.TokenKey}} + defaultMode: 320 + - hostPath: + path: /etc/docker/certs.d + type: DirectoryOrCreate + name: docker-certs + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 50% + +{{- end }} + +{{- if .IsWindowsCluster}} + +--- + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: cattle-node-agent-windows + namespace: cattle-system +spec: + selector: + matchLabels: + app: cattle-agent-windows + template: + metadata: + labels: + app: cattle-agent-windows + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/os + operator: NotIn + values: + - linux + serviceAccountName: cattle + tolerations: + - operator: Exists + containers: + - name: agent + image: {{.AgentImage}} + imagePullPolicy: IfNotPresent + env: + - name: CATTLE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: CATTLE_SERVER + value: "{{.URLPlain}}" + - name: CATTLE_CA_CHECKSUM + value: "{{.CAChecksum}}" + - name: CATTLE_CLUSTER + value: "false" + - name: CATTLE_K8S_MANAGED + value: "true" + - name: CATTLE_AGENT_CONNECT + value: "true" + volumeMounts: + - name: cattle-credentials + mountPath: c:/cattle-credentials + readOnly: true + - name: k8s-ssl + mountPath: c:/etc/kubernetes + - name: run + mountPath: c:/run + - name: docker-certs + mountPath: c:/etc/docker/certs.d + - name: docker-pipe + mountPath: \\.\pipe\docker_engine + - name: wins-pipe + mountPath: \\.\pipe\rancher_wins + - name: wins-config + mountPath: c:/etc/rancher/wins + volumes: + - name: k8s-ssl + hostPath: + path: c:/etc/kubernetes + type: DirectoryOrCreate + - name: run + hostPath: + path: c:/run + type: DirectoryOrCreate + - name: cattle-credentials + secret: + secretName: cattle-credentials-{{.TokenKey}} + - name: docker-certs + hostPath: + path: c:/ProgramData/docker/certs.d + type: DirectoryOrCreate + - name: docker-pipe + hostPath: + path: \\.\pipe\docker_engine + - name: wins-pipe + hostPath: + path: \\.\pipe\rancher_wins + - name: wins-config + hostPath: + path: c:/etc/rancher/wins + type: DirectoryOrCreate + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 50% +{{- end }} + +{{- if .AuthImage}} + +--- + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kube-api-auth + namespace: cattle-system +spec: + selector: + matchLabels: + app: kube-api-auth + template: + metadata: + labels: + app: kube-api-auth + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/os + operator: NotIn + values: + - windows + - key: node-role.kubernetes.io/controlplane + operator: In + values: + - "true" + - matchExpressions: + - key: beta.kubernetes.io/os + operator: NotIn + values: + - windows + - key: node-role.kubernetes.io/control-plane + operator: In + values: + - "true" + - matchExpressions: + - key: beta.kubernetes.io/os + operator: NotIn + values: + - windows + - key: node-role.kubernetes.io/master + operator: In + values: + - "true" + hostNetwork: true + serviceAccountName: cattle + tolerations: + - operator: Exists + containers: + - name: kube-api-auth + image: {{.AuthImage}} + imagePullPolicy: IfNotPresent + volumeMounts: + - name: k8s-ssl + mountPath: /etc/kubernetes + securityContext: + privileged: true + {{- if .PrivateRegistryConfig}} + imagePullSecrets: + - name: cattle-private-registry + {{- end }} + volumes: + - name: k8s-ssl + hostPath: + path: /etc/kubernetes + type: DirectoryOrCreate + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 25% +{{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: cattle-cluster-agent + namespace: cattle-system +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + targetPort: 444 + protocol: TCP + name: https-internal + selector: + app: cattle-cluster-agent +` + +var ( + AuthDaemonSet = ` +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kube-api-auth + namespace: cattle-system +` + NodeAgentDaemonSet = ` +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: cattle-node-agent + namespace: cattle-system +` +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtokens/systemtokens.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtokens/systemtokens.go new file mode 100644 index 0000000..af73dbf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/systemtokens/systemtokens.go @@ -0,0 +1,116 @@ +package systemtokens + +import ( + "errors" + "fmt" + "strings" + + "github.com/rancher/rancher/pkg/auth/tokens" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func NewSystemTokensFromScale(mgmt *config.ScaledContext) systemtokens.Interface { + return &systemTokens{ + tokenLister: mgmt.Management.Tokens("").Controller().Lister(), + tokenClient: mgmt.Management.Tokens(""), + } +} + +type systemTokens struct { + tokenClient v3.TokenInterface + tokenLister v3.TokenLister +} + +// EnsureSystemToken creates tokens or updates their values if they already exist and returns their value. +// TTL defaults to 1 hour, after that this method will auto-refresh. If your token will be in use for more +// than one hour without calling this method again you must pass in an overrideTTL. +// However, if the overrideTTL is 0 the token will never be cleaned up; this should be done with caution. +func (t *systemTokens) EnsureSystemToken(tokenName, description, kind, username string, overrideTTL *int64, randomize bool) (string, error) { + var err error + if !randomize { + _, err = t.tokenLister.Get("", tokenName) + if err != nil && !apierrors.IsNotFound(err) { + return "", err + } + } + + // needs fresh token because its missing or expired + val, err := t.createOrUpdateSystemToken(tokenName, description, kind, username, overrideTTL, randomize) + if err != nil { + return "", err + } + + return val, nil +} + +func (t *systemTokens) DeleteToken(tokenName string) error { + return t.tokenClient.Delete(tokenName, &v1.DeleteOptions{}) +} + +// Creates token obj with hashed token, returns token. Overwrites if pre-existing. +func (t *systemTokens) createOrUpdateSystemToken(tokenName, description, kind, userName string, overrideTTL *int64, randomize bool) (string, error) { + if strings.HasPrefix(tokenName, "token-") { + return "", errors.New("token names can't start with token-") + } + key, err := randomtoken.Generate() + if err != nil { + return "", errors.New("failed to generate token key") + } + + if !randomize { + token, err := t.tokenLister.Get("", tokenName) + if err != nil { + if !apierrors.IsNotFound(err) { + return "", err + } + } + if err == nil { + if err := t.tokenClient.Delete(token.Name, &v1.DeleteOptions{}); err != nil { + return "", err + } + } + } + + // not found error, make new token + token := &v3.Token{ + ObjectMeta: v1.ObjectMeta{ + Name: tokenName, + Labels: map[string]string{ + tokens.UserIDLabel: userName, + tokens.TokenKindLabel: kind, + }, + }, + TTLMillis: 3600000, // 1 hour, token purge daemon will cleanup + Description: description, + UserID: userName, + AuthProvider: "local", + IsDerived: true, + Token: key, + } + if overrideTTL != nil { + token.TTLMillis = *overrideTTL + } + if randomize { + token.ObjectMeta.Name = "" + token.ObjectMeta.GenerateName = tokenName + } + + err = tokens.ConvertTokenKeyToHash(token) + if err != nil { + return "", err + } + logrus.Infof("Creating system token for %v, token: %v", userName, tokenName) + token, err = t.tokenClient.Create(token) + if err != nil { + return "", err + } + + fullVal := fmt.Sprintf("%s:%s", token.Name, key) + return fullVal, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils.go new file mode 100644 index 0000000..f69e94c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils.go @@ -0,0 +1,147 @@ +package taints + +import ( + "fmt" + "strings" + + rketypes "github.com/rancher/rke/types" + + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" +) + +func GetTaintsString(taint v1.Taint) string { + return fmt.Sprintf("%s=%s:%s", taint.Key, taint.Value, taint.Effect) +} + +func GetRKETaintsString(taint rketypes.RKETaint) string { + return fmt.Sprintf("%s=%s:%s", taint.Key, taint.Value, taint.Effect) +} + +func GetKeyEffectString(taint v1.Taint) string { + return fmt.Sprintf("%s:%s", taint.Key, taint.Effect) +} + +func GetTaintFromString(taintStr string) *v1.Taint { + taintStruct := strings.Split(taintStr, "=") + if len(taintStruct) != 2 { + logrus.Warnf("taint string %s is not validated", taintStr) + return nil + } + tmp := strings.Split(taintStruct[1], ":") + if len(tmp) != 2 { + logrus.Warnf("taint string %s is not validated", taintStr) + return nil + } + key := taintStruct[0] + value := tmp[0] + effect := v1.TaintEffect(tmp[1]) + return &v1.Taint{ + Key: key, + Value: value, + Effect: effect, + } +} + +func GetTaintSet(taints []v1.Taint) map[string]int { + rtn := map[string]int{} + for i, taint := range taints { + rtn[GetTaintsString(taint)] = i + } + return rtn +} + +func GetKeyEffectTaintSet(taints []v1.Taint) map[string]int { + rtn := map[string]int{} + for i, taint := range taints { + rtn[GetKeyEffectString(taint)] = i + } + return rtn +} + +func GetToDiffTaints(current, desired []v1.Taint) (toAdd map[int]v1.Taint, toDel map[int]v1.Taint) { + toAdd, toDel = map[int]v1.Taint{}, map[int]v1.Taint{} + currentSet := GetTaintSet(current) + desiredSet := GetTaintSet(desired) + for k, index := range currentSet { + if _, ok := desiredSet[k]; !ok { + toDel[index] = current[index] + } + } + for k, index := range desiredSet { + if _, ok := currentSet[k]; !ok { + toAdd[index] = desired[index] + } + } + return toAdd, toDel +} + +func GetRKETaintsFromStrings(sources []string) []rketypes.RKETaint { + rtn := make([]rketypes.RKETaint, len(sources)) + for i, source := range sources { + t := GetTaintFromString(source) + rtn[i] = rketypes.RKETaint{ + Key: t.Key, + Value: t.Value, + Effect: t.Effect, + TimeAdded: t.TimeAdded, + } + } + return rtn +} + +func GetStringsFromRKETaint(taints []rketypes.RKETaint) []string { + var rtn []string + for _, taint := range taints { + rtn = append(rtn, GetRKETaintsString(taint)) + } + return rtn +} + +func GetRKETaintsFromTaints(sources []v1.Taint) []rketypes.RKETaint { + rtn := make([]rketypes.RKETaint, len(sources)) + for i, source := range sources { + rtn[i] = rketypes.RKETaint{ + Key: source.Key, + Effect: source.Effect, + Value: source.Value, + TimeAdded: source.TimeAdded, + } + } + return rtn +} + +func GetStringsFromTaint(taints []v1.Taint) []string { + var rtn []string + for _, taint := range taints { + rtn = append(rtn, GetTaintsString(taint)) + } + return rtn +} + +func GetTaintsFromStrings(sources []string) []v1.Taint { + var rtn []v1.Taint + for _, source := range sources { + taint := GetTaintFromString(source) + if taint == nil { + continue + } + rtn = append(rtn, *taint) + } + return rtn +} + +// MergeTaints will override t1 taint by t2 with same key and effect +func MergeTaints(t1 []v1.Taint, t2 []v1.Taint) []v1.Taint { + set1 := GetKeyEffectTaintSet(t1) + set2 := GetKeyEffectTaintSet(t2) + rtn := t2 + for key, i := range set1 { + if j, ok := set2[key]; ok { + logrus.Infof("overriding taint %s with %s", GetTaintsString(t1[i]), GetTaintsString(t2[j])) + continue + } + rtn = append(rtn, t1[i]) + } + return rtn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils_test.go new file mode 100644 index 0000000..26f896c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/taints/utils_test.go @@ -0,0 +1,86 @@ +package taints + +import ( + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" +) + +func TestMergeTaints(t *testing.T) { + type testCase struct { + name string + t1 []v1.Taint + t2 []v1.Taint + mergedTaints []v1.Taint + } + testCases := []testCase{ + testCase{ + name: "merge with unique key and effect", + t1: []v1.Taint{ + v1.Taint{ + Key: "t1", + Value: "t1", + Effect: v1.TaintEffectNoSchedule, + }, + }, + t2: []v1.Taint{ + v1.Taint{ + Key: "t2", + Value: "t2", + Effect: v1.TaintEffectNoSchedule, + }, + }, + mergedTaints: []v1.Taint{ + v1.Taint{ + Key: "t1", + Value: "t1", + Effect: v1.TaintEffectNoSchedule, + }, + v1.Taint{ + Key: "t2", + Value: "t2", + Effect: v1.TaintEffectNoSchedule, + }, + }, + }, + testCase{ + name: "override values", + t1: []v1.Taint{ + v1.Taint{ + Key: "t1", + Value: "t1", + Effect: v1.TaintEffectNoSchedule, + }, + }, + t2: []v1.Taint{ + v1.Taint{ + Key: "t1", + Value: "v3", + Effect: v1.TaintEffectNoSchedule, + }, + }, + mergedTaints: []v1.Taint{ + v1.Taint{ + Key: "t1", + Value: "v3", + Effect: v1.TaintEffectNoSchedule, + }, + }, + }, + } + for _, tc := range testCases { + merged := MergeTaints(tc.t1, tc.t2) + mergedSet := getUniqueSet(GetTaintSet(merged)) + expectedSet := getUniqueSet(GetTaintSet(tc.mergedTaints)) + assert.Equal(t, expectedSet, mergedSet, "test case %s failed, expected merged taints %+v are different from merged taints %+v", tc.name, expectedSet, mergedSet) + } +} + +func getUniqueSet(set map[string]int) map[string]struct{} { + rtn := make(map[string]struct{}, len(set)) + for key := range set { + rtn[key] = struct{}{} + } + return rtn +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/handler.go new file mode 100644 index 0000000..bac15f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/handler.go @@ -0,0 +1,13 @@ +package telemetry + +import ( + "net/http/httputil" + rurl "net/url" +) + +var rawURL = "http://localhost:8114" + +func NewProxy() *httputil.ReverseProxy { + url, _ := rurl.Parse(rawURL) + return httputil.NewSingleHostReverseProxy(url) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/telemetry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/telemetry.go new file mode 100644 index 0000000..e8aa88c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/telemetry/telemetry.go @@ -0,0 +1,156 @@ +package telemetry + +import ( + "context" + "fmt" + "os" + "os/exec" + "sync" + "time" + + "github.com/pkg/errors" + localprovider "github.com/rancher/rancher/pkg/auth/providers/local" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config" + ruser "github.com/rancher/rancher/pkg/user" + "github.com/rancher/wrangler/v3/pkg/ticker" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/labels" +) + +var adminRole = "Default Admin" + +type process struct { + cmd *exec.Cmd + running bool + lock sync.RWMutex +} + +func (p *process) kill() { + p.lock.Lock() + defer p.lock.Unlock() + if p.cmd.Process != nil { + p.cmd.Process.Kill() + } +} + +func (p *process) getRunningState() bool { + p.lock.RLock() + defer p.lock.RUnlock() + return p.running +} + +func (p *process) setRunningState(state bool) { + p.lock.Lock() + defer p.lock.Unlock() + p.running = state +} + +func isLeader(management *config.ScaledContext) bool { + if management.PeerManager == nil { + return true + } + return management.PeerManager.IsLeader() +} + +func Start(ctx context.Context, httpsPort int, management *config.ScaledContext) error { + p := process{ + lock: sync.RWMutex{}, + } + + // have two go routines running. One is to run telemetry if setting is true, one is to kill telemetry if setting is false + go func() { + t := time.NewTicker(time.Second * 5) + go func() { + <-ctx.Done() + t.Stop() + }() + defer t.Stop() + for range t.C { + if settings.TelemetryOpt.Get() == "in" && isLeader(management) { + if !p.running { + var token string + var e error + for i := 0; i < 3; i++ { + token, e = createToken(management) + if e != nil { + logrus.Info(e) + time.Sleep(time.Second * 5) + continue + } else { + break + } + } + if token == "" { + logrus.Infof("Unable to obtain token for telemetry service. Telemetry will not be launched.") + return + } + cmd := exec.Command("telemetry", "client", "--url", fmt.Sprintf("https://localhost:%d/v3", httpsPort), "--token-key", token) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + p.cmd = cmd + if err := cmd.Start(); err != nil { + logrus.Error(err) + continue + } + p.setRunningState(true) + // in here we don't care the error, it will block until the telemetry process exited + cmd.Wait() + p.setRunningState(false) + } + } + } + }() + + go func() { + for range ticker.Context(ctx, time.Second*5) { + if settings.TelemetryOpt.Get() != "in" || !isLeader(management) { + if p.getRunningState() { + p.kill() + p.setRunningState(false) + } + } + } + }() + + go func() { + select { + case <-ctx.Done(): + if p.getRunningState() { + p.kill() + p.setRunningState(false) + } + } + }() + return nil +} + +func createToken(management *config.ScaledContext) (string, error) { + users, err := management.Management.Users("").Controller().Lister().List("", labels.SelectorFromSet( + map[string]string{ + "authz.management.cattle.io/bootstrapping": "admin-user", + }, + )) + if err != nil { + return "", errors.Wrapf(err, "Can't list admin-user for telemetry. Err: %v. Retry after 5 seconds", err) + } + for _, user := range users { + if user.DisplayName == adminRole { + input := ruser.TokenInput{ + TokenName: "telemetry", + Description: "telemetry token", + Kind: "telemetry", + UserName: user.Name, + AuthProvider: localprovider.Name, + TTL: nil, + Randomize: false, + } + token, err := management.UserManager.EnsureToken(input) + if err != nil { + return "", errors.Wrapf(err, "Can't create token for telemetry. Err: %v. Retry after 5 seconds", err) + } + return token, nil + } + } + return "", errors.Errorf("user %s doesn't exist for telemetry. Retry after 5 seconds", adminRole) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config.go new file mode 100644 index 0000000..686713d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config.go @@ -0,0 +1,115 @@ +package tls + +import ( + "crypto/tls" + "fmt" + "sort" + "strings" +) + +var ( + validVersions = map[string]uint16{ + "1.3": tls.VersionTLS13, + "1.2": tls.VersionTLS12, + // Deprecated. + "1.1": tls.VersionTLS11, + // Deprecated. + "1.0": tls.VersionTLS10, + } + + // https://golang.org/pkg/crypto/tls/#pkg-constants + validCiphers10to12 = map[string]uint16{ + "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + } + + validCiphers13 = map[string]uint16{ + "TLS_AES_128_GCM_SHA256": tls.TLS_AES_128_GCM_SHA256, + "TLS_AES_256_GCM_SHA384": tls.TLS_AES_256_GCM_SHA384, + "TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256, + } +) + +func baseTLSConfig(minVersion, ciphers string) (*tls.Config, error) { + version, err := validatedMinVersion(minVersion) + if err != nil { + return nil, err + } + cipherSuites, err := validatedCiphers(ciphers, version) + if err != nil { + return nil, err + } + return &tls.Config{ + MinVersion: version, + CipherSuites: cipherSuites, + }, nil +} + +func validatedMinVersion(version string) (uint16, error) { + if val, ok := validVersions[strings.TrimSpace(version)]; ok { + return val, nil + } + valid := keysFromMap(validVersions) + sort.Strings(valid) + return 0, fmt.Errorf("unsupported minimal TLS version %s, must be one of: %s", version, strings.Join(valid, ", ")) +} + +func validatedCiphers(ciphers string, version uint16) ([]uint16, error) { + split := strings.Split(ciphers, ",") + if version == tls.VersionTLS13 { + return validatedCipherSet(split, validCiphers13) + } + return validatedCipherSet(split, union(validCiphers10to12, validCiphers13)) +} + +func validatedCipherSet(ciphers []string, validCiphers map[string]uint16) ([]uint16, error) { + tlsCiphers := make([]uint16, 0, len(ciphers)) + for _, cipher := range ciphers { + c, ok := validCiphers[strings.TrimSpace(cipher)] + if !ok { + valid := keysFromMap(validCiphers) + sort.Strings(valid) + return nil, fmt.Errorf("unsupported cipher %s, must be one or more of: %s", cipher, strings.Join(valid, "\n")) + } + tlsCiphers = append(tlsCiphers, c) + } + return tlsCiphers, nil +} + +func union(cipherSets ...map[string]uint16) map[string]uint16 { + result := make(map[string]uint16) + for _, set := range cipherSets { + for k, v := range set { + result[k] = v + } + } + return result +} + +func keysFromMap(input map[string]uint16) []string { + keys := make([]string, 0, len(input)) + for key := range input { + keys = append(keys, key) + } + return keys +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config_test.go new file mode 100644 index 0000000..c79d00b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/config_test.go @@ -0,0 +1,96 @@ +package tls + +import ( + "crypto/tls" + "reflect" + "testing" +) + +func TestBaseTLSConfig(t *testing.T) { + t.Parallel() + tests := []struct { + name string + minVersion string + ciphers string + cfg *tls.Config + errorExpected bool + }{ + { + name: "valid base config for TLS 1.0", + minVersion: "1.0", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + cfg: &tls.Config{ + MinVersion: tls.VersionTLS10, + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, + }, + }, + { + name: "valid base config for TLS 1.1", + minVersion: "1.1", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + cfg: &tls.Config{ + MinVersion: tls.VersionTLS11, + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, + }, + }, + { + name: "valid base config for TLS 1.2 with ciphers from 1.2 and 1.3", + minVersion: "1.2", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256", + cfg: &tls.Config{ + MinVersion: tls.VersionTLS12, + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_AES_128_GCM_SHA256}, + }, + }, + { + name: "valid base config for TLS 1.3", + minVersion: "1.3", + ciphers: "TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384", + cfg: &tls.Config{ + MinVersion: tls.VersionTLS13, + CipherSuites: []uint16{tls.TLS_AES_128_GCM_SHA256, tls.TLS_AES_256_GCM_SHA384}, + }, + }, + { + name: "unsupported min version", + minVersion: "3.4", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + errorExpected: true, + }, + { + name: "unknown cipher in cipher suite", + minVersion: "1.3", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,BAD_CIPHER", + errorExpected: true, + }, + { + name: "unsupported min version and unknown cipher in cipher suite", + minVersion: "3.4", + ciphers: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,BAD_CIPHER", + errorExpected: true, + }, + { + name: "wrong cipher for TLS 1.3", + minVersion: "1.3", + ciphers: "TLS_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + errorExpected: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + got, err := baseTLSConfig(test.minVersion, test.ciphers) + if err != nil && !test.errorExpected { + t.Fatalf("got an unexpected error: %v", err) + } + if err == nil && test.errorExpected { + t.Fatalf("expected an error but did not get it") + } + if !reflect.DeepEqual(got, test.cfg) { + t.Errorf("\nexpected\n%v\ngot\n%v", test.cfg, got) + } + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/tls.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/tls.go new file mode 100644 index 0000000..4144142 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tls/tls.go @@ -0,0 +1,402 @@ +package tls + +import ( + "context" + "crypto/tls" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + "github.com/rancher/dynamiclistener" + "github.com/rancher/dynamiclistener/cert" + "github.com/rancher/dynamiclistener/server" + "github.com/rancher/dynamiclistener/storage/kubernetes" + "github.com/rancher/norman/types/convert" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps" + appscontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" + corev1controllers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" +) + +const ( + rancherCertFile = "/etc/rancher/ssl/cert.pem" + rancherKeyFile = "/etc/rancher/ssl/key.pem" + rancherCACertsFile = "/etc/rancher/ssl/cacerts.pem" + + commonName = "rancher" +) + +type internalAPI struct{} + +var ( + InternalAPI = internalAPI{} +) + +func ListenAndServe(ctx context.Context, restConfig *rest.Config, handler http.Handler, bindHost string, httpsPort, httpPort int, acmeDomains []string, noCACerts bool) error { + restConfig = rest.CopyConfig(restConfig) + restConfig.Timeout = 10 * time.Minute + opts := &server.ListenOpts{} + var err error + + core, err := core.NewFactoryFromConfig(restConfig) + if err != nil { + return err + } + apps, err := apps.NewFactoryFromConfig(restConfig) + if err != nil { + return err + } + + if httpsPort != 0 { + opts, err = SetupListener(core.Core().V1().Secret(), acmeDomains, noCACerts) + if err != nil { + return errors.Wrap(err, "failed to setup TLS listener") + } + } + + opts.BindHost = bindHost + + migrateConfig(ctx, restConfig, opts) + + backoff := wait.Backoff{ + Duration: 100 * time.Millisecond, + Factor: 2, + Steps: 3, + } + + // Try listen and serve over if there is an already exist error which comes from + // creating the ca. Rancher will hit this error during HA startup as all servers + // will race to create the ca secret. + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + if err := server.ListenAndServe(ctx, httpsPort, httpPort, handler, opts); err != nil { + if apierrors.IsAlreadyExists(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return errors.Wrap(err, "failed to ListenAndServe") + } + + internalPort := 0 + if httpsPort != 0 { + internalPort = httpsPort + 1 + } + + serverOptions := &server.ListenOpts{ + Storage: opts.Storage, + Secrets: opts.Secrets, + CAName: "tls-rancher-internal-ca", + CANamespace: namespace.System, + CertNamespace: namespace.System, + CertName: "tls-rancher-internal", + } + clusterIP, err := getClusterIP(core.Core().V1().Service()) + if err != nil { + return err + } + hostIPs, err := getHostIPs(apps.Apps().V1().Deployment(), core.Core().V1().Node()) + if err != nil { + return err + } + + if clusterIP != "" { + hostIPs = append(hostIPs, clusterIP) + } + if len(hostIPs) > 0 { + serverOptions.TLSListenerConfig = dynamiclistener.Config{ + SANs: hostIPs, + } + } + + internalAPICtx := context.WithValue(ctx, InternalAPI, true) + err = wait.ExponentialBackoff(backoff, func() (bool, error) { + if err := server.ListenAndServe(internalAPICtx, internalPort, 0, handler, serverOptions); err != nil { + if apierrors.IsAlreadyExists(err) { + return false, nil + } + return false, err + } + return true, nil + }) + if err != nil { + return errors.Wrap(err, "failed to ListenAndServe for fleet") + } + + if err := core.Start(ctx, 5); err != nil { + return err + } + + <-ctx.Done() + return ctx.Err() + +} + +func migrateConfig(ctx context.Context, restConfig *rest.Config, opts *server.ListenOpts) { + c, err := dynamic.NewForConfig(restConfig) + if err != nil { + return + } + + config, err := c.Resource(schema.GroupVersionResource{ + Group: "management.cattle.io", + Version: "v3", + Resource: "listenconfigs", + }).Get(ctx, "cli-config", metav1.GetOptions{}) + if err != nil { + return + } + + known := convert.ToStringSlice(config.Object["knownIps"]) + for k := range convert.ToMapInterface(config.Object["generatedCerts"]) { + if strings.HasPrefix(k, "local/") { + continue + } + known = append(known, k) + } + + for _, k := range known { + k = strings.SplitN(k, ":", 2)[0] + found := false + for _, san := range opts.TLSListenerConfig.SANs { + if san == k { + found = true + break + } + } + if !found { + opts.TLSListenerConfig.SANs = append(opts.TLSListenerConfig.SANs, k) + } + } +} + +func SetupListener(secrets corev1controllers.SecretController, acmeDomains []string, noCACerts bool) (*server.ListenOpts, error) { + caForAgent, noCACerts, opts, err := readConfig(secrets, acmeDomains, noCACerts) + if err != nil { + return nil, err + } + + if noCACerts { + caForAgent = "" + } else if caForAgent == "" { + caCert, caKey, err := kubernetes.LoadOrGenCA(secrets, opts.CANamespace, opts.CAName) + if err != nil { + return nil, err + } + caForAgent = string(cert.EncodeCertPEM(caCert)) + opts.CA = caCert + opts.CAKey = caKey + } + + caForAgent = strings.TrimSpace(caForAgent) + if settings.CACerts.Get() != caForAgent { + if err := settings.CACerts.Set(caForAgent); err != nil { + return nil, err + } + } + + return opts, nil +} + +func readConfig(secrets corev1controllers.SecretController, acmeDomains []string, noCACerts bool) (string, bool, *server.ListenOpts, error) { + var ( + ca string + err error + ) + + tlsConfig, err := baseTLSConfig(settings.TLSMinVersion.Get(), settings.TLSCiphers.Get()) + if err != nil { + return "", noCACerts, nil, err + } + + expiration, err := strconv.Atoi(settings.RotateCertsIfExpiringInDays.Get()) + if err != nil { + return "", noCACerts, nil, errors.Wrapf(err, "parsing %s", settings.RotateCertsIfExpiringInDays.Get()) + } + + sans := []string{"localhost", "127.0.0.1", "rancher.cattle-system"} + ip, err := net.ChooseHostInterface() + if err == nil { + sans = append(sans, ip.String()) + } + + opts := &server.ListenOpts{ + Secrets: secrets, + CAName: "tls-rancher", + CANamespace: "cattle-system", + CertNamespace: "cattle-system", + AcmeDomains: acmeDomains, + TLSListenerConfig: dynamiclistener.Config{ + TLSConfig: tlsConfig, + ExpirationDaysCheck: expiration, + SANs: sans, + FilterCN: filterCN, + CloseConnOnCertChange: true, + }, + } + + // ACME / Let's Encrypt + // If --acme-domain is set, configure and return + if len(acmeDomains) > 0 { + return "", true, opts, nil + } + + // Mounted certificates + // If certificate file/key are set + certFileExists := fileExists(rancherCertFile) + keyFileExists := fileExists(rancherKeyFile) + + // If certificate file exists but not certificate key, or other way around, error out + if (certFileExists && !keyFileExists) || (!certFileExists && keyFileExists) { + return "", noCACerts, nil, fmt.Errorf("invalid SSL configuration found, please set both certificate file and certificate key file (one is missing)") + } + + caFileExists := fileExists(rancherCACertsFile) + + // If certificate file and certificate key file exists, load files into listenConfig + if certFileExists && keyFileExists { + cert, err := tls.LoadX509KeyPair(rancherCertFile, rancherKeyFile) + if err != nil { + return "", noCACerts, nil, err + } + opts.TLSListenerConfig.TLSConfig.Certificates = []tls.Certificate{cert} + + // Selfsigned needs cacerts, recognized CA needs --no-cacerts but can't be used together + if (caFileExists && noCACerts) || (!caFileExists && !noCACerts) { + return "", noCACerts, nil, fmt.Errorf("invalid SSL configuration found, please set cacerts when using self signed certificates or use --no-cacerts when using certificates from a recognized Certificate Authority, do not use both at the same time") + } + // Load cacerts if exists + if caFileExists { + ca, err = readPEM(rancherCACertsFile) + if err != nil { + return "", noCACerts, nil, err + } + } + return ca, noCACerts, opts, nil + } + + // External termination + // We need to check if cacerts is passed or if --no-cacerts is used (when not providing certificate file and key) + // If cacerts is passed + if caFileExists { + // We can't have --no-cacerts + if noCACerts { + return "", noCACerts, nil, fmt.Errorf("invalid SSL configuration found, please set cacerts when using self signed certificates or use --no-cacerts when using certificates from a recognized Certificate Authority, do not use both at the same time") + } + ca, err = readPEM(rancherCACertsFile) + if err != nil { + return "", noCACerts, nil, err + } + } + + // No certificates mounted or only --no-cacerts used + return ca, noCACerts, opts, nil +} + +func getClusterIP(services corev1controllers.ServiceController) (string, error) { + service, err := services.Get(namespace.System, commonName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return "", nil + } + return "", err + } + if service.Spec.ClusterIP == "" { + return "", fmt.Errorf("waiting on service %s/rancher to be assigned a ClusterIP", namespace.System) + } + return service.Spec.ClusterIP, nil +} + +func getHostIPs(deployments appscontrollers.DeploymentController, nodes corev1controllers.NodeController) ([]string, error) { + deployment, err := deployments.Get(namespace.System, commonName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return nil, nil + } + return nil, err + } + + for _, container := range deployment.Spec.Template.Spec.Containers { + if container.Name != commonName { + continue + } + for _, port := range container.Ports { + if port.HostIP != "" || port.HostPort != 0 { + return collectNodeIPs(nodes) + } + } + } + return nil, nil +} + +func collectNodeIPs(nodeController corev1controllers.NodeController) ([]string, error) { + nodes, err := nodeController.List(metav1.ListOptions{}) + if err != nil { + return nil, err + } + + nodeIPs := make([]string, 0, 2*len(nodes.Items)) + for _, node := range nodes.Items { + for _, ip := range node.Status.Addresses { + if ip.Type == v1.NodeInternalIP || ip.Type == v1.NodeExternalIP { + nodeIPs = append(nodeIPs, ip.Address) + } + } + } + + return nodeIPs, nil +} + +func filterCN(cns ...string) []string { + serverURL := settings.ServerURL.Get() + if serverURL == "" { + return cns + } + u, err := url.Parse(serverURL) + if err != nil { + logrus.Errorf("invalid server-url, can not parse %s: %v", serverURL, err) + return cns + } + host := u.Hostname() + if host != "" { + return []string{host} + } + return cns +} + +func fileExists(path string) bool { + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + +func readPEM(path string) (string, error) { + content, err := ioutil.ReadFile(path) + if err != nil { + return "", err + } + + return string(content), nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/chain.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/chain.go new file mode 100644 index 0000000..0578d06 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/chain.go @@ -0,0 +1,47 @@ +package tunnelserver + +import ( + "fmt" + "net/http" + + "github.com/rancher/remotedialer" + "github.com/sirupsen/logrus" +) + +type Authorizers struct { + chain []remotedialer.Authorizer +} + +func ErrorWriter(rw http.ResponseWriter, req *http.Request, code int, err error) { + fullAddress := req.RemoteAddr + forwardedFor := req.Header.Get("X-Forwarded-For") + if forwardedFor != "" { + fullAddress = fmt.Sprintf("%s (X-Forwarded-For: %s)", req.RemoteAddr, forwardedFor) + } + logrus.Errorf("Failed to handle tunnel request from remote address %s: response %d: %v", fullAddress, code, err) + logrus.Tracef("ErrorWriter: response code: %d, request: %v", code, req) + remotedialer.DefaultErrorWriter(rw, req, code, err) +} + +func (a *Authorizers) Authorize(req *http.Request) (clientKey string, authed bool, err error) { + var ( + firstErr error + ) + + for _, auth := range a.chain { + key, authed, err := auth(req) + if err != nil || !authed { + if firstErr == nil { + firstErr = err + } + continue + } + return key, authed, err + } + + return "", false, firstErr +} + +func (a *Authorizers) Add(authorizer remotedialer.Authorizer) { + a.chain = append(a.chain, authorizer) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/mcmauthorizer/tunnel.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/mcmauthorizer/tunnel.go new file mode 100644 index 0000000..def587c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/mcmauthorizer/tunnel.go @@ -0,0 +1,427 @@ +package mcmauthorizer + +import ( + "crypto/md5" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "net/http" + "reflect" + "strings" + + v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/secretmigrator" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + "github.com/rancher/rancher/pkg/kontainerdriver" + "github.com/rancher/rancher/pkg/namespace" + + "github.com/rancher/norman/types/convert" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/taints" + "github.com/rancher/rancher/pkg/types/config" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +const ( + crtKeyIndex = "crtKeyIndex" + nodeKeyIndex = "nodeKeyIndex" + + Token = "X-API-Tunnel-Token" + Params = "X-API-Tunnel-Params" +) + +var ( + ErrClusterNotFound = errors.New("cluster not found") + importDrivers = map[string]bool{ + v32.ClusterDriverImported: true, + v32.ClusterDriverK3s: true, + v32.ClusterDriverK3os: true, + v32.ClusterDriverRancherD: true, + v32.ClusterDriverRke2: true, + } +) + +type cluster struct { + Address string `json:"address"` + Token string `json:"token"` + CACert string `json:"caCert"` +} + +type input struct { + Node *client.Node `json:"node"` + Cluster *cluster `json:"cluster"` + NodeVersion int `json:"nodeVersion"` +} + +func NewAuthorizer(context *config.ScaledContext) *Authorizer { + auth := &Authorizer{ + crtIndexer: context.Management.ClusterRegistrationTokens("").Controller().Informer().GetIndexer(), + clusterLister: context.Management.Clusters("").Controller().Lister(), + nodeIndexer: context.Management.Nodes("").Controller().Informer().GetIndexer(), + machineLister: context.Management.Nodes("").Controller().Lister(), + machines: context.Management.Nodes(""), + clusters: context.Management.Clusters(""), + KontainerDriverLister: context.Management.KontainerDrivers("").Controller().Lister(), + Secrets: context.Core.Secrets(""), + SecretLister: context.Core.Secrets("").Controller().Lister(), + } + context.Management.ClusterRegistrationTokens("").Controller().Informer().AddIndexers(map[string]cache.IndexFunc{ + crtKeyIndex: auth.crtIndex, + }) + context.Management.Nodes("").Controller().Informer().AddIndexers(map[string]cache.IndexFunc{ + nodeKeyIndex: auth.nodeIndex, + }) + return auth +} + +type Authorizer struct { + crtIndexer cache.Indexer + clusterLister v3.ClusterLister + nodeIndexer cache.Indexer + machineLister v3.NodeLister + machines v3.NodeInterface + clusters v3.ClusterInterface + KontainerDriverLister v3.KontainerDriverLister + Secrets corev1.SecretInterface + SecretLister corev1.SecretLister +} + +type Client struct { + Cluster *v3.Cluster + Node *v3.Node + Token string + Server string + NodeVersion int +} + +func (t *Authorizer) AuthorizeTunnel(req *http.Request) (string, bool, error) { + client, ok, err := t.Authorize(req) + if client != nil && client.Node != nil { + return client.Cluster.Name + ":" + client.Node.Name, ok, err + } else if client != nil && client.Cluster != nil { + return client.Cluster.Name, ok, err + } + + return "", false, err +} + +func (t *Authorizer) Authorize(req *http.Request) (*Client, bool, error) { + token := req.Header.Get(Token) + if token == "" { + logrus.Debugf("Authorize: Token header [%s] is empty", Token) + return nil, false, nil + } + + cluster, err := t.getClusterByToken(token) + if err != nil || cluster == nil { + return nil, false, err + } + + input, err := t.readInput(cluster, req) + if err != nil { + return nil, false, err + } + + if input.Node != nil { + register := strings.HasSuffix(req.URL.Path, "/register") + + node, ok, err := t.authorizeNode(register, cluster, input.Node, req) + if err != nil { + return nil, false, err + } + if register && node.Status.NodeConfig != nil && input.Node.CustomConfig != nil { + node = node.DeepCopy() + node.Status.NodeConfig.Address = input.Node.CustomConfig.Address + node.Status.NodeConfig.InternalAddress = input.Node.CustomConfig.InternalAddress + node.Status.NodeConfig.Taints = taints.GetRKETaintsFromStrings(input.Node.CustomConfig.Taints) + } + return &Client{ + Cluster: cluster, + Node: node, + Token: token, + Server: req.Host, + NodeVersion: input.NodeVersion, + }, ok, err + } + + if input.Cluster != nil { + cluster, ok, err := t.authorizeCluster(cluster, input.Cluster, req) + return &Client{ + Cluster: cluster, + Token: token, + Server: req.Host, + }, ok, err + } + + return nil, false, nil +} + +func (t *Authorizer) getMachine(cluster *v3.Cluster, inNode *client.Node) (*v3.Node, error) { + machineName := machineName(inNode) + logrus.Tracef("getMachine: looking up machine [%s] in cluster [%s]", machineName, cluster.Name) + machine, err := t.machineLister.Get(cluster.Name, machineName) + if apierrors.IsNotFound(err) { + if objs, err := t.nodeIndexer.ByIndex(nodeKeyIndex, fmt.Sprintf("%s/%s", cluster.Name, inNode.RequestedHostname)); err == nil { + for _, obj := range objs { + return obj.(*v3.Node), err + } + } + + logrus.Tracef("getMachine: looking up [%s] as node name in cluster [%s]", inNode.RequestedHostname, cluster.Name) + machine, err := t.machineLister.Get(cluster.Name, inNode.RequestedHostname) + if err == nil { + logrus.Debugf("Found [%s] as node name in cluster [%s], error: %v", inNode.RequestedHostname, cluster.Name, err) + return machine, nil + } + + logrus.Tracef("getMachine: looking up [%s] as RequestedHostname in cluster [%s]", inNode.RequestedHostname, cluster.Name) + machines, _ := t.machineLister.List(cluster.Name, labels.NewSelector()) + for _, machine := range machines { + logrus.Tracef("getMachine: comparing machine.Spec.RequestedHostname [%s] to inNode.RequestedHostname [%s]", machine.Spec.RequestedHostname, inNode.RequestedHostname) + if machine.Spec.RequestedHostname == inNode.RequestedHostname { + return machine, nil + } + } + } + + return machine, err +} + +func (t *Authorizer) authorizeNode(register bool, cluster *v3.Cluster, inNode *client.Node, req *http.Request) (*v3.Node, bool, error) { + machine, err := t.getMachine(cluster, inNode) + if apierrors.IsNotFound(err) { + if !register { + return nil, false, err + } + machine, err = t.createNode(inNode, cluster, req) + if err != nil { + return nil, false, err + } + } else if err != nil && machine == nil { + return nil, false, err + } + + if register { + machine, err = t.updateNode(machine, inNode, cluster) + if err != nil { + return nil, false, err + } + } + + logrus.Tracef("updateDockerInfo: cluster [%s] node [%s] dockerInfo [%v]", cluster.Name, machine.Name, inNode.DockerInfo) + machine, err = t.updateDockerInfo(machine, inNode) + return machine, true, err +} + +func (t *Authorizer) createNode(inNode *client.Node, cluster *v3.Cluster, req *http.Request) (*v3.Node, error) { + customConfig := t.toCustomConfig(inNode) + if customConfig == nil { + return nil, errors.New("invalid input, missing custom config") + } + + if customConfig.Address == "" { + return nil, errors.New("invalid input, address empty") + } + + name := machineName(inNode) + + machine := &v3.Node{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + Namespace: cluster.Name, + }, + Spec: v32.NodeSpec{ + Etcd: inNode.Etcd, + ControlPlane: inNode.ControlPlane, + Worker: inNode.Worker, + RequestedHostname: inNode.RequestedHostname, + CustomConfig: customConfig, + Imported: true, + }, + } + + return t.machines.Create(machine) +} + +func (t *Authorizer) updateDockerInfo(machine *v3.Node, inNode *client.Node) (*v3.Node, error) { + if inNode.DockerInfo == nil { + return machine, nil + } + + dockerInfo := &v32.DockerInfo{} + err := convert.ToObj(inNode.DockerInfo, dockerInfo) + if err != nil { + return nil, err + } + + newMachine := machine.DeepCopy() + newMachine.Status.DockerInfo = dockerInfo + if !reflect.DeepEqual(machine, newMachine) { + return t.machines.Update(newMachine) + } + return machine, nil +} + +func (t *Authorizer) updateNode(machine *v3.Node, inNode *client.Node, cluster *v3.Cluster) (*v3.Node, error) { + newMachine := machine.DeepCopy() + newMachine.Spec.Etcd = inNode.Etcd + newMachine.Spec.ControlPlane = inNode.ControlPlane + newMachine.Spec.Worker = inNode.Worker + if !reflect.DeepEqual(machine, newMachine) { + return t.machines.Update(newMachine) + } + return machine, nil +} + +func (t *Authorizer) authorizeCluster(cluster *v3.Cluster, inCluster *cluster, req *http.Request) (*v3.Cluster, bool, error) { + var ( + err error + ) + + if !importDrivers[cluster.Status.Driver] && cluster.Status.Driver != "" { + return cluster, true, nil + } + + changed := false + + if cluster.Status.Driver == "" { + driver, err := kontainerdriver.GetDriver(cluster, t.KontainerDriverLister) + if err != nil { + return cluster, true, err + } + if driver == "" { + logrus.Tracef("Setting the driver to imported for cluster %v %v", cluster.Name, cluster.Spec.DisplayName) + cluster.Status.Driver = v32.ClusterDriverImported + changed = true + } + } + + apiEndpoint := "https://" + inCluster.Address + token := inCluster.Token + caCert := inCluster.CACert + + var currentSecret *corev1.Secret + migrator := secretmigrator.NewMigrator(t.SecretLister, t.Secrets) + if importDrivers[cluster.Status.Driver] { + currentSecret, _ := t.SecretLister.Get(namespace.GlobalNamespace, cluster.Status.ServiceAccountTokenSecret) + if cluster.Status.APIEndpoint != apiEndpoint || + cluster.Status.CACert != caCert || + cluster.Status.ServiceAccountTokenSecret == "" || + tokenChanged(currentSecret, token) { + secret, err := migrator.CreateOrUpdateServiceAccountTokenSecret("", token, cluster) + if err != nil { + return cluster, true, err + } + if currentSecret != nil && secret.GetResourceVersion() != currentSecret.GetResourceVersion() { + logrus.Infof("updated service account token for cluster %s (%s)", cluster.Name, cluster.Spec.DisplayName) + } + cluster.Status.APIEndpoint = apiEndpoint + cluster.Status.ServiceAccountTokenSecret = secret.Name + cluster.Status.ServiceAccountToken = "" + cluster.Status.CACert = caCert + changed = true + } + } + + if changed { + _, err = t.clusters.Update(cluster) + if currentSecret != nil { + migrator.CleanupKnownSecrets([]*corev1.Secret{currentSecret}) + } + } + + return cluster, true, err +} + +func tokenChanged(secret *corev1.Secret, token string) bool { + return secret != nil && string(secret.Data[secretmigrator.SecretKey]) != token +} + +func (t *Authorizer) readInput(cluster *v3.Cluster, req *http.Request) (*input, error) { + params := req.Header.Get(Params) + var input input + + bytes, err := base64.StdEncoding.DecodeString(params) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(bytes, &input); err != nil { + return nil, err + } + + if input.Node == nil && input.Cluster == nil { + return nil, errors.New("missing node or cluster registration info") + } + + if input.Node != nil && input.Node.RequestedHostname == "" { + return nil, errors.New("invalid input, hostname empty") + } + + if input.Cluster != nil && input.Cluster.Address == "" { + return nil, errors.New("invalid input, address empty") + } + + if input.Cluster != nil && input.Cluster.Token == "" { + return nil, errors.New("invalid input, token empty") + } + + if input.Cluster != nil && input.Cluster.CACert == "" { + return nil, errors.New("invalid input, caCert empty") + } + + return &input, nil +} + +func machineName(machine *client.Node) string { + digest := md5.Sum([]byte(machine.RequestedHostname)) + machineNameMD5 := fmt.Sprintf("m-%s", hex.EncodeToString(digest[:])[:12]) + logrus.Tracef("machineName: returning [%s] for node with RequestedHostname [%s]", machineNameMD5, machine.RequestedHostname) + return machineNameMD5 +} + +func (t *Authorizer) getClusterByToken(token string) (*v3.Cluster, error) { + keys, err := t.crtIndexer.ByIndex(crtKeyIndex, token) + if err != nil { + return nil, err + } + + for _, obj := range keys { + crt := obj.(*v3.ClusterRegistrationToken) + return t.clusterLister.Get("", crt.Spec.ClusterName) + } + + return nil, ErrClusterNotFound +} + +func (t *Authorizer) crtIndex(obj interface{}) ([]string, error) { + crt := obj.(*v3.ClusterRegistrationToken) + if crt.Status.Token == "" { + return nil, nil + } + return []string{crt.Status.Token}, nil +} + +func (t *Authorizer) nodeIndex(obj interface{}) ([]string, error) { + node := obj.(*v3.Node) + return []string{fmt.Sprintf("%s/%s", node.Namespace, node.Status.NodeName)}, nil +} + +func (t *Authorizer) toCustomConfig(machine *client.Node) *v32.CustomConfig { + if machine == nil || machine.CustomConfig == nil { + return nil + } + + result := &v32.CustomConfig{} + if err := convert.ToObj(machine.CustomConfig, result); err != nil { + return nil + } + return result +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/peermanager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/peermanager.go new file mode 100644 index 0000000..f8afd75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/tunnelserver/peermanager.go @@ -0,0 +1,229 @@ +package tunnelserver + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" + "sync" + + "github.com/pkg/errors" + "github.com/rancher/norman/types/set" + "github.com/rancher/rancher/pkg/peermanager" + "github.com/rancher/rancher/pkg/serviceaccounttoken" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/remotedialer" + "github.com/rancher/wrangler/v3/pkg/data" + corecontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/sirupsen/logrus" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/net" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +func NewPeerManager(ctx context.Context, endpoints corecontrollers.EndpointsController, dialer *remotedialer.Server) (peermanager.PeerManager, error) { + return startPeerManager(ctx, endpoints, dialer) +} + +type peerManager struct { + sync.Mutex + leader bool + ready bool + token string + urlFormat string + server *remotedialer.Server + peers map[string]bool + listeners map[chan<- peermanager.Peers]bool +} + +func getTokenFromToken(ctx context.Context, tokenBytes []byte) ([]byte, error) { + // detect and handle 1.21+ token + parts := strings.Split(string(tokenBytes), ".") + if len(parts) != 3 { + return nil, fmt.Errorf("invalid token, not jwt format") + } + newBytes, err := base64.RawStdEncoding.DecodeString(parts[1]) + if err != nil { + return nil, fmt.Errorf("decoding service token: %w", err) + } + data := data.Object{} + if err := json.Unmarshal(newBytes, &data); err != nil { + return nil, fmt.Errorf("unmarshal service token: %w", err) + } + ns := data.String("kubernetes.io", "namespace") + name := data.String("kubernetes.io", "serviceaccount", "name") + + if name == "" || ns == "" { + return tokenBytes, nil + } + + cfg, err := rest.InClusterConfig() + if err != nil { + return nil, err + } + + client, err := kubernetes.NewForConfig(cfg) + if err != nil { + return nil, err + } + + sa, err := client.CoreV1().ServiceAccounts(ns).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + secret, err := serviceaccounttoken.EnsureSecretForServiceAccount(ctx, nil, client, sa) + if err != nil { + return nil, err + } + return secret.Data[v1.ServiceAccountTokenKey], nil +} + +func startPeerManager(ctx context.Context, endpoints corecontrollers.EndpointsController, server *remotedialer.Server) (peermanager.PeerManager, error) { + tokenBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token") + if os.IsNotExist(err) || settings.Namespace.Get() == "" || settings.PeerServices.Get() == "" { + logrus.Infof("Running in single server mode, will not peer connections") + return nil, nil + } else if err != nil { + return nil, err + } + + tokenBytes, err = getTokenFromToken(ctx, tokenBytes) + if err != nil { + return nil, err + } + + ip, err := net.ChooseHostInterface() + if err != nil { + return nil, errors.Wrap(err, "choosing interface IP") + } + + logrus.Infof("Running in clustered mode with ID %s, monitoring endpoint %s/%s", ip, settings.Namespace.Get(), settings.PeerServices.Get()) + + server.PeerID = ip.String() + server.PeerToken = string(tokenBytes) + + pm := &peerManager{ + token: server.PeerToken, + urlFormat: "wss://%s/v3/connect", + server: server, + peers: map[string]bool{}, + listeners: map[chan<- peermanager.Peers]bool{}, + } + + endpoints.OnChange(ctx, "peer-manager-controller", pm.syncService) + return pm, nil +} + +func (p *peerManager) syncService(key string, endpoint *v1.Endpoints) (*v1.Endpoints, error) { + if endpoint == nil { + return nil, nil + } + + if endpoint.Namespace != settings.Namespace.Get() { + return endpoint, nil + } + + parts := strings.SplitN(key, "/", 2) + if len(parts) != 2 { + return nil, nil + } + + ns, name := parts[0], parts[1] + if ns != settings.Namespace.Get() { + return nil, nil + } + + for _, svc := range strings.Split(settings.PeerServices.Get(), ",") { + if name == strings.TrimSpace(svc) { + p.addRemovePeers(endpoint) + break + } + } + + return nil, nil +} + +func (p *peerManager) addRemovePeers(endpoints *v1.Endpoints) { + p.Lock() + defer p.Unlock() + + newSet := map[string]bool{} + ready := false + for _, subset := range endpoints.Subsets { + for _, addr := range subset.Addresses { + if addr.IP == p.server.PeerID { + ready = true + } else { + newSet[addr.IP] = true + } + } + } + + toCreate, toDelete, _ := set.Diff(newSet, p.peers) + for _, ip := range toCreate { + p.server.AddPeer(fmt.Sprintf(p.urlFormat, ip), ip, p.token) + } + for _, ip := range toDelete { + p.server.RemovePeer(ip) + } + + p.peers = newSet + p.ready = ready + p.notify() +} + +func (p *peerManager) notify() { + peers := peermanager.Peers{ + Leader: p.leader, + Ready: p.ready, + SelfID: p.server.PeerID, + } + + for id := range p.peers { + peers.IDs = append(peers.IDs, id) + } + + for c := range p.listeners { + c <- peers + } +} + +func (p *peerManager) AddListener(c chan<- peermanager.Peers) { + p.Lock() + defer p.Unlock() + p.listeners[c] = true +} + +func (p *peerManager) RemoveListener(c chan<- peermanager.Peers) { + p.Lock() + defer p.Unlock() + delete(p.listeners, c) + c <- peermanager.Peers{ + SelfID: p.server.PeerID, + Leader: p.leader, + } +} + +func (p *peerManager) IsLeader() bool { + p.Lock() + defer p.Unlock() + return p.leader +} + +func (p *peerManager) Leader() { + p.Lock() + defer p.Unlock() + + if p.leader { + return + } + + p.leader = true + p.notify() +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/context.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/context.go new file mode 100644 index 0000000..10dfbcf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/context.go @@ -0,0 +1,519 @@ +/* +Package config contains functions for creating management, scaled, and user contexts that user norman controllers. +*/ +package config + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/rancher/lasso/pkg/cache" + "github.com/rancher/lasso/pkg/client" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/norman/objectclient/dynamic" + "github.com/rancher/norman/restwatch" + "github.com/rancher/norman/store/proxy" + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/catalog/manager" + "github.com/rancher/rancher/pkg/controllers" + "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io" + apiregistrationv1 "github.com/rancher/rancher/pkg/generated/norman/apiregistration.k8s.io/v1" + appsv1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + autoscaling "github.com/rancher/rancher/pkg/generated/norman/autoscaling/v2" + batchv1 "github.com/rancher/rancher/pkg/generated/norman/batch/v1" + clusterv3 "github.com/rancher/rancher/pkg/generated/norman/cluster.cattle.io/v3" + corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + extv1beta1 "github.com/rancher/rancher/pkg/generated/norman/extensions/v1beta1" + managementv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + knetworkingv1 "github.com/rancher/rancher/pkg/generated/norman/networking.k8s.io/v1" + projectv3 "github.com/rancher/rancher/pkg/generated/norman/project.cattle.io/v3" + rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + storagev1 "github.com/rancher/rancher/pkg/generated/norman/storage.k8s.io/v1" + "github.com/rancher/rancher/pkg/peermanager" + clusterSchema "github.com/rancher/rancher/pkg/schemas/cluster.cattle.io/v3" + managementSchema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" + projectSchema "github.com/rancher/rancher/pkg/schemas/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/types/config/dialer" + "github.com/rancher/rancher/pkg/types/config/systemtokens" + "github.com/rancher/rancher/pkg/user" + "github.com/rancher/rancher/pkg/wrangler" + steve "github.com/rancher/steve/pkg/server" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac" + wrbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/sirupsen/logrus" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + k8dynamic "k8s.io/client-go/dynamic" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +var ( + UserStorageContext types.StorageContext = "user" + ManagementStorageContext types.StorageContext = "mgmt" +) + +type ScaledContext struct { + ClientGetter proxy.ClientGetter + RESTConfig rest.Config + ControllerFactory controller.SharedControllerFactory + UnversionedClient rest.Interface + K8sClient kubernetes.Interface + APIExtClient clientset.Interface + Schemas *types.Schemas + AccessControl types.AccessControl + Dialer dialer.Factory + SystemTokens systemtokens.Interface + UserManager user.Manager + PeerManager peermanager.PeerManager + CatalogManager manager.CatalogManager + + Management managementv3.Interface + Project projectv3.Interface + RBAC rbacv1.Interface + Core corev1.Interface + Storage storagev1.Interface + + Wrangler *wrangler.Context + RunContext context.Context + managementContext *ManagementContext +} + +func (c *ScaledContext) NewManagementContext() (*ManagementContext, error) { + if c.managementContext != nil { + return c.managementContext, nil + } + mgmt, err := newManagementContext(c) + if err != nil { + return nil, err + } + mgmt.Dialer = c.Dialer + mgmt.UserManager = c.UserManager + mgmt.SystemTokens = c.SystemTokens + mgmt.CatalogManager = c.CatalogManager + mgmt.Wrangler = c.Wrangler + c.managementContext = mgmt + return mgmt, nil +} + +type ScaleContextOptions struct { + ControllerFactory controller.SharedControllerFactory +} + +func enableProtobuf(cfg *rest.Config) *rest.Config { + cpy := rest.CopyConfig(cfg) + cpy.AcceptContentTypes = "application/vnd.kubernetes.protobuf, application/json" + cpy.ContentType = "application/json" + return cpy +} + +func NewScaledContext(config rest.Config, opts *ScaleContextOptions) (*ScaledContext, error) { + var err error + + if opts == nil { + opts = &ScaleContextOptions{} + } + + context := &ScaledContext{ + RESTConfig: *steve.RestConfigDefaults(&config), + } + + if opts.ControllerFactory == nil { + controllerFactoryOpts := controllers.GetOptsFromEnv(controllers.Scaled) + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(enableProtobuf(&context.RESTConfig), wrangler.Scheme, controllerFactoryOpts) + if err != nil { + return nil, err + } + context.ControllerFactory = controllerFactory + } else { + context.ControllerFactory = opts.ControllerFactory + } + + context.Management = managementv3.NewFromControllerFactory(context.ControllerFactory) + context.Project = projectv3.NewFromControllerFactory(context.ControllerFactory) + context.RBAC = rbacv1.NewFromControllerFactory(context.ControllerFactory) + context.Core = corev1.NewFromControllerFactory(context.ControllerFactory) + + context.K8sClient, err = kubernetes.NewForConfig(&config) + if err != nil { + return nil, err + } + + dynamicConfig := config + if dynamicConfig.NegotiatedSerializer == nil { + dynamicConfig.NegotiatedSerializer = dynamic.NegotiatedSerializer + } + + context.UnversionedClient, err = restwatch.UnversionedRESTClientFor(&dynamicConfig) + if err != nil { + return nil, err + } + + context.APIExtClient, err = clientset.NewForConfig(&dynamicConfig) + if err != nil { + return nil, err + } + + context.Schemas = types.NewSchemas(). + AddSchemas(managementSchema.Schemas). + AddSchemas(clusterSchema.Schemas). + AddSchemas(projectSchema.Schemas) + + return context, err +} + +func (c *ScaledContext) Start(ctx context.Context) error { + logrus.Info("Starting API controllers") + return c.ControllerFactory.Start(ctx, 50) +} + +type ManagementContext struct { + ClientGetter proxy.ClientGetter + RESTConfig rest.Config + ControllerFactory controller.SharedControllerFactory + UnversionedClient rest.Interface + DynamicClient k8dynamic.Interface + K8sClient kubernetes.Interface + APIExtClient clientset.Interface + Schemas *types.Schemas + Scheme *runtime.Scheme + Dialer dialer.Factory + UserManager user.Manager + SystemTokens systemtokens.Interface + CatalogManager manager.CatalogManager + + Management managementv3.Interface + Project projectv3.Interface + RBAC rbacv1.Interface + Core corev1.Interface + Apps appsv1.Interface + Wrangler *wrangler.Context +} + +type UserContext struct { + Management *ManagementContext + ClusterName string + RESTConfig rest.Config + ControllerFactory controller.SharedControllerFactory + UnversionedClient rest.Interface + APIExtClient clientset.Interface + K8sClient kubernetes.Interface + runContext context.Context + + APIAggregation apiregistrationv1.Interface + Apps appsv1.Interface + Autoscaling autoscaling.Interface + Catalog catalog.Interface + Project projectv3.Interface + Core corev1.Interface + RBAC rbacv1.Interface + Extensions extv1beta1.Interface + BatchV1 batchv1.Interface + Networking knetworkingv1.Interface + Cluster clusterv3.Interface + Storage storagev1.Interface + + RBACw wrbacv1.Interface + Corew wcorev1.Interface + KindNamespaces map[schema.GroupVersionKind]string +} + +// WithAgent returns a shallow copy of the Context that has been configured to use a user agent in its +// clients that is the given userAgent appended to "rancher-%s-%s". +func (c *ManagementContext) WithAgent(userAgent string) *ManagementContext { + mgmtCopy := *c + fullUserAgent := fmt.Sprintf("rancher-%s-%s", settings.ServerVersion.Get(), userAgent) + mgmtCopy.Management = managementv3.NewFromControllerFactoryWithAgent(fullUserAgent, c.ControllerFactory) + mgmtCopy.Project = projectv3.NewFromControllerFactoryWithAgent(fullUserAgent, c.ControllerFactory) + mgmtCopy.RBAC = rbacv1.NewFromControllerFactoryWithAgent(fullUserAgent, c.ControllerFactory) + mgmtCopy.Core = corev1.NewFromControllerFactoryWithAgent(fullUserAgent, c.ControllerFactory) + mgmtCopy.Apps = appsv1.NewFromControllerFactoryWithAgent(fullUserAgent, c.ControllerFactory) + + mgmtCopy.Wrangler = mgmtCopy.Wrangler.WithAgent(userAgent) + + return &mgmtCopy +} + +func (w *UserContext) DeferredStart(ctx context.Context, register func(ctx context.Context) error) func() error { + f := w.deferredStartAsync(ctx, register) + return func() error { + go f() + return nil + } +} + +func (w *UserContext) deferredStartAsync(ctx context.Context, register func(ctx context.Context) error) func() error { + var ( + startLock sync.Mutex + started = false + ) + + return func() error { + startLock.Lock() + defer startLock.Unlock() + + if started { + return nil + } + + cancelCtx, cancel := context.WithCancel(ctx) + transaction := controller.NewHandlerTransaction(cancelCtx) + if err := register(transaction); err != nil { + cancel() + transaction.Rollback() + return err + } + + if err := w.Start(cancelCtx); err != nil { + cancel() + transaction.Rollback() + return err + } + + transaction.Commit() + started = true + go func() { + // this is make go vet happy that we aren't leaking a context + <-ctx.Done() + cancel() + }() + return nil + } +} + +func (w *UserContext) UserOnlyContext() *UserOnlyContext { + return &UserOnlyContext{ + Schemas: w.Management.Schemas, + ClusterName: w.ClusterName, + RESTConfig: w.RESTConfig, + UnversionedClient: w.UnversionedClient, + K8sClient: w.K8sClient, + + Autoscaling: w.Autoscaling, + Apps: w.Apps, + Project: w.Project, + Core: w.Core, + RBAC: w.RBAC, + Extensions: w.Extensions, + Networking: w.Networking, + BatchV1: w.BatchV1, + Cluster: w.Cluster, + Storage: w.Storage, + } +} + +type UserOnlyContext struct { + Schemas *types.Schemas + ClusterName string + RESTConfig rest.Config + ControllerFactory controller.SharedControllerFactory + UnversionedClient rest.Interface + K8sClient kubernetes.Interface + + APIRegistration apiregistrationv1.Interface + Apps appsv1.Interface + Autoscaling autoscaling.Interface + Project projectv3.Interface + Core corev1.Interface + RBAC rbacv1.Interface + Extensions extv1beta1.Interface + BatchV1 batchv1.Interface + Networking knetworkingv1.Interface + Cluster clusterv3.Interface + Storage storagev1.Interface +} + +func newManagementContext(c *ScaledContext) (*ManagementContext, error) { + var err error + + context := &ManagementContext{ + RESTConfig: *steve.RestConfigDefaults(&c.RESTConfig), + } + + config := c.RESTConfig + controllerFactory := c.ControllerFactory + context.ControllerFactory = controllerFactory + + context.Management = managementv3.NewFromControllerFactory(controllerFactory) + context.Project = projectv3.NewFromControllerFactory(controllerFactory) + context.RBAC = rbacv1.NewFromControllerFactory(controllerFactory) + context.Core = corev1.NewFromControllerFactory(controllerFactory) + context.Apps = appsv1.NewFromControllerFactory(controllerFactory) + + context.K8sClient, err = kubernetes.NewForConfig(&config) + if err != nil { + return nil, err + } + + context.DynamicClient, err = k8dynamic.NewForConfig(&config) + if err != nil { + return nil, err + } + + dynamicConfig := config + if dynamicConfig.NegotiatedSerializer == nil { + dynamicConfig.NegotiatedSerializer = dynamic.NegotiatedSerializer + } + + context.UnversionedClient, err = restwatch.UnversionedRESTClientFor(&dynamicConfig) + if err != nil { + return nil, err + } + + context.APIExtClient, err = clientset.NewForConfig(&dynamicConfig) + if err != nil { + return nil, err + } + + context.Schemas = types.NewSchemas(). + AddSchemas(managementSchema.Schemas). + AddSchemas(clusterSchema.Schemas). + AddSchemas(projectSchema.Schemas) + + context.Scheme = wrangler.Scheme + + return context, err +} + +func NewUserContext(scaledContext *ScaledContext, config rest.Config, clusterName string) (*UserContext, error) { + var err error + context := &UserContext{ + RESTConfig: *steve.RestConfigDefaults(&config), + ClusterName: clusterName, + runContext: scaledContext.RunContext, + KindNamespaces: map[schema.GroupVersionKind]string{}, + } + + context.Management, err = scaledContext.NewManagementContext() + if err != nil { + return nil, err + } + + clientFactory, err := client.NewSharedClientFactory(enableProtobuf(&context.RESTConfig), &client.SharedClientFactoryOptions{ + Scheme: wrangler.Scheme, + }) + if err != nil { + return nil, err + } + + cacheFactory := cache.NewSharedCachedFactory(clientFactory, &cache.SharedCacheFactoryOptions{ + KindNamespace: context.KindNamespaces, + }) + + controllerFactory := controller.NewSharedControllerFactory(cacheFactory, controllers.GetOptsFromEnv(controllers.User)) + context.ControllerFactory = controllerFactory + + context.K8sClient, err = kubernetes.NewForConfig(&config) + if err != nil { + return nil, err + } + + context.Apps = appsv1.NewFromControllerFactory(controllerFactory) + context.Core = corev1.NewFromControllerFactory(controllerFactory) + context.Project = projectv3.NewFromControllerFactory(controllerFactory) + context.Storage = storagev1.NewFromControllerFactory(controllerFactory) + context.RBAC = rbacv1.NewFromControllerFactory(controllerFactory) + context.Networking = knetworkingv1.NewFromControllerFactory(controllerFactory) + context.Extensions = extv1beta1.NewFromControllerFactory(controllerFactory) + context.BatchV1 = batchv1.NewFromControllerFactory(controllerFactory) + context.Autoscaling = autoscaling.NewFromControllerFactory(controllerFactory) + context.Cluster = clusterv3.NewFromControllerFactory(controllerFactory) + context.APIAggregation = apiregistrationv1.NewFromControllerFactory(controllerFactory) + + wranglerConf := config + wranglerConf.Timeout = 30 * time.Minute + opts := &generic.FactoryOptions{ + SharedControllerFactory: controllerFactory, + } + rbacw, err := rbac.NewFactoryFromConfigWithOptions(&wranglerConf, opts) + if err != nil { + return nil, err + } + context.RBACw = rbacw.Rbac().V1() + corew, err := core.NewFactoryFromConfigWithOptions(&wranglerConf, opts) + if err != nil { + return nil, err + } + context.Corew = corew.Core().V1() + + ctlg, err := catalog.NewFactoryFromConfigWithOptions(&context.RESTConfig, &catalog.FactoryOptions{SharedControllerFactory: controllerFactory}) + if err != nil { + return nil, err + } + context.Catalog = ctlg.Catalog() + + dynamicConfig := config + if dynamicConfig.NegotiatedSerializer == nil { + dynamicConfig.NegotiatedSerializer = dynamic.NegotiatedSerializer + } + + context.UnversionedClient, err = restwatch.UnversionedRESTClientFor(&dynamicConfig) + if err != nil { + return nil, err + } + + context.APIExtClient, err = clientset.NewForConfig(&dynamicConfig) + if err != nil { + return nil, err + } + + return context, err +} + +func (w *UserContext) Start(ctx context.Context) error { + logrus.Info("Starting cluster controllers for ", w.ClusterName) + if err := w.Management.ControllerFactory.Start(w.runContext, 50); err != nil { + return err + } + return w.ControllerFactory.Start(ctx, 5) +} + +func NewUserOnlyContext(config *wrangler.Context) (*UserOnlyContext, error) { + var err error + context := &UserOnlyContext{ + RESTConfig: *config.RESTConfig, + ControllerFactory: config.ControllerFactory, + K8sClient: config.K8s, + } + + context.Apps = appsv1.NewFromControllerFactory(context.ControllerFactory) + context.Core = corev1.NewFromControllerFactory(context.ControllerFactory) + context.Project = projectv3.NewFromControllerFactory(context.ControllerFactory) + context.Storage = storagev1.NewFromControllerFactory(context.ControllerFactory) + context.RBAC = rbacv1.NewFromControllerFactory(context.ControllerFactory) + context.Extensions = extv1beta1.NewFromControllerFactory(context.ControllerFactory) + context.BatchV1 = batchv1.NewFromControllerFactory(context.ControllerFactory) + context.Autoscaling = autoscaling.NewFromControllerFactory(context.ControllerFactory) + context.Cluster = clusterv3.NewFromControllerFactory(context.ControllerFactory) + context.APIRegistration = apiregistrationv1.NewFromControllerFactory(context.ControllerFactory) + context.Networking = knetworkingv1.NewFromControllerFactory(context.ControllerFactory) + + dynamicConfig := context.RESTConfig + if dynamicConfig.NegotiatedSerializer == nil { + dynamicConfig.NegotiatedSerializer = dynamic.NegotiatedSerializer + } + + context.UnversionedClient, err = restwatch.UnversionedRESTClientFor(&dynamicConfig) + if err != nil { + return nil, err + } + + context.Schemas = types.NewSchemas(). + AddSchemas(managementSchema.Schemas). + AddSchemas(clusterSchema.Schemas). + AddSchemas(projectSchema.Schemas) + + return context, err +} + +func (w *UserOnlyContext) Start(ctx context.Context) error { + logrus.Info("Starting workload controllers") + return w.ControllerFactory.Start(ctx, 5) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/dialer/dialer.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/dialer/dialer.go new file mode 100644 index 0000000..9fbb179 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/dialer/dialer.go @@ -0,0 +1,18 @@ +package dialer + +import ( + "context" + "net" +) + +type Dialer func(ctx context.Context, network, address string) (net.Conn, error) + +type Factory interface { + // ClusterDialer returns a dialer that can be used to connect to a cluster's Kubernetes API + // Note that the dialer may or may not use a remotedialer tunnel + // If retryOnError is true, the dialer will retry for ~30s in case it cannot connect, + // otherwise return immediately + ClusterDialer(clusterName string, retryOnError bool) (Dialer, error) + DockerDialer(clusterName, machineName string) (Dialer, error) + NodeDialer(clusterName, machineName string) (Dialer, error) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/systemtokens/systemtokens.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/systemtokens/systemtokens.go new file mode 100644 index 0000000..e6038b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/types/config/systemtokens/systemtokens.go @@ -0,0 +1,6 @@ +package systemtokens + +type Interface interface { + EnsureSystemToken(name, description, kind, username string, overrideTTL *int64, randomize bool) (string, error) + DeleteToken(tokenName string) error +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/authredirect.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/authredirect.go new file mode 100644 index 0000000..0a8151f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/authredirect.go @@ -0,0 +1,40 @@ +package ui + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "net/url" + + "github.com/gorilla/mux" +) + +var ( + authToTarget = map[string]string{ + "vue": "/dashboard/auth/verify", + "ember": "/verify", + } +) + +func redirectAuth(rw http.ResponseWriter, req *http.Request) { + vars := mux.Vars(req) + bytes, err := base64.RawURLEncoding.DecodeString(vars["state"]) + if err != nil { + emberIndexUnlessAPI().ServeHTTP(rw, req) + return + } + + input := struct { + To string `json:"to,omitempty"` + }{} + if err := json.Unmarshal(bytes, &input); err != nil || authToTarget[input.To] == "" { + emberIndexUnlessAPI().ServeHTTP(rw, req) + return + } + + u := url.URL{ + Path: authToTarget[input.To], + RawQuery: req.URL.RawQuery, + } + http.Redirect(rw, req, u.String(), http.StatusFound) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/handler.go new file mode 100644 index 0000000..f1de02a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/handler.go @@ -0,0 +1,44 @@ +package ui + +import ( + "crypto/tls" + "net/http" + + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/steve/pkg/ui" +) + +var ( + insecureClient = &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } + + ember = newHandler(settings.UIIndex.Get, + settings.UIPath.Get, + settings.UIOfflinePreferred.Get) + emberAlwaysOffline = newHandler(settings.UIIndex.Get, + settings.UIPath.Get, + func() string { return "true" }) + vue = newHandler(settings.UIDashboardIndex.Get, + settings.UIDashboardPath.Get, + settings.UIOfflinePreferred.Get) + emberIndex = ember.IndexFile() + vueIndex = vue.IndexFile() +) + +func newHandler( + indexSetting func() string, + pathSetting func() string, + offlineSetting func() string) *ui.Handler { + return ui.NewUIHandler(&ui.Options{ + Index: indexSetting, + Offline: offlineSetting, + Path: pathSetting, + ReleaseSetting: settings.IsRelease, + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/routes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/routes.go new file mode 100644 index 0000000..8b0a980 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/ui/routes.go @@ -0,0 +1,57 @@ +package ui + +import ( + "net/http" + + "github.com/gorilla/mux" + "github.com/rancher/apiserver/pkg/parse" + "github.com/rancher/rancher/pkg/cacerts" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" +) + +func New(_ v3.PreferenceCache, clusterRegistrationTokenCache v3.ClusterRegistrationTokenCache) http.Handler { + router := mux.NewRouter() + router.UseEncodedPath() + + router.Handle("/", PreferredIndex()) + router.Handle("/cacerts", cacerts.Handler(clusterRegistrationTokenCache)) + router.Handle("/asset-manifest.json", ember.ServeAsset()) + router.Handle("/crossdomain.xml", ember.ServeAsset()) + router.Handle("/dashboard", http.RedirectHandler("/dashboard/", http.StatusFound)) + router.Handle("/dashboard/", vue.IndexFile()) + router.Handle("/humans.txt", ember.ServeAsset()) + router.Handle("/index.txt", ember.ServeAsset()) + router.Handle("/robots.txt", ember.ServeAsset()) + router.Handle("/VERSION.txt", ember.ServeAsset()) + router.Handle("/favicon.png", vue.ServeFaviconDashboard()) + router.Handle("/favicon.ico", vue.ServeFaviconDashboard()) + router.Path("/verify-auth-azure").Queries("state", "{state}").HandlerFunc(redirectAuth) + router.Path("/verify-auth").Queries("state", "{state}").HandlerFunc(redirectAuth) + router.PathPrefix("/api-ui").Handler(ember.ServeAsset()) + router.PathPrefix("/assets/rancher-ui-driver-linode").Handler(emberAlwaysOffline.ServeAsset()) + router.PathPrefix("/assets").Handler(ember.ServeAsset()) + router.PathPrefix("/dashboard/").Handler(vue.IndexFileOnNotFound()) + router.PathPrefix("/ember-fetch").Handler(ember.ServeAsset()) + router.PathPrefix("/engines-dist").Handler(ember.ServeAsset()) + router.PathPrefix("/static").Handler(ember.ServeAsset()) + router.PathPrefix("/translations").Handler(ember.ServeAsset()) + router.NotFoundHandler = emberIndexUnlessAPI() + + return router +} + +func emberIndexUnlessAPI() http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if parse.IsBrowser(req, true) { + emberIndex.ServeHTTP(rw, req) + } else { + http.NotFound(rw, req) + } + }) +} + +func PreferredIndex() http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + http.Redirect(rw, req, "/dashboard/", http.StatusFound) + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/user/manager.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/user/manager.go new file mode 100644 index 0000000..54aa500 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/user/manager.go @@ -0,0 +1,32 @@ +package user + +import ( + "github.com/rancher/norman/types" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + apitypes "k8s.io/apimachinery/pkg/types" +) + +type TokenInput struct { + TokenName string + Description string + Kind string + UserName string + AuthProvider string + TTL *int64 + Randomize bool + UserPrincipal v3.Principal +} + +type Manager interface { + SetPrincipalOnCurrentUser(apiContext *types.APIContext, principal v3.Principal) (*v3.User, error) + GetUser(apiContext *types.APIContext) string + EnsureToken(input TokenInput) (string, error) + EnsureClusterToken(clusterName string, input TokenInput) (string, error) + DeleteToken(tokenName string) error + EnsureUser(principalName, displayName string) (*v3.User, error) + CheckAccess(accessMode string, allowedPrincipalIDs []string, userPrincipalID string, groups []v3.Principal) (bool, error) + SetPrincipalOnCurrentUserByUserID(userID string, principal v3.Principal) (*v3.User, error) + CreateNewUserClusterRoleBinding(userName string, userUID apitypes.UID) error + GetUserByPrincipalID(principalName string) (*v3.User, error) + GetKubeconfigToken(clusterName, tokenName, description, kind, userName string, userPrincipal v3.Principal) (*v3.Token, string, error) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/utils/utils.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/utils/utils.go new file mode 100644 index 0000000..ff919fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/utils/utils.go @@ -0,0 +1,19 @@ +package utils + +import ( + "fmt" + "sort" + "strings" + + v1 "k8s.io/api/core/v1" +) + +func FormatResourceList(resources v1.ResourceList) string { + resourceStrings := make([]string, 0, len(resources)) + for key, value := range resources { + resourceStrings = append(resourceStrings, fmt.Sprintf("%v=%v", key, value.String())) + } + // sort the results for consistent log output + sort.Strings(resourceStrings) + return strings.Join(resourceStrings, ",") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version.go new file mode 100644 index 0000000..63adfa5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version.go @@ -0,0 +1,54 @@ +// Package version gathers version data from variables set at build time and runtime +// and provides access points to retrieve them. +package version + +import ( + "encoding/json" + "fmt" + "net/http" + "os" +) + +var ( + Version = "dev" + GitCommit = "HEAD" +) + +const primeEnv = "RANCHER_PRIME" + +// Info encapsulates version metadata. +type Info struct { + Version string + GitCommit string + RancherPrime string +} + +// FriendlyVersion returns a human-readable string that can be included in log output. +func FriendlyVersion() string { + return fmt.Sprintf("%s (%s)", Version, GitCommit) +} + +type versionHandler struct { + info Info +} + +// NewVersionHandler checks the runtime environment for the RANCHER_PRIME environment variable +// and uses that along with build-time version information to create an HTTP handler. +func NewVersionHandler() http.Handler { + var rancherPrime = "false" + if isPrime, ok := os.LookupEnv(primeEnv); ok && isPrime == "true" { + rancherPrime = "true" + } + return &versionHandler{info: Info{Version, GitCommit, rancherPrime}} +} + +// ServeHTTP handles GET requests for version information. +func (h *versionHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + body, err := json.Marshal(h.info) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + return + } + rw.Write(body) + rw.WriteHeader(http.StatusOK) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version_test.go new file mode 100644 index 0000000..0e5eef5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/version/version_test.go @@ -0,0 +1,55 @@ +package version + +import ( + "io" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestVersionServeHTTP(t *testing.T) { + tests := []struct { + name string + setPrime func() + cleanup func() + want string + }{ + { + name: "unmodified", + setPrime: func() {}, + cleanup: func() {}, + want: `{"Version":"dev","GitCommit":"HEAD","RancherPrime":"false"}`, + }, + { + name: "prime=true", + setPrime: func() { os.Setenv("RANCHER_PRIME", "true") }, + cleanup: func() { os.Unsetenv("RANCHER_PRIME") }, + want: `{"Version":"dev","GitCommit":"HEAD","RancherPrime":"true"}`, + }, + { + name: "prime=false", + setPrime: func() { os.Setenv("RANCHER_PRIME", "false") }, + cleanup: func() { os.Unsetenv("RANCHER_PRIME") }, + want: `{"Version":"dev","GitCommit":"HEAD","RancherPrime":"false"}`, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.setPrime() + defer tt.cleanup() + req := httptest.NewRequest(http.MethodGet, "/rancherversion", nil) + rr := httptest.NewRecorder() + handler := NewVersionHandler() + handler.ServeHTTP(rr, req) + assert.Equal(t, http.StatusOK, rr.Code) + resp := rr.Result() + body, err := io.ReadAll(resp.Body) + assert.Nil(t, err) + assert.Equal(t, tt.want, string(body)) + }) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler.go new file mode 100644 index 0000000..160a16d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler.go @@ -0,0 +1,113 @@ +package websocket + +import ( + "encoding/json" + "net/http" + "net/url" + "strings" + + "github.com/rancher/norman/httperror" +) + +const ( + originHeader = "Origin" + connectionHeader = "Connection" + userAgentHeader = "User-Agent" +) + +func NewWebsocketHandler(handler http.Handler) http.Handler { + return &websocketHandler{ + handler, + } +} + +type websocketHandler struct { + next http.Handler +} + +func (h websocketHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + if isWebsocket(req) && isBrowserUserAgent(req.Header) { + if !checkSameOrigin(req) { + response(rw, httperror.PermissionDenied, "origin not allowed") + return + } + } + h.next.ServeHTTP(rw, req) +} + +// Inspired by https://github.com/gorilla/websocket/blob/80c2d40e9b91f2ef7a9c1a403aeec64d1b89a9a6/server.go#L87 +// checkSameOrigin returns true if the origin is not set or is equal to the request host. +func checkSameOrigin(r *http.Request) bool { + origins := r.Header[originHeader] + + if len(origins) == 0 { + return true + } + + for _, origin := range r.Header[originHeader] { + u, err := url.Parse(origin) + if err != nil { + continue + } + + if u.Port() == "" { + if u.Host == r.Host { + return true + } + } else if u.Host == r.Host && u.Port() == portOnly(r.Host) { + return true + } + } + return false +} + +// isWebsocket returns true if the request is a websocket +func isWebsocket(r *http.Request) bool { + if !headerListContainsValue(r.Header, connectionHeader, "upgrade") { + return false + } + return true +} + +// headerListContainsValue returns true if the token header with the given name contains token. +func headerListContainsValue(header http.Header, name string, value string) bool { + for _, v := range header[name] { + for _, s := range strings.Split(v, ",") { + if strings.EqualFold(value, strings.TrimSpace(s)) { + return true + } + } + } + return false +} + +// isBrowserUserAgent returns true if User-Agent is assumed to be a browser (UA header contains "mozilla"). +func isBrowserUserAgent(header http.Header) bool { + for _, v := range header[userAgentHeader] { + if strings.Contains(strings.ToLower(v), "mozilla") { + return true + } + } + return false +} + +func response(rw http.ResponseWriter, code httperror.ErrorCode, message string) { + rw.WriteHeader(code.Status) + rw.Header().Set("content-type", "application/json") + json.NewEncoder(rw).Encode(httperror.NewAPIError(code, message)) +} + +// portOnly returns the port part of localhost:port, without the leading colon +func portOnly(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return "" + } + if i := strings.Index(hostport, "]:"); i != -1 { + return hostport[i+len("]:"):] + } + if strings.Contains(hostport, "]") { + return "" + } + return hostport[colon+len(":"):] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler_test.go new file mode 100644 index 0000000..7b36290 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/websocket/handler_test.go @@ -0,0 +1,88 @@ +package websocket + +import ( + "fmt" + "net/http" + "strconv" + "testing" + + "github.com/stretchr/testify/assert" +) + +type testResponseWriter struct { + header http.Header +} + +type testHandler struct { +} + +func serveHTTPWithHeader(port string, origins []string, connections []string, uas []string) int { + testRW := newTestResponseWriter() + testReq := newTestRequest(port, origins, connections, uas) + testWSHandler := NewWebsocketHandler(&testHandler{}) + testWSHandler.ServeHTTP(testRW, testReq) + + if statusCode := testRW.header["code"]; len(statusCode) == 0 { + return -1 + } + + code, err := strconv.Atoi(testRW.header["code"][0]) + if err != nil { + return -1 + } + + return code +} + +func newTestResponseWriter() *testResponseWriter { + return &testResponseWriter{ + header: http.Header(make(map[string][]string)), + } +} + +func newTestRequest(port string, origins []string, connections []string, uas []string) *http.Request { + return &http.Request{ + Header: http.Header( + map[string][]string{ + "Origin": origins, + "Connection": connections, + "User-Agent": uas, + }, + ), + Host: fmt.Sprintf("rancher%s", port), + } +} + +// TestServeHTTP tests the websocket handler using various values for relevant header fields +func TestServeHTTP(t *testing.T) { + assert := assert.New(t) + + // if origin is a websocket request and contains "mozilla" then the origin request origin header must match the request host + assert.Equal(403, serveHTTPWithHeader("", []string{"asdf"}, []string{"upgrade"}, []string{"dsafmozillaasdf"})) + assert.Equal(403, serveHTTPWithHeader("", []string{"asdf"}, []string{"upgrade"}, []string{"mozilla"})) + assert.Equal(403, serveHTTPWithHeader(":3000", []string{"https://rancher"}, []string{"upgrade"}, []string{"dsafmozillaasdf"})) + assert.Equal(403, serveHTTPWithHeader("", []string{"https://rancher:3000"}, []string{"upgrade"}, []string{"dsafmozillaasdf"})) + assert.Equal(403, serveHTTPWithHeader("", []string{""}, []string{"upgrade"}, []string{"dsafmozillaasdf"})) + assert.Equal(200, serveHTTPWithHeader(":3000", []string{"https://rancher:3000"}, []string{"upgrade"}, []string{"asdf"})) + assert.Equal(200, serveHTTPWithHeader(":3000", []string{"https://rancher:3000"}, []string{}, []string{"mozilla"})) + assert.Equal(200, serveHTTPWithHeader("", []string{"asdf"}, []string{"upgrade"}, []string{"somthingelse"})) + assert.Equal(200, serveHTTPWithHeader("", []string{"https://rancher"}, []string{"upgrade"}, []string{"mozilla"})) + assert.Equal(200, serveHTTPWithHeader(":3000", []string{"https://rancher:3000"}, []string{"upgrade"}, []string{"mozilla"})) + assert.Equal(200, serveHTTPWithHeader(":3000", []string{"https://rancher:3000"}, []string{"upgrade"}, []string{"dsafmozillaasdf"})) +} + +func (trw *testResponseWriter) Header() http.Header { + return trw.header +} + +func (trw *testResponseWriter) Write([]byte) (int, error) { + return 0, nil +} + +func (trw *testResponseWriter) WriteHeader(statusCode int) { + trw.header["code"] = []string{strconv.Itoa(statusCode)} +} + +func (th *testHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + rw.WriteHeader(200) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/wrangler/context.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/wrangler/context.go new file mode 100644 index 0000000..c25cb5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/pkg/wrangler/context.go @@ -0,0 +1,514 @@ +/* +Package wrangler contains functions for creating a management context with wrangler controllers. +*/ +package wrangler + +import ( + "context" + "fmt" + "net" + "net/http" + "sync" + + fleetv1alpha1api "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/lasso/pkg/dynamic" + "github.com/rancher/norman/types" + catalogv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + clusterv3api "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3" + managementv3api "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + projectv3api "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3" + provisioningv1api "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1api "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/content" + helmcfg "github.com/rancher/rancher/pkg/catalogv2/helm" + "github.com/rancher/rancher/pkg/catalogv2/helmop" + "github.com/rancher/rancher/pkg/catalogv2/system" + "github.com/rancher/rancher/pkg/controllers" + "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io" + catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1" + capi "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io" + capicontrollers "github.com/rancher/rancher/pkg/generated/controllers/cluster.x-k8s.io/v1beta1" + "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io" + fleetv1alpha1 "github.com/rancher/rancher/pkg/generated/controllers/fleet.cattle.io/v1alpha1" + "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io" + managementv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/controllers/project.cattle.io" + projectv3 "github.com/rancher/rancher/pkg/generated/controllers/project.cattle.io/v3" + "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io" + provisioningv1 "github.com/rancher/rancher/pkg/generated/controllers/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io" + rkecontrollers "github.com/rancher/rancher/pkg/generated/controllers/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/peermanager" + "github.com/rancher/rancher/pkg/settings" + "github.com/rancher/rancher/pkg/tunnelserver" + "github.com/rancher/remotedialer" + "github.com/rancher/steve/pkg/accesscontrol" + "github.com/rancher/steve/pkg/client" + "github.com/rancher/wrangler/v3/pkg/apply" + admissionreg "github.com/rancher/wrangler/v3/pkg/generated/controllers/admissionregistration.k8s.io" + admissionregcontrollers "github.com/rancher/wrangler/v3/pkg/generated/controllers/admissionregistration.k8s.io/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io" + crdv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiregistration.k8s.io" + apiregv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiregistration.k8s.io/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps" + appsv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apps/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/batch" + batchv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/batch/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" + corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac" + rbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" + "github.com/rancher/wrangler/v3/pkg/generic" + "github.com/rancher/wrangler/v3/pkg/leader" + "github.com/rancher/wrangler/v3/pkg/schemes" + "github.com/sirupsen/logrus" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/discovery" + "k8s.io/client-go/discovery/cached/memory" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" + "k8s.io/client-go/tools/clientcmd" + apiregistrationv12 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" + capiv1beta1api "sigs.k8s.io/cluster-api/api/v1beta1" +) + +var ( + localSchemeBuilder = runtime.SchemeBuilder{ + provisioningv1api.AddToScheme, + capiv1beta1api.AddToScheme, + fleetv1alpha1api.AddToScheme, + managementv3api.AddToScheme, + projectv3api.AddToScheme, + clusterv3api.AddToScheme, + rkev1api.AddToScheme, + scheme.AddToScheme, + apiextensionsv1.AddToScheme, + apiregistrationv12.AddToScheme, + catalogv1.AddToScheme, + } + AddToScheme = localSchemeBuilder.AddToScheme + Scheme = runtime.NewScheme() +) + +func init() { + metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) + utilruntime.Must(schemes.AddToScheme(Scheme)) +} + +type Context struct { + RESTConfig *rest.Config + + Apply apply.Apply + Dynamic *dynamic.Controller + CAPI capicontrollers.Interface + RKE rkecontrollers.Interface + Mgmt managementv3.Interface + Apps appsv1.Interface + Admission admissionregcontrollers.Interface + Batch batchv1.Interface + Fleet fleetv1alpha1.Interface + Project projectv3.Interface + Catalog catalogcontrollers.Interface + ControllerFactory controller.SharedControllerFactory + MultiClusterManager MultiClusterManager + TunnelServer *remotedialer.Server + TunnelAuthorizer *tunnelserver.Authorizers + PeerManager peermanager.PeerManager + Provisioning provisioningv1.Interface + RBAC rbacv1.Interface + Core corev1.Interface + API apiregv1.Interface + CRD crdv1.Interface + K8s *kubernetes.Clientset + + ASL accesscontrol.AccessSetLookup + ClientConfig clientcmd.ClientConfig + CachedDiscovery discovery.CachedDiscoveryInterface + RESTMapper meta.RESTMapper + SharedControllerFactory controller.SharedControllerFactory + leadership *leader.Manager + controllerLock *sync.Mutex + + RESTClientGetter genericclioptions.RESTClientGetter + CatalogContentManager *content.Manager + HelmOperations *helmop.Operations + SystemChartsManager *system.Manager + + mgmt *management.Factory + rbac *rbac.Factory + project *project.Factory + ctlg *catalog.Factory + adminReg *admissionreg.Factory + apps *apps.Factory + capi *capi.Factory + rke *rke.Factory + fleet *fleet.Factory + provisioning *provisioning.Factory + batch *batch.Factory + core *core.Factory + api *apiregistration.Factory + crd *apiextensions.Factory + + started bool +} + +type MultiClusterManager interface { + NormanSchemas() *types.Schemas + ClusterDialer(clusterID string) func(ctx context.Context, network, address string) (net.Conn, error) + Start(ctx context.Context) error + Wait(ctx context.Context) + Middleware(next http.Handler) http.Handler + K8sClient(clusterName string) (kubernetes.Interface, error) +} + +func (w *Context) OnLeader(f func(ctx context.Context) error) { + w.leadership.OnLeader(f) +} + +func (w *Context) StartWithTransaction(ctx context.Context, f func(context.Context) error) (err error) { + transaction := controller.NewHandlerTransaction(ctx) + if err := f(transaction); err != nil { + transaction.Rollback() + return err + } + + if err := w.ControllerFactory.SharedCacheFactory().Start(ctx); err != nil { + transaction.Rollback() + return err + } + + w.ControllerFactory.SharedCacheFactory().WaitForCacheSync(ctx) + transaction.Commit() + return w.Start(ctx) +} + +func (w *Context) Start(ctx context.Context) error { + w.controllerLock.Lock() + defer w.controllerLock.Unlock() + + if !w.started { + if err := w.Dynamic.Register(ctx, w.SharedControllerFactory); err != nil { + return err + } + w.SystemChartsManager.Start(ctx) + w.started = true + } + + if err := w.ControllerFactory.Start(ctx, 50); err != nil { + return err + } + w.leadership.Start(ctx) + return nil +} + +// WithAgent returns a shallow copy of the Context that has been configured to use a user agent in its +// clients that is the given userAgent appended to "rancher-%s-%s". +func (w *Context) WithAgent(userAgent string) *Context { + userAgent = fmt.Sprintf("rancher-%s-%s", settings.ServerVersion.Get(), userAgent) + wContextCopy := *w + restConfigCopy := &rest.Config{} + if w.RESTConfig != nil { + *restConfigCopy = *w.RESTConfig + restConfigCopy.UserAgent = userAgent + } + k8sClientWithAgent, err := kubernetes.NewForConfig(restConfigCopy) + if err != nil { + logrus.Debugf("failed to set agent [%s] on k8s client: %v", userAgent, err) + } + if err == nil { + wContextCopy.K8s = k8sClientWithAgent + } + applyWithAgent, err := apply.NewForConfig(restConfigCopy) + if err != nil { + logrus.Debugf("failed to set agent [%s] on apply client: %v", userAgent, err) + } + if err == nil { + wContextCopy.Apply = applyWithAgent + } + wContextCopy.Dynamic = dynamic.New(wContextCopy.K8s.Discovery()) + wContextCopy.CAPI = wContextCopy.capi.WithAgent(userAgent).V1beta1() + wContextCopy.RKE = wContextCopy.rke.WithAgent(userAgent).V1() + wContextCopy.Mgmt = wContextCopy.mgmt.WithAgent(userAgent).V3() + wContextCopy.Apps = wContextCopy.apps.WithAgent(userAgent).V1() + wContextCopy.Admission = wContextCopy.adminReg.WithAgent(userAgent).V1() + wContextCopy.Batch = wContextCopy.batch.WithAgent(userAgent).V1() + wContextCopy.Fleet = wContextCopy.fleet.WithAgent(userAgent).V1alpha1() + wContextCopy.Project = wContextCopy.project.WithAgent(userAgent).V3() + wContextCopy.Catalog = wContextCopy.ctlg.WithAgent(userAgent).V1() + wContextCopy.Provisioning = wContextCopy.provisioning.WithAgent(userAgent).V1() + wContextCopy.RBAC = wContextCopy.rbac.WithAgent(userAgent).V1() + wContextCopy.Core = wContextCopy.core.WithAgent(userAgent).V1() + wContextCopy.API = wContextCopy.api.WithAgent(userAgent).V1() + wContextCopy.CRD = wContextCopy.crd.WithAgent(userAgent).V1() + + return &wContextCopy +} + +func enableProtobuf(cfg *rest.Config) *rest.Config { + cpy := rest.CopyConfig(cfg) + cpy.AcceptContentTypes = "application/vnd.kubernetes.protobuf, application/json" + cpy.ContentType = "application/json" + return cpy +} + +func NewContext(ctx context.Context, clientConfig clientcmd.ClientConfig, restConfig *rest.Config) (*Context, error) { + sharedOpts := controllers.GetOptsFromEnv(controllers.Management) + controllerFactory, err := controller.NewSharedControllerFactoryFromConfigWithOptions(enableProtobuf(restConfig), Scheme, sharedOpts) + if err != nil { + return nil, err + } + + opts := &generic.FactoryOptions{ + SharedControllerFactory: controllerFactory, + } + + apply, err := apply.NewForConfig(restConfig) + if err != nil { + return nil, err + } + + mgmt, err := management.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + ctlg, err := catalog.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + apps, err := apps.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + rbac, err := rbac.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + adminReg, err := admissionreg.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + project, err := project.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + capi, err := capi.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + rke, err := rke.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + fleet, err := fleet.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + provisioning, err := provisioning.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + helm, err := catalog.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + batch, err := batch.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + core, err := core.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + api, err := apiregistration.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + crd, err := apiextensions.NewFactoryFromConfigWithOptions(restConfig, opts) + if err != nil { + return nil, err + } + + k8s, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return nil, err + } + + asl := accesscontrol.NewAccessStore(ctx, true, rbac.Rbac().V1()) + + cg, err := client.NewFactory(restConfig, false) + if err != nil { + return nil, err + } + + content := content.NewManager( + k8s.Discovery(), + core.Core().V1().ConfigMap().Cache(), + core.Core().V1().Secret().Cache(), + helm.Catalog().V1().ClusterRepo().Cache()) + + helmop := helmop.NewOperations(cg, + helm.Catalog().V1(), + rbac.Rbac().V1(), + content, + core.Core().V1().Pod()) + + cache := memory.NewMemCacheClient(k8s.Discovery()) + restMapper := restmapper.NewDeferredDiscoveryRESTMapper(cache) + restClientGetter := &SimpleRESTClientGetter{ + ClientConfig: clientConfig, + RESTConfig: restConfig, + CachedDiscovery: cache, + RESTMapper: restMapper, + } + helmClient := helmcfg.NewClient(restClientGetter) + + systemCharts, err := system.NewManager(ctx, content, helmop, core.Core().V1().Pod(), + mgmt.Management().V3().Setting(), ctlg.Catalog().V1().ClusterRepo(), helmClient) + if err != nil { + return nil, err + } + + tunnelAuth := &tunnelserver.Authorizers{} + tunnelServer := remotedialer.New(tunnelAuth.Authorize, tunnelserver.ErrorWriter) + peerManager, err := tunnelserver.NewPeerManager(ctx, core.Core().V1().Endpoints(), tunnelServer) + if err != nil { + return nil, err + } + + leadership := leader.NewManager("", "cattle-controllers", k8s) + leadership.OnLeader(func(ctx context.Context) error { + if peerManager != nil { + peerManager.Leader() + } + return nil + }) + wContext := &Context{ + RESTConfig: restConfig, + Apply: apply, + SharedControllerFactory: controllerFactory, + Dynamic: dynamic.New(k8s.Discovery()), + CAPI: capi.Cluster().V1beta1(), + RKE: rke.Rke().V1(), + Mgmt: mgmt.Management().V3(), + Apps: apps.Apps().V1(), + Admission: adminReg.Admissionregistration().V1(), + Project: project.Project().V3(), + Fleet: fleet.Fleet().V1alpha1(), + Provisioning: provisioning.Provisioning().V1(), + Catalog: helm.Catalog().V1(), + Batch: batch.Batch().V1(), + RBAC: rbac.Rbac().V1(), + Core: core.Core().V1(), + API: api.Apiregistration().V1(), + CRD: crd.Apiextensions().V1(), + K8s: k8s, + ControllerFactory: controllerFactory, + ASL: asl, + ClientConfig: clientConfig, + MultiClusterManager: noopMCM{}, + CachedDiscovery: cache, + RESTMapper: restMapper, + leadership: leadership, + controllerLock: &sync.Mutex{}, + PeerManager: peerManager, + RESTClientGetter: restClientGetter, + CatalogContentManager: content, + HelmOperations: helmop, + SystemChartsManager: systemCharts, + TunnelAuthorizer: tunnelAuth, + TunnelServer: tunnelServer, + + mgmt: mgmt, + apps: apps, + adminReg: adminReg, + project: project, + fleet: fleet, + provisioning: provisioning, + ctlg: helm, + batch: batch, + core: core, + api: api, + crd: crd, + capi: capi, + rke: rke, + rbac: rbac, + } + + return wContext, nil +} + +type noopMCM struct { +} + +func (n noopMCM) NormanSchemas() *types.Schemas { + return nil +} + +func (n noopMCM) ClusterDialer(clusterID string) func(ctx context.Context, network string, address string) (net.Conn, error) { + return func(ctx context.Context, network string, address string) (net.Conn, error) { + return nil, fmt.Errorf("no cluster manager") + } +} + +func (n noopMCM) Wait(ctx context.Context) { +} + +func (n noopMCM) Start(ctx context.Context) error { + return nil +} + +func (n noopMCM) Middleware(next http.Handler) http.Handler { + return next +} + +func (n noopMCM) K8sClient(clusterName string) (kubernetes.Interface, error) { + return nil, nil +} + +type SimpleRESTClientGetter struct { + ClientConfig clientcmd.ClientConfig + RESTConfig *rest.Config + CachedDiscovery discovery.CachedDiscoveryInterface + RESTMapper meta.RESTMapper +} + +func (s *SimpleRESTClientGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig { + return s.ClientConfig +} + +func (s *SimpleRESTClientGetter) ToRESTConfig() (*rest.Config, error) { + return s.RESTConfig, nil +} + +func (s *SimpleRESTClientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { + return s.CachedDiscovery, nil +} + +func (s *SimpleRESTClientGetter) ToRESTMapper() (meta.RESTMapper, error) { + return s.RESTMapper, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/artifacts-hashes.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/artifacts-hashes.sh new file mode 100755 index 0000000..72e3144 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/artifacts-hashes.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +cd $(dirname $0)/.. + +dist_folder="./dist" + +for filename in $dist_folder/*; do + sum_file=$(sha256sum $filename) + sum=$(echo $sum_file | awk '{print $1}') + file_path=$(echo $sum_file | awk '{print $2}') + file=${file_path#"$dist_folder/"} + echo "$sum $file" >> ./dist/sha256sum.txt +done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/boilerplate.go.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/boilerplate.go.txt new file mode 100755 index 0000000..115ad20 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/boilerplate.go.txt @@ -0,0 +1,16 @@ +/* +Copyright YEAR Rancher Labs, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build new file mode 100755 index 0000000..71b9fee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +echo Running: build-server +$(dirname $0)/build-server +echo Running: build-agent +$(dirname $0)/build-agent diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-agent b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-agent new file mode 100755 index 0000000..2a632ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-agent @@ -0,0 +1,21 @@ +#!/bin/bash +set -e + +source $(dirname $0)/version + +cd $(dirname $0)/.. + +mkdir -p bin + +if [ -n "${DEBUG}" ]; then + GCFLAGS="-N -l" +fi + +if [ "$(uname)" != "Darwin" ]; then + LINKFLAGS="-extldflags -static" + if [ -z "${DEBUG}" ]; then + LINKFLAGS="${LINKFLAGS} -s" + fi +fi + +CGO_ENABLED=0 go build -tags k8s -gcflags="all=${GCFLAGS}" -ldflags "-X main.VERSION=$VERSION $LINKFLAGS" -o bin/agent ./cmd/agent diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-crds b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-crds new file mode 100755 index 0000000..511d737 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-crds @@ -0,0 +1,10 @@ +#! /bin/sh + +cd $(dirname $0)/../ + +# This will return non-zero until all of our objects in ./pkg/apis can generate valid crds. +# allowDangerousTypes is needed for struct that use floats +controller-gen crd:generateEmbeddedObjectMeta=true,allowDangerousTypes=false paths=./pkg/apis/... output:crd:dir=./pkg/crds/yaml/generated + +# remove empty CRD that is generated from our use of // +kubebuilder:skipversion +rm -f ./pkg/crds/yaml/generated/_.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-server b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-server new file mode 100755 index 0000000..d8e4b76 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/build-server @@ -0,0 +1,39 @@ +#!/bin/bash +set -ex + +source $(dirname $0)/version +source $(dirname $0)/export-config + +cd $(dirname $0)/.. + +mkdir -p bin + +if [ -n "${DEBUG}" ]; then + GCFLAGS="-N -l" +fi + +if [ "$(uname)" != "Darwin" ]; then + LINKFLAGS="-extldflags -static" + if [ -z "${DEBUG}" ]; then + LINKFLAGS="${LINKFLAGS} -s" + fi +fi + +RKE_VERSION="$(grep -m1 'github.com/rancher/rke' go.mod | awk '{print $2}')" + +# Inject Setting values +DEFAULT_VALUES="{\"rke-version\":\"${RKE_VERSION}\"}" + +CGO_ENABLED=0 go build -tags k8s \ + -gcflags="all=${GCFLAGS}" \ + -ldflags \ + "-X github.com/rancher/rancher/pkg/version.Version=$VERSION + -X github.com/rancher/rancher/pkg/version.GitCommit=$COMMIT + -X github.com/rancher/rancher/pkg/settings.InjectDefaults=$DEFAULT_VALUES $LINKFLAGS" \ + -o bin/rancher + +if [ -n "$CATTLE_KDM_BRANCH" ]; then + curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${CATTLE_KDM_BRANCH}/data.json > bin/data.json +elif [ ! -e bin/data.json ] && [ -e ../kontainer-driver-metadata/data/data.json ]; then + cp ../kontainer-driver-metadata/data/data.json bin/data.json +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/build b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/build new file mode 100755 index 0000000..91eecef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/build @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -e -x + +echo "-- chart/build --" + +cd $(dirname $0)/.. +. ./version +. ./export-config + +cd .. +mkdir -p build/chart +rm -rf build/chart/rancher +cp -rf ${1} build/chart/rancher + +sed -i -e "s/%VERSION%/${CHART_VERSION}/g" build/chart/rancher/Chart.yaml +sed -i -e "s/%APP_VERSION%/${APP_VERSION}/g" build/chart/rancher/Chart.yaml + +post_delete_base=$CATTLE_DEFAULT_SHELL_VERSION +post_delete_image_name=$(echo "${post_delete_base}" | cut -d ":" -f 1) || "" +post_delete_image_tag=$(echo "${post_delete_base}" | cut -d ":" -f 2) || "" +if [[ ! ${post_delete_image_name} =~ ^rancher\/.+ ]]; then + echo "The image name [$post_delete_image_name] is invalid. Its prefix should be rancher/" + exit 1 +fi +if [[ ! ${post_delete_image_tag} =~ ^v.+ ]]; then + echo "The image tag [$post_delete_image_tag] is invalid. It should start with the letter v" + exit 1 +fi +sed -i -e "s@%POST_DELETE_IMAGE_NAME%@${post_delete_image_name}@g" build/chart/rancher/values.yaml +sed -i -e "s/%POST_DELETE_IMAGE_TAG%/${post_delete_image_tag}/g" build/chart/rancher/values.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/ci b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/ci new file mode 100755 index 0000000..57965ae --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/ci @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +cd $(dirname $0) + +./build chart +./validate +./test +./package diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/copy b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/copy new file mode 100755 index 0000000..6da04cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/copy @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -e + +echo "-- chart/copy --" + +cd $(dirname $0)/.. +. ./version + +# A Promotion is from Latest to Stable. +if [[ -z "${DRONE_TAG}" ]]; then + echo "We can only promote Tags from the 'latest' chart repo to 'stable'" + exit 1 +fi + +if [[ "${CHART_REPO}" != "latest" ]]; then + echo "We can only promote Tags from the 'latest' chart repo to 'stable'" + exit 1 +fi + +# Remove any existing charts. +rm -rf ../bin/chart + +mkdir -p ../bin/chart/stable + +curl -f -H 'Cache-Control: max-age=0,no-cache' -H 'Host: releases.rancher.com' "https://c.storage.googleapis.com/server-charts/latest/rancher-${CHART_VERSION}.tgz?$(date +%s%N)" -o ../bin/chart/stable/rancher-${CHART_VERSION}.tgz + +./chart/index stable diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/index b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/index new file mode 100755 index 0000000..87889f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/index @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -e + +echo "-- chart/index --" + +cd $(dirname $0)/../.. +mkdir -p build + +repo_index=${1} + +echo "Getting current index from ${repo_index}" +curl -f -H 'Cache-Control: max-age=0,no-cache' -H 'Host: releases.rancher.com' "https://c.storage.googleapis.com/server-charts/${repo_index}/index.yaml?$(date +%s%N)" -o build/index.yaml + +helm_v3 repo index --merge build/index.yaml ./bin/chart/${repo_index} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/package b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/package new file mode 100755 index 0000000..e4170a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/package @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e + +echo "-- chart/package --" + +cd $(dirname $0)/.. +. ./version + +mkdir -p ../bin/chart/${CHART_REPO} + +helm_v3 package -d ../bin/chart/${CHART_REPO} ../build/chart/rancher + +if [[ "${CHART_REPO}" == "dev" ]]; then + echo "dev repo - skipping index" +else + echo "updating index ... " + ./chart/index ${CHART_REPO} +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/promote-to-stable.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/promote-to-stable.sh new file mode 100755 index 0000000..5a358b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/promote-to-stable.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +drone_cli_help() +{ + echo " Requires Drone CLI and personal access token" + echo " Download CLI following instructions at https://docs.drone.io/cli/install/" + echo " Then configure access token: https://docs.drone.io/cli/setup/" + echo "" + echo " To test if Drone CLI is properly configured type:" + echo "" + echo " drone build ls rancher/rancher" + echo "" + echo " This will show the last 25 builds" +} + +if [[ -z "${1}" ]]; then + echo "Promote a chart in latest to stable." + echo " $0 " + echo "" + drone_cli_help + exit 1 +fi + +if ! drone -v; then + drone_cli_help + exit 1 +fi + +source_tag=$1 +page=1 +until [ $page -gt 100 ]; do + echo "Finding build number for tag ${source_tag}" + build_number=$(drone build ls rancher/rancher --page $page --event tag --format "{{.Number}},{{.Ref}}"| grep "${source_tag}"$ |cut -d',' -f1|head -1) + if [[ -n ${build_number} ]]; then + echo "Found build number ${build_number} for tag ${source_tag}" + drone build promote rancher/rancher "${build_number}" promote-stable + exit 0 + break + fi + ((page++)) + sleep 1 +done + +echo "No Build Found for TAG: ${1}" +exit 1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/test b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/test new file mode 100755 index 0000000..550e55b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/test @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +echo "-- chart/test --" +set -ex + +# Check for helm +if [ -z "$(type -p helm_v3)" ]; then + echo "helm not found. Helm is required to run tests." + exit 1 +fi + +if [ "${ARCH}" != "amd64" ]; then + echo "${ARCH} is not supported for chart tests, chart tests won't run" + exit 0 +fi +# Check for unittest plugin +helm_v3 unittest --help >/dev/null 2>&1 +if [[ $? > 0 ]]; then + echo "helm plugin unittest not found." + echo "Run to install plugin: helm plugin install https://github.com/helm-unittest/helm-unittest.git" + exit 1 +fi + +current_dir=$(pwd) +cd $(dirname $0)/../../build/chart/rancher +helm_v3 unittest ./ +cd $current_dir diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/validate b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/validate new file mode 100755 index 0000000..2838007 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/chart/validate @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -ex + +echo "-- chart/validate --" + +# Check for helm +if [ -z "$(type -p helm_v3)" ]; then + echo "helm_v3 not found. Helm is required to run tests." + exit 1 +fi + +helm_v3 lint $(dirname $0)/../../build/chart/rancher diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-chart-kdm-source-values b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-chart-kdm-source-values new file mode 100755 index 0000000..4f07f51 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-chart-kdm-source-values @@ -0,0 +1,77 @@ +#!/bin/bash +# Without RELEASE_TYPE set, it will show the values for each. +# With RELEASE_TYPE set to 'rc' or 'final-rc', it will compare the values to the expected ones and report CORRECT or INCORRECT + +case $RELEASE_TYPE in + rc) + REQUIRED_VALUE="dev-v2.9" + ;; + final-rc) + REQUIRED_VALUE="release-v2.9" + ;; +esac + +if [ -n "${RELEASE_TYPE}" ]; then + echo "RELEASE_TYPE is ${RELEASE_TYPE}" + echo "Going to check for ${REQUIRED_VALUE}" +fi + +# scripts/package-env +for PKGENV in SYSTEM_CHART_DEFAULT_BRANCH CHART_DEFAULT_BRANCH; do + FOUND_VALUE=$(grep ^${PKGENV} scripts/package-env | awk -F':-' '{ print $2 }' | sed 's/.$//' | sed 's/"//g') + if [ -n "${RELEASE_TYPE}" ]; then + echo -n "${PKGENV}: ${FOUND_VALUE} in scripts/package-env: " + if [ "${FOUND_VALUE}" != "${REQUIRED_VALUE}" ]; then + echo "INCORRECT (should be ${REQUIRED_VALUE})" + else + echo "CORRECT" + fi + else + echo "* ${PKGENV}: ${FOUND_VALUE} (\`scripts/package-env\`)" + fi +done + +# package/Dockerfile +for DFARG in SYSTEM_CHART_DEFAULT_BRANCH CHART_DEFAULT_BRANCH CATTLE_KDM_BRANCH; do + FOUND_VALUE=$(grep ^"ARG ${DFARG}" package/Dockerfile | awk -F'=' '{ print $2 }') + if [ -n "${RELEASE_TYPE}" ]; then + echo -n "${DFARG}: ${FOUND_VALUE} in package/Dockerfile: " + if [ "${FOUND_VALUE}" != "${REQUIRED_VALUE}" ]; then + echo "INCORRECT (should be ${REQUIRED_VALUE})" + else + echo "CORRECT" + fi + else + echo "* ${DFARG}: ${FOUND_VALUE} (\`package/Dockerfile\`)" + fi +done + +# Dockerfile.dapper +for DFDENV in CATTLE_KDM_BRANCH; do + FOUND_VALUE=$(grep ^"ENV ${DFDENV}" Dockerfile.dapper| awk -F'=' '{ print $2 }') + if [ -n "${RELEASE_TYPE}" ]; then + echo -n "${DFDENV}: ${FOUND_VALUE} in Dockerfile.dapper: " + if [ "${FOUND_VALUE}" != "${REQUIRED_VALUE}" ]; then + echo "INCORRECT (should be ${REQUIRED_VALUE})" + else + echo "CORRECT" + fi + else + echo "* ${DFDENV}: ${FOUND_VALUE} (\`Dockerfile.dapper\`)" + fi +done + +# pkg/settings/setting.go +for PKGSETTING in KDMBranch ChartDefaultBranch; do + FOUND_VALUE=$(grep ^"\\s*${PKGSETTING}" pkg/settings/setting.go | awk -F', ' '{ print $2 }' | sed 's/)//' | sed 's/"//g') + if [ -n "${RELEASE_TYPE}" ]; then + echo -n "${PKGSETTING}: ${FOUND_VALUE} in pkg/settings/setting.go: " + if [ "${FOUND_VALUE}" != "${REQUIRED_VALUE}" ]; then + echo "INCORRECT (should be ${REQUIRED_VALUE})" + else + echo "CORRECT" + fi + else + echo "* ${PKGSETTING}: ${FOUND_VALUE} (\`pkg/settings/setting.go\`)" + fi +done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-origins b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-origins new file mode 100755 index 0000000..01eabd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-origins @@ -0,0 +1,32 @@ +#!/bin/bash +set -e +cd $(dirname $0) + +if [ -n "$CATTLE_KDM_BRANCH" ]; then + curl -sLf https://releases.rancher.com/kontainer-driver-metadata/${CATTLE_KDM_BRANCH}/data.json > ../bin/data.json +elif [ ! -e ../bin/data.json ] && [ -e ../kontainer-driver-metadata/data/data.json ]; then + cp ../kontainer-driver-metadata/data/data.json ../bin/data.json +fi + +source version +source package-env + +cd ../package +../scripts/k3s-images.sh + +cp ../bin/data.json ../bin/rancher-data.json + +cd ../bin + +# Clone charts and system-charts so that we can +# determine all images used by them +if [ ! -d build/system-charts ]; then + mkdir -p build + git clone --depth=1 --no-tags --branch $SYSTEM_CHART_DEFAULT_BRANCH https://github.com/rancher/system-charts $SYSTEM_CHART_REPO_DIR +fi + +if [ ! -d $CHART_REPO_DIR ]; then + git clone --branch $CHART_DEFAULT_BRANCH https://github.com/rancher/charts $CHART_REPO_DIR +fi + +TAG=$TAG REPO=${REPO} go run ../pkg/image/origins/main.go $SYSTEM_CHART_REPO_DIR $CHART_REPO_DIR $IMAGE $AGENT_IMAGE $SYSTEM_AGENT_UPGRADE_IMAGE $WINS_AGENT_UPGRADE_IMAGE ${SYSTEM_AGENT_INSTALLER_RKE2_IMAGES[@]} ${SYSTEM_AGENT_INSTALLER_K3S_IMAGES[@]} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-release-images-exist b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-release-images-exist new file mode 100755 index 0000000..9db934d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/check-release-images-exist @@ -0,0 +1,38 @@ +#!/bin/bash +# This script checks if all images in the (pre) release are available in Docker Hub by checking the existence of a manifest +# This script does not guarantee that all archs for that image are available +cd $(dirname $0) + +./build +./package + +cd ./.. + +TEMP_FILE=$(mktemp) + +if [ -n "${DRONE_TAG}" ]; then + if [ -s ./bin/rancher-images.txt ]; then + # We skip rancher/rancher and rancher/rancher-agent because the manifest for these gets created later in the pipeline + for rancherimage in $(cat ./bin/rancher-images.txt | egrep -v "^rancher/rancher:|^rancher/rancher-agent:"); do + echo "INFO: Checking if image [${rancherimage}] exists" + if ! skopeo inspect "docker://${rancherimage}" >/dev/null; then + echo "ERROR: Image [${rancherimage}] does not exist" + echo "${rancherimage}" >> $TEMP_FILE + else + echo "OK: Image [${rancherimage}] does exist" + fi + done + else + echo "ERROR: ./bin/rancher-images.txt does not exist or is empty" + exit 1 + fi + + if [ -s $TEMP_FILE ]; then + echo "ERROR: Summary of missing image(s):" + cat $TEMP_FILE + exit 1 + else + echo "OK: All images exist" + exit 0 + fi +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/ci b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/ci new file mode 100755 index 0000000..6d7b13d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/ci @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +cd $(dirname $0) + +if ./only-ui-bumps.sh; then + ./build + ./package + ./chart/ci + exit 0 +fi + +./validate +./build +./package +./test +./chart/ci diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-file.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-file.sh new file mode 100755 index 0000000..a1393f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-file.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# This script will create a txt file with -rc images/components which will be used as (pre) release description by Drone +set -e -x + +echo "Creating ./bin/rancher-components.txt" + +cd $(dirname $0)/.. + +mkdir -p bin + +COMPONENTSFILE=./bin/rancher-components.txt + +echo "# Images with -rc" > $COMPONENTSFILE + +printf '%s\n' "$(grep -h "\-rc" ./bin/rancher-images.txt ./bin/rancher-windows-images.txt | awk -F: '{ print $1,$2 }')" | sort -u >> $COMPONENTSFILE + +echo "# Components with -rc" >> $COMPONENTSFILE + +printf '%s\n' "$(grep "_VERSION" ./package/Dockerfile | grep ENV | egrep -v "http|\\$|MIN_VERSION" | grep CATTLE |sed 's/CATTLE_//g' | sed 's/=/ /g' | awk '{ print $2,$3 }' | sort | grep "\-rc")" >> $COMPONENTSFILE + +printf '%s\n' "$(grep "rancher/" ./go.mod | egrep -v "\./" | egrep -v "\/pkg\/apis|\/pkg\/client|^module" | grep -v "=>" | awk -F'/' '{ print $NF }' | awk '$1 = toupper($1)' | sort | grep "\-rc")" >> $COMPONENTSFILE + +echo "# Min version components with -rc" >> $COMPONENTSFILE + +printf '%s\n' "$(grep "_MIN_VERSION" ./package/Dockerfile | grep ENV | grep CATTLE |sed 's/CATTLE_//g' | sed 's/=/ /g' | awk '{ print $2,$3 }' | sort | grep "\-rc")" >> $COMPONENTSFILE + +K8SVERSIONSFILE=./bin/rancher-rke-k8s-versions.txt + +if [[ -f "$K8SVERSIONSFILE" ]]; then + echo "# RKE Kubernetes versions" >> $COMPONENTSFILE + cat $K8SVERSIONSFILE >> $COMPONENTSFILE +fi + +echo "# Chart/KDM sources" >> $COMPONENTSFILE + +bash ./scripts/check-chart-kdm-source-values >> $COMPONENTSFILE + +echo "Done creating ./bin/rancher-components.txt" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-images-files.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-images-files.sh new file mode 100755 index 0000000..08f1c3b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/create-components-images-files.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + set -e + +cd $(dirname $0) + +source version +source export-config +source package-env + +cd ../package + +../scripts/k3s-images.sh + +# Make sure the used data.json is a release artifact + +if [ ${ARCH} == arm64 ]; then + ETCD_UNSUPPORTED_ARCH=arm64 +fi +if [ ${ARCH} == s390x ]; then + ETCD_UNSUPPORTED_ARCH=s390x +fi + +mkdir -p ../dist +cp ../bin/data.json ../dist/rancher-data.json + +cd ../bin + +if [ ! -d build/system-charts ]; then + mkdir -p build + git clone --depth=1 --no-tags --branch $SYSTEM_CHART_DEFAULT_BRANCH https://github.com/rancher/system-charts $SYSTEM_CHART_REPO_DIR +fi + +if [ ! -d $CHART_REPO_DIR ]; then + git clone --branch $CHART_DEFAULT_BRANCH https://github.com/rancher/charts $CHART_REPO_DIR +fi + +if [ ! -d $SMALL_FORK_REPO_DIR ]; then + mkdir -p $SMALL_FORK_REPO_DIR + git clone --branch main https://github.com/rancher/charts-small-fork $SMALL_FORK_REPO_DIR +fi + +if [ ${ARCH} == amd64 ]; then + # Move this out of ARCH check for local dev on non-amd64 hardware. + TAG=$TAG REPO=${REPO} go run ../pkg/image/export/main.go $SYSTEM_CHART_REPO_DIR $CHART_REPO_DIR $IMAGE $AGENT_IMAGE $SYSTEM_AGENT_UPGRADE_IMAGE $WINS_AGENT_UPGRADE_IMAGE ${SYSTEM_AGENT_INSTALLER_RKE2_IMAGES[@]} ${SYSTEM_AGENT_INSTALLER_K3S_IMAGES[@]} +fi + +# Create components file used for pre-release notes +../scripts/create-components-file.sh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/entry b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/entry new file mode 100755 index 0000000..78fb567 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/entry @@ -0,0 +1,11 @@ +#!/bin/bash +set -e + +mkdir -p bin dist +if [ -e ./scripts/$1 ]; then + ./scripts/"$@" +else + exec "$@" +fi + +chown -R $DAPPER_UID:$DAPPER_GID . diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/export-config b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/export-config new file mode 100755 index 0000000..3686650 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/export-config @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -e + +if [ -n "$DEBUG" ]; then + set -x +fi + +file="$(git rev-parse --show-toplevel)/build.yaml" + +CATTLE_RANCHER_WEBHOOK_VERSION=$(yq -e '.webhookVersion' "$file") +CATTLE_RANCHER_PROVISIONING_CAPI_VERSION=$(yq -e '.provisioningCAPIVersion' "$file") +CATTLE_CSP_ADAPTER_MIN_VERSION=$(yq -e '.cspAdapterMinVersion' "$file") +CATTLE_DEFAULT_SHELL_VERSION=$(yq -e '.defaultShellVersion' "$file") +CATTLE_FLEET_VERSION=$(yq -e '.fleetVersion' "$file") + +export CATTLE_RANCHER_WEBHOOK_VERSION +export CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +export CATTLE_CSP_ADAPTER_MIN_VERSION +export CATTLE_DEFAULT_SHELL_VERSION +export CATTLE_FLEET_VERSION diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/fossa b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/fossa new file mode 100755 index 0000000..e16971e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/fossa @@ -0,0 +1,4 @@ +#!/bin/bash + +fossa analyze +fossa test \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/generate-linux-digests.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/generate-linux-digests.sh new file mode 100755 index 0000000..2fcb46e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/generate-linux-digests.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +cd $(dirname $0)/.. +mkdir -p bin + +declare -a archs=(amd64 arm64 s390x) + +if [ -z "${DRONE_TAG}" ]; then + echo "Environment variable DRONE_TAG not set" + exit 0 +fi + +DIGEST_TEMPLATE_FILENAME="./bin/rancher-images-digests-linux" +IMAGES_FILE=$(mktemp) +IMAGES_URL="https://github.com/rancher/rancher/releases/download/${DRONE_TAG}/rancher-images.txt" + +wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 10 $IMAGES_URL -O $IMAGES_FILE + +for image in $(cat $IMAGES_FILE); do + INSPECT_JSON=$(skopeo inspect "docker://${image}" --raw) + MEDIATYPE=$(echo "${INSPECT_JSON}" | jq -r .mediaType) + echo "Image: ${image}, mediaType: ${MEDIATYPE}" + if [ "${MEDIATYPE}" = "application/vnd.docker.distribution.manifest.list.v2+json" ] || [ "${MEDIATYPE}" = "application/vnd.oci.image.index.v1+json" ]; then + DIGEST=$(echo -n "${INSPECT_JSON}" | sha256sum | awk '{ print $1 }') + for arch in "${archs[@]}"; do + if echo "${INSPECT_JSON}" | jq -e --arg ARCH "$arch" 'select(.manifests[].platform.architecture == $ARCH)' >/dev/null 2>&1; then + echo "docker.io/${image} sha256:${DIGEST}" >> "${DIGEST_TEMPLATE_FILENAME}-${arch}.txt" + fi + done + else + for arch in "${archs[@]}"; do + INSPECT_JSON=$(skopeo --override-arch $arch inspect "docker://${image}") + if echo "${INSPECT_JSON}" | jq -e --arg ARCH "$arch" '.Architecture == $ARCH' >/dev/null 2>&1; then + echo "Image: ${image}, arch ${arch}, FOUND" + DIGEST=$(skopeo --override-arch $arch inspect "docker://${image}" --raw | sha256sum | awk '{ print $1 }') + echo "docker.io/${image} sha256:${DIGEST}" >> "${DIGEST_TEMPLATE_FILENAME}-${arch}.txt" + else + echo "Image: ${image}, arch ${arch}, NOT_FOUND" + fi + done + fi +done + +rm -f ${IMAGES_FILE} + +ls -la ./bin/rancher-images-digests-linux-* diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/run b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/run new file mode 100755 index 0000000..1b3c02f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/run @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +echo Starting rancher server + +echo "scripts/run" + +source $(dirname $0)/../version +source $(dirname $0)/../export-config +cd scripts +source ./package-env +cd .. + + +cd $(dirname $0)/../.. + +if [ ! -z $1 ] && ( [ $1 = "--trace" ] || [ $1 = "--info" ] || [ $1 = "--debug" ] ); then + LOGFLAG=$1 +fi + +rm -rf build/testdata +mkdir -p build/testdata +cd build/testdata +export KUBECONFIG= +export CATTLE_DEV_MODE=yes +export CATTLE_SERVER_URL="https://$(ip route get 8.8.8.8 | awk '{print $7}')" +export CATTLE_BOOTSTRAP_PASSWORD="admin" +export CATTLE_FEATURES="harvester=false" + +echo "docker run -d --name rancher-server --restart=unless-stopped --privileged -p 6443:6443 -p 8080:8080 -p 443:443 -e CATTLE_SERVER_URL=$CATTLE_SERVER_URL -e CATTLE_BOOTSTRAP_PASSWORD="admin" -e CATTLE_DEV_MODE=yes -e CATTLE_AGENT_IMAGE=$AGENT_IMAGE $IMAGE" +docker run -d --name rancher-server --restart=unless-stopped --privileged -p 6443:6443 -p 8080:8080 -p 443:443 -e CATTLE_SERVER_URL=$CATTLE_SERVER_URL -e CATTLE_BOOTSTRAP_PASSWORD="admin" -e CATTLE_DEV_MODE=yes -e CATTLE_AGENT_IMAGE=$AGENT_IMAGE $IMAGE + +sleep 5 + +echo "docker container ls" +docker container ls + +mkdir -p /etc/rancher/k3s/ +docker cp rancher-server:/etc/rancher/k3s/k3s.yaml /etc/rancher/k3s/k3s.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/tests b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/tests new file mode 100755 index 0000000..4c01e12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/gha/tests @@ -0,0 +1,167 @@ +#!/bin/bash +set -e + +GOBIN=${GOBIN-"go"} + +cleanup() +{ + EXIT=$? + set +ex + echo Stopping rancher server + kill $RANCHER_RUN_PID + wait $RANCHER_RUN_PID + if [ $PID != -1 ]; then + kill $PID + wait $PID + fi + return $EXIT +} + +cd $(dirname $0)/../.. + + +TB_ORG=rancher + +if [ -z "${TEST_DIST}" ] || [ "${TEST_DIST}" = "k3s" ]; then + TEST_DIST=k3s + AIRGAP=-airgap + TB_ORG=k3s-io +else + LINUX=.linux +fi + +export DIST=${TEST_DIST} +export SOME_K8S_VERSION=${SOME_K8S_VERSION} +export TB_ORG=${TB_ORG} +export CATTLE_CHART_DEFAULT_URL=${CATTLE_CHART_DEFAULT_URL} +REGISTRY=${REGISTRY-""} + +# Tell Rancher to use the recently-built Rancher cluster agent image. This image is built as part of CI and will be +# copied to the in-cluster registry during test setup below. +source ./scripts/version +export CATTLE_AGENT_IMAGE="${REGISTRY}rancher/rancher-agent:${AGENT_TAG}" +echo "Using Rancher agent image $CATTLE_AGENT_IMAGE" + +eval "$(grep '^ENV CATTLE_SYSTEM_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_WINS_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_CSI_PROXY_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_KDM_BRANCH' package/Dockerfile | awk '{print "export " $2 "=" $3}')" + +if [ -z "${SOME_K8S_VERSION}" ]; then +# Get the last release for $DIST, which is usually the latest version or an experimental version. +# Previously this would use channels, but channels no longer reflect the latest version since +# https://github.com/rancher/rancher/issues/36827 has added appDefaults. We do not use appDefaults +# here for simplicity's sake, as it requires semver parsing & matching. The last release should +# be good enough for our needs. +export SOME_K8S_VERSION=$(curl -sS https://raw.githubusercontent.com/rancher/kontainer-driver-metadata/release-v2.9/data/data.json | jq -r ".$DIST.releases[-1].version") +fi + +if [ -z "${CATTLE_CHART_DEFAULT_URL}" ]; then +# If `CATTLE_CHART_DEFAULT_URL` is not set, use the `https://github.com/rancher/charts` so GitHub is used instead of +# the default `https://git.rancher.io/charts` to reduce the reliance and load on our Git mirror +export CATTLE_CHART_DEFAULT_URL=https://github.com/rancher/charts +fi + +echo Starting rancher server for test +touch /tmp/rancher.log + +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + +mkdir -p /var/lib/rancher/$DIST/agent/images +grep PodTestImage ./tests/v2prov/defaults/defaults.go | cut -f2 -d'"' > /var/lib/rancher/$DIST/agent/images/pull.txt +grep MachineProvisionImage ./pkg/settings/setting.go | cut -f4 -d'"' >> /var/lib/rancher/$DIST/agent/images/pull.txt +mkdir -p /usr/share/rancher/ui/assets +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -o /usr/share/rancher/ui/assets/rancher-system-agent-amd64 +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-arm64 -o /usr/share/rancher/ui/assets/rancher-system-agent-arm64 +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh -o /usr/share/rancher/ui/assets/system-agent-uninstall.sh + +run_rancher() +{ + RESTART_COUNT=0 + while sleep 2; do + if [ "$PID" != "-1" ] && [ ! -e /proc/$PID ]; then + echo Rancher died + dump_rancher_logs + echo K3s logs were: + echo -e "-----K3S-LOG-DUMP-START-----" + cat build/testdata/k3s.log + echo -e "\n-----K3S-LOG-DUMP-END-----" + set +e + echo Attempting to kill K3s + pkill -e k3s + set -e + PID=-1 + if [ "$RESTART_COUNT" = "2" ]; then + echo Rancher died 3 times, aborting + kill -42 $PWRAPPROC + fi + RESTART_COUNT=$((RESTART_COUNT + 1)) + sleep 5 + fi + if [ "$PID" = "-1" ]; then + echo Starting rancher server using run + ./scripts/gha/run >/tmp/rancher.log 2>&1 & + PID=$! + fi + sleep 2 + done +} + +dump_rancher_logs() +{ + echo Rancher logs were + echo -e "-----RANCHER-LOG-DUMP-START-----" + cat /tmp/rancher.log + echo -e "\n-----RANCHER-LOG-DUMP-END-----" +} + +# uncomment to get startup logs. Don't leave them on because it slows drone down too +# much +#tail -F /tmp/rancher.log & +#TPID=$! + +trap "exit 1" 42 +PWRAPPROC="$$" + +PID=-1 +run_rancher & +RANCHER_RUN_PID=$! +trap cleanup exit + +echo "Waiting up to 5 minutes for rancher-webhook deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-webhook was not available after {{elapsed}} seconds" `# Print this progress message` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-system deploy/rancher-webhook &" + +echo "Waiting up to 5 minutes for rancher-provisioning-capi deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-provisioning-capi was not available after {{elapsed}} seconds" `# Print this progress message` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-provisioning-capi-system deploy/capi-controller-manager &" + + +echo Running integrationsetup +export CATTLE_TEST_CONFIG=$(pwd)/config.yaml # used by integration tests and test setup +./tests/v2/integration/bin/integrationsetup || { + dump_rancher_logs + exit 1 +} + +echo Running go integration tests +$GOBIN test -v -failfast -timeout 30m -p 1 ./tests/v2/integration/... || { + dump_rancher_logs + exit 1 +} + +echo Running tox tests +INT_TESTS_STARTED=true +cd ./tests/integration +tox -e rancher -- -m "not nonparallel" -n $(nproc) +tox -e rancher -- -m nonparallel + +tail -f /tmp/rancher-test.log & diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/go-get b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/go-get new file mode 100755 index 0000000..98f3914 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/go-get @@ -0,0 +1,20 @@ +#!/bin/bash +set -e +MODULE=$GOGET_MODULE +VERSION=$GOGET_VERSION + +SUBDIRS="pkg/apis pkg/client" + +for SUBDIR in $SUBDIRS; do + if grep -q $MODULE "${SUBDIR}/go.mod"; then + cd $SUBDIR + go get -d "${MODULE}@${VERSION}" + go mod tidy + go mod verify + cd - + fi +done + +go get -d "${MODULE}@${VERSION}" +go mod tidy +go mod verify diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/k3s-images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/k3s-images.sh new file mode 100755 index 0000000..6431e6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/k3s-images.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e -x + +cd $(dirname $0)/.. + +mkdir -p bin + +# This is used for downloading the tar file and not the images text file. +# Referenced in test: tests/validation/tests/v3_api/test_airgap.py +if [ -e /usr/tmp/k3s-images.txt ]; then + images=$(grep -e 'docker.io/rancher/mirrored-pause' -e 'docker.io/rancher/mirrored-coredns-coredns' /usr/tmp/k3s-images.txt) + xargs -n1 docker pull <<< "${images}" + docker save -o ./bin/k3s-airgap-images.tar ${images} +else + touch bin/k3s-airgap-images.tar +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/only-ui-bumps.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/only-ui-bumps.sh new file mode 100755 index 0000000..a4e26bb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/only-ui-bumps.sh @@ -0,0 +1,17 @@ +#!/bin/bash +echo "Checking if we can skip CI because of an only UI/dashboard change" +echo "Environment variable DRONE_BUILD_EVENT is ${DRONE_BUILD_EVENT}" +# Only run check if Drone build event is 'push' or 'pull_request' +if [ "${DRONE_BUILD_EVENT}" = "push" ] || [ "${DRONE_BUILD_EVENT}" = "pull_request" ]; then + # Check if there is only one changed file and if its 'package/Dockerfile' + if [ $(git diff HEAD~1 --name-only | wc -l) -eq 1 ] && [ $(git diff HEAD~1 --name-only) = "package/Dockerfile" ]; then + echo "Only package/Dockerfile changes found" + # Check if only CATTLE_UI_VERSION and CATTLE_DASHBOARD_UI_VERSION are changed in 'package/Dockerfile' + if [ -z "$(git diff -U0 HEAD~1 -- package/Dockerfile | tail -n +5 | grep -v ^@@ | egrep -v "CATTLE_UI_VERSION|CATTLE_DASHBOARD_UI_VERSION")" ]; then + echo "Skipping CI because it is only UI/dashboard change" + exit 0 + fi + fi +fi +echo "Not skipping CI, not an only UI/dashboard change" +exit 1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package new file mode 100755 index 0000000..ee003b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +source $(dirname $0)/version +source $(dirname $0)/export-config +source $(dirname $0)/package-env + +cd $(dirname $0)/../package + +../scripts/k3s-images.sh + +cp ../bin/rancher ../bin/agent ../bin/data.json ../bin/k3s-airgap-images.tar . + +# Make sure the used data.json is a release artifact +cp ../bin/data.json ../bin/rancher-data.json + +if [ ${ARCH} == arm64 ]; then + ETCD_UNSUPPORTED_ARCH=arm64 +fi +if [ ${ARCH} == s390x ]; then + ETCD_UNSUPPORTED_ARCH=s390x +fi + +docker build \ + --build-arg VERSION=${TAG} \ + --build-arg ETCD_UNSUPPORTED_ARCH=${ETCD_UNSUPPORTED_ARCH} \ + --build-arg ARCH=${ARCH} \ + --build-arg IMAGE_REPO=${REPO} \ + --build-arg SYSTEM_CHART_DEFAULT_BRANCH=${SYSTEM_CHART_DEFAULT_BRANCH} \ + --build-arg CHART_DEFAULT_BRANCH=${CHART_DEFAULT_BRANCH} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION="${CATTLE_RANCHER_WEBHOOK_VERSION}" \ + --build-arg CATTLE_RANCHER_PROVISIONING_CAPI_VERSION="${CATTLE_RANCHER_PROVISIONING_CAPI_VERSION}" \ + --build-arg CATTLE_CSP_ADAPTER_MIN_VERSION="${CATTLE_CSP_ADAPTER_MIN_VERSION}" \ + --build-arg CATTLE_FLEET_VERSION="${CATTLE_FLEET_VERSION}" \ + -t ${IMAGE} . + +docker build \ + --build-arg VERSION=${TAG} \ + --build-arg ARCH=${ARCH} \ + --build-arg RANCHER_TAG=${TAG} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION="${CATTLE_RANCHER_WEBHOOK_VERSION}" \ + --build-arg CATTLE_RANCHER_PROVISIONING_CAPI_VERSION="${CATTLE_RANCHER_PROVISIONING_CAPI_VERSION}" \ + --build-arg RANCHER_REPO=${REPO} \ + -t ${AGENT_IMAGE} -f Dockerfile.agent . + +mkdir -p ../dist +echo ${IMAGE} > ../dist/images +echo ${AGENT_IMAGE} >> ../dist/images +echo Built ${IMAGE} #${AGENT_IMAGE} +echo + +cd ../bin + +if [ ! -d build/system-charts ]; then + mkdir -p build + git clone --depth=1 --no-tags --branch $SYSTEM_CHART_DEFAULT_BRANCH https://github.com/rancher/system-charts $SYSTEM_CHART_REPO_DIR +fi + +if [ ! -d $CHART_REPO_DIR ]; then + git clone --branch $CHART_DEFAULT_BRANCH https://github.com/rancher/charts $CHART_REPO_DIR +fi + +if [ ${ARCH} == amd64 ]; then + # Move this out of ARCH check for local dev on non-amd64 hardware. + TAG=$TAG REPO=${REPO} CGO_ENABLED=0 go run ../pkg/image/export/main.go $SYSTEM_CHART_REPO_DIR $CHART_REPO_DIR $IMAGE $AGENT_IMAGE $SYSTEM_AGENT_UPGRADE_IMAGE $WINS_AGENT_UPGRADE_IMAGE ${SYSTEM_AGENT_INSTALLER_RKE2_IMAGES[@]} ${SYSTEM_AGENT_INSTALLER_K3S_IMAGES[@]} +fi + +# Create components file used for pre-release notes +../scripts/create-components-file.sh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package-env b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package-env new file mode 100644 index 0000000..ba3ad68 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/package-env @@ -0,0 +1,29 @@ +#!/bin/bash + +ARCH=${ARCH:-"amd64"} +SYSTEM_CHART_REPO_DIR=build/system-charts +SYSTEM_CHART_DEFAULT_BRANCH=${SYSTEM_CHART_DEFAULT_BRANCH:-"release-v2.9"} +CHART_REPO_DIR=build/charts +CHART_DEFAULT_BRANCH=${CHART_DEFAULT_BRANCH:-"release-v2.9"} + +REGISTRY=${REGISTRY:-""} +IMAGE=${REGISTRY}${REPO}/rancher:${TAG} +AGENT_IMAGE=${REPO}/rancher-agent:${AGENT_TAG} +SYSTEM_AGENT_UPGRADE_TAG=$(grep "ENV CATTLE_SYSTEM_AGENT_VERSION" ../package/Dockerfile | awk '{ print $NF }')-suc +SYSTEM_AGENT_UPGRADE_IMAGE=${REPO}/system-agent:${SYSTEM_AGENT_UPGRADE_TAG} +WINS_AGENT_UPGRADE_TAG=$(grep "ENV CATTLE_WINS_AGENT_VERSION" ../package/Dockerfile | awk '{ print $NF }') +WINS_AGENT_UPGRADE_IMAGE=${REPO}/wins:${WINS_AGENT_UPGRADE_TAG} + +# Query KDM data for RKE2 released versions where server args are defined. +RKE2_RELEASE_VERSIONS=$(jq -r '[.rke2.releases[] | select(.serverArgs) | .version] | join(" ")' ../bin/data.json) +# Convert versions with build metadata into valid image tags (replace + for -) and construct an array of tags. +RKE2_RELEASE_TAGS=( $(echo $RKE2_RELEASE_VERSIONS | tr + -) ) +# Prefix image repo and name to tags. +SYSTEM_AGENT_INSTALLER_RKE2_IMAGES=( "${RKE2_RELEASE_TAGS[@]/#/${REPO}/system-agent-installer-rke2:}" ) + +# Query KDM data for K3S released versions where server args are defined. +K3S_RELEASE_VERSIONS=$(jq -r '[.k3s.releases[] | select(.serverArgs) | .version] | join(" ")' ../bin/data.json) +# Convert versions with build metadata into valid image tags (replace + for -) and construct an array of tags. +K3S_RELEASE_TAGS=( $(echo $K3S_RELEASE_VERSIONS | tr + -) ) +# Prefix image repo and name to tags. +SYSTEM_AGENT_INSTALLER_K3S_IMAGES=( "${K3S_RELEASE_TAGS[@]/#/${REPO}/system-agent-installer-k3s:}" ) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/print-tags.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/print-tags.sh new file mode 100755 index 0000000..bedbfe0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/print-tags.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +if [ -z "$1" ]; then + master="(Rancher tag not specified)" + tag='master' +else + tag=$1 +fi + +CATTLE_VER=$(curl https://raw.githubusercontent.com/rancher/rancher/$tag/server/Dockerfile 2>/dev/null | grep 'ENV CATTLE_CATTLE_VERSION' | awk '{print $3}') + +echo -e "\nPrinting project/service tag information for Rancher tag $tag. $master" + +echo -e "\nCattle Tag: $CATTLE_VER\n" + +echo "Other project tags:" +while read -r l; do + PROP=$(echo "$l" | awk -F= '{print $1}') + URL=$(echo "$l" | awk -F= '{print $2}') + IFS=', ' read -r -a array <<< "$(echo $l | awk -F= '{print $2}')" + for element in "${array[@]}" + do + if [[ $element == http* ]]; then + URL=$element + fi + done + + VER_AND_FILE=$(echo "$l" | grep "releases/download" | sed "s/^.*download\///g") + #echo $VER_AND_FILE + VER=$(echo "$VER_AND_FILE" | awk -F/ '{print $1}') + FILE=$(echo "$VER_AND_FILE" | awk -F/ '{print $2}') + if [[ -n "$VER" ]]; then + printf "%40s %15s %s\n" "$PROP" "$VER" "$URL" + fi + +done < <(curl -s https://raw.githubusercontent.com/rancher/cattle/$CATTLE_VER/resources/content/cattle-global.properties) + +echo -e "\n\nCatalog item versions: (Pulling image may take several minutes)" +docker run --rm -it rancher/server:$tag bash -c 'for i in /var/lib/cattle/cache/global/*; do git -C $i remote -vv; git -C $i rev-parse HEAD; for j in $i/infra-templates/*; do A=$(grep version $j/config.yml 2>/dev/null | cut -d" " -f2); echo $(basename $j): $A; for x in $(grep -Irl --exclude=config.yml $A $j 2>/dev/null); do grep -rh --include="docker-compose.*" -e "^[ \t]*image: " $(dirname $x) 2>/dev/null; done; done; echo -e "\n"; done' 2>/dev/null diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/promote-docker-image.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/promote-docker-image.sh new file mode 100755 index 0000000..dfcbe85 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/promote-docker-image.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +drone_cli_help() +{ + echo " Requires Drone CLI and personal access token" + echo " Download CLI following instructions at https://docs.drone.io/cli/install/" + echo " Then configure access token: https://docs.drone.io/cli/setup/" + echo "" + echo " To test if Drone CLI is properly configured type:" + echo "" + echo " drone build ls rancher/rancher" + echo "" + echo " This will show the last 25 builds" +} + +if [[ $# -ne 2 ]]; then + echo "Promote Docker image to stable or latest tag" + echo " $0 " + echo "" + drone_cli_help + exit 1 +fi + +if ! drone -v; then + drone_cli_help + exit 1 +fi + +source_tag=$1 +destination_tag=$2 + +if [[ ! $destination_tag =~ ^(stable|latest|donotuse)$ ]]; then + echo "Docker tag needs to be stable or latest (or donotuse for testing), not ${destination_tag}" + exit 1 +fi + +echo "Promoting ${source_tag} to ${destination_tag}" + +page=1 +until [ $page -gt 100 ]; do + echo "Finding build number for tag ${source_tag}" + build_number=$(drone build ls rancher/rancher --page $page --event tag --format "{{.Number}},{{.Ref}}"| grep ${source_tag}$ |cut -d',' -f1|head -1) + if [[ -n ${build_number} ]]; then + echo "Found build number ${build_number} for tag ${source_tag}" + drone build promote rancher/rancher ${build_number} promote-docker-image --param=SOURCE_TAG=$source_tag --param=DESTINATION_TAG=$destination_tag + exit 0 + break + fi + ((page++)) + sleep 1 +done + +echo "No build number found for tag: ${source_tag}" +exit 1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/provisioning-tests b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/provisioning-tests new file mode 100755 index 0000000..d99e07a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/provisioning-tests @@ -0,0 +1,175 @@ +#!/bin/bash +set -e +if ./scripts/only-ui-bumps.sh; then + exit 0 +fi + +cleanup() +{ + EXIT=$? + set +ex + echo Stopping rancher server + kill $RANCHER_RUN_PID + wait $RANCHER_RUN_PID + if [ $PID != -1 ]; then + kill $PID + wait $PID + fi + return $EXIT +} + +cd $(dirname $0)/.. + +TB_ORG=rancher + +if [ -z "${V2PROV_TEST_DIST}" ] || [ "${V2PROV_TEST_DIST}" = "k3s" ]; then + V2PROV_TEST_DIST=k3s + AIRGAP=-airgap + TB_ORG=k3s-io +else + LINUX=.linux +fi + +if [ -z "${V2PROV_TEST_RUN_REGEX}" ]; then + V2PROV_TEST_RUN_REGEX="^Test_(General|Provisioning|Fleet)_.*$" +fi + +RUNARG="-run ${V2PROV_TEST_RUN_REGEX}" + +export DIST=${V2PROV_TEST_DIST} +export SOME_K8S_VERSION=${SOME_K8S_VERSION} +export TB_ORG=${TB_ORG} +export CATTLE_CHART_DEFAULT_URL=${CATTLE_CHART_DEFAULT_URL} + +eval "$(grep '^ENV CATTLE_SYSTEM_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_WINS_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_CSI_PROXY_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_KDM_BRANCH' package/Dockerfile | awk '{print "export " $2 "=" $3}')" + +#if [ -z "${SOME_K8S_VERSION}" ]; then +# Only set SOME_K8S_VERSION if it is empty -- for KDM provisioning tests, this value should already be populated +# Get the last release for $DIST, which is usually the latest version or an experimental version. +# Previously this would use channels, but channels no longer reflect the latest version since +# https://github.com/rancher/rancher/issues/36827 has added appDefaults. We do not use appDefaults +# here for simplicity's sake, as it requires semver parsing & matching. The last release should +# be good enough for our needs. +#export SOME_K8S_VERSION=$(curl -sS https://raw.githubusercontent.com/rancher/kontainer-driver-metadata/dev-v2.9/data/data.json | jq -r ".$DIST.releases[-1].version") +#fi + +# Remove the following K8s version setting after the root cause of issues/rancher/45577 is determined +if [ -z "${SOME_K8S_VERSION}" ]; then + if [ "$DIST" = "rke2" ]; then + export SOME_K8S_VERSION="v1.27.10+rke2r1" + else + export SOME_K8S_VERSION=$(curl https://raw.githubusercontent.com/rancher/kontainer-driver-metadata/release-v2.9/data/data.json | jq -r ".$DIST.releases[-1].version") + fi +fi + +if [ -z "${CATTLE_CHART_DEFAULT_URL}" ]; then +# If `CATTLE_CHART_DEFAULT_URL` is not set, use the `https://github.com/rancher/charts` so GitHub is used instead of +# the default `https://git.rancher.io/charts` to reduce the reliance and load on our Git mirror +export CATTLE_CHART_DEFAULT_URL=https://github.com/rancher/charts +fi + +echo "Starting rancher server for provisioning-tests using $SOME_K8S_VERSION" +touch /tmp/rancher.log + +mkdir -p /var/lib/rancher/$DIST/agent/images +grep PodTestImage ./tests/v2prov/defaults/defaults.go | cut -f2 -d'"' > /var/lib/rancher/$DIST/agent/images/pull.txt +grep MachineProvisionImage ./pkg/settings/setting.go | cut -f4 -d'"' >> /var/lib/rancher/$DIST/agent/images/pull.txt +mkdir -p /usr/share/rancher/ui/assets +curl -sLf ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -o /usr/share/rancher/ui/assets/rancher-system-agent-amd64 +curl -sLf ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-arm64 -o /usr/share/rancher/ui/assets/rancher-system-agent-arm64 +curl -sLf ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh -o /usr/share/rancher/ui/assets/system-agent-uninstall.sh + +build_and_run_rancher() +{ + RESTART_COUNT=0 + while sleep 2; do + if [ "$PID" != "-1" ] && [ ! -e /proc/$PID ]; then + echo Rancher died + dump_rancher_logs + echo K3s logs were: + echo -e "-----K3S-LOG-DUMP-START-----" + cat build/testdata/k3s.log | gzip | base64 -w 0 + echo -e "\n-----K3S-LOG-DUMP-END-----" + set +e + echo Attempting to kill K3s + pkill -e k3s + set -e + PID=-1 + if [ "$RESTART_COUNT" = "2" ]; then + echo Rancher died 3 times, aborting + kill -42 $PWRAPPROC + fi + RESTART_COUNT=$((RESTART_COUNT + 1)) + sleep 5 + fi + if [ "$PID" = "-1" ]; then + echo Starting rancher server using run + ./scripts/run >/tmp/rancher.log 2>&1 & + PID=$! + fi + sleep 2 + done +} + +dump_rancher_logs() +{ + echo Rancher logs were + echo -e "-----RANCHER-LOG-DUMP-START-----" + cat /tmp/rancher.log | gzip | base64 -w 0 + echo -e "\n-----RANCHER-LOG-DUMP-END-----" +} +export -f dump_rancher_logs + +# Compile Rancher +# This needs to happen before build_and_run_rancher is executed in the background. +# Otherwise, build_and_run_rancher will also compile Rancher, overly elongating the +# time before Rancher is ready and therefore causing flakiness of the health check below. +./scripts/build-server + +# uncomment to get startup logs. Don't leave them on because it slows drone down too +# much +#tail -F /tmp/rancher.log & +#TPID=$! + +trap "exit 1" 42 +PWRAPPROC="$$" + +PID=-1 +build_and_run_rancher & +RANCHER_RUN_PID=$! +trap cleanup exit + +echo "Waiting for Rancher to be healthy" +./scripts/retry --sleep 2 --timeout 300 "curl -sf -o /dev/null http://localhost:8080/ping" + +echo "Waiting up to 5 minutes for rancher-webhook deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-webhook was not available after {{elapsed}} seconds" `# Print this progress message` \ + --exit-command "dump_rancher_logs" `# Dump logs to find out why webhook did not start` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-system deploy/rancher-webhook &>/dev/null" + +echo "Waiting up to 5 minutes for rancher-provisioning-capi deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-provisioning-capi was not available after {{elapsed}} seconds" `# Print this progress message` \ + --exit-command "dump_rancher_logs" `# Dump logs to find out why webhook did not start` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-provisioning-capi-system deploy/capi-controller-manager &>/dev/null" + + +#kill $TPID + +echo Running provisioning-tests $RUNARG + +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +go test $RUNARG -v -failfast -timeout 60m ./tests/v2prov/tests/... || { + dump_rancher_logs + exit 1 +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/publish-manifests.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/publish-manifests.sh new file mode 100755 index 0000000..e399762 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/publish-manifests.sh @@ -0,0 +1,158 @@ +#!/bin/sh +set -e -x + +# This script publishes docker manifests and images required for multi-architecture support that we (Rancher) don't have automated publishing for. +# We don't have automate publishing for these images because the upstream providers already build images for multiple architectures. +# We need to publish these images under the rancher organization for two reasons: +# 1. To support deploying Rancher in places where quay.io gcr.io are not available +# 2. To support multiple architectures seemlessly through docker manifests. +# TODO Automate this so that we don't need to run this manually + + +# quay.io/coreos/etcd:v3.2.24 +docker pull quay.io/coreos/etcd:v3.2.24 +docker tag quay.io/coreos/etcd:v3.2.24 rancher/coreos-etcd:v3.2.24-amd64 +docker pull quay.io/coreos/etcd:v3.2.24-arm64 +docker tag quay.io/coreos/etcd:v3.2.24-arm64 rancher/coreos-etcd:v3.2.24-arm64 +docker push rancher/coreos-etcd:v3.2.24-amd64 +docker push rancher/coreos-etcd:v3.2.24-arm64 +docker manifest create rancher/coreos-etcd:v3.2.24-rancher1 rancher/coreos-etcd:v3.2.24-amd64 rancher/coreos-etcd:v3.2.24-arm64 +docker manifest annotate rancher/coreos-etcd:v3.2.24-rancher1 rancher/coreos-etcd:v3.2.24-amd64 --arch amd64 +docker manifest annotate rancher/coreos-etcd:v3.2.24-rancher1 rancher/coreos-etcd:v3.2.24-arm64 --arch arm64 +docker manifest push -p rancher/coreos-etcd:v3.2.24-rancher1 + +# quay.io/coreos/flannel:v0.10.0 +docker pull quay.io/coreos/flannel:v0.10.0 +docker tag quay.io/coreos/flannel:v0.10.0 rancher/coreos-flannel:v0.10.0-amd64 +docker pull quay.io/coreos/flannel:v0.10.0-arm64 +docker tag quay.io/coreos/flannel:v0.10.0-arm64 rancher/coreos-flannel:v0.10.0-arm64 +docker push rancher/coreos-flannel:v0.10.0-amd64 +docker push rancher/coreos-flannel:v0.10.0-arm64 +docker manifest create rancher/coreos-flannel:v0.10.0-rancher1 rancher/coreos-flannel:v0.10.0-amd64 rancher/coreos-flannel:v0.10.0-arm64 +docker manifest annotate rancher/coreos-flannel:v0.10.0-rancher1 rancher/coreos-flannel:v0.10.0-amd64 --arch amd64 +docker manifest annotate rancher/coreos-flannel:v0.10.0-rancher1 rancher/coreos-flannel:v0.10.0-arm64 --arch arm64 +docker manifest push -p rancher/coreos-flannel:v0.10.0-rancher1 + +# k8s.gcr.io/defaultbackend-amd64:1.4 +docker pull k8s.gcr.io/defaultbackend-amd64:1.4 +docker tag k8s.gcr.io/defaultbackend-amd64:1.4 rancher/nginx-ingress-controller-defaultbackend:1.4-amd64 +docker pull k8s.gcr.io/defaultbackend-arm64:1.4 +docker tag k8s.gcr.io/defaultbackend-arm64:1.4 rancher/nginx-ingress-controller-defaultbackend:1.4-arm64 +docker push rancher/nginx-ingress-controller-defaultbackend:1.4-amd64 +docker push rancher/nginx-ingress-controller-defaultbackend:1.4-arm64 +docker manifest create rancher/nginx-ingress-controller-defaultbackend:1.4-rancher1 rancher/nginx-ingress-controller-defaultbackend:1.4-amd64 rancher/nginx-ingress-controller-defaultbackend:1.4-arm64 +docker manifest annotate rancher/nginx-ingress-controller-defaultbackend:1.4-rancher1 rancher/nginx-ingress-controller-defaultbackend:1.4-amd64 --arch amd64 +docker manifest annotate rancher/nginx-ingress-controller-defaultbackend:1.4-rancher1 rancher/nginx-ingress-controller-defaultbackend:1.4-arm64 --arch arm64 +docker manifest push -p rancher/nginx-ingress-controller-defaultbackend:1.4-rancher1 + +# gcr.io/google_containers/k8s-dns-kube-dns:1.14.13 +docker pull gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.13 rancher/k8s-dns-kube-dns:1.14.13-amd64 +docker pull gcr.io/google_containers/k8s-dns-kube-dns-arm64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-kube-dns-arm64:1.14.13 rancher/k8s-dns-kube-dns:1.14.13-arm64 +docker push rancher/k8s-dns-kube-dns:1.14.13-amd64 +docker push rancher/k8s-dns-kube-dns:1.14.13-arm64 +docker manifest create rancher/k8s-dns-kube-dns:1.14.13 rancher/k8s-dns-kube-dns:1.14.13-amd64 rancher/k8s-dns-kube-dns:1.14.13-arm64 +docker manifest annotate rancher/k8s-dns-kube-dns:1.14.13 rancher/k8s-dns-kube-dns:1.14.13-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-kube-dns:1.14.13 rancher/k8s-dns-kube-dns:1.14.13-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-kube-dns:1.14.13 + +#gcr.io/google_containers/k8s-dns-dnsmasq-nanny:1.14.13 +docker pull gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.13 rancher/k8s-dns-dnsmasq-nanny:1.14.13-amd64 +docker pull gcr.io/google_containers/k8s-dns-dnsmasq-nanny-arm64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-dnsmasq-nanny-arm64:1.14.13 rancher/k8s-dns-dnsmasq-nanny:1.14.13-arm64 +docker push rancher/k8s-dns-dnsmasq-nanny:1.14.13-amd64 +docker push rancher/k8s-dns-dnsmasq-nanny:1.14.13-arm64 +docker manifest create rancher/k8s-dns-dnsmasq-nanny:1.14.13 rancher/k8s-dns-dnsmasq-nanny:1.14.13-amd64 rancher/k8s-dns-dnsmasq-nanny:1.14.13-arm64 +docker manifest annotate rancher/k8s-dns-dnsmasq-nanny:1.14.13 rancher/k8s-dns-dnsmasq-nanny:1.14.13-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-dnsmasq-nanny:1.14.13 rancher/k8s-dns-dnsmasq-nanny:1.14.13-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-dnsmasq-nanny:1.14.13 + +#gcr.io/google_containers/k8s-dns-sidecar:1.14.13 +docker pull gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.13 rancher/k8s-dns-sidecar:1.14.13-amd64 +docker pull gcr.io/google_containers/k8s-dns-sidecar-arm64:1.14.13 +docker tag gcr.io/google_containers/k8s-dns-sidecar-arm64:1.14.13 rancher/k8s-dns-sidecar:1.14.13-arm64 +docker push rancher/k8s-dns-sidecar:1.14.13-amd64 +docker push rancher/k8s-dns-sidecar:1.14.13-arm64 +docker manifest create rancher/k8s-dns-sidecar:1.14.13 rancher/k8s-dns-sidecar:1.14.13-amd64 rancher/k8s-dns-sidecar:1.14.13-arm64 +docker manifest annotate rancher/k8s-dns-sidecar:1.14.13 rancher/k8s-dns-sidecar:1.14.13-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-sidecar:1.14.13 rancher/k8s-dns-sidecar:1.14.13-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-sidecar:1.14.13 + +#gcr.io/google_containers/cluster-proportional-autoscaler:1.0.0 +docker pull gcr.io/google_containers/cluster-proportional-autoscaler-amd64:1.0.0 +docker tag gcr.io/google_containers/cluster-proportional-autoscaler-amd64:1.0.0 rancher/cluster-proportional-autoscaler:1.0.0-amd64 +docker pull gcr.io/google_containers/cluster-proportional-autoscaler-arm64:1.0.0 +docker tag gcr.io/google_containers/cluster-proportional-autoscaler-arm64:1.0.0 rancher/cluster-proportional-autoscaler:1.0.0-arm64 +docker push rancher/cluster-proportional-autoscaler:1.0.0-amd64 +docker push rancher/cluster-proportional-autoscaler:1.0.0-arm64 +docker manifest create rancher/cluster-proportional-autoscaler:1.0.0 rancher/cluster-proportional-autoscaler:1.0.0-amd64 rancher/cluster-proportional-autoscaler:1.0.0-arm64 +docker manifest annotate rancher/cluster-proportional-autoscaler:1.0.0 rancher/cluster-proportional-autoscaler:1.0.0-amd64 --arch amd64 +docker manifest annotate rancher/cluster-proportional-autoscaler:1.0.0 rancher/cluster-proportional-autoscaler:1.0.0-arm64 --arch arm64 +docker manifest push -p rancher/cluster-proportional-autoscaler:1.0.0 + +#gcr.io/google_containers/pause:3.1 +docker pull gcr.io/google_containers/pause-amd64:3.1 +docker tag gcr.io/google_containers/pause-amd64:3.1 rancher/pause:3.1-amd64 +docker pull gcr.io/google_containers/pause-arm64:3.1 +docker tag gcr.io/google_containers/pause-arm64:3.1 rancher/pause:3.1-arm64 +docker pull gcr.io/google_containers/pause-arm:3.1 +docker tag gcr.io/google_containers/pause-arm:3.1 rancher/pause:3.1-arm +docker push rancher/pause:3.1-amd64 +docker push rancher/pause:3.1-arm64 +docker push rancher/pause:3.1-arm +docker manifest create rancher/pause:3.1 rancher/pause:3.1-amd64 rancher/pause:3.1-arm64 rancher/pause:3.1-arm +docker manifest annotate rancher/pause:3.1 rancher/pause:3.1-amd64 --arch amd64 +docker manifest annotate rancher/pause:3.1 rancher/pause:3.1-arm64 --arch arm64 +docker manifest annotate rancher/pause:3.1 rancher/pause:3.1-arm --arch arm +docker manifest push -p rancher/pause:3.1 + +#gcr.io/google_containers/metrics-server:v0.3.1 +docker pull gcr.io/google_containers/metrics-server-amd64:v0.3.1 +docker tag gcr.io/google_containers/metrics-server-amd64:v0.3.1 rancher/metrics-server:v0.3.1-amd64 +docker pull gcr.io/google_containers/metrics-server-arm64:v0.3.1 +docker tag gcr.io/google_containers/metrics-server-arm64:v0.3.1 rancher/metrics-server:v0.3.1-arm64 +docker push rancher/metrics-server:v0.3.1-amd64 +docker push rancher/metrics-server:v0.3.1-arm64 +docker manifest create rancher/metrics-server:v0.3.1 rancher/metrics-server:v0.3.1-amd64 rancher/metrics-server:v0.3.1-arm64 +docker manifest annotate rancher/metrics-server:v0.3.1 rancher/metrics-server:v0.3.1-amd64 --arch amd64 +docker manifest annotate rancher/metrics-server:v0.3.1 rancher/metrics-server:v0.3.1-arm64 --arch arm64 +docker manifest push -p rancher/metrics-server:v0.3.1 + +#gcr.io/google_containers/k8s-dns-kube-dns:1.15.2 +docker pull gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.15.2 rancher/k8s-dns-kube-dns:1.15.2-amd64 +docker pull gcr.io/google_containers/k8s-dns-kube-dns-arm64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-kube-dns-arm64:1.15.2 rancher/k8s-dns-kube-dns:1.15.2-arm64 +docker push rancher/k8s-dns-kube-dns:1.15.2-amd64 +docker push rancher/k8s-dns-kube-dns:1.15.2-arm64 +docker manifest create rancher/k8s-dns-kube-dns:1.15.2 rancher/k8s-dns-kube-dns:1.15.2-amd64 rancher/k8s-dns-kube-dns:1.15.2-arm64 +docker manifest annotate rancher/k8s-dns-kube-dns:1.15.2 rancher/k8s-dns-kube-dns:1.15.2-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-kube-dns:1.15.2 rancher/k8s-dns-kube-dns:1.15.2-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-kube-dns:1.15.2 + +#gcr.io/google_containers/k8s-dns-dnsmasq-nanny:1.15.2 +docker pull gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.15.2 rancher/k8s-dns-dnsmasq-nanny:1.15.2-amd64 +docker pull gcr.io/google_containers/k8s-dns-dnsmasq-nanny-arm64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-dnsmasq-nanny-arm64:1.15.2 rancher/k8s-dns-dnsmasq-nanny:1.15.2-arm64 +docker push rancher/k8s-dns-dnsmasq-nanny:1.15.2-amd64 +docker push rancher/k8s-dns-dnsmasq-nanny:1.15.2-arm64 +docker manifest create rancher/k8s-dns-dnsmasq-nanny:1.15.2 rancher/k8s-dns-dnsmasq-nanny:1.15.2-amd64 rancher/k8s-dns-dnsmasq-nanny:1.15.2-arm64 +docker manifest annotate rancher/k8s-dns-dnsmasq-nanny:1.15.2 rancher/k8s-dns-dnsmasq-nanny:1.15.2-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-dnsmasq-nanny:1.15.2 rancher/k8s-dns-dnsmasq-nanny:1.15.2-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-dnsmasq-nanny:1.15.2 + +#gcr.io/google_containers/k8s-dns-sidecar:1.15.2 +docker pull gcr.io/google_containers/k8s-dns-sidecar-amd64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-sidecar-amd64:1.15.2 rancher/k8s-dns-sidecar:1.15.2-amd64 +docker pull gcr.io/google_containers/k8s-dns-sidecar-arm64:1.15.2 +docker tag gcr.io/google_containers/k8s-dns-sidecar-arm64:1.15.2 rancher/k8s-dns-sidecar:1.15.2-arm64 +docker push rancher/k8s-dns-sidecar:1.15.2-amd64 +docker push rancher/k8s-dns-sidecar:1.15.2-arm64 +docker manifest create rancher/k8s-dns-sidecar:1.15.2 rancher/k8s-dns-sidecar:1.15.2-amd64 rancher/k8s-dns-sidecar:1.15.2-arm64 +docker manifest annotate rancher/k8s-dns-sidecar:1.15.2 rancher/k8s-dns-sidecar:1.15.2-amd64 --arch amd64 +docker manifest annotate rancher/k8s-dns-sidecar:1.15.2 rancher/k8s-dns-sidecar:1.15.2-arm64 --arch arm64 +docker manifest push -p rancher/k8s-dns-sidecar:1.15.2 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/push-master.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/push-master.sh new file mode 100755 index 0000000..87dc7c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/push-master.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +cd $(dirname $0)/.. +mkdir -p dist +./scripts/build +export REPO=${REPO:-rancher} +TAG=master ./scripts/package +docker push $REPO/server:master diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher-namespace.yaml.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher-namespace.yaml.tmpl new file mode 100644 index 0000000..6e31850 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher-namespace.yaml.tmpl @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: cattle-system \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher.yaml.tmpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher.yaml.tmpl new file mode 100644 index 0000000..85a99bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/rancher.yaml.tmpl @@ -0,0 +1,8 @@ +apiVersion: helm.cattle.io/v1 +kind: HelmChart +metadata: + name: rancher + namespace: kube-system +spec: + targetNamespace: cattle-system + chartContent: %{CHART_CONTENT}% diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/release b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/release new file mode 100755 index 0000000..7af0df3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/release @@ -0,0 +1,3 @@ +#!/bin/bash + +exec $(dirname $0)/ci diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/replace-env-value-in-file.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/replace-env-value-in-file.sh new file mode 100755 index 0000000..1bf7d96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/replace-env-value-in-file.sh @@ -0,0 +1,18 @@ +if [ $# -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi + +FILEPATH=$1 +REPLACE_ENV=$2 +REPLACE_VALUE=$3 + +TMPFILE=$(mktemp) + +# Check if equal sign is present +if grep "ENV ${REPLACE_ENV}" $FILEPATH | grep -q '='; then + awk -F'=' 'BEGIN {OFS = FS} /ENV '"${REPLACE_ENV}"'/{$NF="'"${REPLACE_VALUE}"'"} 1' $FILEPATH > $TMPFILE && mv $TMPFILE $FILEPATH +else + awk '/ENV '"${REPLACE_ENV}"'/{$NF="'"${REPLACE_VALUE}"'"} 1' $FILEPATH > $TMPFILE && mv $TMPFILE $FILEPATH +fi + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/retry b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/retry new file mode 100755 index 0000000..99b8977 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/retry @@ -0,0 +1,94 @@ +#!/bin/bash + +cmd="" +timeoutSeconds=60 +sleepSeconds=1 +message="" +messageInterval=5 +startTimeSeconds=$(date +%s) +elapsedSeconds=0 +attempts=0 + +print_usage() { + echo "Usage: $0 [options] " + echo + echo "Attempts to execute a given command periodically until it succeeds or a timeout occurs." + echo + echo "Options:" + echo " -t, --timeout The maximum number of seconds to wait for the command to succeed (default: 60)" + echo " -s, --sleep The number of seconds to sleep for between command attempts (default: 1)" + echo " -m, --message The progress message to print after every attempt (default: '')" + echo " Instances of {{elapsed}} and {{attempts}} in the message will be replaced by total" + echo " elapsed time (in seconds) and total attempts respectively." + echo " -i, --message-interval The number of command attempts to make before each printing of the progress message" + echo " (default: 5)." + echo " -e, --exit-command Optional command to run before exiting (default: '')" + echo +} + +print_progress() { + if [ -n "$message" ]; then + echo "$message" | sed "s/{{attempts}}/$attempts/g; s/{{elapsed}}/$elapsedSeconds/g" + fi +} + +# Parse options and arguments +while [[ $# -gt 0 ]]; do + case "$1" in + -t | --timeout) + shift + timeoutSeconds="$1" + ;; + -s | --sleep) + shift + sleepSeconds="$1" + ;; + -m | --message) + shift + message="$1" + ;; + -i | --message-interval) + shift + messageInterval="$1" + ;; + -e | --exit-command) + shift + exitCommand="$1" + ;; + *) + cmd="$@" + break + ;; + esac + shift +done + +# Error if no command was provided +if [ -z "$cmd" ]; then + print_usage + exit 1 +fi + +# Loop until either the command succeeds or a timeout occurs. +until [ "$elapsedSeconds" -gt "$timeoutSeconds" ] || eval "$cmd"; do + sleep "$sleepSeconds" + + # Increment attempt counter. If we've hit the message interval, print the message + attempts=$((attempts + 1)) + if [ $((attempts % messageInterval)) -eq 0 ]; then + print_progress + fi + + # Recalculate $elapsedSeconds + currentTimeSeconds=$(date +%s) + elapsedSeconds=$((currentTimeSeconds - startTimeSeconds)) +done + +# If we timed out, print the final progress message and exit with code 1. +if [ "$elapsedSeconds" -gt "$timeoutSeconds" ]; then + print_progress + if [ -n "$exitCommand" ]; then + eval "$exitCommand" + fi + exit 1 +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/run b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/run new file mode 100755 index 0000000..0f3b165 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/run @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +echo Starting rancher server +cd $(dirname $0)/.. + +CMD=bin/rancher +if [ ! -x $CMD ]; then + ./scripts/build-server +fi + +if [ ! -z $1 ] && ( [ $1 = "--trace" ] || [ $1 = "--info" ] || [ $1 = "--debug" ] ); then + LOGFLAG=$1 +fi + +rm -rf build/testdata +mkdir -p build/testdata +cd build/testdata +export KUBECONFIG= +export CATTLE_DEV_MODE=yes +export CATTLE_SERVER_URL="https://$(ip route get 8.8.8.8 | awk '{print $7}'):8443" +export CATTLE_BOOTSTRAP_PASSWORD="admin" +export CATTLE_FEATURES="harvester=false" + +######################################################################################################################################### +# DISCLAIMER # +# Copied from https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/hack/dind#L28-L37 # +# Permission granted by Akihiro Suda (https://github.com/rancher/k3d/issues/493#issuecomment-827405962) # +# Moby License Apache 2.0: https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/LICENSE # +######################################################################################################################################### +# only run this if rancher is not running in kubernetes cluster +if [ -f /sys/fs/cgroup/cgroup.controllers ]; then + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + mkdir -p /sys/fs/cgroup/init + xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' <"/sys/fs/cgroup/cgroup.controllers" >"/sys/fs/cgroup/cgroup.subtree_control" +fi + +if [ $CI ]; then + # DISCLAIMER + # This code relies on the fact that our CI pipleine runs on one system at a time. Currently with drone this means that the setting `DRONE_AGENT_CONCURRENCY=1` + + # Attempt to find and stop any previous instances of dapper containers. + # To combat the scenario where drone runners are reused and an instance of rancher is still running. + echo "Checking for running containers from a previous build." + + # gets a list of all docker containers that were started in a CI build. + dapper_containers=$(docker ps --format '{{.Names}}/{{.Label "DRONE_BUILD_NUMBER"}}' --filter 'label=CI=true') + for container_info in $dapper_containers; do + IFS='/' read -ra split_info <<<"$container_info" + + # remove containers that were not created in this build + if [ "${split_info[1]}" != "${DRONE_BUILD_NUMBER}" ]; then + echo "Removing old drone container ${split_info[0]}" + docker stop ${split_info[0]} + docker rm ${split_info[0]} + fi + done +fi + +exec ../../$CMD $LOGFLAG \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/test b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/test new file mode 100755 index 0000000..8c1e59e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/test @@ -0,0 +1,186 @@ +#!/bin/bash +set -e + +cleanup() +{ + EXIT=$? + set +ex + echo Stopping rancher server + kill $RANCHER_RUN_PID + wait $RANCHER_RUN_PID + if [ $PID != -1 ]; then + kill $PID + wait $PID + fi + return $EXIT +} + +# skipping tests for s390x since k3s doesn't support s390x yet +if [ ${ARCH} == s390x ]; then + exit 0 +fi + +cd $(dirname $0)/.. + +echo Running unit tests +CGO_ENABLED=0 go test -cover -tags=test ./pkg/... + +if [ ${ARCH} == arm64 ] || [ ${ARCH} == s390x ]; then + export ETCD_UNSUPPORTED_ARCH=${ARCH} +fi + +TB_ORG=rancher + +if [ -z "${TEST_DIST}" ] || [ "${TEST_DIST}" = "k3s" ]; then + TEST_DIST=k3s + AIRGAP=-airgap + TB_ORG=k3s-io +else + LINUX=.linux +fi + +export DIST=${TEST_DIST} +export SOME_K8S_VERSION=${SOME_K8S_VERSION} +export TB_ORG=${TB_ORG} +export CATTLE_CHART_DEFAULT_URL=${CATTLE_CHART_DEFAULT_URL} + +# Tell Rancher to use the recently-built Rancher cluster agent image. This image is built as part of CI and will be +# copied to the in-cluster registry during test setup below. +source ./scripts/version +export CATTLE_AGENT_IMAGE="rancher/rancher-agent:${AGENT_TAG}" +echo "Using Rancher agent image $CATTLE_AGENT_IMAGE" + +eval "$(grep '^ENV CATTLE_SYSTEM_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_WINS_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_CSI_PROXY_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_KDM_BRANCH' package/Dockerfile | awk '{print "export " $2 "=" $3}')" + +if [ -z "${SOME_K8S_VERSION}" ]; then +# Get the last release for $DIST, which is usually the latest version or an experimental version. +# Previously this would use channels, but channels no longer reflect the latest version since +# https://github.com/rancher/rancher/issues/36827 has added appDefaults. We do not use appDefaults +# here for simplicity's sake, as it requires semver parsing & matching. The last release should +# be good enough for our needs. +export SOME_K8S_VERSION=$(curl -sS https://raw.githubusercontent.com/rancher/kontainer-driver-metadata/release-v2.9/data/data.json | jq -r ".$DIST.releases[-1].version") +fi + +if [ -z "${CATTLE_CHART_DEFAULT_URL}" ]; then +# If `CATTLE_CHART_DEFAULT_URL` is not set, use the `https://github.com/rancher/charts` so GitHub is used instead of +# the default `https://git.rancher.io/charts` to reduce the reliance and load on our Git mirror +export CATTLE_CHART_DEFAULT_URL=https://github.com/rancher/charts +fi + +echo Starting rancher server for test +touch /tmp/rancher.log + +mkdir -p /var/lib/rancher/$DIST/agent/images +grep PodTestImage ./tests/v2prov/defaults/defaults.go | cut -f2 -d'"' > /var/lib/rancher/$DIST/agent/images/pull.txt +grep MachineProvisionImage ./pkg/settings/setting.go | cut -f4 -d'"' >> /var/lib/rancher/$DIST/agent/images/pull.txt +mkdir -p /usr/share/rancher/ui/assets +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -o /usr/share/rancher/ui/assets/rancher-system-agent-amd64 +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-arm64 -o /usr/share/rancher/ui/assets/rancher-system-agent-arm64 +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh -o /usr/share/rancher/ui/assets/system-agent-uninstall.sh + +build_and_run_rancher() +{ + RESTART_COUNT=0 + while sleep 2; do + if [ "$PID" != "-1" ] && [ ! -e /proc/$PID ]; then + echo Rancher died + dump_rancher_logs + echo K3s logs were: + echo -e "-----K3S-LOG-DUMP-START-----" + cat build/testdata/k3s.log | gzip | base64 -w 0 + echo -e "\n-----K3S-LOG-DUMP-END-----" + set +e + echo Attempting to kill K3s + pkill -e k3s + set -e + PID=-1 + if [ "$RESTART_COUNT" = "2" ]; then + echo Rancher died 3 times, aborting + kill -42 $PWRAPPROC + fi + RESTART_COUNT=$((RESTART_COUNT + 1)) + sleep 5 + fi + if [ "$PID" = "-1" ]; then + echo Starting rancher server using run + ./scripts/run >/tmp/rancher.log 2>&1 & + PID=$! + fi + sleep 2 + done +} + +dump_rancher_logs() +{ + echo Rancher logs were + echo -e "-----RANCHER-LOG-DUMP-START-----" + cat /tmp/rancher.log | gzip | base64 -w 0 + echo -e "\n-----RANCHER-LOG-DUMP-END-----" +} + +# Compile Rancher +# This needs to happen before build_and_run_rancher is executed in the background. +# Otherwise, build_and_run_rancher will also compile Rancher, overly elongating the +# time before Rancher is ready and therefore causing flakiness of the health check below. +./scripts/build-server + +# uncomment to get startup logs. Don't leave them on because it slows drone down too +# much +#tail -F /tmp/rancher.log & +#TPID=$! + +trap "exit 1" 42 +PWRAPPROC="$$" + +PID=-1 +build_and_run_rancher & +RANCHER_RUN_PID=$! +trap cleanup exit + +echo "Waiting for Rancher to be healthy" +./scripts/retry --sleep 2 "curl -sf -o /dev/null http://localhost:8080/ping" + +echo "Waiting up to 5 minutes for rancher-webhook deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-webhook was not available after {{elapsed}} seconds" `# Print this progress message` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-system deploy/rancher-webhook &>/dev/null" + +echo "Waiting up to 5 minutes for rancher-provisioning-capi deployment" +./scripts/retry \ + --timeout 300 `# Time out after 300 seconds (5 min)` \ + --sleep 2 `# Sleep for 2 seconds in between attempts` \ + --message-interval 30 `# Print the progress message below every 30 attempts (roughly every minute)` \ + --message "rancher-provisioning-capi was not available after {{elapsed}} seconds" `# Print this progress message` \ + "kubectl --kubeconfig /etc/rancher/k3s/k3s.yaml rollout status -w -n cattle-provisioning-capi-system deploy/capi-controller-manager &>/dev/null" + +#kill $TPID + +echo Running build-integration-setup +./tests/v2/integration/scripts/build-integration-setup + +echo Running integrationsetup +export CATTLE_TEST_CONFIG=$(pwd)/config.yaml # used by integration tests and test setup +./tests/v2/integration/bin/integrationsetup || { + dump_rancher_logs + exit 1 +} + +echo Running go integration tests +CGO_ENABLED=0 go test -v -failfast -p 1 ./tests/v2/integration/... || { + dump_rancher_logs + exit 1 +} + +echo Running tox tests +INT_TESTS_STARTED=true +cd ./tests/integration +tox -e rancher -- -m "not nonparallel" -n $(nproc) +tox -e rancher -- -m nonparallel + +tail -f /tmp/rancher-test.log & \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/validate b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/validate new file mode 100755 index 0000000..abea2e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/validate @@ -0,0 +1,57 @@ +#!/bin/bash +set -e + +echo Running: flake8 python linting + +cd $(dirname $0)/../tests/integration +tox -e flake8 + +cd ../.. + +if ! command -v golangci-lint; then + echo "Skipping validation on ARCH's other than linux amd64" + exit +fi + +echo Running: golangci-lint +golangci-lint run + +echo Tidying up modules +cd pkg/apis/ +go mod tidy +cd ../.. +go mod tidy + +echo Verifying modules +go mod verify + +dirty_files="$(git status --porcelain --untracked-files=no)" +if [ -n "$dirty_files" ]; then + echo "Encountered dirty repo! Aborting." + echo "If you're seeing this, it means there are uncommitted changes in the repo." + echo "If you're seeing this in CI, it probably means that your Go modules aren't tidy, or more generally that running" + echo "validation would result in changes to the repo. Make sure you're up to date with the upstream branch and run" + echo "'go mod tidy' and commit the changes, if any. The offending changed files are as follows:" + echo "$dirty_files" + exit 1 +fi + +# Check diff between ./go.mod and ./pkg/apis/go.mod +badmodule="false" +while read -r module tag; do + # Get tag from module in ./go.mod + roottag=$(cat go.mod | sed '1,/^require/d' | grep "${module} " | awk '{ print $2 }') + echo "${module}:" + echo "${tag} (./pkg/apis/go.mod)" + echo "${roottag} (./go.mod)" + # Compare with tag from module in ./pkg/apis/go.mod + if [[ "${tag}" != "${roottag}" ]]; then + echo "${module} is different ("${tag}" vs "${roottag}")" + badmodule="true" + fi +done <<< $(cat pkg/apis/go.mod | sed '1,/require/d' | head -n -1 | grep -v indirect | grep rancher | awk '{ print $1,$2 }') + +if [[ "${badmodule}" == "true" ]]; then + echo "Diff found between ./go.mod and ./pkg/apis/go.mod" + exit 1 +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/version b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/version new file mode 100755 index 0000000..fa99bf9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/version @@ -0,0 +1,86 @@ +#!/bin/bash +shopt -s extglob + +if [ -n "$(git status --porcelain --untracked-files=no)" ]; then + DIRTY="-dirty" +fi + +COMMIT=$(git rev-parse --short HEAD) +COMMIT_DATE=$(git --no-pager log -1 --format='%ct') +COMMIT_BRANCH=$(git rev-parse --abbrev-ref HEAD | sed -E 's/[^a-zA-Z0-9]+/-/g') +GIT_TAG=${GIT_TAG:-$(git tag -l --contains HEAD | head -n 1)} +LAST_TAG=${GIT_TAG:-'v0.0.0'} + +if [ -n "$GIT_TAG" ]; then + TAG=$GIT_TAG +fi + +if [[ -z "$DIRTY" && -n "$GIT_TAG" ]]; then + VERSION=$GIT_TAG +else + VERSION="${COMMIT}${DIRTY}" +fi + +if [ -z "$GIT_TAG" ] && [ -n "$GIT_COMMIT" ] && [ -n "$GIT_BRANCH" ]; then + APP_VERSION=${GIT_BRANCH/release\//}-${GIT_COMMIT}-head +else + APP_VERSION=$VERSION +fi + +# Chart tag. +if [[ -z "${DIRTY}" && -n "${GIT_TAG}" ]]; then + CHART_VERSION="${GIT_TAG}" +elif [[ "$DIRTY" ]]; then + CHART_VERSION="${LAST_TAG}${DIRTY}.commit-${COMMIT}" +else + CHART_VERSION="${LAST_TAG}-${COMMIT_DATE}.commit-${COMMIT}.${COMMIT_BRANCH}" +fi + +# Drop the v prefix for Chart Version to follow existing pattern. +CHART_VERSION="$(echo ${CHART_VERSION} | sed -E 's/^v//' | sed -e 's/^\(.\{55\}\).*/\1/')" + +# Chart Repo - Target Repo for releases. +case $CHART_VERSION in + *-alpha*) # All alpha tags + CHART_REPO="alpha" ;; + *-rc*) # All rc tags + CHART_REPO="latest" ;; + +([0-9]).+([0-9]).+([0-9])) # All release tags + CHART_REPO="latest" ;; + *) # Anything else - Future use + CHART_REPO="dev" ;; +esac + +if [ -z "$ARCH" ]; then + ARCH=amd64 +fi + +SUFFIX="" +[ "${ARCH}" != "amd64" ] && SUFFIX="_${ARCH}" + +TAG=${TAG:-${VERSION}${SUFFIX}} +REPO=${REPO:-rancher} + +if echo $TAG | grep -q dirty; then + TAG=dev +fi + +AGENT_TAG="$TAG" +if [ "$AGENT_TAG" = dev ]; then + AGENT_TAG="master-head" +fi + +echo "ARCH: $ARCH" +echo "CHART_REPO: $CHART_REPO" +echo "CHART_VERSION: $CHART_VERSION" +echo "VERSION: $VERSION" +echo "APP_VERSION: $APP_VERSION" +echo "SUFFIX: $SUFFIX" +echo "REPO: $REPO" +echo "TAG: $TAG" +echo "AGENT_TAG: $AGENT_TAG" +echo "CATTLE_KDM_BRANCH: $CATTLE_KDM_BRANCH" +echo "DIRNAME: $(dirname $0)" +echo "GIT_TAG: $GIT_TAG" +echo "COMMIT: $COMMIT" +echo "BRANCH: $BRANCH" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build-agent.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build-agent.ps1 new file mode 100644 index 0000000..1c52349 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build-agent.ps1 @@ -0,0 +1,16 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Invoke-Script -File "$PSScriptRoot\version.ps1" + +$DIR_PATH = Split-Path -Parent $MyInvocation.MyCommand.Definition +$SRC_PATH = (Resolve-Path "$DIR_PATH\..\..").Path +cd $SRC_PATH + +$null = New-Item -Force -ItemType Directory -Path bin -ErrorAction Ignore +$env:GOARCH=$env:ARCH +$env:GOOS='windows' +$env:CGO_ENABLED=0 +$LINKFLAGS = ('-X main.VERSION={0} -s -w -extldflags "-static"' -f $env:VERSION) +go build -tags k8s -ldflags $LINKFLAGS -o .\bin\agent.exe .\cmd\agent diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build.ps1 new file mode 100644 index 0000000..e05ac6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/build.ps1 @@ -0,0 +1,6 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Log-Info "Running: build-agent" +Invoke-Script -File "$PSScriptRoot\build-agent.ps1" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/ci.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/ci.ps1 new file mode 100644 index 0000000..6264c56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/ci.ps1 @@ -0,0 +1,8 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Invoke-Script -File "$PSScriptRoot\build.ps1" +Invoke-Script -File "$PSScriptRoot\test.ps1" +Invoke-Script -File "$PSScriptRoot\package.ps1" + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/entry.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/entry.ps1 new file mode 100644 index 0000000..e30571a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/entry.ps1 @@ -0,0 +1,13 @@ +$ErrorActionPreference = 'Stop' + +$SCRIPT_PATH = ("{0}\{1}.ps1" -f $PSScriptRoot, $Args[0]) +if (Test-Path $SCRIPT_PATH -ErrorAction Ignore) +{ + Invoke-Expression -Command $SCRIPT_PATH + if (-not $?) { + exit 255 + } + exit 0 +} + +Start-Process -Wait -FilePath $Args[0] -ArgumentList $Args[1..$Args.Length] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/package.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/package.ps1 new file mode 100644 index 0000000..c9bbfea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/package.ps1 @@ -0,0 +1,58 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Invoke-Script -File "$PSScriptRoot\version.ps1" + +$DIR_PATH = Split-Path -Parent $MyInvocation.MyCommand.Definition +$SRC_PATH = (Resolve-Path "$DIR_PATH\..\..").Path +cd $SRC_PATH\package\windows + +$TAG = $env:TAG +if (-not $TAG) { + $TAG = ('{0}{1}' -f $env:VERSION, $env:SUFFIX) +} +$REPO = $env:REPO +if (-not $REPO) { + $REPO = "rancher" +} + +if ($TAG | Select-String -Pattern 'dirty') { + $TAG = "dev" +} + +if ($env:DRONE_TAG) { + $TAG = $env:DRONE_TAG +} + +$null = Copy-Item -Force -Path "$SRC_PATH\bin\agent.exe" -Destination . + +# Get release id as image tag suffix +$HOST_RELEASE_ID = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' -ErrorAction Ignore).ReleaseId +$RELEASE_ID = $env:RELEASE_ID +if (-not $RELEASE_ID) { + $RELEASE_ID = $HOST_RELEASE_ID +} + +$AGENT_IMAGE = ('{0}/rancher-agent:{1}-windows-{2}' -f $REPO, $TAG, $RELEASE_ID) + +$ARCH = $env:ARCH +if ($RELEASE_ID -eq $HOST_RELEASE_ID) { + docker build ` + --build-arg SERVERCORE_VERSION=$RELEASE_ID ` + --build-arg ARCH=$ARCH ` + --build-arg VERSION=$TAG ` + -t $AGENT_IMAGE ` + -f Dockerfile.agent . +} else { + docker build ` + --isolation hyperv ` + --build-arg SERVERCORE_VERSION=$RELEASE_ID ` + --build-arg ARCH=$ARCH ` + --build-arg VERSION=$TAG ` + -t $AGENT_IMAGE ` + -f Dockerfile.agent . +} + +# $AGENT_IMAGE | Out-File -Encoding ascii -Force -FilePath "$SRC_PATH\dist\images" +Log-Info "Built $AGENT_IMAGE`n" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/release.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/release.ps1 new file mode 100644 index 0000000..ed4e875 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/release.ps1 @@ -0,0 +1,5 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Invoke-Script -File "$PSScriptRoot\ci.ps1" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/test.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/test.ps1 new file mode 100644 index 0000000..7f496ce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/test.ps1 @@ -0,0 +1,16 @@ +$ErrorActionPreference = 'Stop' + +Import-Module -WarningAction Ignore -Name "$PSScriptRoot\utils.psm1" + +Invoke-Script -File "$PSScriptRoot\version.ps1" + +$DIR_PATH = Split-Path -Parent $MyInvocation.MyCommand.Definition +$SRC_PATH = (Resolve-Path "$DIR_PATH\..\..").Path +cd $SRC_PATH + +$env:GOARCH=$env:ARCH +$env:GOOS='windows' +go test -v -cover -tags 'test' ./cmd/agent/... +if (-not $?) { + Log-Fatal "go test failed" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/utils.psm1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/utils.psm1 new file mode 100644 index 0000000..373071a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/utils.psm1 @@ -0,0 +1,59 @@ +$ErrorActionPreference = 'Stop' +$WarningPreference = 'SilentlyContinue' +$VerbosePreference = 'SilentlyContinue' +$DebugPreference = 'SilentlyContinue' +$InformationPreference = 'SilentlyContinue' + +function Log-Info +{ + Write-Host -NoNewline -ForegroundColor Blue "INFO: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($Args -join " ")) +} + +function Log-Warn +{ + Write-Host -NoNewline -ForegroundColor DarkYellow "WARN: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + +function Log-Error +{ + Write-Host -NoNewline -ForegroundColor DarkRed "ERRO " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) +} + + +function Log-Fatal +{ + Write-Host -NoNewline -ForegroundColor DarkRed "FATA: " + Write-Host -ForegroundColor Gray ("{0,-44}" -f ($args -join " ")) + + throw "EXITED" +} + +function Invoke-Script +{ + param ( + [parameter(Mandatory = $true)] [string]$File + ) + + try { + Invoke-Expression -Command $File + if (-not $?) { + throw "CALLFAILED" + } + } catch { + $Msg = $_.Exception.Message + if ($Msg -eq "CALLFAILED") { + Log-Fatal "Failed to invoke $File" + } else { + Log-Fatal "Could not invoke $File, $Msg" + } + } +} + +Export-ModuleMember -Function Log-Info +Export-ModuleMember -Function Log-Warn +Export-ModuleMember -Function Log-Error +Export-ModuleMember -Function Log-Fatal +Export-ModuleMember -Function Invoke-Script diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/version.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/version.ps1 new file mode 100644 index 0000000..94ed3c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/scripts/windows/version.ps1 @@ -0,0 +1,24 @@ +$ErrorActionPreference = 'Stop' + +$DIRTY = "" +if ("$(git status --porcelain --untracked-files=no)") { + $DIRTY = "-dirty" +} + +$COMMIT = $(git rev-parse --short HEAD) +$GIT_TAG = $env:DRONE_TAG +if (-not $GIT_TAG) { + $GIT_TAG = $(git tag -l --contains HEAD | Select-Object -First 1) +} + +$VERSION = "${COMMIT}${DIRTY}" +if ((-not $DIRTY) -and ($GIT_TAG)) { + $VERSION = "${GIT_TAG}" +} +$env:VERSION = $VERSION + +$ARCH = $env:ARCH +if (-not $ARCH) { + $ARCH = "amd64" +} +$env:ARCH = $ARCH diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/README.md new file mode 100644 index 0000000..e9f99fa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/README.md @@ -0,0 +1,38 @@ +# Rancher Test Framework + +The Rancher Test Framework provides tools for writing integrations and validation tests. The framework manages interactions with the external services being tested and aids in cleaning up resources after a test is completed. The framework is organized into three disciplines: framework, clients, and extensions. The framework consists of a few core libraries used to make it easy to write homologous tests. See [extensions](#extensions) and [clients](#clients) for more details. + +## Requirements + +--- + +#### Integration +To run rancher integration tests you will need: +- a running instance of rancher with an accessible url +- a rancher access token for the admin user +- [golang 1.22](https://go.dev/doc/install) +- [k3d](https://k3d.io/v5.1.0/) + +#### Validation +Validation tests have the same requirements as integration tests however different suites may need credentials for cloud providers. Check the configs for your test suite for details. + +## Concepts + +--- + +### Integration vs Validation + +Integration tests - Don't require any external configuration or access to any other external services. These should also be short running as they will run on every PR within CI. Integration tests do not need access keys to cloud providers to run. + +Validation tests - Require access to external services, and needs to a config file to run them. + +## Framework + +Shepherd is our testing framework and is located https://github.com/rancher/shepherd. For more info please visit the repo. + + +## How to Write Tests + +--- + +Tests should be created under `tests/v2/integration` or `tests/v2/validation`, see [Integration vs Validation](#integration-vs-validation) for details. Tests can be grouped into files and packages however the developer sees fit. When grouping tests a developer should make sure the test will be easy to find for the next developer and that it is grouped with other tests that would be run at the same time. Within the files tests should be grouped into [Suites](https://pkg.go.dev/github.com/stretchr/testify/suite). A suite should share clients and a session across all it's tests. A Suite's tests should all be testing the same functionality and reuse suite resources. For example if we were writing tests that ensure project roles have appropriate access to project resources, a suite could contain all tests for every role and share a project across all tests. This will save time because each test will not need to create a project. A test name should not contain `/` as this denotes test suites. Including this character causes confusion on the structure of the test. Tests should always use the framework clients when possible, this will ensure that any resources created by tests will be cleaned up and not interfere with other tests. A test is responsible for cleaning up any resource it creates fully before the next test is run. See [Sessions](#sessions) for how to track resources in tests. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/Makefile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/Makefile new file mode 100644 index 0000000..7d0174b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/Makefile @@ -0,0 +1,2 @@ +controller-test: + ./run_controller_tests.sh \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/README.md new file mode 100644 index 0000000..0f749bc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/README.md @@ -0,0 +1,110 @@ +# Controller Integration Tests + +## Summary + +The controller integration tests make use of [envtest](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest). It starts a local control plane that controllers can be registered to it and tested against. It creates an instance of etcd and the Kubernetes API server, but without other components, making it lightweight and fast. +The library is maintained by kubebuilder. For more information see: https://book.kubebuilder.io/reference/envtest.html + +## Dependencies + +To run the tests, [`setup-envtest`](https://pkg.go.dev/sigs.k8s.io/controller-runtime/tools/setup-envtest) needs to be installed. That can be done by doing: +``` +go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest +``` + +## Running Integration Tests + +### Makefile +All tests can be run with `make controller-test`. That runs the bash script [`run_controller_tests.sh`](./run_controller_tests.sh). + +### Manually + +After installing `setup-envtest`, export the environment variable `KUBEBUILDER_ASSETS` to point to where setup-envtest was installed using the following: +``` +export KUBEBUILDER_ASSETS=$(setup-envtest use -p path) +``` + +Note: You can add a k8s version to the export command if you want to test a specific version. Otherwise it will use the latest version installed. + +After setting the environment variable, running the tests is the same as any other go test and can be run with `go test`. + +## Developing Tests + +All integration tests have the following initial steps in common: + +1. Start a local kubernetes server + +``` +testEnv = &envtest.Environment{} +restCfg, err := testEnv.Start() +``` + +2. Create the CRDs + +``` +import "github.com/rancher/wrangler/v3/pkg/crd" + +factory, err := crd.NewFactoryFromClient(restCfg) +err = factory.BatchCreateCRDs(ctx, +crd.CRD{ + SchemaObject: , + NonNamespace: , +}) +``` + +After those two initial steps, the process depends on the kind of controller being used. + +### Wrangler Controllers + +The [feature controller](feature/feature_test.go) is an example of a wrangler controller. It is used for the examples below. + +1. Create a wrangler context + +``` +import "github.com/rancher/rancher/pkg/wrangler" + +wranglerContext, err := wrangler.NewContext(ctx, nil, restCfg) +``` + +2. Register the controller + +``` +import "github.com/rancher/rancher/pkg/controllers/management/feature" + +feature.Register(ctx, wranglerContext) +``` + +3. Create and start the controller factory + +``` +import "k8s.io/apimachinery/pkg/runtime/schema" + +controllerFactory := wranglerContext.ControllerFactory.ForResourceKind(schema.GroupVersionResource{ + Group: "management.cattle.io", + Version: "v3", + Resource: "features", +}, "Feature", false) +err := controllerFactory.Start(ctx, 1) +``` + +4. (Optional) Start any needed resource caches + +For controllers that have caches for other resources, those need to be created and started as well. + +``` +_, err := wranglerContext.ControllerFactory.SharedCacheFactory().ForKind(schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "NodeDriver", +}) +err = wranglerContext.ControllerFactory.SharedCacheFactory().StartGVK(s.ctx, schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "NodeDriver", +}) +``` + +Now the controller has been registered and started, it can be used for any operations like `wranglerContext.Mgmt.Feature().Get("feature-name", metav1.GetOptions{})` + +### Norman Controller +TODO \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/authconfig/authconfig_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/authconfig/authconfig_test.go new file mode 100644 index 0000000..d2aa3b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/authconfig/authconfig_test.go @@ -0,0 +1,165 @@ +package authconfig_test + +import ( + "context" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/controllers/management/auth" + "github.com/rancher/rancher/pkg/multiclustermanager" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/rancher/tests/controllers/common" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "testing" + "time" +) + +type AuthConfigSuite struct { + suite.Suite + ctx context.Context + cancel context.CancelFunc + testEnv *envtest.Environment + managementContext *config.ManagementContext + wranglerContext *wrangler.Context +} + +func TestAuthConfigSuite(t *testing.T) { + suite.Run(t, new(AuthConfigSuite)) +} + +func (s *AuthConfigSuite) SetupSuite() { + t := s.T() + s.ctx, s.cancel = context.WithCancel(context.Background()) + + // Load CRD from YAML for REST Client + s.testEnv = &envtest.Environment{} + restCfg, err := s.testEnv.Start() + assert.NoError(t, err) + assert.NotNil(t, restCfg) + + // Create CRDs + factory, err := crd.NewFactoryFromClient(restCfg) + assert.NoError(t, err) + + err = factory.BatchCreateCRDs(s.ctx, + crd.CRD{ + SchemaObject: v3.Token{}, + NonNamespace: true, + }, + crd.CRD{ + SchemaObject: v3.AuthConfig{}, + NonNamespace: true, + }, + ).BatchWait() + assert.NoError(t, err) + + // Create the wrangler and management contexts + wranglerContext, err := wrangler.NewContext(s.ctx, nil, restCfg) + assert.NoError(t, err) + + scaledContext, clusterManager, _, err := multiclustermanager.BuildScaledContext(s.ctx, wranglerContext, &multiclustermanager.Options{}) + assert.NoError(t, err) + s.managementContext, err = scaledContext.NewManagementContext() + assert.NoError(t, err) + + // Register the auth controller + auth.RegisterEarly(s.ctx, s.managementContext, clusterManager) + + // Start controllers + common.StartNormanControllers(s.ctx, t, s.managementContext, + schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "AuthConfig", + }, + ) + + // Start caches + common.StartWranglerCaches(s.ctx, t, s.managementContext.Wrangler, + schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "Token", + }, + ) +} + +func (s *AuthConfigSuite) TestTokensCleanup() { + t := s.T() + + const ( + tick = 1 * time.Second + duration = 10 * time.Second + numOfTokens = 1000 + authProvider = "openldap" + ) + + // create the AuthConfig for the authProvider + _, err := s.managementContext.Management.AuthConfigs("").Create(&v3.AuthConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: authProvider, + }, + Type: client.OpenLdapConfigType, + Enabled: true, + }) + assert.NoError(t, err) + + // create some tokens for the authProvider + for i := 0; i < numOfTokens; i++ { + _, err := s.managementContext.Management.Tokens("").Create(&v3.Token{ + ObjectMeta: metav1.ObjectMeta{GenerateName: "t-"}, + AuthProvider: authProvider, + }) + assert.NoError(t, err) + } + + // and also some local tokens + for i := 0; i < numOfTokens; i++ { + _, err := s.managementContext.Management.Tokens("").Create(&v3.Token{ + ObjectMeta: metav1.ObjectMeta{GenerateName: "t-"}, + AuthProvider: "local", + }) + assert.NoError(t, err) + } + + t.Logf("created %d tokens\n", numOfTokens) + + // disable the provider, setting the cleanup annotation (eventually because of retries) + authConfig, err := s.managementContext.Management.AuthConfigs("").Get(authProvider, metav1.GetOptions{}) + assert.NoError(t, err) + + authConfig.Enabled = false + authConfig.Annotations = map[string]string{auth.CleanupAnnotation: auth.CleanupUnlocked} + authConfig, err = s.managementContext.Management.AuthConfigs("").Update(authConfig) + assert.NoError(t, err) + + // check that all the authProvider tokens are deleted + ok := assert.EventuallyWithT(t, func(c *assert.CollectT) { + tokens, err := s.managementContext.Management.Tokens("").List(metav1.ListOptions{}) + assert.NoError(c, err) + assert.NotNil(c, tokens) + + var remainingTokens int + for _, token := range tokens.Items { + if token.AuthProvider == authProvider { + remainingTokens++ + } + } + + t.Logf("remaining %d tokens\n", remainingTokens) + assert.Zero(c, remainingTokens) + }, duration, tick) + + assert.True(t, ok, "secrets were left over after disabling auth configuration") +} + +func (s *AuthConfigSuite) TearDownSuite() { + s.cancel() + err := s.testEnv.Stop() + assert.NoError(s.T(), err, "error shutting down environment") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/common/common.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/common/common.go new file mode 100644 index 0000000..301ec65 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/common/common.go @@ -0,0 +1,42 @@ +package common + +import ( + "context" + "testing" + + "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" +) + +func RegisterCRDs(ctx context.Context, t *testing.T, r *rest.Config, crds ...crd.CRD) { + factory, err := crd.NewFactoryFromClient(r) + assert.NoError(t, err) + + err = factory.BatchCreateCRDs(ctx, crds...).BatchWait() + assert.NoError(t, err) +} + +func StartNormanControllers(ctx context.Context, t *testing.T, m *config.ManagementContext, gvk ...schema.GroupVersionKind) { + controllers := []controller.SharedController{} + for _, g := range gvk { + c, err := m.ControllerFactory.ForKind(g) + assert.NoError(t, err) + controllers = append(controllers, c) + } + for _, c := range controllers { + err := c.Start(ctx, 1) + assert.NoError(t, err) + } +} + +func StartWranglerCaches(ctx context.Context, t *testing.T, w *wrangler.Context, gvk ...schema.GroupVersionKind) { + for _, g := range gvk { + err := w.ControllerFactory.SharedCacheFactory().StartGVK(ctx, g) + assert.NoError(t, err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/feature/feature_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/feature/feature_test.go new file mode 100644 index 0000000..ca6d34f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/feature/feature_test.go @@ -0,0 +1,187 @@ +package feature_test + +import ( + "context" + "testing" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/controllers/management/feature" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +type FeatureTestSuite struct { + suite.Suite + ctx context.Context + cancel context.CancelFunc + testEnv *envtest.Environment + wranglerContext *wrangler.Context +} + +const ( + tick = 1 * time.Second + duration = 10 * time.Second +) + +var ( + truePtr = &[]bool{true}[0] +) + +func (s *FeatureTestSuite) SetupSuite() { + s.ctx, s.cancel = context.WithCancel(context.TODO()) + // Load CRD from YAML for REST Client + s.testEnv = &envtest.Environment{} + restCfg, err := s.testEnv.Start() + assert.NoError(s.T(), err) + assert.NotNil(s.T(), restCfg) + + // Create CRDs + factory, err := crd.NewFactoryFromClient(restCfg) + assert.NoError(s.T(), err) + err = factory.BatchCreateCRDs(s.ctx, + crd.CRD{ + SchemaObject: v3.Feature{}, + NonNamespace: true, + }, + crd.CRD{ + SchemaObject: v3.NodeDriver{}, + NonNamespace: true, + }, + ).BatchWait() + assert.NoError(s.T(), err) + + // Create the wrangler context + s.wranglerContext, err = wrangler.NewContext(s.ctx, nil, restCfg) + assert.NoError(s.T(), err) + + // Register the feature controller + feature.Register(s.ctx, s.wranglerContext) + + // Create and start the feature controller factory + cf := s.wranglerContext.ControllerFactory.ForResourceKind(schema.GroupVersionResource{ + Group: "management.cattle.io", + Version: "v3", + Resource: "features", + }, "Feature", false) + assert.NoError(s.T(), err) + err = cf.Start(s.ctx, 1) + assert.NoError(s.T(), err) + + // Start the NodeDriver cache + _, err = s.wranglerContext.ControllerFactory.SharedCacheFactory().ForKind(schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "NodeDriver", + }) + assert.NoError(s.T(), err) + err = s.wranglerContext.ControllerFactory.SharedCacheFactory().StartGVK(s.ctx, schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "NodeDriver", + }) + assert.NoError(s.T(), err) + + // The feature controller checks the harvester NodeDriver, so it needs to exist + n, err := s.wranglerContext.Mgmt.NodeDriver().Create(&v3.NodeDriver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "harvester", + }, + }) + assert.NoError(s.T(), err) + assert.NotNil(s.T(), n) + + // Initialize Features - this creates all feature resources used by rancher + features.InitializeFeatures(s.wranglerContext.Mgmt.Feature(), "") +} + +func (s *FeatureTestSuite) TestHarvesterFeature() { + t := assert.New(s.T()) + // If the harvester feature is enabled, it needs to enable the NodeDriver as well + n, err := s.wranglerContext.Mgmt.NodeDriver().Get("harvester", metav1.GetOptions{}) + t.NoError(err) + t.NotNil(n) + + nCopy := n.DeepCopy() + nCopy.Spec.Active = false + _, err = s.wranglerContext.Mgmt.NodeDriver().Update(nCopy) + t.NoError(err) + + s.triggerFeatureSync("harvester") + + t.EventuallyWithT(func(c *assert.CollectT) { + nd, err := s.wranglerContext.Mgmt.NodeDriver().Get("harvester", metav1.GetOptions{}) + assert.NoError(c, err) + assert.True(c, nd.Spec.Active) + }, duration, tick, "harvester feature has not been enabled") + +} + +func (s *FeatureTestSuite) TestHarvesterBaremetalFeature() { + t := assert.New(s.T()) + // Set harvester baremetal feature to true + features.GetFeatureByName("harvester-baremetal-container-workload").Set(true) + + // Harvester feature should get set if baremetal feature is enabled + h, err := s.wranglerContext.Mgmt.Feature().Get("harvester", metav1.GetOptions{}) + t.NoError(err) + t.NotNil(h) + + hCopy := h.DeepCopy() + h.Spec.Value = nil + _, err = s.wranglerContext.Mgmt.Feature().Update(hCopy) + t.NoError(err) + + // Baremetal feature gets annotation added if it's not there + hf, err := s.wranglerContext.Mgmt.Feature().Get("harvester-baremetal-container-workload", metav1.GetOptions{}) + t.NoError(err) + t.NotNil(hf) + + harvesterFeature := hf.DeepCopy() + harvesterFeature.Annotations = nil + _, err = s.wranglerContext.Mgmt.Feature().Update(harvesterFeature) + t.NoError(err) + + // Check that feature.cattle.io/experimental gets set to true by the controller + t.EventuallyWithT(func(c *assert.CollectT) { + f, err := s.wranglerContext.Mgmt.Feature().Get("harvester-baremetal-container-workload", metav1.GetOptions{}) + assert.NoError(c, err) + assert.Equal(c, v3.ExperimentalFeatureValue, f.Annotations[v3.ExperimentalFeatureKey]) + }, duration, tick, "annotation feature.cattle.io/experimental has not changed to true") + + // Check that harvester feature gets set to true + t.EventuallyWithT(func(c *assert.CollectT) { + nd, err := s.wranglerContext.Mgmt.Feature().Get("harvester", metav1.GetOptions{}) + assert.NoError(c, err) + assert.Equal(c, truePtr, nd.Spec.Value) + }, duration, tick, "harvester feature has not been enabled") +} + +// triggerFeatureSync updates an annotation on the feature triggering a sync to occur +// useful when testing that a non-feature setting gets modified +func (s *FeatureTestSuite) triggerFeatureSync(name string) { + h, _ := s.wranglerContext.Mgmt.Feature().Get(name, metav1.GetOptions{}) + hCopy := h.DeepCopy() + if hCopy.Annotations == nil { + hCopy.Annotations = map[string]string{"test": "test"} + } else { + hCopy.Annotations["test"] = "test" + } + s.wranglerContext.Mgmt.Feature().Update(hCopy) +} + +func (s *FeatureTestSuite) TearDownSuite() { + s.cancel() + err := s.testEnv.Stop() + assert.NoError(s.T(), err) +} + +func TestFeatureTestSuite(t *testing.T) { + suite.Run(t, new(FeatureTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/globalroles/globalrole_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/globalroles/globalrole_test.go new file mode 100644 index 0000000..21950aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/globalroles/globalrole_test.go @@ -0,0 +1,348 @@ +package globalroles_integration_test + +import ( + "context" + "reflect" + "testing" + "time" + + "github.com/rancher/rancher/pkg/controllers/management/auth/globalroles" + v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/multiclustermanager" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/rancher/tests/controllers/common" + "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/envtest" +) + +type GlobalRoleTestSuite struct { + suite.Suite + ctx context.Context + cancel context.CancelFunc + testEnv *envtest.Environment + managementContext *config.ManagementContext +} + +const ( + tick = 1 * time.Second + duration = 20 * time.Second +) + +var ( + getPodRule = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + } + readNodeRule = rbacv1.PolicyRule{ + Verbs: []string{"get"}, + APIGroups: []string{""}, + Resources: []string{"nodes"}, + } + editTemplates = rbacv1.PolicyRule{ + Verbs: []string{"edit"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"templates"}, + } + globalRoleLabel = "authz.management.cattle.io/globalrole" + crNameLabel = "authz.management.cattle.io/cr-name" + grOwnerLabel = "authz.management.cattle.io/gr-owner" +) + +func (s *GlobalRoleTestSuite) SetupSuite() { + s.ctx, s.cancel = context.WithCancel(context.TODO()) + + // Start envtest + s.testEnv = &envtest.Environment{} + restCfg, err := s.testEnv.Start() + assert.NoError(s.T(), err) + assert.NotNil(s.T(), restCfg) + + // Register CRDs + common.RegisterCRDs(s.ctx, s.T(), restCfg, + crd.CRD{ + SchemaObject: v3.GlobalRole{}, + NonNamespace: true, + Status: true, + }, + crd.CRD{ + SchemaObject: v3.GlobalRoleBinding{}, + NonNamespace: true, + }) + + // Create wrangler context + wranglerContext, err := wrangler.NewContext(s.ctx, nil, restCfg) + assert.NoError(s.T(), err) + + // Create management context + scaledContext, clusterManager, _, err := multiclustermanager.BuildScaledContext(s.ctx, wranglerContext, &multiclustermanager.Options{}) + assert.NoError(s.T(), err) + s.managementContext, err = scaledContext.NewManagementContext() + assert.NoError(s.T(), err) + + // Register controller + globalroles.Register(s.ctx, s.managementContext, clusterManager) + + // Start controllers + common.StartNormanControllers(s.ctx, s.T(), s.managementContext, + schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "GlobalRoleBinding", + }, + schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "GlobalRole", + }) + + // Start caches + common.StartWranglerCaches(s.ctx, s.T(), s.managementContext.Wrangler, + schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRole", + }, + schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "ClusterRoleBinding", + }, + schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "Role", + }, + schema.GroupVersionKind{ + Group: "rbac.authorization.k8s.io", + Version: "v1", + Kind: "RoleBinding", + }, + schema.GroupVersionKind{ + Group: "management.cattle.io", + Version: "v3", + Kind: "GlobalRole", + }, + schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Namespace", + }) +} + +func (s *GlobalRoleTestSuite) TearDownSuite() { + s.cancel() + err := s.testEnv.Stop() + assert.NoError(s.T(), err) +} + +func (s *GlobalRoleTestSuite) TestCreateGlobalRole() { + ns1 := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace1", + }, + } + ns2 := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace2", + }, + } + globalDataNS := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-global-data", + }, + } + s.managementContext.Core.Namespaces("").Create(&ns1) + s.managementContext.Core.Namespaces("").Create(&ns2) + s.managementContext.Core.Namespaces("").Create(&globalDataNS) + + tests := []struct { + name string + globalRole v3.GlobalRole + roles []rbacv1.Role + clusterRole rbacv1.ClusterRole + }{ + // NOTE: These test can be run in parallel only if the global role names are unique + { + name: "create primary cluster role given cr-name", + globalRole: v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + crNameLabel: "cr-name", + }, + Name: "cr-name-gr", + }, + Rules: []rbacv1.PolicyRule{getPodRule}, + }, + clusterRole: rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cr-name", + }, + Rules: []rbacv1.PolicyRule{getPodRule}, + }, + }, + { + name: "create primary cluster role with generated name", + globalRole: v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "generated-name-gr", + }, + Rules: []rbacv1.PolicyRule{getPodRule}, + }, + clusterRole: rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-globalrole-generated-name-gr", + }, + Rules: []rbacv1.PolicyRule{getPodRule}, + }, + }, + { + name: "global role with catalog role", + globalRole: v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "catalog-role-gr", + }, + Rules: []rbacv1.PolicyRule{getPodRule, editTemplates}, + }, + clusterRole: rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-globalrole-catalog-role-gr", + }, + Rules: []rbacv1.PolicyRule{getPodRule, editTemplates}, + }, + roles: []rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "catalog-role-gr-global-catalog", + Namespace: "cattle-global-data", + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"catalogtemplates"}, + Verbs: []string{"edit"}, + }, + }, + }, + }, + }, + { + name: "global role with namespaced rules", + globalRole: v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespaced-rules-gr", + }, + NamespacedRules: map[string][]rbacv1.PolicyRule{ + "namespace1": {getPodRule, readNodeRule}, + "namespace2": {getPodRule}, + }, + }, + clusterRole: rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cattle-globalrole-namespaced-rules-gr", + }, + }, + roles: []rbacv1.Role{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "namespaced-rules-gr-namespace1", + Namespace: "namespace1", + Labels: map[string]string{ + grOwnerLabel: "namespaced-rules-gr", + }, + }, + Rules: []rbacv1.PolicyRule{getPodRule, readNodeRule}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "namespaced-rules-gr-namespace2", + Namespace: "namespace2", + Labels: map[string]string{ + grOwnerLabel: "namespaced-rules-gr", + }, + }, + Rules: []rbacv1.PolicyRule{getPodRule}, + }, + }, + }, + } + for _, test := range tests { + test := test + s.Run(test.name, func() { + t := s.T() + t.Parallel() + gr, err := s.managementContext.Management.GlobalRoles("").Create(&test.globalRole) + assert.NoError(t, err) + + // testenv does not run any garbage collection, objects won't get deleted. + // To ensure that deletion would work, instead we check the created resources have the right OwnerReference + grOwnerRef := metav1.OwnerReference{ + APIVersion: "management.cattle.io/v3", + Kind: "GlobalRole", + Name: test.globalRole.Name, + UID: gr.UID, + } + + // Create Global Role + assert.EventuallyWithT(t, func(c *assert.CollectT) { + gr, err = s.managementContext.Management.GlobalRoles("").Get(test.globalRole.Name, metav1.GetOptions{}) + assert.NoError(c, err) + assert.NotNil(c, gr) + assert.NotNil(c, gr.Status) + + // Once status is completed, all necessary backing resources should have been created + assert.Equal(c, globalroles.SummaryCompleted, gr.Status.Summary) + }, duration, tick) + + // Check created Cluster Role + clusterRole, err := s.managementContext.RBAC.ClusterRoles("").Get(test.clusterRole.Name, metav1.GetOptions{}) + assert.NoError(t, err) + assert.True(t, reflect.DeepEqual(test.clusterRole.Rules, clusterRole.Rules)) + // Check the ownership to ensure deletion would work + assert.Contains(t, clusterRole.OwnerReferences, grOwnerRef) + // ClusterRole should always indicate it is from a globalrole + assert.Contains(t, clusterRole.Labels, globalRoleLabel) + assert.Equal(t, "true", clusterRole.Labels[globalRoleLabel]) + + // Check created Roles + for _, r := range test.roles { + role, err := s.managementContext.RBAC.Roles(r.Namespace).Get(r.Name, metav1.GetOptions{}) + assert.NoError(t, err) + + // Assert any desired role fields + assert.True(t, reflect.DeepEqual(r.Rules, role.Rules)) + + // Check that the owner label exists and is set correctly + if _, ok := r.Labels[grOwnerLabel]; ok { + owner, ok := role.Labels[grOwnerLabel] + assert.True(t, ok) + assert.Equal(t, r.Labels[grOwnerLabel], owner) + } + + // Check the ownership to ensure deletion would work + assert.Contains(t, role.OwnerReferences, grOwnerRef) + } + + // clean up + err = s.managementContext.Management.GlobalRoles("").Delete(test.globalRole.Name, &metav1.DeleteOptions{}) + assert.NoError(t, err) + err = s.managementContext.RBAC.ClusterRoles("").Delete(test.clusterRole.Name, &metav1.DeleteOptions{}) + assert.NoError(t, err) + for _, r := range test.roles { + err = s.managementContext.RBAC.Roles(r.Namespace).Delete(r.Name, &metav1.DeleteOptions{}) + assert.NoError(t, err) + } + }) + } +} + +func TestGlobalRoleTestSuite(t *testing.T) { + suite.Run(t, new(GlobalRoleTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/run_controller_tests.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/run_controller_tests.sh new file mode 100755 index 0000000..cd634dd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/controllers/run_controller_tests.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +ENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION-1.28.3} + +if ! command -v setup-envtest &> /dev/null +then + go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest +fi + +if [ -z "$KUBEBUILDER_ASSETS" ]; +then + KUBEBUILDER_ASSETS=$(setup-envtest use --use-env -p path $ENVTEST_K8S_VERSION) + export KUBEBUILDER_ASSETS +fi + +go test ./... \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.md new file mode 100644 index 0000000..7de3c1e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.md @@ -0,0 +1,53 @@ +# Integration Tests + +## Dependencies + +--- + +Instructions for installing dependencies can be found in the [wiki](https://github.com/rancher/rancher/wiki/Setting-Up-Rancher-2.0-Development-Environment#setting-up-and-running-the-tests). + +## CI + +--- + +To execute a full CI test, run `make test` or `make ci` which will build Rancher (including any local changes) and run the test suite on it. + +## Install + +--- + +``` +pip install -r requirements.txt +pip install tox +``` + + +## How to Run Integration Tests + +--- + +*The tests require python 3.7. Some other versions may work, but are not guaranteed to be supported.* + +Start a local rancher instance on port 8443. If the password is not set to `admin`, set the environment variable `RANCHER_SERVER_PASSWORD` to the appropriate password. + +Run with [Tox](https://tox.wiki/en/4.11.0/) - from tests/integration dir. See [tox.ini](./tox.ini) for configuration + +* the entire suite: `tox` (from tests/integration) +* a single file with tox: `tox -- -x suite/test_users.py` (from tests/integration) + +Run with [pytest](https://docs.pytest.org/en/7.4.x/) + +* a single test: `pytest -k test_user_cant_delete_self` +* a file: `pytest tests/integration/suite/test_auth_proxy.py` + + +## Notes + +--- + +To debug, use the standard inline process: `breakpoint()` + +The tests use a [Rancher python client](https://github.com/rancher/client-python) which is dynamically generated based on the Rancher API, so any methods called on it do not exist until runtime. +It will be helpful to use the debugger and tools like `dir(admin_mc)` to see all methods on a variable. + +`conftest.py` holds the primary supporting code. See [pytest docs](https://docs.pytest.org) for more info. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.txt new file mode 100644 index 0000000..8f3bf3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/README.txt @@ -0,0 +1 @@ +Integration Tests \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/pkg/defaults/defaults.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/pkg/defaults/defaults.go new file mode 100644 index 0000000..af70816 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/pkg/defaults/defaults.go @@ -0,0 +1,5 @@ +package defaults + +var ( + WatchTimeoutSeconds = int64(600) // 10 minutes. +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/requirements.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/requirements.txt new file mode 100644 index 0000000..601fe15 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/requirements.txt @@ -0,0 +1,16 @@ +git+https://github.com/rancher/client-python.git@1ecfc3e6a300f5f336da4e4416c46c50d544fd77 +websocket-client==0.56.0 +PyJWT==2.4.0 + +flask==2.2.5 +pytest==6.2.5 +pytest-repeat==0.8.0 +pytest-xdist==2.0.0 +pytest-timeout==2.1.0 +pyyaml==6.0.1 +netaddr==0.8.0 +requests==2.31.0 +kubernetes==12.0.1 +jinja2>=2.10 +cryptography==42.0.4 +werkzeug==3.0.3 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/setup.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/setup.py new file mode 100644 index 0000000..57c4363 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/setup.py @@ -0,0 +1,11 @@ +from distutils.core import setup + +setup( + name='IntegrationTests', + version='0.1', + packages=[ + 'suite', + ], + license='ASL 2.0', + long_description=open('README.txt').read(), +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/alert_common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/alert_common.py new file mode 100644 index 0000000..01d5fbc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/alert_common.py @@ -0,0 +1,68 @@ +from flask import request +from flask import Flask +from threading import Thread +from werkzeug.serving import make_server +import socket + + +def get_ip(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + # doesn't even have to be reachable + s.connect(('10.255.255.255', 1)) + IP = s.getsockname()[0] + except Exception: + IP = '127.0.0.1' + finally: + s.close() + return IP + + +LOCAL_IP = get_ip() + + +class MockServer(Thread): + def __init__(self, port=5000): + self.port = port + self.app = Flask(__name__) + self.server = make_server(LOCAL_IP, self.port, self.app) + self.url = "http://%s:%s" % (LOCAL_IP, self.port) + self.thread = None + + def stop(self): + self.server.shutdown() + self.thread.join() + + def start(self): + self.thread = Thread(target=self.server.serve_forever, daemon=True) + self.thread.start() + + +class MockReceiveAlert(MockServer): + def __init__(self, port): + super().__init__(port) + self.add_endpoints() + + def api_microsoft_teams(self): + message = request.json.get("text") + assert message == MICROSOFTTEAMS_MESSAGE + return "success" + + def api_dingtalk(self, url): + message = request.json.get("text") + assert message.get('content') == DINGTALK_MESSAGE + return '{"errcode":0,"errmsg":""}' + + def add_endpoints(self): + self.app.add_url_rule("/microsoftTeams", + view_func=self.api_microsoft_teams, + methods=('POST',)) + self.app.add_url_rule("/dingtalk//", + view_func=self.api_dingtalk, + methods=('POST',)) + pass + + +DINGTALK_MESSAGE = "Dingtalk setting validated" + +MICROSOFTTEAMS_MESSAGE = "MicrosoftTeams setting validated" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/cluster_common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/cluster_common.py new file mode 100644 index 0000000..fcbe3d3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/cluster_common.py @@ -0,0 +1,113 @@ +import subprocess +import os +import re +import yaml +from .common import random_str +from jinja2 import Template + + +def generate_cluster_config(request, dind_rke_node_num): + # generate a random and kube_config file + dind_name = 'dind-' + random_str() + dind_cluster_config_file = dind_name + '.yml' + dind_kube_config_file = 'kube_config_' + dind_name + '.yml' + cluster_config_tmpl = get_rke_config_template() + # generate nodes + random_nodes = [ + 'node-' + + random_str() + for x in range(dind_rke_node_num)] + rke_config_template = Template(cluster_config_tmpl) + rendered_tmpl = rke_config_template.render( + random_nodes=random_nodes) + # write config file on disk + cluster_config_file = open(dind_cluster_config_file, 'w') + cluster_config_file.write(rendered_tmpl) + cluster_config_file.close() + + request.addfinalizer(lambda: cleanup_dind( + dind_cluster_config_file, + dind_name + '.rkestate' + )) + + return \ + dind_name, \ + yaml.safe_load(rendered_tmpl), \ + dind_cluster_config_file, \ + dind_kube_config_file + + +def cleanup_dind(cluster_file, state_file): + remove_cluster(cluster_file) + os.remove(cluster_file) + os.remove(state_file) + + +def get_rke_config_template(): + dind_cluster_config_j2 = """ +--- +authentication: + strategy: "x509|webhook" +nodes:{% for node in random_nodes %} + - address: {{ node }} + user: docker + role: + - controlplane + - worker + - etcd{% endfor %} +""" + return dind_cluster_config_j2 + + +def create_cluster(cluster_config_file): + raise Exception('cluster creation needs refactor') + # attempt to resolve unknown random rke up errors + for _ in range(3): + try: + return subprocess.check_output( + 'rke up --dind --config ' + + cluster_config_file, + stderr=subprocess.STDOUT, shell=True + ) + except subprocess.CalledProcessError as err: + print('RKE up error: ' + str(err.output)) + raise Exception('rke up failure') + + +def remove_cluster(cluster_config_file): + try: + return subprocess.check_output( + 'rke remove --force --dind --config ' + + cluster_config_file, + stderr=subprocess.STDOUT, shell=True + ) + except subprocess.CalledProcessError as err: + print('RKE down error: ' + str(err.output)) + raise err + + +def import_cluster(admin_mc, kube_config_file, cluster_name): + client = admin_mc.client + + imported_cluster = client.create_cluster( + replace=True, + name=cluster_name, + localClusterAuthEndpoint={ + 'enabled': True, + }, + rancherKubernetesEngineConfig={}, + ) + reg_token = client.create_cluster_registration_token( + clusterId=imported_cluster.id + ) + + # modify import command to add auth image + match = r'\.yaml \|' + replace = '.yaml?authImage=fixed |' + insecure_command = re.sub(match, replace, reg_token.insecureCommand) + + # run kubectl command + os_env = os.environ.copy() + os_env['KUBECONFIG'] = kube_config_file + subprocess.check_output(insecure_command, env=os_env, shell=True) + return imported_cluster diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/common.py new file mode 100644 index 0000000..cd49d23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/common.py @@ -0,0 +1,183 @@ +import base64 +import hashlib +import random +import time + + +def random_str(): + return 'random-{0}-{1}'.format(random_num(), int(time.time())) + + +def random_num(): + return random.randint(0, 1000000) + + +def find_one(method, *args, **kw): + return find_count(1, method, *args, **kw)[0] + + +def find_count(count, method, *args, **kw): + ret = method(*args, **kw) + assert len(ret) == count + return ret + + +def auth_check(schema, id, access, props=None): + schema_type = schema.types[id] + access_actual = set() + + try: + if 'GET' in schema_type.collectionMethods: + access_actual.add('r') + except AttributeError: + pass + + try: + if 'GET' in schema_type.resourceMethods: + access_actual.add('r') + except AttributeError: + pass + + try: + if 'POST' in schema_type.collectionMethods: + access_actual.add('c') + except AttributeError: + pass + + try: + if 'DELETE' in schema_type.resourceMethods: + access_actual.add('d') + except AttributeError: + pass + + try: + if 'PUT' in schema_type.resourceMethods: + access_actual.add('u') + except AttributeError: + pass + + assert access_actual == set(access) + + if props is None: + return 1 + + for i in ['description', 'annotations', 'labels']: + if i not in props and i in schema_type.resourceFields.keys(): + props[i] = 'cru' + + for i in ['created', 'removed', 'transitioning', 'transitioningProgress', + 'removeTime', 'transitioningMessage', 'id', 'uuid', 'kind', + 'state', 'creatorId', 'finalizers', 'ownerReferences', 'type', + 'scaledownTime']: + if i not in props and i in schema_type.resourceFields.keys(): + props[i] = 'r' + + for i in ['name']: + if i not in props and i in schema_type.resourceFields.keys(): + props[i] = 'cr' + + prop = set(props.keys()) + prop_actual = set(schema_type.resourceFields.keys()) + + if prop_actual != prop: + for k in prop: + assert k in prop_actual + for k in prop_actual: + assert k in prop + + assert prop_actual == prop + + for name, field in schema_type.resourceFields.items(): + assert name in props + + prop = set(props[name]) + prop_actual = set('r') + + prop.add(name) + prop_actual.add(name) + + if field.create: + prop_actual.add('c') + if field.update: + prop_actual.add('u') + if 'writeOnly' in field and field.writeOnly: + prop_actual.add('o') + + if prop_actual != prop: + assert prop_actual == prop + + return 1 + + +def wait_for_template_to_be_created(client, name, timeout=45): + found = False + start = time.time() + interval = 1 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(catalogId=name) + if len(templates) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def wait_for_template_versions_to_be_created(client, version, timeout=45): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templateVersion = client.list_templateVersion(name=version) + if len(templateVersion) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def wait_for_template_to_be_deleted(client, name, timeout=60): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(catalogId=name) + if len(templates) == 0: + found = True + time.sleep(interval) + interval *= 2 + + +def check_subject_in_rb(rbac, ns, subject_id, name): + rbs = rbac.list_namespaced_role_binding(ns) + for rb in rbs.items: + if rb.metadata.name == name: + for i in range(0, len(rb.subjects)): + if rb.subjects[i].name == subject_id: + return True + return False + + +def wait_for_atleast_workload(pclient, nsid, timeout=60, count=0): + start = time.time() + interval = 0.5 + workloads = pclient.list_workload(namespaceId=nsid) + while len(workloads.data) < count: + if time.time() - start > timeout: + raise Exception('Timeout waiting for workload service') + time.sleep(interval) + interval *= 2 + workloads = pclient.list_workload(namespaceId=nsid) + return workloads + + +def string_to_encoding(input): + m = hashlib.sha256() + m.update(bytes(input, 'utf-8')) + return base64.b32encode(m.digest())[:10].decode('utf-8') diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/conftest.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/conftest.py new file mode 100644 index 0000000..f974e4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/conftest.py @@ -0,0 +1,642 @@ +import os +import pytest +import requests +import time +import urllib3 +import yaml +import subprocess +import json +import rancher +from sys import platform +from .common import random_str, wait_for_template_to_be_created +from kubernetes.client import ApiClient, Configuration, CustomObjectsApi, \ + ApiextensionsV1Api +from kubernetes.client.rest import ApiException +from kubernetes.config.kube_config import KubeConfigLoader +from rancher import ApiError +from .cluster_common import \ + generate_cluster_config, \ + create_cluster, \ + import_cluster + + +# This stops ssl warnings for unsecure certs +urllib3.disable_warnings() + + +IP = "localhost" +SERVER_URL = os.environ.get('CATTLE_TEST_URL', 'https://' + IP + ':443') +SERVER_PASSWORD = os.environ.get('RANCHER_SERVER_PASSWORD', 'admin') +BASE_URL = SERVER_URL + '/v3' +AUTH_URL = BASE_URL + '-public/localproviders/local?action=login' +DEFAULT_TIMEOUT = 120 +DEFAULT_CATALOG = "https://github.com/rancher/integration-test-charts" +WAIT_HTTP_ERROR_CODES = [404, 405] + + +class ManagementContext: + """Contains a client that is scoped to the managment plane APIs. That is, + APIs that are not specific to a cluster or project.""" + + def __init__(self, client, k8s_client=None, user=None): + self.client = client + self.k8s_client = k8s_client + self.user = user + + +class ClusterContext: + """Contains a client that is scoped to a specific cluster. Also contains + a reference to the ManagementContext used to create cluster client and + the cluster object itself. + """ + + def __init__(self, management, cluster, client): + self.management = management + self.cluster = cluster + self.client = client + + +class ProjectContext: + """Contains a client that is scoped to a newly created project. Also + contains a reference to the clusterContext used to crete the project and + the project object itself. + """ + + def __init__(self, cluster_context, project, client): + self.cluster = cluster_context + self.project = project + self.client = client + + +class DINDContext: + """Returns a DINDContext for a new RKE cluster for the default global + admin user.""" + + def __init__( + self, name, admin_mc, cluster, client, cluster_file, kube_file + ): + self.name = name + self.admin_mc = admin_mc + self.cluster = cluster + self.client = client + self.cluster_file = cluster_file + self.kube_file = kube_file + + +@pytest.fixture(scope="session") +def admin_mc(): + """Returns a ManagementContext for the default global admin user.""" + r = requests.post(AUTH_URL, json={ + 'username': 'admin', + 'password': SERVER_PASSWORD, + 'responseType': 'json', + }, verify=False) + protect_response(r) + client = rancher.Client(url=BASE_URL, token=r.json()['token'], + verify=False) + k8s_client = kubernetes_api_client(client, 'local') + admin = client.list_user(username='admin').data[0] + return ManagementContext(client, k8s_client, user=admin) + + +@pytest.fixture +def admin_cc(admin_mc): + """Returns a ClusterContext for the local cluster for the default global + admin user.""" + cluster, client = cluster_and_client('local', admin_mc.client) + return ClusterContext(admin_mc, cluster, client) + + +def cluster_and_client(cluster_id, mgmt_client): + cluster = mgmt_client.by_id_cluster(cluster_id) + url = cluster.links.self + '/schemas' + client = rancher.Client(url=url, + verify=False, + token=mgmt_client.token) + return cluster, client + + +def user_project_client(user, project): + """Returns a project level client for the user""" + return rancher.Client(url=project.links.self+'/schemas', verify=False, + token=user.client.token) + + +def user_cluster_client(user, cluster): + """Returns a cluster level client for the user""" + return rancher.Client(url=cluster.links.self+'/schemas', verify=False, + token=user.client.token) + + +@pytest.fixture +def admin_pc_factory(admin_cc, remove_resource): + """Returns a ProjectContext for a newly created project in the local + cluster for the default global admin user. The project will be deleted + when this fixture is cleaned up.""" + def _admin_pc(): + admin = admin_cc.management.client + p = admin.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + p = admin.wait_success(p) + wait_for_condition("BackingNamespaceCreated", "True", + admin_cc.management.client, p) + assert p.state == 'active' + remove_resource(p) + p = admin.reload(p) + url = p.links.self + '/schemas' + return ProjectContext(admin_cc, p, rancher.Client(url=url, + verify=False, + token=admin.token)) + return _admin_pc + + +@pytest.fixture +def admin_pc(admin_pc_factory): + return admin_pc_factory() + + +@pytest.fixture +def admin_system_pc(admin_mc): + """Returns a ProjectContext for the system project in the local cluster + for the default global admin user.""" + admin = admin_mc.client + plist = admin.list_project(name='System', clusterId='local') + assert len(plist) == 1 + p = plist.data[0] + url = p.links.self + '/schemas' + return ProjectContext(admin_cc, p, rancher.Client(url=url, + verify=False, + token=admin.token)) + + +@pytest.fixture +def user_mc(user_factory): + """Returns a ManagementContext for a newly created standard user""" + return user_factory() + + +@pytest.fixture +def user_factory(admin_mc, remove_resource): + """Returns a factory for creating new users which a ManagementContext for + a newly created standard user is returned. + This user and globalRoleBinding will be cleaned up automatically by the + fixture remove_resource. + """ + def _create_user(globalRoleId='user'): + admin = admin_mc.client + # User creation will fail if password < minimum (default: 12) or + # username == password. Since random_str concatenates a random number + # plus seconds since epoch, this ensures no collisions + username = random_str() + "username" + password = random_str() + "password" + user = admin.create_user(username=username, password=password) + remove_resource(user) + grb = admin.create_global_role_binding( + userId=user.id, globalRoleId=globalRoleId) + remove_resource(grb) + response = requests.post(AUTH_URL, json={ + 'username': username, + 'password': password, + 'responseType': 'json', + }, verify=False) + protect_response(response) + client = rancher.Client(url=BASE_URL, token=response.json()['token'], + verify=False) + return ManagementContext(client, user=user) + + return _create_user + + +@pytest.fixture +def admin_cc_client(admin_cc): + """Returns the client from the default admin's ClusterContext""" + return admin_cc.client + + +@pytest.fixture +def admin_pc_client(admin_pc): + """Returns the client from the default admin's ProjectContext """ + return admin_pc.client + + +@pytest.fixture(scope="session") +def custom_catalog(admin_mc, remove_resource_session): + """Create a catalog from the URL and cleanup after tests finish""" + def _create_catalog(name=random_str(), catalogURL=DEFAULT_CATALOG): + client = admin_mc.client + catalog = client.create_catalog(name=name, + branch="master", + url=catalogURL, + ) + remove_resource_session(catalog) + wait_for_template_to_be_created(client, name) + return _create_catalog + + +@pytest.fixture() +def restore_rancher_version(request, admin_mc): + client = admin_mc.client + server_version = client.by_id_setting('server-version') + + def _restore(): + client.update_by_id_setting( + id=server_version.id, value=server_version.value) + request.addfinalizer(_restore) + + +def set_server_version(client, version): + client.update_by_id_setting(id='server-version', value=version) + + def _wait_for_version(): + server_version = client.by_id_setting('server-version') + return server_version.value == version + + wait_for(_wait_for_version) + + +@pytest.fixture(scope="session") +def dind_cc(request, admin_mc): + # verify platform is linux + if platform != 'linux': + raise Exception('rke dind only supported on linux') + + def set_server_url(url): + admin_mc.client.update_by_id_setting(id='server-url', value=url) + + original_url = admin_mc.client.by_id_setting('server-url').value + + # make sure server-url is set to IP address for dind accessibility + set_server_url(SERVER_URL) + + # revert server url to original when done + request.addfinalizer(lambda: set_server_url(original_url)) + + # create the cluster & import + name, config, cluster_file, kube_file = generate_cluster_config(request, 1) + create_cluster(cluster_file) + cluster = import_cluster(admin_mc, kube_file, cluster_name=name) + + # delete cluster when done + request.addfinalizer(lambda: admin_mc.client.delete(cluster)) + + # wait for cluster to completely provision + wait_for_condition("Ready", "True", admin_mc.client, cluster, 120) + cluster, client = cluster_and_client(cluster.id, admin_mc.client) + + # get ip address of cluster node + node_name = config['nodes'][0]['address'] + node_inspect = subprocess.check_output('docker inspect rke-dind-' + + node_name, shell=True).decode() + node_json = json.loads(node_inspect) + node_ip = node_json[0]['NetworkSettings']['IPAddress'] + + # update cluster fqdn with node ip + admin_mc.client.update_by_id_cluster( + id=cluster.id, + name=cluster.name, + localClusterAuthEndpoint={ + 'enabled': True, + 'fqdn': node_ip + ':6443', + 'caCerts': cluster.caCert, + }, + ) + return DINDContext( + name, admin_mc, cluster, client, cluster_file, kube_file + ) + + +def wait_for(callback, timeout=DEFAULT_TIMEOUT, fail_handler=None): + sleep_time = _sleep_time() + start = time.time() + ret = callback() + while ret is None or ret is False: + time.sleep(next(sleep_time)) + if time.time() - start > timeout: + exception_msg = 'Timeout waiting for condition.' + if fail_handler: + exception_msg = exception_msg + ' Fail handler message: ' + \ + fail_handler() + raise Exception(exception_msg) + ret = callback() + return ret + + +def _sleep_time(): + sleep = 0.01 + while True: + yield sleep + sleep *= 2 + if sleep > 1: + sleep = 1 + + +def wait_until_available(client, obj, timeout=DEFAULT_TIMEOUT): + start = time.time() + sleep = 0.01 + while True: + time.sleep(sleep) + sleep *= 2 + if sleep > 2: + sleep = 2 + try: + obj = client.reload(obj) + except ApiError as e: + if e.error.status != 403: + raise e + else: + return obj + delta = time.time() - start + if delta > timeout: + msg = 'Timeout waiting for [{}:{}] for condition after {}' \ + ' seconds'.format(obj.type, obj.id, delta) + raise Exception(msg) + + +@pytest.fixture +def remove_resource(admin_mc, request): + """Remove a resource after a test finishes even if the test fails.""" + client = admin_mc.client + + def _cleanup(resource): + def clean(): + try: + client.delete(resource) + except ApiError as e: + code = e.error.status + if code == 409 and "namespace will automatically be purged " \ + in e.error.message: + pass + elif code not in WAIT_HTTP_ERROR_CODES: + raise e + request.addfinalizer(clean) + return _cleanup + + +@pytest.fixture +def remove_resouce_func(request): + """Call the delete_func passing in the name of the resource. This is useful + when dealing with the k8s clients for objects that don't exist in the + Rancher client + """ + def _cleanup(delete_func, name): + def clean(): + try: + delete_func(name) + except ApiException as e: + body = json.loads(e.body) + if body["code"] not in WAIT_HTTP_ERROR_CODES: + raise e + request.addfinalizer(clean) + return _cleanup + + +@pytest.fixture +def raw_remove_custom_resource(admin_mc, request): + """Remove a custom resource, using the k8s client, after a test finishes + even if the test fails. This should only be used if remove_resource, which + exclusively uses the rancher api, cannot be used""" + def _cleanup(resource): + k8s_v1_client = ApiextensionsV1Api(admin_mc.k8s_client) + k8s_client = CustomObjectsApi(admin_mc.k8s_client) + + def clean(): + kind = resource["kind"] + metadata = resource["metadata"] + api_version = resource["apiVersion"] + api_version_parts = api_version.split("/") + if len(api_version_parts) != 2: + raise ValueError("Error parsing ApiVersion [" + api_version + + "]." + "Expected form \"group/version\"" + ) + + group = api_version_parts[0] + version = api_version_parts[1] + + crd_list = k8s_v1_client.\ + list_custom_resource_definition().items + + crd = list(filter(lambda x: x.spec.names.kind == kind and + x.spec.group == group and + x.spec.versions[0].name == version, + crd_list))[0] + try: + k8s_client.delete_namespaced_custom_object( + group, + version, + metadata["namespace"], + crd.spec.names.plural, + metadata["name"]) + except ApiException as e: + body = json.loads(e.body) + if body["code"] not in WAIT_HTTP_ERROR_CODES: + raise e + request.addfinalizer(clean) + return _cleanup + + +@pytest.fixture(scope="session") +def remove_resource_session(admin_mc, request): + """Remove a resource after the test session finishes. Can only be used + with fixtures that are 'session' scoped. + """ + client = admin_mc.client + + def _cleanup(resource): + def clean(): + try: + client.delete(resource) + except ApiError as e: + if e.error.status not in WAIT_HTTP_ERROR_CODES: + raise e + request.addfinalizer(clean) + return _cleanup + + +@pytest.fixture() +def wait_remove_resource(admin_mc, request, timeout=DEFAULT_TIMEOUT): + """Remove a resource after a test finishes even if the test fails and + wait until deletion is confirmed.""" + client = admin_mc.client + + def _cleanup(resource): + def clean(): + try: + client.delete(resource) + except ApiError as e: + code = e.error.status + if code == 409 and "namespace will automatically be purged " \ + in e.error.message: + pass + elif code not in WAIT_HTTP_ERROR_CODES: + raise e + wait_until(lambda: client.reload(resource) is None) + request.addfinalizer(clean) + return _cleanup + + +@pytest.fixture() +def list_remove_resource(admin_mc, request): + """Takes list of resources to remove & supports reordering of the list """ + client = admin_mc.client + + def _cleanup(resource): + def clean(): + for item in resource: + try: + client.delete(item) + except ApiError as e: + if e.error.status not in WAIT_HTTP_ERROR_CODES: + raise e + wait_until(lambda: client.reload(item) is None) + request.addfinalizer(clean) + return _cleanup + + +def wait_for_condition(condition_type, status, client, obj, timeout=45): + start = time.time() + obj = client.reload(obj) + sleep = 0.01 + while not find_condition(condition_type, status, obj): + time.sleep(sleep) + sleep *= 2 + if sleep > 2: + sleep = 2 + obj = client.reload(obj) + delta = time.time() - start + if delta > timeout: + msg = 'Expected condition {} to have status {}\n'\ + 'Timeout waiting for [{}:{}] for condition after {} ' \ + 'seconds\n {}'.format(condition_type, status, obj.type, obj.id, + delta, str(obj)) + raise Exception(msg) + return obj + + +def wait_until(cb, timeout=DEFAULT_TIMEOUT, backoff=True): + start_time = time.time() + interval = 1 + while time.time() < start_time + timeout and cb() is False: + if backoff: + interval *= 2 + time.sleep(interval) + + +def find_condition(condition_type, status, obj): + if not hasattr(obj, "conditions"): + return False + + if obj.conditions is None: + return False + + for condition in obj.conditions: + if condition.type == condition_type and condition.status == status: + return True + return False + + +def kubernetes_api_client(rancher_client, cluster_name): + c = rancher_client.by_id_cluster(cluster_name) + kc = c.generateKubeconfig() + loader = KubeConfigLoader(config_dict=yaml.full_load(kc.config)) + client_configuration = type.__call__(Configuration) + loader.load_and_set(client_configuration) + k8s_client = ApiClient(configuration=client_configuration) + return k8s_client + + +def protect_response(r): + if r.status_code >= 300: + message = f'Server responded with {r.status_code}\nbody:\n{r.text}' + raise ValueError(message) + + +def create_kubeconfig(request, dind_cc, client): + # request cluster scoped kubeconfig, permissions may not be synced yet + def generateKubeconfig(max_attempts=5): + for attempt in range(1, max_attempts+1): + try: + # get cluster for client + cluster = client.by_id_cluster(dind_cc.cluster.id) + return cluster.generateKubeconfig()['config'] + except ApiError as err: + if attempt == max_attempts: + raise err + time.sleep(1) + + cluster_kubeconfig = generateKubeconfig() + + # write cluster scoped kubeconfig + cluster_kubeconfig_file = "kubeconfig-" + random_str() + ".yml" + f = open(cluster_kubeconfig_file, "w") + f.write(cluster_kubeconfig) + f.close() + + # cleanup file when done + request.addfinalizer(lambda: os.remove(cluster_kubeconfig_file)) + + # extract token name + config = yaml.safe_load(cluster_kubeconfig) + token_name = config['users'][0]['user']['token'].split(':')[0] + + # wait for token to sync + crd_client = CustomObjectsApi( + kubernetes_api_client( + dind_cc.admin_mc.client, + dind_cc.cluster.id + ) + ) + + def cluster_token_available(): + try: + return crd_client.get_namespaced_custom_object( + 'cluster.cattle.io', + 'v3', + 'cattle-system', + 'clusterauthtokens', + token_name + ) + except ApiException: + return None + + wait_for(cluster_token_available) + + return cluster_kubeconfig_file + + +def set_cluster_psp(admin_mc, value): + """Enable or Disable the pod security policy at the local cluster""" + k8s_dynamic_client = CustomObjectsApi(admin_mc.k8s_client) + # these create a mock pspts... not valid for real psp's + + def update_cluster(): + try: + local_cluster = k8s_dynamic_client.get_cluster_custom_object( + "management.cattle.io", "v3", "clusters", "local") + local_cluster["metadata"]["annotations"][ + "capabilities/pspEnabled"] = value + k8s_dynamic_client.replace_cluster_custom_object( + "management.cattle.io", "v3", "clusters", "local", + local_cluster) + except ApiException as e: + assert e.status == 409 + return False + return True + + wait_for(update_cluster) + + def check_psp(): + cluster_obj = admin_mc.client.by_id_cluster(id="local") + return str(cluster_obj.capabilities.pspEnabled).lower() == value + + wait_for(check_psp) + + +@pytest.fixture() +def restore_cluster_psp(admin_mc, request): + cluster_obj = admin_mc.client.by_id_cluster(id="local") + value = str(cluster_obj.capabilities.pspEnabled).lower() + + def _restore(): + set_cluster_psp(admin_mc, value) + + request.addfinalizer(_restore) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_alert.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_alert.py new file mode 100644 index 0000000..81efc24 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_alert.py @@ -0,0 +1,85 @@ +import pytest +from rancher import ApiError +from .common import random_str +from .conftest import wait_for +from .alert_common import MockReceiveAlert +from .alert_common import LOCAL_IP + +dingtalk_config = { + "type": "/v3/schemas/dingtalkConfig", + "url": "http://%s:4050/dingtalk/test/" % LOCAL_IP, +} + +microsoft_teams_config = { + "type": "/v3/schemas/msTeamsConfig", + "url": "http://%s:4050/microsoftTeams" % LOCAL_IP, +} + +MOCK_RECEIVER_ALERT_PORT = 4050 + + +@pytest.mark.skip +def test_alert_access(admin_mc, admin_pc, admin_cc, user_mc, remove_resource): + """Tests that a user with read-only access is not + able to deactivate an alert. + """ + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=admin_pc.project.id, + roleTemplateId="read-only") + remove_resource(prtb) + + # we get some project defaults, wait for them to come up + wait_for(projectAlertRules(user_mc.client), + fail_handler=lambda: "failed waiting for project alerts", + timeout=120) + # list with admin_mc to get action not available to user + alerts = admin_mc.client.list_projectAlertRule( + projectId=admin_pc.project.id + ) + with pytest.raises(ApiError) as e: + user_mc.client.action(obj=alerts.data[0], action_name="deactivate") + assert e.value.error.status == 404 + + +def projectAlertRules(client): + """Wait for the crtb to have the userId populated""" + def cb(): + return len(client.list_projectAlertRule().data) > 0 + return cb + + +@pytest.fixture(scope="module") +def mock_receiver_alert(): + server = MockReceiveAlert(port=MOCK_RECEIVER_ALERT_PORT) + server.start() + yield server + server.stop() + + +@pytest.mark.skip +def test_add_notifier(admin_mc, remove_resource, mock_receiver_alert): + client = admin_mc.client + + # Add the notifier dingtalk and microsoftTeams + notifier_dingtalk = client.create_notifier(name="dingtalk", + clusterId="local", + dingtalkConfig=dingtalk_config) + + notifier_microsoft_teams = client.create_notifier( + name="microsoftTeams", + clusterId="local", + msteamsConfig=microsoft_teams_config) + + client.action(obj=notifier_microsoft_teams, + action_name="send", + msteamsConfig=microsoft_teams_config) + + client.action(obj=notifier_dingtalk, + action_name="send", + dingtalkConfig=dingtalk_config) + + # Remove the notifiers + remove_resource(notifier_dingtalk) + remove_resource(notifier_microsoft_teams) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_app.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_app.py new file mode 100644 index 0000000..7dbe959 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_app.py @@ -0,0 +1,837 @@ +import time +import pytest +from rancher import ApiError +from .test_catalog import wait_for_template_to_be_created +from .common import random_str, wait_for_template_versions_to_be_created +from .conftest import set_server_version, wait_for, wait_for_condition, \ + wait_until, user_project_client, DEFAULT_CATALOG + + +@pytest.mark.skip +def test_app_mysql(admin_pc, admin_mc): + client = admin_pc.client + name = random_str() + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + wait_for_template_to_be_created(admin_mc.client, "library") + answers = { + "defaultImage": "true", + "image": "mysql", + "imageTag": "5.7.14", + "mysqlDatabase": "admin", + "mysqlPassword": "", + "mysqlUser": "admin", + "persistence.enabled": "false", + "persistence.size": "8Gi", + "persistence.storageClass": "", + "service.nodePort": "", + "service.port": "3306", + "service.type": "ClusterIP" + } + client.create_app( + name=name, + externalId="catalog://?catalog=library&template=mysql&version=1.3.1&" + "namespace=cattle-global-data", + targetNamespace=ns.name, + projectId=admin_pc.project.id, + answers=answers + ) + wait_for_workload(client, ns.name, count=1) + + +@pytest.mark.skip(reason="istio disabled") +def test_app_istio(admin_cc, admin_pc, admin_mc): + client = admin_pc.client + name = "rancher-istio" + url = " https://github.com/guangbochen/system-charts.git" + external_id = "catalog://?catalog=system-library" \ + "&template=rancher-istio&version=1.1.5" + + ns = admin_pc.cluster.client.create_namespace(name="istio-system", + projectId=admin_pc. + project.id) + admin_mc.client.create_catalog(name="system-library", + branch="istio", + url=url, + ) + wait_for_template_to_be_created(admin_mc.client, "system-library") + + answers = { + "certmanager.enabled": "false", + "enableCRDs": "true", + "galley.enabled": "true", + "gateways.enabled": "false", + "gateways.istio-ingressgateway.type": "NodePort", + "grafana.enabled": "true", + "grafana.persistence.enabled": "false", + "istio_cni.enabled": "false", + "istiocoredns.enabled": "false", + "kiali.enabled": "true", + "mixer.enabled": "true", + "mixer.policy.enabled": "false", + "mixer.telemetry.resources.limits.cpu": "4800m", + "mixer.telemetry.resources.limits.memory": "4048Mi", + "mixer.telemetry.resources.requests.cpu": "1000m", + "mixer.telemetry.resources.requests.memory": "1024Mi", + "mtls.enabled": "false", + "nodeagent.enabled": "false", + "pilot.enabled": "true", + "pilot.resources.limits.cpu": "1000m", + "pilot.resources.limits.memory": "4096Mi", + "pilot.resources.requests.cpu": "500m", + "pilot.resources.requests.memory": "2048Mi", + "pilot.traceSampling": "1", + "prometheus.enabled": "true", + "prometheus.resources.limits.cpu": "1000m", + "prometheus.resources.limits.memory": "1000Mi", + "prometheus.resources.requests.cpu": "750m", + "prometheus.resources.requests.memory": "750Mi", + "prometheus.retention": "6h", + "security.enabled": "true", + "sidecarInjectorWebhook.enabled": "true", + "tracing.enabled": "true" + } + + client.create_app( + name=name, + externalId=external_id, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + answers=answers + ) + wait_for_monitor_metric(admin_cc, admin_mc) + + +def test_prehook_chart(admin_pc, admin_mc): + client = admin_pc.client + name = random_str() + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + url = "https://github.com/StrongMonkey/charts-1.git" + catalog = admin_mc.client.create_catalog(name=random_str(), + branch="test", + url=url, + ) + wait_for_template_to_be_created(admin_mc.client, catalog.name) + external_id = "catalog://?catalog=" + \ + catalog.name + "&template=busybox&version=0.0.2" \ + "&namespace=cattle-global-data" + client.create_app( + name=name, + externalId=external_id, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + ) + # it will be only one workload(job), because the deployment has to + # wait for job to be finished, and it will never finish because we + # can't create real container + wait_for_workload(client, ns.name, count=1) + jobs = client.list_job(namespaceId=ns.id) + assert len(jobs) == 1 + + +@pytest.mark.skip +def test_helm_timeout(admin_pc, admin_mc, remove_resource): + """Test helm timeout flag. This test asserts timeout flag is properly being + passed to helm. + """ + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace(name="ns-" + random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + + wait_for_template_to_be_created(admin_mc.client, "library") + + # timeout of one second is not sufficient for installing mysql and should + # result in failure + app1 = client.create_app( + name="app-" + random_str(), + externalId="catalog://?catalog=library&template=mysql&version=1.3.1&" + "namespace=cattle-global-data", + targetNamespace=ns.name, + projectId=admin_pc.project.id, + wait=True, + timeout=1, + ) + remove_resource(app1) + + assert app1.timeout == 1 + assert app1.wait + + wait_for_workload(client, ns.name, count=1) + + def wait_for_transition_error(app): + def transition_error(): + test_app = client.reload(app) + if test_app.transitioning != "error": + return False + return test_app + + return wait_for(transition_error, timeout=15, fail_handler=lambda: + "expected transitioning to fail") + + app1 = wait_for_transition_error(app1) + assert "timed out waiting for the condition" in app1.transitioningMessage + + +def wait_for_app_annotation(admin_pc, ns, app_name, exists=True, timeout=60): + start = time.time() + interval = 0.5 + ns = admin_pc.cluster.client.reload(ns) + while (app_name in ns.annotations.get('cattle.io/appIds', [])) != exists: + if time.time() - start > timeout: + print(ns.annotations) + raise Exception('Timeout waiting for app annotation') + time.sleep(interval) + interval *= 2 + ns = admin_pc.cluster.client.reload(ns) + return ns + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_app_create_validation(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test create validation for apps. This test will set the rancher version + explicitly and attempt to create apps with rancher version requirements. + """ + # 2.3.1 uses 2.4.1-2.6.0 + # 2.7.0 uses 2.5.0-2.7.0 + client = admin_mc.client + + c_name = random_str() + custom_catalog(name=c_name) + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + + cat_base = "catalog://?catalog="+c_name+"&template=chartmuseum&version=" + + app_data = { + 'name': random_str(), + 'externalId': cat_base+"2.7.0", + 'targetNamespace': ns.name, + 'projectId': admin_pc.project.id, + "answers": [{ + "type": "answer", + "clusterId": None, + "projectId": None, + "values": { + "defaultImage": "true", + "image.repository": "chartmuseum/chartmuseum", + "image.tag": "v0.11.0", + "env.open.STORAGE": "local", + "gcp.secret.enabled": "false", + "gcp.secret.key": "credentials.json", + "persistence.enabled": "true", + "persistence.size": "10Gi", + "ingress.enabled": "true", + "ingress.hosts[0]": "xip.io", + "service.type": "NodePort", + "env.open.SHOW_ADVANCED": "false", + "env.open.DEPTH": "0", + "env.open.ALLOW_OVERWRITE": "false", + "env.open.AUTH_ANONYMOUS_GET": "false", + "env.open.DISABLE_METRICS": "true" + } + }] + } + + server_version = "2.4.2-beta2" + set_server_version(client, server_version) + + # First try requires a min of 2.5.0 so an error should be returned + with pytest.raises(ApiError) as e: + app1 = admin_pc.client.create_app(app_data) + remove_resource(app1) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + server_version = "2.7.1" + set_server_version(client, server_version) + + # Second try requires a max of 2.7.0 so an error should be returned + with pytest.raises(ApiError) as e: + app1 = admin_pc.client.create_app(app_data) + remove_resource(app1) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + set_server_version(client, "2.5.1-rc4") + + # Third try should work + app1 = admin_pc.client.create_app(app_data) + remove_resource(app1) + wait_for_workload(admin_pc.client, ns.name, count=1) + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_app_update_validation(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test update validation for apps. This test will set the rancher version + explicitly and attempt to update apps with rancher version requirements. + """ + # 2.3.1 uses 2.4.1-2.6.0 + # 2.7.0 uses 2.5.0-2.7.0 + client = admin_mc.client + + c_name = random_str() + custom_catalog(name=c_name) + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + + cat_base = "catalog://?catalog="+c_name+"&template=chartmuseum&version=" + + app_data = { + 'name': random_str(), + 'externalId': cat_base+"2.3.1", + 'targetNamespace': ns.name, + 'projectId': admin_pc.project.id, + "answers": [{ + "type": "answer", + "clusterId": None, + "projectId": None, + "values": { + "defaultImage": "true", + "image.repository": "chartmuseum/chartmuseum", + "image.tag": "v0.9.0", + "env.open.STORAGE": "local", + "gcp.secret.enabled": "false", + "gcp.secret.key": "credentials.json", + "persistence.enabled": "true", + "persistence.size": "10Gi", + "ingress.enabled": "true", + "ingress.hosts[0]": "xip.io", + "service.type": "NodePort", + "env.open.SHOW_ADVANCED": "false", + "env.open.DEPTH": "0", + "env.open.ALLOW_OVERWRITE": "false", + "env.open.AUTH_ANONYMOUS_GET": "false", + "env.open.DISABLE_METRICS": "true" + } + }] + } + + server_version = "2.4.2-rc3" + set_server_version(client, server_version) + + # Launch the app version 2.3.1 with rancher 2.4.2-rc3 + app1 = admin_pc.client.create_app(app_data) + remove_resource(app1) + wait_for_workload(admin_pc.client, ns.name, count=1) + + upgrade_dict = { + 'obj': app1, + 'action_name': 'upgrade', + 'answers': app_data['answers'], + 'externalId': cat_base+"2.7.0", + 'forceUpgrade': False, + } + + # Attempt to upgrade, app version 2.7.0 requires a min of 2.5.0 so this + # will error + with pytest.raises(ApiError) as e: + app1 = client.action(**upgrade_dict) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + server_version = "2.7.1" + set_server_version(client, server_version) + + # # Second try requires a max of 2.7.0 so an error should be returned + with pytest.raises(ApiError) as e: + app1 = client.action(**upgrade_dict) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_app_rollback_validation(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test rollback validation for apps. This test will set the rancher version + explicitly and attempt to rollback apps with rancher version requirements. + """ + # 2.3.1 uses 2.4.1-2.6.0 + # 2.7.0 uses 2.5.0-2.7.0 + client = admin_mc.client + + c_name = random_str() + custom_catalog(name=c_name) + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + + cat_base = "catalog://?catalog="+c_name+"&template=chartmuseum&version=" + + app_data = { + 'name': random_str(), + 'externalId': cat_base+"2.3.1", + 'targetNamespace': ns.name, + 'projectId': admin_pc.project.id, + "answers": [{ + "type": "answer", + "clusterId": None, + "projectId": None, + "values": { + "defaultImage": "true", + "image.repository": "chartmuseum/chartmuseum", + "image.tag": "v0.9.0", + "env.open.STORAGE": "local", + "gcp.secret.enabled": "false", + "gcp.secret.key": "credentials.json", + "persistence.enabled": "true", + "persistence.size": "10Gi", + "ingress.enabled": "true", + "ingress.hosts[0]": "xip.io", + "service.type": "NodePort", + "env.open.SHOW_ADVANCED": "false", + "env.open.DEPTH": "0", + "env.open.ALLOW_OVERWRITE": "false", + "env.open.AUTH_ANONYMOUS_GET": "false", + "env.open.DISABLE_METRICS": "true" + } + }] + } + + set_server_version(client, "2.5.0") + + # Launch the app version 2.3.1 with rancher 2.4.2 + app1 = admin_pc.client.create_app(app_data) + remove_resource(app1) + wait_for_workload(admin_pc.client, ns.name, count=1) + + def _app_revision(): + app = admin_pc.client.reload(app1) + return app.appRevisionId is not None + + wait_for(_app_revision, fail_handler=lambda: 'app has no revision') + + app1 = admin_pc.client.reload(app1) + + assert app1.appRevisionId is not None, 'app has no revision' + + original_rev = app1.appRevisionId + + upgrade_dict = { + 'obj': app1, + 'action_name': 'upgrade', + 'answers': app_data['answers'], + 'externalId': cat_base+"2.7.0", + 'forceUpgrade': False, + } + + # Upgrade the app to get a rollback revision + client.action(**upgrade_dict) + + def _app_revisions(): + app = admin_pc.client.reload(app1) + if len(app.revision().data) > 1: + return app.appRevisionId != original_rev + return False + + def _app_fail(): + app = admin_pc.client.reload(app1) + return 'app did not upgrade: {}'.format(app) + + wait_for(_app_revisions, + fail_handler=_app_fail, + timeout=90) + + app1 = admin_pc.client.reload(app1) + + assert app1.appRevisionId != original_rev, 'app did not upgrade' + + rollback_dict = { + 'obj': app1, + 'action_name': 'rollback', + 'revisionId': original_rev, + 'forceUpgrade': False, + } + + server_version = "2.6.1" + set_server_version(client, server_version) + + # Rollback requires a max of 2.6.0 so an error should be returned + with pytest.raises(ApiError) as e: + client.action(**rollback_dict) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + server_version = "2.0.0-rc3" + set_server_version(client, server_version) + + # Second try requires a min of 2.4.1 so an error should be returned + with pytest.raises(ApiError) as e: + client.action(**rollback_dict) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + +@pytest.mark.skip +def test_app_has_helmversion(admin_pc, admin_mc, remove_resource): + """Test that app is using specified helm version""" + app_client = admin_pc.client + catalog_client = admin_mc.client + catalog_name1 = random_str() + catalog_name2 = random_str() + app_name1 = random_str() + app_name2 = random_str() + catalog1 = catalog_client.create_catalog(name=catalog_name1, + branch="master", + url=DEFAULT_CATALOG, + ) + remove_resource(catalog1) + catalog2 = catalog_client.create_catalog(name=catalog_name2, + branch="master", + url=DEFAULT_CATALOG, + helmVersion="helm_v3" + ) + remove_resource(catalog2) + wait_for_template_to_be_created(catalog_client, catalog_name1) + wait_for_template_to_be_created(catalog_client, catalog_name2) + + ns1 = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns1) + ns2 = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns2) + app1 = app_client.create_app( + name=app_name1, + externalId="catalog://?catalog="+catalog_name1+"&template=chartmuseum&" + "version=2.7.0&namespace=cattle-global-data", + targetNamespace=ns1.name, + projectId=admin_pc.project.id, + ) + remove_resource(app1) + app2 = app_client.create_app( + name=app_name2, + externalId="catalog://?catalog="+catalog_name2+"&template=chartmuseum&" + "version=2.7.0&namespace=cattle-global-data", + targetNamespace=ns2.name, + projectId=admin_pc.project.id, + ) + remove_resource(app2) + wait_for_workload(admin_pc.client, ns1.name, count=1) + wait_for_workload(admin_pc.client, ns2.name, count=1) + app1 = admin_pc.client.reload(app1) + app2 = admin_pc.client.reload(app2) + assert "helmVersion" not in app1 + assert "helmVersion" in app2 + assert app2.helmVersion == "helm_v3" + + +@pytest.mark.skip +def test_app_upgrade_has_helmversion(admin_pc, admin_mc, remove_resource): + """Test helm version exists on new chart versions when added to an + existing catalog and that the helm version carries through template, + templateVersion and app on upgrade""" + app_client = admin_pc.client + catalog_client = admin_mc.client + catalog_name = random_str() + app1_name = random_str() + app2_name = random_str() + helm_3 = 'helm_v3' + cat_base = "catalog://?catalog=" + catalog_name + \ + "&template=rancher-v3-issue&version=" + + helm3_catalog = catalog_client.create_catalog( + name=catalog_name, + branch="helmversion-onupdate-1v", + url=DEFAULT_CATALOG, + helmVersion=helm_3 + ) + remove_resource(helm3_catalog) + version = catalog_name+"-rancher-v3-issue-0.1.0" + wait_for_template_to_be_created(catalog_client, catalog_name) + wait_for_template_versions_to_be_created(catalog_client, version) + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + # check helm version at template level + templates = catalog_client.list_template(catalogId=helm3_catalog.id).data + assert templates[1].status.helmVersion == helm_3 + # check helm version at templateVersion level + templateVersion = catalog_client.list_templateVersion( + name=version) + assert templateVersion.data[0].status.helmVersion == helm_3 + # creating app with existing chart version in catalog + app1 = app_client.create_app( + name=app1_name, + externalId=cat_base+"0.1.0&namespace="+ns.name, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + ) + remove_resource(app1) + wait_for_workload(app_client, ns.name, count=1) + app1 = app_client.reload(app1) + # check that the correct helm version is on the app + assert "helmVersion" in app1 + assert app1.helmVersion == helm_3 + # changing branch on catalog to simulate adding a new chart version to the + # catalog + catalog_data = { + 'name': catalog_name, + 'branch': "helmversion-onupdate-2v", + 'url': DEFAULT_CATALOG, + 'helmVersion': helm_3 + } + helm3_catalog = catalog_client.update(helm3_catalog, catalog_data) + + def ensure_updated_catalog(catalog): + catalog = catalog_client.reload(catalog) + templates = catalog_client.list_template(catalogId=catalog.id).data + templatesString = ','.join([str(i) for i in templates]) + if "0.1.1" in templatesString: + return catalog + return None + helm3_catalog = wait_for( + lambda: ensure_updated_catalog(helm3_catalog), + fail_handler=lambda: + "Timed out waiting for catalog to stop transitioning") + + version = catalog_name+"-rancher-v3-issue-0.1.1" + wait_for_template_versions_to_be_created(catalog_client, version) + templates = catalog_client.list_template(catalogId=helm3_catalog.id).data + assert templates[1].status.helmVersion == helm_3 + templateVersion = catalog_client.list_templateVersion( + name=version) + assert templateVersion.data[0].status.helmVersion == helm_3 + project_client = user_project_client(admin_pc, admin_pc.project) + # update existing app with new version to ensure correct + # helm version is listed + app_data = { + 'name': app1_name, + 'externalId': cat_base+"0.1.1", + 'targetNamespace': ns.name, + 'projectId': admin_pc.project.id, + } + project_client.update(app1, app_data) + app1 = project_client.reload(app1) + assert "helmVersion" in app1 + assert app1.helmVersion == helm_3 + + # create a new app with new version to ensure helm version is listed + app2 = app_client.create_app( + name=app2_name, + externalId=cat_base+"0.1.1&namespace="+ns.name, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + ) + remove_resource(app2) + wait_for_workload(admin_pc.client, ns.name, count=2) + app2 = app_client.reload(app2) + # check that the correct helm version is on the app + assert "helmVersion" in app2 + assert app2.helmVersion == helm_3 + + +@pytest.mark.skip +def test_app_externalid_target_project_verification(admin_mc, + admin_pc, + user_factory, + remove_resource): + client = admin_mc.client + + p1 = client.create_project(name=random_str(), clusterId='local') + remove_resource(p1) + wait_for_condition('InitialRolesPopulated', 'True', client, p1) + p1 = client.reload(p1) + + # create a project scoped catalog in p1 + project_name = str.lstrip(p1.id, "local:") + name = random_str() + url = "https://github.com/rancher/integration-test-charts.git" + + client.create_project_catalog(name=name, + branch="master", + url=url, + projectId=p1.id, + ) + wait_until(lambda: len(client.list_template(projectCatalogId=name)) > 0) + + external_id = "catalog://?catalog=" + project_name + "/" + name + \ + "&type=projectCatalog&template=chartmuseum" \ + "&version=2.7.0" + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + app_data = { + 'name': random_str(), + 'externalId': external_id, + 'targetNamespace': ns.name, + 'projectId': admin_pc.project.id, + } + + try: + # using this catalog creating an app in another project should fail + admin_pc.client.create_app(app_data) + except ApiError as e: + assert e.error.status == 422 + assert "Cannot use catalog from" in e.error.message + + # create app in the p1 project, this should work + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p1.id) + remove_resource(ns) + app_name = random_str() + app_data = { + 'name': app_name, + 'externalId': external_id, + 'targetNamespace': ns.name, + 'projectId': p1.id, + "answers": [{ + "values": { + "defaultImage": "true", + "image.repository": "chartmuseum/chartmuseum", + "image.tag": "v0.7.1", + "env.open.STORAGE": "local", + "gcp.secret.enabled": "false", + "gcp.secret.key": "credentials.json", + "persistence.enabled": "true", + "persistence.size": "10Gi", + "ingress.enabled": "true", + "ingress.hosts[0]": "xip.io", + "service.type": "NodePort", + "env.open.SHOW_ADVANCED": "false", + "env.open.DEPTH": "0", + "env.open.ALLOW_OVERWRITE": "false", + "env.open.AUTH_ANONYMOUS_GET": "false", + "env.open.DISABLE_METRICS": "true" + } + }] + } + + p1_client = user_project_client(admin_pc, p1) + app1 = p1_client.create_app(app_data) + remove_resource(app1) + wait_for_workload(p1_client, ns.name, count=1) + + app = p1_client.reload(app1) + # updating app without passing projectId should not throw any error + update_data = { + 'name': app_name, + 'externalId': external_id, + 'targetNamespace': ns.name, + 'type': app, + "answers": [{ + "values": { + "defaultImage": "true", + "image.repository": "chartmuseum/chartmuseum", + "image.tag": "v0.7.1", + "env.open.STORAGE": "local", + "gcp.secret.enabled": "false", + "gcp.secret.key": "credentials.json", + "persistence.enabled": "true", + "persistence.size": "10Gi", + "ingress.enabled": "true", + "ingress.hosts[0]": "xip.io", + "service.type": "NodePort", + "env.open.SHOW_ADVANCED": "false", + "env.open.DEPTH": "1", + "env.open.ALLOW_OVERWRITE": "false", + "env.open.AUTH_ANONYMOUS_GET": "false", + "env.open.DISABLE_METRICS": "true" + } + }] + } + p1_client.update(app, update_data) + + +def test_local_app_can_deploy(admin_pc, admin_mc, remove_resource): + """Test that an app without an externalId can be deployed + successfully to simulate a local app deployed through cli""" + app_client = admin_pc.client + app_name = random_str() + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + + # create app without the externalId value set + app = app_client.create_app( + name=app_name, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + ) + remove_resource(app) + wait_for(lambda: app_client.by_id_app(app.id) is not None, + fail_handler=lambda: + "app could not be found") + + +def wait_for_workload(client, ns, timeout=60, count=0): + start = time.time() + interval = 0.5 + workloads = client.list_workload(namespaceId=ns) + while len(workloads.data) < count: + if time.time() - start > timeout: + print(workloads) + raise Exception('Timeout waiting for workload service') + time.sleep(interval) + interval *= 2 + workloads = client.list_workload(namespaceId=ns) + return workloads + + +def wait_for_replicas(client, ns, timeout=60, count=0): + start = time.time() + interval = 0.5 + workloads = client.list_workload(namespaceId=ns) + while workloads.data[0].deploymentStatus.replicas != count: + if time.time() - start > timeout: + print(workloads) + raise Exception('Timeout waiting for workload replicas') + time.sleep(interval) + interval *= 2 + workloads = client.list_workload(namespaceId=ns) + return workloads + + +def wait_for_monitor_metric(admin_cc, admin_mc, timeout=60): + client = admin_mc.client + start = time.time() + interval = 0.5 + monitorMetrics = client.list_monitor_metric(namespaceId=admin_cc. + cluster.id) + while len(monitorMetrics.data) == 0: + if time.time() - start > timeout: + print(monitorMetrics) + raise Exception('Timeout waiting for monitorMetrics service') + time.sleep(interval) + interval *= 2 + monitorMetrics = client.list_monitor_metric(namespaceId=admin_cc. + cluster.id) + found = False + for m in monitorMetrics: + if m.labels.component == "istio": + found = True + break + if not found: + raise AssertionError( + "not found istio expression") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_auth_configs.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_auth_configs.py new file mode 100644 index 0000000..07934aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_auth_configs.py @@ -0,0 +1,163 @@ +import pytest +from rancher import ApiError +from kubernetes.client import CoreV1Api, CustomObjectsApi +from .conftest import wait_for + + +def test_auth_configs(admin_mc): + client = admin_mc.client + + with pytest.raises(AttributeError) as e: + client.list_github_config() + + with pytest.raises(AttributeError) as e: + client.create_auth_config({}) + + configs = client.list_auth_config() + + assert configs.pagination.total == 15 + + gh = None + local = None + ad = None + azure = None + openldap = None + freeIpa = None + ping = None + adfs = None + keycloak = None + okta = None + googleoauth = None + shibboleth = None + oidc = None + keycloakoidc = None + genericoidc = None + + for c in configs: + print(c) + if c.type == "githubConfig": + gh = c + elif c.type == "localConfig": + local = c + elif c.type == "activeDirectoryConfig": + ad = c + elif c.type == "azureADConfig": + azure = c + elif c.type == "openLdapConfig": + openldap = c + elif c.type == "freeIpaConfig": + freeIpa = c + elif c.type == "pingConfig": + ping = c + elif c.type == "adfsConfig": + adfs = c + elif c.type == "keyCloakConfig": + keycloak = c + elif c.type == "oktaConfig": + okta = c + elif c.type == "googleOauthConfig": + googleoauth = c + elif c.type == "shibbolethConfig": + shibboleth = c + elif c.type == "oidcConfig": + oidc = c + elif c.type == "keyCloakOIDCConfig": + keycloakoidc = c + elif c.type == "genericOIDCConfig": + genericoidc = c + + for x in [gh, local, ad, azure, openldap, + freeIpa, ping, adfs, keycloak, okta, googleoauth, + oidc, keycloakoidc, genericoidc]: + assert x is not None + config = client.by_id_auth_config(x.id) + with pytest.raises(ApiError) as e: + client.delete(config) + assert e.value.error.status == 405 + + assert gh.actions.testAndApply + assert gh.actions.configureTest + + assert ad.actions.testAndApply + + assert azure.actions.testAndApply + assert azure.actions.configureTest + + assert openldap.actions.testAndApply + + assert freeIpa.actions.testAndApply + + assert ping.actions.testAndEnable + + assert adfs.actions.testAndEnable + + assert keycloak.actions.testAndEnable + + assert okta.actions.testAndEnable + + assert googleoauth.actions.configureTest + assert googleoauth.actions.testAndApply + + assert shibboleth.actions.testAndEnable + + assert oidc.actions.configureTest + assert oidc.actions.testAndApply + + assert genericoidc.actions.configureTest + assert genericoidc.actions.testAndApply + + +def test_auth_config_secrets(admin_mc): + client = admin_mc.client + key_data = { + "spKey": "-----BEGIN PRIVATE KEY-----", + } + ping_config = client.by_id_auth_config("ping") + # Ensure the config is enabled, else Rancher will think the auth provider + # has been disabled and needs to perform cleanup, + # which will delete the secret. + client.update(ping_config, key_data, enabled=True) + k8sclient = CoreV1Api(admin_mc.k8s_client) + # wait for ping secret to get created + wait_for(lambda: key_secret_creation(k8sclient), timeout=60, + fail_handler=lambda: "failed to create secret for ping spKey") + + secrets = k8sclient.list_namespaced_secret("cattle-global-data") + auth_configs_not_setup = ["adfsconfig-spkey", "oktaconfig-spkey", + "keycloakconfig-spkey"] + for s in secrets.items: + assert s.metadata.name not in auth_configs_not_setup + + +def key_secret_creation(k8sclient): + secrets = k8sclient.list_namespaced_secret("cattle-global-data") + for s in secrets.items: + if s.metadata.name == "pingconfig-spkey": + return True + return False + + +def test_auth_label(admin_mc, user_factory): + user = user_factory() + k8s_client = CustomObjectsApi(admin_mc.k8s_client) + user_token = wait_for( + lambda: user_token_creation(k8s_client, user.user.id), + timeout=30, + fail_handler=lambda: "failed to find token for factory user login" + ) + label_name = "authn.management.cattle.io/kind" + assert user_token["metadata"]["labels"][label_name] == "session" + + +def user_token_creation(k8s_client, user_id): + tokens = k8s_client.list_cluster_custom_object( + "management.cattle.io", + "v3", + "tokens" + ) + user_token = [ + token for token in tokens["items"] if token['userId'] == user_id + ] + if len(user_token) > 0: + return user_token[0] + return False diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_catalog.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_catalog.py new file mode 100644 index 0000000..e366d9e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_catalog.py @@ -0,0 +1,411 @@ +import pytest +import time +from rancher import ApiError +from .common import wait_for_template_to_be_created, \ + wait_for_template_to_be_deleted, random_str, wait_for_atleast_workload +from .conftest import set_server_version, wait_for, DEFAULT_CATALOG + + +def test_catalog(admin_mc, remove_resource): + client = admin_mc.client + name1 = random_str() + name2 = random_str() + url1 = "https://github.com/StrongMonkey/charts-1.git" + url2 = "HTTP://github.com/StrongMonkey/charts-1.git" + catalog1 = client.create_catalog(name=name1, + branch="test", + url=url1, + ) + remove_resource(catalog1) + catalog2 = client.create_catalog(name=name2, + branch="test", + url=url2, + ) + remove_resource(catalog2) + wait_for_template_to_be_created(client, name1) + wait_for_template_to_be_created(client, name2) + client.delete(catalog1) + client.delete(catalog2) + wait_for_template_to_be_deleted(client, name1) + wait_for_template_to_be_deleted(client, name2) + + +def test_invalid_catalog_chars(admin_mc, remove_resource): + client = admin_mc.client + name = random_str() + url = "https://github.com/%0dStrongMonkey%0A/charts-1.git" + with pytest.raises(ApiError) as e: + catalog = client.create_catalog(name=name, + branch="test", + url=url, + ) + remove_resource(catalog) + assert e.value.error.status == 422 + assert e.value.error.message == "Invalid characters in catalog URL" + url = "https://github.com/StrongMonkey\t/charts-1.git" + with pytest.raises(ApiError) as e: + catalog = client.create_catalog(name=name, + branch="test", + url=url, + ) + remove_resource(catalog) + assert e.value.error.status == 422 + assert e.value.error.message == "Invalid characters in catalog URL" + + +def test_global_catalog_template_access(admin_mc, user_factory, + remove_resource): + client = admin_mc.client + user1 = user_factory() + remove_resource(user1) + name = random_str() + + # Get all templates from library catalog that is enabled by default + updated = False + start = time.time() + interval = 0.5 + while not updated: + time.sleep(interval) + interval *= 2 + c = client.list_catalog(name="library").data[0] + if c.transitioning == "no": + updated = True + continue + if time.time() - start > 90: + raise AssertionError( + "Timed out waiting for catalog to stop transitioning") + + existing = client.list_template(catalogId="library").data + templates = [] + for t in existing: + templates.append("library-" + t.name) + + url = "https://github.com/mrajashree/charts.git" + catalog = client.create_catalog(name=name, + branch="onlyOne", + url=url, + ) + wait_for_template_to_be_created(client, name) + updated = False + start = time.time() + interval = 0.5 + while not updated: + time.sleep(interval) + interval *= 2 + c = client.list_catalog(name=name).data[0] + if c.transitioning == "no": + updated = True + continue + if time.time() - start > 90: + raise AssertionError( + "Timed out waiting for catalog to stop transitioning") + + # Now list all templates of this catalog + new_templates = client.list_template(catalogId=name).data + for t in new_templates: + templates.append(name + "-" + t.name) + + all_templates = existing + new_templates + # User should be able to list all these templates + user_client = user1.client + user_lib_templates = user_client.list_template(catalogId="library").data + user_new_templates = user_client.list_template(catalogId=name).data + user_templates = user_lib_templates + user_new_templates + assert len(user_templates) == len(all_templates) + + client.delete(catalog) + wait_for_template_to_be_deleted(client, name) + + +def test_user_can_list_global_catalog(user_factory, remove_resource): + user1 = user_factory() + remove_resource(user1) + user_client = user1.client + c = user_client.list_catalog(name="library") + assert len(c) == 1 + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_template_version_links(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test that template versionLinks are being updated based off the rancher + version set on the server and the query paramater 'rancherVersion' being + set. + """ + # 1.6.0 uses 2.0.0-2.2.0 + # 1.6.2 uses 2.1.0-2.3.0 + client = admin_mc.client + + c_name = random_str() + custom_catalog(name=c_name) + + # Set the server expecting both versions + set_server_version(client, "2.1.0") + + templates = client.list_template( + rancherVersion='2.1.0', catalogId=c_name) + + assert len(templates.data[0]['versionLinks']) == 2 + assert '1.6.0' in templates.data[0]['versionLinks'] + assert '1.6.2' in templates.data[0]['versionLinks'] + + # Set the server expecting only the older version + set_server_version(client, "2.0.0") + + templates = client.list_template( + rancherVersion='2.0.0', catalogId=c_name) + + assert len(templates.data[0]['versionLinks']) == 1 + assert '1.6.0' in templates.data[0]['versionLinks'] + + # Set the server expecting only the newer version + set_server_version(client, "2.3.0") + + templates = client.list_template( + rancherVersion='2.3.0', catalogId=c_name) + + assert len(templates.data[0]['versionLinks']) == 1 + assert '1.6.2' in templates.data[0]['versionLinks'] + + # Set the server expecting no versions, this should be outside both + # versions acceptable ranges + set_server_version(client, "2.4.0") + + templates = client.list_template( + rancherVersion='2.4.0', catalogId=c_name) + + assert len(templates.data[0]['versionLinks']) == 0 + + +def test_relative_paths(admin_mc, admin_pc, remove_resource): + """ This test adds a catalog's index.yaml with a relative chart url + and ensures that rancher can resolve the relative url""" + + client = admin_mc.client + catalogname = "cat-" + random_str() + url = "https://raw.githubusercontent.com/rancher/integration-test-charts"\ + "/relative-path" + catalog = client.create_catalog(catalogName=catalogname, branch="master", + url=url) + remove_resource(catalog) + + catalog = client.reload(catalog) + assert catalog['url'] == url + + # now deploy the app in the catalog to ensure we can resolve the tarball + ns = admin_pc.cluster.client.create_namespace( + catalogName="ns-" + random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + + wait_for_template_to_be_created(client, catalog.id) + mysqlha = admin_pc.client.create_app(name="app-" + random_str(), + externalId="catalog://?catalog=" + + catalog.id + + "&template=mysql" + "&version=1.6.2", + targetNamespace=ns.name, + projectId=admin_pc.project.id) + remove_resource(mysqlha) + wait_for_atleast_workload(pclient=admin_pc.client, nsid=ns.id, timeout=60, + count=1) + + +def test_cannot_delete_system_catalog(admin_mc): + """This test asserts that the system catalog cannot be delete""" + client = admin_mc.client + + system_catalog = client.by_id_catalog("system-library") + + with pytest.raises(ApiError) as e: + client.delete(system_catalog) + + assert e.value.error.status == 422 + assert e.value.error.message == 'not allowed to delete system-library' \ + ' catalog' + + +def test_system_catalog_missing_remove_link(admin_mc): + """This test asserts that the remove link is missing from system-catalog's + links""" + client = admin_mc.client + + system_catalog = client.by_id_catalog("system-library") + + assert "remove" not in system_catalog.links + + +def test_cannot_update_system_if_embedded(admin_mc): + """This test asserts that the system catalog cannot be updated if + system-catalog setting is set to 'bundled'""" + client = admin_mc.client + + system_catalog_setting = client.by_id_setting("system-catalog") + # this could potentially interfere with other tests if they were to rely + # on system-catalog setting + client.update_by_id_setting(id=system_catalog_setting.id, value="bundled") + + system_catalog = client.by_id_catalog("system-library") + + with pytest.raises(ApiError) as e: + client.update_by_id_catalog(id=system_catalog.id, branch="asd") + + assert e.value.error.status == 422 + assert e.value.error.message == 'not allowed to edit system-library' \ + ' catalog' + + +def test_embedded_system_catalog_missing_edit_link(admin_mc): + """This test asserts that the system catalog is missing the 'update' link + if system-catalog setting is set to 'bundled'""" + client = admin_mc.client + + system_catalog_setting = client.by_id_setting("system-catalog") + # this could potentially interfere with other tests if they were to rely + # on system-catalog setting + client.update_by_id_setting(id=system_catalog_setting.id, value="bundled") + + system_catalog = client.by_id_catalog("system-library") + + assert "update" not in system_catalog.links + + +@pytest.mark.nonparallel +def test_catalog_refresh(admin_mc): + """Test that on refresh the response includes the names of the catalogs + that are being refreshed""" + client = admin_mc.client + catalog = client.by_id_catalog("library") + out = client.action(obj=catalog, action_name="refresh") + assert out['catalogs'][0] == "library" + + catalogs = client.list_catalog() + out = client.action(obj=catalogs, action_name="refresh") + # It just needs to be more than none, other test can add/remove catalogs + # so a hard count will break + assert len(out['catalogs']) > 0, 'no catalogs in response' + + +def test_invalid_catalog_chart_names(admin_mc, remove_resource): + """Test chart with invalid name in catalog error properly + and test that a chart names are truncated and processed without + error""" + client = admin_mc.client + name = random_str() + catalog = client.create_catalog(name=name, + branch="broke-charts", + url=DEFAULT_CATALOG, + ) + remove_resource(catalog) + wait_for_template_to_be_created(client, catalog.id) + + def get_errored_catalog(catalog): + catalog = client.reload(catalog) + if catalog.transitioning == "error": + return catalog + return None + catalog = wait_for(lambda: get_errored_catalog(catalog), + fail_handler=lambda: + "catalog was not found in error state") + templates = client.list_template(catalogId=catalog.id).data + templatesString = ','.join([str(i) for i in templates]) + assert "areallylongname" not in templatesString + assert "bad-chart_name" not in templatesString + assert catalog.state == "processed" + assert catalog.transitioning == "error" + assert "Error in chart(s):" in catalog.transitioningMessage + assert "bad-chart_name" in catalog.transitioningMessage + assert "areallylongname" in catalog.transitioningMessage + # this will break if github repo changes + assert len(templates) == 6 + # checking that the errored catalog can be deleted successfully + client.delete(catalog) + wait_for_template_to_be_deleted(client, name) + assert not client.list_catalog(name=name).data + + +def test_invalid_catalog_chart_urls(admin_mc, remove_resource): + """Test chart with file:// and local:// url paths""" + client = admin_mc.client + name = random_str() + catalog = client.create_catalog(name=name, + branch="invalid-urls", + url=DEFAULT_CATALOG, + ) + remove_resource(catalog) + wait_for_template_to_be_created(client, catalog.id) + + def get_errored_catalog(catalog): + catalog = client.reload(catalog) + if catalog.transitioning == "error": + return catalog + return None + catalog = wait_for(lambda: get_errored_catalog(catalog), + fail_handler=lambda: + "catalog was not found in error state") + templates = client.list_template(catalogId=catalog.id).data + templatesString = ','.join([str(i) for i in templates]) + # url in index.yaml: + # local://azure-samples.github.io/helm-charts/aks-helloworld-0.1.0.tgz + assert "aks-goodbyeworld" not in templatesString + # url in index.yaml: + # file://azure-samples.github.io/helm-charts/aks-helloworld-0.1.0.tgz + assert "aks-helloworld" not in templatesString + assert catalog.state == "processed" + assert catalog.transitioning == "error" + assert "Error in chart(s):" in catalog.transitioningMessage + assert "aks-goodbyeworld" in catalog.transitioningMessage + assert "aks-helloworld" in catalog.transitioningMessage + # this will break if github repo changes + # valid url in index.yaml: + # https://azure-samples.github.io/helm-charts/azure-vote-0.1.0.tgz + assert len(templates) == 1 + # checking that the errored catalog can be deleted successfully + client.delete(catalog) + wait_for_template_to_be_deleted(client, name) + assert not client.list_catalog(name=name).data + + +def test_catalog_has_helmversion(admin_mc, remove_resource): + """Test to see that the helm version can be added to a catalog + on create and that the value is passed to the template""" + client = admin_mc.client + name1 = random_str() + name2 = random_str() + catalog1 = client.create_catalog(name=name1, + branch="master", + url=DEFAULT_CATALOG, + ) + remove_resource(catalog1) + catalog2 = client.create_catalog(name=name2, + branch="master", + url=DEFAULT_CATALOG, + helmVersion="helm_v3" + ) + + remove_resource(catalog2) + wait_for_template_to_be_created(client, name1) + wait_for_template_to_be_created(client, name2) + assert "helm_v3" not in catalog1 + assert catalog2.helmVersion == "helm_v3" + templates1 = client.list_template(catalogId=catalog1.id).data + for template in templates1: + assert "helmVersion" not in template.status + templates2 = client.list_template(catalogId=catalog2.id).data + for template in templates2: + assert "helmVersion" in template.status + assert template.status.helmVersion == "helm_v3" + + +def test_refresh_catalog_access(admin_mc, user_mc): + """Tests that a user with standard access is not + able to refresh a catalog. + """ + catalog = admin_mc.client.by_id_catalog("library") + out = admin_mc.client.action(obj=catalog, action_name="refresh") + assert out['catalogs'][0] == "library" + # use catalog obj from admin client to get action not available to user + with pytest.raises(ApiError) as e: + user_mc.client.action(obj=catalog, action_name="refresh") + assert e.value.error.status == 404 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster.py new file mode 100644 index 0000000..e98eed2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster.py @@ -0,0 +1,92 @@ +import kubernetes +from .common import random_str +from .conftest import wait_for, kubernetes_api_client +from kubernetes.client import CustomObjectsApi +from kubernetes.client.rest import ApiException + + +def test_cluster_node_count(admin_mc, remove_resource, + raw_remove_custom_resource): + """Test that the cluster node count gets updated as nodes are added""" + client = admin_mc.client + cluster = client.create_cluster( + name=random_str(), + rancherKubernetesEngineConfig={ + "accessKey": "junk" + } + ) + remove_resource(cluster) + + def _check_node_count(cluster, nodes): + c = client.reload(cluster) + return c.nodeCount == nodes + + def _node_count_fail(cluster, nodes): + c = client.reload(cluster) + s = "cluster {} failed to have proper node count, expected: {} has: {}" + return s.format(c.id, nodes, c.nodeCount) + + node_count = 0 + wait_for(lambda: _check_node_count(cluster, node_count), + fail_handler=lambda: _node_count_fail(cluster, node_count)) + + # Wait for cluster ns to be created + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + ns_api = kubernetes.client.CoreV1Api(k8s_client) + + def _check_cluster_ns(cluster): + try: + ns = ns_api.read_namespace(cluster.id) + except ApiException as e: + if e.status != 404: + raise(e) + return False + else: + return ns is not None + + def _check_cluster_ns_fail(cluster): + s = "cluster {} namespace isn't created" + return s.format(cluster.id) + + wait_for(lambda: _check_cluster_ns(cluster), + fail_handler=lambda: _check_cluster_ns_fail(cluster)) + + # Nodes have to be created manually through k8s client to attach to a + # pending cluster + k8s_dynamic_client = CustomObjectsApi(admin_mc.k8s_client) + body = { + "metadata": { + "name": random_str(), + "namespace": cluster.id, + }, + "kind": "Node", + "apiVersion": "management.cattle.io/v3", + } + + dynamic_nt = k8s_dynamic_client.create_namespaced_custom_object( + "management.cattle.io", "v3", cluster.id, 'nodes', body) + raw_remove_custom_resource(dynamic_nt) + + node_count = 1 + wait_for(lambda: _check_node_count(cluster, node_count), + fail_handler=lambda: _node_count_fail(cluster, node_count)) + + # Create node number 2 + body['metadata']['name'] = random_str() + + dynamic_nt1 = k8s_dynamic_client.create_namespaced_custom_object( + "management.cattle.io", "v3", cluster.id, 'nodes', body) + raw_remove_custom_resource(dynamic_nt1) + + node_count = 2 + wait_for(lambda: _check_node_count(cluster, node_count), + fail_handler=lambda: _node_count_fail(cluster, node_count)) + + # Delete a node + k8s_dynamic_client.delete_namespaced_custom_object( + "management.cattle.io", "v3", cluster.id, 'nodes', + dynamic_nt1['metadata']['name']) + + node_count = 1 + wait_for(lambda: _check_node_count(cluster, node_count), + fail_handler=lambda: _node_count_fail(cluster, node_count)) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_auth_tokens.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_auth_tokens.py new file mode 100644 index 0000000..31af752 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_auth_tokens.py @@ -0,0 +1,101 @@ +import subprocess +import pytest +from .conftest import create_kubeconfig, wait_for +from sys import platform +from kubernetes.client import CustomObjectsApi +from rancher import ApiError + + +# test if the kubeconfig works to list api-resources for the fqdn context +def exec_kubectl(request, dind_cc, client, cmd='api-resources'): + cluster_kubeconfig_file = create_kubeconfig(request, dind_cc, client) + # verify cluster scoped access + try: + return subprocess.check_output( + 'kubectl ' + cmd + + ' --kubeconfig ' + cluster_kubeconfig_file + + ' --context ' + dind_cc.name + '-fqdn', + stderr=subprocess.STDOUT, shell=True, + ) + except subprocess.CalledProcessError as err: + print('kubectl error: ' + str(err.output)) + raise err + + +# test generator for multiple attempts +def kubectl_available(request, dind_cc, client): + def test(): + try: + exec_kubectl(request, dind_cc, client) + return True + except subprocess.CalledProcessError: + return False + return test + + +# as an admin, we should have access +@pytest.mark.skip(reason='cluster testing needs refactor') +@pytest.mark.skipif(platform != 'linux', reason='requires linux for dind') +@pytest.mark.nonparallel +def test_admin_api_resources(request, dind_cc): + wait_for(kubectl_available(request, dind_cc, dind_cc.admin_mc.client)) + + +# as a user which has not been given permission, we should fail +@pytest.mark.skip(reason='cluster testing needs refactor') +@pytest.mark.skipif(platform != 'linux', reason='requires linux for dind') +@pytest.mark.nonparallel +def test_user_no_template(request, dind_cc, user_mc): + test_admin_api_resources(request, dind_cc) + with pytest.raises(ApiError) as e: + exec_kubectl(request, dind_cc, user_mc.client) + assert e.value.error.status == 403, 'user should not have permission' + + +# as a user that is a cluster member, we should have access +@pytest.mark.skip(reason='cluster testing needs refactor') +@pytest.mark.skipif(platform != 'linux', reason='requires linux for dind') +@pytest.mark.nonparallel +def test_user_with_template(request, dind_cc, user_mc): + test_user_no_template(request, dind_cc, user_mc) + role_template = { + 'clusterId': dind_cc.cluster.id, + 'userPrincipalId': 'local://' + user_mc.user.id, + 'roleTemplateId': 'cluster-member' + } + dind_cc.admin_mc.client.create_clusterRoleTemplateBinding(role_template) + wait_for(kubectl_available(request, dind_cc, user_mc.client)) + + +# as a user that is part of a group that has access, we should have access +@pytest.mark.skip(reason='cluster testing needs refactor') +@pytest.mark.skipif(platform != 'linux', reason='requires linux for dind') +@pytest.mark.nonparallel +def test_user_group_with_template(request, dind_cc, user_mc): + test_user_no_template(request, dind_cc, user_mc) + crdClient = CustomObjectsApi(dind_cc.admin_mc.k8s_client) + user_attribute = crdClient.get_cluster_custom_object( + 'management.cattle.io', + 'v3', + 'userattributes', + user_mc.user.id + ) + user_attribute['GroupPrincipals']['local']['Items'] = [{ + 'metadata': { + 'name': 'local_group://test-123' + } + }] + crdClient.replace_cluster_custom_object( + 'management.cattle.io', + 'v3', + 'userattributes', + user_mc.user.id, + user_attribute + ) + role_template = { + 'clusterId': dind_cc.cluster.id, + 'groupPrincipalId': 'local_group://test-123', + 'roleTemplateId': 'cluster-member' + } + dind_cc.admin_mc.client.create_clusterRoleTemplateBinding(role_template) + wait_for(kubectl_available(request, dind_cc, user_mc.client)) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_catalog.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_catalog.py new file mode 100644 index 0000000..1a42e00 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_catalog.py @@ -0,0 +1,162 @@ +from .conftest import wait_until, wait_until_available +from rancher import ApiError +from .common import random_str +import time + + +def test_cluster_catalog_templates_access(admin_mc, user_factory, + remove_resource, admin_pc): + # Cluster-owner,cluster-member, and all project-owners/members + # in that cluster should have access to cluster catalog's templates + + # First add a user as cluster member to this cluster + user1 = user_factory() + remove_resource(user1) + admin_client = admin_mc.client + crtb_member = admin_client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId="cluster-member", + userId=user1.user.id) + remove_resource(crtb_member) + + wait_until(crtb_cb(admin_client, crtb_member)) + + # cluster roles should be able to list global catalog + # so that it shows up in dropdown on the app launch page + c = user1.client.list_catalog(name="library") + assert len(c) == 1 + + # Now create a cluster catalog + name = random_str() + catalog_name = "local:" + name + url = "https://github.com/mrajashree/charts.git" + cc = admin_client.create_cluster_catalog(name=name, + branch="onlyOne", + url=url, + clusterId="local", + ) + wait_for_clustercatalog_template_to_be_created(admin_client, catalog_name) + + # Now add a user to a project within this cluster as project-owner + user2 = user_factory() + remove_resource(user2) + prtb_owner = admin_client.create_project_role_template_binding( + userId=user2.user.id, + roleTemplateId="project-owner", + projectId=admin_pc.project.id, + ) + remove_resource(prtb_owner) + wait_until(prtb_cb(admin_client, prtb_owner)) + + wait_until_available(admin_client, prtb_owner) + project_owner_client = user2.client + + templates = \ + project_owner_client.list_template(clusterCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + project_owner_client.list_template(clusterCatalogId=catalog_name) + assert len(templateversions) == 1 + + # project roles should be able to list global and cluster catalogs + # so that they show up in dropdown on the app launch page + c = project_owner_client.list_catalog(name="library") + assert len(c) == 1 + cluster_cat = project_owner_client.list_cluster_catalog(name=name) + assert len(cluster_cat) == 1 + # but project-owners should't have cud permissions for cluster catalog + # create must fail + try: + project_owner_client.create_cluster_catalog(name=random_str(), + branch="onlyOne", + url=url, + clusterId="local", + ) + except ApiError as e: + assert e.error.status == 403 + + # delete must fail + try: + project_owner_client.delete(cc) + except ApiError as e: + assert e.error.status == 403 + + # update must fail + try: + project_owner_client.update(cc, branch="master") + except ApiError as e: + assert e.error.status == 403 + + cluster_member_client = user1.client + templates = \ + cluster_member_client.list_template(clusterCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + cluster_member_client.list_template(clusterCatalogId=catalog_name) + assert len(templateversions) == 1 + + # Now remove user1 also from the cluster, this should mean user1 should + # no longer be able to access the catalog and templates + admin_client.delete(crtb_member) + wait_for_clustercatalog_template_to_be_deleted(user1.client, catalog_name, + 120) + + # Now remove the user admin_pc from the project of this cluster, + # so admin_pc should no longer have access to catalog and templates + admin_client.delete(prtb_owner) + wait_for_clustercatalog_template_to_be_deleted(user2.client, catalog_name, + 120) + + templateversions = \ + user2.client.list_template(clusterCatalogId=catalog_name) + assert len(templateversions) == 0 + + admin_client.delete(cc) + wait_for_clustercatalog_template_to_be_deleted(admin_client, catalog_name, + 120) + + +def wait_for_clustercatalog_template_to_be_created(client, name, timeout=45): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(clusterCatalogId=name) + if len(templates) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def wait_for_clustercatalog_template_to_be_deleted(client, name, timeout=60): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(clusterCatalogId=name) + if len(templates) == 0: + found = True + time.sleep(interval) + interval *= 2 + + +def crtb_cb(client, crtb): + """Wait for the crtb to have the userId populated""" + def cb(): + c = client.reload(crtb) + return c.userPrincipalId is not None + return cb + + +def prtb_cb(client, prtb): + """Wait for the crtb to have the userId populated""" + def cb(): + p = client.reload(prtb) + return p.userPrincipalId is not None + return cb diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_defaults.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_defaults.py new file mode 100644 index 0000000..bf3c4cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_defaults.py @@ -0,0 +1,233 @@ +import json +import pytest +from rancher import ApiError +from .common import random_str +from .conftest import wait_for + + +@pytest.fixture(scope='module') +def check_cluster_kubernetes_version(admin_mc): + """ + Checks the local cluster's k8s version + """ + client = admin_mc.client + cluster = client.by_id_cluster("local") + version = cluster.get("version") + if version is not None: + k8s_version = int(version.get("gitVersion")[3:5]) + if k8s_version >= 25: + pytest.skip("Needs to be reworked for PSA") + + +@pytest.mark.skip(reason="cluster-defaults disabled") +def test_generic_initial_defaults(admin_mc): + cclient = admin_mc.client + schema_defaults = {} + setting_defaults = {} + + data = cclient.schema.types['cluster'].resourceFields + default = data["enableNetworkPolicy"]["default"] + + for name in cclient.schema.types['cluster'].resourceFields.keys(): + if name == "enableNetworkPolicy": + schema_defaults["enableNetworkPolicy"] = default + + for name in cclient.schema.types['rancherKubernetesEngineConfig'] \ + .resourceFields.keys(): + if name == "ignoreDockerVersion": + schema_defaults["ignoreDockerVersion"] = cclient.schema. \ + types["rancherKubernetesEngineConfig"]. \ + resourceFields["ignoreDockerVersion"]. \ + data_dict()["default"] + + setting = cclient.list_setting(name="cluster-defaults") + data = json.loads(setting['data'][0]['default']) + + setting_defaults["enableNetworkPolicy"] = data["enableNetworkPolicy"] + setting_defaults["ignoreDockerVersion"] = \ + data["rancherKubernetesEngineConfig"]["ignoreDockerVersion"] + + assert schema_defaults == setting_defaults + + +def test_generic_initial_conditions(admin_mc, remove_resource): + cluster = admin_mc.client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig={ + "accessKey": "asdfsd"}) + remove_resource(cluster) + + assert len(cluster.conditions) == 3 + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + assert cluster.conditions[1].type == 'Provisioned' + assert cluster.conditions[1].status == 'Unknown' + + assert cluster.conditions[2].type == 'Waiting' + assert cluster.conditions[2].status == 'Unknown' + + assert 'exportYaml' not in cluster.actions + + +def test_eks_cluster_immutable_subnets(admin_mc, remove_resource): + cluster = admin_mc.client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig={ + "accessKey": "asdfsd", + "secretKey": "verySecretKey", + "subnets": [ + "subnet-045bfaeca7d3f1cb3", + "subnet-02388a166136f98c4" + ]}) + remove_resource(cluster) + + def cannot_modify_error(): + with pytest.raises(ApiError) as e: + # try to edit cluster subnets + admin_mc.client.update_by_id_cluster( + id=cluster.id, + amazonElasticContainerServiceConfig={ + "accessKey": "asdfsd", + "secretKey": "verySecretKey", + "subnets": [ + "subnet-045bfaeca7d3f1cb3" + ]}) + if e.value.error.status == 404 or e.value.error.status == 500: + return False + print(e) + assert e.value.error.status == 422 + assert e.value.error.message ==\ + 'cannot modify EKS subnets after creation' + return True + + # lister used by cluster validator may not be up to date, may need to retry + wait_for(cannot_modify_error) + + # tests updates still work + new = admin_mc.client.update_by_id_cluster( + id=cluster.id, + name=cluster.name, + description="update", + amazonElasticContainerServiceConfig={ + # required field when updating KE clusters + "driverName": "amazonelasticcontainerservice", + "accessKey": "asdfsd", + "secretKey": "verySecretKey", + "subnets": [ + "subnet-045bfaeca7d3f1cb3", + "subnet-02388a166136f98c4" + ]}) + + assert new.id == cluster.id + assert not hasattr(cluster, "description") + assert hasattr(new, "description") + + +def test_rke_initial_conditions(admin_mc, remove_resource): + cluster = admin_mc.client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "accessKey": "asdfsd"}) + remove_resource(cluster) + + assert len(cluster.conditions) == 3 + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + assert cluster.conditions[1].type == 'Provisioned' + assert cluster.conditions[1].status == 'Unknown' + + assert cluster.conditions[2].type == 'Waiting' + assert cluster.conditions[2].status == 'Unknown' + + assert 'exportYaml' in cluster.actions + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_psp_enabled_set(admin_mc, remove_resource): + """Asserts podSecurityPolicy field is used to populate pspEnabled in + cluster capabilities""" + admin_client = admin_mc.client + cluster = admin_client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "accessKey": "asdfsd", + "services": { + "kubeApi": { + "podSecurityPolicy": True, + } + } + }) + remove_resource(cluster) + + def psp_set_to_true(): + updated_cluster = admin_client.by_id_cluster(id=cluster.id) + capabilities = updated_cluster.get("capabilities") + if capabilities is not None: + return capabilities.get("pspEnabled") is True + return None + + wait_for(lambda: psp_set_to_true(), fail_handler=lambda: "failed waiting " + "for pspEnabled to be set") + + +def test_import_initial_conditions(admin_mc, remove_resource): + cluster = admin_mc.client.create_cluster(name=random_str()) + remove_resource(cluster) + + assert not cluster.conditions + + +def test_rke_k8s_deprecated_versions(admin_mc, remove_resource): + client = admin_mc.client + deprecated_versions_setting = client.by_id_setting( + "k8s-versions-deprecated") + client.update_by_id_setting(id=deprecated_versions_setting.id, + value="{\"v1.8.10-rancher1-1\":true}") + with pytest.raises(ApiError) as e: + cluster = client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "kubernetesVersion": "v1.8.10-rancher1-1"}) + remove_resource(cluster) + assert e.value.error.status == 500 + assert e.value.error.message == 'Requested kubernetesVersion ' \ + 'v1.8.10-rancher1-1 is deprecated' + client.update_by_id_setting(id=deprecated_versions_setting.id, + value="") + + +def test_save_as_template_action_rbac(admin_mc, remove_resource, user_factory): + cluster = admin_mc.client.create_cluster(name=random_str(), + rancherKubernetesEngineConfig={ + "services": { + "type": + "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": + "false", + "podSecurityPolicy": + "false", + "serviceNodePort\ + Range": + "30000-32767", + "type": + "kubeAPIService" + } + } + }) + remove_resource(cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + try: + admin_mc.client.action(obj=cluster, action_name="saveAsTemplate", + clusterTemplateName="template1", + clusterTemplateRevisionName="v1") + except ApiError as e: + assert e.error.status == 503 + + user = user_factory() + user_cluster = user.client.create_cluster(name=random_str()) + remove_resource(user_cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + try: + user.client.action(obj=user_cluster, action_name="saveAsTemplate") + except AttributeError as e: + assert e is not None diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_role_template_bindings.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_role_template_bindings.py new file mode 100644 index 0000000..b1f9adf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_role_template_bindings.py @@ -0,0 +1,67 @@ +import pytest + +from .common import random_str +from .conftest import wait_for +from rancher import ApiError + + +def test_cannot_target_users_and_group(admin_mc, remove_resource): + """Asserts that a clusterroletemplatebinding cannot target both + user and group subjects""" + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + crtb = admin_client.create_cluster_role_template_binding( + name="crtb-"+random_str(), + clusterId="local", + userId=admin_mc.user.id, + groupPrincipalId="someauthprovidergroupid", + roleTemplateId="clustercatalogs-view") + remove_resource(crtb) + assert e.value.error.status == 422 + assert "must target a user [userId]/[userPrincipalId] OR a group " \ + "[groupId]/[groupPrincipalId]" in e.value.error.message + + +def test_must_have_target(admin_mc, remove_resource): + """Asserts that a clusterroletemplatebinding must have a subject""" + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + crtb = admin_client.create_cluster_role_template_binding( + name="crtb-" + random_str(), + clusterId="local", + roleTemplateId="clustercatalogs-view") + remove_resource(crtb) + assert e.value.error.status == 422 + assert "must target a user [userId]/[userPrincipalId] OR a group " \ + "[groupId]/[groupPrincipalId]" in e.value.error.message + + +def test_cannot_update_subjects_or_cluster(admin_mc, remove_resource): + """Asserts non-metadata fields cannot be updated""" + admin_client = admin_mc.client + old_crtb = admin_client.create_cluster_role_template_binding( + name="crtb-" + random_str(), + clusterId="local", + userId=admin_mc.user.id, + roleTemplateId="clustercatalogs-view") + remove_resource(old_crtb) + + wait_for(lambda: admin_client.reload(old_crtb).userPrincipalId is not None) + old_crtb = admin_client.reload(old_crtb) + + crtb = admin_client.update_by_id_cluster_role_template_binding( + id=old_crtb.id, + clusterId="fakecluster", + userId="", + userPrincipalId="asdf", + groupPrincipalId="asdf", + group="asdf" + ) + + assert crtb.get("clusterId") == old_crtb.get("clusterId") + assert crtb.get("userId") == old_crtb.get("userId") + assert crtb.get("userPrincipalId") == old_crtb.get("userPrincipalId") + assert crtb.get("groupPrincipalId") == old_crtb.get("groupPrincipalId") + assert crtb.get("group") == old_crtb.get("group") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_scan.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_scan.py new file mode 100644 index 0000000..e8bcc84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_cluster_scan.py @@ -0,0 +1,16 @@ +from .common import random_str +from .conftest import cluster_and_client + + +def test_run_scan_not_available_on_not_ready_cluster(admin_mc, + remove_resource): + client = admin_mc.client + cluster = client.create_cluster( + name=random_str(), + rancherKubernetesEngineConfig={ + "accessKey": "junk" + } + ) + remove_resource(cluster) + _, cluster_client = cluster_and_client(cluster.id, client) + assert 'runSecurityScan' not in cluster.actions diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_clustertemplate.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_clustertemplate.py new file mode 100644 index 0000000..decacbf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_clustertemplate.py @@ -0,0 +1,1158 @@ +from .common import random_str, check_subject_in_rb +from rancher import ApiError +from .conftest import wait_until, wait_for, DEFAULT_TIMEOUT +import pytest +import time +import kubernetes + +rb_resource = 'rolebinding' + + +@pytest.fixture(scope='module') +def check_cluster_kubernetes_version(admin_mc): + """ + Checks the local cluster's k8s version + """ + client = admin_mc.client + cluster = client.by_id_cluster("local") + version = cluster.get("version") + if version is not None: + k8s_version = int(version.get("gitVersion")[3:5]) + if k8s_version >= 25: + pytest.skip("Needs to be reworked for PSA") + + +def test_create_cluster_template_with_revision(admin_mc, remove_resource): + + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_resource(cluster_template) + templateId = cluster_template.id + _ = \ + create_cluster_template_revision(admin_mc.client, templateId) + _ = \ + create_cluster_template_revision(admin_mc.client, templateId) + client = admin_mc.client + template_reloaded = client.by_id_cluster_template(cluster_template.id) + assert template_reloaded.links.revisions is not None + + +def test_create_template_revision_k8s_translation(admin_mc, remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_resource(cluster_template) + tId = cluster_template.id + client = admin_mc.client + + cconfig = { + "rancherKubernetesEngineConfig": { + "kubernetesVersion": "1.15" + } + } + with pytest.raises(ApiError) as e: + client.create_cluster_template_revision(clusterConfig=cconfig, + clusterTemplateId=tId, + enabled="true") + assert e.value.error.status == 422 + + # template k8s question needed if using generic version + cconfig = { + "rancherKubernetesEngineConfig": { + "kubernetesVersion": "1.15.x" + } + } + questions = [{ + "variable": "dockerRootDir", + "required": "false", + "type": "string", + "default": "/var/lib/docker" + }] + with pytest.raises(ApiError) as e: + client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + questions=questions, + enabled="true") + assert e.value.error.status == 422 + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_default_pod_sec(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + + tId = cluster_template.id + client = admin_mc.client + cconfig = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "defaultPodSecurityPolicyTemplateId": "restricted", + } + rev = client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + enabled="true") + + time.sleep(2) + cluster = wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id) + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + assert cluster.defaultPodSecurityPolicyTemplateId == "restricted" + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +def test_cron_schedule(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + + tId = cluster_template.id + client = admin_mc.client + cconfig = { + "dockerRootDir": "/var/lib/docker", + "enableClusterAlerting": "false", + "enableClusterMonitoring": "false", + "enableNetworkPolicy": "false", + "labels": {}, + "clusterTemplateRevisionId": "cattle-global-data:ctr-xxxxx", + "name": "testclusterfromtemplate", + "rancherKubernetesEngineConfig": {}, + "scheduledClusterScan": { + "enabled": "true", + "scanConfig": { + "cisScanConfig": { + "failuresOnly": "false", + "overrideBenchmarkVersion": "rke-cis-1.4", + "profile": "permissive", + "skip": "null" + } + }, + "scheduleConfig": { + "cronSchedule": "" + } + }, + "type": "cluster" + } + rev = client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + enabled="true") + + time.sleep(2) + cluster = wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id) + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +def test_check_default_revision(admin_mc, remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_resource(cluster_template) + templateId = cluster_template.id + first_revision = \ + create_cluster_template_revision(admin_mc.client, templateId) + client = admin_mc.client + wait_for_default_revision(client, templateId, first_revision.id) + # delete the cluster template revision, it should error out + with pytest.raises(ApiError) as e: + client.delete(first_revision) + assert e.value.error.status == 403 + + +@pytest.mark.skip +def test_create_cluster_with_template(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + templateId = cluster_template.id + + template_revision = \ + create_cluster_template_revision(admin_mc.client, templateId) + + # create a cluster with this template + answers = { + "values": { + "dockerRootDir": "/var/lib/docker123", + "rancherKubernetesEngineConfig.ignoreDockerVersion": + "false" + } + } + + revId = template_revision.id + client = admin_mc.client + + cluster = wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=revId, + description="template from cluster", + answers=answers) + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + assert cluster.questions is not None + k8s_version = cluster.rancherKubernetesEngineConfig.kubernetesVersion + assert k8s_version != "v1.15.x" + + # edit cluster should not fail + client.update(cluster, name=random_str(), clusterTemplateRevisionId=revId) + + # edit cluster to remove template must fail + with pytest.raises(ApiError) as e: + client.update(cluster, name=random_str(), clusterTemplateId=None, + clusterTemplateRevisionId=None) + assert e.value.error.status == 422 + + # delete the cluster template, it should error out + with pytest.raises(ApiError) as e: + client.delete(cluster_template) + assert e.value.error.status == 422 + + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +def test_create_cluster_validations(admin_mc, remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_resource(cluster_template) + templateId = cluster_template.id + template_revision = \ + create_cluster_template_revision(admin_mc.client, templateId) + # create a cluster with this template + revId = template_revision.id + client = admin_mc.client + rConfig = getRKEConfig() + try: + wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=revId, + description="template from cluster", + rancherKubernetesEngineConfig=rConfig) + + except ApiError as e: + assert e.error.status == 500 + + +@pytest.mark.nonparallel +def test_create_cluster_template_with_members(admin_mc, remove_resource, + user_factory): + client = admin_mc.client + user_member = user_factory() + remove_resource(user_member) + user_not_member = user_factory() + remove_resource(user_not_member) + members = [{"userPrincipalId": "local://" + user_member.user.id, + "accessType": "read-only"}] + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_resource(cluster_template) + time.sleep(30) + # check who has access to the cluster template + # admin and user_member should be able to list it + id = cluster_template.id + ct = client.by_id_cluster_template(id) + assert ct is not None + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = cluster_template.id.split(":") + name = split[1] + rb_name = name + "-ct-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_member.user.id, rb_name), + timeout=60, + fail_handler=lambda: "failed to check rolebinding") + um_client = user_member.client + ct = um_client.by_id_cluster_template(id) + assert ct is not None + + # user not added as member shouldn't be able to access + unm_client = user_not_member.client + try: + unm_client.by_id_cluster_template(id) + except ApiError as e: + assert e.error.status == 403 + + # add * as member to share with all + new_members = [{"userPrincipalId": "local://" + user_member.user.id, + "accessType": "read-only"}, {"groupPrincipalId": "*", + "accessType": "read-only"}] + client.update(ct, members=new_members) + + split = cluster_template.id.split(":") + name = split[1] + rb_name = name + "-ct-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + 'system:authenticated', rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + time.sleep(30) + ct = user_not_member.client.by_id_cluster_template(id) + assert ct is not None + + +def test_creation_standard_user(admin_mc, remove_resource, user_factory): + user_member = user_factory() + remove_resource(user_member) + um_client = user_member.client + with pytest.raises(ApiError) as e: + um_client.create_cluster_template(name="user template", + description="user template") + assert e.value.error.status == 403 + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_check_enforcement(admin_mc, remove_resource, + list_remove_resource, user_factory): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + templateId = cluster_template.id + rev = \ + create_cluster_template_revision(admin_mc.client, templateId) + + client = admin_mc.client + + # turn on the enforcement + client.update_by_id_setting(id='cluster-template-enforcement', + value="true") + + # a globaladmin can create a rke cluster without a template + cluster = client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "accessKey": "asdfsd"}) + remove_list.insert(0, cluster) + + # a user cannot create an rke cluster without template + user = user_factory() + remove_resource(user) + crtb_owner = client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId="cluster-owner", + userId=user.user.id) + remove_resource(crtb_owner) + wait_until(rtb_cb(client, crtb_owner)) + + user_client = user.client + with pytest.raises(ApiError) as e: + user_client.create_cluster(name=random_str(), + rancherKubernetesEngineConfig={ + "accessKey": "asdfsd"}) + assert e.value.error.status == 422 + + # a user can create a non-rke cluster without template + cluster2 = user_client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig={ + "accessKey": "asdfsd"}) + remove_list.insert(0, cluster2) + + # a user can create an rke cluster with a public template + template_reloaded = client.by_id_cluster_template(templateId) + new_members = [{"groupPrincipalId": "*", "accessType": "read-only"}] + client.update(template_reloaded, members=new_members) + + cluster3 = wait_for_cluster_create(user_client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + remove_list.insert(0, cluster3) + client.update_by_id_setting(id='cluster-template-enforcement', + value="false") + + +def test_revision_creation_permission(admin_mc, remove_resource, + user_factory): + user_readonly = user_factory() + user_owner = user_factory() + members = [{"userPrincipalId": "local://" + user_readonly.user.id, + "accessType": "read-only"}, + {"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "owner"}] + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_resource(cluster_template) + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = cluster_template.id.split(":") + name = split[1] + rb_name = name + "-ct-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_readonly.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + rb_name = name + "-ct-a" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_owner.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + templateId = cluster_template.id + # user with accessType=owner should be able to create revision + # since a standard user can add revisions to template shared + # with owner access + + create_cluster_template_revision(user_owner.client, templateId) + + # user with read-only accessType should get Forbidden error + with pytest.raises(ApiError) as e: + create_cluster_template_revision(user_readonly.client, templateId) + assert e.value.error.status == 403 + + +def test_updated_members_revision_access(admin_mc, remove_resource, + user_factory): + # create cluster template without members and a revision + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_resource(cluster_template) + templateId = cluster_template.id + rev = \ + create_cluster_template_revision(admin_mc.client, templateId) + + # update template to add a user as member + user_member = user_factory() + members = [{"userPrincipalId": "local://" + user_member.user.id, + "accessType": "read-only"}] + admin_mc.client.update(cluster_template, members=members) + + # this member should get access to existing revision "rev" + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = rev.id.split(":") + name = split[1] + rb_name = name + "-ctr-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_member.user.id, rb_name), + timeout=120, + fail_handler=fail_handler(rb_resource)) + revision = user_member.client.by_id_cluster_template_revision(rev.id) + assert revision is not None + + # remove this user from cluster_template members list + admin_mc.client.update(cluster_template, members=[]) + + # now this user should not be able to see that revision + try: + user_member.client.by_id_cluster_template_revision(rev.id) + except ApiError as e: + assert e.error.status == 403 + + +def test_permissions_removed_on_downgrading_access(admin_mc, remove_resource, + user_factory): + user_owner = user_factory() + remove_resource(user_owner) + members = [{"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "owner"}] + # create cluster template with one member having "member" accessType + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_resource(cluster_template) + + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = cluster_template.id.split(":") + name = split[1] + rb_name = name + "-ct-a" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_owner.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + + # user with accessType=owner should be able to update template + # so adding new member by the user_member should be allowed + new_member = user_factory() + remove_resource(new_member) + members = [{"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "owner"}, + {"userPrincipalId": "local://" + new_member.user.id, + "accessType": "read-only"}] + user_owner.client.update(cluster_template, members=members) + + # now change user_owner's accessType to read-only + members = [{"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "read-only"}, + {"userPrincipalId": "local://" + new_member.user.id, + "accessType": "read-only"}] + admin_mc.client.update(cluster_template, members=members) + rb_name = name + "-ct-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_owner.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + + # user_owner should not be allowed to update cluster template now + # test updating members field by removing new_member + members = [{"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "read-only"}] + try: + user_owner.client.update(cluster_template, members=members) + except ApiError as e: + assert e.error.status == 403 + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_required_template_question(admin_mc, remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_resource(cluster_template) + tId = cluster_template.id + client = admin_mc.client + + cconfig = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "defaultPodSecurityPolicyTemplateId": "restricted", + } + questions = [{ + "variable": "dockerRootDir", + "required": "true", + "type": "string", + "default": "" + }, + { + "variable": + "rancherKubernetesEngineConfig.ignoreDockerVersion", + "required": "false", + "type": "boolean", + "default": "true" + }] + + rev = client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + questions=questions, + enabled="true") + + # creating a cluster with this template with no answer should fail + answers = { + "values": { + "rancherKubernetesEngineConfig.ignoreDockerVersion": + "false" + } + } + + try: + wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster", + answers=answers) + except ApiError as e: + assert e.error.status == 422 + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_secret_template_answers(admin_mc, remove_resource, + list_remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + tId = cluster_template.id + client = admin_mc.client + + cconfig = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "defaultPodSecurityPolicyTemplateId": "restricted", + } + azureClientId = "rancherKubernetesEngineConfig.cloudProvider.\ +azureCloudProvider.aadClientId" + azureClientSecret = "rancherKubernetesEngineConfig.cloudProvider.\ +azureCloudProvider.aadClientSecret" + + questions = [{ + "variable": "dockerRootDir", + "required": "true", + "type": "string", + "default": "" + }, + { + "variable": azureClientId, + "required": "true", + "type": "string", + "default": "abcdClientId" + }, + { + "variable": azureClientSecret, + "required": "true", + "type": "string", + "default": "" + }] + + rev = client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + questions=questions, + enabled="true") + + # creating a cluster with this template + answers = { + "values": { + "dockerRootDir": "/var/lib/docker123", + azureClientId: "abcdClientId", + azureClientSecret: "abcdClientSecret" + } + } + + cluster = wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster", + answers=answers) + + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + assert cluster.answers.values[azureClientId] is not None + assert azureClientSecret not in cluster.answers.values + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +def test_member_accesstype_check(admin_mc, user_factory, remove_resource): + client = admin_mc.client + user_readonly = user_factory() + user_owner = user_factory() + members = [{"userPrincipalId": "local://" + user_readonly.user.id, + "accessType": "read-only"}, + {"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "member"}] + # creation with a member with accessType "member" shouldn't be allowed + try: + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_resource(cluster_template) + except ApiError as e: + assert e.error.status == 422 + + members = [{"userPrincipalId": "local://" + user_readonly.user.id, + "accessType": "read-only"}, + {"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "owner"}] + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_resource(cluster_template) + + updated_members = \ + [{"userPrincipalId": "local://" + user_readonly.user.id, + "accessType": "read-only"}, + {"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "member"}] + # updating a cluster template to add user with access type "member" + # shouldn't be allowed + try: + client.update(cluster_template, members=updated_members) + except ApiError as e: + assert e.error.status == 422 + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_create_cluster_with_invalid_revision(admin_mc, remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_resource(cluster_template) + tId = cluster_template.id + client = admin_mc.client + + # templaterevision with question with invalid format + cconfig = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "defaultPodSecurityPolicyTemplateId": "restricted", + } + questions = [{ + "variable": "dockerRootDir", + "required": "true", + "type": "string", + "default": "" + }, + { + "default": "map[enabled:true type:localClusterAuthEndpoint]", + "required": "false", + "type": "string", + "variable": "localClusterAuthEndpoint" + }] + + rev = client.create_cluster_template_revision(name=random_str(), + clusterConfig=cconfig, + clusterTemplateId=tId, + questions=questions, + enabled="true") + + # creating a cluster with this template + try: + wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + except ApiError as e: + assert e.error.status == 422 + + +@pytest.mark.skip +def test_disable_template_revision(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + + tId = cluster_template.id + client = admin_mc.client + rev = \ + create_cluster_template_revision(admin_mc.client, tId) + + # creating a cluster with this template + cluster = wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + # disable the revision + client.action(obj=rev, action_name="disable") + + try: + wait_for_cluster_create(client, name=random_str(), + clusterTemplateRevisionId=rev.id) + except ApiError as e: + assert e.error.status == 500 + + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +@pytest.mark.skip +def test_template_delete_by_members(admin_mc, remove_resource, + list_remove_resource, user_factory): + user_owner = user_factory() + members = [{"userPrincipalId": "local://" + user_owner.user.id, + "accessType": "owner"}] + cluster_template = create_cluster_template(admin_mc, members, admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = cluster_template.id.split(":") + name = split[1] + rb_name = name + "-ct-a" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + user_owner.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + templateId = cluster_template.id + rev = create_cluster_template_revision(user_owner.client, templateId) + + cluster = wait_for_cluster_create(admin_mc.client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + # user with accessType=owner should not be able to delete this + # template since a cluster exists + wait_for_clusterTemplate_update_failure(admin_mc.client, rev) + with pytest.raises(ApiError) as e: + user_owner.client.delete(cluster_template) + assert e.value.error.status == 422 + + admin_mc.client.delete(cluster) + wait_for_cluster_to_be_deleted(admin_mc.client, cluster.id) + + +def test_template_access(admin_mc, remove_resource, user_factory): + user = user_factory() + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_resource(cluster_template) + templateId = cluster_template.id + rev = create_cluster_template_revision(admin_mc.client, templateId) + + wait_for_clusterTemplate_list_failure(user.client, rev) + + with pytest.raises(ApiError) as e: + user.client.create_cluster(name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + assert e.value.error.status == 404 + + +@pytest.mark.skip +def test_save_as_template_action(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + + templateId = cluster_template.id + rev = create_cluster_template_revision(admin_mc.client, templateId) + + cluster = wait_for_cluster_create(admin_mc.client, name=random_str(), + clusterTemplateRevisionId=rev.id, + description="template from cluster") + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + try: + admin_mc.client.action(obj=cluster, action_name="saveAsTemplate", ) + except AttributeError as e: + assert e is not None + + +@pytest.mark.skip +def test_cluster_desc_update(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, + [], admin_mc) + remove_list = [cluster_template] + list_remove_resource(remove_list) + templateId = cluster_template.id + + rev = \ + create_cluster_template_revision(admin_mc.client, templateId) + + # create a cluster with this template + client = admin_mc.client + + cname = random_str() + cluster = wait_for_cluster_create(admin_mc.client, name=cname, + clusterTemplateRevisionId=rev.id, + description="template from cluster") + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + assert cluster.description == 'template from cluster' + + # edit cluster description + updatedC = client.update(cluster, name=cname, + clusterTemplateRevisionId=rev.id, + description="updated desc") + assert updatedC.description == 'updated desc' + + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_update_cluster_monitoring(admin_mc, list_remove_resource): + cluster_template = create_cluster_template(admin_mc, [], admin_mc) + + remove_list = [cluster_template] + list_remove_resource(remove_list) + + tId = cluster_template.id + client = admin_mc.client + cconfig = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "enableClusterMonitoring": "true", + "defaultPodSecurityPolicyTemplateId": "restricted", + } + rev1 = client.create_cluster_template_revision(clusterConfig=cconfig, + name="v1", + clusterTemplateId=tId, + enabled="true") + cconfig2 = { + "rancherKubernetesEngineConfig": { + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + } + } + }, + "enableClusterMonitoring": "false", + "defaultPodSecurityPolicyTemplateId": "restricted", + } + rev2 = client.create_cluster_template_revision(clusterConfig=cconfig2, + name="v2", + clusterTemplateId=tId, + enabled="true") + + cluster_name = random_str() + cluster = wait_for_cluster_create(client, name=cluster_name, + clusterTemplateRevisionId=rev1.id, + description="template from cluster") + remove_list.insert(0, cluster) + assert cluster.conditions[0].type == 'Pending' + assert cluster.conditions[0].status == 'True' + + # update cluster to use rev2 that turns off monitoring + # expect no change to monitoring + + client.update(cluster, + name=cluster_name, clusterTemplateRevisionId=rev2.id) + + reloaded_cluster = client.by_id_cluster(cluster.id) + assert reloaded_cluster.enableClusterMonitoring is True + + client.delete(cluster) + wait_for_cluster_to_be_deleted(client, cluster.id) + + +def rtb_cb(client, rtb): + """Wait for the prtb to have the userId populated""" + def cb(): + rt = client.reload(rtb) + return rt.userPrincipalId is not None + return cb + + +def grb_cb(client, grb): + """Wait for the grb to have the userId populated""" + def cb(): + rt = client.reload(grb) + return rt.userId is not None + return cb + + +# When calling this function you _must_ remove the cluster_template manually +# If a cluster is created also it must be removed after the template +def create_cluster_template(creator, members, admin_mc): + template_name = random_str() + + cluster_template = \ + creator.client.create_cluster_template( + name=template_name, + description="demo template", + members=members) + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + rb_name = cluster_template.id.split(":")[1] + "-ct-a" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + creator.user.id, rb_name), + timeout=60, + fail_handler=fail_handler(rb_resource)) + + return cluster_template + + +def create_cluster_template_revision(client, clusterTemplateId): + rke_config = getRKEConfig() + + cluster_config = { + "dockerRootDir": "/var/lib/docker", + "enableClusterAlerting": "false", + "enableClusterMonitoring": "false", + "enableNetworkPolicy": "false", + "type": "clusterSpecBase", + "localClusterAuthEndpoint": { + "enabled": "true", + "type": "localClusterAuthEndpoint" + }, + "rancherKubernetesEngineConfig": rke_config + } + + questions = [{ + "variable": "dockerRootDir", + "required": "false", + "type": "string", + "default": "/var/lib/docker" + }, + { + "variable": + "rancherKubernetesEngineConfig.ignoreDockerVersion", + "required": "false", + "type": "boolean", + "default": "true" + }, + { + "variable": + "rancherKubernetesEngineConfig.kubernetesVersion", + "required": "false", + "type": "string", + "default": "1.27.x" + }] + + revision_name = random_str() + + cluster_template_revision = \ + client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config, + clusterTemplateId=clusterTemplateId, + disabled="false", + questions=questions + ) + + return cluster_template_revision + + +def getRKEConfig(): + rke_config = { + "addonJobTimeout": 30, + "ignoreDockerVersion": "true", + "sshAgentAuth": "false", + "type": "rancherKubernetesEngineConfig", + "kubernetesVersion": "1.15.x", + "authentication": { + "strategy": "x509", + "type": "authnConfig" + }, + "network": { + "plugin": "canal", + "type": "networkConfig", + "options": { + "flannel_backend_type": "vxlan" + } + }, + "ingress": { + "provider": "nginx", + "type": "ingressConfig" + }, + "monitoring": { + "provider": "metrics-server", + "type": "monitoringConfig" + }, + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + }, + "etcd": { + "creation": "12h", + "extraArgs": { + "heartbeat-interval": 500, + "election-timeout": 5000 + }, + "retention": "72h", + "snapshot": "false", + "type": "etcdService", + "backupConfig": { + "enabled": "true", + "intervalHours": 12, + "retention": 6, + "type": "backupConfig" + } + } + } + } + return rke_config + + +def wait_for_cluster_to_be_deleted(client, clusterId, timeout=45): + deleted = False + start = time.time() + interval = 0.5 + while not deleted: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for clusters") + cluster = client.by_id_cluster(clusterId) + if cluster is None: + deleted = True + time.sleep(interval) + interval *= 2 + + +def wait_for_default_revision(client, templateId, revisionId, timeout=60): + updated = False + interval = 0.5 + start = time.time() + while not updated: + if time.time() - start > timeout: + raise Exception('Timeout waiting for clustertemplate to update') + template_reloaded = client.by_id_cluster_template(templateId) + if template_reloaded.defaultRevisionId is not None: + updated = True + time.sleep(interval) + interval *= 2 + + +def fail_handler(resource): + return "failed waiting for clustertemplate" + resource + " to get updated" + + +def wait_for_cluster_create(client, **kwargs): + timeout = DEFAULT_TIMEOUT + interval = 0.5 + start = time.time() + while True: + try: + return client.create_cluster(kwargs) + except ApiError as e: + if e.error.status != 404: + raise e + if time.time() - start > timeout: + exception_msg = 'Timeout waiting for condition.' + raise Exception(exception_msg) + time.sleep(interval) + interval *= 2 + + +def wait_for_clusterTemplate_update_failure(client, revision, timeout=45): + updateWorks = True + start = time.time() + interval = 0.5 + cconfig = { + "rancherKubernetesEngineConfig": { + } + } + while updateWorks: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for clustertemplate update failure") + try: + client.update(revision, name=random_str(), clusterConfig=cconfig) + except ApiError as e: + if e.error.status == 422: + updateWorks = False + + time.sleep(interval) + interval *= 2 + + +def wait_for_clusterTemplate_list_failure(client, revision, timeout=45): + listWorks = True + start = time.time() + interval = 0.5 + while listWorks: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for clustertemplate list failure") + try: + client.by_id_cluster_template_revision(revision.id) + except ApiError as e: + if e.error.status == 403: + listWorks = False + time.sleep(interval) + interval *= 2 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_default_roles.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_default_roles.py new file mode 100644 index 0000000..2a7be6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_default_roles.py @@ -0,0 +1,312 @@ +import pytest +import kubernetes +import json +from .common import random_str +from .conftest import ( + wait_for_condition, wait_until, wait_for, kubernetes_api_client) + +CREATOR_ANNOTATION = 'authz.management.cattle.io/creator-role-bindings' +systemProjectLabel = "authz.management.cattle.io/system-project" +defaultProjectLabel = "authz.management.cattle.io/default-project" + + +@pytest.fixture +def cleanup_roles(request, admin_mc): + """Resets global roles and role remplates back to the server default: + global role == 'user' + cluster create == 'cluster-owner' + project create == 'project-owner' + """ + client = admin_mc.client + + def _cleanup(): + for role in client.list_role_template(): + if role.id == 'cluster-owner': + client.update(role, clusterCreatorDefault=True, + projectCreatorDefault=False, locked=False) + elif role.id == 'project-owner': + client.update(role, clusterCreatorDefault=False, + projectCreatorDefault=True, locked=False) + elif (role.clusterCreatorDefault or role.projectCreatorDefault or + role.locked): + client.update(role, clusterCreatorDefault=False, + projectCreatorDefault=False, locked=False) + + for role in client.list_global_role(): + if role.id == 'user': + client.update(role, newUserDefault=True) + elif role.newUserDefault: + client.update(role, newUserDefault=False) + + request.addfinalizer(_cleanup) + + +@pytest.fixture(autouse=True) +def add_cluster_roles(admin_mc, remove_resource): + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + rbac_api = kubernetes.client.RbacAuthorizationV1Api(k8s_client) + + roles = rbac_api.list_cluster_role() + + cr1 = add_cr_if_not_exist(roles=roles, + name="monitoring-ui-view", + rbac_api=rbac_api) + + cr2 = add_cr_if_not_exist(roles=roles, + name="navlinks-view", + rbac_api=rbac_api) + + cr3 = add_cr_if_not_exist(roles=roles, + name="navlinks-manage", + rbac_api=rbac_api) + + yield + + # if the cluster role didn't exist before, delete it after the test + if cr1: + rbac_api.delete_cluster_role("monitoring-ui-view") + if cr2: + rbac_api.delete_cluster_role("navlinks-view") + if cr3: + rbac_api.delete_cluster_role("navlinks-manage") + + +@pytest.mark.nonparallel +def test_cluster_create_default_role(admin_mc, cleanup_roles, remove_resource): + test_roles = ['projects-create', 'storage-manage', 'nodes-view'] + client = admin_mc.client + + set_role_state(client, test_roles, 'cluster') + + cluster = client.create_cluster(name=random_str()) + remove_resource(cluster) + + wait_for_condition('InitialRolesPopulated', 'True', client, cluster) + + cluster = client.reload(cluster) + + data_dict = json.loads(cluster.annotations[CREATOR_ANNOTATION]) + + assert len(cluster.clusterRoleTemplateBindings()) == 3 + assert set(data_dict['created']) == set(data_dict['required']) + assert set(data_dict['created']) == set(test_roles) + + for binding in cluster.clusterRoleTemplateBindings(): + def binding_principal_validate(): + bind = client.by_id_cluster_role_template_binding(binding.id) + if bind.userPrincipalId is None: + return False + return bind + + binding = wait_for(binding_principal_validate) + assert binding.roleTemplateId in test_roles + assert binding.userId is not None + user = client.by_id_user(binding.userId) + assert binding.userPrincipalId in user.principalIds + + +@pytest.mark.nonparallel +def test_cluster_create_role_locked(admin_mc, cleanup_roles, remove_resource): + test_roles = ['projects-create', 'storage-manage', 'nodes-view'] + client = admin_mc.client + + set_role_state(client, test_roles, 'cluster') + + # Grab a role to lock + locked_role = test_roles.pop() + + # Lock the role + client.update(client.by_id_role_template(locked_role), locked=True) + + cluster = client.create_cluster(name=random_str()) + remove_resource(cluster) + + wait_for_condition('InitialRolesPopulated', 'True', client, cluster) + + cluster = client.reload(cluster) + + data_dict = json.loads(cluster.annotations[CREATOR_ANNOTATION]) + + assert len(cluster.clusterRoleTemplateBindings()) == 2 + assert set(data_dict['created']) == set(data_dict['required']) + assert set(data_dict['created']) == set(test_roles) + + for binding in cluster.clusterRoleTemplateBindings(): + assert binding.roleTemplateId in test_roles + + +@pytest.mark.nonparallel +def test_project_create_default_role(admin_mc, cleanup_roles, remove_resource): + test_roles = ['project-member', 'workloads-view', 'secrets-view'] + client = admin_mc.client + + set_role_state(client, test_roles, 'project') + + project = client.create_project(name=random_str(), clusterId='local') + remove_resource(project) + + wait_for_condition('InitialRolesPopulated', 'True', client, project) + + project = client.reload(project) + + data_dict = json.loads(project.annotations[ + CREATOR_ANNOTATION]) + + assert len(project.projectRoleTemplateBindings()) == 3 + assert set(data_dict['required']) == set(test_roles) + + for binding in project.projectRoleTemplateBindings(): + def binding_principal_validate(): + bind = client.by_id_project_role_template_binding(binding.id) + if bind.userPrincipalId is None: + return False + return bind + + binding = wait_for(binding_principal_validate) + + assert binding.roleTemplateId in test_roles + assert binding.userId is not None + user = client.by_id_user(binding.userId) + assert binding.userPrincipalId in user.principalIds + + +@pytest.mark.nonparallel +def test_project_create_role_locked(admin_mc, cleanup_roles, remove_resource): + """Test a locked role that is set to default is not applied + """ + test_roles = ['project-member', 'workloads-view', 'secrets-view'] + client = admin_mc.client + + set_role_state(client, test_roles, 'project') + + # Grab a role to lock + locked_role = test_roles.pop() + + # Lock the role + client.update(client.by_id_role_template(locked_role), locked=True) + # Wait for role to get updated + wait_for(lambda: client.by_id_role_template(locked_role)['locked'] is True, + fail_handler=lambda: "Failed to lock role"+locked_role) + + project = client.create_project(name=random_str(), clusterId='local') + remove_resource(project) + + wait_for_condition('InitialRolesPopulated', 'True', client, project) + + project = client.reload(project) + + data_dict = json.loads(project.annotations[ + CREATOR_ANNOTATION]) + + assert len(project.projectRoleTemplateBindings()) == 2 + assert set(data_dict['required']) == set(test_roles) + + for binding in project.projectRoleTemplateBindings(): + assert binding.roleTemplateId in test_roles + + +@pytest.mark.nonparallel +def test_user_create_default_role(admin_mc, cleanup_roles, remove_resource): + test_roles = ['user-base', 'settings-manage', 'catalogs-use'] + principal = "local://fakeuser" + client = admin_mc.client + + set_role_state(client, test_roles, 'global') + + # Creating a crtb with a fake principal causes the user to be created + # through usermanager.EnsureUser. This triggers the creation of default + # globalRoleBinding + crtb = client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId="cluster-owner", + userPrincipalId=principal) + remove_resource(crtb) + + wait_until(crtb_cb(client, crtb)) + + crtb = client.reload(crtb) + + user = client.by_id_user(crtb.userId) + remove_resource(user) + + wait_for_condition('InitialRolesPopulated', + 'True', client, user, timeout=5) + + user = client.reload(user) + assert len(user.globalRoleBindings()) == 3 + for binding in user.globalRoleBindings(): + assert binding.globalRoleId in test_roles + + +@pytest.mark.nonparallel +def test_default_system_project_role(admin_mc): + test_roles = ['project-owner'] + client = admin_mc.client + projects = client.list_project(clusterId="local") + required_projects = {} + required_projects["Default"] = defaultProjectLabel + required_projects["System"] = systemProjectLabel + created_projects = [] + + for project in projects: + name = project['name'] + if name == "Default" or name == "System": + project = client.reload(project) + + projectLabel = required_projects[name] + assert project['labels'].\ + data_dict()[projectLabel] == 'true' + created_projects.append(project) + + assert len(required_projects) == len(created_projects) + + for project in created_projects: + for binding in project.projectRoleTemplateBindings(): + assert binding.roleTemplateId in test_roles + + +def set_role_state(client, roles, context): + """Set the default templates for globalRole or roleTemplates""" + if context == 'cluster' or context == 'project': + existing_roles = client.list_role_template() + + for role in existing_roles: + client.update(role, clusterCreatorDefault=False, + projectCreatorDefault=False) + + for role in roles: + if context == 'cluster': + client.update(client.by_id_role_template( + role), clusterCreatorDefault=True) + elif context == 'project': + client.update(client.by_id_role_template( + role), projectCreatorDefault=True) + + elif context == 'global': + existing_roles = client.list_global_role() + + for role in existing_roles: + client.update(role, newUserDefault=False) + + for role in roles: + client.update(client.by_id_global_role(role), newUserDefault=True) + + +def crtb_cb(client, crtb): + """Wait for the crtb to have the userId populated""" + def cb(): + c = client.reload(crtb) + return c.userId is not None + return cb + + +def add_cr_if_not_exist(roles, name, rbac_api): + hasRole = False + for r in roles.items: + if r.metadata.name == name: + hasRole = True + + if not hasRole: + body = kubernetes.client.V1ClusterRole() + body.metadata = kubernetes.client.V1ObjectMeta(name=name) + return rbac_api.create_cluster_role(body=body) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_deployment.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_deployment.py new file mode 100644 index 0000000..892941e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_deployment.py @@ -0,0 +1,104 @@ +from .common import random_str +import kubernetes + +from .conftest import kubernetes_api_client, user_project_client + + +def test_dep_creation_kubectl(admin_mc, admin_cc, remove_resource): + name = random_str() + project = admin_mc.client.create_project(name=random_str(), + clusterId='local') + remove_resource(project) + namespace_name = random_str() + ns = admin_cc.client.create_namespace(name=namespace_name, + projectId=project.id) + remove_resource(ns) + + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + d_api = kubernetes.client.AppsV1Api(k8s_client) + + d = kubernetes.client.V1beta2Deployment() + # Metadata + d.metadata = kubernetes.client.V1ObjectMeta( + name=name, + namespace=namespace_name) + pod_meta = kubernetes.client.V1ObjectMeta( + labels={"foo": "bar"}) + port = kubernetes.client.V1ContainerPort( + container_port=80, + host_port=8099, + ) + container = {"name": "nginx", "image": "nginx:1.7.9", "ports": [port]} + spec = kubernetes.client.V1PodSpec( + containers=[container]) + template = kubernetes.client.V1PodTemplateSpec( + metadata=pod_meta, + spec=spec + ) + selector = kubernetes.client.V1LabelSelector( + match_labels={"foo": "bar"} + ) + + d.spec = kubernetes.client.V1beta2DeploymentSpec( + selector=selector, + template=template + ) + dep = d_api.create_namespaced_deployment(namespace=namespace_name, + body=d) + remove_resource(dep) + assert dep is not None + + # now get this through rancher api as namespacedCertificate + p_client = user_project_client(admin_mc, project) + d = p_client.list_workload(name=name, namespace=namespace_name).data[0] + assert d is not None + port = d['containers'][0]['ports'][0] + assert port['sourcePort'] == 8099 + assert port['kind'] == 'HostPort' + + +def test_port(admin_pc): + client = admin_pc.client + + ports = [{ + 'sourcePort': 776, + 'containerPort': 80, + 'kind': 'HostPort', + 'protocol': 'TCP', }, + { + 'sourcePort': 777, + 'containerPort': 80, + 'kind': 'NodePort', + 'protocol': 'TCP', }, + { + 'sourcePort': 778, + 'containerPort': 80, + 'kind': 'LoadBalancer', + 'protocol': 'TCP', }, + { + 'sourcePort': 779, + 'containerPort': 80, + 'kind': 'ClusterIP', + 'protocol': 'TCP', }, + ] + + for port in ports: + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + name = random_str() + + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + 'ports': [port], + }]) + workload_ports = workload['containers'][0]['ports'] + assert workload_ports is not None + assert workload_ports[0]['kind'] == port['kind'] + assert workload_ports[0]['containerPort'] == port['containerPort'] + assert workload_ports[0]['sourcePort'] == port['sourcePort'] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dns.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dns.py new file mode 100644 index 0000000..0980fe9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dns.py @@ -0,0 +1,124 @@ +from .common import random_str, auth_check +from rancher import ApiError +import pytest + + +def test_dns_fields(admin_pc_client): + auth_check(admin_pc_client.schema, 'dnsRecord', 'crud', { + 'namespaceId': 'cr', + 'projectId': 'cr', + 'hostname': 'cru', + 'allocateLoadBalancerNodePorts': 'cru', + 'ipAddresses': 'cru', + 'ipFamilies': 'cru', + 'ipFamilyPolicy': 'cru', + 'clusterIPs': 'cru', + 'clusterIp': 'r', + 'selector': 'cru', + 'targetWorkloadIds': 'cru', + 'workloadId': 'r', + 'targetDnsRecordIds': 'cru', + 'trafficDistribution': 'cru', + 'publicEndpoints': 'r', + 'ports': 'r', + }) + + +def test_dns_hostname(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + dns_record = client.create_dns_record(name=name, + hostname='target', + namespaceId=ns.id) + assert dns_record.baseType == 'dnsRecord' + assert dns_record.type == 'dnsRecord' + assert dns_record.name == name + assert dns_record.hostname == 'target' + assert "clusterIp" not in dns_record + assert dns_record.namespaceId == ns.id + assert 'namespace' not in dns_record + assert dns_record.projectId == admin_pc.project.id + + dns_record = client.update(dns_record, hostname='target2') + dns_record = client.reload(dns_record) + + assert dns_record.baseType == 'dnsRecord' + assert dns_record.type == 'dnsRecord' + assert dns_record.name == name + assert dns_record.hostname == 'target2' + assert "clusterIp" not in dns_record + assert dns_record.namespaceId == ns.id + assert 'namespace' not in dns_record + assert dns_record.projectId == admin_pc.project.id + + found = False + for i in client.list_dns_record(): + if i.id == dns_record.id: + found = True + break + + assert found + + dns_record = client.by_id_dns_record(dns_record.id) + assert dns_record is not None + + client.delete(dns_record) + + +def test_dns_ips(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + dns_record = client.create_dns_record(name=name, + ipAddresses=['1.1.1.1', + '2.2.2.2'], + namespaceId=ns.id) + assert dns_record.baseType == 'dnsRecord' + assert dns_record.type == 'dnsRecord' + assert dns_record.name == name + assert 'hostname' not in dns_record + assert dns_record.ipAddresses == ['1.1.1.1', '2.2.2.2'] + assert dns_record.clusterIp is None + assert dns_record.namespaceId == ns.id + assert 'namespace' not in dns_record + assert dns_record.projectId == admin_pc.project.id + + dns_record = client.update(dns_record, ipAddresses=['1.1.1.2', '2.2.2.1']) + dns_record = client.reload(dns_record) + + assert dns_record.baseType == 'dnsRecord' + assert dns_record.type == 'dnsRecord' + assert dns_record.name == name + assert 'hostname' not in dns_record + assert dns_record.ipAddresses == ['1.1.1.2', '2.2.2.1'] + assert dns_record.clusterIp is None + assert dns_record.namespaceId == ns.id + assert 'namespace' not in dns_record + assert dns_record.projectId == admin_pc.project.id + + dnsname = random_str() + with pytest.raises(ApiError) as e: + client.create_dns_record(name=dnsname, + ipAddresses=['127.0.0.2'], + namespaceId='default') + assert e.value.error.status == 422 + + found = False + for i in client.list_dns_record(): + if i.id == dns_record.id: + found = True + break + + assert found + + dns_record = client.by_id_dns_record(dns_record.id) + assert dns_record is not None + + client.delete(dns_record) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dynamic_schemas.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dynamic_schemas.py new file mode 100644 index 0000000..b6eccd1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_dynamic_schemas.py @@ -0,0 +1,49 @@ +import copy +import pytest + +from .conftest import wait_for + + +@pytest.mark.nonparallel +def test_dynamic_schemas_update(request, admin_mc): + assert not schema_has_field(admin_mc) + + eks_schema = admin_mc.client.by_id_dynamicSchema( + 'amazonelasticcontainerserviceconfig') + + new_field = copy.deepcopy(eks_schema.resourceFields['displayName']) + new_field.description = 'My special field.' + setattr(eks_schema.resourceFields, 'mySpecialField', new_field) + + admin_mc.client.update_by_id_dynamicSchema(eks_schema.id, eks_schema) + request.addfinalizer(lambda: cleanup_extra_field(admin_mc)) + + wait_for(lambda: schema_has_field(admin_mc), + fail_handler=lambda: "could not add extra field", + timeout=120) + + +def cleanup_extra_field(admin_mc): + eks_schema = admin_mc.client.by_id_dynamicSchema( + 'amazonelasticcontainerserviceconfig') + delattr(eks_schema.resourceFields, 'mySpecialField') + admin_mc.client.delete(eks_schema) + admin_mc.client.create_dynamicSchema(eks_schema) + + wait_for(lambda: not schema_has_field(admin_mc), + fail_handler=lambda: "could not clean up extra field", + timeout=120) + + +def schema_has_field(admin_mc): + admin_mc.client.reload_schema() + schemas = admin_mc.client.schema.types + + eks_schema = None + for name, schema in schemas.items(): + if name == "amazonElasticContainerServiceConfig": + eks_schema = schema + + return hasattr(eks_schema.resourceFields, + 'mySpecialField') and eks_schema.resourceFields[ + 'mySpecialField'] is not None diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_etcdbackups.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_etcdbackups.py new file mode 100644 index 0000000..20e44be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_etcdbackups.py @@ -0,0 +1,39 @@ +from .conftest import wait_until +import kubernetes + + +role_template = "backups-manage" + + +def test_backups_manage_role(admin_mc, user_factory, remove_resource): + client = admin_mc.client + restricted_user = user_factory(globalRoleId='user-base') + + # add user to local cluster with "Manage cluster backups" role + crtb_rstrd = client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId=role_template, + userId=restricted_user.user.id, ) + remove_resource(crtb_rstrd) + wait_until(crtb_cb(client, crtb_rstrd)) + + # check that role "backups-manage" was created in the cluster + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + role = rbac.read_namespaced_role(role_template, "local") + assert role is not None + assert "etcdbackups" in role.rules[0].resources + + +def test_standard_users_cannot_access_backups(admin_mc, user_factory): + client = admin_mc.client + user_role = client.by_id_global_role("user") + for r in user_role['rules']: + assert "etcdbackups" not in r['resources'] + + +def crtb_cb(client, crtb): + """Wait for the crtb to have the userId populated""" + def cb(): + c = client.reload(crtb) + return c.userPrincipalId is not None + return cb diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_features.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_features.py new file mode 100644 index 0000000..920541f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_features.py @@ -0,0 +1,29 @@ +import pytest +from rancher import ApiError + + +# no one should be able to create features via the api +def test_cannot_create(admin_mc, user_mc, remove_resource): + admin_client = admin_mc.client + user_client = user_mc.client + + with pytest.raises(ApiError) as e: + admin_client.create_feature(name="testfeature", value=True) + + assert e.value.error.status == 405 + + with pytest.raises(ApiError) as e: + user_client.create_feature(name="testfeature", value=True) + + assert e.value.error.status == 405 + + +# users and admins should be able to list features +def test_can_list(admin_mc, user_mc, remove_resource): + user_client = user_mc.client + user_client.list_feature() + assert True + + admin_client = admin_mc.client + admin_client.list_feature() + assert True diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_role_bindings.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_role_bindings.py new file mode 100644 index 0000000..541cb86 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_role_bindings.py @@ -0,0 +1,141 @@ +import pytest + +from rancher import ApiError + +from kubernetes.client.rest import ApiException +from kubernetes.client import RbacAuthorizationV1Api +from .conftest import wait_for +from .common import random_str, string_to_encoding + + +def test_cannot_update_global_role(admin_mc, remove_resource): + """Asserts that globalRoleId field cannot be changed""" + admin_client = admin_mc.client + + grb = admin_client.create_global_role_binding( + name="gr-" + random_str(), + userId=admin_mc.user.id, + globalRoleId="nodedrivers-manage") + remove_resource(grb) + + grb = admin_client.update_by_id_global_role_binding( + id=grb.id, + globalRoleId="settings-manage") + assert grb.globalRoleId == "nodedrivers-manage" + + +def test_globalrole_must_exist(admin_mc, remove_resource): + """Asserts that globalRoleId must reference an existing role""" + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + grb = admin_client.create_global_role_binding( + name="gr-" + random_str(), + globalRoleId="somefakerole", + userId=admin_mc.user.id + ) + remove_resource(grb) + assert e.value.error.status == 404 + assert "globalroles.management.cattle.io \"somefakerole\" not found" in \ + e.value.error.message + + +def test_cannot_update_subject(admin_mc, user_mc, remove_resource): + """Asserts that userId and groupPrincipalId fields cannot be + changed""" + admin_client = admin_mc.client + + grb = admin_client.create_global_role_binding( + name="gr-" + random_str(), + userId=admin_mc.user.id, + globalRoleId="nodedrivers-manage") + remove_resource(grb) + + grb = admin_client.update_by_id_global_role_binding( + id=grb.id, + userId=user_mc.user.id) + assert grb.userId == admin_mc.user.id + + grb = admin_client.update_by_id_global_role_binding( + id=grb.id, + groupPrincipalId="groupa") + assert grb.userId == admin_mc.user.id + assert grb.groupPrincipalId is None + + +def test_grb_crb_lifecycle(admin_mc, remove_resource): + """Asserts that global role binding creation and deletion + properly creates and deletes underlying cluster role binding""" + admin_client = admin_mc.client + + # admin role is used because it requires an + # additional cluster role bindig to be managed + grb = admin_client.create_global_role_binding( + groupPrincipalId="asd", globalRoleId="admin" + ) + remove_resource + + cattle_grb = "cattle-globalrolebinding-" + grb.id + admin_grb = "globaladmin-u-" + string_to_encoding("asd").lower() + + api_instance = RbacAuthorizationV1Api( + admin_mc.k8s_client) + + def get_crb_by_id(id): + def get_crb_from_k8s(): + try: + return api_instance.read_cluster_role_binding(id) + except ApiException as e: + assert e.status == 404 + return get_crb_from_k8s + + k8s_grb = wait_for(get_crb_by_id(cattle_grb)) + assert k8s_grb.subjects[0].kind == "Group" + assert k8s_grb.subjects[0].name == "asd" + + k8s_grb = wait_for(get_crb_by_id(admin_grb)) + assert k8s_grb.subjects[0].kind == "Group" + assert k8s_grb.subjects[0].name == "asd" + + grb = admin_client.reload(grb) + admin_client.delete(grb) + + def crb_deleted_by_id(id): + def is_crb_deleted(): + try: + api_instance.read_cluster_role_binding(id) + except ApiException as e: + return e.status == 404 + return False + return is_crb_deleted + + wait_for(crb_deleted_by_id(cattle_grb)) + wait_for(crb_deleted_by_id(admin_grb)) + + +def test_grb_targets_user_or_group(admin_mc, remove_resource): + """Asserts that a globalrolebinding must exclusively target + a userId or groupPrincipalId""" + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + grb = admin_client.create_global_role_binding( + userId="asd", + groupPrincipalId="asd", + globalRoleId="admin" + ) + remove_resource(grb) + + assert e.value.error.status == 422 + assert "must contain field [groupPrincipalId] OR field [userId]" in\ + e.value.error.message + + with pytest.raises(ApiError) as e: + grb = admin_client.create_global_role_binding( + globalRoleId="admin" + ) + remove_resource(grb) + + assert e.value.error.status == 422 + assert "must contain field [groupPrincipalId] OR field [userId]" in \ + e.value.error.message diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_roles.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_roles.py new file mode 100644 index 0000000..0109777 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_global_roles.py @@ -0,0 +1,140 @@ +import pytest +from rancher import ApiError + +from .common import random_str +from .conftest import wait_for + + +@pytest.mark.nonparallel +def test_builtin_default_can_be_edited(admin_mc, revert_gr): + """Asserts admins can only edit a builtin global role's newUserDefault + field""" + admin_client = admin_mc.client + + gr = admin_client.by_id_global_role(id="admin") + revert_gr(gr) + assert gr.builtin is True + assert "remove" not in gr.links.keys() + assert gr.newUserDefault is False + + new_gr = admin_client.update_by_id_global_role(id=gr.id, + displayName="gr-test", + description="asdf", + rules=None, + newUserDefault=True, + builtin=True) + assert new_gr.name == gr.name + assert not hasattr(new_gr, "description") + assert new_gr.rules is not None + assert new_gr.get("builtin") is True + + # newUserDefault is the only field that should editable + # for a builtin role + assert new_gr.newUserDefault is True + + +def test_only_admin_can_crud_global_roles(admin_mc, user_mc, remove_resource): + """Asserts that only admins can create, get, update, and delete + non-builtin global roles""" + admin_client = admin_mc.client + user_client = user_mc.client + + gr = admin_client.create_global_role(name="gr-" + random_str()) + remove_resource(gr) + + gr.annotations = {"test": "asdf"} + + def try_gr_update(): + try: + return admin_client.update_by_id_global_role( + id=gr.id, + value=gr) + except ApiError as e: + assert e.error.status == 404 + return False + + wait_for(try_gr_update) + + gr_list = admin_client.list_global_role() + assert len(gr_list.data) > 0 + + admin_client.delete(gr) + + with pytest.raises(ApiError) as e: + gr2 = user_client.create_global_role(name="gr2-" + random_str()) + remove_resource(gr2) + assert e.value.error.status == 403 + + gr3 = admin_client.create_global_role(name="gr3-" + random_str()) + remove_resource(gr3) + + with pytest.raises(ApiError) as e: + user_client.by_id_global_role(id=gr3.id) + gr3.annotations = {"test2": "jkl"} + + def try_gr_unauth(): + with pytest.raises(ApiError) as e: + user_client.update_by_id_global_role(id=gr3.id, value=gr3) + if e.value.error.status == 404: + return False + assert e.value.error.status == 403 + return True + + wait_for(try_gr_unauth) + + gr_list = user_client.list_global_role() + assert len(gr_list.data) == 0 + + with pytest.raises(ApiError) as e: + user_client.delete(gr3) + assert e.value.error.status == 403 + + +def test_admin_can_only_edit_builtin_global_roles(admin_mc, remove_resource): + """Asserts admins can edit builtin global roles created by rancher but + cannot delete them""" + admin_client = admin_mc.client + + gr = admin_client.by_id_global_role(id="admin") + assert gr.builtin is True + assert "remove" not in gr.links.keys() + + gr2 = admin_client.create_global_role(name="gr2-" + random_str(), + builtin=True) + remove_resource(gr2) + + # assert that builtin cannot be set by admin and is false + assert gr2.builtin is False + + admin_client.update_by_id_global_role(id=gr.id) + + with pytest.raises(ApiError) as e: + admin_client.delete(gr) + assert e.value.error.status == 403 + assert "cannot delete builtin global roles" in e.value.error.message + + +@pytest.fixture +def revert_gr(admin_mc, request): + """Ensures gr was reverted to previous state, regardless of test results + """ + def _cleanup(old_gr): + def revert(): + reverted_gr = admin_mc.client.update_by_id_global_role( + id=old_gr.id, + displayName=old_gr.name, + description=getattr(old_gr, "description", None), + rules=old_gr.rules, + newUserDefault=old_gr.newUserDefault, + builtin=old_gr.builtin) + + assert reverted_gr.name == old_gr.name + assert reverted_gr.get("description", None) == \ + old_gr.get("description", None) + assert reverted_gr.rules[0].data_dict() == old_gr.rules[0].\ + data_dict() + assert reverted_gr.get("builtin") is old_gr.builtin + assert reverted_gr.newUserDefault is old_gr.newUserDefault + + request.addfinalizer(revert) + return _cleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_globaldns.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_globaldns.py new file mode 100644 index 0000000..e9260f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_globaldns.py @@ -0,0 +1,336 @@ +from .common import random_str +from rancher import ApiError +from kubernetes.client import CustomObjectsApi +from kubernetes.client import CoreV1Api +import pytest +import time +import kubernetes +import base64 + + +def test_dns_fqdn_unique(admin_mc): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + + fqdn = random_str() + ".example.com" + globaldns_entry = \ + client.create_global_dns(fqdn=fqdn, providerId=provider_name) + + with pytest.raises(ApiError) as e: + client.create_global_dns(fqdn=fqdn, providerId=provider_name) + assert e.value.error.status == 422 + + client.delete(globaldns_entry) + client.delete(globaldns_provider) + + +def test_dns_provider_deletion(admin_mc): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + + fqdn = random_str() + ".example.com" + provider_id = "cattle-global-data:"+provider_name + globaldns_entry = \ + client.create_global_dns(fqdn=fqdn, providerId=provider_id) + + with pytest.raises(ApiError) as e: + client.delete(globaldns_provider) + assert e.value.error.status == 403 + + client.delete(globaldns_entry) + client.delete(globaldns_provider) + + +def test_share_globaldns_provider_entry(admin_mc, user_factory, + remove_resource): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + # Add regular user as member to gdns provider + user_member = user_factory() + remove_resource(user_member) + user_client = user_member.client + members = [{"userPrincipalId": "local://" + user_member.user.id, + "accessType": "owner"}] + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}, + members=members) + + remove_resource(globaldns_provider) + fqdn = random_str() + ".example.com" + globaldns_entry = \ + client.create_global_dns(fqdn=fqdn, providerId=provider_name, + members=members) + remove_resource(globaldns_entry) + # Make sure creator can access both, provider and entry + gdns_provider_id = "cattle-global-data:" + provider_name + gdns_provider = client.by_id_global_dns_provider(gdns_provider_id) + assert gdns_provider is not None + + gdns_entry_id = "cattle-global-data:" + globaldns_entry.name + gdns = client.by_id_global_dns(gdns_entry_id) + assert gdns is not None + # user should be able to list this gdns provider + api_instance = kubernetes.client.RbacAuthorizationV1Api( + admin_mc.k8s_client) + provider_rb_name = provider_name + "-gp-a" + wait_to_ensure_user_in_rb_subject(api_instance, provider_rb_name, + user_member.user.id) + gdns_provider = user_client.by_id_global_dns_provider(gdns_provider_id) + assert gdns_provider is not None + + # user should be able to list this gdns entry + entry_rb_name = globaldns_entry.name + "-g-a" + wait_to_ensure_user_in_rb_subject(api_instance, entry_rb_name, + user_member.user.id) + gdns = user_client.by_id_global_dns(gdns_entry_id) + assert gdns is not None + + +def test_user_access_global_dns(admin_mc, user_factory, remove_resource): + user1 = user_factory() + remove_resource(user1) + user_client = user1.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + user_client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + + remove_resource(globaldns_provider) + fqdn = random_str() + ".example.com" + globaldns_entry = \ + user_client.create_global_dns(fqdn=fqdn, providerId=provider_name) + + remove_resource(globaldns_entry) + # Make sure creator can access both, provider and entry + api_instance = kubernetes.client.RbacAuthorizationV1Api( + admin_mc.k8s_client) + provider_rb_name = provider_name + "-gp-a" + wait_to_ensure_user_in_rb_subject(api_instance, provider_rb_name, + user1.user.id) + + gdns_provider_id = "cattle-global-data:" + provider_name + gdns_provider = user_client.by_id_global_dns_provider(gdns_provider_id) + assert gdns_provider is not None + + entry_rb_name = globaldns_entry.name + "-g-a" + wait_to_ensure_user_in_rb_subject(api_instance, entry_rb_name, + user1.user.id) + gdns_entry_id = "cattle-global-data:" + globaldns_entry.name + gdns = user_client.by_id_global_dns(gdns_entry_id) + assert gdns is not None + + +def test_update_gdns_entry(admin_mc, remove_resource): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + + remove_resource(globaldns_provider) + fqdn = random_str() + ".example.com" + gdns_entry_name = random_str() + globaldns_entry = \ + client.create_global_dns(name=gdns_entry_name, + fqdn=fqdn, providerId=provider_name) + remove_resource(globaldns_entry) + new_fqdn = random_str() + wait_for_gdns_entry_creation(admin_mc, gdns_entry_name) + client.update(globaldns_entry, fqdn=new_fqdn) + wait_for_gdns_update(admin_mc, gdns_entry_name, new_fqdn) + + +def test_create_globaldns_provider_regular_user(remove_resource, + user_factory): + provider_name = random_str() + access = random_str() + secret = random_str() + user = user_factory() + globaldns_provider = \ + user.client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + remove_resource(globaldns_provider) + + +def wait_to_ensure_user_in_rb_subject(api, name, + userId, timeout=60): + found = False + interval = 0.5 + start = time.time() + while not found: + time.sleep(interval) + interval *= 2 + try: + rb = api.read_namespaced_role_binding(name, "cattle-global-data") + for i in range(0, len(rb.subjects)): + if rb.subjects[i].name == userId: + found = True + except kubernetes.client.rest.ApiException: + found = False + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for user to get added to rb") + + +def wait_for_gdns_update(admin_mc, gdns_entry_name, new_fqdn, timeout=60): + client = admin_mc.client + updated = False + interval = 0.5 + start = time.time() + id = "cattle-global-data:" + gdns_entry_name + while not updated: + if time.time() - start > timeout: + raise Exception('Timeout waiting for gdns entry to update') + gdns = client.by_id_global_dns(id) + if gdns is not None and gdns.fqdn == new_fqdn: + updated = True + time.sleep(interval) + interval *= 2 + + +def wait_for_gdns_entry_creation(admin_mc, gdns_name, timeout=60): + start = time.time() + interval = 0.5 + client = admin_mc.client + found = False + while not found: + if time.time() - start > timeout: + raise Exception('Timeout waiting for globalDNS entry creation') + gdns = client.list_global_dns(name=gdns_name) + if len(gdns) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def test_cloudflare_provider_proxy_setting(admin_mc, remove_resource): + client = admin_mc.client + provider_name = random_str() + apiEmail = random_str() + apiKey = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + cloudflareProviderConfig={ + 'proxySetting': True, + 'apiEmail': apiEmail, + 'apiKey': apiKey}) + + gdns_provider_id = "cattle-global-data:" + provider_name + gdns_provider = client.by_id_global_dns_provider(gdns_provider_id) + assert gdns_provider is not None + assert gdns_provider.cloudflareProviderConfig.proxySetting is True + + remove_resource(globaldns_provider) + + +def test_dns_fqdn_hostname(admin_mc, remove_resource): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + remove_resource(globaldns_provider) + + fqdn = random_str() + ".example!!!*.com" + with pytest.raises(ApiError) as e: + client.create_global_dns(fqdn=fqdn, providerId=provider_name) + assert e.value.error.status == 422 + + +def test_globaldnsprovider_secret(admin_mc, remove_resource): + client = admin_mc.client + provider_name = random_str() + access_key = random_str() + secret_key = random_str() + + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access_key, + 'secretKey': secret_key}) + + # Test password not present in api + assert globaldns_provider is not None + assert globaldns_provider.route53ProviderConfig.get('secretKey') is None + + crdClient, k8sclient = getClients(admin_mc) + ns, name = globaldns_provider["id"].split(":") + # Test password is in k8s secret after creation + verifyGDNSPassword(crdClient, k8sclient, ns, name, secret_key) + + # Test updating password + newSecretPassword = random_str() + _ = client.update(globaldns_provider, route53ProviderConfig={ + 'accessKey': access_key, + 'secretKey': newSecretPassword}) + verifyGDNSPassword(crdClient, k8sclient, ns, name, newSecretPassword) + + +def getClients(admin_mc): + return CustomObjectsApi(admin_mc.k8s_client), \ + CoreV1Api(admin_mc.k8s_client) + + +def verifyGDNSPassword(crdClient, k8sclient, ns, name, secretPassword): + k8es = crdClient.get_namespaced_custom_object( + "management.cattle.io", "v3", ns, 'globaldnsproviders', name) + + secretName = k8es['spec']['route53ProviderConfig']['secretKey'] + ns, name = secretName.split(":") + assert ns is not None + assert name is not None + + secret = k8sclient.read_namespaced_secret(name, ns) + assert base64.b64decode(secret.data[name]).\ + decode("utf-8") == secretPassword diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_hpa.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_hpa.py new file mode 100644 index 0000000..28d6960 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_hpa.py @@ -0,0 +1,71 @@ +from .common import random_str + + +def test_hpa(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + 'resources': { + 'requests': '100m', + }, + }]) + assert workload.id != '' + name = random_str() + client.create_horizontalPodAutoscaler( + name=name, + namespaceId=ns.id, + maxReplicas=10, + workloadId=workload.id, + metrics=[{ + 'name': 'cpu', + 'type': 'Resource', + 'target': { + 'type': 'Utilization', + 'utilization': '50', + }, + }, { + 'name': 'pods-test', + 'type': 'Pods', + 'target': { + 'type': 'AverageValue', + 'averageValue': '50', + }, + }, { + 'name': 'pods-external', + 'type': 'External', + 'target': { + 'type': 'Value', + 'value': '50', + }, + }, { + "describedObject": { + "apiVersion": "extensions/v1beta1", + "kind": "Ingress", + "name": "test", + }, + 'name': 'object-test', + 'type': 'Object', + 'target': { + 'type': 'Value', + 'value': '50', + }, + }], + ) + hpas = client.list_horizontalPodAutoscaler( + namespaceId=ns.id + ) + assert len(hpas) == 1 + hpa = hpas.data[0] + assert hpa.state == "initializing" + client.delete(hpa) + client.delete(workload) + client.delete(ns) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_ingress.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_ingress.py new file mode 100644 index 0000000..2568ee5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_ingress.py @@ -0,0 +1,143 @@ +from .common import random_str, auth_check + + +def test_ingress_fields(admin_pc_client): + auth_check(admin_pc_client.schema, 'ingress', 'crud', { + 'namespaceId': 'cr', + 'projectId': 'cr', + 'rules': 'cru', + 'tls': 'cru', + 'ingressClassName': 'cru', + 'backend': 'cru', + 'defaultBackend': 'cru', + 'publicEndpoints': 'r', + 'status': 'r', + }) + + auth_check(admin_pc_client.schema, 'ingressBackend', '', { + 'serviceId': 'cru', + 'service': 'cru', + 'targetPort': 'cru', + 'resource': 'cru', + 'workloadIds': 'cru', + }) + + auth_check(admin_pc_client.schema, 'ingressRule', '', { + 'host': 'cru', + 'paths': 'cru', + }) + + auth_check(admin_pc_client.schema, 'httpIngressPath', '', { + 'resource': 'cru', + 'pathType': 'cru', + 'path': 'cru', + 'serviceId': 'cru', + 'service': 'cru', + 'targetPort': 'cru', + 'workloadIds': 'cru', + }) + + +def test_ingress(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + + name = random_str() + "." + random_str() + ingress = client.create_ingress(name=name, + namespaceId=ns.id, + rules=[{ + 'host': "foo.com", + 'paths': [ + { + 'path': '/', + 'targetPort': 80, + 'workloadIds': + [workload.id], + }, + ]}, + ]) + + assert len(ingress.rules) == 1 + assert ingress.rules[0].host == "foo.com" + path = ingress.rules[0].paths[0] + assert path.path == '/' + assert path.targetPort == 80 + assert path.workloadIds == [workload.id] + assert path.serviceId is None + + client.delete(ns) + + +def test_ingress_rules_same_hostPortPath(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + workload1 = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + + name = random_str() + workload2 = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + + name = random_str() + ingress = client.create_ingress(name=name, + namespaceId=ns.id, + rules=[{ + 'host': "foo.com", + 'paths': [ + { + 'path': '/', + 'targetPort': 80, + 'workloadIds': + [workload1.id], + }, + ]}, + { + 'host': "foo.com", + 'paths': [ + { + 'path': '/', + 'targetPort': 80, + 'workloadIds': + [workload2.id], + } + ]}, + ]) + + assert len(ingress.rules) == 1 + assert ingress.rules[0].host == "foo.com" + path = ingress.rules[0].paths[0] + assert path.path == '/' + assert path.targetPort == 80 + assert len(path.workloadIds) == 2 + assert set(path.workloadIds) == set([workload1.id, workload2.id]) + assert path.serviceId is None + + client.delete(ns) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_istio.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_istio.py new file mode 100644 index 0000000..0494281 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_istio.py @@ -0,0 +1,185 @@ +import os +import pytest +import subprocess +from .common import random_str +from .conftest import cluster_and_client, ClusterContext + +kube_fname = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "k8s_kube_config") +istio_crd_url = "https://raw.githubusercontent.com/istio/istio/1.1.5" \ + "/install/kubernetes/helm/istio-init/files/crd-10.yaml" + + +@pytest.mark.skip(reason='skipping for now, enable with istio 1.22 fix') +@pytest.mark.nonparallel +def test_virtual_service(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + name = random_str() + client.create_virtualService( + name=name, + namespaceId=ns.id, + hosts=["test"], + http=[{ + "route": [ + { + "destination": { + "host": "test", + "subset": "v1" + } + } + ] + }], + ) + virtualServices = client.list_virtualService( + namespaceId=ns.id + ) + assert len(virtualServices) == 1 + client.delete(virtualServices.data[0]) + client.delete(ns) + + +@pytest.mark.skip(reason='skipping for now, enable with istio 1.22 fix') +@pytest.mark.nonparallel +def test_destination_rule(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + name = random_str() + client.create_destinationRule( + name=name, + namespaceId=ns.id, + host="test", + subsets=[{ + "name": "v1", + "labels": { + "version": "v1", + } + }], + ) + destinationRules = client.list_destinationRule( + namespaceId=ns.id + ) + assert len(destinationRules) == 1 + client.delete(destinationRules.data[0]) + client.delete(ns) + + +# consistentHash has a "oneOf" only openAPI validation on it, +# and our types were passing multiple options which failed. +# This test ensures you can pass a single option. +# See: https://github.com/rancher/rancher/issues/25515 +@pytest.mark.skip(reason='skipping for now, enable with istio 1.22 fix') +@pytest.mark.nonparallel +def test_destination_rule_on_cookie(admin_pc, remove_resource): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + name = random_str() + cookie_name = name + "_cookie" + dr = client.create_destinationRule( + name=name, + namespaceId=ns.id, + host="test", + subsets=[{ + "name": "v1", + "labels": { + "version": "v1", + } + }], + trafficPolicy={ + "loadBalancer": { + "consistentHash": { + "httpCookie": { + "ttl": "0s", + "name": cookie_name, + } + } + } + } + ) + remove_resource(dr) + destinationRules = client.list_destinationRule( + namespaceId=ns.id + ) + assert len(destinationRules) == 1 + assert destinationRules.data[0].trafficPolicy.loadBalancer\ + .consistentHash.httpCookie.name == cookie_name + + +@pytest.mark.skip(reason='skipping for now, enable with istio 1.22 fix') +@pytest.mark.nonparallel +def test_gateway(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + name = random_str() + client.create_gateway( + name=name, + namespaceId=ns.id, + servers=[{ + "hosts": [ + "*", + ], + "port": { + "number": 443, + "name": "https", + "protocol": "HTTPS", + }, + "tls": { + "mode": "SIMPLE", + "serverCertificate": "/etc/certs/server.pem", + "privateKey": "/etc/certs/privatekey.pem", + } + }], + ) + gateways = client.list_gateway( + namespaceId=ns.id + ) + assert len(gateways) == 1 + client.delete(gateways.data[0]) + client.delete(ns) + + +@pytest.fixture(scope='module', autouse="True") +def install_crd(admin_mc): + cluster, client = cluster_and_client('local', admin_mc.client) + cc = ClusterContext(admin_mc, cluster, client) + create_kubeconfig(cc.cluster) + try: + return subprocess.check_output( + 'kubectl apply ' + + ' --kubeconfig ' + kube_fname + + ' -f ' + istio_crd_url, + stderr=subprocess.STDOUT, shell=True, + ) + except subprocess.CalledProcessError as err: + print('kubectl error: ' + str(err.output)) + raise err + + +def teardown_module(module): + try: + return subprocess.check_output( + 'kubectl delete ' + + ' --kubeconfig ' + kube_fname + + ' -f ' + istio_crd_url, + stderr=subprocess.STDOUT, shell=True, + ) + except subprocess.CalledProcessError as err: + print('kubectl error: ' + str(err.output)) + raise err + + +def create_kubeconfig(cluster): + generateKubeConfigOutput = cluster.generateKubeconfig() + print(generateKubeConfigOutput.config) + file = open(kube_fname, "w") + file.write(generateKubeConfigOutput.config) + file.close() diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_drivers.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_drivers.py new file mode 100644 index 0000000..1860f11 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_drivers.py @@ -0,0 +1,383 @@ +import platform +import pytest +import sys +import requests +from rancher import ApiError + +from .conftest import wait_for_condition, wait_until, random_str, \ + wait_for, BASE_URL + +NEW_DRIVER_URL = "https://github.com/rancher/kontainer-engine-driver-" \ + "example/releases/download/v0.2.2/kontainer-engine-" \ + "driver-example-" + sys.platform + "-amd64" +NEW_DRIVER_ARM64_URL = "https://github.com/rancher/kontainer-engine-driver-" \ + "example/releases/download/v0.2.2/kontainer-engine-" \ + "driver-example-" + sys.platform + "-arm64" +DRIVER_AMD64_URL = "https://github.com/rancher/" \ + "kontainer-engine-driver-example/" \ + "releases/download/v0.2.1/kontainer-engine-driver-example-"\ + + sys.platform +DRIVER_ARM64_URL = "https://github.com/jianghang8421/" \ + "kontainer-engine-driver-example/" \ + "releases/download/v0.2.1-multiarch/" \ + "kontainer-engine-driver-example-" \ + + sys.platform + "-arm64" + + +def test_builtin_drivers_are_present(admin_mc): + """Test if builtin kd are present and cannot be deleted via API or UI""" + admin_mc.client.reload_schema() + types = admin_mc.client.schema.types + + for name in ['azureKubernetesService', + 'googleKubernetesEngine', + 'amazonElasticContainerService']: + kd = admin_mc.client.list_kontainerDriver( + name=name, + ).data[0] + wait_for_condition('Active', "True", admin_mc.client, kd, timeout=90) + # check in schema + assert name + "Config" in types + + # verify has no delete link because its built in + kd = admin_mc.client.by_id_kontainer_driver(name.lower()) + assert not hasattr(kd.links, 'remove') + # assert cannot delete it via API + with pytest.raises(ApiError) as e: + admin_mc.client.delete(kd) + + assert e.value.error.status == 405 + + +@pytest.mark.skip +@pytest.mark.nonparallel +def test_kontainer_driver_lifecycle(admin_mc, list_remove_resource): + URL = DRIVER_AMD64_URL + if platform.machine() == "aarch64": + URL = DRIVER_ARM64_URL + kd = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + ) + remove_list = [kd] + list_remove_resource(remove_list) + + # Test that it is in downloading state while downloading + kd = wait_for_condition('Downloaded', 'Unknown', admin_mc.client, kd) + assert "downloading" == kd.state + + # no actions should be present while downloading/installing + assert not hasattr(kd, 'actions') + + # test driver goes active and appears in schema + kd = wait_for_condition('Active', 'True', admin_mc.client, kd, + timeout=90) + verify_driver_in_types(admin_mc.client, kd) + # verify the leading kontainer driver identifier and trailing system + # type are removed from the name + assert kd.name == "example" + + # verify the kontainer driver has activate and no deactivate links + assert not hasattr(kd.actions, "activate") + assert hasattr(kd.actions, "deactivate") + assert kd.actions.deactivate != "" + + # verify driver has delete link + assert kd.links.remove != "" + + # associate driver with a cluster + cluster = admin_mc.client.create_cluster( + name=random_str(), + exampleEngineConfig={ + "credentials": "bad credentials", + "nodeCount": 3 + }) + # order matters here, need to remove cluster before kontainer driver + remove_list.insert(0, cluster) + + def check_remove_link(kod): + kod = admin_mc.client.reload(kod) + if hasattr(kod.links, "remove"): + return False + return True + + wait_for(lambda: check_remove_link(kd)) + with pytest.raises(ApiError) as e: + admin_mc.client.delete(kd) + + assert e.value.error.status == 405 + + # cleanup local cluster, note this depends on a force delete of the cluster + # within rancher since this cluster is not a "true" cluster + + def cluster_steady_state(clus): + clus = admin_mc.client.reload(clus) + if "lifecycle.cattle.io/" \ + "create.mgmt-cluster-rbac-remove" in clus.annotations: + return True + return False + + # this typically takes at least 45 seconds + wait_for(lambda: cluster_steady_state(cluster), timeout=90) + admin_mc.client.delete(cluster) + # wait for removal link to return + wait_for(lambda: not (check_remove_link(kd)), timeout=90) + admin_mc.client.delete(kd) + # test driver is removed from schema after deletion + verify_driver_not_in_types(admin_mc.client, kd) + + +@pytest.mark.skip +@pytest.mark.nonparallel +def test_enabling_driver_exposes_schema(admin_mc, wait_remove_resource): + """ Test if enabling driver exposes its dynamic schema, drivers are + downloaded / installed once they are active, and if re-activating a + driver exposes its schema again""" + URL = DRIVER_AMD64_URL + if platform.machine() == "aarch64": + URL = DRIVER_ARM64_URL + kd = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=False, + url=URL + ) + wait_remove_resource(kd) + + kd = wait_for_condition('Inactive', 'True', admin_mc.client, kd, + timeout=90) + + # verify the kontainer driver has no activate and a deactivate link + assert hasattr(kd.actions, "activate") + assert kd.actions.activate != "" + assert not hasattr(kd.actions, "deactivate") + + verify_driver_not_in_types(admin_mc.client, kd) + + kd.active = True # driver should begin downloading / installing + admin_mc.client.update_by_id_kontainerDriver(kd.id, kd) + + kd = wait_for_condition('Active', 'True', admin_mc.client, kd, + timeout=90) + + verify_driver_in_types(admin_mc.client, kd) + + kd.active = False + admin_mc.client.update_by_id_kontainerDriver(kd.id, kd) + + verify_driver_not_in_types(admin_mc.client, kd) + + # test re-activation flow + kd.active = True + admin_mc.client.update_by_id_kontainerDriver(kd.id, kd) + verify_driver_in_types(admin_mc.client, kd) + + +@pytest.mark.skip +@pytest.mark.nonparallel +def test_upgrade_changes_schema(admin_mc, wait_remove_resource): + client = admin_mc.client + URL = DRIVER_AMD64_URL + if platform.machine() == "aarch64": + URL = DRIVER_ARM64_URL + kd = client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + ) + wait_remove_resource(kd) + + kd = wait_for_condition('Active', 'True', admin_mc.client, kd, + timeout=90) + + verify_driver_in_types(client, kd) + kdSchema = client.schema.types[kd.name + 'EngineConfig'] + assert 'specialTestingField' not in kdSchema.resourceFields + + NEW_URL = NEW_DRIVER_URL + if platform.machine() == "aarch64": + NEW_URL = NEW_DRIVER_ARM64_URL + kd.url = NEW_URL + kd = client.update_by_id_kontainerDriver(kd.id, kd) + + def schema_updated(): + client.reload_schema() + kdSchema = client.schema.types[kd.name + 'EngineConfig'] + return 'specialTestingField' in kdSchema.resourceFields + + wait_until(schema_updated) + + kdSchema = client.schema.types[kd.name + 'EngineConfig'] + assert 'specialTestingField' in kdSchema.resourceFields + + +@pytest.mark.skip +@pytest.mark.nonparallel +def test_create_duplicate_driver_conflict(admin_mc, wait_remove_resource): + """ Test if adding a driver with a pre-existing driver's URL + returns a conflict error""" + URL = DRIVER_AMD64_URL + if platform.machine() == "aarch64": + URL = DRIVER_ARM64_URL + kd = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + ) + wait_remove_resource(kd) + kd = wait_for_condition('Active', 'True', admin_mc.client, kd, timeout=90) + + try: + kd2 = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + ) + wait_remove_resource(kd2) + pytest.fail("Failed to catch duplicate driver URL on create") + except ApiError as e: + assert e.error.status == 409 + assert "Driver URL already in use:" in e.error.message + + +@pytest.mark.skip +@pytest.mark.nonparallel +def test_update_duplicate_driver_conflict(admin_mc, wait_remove_resource): + """ Test if updating a driver's URL to a pre-existing driver's URL + returns a conflict error""" + URL = DRIVER_AMD64_URL + if platform.machine() == "aarch64": + URL = DRIVER_ARM64_URL + kd1 = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + ) + wait_remove_resource(kd1) + kd1 = wait_for_condition('Active', 'True', admin_mc.client, kd1, + timeout=90) + + kd2 = admin_mc.client.create_kontainerDriver( + createDynamicSchema=True, + active=True, + url=URL + "2" + ) + wait_remove_resource(kd2) + kd2.url = URL + + try: + admin_mc.client.update_by_id_kontainerDriver(kd2.id, kd2) + pytest.fail("Failed to catch duplicate driver URL on update") + except ApiError as e: + assert e.error.status == 409 + assert "Driver URL already in use:" in e.error.message + + +@pytest.mark.skip +def test_kontainer_driver_links(admin_mc): + client = admin_mc.client + lister = client.list_kontainerDriver() + assert 'rancher-images' in lister.links + assert 'rancher-windows-images' in lister.links + token = 'Bearer '+client.token + url = BASE_URL + "/kontainerdrivers/rancher-images" + images = get_images(url, token) + assert "hyperkube" in images + assert "rke-tools" in images + assert "kubelet-pause" not in images + # test windows link + url = BASE_URL + "/kontainerdrivers/rancher-windows-images" + images = get_images(url, token) + assert "hyperkube" in images + assert "rke-tools" in images + assert "mirrored-pause" in images + + +def get_images(url, token): + data = requests.get( + url=url, + verify=False, + headers={'Accept': '*/*', 'Authorization': token}) + assert data is not None + content = data.content.splitlines() + assert len(content) > 0 + test = {} + for line in content: + if "rancher/hyperkube" in str(line): + test["hyperkube"] = True + elif "rancher/rke-tools" in str(line): + test["rke-tools"] = True + elif "rancher/kubelet-pause" in str(line): + test["kubelet-pause"] = True + elif "rancher/mirrored-pause" in str(line): + test["mirrored-pause"] = True + return test + + +def verify_driver_in_types(client, kd): + def check(): + client.reload_schema() + types = client.schema.types + return kd.name + 'EngineConfig' in types + + wait_until(check) + client.reload_schema() + assert kd.name + 'EngineConfig' in client.schema.types + + +def verify_driver_not_in_types(client, kd): + def check(): + client.reload_schema() + types = client.schema.types + return kd.name + 'EngineConfig' not in types + + wait_until(check) + client.reload_schema() + assert kd.name + 'EngineConfig' not in client.schema.types + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_user_update_settings(admin_mc): + client = admin_mc.client + k8s_version_setting = client.by_id_setting('k8s-version') + default_k8s_version = k8s_version_setting["default"] + k8s_versions_curr = client.by_id_setting( + 'k8s-versions-current')["value"].split(",") + + # user updates correct value + user_value = k8s_versions_curr[0] + updated_version = admin_mc.client.update_by_id_setting( + id='k8s-version', value=user_value) + assert updated_version["default"] == default_k8s_version + assert updated_version["value"] == user_value + assert updated_version["labels"]["io.cattle.user.updated"] == "true" + + # assert refresh action doesn't override + lister = client.list_kontainerDriver() + + try: + client.action(obj=lister, action_name="refresh") + except ApiError as e: + assert e.value.error.status == 422 + + new_k8s_version = client.by_id_setting('k8s-version') + assert new_k8s_version["default"] == default_k8s_version + assert new_k8s_version["value"] == user_value + + # user updates invalid value + user_value = "v1.15.4-rancher13" + try: + updated_version = admin_mc.client.update_by_id_setting( + id='k8s-version', value=user_value) + except ApiError as e: + assert e.error.code == "MissingRequired" + assert e.error.status == 422 + + # bring back the default value, user updates with empty value + user_value = "" + updated_version = admin_mc.client.update_by_id_setting( + id='k8s-version', value=user_value) + assert updated_version["default"] == default_k8s_version + assert updated_version["value"] == default_k8s_version + assert updated_version["labels"]["io.cattle.user.updated"] == "false" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_annotations.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_annotations.py new file mode 100644 index 0000000..ada9d7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_annotations.py @@ -0,0 +1,110 @@ +from .common import random_str +from .conftest import wait_until, wait_for + +annotation = "clusterstatus.management.cattle.io/" \ + "temporary-security-credentials" +access_key = "accessKey" +secret_key = "secretKey" +session_token = "sessionToken" +region = "region" + +""" +There are effectively 2 ways that an EKS cluster will get a temporary \ +security credentials annotation. The first way is if it is created with \ +a session token, then an annotation will be added in the \ +cluster_store.go. The other way is if a cluster is edited to add a \ +session token. In this case a controller will watch for the change and \ +apply the annotation. We test for both of those scenarios here. +""" + + +def has_cluster_annotation(client, cluster, expected=None): + def poll(): + cluster2 = client.reload(cluster) + + has_attribute = hasattr(cluster2.annotations, annotation) + + if expected is not None: + return has_attribute and cluster2.annotations[annotation] == \ + expected + else: + return has_attribute + + return poll + + +def assert_cluster_annotation(expected, admin_mc, remove_resource, config): + cluster = admin_mc.client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig=config) + remove_resource(cluster) + + assert cluster.annotations[annotation] == expected + + wait_until(has_cluster_annotation(admin_mc.client, cluster)) + + cluster = admin_mc.client.reload(cluster) + + assert cluster.annotations[annotation] == expected + + return cluster + + +def test_eks_cluster_gets_temp_security_credentials_annotation( + admin_mc, remove_resource): + eks = { + access_key: "not a real access key", + secret_key: "not a real secret key", + session_token: "not a real session token", + region: "us-west-2", + } + + assert_cluster_annotation("true", admin_mc, remove_resource, eks) + + +def test_eks_does_not_get_temp_security_creds_annotation_no_field( + admin_mc, remove_resource): + eks = { + access_key: "not a real access key", + secret_key: "not a real secret key", + region: "us-west-2", + } + + assert_cluster_annotation("false", admin_mc, remove_resource, eks) + + +def test_eks_does_not_get_temp_security_creds_annotation_empty_field( + admin_mc, remove_resource): + eks = { + access_key: "not a real access key", + secret_key: "not a real secret key", + session_token: "", + region: "us-west-2", + } + + assert_cluster_annotation("false", admin_mc, remove_resource, eks) + + +def test_editing_eks_cluster_gives_temp_creds_annotation( + admin_mc, remove_resource): + eks = { + access_key: "not a real access key", + secret_key: "not a real secret key", + region: "us-west-2", + } + + cluster = assert_cluster_annotation("false", admin_mc, remove_resource, + eks) + eks = cluster.amazonElasticContainerServiceConfig + setattr(eks, session_token, "not a real session token") + cluster = admin_mc.client.update_by_id_cluster( + id=cluster.id, + name=cluster.name, + amazonElasticContainerServiceConfig=eks + ) + + wait_for(has_cluster_annotation(admin_mc.client, cluster, + expected="true"), timeout=120) + + cluster = admin_mc.client.reload(cluster) + + assert cluster.annotations[annotation] == "true" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_config.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_config.py new file mode 100644 index 0000000..cbd9ed9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_config.py @@ -0,0 +1,159 @@ +from .common import random_str + + +def test_gke_config_appears_correctly(admin_mc, remove_resource): + cluster = admin_mc.client.create_cluster( + name=random_str(), googleKubernetesEngineConfig={ + "credentials": "bad credentials", + "nodeCount": 3 + }) + remove_resource(cluster) + + # test that a cluster returned from a POST has the correct config + assert cluster.googleKubernetesEngineConfig.nodeCount == 3 + + clusters = admin_mc.client.list_cluster(name=cluster.name) + + # test that a cluster returned from a list has the correct config + assert len(clusters) == 1 + assert clusters.data[0].googleKubernetesEngineConfig.nodeCount == 3 + + cluster = admin_mc.client.by_id_cluster(id=cluster.id) + # test that a cluster returned from a GET has the correct config + assert cluster.googleKubernetesEngineConfig.nodeCount == 3 + + cluster.googleKubernetesEngineConfig.nodeCount = 4 + cluster = admin_mc.client.update_by_id_cluster(cluster.id, cluster) + + # test that a cluster returned from a PUT has the correct config + assert cluster.googleKubernetesEngineConfig.nodeCount == 4 + + +def test_eks_config_appears_correctly(admin_mc, remove_resource): + """ Simple test to ensure that cluster returned from POST is correct""" + cluster = admin_mc.client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig={ + "accessKey": "MyAccessKey", + "ami": "", + "associateWorkerNodePublicIp": True, + "displayName": "EKS-api-cluster", + "driverName": "amazonelasticcontainerservice", + "instanceType": "t3.small", + "kubernetesVersion": "1.14", + "maximumNodes": 3, + "minimumNodes": 1, + "region": "us-east-2", + "secretKey": "secret-key", + "serviceRole": "", + "sessionToken": "", + "userData": "!#/bin/bash\ntouch /tmp/testfile.txt", + "virtualNetwork": "", + }) + remove_resource(cluster) + + # test cluster returned from POST has correct config + assert cluster.amazonElasticContainerServiceConfig.maximumNodes == 3 + + assert (cluster.amazonElasticContainerServiceConfig.userData == + "!#/bin/bash\ntouch /tmp/testfile.txt") + + clusters = admin_mc.client.list_cluster(name=cluster.name) + + # test that a cluster returned from a list has the correct config + assert len(clusters) == 1 + assert (clusters.data[0].amazonElasticContainerServiceConfig.maximumNodes + == 3) + + cluster = admin_mc.client.by_id_cluster(cluster.id) + # test that a cluster returned from a GET has the correct config + assert cluster.amazonElasticContainerServiceConfig.maximumNodes == 3 + + cluster.amazonElasticContainerServiceConfig.maximumNodes = 5 + cluster = admin_mc.client.update_by_id_cluster(cluster.id, cluster) + + # test that cluster returned from PUT has correct config + assert cluster.amazonElasticContainerServiceConfig.maximumNodes == 5 + + +def test_rke_config_appears_correctly(admin_mc, remove_resource): + """ Testing a single field from the RKE config to ensure that the + schema is properly populated""" + cluster = admin_mc.client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "kubernetesVersion": "v1.12.9-rancher1-1", + }) + remove_resource(cluster) + + k8s_version = cluster.rancherKubernetesEngineConfig.kubernetesVersion + assert k8s_version == "v1.12.9-rancher1-1" + + +def test_rke_config_no_change_k8sversion_addon(admin_mc, remove_resource): + """ Testing if kubernetesVersion stays the same after updating + something else in the cluster, e.g. addonJobTimeout""" + k8s_version = "v1.12.9-rancher1-1" + cluster = admin_mc.client.create_cluster( + name=random_str(), rancherKubernetesEngineConfig={ + "kubernetesVersion": k8s_version, + }) + remove_resource(cluster) + cluster = admin_mc.client.update_by_id_cluster( + id=cluster.id, + name=cluster.name, + rancherKubernetesEngineConfig={ + "addonJobTimeout": 45, + }) + k8s_version_post = cluster.rancherKubernetesEngineConfig.kubernetesVersion + assert k8s_version_post == k8s_version + + +def test_rke_config_no_change_k8sversion_np(admin_mc, remove_resource): + """ Testing if kubernetesVersion stays the same after updating + something else in the cluster, e.g. addonJobTimeout""" + cluster_config_np_false = { + "enableNetworkPolicy": "false", + "rancherKubernetesEngineConfig": { + "addonJobTimeout": 45, + "kubernetesVersion": "v1.12.9-rancher1-1", + "network": { + "plugin": "canal", + } + } + } + + cluster = admin_mc.client.create_cluster( + name=random_str(), + cluster=cluster_config_np_false, + ) + remove_resource(cluster) + + cluster_config_np_true = { + "name": cluster.name, + "enableNetworkPolicy": "true", + "rancherKubernetesEngineConfig": { + "network": { + "plugin": "canal", + } + } + } + + cluster = admin_mc.client.update_by_id_cluster( + cluster.id, + cluster_config_np_true, + ) + + cluster_config_addonjob = { + "name": cluster.name, + "rancherKubernetesEngineConfig": { + "addonJobTimeout": 55, + "network": { + "plugin": "canal", + } + } + } + + cluster = admin_mc.client.update_by_id_cluster( + cluster.id, + cluster_config_addonjob, + ) + assert cluster.enableNetworkPolicy is True diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_validation.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_validation.py new file mode 100644 index 0000000..d94baaa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_kontainer_engine_validation.py @@ -0,0 +1,99 @@ +from .common import random_str +from .conftest import wait_until + + +def assert_has_error_message(admin_mc, remove_resource, eks, message): + cluster = admin_mc.client.create_cluster( + name=random_str(), amazonElasticContainerServiceConfig=eks) + remove_resource(cluster) + + def get_provisioned_type(cluster): + for condition in cluster.conditions: + if condition.type == "Provisioned": + if hasattr(condition, 'message'): + return condition.message + return None + + def has_provision_status(): + new_cluster = admin_mc.client.reload(cluster) + + return \ + hasattr(new_cluster, "conditions") and \ + get_provisioned_type(new_cluster) is not None + + def has_error_message(): + for condition in cluster.conditions: + if condition.type == "Provisioned": + if getattr(condition, 'message') == message: + return True + + return False + + wait_until(has_provision_status) + cluster = admin_mc.client.reload(cluster) + + wait_until(has_error_message, timeout=120, backoff=False) + cluster = admin_mc.client.reload(cluster) + + assert has_error_message(), "no error message %r was present" % \ + message + + +def test_min_nodes_cannot_be_greater_than_max(admin_mc, remove_resource): + eks = { + "accessKey": "not a real access key", + "secretKey": "not a real secret key", + "region": "us-west-2", + "kubernetesVersion": "1.17", + "minimumNodes": 3, + "maximumNodes": 2 + } + + assert_has_error_message(admin_mc, remove_resource, eks, + "error parsing state: maximum nodes cannot " + "be less than minimum nodes") + + +def test_min_nodes_cannot_be_zero(admin_mc, remove_resource): + eks = { + "accessKey": "not a real access key", + "secretKey": "not a real secret key", + "region": "us-west-2", + "kubernetesVersion": "1.17", + "minimumNodes": 0, + "maximumNodes": 0 + } + assert_has_error_message(admin_mc, remove_resource, eks, + "error parsing state: minimum nodes must be " + "greater than 0") + + +def test_node_volume_size_cannot_be_zero(admin_mc, remove_resource): + eks = { + "accessKey": "not a real access key", + "secretKey": "not a real secret key", + "region": "us-west-2", + "kubernetesVersion": "1.17", + "minimumNodes": 1, + "maximumNodes": 3, + "nodeVolumeSize": 0 + } + assert_has_error_message(admin_mc, remove_resource, eks, + "error parsing state: node volume size must " + "be greater than 0") + + +def test_private_cluster_requires_vpc_subnets(admin_mc, remove_resource): + eks = { + "accessKey": "not a real access key", + "secretKey": "not a real secret key", + "region": "us-west-2", + "kubernetesVersion": "1.17", + "minimumNodes": 1, + "maximumNodes": 3, + "associateWorkerNodePublicIp": False + } + assert_has_error_message(admin_mc, remove_resource, eks, + "error parsing state: if " + "AssociateWorkerNodePublicIP is set to " + "false a VPC and subnets must also be provided") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_multi_cluster_app.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_multi_cluster_app.py new file mode 100644 index 0000000..40c9fab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_multi_cluster_app.py @@ -0,0 +1,686 @@ +from .common import random_str, check_subject_in_rb + +from rancher import ApiError + +from .conftest import ( + wait_until, wait_for, set_server_version, wait_until_available, + user_project_client +) +import time +import pytest +import kubernetes + +roles_resource = 'roles' +projects_resource = 'projects' +members_resource = 'members' + + +def test_multiclusterapp_create_no_roles(admin_mc, admin_pc, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + # should not be able to create without passing roles + try: + mcapp = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets) + remove_resource(mcapp) + except ApiError as e: + assert e.error.status == 422 + + +def test_mutliclusterapp_invalid_project(admin_mc, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": "abc:def"}] + try: + mcapp = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets) + remove_resource(mcapp) + except ApiError as e: + assert e.error.status == 422 + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_multiclusterapp_create_with_members(admin_mc, admin_pc, + user_factory, remove_resource, + ): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + + targets = [{"projectId": admin_pc.project.id}] + + user_member = user_factory() + remove_resource(user_member) + user_not_member = user_factory() + remove_resource(user_not_member) + members = [{"userPrincipalId": "local://"+user_member.user.id, + "accessType": "read-only"}] + roles = ["cluster-owner", "project-member"] + + mcapp1 = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + members=members, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + # check who has access to the multiclusterapp + # admin and user_member should be able to list it + id = "cattle-global-data:" + mcapp_name + mcapp = client.by_id_multi_cluster_app(id) + assert mcapp is not None + um_client = user_member.client + mcapp = um_client.by_id_multi_cluster_app(id) + assert mcapp is not None + + # member should also get access to the mcapp revision + if mcapp['status']['revisionId'] != '': + mcapp_revision_id = "cattle-global-data:" + \ + mcapp['status']['revisionId'] + mcr = um_client.\ + by_id_multi_cluster_app_revision(mcapp_revision_id) + assert mcr is not None + + # user who's not a member shouldn't get access + unm_client = user_not_member.client + try: + unm_client.by_id_multi_cluster_app(id) + except ApiError as e: + assert e.error.status == 403 + + # add the special char * to indicate sharing of resource with all + # authenticated users + new_members = [{"userPrincipalId": "local://"+user_member.user.id, + "accessType": "read-only"}, {"groupPrincipalId": "*"}] + client.update(mcapp, members=new_members, roles=roles) + + # now user_not_member should be able to access this mcapp without + # being explicitly added + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + split = mcapp.id.split(":") + name = split[1] + rb_name = name + "-m-r" + wait_for(lambda: check_subject_in_rb(rbac, 'cattle-global-data', + 'system:authenticated', rb_name), + timeout=60, fail_handler=lambda: + 'failed to check updated rolebinding') + + mcapp = user_not_member.client.by_id_multi_cluster_app(id) + assert mcapp is not None + + # even newly created users should be able to access this mcapp + new_user = user_factory() + remove_resource(new_user) + mcapp = new_user.client.by_id_multi_cluster_app(id) + assert mcapp is not None + + +@pytest.mark.skip +def test_multiclusterapp_admin_create(admin_mc, admin_pc, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + roles = ["cluster-owner", "project-member"] + # roles check should be relaxed for admin + mcapp1 = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + +@pytest.mark.skip +def test_multiclusterapp_cluster_owner_create(admin_mc, admin_pc, + remove_resource, user_factory): + client = admin_mc.client + mcapp_name = random_str() + cowner = user_factory() + crtb_owner = client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId="cluster-owner", + userId=cowner.user.id) + remove_resource(crtb_owner) + wait_until(rtb_cb(client, crtb_owner)) + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + roles = ["cluster-owner", "project-member"] + # user isn't explicitly added as project-member, but this check should be + # relaxed since user is added as cluster-owner + mcapp1 = cowner.client.\ + create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + + +@pytest.mark.skip +def test_multiclusterapp_project_owner_create(admin_mc, admin_pc, + remove_resource, user_factory): + client = admin_mc.client + mcapp_name = random_str() + powner = user_factory() + prtb_owner = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-owner", + userId=powner.user.id) + remove_resource(prtb_owner) + wait_until(rtb_cb(client, prtb_owner)) + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + roles = ["project-member"] + # user isn't explicitly added as project-member, but this check should be + # relaxed since user is added as project-owner + mcapp1 = powner.client.\ + create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + + +@pytest.mark.skip +def test_multiclusterapp_user_create(admin_mc, admin_pc, remove_resource, + user_factory): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + # make regular user cluster-owner and project-owner in the cluster and + # it's project + user = user_factory() + remove_resource(user) + user_client = user.client + crtb_owner = client.create_cluster_role_template_binding( + clusterId="local", + roleTemplateId="cluster-owner", + userId=user.user.id) + remove_resource(crtb_owner) + wait_until(rtb_cb(client, crtb_owner)) + prtb_member = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-member", + userId=user.user.id) + remove_resource(prtb_member) + wait_until(rtb_cb(client, prtb_member)) + roles = ["cluster-owner", "project-member"] + mcapp1 = user_client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + # try creating as a user who is not cluster-owner, + # but that is one of the roles listed, must fail + user_no_roles = user_factory() + remove_resource(user_no_roles) + # add user to project as member but not to cluster as owner + prtb_member = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-member", + userId=user_no_roles.user.id) + remove_resource(prtb_member) + + wait_until(rtb_cb(client, prtb_member)) + try: + user_no_roles.client.\ + create_multi_cluster_app(name=random_str(), + templateVersionId=temp_ver, + targets=targets, + roles=roles) + except ApiError as e: + assert e.error.status == 403 + assert "does not have roles cluster-owner in cluster"\ + in e.error.message + assert "cluster-owner" in e.error.message + + +@pytest.mark.skip +def test_multiclusterapp_admin_update_roles(admin_mc, admin_pc, + remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + roles = ["project-member"] + mcapp1 = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + # admin doesn't get cluster/project roles (crtb/prtb) by default + # but updating the mcapp to add these roles must pass, since global admin + # should have access to everything and must be excused + new_roles = ["cluster-owner", "project-member"] + client.update(mcapp1, roles=new_roles) + wait_for(lambda: check_updated_roles(admin_mc, mcapp_name, new_roles), + timeout=60, fail_handler=fail_handler(roles_resource)) + + +@pytest.mark.skip +def test_multiclusterapp_user_update_roles(admin_mc, admin_pc, remove_resource, + user_factory): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + # create mcapp as admin, passing "cluster-owner" role + roles = ["cluster-owner"] + # add a user as a member with access-type owner + user = user_factory() + remove_resource(user) + members = [{"userPrincipalId": "local://" + user.user.id, + "accessType": "owner"}] + mcapp1 = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles, + members=members) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + # user wants to update roles to add project-member role + # but user is not a part of target project, so this must fail + new_roles = ["cluster-owner", "project-member"] + try: + user.client.update(mcapp1, roles=new_roles) + except ApiError as e: + assert e.error.status == 403 + assert "does not have roles project-member in project" \ + in e.error.message + assert "of cluster local" in e.error.message + + # now admin adds this user to project as project-member + prtb_member = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-member", + userId=user.user.id) + remove_resource(prtb_member) + wait_until(rtb_cb(client, prtb_member)) + + # now user should be able to add project-member role + user.client.update(mcapp1, roles=new_roles) + wait_for(lambda: check_updated_roles(admin_mc, mcapp_name, new_roles), + timeout=60, fail_handler=fail_handler(roles_resource)) + + +@pytest.mark.skip +def test_admin_access(admin_mc, admin_pc, user_factory, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + user = user_factory() + remove_resource(user) + prtb_member = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-member", + userId=user.user.id) + remove_resource(prtb_member) + wait_until(rtb_cb(client, prtb_member)) + mcapp1 = user.client.\ + create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=["project-member"]) + wait_for_app(admin_pc, mcapp_name, 60) + client.update(mcapp1, roles=["cluster-owner"]) + wait_for(lambda: check_updated_roles(admin_mc, mcapp_name, + ["cluster-owner"]), timeout=60, + fail_handler=fail_handler(roles_resource)) + + +@pytest.mark.skip +def test_add_projects(admin_mc, admin_pc, admin_cc, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + targets = [{"projectId": admin_pc.project.id}] + mcapp1 = client.\ + create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=["project-member"]) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + remove_resource(p) + p = admin_cc.management.client.wait_success(p) + client.action(obj=mcapp1, action_name="addProjects", + projects=[p.id]) + new_projects = [admin_pc.project.id, p.id] + wait_for(lambda: check_updated_projects(admin_mc, mcapp_name, + new_projects), timeout=60, + fail_handler=fail_handler(projects_resource)) + + +@pytest.mark.skip +def test_remove_projects(admin_mc, admin_pc, admin_cc, remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-wordpress-1.0.5" + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + remove_resource(p) + p = admin_cc.management.client.wait_success(p) + targets = [{"projectId": admin_pc.project.id}, {"projectId": p.id}] + mcapp1 = client. \ + create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=["project-member"]) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + client.action(obj=mcapp1, action_name="removeProjects", projects=[p.id]) + new_projects = [admin_pc.project.id] + wait_for(lambda: check_updated_projects(admin_mc, mcapp_name, + new_projects), timeout=60, + fail_handler=fail_handler(projects_resource)) + + +@pytest.mark.skip +def test_multiclusterapp_revision_access(admin_mc, admin_pc, remove_resource, + user_factory): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-mysql-0.3.8" + targets = [{"projectId": admin_pc.project.id}] + user = user_factory() + remove_resource(user) + user_client = user.client + # assign user to local cluster as project-member + prtb_member = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-member", + userId=user.user.id) + + remove_resource(prtb_member) + wait_until(rtb_cb(client, prtb_member)) + roles = ["project-member"] + mcapp1 = user_client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + + mcapp_revisions = user_client.list_multi_cluster_app_revision() + assert len(mcapp_revisions) == 1 + + +@pytest.mark.skip(reason='flaky test maybe, skipping for now') +def test_app_upgrade_mcapp_roles_change(admin_mc, admin_pc, + remove_resource): + client = admin_mc.client + mcapp_name = random_str() + temp_ver = "cattle-global-data:library-grafana-0.0.31" + targets = [{"projectId": admin_pc.project.id}] + roles = ["project-member"] + mcapp1 = client.create_multi_cluster_app(name=mcapp_name, + templateVersionId=temp_ver, + targets=targets, + roles=roles) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_name, 60) + # changing roles should trigger app upgrade + roles = ["cluster-owner"] + client.update(mcapp1, roles=roles) + wait_for_app_condition(admin_pc, mcapp_name, 'UserTriggeredAction', 60) + + +def wait_for_app_condition(admin_pc, name, condition, timeout=60): + start = time.time() + interval = 0.5 + client = admin_pc.client + cluster_id, project_id = admin_pc.project.id.split(':') + app_name = name+"-"+project_id + found = False + while not found: + if time.time() - start > timeout: + raise Exception('Timeout waiting for app of multiclusterapp') + apps = client.list_app(name=app_name) + if len(apps) > 0: + conditions = apps['data'][0]['conditions'] + for c in conditions: + if c['type'] == condition and\ + c['status'] == 'True': + found = True + time.sleep(interval) + interval *= 2 + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_mcapp_create_validation(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test create validation of multi cluster apps. This test will set the + rancher version explicitly and attempt to create apps with rancher version + requirements + """ + # 1.6.0 uses 2.0.0-2.2.0 + # 1.6.2 uses 2.1.0-2.3.0 + c_name = random_str() + custom_catalog(name=c_name) + + client = admin_mc.client + server_version = "2.0.0" + set_server_version(client, server_version) + + cat_ns_name = "cattle-global-data:"+c_name + + mcapp_data = { + 'name': random_str(), + 'templateVersionId': cat_ns_name+"-chartmuseum-1.6.2", + 'targets': [{"projectId": admin_pc.project.id}], + 'roles': ["cluster-owner", "project-member"], + } + + # First app requires a min rancher version of 2.1 so we expect an error + with pytest.raises(ApiError) as e: + mcapp1 = client.create_multi_cluster_app(mcapp_data) + remove_resource(mcapp1) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + # Second app requires a min of 2.0 so no error should be returned + mcapp_data['name'] = random_str() + mcapp_data['templateVersionId'] = cat_ns_name+"-chartmuseum-1.6.0", + mcapp2 = client.create_multi_cluster_app(mcapp_data) + remove_resource(mcapp2) + wait_for_app(admin_pc, mcapp_data['name']) + + server_version = "2.2.1" + set_server_version(client, server_version) + # Third app requires a max of version 2.2.0 so expect error + with pytest.raises(ApiError) as e: + mcapp_data['name'] = random_str() + mcapp3 = client.create_multi_cluster_app(mcapp_data) + remove_resource(mcapp3) + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + +@pytest.mark.nonparallel +@pytest.mark.skip +def test_mcapp_update_validation(admin_mc, admin_pc, custom_catalog, + remove_resource, restore_rancher_version): + """Test update validation of multi cluster apps. This test will set the + rancher version explicitly and attempt to update an app with rancher + version requirements + """ + # 1.6.0 uses 2.0.0-2.2.0 + # 1.6.2 uses 2.1.0-2.3.0 + c_name = random_str() + custom_catalog(name=c_name) + + client = admin_mc.client + server_version = "2.0.0" + set_server_version(client, server_version) + + cat_ns_name = "cattle-global-data:"+c_name + + mcapp_data = { + 'name': random_str(), + 'templateVersionId': cat_ns_name+"-chartmuseum-1.6.0", + 'targets': [{"projectId": admin_pc.project.id}], + 'roles': ["cluster-owner", "project-member"], + } + + # First app requires a min rancher version of 2.0 so no error + mcapp1 = client.create_multi_cluster_app(mcapp_data) + remove_resource(mcapp1) + wait_for_app(admin_pc, mcapp_data['name']) + + # App upgrade requires a min of 2.1 so expect error + with pytest.raises(ApiError) as e: + mcapp1 = client.update_by_id_multi_cluster_app( + id=mcapp1.id, templateVersionId=cat_ns_name+"-chartmuseum-1.6.2") + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + server_version = "2.3.1" + set_server_version(client, server_version) + # App upgrade requires a max of 2.3 so expect error + with pytest.raises(ApiError) as e: + mcapp1 = client.update_by_id_multi_cluster_app( + id=mcapp1.id, templateVersionId=cat_ns_name+"-chartmuseum-1.6.2") + assert e.value.error.status == 422 + assert 'incompatible rancher version [%s] for template' % server_version \ + in e.value.error.message + + +@pytest.mark.skip +def test_perform_mca_action_read_only(admin_mc, admin_pc, remove_resource, + user_mc, user_factory): + """Tests MCA actions with a read-only user and a member user.""" + client = admin_mc.client + project = admin_pc.project + user = user_mc + user_member = user_factory() + + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=project.id) + remove_resource(ns) + + # Create a read-only user binding. + prtb1 = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user.user.id, + projectId=project.id, + roleTemplateId="read-only") + remove_resource(prtb1) + wait_until_available(user.client, project) + + # Then, create a member user binding. + prtb2 = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_member.user.id, + projectId=project.id, + roleTemplateId="project-member") + remove_resource(prtb2) + wait_until_available(user_member.client, project) + user_pc = user_project_client(user, project) + user_member_pc = user_project_client(user_member, project) + + # Admin user creates the MCA and specifically adds both users. The + # project-member user should have permissions by default since their role + # is specified in the MCA creation. + mcapp_name = random_str() + mcapp_user_read_only = "local://" + user.user.id + mcapp_user_member = "local://" + user_member.user.id + mcapp = client.create_multi_cluster_app( + name=mcapp_name, + templateVersionId="cattle-global-data:library-docker-registry-1.9.2", + targets=[{"projectId": admin_pc.project.id}], + members=[{"userPrincipalId": mcapp_user_read_only, + "accessType": "read-only"}, + {"userPrincipalId": mcapp_user_member, + "accessType": "member"}], + roles=["cluster-owner", "project-member"]) + remove_resource(mcapp) + wait_for_app(admin_pc, mcapp_name) + + # Admin user updates the MCA to yield a rollback option. We change the + # image version below. + mcapp = client.reload(mcapp) + original_rev = mcapp.revisions().data[0].name + mcapp.templateVersionId = ( + "cattle-global-data:library-docker-registry-1.8.1") + mcapp = client.update_by_id_multi_cluster_app(mcapp.id, mcapp) + wait_for_app(admin_pc, mcapp_name) + mcapp = client.reload(mcapp) + + # Read-only users should receive a 404 error. + with pytest.raises(ApiError) as e: + user_pc.action(obj=mcapp, action_name="rollback", + revisionId=original_rev) + assert e.value.error.status == 404 + + # Member users will be able to perform the rollback. + user_member_pc.action(obj=mcapp, action_name="rollback", + revisionId=original_rev) + + +def wait_for_app(admin_pc, name, timeout=60): + start = time.time() + interval = 0.5 + client = admin_pc.client + project_id = admin_pc.project.id.split(':')[1] + app_name = name+"-"+project_id + found = False + while not found: + if time.time() - start > timeout: + raise Exception('Timeout waiting for app of multiclusterapp') + apps = client.list_app(name=app_name) + if len(apps) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def rtb_cb(client, rtb): + """Wait for the prtb to have the userId populated""" + def cb(): + rt = client.reload(rtb) + return rt.userPrincipalId is not None + return cb + + +def check_updated_projects(admin_mc, mcapp_name, projects): + mcapp_projects = [] + id = "cattle-global-data:" + mcapp_name + mcapp = admin_mc.client.by_id_multi_cluster_app(id) + for t in mcapp.targets: + mcapp_projects.append(t.projectId) + if mcapp_projects == projects: + return True + return False + + +def check_updated_roles(admin_mc, mcapp_name, roles): + id = "cattle-global-data:" + mcapp_name + mcapp = admin_mc.client.by_id_multi_cluster_app(id) + if mcapp is not None and mcapp.roles == roles: + return True + return False + + +def fail_handler(resource): + return "failed waiting for multiclusterapp " + resource + " to get updated" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_namespaced_secrets.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_namespaced_secrets.py new file mode 100644 index 0000000..9e41f95 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_namespaced_secrets.py @@ -0,0 +1,252 @@ +from .common import random_str +from .test_secrets import CERT, KEY + +UPDATED_CERT = """-----BEGIN CERTIFICATE----- +MIIDEDCCAfgCCQC+HwE8rpMN7jANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hlciBMYWJzMRIwEAYD +VQQDEwlsb2NhbGhvc3QwHhcNMTYwNjMwMDExMzMyWhcNMjYwNjI4MDExMzMyWjBK +MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hl +ciBMYWJzMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC1PR0EiJjM0wbFQmU/yKSb7AuQdzhdW02ya+RQe+31/B+sOTMr +z9b473KCKf8LiFKFOIQUhR5fPvwyrrIWKCEV9pCp/wM474fX32j0zYaH6ezZjL0r +L6hTeGFScGse3dk7ej2+6nNWexpujos0djFi9Gu11iVHIJyT2Sx66kPPPZVRkJO9 +5Pfetm5SLIQtJHUwy5iWv5Br+AbdXlUAjTYUqS4mhKIIbblAPbOKrYRxGXX/6oDV +J5OGLle8Uvlb8poxqmy67FPyMObNHhjggKwboXhmNuuT2OGf/VeZANMYubs4JP2V +ZLs3U/1tFMAOaQM+PbT9JuwMSmGYFX0Qiuh/AgMBAAEwDQYJKoZIhvcNAQEFBQAD +ggEBACpkRCQpCn/zmTOwboBckkOFeqMVo9cvSu0Sez6EPED4WUv/6q5tlJeHekQm +6YVcsXeOMkpfZ7qtGmBDwR+ly7D43dCiPKplm0uApO1CkogG5ePv0agvKHEybd36 +xu9pt0fnxDdrP2NrP6trHq1D+CzPZooLRfmYqbt1xmIb00GpnyiJIUNuMu7GUM3q +NxWGK3eq+1cyt6xr8nLOC5zaGeSyZikw4+9vqLudNSyYdnw9mdHtrYT0GlcEP1Vc +NK+yrhDCvEWH6+4+pp8Ve2P2Le5tvbA1m24AxyuC9wHS5bUmiNHweLXNpxLFTjK8 +BBUi6y1Vm9jrDi/LiiHcN4sJEoP= +-----END CERTIFICATE-----""" + + +def test_namespaced_secrets(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + secret = client.create_namespaced_secret(name=name, namespaceId=ns.id, + stringData={ + 'foo': 'bar' + }) + + assert secret.baseType == 'namespacedSecret' + assert secret.type == 'namespacedSecret' + assert secret.kind == 'Opaque' + assert secret.name == name + assert secret.data.foo == 'YmFy' + + secret.data.baz = 'YmFy' + secret = client.update(secret, data=secret.data) + assert secret is not None + secret = client.reload(secret) + + assert secret.baseType == 'namespacedSecret' + assert secret.type == 'namespacedSecret' + assert secret.kind == 'Opaque' + assert secret.name == name + assert secret.data.foo == 'YmFy' + assert secret.data.baz == 'YmFy' + assert secret.namespaceId == ns.id + assert 'namespace' not in secret.data + assert secret.projectId == admin_pc.project.id + + found = False + for i in client.list_namespaced_secret(): + if i.id == secret.id: + found = True + break + + assert found + + client.delete(secret) + + +def test_namespaced_certificates(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + cert = client.create_namespaced_certificate(name=name, key=KEY, + namespaceId=ns.id, + certs=CERT) + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedCertificate' + assert cert.name == name + assert cert.certs == CERT + assert cert.namespaceId == ns.id + assert cert.projectId == admin_pc.project.id + assert 'namespace' not in cert + + cert = client.update(cert, certs=UPDATED_CERT) + assert cert.namespaceId == ns.id + assert cert.projectId == admin_pc.project.id + + cert = client.reload(cert) + + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedCertificate' + assert cert.name == name + assert cert.certs == UPDATED_CERT + assert cert.namespaceId == ns.id + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_namespaced_certificate(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_namespaced_certificate(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_namespaced_docker_credential(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + registries = {'index.docker.io': { + 'username': 'foo', + 'password': 'bar', + }} + cert = client.create_namespaced_docker_credential(name=name, + namespaceId=ns.id, + registries=registries) + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedDockerCredential' + assert cert.name == name + assert cert.registries['index.docker.io'].username == 'foo' + assert 'password' in cert.registries['index.docker.io'] + assert cert.namespaceId == ns.id + assert cert.projectId == admin_pc.project.id + + registries['two'] = { + 'username': 'blah' + } + + cert = client.update(cert, registries=registries) + cert = client.reload(cert) + + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedDockerCredential' + assert cert.name == name + assert cert.registries['index.docker.io'].username == 'foo' + assert cert.registries.two.username == 'blah' + assert 'password' not in cert.registries['index.docker.io'] + assert cert.namespaceId == ns.id + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_namespaced_docker_credential(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_namespaced_docker_credential(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_namespaced_basic_auth(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + cert = client.create_namespaced_basic_auth(name=name, + namespaceId=ns.id, + username='foo', + password='bar') + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedBasicAuth' + assert cert.name == name + assert cert.username == 'foo' + assert 'password' in cert + assert cert.namespaceId == ns.id + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + cert = client.update(cert, username='foo2') + cert = client.reload(cert) + + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedBasicAuth' + assert cert.name == name + assert cert.username == 'foo2' + assert 'password' not in cert + assert cert.namespaceId == ns.id + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_namespaced_basic_auth(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_namespaced_basic_auth(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_namespaced_ssh_auth(admin_pc, admin_cc_client): + client = admin_pc.client + + ns = admin_cc_client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + + name = random_str() + cert = client.create_namespaced_ssh_auth(name=name, + namespaceId=ns.id, + privateKey='foo') + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedSshAuth' + assert cert.name == name + assert 'privateKey' in cert + assert cert.namespaceId == ns.id + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + cert = client.update(cert, privateKey='foo2') + cert = client.reload(cert) + assert cert.baseType == 'namespacedSecret' + assert cert.type == 'namespacedSshAuth' + assert cert.name == name + assert 'privateKey' not in cert + assert cert.namespaceId == ns.id + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_namespaced_ssh_auth(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_namespaced_ssh_auth(cert.id) + assert cert is not None + + client.delete(cert) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node.py new file mode 100644 index 0000000..37a9892 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node.py @@ -0,0 +1,453 @@ +import os +import tempfile +import pytest +from rancher import ApiError +from kubernetes.client import CoreV1Api +from .common import auth_check, random_str, string_to_encoding +from .conftest import wait_for, wait_for_condition +import time + + +def test_node_fields(admin_mc): + cclient = admin_mc.client + fields = { + 'annotations': 'cru', + 'appliedNodeVersion': 'r', + 'labels': 'cru', + 'nodeTaints': 'r', + 'namespaceId': 'cr', + 'conditions': 'r', + 'allocatable': 'r', + 'capacity': 'r', + 'hostname': 'r', + 'info': 'r', + 'ipAddress': 'r', + 'externalIpAddress': 'r', + 'limits': 'r', + 'publicEndpoints': 'r', + 'nodePoolId': 'r', + 'nodePlan': 'r', + 'nodeName': 'r', + 'requested': 'r', + 'clusterId': 'cr', + 'etcd': 'cr', + 'controlPlane': 'cr', + 'worker': 'cr', + 'requestedHostname': 'cr', + 'volumesAttached': 'r', + 'nodeTemplateId': 'cr', + 'volumesInUse': 'r', + 'podCidr': 'r', + 'podCidrs': 'r', + 'name': 'cru', + 'taints': 'ru', + 'unschedulable': 'r', + 'providerId': 'r', + 'sshUser': 'r', + 'imported': 'cru', + 'dockerInfo': 'r', + 'scaledownTime': 'cru', + 'runtimeHandlers': 'r' + } + + for name in cclient.schema.types['node'].resourceFields.keys(): + if name.endswith("Config"): + fields[name] = 'cr' + + fields['customConfig'] = 'cru' + + auth_check(cclient.schema, 'node', 'crud', fields) + + +def test_node_template_delete(admin_mc, remove_resource): + """Test deleting a nodeTemplate that is in use by a nodePool. + The nodeTemplate should not be deleted while in use, after the nodePool is + removed, the nodes referencing the nodeTemplate will be deleted + and the nodeTemplate should delete + """ + client = admin_mc.client + node_template, cloud_credential = create_node_template(client) + node_pool = client.create_node_pool( + nodeTemplateId=node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + + # node_pool needs to come first or the API will stop the delete if the + # template still exists + remove_resource(node_pool) + remove_resource(node_template) + + assert node_pool.nodeTemplateId == node_template.id + + def _wait_for_no_remove_link(): + nt = client.reload(node_template) + if not hasattr(nt.links, "remove"): + return True + return False + + wait_for(_wait_for_no_remove_link) + + # Attempting to delete the template should raise an ApiError + with pytest.raises(ApiError) as e: + client.delete(node_template) + assert e.value.error.status == 405 + + client.delete(node_pool) + + def _node_pool_reload(): + np = client.reload(node_pool) + return np is None + + wait_for(_node_pool_reload) + + def _wait_for_remove_link(): + nt = client.reload(node_template) + if hasattr(nt.links, "remove"): + return True + return False + + wait_for(_wait_for_remove_link) + + # NodePool and Nodes are gone, template should delete + client.delete(node_template) + + node_template = client.reload(node_template) + assert node_template is None + + +def test_cloud_credential_delete(admin_mc, remove_resource): + """Test deleting a cloud credential that is referenced by nodeTemplate, which + is in use by nodePool + """ + client = admin_mc.client + node_template, cloud_credential = create_node_template(client) + node_pool = client.create_node_pool( + nodeTemplateId=node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + assert node_pool.nodeTemplateId == node_template.id + + wait_for_node_template(client, node_template.id) + + # Attempting to delete the template should raise an ApiError + with pytest.raises(ApiError) as e: + client.delete(cloud_credential) + assert e.value.error.status == 405 + + +@pytest.mark.skip +def test_writing_config_to_disk(admin_mc, wait_remove_resource): + """Test that userdata and other fields from node driver configs are being + written to disk as expected. + """ + client = admin_mc.client + tempdir = tempfile.gettempdir() + cloud_credential = client.create_cloud_credential( + digitaloceancredentialConfig={"accessToken": "test"}) + wait_remove_resource(cloud_credential) + + data = {'userdata': 'do cool stuff' + random_str() + '\n', + # This validates ssh keys don't drop the ending \n + 'id_rsa': 'some\nfake\nstuff\n' + random_str() + '\n' + } + + def _node_template(): + try: + return client.create_node_template( + digitaloceanConfig={ + 'userdata': data['userdata'], + 'sshKeyContents': data['id_rsa'] + }, + name=random_str(), + cloudCredentialId=cloud_credential.id) + + except ApiError: + return False + + node_template = wait_for(_node_template, + fail_handler=lambda: + 'failed to create node template') + wait_remove_resource(node_template) + + node_pool = client.create_node_pool( + nodeTemplateId=node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + + def node_available(): + node = client.list_node(nodePoolId=node_pool.id) + if len(node.data): + return node.data[0] + return None + + node = wait_for(node_available) + wait_for_condition("Saved", "False", client, node) + wait_remove_resource(node_pool) + + for key, value in data.items(): + dir_name = string_to_encoding(value) + + full_path = os.path.join(tempdir, dir_name, key) + + def file_exists(): + try: + os.stat(full_path) + return True + except FileNotFoundError: + return False + + wait_for(file_exists, timeout=120, + fail_handler=lambda: 'file is missing from disk') + + with open(full_path, 'r') as f: + contents = f.read() + + assert contents == value + + +def test_node_driver_schema(admin_mc): + """Test node driver schemas have path fields removed.""" + drivers = ['amazonec2config', 'digitaloceanconfig', 'azureconfig'] + bad_fields = ['sshKeypath', 'sshKeyPath', 'existingKeyPath'] + client = admin_mc.client + for driver in drivers: + schema = client.schema.types[driver] + for field in bad_fields: + assert field not in schema.resourceFields, \ + 'Driver {} has field {}'.format(driver, field) + + +def test_amazon_node_driver_schema(admin_mc): + """Test amazon node driver schema supports AWS-specific resource fields""" + required_fields = ['encryptEbsVolume'] + client = admin_mc.client + schema = client.schema.types['amazonec2config'] + for field in required_fields: + assert field in schema.resourceFields, \ + 'amazonec2config missing support for field {}'.format(field) + + +def create_node_template(client, clientId="test"): + cloud_credential = client.create_cloud_credential( + azurecredentialConfig={"clientId": clientId, + "subscriptionId": "test", + "clientSecret": "test"}) + wait_for_cloud_credential(client, cloud_credential.id) + node_template = client.create_node_template( + azureConfig={}, + cloudCredentialId=cloud_credential.id) + assert node_template.cloudCredentialId == cloud_credential.id + return node_template, cloud_credential + + +def wait_for_cloud_credential(client, cloud_credential_id, timeout=60): + start = time.time() + interval = 0.5 + creds = client.list_cloud_credential() + cred = None + for val in creds: + if val["id"] == cloud_credential_id: + cred = val + while cred is None: + if time.time() - start > timeout: + print(cred) + raise Exception('Timeout waiting for cloud credential') + time.sleep(interval) + interval *= 2 + creds = client.list_cloud_credential() + for val in creds: + if val["id"] == cloud_credential_id: + cred = val + return cred + + +def wait_for_node_template(client, node_template_id, timeout=60): + start = time.time() + interval = 0.5 + template = None + while template is None: + if time.time() - start > timeout: + raise Exception('Timeout waiting for node template lister') + time.sleep(interval) + interval *= 2 + nodeTemplates = client.list_node_template() + for each_template in nodeTemplates: + if each_template["id"] == node_template_id: + template = each_template + + +def test_user_access_to_other_template(user_factory, remove_resource): + """Asserts that a normal user's nodepool cannot reference another user's + nodetemplate""" + user1_client = user_factory().client + user2_client = user_factory().client + + user2_node_template = user2_client.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_resource(user2_node_template) + wait_for_node_template(user2_client, user2_node_template.id) + + with pytest.raises(ApiError) as e: + user1_client.create_node_pool( + nodeTemplateId=user2_node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + assert e.value.error.status == 404 + assert e.value.error.message == \ + "unable to find node template [%s]" % user2_node_template.id + + +@pytest.mark.skip(reason="flaky, todo in 27885") +def test_user_cluster_owner_access_to_pool(admin_mc, + user_factory, + remove_resource, + wait_remove_resource): + """Test that a cluster created by the admin is accessible by another user + added as a cluster-owner, validate nodepool changing and switching + nodetemplate""" + + # make an admin and user client + admin_client = admin_mc.client + k8sclient = CoreV1Api(admin_mc.k8s_client) + user = user_factory() + + # make a cluster + cluster = admin_client.create_cluster( + name=random_str(), + rancherKubernetesEngineConfig={ + "accessKey": "junk" + } + ) + remove_resource(cluster) + + # wait for the namespace created by the cluster + def _check_namespace(cluster): + for n in k8sclient.list_namespace().items: + if n.metadata.name == cluster.id: + return True + return False + + wait_for(lambda: _check_namespace(cluster)) + + # add user as cluster-owner to the cluster + crtb = admin_client.create_cluster_role_template_binding( + userId=user.user.id, + roleTemplateId="cluster-owner", + clusterId=cluster.id, + ) + remove_resource(crtb) + + # admin creates a node template and assigns to a pool + admin_node_template, admin_cloud_credential = create_node_template( + admin_client, "admincloudcred-" + random_str()) + admin_pool = admin_client.create_node_pool( + nodeTemplateId=admin_node_template.id, + hostnamePrefix=random_str(), + clusterId=cluster.id) + wait_remove_resource(admin_pool) + remove_resource(admin_cloud_credential) + remove_resource(admin_node_template) + + # create a template for the user to try and assign + user_node_template, user_cloud_credential = create_node_template( + user.client, "usercloudcred-" + random_str()) + remove_resource(user_cloud_credential) + remove_resource(user_node_template) + + # will pass, cluster owner user can change pool quantity + user.client.update(admin_pool, quantity=2) + # will pass, can set to a template owned by the user + user.client.update(admin_pool, nodeTemplateId=user_node_template.id) + + # will fail, can not update nodepool template, + # if no access to the original template + with pytest.raises(ApiError) as e: + user.client.update(admin_pool, nodeTemplateId=admin_node_template.id) + assert e.value.error.status == 404 + assert e.value.error.message == "unable to find node template [%s]" % \ + admin_node_template.id + + # delete this by hand and the rest will cleanup + admin_client.delete(admin_pool) + + +def test_admin_access_to_node_template(admin_mc, list_remove_resource): + """Asserts that an admin user's nodepool can reference + nodetemplates they have created""" + admin_client = admin_mc.client + + admin_node_template = admin_client.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_list = [admin_node_template] + list_remove_resource(remove_list) + + # Admin has access to create nodepool and nodepool create only happens + # after it passes validation. + node_pool = admin_client.create_node_pool( + nodeTemplateId=admin_node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + + remove_list.insert(0, node_pool) + + +def test_user_access_to_node_template(user_mc, remove_resource): + """Asserts that a normal user's nodepool can reference + nodetemplates they have created""" + user_client = user_mc.client + + user_node_template = user_client.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_resource(user_node_template) + wait_for_node_template(user_client, user_node_template.id) + + with pytest.raises(ApiError) as e: + user_client.create_node_pool( + nodeTemplateId=user_node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + # User does not have access to create nodepools but has + # access to nodetemplate. Nodepool create happens after + # validation has passed. + assert e.value.error.status == 403 + assert 'cannot create resource "nodepools"' in e.value.error.message + + +def test_admin_access_user_template(admin_mc, user_mc, list_remove_resource): + """Asserts that an admin user's nodepool can reference another user's + nodetemplates""" + admin_client = admin_mc.client + user_client = user_mc.client + + user_node_template = user_client.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_list = [user_node_template] + list_remove_resource(remove_list) + # Admin has access to create nodepool and nodepool create only happens + # after it passes validation. + node_pool = admin_client.create_node_pool( + nodeTemplateId=user_node_template.id, + hostnamePrefix=random_str(), + clusterId="local") + remove_list.insert(0, node_pool) + + +def test_no_node_template(user_mc): + """Asserts that a nodepool cannot create without a valid + nodetemplate""" + user_client = user_mc.client + + invalid_template_id = "thisinsnotatemplateid" + + with pytest.raises(ApiError) as e: + user_client.create_node_pool( + nodeTemplateId=invalid_template_id, + hostnamePrefix=random_str(), + clusterId="local") + assert e.value.error.status == 404 + assert e.value.error.message == \ + "unable to find node template [%s]" % invalid_template_id diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node_templates.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node_templates.py new file mode 100644 index 0000000..601d74c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_node_templates.py @@ -0,0 +1,181 @@ +import pytest +import time + +from .common import random_str +from .conftest import wait_for +from rancher import ApiError +from rancher import RestObject +from kubernetes.client import CustomObjectsApi +from kubernetes.client.rest import ApiException + + +def test_legacy_template_migrate_and_delete(admin_mc, admin_cc, + remove_resource, user_mc, + raw_remove_custom_resource): + """Asserts that any node template not in cattle-global-nt namespace is + duplicated into cattle-global-nt, then deleted. Also, asserts that + operations on legacy node templates are forwarded to corresponding + migrated node templates""" + admin_client = admin_mc.client + admin_cc_client = admin_cc.client + user_client = user_mc.client + + k8s_dynamic_client = CustomObjectsApi(admin_mc.k8s_client) + + ns = admin_cc_client.create_namespace(name="ns-" + random_str(), + clusterId=admin_cc.cluster.id) + remove_resource(ns) + + node_template_name = "nt-" + random_str() + body = { + "metadata": { + "name": node_template_name, + "annotations": { + "field.cattle.io/creatorId": user_mc.user.id + } + }, + "kind": "NodeTemplate", + "apiVersion": "management.cattle.io/v3", + "azureConfig": {"customData": "asdfsadfsd"} + } + + # create a node template that will be recognized as legacy + dynamic_nt = k8s_dynamic_client.create_namespaced_custom_object( + "management.cattle.io", "v3", ns.name, 'nodetemplates', body) + raw_remove_custom_resource(dynamic_nt) + + def migrated_template_exists(id): + try: + nt = user_client.by_id_node_template(id=id) + remove_resource(nt) + return nt + except ApiError as e: + assert e.error.status == 403 + return False + id = "cattle-global-nt:nt-" + ns.id + "-" + dynamic_nt["metadata"]["name"] + legacy_id = dynamic_nt["metadata"]["name"] + legacy_ns = dynamic_nt["metadata"]["namespace"] + full_legacy_id = legacy_ns + ":" + legacy_id + + # wait for node template to be migrated + nt = wait_for(lambda: migrated_template_exists(id), fail_handler=lambda: + "failed waiting for node template to migrate") + + # assert that config has not been removed from node template + assert nt.azureConfig["customData"] ==\ + dynamic_nt["azureConfig"]["customData"] + + def legacy_template_deleted(): + try: + k8s_dynamic_client.get_namespaced_custom_object( + "management.cattle.io", "v3", ns.name, 'nodetemplates', + legacy_id) + return False + except ApiException as e: + return e.status == 404 + + # wait for legacy node template to be deleted + wait_for(lambda: legacy_template_deleted(), fail_handler=lambda: + "failed waiting for old node template to delete") + + # retrieve node template via legacy id + nt = admin_client.by_id_node_template(id=full_legacy_id) + # retrieve node template via migrated id + migrated_nt = admin_client.by_id_node_template(id=id) + + def compare(d1, d2): + if d1 == d2: + return True + if d1.keys() != d2.keys(): + return False + for key in d1.keys(): + if key in ["id", "namespace", "links", "annotations"]: + continue + if d1[key] == d2[key]: + continue + if callable(d1[key]): + continue + if isinstance(d1[key], RestObject): + if compare(d1[key], d1[key]): + continue + return False + return True + + # ensure templates returned are identical aside from fields containing + # id/ns + if not compare(nt, migrated_nt): + raise Exception("forwarded does not match migrated nodetemplate") + + nt.azureConfig.customData = "asdfasdf" + new_config = nt.azureConfig + new_config.customData = "adsfasdfadsf" + + # update node template via legacy id + nt = admin_client.update_by_id_node_template( + id=full_legacy_id, + azureConfig=new_config) + + # assert node template is being updated + assert nt.azureConfig.customData == new_config.customData + nt2 = admin_client.by_id_node_template(id=id) + # assert node template being updated is migrated node template + assert nt2.azureConfig.customData == new_config.customData + + # delete node template via legacy id + admin_client.delete(nt) + wait_for(lambda: admin_client.by_id_node_template(id) is None, + fail_handler=lambda: + "failed waiting for migrate node template to delete") + + +def test_node_template_namespace(admin_mc, remove_resource): + """asserts that node template is automatically created in + 'cattle-global-nt' namespace""" + admin_client = admin_mc.client + + node_template = admin_client.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_resource(node_template) + assert node_template.id.startswith("cattle-global-nt") + + +def test_user_can_only_view_own_template(user_factory, remove_resource): + """Asserts that user can view template after they have created it""" + user_client1 = user_factory().client + user_client2 = user_factory().client + + node_template = user_client1.create_node_template(name="nt-" + + random_str(), + azureConfig={}) + remove_resource(node_template) + + def can_view_template(): + try: + return user_client1.by_id_node_template(id=node_template.id) + except ApiError as e: + assert e.error.status == 403 + return None + + wait_for(can_view_template, fail_handler=lambda: + "creator was unable to view node template") + + # assert user cannot view template created by another user + ensure_user_cannot_view_template(user_client2, node_template.id) + + +def ensure_user_cannot_view_template(client, nodeTemplateId, timeout=5): + """Asserts user is unable to view node template associated with given node + template id""" + can_view = False + start = time.time() + interval = 0.2 + while not can_view: + if time.time() - start > timeout: + return + with pytest.raises(ApiError) as e: + client.by_id_node_template(nodeTemplateId) + + assert e.value.error.status == 403 + time.sleep(interval) + interval *= 2 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_password_store.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_password_store.py new file mode 100644 index 0000000..96f0709 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_password_store.py @@ -0,0 +1,123 @@ +from kubernetes.client import CustomObjectsApi +from kubernetes.client import CoreV1Api +from kubernetes.client.rest import ApiException +from .common import random_str +import base64 + +group = 'management.cattle.io' +version = 'v3' +namespace = 'local' +plural = 'clusterloggings' +clusterId = "local" +globalNS = "cattle-global-data" + + +def verifyPassword(crdClient, k8sclient, ns, name, secretPassword): + k8es = crdClient.get_namespaced_custom_object( + group, version, namespace, plural, name) + + secretName = k8es['spec']['elasticsearchConfig']['authPassword'] + ns, name = secretName.split(":") + assert ns is not None + assert name is not None + + secret = k8sclient.read_namespaced_secret(name, ns) + assert base64.b64decode(secret.data[name]).\ + decode("utf-8") == secretPassword + + +def verifyPasswords(crdClient, k8sclient, ns, name, fluentdServers): + k8fs = crdClient.get_namespaced_custom_object( + group, version, namespace, plural, name) + servers = k8fs['spec']['fluentForwarderConfig']['fluentServers'] + + for ind, server in enumerate(fluentdServers): + secretName = servers[ind]['password'] + ns, name = secretName.split(":") + assert ns is not None + assert name is not None + + secret = k8sclient.read_namespaced_secret(name, ns) + assert base64.b64decode(secret.data[name]).\ + decode("utf-8") == server['password'] + + +def checkSecret(crdClient, k8sclient, ns, name, es, client, func): + k8es = crdClient.get_namespaced_custom_object( + group, version, namespace, plural, name) + secretName = k8es['spec']['elasticsearchConfig']['authPassword'] + ns, name = secretName.split(":") + + func(client, es) + + try: + k8sclient.read_namespaced_secret(name, ns) + except ApiException as e: + assert e.status == 404 + + +def checkSecrets(crdClient, k8sclient, ns, name, fs, client, func): + k8fs = crdClient.get_namespaced_custom_object( + group, version, namespace, plural, name) + servers = k8fs['spec']['fluentForwarderConfig']['fluentServers'] + + secretNames = [] + for ind, server in enumerate(servers): + secretName = server['password'] + ns, name = secretName.split(":") + secretNames.append(name) + + func(client, fs) + + for secretName in secretNames: + try: + k8sclient.read_namespaced_secret(name, globalNS) + except ApiException as e: + assert e.status == 404 + + +def getClients(admin_mc): + return CustomObjectsApi(admin_mc.k8s_client), \ + CoreV1Api(admin_mc.k8s_client) + + +def upFuncFluentd(client, fs): + try: + fs = client.update(fs, fluentForwarderConfig=None) + except ApiException as e: + assert e is None + + +def upFuncElastic(client, es): + try: + es = client.update(es, elasticsearchConfig=None) + except ApiException as e: + assert e is None + + +def deleteFunc(client, obj): + client.delete(obj) + + +def getFluentdServers(): + return [{ + "endpoint": "192.168.1.10:87", + "standby": False, + "username": random_str(), + "weight": 100, + "password": random_str() + }, + { + "endpoint": "192.168.1.10:89", + "standby": False, + "username": random_str(), + "weight": 100, + "password": random_str() + }, + { + "endpoint": "192.168.2.10:86", + "standby": False, + "username": random_str(), + "weight": 100, + "password": random_str() + }] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume.py new file mode 100644 index 0000000..674f75b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume.py @@ -0,0 +1,26 @@ +from .common import random_str + + +def test_persistent_volume_update(admin_cc, remove_resource): + client = admin_cc.client + name = random_str() + pv = client.create_persistent_volume( + clusterId="local", + name=name, + accessModes=["ReadWriteOnce"], + capacity={"storage": "10Gi"}, + cinder={"readOnly": "false", + "secretRef": {"name": "fss", + "namespace": "fsf"}, + "volumeID": "fss", + "fsType": "fss"}) + remove_resource(pv) + assert pv is not None + # fields shouldn't get updated + toUpdate = {"readOnly": "true"} + pv = client.update(pv, cinder=toUpdate) + assert (pv["cinder"]["readOnly"]) is False + # persistentVolumeSource type cannot be changed + pv = client.update(pv, azureFile={"readOnly": "true", + "shareName": "abc"}, cinder={}) + assert "azureFile" not in pv diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume_claim.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume_claim.py new file mode 100644 index 0000000..7f26f14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_persistent_volume_claim.py @@ -0,0 +1,129 @@ +import pytest +import kubernetes +from .conftest import random_str, kubernetes_api_client +from rancher import ApiError + + +def test_cannot_create_azure_no_accountstoragetype(admin_pc, admin_cc, + admin_mc, remove_resource): + """Tests that a PVC referencing a storage class with empty skuName and + storageaccounttype fields fails to create + """ + client = admin_pc.client + # using k8s_client is required since rancher client will automatically + # set default if sc has no storageaccounttype/skuName + k8s_client = kubernetes_api_client(admin_mc.client, admin_cc.cluster.id) + storage_client = kubernetes.client.StorageV1Api(api_client=k8s_client) + + ns = admin_pc.cluster.client.create_namespace( + name="ns" + random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + + sc = storage_client.create_storage_class( + body={ + "metadata": { + "name": "sc" + random_str() + }, + "parameters": { + "kind": "shared" + }, + "provisioner": "kubernetes.io/azure-disk"}) + remove_resource(sc) + + with pytest.raises(ApiError) as e: + client.create_persistent_volume_claim( + name="pc" + random_str(), + storageClassId=sc.metadata.name, + namespaceId=ns.id, + accessModes=["ReadWriteOnce"], + resources={ + "requests": { + "storage": "30Gi" + } + }) + assert e.value.error.status == 422 + assert "must provide storageaccounttype or skuName" in \ + e.value.error.message + + +def test_can_create_azure_any_accountstoragetype(admin_pc, admin_cc, + remove_resource): + """Tests that a PVC referencing a storage class with any non-empty skuName or + storageaccounttype field successfully creates + """ + cc_client = admin_cc.client + pc_client = admin_pc.client + + ns = cc_client.create_namespace( + name="ns" + random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + + # try with storageaccounttype value + sc1 = cc_client.create_storage_class( + name="sc" + random_str(), + provisioner="kubernetes.io/azure-disk", + kind="shared", + parameters={ + "storageaccounttype": "asdf", + }, + ) + remove_resource(sc1) + + pvc1 = pc_client.create_persistent_volume_claim( + name="pc" + random_str(), + storageClassId=sc1.name, + namespaceId=ns.id, + accessModes=["ReadWriteOnce"], + resources={ + "requests": { + "storage": "30Gi" + } + }) + remove_resource(pvc1) + + # try with skuName value + sc2 = cc_client.create_storage_class( + name="sc" + random_str(), + provisioner="kubernetes.io/azure-disk", + parameters={ + "skuName": "asdf", + }, + ) + remove_resource(sc2) + + pvc2 = pc_client.create_persistent_volume_claim( + name="pc" + random_str(), + storageClassId=sc2.name, + namespaceId=ns.id, + accessModes=["ReadWriteOnce"], + resources={ + "requests": { + "storage": "30Gi" + } + }) + remove_resource(pvc2) + + +def test_can_create_pvc_no_storage_no_vol(admin_pc, remove_resource): + """Tests that a PVC referencing no storage class and no volume + can be created + """ + ns = admin_pc.cluster.client.create_namespace( + name="ns" + random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + + pvc = admin_pc.client.create_persistent_volume_claim( + name="pc" + random_str(), + namespaceId=ns.id, + accessModes=["ReadWriteOnce"], + resources={ + "requests": { + "storage": "30Gi" + } + }) + remove_resource(pvc) + assert pvc is not None + assert pvc.state == "pending" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_pod_security_policies.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_pod_security_policies.py new file mode 100644 index 0000000..8299f63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_pod_security_policies.py @@ -0,0 +1,365 @@ +import kubernetes +from .conftest import kubernetes_api_client, wait_for, set_cluster_psp +from .common import random_str +from rancher import ApiError +import pytest +from kubernetes.client.rest import ApiException + + +def cleanup_pspt(client, request, cluster): + def remove_pspt_from_cluster_and_delete(cluster): + pspt_id = cluster.defaultPodSecurityPolicyTemplateId + pspt = client.by_id_pod_security_policy_template(pspt_id) + cluster.defaultPodSecurityPolicyTemplateId = "" + client.update_by_id_cluster(cluster.id, cluster) + client.delete(pspt) + + request.addfinalizer( + lambda: remove_pspt_from_cluster_and_delete(cluster) + ) + + +@pytest.fixture(scope='module') +def check_cluster_kubernetes_version(admin_mc): + """ + Checks the local cluster's k8s version + """ + client = admin_mc.client + cluster = client.by_id_cluster("local") + version = cluster.get("version") + if version is not None: + k8s_version = int(version.get("gitVersion")[3:5]) + if k8s_version >= 25: + pytest.skip("Needs to be reworked for PSA") + + +def create_pspt(client): + """ Creates a minimally valid pspt with cleanup left to caller""" + runas = {"rule": "RunAsAny"} + selinx = {"rule": "RunAsAny"} + supgrp = {"ranges": [{"max": 65535, "min": 1}], + "rule": "MustRunAs" + } + fsgrp = {"ranges": [{"max": 65535, "min": 1, }], + "rule": "MustRunAs", + } + pspt = \ + client.create_pod_security_policy_template(name="test" + random_str(), + description="Test PSPT", + privileged=False, + seLinux=selinx, + supplementalGroups=supgrp, + runAsUser=runas, + fsGroup=fsgrp, + volumes='*' + ) + return pspt + + +def setup_cluster_with_pspt(client, request): + """ + Sets the 'local' cluster to mock a PSP by applying a minimally valid + restricted type PSPT + """ + pspt = create_pspt(client) + pspt_id = pspt.id + + # this won't enforce pod security policies on the local cluster but it + # will let us test that the role bindings are being created correctly + cluster = client.by_id_cluster("local") + setattr(cluster, "defaultPodSecurityPolicyTemplateId", pspt_id) + client.update_by_id_cluster("local", cluster) + cleanup_pspt(client, request, cluster) + + return pspt + + +def service_account_has_role_binding(rbac, pspt): + try: + rbac.read_namespaced_role_binding("default-asdf-default-" + pspt.id + + "-clusterrole-binding", "default") + return True + except ApiException: + return False + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_service_accounts_have_role_binding(admin_mc, request): + api_client = admin_mc.client + pspt = setup_cluster_with_pspt(api_client, request) + + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + core = kubernetes.client.CoreV1Api(api_client=k8s_client) + rbac = kubernetes.client.RbacAuthorizationV1Api(api_client=k8s_client) + + service_account = kubernetes.client.V1ServiceAccount() + service_account.metadata = kubernetes.client.V1ObjectMeta() + service_account.metadata.name = "asdf" + + core.create_namespaced_service_account("default", service_account) + request.addfinalizer(lambda: core.delete_namespaced_service_account( + "asdf", "default")) + request.addfinalizer( + lambda: rbac.delete_namespaced_role_binding( + "default-asdf-default-" + pspt.id + "-clusterrole-binding", + "default")) + + wait_for(lambda: service_account_has_role_binding(rbac, pspt), timeout=30) + + +@pytest.mark.nonparallel +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_pod_security_policy_template_del(admin_mc, admin_pc, remove_resource, + restore_cluster_psp): + """ Test for pod security policy template binding correctly. + May have to mark this test as nonparallel if new test are introduced + that toggle pspEnabled. + ref https://github.com/rancher/rancher/issues/15728 + ref https://localhost:8443/v3/podsecuritypolicytemplates + """ + api_client = admin_mc.client + pspt_proj = create_pspt(api_client) + # add a finalizer to delete the pspt + remove_resource(pspt_proj) + + # creates a project and handles cleanup + proj = admin_pc.project + # this will retry 3 times if there is an ApiError + + set_cluster_psp(admin_mc, "false") + + with pytest.raises(ApiError) as e: + api_client.action(obj=proj, + action_name="setpodsecuritypolicytemplate", + podSecurityPolicyTemplateId=pspt_proj.id) + assert e.value.error.status == 422 + assert "cluster [local] does not have Pod Security Policies enabled" in \ + e.value.error.message + + set_cluster_psp(admin_mc, "true") + + api_client.action(obj=proj, action_name="setpodsecuritypolicytemplate", + podSecurityPolicyTemplateId=pspt_proj.id) + proj = api_client.wait_success(proj) + + # Check that project was created successfully with pspt + assert proj.state == 'active' + assert proj.podSecurityPolicyTemplateId == pspt_proj.id + + def check_psptpb(): + proj_obj = proj.podSecurityPolicyTemplateProjectBindings() + for data in proj_obj.data: + if (data.targetProjectId == proj.id and + data.podSecurityPolicyTemplateId == pspt_proj.id): + return True + + return False + + wait_for(check_psptpb, lambda: "PSPTB project binding not found") + # allow for binding deletion + api_client.delete(proj) + + def check_project(): + return api_client.by_id_project(proj.id) is None + + wait_for(check_project) + # delete the PSPT that was associated with the deleted project + api_client.delete(pspt_proj) + + def pspt_del_check(): + if api_client.by_id_pod_security_policy_template(pspt_proj.id) is None: + return True + else: # keep checking to see delete occurred + return False + + # will timeout if pspt is not deleted + wait_for(pspt_del_check) + assert api_client.by_id_pod_security_policy_template(pspt_proj.id) is None + + set_cluster_psp(admin_mc, "false") + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_incorrect_pspt(admin_mc, remove_resource): + """ Test that incorrect pod security policy templates cannot be created""" + api_client = admin_mc.client + + name = "pspt" + random_str() + with pytest.raises(ApiError) as e: + api_client.create_podSecurityPolicyTemplate(name=name) + assert e.value.error.status == 422 + + name = "pspt" + random_str() + with pytest.raises(ApiError) as e: + args = {'name': name, + 'description': 'Test PSPT', + 'fsGroup': {"rule": "RunAsAny"}, + 'runAsUser': {"rule": "RunAsAny"}, + 'seLinux': {"rule": "RunAsAny"}, + 'supplementalGroups': {"rule": "RunAsAny"}, + 'allowPrivilegeEscalation': False, + 'defaultAllowPrivilegeEscalation': True} + # Should not set the default True if allowPrivilegedEscalation is false + api_client.create_podSecurityPolicyTemplate(**args) + assert e.value.error.status == 422 + assert e.value.error.code == 'InvalidBodyContent' + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_pspt_binding(admin_mc, admin_pc, remove_resource): + """Test that a PSPT binding is validated before creating it""" + api_client = admin_mc.client + + # No podSecurityPolicyTemplateId causes a 422 + name = random_str() + with pytest.raises(ApiError) as e: + b = api_client.create_podSecurityPolicyTemplateProjectBinding( + name=name, + namespaceId='default', + podSecurityPolicyTemplateId=None, + targetProjectId=admin_pc.project.id, + ) + remove_resource(b) + assert e.value.error.status == 422 + assert e.value.error.message == \ + 'missing required podSecurityPolicyTemplateId' + + # An invalid podSecurityPolicyTemplateId causes a 422 + name = random_str() + with pytest.raises(ApiError) as e: + b = api_client.create_podSecurityPolicyTemplateProjectBinding( + name=name, + namespaceId='default', + podSecurityPolicyTemplateId='thisdoesntexist', + targetProjectId=admin_pc.project.id, + ) + remove_resource(b) + assert e.value.error.status == 422 + assert e.value.error.message == 'podSecurityPolicyTemplate not found' + + +@pytest.mark.nonparallel +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_project_action_set_pspt(admin_mc, admin_pc, + remove_resource, restore_cluster_psp): + """Test project's action: setpodsecuritypolicytemplate""" + api_client = admin_mc.client + + # these create a mock pspt + pspt_proj = create_pspt(api_client) + # add a finalizer to delete the pspt + remove_resource(pspt_proj) + # creates a project + proj = admin_pc.project + + set_cluster_psp(admin_mc, "false") + + # Check 1: the action should error out if psp is disabled at cluster level + with pytest.raises(ApiError) as e: + api_client.action(obj=proj, + action_name="setpodsecuritypolicytemplate", + podSecurityPolicyTemplateId=pspt_proj.id) + assert e.value.error.status == 422 + assert "cluster [local] does not have Pod Security Policies enabled" in \ + e.value.error.message + + set_cluster_psp(admin_mc, "true") + + # Check 2: the action should succeed if psp is enabled at cluster level + # and podSecurityPolicyTemplateId is valid + api_client.action(obj=proj, + action_name="setpodsecuritypolicytemplate", + podSecurityPolicyTemplateId=pspt_proj.id) + proj = api_client.wait_success(proj) + assert proj.state == 'active' + assert proj.podSecurityPolicyTemplateId == pspt_proj.id + + def check_psptpb(): + proj_obj = proj.podSecurityPolicyTemplateProjectBindings() + for data in proj_obj.data: + if (data.targetProjectId == proj.id and + data.podSecurityPolicyTemplateId == pspt_proj.id): + return True + return False + + wait_for(check_psptpb, lambda: "PSPTB project binding not found") + + # Check 3: an invalid podSecurityPolicyTemplateId causes 422 + with pytest.raises(ApiError) as e: + api_client.action(obj=proj, + action_name="setpodsecuritypolicytemplate", + podSecurityPolicyTemplateId="doNotExist") + assert e.value.error.status == 422 + assert "podSecurityPolicyTemplate [doNotExist] not found" in \ + e.value.error.message + + api_client.delete(proj) + + def check_project(): + return api_client.by_id_project(proj.id) is None + wait_for(check_project) + + set_cluster_psp(admin_mc, "false") + + +@pytest.mark.usefixtures('check_cluster_kubernetes_version') +def test_psp_annotations(admin_mc, remove_resouce_func): + """Test that a psp with a pspt owner annotation will get cleaned up if the + parent pspt does not exist""" + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + policy = kubernetes.client.PolicyV1beta1Api(api_client=k8s_client) + kubernetes.client.PolicyV1beta1PodSecurityPolicy + psp_name = random_str() + args = { + 'metadata': { + 'name': psp_name + }, + 'spec': { + "allowPrivilegeEscalation": True, + "fsGroup": { + "rule": "RunAsAny" + }, + "runAsUser": { + "rule": "RunAsAny" + }, + "seLinux": { + "rule": "RunAsAny" + }, + "supplementalGroups": { + "rule": "RunAsAny" + }, + "volumes": [ + "*" + ] + } + } + + psp = policy.create_pod_security_policy(args) + remove_resouce_func(policy.delete_pod_security_policy, psp_name) + psp = policy.read_pod_security_policy(psp_name) + assert psp is not None + + anno = { + 'metadata': { + 'annotations': { + 'serviceaccount.cluster.cattle.io/pod-security': 'doesntexist' + } + } + } + # Add the annotation the controller is looking for + psp = policy.patch_pod_security_policy(psp_name, anno) + + # Controller will delete the PSP as the parent PSPT doesn't exist + def _get_psp(): + try: + policy.read_pod_security_policy(psp_name) + return False + except ApiException as e: + if e.status != 404: + raise e + return True + wait_for(_get_psp, fail_handler=lambda: "psp was not cleaned up") + + with pytest.raises(ApiException) as e: + policy.read_pod_security_policy(psp_name) + assert e.value.status == 404 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_catalog.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_catalog.py new file mode 100644 index 0000000..b89acbc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_catalog.py @@ -0,0 +1,314 @@ +from .conftest import wait_until, wait_until_available, wait_for_condition,\ + user_project_client +from rancher import ApiError +from .common import random_str +import time + + +def test_project_catalog_creation(admin_mc, remove_resource, + user_mc, user_factory, admin_pc, + admin_cc): + client = admin_mc.client + + # When project-owner tries to create project catalog, it should succeed + prtb_owner = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-owner", + userId=admin_mc.user.id,) + remove_resource(prtb_owner) + + wait_until(prtb_cb(client, prtb_owner)) + + project_owner_client = client + name = random_str() + project_name = str.lstrip(admin_pc.project.id, "local:") + catalog_name = project_name + ":" + name + url = "https://github.com/mrajashree/charts.git" + + project = admin_pc.project + project_catalog = \ + project_owner_client.create_project_catalog(name=name, + branch="onlyOne", + url=url, + projectId=project.id, + ) + wait_for_projectcatalog_template_to_be_created(project_owner_client, + catalog_name) + + # The project-owner should now be able to access the project level + # catalog and its templates + cc = project_owner_client.list_project_catalog(name=name) + assert len(cc) == 1 + templates = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templateversions) == 1 + + # Now add a user as project-member to this project + prtb_member = client.create_project_role_template_binding( + projectId=project.id, + roleTemplateId="project-member", + userId=user_mc.user.id,) + remove_resource(prtb_member) + + wait_until_available(user_mc.client, admin_cc.cluster) + wait_until(prtb_cb(client, prtb_member)) + + project_member_client = user_mc.client + # The project-member should now be able to access the project level + # catalog and its templates + cc = project_member_client.list_project_catalog() + assert len(cc) == 1 + templates = \ + project_member_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + project_member_client.list_template(projectCatalogId=catalog_name) + assert len(templateversions) == 1 + + # But project-member should not be able to create a project catalog + try: + project_member_client.create_project_catalog(name=random_str(), + branch="onlyOne", + url=url, + projectId=project.id, + ) + except ApiError as e: + assert e.error.status == 403 + + # Create another user and don't add to project, this user should not + # be able to access this cluster catalog or its templates + user2 = user_factory() + templates = \ + user2.client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 0 + cc = user2.client.list_cluster_catalog(name=name) + assert len(cc) == 0 + + client.delete(project_catalog) + wait_for_projectcatalog_template_to_be_deleted(client, catalog_name) + + +def test_create_project_catalog_after_user_addition(admin_mc, + user_factory, + remove_resource, + admin_pc): + # Create a new user + user1 = user_factory() + remove_resource(user1) + client = admin_mc.client + project = admin_pc.project + # Add this user as project-member + prtb_member = client.create_project_role_template_binding( + projectId=project.id, + roleTemplateId="project-member", + userId=user1.user.id) + remove_resource(prtb_member) + + wait_until(prtb_cb(client, prtb_member)) + + # Create project-level catalog for this project as admin + name = random_str() + project_name = str.lstrip(admin_pc.project.id, "local:") + catalog_name = project_name + ":" + name + url = "https://github.com/mrajashree/charts.git" + + project = admin_pc.project + project_owner_client = client + project_catalog = \ + project_owner_client.create_project_catalog(name=name, + branch="onlyOne", + url=url, + projectId=project.id, + ) + wait_for_projectcatalog_template_to_be_created(project_owner_client, + catalog_name) + + # The project-owner should now be able to access the project level + # catalog and its templates + cc = project_owner_client.list_project_catalog(name=name) + assert len(cc) == 1 + templates = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templateversions) == 1 + + project_member_client = user1.client + # The project-member should now be able to access the project level + # catalog and its templates + cc = project_member_client.list_project_catalog() + assert len(cc) == 1 + templates = \ + project_member_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + + client.delete(project_catalog) + wait_for_projectcatalog_template_to_be_deleted(client, catalog_name) + + +def test_user_addition_after_creating_project_catalog(admin_mc, + user_factory, + remove_resource, + admin_pc): + # Create project-level catalog for this project as admin + client = admin_mc.client + name = random_str() + project_name = str.lstrip(admin_pc.project.id, "local:") + catalog_name = project_name + ":" + name + url = "https://github.com/mrajashree/charts.git" + + project = admin_pc.project + project_owner_client = client + project_catalog = \ + project_owner_client.create_project_catalog(name=name, + branch="onlyOne", + url=url, + projectId=project.id, + ) + wait_for_projectcatalog_template_to_be_created(project_owner_client, + catalog_name) + + # The project-owner should now be able to access the project level + # catalog and its templates + cc = project_owner_client.list_project_catalog(name=name) + assert len(cc) == 1 + templates = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + templateverions = \ + project_owner_client.list_template(projectCatalogId=catalog_name) + assert len(templateverions) == 1 + + # Create a new user + user1 = user_factory() + remove_resource(user1) + project = admin_pc.project + # Add this user as project-member + prtb_member = client.create_project_role_template_binding( + projectId=project.id, + roleTemplateId="project-member", + userId=user1.user.id) + remove_resource(prtb_member) + + wait_until(prtb_cb(client, prtb_member)) + + project_member_client = user1.client + # The project-member should now be able to access the project level + # catalog and its templates + cc = project_member_client.list_project_catalog() + assert len(cc) == 1 + templates = \ + project_member_client.list_template(projectCatalogId=catalog_name) + assert len(templates) == 1 + templateversions = \ + project_member_client.list_template(projectCatalogId=catalog_name) + assert len(templateversions) == 1 + + client.delete(project_catalog) + wait_for_projectcatalog_template_to_be_deleted(client, catalog_name) + + +def test_project_catalog_access_before_app_creation(admin_mc, admin_pc, + remove_resource, + user_factory): + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + remove_resource(ns) + client = admin_mc.client + + name = random_str() + new_project = client.create_project(name=random_str(), clusterId='local') + remove_resource(new_project) + wait_for_condition('InitialRolesPopulated', 'True', client, new_project) + new_project = client.reload(new_project) + + project_name = str.lstrip(new_project.id, "local:") + catalog_name = project_name + ":" + name + url = "https://github.com/rancher/integration-test-charts.git" + + client.create_project_catalog(name=name, + branch="master", + url=url, + projectId=new_project.id, + ) + wait_for_projectcatalog_template_to_be_created(client, + catalog_name) + + external_id = "catalog://?catalog="+project_name+"/"+name + \ + "&type=projectCatalog&template=chartmuseum" \ + "&version=1.6.0" + + user = user_factory() + # Add this user as project-owner + prtb_owner = client.create_project_role_template_binding( + projectId=admin_pc.project.id, + roleTemplateId="project-owner", + userId=user.user.id) + remove_resource(prtb_owner) + wait_until(prtb_cb(client, prtb_owner)) + u_p_client = user_project_client(user, admin_pc.project) + try: + # creating app in user's project, using template version from + # new_project should not be allowed + u_p_client.create_app( + name=random_str(), + externalId=external_id, + targetNamespace=ns.name, + projectId=admin_pc.project.id, + ) + except ApiError as e: + assert e.error.status == 404 + assert "Cannot find template version" in e.error.message + + +def wait_for_projectcatalog_template_to_be_created(client, name, timeout=45): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(projectCatalogId=name) + if len(templates) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def wait_for_projectcatalog_template_to_be_deleted(client, name, timeout=45): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(projectCatalogId=name) + if len(templates) == 0: + found = True + time.sleep(interval) + interval *= 2 + + +def prtb_cb(client, prtb): + """Wait for the crtb to have the userId populated""" + def cb(): + p = client.reload(prtb) + return p.userPrincipalId is not None + return cb + + +def cr_rule_template(api_instance, cr_name, cr, resource): + def cb(): + c = api_instance.read_cluster_role(cr_name) + cr_rules = c.rules + for i in range(0, len(cr_rules)): + if cr_rules[i].resources[0] == resource: + return cr_rules[i].resource_names is not None + return cb diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_resource_quota.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_resource_quota.py new file mode 100644 index 0000000..acbadcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_resource_quota.py @@ -0,0 +1,484 @@ +import pytest +from .common import random_str +import time +from rancher import ApiError + + +def ns_default_quota(): + return {"limit": {"pods": "4"}} + + +def ns_quota(): + return {"limit": {"pods": "4"}} + + +def ns_small_quota(): + return {"limit": {"pods": "1"}} + + +def ns_large_quota(): + return {"limit": {"pods": "200"}} + + +def default_project_quota(): + return {"limit": {"pods": "100"}} + + +def ns_default_limit(): + return {"requestsCpu": "1", + "requestsMemory": "1Gi", + "limitsCpu": "2", + "limitsMemory": "2Gi"} + + +def wait_for_applied_quota_set(admin_cc_client, ns, timeout=30): + start = time.time() + ns = admin_cc_client.reload(ns) + a = ns.annotations["cattle.io/status"] + while a is None: + time.sleep(.5) + ns = admin_cc_client.reload(ns) + a = ns.annotations["cattle.io/status"] + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' resource quota to be validated') + + while "Validating resource quota" in a or "exceeds project limit" in a: + time.sleep(.5) + ns = admin_cc_client.reload(ns) + a = ns.annotations["cattle.io/status"] + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' resource quota to be validated') + + +def test_namespace_resource_quota(admin_cc, admin_pc): + q = default_project_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=q) + + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + + client = admin_pc.cluster.client + ns = client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_quota()) + assert ns is not None + assert ns.resourceQuota is not None + wait_for_applied_quota_set(admin_pc.cluster.client, + ns) + + +def test_project_resource_quota_fields(admin_cc): + q = default_project_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + + assert p.resourceQuota is not None + assert p.resourceQuota.limit.pods == '100' + assert p.namespaceDefaultResourceQuota is not None + assert p.namespaceDefaultResourceQuota.limit.pods == '100' + + +def test_resource_quota_ns_create(admin_cc, admin_pc): + q = default_project_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.resourceQuota.limit.pods == '100' + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_quota()) + assert ns is not None + assert ns.resourceQuota is not None + wait_for_applied_quota_set(admin_pc.cluster.client, ns) + + +def test_default_resource_quota_ns_set(admin_cc, admin_pc): + q = ns_default_quota() + pq = default_project_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id) + wait_for_applied_quota_set(admin_pc.cluster.client, + ns) + + +def test_quota_ns_create_exceed(admin_cc, admin_pc): + q = default_project_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + + # namespace quota exceeding project resource quota + cluster_client = admin_pc.cluster.client + with pytest.raises(ApiError) as e: + cluster_client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_large_quota()) + + assert e.value.error.status == 422 + + +def test_default_resource_quota_ns_create_invalid_combined(admin_cc, admin_pc): + pq = default_project_quota() + q = ns_default_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_quota()) + assert ns is not None + assert ns.resourceQuota is not None + + # namespace quota exceeding project resource quota + cluster_client = admin_pc.cluster.client + with pytest.raises(ApiError) as e: + cluster_client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_large_quota()) + + assert e.value.error.status == 422 + + # quota within limits + ns = cluster_client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_small_quota()) + assert ns is not None + assert ns.resourceQuota is not None + wait_for_applied_quota_set(admin_pc.cluster.client, ns, 10) + ns = admin_cc.client.reload(ns) + + # update namespace with exceeding quota + with pytest.raises(ApiError) as e: + admin_pc.cluster.client.update(ns, + resourceQuota=ns_large_quota()) + + assert e.value.error.status == 422 + + +def test_project_used_quota(admin_cc, admin_pc): + pq = default_project_quota() + q = ns_default_quota() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id) + wait_for_applied_quota_set(admin_pc.cluster.client, + ns) + used = wait_for_used_pods_limit_set(admin_cc.management.client, p) + assert used.pods == "4" + + +def wait_for_used_pods_limit_set(admin_cc_client, project, timeout=30, + value="0"): + start = time.time() + project = admin_cc_client.reload(project) + while "usedLimit" not in project.resourceQuota \ + or "pods" not in project.resourceQuota.usedLimit: + time.sleep(.5) + project = admin_cc_client.reload(project) + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' project.usedLimit.pods to be set') + if value == "0": + return project.resourceQuota.usedLimit + while project.resourceQuota.usedLimit.pods != value: + time.sleep(.5) + project = admin_cc_client.reload(project) + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' project.usedLimit.pods to be set to ' + value) + + +def test_default_resource_quota_project_update(admin_cc, admin_pc): + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id) + wait_for_applied_quota_set(admin_pc.cluster.client, ns, 10) + + pq = default_project_quota() + q = ns_default_quota() + p = admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + wait_for_applied_quota_set(admin_pc.cluster.client, + ns) + + +def test_api_validation_project(admin_cc): + client = admin_cc.management.client + q = default_project_quota() + # default namespace quota missing + with pytest.raises(ApiError) as e: + client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q) + + assert e.value.error.status == 422 + + # default namespace quota as None + with pytest.raises(ApiError) as e: + client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=None) + + assert e.value.error.status == 422 + + with pytest.raises(ApiError) as e: + client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + namespaceDefaultResourceQuota=q) + + assert e.value.error.status == 422 + + lq = ns_large_quota() + with pytest.raises(ApiError) as e: + client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=lq) + + assert e.value.error.status == 422 + + pq = {"limit": {"pods": "100", + "services": "100"}} + iq = {"limit": {"pods": "100"}} + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + with pytest.raises(ApiError) as e: + admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=iq) + + +def test_api_validation_namespace(admin_cc, admin_pc): + pq = {"limit": {"pods": "100", + "services": "100"}} + q = {"limit": {"pods": "10", + "services": "10"}} + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + nsq = {"limit": {"pods": "10"}} + with pytest.raises(ApiError) as e: + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=nsq) + assert e.value.error.status == 422 + + +def test_used_quota_exact_match(admin_cc, admin_pc): + pq = {"limit": {"pods": "10"}} + q = {"limit": {"pods": "2"}} + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + nsq = {"limit": {"pods": "2"}} + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=nsq) + + nsq = {"limit": {"pods": "8"}} + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=nsq) + wait_for_used_pods_limit_set(admin_cc.management.client, p, 10, "10") + + # try reducing the project quota + pq = {"limit": {"pods": "8"}} + dq = {"limit": {"pods": "1"}} + with pytest.raises(ApiError) as e: + admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=dq) + assert e.value.error.status == 422 + + +def test_add_remove_fields(admin_cc, admin_pc): + pq = {"limit": {"pods": "10"}} + q = {"limit": {"pods": "2"}} + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=pq, + namespaceDefaultResourceQuota=q) + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.namespaceDefaultResourceQuota is not None + + nsq = {"limit": {"pods": "2"}} + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=nsq) + + wait_for_used_pods_limit_set(admin_cc.management.client, p, + 10, "2") + + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=nsq) + + wait_for_used_pods_limit_set(admin_cc.management.client, p, + 10, "4") + + # update project with services quota + with pytest.raises(ApiError) as e: + pq = {"limit": {"pods": "10", "services": "10"}} + dq = {"limit": {"pods": "2", "services": "7"}} + admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=dq) + assert e.value.error.status == 422 + + pq = {"limit": {"pods": "10", "services": "10"}} + dq = {"limit": {"pods": "2", "services": "2"}} + p = admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=dq) + wait_for_used_svcs_limit_set(admin_cc.management.client, p, + 30, "4") + + # remove services quota + pq = {"limit": {"pods": "10"}} + dq = {"limit": {"pods": "2"}} + p = admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=dq) + wait_for_used_svcs_limit_set(admin_cc.management.client, p, + 30, "0") + + +def wait_for_used_svcs_limit_set(admin_cc_client, project, timeout=30, + value="0"): + start = time.time() + project = admin_cc_client.reload(project) + while "usedLimit" not in project.resourceQuota \ + or "services" not in project.resourceQuota.usedLimit: + time.sleep(.5) + project = admin_cc_client.reload(project) + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' project.usedLimit.services to be set') + if value == "0": + return project.resourceQuota.usedLimit + while project.resourceQuota.usedLimit.services != value: + time.sleep(.5) + project = admin_cc_client.reload(project) + if time.time() - start > timeout: + raise Exception('Timeout waiting for' + ' usedLimit.services to be set to ' + value) + + +def test_update_quota(admin_cc, admin_pc): + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id) + p = admin_cc.management.client.wait_success(p) + + # create 4 namespaces + for x in range(4): + admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=p.id) + + # update project with default namespace quota that + # won't qualify for the limit + with pytest.raises(ApiError) as e: + pq = {"limit": {"pods": "5"}} + dq = {"limit": {"pods": "2"}} + admin_cc.management.client.update(p, + resourceQuota=pq, + namespaceDefaultResourceQuota=dq) + assert e.value.error.status == 422 + + +def test_container_resource_limit(admin_cc, admin_pc): + q = default_project_quota() + lmt = ns_default_limit() + client = admin_cc.management.client + p = client.create_project(name='test-' + random_str(), + clusterId=admin_cc.cluster.id, + resourceQuota=q, + namespaceDefaultResourceQuota=q, + containerDefaultResourceLimit=lmt) + + p = admin_cc.management.client.wait_success(p) + assert p.resourceQuota is not None + assert p.containerDefaultResourceLimit is not None + + client = admin_pc.cluster.client + ns = client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota=ns_quota()) + assert ns is not None + assert ns.resourceQuota is not None + assert ns.containerDefaultResourceLimit is not None + wait_for_applied_quota_set(admin_pc.cluster.client, + ns) + + # reset the container limit + p = admin_cc.management.client.update(p, + containerDefaultResourceLimit=None) + + assert not hasattr(p, 'containerDefaultResourceLimit') + + ns = admin_cc.management.client.update(ns, + containerDefaultResourceLimit=None) + assert len(ns.containerDefaultResourceLimit) == 0 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_role_template_bindings.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_role_template_bindings.py new file mode 100644 index 0000000..91acdd9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_project_role_template_bindings.py @@ -0,0 +1,73 @@ +import pytest + +from .common import random_str +from .conftest import wait_for +from rancher import ApiError + + +def test_cannot_target_users_and_group(admin_mc, remove_resource): + """Asserts that a projectroletemplatebinding cannot target both + user and group subjects""" + admin_client = admin_mc.client + + project = admin_client.create_project( + name="p-" + random_str(), + clusterId="local") + remove_resource(project) + + with pytest.raises(ApiError) as e: + prtb = admin_client.create_project_role_template_binding( + name="prtb-"+random_str(), + projectId=project.id, + userId=admin_mc.user.id, + groupPrincipalId="someauthprovidergroupid", + roleTemplateId="projectcatalogs-view") + remove_resource(prtb) + assert e.value.error.status == 422 + assert "must target a user [userId]/[userPrincipalId] OR a group " \ + "[groupId]/[groupPrincipalId]" in e.value.error.message + + +def test_must_have_target(admin_mc, admin_pc, remove_resource): + """Asserts that a projectroletemplatebinding must have a subject""" + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + prtb = admin_client.create_project_role_template_binding( + name="prtb-" + random_str(), + projectId=admin_pc.project.id, + roleTemplateId="projectcatalogs-view") + remove_resource(prtb) + assert e.value.error.status == 422 + assert "must target a user [userId]/[userPrincipalId] OR a group " \ + "[groupId]/[groupPrincipalId]" in e.value.error.message + + +def test_cannot_update_subject_or_proj(admin_mc, admin_pc, remove_resource): + """Asserts non-metadata fields cannot be updated""" + admin_client = admin_mc.client + + old_prtb = admin_client.create_project_role_template_binding( + name="prtb-" + random_str(), + projectId=admin_pc.project.id, + userId=admin_mc.user.id, + roleTemplateId="projectcatalogs-view") + remove_resource(old_prtb) + + wait_for(lambda: admin_client.reload(old_prtb).userPrincipalId is not None) + old_prtb = admin_client.reload(old_prtb) + + prtb = admin_client.update_by_id_project_role_template_binding( + id=old_prtb.id, + clusterId="fakeproject", + userId="", + userPrincipalId="asdf", + groupPrincipalId="asdf", + group="asdf" + ) + + assert prtb.get("projectId") == old_prtb.get("projectId") + assert prtb.get("userId") == old_prtb.get("userId") + assert prtb.get("userPrincipalId") == old_prtb.get("userPrincipalId") + assert prtb.get("groupPrincipalId") == old_prtb.get("groupPrincipalId") + assert prtb.get("group") == old_prtb.get("group") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_rbac.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_rbac.py new file mode 100644 index 0000000..8e063f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_rbac.py @@ -0,0 +1,955 @@ +import kubernetes +import pytest +from rancher import ApiError +import time + +from .common import random_str +from .test_catalog import wait_for_template_to_be_created +from .conftest import wait_until_available, wait_until, \ + cluster_and_client, user_project_client, \ + kubernetes_api_client, wait_for, ClusterContext, \ + user_cluster_client + + +def test_multi_user(admin_mc, user_mc): + """Tests a bug in the python client where multiple clients would not + work properly. All clients would get the auth header of the last client""" + # Original admin client should be able to get auth configs + ac = admin_mc.client.list_auth_config() + assert len(ac) > 0 + + # User client should not. We currently dont 404 on this, which would be + # more correct. Instead, list gets filtered to zero + ac = user_mc.client.list_auth_config() + assert len(ac) == 0 + + +def test_project_owner(admin_cc, admin_mc, user_mc, remove_resource): + """Tests that a non-admin member can create a project, create and + add a namespace to it, and can do workload related things in the namespace. + + This is the first test written incorporating a non-admin user and the + kubernetes python client. It does a lot partially as an experiment and + partially as an example for other yet-to-be-written tests + """ + admin_client = admin_mc.client + admin_client.create_cluster_role_template_binding( + userId=user_mc.user.id, + roleTemplateId="cluster-member", + clusterId=admin_cc.cluster.id, + ) + + user_client = user_mc.client + + # When this returns, the user can successfully access the cluster and thus + # can create a project in it. We generally need this wait_until_available + # call when we are creating cluster, project, and namespaces as non-admins + # because until the rbac controllers have had a chance to run and the + # creator is bootstrapped into the resource, they will not be able to + # access it + wait_until_available(user_client, admin_cc.cluster) + + proj_name = 'test-' + random_str() + + def can_create_project(): + try: + p = user_client.create_project(name=proj_name, + clusterId=admin_cc.cluster.id) + # In case something goes badly as the user, add a finalizer to + # delete the project as the admin + remove_resource(p) + return p + except ApiError as e: + assert e.error.status == 403 + return False + + proj = wait_for(can_create_project) + + # When this returns, the user can successfully access the project and thus + # can create a namespace in it + proj = wait_until_available(user_client, proj) + proj = user_client.wait_success(proj) + assert proj.state == 'active' + + k8s_client = kubernetes_api_client(user_client, 'local') + auth = kubernetes.client.AuthorizationV1Api(k8s_client) + + # Rancher API doesn't have a surefire way of knowing exactly when the user + # has the ability to create namespaces yet. So we have to rely on an actual + # kubernetes auth check. + def can_create_ns(): + access_review = kubernetes.client.V1SelfSubjectAccessReview(spec={ + "resourceAttributes": { + 'verb': 'create', + 'resource': 'namespaces', + 'group': '', + }, + }) + response = auth.create_self_subject_access_review(access_review) + return response.status.allowed + + wait_for(can_create_ns) + + c_client = cluster_and_client('local', user_mc.client)[1] + ns = c_client.create_namespace(name='test-' + random_str(), + projectId=proj.id) + ns = wait_until_available(c_client, ns) + ns = c_client.wait_success(ns) + assert ns.state == 'active' + + # Simple proof that user can get pods in the created namespace. + # We just care that the list call does not error out + core = kubernetes.client.CoreV1Api(api_client=k8s_client) + core.list_namespaced_pod(ns.name) + + # As the user, assert that the two expected role bindings exist in the + # namespace for the user. There should be one for the rancher role + # 'project-owner' and one for the k8s built-in role 'admin' + rbac = kubernetes.client.RbacAuthorizationV1Api(api_client=k8s_client) + rbs = rbac.list_namespaced_role_binding(ns.name) + rb_dict = {} + for rb in rbs.items: + if rb.subjects[0].name == user_mc.user.id: + rb_dict[rb.role_ref.name] = rb + assert 'project-owner' in rb_dict + assert 'admin' in rb_dict + + # As an additional measure of proof and partially just as an exercise in + # using this particular k8s api, check that the user can create + # deployments using the subject access review api + access_review = kubernetes.client.V1LocalSubjectAccessReview(spec={ + "resourceAttributes": { + 'namespace': ns.name, + 'verb': 'create', + 'resource': 'deployments', + 'group': 'extensions', + }, + }) + response = auth.create_self_subject_access_review(access_review) + assert response.status.allowed is True + + # List_namespaced_pod just list the pods of default core groups. + # If you want to list the metrics of pods, + # users should have the permissions of metrics.k8s.io group. + # As a proof, we use this particular k8s api, check that the user can list + # pods.metrics.k8s.io using the subject access review api + access_review = kubernetes.client.V1LocalSubjectAccessReview(spec={ + "resourceAttributes": { + 'namespace': ns.name, + 'verb': 'list', + 'resource': 'pods', + 'group': 'metrics.k8s.io', + }, + }) + response = auth.create_self_subject_access_review(access_review) + assert response.status.allowed is True + + +def test_api_group_in_role_template(admin_mc, admin_pc, user_mc, + remove_resource): + """Test that a role moved into a cluster namespace is translated as + intended and respects apiGroups + """ + # If the admin can't see any nodes this test will fail + if len(admin_mc.client.list_node().data) == 0: + pytest.skip("no nodes in the cluster") + + # Validate the standard user can not see any nodes + assert len(user_mc.client.list_node().data) == 0 + + rt_dict = { + "administrative": False, + "clusterCreatorDefault": False, + "context": "cluster", + "external": False, + "hidden": False, + "locked": False, + "name": random_str(), + "projectCreatorDefault": False, + "rules": [{ + "apiGroups": [ + "management.cattle.io" + ], + "resources": ["nodes", + "nodepools" + ], + "type": "/v3/schemas/policyRule", + "verbs": ["get", + "list", + "watch" + ] + }, + { + "apiGroups": [ + "scheduling.k8s.io" + ], + "resources": [ + "*" + ], + "type": "/v3/schemas/policyRule", + "verbs": [ + "*" + ] + } + ], + } + + rt = admin_mc.client.create_role_template(rt_dict) + remove_resource(rt) + + def _wait_role_template(): + return admin_mc.client.by_id_role_template(rt.id) is not None + + wait_for(_wait_role_template, + fail_handler=lambda: "role template is missing") + + crtb_client = admin_mc.client.create_cluster_role_template_binding + + crtb = crtb_client(userPrincipalId=user_mc.user.principalIds[0], + roleTemplateId=rt.id, + clusterId='local') + remove_resource(crtb) + + def _wait_on_user(): + return len(user_mc.client.list_node().data) > 0 + + wait_for(_wait_on_user, fail_handler=lambda: "User could never see nodes") + + # With the new binding user should be able to see nodes + assert len(user_mc.client.list_node().data) > 0 + + # The binding does not allow delete permissions + with pytest.raises(ApiError) as e: + user_mc.client.delete(user_mc.client.list_node().data[0]) + + assert e.value.error.status == 403 + assert 'cannot delete resource "nodes"' in e.value.error.message + + +def test_removing_user_from_cluster(admin_pc, admin_mc, user_mc, admin_cc, + remove_resource): + """Test that a user added to a project in a cluster is able to see that + cluster and after being removed from the project they are no longer able + to see the cluster. + """ + + mbo = 'membership-binding-owner' + + admin_client = admin_mc.client + prtb = admin_client.create_project_role_template_binding( + userId=user_mc.user.id, + roleTemplateId="project-member", + projectId=admin_pc.project.id, + ) + remove_resource(prtb) + + # Verify the user can see the cluster + wait_until_available(user_mc.client, admin_cc.cluster) + + split = str.split(prtb.id, ":") + prtb_key = split[0] + "_" + split[1] + api_instance = kubernetes.client.RbacAuthorizationV1Api( + admin_mc.k8s_client) + + def crb_created(): + crbs = api_instance.list_cluster_role_binding( + label_selector=prtb_key + "=" + mbo) + return len(crbs.items) == 1 + + # Find the expected k8s clusterRoleBinding + wait_for(crb_created, + fail_handler=lambda: "failed waiting for clusterRoleBinding" + " to get created", + timeout=120) + + # Delete the projectRoleTemplateBinding, this should cause the user to no + # longer be able to see the cluster + admin_mc.client.delete(prtb) + + def crb_deleted(): + crbs = api_instance.list_cluster_role_binding( + label_selector=prtb_key + "=" + mbo) + return len(crbs.items) == 0 + + wait_for(crb_deleted, + fail_handler=lambda: "failed waiting for clusterRoleBinding" + " to get deleted", + timeout=120) + + # user should now have no access to any clusters + def list_clusters(): + clusters = user_mc.client.list_cluster() + return len(clusters.data) == 0 + + wait_for(list_clusters, + fail_handler=lambda: "failed revoking access to cluster", + timeout=120) + + with pytest.raises(ApiError) as e: + user_mc.client.by_id_cluster(admin_cc.cluster.id) + assert e.value.error.status == 403 + + +def test_upgraded_setup_removing_user_from_cluster(admin_pc, admin_mc, + user_mc, admin_cc, + remove_resource): + """Test that a user added to a project in a cluster prior to 2.5, upon + upgrade is able to see that cluster, and after being removed from the + project they are no longer able to see the cluster. + Upgrade will be simulated by editing the CRB to include the older label + format, containing the PRTB UID + """ + + mbo = 'membership-binding-owner' + + # Yes, this is misspelled, it's how the actual label was spelled + # prior to 2.5. + mbo_legacy = 'memberhsip-binding-owner' + + admin_client = admin_mc.client + prtb = admin_client.create_project_role_template_binding( + userId=user_mc.user.id, + roleTemplateId="project-member", + projectId=admin_pc.project.id, + ) + remove_resource(prtb) + + # Verify the user can see the cluster + wait_until_available(user_mc.client, admin_cc.cluster) + + api_instance = kubernetes.client.RbacAuthorizationV1Api( + admin_mc.k8s_client) + + split = str.split(prtb.id, ":") + prtb_key = split[0]+"_"+split[1] + + def crb_created(): + crbs = api_instance.list_cluster_role_binding( + label_selector=prtb_key + "=" + mbo) + return len(crbs.items) == 1 + + # Find the expected k8s clusterRoleBinding + wait_for(crb_created, + fail_handler=lambda: "failed waiting for clusterRoleBinding to" + "get created", timeout=120) + + crbs = api_instance.list_cluster_role_binding( + label_selector=prtb_key + "=" + mbo) + + assert len(crbs.items) == 1 + + # edit this CRB to add in the legacy label to simulate an upgraded setup + crb = crbs.items[0] + crb.metadata.labels[prtb.uuid] = mbo_legacy + api_instance.patch_cluster_role_binding(crb.metadata.name, crb) + + def crb_label_updated(): + crbs = api_instance.list_cluster_role_binding( + label_selector=prtb.uuid + "=" + mbo_legacy) + return len(crbs.items) == 1 + + wait_for(crb_label_updated, + fail_handler=lambda: "failed waiting for cluster role binding to" + "be updated", timeout=120) + + # Delete the projectRoleTemplateBinding, this should cause the user to no + # longer be able to see the cluster + admin_mc.client.delete(prtb) + + def crb_callback(): + crbs_listed_with_new_label = api_instance.list_cluster_role_binding( + label_selector=prtb_key + "=" + mbo) + crbs_listed_with_old_label = api_instance.list_cluster_role_binding( + label_selector=prtb.uuid + "=" + mbo_legacy) + return len(crbs_listed_with_new_label.items) == 0 and\ + len(crbs_listed_with_old_label.items) == 0 + + def fail_handler(): + return "failed waiting for cluster role binding to be deleted" + + wait_for(crb_callback, fail_handler=fail_handler, timeout=120) + + # user should now have no access to any clusters + def list_clusters(): + clusters = user_mc.client.list_cluster() + return len(clusters.data) == 0 + + wait_for(list_clusters, + fail_handler=lambda: "failed revoking access to cluster", + timeout=120) + + with pytest.raises(ApiError) as e: + user_mc.client.by_id_cluster(admin_cc.cluster.id) + assert e.value.error.status == 403 + + +def test_user_role_permissions(admin_mc, user_factory, remove_resource): + """Test that a standard user can only see themselves """ + admin_client = admin_mc.client + + # Create 4 new users, one with user-base + user1 = user_factory() + user2 = user_factory(globalRoleId='user-base') + user_factory() + user_factory() + + users = admin_client.list_user() + # Admin should see at least 5 users + assert len(users.data) >= 5 + + # user1 should only see themselves in the user list + users1 = user1.client.list_user() + assert len(users1.data) == 1, "user should only see themselves" + + # user1 can see all roleTemplates + role_templates = user1.client.list_role_template() + assert len(role_templates.data) > 0, ("user should be able to see all " + + "roleTemplates") + + # user2 should only see themselves in the user list + users2 = user2.client.list_user() + assert len(users2.data) == 1, "user should only see themselves" + # user2 should not see any role templates + role_templates = user2.client.list_role_template() + assert len(role_templates.data) == 0, ("user2 does not have permission " + + "to view roleTemplates") + + +def test_impersonation_passthrough(admin_mc, admin_cc, user_mc, user_factory, + remove_resource, request): + """Test users abalility to impersonate other users""" + admin_client = admin_mc.client + + user1 = user_factory() + user2 = user_factory() + + admin_client.create_cluster_role_template_binding( + userId=user1.user.id, + roleTemplateId="cluster-member", + clusterId=admin_cc.cluster.id, + ) + + admin_client.create_cluster_role_template_binding( + userId=user2.user.id, + roleTemplateId="cluster-owner", + clusterId=admin_cc.cluster.id, + ) + + wait_until_available(user1.client, admin_cc.cluster) + wait_until_available(user2.client, admin_cc.cluster) + + admin_k8s_client = kubernetes_api_client(admin_client, 'local') + user1_k8s_client = kubernetes_api_client(user1.client, 'local') + user2_k8s_client = kubernetes_api_client(user2.client, 'local') + + admin_auth = kubernetes.client.AuthorizationV1Api(admin_k8s_client) + user1_auth = kubernetes.client.AuthorizationV1Api(user1_k8s_client) + user2_auth = kubernetes.client.AuthorizationV1Api(user2_k8s_client) + + access_review = kubernetes.client.V1SelfSubjectAccessReview(spec={ + "resourceAttributes": { + 'verb': 'impersonate', + 'resource': 'users', + 'group': '', + }, + }) + + # Admin can always impersonate + response = admin_auth.create_self_subject_access_review(access_review) + assert response.status.allowed is True + + # User1 is a member of the cluster which does not grant impersonate + response = user1_auth.create_self_subject_access_review(access_review) + assert response.status.allowed is False + + # User2 is an owner/admin which allows them to impersonate + def _access_check(): + response = user2_auth.create_self_subject_access_review(access_review) + return response.status.allowed is True + + wait_for(_access_check, fail_handler=lambda: "user2 does not have access") + + # Add a role and role binding to user user1 allowing user1 to impersonate + # user2 + admin_rbac = kubernetes.client.RbacAuthorizationV1Api(admin_k8s_client) + body = kubernetes.client.V1ClusterRole( + metadata={'name': 'limited-impersonator'}, + rules=[{ + 'resources': ['users'], + 'apiGroups': [''], + 'verbs': ['impersonate'], + 'resourceNames': [user2.user.id] + }] + ) + impersonate_role = admin_rbac.create_cluster_role(body) + + request.addfinalizer(lambda: admin_rbac.delete_cluster_role( + impersonate_role.metadata.name)) + + binding = kubernetes.client.V1ClusterRoleBinding( + metadata={'name': 'limited-impersonator-binding'}, + role_ref={ + 'apiGroups': [''], + 'kind': 'ClusterRole', + 'name': 'limited-impersonator' + }, + subjects=[{'kind': 'User', 'name': user1.user.id}] + ) + + impersonate_role_binding = admin_rbac.create_cluster_role_binding(binding) + + request.addfinalizer(lambda: admin_rbac.delete_cluster_role_binding( + impersonate_role_binding.metadata.name)) + + access_review2 = kubernetes.client.V1SelfSubjectAccessReview(spec={ + "resourceAttributes": { + 'verb': 'impersonate', + 'resource': 'users', + 'group': '', + 'name': user2.user.id + }, + }) + + # User1 should now be abele to imerpsonate as user2 + def _access_check2(): + response = user1_auth.create_self_subject_access_review(access_review2) + return response.status.allowed is True + + wait_for(_access_check2, fail_handler=lambda: "user1 does not have access") + + +def test_permissions_can_be_removed(admin_cc, admin_mc, user_mc, request, + remove_resource, admin_pc_factory): + def create_project_and_add_user(): + admin_pc_instance = admin_pc_factory() + + prtb = admin_mc.client.create_project_role_template_binding( + userId=user_mc.user.id, + roleTemplateId="project-member", + projectId=admin_pc_instance.project.id, + ) + remove_resource(prtb) + wait_until_available(user_mc.client, admin_pc_instance.project) + return admin_pc_instance, prtb + + admin_pc1, _ = create_project_and_add_user() + admin_pc2, prtb2 = create_project_and_add_user() + + def add_namespace_to_project(admin_pc): + def safe_remove(client, resource): + try: + client.delete(resource) + except ApiError: + pass + + ns = admin_cc.client.create_namespace(name=random_str(), + projectId=admin_pc.project.id) + request.addfinalizer(lambda: safe_remove(admin_cc.client, ns)) + + def ns_active(): + new_ns = admin_cc.client.reload(ns) + return new_ns.state == 'active' + + wait_for(ns_active) + + add_namespace_to_project(admin_pc1) + + def new_user_cc(user_mc): + cluster, client = cluster_and_client('local', user_mc.client) + return ClusterContext(user_mc, cluster, client) + + user_cc = new_user_cc(user_mc) + wait_for(lambda: ns_count(user_cc.client, 1), timeout=60) + + add_namespace_to_project(admin_pc2) + + user_cc = new_user_cc(user_mc) + wait_for(lambda: ns_count(user_cc.client, 2), timeout=60) + admin_mc.client.delete(prtb2) + + user_cc = new_user_cc(user_mc) + wait_for(lambda: ns_count(user_cc.client, 1), timeout=60) + + +def ns_count(client, count): + return len(client.list_namespace()) == count + + +def test_appropriate_users_can_see_kontainer_drivers(user_factory): + kds = user_factory().client.list_kontainer_driver() + assert len(kds) == 11 + + kds = user_factory('clusters-create').client.list_kontainer_driver() + assert len(kds) == 11 + + kds = user_factory('kontainerdrivers-manage').client. \ + list_kontainer_driver() + assert len(kds) == 11 + + kds = user_factory('settings-manage').client.list_kontainer_driver() + assert len(kds) == 0 + + +@pytest.mark.skip +def test_readonly_cannot_perform_app_action(admin_mc, admin_pc, user_mc, + remove_resource): + """Tests that a user with readonly access is not able to upgrade an app + """ + client = admin_pc.client + project = admin_pc.project + + user = user_mc + remove_resource(user) + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=project.id) + remove_resource(ns) + + wait_for_template_to_be_created(admin_mc.client, "library") + + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user.user.id, + projectId=project.id, + roleTemplateId="read-only") + remove_resource(prtb) + + wait_until_available(user.client, project) + + app = client.create_app( + name="app-" + random_str(), + externalId="catalog://?catalog=library&template=mysql&version=0.3.7&" + "namespace=cattle-global-data", + targetNamespace=ns.name, + projectId=project.id + ) + + with pytest.raises(ApiError) as e: + user.client.action(obj=app, action_name="upgrade", + answers={"abc": "123"}) + assert e.value.error.status == 403 + + with pytest.raises(ApiError) as e: + user.client.action(obj=app, action_name="rollback", + revisionId="test") + assert e.value.error.status == 403 + + +@pytest.mark.skip +def test_member_can_perform_app_action(admin_mc, admin_pc, remove_resource, + user_mc): + """Tests that a user with member access is able to upgrade an app + """ + client = admin_pc.client + project = admin_pc.project + + user = user_mc + remove_resource(user) + + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=project.id) + remove_resource(ns) + + wait_for_template_to_be_created(admin_mc.client, "library") + + prtb = admin_mc.client.create_project_role_template_binding( + name="test-" + random_str(), + userId=user.user.id, + projectId=project.id, + roleTemplateId="project-owner") + remove_resource(prtb) + + wait_until_available(user.client, project) + + app = client.create_app( + name="test-" + random_str(), + externalId="catalog://?catalog=library&template" + "=mysql&version=1.3.1&" + "namespace=cattle-global-data", + targetNamespace=ns.name, + projectId=project.id + ) + + # if upgrade is performed prior to installing state, + # it may return a modified error + def is_installing(): + current_state = client.reload(app) + if current_state.state == "installing": + return True + return False + + try: + wait_for(is_installing) + except Exception as e: + # a timeout here is okay, the intention of the wait_for is to reach a + # steady state, this test is not concerned with whether an app reaches + # installing state or not + assert "Timeout waiting for condition" in str(e) + + user.client.action( + obj=app, + action_name="upgrade", + answers={"asdf": "asdf"}) + + def _app_revisions_exist(): + a = admin_pc.client.reload(app) + return len(a.revision().data) > 0 + wait_for(_app_revisions_exist, timeout=60, + fail_handler=lambda: 'no revisions exist') + proj_user_client = user_project_client(user_mc, project) + app = proj_user_client.reload(app) + revID = app.revision().data[0]['id'] + revID = revID.split(":")[1] if ":" in revID else revID + user.client.action( + obj=app, + action_name="rollback", + revisionId=revID + ) + + +def test_readonly_cannot_edit_secret(admin_mc, user_mc, admin_pc, + remove_resource): + """Tests that a user with readonly access is not able to create/update + a secret or ns secret + """ + project = admin_pc.project + user_client = user_mc.client + + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=project.id, + roleTemplateId="read-only" + ) + remove_resource(prtb) + + wait_until_available(user_client, project) + + proj_user_client = user_project_client(user_mc, project) + + # readonly should failed to create a regular secret + with pytest.raises(ApiError) as e: + proj_user_client.create_secret( + name="test-" + random_str(), + stringData={ + 'abc': '123' + } + ) + assert e.value.error.status == 403 + + secret = admin_pc.client.create_secret( + name="test-" + random_str(), + stringData={ + 'abc': '123' + } + ) + remove_resource(secret) + + wait_until_available(admin_pc.client, secret) + + # readonly should failed to update a regular secret + with pytest.raises(ApiError) as e: + proj_user_client.update_by_id_secret( + id=secret.id, + stringData={ + 'asd': 'fgh' + } + ) + assert e.value.error.status == 404 + + ns = admin_pc.cluster.client.create_namespace( + name='test-' + random_str(), + projectId=project.id + ) + remove_resource(ns) + + # readonly should fail to create ns secret + with pytest.raises(ApiError) as e: + proj_user_client.create_namespaced_secret( + namespaceId=ns.id, + name="test-" + random_str(), + stringData={ + 'abc': '123' + } + ) + assert e.value.error.status == 403 + + ns_secret = admin_pc.client.create_namespaced_secret( + namespaceId=ns.id, + name="test-" + random_str(), + stringData={ + 'abc': '123' + } + ) + remove_resource(ns_secret) + + wait_until_available(admin_pc.client, ns_secret) + + # readonly should fail to update ns secret + with pytest.raises(ApiError) as e: + proj_user_client.update_by_id_namespaced_secret( + namespaceId=ns.id, + id=ns_secret.id, + stringData={ + 'asd': 'fgh' + } + ) + assert e.value.error.status == 404 + + +def test_member_can_edit_secret(admin_mc, admin_pc, remove_resource, + user_mc): + """Tests that a user with project-member role is able to create/update + secrets and namespaced secrets + """ + project = admin_pc.project + user_client = user_mc.client + + ns = admin_pc.cluster.client.create_namespace( + name='test-' + random_str(), + projectId=project.id + ) + remove_resource(ns) + + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=project.id, + roleTemplateId="project-member" + ) + + remove_resource(prtb) + + wait_until_available(user_client, project) + + proj_user_client = user_project_client(user_mc, project) + + def try_create_secret(): + try: + return proj_user_client.create_secret( + name="secret-" + random_str(), + stringData={ + 'abc': '123' + } + ) + except ApiError as e: + assert e.error.status == 403 + return False + + # Permission to create secret may not have been granted yet, + # so it will be retried for 45 seconds + secret = wait_for(try_create_secret, fail_handler=lambda: + "do not have permission to create secret") + remove_resource(secret) + + wait_until_available(proj_user_client, secret) + + proj_user_client.update_by_id_secret(id=secret.id, stringData={ + 'asd': 'fgh' + }) + + def try_create_ns_secret(): + try: + return proj_user_client.create_namespaced_secret( + name="secret-" + random_str(), + namespaceId=ns.id, + stringData={ + "abc": "123" + } + ) + + except ApiError as e: + assert e.error.status == 403 + return False + + ns_secret = wait_for(try_create_ns_secret, fail_handler=lambda: + "do not have permission to create ns secret") + remove_resource(ns_secret) + + wait_until_available(proj_user_client, ns_secret) + + proj_user_client.update_by_id_namespaced_secret( + namespaceId=ns.id, + id=ns_secret.id, + stringData={ + "asd": "fgh" + } + ) + + +def test_readonly_cannot_move_namespace( + admin_cc, admin_mc, user_mc, remove_resource): + """Tests that a user with readonly access is not able to + move namespace across projects. Makes 2 projects and one + namespace and then moves NS across. + """ + p1 = admin_mc.client.create_project( + name='test-' + random_str(), + clusterId=admin_cc.cluster.id + ) + remove_resource(p1) + p1 = admin_cc.management.client.wait_success(p1) + + p2 = admin_mc.client.create_project( + name='test-' + random_str(), + clusterId=admin_cc.cluster.id + ) + remove_resource(p2) + p2 = admin_mc.client.wait_success(p2) + + # Use k8s client to see if project namespace exists + k8s_client = kubernetes.client.CoreV1Api(admin_mc.k8s_client) + wait_until(cluster_has_namespace(k8s_client, p1.id.split(":")[1])) + wait_until(cluster_has_namespace(k8s_client, p2.id.split(":")[1])) + + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=p1.id, + roleTemplateId="read-only") + remove_resource(prtb) + + prtb2 = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=p2.id, + roleTemplateId="read-only") + remove_resource(prtb2) + + wait_until_available(user_mc.client, p1) + wait_until_available(user_mc.client, p2) + + ns = admin_cc.client.create_namespace( + name=random_str(), + projectId=p1.id + ) + wait_until_available(admin_cc.client, ns) + remove_resource(ns) + + cluster_user_client = user_cluster_client(user_mc, admin_cc.cluster) + wait_until_available(cluster_user_client, ns) + + with pytest.raises(ApiError) as e: + user_mc.client.action(obj=ns, action_name="move", projectId=p2.id) + assert e.value.error.status == 404 + + +def wait_for_workload(client, ns, timeout=60, count=0): + start = time.time() + interval = 0.5 + workloads = client.list_workload(namespaceId=ns) + while len(workloads.data) != count: + if time.time() - start > timeout: + print(workloads) + raise Exception('Timeout waiting for workload service') + time.sleep(interval) + interval *= 2 + workloads = client.list_workload(namespaceId=ns) + return workloads + + +def cluster_has_namespace(client, ns_name): + """Wait for the give namespace to exist, useful for project namespaces""" + def cb(): + return ns_name in \ + [ns.metadata.name for ns in client.list_namespace().items] + return cb diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_role_template.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_role_template.py new file mode 100644 index 0000000..cf0feb0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_role_template.py @@ -0,0 +1,317 @@ +from .common import random_str +from .conftest import wait_until_available, wait_until, wait_for +from rancher import ApiError +import time +import pytest +import kubernetes + + +def test_role_template_creation(admin_mc, remove_resource): + rt_name = random_str() + rt = admin_mc.client.create_role_template(name=rt_name) + remove_resource(rt) + assert rt is not None + assert rt.name == rt_name + + +def test_administrative_role_template_creation(admin_mc, remove_resource): + client = admin_mc.client + crt_name = random_str() + crt = client.create_role_template(name=crt_name, + context="cluster", + administrative=True) + remove_resource(crt) + assert crt is not None + assert crt.name == crt_name + + prt_name = random_str() + try: + client.create_role_template(name=prt_name, + context="project", + administrative=True) + except ApiError as e: + assert e.error.status == 500 + assert e.error.message == "Only cluster roles can be administrative" + + +def test_edit_builtin_role_template(admin_mc, remove_resource): + client = admin_mc.client + # edit non builtin role, any field is updatable + org_rt_name = random_str() + rt = client.create_role_template(name=org_rt_name) + remove_resource(rt) + wait_for_role_template_creation(admin_mc, org_rt_name) + new_rt_name = random_str() + rt = client.update(rt, name=new_rt_name) + assert rt.name == new_rt_name + + # edit builtin role, only locked,cluster/projectcreatordefault + # are updatable + new_rt_name = "Cluster Member-Updated" + cm_rt = client.by_id_role_template("cluster-member") + rt = client.update(cm_rt, name=new_rt_name) + assert rt.name == "Cluster Member" + + +def test_context_prtb(admin_mc, admin_pc, remove_resource, + user_mc): + """Asserts that a projectroletemplatebinding cannot reference a cluster + roletemplate + """ + admin_client = admin_mc.client + project = admin_pc.project + + with pytest.raises(ApiError) as e: + prtb = admin_client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_mc.user.id, + projectId=project.id, + roleTemplateId="cluster-owner" + ) + remove_resource(prtb) + + assert e.value.error.status == 422 + assert "Cannot reference context [cluster] from [project] context" in \ + e.value.error.message + + +def test_context_crtb(admin_mc, admin_cc, remove_resource, + user_mc): + """Asserts that a clusterroletemplatebinding cannot reference a project + roletemplate + """ + admin_client = admin_mc.client + + with pytest.raises(ApiError) as e: + crtb = admin_client.create_cluster_role_template_binding( + userId=user_mc.user.id, + roleTemplateId="project-owner", + clusterId=admin_cc.cluster.id, + ) + remove_resource(crtb) + + assert e.value.error.status == 422 + assert "Cannot reference context [project] from [cluster] context" in \ + e.value.error.message + + +def test_update_role_template_permissions(admin_mc, remove_resource, + user_factory, admin_cc): + client = admin_mc.client + cc_rt_name = random_str() + view_cc_rule = [{'apiGroups': ['management.cattle.io'], + 'resources': ['clustercatalogs'], + 'type': '/v3/schemas/policyRule', + 'verbs': ['get', 'list', 'watch']}, + {'apiGroups': ['management.cattle.io'], + 'resources': ['clusteralertrules'], + 'type': '/v3/schemas/policyRule', + 'verbs': ['get', 'list', 'watch']}] + rt = client.create_role_template(name=cc_rt_name, context="cluster", + rules=view_cc_rule) + role_template_id = rt['id'] + wait_for_role_template_creation(admin_mc, cc_rt_name) + + user_view_cc = user_factory() + user_client = user_view_cc.client + crtb = client.create_cluster_role_template_binding( + userId=user_view_cc.user.id, + roleTemplateId=role_template_id, + clusterId=admin_cc.cluster.id, + ) + remove_resource(crtb) + wait_until_available(user_client, admin_cc.cluster) + + # add clustercatalog as admin + url = "https://github.com/rancher/integration-test-charts.git" + name = random_str() + cluster_catalog = \ + client.create_cluster_catalog(name=name, + branch="master", + url=url, + clusterId="local", + ) + remove_resource(cluster_catalog) + wait_until_available(client, cluster_catalog) + + # list clustercatalog as the cluster-member + cc = user_client.list_cluster_catalog(name=name) + assert len(cc) == 1 + + # update role to remove view clustercatalogs permission + view_cc_role_template = client.by_id_role_template(role_template_id) + new_rules = [{'apiGroups': ['management.cattle.io'], + 'resources': ['clusteralertrules'], + 'type': '/v3/schemas/policyRule', + 'verbs': ['get', 'list', 'watch']}] + client.update(view_cc_role_template, rules=new_rules) + wait_until(lambda: client.reload(view_cc_role_template)['rules'] is None) + + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + + def check_role_rules(rbac, namespace, role_name, rules): + role = rbac.read_namespaced_role(role_name, namespace) + if len(role.rules) == len(rules) and \ + role.rules[0].resources == ["clusteralertrules"]: + return True + + wait_for(lambda: check_role_rules(rbac, 'local', role_template_id, + new_rules), + timeout=60, fail_handler=lambda: + 'failed to check updated role') + # user should not be able to list cluster catalog now + cc = user_client.list_cluster_catalog(name=name) + assert len(cc) == 0 + + +def test_role_template_update_inherited_role(admin_mc, remove_resource, + user_factory, admin_pc): + client = admin_mc.client + name = random_str() + # clone project-member role + pm = client.by_id_role_template("project-member") + cloned_pm = client.create_role_template(name=name, context="project", + rules=pm.rules, + roleTemplateIds=["edit"]) + remove_resource(cloned_pm) + role_template_id = cloned_pm['id'] + wait_for_role_template_creation(admin_mc, name) + + # create a namespace in this project + ns_name = random_str() + ns = admin_pc.cluster.client.create_namespace(name=ns_name, + projectId=admin_pc. + project.id) + remove_resource(ns) + + # add user to a project with this role + user_cloned_pm = user_factory() + prtb = client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_cloned_pm.user.id, + projectId=admin_pc.project.id, + roleTemplateId=role_template_id + ) + remove_resource(prtb) + wait_until_available(user_cloned_pm.client, admin_pc.project) + + # As the user, assert that the two expected role bindings exist in the + # namespace for the user. There should be one for the rancher role + # 'cloned_pm' and one for the k8s built-in role 'edit' + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + + def _refresh_user_template(): + rbs = rbac.list_namespaced_role_binding(ns_name) + rb_dict = {} + for rb in rbs.items: + if rb.subjects[0].name == user_cloned_pm.user.id: + rb_dict[rb.role_ref.name] = rb + return role_template_id in rb_dict and 'edit' in rb_dict + + wait_for(_refresh_user_template, + fail_handler=lambda: 'role bindings do not exist') + + # now edit the roleTemplate to remove "edit" from inherited roles, + # and add "view" to inherited roles + client.update(cloned_pm, roleTemplateIds=["view"]) + wait_until(lambda: client.reload(cloned_pm)['roleTemplateIds'] is ["view"]) + + def check_rb(rbac): + rbs = rbac.list_namespaced_role_binding(ns_name) + for rb in rbs.items: + if rb.subjects[0].name == user_cloned_pm.user.id \ + and rb.role_ref.name == "view": + return True + + wait_for(lambda: check_rb(rbac), timeout=60, + fail_handler=lambda: 'failed to check updated rolebinding') + + # Now there should be one rolebinding for the rancher role + # 'cloned_pm' and one for the k8s built-in role 'view' + rbac = kubernetes.client.RbacAuthorizationV1Api(admin_mc.k8s_client) + rbs = rbac.list_namespaced_role_binding(ns_name) + rb_dict = {} + for rb in rbs.items: + if rb.subjects[0].name == user_cloned_pm.user.id: + rb_dict[rb.role_ref.name] = rb + assert role_template_id in rb_dict + assert 'view' in rb_dict + assert 'edit' not in rb_dict + + +def test_role_template_changes_revoke_permissions(admin_mc, remove_resource, + user_factory, admin_pc): + client = admin_mc.client + name = random_str() + # clone project-owner role + po = client.by_id_role_template("project-owner") + cloned_po = client.create_role_template(name=name, context="project", + rules=po.rules, + roleTemplateIds=["admin"]) + remove_resource(cloned_po) + wait_for_role_template_creation(admin_mc, name) + role_template_id = cloned_po['id'] + + user = user_factory() + # add a user with this cloned project-owner role to a project + prtb = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user.user.id, + projectId=admin_pc.project.id, + roleTemplateId=role_template_id + ) + remove_resource(prtb) + wait_until_available(user.client, admin_pc.project) + + # this user should be able to list PRTBs + def _list_prtbs(): + prtbs = user.client.list_project_role_template_binding() + return len(prtbs.data) > 0 + + wait_for(_list_prtbs, fail_handler=lambda: "user was unable to list PRTBs") + + # now edit the cloned roletemplate to remove permission + # to list projectroletemplatebindings + rules = cloned_po['rules'] + for ind, rule in enumerate(rules): + if 'projectroletemplatebindings' in rule['resources']: + del rules[ind] + + client.update(cloned_po, rules=rules) + + def role_template_update_check(): + rt = client.by_id_role_template(role_template_id) + for rule in rt['rules']: + if 'projectroletemplatebindings' in rule['resources']: + return False + return True + + def fail_handler(): + return "failed waiting for cloned roletemplate to be updated" + + # Validate the rule was dropped + wait_for(role_template_update_check, fail_handler=fail_handler(), + timeout=120) + + # this user should NOT be able to list PRTBs + def _list_prtbs_empty(): + prtbs = user.client.list_project_role_template_binding() + return len(prtbs.data) == 0 + + wait_for(_list_prtbs_empty, + fail_handler=lambda: "user was able to list PRTBs") + + +def wait_for_role_template_creation(admin_mc, rt_name, timeout=60): + start = time.time() + interval = 0.5 + client = admin_mc.client + found = False + while not found: + if time.time() - start > timeout: + raise Exception('Timeout waiting for roletemplate creation') + rt = client.list_role_template(name=rt_name) + if len(rt) > 0: + found = True + time.sleep(interval) + interval *= 2 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_secrets.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_secrets.py new file mode 100644 index 0000000..c00a5a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_secrets.py @@ -0,0 +1,338 @@ +from .common import random_str +import kubernetes +from .conftest import kubernetes_api_client, user_project_client + +CERT = """-----BEGIN CERTIFICATE----- +MIIDEDCCAfgCCQC+HwE8rpMN7jANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hlciBMYWJzMRIwEAYD +VQQDEwlsb2NhbGhvc3QwHhcNMTYwNjMwMDExMzMyWhcNMjYwNjI4MDExMzMyWjBK +MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hl +ciBMYWJzMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC1PR0EiJjM0wbFQmU/yKSb7AuQdzhdW02ya+RQe+31/B+sOTMr +z9b473KCKf8LiFKFOIQUhR5fPvwyrrIWKCEV9pCp/wM474fX32j0zYaH6ezZjL0r +L6hTeGFScGse3dk7ej2+6nNWexpujos0djFi9Gu11iVHIJyT2Sx66kPPPZVRkJO9 +5Pfetm5SLIQtJHUwy5iWv5Br+AbdXlUAjTYUqS4mhKIIbblAPbOKrYRxGXX/6oDV +J5OGLle8Uvlb8poxqmy67FPyMObNHhjggKwboXhmNuuT2OGf/VeZANMYubs4JP2V +ZLs3U/1tFMAOaQM+PbT9JuwMSmGYFX0Qiuh/AgMBAAEwDQYJKoZIhvcNAQEFBQAD +ggEBACpkRCQpCn/zmTOwboBckkOFeqMVo9cvSu0Sez6EPED4WUv/6q5tlJeHekQm +6YVcsXeOMkpfZ7qtGmBDwR+ly7D43dCiPKplm0uApO1CkogG5ePv0agvKHEybd36 +xu9pt0fnxDdrP2NrP6trHq1D+CzPZooLRfmYqbt1xmIb00GpnyiJIUNuMu7GUM3q +NxWGK3eq+1cyt6xr8nLOC5zaGeSyZikw4+9vqLudNSyYdnw9mdHtrYT0GlcEP1Vc +NK+yrhDCvEWH6+4+pp8Ve2P2Le5tvbA1m24AxyuC9wHS5bUmiNHweLXNpxLFTjK8 +BBUi6y1Vm9jrDi/LiiHcN4sJEoU= +-----END CERTIFICATE-----""" + +KEY = """-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAtT0dBIiYzNMGxUJlP8ikm+wLkHc4XVtNsmvkUHvt9fwfrDkz +K8/W+O9ygin/C4hShTiEFIUeXz78Mq6yFighFfaQqf8DOO+H199o9M2Gh+ns2Yy9 +Ky+oU3hhUnBrHt3ZO3o9vupzVnsabo6LNHYxYvRrtdYlRyCck9kseupDzz2VUZCT +veT33rZuUiyELSR1MMuYlr+Qa/gG3V5VAI02FKkuJoSiCG25QD2ziq2EcRl1/+qA +1SeThi5XvFL5W/KaMapsuuxT8jDmzR4Y4ICsG6F4Zjbrk9jhn/1XmQDTGLm7OCT9 +lWS7N1P9bRTADmkDPj20/SbsDEphmBV9EIrofwIDAQABAoIBAGehHxN1i3EqhKeL +9FrJPh4NlPswwCDZUQ7hFDZU9lZ9qBqQxkqZ18CVIXN90eBlPVIBY7xb9Wbem9Pb +AecbYPeu+T7KmqwWgiUUEG5RikfyoMQv7gZghK3dmkBKGWYX0dtpZR7h7bsYPp/S +j5QatNhxC5l4be5CnmUHe6B4jPdUt8kRfTj0ukYGm/h3cOm/tEQeRYIIN/N6JN2Z +JWYzsyqGmlOTp7suczkRIUS0AjiljT1186bQSou62iMtMqEgArusFFb9m/dXCCYo +t/Q1SR4lRodDfzcF/CRbdR/ZC8gZlyCdbI4WHOw9IwwHnmrllx4MXFP/p6p+gEtl +cKMzHXECgYEA27KnkDnz338qKC2cCGkMf3ARfTX6gSlqmvgM9zOa8FLWp6GR6Rvo +NgVLUi63bQqv9D5qYSsweAp1QTvIxJffWMJDTWtxowOXVW5P8WJ8jp/pAXoWGRbd +pnavy6Ih0XT57huwT7fGGIikXYfw/kB85PPJL3FsT/b6G4ay2+Z7OGkCgYEA0y+d +bxUewYZkpNy7+kIh0x4vrJvNqSL9ZwiP2R159zu7zDwDph/fkhXej0FEtbXybt+O +4s9M3l4nNsY6AS9sIPCB5SxWguhx0z76U5cz1qFFZwIHtL8r1jHrl5iwkVyOAtVV +0BokmJG4Pn07yZo/iCmSTEfwcePvCMvOsPtcvKcCgYEAu5+SbKChfhBaz19MLv6P +ttHdjcIogl/9dAU9BWxj+LO2MAjS1HKJ2ICi97d/3LbQ19TqArvgs9OymZhV+Fb/ +Xgzhb1+/94icmFASI8KJP0CfvCwobRrTBlO8BDsdiITO4SNyalI28kLXpCzxiiFG +yDzOZx8FcjEpHZLmctgeCWkCgYAO0rDCM0FNZBl8WOH41tt47g16mBT/Yi1XJgqy +upbs+4xa8XtwFZyjrFVKyNIBzxuNHLPyx4olsYYfGhrIKoP0a+0yIMKRva7/nNQF +Of+xePBeIo5X6XMyPZ7DrTv3d/+fw0maqbsX2mKMQE4KAIGlFQXnxMTjuZP1khiX +44zG0QKBgGwQ8T4DGZK5ukLQmhLi9npCaAW99s/uuKArMzAG9xd/I8YntM/kVY0V +VUi3lKqwXhtReYdrqVTPdjnyGIYIGGNRD7EKqQe15IRfbpy536DSN+LvL65Fdyis +iNITDKNP1H3hedFNFfbTGpueYdRX6QaptK4+NB4+dOm7hn8iqq7U +-----END RSA PRIVATE KEY-----""" + +MALFORMED_CERT = """-----BEGIN CERTIFICATE----- +MIIDEDCCAfgCCQC+HwE8rpMN7jANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hlciBMYWJzMRIwEAYD +VQQDEwlsb2NhbGhvc3QwHhcNMTYwNjMwMDExMzMyWhcNMjYwNjI4MDExMzMyWjBK +MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTEVMBMGA1UEChMMUmFuY2hl +ciBMYWJzMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC1PR0EiJjM0wbFQmU/yKSb7AuQdzhdW02ya+RQe+31/B+sOTMr +z9b473KCKf8LiFKFOxyuC9wHS5bUmiNHweLXNpxLFTjK8 +BBUi6y1Vm9jrDi/LiiHcN4sJEoU= +-----END CERTIFICATE-----""" + + +def test_secrets(admin_pc): + client = admin_pc.client + + name = random_str() + secret = client.create_secret(name=name, stringData={ + 'foo': 'bar' + }) + + assert secret.type == 'secret' + assert secret.kind == 'Opaque' + assert secret.name == name + assert secret.data.foo == 'YmFy' + + secret.data.baz = 'YmFy' + secret = client.update(secret, data=secret.data) + secret = client.reload(secret) + + assert secret.baseType == 'secret' + assert secret.type == 'secret' + assert secret.kind == 'Opaque' + assert secret.name == name + assert secret.data.foo == 'YmFy' + assert secret.data.baz == 'YmFy' + assert secret.namespaceId is None + assert 'namespace' not in secret.data + assert secret.projectId == admin_pc.project.id + + found = False + for i in client.list_secret(): + if i.id == secret.id: + found = True + break + + assert found + + client.delete(secret) + + +def test_certificates(admin_pc): + client = admin_pc.client + + name = random_str() + cert = client.create_certificate(name=name, key=KEY, certs=CERT) + assert cert.baseType == 'secret' + assert cert.expiresAt == '2026-06-28T01:13:32Z' + assert cert.type == 'certificate' + assert cert.name == name + assert cert.certs == CERT + assert cert.namespaceId is None + assert 'namespace' not in cert + + # cert = client.update(cert, certs='certdata2') + # cert = client.reload(cert) + # + # assert cert.baseType == 'secret' + # assert cert.type == 'certificate' + # assert cert.name == name + # assert cert.certs == 'certdata2' + # assert cert.namespaceId is None + # assert 'namespace' not in cert + # assert cert.projectId == pc.project.id + + found = False + for i in client.list_certificate(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_certificate(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_docker_credential(admin_pc): + client = admin_pc.client + + name = random_str() + registries = {'index.docker.io': { + 'username': 'foo', + 'password': 'bar', + }} + cert = client.create_docker_credential(name=name, + registries=registries) + assert cert.baseType == 'secret' + assert cert.type == 'dockerCredential' + assert cert.name == name + assert cert.registries['index.docker.io'].username == 'foo' + assert 'password' in cert.registries['index.docker.io'] + assert 'auth' in cert.registries['index.docker.io'] + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + registries['two'] = { + 'username': 'blah' + } + + cert = client.update(cert, registries=registries) + cert = client.reload(cert) + + assert cert.baseType == 'secret' + assert cert.type == 'dockerCredential' + assert cert.name == name + assert cert.registries['index.docker.io'].username == 'foo' + assert cert.registries.two.username == 'blah' + assert 'password' not in cert.registries['index.docker.io'] + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_docker_credential(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_docker_credential(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_basic_auth(admin_pc): + client = admin_pc.client + + name = random_str() + cert = client.create_basic_auth(name=name, + username='foo', + password='bar') + assert cert.baseType == 'secret' + assert cert.type == 'basicAuth' + assert cert.name == name + assert cert.username == 'foo' + assert 'password' in cert + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + cert = client.update(cert, username='foo2') + cert = client.reload(cert) + + assert cert.baseType == 'secret' + assert cert.type == 'basicAuth' + assert cert.name == name + assert cert.username == 'foo2' + assert 'password' not in cert + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_basic_auth(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_basic_auth(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_ssh_auth(admin_pc): + client = admin_pc.client + + name = random_str() + cert = client.create_ssh_auth(name=name, + privateKey='foo') + assert cert.baseType == 'secret' + assert cert.type == 'sshAuth' + assert cert.name == name + assert 'privateKey' in cert + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + cert = client.update(cert, privateKey='foo2') + cert = client.reload(cert) + assert cert.baseType == 'secret' + assert cert.type == 'sshAuth' + assert cert.name == name + assert 'privateKey' not in cert + assert cert.namespaceId is None + assert 'namespace' not in cert + assert cert.projectId == admin_pc.project.id + + found = False + for i in client.list_ssh_auth(): + if i.id == cert.id: + found = True + break + + assert found + + cert = client.by_id_ssh_auth(cert.id) + assert cert is not None + + client.delete(cert) + + +def test_secret_creation_kubectl(admin_mc, admin_cc, remove_resource): + name = random_str() + project = admin_mc.client.create_project(name=random_str(), + clusterId='local') + remove_resource(project) + namespace_name = random_str() + ns = admin_cc.client.create_namespace(name=namespace_name, + projectId=project.id) + remove_resource(ns) + + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + secrets_api = kubernetes.client.CoreV1Api(k8s_client) + + secret = kubernetes.client.V1Secret() + # Metadata + secret.metadata = kubernetes.client.V1ObjectMeta( + name=name, + namespace=namespace_name) + secret.string_data = {'tls.key': KEY, 'tls.crt': CERT} + secret.type = "kubernetes.io/tls" + + sec = secrets_api.create_namespaced_secret(namespace=namespace_name, + body=secret) + remove_resource(sec) + assert sec is not None + + # now get this through rancher api as namespacedCertificate + cert_id = namespace_name+':'+name + proj_client = user_project_client(admin_mc, project) + cert = proj_client.by_id_namespaced_certificate(cert_id) + assert cert is not None + assert "RSA" in cert['algorithm'] + assert cert['expiresAt'] is not None + assert cert['issuedAt'] is not None + + +def test_malformed_secret_parse(admin_mc, admin_cc, remove_resource): + name = random_str() + project = admin_mc.client.create_project(name=random_str(), + clusterId='local') + remove_resource(project) + namespace_name = random_str() + ns = admin_cc.client.create_namespace(name=namespace_name, + projectId=project.id) + remove_resource(ns) + + k8s_client = kubernetes_api_client(admin_mc.client, 'local') + secrets_api = kubernetes.client.CoreV1Api(k8s_client) + + secret = kubernetes.client.V1Secret() + # Metadata + secret.metadata = kubernetes.client.V1ObjectMeta( + name=name, + namespace=namespace_name) + secret.string_data = {'tls.key': KEY, 'tls.crt': MALFORMED_CERT} + secret.type = "kubernetes.io/tls" + + sec = secrets_api.create_namespaced_secret(namespace=namespace_name, + body=secret) + remove_resource(sec) + assert sec is not None + + # now get this through rancher api as namespacedCertificate + cert_id = namespace_name+':'+name + proj_client = user_project_client(admin_mc, project) + cert = proj_client.by_id_namespaced_certificate(cert_id) + assert cert is not None diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_settings.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_settings.py new file mode 100644 index 0000000..1ec89f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_settings.py @@ -0,0 +1,107 @@ +import pytest +from rancher import ApiError +from .common import random_str +from .conftest import wait_until + + +# cacerts is readOnly, and should not be able to be set through the API +def test_create_read_only(admin_mc, remove_resource): + client = admin_mc.client + + with pytest.raises(ApiError) as e: + client.create_setting(name="cacerts", value="a") + + assert e.value.error.status == 405 + assert "readOnly" in e.value.error.message + + +# cacerts is readOnly setting, and should not be able to be updated through API +def test_update_read_only(admin_mc, remove_resource): + client = admin_mc.client + + with pytest.raises(ApiError) as e: + client.update_by_id_setting(id="cacerts", value="b") + + assert e.value.error.status == 405 + assert "readOnly" in e.value.error.message + + +# cacerts is readOnly, and should be able to be read +def test_get_read_only(admin_mc, remove_resource): + client = admin_mc.client + client.by_id_setting(id="cacerts") + + +# cacerts is readOnly, and user should not be able to delete +def test_delete_read_only(admin_mc, remove_resource): + client = admin_mc.client + setting = client.by_id_setting(id="cacerts") + + with pytest.raises(ApiError) as e: + client.delete(setting) + + assert e.value.error.status == 405 + assert "readOnly" in e.value.error.message + + +# user should be able to create a setting that does not exist yet +def test_create(admin_mc, remove_resource): + client = admin_mc.client + setting = client.create_setting(name="samplesetting1", value="a") + remove_resource(setting) + + assert setting.value == "a" + + +# user should not be able to create a setting if it already exists +def test_create_existing(admin_mc, remove_resource): + client = admin_mc.client + setting = client.create_setting(name="samplefsetting2", value="a") + remove_resource(setting) + + with pytest.raises(ApiError) as e: + setting2 = client.create_setting(name="samplefsetting2", value="a") + remove_resource(setting2) + + assert e.value.error.status == 409 + assert e.value.error.code == "AlreadyExists" + + +# user should be able to update a setting if it exists +def test_update(admin_mc, remove_resource): + client = admin_mc.client + setting = client.create_setting(name="samplesetting3", value="a") + remove_resource(setting) + + setting = client.update_by_id_setting(id="samplesetting3", value="b") + assert setting.value == "b" + + +# user should not be able to update a setting if it does not exists +def test_update_nonexisting(admin_mc, remove_resource): + client = admin_mc.client + + with pytest.raises(ApiError) as e: + setting = client.update_by_id_setting(id="samplesetting4", value="a") + remove_resource(setting) + + assert e.value.error.status == 404 + assert e.value.error.code == "NotFound" + + +def test_update_link(admin_mc, user_factory, remove_resource): + client = admin_mc.client + setting = client.create_setting(name=random_str(), value="a") + remove_resource(setting) + wait_until(lambda: client.reload(setting) is not None) + + # admin should see update link + setting = client.reload(setting) + assert 'update' in setting.links + + # create standard user + user = user_factory() + + # this user should not be able to see update link + setting = user.client.reload(setting) + assert 'update' not in setting.links diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_app_creator.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_app_creator.py new file mode 100644 index 0000000..24e47ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_app_creator.py @@ -0,0 +1,38 @@ +from .common import random_str +import time +import pytest + + +@pytest.mark.skip +def test_system_app_creator(admin_mc, admin_system_pc, remove_resource): + client = admin_mc.client + provider_name = random_str() + access = random_str() + secret = random_str() + globaldns_provider = \ + client.create_global_dns_provider( + name=provider_name, + rootDomain="example.com", + route53ProviderConfig={ + 'accessKey': access, + 'secretKey': secret}) + remove_resource(globaldns_provider) + app = wait_for_system_app( + admin_system_pc.client, + "systemapp-"+globaldns_provider.name) + # the creator id of system app won't be listed in api + assert app.creatorId != globaldns_provider.creatorId + + +def wait_for_system_app(client, name, timeout=60): + start = time.time() + interval = 0.5 + apps = client.list_app(name=name) + while len(apps.data) != 1: + if time.time() - start > timeout: + print(apps) + raise Exception('Timeout waiting for workload service') + time.sleep(interval) + interval *= 2 + apps = client.list_app(name=name) + return apps.data[0] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_project.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_project.py new file mode 100644 index 0000000..312790f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_system_project.py @@ -0,0 +1,109 @@ +import pytest +from rancher import ApiError +from kubernetes.client import CoreV1Api +from .conftest import wait_for + +systemProjectLabel = "authz.management.cattle.io/system-project" +defaultProjectLabel = "authz.management.cattle.io/default-project" +initial_system_namespaces = set(["kube-node-lease", + "kube-system", + "cattle-system", + "kube-public", + "cattle-global-data", + "cattle-global-nt", + "cattle-fleet-system"]) +loggingNamespace = "cattle-logging" +operatorNamespace = "rancher-operator-system" + + +def test_system_project_created(admin_cc): + projects = admin_cc.management.client.list_project( + clusterId=admin_cc.cluster.id) + initial_projects = {} + initial_projects["Default"] = defaultProjectLabel + initial_projects["System"] = systemProjectLabel + required_projects = [] + + for project in projects: + name = project['name'] + if name in initial_projects: + projectLabel = initial_projects[name] + assert project['labels'].\ + data_dict()[projectLabel] == 'true' + required_projects.append(name) + + assert len(required_projects) == len(initial_projects) + + +@pytest.mark.skip +def test_system_namespaces_assigned(admin_cc): + projects = admin_cc.management.client.list_project( + clusterId=admin_cc.cluster.id) + systemProject = None + for project in projects: + if project['name'] == "System": + systemProject = project + break + assert systemProject is not None + + system_namespaces = admin_cc.client.list_namespace( + projectId=systemProject.id) + system_namespaces_names = set( + [ns['name'] for ns in system_namespaces]) + + # If clusterLogging tests run before this, cattle-logging + # will be present in current system_namespaces, removing it + if loggingNamespace in system_namespaces_names: + system_namespaces_names.remove(loggingNamespace) + if operatorNamespace in system_namespaces_names: + system_namespaces_names.remove(operatorNamespace) + + assert initial_system_namespaces.issubset(system_namespaces_names) + + +def test_system_project_cant_be_deleted(admin_mc, admin_cc): + """The system project is not allowed to be deleted, test to ensure that is + true + """ + projects = admin_cc.management.client.list_project( + clusterId=admin_cc.cluster.id) + system_project = None + for project in projects: + if project['name'] == "System": + system_project = project + break + assert system_project is not None + + # Attempting to delete the template should raise an ApiError + with pytest.raises(ApiError) as e: + admin_mc.client.delete(system_project) + assert e.value.error.status == 405 + assert e.value.error.message == 'System Project cannot be deleted' + + +def test_system_namespaces_default_svc_account(admin_mc): + system_namespaces_setting = admin_mc.client.by_id_setting( + "system-namespaces") + system_namespaces = system_namespaces_setting["value"].split(",") + k8sclient = CoreV1Api(admin_mc.k8s_client) + def_saccnts = k8sclient.list_service_account_for_all_namespaces( + field_selector='metadata.name=default') + for sa in def_saccnts.items: + ns = sa.metadata.namespace + + def _check_system_sa_flag(): + if ns in system_namespaces and ns != "kube-system": + if sa.automount_service_account_token is False: + return True + else: + return False + else: + return True + + def _sa_update_fail(): + name = sa.metadata.name + flag = sa.automount_service_account_token + return 'Service account {} in namespace {} does not have correct \ + automount_service_account_token flag: {}'.format(name, ns, flag) + + wait_for(_check_system_sa_flag, fail_handler=_sa_update_fail) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_tokens.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_tokens.py new file mode 100644 index 0000000..5a6474c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_tokens.py @@ -0,0 +1,111 @@ +import pytest +import rancher +import requests +import time +from .conftest import SERVER_PASSWORD, BASE_URL, AUTH_URL, protect_response + + +def test_certificates(admin_mc): + client = admin_mc.client + + tokens = client.list_token() + + currentCount = 0 + for t in tokens: + if t.current: + assert t.userId == admin_mc.user.id + currentCount += 1 + + assert currentCount == 1 + + +def test_websocket(admin_mc): + client = rancher.Client(url=BASE_URL, token=admin_mc.client.token, + verify=False) + # make a request that looks like a websocket + client._session.headers["Connection"] = "upgrade" + client._session.headers["Upgrade"] = "websocket" + client._session.headers["Origin"] = "badStuff" + client._session.headers["User-Agent"] = "Mozilla" + # do something with client now that we have a "websocket" + + with pytest.raises(rancher.ApiError) as e: + client.list_cluster() + + assert e.value.error.Code.Status == 403 + + +def test_api_token_ttl(admin_mc, remove_resource): + client = admin_mc.client + + max_ttl = client.by_id_setting("auth-token-max-ttl-minutes") + max_ttl_mins = int(max_ttl["value"]) + + # api tokens must be created with min(input_ttl, max_ttl) + token = client.create_token(ttl=0) + remove_resource(token) + + token_ttl_mins = mins(token["ttl"]) + + assert token_ttl_mins == max_ttl_mins + + +@pytest.mark.nonparallel +def test_kubeconfig_token_ttl(admin_mc, user_mc): + client = admin_mc.client + + # delete existing kubeconfig token + kubeconfig_token_name = "kubeconfig-" + admin_mc.user.id + token = client.by_id_token(kubeconfig_token_name) + if token is not None: + client.delete(token) + + # disable kubeconfig generation setting + client.update_by_id_setting(id="kubeconfig-generate-token", value="false") + + # update kubeconfig ttl setting for test + kubeconfig_ttl_mins = 0.01 + client.update_by_id_setting( + id="kubeconfig-default-token-ttl-minutes", + value=kubeconfig_ttl_mins) + + # call login action for kubeconfig token + kubeconfig_token = login() + ttl1, token1 = get_token_and_ttl(kubeconfig_token) + assert ttl1 == kubeconfig_ttl_mins + + # wait for token to expire + time.sleep(kubeconfig_ttl_mins*60) + + # confirm new kubeconfig token gets generated + kubeconfig_token2 = login() + ttl2, token2 = get_token_and_ttl(kubeconfig_token2) + assert ttl2 == kubeconfig_ttl_mins + assert token1 != token2 + + # reset kubeconfig ttl setting + client.update_by_id_setting(id="kubeconfig-default-token-ttl-minutes", + value="43200") + + # enable kubeconfig generation setting + client.update_by_id_setting(id="kubeconfig-generate-token", value="true") + + +def login(): + r = requests.post(AUTH_URL, json={ + 'username': 'admin', + 'password': SERVER_PASSWORD, + 'responseType': 'kubeconfig', + }, verify=False) + protect_response(r) + return r.json() + + +def get_token_and_ttl(token): + token1_ttl_mins = mins(int(token["ttl"])) + token1_token = token["token"] + return token1_ttl_mins, token1_token + + +def mins(time_millisec): + return time_millisec / 60000 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_users.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_users.py new file mode 100644 index 0000000..5a0b51e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_users.py @@ -0,0 +1,149 @@ +import pytest +from kubernetes.client import CustomObjectsApi +from rancher import ApiError +from .conftest import random_str, wait_for + +grbAnno = "cleanup.cattle.io/grbUpgradeCluster" +rtAnno = "cleanup.cattle.io/rtUpgradeCluster" + + +def test_user_cant_delete_self(admin_mc): + client = admin_mc.client + with pytest.raises(ApiError) as e: + client.delete(admin_mc.user) + + assert e.value.error.status == 422 + + +def test_user_cant_deactivate_self(admin_mc): + client = admin_mc.client + with pytest.raises(ApiError) as e: + client.update(admin_mc.user, enabled=False) + + assert e.value.error.status == 422 + + +def test_user_cant_use_username_as_password(user_mc): + client = user_mc.client + with pytest.raises(ApiError) as e: + client.create_user(username="administrator", password="administrator") + + assert e.value.error.status == 422 + + +def test_password_too_short(user_mc): + client = user_mc.client + with pytest.raises(ApiError) as e: + client.create_user(username="testuser", password="tooshort") + + assert e.value.error.status == 422 + + +def test_globalrolebinding_finalizer_cleanup(admin_mc, remove_resource): + """This ensures that globalrolebinding cleanup of clusters < v2.2.8 + is performed correctly""" + client = admin_mc.client + grb = client.create_globalRoleBinding( + globalRoleId="admin", userId="u-" + random_str() + ) + remove_resource(grb) + assert grb.annotations[grbAnno] == "true" + + # create a grb without the rancher api with a bad finalizer + api = CustomObjectsApi(admin_mc.k8s_client) + json = { + "apiVersion": "management.cattle.io/v3", + "globalRoleName": "admin", + "kind": "GlobalRoleBinding", + "metadata": { + "finalizers": ["clusterscoped.controller.cattle.io/grb-sync_fake"], + "generation": 1, + "name": "grb-" + random_str(), + }, + "userName": "u-" + random_str(), + } + grb_k8s = api.create_cluster_custom_object( + group="management.cattle.io", + version="v3", + plural="globalrolebindings", + body=json, + ) + grb_name = grb_k8s["metadata"]["name"] + grb_k8s = client.by_id_globalRoleBinding(id=grb_name) + remove_resource(grb_k8s) + + def check_annotation(): + grb1 = client.by_id_globalRoleBinding(grb_k8s.id) + try: + if grb1.annotations[grbAnno] == "true": + return True + else: + return False + except (AttributeError, KeyError): + return False + + wait_for(check_annotation, fail_handler=lambda: "annotation was not added") + grb1 = api.get_cluster_custom_object( + group="management.cattle.io", + version="v3", + plural="globalrolebindings", + name=grb_k8s.id, + ) + if "finalizers" in grb1["metadata"]: + assert ( + "clusterscoped.controller.cattle.io/grb-sync_fake" + not in grb1["metadata"]["finalizers"] + ) + + +def test_roletemplate_finalizer_cleanup(admin_mc, remove_resource): + """ This ensures that roletemplates cleanup for clusters < v2.2.8 + is performed correctly""" + client = admin_mc.client + rt = client.create_roleTemplate(name="rt-" + random_str()) + remove_resource(rt) + assert rt.annotations[rtAnno] == "true" + + # create rt without rancher api with a bad finalizer + api = CustomObjectsApi(admin_mc.k8s_client) + json = { + "apiVersion": "management.cattle.io/v3", + "kind": "RoleTemplate", + "metadata": { + "finalizers": [ + "clusterscoped.controller.cattle.io/" + + "cluster-roletemplate-sync_fake", + "fake-finalizer" + ], + "name": "test-" + random_str(), + } + } + rt_k8s = api.create_cluster_custom_object( + group="management.cattle.io", + version="v3", + plural="roletemplates", + body=json, + ) + rt_name = rt_k8s["metadata"]["name"] + rt_k8s = client.by_id_roleTemplate(id=rt_name) + remove_resource(rt_k8s) + + def check_annotation(): + rt1 = client.by_id_roleTemplate(rt_k8s.id) + try: + if rt1.annotations[rtAnno] == "true": + return True + else: + return False + except (AttributeError, KeyError): + return False + wait_for(check_annotation, fail_handler=lambda: "annotation was not added") + rt1 = api.get_cluster_custom_object( + group="management.cattle.io", + version="v3", + plural="roletemplates", + name=rt_k8s.id, + ) + if "finalizers" in rt1["metadata"]: + assert "clusterscoped.controller.cattle.io/grb-sync_fake" \ + not in rt1["metadata"]["finalizers"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_workloads.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_workloads.py new file mode 100644 index 0000000..7dd44e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/suite/test_workloads.py @@ -0,0 +1,470 @@ +from .common import random_str +from rancher import ApiError +from .conftest import wait_for, wait_until_available, user_project_client + +import time +import pytest + + +def test_workload_image_change_private_registry(admin_pc): + client = admin_pc.client + + registry1_name = random_str() + registries = {'index.docker.io': { + 'username': 'testuser', + 'password': 'foobarbaz', + }} + registry1 = client.create_dockerCredential(name=registry1_name, + registries=registries) + assert registry1.name == registry1_name + + registry2_name = random_str() + registries = {'quay.io': { + 'username': 'testuser', + 'password': 'foobarbaz', + }} + registry2 = client.create_dockerCredential(name=registry2_name, + registries=registries) + + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'testuser/testimage', + }]) + + assert workload.name == name + assert len(workload.imagePullSecrets) == 1 + for secret in workload.imagePullSecrets: + assert secret['name'] == registry1_name + + containers = [{ + 'name': 'one', + 'image': 'quay.io/testuser/testimage', + }] + + workload = client.update(workload, containers=containers) + + for container in workload.containers: + assert container['image'] == 'quay.io/testuser/testimage' + + assert len(workload.imagePullSecrets) == 1 + + assert workload.imagePullSecrets[0]['name'] == registry2_name + + client.delete(registry1) + client.delete(registry2) + client.delete(ns) + + +def test_workload_ports_change(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + # create workload with no ports assigned + # and verify headless service is created + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + svc = wait_for_service_create(client, name) + assert svc.clusterIp is None + assert svc.name == workload.name + assert svc.kind == "ClusterIP" + + # update workload with port, and validate cluster ip is set + ports = [{ + 'sourcePort': '0', + 'containerPort': '80', + 'kind': 'ClusterIP', + 'protocol': 'TCP', }] + client.update(workload, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + 'ports': ports, + }]), + svc = wait_for_service_cluserip_set(client, name) + assert svc.clusterIp is not None + + # update workload with no ports, and validate cluster ip is reset + client.update(workload, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + 'ports': [], + }]), + svc = wait_for_service_cluserip_reset(client, name) + assert svc.clusterIp is None + + client.delete(ns) + + +def test_workload_probes(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + # create workload with probes + name = random_str() + container = { + 'name': 'one', + 'image': 'nginx', + 'livenessProbe': { + 'failureThreshold': 3, + 'initialDelaySeconds': 10, + 'periodSeconds': 2, + 'successThreshold': 1, + 'tcp': False, + 'timeoutSeconds': 2, + 'host': 'localhost', + 'path': '/healthcheck', + 'port': 80, + 'scheme': 'HTTP', + }, + 'readinessProbe': { + 'failureThreshold': 3, + 'initialDelaySeconds': 10, + 'periodSeconds': 2, + 'successThreshold': 1, + 'timeoutSeconds': 2, + 'tcp': True, + 'host': 'localhost', + 'port': 80, + }, + } + workload = client.create_workload(name=name, + namespaceId=ns.id, + scale=1, + containers=[container]) + assert workload.containers[0].livenessProbe.host == 'localhost' + assert workload.containers[0].readinessProbe.host == 'localhost' + container['livenessProbe']['host'] = 'updatedhost' + container['readinessProbe']['host'] = 'updatedhost' + workload = client.update(workload, + namespaceId=ns.id, + scale=1, + containers=[container]) + assert workload.containers[0].livenessProbe.host == 'updatedhost' + assert workload.containers[0].readinessProbe.host == 'updatedhost' + client.delete(ns) + + +def test_workload_scheduling(admin_pc): + client = admin_pc.client + ns = admin_pc.cluster.client.create_namespace(name=random_str(), + projectId=admin_pc. + project.id) + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + scheduling={ + "scheduler": "some-scheduler", + }, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + assert workload.scheduling.scheduler == "some-scheduler" + workload = client.update(workload, + namespaceId=ns.id, + scale=1, + scheduling={ + "scheduler": "test-scheduler", + }, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]), + assert workload[0].scheduling.scheduler == "test-scheduler" + client.delete(ns) + + +def test_statefulset_workload_volumemount_subpath(admin_pc): + client = admin_pc.client + # setup + name = random_str() + + # valid volumeMounts + volumeMounts = [{ + 'name': 'vol1', + 'mountPath': 'var/lib/mysql', + 'subPath': 'mysql', + }] + + containers = [{ + 'name': 'mystatefulset', + 'image': 'ubuntu:xenial', + 'volumeMounts': volumeMounts, + }] + + # invalid volumeMounts + volumeMounts_one = [{ + 'name': 'vol1', + 'mountPath': 'var/lib/mysql', + 'subPath': '/mysql', + }] + + containers_one = [{ + 'name': 'mystatefulset', + 'image': 'ubuntu:xenial', + 'volumeMounts': volumeMounts_one, + }] + + volumeMounts_two = [{ + 'name': 'vol1', + 'mountPath': 'var/lib/mysql', + 'subPath': '../mysql', + }] + + containers_two = [{ + 'name': 'mystatefulset', + 'image': 'ubuntu:xenial', + 'volumeMounts': volumeMounts_two, + }] + + statefulSetConfig = { + 'podManagementPolicy': 'OrderedReady', + 'revisionHistoryLimit': 10, + 'strategy': 'RollingUpdate', + 'type': 'statefulSetConfig', + } + + volumes = [{ + 'name': 'vol1', + 'persistentVolumeClaim': { + 'persistentVolumeClaimId': "default: myvolume", + 'readOnly': False, + 'type': 'persistentVolumeClaimVolumeSource', + }, + 'type': 'volume', + }] + + # 1. validate volumeMounts.subPath when workload creating + # invalid volumeMounts.subPath: absolute path + with pytest.raises(ApiError) as e: + client.create_workload(name=name, + namespaceId='default', + scale=1, + containers=containers_one, + statefulSetConfig=statefulSetConfig, + volumes=volumes) + + assert e.value.error.status == 422 + + # invalid volumeMounts.subPath: contains '..' + with pytest.raises(ApiError) as e: + client.create_workload(name=name, + namespaceId='default', + scale=1, + containers=containers_two, + statefulSetConfig=statefulSetConfig, + volumes=volumes) + + assert e.value.error.status == 422 + + # 2. validate volumeMounts.subPath when workload update + # create a validate workload then update + workload = client.create_workload(name=name, + namespaceId='default', + scale=1, + containers=containers, + statefulSetConfig=statefulSetConfig, + volumes=volumes) + + with pytest.raises(ApiError) as e: + client.update(workload, + namespaceId='default', + scale=1, + containers=containers_one, + statefulSetConfig=statefulSetConfig, + volumes=volumes) + + assert e.value.error.status == 422 + + with pytest.raises(ApiError) as e: + client.update(workload, + namespaceId='default', + scale=1, + containers=containers_two, + statefulSetConfig=statefulSetConfig, + volumes=volumes) + + assert e.value.error.status == 422 + + +def test_workload_redeploy(admin_pc, remove_resource): + client = admin_pc.client + + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=admin_pc.project.id) + remove_resource(ns) + + name = random_str() + workload = client.create_workload( + name=name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + remove_resource(workload) + + client.action(workload, 'redeploy') + + def _timestamp_reset(): + workloads = client.list_workload(uuid=workload.uuid).data + return len(workloads) > 0 and workloads[0].annotations[ + 'cattle.io/timestamp'] is not None + + wait_for(_timestamp_reset, + fail_handler=lambda: 'Timed out waiting for timestamp reset') + + +def test_perform_workload_action_read_only(admin_mc, admin_pc, remove_resource, + user_mc, user_factory): + """Tests workload actions with a read-only user and a member user. + Note: this test exists only in 2.5+ due to pod scheduling on the + local cluster. Manually ensure that any changes in 2.4 and below + work.""" + client = admin_pc.client + project = admin_pc.project + user = user_mc + user_member = user_factory() + + ns = admin_pc.cluster.client.create_namespace( + name=random_str(), + projectId=project.id) + remove_resource(ns) + + # Create a read-only user binding. + prtb1 = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user.user.id, + projectId=project.id, + roleTemplateId="read-only") + remove_resource(prtb1) + wait_until_available(user.client, project) + + # Then, create a member user binding. + prtb2 = admin_mc.client.create_project_role_template_binding( + name="prtb-" + random_str(), + userId=user_member.user.id, + projectId=project.id, + roleTemplateId="project-member") + remove_resource(prtb2) + wait_until_available(user_member.client, project) + user_pc = user_project_client(user, project) + user_member_pc = user_project_client(user_member, project) + + # Admin user creates the workload. + workload_name = random_str() + workload = client.create_workload( + name=workload_name, + namespaceId=ns.id, + scale=1, + containers=[{ + 'name': 'foo', + 'image': 'rancher/mirrored-library-nginx:1.21.1-alpine', + 'env': [{ + 'name': 'FOO_KEY', + 'value': 'FOO_VALUE', + }] + }]) + remove_resource(workload) + wait_for_workload(client, workload.id, ns.id) + + # Admin user updates the workload to yield a rollback option. + workload.containers = [{ + 'name': 'foo', + 'image': 'rancher/mirrored-library-nginx:1.21.1-alpine', + 'env': [{ + 'name': 'BAR_KEY', + 'value': 'BAR_VALUE', + }] + }] + workload = client.reload(workload) + workload = client.update_by_id_workload(workload.id, workload) + + workload = client.reload(workload) + wait_for_workload(client, workload.id, ns.id) + original_rev_id = workload.revisions().data[0].id + + # Read-only users should receive a 404 error. + with pytest.raises(ApiError) as e: + workload = client.reload(workload) + user_pc.action(obj=workload, action_name="rollback", + replicaSetId=original_rev_id) + assert e.value.error.status == 404 + + # Member users will be able to perform the rollback. + workload = client.reload(workload) + user_member_pc.action(obj=workload, action_name="rollback", + replicaSetId=original_rev_id) + + +def wait_for_service_create(client, name, timeout=30): + start = time.time() + services = client.list_service(name=name, kind="ClusterIP") + while len(services) == 0: + time.sleep(.5) + services = client.list_service(name=name, kind="ClusterIP") + if time.time() - start > timeout: + raise Exception('Timeout waiting for workload service') + return services.data[0] + + +def wait_for_service_cluserip_set(client, name, timeout=30): + start = time.time() + services = client.list_service(name=name, kind="ClusterIP") + while len(services) == 0 or services.data[0].clusterIp is None: + time.sleep(.5) + services = client.list_service(name=name, kind="ClusterIP") + if time.time() - start > timeout: + raise Exception('Timeout waiting for workload service') + return services.data[0] + + +def wait_for_service_cluserip_reset(client, name, timeout=30): + start = time.time() + services = client.list_service(name=name, kind="ClusterIP") + while len(services) == 0 or services.data[0].clusterIp is not None: + time.sleep(.5) + services = client.list_service(name=name, kind="ClusterIP") + if time.time() - start > timeout: + raise Exception('Timeout waiting for workload service') + return services.data[0] + + +def wait_for_workload(client, workload_id, workload_ns, timeout=30): + def _is_found(): + workloads = client.list_workload(namespaceId=workload_ns) + for workload in workloads.data: + if workload.id == workload_id: + return True + return False + start = time.time() + while not _is_found(): + time.sleep(.5) + if time.time() - start > timeout: + raise Exception("Timeout waiting for workload") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/tox.ini b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/tox.ini new file mode 100644 index 0000000..8f887b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/integration/tox.ini @@ -0,0 +1,25 @@ +[tox] +envlist = flake8,rancher + +[testenv] +basepython = python3.10 +passenv = + CATTLE_TEST_URL + RANCHER_SERVER_PASSWORD + +[testenv:flake8] +deps = + flake8===3.7.9 +changedir = {toxinidir} +commands = flake8 suite + +[testenv:rancher] +deps = -rrequirements.txt +changedir = suite +commands = pytest --durations=20 -rfE -v {posargs} + +[pytest] +timeout = 300 +faulthandler_timeout = 300 +markers = + nonparallel: mark a test as non-parallel. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/kev2/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/kev2/README.md new file mode 100644 index 0000000..2fb11fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/kev2/README.md @@ -0,0 +1,56 @@ +# KEv2 Unit Tests + +KEv2 integration (unit) tests tests code functionality in the rancher/rancher handler for each KEv2 cloud provider (AKS EKS and GKE). The tests are written using the [Go Test Framework](https://pkg.go.dev/testing) and [MockCompose](https://github.com/kelveny/mockcompose). They mock the cluster state and `AKSClusterConfig` objects using test files to simulate reactions to a real cluster, and mock any mockable Interfaces used by the OperatorController. Test files are located in each handler folder and data used by the tests are located in a `/test` sub folder. The unit test structure is different from `rancher/rancher/tests` because [Go Test Framework](https://pkg.go.dev/testing) requires test files to be in the same package as the source code. + +## File structure + +## Requirements + +--- + +To run kev2 unit tests you will need: +- [golang 1.17](https://go.dev/doc/install) + +## File Structure + +--- + +``` +rancher/rancher +-> pkg/controllers/management/aks + -> aks_cluster_handler.go + -> aks_cluster_handler_test.go + -> tests/ + -> test1.yaml + -> test2.json +``` + +## How to Run Unit Tests + +Clone the repo + +``` +Git clone rancher/rancher +cd rancher +``` + +If you want to test each provider separately + +``` +go test -v ./pkg/controllers/management/aks +go test -v ./pkg/controllers/management/eks +go test -v ./pkg/controllers/management/gke +``` + +If you want to run all tests + +``` +go test -v ./pkg/controllers/management/aks ./pkg/controllers/management/eks ./pkg/controllers/management/gke +``` + +If you want to check test coverage (example: 72.5% of statements) + +``` +go test (or alias command) -coverprofile=coverage.out +go tool cover -html=coverage.out +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Dockerfile new file mode 100644 index 0000000..9b0e6c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Dockerfile @@ -0,0 +1,58 @@ +FROM ubuntu:22.04 +WORKDIR /usr/app/src + +ARG AWS_ACCESS_KEY_ID +ENV AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID +ARG AWS_SECRET_ACCESS_KEY +ENV AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY +ARG AZURE_AKS_SUBSCRIPTION_ID +ENV AZURE_SUBSCRIPTION_ID=$AZURE_AKS_SUBSCRIPTION_ID +ARG AZURE_TENANT_ID +ENV AZURE_TENANT_ID=$AZURE_TENANT_ID +ARG AZURE_CLIENT_ID +ENV AZURE_CLIENT_ID=$AZURE_CLIENT_ID +ARG AZURE_CLIENT_SECRET +ENV AZURE_CLIENT_SECRET=$AZURE_CLIENT_SECRET +ARG RANCHER_LINODE_ACCESSKEY +ENV RANCHER_LINODE_CREDENTIAL=$RANCHER_LINODE_ACCESSKEY + +ARG OVERRIDE_REGION +ENV OVERRIDE_REGION=$OVERRIDE_REGION + +ARG USER_KEYS +ENV USER_KEYS=$USER_KEYS +ARG DONOTDELETE_KEYS +ENV DONOTDELETE_KEYS=$DONOTDELETE_KEYS + +ENV CUSTODIAN_YAML=aws.yaml + +ENV GOOGLE_APPLICATION_CREDENTIALS=google_credentials.json +ENV GOOGLE_CLOUD_PROJECT=ei-container-platform-qa + +ADD ./* ./ +SHELL ["/bin/bash", "-c"] + +RUN apt-get update && apt-get install -y python3 python3-pip python3-venv apt-transport-https ca-certificates gnupg curl +RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && apt-get update -y && apt-get install google-cloud-cli -y +RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash + +RUN python3 -m venv custodian-venv +RUN . custodian-venv/bin/activate +RUN pip3 install c7n c7n_azure c7n_gcp c7n_mailer + +RUN az login -u ${AZURE_CLIENT_ID} --service-principal -p ${AZURE_CLIENT_SECRET} --tenant ${AZURE_TENANT_ID} > /dev/null +RUN gcloud auth activate-service-account --key-file $GOOGLE_APPLICATION_CREDENTIALS > /dev/null + +CMD for i in `ls *.yaml`; \ + do cat $i | sed -e 's/USERKEYS/'"${USER_KEYS}"'/g' -i $i; done ; \ + echo $USER_KEYS; \ + for i in `ls *.yaml`; \ + do cat $i | sed -e 's/DONOTDELETEKEYS/'"${DONOTDELETE_KEYS}"'/g' -i $i; done; \ + if [ "$CUSTODIAN_YAML" = "aws.yaml" ] ; then \ + custodian run --output-dir=. --region="us-east-2" --dry-run ${CUSTODIAN_YAML}; \ + custodian run --output-dir=. --region="us-east-1" --dry-run ${CUSTODIAN_YAML}; \ + custodian run --output-dir=. --region="us-west-1" --dry-run ${CUSTODIAN_YAML}; \ + custodian run --output-dir=. --region="us-west-2" --dry-run ${CUSTODIAN_YAML}; \ + elif [ "$CUSTODIAN_YAML" = "tag-to-save.yaml" ] ; then \ + custodian run --output-dir=. --region=$OVERRIDE_REGION --dry-run ${CUSTODIAN_YAML}; \ + else custodian run --output-dir=. --dry-run ${CUSTODIAN_YAML}; fi; \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Jenkinsfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Jenkinsfile new file mode 100644 index 0000000..0fd436c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/Jenkinsfile @@ -0,0 +1,86 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/tests/scripts/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def imageName = "qa-custodian-${job_name}${env.BUILD_NUMBER}" + def testResultsOut = "results.xml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def awsYaml="aws.yaml" + def azureYaml="azure.yaml" + def gcpYaml="gcp.yaml" + if ("${env.CUSTODIAN_YAML}" != "null" && "${env.CUSTODIAN_YAML}" != "") { + yamlToRun="${env.CUSTODIAN_YAML}" + } + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + def repo = scm.userRemoteConfigs + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + repo = [[url: "${env.REPO}"]] + } + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + + string(credentialsId: 'DONOTDELETE_KEYS', variable: 'DONOTDELETE_KEYS'), + string(credentialsId: 'USER_KEYS', variable: 'USER_KEYS'), + + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'AZURE_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: repo + ]) + } + dir ("./tests/scripts/custodian/") { + stage('Build Docker Image') { + try { + def decoded = new String(RANCHER_GKE_CREDENTIAL.decodeBase64()) + writeFile file: 'google_credentials.json', text: decoded + sh "docker build -t ${imageName} -f Dockerfile . --build-arg AWS_ACCESS_KEY_ID=\"${AWS_ACCESS_KEY_ID}\" --build-arg AWS_SECRET_ACCESS_KEY=\"${AWS_SECRET_ACCESS_KEY}\" --build-arg AZURE_AKS_SUBSCRIPTION_ID=\"${AZURE_AKS_SUBSCRIPTION_ID}\" --build-arg AZURE_TENANT_ID=\"${AZURE_TENANT_ID}\" --build-arg AZURE_CLIENT_ID=\"${AZURE_CLIENT_ID}\" --build-arg AZURE_CLIENT_SECRET=\"${AZURE_CLIENT_SECRET}\" --build-arg RANCHER_LINODE_ACCESSKEY=\"${RANCHER_LINODE_ACCESSKEY}\"" + } + catch(err) { + echo 'Docker Build had partial failures...' + echo "${err}" + } + } + stage('Run Docker Image for Adding Tags') { + // if a user only wants to run the test using a subset of keys, they can pass in OVERRIDE_REGION + if ("${env.OVERRIDE_REGION}" != "null" && "${env.OVERRIDE_REGION}" != "") { + sh "docker run --privileged --name ${testContainer} -e CUSTODIAN_YAML=\"add-friday-tags.yaml\" -e OVERRIDE_REGION=\"${env.OVERRIDE_REGION}\" -e DONOTDELETE_KEYS=\"${DONOTDELETE_KEYS}\" -e USER_KEYS=\"${USER_KEYS}\" ${imageName} " + } else { + echo "No OVERRIDE_REGION passed in, running all tests" + } + } + stage('Run Docker Image for AWS,Azure, and GCP'){ + sh "docker run --privileged --name ${testContainer} -e CUSTODIAN_YAML=\"${CUSTODIAN_YAML}\" -e DONOTDELETE_KEYS=\"${DONOTDELETE_KEYS}\" -e USER_KEYS=\"${USER_KEYS}\" ${imageName}" + } + } // dir + } // creds + } // folder properties + } +}// node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/README.md new file mode 100644 index 0000000..8b2e57c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/README.md @@ -0,0 +1,22 @@ +# QA Cloud Custodian + +QA custodian will clean up resources in AWS, GCR, and AZURE. Currently, we have automation configured for: +* AWS + * instances + * NLBs + * EKS +* AZURE + * VMs + * AKS +* GCP + * instances + +### Getting Started +New Hires - make a PR adding one line to the `user-keys.txt` file. Use that key in ALL resources you create when using SUSE resources. Keep it short (6 characters or less) unique to you, and recognizable by others (And, this is case sensitive!). For example, if your name was Jane Elaine Morrison, something like `jem` would suffice. Just make sure you can remember it, and others can know who's it is if they are on your team. + +### About the Code +This suite is fairly simple, and runs using [Cloud Custodian](https://cloud-custodian.github.io/cloud-custodian/docs/quickstart/index.html). Our modifications consist of the following: +* text files + * `*-keys.txt` representing special keys that correspond with QA's resources + * `regions.txt` (AWS explicit) representing the regions we use on a regular basis, and therefore what the custodian will check against +* `.yaml` files, which are different configurations for the custodian to use when running. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/aws.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/aws.yaml new file mode 100644 index 0000000..f4aa883 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/aws.yaml @@ -0,0 +1,262 @@ +policies: +- name: mark-unknown-instances-for-deletion + resource: aws.ec2 + description: | + Mark unknown user instances for deletion in 1 day + filters: + - "State.Name": running + # instance name not in accepted user keys + - type: value + key: tag:Name + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_known_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_unknown_user + op: terminate + days: 1 + +- name: mark-known-instances-for-deletion + resource: aws.ec2 + description: | + Mark known user instances for deletion in 2 days + filters: + - "State.Name": running + - type: value + key: tag:Name + op: regex + value: "^.*USERKEYS.*$" + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_unknown_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_known_user + op: terminate + days: 2 + +- name: ec2-unmark-if-friday-tagged + resource: aws.ec2 + description: | + Remove the deletion tag from any resource group which now contain resources + so it doesn't get deleted by the following policy + filters: + - or: + - "tag:ec2_unknown_user": not-null + - "tag:ec2_known_user": not-null + - "tag:DeletesOnFriday": present + actions: + - type: remove-tag + tags: ['ec2_unknown_user', 'ec2_known_user'] + +- name: ec2-terminate-instances + resource: aws.ec2 + description: | + Delete any marked instances which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + tag: ec2_unknown_user + op: terminate + - type: marked-for-op + tag: ec2_known_user + op: terminate + actions: + - type: terminate + +# EKS Policies +# Note: cannot manage EKS nodegroups at this time, but the +# above ec2 policies should take care of any nodes + +# There is a resource for eks-nodegroup in cloud custodian, +# however there is no support for time delay nor tagging. + +# EKS +- name: eks-mark-unknown-instances-for-deletion + resource: aws.eks + description: | + Mark unknown user instances for deletion in 1 day + filters: + - type: value + key: name + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_known_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_unknown_user + op: delete + days: 1 + +- name: eks-mark-known-instances-for-deletion + resource: aws.eks + description: | + Mark known user instances for deletion in 2 days + filters: + - type: value + key: name + op: regex + value: "^.*USERKEYS.*$" + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_unknown_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_known_user + op: delete + days: 2 + +- name: eks-unmark-if-friday-tagged + resource: aws.eks + description: | + Remove the deletion tag from any resource group which now contain resources + so it doesn't get deleted by the following policy + filters: + - or: + - "tag:ec2_unknown_user": not-null + - "tag:ec2_known_user": not-null + - "tag:DeletesOnFriday": present + actions: + - type: remove-tag + tags: ['ec2_unknown_user', 'ec2_known_user'] + +- name: eks-terminate-instances + resource: aws.eks + description: | + Delete any marked instances which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + tag: ec2_unknown_user + op: delete + - type: marked-for-op + tag: ec2_known_user + op: delete + actions: + - type: delete + +# NLBs +- name: mark-unknown-nlbs-for-deletion + resource: app-elb + filters: + # nlb name not in accepted user keys + - type: value + key: LoadBalancerArn + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_known_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: LoadBalancerArn + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_unknown_user + op: delete + days: 1 + ### option for notifying slack / via email (needs lambda permissions) + # - type: notify + # slack_template: slack_default + # slack_msg_color: danger + # violation_desc: No violation. + # action_desc: No action taken. + # to: + # - https://hooks.slack.com/services/T0000000000/B000000000/XXXXXXXXXXXXXXX + # transport: + # type: sqs + # queue: queue-url + +- name: mark-known-nlbs-for-deletion + resource: app-elb + filters: + # nlb is named with accepted user key + - type: value + key: LoadBalancerArn + op: regex + value: "^.*USERKEYS.*$" + # nlb is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:ec2_unknown_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: LoadBalancerArn + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: ec2_known_user + op: delete + days: 2 + +- name: nlb-unmark-if-friday-tagged + resource: app-elb + description: | + Remove the deletion tag from any resource group which now contain resources + so it doesn't get deleted by the following policy + filters: + - or: + - "tag:ec2_unknown_user": not-null + - "tag:ec2_known_user": not-null + - "tag:DeletesOnFriday": present + actions: + - type: remove-tag + tags: ['ec2_unknown_user', 'ec2_known_user'] + +- name: ec2-delete-nlbs + resource: app-elb + description: | + Delete any marked nlbs which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + tag: ec2_unknown_user + op: delete + - type: marked-for-op + tag: ec2_known_user + op: delete + actions: + - type: delete \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/azure.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/azure.yaml new file mode 100644 index 0000000..bc6ced2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/azure.yaml @@ -0,0 +1,141 @@ +# Azure Policies +policies: +# VMs +- name: az-mark-unknown-vms-for-deletion + resource: azure.vm + description: | + Mark unknown user instances for deletion in 1 day + filters: + # instance name not in accepted user keys + - type: value + key: name + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:known_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: unknown_user + op: delete + days: 1 + +- name: az-mark-known-vms-for-deletion + resource: azure.vm + description: | + Mark known user instances for deletion in 2 days + filters: + # instance is named with accepted user key + - type: value + key: name + op: regex + value: "^.*USERKEYS.*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:unknown_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: known_user + op: delete + days: 2 + +- name: azure-terminate-vms + resource: azure.vm + description: | + Delete any marked instances which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + tag: unknown_user + op: delete + - type: marked-for-op + tag: known_user + op: delete + actions: + - type: delete + +# AKS +- name: az-mark-unknown-aks-for-deletion + resource: azure.aks + description: | + Mark unknown user instances for deletion in 1 day + filters: + # instance name not in accepted user keys + - type: value + key: name + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:known_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: unknown_user + op: delete + days: 1 + +- name: az-mark-known-aks-for-deletion + resource: azure.aks + description: | + Mark known user instances for deletion in 2 days + filters: + # instance is named with accepted user key + - type: value + key: name + op: regex + value: "^.*USERKEYS.*$" + # instance is not doNotDelete + - 'tag:doNotDelete': absent + - 'tag:DoNotDelete': absent + - 'tag:unknown_user': absent + - "tag:DeletesOnFriday": absent + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: mark-for-op + tag: known_user + op: delete + days: 2 + +- name: azure-terminate-aks + resource: azure.aks + description: | + Delete any marked instances which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + tag: unknown_user + op: delete + - type: marked-for-op + tag: known_user + op: delete + actions: + - type: delete \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/gcp.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/gcp.yaml new file mode 100644 index 0000000..7799079 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/gcp.yaml @@ -0,0 +1,72 @@ +# GCP Policies +# Note: for GOOGLE_APPLICATION_CREDENTIALS, must be valid json +# with quotes commented out +policies: +# VMs +- name: gcp-mark-unknown-instance-for-deletion + resource: gcp.instance + description: | + Mark unknown user instances for deletion in 1 day + filters: + # instance name not in accepted user keys + - type: value + key: name + op: regex + #doesNOTcontain + value: "^((?!USERKEYS).)*$" + # tagging not supported through cloud custodian at this time + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: set-labels + labels: + unknown_user: setForDeletion + - type: mark-for-op + op: delete + days: 1 + + +- name: gcp-mark-known-instance-for-deletion + resource: gcp.instance + description: | + Mark known user instances for deletion in 2 days + filters: + # instance is named with accepted user key + - type: value + key: name + op: regex + value: "^.*USERKEYS.*$" + # tagging not supported through cloud custodian at this time + - not: + - type: value + key: name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: set-labels + labels: + known_user: setForDeletion + - type: mark-for-op + op: delete + days: 2 + +- name: gcp-terminate-instance + resource: gcp.instance + description: | + Delete any marked instances which have been + marked for deletion for more than 1 day. + filters: + - or: + - type: marked-for-op + label: unknown_user + op: delete + - type: marked-for-op + label: known_user + op: delete + actions: + - type: delete + +# GKE - no support for labels nor tags at this time \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/tag-to-save.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/tag-to-save.yaml new file mode 100644 index 0000000..191ad57 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/tag-to-save.yaml @@ -0,0 +1,40 @@ +policies: +# note: userkeys here is an override var. +- name: tag-instances-til-friday + resource: aws.ec2 + filters: + - and: + - type: value + key: tag:Name + op: regex + value: "^.*USERKEYS.*$" + - not: + - 'tag:doNotDelete': present + - 'tag:DoNotDelete': present + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: tag + tags: + DeletesOnFriday: 'true' +- name: tag-nlbs-til-friday + resource: app-elb + filters: + - and: + - type: value + key: LoadBalancerArn + op: regex + value: "^.*USERKEYS.*$" + - not: + - 'tag:doNotDelete': present + - 'tag:DoNotDelete': present + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: tag + tags: + DeletesOnFriday: 'true' \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/untag-to-delete.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/untag-to-delete.yaml new file mode 100644 index 0000000..2dd631f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/custodian/untag-to-delete.yaml @@ -0,0 +1,29 @@ +policies: +# should be ran on CRON to remove on every saturday morning / friday night +# note: userkeys here is an override var. +- name: remove-tagged-friday-instances + resource: aws.ec2 + filters: + - 'tag:DeletesOnFriday': present + - not: + - 'tag:doNotDelete': present + - 'tag:DoNotDelete': present + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: terminate +- name: remove-tagged-friday-nlbs + resource: app-elb + filters: + - 'tag:DeletesOnFriday': present + - not: + - 'tag:doNotDelete': present + - 'tag:DoNotDelete': present + - type: value + key: tag:Name + op: regex + value: "^.*DONOTDELETEKEYS.*$" + actions: + - type: delete \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/final_rc_checks/final_rc_checks.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/final_rc_checks/final_rc_checks.py new file mode 100644 index 0000000..54dba4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/final_rc_checks/final_rc_checks.py @@ -0,0 +1,36 @@ +import requests +import json +import argparse + +# Set parser variable to reduce redundancy +parser = argparse.ArgumentParser() + +# -fqdn FQDN -api API_Bearer_token +parser.add_argument("-fqdn", "--rancherURL", dest = "fqdn", help="Rancher FQDN, e.g. https://") +parser.add_argument("-api", "--api", dest = "api_bearer_token", help="API Bearer token") + +args = parser.parse_args() + +# List of settings to check - URL tags +list_of_urls = ["rke-version", "ui-index", "ui-dashboard-index", "cli-url-linux", + "cli-url-darwin", "cli-url-windows", "system-catalog","kdm-branch", + "ui-k8s-supported-versions-range"] +url_label = ["Released RKE version", "UI Tag", "UI Dashboard Index", "CLI URL (Linux)", + "CLI URL (Darwin)", "CLI URL (Windows)", "System Chart Catalog", "KDM branch", + "UI k8s supported versions range"] +rancher_server_url = args.fqdn + +# Disable warnings +requests.packages.urllib3.disable_warnings() + +# Add content type and api_bearer_token to the header +headers = {"Content-Type":"application/json","Authorization": "Bearer " + args.api_bearer_token} + +# Iterate through list_of_urls to get the values +for url, label in zip(list_of_urls, url_label): + web_url = rancher_server_url + "/v3/settings/" + url + response = requests.get(web_url, headers=headers, verify=False) + if response.status_code == 200: + print("\t" + label + ": " + response.json()["value"]) + else: + print("\t" + label + " is not set") \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/compare-registry.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/compare-registry.sh new file mode 100755 index 0000000..ca5d614 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/compare-registry.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +RANCHER_IMAGES_PATH="$(pwd)/rancher-images.txt" +RANCHER_MISSING_IMAGES_PATH="$(pwd)/missing-images.txt" +SCAN_REGISTRY_PATH="$(pwd)/scan-registry.sh" +DOCKER_IMAGES_PATH="$(pwd)/docker-hub-existing-images.txt" +USER_REGISTRY_IMAGES_PATH="$(pwd)/user-existing-images.txt" +DOCKER_REGISTRY="docker.io/" +RANCHER_VERSION="$1" +USER_REGISTRY="$2" + +prereq() { + echo -e "\nInstalling skopeo tool..." + if skopeo -v > /dev/null 2>&1; then + echo -e "\nSkopeo is already installed!" + else + . /etc/os-release + + # Ubuntu 20.10 or higher are needed for skopeo. + [[ "${ID}" == "ubuntu" || "${ID}" == "debian" ]] && sudo apt update && sudo apt -y install skopeo + [[ "${ID}" == "rhel" || "${ID}" == "fedora" ]] && sudo yum install skopeo -y + [[ "${ID}" == "opensuse-leap" || "${ID}" == "sles" ]] && sudo zypper install -y skopeo + fi +} + +scanRegistries() { + echo -e "\nPulling rancher-images.txt file..." + wget https://github.com/rancher/rancher/releases/download/"${RANCHER_VERSION}"/rancher-images.txt + + echo -e "\nRunning scan-registry.sh against Docker Hub..." + "${SCAN_REGISTRY_PATH}" -l "$(pwd)/rancher-images.txt" -r "${DOCKER_REGISTRY}" >> "${DOCKER_IMAGES_PATH}" + + echo -e "\nRunning scan-registry.sh against specified registry..." + "${SCAN_REGISTRY_PATH}" -l "$(pwd)/rancher-images.txt" -r "${USER_REGISTRY}" >> "${USER_REGISTRY_IMAGES_PATH}" +} + +compareResults() { + echo -e "\nComparing the results..." + comm -13 <(sort -u "${DOCKER_IMAGES_PATH}" | cut -d ' ' -f1) <(sort -u "${USER_REGISTRY_IMAGES_PATH}"| cut -d ' ' -f1) >> "${RANCHER_MISSING_IMAGES_PATH}" + sed -i '/^$/d' "${RANCHER_MISSING_IMAGES_PATH}" + + echo -e "\nImages that are missing in user specified registry:" + if [[ ! -s "${RANCHER_MISSING_IMAGES_PATH}" ]]; then + echo -e "\nNo missing images in your registry!" + else + cat "${RANCHER_MISSING_IMAGES_PATH}" + fi +} + +usage() { + cat << EOF + +$(basename "$0") + +This script will run the scan-registry.sh two times; once with the Docker Hub registry and once with the specified + +registry. Once done, it will compare the results and list the images that are missing in the user specified registry. + +When running the script, specify the Rancher version, prefixed with a leading 'v' and the registry to compare against + +Docker, suffixed with a trailing slash. + +USAGE: % ./$(basename "$0") [options] + +OPTIONS: + -h -> Usage + +EXAMPLES OF USAGE: + +* Run script + + $ ./$(basename "$0") v / + +EOF +} + +while getopts "h" opt; do + case ${opt} in + h) + usage + exit 0;; + esac +done + +Main() { + prereq + scanRegistries + compareResults +} + +Main "$@" \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/scan-registry.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/scan-registry.sh new file mode 100755 index 0000000..4e3f378 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/prime/scan-registry.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +LIST="rancher-images.txt" +MISSING_IMAGES="" + +scanRegistry() { + while IFS= read -r i; do + [ -z "${i}" ] && continue + if inspect=$(skopeo inspect --raw docker://${REGISTRY_NAME}${i} | egrep '(digest|os|arch)') > /dev/null 2>&1; then + echo "${i} - ${inspect}" + else + MISSING_IMAGES="${MISSING_IMAGES}\n${i}" + fi + done < "${list}" + + if [[ ${MISSING_IMAGES} ]]; then + echo -e "\nThe following images were missing in registry ${REGISTRY_NAME}:" + echo -e "\n${MISSING_IMAGES}" - "${inspect}" + else + echo -e "\nNo missing images in your registry!" + fi +} + +usage() { + cat << EOF + +$(basename "$0") + +This script will scan a specified repository for Rancher images and list images that are not found. + +USAGE: % ./$(basename "$0") [options] + +OPTIONS: + -h -> Usage + -l | --image-list -> Path to text file with list of images + -r | --registry -> Registry to use + +EXAMPLES OF USAGE: + +* Run script + + $ ./$(basename "$0") -l rancher-images.txt -r docker.io/ + +EOF +} + +Main() { + POSITIONAL=() + while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -r|--registry) + REGISTRY_NAME="$2" + shift + shift + ;; + -l|--image-list) + list="$2" + shift + shift + ;; + -h|--help) + help="true" + shift + ;; + *) + usage + exit 1 + ;; + esac + done + + if [[ $help ]]; then + usage + exit 0 + fi + + scanRegistry +} + +Main "$@" \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/privateregistry/populate-ecr.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/privateregistry/populate-ecr.sh new file mode 100755 index 0000000..0bfafca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/privateregistry/populate-ecr.sh @@ -0,0 +1,99 @@ +#!/usr/bin/bash + +AWS_ACCESS_KEY_ID="$(aws configure get aws_access_key_id)" +AWS_SECRET_ACCESS_KEY="$(aws configure get aws_secret_access_key)" +REGION="$(aws configure get region)" +USERNAME="AWS" +ECR="$1" +RANCHER_VERSION="$2" + +loginECR() { + echo -e "\nLogging into ECR..." + aws ecr get-login-password --region ${REGION} | docker login --username "${USERNAME}" --password-stdin "${ECR}" +} + +createCert() { + echo -e "\nCreating a self-signed certificate..." + mkdir -p certs + openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -addext "subjectAltName = DNS:${ECR}" -x509 -days 365 -out certs/domain.crt -subj "/C=US/ST=CA/L=SUSE/O=Dis/CN=${ECR}" + + echo -e "\nCopying the certificate to the /etc/docker/certs.d/${ECR} directory..." + sudo mkdir -p /etc/docker/certs.d/"${ECR}" + sudo cp certs/domain.crt /etc/docker/certs.d/"${ECR}"/ca.crt +} + +createECRRepo() { + echo -e "\nDownloading "${RANCHER_VERSION}" image list and scripts..." + wget https://github.com/rancher/rancher/releases/download/"${RANCHER_VERSION}"/rancher-images.txt + wget https://github.com/rancher/rancher/releases/download/"${RANCHER_VERSION}"/rancher-save-images.sh + chmod +x rancher-save-images.sh + + echo -e "\nCutting the tags from the image names..." + while read LINE; do + echo ${LINE} | cut -d: -f1 + done < rancher-images.txt > rancher-images-no-tags.txt + + echo -e "\nCreating ECR repositories..." + for IMAGE in $(cat rancher-images-no-tags.txt); do + aws ecr create-repository --repository-name ${IMAGE} + done +} + +saveAndLoadImages() { + echo -e "\nSaving the images..." + ./rancher-save-images.sh --image-list ./rancher-images.txt + + echo -e "\nTagging the images..." + for IMAGE in $(cat rancher-images.txt); do + docker tag ${IMAGE} ${ECR}/${IMAGE} + done + + echo -e "\nPushing the newly tagged images ECR..." + for IMAGE in $(cat rancher-images.txt); do + docker push ${ECR}/${IMAGE} + done +} + +usage() { + cat << EOF + +$(basename "$0") + +This script will populate a private ECR with Rancher images. This script assumes you have the following +tools installed and configured on the system: + + * Docker + * AWS CLI + +When running the script, specify the ECR URI and the version of Rancher, prefixed with a leading 'v'. + +USAGE: % ./$(basename "$0") [options] + +OPTIONS: + -h -> Usage + +EXAMPLES OF USAGE: + +* Run script + + $ ./$(basename "$0") v + +EOF +} + +while getopts "h" opt; do + case ${opt} in + h) + usage + exit 0;; + esac +done + +Main() { + loginECR + createCert + createECRRepo + saveAndLoadImages +} + +Main "$@" \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/rollback/rollback-rancher.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/rollback/rollback-rancher.sh new file mode 100755 index 0000000..c2b25a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/rollback/rollback-rancher.sh @@ -0,0 +1,66 @@ +#!/usr/bin/bash + +ROLLBACK_VERSION="$1" +RANCHER="rancher/rancher" +ROLLBACK_IMAGE_TAG="${RANCHER}:$ROLLBACK_VERSION" +CONTAINER_ID=`docker ps | awk 'NR > 1 {print $1}'` +DATA_CONTAINER="rancher-data" +VARLIB="/var/lib/rancher" +BACKUP="/backup/${DATA_CONTAINER}-${ROLLBACK_VERSION}.tar.gz" + +rollbackRancher() { + echo -e "\nStopping Rancher..." + docker stop "${CONTAINER_ID}" + + echo -e "\nPulling old Rancher image..." + docker pull "${ROLLBACK_IMAGE_TAG}" + + echo -e "\nReplacing data in ${DATA_CONTAINER} with the data in ${BACKUP}..." + docker run --volumes-from "${DATA_CONTAINER}" -v ${PWD}:/backup busybox sh -c "rm ${VARLIB}/* -rf && tar zxvf ${BACKUP}" + + echo -e "\nStarting Rancher..." + docker run -d --volumes-from "${DATA_CONTAINER}" --restart=unless-stopped \ + -p 80:80 -p 443:443 \ + --privileged "${ROLLBACK_IMAGE_TAG}" +} + +usage() { + cat << EOF + +$(basename "$0") + +This script will rollback Rancher API Server using Docker. This script assumes the following: + + * Rancher is running in a Docker container + * Docker is installed and script user is in the docker group + * The upgrade.sh script has been run before this one + +When running the script, specify the version of Rancher to rollback to, prefixed with a leading 'v'. + +USAGE: % ./$(basename "$0") [options] + +OPTIONS: + -h -> Usage + +EXAMPLES OF USAGE: + +* Run script + + $ ./$(basename "$0") v + +EOF +} + +while getopts "h" opt; do + case ${opt} in + h) + usage + exit 0;; + esac +done + +Main() { + rollbackRancher +} + +Main "$@" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/shepherd/update-gomod-shepherd.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/shepherd/update-gomod-shepherd.sh new file mode 100755 index 0000000..7123218 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/shepherd/update-gomod-shepherd.sh @@ -0,0 +1,45 @@ +#!/bin/bash +if [ "$1" == "-h" ] || [ -z "$1" ]; then + echo "Usage: `basename $0` " + echo "WARN: this will update your local go.mod and go.sum files in your rancher repo." + echo -e "Requirements:\n* local clone of upstream rancher/shepherd\n* clone of rancher fork with local changes" + echo "example: `basename $0` ~/upstream-shepherd release/v2.8 ~/rancher-fork" + exit 0 +fi + +if [ ! -d $1 ]; then + echo "$1 not a valid path" + exit 1 +fi + +if [ ! -d $3 ]; then + echo "$3 is not a valid path" + exit 1 +fi + +echo "getting latest shepherd version for branch $2" +cd $1 +git checkout $2 -q +git fetch upstream -q +git pull -q +git rebase upstream/$2 + +if [[ $4 == "" ]]; then + export upstream="rancher" +else + export upstream=$4 +fi + +export SHEPHERD_VERSION=$(curl -s https://proxy.golang.org/github.com/$upstream/shepherd/@v/$(git log -n 1 --pretty=format:"%H").info | grep -E -o "\bv0.0.0-+[A-Za-z0-9.-]+[A-Za-z0-9.-]\b") +echo "Shepherd Version is: $SHEPHERD_VERSION" + +echo "writing version to go.mod, then tidying in $3" +cd $3 + +if [[ $upstream == "rancher" ]]; then + go get github.com/$upstream/shepherd@$SHEPHERD_VERSION +else + go mod edit -replace=github.com/rancher/shepherd=github.com/$upstream/shepherd@$SHEPHERD_VERSION +fi + +go mod tidy diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/upgrade/upgrade-rancher.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/upgrade/upgrade-rancher.sh new file mode 100755 index 0000000..8f79d9b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/scripts/upgrade/upgrade-rancher.sh @@ -0,0 +1,70 @@ +#!/usr/bin/bash + +OLD_VERSION="$1" +NEW_VERSION="$2" +RANCHER="rancher/rancher" +OLD_IMAGE_TAG="${RANCHER}:${OLD_VERSION}" +NEW_IMAGE_TAG="${RANCHER}:${NEW_VERSION}" +CONTAINER_ID=`docker ps | awk 'NR > 1 {print $1}'` +DATA_CONTAINER="rancher-data" +VARLIB="/var/lib/rancher" +BACKUP="/backup/${DATA_CONTAINER}-${OLD_VERSION}.tar.gz" + +upgradeRancher() { + echo -e "\nStopping Rancher and creating a data container..." + docker stop "${CONTAINER_ID}" + docker create --volumes-from "${CONTAINER_ID}" --name "${DATA_CONTAINER}" "${OLD_IMAGE_TAG}" + + echo -e "\nCreating a backup tarball..." + docker run --volumes-from "${DATA_CONTAINER}" -v "${PWD}:/backup" --rm busybox tar zcvf "${BACKUP}" "${VARLIB}" + + echo -e "\nPulling new Rancher image..." + docker pull "${NEW_IMAGE_TAG}" + + echo -e "\nStarting Rancher..." + docker run -d --volumes-from "${DATA_CONTAINER}" --restart=unless-stopped \ + -p 80:80 -p 443:443 \ + --privileged "${NEW_IMAGE_TAG}" +} + +usage() { + cat << EOF + +$(basename "$0") + +This script will upgrade Rancher API Server using Docker. This script assumes the following: + + * Rancher is running in a Docker container + * Docker is installed and script user is in the docker group + +When running the script, specify the current Rancher version and the upgraded Rancher version. + +Both need to be prefixed with a leading 'v'. + +USAGE: % ./$(basename "$0") [options] + +OPTIONS: + -h -> Usage + +EXAMPLES OF USAGE: + +* Run script + + $ ./$(basename "$0") v v + +EOF +} + +while getopts "h" opt; do + case ${opt} in + h) + usage + exit 0;; + esac +done + +Main() { + upgradeRancher +} + +Main "$@" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testchart-1.0.0.tgz b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testchart-1.0.0.tgz new file mode 100644 index 0000000..d655933 Binary files /dev/null and b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testchart-1.0.0.tgz differ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testingchart-0.1.0.tgz b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testingchart-0.1.0.tgz new file mode 100644 index 0000000..098f480 Binary files /dev/null and b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/testdata/testingchart-0.1.0.tgz differ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/auth/auth.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/auth/auth.go new file mode 100644 index 0000000..7fb9428 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/auth/auth.go @@ -0,0 +1,59 @@ +package auth + +import ( + "fmt" + "strconv" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/rancher" + client "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + LastloginLabel = "cattle.io/last-login" +) + +func GetLastLoginTime(labels map[string]string) (lastLogin time.Time, err error) { + value, exists := IsLabelPresent(labels) + + if !exists || value == "" { + return + } + epochTime, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return + } + lastLogin = ConvertEpochToTime(epochTime) + return +} + +func ConvertEpochToTime(epochTime int64) time.Time { + return time.Unix(epochTime, 0) +} + +func IsLabelPresent(labels map[string]string) (string, bool) { + value, exists := labels[LastloginLabel] + return value, exists +} + +func GetUserAfterLogin(rancherClient *rancher.Client, user client.User) (userDetails *v3.User, err error) { + + _, err = rancherClient.AsUser(&user) + if err != nil { + return + } + listOpt := v1.ListOptions{ + FieldSelector: "metadata.name=" + user.ID, + } + userList, err := rancherClient.WranglerContext.Mgmt.User().List(listOpt) + + if len(userList.Items) == 0 { + return nil, fmt.Errorf("User %s not found", user.ID) + } + userDetails = &userList.Items[0] + + return +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/projects/projects.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/projects/projects.go new file mode 100644 index 0000000..c390ba4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/projects/projects.go @@ -0,0 +1,71 @@ +package projects + +import ( + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + projectsapi "github.com/rancher/shepherd/extensions/kubeapi/projects" + "github.com/rancher/shepherd/extensions/projects" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +// CreateProjectAndNamespace is a helper to create a project (norman) and a namespace in the project +func CreateProjectAndNamespace(client *rancher.Client, clusterID string) (*management.Project, *corev1.Namespace, error) { + createdProject, err := client.Management.Project.Create(projects.NewProjectConfig(clusterID)) + if err != nil { + return nil, nil, err + } + + namespaceName := namegen.AppendRandomString("testns") + projectName := strings.Split(createdProject.ID, ":")[1] + + createdNamespace, err := namespaces.CreateNamespace(client, clusterID, projectName, namespaceName, "{}", map[string]string{}, map[string]string{}) + if err != nil { + return nil, nil, err + } + + return createdProject, createdNamespace, nil +} + +// WaitForProjectFinalizerToUpdate is a helper to wait for project finalizer to update to match the expected finalizer count +func WaitForProjectFinalizerToUpdate(client *rancher.Client, projectName string, projectNamespace string, finalizerCount int) error { + err := kwait.Poll(defaults.FiveHundredMillisecondTimeout, defaults.TenSecondTimeout, func() (done bool, pollErr error) { + project, pollErr := projectsapi.ListProjects(client, projectNamespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + projectName, + }) + if pollErr != nil { + return false, pollErr + } + + if len(project.Items[0].Finalizers) == finalizerCount { + return true, nil + } + return false, pollErr + }) + + if err != nil { + return err + } + + return nil +} + +// UpdateProjectNamespaceFinalizer is a helper to update the finalizer in a project +func UpdateProjectNamespaceFinalizer(client *rancher.Client, existingProject *v3.Project, finalizer []string) (*v3.Project, error) { + updatedProject := existingProject.DeepCopy() + updatedProject.ObjectMeta.Finalizers = finalizer + + updatedProject, err := projectsapi.UpdateProject(client, existingProject, updatedProject) + if err != nil { + return nil, err + } + + return updatedProject, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/rbac/rbac.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/rbac/rbac.go new file mode 100644 index 0000000..21b64b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/rbac/rbac.go @@ -0,0 +1,136 @@ +package rbac + +import ( + "fmt" + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + rbacv2 "github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + "github.com/sirupsen/logrus" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type Role string + +const ( + Admin Role = "admin" + RestrictedAdmin Role = "restricted-admin" + StandardUser Role = "user" + ClusterOwner Role = "cluster-owner" + ClusterMember Role = "cluster-member" + ProjectOwner Role = "project-owner" + ProjectMember Role = "project-member" + CreateNS Role = "create-ns" + ReadOnly Role = "read-only" + CustomManageProjectMember Role = "projectroletemplatebindings-manage" + CrtbView Role = "clusterroletemplatebindings-view" + ProjectsCreate Role = "projects-create" + ProjectsView Role = "projects-view" + ActiveStatus = "active" + ForbiddenError = "403 Forbidden" + DefaultNamespace = "fleet-default" +) + +func (r Role) String() string { + return string(r) +} + +// AddUserWithRoleToCluster creates a user based on the global role and then adds the user to cluster with provided permissions. +func AddUserWithRoleToCluster(adminClient *rancher.Client, globalRole, role string, cluster *management.Cluster, project *management.Project) (*management.User, *rancher.Client, error) { + user, userClient, err := SetupUser(adminClient, globalRole) + if err != nil { + return nil, nil, err + } + + if globalRole == rbac.StandardUser.String() { + if strings.Contains(role, "project") || role == rbac.ReadOnly.String() { + err := users.AddProjectMember(adminClient, project, user, role, nil) + if err != nil { + return nil, nil, err + } + } else { + err := users.AddClusterRoleToUser(adminClient, cluster, user, role, nil) + if err != nil { + return nil, nil, err + } + } + } + + return user, userClient, nil +} + +// SetupUser is a helper to create a user with the specified global role and a client for the user. +func SetupUser(client *rancher.Client, globalRole string) (user *management.User, userClient *rancher.Client, err error) { + user, err = users.CreateUserWithRole(client, users.UserConfig(), globalRole) + if err != nil { + return + } + userClient, err = client.AsUser(user) + if err != nil { + return + } + return +} + +//GetRoleBindings is a helper function to fetch rolebindings for a user +func GetRoleBindings(rancherClient *rancher.Client, clusterID string, userID string) ([]rbacv1.RoleBinding, error) { + logrus.Infof("Getting role bindings for user %s in cluster %s", userID, clusterID) + listOpt := v1.ListOptions{} + roleBindings, err := rbacv2.ListRoleBindings(rancherClient, clusterID, "", listOpt) + if err != nil { + return nil, fmt.Errorf("failed to fetch RoleBindings: %w", err) + } + + var userRoleBindings []rbacv1.RoleBinding + for _, rb := range roleBindings.Items { + for _, subject := range rb.Subjects { + if subject.Name == userID { + userRoleBindings = append(userRoleBindings, rb) + break + } + } + } + logrus.Infof("Found %d role bindings for user %s", len(userRoleBindings), userID) + return userRoleBindings, nil +} + +//GetBindings is a helper function to fetch bindings for a user +func GetBindings(rancherClient *rancher.Client, userID string) (map[string]interface{}, error) { + logrus.Infof("Getting all bindings for user %s", userID) + bindings := make(map[string]interface{}) + + roleBindings, err := GetRoleBindings(rancherClient, rbacv2.LocalCluster, userID) + if err != nil { + return nil, fmt.Errorf("failed to get role bindings: %w", err) + } + bindings["RoleBindings"] = roleBindings + + logrus.Info("Getting cluster role bindings") + clusterRoleBindings, err := rbacv2.ListClusterRoleBindings(rancherClient, rbacv2.LocalCluster, v1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to list cluster role bindings: %w", err) + } + bindings["ClusterRoleBindings"] = clusterRoleBindings.Items + + logrus.Info("Getting global role bindings") + globalRoleBindings, err := rancherClient.Management.GlobalRoleBinding.ListAll(&types.ListOpts{}) + if err != nil { + return nil, fmt.Errorf("failed to list global role bindings: %w", err) + } + bindings["GlobalRoleBindings"] = globalRoleBindings.Data + + logrus.Info("Getting cluster role template bindings") + clusterRoleTemplateBindings, err := rancherClient.Management.ClusterRoleTemplateBinding.List(&types.ListOpts{}) + if err != nil { + return nil, fmt.Errorf("failed to list cluster role template bindings: %w", err) + } + bindings["ClusterRoleTemplateBindings"] = clusterRoleTemplateBindings.Data + + logrus.Info("All bindings retrieved successfully") + return bindings, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/secrets/secrets.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/secrets/secrets.go new file mode 100644 index 0000000..9ea8434 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/secrets/secrets.go @@ -0,0 +1,50 @@ +package secrets + +import ( + "fmt" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/secrets" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/wrangler" + corev1 "k8s.io/api/core/v1" +) + +// CreateSecret is a helper to create a secret using wrangler client +func CreateSecret(client *rancher.Client, clusterID, namespaceName string, data map[string][]byte) (*corev1.Secret, error) { + var ctx *wrangler.Context + var err error + + if clusterID != "local" { + ctx, err = client.WranglerContext.DownStreamClusterWranglerContext(clusterID) + if err != nil { + return nil, fmt.Errorf("failed to get downstream context: %w", err) + } + } else { + ctx = client.WranglerContext + } + + secretName := namegen.AppendRandomString("testsecret") + secretTemplate := secrets.NewSecretTemplate(secretName, namespaceName, data, corev1.SecretTypeOpaque) + + createdSecret, err := ctx.Core.Secret().Create(&secretTemplate) + if err != nil { + return nil, fmt.Errorf("failed to create secret: %w", err) + } + + return createdSecret, nil +} + +// UpdateSecretData is a helper to update the existing secret data with new data +func UpdateSecretData(secret *corev1.Secret, newData map[string][]byte) *corev1.Secret { + updatedSecretObj := secret.DeepCopy() + if updatedSecretObj.Data == nil { + updatedSecretObj.Data = make(map[string][]byte) + } + + for key, value := range newData { + updatedSecretObj.Data[key] = value + } + + return updatedSecretObj +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deamonset/deamonset.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deamonset/deamonset.go new file mode 100644 index 0000000..9357f5b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deamonset/deamonset.go @@ -0,0 +1,26 @@ +package deamonset + +import ( + "github.com/rancher/rancher/tests/v2/actions/workloads/deployment" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/workloads" + appv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// CreateDeamonset is a helper to create a deamonset +func CreateDeamonset(client *rancher.Client, clusterID, namespaceName string, replicaCount int, secretName, configMapName string, useEnvVars, useVolumes bool) (*appv1.DaemonSet, error) { + deploymentTemplate, err := deployment.CreateDeployment(client, clusterID, namespaceName, replicaCount, secretName, configMapName, useEnvVars, useVolumes) + if err != nil { + return nil, err + } + + createdDaemonset := workloads.NewDaemonSetTemplate(deploymentTemplate.Name, namespaceName, deploymentTemplate.Spec.Template, true, nil) + + err = charts.WatchAndWaitDaemonSets(client, clusterID, namespaceName, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdDaemonset.Name, + }) + + return createdDaemonset, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deployment/deployment.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deployment/deployment.go new file mode 100644 index 0000000..cdc670a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/deployment/deployment.go @@ -0,0 +1,85 @@ +package deployment + +import ( + "github.com/rancher/rancher/tests/v2/actions/workloads/pods" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/kubeapi/workloads/deployments" + "github.com/rancher/shepherd/extensions/workloads" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + imageName = "nginx" +) + +// CreateDeployment is a helper to create a deployment with or without a secret/configmap +func CreateDeployment(client *rancher.Client, clusterID, namespaceName string, replicaCount int, secretName, configMapName string, useEnvVars, useVolumes bool) (*appv1.Deployment, error) { + deploymentName := namegen.AppendRandomString("testdeployment") + containerName := namegen.AppendRandomString("testcontainer") + pullPolicy := corev1.PullAlways + replicas := int32(replicaCount) + + var podTemplate corev1.PodTemplateSpec + + if secretName != "" || configMapName != "" { + podTemplate = pods.NewPodTemplateWithConfig(secretName, configMapName, useEnvVars, useVolumes) + } else { + containerTemplate := workloads.NewContainer( + containerName, + imageName, + pullPolicy, + []corev1.VolumeMount{}, + []corev1.EnvFromSource{}, + nil, + nil, + nil, + ) + podTemplate = workloads.NewPodTemplate( + []corev1.Container{containerTemplate}, + []corev1.Volume{}, + []corev1.LocalObjectReference{}, + nil, + ) + } + + createdDeployment, err := deployments.CreateDeployment(client, clusterID, deploymentName, namespaceName, podTemplate, replicas) + if err != nil { + return nil, err + } + + err = charts.WatchAndWaitDeployments(client, clusterID, namespaceName, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdDeployment.Name, + }) + + return createdDeployment, err +} + +// UpdateDeployment is a helper to update deployments +func UpdateDeployment(client *rancher.Client, clusterID, namespaceName string, deployment *appv1.Deployment) (*appv1.Deployment, error) { + wranglerContext, err := client.WranglerContext.DownStreamClusterWranglerContext(clusterID) + if err != nil { + return nil, err + } + + latestDeployment, err := wranglerContext.Apps.Deployment().Get(namespaceName, deployment.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + deployment.ResourceVersion = latestDeployment.ResourceVersion + + updatedDeployment, err := wranglerContext.Apps.Deployment().Update(deployment) + if err != nil { + return nil, err + } + + err = charts.WatchAndWaitDeployments(client, clusterID, namespaceName, metav1.ListOptions{ + FieldSelector: "metadata.name=" + updatedDeployment.Name, + }) + + return updatedDeployment, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/pods/pods.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/pods/pods.go new file mode 100644 index 0000000..9d1eb7f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/actions/workloads/pods/pods.go @@ -0,0 +1,152 @@ +package pods + +import ( + "errors" + "regexp" + "strings" + "time" + + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/extensions/workloads" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + corev1 "k8s.io/api/core/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + timeFormat = "2006/01/02 15:04:05" + imageName = "nginx" + podSteveType = "pod" +) + +// NewPodTemplateWithConfig is a helper to create a Pod template with a secret/configmap as an environment variable or volume mount or both +func NewPodTemplateWithConfig(secretName, configMapName string, useEnvVars, useVolumes bool) corev1.PodTemplateSpec { + containerName := namegen.AppendRandomString("testcontainer") + pullPolicy := corev1.PullAlways + + var envFrom []corev1.EnvFromSource + if useEnvVars { + if secretName != "" { + envFrom = append(envFrom, corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, + }, + }) + } + if configMapName != "" { + envFrom = append(envFrom, corev1.EnvFromSource{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + }, + }) + } + } + + var volumes []corev1.Volume + if useVolumes { + volumeName := namegen.AppendRandomString("vol") + optional := false + if secretName != "" { + volumes = append(volumes, corev1.Volume{ + Name: volumeName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: secretName, + Optional: &optional, + }, + }, + }) + } + if configMapName != "" { + volumes = append(volumes, corev1.Volume{ + Name: volumeName, + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + Optional: &optional, + }, + }, + }) + } + } + + container := workloads.NewContainer(containerName, imageName, pullPolicy, nil, envFrom, nil, nil, nil) + containers := []corev1.Container{container} + return workloads.NewPodTemplate(containers, volumes, nil, nil) +} + +// CheckPodLogsForErrors is a helper to check pod logs for errors +func CheckPodLogsForErrors(client *rancher.Client, clusterID string, podName string, namespace string, errorPattern string, startTime time.Time) error { + startTimeUTC := startTime.UTC() + + errorRegex := regexp.MustCompile(errorPattern) + timeRegex := regexp.MustCompile(`^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}`) + + var errorMessage string + + kwait.Poll(defaults.TenSecondTimeout, defaults.TwoMinuteTimeout, func() (bool, error) { + podLogs, err := kubeconfig.GetPodLogs(client, clusterID, podName, namespace, "") + if err != nil { + return false, err + } + + segments := strings.Split(podLogs, "\n") + for _, segment := range segments { + timeMatches := timeRegex.FindStringSubmatch(segment) + if len(timeMatches) > 0 { + segmentTime, err := time.Parse(timeFormat, timeMatches[0]) + if err != nil { + continue + } + + segmentTimeUTC := segmentTime.UTC() + if segmentTimeUTC.After(startTimeUTC) { + if matches := errorRegex.FindStringSubmatch(segment); len(matches) > 0 { + errorMessage = "error logs found in rancher: " + segment + return true, nil + } + } + } + } + return false, nil + }) + + if errorMessage != "" { + return errors.New(errorMessage) + } + + return nil +} + +// CountPodContainerRunning is a helper to count all pod containers running +func CountPodContainerRunning(client *rancher.Client, clusterID, namespaceName string) (int, error) { + steveclient, err := client.Steve.ProxyDownstream(clusterID) + if err != nil { + return 0, err + } + + podsResp, err := steveclient.SteveType(podSteveType).NamespacedSteveClient(namespaceName).List(nil) + if err != nil { + return 0, err + } + + count := 0 + for _, podResp := range podsResp.Data { + podStatus := &corev1.PodStatus{} + err = v1.ConvertToK8sType(podResp.Status, podStatus) + if err != nil { + return 0, err + } + + for _, containerStatus := range podStatus.ContainerStatuses { + if containerStatus.State.Running != nil { + count++ + } + } + } + + return count, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/.gitignore new file mode 100644 index 0000000..e8f055e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/.gitignore @@ -0,0 +1,7 @@ +/bin +/package/data.json +/package/k3s-airgap-images.tar +/package/rancher +/package/agent +*.yaml +/ranchercover/cover \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.buildcodecoverage b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.buildcodecoverage new file mode 100644 index 0000000..1fa4528 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.buildcodecoverage @@ -0,0 +1,17 @@ +FROM registry.suse.com/bci/golang:1.22 + +# Configure Go +ENV GOPATH /root/go +ENV PATH ${PATH}:/root/go/bin + +ENV WORKSPACE ${GOPATH}/src/github.com/rancher/rancher + +WORKDIR $WORKSPACE + +COPY [".", "$WORKSPACE"] + +RUN apt-get update && \ + apt-get -qy full-upgrade && \ + apt-get install -qy curl && \ + apt-get install -qy curl && \ + curl -sSL https://get.docker.com/ | sh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.codecoverage b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.codecoverage new file mode 100644 index 0000000..28d80f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Dockerfile.codecoverage @@ -0,0 +1,24 @@ +FROM registry.suse.com/bci/golang:1.22 + +# Configure Go +ENV GOPATH /root/go +ENV PATH ${PATH}:/root/go/bin + +ENV WORKSPACE ${GOPATH}/src/github.com/rancher/rancher +ENV WORKSPACE2 ${GOPATH}/src/github.com/rancherlabs/corral-packages + +WORKDIR $WORKSPACE + +COPY ["./rancher", "$WORKSPACE"] +COPY ["./corral-packages", "$WORKSPACE2"] + +ENV CORRAL_VERSION="v1.1.1" + +RUN zypper -n install gcc binutils glibc-devel-static ca-certificates git-core wget curl unzip tar vim less file xz gzip sed gawk iproute2 iptables jq +RUN zypper install -y -f docker && rpm -e --nodeps --noscripts containerd +RUN zypper install -y python3-tox python3-base python3 libffi-devel libopenssl-devel +RUN go mod download && \ + go install gotest.tools/gotestsum@latest && \ + go install golang.org/x/tools/cmd/cover@latest && \ + go install github.com/rancherlabs/corral@${CORRAL_VERSION} && \ + go install github.com/wadey/gocovmerge@latest diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_buildcodecoverage b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_buildcodecoverage new file mode 100644 index 0000000..d2c180e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_buildcodecoverage @@ -0,0 +1,67 @@ +#!groovy +node { + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/codecoverage/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def imageName = "rancher-code-coverage-image-build-${job_name}${env.BUILD_NUMBER}" + def buildDockerContainer = "build-code-cover-docker-container" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def coverfile = "cover.out" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def repo = scm.userRemoteConfigs + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + repo = [[url: "${env.REPO}"]] + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'RANCHER_TEST_DOCKER_USERNAME', variable: 'RANCHER_TEST_DOCKER_USERNAME'), + string(credentialsId: 'RANCHER_TEST_DOCKER_PASSWORD', variable: 'RANCHER_TEST_DOCKER_PASSWORD')]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: repo + ]) + } + dir ("/home/jenkins/go/src/github.com/rancher/rancher") { + try { + stage('Configure and Build') { + sh "tests/v2/validation/configure.sh" + sh "docker build . -f tests/v2/codecoverage/Dockerfile.buildcodecoverage -t ${goImageName}" + } + stage('Build Code Coverage Test Image') { + sh "docker run -v /var/run/docker.sock:/var/run/docker.sock --name ${buildDockerContainer} -t --env-file ${envFile} " + + "${goImageName} sh -c \"${workPath}scripts/build_test_images.sh;${workPath}scripts/build_docker_images.sh\"" + } + } finally { + stage('Test Report') { + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi -f ${imageName}" + } + } // finally + } // dir + } // creds + } // withEnv + } // folder properties + } // wrap +}// node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_codecoverage b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_codecoverage new file mode 100644 index 0000000..134c3a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/Jenkinsfile_codecoverage @@ -0,0 +1,400 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/codecoverage/" + def job_name = "${JOB_NAME}" + def code_cover_volume = "CodeCoverageTestReportSharedVolume" + + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def integrationTestContainer = "integration-test-container" + def codeCoverTestContainer = "code-cover-test-container" + def golangTestContainer = "golang-setup-test" + def golangUnitTestContainer = "golang-unit-test" + def pythonTestContainer = "python-integration-test" + def v2ProvTestContainer = "v2-prov-integration-test" + def cleanupContainer = "code-cover-cleanup" + def goImageName = "rancher-code-coverage-${job_name}" + def envFile = ".env" + def codeCoverageDir = "github.com/rancher/rancher/tests/v2/codecoverage/ranchercover" + def codeCoverageTest = "-run TestRetrieveCoverageReports" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def defaultBranch = branch + def unitTestCoverfile = "unittestcover.out" + def unitTestHTMLfile = "coverage.html" + def coverDir = "cover/" + def mergedCovFile = "profile.txt" + def mergedHTMLFile = "merged.html" + def cleanupYaml = "initalvalue" + def configYaml = "initalvalue" + def provisioningYaml = "initalvalue" + + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "") { + corralBranch = "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" + } + + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + + def corralRepo = scm.getUserRemoteConfigs()[1].getUrl() + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "") { + corralRepo = "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" + } + def timeout = "6h45m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir('./') { + echo "cloning corral-packages repo" + + dir('./corral-packages') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${corralBranch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: corralRepo]] + ]) + } + } + } + dir ("./") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./rancher/tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + dir("./rancher/tests/v2/codecoverage") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = workPath+filename + } + sh "rancher/tests/v2/validation/configure.sh" + sh "docker build . -f rancher/tests/v2/codecoverage/Dockerfile.codecoverage -t ${goImageName}" + sh "docker volume create --name ${code_cover_volume}" + } + stage('Run Unit Tests') { + sh "docker run --name ${golangUnitTestContainer} -t " + + "${goImageName} sh -c \"go test -coverprofile ${unitTestCoverfile} -tags=test ${rootPath}pkg/..." + + ";go tool cover -func ${unitTestCoverfile} | grep \"total\";go tool cover -html ${unitTestCoverfile} -o ${unitTestHTMLfile}\"" + } + stage('Setup Enviornment') { + try { + sh "docker run -v ${code_cover_volume}:/root --name ${golangTestContainer} -t --env-file ${envFile} " + + "${goImageName} sh -c \"${workPath}scripts/setup_code_coverage_enviornment.sh\"" + dir("./rancher/tests/v2/codecoverage") { + sh "rm config.yaml" + sh "docker cp ${golangTestContainer}:${workPath}config.yaml ./" + sh "cp config.yaml cleanupconfig.yaml" + sh "cp config.yaml provisioningconfig.yaml" + } + + + dir("./rancher/tests/v2/codecoverage/scripts") { + sh "docker cp ${golangTestContainer}:${rootPath}userclusterconfig.yaml ./" + sh ". ./download_yq.sh" + env.RANCHER_CLUSTER0 = sh ( + script: './yq ".userClusterConfig.clusters.[0]" ./userclusterconfig.yaml', + returnStdout: true + ) + env.RANCHER_CLUSTER1 = sh ( + script: './yq ".userClusterConfig.clusters.[1]" ./userclusterconfig.yaml', + returnStdout: true + ) + env.USER_TOKEN = sh ( + script: './yq ".userClusterConfig.token" ./userclusterconfig.yaml', + returnStdout: true + ) + env.ADMIN_TOKEN = sh ( + script: './yq ".rancher.adminToken" ../config.yaml', + returnStdout: true + ) + env.RANCHER_SERVER_PASSWORD = sh ( + script: './yq ".userClusterConfig.adminPassword" ./userclusterconfig.yaml', + returnStdout: true + ) + sh "./yq e '.rancher.cleanup = true' -i ../cleanupconfig.yaml" + sh "./yq e '.provisioningInput.providers = [\"aws\"]' -i ../provisioningconfig.yaml" + } + } catch(err) { + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + sh "docker volume rm -f ${code_cover_volume}" + error "Setup Environment had failures." + } + + env.CATTLE_TEST_CONFIG = "${workPath}cleanupconfig.yaml" + dir("./rancher/tests/v2/codecoverage") { + sh "docker cp ./cleanupconfig.yaml ${golangTestContainer}:${workPath}cleanupconfig.yaml" + cleanupYaml = readFile(file: './cleanupconfig.yaml') + configYaml = readFile(file: './config.yaml') + provisioningYaml = readFile(file: './provisioningconfig.yaml') + } + + sh "rm ${envFile}" + sh "rancher/tests/v2/validation/configure.sh" + } + + stage ('Run Go Integration Tests') { + try { + sh "docker run --volumes-from ${golangTestContainer} --name ${integrationTestContainer} -t --env-file ${envFile} " + + "${goImageName} sh -c \"go test -v -tags=test ${rootPath}tests/v2/integration/...\"" + } catch(err) { + echo "Go Integration tests had failures." + } + } + stage('Execute Subjobs') { + try { + jobs = [:] + goProvisioningParams = [ string(name: 'TIMEOUT', value: "3h"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: repo), + string(name: 'BRANCH', value: branch), + string(name: 'TEST_PACKAGE', value: "provisioning/..."), + string(name: 'GOTEST_TESTCASE', value: "${GO_PROVISIONING_TEST_CASES}") ] + + goExtendedProvisioningParams = [ string(name: 'TIMEOUT', value: "3h"), + text(name: 'CONFIG', value: provisioningYaml), + string(name: 'REPO', value: repo), + string(name: 'BRANCH', value: branch), + string(name: 'TEST_PACKAGE', value: "provisioning/..."), + string(name: 'GOTEST_TESTCASE', value: "${GO_EXTEND_PROVISIONING_TEST_CASES}") ] + + goValidationParams = [ string(name: 'TIMEOUT', value: "1h"), + text(name: 'CONFIG', value: cleanupYaml), + string(name: 'REPO', value: repo), + string(name: 'BRANCH', value: branch), + string(name: 'TEST_PACKAGE', value: "..."), + string(name: 'GOTEST_TESTCASE', value: "${GO_VALIDATION_TEST_CASES} -p 1") ] + + pythonParam0 = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: env.ADMIN_TOKEN), + string(name: 'USER_TOKEN', value: env.USER_TOKEN), + string(name: 'PYTEST_OPTIONS', value: "${PYTEST_OPTIONS}"), + string(name: 'BRANCH', value: defaultBranch), + string(name: 'RANCHER_CLUSTER_NAME', value: env.RANCHER_CLUSTER0) ] + + pythonParam1 = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: env.ADMIN_TOKEN), + string(name: 'USER_TOKEN', value: env.USER_TOKEN), + string(name: 'BRANCH', value: defaultBranch), + string(name: 'PYTEST_OPTIONS', value: "${PYTEST_OPTIONS_ADDITIONAL}"), + string(name: 'RANCHER_CLUSTER_NAME', value: env.RANCHER_CLUSTER1) ] + // Go provisioning base tests + jobs["go-provisioning"] = { build job: 'go-automation-freeform-job', parameters: goProvisioningParams } + // Go provisioning tests + jobs["go-extent-provisioning"] = { build job: 'go-automation-freeform-job', parameters: goExtendedProvisioningParams } + // Go charts tests + jobs["go-validations"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + // python cluster tests + jobs["python-cluster-test"] = { build job: 'rancher-v3_needs_cluster', parameters: pythonParam0} + // python additional tests + jobs["python-additional-cluster-test"] = { build job: 'rancher-v3_needs_cluster', parameters: pythonParam1} + parallel jobs + } catch(err) { + echo "Validation SubJobs had failures ${err}" + } + + } + stage ('Run Python Integration Tests') { + try { + sh "docker run --name ${pythonTestContainer} --env-file ${envFile} " + + "${goImageName} /bin/bash -c \'cd ${rootPath}tests/integration;tox -e rancher -- -m \"not nonparallel\" -n 8;tox -e rancher -- -m nonparallel\'" + } catch(err) { + echo "Python Integration tests had failures." + } + } + stage ('Run V2Prov Tests') { + try { + sh "docker run --volumes-from ${golangTestContainer} --name ${v2ProvTestContainer} --env-file ${envFile} " + + "${goImageName} sh -c \"${workPath}scripts/run_provisioning_integration_tests.sh\"" + } catch(err) { + echo "Python Integration tests had failures." + } + } + stage("Code Coverage Report") { + sh "docker run --volumes-from ${golangTestContainer} --name ${codeCoverTestContainer} -t --env-file ${envFile} " + + "${goImageName} sh -c \"gotestsum --format standard-verbose --packages=${codeCoverageDir} -- ${codeCoverageTest} -timeout=${timeout} -v;cd ${workPath}scripts; . ./merge_coverage_reports.sh\"" + } + stage('Cleanup Rancher Environment') { + try { + if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") { + sh "docker run --volumes-from ${golangTestContainer} --name ${cleanupContainer} -t --env-file ${envFile} " + + " ${goImageName} sh -c \"${workPath}bin/ranchercleanup\"" + } + } catch(err) { + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + + sh "docker stop ${integrationTestContainer}" + sh "docker rm -v ${integrationTestContainer}" + + sh "docker stop ${pythonTestContainer}" + sh "docker rm -v ${pythonTestContainer}" + + sh "docker stop ${v2ProvTestContainer}" + sh "docker rm -v ${v2ProvTestContainer}" + + sh "docker stop ${golangUnitTestContainer}" + sh "docker rm -v ${golangUnitTestContainer}" + sh "docker stop ${codeCoverTestContainer}" + sh "docker rm -v ${codeCoverTestContainer}" + sh "docker rmi -f ${goImageName}" + sh "docker volume rm -f ${code_cover_volume}" + error "Cleanup had failures." + } + } + stage('Test Report') { + try { + sh "docker cp ${codeCoverTestContainer}:${workPath}ranchercover/${coverDir}${mergedCovFile} ." + sh "docker cp ${codeCoverTestContainer}:${workPath}ranchercover/${coverDir}${mergedHTMLFile} ." + archiveArtifacts(artifacts: "**/${mergedCovFile}", + allowEmptyArchive: true, + fingerprint: true, + onlyIfSuccessful: true) + + sh "docker cp ${golangUnitTestContainer}:${rootPath}${unitTestCoverfile} ." + sh "docker cp ${golangUnitTestContainer}:${rootPath}${unitTestHTMLfile} ." + archiveArtifacts(artifacts: "**/${unitTestCoverfile}", + allowEmptyArchive: true, + fingerprint: true, + onlyIfSuccessful: true) + // publishHTML (target: [ + // allowMissing: false, + // alwaysLinkToLastBuild: true, + // keepAll: true, + // reportDir: ".", + // reportFiles: mergedHTMLFile, + // reportName: "Single-click Code Coverage Test Results" + // ]) + } catch (err) { + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + + sh "docker stop ${integrationTestContainer}" + sh "docker rm -v ${integrationTestContainer}" + + sh "docker stop ${pythonTestContainer}" + sh "docker rm -v ${pythonTestContainer}" + + sh "docker stop ${v2ProvTestContainer}" + sh "docker rm -v ${v2ProvTestContainer}" + sh "docker stop ${golangUnitTestContainer}" + sh "docker rm -v ${golangUnitTestContainer}" + sh "docker stop ${codeCoverTestContainer}" + sh "docker rm -v ${codeCoverTestContainer}" + sh "docker rmi -f ${goImageName}" + sh "docker volume rm -f ${code_cover_volume}" + error 'Report had failures.' + } + stage('Clean Up Containers, Image, and Volume') { + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + + sh "docker stop ${integrationTestContainer}" + sh "docker rm -v ${integrationTestContainer}" + + sh "docker stop ${pythonTestContainer}" + sh "docker rm -v ${pythonTestContainer}" + + sh "docker stop ${v2ProvTestContainer}" + sh "docker rm -v ${v2ProvTestContainer}" + sh "docker stop ${golangUnitTestContainer}" + sh "docker rm -v ${golangUnitTestContainer}" + sh "docker stop ${codeCoverTestContainer}" + sh "docker rm -v ${codeCoverTestContainer}" + sh "docker rmi -f ${goImageName}" + sh "docker volume rm -f ${code_cover_volume}" + } + } // test report + } // dir + } // creds + } // withEnv + } // folder properties + } // wrap +}// node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/agent/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/agent/main.go new file mode 100644 index 0000000..d743ff7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/agent/main.go @@ -0,0 +1,622 @@ +package main + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "log" + "net/http" + _ "net/http/pprof" + "net/url" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/client" + "github.com/mattn/go-colorable" + "github.com/rancher/rancher/pkg/agent/clean" + "github.com/rancher/rancher/pkg/agent/cluster" + "github.com/rancher/rancher/pkg/agent/node" + "github.com/rancher/rancher/pkg/agent/rancher" + "github.com/rancher/rancher/pkg/features" + "github.com/rancher/rancher/pkg/logserver" + "github.com/rancher/rancher/pkg/rkenodeconfigclient" + "github.com/rancher/rancher/pkg/rkenodeconfigserver" + "github.com/rancher/remotedialer" + "github.com/rancher/shepherd/pkg/killserver" + "github.com/rancher/wrangler/v3/pkg/signals" + "github.com/sirupsen/logrus" +) + +var ( + VERSION = "dev" +) + +const ( + Token = "X-API-Tunnel-Token" + KubeletCertValidityLimit = time.Hour * 72 +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + + killServer := killserver.NewKillServer(killserver.Port, cancel) + + go killServer.Start() + go runAgent(ctx) + <-ctx.Done() +} + +func runAgent(ctx context.Context) { + var err error + + if len(os.Args) > 1 { + err = runArgs(ctx) + } else { + if _, err = reconcileKubelet(ctx); err != nil { + logrus.Warnf("failed to reconcile kubelet, error: %v", err) + } + + logrus.SetOutput(colorable.NewColorableStdout()) + logserver.StartServerWithDefaults() + if os.Getenv("CATTLE_DEBUG") == "true" || os.Getenv("RANCHER_DEBUG") == "true" { + logrus.SetLevel(logrus.DebugLevel) + } + + initFeatures() + + if os.Getenv("CLUSTER_CLEANUP") == "true" { + err = clean.Cluster() + } else if os.Getenv("BINDING_CLEANUP") == "true" { + err = errors.Join( + clean.DuplicateBindings(nil), + clean.OrphanBindings(nil), + clean.OrphanCatalogBindings(nil), + ) + } else { + err = run(ctx) + } + } + + if err != nil { + logrus.Fatal(err) + } +} + +func runArgs(ctx context.Context) error { + switch os.Args[1] { + case "clean": + return clean.Run(ctx, os.Args) + default: + return run(ctx) + } +} + +func initFeatures() { + features.InitializeFeatures(nil, os.Getenv("CATTLE_FEATURES")) +} + +func isCluster() bool { + return os.Getenv("CATTLE_CLUSTER") == "true" +} + +func getParams() (map[string]interface{}, error) { + if isCluster() { + return cluster.Params() + } + return node.Params(), nil +} + +func getTokenAndURL() (string, string, error) { + token, url, err := node.TokenAndURL() + if err != nil { + return "", "", err + } + if token == "" { + return cluster.TokenAndURL() + } + return token, url, nil +} + +func isConnect() bool { + if os.Getenv("CATTLE_AGENT_CONNECT") == "true" { + return true + } + _, err := os.Stat("connected") + return err == nil +} + +func connected() { + f, err := os.Create("connected") + if err != nil { + f.Close() + } +} + +func cleanup(ctx context.Context) error { + if os.Getenv("CATTLE_K8S_MANAGED") != "true" { + return nil + } + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return err + } + defer c.Close() + + args := filters.NewArgs() + args.Add("label", "io.cattle.agent=true") + + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + return err + } + + for _, container := range containers { + if _, ok := container.Labels["io.kubernetes.pod.namespace"]; ok { + continue + } + + if strings.Contains(container.Names[0], "share-mnt") { + continue + } + + container := container + go func() { + time.Sleep(15 * time.Second) + logrus.Infof("Removing unmanaged agent %s(%s)", container.Names[0], container.ID) + c.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{ + Force: true, + }) + }() + } + + return nil +} + +func run(ctx context.Context) error { + topContext := signals.SetupSignalContext() + + logrus.Infof("Rancher agent version %s is starting", VERSION) + params, err := getParams() + if err != nil { + return err + } + writeCertsOnly := os.Getenv("CATTLE_WRITE_CERT_ONLY") == "true" + bytes, err := json.Marshal(params) + if err != nil { + return err + } + + token, server, err := getTokenAndURL() + if err != nil { + return err + } + + headers := http.Header{ + Token: {token}, + rkenodeconfigclient.Params: {base64.StdEncoding.EncodeToString(bytes)}, + } + + err = KubeletNeedsNewCertificate(headers) + if err != nil { + return err + } + + serverURL, err := url.Parse(server) + if err != nil { + return err + } + + // Check if secure connection can be made successfully + var httpClient = &http.Client{ + Timeout: time.Second * 5, + } + + _, err = httpClient.Get(server) + if err != nil { + if strings.Contains(err.Error(), "x509:") { + certErr := err + if strings.Contains(err.Error(), "certificate signed by unknown authority") { + certErr = fmt.Errorf("Certificate chain is not complete, please check if all needed intermediate certificates are included in the server certificate (in the correct order) and if the cacerts setting in Rancher either contains the correct CA certificate (in the case of using self signed certificates) or is empty (in the case of using a certificate signed by a recognized CA). Certificate information is displayed above. error: %s", err) + } + if strings.Contains(err.Error(), "certificate has expired or is not yet valid") { + certErr = fmt.Errorf("Server certificate is not valid, please check if the host has the correct time configured and if the server certificate has a notAfter date and time in the future. Certificate information is displayed above. error: %s", err) + } + if strings.Contains(err.Error(), "because it doesn't contain any IP SANs") || strings.Contains(err.Error(), "certificate is not valid for any names, but wanted to match") || strings.Contains(err.Error(), "cannot validate certificate for") { + certErr = fmt.Errorf("Server certificate does not contain correct DNS and/or IP address entries in the Subject Alternative Names (SAN). Certificate information is displayed above. error: %s", err) + } + insecureClient := &http.Client{ + Timeout: time.Second * 5, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } + res, err := insecureClient.Get(server) + if err != nil { + logrus.Errorf("Could not connect to %s: %v", server, err) + os.Exit(1) + } + var lastFoundIssuer string + if res.TLS != nil && len(res.TLS.PeerCertificates) > 0 { + logrus.Infof("Certificate details from %s", serverURL) + var previouscert *x509.Certificate + for i := range res.TLS.PeerCertificates { + cert := res.TLS.PeerCertificates[i] + logrus.Infof("Certificate #%d (%s)", i, serverURL) + certinfo(cert) + if i > 0 { + if previouscert.Issuer.String() != cert.Subject.String() { + logrus.Errorf("Certficate's Subject (%s) does not match with previous certificate Issuer (%s). Please check if the configured server certificate contains all needed intermediate certificates and make sure they are in the correct order (server certificate first, intermediates after)", cert.Subject.String(), previouscert.Issuer.String()) + } + } + previouscert = cert + lastFoundIssuer = cert.Issuer.String() + } + } + caFileLocation := "/etc/kubernetes/ssl/certs/serverca" + if _, err := os.Stat(caFileLocation); err == nil { + caFile, err := os.ReadFile(caFileLocation) + if err != nil { + return err + } + var blocks [][]byte + for { + var certDERBlock *pem.Block + certDERBlock, caFile = pem.Decode(caFile) + if certDERBlock == nil { + break + } + + if certDERBlock.Type == "CERTIFICATE" { + blocks = append(blocks, certDERBlock.Bytes) + } + } + if len(blocks) > 1 { + logrus.Warnf("Found %d certificates at %s, should be 1", len(blocks), caFileLocation) + } + logrus.Infof("Certificate details for %s", caFileLocation) + + blockcount := 0 + var lastCACert *x509.Certificate + for _, block := range blocks { + cert, err := x509.ParseCertificate(block) + if err != nil { + logrus.Println(err) + continue + } + + logrus.Infof("Certificate #%d (%s)", blockcount, caFileLocation) + certinfo(cert) + + blockcount = blockcount + 1 + lastCACert = cert + } + if lastFoundIssuer != lastCACert.Issuer.String() { + logrus.Errorf("Issuer of last certificate found in chain (%s) does not match with CA certificate Issuer (%s). Please check if the configured server certificate contains all needed intermediate certificates and make sure they are in the correct order (server certificate first, intermediates after)", lastFoundIssuer, lastCACert.Issuer.String()) + } + } + return certErr + } + } + + onConnect := func(ctx context.Context, _ *remotedialer.Session) error { + connected() + connectConfig := fmt.Sprintf("https://%s/v3/connect/config", serverURL.Host) + httpClient := http.Client{ + Timeout: 300 * time.Second, + } + interval, err := rkenodeconfigclient.ConfigClient(ctx, &httpClient, connectConfig, headers, writeCertsOnly) + if err != nil { + return err + } + + if writeCertsOnly { + exitCertWriter(ctx) + } + + if isCluster() { + err = rancher.Run(topContext) + if err != nil { + logrus.Fatal(err) + } + return nil + } + + if err := cleanup(context.Background()); err != nil { + logrus.Warnf("Unable to perform docker cleanup: %v", err) + } + + go func() { + logrus.Infof("Starting plan monitor, checking every %v seconds", interval) + tt := time.Duration(interval) * time.Second + for { + select { + case <-time.After(tt): + // each time we request a plan we should + // check if our cert about to expire + err = KubeletNeedsNewCertificate(headers) + if err != nil { + logrus.Errorf("failed to check validity of kubelet certs: %v", err) + } + receivedInterval, err := rkenodeconfigclient.ConfigClient(ctx, &httpClient, connectConfig, headers, writeCertsOnly) + if err != nil { + logrus.Errorf("failed to check plan: %v", err) + } else if receivedInterval != 0 && receivedInterval != interval { + tt = time.Duration(receivedInterval) * time.Second + logrus.Infof("Plan monitor checking %v seconds", receivedInterval) + } + + case <-ctx.Done(): + return + } + } + }() + + return nil + } + + if isCluster() { + go func() { + log.Println(http.ListenAndServe("localhost:6060", nil)) + }() + } + + for { + wsURL := fmt.Sprintf("wss://%s/v3/connect", serverURL.Host) + if !isConnect() { + wsURL += "/register" + } + + // check if we need a new kubelet cert on reconnection + err = KubeletNeedsNewCertificate(headers) + if err != nil { + return err + } + + logrus.Infof("Connecting to %s with token starting with %s", wsURL, token[:len(token)/2]) + logrus.Tracef("Connecting to %s with token %s", wsURL, token) + remotedialer.ClientConnect(ctx, wsURL, headers, nil, func(proto, address string) bool { + switch proto { + case "tcp": + return true + case "unix": + return address == "/var/run/docker.sock" + case "npipe": + return address == "//./pipe/docker_engine" + } + return false + }, onConnect) + time.Sleep(5 * time.Second) + } +} + +func exitCertWriter(ctx context.Context) { + // share-mnt process needs an always restart policy and to be killed so it can restart on startup + // this functionality is really only needed for OSes with ephemeral /etc like RancherOS + // everything here will just exit(0) with errors as we need to bail out completely. + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGTERM) + // trap SIGTERM here so that container can exit with 0 + go func() { + <-sigs + os.Exit(0) + }() + + logrus.Info("attempting to stop the share-mnt container so it can reboot on startup") + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + logrus.Error(err) + os.Exit(0) + } + + args := filters.NewArgs() + args.Add("label", "io.rancher.rke.container.name=share-mnt") + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + logrus.Error(err) + os.Exit(0) + } + + for _, container := range containers { + if len(container.Names) > 0 && strings.Contains(container.Names[0], "share-mnt") { + err := c.ContainerKill(ctx, container.ID, "SIGTERM") + if err != nil { + logrus.Error(err) + os.Exit(0) // only need to write certs so exit cleanly + } + } + } + // wait for itself to be kill with SIGTERM so it can return exit 0 + select {} +} + +func certinfo(cert *x509.Certificate) { + logrus.Infof("Subject: %+v", cert.Subject) + logrus.Infof("Issuer: %+v", cert.Issuer) + logrus.Infof("IsCA: %+v", cert.IsCA) + if len(cert.DNSNames) > 0 { + logrus.Infof("DNS Names: %+v", cert.DNSNames) + } else { + logrus.Infof("DNS Names: ") + } + if len(cert.IPAddresses) > 0 { + logrus.Infof("IPAddresses: %+v", cert.IPAddresses) + } else { + logrus.Info("IPAddresses: ") + } + logrus.Infof("NotBefore: %+v", cert.NotBefore) + logrus.Infof("NotAfter: %+v", cert.NotAfter) + logrus.Infof("SignatureAlgorithm: %+v", cert.SignatureAlgorithm) + logrus.Infof("PublicKeyAlgorithm: %+v", cert.PublicKeyAlgorithm) +} + +// reconcileKubelet restarts kubelet in unmanaged agents +func reconcileKubelet(ctx context.Context) (bool, error) { + if os.Getenv("CATTLE_K8S_MANAGED") == "true" { + return true, nil + } + + writeCertsOnly := os.Getenv("CATTLE_WRITE_CERT_ONLY") == "true" + if writeCertsOnly { + return true, nil + } + + c, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.FromEnv) + if err != nil { + return false, err + } + defer c.Close() + + args := filters.NewArgs() + args.Add("label", "io.rancher.rke.container.name=kubelet") + + containers, err := c.ContainerList(ctx, types.ContainerListOptions{ + All: true, + Filters: args, + }) + if err != nil { + return false, err + } + + for _, container := range containers { + if len(container.Names) > 0 && strings.Contains(container.Names[0], "kubelet") { + nodeName := os.Getenv("CATTLE_NODE_NAME") + logrus.Infof("node %v is not registered, restarting kubelet now", nodeName) + if err := c.ContainerRestart(ctx, container.ID, nil); err != nil { + return false, err + } + break + } + } + return false, nil +} + +// KubeletNeedsNewCertificate will set the +// 'RegenerateKubeletCertificate' header field to true if +// a) the kubelet serving certificate does not exist +// b) the certificate will expire in 72 hours +// c) the certificate does not accurately represent the +// +// current IP address and Hostname of the node +// +// While the agent may denote it needs a new kubelet certificate +// in its connection request, a new certificate will only be +// delivered by Rancher if the generate_serving_certificate property +// is set to 'true' for the clusters kubelet service. +func KubeletNeedsNewCertificate(headers http.Header) error { + currentHostname := os.Getenv("CATTLE_NODE_NAME") + + // RKE will save the certs on the node using either the public or private IP address, depending on the infrastructure provider. + // For example, the certs will be stored using the public IP address for VM's on digital ocean, but will use the private IP + // address for VM's on AWS. We do not know which IP address RKE decided to use, so we need to check both locations. + kubeletCertFile, kubeletCertKeyFile, ipAddress := findCertificateFiles(os.Getenv("CATTLE_ADDRESS"), os.Getenv("CATTLE_INTERNAL_ADDRESS")) + if kubeletCertFile == "" || kubeletCertKeyFile == "" || ipAddress == "" { + logrus.Tracef("did not find kubelet certificate files using either public ip address (%s) or private ip address (%s)", os.Getenv("CATTLE_ADDRESS"), os.Getenv("CATTLE_INTERNAL_ADDRESS")) + } + + cert, err := tls.LoadX509KeyPair(kubeletCertFile, kubeletCertKeyFile) + if err != nil && !strings.Contains(err.Error(), "no such file") { + return err + } + + needsRegen, err := KubeletCertificateNeedsRegeneration(ipAddress, currentHostname, cert, time.Now()) + if err != nil { + return err + } + + if needsRegen { + headers.Set(rkenodeconfigserver.RegenerateKubeletCertificate, "true") + } else { + headers.Set(rkenodeconfigserver.RegenerateKubeletCertificate, "false") + } + + return nil +} + +func findCertificateFiles(IPAddresses ...string) (string, string, string) { + for _, ip := range IPAddresses { + fileSafeIPAddress := strings.ReplaceAll(ip, ".", "-") + certFile := fmt.Sprintf("/etc/kubernetes/ssl/kube-kubelet-%s.pem", fileSafeIPAddress) + certKeyFile := fmt.Sprintf("/etc/kubernetes/ssl/kube-kubelet-%s-key.pem", fileSafeIPAddress) + _, certErr := os.Stat(certFile) + _, keyErr := os.Stat(certKeyFile) + // check that both files exist + if certErr == nil && keyErr == nil { + return certFile, certKeyFile, ip + } + } + return "", "", "" +} + +func KubeletCertificateNeedsRegeneration(ipAddress, currentHostname string, cert tls.Certificate, currentTime time.Time) (bool, error) { + if len(cert.Certificate) == 0 { + return true, nil + } + + parsedCert, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return false, err + } + + if !CertificateIncludesHostname(currentHostname, parsedCert) { + logrus.Tracef("certificate does not include current hostname, requesting new certificate") + return true, nil + } + + if CertificateIsExpiring(parsedCert, currentTime) { + logrus.Tracef("certificate is expiring soon, requesting new certificate") + return true, nil + } + + if !CertificateIncludesCurrentIP(ipAddress, parsedCert) { + logrus.Tracef("certificate does not include current IP address, requesting new certificate") + return true, nil + } + + return false, nil +} + +// CertificateIsExpiring checks if the passed certificate will expire within +// the KubeletCertValidityLimit +func CertificateIsExpiring(cert *x509.Certificate, currentTime time.Time) bool { + return cert.NotAfter.Sub(currentTime) < KubeletCertValidityLimit +} + +// CertificateIncludesHostname checks that the passed certificate includes +// the provided hostname in its SAN list +func CertificateIncludesHostname(hostname string, cert *x509.Certificate) bool { + for _, name := range cert.DNSNames { + if name == hostname { + return true + } + } + return false +} + +// CertificateIncludesCurrentIP checks that the passed certificate includes the provided IP address +func CertificateIncludesCurrentIP(ipAddress string, cert *x509.Certificate) bool { + for _, ip := range cert.IPAddresses { + if ipAddress == ip.String() { + return true + } + } + return false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile new file mode 100644 index 0000000..5fdb376 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile @@ -0,0 +1,282 @@ +FROM registry.suse.com/bci/bci-micro:15.6 AS final + +# Temporary build stage image +FROM registry.suse.com/bci/bci-base:15.6 AS builder + +# Install system packages using builder image that has zypper +COPY --from=final / /chroot/ + +# Install some packages with zypper in the chroot of the final micro image +RUN zypper refresh && \ + zypper --installroot /chroot -n in --no-recommends \ + git-core curl util-linux ca-certificates ca-certificates-mozilla unzip xz gzip sed tar shadow gawk vim-small \ + netcat-openbsd mkisofs openssh-clients && \ + zypper --installroot /chroot clean -a && \ + rm -rf /chroot/var/cache/zypp/* /chroot/var/log/zypp/* /chroot/tmp/* /chroot/var/tmp/* /chroot/usr/share/doc/packages/* + +# Main stage using bci-micro as the base image +FROM final + +# Copy binaries and configuration files from builder to micro +COPY --from=builder /chroot/ / + +# Test that some of the dependency binaries were copied +# and are working on the target image. +RUN /usr/bin/unshare --version && \ + /usr/bin/mount --version && \ + /usr/bin/umount --version && \ + /usr/bin/nsenter --version + +RUN useradd rancher && \ + mkdir -p /var/lib/rancher /var/lib/cattle /opt/jail /opt/drivers/management-state/bin && \ + chown -R rancher /var/lib/rancher /var/lib/cattle /usr/local/bin + +RUN mkdir /root/.kube && \ + ln -s /etc/rancher/k3s/k3s.yaml /root/.kube/k3s.yaml && \ + ln -s /etc/rancher/k3s/k3s.yaml /root/.kube/config && \ + ln -s $(GOCOVERDIR=ranchercoverage /usr/bin/rancher) /usr/bin/reset-password && \ + ln -s $(GOCOVERDIR=ranchercoverage /usr/bin/rancher) /usr/bin/ensure-default-admin +WORKDIR /var/lib/rancher + +ARG ARCH=amd64 +ARG ETCD_UNSUPPORTED_ARCH +ARG IMAGE_REPO=rancher +ARG SYSTEM_CHART_DEFAULT_BRANCH=release-v2.9 +ARG CHART_DEFAULT_BRANCH=release-v2.9 +ARG PARTNER_CHART_DEFAULT_BRANCH=main +ARG RKE2_CHART_DEFAULT_BRANCH=main +# kontainer-driver-metadata branch to be set for specific branch other than dev/master, logic at rancher/rancher/pkg/settings/setting.go +ARG CATTLE_KDM_BRANCH=release-v2.9 + +ENV CATTLE_SYSTEM_CHART_DEFAULT_BRANCH=$SYSTEM_CHART_DEFAULT_BRANCH +ENV CATTLE_CHART_DEFAULT_BRANCH=$CHART_DEFAULT_BRANCH +ENV CATTLE_PARTNER_CHART_DEFAULT_BRANCH=$PARTNER_CHART_DEFAULT_BRANCH +ENV CATTLE_RKE2_CHART_DEFAULT_BRANCH=$RKE2_CHART_DEFAULT_BRANCH +ENV CATTLE_HELM_VERSION v2.16.8-rancher2 +ENV CATTLE_MACHINE_VERSION v0.15.0-rancher116 +ENV CATTLE_K3S_VERSION v1.30.2+k3s2 +ENV CATTLE_MACHINE_PROVISION_IMAGE rancher/machine:${CATTLE_MACHINE_VERSION} +ENV CATTLE_ETCD_VERSION v3.5.14 +ENV LOGLEVEL_VERSION v0.1.6 +ENV TINI_VERSION v0.18.0 +ENV TELEMETRY_VERSION v0.5.20 +ENV DOCKER_MACHINE_LINODE_VERSION v0.1.12 +ENV LINODE_UI_DRIVER_VERSION v0.7.0 +# make sure the version number is consistent with the one at Line 100 of pkg/data/management/machinedriver_data.go +ENV DOCKER_MACHINE_HARVESTER_VERSION v0.6.5 +ENV CATTLE_KDM_BRANCH ${CATTLE_KDM_BRANCH} +ENV HELM_VERSION v3.15.2 +ENV KUSTOMIZE_VERSION v5.4.2 +ENV CATTLE_WINS_AGENT_VERSION v0.4.17 +ENV CATTLE_WINS_AGENT_INSTALL_SCRIPT https://raw.githubusercontent.com/rancher/wins/${CATTLE_WINS_AGENT_VERSION}/install.ps1 +ENV CATTLE_WINS_AGENT_UNINSTALL_SCRIPT https://raw.githubusercontent.com/rancher/wins/${CATTLE_WINS_AGENT_VERSION}/uninstall.ps1 +ENV CATTLE_WINS_AGENT_UPGRADE_IMAGE rancher/wins:${CATTLE_WINS_AGENT_VERSION} +ENV CATTLE_CSI_PROXY_AGENT_VERSION v1.1.3 +# make sure the CATTLE_SYSTEM_AGENT_VERSION is consistent with tests/v2/codecoverage/package/Dockerfile +ENV CATTLE_SYSTEM_AGENT_VERSION v0.3.8 +ENV CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX https://github.com/rancher/system-agent/releases/download +ENV CATTLE_SYSTEM_AGENT_UPGRADE_IMAGE rancher/system-agent:${CATTLE_SYSTEM_AGENT_VERSION}-suc +ENV CATTLE_SYSTEM_AGENT_INSTALLER_IMAGE rancher/system-agent-installer- +ENV CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/install.sh +ENV CATTLE_SYSTEM_AGENT_UNINSTALL_SCRIPT ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh +ENV CATTLE_SYSTEM_UPGRADE_CONTROLLER_CHART_VERSION 104.0.0+up0.7.0 + +# AKS,EKS,GKE Operator charts versions +ARG CATTLE_AKS_OPERATOR_VERSION +ENV CATTLE_AKS_OPERATOR_VERSION=$CATTLE_AKS_OPERATOR_VERSION +ARG CATTLE_EKS_OPERATOR_VERSION +ENV CATTLE_EKS_OPERATOR_VERSION=$CATTLE_EKS_OPERATOR_VERSION +ARG CATTLE_GKE_OPERATOR_VERSION +ENV CATTLE_GKE_OPERATOR_VERSION=$CATTLE_GKE_OPERATOR_VERSION + +# System charts minimal version +# Deprecated in favor of CATTLE_FLEET_VERSION +ENV CATTLE_FLEET_MIN_VERSION="" +ARG CATTLE_FLEET_VERSION +ENV CATTLE_FLEET_VERSION=$CATTLE_FLEET_VERSION +ARG CATTLE_RANCHER_WEBHOOK_VERSION +ENV CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION +ARG CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ENV CATTLE_RANCHER_PROVISIONING_CAPI_VERSION=$CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ARG CATTLE_CSP_ADAPTER_MIN_VERSION +ENV CATTLE_CSP_ADAPTER_MIN_VERSION=$CATTLE_CSP_ADAPTER_MIN_VERSION + +RUN mkdir -p /var/lib/rancher-data/local-catalogs/system-library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/helm3-library && \ + mkdir -p /var/lib/rancher-data/local-catalogs/v2 && \ + git clone -b $CATTLE_SYSTEM_CHART_DEFAULT_BRANCH --depth 1 https://github.com/rancher/system-charts /var/lib/rancher-data/local-catalogs/system-library && \ + # Temporarily clone from our GitHub's main repo, to avoid unnecessary load + # in git.rancher.io + git config --global url."https://github.com/rancher/".insteadOf https://git.rancher.io/ && \ + # Charts need to be copied into the sha256 value of git url computed in https://github.com/rancher/rancher/blob/5ebda9ac23c06e9647b586ec38aa51cc9ff9b031/pkg/catalogv2/git/download.go#L102 to create a unique folder per url + git clone -b $CATTLE_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/charts /var/lib/rancher-data/local-catalogs/v2/rancher-charts/4b40cac650031b74776e87c1a726b0484d0877c3ec137da0872547ff9b73a721/ && \ + git clone -b $CATTLE_PARTNER_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/partner-charts /var/lib/rancher-data/local-catalogs/v2/rancher-partner-charts/8f17acdce9bffd6e05a58a3798840e408c4ea71783381ecd2e9af30baad65974 && \ + git clone -b $CATTLE_RKE2_CHART_DEFAULT_BRANCH --depth 1 https://git.rancher.io/rke2-charts /var/lib/rancher-data/local-catalogs/v2/rancher-rke2-charts/675f1b63a0a83905972dcab2794479ed599a6f41b86cd6193d69472d0fa889c9 && \ + # Revert the previous change in git.rancher.io from .gitconfig + rm "${HOME}/.gitconfig" && \ + git clone -b master --depth 1 https://github.com/rancher/charts /var/lib/rancher-data/local-catalogs/library && \ + git clone -b master --depth 1 https://github.com/rancher/helm3-charts /var/lib/rancher-data/local-catalogs/helm3-library + +RUN curl -sLf https://github.com/rancher/machine/releases/download/${CATTLE_MACHINE_VERSION}/rancher-machine-${ARCH}.tar.gz | tar xvzf - -C /usr/bin && \ + curl -sLf https://github.com/rancher/loglevel/releases/download/${LOGLEVEL_VERSION}/loglevel-${ARCH}-${LOGLEVEL_VERSION}.tar.gz | tar xvzf - -C /usr/bin && \ + curl -LO https://github.com/linode/docker-machine-driver-linode/releases/download/${DOCKER_MACHINE_LINODE_VERSION}/docker-machine-driver-linode_linux-amd64.zip && \ + unzip docker-machine-driver-linode_linux-amd64.zip -d /opt/drivers/management-state/bin && \ + mkdir -p /usr/share/rancher/ui/assets/ && \ + cp /opt/drivers/management-state/bin/docker-machine-driver-linode /usr/share/rancher/ui/assets/ && \ + rm docker-machine-driver-linode_linux-amd64.zip + +RUN curl -LO https://releases.rancher.com/harvester-node-driver/${DOCKER_MACHINE_HARVESTER_VERSION}/docker-machine-driver-harvester-amd64.tar.gz && \ + tar -xf docker-machine-driver-harvester-amd64.tar.gz -C /opt/drivers/management-state/bin && \ + cp /opt/drivers/management-state/bin/docker-machine-driver-harvester /usr/share/rancher/ui/assets/ && \ + rm docker-machine-driver-harvester-amd64.tar.gz + +ENV TINI_URL_amd64=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini \ + TINI_URL_arm64=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-arm64 \ + TINI_URL_s390x=https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-s390x \ + TINI_URL=TINI_URL_${ARCH} + +ENV HELM_URL_V2_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm \ + HELM_URL_V2_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-arm64 \ + HELM_URL_V2_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-helm-s390x \ + HELM_URL_V2=HELM_URL_V2_${ARCH} \ + HELM_URL_V3=https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz \ + TILLER_URL_amd64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller \ + TILLER_URL_arm64=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-arm64 \ + TILLER_URL_s390x=https://github.com/rancher/helm/releases/download/${CATTLE_HELM_VERSION}/rancher-tiller-s390x \ + TILLER_URL=TILLER_URL_${ARCH} \ + ETCD_URL=https://github.com/etcd-io/etcd/releases/download/${CATTLE_ETCD_VERSION}/etcd-${CATTLE_ETCD_VERSION}-linux-${ARCH}.tar.gz \ + KUSTOMIZE_URL=https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize/${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz + +RUN curl -sLf ${KUSTOMIZE_URL} | tar -xzf - -C /usr/bin + +# set up helm 2 +RUN curl -sLf ${!HELM_URL_V2} > /usr/bin/rancher-helm && \ + curl -sLf ${!TILLER_URL} > /usr/bin/rancher-tiller && \ + ln -s /usr/bin/rancher-helm /usr/bin/helm && \ + ln -s /usr/bin/rancher-tiller /usr/bin/tiller && \ + chmod +x /usr/bin/rancher-helm /usr/bin/rancher-tiller + +# set up helm 3 +RUN curl ${HELM_URL_V3} | tar xvzf - --strip-components=1 -C /usr/bin && \ + mv /usr/bin/helm /usr/bin/helm_v3 && \ + chmod +x /usr/bin/kustomize + +# Set up K3s: copy the necessary binaries from the K3s image. +COPY --from=rancher/k3s:v1.30.2-k3s2 \ + /bin/blkid \ + /bin/bandwidth \ + /bin/cni \ + /bin/conntrack \ + /bin/containerd \ + /bin/containerd-shim-runc-v2 \ + /bin/ethtool \ + /bin/firewall \ + /bin/ip \ + /bin/ipset \ + /bin/k3s \ + /bin/losetup \ + /bin/pigz \ + /bin/runc \ + /bin/which \ + /bin/aux/xtables-legacy-multi \ + /usr/bin/ + +RUN ln -s /usr/bin/cni /usr/bin/bridge && \ + ln -s /usr/bin/cni /usr/bin/flannel && \ + ln -s /usr/bin/cni /usr/bin/host-local && \ + ln -s /usr/bin/cni /usr/bin/loopback && \ + ln -s /usr/bin/cni /usr/bin/portmap && \ + ln -s /usr/bin/k3s /usr/bin/crictl && \ + ln -s /usr/bin/k3s /usr/bin/ctr && \ + ln -s /usr/bin/k3s /usr/bin/k3s-agent && \ + ln -s /usr/bin/k3s /usr/bin/k3s-etcd-snapshot && \ + ln -s /usr/bin/k3s /usr/bin/k3s-server && \ + ln -s /usr/bin/k3s /usr/bin/kubectl && \ + ln -s /usr/bin/pigz /usr/bin/unpigz && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/iptables-translate && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-save && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-restore && \ + ln -s /usr/bin/xtables-legacy-multi /usr/bin/ip6tables-translate + +RUN curl -sLf ${!TINI_URL} > /usr/bin/tini && \ + mkdir -p /var/lib/rancher/k3s/agent/images/ && \ + curl -sfL ${ETCD_URL} | tar xvzf - --strip-components=1 --no-same-owner -C /usr/bin/ etcd-${CATTLE_ETCD_VERSION}-linux-${ARCH}/etcdctl && \ + curl -sLf https://github.com/rancher/telemetry/releases/download/${TELEMETRY_VERSION}/telemetry-${ARCH} > /usr/bin/telemetry && \ + chmod +x /usr/bin/tini /usr/bin/telemetry && \ + mkdir -p /var/lib/rancher-data/driver-metadata + +ENV CATTLE_UI_VERSION 2.9.0-alpha2 +ENV CATTLE_DASHBOARD_UI_VERSION v2.9.0-alpha6 +ENV CATTLE_CLI_VERSION v2.9.0 + +# Base UI brand used as a fallback env setting (not user facing) to indicate this is a non-prime install +ENV CATTLE_BASE_UI_BRAND= + +# Please update the api-ui-version in pkg/settings/settings.go when updating the version here. +ENV CATTLE_API_UI_VERSION 1.1.11 + +RUN mkdir -p /var/log/auditlog +ENV AUDIT_LOG_PATH /var/log/auditlog/rancher-api-audit.log +ENV AUDIT_LOG_MAXAGE 10 +ENV AUDIT_LOG_MAXBACKUP 10 +ENV AUDIT_LOG_MAXSIZE 100 +ENV AUDIT_LEVEL 0 + +RUN mkdir -p /usr/share/rancher/ui && \ + cd /usr/share/rancher/ui && \ + curl -sL https://releases.rancher.com/ui/${CATTLE_UI_VERSION}.tar.gz | tar xvzf - --strip-components=1 && \ + mkdir -p assets/rancher-ui-driver-linode && \ + cd assets/rancher-ui-driver-linode && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/component.js && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/component.css && \ + curl -O https://linode.github.io/rancher-ui-driver-linode/releases/${LINODE_UI_DRIVER_VERSION}/linode.svg && \ + mkdir -p /usr/share/rancher/ui/api-ui && \ + cd /usr/share/rancher/ui/api-ui && \ + curl -sL https://releases.rancher.com/api-ui/${CATTLE_API_UI_VERSION}.tar.gz | tar xvzf - --strip-components=1 && \ + mkdir -p /usr/share/rancher/ui-dashboard/dashboard && \ + cd /usr/share/rancher/ui-dashboard/dashboard && \ + curl -sL https://releases.rancher.com/dashboard/${CATTLE_DASHBOARD_UI_VERSION}.tar.gz | tar xvzf - --strip-components=2 && \ + ln -s dashboard/index.html ../index.html && \ + cd ../../ui/assets && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-arm64 -O && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_DOWNLOAD_PREFIX}/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -O && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_INSTALL_SCRIPT} -o system-agent-install.sh && \ + curl -sfL ${CATTLE_SYSTEM_AGENT_UNINSTALL_SCRIPT} -o system-agent-uninstall.sh && \ + curl -sfL https://github.com/rancher/wins/releases/download/${CATTLE_WINS_AGENT_VERSION}/wins.exe -O && \ + curl -sfL https://acs-mirror.azureedge.net/csi-proxy/${CATTLE_CSI_PROXY_AGENT_VERSION}/binaries/csi-proxy-${CATTLE_CSI_PROXY_AGENT_VERSION}.tar.gz -O && \ + curl -sfL ${CATTLE_WINS_AGENT_INSTALL_SCRIPT} -o wins-agent-install.ps1 \ + curl -sfL ${CATTLE_WINS_AGENT_UNINSTALL_SCRIPT} -o wins-agent-uninstall.ps1 + +ENV CATTLE_CLI_URL_DARWIN https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-darwin-amd64-${CATTLE_CLI_VERSION}.tar.gz +ENV CATTLE_CLI_URL_LINUX https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-linux-amd64-${CATTLE_CLI_VERSION}.tar.gz +ENV CATTLE_CLI_URL_WINDOWS https://releases.rancher.com/cli2/${CATTLE_CLI_VERSION}/rancher-windows-386-${CATTLE_CLI_VERSION}.zip + +ARG VERSION=dev +ENV CATTLE_SERVER_VERSION ${VERSION} +COPY run_rancher.sh rancher /usr/bin/ +COPY kustomize.sh /usr/bin/ +COPY jailer.sh /usr/bin/ +COPY k3s-airgap-images.tar /var/lib/rancher/k3s/agent/images/ +RUN chmod +x /usr/bin/run_rancher.sh +RUN chmod +x /usr/bin/kustomize.sh + +COPY data.json /var/lib/rancher-data/driver-metadata/ + +ENV CATTLE_AGENT_IMAGE ${IMAGE_REPO}/rancher-agent:${VERSION} +ENV CATTLE_SERVER_IMAGE ${IMAGE_REPO}/rancher +ENV ETCDCTL_API=3 + +ENV SSL_CERT_DIR /etc/rancher/ssl +VOLUME /var/lib/rancher +VOLUME /var/lib/kubelet +VOLUME /var/lib/cni +VOLUME /var/log + +ENV ETCD_UNSUPPORTED_ARCH ${ETCD_UNSUPPORTED_ARCH} + +ENTRYPOINT ["run_rancher.sh"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile.agent b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile.agent new file mode 100644 index 0000000..005be52 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/Dockerfile.agent @@ -0,0 +1,56 @@ +ARG RANCHER_TAG=dev +ARG RANCHER_REPO=rancher +FROM ${RANCHER_REPO}/rancher:${RANCHER_TAG} as rancher + +FROM registry.suse.com/bci/bci-micro:15.6 AS final + +# Temporary build stage image +FROM registry.suse.com/bci/bci-base:15.6 AS builder + +# Install system packages using builder image that has zypper +COPY --from=final / /chroot/ + +# Install some packages with zypper in the chroot of the final micro image +RUN zypper refresh && \ + zypper --installroot /chroot -n in --no-recommends \ + curl util-linux ca-certificates ca-certificates-mozilla jq git-core hostname iproute2 vim-small less \ + bash-completion bind-utils acl openssh-clients tar gzip xz gawk sysstat && \ + zypper --installroot /chroot clean -a && \ + rm -rf /chroot/var/cache/zypp/* /chroot/var/log/zypp/* /chroot/tmp/* /chroot/var/tmp/* /chroot/usr/share/doc/packages/* + +# Main stage using bco-micro as the base image +FROM final + +# Copy binaries and configuration files from builder to micro +COPY --from=builder /chroot/ / + +# Test that some of the dependency binaries were copied +# and are working on the target image. +RUN /usr/bin/unshare --version && \ + /usr/bin/mount --version && \ + /usr/bin/umount --version && \ + /usr/bin/nsenter --version + +ARG ARCH=amd64 +ENV KUBECTL_VERSION v1.27.10 + +RUN curl -sLf https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl > /usr/bin/kubectl && \ + chmod +x /usr/bin/kubectl + +ENV LOGLEVEL_VERSION v0.1.6 + +RUN curl -sLf https://github.com/rancher/loglevel/releases/download/${LOGLEVEL_VERSION}/loglevel-${ARCH}-${LOGLEVEL_VERSION}.tar.gz | tar xvzf - -C /usr/bin + +ARG VERSION=dev +LABEL io.cattle.agent true +ENV AGENT_IMAGE ${RANCHER_REPO}/rancher-agent:${VERSION} +ENV SSL_CERT_DIR /etc/kubernetes/ssl/certs +ARG CATTLE_RANCHER_WEBHOOK_VERSION +ENV CATTLE_RANCHER_WEBHOOK_VERSION=$CATTLE_RANCHER_WEBHOOK_VERSION +ARG CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +ENV CATTLE_RANCHER_PROVISIONING_CAPI_VERSION=$CATTLE_RANCHER_PROVISIONING_CAPI_VERSION +COPY --from=rancher /var/lib/rancher-data /var/lib/rancher-data +COPY --from=rancher /usr/bin/tini /usr/bin/ +COPY agent run_agent.sh kubectl-shell.sh shell-setup.sh /usr/bin/ +WORKDIR /var/lib/rancher +ENTRYPOINT ["run_agent.sh"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/jailer.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/jailer.sh new file mode 100755 index 0000000..e2c9a6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/jailer.sh @@ -0,0 +1,100 @@ +#!/bin/bash +set -e + +NAME=$1 + +if [[ -z "$1" ]] + then + echo "No name supplied" + exit 1 +fi + +# Build the jail directory structure +mkdir -p /opt/jail/$NAME/dev +mkdir -p /opt/jail/$NAME/etc/ssl +mkdir -p /opt/jail/$NAME/usr/bin +mkdir -p /opt/jail/$NAME/management-state/node/nodes +mkdir -p /opt/jail/$NAME/var/lib/rancher/management-state/bin +mkdir -p /opt/jail/$NAME/management-state/bin +mkdir -p /opt/jail/$NAME/tmp +mkdir -p /opt/jail/$NAME/bin + +# Copy over required files to the jail +if [[ -d /lib64 ]]; then + cp -r /lib64 /opt/jail/$NAME + cp -r /usr/lib64 /opt/jail/$NAME/usr +fi + +cp -r /lib /opt/jail/$NAME +cp -r /usr/lib /opt/jail/$NAME/usr +cp /var/lib/ca-certificates/ca-bundle.pem /opt/jail/$NAME/etc/ssl +cp /etc/resolv.conf /opt/jail/$NAME/etc/ +cp /etc/passwd /opt/jail/$NAME/etc/ +cp /etc/hosts /opt/jail/$NAME/etc/ +cp /etc/nsswitch.conf /opt/jail/$NAME/etc/ + +if [ -d /var/lib/rancher/management-state/bin ] && [ "$(ls -A /var/lib/rancher/management-state/bin)" ]; then + ( cd /var/lib/rancher/management-state/bin + for f in *; do + if [ ! -f "/opt/drivers/management-state/bin/$f" ]; then + cp "$f" "/opt/drivers/management-state/bin/$f" + fi + done + ) +fi + +if [[ -f /etc/ssl/certs/ca-additional.pem ]]; then + cp /etc/ssl/certs/ca-additional.pem /opt/jail/$NAME/etc/ssl +fi + +if [[ -f /etc/rancher/ssl/cacerts.pem ]]; then + cp /etc/rancher/ssl/cacerts.pem /opt/jail/$NAME/etc/ssl +fi + +# Hard link driver binaries +cp -r -l /opt/drivers/management-state/bin /opt/jail/$NAME/var/lib/rancher/management-state + +# Hard link rancher-machine into the jail +cp -l /usr/bin/rancher-machine /opt/jail/$NAME/usr/bin + +# Hard link helm_2 into the jail +cp -l /usr/bin/rancher-helm /opt/jail/$NAME/usr/bin + +# Hard link helm_3 into the jail +cp -l /usr/bin/helm_v3 /opt/jail/$NAME/usr/bin + +# Hard link tiller into the jail +cp -l /usr/bin/rancher-tiller /opt/jail/$NAME/usr/bin + +# Hard link kustomize into the jail +cp -l /usr/bin/kustomize /opt/jail/$NAME/usr/bin + +# Hard link custom kustomize script into jail +cp -l /usr/bin/kustomize.sh /opt/jail/$NAME + +# Hard link ssh into the jail +cp -l /usr/bin/ssh /opt/jail/$NAME/usr/bin + +# Hard link nc into the jail +cp -l /usr/bin/nc /opt/jail/$NAME/usr/bin + +# Hard link cat into the jail +cp -l /bin/cat /opt/jail/$NAME/bin/ + +# Hard link bash into the jail +cp -l /bin/bash /opt/jail/$NAME/bin/ + +# Hard link sh into the jail +cp -l /bin/sh /opt/jail/$NAME/bin/ + +# Hard link rm into the jail +cp -l /bin/rm /opt/jail/$NAME/bin/ + +# Hard link mkisofs into the jail +cp -l /usr/bin/mkisofs /opt/jail/$NAME/usr/bin + +cd /dev +# tar copy /dev excluding mqueue and shm +tar cf - --exclude=mqueue --exclude=shm --exclude=pts . | (cd /opt/jail/${NAME}/dev; tar xfp -) + +touch /opt/jail/$NAME/done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kubectl-shell.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kubectl-shell.sh new file mode 100755 index 0000000..558e485 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kubectl-shell.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +token=$1 +cluster=$2 +cacerts=$3 + +if [ -z "${token}" ]; then + echo No token provided + exit 1 +fi + +if [ -z "${cluster}" ]; then + echo No cluster provided + exit 1 +fi + +echo "# Run kubectl commands inside here" +echo "# e.g. kubectl get all" +export TERM=screen-256color +export TOKEN=${token} +export CLUSTER=${cluster} +export CACERTS=${cacerts} +unshare --fork --pid --mount-proc --mount shell-setup.sh || true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kustomize.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kustomize.sh new file mode 100755 index 0000000..88541c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/kustomize.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +cat <&0 > "$CATTLE_KUSTOMIZE_YAML"/all.yaml + +kustomize build "$CATTLE_KUSTOMIZE_YAML" && rm "$CATTLE_KUSTOMIZE_YAML"/all.yaml diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_agent.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_agent.sh new file mode 100755 index 0000000..d5c2a70 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_agent.sh @@ -0,0 +1,285 @@ +#!/bin/bash +set -e + +# Logging helper functions +info() +{ + echo "INFO:" "$@" 1>&2 +} + +error() +{ + echo "ERROR:" "$@" 1>&2 +} +warn() +{ + echo "WARN:" "$@" 1>&2 +} + +# Print all given arguments +if [ $# -ne 0 ]; then + info "Arguments: $(echo $@ | sed -e 's/\(token\s\)\w*/\1REDACTED/')" +fi + +if [ "$1" = "--" ]; then + shift 1 + exec "$@" +fi + +if [ "$CLUSTER_CLEANUP" = true ]; then + mkdir agentcoverage + while true; do + echo "Agent started in coverage mode" + GOCOVERDIR=agentcoverage /usr/bin/agent "${@}" + echo "Agent restarting.." + done +fi + +get_address() +{ + local address=$1 + # If nothing is given, return empty (it will be automatically determined later if empty) + if [ -z $address ]; then + echo "" + # If given address is a network interface on the system, retrieve configured IP on that interface (only the first configured IP is taken) + elif [ -n "$(find /sys/devices -name $address)" ]; then + echo $(ip addr show dev $address | grep -w inet | awk '{print $2}' | cut -f1 -d/ | head -1) + # Loop through cloud provider options to get IP from metadata, if not found return given value + else + case $address in + awslocal) + echo $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) + ;; + awspublic) + echo $(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) + ;; + doprivate) + echo $(curl -s http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address) + ;; + dopublic) + echo $(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address) + ;; + azprivate) + echo $(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text") + ;; + azpublic) + echo $(curl -s -H Metadata:true "http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/publicIpAddress?api-version=2017-08-01&format=text") + ;; + gceinternal) + echo $(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) + ;; + gceexternal) + echo $(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip) + ;; + packetlocal) + echo $(curl -s https://metadata.packet.net/2009-04-04/meta-data/local-ipv4) + ;; + packetpublic) + echo $(curl -s https://metadata.packet.net/2009-04-04/meta-data/public-ipv4) + ;; + ipify) + echo $(curl -s https://api.ipify.org) + ;; + *) + echo $address + ;; + esac + fi +} + +check_url() +{ + local url=$1 + local err + err=$(curl --insecure -sS -fL -o /dev/null --stderr - $url | head -n1 ; exit ${PIPESTATUS[0]}) + if [ $? -eq 0 ] + then + echo "" + else + echo ${err} | sed -e 's/^curl: ([0-9]\+) //' + fi +} + +check_x509_cert() +{ + local cert=$1 + local err + err=$(openssl x509 -in $cert -noout 2>&1) + if [ $? -eq 0 ] + then + echo "" + else + echo ${err} + fi +} + +export CATTLE_ADDRESS +export CATTLE_AGENT_CONNECT +export CATTLE_INTERNAL_ADDRESS +export CATTLE_NODE_NAME +export CATTLE_ROLE +export CATTLE_SERVER +export CATTLE_TOKEN +export CATTLE_NODE_LABEL +export CATTLE_WRITE_CERT_ONLY +export CATTLE_NODE_TAINTS + +while true; do + case "$1" in + -d | --debug) DEBUG=true ;; + -s | --server) shift; CATTLE_SERVER=$1 ;; + -t | --token) shift; CATTLE_TOKEN=$1 ;; + -c | --ca-checksum) shift; CATTLE_CA_CHECKSUM=$1 ;; + -a | --all-roles) ALL=true ;; + -e | --etcd) ETCD=true ;; + -w | --worker) WORKER=true ;; + -p | --controlplane) CONTROL=true ;; + -n | --node-name) shift; CATTLE_NODE_NAME=$1 ;; + -r | --no-register) CATTLE_AGENT_CONNECT=true ;; + -a | --address) shift; CATTLE_ADDRESS=$1 ;; + -i | --internal-address) shift; CATTLE_INTERNAL_ADDRESS=$1 ;; + -l | --label) shift; CATTLE_NODE_LABEL+=",$1" ;; + -o | --only-write-certs) CATTLE_WRITE_CERT_ONLY=true ;; + --taints) shift; CATTLE_NODE_TAINTS+=",$1" ;; + *) break; + esac + shift +done + +if [ "$DEBUG" = true ]; then + set -x +fi + +if [ "$CATTLE_CLUSTER" != "true" ]; then + if [ ! -w /var/run/docker.sock ] || [ ! -S /var/run/docker.sock ]; then + warn "Docker socket is not available!" + warn "Please bind mount in the docker socket to /var/run/docker.sock if docker errors occur" + warn "example: docker run -v /var/run/docker.sock:/var/run/docker.sock ..." + fi +fi + +if [ -z "$CATTLE_NODE_NAME" ]; then + CATTLE_NODE_NAME=$(hostname -s) +fi + +export CATTLE_ADDRESS=$(get_address $CATTLE_ADDRESS) +export CATTLE_INTERNAL_ADDRESS=$(get_address $CATTLE_INTERNAL_ADDRESS) + +if [ -z "$CATTLE_ADDRESS" ]; then + # Try to get external IP with dig, often works better than ip -o route. + if dig +short myip.opendns.com @resolver1.opendns.com && echo $?; then + CATTLE_ADDRESS=$(dig +short myip.opendns.com @resolver1.opendns.com) + fi +fi + +if [ -z "$CATTLE_ADDRESS" ]; then + # Example output: '8.8.8.8 via 10.128.0.1 dev ens4 src 10.128.0.34 uid 0' + CATTLE_ADDRESS=$(ip -o route get 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p') +fi + +if [ -z "$CATTLE_INTERNAL_ADDRESS" ]; then + # Example output: '8.8.8.8 via 10.128.0.1 dev ens4 src 10.128.0.34 uid 0' + # Will provide the private IP address, if no private IP address is found the public IP address will be returned + ROUTE_OUTPUT=$(ip -o route get 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p') + if [ "$CATTLE_ADDRESS" != "$ROUTE_OUTPUT" ]; then + CATTLE_INTERNAL_ADDRESS="$ROUTE_OUTPUT" + fi +fi + +if [ "$CATTLE_K8S_MANAGED" != "true" ]; then + if [ -z "$CATTLE_TOKEN" ]; then + error -- --token is a required option + exit 1 + fi + + if [ -z "$CATTLE_ADDRESS" ]; then + error -- --address is a required option + exit 1 + fi +fi + +if [ "$ALL" = true ]; then + CATTLE_ROLE="etcd,worker,controlplane" +else + if [ "$ETCD" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},etcd" + fi + if [ "$WORKER" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},worker" + fi + if [ "$CONTROL" = true ]; then + CATTLE_ROLE="${CATTLE_ROLE},controlplane" + fi +fi + +if [ -z "$CATTLE_SERVER" ]; then + error -- --server is a required option + exit 1 +fi + +info "Environment: $(echo $(printenv | grep CATTLE | sort | sed -e 's/\(CATTLE_TOKEN=\).*/\1REDACTED/'))" +info "Using resolv.conf: $(echo $(cat /etc/resolv.conf | grep -v ^#))" +if grep -E -q '^nameserver 127.*.*.*|^nameserver localhost|^nameserver ::1' /etc/resolv.conf; then + warn "Loopback address found in /etc/resolv.conf, please refer to the documentation how to configure your cluster to resolve DNS properly" +fi + +CATTLE_SERVER_PING="${CATTLE_SERVER}/ping" +err=$(check_url $CATTLE_SERVER_PING) +if [[ $err ]]; then + error "${CATTLE_SERVER_PING} is not accessible (${err})" + exit 1 +else + info "${CATTLE_SERVER_PING} is accessible" +fi + +# Extract hostname from URL +CATTLE_SERVER_HOSTNAME=$(echo $CATTLE_SERVER | sed -e 's/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/') +CATTLE_SERVER_HOSTNAME_WITH_PORT=$(echo $CATTLE_SERVER | sed -e 's/[^/]*\/\/\([^@]*@\)\?\(.*\).*/\2/') +# Resolve IPv4 address(es) from hostname +RESOLVED_ADDR=$(getent ahostsv4 $CATTLE_SERVER_HOSTNAME | sed -n 's/ *STREAM.*//p') + +# If CATTLE_SERVER_HOSTNAME equals RESOLVED_ADDR, its an IP address and there is nothing to resolve +if [ "${CATTLE_SERVER_HOSTNAME}" != "${RESOLVED_ADDR}" ]; then + info "${CATTLE_SERVER_HOSTNAME} resolves to $(echo $RESOLVED_ADDR)" +fi + +if [ -n "$CATTLE_CA_CHECKSUM" ]; then + temp=$(mktemp) + curl --insecure -s -fL $CATTLE_SERVER/v3/settings/cacerts | jq -r '.value | select(length > 0)' > $temp + if [ ! -s $temp ]; then + error "The environment variable CATTLE_CA_CHECKSUM is set but there is no CA certificate configured at $CATTLE_SERVER/v3/settings/cacerts" + exit 1 + fi + err=$(check_x509_cert $temp) + if [[ $err ]]; then + error "Value from $CATTLE_SERVER/v3/settings/cacerts does not look like an x509 certificate (${err})" + error "Retrieved cacerts:" + cat $temp + exit 1 + else + info "Value from $CATTLE_SERVER/v3/settings/cacerts is an x509 certificate" + fi + CATTLE_SERVER_CHECKSUM=$(sha256sum $temp | awk '{print $1}') + if [ $CATTLE_SERVER_CHECKSUM != $CATTLE_CA_CHECKSUM ]; then + rm -f $temp + error "Configured cacerts checksum ($CATTLE_SERVER_CHECKSUM) does not match given --ca-checksum ($CATTLE_CA_CHECKSUM)" + error "Please check if the correct certificate is configured at $CATTLE_SERVER/v3/settings/cacerts" + exit 1 + else + mkdir -p /etc/kubernetes/ssl/certs + mv $temp /etc/kubernetes/ssl/certs/serverca + chmod 755 /etc/kubernetes/ssl + chmod 700 /etc/kubernetes/ssl/certs + chmod 600 /etc/kubernetes/ssl/certs/serverca + mkdir -p /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT + cp /etc/kubernetes/ssl/certs/serverca /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT/ca.crt + + fi +fi + +mkdir agentcoverage +while true; do + echo "Agent started in coverage mode" + GOCOVERDIR=agentcoverage /usr/bin/agent "${@}" + echo "Agent restarting.." +done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_rancher.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_rancher.sh new file mode 100644 index 0000000..0d604e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/run_rancher.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +set -e + +if [ ! -e /run/secrets/kubernetes.io/serviceaccount ] && [ ! -e /dev/kmsg ]; then + echo "ERROR: Rancher must be ran with the --privileged flag when running outside of Kubernetes" + exit 1 +fi + +######################################################################################################################################### +# DISCLAIMER # +# Copied from https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/hack/dind#L28-L37 # +# Permission granted by Akihiro Suda (https://github.com/rancher/k3d/issues/493#issuecomment-827405962) # +# Moby License Apache 2.0: https://github.com/moby/moby/blob/ed89041433a031cafc0a0f19cfe573c31688d377/LICENSE # +######################################################################################################################################### +# only run this if rancher is not running in kubernetes cluster +if [ ! -e /run/secrets/kubernetes.io/serviceaccount ] && [ -f /sys/fs/cgroup/cgroup.controllers ]; then + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + mkdir -p /sys/fs/cgroup/init + xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' <"/sys/fs/cgroup/cgroup.controllers" >"/sys/fs/cgroup/cgroup.subtree_control" +fi + +rm -f /var/lib/rancher/k3s/server/cred/node-passwd +if [ -e /var/lib/rancher/management-state/etcd ] && [ ! -e /var/lib/rancher/k3s/server/db/etcd ]; then + mkdir -p /var/lib/rancher/k3s/server/db + ln -sf /var/lib/rancher/management-state/etcd /var/lib/rancher/k3s/server/db/etcd + echo -n 'default' > /var/lib/rancher/k3s/server/db/etcd/name +fi +if [ -e /var/lib/rancher/k3s/server/db/etcd ]; then + echo "INFO: Running k3s server --cluster-init --cluster-reset" + set +e + k3s server --cluster-init --cluster-reset &> ./k3s-cluster-reset.log + K3S_CR_CODE=$? + if [ "${K3S_CR_CODE}" -ne 0 ]; then + echo "ERROR:" && cat ./k3s-cluster-reset.log + rm -f /var/lib/rancher/k3s/server/db/reset-flag + exit ${K3S_CR_CODE} + fi + set -e +fi +if [ -x "$(command -v update-ca-certificates)" ]; then + update-ca-certificates +fi +if [ -x "$(command -v c_rehash)" ]; then + c_rehash +fi + +mkdir ranchercoverage +while true; do + echo "Rancher started in coverage mode" + GOCOVERDIR=ranchercoverage /usr/bin/rancher --http-listen-port=80 --https-listen-port=443 --audit-log-path=${AUDIT_LOG_PATH} --audit-level=${AUDIT_LEVEL} --audit-log-maxage=${AUDIT_LOG_MAXAGE} --audit-log-maxbackup=${AUDIT_LOG_MAXBACKUP} --audit-log-maxsize=${AUDIT_LOG_MAXSIZE} "${@}" + echo "Rancher restarting.." +done \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/shell-setup.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/shell-setup.sh new file mode 100755 index 0000000..be95d4e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/package/shell-setup.sh @@ -0,0 +1,67 @@ +#!/bin/bash +set -e + +mkdir -p /nonexistent +mount -t tmpfs tmpfs /nonexistent +cd /nonexistent + +mkdir -p .kube/certs + +SERVER="${CATTLE_SERVER}/k8s/clusters/${CLUSTER}" + +if [ -f /etc/kubernetes/ssl/certs/serverca ]; then + cp /etc/kubernetes/ssl/certs/serverca .kube/certs/ca.crt + chmod 666 .kube/certs/ca.crt + +elif [ -n "${CACERTS}" ]; then + echo "${CACERTS}" | base64 -d > .kube/certs/ca.crt + chmod 666 .kube/certs/ca.crt +fi + +if [ -f /nonexistent/.kube/certs/ca.crt ] && ! curl -s $SERVER > /dev/null; then + CERT=" certificate-authority: /nonexistent/.kube/certs/ca.crt" +fi + +for i in /run /var/run /etc/kubernetes; do + mount -t tmpfs tmpfs $i +done + +cat < .kube/config +apiVersion: v1 +kind: Config +clusters: +- cluster: + api-version: v1 + server: "${CATTLE_SERVER}/k8s/clusters/${CLUSTER}" +${CERT} + name: "Default" +contexts: +- context: + cluster: "Default" + user: "Default" + name: "Default" +current-context: "Default" +users: +- name: "Default" + user: + token: "${TOKEN}" +EOF + +cp /etc/skel/.bashrc . +cat >> .bashrc < tests/v2/codecoverage/bin/data.json diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_code_coverage_images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_code_coverage_images.sh new file mode 100755 index 0000000..83dd623 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_code_coverage_images.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../ + + +echo "building cluster setup bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/codecoverage/bin/setuprancher ./tests/v2/codecoverage/setuprancher + +echo "building rancher HA corral bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/codecoverage/bin/ranchercorral ./tests/v2/codecoverage/rancherha + +echo "building rancher cleanup bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/codecoverage/bin/ranchercleanup ./tests/v2/codecoverage/ranchercleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral.sh new file mode 100755 index 0000000..e4be404 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +cd /go/src/github.com/rancherlabs/corral + +echo "building corral bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build + +mv corral /go/bin \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral_packages.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral_packages.sh new file mode 100755 index 0000000..198b770 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_corral_packages.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +cd /root/go/src/github.com/rancherlabs/corral-packages + +make init +make build \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_docker_images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_docker_images.sh new file mode 100755 index 0000000..7df3b0f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_docker_images.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e + +source $(dirname $0)/../../../../scripts/export-config + +ARCH=${ARCH:-"amd64"} +REPO=ranchertest +TAG=v2.9-head +SYSTEM_CHART_REPO_DIR=build/system-charts +SYSTEM_CHART_DEFAULT_BRANCH=${SYSTEM_CHART_DEFAULT_BRANCH:-"dev-v2.9"} +CHART_REPO_DIR=build/charts +CHART_DEFAULT_BRANCH=${CHART_DEFAULT_BRANCH:-"dev-v2.9"} + +cd $(dirname $0)/../package + +../scripts/k3s-images.sh + +cp ../bin/rancher ../bin/agent ../bin/data.json ../bin/k3s-airgap-images.tar . + +# Make sure the used data.json is a release artifact +cp ../bin/data.json ../bin/rancher-data.json + +IMAGE=${REPO}/rancher:${TAG} +AGENT_IMAGE=${REPO}/rancher-agent:${TAG} + +echo "building rancher test docker image" +docker build \ + --build-arg VERSION=${TAG} \ + --build-arg ARCH=${ARCH} \ + --build-arg IMAGE_REPO=${REPO} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION="${CATTLE_RANCHER_WEBHOOK_VERSION}" \ + --build-arg CATTLE_RANCHER_PROVISIONING_CAPI_VERSION="${CATTLE_RANCHER_PROVISIONING_CAPI_VERSION}" \ + --build-arg CATTLE_CSP_ADAPTER_MIN_VERSION="${CATTLE_CSP_ADAPTER_MIN_VERSION}" \ + --build-arg CATTLE_FLEET_VERSION="${CATTLE_FLEET_VERSION}" \ + -t ${IMAGE} -f Dockerfile . --no-cache + +echo "building agent test docker image" +docker build \ + --build-arg VERSION=${TAG} \ + --build-arg ARCH=${ARCH} \ + --build-arg RANCHER_TAG=${TAG} \ + --build-arg RANCHER_REPO=${REPO} \ + --build-arg CATTLE_RANCHER_WEBHOOK_VERSION="${CATTLE_RANCHER_WEBHOOK_VERSION}" \ + --build-arg CATTLE_RANCHER_PROVISIONING_CAPI_VERSION="${CATTLE_RANCHER_PROVISIONING_CAPI_VERSION}" \ + -t ${AGENT_IMAGE} -f Dockerfile.agent . --no-cache + +echo ${DOCKERHUB_PASSWORD} | docker login --username ${DOCKERHUB_USERNAME} --password-stdin + +echo "docker push rancher" +docker image push ${IMAGE} + +echo "docker push agent" +docker image push ${AGENT_IMAGE} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_test_images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_test_images.sh new file mode 100755 index 0000000..2238f33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/build_test_images.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +cd $(dirname $0) + +echo "build rancher" +./build-rancher.sh +echo "build agent" +./build-agent.sh \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/download_yq.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/download_yq.sh new file mode 100755 index 0000000..f9916b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/download_yq.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e + +wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 +chmod a+x ./yq \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/k3s-images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/k3s-images.sh new file mode 100755 index 0000000..6431e6d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/k3s-images.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e -x + +cd $(dirname $0)/.. + +mkdir -p bin + +# This is used for downloading the tar file and not the images text file. +# Referenced in test: tests/validation/tests/v3_api/test_airgap.py +if [ -e /usr/tmp/k3s-images.txt ]; then + images=$(grep -e 'docker.io/rancher/mirrored-pause' -e 'docker.io/rancher/mirrored-coredns-coredns' /usr/tmp/k3s-images.txt) + xargs -n1 docker pull <<< "${images}" + docker save -o ./bin/k3s-airgap-images.tar ${images} +else + touch bin/k3s-airgap-images.tar +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/merge_coverage_reports.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/merge_coverage_reports.sh new file mode 100755 index 0000000..b4fa34b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/merge_coverage_reports.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e -x + +cd ~/go/src/github.com/rancher/rancher/tests/v2/codecoverage/ranchercover/cover + +ls -al + +dirlist=(`ls -p | tr '\n' ',' | tr -d '/' | sed 's/.$//'`) +mkdir merged +go tool covdata merge -i=${dirlist} -o merged + +go tool covdata textfmt -i=merged -o profile.txt +# Output Total Coverage +go tool cover -func=profile.txt | grep -E '^total\:' | sed -E 's/\s+/ /g' + +go tool cover -html profile.txt -o merged.html \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/run_provisioning_integration_tests.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/run_provisioning_integration_tests.sh new file mode 100755 index 0000000..d589360 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/run_provisioning_integration_tests.sh @@ -0,0 +1,60 @@ +#!/bin/bash +set -e -x + +mkdir -p /etc/rancher/k3s + +corral vars ranchertestcoverage kubeconfig | base64 --decode > /etc/rancher/k3s/k3s.yaml + +TB_ORG=rancher + +if [ -z "${V2PROV_TEST_DIST}" ] || [ "${V2PROV_TEST_DIST}" = "k3s" ]; then + V2PROV_TEST_DIST=k3s + AIRGAP=-airgap + TB_ORG=k3s-io +else + LINUX=.linux +fi + +if [ -z "${V2PROV_TEST_RUN_REGEX}" ]; then + V2PROV_TEST_RUN_REGEX="^Test_(General|Provisioning)_.*$" +fi + +RUNARG="-run ${V2PROV_TEST_RUN_REGEX}" + +export DIST=${V2PROV_TEST_DIST} +export SOME_K8S_VERSION=${SOME_K8S_VERSION} +export TB_ORG=${TB_ORG} + +eval "$(grep '^ENV CATTLE_SYSTEM_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_WINS_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_CSI_PROXY_AGENT' package/Dockerfile | awk '{print "export " $2 "=" $3}')" +eval "$(grep '^ENV CATTLE_KDM_BRANCH' package/Dockerfile | awk '{print "export " $2 "=" $3}')" + +if [ -z "${SOME_K8S_VERSION}" ]; then +# Get the last release for $DIST, which is usually the latest version or an experimental version. +# Previously this would use channels, but channels no longer reflect the latest version since +# https://github.com/rancher/rancher/issues/36827 has added appDefaults. We do not use appDefaults +# here for simplicity's sake, as it requires semver parsing & matching. The last release should +# be good enough for our needs. +export SOME_K8S_VERSION=$(curl -sS https://raw.githubusercontent.com/rancher/kontainer-driver-metadata/release-v2.9/data/data.json | jq -r ".$DIST.releases[-1].version") +fi + +echo "Starting rancher server for provisioning-tests using $SOME_K8S_VERSION" +touch /tmp/rancher.log + +mkdir -p /var/lib/rancher/$DIST/agent/images +grep PodTestImage ./tests/v2prov/defaults/defaults.go | cut -f2 -d'"' > /var/lib/rancher/$DIST/agent/images/pull.txt +grep MachineProvisionImage ./pkg/settings/setting.go | cut -f4 -d'"' >> /var/lib/rancher/$DIST/agent/images/pull.txt +mkdir -p /usr/share/rancher/ui/assets +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/rancher-system-agent-amd64 -o /usr/share/rancher/ui/assets/rancher-system-agent-amd64 +curl -sLf https://github.com/rancher/system-agent/releases/download/${CATTLE_SYSTEM_AGENT_VERSION}/system-agent-uninstall.sh -o /usr/share/rancher/ui/assets/system-agent-uninstall.sh + +echo Running provisioning-tests $RUNARG + +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +go test $RUNARG -v -failfast -timeout 60m ./tests/v2prov/tests/... || { + echo -e "-----RANCHER-LOG-DUMP-START-----" + cat /tmp/rancher.log | gzip | base64 -w 0 + echo -e "\n-----RANCHER-LOG-DUMP-END-----" + exit 1 +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/setup_code_coverage_enviornment.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/setup_code_coverage_enviornment.sh new file mode 100755 index 0000000..3d5f64d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/scripts/setup_code_coverage_enviornment.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../ + +echo "building bins" +sh tests/v2/codecoverage/scripts/build_code_coverage_images.sh + +echo "build corral packages" +sh tests/v2/codecoverage/scripts/build_corral_packages.sh + +echo "running rancher corral" +tests/v2/codecoverage/bin/ranchercorral + +echo "setup rancher" +tests/v2/codecoverage/bin/setuprancher \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/setuprancher/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/setuprancher/main.go new file mode 100644 index 0000000..0e2e2fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/codecoverage/setuprancher/main.go @@ -0,0 +1,336 @@ +package main + +import ( + "context" + "os" + "time" + + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/dynamic" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeapi/workloads/deployments" + "github.com/rancher/shepherd/extensions/pipeline" + "github.com/rancher/shepherd/extensions/provisioninginput" + nodepools "github.com/rancher/shepherd/extensions/rke1/nodepools" + aws "github.com/rancher/shepherd/extensions/rke1/nodetemplates/aws" + "github.com/rancher/shepherd/extensions/token" + "github.com/rancher/shepherd/extensions/unstructured" + "github.com/rancher/shepherd/extensions/users" + passwordgenerator "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + appv1 "k8s.io/api/apps/v1" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/clientcmd" +) + +var ( + adminPassword = os.Getenv("ADMIN_PASSWORD") +) + +const ( + corralName = "ranchertestcoverage" + rancherTestImage = "ranchertest/rancher:v2.9-head" + namespace = "cattle-system" + deploymentName = "rancher" + clusterName = "local" + // The json/yaml config key for the corral package to be build .. + userClusterConfigsConfigurationFileKey = "userClusterConfig" +) + +type UserClusterConfig struct { + Token string `json:"token" yaml:"token"` + Username string `json:"username" yaml:"username"` + Clusters []string `json:"clusters" yaml:"clusters"` + AdminPassword string `json:"adminPassword" yaml:"adminPassword"` +} + +// setup for code coverage testing and reporting +func main() { + rancherConfig := new(rancher.Config) + config.LoadConfig(rancher.ConfigurationFileKey, rancherConfig) + + kubeconfig, err := getRancherKubeconfig() + if err != nil { + logrus.Fatalf("error with getting kube config using corral: %v", err) + } + + password, err := corral.GetCorralEnvVar(corralName, "bootstrap_password") + if err != nil { + logrus.Fatalf("error getting password %v", err) + } + + // update deployment + err = updateRancherDeployment(kubeconfig) + if err != nil { + logrus.Fatalf("error updating rancher deployment: %v", err) + } + + token, err := createAdminToken(password, rancherConfig) + if err != nil { + logrus.Fatalf("error with generating admin token: %v", err) + } + + rancherConfig.AdminToken = token + config.UpdateConfig(rancher.ConfigurationFileKey, rancherConfig) + //provision clusters for test + session := session.NewSession() + clustersConfig := new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, clustersConfig) + + client, err := rancher.NewClient("", session) + if err != nil { + logrus.Fatalf("error creating admin client: %v", err) + } + + err = pipeline.PostRancherInstall(client, adminPassword) + if err != nil { + logrus.Errorf("error during post rancher install: %v", err) + } + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = passwordgenerator.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + if err != nil { + logrus.Fatalf("error creating admin client: %v", err) + } + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + if err != nil { + logrus.Fatalf("error creating standard user client: %v", err) + } + + // create admin cluster + adminClusterNames, err := createTestCluster(client, client, 1, "admintestcluster", clustersConfig) + if err != nil { + logrus.Fatalf("error creating admin user cluster: %v", err) + } + + // create standard user clusters + standardClusterNames, err := createTestCluster(standardUserClient, client, 2, "standardtestcluster", clustersConfig) + if err != nil { + logrus.Fatalf("error creating standard user clusters: %v", err) + } + + //update userconfig + userClusterConfig := UserClusterConfig{} + userClusterConfig.Token = standardUserClient.Steve.Opts.TokenKey + userClusterConfig.Username = newUser.Name + userClusterConfig.AdminPassword = adminPassword + userClusterConfig.Clusters = standardClusterNames + + rancherConfig.ClusterName = adminClusterNames[0] + config.UpdateConfig(rancher.ConfigurationFileKey, rancherConfig) + + err = writeToConfigFile(userClusterConfig) + if err != nil { + logrus.Fatalf("error writing config file: %v", err) + } +} + +func getRancherKubeconfig() ([]byte, error) { + kubeconfig, err := corral.GetKubeConfig(corralName) + if err != nil { + return nil, err + } + + return kubeconfig, nil +} + +func createAdminToken(password string, rancherConfig *rancher.Config) (string, error) { + adminUser := &management.User{ + Username: "admin", + Password: password, + } + + hostURL := rancherConfig.Host + var userToken *management.Token + err := kwait.Poll(500*time.Millisecond, 5*time.Minute, func() (done bool, err error) { + userToken, err = token.GenerateUserToken(adminUser, hostURL) + if err != nil { + return false, nil + } + return true, nil + }) + + if err != nil { + return "", err + } + + return userToken.Token, nil +} + +func updateRancherDeployment(kubeconfig []byte) error { + session := session.NewSession() + clientConfig, err := clientcmd.NewClientConfigFromBytes(kubeconfig) + if err != nil { + return err + } + + restConfig, err := (clientConfig).ClientConfig() + if err != nil { + return err + } + + dynamicClient, err := dynamic.NewForConfig(session, restConfig) + if err != nil { + return err + } + + deploymentResource := dynamicClient.Resource(deployments.DeploymentGroupVersionResource) + + cattleSystemDeploymentResource := deploymentResource.Namespace(namespace) + unstructuredDeployment, err := cattleSystemDeploymentResource.Get(context.TODO(), deploymentName, metav1.GetOptions{}) + if err != nil { + return err + } + + updatedDeployment := &appv1.Deployment{} + err = scheme.Scheme.Convert(unstructuredDeployment, updatedDeployment, unstructuredDeployment.GroupVersionKind()) + if err != nil { + return err + } + + updatedDeployment.Spec.Template.Spec.Containers[0].Args = []string{} + updatedDeployment.Spec.Template.Spec.Containers[0].Image = rancherTestImage + updatedDeployment.Spec.Strategy.RollingUpdate = nil + updatedDeployment.Spec.Strategy.Type = appv1.RecreateDeploymentStrategyType + + _, err = cattleSystemDeploymentResource.Update(context.TODO(), unstructured.MustToUnstructured(updatedDeployment), metav1.UpdateOptions{}) + if err != nil { + return err + } + + err = kwait.Poll(500*time.Millisecond, 10*time.Minute, func() (done bool, err error) { + deployment, err := cattleSystemDeploymentResource.Get(context.TODO(), deploymentName, metav1.GetOptions{}) + if k8sErrors.IsNotFound(err) { + return false, nil + } else if err != nil { + return false, err + } + + newDeployment := &appv1.Deployment{} + err = scheme.Scheme.Convert(deployment, newDeployment, deployment.GroupVersionKind()) + if err != nil { + return false, err + } + if newDeployment.Status.ReadyReplicas == int32(3) { + return true, nil + } + + return false, nil + }) + + if err != nil { + logrus.Infof("time out updating rancher deployment %v", err) + return err + } + + err = kwait.Poll(500*time.Millisecond, 10*time.Minute, func() (done bool, err error) { + webhookDeployment, err := cattleSystemDeploymentResource.Get(context.TODO(), "rancher-webhook", metav1.GetOptions{}) + if k8sErrors.IsNotFound(err) { + return false, nil + } else if err != nil { + return false, err + } + + newDeployment := &appv1.Deployment{} + err = scheme.Scheme.Convert(webhookDeployment, newDeployment, webhookDeployment.GroupVersionKind()) + if err != nil { + return false, err + } + if newDeployment.Status.ReadyReplicas == int32(1) { + return true, nil + } + return false, nil + }) + logrus.Infof("time out updating rancher webhook deployment %v", err) + return err +} + +func createTestCluster(client, adminClient *rancher.Client, numClusters int, clusterNameBase string, clustersConfig *provisioninginput.Config) ([]string, error) { + clusterNames := []string{} + for i := 0; i < numClusters; i++ { + nodeTemplateResp, err := aws.CreateAWSNodeTemplate(client) + if err != nil { + return nil, err + } + + clusterName := namegen.AppendRandomString(clusterNameBase) + clusterNames = append(clusterNames, clusterName) + testClusterConfig := clusters.ConvertConfigToClusterConfig(clustersConfig) + testClusterConfig.KubernetesVersion = clustersConfig.RKE1KubernetesVersions[0] + testClusterConfig.CNI = clustersConfig.CNIs[0] + cluster := clusters.NewRKE1ClusterConfig(clusterName, client, testClusterConfig) + + clusterResp, err := clusters.CreateRKE1Cluster(client, cluster) + if err != nil { + return nil, err + } + + err = kwait.Poll(500*time.Millisecond, 10*time.Minute, func() (done bool, err error) { + var nodeRoles []nodepools.NodeRoles + for _, nodepool := range clustersConfig.NodePools { + nodeRoles = append(nodeRoles, nodepool.NodeRoles) + } + _, err = nodepools.NodePoolSetup(client, nodeRoles, clusterResp.ID, nodeTemplateResp.ID) + if err != nil { + return false, nil + } + return true, nil + }) + if err != nil { + return nil, err + } + + opts := metav1.ListOptions{ + FieldSelector: "metadata.name=" + clusterResp.ID, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + } + watchInterface, err := adminClient.GetManagementWatchInterface(management.ClusterType, opts) + if err != nil { + return nil, err + } + + checkFunc := clusters.IsHostedProvisioningClusterReady + + err = wait.WatchWait(watchInterface, checkFunc) + if err != nil { + return nil, err + } + } + return clusterNames, nil +} + +func writeToConfigFile(config UserClusterConfig) error { + result := map[string]UserClusterConfig{} + result[userClusterConfigsConfigurationFileKey] = config + + yamlConfig, err := yaml.Marshal(result) + + if err != nil { + return err + } + + return os.WriteFile("userclusterconfig.yaml", yamlConfig, 0644) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/.gitignore new file mode 100644 index 0000000..6dd29b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/.gitignore @@ -0,0 +1 @@ +bin/ \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/README.md new file mode 100644 index 0000000..476bc43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/README.md @@ -0,0 +1,54 @@ +# Integration Tests + +## Running Tests + +To run the integration tests in `tests/v2/integration`, use + +```shell +make ci +``` + +This will run `scripts/test` inside a Dapper container created using `Dockerfile.dapper`. The script will set up and run +Rancher. Upon startup, Rancher will create a local cluster using k3s and deploy CRDs to it. Once the Rancher and the +local cluster are ready, the tests will be run. + +This _should_ work on Mac and Linux systems out of the box, at least in theory. The whole integration test process does +consume a fair bit of CPU and memory. If you experience unexpected timeouts, you may not have enough compute power. If +you encounter OOM issues that affect scheduling of containers, you may not have enough memory. + +## Test Setup + +Setup for the integration tests can be found in `scripts/test` and `tests/v2/integration/setup/main.go`. The latter is +responsible primarily for +1. Generating and saving a test config file that will be used by the integration tests. +2. Creating a user and corresponding token with which to access Rancher from tests. +3. Creating a new test namespace in the local cluster to which credentials for Docker container registries will be +deployed in the form of secrets. +4. Deploying two registries to the `default` namespace. + +### Registry Setup +The first of the two registries deployed during the setup process is a configured normally, so images can be pushed to +and pulled from it. The second registry is configured as a pull-through cache, and its sole purpose is to cache +images pulled by downstream clusters when they create containers in order to speed up the test process. The process of +creating these registries will also result in secrets being deployed to the aforementioned test namespace. The cattle +cluster agent image built locally (by `scripts/ci`) is then pushed to the first registry, so it can be pulled by +downstream clusters. Configuration for these two registries is merged together and used to create a test cluster that +is used in integration tests. The merged registry config is what allows the downstream cluster to access the registries +inside the local cluster. + +### Downstream Cluster Provisioning + +The downstream cluster is created the same way in the integration test setup as it would be in v2 provisioning tests. +We create the downstream cluster using the provided `cluster.New()` function in +`github.com/rancher/rancher/tests/v2prov/cluster`. This, in turn, uses Rancher's v2 provisioning functionality to create +a container in the test namespace that runs a machine provisioner. This machine provisioner will create a +[`systemd-node`](https://github.com/rancher/systemd-node/tree/master) container that will create its own contained +Kubernetes cluster. In other words, the end result is +- A Docker container (created by Dapper) running + - `scripts/test` running + - Integration tests + - Rancher + - Rancher's "local" cluster: a k3s cluster running + - A number of containers (for stuff like networking, but Rancher-specific things like the rancher-webhook) + - A `systemd-node` container running + - The "downstream cluster": a k3s cluster running the cluster agent and some other Rancher downstream components diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/cluster_repo_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/cluster_repo_test.go new file mode 100644 index 0000000..e3d923b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/cluster_repo_test.go @@ -0,0 +1,833 @@ +package integration + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "io" + "log" + "net" + "net/http" + "net/http/httptest" + "net/url" + "os" + "strings" + "testing" + "time" + + registryGoogle "github.com/google/go-containerregistry/pkg/registry" + "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/catalogv2/oci" + "github.com/rancher/rancher/pkg/controllers/dashboard/helm" + "github.com/rancher/rancher/tests/integration/pkg/defaults" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + stevev1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/pkg/api/steve/catalog/types" + "github.com/rancher/shepherd/pkg/session" + rancherWait "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "helm.sh/helm/v3/pkg/registry" + "helm.sh/helm/v3/pkg/repo" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/kubernetes" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "oras.land/oras-go/v2" + "oras.land/oras-go/v2/content/memory" +) + +const ( + HTTPClusterRepoName = "test-http-cluster-repo" + LatestHTTPRepoURL = "https://releases.rancher.com/server-charts/latest" + StableHTTPRepoURL = "https://releases.rancher.com/server-charts/stable" + + GitClusterRepoName = "test-git-cluster-repo" + RancherChartsGitRepoURL = "https://github.com/rancher/charts" + RKE2ChartsGitRepoURL = "https://github.com/rancher/rke2-charts" + + OCIClusterRepoName = "test-oci-cluster-repo" +) + +var ( + PollInterval = time.Duration(500 * time.Millisecond) + PollTimeout = time.Duration(5 * time.Minute) +) + +type ClusterRepoTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + catalogClient *catalog.Client + corev1 corev1client.CoreV1Interface +} + +func (c *ClusterRepoTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *ClusterRepoTestSuite) SetupSuite() { + var err error + testSession := session.NewSession() + c.session = testSession + + c.client, err = rancher.NewClient("", testSession) + require.NoError(c.T(), err) + insecure := true + c.client.RancherConfig.Insecure = &insecure + c.catalogClient, err = c.client.GetClusterCatalogClient("local") + require.NoError(c.T(), err) + + kubeConfig, err := kubeconfig.GetKubeconfig(c.client, "local") + require.NoError(c.T(), err) + restConfig, err := (*kubeConfig).ClientConfig() + require.NoError(c.T(), err) + cset, err := kubernetes.NewForConfig(restConfig) + require.NoError(c.T(), err) + c.corev1 = cset.CoreV1() +} + +type RepoType int64 + +const ( + Git RepoType = iota + HTTP + OCI +) + +// ClusterRepoParams is used to pass params to func testClusterRepo for testing +type ClusterRepoParams struct { + Name string // Name of the ClusterRepo resource + Type RepoType // Type of the ClusterRepo resource + URL1 string // URL to use when creating the ClusterRepo resource + URL2 string // URL to use when updating the ClusterRepo resource to a new URL + InsecurePlainHTTP bool + StatusCode int + ForceRefresh bool +} + +// TestHTTPRepo tests CREATE, UPDATE, and DELETE operations of HTTP ClusterRepo resources +func (c *ClusterRepoTestSuite) TestHTTPRepo() { + c.testClusterRepo(ClusterRepoParams{ + Name: HTTPClusterRepoName, + URL1: LatestHTTPRepoURL, + URL2: StableHTTPRepoURL, + Type: HTTP, + }) +} + +// TestGitRepo tests CREATE, UPDATE, and DELETE operations of Git ClusterRepo resources +func (c *ClusterRepoTestSuite) TestGitRepo() { + c.testClusterRepo(ClusterRepoParams{ + Name: GitClusterRepoName, + URL1: RancherChartsGitRepoURL, + URL2: RKE2ChartsGitRepoURL, + Type: Git, + }) +} + +func StartRegistry() (*httptest.Server, error) { + // Create a new registry handler + handler := registryGoogle.New() + + // Optionally, you can customize the handler here if needed + // e.g., add middleware, logging, etc. + customHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + logrus.Infof("Received request: %s %s", r.Method, r.URL) + handler.ServeHTTP(w, r) + }) + + // Create a new test server + ts := httptest.NewUnstartedServer(customHandler) + + ip := getOutboundIP() + // Bind the server to a specific IP address (your local machine's IP) + listener, err := net.Listen("tcp", fmt.Sprintf("%s:4050", ip.String())) + if err != nil { + return nil, err + } + ts.Listener = listener + ts.Start() + + return ts, nil +} + +func StartErrorRegistry(status int) (*url.URL, error) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(status) + })) + + u, err := url.Parse(ts.URL) + if err != nil { + return nil, err + } + + return u, nil +} + +func Start429Registry(t assert.TestingT, rateLimitedHeader bool) (*httptest.Server, error) { + testingChartPath := "../../../testdata/testingchart-0.1.0.tgz" + testChartPath := "../../../testdata/testchart-1.0.0.tgz" + helmChartTar, err := os.ReadFile(testingChartPath) + assert.NoError(t, err) + + layerDesc := ocispec.Descriptor{ + MediaType: registry.ChartLayerMediaType, + Digest: digest.FromBytes(helmChartTar), + Size: int64(len(helmChartTar)), + } + + helmChartTar2, err := os.ReadFile(testChartPath) + assert.NoError(t, err) + + layerDesc2 := ocispec.Descriptor{ + MediaType: registry.ChartLayerMediaType, + Digest: digest.FromBytes(helmChartTar2), + Size: int64(len(helmChartTar2)), + } + + configBlob := []byte("config") + configDesc := ocispec.Descriptor{ + MediaType: registry.ConfigMediaType, + Digest: digest.FromBytes(configBlob), + Size: int64(len(configBlob)), + } + + manifest := ocispec.Manifest{ + MediaType: ocispec.MediaTypeImageManifest, + Config: configDesc, + Layers: []ocispec.Descriptor{layerDesc}, + } + manifestJSON, err := json.Marshal(manifest) + assert.NoError(t, err) + manifestDesc := ocispec.Descriptor{ + MediaType: ocispec.MediaTypeImageManifest, + Digest: digest.FromBytes(manifestJSON), + Size: int64(len(manifestJSON)), + } + + manifest2 := ocispec.Manifest{ + MediaType: ocispec.MediaTypeImageManifest, + Config: configDesc, + Layers: []ocispec.Descriptor{layerDesc2}, + } + manifestJSON2, err := json.Marshal(manifest2) + assert.NoError(t, err) + manifestDesc2 := ocispec.Descriptor{ + MediaType: ocispec.MediaTypeImageManifest, + Digest: digest.FromBytes(manifestJSON2), + Size: int64(len(manifestJSON2)), + } + + manifestCount := 1 + timerStart := false + + // Create an OCI Registry Server + customHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + switch r.URL.Path { + case "/v2/testingchart/tags/list": + t := `{"tags": ["0.1.0","0.0.1","sha256"]}` + w.Write([]byte(t)) + case "/v2/testchart/tags/list": + t := `{"tags": ["1.0.0","0.1.1","sha256"]}` + w.Write([]byte(t)) + + case "/v2/_catalog": + t := `{"repositories": ["testingchart","testchart"]}` + w.Write([]byte(t)) + + case "/v2/testingchart/blobs/" + layerDesc.Digest.String(): + http.ServeFile(w, r, testingChartPath) + case "/v2/testchart/blobs/" + layerDesc2.Digest.String(): + http.ServeFile(w, r, testChartPath) + case "/v2/testingchart/manifests/0.1.0": + if accept := r.Header.Get("Accept"); !strings.Contains(accept, manifestDesc.MediaType) { + assert.NoError(t, err) + w.WriteHeader(http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", manifestDesc.MediaType) + w.Header().Set("Docker-Content-Digest", manifestDesc.Digest.String()) + if _, err := w.Write(manifestJSON); err != nil { + assert.NoError(t, err) + } + case "/v2/testchart/manifests/1.0.0": + if r.Method == http.MethodHead { + if rateLimitedHeader { + w.Header().Set("RateLimit-Remaining", "0;w=60") + } + w.WriteHeader(http.StatusOK) + return + } + manifestCount++ + if manifestCount > 1 { + if !timerStart { + go func() { + d := time.NewTicker(1 * time.Minute) + for { + <-d.C + manifestCount = 0 + return + } + }() + timerStart = true + } + w.WriteHeader(http.StatusTooManyRequests) + return + } + if accept := r.Header.Get("Accept"); !strings.Contains(accept, manifestDesc2.MediaType) { + assert.NoError(t, err) + w.WriteHeader(http.StatusBadRequest) + return + } + w.Header().Set("Content-Type", manifestDesc2.MediaType) + w.Header().Set("Docker-Content-Digest", manifestDesc2.Digest.String()) + if _, err := w.Write(manifestJSON2); err != nil { + assert.NoError(t, err) + } + + } + }) + + // Create a new test server + ts := httptest.NewUnstartedServer(customHandler) + + ip := getOutboundIP() + // Bind the server to a specific IP address (your local machine's IP) + listener, err := net.Listen("tcp", fmt.Sprintf("%s:8080", ip.String())) + if err != nil { + log.Printf("Failed to bind to local IP: %v", err) + return nil, err + } + ts.Listener = listener + ts.Start() + + return ts, nil +} + +func AddHelmChart(u *url.URL) error { + chartTar, err := os.ReadFile("../../../testdata/testingchart-0.1.0.tgz") + if err != nil { + return err + } + + configBlob := []byte("config") + configDesc := ocispec.Descriptor{ + MediaType: registry.ConfigMediaType, + Digest: digest.FromBytes(configBlob), + Size: int64(len(configBlob)), + } + layerDesc := ocispec.Descriptor{ + MediaType: registry.ChartLayerMediaType, + Digest: digest.FromBytes(chartTar), + Size: int64(len(chartTar)), + } + manifest := ocispec.Manifest{ + MediaType: ocispec.MediaTypeImageManifest, + Config: configDesc, + Layers: []ocispec.Descriptor{layerDesc}, + } + manifestJSON, err := json.Marshal(manifest) + if err != nil { + return err + } + + manifestDesc := ocispec.Descriptor{ + MediaType: ocispec.MediaTypeImageManifest, + Digest: digest.FromBytes(manifestJSON), + Size: int64(len(manifestJSON)), + } + + target := memory.New() + target.Push(context.Background(), configDesc, bytes.NewReader(configBlob)) + target.Push(context.Background(), layerDesc, bytes.NewReader(chartTar)) + target.Push(context.Background(), manifestDesc, bytes.NewReader(manifestJSON)) + err = target.Tag(context.Background(), manifestDesc, "0.1.0") + if err != nil { + return err + } + + ociClient, err := oci.NewClient(fmt.Sprintf("oci://%s/rancher/testingchart", u.Host), v1.RepoSpec{}, nil) + if err != nil { + return err + } + + orasRepository, err := ociClient.GetOrasRepository() + if err != nil { + return err + } + orasRepository.PlainHTTP = true + + _, err = oras.Copy(context.Background(), target, "0.1.0", orasRepository, "", oras.DefaultCopyOptions) + if err != nil { + return err + } + + return nil +} + +// TestOCIRepo tests CREATE, UPDATE, and DELETE operations of OCI ClusterRepo resources +func (c *ClusterRepoTestSuite) TestOCIRepo() { + //start registry + ts, err := StartRegistry() + assert.NoError(c.T(), err) + + defer ts.Close() + + u, err := url.Parse(ts.URL) + require.NoError(c.T(), err) + + //push testingchart helm chart + err = AddHelmChart(u) + require.NoError(c.T(), err) + + c.testClusterRepo(ClusterRepoParams{ + Name: OCIClusterRepoName, + URL1: fmt.Sprintf("oci://%s/rancher/testingchart", u.Host), + URL2: fmt.Sprintf("oci://%s/rancher/testingchart:0.1.0", u.Host), + Type: OCI, + InsecurePlainHTTP: true, + }) +} + +// TestOCIRepo2 tests CREATE, UPDATE, and DELETE operations of OCI ClusterRepo additional cases +func (c *ClusterRepoTestSuite) TestOCIRepo2() { + //start registry + ts, err := StartRegistry() + assert.NoError(c.T(), err) + + defer ts.Close() + + u, err := url.Parse(ts.URL) + require.NoError(c.T(), err) + + //push testingchart helm chart + err = AddHelmChart(u) + require.NoError(c.T(), err) + + c.testClusterRepo(ClusterRepoParams{ + Name: OCIClusterRepoName, + URL1: fmt.Sprintf("oci://%s/rancher", u.Host), + URL2: fmt.Sprintf("oci://%s/", u.Host), + Type: OCI, + InsecurePlainHTTP: true, + }) +} + +// TestOCIRepo3 tests 4xx response codes received from the registry +func (c *ClusterRepoTestSuite) TestOCIRepo3() { + statusCodes := [3]int{404, 401, 403} + for _, statusCode := range statusCodes { + u, err := StartErrorRegistry(statusCode) + require.NoError(c.T(), err) + + c.test4xxErrors(ClusterRepoParams{ + Name: OCIClusterRepoName, + URL1: fmt.Sprintf("oci://%s/rancher", u.Host), + StatusCode: statusCode, + InsecurePlainHTTP: true, + Type: OCI, + }) + } +} + +// TestOCIRepo4 tests 429 response code received from the registry +func (c *ClusterRepoTestSuite) TestOCIRepo4() { + ts, err := Start429Registry(c.T(), false) + require.NoError(c.T(), err) + + defer ts.Close() + + u, err := url.Parse(ts.URL) + require.NoError(c.T(), err) + + c.test429Error(ClusterRepoParams{ + Name: OCIClusterRepoName, + URL1: fmt.Sprintf("oci://%s/", u.Host), + InsecurePlainHTTP: true, + Type: OCI, + ForceRefresh: true, + }) +} + +// TestOCIRepo4 tests 429 response code received from the registry which sends RateLimited-Remaining header +func (c *ClusterRepoTestSuite) TestOCIRepo5() { + ts, err := Start429Registry(c.T(), true) + require.NoError(c.T(), err) + + defer ts.Close() + + u, err := url.Parse(ts.URL) + require.NoError(c.T(), err) + + c.test429Error(ClusterRepoParams{ + Name: OCIClusterRepoName, + URL1: fmt.Sprintf("oci://%s/", u.Host), + InsecurePlainHTTP: true, + Type: OCI, + ForceRefresh: false, + }) +} + +func (c *ClusterRepoTestSuite) test429Error(params ClusterRepoParams) { + var err error + + clusterRepo := v1.NewClusterRepo("", params.Name, v1.ClusterRepo{}) + setClusterRepoURL(&clusterRepo.Spec, params.Type, params.URL1) + clusterRepo.Spec.InsecurePlainHTTP = params.InsecurePlainHTTP + expoValues := v1.ExponentialBackOffValues{ + MinWait: 1, + MaxWait: 1, + MaxRetries: 1, + } + clusterRepo.Spec.ExponentialBackOffValues = &expoValues + clusterRepo, err = c.catalogClient.ClusterRepos().Create(context.TODO(), clusterRepo, metav1.CreateOptions{}) + assert.NoError(c.T(), err) + + err = wait.Poll(50*time.Millisecond, 5*time.Minute, func() (done bool, err error) { + clusterRepo, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + + for _, condition := range clusterRepo.Status.Conditions { + if v1.RepoCondition(condition.Type) == v1.OCIDownloaded { + return condition.Status == corev1.ConditionFalse && clusterRepo.Status.NumberOfRetries == 0, nil + } + } + + return false, nil + }) + assert.NoError(c.T(), err) + + configMap, err := c.corev1.ConfigMaps(helm.GetConfigMapNamespace(clusterRepo.Namespace)).Get(context.TODO(), helm.GenerateConfigMapName(clusterRepo.Name, 0, clusterRepo.UID), metav1.GetOptions{}) + assert.NoError(c.T(), err) + + data := configMap.BinaryData["content"] + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + assert.NoError(c.T(), err) + defer gz.Close() + data, err = io.ReadAll(gz) + assert.NoError(c.T(), err) + index := &repo.IndexFile{} + err = json.Unmarshal(data, index) + assert.NoError(c.T(), err) + + index.SortEntries() + assert.Equal(c.T(), len(index.Entries), 2) + assert.Equal(c.T(), len(index.Entries["testingchart"]), 2) + assert.NotEmpty(c.T(), index.Entries["testingchart"][0].Digest) + time.Sleep(65 * time.Second) + + if params.ForceRefresh { + // Refresh the clusterRepo + clusterRepo, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + clusterRepo.Spec.ForceUpdate = &metav1.Time{Time: time.Now()} + clusterRepo, err = c.catalogClient.ClusterRepos().Update(context.TODO(), clusterRepo.DeepCopy(), metav1.UpdateOptions{}) + assert.NoError(c.T(), err) + } + + err = wait.Poll(PollInterval, 5*time.Second, func() (done bool, err error) { + clusterRepo, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + + for _, condition := range clusterRepo.Status.Conditions { + if v1.RepoCondition(condition.Type) == v1.OCIDownloaded { + return condition.Status == corev1.ConditionTrue, nil + } + } + + return false, nil + }) + + clusterRepo, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + assert.Equal(c.T(), clusterRepo.Status.NumberOfRetries, 0, "Number of retries should be 0 since there were no 429s") + configMap, err = c.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Get(context.TODO(), clusterRepo.Status.IndexConfigMapName, metav1.GetOptions{}) + assert.NoError(c.T(), err) + + data = configMap.BinaryData["content"] + gz, err = gzip.NewReader(bytes.NewBuffer(data)) + assert.NoError(c.T(), err) + defer gz.Close() + data, err = io.ReadAll(gz) + assert.NoError(c.T(), err) + index = &repo.IndexFile{} + err = json.Unmarshal(data, index) + assert.NoError(c.T(), err) + + assert.Equal(c.T(), len(index.Entries), 2) + assert.Equal(c.T(), len(index.Entries["testchart"]), 2) + assert.Equal(c.T(), len(index.Entries["testingchart"]), 2) + assert.NotEmpty(c.T(), index.Entries["testchart"][0].Digest) + assert.NotEmpty(c.T(), index.Entries["testingchart"][0].Digest) + + err = c.catalogClient.ClusterRepos().Delete(context.TODO(), params.Name, metav1.DeleteOptions{}) + assert.NoError(c.T(), err) + + clusterRepo, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.Error(c.T(), err) +} + +func (c *ClusterRepoTestSuite) test4xxErrors(params ClusterRepoParams) { + // Create a ClusterRepo + cr := v1.NewClusterRepo("", params.Name, v1.ClusterRepo{}) + setClusterRepoURL(&cr.Spec, params.Type, params.URL1) + cr.Spec.InsecurePlainHTTP = params.InsecurePlainHTTP + _, err := c.catalogClient.ClusterRepos().Create(context.TODO(), cr, metav1.CreateOptions{}) + assert.NoError(c.T(), err) + + err = wait.Poll(PollInterval, 5*time.Second, func() (done bool, err error) { + clusterRepo, err := c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + + for _, condition := range clusterRepo.Status.Conditions { + if v1.RepoCondition(condition.Type) == v1.OCIDownloaded { + return condition.Status == corev1.ConditionFalse, nil + } + } + + return false, nil + }) + + clusterRepo, err := c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.NoError(c.T(), err) + + _, err = c.corev1.ConfigMaps(helm.GetConfigMapNamespace(clusterRepo.Namespace)).Get(context.TODO(), helm.GenerateConfigMapName(clusterRepo.Name, 0, clusterRepo.UID), metav1.GetOptions{}) + assert.True(c.T(), apierrors.IsNotFound(err)) + + err = c.catalogClient.ClusterRepos().Delete(context.TODO(), params.Name, metav1.DeleteOptions{}) + assert.NoError(c.T(), err) + + _, err = c.catalogClient.ClusterRepos().Get(context.TODO(), params.Name, metav1.GetOptions{}) + assert.Error(c.T(), err) +} + +// TestOCI tests creating an OCI clusterrepo and install a chart +func (c *ClusterRepoTestSuite) TestOCIRepoChartInstallation() { + //start registry + ts, err := StartRegistry() + assert.NoError(c.T(), err) + + u, err := url.Parse(ts.URL) + require.NoError(c.T(), err) + + //push testingchart helm chart + err = AddHelmChart(u) + require.NoError(c.T(), err) + + repoName := "oci" + + // create cluster repo + catalogClient, err := c.client.GetClusterCatalogClient("local") + assert.NoError(c.T(), err) + + clusterRepo := &v1.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{ + Name: repoName, + }, + Spec: v1.RepoSpec{ + URL: fmt.Sprintf("oci://%s/rancher", u.Host), + InsecurePlainHTTP: true, + }, + } + _, err = catalogClient.ClusterRepos().Create(context.Background(), clusterRepo, metav1.CreateOptions{}) + assert.NoError(c.T(), err) + + // Validate the ClusterRepo was created + _, err = c.pollUntilDownloaded(repoName, metav1.Time{}) + require.NoError(c.T(), err) + + // check if chart can be fetched + chartInstallAction := types.ChartInstallAction{ + DisableHooks: false, + Timeout: nil, + } + + chartInstallAction.Charts = []types.ChartInstall{ + { + ChartName: "testingchart", + Version: "0.1.0", + ReleaseName: "testreleasename", + }, + } + + err = catalogClient.InstallChart(&chartInstallAction, repoName) + assert.NoError(c.T(), err) + + // wait for chart to be full deployed + watchAppInterface, err := catalogClient.Apps("default").Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + "testreleasename", + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + assert.NoError(c.T(), err) + + err = rancherWait.WatchWait(watchAppInterface, func(event watch.Event) (ready bool, err error) { + app := event.Object.(*v1.App) + + state := app.Status.Summary.State + if state == string(v1.StatusDeployed) { + return true, nil + } + return false, nil + }) + assert.NoError(c.T(), err) + + appCR, err := catalogClient.Apps("default").Get(context.TODO(), "testreleasename", metav1.GetOptions{}) + assert.NoError(c.T(), err) + + // Every AppCR installed through rancher must + // have the catalog clusterRepoName label + value, ok := appCR.Labels["catalog.cattle.io/cluster-repo-name"] + assert.True(c.T(), ok) + assert.Equal(c.T(), value, "oci") + + // Validate uninstalling the chart + chartUninstallAction := types.ChartUninstallAction{ + DisableHooks: false, + Timeout: nil, + } + + err = catalogClient.UninstallChart("testreleasename", "default", &chartUninstallAction) + assert.NoError(c.T(), err) + + watchAppInterface, err = catalogClient.Apps("default").Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + "testreleasename", + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + assert.NoError(c.T(), err) + + err = rancherWait.WatchWait(watchAppInterface, func(event watch.Event) (ready bool, err error) { + if event.Type == watch.Deleted { + return true, nil + } + return false, nil + }) + assert.NoError(c.T(), err) + + // Validate deleting the ClusterRepo + err = catalogClient.ClusterRepos().Delete(context.Background(), "oci", metav1.DeleteOptions{}) + assert.NoError(c.T(), err) + + err = catalogClient.ClusterRepos().Delete(context.Background(), "oci", metav1.DeleteOptions{}) + assert.Error(c.T(), err) +} + +// testClusterRepo takes in ClusterRepoParams and tests CREATE, UPDATE, and DELETE operations +func (c *ClusterRepoTestSuite) testClusterRepo(params ClusterRepoParams) { + // Create a ClusterRepo + cr := v1.NewClusterRepo("", params.Name, v1.ClusterRepo{}) + setClusterRepoURL(&cr.Spec, params.Type, params.URL1) + cr.Spec.InsecurePlainHTTP = params.InsecurePlainHTTP + _, err := c.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).Create(cr) + require.NoError(c.T(), err) + time.Sleep(1 * time.Second) + + // Validate the ClusterRepo was created and resources were downloaded + clusterRepo, err := c.pollUntilDownloaded(params.Name, metav1.Time{}) + require.NoError(c.T(), err) + + status := c.getStatusFromClusterRepo(clusterRepo) + assert.Equal(c.T(), params.URL1, status.URL) + + // Save download timestamp and generation count before changing the URL + downloadTime := status.DownloadTime + observedGeneration := status.ObservedGeneration + + // Validate updating the ClusterRepo by changing the repo URL and verifying DownloadTime was updated (meaning new resources were pulled) + spec := c.getSpecFromClusterRepo(clusterRepo) + setClusterRepoURL(spec, params.Type, params.URL2) + clusterRepoUpdated := *clusterRepo + clusterRepoUpdated.Spec = spec + + _, err = c.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).Replace(&clusterRepoUpdated) + require.NoError(c.T(), err) + + clusterRepo, err = c.pollUntilDownloaded(params.Name, downloadTime) + require.NoError(c.T(), err) + + status = c.getStatusFromClusterRepo(clusterRepo) + assert.Equal(c.T(), params.URL2, status.URL) + assert.Greater(c.T(), status.ObservedGeneration, observedGeneration) + + // Validate deleting the ClusterRepo + err = c.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).Delete(clusterRepo) + require.NoError(c.T(), err) + + _, err = c.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).ByID(params.Name) + require.Error(c.T(), err) +} + +// pollUntilDownloaded Polls until the ClusterRepo of the given name has been downloaded (by comparing prevDownloadTime against the current DownloadTime) +func (c *ClusterRepoTestSuite) pollUntilDownloaded(ClusterRepoName string, prevDownloadTime metav1.Time) (*stevev1.SteveAPIObject, error) { + var clusterRepo *stevev1.SteveAPIObject + err := wait.Poll(PollInterval, PollTimeout, func() (done bool, err error) { + clusterRepo, err = c.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).ByID(ClusterRepoName) + if err != nil { + return false, err + } + status := c.getStatusFromClusterRepo(clusterRepo) + if clusterRepo.Name != ClusterRepoName { + return false, nil + } + + return status.DownloadTime != prevDownloadTime, nil + }) + + return clusterRepo, err +} + +func (c *ClusterRepoTestSuite) getSpecFromClusterRepo(obj *stevev1.SteveAPIObject) *v1.RepoSpec { + spec := &v1.RepoSpec{} + err := stevev1.ConvertToK8sType(obj.Spec, spec) + require.NoError(c.T(), err) + + return spec +} + +func (c *ClusterRepoTestSuite) getStatusFromClusterRepo(obj *stevev1.SteveAPIObject) *v1.RepoStatus { + status := &v1.RepoStatus{} + err := stevev1.ConvertToK8sType(obj.Status, status) + require.NoError(c.T(), err) + + return status +} + +func setClusterRepoURL(spec *v1.RepoSpec, repoType RepoType, URL string) { + switch repoType { + case Git: + spec.GitRepo = URL + case HTTP: + spec.URL = URL + case OCI: + spec.URL = URL + } +} + +// Get preferred outbound ip of this machine +func getOutboundIP() net.IP { + conn, err := net.Dial("udp", "8.8.8.8:80") + if err != nil { + logrus.Fatal(err) + } + defer conn.Close() + + localAddr := conn.LocalAddr().(*net.UDPAddr) + + return localAddr.IP +} + +func TestClusterRepoTestSuite(t *testing.T) { + suite.Run(t, new(ClusterRepoTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/rancher_managed_charts_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/rancher_managed_charts_test.go new file mode 100644 index 0000000..1d1cb6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/rancher_managed_charts_test.go @@ -0,0 +1,546 @@ +package integration + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/json" + "fmt" + "io" + "os" + "testing" + "time" + + "github.com/go-git/go-git/v5" + rv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + client "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + stevev1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/repo" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +const smallForkURL = "https://github.com/rancher/charts-small-fork" +const smallForkClusterRepoName = "rancher-charts-small-fork" + +var propagation = metav1.DeletePropagationForeground + +type RancherManagedChartsTest struct { + suite.Suite + client *rancher.Client + session *session.Session + restClientGetter genericclioptions.RESTClientGetter + catalogClient *catalog.Client + cluster *client.Cluster + corev1 corev1.CoreV1Interface + originalBranch string + originalGitRepo string +} + +func (w *RancherManagedChartsTest) TearDownSuite() { + w.session.Cleanup() + w.Require().NoError(w.updateSetting("system-managed-charts-operation-timeout", "300s")) + w.Require().NoError(w.updateSetting("system-feature-chart-refresh-seconds", "21600")) +} + +func (w *RancherManagedChartsTest) SetupSuite() { + var err error + testSession := session.NewSession() + w.session = testSession + w.client, err = rancher.NewClient("", testSession) + require.NoError(w.T(), err) + insecure := true + w.client.RancherConfig.Insecure = &insecure + w.catalogClient, err = w.client.GetClusterCatalogClient("local") + require.NoError(w.T(), err) + + kubeConfig, err := kubeconfig.GetKubeconfig(w.client, "local") + require.NoError(w.T(), err) + + restConfig, err := (*kubeConfig).ClientConfig() + require.NoError(w.T(), err) + //restConfig.Insecure = true + cset, err := kubernetes.NewForConfig(restConfig) + require.NoError(w.T(), err) + w.corev1 = cset.CoreV1() + + w.restClientGetter, err = kubeconfig.NewRestGetter(restConfig, *kubeConfig) + require.NoError(w.T(), err) + c, err := w.client.Management.Cluster.ByID("local") + require.NoError(w.T(), err) + w.cluster = c + w.Require().NoError(w.updateSetting("system-managed-charts-operation-timeout", "50s")) + w.Require().NoError(w.updateSetting("system-feature-chart-refresh-seconds", "21600")) + clusterRepo, err := w.catalogClient.ClusterRepos().Get(context.TODO(), "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + w.originalBranch = clusterRepo.Spec.GitBranch + w.originalGitRepo = clusterRepo.Spec.GitRepo + w.resetSettings() +} + +func (w *RancherManagedChartsTest) resetSettings() { + w.resetManagementCluster() + list, err := w.catalogClient.Operations("cattle-system").List(context.TODO(), metav1.ListOptions{}) + w.Require().NoError(err) + for _, item := range list.Items { + if item.Status.Release == "rancher-aks-operator" || item.Status.Release == "rancher-aks-operator-crd" { + w.Require().NoError(w.catalogClient.Operations("cattle-system").Delete(context.TODO(), item.Name, metav1.DeleteOptions{PropagationPolicy: &propagation})) + } + } + err = kwait.Poll(2*time.Second, time.Minute, func() (done bool, err error) { + list, err := w.catalogClient.Operations("cattle-system").List(context.TODO(), metav1.ListOptions{}) + w.Require().NoError(err) + for _, item := range list.Items { + if item.Status.Release == "rancher-aks-operator" || item.Status.Release == "rancher-aks-operator-crd" { + return false, nil + } + } + return true, nil + }) + w.Require().NoError(err) + w.Require().NoError(w.uninstallApp("cattle-system", "rancher-aks-operator")) + w.Require().NoError(w.uninstallApp("cattle-system", "rancher-aks-operator-crd")) + clusterRepo, err := w.catalogClient.ClusterRepos().Get(context.TODO(), "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + if clusterRepo.Spec.GitRepo != w.originalGitRepo { + clusterRepo.Spec.GitRepo = w.originalGitRepo + clusterRepo.Spec.GitBranch = w.originalBranch + downloadTime := clusterRepo.Status.DownloadTime + _, err = w.catalogClient.ClusterRepos().Update(context.TODO(), clusterRepo, metav1.UpdateOptions{}) + w.Require().NoError(err) + w.Require().NoError(w.pollUntilDownloaded("rancher-charts", downloadTime)) + } +} + +func TestRancherManagedChartsSuite(t *testing.T) { + suite.Run(t, new(RancherManagedChartsTest)) +} + +func (w *RancherManagedChartsTest) TestInstallChartLatestVersion() { + defer w.resetSettings() + ctx := context.Background() + + clusterRepo, err := w.catalogClient.ClusterRepos().Get(ctx, "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.GitRepo = "https://github.com/rancher/charts-small-fork" + clusterRepo.Spec.GitBranch = "aks-integration-test-working-charts" + clusterRepo, err = w.catalogClient.ClusterRepos().Update(ctx, clusterRepo, metav1.UpdateOptions{}) + w.Require().NoError(err) + downloadTime := clusterRepo.Status.DownloadTime + w.Require().NoError(w.pollUntilDownloaded("rancher-charts", downloadTime)) + + w.Require().NoError(w.updateManagementCluster()) + app, _, err := w.waitForAksChart(rv1.StatusDeployed, "rancher-aks-operator", 0) + w.Require().NoError(err) + + latest, err := w.catalogClient.GetLatestChartVersion("rancher-aks-operator", catalog.RancherChartRepo) + w.Require().NoError(err) + w.Assert().Equal(app.Spec.Chart.Metadata.Version, latest) +} + +func (w *RancherManagedChartsTest) TestUpgradeChartToLatestVersion() { + defer w.resetSettings() + + clusterRepo, err := w.catalogClient.ClusterRepos().Get(context.TODO(), "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + cfgMap, err := w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Get(context.TODO(), clusterRepo.Status.IndexConfigMapName, metav1.GetOptions{}) + w.Require().NoError(err) + origCfg := cfgMap.DeepCopy() + + // GETTING INDEX FROM CONFIGMAP AND MODIFYING IT + originalLatestVersion := w.updateConfigMap(cfgMap) + + //UPDATING THE CONFIGMAP + cfgMap, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + + //KWait for config map to be updated + w.Require().NoError(w.WaitForConfigMap(clusterRepo.Status.IndexConfigMapNamespace, clusterRepo.Status.IndexConfigMapName, originalLatestVersion)) + + //Updating the cluster + w.Require().NoError(w.updateManagementCluster()) + + app, _, err := w.waitForAksChart(rv1.StatusDeployed, "rancher-aks-operator", 0) + w.Require().NoError(err) + + w.Require().NoError(err) + w.Assert().Greater(originalLatestVersion, app.Spec.Chart.Metadata.Version) + + //REVERT CONFIGMAP TO ORIGINAL VALUE + cfgMap.BinaryData["content"] = origCfg.BinaryData["content"] + _, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + + clusterRepo, err = w.catalogClient.ClusterRepos().Get(context.TODO(), "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.ForceUpdate = &metav1.Time{Time: time.Now()} + _, err = w.catalogClient.ClusterRepos().Update(context.TODO(), clusterRepo.DeepCopy(), metav1.UpdateOptions{}) + w.Require().NoError(err) + + app, _, err = w.waitForAksChart(rv1.StatusDeployed, "rancher-aks-operator", app.Spec.Version) + w.Require().NoError(err) + + w.Assert().Equal(originalLatestVersion, app.Spec.Chart.Metadata.Version) +} + +func (w *RancherManagedChartsTest) TestUpgradeToWorkingVersion() { + defer w.resetSettings() + ctx := context.Background() + w.Require().Nil(w.cluster.AKSConfig) + _, err := w.catalogClient.Apps("cattle-system").Get(ctx, "rancher-aks-charts", metav1.GetOptions{}) + w.Require().Error(err) + + clusterRepo, err := w.catalogClient.ClusterRepos().Get(ctx, "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.GitRepo = "https://github.com/rancher/charts-small-fork" + clusterRepo.Spec.GitBranch = "aks-integration-test-1" + clusterRepo, err = w.catalogClient.ClusterRepos().Update(ctx, clusterRepo, metav1.UpdateOptions{}) + w.Require().NoError(err) + downloadTime := clusterRepo.Status.DownloadTime + w.Require().NoError(w.pollUntilDownloaded("rancher-charts", downloadTime)) + cfgMap, err := w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Get(context.TODO(), clusterRepo.Status.IndexConfigMapName, metav1.GetOptions{}) + w.Require().NoError(err) + origCfg := cfgMap.DeepCopy() + + // GETTING INDEX FROM CONFIGMAP AND MODIFYING iT + latestVersion := w.updateConfigMap(cfgMap) + //UPDATING THE CONFIGMAP + cfgMap, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + + //KWait for config map to be updated + w.Require().NoError(w.WaitForConfigMap(clusterRepo.Status.IndexConfigMapNamespace, clusterRepo.Status.IndexConfigMapName, latestVersion)) + list, err := w.catalogClient.Operations("cattle-system").List(ctx, metav1.ListOptions{}) + w.Require().NoError(err) + numberOfOps := countNumberOfOperations(list, "rancher-aks-operator", time.Now()) + //Updating the cluster + w.Require().NoError(w.updateManagementCluster()) + + _, at, err := w.waitForAksChart(rv1.StatusFailed, "rancher-aks-operator", 0) + w.Require().NoError(err) + list, err = w.catalogClient.Operations("cattle-system").List(ctx, metav1.ListOptions{}) + w.Require().NoError(err) + w.Require().LessOrEqual(countNumberOfOperations(list, "rancher-aks-operator", at), numberOfOps+2) + + //REVERT CONFIGMAP TO ORIGINAL VALUE + cfgMap.BinaryData["content"] = origCfg.BinaryData["content"] + _, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + clusterRepo, err = w.catalogClient.ClusterRepos().Get(ctx, "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.ForceUpdate = &metav1.Time{Time: time.Now()} + _, err = w.catalogClient.ClusterRepos().Update(context.TODO(), clusterRepo.DeepCopy(), metav1.UpdateOptions{}) + w.Require().NoError(err) + + app, _, err := w.waitForAksChart(rv1.StatusDeployed, "rancher-aks-operator", 0) + w.Require().NoError(err) + w.Assert().Equal(latestVersion, app.Spec.Chart.Metadata.Version) +} + +func (w *RancherManagedChartsTest) TestUpgradeToBrokenVersion() { + defer w.resetSettings() + ctx := context.Background() + + clusterRepo, err := w.catalogClient.ClusterRepos().Get(ctx, "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.GitRepo = "https://github.com/rancher/charts-small-fork" + clusterRepo.Spec.GitBranch = "aks-integration-test-2" + clusterRepo, err = w.catalogClient.ClusterRepos().Update(ctx, clusterRepo, metav1.UpdateOptions{}) + w.Require().NoError(err) + + downloadTime := clusterRepo.Status.DownloadTime + w.Require().NoError(w.pollUntilDownloaded("rancher-charts", downloadTime)) + cfgMap, err := w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Get(context.TODO(), clusterRepo.Status.IndexConfigMapName, metav1.GetOptions{}) + w.Require().NoError(err) + origCfg := cfgMap.DeepCopy() + + // GETTING INDEX FROM CONFIGMAP AND MODIFYING iT + latestVersion := w.updateConfigMap(cfgMap) + //UPDATING THE CONFIGMAP + cfgMap, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + + //KWait for config map to be updated + w.Require().NoError(w.WaitForConfigMap(clusterRepo.Status.IndexConfigMapNamespace, clusterRepo.Status.IndexConfigMapName, latestVersion)) + + //Updating the cluster + w.Require().NoError(w.updateManagementCluster()) + + app, at, err := w.waitForAksChart(rv1.StatusDeployed, "rancher-aks-operator", 0) + w.Require().NoError(err) + + ops := w.catalogClient.Operations("cattle-system") + list, err := ops.List(ctx, metav1.ListOptions{}) + w.Require().NoError(err) + numberOfOps := countNumberOfOperations(list, "rancher-aks-operator", at) + + //REVERT CONFIGMAP TO ORIGINAL VALUE + cfgMap.BinaryData["content"] = origCfg.BinaryData["content"] + _, err = w.corev1.ConfigMaps(clusterRepo.Status.IndexConfigMapNamespace).Update(context.TODO(), cfgMap, metav1.UpdateOptions{}) + w.Require().NoError(err) + + clusterRepo, err = w.catalogClient.ClusterRepos().Get(ctx, "rancher-charts", metav1.GetOptions{}) + w.Require().NoError(err) + clusterRepo.Spec.ForceUpdate = &metav1.Time{Time: time.Now()} + _, err = w.catalogClient.ClusterRepos().Update(context.TODO(), clusterRepo.DeepCopy(), metav1.UpdateOptions{}) + w.Require().NoError(err) + + _, at, err = w.waitForAksChart(rv1.StatusFailed, "rancher-aks-operator", app.Spec.Version) + w.Require().NoError(err) + list, err = ops.List(ctx, metav1.ListOptions{}) + w.Require().NoError(err) + w.Require().LessOrEqual(countNumberOfOperations(list, "rancher-aks-operator", at), numberOfOps+2) +} + +func countNumberOfOperations(ops *rv1.OperationList, name string, at time.Time) int { + count := 0 + for _, item := range ops.Items { + if item.Status.Release == name && item.CreationTimestamp.Time.Before(at) { + count += 1 + } + } + return count +} + +func (w *RancherManagedChartsTest) WaitForConfigMap(namespace, name, latestVersion string) error { + return kwait.Poll(1*time.Second, 3*time.Minute, func() (done bool, err error) { + cfgMap, err := w.corev1.ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + w.Require().NoError(err) + gz, err := gzip.NewReader(bytes.NewBuffer(cfgMap.BinaryData["content"])) + w.Require().NoError(err) + defer gz.Close() + data, err := io.ReadAll(gz) + w.Require().NoError(err) + index := &repo.IndexFile{} + w.Require().NoError(json.Unmarshal(data, index)) + index.SortEntries() + return index.Entries["rancher-aks-operator"][0].Version < latestVersion, nil + }) +} + +func (w *RancherManagedChartsTest) updateConfigMap(cfgMap *v1.ConfigMap) string { + gz, err := gzip.NewReader(bytes.NewBuffer(cfgMap.BinaryData["content"])) + w.Require().NoError(err) + defer gz.Close() + data, err := io.ReadAll(gz) + w.Require().NoError(err) + index := &repo.IndexFile{} + w.Require().NoError(json.Unmarshal(data, index)) + index.SortEntries() + latestVersion := index.Entries["rancher-aks-operator"][0].Version + index.Entries["rancher-aks-operator"] = index.Entries["rancher-aks-operator"][1:] + marshal, err := json.Marshal(index) + w.Require().NoError(err) + var compressedData bytes.Buffer + writer := gzip.NewWriter(&compressedData) + _, err = writer.Write(marshal) + w.Require().NoError(err) + w.Require().NoError(writer.Close()) + cfgMap.BinaryData["content"] = compressedData.Bytes() + return latestVersion +} + +func (w *RancherManagedChartsTest) waitForAksChart(status rv1.Status, name string, previousVersion int) (*rv1.App, time.Time, error) { + t := 360 + var app *rv1.App + var at time.Time + err := kwait.Poll(PollInterval, time.Duration(t)*time.Second, func() (done bool, err error) { + app, err = w.catalogClient.Apps("cattle-system").Get(context.TODO(), name, metav1.GetOptions{}) + e, ok := err.(*errors.StatusError) + if ok && errors.IsNotFound(e) { + return false, nil + } + if err != nil { + return false, err + } + if app.Spec.Info.Status == status && app.Spec.Version > previousVersion { + at = time.Now().Add(-(2 * PollInterval)).UTC() + return true, nil + } + return false, nil + }) + w.Require().NoError(err) + return app, at, err +} + +func (w *RancherManagedChartsTest) updateManagementCluster() error { + w.cluster.AKSConfig = &client.AKSClusterConfigSpec{} + c, err := w.client.Management.Cluster.Replace(w.cluster) + w.cluster = c + return err +} + +func (w *RancherManagedChartsTest) resetManagementCluster() { + w.cluster.AKSConfig = nil + w.cluster.AppliedSpec.AKSConfig = nil + c, err := w.client.Management.Cluster.Replace(w.cluster) + w.Require().NoError(err) + err = kwait.Poll(5*time.Second, 2*time.Minute, func() (done bool, err error) { + c, err = w.client.Management.Cluster.ByID("local") + if err != nil { + return false, err + } + if c.AKSConfig == nil { + return true, nil + } + return false, nil + }) + w.Require().NoError(err) + w.cluster = c + err = kwait.Poll(5*time.Second, 2*time.Minute, func() (done bool, err error) { + list, err := w.corev1.Secrets("cattle-system").List(context.TODO(), metav1.ListOptions{LabelSelector: "name in (rancher-aks-operator, rancher-aks-operator-crd)"}) + w.Require().NoError(err) + if len(list.Items) == 0 { + return true, nil + } + for _, s := range list.Items { + w.Require().NoError(w.corev1.Secrets("cattle-system").Delete(context.Background(), s.Name, metav1.DeleteOptions{PropagationPolicy: &propagation})) + } + return false, nil + }) + w.Require().NoError(err) +} + +func (w *RancherManagedChartsTest) updateSetting(name, value string) error { + // Use the Steve client instead of the main one to be able to set a setting's value to an empty string. + existing, err := w.client.Steve.SteveType("management.cattle.io.setting").ByID(name) + if err != nil { + return err + } + + var s v3.Setting + if err := stevev1.ConvertToK8sType(existing.JSONResp, &s); err != nil { + return err + } + + s.Value = value + _, err = w.client.Steve.SteveType("management.cattle.io.setting").Update(existing, s) + return err +} + +func (w *RancherManagedChartsTest) uninstallApp(namespace, chartName string) error { + var cfg action.Configuration + if err := cfg.Init(w.restClientGetter, namespace, "", logrus.Infof); err != nil { + return err + } + l := action.NewList(&cfg) + l.All = true + l.SetStateMask() + releases, err := l.Run() + if err != nil { + return fmt.Errorf("failed to fetch all releases in the %s namespace: %w", namespace, err) + } + for _, r := range releases { + if r.Chart.Name() == chartName { + err = kwait.Poll(10*time.Second, time.Minute, func() (done bool, err error) { + act := action.NewUninstall(&cfg) + act.Wait = true + act.Timeout = time.Minute + if _, err = act.Run(r.Name); err != nil { + return false, nil + } + return true, nil + }) + w.Require().NoError(err) + } + } + return nil +} + +// pollUntilDownloaded Polls until the ClusterRepo of the given name has been downloaded (by comparing prevDownloadTime against the current DownloadTime) +func (w *RancherManagedChartsTest) pollUntilDownloaded(ClusterRepoName string, prevDownloadTime metav1.Time) error { + err := kwait.Poll(PollInterval, time.Minute, func() (done bool, err error) { + clusterRepo, err := w.catalogClient.ClusterRepos().Get(context.TODO(), ClusterRepoName, metav1.GetOptions{}) + if err != nil { + return false, err + } + w.Require().NoError(err) + if clusterRepo.Name != ClusterRepoName { + return false, nil + } + + return clusterRepo.Status.DownloadTime != prevDownloadTime, nil + }) + return err +} + +func (w *RancherManagedChartsTest) TestServeIcons() { + // Clone the git repository at a spcecific location so + // that Rancher assumes it as prebuild helm repository. + // Since Rancher starts at build/testdata, the LocalDir would + // be build/rancher-data.... Also since this test resides in + // tests/v2/integration/catalogv2, the cloneDir would be + // ../../../../build/rancher-data/... + repoURL := "https://github.com/rancher/charts-small-fork" + cloneDir := "../../../../build/rancher-data/local-catalogs/v2/rancher-charts-small-fork/d39a2f6abd49e537e5015bbe1a4cd4f14919ba1c3353208a7ff6be37ffe00c52" + + err := os.MkdirAll(cloneDir, os.ModePerm) + w.Require().NoError(err) + + _, err = git.PlainClone(cloneDir, false, &git.CloneOptions{ + URL: repoURL, + Depth: 1, + }) + w.Require().NoError(err) + + // Testing: Chart.icon field with (file:// scheme) + // Create ClusterRepo for charts-small-fork + clusterRepoToCreate := rv1.NewClusterRepo("", smallForkClusterRepoName, + rv1.ClusterRepo{ + Spec: rv1.RepoSpec{ + GitRepo: smallForkURL, + GitBranch: "main", + }, + }, + ) + _, err = w.client.Steve.SteveType(catalog.ClusterRepoSteveResourceType).Create(clusterRepoToCreate) + w.Require().NoError(err) + time.Sleep(1 * time.Second) + + w.Require().NoError(w.pollUntilDownloaded(smallForkClusterRepoName, metav1.Time{})) + + // Get Charts from the ClusterRepo + smallForkCharts, err := w.catalogClient.GetChartsFromClusterRepo(smallForkClusterRepoName) + w.Require().NoError(err) + w.Assert().Greater(len(smallForkCharts), 1) + + // Get the client settings to update settings.SystemCatalog + systemCatalog, err := w.client.Management.Setting.ByID("system-catalog") + w.Require().NoError(err) + w.Assert().Equal("external", systemCatalog.Value) + + // Update settings.SystemCatalog to bundled + systemCatalogUpdated, err := w.client.Management.Setting.Update(systemCatalog, map[string]interface{}{"value": "bundled"}) + w.Require().NoError(err) + w.Assert().Equal("bundled", systemCatalogUpdated.Value) + + imgLength, err := w.catalogClient.FetchChartIcon(smallForkClusterRepoName, "rancher-cis-benchmark") + w.Require().NoError(err) + w.Assert().Greater(imgLength, 0) + + // Update settings.SystemCatalog to external + _, err = w.client.Management.Setting.Update(systemCatalog, map[string]interface{}{"value": "external"}) + w.Require().NoError(err) + + // Deleting clusterRepo + err = w.catalogClient.ClusterRepos().Delete(context.Background(), smallForkClusterRepoName, metav1.DeleteOptions{}) + w.Require().NoError(err) + + // Delete the cloneDir + err = os.RemoveAll(cloneDir) + w.Require().NoError(err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/system_charts_version_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/system_charts_version_test.go new file mode 100644 index 0000000..c8125c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/system_charts_version_test.go @@ -0,0 +1,270 @@ +package integration + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/rancher/rancher/pkg/api/scheme" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/tests/integration/pkg/defaults" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + stevev1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/kubeapi/workloads/deployments" + "github.com/rancher/shepherd/extensions/kubeapi/workloads/pods" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/release" + appv1 "k8s.io/api/apps/v1" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/cli-runtime/pkg/genericclioptions" +) + +const ( + cattleSystemNameSpace = "cattle-system" + rancherWebhook = "rancher-webhook" +) + +type SystemChartsVersionSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + restClientGetter genericclioptions.RESTClientGetter + catalogClient *catalog.Client + latestWebhookVersion string +} + +func (w *SystemChartsVersionSuite) TearDownSuite() { + w.session.Cleanup() +} + +func (w *SystemChartsVersionSuite) SetupSuite() { + var err error + testSession := session.NewSession() + w.session = testSession + + w.client, err = rancher.NewClient("", testSession) + require.NoError(w.T(), err) + + w.catalogClient, err = w.client.GetClusterCatalogClient("local") + require.NoError(w.T(), err) + + kubeConfig, err := kubeconfig.GetKubeconfig(w.client, "local") + require.NoError(w.T(), err) + restConfig, err := (*kubeConfig).ClientConfig() + require.NoError(w.T(), err) + w.restClientGetter, err = kubeconfig.NewRestGetter(restConfig, *kubeConfig) + require.NoError(w.T(), err) + + w.latestWebhookVersion, err = w.catalogClient.GetLatestChartVersion(rancherWebhook, catalog.RancherChartRepo) + require.NoError(w.T(), err) + + require.NoError(w.T(), w.updateSetting("rancher-webhook-version", w.latestWebhookVersion)) + require.NoError(w.T(), w.updateSetting("system-feature-chart-refresh-seconds", "10")) +} + +func (w *SystemChartsVersionSuite) resetSettings() { + w.T().Helper() + require.NoError(w.T(), w.updateSetting("rancher-webhook-version", w.latestWebhookVersion)) + require.NoError(w.T(), w.updateSetting("system-feature-chart-refresh-seconds", "10")) + + // need to recreate the rancher-webhook pod because there are rbac issues without doing so. + dynamicClient, err := w.client.GetRancherDynamicClient() + require.NoError(w.T(), err) + + podList, err := dynamicClient.Resource(pods.PodGroupVersionResource).Namespace(cattleSystemNameSpace).List(context.Background(), metav1.ListOptions{}) + require.NoError(w.T(), err) + + var podName string + + for _, pod := range podList.Items { + name := pod.GetName() + if strings.Contains(name, rancherWebhook) { + podName = name + break + } + } + + err = dynamicClient.Resource(pods.PodGroupVersionResource).Namespace(cattleSystemNameSpace).Delete(context.Background(), podName, metav1.DeleteOptions{}) + require.NoError(w.T(), err) + + err = kwait.Poll(500*time.Millisecond, 10*time.Minute, func() (done bool, err error) { + deployment, err := dynamicClient.Resource(deployments.DeploymentGroupVersionResource).Namespace(cattleSystemNameSpace).Get(context.TODO(), rancherWebhook, metav1.GetOptions{}) + if k8sErrors.IsNotFound(err) { + return false, nil + } else if err != nil { + return false, err + } + + newDeployment := &appv1.Deployment{} + err = scheme.Scheme.Convert(deployment, newDeployment, deployment.GroupVersionKind()) + if err != nil { + return false, err + } + if newDeployment.Status.ReadyReplicas == *newDeployment.Spec.Replicas { + return true, nil + } + + return false, nil + }) + require.NoError(w.T(), err) + +} + +func TestSystemChartsVersionSuite(t *testing.T) { + // suite.Run(t, new(SystemChartsVersionSuite)) +} + +func (w *SystemChartsVersionSuite) TestInstallWebhook() { + defer w.resetSettings() + + const exactVersion = "2.0.3+up0.3.3" + w.Require().NoError(w.uninstallApp("cattle-system", "rancher-webhook")) + w.Require().NoError(w.updateSetting("rancher-webhook-version", exactVersion)) + + watcher, err := w.catalogClient.Apps("cattle-system").Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + "rancher-webhook", + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + w.Require().NoError(err) + + err = wait.WatchWait(watcher, func(event watch.Event) (ready bool, err error) { + if event.Type == watch.Error { + return false, fmt.Errorf("there was an error installing the rancher-webhook chart") + } else if event.Type == watch.Added { + return true, nil + } + return false, nil + }) + w.Require().NoError(err) + + // Allow the new release to fully deploy. Otherwise, the client won't find it among current releases. + var newRelease *release.Release + err = kwait.Poll(10*time.Second, 2*time.Minute, func() (done bool, err error) { + newRelease, err = w.fetchRelease("cattle-system", "rancher-webhook") + if err != nil { + return false, nil + } + if v := newRelease.Chart.Metadata.Version; v != exactVersion { + w.T().Logf("%s version %s does not yet match expected %s", newRelease.Chart.Name(), v, exactVersion) + return false, nil + } + return true, nil + }) + w.Require().NoError(err) +} + +func (w *SystemChartsVersionSuite) TestInstallFleet() { + defer w.resetSettings() + + w.Require().NoError(w.uninstallApp("cattle-fleet-system", "fleet")) + + const minVersion = "102.0.0+up0.6.0" + w.Require().NoError(w.updateSetting("fleet-min-version", minVersion)) + + watcher, err := w.catalogClient.Apps("cattle-fleet-system").Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + "fleet", + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + w.Require().NoError(err) + + err = wait.WatchWait(watcher, func(event watch.Event) (ready bool, err error) { + if event.Type == watch.Error { + return false, fmt.Errorf("there was an error installing the fleet chart") + } else if event.Type == watch.Added { + return true, nil + } + return false, nil + }) + w.Require().NoError(err) + + // Allow the new release to fully deploy. Otherwise, the client won't find it among current releases. + var newRelease *release.Release + err = kwait.Poll(10*time.Second, 2*time.Minute, func() (done bool, err error) { + newRelease, err = w.fetchRelease("cattle-fleet-system", "fleet") + if err != nil { + return false, nil + } + return true, nil + }) + w.Require().NoError(err) + + latest, err := w.catalogClient.GetLatestChartVersion("fleet", catalog.RancherChartRepo) + w.Require().NoError(err) + + // Ensure Rancher deployed the latest version when the minimum version is below the latest. + w.Assert().Equal(newRelease.Chart.Metadata.Version, latest) +} + +func (w *SystemChartsVersionSuite) uninstallApp(namespace, chartName string) error { + var cfg action.Configuration + if err := cfg.Init(w.restClientGetter, namespace, "", logrus.Infof); err != nil { + return err + } + releases, err := w.getReleases(&cfg) + if err != nil { + return fmt.Errorf("failed to fetch all releases in the %s namespace: %w", namespace, err) + } + for _, r := range releases { + if r.Chart.Name() == chartName { + err = kwait.Poll(10*time.Second, time.Minute, func() (done bool, err error) { + if _, err := action.NewUninstall(&cfg).Run(r.Name); err != nil { + return false, nil + } + return true, nil + }) + return err + } + } + return fmt.Errorf("the chartName %s was never installed", chartName) +} + +func (w *SystemChartsVersionSuite) getReleases(cfg *action.Configuration) ([]*release.Release, error) { + l := action.NewList(cfg) + return l.Run() +} + +func (w *SystemChartsVersionSuite) fetchRelease(namespace, chartName string) (*release.Release, error) { + var cfg action.Configuration + if err := cfg.Init(w.restClientGetter, namespace, "", logrus.Infof); err != nil { + return nil, err + } + releases, err := w.getReleases(&cfg) + if err != nil { + return nil, err + } + for _, r := range releases { + if r.Chart.Name() == chartName { + return r, nil + } + } + return nil, fmt.Errorf("%s release not found", chartName) +} + +func (w *SystemChartsVersionSuite) updateSetting(name, value string) error { + // Use the Steve client instead of the main one to be able to set a setting's value to an empty string. + existing, err := w.client.Steve.SteveType("management.cattle.io.setting").ByID(name) + if err != nil { + return err + } + + var s v3.Setting + if err := stevev1.ConvertToK8sType(existing.JSONResp, &s); err != nil { + return err + } + + s.Value = value + _, err = w.client.Steve.SteveType("management.cattle.io.setting").Update(existing, s) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/ui_plugin_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/ui_plugin_test.go new file mode 100644 index 0000000..95d7ce2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/catalogv2/ui_plugin_test.go @@ -0,0 +1,298 @@ +package integration + +import ( + "context" + "crypto/tls" + "encoding/json" + "fmt" + "mime" + "path/filepath" + + "io" + "net/http" + "testing" + "time" + + rv1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1" + "github.com/rancher/rancher/pkg/controllers/dashboard/plugin" + "github.com/rancher/rancher/pkg/namespace" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/pkg/api/steve/catalog/types" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "helm.sh/helm/v3/pkg/action" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/kubernetes/typed/core/v1" +) + +type UIPluginTest struct { + suite.Suite + client *rancher.Client + session *session.Session + restClientGetter genericclioptions.RESTClientGetter + catalogClient *catalog.Client + corev1 corev1.CoreV1Interface +} + +func (w *UIPluginTest) TearDownSuite() { + w.Require().NoError(w.uninstallApp(namespace.UIPluginNamespace, "uk-locale")) + w.Require().NoError(w.uninstallApp(namespace.UIPluginNamespace, "clock")) + w.Require().NoError(w.catalogClient.ClusterRepos().Delete(context.Background(), "extensions-examples", metav1.DeleteOptions{PropagationPolicy: &propagation})) + w.session.Cleanup() + +} + +func (w *UIPluginTest) SetupSuite() { + var err error + testSession := session.NewSession() + w.session = testSession + w.client, err = rancher.NewClient("", testSession) + require.NoError(w.T(), err) + insecure := true + w.client.RancherConfig.Insecure = &insecure + w.catalogClient, err = w.client.GetClusterCatalogClient("local") + require.NoError(w.T(), err) + + kubeConfig, err := kubeconfig.GetKubeconfig(w.client, "local") + require.NoError(w.T(), err) + + restConfig, err := (*kubeConfig).ClientConfig() + require.NoError(w.T(), err) + cset, err := kubernetes.NewForConfig(restConfig) + require.NoError(w.T(), err) + w.corev1 = cset.CoreV1() + + w.restClientGetter, err = kubeconfig.NewRestGetter(restConfig, *kubeConfig) + require.NoError(w.T(), err) + _, err = w.catalogClient.ClusterRepos().Create(context.Background(), &rv1.ClusterRepo{ + ObjectMeta: metav1.ObjectMeta{Name: "extensions-examples"}, + Spec: rv1.RepoSpec{GitRepo: "https://github.com/rancher/ui-plugin-examples", GitBranch: "main"}, + }, metav1.CreateOptions{}) + w.Require().NoError(err) + w.Require().NoError(w.pollUntilDownloaded("extensions-examples", metav1.Time{})) + w.Require().NoError(w.catalogClient.InstallChart(&types.ChartInstallAction{ + DisableHooks: false, + Timeout: &metav1.Duration{Duration: 60 * time.Second}, + Wait: true, + Namespace: namespace.UIPluginNamespace, + DisableOpenAPIValidation: false, + Charts: []types.ChartInstall{{ + ChartName: "uk-locale", + Version: "0.1.1", + ReleaseName: "uk-locale", + Description: "locale", + }}, + }, "extensions-examples")) + w.Require().NoError(w.waitForChart(rv1.StatusDeployed, "uk-locale", 0)) + + w.Require().NoError(w.catalogClient.InstallChart(&types.ChartInstallAction{ + DisableHooks: false, + Timeout: &metav1.Duration{Duration: 60 * time.Second}, + Wait: true, + Namespace: namespace.UIPluginNamespace, + DisableOpenAPIValidation: false, + Charts: []types.ChartInstall{{ + ChartName: "clock", + Version: "0.2.0", + ReleaseName: "clock", + Description: "clock", + }}, + }, "extensions-examples")) + w.Require().NoError(w.waitForChart(rv1.StatusDeployed, "clock", 0)) + + w.Require().NoError(w.catalogClient.InstallChart(&types.ChartInstallAction{ + DisableHooks: false, + Timeout: &metav1.Duration{Duration: 60 * time.Second}, + Wait: true, + Namespace: namespace.UIPluginNamespace, + DisableOpenAPIValidation: false, + Charts: []types.ChartInstall{{ + ChartName: "top-level-product", + Version: "0.1.0", + ReleaseName: "top-level-product", + Description: "top-level-product", + Values: map[string]interface{}{ + "plugin": map[string]interface{}{ + "noCache": true, + }, + }, + }}, + }, "extensions-examples")) + w.Require().NoError(w.waitForChart(rv1.StatusDeployed, "top-level-product", 0)) + + //Waiting for controller cache to update + time.Sleep(10 * time.Second) +} + +func TestUIPluginSuite(t *testing.T) { + suite.Run(t, new(UIPluginTest)) +} + +// TestGetIndexAuthenticated Tests if all extensions are returned in the index if the user is authenticated +func (w *UIPluginTest) TestGetIndexAuthenticated() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + req, err := http.NewRequest(http.MethodGet, "https://localhost:443/v1/uiplugins", nil) + require.NoError(w.T(), err) + req.AddCookie(&http.Cookie{ + Name: "R_SESS", + Value: w.client.RancherConfig.AdminToken, + }) + + res, err := client.Do(req) + w.Require().NoError(err) + body, err := io.ReadAll(res.Body) + require.NoError(w.T(), err) + res.Body.Close() + var index plugin.SafeIndex + w.Require().NoError(json.Unmarshal(body, &index)) + w.Require().Equal(len(index.Entries), 3) +} + +// TestGetIndexUnauthenticated Tests if the unauthenticated extensions (and only them) are present +// in the anonymous index and that it is returned if the user is not authenticated +func (w *UIPluginTest) TestGetIndexUnauthenticated() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + + res, err := client.Get("https://localhost:443/v1/uiplugins") + w.Require().NoError(err) + body, err := io.ReadAll(res.Body) + require.NoError(w.T(), err) + res.Body.Close() + var index plugin.SafeIndex + w.Require().NoError(json.Unmarshal(body, &index)) + w.Require().Equal(len(index.Entries), 1) + _, ok := index.Entries["uk-locale"] + w.Require().True(ok) +} + +// TestGetSingleExtensionAuthenticated Tests that the requests returns the correct Content-Type header +func (w *UIPluginTest) TestCorrectContentType() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + file := "/top-level-product-0.1.0.umd.min.1.js" + req, _ := http.NewRequest(http.MethodGet, "https://localhost:443/v1/uiplugins/top-level-product/0.1.0/plugin"+file, nil) + req.AddCookie(&http.Cookie{ + Name: "R_SESS", + Value: w.client.RancherConfig.AdminToken, + }) + + res, _ := client.Do(req) + w.Require().Equal(res.StatusCode, http.StatusOK) + w.Require().Equal(mime.TypeByExtension(filepath.Ext(file)), res.Header.Get("Content-Type")) +} + +// TestGetSingleExtensionAuthenticated Tests that the requests succeeds if the user is authenticated +func (w *UIPluginTest) TestGetSingleExtensionAuthenticated() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + req, _ := http.NewRequest(http.MethodGet, "https://localhost:443/v1/uiplugins/clock/0.2.0/plugin/clock-0.2.0.umd.min.js", nil) + req.AddCookie(&http.Cookie{ + Name: "R_SESS", + Value: w.client.RancherConfig.AdminToken, + }) + + res, _ := client.Do(req) + w.Require().Equal(res.StatusCode, http.StatusOK) +} + +// TestGetSingleExtensionUnauthenticated Tests that the requests succeeds if +// the user is unauthenticated when the requested extension does not require authentication +func (w *UIPluginTest) TestGetSingleExtensionUnauthenticated() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + res, _ := client.Get("https://localhost:443/v1/uiplugins/uk-locale/0.1.1/plugin/uk-locale-0.1.1.umd.min.js") + + w.Require().Equal(res.StatusCode, http.StatusOK) +} + +// TestGetSingleUnauthorizedExtension Tests that the requests fails and returns 404 if the +// extension requires authentication and the user is not authenticated +func (w *UIPluginTest) TestGetSingleUnauthorizedExtension() { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }} + res, _ := client.Get("https://localhost:443/v1/uiplugins/clock/0.2.0/plugin/clock-0.2.0.umd.min.js") + w.Require().Equal(res.StatusCode, http.StatusNotFound) +} + +func (w *UIPluginTest) waitForChart(status rv1.Status, name string, previousVersion int) error { + t := 360 + var app *rv1.App + err := kwait.Poll(time.Duration(500*time.Millisecond), time.Duration(t)*time.Second, func() (done bool, err error) { + app, err = w.catalogClient.Apps(namespace.UIPluginNamespace).Get(context.TODO(), name, metav1.GetOptions{}) + e, ok := err.(*errors.StatusError) + if ok && errors.IsNotFound(e) { + return false, nil + } + if err != nil { + return false, err + } + if app.Spec.Info.Status == status && app.Spec.Version > previousVersion { + return true, nil + } + return false, nil + }) + w.Require().NoError(err) + return err +} + +func (w *UIPluginTest) uninstallApp(namespace, chartName string) error { + var cfg action.Configuration + if err := cfg.Init(w.restClientGetter, namespace, "", logrus.Infof); err != nil { + return err + } + l := action.NewList(&cfg) + l.All = true + l.SetStateMask() + releases, err := l.Run() + if err != nil { + return fmt.Errorf("failed to fetch all releases in the %s namespace: %w", namespace, err) + } + for _, r := range releases { + if r.Chart.Name() == chartName { + err = kwait.Poll(10*time.Second, time.Minute, func() (done bool, err error) { + act := action.NewUninstall(&cfg) + act.Wait = true + act.Timeout = time.Minute + if _, err = act.Run(r.Name); err != nil { + return false, nil + } + return true, nil + }) + w.Require().NoError(err) + } + } + return nil +} + +// pollUntilDownloaded Polls until the ClusterRepo of the given name has been downloaded (by comparing prevDownloadTime against the current DownloadTime) +func (w *UIPluginTest) pollUntilDownloaded(ClusterRepoName string, prevDownloadTime metav1.Time) error { + err := kwait.Poll(PollInterval, time.Minute, func() (done bool, err error) { + clusterRepo, err := w.catalogClient.ClusterRepos().Get(context.TODO(), ClusterRepoName, metav1.GetOptions{}) + if err != nil { + return false, err + } + w.Require().NoError(err) + if clusterRepo.Name != ClusterRepoName { + return false, nil + } + + return clusterRepo.Status.DownloadTime != prevDownloadTime, nil + }) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/project_user_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/project_user_test.go new file mode 100644 index 0000000..45ea6b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/project_user_test.go @@ -0,0 +1,106 @@ +package integration + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + namespaceName = "testnamespace" +) + +type ProjectUserTestSuite struct { + suite.Suite + testUser *management.User + client *rancher.Client + project *management.Project + session *session.Session +} + +func (p *ProjectUserTestSuite) TearDownSuite() { + p.session.Cleanup() +} + +func (p *ProjectUserTestSuite) SetupSuite() { + testSession := session.NewSession() + p.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(p.T(), err) + + p.client = client + + projectConfig := &management.Project{ + ClusterID: "local", + Name: "TestProject", + } + + testProject, err := client.Management.Project.Create(projectConfig) + require.NoError(p.T(), err) + + p.project = testProject + + enabled := true + var testuser = "testuser" + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(p.T(), err) + newUser.Password = user.Password + p.testUser = newUser +} + +func (p *ProjectUserTestSuite) TestCreateNamespaceProjectMember() { + subSession := p.session.NewSession() + defer subSession.Cleanup() + + client, err := p.client.WithSession(subSession) + require.NoError(p.T(), err) + + err = users.AddProjectMember(client, p.project, p.testUser, "project-member", nil) + require.NoError(p.T(), err) + + testUser, err := client.AsUser(p.testUser) + require.NoError(p.T(), err) + + createdNamespace, err := namespaces.CreateNamespace(testUser, namespaceName, "{}", map[string]string{}, map[string]string{}, p.project) + assert.NoError(p.T(), err) + assert.Equal(p.T(), namespaceName, createdNamespace.Name) +} + +func (p *ProjectUserTestSuite) TestCreateNamespaceProjectOwner() { + subSession := p.session.NewSession() + defer subSession.Cleanup() + + client, err := p.client.WithSession(subSession) + require.NoError(p.T(), err) + + err = users.AddProjectMember(client, p.project, p.testUser, "project-owner", nil) + require.NoError(p.T(), err) + + testUser, err := client.AsUser(p.testUser) + require.NoError(p.T(), err) + + createdNamespace, err := namespaces.CreateNamespace(testUser, namespaceName, "{}", map[string]string{}, map[string]string{}, p.project) + assert.NoError(p.T(), err) + assert.Equal(p.T(), namespaceName, createdNamespace.Name) +} + +func TestProjectUserTestSuite(t *testing.T) { + suite.Run(t, new(ProjectUserTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/resource_quota_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/resource_quota_test.go new file mode 100644 index 0000000..1b1851d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/projects/resource_quota_test.go @@ -0,0 +1,350 @@ +package integration + +import ( + "context" + "fmt" + "reflect" + "testing" + "time" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeapi/resourcequotas" + "github.com/rancher/shepherd/extensions/namespaces" + steveResourceQuotas "github.com/rancher/shepherd/extensions/resourcequotas" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/stretchr/testify/suite" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" +) + +const ( + resourceQuotaNamespaceName = "ns1" + resourceQuotaNamespaceName2 = "ns2" + localClusterID = "local" +) + +type ResourceQuotaSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (s *ResourceQuotaSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *ResourceQuotaSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + client, err := rancher.NewClient("", testSession) + s.Require().NoError(err) + s.client = client +} + +func (s *ResourceQuotaSuite) TestCreateNamespaceWithQuotaInProject() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + client, err := s.client.WithSession(subSession) + s.Require().NoError(err) + + projectLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "500m", + } + namespaceDefaultLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "200m", + } + + projectConfig := &management.Project{ + ClusterID: "local", + Name: "TestProject", + ResourceQuota: &management.ProjectResourceQuota{ + Limit: projectLimit, + }, + NamespaceDefaultResourceQuota: &management.NamespaceResourceQuota{ + Limit: namespaceDefaultLimit, + }, + } + testProject, err := client.Management.Project.Create(projectConfig) + s.Require().NoError(err) + + namespace, err := namespaces.CreateNamespace(client, resourceQuotaNamespaceName, "", map[string]string{}, map[string]string{}, testProject) + s.Require().NoError(err) + s.Require().NotNil(namespace) + + quotas, err := resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + s.Require().NoError(err) + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 1, "Expected 1 quota in a new namespace, but got %d", len(quotas.Items)) + + resourceList := quotas.Items[0].Spec.Hard + want := v1.ResourceList{ + v1.ResourceLimitsCPU: resource.MustParse("200m"), + } + s.Require().Equal(want, resourceList) + s.Require().NoError(err) +} + +func (s *ResourceQuotaSuite) TestCreateNamespaceWithOverriddenQuotaInProject() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + client, err := s.client.WithSession(subSession) + s.Require().NoError(err) + + projectConfig := &management.Project{ + ClusterID: "local", + Name: "TestProject", + ResourceQuota: &management.ProjectResourceQuota{ + Limit: &management.ResourceQuotaLimit{ + LimitsCPU: "500m", + }, + }, + NamespaceDefaultResourceQuota: &management.NamespaceResourceQuota{ + Limit: &management.ResourceQuotaLimit{ + LimitsCPU: "200m", + }, + }, + } + testProject, err := client.Management.Project.Create(projectConfig) + s.Require().NoError(err) + + annotations1 := map[string]string{ + "field.cattle.io/resourceQuota": "{\"limit\":{\"limitsCpu\":\"190m\"}}", + } + namespace, err := namespaces.CreateNamespace(client, resourceQuotaNamespaceName, "", map[string]string{}, annotations1, testProject) + s.Require().NoError(err) + s.Require().NotNil(namespace) + + annotations2 := map[string]string{ + "field.cattle.io/resourceQuota": "{\"limit\":{\"limitsCpu\":\"400m\", \"configMaps\":\"50\"}}", + } + namespace, err = namespaces.CreateNamespace(client, resourceQuotaNamespaceName2, "", map[string]string{}, annotations2, testProject) + s.Require().NoError(err) + s.Require().NotNil(namespace) + + quotas, err := resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + s.Require().NoError(err) + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 1, "Expected 1 quota in %s, but got %d", resourceQuotaNamespaceName, len(quotas.Items)) + + resourceList := quotas.Items[0].Spec.Hard + want := v1.ResourceList{ + v1.ResourceLimitsCPU: resource.MustParse("190m"), + } + s.Require().Equal(want, resourceList) + s.Require().NoError(err) + + quotas, err = resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName2, metav1.ListOptions{}) + s.Require().NoError(err) + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 1, "Expected 1 quota in %s, but got %d", resourceQuotaNamespaceName2, len(quotas.Items)) + + resourceList = quotas.Items[0].Spec.Hard + want = v1.ResourceList{ + v1.ResourceLimitsCPU: resource.MustParse("0"), + } + s.Require().Equal(want, resourceList) + s.Require().NoError(err) +} + +func (s *ResourceQuotaSuite) TestRemoveQuotaFromProjectWithNamespacePropagation() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + client, err := s.client.WithSession(subSession) + s.Require().NoError(err) + + dynamicClient, err := client.GetRancherDynamicClient() + s.Require().NoError(err) + + projectLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "500m", + ConfigMaps: "10", + } + namespaceDefaultLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "200m", + ConfigMaps: "5", + } + + projectConfig := &management.Project{ + ClusterID: "local", + Name: "TestProject", + ResourceQuota: &management.ProjectResourceQuota{ + Limit: projectLimit, + }, + NamespaceDefaultResourceQuota: &management.NamespaceResourceQuota{ + Limit: namespaceDefaultLimit, + }, + } + testProject, err := client.Management.Project.Create(projectConfig) + s.Require().NoError(err) + + namespace, err := namespaces.CreateNamespace(client, resourceQuotaNamespaceName, "", map[string]string{}, map[string]string{}, testProject) + s.Require().NoError(err) + s.Require().NotNil(namespace) + + testProject.ResourceQuota.Limit.LimitsCPU = "" + testProject.NamespaceDefaultResourceQuota.Limit.LimitsCPU = "" + + _, err = client.Management.Project.Replace(testProject) + s.Require().NoError(err) + + quotas, err := resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + s.Require().NoError(err) + + // Allow the controller to update the resource quotas after the project has been updated. + quotaName := quotas.Items[0].Name + quotaID := fmt.Sprintf("%s/%s", resourceQuotaNamespaceName, quotaName) + err = steveResourceQuotas.CheckResourceActiveState(client, quotaID) + s.Require().NoError(err) + + // Wait a little while for the resourcequota to be updated. + // The quota controller sometimes gets conflict error trying to update the namespace annotation and needs time to retry. + want := v1.ResourceList{ + v1.ResourceConfigMaps: resource.MustParse("5"), + } + var resourceList v1.ResourceList + err = kwait.Poll(500*time.Millisecond, 10*time.Second, func() (done bool, err error) { + quotas, err = resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + if err != nil { + return false, err + } + if quotas == nil { + return false, nil + } + if len(quotas.Items) != 1 { + return false, fmt.Errorf("expected 1 quota in the namespace, but got %d", len(quotas.Items)) + } + resourceList = quotas.Items[0].Spec.Hard + if !reflect.DeepEqual(want, resourceList) { + return false, nil + } + return true, nil + }) + if err != nil { + // if it was a timeout error, check why it never succeeded so it can be reported as output + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 1, "Expected 1 quota in the namespace, but got %d", len(quotas.Items)) + s.Require().Equal(want, resourceList, "Expected the CPU limits to be removed, but config maps limit to remain") + } + s.Require().NoError(err) + + // Now remove the last resource limit from the project. + testProject.ResourceQuota.Limit.ConfigMaps = "" + testProject.NamespaceDefaultResourceQuota.Limit.ConfigMaps = "" + + watchInterface, err := dynamicClient.Resource(resourcequotas.ResourceQuotaGroupVersionResource).Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + quotaName, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + s.Require().NoError(err) + + _, err = client.Management.Project.Replace(testProject) + s.Require().NoError(err) + + err = wait.WatchWait(watchInterface, func(event watch.Event) (ready bool, err error) { + if event.Type == watch.Error { + return false, fmt.Errorf("there was an error deleting cluster") + } else if event.Type == watch.Deleted { + return true, nil + } + return false, nil + }) + s.Require().NoError(err) + + quotas, err = resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + s.Require().NoError(err) + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 0, "Expected no quotas in the namespace, but got %d", len(quotas.Items)) +} + +func (s *ResourceQuotaSuite) TestAddQuotaFromProjectWithNamespacePropagation() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + client, err := s.client.WithSession(subSession) + s.Require().NoError(err) + + projectLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "500m", + } + namespaceDefaultLimit := &management.ResourceQuotaLimit{ + LimitsCPU: "200m", + } + + projectConfig := &management.Project{ + ClusterID: "local", + Name: "TestProject", + ResourceQuota: &management.ProjectResourceQuota{ + Limit: projectLimit, + }, + NamespaceDefaultResourceQuota: &management.NamespaceResourceQuota{ + Limit: namespaceDefaultLimit, + }, + } + testProject, err := client.Management.Project.Create(projectConfig) + s.Require().NoError(err) + + namespace, err := namespaces.CreateNamespace(client, resourceQuotaNamespaceName, "", map[string]string{}, map[string]string{}, testProject) + s.Require().NoError(err) + s.Require().NotNil(namespace) + + testProject.ResourceQuota.Limit.Secrets = "20" + testProject.NamespaceDefaultResourceQuota.Limit.Secrets = "10" + + _, err = client.Management.Project.Replace(testProject) + s.Require().NoError(err) + + quotas, err := resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + s.Require().NoError(err) + + // Allow the controller to update the resource quotas after the project has been updated. + quotaName := quotas.Items[0].Name + quotaID := fmt.Sprintf("%s/%s", resourceQuotaNamespaceName, quotaName) + err = steveResourceQuotas.CheckResourceActiveState(client, quotaID) + s.Require().NoError(err) + + // Wait a little while for the resourcequota to be updated. + // The quota controller sometimes gets conflict error trying to update the namespace annotation and needs time to retry. + want := v1.ResourceList{ + v1.ResourceLimitsCPU: resource.MustParse("200m"), + v1.ResourceSecrets: resource.MustParse("10"), + } + var resourceList v1.ResourceList + err = kwait.Poll(500*time.Millisecond, 10*time.Second, func() (done bool, err error) { + quotas, err = resourcequotas.ListResourceQuotas(client, localClusterID, resourceQuotaNamespaceName, metav1.ListOptions{}) + if err != nil { + return false, err + } + if quotas == nil { + return false, nil + } + if len(quotas.Items) != 1 { + return false, fmt.Errorf("expected 1 quota in the namespace, but got %d", len(quotas.Items)) + } + resourceList = quotas.Items[0].Spec.Hard + if !reflect.DeepEqual(want, resourceList) { + return false, nil + } + return true, nil + }) + if err != nil { + // if it was a timeout error, check why it never succeeded so it can be reported as output + s.Require().NotNil(quotas) + s.Require().Lenf(quotas.Items, 1, "Expected 1 quota in the namespace, but got %d", len(quotas.Items)) + s.Require().Equal(want, resourceList, "Expected the secrets limits to be added") + } + s.Require().NoError(err) +} + +func TestResourceQuotaTestSuite(t *testing.T) { + suite.Run(t, new(ResourceQuotaSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/rtbs/rtbs_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/rtbs/rtbs_test.go new file mode 100644 index 0000000..fcf26da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/rtbs/rtbs_test.go @@ -0,0 +1,333 @@ +package integration + +import ( + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + extauthz "github.com/rancher/shepherd/extensions/kubeapi/authorization" + extnamespaces "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + "github.com/rancher/shepherd/extensions/kubeapi/secrets" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/api/scheme" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + authzv1 "k8s.io/api/authorization/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func init() { + authzv1.SchemeBuilder.AddToScheme(scheme.Scheme.Scheme) +} + +type RTBTestSuite struct { + suite.Suite + testUser *management.User + client *rancher.Client + project *management.Project + session *session.Session + downstreamClusterID string +} + +func (p *RTBTestSuite) TearDownSuite() { + p.session.Cleanup() +} + +func (p *RTBTestSuite) SetupSuite() { + p.downstreamClusterID = "local" + testSession := session.NewSession() + p.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(p.T(), err) + + p.client = client + + projectConfig := &management.Project{ + ClusterID: p.downstreamClusterID, + Name: "TestProject", + } + + testProject, err := client.Management.Project.Create(projectConfig) + require.NoError(p.T(), err) + + p.project = testProject + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(p.T(), err) + newUser.Password = user.Password + p.testUser = newUser +} + +func (p *RTBTestSuite) TestPRTBRoleTemplateInheritance() { + subSession := p.session.NewSession() + defer subSession.Cleanup() + + client, err := p.client.WithSession(subSession) + require.NoError(p.T(), err) + + projectName := strings.Split(p.project.ID, ":")[1] + createdNamespace, err := extnamespaces.CreateNamespace(client, p.downstreamClusterID, projectName, namegen.AppendRandomString("testns-"), "{}", map[string]string{}, map[string]string{}) + require.NoError(p.T(), err) + + testUser, err := client.AsUser(p.testUser) + require.NoError(p.T(), err) + + // Test that user can get a specified secret once granted the permission to do so via roletemplate inheritance bounded + // by a PRTB. + + secret, err := secrets.CreateSecretForCluster(client, &corev1.Secret{ObjectMeta: metav1.ObjectMeta{GenerateName: "rtb-test-s-"}}, "local", createdNamespace.Name) + require.NoError(p.T(), err) + + _, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, secret.Name, metav1.GetOptions{}) + require.Error(p.T(), err) + + rtB, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "project", + Name: "RoleB", + Rules: []management.PolicyRule{ + { + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{secret.Name}, + Verbs: []string{"get"}, + }, + }, + }) + require.NoError(p.T(), err) + + rtA, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "project", + Name: "RoleA", + RoleTemplateIDs: []string{rtB.ID}, + }) + require.NoError(p.T(), err) + + err = users.AddProjectMember(client, p.project, p.testUser, rtA.ID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "secrets", + Name: secret.Name, + Namespace: createdNamespace.Name, + }, + }) + require.NoError(p.T(), err) + + secret, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, secret.Name, metav1.GetOptions{}) + require.NoError(p.T(), err) + + err = users.RemoveProjectMember(client, p.testUser) + require.NoError(p.T(), err) + + // Test that user can get a specified secret once granted the permission to do so via a chain of + // roletemplate inheritance bounded by a PRTB. Here a chain means the permission is not directly inherited from the + // parent. + + rtC, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "project", + Name: "RoleC", + RoleTemplateIDs: []string{rtA.ID}, + }) + require.NoError(p.T(), err) + + _, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, secret.Name, metav1.GetOptions{}) + require.Error(p.T(), err) + + err = users.AddProjectMember(client, p.project, p.testUser, rtC.ID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "secrets", + Name: secret.Name, + Namespace: createdNamespace.Name, + }, + }) + require.NoError(p.T(), err) + + secret, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, secret.Name, metav1.GetOptions{}) + require.NoError(p.T(), err) + + anotherSecret, err := secrets.CreateSecretForCluster(client, &corev1.Secret{ObjectMeta: metav1.ObjectMeta{GenerateName: "rtb-test-s-"}}, p.downstreamClusterID, createdNamespace.Name) + require.NoError(p.T(), err) + + _, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, anotherSecret.Name, metav1.GetOptions{}) + require.Error(p.T(), err) + + // Test that permissions are updated when inherited roletemplate bound by PRTB is changed. + + updatedRTB := *rtB + updatedRTB.Rules = append(rtB.Rules, management.PolicyRule{ + APIGroups: []string{""}, + Resources: []string{"secrets"}, + ResourceNames: []string{anotherSecret.Name}, + Verbs: []string{"get"}, + }) + + _, err = client.Management.RoleTemplate.Update(rtB, updatedRTB) + require.NoError(p.T(), err) + + err = extauthz.WaitForAllowed(testUser, p.downstreamClusterID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "secrets", + Name: secret.Name, + Namespace: createdNamespace.Name, + }, + { + Verb: "get", + Resource: "secrets", + Name: anotherSecret.Name, + Namespace: createdNamespace.Name, + }, + }) + require.NoError(p.T(), err) + + _, err = secrets.GetSecretByName(testUser, p.downstreamClusterID, createdNamespace.Name, anotherSecret.Name, metav1.GetOptions{}) + require.NoError(p.T(), err) +} + +func (p *RTBTestSuite) TestCRTBRoleTemplateInheritance() { + subSession := p.session.NewSession() + defer subSession.Cleanup() + + client, err := p.client.WithSession(subSession) + require.NoError(p.T(), err) + + // Test that user can get a specified namespace once granted the permission to do so via roletemplate inheritance bounded + // by a CRTB. + + projectName := strings.Split(p.project.ID, ":")[1] + ns, err := extnamespaces.CreateNamespace(client, p.downstreamClusterID, projectName, namegen.AppendRandomString("testns-"), "{}", map[string]string{}, map[string]string{}) + require.NoError(p.T(), err) + + testUser, err := client.AsUser(p.testUser) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, ns.Name) + require.Error(p.T(), err) + + rtB, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "", + Name: "RoleB", + Rules: []management.PolicyRule{ + { + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + ResourceNames: []string{ns.Name}, + Verbs: []string{"get"}, + }, + }, + }) + require.NoError(p.T(), err) + + rtA, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "cluster", + Name: "RoleA", + RoleTemplateIDs: []string{rtB.ID}, + }) + require.NoError(p.T(), err) + + localCluster, err := p.client.Management.Cluster.ByID(p.downstreamClusterID) + require.NoError(p.T(), err) + + err = users.AddClusterRoleToUser(client, localCluster, p.testUser, rtA.ID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "namespaces", + Name: ns.Name, + }, + }) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, ns.Name) + require.NoError(p.T(), err) + + err = users.RemoveClusterRoleFromUser(client, p.testUser) + require.NoError(p.T(), err) + + // Test that user can get a specified namespace once granted the permission to do so via a chain of + // roletemplate inheritance bounded by a CRTB. Here a chain means the permission is not directly inherited from the + // parent. + + rtC, err := client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: "cluster", + Name: "RoleC", + RoleTemplateIDs: []string{rtA.ID}, + }) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, ns.Name) + require.Error(p.T(), err) + + err = users.AddClusterRoleToUser(client, localCluster, p.testUser, rtC.ID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "namespaces", + Name: ns.Name, + }, + }) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, ns.Name) + require.NoError(p.T(), err) + + anotherNS, err := extnamespaces.CreateNamespace(client, p.downstreamClusterID, projectName, namegen.AppendRandomString("testns-"), "{}", map[string]string{}, map[string]string{}) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, anotherNS.Name) + require.Error(p.T(), err) + + // Test that permissions are updated when inherited roletemplate bound by CRTB is changed. + + updatedRTB := *rtB + updatedRTB.Rules = append(rtB.Rules, management.PolicyRule{ + APIGroups: []string{""}, + Resources: []string{"namespaces"}, + ResourceNames: []string{anotherNS.Name}, + Verbs: []string{"get"}, + }) + + _, err = client.Management.RoleTemplate.Update(rtB, updatedRTB) + require.NoError(p.T(), err) + + err = extauthz.WaitForAllowed(testUser, p.downstreamClusterID, []*authzv1.ResourceAttributes{ + { + Verb: "get", + Resource: "namespaces", + Name: ns.Name, + }, + { + Verb: "get", + Resource: "namespaces", + Name: anotherNS.Name, + }, + }) + require.NoError(p.T(), err) + + _, err = extnamespaces.GetNamespaceByName(testUser, p.downstreamClusterID, anotherNS.Name) + require.NoError(p.T(), err) +} + +func TestRTBTestSuite(t *testing.T) { + suite.Run(t, new(RTBTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/scripts/build-integration-setup b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/scripts/build-integration-setup new file mode 100755 index 0000000..b363dac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/scripts/build-integration-setup @@ -0,0 +1,8 @@ +#!/bin/bash +set -e + +cd $(dirname $0)/.. + +# We're compiling with the tag "containers_image_openpgp" to prevent Go from attempting to build unnecessary C +# dependencies of the github.com/containers/image package we use in the setup package. +CGO_ENABLED=0 go build -tags containers_image_openpgp,integrationsetup -o bin/integrationsetup ./setup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/setup/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/setup/main.go new file mode 100644 index 0000000..0fc47b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/setup/main.go @@ -0,0 +1,118 @@ +// We're protecting this file with a build tag because it depends on github.com/containers/image which depends on C +// libraries that we can't and don't want to build unless we're going to run this integration setup program. + +package main + +import ( + "context" + "fmt" + "net" + "os" + "time" + + "github.com/creasty/defaults" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/k3d" + rancherClient "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/token" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +var ( + agentImage = os.Getenv("CATTLE_AGENT_IMAGE") +) + +const ( + k3dClusterNameBasename = "k3d-cluster" +) + +// main creates a test namespace and cluster for use in integration tests. +func main() { + rancherConfig := new(rancherClient.Config) + + ipAddress := getOutboundIP() + hostURL := fmt.Sprintf("%s:443", ipAddress.String()) + + var userToken *management.Token + logrus.Infof("CATTLE AGENT IS %s", agentImage) + err := kwait.PollUntilContextTimeout(context.TODO(), 500*time.Millisecond, 5*time.Minute, true, func(ctx context.Context) (done bool, err error) { + userToken, err = token.GenerateUserToken(&management.User{ + Username: "admin", + Password: "admin", + }, hostURL) + if err != nil { + return false, nil + } + + return true, nil + }) + + if err != nil { + logrus.Fatalf("Error with generating admin token: %v", err) + } + + clusterName := namegen.AppendRandomString(k3dClusterNameBasename) + + cleanup := true + rancherConfig.AdminToken = userToken.Token + rancherConfig.Host = hostURL + rancherConfig.Cleanup = &cleanup + rancherConfig.ClusterName = clusterName + + if err := defaults.Set(rancherConfig); err != nil { + logrus.Fatalf("error with setting up config file: %v", err) + } + + config.WriteConfig(rancherClient.ConfigurationFileKey, rancherConfig) + + testSession := session.NewSession() + + var client *rancherClient.Client + + agentSetting := &v3.Setting{} + var agentSettingResp *v1.SteveAPIObject + client, err = rancherClient.NewClient("", testSession) + if err != nil { + logrus.Fatalf("error instantiating client: %v", err) + } + + agentSettingResp, err = client.Steve.SteveType("management.cattle.io.setting").ByID("agent-image") + if err != nil { + logrus.Fatalf("error get agent-image setting: %v", err) + } + + err = v1.ConvertToK8sType(agentSettingResp.JSONResp, agentSetting) + if err != nil { + logrus.Fatalf("error converting to k8s type: %v", err) + } + agentSetting.Value = agentImage + + _, err = client.Steve.SteveType("management.cattle.io.setting").Update(agentSettingResp, agentSetting) + if err != nil { + logrus.Fatalf("error updating agent-image setting: %v", err) + } + + _, err = k3d.CreateAndImportK3DCluster(client, clusterName, agentImage, "", 1, 0, true) + if err != nil { + logrus.Fatalf("error creating and importing a k3d cluster: %v", err) + } +} + +// Get preferred outbound ip of this machine +func getOutboundIP() net.IP { + conn, err := net.Dial("udp", "8.8.8.8:80") + if err != nil { + logrus.Fatal(err) + } + defer conn.Close() + + localAddr := conn.LocalAddr().(*net.UDPAddr) + + return localAddr.IP +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/README.md new file mode 100644 index 0000000..3474525 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/README.md @@ -0,0 +1,210 @@ +Steve API Integration Tests +=========================== + +This test suite tests the steve resource listing API using secrets as the main +test resource, since they are quick to create. The suite uses three user +scenarios, one user who is a project member, one user who has access to one +namespace in the project, and one user who has access to a few resources in a +few namespaces in the project, in order to demonstrate steve's ability to +collect and return resources across multiple access partitions. There are 25 +sample secrets across 5 namespaces. Some of the sample secrets have labels or +annotations to demonstrate query parameters that use such fields. + +Users +----- + +| User | Access | +|--------|------------------------------------------------------------------------------| +| user-a | Project Owner | +| user-b | get,list for namespace test-ns-1 | +| user-c | get,list for secrets test1,test2 in namespaces test-ns-1,test-ns-2,test-ns-3 | + +Running +------- +Create a `steveapi.yaml` file like the following: + +```yaml +rancher: + host: localhost:8444 + adminToken: token-XXX:YYY +``` + +`adminToken` can be obtained by logging in as the `admin` user into Rancher, then clicking on the user icon (in the top +right corner) -> Account & API Keys -> Create API Key. Choose "No Scope" for the Scope, click Create and copy the Bearer +Token string. + +Then run as a normal go test, from your IDE or via: + +```shell +go test -count=1 -v -run TestSteveLocal +``` + +API examples +------------ + +This table is automatically generated from the output of the integration tests. If you add or update any tests, update this table by: + +1. Run the integration tests locally: + +``` +go test -count=1 -v ./tests/v2/integration/steveapi/ -run TestSteveLocal +``` + +2. Use the [included script](./make-table.sh) to validate the JSON files and update the markdown table: + +``` +cd ./tests/v2/integration/steveapi/ +./make-table.sh +``` + + +user | url | response +---|---|--- +user-a | https://rancherurl/v1/secrets | [json/user-a_none_none.json](json/user-a_none_none.json) +user-a | https://rancherurl/v1/secrets/test-ns-1 | [json/user-a_test-ns-1_none.json](json/user-a_test-ns-1_none.json) +user-a | https://rancherurl/v1/secrets/test-ns-5 | [json/user-a_test-ns-5_none.json](json/user-a_test-ns-5_none.json) +user-a | https://rancherurl/v1/secrets?labelSelector=test-label=2 | [json/user-a_none_labelSelector=test-label=2.json](json/user-a_none_labelSelector=test-label=2.json) +user-a | https://rancherurl/v1/secrets/test-ns-2?labelSelector=test-label=2 | [json/user-a_test-ns-2_labelSelector=test-label=2.json](json/user-a_test-ns-2_labelSelector=test-label=2.json) +user-a | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1 | [json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-a | https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1 | [json/user-a_none_fieldSelector=metadata.name=test1.json](json/user-a_none_fieldSelector=metadata.name=test1.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1 | [json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-a | https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1 | [json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1 | [json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json) +user-a | https://rancherurl/v1/secrets?limit=8 | [json/user-a_none_limit=8.json](json/user-a_none_limit=8.json) +user-a | https://rancherurl/v1/secrets?limit=8&continue=nondeterministictoken | [json/user-a_none_limit=8&continue=nondeterministictoken.json](json/user-a_none_limit=8&continue=nondeterministictoken.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?limit=3 | [json/user-a_test-ns-1_limit=3.json](json/user-a_test-ns-1_limit=3.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?limit=3&continue=nondeterministictoken | [json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json](json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.name=test1 | [json/user-a_none_filter=metadata.name=test1.json](json/user-a_none_filter=metadata.name=test1.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.name=test6 | [json/user-a_none_filter=metadata.name=test6.json](json/user-a_none_filter=metadata.name=test6.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1 | [json/user-a_test-ns-1_filter=metadata.name=test1.json](json/user-a_test-ns-1_filter=metadata.name=test1.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1 | [json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1 | [json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.name!=1 | [json/user-a_none_filter=metadata.name!=1.json](json/user-a_none_filter=metadata.name!=1.json) +user-a | https://rancherurl/v1/secrets?sort=metadata.name | [json/user-a_none_sort=metadata.name.json](json/user-a_none_sort=metadata.name.json) +user-a | https://rancherurl/v1/secrets?sort=-metadata.name | [json/user-a_none_sort=-metadata.name.json](json/user-a_none_sort=-metadata.name.json) +user-a | https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace | [json/user-a_none_sort=metadata.name,metadata.namespace.json](json/user-a_none_sort=metadata.name,metadata.namespace.json) +user-a | https://rancherurl/v1/secrets?sort=metadata.name,-metadata.namespace | [json/user-a_none_sort=metadata.name,-metadata.namespace.json](json/user-a_none_sort=metadata.name,-metadata.namespace.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name | [json/user-a_test-ns-1_sort=metadata.name.json](json/user-a_test-ns-1_sort=metadata.name.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name | [json/user-a_test-ns-1_sort=-metadata.name.json](json/user-a_test-ns-1_sort=-metadata.name.json) +user-a | https://rancherurl/v1/secrets?pagesize=8 | [json/user-a_none_pagesize=8.json](json/user-a_none_pagesize=8.json) +user-a | https://rancherurl/v1/secrets?pagesize=8&page=2&revision=nondeterministicint | [json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json](json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?pagesize=3 | [json/user-a_test-ns-1_pagesize=3.json](json/user-a_test-ns-1_pagesize=3.json) +user-a | https://rancherurl/v1/secrets/test-ns-1?pagesize=3&page=2&revision=nondeterministicint | [json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json](json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20 | [json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20 | [json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json) +user-a | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken | [json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json) +user-b | https://rancherurl/v1/secrets | [json/user-b_none_none.json](json/user-b_none_none.json) +user-b | https://rancherurl/v1/secrets/test-ns-1 | [json/user-b_test-ns-1_none.json](json/user-b_test-ns-1_none.json) +user-b | https://rancherurl/v1/secrets/test-ns-5 | [json/user-b_test-ns-5_none.json](json/user-b_test-ns-5_none.json) +user-b | https://rancherurl/v1/secrets?labelSelector=test-label=2 | [json/user-b_none_labelSelector=test-label=2.json](json/user-b_none_labelSelector=test-label=2.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?labelSelector=test-label=2 | [json/user-b_test-ns-1_labelSelector=test-label=2.json](json/user-b_test-ns-1_labelSelector=test-label=2.json) +user-b | https://rancherurl/v1/secrets/test-ns-2?labelSelector=test-label=2 | [json/user-b_test-ns-2_labelSelector=test-label=2.json](json/user-b_test-ns-2_labelSelector=test-label=2.json) +user-b | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1 | [json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-b | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-2 | [json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json](json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json) +user-b | https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1 | [json/user-b_none_fieldSelector=metadata.name=test1.json](json/user-b_none_fieldSelector=metadata.name=test1.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1 | [json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-b | https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1 | [json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-2 | [json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json](json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1 | [json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json) +user-b | https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.name=test1 | [json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json](json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json) +user-b | https://rancherurl/v1/secrets?limit=3 | [json/user-b_none_limit=3.json](json/user-b_none_limit=3.json) +user-b | https://rancherurl/v1/secrets?limit=3&continue=nondeterministictoken | [json/user-b_none_limit=3&continue=nondeterministictoken.json](json/user-b_none_limit=3&continue=nondeterministictoken.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?limit=3 | [json/user-b_test-ns-1_limit=3.json](json/user-b_test-ns-1_limit=3.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?limit=3&continue=nondeterministictoken | [json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json](json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json) +user-b | https://rancherurl/v1/secrets/test-ns-5?limit=3 | [json/user-b_test-ns-5_limit=3.json](json/user-b_test-ns-5_limit=3.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.name=test1 | [json/user-b_none_filter=metadata.name=test1.json](json/user-b_none_filter=metadata.name=test1.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1 | [json/user-b_test-ns-1_filter=metadata.name=test1.json](json/user-b_test-ns-1_filter=metadata.name=test1.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test6 | [json/user-b_test-ns-1_filter=metadata.name=test6.json](json/user-b_test-ns-1_filter=metadata.name=test6.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1 | [json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1 | [json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.name!=1 | [json/user-b_none_filter=metadata.name!=1.json](json/user-b_none_filter=metadata.name!=1.json) +user-b | https://rancherurl/v1/secrets?sort=metadata.name | [json/user-b_none_sort=metadata.name.json](json/user-b_none_sort=metadata.name.json) +user-b | https://rancherurl/v1/secrets?sort=-metadata.name | [json/user-b_none_sort=-metadata.name.json](json/user-b_none_sort=-metadata.name.json) +user-b | https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace | [json/user-b_none_sort=metadata.name,metadata.namespace.json](json/user-b_none_sort=metadata.name,metadata.namespace.json) +user-b | https://rancherurl/v1/secrets?sort=-metadata.name,metadata.namespace | [json/user-b_none_sort=-metadata.name,metadata.namespace.json](json/user-b_none_sort=-metadata.name,metadata.namespace.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name | [json/user-b_test-ns-1_sort=metadata.name.json](json/user-b_test-ns-1_sort=metadata.name.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name | [json/user-b_test-ns-1_sort=-metadata.name.json](json/user-b_test-ns-1_sort=-metadata.name.json) +user-b | https://rancherurl/v1/secrets/test-ns-5?sort=metadata.name | [json/user-b_test-ns-5_sort=metadata.name.json](json/user-b_test-ns-5_sort=metadata.name.json) +user-b | https://rancherurl/v1/secrets?pagesize=3 | [json/user-b_none_pagesize=3.json](json/user-b_none_pagesize=3.json) +user-b | https://rancherurl/v1/secrets?pagesize=3&page=2&revision=nondeterministicint | [json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json](json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?pagesize=3 | [json/user-b_test-ns-1_pagesize=3.json](json/user-b_test-ns-1_pagesize=3.json) +user-b | https://rancherurl/v1/secrets/test-ns-1?pagesize=3&page=2&revision=nondeterministicint | [json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json](json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json) +user-b | https://rancherurl/v1/secrets/test-ns-5?pagesize=3 | [json/user-b_test-ns-5_pagesize=3.json](json/user-b_test-ns-5_pagesize=3.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2 | [json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json](json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json) +user-b | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint | [json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json](json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json) +user-c | https://rancherurl/v1/secrets | [json/user-c_none_none.json](json/user-c_none_none.json) +user-c | https://rancherurl/v1/secrets/test-ns-1 | [json/user-c_test-ns-1_none.json](json/user-c_test-ns-1_none.json) +user-c | https://rancherurl/v1/secrets/test-ns-5 | [json/user-c_test-ns-5_none.json](json/user-c_test-ns-5_none.json) +user-c | https://rancherurl/v1/secrets?labelSelector=test-label=2 | [json/user-c_none_labelSelector=test-label=2.json](json/user-c_none_labelSelector=test-label=2.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?labelSelector=test-label=2 | [json/user-c_test-ns-1_labelSelector=test-label=2.json](json/user-c_test-ns-1_labelSelector=test-label=2.json) +user-c | https://rancherurl/v1/secrets/test-ns-5?labelSelector=test-label=2 | [json/user-c_test-ns-5_labelSelector=test-label=2.json](json/user-c_test-ns-5_labelSelector=test-label=2.json) +user-c | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1 | [json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-c | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-2 | [json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json) +user-c | https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-5 | [json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json) +user-c | https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1 | [json/user-c_none_fieldSelector=metadata.name=test1.json](json/user-c_none_fieldSelector=metadata.name=test1.json) +user-c | https://rancherurl/v1/secrets?fieldSelector=metadata.name=test5 | [json/user-c_none_fieldSelector=metadata.name=test5.json](json/user-c_none_fieldSelector=metadata.name=test5.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1 | [json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-c | https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1 | [json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-2 | [json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json](json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1 | [json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json) +user-c | https://rancherurl/v1/secrets/test-ns-5?fieldSelector=metadata.name=test1 | [json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json](json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test5 | [json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json](json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json) +user-c | https://rancherurl/v1/secrets?limit=3 | [json/user-c_none_limit=3.json](json/user-c_none_limit=3.json) +user-c | https://rancherurl/v1/secrets?limit=3&continue=nondeterministictoken | [json/user-c_none_limit=3&continue=nondeterministictoken.json](json/user-c_none_limit=3&continue=nondeterministictoken.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?limit=3 | [json/user-c_test-ns-1_limit=3.json](json/user-c_test-ns-1_limit=3.json) +user-c | https://rancherurl/v1/secrets/test-ns-5?limit=3 | [json/user-c_test-ns-5_limit=3.json](json/user-c_test-ns-5_limit=3.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.name=test1 | [json/user-c_none_filter=metadata.name=test1.json](json/user-c_none_filter=metadata.name=test1.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1 | [json/user-c_test-ns-1_filter=metadata.name=test1.json](json/user-c_test-ns-1_filter=metadata.name=test1.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test3 | [json/user-c_test-ns-1_filter=metadata.name=test3.json](json/user-c_test-ns-1_filter=metadata.name=test3.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1 | [json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.name!=test1 | [json/user-c_none_filter=metadata.name!=test1.json](json/user-c_none_filter=metadata.name!=test1.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1 | [json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json) +user-c | https://rancherurl/v1/secrets?sort=metadata.name | [json/user-c_none_sort=metadata.name.json](json/user-c_none_sort=metadata.name.json) +user-c | https://rancherurl/v1/secrets?sort=-metadata.name | [json/user-c_none_sort=-metadata.name.json](json/user-c_none_sort=-metadata.name.json) +user-c | https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace | [json/user-c_none_sort=metadata.name,metadata.namespace.json](json/user-c_none_sort=metadata.name,metadata.namespace.json) +user-c | https://rancherurl/v1/secrets?sort=metadata.name,-metadata.namespace | [json/user-c_none_sort=metadata.name,-metadata.namespace.json](json/user-c_none_sort=metadata.name,-metadata.namespace.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name | [json/user-c_test-ns-1_sort=metadata.name.json](json/user-c_test-ns-1_sort=metadata.name.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name | [json/user-c_test-ns-1_sort=-metadata.name.json](json/user-c_test-ns-1_sort=-metadata.name.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,metadata.namespace | [json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json](json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,-metadata.namespace | [json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json](json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json) +user-c | https://rancherurl/v1/secrets/test-ns-5?sort=metadata.name | [json/user-c_test-ns-5_sort=metadata.name.json](json/user-c_test-ns-5_sort=metadata.name.json) +user-c | https://rancherurl/v1/secrets?pagesize=3 | [json/user-c_none_pagesize=3.json](json/user-c_none_pagesize=3.json) +user-c | https://rancherurl/v1/secrets?pagesize=3&page=2&revision=nondeterministicint | [json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json](json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json) +user-c | https://rancherurl/v1/secrets/test-ns-1?pagesize=3 | [json/user-c_test-ns-1_pagesize=3.json](json/user-c_test-ns-1_pagesize=3.json) +user-c | https://rancherurl/v1/secrets/test-ns-5?pagesize=3 | [json/user-c_test-ns-5_pagesize=3.json](json/user-c_test-ns-5_pagesize=3.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1 | [json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json](json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json) +user-c | https://rancherurl/v1/secrets?filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint | [json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json](json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json) +user-d | https://rancherurl/v1/secrets | [json/user-d_none_none.json](json/user-d_none_none.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2 | [json/user-d_none_projectsornamespaces=test-prj-2.json](json/user-d_none_projectsornamespaces=test-prj-2.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-1,test-prj-2 | [json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json](json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1 | [json/user-d_none_projectsornamespaces=test-ns-1.json](json/user-d_none_projectsornamespaces=test-ns-1.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,test-ns-2 | [json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json](json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,test-ns-2,test-ns-3 | [json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json](json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-8,test-ns-9 | [json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json](json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1 | [json/user-d_none_projectsornamespaces!=test-prj-1.json](json/user-d_none_projectsornamespaces!=test-prj-1.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-prj-2 | [json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json) +user-d | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8 | [json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json](json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json) +user-d | https://rancherurl/v1/secrets/test-ns-6 | [json/user-d_test-ns-6_none.json](json/user-d_test-ns-6_none.json) +user-d | https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-2 | [json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json](json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json) +user-d | https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-1 | [json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json](json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json) +user-d | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7 | [json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json](json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json) +user-d | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1 | [json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json](json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json) +user-d | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-prj-2 | [json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json) +user-e | https://rancherurl/v1/secrets | [json/user-e_none_none.json](json/user-e_none_none.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2 | [json/user-e_none_projectsornamespaces=test-prj-2.json](json/user-e_none_projectsornamespaces=test-prj-2.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-1,test-prj-2 | [json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json](json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1 | [json/user-e_none_projectsornamespaces=test-ns-1.json](json/user-e_none_projectsornamespaces=test-ns-1.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,test-ns-2 | [json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json](json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,test-ns-2,test-ns-3 | [json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json](json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces=test-ns-8,test-ns-9 | [json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json](json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1 | [json/user-e_none_projectsornamespaces!=test-prj-1.json](json/user-e_none_projectsornamespaces!=test-prj-1.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-prj-2 | [json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json) +user-e | https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8 | [json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json](json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json) +user-e | https://rancherurl/v1/secrets/test-ns-6 | [json/user-e_test-ns-6_none.json](json/user-e_test-ns-6_none.json) +user-e | https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-2 | [json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json](json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json) +user-e | https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-1 | [json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json](json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json) +user-e | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7 | [json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json](json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json) +user-e | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1 | [json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json) +user-e | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-prj-2 | [json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json) +user-e | https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8 | [json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json) + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..5f06ca8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.name=test1.json @@ -0,0 +1,140 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..4d55f59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json new file mode 100644 index 0000000..2942473 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json @@ -0,0 +1,178 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 12, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026filter=metadata.labels.test-label-gte%3D3\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=20\u0026pagesize=6\u0026sort=-metadata.name", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json new file mode 100644 index 0000000..0b03108 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json @@ -0,0 +1,98 @@ +{ + "actions": {}, + "count": 3, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 1, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json new file mode 100644 index 0000000..4f7d079 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json @@ -0,0 +1,178 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 12, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026filter=metadata.labels.test-label-gte%3D3\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=20\u0026page=2\u0026pagesize=6\u0026revision=nondeterministicint\u0026sort=-metadata.name", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json new file mode 100644 index 0000000..23016a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json @@ -0,0 +1,119 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name!=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name!=1.json new file mode 100644 index 0000000..6a28881 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name!=1.json @@ -0,0 +1,535 @@ +{ + "actions": {}, + "count": 20, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json new file mode 100644 index 0000000..8f0189a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json @@ -0,0 +1,244 @@ +{ + "actions": {}, + "count": 9, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test1.json new file mode 100644 index 0000000..5f06ca8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test1.json @@ -0,0 +1,140 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test6.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test6.json new file mode 100644 index 0000000..181d404 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_filter=metadata.name=test6.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_labelSelector=test-label=2.json new file mode 100644 index 0000000..d7b705c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_labelSelector=test-label=2.json @@ -0,0 +1,145 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8&continue=nondeterministictoken.json new file mode 100644 index 0000000..b079c29 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8&continue=nondeterministictoken.json @@ -0,0 +1,227 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 8, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=8", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8.json new file mode 100644 index 0000000..def62c1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_limit=8.json @@ -0,0 +1,227 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 8, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=8", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_none.json new file mode 100644 index 0000000..959b1fc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_none.json @@ -0,0 +1,660 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..a9f83bd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json @@ -0,0 +1,222 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 4, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8.json new file mode 100644 index 0000000..27602a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_pagesize=8.json @@ -0,0 +1,222 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 4, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=-metadata.name.json new file mode 100644 index 0000000..085b13f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=-metadata.name.json @@ -0,0 +1,660 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,-metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,-metadata.namespace.json new file mode 100644 index 0000000..6fda0ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,-metadata.namespace.json @@ -0,0 +1,660 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,metadata.namespace.json new file mode 100644 index 0000000..9f8a003 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name,metadata.namespace.json @@ -0,0 +1,660 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name.json new file mode 100644 index 0000000..69183b6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_none_sort=metadata.name.json @@ -0,0 +1,660 @@ +{ + "actions": {}, + "count": 25, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..0660f1c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json @@ -0,0 +1,40 @@ +{ + "actions": {}, + "count": 1, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..4ea30f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_filter=metadata.name=test1.json new file mode 100644 index 0000000..0660f1c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_filter=metadata.name=test1.json @@ -0,0 +1,40 @@ +{ + "actions": {}, + "count": 1, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json new file mode 100644 index 0000000..c7aef1b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json @@ -0,0 +1,71 @@ +{ + "actions": {}, + "count": 2, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets/test-ns-1", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3.json new file mode 100644 index 0000000..6585ddc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_limit=3.json @@ -0,0 +1,98 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 3, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets/test-ns-1", + "next": "https://rancherurl/v1/secrets/test-ns-1?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=3", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_none.json new file mode 100644 index 0000000..4ea30f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_none.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..2222e1b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json @@ -0,0 +1,68 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3.json new file mode 100644 index 0000000..22c3744 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_pagesize=3.json @@ -0,0 +1,93 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=-metadata.name.json new file mode 100644 index 0000000..59bd5b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=-metadata.name.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=metadata.name.json new file mode 100644 index 0000000..4ea30f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-1_sort=metadata.name.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..af9d665 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_labelSelector=test-label=2.json new file mode 100644 index 0000000..1e5f378 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-2_labelSelector=test-label=2.json @@ -0,0 +1,41 @@ +{ + "actions": {}, + "count": 1, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-5_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-5_none.json new file mode 100644 index 0000000..47e7cec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-a_test-ns-5_none.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..c889a4c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..d78e29f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json new file mode 100644 index 0000000..fc66adf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..b561667 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json @@ -0,0 +1,37 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json new file mode 100644 index 0000000..e99b35b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json @@ -0,0 +1,61 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json new file mode 100644 index 0000000..479c57e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json @@ -0,0 +1,108 @@ +{ + "actions": {}, + "count": 4, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name!=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name!=1.json new file mode 100644 index 0000000..479c57e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name!=1.json @@ -0,0 +1,108 @@ +{ + "actions": {}, + "count": 4, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json new file mode 100644 index 0000000..d78e29f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=test1.json new file mode 100644 index 0000000..c889a4c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_filter=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_labelSelector=test-label=2.json new file mode 100644 index 0000000..8de2c6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_labelSelector=test-label=2.json @@ -0,0 +1,36 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3&continue=nondeterministictoken.json new file mode 100644 index 0000000..86fde97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3&continue=nondeterministictoken.json @@ -0,0 +1,64 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3.json new file mode 100644 index 0000000..616cdcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_limit=3.json @@ -0,0 +1,89 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=3", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_none.json new file mode 100644 index 0000000..d78e29f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_none.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..5950797 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json @@ -0,0 +1,61 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3.json new file mode 100644 index 0000000..7db9170 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_pagesize=3.json @@ -0,0 +1,84 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name,metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name,metadata.namespace.json new file mode 100644 index 0000000..25c6278 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name,metadata.namespace.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name.json new file mode 100644 index 0000000..25c6278 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=-metadata.name.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name,metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name,metadata.namespace.json new file mode 100644 index 0000000..d78e29f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name,metadata.namespace.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name.json new file mode 100644 index 0000000..d78e29f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_none_sort=metadata.name.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..259e081 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..2927e56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json new file mode 100644 index 0000000..06d94f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test1.json new file mode 100644 index 0000000..259e081 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test6.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test6.json new file mode 100644 index 0000000..06d94f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_filter=metadata.name=test6.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_labelSelector=test-label=2.json new file mode 100644 index 0000000..b9afbdc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_labelSelector=test-label=2.json @@ -0,0 +1,36 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json new file mode 100644 index 0000000..4a4b39e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json @@ -0,0 +1,64 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets/test-ns-1", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3.json new file mode 100644 index 0000000..de882b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_limit=3.json @@ -0,0 +1,89 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets/test-ns-1", + "next": "https://rancherurl/v1/secrets/test-ns-1?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=3", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_none.json new file mode 100644 index 0000000..2927e56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_none.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..134f402 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json @@ -0,0 +1,61 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3.json new file mode 100644 index 0000000..de2408e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_pagesize=3.json @@ -0,0 +1,84 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=-metadata.name.json new file mode 100644 index 0000000..49b5a89 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=-metadata.name.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=metadata.name.json new file mode 100644 index 0000000..2927e56 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-1_sort=metadata.name.json @@ -0,0 +1,131 @@ +{ + "actions": {}, + "count": 5, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..8b634ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..8b634ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_labelSelector=test-label=2.json new file mode 100644 index 0000000..8b634ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-2_labelSelector=test-label=2.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_limit=3.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_limit=3.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_none.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_none.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_pagesize=3.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_pagesize=3.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_sort=metadata.name.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-b_test-ns-5_sort=metadata.name.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..1fef8af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test1.json @@ -0,0 +1,81 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test5.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test5.json new file mode 100644 index 0000000..fc66adf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.name=test5.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..02e10d5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json new file mode 100644 index 0000000..a2f7d67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json new file mode 100644 index 0000000..fc66adf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json new file mode 100644 index 0000000..8de2c6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json @@ -0,0 +1,36 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name!=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name!=test1.json new file mode 100644 index 0000000..2da0ff2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name!=test1.json @@ -0,0 +1,84 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json new file mode 100644 index 0000000..9a935f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json @@ -0,0 +1,105 @@ +{ + "actions": {}, + "count": 4, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=test1.json new file mode 100644 index 0000000..1fef8af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.name=test1.json @@ -0,0 +1,81 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..5ce221c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json @@ -0,0 +1,36 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json new file mode 100644 index 0000000..f44bb93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json @@ -0,0 +1,37 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_labelSelector=test-label=2.json new file mode 100644 index 0000000..2da0ff2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_labelSelector=test-label=2.json @@ -0,0 +1,84 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3&continue=nondeterministictoken.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3&continue=nondeterministictoken.json new file mode 100644 index 0000000..88b9dca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3&continue=nondeterministictoken.json @@ -0,0 +1,87 @@ +{ + "actions": {}, + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3.json new file mode 100644 index 0000000..98546ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_limit=3.json @@ -0,0 +1,88 @@ +{ + "actions": {}, + "continue": "nondeterministictoken", + "count": 3, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pagination": { + "first": "https://rancherurl/v1/secrets", + "next": "https://rancherurl/v1/secrets?continue=nondeterministictoken\u0026labelSelector=test.cattle.io%2Fsteveapi%3Dnondeterministicid\u0026limit=3", + "partial": true + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_none.json new file mode 100644 index 0000000..118c3f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_none.json @@ -0,0 +1,153 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json new file mode 100644 index 0000000..187230c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json @@ -0,0 +1,84 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3.json new file mode 100644 index 0000000..2f65986 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_pagesize=3.json @@ -0,0 +1,83 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "pages": 2, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=-metadata.name.json new file mode 100644 index 0000000..ea498f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=-metadata.name.json @@ -0,0 +1,153 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,-metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,-metadata.namespace.json new file mode 100644 index 0000000..65dbf63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,-metadata.namespace.json @@ -0,0 +1,153 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,metadata.namespace.json new file mode 100644 index 0000000..fae7fa5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name,metadata.namespace.json @@ -0,0 +1,153 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name.json new file mode 100644 index 0000000..fae7fa5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_none_sort=metadata.name.json @@ -0,0 +1,153 @@ +{ + "actions": {}, + "count": 6, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..259e081 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json new file mode 100644 index 0000000..06d94f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json new file mode 100644 index 0000000..06d94f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test1.json new file mode 100644 index 0000000..259e081 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test1.json @@ -0,0 +1,35 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test3.json new file mode 100644 index 0000000..06d94f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_filter=metadata.name=test3.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_labelSelector=test-label=2.json new file mode 100644 index 0000000..b9afbdc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_labelSelector=test-label=2.json @@ -0,0 +1,36 @@ +{ + "actions": {}, + "count": 1, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_limit=3.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_limit=3.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_none.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_none.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_pagesize=3.json new file mode 100644 index 0000000..877627c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_pagesize=3.json @@ -0,0 +1,60 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "pages": 1, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=-metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=-metadata.name.json new file mode 100644 index 0000000..f815612 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=-metadata.name.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name.json new file mode 100644 index 0000000..a30d291 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-1_sort=metadata.name.json @@ -0,0 +1,59 @@ +{ + "actions": {}, + "count": 2, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json new file mode 100644 index 0000000..8b634ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-2" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_labelSelector=test-label=2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_labelSelector=test-label=2.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_labelSelector=test-label=2.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_limit=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_limit=3.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_limit=3.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_none.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_none.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_pagesize=3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_pagesize=3.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_pagesize=3.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_sort=metadata.name.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_sort=metadata.name.json new file mode 100644 index 0000000..53fc392 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-c_test-ns-5_sort=metadata.name.json @@ -0,0 +1,9 @@ +{ + "actions": {}, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-5" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_none.json new file mode 100644 index 0000000..7b1e4c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_none.json @@ -0,0 +1,864 @@ +{ + "actions": {}, + "count": 33, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json new file mode 100644 index 0000000..dde4490 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..0307b47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1.json new file mode 100644 index 0000000..03eddaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces!=test-prj-1.json @@ -0,0 +1,219 @@ +{ + "actions": {}, + "count": 8, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json new file mode 100644 index 0000000..442554c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json @@ -0,0 +1,273 @@ +{ + "actions": {}, + "count": 10, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1.json new file mode 100644 index 0000000..4d55f59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-1.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json new file mode 100644 index 0000000..0307b47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..b4446cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json @@ -0,0 +1,762 @@ +{ + "actions": {}, + "count": 29, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json new file mode 100644 index 0000000..81a8394 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json @@ -0,0 +1,375 @@ +{ + "actions": {}, + "count": 14, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2.json new file mode 100644 index 0000000..223e429 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_none_projectsornamespaces=test-prj-2.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..a9a034b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json new file mode 100644 index 0000000..a9a034b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json new file mode 100644 index 0000000..4ea30f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_none.json new file mode 100644 index 0000000..769f8b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_none.json @@ -0,0 +1,66 @@ +{ + "actions": {}, + "count": 2, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json new file mode 100644 index 0000000..f2c9598 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json new file mode 100644 index 0000000..769f8b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json @@ -0,0 +1,66 @@ +{ + "actions": {}, + "count": 2, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_none.json new file mode 100644 index 0000000..7b1e4c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_none.json @@ -0,0 +1,864 @@ +{ + "actions": {}, + "count": 33, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json new file mode 100644 index 0000000..dde4490 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..0307b47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1.json new file mode 100644 index 0000000..03eddaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces!=test-prj-1.json @@ -0,0 +1,219 @@ +{ + "actions": {}, + "count": 8, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json new file mode 100644 index 0000000..442554c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json @@ -0,0 +1,273 @@ +{ + "actions": {}, + "count": 10, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1.json new file mode 100644 index 0000000..4d55f59 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-1.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json new file mode 100644 index 0000000..0307b47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test1", + "self": "https://rancherurl/v1/secrets/test-ns-8/test1", + "update": "https://rancherurl/v1/secrets/test-ns-8/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-8/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-8/test2", + "self": "https://rancherurl/v1/secrets/test-ns-8/test2", + "update": "https://rancherurl/v1/secrets/test-ns-8/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-8/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-8", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test1", + "self": "https://rancherurl/v1/secrets/test-ns-9/test1", + "update": "https://rancherurl/v1/secrets/test-ns-9/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-9/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-9/test2", + "self": "https://rancherurl/v1/secrets/test-ns-9/test2", + "update": "https://rancherurl/v1/secrets/test-ns-9/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-9/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-9", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..b4446cc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json @@ -0,0 +1,762 @@ +{ + "actions": {}, + "count": 29, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test1", + "self": "https://rancherurl/v1/secrets/test-ns-4/test1", + "update": "https://rancherurl/v1/secrets/test-ns-4/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test2", + "self": "https://rancherurl/v1/secrets/test-ns-4/test2", + "update": "https://rancherurl/v1/secrets/test-ns-4/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test3", + "self": "https://rancherurl/v1/secrets/test-ns-4/test3", + "update": "https://rancherurl/v1/secrets/test-ns-4/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test4", + "self": "https://rancherurl/v1/secrets/test-ns-4/test4", + "update": "https://rancherurl/v1/secrets/test-ns-4/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-4/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-4/test5", + "self": "https://rancherurl/v1/secrets/test-ns-4/test5", + "update": "https://rancherurl/v1/secrets/test-ns-4/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-4/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-4", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test1", + "self": "https://rancherurl/v1/secrets/test-ns-5/test1", + "update": "https://rancherurl/v1/secrets/test-ns-5/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test2", + "self": "https://rancherurl/v1/secrets/test-ns-5/test2", + "update": "https://rancherurl/v1/secrets/test-ns-5/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test3", + "self": "https://rancherurl/v1/secrets/test-ns-5/test3", + "update": "https://rancherurl/v1/secrets/test-ns-5/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test4", + "self": "https://rancherurl/v1/secrets/test-ns-5/test4", + "update": "https://rancherurl/v1/secrets/test-ns-5/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-5/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-5/test5", + "self": "https://rancherurl/v1/secrets/test-ns-5/test5", + "update": "https://rancherurl/v1/secrets/test-ns-5/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-5/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-5", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json new file mode 100644 index 0000000..81a8394 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json @@ -0,0 +1,375 @@ +{ + "actions": {}, + "count": 14, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test1", + "self": "https://rancherurl/v1/secrets/test-ns-2/test1", + "update": "https://rancherurl/v1/secrets/test-ns-2/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test2", + "self": "https://rancherurl/v1/secrets/test-ns-2/test2", + "update": "https://rancherurl/v1/secrets/test-ns-2/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test3", + "self": "https://rancherurl/v1/secrets/test-ns-2/test3", + "update": "https://rancherurl/v1/secrets/test-ns-2/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test4", + "self": "https://rancherurl/v1/secrets/test-ns-2/test4", + "update": "https://rancherurl/v1/secrets/test-ns-2/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-2/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-2/test5", + "self": "https://rancherurl/v1/secrets/test-ns-2/test5", + "update": "https://rancherurl/v1/secrets/test-ns-2/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-2/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-2", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test1", + "self": "https://rancherurl/v1/secrets/test-ns-3/test1", + "update": "https://rancherurl/v1/secrets/test-ns-3/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test2", + "self": "https://rancherurl/v1/secrets/test-ns-3/test2", + "update": "https://rancherurl/v1/secrets/test-ns-3/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test3", + "self": "https://rancherurl/v1/secrets/test-ns-3/test3", + "update": "https://rancherurl/v1/secrets/test-ns-3/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test4", + "self": "https://rancherurl/v1/secrets/test-ns-3/test4", + "update": "https://rancherurl/v1/secrets/test-ns-3/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-3/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-3/test5", + "self": "https://rancherurl/v1/secrets/test-ns-3/test5", + "update": "https://rancherurl/v1/secrets/test-ns-3/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-3/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-3", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2.json new file mode 100644 index 0000000..223e429 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_none_projectsornamespaces=test-prj-2.json @@ -0,0 +1,117 @@ +{ + "actions": {}, + "count": 4, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test1", + "self": "https://rancherurl/v1/secrets/test-ns-7/test1", + "update": "https://rancherurl/v1/secrets/test-ns-7/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-7/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-7/test2", + "self": "https://rancherurl/v1/secrets/test-ns-7/test2", + "update": "https://rancherurl/v1/secrets/test-ns-7/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-7/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-7", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json new file mode 100644 index 0000000..a9a034b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json new file mode 100644 index 0000000..a9a034b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json new file mode 100644 index 0000000..a9a034b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json new file mode 100644 index 0000000..4ea30f9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json @@ -0,0 +1,144 @@ +{ + "actions": {}, + "count": 5, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test1", + "self": "https://rancherurl/v1/secrets/test-ns-1/test1", + "update": "https://rancherurl/v1/secrets/test-ns-1/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test2", + "self": "https://rancherurl/v1/secrets/test-ns-1/test2", + "update": "https://rancherurl/v1/secrets/test-ns-1/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test3", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test3", + "self": "https://rancherurl/v1/secrets/test-ns-1/test3", + "update": "https://rancherurl/v1/secrets/test-ns-1/test3", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test3" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test3", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test4", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test4", + "self": "https://rancherurl/v1/secrets/test-ns-1/test4", + "update": "https://rancherurl/v1/secrets/test-ns-1/test4", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test4" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test4", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-1/test5", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-1/test5", + "self": "https://rancherurl/v1/secrets/test-ns-1/test5", + "update": "https://rancherurl/v1/secrets/test-ns-1/test5", + "view": "https://rancherurl/api/v1/namespaces/test-ns-1/secrets/test5" + }, + "metadata": { + "labels": { + "test-label-gte": "3", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test5", + "namespace": "test-ns-1", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-1" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_none.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_none.json new file mode 100644 index 0000000..769f8b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_none.json @@ -0,0 +1,66 @@ +{ + "actions": {}, + "count": 2, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json new file mode 100644 index 0000000..f2c9598 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json @@ -0,0 +1,12 @@ +{ + "actions": {}, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json new file mode 100644 index 0000000..769f8b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json @@ -0,0 +1,66 @@ +{ + "actions": {}, + "count": 2, + "createTypes": { + "secret": "https://rancherurl/v1/secrets" + }, + "data": [ + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test1", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test1", + "self": "https://rancherurl/v1/secrets/test-ns-6/test1", + "update": "https://rancherurl/v1/secrets/test-ns-6/test1", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test1" + }, + "metadata": { + "labels": { + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test1", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + }, + { + "actions": null, + "apiVersion": "v1", + "id": "test-ns-6/test2", + "kind": "Secret", + "links": { + "remove": "https://rancherurl/v1/secrets/test-ns-6/test2", + "self": "https://rancherurl/v1/secrets/test-ns-6/test2", + "update": "https://rancherurl/v1/secrets/test-ns-6/test2", + "view": "https://rancherurl/api/v1/namespaces/test-ns-6/secrets/test2" + }, + "metadata": { + "labels": { + "test-label": "2", + "test.cattle.io/steveapi": "nondeterministicid" + }, + "name": "test2", + "namespace": "test-ns-6", + "resourceVersion": "1000", + "state": { + "message": "Resource is always ready", + "name": "active" + } + }, + "type": "secret" + } + ], + "links": { + "self": "https://rancherurl/v1/secrets/test-ns-6" + }, + "resourceType": "secret", + "revision": "100", + "type": "collection" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/make-table.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/make-table.sh new file mode 100755 index 0000000..c0ab083 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/make-table.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +command -v csv2md >/dev/null || { echo "Install csv2md with 'npm install -g csv2md'"; exit 1; } +command -v jq >/dev/null || { echo "Install jq"; exit 1; } + +for j in json/* ; do + jq . $j >/dev/null + if [ $? -ne 0 ] ; then + echo "INVALID JSON IN FILE $j" + exit 1 + fi +done + +sed -i -e '/INSERT TABLE HERE/q' README.md +csv2md output.csv >> README.md diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/output.csv b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/output.csv new file mode 100644 index 0000000..4f11c8f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/output.csv @@ -0,0 +1,148 @@ +user,url,response +user-a,https://rancherurl/v1/secrets,[json/user-a_none_none.json](json/user-a_none_none.json) +user-a,https://rancherurl/v1/secrets/test-ns-1,[json/user-a_test-ns-1_none.json](json/user-a_test-ns-1_none.json) +user-a,https://rancherurl/v1/secrets/test-ns-5,[json/user-a_test-ns-5_none.json](json/user-a_test-ns-5_none.json) +user-a,https://rancherurl/v1/secrets?labelSelector=test-label=2,[json/user-a_none_labelSelector=test-label=2.json](json/user-a_none_labelSelector=test-label=2.json) +user-a,https://rancherurl/v1/secrets/test-ns-2?labelSelector=test-label=2,[json/user-a_test-ns-2_labelSelector=test-label=2.json](json/user-a_test-ns-2_labelSelector=test-label=2.json) +user-a,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1,[json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-a,https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1,[json/user-a_none_fieldSelector=metadata.name=test1.json](json/user-a_none_fieldSelector=metadata.name=test1.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1,[json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-a,https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1,[json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-a_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1,[json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-a_test-ns-1_fieldSelector=metadata.name=test1.json) +user-a,https://rancherurl/v1/secrets?limit=8,[json/user-a_none_limit=8.json](json/user-a_none_limit=8.json) +user-a,https://rancherurl/v1/secrets?limit=8&continue=nondeterministictoken,[json/user-a_none_limit=8&continue=nondeterministictoken.json](json/user-a_none_limit=8&continue=nondeterministictoken.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?limit=3,[json/user-a_test-ns-1_limit=3.json](json/user-a_test-ns-1_limit=3.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?limit=3&continue=nondeterministictoken,[json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json](json/user-a_test-ns-1_limit=3&continue=nondeterministictoken.json) +user-a,https://rancherurl/v1/secrets?filter=metadata.name=test1,[json/user-a_none_filter=metadata.name=test1.json](json/user-a_none_filter=metadata.name=test1.json) +user-a,https://rancherurl/v1/secrets?filter=metadata.name=test6,[json/user-a_none_filter=metadata.name=test6.json](json/user-a_none_filter=metadata.name=test6.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1,[json/user-a_test-ns-1_filter=metadata.name=test1.json](json/user-a_test-ns-1_filter=metadata.name=test1.json) +user-a,"https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1","[json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-a_none_filter=metadata.name=1,metadata.namespace=1.json)" +user-a,"https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1","[json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-a_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json)" +user-a,https://rancherurl/v1/secrets?filter=metadata.name!=1,[json/user-a_none_filter=metadata.name!=1.json](json/user-a_none_filter=metadata.name!=1.json) +user-a,https://rancherurl/v1/secrets?sort=metadata.name,[json/user-a_none_sort=metadata.name.json](json/user-a_none_sort=metadata.name.json) +user-a,https://rancherurl/v1/secrets?sort=-metadata.name,[json/user-a_none_sort=-metadata.name.json](json/user-a_none_sort=-metadata.name.json) +user-a,"https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace","[json/user-a_none_sort=metadata.name,metadata.namespace.json](json/user-a_none_sort=metadata.name,metadata.namespace.json)" +user-a,"https://rancherurl/v1/secrets?sort=metadata.name,-metadata.namespace","[json/user-a_none_sort=metadata.name,-metadata.namespace.json](json/user-a_none_sort=metadata.name,-metadata.namespace.json)" +user-a,https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,[json/user-a_test-ns-1_sort=metadata.name.json](json/user-a_test-ns-1_sort=metadata.name.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name,[json/user-a_test-ns-1_sort=-metadata.name.json](json/user-a_test-ns-1_sort=-metadata.name.json) +user-a,https://rancherurl/v1/secrets?pagesize=8,[json/user-a_none_pagesize=8.json](json/user-a_none_pagesize=8.json) +user-a,https://rancherurl/v1/secrets?pagesize=8&page=2&revision=nondeterministicint,[json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json](json/user-a_none_pagesize=8&page=2&revision=nondeterministicint.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?pagesize=3,[json/user-a_test-ns-1_pagesize=3.json](json/user-a_test-ns-1_pagesize=3.json) +user-a,https://rancherurl/v1/secrets/test-ns-1?pagesize=3&page=2&revision=nondeterministicint,[json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json](json/user-a_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json) +user-a,https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20,[json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20.json) +user-a,https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20,[json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=nondeterministicint&limit=20.json) +user-a,https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken,[json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json](json/user-a_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=nondeterministictoken.json) +user-b,https://rancherurl/v1/secrets,[json/user-b_none_none.json](json/user-b_none_none.json) +user-b,https://rancherurl/v1/secrets/test-ns-1,[json/user-b_test-ns-1_none.json](json/user-b_test-ns-1_none.json) +user-b,https://rancherurl/v1/secrets/test-ns-5,[json/user-b_test-ns-5_none.json](json/user-b_test-ns-5_none.json) +user-b,https://rancherurl/v1/secrets?labelSelector=test-label=2,[json/user-b_none_labelSelector=test-label=2.json](json/user-b_none_labelSelector=test-label=2.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?labelSelector=test-label=2,[json/user-b_test-ns-1_labelSelector=test-label=2.json](json/user-b_test-ns-1_labelSelector=test-label=2.json) +user-b,https://rancherurl/v1/secrets/test-ns-2?labelSelector=test-label=2,[json/user-b_test-ns-2_labelSelector=test-label=2.json](json/user-b_test-ns-2_labelSelector=test-label=2.json) +user-b,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1,[json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-b,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-2,[json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json](json/user-b_none_fieldSelector=metadata.namespace=test-ns-2.json) +user-b,https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1,[json/user-b_none_fieldSelector=metadata.name=test1.json](json/user-b_none_fieldSelector=metadata.name=test1.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1,[json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-b,https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1,[json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-b_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-2,[json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json](json/user-b_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1,[json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-b_test-ns-1_fieldSelector=metadata.name=test1.json) +user-b,https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.name=test1,[json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json](json/user-b_test-ns-2_fieldSelector=metadata.name=test1.json) +user-b,https://rancherurl/v1/secrets?limit=3,[json/user-b_none_limit=3.json](json/user-b_none_limit=3.json) +user-b,https://rancherurl/v1/secrets?limit=3&continue=nondeterministictoken,[json/user-b_none_limit=3&continue=nondeterministictoken.json](json/user-b_none_limit=3&continue=nondeterministictoken.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?limit=3,[json/user-b_test-ns-1_limit=3.json](json/user-b_test-ns-1_limit=3.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?limit=3&continue=nondeterministictoken,[json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json](json/user-b_test-ns-1_limit=3&continue=nondeterministictoken.json) +user-b,https://rancherurl/v1/secrets/test-ns-5?limit=3,[json/user-b_test-ns-5_limit=3.json](json/user-b_test-ns-5_limit=3.json) +user-b,https://rancherurl/v1/secrets?filter=metadata.name=test1,[json/user-b_none_filter=metadata.name=test1.json](json/user-b_none_filter=metadata.name=test1.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1,[json/user-b_test-ns-1_filter=metadata.name=test1.json](json/user-b_test-ns-1_filter=metadata.name=test1.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test6,[json/user-b_test-ns-1_filter=metadata.name=test6.json](json/user-b_test-ns-1_filter=metadata.name=test6.json) +user-b,"https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1","[json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-b_none_filter=metadata.name=1,metadata.namespace=1.json)" +user-b,"https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1","[json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-b_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json)" +user-b,https://rancherurl/v1/secrets?filter=metadata.name!=1,[json/user-b_none_filter=metadata.name!=1.json](json/user-b_none_filter=metadata.name!=1.json) +user-b,https://rancherurl/v1/secrets?sort=metadata.name,[json/user-b_none_sort=metadata.name.json](json/user-b_none_sort=metadata.name.json) +user-b,https://rancherurl/v1/secrets?sort=-metadata.name,[json/user-b_none_sort=-metadata.name.json](json/user-b_none_sort=-metadata.name.json) +user-b,"https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace","[json/user-b_none_sort=metadata.name,metadata.namespace.json](json/user-b_none_sort=metadata.name,metadata.namespace.json)" +user-b,"https://rancherurl/v1/secrets?sort=-metadata.name,metadata.namespace","[json/user-b_none_sort=-metadata.name,metadata.namespace.json](json/user-b_none_sort=-metadata.name,metadata.namespace.json)" +user-b,https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,[json/user-b_test-ns-1_sort=metadata.name.json](json/user-b_test-ns-1_sort=metadata.name.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name,[json/user-b_test-ns-1_sort=-metadata.name.json](json/user-b_test-ns-1_sort=-metadata.name.json) +user-b,https://rancherurl/v1/secrets/test-ns-5?sort=metadata.name,[json/user-b_test-ns-5_sort=metadata.name.json](json/user-b_test-ns-5_sort=metadata.name.json) +user-b,https://rancherurl/v1/secrets?pagesize=3,[json/user-b_none_pagesize=3.json](json/user-b_none_pagesize=3.json) +user-b,https://rancherurl/v1/secrets?pagesize=3&page=2&revision=nondeterministicint,[json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json](json/user-b_none_pagesize=3&page=2&revision=nondeterministicint.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?pagesize=3,[json/user-b_test-ns-1_pagesize=3.json](json/user-b_test-ns-1_pagesize=3.json) +user-b,https://rancherurl/v1/secrets/test-ns-1?pagesize=3&page=2&revision=nondeterministicint,[json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json](json/user-b_test-ns-1_pagesize=3&page=2&revision=nondeterministicint.json) +user-b,https://rancherurl/v1/secrets/test-ns-5?pagesize=3,[json/user-b_test-ns-5_pagesize=3.json](json/user-b_test-ns-5_pagesize=3.json) +user-b,https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2,[json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json](json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2.json) +user-b,https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint,[json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json](json/user-b_none_filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=nondeterministicint.json) +user-c,https://rancherurl/v1/secrets,[json/user-c_none_none.json](json/user-c_none_none.json) +user-c,https://rancherurl/v1/secrets/test-ns-1,[json/user-c_test-ns-1_none.json](json/user-c_test-ns-1_none.json) +user-c,https://rancherurl/v1/secrets/test-ns-5,[json/user-c_test-ns-5_none.json](json/user-c_test-ns-5_none.json) +user-c,https://rancherurl/v1/secrets?labelSelector=test-label=2,[json/user-c_none_labelSelector=test-label=2.json](json/user-c_none_labelSelector=test-label=2.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?labelSelector=test-label=2,[json/user-c_test-ns-1_labelSelector=test-label=2.json](json/user-c_test-ns-1_labelSelector=test-label=2.json) +user-c,https://rancherurl/v1/secrets/test-ns-5?labelSelector=test-label=2,[json/user-c_test-ns-5_labelSelector=test-label=2.json](json/user-c_test-ns-5_labelSelector=test-label=2.json) +user-c,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-1,[json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-1.json) +user-c,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-2,[json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-2.json) +user-c,https://rancherurl/v1/secrets?fieldSelector=metadata.namespace=test-ns-5,[json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json](json/user-c_none_fieldSelector=metadata.namespace=test-ns-5.json) +user-c,https://rancherurl/v1/secrets?fieldSelector=metadata.name=test1,[json/user-c_none_fieldSelector=metadata.name=test1.json](json/user-c_none_fieldSelector=metadata.name=test1.json) +user-c,https://rancherurl/v1/secrets?fieldSelector=metadata.name=test5,[json/user-c_none_fieldSelector=metadata.name=test5.json](json/user-c_none_fieldSelector=metadata.name=test5.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-1,[json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-1.json) +user-c,https://rancherurl/v1/secrets/test-ns-2?fieldSelector=metadata.namespace=test-ns-1,[json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json](json/user-c_test-ns-2_fieldSelector=metadata.namespace=test-ns-1.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.namespace=test-ns-2,[json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json](json/user-c_test-ns-1_fieldSelector=metadata.namespace=test-ns-2.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test1,[json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json](json/user-c_test-ns-1_fieldSelector=metadata.name=test1.json) +user-c,https://rancherurl/v1/secrets/test-ns-5?fieldSelector=metadata.name=test1,[json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json](json/user-c_test-ns-5_fieldSelector=metadata.name=test1.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?fieldSelector=metadata.name=test5,[json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json](json/user-c_test-ns-1_fieldSelector=metadata.name=test5.json) +user-c,https://rancherurl/v1/secrets?limit=3,[json/user-c_none_limit=3.json](json/user-c_none_limit=3.json) +user-c,https://rancherurl/v1/secrets?limit=3&continue=nondeterministictoken,[json/user-c_none_limit=3&continue=nondeterministictoken.json](json/user-c_none_limit=3&continue=nondeterministictoken.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?limit=3,[json/user-c_test-ns-1_limit=3.json](json/user-c_test-ns-1_limit=3.json) +user-c,https://rancherurl/v1/secrets/test-ns-5?limit=3,[json/user-c_test-ns-5_limit=3.json](json/user-c_test-ns-5_limit=3.json) +user-c,https://rancherurl/v1/secrets?filter=metadata.name=test1,[json/user-c_none_filter=metadata.name=test1.json](json/user-c_none_filter=metadata.name=test1.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test1,[json/user-c_test-ns-1_filter=metadata.name=test1.json](json/user-c_test-ns-1_filter=metadata.name=test1.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?filter=metadata.name=test3,[json/user-c_test-ns-1_filter=metadata.name=test3.json](json/user-c_test-ns-1_filter=metadata.name=test3.json) +user-c,"https://rancherurl/v1/secrets?filter=metadata.name=1,metadata.namespace=1","[json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json](json/user-c_none_filter=metadata.name=1,metadata.namespace=1.json)" +user-c,https://rancherurl/v1/secrets?filter=metadata.name!=test1,[json/user-c_none_filter=metadata.name!=test1.json](json/user-c_none_filter=metadata.name!=test1.json) +user-c,"https://rancherurl/v1/secrets?filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1","[json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json](json/user-c_none_filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1.json)" +user-c,https://rancherurl/v1/secrets?sort=metadata.name,[json/user-c_none_sort=metadata.name.json](json/user-c_none_sort=metadata.name.json) +user-c,https://rancherurl/v1/secrets?sort=-metadata.name,[json/user-c_none_sort=-metadata.name.json](json/user-c_none_sort=-metadata.name.json) +user-c,"https://rancherurl/v1/secrets?sort=metadata.name,metadata.namespace","[json/user-c_none_sort=metadata.name,metadata.namespace.json](json/user-c_none_sort=metadata.name,metadata.namespace.json)" +user-c,"https://rancherurl/v1/secrets?sort=metadata.name,-metadata.namespace","[json/user-c_none_sort=metadata.name,-metadata.namespace.json](json/user-c_none_sort=metadata.name,-metadata.namespace.json)" +user-c,https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,[json/user-c_test-ns-1_sort=metadata.name.json](json/user-c_test-ns-1_sort=metadata.name.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?sort=-metadata.name,[json/user-c_test-ns-1_sort=-metadata.name.json](json/user-c_test-ns-1_sort=-metadata.name.json) +user-c,"https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,metadata.namespace","[json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json](json/user-c_test-ns-1_sort=metadata.name,metadata.namespace.json)" +user-c,"https://rancherurl/v1/secrets/test-ns-1?sort=metadata.name,-metadata.namespace","[json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json](json/user-c_test-ns-1_sort=metadata.name,-metadata.namespace.json)" +user-c,https://rancherurl/v1/secrets/test-ns-5?sort=metadata.name,[json/user-c_test-ns-5_sort=metadata.name.json](json/user-c_test-ns-5_sort=metadata.name.json) +user-c,https://rancherurl/v1/secrets?pagesize=3,[json/user-c_none_pagesize=3.json](json/user-c_none_pagesize=3.json) +user-c,https://rancherurl/v1/secrets?pagesize=3&page=2&revision=nondeterministicint,[json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json](json/user-c_none_pagesize=3&page=2&revision=nondeterministicint.json) +user-c,https://rancherurl/v1/secrets/test-ns-1?pagesize=3,[json/user-c_test-ns-1_pagesize=3.json](json/user-c_test-ns-1_pagesize=3.json) +user-c,https://rancherurl/v1/secrets/test-ns-5?pagesize=3,[json/user-c_test-ns-5_pagesize=3.json](json/user-c_test-ns-5_pagesize=3.json) +user-c,https://rancherurl/v1/secrets?filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1,[json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json](json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1.json) +user-c,https://rancherurl/v1/secrets?filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint,[json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json](json/user-c_none_filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=nondeterministicint.json) +user-d,https://rancherurl/v1/secrets,[json/user-d_none_none.json](json/user-d_none_none.json) +user-d,https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,[json/user-d_none_projectsornamespaces=test-prj-2.json](json/user-d_none_projectsornamespaces=test-prj-2.json) +user-d,"https://rancherurl/v1/secrets?projectsornamespaces=test-prj-1,test-prj-2","[json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json](json/user-d_none_projectsornamespaces=test-prj-1,test-prj-2.json)" +user-d,https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,[json/user-d_none_projectsornamespaces=test-ns-1.json](json/user-d_none_projectsornamespaces=test-ns-1.json) +user-d,"https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,test-ns-2","[json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json](json/user-d_none_projectsornamespaces=test-ns-1,test-ns-2.json)" +user-d,"https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,test-ns-2,test-ns-3","[json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json](json/user-d_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json)" +user-d,"https://rancherurl/v1/secrets?projectsornamespaces=test-ns-8,test-ns-9","[json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json](json/user-d_none_projectsornamespaces=test-ns-8,test-ns-9.json)" +user-d,https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,[json/user-d_none_projectsornamespaces!=test-prj-1.json](json/user-d_none_projectsornamespaces!=test-prj-1.json) +user-d,"https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-prj-2","[json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-d_none_projectsornamespaces!=test-prj-1,test-prj-2.json)" +user-d,"https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8","[json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json](json/user-d_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json)" +user-d,https://rancherurl/v1/secrets/test-ns-6,[json/user-d_test-ns-6_none.json](json/user-d_test-ns-6_none.json) +user-d,https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-2,[json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json](json/user-d_test-ns-6_projectsornamespaces=test-prj-2.json) +user-d,https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-1,[json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json](json/user-d_test-ns-6_projectsornamespaces=test-prj-1.json) +user-d,"https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7","[json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json](json/user-d_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json)" +user-d,https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,[json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json](json/user-d_test-ns-1_projectsornamespaces!=test-prj-1.json) +user-d,"https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-prj-2","[json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-d_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json)" +user-e,https://rancherurl/v1/secrets,[json/user-e_none_none.json](json/user-e_none_none.json) +user-e,https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,[json/user-e_none_projectsornamespaces=test-prj-2.json](json/user-e_none_projectsornamespaces=test-prj-2.json) +user-e,"https://rancherurl/v1/secrets?projectsornamespaces=test-prj-1,test-prj-2","[json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json](json/user-e_none_projectsornamespaces=test-prj-1,test-prj-2.json)" +user-e,https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,[json/user-e_none_projectsornamespaces=test-ns-1.json](json/user-e_none_projectsornamespaces=test-ns-1.json) +user-e,"https://rancherurl/v1/secrets?projectsornamespaces=test-ns-1,test-ns-2","[json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json](json/user-e_none_projectsornamespaces=test-ns-1,test-ns-2.json)" +user-e,"https://rancherurl/v1/secrets?projectsornamespaces=test-prj-2,test-ns-2,test-ns-3","[json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json](json/user-e_none_projectsornamespaces=test-prj-2,test-ns-2,test-ns-3.json)" +user-e,"https://rancherurl/v1/secrets?projectsornamespaces=test-ns-8,test-ns-9","[json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json](json/user-e_none_projectsornamespaces=test-ns-8,test-ns-9.json)" +user-e,https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,[json/user-e_none_projectsornamespaces!=test-prj-1.json](json/user-e_none_projectsornamespaces!=test-prj-1.json) +user-e,"https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-prj-2","[json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-e_none_projectsornamespaces!=test-prj-1,test-prj-2.json)" +user-e,"https://rancherurl/v1/secrets?projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8","[json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json](json/user-e_none_projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8.json)" +user-e,https://rancherurl/v1/secrets/test-ns-6,[json/user-e_test-ns-6_none.json](json/user-e_test-ns-6_none.json) +user-e,https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-2,[json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json](json/user-e_test-ns-6_projectsornamespaces=test-prj-2.json) +user-e,https://rancherurl/v1/secrets/test-ns-6?projectsornamespaces=test-prj-1,[json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json](json/user-e_test-ns-6_projectsornamespaces=test-prj-1.json) +user-e,"https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7","[json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json](json/user-e_test-ns-1_projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7.json)" +user-e,https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,[json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1.json) +user-e,"https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-prj-2","[json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-prj-2.json)" +user-e,"https://rancherurl/v1/secrets/test-ns-1?projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8","[json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json](json/user-e_test-ns-1_projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8.json)" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/steve_api_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/steve_api_test.go new file mode 100644 index 0000000..5e516a9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/integration/steveapi/steve_api_test.go @@ -0,0 +1,2694 @@ +package integration + +import ( + "bufio" + "context" + "encoding/csv" + "encoding/json" + "fmt" + "net/url" + "os" + "path/filepath" + "regexp" + "strings" + "testing" + "time" + + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + clientv1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + kubenamespaces "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + "github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/kubeapi/secrets" + "github.com/rancher/shepherd/extensions/namespaces" + stevesecrets "github.com/rancher/shepherd/extensions/secrets" + "github.com/rancher/shepherd/extensions/serviceaccounts" + "github.com/rancher/shepherd/extensions/unstructured" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" +) + +const ( + labelKey = "test-label" + labelGTEKey = "test-label-gte" + continueToken = "nondeterministictoken" + revisionNum = "nondeterministicint" + fakeTestID = "nondeterministicid" + defautlUrlString = "https://rancherurl/" + steveAPITestLabel = "test.cattle.io/steveapi" +) + +var ( + testID = namegenerator.RandStringLower(5) + userEnabled = true + impersonationNamespace = "cattle-impersonation-system" + impersonationSABase = "cattle-impersonation-" + urlRegex = regexp.MustCompile(`https://([\w.:]+)/`) + continueReg = regexp.MustCompile(`(continue=)[\w]+(%3D){0,2}`) + revisionReg = regexp.MustCompile(`(revision=)[\d]+`) + testLabelReg = regexp.MustCompile(`(labelSelector=test.cattle.io%2Fsteveapi%3D)[\w]+`) + projectTag = regexp.MustCompile(`(test-prj-[1-9])`) + namespaceTag = regexp.MustCompile(`(test-ns-[1-9])`) + namespaceSecretManagerRole = rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace-secret-manager", + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{ + "get", + "list", + }, + APIGroups: []string{ + "", + }, + Resources: []string{ + "secrets", + }, + }, + }, + } + mixedSecretUserRole = rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mixed-secret-user", + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{ + "get", + "list", + }, + APIGroups: []string{ + "", + }, + Resources: []string{ + "secrets", + }, + ResourceNames: []string{ + "test1", + "test2", + }, + }, + }, + } + testUsers = map[string][]interface{}{ + "user-a": { + management.ProjectRoleTemplateBinding{ + RoleTemplateID: "project-owner", + ProjectID: "test-prj-1", + }, + }, + "user-b": { + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace-secret-manager", + Namespace: "test-ns-1", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "namespace-secret-manager", + }, + }, + }, + "user-c": { + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mixed-secret-user", + Namespace: "test-ns-1", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "mixed-secret-user", + }, + }, + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mixed-secret-user", + Namespace: "test-ns-2", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "mixed-secret-user", + }, + }, + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "mixed-secret-user", + Namespace: "test-ns-3", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "mixed-secret-user", + }, + }, + }, + "user-d": { + management.ProjectRoleTemplateBinding{ + RoleTemplateID: "project-owner", + ProjectID: "test-prj-1", + }, + management.ProjectRoleTemplateBinding{ + RoleTemplateID: "project-owner", + ProjectID: "test-prj-2", + }, + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace-secret-manager", + Namespace: "test-ns-8", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "namespace-secret-manager", + }, + }, + rbacv1.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace-secret-manager", + Namespace: "test-ns-9", + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "Role", + Name: "namespace-secret-manager", + }, + }, + }, + "user-e": { + management.ClusterRoleTemplateBinding{ + RoleTemplateID: "cluster-owner", + }, + }, + } + namespaceMap = map[string]string{ + "test-ns-1": "", + "test-ns-2": "", + "test-ns-3": "", + "test-ns-4": "", + "test-ns-5": "", + "test-ns-6": "", + "test-ns-7": "", + "test-ns-8": "", + "test-ns-9": "", + } + projectMap = map[string]*management.Project{ + "test-prj-1": nil, + "test-prj-2": nil, + } + projectNamespaceMap = map[string]string{ + "test-ns-1": "test-prj-1", + "test-ns-2": "test-prj-1", + "test-ns-3": "test-prj-1", + "test-ns-4": "test-prj-1", + "test-ns-5": "test-prj-1", + "test-ns-6": "test-prj-2", + "test-ns-7": "test-prj-2", + "test-ns-8": "", + "test-ns-9": "", + } +) + +type steveAPITestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + clusterID string + userClients map[string]*rancher.Client + lastContinueToken string + lastRevision string +} + +type LocalSteveAPITestSuite struct { + steveAPITestSuite +} + +type DownstreamSteveAPITestSuite struct { + steveAPITestSuite +} + +func (s *steveAPITestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *LocalSteveAPITestSuite) SetupSuite() { + s.steveAPITestSuite.setupSuite("local") +} + +func (s *DownstreamSteveAPITestSuite) SetupSuite() { + s.steveAPITestSuite.setupSuite("") +} + +func (s *steveAPITestSuite) setupSuite(clusterName string) { + testSession := session.NewSession() + s.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + s.client = client + + s.userClients = make(map[string]*rancher.Client) + + if clusterName == "" { + clusterName = s.client.RancherConfig.ClusterName + } + s.clusterID, err = clusters.GetClusterIDByName(client, clusterName) + require.NoError(s.T(), err) + + mgmtCluster, err := client.Management.Cluster.ByID(s.clusterID) + require.NoError(s.T(), err) + + // create projects + for p := range projectMap { + project, err := s.client.Management.Project.Create(&management.Project{ + ClusterID: s.clusterID, + Name: p, + }) + require.NoError(s.T(), err) + projectMap[p] = project + } + + userID, err := users.GetUserIDByName(client, "admin") + require.NoError(s.T(), err) + + impersonationSA := impersonationSABase + userID + err = serviceaccounts.IsServiceAccountReady(client, s.clusterID, impersonationNamespace, impersonationSA) + require.NoError(s.T(), err) + + // create project namespaces + for n := range namespaceMap { + if projectMap[projectNamespaceMap[n]] == nil { + continue + } + name := namegenerator.AppendRandomString(n) + _, err := namespaces.CreateNamespace(client, name, "", nil, nil, projectMap[projectNamespaceMap[n]]) + require.NoError(s.T(), err) + namespaceMap[n] = name + } + // create non project namespaces + for n := range namespaceMap { + if projectMap[projectNamespaceMap[n]] != nil { + continue + } + name := namegenerator.AppendRandomString(n) + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } + dynamicClient, err := client.GetDownStreamClusterClient(s.clusterID) + require.NoError(s.T(), err) + namespaceResource := dynamicClient.Resource(kubenamespaces.NamespaceGroupVersionResource) + resp, err := namespaceResource.Create(context.TODO(), unstructured.MustToUnstructured(ns), metav1.CreateOptions{}) + require.NoError(s.T(), err) + s.client.Session.RegisterCleanupFunc(func() error { + err := namespaceResource.Delete(context.TODO(), resp.GetName(), metav1.DeleteOptions{}) + if apierrors.IsNotFound(err) { + return nil + } + return err + }) + err = scheme.Scheme.Convert(resp, ns, resp.GroupVersionKind()) + require.NoError(s.T(), err) + err = wait.Poll(time.Second, time.Minute, func() (done bool, err error) { + ns, _ := kubenamespaces.GetNamespaceByName(s.client, s.clusterID, ns.Name) + if ns != nil { + return true, nil + } + return false, nil + }) + require.NoError(s.T(), err) + namespaceMap[n] = name + } + + // create resources in all namespaces + for name, n := range namespaceMap { + for i := 1; i <= 5; i++ { + if i > 2 && (projectNamespaceMap[name] == "test-prj-2" || projectNamespaceMap[name] == "") { + break + } + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("test%d", i), + }, + } + labels := map[string]string{steveAPITestLabel: testID} + if i == 2 { + labels[labelKey] = "2" + } + if i >= 3 { + labels[labelGTEKey] = "3" + } + secret.ObjectMeta.SetLabels(labels) + err := retryRequest(func() error { + _, err := secrets.CreateSecretForCluster(s.client, secret, s.clusterID, n) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err + }) + require.NoError(s.T(), err) + } + } + + // create test roles in all namespaces + for _, n := range namespaceMap { + role := namespaceSecretManagerRole + role.Namespace = n + err := retryRequest(func() error { + _, err = rbac.CreateRole(s.client, s.clusterID, &role) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err + }) + require.NoError(s.T(), err) + role = mixedSecretUserRole + role.Namespace = n + err = retryRequest(func() error { + _, err = rbac.CreateRole(s.client, s.clusterID, &role) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err + }) + require.NoError(s.T(), err) + } + + // create users and assign access + for user, access := range testUsers { + username := namegenerator.AppendRandomString(user) + password := password.GenerateUserPassword("testpass") + userObj := &management.User{ + Username: username, + Password: password, + Name: username, + Enabled: &userEnabled, + } + userObj, err := s.client.Management.User.Create(userObj) + require.NoError(s.T(), err) + userObj.Password = password + // users either have access to a whole project or to select namespaces or resources in a project + for _, binding := range access { + switch b := binding.(type) { + case management.ClusterRoleTemplateBinding: + err = users.AddClusterRoleToUser(client, mgmtCluster, userObj, b.RoleTemplateID, nil) + require.NoError(s.T(), err) + case management.ProjectRoleTemplateBinding: + err = users.AddProjectMember(client, projectMap[b.ProjectID], userObj, b.RoleTemplateID, nil) + require.NoError(s.T(), err) + case rbacv1.RoleBinding: + _ = users.AddClusterRoleToUser(client, mgmtCluster, userObj, "cluster-member", nil) + subject := rbacv1.Subject{ + Kind: "User", + Name: userObj.ID, + } + err := retryRequest(func() error { + _, err = rbac.CreateRoleBinding(s.client, s.clusterID, namegenerator.AppendRandomString(b.Name), namespaceMap[b.Namespace], b.RoleRef.Name, subject) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err + }) + require.NoError(s.T(), err) + } + } + s.userClients[user], err = s.client.AsUser(userObj) + require.NoError(s.T(), err) + } +} + +func (s *steveAPITestSuite) TestList() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + description string + user string + namespace string + query string + expect []map[string]string + expectExcludes bool + expectContains bool + }{ + // user-a + { + description: "user:user-a,namespace:none,query:none", + user: "user-a", + namespace: "", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:none", + user: "user-a", + namespace: "test-ns-1", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-5,query:none", + user: "user-a", + namespace: "test-ns-5", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:labelSelector=test-label=2", + user: "user-a", + namespace: "", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-2,query:labelSelector=test-label=2", + user: "user-a", + namespace: "test-ns-2", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-a,namespace:none,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-a", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:fieldSelector=metadata.name=test1", + user: "user-a", + namespace: "", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-a", + namespace: "test-ns-1", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-2,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-a", + namespace: "test-ns-2", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{}, + }, + { + description: "user:user-a,namespace:test-ns-1,query:fieldSelector=metadata.name=test1", + user: "user-a", + namespace: "test-ns-1", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:limit=8", + user: "user-a", + namespace: "", + query: "limit=8", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-a,namespace:none,query:limit=8&continue=" + continueToken, + user: "user-a", + namespace: "", + query: "limit=8&continue=" + continueToken, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:limit=3", + user: "user-a", + namespace: "test-ns-1", + query: "limit=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:limit=3&continue=" + continueToken, + user: "user-a", + namespace: "test-ns-1", + query: "limit=3&continue=" + continueToken, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.name=test1", + user: "user-a", + namespace: "", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.name=test6", + user: "user-a", + namespace: "", + query: "filter=metadata.name=test6", + expect: []map[string]string{}, + }, + { + description: "user:user-a,namespace:test-ns-1,query:filter=metadata.name=test1", + user: "user-a", + namespace: "test-ns-1", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.name=1,metadata.namespace=1", + user: "user-a", + namespace: "", + query: "filter=metadata.name=1,metadata.namespace=1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + user: "user-a", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.name!=1", + user: "user-a", + namespace: "", + query: "filter=metadata.name!=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:sort=metadata.name", + user: "user-a", + namespace: "", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:sort=-metadata.name", + user: "user-a", + namespace: "", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test4"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:sort=metadata.name,metadata.namespace", + user: "user-a", + namespace: "", + query: "sort=metadata.name,metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-5"}, + }, + }, + { + description: "user:user-a,namespace:none,query:sort=metadata.name,-metadata.namespace", + user: "user-a", + namespace: "", + query: "sort=metadata.name,-metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:sort=metadata.name", + user: "user-a", + namespace: "test-ns-1", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:sort=-metadata.name", + user: "user-a", + namespace: "test-ns-1", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:pagesize=8", + user: "user-a", + namespace: "", + query: "pagesize=8", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-a,namespace:none,query:pagesize=8&page=2&revision=" + revisionNum, + user: "user-a", + namespace: "", + query: "pagesize=8&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:pagesize=3", + user: "user-a", + namespace: "test-ns-1", + query: "pagesize=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:test-ns-1,query:pagesize=3&page=2&revision=" + revisionNum, + user: "user-a", + namespace: "test-ns-1", + query: "pagesize=3&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20", + user: "user-a", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&limit=20", + // limit is applied BEFORE filter and pagesize, which is why not all test5 secrets appear in the result + expect: []map[string]string{ + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test5"}, + {"name": "test4"}, + {"name": "test4"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=" + revisionNum + "&limit=20", + user: "user-a", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=2&revision=" + revisionNum + "&limit=20", + expect: []map[string]string{ + {"name": "test4"}, + {"name": "test4"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + {"name": "test3"}, + }, + }, + { + description: "user:user-a,namespace:none,query:filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=" + continueToken, + user: "user-a", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=6&page=1&limit=20&continue=" + continueToken, + // the remaining chunk is all from test-ns-5 + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + }, + }, + + // user-b + { + description: "user:user-b,namespace:none,query:none", + user: "user-b", + namespace: "", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:none", + user: "user-b", + namespace: "test-ns-1", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-5,query:none", + user: "user-b", + namespace: "test-ns-5", + query: "", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:labelSelector=test-label=2", + user: "user-b", + namespace: "", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:labelSelector=test-label=2", + user: "user-b", + namespace: "test-ns-1", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-2,query:labelSelector=test-label=2", + user: "user-b", + namespace: "test-ns-2", + query: "labelSelector=test-label=2", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-b", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:fieldSelector=metadata.namespace=test-ns-2", + user: "user-b", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-2", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:fieldSelector=metadata.name=test1", + user: "user-b", + namespace: "", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-b", + namespace: "test-ns-1", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-2,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-b", + namespace: "test-ns-2", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:test-ns-1,query:fieldSelector=metadata.namespace=test-ns-2", + user: "user-b", + namespace: "test-ns-1", + query: "fieldSelector=metadata.namespace=test-ns-2", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:test-ns-1,query:fieldSelector=metadata.name=test1", + user: "user-b", + namespace: "test-ns-1", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-2,query:fieldSelector=metadata.name=test1", + user: "user-b", + namespace: "test-ns-2", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:limit=3", + user: "user-b", + namespace: "", + query: "limit=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:limit=3&continue=" + continueToken, + user: "user-b", + namespace: "", + query: "limit=3&continue=" + continueToken, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:limit=3", + user: "user-b", + namespace: "test-ns-1", + query: "limit=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:limit=3&continue=" + continueToken, + user: "user-b", + namespace: "test-ns-1", + query: "limit=3&continue=" + continueToken, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-5,query:limit=3", + user: "user-b", + namespace: "test-ns-5", + query: "limit=3", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.name=test1", + user: "user-b", + namespace: "", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:filter=metadata.name=test1", + user: "user-b", + namespace: "test-ns-1", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:filter=metadata.name=test6", + user: "user-b", + namespace: "test-ns-1", + query: "filter=metadata.name=test6", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.name=1,metadata.namespace=1", + user: "user-b", + namespace: "", + query: "filter=metadata.name=1,metadata.namespace=1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + user: "user-b", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.name!=1", + user: "user-b", + namespace: "", + query: "filter=metadata.name!=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:sort=metadata.name", + user: "user-b", + namespace: "", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:sort=-metadata.name", + user: "user-b", + namespace: "", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:sort=metadata.name,metadata.namespace", + user: "user-b", + namespace: "", + query: "sort=metadata.name,metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:sort=-metadata.name,metadata.namespace", + user: "user-b", + namespace: "", + query: "sort=-metadata.name,metadata.namespace", + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:sort=metadata.name", + user: "user-b", + namespace: "test-ns-1", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:sort=-metadata.name", + user: "user-b", + namespace: "test-ns-1", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-5,query:sort=metadata.name", + user: "user-b", + namespace: "test-ns-5", + query: "sort=metadata.name", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:pagesize=3", + user: "user-b", + namespace: "", + query: "pagesize=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:pagesize=3&page=2&revision=" + revisionNum, + user: "user-b", + namespace: "", + query: "pagesize=3&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:pagesize=3", + user: "user-b", + namespace: "test-ns-1", + query: "pagesize=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-1,query:pagesize=3&page=2&revision=" + revisionNum, + user: "user-b", + namespace: "test-ns-1", + query: "pagesize=3&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:test-ns-5,query:pagesize=3", + user: "user-b", + namespace: "test-ns-5", + query: "pagesize=3", + expect: []map[string]string{}, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2", + user: "user-b", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2", + expect: []map[string]string{ + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-b,namespace:none,query:filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=" + revisionNum, + user: "user-b", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3&sort=-metadata.name&pagesize=2&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test3", "namespace": "test-ns-1"}, + }, + }, + + // user-c + { + description: "user:user-c,namespace:none,query:none", + user: "user-c", + namespace: "", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:none", + user: "user-c", + namespace: "test-ns-1", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:none", + user: "user-c", + namespace: "test-ns-5", + query: "", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:labelSelector=test-label=2", + user: "user-c", + namespace: "", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:labelSelector=test-label=2", + user: "user-c", + namespace: "test-ns-1", + query: "labelSelector=test-label=2", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:labelSelector=test-label=2", + user: "user-c", + namespace: "test-ns-5", + query: "labelSelector=test-label=2", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-c", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:none,query:fieldSelector=metadata.namespace=test-ns-2", + user: "user-c", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-c,namespace:none,query:fieldSelector=metadata.namespace=test-ns-5", + user: "user-c", + namespace: "", + query: "fieldSelector=metadata.namespace=test-ns-5", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:fieldSelector=metadata.name=test1", + user: "user-c", + namespace: "", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:none,query:fieldSelector=metadata.name=test5", + user: "user-c", + namespace: "", + query: "fieldSelector=metadata.name=test5", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:test-ns-1,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-c", + namespace: "test-ns-1", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-2,query:fieldSelector=metadata.namespace=test-ns-1", + user: "user-c", + namespace: "test-ns-2", + query: "fieldSelector=metadata.namespace=test-ns-1", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:test-ns-1,query:fieldSelector=metadata.namespace=test-ns-2", + user: "user-c", + namespace: "test-ns-1", + query: "fieldSelector=metadata.namespace=test-ns-2", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:test-ns-1,query:fieldSelector=metadata.name=test1", + user: "user-c", + namespace: "test-ns-1", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:fieldSelector=metadata.name=test1", + user: "user-c", + namespace: "test-ns-5", + query: "fieldSelector=metadata.name=test1", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:test-ns-1,query:fieldSelector=metadata.name=test5", + user: "user-c", + namespace: "test-ns-1", + query: "fieldSelector=metadata.name=test5", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:limit=3", + user: "user-c", + namespace: "", + query: "limit=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-c,namespace:none,query:limit=3&continue=" + continueToken, + user: "user-c", + namespace: "", + query: "limit=3&continue=" + continueToken, + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:limit=3", + user: "user-c", + namespace: "test-ns-1", + query: "limit=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:limit=3", + user: "user-c", + namespace: "test-ns-5", + query: "limit=3", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:filter=metadata.name=test1", + user: "user-c", + namespace: "", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:filter=metadata.name=test1", + user: "user-c", + namespace: "test-ns-1", + query: "filter=metadata.name=test1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:filter=metadata.name=test3", + user: "user-c", + namespace: "test-ns-1", + query: "filter=metadata.name=test3", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:filter=metadata.name=1,metadata.namespace=1", + user: "user-c", + namespace: "", + query: "filter=metadata.name=1,metadata.namespace=1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:filter=metadata.name!=test1", + user: "user-c", + namespace: "", + query: "filter=metadata.name!=test1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:none,query:filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + user: "user-c", + namespace: "", + query: "filter=metadata.labels.test-label-gte=3,metadata.labels.test-label=2&filter=metadata.namespace=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:none,query:sort=metadata.name", + user: "user-c", + namespace: "", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + }, + }, + { + description: "user:user-c,namespace:none,query:sort=-metadata.name", + user: "user-c", + namespace: "", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test2"}, + {"name": "test2"}, + {"name": "test2"}, + {"name": "test1"}, + {"name": "test1"}, + {"name": "test1"}, + }, + }, + { + description: "user:user-c,namespace:none,query:sort=metadata.name,metadata.namespace", + user: "user-c", + namespace: "", + query: "sort=metadata.name,metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:none,query:sort=metadata.name,-metadata.namespace", + user: "user-c", + namespace: "", + query: "sort=metadata.name,-metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:sort=metadata.name", + user: "user-c", + namespace: "test-ns-1", + query: "sort=metadata.name", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:sort=-metadata.name", + user: "user-c", + namespace: "test-ns-1", + query: "sort=-metadata.name", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:sort=metadata.name,metadata.namespace", + user: "user-c", + namespace: "test-ns-1", + query: "sort=metadata.name,metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:sort=metadata.name,-metadata.namespace", + user: "user-c", + namespace: "test-ns-1", + query: "sort=metadata.name,-metadata.namespace", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:sort=metadata.name", + user: "user-c", + namespace: "test-ns-5", + query: "sort=metadata.name", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:pagesize=3", + user: "user-c", + namespace: "", + query: "pagesize=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-c,namespace:none,query:pagesize=3&page=2&revision=" + revisionNum, + user: "user-c", + namespace: "", + query: "pagesize=3&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-1,query:pagesize=3", + user: "user-c", + namespace: "test-ns-1", + query: "pagesize=3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-c,namespace:test-ns-5,query:pagesize=3", + user: "user-c", + namespace: "test-ns-5", + query: "pagesize=3", + expect: []map[string]string{}, + }, + { + description: "user:user-c,namespace:none,query:filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1", + user: "user-c", + namespace: "", + query: "filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1", + expect: []map[string]string{ + {"name": "test2", "namespace": "test-ns-3"}, + }, + }, + { + description: "user:user-c,namespace:none,query:filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=" + revisionNum, + user: "user-c", + namespace: "", + query: "filter=metadata.namespace=test-ns-3&sort=-metadata.name&pagesize=1&page=2&revision=" + revisionNum, + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-3"}, + }, + }, + + // user-d + { + description: "user:user-d,namespace:none,query:none", + user: "user-d", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-prj-2", + user: "user-d", + query: "projectsornamespaces=test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-prj-1,test-prj-2", + user: "user-d", + query: "projectsornamespaces=test-prj-1,test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-ns-1", + user: "user-d", + query: "projectsornamespaces=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-ns-1,test-ns-2", + user: "user-d", + query: "projectsornamespaces=test-ns-1,test-ns-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-prj-2,test-ns-2,test-ns-3", + user: "user-d", + query: "projectsornamespaces=test-prj-2,test-ns-2,test-ns-3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces=test-ns-8,test-ns-9", + user: "user-d", + query: "projectsornamespaces=test-ns-8,test-ns-9", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces!=test-prj-1", + user: "user-d", + query: "projectsornamespaces!=test-prj-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces!=test-prj-1,test-prj-2", + user: "user-d", + query: "projectsornamespaces!=test-prj-1,test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-d,namespace:none,query:projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8", + user: "user-d", + query: "projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-d,namespace:test-ns-6,query:none", + user: "user-d", + namespace: "test-ns-6", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + }, + }, + { + description: "user:user-d,namespace:test-ns-6,query:projectsornamespaces=test-prj-2", + user: "user-d", + namespace: "test-ns-6", + query: "projectsornamespaces=test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + }, + }, + { + description: "user:user-d,namespace:test-ns-6,query:projectsornamespaces=test-prj-2", + user: "user-d", + namespace: "test-ns-6", + query: "projectsornamespaces=test-prj-1", + expect: []map[string]string{}, + }, + { + description: "user:user-d,namespace:test-ns-1,query:projectsornamespaces=test-ns-1,test-ns-2,-test-prj-2,test-ns-7", + user: "user-d", + namespace: "test-ns-1", + query: "projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-d,namespace:test-ns-1,query:projectsornamespaces!=test-prj-1", + user: "user-d", + namespace: "test-ns-1", + query: "projectsornamespaces!=test-prj-1", + expect: []map[string]string{}, + }, + { + description: "user:user-d,namespace:test-ns-1,query:projectsornamespaces!=test-prj-1,test-prj-2", + user: "user-d", + namespace: "test-ns-1", + query: "projectsornamespaces!=test-prj-1,test-prj-2", + expect: []map[string]string{}, + }, + + // user-e + { + description: "user:user-e,namespace:none,query:none", + user: "user-e", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + expectContains: true, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-prj-2", + user: "user-e", + query: "projectsornamespaces=test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-prj-1,test-prj-2", + user: "user-e", + query: "projectsornamespaces=test-prj-1,test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-ns-1", + user: "user-e", + query: "projectsornamespaces=test-ns-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-ns-1,test-ns-2", + user: "user-e", + query: "projectsornamespaces=test-ns-1,test-ns-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-prj-2,test-ns-2,test-ns-3", + user: "user-e", + query: "projectsornamespaces=test-prj-2,test-ns-2,test-ns-3", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces=test-ns-8,test-ns-9", + user: "user-e", + query: "projectsornamespaces=test-ns-8,test-ns-9", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + {"name": "test1", "namespace": "test-ns-9"}, + {"name": "test2", "namespace": "test-ns-9"}, + }, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces!=test-prj-1", + user: "user-e", + query: "projectsornamespaces!=test-prj-1", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + }, + expectExcludes: true, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces!=test-prj-1,test-prj-2", + user: "user-e", + query: "projectsornamespaces!=test-prj-1,test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-7"}, + {"name": "test2", "namespace": "test-ns-7"}, + }, + expectExcludes: true, + }, + { + description: "user:user-e,namespace:none,query:projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8", + user: "user-e", + query: "projectsornamespaces!=test-prj-1,test-ns-6,test-ns-8", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + {"name": "test1", "namespace": "test-ns-2"}, + {"name": "test2", "namespace": "test-ns-2"}, + {"name": "test3", "namespace": "test-ns-2"}, + {"name": "test4", "namespace": "test-ns-2"}, + {"name": "test5", "namespace": "test-ns-2"}, + {"name": "test1", "namespace": "test-ns-3"}, + {"name": "test2", "namespace": "test-ns-3"}, + {"name": "test3", "namespace": "test-ns-3"}, + {"name": "test4", "namespace": "test-ns-3"}, + {"name": "test5", "namespace": "test-ns-3"}, + {"name": "test1", "namespace": "test-ns-4"}, + {"name": "test2", "namespace": "test-ns-4"}, + {"name": "test3", "namespace": "test-ns-4"}, + {"name": "test4", "namespace": "test-ns-4"}, + {"name": "test5", "namespace": "test-ns-4"}, + {"name": "test1", "namespace": "test-ns-5"}, + {"name": "test2", "namespace": "test-ns-5"}, + {"name": "test3", "namespace": "test-ns-5"}, + {"name": "test4", "namespace": "test-ns-5"}, + {"name": "test5", "namespace": "test-ns-5"}, + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + {"name": "test1", "namespace": "test-ns-8"}, + {"name": "test2", "namespace": "test-ns-8"}, + }, + expectExcludes: true, + }, + { + description: "user:user-e,namespace:test-ns-6,query:none", + user: "user-e", + namespace: "test-ns-6", + query: "", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + }, + }, + { + description: "user:user-e,namespace:test-ns-6,query:projectsornamespaces=test-prj-2", + user: "user-e", + namespace: "test-ns-6", + query: "projectsornamespaces=test-prj-2", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-6"}, + {"name": "test2", "namespace": "test-ns-6"}, + }, + }, + { + description: "user:user-e,namespace:test-ns-6,query:projectsornamespaces=test-prj-1", + user: "user-e", + namespace: "test-ns-6", + query: "projectsornamespaces=test-prj-1", + expect: []map[string]string{}, + }, + { + description: "user:user-e,namespace:test-ns-1,query:projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7", + user: "user-e", + namespace: "test-ns-1", + query: "projectsornamespaces=test-ns-1,test-ns-2,test-prj-2,test-ns-7", + expect: []map[string]string{ + {"name": "test1", "namespace": "test-ns-1"}, + {"name": "test2", "namespace": "test-ns-1"}, + {"name": "test3", "namespace": "test-ns-1"}, + {"name": "test4", "namespace": "test-ns-1"}, + {"name": "test5", "namespace": "test-ns-1"}, + }, + }, + { + description: "user:user-e,namespace:test-ns-1,query:projectsornamespaces!=test-prj-1", + user: "user-e", + namespace: "test-ns-1", + query: "projectsornamespaces!=test-prj-1", + expect: []map[string]string{}, + }, + { + description: "user:user-e,namespace:test-ns-1,query:projectsornamespaces!=test-prj-1,test-prj-2", + user: "user-e", + namespace: "test-ns-1", + query: "projectsornamespaces!=test-prj-1,test-prj-2", + expect: []map[string]string{}, + }, + { + description: "user:user-e,namespace:test-ns-1,query:projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8", + user: "user-e", + namespace: "test-ns-1", + query: "projectsornamespaces!=test-prj-1,test-ns-2,test-ns-8", + expect: []map[string]string{}, + }, + } + + var csvWriter *csv.Writer + var jsonDir string + if s.clusterID == "local" { + var fp *os.File + var err error + csvWriter, fp, jsonDir, err = setUpResults() + defer fp.Close() + defer func() { + csvWriter.Flush() + require.NoError(s.T(), csvWriter.Error()) + }() + require.NoError(s.T(), err) + } + + for _, test := range tests { + s.Run(test.description, func() { + userClient := s.userClients[test.user] + + client, err := userClient.Steve.ProxyDownstream(s.clusterID) + require.NoError(s.T(), err) + var secretClient clientv1.SteveOperations + secretClient = client.SteveType(stevesecrets.SecretSteveType) + if test.namespace != "" { + secretClient = secretClient.(*clientv1.SteveClient).NamespacedSteveClient(namespaceMap[test.namespace]) + } + query, err := url.ParseQuery(test.query) + require.NoError(s.T(), err) + if _, ok := query["sort"]; !ok && s.clusterID != "local" { + // k8s does not guarantee any particular order but usually returns results sorted by namespace and name. + // k3d seems to have its own ideas, so we can't rely on a consistent order when testing on the downstream cluster. + query["sort"] = []string{"metadata.namespace,metadata.name"} + } + if _, ok := query["continue"]; ok { + query["continue"] = []string{s.lastContinueToken} + } + if fs, ok := query["fieldSelector"]; ok { + if strings.Contains(fs[0], "metadata.namespace") { + fieldParts := strings.Split(fs[0], "=") + ns := namespaceMap[fieldParts[1]] + query["fieldSelector"] = []string{"metadata.namespace=" + ns} + } + } + key := "projectsornamespaces" + projectsOrNamespaces, ok := query[key] + if !ok { + key += "!" + projectsOrNamespaces = query[key] + } + if len(projectsOrNamespaces) != 0 { + groups := projectTag.FindAllStringSubmatch(projectsOrNamespaces[0], -1) + for _, g := range groups { + name := string(g[1]) + projectID := projectMap[name].ID + projectID = strings.Split(projectID, ":")[1] + projectsOrNamespaces[0] = strings.ReplaceAll(projectsOrNamespaces[0], name, projectID) + } + groups = namespaceTag.FindAllStringSubmatch(projectsOrNamespaces[0], -1) + for _, g := range groups { + name := string(g[1]) + projectsOrNamespaces[0] = strings.ReplaceAll(projectsOrNamespaces[0], name, namespaceMap[name]) + } + query[key] = projectsOrNamespaces + } + if _, ok := query["revision"]; ok { + query["revision"] = []string{s.lastRevision} + } + query["labelSelector"] = append(query["labelSelector"], steveAPITestLabel+"="+testID) + secretList, err := secretClient.List(query) + require.NoError(s.T(), err) + + if secretList.Continue != "" { + s.lastContinueToken = secretList.Continue + } + s.lastRevision = secretList.Revision + + if test.expectContains { + s.assertListContains(test.expect, secretList.Data) + } else if test.expectExcludes { + s.assertListExcludes(test.expect, secretList.Data) + } else { + s.assertListIsEqual(test.expect, secretList.Data) + } + + // Write human-readable request and response examples + if s.clusterID == "local" { + curlURL, err := getCurlURL(client, test.namespace, test.query) + require.NoError(s.T(), err) + jsonResp, err := formatJSON(secretList) + require.NoError(s.T(), err) + jsonFilePath := filepath.Join(jsonDir, getFileName(test.user, test.namespace, test.query)) + err = writeResp(csvWriter, test.user, curlURL, jsonFilePath, jsonResp) + require.NoError(s.T(), err) + } + }) + } +} + +func getFileName(user, ns, query string) string { + if user == "" { + user = "none" + } + if ns == "" { + ns = "none" + } + if query == "" { + query = "none" + } + return user + "_" + ns + "_" + query + ".json" +} + +func getCurlURL(client *clientv1.Client, namespace, query string) (string, error) { + curlURL, err := client.APIBaseClient.Ops.GetCollectionURL(stevesecrets.SecretSteveType, "GET") + if err != nil { + return "", err + } + if namespace != "" { + curlURL += "/" + namespace + } + if query != "" { + curlURL += "?" + query + } + + curlURL = urlRegex.ReplaceAllString(curlURL, defautlUrlString) + return curlURL, nil +} + +func formatJSON(obj *clientv1.SteveCollection) ([]byte, error) { + jsonResp, err := json.Marshal(obj) + if err != nil { + return nil, err + } + var mapResp map[string]interface{} + err = json.Unmarshal(jsonResp, &mapResp) + if err != nil { + return nil, err + } + + mapResp["revision"] = "100" + if _, ok := mapResp["continue"]; ok { + mapResp["continue"] = continueToken + } + if pagination, ok := mapResp["pagination"].(map[string]interface{}); ok { + if next, ok := pagination["next"].(string); ok { + next = continueReg.ReplaceAllString(next, "${1}"+continueToken) + next = revisionReg.ReplaceAllString(next, "${1}"+revisionNum) + next = testLabelReg.ReplaceAllString(next, "${1}"+fakeTestID) + pagination["next"] = next + mapResp["pagination"] = pagination + } + } + data, ok := mapResp["data"].([]interface{}) + if ok { + for i := range data { + delete(data[i].(map[string]interface{}), "JSONResp") + delete(data[i].(map[string]interface{})["metadata"].(map[string]interface{}), "creationTimestamp") + delete(data[i].(map[string]interface{})["metadata"].(map[string]interface{}), "managedFields") + delete(data[i].(map[string]interface{})["metadata"].(map[string]interface{}), "uid") + data[i].(map[string]interface{})["metadata"].(map[string]interface{})["labels"].(map[string]interface{})[steveAPITestLabel] = fakeTestID + data[i].(map[string]interface{})["metadata"].(map[string]interface{})["resourceVersion"] = "1000" + } + mapResp["data"] = data + } + jsonBytes, err := json.MarshalIndent(mapResp, "", " ") + if err != nil { + return nil, err + } + jsonString := string(jsonBytes) + for k, v := range namespaceMap { + jsonString = strings.ReplaceAll(jsonString, v, k) + } + jsonString = urlRegex.ReplaceAllString(jsonString, defautlUrlString) + return []byte(jsonString), nil +} + +func setUpResults() (*csv.Writer, *os.File, string, error) { + outputFile := "output.csv" + fields := []string{"user", "url", "response"} + csvFile, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return nil, nil, "", err + } + csvWriter := csv.NewWriter(bufio.NewWriter(csvFile)) + csvWriter.Write(fields) + if csvWriter.Error() != nil { + return nil, csvFile, "", err + } + jsonDir := "json" + err = os.MkdirAll(jsonDir, 0755) + if err != nil { + return nil, csvFile, "", err + } + return csvWriter, csvFile, jsonDir, nil +} + +func writeResp(csvWriter *csv.Writer, user, url, path string, resp []byte) error { + jsonFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return err + } + jsonFile.Write(resp) + csvWriter.Write([]string{user, url, fmt.Sprintf("[%s](%s)", path, path)}) + return nil +} + +func (s *steveAPITestSuite) TestCRUD() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + client, err := s.client.Steve.ProxyDownstream(s.clusterID) + require.NoError(s.T(), err) + + s.Run("global", func() { + secretClient := client.SteveType(stevesecrets.SecretSteveType) + + // create + secretObj, err := secretClient.Create(corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namegenerator.AppendRandomString("steve-secret"), + Namespace: namespaceMap["test-ns-1"], // need to specify the namespace for a namespaced resource if using a global endpoint ("/v1/secrets") + }, + Data: map[string][]byte{"foo": []byte("bar")}, + }) + require.NoError(s.T(), err) + + // read + readObj, err := secretClient.ByID(secretObj.ID) + require.NoError(s.T(), err) + assert.Contains(s.T(), readObj.JSONResp["data"], "foo") + + // update + updatedSecret := secretObj.JSONResp + updatedSecret["data"] = map[string][]byte{"lorem": []byte("ipsum")} + secretObj, err = secretClient.Update(secretObj, &updatedSecret) + require.NoError(s.T(), err) + + // read again + readObj, err = secretClient.ByID(secretObj.ID) + require.NoError(s.T(), err) + assert.Contains(s.T(), readObj.JSONResp["data"], "lorem") + + // delete + err = secretClient.Delete(readObj) + require.NoError(s.T(), err) + + // read again + readObj, err = secretClient.ByID(secretObj.ID) + require.Error(s.T(), err) + assert.Nil(s.T(), readObj) + }) + + s.Run("namespaced", func() { + secretClient := client.SteveType(stevesecrets.SecretSteveType).NamespacedSteveClient(namespaceMap["test-ns-1"]) + + // create + secretObj, err := secretClient.Create(corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namegenerator.AppendRandomString("steve-secret"), + // no need to provide a namespace since using a namespaced endpoint ("/v1/secrets/test-ns-1") + }, + Data: map[string][]byte{"foo": []byte("bar")}, + }) + require.NoError(s.T(), err) + + // read + readObj, err := secretClient.ByID(secretObj.ID) + require.NoError(s.T(), err) + assert.Contains(s.T(), readObj.JSONResp["data"], "foo") + + // update + updatedSecret := secretObj.JSONResp + updatedSecret["data"] = map[string][]byte{"lorem": []byte("ipsum")} + secretObj, err = secretClient.Update(secretObj, &updatedSecret) + require.NoError(s.T(), err) + + // read again + readObj, err = secretClient.ByID(secretObj.ID) + require.NoError(s.T(), err) + assert.Contains(s.T(), readObj.JSONResp["data"], "lorem") + + // delete + err = secretClient.Delete(readObj) + require.NoError(s.T(), err) + + // read again + readObj, err = secretClient.ByID(secretObj.ID) + require.Error(s.T(), err) + assert.Nil(s.T(), readObj) + }) +} +func (s *steveAPITestSuite) assertListIsEqual(expect []map[string]string, list []clientv1.SteveAPIObject) { + assert.Equal(s.T(), len(expect), len(list)) + for i, w := range expect { + if name, ok := w["name"]; ok { + assert.Equal(s.T(), name, list[i].Name) + } + if ns, ok := w["namespace"]; ok { + assert.Equal(s.T(), namespaceMap[ns], list[i].Namespace) + } + } +} + +func (s *steveAPITestSuite) assertListContains(expect []map[string]string, list []clientv1.SteveAPIObject) { + assert.GreaterOrEqual(s.T(), len(list), len(expect)) + matches := true + for _, w := range expect { + found := false + for _, obj := range list { + if obj.Name == w["name"] && obj.Namespace == namespaceMap[w["namespace"]] { + found = true + break + } + } + if !found { + matches = false + } + } + assert.True(s.T(), matches, "list did not contain expected results") +} + +func (s *steveAPITestSuite) assertListExcludes(expect []map[string]string, list []clientv1.SteveAPIObject) { + found := false + for _, w := range expect { + for _, obj := range list { + if obj.Name == w["name"] && obj.Namespace == namespaceMap[w["namespace"]] { + found = true + break + } + } + if found == true { + break + } + } + assert.False(s.T(), found, "list contained unexpected results") +} + +func retryRequest(fn func() error) error { + retriable := func(err error) bool { return strings.Contains(err.Error(), "tunnel disconnect") } + return retry.OnError(retry.DefaultBackoff, retriable, fn) +} + +func TestSteveLocal(t *testing.T) { + suite.Run(t, new(LocalSteveAPITestSuite)) +} + +func TestSteveDownstream(t *testing.T) { + // TODO: Re-enable the test when the bug is fixed + t.Skip() + suite.Run(t, new(DownstreamSteveAPITestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/.gitignore new file mode 100644 index 0000000..24f5fcd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/.gitignore @@ -0,0 +1,7 @@ +# dot env +.env +# json +*.json +#yaml +*.yaml +!manifest.yaml \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.e2e b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.e2e new file mode 100644 index 0000000..43cfb6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.e2e @@ -0,0 +1,39 @@ +FROM registry.suse.com/bci/golang:1.22 + +# Configure Go +ENV GOPATH /root/go +ENV PATH ${PATH}:/root/go/bin + +ENV WORKSPACE ${GOPATH}/src/github.com/rancher/rancher +ENV WORKSPACE2 ${GOPATH}/src/github.com/rancherlabs/corral-packages + +WORKDIR $WORKSPACE + +COPY ["./rancher", "$WORKSPACE"] +COPY ["./corral-packages", "$WORKSPACE2"] + +ARG CORRAL_VERSION=v1.1.1 + +RUN zypper -n install gcc binutils glibc-devel-static ca-certificates git-core wget curl unzip tar vim less file xz gzip sed gawk iproute2 iptables jq +RUN zypper install -y -f docker && rpm -e --nodeps --noscripts containerd +RUN go mod download && \ + go install gotest.tools/gotestsum@latest && \ + go install github.com/rancherlabs/corral@${CORRAL_VERSION} + +# necessary to run if statements using [[ ]] +SHELL ["/bin/bash", "-c"] + +ARG RKE_VERSION +RUN if [[ -n "$RKE_VERSION" ]] ; then echo installing latest version RKE && \ + curl -0Ls https://github.com/rancher/rke/releases/latest/download/rke_linux-amd64 > rke ; else echo installing ${RKE_VERSION} version RKE && \ + curl -0Ls https://github.com/rancher/rke/releases/download/$RKE_VERSION/rke_linux-amd64 > rke; fi; +RUN mv rke /bin/rke && \ + chmod +x /bin/rke + +ARG CLI_VERSION +RUN if [[ -n "$CLI_VERSION" ]] ; then \ + echo installing CLI version $CLI_VERSION ; \ + curl -LO https://github.com/rancher/cli/releases/download/$CLI_VERSION/rancher-linux-amd64-$CLI_VERSION.tar.gz ; \ + tar -xf rancher-linux-amd64-$CLI_VERSION.tar.gz && \ + mv rancher-$CLI_VERSION/rancher /bin/rancher && \ + chmod +x /bin/rancher; fi; \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.validation b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.validation new file mode 100644 index 0000000..da0f1ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Dockerfile.validation @@ -0,0 +1,58 @@ +FROM golang:1.22 + +# Configure Go +ENV GOPATH /root/go +ENV PATH ${PATH}:/root/go/bin + +ENV WORKSPACE ${GOPATH}/src/github.com/rancher/rancher +# configure VPN +ARG EXTERNAL_ENCODED_VPN +ARG VPN_ENCODED_LOGIN + +WORKDIR $WORKSPACE/tests/v2/validation + +COPY [".", "$WORKSPACE"] + +RUN go mod download && \ + go install gotest.tools/gotestsum@latest + + +# Configure Corral +ENV CORRAL_VERSION="v1.1.1" +RUN go install github.com/rancherlabs/corral@${CORRAL_VERSION} + +RUN mkdir /root/.ssh && chmod 600 .ssh/jenkins-* +RUN ssh-keygen -f .ssh/jenkins-* -y > /root/.ssh/public.pub + +RUN CGO_ENABLED=0 + +# necessary to run if statements using [[ ]] +SHELL ["/bin/bash", "-c"] + +RUN if [[ -z '$EXTERNAL_ENCODED_VPN' ]] ; then \ + echo 'no vpn provided' ; \ + else \ + apt-get update && apt-get -y install openvpn net-tools && \ + echo $EXTERNAL_ENCODED_VPN | base64 -d > external.ovpn && \ + if [[ -z '$VPN_ENCODED_LOGIN' ]] ; then \ + echo 'no passcode provided' ; \ + else \ + echo 'adding passfile' && echo $VPN_ENCODED_LOGIN | base64 -d > passfile && \ + sed -i 's/auth-user-pass/auth-user-pass passfile/g' external.ovpn; \ + fi; \ + fi; + +ARG RKE_VERSION +RUN if [[ -n "$RKE_VERSION" ]] ; then echo installing latest version RKE && \ + curl -0Ls https://github.com/rancher/rke/releases/latest/download/rke_linux-amd64 > rke ; else echo installing ${RKE_VERSION} version RKE && \ + curl -0Ls https://github.com/rancher/rke/releases/download/$RKE_VERSION/rke_linux-amd64 > rke; fi; +RUN mv rke /bin/rke && \ + chmod +x /bin/rke + +ARG CLI_VERSION +RUN if [[ -n "$CLI_VERSION" ]] ; then \ + echo installing CLI version $CLI_VERSION ; \ + curl -LO https://github.com/rancher/cli/releases/download/$CLI_VERSION/rancher-linux-amd64-$CLI_VERSION.tar.gz ; \ + tar -xf rancher-linux-amd64-$CLI_VERSION.tar.gz && \ + mv rancher-$CLI_VERSION/rancher /bin/rancher && \ + chmod +x /bin/rancher; fi; \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile new file mode 100644 index 0000000..49621e9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile @@ -0,0 +1,143 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "github.com/rancher/rancher/tests/v2/validation/${env.TEST_PACKAGE}" + def testResultsOut = "results.xml" + def testResultsJSON = "results.json" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def repo = scm.userRemoteConfigs + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + repo = [[url: "${env.REPO}"]] + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN'), + string(credentialsId: 'SLACK_WEBHOOK', variable: 'SLACK_WEBHOOK'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: repo + ]) + } + dir ("./") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + dir("./tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = rootPath+filename + } + + sh "./tests/v2/validation/configure.sh" + sh "./tests/v2/validation/build.sh" + } + stage('Run Validation Tests') { + try { + sh "docker run --name ${testContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"/root/go/bin/gotestsum --format standard-verbose --packages=${testsDir} --junitfile ${testResultsOut} --jsonfile ${testResultsJSON} -- -tags=${TAGS} ${GOTEST_TESTCASE} -timeout=${timeout} -v;" + + "${rootPath}pipeline/scripts/build_qase_reporter.sh;" + + "${rootPath}reporter\"" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + stage('Test Report') { + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi -f ${imageName}" + } + } catch(err) { + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi -f ${imageName}" + } // catch error + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.e2e b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.e2e new file mode 100644 index 0000000..1f6be97 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.e2e @@ -0,0 +1,201 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def golangTestContainer = "${job_name}${env.BUILD_NUMBER}-golangtest" + def buildTestContainer = "${job_name}${env.BUILD_NUMBER}-buildtest" + def cleanupTestContainer = "${job_name}${env.BUILD_NUMBER}-cleanuptest" + def golangImageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def validationVolume = "ValidationSharedVolume-${job_name}${env.BUILD_NUMBER}" + def testsDir = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/${env.TEST_PACKAGE}" + def testResultsOut = "results.xml" + def testResultsJSON = "results.json" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def corralBranch = "main" + def cleanup = env.RANCHER_CLEANUP.toLowerCase() + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "") { + corralBranch = "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" + } + + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + + if (scm.getUserRemoteConfigs().size() > 1) { + corralRepo = scm.getUserRemoteConfigs()[1].getUrl() + } + + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "") { + corralRepo = "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" + } + + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN'), + string(credentialsId: 'SLACK_WEBHOOK', variable: 'SLACK_WEBHOOK'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY')]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir('./') { + echo "cloning corral-packages repo" + + dir('./corral-packages') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${corralBranch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: corralRepo]] + ]) + } + def rancherFilename = "rancher-registry.yaml" + def rancherConfigContents = env.RANCHER_CORRAL_CONFIG + def registriesFilename = "registry.yaml" + def registriesConfigContents = env.REGISTRIES_CORRAL_CONFIG + if (rancherConfigContents != null && registriesConfigContents != null) { + writeFile file: "./corral-packages/packages/aws/"+rancherFilename, text: rancherConfigContents + writeFile file: "./corral-packages/packages/aws/"+registriesFilename, text: registriesConfigContents + } + } + } + dir ("./") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./rancher/tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + dir("./rancher/tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = "${workPath}"+filename + } + dir ("./") { + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e --build-arg CORRAL_VERSION=${env.CORRAL_VERSION} -t ${golangImageName}" + sh "docker volume create --name ${validationVolume}" + } + } + stage("Build Environment") { + try { + sh "docker run -v ${validationVolume}:/root --name ${buildTestContainer} -t --env-file ${envFile} " + + "${golangImageName} sh -c \"${workPath}pipeline/scripts/setup_environment.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker volume rm -f ${validationVolume}" + error "Build Environment had failures." + } + } + stage('Run Validation Tests') { + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${golangTestContainer} -t --env-file ${envFile} " + + "${golangImageName} sh -c \"gotestsum --format standard-verbose --packages=${testsDir} --junitfile ${testResultsOut} --jsonfile ${testResultsJSON} -- -tags=${TAGS} ${GOTEST_TESTCASE} -timeout=${timeout} -v;" + + "${workPath}pipeline/scripts/build_qase_reporter.sh;" + + "${workPath}reporter\"" + } catch(err) { + echo 'Validation tests had failures. Aborting' + } + } + stage('Cleanup Rancher Environment') { + try { + if (cleanup.toBoolean()) { + sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " + + "${golangImageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\"" + } + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + sh "docker rmi -f ${golangImageName}" + sh "docker volume rm -f ${validationVolume}" + error "Cleanup had failures." + } + } + stage('Test Report') { + try { + sh "docker cp ${golangTestContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + } catch (err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + if (cleanup.toBoolean()) { + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + } + sh "docker rmi -f ${golangImageName}" + sh "docker volume rm -f ${validationVolume}" + error 'Report had failures.' + } + } + stage('Clean Up Images and Volume') { + echo 'Cleaning test images and volume.' + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${golangTestContainer}" + sh "docker rm -v ${golangTestContainer}" + if (cleanup.toBoolean()) { + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + } + sh "docker rmi -f ${golangImageName}" + sh "docker volume rm -f ${validationVolume}" + } + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.rc b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.rc new file mode 100644 index 0000000..4a7f4b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile.rc @@ -0,0 +1,394 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def jobName = "${JOB_NAME}" + if (jobName.contains('/')) { + jobNames = jobName.split('/') + jobName = jobNames[jobNames.size() - 1] + } + def golangTestContainer = "${jobName}${env.BUILD_NUMBER}-golangtest" + def buildTestContainer = "${jobName}${env.BUILD_NUMBER}-buildtest" + def configGeneratorContainer = "${jobName}${env.BUILD_NUMBER}_generator" + def cleanupTestContainer = "${jobName}${env.BUILD_NUMBER}-cleanuptest" + def imageName = "rancher-recurring-runs-validation-${jobName}${env.BUILD_NUMBER}" + def validationVolume = "RecurringRunsSharedVolume-${jobName}${env.BUILD_NUMBER}" + def testsDir = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def configsDir = "cattle-configs" + def patchedConfigsDir = "patched-cattle-configs" + def testResultsOut = "results.xml" + def qaseRun = "testrun" + def testRunConfig = "testrunconfig.yaml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def corralBranch = "main" + def config = env.CONFIG + def rancherToken = "" + def filename = "config.yaml" + def individualJob = "go-recurring-daily" + def corralJob = "corral-go-job" + individualJob = "${individualJob}-individual-job" + + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "") { + corralBranch = "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" + } + + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + + def corralRepo = scm.getUserRemoteConfigs()[1].getUrl() + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "") { + corralRepo = "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" + } + + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + + def configFiles = [] + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + + string(credentialsId: 'AWS_RSA_KEY_NAME', variable: 'AWS_RSA_KEY_NAME'), + string(credentialsId: 'AWS_SSH_RSA_KEY', variable: 'AWS_SSH_RSA_KEY'), + + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: 'RANCHER_LINODE_ACCESSKEY'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN')]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir('./') { + echo "cloning corral-packages repo" + + dir('./corral-packages') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${corralBranch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: corralRepo]] + ]) + } + } + } + dir ("./") { + stage('Configure and Build') { + config = config.replace('${AWS_SECRET_ACCESS_KEY}', env.AWS_SECRET_ACCESS_KEY) + config = config.replace('${AWS_ACCESS_KEY_ID}', env.AWS_ACCESS_KEY_ID) + config = config.replace('${AWS_IAM_PROFILE}', env.AWS_IAM_PROFILE) + config = config.replace('${AWS_REGION}', env.AWS_REGION) + config = config.replace('${AWS_VPC}', env.AWS_VPC) + config = config.replace('${AWS_SECURITY_GROUPS}', env.AWS_SECURITY_GROUPS) + config = config.replace('${ADMIN_PASSWORD}', env.ADMIN_PASSWORD) + + config = config.replace('${AZURE_CLIENT_ID}', env.AZURE_CLIENT_ID) + config = config.replace('${AZURE_CLIENT_SECRET}', env.AZURE_CLIENT_SECRET) + config = config.replace('${AZURE_SUBSCRIPTION_ID}', env.AZURE_SUBSCRIPTION_ID) + + config = config.replace('${AWS_SSH_PEM_KEY}', env.AWS_SSH_KEY_NAME) + config = config.replace('${AWS_SSH_RSA_KEY}', env.AWS_SSH_RSA_KEY) + config = config.replace('${RANCHER_LINODE_ACCESSKEY}', env.RANCHER_LINODE_ACCESSKEY) + + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./rancher/tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + dir("./rancher/tests/v2/validation") { + writeFile file: filename, text: config + env.CATTLE_TEST_CONFIG = "${workPath}${filename}" + } + dir ("./") { + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e --build-arg CLI_VERSION=\"${CLI_VERSION}\" -t ${imageName}" + sh "docker volume create --name ${validationVolume}" + } + } + stage('Setup') { + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout:true, script: 'chmod a+x ./yq' + } + stage("Build Environment") { + try { + sh "docker run -v ${validationVolume}:/root --name ${buildTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"${workPath}pipeline/scripts/setup_environment.sh;${workPath}pipeline/scripts/build_qase_auto_testrun.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker volume rm -f ${validationVolume}" + error "Build Environment had failures." + } + } + try { + stage ('Generate configuration files') { + sh "docker run --volumes-from ${buildTestContainer} --name ${configGeneratorContainer} -t -e CATTLE_TEST_CONFIG=\$CATTLE_TEST_CONFIG " + + "${imageName} sh -c \"${workPath}pipeline/releaseupgrade/releaseupgrade.sh\"" + + sh "docker cp ${configGeneratorContainer}:${rootPath}${configsDir}/ ." + + def configs = sh(script: "ls -1 ./${configsDir}", returnStdout: true).split() + + for (int i = 0; i < configs.size(); i++) { + def configName = configs[i] + echo "pushing ${configName} to the global variable" + configFiles << "${configName}" + } + + println "Building the image again with the config files" + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e --build-arg CLI_VERSION=\"${CLI_VERSION}\" -t ${imageName}" + } + stage('Deploys clusters') { + try { + jobs = [:] + + configFiles.each { + def configPath = "./${configsDir}/$it" + def absoluteConfigPath = "${rootPath}${configsDir}/$it" + + def testCase = sh ( + script: "./yq '.testCases.provisioningTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.provisioningTestPackage' ${configPath}", + returnStdout: true + ).trim() + + jobs["$it-provisioning"] = { + stage("Parallel Provisioning: $it"){ + def containerName = "${jobName}${env.BUILD_NUMBER}_$it-provisioning" + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${containerName} -t -e CATTLE_TEST_CONFIG=\"${absoluteConfigPath}\" " + + "${imageName} sh -c \"gotestsum --format standard-verbose --packages=\"${testsDir}${testPackage}\" --junitfile ${testResultsOut} -- -tags=validation ${testCase} -timeout=\"60m\" -v\"" + + dir("./${patchedConfigsDir}") { + sh "docker cp ${containerName}:${rootPath}${configsDir}/$it ." + } + } catch (err){ + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + } + } + + parallel jobs + } catch(err){ + echo "Provisioning tests had failures: " + err + } + } + stage('Run Test Validations') { + try { + jobs = [:] + + // copy updated config file from the build test container + sh "docker cp ${buildTestContainer}:${workPath}${filename} ./" + sh "docker cp ${buildTestContainer}:${workPath}${qaseRun} ./" + sh "./${qaseRun} --startRun=true" + + def testRunID = sh ( + script: "./yq '.id' ./${testRunConfig}", + returnStdout: true + ).trim() + + def mainRancherConfigPath = "./${filename}" + + sh "./yq e '.rancher.cleanup = true' -i ${mainRancherConfigPath}" + configFiles.each { + try { + def configPath = "./${patchedConfigsDir}/$it" + + def tags = sh ( + script: "./yq '.testCases.tags' ${configPath}", + returnStdout: true + ).trim() + + def runFlag = sh ( + script: "./yq '.testCases.runFlag' ${configPath}", + returnStdout: true + ).trim() + + def clusterName = sh ( + script: "./yq '.rancher.clusterName' ${configPath}", + returnStdout: true + ).trim() + + sh "./yq e '.rancher.clusterName = \"${clusterName}\"' -i ${mainRancherConfigPath}" + + def configYaml = readFile(file: "${mainRancherConfigPath}") + // This is the config for the glue-code clusters + def goValidationParams = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'QASE_TEST_RUN_ID', value: "${testRunID}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${runFlag}"), + string(name: 'TAGS', value: tags), + string(name: 'CLI_VERSION', value: "${CLI_VERSION}"), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_SINGLE_CLUSTER}"), + ] + + jobs["$it-test-validation"] = { build job: individualJob, parameters: goValidationParams } + + + } catch(err) { + echo "Test Validation $it had failures: " + err + } + } + + if ("${env.TAGS}" != "") { + // need to add RSA key to jenkins before windows will work + // sh "./yq '.provisioningInput.machinePools += [{\"machinePoolConfig\": {\"windows\": true, \"quantity\": 1}}]' -i ${mainRancherConfigPath}" + sh "./yq e '.corralConfigs.corralConfigVars.aws_hostname_prefix = \"k3spro\"' -i ${mainRancherConfigPath}" + sh "./yq e '.corralConfigs.corralConfigVars.hostname = \"k3spro.qa.rancher.space\"' -i ${mainRancherConfigPath}" + sh "./yq e 'del(.corralConfigs.corralConfigVars.rancher_version)' -i ${mainRancherConfigPath}" + sh "./yq e 'del(.corralConfigs.corralConfigVars.rancher_image_tag)' -i ${mainRancherConfigPath}" + sh "./yq e 'del(.corralConfigs.corralConfigVars.kubernetes_version)' -i ${mainRancherConfigPath}" + + sh "./yq e 'del(.corralPackages.corralPackageImages.rancherha)' -i ${mainRancherConfigPath}" + + def configYaml = readFile(file: "${mainRancherConfigPath}") + + def goValidationParams = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'QASE_TEST_RUN_ID', value: "${testRunID}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'TAGS', value: "${env.TAGS}"), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_PROVISIONING}"), + ] + + jobs["provisioning-test-validation"] = { build job: individualJob, parameters: goValidationParams } + + sh "./yq e '.rancher.rancherCLI = true' -i ${mainRancherConfigPath}" + + def config2Yaml = readFile(file: "${mainRancherConfigPath}") + // This is the config for the local cluster i.e. CLI tests + def goValidation2Params = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: config2Yaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'TAGS', value: tags), + string(name: 'CLI_VERSION', value: "${CLI_VERSION}"), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_CLI}"), + ] + + jobs["provisioning-cli-validation"] = { build job: individualJob, parameters: goValidation2Params } + + sh "./yq e 'del(.rancher.rancherCLI)' -i ${mainRancherConfigPath}" + + sh "./yq e 'del(.flags.desiredflags)' -i ${mainRancherConfigPath}" + sh "./yq e '.flags.desiredflags = \"Short|Long\"' -i ${mainRancherConfigPath}" + sh "./yq e 'del(.corralRancherHA)' -i ${mainRancherConfigPath}" + + def config3Yaml = readFile(file: "${mainRancherConfigPath}") + def goValidation3Params = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: config3Yaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'TAGS', value: tags), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_CORRAL}"), + ] + + jobs["provisioning-corral-validation"] = { build job: corralJob, parameters: goValidation3Params } + } + parallel jobs + } catch(err) { + echo "Test validations had failures: " + err + } + sh "./${qaseRun} --startRun=false" + } + } catch(err) { + echo "Failures " + err + } + + stage('Cleanup Rancher Environment') { + if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") { + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + sh "docker rmi -f ${imageName}" + sh "docker volume rm -f ${validationVolume}" + error "Cleanup had failures." + } + } + } + stage('Clean Up Images and Volume') { + echo 'Cleaning test images and volume.' + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") { + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + } + sh "docker rmi -f ${imageName}" + sh "docker volume rm -f ${validationVolume}" + } + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_pre_post_upgrade b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_pre_post_upgrade new file mode 100644 index 0000000..fd5e5f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_pre_post_upgrade @@ -0,0 +1,182 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def upgradeTestContainer = "${job_name}${env.BUILD_NUMBER}-2_test" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "github.com/rancher/rancher/tests/v2/validation/${env.TEST_PACKAGE}" + def testResultsOut = "results.xml" + def upgradeTestResultsOut = "results_upgrade.xml" + def localPipelinePath = "./tests/v2/validation/pipeline/" + def testResultsJSON = "results.json" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def repo = scm.userRemoteConfigs + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + repo = [[url: "${env.REPO}"]] + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: repo + ]) + } + dir ("./") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + dir("./tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = "/go/src/github.com/rancher/rancher/tests/v2/validation/"+filename + } + + sh "./tests/v2/validation/configure.sh" + sh "./tests/v2/validation/build.sh" + } + stage('Run Validation Tests') { + try { + echo envFile + sh "docker run --name ${testContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"/go/bin/gotestsum --format standard-verbose --packages=${testsDir} --junitfile ${testResultsOut} -- ${GOTEST_TESTCASE} -timeout=${timeout} -v" + + ".${rootPath}pipeline/scripts/build_qase_reporter.sh;" + + ".${rootPath}reporter\"" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + stage('upgrade') { + upgradeParams = [ + string(name: 'RANCHER_HA_HOSTNAME', value: "${RANCHER_HA_HOSTNAME}"), + string(name: 'RANCHER_CHART_VERSION', value: "${RANCHER_CHART_VERSION}"), + string(name: 'RANCHER_HA_CERT_OPTION', value: "${RANCHER_HA_CERT_OPTION}"), + string(name: 'RANCHER_HA_KUBECONFIG', value: "${RANCHER_HA_KUBECONFIG}") + ] + build job: 'rancher-v3_ha_upgrade', parameters: upgradeParams + } + + stage ('post upgrade tests') { + try { + sh "docker run --name ${upgradeTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"/root/go/bin/gotestsum --format standard-verbose --packages=${testsDir} --junitfile ${upgradeTestResultsOut} -- ${GOTEST_TESTCASE_2} -timeout=${timeout} -v" + + ".${rootPath}pipeline/scripts/build_qase_reporter.sh;" + + ".${rootPath}reporter\"" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + stage('delete') { + CATTLE_TEST_URL = "http://${RANCHER_HA_HOSTNAME}" + deleteParams = [ + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + + ] + build job: 'rancher-v3_ha_delete', parameters: deleteParams + } + + stage('Test Report') { + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + sh "docker cp ${upgradeTestContainer}:${rootPath}${upgradeTestResultsOut} ." + sh "./rancher/tests/v2/validation/pipeline/reporter" + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + step([$class: 'JUnitResultArchiver', testResults: "**/${upgradeTestResultsOut}"]) + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker stop ${upgradeTestContainer}" + sh "docker rm -v ${upgradeTestContainer}" + sh "docker rmi -f ${imageName}" + } + } catch(err) { + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker stop ${upgradeTestContainer}" + sh "docker rm -v ${upgradeTestContainer}" + sh "docker rmi -f ${imageName}" + } // catch + } // dir + } // withEnv + } // withCredentials + } // withFolderProperties + } // wrap +}// node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_support_matrix_os b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_support_matrix_os new file mode 100644 index 0000000..dac7373 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_support_matrix_os @@ -0,0 +1,250 @@ +#!groovy +node { + def rootPath = "/go/src/github.com/rancher/rancher/tests/v2/validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "github.com/rancher/rancher/tests/v2/validation/${env.TEST_PACKAGE}" + def testResultsOut = "results.xml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir ("./") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v2/validation/configure.sh" + + } + stage('Run Jobs') { + dir("./tests/v2/validation/") { + // install yq + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout: true, script: 'chmod a+x ./yq' + def amis = env.RANCHER_AMI_LIST + + def amisList = amis.split(',') + for (int i = 0; i < amisList.size(); i++) { + String ami + String sshUser + if (amisList[i].contains(':')){ + def data = amisList[i].split(':') + ami = data[0] + sshUser = data[1] + } else { + ami = amisList[i] + sshUser = 'ec2-user' + } + + // RKE1 Node Driver: awsNodeTemplate + + def awsNodeTemplateFilename = "awsNodeTemplate.yaml" + def awsNodeTemplate = env.RANCHER_RKE1_NODE_CONFIG + + writeFile file: awsNodeTemplateFilename, text: awsNodeTemplate + + sh "./yq e '.awsNodeTemplate.ami = \"$ami\"' -i awsNodeTemplate.yaml" + + sh "./yq e '.awsNodeTemplate.sshUser = \"$sshUser\"' -i awsNodeTemplate.yaml" + + def awsNodeTemplateParam = readFile(file: './awsNodeTemplate.yaml') + + echo awsNodeTemplateParam + + // RKE2 Node Driver: awsMachineConfig + + def awsMachineConfigFilename = "awsMachineConfig.yaml" + def awsMachineConfig = env.RANCHER_RKE2_NODE_CONFIG + + writeFile file: awsMachineConfigFilename, text: awsMachineConfig + + sh "./yq e '.awsMachineConfig.ami = \"$ami\"' -i awsMachineConfig.yaml" + + sh "./yq e '.awsMachineConfig.sshUser = \"$sshUser\"' -i awsMachineConfig.yaml" + + def awsMachineConfigParam = readFile(file: './awsMachineConfig.yaml') + + echo awsMachineConfigParam + + // Single custom cluster config: awsEC2Config + + def awsEC2ConfigFilename = "awsEC2Config.yaml" + def awsEC2Config = env.RANCHER_CUSTOM_CONFIG + + writeFile file: awsEC2ConfigFilename, text: awsEC2Config + + sh "./yq e '.awsEC2Configs.awsEC2Config.[0].awsAMI = \"$ami\"' -i awsEC2Config.yaml" + + sh "./yq e '.awsEC2Configs.awsEC2Config.[0].awsUser = \"$sshUser\"' -i awsEC2Config.yaml" + + def awsEC2ConfigParam = readFile(file: './awsEC2Config.yaml') + + echo awsEC2ConfigParam + + rke1NodeParams = [ + string(name: 'TIMEOUT', value: "${env.TIMEOUT}"), + text(name: 'CONFIG', value: awsNodeTemplateParam), + string(name: 'TEST_PACKAGE', value: "${env.RANCHER_RKE1_TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${env.RANCHER_RKE1_NODE_GOTEST_TESTCASE}"), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + ] + rke2NodeParams = [ + string(name: 'TIMEOUT', value: "${env.TIMEOUT}"), + text(name: 'CONFIG', value: awsMachineConfigParam), + string(name: 'TEST_PACKAGE', value: "${env.RANCHER_RKE2_TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${env.RANCHER_RKE2_NODE_GOTEST_TESTCASE}"), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + ] + rke1CustomParams = [ + string(name: 'TIMEOUT', value: "${env.TIMEOUT}"), + text(name: 'CONFIG', value: awsEC2ConfigParam), + string(name: 'TEST_PACKAGE', value: "${env.RANCHER_RKE1_TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${env.RANCHER_RKE1_CUSTOM_GOTEST_TESTCASE}"), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + ] + rke2CustomParams = [ + string(name: 'TIMEOUT', value: "${env.TIMEOUT}"), + text(name: 'CONFIG', value: awsEC2ConfigParam), + string(name: 'TEST_PACKAGE', value: "${env.RANCHER_RKE2_TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${env.RANCHER_RKE2_CUSTOM_GOTEST_TESTCASE}"), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + ] + + jobs = [:] + + failBuild = false + failJobs =[] + + jobs["rke1node"] = { + try {build job: 'go-validation-provisioning', parameters: rke1NodeParams} + catch (err) { + echo err.toString() + failBuild = true + } + } + jobs["rke2node"] = { + try {build job: 'go-validation-provisioning', parameters: rke2NodeParams} + catch (err) { + echo err.toString() + failBuild = true + } + } + jobs["rke1custom"] = { + try {build job: 'go-validation-provisioning', parameters: rke1CustomParams} + catch (err) { + echo err.toString() + failBuild = true + } + } + jobs["rke2custom"] = { + try {build job: 'go-validation-provisioning', parameters: rke2CustomParams} + catch (err) { + echo err.toString() + failBuild = true + } + } + + parallel jobs + + } + + if (failBuild) { + throw new Exception("some jobs failed") + } + }// + }// run jobs + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_vpn b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_vpn new file mode 100644 index 0000000..f259639 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/Jenkinsfile_vpn @@ -0,0 +1,139 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "github.com/rancher/rancher/tests/v2/validation/${env.TEST_PACKAGE}" + def testResultsOut = "results.xml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def repo = scm.userRemoteConfigs + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + repo = [[url: "${env.REPO}"]] + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'EXTERNAL_ENCODED_VPN', variable: 'EXTERNAL_ENCODED_VPN'), + string(credentialsId: 'VPN_ENCODED_LOGIN', variable: 'VPN_ENCODED_LOGIN'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: repo + ]) + } + dir ("./") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + dir("./tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = rootPath+filename + } + + sh "./tests/v2/validation/configure.sh" + sh "./tests/v2/validation/build.sh" + } + def runArgs = "" + if (env.EXTERNAL_ENCODED_VPN) { + runArgs = runArgs + "openvpn --daemon --config external.ovpn && sleep 10 && " + } + runArgs = runArgs + "/root/go/bin/gotestsum --format standard-verbose --packages=${testsDir} --junitfile ${testResultsOut} -- -tags=${TAGS} ${GOTEST_TESTCASE} -timeout=${timeout} -v" + stage('Run Validation Tests') { + sh "docker run --name ${testContainer} -t --env-file ${envFile} --privileged " + + "${imageName} sh -c \"${runArgs}\"" + } + stage('Test Report') { + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi -f ${imageName}" + } + } catch(err) { + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi -f ${imageName}" + } // catch error + } // dir + } // withEnv + } // creds +} // folder properties +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/README.md new file mode 100644 index 0000000..47cb4ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/README.md @@ -0,0 +1,21 @@ +# LastLogin +Last login introduces a new label in user resource and LastLogin field in user attribute resource. Last login is now updated based on the user login time. + +## Pre-requisites +- This test runs all the validations on a local cluster. This can be run on an rancher server without any downstream clusters. +- We need default admin password to be updated in the config below. Tests use the admin password to login to rancher as default admin. + +## Getting Started +Your GO suite should be set to `-run ^Test<>TestSuite$`. To run the last_login_test.go, set the GO suite to `-run ^TestLastLoginTestSuite$` You can find specific tests by checking the test file you plan to run. +In your config file, set the following: + +```json +"rancher": { + "host": "rancher_server_address", + "adminToken": "rancher_admin_token", + "insecure": true/optional, + "cleanup": false/optional, + "adminPassword": "" +} +``` + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/last_login_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/last_login_test.go new file mode 100644 index 0000000..9035f4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/lastlogin/last_login_test.go @@ -0,0 +1,276 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package lastlogin + +import ( + "regexp" + "strconv" + "testing" + "time" + + "github.com/rancher/rancher/tests/v2/actions/auth" + "github.com/rancher/shepherd/clients/rancher" + users "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type LastLoginTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (ll *LastLoginTestSuite) TearDownSuite() { + ll.session.Cleanup() +} + +func (ll *LastLoginTestSuite) SetupSuite() { + testSession := session.NewSession() + ll.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(ll.T(), err) + + ll.client = client +} + +func (ll *LastLoginTestSuite) TestLastLoginAdmin() { + adminId, err := users.GetUserIDByName(ll.client, "admin") + require.NoError(ll.T(), err) + adminUser, err := ll.client.Management.User.ByID(adminId) + adminUser.Password = ll.client.RancherConfig.AdminPassword + + adminRelogin, err := auth.GetUserAfterLogin(ll.client, *adminUser) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(adminRelogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(adminId, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) +} + +func (ll *LastLoginTestSuite) TestLastLoginStandardUser() { + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) +} + +func (ll *LastLoginTestSuite) TestReLoginUpdatesLastLogin() { + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + lastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) + + userLogin, err = auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + reLoginLastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + reLoginUserAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + assert.Equal(ll.T(), reLoginLastLoginTime, reLoginUserAttributes.LastLogin.Time) + + if reLoginLastLoginTime.Before(lastLoginTime) || reLoginLastLoginTime.Equal(lastLoginTime) { + require.FailNow(ll.T(), "Last login time after user relogs should be greater than initial lastlogin time.") + } +} + +func (ll *LastLoginTestSuite) TestUserLastLoginNotUpdated() { + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + expectedErrMessage := "userattributes.management.cattle.io \"" + regexp.QuoteMeta(newUser.ID+"\" not found") + + user, err := ll.client.WranglerContext.Mgmt.User().Get(newUser.ID, v1.GetOptions{}) + + _, exists := user.Labels[auth.LastloginLabel] + if exists { + ll.Assert().Fail("Expected the lastlogin to be not present and empty") + } + + _, err = ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + require.Error(ll.T(), err) + require.Contains(ll.T(), err.Error(), expectedErrMessage) +} + +func (ll *LastLoginTestSuite) TestLastLoginNotUpdatedWhenLoginFails() { + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + lastLoginTimePreFailure, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + + newUser.Password = password.GenerateUserPassword("testpass-") + _, err = auth.GetUserAfterLogin(ll.client, *newUser) + require.Error(ll.T(), err) + k8sErrors.IsUnauthorized(err) + + userDetails, err := ll.client.WranglerContext.Mgmt.User().Get(newUser.ID, v1.GetOptions{}) + require.NoError(ll.T(), err) + lastLoginTimePostFailure, err := auth.GetLastLoginTime(userDetails.Labels) + require.NoError(ll.T(), err) + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + require.NoError(ll.T(), err) + + assert.Equal(ll.T(), lastLoginTimePostFailure, userAttributes.LastLogin.Time) + require.Equal(ll.T(), lastLoginTimePreFailure, lastLoginTimePostFailure) +} + +func (ll *LastLoginTestSuite) TestStandardUserCantUpdateLastLogin() { + + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + updatedUserLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(updatedUserLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + lastLoginTime = lastLoginTime.Add(48 * time.Hour) + newLastLogin := strconv.FormatInt(lastLoginTime.Unix(), 10) + updatedUserLogin.Labels[auth.LastloginLabel] = newLastLogin + + standardClient, err := ll.client.AsUser(newUser) + require.NoError(ll.T(), err) + + _, err = standardClient.WranglerContext.Mgmt.User().Update(updatedUserLogin) + require.Error(ll.T(), err) + k8sErrors.IsForbidden(err) + +} + +func (ll *LastLoginTestSuite) TestStandardUserCantDeleteLastLogin() { + + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + updatedUserLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + + _, exists := updatedUserLogin.Labels[auth.LastloginLabel] + if !exists { + ll.Assert().Fail("Expected the lastlogin to be not present and empty") + } + delete(updatedUserLogin.Labels, auth.LastloginLabel) + + standardClient, err := ll.client.AsUser(newUser) + require.NoError(ll.T(), err) + + _, err = standardClient.WranglerContext.Mgmt.User().Update(updatedUserLogin) + require.Error(ll.T(), err) + k8sErrors.IsForbidden(err) +} + +func (ll *LastLoginTestSuite) TestAdminCanDeleteLastLogin() { + + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "admin") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + updatedUserLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + + _, exists := updatedUserLogin.Labels[auth.LastloginLabel] + if !exists { + ll.Assert().Fail("Expected the lastlogin to be not present and empty") + } + delete(updatedUserLogin.Labels, auth.LastloginLabel) + + _, err = ll.client.WranglerContext.Mgmt.User().Update(updatedUserLogin) + require.NoError(ll.T(), err) +} + +func (ll *LastLoginTestSuite) TestConcurrentLoginAsMultipleUsers() { + + newUser1, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser1.Username) + + newUser2, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser2.Username) + + go func() { + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser1) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser1.ID, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) + }() + go func() { + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser2) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser2.ID, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) + }() +} + +func (ll *LastLoginTestSuite) TestConcurrentRefreshAndLogin() { + + newUser, err := users.CreateUserWithRole(ll.client, users.UserConfig(), "user") + require.NoError(ll.T(), err) + ll.T().Logf("Created a standard user: %v", newUser.Username) + + go func() { + userLogin, err := auth.GetUserAfterLogin(ll.client, *newUser) + require.NoError(ll.T(), err) + + lastLoginTime, err := auth.GetLastLoginTime(userLogin.Labels) + require.NoError(ll.T(), err) + require.False(ll.T(), lastLoginTime.IsZero(), "Last login is empty") + + userAttributes, err := ll.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + assert.Equal(ll.T(), lastLoginTime, userAttributes.LastLogin.Time) + }() + + go func() { + err = ll.client.Management.User.ActionRefreshauthprovideraccess(newUser) + require.NoError(ll.T(), err) + }() +} + +func TestLastLoginTestSuite(t *testing.T) { + suite.Run(t, new(LastLoginTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap.go new file mode 100644 index 0000000..035df8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap.go @@ -0,0 +1,43 @@ +package auth + +import ( + "context" + "time" + + "github.com/rancher/shepherd/clients/rancher" + v3 "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + passwordSecretID = "cattle-global-data/openldapconfig-serviceaccountpassword" + authProvCleanupAnnotationKey = "management.cattle.io/auth-provider-cleanup" + authProvCleanupAnnotationValLocked = "rancher-locked" + authProvCleanupAnnotationValUnlocked = "unlocked" +) + +func waitUntilAnnotationIsUpdated(client *rancher.Client) (*v3.AuthConfig, error) { + ldapConfig, err := client.Management.AuthConfig.ByID("openldap") + if err != nil { + return nil, err + } + + err = kwait.PollUntilContextTimeout(context.TODO(), 500*time.Millisecond, 2*time.Minute, true, func(context.Context) (bool, error) { + newLDAPConfig, err := client.Management.AuthConfig.ByID("openldap") + if err != nil { + return false, nil + } + + if ldapConfig.Annotations[authProvCleanupAnnotationKey] != newLDAPConfig.Annotations[authProvCleanupAnnotationKey] { + ldapConfig = newLDAPConfig + return true, nil + } + + return false, nil + }) + if err != nil { + return nil, err + } + + return ldapConfig, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap_test.go new file mode 100644 index 0000000..dd4b151 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/openldap_test.go @@ -0,0 +1,94 @@ +package auth + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/auth" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + corev1 "k8s.io/api/core/v1" +) + +type OLDAPTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client +} + +func (o *OLDAPTestSuite) TearDownSuite() { + o.session.Cleanup() +} + +func (o *OLDAPTestSuite) SetupSuite() { + testSession := session.NewSession() + o.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(o.T(), err) + + o.client = client +} + +func (o *OLDAPTestSuite) TestEnableOLDAP() { + subSession := o.session.NewSession() + defer subSession.Cleanup() + + client, err := o.client.WithSession(subSession) + require.NoError(o.T(), err) + + a, err := auth.NewAuth(client, subSession) + require.NoError(o.T(), err) + + err = a.OLDAP.Enable() + require.NoError(o.T(), err) + + ldapConfig, err := client.Management.AuthConfig.ByID("openldap") + require.NoError(o.T(), err) + + assert.Truef(o.T(), ldapConfig.Enabled, "Checking if Open LDAP is enabled") + + assert.Equalf(o.T(), authProvCleanupAnnotationValUnlocked, ldapConfig.Annotations[authProvCleanupAnnotationKey], "Checking if annotation set to unlocked for LDAP Auth Config") + + passwordSecretResp, err := client.Steve.SteveType("secret").ByID(passwordSecretID) + assert.NoErrorf(o.T(), err, "Checking open LDAP config secret for service account password exists") + + passwordSecret := &corev1.Secret{} + err = v1.ConvertToK8sType(passwordSecretResp.JSONResp, passwordSecret) + require.NoError(o.T(), err) + + assert.Equal(o.T(), a.OLDAP.Config.ServiceAccount.Password, string(passwordSecret.Data["serviceaccountpassword"]), "Checking if serviceaccountpassword value is equal to the given") +} + +func (o *OLDAPTestSuite) TestDisableOLDAP() { + subSession := o.session.NewSession() + defer subSession.Cleanup() + + client, err := o.client.WithSession(subSession) + require.NoError(o.T(), err) + + a, err := auth.NewAuth(client, subSession) + require.NoError(o.T(), err) + + err = a.OLDAP.Disable() + require.NoError(o.T(), err) + + ldapConfig, err := waitUntilAnnotationIsUpdated(client) + require.NoError(o.T(), err) + + assert.Falsef(o.T(), ldapConfig.Enabled, "Checking if Open LDAP is disabled") + + assert.Equalf(o.T(), authProvCleanupAnnotationValLocked, ldapConfig.Annotations[authProvCleanupAnnotationKey], "Checking if annotation set to locked for LDAP Auth Config") + + _, err = client.Steve.SteveType("secret").ByID(passwordSecretID) + assert.Errorf(o.T(), err, "Checking open LDAP config secret for service account password does not exist") + assert.Containsf(o.T(), err.Error(), "404", "Checking open LDAP config secret for service account password error returns 404") +} + +func TestOLDAPSuite(t *testing.T) { + suite.Run(t, new(OLDAPTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/README.md new file mode 100644 index 0000000..a5c96e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/README.md @@ -0,0 +1,28 @@ +# Userretention + +The User Retention feature in Rancher allows administrators to manage inactive users by automatically disabling and deleting them based on predefined settings and a user retention cron job. This functionality is implemented based on the user's last login timestamp. The tests included in this package focus on validating the behavior of the User Retention feature, including updating retention settings and verifying the proper disabling and deletion of inactive users. + +## Pre-requisites + +- The tests are designed to be executed on a local cluster. They can be run on a Rancher server without any downstream clusters. +- Update the default admin password in the configuration file. The tests rely on the admin password to authenticate and perform actions as the default admin user in Rancher. + +## Getting Started + +Your GO suite should be set to `-run ^Test<>TestSuite$`. + +To run the userretention_test.go, set the GO suite to `-run ^TestUserRetentionSettingsSuite$` You can find specific tests by checking the test file you plan to run. +To run the userretention_disable_user_test.go, set the GO suite to `-run ^TestURDisableUserSuite$` You can find specific tests by checking the test file you plan to run. +To run the userretention_delete_user_test.go, set the GO suite to `-run ^TestURDeleteUserSuite$` You can find specific tests by checking the test file you plan to run. + +In your config file, set the following: + +```json +"rancher": { + "host": "rancher_server_address", + "adminToken": "rancher_admin_token", + "insecure": true/optional, + "cleanup": false/optional, + "adminPassword": "" +} +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention.go new file mode 100644 index 0000000..253b9ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention.go @@ -0,0 +1,103 @@ +package userretention + +import ( + "context" + "fmt" + "time" + + "github.com/rancher/rancher/tests/v2/actions/auth" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/users" + "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + disableInactiveUserAfter = "disable-inactive-user-after" + deleteInactiveUserAfter = "delete-inactive-user-after" + userRetentionCron = "user-retention-cron" + userRetentionDryRun = "user-retention-dry-run" + lastloginLabel = "cattle.io/last-login" + defaultWaitDuration = 70 * time.Second + pollInterval = 10 * time.Second + isActive = true + isInActive = false + webhookErrorMessage = "admission webhook \"rancher.cattle.io.settings.management.cattle.io\" denied the request: value: Invalid value:" +) + +func setupUserRetentionSettings(client *rancher.Client, disableAfterValue string, deleteAfterValue string, userRetentionCronValue string, dryRunValue string) error { + logrus.Info("Setting up user retention settings TO : ") + logrus.Infof("DisableAfterValue as %s, DeleteAfterValue as %s, UserRetentionCronValue as %s, DryRunValue as %s", disableAfterValue, deleteAfterValue, userRetentionCronValue, dryRunValue) + err := updateUserRetentionSettings(client, disableInactiveUserAfter, disableAfterValue) + if err != nil { + return fmt.Errorf("failed to update disable-inactive-user-after setting: %w", err) + } + err = updateUserRetentionSettings(client, deleteInactiveUserAfter, deleteAfterValue) + if err != nil { + return fmt.Errorf("failed to update delete-inactive-user-after setting: %w", err) + } + + err = updateUserRetentionSettings(client, userRetentionCron, userRetentionCronValue) + if err != nil { + return fmt.Errorf("failed to update user-retention-cron setting: %w", err) + } + err = updateUserRetentionSettings(client, userRetentionDryRun, dryRunValue) + if err != nil { + return fmt.Errorf("failed to update user-retention-dry-run setting: %w", err) + } + logrus.Info("User retention settings setup completed") + return nil +} + +func updateUserRetentionSettings(client *rancher.Client, settingName string, settingValue string) error { + logrus.Infof("Updating setting: %s, value: %s", settingName, settingValue) + setting, err := client.WranglerContext.Mgmt.Setting().Get(settingName, v1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get setting %s: %w", settingName, err) + } + + setting.Value = settingValue + _, err = client.WranglerContext.Mgmt.Setting().Update(setting) + if err != nil { + return fmt.Errorf("failed to update setting %s: %w", settingName, err) + } + return nil +} + +func pollUserStatus(rancherClient *rancher.Client, userID string, expectedStatus bool) error { + logrus.Infof("Polling user status for user %s, expected status: %v", userID, expectedStatus) + ctx, cancel := context.WithTimeout(context.Background(), defaultWaitDuration) + defer cancel() + + adminID, err := users.GetUserIDByName(rancherClient, "admin") + if err != nil { + return fmt.Errorf("failed to get admin user ID: %v", err) + } + adminUser, err := rancherClient.Management.User.ByID(adminID) + if err != nil { + return fmt.Errorf("failed to get admin user: %v", err) + } + adminUser.Password = rancherClient.RancherConfig.AdminPassword + + return wait.PollUntilContextTimeout(ctx, pollInterval, defaultWaitDuration, true, func(ctx context.Context) (bool, error) { + logrus.Info("Logging in with default admin user") + _, err := auth.GetUserAfterLogin(rancherClient, *adminUser) + if err != nil { + return false, fmt.Errorf("failed to login with admin user: %v", err) + } + + logrus.Info("Searching for the user status using the admin client") + user, err := rancherClient.Management.User.ByID(userID) + if err != nil { + return false, fmt.Errorf("failed to get user by ID: %v", err) + } + if user.Enabled == nil { + return false, fmt.Errorf("user.Enabled is nil") + } + + currentStatus := *user.Enabled + logrus.Infof("Current user status: %v, Expected status: %v", currentStatus, expectedStatus) + return currentStatus == expectedStatus, nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_delete_user_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_delete_user_test.go new file mode 100644 index 0000000..300e330 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_delete_user_test.go @@ -0,0 +1,248 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package userretention + +import ( + "testing" + "time" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/tests/v2/actions/auth" + "github.com/rancher/rancher/tests/v2/actions/rbac" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + rbac1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type URDeleteTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (ur *URDeleteTestSuite) SetupSuite() { + logrus.Info("Setting up URDeleteTestSuite") + ur.session = session.NewSession() + + logrus.Info("Creating new Rancher client") + client, err := rancher.NewClient("", ur.session) + require.NoError(ur.T(), err) + ur.client = client +} + +func (ur *URDeleteTestSuite) TearDownSuite() { + logrus.Info("Tearing down URDeleteTestSuite") + ur.session.Cleanup() +} + +func (ur *URDeleteTestSuite) TestDefaultAdminUserIsNotDeleted() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "", "400h", "*/1 * * * *", "false") + + logrus.Info("Getting admin user details") + adminID, err := users.GetUserIDByName(ur.client, "admin") + require.NoError(ur.T(), err) + adminUser, err := ur.client.Management.User.ByID(adminID) + require.NoError(ur.T(), err) + adminUser.Password = ur.client.RancherConfig.AdminPassword + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(adminUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DeleteAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Attempting initial login") + _, err = auth.GetUserAfterLogin(ur.client, *adminUser) + require.NoError(ur.T(), err) + + logrus.Info("Waiting for default duration") + time.Sleep(defaultWaitDuration) + + logrus.Info("Attempting login after wait period") + _, err = auth.GetUserAfterLogin(ur.client, *adminUser) + require.NoError(ur.T(), err) +} + +func (ur *URDeleteTestSuite) TestAdminUserGetDeleted() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "", "400h", "*/1 * * * *", "false") + + logrus.Info("Creating new admin user") + newAdminUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "admin") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newAdminUser) + require.NoError(ur.T(), err) + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newAdminUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DeleteAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Waiting for default duration") + pollUserStatus(ur.client, newAdminUser.ID, isInActive) + + logrus.Info("Attempting login after wait period") + _, err = auth.GetUserAfterLogin(ur.client, *newAdminUser) + assert.ErrorContains(ur.T(), err, "401 Unauthorized") + + logrus.Info("Checking bindings after user deletion") + bindingsAfter, err := rbac.GetBindings(ur.client, newAdminUser.ID) + require.NoError(ur.T(), err) + assert.Empty(ur.T(), bindingsAfter["RoleBindings"], "Expected no RoleBindings after user deletion") + assert.Equal(ur.T(), 0, len(bindingsAfter["RoleBindings"].([]rbac1.RoleBinding)), "RoleBindings slice should be empty after user deletion") + + logrus.Info("Checking global role bindings after user deletion") + globalRoleBindingsAfter, err := ur.client.Management.GlobalRoleBinding.List(&types.ListOpts{ + Filters: map[string]interface{}{ + "userId": newAdminUser.ID, + }, + }) + require.NoError(ur.T(), err) + assert.Empty(ur.T(), globalRoleBindingsAfter.Data, "Expected no GlobalRoleBindings after user deletion") +} + +func (ur *URDeleteTestSuite) TestStandardUserGetDeleted() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "", "400h", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newStdUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + + logrus.Info("Logging in with new standard user") + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newStdUser) + require.NoError(ur.T(), err) + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newStdUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DeleteAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Polling user status to disable") + pollUserStatus(ur.client, newStdUser.ID, isInActive) + + logrus.Info("Attempting login after wait period") + _, err = auth.GetUserAfterLogin(ur.client, *newStdUser) + assert.ErrorContains(ur.T(), err, "401 Unauthorized") + + logrus.Info("Checking bindings after user deletion") + bindingsAfter, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err) + assert.Empty(ur.T(), bindingsAfter["RoleBindings"], "Expected no RoleBindings after user deletion") + assert.Equal(ur.T(), 0, len(bindingsAfter["RoleBindings"].([]rbac1.RoleBinding)), "RoleBindings slice should be empty after user deletion") + + logrus.Info("Checking global role bindings after user deletion") + globalRoleBindingsAfter, err := ur.client.Management.GlobalRoleBinding.List(&types.ListOpts{ + Filters: map[string]interface{}{ + "userId": newStdUser.ID, + }, + }) + require.NoError(ur.T(), err) + assert.Empty(ur.T(), globalRoleBindingsAfter.Data, "Expected no GlobalRoleBindings after user deletion") +} + +func (ur *URDeleteTestSuite) TestUserIsNotDeletedWithBlankSettings() { + logrus.Info("Setting up user retention settings with blank values") + setupUserRetentionSettings(ur.client, "", "400h", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + + logrus.Info("Logging in with new user") + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newUser) + require.NoError(ur.T(), err) + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DeleteAfter = nil + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Waiting for default duration") + time.Sleep(defaultWaitDuration) + + logrus.Info("Verifying user status after wait period") + userReLogin1, err := ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin1).Enabled) +} + +func (ur *URDeleteTestSuite) TestUserIsNotGetDeletedWithDryRun() { + logrus.Info("Setting up user retention settings with dry run") + setupUserRetentionSettings(ur.client, "", "400h", "*/1 * * * *", "true") + + logrus.Info("Creating new standard user") + newUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + + logrus.Info("Logging in with new user") + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newUser) + require.NoError(ur.T(), err) + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DeleteAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Getting initial bindings") + bindingsBefore, _ := rbac.GetBindings(ur.client, newUser.ID) + + logrus.Info("Waiting for default duration") + time.Sleep(2 * defaultWaitDuration) + + logrus.Info("Verifying user status after wait period") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + logrus.Info("Checking bindings after wait period") + bindingsAfter, _ := rbac.GetBindings(ur.client, newUser.ID) + assert.Equal(ur.T(), bindingsBefore, bindingsAfter, "RoleBindings") + assert.Equal(ur.T(), bindingsBefore, bindingsAfter, "ClusterRoleBindings") + assert.Equal(ur.T(), bindingsBefore, bindingsAfter, "GlobalRoleBindings") + assert.Equal(ur.T(), bindingsBefore, bindingsAfter, "ClusterRoleTemplateBindings") + require.NoError(ur.T(), err) + + logrus.Info("Resetting user retention dry run setting") + updateUserRetentionSettings(ur.client, userRetentionDryRun, "false") +} + +func TestURDeleteUserSuite(t *testing.T) { + suite.Run(t, new(URDeleteTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_disable_user_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_disable_user_test.go new file mode 100644 index 0000000..76f7d5a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_disable_user_test.go @@ -0,0 +1,298 @@ +package userretention + +import ( + "testing" + "time" + + "github.com/rancher/rancher/tests/v2/actions/auth" + "github.com/rancher/rancher/tests/v2/actions/rbac" + "github.com/rancher/shepherd/clients/rancher" + managementv3 "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type URDisableTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + adminClient *rancher.Client + adminUser *managementv3.User +} + +func (ur *URDisableTestSuite) SetupSuite() { + logrus.Info("Setting up URDisableTestSuite") + ur.session = session.NewSession() + + logrus.Info("Creating new Rancher client") + client, err := rancher.NewClient("", ur.session) + require.NoError(ur.T(), err) + ur.client = client +} + +func (ur *URDisableTestSuite) TearDownSuite() { + logrus.Info("Tearing down URDisableTestSuite") + if ur.adminUser != nil { + logrus.Info("Deleting admin user") + err := ur.client.Management.User.Delete(ur.adminUser) + if err != nil { + logrus.Errorf("Failed to delete admin user: %v", err) + } + } + logrus.Info("Cleaning up session") + ur.session.Cleanup() +} + +func (ur *URDisableTestSuite) assertBindingsEqual(before, after map[string]interface{}) { + assert.Equal(ur.T(), before["RoleBindings"], after["RoleBindings"], "RoleBindings mismatch") + assert.Equal(ur.T(), before["ClusterRoleBindings"], after["ClusterRoleBindings"], "ClusterRoleBindings mismatch") + assert.Equal(ur.T(), before["GlobalRoleBindings"], after["GlobalRoleBindings"], "GlobalRoleBindings mismatch") + assert.Equal(ur.T(), before["ClusterRoleTemplateBindings"], after["ClusterRoleTemplateBindings"], "ClusterRoleTemplateBindings mismatch") +} + +func (ur *URDisableTestSuite) TestDefaultAdminUserIsNotDisabled() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "false") + logrus.Info("Retrieving admin user details") + adminID, err := users.GetUserIDByName(ur.client, "admin") + require.NoError(ur.T(), err) + adminUser, err := ur.client.Management.User.ByID(adminID) + require.NoError(ur.T(), err) + adminUser.Password = ur.client.RancherConfig.AdminPassword + + logrus.Info("Attempting initial login for admin user") + _, err = auth.GetUserAfterLogin(ur.client, *adminUser) + require.NoError(ur.T(), err) + + logrus.Info("Waiting for default duration") + time.Sleep(defaultWaitDuration) + + logrus.Info("Attempting login after wait period") + _, err = auth.GetUserAfterLogin(ur.client, *adminUser) + require.NoError(ur.T(), err) +} + +func (ur *URDisableTestSuite) TestAdminUserGetDisabled() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "false") + + logrus.Info("Creating new admin user") + newAdminUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "admin") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newAdminUser) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + bindingsBefore, err := rbac.GetBindings(ur.client, newAdminUser.ID) + require.NoError(ur.T(), err, "Failed to get initial bindings") + + logrus.Info("Polling user status") + pollUserStatus(ur.client, newAdminUser.ID, isInActive) + + logrus.Info("Verifying user status after polling") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isInActive, *(userReLogin).Enabled) + + logrus.Info("Attempting login with disabled user") + _, err = auth.GetUserAfterLogin(ur.client, *newAdminUser) + assert.ErrorContains(ur.T(), err, "403 Forbidden") + bindingsAfter, err := rbac.GetBindings(ur.client, newAdminUser.ID) + require.NoError(ur.T(), err, "Failed to get final bindings") + ur.assertBindingsEqual(bindingsBefore, bindingsAfter) + +} + +func (ur *URDisableTestSuite) TestStandardUserGetDisabled() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newStdUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newStdUser) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + logrus.Info("Getting initial bindings") + bindingsBefore, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get initial bindings") + + logrus.Info("Polling user status") + pollUserStatus(ur.client, newStdUser.ID, isInActive) + + logrus.Info("Verifying user status after polling") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isInActive, *(userReLogin).Enabled) + + logrus.Info("Attempting login with disabled user") + _, err = auth.GetUserAfterLogin(ur.client, *newStdUser) + assert.ErrorContains(ur.T(), err, "403 Forbidden") + + logrus.Info("Getting final bindings") + bindingsAfter, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get final bindings") + ur.assertBindingsEqual(bindingsBefore, bindingsAfter) +} + +func (ur *URDisableTestSuite) TestDisabledUserGetEnabled() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newStdUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newStdUser) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + logrus.Info("Getting initial bindings") + bindingsBefore, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get initial bindings") + + logrus.Info("Polling user status to disable") + pollUserStatus(ur.client, newStdUser.ID, isInActive) + + logrus.Info("Verifying user status after polling") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isInActive, *(userReLogin).Enabled) + + logrus.Info("Attempting login with disabled user") + _, err = auth.GetUserAfterLogin(ur.client, *newStdUser) + assert.ErrorContains(ur.T(), err, "403 Forbidden") + + logrus.Info("Enabling the disabled user") + enabled := true + userReLogin.Enabled = &enabled + activateUser, err := ur.client.WranglerContext.Mgmt.User().Update(userReLogin) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(activateUser).Enabled) + + logrus.Info("Verifying user status after enabling") + activeUserReLogin, err := ur.client.WranglerContext.Mgmt.User().Get(activateUser.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(activeUserReLogin).Enabled) + + logrus.Info("Getting final bindings") + bindingsAfterEnabled, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get final bindings") + ur.assertBindingsEqual(bindingsBefore, bindingsAfterEnabled) +} + +func (ur *URDisableTestSuite) TestStandardUserDidNotGetDisabledWithBlankSettings() { + logrus.Info("Setting up user retention settings with blank values") + setupUserRetentionSettings(ur.client, "", "", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newUser) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + logrus.Info("Waiting for default duration") + time.Sleep(defaultWaitDuration) + + logrus.Info("Attempting login after wait period") + userReLogin, err = auth.GetUserAfterLogin(ur.client, *newUser) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) +} + +func (ur *URDisableTestSuite) TestUserDisableByUpdatingUserattributes() { + logrus.Info("Setting up user retention settings") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "false") + + logrus.Info("Creating new standard user") + newStdUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newStdUser) + require.NoError(ur.T(), err) + + logrus.Info("Getting initial bindings") + bindingsBefore, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get initial bindings") + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newStdUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DisableAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status after updating attributes") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Polling user status") + pollUserStatus(ur.client, newStdUser.ID, isInActive) + + logrus.Info("Verifying user status after polling") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isInActive, *(userReLogin).Enabled) + + logrus.Info("Attempting login with disabled user") + _, err = auth.GetUserAfterLogin(ur.client, *newStdUser) + assert.ErrorContains(ur.T(), err, "403 Forbidden") + + logrus.Info("Getting final bindings") + bindingsAfter, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get final bindings") + ur.assertBindingsEqual(bindingsBefore, bindingsAfter) +} + +func (ur *URDisableTestSuite) TestUserIsNotDisabledWithDryRun() { + logrus.Info("Setting up user retention settings with dry run") + setupUserRetentionSettings(ur.client, "10s", "", "*/1 * * * *", "true") + + logrus.Info("Creating new standard user") + newStdUser, err := users.CreateUserWithRole(ur.client, users.UserConfig(), "user") + require.NoError(ur.T(), err) + userReLogin, err := auth.GetUserAfterLogin(ur.client, *newStdUser) + require.NoError(ur.T(), err) + + logrus.Info("Getting initial bindings") + bindingsBefore, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get initial bindings") + + logrus.Info("Updating user attributes") + userAttributes, err := ur.client.WranglerContext.Mgmt.UserAttribute().Get(newStdUser.ID, v1.GetOptions{}) + require.NoError(ur.T(), err) + userAttributes.DisableAfter = &v1.Duration{Duration: time.Second * 10} + _, err = ur.client.WranglerContext.Mgmt.UserAttribute().Update(userAttributes) + require.NoError(ur.T(), err) + + logrus.Info("Verifying user status after updating attributes") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + require.NoError(ur.T(), err) + + logrus.Info("Waiting for default duration") + time.Sleep(2 * defaultWaitDuration) + + logrus.Info("Attempting login after wait period") + userReLogin, err = ur.client.WranglerContext.Mgmt.User().Get(userReLogin.Name, v1.GetOptions{}) + require.NoError(ur.T(), err) + assert.Equal(ur.T(), isActive, *(userReLogin).Enabled) + + logrus.Info("Getting final bindings") + bindingsAfter, err := rbac.GetBindings(ur.client, newStdUser.ID) + require.NoError(ur.T(), err, "Failed to get final bindings") + ur.assertBindingsEqual(bindingsBefore, bindingsAfter) + + logrus.Info("User retention settings:dry run settings back to default value") + updateUserRetentionSettings(ur.client, userRetentionDryRun, "false") +} + +func TestURDisableUserSuite(t *testing.T) { + suite.Run(t, new(URDisableTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_settings_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_settings_test.go new file mode 100644 index 0000000..8bfa0f8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/auth/userretention/userretention_settings_test.go @@ -0,0 +1,221 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package userretention + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +type UserRetentionSettingsTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (ur *UserRetentionSettingsTestSuite) SetupSuite() { + ur.session = session.NewSession() + client, err := rancher.NewClient("", ur.session) + require.NoError(ur.T(), err) + ur.client = client +} + +func (ur *UserRetentionSettingsTestSuite) TearDownSuite() { + ur.session.Cleanup() +} + +func (ur *UserRetentionSettingsTestSuite) testPositiveInputValues(settingName string, tests []struct { + value string + description string +}) { + logrus.Infof("Updating %s settings with positive values:", settingName) + for _, inputValue := range tests { + ur.T().Run(inputValue.value, func(*testing.T) { + err := updateUserRetentionSettings(ur.client, settingName, inputValue.value) + assert.NoError(ur.T(), err, "Unexpected error for input '%s'", inputValue.value) + + if err == nil { + settings, err1 := ur.client.Management.Setting.ByID(settingName) + if assert.NoError(ur.T(), err1, "Failed to retrieve settings") { + assert.Equal(ur.T(), settingName, settings.Name) + assert.Equal(ur.T(), inputValue.value, settings.Value) + } + } + logrus.Infof("%s setting is updated to %s ; %s", settingName, inputValue.value, inputValue.description) + }) + } +} + +func (ur *UserRetentionSettingsTestSuite) testNegativeInputValues(settingName string, tests []struct { + value string + description string +}) { + logrus.Infof("Updating %s settings with negative values:", settingName) + for _, inputValue := range tests { + ur.T().Run(inputValue.value, func(*testing.T) { + err := updateUserRetentionSettings(ur.client, settingName, inputValue.value) + assert.Error(ur.T(), err, "Expected an error for input '%s', but got nil", inputValue.value) + + if err != nil { + ur.validateError(err, inputValue.description) + ur.validateSettingsNotUpdated(settingName, inputValue.value) + } + logrus.Infof("Failed to update %s settings to %s; %s", settingName, inputValue.value, inputValue.description) + }) + } +} + +func (ur *UserRetentionSettingsTestSuite) validateError(err error, expectedDescription string) { + var statusErr *apierrors.StatusError + var found bool + + switch e := err.(type) { + case interface{ Unwrap() error }: + if innerErr := e.Unwrap(); innerErr != nil { + if innerWrapper, ok := innerErr.(interface{ Unwrap() error }); ok { + if deepestErr := innerWrapper.Unwrap(); deepestErr != nil { + statusErr, found = deepestErr.(*apierrors.StatusError) + } + } + } + } + + if found && statusErr != nil { + assert.Equal(ur.T(), int32(400), statusErr.ErrStatus.Code, "Status code should be 400") + assert.Equal(ur.T(), metav1.StatusReasonBadRequest, statusErr.ErrStatus.Reason, "Reason should be BadRequest") + assert.Contains(ur.T(), statusErr.ErrStatus.Message, expectedDescription, "Error should contain the expected description") + } else { + errMsg := err.Error() + assert.Contains(ur.T(), errMsg, "denied the request", "Error should mention denied request") + assert.Contains(ur.T(), errMsg, expectedDescription, "Error should contain the expected description") + } +} + +func (ur *UserRetentionSettingsTestSuite) validateSettingsNotUpdated(settingName, inputValue string) { + settings, err := ur.client.Management.Setting.ByID(settingName) + if assert.NoError(ur.T(), err, "Failed to retrieve settings") { + assert.Equal(ur.T(), settingName, settings.Name) + assert.NotEqual(ur.T(), inputValue, settings.Value) + } +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForDisableInactiveUserAfterWithPositiveInputValues() { + tests := []struct { + value string + description string + }{ + {"", "No action - users will not be deactivated"}, + {"0s", "Users will be deactivated after 0s"}, + {"0m", "Users will be deactivated after 0m"}, + {"0h", "Users will be deactivated after 0h"}, + {"10s", "Users will be deactivated after 10s"}, + {"10m", "Users will be deactivated after 10m"}, + {"20h", "Users will be deactivated after 20h"}, + {"10000s", "Users will be deactivated after 10000s"}, + {"10000m", "Users will be deactivated after 10000m"}, + {"10000h", "Users will be deactivated after 10000h"}, + } + ur.testPositiveInputValues(disableInactiveUserAfter, tests) +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForDisableInactiveUserAfterWithNegativeInputValues() { + tests := []struct { + value string + description string + }{ + {"10", "Invalid value: \"10\": time: missing unit in duration \"10\""}, + {"10S", "Invalid value: \"10S\": time: unknown unit \"S\" in duration \"10S\""}, + {"10M", "Invalid value: \"10M\": time: unknown unit \"M\" in duration \"10M\""}, + {"10H", "Invalid value: \"10H\": time: unknown unit \"H\" in duration \"10H\""}, + {"10sec", "Invalid value: \"10sec\": time: unknown unit \"sec\" in duration \"10sec\""}, + {"10min", "Invalid value: \"10min\": time: unknown unit \"min\" in duration \"10min\""}, + {"20hour", "Invalid value: \"20hour\": time: unknown unit \"hour\" in duration \"20hour\""}, + {"1d", "Invalid value: \"1d\": time: unknown unit \"d\" in duration \"1d\""}, + {"-20m", "Invalid value: \"-20m\": negative duration"}, + {"tens", "Invalid value: \"tens\": time: invalid duration \"tens\""}, + } + ur.testNegativeInputValues(disableInactiveUserAfter, tests) +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForDeleteInactiveUserAfterWithPositiveInputValues() { + tests := []struct { + value string + description string + }{ + {"", "No action - users will not be deleted"}, + {"100000000s", "Users will delete after 100000000s"}, + {"200000m", "Users will delete after 200000m"}, + {"10000h", "Users will delete after 10000h"}, + } + ur.testPositiveInputValues(deleteInactiveUserAfter, tests) +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForDeleteInactiveUserAfterWithNegativeInputValues() { + tests := []struct { + value string + description string + }{ + {"10", "Invalid value: \"10\": time: missing unit in duration \"10\""}, + {"10s", "Invalid value: \"10s\": must be at least 336h0m0s"}, + {"10m", "Invalid value: \"10m\": must be at least 336h0m0s"}, + {"10h", "Invalid value: \"10h\": must be at least 336h0m0s"}, + {"10S", "Invalid value: \"10S\": time: unknown unit \"S\" in duration \"10S\""}, + {"10M", "Invalid value: \"10M\": time: unknown unit \"M\" in duration \"10M\""}, + {"10H", "Invalid value: \"10H\": time: unknown unit \"H\" in duration \"10H\""}, + {"10sec", "Invalid value: \"10sec\": time: unknown unit \"sec\" in duration \"10sec\""}, + {"10min", "Invalid value: \"10min\": time: unknown unit \"min\" in duration \"10min\""}, + {"20hour", "Invalid value: \"20hour\": time: unknown unit \"hour\" in duration \"20hour\""}, + {"1d", "Invalid value: \"1d\": time: unknown unit \"d\" in duration \"1d\""}, + {"-20m", "Invalid value: \"-20m\": negative duration"}, + } + ur.testNegativeInputValues(deleteInactiveUserAfter, tests) +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForUserRetentionCronWithPositiveInputValues() { + tests := []struct { + value string + description string + }{ + {"0 * * * *", "every 1 hour"}, + {"0 0 * * *", "every 1 day"}, + {"*/5 * * * *", "every 5 mins"}, + {"*/1 * * * *", "every min"}, + {"* * * * *", "every min"}, + {"30/1 * * * *", "every 30 sec"}, + {"0-5 14 * * *", "every minute starting at 2:00 PM and ending at 2:05 PM, every day"}, + {"0 0 1,2 * *", "at midnight of 1st, 2nd day of each month"}, + {"0 0 1,2 * 3", "at midnight of 1st, 2nd day of each month, and each Wednesday"}, + } + ur.testPositiveInputValues(userRetentionCron, tests) +} + +func (ur *UserRetentionSettingsTestSuite) TestUpdateSettingsForUserRetentionCronWithNegativeInputValues() { + tests := []struct { + value string + description string + }{ + {"* * * * * *", "Invalid value: \"* * * * * *\": Expected exactly 5 fields, found 6: * * * * * *"}, + {"*/-1 * * * *", "Invalid value: \"*/-1 * * * *\": Negative number (-1) not allowed: -1"}, + {"60/1 * * * *", "Invalid value: \"60/1 * * * *\": Beginning of range (60) beyond end of range (59): 60/1"}, + {"-30/1 * * * *", "Invalid value: \"-30/1 * * * *\": Failed to parse int from : strconv.Atoi: parsing \"\": invalid syntax"}, + {"(*/1) * * * *", "Invalid value: \"(*/1) * * * *\": Failed to parse int from (*: strconv.Atoi: parsing \"(*\": invalid syntax"}, + {"10min", "Invalid value: \"10min\": Expected exactly 5 fields, found 1: 10min"}, + {"* * * * * */2", "Invalid value: \"* * * * * */2\": Expected exactly 5 fields, found 6: * * * * * */2"}, + {"1d", "Invalid value: \"1d\": Expected exactly 5 fields, found 1: 1d"}, + {"-20m", "Invalid value: \"-20m\": Expected exactly 5 fields, found 1: -20m"}, + } + ur.testNegativeInputValues(userRetentionCron, tests) +} + +func TestUserRetentionSettingsSuite(t *testing.T) { + suite.Run(t, new(UserRetentionSettingsTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/build.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/build.sh new file mode 100755 index 0000000..6cca49f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" +CLI_VERSION="${CLI_VERSION:-}" +EXTERNAL_ENCODED_VPN="${EXTERNAL_ENCODED_VPN:-}" +VPN_ENCODED_LOGIN="${VPN_ENCODED_LOGIN:-}" + +TRIM_JOB_NAME=$(basename "$JOB_NAME") + +if [ "false" != "${DEBUG}" ]; then + echo "Environment:" + env | sort +fi + +count=0 +while [[ 3 -gt $count ]]; do + docker build . -f tests/v2/validation/Dockerfile.validation --build-arg CLI_VERSION="$CLI_VERSION" --build-arg EXTERNAL_ENCODED_VPN="$EXTERNAL_ENCODED_VPN" --build-arg VPN_ENCODED_LOGIN="$VPN_ENCODED_LOGIN" -t rancher-validation-"${TRIM_JOB_NAME}""${BUILD_NUMBER}" + + if [[ $? -eq 0 ]]; then break; fi + count=$(($count + 1)) + echo "Repeating failed Docker build ${count} of 3..." +done \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/README.md new file mode 100644 index 0000000..88dc20c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/README.md @@ -0,0 +1,43 @@ +# Certificate Rotation + +For certificate rotation, the test has only been tested on RKE2. That does not mean RKE1 or K3S are unsupported, they just have not been tested. These tests are designed to accept an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, you should create one first before running these tests. + +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + clusterName: "cluster_to_run_tests_on" + insecure: true/optional + cleanup: false/optional +``` + +Typically, a cluster with the following 3 pools is used for testing: +```yaml +{ + { + ControlPlane: true, + Quantity: 1, + }, + { + Etcd: true, + Quantity: 1, + }, + { + Worker: true, + Quantity: 1, + }, +} +``` + +These tests utilize Go build tags. Due to this, see the below example on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/certrotation --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCertRotation/TestCertRotation"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation.go new file mode 100644 index 0000000..9a91b67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation.go @@ -0,0 +1,383 @@ +package certrotation + +import ( + "context" + "errors" + "io" + "net/http" + "regexp" + "strings" + + "github.com/rancher/norman/types" + apiv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/sshkeys" + "github.com/rancher/shepherd/pkg/nodes" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + namespace = "fleet-default" + provisioningSteveResourceType = "provisioning.cattle.io.cluster" + machineSteveResourceType = "cluster.x-k8s.io.machine" + machineSteveAnnotation = "cluster.x-k8s.io/machine" + etcdLabel = "node-role.kubernetes.io/etcd" + clusterLabel = "cluster.x-k8s.io/cluster-name" + certFileExtension = ".crt" + pemFileExtension = ".pem" + + privateKeySSHKeyRegExPattern = `-----BEGIN RSA PRIVATE KEY-{3,}\n([\s\S]*?)\n-{3,}END RSA PRIVATE KEY-----` +) + +// rotateCerts rotates the certificates in a cluster +func rotateCerts(client *rancher.Client, clusterName string) error { + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + if err != nil { + return err + } + + id, err := clusters.GetV1ProvisioningClusterByName(client, clusterName) + if err != nil { + return err + } + + cluster, err := adminClient.Steve.SteveType(provisioningSteveResourceType).ByID(id) + if err != nil { + return err + } + + clusterSpec := &apiv1.ClusterSpec{} + err = v1.ConvertToK8sType(cluster.Spec, clusterSpec) + if err != nil { + return err + } + + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + if err != nil { + return err + } + + steveclient, err := client.Steve.ProxyDownstream(clusterID) + if err != nil { + return err + } + + nodeList, err := steveclient.SteveType("node").List(nil) + if err != nil { + return err + } + + nodeCertificates := map[string]map[string]string{} + + sshUser, err := sshkeys.GetSSHUser(client, cluster) + if err != nil { + return err + } + if sshUser == "" { + return errors.New("sshUser does not exist") + } + + for _, node := range nodeList.Data { + newCertificate, err := getCertificatesFromMachine(client, &node, sshUser) + if err != nil { + return err + } + + nodeCertificates[node.ID] = newCertificate + } + + updatedCluster := *cluster + generation := int64(1) + if clusterSpec.RKEConfig.RotateCertificates != nil { + generation = clusterSpec.RKEConfig.RotateCertificates.Generation + 1 + } + + clusterSpec.RKEConfig.RotateCertificates = &rkev1.RotateCertificates{ + Generation: generation, + } + + updatedCluster.Spec = *clusterSpec + + _, err = client.Steve.SteveType(provisioningSteveResourceType).Update(cluster, updatedCluster) + if err != nil { + return err + } + + logrus.Infof("updated cluster, certs are rotating...") + kubeRKEClient, err := client.GetKubeAPIRKEClient() + if err != nil { + return err + } + + result, err := kubeRKEClient.RKEControlPlanes(namespace).Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + clusterName, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + if err != nil { + return err + } + + checkFunc := provisioning.CertRotationCompleteCheckFunc(generation) + logrus.Infof("waiting for certs to rotate, checking status now...") + err = wait.WatchWait(result, checkFunc) + if err != nil { + return err + } + + kubeProvisioningClient, err := client.GetKubeAPIProvisioningClient() + if err != nil { + return err + } + + clusterWait, err := kubeProvisioningClient.Clusters("fleet-default").Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + clusterName, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + if err != nil { + return err + } + + clusterCheckFunc := clusters.IsProvisioningClusterReady + logrus.Infof("waiting for cluster to become active again, checking status now...") + err = wait.WatchWait(clusterWait, clusterCheckFunc) + if err != nil { + return err + } + + postRotatedCertificates := map[string]map[string]string{} + + for _, node := range nodeList.Data { + newCertificate, err := getCertificatesFromMachine(client, &node, sshUser) + if err != nil { + return err + } + + postRotatedCertificates[node.ID] = newCertificate + } + + isAllCertRotated := compareCertificatesFromMachines(nodeCertificates, postRotatedCertificates) + if !isAllCertRotated { + return errors.New("certs weren't properly rotated") + } + + logrus.Infof("Cert Rotation Complete.") + return nil +} + +func rotateRKE1Certs(client *rancher.Client, clusterName string) error { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + if err != nil { + return err + } + + nodeList, err := client.Management.Node.List(&types.ListOpts{Filters: map[string]interface{}{ + "clusterId": clusterID, + }}) + if err != nil { + return err + } + + nodeCertificates := map[string]map[string]string{} + + for _, node := range nodeList.Data { + newCertificate, err := getCertificatesFromV3Node(client, &node) + if err != nil { + return err + } + + nodeCertificates[node.ID] = newCertificate + } + + cluster, err := client.Management.Cluster.ByID(clusterID) + if err != nil { + return err + } + + _, err = client.Management.Cluster.ActionRotateCertificates( + cluster, + &management.RotateCertificateInput{CACertificates: false, Services: ""}, + ) + if err != nil { + return err + } + + logrus.Infof("updated cluster, certs are rotating...") + + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + if err != nil { + return err + } + + err = clusters.WaitClusterToBeUpgraded(adminClient, clusterID) + if err != nil { + return err + } + + postRotatedCertificates := map[string]map[string]string{} + + for _, node := range nodeList.Data { + newCertificate, err := getCertificatesFromV3Node(client, &node) + if err != nil { + return err + } + + postRotatedCertificates[node.ID] = newCertificate + } + + isAllCertRotated := compareCertificatesFromMachines(nodeCertificates, postRotatedCertificates) + if !isAllCertRotated { + return errors.New("certs weren't properly rotated") + } + + return nil +} + +func compareCertificatesFromMachines(certObject1, certObject2 map[string]map[string]string) bool { + isRotated := true + for nodeID := range certObject1 { + for certType := range certObject1[nodeID] { + + if certObject1[nodeID][certType] == certObject2[nodeID][certType] { + logrus.Infof("non-rotated cert info:") + logrus.Infof("%s %s was not updated: %s", nodeID, certType, certObject1[nodeID][certType]) + + isRotated = false + } + } + } + return isRotated +} + +func getCertificatesFromMachine(client *rancher.Client, machineNode *v1.SteveAPIObject, sshUser string) (map[string]string, error) { + certificates := map[string]string{} + + sshNode, err := sshkeys.GetSSHNodeFromMachine(client, sshUser, machineNode) + if err != nil { + return nil, err + } + + logrus.Infof("Getting certificates from machine: %s", machineNode.Name) + + clusterType := machineNode.Labels["node.kubernetes.io/instance-type"] + certsPath := "/var/lib/rancher/" + clusterType + "/server/tls/" + + certsList := []string{ + "client-admin", + "client-auth-proxy", + "client-controller", + "client-kube-apiserver", + "client-kubelet", + "client-kube-proxy", + + "client-" + clusterType + "-cloud-controller", + "client-" + clusterType + "-controller", + + "client-scheduler", + "client-supervisor", + "etcd/client", + "etcd/peer-server-client", + "kube-controller-manager/kube-controller-manager", + "kube-scheduler/kube-scheduler", + "serving-kube-apiserver", + } + + for _, filename := range certsList { + // ignoring errors since node roles have different subsets of the certs. + certString, _ := sshNode.ExecuteCommand("openssl x509 -enddate -noout -in " + certsPath + filename + certFileExtension) + + if certString != "" { + certificates[filename] = certString + } + } + + return certificates, nil +} + +func getCertificatesFromV3Node(client *rancher.Client, v3Node *management.Node) (map[string]string, error) { + certificates := map[string]string{} + + sshNode, err := getSSHNodeFromV3Node(client, v3Node) + if err != nil { + return nil, err + } + + logrus.Infof("Getting certificates from machine: %s", v3Node.ID) + + certsPath := "/etc/kubernetes/ssl/" + + certsList := []string{ + "kube-apiserver", + "kube-apiserver-proxy-client", + "$(find /etc/kubernetes/ssl -name 'kube-etcd-*' | grep -v \"key\")", + "kube-controller-manager", + "kube-node", + "kube-proxy", + "kube-scheduler", + } + + for _, filename := range certsList { + fullAbsolutePath := certsPath + filename + pemFileExtension + if strings.Contains(filename, "etcd") { + fullAbsolutePath = filename + } + + certString, _ := sshNode.ExecuteCommand("openssl x509 -enddate -noout -in " + fullAbsolutePath) + + if certString != "" { + certificates[filename] = certString + } + } + + return certificates, nil +} + +func downloadRKE1SSHKeys(client *rancher.Client, v3Node *management.Node) ([]byte, error) { + sshKeyLink := v3Node.Links["nodeConfig"] + + req, err := http.NewRequest("GET", sshKeyLink, nil) + if err != nil { + return nil, err + } + + req.Header.Add("Authorization", "Bearer "+client.RancherConfig.AdminToken) + + resp, err := client.Management.APIBaseClient.Ops.Client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + privateSSHKeyRegEx := regexp.MustCompile(privateKeySSHKeyRegExPattern) + privateSSHKey := privateSSHKeyRegEx.FindString(string(bodyBytes)) + + return []byte(privateSSHKey), err +} + +func getSSHNodeFromV3Node(client *rancher.Client, v3Node *management.Node) (*nodes.Node, error) { + sshkey, err := downloadRKE1SSHKeys(client, v3Node) + if err != nil { + return nil, err + } + + clusterNode := &nodes.Node{ + NodeID: v3Node.ID, + PublicIPAddress: v3Node.ExternalIPAddress, + SSHUser: v3Node.SshUser, + SSHKey: sshkey, + } + + return clusterNode, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation_test.go new file mode 100644 index 0000000..4b510ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/certrotation/cert_rotation_test.go @@ -0,0 +1,81 @@ +//go:build (validation || infra.rke2k3s || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !sanity && !extended + +package certrotation + +import ( + "strings" + "testing" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type V2ProvCertRotationTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clustersConfig *provisioninginput.Config +} + +func (r *V2ProvCertRotationTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *V2ProvCertRotationTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client +} + +func (r *V2ProvCertRotationTestSuite) TestCertRotation() { + id, err := clusters.GetV1ProvisioningClusterByName(r.client, r.client.RancherConfig.ClusterName) + require.NoError(r.T(), err) + + cluster, err := r.client.Steve.SteveType(provisioningSteveResourceType).ByID(id) + require.NoError(r.T(), err) + + spec := &provv1.ClusterSpec{} + err = steveV1.ConvertToK8sType(cluster.Spec, spec) + require.NoError(r.T(), err) + + clusterType := "RKE1" + + if strings.Contains(spec.KubernetesVersion, "-rancher") || len(spec.KubernetesVersion) == 0 { + r.Run("test-cert-rotation "+clusterType, func() { + require.NoError(r.T(), rotateRKE1Certs(r.client, r.client.RancherConfig.ClusterName)) + require.NoError(r.T(), rotateRKE1Certs(r.client, r.client.RancherConfig.ClusterName)) + }) + + } else { + + if strings.Contains(spec.KubernetesVersion, "k3s") { + clusterType = "K3s" + } else { + clusterType = "RKE2" + } + + r.Run("test-cert-rotation "+clusterType, func() { + require.NoError(r.T(), rotateCerts(r.client, r.client.RancherConfig.ClusterName)) + require.NoError(r.T(), rotateCerts(r.client, r.client.RancherConfig.ClusterName)) + }) + } + +} + +func TestCertRotationTestSuite(t *testing.T) { + suite.Run(t, new(V2ProvCertRotationTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/README.md new file mode 100644 index 0000000..1b66aec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/README.md @@ -0,0 +1,26 @@ +# Charts Configs + +You can find the correct suite name in the below by checking the test file you plan to run. +In your config file, set the following: + +```json +"rancher": { + "host": "", + "adminToken": "", + "insecure": true/optional, + "cleanup": false/optional, + "clusterName": "" +} +``` + +From there, please use one of the following links to check charts tests: + +1. [Monitoring Chart](monitoring_test.go) +2. [Gatekeeper Chart](gatekeeper_test.go) +3. [Istio Chart](istio_test.go) +4. [Webhook Chart](webhook_test.go) + + +## Note +* For webhook charts, validations are run on the local cluster and the cluster name provided in the config.yaml. Please make sure to provide a downstream cluster name in the config.yaml instead of local cluster, so the validations are not run on the local cluster twice. + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper.go new file mode 100644 index 0000000..ce8a8ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper.go @@ -0,0 +1,56 @@ +package charts + +import ( + "time" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "golang.org/x/net/context" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + // Project that charts are installed in + gatekeeperProjectName = "gatekeeper-project" + // namespace that is created without a label + RancherDisallowedNamespace = "no-label" + ConstraintResourceSteveType = "constraints.gatekeeper.sh.k8srequiredlabels" +) + +type ConstraintStatus struct { + AuditTimestamp string + ByPod interface{} + TotalViolations int64 + Violations []interface{} +} + +func getAuditTimestamp(client *rancher.Client, project *management.Project) error { + // wait until the first audit finishes running. + // AuditTimestamp will be empty string until first audit finishes + steveClient, err := client.Steve.ProxyDownstream(project.ClusterID) + if err != nil { + return err + } + return wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, 5*time.Minute, true, func(context.Context) (done bool, err error) { + // get list of constraints + auditList, err := steveClient.SteveType(ConstraintResourceSteveType).List(nil) + if err != nil { + return false, nil + } + + constraintsStatusType := &ConstraintStatus{} + constraintStatus := auditList.Data[0].Status + err = v1.ConvertToK8sType(constraintStatus, constraintsStatusType) + if err != nil { + return false, nil + } + + // extract the timestamp of the last constraint audit + auditTime := constraintsStatusType.AuditTimestamp + if auditTime == "" { + return false, nil + } + return true, nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper_test.go new file mode 100644 index 0000000..e710be9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeper_test.go @@ -0,0 +1,215 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "os" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type GateKeeperTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + project *management.Project + gatekeeperChartInstallOptions *charts.InstallOptions +} + +func (g *GateKeeperTestSuite) TearDownSuite() { + g.session.Cleanup() +} + +func (g *GateKeeperTestSuite) SetupSuite() { + testSession := session.NewSession() + g.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(g.T(), err) + + g.client = client + + // Get clusterName from config yaml + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(g.T(), clusterName, "Cluster name to install is not set") + + // Get cluster meta + cluster, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(g.T(), err) + + // get latest version of gatekeeper chart + latestGatekeeperVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherGatekeeperName, catalog.RancherChartRepo) + require.NoError(g.T(), err) + + // Create project + projectConfig := &management.Project{ + ClusterID: cluster.ID, + Name: gatekeeperProjectName, + } + createdProject, err := client.Management.Project.Create(projectConfig) + require.NoError(g.T(), err) + require.Equal(g.T(), createdProject.Name, gatekeeperProjectName) + g.project = createdProject + + g.gatekeeperChartInstallOptions = &charts.InstallOptions{ + Cluster: cluster, + Version: latestGatekeeperVersion, + ProjectID: createdProject.ID, + } +} + +func (g *GateKeeperTestSuite) TestGatekeeperChart() { + subSession := g.session.NewSession() + defer subSession.Cleanup() + + client, err := g.client.WithSession(subSession) + require.NoError(g.T(), err) + + g.T().Log("Installing latest version of gatekeeper chart") + err = charts.InstallRancherGatekeeperChart(client, g.gatekeeperChartInstallOptions) + require.NoError(g.T(), err) + + g.T().Log("Waiting for gatekeeper chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + + g.T().Log("Waiting for gatekeeper chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + + g.T().Log("Applying constraint") + readYamlFile, err := os.ReadFile("./resources/opa-k8srequiredlabels.yaml") + require.NoError(g.T(), err) + yamlInput := &management.ImportClusterYamlInput{ + DefaultNamespace: charts.RancherGatekeeperNamespace, + YAML: string(readYamlFile), + } + + // get the cluster + cluster, err := client.Management.Cluster.ByID(g.project.ClusterID) + require.NoError(g.T(), err) + // Use ActionImportYaml to the apply the constraint yaml file + _, err = client.Management.Cluster.ActionImportYaml(cluster, yamlInput) + require.NoError(g.T(), err) + + g.T().Log("Create a namespace that doesn't have the proper label and assert that creation fails with the expected error") + _, err = namespaces.CreateNamespace(client, RancherDisallowedNamespace, "{}", map[string]string{}, map[string]string{}, g.project) + assert.ErrorContains(g.T(), err, "Bad response statusCode [403]. Status [403 Forbidden].") + g.T().Log("Waiting for gatekeeper audit to finish") + err = getAuditTimestamp(client, g.project) + require.NoError(g.T(), err) + + steveClient, err := client.Steve.ProxyDownstream(g.project.ClusterID) + require.NoError(g.T(), err) + + // now that audit has run, get the list of constraints again + constraintList, err := steveClient.SteveType(ConstraintResourceSteveType).List(nil) + require.NoError(g.T(), err) + + // parse list of constraints + constraintsStatusType := &ConstraintStatus{} + constraintStatus := constraintList.Data[0].Status + err = v1.ConvertToK8sType(constraintStatus, constraintsStatusType) + require.NoError(g.T(), err) + + g.T().Log("getting list of all namespaces") + namespacesList, err := steveClient.SteveType(namespaces.NamespaceSteveType).List(nil) + require.NoError(g.T(), err) + + g.T().Log("getting list of namespaces with violations...") + totalViolations := constraintsStatusType.TotalViolations + // get the number of namespaces + totalNamespaces := len(namespacesList.Data) + + g.T().Log("Asserting that all namespaces violate the constraint") + assert.EqualValues(g.T(), totalNamespaces, totalViolations) +} + +func (g *GateKeeperTestSuite) TestUpgradeGatekeeperChart() { + subSession := g.session.NewSession() + defer subSession.Cleanup() + + client, err := g.client.WithSession(subSession) + require.NoError(g.T(), err) + + // Change gatekeeper install option version to previous version of the latest version + versionsList, err := client.Catalog.GetListChartVersions(charts.RancherGatekeeperName, catalog.RancherChartRepo) + require.NoError(g.T(), err) + + if len(versionsList) < 2 { + g.T().Skip("Skipping the upgrade case, only one version of gatekeeper is available") + } + assert.GreaterOrEqualf(g.T(), len(versionsList), 2, "There should be at least 2 versions of the gatekeeper chart") + versionLatest := versionsList[0] + g.T().Log(versionLatest) + versionBeforeLatest := versionsList[1] + g.T().Log(versionBeforeLatest) + g.gatekeeperChartInstallOptions.Version = versionBeforeLatest + + g.T().Log("Checking if the gatekeeper chart is installed with one of the previous versions") + initialGatekeeperChart, err := charts.GetChartStatus(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, charts.RancherGatekeeperName) + require.NoError(g.T(), err) + + if initialGatekeeperChart.IsAlreadyInstalled && initialGatekeeperChart.ChartDetails.Spec.Chart.Metadata.Version == versionLatest { + g.T().Skip("Skipping the upgrade case, gatekeeper chart is already installed with the latest version") + } + + if !initialGatekeeperChart.IsAlreadyInstalled { + g.T().Log("Installing gatekeeper chart with the version before the latest version") + err = charts.InstallRancherGatekeeperChart(client, g.gatekeeperChartInstallOptions) + require.NoError(g.T(), err) + + g.T().Log("Waiting gatekeeper chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + + g.T().Log("Waiting gatekeeper chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + } + + gatekeeperChartPreUpgrade, err := charts.GetChartStatus(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, charts.RancherGatekeeperName) + require.NoError(g.T(), err) + + // Validate current version of rancher-gatekeeper is one of the versions before latest + chartVersionPreUpgrade := gatekeeperChartPreUpgrade.ChartDetails.Spec.Chart.Metadata.Version + require.Contains(g.T(), versionsList[1:], chartVersionPreUpgrade) + + g.gatekeeperChartInstallOptions.Version, err = client.Catalog.GetLatestChartVersion(charts.RancherGatekeeperName, catalog.RancherChartRepo) + require.NoError(g.T(), err) + + g.T().Log("Upgrading gatekeeper chart to the latest version") + err = charts.UpgradeRancherGatekeeperChart(client, g.gatekeeperChartInstallOptions) + require.NoError(g.T(), err) + + g.T().Log("Waiting for gatekeeper chart deployments to have expected number of available replicas after upgrade") + err = charts.WatchAndWaitDeployments(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + + g.T().Log("Waiting gatekeeper chart DaemonSets to have expected number of available nodes after upgrade") + err = charts.WatchAndWaitDaemonSets(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(g.T(), err) + + gatekeeperChartPostUpgrade, err := charts.GetChartStatus(client, g.project.ClusterID, charts.RancherGatekeeperNamespace, charts.RancherGatekeeperName) + require.NoError(g.T(), err) + + g.T().Log("Comparing installed and desired gatekeeper versions") + chartVersionPostUpgrade := gatekeeperChartPostUpgrade.ChartDetails.Spec.Chart.Metadata.Version + require.Equal(g.T(), g.gatekeeperChartInstallOptions.Version, chartVersionPostUpgrade) +} + +func TestGateKeeperTestSuite(t *testing.T) { + suite.Run(t, new(GateKeeperTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespaces_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespaces_test.go new file mode 100644 index 0000000..adfcb09 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespaces_test.go @@ -0,0 +1,86 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "os" + "strings" + + settings "github.com/rancher/rancher/pkg/settings" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + namespaces "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/pkg/environmentflag" + "github.com/stretchr/testify/assert" + require "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (n *GateKeeperTestSuite) TestGateKeeperAllowedNamespaces() { + subSession := n.session.NewSession() + defer subSession.Cleanup() + + client, err := n.client.WithSession(subSession) + require.NoError(n.T(), err) + + if !client.Flags.GetValue(environmentflag.GatekeeperAllowedNamespaces) { + n.T().Skip("skipping TestGateKeeperAllowedNamespaces because GatekeeperAllowedNamespaces flag not set in cattle config") + } + + n.T().Log("Installing latest version of gatekeeper chart") + err = charts.InstallRancherGatekeeperChart(client, n.gatekeeperChartInstallOptions) + require.NoError(n.T(), err) + + n.T().Log("Waiting for gatekeeper chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, n.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(n.T(), err) + + n.T().Log("Waiting for gatekeeper chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, n.project.ClusterID, charts.RancherGatekeeperNamespace, metav1.ListOptions{}) + require.NoError(n.T(), err) + + n.T().Log("creating constraint template") + readTemplateYamlFile, err := os.ReadFile("./resources/opa-allowednamespacestemplate.yaml") + require.NoError(n.T(), err) + yamlTemplateInput := &management.ImportClusterYamlInput{ + DefaultNamespace: charts.RancherGatekeeperNamespace, + YAML: string(readTemplateYamlFile), + } + + n.T().Log("getting list of all namespaces") + sysNamespaces := settings.SystemNamespaces.Get() + sysNamespacesSlice := strings.Split(sysNamespaces, ",") + + // constraint must exclude cattle-gatekeeper-system and all namespaces that are dynamically generated during gatekeeper installation and upgrade + // for example: pod-impersonation-helm-op-f9pwc and cattle-impersonation-user-vhkst-token + n.T().Log("creating constraint") + yamlString, err := charts.GenerateGatekeeperConstraintYaml([]string{""}, + []string{"cattle-gatekeeper-system", "ingress-nginx-controller-admission", "kube-dns", "cattle-controllers", "rke-network-plugin", "extension-apiserver-authentication", "fleet-agent-lock", "udp-services", "cattle-impersonation-user*", "pod-impersonation-helm-op*", "local*", "default*", "test*", "canal*", "nginx-ingress-controller*", "rke*", "coredns*", "gatekeeper*", "calico-kube-controllers*", "kube-root*", "cattle*", "kube-root-ca*", "ingress-nginx-admission*", "metrics-server*"}, + []string{"Namespace"}, + "ns-must-be-allowed", sysNamespacesSlice, "deny", "constraints.gatekeeper.sh/v1beta1", "K8sAllowedNamespaces") + require.NoError(n.T(), err) + n.T().Log(yamlString) + + yamlConstraintInput := &management.ImportClusterYamlInput{ + DefaultNamespace: charts.RancherGatekeeperNamespace, + YAML: yamlString, + } + + // get the cluster + cluster, err := client.Management.Cluster.ByID(n.project.ClusterID) + require.NoError(n.T(), err) + + n.T().Log("applying constraint template") + _, err = client.Management.Cluster.ActionImportYaml(cluster, yamlTemplateInput) + require.NoError(n.T(), err) + + n.T().Log("applying constraint") + // Use ActionImportYaml to the apply the constraint yaml file + _, err = client.Management.Cluster.ActionImportYaml(cluster, yamlConstraintInput) + require.NoError(n.T(), err) + + n.T().Log("Create a namespace that doesn't have an allowed name and assert that creation fails with the expected error") + _, err = namespaces.CreateNamespace(client, RancherDisallowedNamespace, "{}", map[string]string{}, map[string]string{}, n.project) + assert.ErrorContains(n.T(), err, "admission webhook \"validation.gatekeeper.sh\" denied the request: [ns-must-be-allowed] Namespace not allowed") + +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespacespostupgrade_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespacespostupgrade_test.go new file mode 100644 index 0000000..7bdf195 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/gatekeeperallowednamespacespostupgrade_test.go @@ -0,0 +1,36 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "strings" + + settings "github.com/rancher/rancher/pkg/settings" + namespaces "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/pkg/environmentflag" + "github.com/stretchr/testify/require" +) + +func (n *GateKeeperTestSuite) TestGateKeeperAllowedNamespacesPostUpgrade() { + + subSession := n.session.NewSession() + defer subSession.Cleanup() + + client, err := n.client.WithSession(subSession) + require.NoError(n.T(), err) + + if !client.Flags.GetValue(environmentflag.GatekeeperAllowedNamespaces) { + n.T().Skip("skipping TestGateKeeperAllowedNamespacesPostUpgrade because GatekeeperAllowedNamespaces flag not set in cattle config") + } + + sysNamespaces := settings.SystemNamespaces.Get() + + sysNamespacesSlice := strings.Split(sysNamespaces, ",") + for _, namespace := range sysNamespacesSlice { + _, err = namespaces.CreateNamespace(client, namespace, "{}", map[string]string{}, map[string]string{}, n.project) + if err != nil { + errString := "namespaces \"" + namespace + "\" already exists" + require.ErrorContains(n.T(), err, errString) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/installations_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/installations_test.go new file mode 100644 index 0000000..c2bf518 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/installations_test.go @@ -0,0 +1,227 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/registries" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type InstallationTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + project *management.Project + cluster *clusters.ClusterMeta + registrySetting *management.Setting +} + +func (i *InstallationTestSuite) TearDownSuite() { + i.session.Cleanup() +} + +func (i *InstallationTestSuite) SetupSuite() { + testSession := session.NewSession() + i.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(i.T(), err) + + i.client = client + + // Get clusterName from config yaml + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(i.T(), clusterName, "Cluster name to install is not set") + + // Get cluster meta + cluster, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(i.T(), err) + + i.cluster = cluster + + // Get Server and Registry Setting Values + i.registrySetting, err = client.Management.Setting.ByID("system-default-registry") + require.NoError(i.T(), err) + + // Create project + projectConfig := &management.Project{ + ClusterID: cluster.ID, + Name: exampleAppProjectName, + } + createdProject, err := client.Management.Project.Create(projectConfig) + require.NoError(i.T(), err) + require.Equal(i.T(), createdProject.Name, exampleAppProjectName) + i.project = createdProject +} + +func (i *InstallationTestSuite) TestInstallMonitoringChart() { + client, err := i.client.WithSession(i.session) + require.NoError(i.T(), err) + + i.T().Log("Checking if the monitoring chart is already installed") + initialMonitoringChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(i.T(), err) + + if !initialMonitoringChart.IsAlreadyInstalled { + // Get latest versions of monitoring + latestMonitoringVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherMonitoringName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + + monitoringInstOpts := &charts.InstallOptions{ + Cluster: i.cluster, + Version: latestMonitoringVersion, + ProjectID: i.project.ID, + } + + monitoringOpts := &charts.RancherMonitoringOpts{ + IngressNginx: true, + ControllerManager: true, + Etcd: true, + Proxy: true, + Scheduler: true, + } + + i.T().Logf("Installing monitoring chart with the latest version in cluster [%v] with version [%v]", i.cluster.Name, latestMonitoringVersion) + err = charts.InstallRancherMonitoringChart(client, monitoringInstOpts, monitoringOpts) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart StatefulSets to have expected number of ready replicas") + err = charts.WatchAndWaitStatefulSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + } + + isUsingRegistry, err := registries.CheckAllClusterPodsForRegistryPrefix(client, i.cluster.ID, i.registrySetting.Value) + require.NoError(i.T(), err) + assert.Truef(i.T(), isUsingRegistry, "Checking if using correct registry prefix") +} + +func (i *InstallationTestSuite) TestInstallAlertingChart() { + i.TestInstallMonitoringChart() + + client, err := i.client.WithSession(i.session) + require.NoError(i.T(), err) + + alertingChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherAlertingNamespace, charts.RancherAlertingName) + require.NoError(i.T(), err) + + if !alertingChart.IsAlreadyInstalled { + // Get latest versions of alerting + latestAlertingVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherAlertingName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + + alertingChartInstallOption := &charts.InstallOptions{ + Cluster: i.cluster, + Version: latestAlertingVersion, + ProjectID: i.project.ID, + } + + alertingFeatureOption := &charts.RancherAlertingOpts{ + SMS: true, + Teams: true, + } + + i.T().Logf("Installing alerting chart with the latest version in cluster [%v] with version [%v]", i.cluster.Name, latestAlertingVersion) + err = charts.InstallRancherAlertingChart(client, alertingChartInstallOption, alertingFeatureOption) + require.NoError(i.T(), err) + } + + isUsingRegistry, err := registries.CheckAllClusterPodsForRegistryPrefix(client, i.cluster.ID, i.registrySetting.Value) + require.NoError(i.T(), err) + assert.Truef(i.T(), isUsingRegistry, "Checking if using correct registry prefix") +} + +func (i *InstallationTestSuite) TestInstallLoggingChart() { + client, err := i.client.WithSession(i.session) + require.NoError(i.T(), err) + + loggingChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherLoggingNamespace, charts.RancherLoggingName) + require.NoError(i.T(), err) + + if !loggingChart.IsAlreadyInstalled { + // Get latest versions of logging + latestLoggingVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherLoggingName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + + loggingChartInstallOption := &charts.InstallOptions{ + Cluster: i.cluster, + Version: latestLoggingVersion, + ProjectID: i.project.ID, + } + + loggingChartFeatureOption := &charts.RancherLoggingOpts{ + AdditionalLoggingSources: true, + } + + i.T().Logf("Installing logging chart with the latest version in cluster [%v] with version [%v]", i.cluster.Name, latestLoggingVersion) + err = charts.InstallRancherLoggingChart(client, loggingChartInstallOption, loggingChartFeatureOption) + require.NoError(i.T(), err) + } + + isUsingRegistry, err := registries.CheckAllClusterPodsForRegistryPrefix(client, i.cluster.ID, i.registrySetting.Value) + require.NoError(i.T(), err) + assert.Truef(i.T(), isUsingRegistry, "Checking if using correct registry prefix") +} + +func (i *InstallationTestSuite) TestInstallIstioChart() { + i.TestInstallMonitoringChart() + + client, err := i.client.WithSession(i.session) + require.NoError(i.T(), err) + + istioChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherIstioNamespace, charts.RancherIstioName) + require.NoError(i.T(), err) + + if !istioChart.IsAlreadyInstalled { + // Get latest versions of logging + latestIstioVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherIstioName, catalog.RancherChartRepo) + + require.NoError(i.T(), err) + + istioChartInstallOption := &charts.InstallOptions{ + Cluster: i.cluster, + Version: latestIstioVersion, + ProjectID: i.project.ID, + } + + istioChartFeatureOption := &charts.RancherIstioOpts{ + IngressGateways: true, + EgressGateways: false, + Pilot: true, + Telemetry: true, + Kiali: true, + Tracing: true, + CNI: false, + } + + i.T().Logf("Installing istio chart with the latest version in cluster [%v] with version [%v]", i.cluster.Name, latestIstioVersion) + err = charts.InstallRancherIstioChart(client, istioChartInstallOption, istioChartFeatureOption) + require.NoError(i.T(), err) + } + + isUsingRegistry, err := registries.CheckAllClusterPodsForRegistryPrefix(client, i.cluster.ID, i.registrySetting.Value) + require.NoError(i.T(), err) + assert.Truef(i.T(), isUsingRegistry, "Checking if using correct registry prefix") +} + +func TestInstallationTestSuite(t *testing.T) { + suite.Run(t, new(InstallationTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio.go new file mode 100644 index 0000000..a408f0b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio.go @@ -0,0 +1,109 @@ +package charts + +import ( + "context" + "strings" + "time" + "unicode" + + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/ingresses" + "github.com/rancher/shepherd/extensions/workloads" + appv1 "k8s.io/api/apps/v1" + kubewait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + // Project that example app and charts are installed in + exampleAppProjectName = "demo-project" + // Namespace that example app objects are installed in + exampleAppNamespaceName = "demo-namespace" + + // Example app port and path to be checked + exampleAppPort = "31380" + exampleAppProductPagePath = "productpage" + + // Example app different review bodies to be checked + firstReviewBodyPart = `Reviewer1` + secondReviewBodyPart = `` + thirdReviewBodyPart = `` +) + +var ( + // Rancher istio chart kiali path + kialiPath = "api/v1/namespaces/istio-system/services/http:kiali:20001/proxy/console/" + // Rancher istio chart tracing path + tracingPath = "api/v1/namespaces/istio-system/services/http:tracing:16686/proxy/jaeger/search" +) + +// chartInstallOptions is a private struct that has istio and monitoring charts install options +type chartInstallOptions struct { + monitoring *charts.InstallOptions + istio *charts.InstallOptions +} + +// chartFeatureOptions is a private struct that has istio and monitoring charts feature options +type chartFeatureOptions struct { + monitoring *charts.RancherMonitoringOpts + istio *charts.RancherIstioOpts +} + +// getChartCaseEndpointUntilBodyHas is a private helper function +// that awaits the body of the response until the desired string is found +func getChartCaseEndpointUntilBodyHas(client *rancher.Client, host, path, bodyPart string) (found bool, err error) { + trimAllSpaces := func(str string) string { + return strings.Map(func(r rune) rune { + if unicode.IsSpace(r) { + return -1 + } + return r + }, str) + } + + err = kubewait.PollUntilContextTimeout(context.TODO(), 500*time.Millisecond, 2*time.Minute, true, func(context.Context) (ongoing bool, err error) { + bodyString, err := ingresses.GetExternalIngressResponse(client, host, path, false) + if err != nil { + return ongoing, err + } + + trimmedBody := trimAllSpaces(bodyString) + if strings.Contains(trimmedBody, bodyPart) { + found = true + return !ongoing, nil + } + + return + }) + if err != nil { + return false, err + } + + return +} + +// listIstioDeployments is a private helper function +// that returns the deployment specs if deployments have "operator.istio.io/version" label +func listIstioDeployments(steveclient *v1.Client) (deploymentSpecList []*appv1.DeploymentSpec, err error) { + deploymentList, err := steveclient.SteveType(workloads.DeploymentSteveType).List(nil) + if err != nil { + return + } + + for _, deployment := range deploymentList.Data { + _, ok := deployment.ObjectMeta.Labels["operator.istio.io/version"] + + if ok { + deploymentSpec := &appv1.DeploymentSpec{} + err := v1.ConvertToK8sType(deployment.Spec, deploymentSpec) + if err != nil { + return deploymentSpecList, err + } + + deploymentSpecList = append(deploymentSpecList, deploymentSpec) + } + } + + return deploymentSpecList, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio_test.go new file mode 100644 index 0000000..0757c9f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/istio_test.go @@ -0,0 +1,337 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "fmt" + "math/rand" + "os" + "strings" + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/rancher/norman/types" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/ingresses" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type IstioTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + project *management.Project + chartInstallOptions *chartInstallOptions + chartFeatureOptions *chartFeatureOptions +} + +func (i *IstioTestSuite) TearDownSuite() { + i.session.Cleanup() +} + +func (i *IstioTestSuite) SetupSuite() { + testSession := session.NewSession() + i.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(i.T(), err) + + i.client = client + + // Get clusterName from config yaml + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(i.T(), clusterName, "Cluster name to install is not set") + + // Get cluster meta + cluster, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(i.T(), err) + + // Change kiali and jaeger paths if it's not local cluster + if !cluster.IsLocal { + kialiPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, kialiPath) + tracingPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, tracingPath) + } + + // Get latest versions of monitoring & istio charts + latestIstioVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherIstioName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + latestMonitoringVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherMonitoringName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + + // Create project + projectConfig := &management.Project{ + ClusterID: cluster.ID, + Name: exampleAppProjectName, + } + createdProject, err := client.Management.Project.Create(projectConfig) + require.NoError(i.T(), err) + require.Equal(i.T(), createdProject.Name, exampleAppProjectName) + i.project = createdProject + + i.chartInstallOptions = &chartInstallOptions{ + monitoring: &charts.InstallOptions{ + Version: latestMonitoringVersion, + ProjectID: createdProject.ID, + }, + istio: &charts.InstallOptions{ + Version: latestIstioVersion, + ProjectID: createdProject.ID, + }, + } + + i.chartFeatureOptions = &chartFeatureOptions{ + monitoring: &charts.RancherMonitoringOpts{ + IngressNginx: true, + ControllerManager: true, + Etcd: true, + Proxy: true, + Scheduler: true, + }, + istio: &charts.RancherIstioOpts{ + IngressGateways: true, + EgressGateways: false, + Pilot: true, + Telemetry: true, + Kiali: true, + Tracing: true, + CNI: false, + }, + } +} + +func (i *IstioTestSuite) TestIstioChart() { + subSession := i.session.NewSession() + defer subSession.Cleanup() + + client, err := i.client.WithSession(subSession) + require.NoError(i.T(), err) + + i.T().Log("Checking if the monitoring chart is installed") + monitoringChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(i.T(), err) + + if !monitoringChart.IsAlreadyInstalled { + i.T().Log("Installing monitoring chart") + err = charts.InstallRancherMonitoringChart(client, i.chartInstallOptions.monitoring, i.chartFeatureOptions.monitoring) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart StatefulSets to have expected number of ready replicas") + err = charts.WatchAndWaitStatefulSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + } + + i.T().Log("Checking if the istio chart is installed") + istioChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherIstioNamespace, charts.RancherIstioName) + require.NoError(i.T(), err) + + if !istioChart.IsAlreadyInstalled { + i.T().Log("Installing istio chart with the latest version") + err = charts.InstallRancherIstioChart(client, i.chartInstallOptions.istio, i.chartFeatureOptions.istio) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + } + + i.T().Log("Creating namespace with istio injection enabled option for the example app") + createdNamespace, err := namespaces.CreateNamespace(client, exampleAppNamespaceName, "{}", map[string]string{"istio-injection": "enabled"}, map[string]string{}, i.project) + require.NoError(i.T(), err) + require.Equal(i.T(), exampleAppNamespaceName, createdNamespace.Name) + + i.T().Log("Importing example app objects to the namespace") + readYamlFile, err := os.ReadFile("./resources/istio-demobookapp.yaml") + require.NoError(i.T(), err) + yamlInput := &management.ImportClusterYamlInput{ + DefaultNamespace: exampleAppNamespaceName, + YAML: string(readYamlFile), + } + cluster, err := client.Management.Cluster.ByID(i.project.ClusterID) + require.NoError(i.T(), err) + _, err = client.Management.Cluster.ActionImportYaml(cluster, yamlInput) + require.NoError(i.T(), err) + + i.T().Log("Waiting example app deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, exampleAppNamespaceName, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Validating kiali and jaeger endpoints are accessible") + kialiResult, err := ingresses.IsIngressExternallyAccessible(client, client.RancherConfig.Host, kialiPath, true) + require.NoError(i.T(), err) + assert.True(i.T(), kialiResult) + + tracingResult, err := ingresses.IsIngressExternallyAccessible(client, client.RancherConfig.Host, tracingPath, true) + require.NoError(i.T(), err) + assert.True(i.T(), tracingResult) + + // Get a random worker node' public external IP of a specific cluster + nodeCollection, err := client.Management.Node.List(&types.ListOpts{Filters: map[string]interface{}{ + "clusterId": i.project.ClusterID, + }}) + require.NoError(i.T(), err) + workerNodePublicIPs := []string{} + for _, node := range nodeCollection.Data { + workerNodePublicIPs = append(workerNodePublicIPs, node.Annotations["rke.cattle.io/external-ip"]) + } + randWorkerNodePublicIP := workerNodePublicIPs[rand.Intn(len(workerNodePublicIPs))] + istioGatewayHost := randWorkerNodePublicIP + ":" + exampleAppPort + + i.T().Log("Validating example app is accessible") + exampleAppResult, err := ingresses.IsIngressExternallyAccessible(client, istioGatewayHost, exampleAppProductPagePath, false) + require.NoError(i.T(), err) + assert.True(i.T(), exampleAppResult) + + i.T().Log("Validating example app has three different reviews bodies") + doesContainFirstPart, err := getChartCaseEndpointUntilBodyHas(client, istioGatewayHost, exampleAppProductPagePath, firstReviewBodyPart) + require.NoError(i.T(), err) + assert.True(i.T(), doesContainFirstPart) + + doesContainSecondPart, err := getChartCaseEndpointUntilBodyHas(client, istioGatewayHost, exampleAppProductPagePath, secondReviewBodyPart) + require.NoError(i.T(), err) + assert.True(i.T(), doesContainSecondPart) + + doesContainThirdPart, err := getChartCaseEndpointUntilBodyHas(client, istioGatewayHost, exampleAppProductPagePath, thirdReviewBodyPart) + require.NoError(i.T(), err) + assert.True(i.T(), doesContainThirdPart) +} + +func (i *IstioTestSuite) TestUpgradeIstioChart() { + subSession := i.session.NewSession() + defer subSession.Cleanup() + + client, err := i.client.WithSession(subSession) + require.NoError(i.T(), err) + + steveclient, err := client.Steve.ProxyDownstream(i.project.ClusterID) + require.NoError(i.T(), err) + + i.T().Log("Checking if the monitoring chart is installed") + monitoringChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(i.T(), err) + + if !monitoringChart.IsAlreadyInstalled { + i.T().Log("Installing monitoring chart with the latest version") + err = charts.InstallRancherMonitoringChart(client, i.chartInstallOptions.monitoring, i.chartFeatureOptions.monitoring) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting monitoring chart StatefulSets to have expected number of ready replicas") + err = charts.WatchAndWaitStatefulSets(client, i.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + } + + // Change istio install option version to previous version of the latest version + versionsList, err := client.Catalog.GetListChartVersions(charts.RancherIstioName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + require.Greaterf(i.T(), len(versionsList), 1, "There should be at least 2 versions of the istio chart") + versionLatest := versionsList[0] + versionBeforeLatest := versionsList[1] + i.chartInstallOptions.istio.Version = versionBeforeLatest + + i.T().Log("Checking if the istio chart is installed with one of the previous versions") + initialIstioChart, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherIstioNamespace, charts.RancherIstioName) + require.NoError(i.T(), err) + + if initialIstioChart.IsAlreadyInstalled && initialIstioChart.ChartDetails.Spec.Chart.Metadata.Version == versionLatest { + i.T().Skip("Skipping the upgrade case, istio chart is already installed with the latest version") + } + + if !initialIstioChart.IsAlreadyInstalled { + i.T().Log("Installing istio chart with the last but one version") + err = charts.InstallRancherIstioChart(client, i.chartInstallOptions.istio, i.chartFeatureOptions.istio) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + } + + istioChartPreUpgrade, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherIstioNamespace, charts.RancherIstioName) + require.NoError(i.T(), err) + + // Validate current version of rancheristio is one of the versions before latest + chartVersionPreUpgrade := istioChartPreUpgrade.ChartDetails.Spec.Chart.Metadata.Version + require.Contains(i.T(), versionsList[1:], chartVersionPreUpgrade) + + // List deployments that have the istio app version as label + istioVersionPreUpgrade := istioChartPreUpgrade.ChartDetails.Spec.Chart.Metadata.AppVersion + deploymentListPreUpgrade, err := listIstioDeployments(steveclient) + require.NoError(i.T(), err) + require.Equalf(i.T(), 2, len(deploymentListPreUpgrade), "Pilot & Ingressgateways deployments don't have the correct istio version labels") + + for _, deploymentSpec := range deploymentListPreUpgrade { + imageVersion := strings.Split(deploymentSpec.Template.Spec.Containers[0].Image, ":")[1] + i.T().Logf("Comparing image and app versions: \n container image version: %v \n istio version: %v and actual: %v\n", deploymentSpec.Template.Spec.Containers[0].Image, istioVersionPreUpgrade, imageVersion) + require.Containsf(i.T(), imageVersion, istioVersionPreUpgrade, "Pilot & Ingressgateways images don't use the correct istio image version") + } + + i.chartInstallOptions.istio.Version, err = client.Catalog.GetLatestChartVersion(charts.RancherIstioName, catalog.RancherChartRepo) + require.NoError(i.T(), err) + + i.T().Log("Upgrading istio chart with the latest version") + err = charts.UpgradeRancherIstioChart(client, i.chartInstallOptions.istio, i.chartFeatureOptions.istio) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart deployments to have expected number of available replicas after upgrade") + err = charts.WatchAndWaitDeployments(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + i.T().Log("Waiting istio chart DaemonSets to have expected number of available nodes after upgrade") + err = charts.WatchAndWaitDaemonSets(client, i.project.ClusterID, charts.RancherIstioNamespace, metav1.ListOptions{}) + require.NoError(i.T(), err) + + istioChartPostUpgrade, err := charts.GetChartStatus(client, i.project.ClusterID, charts.RancherIstioNamespace, charts.RancherIstioName) + require.NoError(i.T(), err) + + // Compare rancheristio versions + chartVersionPostUpgrade := istioChartPostUpgrade.ChartDetails.Spec.Chart.Metadata.Version + assert.Equal(i.T(), i.chartInstallOptions.istio.Version, chartVersionPostUpgrade) + + // List deployments that have the istio app version as label + istioVersionPostUpgrade := istioChartPostUpgrade.ChartDetails.Spec.Chart.Metadata.AppVersion + deploymentListPostUpgrade, err := listIstioDeployments(steveclient) + require.NoError(i.T(), err) + require.Equalf(i.T(), 2, len(deploymentListPostUpgrade), "Pilot & Ingressgateways deployments don't have the correct istio version labels") + + for _, deploymentSpec := range deploymentListPostUpgrade { + imageVersion := strings.Split(deploymentSpec.Template.Spec.Containers[0].Image, ":")[1] + i.T().Logf("Comparing image and app versions: \n container image: %v \n istio version: %v and actual: %v\n", deploymentSpec.Template.Spec.Containers[0].Image, istioVersionPostUpgrade, imageVersion) + require.Containsf(i.T(), imageVersion, istioVersionPostUpgrade, "Pilot & Ingressgateways images don't use the correct istio image version") + } +} + +func TestIstioTestSuite(t *testing.T) { + suite.Run(t, new(IstioTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring.go new file mode 100644 index 0000000..1a2c02a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring.go @@ -0,0 +1,453 @@ +package charts + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "net/url" + "time" + + "github.com/rancher/rancher/tests/v2/validation/charts/resources" + "gopkg.in/yaml.v2" + + "github.com/pkg/errors" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusterrolebindings" + "github.com/rancher/shepherd/extensions/configmaps" + "github.com/rancher/shepherd/extensions/ingresses" + "github.com/rancher/shepherd/extensions/serviceaccounts" + "github.com/rancher/shepherd/extensions/workloads" + "github.com/rancher/shepherd/pkg/namegenerator" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + kubewait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + // Project that example app and charts are installed in + projectName = "System" + // Secret path that contains encoded alert manager config + secretPath = "alertmanager.yaml" + // Secret ID that points alert manager secret + alertManagerSecretID = charts.RancherMonitoringNamespace + "/" + charts.RancherMonitoringAlertSecret + // Default random string length for random name generation + defaultRandStringLength = 5 + // Webhook deployment annotation key that is being watched + webhookReceiverAnnotationKey = "didReceiveRequestFromAlertmanager" + // Webhook deployment annotation value that is being watched + webhookReceiverAnnotationValue = "true" + // Steve type for prometheus rules for schema + prometheusRulesSteveType = "monitoring.coreos.com.prometheusrule" + // rancherShellSettingID is the setting ID that used to grab rancher/shell image + rancherShellSettingID = "shell-image" + // Kubeconfig that linked to webhook deployment + kubeConfig = ` +apiVersion: v1 +kind: Config +clusters: +- name: cluster + cluster: + certificate-authority: /run/secrets/kubernetes.io/serviceaccount/ca.crt + server: https://kubernetes.default +contexts: +- name: default + context: + cluster: cluster + user: user +current-context: default +users: +- name: user + user: + tokenFile: /run/secrets/kubernetes.io/serviceaccount/token +` +) + +var ( + // Rancher monitoring chart alert manager path + alertManagerPath = "api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-alertmanager:9093/proxy/#/alerts" + // Rancher monitoring chart grafana path + grafanaPath = "api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-grafana:80/proxy" + // Rancher monitoring chart prometheus path + prometheusPath = "api/v1/namespaces/cattle-monitoring-system/services/http:rancher-monitoring-prometheus:9090/proxy" + // Rancher monitoring chart prometheus graph path + prometheusGraphPath = prometheusPath + "/graph" + // Rancher monitoring chart prometheus rules path + prometheusRulesPath = prometheusPath + "/rules" + // Rancher monitoring chart prometheus targets path + prometheusTargetsPath = prometheusPath + "/targets" + // Rancher monitoring chart prometheus targets API path + prometheusTargetsPathAPI = prometheusPath + "/api/v1/targets" + // Webhook receiver kubernetes object names + webhookReceiverNamespaceName = "webhook-namespace-" + namegenerator.RandStringLower(defaultRandStringLength) + webhookReceiverDeploymentName = "webhook-" + namegenerator.RandStringLower(defaultRandStringLength) + webhookReceiverServiceName = "webhook-service-" + namegenerator.RandStringLower(defaultRandStringLength) + // Label that is used to identify webhook and rule + ruleLabel = map[string]string{"team": "qa"} +) + +// waitUnknownPrometheusTargets is a private helper function +// that awaits the unknown Prometheus targets to be resolved until the timeout by using Prometheus API. +func waitUnknownPrometheusTargets(client *rancher.Client) error { + checkUnknownPrometheusTargets := func() (bool, error) { + var statusInit bool + var unknownTargets []string + bodyString, err := ingresses.GetExternalIngressResponse(client, client.RancherConfig.Host, prometheusTargetsPathAPI, true) + if err != nil { + return statusInit, err + } + + var mapResponse map[string]interface{} + if err = json.Unmarshal([]byte(bodyString), &mapResponse); err != nil { + return statusInit, err + } + if mapResponse["status"] != "success" { + return statusInit, errors.New("failed to get targets from prometheus") + } + activeTargets := mapResponse["data"].(map[string]interface{})["activeTargets"].([]interface{}) + if len(activeTargets) < 1 { + return false, errors.New("failed to find any active targets") + } + for _, target := range activeTargets { + targetMap := target.(map[string]interface{}) + if targetMap["health"].(string) == "unknown" { + unknownTargets = append(unknownTargets, targetMap["labels"].(map[string]interface{})["instance"].(string)) + } + } + return len(unknownTargets) == 0, nil + } + + return kubewait.PollUntilContextTimeout(context.TODO(), 500*time.Millisecond, 2*time.Minute, true, func(context.Context) (ongoing bool, err error) { + result, err := checkUnknownPrometheusTargets() + if err != nil { + return ongoing, err + } + + if result { + return !ongoing, nil + } + + return + }) +} + +// checkPrometheusTargets is a private helper function +// that checks if all active prometheus targets are healthy by using prometheus API. +func checkPrometheusTargets(client *rancher.Client) (bool, error) { + var statusInit bool + var downTargets []string + + err := waitUnknownPrometheusTargets(client) + if err != nil { + return statusInit, err + } + + bodyString, err := ingresses.GetExternalIngressResponse(client, client.RancherConfig.Host, prometheusTargetsPathAPI, true) + if err != nil { + return statusInit, err + } + + var mapResponse map[string]interface{} + if err = json.Unmarshal([]byte(bodyString), &mapResponse); err != nil { + return statusInit, err + } + + if mapResponse["status"] != "success" { + return statusInit, errors.New("failed to get targets from prometheus") + } + + activeTargets := mapResponse["data"].(map[string]interface{})["activeTargets"].([]interface{}) + if len(activeTargets) < 1 { + return false, errors.New("failed to find any active targets") + } + + for _, target := range activeTargets { + targetMap := target.(map[string]interface{}) + if targetMap["health"].(string) == "down" { + downTargets = append(downTargets, targetMap["labels"].(map[string]interface{})["instance"].(string)) + } + } + statusInit = len(downTargets) == 0 + + if !statusInit { + return statusInit, errors.Wrapf(err, "All active target(s) are not healthy: %v", downTargets) + } + + return statusInit, nil +} + +// editAlertReceiver is a private helper function +// that edits alert config structure to be used by the webhook receiver. +func editAlertReceiver(alertConfigByte []byte, originURL *url.URL) ([]byte, error) { + alertConfig := &resources.AlertmanagerConfig{} + err := yaml.Unmarshal(alertConfigByte, alertConfig) + if err != nil { + return nil, errors.Wrapf(err, "failed to unmarshal alert config") + } + + vsendresolved := false + + alertConfig.Global = &resources.GlobalConfig{ + ResolveTimeout: alertConfig.Global.ResolveTimeout, + } + alertConfig.Receivers = append(alertConfig.Receivers, &resources.Receiver{ + Name: webhookReceiverDeploymentName, + WebhookConfigs: []*resources.WebhookConfig{ + { + VSendResolved: &vsendresolved, + HTTPConfig: &resources.HTTPClientConfig{ + ProxyURL: originURL.String(), + }, + URL: originURL.String(), + }, + }, + }) + + byteAlertConfig, err := yaml.Marshal(alertConfig) + if err != nil { + return nil, err + } + + dst := make([]byte, base64.StdEncoding.EncodedLen(len(byteAlertConfig))) + base64.StdEncoding.Encode(dst, byteAlertConfig) + + return byteAlertConfig, nil +} + +// editAlertRoute is a private helper function +// that edits alert config structure to be used by the webhook receiver. +func editAlertRoute(alertConfigByte []byte) ([]byte, error) { + alertConfig := &resources.AlertmanagerConfig{} + err := yaml.Unmarshal(alertConfigByte, alertConfig) + if err != nil { + return nil, errors.Wrapf(err, "failed to unmarshal alert config") + } + + alertConfig.Global = &resources.GlobalConfig{ + ResolveTimeout: alertConfig.Global.ResolveTimeout, + } + + alertConfig.Route.Routes = append(alertConfig.Route.Routes, &resources.Route{ + Receiver: webhookReceiverDeploymentName, + Match: ruleLabel, + GroupWait: alertConfig.Route.GroupWait, + GroupInterval: alertConfig.Route.GroupInterval, + RepeatInterval: alertConfig.Route.RepeatInterval, + }) + + byteAlertConfig, err := yaml.Marshal(alertConfig) + if err != nil { + return nil, err + } + dst := make([]byte, base64.StdEncoding.EncodedLen(len(byteAlertConfig))) + base64.StdEncoding.Encode(dst, byteAlertConfig) + + return byteAlertConfig, nil +} + +// createPrometheusRule is a private helper function +// that creates a prometheus rule to be used by the webhook receiver. +func createPrometheusRule(client *rancher.Client, clusterID string) error { + ruleName := "webhook-rule-" + namegenerator.RandStringLower(defaultRandStringLength) + alertName := "alert-" + namegenerator.RandStringLower(defaultRandStringLength) + + _, err := client.ReLogin() + if err != nil { + return err + } + + steveclient, err := client.Steve.ProxyDownstream(clusterID) + if err != nil { + return err + } + + prometheusRule := &monitoringv1.PrometheusRule{ + ObjectMeta: metav1.ObjectMeta{ + Name: ruleName, + Namespace: charts.RancherMonitoringNamespace, + }, + Spec: monitoringv1.PrometheusRuleSpec{ + Groups: []monitoringv1.RuleGroup{ + { + Name: ruleName, + Rules: []monitoringv1.Rule{ + { + Alert: alertName, + Expr: intstr.IntOrString{Type: intstr.String, StrVal: "vector(0)"}, + Labels: ruleLabel, + For: "0s", + }, + }, + }, + }, + }, + } + _, err = steveclient.SteveType(prometheusRulesSteveType).Create(prometheusRule) + if err != nil { + return err + } + + return nil +} + +// createWebhookReceiverDeployment is a private helper function that creates a service account, cluster role binding, and deployment for webhook receiver. +// The deployment has two different containers with a shared volume, one for kubectl commands, and the other one to receive requests and write access logs to the shared empty dir volume. +// Container that uses rancher/shell has a mounted volume to use the kubeconfig of the cluster. And it watches the access logs until a request from "alermanager" is received. +// When the request is received it sets its deployment annotation "didReceiveRequestFromAlertmanager" to "true" while the annotations being watched by the test itself. +func createAlertWebhookReceiverDeployment(client *rancher.Client, clusterID, namespace, deploymentName string) (*v1.SteveAPIObject, error) { + serviceAccountName := "alert-receiver-sa-" + namegenerator.RandStringLower(defaultRandStringLength) + clusterRoleBindingName := "alert-receiver-cluster-admin-" + namegenerator.RandStringLower(defaultRandStringLength) + configMapName := "alert-receiver-cm-" + namegenerator.RandStringLower(defaultRandStringLength) + + steveclient, err := client.Steve.ProxyDownstream(clusterID) + if err != nil { + return nil, err + } + + // Create webhook receiver service account + serviceAccount := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceAccountName, + Namespace: namespace, + }, + } + + _, err = steveclient.SteveType(serviceaccounts.ServiceAccountSteveType).Create(serviceAccount) + if err != nil { + return nil, err + } + + // Create webhook receiver cluster role binding + clusterRoleBinding := &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterRoleBindingName, + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: serviceAccount.Name, + Namespace: namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + APIGroup: rbacv1.SchemeGroupVersion.Group, + Kind: "ClusterRole", + Name: "cluster-admin", + }, + } + + _, err = steveclient.SteveType(clusterrolebindings.ClusterRoleBindingSteveType).Create(clusterRoleBinding) + if err != nil { + return nil, err + } + + labels := map[string]string{} + labels["workload.user.cattle.io/workloadselector"] = fmt.Sprintf("apps.deployment-%v-%v", namespace, deploymentName) + + // Create webhook receiver config map + configmap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + Namespace: namespace, + Labels: labels, + }, + Data: map[string]string{ + "config": kubeConfig, + }, + } + + _, err = steveclient.SteveType(configmaps.ConfigMapSteveType).Create(configmap) + if err != nil { + return nil, err + } + + imageSetting, err := client.Management.Setting.ByID(rancherShellSettingID) + if err != nil { + return nil, err + } + + // Create webhook receiver deployment + var runAsUser int64 + var runAsGroup int64 + podSpecTemplate := corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "alert-receiver-deployment", + Namespace: namespace, + Labels: labels, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: serviceAccount.Name, + Containers: []corev1.Container{ + { + Name: "kubectl", + Image: imageSetting.Value, + Command: []string{"/bin/sh", "-c"}, + Args: []string{ + fmt.Sprintf( + `until [ "$didReceiveRequestFromAlertmanager" = true ]; do if grep -q "Alertmanager" "/traefik/access.log"; then kubectl patch deployment %s -n %s --type "json" -p '[{"op":"add","path":"/metadata/annotations/%s","value":"%s"}]'; didReceiveRequestFromAlertmanager=true; sleep 5m; else sleep 10; echo "Checking logs file one more time"; fi; done`, + deploymentName, namespace, webhookReceiverAnnotationKey, webhookReceiverAnnotationValue, + ), + }, + SecurityContext: &corev1.SecurityContext{ + RunAsUser: &runAsUser, + RunAsGroup: &runAsGroup, + }, + VolumeMounts: []corev1.VolumeMount{ + {Name: "config", MountPath: "/root/usr/share/.kube/"}, + {Name: "logs", MountPath: "/traefik"}, + }, + }, + { + Name: "traefik", + Image: "traefik:latest", + Args: []string{ + "--entrypoints.web.address=:80", "--api.dashboard=true", "--api.insecure=true", "--accesslog=true", "--accesslog.filepath=/var/log/traefik/access.log", "--log.level=INFO", "--accesslog.fields.headers.defaultmode=keep", + }, + Ports: []corev1.ContainerPort{ + { + ContainerPort: 80, + Protocol: corev1.ProtocolTCP, + }, + { + ContainerPort: 8080, + Protocol: corev1.ProtocolTCP, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + {Name: "logs", MountPath: "/var/log/traefik"}, + }, + }, + }, + Volumes: []corev1.Volume{ + { + Name: "config", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configmap.Name}, + }, + }, + }, + { + Name: "logs", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, + }, + } + + isCattleLabeled := true + deploymentTemplate := workloads.NewDeploymentTemplate(deploymentName, namespace, podSpecTemplate, isCattleLabeled, nil) + deployment, err := steveclient.SteveType(workloads.DeploymentSteveType).Create(deploymentTemplate) + if err != nil { + return deployment, err + } + + return deployment, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring_test.go new file mode 100644 index 0000000..d9e90f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/monitoring_test.go @@ -0,0 +1,316 @@ +//go:build (validation || infra.rke1 || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !sanity && !extended + +package charts + +import ( + "fmt" + "math/rand" + "net/url" + "testing" + + "github.com/rancher/norman/types" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/ingresses" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/secrets" + "github.com/rancher/shepherd/extensions/services" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type MonitoringTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + project *management.Project + chartInstallOptions *charts.InstallOptions + chartFeatureOptions *charts.RancherMonitoringOpts +} + +func (m *MonitoringTestSuite) TearDownSuite() { + m.session.Cleanup() +} + +func (m *MonitoringTestSuite) SetupSuite() { + testSession := session.NewSession() + m.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(m.T(), err) + + m.client = client + + // Get clusterName from config yaml + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(m.T(), clusterName, "Cluster name to install is not set") + + // Get cluster meta + cluster, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(m.T(), err) + + // Change alert manager and grafana paths if it's not local cluster + if !cluster.IsLocal { + alertManagerPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, alertManagerPath) + grafanaPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, grafanaPath) + prometheusTargetsPathAPI = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, prometheusTargetsPathAPI) + } + + // Change prometheus paths to use the clusterID + prometheusGraphPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, prometheusGraphPath) + prometheusRulesPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, prometheusRulesPath) + prometheusTargetsPath = fmt.Sprintf("k8s/clusters/%s/%s", cluster.ID, prometheusTargetsPath) + + // Get latest versions of the monitoring chart + latestMonitoringVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherMonitoringName, catalog.RancherChartRepo) + require.NoError(m.T(), err) + + // Get project system projectId + project, err := projects.GetProjectByName(client, cluster.ID, projectName) + require.NoError(m.T(), err) + + m.project = project + require.NotEmpty(m.T(), m.project) + + m.chartInstallOptions = &charts.InstallOptions{ + Cluster: cluster, + Version: latestMonitoringVersion, + ProjectID: m.project.ID, + } + m.chartFeatureOptions = &charts.RancherMonitoringOpts{ + IngressNginx: true, + ControllerManager: true, + Etcd: true, + Proxy: true, + Scheduler: true, + } +} + +func (m *MonitoringTestSuite) TestMonitoringChart() { + subSession := m.session.NewSession() + defer subSession.Cleanup() + + client, err := m.client.WithSession(subSession) + require.NoError(m.T(), err) + + steveclient, err := client.Steve.ProxyDownstream(m.project.ClusterID) + require.NoError(m.T(), err) + + m.T().Log("Checking if the monitoring chart is already installed") + initialMonitoringChart, err := charts.GetChartStatus(client, m.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(m.T(), err) + + if !initialMonitoringChart.IsAlreadyInstalled { + m.T().Log("Installing monitoring chart") + err = charts.InstallRancherMonitoringChart(client, m.chartInstallOptions, m.chartFeatureOptions) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart StatefulSets to have expected number of ready replicas") + err = charts.WatchAndWaitStatefulSets(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + } + + paths := []string{alertManagerPath, grafanaPath, prometheusGraphPath, prometheusRulesPath, prometheusTargetsPath} + for _, path := range paths { + m.T().Logf("Validating %s is accessible", path) + result, err := ingresses.IsIngressExternallyAccessible(client, client.RancherConfig.Host, path, true) + assert.NoError(m.T(), err) + assert.True(m.T(), result) + } + + m.T().Log("Validating all Prometheus active targets are up") + prometheusTargetsResult, err := checkPrometheusTargets(client) + assert.NoError(m.T(), err) + assert.True(m.T(), prometheusTargetsResult) + + m.T().Log("Creating webhook receiver's namespace") + webhookReceiverNamespace, err := namespaces.CreateNamespace(client, webhookReceiverNamespaceName, "{}", map[string]string{}, map[string]string{}, m.project) + require.NoError(m.T(), err) + + m.T().Log("Creating alert webhook receiver deployment and its resources") + alertWebhookReceiverDeploymentResp, err := createAlertWebhookReceiverDeployment(client, m.project.ClusterID, webhookReceiverNamespace.Name, webhookReceiverDeploymentName) + require.NoError(m.T(), err) + assert.Equal(m.T(), alertWebhookReceiverDeploymentResp.Name, webhookReceiverDeploymentName) + + m.T().Log("Waiting webhook receiver deployment to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, m.project.ClusterID, webhookReceiverNamespace.Name, metav1.ListOptions{}) + require.NoError(m.T(), err) + + alertWebhookReceiverDeploymentSpec := &appv1.DeploymentSpec{} + err = v1.ConvertToK8sType(alertWebhookReceiverDeploymentResp.Spec, alertWebhookReceiverDeploymentSpec) + require.NoError(m.T(), err) + + m.T().Log("Creating node port service for webhook receiver deployment") + webhookServiceTemplate := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: webhookReceiverServiceName, + Namespace: webhookReceiverNamespace.Name, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeNodePort, + Ports: []corev1.ServicePort{ + { + Name: "port", + Port: 8080, + }, + }, + Selector: alertWebhookReceiverDeploymentSpec.Template.Labels, + }, + } + webhookReceiverServiceResp, err := steveclient.SteveType(services.ServiceSteveType).Create(webhookServiceTemplate) + require.NoError(m.T(), err) + + webhookReceiverServiceSpec := &corev1.ServiceSpec{} + err = v1.ConvertToK8sType(webhookReceiverServiceResp.Spec, webhookReceiverServiceSpec) + require.NoError(m.T(), err) + + // Get a random worker node' public external IP of a specific cluster + nodeCollection, err := client.Management.Node.List(&types.ListOpts{Filters: map[string]interface{}{ + "clusterId": m.project.ClusterID, + }}) + require.NoError(m.T(), err) + workerNodePublicIPs := []string{} + for _, node := range nodeCollection.Data { + workerNodePublicIPs = append(workerNodePublicIPs, node.Annotations["rke.cattle.io/external-ip"]) + } + randWorkerNodePublicIP := workerNodePublicIPs[rand.Intn(len(workerNodePublicIPs))] + + // Get URL and string versions of origin with random node' public IP + hostWithProtocol := fmt.Sprintf("http://%v:%v", randWorkerNodePublicIP, webhookReceiverServiceSpec.Ports[0].NodePort) + urlOfHost, err := url.Parse(hostWithProtocol) + require.NoError(m.T(), err) + + m.T().Logf("Getting alert manager secret to edit receiver") + alertManagerSecretResp, err := steveclient.SteveType(secrets.SecretSteveType).ByID(alertManagerSecretID) + require.NoError(m.T(), err) + + alertManagerSecret := &corev1.Secret{} + err = v1.ConvertToK8sType(alertManagerSecretResp.JSONResp, alertManagerSecret) + require.NoError(m.T(), err) + + m.T().Logf("Editing alert manager secret receivers") + encodedAlertConfigWithReceiver, err := editAlertReceiver(alertManagerSecret.Data[secretPath], urlOfHost) + require.NoError(m.T(), err) + + alertManagerSecret.Data[secretPath] = encodedAlertConfigWithReceiver + + editedReceiverSecretResp, err := steveclient.SteveType(secrets.SecretSteveType).Update(alertManagerSecretResp, alertManagerSecret) + require.NoError(m.T(), err) + assert.Equal(m.T(), editedReceiverSecretResp.Name, charts.RancherMonitoringAlertSecret) + + m.T().Logf("Creating prometheus rule") + err = createPrometheusRule(client, m.project.ClusterID) + require.NoError(m.T(), err) + + m.T().Logf("Getting alert manager secret to edit routes") + alertManagerSecretResp, err = steveclient.SteveType(secrets.SecretSteveType).ByID(alertManagerSecretID) + require.NoError(m.T(), err) + + err = v1.ConvertToK8sType(alertManagerSecretResp.JSONResp, alertManagerSecret) + require.NoError(m.T(), err) + + m.T().Logf("Editing alert manager secret routes") + encodedAlertConfigWithRoute, err := editAlertRoute(alertManagerSecret.Data[secretPath]) + require.NoError(m.T(), err) + + alertManagerSecret.Data[secretPath] = encodedAlertConfigWithRoute + + editedRouteSecretResp, err := steveclient.SteveType(secrets.SecretSteveType).Update(alertManagerSecretResp, alertManagerSecret) + require.NoError(m.T(), err) + assert.Equal(m.T(), editedRouteSecretResp.Name, charts.RancherMonitoringAlertSecret) + + m.T().Logf("Validating traefik is accessible externally") + host := fmt.Sprintf("%v:%v", randWorkerNodePublicIP, webhookReceiverServiceSpec.Ports[0].NodePort) + result, err := ingresses.IsIngressExternallyAccessible(client, host, "dashboard", false) + assert.NoError(m.T(), err) + assert.True(m.T(), result) + + m.T().Logf("Validating alertmanager sent alert to webhook receiver") + err = charts.WatchAndWaitDeploymentForAnnotation(client, m.project.ClusterID, webhookReceiverNamespace.Name, alertWebhookReceiverDeploymentResp.Name, webhookReceiverAnnotationKey, webhookReceiverAnnotationValue) + require.NoError(m.T(), err) +} + +func (m *MonitoringTestSuite) TestUpgradeMonitoringChart() { + subSession := m.session.NewSession() + defer subSession.Cleanup() + + client, err := m.client.WithSession(subSession) + require.NoError(m.T(), err) + + m.T().Log("Checking if the monitoring chart is installed with one of the previous versions") + initialMonitoringChart, err := charts.GetChartStatus(client, m.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(m.T(), err) + + // Change monitoring install option version to previous version of the latest version + versionsList, err := client.Catalog.GetListChartVersions(charts.RancherMonitoringName, catalog.RancherChartRepo) + require.NoError(m.T(), err) + require.Greaterf(m.T(), len(versionsList), 1, "There should be at least 2 versions of the monitoring chart") + versionLatest := versionsList[0] + versionBeforeLatest := versionsList[1] + m.chartInstallOptions.Version = versionBeforeLatest + + if initialMonitoringChart.IsAlreadyInstalled && initialMonitoringChart.ChartDetails.Spec.Chart.Metadata.Version == versionLatest { + m.T().Skip("Skipping the upgrade case, monitoring chart is already installed with the latest version") + } + + if !initialMonitoringChart.IsAlreadyInstalled { + m.T().Log("Installing monitoring chart with the last but one version") + err = charts.InstallRancherMonitoringChart(client, m.chartInstallOptions, m.chartFeatureOptions) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart deployments to have expected number of available replicas") + err = charts.WatchAndWaitDeployments(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart DaemonSets to have expected number of available nodes") + err = charts.WatchAndWaitDaemonSets(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + + m.T().Log("Waiting monitoring chart StatefulSets to have expected number of ready replicas") + err = charts.WatchAndWaitStatefulSets(client, m.project.ClusterID, charts.RancherMonitoringNamespace, metav1.ListOptions{}) + require.NoError(m.T(), err) + } + + monitoringChartPreUpgrade, err := charts.GetChartStatus(client, m.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(m.T(), err) + + // Validate current version of rancher monitoring is one of the versions before latest + chartVersionPreUpgrade := monitoringChartPreUpgrade.ChartDetails.Spec.Chart.Metadata.Version + assert.Contains(m.T(), versionsList[1:], chartVersionPreUpgrade) + + m.chartInstallOptions.Version, err = client.Catalog.GetLatestChartVersion(charts.RancherMonitoringName, catalog.RancherChartRepo) + require.NoError(m.T(), err) + + m.T().Log("Upgrading monitoring chart with the latest version") + err = charts.UpgradeRancherMonitoringChart(client, m.chartInstallOptions, m.chartFeatureOptions) + require.NoError(m.T(), err) + + monitoringChartPostUpgrade, err := charts.GetChartStatus(client, m.project.ClusterID, charts.RancherMonitoringNamespace, charts.RancherMonitoringName) + require.NoError(m.T(), err) + + // Compare rancher monitoring versions + chartVersionPostUpgrade := monitoringChartPostUpgrade.ChartDetails.Spec.Chart.Metadata.Version + assert.Equal(m.T(), m.chartInstallOptions.Version, chartVersionPostUpgrade) +} + +func TestMonitoringTestSuite(t *testing.T) { + suite.Run(t, new(MonitoringTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/resources/alertmanagerstypes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/resources/alertmanagerstypes.go new file mode 100644 index 0000000..f7f86a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/resources/alertmanagerstypes.go @@ -0,0 +1,440 @@ +package resources + +import ( + "net/url" + "time" + + "github.com/prometheus/common/model" +) + +// URL is a custom type that represents an HTTP or HTTPS URL and allows validation at configuration load time. +type URL struct { + *url.URL +} + +// HostPort represents a "host:port" network address. +type HostPort struct { + Host string + Port string +} + +// Customization of Config type from alertmanager repo: +// https://github.com/prometheus/alertmanager/blob/main/config/config.go +// +// Custom global type to get around obfuscation of secret values when +// marshalling. See the following issue for details: +// https://github.com/prometheus/alertmanager/issues/1985 +type AlertmanagerConfig struct { + Global *GlobalConfig `yaml:"global,omitempty" json:"global,omitempty"` + Route *Route `yaml:"route,omitempty" json:"route,omitempty"` + InhibitRules []*inhibitRule `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"` + Receivers []*Receiver `yaml:"receivers,omitempty" json:"receivers,omitempty"` + MuteTimeIntervals []*timeInterval `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"` + TimeIntervals []*timeInterval `yaml:"time_intervals,omitempty" json:"time_intervals,omitempty"` + Templates []string `yaml:"templates" json:"templates"` +} + +type GlobalConfig struct { + // ResolveTimeout is the time after which an alert is declared resolved + // if it has not been updated. + ResolveTimeout *model.Duration `yaml:"resolve_timeout,omitempty" json:"resolve_timeout,omitempty"` + + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + + SMTPFrom string `yaml:"smtp_from,omitempty" json:"smtp_from,omitempty"` + SMTPHello string `yaml:"smtp_hello,omitempty" json:"smtp_hello,omitempty"` + SMTPSmarthost HostPort `yaml:"smtp_smarthost,omitempty" json:"smtp_smarthost,omitempty"` + SMTPAuthUsername string `yaml:"smtp_auth_username,omitempty" json:"smtp_auth_username,omitempty"` + SMTPAuthPassword string `yaml:"smtp_auth_password,omitempty" json:"smtp_auth_password,omitempty"` + SMTPAuthPasswordFile string `yaml:"smtp_auth_password_file,omitempty" json:"smtp_auth_password_file,omitempty"` + SMTPAuthSecret string `yaml:"smtp_auth_secret,omitempty" json:"smtp_auth_secret,omitempty"` + SMTPAuthIdentity string `yaml:"smtp_auth_identity,omitempty" json:"smtp_auth_identity,omitempty"` + SMTPRequireTLS *bool `yaml:"smtp_require_tls,omitempty" json:"smtp_require_tls,omitempty"` + SlackAPIURL *URL `yaml:"slack_api_url,omitempty" json:"slack_api_url,omitempty"` + SlackAPIURLFile string `yaml:"slack_api_url_file,omitempty" json:"slack_api_url_file,omitempty"` + PagerdutyURL *URL `yaml:"pagerduty_url,omitempty" json:"pagerduty_url,omitempty"` + HipchatAPIURL *URL `yaml:"hipchat_api_url,omitempty" json:"hipchat_api_url,omitempty"` + HipchatAuthToken string `yaml:"hipchat_auth_token,omitempty" json:"hipchat_auth_token,omitempty"` + OpsGenieAPIURL *URL `yaml:"opsgenie_api_url,omitempty" json:"opsgenie_api_url,omitempty"` + OpsGenieAPIKey string `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"` + OpsGenieAPIKeyFile string `yaml:"opsgenie_api_key_file,omitempty" json:"opsgenie_api_key_file,omitempty"` + WeChatAPIURL *URL `yaml:"wechat_api_url,omitempty" json:"wechat_api_url,omitempty"` + WeChatAPISecret string `yaml:"wechat_api_secret,omitempty" json:"wechat_api_secret,omitempty"` + WeChatAPICorpID string `yaml:"wechat_api_corp_id,omitempty" json:"wechat_api_corp_id,omitempty"` + VictorOpsAPIURL *URL `yaml:"victorops_api_url,omitempty" json:"victorops_api_url,omitempty"` + VictorOpsAPIKey string `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"` + VictorOpsAPIKeyFile string `yaml:"victorops_api_key_file,omitempty" json:"victorops_api_key_file,omitempty"` + TelegramAPIURL *URL `yaml:"telegram_api_url,omitempty" json:"telegram_api_url,omitempty"` + WebexAPIURL *URL `yaml:"webex_api_url,omitempty" json:"webex_api_url,omitempty"` +} + +type Route struct { + Receiver string `yaml:"receiver,omitempty" json:"receiver,omitempty"` + GroupByStr []string `yaml:"group_by,omitempty" json:"group_by,omitempty"` + Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"` + MatchRE map[string]string `yaml:"match_re,omitempty" json:"match_re,omitempty"` + Matchers []string `yaml:"matchers,omitempty" json:"matchers,omitempty"` + Continue bool `yaml:"continue,omitempty" json:"continue,omitempty"` + Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"` + GroupWait string `yaml:"group_wait,omitempty" json:"group_wait,omitempty"` + GroupInterval string `yaml:"group_interval,omitempty" json:"group_interval,omitempty"` + RepeatInterval string `yaml:"repeat_interval,omitempty" json:"repeat_interval,omitempty"` + MuteTimeIntervals []string `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"` + ActiveTimeIntervals []string `yaml:"active_time_intervals,omitempty" json:"active_time_intervals,omitempty"` +} + +type inhibitRule struct { + TargetMatch map[string]string `yaml:"target_match,omitempty" json:"target_match,omitempty"` + TargetMatchRE map[string]string `yaml:"target_match_re,omitempty" json:"target_match_re,omitempty"` + TargetMatchers []string `yaml:"target_matchers,omitempty" json:"target_matchers,omitempty"` + SourceMatch map[string]string `yaml:"source_match,omitempty" json:"source_match,omitempty"` + SourceMatchRE map[string]string `yaml:"source_match_re,omitempty" json:"source_match_re,omitempty"` + SourceMatchers []string `yaml:"source_matchers,omitempty" json:"source_matchers,omitempty"` + Equal []string `yaml:"equal,omitempty" json:"equal,omitempty"` +} + +type Receiver struct { + Name string `yaml:"name" json:"name"` + OpsgenieConfigs []*opsgenieConfig `yaml:"opsgenie_configs,omitempty" json:"opsgenie_configs,omitempty"` + PagerdutyConfigs []*pagerdutyConfig `yaml:"pagerduty_configs,omitempty" json:"pagerduty_configs,omitempty"` + SlackConfigs []*slackConfig `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"` + WebhookConfigs []*WebhookConfig `yaml:"webhook_configs,omitempty" json:"webhook_configs,omitempty"` + WeChatConfigs []*weChatConfig `yaml:"wechat_configs,omitempty" json:"wechat_config,omitempty"` + EmailConfigs []*emailConfig `yaml:"email_configs,omitempty" json:"email_configs,omitempty"` + PushoverConfigs []*pushoverConfig `yaml:"pushover_configs,omitempty" json:"pushover_configs,omitempty"` + VictorOpsConfigs []*victorOpsConfig `yaml:"victorops_configs,omitempty" json:"victorops_configs,omitempty"` + SNSConfigs []*snsConfig `yaml:"sns_configs,omitempty" json:"sns_configs,omitempty"` + TelegramConfigs []*telegramConfig `yaml:"telegram_configs,omitempty" json:"telegram_configs,omitempty"` + DiscordConfigs []*discordConfig `yaml:"discord_configs,omitempty"` + WebexConfigs []*webexConfig `yaml:"webex_configs,omitempty"` +} + +type WebhookConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + URL string `yaml:"url,omitempty" json:"url,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + MaxAlerts int32 `yaml:"max_alerts,omitempty" json:"max_alerts,omitempty"` +} + +type pagerdutyConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + ServiceKey string `yaml:"service_key,omitempty" json:"service_key,omitempty"` + ServiceKeyFile string `yaml:"service_key_file,omitempty" json:"service_key_file,omitempty"` + RoutingKey string `yaml:"routing_key,omitempty" json:"routing_key,omitempty"` + RoutingKeyFile string `yaml:"routing_key_file,omitempty" json:"routing_key_file,omitempty"` + URL string `yaml:"url,omitempty" json:"url,omitempty"` + Client string `yaml:"client,omitempty" json:"client,omitempty"` + ClientURL string `yaml:"client_url,omitempty" json:"client_url,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Details map[string]string `yaml:"details,omitempty" json:"details,omitempty"` + Images []pagerdutyImage `yaml:"images,omitempty" json:"images,omitempty"` + Links []pagerdutyLink `yaml:"links,omitempty" json:"links,omitempty"` + Severity string `yaml:"severity,omitempty" json:"severity,omitempty"` + Class string `yaml:"class,omitempty" json:"class,omitempty"` + Component string `yaml:"component,omitempty" json:"component,omitempty"` + Group string `yaml:"group,omitempty" json:"group,omitempty"` + Source string `yaml:"source,omitempty" json:"source,omitempty"` +} + +type opsgenieConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + APIKey string `yaml:"api_key,omitempty" json:"api_key,omitempty"` + APIKeyFile string `yaml:"api_key_file,omitempty" json:"api_key_file,omitempty"` + APIURL string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + Description string `yaml:"description,omitempty" json:"description,omitempty"` + Source string `yaml:"source,omitempty" json:"source,omitempty"` + Details map[string]string `yaml:"details,omitempty" json:"details,omitempty"` + Responders []opsgenieResponder `yaml:"responders,omitempty" json:"responders,omitempty"` + Tags string `yaml:"tags,omitempty" json:"tags,omitempty"` + Note string `yaml:"note,omitempty" json:"note,omitempty"` + Priority string `yaml:"priority,omitempty" json:"priority,omitempty"` + UpdateAlerts *bool `yaml:"update_alerts,omitempty" json:"update_alerts,omitempty"` + Entity string `yaml:"entity,omitempty" json:"entity,omitempty"` + Actions string `yaml:"actions,omitempty" json:"actions,omitempty"` +} + +type weChatConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + APISecret string `yaml:"api_secret,omitempty" json:"api_secret,omitempty"` + APIURL string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + CorpID string `yaml:"corp_id,omitempty" json:"corp_id,omitempty"` + AgentID string `yaml:"agent_id,omitempty" json:"agent_id,omitempty"` + ToUser string `yaml:"to_user,omitempty" json:"to_user,omitempty"` + ToParty string `yaml:"to_party,omitempty" json:"to_party,omitempty"` + ToTag string `yaml:"to_tag,omitempty" json:"to_tag,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + MessageType string `yaml:"message_type,omitempty" json:"message_type,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` +} + +type slackConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + APIURL string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + APIURLFile string `yaml:"api_url_file,omitempty" json:"api_url_file,omitempty"` + Channel string `yaml:"channel,omitempty" json:"channel,omitempty"` + Username string `yaml:"username,omitempty" json:"username,omitempty"` + Color string `yaml:"color,omitempty" json:"color,omitempty"` + Title string `yaml:"title,omitempty" json:"title,omitempty"` + TitleLink string `yaml:"title_link,omitempty" json:"title_link,omitempty"` + Pretext string `yaml:"pretext,omitempty" json:"pretext,omitempty"` + Text string `yaml:"text,omitempty" json:"text,omitempty"` + Fields []slackField `yaml:"fields,omitempty" json:"fields,omitempty"` + ShortFields bool `yaml:"short_fields,omitempty" json:"short_fields,omitempty"` + Footer string `yaml:"footer,omitempty" json:"footer,omitempty"` + Fallback string `yaml:"fallback,omitempty" json:"fallback,omitempty"` + CallbackID string `yaml:"callback_id,omitempty" json:"callback_id,omitempty"` + IconEmoji string `yaml:"icon_emoji,omitempty" json:"icon_emoji,omitempty"` + IconURL string `yaml:"icon_url,omitempty" json:"icon_url,omitempty"` + ImageURL string `yaml:"image_url,omitempty" json:"image_url,omitempty"` + ThumbURL string `yaml:"thumb_url,omitempty" json:"thumb_url,omitempty"` + LinkNames bool `yaml:"link_names,omitempty" json:"link_names,omitempty"` + MrkdwnIn []string `yaml:"mrkdwn_in,omitempty" json:"mrkdwn_in,omitempty"` + Actions []slackAction `yaml:"actions,omitempty" json:"actions,omitempty"` +} + +type HTTPClientConfig struct { + Authorization *authorization `yaml:"authorization,omitempty"` + BasicAuth *basicAuth `yaml:"basic_auth,omitempty"` + OAuth2 *oauth2 `yaml:"oauth2,omitempty"` + BearerToken string `yaml:"bearer_token,omitempty"` + BearerTokenFile string `yaml:"bearer_token_file,omitempty"` + ProxyURL string `yaml:"proxy_url,omitempty"` + TLSConfig *tlsConfig `yaml:"tls_config,omitempty"` + FollowRedirects *bool `yaml:"follow_redirects,omitempty"` + EnableHTTP2 *bool `yaml:"enable_http2,omitempty"` +} + +type tlsConfig struct { + CAFile string `yaml:"ca_file,omitempty"` + CertFile string `yaml:"cert_file,omitempty"` + KeyFile string `yaml:"key_file,omitempty"` + ServerName string `yaml:"server_name,omitempty"` + InsecureSkipVerify bool `yaml:"insecure_skip_verify"` + MinVersion string `yaml:"min_version,omitempty"` + MaxVersion string `yaml:"max_version,omitempty"` +} + +type authorization struct { + Type string `yaml:"type,omitempty"` + Credentials string `yaml:"credentials,omitempty"` + CredentialsFile string `yaml:"credentials_file,omitempty"` +} + +type basicAuth struct { + Username string `yaml:"username"` + Password string `yaml:"password,omitempty"` + PasswordFile string `yaml:"password_file,omitempty"` +} + +type oauth2 struct { + ClientID string `yaml:"client_id"` + ClientSecret string `yaml:"client_secret"` + ClientSecretFile string `yaml:"client_secret_file,omitempty"` + Scopes []string `yaml:"scopes,omitempty"` + TokenURL string `yaml:"token_url"` + EndpointParams map[string]string `yaml:"endpoint_params,omitempty"` + ProxyURL string `yaml:"proxy_url,omitempty"` + + TLSConfig *tlsConfig `yaml:"tls_config,omitempty"` +} + +type pagerdutyLink struct { + Href string `yaml:"href,omitempty" json:"href,omitempty"` + Text string `yaml:"text,omitempty" json:"text,omitempty"` +} + +type pagerdutyImage struct { + Src string `yaml:"src,omitempty" json:"src,omitempty"` + Alt string `yaml:"alt,omitempty" json:"alt,omitempty"` + Href string `yaml:"href,omitempty" json:"href,omitempty"` +} + +type opsgenieResponder struct { + ID string `yaml:"id,omitempty" json:"id,omitempty"` + Name string `yaml:"name,omitempty" json:"name,omitempty"` + Username string `yaml:"username,omitempty" json:"username,omitempty"` + Type string `yaml:"type,omitempty" json:"type,omitempty"` +} + +type slackField struct { + Title string `yaml:"title,omitempty" json:"title,omitempty"` + Value string `yaml:"value,omitempty" json:"value,omitempty"` + Short bool `yaml:"short,omitempty" json:"short,omitempty"` +} + +type slackAction struct { + Type string `yaml:"type,omitempty" json:"type,omitempty"` + Text string `yaml:"text,omitempty" json:"text,omitempty"` + URL string `yaml:"url,omitempty" json:"url,omitempty"` + Style string `yaml:"style,omitempty" json:"style,omitempty"` + Name string `yaml:"name,omitempty" json:"name,omitempty"` + Value string `yaml:"value,omitempty" json:"value,omitempty"` + ConfirmField *slackConfirmationField `yaml:"confirm,omitempty" json:"confirm,omitempty"` +} + +type slackConfirmationField struct { + Text string `yaml:"text,omitempty" json:"text,omitempty"` + Title string `yaml:"title,omitempty" json:"title,omitempty"` + OkText string `yaml:"ok_text,omitempty" json:"ok_text,omitempty"` + DismissText string `yaml:"dismiss_text,omitempty" json:"dismiss_text,omitempty"` +} + +type emailConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + To string `yaml:"to,omitempty" json:"to,omitempty"` + From string `yaml:"from,omitempty" json:"from,omitempty"` + Hello string `yaml:"hello,omitempty" json:"hello,omitempty"` + Smarthost HostPort `yaml:"smarthost,omitempty" json:"smarthost,omitempty"` + AuthUsername string `yaml:"auth_username,omitempty" json:"auth_username,omitempty"` + AuthPassword string `yaml:"auth_password,omitempty" json:"auth_password,omitempty"` + AuthPasswordFile string `yaml:"auth_password_file,omitempty" json:"auth_password_file,omitempty"` + AuthSecret string `yaml:"auth_secret,omitempty" json:"auth_secret,omitempty"` + AuthIdentity string `yaml:"auth_identity,omitempty" json:"auth_identity,omitempty"` + Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"` + HTML *string `yaml:"html,omitempty" json:"html,omitempty"` + Text *string `yaml:"text,omitempty" json:"text,omitempty"` + RequireTLS *bool `yaml:"require_tls,omitempty" json:"require_tls,omitempty"` + TLSConfig *tlsConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"` +} + +type pushoverConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + UserKey string `yaml:"user_key,omitempty" json:"user_key,omitempty"` + Token string `yaml:"token,omitempty" json:"token,omitempty"` + Title string `yaml:"title,omitempty" json:"title,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + URL string `yaml:"url,omitempty" json:"url,omitempty"` + URLTitle string `yaml:"url_title,omitempty" json:"url_title,omitempty"` + Sound string `yaml:"sound,omitempty" json:"sound,omitempty"` + Priority string `yaml:"priority,omitempty" json:"priority,omitempty"` + Retry duration `yaml:"retry,omitempty" json:"retry,omitempty"` + Expire duration `yaml:"expire,omitempty" json:"expire,omitempty"` + HTML bool `yaml:"html,omitempty" json:"html,omitempty"` +} + +type snsConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + APIUrl string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + Sigv4 sigV4Config `yaml:"sigv4,omitempty" json:"sigv4,omitempty"` + TopicARN string `yaml:"topic_arn,omitempty" json:"topic_arn,omitempty"` + PhoneNumber string `yaml:"phone_number,omitempty" json:"phone_number,omitempty"` + TargetARN string `yaml:"target_arn,omitempty" json:"target_arn,omitempty"` + Subject string `yaml:"subject,omitempty" json:"subject,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + Attributes map[string]string `yaml:"attributes,omitempty" json:"attributes,omitempty"` +} + +type telegramConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + APIUrl string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + BotToken string `yaml:"bot_token,omitempty" json:"bot_token,omitempty"` + BotTokenFile string `yaml:"bot_token_file,omitempty" json:"bot_token_file,omitempty"` + ChatID int64 `yaml:"chat_id,omitempty" json:"chat_id,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` + DisableNotifications bool `yaml:"disable_notifications,omitempty" json:"disable_notifications,omitempty"` + ParseMode string `yaml:"parse_mode,omitempty" json:"parse_mode,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` +} + +type discordConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty"` + WebhookURL string `yaml:"webhook_url,omitempty"` + Title string `yaml:"title,omitempty"` + Message string `yaml:"message,omitempty"` +} + +type webexConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty"` + APIURL string `yaml:"api_url,omitempty"` + Message string `yaml:"message,omitempty"` + RoomID string `yaml:"room_id"` +} + +type sigV4Config struct { + Region string `yaml:"region,omitempty" json:"region,omitempty"` + AccessKey string `yaml:"access_key,omitempty" json:"access_key,omitempty"` + SecretKey string `yaml:"secret_key,omitempty" json:"secret_key,omitempty"` + Profile string `yaml:"profile,omitempty" json:"profile,omitempty"` + RoleARN string `yaml:"role_arn,omitempty" json:"role_arn,omitempty"` +} + +type duration time.Duration + +type victorOpsConfig struct { + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + HTTPConfig *HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + APIKey string `yaml:"api_key,omitempty" json:"api_key,omitempty"` + APIKeyFile string `yaml:"api_key_file,omitempty" json:"api_key_file,omitempty"` + APIURL string `yaml:"api_url,omitempty" json:"api_url,omitempty"` + RoutingKey string `yaml:"routing_key,omitempty" json:"routing_key,omitempty"` + MessageType string `yaml:"message_type,omitempty" json:"message_type,omitempty"` + StateMessage string `yaml:"state_message,omitempty" json:"state_message,omitempty"` + EntityDisplayName string `yaml:"entity_display_name,omitempty" json:"entity_display_name,omitempty"` + MonitoringTool string `yaml:"monitoring_tool,omitempty" json:"monitoring_tool,omitempty"` + CustomFields map[string]string `yaml:"custom_fields,omitempty" json:"custom_fields,omitempty"` +} + +type timeInterval TimeInterval + +// TimeInterval represents a named set of time intervals for which a route should be muted. +type TimeInterval struct { + Name string `yaml:"name" json:"name"` + TimeIntervals []TimeInterval1 `yaml:"time_intervals" json:"time_intervals"` +} + +// TimeInterval describes intervals of time. ContainsTime will tell you if a golang time is contained +// within the interval. +type TimeInterval1 struct { + Times []TimeRange `yaml:"times,omitempty" json:"times,omitempty"` + Weekdays []WeekdayRange `yaml:"weekdays,flow,omitempty" json:"weekdays,omitempty"` + DaysOfMonth []DayOfMonthRange `yaml:"days_of_month,flow,omitempty" json:"days_of_month,omitempty"` + Months []MonthRange `yaml:"months,flow,omitempty" json:"months,omitempty"` + Years []YearRange `yaml:"years,flow,omitempty" json:"years,omitempty"` + Location *Location `yaml:"location,flow,omitempty" json:"location,omitempty"` +} + +// TimeRange represents a range of minutes within a 1440 minute day, exclusive of the End minute. A day consists of 1440 minutes. +// For example, 4:00PM to End of the day would Begin at 1020 and End at 1440. +type TimeRange struct { + StartMinute int + EndMinute int +} + +// InclusiveRange is used to hold the Beginning and End values of many time interval components. +type InclusiveRange struct { + Begin int + End int +} + +// A WeekdayRange is an inclusive range between [0, 6] where 0 = Sunday. +type WeekdayRange struct { + InclusiveRange +} + +// A DayOfMonthRange is an inclusive range that may have negative Beginning/End values that represent distance from the End of the month Beginning at -1. +type DayOfMonthRange struct { + InclusiveRange +} + +// A MonthRange is an inclusive range between [1, 12] where 1 = January. +type MonthRange struct { + InclusiveRange +} + +// A YearRange is a positive inclusive range. +type YearRange struct { + InclusiveRange +} + +// A Location is a container for a time.Location, used for custom unmarshalling/validation logic. +type Location struct { + *time.Location +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook.go new file mode 100644 index 0000000..ded509f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook.go @@ -0,0 +1,43 @@ +package charts + +import ( + "strings" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/kubeapi/webhook" +) + +const ( + resourceName = "rancher.cattle.io" + restrictedAdmin = "restricted-admin" + admin = "admin" + localCluster = "local" +) + +func getWebhookNames(client *rancher.Client, clusterID, resourceName string) ([]string, error) { + webhookList, err := webhook.GetWebhook(client, clusterID, resourceName) + if err != nil { + return nil, err + } + + var webhookL []string + for _, webhook := range webhookList.Webhooks { + webhookL = append(webhookL, webhook.Name) + } + + return webhookL, nil + +} + +func validateWebhookPodLogs(podLogs string) interface{} { + + delimiter := "\n" + segments := strings.Split(podLogs, delimiter) + + for _, segment := range segments { + if strings.Contains(segment, "level=error") { + return "Error logs in webhook" + segment + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook_test.go new file mode 100644 index 0000000..0733027 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/charts/webhook_test.go @@ -0,0 +1,134 @@ +//go:build (validation || infra.any || cluster.any || stress) && !sanity && !extended + +package charts + +import ( + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubeconfig" + "github.com/rancher/shepherd/extensions/workloads/pods" + + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type WebhookTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + clusterName string + chartVersion string +} + +func (w *WebhookTestSuite) TearDownSuite() { + w.session.Cleanup() +} + +func (w *WebhookTestSuite) SetupSuite() { + testSession := session.NewSession() + w.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(w.T(), err) + + w.client = client + + // Get clusterName from config yaml + w.clusterName = client.RancherConfig.ClusterName + w.chartVersion, err = client.Catalog.GetLatestChartVersion(charts.RancherWebhookName, catalog.RancherChartRepo) + require.NoError(w.T(), err) +} + +func (w *WebhookTestSuite) TestWebhookChart() { + subSession := w.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + cluster string + }{ + {localCluster}, + {w.clusterName}, + } + + for _, tt := range tests { + + clusterID, err := clusters.GetClusterIDByName(w.client, tt.cluster) + require.NoError(w.T(), err) + + w.Run("Verify the version of webhook on "+tt.cluster, func() { + subSession := w.session.NewSession() + defer subSession.Cleanup() + + initialWebhookChart, err := charts.GetChartStatus(w.client, clusterID, charts.RancherWebhookNamespace, charts.RancherWebhookName) + require.NoError(w.T(), err) + chartVersion := initialWebhookChart.ChartDetails.Spec.Chart.Metadata.Version + require.NoError(w.T(), err) + assert.Equal(w.T(), w.chartVersion, chartVersion) + }) + + w.Run("Verify webhook pod logs", func() { + steveClient, err := w.client.Steve.ProxyDownstream(clusterID) + require.NoError(w.T(), err) + + pods, err := steveClient.SteveType(pods.PodResourceSteveType).NamespacedSteveClient(charts.RancherWebhookNamespace).List(nil) + require.NoError(w.T(), err) + + var podName string + for _, pod := range pods.Data { + if strings.Contains(pod.Name, charts.RancherWebhookName) { + podName = pod.Name + } + } + + podLogs, err := kubeconfig.GetPodLogs(w.client, clusterID, podName, charts.RancherWebhookNamespace, "") + require.NoError(w.T(), err) + webhookLogs := validateWebhookPodLogs(podLogs) + require.Nil(w.T(), webhookLogs) + }) + + w.Run("Verify the count of webhook is greater than zero and list webhooks", func() { + webhookList, err := getWebhookNames(w.client, clusterID, resourceName) + require.NoError(w.T(), err) + + assert.True(w.T(), len(webhookList) > 0, "Expected webhooks list to be greater than zero") + log.Info("Count of webhook obtained for the cluster: ", tt.cluster, " is ", len(webhookList)) + listStr := strings.Join(webhookList, ", ") + log.WithField("", listStr).Info("List of webhooks obtained for the ", tt.cluster) + }) + } +} + +func (w *WebhookTestSuite) TestWebhookEscalationCheck() { + w.Run("Verify escalation check", func() { + newUser, err := users.CreateUserWithRole(w.client, users.UserConfig(), restrictedAdmin) + require.NoError(w.T(), err) + w.T().Logf("Created user: %v", newUser.Name) + + restrictedAdminClient, err := w.client.AsUser(newUser) + require.NoError(w.T(), err) + + getAdminRole, err := restrictedAdminClient.Management.GlobalRole.ByID(admin) + require.NoError(w.T(), err) + updatedAdminRole := *getAdminRole + updatedAdminRole.NewUserDefault = true + + _, err = restrictedAdminClient.Management.GlobalRole.Update(getAdminRole, updatedAdminRole) + require.Error(w.T(), err) + errMessage := "admission webhook \"rancher.cattle.io.globalroles.management.cattle.io\" denied the request" + assert.Contains(w.T(), err.Error(), errMessage) + }) +} + +func TestWebhookTestSuite(t *testing.T) { + suite.Run(t, new(WebhookTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/README.md new file mode 100644 index 0000000..6a71c22 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/README.md @@ -0,0 +1,24 @@ +# CLI + +For CLI tests, the local cluster is used to perform each of the tests. It is important to note that you must have the Rancher CLI already installed and configured on your client machine before running this test. + +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: true/optional + rancherCLI: true +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/cli --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCLITestSuite$"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/cli_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/cli_test.go new file mode 100644 index 0000000..b404df5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/cli/cli_test.go @@ -0,0 +1,80 @@ +//go:build validation + +package cli + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/cli" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CLITestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (c *CLITestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *CLITestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client +} + +func (c *CLITestSuite) TestContext() { + err := cli.SwitchContext(c.client.CLI) + require.NoError(c.T(), err) +} + +func (c *CLITestSuite) TestProjects() { + var projectName = namegen.AppendRandomString("projects") + var clusterName = namegen.AppendRandomString("cluster") + + err := cli.CreateProjects(c.client.CLI, projectName, "local") + require.NoError(c.T(), err) + + err = cli.CreateProjects(c.client.CLI, projectName, clusterName) + require.Error(c.T(), err) + + err = cli.DeleteProjects(c.client.CLI, projectName) + require.NoError(c.T(), err) +} + +func (c *CLITestSuite) TestNamespaces() { + var namespaceName = namegen.AppendRandomString("ns") + var projectName = namegen.AppendRandomString("projects") + + err := cli.CreateNamespaces(c.client.CLI, namespaceName, projectName) + require.NoError(c.T(), err) + + err = cli.DeleteNamespaces(c.client.CLI, namespaceName, projectName) + require.NoError(c.T(), err) +} + +func (c *CLITestSuite) TestCatalog() { + var catalogName = namegen.AppendRandomString("catalog") + + err := cli.CreateCatalogs(c.client.CLI, catalogName) + require.NoError(c.T(), err) + + err = cli.DeleteCatalogs(c.client.CLI, catalogName) + require.NoError(c.T(), err) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestCLITestSuite(t *testing.T) { + suite.Run(t, new(CLITestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields.go new file mode 100644 index 0000000..61e8ced --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields.go @@ -0,0 +1,32 @@ +package configmaps + +import ( + "github.com/pkg/errors" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + cm "github.com/rancher/shepherd/extensions/configmaps" + "github.com/sirupsen/logrus" +) + +const ( + APIVersion = "v1" + Kind = "ConfigMap" +) + +func setPayload(apiObject *steveV1.SteveAPIObject, payload *cm.SteveConfigMap) error { + payload.APIVersion = APIVersion + payload.Kind = Kind + payload.Name = apiObject.Name + payload.Namespace = "default" + payload.ResourceVersion = apiObject.ResourceVersion + payload.UID = apiObject.UID + payload.State = &steveV1.State{} + payload.Relationships = &[]steveV1.Relationship{} + payload.Fields = []any{"foo", "bar"} + data, ok := apiObject.JSONResp["data"].(map[string]interface{}) + if !ok { + logrus.Println("Type assertion failed") + return errors.New("type assertion failed for apiObject.JSONResp[\"data\"]") + } + payload.Data = data + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields_test.go new file mode 100644 index 0000000..7b7f3ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configmaps/generatedfields_test.go @@ -0,0 +1,91 @@ +//go:build (infra.any || cluster.any || sanity || validation) && !stress && !extended + +package configmaps + +import ( + "fmt" + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + cm "github.com/rancher/shepherd/extensions/configmaps" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const configMapNamespace = "default" + +type ConfigMapTestSuite struct { + suite.Suite + client *rancher.Client + steveClient *steveV1.Client + session *session.Session + cluster *management.Cluster + nameSpacedV1Client *steveV1.NamespacedSteveClient + configMapPayload *cm.SteveConfigMap +} + +func (c *ConfigMapTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *ConfigMapTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + client, err := rancher.NewClient("", c.session) + require.NoError(c.T(), err) + c.client = client + c.steveClient = client.Steve +} + +func (c *ConfigMapTestSuite) TestSteveGeneratedFields() { + + steveClient := c.client.Steve + configMapName := namegenerator.AppendRandomString("test-configmap") + + v1ConfigMap := &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + Namespace: configMapNamespace, + }, + Data: map[string]string{ + "env": "qa", + }, + } + + configmapSteveObject, err := steveClient.SteveType(cm.ConfigMapSteveType).Create(v1ConfigMap) + require.NoError(c.T(), err) + + c.configMapPayload = new(cm.SteveConfigMap) + err = setPayload(configmapSteveObject, c.configMapPayload) + require.NoError(c.T(), err) + + headers, _, err := steveClient.SteveType("configmaps").NamespacedSteveClient(configMapNamespace).PerformPutCaptureHeaders(c.client.RancherConfig.Host, c.client.RancherConfig.AdminToken, c.configMapPayload.Name, c.configMapPayload) + require.NoError(c.T(), err) + + warnings, ok := headers["Warning"] + var failWarnings []string + if ok { + for _, warning := range warnings { + if strings.HasPrefix(warning, "299") { + logrus.Printf("Warning header found: %s", warning) + failWarnings = append(failWarnings, warning) + } + } + } + + if len(failWarnings) > 0 { + require.Fail(c.T(), fmt.Sprintf("Test failed due to warnings: \n%s", strings.Join(failWarnings, "\n"))) + } +} + +func TestConfigMapTestSuite(t *testing.T) { + suite.Run(t, new(ConfigMapTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configure.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configure.sh new file mode 100755 index 0000000..af742ba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/configure.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" + +env | egrep '^(ARM_|CATTLE_|ADMIN|USER|DO|RANCHER_|AWS_|DEBUG|LOGLEVEL|DEFAULT_|OS_|DOCKER_|CLOUD_|KUBE|BUILD_NUMBER|AZURE|TEST_|QASE_|SLACK_).*\=.+' | sort > .env + +if [ "false" != "${DEBUG}" ]; then + cat .env +fi \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/README.md new file mode 100644 index 0000000..2502635 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/README.md @@ -0,0 +1,34 @@ +# Deleting + +For deleting clusters, the following cluster types are supported for both node drivers and custom clusters: RKE1, RKE2, K3S. These tests are designed to accept an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, you should create one first before running these tests. + +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + clusterName: "cluster_to_run_tests_on" + insecure: true/optional + cleanup: false/optional +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +### RKE1 +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/deleting --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1ClusterDeleteTestSuite/TestDeletingRKE1Cluster"` + +### RKE2 | K3S +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/deleting --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestClusterDeleteTestSuite/TestDeletingCluster"` + +### Delete Init Machine Suite (rke2/k3s) +automated check to validate [this issue](https://github.com/rancher/rancher/issues/42709), where the "init node" machine for v2 prov clusters would hang in deletion state and fail to be removed. + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/deleting --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestDeleteInitMachineTestSuite/TestDeleteInitMachine"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_rke1_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_rke1_test.go new file mode 100644 index 0000000..89eaaa0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_rke1_test.go @@ -0,0 +1,57 @@ +//go:build (infra.rke1 || validation) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !stress && !sanity && !extended + +package deleting + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1ClusterDeleteTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (c *RKE1ClusterDeleteTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *RKE1ClusterDeleteTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client +} + +func (c *RKE1ClusterDeleteTestSuite) TestDeletingRKE1Cluster() { + tests := []struct { + name string + client *rancher.Client + }{ + {"Deleting cluster", c.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(c.client, c.client.RancherConfig.ClusterName) + require.NoError(c.T(), err) + + clusters.DeleteRKE1Cluster(tt.client, clusterID) + provisioning.VerifyDeleteRKE1Cluster(c.T(), tt.client, clusterID) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1ClusterDeleteTestSuite(t *testing.T) { + suite.Run(t, new(RKE1ClusterDeleteTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_test.go new file mode 100644 index 0000000..d579207 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_cluster_test.go @@ -0,0 +1,75 @@ +//go:build (infra.rke2k3s || validation) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !stress && !sanity && !extended + +package deleting + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type ClusterDeleteTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (c *ClusterDeleteTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *ClusterDeleteTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client +} + +func (c *ClusterDeleteTestSuite) TestDeletingCluster() { + tests := []struct { + name string + client *rancher.Client + }{ + {"cluster", c.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetV1ProvisioningClusterByName(c.client, c.client.RancherConfig.ClusterName) + require.NoError(c.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(c.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(c.T(), err) + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "Deleting RKE2 " + tt.name + } else { + tt.name = "Deleting K3S " + tt.name + } + + c.Run(tt.name, func() { + clusters.DeleteK3SRKE2Cluster(tt.client, clusterID) + provisioning.VerifyDeleteRKE2K3SCluster(c.T(), tt.client, clusterID) + }) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestClusterDeleteTestSuite(t *testing.T) { + suite.Run(t, new(ClusterDeleteTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine.go new file mode 100644 index 0000000..7b85ad3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine.go @@ -0,0 +1,33 @@ +package deleting + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/steve" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" +) + +const ( + machineSteveResourceType = "cluster.x-k8s.io.machine" +) + +func deleteInitMachine(t *testing.T, client *rancher.Client, clusterID string) { + initMachine, err := machinepools.GetInitMachine(client, clusterID) + require.NoError(t, err) + + err = client.Steve.SteveType(machineSteveResourceType).Delete(initMachine) + require.NoError(t, err) + + logrus.Info("Awaiting machine deletion...") + err = steve.WaitForSteveResourceDeletion(client, defaults.FiveHundredMillisecondTimeout, defaults.TenMinuteTimeout, machineSteveResourceType, initMachine.ID) + require.NoError(t, err) + + logrus.Info("Awaiting machine replacement...") + err = clusters.WatchAndWaitForCluster(client, clusterID) + require.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine_test.go new file mode 100644 index 0000000..1eaed39 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/deleting/delete_init_machine_test.go @@ -0,0 +1,71 @@ +//go:build (infra.rke2k3s || validation) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !stress && !sanity && !extended + +package deleting + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + ProvisioningSteveResourceType = "provisioning.cattle.io.cluster" +) + +type DeleteInitMachineTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (d *DeleteInitMachineTestSuite) TearDownSuite() { + d.session.Cleanup() +} + +func (d *DeleteInitMachineTestSuite) SetupSuite() { + testSession := session.NewSession() + d.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(d.T(), err) + + d.client = client +} + +func (d *DeleteInitMachineTestSuite) TestDeleteInitMachine() { + clusterID, err := clusters.GetV1ProvisioningClusterByName(d.client, d.client.RancherConfig.ClusterName) + require.NoError(d.T(), err) + + cluster, err := d.client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(d.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(d.T(), err) + + name := "K3S" + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + name = "RKE2" + } + + require.NotContains(d.T(), updatedCluster.Spec.KubernetesVersion, "-rancher") + require.NotEmpty(d.T(), updatedCluster.Spec.KubernetesVersion) + + d.Run(name, func() { + deleteInitMachine(d.T(), d.client, clusterID) + }) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestDeleteInitMachineTestSuite(t *testing.T) { + suite.Run(t, new(DeleteInitMachineTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/README.md new file mode 100644 index 0000000..625ff92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/README.md @@ -0,0 +1,118 @@ +# Node Scaling + +These tests are designed to accept an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, you should create one first before running this test. + +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) +2. [Replacing Nodes](#Node-Replacing) +3. [Scaling Existing Node Pools](#Scaling-Existing-Node-Pools) + +## Getting Started +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + clusterName: "cluster_to_run_tests_on" + insecure: true/optional + cleanup: false/optional +``` + +## Node Replacing +Node replacement tests require that the given pools have unique, distinct roles and more than 1 node per pool. Typically, a cluster with the following 3 pools is used for testing: +```yaml +provisioningInput: + nodePools: # nodePools is specific for RKE1 clusters. + - nodeRoles: + etcd: true + quantity: 3 + - nodeRoles: + controlplane: true + quantity: 2 + - nodeRoles: + worker: true + quantity: 3 + machinePools: # machienPools is specific for RKE2/K3s clusters. + - machinePoolConfig: + etcd: true + quantity: 3 + - machinePoolConfig: + controlplane: true + quantity: 2 + - machinePoolConfig: + worker: true + quantity: 3 + ``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +### RKE1 +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1NodeReplacingTestSuite/TestReplacingRKE1Nodes"` + +### RKE2 | K3S +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestNodeReplacingTestSuite/TestReplacingNodes"` + +## Scaling Existing Node Pools +Similar to the `provisioning` tests, the node scaling tests have static test cases as well as dynamicInput tests you can specify. In order to run the dynamicInput tests, you will need to define the `scalingInput` block in your config file. This block defines the quantity you would like the pool to be scaled up/down to. See an example below that accounts for node drivers, custom clusters and hosted clusters: +```yaml +scalingInput: + nodeProvider: "ec2" + nodePools: + nodeRoles: + worker: true + quantity: 2 + machinePools: + nodeRoles: + etcd: true + quantity: 1 + aksNodePool: + nodeCount: 3 + eksNodePool: + desiredSize: 6 + gkeNodePool: + initialNodeCount: 3 +``` +NOTE: When scaling AKS and EKS, you will need to make sure that the `maxCount` and `maxSize` parameter is greater than the desired scale amount, respectively. For example, if you wish to have 6 total EKS nodes, then the `maxSize` parameter needs to be at least 7. This is not a limitation of the automation, but rather how EKS specifically handles nodegroups. + +Additionally, for AKS, you must have `enableAutoScaling` set to true if you specify `maxCount` and `minCount`. + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +### RKE1 +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1NodeScalingTestSuite/TestScalingRKE1NodePools"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1NodeScalingTestSuite/TestScalingRKE1NodePoolsDynamicInput"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1CustomClusterNodeScalingTestSuite/TestScalingRKE1CustomClusterNodes"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1CustomClusterNodeScalingTestSuite/TestScalingRKE1CustomClusterNodesDynamicInput"` + +### RKE2 | K3S +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestNodeScalingTestSuite/TestScalingNodePools"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestNodeScalingTestSuite/TestScalingNodePoolsDynamicInput"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterNodeScalingTestSuite/TestScalingCustomClusterNodes"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterNodeScalingTestSuite/TestScalingCustomClusterNodesDynamicInput"` + +### AKS +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestAKSNodeScalingTestSuite/TestScalingAKSNodePools"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestAKSNodeScalingTestSuite/TestScalingAKSNodePoolsDynamicInput"` + +### EKS +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestEKSNodeScalingTestSuite/TestScalingEKSNodePools"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestEKSNodeScalingTestSuite/TestScalingEKSNodePoolsDynamicInput"` + +### GKE +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestGKENodeScalingTestSuite/TestScalingGKENodePools"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestGKENodeScalingTestSuite/TestScalingGKENodePoolsDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + + +## Auto Replacing Nodes +If UnhealthyNodeTimeout is set on your machinepools, auto_replace_test.go will replace a single node with the given role. There are static tests for Etcd, ControlPlane and Worker roles. + +If UnhealthyNodeTimeout is not set, the test(s) in this suite will wait for the cluster upgrade default timeout to be reached (30 mins), expecting an error on the node to remain as a negative test. + +Each test requires 2 or more nodes in the specified role's pool. i.e. if you're running the entire suite, you would need 3etcd, 2controlplane, 2worker, minimum. + +### RKE2 | K3S +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/nodescaling --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestEtcdAutoReplaceRKE2K3S/TestEtcdAutoReplaceRKE2K3S"` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/auto_replace_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/auto_replace_test.go new file mode 100644 index 0000000..31c2ace --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/auto_replace_test.go @@ -0,0 +1,61 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/rancherversion" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + fleetNamespace = "fleet-default" + deletingState = "deleting" + machineNameAnnotation = "cluster.x-k8s.io/machine" +) + +type AutoReplaceSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + rancherConfig *rancherversion.Config +} + +func (s *AutoReplaceSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *AutoReplaceSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + rancherConfig := new(rancherversion.Config) + config.LoadConfig(rancherversion.ConfigurationFileKey, rancherConfig) + s.rancherConfig = rancherConfig + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *AutoReplaceSuite) TestEtcdAutoReplaceRKE2K3S() { + AutoReplaceFirstNodeWithRole(s.T(), s.client, s.client.RancherConfig.ClusterName, "etcd") +} + +func (s *AutoReplaceSuite) TestControlPlaneAutoReplaceRKE2K3S() { + AutoReplaceFirstNodeWithRole(s.T(), s.client, s.client.RancherConfig.ClusterName, "control-plane") +} + +func (s *AutoReplaceSuite) TestWorkerAutoReplaceRKE2K3S() { + AutoReplaceFirstNodeWithRole(s.T(), s.client, s.client.RancherConfig.ClusterName, "worker") +} + +func TestAutoReplaceSuite(t *testing.T) { + suite.Run(t, new(AutoReplaceSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/replace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/replace.go new file mode 100644 index 0000000..7b84b18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/replace.go @@ -0,0 +1,214 @@ +package nodescaling + +import ( + "errors" + "net/url" + "strings" + "testing" + "time" + + "github.com/rancher/norman/types" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/nodes" + nodestat "github.com/rancher/shepherd/extensions/nodes" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/sshkeys" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/crypto/ssh" +) + +const ( + shutdownCommand = "sudo shutdown -h now" + controlPlane = "control-plane" + etcd = "etcd" + worker = "worker" + + unreachableCondition = "NodeStatusUnknown" + namespace = "fleet-default" + ProvisioningSteveResouceType = "provisioning.cattle.io.cluster" + machineSteveResourceType = "cluster.x-k8s.io.machine" + machineSteveAnnotation = "cluster.x-k8s.io/machine" + etcdLabel = "node-role.kubernetes.io/etcd" + clusterLabel = "cluster.x-k8s.io/cluster-name" +) + +func MatchNodeToRole(t *testing.T, client *rancher.Client, clusterID string, isEtcd bool, isControlPlane bool, isWorker bool) (int, []management.Node) { + machines, err := client.Management.Node.List(&types.ListOpts{Filters: map[string]interface{}{ + "clusterId": clusterID, + }}) + require.NoError(t, err) + + numOfNodes := 0 + matchingNodes := []management.Node{} + + for _, machine := range machines.Data { + if machine.Etcd == isEtcd && machine.ControlPlane == isControlPlane && machine.Worker == isWorker { + matchingNodes = append(matchingNodes, machine) + numOfNodes++ + } + } + require.NotEmpty(t, matchingNodes, "matching node name is empty") + + return numOfNodes, matchingNodes +} + +// ReplaceNodes replaces the last node with the specified role(s) in a k3s/rke2 cluster +func ReplaceNodes(t *testing.T, client *rancher.Client, clusterName string, isEtcd bool, isControlPlane bool, isWorker bool) { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + _, nodesToDelete := MatchNodeToRole(t, client, clusterID, isEtcd, isControlPlane, isWorker) + + for i := range nodesToDelete { + machineToDelete, err := client.Steve.SteveType(machineSteveResourceType).ByID("fleet-default/" + nodesToDelete[i].Annotations[machineSteveAnnotation]) + require.NoError(t, err) + + logrus.Infof("Deleting node: " + nodesToDelete[i].NodeName) + err = client.Steve.SteveType(machineSteveResourceType).Delete(machineToDelete) + require.NoError(t, err) + + err = nodestat.IsNodeDeleted(client, nodesToDelete[i].NodeName, clusterID) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, clusterID) + require.NoError(t, err) + + err = nodestat.AllMachineReady(client, clusterID, defaults.ThirtyMinuteTimeout) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + } +} + +// ReplaceRKE1Nodes replaces the last node with the specified role(s) in a rke1 cluster +func ReplaceRKE1Nodes(t *testing.T, client *rancher.Client, clusterName string, isEtcd bool, isControlPlane bool, isWorker bool) { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + _, nodesToDelete := MatchNodeToRole(t, client, clusterID, isEtcd, isControlPlane, isWorker) + + for i := range nodesToDelete { + logrus.Info("Deleting node: " + nodesToDelete[i].NodeName) + err = client.Management.Node.Delete(&nodesToDelete[i]) + require.NoError(t, err) + + err = nodestat.IsNodeDeleted(client, nodesToDelete[i].NodeName, clusterID) + require.NoError(t, err) + + err = nodestat.AllManagementNodeReady(client, clusterID, defaults.ThirtyMinuteTimeout) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + } +} + +// shutdownFirstNodeWithRole uses ssh to shutdown the first node matching the specified role in a given cluster. +func shutdownFirstNodeWithRole(client *rancher.Client, stevecluster *steveV1.SteveAPIObject, clusterID, nodeRole string) (*steveV1.SteveAPIObject, error) { + steveclient, err := client.Steve.ProxyDownstream(clusterID) + if err != nil { + return nil, err + } + + query, err := url.ParseQuery("labelSelector=node-role.kubernetes.io/" + nodeRole + "=true") + if err != nil { + return nil, err + } + + nodeList, err := steveclient.SteveType("node").List(query) + if err != nil { + return nil, err + } + + firstMachine := nodeList.Data[0] + + sshUser, err := sshkeys.GetSSHUser(client, stevecluster) + if err != nil { + return nil, err + } + + if sshUser == "" { + return nil, errors.New("sshUser does not exist") + } + + sshNode, err := sshkeys.GetSSHNodeFromMachine(client, sshUser, &firstMachine) + if err != nil { + return nil, err + } + + logrus.Infof("Running node auto-replace on node %s", firstMachine.Name) + + // Shutdown node using ssh outside of Rancher to simulate unhealthy node + _, err = sshNode.ExecuteCommand(shutdownCommand) + if err != nil && !errors.Is(err, &ssh.ExitMissingError{}) { + return nil, err + } + + return &firstMachine, nil +} + +// matchNodeToMachinePool takes a given node name and returns the cluster's first matching machinePool from its RKEConfig, if any. +func matchNodeToMachinePool(client *rancher.Client, clusterObject *steveV1.SteveAPIObject, nodeName string) (*provv1.RKEMachinePool, error) { + clusterSpec := &provv1.ClusterSpec{} + err := steveV1.ConvertToK8sType(clusterObject.Spec, clusterSpec) + if err != nil { + return nil, err + } + + for _, pool := range clusterSpec.RKEConfig.MachinePools { + if strings.Contains(nodeName, "-"+pool.Name+"-") { + + return &pool, nil + } + } + + return nil, errors.New("could not find matching machine pool for this node") +} + +// AutoReplaceFirstNodeWithRole ssh into the first node with the specified role and shuts it down. If the node is replacable, +// wait for the cluster to return to a healthy state. Otherwise, we expect the cluster to never return to active, as the node will remain unreachable. +func AutoReplaceFirstNodeWithRole(t *testing.T, client *rancher.Client, clusterName, nodeRole string) { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + + _, stevecluster, err := clusters.GetProvisioningClusterByName(client, clusterName, provisioninginput.Namespace) + require.NoError(t, err) + + machine, err := shutdownFirstNodeWithRole(client, stevecluster, clusterID, nodeRole) + require.NoError(t, err) + + machinePool, err := matchNodeToMachinePool(client, stevecluster, machine.Name) + require.NoError(t, err) + + if nodeRole == controlPlane || nodeRole == etcd { + err = clusters.WaitClusterToBeUpgraded(client, clusterID) + if machinePool.UnhealthyNodeTimeout.String() == "0s" { + require.Error(t, err, "UnhealthyNodeTimeout set to 0s, but node was replaced!") + return + } + require.NoError(t, err) + } + + err = nodes.Isv1NodeConditionMet(client, machine.ID, clusterID, unreachableCondition) + if machinePool.UnhealthyNodeTimeout.String() == "0s" { + require.Error(t, err, "UnhealthyNodeTimeout set to 0s, but node was replaced!") + return + } + require.NoError(t, err) + + err = nodestat.IsNodeDeleted(client, machine.Name, clusterID) + require.NoError(t, err) + + err = nodes.AllMachineReady(client, clusterID, machinePool.UnhealthyNodeTimeout.Duration+time.Duration(1800)) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, clusterID) + require.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_rke1_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_rke1_test.go new file mode 100644 index 0000000..96bbde0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_rke1_test.go @@ -0,0 +1,82 @@ +//go:build (validation || infra.rke1 || cluster.nodedriver || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/provisioninginput" + nodepools "github.com/rancher/shepherd/extensions/rke1/nodepools" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1NodeReplacingTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + ns string + clustersConfig *provisioninginput.Config +} + +func (s *RKE1NodeReplacingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *RKE1NodeReplacingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.ns = provisioninginput.Namespace + + s.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *RKE1NodeReplacingTestSuite) TestReplacingRKE1Nodes() { + nodeRolesEtcd := nodepools.NodeRoles{ + Etcd: true, + ControlPlane: false, + Worker: false, + } + + nodeRolesControlPlane := nodepools.NodeRoles{ + Etcd: false, + ControlPlane: true, + Worker: false, + } + + nodeRolesWorker := nodepools.NodeRoles{ + Etcd: false, + ControlPlane: false, + Worker: true, + } + + tests := []struct { + name string + nodeRoles nodepools.NodeRoles + client *rancher.Client + }{ + {"Replacing control plane nodes", nodeRolesControlPlane, s.client}, + {"Replacing etcd nodes", nodeRolesEtcd, s.client}, + {"Replacing worker nodes", nodeRolesWorker, s.client}, + } + + for _, tt := range tests { + s.Run(tt.name, func() { + ReplaceRKE1Nodes(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.nodeRoles.Etcd, tt.nodeRoles.ControlPlane, tt.nodeRoles.Worker) + }) + } +} + +func TestRKE1NodeReplacingTestSuite(t *testing.T) { + suite.Run(t, new(RKE1NodeReplacingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_test.go new file mode 100644 index 0000000..89d8864 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scale_replace_test.go @@ -0,0 +1,102 @@ +//go:build (validation || infra.rke2k3s || cluster.nodedriver || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !sanity && !stress + +package nodescaling + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type NodeReplacingTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + ns string + clustersConfig *provisioninginput.Config +} + +func (s *NodeReplacingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *NodeReplacingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.ns = provisioninginput.Namespace + + s.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *NodeReplacingTestSuite) TestReplacingNodes() { + nodeRolesEtcd := machinepools.NodeRoles{ + Etcd: true, + ControlPlane: false, + Worker: false, + } + + nodeRolesControlPlane := machinepools.NodeRoles{ + Etcd: false, + ControlPlane: true, + Worker: false, + } + + nodeRolesWorker := machinepools.NodeRoles{ + Etcd: false, + ControlPlane: false, + Worker: true, + } + + tests := []struct { + name string + nodeRoles machinepools.NodeRoles + client *rancher.Client + }{ + {"control plane nodes", nodeRolesControlPlane, s.client}, + {"etcd nodes", nodeRolesEtcd, s.client}, + {"worker nodes", nodeRolesWorker, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "Replacing RKE2 " + tt.name + } else { + tt.name = "Replacing K3S " + tt.name + } + + s.Run(tt.name, func() { + ReplaceNodes(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.nodeRoles.Etcd, tt.nodeRoles.ControlPlane, tt.nodeRoles.Worker) + }) + } +} + +func TestNodeReplacingTestSuite(t *testing.T) { + suite.Run(t, new(NodeReplacingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_rke1_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_rke1_test.go new file mode 100644 index 0000000..38ca070 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_rke1_test.go @@ -0,0 +1,106 @@ +//go:build (validation || infra.rke1 || cluster.custom || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.nodedriver && !sanity && !extended + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + nodepools "github.com/rancher/shepherd/extensions/rke1/nodepools" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1CustomClusterNodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *RKE1CustomClusterNodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *RKE1CustomClusterNodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *RKE1CustomClusterNodeScalingTestSuite) TestScalingRKE1CustomClusterNodes() { + nodeRolesEtcd := nodepools.NodeRoles{ + Etcd: true, + Quantity: 1, + } + + nodeRolesControlPlane := nodepools.NodeRoles{ + ControlPlane: true, + Quantity: 1, + } + + nodeRolesEtcdControlPlane := nodepools.NodeRoles{ + Etcd: true, + ControlPlane: true, + Quantity: 1, + } + + nodeRolesWorker := nodepools.NodeRoles{ + Worker: true, + Quantity: 1, + } + + nodeRolesTwoWorkers := nodepools.NodeRoles{ + Worker: true, + Quantity: 2, + } + + tests := []struct { + name string + nodeRoles nodepools.NodeRoles + client *rancher.Client + }{ + {"Scaling custom control plane by 1", nodeRolesControlPlane, s.client}, + {"Scaling custom etcd by 1", nodeRolesEtcd, s.client}, + {"Scaling custom etcd and control plane by 1", nodeRolesEtcdControlPlane, s.client}, + {"Scaling custom worker by 1", nodeRolesWorker, s.client}, + {"Scaling custom worker by 2", nodeRolesTwoWorkers, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + s.Run(tt.name, func() { + scalingRKE1CustomClusterPools(s.T(), s.client, clusterID, s.scalingConfig.NodeProvider, tt.nodeRoles) + }) + } +} + +func (s *RKE1CustomClusterNodeScalingTestSuite) TestScalingRKE1CustomClusterNodesDynamicInput() { + if s.scalingConfig.MachinePools.NodeRoles == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingRKE1CustomClusterPools(s.T(), s.client, clusterID, s.scalingConfig.NodeProvider, *s.scalingConfig.NodePools.NodeRoles) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1CustomClusterNodeScalingTestSuite(t *testing.T) { + suite.Run(t, new(RKE1CustomClusterNodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_test.go new file mode 100644 index 0000000..837c0a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_custom_cluster_test.go @@ -0,0 +1,122 @@ +//go:build (validation || infra.rke2k3s || cluster.custom || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !cluster.any && !cluster.nodedriver && !sanity && !extended + +package nodescaling + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CustomClusterNodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *CustomClusterNodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *CustomClusterNodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *CustomClusterNodeScalingTestSuite) TestScalingCustomClusterNodes() { + nodeRolesEtcd := machinepools.NodeRoles{ + Etcd: true, + Quantity: 1, + } + + nodeRolesControlPlane := machinepools.NodeRoles{ + ControlPlane: true, + Quantity: 1, + } + + nodeRolesEtcdControlPlane := machinepools.NodeRoles{ + Etcd: true, + ControlPlane: true, + Quantity: 1, + } + + nodeRolesWorker := machinepools.NodeRoles{ + Worker: true, + Quantity: 1, + } + + nodeRolesTwoWorkers := machinepools.NodeRoles{ + Worker: true, + Quantity: 2, + } + + tests := []struct { + name string + nodeRoles machinepools.NodeRoles + client *rancher.Client + }{ + {"control plane by 1", nodeRolesControlPlane, s.client}, + {"etcd by 1", nodeRolesEtcd, s.client}, + {"etcd and control plane by 1", nodeRolesEtcdControlPlane, s.client}, + {"worker by 1", nodeRolesWorker, s.client}, + {"worker by 2", nodeRolesTwoWorkers, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "Scaling custom RKE2 " + tt.name + } else { + tt.name = "Scaling custom K3S " + tt.name + } + + s.Run(tt.name, func() { + scalingRKE2K3SCustomClusterPools(s.T(), s.client, clusterID, s.scalingConfig.NodeProvider, tt.nodeRoles) + }) + } +} + +func (s *CustomClusterNodeScalingTestSuite) TestScalingCustomClusterNodesDynamicInput() { + if s.scalingConfig.MachinePools.NodeRoles == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingRKE2K3SCustomClusterPools(s.T(), s.client, clusterID, s.scalingConfig.NodeProvider, *s.scalingConfig.MachinePools.NodeRoles) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestCustomClusterNodeScalingTestSuite(t *testing.T) { + suite.Run(t, new(CustomClusterNodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_aks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_aks_test.go new file mode 100644 index 0000000..7cd67a4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_aks_test.go @@ -0,0 +1,86 @@ +//go:build (validation || infra.aks || extended) && !infra.any && !infra.eks && !infra.gke && !infra.rke2k3s && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/aks" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type AKSNodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *AKSNodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *AKSNodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *AKSNodeScalingTestSuite) TestScalingAKSNodePools() { + scaleOneNode := aks.NodePool{ + NodeCount: &oneNode, + } + + scaleTwoNodes := aks.NodePool{ + NodeCount: &twoNodes, + } + + tests := []struct { + name string + aksNodes aks.NodePool + client *rancher.Client + }{ + {"Scaling AKS agentpool by 1", scaleOneNode, s.client}, + {"Scaling AKS agentpool by 2", scaleTwoNodes, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + s.Run(tt.name, func() { + scalingAKSNodePools(s.T(), s.client, clusterID, &tt.aksNodes) + }) + } +} + +func (s *AKSNodeScalingTestSuite) TestScalingAKSNodePoolsDynamicInput() { + if s.scalingConfig.AKSNodePool == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingAKSNodePools(s.T(), s.client, clusterID, s.scalingConfig.AKSNodePool) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestAKSNodeScalingTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(AKSNodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_eks_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_eks_test.go new file mode 100644 index 0000000..b3f281b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_eks_test.go @@ -0,0 +1,86 @@ +//go:build (validation || infra.eks || extended) && !infra.any && !infra.aks && !infra.gke && !infra.rke2k3s && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/eks" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type EKSNodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *EKSNodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *EKSNodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *EKSNodeScalingTestSuite) TestScalingEKSNodePools() { + scaleOneNode := eks.NodeGroupConfig{ + DesiredSize: &oneNode, + } + + scaleTwoNodes := eks.NodeGroupConfig{ + DesiredSize: &twoNodes, + } + + tests := []struct { + name string + eksNodes eks.NodeGroupConfig + client *rancher.Client + }{ + {"Scaling EKS node group by 1", scaleOneNode, s.client}, + {"Scaling EKS node group by 2", scaleTwoNodes, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + s.Run(tt.name, func() { + scalingEKSNodePools(s.T(), s.client, clusterID, &tt.eksNodes) + }) + } +} + +func (s *EKSNodeScalingTestSuite) TestScalingEKSNodePoolsDynamicInput() { + if s.scalingConfig.EKSNodePool == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingEKSNodePools(s.T(), s.client, clusterID, s.scalingConfig.EKSNodePool) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestEKSNodeScalingTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(EKSNodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_gke_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_gke_test.go new file mode 100644 index 0000000..106f944 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_gke_test.go @@ -0,0 +1,86 @@ +//go:build (validation || infra.gke || extended) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/gke" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type GKENodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *GKENodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *GKENodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *GKENodeScalingTestSuite) TestScalingGKENodePools() { + scaleOneNode := gke.NodePool{ + InitialNodeCount: &oneNode, + } + + scaleTwoNodes := gke.NodePool{ + InitialNodeCount: &twoNodes, + } + + tests := []struct { + name string + gkeNodes gke.NodePool + client *rancher.Client + }{ + {"Scaling GKE node group by 1", scaleOneNode, s.client}, + {"Scaling GKE node group by 2", scaleTwoNodes, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + s.Run(tt.name, func() { + scalingGKENodePools(s.T(), s.client, clusterID, &tt.gkeNodes) + }) + } +} + +func (s *GKENodeScalingTestSuite) TestScalingGKENodePoolsDynamicInput() { + if s.scalingConfig.GKENodePool == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingGKENodePools(s.T(), s.client, clusterID, s.scalingConfig.GKENodePool) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestGKENodeScalingTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(GKENodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_rke1_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_rke1_test.go new file mode 100644 index 0000000..1ebfe67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_rke1_test.go @@ -0,0 +1,99 @@ +//go:build (validation || infra.rke1 || cluster.nodedriver || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !sanity && !stress + +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + nodepools "github.com/rancher/shepherd/extensions/rke1/nodepools" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1NodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *RKE1NodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *RKE1NodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *RKE1NodeScalingTestSuite) TestScalingRKE1NodePools() { + nodeRolesEtcd := nodepools.NodeRoles{ + Etcd: true, + Quantity: 1, + } + + nodeRolesControlPlane := nodepools.NodeRoles{ + ControlPlane: true, + Quantity: 1, + } + + nodeRolesWorker := nodepools.NodeRoles{ + Worker: true, + Quantity: 1, + } + + nodeRolesTwoWorkers := nodepools.NodeRoles{ + Worker: true, + Quantity: 2, + } + + tests := []struct { + name string + nodeRoles nodepools.NodeRoles + client *rancher.Client + }{ + {"Scaling control plane by 1", nodeRolesControlPlane, s.client}, + {"Scaling etcd node by 1", nodeRolesEtcd, s.client}, + {"Scaling worker by 1", nodeRolesWorker, s.client}, + {"Scaling worker node machine by 2", nodeRolesTwoWorkers, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + s.Run(tt.name, func() { + scalingRKE1NodePools(s.T(), s.client, clusterID, tt.nodeRoles) + }) + } +} + +func (s *RKE1NodeScalingTestSuite) TestScalingRKE1NodePoolsDynamicInput() { + if s.scalingConfig.NodePools.NodeRoles == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingRKE1NodePools(s.T(), s.client, clusterID, *s.scalingConfig.NodePools.NodeRoles) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1NodeScalingTestSuite(t *testing.T) { + suite.Run(t, new(RKE1NodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_test.go new file mode 100644 index 0000000..b2141b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_node_driver_test.go @@ -0,0 +1,115 @@ +//go:build (validation || infra.rke2k3s || cluster.nodedriver || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !sanity && !stress + +package nodescaling + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/scalinginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type NodeScalingTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + scalingConfig *scalinginput.Config +} + +func (s *NodeScalingTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *NodeScalingTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.scalingConfig = new(scalinginput.Config) + config.LoadConfig(scalinginput.ConfigurationFileKey, s.scalingConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *NodeScalingTestSuite) TestScalingNodePools() { + nodeRolesEtcd := machinepools.NodeRoles{ + Etcd: true, + Quantity: 1, + } + + nodeRolesControlPlane := machinepools.NodeRoles{ + ControlPlane: true, + Quantity: 1, + } + + nodeRolesWorker := machinepools.NodeRoles{ + Worker: true, + Quantity: 1, + } + + nodeRolesTwoWorkers := machinepools.NodeRoles{ + Worker: true, + Quantity: 2, + } + + tests := []struct { + name string + nodeRoles machinepools.NodeRoles + client *rancher.Client + }{ + {"control plane by 1", nodeRolesControlPlane, s.client}, + {"etcd by 1", nodeRolesEtcd, s.client}, + {"worker by 1", nodeRolesWorker, s.client}, + {"worker by 2", nodeRolesTwoWorkers, s.client}, + } + + for _, tt := range tests { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "Scaling RKE2 " + tt.name + } else { + tt.name = "Scaling K3S " + tt.name + } + + s.Run(tt.name, func() { + scalingRKE2K3SNodePools(s.T(), s.client, clusterID, tt.nodeRoles) + }) + } +} + +func (s *NodeScalingTestSuite) TestScalingNodePoolsDynamicInput() { + if s.scalingConfig.MachinePools == nil { + s.T().Skip() + } + + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + scalingRKE2K3SNodePools(s.T(), s.client, clusterID, *s.scalingConfig.MachinePools.NodeRoles) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestNodeScalingTestSuite(t *testing.T) { + suite.Run(t, new(NodeScalingTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_nodepools.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_nodepools.go new file mode 100644 index 0000000..8c3a67d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/nodescaling/scaling_nodepools.go @@ -0,0 +1,186 @@ +package nodescaling + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/aks" + "github.com/rancher/shepherd/extensions/clusters/eks" + "github.com/rancher/shepherd/extensions/clusters/gke" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/provisioning" + rke1 "github.com/rancher/shepherd/extensions/rke1/nodepools" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/stretchr/testify/require" +) + +const ( + ProvisioningSteveResourceType = "provisioning.cattle.io.cluster" + defaultNamespace = "fleet-default" +) + +var oneNode int64 = 1 +var twoNodes int64 = 2 + +func scalingRKE2K3SNodePools(t *testing.T, client *rancher.Client, clusterID string, nodeRoles machinepools.NodeRoles) { + cluster, err := client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(t, err) + + clusterResp, err := machinepools.ScaleMachinePoolNodes(client, cluster, nodeRoles) + require.NoError(t, err) + + pods.VerifyReadyDaemonsetPods(t, client, clusterResp) + + updatedCluster, err := client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(t, err) + + nodeRoles.Quantity = -nodeRoles.Quantity + scaledClusterResp, err := machinepools.ScaleMachinePoolNodes(client, updatedCluster, nodeRoles) + require.NoError(t, err) + + pods.VerifyReadyDaemonsetPods(t, client, scaledClusterResp) +} + +func scalingRKE2K3SCustomClusterPools(t *testing.T, client *rancher.Client, clusterID string, nodeProvider string, nodeRoles machinepools.NodeRoles) { + rolesPerNode := []string{} + quantityPerPool := []int32{} + rolesPerPool := []string{} + for _, nodeRoles := range []machinepools.NodeRoles{nodeRoles} { + var finalRoleCommand string + if nodeRoles.ControlPlane { + finalRoleCommand += " --controlplane" + } + if nodeRoles.Etcd { + finalRoleCommand += " --etcd" + } + if nodeRoles.Worker { + finalRoleCommand += " --worker" + } + if nodeRoles.Windows { + finalRoleCommand += " --windows" + } + quantityPerPool = append(quantityPerPool, nodeRoles.Quantity) + rolesPerPool = append(rolesPerPool, finalRoleCommand) + for i := int32(0); i < nodeRoles.Quantity; i++ { + rolesPerNode = append(rolesPerNode, finalRoleCommand) + } + } + + var externalNodeProvider provisioning.ExternalNodeProvider + externalNodeProvider = provisioning.ExternalNodeProviderSetup(nodeProvider) + + nodes, err := externalNodeProvider.NodeCreationFunc(client, rolesPerPool, quantityPerPool) + require.NoError(t, err) + + cluster, err := client.Steve.SteveType(ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(t, err) + + err = provisioning.AddRKE2K3SCustomClusterNodes(client, cluster, nodes, rolesPerNode) + require.NoError(t, err) + + pods.VerifyReadyDaemonsetPods(t, client, cluster) + require.NoError(t, err) + + clusterID, err = clusters.GetClusterIDByName(client, cluster.Name) + require.NoError(t, err) + + err = provisioning.DeleteRKE2K3SCustomClusterNodes(client, clusterID, cluster, nodes) + require.NoError(t, err) + + err = externalNodeProvider.NodeDeletionFunc(client, nodes) + require.NoError(t, err) +} + +func scalingRKE1NodePools(t *testing.T, client *rancher.Client, clusterID string, nodeRoles rke1.NodeRoles) { + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + node, err := rke1.MatchRKE1NodeRoles(client, cluster, nodeRoles) + require.NoError(t, err) + + _, err = rke1.ScaleNodePoolNodes(client, cluster, node, nodeRoles) + require.NoError(t, err) + + nodeRoles.Quantity = -nodeRoles.Quantity + _, err = rke1.ScaleNodePoolNodes(client, cluster, node, nodeRoles) + require.NoError(t, err) +} + +func scalingRKE1CustomClusterPools(t *testing.T, client *rancher.Client, clusterID string, nodeProvider string, nodeRoles rke1.NodeRoles) { + rolesPerNode := []string{} + quantityPerPool := []int32{} + rolesPerPool := []string{} + for _, pool := range []rke1.NodeRoles{nodeRoles} { + var finalRoleCommand string + if pool.ControlPlane { + finalRoleCommand += " --controlplane" + } + if pool.Etcd { + finalRoleCommand += " --etcd" + } + if pool.Worker { + finalRoleCommand += " --worker" + } + + quantityPerPool = append(quantityPerPool, int32(pool.Quantity)) + rolesPerPool = append(rolesPerPool, finalRoleCommand) + for i := int64(0); i < pool.Quantity; i++ { + rolesPerNode = append(rolesPerNode, finalRoleCommand) + } + } + + var externalNodeProvider provisioning.ExternalNodeProvider + externalNodeProvider = provisioning.ExternalNodeProviderSetup(nodeProvider) + + nodes, err := externalNodeProvider.NodeCreationFunc(client, rolesPerPool, quantityPerPool) + require.NoError(t, err) + + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + err = provisioning.AddRKE1CustomClusterNodes(client, cluster, nodes, rolesPerNode) + require.NoError(t, err) + + err = provisioning.DeleteRKE1CustomClusterNodes(client, cluster, nodes) + require.NoError(t, err) + + err = externalNodeProvider.NodeDeletionFunc(client, nodes) + require.NoError(t, err) +} + +func scalingAKSNodePools(t *testing.T, client *rancher.Client, clusterID string, nodePool *aks.NodePool) { + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + clusterResp, err := aks.ScalingAKSNodePoolsNodes(client, cluster, nodePool) + require.NoError(t, err) + + *nodePool.NodeCount = -*nodePool.NodeCount + _, err = aks.ScalingAKSNodePoolsNodes(client, clusterResp, nodePool) + require.NoError(t, err) +} + +func scalingEKSNodePools(t *testing.T, client *rancher.Client, clusterID string, nodePool *eks.NodeGroupConfig) { + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + clusterResp, err := eks.ScalingEKSNodePoolsNodes(client, cluster, nodePool) + require.NoError(t, err) + + *nodePool.DesiredSize = -*nodePool.DesiredSize + _, err = eks.ScalingEKSNodePoolsNodes(client, clusterResp, nodePool) + require.NoError(t, err) +} + +func scalingGKENodePools(t *testing.T, client *rancher.Client, clusterID string, nodePool *gke.NodePool) { + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + clusterResp, err := gke.ScalingGKENodePoolsNodes(client, cluster, nodePool) + require.NoError(t, err) + + *nodePool.InitialNodeCount = -*nodePool.InitialNodeCount + _, err = gke.ScalingGKENodePoolsNodes(client, clusterResp, nodePool) + require.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.multibranch.recurring b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.multibranch.recurring new file mode 100644 index 0000000..9a43ddc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.multibranch.recurring @@ -0,0 +1,134 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def rancherImageTags = "${env.RANCHER_IMAGE_TAGS}".split(',') + def jobName = "${JOB_NAME}" + def config = env.CONFIG + def filename = "config.yaml" + def hostnameSuffix = ["v2.7-head":"v27", "v2.8-head":"v28", "v2.9-head":"v29"] + def releaseBranchTagMap = ["v2.7-head":"release/v2.7", "v2.8-head":"release/v2.8", "v2.9-head":"release/v2.9"] + def tagChartMap = ["v2.7-head":"2.7.12", "v2.8-head":"2.8.3", "v2.9-head":"2.8.3"] + def rancherChartRepo = "prime" + def configPath = "" + + if (jobName.contains('/')) { + jobNames = jobName.split('/') + jobName = jobNames[jobNames.size() - 1] + } + + def branch = "release/v2.9" + def recurringRunJob = (jobName =~ /(go-recurring-[a-z]+)/)[0][1] + recurringRunJob = "${recurringRunJob}-job" + + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + + def configFiles = [] + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'PRIME_STAGING_REPO', variable: 'PRIME_STAGING_REPO'), + string(credentialsId: 'PRIME_STAGING_REGISTRY', variable: 'PRIME_STAGING_REGISTRY'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN')]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + } + dir ("./") { + stage('Setup') { + dir("./rancher/tests/v2/validation") { + writeFile file: filename, text: config + env.CATTLE_TEST_CONFIG = "${workPath}${filename}" + configPath = "./rancher/tests/v2/validation/${filename}" + } + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout:true, script: 'chmod a+x ./yq' + } + stage('Run Different Release Branches Testing') { + try { + jobs = [:] + def hostnamePrefix = sh ( + script: "./yq '.corralConfigs.corralConfigVars.aws_hostname_prefix ' ${configPath}", + returnStdout: true + ).trim() + for( String testTag : rancherImageTags ) { + dir("./rancher/tests/v2/validation") { + writeFile file: filename, text: config + } + + def hostname = "${hostnamePrefix}${hostnameSuffix[testTag]}" + def rancherHostName = "${hostname}.qa.rancher.space" + + sh "./yq e '.corralConfigs.corralConfigVars.rancher_image_tag = \"${testTag}\"' -i ${configPath}" + sh "./yq e '.corralConfigs.corralConfigVars.rancher_version = \"${tagChartMap[testTag]}\"' -i ${configPath}" + sh "./yq e '.corralConfigs.corralConfigVars.aws_hostname_prefix = \"${hostname}\"' -i ${configPath}" + sh "./yq e '.rancher.host = \"${rancherHostName}\"' -i ${configPath}" + + if (testTag == "v2.7-head") { + def cattleImageEnvVar = '[\\"CATTLE_AGENT_IMAGE|'+"${env.PRIME_STAGING_REGISTRY}"+'/rancher/rancher-agent:v2.7-head\\"]' + def rancherImage = "${env.PRIME_STAGING_REGISTRY}/rancher/rancher" + sh "./yq e '.corralConfigs.corralConfigVars.rancher_chart_url = \"${env.PRIME_STAGING_REPO}\"' -i ${configPath}" + sh "./yq e '.corralConfigs.corralConfigVars.rancher_chart_repo = \"${rancherChartRepo}\"' -i ${configPath}" + sh "./yq e '.corralConfigs.corralConfigVars.rancher_image = \"${rancherImage}\"' -i ${configPath}" + sh "./yq e '.corralConfigs.corralConfigVars.env_var_map = \"${cattleImageEnvVar}\"' -i ${configPath}" + } + def configYaml = readFile(file: "${configPath}") + def goValidationParams = [ + text(name: 'CONFIG', value: configYaml), + string(name: 'BRANCH', value: "${releaseBranchTagMap[testTag]}"), + string(name: 'TEST_RUN_NAME', value: "${testTag}-${env.TEST_RUN_NAME}"), + ] + + jobs["$testTag-test-validation"] = { build job: recurringRunJob, parameters: goValidationParams } + } + parallel jobs + } catch(err){ + echo "Provisioning tests had failures: " + err + } + } //stage + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.recurring b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.recurring new file mode 100644 index 0000000..61dae94 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.recurring @@ -0,0 +1,330 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def jobName = "${JOB_NAME}" + if (jobName.contains('/')) { + jobNames = jobName.split('/') + jobName = jobNames[jobNames.size() - 1] + } + def golangTestContainer = "${jobName}${env.BUILD_NUMBER}-golangtest" + def buildTestContainer = "${jobName}${env.BUILD_NUMBER}-buildtest" + def configGeneratorContainer = "${jobName}${env.BUILD_NUMBER}_generator" + def cleanupTestContainer = "${jobName}${env.BUILD_NUMBER}-cleanuptest" + def imageName = "rancher-recurring-runs-validation-${jobName}${env.BUILD_NUMBER}" + def validationVolume = "RecurringRunsSharedVolume-${jobName}${env.BUILD_NUMBER}" + def testsDir = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def configsDir = "cattle-configs" + def patchedConfigsDir = "patched-cattle-configs" + def testResultsOut = "results.xml" + def qaseRun = "testrun" + def testRunConfig = "testrunconfig.yaml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def corralBranch = "main" + def config = env.CONFIG + def rancherToken = "" + def filename = "config.yaml" + def individualJob = (jobName =~ /(go-recurring-[a-z]+)/)[0][1] + individualJob = "${individualJob}-individual-job" + + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "") { + corralBranch = "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" + } + + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + + def corralRepo = scm.getUserRemoteConfigs()[1].getUrl() + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "") { + corralRepo = "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" + } + + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + + def configFiles = [] + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'SLACK_WEBHOOK', variable: 'SLACK_WEBHOOK'), + string(credentialsId: 'QASE_AUTOMATION_TOKEN', variable: 'QASE_AUTOMATION_TOKEN')]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir('./') { + echo "cloning corral-packages repo" + + dir('./corral-packages') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${corralBranch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: corralRepo]] + ]) + } + } + } + dir ("./") { + stage('Configure and Build') { + config = config.replace('${AWS_SECRET_ACCESS_KEY}', env.AWS_SECRET_ACCESS_KEY) + config = config.replace('${AWS_ACCESS_KEY_ID}', env.AWS_ACCESS_KEY_ID) + config = config.replace('${AWS_IAM_PROFILE}', env.AWS_IAM_PROFILE) + config = config.replace('${AWS_REGION}', env.AWS_REGION) + config = config.replace('${AWS_VPC}', env.AWS_VPC) + config = config.replace('${AWS_SECURITY_GROUPS}', env.AWS_SECURITY_GROUPS) + config = config.replace('${ADMIN_PASSWORD}', env.ADMIN_PASSWORD) + + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./rancher/tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + dir("./rancher/tests/v2/validation") { + writeFile file: filename, text: config + env.CATTLE_TEST_CONFIG = "${workPath}${filename}" + } + dir ("./") { + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e -t ${imageName}" + sh "docker volume create --name ${validationVolume}" + } + } + stage('Setup') { + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout:true, script: 'chmod a+x ./yq' + } + stage("Build Environment") { + try { + sh "docker run -v ${validationVolume}:/root --name ${buildTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"${workPath}pipeline/scripts/setup_environment.sh;${workPath}pipeline/scripts/build_qase_auto_testrun.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker volume rm -f ${validationVolume}" + error "Build Environment had failures." + } + } + try { + stage ('Generate configuration files') { + sh "docker run --volumes-from ${buildTestContainer} --name ${configGeneratorContainer} -t -e CATTLE_TEST_CONFIG=\$CATTLE_TEST_CONFIG " + + "${imageName} sh -c \"${workPath}pipeline/releaseupgrade/releaseupgrade.sh\"" + + sh "docker cp ${configGeneratorContainer}:${rootPath}${configsDir}/ ." + + def configs = sh(script: "ls -1 ./${configsDir}", returnStdout: true).split() + + for (int i = 0; i < configs.size(); i++) { + def configName = configs[i] + echo "pushing ${configName} to the global variable" + configFiles << "${configName}" + } + + println "Building the image again with the config files" + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e -t ${imageName}" + } + stage('Deploys clusters') { + try { + jobs = [:] + + configFiles.each { + def configPath = "./${configsDir}/$it" + def absoluteConfigPath = "${rootPath}${configsDir}/$it" + + def testCase = sh ( + script: "./yq '.testCases.provisioningTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.provisioningTestPackage' ${configPath}", + returnStdout: true + ).trim() + + jobs["$it-provisioning"] = { + stage("Parallel Provisioning: $it"){ + def containerName = "${jobName}${env.BUILD_NUMBER}_$it-provisioning" + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${containerName} -t -e CATTLE_TEST_CONFIG=\"${absoluteConfigPath}\" " + + "${imageName} sh -c \"gotestsum --format standard-verbose --packages=\"${testsDir}${testPackage}\" --junitfile ${testResultsOut} -- -tags=validation ${testCase} -timeout=\"60m\" -v\"" + + dir("./${patchedConfigsDir}") { + sh "docker cp ${containerName}:${rootPath}${configsDir}/$it ." + } + } catch (err){ + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + } + } + parallel jobs + } catch(err){ + echo "Provisioning tests had failures: " + err + } + } + stage('Run Test Validations') { + try { + jobs = [:] + + // copy updated config file from the build test container + sh "docker cp ${buildTestContainer}:${workPath}${filename} ./" + sh "docker cp ${buildTestContainer}:${workPath}${qaseRun} ./" + sh "./${qaseRun} --startRun=true" + + def testRunID = sh ( + script: "./yq '.id' ./${testRunConfig}", + returnStdout: true + ).trim() + + def mainRancherConfigPath = "./${filename}" + + sh "./yq e '.rancher.cleanup = true' -i ${mainRancherConfigPath}" + configFiles.each { + try { + def configPath = "./${patchedConfigsDir}/$it" + + def tags = sh ( + script: "./yq '.testCases.tags' ${configPath}", + returnStdout: true + ).trim() + + def runFlag = sh ( + script: "./yq '.testCases.runFlag' ${configPath}", + returnStdout: true + ).trim() + + def clusterName = sh ( + script: "./yq '.rancher.clusterName' ${configPath}", + returnStdout: true + ).trim() + + sh "./yq e '.rancher.clusterName = \"${clusterName}\"' -i ${mainRancherConfigPath}" + + def configYaml = readFile(file: "${mainRancherConfigPath}") + + def goValidationParams = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'QASE_TEST_RUN_ID', value: "${testRunID}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'GOTEST_TESTCASE', value: "${runFlag} -p 1"), + string(name: 'TAGS', value: tags), + ] + + jobs["$it-test-validation"] = { build job: individualJob, parameters: goValidationParams } + } catch(err) { + echo "Test Validation $it had failures: " + err + } + } + + if ("${env.TAGS}" != "") { + sh "./yq e 'del(.provisioningInput.machinePools)' -i ${mainRancherConfigPath}" + sh "./yq e 'del(.provisioningInput.nodePools)' -i ${mainRancherConfigPath}" + def configYaml = readFile(file: "${mainRancherConfigPath}") + + def goValidationParams = [ + string(name: 'TIMEOUT', value: timeout), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'QASE_TEST_RUN_ID', value: "${testRunID}"), + string(name: 'TEST_PACKAGE', value: "${env.TEST_PACKAGE}"), + string(name: 'TAGS', value: "${env.TAGS}"), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_TESTCASE} -p 1"), + ] + + jobs["provisioning-test-validation"] = { build job: individualJob, parameters: goValidationParams } + + } + parallel jobs + } catch(err) { + echo "Test validations had failures: " + err + } + sh "./${qaseRun} --startRun=false" + } + } catch(err) { + echo "Failures " + err + } + + stage('Cleanup Rancher Environment') { + if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") { + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + sh "docker rmi -f ${imageName}" + sh "docker volume rm -f ${validationVolume}" + error "Cleanup had failures." + } + } + } + stage('Clean Up Images and Volume') { + echo 'Cleaning test images and volume.' + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + if ("${env.CLEANUP_RANCHER}" == "True" || "${env.CLEANUP_RANCHER}" == "true") { + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + } + sh "docker rmi -f ${imageName}" + sh "docker volume rm -f ${validationVolume}" + } + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.ha b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.ha new file mode 100644 index 0000000..2e32f6a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.ha @@ -0,0 +1,626 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def configGeneratorContainer = "${job_name}${env.BUILD_NUMBER}_generator" + def cleanupContainer = "${job_name}${env.BUILD_NUMBER}_cleanup" + + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + + def testsDir = "github.com/rancher/rancher/tests/v2/validation/" + def upgradeTestsDir = "${testsDir}upgrade" + def provisioningTestsDir = "${testsDir}provisioning" + + def groovyEnvironments = "environments.groovy" + def configsDir = "cattle-configs" + def patchedConfigsDir = "patched-cattle-configs" + + def testResultsOut = "results.xml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + def branch = "release/v2.8" + def defaultTag = "validation" + + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + + def configFiles = [] + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir ("./") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + dir("./tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = workPath+filename + } + + sh "./tests/v2/validation/configure.sh" + sh "./tests/v2/validation/build.sh" + } + stage('Setup') { + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout:true, script: 'chmod a+x ./yq' + + def initConfigPath = "./tests/v2/validation/config.yaml" + + env.HA_HOST= sh ( + script: "./yq '.ha.host' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA host: ${env.HA_HOST}" + + env.HA_HOST_PREFIX= (env.HA_HOST.substring(0, env.HA_HOST.indexOf('.'))).trim() + println "HA host Prefix: ${env.HA_HOST_PREFIX}" + + env.HA_CHART_VERSION= sh ( + script: "./yq '.ha.chartVersion' ${initConfigPath}", + returnStdout: true + ).trim() + println " HA chart version: ${env.HA_CHART_VERSION}" + + env.HA_CHART_VERSION_TO_UPGRADE= sh ( + script: "./yq '.ha.chartVersionToUpgrade' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA chart version to upgrade: ${env.HA_CHART_VERSION_TO_UPGRADE}" + + env.HA_IMAGE_TAG= sh ( + script: "./yq '.ha.imageTag' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA image tag: ${env.HA_IMAGE_TAG}" + + env.HA_IMAGE_TAG_TO_UPGRADE= sh ( + script: "./yq '.ha.imageTagToUpgrade' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA image tag to upgrade: ${env.HA_IMAGE_TAG_TO_UPGRADE}" + + env.HA_HELM_REPO= sh ( + script: "./yq '.ha.helmRepo' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA helm repo: ${env.HA_HELM_REPO}" + + env.HA_HELM_REPO_TO_UPGRADE= sh ( + script: "./yq '.ha.helmRepoToUpgrade' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA helm repo to upgrade: ${env.HA_HELM_REPO_TO_UPGRADE}" + + env.HA_HELM_URL= sh ( + script: "./yq '.ha.helmURL' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA helm url: ${env.HA_HELM_URL}" + + env.HA_HELM_URL_TO_UPGRADE= sh ( + script: "./yq '.ha.helmURLToUpgrade' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA helm url to upgrade: ${env.HA_HELM_URL_TO_UPGRADE}" + + env.RKE_VERSION= sh ( + script: "./yq '.ha.rkeVersion' ${initConfigPath}", + returnStdout: true + ).trim() + println "RKE version: ${env.RKE_VERSION}" + + env.HA_CERT_OPTION= sh ( + script: "./yq '.ha.certOption' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA cert option: ${env.HA_CERT_OPTION}" + + env.RANCHER_HA_HARDENED= sh ( + script: "./yq '.ha.hardened' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA hardened option: ${env.RANCHER_HA_HARDENED}" + + env.RANCHER_PSP_ENABLED= sh ( + script: "./yq '.ha.pspEnabled' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA PSP enabled option: ${env.RANCHER_PSP_ENABLED}" + + env.RANCHER_HELM_EXTRA_SETTINGS= sh ( + script: "./yq '.ha.helmExtraSettings' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA Helm extra settings option: ${env.RANCHER_HELM_EXTRA_SETTINGS}" + + env.RANCHER_HELM_EXTRA_SETTINGS_TO_UPGRADE= sh ( + script: "./yq '.ha.helmExtraSettingsToUpgrade' ${initConfigPath}", + returnStdout: true + ).trim() + println "HA Helm extra settings option to be used on an upgrade: ${env.RANCHER_HELM_EXTRA_SETTINGS_TO_UPGRADE}" + + env.HA_CLEANUP= sh ( + script: "./yq '.ha.cleanup' ${initConfigPath}", + returnStdout: true + ).trim() + + if ("${env.HA_CLEANUP}" == "" || "${env.HA_CLEANUP}" == "null") { + env.HA_CLEANUP=true + } + println "HA cleanup: ${env.HA_CLEANUP}" + } + stage('Deploys Rancher on a specified version') { + deployParams = [ + string(name: 'RANCHER_HOSTNAME_PREFIX', value: "${env.HA_HOST_PREFIX}"), + string(name: 'RANCHER_CHART_VERSION', value: "${env.HA_CHART_VERSION}"), + string(name: 'RANCHER_IMAGE_TAG', value: "${env.HA_IMAGE_TAG}"), + string(name: 'RANCHER_HELM_REPO', value: "${env.HA_HELM_REPO}"), + string(name: 'RANCHER_HELM_URL', value: "${env.HA_HELM_URL}"), + string(name: 'RANCHER_HA_CERT_OPTION', value: "${env.HA_CERT_OPTION}"), + string(name: 'RKE_VERSION', value: "${env.RKE_VERSION}"), + string(name: 'RANCHER_HA_HARDENED', value: "${env.RANCHER_HA_HARDENED}"), + string(name: 'RANCHER_PSP_ENABLED', value: "${env.RANCHER_PSP_ENABLED}"), + string(name: 'RANCHER_HELM_EXTRA_SETTINGS', value: "${env.RANCHER_HELM_EXTRA_SETTINGS}") + ] + + build job: 'rancher-v3_ha_deploy', parameters: deployParams + } + stage('Post Rancher Install Configuration') { + sh "docker run --name ${setupContainer} -t -e HA_HOST=\$HA_HOST -e ADMIN_PASSWORD=\$ADMIN_PASSWORD " + + "${imageName} sh -c \"${workPath}pipeline/hapostinstall/hapostinstall.sh\"" + + // load HA_KUBECONFIG and HA_TOKEN + sh "docker cp ${setupContainer}:${rootPath}${groovyEnvironments} ." + load groovyEnvironments + } + stage ('Generate configuration files') { + sh "docker run --name ${configGeneratorContainer} -t -e HA_TOKEN=\$HA_TOKEN -e CATTLE_TEST_CONFIG=\$CATTLE_TEST_CONFIG " + + "${imageName} sh -c \"${workPath}pipeline/releaseupgrade/releaseupgrade.sh\"" + + sh "docker cp ${configGeneratorContainer}:${rootPath}${configsDir}/ ." + + def configs = sh(script: "ls -1 ./${configsDir}", returnStdout: true).split() + + for (int i = 0; i < configs.size(); i++) { + def configName = configs[i] + echo "pushing ${configName} to the global variable" + configFiles << "${configName}" + } + + println "Removing the tagged image" + sh "docker rmi -f ${imageName}" + + println "Building the image again with the config files" + sh "./tests/v2/validation/build.sh" + sh "./tests/v2/validation/configure.sh" + } + stage('Deploys clusters') { + try { + jobs = [:] + + configFiles.each { + def configPath = "./${configsDir}/$it" + def absoluteConfigPath = "${rootPath}${configsDir}/$it" + + def testCase = sh ( + script: "./yq '.testCases.provisioningTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.provisioningTestPackage' ${configPath}", + returnStdout: true + ).trim() + + jobs["$it-provisioning"] = { + stage("Parallel Provisioning: $it"){ + def containerName = "${job_name}${env.BUILD_NUMBER}_$it-provisioning" + try { + sh "docker run --name ${containerName} -t -e CATTLE_TEST_CONFIG=\"${absoluteConfigPath}\" " + + "${imageName} sh -c \"/root/go/bin/gotestsum --format standard-verbose --packages=\"${testsDir}${testPackage}\" --junitfile ${testResultsOut} -- -tags=validation ${testCase} -timeout=\"60m\" -v\"" + + dir("./${patchedConfigsDir}") { + sh "docker cp ${containerName}:${rootPath}${configsDir}/$it ." + } + } catch (err){ + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + } + } + + parallel jobs + } catch(err){ + echo "Provisioning tests had failures: " + err + } + } + stage('Cluster names mapping') { + configFiles.each { + try{ + sh ( + script: "./yq -i '.upgradeInput.clusters[0].name = .rancher.clusterName' ./${patchedConfigsDir}/$it", + returnStdout: true + ) + } catch(err){ + echo "Cluster mapping had failures: " + err + } + } + } + stage('Run preupgrade checks') { + try { + jobs = [:] + + configFiles.each { + try { + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.preUpgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "30m"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}") + ] + + jobs["$it-preupgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err) { + echo "Pre upgrade $it had failures: " + err + } + } + + parallel jobs + } catch(err) { + echo "Pre upgrade tests had failures: " + err + } + } + stage('Upgrade Rancher') { + upgradeParams = [ + string(name: 'RANCHER_HA_HOSTNAME', value: "${env.HA_HOST}"), + string(name: 'RANCHER_CHART_VERSION', value: "${env.HA_CHART_VERSION_TO_UPGRADE}"), + string(name: 'RANCHER_IMAGE_TAG', value: "${env.HA_IMAGE_TAG_TO_UPGRADE}"), + string(name: 'RANCHER_HELM_REPO', value: "${env.HA_HELM_REPO_TO_UPGRADE}"), + string(name: 'RANCHER_HELM_URL', value: "${env.HA_HELM_URL_TO_UPGRADE}"), + string(name: 'RANCHER_HA_CERT_OPTION', value: "${env.HA_CERT_OPTION}"), + string(name: 'RANCHER_HA_KUBECONFIG', value: "${env.HA_KUBECONFIG}"), + string(name: 'RANCHER_HELM_EXTRA_SETTINGS', value: "${env.RANCHER_HELM_EXTRA_SETTINGS_TO_UPGRADE}") + ] + + build job: 'rancher-v3_ha_upgrade', parameters: upgradeParams + } + stage('Run postupgrade checks') { + try { + jobs = [:] + + configFiles.each { + try { + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.postUpgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "30m"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}") + ] + + jobs["$it-postupgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err) { + echo "Post upgrade $it had failures: " + err + } + } + + parallel jobs + } catch(err){ + echo "Post upgrade tests had failures: " + err + } + } + stage('Upgrade cluster versions') { + try{ + jobs = [:] + + configFiles.each { + try { + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.upgradeKubernetesTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "2h"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}" ) + ] + + jobs["$it-k8supgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err){ + echo "Kubernetes upgrade $it had failures: " + err + } + } + + parallel jobs + } catch(err){ + echo "Kubernetes upgrade tests had failures: " + err + } + } + stage('Run postupgrade checks') { + try{ + jobs = [:] + + configFiles.each { + try{ + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.postUpgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "30m"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}") + ] + + jobs["$it-postupgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err){ + echo "Post upgrade test $it had failures: " + err + } + } + + parallel jobs + } catch(err){ + echo "Post upgrade tests had failures: " + err + } + } + stage('Deploy new clusters') { + try { + jobs = [:] + + configFiles.each { + try{ + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "${configPath}") + + def testCase = sh ( + script: "./yq '.testCases.provisioningTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.provisioningTestPackage' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "1h"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}") + ] + + jobs["$it-provisioning"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err){ + echo "Deploy new cluster test $it had failures: " + err + } + } + + parallel jobs + } catch(err){ + echo "Deploy new clusters tests had failures: " + err + } + } + stage('Delete Rancher and resources') { + if (env.HA_CLEANUP.toBoolean()) { + try{ + sh 'echo Cleanup is enabled' + + sh "docker run --name ${cleanupContainer} -t -e HA_HOST=\$HA_HOST -e ADMIN_PASSWORD=\$ADMIN_PASSWORD " + + "${imageName} sh -c \"${workPath}pipeline/downstreamcleanup/downstreamcleanup.sh\"" + + deleteParams = [ + string(name: 'CATTLE_TEST_URL', value: "http://${env.HA_HOST}") + ] + + build job: 'rancher-v3_ha_delete', parameters: deleteParams + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + } catch(err){ + echo "Cleanup had failures: " + err + } + } else { + sh 'echo Cleanup is disabled' + } + } + stage('Test Report') { + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + + sh "docker rmi -f ${imageName}" + } + } catch(err) { + echo "Caught: ${err}" + stage('Delete Rancher and resources in error') { + if (env.HA_CLEANUP.toBoolean()) { + try { + sh 'echo Cleanup is enabled' + + sh "docker run --name ${cleanupContainer} -t -e HA_HOST=\$HA_HOST -e ADMIN_PASSWORD=\$ADMIN_PASSWORD " + + "${imageName} sh -c \"${workPath}pipeline/downstreamcleanup/downstreamcleanup.sh\"" + + deleteParams = [ + string(name: 'CATTLE_TEST_URL', value: "http://${env.HA_HOST}") + ] + + build job: 'rancher-v3_ha_delete', parameters: deleteParams + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + } catch(error) { + echo "Cleanup had failures: " + error + } + } else { + sh 'echo Cleanup is disabled' + } + } + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + + sh "docker rmi -f ${imageName}" + } // catch error + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.local b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.local new file mode 100644 index 0000000..0a96d1c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/Jenkinsfile.release.upgrade.local @@ -0,0 +1,456 @@ +#!groovy +node { + def rootPath = "/root/go/src/github.com/rancher/rancher/" + def workPath = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def buildTestContainer = "${job_name}${env.BUILD_NUMBER}-buildtest" + def configGeneratorContainer = "${job_name}${env.BUILD_NUMBER}_generator" + def cleanupContainer = "${job_name}${env.BUILD_NUMBER}_cleanup" + + def validationVolume = "ValidationSharedVolume-${job_name}${env.BUILD_NUMBER}" + + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + + def testsDir = "/root/go/src/github.com/rancher/rancher/tests/v2/validation/" + def upgradeTestsDir = "${testsDir}upgrade" + def provisioningTestsDir = "${testsDir}provisioning" + + def groovyEnvironments = "environments.groovy" + def configsDir = "cattle-configs" + def patchedConfigsDir = "patched-cattle-configs" + + def testResultsOut = "results.xml" + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + // rancher + def rancherRepo = scm.getUserRemoteConfigs()[0].getUrl() + if ("${env.REPO}" != "null" && "${env.REPO}" != "") { + rancherRepo = "${env.REPO}" + } + def branch = "release/v2.8" + if ("${env.BRANCH}" != "null" && "${env.BRANCH}" != "") { + branch = "${env.BRANCH}" + } + + // corral + def corralBranch = "main" + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" != "") { + corralBranch = "${env.RANCHER_CORRAL_PACKAGES_REPO_BRANCH}" + } + if (scm.getUserRemoteConfigs().size() > 1) { + corralRepo = scm.getUserRemoteConfigs()[1].getUrl() + } + if ("${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "null" && "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" != "") { + corralRepo = "${env.RANCHER_CORRAL_PACKAGES_REPO_URL}" + } + + + def timeout = "60m" + if ("${env.TIMEOUT}" != "null" && "${env.TIMEOUT}" != "") { + timeout = "${env.TIMEOUT}" + } + + def cleanup = env.RANCHER_CLEANUP.toLowerCase() + + def localConfigFileName = "" + def configFiles = [] + + def defaultTag = "validation" + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + dir("./rancher") { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: rancherRepo]] + ]) + } + dir('./') { + echo "cloning corral-packages repo" + + dir('./corral-packages') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${corralBranch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: [[url: corralRepo]] + ]) + } + } + } + dir ("./") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./rancher/tests/v2/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + dir("./rancher/tests/v2/validation") { + def filename = "config.yaml" + def configContents = env.CONFIG + + writeFile file: filename, text: configContents + env.CATTLE_TEST_CONFIG = workPath+filename + } + dir ("./") { + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e --build-arg CORRAL_VERSION=${env.CORRAL_VERSION} --build-arg RKE_VERSION=${env.RKE_VERSION} -t ${imageName}" + sh "docker volume create --name ${validationVolume}" + } + } + stage('Setup') { + sh returnStdout: true, script: 'wget -qO ./yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64' + sh returnStdout:true, script: 'chmod a+x ./yq' + } + stage("Build Environment") { + try { + sh "docker run -v ${validationVolume}:/root --name ${buildTestContainer} -t --env-file ${envFile} " + + "${imageName} sh -c \"${workPath}pipeline/scripts/setup_environment.sh\"" + } catch(err) { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + sh "docker volume rm -f ${validationVolume}" + error "Build Environment had failures." + } + } + stage ('Generate configuration files') { + sh "docker run --volumes-from ${buildTestContainer} --name ${configGeneratorContainer} -t -e CATTLE_TEST_CONFIG=\$CATTLE_TEST_CONFIG " + + "${imageName} sh -c \"${workPath}pipeline/releaseupgrade/releaseupgrade.sh\"" + + sh "docker cp ${configGeneratorContainer}:${rootPath}${configsDir}/ ." + + def configs = sh(script: "ls -1 ./${configsDir}", returnStdout: true).split() + + for (int i = 0; i < configs.size(); i++) { + def configName = configs[i] + if (configName.contains('local')) { + echo "skipping pushing local to the global variable" + localConfigFileName = "$configName" + continue + } + echo "pushing ${configName} to the global variable" + configFiles << "${configName}" + } + + //copy local config file to patched dir to prevent any additional permission access + dir("./${patchedConfigsDir}") { + sh "docker cp ${configGeneratorContainer}:${rootPath}${configsDir}/${localConfigFileName} ." + } + + println "Building the image again with the config files" + sh "./rancher/tests/v2/validation/configure.sh" + sh "docker build . -f ./rancher/tests/v2/validation/Dockerfile.e2e -t ${imageName}" + } + stage('Deploys clusters') { + if ( configFiles.size() >= 1 ) { + try { + jobs = [:] + + configFiles.each { + def configPath = "./${configsDir}/$it" + def absoluteConfigPath = "${rootPath}${configsDir}/$it" + + def testCase = sh ( + script: "./yq '.testCases.provisioningTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.provisioningTestPackage' ${configPath}", + returnStdout: true + ).trim() + + jobs["$it-provisioning"] = { + stage("Parallel Provisioning: $it"){ + def containerName = "${job_name}${env.BUILD_NUMBER}_$it-provisioning" + try { + sh "docker run --volumes-from ${buildTestContainer} --name ${containerName} -t -e CATTLE_TEST_CONFIG=\"${absoluteConfigPath}\" " + + "${imageName} sh -c \"gotestsum --format standard-verbose --packages=\"${testsDir}${testPackage}\" --junitfile ${testResultsOut} -- -tags=validation ${testCase} -timeout=\"60m\" -v\"" + + dir("./${patchedConfigsDir}") { + sh "docker cp ${containerName}:${rootPath}${configsDir}/$it ." + } + } catch (err){ + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + + sh "docker stop ${containerName}" + sh "docker rm -v ${containerName}" + } + } + } + + parallel jobs + + } catch(err){ + echo "Provisioning tests had failures: " + err + } + } else { + echo "No downstream configuration found to provision" + } + } + stage('Cluster names mapping') { + if ( configFiles.size() >= 1 ) { + configFiles.each { + try{ + sh ( + script: "./yq -i '.upgradeInput.clusters[0].name = .rancher.clusterName' ./${patchedConfigsDir}/$it", + returnStdout: true + ) + } catch(err){ + echo "Cluster mapping had failures: " + err + } + } + } else { + echo "No downstream configuration found to map cluster name" + } + + echo "pushing ${localConfigFileName} to the global variable" + configFiles << "${localConfigFileName}" + + } + stage('Run preupgrade checks') { + try { + jobs = [:] + + configFiles.each { + try { + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.preUpgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "30m"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}"), + string(name: 'RKE_VERSION', value: "${env.RKE_VERSION}") + ] + + jobs["$it-preupgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err) { + echo "Pre upgrade $it had failures: " + err + } + } + + parallel jobs + } catch(err) { + echo "Pre upgrade tests had failures: " + err + } + } + stage('Upgrade local cluster version') { + try { + def configPath = "./${configsDir}/${localConfigFileName}" + def configYaml = readFile(file: "./${patchedConfigsDir}/${localConfigFileName}") + + def testCase = sh ( + script: "./yq '.testCases.upgradeKubernetesTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "2h"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}" ), + string(name: 'RKE_VERSION', value: "${env.RKE_VERSION}") + ] + + build job: 'go-automation-freeform-job', parameters: goValidationParams + } catch(err) { + echo "Kubernetes upgrade tests had failures: " + err + } + } + stage('Run postupgrade checks') { + try { + jobs = [:] + + configFiles.each { + try { + def configPath = "./${configsDir}/$it" + def configYaml = readFile(file: "./${patchedConfigsDir}/$it") + + def testCase = sh ( + script: "./yq '.testCases.postUpgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def testPackage = sh ( + script: "./yq '.testCases.upgradeTestCase' ${configPath}", + returnStdout: true + ).trim() + + def goValidationParams = [ + string(name: 'TIMEOUT', value: "30m"), + text(name: 'CONFIG', value: configYaml), + string(name: 'REPO', value: "${rancherRepo}"), + string(name: 'BRANCH', value: "${branch}"), + string(name: 'TEST_PACKAGE', value: "${testPackage}"), + string(name: 'TAGS', value: "${defaultTag}"), + string(name: 'GOTEST_TESTCASE', value: "${testCase}"), + string(name: 'RKE_VERSION', value: "${env.RKE_VERSION}") + ] + + jobs["$it-postupgrade"] = { build job: 'go-automation-freeform-job', parameters: goValidationParams } + } catch(err) { + echo "Post upgrade $it had failures: " + err + } + } + + parallel jobs + } catch(err){ + echo "Post upgrade tests had failures: " + err + } + } + stage('Delete Rancher and resources') { + if (cleanup.toBoolean()) { + try{ + sh 'echo Cleanup is enabled' + + sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " + + "${golangImageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\"" + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + } catch(err){ + echo "Cleanup had failures: " + err + } + } else { + sh 'echo Cleanup is disabled' + } + } + stage('Test Report') { + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + + if (cleanup.toBoolean()) { + sh "docker stop ${cleanupTestContainer}" + sh "docker rm -v ${cleanupTestContainer}" + } + + sh "docker rmi -f ${imageName}" + } + } catch(err) { + echo "Caught: ${err}" + stage('Delete Rancher and resources in error') { + if (cleanup.toBoolean()) { + try { + sh 'echo Cleanup is enabled' + + sh "docker run --volumes-from ${buildTestContainer} --name ${cleanupTestContainer} -t --env-file ${envFile} " + + "${golangImageName} sh -c \"${workPath}pipeline/scripts/rancher_cleanup.sh\"" + + sh "docker stop ${cleanupContainer}" + sh "docker rm -v ${cleanupContainer}" + } catch(error) { + echo "Cleanup had failures: " + error + } + } else { + sh 'echo Cleanup is disabled' + } + } + sh "docker stop ${buildTestContainer}" + sh "docker rm -v ${buildTestContainer}" + + sh "docker stop ${configGeneratorContainer}" + sh "docker rm -v ${configGeneratorContainer}" + + sh "docker rmi -f ${imageName}" + } // catch error + } // dir + } // withEnv + } // creds + } // folder properties + } // wrap +} // node diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/docs/release-upgrade/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/docs/release-upgrade/README.md new file mode 100644 index 0000000..ceae679 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/docs/release-upgrade/README.md @@ -0,0 +1,156 @@ +# Release HA Upgrade Validation + +Release HA upgrade is an automation task for the Rancher release testing process. It heavily relies on the framework's configuration file generation. Its initial configuration contains two main components: + +1. HA Configuration: Parent field that has the HA options, such as rancher version to deploy, or rancher version to upgrade. +2. Clusters Configuration: Parent field that has the downstream options. This part maintains the match of the matrix for the configuration file generation. This matrix enables the test to generate individual configuration files per cluster type, providers, image, and SSH user to the given images. + +You can check the whole configuration, [here](../../../../../framework/extensions/pipelineutil/releaseupgrade.go). + +### HA Configuration + +```yaml +ha: + host: "" # String, needs to be URL + chartVersion: "" # String without any prefix, no v in front of version + chartVersionToUpgrade: "" # String without any prefix, no v in front of version + rkeVersion: "" # String with prefix v + imageTag: "" # String with prefix v + imageTagToUpgrade: "" # String with prefix v + helmRepo: "" # String + certOption: "" # String + insecure: false # String + cleanup: false # String, default is true +``` + +### Clusters Configuration + +Below an example test configuration with 1 Node Provider, 1 Custom; RKE1, K3s, and RKE2 types. And 3 Hosted Clusters: + +```yaml +clusters: + rke1: + nodeProvider: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + custom: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + rke2: + nodeProvider: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + - provider: "aws" + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "ubuntu" + cni: ["calico"] + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + custom: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + k3s: + nodeProvider: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + custom: + - provider: "" # Name of the provider + kubernetesVersion: "vMYVERSION" # String with prefix v, as UI shows + kubernetesVersionToUpgrade: "vMYVERSION" # String with prefix v, as UI shows + image: "" # String + sshUser: "" # String + cni: ["calico"] # Slice of strings, options can be found in provisioning configuration + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable + hosted: + - provider: "" # Name of the provider + kubernetesVersion: "MYVERSION" # String without prefix v, as UI shows + kubernetesVersionToUpgrade: "MYVERSION" # String without prefix v, as UI shows + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + - provider: "" # Name of the provider + kubernetesVersion: "MYVERSION" # String without prefix v, as UI shows + kubernetesVersionToUpgrade: "MYVERSION" # String without prefix v, as UI shows + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + - provider: "" # Name of the provider + kubernetesVersion: "MYVERSION" # String without prefix v, as UI shows + kubernetesVersionToUpgrade: "MYVERSION" # String without prefix v, as UI shows + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + # This is a slice of structs, elements are expandable +``` + +### Other Required Configuration + +Depending on the cluster types you want to test, the following configurations are required: + +1. [RKE1 Provisioning](../../../provisioning/rke1/README.md) +2. [RKE2 Provisioning](../../../provisioning/rke2/README.md) +3. [K3s Provisioning](../../../provisioning/k3s/README.md) +4. [Hosted Provider Provisioning](../../../provisioning/hosted/README.md) + +*The fields that are declared in the [clusters](#clusters-configuration) input above, are going to overwrite the values that are given as provisioning configuration.* + +In addition to this configuration generation, other dependent factors are: + +1. An environment flag called **UpdateClusterName** updates the test configuration's YAML cluster name field, in all provisioning tests, after the cluster creation steps. +2. Provider names and different user types, particularly for all provisioning tests, are hardcoded in their corresponding test case regexp while generating the configuration files. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/downstreamcleanup.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/downstreamcleanup.sh new file mode 100755 index 0000000..94a2635 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/downstreamcleanup.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ + +echo "building release downstream cleanup bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/pipeline/bin/downstreamcleanup ./tests/v2/validation/pipeline/downstreamcleanup + +echo "running downstream cleanup" +tests/v2/validation/pipeline/bin/downstreamcleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/main.go new file mode 100644 index 0000000..6bf8069 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/downstreamcleanup/main.go @@ -0,0 +1,116 @@ +package main + +import ( + "fmt" + "os" + "time" + + "github.com/rancher/norman/types" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/token" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/file" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" +) + +type wrappedConfig struct { + Configuration *rancher.Config `yaml:"rancher"` +} + +var ( + adminPassword = os.Getenv("ADMIN_PASSWORD") + host = os.Getenv("HA_HOST") + + configFileName = file.Name("cattle-config.yaml") +) + +func main() { + rancherConfig := new(rancher.Config) + rancherConfig.Host = host + isCleanupEnabled := true + rancherConfig.Cleanup = &isCleanupEnabled + + adminUser := &management.User{ + Username: "admin", + Password: adminPassword, + } + + //create admin token + var adminToken *management.Token + err := kwait.Poll(500*time.Millisecond, 5*time.Minute, func() (done bool, err error) { + adminToken, err = token.GenerateUserToken(adminUser, host) + if err != nil { + return false, nil + } + return true, nil + }) + if err != nil { + logrus.Errorf("error creating admin token: %v", err) + } + rancherConfig.AdminToken = adminToken.Token + + //create config file + configWrapped := &wrappedConfig{ + Configuration: rancherConfig, + } + configData, err := yaml.Marshal(configWrapped) + if err != nil { + logrus.Errorf("error marshaling: %v", err) + } + _, err = configFileName.NewFile(configData) + if err != nil { + logrus.Fatalf("error writing yaml: %v", err) + } + err = configFileName.SetEnvironmentKey(config.ConfigEnvironmentKey) + if err != nil { + logrus.Fatalf("error while setting environment path: %v", err) + } + + session := session.NewSession() + client, err := rancher.NewClient("", session) + if err != nil { + logrus.Errorf("error creating client: %v", err) + } + + clusterList, err := client.Management.Cluster.List(&types.ListOpts{}) + if err != nil { + logrus.Errorf("error getting cluster list: %v", err) + } + + for _, c := range clusterList.Data { + isLocalCluster := c.ID == "local" + if !isLocalCluster { + opts := metav1.ListOptions{ + FieldSelector: "metadata.name=" + c.ID, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + } + + err := client.Management.Cluster.Delete(&c) + if err != nil { + logrus.Errorf("error delete cluster call: %v", err) + } + + watchInterface, err := client.GetManagementWatchInterface(management.ClusterType, opts) + if err != nil { + logrus.Errorf("error while getting the watch interface: %v", err) + } + + wait.WatchWait(watchInterface, func(event watch.Event) (ready bool, err error) { + if event.Type == watch.Error { + return false, fmt.Errorf("there was an error deleting cluster") + } else if event.Type == watch.Deleted { + return true, nil + } + return false, nil + }) + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/hapostinstall.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/hapostinstall.sh new file mode 100755 index 0000000..ad18918 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/hapostinstall.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ + +configPath=$CATTLE_TEST_CONFIG + +echo "building ha post install bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/pipeline/bin/hapostinstall ./tests/v2/validation/pipeline/hapostinstall + +echo "running ha post install" +tests/v2/validation/pipeline/bin/hapostinstall + +export CATTLE_TEST_CONFIG=$configPath diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/main.go new file mode 100644 index 0000000..4c5b170 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/hapostinstall/main.go @@ -0,0 +1,118 @@ +package main + +import ( + "fmt" + "os" + "strings" + "time" + + b64 "encoding/base64" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/pipeline" + "github.com/rancher/shepherd/extensions/token" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/file" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +var ( + adminPassword = os.Getenv("ADMIN_PASSWORD") + host = os.Getenv("HA_HOST") + + clusterID = "local" + + configFileName = file.Name("cattle-config.yaml") + environmentsFileName = "environments.groovy" + + tokenEnvironmentKey = "HA_TOKEN" + kubeconfigEnvironmentKey = "HA_KUBECONFIG" +) + +type wrappedConfig struct { + Configuration *rancher.Config `yaml:"rancher"` +} + +func main() { + rancherConfig := new(rancher.Config) + rancherConfig.Host = host + isCleanupEnabled := false + rancherConfig.Cleanup = &isCleanupEnabled + + adminUser := &management.User{ + Username: "admin", + Password: adminPassword, + } + + //create admin token + var adminToken *management.Token + err := kwait.Poll(500*time.Millisecond, 5*time.Minute, func() (done bool, err error) { + adminToken, err = token.GenerateUserToken(adminUser, host) + if err != nil { + return false, nil + } + return true, nil + }) + if err != nil { + logrus.Fatalf("error creating admin token: %v", err) + } + rancherConfig.AdminToken = adminToken.Token + + //create config file + configWrapped := &wrappedConfig{ + Configuration: rancherConfig, + } + configData, err := yaml.Marshal(configWrapped) + if err != nil { + logrus.Fatalf("error marshaling: %v", err) + } + _, err = configFileName.NewFile(configData) + if err != nil { + logrus.Fatalf("error writing yaml: %v", err) + } + err = configFileName.SetEnvironmentKey(config.ConfigEnvironmentKey) + if err != nil { + logrus.Fatalf("error while setting environment path: %v", err) + } + + //generate kubeconfig + session := session.NewSession() + client, err := rancher.NewClient("", session) + if err != nil { + logrus.Fatalf("error creating client: %v", err) + } + + err = pipeline.UpdateEULA(client) + if err != nil { + logrus.Fatalf("error updating EULA: %v", err) + } + + cluster, err := client.Management.Cluster.ByID(clusterID) + if err != nil { + logrus.Fatalf("error getting cluster: %v", err) + } + kubeconfig, err := client.Management.Cluster.ActionGenerateKubeconfig(cluster) + if err != nil { + logrus.Fatalf("error getting kubeconfig: %v", err) + } + + //create groovy environments file + kubeconfigb64 := b64.StdEncoding.EncodeToString([]byte(kubeconfig.Config)) + kubeconfigEnvironment := newGroovyEnvStr(kubeconfigEnvironmentKey, kubeconfigb64) + tokenEnvironment := newGroovyEnvStr(tokenEnvironmentKey, adminToken.Token) + environmentsData := strings.Join([]string{tokenEnvironment, kubeconfigEnvironment}, "\n") + err = os.WriteFile(environmentsFileName, []byte(environmentsData), 0644) + if err != nil { + logrus.Fatalf("error writing yaml: %v", err) + } + +} + +func newGroovyEnvStr(key, value string) string { + prefix := "env" + return fmt.Sprintf("%v.%v='%v'", prefix, key, value) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/README.md new file mode 100644 index 0000000..0a975c2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/README.md @@ -0,0 +1,13 @@ +# Qase Reporting + +The package contains two main.go files, that use the qase-go client to perform API calls to Qase. Reporter updates Qase with test cases and their statuses, and testrun starts and ends test runs for our recurring runs pipelines. + +## Table of Contents +1. [Reporter](#Reporter) +2. [Test Run](#Test-Run) + +## Reporter +Reporter retreives all test cases inorder to determine if said automation test exists or not. If it does not it will create the test case. There is a custom field for automation test name, so we can update results for existing tests. This is to determine if a pre-existing manual test case has been automated. This value should be the package and test name, ex: TestTokenTestSuite/TestPatchTokenTest1. It will then update the status of the test case, for a specifc test run provided. + +## Test Run +Test run is primarily used to create a test run for our different recurring run pipelines ie daily, weekly and biweekly. There is a custom field in test run for source, so we can filter by how the test run is created. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/defaults.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/defaults.go new file mode 100644 index 0000000..cacbdb1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/defaults.go @@ -0,0 +1,8 @@ +package qase + +const ( + RancherManagerProjectID = "RM" + QaseTokenEnvVar = "QASE_AUTOMATION_TOKEN" + TestRunEnvVar = "QASE_TEST_RUN_ID" + TestRunNameEnvVar = "TEST_RUN_NAME" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/reporter/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/reporter/main.go new file mode 100644 index 0000000..d1cf38c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/reporter/main.go @@ -0,0 +1,306 @@ +package main + +import ( + "bufio" + "context" + "fmt" + "os" + "regexp" + "strconv" + "strings" + + "github.com/antihax/optional" + qasedefaults "github.com/rancher/rancher/tests/v2/validation/pipeline/qase" + "github.com/rancher/rancher/tests/v2/validation/pipeline/qase/testcase" + "github.com/rancher/rancher/tests/v2/validation/pipeline/slack" + "github.com/sirupsen/logrus" + qase "go.qase.io/client" + "gopkg.in/yaml.v2" +) + +const ( + automationSuiteID = int32(554) + failStatus = "fail" + passStatus = "pass" + skipStatus = "skip" + automationTestNameID = 15 + testSourceID = 14 + testSource = "GoValidation" + multiSubTestPattern = `(\w+/\w+/\w+){1,}` + subtestPattern = `(\w+/\w+){1,1}` + testResultsJSON = "results.json" +) + +var ( + multiSubTestReg = regexp.MustCompile(multiSubTestPattern) + subTestReg = regexp.MustCompile(subtestPattern) + qaseToken = os.Getenv(qasedefaults.QaseTokenEnvVar) + runIDEnvVar = os.Getenv(qasedefaults.TestRunEnvVar) +) + +func main() { + if runIDEnvVar != "" { + cfg := qase.NewConfiguration() + cfg.AddDefaultHeader("Token", qaseToken) + client := qase.NewAPIClient(cfg) + + runID, err := strconv.ParseInt(runIDEnvVar, 10, 64) + if err != nil { + logrus.Fatalf("error reporting converting string to int64: %v", err) + } + + err = reportTestQases(client, runID) + if err != nil { + logrus.Error("error reporting: ", err) + } + } +} + +func getAllAutomationTestCases(client *qase.APIClient) (map[string]qase.TestCase, error) { + testCases := []qase.TestCase{} + testCaseNameMap := map[string]qase.TestCase{} + var numOfTestsCases int32 = 1 + offSetCount := 0 + for numOfTestsCases > 0 { + offset := optional.NewInt32(int32(offSetCount)) + localVarOptionals := &qase.CasesApiGetCasesOpts{ + Offset: offset, + } + tempResult, _, err := client.CasesApi.GetCases(context.TODO(), qasedefaults.RancherManagerProjectID, localVarOptionals) + if err != nil { + return nil, err + } + + testCases = append(testCases, tempResult.Result.Entities...) + numOfTestsCases = tempResult.Result.Count + offSetCount += 10 + } + + for _, testCase := range testCases { + automationTestNameCustomField := getAutomationTestName(testCase.CustomFields) + if automationTestNameCustomField != "" { + testCaseNameMap[automationTestNameCustomField] = testCase + } else { + testCaseNameMap[testCase.Title] = testCase + } + + } + + return testCaseNameMap, nil +} + +func readTestCase() ([]testcase.GoTestOutput, error) { + file, err := os.Open(testResultsJSON) + if err != nil { + return nil, err + } + + fscanner := bufio.NewScanner(file) + testCases := []testcase.GoTestOutput{} + for fscanner.Scan() { + var testCase testcase.GoTestOutput + err = yaml.Unmarshal(fscanner.Bytes(), &testCase) + if err != nil { + return nil, err + } + testCases = append(testCases, testCase) + } + + return testCases, nil +} + +func parseCorrectTestCases(testCases []testcase.GoTestOutput) map[string]*testcase.GoTestCase { + finalTestCases := map[string]*testcase.GoTestCase{} + var deletedTest string + var timeoutFailure bool + for _, testCase := range testCases { + if testCase.Action == "run" && strings.Contains(testCase.Test, "/") { + newTestCase := &testcase.GoTestCase{Name: testCase.Test} + finalTestCases[testCase.Test] = newTestCase + } else if testCase.Action == "output" && strings.Contains(testCase.Test, "/") { + goTestCase := finalTestCases[testCase.Test] + goTestCase.StackTrace += testCase.Output + } else if testCase.Action == skipStatus { + delete(finalTestCases, testCase.Test) + } else if (testCase.Action == failStatus || testCase.Action == passStatus) && strings.Contains(testCase.Test, "/") { + goTestCase := finalTestCases[testCase.Test] + + if goTestCase != nil { + substring := subTestReg.FindString(goTestCase.Name) + goTestCase.StackTrace += testCase.Output + goTestCase.Status = testCase.Action + goTestCase.Elapsed = testCase.Elapsed + + if multiSubTestReg.MatchString(goTestCase.Name) && substring != deletedTest { + deletedTest = subTestReg.FindString(goTestCase.Name) + delete(finalTestCases, deletedTest) + } + + } + } else if testCase.Action == failStatus && testCase.Test == "" { + timeoutFailure = true + } + } + + for _, testCase := range finalTestCases { + testSuite := strings.Split(testCase.Name, "/") + testName := testSuite[len(testSuite)-1] + testCase.Name = testName + testCase.TestSuite = testSuite[0 : len(testSuite)-1] + if timeoutFailure && testCase.Status == "" { + testCase.Status = failStatus + } + } + + return finalTestCases +} + +func reportTestQases(client *qase.APIClient, testRunID int64) error { + tempTestCases, err := readTestCase() + if err != nil { + return nil + } + + goTestCases := parseCorrectTestCases(tempTestCases) + + qaseTestCases, err := getAllAutomationTestCases(client) + if err != nil { + return err + } + + resultTestMap := []*testcase.GoTestCase{} + for _, goTestCase := range goTestCases { + if testQase, ok := qaseTestCases[goTestCase.Name]; ok { + // update test status + err = updateTestInRun(client, *goTestCase, testQase.Id, testRunID) + if err != nil { + return err + } + + if goTestCase.Status == failStatus { + resultTestMap = append(resultTestMap, goTestCase) + } + } else { + // write test case + caseID, err := writeTestCaseToQase(client, *goTestCase) + if err != nil { + return err + } + + err = updateTestInRun(client, *goTestCase, caseID.Result.Id, testRunID) + if err != nil { + return err + } + + if goTestCase.Status == failStatus { + resultTestMap = append(resultTestMap, goTestCase) + } + } + } + resp, _, err := client.RunsApi.GetRun(context.TODO(), qasedefaults.RancherManagerProjectID, int32(testRunID)) + if err != nil { + return fmt.Errorf("error getting test run: %v", err) + } + if strings.Contains(resp.Result.Title, "-head") { + return slack.PostSlackMessage(resultTestMap, testRunID, resp.Result.Title) + } + + return nil +} + +func writeTestSuiteToQase(client *qase.APIClient, testCase testcase.GoTestCase) (*int64, error) { + parentSuite := int64(automationSuiteID) + var id int64 + for _, suiteGo := range testCase.TestSuite { + localVarOptionals := &qase.SuitesApiGetSuitesOpts{ + FiltersSearch: optional.NewString(suiteGo), + } + + qaseSuites, _, err := client.SuitesApi.GetSuites(context.TODO(), qasedefaults.RancherManagerProjectID, localVarOptionals) + if err != nil { + return nil, err + } + + var testSuiteWasFound bool + var qaseSuiteFound qase.Suite + for _, qaseSuite := range qaseSuites.Result.Entities { + if qaseSuite.Title == suiteGo { + testSuiteWasFound = true + qaseSuiteFound = qaseSuite + } + } + if !testSuiteWasFound { + suiteBody := qase.SuiteCreate{ + Title: suiteGo, + ParentId: int64(parentSuite), + } + idResponse, _, err := client.SuitesApi.CreateSuite(context.TODO(), suiteBody, qasedefaults.RancherManagerProjectID) + if err != nil { + return nil, err + } + id = idResponse.Result.Id + parentSuite = id + } else { + id = qaseSuiteFound.Id + } + } + + return &id, nil +} + +func writeTestCaseToQase(client *qase.APIClient, testCase testcase.GoTestCase) (*qase.IdResponse, error) { + testSuiteID, err := writeTestSuiteToQase(client, testCase) + if err != nil { + return nil, err + } + + testQaseBody := qase.TestCaseCreate{ + Title: testCase.Name, + SuiteId: *testSuiteID, + IsFlaky: int32(0), + Automation: int32(2), + CustomField: map[string]string{ + fmt.Sprintf("%d", testSourceID): testSource, + }, + } + caseID, _, err := client.CasesApi.CreateCase(context.TODO(), testQaseBody, qasedefaults.RancherManagerProjectID) + if err != nil { + return nil, err + } + return &caseID, err +} + +func updateTestInRun(client *qase.APIClient, testCase testcase.GoTestCase, qaseTestCaseID, testRunID int64) error { + status := fmt.Sprintf("%sed", testCase.Status) + var elapsedTime float64 + if testCase.Elapsed != "" { + var err error + elapsedTime, err = strconv.ParseFloat(testCase.Elapsed, 64) + if err != nil { + return err + } + } + + resultBody := qase.ResultCreate{ + CaseId: qaseTestCaseID, + Status: status, + Comment: testCase.StackTrace, + Time: int64(elapsedTime), + } + + _, _, err := client.ResultsApi.CreateResult(context.TODO(), resultBody, qasedefaults.RancherManagerProjectID, testRunID) + if err != nil { + return err + } + + return nil +} + +func getAutomationTestName(customFields []qase.CustomFieldValue) string { + for _, field := range customFields { + if field.Id == automationTestNameID { + return field.Value + } + } + return "" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testcase/testcase.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testcase/testcase.go new file mode 100644 index 0000000..a27cebd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testcase/testcase.go @@ -0,0 +1,20 @@ +package testcase + +// GoTestOutput is the JSON output from gotestsum, this what is used to parse go test results. +type GoTestOutput struct { + Time string `json:"Time" yaml:"Time"` + Action string `json:"Action" yaml:"Action"` + Package string `json:"Package" yaml:"Package"` + Test string `json:"Test" yaml:"Test"` + Output string `json:"Output" yaml:"Output"` + Elapsed string `json:"Elapsed" yaml:"Elapsed"` +} + +// GoTestCase is the struct used for sending the appropriate API call to Qase +type GoTestCase struct { + Name string + TestSuite []string + Status string + StackTrace string + Elapsed string +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testrun/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testrun/main.go new file mode 100644 index 0000000..ae3a60a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/qase/testrun/main.go @@ -0,0 +1,107 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "os" + + qasedefaults "github.com/rancher/rancher/tests/v2/validation/pipeline/qase" + "github.com/sirupsen/logrus" + qase "go.qase.io/client" + "gopkg.in/yaml.v2" +) + +const ( + runSourceID = 16 + recurringRunID = 1 +) + +var ( + testRunName = os.Getenv(qasedefaults.TestRunNameEnvVar) + qaseToken = os.Getenv(qasedefaults.QaseTokenEnvVar) +) + +type RecurringTestRun struct { + ID int64 `json:"id" yaml:"id"` +} + +func main() { + // commandline flags + startRun := flag.Bool("startRun", false, "commandline flag that determines when to start a run, and conversely when to end it.") + flag.Parse() + + cfg := qase.NewConfiguration() + cfg.AddDefaultHeader("Token", qaseToken) + client := qase.NewAPIClient(cfg) + + if *startRun { + // create test run + resp, err := createTestRun(client, testRunName) + if err != nil { + logrus.Error("error creating test run: ", err) + } + + newRunID := resp.Result.Id + recurringTestRun := RecurringTestRun{} + recurringTestRun.ID = newRunID + err = writeToConfigFile(recurringTestRun) + if err != nil { + logrus.Error("error writiing test run config: ", err) + } + } else { + + testRunConfig, err := readConfigFile() + if err != nil { + logrus.Fatalf("error reporting converting string to int32: %v", err) + } + // complete test run + _, _, err = client.RunsApi.CompleteRun(context.TODO(), qasedefaults.RancherManagerProjectID, int32(testRunConfig.ID)) + if err != nil { + log.Fatalf("error completing test run: %v", err) + } + } + +} + +func createTestRun(client *qase.APIClient, testRunName string) (*qase.IdResponse, error) { + runCreateBody := qase.RunCreate{ + Title: testRunName, + CustomField: map[string]string{ + fmt.Sprintf("%d", runSourceID): fmt.Sprintf("%d", recurringRunID), + }, + } + + idResponse, _, err := client.RunsApi.CreateRun(context.TODO(), runCreateBody, qasedefaults.RancherManagerProjectID) + if err != nil { + return nil, err + } + + return &idResponse, nil +} + +func writeToConfigFile(config RecurringTestRun) error { + yamlConfig, err := yaml.Marshal(config) + + if err != nil { + return err + } + + return os.WriteFile("testrunconfig.yaml", yamlConfig, 0644) +} + +func readConfigFile() (*RecurringTestRun, error) { + configString, err := os.ReadFile("testrunconfig.yaml") + if err != nil { + return nil, err + } + + var testRunConfig RecurringTestRun + err = yaml.Unmarshal(configString, &testRunConfig) + if err != nil { + return nil, err + } + + return &testRunConfig, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/ranchercleanup/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/ranchercleanup/main.go new file mode 100644 index 0000000..61653c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/ranchercleanup/main.go @@ -0,0 +1,92 @@ +package main + +import ( + "context" + "fmt" + "time" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + k8sErrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" +) + +const ( + timeout = int64(60 * 10) +) + +func main() { + testSession := session.NewSession() + + client, err := rancher.NewClient("", testSession) + if err != nil { + logrus.Errorf("error creating admin client: %v", err) + } else { + var clusterList *v1.SteveCollection + err = kwait.Poll(500*time.Millisecond, 2*time.Minute, func() (done bool, err error) { + //clean up clusters + resp, err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).List(nil) + if k8sErrors.IsInternalError(err) || k8sErrors.IsServiceUnavailable(err) { + return false, err + } else if resp != nil { + clusterList = resp + return true, nil + } + return false, nil + }) + + if err != nil { + logrus.Errorf("error retrieving cluster list: %v", err) + } + + deleteTimeout := timeout + for _, cluster := range clusterList.Data { + if cluster.ObjectMeta.Name != "local" { + err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).Delete(&cluster) + if err != nil { + logrus.Errorf("error deleting cluster: %v", err) + } + + provKubeClient, err := client.GetKubeAPIProvisioningClient() + if err != nil { + logrus.Errorf("error deleting corral: %v", err) + } + + watchInterface, err := provKubeClient.Clusters(cluster.ObjectMeta.Namespace).Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + cluster.ObjectMeta.Name, + TimeoutSeconds: &deleteTimeout, + }) + if err != nil { + logrus.Errorf("error initiating watchInterface: %v", err) + } + + err = wait.WatchWait(watchInterface, func(event watch.Event) (ready bool, err error) { + cluster := event.Object.(*apisV1.Cluster) + if event.Type == watch.Error { + return false, fmt.Errorf("there was an error deleting cluster") + } else if event.Type == watch.Deleted { + return true, nil + } else if cluster == nil { + return true, nil + } + return false, nil + }) + if err != nil { + logrus.Errorf("error while deleting clusters: %v", err) + } + } + } + } + corral.DeleteAllCorrals() + if err != nil { + logrus.Errorf("error deleting corrals: %v", err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/corralha/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/corralha/config.go new file mode 100644 index 0000000..96aa33f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/corralha/config.go @@ -0,0 +1,11 @@ +package corralha + +// The json/yaml config key for the corral package to be build .. +const ( + CorralRancherHAConfigConfigurationFileKey = "corralRancherHA" +) + +// CorralPackages is a struct that has the path to the packages +type CorralRancherHA struct { + Name string `json:"name" yaml:"name"` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/main.go new file mode 100644 index 0000000..131c8ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/rancherha/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "strings" + + "github.com/rancher/rancher/tests/v2/validation/pipeline/rancherha/corralha" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rkecli" + "github.com/rancher/shepherd/extensions/pipeline" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" +) + +const rke1 = "rke1" + +func main() { + corralRancherHA := new(corralha.CorralRancherHA) + config.LoadConfig(corralha.CorralRancherHAConfigConfigurationFileKey, corralRancherHA) + + corralSession := session.NewSession() + + corralConfig := corral.Configurations() + err := corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + if err != nil { + logrus.Fatalf("error setting up corral: %v", err) + } + + configPackage := corral.PackagesConfig() + + environmentFlags := environmentflag.NewEnvironmentFlags() + environmentflag.LoadEnvironmentFlags(environmentflag.ConfigurationFileKey, environmentFlags) + installRancher := environmentFlags.GetValue(environmentflag.InstallRancher) + + logrus.Infof("installRancher value is %t", installRancher) + + if installRancher { + path := configPackage.CorralPackageImages[corralRancherHA.Name] + corralName := corralRancherHA.Name + + _, err = corral.CreateCorral(corralSession, corralName, path, true, configPackage.HasCleanup) + if err != nil { + logrus.Errorf("error creating corral: %v", err) + } + + bootstrapPassword, err := corral.GetCorralEnvVar(corralName, "bootstrap_password") + if err != nil { + logrus.Errorf("error getting the bootstrap password: %v", err) + } + + rancherConfig := new(rancher.Config) + config.LoadConfig(rancher.ConfigurationFileKey, rancherConfig) + + token, err := pipeline.CreateAdminToken(bootstrapPassword, rancherConfig) + if err != nil { + logrus.Errorf("error creating the admin token: %v", err) + } + + rancherConfig.AdminToken = token + config.UpdateConfig(rancher.ConfigurationFileKey, rancherConfig) + rancherSession := session.NewSession() + client, err := rancher.NewClient(rancherConfig.AdminToken, rancherSession) + if err != nil { + logrus.Errorf("error creating the rancher client: %v", err) + } + + err = pipeline.PostRancherInstall(client, rancherConfig.AdminPassword) + if err != nil { + logrus.Errorf("error during post rancher install: %v", err) + } + + if strings.Contains(configPackage.CorralPackageImages[corralRancherHA.Name], rke1) { + sshkey, err := corral.GetCorralEnvVar(corralName, "corral_private_key") + if err != nil { + logrus.Errorf("error getting the private SSH key: %v", err) + } + + rkecliConfig := new(rkecli.Config) + config.LoadAndUpdateConfig(rkecli.ConfigurationFileKey, rkecliConfig, func() { + rkecliConfig.SSHKey = sshkey + }) + } + } else { + logrus.Infof("Skipped Rancher Install because installRancher is %t", installRancher) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/main.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/main.go new file mode 100644 index 0000000..cb868c4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/main.go @@ -0,0 +1,359 @@ +package main + +import ( + "fmt" + "os" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/pipeline" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/upgradeinput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + "github.com/rancher/shepherd/pkg/file" + "github.com/sirupsen/logrus" +) + +var ( + configEnvironmentKey = "CATTLE_TEST_CONFIG" + adminToken = os.Getenv("HA_TOKEN") + configPath = os.Getenv(configEnvironmentKey) +) + +const ( + dirName = "cattle-configs" + + localFileName = "local" + + nodeProviderFileName = "node" + customFileName = "custom" + + rke1FileName = "rke1" + rke2FileName = "rke2" + k3sFileName = "k3s" + + eksFileName = "eks" + gkeFileName = "gke" + aksFileName = "aks" +) + +func main() { + os.Setenv(configEnvironmentKey, configPath) + defer os.Unsetenv(configEnvironmentKey) + + haConfig := new(pipeline.HAConfig) + config.LoadConfig(pipeline.HAConfigKey, haConfig) + + rancherConfig := new(rancher.Config) + config.LoadConfig(rancher.ConfigurationFileKey, rancherConfig) + + if haConfig.Host != "" { + rancherConfig.Host = haConfig.Host + rancherConfig.AdminToken = adminToken + + //Rancher cleanup has to be false for the future steps to prevent resource deletion + rancherCleanup := false + rancherConfig.Cleanup = &rancherCleanup + + //HA cleanup default to true if not specified + if haConfig.Cleanup == nil { + HACleanup := true + haConfig.Cleanup = &HACleanup + } + + //Rancher insecure default to true if not specified + if haConfig.Insecure == nil { + insecure := true + rancherConfig.Insecure = &insecure + haConfig.Insecure = &insecure + } else { + rancherConfig.Insecure = haConfig.Insecure + } + + config.UpdateConfig(rancher.ConfigurationFileKey, rancherConfig) + config.UpdateConfig(pipeline.HAConfigKey, haConfig) + } + + testCases := new(pipeline.TestCases) + config.LoadAndUpdateConfig(pipeline.TestCasesConfigKey, testCases, func() { + //Upgrade package and tests + testCases.UpgradeTestPackage = "upgrade" + testCases.PreUpgradeTestCase = `-run \"TestWorkloadUpgradeTestSuite/TestWorkloadPreUpgrade\"` + testCases.PostUpgradeTestCase = `-run \"TestWorkloadUpgradeTestSuite/TestWorkloadPostUpgrade\"` + testCases.UpgradeKubernetesTestCase = `-run \"TestKubernetesUpgradeTestSuite/TestUpgradeKubernetes\"` + }) + + environmentFlags := new(environmentflag.Config) + config.LoadConfig(environmentflag.ConfigurationFileKey, environmentFlags) + + //Overwrite/update flag to grab cluster names that are provisioned + environmentFlags.DesiredFlags += "|" + environmentflag.UpdateClusterName.String() + + config.UpdateConfig(environmentflag.ConfigurationFileKey, environmentFlags) + + //make cattle-configs dir + err := file.NewDir(dirName) + if err != nil { + logrus.Fatal("error while creating configs dir", err) + } + + //copy common configuration for individual configs + copiedConfig, err := os.ReadFile(configPath) + if err != nil { + logrus.Fatal("error while copying upgrade config", err) + } + + clusters := new(pipeline.Clusters) + config.LoadConfig(pipeline.ClustersConfigKey, clusters) + + local := clusters.Local + if local != nil { + newConfigName := config.NewConfigFileName(dirName, localFileName) + err := NewRancherLocalClusterConfiguration(*local, newConfigName, copiedConfig) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + } + } + + for i, v := range clusters.RKE1.Custom { + const isCustom = true + const isRKE1 = true + const isRKE2 = false + + for _, cni := range v.CNIs { + testPackage := "provisioning/rke1" + runCommand := pipeline.WrapWithAdminRunCommand("TestCustomClusterRKE1ProvisioningTestSuite/TestProvisioningRKE1CustomClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, rke1FileName, customFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.RKE1.NodeProvider { + const isCustom = false + const isRKE1 = true + const isRKE2 = false + + for _, cni := range v.CNIs { + testPackage := "provisioning/rke1" + runCommand := pipeline.WrapWithAdminRunCommand("TestRKE1ProvisioningTestSuite/TestProvisioningRKE1ClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, rke1FileName, nodeProviderFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.RKE2.Custom { + const isCustom = true + const isRKE1 = false + const isRKE2 = true + + for _, cni := range v.CNIs { + testPackage := "provisioning/rke2" + runCommand := pipeline.WrapWithAdminRunCommand("TestCustomClusterRKE2ProvisioningTestSuite/TestProvisioningRKE2CustomClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, rke2FileName, customFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.RKE2.NodeProvider { + const isCustom = false + const isRKE1 = false + const isRKE2 = true + + for _, cni := range v.CNIs { + testPackage := "provisioning/rke2" + runCommand := pipeline.WrapWithAdminRunCommand("TestRKE2ProvisioningTestSuite/TestProvisioningRKE2ClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, rke2FileName, nodeProviderFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.K3s.Custom { + const isCustom = true + const isRKE1 = false + const isRKE2 = false + + for _, cni := range v.CNIs { + testPackage := "provisioning/k3s" + runCommand := pipeline.WrapWithAdminRunCommand("TestCustomClusterK3SProvisioningTestSuite/TestProvisioningK3SCustomClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, k3sFileName, customFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.K3s.NodeProvider { + const isCustom = false + const isRKE1 = false + const isRKE2 = false + + for _, cni := range v.CNIs { + testPackage := "provisioning/k3s" + runCommand := pipeline.WrapWithAdminRunCommand("TestK3SProvisioningTestSuite/TestProvisioningK3SClusterDynamicInput") + newConfigName := config.NewConfigFileName(dirName, k3sFileName, nodeProviderFileName, v.Provider, cni, fmt.Sprint(i)) + err := NewRancherClusterConfiguration(v, newConfigName, isCustom, isRKE1, isRKE2, copiedConfig, cni, testPackage, runCommand, v.Tags, v.RunFlag) + if err != nil { + logrus.Info("error while generating a rancher cluster config", err) + continue + } + } + } + + for i, v := range clusters.Hosted { + var newConfigName file.Name + + switch v.Provider { + case provisioninginput.AWSProviderName.String(): + newConfigName = config.NewConfigFileName(dirName, v.Provider, eksFileName, fmt.Sprint(i)) + case provisioninginput.AzureProviderName.String(): + newConfigName = config.NewConfigFileName(dirName, v.Provider, aksFileName, fmt.Sprint(i)) + case provisioninginput.GoogleProviderName.String(): + newConfigName = config.NewConfigFileName(dirName, v.Provider, gkeFileName, fmt.Sprint(i)) + default: + continue + } + + newConfigName.NewFile(copiedConfig) + + newConfigName.SetEnvironmentKey(config.ConfigEnvironmentKey) + + pipeline.UpdateHostedKubernetesVField(v.Provider, v.KubernetesVersion) + + hostedTestPackage := "provisioning/hosted/" + + switch v.Provider { + case provisioninginput.AWSProviderName.String(): + config.LoadAndUpdateConfig(pipeline.TestCasesConfigKey, testCases, func() { + testCases.ProvisioningTestPackage = hostedTestPackage + "eks" + runCommand := "TestHostedEKSClusterProvisioningTestSuite/TestProvisioningHostedEKS" + testCases.ProvisioningTestCase = pipeline.WrapWithAdminRunCommand(runCommand) + }) + case provisioninginput.AzureProviderName.String(): + config.LoadAndUpdateConfig(pipeline.TestCasesConfigKey, testCases, func() { + testCases.ProvisioningTestPackage = hostedTestPackage + "aks" + runCommand := "TestHostedAKSClusterProvisioningTestSuite/TestProvisioningHostedAKS" + testCases.ProvisioningTestCase = pipeline.WrapWithAdminRunCommand(runCommand) + }) + case provisioninginput.GoogleProviderName.String(): + config.LoadAndUpdateConfig(pipeline.TestCasesConfigKey, testCases, func() { + testCases.ProvisioningTestPackage = hostedTestPackage + "gke" + runCommand := "TestHostedGKEClusterProvisioningTestSuite/TestProvisioningHostedGKE" + testCases.ProvisioningTestCase = pipeline.WrapWithAdminRunCommand(runCommand) + }) + default: + continue + } + + upgradeConfig := new(upgradeinput.Config) + config.LoadAndUpdateConfig(upgradeinput.ConfigurationFileKey, upgradeConfig, func() { + clusters := []upgradeinput.Cluster{ + { + VersionToUpgrade: v.KubernetesVersionToUpgrade, + FeaturesToTest: v.FeaturesToTest, + }, + } + upgradeConfig.Clusters = clusters + }) + } +} + +// NewRancherClusterConfiguration is a function that accepts single cluster from the cluster matrix. +// +// Writes a new configuration file with the original configuration's content and updates the new file's content with the given cluster values. +func NewRancherClusterConfiguration(cluster pipeline.RancherCluster, newConfigName file.Name, isCustom, isRKE1, isRKE2 bool, copiedConfig []byte, cni, provTestPackage, runCommand, tags, runFlag string) (err error) { + _, err = newConfigName.NewFile(copiedConfig) + if err != nil { + logrus.Info("error while writing populated config", err) + return err + } + + err = newConfigName.SetEnvironmentKey(config.ConfigEnvironmentKey) + if err != nil { + logrus.Info("error while setting new config as env var", err) + return err + } + + provisioningConfig := new(provisioninginput.Config) + config.LoadAndUpdateConfig(provisioninginput.ConfigurationFileKey, provisioningConfig, func() { + provisioningConfig.CNIs = []string{cni} + if isRKE1 { + provisioningConfig.RKE1KubernetesVersions = []string{cluster.KubernetesVersion} + } else if isRKE2 { + provisioningConfig.RKE2KubernetesVersions = []string{cluster.KubernetesVersion} + } else { + provisioningConfig.K3SKubernetesVersions = []string{cluster.KubernetesVersion} + } + }) + + testCases := new(pipeline.TestCases) + config.LoadAndUpdateConfig(pipeline.TestCasesConfigKey, testCases, func() { + testCases.ProvisioningTestPackage = provTestPackage + testCases.ProvisioningTestCase = runCommand + testCases.Tags = tags + }) + + pipeline.UpdateRancherDownstreamClusterFields(&cluster, isCustom, isRKE1) + + upgradeConfig := new(upgradeinput.Config) + config.LoadAndUpdateConfig(upgradeinput.ConfigurationFileKey, upgradeConfig, func() { + clusters := []upgradeinput.Cluster{ + { + VersionToUpgrade: cluster.KubernetesVersionToUpgrade, + FeaturesToTest: cluster.FeaturesToTest, + }, + } + upgradeConfig.Clusters = clusters + }) + + return +} + +// NewRancherLocalClusterConfiguration is a function that accepts single cluster from the cluster matrix's local field. +// +// Writes a new configuration file with the original configuration's content and updates the new file's content with the given cluster values. +func NewRancherLocalClusterConfiguration(cluster pipeline.RancherCluster, newConfigName file.Name, copiedConfig []byte) (err error) { + _, err = newConfigName.NewFile(copiedConfig) + if err != nil { + logrus.Info("error while writing populated config", err) + return err + } + + err = newConfigName.SetEnvironmentKey(config.ConfigEnvironmentKey) + if err != nil { + logrus.Info("error while setting new config as env var", err) + return err + } + + clusterID := "local" + upgradeConfig := new(upgradeinput.Config) + config.LoadAndUpdateConfig(upgradeinput.ConfigurationFileKey, upgradeConfig, func() { + clusters := []upgradeinput.Cluster{ + { + Name: clusterID, + VersionToUpgrade: cluster.KubernetesVersionToUpgrade, + FeaturesToTest: cluster.FeaturesToTest, + }, + } + upgradeConfig.Clusters = clusters + }) + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/releaseupgrade.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/releaseupgrade.sh new file mode 100755 index 0000000..4f981d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/releaseupgrade/releaseupgrade.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ + +echo "building release upgrade bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/pipeline/bin/releaseupgrade ./tests/v2/validation/pipeline/releaseupgrade + +echo "running release upgrade" +tests/v2/validation/pipeline/bin/releaseupgrade diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_corral_packages.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_corral_packages.sh new file mode 100755 index 0000000..9dd4a6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_corral_packages.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +cd /root/go/src/github.com/rancherlabs/corral-packages + +make init +make build diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_auto_testrun.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_auto_testrun.sh new file mode 100755 index 0000000..fc527ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_auto_testrun.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ + + echo "building qase auto testrun bin" + env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/testrun ./tests/v2/validation/pipeline/qase/testrun \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_reporter.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_reporter.sh new file mode 100755 index 0000000..738d28b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_qase_reporter.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ +if [[ -z "${QASE_TEST_RUN_ID}" ]]; then + echo "no test run ID is provided" +else + echo "building qase reporter bin" + env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/reporter ./tests/v2/validation/pipeline/qase/reporter +fi \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_rancherha_images.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_rancherha_images.sh new file mode 100755 index 0000000..bcf497f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/build_rancherha_images.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e +cd $(dirname $0)/../../../../../ + +echo "building rancher HA corral bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/registries/bin/rancherha ./tests/v2/validation/pipeline/rancherha + +echo "building rancher cleanup bin" +env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o tests/v2/validation/registries/bin/ranchercleanup ./tests/v2/validation/pipeline/ranchercleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/rancher_cleanup.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/rancher_cleanup.sh new file mode 100755 index 0000000..fd30088 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/rancher_cleanup.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -ex +cd $(dirname $0)/../../../../../ + +echo | corral config + +corral list + +echo "cleanup rancher" +tests/v2/validation/registries/bin/ranchercleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/setup_environment.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/setup_environment.sh new file mode 100755 index 0000000..de3cf1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/scripts/setup_environment.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -ex +cd $(dirname $0)/../../../../../ + +echo "build corral packages" +sh tests/v2/validation/pipeline/scripts/build_corral_packages.sh + +echo | corral config + +echo "build rancherHA images" +sh tests/v2/validation/pipeline/scripts/build_rancherha_images.sh + +corral list + +echo "running rancher corral" +tests/v2/validation/registries/bin/rancherha diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/slack/slack.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/slack/slack.go new file mode 100644 index 0000000..2330445 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/pipeline/slack/slack.go @@ -0,0 +1,126 @@ +package slack + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "strings" + + "github.com/rancher/norman/httperror" + "github.com/rancher/rancher/tests/v2/validation/pipeline/qase/testcase" +) + +var ( + slackWebhook = os.Getenv("SLACK_WEBHOOK") +) + +type Text struct { + Type string `json:"type"` + Text string `json:"text"` +} + +type Block struct { + Type string `json:"type"` + Text Text `json:"text"` + BlockID string `json:"block_id"` +} + +func setupTestSlackBlocks(testCaseSlice []*testcase.GoTestCase, runID int64, testRunName string) []Block { + var testSuite string + var blockSlice []Block + + titleBlock := Block{ + Type: "section", + Text: Text{ + Type: "mrkdwn", + Text: fmt.Sprintf("Failures: %s", testRunName), + }, + } + + blockSlice = append(blockSlice, titleBlock) + for _, testCase := range testCaseSlice { + combinedTestSuite := strings.Join(testCase.TestSuite, "/") + if combinedTestSuite != testSuite { + testSuite = combinedTestSuite + testSuiteBlock := Block{ + Type: "section", + Text: Text{ + Type: "mrkdwn", + Text: fmt.Sprintf("TestSuite: %s", testSuite), + }, + } + blockSlice = append(blockSlice, testSuiteBlock) + } + + testCaseBlock := Block{ + Type: "section", + Text: Text{ + Type: "mrkdwn", + Text: fmt.Sprintf(":Failed\n", runID, testCase.Name), + }, + } + blockSlice = append(blockSlice, testCaseBlock) + + } + return blockSlice +} + +// PostSlackMesasge is a function that posts the end to end validation results to our specified slack channel +func PostSlackMessage(testCaseSlice []*testcase.GoTestCase, runID int64, testRunName string) error { + slackBlocks := setupTestSlackBlocks(testCaseSlice, runID, testRunName) + + bodyContent, err := json.Marshal(struct { + Text string `json:"text"` + Blocks []Block `json:"blocks"` + }{ + Text: "Recurring Runs Failures", + Blocks: slackBlocks, + }) + + if err != nil { + return fmt.Errorf("error with marshal slack message: %v", err) + } + + err = postAction(slackWebhook, bodyContent) + if err != nil { + return fmt.Errorf("error with slack message post: %v", err) + } + + return nil +} + +func postAction(url string, body []byte) error { + req, err := http.NewRequest("POST", url, bytes.NewBuffer(body)) + if err != nil { + return err + } + + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + + req.Header.Set("Content-Type", "application/json") + + resp, err := client.Do(req) + if err != nil { + return err + } + + defer resp.Body.Close() + + if resp.StatusCode >= 300 { + return httperror.NewAPIErrorLong(resp.StatusCode, resp.Status, url) + } + + _, err = io.ReadAll(resp.Body) + if err != nil { + return err + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/README.md new file mode 100644 index 0000000..f857ed8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/README.md @@ -0,0 +1,22 @@ +# Prime Configs + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +Your GO suite should be set to `-run ^TestPrimeTestSuite$`. You can find any additional suite name(s) by checking the test file you plan to run. + +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + ... +prime: + brand: "" + isPrime: false #boolean, default is false + rancherVersion: "" + registry: " +``` + +if isPrime is `true`, we will also check that the ui-brand is correctly set. For the `TestPrimeVersion` test case, your Rancher URL that is passed must use a secure certificate. If an insecure certificate is recognized, then the test will fail; this is expected. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/prime_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/prime_test.go new file mode 100644 index 0000000..12b378b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/prime/prime_test.go @@ -0,0 +1,88 @@ +//go:build validation + +package prime + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + prime "github.com/rancher/shepherd/extensions/prime" + "github.com/rancher/shepherd/extensions/rancherversion" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + systemRegistry = "system-default-registry" + localCluster = "local" + uiBrand = "ui-brand" +) + +type PrimeTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + brand string + isPrime bool + rancherVersion string + primeRegistry string +} + +func (t *PrimeTestSuite) TearDownSuite() { + t.session.Cleanup() +} + +func (t *PrimeTestSuite) SetupSuite() { + testSession := session.NewSession() + t.session = testSession + + primeConfig := new(rancherversion.Config) + config.LoadConfig(rancherversion.ConfigurationFileKey, primeConfig) + + t.brand = primeConfig.Brand + t.isPrime = primeConfig.IsPrime + t.rancherVersion = primeConfig.RancherVersion + t.primeRegistry = primeConfig.Registry + + client, err := rancher.NewClient("", t.session) + assert.NoError(t.T(), err) + + t.client = client +} + +func (t *PrimeTestSuite) TestPrimeUIBrand() { + rancherBrand, err := t.client.Management.Setting.ByID(uiBrand) + require.NoError(t.T(), err) + + checkBrand := prime.CheckUIBrand(t.client, t.isPrime, rancherBrand, t.brand) + assert.NoError(t.T(), checkBrand) +} + +func (t *PrimeTestSuite) TestPrimeVersion() { + serverConfig, err := rancherversion.RequestRancherVersion(t.client.RancherConfig.Host) + require.NoError(t.T(), err) + + checkVersion := prime.CheckVersion(t.isPrime, t.rancherVersion, serverConfig) + assert.NoError(t.T(), checkVersion) +} + +func (t *PrimeTestSuite) TestSystemDefaultRegistry() { + registry, err := t.client.Management.Setting.ByID(systemRegistry) + require.NoError(t.T(), err) + + checkRegistry := prime.CheckSystemDefaultRegistry(t.isPrime, t.primeRegistry, registry) + assert.NoError(t.T(), checkRegistry) +} + +func (t *PrimeTestSuite) TestLocalClusterRancherImages() { + podErrors := pods.StatusPods(t.client, localCluster) + assert.Empty(t.T(), podErrors) +} + +func TestPrimeTestSuite(t *testing.T) { + suite.Run(t, new(PrimeTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/README.md new file mode 100644 index 0000000..9f9a6d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/README.md @@ -0,0 +1,20 @@ +# Projects + +## Pre-requisites + +- Ensure you have an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, create one first before running this test. + +## Test Setup + +Your GO suite should be set to `-run ^Test$`. For example to run the projects_test.go, set the GO suite to `-run ^TestProjectsTestSuite$` You can find specific tests by checking the test file you plan to run. + +In your config file, set the following: + +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True #optional + cleanup: True #optional + clusterName: "downstream_cluster_name" +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects.go new file mode 100644 index 0000000..e7559d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects.go @@ -0,0 +1,112 @@ +package projects + +import ( + "errors" + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + "github.com/rancher/shepherd/extensions/kubeapi/projects" + rbacapi "github.com/rancher/shepherd/extensions/kubeapi/rbac" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + dummyFinalizer = "example.com/dummy" + systemProjectLabel = "authz.management.cattle.io/system-project" + resourceQuotaAnnotation = "field.cattle.io/resourceQuota" +) + +var prtb = v3.ProjectRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + Namespace: "", + }, + ProjectName: "", + RoleTemplateName: "", + UserPrincipalName: "", +} + +func createProjectAndNamespace(client *rancher.Client, clusterID string, project *v3.Project) (*v3.Project, *corev1.Namespace, error) { + createdProject, err := client.WranglerContext.Mgmt.Project().Create(project) + if err != nil { + return nil, nil, err + } + + namespaceName := namegen.AppendRandomString("testns-") + createdNamespace, err := namespaces.CreateNamespace(client, clusterID, createdProject.Name, namespaceName, "", map[string]string{}, map[string]string{}) + if err != nil { + return nil, nil, err + } + + return createdProject, createdNamespace, nil +} + +func checkAnnotationExistsInNamespace(client *rancher.Client, clusterID string, namespaceName string, annotationKey string, expectedExistence bool) error { + updatedNamespace, err := namespaces.GetNamespaceByName(client, clusterID, namespaceName) + if err != nil { + return err + } + + _, exists := updatedNamespace.Annotations[annotationKey] + if (expectedExistence && !exists) || (!expectedExistence && exists) { + errorMessage := fmt.Sprintf("Annotation '%s' should%s exist", annotationKey, map[bool]string{true: "", false: " not"}[expectedExistence]) + return errors.New(errorMessage) + } + + return nil +} + +func checkNamespaceLabelsAndAnnotations(clusterID string, projectName string, namespace *corev1.Namespace) error { + var errorMessages []string + expectedLabels := map[string]string{ + projects.ProjectIDAnnotation: projectName, + } + + expectedAnnotations := map[string]string{ + projects.ProjectIDAnnotation: clusterID + ":" + projectName, + } + + for key, value := range expectedLabels { + if _, ok := namespace.Labels[key]; !ok { + errorMessages = append(errorMessages, fmt.Sprintf("expected label %s not present in namespace labels", key)) + } else if namespace.Labels[key] != value { + errorMessages = append(errorMessages, fmt.Sprintf("label value mismatch for %s: expected %s, got %s", key, value, namespace.Labels[key])) + } + } + + for key, value := range expectedAnnotations { + if _, ok := namespace.Annotations[key]; !ok { + errorMessages = append(errorMessages, fmt.Sprintf("expected annotation %s not present in namespace annotations", key)) + } else if namespace.Annotations[key] != value { + errorMessages = append(errorMessages, fmt.Sprintf("annotation value mismatch for %s: expected %s, got %s", key, value, namespace.Annotations[key])) + } + } + + if len(errorMessages) > 0 { + return fmt.Errorf(strings.Join(errorMessages, "\n")) + } + + return nil +} + +func createProjectRoleTemplateBinding(client *rancher.Client, user *management.User, project *v3.Project, projectRole string) (*v3.ProjectRoleTemplateBinding, error) { + projectName := fmt.Sprintf("%s:%s", project.Namespace, project.Name) + prtb.Name = namegen.AppendRandomString("prtb-") + prtb.Namespace = project.Name + prtb.ProjectName = projectName + prtb.RoleTemplateName = projectRole + prtb.UserPrincipalName = user.PrincipalIDs[0] + + createdProjectRoleTemplateBinding, err := rbacapi.CreateProjectRoleTemplateBinding(client, &prtb) + if err != nil { + return nil, err + } + + return createdProjectRoleTemplateBinding, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects_test.go new file mode 100644 index 0000000..eaf16b2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/projects_test.go @@ -0,0 +1,315 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package projects + +import ( + "fmt" + "testing" + + project "github.com/rancher/rancher/tests/v2/actions/projects" + rbac "github.com/rancher/rancher/tests/v2/actions/rbac" + deployment "github.com/rancher/rancher/tests/v2/actions/workloads/deployment" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + "github.com/rancher/shepherd/extensions/kubeapi/projects" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ProjectsTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (pr *ProjectsTestSuite) TearDownSuite() { + pr.session.Cleanup() +} + +func (pr *ProjectsTestSuite) SetupSuite() { + pr.session = session.NewSession() + + client, err := rancher.NewClient("", pr.session) + require.NoError(pr.T(), err) + + pr.client = client + + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(pr.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(pr.client, clusterName) + require.NoError(pr.T(), err, "Error getting cluster ID") + pr.cluster, err = pr.client.Management.Cluster.ByID(clusterID) + require.NoError(pr.T(), err) +} + +func (pr *ProjectsTestSuite) TestProjectsCrudLocalCluster() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a project in the local cluster and verify that the project can be listed.") + projectTemplate := projects.NewProjectTemplate(projects.LocalCluster) + createdProject, err := pr.client.WranglerContext.Mgmt.Project().Create(projectTemplate) + require.NoError(pr.T(), err, "Failed to create project") + err = project.WaitForProjectFinalizerToUpdate(pr.client, createdProject.Name, createdProject.Namespace, 2) + require.NoError(pr.T(), err) + projectList, err := projects.ListProjects(pr.client, createdProject.Namespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdProject.Name, + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 1, len(projectList.Items), "Expected exactly one project.") + + log.Info("Verify that the project can be updated by adding a label.") + currentProject := projectList.Items[0] + if currentProject.Labels == nil { + currentProject.Labels = make(map[string]string) + } + currentProject.Labels["hello"] = "world" + _, err = pr.client.WranglerContext.Mgmt.Project().Update(¤tProject) + require.NoError(pr.T(), err, "Failed to update project.") + + updatedProjectList, err := projects.ListProjects(pr.client, createdProject.Namespace, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", "hello", "world"), + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 1, len(updatedProjectList.Items), "Expected one project in the list") + + log.Info("Delete the project.") + err = projects.DeleteProject(pr.client, createdProject.Namespace, createdProject.Name) + require.NoError(pr.T(), err, "Failed to delete project") + projectList, err = projects.ListProjects(pr.client, createdProject.Namespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdProject.Name, + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 0, len(projectList.Items), "Expected zero project.") +} + +func (pr *ProjectsTestSuite) TestProjectsCrudDownstreamCluster() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user and add the user to the downstream cluster as cluster owner.") + _, standardUserClient, err := rbac.AddUserWithRoleToCluster(pr.client, rbac.StandardUser.String(), rbac.ClusterOwner.String(), pr.cluster, nil) + require.NoError(pr.T(), err) + + log.Info("Create a project in the downstream cluster and verify that the project can be listed.") + projectTemplate := projects.NewProjectTemplate(pr.cluster.ID) + createdProject, err := standardUserClient.WranglerContext.Mgmt.Project().Create(projectTemplate) + require.NoError(pr.T(), err, "Failed to create project") + err = project.WaitForProjectFinalizerToUpdate(standardUserClient, createdProject.Name, createdProject.Namespace, 2) + require.NoError(pr.T(), err) + projectList, err := projects.ListProjects(standardUserClient, createdProject.Namespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdProject.Name, + }) + require.NoError(pr.T(), err, "Failed to list project.") + require.Equal(pr.T(), 1, len(projectList.Items), "Expected exactly one project.") + + log.Info("Verify that the project can be updated by adding a label.") + currentProject := projectList.Items[0] + if currentProject.Labels == nil { + currentProject.Labels = make(map[string]string) + } + currentProject.Labels["hello"] = "world" + _, err = standardUserClient.WranglerContext.Mgmt.Project().Update(¤tProject) + require.NoError(pr.T(), err, "Failed to update project.") + + updatedProjectList, err := projects.ListProjects(standardUserClient, createdProject.Namespace, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", "hello", "world"), + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 1, len(updatedProjectList.Items), "Expected one project in the list") + + log.Info("Delete the project.") + err = projects.DeleteProject(standardUserClient, createdProject.Namespace, createdProject.Name) + require.NoError(pr.T(), err, "Failed to delete project") + projectList, err = projects.ListProjects(standardUserClient, createdProject.Namespace, metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdProject.Name, + }) + require.NoError(pr.T(), err, "Failed to list project.") + require.Equal(pr.T(), 0, len(projectList.Items), "Expected zero project.") +} + +func (pr *ProjectsTestSuite) TestDeleteSystemProject() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Delete the System Project in the local cluster.") + projectList, err := projects.ListProjects(pr.client, projects.LocalCluster, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", systemProjectLabel, "true"), + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 1, len(projectList.Items), "Expected one project in the list") + + systemProjectName := projectList.Items[0].ObjectMeta.Name + err = projects.DeleteProject(pr.client, projects.LocalCluster, systemProjectName) + require.Error(pr.T(), err, "Failed to delete project") + expectedErrorMessage := "admission webhook \"rancher.cattle.io.projects.management.cattle.io\" denied the request: System Project cannot be deleted" + require.Equal(pr.T(), expectedErrorMessage, err.Error()) + + log.Info("Delete the System Project in the downstream cluster.") + projectList, err = projects.ListProjects(pr.client, pr.cluster.ID, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("%s=%s", systemProjectLabel, "true"), + }) + require.NoError(pr.T(), err) + require.Equal(pr.T(), 1, len(projectList.Items), "Expected one project in the list") + + systemProjectName = projectList.Items[0].ObjectMeta.Name + err = projects.DeleteProject(pr.client, pr.cluster.ID, systemProjectName) + require.Error(pr.T(), err, "Failed to delete project") + expectedErrorMessage = "admission webhook \"rancher.cattle.io.projects.management.cattle.io\" denied the request: System Project cannot be deleted" + require.Equal(pr.T(), expectedErrorMessage, err.Error()) +} + +func (pr *ProjectsTestSuite) TestProjectWithoutResourceQuota() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user and add the user to the downstream cluster as cluster owner.") + _, standardUserClient, err := rbac.AddUserWithRoleToCluster(pr.client, rbac.StandardUser.String(), rbac.ClusterOwner.String(), pr.cluster, nil) + require.NoError(pr.T(), err) + + log.Info("Create a project (without any resource quota) and a namespace in the project.") + projectTemplate := projects.NewProjectTemplate(pr.cluster.ID) + createdProject, createdNamespace, err := createProjectAndNamespace(standardUserClient, pr.cluster.ID, projectTemplate) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace has the label and annotation referencing the project.") + updatedNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, createdNamespace.Name) + require.NoError(pr.T(), err) + err = checkNamespaceLabelsAndAnnotations(pr.cluster.ID, createdProject.Name, updatedNamespace) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace does not have the annotation: field.cattle.io/resourceQuota.") + err = checkAnnotationExistsInNamespace(standardUserClient, pr.cluster.ID, updatedNamespace.Name, resourceQuotaAnnotation, false) + require.NoError(pr.T(), err, "'field.cattle.io/resourceQuota' annotation should not exist") + + log.Info("Create a deployment in the namespace with ten replicas.") + deployment, err := deployment.CreateDeployment(standardUserClient, pr.cluster.ID, updatedNamespace.Name, 10, "", "", false, false) + require.NoError(pr.T(), err, "Failed to create deployment in the namespace") + + log.Info("Verify that there are ten pods created in the deployment and they are in Running state.") + err = charts.WatchAndWaitDeployments(standardUserClient, pr.cluster.ID, updatedNamespace.Name, metav1.ListOptions{ + FieldSelector: "metadata.name=" + deployment.Name, + }) + require.NoError(pr.T(), err) +} + +func (pr *ProjectsTestSuite) TestMoveNamespaceOutOfProject() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user and add the user to the downstream cluster as cluster owner.") + _, standardUserClient, err := rbac.AddUserWithRoleToCluster(pr.client, rbac.StandardUser.String(), rbac.ClusterOwner.String(), pr.cluster, nil) + require.NoError(pr.T(), err) + + log.Info("Create a project in the downstream cluster and a namespace in the project.") + projectTemplate := projects.NewProjectTemplate(pr.cluster.ID) + createdProject, createdNamespace, err := createProjectAndNamespace(standardUserClient, pr.cluster.ID, projectTemplate) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace has the label and annotation referencing the project.") + updatedNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, createdNamespace.Name) + require.NoError(pr.T(), err) + err = checkNamespaceLabelsAndAnnotations(pr.cluster.ID, createdProject.Name, updatedNamespace) + require.NoError(pr.T(), err) + + log.Info("Move the namespace out of the project.") + delete(updatedNamespace.Labels, projects.ProjectIDAnnotation) + delete(updatedNamespace.Annotations, projects.ProjectIDAnnotation) + + downstreamContext, err := pr.client.WranglerContext.DownStreamClusterWranglerContext(pr.cluster.ID) + require.NoError(pr.T(), err) + + currentNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, updatedNamespace.Name) + require.NoError(pr.T(), err) + updatedNamespace.ResourceVersion = currentNamespace.ResourceVersion + _, err = downstreamContext.Core.Namespace().Update(updatedNamespace) + require.NoError(pr.T(), err, "Failed to move the namespace out of the project") + + log.Info("Verify that the namespace does not have the label and annotation referencing the project.") + movedNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, updatedNamespace.Name) + require.NoError(pr.T(), err) + err = checkNamespaceLabelsAndAnnotations(pr.cluster.ID, createdProject.Name, movedNamespace) + require.Error(pr.T(), err) +} + +func (pr *ProjectsTestSuite) TestMoveNamespaceBetweenProjectsWithNoResourceQuota() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user and add the user to the downstream cluster as cluster owner.") + _, standardUserClient, err := rbac.AddUserWithRoleToCluster(pr.client, rbac.StandardUser.String(), rbac.ClusterOwner.String(), pr.cluster, nil) + require.NoError(pr.T(), err) + + log.Info("Create a project in the downstream cluster and a namespace in the project.") + projectTemplate := projects.NewProjectTemplate(pr.cluster.ID) + projectTemplate.Spec.NamespaceDefaultResourceQuota.Limit.Pods = "" + projectTemplate.Spec.ResourceQuota.Limit.Pods = "" + createdProject, createdNamespace, err := createProjectAndNamespace(standardUserClient, pr.cluster.ID, projectTemplate) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace has the label and annotation referencing the project.") + updatedNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, createdNamespace.Name) + require.NoError(pr.T(), err) + err = checkNamespaceLabelsAndAnnotations(pr.cluster.ID, createdProject.Name, updatedNamespace) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace does not have the annotation: field.cattle.io/resourceQuota.") + err = checkAnnotationExistsInNamespace(standardUserClient, pr.cluster.ID, updatedNamespace.Name, resourceQuotaAnnotation, false) + require.NoError(pr.T(), err, "'field.cattle.io/resourceQuota' annotation should not exist") + + log.Info("Create a deployment in the namespace with ten replicas.") + deployment, err := deployment.CreateDeployment(standardUserClient, createdProject.Namespace, updatedNamespace.Name, 10, "", "", false, false) + require.NoError(pr.T(), err, "Failed to create deployment in the namespace") + + log.Info("Verify that there are ten pods created in the deployment and they are in Running state.") + err = charts.WatchAndWaitDeployments(standardUserClient, createdProject.Namespace, updatedNamespace.Name, metav1.ListOptions{ + FieldSelector: "metadata.name=" + deployment.Name, + }) + require.NoError(pr.T(), err) + + log.Info("Create another project in the downstream cluster.") + projectTemplate = projects.NewProjectTemplate(pr.cluster.ID) + createdProject2, err := standardUserClient.WranglerContext.Mgmt.Project().Create(projectTemplate) + require.NoError(pr.T(), err, "Failed to create project") + err = project.WaitForProjectFinalizerToUpdate(pr.client, createdProject2.Name, createdProject2.Namespace, 2) + require.NoError(pr.T(), err) + + log.Info("Move the namespace from the first project to the second project.") + currentNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, updatedNamespace.Name) + require.NoError(pr.T(), err) + downstreamContext, err := pr.client.WranglerContext.DownStreamClusterWranglerContext(pr.cluster.ID) + require.NoError(pr.T(), err) + + updatedNamespace.Annotations[projects.ProjectIDAnnotation] = createdProject2.Namespace + ":" + createdProject2.Name + updatedNamespace.ResourceVersion = currentNamespace.ResourceVersion + _, err = downstreamContext.Core.Namespace().Update(updatedNamespace) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace has the correct label and annotation referencing the second project.") + movedNamespace, err := namespaces.GetNamespaceByName(standardUserClient, pr.cluster.ID, updatedNamespace.Name) + require.NoError(pr.T(), err) + err = checkNamespaceLabelsAndAnnotations(pr.cluster.ID, createdProject2.Name, movedNamespace) + require.NoError(pr.T(), err) + + log.Info("Verify that the namespace does not have the annotation: field.cattle.io/resourceQuota.") + err = checkAnnotationExistsInNamespace(standardUserClient, pr.cluster.ID, updatedNamespace.Name, resourceQuotaAnnotation, false) + require.NoError(pr.T(), err, "'field.cattle.io/resourceQuota' annotation should not exist") + + log.Info("Verify that the deployment is in Active state and all pods in the deployment are in Running state.") + err = charts.WatchAndWaitDeployments(standardUserClient, pr.cluster.ID, movedNamespace.Name, metav1.ListOptions{ + FieldSelector: "metadata.name=" + deployment.Name, + }) + require.NoError(pr.T(), err) +} + +func TestProjectsTestSuite(t *testing.T) { + suite.Run(t, new(ProjectsTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/rbac_terminating_project_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/rbac_terminating_project_test.go new file mode 100644 index 0000000..1879fd6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/projects/rbac_terminating_project_test.go @@ -0,0 +1,155 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package projects + +import ( + "fmt" + "regexp" + "testing" + "time" + + project "github.com/rancher/rancher/tests/v2/actions/projects" + rbac "github.com/rancher/rancher/tests/v2/actions/rbac" + pod "github.com/rancher/rancher/tests/v2/actions/workloads/pods" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubeapi/projects" + projectsApi "github.com/rancher/shepherd/extensions/kubeapi/projects" + "github.com/rancher/shepherd/extensions/rancherleader" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RbacTerminatingProjectTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (rtp *RbacTerminatingProjectTestSuite) TearDownSuite() { + rtp.session.Cleanup() +} + +func (rtp *RbacTerminatingProjectTestSuite) SetupSuite() { + rtp.session = session.NewSession() + + client, err := rancher.NewClient("", rtp.session) + require.NoError(rtp.T(), err) + + rtp.client = client + + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(rtp.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(rtp.client, clusterName) + require.NoError(rtp.T(), err, "Error getting cluster ID") + rtp.cluster, err = rtp.client.Management.Cluster.ByID(clusterID) + require.NoError(rtp.T(), err) +} + +func (rtp *RbacTerminatingProjectTestSuite) TestUserAdditionToClusterWithTerminatingProjectNamespace() { + subSession := rtp.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user.") + createdUser, err := users.CreateUserWithRole(rtp.client, users.UserConfig(), projectsApi.StandardUser) + require.NoError(rtp.T(), err) + rtp.T().Logf("Created user: %v", createdUser.Username) + + log.Info("Create a project in the downstream cluster.") + projectTemplate := projects.NewProjectTemplate(rtp.cluster.ID) + createdProject, err := rtp.client.WranglerContext.Mgmt.Project().Create(projectTemplate) + require.NoError(rtp.T(), err) + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 2) + require.NoError(rtp.T(), err) + + logCaptureStartTime := time.Now() + log.Info("Simulate a project stuck in terminating state by adding a finalizer to the project.") + finalizer := append([]string{dummyFinalizer}, createdProject.Finalizers...) + updatedProject, err := project.UpdateProjectNamespaceFinalizer(rtp.client, createdProject, finalizer) + require.NoError(rtp.T(), err, "Failed to update finalizer.") + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 3) + require.NoError(rtp.T(), err) + + log.Info("Delete the Project.") + err = projectsApi.DeleteProject(rtp.client, createdProject.Namespace, createdProject.Name) + require.Error(rtp.T(), err) + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 1) + require.NoError(rtp.T(), err) + leaderPodName, err := rancherleader.GetRancherLeaderPodName(rtp.client) + require.NoError(rtp.T(), err) + errorRegex := `\[INFO\] \[mgmt-project-rbac-remove\] Deleting namespace ` + regexp.QuoteMeta(createdProject.Name) + err = pod.CheckPodLogsForErrors(rtp.client, projectsApi.LocalCluster, leaderPodName, projectsApi.RancherNamespace, errorRegex, logCaptureStartTime) + require.Error(rtp.T(), err) + + logCaptureStartTime = time.Now() + log.Info("Add the standard user to the downstream cluster as cluster owner.") + err = users.AddClusterRoleToUser(rtp.client, rtp.cluster, createdUser, rbac.ClusterOwner.String(), nil) + require.NoError(rtp.T(), err) + + log.Info("Verify that there are no errors in the Rancher logs related to role binding.") + errorRegex = `\[ERROR\] error syncing '(.*?)': handler mgmt-auth-crtb-controller: .*? (?:not found|is forbidden), requeuing` + err = pod.CheckPodLogsForErrors(rtp.client, projectsApi.LocalCluster, leaderPodName, projectsApi.RancherNamespace, errorRegex, logCaptureStartTime) + require.NoError(rtp.T(), err) + + logCaptureStartTime = time.Now() + log.Info("Remove the finalizer that was previously added to the project.") + finalizer = nil + _, err = project.UpdateProjectNamespaceFinalizer(rtp.client, updatedProject, finalizer) + require.NoError(rtp.T(), err, "Failed to remove the finalizer.") + + log.Info("Verify that there are no errors in the Rancher logs related to role binding.") + err = pod.CheckPodLogsForErrors(rtp.client, projectsApi.LocalCluster, leaderPodName, projectsApi.RancherNamespace, errorRegex, logCaptureStartTime) + require.NoError(rtp.T(), err) +} + +func (rtp *RbacTerminatingProjectTestSuite) TestUserAdditionToProjectWithTerminatingProjectNamespace() { + subSession := rtp.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a standard user.") + createdUser, err := users.CreateUserWithRole(rtp.client, users.UserConfig(), projectsApi.StandardUser) + require.NoError(rtp.T(), err) + rtp.T().Logf("Created user: %v", createdUser.Username) + + log.Info("Create a project in the downstream cluster.") + projectTemplate := projects.NewProjectTemplate(rtp.cluster.ID) + createdProject, err := rtp.client.WranglerContext.Mgmt.Project().Create(projectTemplate) + require.NoError(rtp.T(), err) + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 2) + require.NoError(rtp.T(), err) + + log.Info("Simulate a project stuck in terminating state by adding a finalizer to the project.") + finalizer := append([]string{dummyFinalizer}, createdProject.Finalizers...) + updatedProject, err := project.UpdateProjectNamespaceFinalizer(rtp.client, createdProject, finalizer) + require.NoError(rtp.T(), err, "Failed to update finalizer.") + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 3) + require.NoError(rtp.T(), err) + + log.Info("Delete the Project.") + err = projectsApi.DeleteProject(rtp.client, createdProject.Namespace, createdProject.Name) + require.Error(rtp.T(), err) + err = project.WaitForProjectFinalizerToUpdate(rtp.client, createdProject.Name, createdProject.Namespace, 1) + require.NoError(rtp.T(), err) + + log.Info("Add the standard user to the project as project owner.") + _, err = createProjectRoleTemplateBinding(rtp.client, createdUser, createdProject, rbac.ProjectOwner.String()) + require.Error(rtp.T(), err) + prtbNamePlaceholder := `[^"]+` + regexPattern := fmt.Sprintf(`projectroletemplatebindings\.management\.cattle\.io "%s" is forbidden: unable to create new content in namespace %s because it is being terminated`, prtbNamePlaceholder, regexp.QuoteMeta(createdProject.Name)) + expectedErrorMessage := regexp.MustCompile(regexPattern) + require.Regexp(rtp.T(), expectedErrorMessage, err.Error()) + + log.Info("Remove the finalizer that was previously added to the project.") + finalizer = nil + _, err = project.UpdateProjectNamespaceFinalizer(rtp.client, updatedProject, finalizer) + require.NoError(rtp.T(), err, "Failed to remove the finalizer.") +} + +func TestRbacTerminatingProjectTestSuite(t *testing.T) { + suite.Run(t, new(RbacTerminatingProjectTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/README.md new file mode 100644 index 0000000..6f68f80 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/README.md @@ -0,0 +1,26 @@ +# Provisioning Configs + +## Table of Contents +1. [Getting Started](#Getting-Started) +2. [Cluster Type READMEs](#Cluster-Type-READMEs) + +## Getting Started +Your GO suite should be set to `-run ^TestProvisioningTestSuite$`. You can find the correct suite name in the below README links, or by checking the test file you plan to run. +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + cleanup: false + insecure: true/optional + cleanup: false/optional +``` + +## Cluster Type READMEs + +From there, your config should contain the tests you want to run (provisioningInput), tokens and configuration for the provider(s) you will use, and any additional tests that you may want to run. Please use one of the following links to continue adding to your config for provisioning tests: + +1. [RKE1 Provisioning](rke1/README.md) +2. [RKE2 Provisioning](rke2/README.md) +3. [K3s Provisioning](k3s/README.md) +4. [Hosted Provider Provisioning](hosted/README.md) \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/README.md new file mode 100644 index 0000000..5830b67 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/README.md @@ -0,0 +1,48 @@ +# Standalone Configs - Corral + +## Getting Started +You should have a basic understanding of Corral before running these tests. In order to run the entire airgap package set the package to `airgap/...` Your GO suite should be set to blank. +In your config file, set the following: +```yaml +corralRancherHA: + name: rancherha # this is the name of your aigap corral package if it hasn't been created beforehand +provisioningInput: + cni: + - calico + # For the kubernetes versions please set it to what is appropriate for that release check + k3sKubernetesVersion: + - v1.23 + - v1.24 + - v1.25 + rke1KubernetesVersion: + - v1.23 + - v1.24 + - v1.25 + rke2KubernetesVersion: + - v1.25 + - v1.24 + - v1.23 +registries: + existingNoAuthRegistry: # only set this if the registry was created beforehand just do `corral vars registry_fqdn` to get the registry hostname +corralPackages: + corralPackageImages: + airgapCustomCluster: dist/aws-rancher-custom-cluster-true + rancherHA: dist/aws-aws-registry-standalone-rke2-rancher-airgap-calico-true-2.15.1-1.8.0 # the name of the corral rancher is configurable with config entry above + ... + hasDebug: + hasCleanup: + hasSetCorralSSHKeys: # If you are creating the airgap rancher instance in the same test run, please set this to true so then the air gap cluster can communicate with the rancher instance. If the rancher instance was created beforehand this boolean is ignored. +corralConfigs: + corralConfigUser: + corralConfigVars: + : # for now only aws is supported, so use the appropriate aws vars + bastion_ip: # if the air gap rancher instance is created beforehand (not in the same job) set this to the registry public IP, otherwise it is automatically done in the job. + corral_private_key: # only set this if you have created the airgap rancher instance beforehand. By doing `corral vars corral_private_key` + corral_public_key: # only set this if you have created the airgap rancher instance beforehand. By doing `corral vars corral_private_key` + registry_cert: # cert for the registry + registry_key: # key for the registry + ... + corralSSHPath: +``` +Note: `corralConfigUser` will be the prefix for all resources created in your provider. +From there, your `corralConfigVars` should contain the parameters necessary to run the test. You can see what variables need to be set by navigating to your corral package folder and checking the `manifest.yaml` variables. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/airgap.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/airgap.go new file mode 100644 index 0000000..22d0d92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/airgap.go @@ -0,0 +1,9 @@ +package airgap + +const ( + corralPackageAirgapCustomClusterName = "airgapCustomCluster" + corralBastionIP = "bastion_ip" + corralRegistryIP = "registry_ip" + corralRegistryFQDN = "registry_fqdn" + logMessageKubernetesVersion = "Validating the current version is the upgraded one" +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/k3s_custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/k3s_custom_cluster_test.go new file mode 100644 index 0000000..be726da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/k3s_custom_cluster_test.go @@ -0,0 +1,130 @@ +//go:build validation + +package airgap + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/pipeline/rancherha/corralha" + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/rancher/tests/v2/validation/provisioning/registries" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + provisioning "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type AirGapK3SCustomClusterTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + corralPackage *corral.Packages + clustersConfig *provisioninginput.Config + registryFQDN string +} + +func (a *AirGapK3SCustomClusterTestSuite) TearDownSuite() { + a.session.Cleanup() +} + +func (a *AirGapK3SCustomClusterTestSuite) SetupSuite() { + testSession := session.NewSession() + a.session = testSession + + a.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, a.clustersConfig) + + corralRancherHA := new(corralha.CorralRancherHA) + config.LoadConfig(corralha.CorralRancherHAConfigConfigurationFileKey, corralRancherHA) + + registriesConfig := new(registries.Registries) + config.LoadConfig(registries.RegistriesConfigKey, registriesConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(a.T(), err) + + a.client = client + listOfCorrals, err := corral.ListCorral() + require.NoError(a.T(), err) + + corralConfig := corral.Configurations() + + err = corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(a.T(), err) + + a.corralPackage = corral.PackagesConfig() + + _, corralExist := listOfCorrals[corralRancherHA.Name] + if corralExist { + bastionIP, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryIP) + require.NoError(a.T(), err) + + err = corral.UpdateCorralConfig(corralBastionIP, bastionIP) + require.NoError(a.T(), err) + + registryFQDN, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryFQDN) + require.NoError(a.T(), err) + logrus.Infof("registry fqdn is %s", registryFQDN) + + err = corral.SetCorralSSHKeys(corralRancherHA.Name) + require.NoError(a.T(), err) + a.registryFQDN = registryFQDN + } else { + a.registryFQDN = registriesConfig.ExistingNoAuthRegistryURL + } +} + +func (a *AirGapK3SCustomClusterTestSuite) TestProvisioningAirGapK3SCustomCluster() { + a.clustersConfig.MachinePools = []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String() + "-" + permutations.K3SAirgapCluster + "-", a.client}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&a.Suite, tt.name, tt.client, a.clustersConfig, permutations.K3SAirgapCluster, nil, a.corralPackage) + } + +} + +func (a *AirGapK3SCustomClusterTestSuite) TestProvisioningUpgradeAirGapK3SCustomCluster() { + a.clustersConfig.MachinePools = []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + + k3sVersions, err := kubernetesversions.ListK3SAllVersions(a.client) + require.NoError(a.T(), err) + + numOfK3SVersions := len(k3sVersions) + require.Equal(a.T(), len(a.clustersConfig.CNIs), 1) + + a.clustersConfig.K3SKubernetesVersions[0] = k3sVersions[numOfK3SVersions-2] + testConfig := clusters.ConvertConfigToClusterConfig(a.clustersConfig) + testConfig.KubernetesVersion = a.clustersConfig.K3SKubernetesVersions[0] + testConfig.CNI = a.clustersConfig.CNIs[0] + clusterObject, err := provisioning.CreateProvisioningAirgapCustomCluster(a.client, testConfig, a.corralPackage) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyCluster(a.T(), a.client, testConfig, clusterObject) + + upgradedCluster, err := provisioning.UpgradeClusterK8sVersion(a.client, &clusterObject.Name, &k3sVersions[numOfK3SVersions-1]) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyUpgrade(a.T(), upgradedCluster, k3sVersions[numOfK3SVersions-1]) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestAirGapCustomClusterK3SProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(AirGapK3SCustomClusterTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke1_custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke1_custom_cluster_test.go new file mode 100644 index 0000000..dec3cc8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke1_custom_cluster_test.go @@ -0,0 +1,133 @@ +//go:build validation + +package airgap + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/pipeline/rancherha/corralha" + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/rancher/tests/v2/validation/provisioning/registries" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + provisioning "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type AirGapRKE1CustomClusterTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + corralPackage *corral.Packages + clustersConfig *provisioninginput.Config + registryFQDN string +} + +func (a *AirGapRKE1CustomClusterTestSuite) TearDownSuite() { + a.session.Cleanup() +} + +func (a *AirGapRKE1CustomClusterTestSuite) SetupSuite() { + testSession := session.NewSession() + a.session = testSession + + a.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, a.clustersConfig) + + corralRancherHA := new(corralha.CorralRancherHA) + config.LoadConfig(corralha.CorralRancherHAConfigConfigurationFileKey, corralRancherHA) + + registriesConfig := new(registries.Registries) + config.LoadConfig(registries.RegistriesConfigKey, registriesConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(a.T(), err) + + a.client = client + listOfCorrals, err := corral.ListCorral() + require.NoError(a.T(), err) + + corralConfig := corral.Configurations() + + err = corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(a.T(), err) + + a.corralPackage = corral.PackagesConfig() + + _, corralExist := listOfCorrals[corralRancherHA.Name] + if corralExist { + bastionIP, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryIP) + require.NoError(a.T(), err) + + err = corral.UpdateCorralConfig(corralBastionIP, bastionIP) + require.NoError(a.T(), err) + + registryFQDN, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryFQDN) + require.NoError(a.T(), err) + logrus.Infof("registry fqdn is %s", registryFQDN) + + err = corral.SetCorralSSHKeys(corralRancherHA.Name) + require.NoError(a.T(), err) + a.registryFQDN = registryFQDN + } else { + a.registryFQDN = registriesConfig.ExistingNoAuthRegistryURL + } + +} + +func (a *AirGapRKE1CustomClusterTestSuite) TestProvisioningAirGapRKE1CustomCluster() { + a.clustersConfig.NodePools = []provisioninginput.NodePools{provisioninginput.AllRolesNodePool} + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String() + "-" + permutations.RKE1AirgapCluster + "-", a.client}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&a.Suite, tt.name, tt.client, a.clustersConfig, permutations.RKE1AirgapCluster, nil, a.corralPackage) + } + +} + +func (a *AirGapRKE1CustomClusterTestSuite) TestProvisioningUpgradeAirGapRKE1CustomCluster() { + a.clustersConfig.NodePools = []provisioninginput.NodePools{provisioninginput.AllRolesNodePool} + + rke1Versions, err := kubernetesversions.ListRKE1AllVersions(a.client) + require.NoError(a.T(), err) + + numOfRKE1Versions := len(rke1Versions) + // for this we will only have one custom cluster entry and one cni entry + require.Equal(a.T(), len(a.clustersConfig.CNIs), 1) + + a.clustersConfig.K3SKubernetesVersions[0] = rke1Versions[numOfRKE1Versions-2] + + testConfig := clusters.ConvertConfigToClusterConfig(a.clustersConfig) + testConfig.KubernetesVersion = a.clustersConfig.RKE1KubernetesVersions[0] + testConfig.CNI = a.clustersConfig.CNIs[0] + clusterObject, err := provisioning.CreateProvisioningRKE1AirgapCustomCluster(a.client, testConfig, a.corralPackage) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyRKE1Cluster(a.T(), a.client, testConfig, clusterObject) + + upgradedCluster, err := provisioning.UpgradeClusterK8sVersion(a.client, &clusterObject.Name, &rke1Versions[numOfRKE1Versions-1]) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyUpgrade(a.T(), upgradedCluster, rke1Versions[numOfRKE1Versions-1]) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestAirGapCustomClusterRKE1ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(AirGapRKE1CustomClusterTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke2_custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke2_custom_cluster_test.go new file mode 100644 index 0000000..3930ae5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/airgap/rke2_custom_cluster_test.go @@ -0,0 +1,133 @@ +//go:build validation + +package airgap + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/pipeline/rancherha/corralha" + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/rancher/tests/v2/validation/provisioning/registries" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + provisioning "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type AirGapRKE2CustomClusterTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + corralPackage *corral.Packages + clustersConfig *provisioninginput.Config + registryFQDN string +} + +func (a *AirGapRKE2CustomClusterTestSuite) TearDownSuite() { + a.session.Cleanup() +} + +func (a *AirGapRKE2CustomClusterTestSuite) SetupSuite() { + testSession := session.NewSession() + a.session = testSession + + a.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, a.clustersConfig) + + corralRancherHA := new(corralha.CorralRancherHA) + config.LoadConfig(corralha.CorralRancherHAConfigConfigurationFileKey, corralRancherHA) + + registriesConfig := new(registries.Registries) + config.LoadConfig(registries.RegistriesConfigKey, registriesConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(a.T(), err) + + a.client = client + listOfCorrals, err := corral.ListCorral() + require.NoError(a.T(), err) + + corralConfig := corral.Configurations() + err = corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(a.T(), err) + + a.corralPackage = corral.PackagesConfig() + + _, corralExist := listOfCorrals[corralRancherHA.Name] + if corralExist { + bastionIP, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryIP) + require.NoError(a.T(), err) + + err = corral.UpdateCorralConfig(corralBastionIP, bastionIP) + require.NoError(a.T(), err) + + registryFQDN, err := corral.GetCorralEnvVar(corralRancherHA.Name, corralRegistryFQDN) + require.NoError(a.T(), err) + logrus.Infof("registry fqdn is %s", registryFQDN) + + err = corral.SetCorralSSHKeys(corralRancherHA.Name) + require.NoError(a.T(), err) + a.registryFQDN = registryFQDN + } else { + a.registryFQDN = registriesConfig.ExistingNoAuthRegistryURL + } + +} + +func (a *AirGapRKE2CustomClusterTestSuite) TestProvisioningAirGapRKE2CustomCluster() { + a.clustersConfig.MachinePools = []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String() + "-" + permutations.RKE2AirgapCluster + "-", a.client}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&a.Suite, tt.name, tt.client, a.clustersConfig, permutations.RKE2AirgapCluster, nil, a.corralPackage) + } + +} + +func (a *AirGapRKE2CustomClusterTestSuite) TestProvisioningAirGapUpgradeRKE2CustomCluster() { + a.clustersConfig.MachinePools = []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + + rke2Versions, err := kubernetesversions.ListRKE2AllVersions(a.client) + require.NoError(a.T(), err) + + numOfRKE2Versions := len(rke2Versions) + // for this we will only have one custom cluster entry and one cni entry + require.Equal(a.T(), len(a.clustersConfig.CNIs), 1) + + a.clustersConfig.RKE2KubernetesVersions[0] = rke2Versions[numOfRKE2Versions-2] + + testConfig := clusters.ConvertConfigToClusterConfig(a.clustersConfig) + testConfig.KubernetesVersion = a.clustersConfig.RKE2KubernetesVersions[0] + testConfig.CNI = a.clustersConfig.CNIs[0] + clusterObject, err := provisioning.CreateProvisioningAirgapCustomCluster(a.client, testConfig, a.corralPackage) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyCluster(a.T(), a.client, testConfig, clusterObject) + + upgradedCluster, err := provisioning.UpgradeClusterK8sVersion(a.client, &clusterObject.Name, &rke2Versions[numOfRKE2Versions-1]) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(a.T(), err) + + provisioning.VerifyUpgrade(a.T(), upgradedCluster, rke2Versions[numOfRKE2Versions-1]) + +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestAirGapCustomClusterRKE2ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(AirGapRKE2CustomClusterTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/README.md new file mode 100644 index 0000000..0174a23 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/README.md @@ -0,0 +1,220 @@ +## Hosted Provider Provisioning Configs + +For your config, you will need everything in the [Prerequisites](../README.md) section on the previous readme along with and at least one [Cloud Credential](#cloud-credentials) and [Hosted Provider Config](#hosted-provider-configs). + +Your GO test_package should be set to `provisioning/hosted`. +Your GO suite should be set to `-run ^TestHostedClusterProvisioningTestSuite$`. +Please see below for more details for your config. Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Prerequisites](../README.md) +2. [Cloud Credential](#cloud-credentials) +3. [Hosted Provider Config](#hosted-provider-configs) +4. [Back to general provisioning](../README.md) + +Below are example configs needed for the different hosted providers including GKE, AKS, and EKS. In order to run these tests, the [cloud credentials](#cloud-credentials) are also needed. GKE (googleCredentials), AKS(azureCredentials), and EKS(awsCredentials) + +## Cloud Credentials + +### AWS +```yaml +awsCredentials: + secretKey: "", + accessKey: "", + defaultRegion: "" +``` +### Azure +```yaml +azureCredentials: + clientId: "", + clientSecret: "", + subscriptionId: "", + environment: "AzurePublicCloud" +``` +### Google +```yaml +googleCredentials: + authEncodedJson: |- + { + "type": "", + "project_id": "", + "private_key_id": "", + "private_key": "", + "client_email": "", + "client_id": "", + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://oauth2.googleapis.com/token", + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + "client_x509_cert_url": "" + } +``` + +## Hosted Provider Configs + +### EKS Cluster Config +```yaml +eksClusterConfig: + imported: false + kmsKey: "" + kubernetesVersion: "1.26" + loggingTypes: [] + nodeGroups: + - desiredSize: 3 + diskSize: 50 + ec2SshKey: "" + gpu: false + imageId: "" + instanceType: t3.medium + labels: {} + maxSize: 10 + minSize: 1 + nodeRole: "" + nodegroupName: "" + requestSpotInstances: false + resourceTags: {} + spotInstanceTypes: [] + subnets: [] + tags: {} + userData: "" + version: "1.26" + privateAccess: false + publicAccess: true + publicAccessSources: [] + region: us-east-2 + secretsEncryption: false + securityGroups: + - + serviceRole: "" + subnets: + - + - + tags: {} +``` + +These tests utilize Go build tags. Due to this, see the below example on how to run the test: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/hosted --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHostedEKSClusterProvisioningTestSuite/TestProvisioningHostedEKS"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +### AKS Cluster Config +```yaml +aksClusterConfig: + dnsPrefix: "" + kubernetesVersion: "1.26.6" + linuxAdminUsername: "azureuser" + loadBalancerSku: "Standard" + networkPlugin: "kubenet" + nodePools: + - availabilityZones: + - "1" + - "2" + - "3" + enableAutoScaling: false + maxPods: 110 + maxCount: 10 + minCount: 3 + mode: "System" + name: "agentpool" + nodeCount: 3 + osDiskSizeGB: 128 + osDiskType: "Managed" + osType: "Linux" + vmSize: "Standard_DS2_v2" + resourceGroup: "" + resourceLocation: "" + tags: {} +``` + +These tests utilize Go build tags. Due to this, see the below example on how to run the test: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/hosted --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHostedAKSClusterProvisioningTestSuite/TestProvisioningHostedAKS"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +### GKE Cluster Config +Note that the following are required and should be updated: +* kubernetesVersion +* location +* locations +* zone +* labels +* nodePools->name +* nodePools->labels +* nodePools->config->imageType (currently set to COS_CONTAINERD for use with 1.23+) + +```yaml +gkeClusterConfig: + clusterAddons: + horizontalPodAutoscaling: true + httpLoadBalancing: true + networkPolicyConfig: false + clusterIpv4Cidr: "" + enableKubernetesAlpha: false + horizontalPodAutoscaling: true + httpLoadBalancing: true + ipAllocationPolicy: + clusterIpv4Cidr: "" + clusterIpv4CidrBlock: null + clusterSecondaryRangeName: null + createSubnetwork: false + nodeIpv4CidrBlock: null + servicesIpv4CidrBlock: null + servicesSecondaryRangeName: null + subnetworkName: null + useIpAliases: true + kubernetesVersion: 1.26.8-gke.200 + labels: {} + locations: [] + loggingService: logging.googleapis.com/kubernetes + maintenanceWindow: "" + masterAuthorizedNetworks: + enabled: false + monitoringService: monitoring.googleapis.com/kubernetes + network: default + networkPolicyConfig: false + networkPolicyEnabled: false + nodePools: + - autoscaling: + enabled: false + maxNodeCount: null + minNodeCount: null + config: + diskSizeGb: 100 + diskType: pd-standard + imageType: COS_CONTAINERD + labels: {} + localSsdCount: 0 + machineType: n1-standard-2 + oauthScopes: + - https://www.googleapis.com/auth/devstorage.read_only + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/monitoring + - https://www.googleapis.com/auth/servicecontrol + - https://www.googleapis.com/auth/service.management.readonly + - https://www.googleapis.com/auth/trace.append + preemptible: false + tags: null + taints: null + initialNodeCount: 3 + isNew: true + management: + autoRepair: true + autoUpgrade: true + maxPodsConstraint: 110 + name: markus-automation + privateClusterConfig: + enablePrivateEndpoint: false + enablePrivateNodes: false + masterIpv4CidrBlock: null + projectID: "" + region: "" + subnetwork: default + zone: us-central1-c +``` + +These tests utilize Go build tags. Due to this, see the below example on how to run the test: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/hosted --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHostedGKEClusterProvisioningTestSuite/TestProvisioningHostedGKE"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/aks/hosted_provisioning_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/aks/hosted_provisioning_test.go new file mode 100644 index 0000000..a50a9fe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/aks/hosted_provisioning_test.go @@ -0,0 +1,91 @@ +//go:build validation + +package provisioning + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters/aks" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HostedAKSClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + cluster *management.Cluster +} + +func (h *HostedAKSClusterProvisioningTestSuite) TearDownSuite() { + h.session.Cleanup() +} + +func (h *HostedAKSClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + h.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(h.T(), err) + + h.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(h.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(h.T(), err) + + h.standardUserClient = standardUserClient +} + +func (h *HostedAKSClusterProvisioningTestSuite) TestProvisioningHostedAKS() { + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), h.client}, + {provisioninginput.StandardClientName.String(), h.standardUserClient}, + } + + for _, tt := range tests { + var aksClusterConfig aks.ClusterConfig + config.LoadConfig(aks.AKSClusterConfigConfigurationFileKey, &aksClusterConfig) + + clusterObject, err := provisioning.CreateProvisioningAKSHostedCluster(tt.client, aksClusterConfig) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(h.T(), err) + + provisioning.VerifyHostedCluster(h.T(), tt.client, clusterObject) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHostedAKSClusterProvisioningTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(HostedAKSClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/eks/hosted_provisioning_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/eks/hosted_provisioning_test.go new file mode 100644 index 0000000..dcf6b0c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/eks/hosted_provisioning_test.go @@ -0,0 +1,90 @@ +//go:build validation + +package eks + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters/eks" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HostedEKSClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client +} + +func (h *HostedEKSClusterProvisioningTestSuite) TearDownSuite() { + h.session.Cleanup() +} + +func (h *HostedEKSClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + h.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(h.T(), err) + + h.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(h.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(h.T(), err) + + h.standardUserClient = standardUserClient +} + +func (h *HostedEKSClusterProvisioningTestSuite) TestProvisioningHostedEKS() { + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), h.client}, + {provisioninginput.StandardClientName.String(), h.standardUserClient}, + } + + for _, tt := range tests { + var eksClusterConfig eks.ClusterConfig + config.LoadConfig(eks.EKSClusterConfigConfigurationFileKey, &eksClusterConfig) + + clusterObject, err := provisioning.CreateProvisioningEKSHostedCluster(tt.client, eksClusterConfig) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(h.T(), err) + + provisioning.VerifyHostedCluster(h.T(), tt.client, clusterObject) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHostedEKSClusterProvisioningTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(HostedEKSClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/gke/hosted_provisioning_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/gke/hosted_provisioning_test.go new file mode 100644 index 0000000..9fb3fc2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hosted/gke/hosted_provisioning_test.go @@ -0,0 +1,89 @@ +//go:build validation + +package gke + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters/gke" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HostedGKEClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client +} + +func (h *HostedGKEClusterProvisioningTestSuite) TearDownSuite() { + h.session.Cleanup() +} + +func (h *HostedGKEClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + h.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(h.T(), err) + + h.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(h.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(h.T(), err) + + h.standardUserClient = standardUserClient +} + +func (h *HostedGKEClusterProvisioningTestSuite) TestProvisioningHostedGKE() { + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), h.client}, + {provisioninginput.StandardClientName.String(), h.standardUserClient}, + } + + for _, tt := range tests { + var gkeClusterConfig gke.ClusterConfig + config.LoadConfig(gke.GKEClusterConfigConfigurationFileKey, &gkeClusterConfig) + clusterObject, err := provisioning.CreateProvisioningGKEHostedCluster(tt.client, gkeClusterConfig) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(h.T(), err) + + provisioning.VerifyHostedCluster(h.T(), tt.client, clusterObject) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHostedGKEClusterProvisioningTestSuite(t *testing.T) { + t.Skip("This test has been deprecated; check https://github.com/rancher/hosted-providers-e2e for updated tests") + suite.Run(t, new(HostedGKEClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/README.md new file mode 100644 index 0000000..9c29f5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/README.md @@ -0,0 +1,55 @@ +# Hostname Truncation + +For your config, you can directly reference the [RKE2 README](../rke2/README.md), specifically, for the prequisites, provisioning input, cloud credentials and machine RKE2 configuration. + +Your GO test_package should be set to `hostnametruncation`. +Your GO suite should be set to `-run ^TestProvisioningRKE2ClusterTruncation$`. +Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +See below a sample config file to run this test: +```yaml +rancher: + host: "" #required + adminToken: "" #required + clusterName: "" + +provisioningInput: + machinePools: + - nodeRoles: #required (at least 1) + etcd: true #required (at least 1 controlplane & etcd & worker) + quantity: 1 + - nodeRoles: + controlplane: true + quantity: 1 + - nodeRoles: + worker: true + quantity: 1 + rke2KubernetesVersion: ["v1.27.6+rke2r1"] #required (at least 1) + cni: ["calico"] #required (at least 1) + providers: ["aws"] #required (at least 1) + +awsCredentials: + secretKey: "", #required + accessKey: "", #required + defaultRegion: "" #required + +awsMachineConfig: + region: "us-east-2" + ami: "" #required + instanceType: "t3a.medium" #required + sshUser: "ubuntu" #required + vpcId: "" #required + volumeType: "gp2" #required + zone: "a" #required + retries: "5" #required + rootSize: "60" #required + securityGroup: [""] #required +``` + +These tests utilize Go build tags. Due to this, see the below example on how to run the test: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/hostnametruncation --junitfile results.xml -- -timeout=120m -tags=validation -v -run "TestProvisioningHostnameTruncationTestSuite/TestProvisioningRKE2ClusterTruncation"` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/hostname_truncation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/hostname_truncation_test.go new file mode 100644 index 0000000..942ce3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/hostnametruncation/hostname_truncation_test.go @@ -0,0 +1,122 @@ +//go:build (validation || stress) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !extended + +package hostnametruncation + +import ( + "fmt" + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HostnameTruncationTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + clustersConfig *provisioninginput.Config +} + +func (r *HostnameTruncationTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *HostnameTruncationTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.clustersConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client +} + +// TestProvisioningRKE2ClusterTruncation consist of several test that loop through three limits +// for hostnames. The test starts at a minimum length limit of 10 characters, then a maximum length +// limit of 63 characters and finally a middle length limit of 31 characters +func (r *HostnameTruncationTestSuite) TestProvisioningRKE2ClusterTruncation() { + tests := []struct { + name string + machinePoolNameLengths []int + hostnameLengthLimits []int + defaultHostnameLengthLimits []int + }{ + { + name: "Cluster level truncation", + machinePoolNameLengths: []int{10, 31, 63}, + defaultHostnameLengthLimits: []int{10, 31, 63}, + }, + { + name: "Machine pool level truncation - 10 characters", + machinePoolNameLengths: []int{10, 10, 10}, + hostnameLengthLimits: []int{10, 31, 63}, + defaultHostnameLengthLimits: []int{10, 16, 63}, + }, + { + name: "Machine pool level truncation - 31 characters", + machinePoolNameLengths: []int{10, 31, 63}, + hostnameLengthLimits: []int{31, 31, 31}, + defaultHostnameLengthLimits: []int{10, 31, 63}, + }, + { + name: "Machine pool level truncation - 63 characters", + machinePoolNameLengths: []int{10, 31, 63}, + hostnameLengthLimits: []int{63, 63, 63}, + defaultHostnameLengthLimits: []int{10, 31, 63}, + }, + { + name: "Cluster and machine pool level truncation - 31 characters", + machinePoolNameLengths: []int{10, 31, 63}, + hostnameLengthLimits: []int{31, 31, 31}, + defaultHostnameLengthLimits: []int{10, 63, 31}, + }, + } + for _, tt := range tests { + for _, defaultLength := range tt.defaultHostnameLengthLimits { + r.Run(tt.name+fmt.Sprintf("_defaultHostnameLimit:%d", defaultLength), func() { + var hostnamePools []machinepools.HostnameTruncation + for i, nameLength := range tt.machinePoolNameLengths { + currentTruncationPool := machinepools.HostnameTruncation{ + Name: namegen.RandStringLower(nameLength), + ClusterNameLengthLimit: defaultLength, + } + if len(tt.hostnameLengthLimits) >= i && len(tt.hostnameLengthLimits) > 0 { + currentTruncationPool.PoolNameLengthLimit = tt.hostnameLengthLimits[i] + } + hostnamePools = append(hostnamePools, currentTruncationPool) + } + testConfig := clusters.ConvertConfigToClusterConfig(r.clustersConfig) + testConfig.KubernetesVersion = r.clustersConfig.RKE2KubernetesVersions[0] + testConfig.CNI = r.clustersConfig.CNIs[0] + + rke2Provider, _, _, _ := permutations.GetClusterProvider(permutations.RKE2ProvisionCluster, (*testConfig.Providers)[0], r.clustersConfig) + + clusterObject, err := provisioning.CreateProvisioningCluster(r.client, *rke2Provider, testConfig, hostnamePools) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(r.T(), err) + + provisioning.VerifyCluster(r.T(), r.client, testConfig, clusterObject) + provisioning.VerifyHostnameLength(r.T(), r.client, clusterObject) + }) + } + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestProvisioningHostnameTruncationTestSuite(t *testing.T) { + suite.Run(t, new(HostnameTruncationTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/README.md new file mode 100644 index 0000000..05e83ad --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/README.md @@ -0,0 +1,58 @@ +# Import Provisioning Config + +For your config, you will need everything in the Prerequisites section on the previous readme, [Define your test](#provisioning-input), and a corral config that points to a package that builds a functional cluster and has a `kubeconfig` var once the corral has built successfully. This test is setup to run the k3s corral-package, but technically as long as the corral is successful and finishes with a valid `kubeconfig`, the cluster import job will still operate properly and successfully. + +Your GO test_package should be set to `provisioning/import`. +Your GO suite should be set to `-run ^TestImportProvisioningTestSuite$`. +Please see below for more details for your config. + + +## Table of Contents +1. [Prerequisites](../README.md) +2. [Configuring test flags](#Flags) +3. [Define your Corral](#corral-input) +4. [Back to general provisioning](../README.md) + +## Flags +Flags are used to determine which static table tests are run (has no effect on dynamic tests) +`Long` Will run the long version of the table tests (usually all of them) +`Short` Will run the subset of table tests with the short flag. + +```yaml +flags: + desiredflags: "Long" #required (static tests only) +``` + +## Corral Input + +```yaml + +corralConfigs: + corralConfigVars: + agent_count: 0 + aws_access_key: "your_key" + aws_ami: "your_ami" + aws_hostname_prefix: autoimport + aws_region: us-west-1 + aws_route53_zone: "your_zone" + aws_secret_key: "your_secret_key" + aws_security_group: "your_security_group" + aws_ssh_user: "your_user" + aws_subnet: "your_subnet" + aws_volume_size: 50 + aws_volume_type: gp3 + hostname: "your_hostname(should match the prefix + route_53 zone)" + aws_vpc: "your_vpc" + instance_type: t3a.medium + # kubernetes_version: not supported with suggested package + node_count: 3 + server_count: 3 + + corralSSHPath: "/root/go/src/github.com/rancher/rancher/tests/v2/validation/.ssh/" +corralPackages: + corralPackageImages: + # NOTE: k3sToImport is the **Required** package name. It can point to any path, as long as the package name is k3sToImport. + k3sToImport: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-k3s-v1.26.8-k3s1 +``` + +**k3sToImport is the **Required** package name. It can point to any path, as long as the package name is k3sToImport.** \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/import_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/import_cluster_test.go new file mode 100644 index 0000000..fcdc547 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/import/import_cluster_test.go @@ -0,0 +1,193 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package imported + +import ( + "testing" + "time" + + apiv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/sirupsen/logrus" + + "k8s.io/client-go/tools/clientcmd" + + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + k3sImportPackageName = "k3sToImport" +) + +type ImportProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *ImportProvisioningTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *ImportProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient + + corralConfig := corral.Configurations() + err = corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(r.T(), err, "error reading corral configs") +} + +func (r *ImportProvisioningTestSuite) TestProvisioningImportK3SCluster() { + corralPackage := corral.PackagesConfig() + + if corralPackage.HasCustomRepo != "" { + err := corral.SetCustomRepo(corralPackage.HasCustomRepo) + require.Nil(r.T(), err, "error setting remote repo") + } + + if len(corralPackage.CorralPackageImages) == 0 { + r.T().Error("No Corral Packages to Test") + } + + _, ok := corralPackage.CorralPackageImages[k3sImportPackageName] + require.True(r.T(), ok, "Please ensure %s package is in corralPackageImages", k3sImportPackageName) + + var importPackageName string + + for packageName, packageImage := range corralPackage.CorralPackageImages { + newPackageName := namegen.AppendRandomString(packageName) + + if packageName == k3sImportPackageName { + importPackageName = newPackageName + + corralRun, err := corral.CreateCorral(r.session, newPackageName, packageImage, corralPackage.HasDebug, corralPackage.HasDebug) + require.NoError(r.T(), err, "error creating corral %v", packageName) + + r.T().Logf("Corral %v created successfully", packageName) + require.NotNil(r.T(), corralRun, "corral run had no restConfig") + } + + } + + importCluster := apiv1.Cluster{ + ObjectMeta: v1.ObjectMeta{ + Name: namegen.AppendRandomString("auto-import"), + Namespace: "fleet-default", + }, + } + + backoff := wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 40, + } + + decodedKubeConfig := []byte{} + err := wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + decodedKubeConfig, err = corral.GetKubeConfig(importPackageName) + if err != nil { + return false, nil + } + return true, nil + }) + + require.NoError(r.T(), err) + + config, err := clientcmd.RESTConfigFromKubeConfig(decodedKubeConfig) + require.NoError(r.T(), err) + + _, err = clusters.CreateK3SRKE2Cluster(r.client, &importCluster) + require.NoError(r.T(), err) + + updatedCluster := new(apiv1.Cluster) + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + updatedCluster, _, err = clusters.GetProvisioningClusterByName(r.client, importCluster.Name, importCluster.Namespace) + require.NoError(r.T(), err) + + if updatedCluster.Status.ClusterName != "" { + return true, nil + } + + return false, nil + }) + require.NoError(r.T(), err) + + logrus.Info(updatedCluster.Status.ClusterName) + err = clusters.ImportCluster(r.client, updatedCluster, config) + require.NoError(r.T(), err) + + backoff = wait.Backoff{ + Duration: 5 * time.Second, + Factor: 1.1, + Jitter: 0.1, + Steps: 100, + } + + err = wait.ExponentialBackoff(backoff, func() (finished bool, err error) { + updatedCluster, _, err = clusters.GetProvisioningClusterByName(r.client, importCluster.Name, importCluster.Namespace) + require.NoError(r.T(), err) + + if updatedCluster.Status.Ready { + return true, nil + } + + return false, nil + }) + require.NoError(r.T(), err) + + podErrors := pods.StatusPods(r.client, updatedCluster.Status.ClusterName) + require.Empty(r.T(), podErrors) + +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestImportProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(ImportProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/README.md new file mode 100644 index 0000000..d1c453b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/README.md @@ -0,0 +1,418 @@ +# K3S Provisioning Configs + +For your config, you will need everything in the Prerequisites section on the previous readme, [Define your test](#provisioning-input), and at least one [Cloud Credential](#cloud-credentials) and [Node Driver Machine Config](#machine-k3s-config) or [Custom Cluster Template](#custom-cluster), which should match what you have specified in `provisioningInput`. + +Your GO test_package should be set to `provisioning/k3s`. +Your GO suite should be set to `-run ^TestK3SProvisioningTestSuite$`. +Please see below for more details for your config. Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Prerequisites](../README.md) +2. [Configuring test flags](#Flags) +3. [Define your test](#provisioning-input) +4. [Cloud Credential](#cloud-credentials) +5. [Configure providers to use for Node Driver Clusters](#machine-k3s-config) +6. [Configuring Custom Clusters](#custom-cluster) +7. [Template Test](#template-test) +8. [Static test cases](#static-test-cases) +9. [Advanced Cluster Settings](#advanced-settings) +10. [Back to general provisioning](../README.md) + +## Flags +Flags are used to determine which static table tests are run (has no effect on dynamic tests) +`Long` Will run the long version of the table tests (usually all of them) +`Short` Will run the subset of table tests with the short flag. + +```yaml +flags: + desiredflags: "Long" #required (static tests only) +``` + +## Provisioning Input +provisioningInput is needed to the run the K3S tests. + +**nodeProviders is only needed for custom cluster tests; the framework only supports custom clusters through aws/ec2 instances.** +```yaml +provisioningInput: + machinePools: + - machinePoolConfig: #required(dynamic only) (at least 1 of each role must be true accross all machinePoolConfigs) + etcd: true #required(dynamic only) (at least 1 role etcd, controlplane, worker must be true) + controlplane: true + worker: true + quantity: 1 + drainBeforeDelete: true + hostnameLengthLimit: 29 + nodeStartupTimeout: "600s" + unhealthyNodeTimeout: "300s" + maxUnhealthy: "2" + unhealthyRange: "2-4" + - machinePoolConfig: + worker: true + quantity: 2 + drainBeforeDelete: true + - machinePoolConfig: + worker: true + quantity: 1 + k3sKubernetesVersion: ["v1.27.6+k3s1"] #required (at least 1) + providers: ["aws"] #required (at least 1) linode,aws,do,harvester,vsphere,azure,google + cni: ["calico"] #required (at least 1) + nodeProviders: ["ec2"] #required(custom clusters only) + hardened: false + psact: "" #either rancher-privileged|rancher-restricted|rancher-baseline + clusterSSHTests: ["CheckCPU", "NodeReboot", "AuditLog"] + etcd: + disableSnapshot: false + snapshotScheduleCron: "0 */5 * * *" + snapshotRetain: 3 + s3: + bucket: "" + endpoint: "s3.us-east-2.amazonaws.com" + endpointCA: "" + folder: "" + region: "us-east-2" + skipSSLVerify: true +``` + +## Cloud Credentials +These are the inputs needed for the different node provider cloud credentials, including linode, aws, harvester, azure, and google. + +### Digital Ocean +```yaml +digitalOceanCredentials: + accessToken: "" #required +``` +### Linode +```yaml +linodeCredentials: + token: "" #required +``` +### Azure +```yaml +azureCredentials: + clientId: "" #required + clientSecret: "" #required + subscriptionId": "" #required + environment: "AzurePublicCloud" #required +``` +### AWS +```yaml +awsCredentials: + secretKey: "" #required + accessKey: "" #required + defaultRegion: "" #required +``` +### Harvester +```yaml +harvesterCredentials: + clusterId: "" #required + clusterType: "" #required + kubeconfigContent: "" #required +``` +### Google +```yaml +googleCredentials: + authEncodedJson: "" #required +``` +### VSphere +```yaml +vmwarevsphereCredentials: + password: "" #required + username: "" #required + vcenter: "" #required + vcenterPort: "" #required +``` + +## Machine K3S Config +Machine K3S config is the final piece needed for the config to run K3S provisioning tests. + +### AWS K3S Machine Config +```yaml +awsMachineConfigs: + region: "us-east-2" #required + awsMachineConfig: + - roles: ["etcd","controlplane","worker"] #required + ami: "" #required + instanceType: "t3a.medium" + sshUser: "ubuntu" #required + vpcId: "" #required + volumeType: "gp2" + zone: "a" #required + retries: "5" + rootSize: "60" + securityGroup: [""] +``` +### Digital Ocean K3S Machine Config +```yaml +doMachineConfig: + image: "ubuntu-20-04-x64" + backups: false + ipv6: false + monitoring: false + privateNetworking: false + region: "nyc3" + size: "s-2vcpu-4gb" + sshKeyContents: "" + sshKeyFingerprint: "" + sshPort: "22" + sshUser: "root" + tags: "" + userdata: "" +``` +### Linode K3S Machine Config +```yaml +linodeMachineConfig: + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-standard-8" + region: "us-west" + rootPass: "" + sshPort: "22" + sshUser: "" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + uaPrefix: "Rancher" +``` +### Azure K3S Machine Config +```yaml +azureMachineConfig: + availabilitySet: "docker-machine" + diskSize: "30" + environment: "AzurePublicCloud" + faultDomainCount: "3" + image: "canonical:UbuntuServer:22.04-LTS:latest" + location: "westus" + managedDisks: false + noPublicIp: false + nsg: "" + openPort: ["6443/tcp", "2379/tcp", "2380/tcp", "8472/udp", "4789/udp", "9796/tcp", "10256/tcp", "10250/tcp", "10251/tcp", "10252/tcp"] + resourceGroup: "docker-machine" + size: "Standard_D2_v2" + sshUser: "docker-user" + staticPublicIp: false + storageType: "Standard_LRS" + subnet: "docker-machine" + subnetPrefix: "192.168.0.0/16" + updateDomainCount: "5" + usePrivateIp: false + vnet: "docker-machine-vnet" +``` +### Harvester K3S Machine Config +```yaml +harvesterMachineConfig": + diskSize: "40" + cpuCount: "2" + memorySize: "8" + networkName: "default/ctw-network-1" + imageName: "default/image-rpj98" + vmNamespace: "default" + sshUser: "ubuntu" + diskBus: "virtio +``` +## Vsphere K3S Machine Config +```yaml +vmwarevsphereMachineConfigs: + datacenter: "/" #required + hostSystem: "//path-to-host" #required + datastoreURL: "/datastore.URL" #required + datastore: ""//path-to-datastore" #required + folder: "//path-to-vm-folder" #required + pool: "//path-to-resource-pool" #required + vmwarevsphereMachineConfig: + - cfgparam: ["disk.enableUUID=TRUE"] #required + cloudConfig: "#cloud-config\n\n" + customAttribute: [] + tag: [] + roles: ["etcd","controlplane",worker] + creationType: "template" #required + os: "linux" #required + cloneFrom: "//path-to-linux-image" #required(linux templates only) + cloneFromWindows: "//path-to-windows-image" #required(windows templates only) + contentLibrary: "" + datastoreCluster: "" + network: ["//path-to-vm-network"] #required + sshUser: "" #required + sshPassword: "" + sshUserGroup: "" + sshPort: "22" + cpuCount: "4" + diskSize: "40000" + memorySize: "8192" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the node driver tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestK3SProvisioningTestSuite/TestProvisioningK3SCluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestK3SProvisioningTestSuite/TestProvisioningK3SClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## Custom Cluster +For custom clusters, no machineConfig or credentials are needed. Currently only supported for ec2. + +Dependencies: +* **Ensure you have nodeProviders in provisioningInput** +* make sure that all roles are entered at least once +* windows pool(s) should always be last in the config +```yaml + awsEC2Configs: + region: "us-east-2" + awsSecretAccessKey: "" + awsAccessKeyID: "" + awsEC2Config: + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["etcd", "controlplane"] + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["worker"] + - instanceType: "t3a.xlarge" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsUser: "Administrator" + volumeSize: 50 + roles: ["windows"] +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the custom cluster tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterK3SProvisioningTestSuite/TestProvisioningK3SCustomCluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterK3SProvisioningTestSuite/TestProvisioningK3SCustomClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## Template Test + +Dependencies: +* [Cloud Credential](#cloud-credentials) +* Make sure the template provider matches the credentials. +```yaml +templateTest: + repo: + metadata: + name: "demo" + spec: + gitRepo: "https://github.com//cluster-template-examples.git" + gitBranch: main + insecureSkipTLSVerify: true + templateProvider: "aws" + templateName: "cluster-template" +``` + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestClusterTemplateTestSuite/TestProvisionK3sTemplateCluster` + +## Static Test Cases +In an effort to have uniform testing across our internal QA test case reporter, there are specific test cases that are put into their respective test files. This section highlights those test cases. + +### PSACT +These test cases cover the following PSACT values as both an admin and standard user: +1. `rancher-privileged` +2. `rancher-restricted` +3. `rancher-baseline` + +See an example YAML below: + +```yaml +rancher: + host: "" + adminToken: "" + cleanup: false + clusterName: "" + insecure: true +provisioningInput: + k3sKubernetesVersion: ["v1.27.10+k3s2"] + cni: ["calico"] + providers: ["linode"] + nodeProviders: ["ec2"] +linodeCredentials: + token: "" +linodeMachineConfigs: + region: "us-west" + linodeMachineConfig: + - roles: ["etcd", "controlplane", "worker"] + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-standard-8" + region: "us-west" + rootPass: "" + sshPort: "22" + sshUser: "" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + uaPrefix: "Rancher" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestK3SPSACTTestSuite$"` + +### Hardened Custom Cluster +This will provision a hardened custom cluster that runs across the following CIS scan profiles: +1. `k3s-cis-1.8-profile-hardened` +2. `k3s-cis-1.8-profile-permissive` + +You would use the same config that you setup for a custom cluster to run this test. Plese reference this [section](#custom-cluster). It also important to note that the machines that you select has `sudo` capabilities. The tests utilize `sudo`, so this can cause issues if there is no `sudo` present on the machine. + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/k3s --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHardenedK3SClusterProvisioningTestSuite$"` + +## Advanced Settings +This encapsulates any other setting that is applied in the cluster.spec. Currently we have support for: +* cluster agent customization +* fleet agent customization + +Please read up on general k8s to get an idea of correct formatting for: +* resource requests +* resource limits +* node affinity +* tolerations + +```yaml +advancedOptions: + clusterAgent: # change this to fleetAgent for fleet agent + appendTolerations: + - key: "Testkey" + value: "testValue" + effect: "NoSchedule" + overrideResourceRequirements: + limits: + cpu: "750m" + memory: "500Mi" + requests: + cpu: "250m" + memory: "250Mi" + overrideAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: "cattle.io/cluster-agent" + operator: "In" + values: + - "true" + weight: 1 +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/custom_cluster_test.go new file mode 100644 index 0000000..c1469d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/custom_cluster_test.go @@ -0,0 +1,131 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package k3s + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CustomClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (c *CustomClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *CustomClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.K3SKubernetesVersions, err = kubernetesversions.Default(c.client, clusters.K3SClusterType.String(), c.provisioningConfig.K3SKubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningK3SCustomCluster() { + nodeRolesAll := []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + nodeRolesShared := []provisioninginput.MachinePools{provisioninginput.EtcdControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + + tests := []struct { + name string + client *rancher.Client + machinePools []provisioninginput.MachinePools + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesAll, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesShared, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, c.client.Flags.GetValue(environmentflag.Long)}, + } + for _, tt := range tests { + if !tt.runFlag { + c.T().Logf("SKIPPED") + continue + } + + provisioningConfig := *c.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, &provisioningConfig, permutations.K3SCustomCluster, nil, nil) + } +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningK3SCustomClusterDynamicInput() { + isWindows := false + for _, pool := range c.provisioningConfig.MachinePools { + if pool.MachinePoolConfig.Windows { + isWindows = true + break + } + } + if isWindows { + c.T().Skip("Skipping Windows tests, not supported on k3s") + } + + if len(c.provisioningConfig.MachinePools) == 0 { + c.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), c.client}, + {provisioninginput.StandardClientName.String(), c.standardUserClient}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, c.provisioningConfig, permutations.K3SCustomCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestCustomClusterK3SProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(CustomClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/hardened_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/hardened_cluster_test.go new file mode 100644 index 0000000..aea5527 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/hardened_cluster_test.go @@ -0,0 +1,139 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package k3s + +import ( + "testing" + + cis "github.com/rancher/rancher/tests/v2/validation/provisioning/resources/cisbenchmark" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HardenedK3SClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config + project *management.Project + chartInstallOptions *charts.InstallOptions + chartFeatureOptions *charts.RancherMonitoringOpts +} + +func (c *HardenedK3SClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *HardenedK3SClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.K3SKubernetesVersions, err = kubernetesversions.Default(c.client, clusters.K3SClusterType.String(), c.provisioningConfig.K3SKubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *HardenedK3SClusterProvisioningTestSuite) TestProvisioningK3SHardenedCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + + tests := []struct { + name string + client *rancher.Client + machinePools []provisioninginput.MachinePools + scanProfileName string + }{ + {"K3S CIS 1.8 Profile Hardened " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "k3s-cis-1.8-profile-hardened"}, + {"K3S CIS 1.8 Profile Permissive " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "k3s-cis-1.8-profile-permissive"}, + } + for _, tt := range tests { + c.Run(tt.name, func() { + provisioningConfig := *c.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + provisioningConfig.Hardened = true + + nodeProviders := provisioningConfig.NodeProviders[0] + externalNodeProvider := provisioning.ExternalNodeProviderSetup(nodeProviders) + + testConfig := clusters.ConvertConfigToClusterConfig(&provisioningConfig) + testConfig.KubernetesVersion = c.provisioningConfig.K3SKubernetesVersions[0] + + clusterObject, err := provisioning.CreateProvisioningCustomCluster(tt.client, &externalNodeProvider, testConfig) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + provisioning.VerifyCluster(c.T(), tt.client, testConfig, clusterObject) + + cluster, err := clusters.NewClusterMeta(tt.client, clusterObject.Name) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + latestCISBenchmarkVersion, err := tt.client.Catalog.GetLatestChartVersion(charts.CISBenchmarkName, catalog.RancherChartRepo) + require.NoError(c.T(), err) + + project, err := projects.GetProjectByName(tt.client, cluster.ID, cis.System) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + c.project = project + require.NotEmpty(c.T(), c.project) + + c.chartInstallOptions = &charts.InstallOptions{ + Cluster: cluster, + Version: latestCISBenchmarkVersion, + ProjectID: c.project.ID, + } + + cis.SetupCISBenchmarkChart(tt.client, c.project.ClusterID, c.chartInstallOptions, charts.CISBenchmarkNamespace) + cis.RunCISScan(tt.client, c.project.ClusterID, tt.scanProfileName) + }) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHardenedK3SClusterProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(HardenedK3SClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/post_kdm_oob_release_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/post_kdm_oob_release_test.go new file mode 100644 index 0000000..6d62cdb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/post_kdm_oob_release_test.go @@ -0,0 +1,69 @@ +//go:build validation + +package k3s + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type KdmChecksTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + ns string + provisioningConfig *provisioninginput.Config +} + +const ( + defaultNamespace = "default" +) + +func (k *KdmChecksTestSuite) TearDownSuite() { + k.session.Cleanup() +} + +func (k *KdmChecksTestSuite) SetupSuite() { + testSession := session.NewSession() + k.session = testSession + + k.ns = defaultNamespace + + k.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, k.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(k.T(), err) + + k.client = client +} + +func (k *KdmChecksTestSuite) TestK3SK8sVersions() { + logrus.Infof("checking for valid k8s versions..") + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.K3SKubernetesVersions), 1) + // fetching all available k8s versions from rancher + releasedK8sVersions, _ := kubernetesversions.ListK3SAllVersions(k.client) + logrus.Info("expected k8s versions : ", k.provisioningConfig.K3SKubernetesVersions) + logrus.Info("k8s versions available on rancher server : ", releasedK8sVersions) + for _, expectedK8sVersion := range k.provisioningConfig.K3SKubernetesVersions { + require.Contains(k.T(), releasedK8sVersions, expectedK8sVersion) + } +} + +func (k *KdmChecksTestSuite) TestProvisioningSingleNodeK3SClusters() { + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.Providers), 1) + permutations.RunTestPermutations(&k.Suite, "oobRelease-", k.client, k.provisioningConfig, permutations.K3SProvisionCluster, nil, nil) +} + +func TestPostKdmOutOfBandReleaseChecks(t *testing.T) { + suite.Run(t, new(KdmChecksTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/provisioning_node_driver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/provisioning_node_driver_test.go new file mode 100644 index 0000000..ff4b719 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/provisioning_node_driver_test.go @@ -0,0 +1,122 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package k3s + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type K3SNodeDriverProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (k *K3SNodeDriverProvisioningTestSuite) TearDownSuite() { + k.session.Cleanup() +} + +func (k *K3SNodeDriverProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + k.session = testSession + + k.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, k.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(k.T(), err) + + k.client = client + + k.provisioningConfig.K3SKubernetesVersions, err = kubernetesversions.Default( + k.client, clusters.K3SClusterType.String(), k.provisioningConfig.K3SKubernetesVersions) + require.NoError(k.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(k.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(k.T(), err) + + k.standardUserClient = standardUserClient +} + +func (k *K3SNodeDriverProvisioningTestSuite) TestProvisioningK3SCluster() { + nodeRolesAll := []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + nodeRolesShared := []provisioninginput.MachinePools{provisioninginput.EtcdControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), nodeRolesAll, k.standardUserClient, k.client.Flags.GetValue(environmentflag.Short) || k.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), nodeRolesShared, k.standardUserClient, k.client.Flags.GetValue(environmentflag.Short) || k.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), nodeRolesDedicated, k.standardUserClient, k.client.Flags.GetValue(environmentflag.Long)}, + } + + for _, tt := range tests { + if !tt.runFlag { + k.T().Logf("SKIPPED") + continue + } + provisioningConfig := *k.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&k.Suite, tt.name, tt.client, &provisioningConfig, permutations.K3SProvisionCluster, nil, nil) + } +} + +func (k *K3SNodeDriverProvisioningTestSuite) TestProvisioningK3SClusterDynamicInput() { + if len(k.provisioningConfig.MachinePools) == 0 { + k.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), k.client}, + {provisioninginput.StandardClientName.String(), k.standardUserClient}, + } + + for _, tt := range tests { + permutations.RunTestPermutations(&k.Suite, tt.name, tt.client, k.provisioningConfig, permutations.K3SProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestK3SProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(K3SNodeDriverProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/psact_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/psact_test.go new file mode 100644 index 0000000..17ca2b9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/psact_test.go @@ -0,0 +1,118 @@ +//go:build validation + +package k3s + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type K3SPSACTTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (k *K3SPSACTTestSuite) TearDownSuite() { + k.session.Cleanup() +} + +func (k *K3SPSACTTestSuite) SetupSuite() { + testSession := session.NewSession() + k.session = testSession + + k.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, k.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(k.T(), err) + + k.client = client + + k.provisioningConfig.K3SKubernetesVersions, err = kubernetesversions.Default( + k.client, clusters.K3SClusterType.String(), k.provisioningConfig.K3SKubernetesVersions) + require.NoError(k.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(k.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(k.T(), err) + + k.standardUserClient = standardUserClient +} + +func (k *K3SPSACTTestSuite) TestK3SPSACTNodeDriverCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{ + provisioninginput.EtcdMachinePool, + provisioninginput.ControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + } + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + psact provisioninginput.PSACT + client *rancher.Client + }{ + { + name: "Rancher Privileged " + provisioninginput.StandardClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-privileged", + client: k.standardUserClient, + }, + { + name: "Rancher Restricted " + provisioninginput.StandardClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-restricted", + client: k.standardUserClient, + }, + { + name: "Rancher Baseline " + provisioninginput.AdminClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-baseline", + client: k.client, + }, + } + + for _, tt := range tests { + provisioningConfig := *k.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + provisioningConfig.PSACT = string(tt.psact) + permutations.RunTestPermutations(&k.Suite, tt.name, tt.client, &provisioningConfig, + permutations.K3SProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestK3SPSACTTestSuite(t *testing.T) { + suite.Run(t, new(K3SPSACTTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/template_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/template_test.go new file mode 100644 index 0000000..6fa6a63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/k3s/template_test.go @@ -0,0 +1,83 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package k3s + +import ( + "testing" + "time" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/cloudcredentials" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/defaults/stevetypes" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/steve" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + localCluster = "local" + fleetNamespace = "fleet-default" + providerName = "k3s" + templateTestConfigKey = "templateTest" +) + +type ClusterTemplateTestSuite struct { + suite.Suite + client *rancher.Client + standardUserClient *rancher.Client + session *session.Session + templateConfig *provisioninginput.TemplateConfig + cloudCredentials *cloudcredentials.CloudCredential +} + +func (r *ClusterTemplateTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *ClusterTemplateTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.templateConfig = new(provisioninginput.TemplateConfig) + config.LoadConfig(templateTestConfigKey, r.templateConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + r.client = client + + provider := provisioning.CreateProvider(r.templateConfig.TemplateProvider) + r.cloudCredentials, err = provider.CloudCredFunc(client) + require.NoError(r.T(), err) +} + +func (r *ClusterTemplateTestSuite) TestProvisionK3sTemplateCluster() { + _, err := steve.CreateAndWaitForResource(r.client, stevetypes.ClusterRepo, r.templateConfig.Repo, true, 5*time.Second, defaults.FiveMinuteTimeout) + require.NoError(r.T(), err) + + k8sversions, err := kubernetesversions.Default(r.client, providerName, nil) + require.NoError(r.T(), err) + + clusterName := namegenerator.AppendRandomString(providerName + "-template") + err = charts.InstallTemplateChart(r.client, r.templateConfig.Repo.ObjectMeta.Name, r.templateConfig.TemplateName, clusterName, k8sversions[0], r.cloudCredentials) + require.NoError(r.T(), err) + + _, cluster, err := clusters.GetProvisioningClusterByName(r.client, clusterName, fleetNamespace) + require.NoError(r.T(), err) + + provisioning.VerifyCluster(r.T(), r.client, nil, cluster) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestClusterTemplateTestSuite(t *testing.T) { + suite.Run(t, new(ClusterTemplateTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/permutations/permutations.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/permutations/permutations.go new file mode 100644 index 0000000..85f22d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/permutations/permutations.go @@ -0,0 +1,512 @@ +package permutations + +import ( + "context" + "os" + "strings" + "testing" + "time" + + "github.com/rancher/rancher/pkg/api/scheme" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubeapi/storageclasses" + "github.com/rancher/shepherd/extensions/kubeapi/volumes/persistentvolumeclaims" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/rke1/componentchecks" + "github.com/rancher/shepherd/extensions/rke1/nodetemplates" + "github.com/rancher/shepherd/extensions/services" + "github.com/rancher/shepherd/extensions/workloads" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + RKE2CustomCluster = "rke2Custom" + RKE2ProvisionCluster = "rke2" + RKE2AirgapCluster = "rke2Airgap" + K3SCustomCluster = "k3sCustom" + K3SProvisionCluster = "k3s" + K3SAirgapCluster = "k3sAirgap" + RKE1CustomCluster = "rke1Custom" + RKE1ProvisionCluster = "rke1" + RKE1AirgapCluster = "rke1Airgap" + CorralProvider = "corral" + + outOfTreeAWSFilePath = "../resources/out-of-tree/aws.yml" + clusterIPPrefix = "cip" + loadBalancerPrefix = "lb" + portName = "port" + nginxName = "nginx" + defaultNamespace = "default" + + pollInterval = time.Duration(1 * time.Second) + pollTimeout = time.Duration(1 * time.Minute) + + repoType = "catalog.cattle.io.clusterrepo" + appsType = "catalog.cattle.io.apps" + awsUpstreamCloudProviderRepo = "https://github.com/kubernetes/cloud-provider-aws.git" + masterBranch = "master" + awsUpstreamChartName = "aws-cloud-controller-manager" + kubeSystemNamespace = "kube-system" + systemProject = "System" + externalProviderString = "external" + vsphereCPIchartName = "rancher-vsphere-cpi" + vsphereCSIchartName = "rancher-vsphere-csi" +) + +var ( + group int64 + user int64 +) + +// RunTestPermutations runs through all relevant perumutations in a given config file, including node providers, k8s versions, and CNIs +func RunTestPermutations(s *suite.Suite, testNamePrefix string, client *rancher.Client, provisioningConfig *provisioninginput.Config, clusterType string, hostnameTruncation []machinepools.HostnameTruncation, corralPackages *corral.Packages) { + var name string + var providers []string + var testClusterConfig *clusters.ClusterConfig + var err error + + testSession := session.NewSession() + defer testSession.Cleanup() + client, err = client.WithSession(testSession) + require.NoError(s.T(), err) + + if strings.Contains(clusterType, "Custom") { + providers = provisioningConfig.NodeProviders + } else if strings.Contains(clusterType, "Airgap") { + providers = []string{"Corral"} + } else { + providers = provisioningConfig.Providers + } + + for _, nodeProviderName := range providers { + + nodeProvider, rke1Provider, customProvider, kubeVersions := GetClusterProvider(clusterType, nodeProviderName, provisioningConfig) + + for _, kubeVersion := range kubeVersions { + for _, cni := range provisioningConfig.CNIs { + + testClusterConfig = clusters.ConvertConfigToClusterConfig(provisioningConfig) + testClusterConfig.CNI = cni + name = testNamePrefix + " Node Provider: " + nodeProviderName + " Kubernetes version: " + kubeVersion + " cni: " + cni + + clusterObject := &steveV1.SteveAPIObject{} + rke1ClusterObject := &management.Cluster{} + nodeTemplate := &nodetemplates.NodeTemplate{} + + s.Run(name, func() { + if testClusterConfig.CloudProvider == provisioninginput.AWSProviderName.String() { + byteYaml, err := os.ReadFile(outOfTreeAWSFilePath) + require.NoError(s.T(), err) + testClusterConfig.AddOnConfig = &provisioninginput.AddOnConfig{ + AdditionalManifest: string(byteYaml), + } + } + + switch clusterType { + case RKE2ProvisionCluster, K3SProvisionCluster: + testClusterConfig.KubernetesVersion = kubeVersion + clusterObject, err = provisioning.CreateProvisioningCluster(client, *nodeProvider, testClusterConfig, hostnameTruncation) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyCluster(s.T(), client, testClusterConfig, clusterObject) + + case RKE1ProvisionCluster: + testClusterConfig.KubernetesVersion = kubeVersion + nodeTemplate, err = rke1Provider.NodeTemplateFunc(client) + require.NoError(s.T(), err) + // workaround to simplify config for rke1 clusters with cloud provider set. This will allow external charts to be installed + // while using the rke2 CloudProvider. + if testClusterConfig.CloudProvider == provisioninginput.VsphereCloudProviderName.String() { + testClusterConfig.CloudProvider = "external" + } + + rke1ClusterObject, err = provisioning.CreateProvisioningRKE1Cluster(client, *rke1Provider, testClusterConfig, nodeTemplate) + reports.TimeoutRKEReport(rke1ClusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyRKE1Cluster(s.T(), client, testClusterConfig, rke1ClusterObject) + + case RKE2CustomCluster, K3SCustomCluster: + testClusterConfig.KubernetesVersion = kubeVersion + + clusterObject, err = provisioning.CreateProvisioningCustomCluster(client, customProvider, testClusterConfig) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyCluster(s.T(), client, testClusterConfig, clusterObject) + + case RKE1CustomCluster: + testClusterConfig.KubernetesVersion = kubeVersion + // workaround to simplify config for rke1 clusters with cloud provider set. This will allow external charts to be installed + // while using the rke2 CloudProvider name in the + if testClusterConfig.CloudProvider == provisioninginput.VsphereCloudProviderName.String() { + testClusterConfig.CloudProvider = "external" + } + + rke1ClusterObject, nodes, err := provisioning.CreateProvisioningRKE1CustomCluster(client, customProvider, testClusterConfig) + reports.TimeoutRKEReport(rke1ClusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyRKE1Cluster(s.T(), client, testClusterConfig, rke1ClusterObject) + etcdVersion, err := componentchecks.CheckETCDVersion(client, nodes, rke1ClusterObject.ID) + require.NoError(s.T(), err) + require.NotEmpty(s.T(), etcdVersion) + + // airgap currently uses corral to create nodes and register with rancher + case RKE2AirgapCluster, K3SAirgapCluster: + testClusterConfig.KubernetesVersion = kubeVersion + clusterObject, err = provisioning.CreateProvisioningAirgapCustomCluster(client, testClusterConfig, corralPackages) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyCluster(s.T(), client, testClusterConfig, clusterObject) + + case RKE1AirgapCluster: + testClusterConfig.KubernetesVersion = kubeVersion + // workaround to simplify config for rke1 clusters with cloud provider set. This will allow external charts to be installed + // while using the rke2 CloudProvider name in the + if testClusterConfig.CloudProvider == provisioninginput.VsphereCloudProviderName.String() { + testClusterConfig.CloudProvider = "external" + } + + clusterObject, err := provisioning.CreateProvisioningRKE1AirgapCustomCluster(client, testClusterConfig, corralPackages) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(s.T(), err) + + provisioning.VerifyRKE1Cluster(s.T(), client, testClusterConfig, clusterObject) + + default: + s.T().Fatalf("Invalid cluster type: %s", clusterType) + } + + RunPostClusterCloudProviderChecks(s.T(), client, clusterType, nodeTemplate, testClusterConfig, clusterObject, rke1ClusterObject) + }) + } + } + } +} + +// RunPostClusterCloudProviderChecks does additinal checks on the cluster if there's a cloud provider set +// on an active cluster. +func RunPostClusterCloudProviderChecks(t *testing.T, client *rancher.Client, clusterType string, nodeTemplate *nodetemplates.NodeTemplate, testClusterConfig *clusters.ClusterConfig, clusterObject *steveV1.SteveAPIObject, rke1ClusterObject *management.Cluster) { + if strings.Contains(clusterType, clusters.RKE1ClusterType.String()) { + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + require.NoError(t, err) + + if strings.Contains(testClusterConfig.CloudProvider, provisioninginput.AWSProviderName.String()) { + if strings.Contains(testClusterConfig.CloudProvider, externalProviderString) { + clusterMeta, err := clusters.NewClusterMeta(client, rke1ClusterObject.Name) + require.NoError(t, err) + + err = CreateAndInstallAWSExternalCharts(client, clusterMeta, false) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, rke1ClusterObject.ID) + require.Empty(t, podErrors) + } + + clusterObject, err = adminClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(provisioninginput.Namespace + "/" + rke1ClusterObject.ID) + require.NoError(t, err) + + lbServiceResp := CreateCloudProviderWorkloadAndServicesLB(t, client, clusterObject) + + status := &provv1.ClusterStatus{} + err = steveV1.ConvertToK8sType(clusterObject.Status, status) + require.NoError(t, err) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResp, status.ClusterName) + } else if strings.Contains(testClusterConfig.CloudProvider, "external") { + rke1ClusterObject, err := adminClient.Management.Cluster.ByID(rke1ClusterObject.ID) + require.NoError(t, err) + + if strings.Contains(rke1ClusterObject.AppliedSpec.DisplayName, provisioninginput.VsphereProviderName.String()) { + chartConfig := new(charts.Config) + config.LoadConfig(charts.ConfigurationFileKey, chartConfig) + + err := charts.InstallVsphereOutOfTreeCharts(client, catalog.RancherChartRepo, rke1ClusterObject.Name, !chartConfig.IsUpgradable) + reports.TimeoutRKEReport(rke1ClusterObject, err) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, rke1ClusterObject.ID) + require.Empty(t, podErrors) + + clusterObject, err := adminClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(provisioninginput.Namespace + "/" + rke1ClusterObject.ID) + require.NoError(t, err) + + CreatePVCWorkload(t, client, clusterObject) + } + } + } else if strings.Contains(clusterType, clusters.RKE2ClusterType.String()) { + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + require.NoError(t, err) + + if testClusterConfig.CloudProvider == provisioninginput.AWSProviderName.String() { + clusterObject, err := adminClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterObject.ID) + require.NoError(t, err) + + lbServiceResp := CreateCloudProviderWorkloadAndServicesLB(t, client, clusterObject) + + status := &provv1.ClusterStatus{} + err = steveV1.ConvertToK8sType(clusterObject.Status, status) + require.NoError(t, err) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResp, status.ClusterName) + } + + if testClusterConfig.CloudProvider == provisioninginput.VsphereCloudProviderName.String() { + CreatePVCWorkload(t, client, clusterObject) + } + } +} + +// GetClusterProvider returns a provider object given cluster type, nodeProviderName (for custom clusters) and the provisioningConfig +func GetClusterProvider(clusterType string, nodeProviderName string, provisioningConfig *provisioninginput.Config) (*provisioning.Provider, *provisioning.RKE1Provider, *provisioning.ExternalNodeProvider, []string) { + var nodeProvider provisioning.Provider + var rke1NodeProvider provisioning.RKE1Provider + var customProvider provisioning.ExternalNodeProvider + var kubeVersions []string + + switch clusterType { + case RKE2ProvisionCluster: + nodeProvider = provisioning.CreateProvider(nodeProviderName) + kubeVersions = provisioningConfig.RKE2KubernetesVersions + case K3SProvisionCluster: + nodeProvider = provisioning.CreateProvider(nodeProviderName) + kubeVersions = provisioningConfig.K3SKubernetesVersions + case RKE1ProvisionCluster: + rke1NodeProvider = provisioning.CreateRKE1Provider(nodeProviderName) + kubeVersions = provisioningConfig.RKE1KubernetesVersions + case RKE2CustomCluster: + customProvider = provisioning.ExternalNodeProviderSetup(nodeProviderName) + kubeVersions = provisioningConfig.RKE2KubernetesVersions + case K3SCustomCluster: + customProvider = provisioning.ExternalNodeProviderSetup(nodeProviderName) + kubeVersions = provisioningConfig.K3SKubernetesVersions + case RKE1CustomCluster: + customProvider = provisioning.ExternalNodeProviderSetup(nodeProviderName) + kubeVersions = provisioningConfig.RKE1KubernetesVersions + case K3SAirgapCluster: + kubeVersions = provisioningConfig.K3SKubernetesVersions + case RKE1AirgapCluster: + kubeVersions = provisioningConfig.RKE1KubernetesVersions + case RKE2AirgapCluster: + kubeVersions = provisioningConfig.RKE2KubernetesVersions + default: + panic("Cluster type not found") + } + return &nodeProvider, &rke1NodeProvider, &customProvider, kubeVersions +} + +// CreateCloudProviderWorkloadAndServicesLB creates a test workload, clusterIP service and LoadBalancer service. +// This should be used when testing cloud provider with in-tree or out-of-tree set on the cluster. +func CreateCloudProviderWorkloadAndServicesLB(t *testing.T, client *rancher.Client, cluster *steveV1.SteveAPIObject) *steveV1.SteveAPIObject { + status := &provv1.ClusterStatus{} + + err := steveV1.ConvertToK8sType(cluster.Status, status) + require.NoError(t, err) + + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + require.NoError(t, err) + + steveclient, err := adminClient.Steve.ProxyDownstream(status.ClusterName) + require.NoError(t, err) + + nginxWorkload, err := createNginxDeployment(steveclient, status.ClusterName) + require.NoError(t, err) + + nginxSpec := &appv1.DeploymentSpec{} + err = steveV1.ConvertToK8sType(nginxWorkload.Spec, nginxSpec) + require.NoError(t, err) + + clusterIPserviceName := namegenerator.AppendRandomString(clusterIPPrefix) + clusterIPserviceTemplate := services.NewServiceTemplate(clusterIPserviceName, defaultNamespace, corev1.ServiceTypeClusterIP, []corev1.ServicePort{{Name: portName, Port: 80}}, nginxSpec.Selector.MatchLabels) + _, err = steveclient.SteveType(services.ServiceSteveType).Create(clusterIPserviceTemplate) + require.NoError(t, err) + + lbServiceName := namegenerator.AppendRandomString(loadBalancerPrefix) + lbServiceTemplate := services.NewServiceTemplate(lbServiceName, defaultNamespace, corev1.ServiceTypeLoadBalancer, []corev1.ServicePort{{Name: portName, Port: 80}}, nginxSpec.Selector.MatchLabels) + lbServiceResp, err := steveclient.SteveType(services.ServiceSteveType).Create(lbServiceTemplate) + require.NoError(t, err) + logrus.Info("loadbalancer created for nginx workload.") + + return lbServiceResp +} + +// CreatePVCWorkload creates a workload with a PVC for storage. This helper should be used to test +// storage class functionality, i.e. for an in-tree / out-of-tree cloud provider +func CreatePVCWorkload(t *testing.T, client *rancher.Client, cluster *steveV1.SteveAPIObject) *steveV1.SteveAPIObject { + status := &provv1.ClusterStatus{} + err := steveV1.ConvertToK8sType(cluster.Status, status) + require.NoError(t, err) + + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + require.NoError(t, err) + + steveclient, err := adminClient.Steve.ProxyDownstream(status.ClusterName) + require.NoError(t, err) + + dynamicClient, err := client.GetDownStreamClusterClient(status.ClusterName) + require.NoError(t, err) + + storageClassVolumesResource := dynamicClient.Resource(storageclasses.StorageClassGroupVersionResource).Namespace("") + + ctx := context.Background() + unstructuredResp, err := storageClassVolumesResource.List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + + storageClasses := &v1.StorageClassList{} + + err = scheme.Scheme.Convert(unstructuredResp, storageClasses, unstructuredResp.GroupVersionKind()) + require.NoError(t, err) + + storageClass := storageClasses.Items[0] + + logrus.Infof("creating PVC") + + accessModes := []corev1.PersistentVolumeAccessMode{ + "ReadWriteOnce", + } + + persistentVolumeClaim, err := persistentvolumeclaims.CreatePersistentVolumeClaim( + client, + status.ClusterName, + namegenerator.AppendRandomString("pvc"), + "test-pvc-volume", + defaultNamespace, + 1, + accessModes, + nil, + &storageClass, + ) + require.NoError(t, err) + + pvcStatus := &corev1.PersistentVolumeClaimStatus{} + stevePvc := &steveV1.SteveAPIObject{} + + err = wait.PollUntilContextTimeout(ctx, pollInterval, pollTimeout, true, func(ctx context.Context) (done bool, err error) { + stevePvc, err = steveclient.SteveType(persistentvolumeclaims.PersistentVolumeClaimType).ByID(defaultNamespace + "/" + persistentVolumeClaim.Name) + require.NoError(t, err) + + err = steveV1.ConvertToK8sType(stevePvc.Status, pvcStatus) + require.NoError(t, err) + + if pvcStatus.Phase == persistentvolumeclaims.PersistentVolumeBoundStatus { + return true, nil + } + return false, err + }) + require.NoError(t, err) + + nginxResponse, err := createNginxDeploymentWithPVC(steveclient, "pvcwkld", persistentVolumeClaim.Name, string(stevePvc.Spec.(map[string]interface{})[persistentvolumeclaims.StevePersistentVolumeClaimVolumeName].(string))) + require.NoError(t, err) + + return nginxResponse +} + +// createNginxDeploymentWithPVC is a helper function that creates a nginx deployment in a cluster's default namespace +func createNginxDeploymentWithPVC(steveclient *steveV1.Client, containerNamePrefix, pvcName, volName string) (*steveV1.SteveAPIObject, error) { + logrus.Infof("Vol: %s", volName) + logrus.Infof("Pod: %s", pvcName) + + containerName := namegenerator.AppendRandomString(containerNamePrefix) + volMount := *&corev1.VolumeMount{ + MountPath: "/auto-mnt", + Name: volName, + } + + podVol := corev1.Volume{ + Name: volName, + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: pvcName, + }, + }, + } + + containerTemplate := workloads.NewContainer(nginxName, nginxName, corev1.PullAlways, []corev1.VolumeMount{volMount}, []corev1.EnvFromSource{}, nil, nil, nil) + podTemplate := workloads.NewPodTemplate([]corev1.Container{containerTemplate}, []corev1.Volume{podVol}, []corev1.LocalObjectReference{}, nil) + deployment := workloads.NewDeploymentTemplate(containerName, defaultNamespace, podTemplate, true, nil) + + deploymentResp, err := steveclient.SteveType(workloads.DeploymentSteveType).Create(deployment) + if err != nil { + return nil, err + } + + return deploymentResp, err +} + +// createNginxDeployment is a helper function that creates a nginx deployment in a cluster's default namespace +func createNginxDeployment(steveclient *steveV1.Client, containerNamePrefix string) (*steveV1.SteveAPIObject, error) { + containerName := namegenerator.AppendRandomString(containerNamePrefix) + containerTemplate := workloads.NewContainer(nginxName, nginxName, corev1.PullAlways, []corev1.VolumeMount{}, []corev1.EnvFromSource{}, nil, nil, nil) + podTemplate := workloads.NewPodTemplate([]corev1.Container{containerTemplate}, []corev1.Volume{}, []corev1.LocalObjectReference{}, nil) + deployment := workloads.NewDeploymentTemplate(containerName, defaultNamespace, podTemplate, true, nil) + + deploymentResp, err := steveclient.SteveType(workloads.DeploymentSteveType).Create(deployment) + if err != nil { + return nil, err + } + + return deploymentResp, err +} + +// CreateAndInstallAWSExternalCharts is a helper function for rke1 external-aws cloud provider +// clusters that install the appropriate chart(s) and returns an error, if any. +func CreateAndInstallAWSExternalCharts(client *rancher.Client, cluster *clusters.ClusterMeta, isLeaderMigration bool) error { + steveclient, err := client.Steve.ProxyDownstream(cluster.ID) + if err != nil { + return err + } + + repoName := namegenerator.AppendRandomString(provisioninginput.AWSProviderName.String()) + err = charts.CreateChartRepoFromGithub(steveclient, awsUpstreamCloudProviderRepo, masterBranch, repoName) + if err != nil { + return err + } + + project, err := projects.GetProjectByName(client, cluster.ID, systemProject) + if err != nil { + return err + } + + catalogClient, err := client.GetClusterCatalogClient(cluster.ID) + if err != nil { + return err + } + + latestVersion, err := catalogClient.GetLatestChartVersion(awsUpstreamChartName, repoName) + if err != nil { + return err + } + + installOptions := &charts.InstallOptions{ + Cluster: cluster, + Version: latestVersion, + ProjectID: project.ID, + } + err = charts.InstallAWSOutOfTreeChart(client, installOptions, repoName, cluster.ID, isLeaderMigration) + return err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/README.md new file mode 100644 index 0000000..b5f3f10 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/README.md @@ -0,0 +1,807 @@ +# Private Registries Automation + +- [Private Registries Automation](#private-registries-automation) + - [Jenkins](#jenkins) + - [Infrastructure](#infrastructure) + - [Test Setup - the use  of Corral Packages](#test-setup---the-use-of-corral-packages) + - [Jenkins job RANCHER\_CORRAL\_CONFIG](#jenkins-job-rancher_corral_config) + - [Jenkins job REGISTRIES\_CORRAL\_CONFIG](#jenkins-job-registries_corral_config) + - [Jenkins job \*BRANCH\* and \*REPO\* variables](#jenkins-job-branch-and-repo-variables) + - [Manual steps that are done automatically by the Pipeline and Test Setup](#manual-steps-that-are-done-automatically-by-the-pipeline-and-test-setup) + - [Test Setup Result either manual or automated](#test-setup-result-either-manual-or-automated) + - [The information about the Private Registries and Rancher is ready to be used by Go](#the-information-about-the-private-registries-and-rancher-is-ready-to-be-used-by-go) + - [Go environment setup and validations](#go-environment-setup-and-validations) + - [Flags](#flags) + - [The registries configuration in CONFIG](#the-registries-configuration-in-config) + - [The Corral Variables configuration in CONFIG](#the-corral-variables-configuration-in-config) + - [The Go Corral client will use the packages to retrieve the information needed for the Go Validations](#the-go-corral-client-will-use-the-packages-to-retrieve-the-information-needed-for-the-go-validations) + - [ The provisioningInput used for the downstream clusters in CONFIG](#the-provisioninginput-used-for-the-downstream-clusters-in-config) + - [Considerations for Testing or Debug ^^^ IMPORTANT ^^^](#considerations-for-testing-or-debug--important-) + - [USE CASE](#use-case) + +## Jenkins + +Information about Jenkins is in our Internal Documentation + +## Infrastructure + +The automation is divided in two Repositories. + +- Corral - rancherlabs/corral-packages +- Rancher / Go tests - rancher/rancher + +### Test Setup - the use  of Corral Packages + +The Corral takes care of creating the Private Registries and the Rancher +setup. + +These configurations and tests are mapped for the release testing test cases. Scroll down to the +Registries table's rows. + +We need two Corral Package Configurations + +1. To create the two standalone registries for the Downstream + Clusters - `Auth`  and  `No Auth` + 1. Or if using the `UseExistingRegistries` flag in the main Go + framework `CONFIG` file do not use the package and use the + existing registries configuration + 2. This will create two standalone Private Registries, those will + be hosted on two standalone nodes, all the registries use Valid + Certs. - Certificate values are set as base64 strings in + `CONFIG` + 3. The Registry Standalone package is used for + this. - The values should match the `rancher-version` under test +2. A second Package to Install Rancher with a standalone Private + Registry for it. - Rancher with Registry package configuration with + values updated to required versions + 1. If the `UseExistingRegistries` flag is set in `CONFIG` use an + existing Rancher install without using the Corral package + 2. Or use the Corral Package for a Rancher without Registry + 3. Rancher install in both cases use Rancher `self-signed` certs - + No config needed for certs +3. An existing ECR registry will be configured to use the registry + images specific to the Rancher version set in the Rancher with Registry package's + 1. `A registry-auth` with a value included as `ecr`  will create + the config for the ECR creation logic. + +The cert manager version for the Rancher `self-signed` certificates +install is also configured in the Rancher Corral packages and the images +pushed to the registry. This is a mandatory dependency for this type of +install. + +The default install of the Rancher packages use an RKE2 cluster. This is +the only option so far in Corral Packages. + +- It is important that the `kubernetes_version` match the RKE2 cluster + image included in the Rancher's `rancher-images.txt` + - `rancher-images.txt` can be found in the Github release page of + the Rancher version. + - example: + https://github.com/rancher/rancher/releases/tag/v2.7.5 + Scrolling down to the assets. This file is important for setting + all the provisioning versions in the `CONFIG`  file too. + +### Jenkins job RANCHER_CORRAL_CONFIG + +The Corral package yaml values to build Rancher. Example: + +Reminder that the `kubernetes_version`  must match with versions +existing in `rancher-images.txt` of the Rancher version under test. + +``` yml +manifest: + name: rancher-registry + description: rancher-registry + variables: + registry_auth: + default: enabled +templates: + - aws/cluster_nodes + - aws/registry_nodes + - registry-standalone + - rke2 + - rancher +variables: + cni: + - calico + kubernetes_version: + - v1.23.10+rke2r1 + - v1.24.4+rke2r1 + registry_auth: + - global + docker_compose_version: + - 2.15.1 + rancher_version: + - 2.7.0 + cert_manager_version: + - 1.11.0 +``` + +### Jenkins job REGISTRIES_CORRAL_CONFIG + +``` yml +manifest: + name: registry + description: registry + variables: + registry_auth: + default: enabled +templates: + - aws/registry_nodes + - registry-standalone +variables: + registry_auth: + - global + - enabled + - disabled + - ecr + docker_compose_version: + - 2.15.1 + rancher_version: + - 2.7.0 + cert_manager_version: + - 1.11.0 +``` + +``` java +awsCredentials: + accessKey: + defaultRegion: us-east-2 + secretKey: +awsEC2Config: + awsAMI: + awsAccessKeyID: + awsCICDInstanceTag: rancher-validation + awsIAMProfile: "" + awsRegionAZ: "" + awsSSHKeyName: + awsSecretAccessKey: + awsSecurityGroups: + - + awsUser: ubuntu + instanceType: t3a.xlarge + region: us-east-2 + volumeSize: 50 +awsMachineConfig: + instanceType: t3a.xlarge + region: us-east-2 + retries: "5" + rootSize: "16" + securityGroup: + - open-all + sshUser: ubuntu + volumeType: gp3 + vpcId: + zone: a +awsNodeTemplate: + accessKey: + ami: + blockDurationMinutes: 0 + encryptEbsVolume: false + endpoint: "" + httpEndpoint: enabled + httpTokens: optional + iamInstanceProfile: + insecureTransport: false + instanceType: t3a.xlarge + keypairName: + kmsKey: "" + monitoring: false + privateAddressOnly: false + region: us-west-1 + requestSpotInstance: true + retries: 5 + rootSize: 50 + secretKey: + securityGroup: + - allopen-dualstack + securityGroupReadonly: false + sessionToken: "" + spotPrice: 0.5 + sshKeyContents: "" + sshUser: ubuntu + subnetId: + tags: "" + type: amazonec2Config + useEbsOptimizedInstance: false + usePrivateAddress: false + userdata: "" + volumeType: gp3 + vpcId: + zone: b +corralConfigs: + corralConfigUser: izaac + corralConfigVars: + agent_count: 1 + aws_access_key: + aws_ami: + aws_domain: + aws_hostname_prefix: example1 + aws_ipv6_80_target_group_arn: + aws_ipv6_443_target_group_arn: + aws_region: us-west-1 + aws_route53_zone: + aws_secret_key: + aws_security_group: + aws_ssh_user: ubuntu + aws_subnet: + aws_vpc: + aws_zone_id: + instance_type: t3a.xlarge + registry_cert: < BASE64 of certificate from the QA certs confluence doc > + registry_ecr_fqdn: .dkr.ecr.us-west-1.amazonaws.com + registry_key: < BASE64 of certificate key from the QA certs confluence doc > + server_count: 3 + corralSSHPath: /Users/izaac/.ssh/id_rsa.pub +corralPackages: + corralPackageImages: + # THESE paths will depend on the versions configured in the corral RANCHER and REGISTRY packages yaml config variables. + # The /root/go/src/github.com/rancherlabs/corral-packages comes from the Dockerfile image + corralecr: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-ecr-2.15.1-2.7.7-rc4-1.11.0 + rancherha: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-aws-registry-standalone-rke2-rancher-calico-v1.24.16-rke2r1-global-2.15.1-2.7.7-rc4-1.11.0 + registryauthdisabled: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-disabled-2.15.1-2.7.7-rc4-1.11.0 + registryauthenabled: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-enabled-2.15.1-2.7.7-rc4-1.11.0 + hasCleanup: false + hasDebug: true +corralRancherHA: + name: rancherha +flags: + # when there is expected for the automation to create the registries + # desiredflags should be desiredflags: InstallRancher without UseExistingRegistries + desiredflags: UseExistingRegistries +provisioningInput: + cni: + - calico + k3sKubernetesVersion: + - v1.25.12-k3s1 + nodeProviders: + - ec2 + nodesAndRoles: + - controlplane: true + etcd: true + quantity: 1 + worker: true + nodesAndRolesRKE1: + - controlplane: true + etcd: true + quantity: 3 + worker: true + providers: + - aws + rke1KubernetesVersion: + - v1.25.12-rancher1 + rke2KubernetesVersion: + - v1.24.16-rke2r1 +rancher: + host: izrancher7.qa.rancher.space + adminToken: < Automatically generated if the UseExistingRegistries flag is not set > + adminPassword: + insecure: true + cleanup: true + caFile: "" + caCerts: "" + clusterName: auto-noauthregcluster-ezgrq + shellImage: "" +registries: + existingAuthRegistry: # Configuration for existing auth registry (optional) + password: + url: + username: corral + ecrRegistryConfig: # Configuration for existing ecr registry (optional) + url: .dkr.ecr.us-west-1.amazonaws.com + password: + awsAccessKeyId: + awsSecretAccessKey: + existingNoAuthRegistry: + registryConfigNames: + - registryauthdisabled + - registryauthenabled + - corralecr +sshPath: + sshPath: /go/src/github.com/rancher/rancher/tests/v2/validation/.ssh +``` + +### Jenkins job \*BRANCH\* and \*REPO\* variables + +These variables can be modified if there's the need to use forked +repositories used for testing + +### Manual steps that are done automatically by the Pipeline and Test Setup + +The manual steps done by the GoLang framework section does in the test +suite is: + +- clone the `corral-packages` repo +- Grab the yaml configurations retrieved from the Pipeline + configuration parameters +- In the `corral-packages` repository directory do the following + - `rm -rf dist`  this is not done as this directory doesn't exist. + But this is for manual steps on a local machine. + - `make build` this will generate the corral package images with + the values set in the corral packages +- Start executing `corral create --debug ` on + each package required by the Golang registries test. +- Get the corral vars values and set these into the *CONFIG* yaml if + applicable +- Execute the Golang tests + +The setup at this point will look like the following: + +### Test Setup Result either manual or automated + +**The generated Rancher package and the Registry Standalone packages +`rancher_version` must match** + +- Registry with Auth with images set in `rancher_version` variable of + the `registry-standalone`  corral package +- Registry without Auth with images set in `rancher_version` variable + of the `registry-standalone`  corral package +- ECR Registry configured for the `rancher_version` too +- A global registry without Auth for the Rancher install. - This + depends on if the RANCHER corral package has a registry configured. + +All of the above should be pre-existing if running the tests with the +`UseExistingRegistries` flag. The configuration information should also +exist in `CONFIG` if this is the case. Below the *registries* key. + +``` java +registries: + existingAuthRegistry: # Configuration for existing auth registry (optional) + password: < + url: + username: corral # corral is the default user in the registry-standalone corral package + ecrRegistryConfig: # Configuration for existing ecr registry (optional) + url: .dkr.ecr.us-west-1.amazonaws.com + password: + awsAccessKeyId: + awsSecretAccessKey: + existingNoAuthRegistry: +``` + +### The information about the Private Registries and Rancher is ready to be used by Go + +The variables information is stored on each Corral Package and ready to +be used using the Go Corral client configure the needed information for +the tests to run and validate. + +The information includes and is automatically taken from the corral vars +by the corral client + +Registry Standalone Package + +- Private Registry fqdn, user and password if is a registry with auth + - Or just the registry fqdn user if the private registry is No + Auth +- Private Registry hosts/fqdn +- ECR - The user is always `AWS`, the CER fqdn and the ECR password + +Ranche Registry package values configured in `CONFIG` and used for the +client login and the information set for the global registry if Rancher +use a Registry + +- Rancher global registry fqdn +- The Rancher global registry is an empty string based in the Global + Registry configuration value get by the test setup. + - This is when using a Rancher Corral Package without a private + registry + +**These configuration variables keys in `CONFIG` is described in a +section below.** + +## Go environment setup and validations + +### Flags + +These flags will determine some of the main logic depending on the setup +infrastructure used for the tests + +``` yml +flags: + desiredflags: UseExistingRegistries, InstallRancher +``` + +In the example above all the registries infrastructure needed is +existing and Rancher is installed by automation. + +``` yml +flags: + desiredFlags: InstallRancher +``` + +All registries as built by Automation and also Rancher. + +``` yml +flags: + desiredFlags: UseExistingRegistries +``` + +In the example above all the registries infrastructure needed is +existing and Rancher is also pre-existing + +In this case the `rancher` section in `CONFIG` must be manually set. As +well as the `registries` section. + +``` yml +rancher: + host: + adminToken: + adminPassword: + insecure: true + cleanup: true +``` + +### The registries configuration in CONFIG + +Most of these values are automatically retrieved by the Corral client +when not using the `UseRegistries`  flag. + +If using the `UseRegistries` flag all the information below is needed. + +``` yml +registries: + existingAuthRegistry: + password: + url: + username: corral + ecrRegistryConfig: + url: .dkr.ecr.us-west-1.amazonaws.com + password: + awsAccessKeyId: + awsSecretAccessKey: + existingNoAuthRegistry: + registryConfigNames: + - registryauthdisabled + - registryauthenabled + - registryecr +``` + +### The Corral Variables configuration in CONFIG + +These values are needed to generate the corral images configurations to +setup the RKE2 nodes, target groups, load balancer, route53 domain +registry and the registry nodes. + +As well as the ECR fqdn. + +``` yml +corralConfigs: + corralConfigUser: izaac + corralConfigVars: + agent_count: 1 + aws_access_key: + aws_ami: + aws_domain: + aws_hostname_prefix: example1 + aws_ipv6_80_target_group_arn: + aws_ipv6_443_target_group_arn: + aws_region: us-west-1 + aws_route53_zone: + aws_secret_key: + aws_security_group: + aws_ssh_user: ec2-user + aws_subnet: + aws_vpc: + aws_zone_id: + instance_type: t3a.xlarge + registry_cert: + registry_key: + registry_ecr_fqdn: .dkr.ecr.us-west-1.amazonaws.com + server_count: 3 +``` + +### The Go Corral client will use the packages to retrieve the information needed for the Go Validations + +`CONFIG`  section example of the Corral Package Images. + +This should match the directory names generated by the `make build` +command in the `corral-packages`  repo. + +- `rancherha`  is the Rancher package +- registryauthdisabled is the Registry without Auth +- registryauthenabled is the Registry with Auth +- corralecr is the ECR registry + +The Global Registry is not needed as this is set in the `rancherha` +package configuration. + +The versions configured on all packages must match. + +- `rancher_version` +- cert_manager_version +- the `kubernetes_version`  must match with an RKE2 kubernetes version + included in `rancher-images.txt` + +``` yml +corralPackages: + cleanup: false + corralPackageImages: + rancherha: /root/src/github.com/rancherlabs/corral-packages/dist/aws-aws-registry-standalone-rke2-rancher-calico-v1.23.10-rke2r1-global-2.15.1-2.7.0-1.11.0 + registryauthdisabled: /root/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-disabled-2.15.1-2.7.0-1.11.0 + registryauthenabled: /root/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-enabled-2.15.1-2.7.0-1.11.0 + corralecr: /root/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-ecr-2.15.1-2.7.0-1.11.0 +``` + +The above paths should exist in the test container. + +###  The provisioningInput used for the downstream clusters in CONFIG + +All the kubernetes version should match with the included in +`rancher-images.txt` + +``` yml +provisioningInput: + cni: + - calico + k3sKubernetesVersion: + - v1.24.7+k3s1 + nodeProviders: + - ec2 + nodesAndRoles: + - controlplane: true + etcd: true + quantity: 1 + worker: true + nodesAndRolesRKE1: + - controlplane: true + etcd: true + quantity: 3 + worker: true + providers: + - aws + rke1KubernetesVersion: + - v1.23.12-rancher1-1 + rke2KubernetesVersion: + - v1.24.7+rke2r1 +``` + +## Considerations for Testing or Debug ^^^ IMPORTANT ^^^ + +- Check All the versions for the different components used for the + `rancher_version`  under test must have images in the + `rancher-images.txt` file in the Rancher Release page for the + version under test. +- If there was a KDM update after the `rancher_version` under test was + released and a different or newer `kubernetes_version` is used. + - We must add the `rke-tools` images that match the + `kubernetes_version` manually in the registries. + - This information can be found in the KDM code + - It is recommended to do this using the `UseExistingRegistries` + flag in CONFIG + - Create registries with the standalone-registry corral + package and use the existing registries flag in CONFIG +- To debug if the `corralPackageImages` filesystem path values in + CONFIG are correct this can be debugged by editing + `setup_environment.sh` in `tests/v2/validation/pipeline/scripts` + - This is in the `rancher/rancher` repo + - Adding a directory list ( ls ) command after the line: + `sh tests/v2/validation/pipeline/scripts/build_corral_packages.sh` + - `For example: ls /root/src/github.com/rancherlabs/corral-packages/dist` +- If the `Jenkinsfile.e2e`  needs some update as part of a code + change. In order to test the changes the repo url and branch should + be changes to the fork's url and branch. In the Job setting not the + job variables. + +## USE CASE + +Configuration for testing Rancher +v2.7.1 + +- Collect the `rancher-images.txt`  from the Rancher release page for + that version. +- Analyze the RKE2, K3s, RKE1 kubernetes versions to configure + RANCHER_CORRAL_CONFIG and CONFIG versions + - Example RKE1 - hyperkube:v1.24.9-rancher1 + - Search the KDM to obtain the exact version string + for that image. + - This result in `v1.24.9-rancher1-1` + - Example RKE2 - rke2-runtime:v1.23.13-rke2r1 + - Results in: `v1.23.13-rke2r1` + - Example K3s - system-agent-installer-k3s:v1.23.15-k3s1 + - Results in: `v1.23.15-k3s1` + +With the k8s versions under tests are identified it's time to configure +the YAML configurations. + +RANCHER_CORRAL_CONFIG + +The Rancher deployment only works with RKE2 as per the current corral +package support. The kubernetes_version should be an RKE2 and make sure +it is added with a + not a - before the suffix. + +- `v1.23.13-rke2r1` NO +- `v1.23.13+rke2r1` YES + +*This configuration can be used to create registries before automation +is executed. This can save time for multiple runs by using the +UseExistingRegistries flag. In that case this YAML with be ignored by +the Jenkins run. +* + +``` java +manifest: + name: rancher-registry + description: rancher-registry + variables: + registry_auth: + default: enabled +templates: + - aws/cluster_nodes + - aws/registry_nodes + - registry-standalone + - rke2 + - rancher +variables: + cni: + - calico + kubernetes_version: + - v1.23.13+rke2r1 + registry_auth: + - global + docker_compose_version: + - 2.15.1 + rancher_version: + - 2.7.1 + cert_manager_version: + - 1.11.0 +``` + +That will create a corral image folder: +aws-aws-registry-standalone-rke2-rancher-calico-v1.23.13-rke2r1-global-2.15.1-2.7.1-1.11.0 + +REGISTRIES_CORRAL_CONFIG + +We only need the Rancher version here and update docker compose and +cert-manager as needed. + +*This configuration can be used to create registries before automation +is executed. This can save time for multiple runs by using the +UseExistingRegistries flag. In that case this YAML with be ignored by +the Jenkins run.* + +``` java +manifest: + name: registry + description: registry + variables: + registry_auth: + default: enabled +templates: + - aws/registry_nodes + - registry-standalone +variables: + registry_auth: + - global + - enabled + - disabled + - ecr + docker_compose_version: + - 2.15.1 + rancher_version: + - 2.7.1 + cert_manager_version: + - 1.11.0 +``` + +CONFIG + +This is an excerpt of the configuration options that need an update to +match the above configuration values. + +The `corralPackageImages` are basically folders that reflect the corral +package variables values in their name. This must change to match the +expected folder name for the configuration of RANCHER_CORRAL_CONFIG and +REGISTRIES_CORRAL_CONFIG + +The below code give an example based on the previous configurations. + +The `provisioningInput`  configuration block is also very important for +the downstream clusters provisioning for testing. The Kubernetes +versions must exist in the rancher-images.txt like the RKE2 one used for +the Rancher package and checked in KDM. + +For this example on `v2.7.1` the kubernetes versions in the +`provisioningInput` were confirmed they exist in the rancher-images.txt + +The values in the `registries`  block are optional but needed if the +`UseExistingRegistries`  flag is used in CONFIG + +- existingAuthRegistry +- existingNoAuthRegistry + +ecrRegistryConfig is needed for RKE1 ecr tests. + +``` java + corralPackages: + corralPackageImages: + # THESE paths will depend on the versions configured in the corral RANCHER and REGISTRY packages yaml config variables. + # The /root/go/src/github.com/rancherlabs/corral-packages comes from the Dockerfile image + corralecr: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-ecr-2.15.1-2.7.1-1.11.0 + rancherha: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-aws-registry-standalone-rke2-rancher-calico-v1.23.13-rke2r1-global-2.15.1-2.7.1-1.11.0 + registryauthdisabled: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-disabled-2.15.1-2.7.1-1.11.0 + registryauthenabled: /root/go/src/github.com/rancherlabs/corral-packages/dist/aws-registry-standalone-enabled-2.15.1-2.7.1-1.11.0 + hasCleanup: false + hasDebug: true +corralRancherHA: + name: rancherha +flags: + # when there is expected for the automation to create the registries + # desiredflags should be desiredflags: InstallRancher without UseExistingRegistries + desiredflags: UseExistingRegistries +provisioningInput: + cni: + - calico + k3sKubernetesVersion: + - v1.23.15-k3s1  + nodeProviders: + - ec2 + nodesAndRoles: + - controlplane: true + etcd: true + quantity: 1 + worker: true + nodesAndRolesRKE1: + - controlplane: true + etcd: true + quantity: 3 + worker: true + providers: + - aws + rke1KubernetesVersion: + - v1.24.9-rancher1-1  + rke2KubernetesVersion: + - v1.23.13-rke2r1  +rancher: + host: izrancher7.qa.rancher.space + adminToken: < Automatically generated if the UseExistingRegistries flag is not set > + adminPassword: + insecure: true + cleanup: true + caFile: "" + caCerts: "" + clusterName: auto-noauthregcluster-ezgrq + shellImage: "" +registries: + existingAuthRegistry: # Configuration for existing auth registry (optional) + password: e04090bb395d + url: + username: corral + ecrRegistryConfig: # Configuration for existing ecr registry (optional) + url: .dkr.ecr.us-west-1.amazonaws.com + password: + awsAccessKeyId: + awsSecretAccessKey: + existingNoAuthRegistry: + registryConfigNames: + - registryauthdisabled + - registryauthenabled + - corralecr +``` + +GOTEST_TESTCASE + +This Jenkins job variable allows to run an specific test in the test +suite. By default it runs everything + +- -run ^TestRegistryTestSuite$ + +But that can be narrowed to an specific, for example K3S only + +- -run ^TestRegistryTestSuite/TestRegistryK3S$ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/config.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/config.go new file mode 100644 index 0000000..b7bea1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/config.go @@ -0,0 +1,24 @@ +package registries + +const RegistriesConfigKey = "registries" + +type ExistingAuthRegistryConfig struct { + Username string `json:"username" yaml:"username" default:""` + Password string `json:"password" yaml:"password" default:""` + URL string `json:"url" yaml:"url" default:""` +} + +type ECRRegistryConfig struct { + Username string `json:"username" yaml:"username" default:"AWS"` + Password string `json:"password" yaml:"password" default:""` + URL string `json:"url" yaml:"url" default:""` + AwsAccessKeyID string `json:"awsAccessKeyId" yaml:"awsAccessKeyId" default:""` + AwsSecretAccessKey string `json:"awsSecretAccessKey" yaml:"awsSecretAccessKey" default:""` +} + +type Registries struct { + RegistryConfigNames []string `json:"registryConfigNames" yaml:"registryConfigNames" default:"[]"` + ExistingNoAuthRegistryURL string `json:"existingNoAuthRegistry" yaml:"existingNoAuthRegistry" default:""` + ExistingAuthRegistryInfo *ExistingAuthRegistryConfig `json:"existingAuthRegistry" yaml:"existingAuthRegistry" default:""` + ECRRegistryConfig *ECRRegistryConfig `json:"ecrRegistryConfig" yaml:"ecrRegistryConfig" default:""` +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/registry_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/registry_test.go new file mode 100644 index 0000000..7589e71 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/registries/registry_test.go @@ -0,0 +1,397 @@ +//go:build validation + +package registries + +import ( + "testing" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/corral" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + provisioning "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/registries" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + corralRancherName = "rancherha" + corralAuthDisabledName = "registryauthdisabled" + corralAuthEnabledName = "registryauthenabled" + corralEcr = "corralecr" + systemRegistry = "system-default-registry" + namespace = "fleet-default" +) + +type RegistryTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clusterLocalID string + localClusterGlobalRegistryHost string + rancherUsesRegistry bool + provisioningConfig *provisioninginput.Config + privateRegistriesAuth []management.PrivateRegistry + privateRegistriesNoAuth []management.PrivateRegistry + privateEcr []management.PrivateRegistry +} + +func (rt *RegistryTestSuite) TearDownSuite() { + rt.session.Cleanup() +} + +func (rt *RegistryTestSuite) SetupSuite() { + testSession := session.NewSession() + rt.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(rt.T(), err) + rt.client = client + + corralConfig := corral.Configurations() + registriesConfig := new(Registries) + config.LoadConfig(RegistriesConfigKey, registriesConfig) + + err = corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(rt.T(), err) + configPackage := corral.PackagesConfig() + + globalRegistryFqdn := "" + registryDisabledFqdn := "" + registryEnabledUsername := "" + registryEnabledPassword := "" + registryEnabledFqdn := "" + ecrRegistryFqdn := "" + ecrRegistryAwsAccessKey := "" + ecrRegistryAwsSecretKey := "" + ecrRegistryPassword := "" + + useRegistries := client.Flags.GetValue(environmentflag.UseExistingRegistries) + logrus.Infof("The value of useRegistries is %t", useRegistries) + + if !useRegistries { + for _, name := range registriesConfig.RegistryConfigNames { + path := configPackage.CorralPackageImages[name] + logrus.Infof("PATH: %s", path) + + _, err = corral.CreateCorral(testSession, name, path, true, configPackage.HasCleanup) + if err != nil { + logrus.Errorf("error creating corral: %v", err) + } + } + registryDisabledFqdn, err = corral.GetCorralEnvVar(corralAuthDisabledName, "registry_fqdn") + require.NoError(rt.T(), err) + logrus.Infof("RegistryNoAuth FQDN %s", registryDisabledFqdn) + registryEnabledUsername, err = corral.GetCorralEnvVar(corralAuthEnabledName, "registry_username") + require.NoError(rt.T(), err) + logrus.Infof("RegistryAuth Username %s", registryEnabledUsername) + registryEnabledPassword, err = corral.GetCorralEnvVar(corralAuthEnabledName, "registry_password") + require.NoError(rt.T(), err) + logrus.Infof("RegistryAuth Password %s", registryEnabledPassword) + registryEnabledFqdn, err = corral.GetCorralEnvVar(corralAuthEnabledName, "registry_fqdn") + require.NoError(rt.T(), err) + logrus.Infof("RegistryAuth FQDN %s", registryEnabledFqdn) + ecrRegistryFqdn, err = corral.GetCorralEnvVar(corralEcr, "registry_ecr_fqdn") + require.NoError(rt.T(), err) + logrus.Infof("Registry ECR FQDN %s", ecrRegistryFqdn) + ecrRegistryAwsAccessKey, err = corral.GetCorralEnvVar(corralEcr, "aws_access_key") + require.NoError(rt.T(), err) + logrus.Infof("Registry ECR Access Key %s", ecrRegistryAwsAccessKey) + ecrRegistryAwsSecretKey, err = corral.GetCorralEnvVar(corralEcr, "aws_secret_key") + require.NoError(rt.T(), err) + logrus.Infof("Registry ECR Secret Key %s", ecrRegistryAwsSecretKey) + ecrRegistryPassword, err = corral.GetCorralEnvVar(corralEcr, "registry_password") + require.NoError(rt.T(), err) + logrus.Infof("Registry ECR Password %s", ecrRegistryPassword) + + } else { + logrus.Infof("Using Existing Registries because value of useRegistries is %t", useRegistries) + registryDisabledFqdn = registriesConfig.ExistingNoAuthRegistryURL + registryEnabledFqdn = registriesConfig.ExistingAuthRegistryInfo.URL + registryEnabledUsername = registriesConfig.ExistingAuthRegistryInfo.Username + registryEnabledPassword = registriesConfig.ExistingAuthRegistryInfo.Password + ecrRegistryFqdn = registriesConfig.ECRRegistryConfig.URL + ecrRegistryAwsAccessKey = registriesConfig.ECRRegistryConfig.AwsAccessKeyID + ecrRegistryAwsSecretKey = registriesConfig.ECRRegistryConfig.AwsSecretAccessKey + ecrRegistryPassword = registriesConfig.ECRRegistryConfig.Password + logrus.Infof("Registry ECR FQDN %s", ecrRegistryFqdn) + logrus.Infof("Registry ECR Access Key %s", ecrRegistryAwsAccessKey) + logrus.Infof("Registry ECR Secret Key %s", ecrRegistryAwsSecretKey) + logrus.Infof("Registry ECR Password %s", ecrRegistryPassword) + logrus.Infof("RegistryNoAuth FQDN %s", registryDisabledFqdn) + logrus.Infof("RegistryAuth Username %s", registryEnabledUsername) + logrus.Infof("RegistryAuth Password %s", registryEnabledPassword) + logrus.Infof("RegistryAuth FQDN %s", registryEnabledFqdn) + } + + rt.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, rt.provisioningConfig) + + rt.rancherUsesRegistry = false + listOfCorrals, err := corral.ListCorral() + require.NoError(rt.T(), err) + _, corralExist := listOfCorrals[corralRancherName] + if corralExist { + globalRegistryFqdn, err = corral.GetCorralEnvVar(corralRancherName, "registry_fqdn") + require.NoError(rt.T(), err) + if globalRegistryFqdn != "" { + rt.rancherUsesRegistry = true + logrus.Infof("Rancher Global Registry FQDN %s", globalRegistryFqdn) + } + logrus.Infof("Rancher was built using corral: %t", corralExist) + logrus.Infof("Is Rancher using a global registry: %t", rt.rancherUsesRegistry) + } else { + var isSystemRegistrySet bool + registry, err := client.Management.Setting.ByID(systemRegistry) + require.NoError(rt.T(), err) + + if registry.Value != "" { + isSystemRegistrySet = true + } + + if useRegistries && isSystemRegistrySet { + globalRegistryFqdn = registry.Value + rt.rancherUsesRegistry = true + logrus.Infof("Rancher was built using corral: %t", corralExist) + logrus.Infof("Is Rancher using a global registry: %t", rt.rancherUsesRegistry) + logrus.Infof("Rancher Global Registry FQDN %s", globalRegistryFqdn) + } else { + rt.rancherUsesRegistry = false + logrus.Infof("Rancher was built using corral: %t", corralExist) + logrus.Infof("Is Rancher using a global registry: %t", rt.rancherUsesRegistry) + } + } + + privateRegistry := management.PrivateRegistry{} + privateRegistry.URL = registryDisabledFqdn + privateRegistry.IsDefault = true + privateRegistry.Password = "" + privateRegistry.User = "" + rt.privateRegistriesNoAuth = append(rt.privateRegistriesNoAuth, privateRegistry) + + privateRegistry = management.PrivateRegistry{} + privateRegistry.URL = registryEnabledFqdn + privateRegistry.IsDefault = true + privateRegistry.Password = registryEnabledPassword + privateRegistry.User = registryEnabledUsername + rt.privateRegistriesAuth = append(rt.privateRegistriesAuth, privateRegistry) + + rt.clusterLocalID = "local" + rt.localClusterGlobalRegistryHost = globalRegistryFqdn + + ECRCredentialPlugin := &management.ECRCredentialPlugin{ + AwsAccessKeyID: ecrRegistryAwsAccessKey, + AwsSecretAccessKey: ecrRegistryAwsSecretKey, + } + privateRegistry = management.PrivateRegistry{} + privateRegistry.URL = ecrRegistryFqdn + privateRegistry.IsDefault = true + privateRegistry.Password = ecrRegistryPassword + privateRegistry.User = "AWS" + rt.privateEcr = append(rt.privateEcr, privateRegistry) + rt.privateEcr[0].ECRCredentialPlugin = ECRCredentialPlugin +} + +func (rt *RegistryTestSuite) TestRegistriesRKE() { + subSession := session.NewSession() + defer subSession.Cleanup() + + subClient, err := rt.client.WithSession(subSession) + require.NoError(rt.T(), err) + + tests := []struct { + registry []management.PrivateRegistry + name string + }{ + {rt.privateRegistriesNoAuth, "RKE1 Registry No Auth"}, + {rt.privateRegistriesAuth, "RKE1 Registry Auth"}, + {rt.privateEcr, "RKE1 Registry ECR"}, + } + + for _, tt := range tests { + rt.Run(tt.name, func() { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.RKE1KubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + + if testConfig.Registries == nil { + testConfig.Registries = &provisioninginput.Registries{} + } + testConfig.Registries.RKE1Registries = tt.registry + _, rke1Provider, _, _ := permutations.GetClusterProvider(permutations.RKE1ProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + + nodeTemplate, err := rke1Provider.NodeTemplateFunc(subClient) + require.NoError(rt.T(), err) + clusterObject, err := provisioning.CreateProvisioningRKE1Cluster(subClient, *rke1Provider, testConfig, nodeTemplate) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyRKE1Cluster(rt.T(), subClient, testConfig, clusterObject) + }) + } + + if rt.rancherUsesRegistry { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.RKE1KubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + + _, rke1Provider, _, _ := permutations.GetClusterProvider(permutations.RKE1ProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + + nodeTemplate, err := rke1Provider.NodeTemplateFunc(subClient) + require.NoError(rt.T(), err) + + clusterObject, err := provisioning.CreateProvisioningRKE1Cluster(subClient, *rke1Provider, testConfig, nodeTemplate) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyRKE1Cluster(rt.T(), subClient, testConfig, clusterObject) + } + + podErrors := pods.StatusPods(rt.client, rt.clusterLocalID) + assert.Empty(rt.T(), podErrors) + registries.CheckAllClusterPodsForRegistryPrefix(rt.client, rt.clusterLocalID, rt.localClusterGlobalRegistryHost) +} + +func (rt *RegistryTestSuite) TestRegistriesK3S() { + subSession := session.NewSession() + defer subSession.Cleanup() + + subClient, err := rt.client.WithSession(subSession) + require.NoError(rt.T(), err) + + tests := []struct { + registry string + name string + }{ + {rt.privateRegistriesNoAuth[0].URL, "K3S Registry No Auth"}, + {rt.privateRegistriesAuth[0].URL, "K3S Registry Auth"}, + } + + for _, tt := range tests { + rt.Run(tt.name, func() { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.K3SKubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + testConfig = rt.configureRKE2K3SRegistry(tt.registry, testConfig) + k3sProvider, _, _, _ := permutations.GetClusterProvider(permutations.K3SProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + clusterObject, err := provisioning.CreateProvisioningCluster(subClient, *k3sProvider, testConfig, nil) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyCluster(rt.T(), subClient, testConfig, clusterObject) + }) + } + + if rt.rancherUsesRegistry { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.K3SKubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + testConfig = rt.configureRKE2K3SRegistry(rt.localClusterGlobalRegistryHost, testConfig) + + k3sProvider, _, _, _ := permutations.GetClusterProvider(permutations.K3SProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + + clusterObject, err := provisioning.CreateProvisioningCluster(subClient, *k3sProvider, testConfig, nil) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyCluster(rt.T(), subClient, testConfig, clusterObject) + } + + podErrors := pods.StatusPods(rt.client, rt.clusterLocalID) + assert.Empty(rt.T(), podErrors) + registries.CheckAllClusterPodsForRegistryPrefix(rt.client, rt.clusterLocalID, rt.localClusterGlobalRegistryHost) +} + +func (rt *RegistryTestSuite) TestRegistriesRKE2() { + subSession := session.NewSession() + defer subSession.Cleanup() + + subClient, err := rt.client.WithSession(subSession) + require.NoError(rt.T(), err) + tests := []struct { + registry string + name string + }{ + {rt.privateRegistriesNoAuth[0].URL, "RKE2 Registry No Auth"}, + {rt.privateRegistriesAuth[0].URL, "RKE2 Registry Auth"}, + } + + for _, tt := range tests { + rt.Run(tt.name, func() { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.RKE2KubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + testConfig = rt.configureRKE2K3SRegistry(tt.registry, testConfig) + + rke2Provider, _, _, _ := permutations.GetClusterProvider(permutations.RKE2ProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + + clusterObject, err := provisioning.CreateProvisioningCluster(subClient, *rke2Provider, testConfig, nil) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyCluster(rt.T(), subClient, testConfig, clusterObject) + }) + } + if rt.rancherUsesRegistry { + testConfig := clusters.ConvertConfigToClusterConfig(rt.provisioningConfig) + testConfig.KubernetesVersion = rt.provisioningConfig.RKE2KubernetesVersions[0] + testConfig.CNI = rt.provisioningConfig.CNIs[0] + testConfig = rt.configureRKE2K3SRegistry(rt.localClusterGlobalRegistryHost, testConfig) + + rke2Provider, _, _, _ := permutations.GetClusterProvider(permutations.RKE2ProvisionCluster, (*testConfig.Providers)[0], rt.provisioningConfig) + + clusterObject, err := provisioning.CreateProvisioningCluster(subClient, *rke2Provider, testConfig, nil) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(rt.T(), err) + + provisioning.VerifyCluster(rt.T(), subClient, testConfig, clusterObject) + } + + podErrors := pods.StatusPods(rt.client, rt.clusterLocalID) + assert.Empty(rt.T(), podErrors) + registries.CheckAllClusterPodsForRegistryPrefix(rt.client, rt.clusterLocalID, rt.localClusterGlobalRegistryHost) +} + +func (rt *RegistryTestSuite) configureRKE2K3SRegistry(registryName string, testConfig *clusters.ClusterConfig) *clusters.ClusterConfig { + testConfig.Registries = &provisioninginput.Registries{ + RKE2Registries: &rkev1.Registry{ + Configs: map[string]rkev1.RegistryConfig{ + registryName: {}, + }, + }, + } + if registryName == rt.privateRegistriesAuth[0].URL { + testConfig.Registries.RKE2Password = rt.privateRegistriesAuth[0].Password + testConfig.Registries.RKE2Username = rt.privateRegistriesAuth[0].User + } + if testConfig.Advanced == nil { + testConfig.Advanced = &provisioninginput.Advanced{} + } + testConfig.Advanced.MachineSelectors = &[]rkev1.RKESystemConfig{ + { + Config: rkev1.GenericMap{ + Data: map[string]interface{}{ + "protect-kernel-defaults": false, + "system-default-registry": registryName, + }, + }, + }, + } + logrus.Infof("returning registry") + return testConfig +} + +func TestRegistryTestSuite(t *testing.T) { + suite.Run(t, new(RegistryTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/cisbenchmark/cisbenchmark.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/cisbenchmark/cisbenchmark.go new file mode 100644 index 0000000..146acdf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/cisbenchmark/cisbenchmark.go @@ -0,0 +1,99 @@ +package charts + +import ( + "time" + + cis "github.com/rancher/cis-operator/pkg/apis/cis.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/defaults" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/sirupsen/logrus" + "golang.org/x/net/context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + System = "System" + pass = "pass" + scan = "scan" + + cisBenchmarkSteveType = "cis.cattle.io.clusterscan" +) + +// SetupCISBenchmarkChart installs the CIS Benchmark chart and waits for all resources to be ready. +func SetupCISBenchmarkChart(client *rancher.Client, projectClusterID string, chartInstallOptions *charts.InstallOptions, benchmarkNamespace string) error { + logrus.Infof("Installing CIS Benchmark chart...") + err := charts.InstallCISBenchmarkChart(client, chartInstallOptions) + if err != nil { + return err + } + + logrus.Infof("Waiting for CIS Benchmark chart deployments to have expected number of available replicas...") + err = charts.WatchAndWaitDeployments(client, projectClusterID, benchmarkNamespace, metav1.ListOptions{}) + if err != nil { + return err + } + + logrus.Infof("Waiting for CIS Benchmark chart DaemonSets to have expected number of available nodes...") + err = charts.WatchAndWaitDaemonSets(client, projectClusterID, benchmarkNamespace, metav1.ListOptions{}) + if err != nil { + return err + } + + logrus.Infof("Waiting for CIS Benchmark chart StatefulSets to have expected number of ready replicas...") + err = charts.WatchAndWaitStatefulSets(client, projectClusterID, benchmarkNamespace, metav1.ListOptions{}) + if err != nil { + return err + } + + logrus.Infof("Successfully installed CIS Benchmark chart!") + + return nil +} + +// RunCISScan runs the CIS Benchmark scan with the specified profile name. +func RunCISScan(client *rancher.Client, projectClusterID, scanProfileName string) error { + logrus.Infof("Running CIS Benchmark scan: %s", scanProfileName) + + cisScan := cis.ClusterScan{ + ObjectMeta: metav1.ObjectMeta{ + Name: namegen.AppendRandomString(scan), + }, + Spec: cis.ClusterScanSpec{ + ScanProfileName: scanProfileName, + ScoreWarning: pass, + }, + } + + steveclient, err := client.Steve.ProxyDownstream(projectClusterID) + if err != nil { + return err + } + + scan, err := steveclient.SteveType(cisBenchmarkSteveType).Create(cisScan) + if err != nil { + return err + } + + err = kwait.PollUntilContextTimeout(context.TODO(), 1*time.Second, defaults.TenMinuteTimeout, true, func(ctx context.Context) (done bool, err error) { + scanResp, err := steveclient.SteveType(cisBenchmarkSteveType).ByID(scan.ID) + if err != nil { + return false, err + } + + if !scanResp.ObjectMeta.State.Transitioning { + return true, nil + } + + return false, nil + }) + if err != nil { + return err + } + + logrus.Infof("CIS Benchmark scan passed!") + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/out-of-tree/aws.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/out-of-tree/aws.yml new file mode 100644 index 0000000..ee5c9f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/resources/out-of-tree/aws.yml @@ -0,0 +1,18 @@ +apiVersion: helm.cattle.io/v1 +kind: HelmChart +metadata: + name: aws-cloud-controller-manager + namespace: kube-system +spec: + chart: aws-cloud-controller-manager + repo: https://kubernetes.github.io/cloud-provider-aws + targetNamespace: kube-system + bootstrap: true + valuesContent: |- + hostNetworking: true + nodeSelector: + node-role.kubernetes.io/control-plane: "true" + args: + - --configure-cloud-routes=false + - --v=5 + - --cloud-provider=aws \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/README.md new file mode 100644 index 0000000..a3a196f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/README.md @@ -0,0 +1,473 @@ +# RKE1 Provisioning Configs + +For your config, you will need everything in the [Prerequisites](../README.md) section on the previous readme, [Define your test](#Provisioning-Input), and at least one [Node Driver Cluster Template](#NodeTemplateConfigs) or [Custom Cluster Template](#Custom-Cluster), which should match what you have specified in `provisioningInput`. + +Your GO test_package should be set to `provisioning/rke1`. +Your GO suite should be set to `-run ^TestRKE1ProvisioningTestSuite$`. +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Prerequisites](../README.md) +2. [Configuring test flags](#Flags) +3. [Define your test](#Provisioning-Input) +4. [Cloud Credential](#cloud-credentials) +5. [Configuring providers to use for Node Driver Clusters](#NodeTemplateConfigs) +6. [Configuring Custom Clusters](#Custom-Cluster) +7. [Static test cases](#static-test-cases) +8. [Cloud Provider](#Cloud-Provider) +9. [Advanced Cluster Settings](#advanced-settings) +10. [Back to general provisioning](../README.md) + + +## Flags +Flags are used to determine which static table tests are run (has no effect on dynamic tests) +`Long` Will run the long version of the table tests (usually all of them) +`Short` Will run the subset of table tests with the short flag. + +```yaml +flags: + desiredflags: "Long" +``` + +## Provisioning Input +provisioningInput is needed to the run the RKE1 tests, specifically kubernetesVersion, cni, and providers. nodesAndRoles is only needed for the TestProvisioningDynamicInput test, node pools are divided by "{nodepool},". psact is optional and takes values `rancher-privileged`, `rancher-restricted` or `rancher-baseline`. + +**nodeProviders is only needed for custom cluster tests; the framework only supports custom clusters through aws/ec2 instances.** +```yaml +provisioningInput: + nodePools: + - nodeRoles: + etcd: true + controlplane: true + worker: true + quantity: 1 + - nodeRoles: + worker: true + drainBeforeDelete: true + quantity: 2 + rke1KubernetesVersion: ["v1.28.10-rancher1-1"] + cni: ["calico"] + providers: ["linode", "aws", "do", "harvester", "vsphere", "azure"] + cloudProvider: "" # either: external-aws|rancher-vsphere + nodeProviders: ["ec2"] + psact: "" + criDockerd: false + etcdRKE1: + backupConfig: + enabled: true + intervalHours: 12 + safeTimestamp: true + timeout: 120 + s3BackupConfig: + accessKey: "" + bucketName: "" + endpoint: "" + folder: "" + region: "" + secretKey: "" + retention: "72h" + snapshot: false +chartUpgrade: # will install a version of the out-of-tree chart (latest - 1) that can later be upgraded to the latest version. This is used for upgrade testing on cloud provider tests. + isUpgradable: false +``` + +## Cloud Credentials +These are the inputs needed for the different node provider cloud credentials, including linode, aws, harvester, azure, and google. + +### Digital Ocean +```yaml +digitalOceanCredentials: + accessToken: "" #required +``` +### Linode +```yaml +linodeCredentials: + token: "" #required +``` +### Azure +```yaml +azureCredentials: + clientId: "" #required + clientSecret: "" #required + subscriptionId: "" #required + environment: "AzurePublicCloud" #required +``` +### AWS +```yaml +awsCredentials: + secretKey: "" #required + accessKey: "" #required + defaultRegion: "" #required +``` +### Harvester +```yaml +harvesterCredentials: + clusterId: "" #required + clusterType: "" #required + kubeconfigContent: "" #required +``` +### Google +```yaml +googleCredentials: + authEncodedJson: "" #required +``` +### VSphere +```yaml +vmwarevsphereCredentials: + password: "" #required + username: "" #required + vcenter: "" #required + vcenterPort: "" #required +``` + + +## Cloud Provider +Cloud Provider enables additional options through the cloud provider, like cloud persistent storage or cloud provisioned load balancers. + +Names of cloud provider options are typically controlled by rancher product. Hence the discrepancy in rke2 vs. rke1 AWS in-tree and out-of-tree options. +To use automation with a cloud provider, simply enter one of the following options in the `cloudProvider` field in the config. + +### RKE1 Cloud Provider Options +* external-aws +* aws +* rancher-vsphere + +### RKE1 Chart Upgrade Options +At the root level of your config.yaml, you can provide the following option: +```yaml +chartUpgrade: + isUpgradable: true +``` +which will install `latest-1` chart version for CPI and CSI charts so that you may run upgrade tests later, if you wish. +This is currently only available for Vsphere RKE1 + +## NodeTemplateConfigs +RKE1 specifically needs a node template config to run properly. These are the inputs needed for the different node providers. +Top level node template config entries can be set. The top level nodeTemplate is optional, and is not need for the different node +providers to work. +```yaml + nodeTemplate: + engineInstallURL: "testNT" + name: "testNTName" +``` +### AWS +```yaml + awsNodeConfig: + ami: "" + blockDurationMinutes: "0" + encryptEbsVolume: false + endpoint: "" + httpEndpoint: "enabled" + httpTokens: "optional" + iamInstanceProfile: "" + insecureTransport: false + instanceType: "t2.2xlarge" + keypairName: "your-key-name" + kmsKey: "" + monitoring: false + privateAddressOnly: false + region: "us-east-2" + requestSpotInstance: true + retries: "5" + rootSize: "16" + securityGroup: ["open-all"] + securityGroupReadonly: false + sessionToken: "" + spotPrice: "0.50" + sshKeyContents: "" + sshUser: "ec2-user" + subnetId: "" + tags: "" + type: "amazonec2Config" + useEbsOptimizedInstance: false + usePrivateAddress: false + userdata: "" + volumeType: "gp2" + vpcId: "" + zone: "a" +``` + +### Azure +```yaml +azureNodeConfig: + availabilitySet: "docker-machine" + customData: "" + diskSize: "30" + dns: "" + dockerPort: "2376" + environment: "AzurePublicCloud" + faultDomainCount: "3" + image: "canonical:UbuntuServer:22.04-LTS:latest" + location: "eastus2" + managedDisks: false + noPublicIp: false + openPort: ["6443/tcp","2379/tcp","2380/tcp","8472/udp","4789/udp","9796/tcp","10256/tcp","10250/tcp","10251/tcp","10252/tcp"] + plan: "" + privateIpAddress: "" + resourceGroup: "" + size: "Standard_D2_v2" + sshUser: "azureuser" + staticPublicIp: false + storageType: "Standard_LRS" + subnet: "docker-machine" + subnetPrefix: "192.168.0.0/16" + subscriptionId: "" + type: "azureConfig" + updateDomainCount: "5" + vnet: "docker-machine-vnet" +``` + +### Harvester +```yaml +harvesterNodeConfig": + cloudConfig: "" + cpuCount: "2" + diskBus: "virtio" + diskSize: "40" + imageName: "default/image-gchq8" + keyPairName: "" + memorySize: "4" + networkData: "" + networkModel: "virtio" + networkName: "" + networkType: "dhcp" + sshPassword: "" + sshPort: "22" + sshPrivateKeyPath: "" + sshUser: "ubuntu" + type: "harvesterConfig" + userData: "" + vmAffinity: "" + vmNamespace: "default +``` + +### Linode +```yaml +linodeNodeConfig: + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-dedicated-8" + label: "" + region: "us-west" + rootPass: "" + sshPort: "22" + sshUser: "root" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + type: "linodeConfig" + uaPrefix: "Rancher" +``` + +### Vsphere +```yaml +vmwarevsphereNodeConfig: + cfgparam: ["disk.enableUUID=TRUE"] + cloneFrom: "" + cloudinit: "#cloud-config\n\n" + contentLibrary: "" + cpuCount: "4" + creationType: "" + datacenter: "" + datastore: "" + datastoreURL: "" + datastoreCluster: "" + diskSize: "20000" + folder: "" + hostSystem: "" + memorySize: "4096" + network: [""] + os: "" + password: "" + pool: "" + sshPassword: "" + sshPort: "22" + sshUser: "" + sshUserGroup: "" + username: "" + vcenter: "" + vcenterPort: "443" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the node driver tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1ProvisioningTestSuite/TestProvisioningRKE1Cluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1ProvisioningTestSuite/TestProvisioningRKE1ClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## Cloud Provider +Cloud Provider enables additional options such as load-balancers and storage devices to be provisioned through your cluster +available options: +### AWS +* `aws` uses the in-tree provider for aws -- **Deprecated on kubernetes 1.26 and below** +* `external-aws` uses the out-of-tree provider for aws. Built in logic to the automation will be applied to the cluster that applies the correct configuration for the out-of-tree charts to be installed. Supported on kubernetes 1.22+. An AWS provided LB will be attached to a workload in order to test that the cloud provider is working as expected. + +### Vsphere +* `rancher-vsphere` is out-of-tree since 1.22. A workload using vsphere's cloud provider storage class will be created on the cluster to test that the provider is working as expected. + +## Custom Cluster +For custom clusters, no nodeTemplateConfig or credentials are required. Currently only supported for ec2. + +Dependencies: +* **Ensure you have nodeDrivers set in provisioningInput** +* make sure that all roles are entered at least once in nodePools.nodeRoles +* ensure nodeProviders is set +* use AMIs that already have Docker installed and the service is enabled on boot + +```yaml + awsEC2Configs: + region: "us-east-2" + awsSecretAccessKey: "" + awsAccessKeyID: "" + awsEC2Config: + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["etcd", "controlplane"] + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["worker"] +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the custom cluster tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterRKE1ProvisioningTestSuite/TestProvisioningRKE1CustomCluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterRKE1ProvisioningTestSuite/TestProvisioningRKE1CustomClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## RKE1 Support Matrix Checks - K8s Components & Architecture +Custom clusters have the ability to perform RKE1 support matrix checks for K8s components & architectures. + +To do this, ensure that your `provisioningInput` has `flannel` and `canal` both defined, along with your desired K8s versions as shown below: + +```yaml +provisioningInput: + nodePools: + - nodeRoles: + etcd: true + controlplane: true + worker: true + quantity: 1 + - nodeRoles: + worker: true + quantity: 2 + rke1KubernetesVersion: ["v1.26.9-rancher1-1", "v1.27.6-rancher1-1"] + cni: ["flannel", "calico"] + nodeProviders: ["ec2"] + psact: "" +``` + +## Static Test Cases +In an effort to have uniform testing across our internal QA test case reporter, there are specific test cases that are put into their respective test files. This section highlights those test cases. + +### PSACT +These test cases cover the following PSACT values as both an admin and standard user: +1. `rancher-privileged` +2. `rancher-restricted` +3. `rancher-baseline` + +See an example YAML below: + +```yaml +rancher: + host: "" + adminToken: "" + cleanup: false + clusterName: "" + insecure: true +provisioningInput: + rke1KubernetesVersion: ["v1.27.10-rancher1-1"] + cni: ["calico"] + providers: ["linode"] + nodeProviders: ["ec2"] +nodeTemplate: + engineInstallURL: "https://releases.rancher.com/install-docker/23.0.sh" +linodeNodeConfig: + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-dedicated-8" + label: "" + region: "us-west" + rootPass: "" + sshPort: "22" + sshUser: "root" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + token: "" + type: "linodeConfig" + uaPrefix: "Rancher" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE1PSACTTestSuite$"` + +### Hardened Custom Cluster +This will provision a hardened custom cluster that runs across the following CIS scan profiles: +1. `rke-profile-hardened-1.8` +2. `rke-profile-permissive-1.8` + +You would use the same config that you setup for a custom cluster to run this test. Plese reference this [section](#custom-cluster). It also important to note that the machines that you select has `sudo` capabilities. The tests utilize `sudo`, so this can cause issues if there is no `sudo` present on the machine. + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke1 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHardenedRKE1ClusterProvisioningTestSuite$"` + +## Advanced Settings +This encapsulates any other setting that is applied in the cluster.spec. Currently we have support for: +* cluster agent customization +* fleet agent customization + +Please read up on general k8s to get an idea of correct formatting for: +* resource requests +* resource limits +* node affinity +* tolerations + +```yaml +advancedOptions: + clusterAgent: # change this to fleetAgent for fleet agent + appendTolerations: + - key: "Testkey" + value: "testValue" + effect: "NoSchedule" + overrideResourceRequirements: + limits: + cpu: "750m" + memory: "500Mi" + requests: + cpu: "250m" + memory: "250Mi" + overrideAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: "cattle.io/cluster-agent" + operator: "In" + values: + - "true" + weight: 1 +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/custom_cluster_test.go new file mode 100644 index 0000000..7b671f7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/custom_cluster_test.go @@ -0,0 +1,125 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package rke1 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CustomClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (c *CustomClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *CustomClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.RKE1KubernetesVersions, err = kubernetesversions.Default(c.client, clusters.RKE1ClusterType.String(), c.provisioningConfig.RKE1KubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningRKE1CustomCluster() { + nodeRolesAll := []provisioninginput.NodePools{provisioninginput.AllRolesNodePool} + nodeRolesShared := []provisioninginput.NodePools{provisioninginput.EtcdControlPlaneNodePool, provisioninginput.WorkerNodePool} + nodeRolesDedicated := []provisioninginput.NodePools{provisioninginput.EtcdNodePool, provisioninginput.ControlPlaneNodePool, provisioninginput.WorkerNodePool} + + require.GreaterOrEqual(c.T(), len(c.provisioningConfig.CNIs), 1) + + tests := []struct { + name string + nodePools []provisioninginput.NodePools + client *rancher.Client + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), nodeRolesAll, c.standardUserClient, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), nodeRolesShared, c.standardUserClient, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), nodeRolesDedicated, c.standardUserClient, c.client.Flags.GetValue(environmentflag.Long)}, + } + for _, tt := range tests { + if !tt.runFlag { + c.T().Logf("SKIPPED") + continue + } + + provisioningConfig := *c.provisioningConfig + provisioningConfig.NodePools = tt.nodePools + provisioningConfig.NodePools[0].SpecifyCustomPublicIP = true + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE1CustomCluster, nil, nil) + } +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningRKE1CustomClusterDynamicInput() { + require.GreaterOrEqual(c.T(), len(c.provisioningConfig.CNIs), 1) + + if len(c.provisioningConfig.NodePools) == 0 { + c.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), c.client}, + {provisioninginput.StandardClientName.String(), c.standardUserClient}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, c.provisioningConfig, permutations.RKE1CustomCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestCustomClusterRKE1ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(CustomClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/hardened_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/hardened_cluster_test.go new file mode 100644 index 0000000..ca616f2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/hardened_cluster_test.go @@ -0,0 +1,139 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package rke1 + +import ( + "testing" + + cis "github.com/rancher/rancher/tests/v2/validation/provisioning/resources/cisbenchmark" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HardenedRKE1ClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config + project *management.Project + chartInstallOptions *charts.InstallOptions + chartFeatureOptions *charts.RancherMonitoringOpts +} + +func (c *HardenedRKE1ClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *HardenedRKE1ClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.RKE1KubernetesVersions, err = kubernetesversions.Default(c.client, clusters.RKE1ClusterType.String(), c.provisioningConfig.RKE1KubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *HardenedRKE1ClusterProvisioningTestSuite) TestProvisioningRKE1HardenedCluster() { + nodeRolesDedicated := []provisioninginput.NodePools{provisioninginput.EtcdNodePool, provisioninginput.ControlPlaneNodePool, provisioninginput.WorkerNodePool} + + tests := []struct { + name string + client *rancher.Client + nodePools []provisioninginput.NodePools + scanProfileName string + }{ + {"RKE1 CIS 1.8 Profile Hardened " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "rke-profile-hardened-1.8"}, + {"RKE1 CIS 1.8 Profile Permissive " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "rke-profile-permissive-1.8"}, + } + for _, tt := range tests { + c.Run(tt.name, func() { + provisioningConfig := *c.provisioningConfig + provisioningConfig.NodePools = tt.nodePools + provisioningConfig.Hardened = true + + nodeProviders := provisioningConfig.NodeProviders[0] + externalNodeProvider := provisioning.ExternalNodeProviderSetup(nodeProviders) + + testConfig := clusters.ConvertConfigToClusterConfig(&provisioningConfig) + testConfig.KubernetesVersion = c.provisioningConfig.RKE1KubernetesVersions[0] + + clusterObject, _, err := provisioning.CreateProvisioningRKE1CustomCluster(tt.client, &externalNodeProvider, testConfig) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(c.T(), err) + + provisioning.VerifyRKE1Cluster(c.T(), tt.client, testConfig, clusterObject) + + cluster, err := clusters.NewClusterMeta(tt.client, clusterObject.Name) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(c.T(), err) + + latestCISBenchmarkVersion, err := tt.client.Catalog.GetLatestChartVersion(charts.CISBenchmarkName, catalog.RancherChartRepo) + require.NoError(c.T(), err) + + project, err := projects.GetProjectByName(tt.client, cluster.ID, cis.System) + reports.TimeoutRKEReport(clusterObject, err) + require.NoError(c.T(), err) + + c.project = project + require.NotEmpty(c.T(), c.project) + + c.chartInstallOptions = &charts.InstallOptions{ + Cluster: cluster, + Version: latestCISBenchmarkVersion, + ProjectID: c.project.ID, + } + + cis.SetupCISBenchmarkChart(tt.client, c.project.ClusterID, c.chartInstallOptions, charts.CISBenchmarkNamespace) + cis.RunCISScan(tt.client, c.project.ClusterID, tt.scanProfileName) + }) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHardenedRKE1ClusterProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(HardenedRKE1ClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/post_kdm_oob_release_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/post_kdm_oob_release_test.go new file mode 100644 index 0000000..9df81e5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/post_kdm_oob_release_test.go @@ -0,0 +1,78 @@ +//go:build validation + +package rke1 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type KdmChecksTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + ns string + provisioningConfig *provisioninginput.Config +} + +const ( + defaultNamespace = "default" + ProvisioningSteveResouceType = "provisioning.cattle.io.cluster" +) + +func (k *KdmChecksTestSuite) TearDownSuite() { + k.session.Cleanup() +} + +func (k *KdmChecksTestSuite) SetupSuite() { + testSession := session.NewSession() + k.session = testSession + + k.ns = defaultNamespace + + k.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, k.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(k.T(), err) + + k.client = client +} + +func (k *KdmChecksTestSuite) TestRKE1K8sVersions() { + logrus.Infof("checking for valid k8s versions..") + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.RKE1KubernetesVersions), 1) + // fetching all available k8s versions from rancher + releasedK8sVersions, _ := kubernetesversions.ListRKE1AllVersions(k.client) + logrus.Info("expected k8s versions : ", k.provisioningConfig.RKE1KubernetesVersions) + logrus.Info("k8s versions available on rancher server : ", releasedK8sVersions) + for _, expectedK8sVersion := range k.provisioningConfig.RKE1KubernetesVersions { + require.Contains(k.T(), releasedK8sVersions, expectedK8sVersion) + } +} + +func (k *KdmChecksTestSuite) TestProvisioningSingleNodeRKE1Clusters() { + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.Providers), 1) + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.CNIs), 1) + + subSession := k.session.NewSession() + defer subSession.Cleanup() + + client, err := k.client.WithSession(subSession) + require.NoError(k.T(), err) + permutations.RunTestPermutations(&k.Suite, "oobRelease-", client, k.provisioningConfig, permutations.RKE1ProvisionCluster, nil, nil) + +} + +func TestPostKdmOutOfBandReleaseChecks(t *testing.T) { + suite.Run(t, new(KdmChecksTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_cloud_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_cloud_provider_test.go new file mode 100644 index 0000000..827d41f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_cloud_provider_test.go @@ -0,0 +1,142 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package rke1 + +import ( + "slices" + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1CloudProviderTestSuite struct { + suite.Suite + client *rancher.Client + standardUserClient *rancher.Client + session *session.Session + provisioningConfig *provisioninginput.Config + chartConfig *charts.Config +} + +func (r *RKE1CloudProviderTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE1CloudProviderTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + r.provisioningConfig.RKE1KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE1ClusterType.String(), r.provisioningConfig.RKE1KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE1CloudProviderTestSuite) TestAWSCloudProviderRKE1Cluster() { + nodeRolesDedicated := []provisioninginput.NodePools{provisioninginput.EtcdNodePool, provisioninginput.ControlPlaneNodePool, provisioninginput.WorkerNodePool} + nodeRolesDedicated[0].NodeRoles.Quantity = 3 + nodeRolesDedicated[1].NodeRoles.Quantity = 2 + nodeRolesDedicated[2].NodeRoles.Quantity = 2 + + tests := []struct { + name string + nodePools []provisioninginput.NodePools + client *rancher.Client + runFlag bool + }{ + {"OutOfTree" + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + + if !slices.Contains(r.provisioningConfig.Providers, "aws") { + r.T().Skip("AWS Cloud Provider test requires access to aws.") + } + + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + provisioningConfig := *r.provisioningConfig + provisioningConfig.CloudProvider = "external-aws" + provisioningConfig.NodePools = tt.nodePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE1ProvisionCluster, nil, nil) + } +} + +func (r *RKE1CloudProviderTestSuite) TestVsphereCloudProviderRKE1Cluster() { + nodeRolesDedicated := []provisioninginput.NodePools{provisioninginput.EtcdNodePool, provisioninginput.ControlPlaneNodePool, provisioninginput.WorkerNodePool} + nodeRolesDedicated[0].NodeRoles.Quantity = 3 + nodeRolesDedicated[1].NodeRoles.Quantity = 2 + nodeRolesDedicated[2].NodeRoles.Quantity = 2 + + tests := []struct { + name string + nodePools []provisioninginput.NodePools + client *rancher.Client + runFlag bool + }{ + {"OutOfTree" + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + + if !slices.Contains(r.provisioningConfig.Providers, "vsphere") { + r.T().Skip("Vsphere Cloud Provider test requires access to Vsphere.") + } + + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + provisioningConfig := *r.provisioningConfig + provisioningConfig.CloudProvider = "rancher-vsphere" + provisioningConfig.NodePools = tt.nodePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE1ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1CloudProviderTestSuite(t *testing.T) { + suite.Run(t, new(RKE1CloudProviderTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_node_driver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_node_driver_test.go new file mode 100644 index 0000000..2fedd96 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/provisioning_node_driver_test.go @@ -0,0 +1,120 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package rke1 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1NodeDriverProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + standardUserClient *rancher.Client + session *session.Session + provisioningConfig *provisioninginput.Config +} + +func (r *RKE1NodeDriverProvisioningTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE1NodeDriverProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + r.provisioningConfig.RKE1KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE1ClusterType.String(), r.provisioningConfig.RKE1KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE1NodeDriverProvisioningTestSuite) TestProvisioningRKE1Cluster() { + nodeRolesAll := []provisioninginput.NodePools{provisioninginput.AllRolesNodePool} + nodeRolesShared := []provisioninginput.NodePools{provisioninginput.EtcdControlPlaneNodePool, provisioninginput.WorkerNodePool} + nodeRolesDedicated := []provisioninginput.NodePools{provisioninginput.EtcdNodePool, provisioninginput.ControlPlaneNodePool, provisioninginput.WorkerNodePool} + tests := []struct { + name string + nodePools []provisioninginput.NodePools + client *rancher.Client + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), nodeRolesAll, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Short) || r.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), nodeRolesShared, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Short) || r.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + provisioningConfig := *r.provisioningConfig + provisioningConfig.NodePools = tt.nodePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE1ProvisionCluster, nil, nil) + } +} + +func (r *RKE1NodeDriverProvisioningTestSuite) TestProvisioningRKE1ClusterDynamicInput() { + + if len(r.provisioningConfig.NodePools) == 0 { + r.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), r.client}, + {provisioninginput.StandardClientName.String(), r.standardUserClient}, + } + for _, tt := range tests { + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, r.provisioningConfig, permutations.RKE1ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(RKE1NodeDriverProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/psact_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/psact_test.go new file mode 100644 index 0000000..768a9de --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke1/psact_test.go @@ -0,0 +1,118 @@ +//go:build validation + +package rke1 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE1PSACTTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE1PSACTTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE1PSACTTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + r.provisioningConfig.RKE1KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE1ClusterType.String(), r.provisioningConfig.RKE1KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE1PSACTTestSuite) TestRKE1PSACTNodeDriverCluster() { + nodeRolesDedicated := []provisioninginput.NodePools{ + provisioninginput.EtcdNodePool, + provisioninginput.ControlPlaneNodePool, + provisioninginput.WorkerNodePool, + } + + tests := []struct { + name string + nodePools []provisioninginput.NodePools + psact provisioninginput.PSACT + client *rancher.Client + }{ + { + name: "Rancher Privileged " + provisioninginput.StandardClientName.String(), + nodePools: nodeRolesDedicated, + psact: "rancher-privileged", + client: r.standardUserClient, + }, + { + name: "Rancher Restricted " + provisioninginput.StandardClientName.String(), + nodePools: nodeRolesDedicated, + psact: "rancher-restricted", + client: r.standardUserClient, + }, + { + name: "Rancher Baseline " + provisioninginput.AdminClientName.String(), + nodePools: nodeRolesDedicated, + psact: "rancher-baseline", + client: r.client, + }, + } + + for _, tt := range tests { + provisioningConfig := *r.provisioningConfig + provisioningConfig.NodePools = tt.nodePools + provisioningConfig.PSACT = string(tt.psact) + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, + permutations.RKE1ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE1PSACTTestSuite(t *testing.T) { + suite.Run(t, new(RKE1PSACTTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/README.md new file mode 100644 index 0000000..a56e5f5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/README.md @@ -0,0 +1,438 @@ +# RKE2 Provisioning Configs + +For your config, you will need everything in the Prerequisites section on the previous readme, [Define your test](#provisioning-input), and at least one [Cloud Credential](#cloud-credentials) and [Node Driver Machine Config](#machine-rke2-config) or [Custom Cluster Template](#custom-cluster), which should match what you have specified in `provisioningInput`. + +Your GO test_package should be set to `provisioning/rke2`. +Your GO suite should be set to `-run ^TestRKE2ProvisioningTestSuite$`. +Please see below for more details for your config. Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Prerequisites](../README.md) +2. [Configuring test flags](#Flags) +3. [Define your test](#provisioning-input) +4. [Cloud Credential](#cloud-credentials) +5. [Cloud Provider](#cloud-provider) +6. [Configure providers to use for Node Driver Clusters](#machine-rke2-config) +7. [Configuring Custom Clusters](#custom-cluster) +8. [Template Test](#template-test) +9. [Static test cases](#static-test-cases) +10. [Advanced Cluster Settings](#advanced-settings) +11. [Back to general provisioning](../README.md) + +## Flags +Flags are used to determine which static table tests are run (has no effect on dynamic tests) +`Long` Will run the long version of the table tests (usually all of them) +`Short` Will run the subset of table tests with the short flag. + +```yaml +flags: + desiredflags: "Long" +``` + +## Provisioning Input +provisioningInput is needed to the run the RKE2 tests. + +**nodeProviders is only needed for custom cluster tests; the framework only supports custom clusters through aws/ec2 instances.** +```yaml +provisioningInput: + machinePools: + - machinePoolConfig: #required(dynamic only) (at least 1) + etcd: true #required(dynamic only) (at least 1 controlplane & etcd & worker) + controlplane: true + worker: true + quantity: 5 + drainBeforeDelete: true + hostnameLengthLimit: 29 + nodeStartupTimeout: "600s" + unhealthyNodeTimeout: "300s" + maxUnhealthy: "2" + unhealthyRange: "2-4" + - machinePoolConfig: + worker: true + quantity: 2 + - machinePoolConfig: + windows: true + quantity: 1 + rke2KubernetesVersion: ["v1.27.10+rke2r1"] + cni: ["calico"] + providers: ["linode", "aws", "do", "harvester", "vsphere", "azure"] + cloudProvider: "" # either: aws|rancher-vsphere + nodeProviders: ["ec2"] + hardened: false + psact: "" #either rancher-privileged|rancher-restricted|rancher-baseline + clusterSSHTests: ["CheckCPU", "NodeReboot", "AuditLog"] + etcd: + disableSnapshot: false + snapshotScheduleCron: "0 */5 * * *" + snapshotRetain: 3 + s3: + bucket: "" + endpoint: "s3.us-east-2.amazonaws.com" + endpointCA: "" + folder: "" + region: "us-east-2" + skipSSLVerify: true +``` + +## Cloud Credentials +These are the inputs needed for the different node provider cloud credentials, including linode, aws, digital ocean, harvester, azure, and google. + +### Digital Ocean +```yaml +digitalOceanCredentials: + accessToken": "" #required +``` +### Linode +```yaml +linodeCredentials: + token: "" #required +``` +### Azure +```yaml +azureCredentials: + clientId: "" #required + clientSecret: "" #required + subscriptionId": "" #required + environment: "AzurePublicCloud" #required +``` +### AWS +```yaml +awsCredentials: + secretKey: "" #required + accessKey: "" #required + defaultRegion: "" #required +``` +### Harvester +```yaml +harvesterCredentials: + clusterId: "" #required + clusterType: "" #required + kubeconfigContent: "" #required +``` +### Google +```yaml +googleCredentials: + authEncodedJson: "" #required +``` +### VSphere +```yaml +vmwarevsphereCredentials: + password: "" #required + username: "" #required + vcenter: "" #required + vcenterPort: "" #required +``` + +## Cloud Provider +Cloud Provider enables additional options through the cloud provider, like cloud persistent storage or cloud provisioned load balancers. + +Names of cloud provider options are typically controlled by rancher product. Hence the discrepancy in rke2 vs. rke1 AWS in-tree and out-of-tree options. +To use automation with a cloud provider, simply enter one of the following options in the `cloudProvider` field in the config. + +### RKE2 Cloud Provider Options +* `aws-in-tree` uses the in-tree provider for aws -- **Deprecated on kubernetes 1.26 and below** +* `aws` uses the out-of-tree provider for aws. Built in logic to the automation will be applied to the cluster that applies the correct configuration for the out-of-tree charts to be installed. Supported on kubernetes 1.22+ +* rancher-vsphere + +## Machine RKE2 Config +Machine RKE2 config is the final piece needed for the config to run RKE2 provisioning tests. + +### AWS RKE2 Machine Config +```yaml +awsMachineConfigs: + region: "us-east-2" #required + awsMachineConfig: + - roles: ["etcd","controlplane","worker"] #required + ami: "" #required + instanceType: "t3a.medium" + sshUser: "ubuntu" #required + vpcId: "" #required + volumeType: "gp2" + zone: "a" #required + retries: "5" + rootSize: "60" + securityGroup: [""] +``` +### Digital Ocean RKE2 Machine Config +```yaml +doMachineConfigs: + region: "nyc3" + doMachineConfig: + - roles: ["etcd","controlplane","worker"] + image: "ubuntu-20-04-x64" + backups: false + ipv6: false + monitoring: false + privateNetworking: false + size: "s-2vcpu-4gb" + sshKeyContents: "" + sshKeyFingerprint: "" + sshPort: "22" + sshUser: "root" + tags: "" + userdata: "" +``` +### Linode RKE2 Machine Config +```yaml +linodeMachineConfigs: + region: "us-west" + linodeMachineConfig: + - roles: ["etcd","controlplane","worker"] + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-standard-8" + rootPass: "" + sshPort: "22" + sshUser: "" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + uaPrefix: "Rancher" +``` +### Azure RKE2 Machine Config +```yaml +azureMachineConfigs: + environment: "AzurePublicCloud" + azureMachineConfig: + - roles: ["etcd","controlplane","worker"] + availabilitySet: "docker-machine" + diskSize: "30" + faultDomainCount: "3" + image: "canonical:UbuntuServer:22.04-LTS:latest" + location: "westus" + managedDisks: false + noPublicIp: false + nsg: "" + openPort: ["6443/tcp", "2379/tcp", "2380/tcp", "8472/udp", "4789/udp", "9796/tcp", "10256/tcp", "10250/tcp", "10251/tcp", "10252/tcp"] + resourceGroup: "docker-machine" + size: "Standard_D2_v2" + sshUser: "docker-user" + staticPublicIp: false + storageType: "Standard_LRS" + subnet: "docker-machine" + subnetPrefix: "192.168.0.0/16" + updateDomainCount: "5" + usePrivateIp: false + vnet: "docker-machine-vnet" +``` +### Harvester RKE2 Machine Config +```yaml +harvesterMachineConfigs: + vmNamespace: "default" + harvesterMachineConfig: + - roles: ["etcd","controlplane","worker"] + diskSize: "40" + cpuCount: "2" + memorySize: "8" + networkName: "default/ctw-network-1" + imageName: "default/image-rpj98" + sshUser: "ubuntu" + diskBus: "virtio +``` +## Vsphere RKE2 Machine Config +```yaml +vmwarevsphereMachineConfigs: + datacenter: "/" #required + hostSystem: "//path-to-host" #required + datastore: "//path-to-datastore" #required + datastoreURL: "ds:///" + folder: "//path-to-vm-folder" #required + pool: "//path-to-resource-pool" #required + vmwarevsphereMachineConfig: + - cfgparam: ["disk.enableUUID=TRUE"] #required + cloudConfig: "#cloud-config\n\n" + customAttribute: [] + tag: [] + roles: ["etcd","controlplane",worker] + creationType: "template" #required + os: "linux" #required + cloneFrom: "//path-to-linux-image" #required(linux templates only) + cloneFromWindows: "//path-to-windows-image" #required(windows templates only) + contentLibrary: "" + datastoreCluster: "" + network: ["//path-to-vm-network"] #required + sshUser: "" #required + sshPassword: "" + sshUserGroup: "" + sshPort: "22" + cpuCount: "4" + diskSize: "40000" + memorySize: "8192" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the node driver tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE2ProvisioningTestSuite/TestProvisioningRKE2Cluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE2ProvisioningTestSuite/TestProvisioningRKE2ClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## Custom Cluster +For custom clusters, no machineConfig or credentials are needed. Currently only supported for ec2. + +Dependencies: +* **Ensure you have nodeProviders in provisioningInput** +* make sure that all roles are entered at least once +* windows pool(s) should always be last in the config +```yaml + awsEC2Configs: + region: "us-east-2" + awsSecretAccessKey: "" + awsAccessKeyID: "" + awsEC2Config: + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["etcd", "controlplane"] + - instanceType: "t3a.medium" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["worker"] + - instanceType: "t3a.xlarge" + awsAMI: "" + awsSecurityGroups: [""] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsUser: "Administrator" + volumeSize: 50 + roles: ["windows"] +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the custom cluster tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterRKE2ProvisioningTestSuite/TestProvisioningRKE2CustomCluster"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCustomClusterRKE2ProvisioningTestSuite/TestProvisioningRKE2CustomClusterDynamicInput"` + +If the specified test passes immediately without warning, try adding the `-count=1` flag to get around this issue. This will avoid previous results from interfering with the new test run. + +## Template Test + +Dependencies: +* [Cloud Credential](#cloud-credentials) +* Make sure the template provider matches the credentials. +```yaml +templateTest: + repo: + metadata: + name: "demo" + spec: + gitRepo: "https://github.com//cluster-template-examples.git" + gitBranch: main + insecureSkipTLSVerify: true + templateProvider: "aws" + templateName: "cluster-template" +``` + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestClusterTemplateTestSuite/TestProvisionRKE2TemplateCluster` + +## Static Test Cases +In an effort to have uniform testing across our internal QA test case reporter, there are specific test cases that are put into their respective test files. This section highlights those test cases. + +### PSACT +These test cases cover the following PSACT values as both an admin and standard user: +1. `rancher-privileged` +2. `rancher-restricted` +3. `rancher-baseline` + +See an example YAML below: + +```yaml +rancher: + host: "" + adminToken: "" + cleanup: false + clusterName: "" + insecure: true +provisioningInput: + rke2KubernetesVersion: ["v1.27.10+rke2r1"] + cni: ["calico"] + providers: ["linode"] + nodeProviders: ["ec2"] +linodeCredentials: + token: "" +linodeMachineConfigs: + region: "us-west" + linodeMachineConfig: + - roles: ["etcd", "controlplane", "worker"] + authorizedUsers: "" + createPrivateIp: true + dockerPort: "2376" + image: "linode/ubuntu22.04" + instanceType: "g6-standard-8" + region: "us-west" + rootPass: "" + sshPort: "22" + sshUser: "" + stackscript: "" + stackscriptData: "" + swapSize: "512" + tags: "" + uaPrefix: "Rancher" +``` + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestRKE2PSACTTestSuite$"` + +### Hardened Custom Cluster +This will provision a hardened custom cluster that runs across the following CIS scan profiles: +1. `rke2-cis-1.8-profile-hardened` +2. `rke2-cis-1.8-profile-permissive` + +You would use the same config that you setup for a custom cluster to run this test. Plese reference this [section](#custom-cluster). It also important to note that the machines that you select has `sudo` capabilities. The tests utilize `sudo`, so this can cause issues if there is no `sudo` present on the machine. + +These tests utilize Go build tags. Due to this, see the below examples on how to run the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/provisioning/rke2 --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestHardenedRKE2ClusterProvisioningTestSuite$"` + +## Advanced Settings +This encapsulates any other setting that is applied in the cluster.spec. Currently we have support for: +* cluster agent customization +* fleet agent customization + +Please read up on general k8s to get an idea of correct formatting for: +* resource requests +* resource limits +* node affinity +* tolerations + +```yaml +advancedOptions: + clusterAgent: # change this to fleetAgent for fleet agent + appendTolerations: + - key: "Testkey" + value: "testValue" + effect: "NoSchedule" + overrideResourceRequirements: + limits: + cpu: "750m" + memory: "500Mi" + requests: + cpu: "250m" + memory: "250Mi" + overrideAffinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: "cattle.io/cluster-agent" + operator: "In" + values: + - "true" + weight: 1 +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/ace_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/ace_test.go new file mode 100644 index 0000000..d9bcc72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/ace_test.go @@ -0,0 +1,122 @@ +//go:build validation + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/machinepools" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE2ACETestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE2ACETestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE2ACETestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE2ACETestSuite) TestProvisioningRKE2ClusterACE() { + nodeRoles0 := []provisioninginput.MachinePools{ + { + MachinePoolConfig: machinepools.MachinePoolConfig{ + NodeRoles: machinepools.NodeRoles{ + ControlPlane: true, + Etcd: false, + Worker: false, + Quantity: 3, + }, + }, + }, + { + MachinePoolConfig: machinepools.MachinePoolConfig{ + NodeRoles: machinepools.NodeRoles{ + ControlPlane: false, + Etcd: true, + Worker: false, + Quantity: 1, + }, + }, + }, + { + MachinePoolConfig: machinepools.MachinePoolConfig{ + NodeRoles: machinepools.NodeRoles{ + ControlPlane: false, + Etcd: false, + Worker: true, + Quantity: 1, + }, + }, + }, + } + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + }{ + {"Multiple Control Planes - Standard", nodeRoles0, r.standardUserClient}, + } + require.NotNil(r.T(), r.provisioningConfig.Networking.LocalClusterAuthEndpoint) + // Test is obsolete when ACE is not set. + for _, tt := range tests { + subSession := r.session.NewSession() + defer subSession.Cleanup() + + client, err := tt.client.WithSession(subSession) + require.NoError(r.T(), err) + r.provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&r.Suite, tt.name, client, r.provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +func TestRKE2ACETestSuite(t *testing.T) { + suite.Run(t, new(RKE2ACETestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/agent_customization_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/agent_customization_test.go new file mode 100644 index 0000000..5d4b065 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/agent_customization_test.go @@ -0,0 +1,199 @@ +//go:build validation + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE2AgentCustomizationTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE2AgentCustomizationTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE2AgentCustomizationTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE2AgentCustomizationTestSuite) TestProvisioningRKE2ClusterAgentCustomization() { + productionPool := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + productionPool[0].MachinePoolConfig.Quantity = 3 + productionPool[1].MachinePoolConfig.Quantity = 2 + productionPool[2].MachinePoolConfig.Quantity = 2 + + agentCustomization := management.AgentDeploymentCustomization{ + AppendTolerations: []management.Toleration{ + { + Key: "TestKeyToleration", + Value: "TestValueToleration", + }, + }, + OverrideResourceRequirements: &management.ResourceRequirements{ + Limits: map[string]string{ + "cpu": "750m", + "mem": "500Mi", + }, + Requests: map[string]string{ + "cpu": "250m", + }, + }, + OverrideAffinity: &management.Affinity{ + NodeAffinity: &management.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []management.PreferredSchedulingTerm{ + { + Preference: &management.NodeSelectorTerm{ + MatchExpressions: []management.NodeSelectorRequirement{ + { + Key: "testAffinityKey", + Operator: "In", + Values: []string{"true"}, + }, + }, + }, + Weight: 100, + }, + }, + }, + }, + } + + customAgents := []string{"fleet-agent", "cluster-agent"} + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + agent string + }{ + {"Custom Fleet Agent - Standard User", productionPool, r.standardUserClient, customAgents[0]}, + {"Custom Cluster Agent - Standard User", productionPool, r.standardUserClient, customAgents[1]}, + } + + for _, tt := range tests { + subSession := r.session.NewSession() + defer subSession.Cleanup() + + client, err := tt.client.WithSession(subSession) + require.NoError(r.T(), err) + r.provisioningConfig.MachinePools = tt.machinePools + + if tt.agent == "fleet-agent" { + r.provisioningConfig.FleetAgent = &agentCustomization + r.provisioningConfig.ClusterAgent = nil + } + + if tt.agent == "cluster-agent" { + r.provisioningConfig.ClusterAgent = &agentCustomization + r.provisioningConfig.FleetAgent = nil + } + + permutations.RunTestPermutations(&r.Suite, tt.name, client, r.provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +func (r *RKE2AgentCustomizationTestSuite) TestFailureProvisioningRKE2ClusterAgentCustomization() { + productionPool := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + productionPool[0].MachinePoolConfig.Quantity = 3 + productionPool[1].MachinePoolConfig.Quantity = 2 + productionPool[2].MachinePoolConfig.Quantity = 2 + + agentCustomization := management.AgentDeploymentCustomization{ + AppendTolerations: []management.Toleration{ + { + Key: "BadLabel", + Value: "123\"[];'{}-+=", + }, + }, + OverrideAffinity: &management.Affinity{}, + OverrideResourceRequirements: &management.ResourceRequirements{}, + } + + customAgents := []string{"fleet-agent", "cluster-agent"} + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + agent string + }{ + {"Invalid Custom Fleet Agent - Standard User", productionPool, r.standardUserClient, customAgents[0]}, + {"Invalid Custom Cluster Agent - Standard User", productionPool, r.standardUserClient, customAgents[1]}, + } + + for _, tt := range tests { + subSession := r.session.NewSession() + defer subSession.Cleanup() + + client, err := tt.client.WithSession(subSession) + require.NoError(r.T(), err) + r.provisioningConfig.MachinePools = tt.machinePools + + if tt.agent == "fleet-agent" { + r.provisioningConfig.FleetAgent = &agentCustomization + r.provisioningConfig.ClusterAgent = nil + } + + if tt.agent == "cluster-agent" { + r.provisioningConfig.ClusterAgent = &agentCustomization + r.provisioningConfig.FleetAgent = nil + } + + rke2Provider, _, _, kubeVersions := permutations.GetClusterProvider(permutations.RKE2ProvisionCluster, r.provisioningConfig.Providers[0], r.provisioningConfig) + testClusterConfig := clusters.ConvertConfigToClusterConfig(r.provisioningConfig) + testClusterConfig.KubernetesVersion = kubeVersions[0] + + _, err = provisioning.CreateProvisioningCluster(client, *rke2Provider, testClusterConfig, nil) + require.Error(r.T(), err) + } +} + +func TestRKE2AgentCustomizationTestSuite(t *testing.T) { + suite.Run(t, new(RKE2AgentCustomizationTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/custom_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/custom_cluster_test.go new file mode 100644 index 0000000..26b40b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/custom_cluster_test.go @@ -0,0 +1,169 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CustomClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config + isWindows bool +} + +func (c *CustomClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *CustomClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + c.isWindows = false + for _, pool := range c.provisioningConfig.MachinePools { + if pool.MachinePoolConfig.Windows { + c.isWindows = true + break + } + } + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.RKE2KubernetesVersions, err = kubernetesversions.Default(c.client, clusters.RKE2ClusterType.String(), c.provisioningConfig.RKE2KubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningRKE2CustomCluster() { + nodeRolesAll := []provisioninginput.MachinePools{ + provisioninginput.AllRolesMachinePool, + } + + nodeRolesShared := []provisioninginput.MachinePools{ + provisioninginput.EtcdControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + } + + nodeRolesDedicated := []provisioninginput.MachinePools{ + provisioninginput.EtcdMachinePool, + provisioninginput.ControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + } + + nodeRolesDedicatedWindows := []provisioninginput.MachinePools{ + provisioninginput.EtcdMachinePool, + provisioninginput.ControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + provisioninginput.WindowsMachinePool, + } + + nodeRolesDedicatedTwoWindows := []provisioninginput.MachinePools{ + provisioninginput.EtcdMachinePool, + provisioninginput.ControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + provisioninginput.WindowsMachinePool, + provisioninginput.WindowsMachinePool, + } + + tests := []struct { + name string + client *rancher.Client + machinePools []provisioninginput.MachinePools + isWindows bool + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesAll, false, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesShared, false, c.client.Flags.GetValue(environmentflag.Short) || c.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, false, c.client.Flags.GetValue(environmentflag.Long)}, + {"4 nodes - 1 role per node + 1 windows worker " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicatedWindows, true, c.client.Flags.GetValue(environmentflag.Long)}, + {"5 nodes - 1 role per node + 2 windows workers " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicatedTwoWindows, true, c.client.Flags.GetValue(environmentflag.Long)}, + } + for _, tt := range tests { + if !tt.runFlag { + c.T().Logf("SKIPPED") + continue + } + + testSession := session.NewSession() + defer testSession.Cleanup() + if (c.isWindows == tt.isWindows) || (c.isWindows && !tt.isWindows) { + provisioningConfig := *c.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE2CustomCluster, nil, nil) + } else { + c.T().Skip("Skipping Windows tests") + } + } +} + +func (c *CustomClusterProvisioningTestSuite) TestProvisioningRKE2CustomClusterDynamicInput() { + if len(c.provisioningConfig.MachinePools) == 0 { + c.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), c.client}, + {provisioninginput.StandardClientName.String(), c.standardUserClient}, + } + for _, tt := range tests { + testSession := session.NewSession() + defer testSession.Cleanup() + _, err := tt.client.WithSession(testSession) + require.NoError(c.T(), err) + + permutations.RunTestPermutations(&c.Suite, tt.name, tt.client, c.provisioningConfig, permutations.RKE2CustomCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestCustomClusterRKE2ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(CustomClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/hardened_cluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/hardened_cluster_test.go new file mode 100644 index 0000000..925e1f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/hardened_cluster_test.go @@ -0,0 +1,139 @@ +//go:build (validation || sanity) && !infra.any && !infra.aks && !infra.eks && !infra.rke2k3s && !infra.gke && !infra.rke1 && !cluster.any && !cluster.custom && !cluster.nodedriver && !extended && !stress + +package rke2 + +import ( + "testing" + + cis "github.com/rancher/rancher/tests/v2/validation/provisioning/resources/cisbenchmark" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type HardenedRKE2ClusterProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config + project *management.Project + chartInstallOptions *charts.InstallOptions + chartFeatureOptions *charts.RancherMonitoringOpts +} + +func (c *HardenedRKE2ClusterProvisioningTestSuite) TearDownSuite() { + c.session.Cleanup() +} + +func (c *HardenedRKE2ClusterProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + c.session = testSession + + c.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, c.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(c.T(), err) + + c.client = client + + c.provisioningConfig.RKE2KubernetesVersions, err = kubernetesversions.Default(c.client, clusters.RKE2ClusterType.String(), c.provisioningConfig.RKE2KubernetesVersions) + require.NoError(c.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(c.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(c.T(), err) + + c.standardUserClient = standardUserClient +} + +func (c *HardenedRKE2ClusterProvisioningTestSuite) TestProvisioningRKE2HardenedCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + + tests := []struct { + name string + client *rancher.Client + machinePools []provisioninginput.MachinePools + scanProfileName string + }{ + {"RKE2 CIS 1.8 Profile Hardened " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "rke2-cis-1.8-profile-hardened"}, + {"RKE2 CIS 1.8 Profile Permissive " + provisioninginput.StandardClientName.String(), c.standardUserClient, nodeRolesDedicated, "rke2-cis-1.8-profile-permissive"}, + } + for _, tt := range tests { + c.Run(tt.name, func() { + provisioningConfig := *c.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + provisioningConfig.Hardened = true + + nodeProviders := provisioningConfig.NodeProviders[0] + externalNodeProvider := provisioning.ExternalNodeProviderSetup(nodeProviders) + + testConfig := clusters.ConvertConfigToClusterConfig(&provisioningConfig) + testConfig.KubernetesVersion = c.provisioningConfig.RKE2KubernetesVersions[0] + + clusterObject, err := provisioning.CreateProvisioningCustomCluster(tt.client, &externalNodeProvider, testConfig) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + provisioning.VerifyCluster(c.T(), tt.client, testConfig, clusterObject) + + cluster, err := clusters.NewClusterMeta(tt.client, clusterObject.Name) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + latestCISBenchmarkVersion, err := tt.client.Catalog.GetLatestChartVersion(charts.CISBenchmarkName, catalog.RancherChartRepo) + require.NoError(c.T(), err) + + project, err := projects.GetProjectByName(tt.client, cluster.ID, cis.System) + reports.TimeoutClusterReport(clusterObject, err) + require.NoError(c.T(), err) + + c.project = project + require.NotEmpty(c.T(), c.project) + + c.chartInstallOptions = &charts.InstallOptions{ + Cluster: cluster, + Version: latestCISBenchmarkVersion, + ProjectID: c.project.ID, + } + + cis.SetupCISBenchmarkChart(tt.client, c.project.ClusterID, c.chartInstallOptions, charts.CISBenchmarkNamespace) + cis.RunCISScan(tt.client, c.project.ClusterID, tt.scanProfileName) + }) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestHardenedRKE2ClusterProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(HardenedRKE2ClusterProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/post_kdm_oob_release_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/post_kdm_oob_release_test.go new file mode 100644 index 0000000..3f1eaf1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/post_kdm_oob_release_test.go @@ -0,0 +1,72 @@ +//go:build validation + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type KdmChecksTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + ns string + provisioningConfig *provisioninginput.Config +} + +func (k *KdmChecksTestSuite) TearDownSuite() { + k.session.Cleanup() +} + +func (k *KdmChecksTestSuite) SetupSuite() { + testSession := session.NewSession() + k.session = testSession + + k.ns = "default" + + k.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, k.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(k.T(), err) + + k.client = client +} + +func (k *KdmChecksTestSuite) TestRKE2K8sVersions() { + logrus.Infof("checking for valid k8s versions..") + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.RKE2KubernetesVersions), 1) + // fetching all available k8s versions from rancher + releasedK8sVersions, _ := kubernetesversions.ListRKE2AllVersions(k.client) + logrus.Info("expected k8s versions : ", k.provisioningConfig.RKE2KubernetesVersions) + logrus.Info("k8s versions available on rancher server : ", releasedK8sVersions) + for _, expectedK8sVersion := range k.provisioningConfig.RKE2KubernetesVersions { + require.Contains(k.T(), releasedK8sVersions, expectedK8sVersion) + } +} + +func (k *KdmChecksTestSuite) TestProvisioningSingleNodeRKE2Clusters() { + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.Providers), 1) + require.GreaterOrEqual(k.T(), len(k.provisioningConfig.CNIs), 1) + + subSession := k.session.NewSession() + defer subSession.Cleanup() + + client, err := k.client.WithSession(subSession) + require.NoError(k.T(), err) + permutations.RunTestPermutations(&k.Suite, "oobRelease-", client, k.provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) +} + +func TestPostKdmOutOfBandReleaseChecks(t *testing.T) { + suite.Run(t, new(KdmChecksTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_cloud_provider_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_cloud_provider_test.go new file mode 100644 index 0000000..4fb11aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_cloud_provider_test.go @@ -0,0 +1,140 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package rke2 + +import ( + "slices" + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE2CloudProviderTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE2CloudProviderTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE2CloudProviderTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + r.client = client + + r.provisioningConfig.RKE2KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE2ClusterType.String(), r.provisioningConfig.RKE2KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE2CloudProviderTestSuite) TestAWSCloudProviderCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + nodeRolesDedicated[0].MachinePoolConfig.Quantity = 3 + nodeRolesDedicated[1].MachinePoolConfig.Quantity = 2 + nodeRolesDedicated[2].MachinePoolConfig.Quantity = 2 + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + runFlag bool + }{ + {"OutOfTree" + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + + if !slices.Contains(r.provisioningConfig.Providers, "aws") { + r.T().Skip("AWS Cloud Provider test requires access to aws.") + } + + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + + provisioningConfig := *r.provisioningConfig + provisioningConfig.CloudProvider = "aws" + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +func (r *RKE2CloudProviderTestSuite) TestVsphereCloudProviderCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + nodeRolesDedicated[0].MachinePoolConfig.Quantity = 3 + nodeRolesDedicated[1].MachinePoolConfig.Quantity = 2 + nodeRolesDedicated[2].MachinePoolConfig.Quantity = 2 + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + runFlag bool + }{ + {"OutOfTree" + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + + if !slices.Contains(r.provisioningConfig.Providers, "vsphere") { + r.T().Skip("Vsphere Cloud Provider test requires access to vsphere.") + } + + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + + provisioningConfig := *r.provisioningConfig + provisioningConfig.CloudProvider = "rancher-vsphere" + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE2CloudProviderTestSuite(t *testing.T) { + suite.Run(t, new(RKE2CloudProviderTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_node_driver_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_node_driver_test.go new file mode 100644 index 0000000..4fba427 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/provisioning_node_driver_test.go @@ -0,0 +1,120 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE2NodeDriverProvisioningTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE2NodeDriverProvisioningTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE2NodeDriverProvisioningTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + r.client = client + + r.provisioningConfig.RKE2KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE2ClusterType.String(), r.provisioningConfig.RKE2KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE2NodeDriverProvisioningTestSuite) TestProvisioningRKE2Cluster() { + nodeRolesAll := []provisioninginput.MachinePools{provisioninginput.AllRolesMachinePool} + nodeRolesShared := []provisioninginput.MachinePools{provisioninginput.EtcdControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + nodeRolesDedicated := []provisioninginput.MachinePools{provisioninginput.EtcdMachinePool, provisioninginput.ControlPlaneMachinePool, provisioninginput.WorkerMachinePool} + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + client *rancher.Client + runFlag bool + }{ + {"1 Node all roles " + provisioninginput.StandardClientName.String(), nodeRolesAll, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Short) || r.client.Flags.GetValue(environmentflag.Long)}, + {"2 nodes - etcd|cp roles per 1 node " + provisioninginput.StandardClientName.String(), nodeRolesShared, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Short) || r.client.Flags.GetValue(environmentflag.Long)}, + {"3 nodes - 1 role per node " + provisioninginput.StandardClientName.String(), nodeRolesDedicated, r.standardUserClient, r.client.Flags.GetValue(environmentflag.Long)}, + } + + for _, tt := range tests { + if !tt.runFlag { + r.T().Logf("SKIPPED") + continue + } + provisioningConfig := *r.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +func (r *RKE2NodeDriverProvisioningTestSuite) TestProvisioningRKE2ClusterDynamicInput() { + if len(r.provisioningConfig.MachinePools) == 0 { + r.T().Skip() + } + + tests := []struct { + name string + client *rancher.Client + }{ + {provisioninginput.AdminClientName.String(), r.client}, + {provisioninginput.StandardClientName.String(), r.standardUserClient}, + } + + for _, tt := range tests { + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, r.provisioningConfig, permutations.RKE2ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE2ProvisioningTestSuite(t *testing.T) { + suite.Run(t, new(RKE2NodeDriverProvisioningTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/psact_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/psact_test.go new file mode 100644 index 0000000..00f700e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/psact_test.go @@ -0,0 +1,118 @@ +//go:build validation + +package rke2 + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/users" + password "github.com/rancher/shepherd/extensions/users/passwordgenerator" + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RKE2PSACTTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + standardUserClient *rancher.Client + provisioningConfig *provisioninginput.Config +} + +func (r *RKE2PSACTTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *RKE2PSACTTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.provisioningConfig = new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, r.provisioningConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + r.provisioningConfig.RKE2KubernetesVersions, err = kubernetesversions.Default( + r.client, clusters.RKE2ClusterType.String(), r.provisioningConfig.RKE2KubernetesVersions) + require.NoError(r.T(), err) + + enabled := true + var testuser = namegen.AppendRandomString("testuser-") + var testpassword = password.GenerateUserPassword("testpass-") + user := &management.User{ + Username: testuser, + Password: testpassword, + Name: testuser, + Enabled: &enabled, + } + + newUser, err := users.CreateUserWithRole(client, user, "user") + require.NoError(r.T(), err) + + newUser.Password = user.Password + + standardUserClient, err := client.AsUser(newUser) + require.NoError(r.T(), err) + + r.standardUserClient = standardUserClient +} + +func (r *RKE2PSACTTestSuite) TestRKE2PSACTNodeDriverCluster() { + nodeRolesDedicated := []provisioninginput.MachinePools{ + provisioninginput.EtcdMachinePool, + provisioninginput.ControlPlaneMachinePool, + provisioninginput.WorkerMachinePool, + } + + tests := []struct { + name string + machinePools []provisioninginput.MachinePools + psact provisioninginput.PSACT + client *rancher.Client + }{ + { + name: "Rancher Privileged " + provisioninginput.StandardClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-privileged", + client: r.standardUserClient, + }, + { + name: "Rancher Restricted " + provisioninginput.StandardClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-restricted", + client: r.standardUserClient, + }, + { + name: "Rancher Baseline " + provisioninginput.AdminClientName.String(), + machinePools: nodeRolesDedicated, + psact: "rancher-baseline", + client: r.client, + }, + } + + for _, tt := range tests { + provisioningConfig := *r.provisioningConfig + provisioningConfig.MachinePools = tt.machinePools + provisioningConfig.PSACT = string(tt.psact) + permutations.RunTestPermutations(&r.Suite, tt.name, tt.client, &provisioningConfig, + permutations.RKE2ProvisionCluster, nil, nil) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestRKE2PSACTTestSuite(t *testing.T) { + suite.Run(t, new(RKE2PSACTTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/template_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/template_test.go new file mode 100644 index 0000000..aaa48cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/provisioning/rke2/template_test.go @@ -0,0 +1,85 @@ +//go:build (validation || extended) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke2k3s && !cluster.any && !cluster.custom && !cluster.nodedriver && !sanity && !stress + +package rke2 + +import ( + "testing" + "time" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/cloudcredentials" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/defaults/stevetypes" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/reports" + "github.com/rancher/shepherd/extensions/steve" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + localCluster = "local" + fleetNamespace = "fleet-default" + providerName = "rke2" + templateTestConfigKey = "templateTest" +) + +type ClusterTemplateTestSuite struct { + suite.Suite + client *rancher.Client + standardUserClient *rancher.Client + session *session.Session + templateConfig *provisioninginput.TemplateConfig + cloudCredentials *cloudcredentials.CloudCredential +} + +func (r *ClusterTemplateTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *ClusterTemplateTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + r.templateConfig = new(provisioninginput.TemplateConfig) + config.LoadConfig(templateTestConfigKey, r.templateConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + r.client = client + + provider := provisioning.CreateProvider(r.templateConfig.TemplateProvider) + r.cloudCredentials, err = provider.CloudCredFunc(client) + require.NoError(r.T(), err) +} + +func (r *ClusterTemplateTestSuite) TestProvisionRKE2TemplateCluster() { + _, err := steve.CreateAndWaitForResource(r.client, stevetypes.ClusterRepo, r.templateConfig.Repo, true, 5*time.Second, defaults.FiveMinuteTimeout) + require.NoError(r.T(), err) + + k8sversions, err := kubernetesversions.Default(r.client, providerName, nil) + require.NoError(r.T(), err) + + clusterName := namegenerator.AppendRandomString(providerName + "-template") + err = charts.InstallTemplateChart(r.client, r.templateConfig.Repo.ObjectMeta.Name, r.templateConfig.TemplateName, clusterName, k8sversions[0], r.cloudCredentials) + require.NoError(r.T(), err) + + _, cluster, err := clusters.GetProvisioningClusterByName(r.client, clusterName, fleetNamespace) + reports.TimeoutClusterReport(cluster, err) + require.NoError(r.T(), err) + + provisioning.VerifyCluster(r.T(), r.client, nil, cluster) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestClusterTemplateTestSuite(t *testing.T) { + suite.Run(t, new(ClusterTemplateTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation.go new file mode 100644 index 0000000..b51deba --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation.go @@ -0,0 +1,124 @@ +package crdgeneration + +import ( + "os" + "strings" + "testing" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/kubeapi/customresourcedefinitions" + "github.com/rancher/shepherd/extensions/kubectl" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + groupManagement = "management.cattle.io" + groupCatalog = "catalog.cattle.io" + groupUI = "ui.cattle.io" + groupCluster = "cluster.cattle.io" + groupProject = "project.cattle.io" + groupRKE = "rke.cattle.io" + groupProvisioning = "provisioning.cattle.io" + groupFleet = "fleet.cattle.io" + roleTemplate = "roletemplates.management.cattle.io" //Remove in 2.8.0 + fleetlocal = "fleet-local" + fleetdefault = "fleet-default" + crdJSONFilePath = "../resources/crds.json" + roleTemplateJSONPath = "../resources/roleTemplate.json" + localCluster = "local" +) + +func mapCRD(crdList []string) map[string][]string { + groups := []string{groupManagement, groupCatalog, groupUI, groupCluster, groupProject, groupRKE, groupProvisioning, groupFleet} + crdMap := make(map[string][]string) + + for _, group := range groups { + crdMap[group] = []string{} + } + + crdMap["additional"] = []string{} + + for _, crd := range crdList { + found := false + for _, group := range groups { + if strings.Contains(crd, group) { + crdMap[group] = append(crdMap[group], crd) + found = true + break + } + } + if !found { + crdMap["additional"] = append(crdMap["additional"], crd) + } + } + + return crdMap +} + +func listCRDS(client *rancher.Client, clusterID string) ([]string, error) { + crdCollection, err := customresourcedefinitions.ListCustomResourceDefinitions(client, clusterID, "") + if err != nil { + return nil, err + } + + crds := make([]string, len(crdCollection.Items)) + for idx, crd := range crdCollection.Items { + crds[idx] = crd.GetName() + } + return crds, nil +} + +func validateCRDList(t *testing.T, crdsList []string, crdMapPreUpgrade map[string][]string, clusterName string) { + crdMap := mapCRD(crdsList) + + if clusterName == "local" { + for group, value := range crdMap { + if group == "additional" || group == groupCluster { + continue + } + assert.Equal(t, crdMapPreUpgrade[group], value) + assert.Equal(t, len(crdMapPreUpgrade[group]), len(value)) + } + } +} + +func validateCRDDescription(t *testing.T, client *rancher.Client, clusterV1 *v1.Cluster, clusterID string) { + + explain := []string{"kubectl", "explain", roleTemplate} + logs, err := kubectl.Command(client, nil, clusterID, explain, "") + require.NoError(t, err) + assert.NotEmpty(t, logs) + desIndexStart := strings.Index(logs, "DESCRIPTION:") + desIndexEnd := strings.Index(logs, "FIELDS") + if desIndexStart == -1 { + t.Log("Pod logs do not contain description field") + t.FailNow() + } + if desIndexEnd == -1 { + desIndexEnd = len(logs) - 1 + } + + description := logs[desIndexStart+len("DESCRIPTION:") : desIndexEnd] + assert.NotContains(t, description, "") + log.Info(description) +} + +func validateRoleCreation(t *testing.T, client *rancher.Client, clusterV1 *v1.Cluster, clusterID string) { + role, err := os.ReadFile(roleTemplateJSONPath) + require.NoError(t, err) + + yamlInput := &management.ImportClusterYamlInput{ + YAML: string(role), + } + + apply := []string{"kubectl", "apply", "-f", "/root/.kube/my-pod.yaml"} + podLogs, err := kubectl.Command(client, yamlInput, clusterID, apply, "") + require.NoError(t, err) + errorLogs := "Unsupported value: \"invalid\": supported values: \"project\", \"cluster\"" + + assert.Contains(t, podLogs, errorLogs) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation_test.go new file mode 100644 index 0000000..f77ea72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/publicapi/crdgeneration/crd_generation_test.go @@ -0,0 +1,74 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package crdgeneration + +import ( + "context" + "encoding/json" + "os" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/pkg/session" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type CRDGenTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + crds map[string][]string +} + +func (crd *CRDGenTestSuite) TearDownSuite() { + crd.session.Cleanup() +} + +func (crd *CRDGenTestSuite) SetupSuite() { + testSession := session.NewSession() + crd.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(crd.T(), err) + + crd.client = client + readJson, err := os.ReadFile(crdJSONFilePath) + require.NoError(crd.T(), err) + err = json.Unmarshal(readJson, &crd.crds) + require.NoError(crd.T(), err) + +} + +func (crd *CRDGenTestSuite) sequentialTestCRD() { + kubeClient, err := crd.client.GetKubeAPIProvisioningClient() + require.NoError(crd.T(), err) + + clusterV1, err := kubeClient.Clusters(fleetlocal).Get(context.TODO(), localCluster, metav1.GetOptions{}) + require.NoError(crd.T(), err) + + crdsList, err := listCRDS(crd.client, localCluster) + require.NoError(crd.T(), err) + + crd.Run("Verify the count of crds deployed and the crds on the cluster "+localCluster, func() { + validateCRDList(crd.T(), crdsList, crd.crds, localCluster) + }) + crd.Run("Verify description fields of crds are non-empty", func() { + validateCRDDescription(crd.T(), crd.client, clusterV1, localCluster) + }) + crd.Run("Verify kubectl validate for role templates", func() { + validateRoleCreation(crd.T(), crd.client, clusterV1, localCluster) + }) +} + +func (crd *CRDGenTestSuite) TestCRDGen() { + subSession := crd.session.NewSession() + defer subSession.Cleanup() + crd.sequentialTestCRD() +} + +func TestCRDGenTestSuite(t *testing.T) { + suite.Run(t, new(CRDGenTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/README.md new file mode 100644 index 0000000..17b11ce --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/README.md @@ -0,0 +1,39 @@ +# Rbac + +## Getting Started +Your GO suite should be set to `-run ^Test<>TestSuite$`. For example to run the rbac_additional_test.go, set the GO suite to `-run ^TestRBACAdditionalTestSuite$` You can find specific tests by checking the test file you plan to run. +In your config file, set the following: + +```json +"rancher": { + "host": "rancher_server_address", + "adminToken": "rancher_admin_token", + "clusterName": "cluster_to_run_tests_on", + "insecure": true/optional, + "cleanup": false/optional, +} +``` + +For the rbac_additional_test.go run, we need the following paramters to be passed in the config file as we create an rke1 cluster +Please use the following links to continue adding to your config for provisioning tests: + [Define your test](../provisioning/rke1/README.md#provisioning-input) +(#Provisioning-Input) + [Configure providers to use for Node Driver Clusters](../provisioning/rke1/README.md#NodeTemplateConfigs) + +# RBAC input +rbacInput is needed to the run the TestRBACDynamicInput tests, specifically username, password and a cluster/project role. role takes the following as input only. Role takes a single value. +Dynamic input will be executed on a single cluster. If the user is added to multiple downstream clusters, only the clusterName specified in the Rancher config will be taken into account. Some tests like VerifyListCluster may fail when the user is added in more than one downstream clusters. +User must be already created in the rancher server. If any other format of roles is provided, the tests fail to run: + +`cluster-owner` +`cluster-member` +`project-owner` +`project-member` +`restricted-admin` + +```json +rbacInput: + role: "cluster-owner" + username: "" + password: "" +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/README.md new file mode 100644 index 0000000..52cf486 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/README.md @@ -0,0 +1,60 @@ +# Rbac + +## Getting Started +Your GO suite should be set to `-run ^Test<>TestSuite$`. For example to run the cluster_role_test.go, set the GO suite to `-run ^TestClusterRoleTestSuite$` You can find specific tests by checking the test file you plan to run. +Config needed for each of the suites cluster_role_test.go, project_role_test.go and restrictedadmin_role_test.go require the following config: + +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True #optional + cleanup: True #optional + clusterName: "downstream_cluster_name" +``` + +For the restrictedadmin_role_test.go run, we need the following additional paramters to be passed in the config file as we create a downstream cluster. We require rke1 custom cluster config as the test creates an RKE1 cluster: + +```yaml +provisioningInput: + nodePools: + - nodeRoles: + controlplane: true + etcd: true + quantity: 1 + worker: true + cni: + - calico + providers: + - aws + nodeProviders: + - ec2 + hardened: false + psact: "" +awsEC2Configs: + region: us-east-2 + awsSecretAccessKey: + awsAccessKeyID: + awsEC2Config: + - instanceType: t3a.xlarge + awsRegionAZ: "" + awsAMI: + awsSecurityGroups: + - + awsSSHKeyName: + awsIAMProfile: + awsUser: ubuntu + volumeSize: 100 + roles: + - etcd + - controlplane + - worker +sshPath: + sshPath: +``` + +For more info, please use the following links to continue adding to your config for provisioning tests: + [Define your test](../provisioning/rke1/README.md#provisioning-input) +(#Provisioning-Input) + + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/cluster_role_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/cluster_role_test.go new file mode 100644 index 0000000..03372b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/cluster_role_test.go @@ -0,0 +1,149 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package clusterandprojectroles + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type ClusterRoleTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (rb *ClusterRoleTestSuite) TearDownSuite() { + rb.session.Cleanup() +} + +func (rb *ClusterRoleTestSuite) SetupSuite() { + rb.session = session.NewSession() + + client, err := rancher.NewClient("", rb.session) + require.NoError(rb.T(), err) + + rb.client = client + + log.Info("Getting cluster name from the config file and append cluster details in rb") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(rb.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(rb.client, clusterName) + require.NoError(rb.T(), err, "Error getting cluster ID") + rb.cluster, err = rb.client.Management.Cluster.ByID(clusterID) + require.NoError(rb.T(), err) +} + +func (rb *ClusterRoleTestSuite) TestClusterOwnerAddsUserAsProjectOwner() { + subSession := rb.session.NewSession() + defer subSession.Cleanup() + + clusterAdmin, clusterAdminClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + additionalUser, additionalUserClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + rb.T().Logf("Adding user as " + rbac.ClusterOwner.String() + " to the downstream cluster.") + err = users.AddClusterRoleToUser(rb.client, rb.cluster, clusterAdmin, rbac.ClusterOwner.String(), nil) + require.NoError(rb.T(), err) + clusterAdminClient, err = clusterAdminClient.ReLogin() + require.NoError(rb.T(), err) + + clusterOwnerProject, err := clusterAdminClient.Management.Project.Create(projects.NewProjectConfig(rb.cluster.ID)) + require.NoError(rb.T(), err) + err = users.AddProjectMember(clusterAdminClient, clusterOwnerProject, additionalUser, rbac.ProjectOwner.String(), nil) + require.NoError(rb.T(), err) + + projectListClusterAdditionalUser, err := projects.ListProjectNames(additionalUserClient, rb.cluster.ID) + require.NoError(rb.T(), err) + assert.Equal(rb.T(), 1, len(projectListClusterAdditionalUser)) + assert.Equal(rb.T(), clusterOwnerProject.Name, projectListClusterAdditionalUser[0]) + + err = users.RemoveProjectMember(clusterAdminClient, additionalUser) + require.NoError(rb.T(), err) + projectListClusterAdditionalUser, err = projects.ListProjectNames(additionalUserClient, rb.cluster.ID) + require.Empty(rb.T(), projectListClusterAdditionalUser) +} + +func (rb *ClusterRoleTestSuite) TestClusterOwnerAddsUserAsClusterOwner() { + subSession := rb.session.NewSession() + defer subSession.Cleanup() + + clusterAdmin, clusterAdminClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + err = users.AddClusterRoleToUser(rb.client, rb.cluster, clusterAdmin, rbac.ClusterOwner.String(), nil) + require.NoError(rb.T(), err) + clusterAdminClient, err = clusterAdminClient.ReLogin() + require.NoError(rb.T(), err) + + additionalUser, additionalUserClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + err = users.AddClusterRoleToUser(clusterAdminClient, rb.cluster, additionalUser, rbac.ClusterOwner.String(), nil) + require.NoError(rb.T(), err) + additionalUserClient, err = additionalUserClient.ReLogin() + require.NoError(rb.T(), err) + + clusterList, err := additionalUserClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ListAll(nil) + require.NoError(rb.T(), err) + assert.Equal(rb.T(), 1, len(clusterList.Data)) + + err = users.RemoveClusterRoleFromUser(clusterAdminClient, additionalUser) + require.NoError(rb.T(), err) + clusterList, err = additionalUserClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ListAll(nil) + require.Empty(rb.T(), clusterList.Data) +} + +func (rb *ClusterRoleTestSuite) TestClusterOwnerAddsClusterMemberAsProjectOwner() { + subSession := rb.session.NewSession() + defer subSession.Cleanup() + + clusterAdmin, clusterAdminClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + err = users.AddClusterRoleToUser(rb.client, rb.cluster, clusterAdmin, rbac.ClusterOwner.String(), nil) + require.NoError(rb.T(), err) + clusterAdminClient, err = clusterAdminClient.ReLogin() + require.NoError(rb.T(), err) + + additionalUser, additionalUserClient, err := rbac.SetupUser(rb.client, rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + err = users.AddClusterRoleToUser(clusterAdminClient, rb.cluster, additionalUser, rbac.ClusterMember.String(), nil) + require.NoError(rb.T(), err) + additionalUserClient, err = additionalUserClient.ReLogin() + require.NoError(rb.T(), err) + + clusterList, err := additionalUserClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ListAll(nil) + require.NoError(rb.T(), err) + assert.Equal(rb.T(), 1, len(clusterList.Data)) + + clusterOwnerProject, err := clusterAdminClient.Management.Project.Create(projects.NewProjectConfig(rb.cluster.ID)) + require.NoError(rb.T(), err) + + err = users.AddProjectMember(clusterAdminClient, clusterOwnerProject, additionalUser, rbac.ProjectOwner.String(), nil) + require.NoError(rb.T(), err) + projectListProjectOwner, err := projects.ListProjectNames(additionalUserClient, rb.cluster.ID) + require.NoError(rb.T(), err) + + assert.Equal(rb.T(), 1, len(projectListProjectOwner)) + assert.Equal(rb.T(), clusterOwnerProject.Name, projectListProjectOwner[0]) +} + +func TestClusterRoleTestSuite(t *testing.T) { + suite.Run(t, new(ClusterRoleTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/project_role_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/project_role_test.go new file mode 100644 index 0000000..cb07a79 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/project_role_test.go @@ -0,0 +1,119 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package clusterandprojectroles + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/projects" + rbac "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type ProjectRolesTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (pr *ProjectRolesTestSuite) TearDownSuite() { + pr.session.Cleanup() +} + +func (pr *ProjectRolesTestSuite) SetupSuite() { + pr.session = session.NewSession() + client, err := rancher.NewClient("", pr.session) + require.NoError(pr.T(), err) + + pr.client = client + + log.Info("Getting cluster name from the config file and append cluster details in pr") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(pr.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(pr.client, clusterName) + require.NoError(pr.T(), err, "Error getting cluster ID") + pr.cluster, err = pr.client.Management.Cluster.ByID(clusterID) + require.NoError(pr.T(), err) +} + +func (pr *ProjectRolesTestSuite) testSetupUserAndProject() (*rancher.Client, *management.Project) { + pr.T().Log("Set up User with cluster Role for additional rbac test cases " + rbac.ClusterOwner) + newUser, standardUserClient, err := rbac.SetupUser(pr.client, rbac.StandardUser.String()) + require.NoError(pr.T(), err) + + createProjectAsAdmin, err := pr.client.Management.Project.Create(projects.NewProjectConfig(pr.cluster.ID)) + require.NoError(pr.T(), err) + + log.Info("Adding a standard user as project Owner in the admin project") + errUserRole := users.AddProjectMember(pr.client, createProjectAsAdmin, newUser, rbac.ProjectOwner.String(), nil) + require.NoError(pr.T(), errUserRole) + standardUserClient, err = standardUserClient.ReLogin() + require.NoError(pr.T(), err) + return standardUserClient, createProjectAsAdmin +} + +func (pr *ProjectRolesTestSuite) TestProjectOwnerAddsAndRemovesOtherProjectOwners() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + standardUserClient, adminProject := pr.testSetupUserAndProject() + additionalUser, additionalUserClient, err := rbac.SetupUser(pr.client, rbac.StandardUser.String()) + require.NoError(pr.T(), err) + + errUserRole := users.AddProjectMember(standardUserClient, adminProject, additionalUser, rbac.ProjectOwner.String(), nil) + require.NoError(pr.T(), errUserRole) + additionalUserClient, err = additionalUserClient.ReLogin() + require.NoError(pr.T(), err) + + userGetProject, err := projects.ListProjectNames(additionalUserClient, pr.cluster.ID) + require.NoError(pr.T(), err) + assert.Equal(pr.T(), 1, len(userGetProject)) + assert.Equal(pr.T(), adminProject.Name, userGetProject[0]) + + errRemoveMember := users.RemoveProjectMember(standardUserClient, additionalUser) + require.NoError(pr.T(), errRemoveMember) + + userProjectEmptyAfterRemoval, err := projects.ListProjectNames(additionalUserClient, pr.cluster.ID) + require.Empty(pr.T(), userProjectEmptyAfterRemoval) +} + +func (pr *ProjectRolesTestSuite) TestManageProjectUserRoleCannotAddProjectOwner() { + subSession := pr.session.NewSession() + defer subSession.Cleanup() + + standardUserClient, adminProject := pr.testSetupUserAndProject() + additionalUser, additionalUserClient, err := rbac.SetupUser(pr.client, rbac.StandardUser.String()) + require.NoError(pr.T(), err) + + errUserRole := users.AddProjectMember(standardUserClient, adminProject, additionalUser, rbac.CustomManageProjectMember.String(), nil) + require.NoError(pr.T(), errUserRole) + additionalUserClient, err = additionalUserClient.ReLogin() + require.NoError(pr.T(), err) + + addNewUserAsProjectOwner, addNewUserAsPOClient, err := rbac.SetupUser(pr.client, rbac.StandardUser.String()) + require.NoError(pr.T(), err) + + errUserRole2 := users.AddProjectMember(additionalUserClient, adminProject, addNewUserAsProjectOwner, rbac.ProjectOwner.String(), nil) + require.Error(pr.T(), errUserRole2) + assert.Contains(pr.T(), errUserRole2.Error(), "422 Unprocessable Entity") + + addNewUserAsPOClient, err = addNewUserAsPOClient.ReLogin() + require.NoError(pr.T(), err) + + userGetProject, err := projects.ListProjectNames(addNewUserAsPOClient, pr.cluster.ID) + require.NoError(pr.T(), err) + assert.Equal(pr.T(), 0, len(userGetProject)) +} + +func TestProjectRolesTestSuite(t *testing.T) { + suite.Run(t, new(ProjectRolesTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/restrictedadmin_role_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/restrictedadmin_role_test.go new file mode 100644 index 0000000..5ac1823 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/clusterandprojectroles/restrictedadmin_role_test.go @@ -0,0 +1,118 @@ +package clusterandprojectroles + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + rbac "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/settings" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RestrictedAdminTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (ra *RestrictedAdminTestSuite) TearDownSuite() { + ra.session.Cleanup() +} + +func (ra *RestrictedAdminTestSuite) SetupSuite() { + ra.session = session.NewSession() + + client, err := rancher.NewClient("", ra.session) + require.NoError(ra.T(), err) + + ra.client = client + + log.Info("Getting cluster name from the config file and append cluster details in the struct.") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(ra.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(ra.client, clusterName) + require.NoError(ra.T(), err, "Error getting cluster ID") + ra.cluster, err = ra.client.Management.Cluster.ByID(clusterID) + require.NoError(ra.T(), err) +} + +func (ra *RestrictedAdminTestSuite) TestRestrictedAdminCreateCluster() { + subSession := ra.session.NewSession() + defer subSession.Cleanup() + + _, restrictedAdminClient, err := rbac.SetupUser(ra.client, rbac.RestrictedAdmin.String()) + require.NoError(ra.T(), err) + ra.T().Logf("Validating restricted admin can create a downstream cluster") + userConfig := new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, userConfig) + nodeProviders := userConfig.NodeProviders[0] + nodeAndRoles := []provisioninginput.NodePools{ + provisioninginput.AllRolesNodePool, + } + externalNodeProvider := provisioning.ExternalNodeProviderSetup(nodeProviders) + clusterConfig := clusters.ConvertConfigToClusterConfig(userConfig) + clusterConfig.NodePools = nodeAndRoles + kubernetesVersion, err := kubernetesversions.Default(restrictedAdminClient, clusters.RKE1ClusterType.String(), []string{}) + require.NoError(ra.T(), err) + + clusterConfig.KubernetesVersion = kubernetesVersion[0] + clusterConfig.CNI = userConfig.CNIs[0] + clusterObject, _, err := provisioning.CreateProvisioningRKE1CustomCluster(restrictedAdminClient, &externalNodeProvider, clusterConfig) + require.NoError(ra.T(), err) + provisioning.VerifyRKE1Cluster(ra.T(), restrictedAdminClient, clusterConfig, clusterObject) +} + +func (ra *RestrictedAdminTestSuite) TestRestrictedAdminGlobalSettings() { + + subSession := ra.session.NewSession() + defer subSession.Cleanup() + + _, restrictedAdminClient, err := rbac.SetupUser(ra.client, rbac.RestrictedAdmin.String()) + require.NoError(ra.T(), err) + ra.T().Log("Validating restricted Admin can list global settings") + steveRestrictedAdminclient := restrictedAdminClient.Steve + steveAdminClient := ra.client.Steve + + adminListSettings, err := steveAdminClient.SteveType(settings.ManagementSetting).List(nil) + require.NoError(ra.T(), err) + adminSettings := adminListSettings.Names() + + resAdminListSettings, err := steveRestrictedAdminclient.SteveType(settings.ManagementSetting).List(nil) + require.NoError(ra.T(), err) + resAdminSettings := resAdminListSettings.Names() + + assert.Equal(ra.T(), len(adminSettings), len(resAdminSettings)) + assert.Equal(ra.T(), adminSettings, resAdminSettings) +} + +func (ra *RestrictedAdminTestSuite) TestRestrictedAdminCantUpdateGlobalSettings() { + ra.T().Logf("Validating restrictedAdmin cannot edit global settings") + + _, restrictedAdminClient, err := rbac.SetupUser(ra.client, rbac.RestrictedAdmin.String()) + require.NoError(ra.T(), err) + + steveRestrictedAdminclient := restrictedAdminClient.Steve + steveAdminClient := ra.client.Steve + + kubeConfigTokenSetting, err := steveAdminClient.SteveType(settings.ManagementSetting).ByID(settings.KubeConfigToken) + require.NoError(ra.T(), err) + + _, err = settings.UpdateGlobalSettings(steveRestrictedAdminclient, kubeConfigTokenSetting, "3") + require.Error(ra.T(), err) + assert.Contains(ra.T(), err.Error(), "Resource type [management.cattle.io.setting] is not updatable") +} + +func TestRestrictedAdminTestSuite(t *testing.T) { + suite.Run(t, new(RestrictedAdminTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/README.md new file mode 100644 index 0000000..2c21ce5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/README.md @@ -0,0 +1,18 @@ +# ClusterRoleTemplateBinding(v1) +This repository contains Golang automation tests for the ClusterRoleTemplateBinding functionality by SteveAPI(V1) and kubectl. This is part of Public API functionality to generate Custom Resource Definitions (CRD's) for ClusterRoleTemplateBinding. ClusterRoleTemplateBindings is allowing users to perform all the CRUD operations by using SteveAPI(V1) OR kubectl. These automation tests contains both success and error test cases to make sure the functionality is working as expected. + +## Pre-requisites +- Ensure you have an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, create one first before running this test. + +## Test Setup +Your GO suite should be set to `-run ^TestCRTBGenTestSuite$`. You can find specific tests by checking the test file you plan to run. + +In your config file, set the following: +``` +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True + cleanup: True + clusterName: "downstream_cluster_name" +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_create_steve_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_create_steve_test.go new file mode 100644 index 0000000..d7cfc0a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_create_steve_test.go @@ -0,0 +1,171 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package crtb + +import ( + "testing" + + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CRTBGenTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + clusterID string + newUser *management.User +} + +func (crtb *CRTBGenTestSuite) TearDownSuite() { + crtb.session.Cleanup() +} + +func (crtb *CRTBGenTestSuite) SetupSuite() { + testSession := session.NewSession() + crtb.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(crtb.T(), err) + + crtb.client = client + + crtb.clusterID, err = clusters.GetClusterIDByName(crtb.client, client.RancherConfig.ClusterName) + require.NoError(crtb.T(), err, "Error getting cluster ID") + + crtb.newUser, err = users.CreateUserWithRole(client, users.UserConfig()) + require.NoError(crtb.T(), err) +} + +func (crtb *CRTBGenTestSuite) TestCreateCrtbWithAllRequiredInputValues() { + client := crtb.client + + tests := []struct { + roleTemplateName string + }{ + {clusterOwner}, + {clusterMember}, + {crtbManage}, + } + for _, rtn := range tests { + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, rtn.roleTemplateName) + + resp, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.NoError(crtb.T(), err) + assert.Contains(crtb.T(), (*resp).JSONResp["id"], crtbName) + assert.Contains(crtb.T(), (*resp).JSONResp["clusterName"], crtb.clusterID) + assert.Contains(crtb.T(), (*resp).JSONResp["userName"], crtb.newUser.ID) + assert.Contains(crtb.T(), (*resp).JSONResp["roleTemplateName"], rtn.roleTemplateName) + } +} + +func (crtb *CRTBGenTestSuite) TestCreateCrtbWithUserPrincipalNameAsInput() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.UserPrincipalName = "local://" + crtb.newUser.ID + + resp, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.NoError(crtb.T(), err) + + assert.Contains(crtb.T(), (*resp).JSONResp["id"], crtbName) + assert.Contains(crtb.T(), (*resp).JSONResp["clusterName"], crtb.clusterID) + assert.Contains(crtb.T(), (*resp).JSONResp["userName"], crtb.newUser.ID) + assert.Contains(crtb.T(), (*resp).JSONResp["roleTemplateName"], clusterMember) + assert.Equal(crtb.T(), (*resp).JSONResp["userPrincipalName"], clusterRoleTemplateBinding.UserPrincipalName) +} + +func (crtb *CRTBGenTestSuite) TestCreateCrtbAndInputLabels() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.ObjectMeta.Labels = map[string]string{"Hello": "World"} + + resp, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.NoError(crtb.T(), err) + + assert.Contains(crtb.T(), (*resp).JSONResp["id"], crtbName) + assert.Contains(crtb.T(), (*resp).JSONResp["clusterName"], crtb.clusterID) + assert.Contains(crtb.T(), (*resp).JSONResp["userName"], crtb.newUser.ID) + assert.Contains(crtb.T(), (*resp).JSONResp["roleTemplateName"], clusterMember) + assert.NotContains(crtb.T(), (*resp).JSONResp, clusterRoleTemplateBinding.Labels) +} + +func (crtb *CRTBGenTestSuite) TestValidateErrorAlreadyCrtbExisted() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + + resp, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.NoError(crtb.T(), err) + assert.Contains(crtb.T(), (*resp).JSONResp["id"], crtbName) + + _, err = client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.Error(crtb.T(), err) + require.ErrorContains(crtb.T(), err, crtbConflictError) + require.ErrorContains(crtb.T(), err, crtbAlreadyExisted) +} + +func (crtb *CRTBGenTestSuite) TestValidateErrorRoleTemplateNameDoesNotExist() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.RoleTemplateName = "roleTemplateNameNotExisted" + + _, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.Error(crtb.T(), err) + require.ErrorContains(crtb.T(), err, badRequest) +} + +func (crtb *CRTBGenTestSuite) TestValidateErrorBadRequestByPassingDifferentClusterAndNamespace() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.ClusterName = localCluster + + _, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.Error(crtb.T(), err) + require.ErrorContains(crtb.T(), err, badRequest) +} + +func (crtb *CRTBGenTestSuite) TestValidateErrorNamespaceNameDoesNotExist() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.ClusterName = "namespacenotexisted" + + _, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.Error(crtb.T(), err) + require.ErrorContains(crtb.T(), err, badRequest) +} + +func (crtb *CRTBGenTestSuite) TestValidateErrorClusterNameAndNamespaceNameDifferent() { + client := crtb.client + crtbName := namegen.RandStringLower(crtbNameWithTenChar) + + clusterRoleTemplateBinding := clusterRoleTemplateBindingTemplate(crtb.clusterID, crtbName, crtb.newUser.ID, clusterMember) + clusterRoleTemplateBinding.ClusterName = localCluster + + _, err := client.Steve.SteveType(crtbAPIEndPoint).Create(clusterRoleTemplateBinding) + require.Error(crtb.T(), err) + require.ErrorContains(crtb.T(), err, cluserNameAndNamespaceSameValue) +} + +func TestCRTBGenTestSuite(t *testing.T) { + suite.Run(t, new(CRTBGenTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_steve.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_steve.go new file mode 100644 index 0000000..270b830 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/crtb/crtb_steve.go @@ -0,0 +1,40 @@ +package crtb + +import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + crtbAPIEndPoint = "management.cattle.io.clusterroletemplatebinding" + apiVersion = "management.cattle.io/v3" + kind = "ClusterRoleTemplateBinding" + localCluster = "local" + clusterOwner = "cluster-owner" + clusterMember = "cluster-member" + crtbManage = "clusterroletemplatebindings-manage" + crtbNameWithTenChar = 10 + crtbConflictError = "409 Conflict" + crtbAlreadyExisted = "AlreadyExists" + badRequest = "400 Bad Request" + notFound = "404 Not Found" + cluserNameAndNamespaceSameValue = "Forbidden: clusterName and namespace must be the same value" +) + +func clusterRoleTemplateBindingTemplate(clusterID string, crtbName string, newUser string, roleTemplateName string) v3.ClusterRoleTemplateBinding { + crtbTemplate := v3.ClusterRoleTemplateBinding{ + TypeMeta: metav1.TypeMeta{ + APIVersion: apiVersion, + Kind: kind, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: clusterID, + Name: crtbName, + }, + ClusterName: clusterID, + RoleTemplateName: roleTemplateName, + UserName: newUser, + } + + return crtbTemplate +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/README.md new file mode 100644 index 0000000..7ab4da5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/README.md @@ -0,0 +1,80 @@ +# Global Roles v2 +Global Roles v2 introduces enhanced capabilities, allowing users to define permissions across all downstream clusters. This update aims to address the limitations of predefined roles, particularly challenges associated with the Restricted Admin role. + +## Pre-requisites +- Ensure you have an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, create one first before running this test. +- Some tests require creating additional downstream cluster. Providing the provisioningInput parameter with appropriate values is mandatory unless you are skipping those tests. + +## Test Setup +* For [globalroles_v2 checks](globalroles_v2_test.go), your GO suite should be set to `-run ^TestGlobalRolesV2TestSuite$`. You can find specific tests by checking the test file you plan to run. +* For [globalroles_v2 webhook checks](globalroles_v2_webhook_test.go), your GO suite should be set to `-run ^TestGlobalRolesV2WebhookTestSuite$`. You can find specific tests by checking the test file you plan to run. + +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True #optional + cleanup: True #optional + clusterName: "downstream_cluster_name" +provisioningInput: + machinePools: + - machinePoolConfig: + etcd: true + controlplane: true + worker: true + quantity: 1 + nodePools: + - nodeRoles: + etcd: true + controlplane: true + worker: true + quantity: 1 + rke1KubernetesVersion: + - "v1.28.10-rancher1-1" + rke2KubernetesVersion: + - "v1.28.10+rke2r1" + k3sKubernetesVersion: + - "v1.28.10+k3s1" + cni: + - "calico" + providers: + - "aws" + nodeProviders: + - "ec2" +awsCredentials: + accessKey: "" + secretKey: "" + defaultRegion: "us-east-2" + +awsMachineConfig: + region: "us-east-2" + instanceType: "t3a.xlarge" + sshUser: "ubuntu" + vpcId: "" + volumeType: "gp2" + zone: "a" + retries: 5 + rootSize: 50 + securityGroup: + - "rancher-nodes" + +awsEC2Configs: + region: "us-east-2" + awsAccessKeyID: "" + awsSecretAccessKey: "" + awsEC2Config: + - instanceType: "t3a.xlarge" + awsRegionAZ: "" + awsAMI: "" + awsSecurityGroups: ["sg-0e753fd5550206e55"] + awsSSHKeyName: "" + awsCICDInstanceTag: "rancher-validation" + awsIAMProfile: "EngineeringUsersUS" + awsUser: "ubuntu" + volumeSize: 50 + roles: ["etcd", "controlplane", "worker"] + isWindows: false +sshPath: + sshPath: "" +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2.go new file mode 100644 index 0000000..b3abfb6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2.go @@ -0,0 +1,305 @@ +package globalrolesv2 + +import ( + "context" + "fmt" + "strings" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/shepherd/pkg/config" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeapi/projects" + rbacapi "github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/provisioninginput" + + "github.com/rancher/rancher/tests/v2/actions/rbac" + "github.com/rancher/shepherd/extensions/kubeapi/namespaces" + "github.com/rancher/shepherd/extensions/users" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + localcluster = "local" + ownerLabel = "authz.management.cattle.io/grb-owner" + namespace = "fleet-default" + localPrefix = "local://" + clusterContext = "cluster" + projectContext = "project" + bindingLabel = "membership-binding-owner" + globalDataNamespace = "cattle-global-data" + defaultNamespace = "default" +) + +var ( + globalRole = v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + }, + InheritedClusterRoles: []string{}, + } + + globalRoleBinding = &v3.GlobalRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: "", + }, + GlobalRoleName: "", + UserName: "", + } + + readSecretsPolicy = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"secrets"}, + } + + readCRTBsPolicy = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"clusterroletemplatebindings"}, + } + + readPods = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{""}, + Resources: []string{"pods"}, + } + + readAllResourcesPolicy = rbacv1.PolicyRule{ + Verbs: []string{"get", "list", "watch"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + } + + secret = corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: namegen.AppendRandomString("secret-"), + }, + Data: map[string][]byte{ + "key": []byte(namegen.RandStringLower(5)), + }, + } +) + +func createGlobalRoleWithInheritedClusterRolesWrangler(client *rancher.Client, inheritedRoles []string) (*v3.GlobalRole, error) { + globalRole.Name = namegen.AppendRandomString("testgr") + globalRole.InheritedClusterRoles = inheritedRoles + createdGlobalRole, err := client.WranglerContext.Mgmt.GlobalRole().Create(&globalRole) + if err != nil { + return nil, err + } + + return createdGlobalRole, nil +} + +func getGlobalRoleBindingForUserWrangler(client *rancher.Client, userID string) (string, error) { + grblist, err := client.WranglerContext.Mgmt.GlobalRoleBinding().List(metav1.ListOptions{}) + if err != nil { + return "", err + } + + for _, grbs := range grblist.Items { + if grbs.GlobalRoleName == globalRole.Name && grbs.UserName == userID { + return grbs.Name, nil + } + } + return "", nil +} + +func listClusterRoleTemplateBindingsForInheritedClusterRoles(client *rancher.Client, grbOwner string, expectedCount int) (*v3.ClusterRoleTemplateBindingList, error) { + req, err := labels.NewRequirement(ownerLabel, selection.In, []string{grbOwner}) + + if err != nil { + return nil, err + } + + selector := labels.NewSelector().Add(*req) + + var crtbs *v3.ClusterRoleTemplateBindingList + + err = kwait.Poll(defaults.FiveHundredMillisecondTimeout, defaults.OneMinuteTimeout, func() (done bool, pollErr error) { + crtbs, pollErr = rbacapi.ListClusterRoleTemplateBindings(client, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + if pollErr != nil { + return false, pollErr + } + if len(crtbs.Items) == expectedCount { + return true, nil + } + return false, nil + }) + + if err != nil { + return nil, err + } + + return crtbs, nil +} + +func getCRBsForCRTBs(client *rancher.Client, crtbs *v3.ClusterRoleTemplateBindingList) (*rbacv1.ClusterRoleBindingList, error) { + var downstreamCRBs rbacv1.ClusterRoleBindingList + + for _, crtb := range crtbs.Items { + labelKey := fmt.Sprintf("%s_%s", crtb.ClusterName, crtb.Name) + req, err := labels.NewRequirement(labelKey, selection.In, []string{bindingLabel}) + + if err != nil { + return nil, err + } + + selector := labels.NewSelector().Add(*req) + downstreamCRBsForCRTB, err := rbacapi.ListClusterRoleBindings(client, localcluster, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + + if err != nil { + return nil, err + } + + downstreamCRBs.Items = append(downstreamCRBs.Items, downstreamCRBsForCRTB.Items...) + } + + return &downstreamCRBs, nil +} + +func getRBsForCRTBs(client *rancher.Client, crtbs *v3.ClusterRoleTemplateBindingList) (*rbacv1.RoleBindingList, error) { + var downstreamRBs rbacv1.RoleBindingList + + for _, crtb := range crtbs.Items { + roleTemplateName := crtb.RoleTemplateName + + if strings.Contains(roleTemplateName, "rt") { + listOpt := metav1.ListOptions{ + FieldSelector: "metadata.name=" + roleTemplateName, + } + roleTemplateList, err := rbacapi.ListRoleTemplates(client, listOpt) + if err != nil { + return nil, err + } + roleTemplateName = roleTemplateList.Items[0].RoleTemplateNames[0] + } + + nameSelector := fmt.Sprintf("metadata.name=%s-%s", crtb.Name, roleTemplateName) + namespaceSelector := fmt.Sprintf("metadata.namespace=%s", crtb.ClusterName) + combinedSelector := fmt.Sprintf("%s,%s", nameSelector, namespaceSelector) + downstreamRBsForCRTB, err := rbacapi.ListRoleBindings(client, localcluster, "", metav1.ListOptions{ + FieldSelector: combinedSelector, + }) + + if err != nil { + return nil, err + } + + downstreamRBs.Items = append(downstreamRBs.Items, downstreamRBsForCRTB.Items...) + } + + return &downstreamRBs, nil +} + +func createDownstreamCluster(client *rancher.Client, clusterType string) (*management.Cluster, *v1.SteveAPIObject, *clusters.ClusterConfig, error) { + provisioningConfig := new(provisioninginput.Config) + config.LoadConfig(provisioninginput.ConfigurationFileKey, provisioningConfig) + nodeProviders := provisioningConfig.NodeProviders[0] + externalNodeProvider := provisioning.ExternalNodeProviderSetup(nodeProviders) + testClusterConfig := clusters.ConvertConfigToClusterConfig(provisioningConfig) + testClusterConfig.CNI = provisioningConfig.CNIs[0] + + var clusterObject *management.Cluster + var steveObject *v1.SteveAPIObject + var err error + + switch clusterType { + case "RKE1": + nodeAndRoles := []provisioninginput.NodePools{ + provisioninginput.AllRolesNodePool, + } + testClusterConfig.NodePools = nodeAndRoles + testClusterConfig.KubernetesVersion = provisioningConfig.RKE1KubernetesVersions[0] + clusterObject, _, err = provisioning.CreateProvisioningRKE1CustomCluster(client, &externalNodeProvider, testClusterConfig) + case "RKE2": + nodeAndRoles := []provisioninginput.MachinePools{ + provisioninginput.AllRolesMachinePool, + } + testClusterConfig.MachinePools = nodeAndRoles + testClusterConfig.KubernetesVersion = provisioningConfig.RKE2KubernetesVersions[0] + steveObject, err = provisioning.CreateProvisioningCustomCluster(client, &externalNodeProvider, testClusterConfig) + default: + return nil, nil, nil, fmt.Errorf("unsupported cluster type: %s", clusterType) + } + + if err != nil { + return nil, nil, nil, err + } + + return clusterObject, steveObject, testClusterConfig, nil +} + +func createGlobalRoleAndUser(client *rancher.Client, inheritedClusterrole []string) (*management.User, error) { + globalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(client, inheritedClusterrole) + if err != nil { + return nil, err + } + + createdUser, err := users.CreateUserWithRole(client, users.UserConfig(), rbac.StandardUser.String(), globalRole.Name) + if err != nil { + return nil, err + } + + return createdUser, err +} + +func crtbStatus(client *rancher.Client, crtbName string, selector labels.Selector) error { + ctx, cancel := context.WithTimeout(context.Background(), defaults.TwoMinuteTimeout) + defer cancel() + + err := kwait.PollUntilContextCancel(ctx, defaults.FiveHundredMillisecondTimeout, false, func(ctx context.Context) (done bool, err error) { + crtbs, err := rbacapi.ListClusterRoleTemplateBindings(client, metav1.ListOptions{ + LabelSelector: selector.String(), + }) + if err != nil { + return false, err + } + + for _, newcrtb := range crtbs.Items { + if crtbName == newcrtb.Name { + return false, nil + } + } + return true, nil + }) + + return err +} + +func createGlobalRoleWithNamespacedRules(client *rancher.Client, namespacedRules map[string][]rbacv1.PolicyRule) (*v3.GlobalRole, error) { + globalRole.Name = namegen.AppendRandomString("test-nsr") + globalRole.NamespacedRules = namespacedRules + createdGlobalRole, err := rbacapi.CreateGlobalRole(client, &globalRole) + if err != nil { + return nil, err + } + return createdGlobalRole, nil +} + +func createProjectAndAddANamespace(client *rancher.Client, nsPrefix string) (string, error) { + project := projects.NewProjectTemplate(localcluster) + customProject, err := client.WranglerContext.Mgmt.Project().Create(project) + if err != nil { + return "", err + } + customNS1, err := namespaces.CreateNamespace(client, localcluster, customProject.Name, namegen.AppendRandomString(nsPrefix), "", nil, nil) + return customNS1.Name, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_test.go new file mode 100644 index 0000000..74f03bc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_test.go @@ -0,0 +1,486 @@ +//go:build (validation || infra.any || cluster.any || stress) && !sanity && !extended + +package globalrolesv2 + +import ( + "testing" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + rbacapi "github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/users" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" + "github.com/rancher/rancher/tests/v2/actions/rbac" +) + +type GlobalRolesV2TestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (gr *GlobalRolesV2TestSuite) TearDownSuite() { + gr.session.Cleanup() +} + +func (gr *GlobalRolesV2TestSuite) SetupSuite() { + testSession := session.NewSession() + gr.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(gr.T(), err) + + gr.client = client + +} + +func (gr *GlobalRolesV2TestSuite) validateRBACResources(createdUser *management.User, inheritedRoles []string) (string, int) { + log.Info("Verify that the global role binding is created for the user.") + grbOwner, err := getGlobalRoleBindingForUserWrangler(gr.client, createdUser.ID) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grbOwner, "Global Role Binding not found for the user") + grbName := grbOwner + + log.Info("Verify that the cluster role template bindings are created for the downstream clusters.") + clusterNames, err := clusters.ListDownstreamClusters(gr.client) + require.NoError(gr.T(), err) + clusterCount := len(clusterNames) + expectedCrtbCount := clusterCount * len(inheritedRoles) + crtbs, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(gr.client, grbOwner, expectedCrtbCount) + require.NoError(gr.T(), err) + actualCrtbCount := len(crtbs.Items) + require.Equal(gr.T(), expectedCrtbCount, actualCrtbCount, "Unexpected number of ClusterRoleTemplateBindings: Expected %d, Actual %d", expectedCrtbCount, actualCrtbCount) + + log.Info("Verify that the cluster role bindings are created for the downstream cluster.") + expectedCrbCount := expectedCrtbCount + crbs, err := getCRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualCrbCount := len(crbs.Items) + require.Equal(gr.T(), expectedCrbCount, actualCrbCount, "Unexpected number of ClusterRoleBindings: Expected %d, Actual %d", expectedCrbCount, actualCrbCount) + + log.Info("Verify that the role bindings are created for the downstream cluster.") + expectedRbCount := expectedCrtbCount + rbs, err := getRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualRbCount := len(rbs.Items) + require.Equal(gr.T(), expectedRbCount, actualRbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", expectedRbCount, actualRbCount) + return grbName, clusterCount +} + +func (gr *GlobalRolesV2TestSuite) TestCreateUserWithInheritedClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterOwner.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + gr.validateRBACResources(createdUser, inheritedClusterRoles) +} + +func (gr *GlobalRolesV2TestSuite) TestCreateUserWithMultipleInheritedClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.CrtbView.String(), rbac.ProjectsCreate.String(), rbac.ProjectsView.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + gr.validateRBACResources(createdUser, inheritedClusterRoles) +} + +func (gr *GlobalRolesV2TestSuite) TestCreateUserWithInheritedCustomClusterRole() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a custom role that inherits rules from the cluster-owner.") + inheritedRoleTemplateName := namegen.AppendRandomString("crole") + inheritedRoleTemplate, err := gr.client.Management.RoleTemplate.Create(&management.RoleTemplate{ + Context: "cluster", + Name: inheritedRoleTemplateName, + RoleTemplateIDs: []string{rbac.ClusterOwner.String()}, + }) + require.NoError(gr.T(), err) + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{inheritedRoleTemplate.ID} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + _, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Verify that the user can list all the downstream clusters.") + userClient, err := gr.client.AsUser(createdUser) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", expectedClusterCount, actualClusterCount) +} + +func (gr *GlobalRolesV2TestSuite) TestClusterCreationAfterAddingGlobalRoleWithInheritedClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterMember.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + _, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Verify that the user can list all the downstream clusters.") + userClient, err := gr.client.AsUser(createdUser) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", expectedClusterCount, actualClusterCount) + + log.Info("As the new user, create new downstream clusters.") + clusterObject, _, testClusterConfig, err := createDownstreamCluster(userClient, "RKE1") + require.NoError(gr.T(), err) + provisioning.VerifyRKE1Cluster(gr.T(), userClient, testClusterConfig, clusterObject) + _, steveObject, testClusterConfig, err := createDownstreamCluster(userClient, "RKE2") + require.NoError(gr.T(), err) + provisioning.VerifyCluster(gr.T(), userClient, testClusterConfig, steveObject) + + gr.validateRBACResources(createdUser, inheritedClusterRoles) +} + +func (gr *GlobalRolesV2TestSuite) TestUpdateExistingUserWithCustomGlobalRoleInheritingClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterOwner.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String()) + require.NoError(gr.T(), err) + + log.Info("Add the new global role with inheritedClusterRoles to the user.") + globalRoleBinding.Name = namegen.AppendRandomString("testgrb") + globalRoleBinding.UserName = createdUser.ID + globalRoleBinding.GlobalRoleName = createdGlobalRole.Name + _, err = rbacapi.CreateGlobalRoleBinding(gr.client, globalRoleBinding) + require.NoError(gr.T(), err) + + _, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Verify that the user can list all the downstream clusters.") + userClient, err := gr.client.AsUser(createdUser) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", expectedClusterCount, actualClusterCount) +} + +func (gr *GlobalRolesV2TestSuite) TestUserDeletionAndResourceCleanupWithInheritedClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterOwner.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + grbName, _ := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Infof("Delete the user: %s.", createdUser.Username) + err = gr.client.Management.User.Delete(createdUser) + require.NoError(gr.T(), err) + + log.Infof("Verify that the global role %s is not deleted.", createdGlobalRole.Name) + listOpt := metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdGlobalRole.Name, + } + grList, err := rbacapi.ListGlobalRoles(gr.client, listOpt) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grList, "Global Role does not exist.") + + log.Infof("Verify that the global role binding %s is deleted for the user.", grbName) + var grbOwner string + err = kwait.Poll(defaults.FiveHundredMillisecondTimeout, defaults.TenSecondTimeout, func() (done bool, pollErr error) { + grbOwner, pollErr = getGlobalRoleBindingForUserWrangler(gr.client, createdUser.ID) + if pollErr != nil { + return false, pollErr + } + if grbOwner == "" { + return true, nil + } + return false, nil + }) + require.NoError(gr.T(), err) + require.Empty(gr.T(), grbOwner, "Global Role Binding exists for the user.") + + log.Info("Verify that the cluster role template bindings are deleted for the downstream clusters.") + expectedCrtbCount := 0 + crtbs, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(gr.client, grbOwner, expectedCrtbCount) + require.NoError(gr.T(), err) + actualCrtbCount := len(crtbs.Items) + require.Equal(gr.T(), expectedCrtbCount, actualCrtbCount, "Unexpected number of ClusterRoleTemplateBindings: Expected %d, Actual %d", expectedCrtbCount, actualCrtbCount) + + log.Info("Verify that the cluster role bindings are deleted for the downstream cluster.") + crbs, err := getCRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualCrbCount := len(crbs.Items) + require.Equal(gr.T(), 0, actualCrbCount, "Unexpected number of ClusterRoleBindings: Expected %d, Actual %d", 0, actualCrbCount) + + log.Info("Verify that the role bindings are deleted for the downstream cluster.") + rbs, err := getRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualRbCount := len(rbs.Items) + require.Equal(gr.T(), 0, actualRbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", 0, actualRbCount) +} + +func (gr *GlobalRolesV2TestSuite) TestUserWithInheritedClusterRolesImpactFromDeletingGlobalRoleBinding() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterOwner.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + grbName, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Verify that the user can list all the downstream clusters.") + userClient, err := gr.client.AsUser(createdUser) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", expectedClusterCount, actualClusterCount) + + log.Info("Delete Global Role Binding.") + err = rbacapi.DeleteGlobalRoleBinding(gr.client, grbName) + require.NoError(gr.T(), err) + + log.Info("Verify that the global role is not deleted.") + listOpt := metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdGlobalRole.Name, + } + grList, err := rbacapi.ListGlobalRoles(gr.client, listOpt) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grList, "Global Role does not exist.") + + log.Info("Verify that the global role binding is deleted for the user.") + grbOwner, err := getGlobalRoleBindingForUserWrangler(gr.client, createdUser.ID) + require.NoError(gr.T(), err) + require.Empty(gr.T(), grbOwner, "Global Role Binding exists for the user.") + + log.Info("Verify that the cluster role template bindings are deleted for the downstream clusters.") + expectedCrtbCount := 0 + crtbs, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(gr.client, grbOwner, expectedCrtbCount) + require.NoError(gr.T(), err) + actualCrtbCount := len(crtbs.Items) + require.Equal(gr.T(), expectedCrtbCount, actualCrtbCount, "Unexpected number of ClusterRoleTemplateBindings: Expected %d, Actual %d", expectedCrtbCount, actualCrtbCount) + + log.Info("Verify that the cluster role bindings are deleted for the downstream cluster.") + crbs, err := getCRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualCrbCount := len(crbs.Items) + require.Equal(gr.T(), 0, actualCrbCount, "Unexpected number of ClusterRoleBindings: Expected %d, Actual %d", 0, actualCrbCount) + + log.Info("Verify that the role bindings are deleted for the downstream cluster.") + rbs, err := getRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualRbCount := len(rbs.Items) + require.Equal(gr.T(), 0, actualRbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", 0, actualRbCount) + + log.Infof("Verify that user %s cannot list the downstream clusters.", createdUser.ID) + clusterNames, err = clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount = len(clusterNames) + require.Equal(gr.T(), 0, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", 0, actualClusterCount) +} + +func (gr *GlobalRolesV2TestSuite) TestUserWithInheritedClusterRolesImpactFromDeletingInheritedClusterRoles() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterMember.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + _, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Create another user with global role standard user and the same global role as the first user.") + secondUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + gr.validateRBACResources(secondUser, inheritedClusterRoles) + users := []*management.User{createdUser, secondUser} + + for _, user := range users { + log.Infof("Verify that user %s can list all the downstream clusters.", user.ID) + userClient, err := gr.client.AsUser(user) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters for user %s. Expected %d, Actual %d.", user.ID, expectedClusterCount, actualClusterCount) + } + + log.Info("Remove InheritedClusterRoles from the global role.") + updateGlobalRole := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdGlobalRole.Name, + }, + InheritedClusterRoles: []string{}, + } + _, err = rbacapi.UpdateGlobalRole(gr.client, &updateGlobalRole) + require.NoError(gr.T(), err) + + for _, user := range users { + log.Infof("Verify that the global role binding is not deleted for user %s.", user.ID) + grbOwner, err := getGlobalRoleBindingForUserWrangler(gr.client, user.ID) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grbOwner, "Global Role Binding does not exist for user %s", user.ID) + + log.Infof("Verify that the cluster role template bindings are deleted for user %s.", user.ID) + crtbs, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(gr.client, grbOwner, 0) + require.NoError(gr.T(), err) + actualCrtbCount := len(crtbs.Items) + require.Equal(gr.T(), 0, actualCrtbCount, "Unexpected number of ClusterRoleTemplateBindings for user %s: Expected %d, Actual %d", user.ID, 0, actualCrtbCount) + + log.Infof("Verify that the cluster role bindings are deleted for the downstream cluster.") + crbs, err := getCRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualCrbCount := len(crbs.Items) + require.Equal(gr.T(), 0, actualCrbCount, "Unexpected number of ClusterRoleBindings: Expected %d, Actual %d", 0, actualCrbCount) + + log.Info("Verify that the role bindings are deleted for the downstream cluster.") + rbs, err := getRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualRbCount := len(rbs.Items) + require.Equal(gr.T(), 0, actualRbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", 0, actualRbCount) + + log.Infof("Verify that user %s cannot list the downstream clusters.", user.ID) + userClient, err := gr.client.AsUser(user) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.Error(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), 0, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", 0, actualClusterCount) + } +} + +func (gr *GlobalRolesV2TestSuite) TestUserWithInheritedClusterRolesImpactFromClusterDeletion() { + subSession := gr.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a RKE2 downstream cluster.") + _, rke2SteveObject, testClusterConfig, err := createDownstreamCluster(gr.client, "RKE2") + require.NoError(gr.T(), err) + provisioning.VerifyCluster(gr.T(), gr.client, testClusterConfig, rke2SteveObject) + + log.Info("Create a global role with inheritedClusterRoles.") + inheritedClusterRoles := []string{rbac.ClusterOwner.String()} + createdGlobalRole, err := createGlobalRoleWithInheritedClusterRolesWrangler(gr.client, inheritedClusterRoles) + require.NoError(gr.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(gr.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(gr.T(), err) + + _, expectedClusterCount := gr.validateRBACResources(createdUser, inheritedClusterRoles) + + log.Info("Verify that the user can list all the downstream clusters.") + userClient, err := gr.client.AsUser(createdUser) + require.NoError(gr.T(), err) + clusterNames, err := clusters.ListDownstreamClusters(userClient) + require.NoError(gr.T(), err) + actualClusterCount := len(clusterNames) + require.Equal(gr.T(), expectedClusterCount, actualClusterCount, "Unexpected number of Clusters: Expected %d, Actual %d", expectedClusterCount, actualClusterCount) + + log.Info("Delete the RKE2 downstream cluster.") + err = clusters.DeleteK3SRKE2Cluster(userClient, rke2SteveObject.ID) + require.NoError(gr.T(), err) + + log.Info("Verify that the global role is not deleted.") + listOpt := metav1.ListOptions{ + FieldSelector: "metadata.name=" + createdGlobalRole.Name, + } + grList, err := rbacapi.ListGlobalRoles(gr.client, listOpt) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grList, "Global Role does not exist.") + + log.Info("Verify that the global role binding is not deleted for the user.") + grbOwner, err := getGlobalRoleBindingForUserWrangler(gr.client, createdUser.ID) + require.NoError(gr.T(), err) + require.NotEmpty(gr.T(), grbOwner, "Global Role Binding does not exist for the user.") + + log.Info("Verify that the cluster role template bindings are deleted for the downstream cluster.") + expectedCrtbCount := actualClusterCount - 1 + crtbs, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(gr.client, grbOwner, expectedCrtbCount) + require.NoError(gr.T(), err) + actualCrtbCount := len(crtbs.Items) + require.Equal(gr.T(), expectedCrtbCount, actualCrtbCount, "Unexpected number of ClusterRoleTemplateBindings: Expected %d, Actual %d", expectedCrtbCount, actualCrtbCount) + + log.Info("Verify that the cluster role bindings are deleted for the downstream cluster.") + expectedCrbCount := expectedCrtbCount + crbs, err := getCRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualCrbCount := len(crbs.Items) + require.Equal(gr.T(), expectedCrbCount, actualCrbCount, "Unexpected number of ClusterRoleBindings: Expected %d, Actual %d", expectedCrbCount, actualCrbCount) + + log.Info("Verify that the role bindings are deleted for the downstream cluster.") + expectedRbCount := expectedCrtbCount + rbs, err := getRBsForCRTBs(gr.client, crtbs) + require.NoError(gr.T(), err) + actualRbCount := len(rbs.Items) + require.Equal(gr.T(), expectedRbCount, actualRbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", expectedRbCount, actualRbCount) +} + +func TestGlobalRolesV2TestSuite(t *testing.T) { + suite.Run(t, new(GlobalRolesV2TestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_webhook_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_webhook_test.go new file mode 100644 index 0000000..e9fcfa4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/globalroles_v2_webhook_test.go @@ -0,0 +1,300 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package globalrolesv2 + +import ( + "regexp" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + rbacapi"github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/users" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/rancher/rancher/tests/v2/actions/rbac" +) + +type GlobalRolesV2WebhookTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + clusterCount int +} + +func (grw *GlobalRolesV2WebhookTestSuite) TearDownSuite() { + grw.session.Cleanup() +} + +func (grw *GlobalRolesV2WebhookTestSuite) SetupSuite() { + grw.session = session.NewSession() + + client, err := rancher.NewClient("", grw.session) + require.NoError(grw.T(), err) + + grw.client = client + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(grw.T(), clusterName, "Cluster name to install should be set") + + clusterNames, err := clusters.ListDownstreamClusters(grw.client) + grw.clusterCount = len(clusterNames) + require.NoError(grw.T(), err) + +} + +func getCRTBFromGRBOwner(t *testing.T, client *rancher.Client, user *management.User, expectedCrtbCount int) (*v3.ClusterRoleTemplateBindingList, error, string) { + log.Info("Verify that the global role binding is created for the user.") + grbOwner, err := getGlobalRoleBindingForUserWrangler(client, user.ID) + require.NoError(t, err) + require.NotEmpty(t, grbOwner, "Global Role Binding not found for the user") + + log.Info("Verify that the cluster role template bindings are created for the downstream clusters.") + crtbList, err := listClusterRoleTemplateBindingsForInheritedClusterRoles(client, grbOwner, expectedCrtbCount) + + return crtbList, err, grbOwner + +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestRemoveOwnerLabelRejectedByWebhook() { + subSession := grw.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with inheritedClusterRoles and verify removing the grb owner label is rejected.") + user, err := createGlobalRoleAndUser(grw.client, []string{rbac.ClusterOwner.String()}) + require.NoError(grw.T(), err) + + crtbList, err, _ := getCRTBFromGRBOwner(grw.T(), grw.client, user, grw.clusterCount) + require.NoError(grw.T(), err) + + var existingCRTB = &v3.ClusterRoleTemplateBinding{} + for _, crtb := range crtbList.Items { + existingCRTB = crtb.DeepCopy() + newLabels := crtb.Labels + if newLabels == nil { + newLabels = make(map[string]string) + } + delete(newLabels, ownerLabel) + crtbWithUpdatedLabels := &v3.ClusterRoleTemplateBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: crtb.Name, + Namespace: crtb.ObjectMeta.Namespace, + Labels: newLabels, + Annotations: crtb.Annotations, + }, + ClusterName: crtb.ClusterName, + UserName: crtb.UserName, + RoleTemplateName: crtb.RoleTemplateName, + UserPrincipalName: crtb.UserPrincipalName, + } + + _, err = rbacapi.UpdateClusterRoleTemplateBindings(grw.client, existingCRTB, crtbWithUpdatedLabels) + require.Error(grw.T(), err) + + expectedErrMessage := "admission webhook \"rancher.cattle.io.clusterroletemplatebindings.management.cattle.io\" denied the request: clusterroletemplatebinding.labels: Forbidden: label authz.management.cattle.io/grb-owner is immutable after creation" + assert.Contains(grw.T(), err.Error(), expectedErrMessage) + + } + +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestLockedRoleTemplateInInheritedClusterRole() { + + log.Info("Verify adding a locked custom cluster role template is rejected by webhook.") + + roleTemplate := &v3.RoleTemplate{} + roleTemplate.Name = namegen.AppendRandomString("customrole") + roleTemplate.RoleTemplateNames = []string{rbac.ClusterOwner.String()} + roleTemplate.Context = clusterContext + roleTemplate.Locked = true + lockedRoleTemplate, err := rbacapi.CreateRoleTemplate(grw.client, roleTemplate) + require.NoError(grw.T(), err) + + _, err = createGlobalRoleWithInheritedClusterRolesWrangler(grw.client, []string{lockedRoleTemplate.Name}) + require.Error(grw.T(), err) + + pattern := "^admission webhook.*" + regexp.QuoteMeta(lockedRoleTemplate.Name+"\": unable to use locked roleTemplate") + "$" + require.Regexp(grw.T(), regexp.MustCompile(pattern), err.Error()) +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestAddGlobalRoleWithCustomTemplateAndLockRoleTemplate() { + + log.Info("Verify adding a custom cluster role template and then locking the template is not rejected by webhook.") + + roleTemplate := &v3.RoleTemplate{} + roleTemplate.Name = namegen.AppendRandomString("customrole") + roleTemplate.RoleTemplateNames = []string{rbac.ClusterOwner.String()} + roleTemplate.Context = clusterContext + customRoleTemplate, err := rbacapi.CreateRoleTemplate(grw.client, roleTemplate) + require.NoError(grw.T(), err) + + _, err = createGlobalRoleWithInheritedClusterRolesWrangler(grw.client, []string{customRoleTemplate.Name}) + require.NoError(grw.T(), err) + + customRoleTemplate.Locked = true + lockCustomRoleTemplate, err := rbacapi.UpdateRoleTemplate(grw.client, customRoleTemplate) + require.NoError(grw.T(), err) + assert.Equal(grw.T(), lockCustomRoleTemplate.Locked, true) + +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestDeleteCustomRoleTemplateInInheritedClusterRole() { + log.Info("Verify deleting a custom cluster role template thats inherited by global role is rejected.") + inheritedRoleTemplateName := namegen.AppendRandomString("customrole") + inheritedRoleTemplate, err := grw.client.Management.RoleTemplate.Create(&management.RoleTemplate{ + Context: "cluster", + Name: inheritedRoleTemplateName, + RoleTemplateIDs: []string{rbac.ClusterOwner.String()}, + }) + require.NoError(grw.T(), err) + + _, err = createGlobalRoleWithInheritedClusterRolesWrangler(grw.client, []string{inheritedRoleTemplate.ID}) + require.NoError(grw.T(), err) + + err = rbacapi.DeleteRoletemplate(grw.client, inheritedRoleTemplate.ID) + require.Error(grw.T(), err) + + pattern := "^admission webhook .*" + regexp.QuoteMeta("cannot be deleted because it is inherited by globalRole(s) \"") + regexp.QuoteMeta(globalRole.Name) + "\"$" + require.Regexp(grw.T(), regexp.MustCompile(pattern), err.Error()) +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestAddProjectRoleTemplateInInheritedClusterRole() { + log.Info("Verify adding a project role template is rejected by webhook.") + inheritedRoleTemplateName := namegen.AppendRandomString("customrole") + inheritedRoleTemplate, err := grw.client.Management.RoleTemplate.Create(&management.RoleTemplate{ + Context: projectContext, + Name: inheritedRoleTemplateName, + RoleTemplateIDs: []string{rbac.ProjectOwner.String()}, + }) + require.NoError(grw.T(), err) + + _, err = createGlobalRoleWithInheritedClusterRolesWrangler(grw.client, []string{inheritedRoleTemplate.ID}) + require.Error(grw.T(), err) + + pattern := "admission webhook.*" + regexp.QuoteMeta("unable to bind a roleTemplate with non-cluster context: project") + require.Regexp(grw.T(), regexp.MustCompile(pattern), err.Error()) + +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestRoleTemplateWithBadUserSubject() { + + log.Info("Verify creating a cluster role template binding with the label grb Owner for a new user is rejected by webhook") + user, err := createGlobalRoleAndUser(grw.client, []string{rbac.ClusterOwner.String()}) + require.NoError(grw.T(), err) + + crtbList, err, grbOwner := getCRTBFromGRBOwner(grw.T(), grw.client, user, grw.clusterCount) + require.NoError(grw.T(), err) + + for _, crtb := range crtbList.Items { + log.Info("Create a new user with global role standard user and custom global role.") + + createdUser, err := users.CreateUserWithRole(grw.client, users.UserConfig(), rbac.StandardUser.String(), globalRole.Name) + require.NoError(grw.T(), err) + + clusterRoleTemplateBinding := &v3.ClusterRoleTemplateBinding{} + + clusterRoleTemplateBinding.Name = namegen.AppendRandomString("test-") + clusterRoleTemplateBinding.Namespace = crtb.Namespace + clusterRoleTemplateBinding.UserName = createdUser.Name + clusterRoleTemplateBinding.RoleTemplateName = crtb.RoleTemplateName + clusterRoleTemplateBinding.UserPrincipalName = localPrefix + createdUser.Name + clusterRoleTemplateBinding.Labels = crtb.Labels + clusterRoleTemplateBinding.ClusterName = crtb.ClusterName + + createdCRTB, err := rbacapi.CreateClusterRoleTemplateBinding(grw.client, clusterRoleTemplateBinding) + require.NoError(grw.T(), err) + + req, err := labels.NewRequirement(ownerLabel, selection.In, []string{grbOwner}) + require.NoError(grw.T(), err) + + selector := labels.NewSelector().Add(*req) + + err = crtbStatus(grw.client, createdCRTB.Name, selector) + require.NoError(grw.T(), err, "Newly created CRTB exists and not deleted") + } +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestDuplicateCRTBsAreDeleted() { + + log.Info("Verify creating a duplicate crtb and adding the grbOwner as label gets deleted.") + user, err := createGlobalRoleAndUser(grw.client, []string{rbac.ClusterOwner.String()}) + require.NoError(grw.T(), err) + + crtbList, err, grbOwner := getCRTBFromGRBOwner(grw.T(), grw.client, user, grw.clusterCount) + require.NoError(grw.T(), err) + + for _, crtb := range crtbList.Items { + clusterRoleTemplateBinding := &v3.ClusterRoleTemplateBinding{} + + clusterRoleTemplateBinding.Name = namegen.AppendRandomString("test-") + clusterRoleTemplateBinding.Namespace = crtb.Namespace + clusterRoleTemplateBinding.UserName = user.Name + clusterRoleTemplateBinding.RoleTemplateName = crtb.RoleTemplateName + clusterRoleTemplateBinding.UserPrincipalName = localPrefix + user.Name + clusterRoleTemplateBinding.Labels = crtb.Labels + clusterRoleTemplateBinding.ClusterName = crtb.ClusterName + createdCRTB, err := rbacapi.CreateClusterRoleTemplateBinding(grw.client, clusterRoleTemplateBinding) + require.NoError(grw.T(), err) + + req, err := labels.NewRequirement(ownerLabel, selection.In, []string{grbOwner}) + require.NoError(grw.T(), err) + + selector := labels.NewSelector().Add(*req) + + err = crtbStatus(grw.client, createdCRTB.Name, selector) + require.NoError(grw.T(), err, "Newly created CRTB exists and not deleted") + } + +} + +func (grw *GlobalRolesV2WebhookTestSuite) TestCRTBWithLocalClusterReferenceIsDeleted() { + + log.Info("Create a global role with inheritedClusterRoles and a user added to the global role.") + user, err := createGlobalRoleAndUser(grw.client, []string{rbac.ClusterOwner.String()}) + require.NoError(grw.T(), err) + + crtbList, err, grbOwner := getCRTBFromGRBOwner(grw.T(), grw.client, user, grw.clusterCount) + require.NoError(grw.T(), err) + + for _, crtb := range crtbList.Items { + + log.Info("Create a new user with global role standard user and custom global role.") + + createdUser, err := users.CreateUserWithRole(grw.client, users.UserConfig(), rbac.StandardUser.String(), globalRole.Name) + require.NoError(grw.T(), err) + + clusterRoleTemplateBinding := &v3.ClusterRoleTemplateBinding{} + + clusterRoleTemplateBinding.Name = namegen.AppendRandomString("test-") + clusterRoleTemplateBinding.Namespace = localcluster + clusterRoleTemplateBinding.UserName = createdUser.Name + clusterRoleTemplateBinding.RoleTemplateName = crtb.RoleTemplateName + clusterRoleTemplateBinding.UserPrincipalName = localPrefix + createdUser.Name + clusterRoleTemplateBinding.Annotations = crtb.Annotations + clusterRoleTemplateBinding.Labels = crtb.Labels + clusterRoleTemplateBinding.ClusterName = localcluster + + createdCRTB, err := rbacapi.CreateClusterRoleTemplateBinding(grw.client, clusterRoleTemplateBinding) + require.NoError(grw.T(), err) + + req, err := labels.NewRequirement(ownerLabel, selection.In, []string{grbOwner}) + require.NoError(grw.T(), err) + selector := labels.NewSelector().Add(*req) + + err = crtbStatus(grw.client, createdCRTB.Name, selector) + require.NoError(grw.T(), err, "Newly created CRTB exists and not deleted") + } +} + +func TestGlobalRolesV2WebhookTestSuite(t *testing.T) { + suite.Run(t, new(GlobalRolesV2WebhookTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/namespacedrules_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/namespacedrules_test.go new file mode 100644 index 0000000..a606f57 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/globalrolesv2/namespacedrules_test.go @@ -0,0 +1,555 @@ +package globalrolesv2 + +import ( + "fmt" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/tests/v2/actions/rbac" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + rbacapi "github.com/rancher/shepherd/extensions/kubeapi/rbac" + "github.com/rancher/shepherd/extensions/kubeapi/secrets" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/users" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + rbacv1 "k8s.io/api/rbac/v1" + k8sError "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type NamespacedRulesTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (ns *NamespacedRulesTestSuite) TearDownSuite() { + ns.session.Cleanup() +} + +func (ns *NamespacedRulesTestSuite) SetupSuite() { + ns.session = session.NewSession() + + client, err := rancher.NewClient("", ns.session) + require.NoError(ns.T(), err) + + ns.client = client +} + +func (ns *NamespacedRulesTestSuite) validateNSRulesRBACResources(user *management.User, namespacedRules map[string][]rbacv1.PolicyRule) { + log.Info("Verify that the global role binding is created for the user.") + grbOwner, err := getGlobalRoleBindingForUserWrangler(ns.client, user.ID) + require.NoError(ns.T(), err) + require.NotEmpty(ns.T(), grbOwner, "Global Role Binding not found for the user") + + expectedRbCount := len(namespacedRules) + log.Info("Verify that the role bindings are created in the local cluster for specified policy rule.") + rbCount := 0 + + for namespace := range namespacedRules { + nameSelector := fmt.Sprintf("metadata.name=%s-%s", grbOwner, namespace) + rbs, err := rbacapi.ListRoleBindings(ns.client, localcluster, namespace, metav1.ListOptions{FieldSelector: nameSelector}) + if namespace == "*" { + require.Empty(ns.T(), rbs.Items, "Unexpected number of RoleBindings: Expected %d, Actual %d", 0, len(rbs.Items)) + return + } + require.NoError(ns.T(), err) + rbCount += 1 + } + + require.Equal(ns.T(), expectedRbCount, rbCount, "Unexpected number of RoleBindings: Expected %d, Actual %d", expectedRbCount, rbCount) +} + +func (ns *NamespacedRulesTestSuite) TestCreateUserWithNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Validate creating a global role with namespacedRules and assign it to a user.") + + project, err := ns.client.Management.Project.Create(projects.NewProjectConfig(localcluster)) + require.NoError(ns.T(), err) + + namespaceName := namegen.AppendRandomString("testns-") + namespace, err := namespaces.CreateNamespace(ns.client, namespaceName, "{}", map[string]string{}, map[string]string{}, project) + require.NoError(ns.T(), err) + log.Info("Create a global role with namespacedRules.") + namespacedRules := map[string][]rbacv1.PolicyRule{ + namespace.Name: { + readSecretsPolicy, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user can list secrets in the namespace from the namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + listSecretsAsUser, err := secrets.ListSecrets(userClient, localcluster, namespace.Name, metav1.ListOptions{}) + require.NoError(ns.T(), err) + listSecretsAsAdmin, err := secrets.ListSecrets(ns.client, localcluster, namespace.Name, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), listSecretsAsAdmin.Items, listSecretsAsUser.Items) + require.Equal(ns.T(), len(listSecretsAsAdmin.Items), len(listSecretsAsUser.Items)) + + log.Info("Verify user cannot create secrets in the namespace from the namespaced rules") + _, err = secrets.CreateSecretForCluster(userClient, &secret, localcluster, namespace.Name) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) + + log.Info("Verify user cannot create secrets in other namespaces as well") + _, err = secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestCreateUserWithStarAsKeyInNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with * as key in namespacedRules.") + namespacedRules := map[string][]rbacv1.PolicyRule{ + "*": { + readSecretsPolicy, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user cannot list secrets in any namespace from the namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + _, err = secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) + + log.Info("Verify user cannot create secrets in other namespaces as well") + _, err = secrets.CreateSecretForCluster(userClient, &secret, localcluster, "default") + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestCreateUserWithStarForResourcesAndGroups() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with * as resources and api groups in namespacedRules in a custom namespace.") + + customNS, err := createProjectAndAddANamespace(ns.client, "ns-readall") + require.NoError(ns.T(), err) + + namespacedRules := map[string][]rbacv1.PolicyRule{ + customNS: { + readAllResourcesPolicy, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user can list secrets in the defined namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + log.Info("Create secrets as an admin in the customNS and verify user can list the secret.") + createAdminSecret, err := secrets.CreateSecretForCluster(ns.client, &secret, localcluster, customNS) + require.NoError(ns.T(), err) + listSecretsCustomNS, err := secrets.ListSecrets(userClient, localcluster, customNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), 1, len(listSecretsCustomNS.Items)) + require.Equal(ns.T(), createAdminSecret.Name, listSecretsCustomNS.Items[0].Name) + + log.Info("Verify user cannot list secrets in any other namespace than the defined from the namespaced rules") + _, err = secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) + + log.Info("Verify user cannot create secrets in other namespaces as well") + _, err = secrets.CreateSecretForCluster(userClient, &secret, localcluster, "default") + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestCreateUserWithMultipleNSInNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with multiple namespaces in namespacedRules.") + + customNS, err := createProjectAndAddANamespace(ns.client, "ns-readcrtbs") + require.NoError(ns.T(), err) + + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + customNS: { + readCRTBsPolicy}, + } + + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user can list secrets in the provided namespace from the namespaced rules for secrets. ") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + listSecretsAsUser, err := secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.NoError(ns.T(), err) + listSecretsAsAdmin, err := secrets.ListSecrets(ns.client, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), listSecretsAsAdmin.Items, listSecretsAsUser.Items) + require.Equal(ns.T(), len(listSecretsAsAdmin.Items), len(listSecretsAsUser.Items)) + + log.Info("Verify user cannot list secrets in the custom namespace from the namespaced rules for secrets. ") + _, err = secrets.ListSecrets(userClient, localcluster, customNS, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) + + log.Info("Verify user can list CRTBS in the custom namespace from the namespaced rules for CRTBs. ") + crtbListAsUser, err := userClient.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(customNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + crtbListAsAdmin, err := ns.client.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(customNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), len(crtbListAsAdmin.Items), len(crtbListAsUser.Items)) + + log.Info("Verify user cannot list CRTBS in the globalDataNamespace from the namespaced rules for CRTBs. ") + _, err = userClient.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestUpdateGlobalRoleWithNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Validate updating global role, creates new role bindings.") + + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, nil) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + } + updatedGlobalRole := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdGlobalRole.Name, + }, + NamespacedRules: namespacedRules, + } + + log.Info("Updating global role with namespaced rules.") + _, err = rbacapi.UpdateGlobalRole(ns.client, &updatedGlobalRole) + require.NoError(ns.T(), err) + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user can list secrets in the namespace from the namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + listSecretsAsUser, err := secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.NoError(ns.T(), err) + listSecretsAsAdmin, err := secrets.ListSecrets(ns.client, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), listSecretsAsAdmin.Items, listSecretsAsUser.Items) + require.Equal(ns.T(), len(listSecretsAsAdmin.Items), len(listSecretsAsUser.Items)) + + log.Info("Updating global role by adding multiple namespaced rules.") + customNS, err := createProjectAndAddANamespace(ns.client, "ns-readcrtbs") + require.NoError(ns.T(), err) + + namespacedRules[customNS] = []rbacv1.PolicyRule{readCRTBsPolicy} + updatedGlobalRoleWithMultiNamespacedRules := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdGlobalRole.Name, + }, + NamespacedRules: namespacedRules, + } + + _, err = rbacapi.UpdateGlobalRole(ns.client, &updatedGlobalRoleWithMultiNamespacedRules) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user cannot list secrets in the custom namespace from the namespaced rules for secrets. ") + _, err = secrets.ListSecrets(userClient, localcluster, customNS, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) + + log.Info("Verify user can list CRTBS in the custom namespace from the namespaced rules for CRTBs. ") + _, err = userClient.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(customNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + + log.Info("Verify user cannot list CRTBS in the globalDataNamespace from the namespaced rules for CRTBs. ") + _, err = userClient.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestDeleteNamespacedRulesFromGlobalRole() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Validate delting namespaced rules from global roles, deletes the role bindings for a user.") + + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + grbOwner, err := getGlobalRoleBindingForUserWrangler(ns.client, createdUser.ID) + require.NoError(ns.T(), err) + nameSelector := fmt.Sprintf("metadata.name=%s-%s", grbOwner, namespace) + + deleteNamespacedRules := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdGlobalRole.Name, + }, + NamespacedRules: map[string][]rbacv1.PolicyRule{}, + } + + log.Info("Delete the namespace in the namespaced rules.") + _, err = rbacapi.UpdateGlobalRole(ns.client, &deleteNamespacedRules) + require.NoError(ns.T(), err) + + rbs, err := rbacapi.ListRoleBindings(ns.client, localcluster, namespace, metav1.ListOptions{FieldSelector: nameSelector}) + require.NoError(ns.T(), err) + require.Empty(ns.T(), rbs.Items) +} + +func (ns *NamespacedRulesTestSuite) TestDeleteANamespaceFromNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Validate deleting a namespace from namespaced rules.") + + readPodsNS, err := createProjectAndAddANamespace(ns.client, "custom-sa-ns") + require.NoError(ns.T(), err) + readCrtbsNS, err := createProjectAndAddANamespace(ns.client, "custom-crtbs-ns") + require.NoError(ns.T(), err) + namespacedRules := map[string][]rbacv1.PolicyRule{ + readPodsNS: { + readPods, + }, + readCrtbsNS: { + readCRTBsPolicy, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Update the global role and remove a namespace.") + namespacedRules = map[string][]rbacv1.PolicyRule{ + readPodsNS: { + readPods, + }, + } + + deleteANamespace := v3.GlobalRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdGlobalRole.Name, + }, + NamespacedRules: namespacedRules, + } + + _, err = rbacapi.UpdateGlobalRole(ns.client, &deleteANamespace) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user can list pods in the namespace from the namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + listPodsAsUser, err := userClient.WranglerContext.Core.Pod().List(readPodsNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + listPodsAsAdmin, err := ns.client.WranglerContext.Core.Pod().List(readPodsNS, metav1.ListOptions{}) + require.NoError(ns.T(), err) + require.Equal(ns.T(), len(listPodsAsAdmin.Items), len(listPodsAsUser.Items)) + require.Equal(ns.T(), listPodsAsAdmin.Items, listPodsAsUser.Items) + + log.Info("Verify user cannot list crtbs in the deleted namespace from the namespaced rules") + _, err = userClient.WranglerContext.Mgmt.ClusterRoleTemplateBinding().List(readCrtbsNS, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestDeleteUserDeletesRolebindingsForNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Validate deleting user deletes the rolebindings created for namespaced rules.") + + readPodsNS, err := createProjectAndAddANamespace(ns.client, "custom-sa-ns") + require.NoError(ns.T(), err) + + namespacedRules := map[string][]rbacv1.PolicyRule{ + readPodsNS: { + readPods, + }, + } + createdGlobalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user with global role standard user and custom global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), createdGlobalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + grbOwner, err := getGlobalRoleBindingForUserWrangler(ns.client, createdUser.ID) + require.NoError(ns.T(), err) + nameSelector := fmt.Sprintf("metadata.name=%s-%s", grbOwner, namespace) + + + log.Info("Deleting the user attached to the namespaced rules.") + err = ns.client.WranglerContext.Mgmt.User().Delete(createdUser.ID, &metav1.DeleteOptions{}) + require.NoError(ns.T(), err) + + rbs, err := rbacapi.ListRoleBindings(ns.client, localcluster, namespace, metav1.ListOptions{FieldSelector: nameSelector}) + require.NoError(ns.T(), err) + require.Empty(ns.T(), rbs.Items) +} + +func (ns *NamespacedRulesTestSuite) TestWebhookRejectsEmptyVerbsInNamespacedRules() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with namespacedRules having empty verbs.") + + readSecretsPolicy.Verbs = []string{} + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + } + _, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.Error(ns.T(), err) + errMessage := "admission webhook \"rancher.cattle.io.globalroles.management.cattle.io\" denied the request: globalrole.namespacedRules." + globalDataNamespace + "[0].verbs: Required value: verbs must contain at least one value" + + require.Equal(ns.T(), errMessage, err.Error()) +} + +func (ns *NamespacedRulesTestSuite) TestWebhookIncorrectVerbsNotRejected() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with namespacedRules having incorrect verbs.") + + readSecretsPolicy.Verbs = []string{"incorrect"} + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + } + globalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user and assign the global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), globalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user cannot list secrets in the defined namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + _, err = secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func (ns *NamespacedRulesTestSuite) TestWebhookIncorrectResourcesNotRejected() { + + subSession := ns.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a global role with namespacedRules having empty verbs.") + + readSecretsPolicy.Resources = []string{"incorrect"} + namespacedRules := map[string][]rbacv1.PolicyRule{ + globalDataNamespace: { + readSecretsPolicy, + }, + } + globalRole, err := createGlobalRoleWithNamespacedRules(ns.client, namespacedRules) + require.NoError(ns.T(), err) + + log.Info("Create a user and assign the global role.") + createdUser, err := users.CreateUserWithRole(ns.client, users.UserConfig(), rbac.StandardUser.String(), globalRole.Name) + require.NoError(ns.T(), err) + + ns.validateNSRulesRBACResources(createdUser, namespacedRules) + + log.Info("Verify user cannot list secrets in the defined namespaced rules") + userClient, err := ns.client.AsUser(createdUser) + require.NoError(ns.T(), err) + + _, err = secrets.ListSecrets(userClient, localcluster, globalDataNamespace, metav1.ListOptions{}) + require.Error(ns.T(), err) + require.True(ns.T(), k8sError.IsForbidden(err)) +} + +func TestNamespacedRulesTestSuite(t *testing.T) { + suite.Run(t, new(NamespacedRulesTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/README.md new file mode 100644 index 0000000..3c958a8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/README.md @@ -0,0 +1,16 @@ +# PSA + +## Getting Started +Your GO suite should be set to `-run ^TestRBACPSATestSuite$`. +In your config file, set the following: + +```json +"rancher": { + "host": "rancher_server_address", + "adminToken": "rancher_admin_token", + "clusterName": "cluster_to_run_tests_on", + "insecure": true/optional, + "cleanup": false/optional, +} +``` + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa.go new file mode 100644 index 0000000..66a36b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa.go @@ -0,0 +1,186 @@ +package psa + +import ( + "errors" + "strings" + "time" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/extensions/workloads" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + appv1 "k8s.io/api/apps/v1" + coreV1 "k8s.io/api/core/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + pssRestrictedPolicy = "restricted" + pssBaselinePolicy = "baseline" + pssPrivilegedPolicy = "privileged" + psaWarn = "pod-security.kubernetes.io/warn" + psaAudit = "pod-security.kubernetes.io/audit" + psaEnforce = "pod-security.kubernetes.io/enforce" + psaRole = "updatepsa" + isCattleLabeled = true +) + +func getPSALabels(response *v1.SteveAPIObject, actualLabels map[string]string) map[string]string { + expectedLabels := map[string]string{} + + for label := range response.Labels { + if _, found := actualLabels[label]; found { + expectedLabels[label] = actualLabels[label] + } + } + return expectedLabels +} + +func createDeploymentAndWait(steveclient *v1.Client, containerName string, image string, namespaceName string) (*v1.SteveAPIObject, error) { + deploymentName := namegen.AppendRandomString("rbac-") + containerTemplate := workloads.NewContainer(containerName, image, coreV1.PullAlways, []coreV1.VolumeMount{}, []coreV1.EnvFromSource{}, nil, nil, nil) + + podTemplate := workloads.NewPodTemplate([]coreV1.Container{containerTemplate}, []coreV1.Volume{}, []coreV1.LocalObjectReference{}, nil) + deployment := workloads.NewDeploymentTemplate(deploymentName, namespaceName, podTemplate, isCattleLabeled, nil) + + deploymentResp, err := steveclient.SteveType(workloads.DeploymentSteveType).Create(deployment) + if err != nil { + return nil, err + } + err = kwait.Poll(5*time.Second, 5*time.Minute, func() (done bool, err error) { + deploymentResp, err := steveclient.SteveType(workloads.DeploymentSteveType).ByID(deployment.Namespace + "/" + deployment.Name) + if err != nil { + return false, err + } + deployment := &appv1.Deployment{} + err = v1.ConvertToK8sType(deploymentResp.JSONResp, deployment) + if err != nil { + return false, err + } + status := deployment.Status.Conditions + for _, statusCondition := range status { + if strings.Contains(statusCondition.Message, "forbidden") { + err = errors.New(statusCondition.Message) + return false, err + } + } + if *deployment.Spec.Replicas == deployment.Status.AvailableReplicas { + return true, nil + } + return false, nil + }) + return deploymentResp, err +} + +func deletePSALabels(labels map[string]string) { + for label := range labels { + if strings.Contains(label, psaWarn) || strings.Contains(label, psaAudit) || strings.Contains(label, psaEnforce) { + delete(labels, label) + } + } +} + +func editPsactCluster(client *rancher.Client, clustername string, namespace string, psact string) (clusterType string, err error) { + clusterID, err := clusters.GetClusterIDByName(client, clustername) + if err != nil { + return "", err + } + //Check if the downstream cluster is RKE2/K3S or RKE1 + if strings.Contains(clusterID, "c-m-") { + clusterType = "RKE2K3S" + clusterObj, existingSteveAPIObj, err := clusters.GetProvisioningClusterByName(client, clustername, namespace) + if err != nil { + return "", err + } + + clusterObj.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName = psact + _, err = clusters.UpdateK3SRKE2Cluster(client, existingSteveAPIObj, clusterObj) + if err != nil { + return clusterType, err + } + updatedClusterObj, _, err := clusters.GetProvisioningClusterByName(client, clustername, namespace) + if err != nil { + return "", err + } + if updatedClusterObj.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName != psact { + errorMsg := "psact value was not changed, Expected: " + psact + ", Actual: " + updatedClusterObj.Spec.DefaultPodSecurityAdmissionConfigurationTemplateName + return clusterType, errors.New(errorMsg) + } + } else { + clusterType = "RKE" + if psact == "" { + psact = " " + } + existingCluster, err := client.Management.Cluster.ByID(clusterID) + if err != nil { + return "", err + } + + updatedCluster := &management.Cluster{ + Name: existingCluster.Name, + DefaultPodSecurityAdmissionConfigurationTemplateName: psact, + } + _, err = client.Management.Cluster.Update(existingCluster, updatedCluster) + if err != nil { + return clusterType, err + } + + err = clusters.WaitForActiveRKE1Cluster(client, clusterID) + if err != nil { + return "", err + } + + modifiedCluster, err := client.Management.Cluster.ByID(clusterID) + if err != nil { + return "", err + } + if psact == " " { + psact = "" + } + if modifiedCluster.DefaultPodSecurityAdmissionConfigurationTemplateName != psact { + errorMsg := "psact value was not changed, Expected: " + psact + ", Actual: " + modifiedCluster.DefaultPodSecurityAdmissionConfigurationTemplateName + return clusterType, errors.New(errorMsg) + } + } + return clusterType, nil +} + +func getAndConvertNamespace(namespace *v1.SteveAPIObject, steveAdminClient *v1.Client) (*coreV1.Namespace, error) { + getNSSteveObject, err := steveAdminClient.SteveType(namespaces.NamespaceSteveType).ByID(namespace.ID) + if err != nil { + return nil, err + } + namespaceObj := &coreV1.Namespace{} + err = v1.ConvertToK8sType(getNSSteveObject.JSONResp, namespaceObj) + if err != nil { + return nil, err + } + return namespaceObj, nil +} + +func createRole(client *rancher.Client, context string, roleName string, rules []management.PolicyRule) (role *management.RoleTemplate, err error) { + role, err = client.Management.RoleTemplate.Create( + &management.RoleTemplate{ + Context: context, + Name: roleName, + Rules: rules, + }) + return + +} + +func createProject(client *rancher.Client, clusterID string) (*management.Project, error) { + projectName := namegen.AppendRandomString("testproject-") + projectConfig := &management.Project{ + ClusterID: clusterID, + Name: projectName, + } + createProject, err := client.Management.Project.Create(projectConfig) + if err != nil { + return nil, err + } + return createProject, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa_test.go new file mode 100644 index 0000000..1df1f92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/psa/psa_test.go @@ -0,0 +1,424 @@ +//go:build (validation || infra.any || cluster.any || stress) && !sanity && !extended + +package psa + +import ( + "regexp" + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/namespaces" + psadeploy "github.com/rancher/shepherd/extensions/psact" + rbac "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + containerImage = "nginx" + containerName = "psa-nginx" +) + +type PSATestSuite struct { + suite.Suite + client *rancher.Client + nonAdminUser *management.User + nonAdminUserClient *rancher.Client + session *session.Session + cluster *management.Cluster + adminProject *management.Project + stdUserProject *management.Project + steveAdminClient *v1.Client + steveNonAdminClient *v1.Client + adminNamespace *v1.SteveAPIObject + stdUserNamespace *v1.SteveAPIObject + psaRole *management.RoleTemplate + clusterName string + clusterID string +} + +func (rb *PSATestSuite) TearDownSuite() { + // reset the PSACT + _, err := editPsactCluster(rb.client, rb.clusterName, rbac.DefaultNamespace, "") + require.NoError(rb.T(), err) + rb.session.Cleanup() +} + +func (rb *PSATestSuite) SetupSuite() { + testSession := session.NewSession() + rb.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(rb.T(), err) + + rb.client = client + rb.clusterName = client.RancherConfig.ClusterName + require.NotEmptyf(rb.T(), rb.clusterName, "Cluster name to install should be set") + rb.clusterID, err = clusters.GetClusterIDByName(rb.client, rb.clusterName) + require.NoError(rb.T(), err, "Error getting cluster ID") + rb.cluster, err = rb.client.Management.Cluster.ByID(rb.clusterID) + require.NoError(rb.T(), err) + + context := "cluster" + roleName := namegen.AppendRandomString("psarole-") + rules := []management.PolicyRule{ + { + APIGroups: []string{"management.cattle.io"}, + Resources: []string{"projects"}, + Verbs: []string{psaRole}, + }, + } + psaRollUpdate, err := createRole(rb.client, context, roleName, rules) + require.NoError(rb.T(), err) + rb.psaRole = psaRollUpdate +} + +func (rb *PSATestSuite) ValidatePSA(role string, customRole bool) { + labels := map[string]string{ + psaWarn: pssPrivilegedPolicy, + psaEnforce: pssPrivilegedPolicy, + psaAudit: pssPrivilegedPolicy, + } + + rb.T().Logf("Validate updating the PSA labels as %v", role) + + updateNS, err := getAndConvertNamespace(rb.adminNamespace, rb.steveAdminClient) + require.NoError(rb.T(), err) + updateNS.Labels = labels + + response, err := rb.steveNonAdminClient.SteveType(namespaces.NamespaceSteveType).Update(rb.adminNamespace, updateNS) + + switch role { + case rbac.RestrictedAdmin.String(), rbac.ClusterOwner.String(): + require.NoError(rb.T(), err) + expectedLabels := getPSALabels(response, labels) + assert.Equal(rb.T(), labels, expectedLabels) + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + require.Error(rb.T(), err) + errMessage := strings.Split(err.Error(), ":")[0] + assert.Equal(rb.T(), "Resource type [namespace] is not updatable", errMessage) + case rbac.ProjectOwner.String(), rbac.ProjectMember.String(), rbac.CreateNS.String(): + require.Error(rb.T(), err) + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + } + + rb.T().Logf("Validate deletion of the PSA labels as %v", role) + + deletePSALabels(labels) + + deleteLabelsNS, err := getAndConvertNamespace(rb.adminNamespace, rb.steveAdminClient) + require.NoError(rb.T(), err) + deleteLabelsNS.Labels = labels + + _, err = rb.steveNonAdminClient.SteveType(namespaces.NamespaceSteveType).Update(rb.adminNamespace, deleteLabelsNS) + switch role { + case rbac.RestrictedAdmin.String(), rbac.ClusterOwner.String(): + require.NoError(rb.T(), err) + expectedLabels := getPSALabels(response, labels) + assert.Equal(rb.T(), 0, len(expectedLabels)) + if !customRole { + _, err = createDeploymentAndWait(rb.steveNonAdminClient, containerName, containerImage, rb.adminNamespace.Name) + require.NoError(rb.T(), err) + } + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + require.Error(rb.T(), err) + errMessage := strings.Split(err.Error(), ":")[0] + assert.Equal(rb.T(), "Resource type [namespace] is not updatable", errMessage) + case rbac.ProjectOwner.String(), rbac.ProjectMember.String(), rbac.CreateNS.String(): + require.Error(rb.T(), err) + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + } + + rb.T().Logf("Validate creation of new namespace with PSA labels as %v", role) + + labels = map[string]string{ + psaWarn: pssBaselinePolicy, + psaEnforce: pssBaselinePolicy, + psaAudit: pssBaselinePolicy, + } + namespaceName := namegen.AppendRandomString("testns-") + namespaceCreate, err := namespaces.CreateNamespace(rb.nonAdminUserClient, namespaceName, "{}", labels, map[string]string{}, rb.adminProject) + + switch role { + case rbac.RestrictedAdmin.String(), rbac.ClusterOwner.String(): + require.NoError(rb.T(), err) + expectedLabels := getPSALabels(response, labels) + assert.Equal(rb.T(), labels, expectedLabels) + if !customRole { + _, err = createDeploymentAndWait(rb.steveNonAdminClient, containerName, containerImage, namespaceCreate.Name) + require.NoError(rb.T(), err) + } + case rbac.ProjectOwner.String(), rbac.ProjectMember.String(), rbac.CreateNS.String(): + require.Error(rb.T(), err) + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + require.Error(rb.T(), err) + errMessage := strings.Split(err.Error(), ":")[0] + assert.Equal(rb.T(), "Resource type [namespace] is not creatable", errMessage) + } +} + +func (rb *PSATestSuite) ValidateAdditionalPSA(role string) { + createProjectAsNonAdmin, err := createProject(rb.nonAdminUserClient, rb.cluster.ID) + require.NoError(rb.T(), err) + rb.stdUserProject = createProjectAsNonAdmin + + relogin, err := rb.nonAdminUserClient.ReLogin() + require.NoError(rb.T(), err) + rb.nonAdminUserClient = relogin + + steveStdUserclient, err := rb.nonAdminUserClient.Steve.ProxyDownstream(rb.cluster.ID) + require.NoError(rb.T(), err) + rb.steveNonAdminClient = steveStdUserclient + + namespaceName := namegen.AppendRandomString("testns-") + createNamespace, err := namespaces.CreateNamespace(rb.nonAdminUserClient, namespaceName, "{}", + map[string]string{}, map[string]string{}, rb.stdUserProject) + require.NoError(rb.T(), err) + rb.stdUserNamespace = createNamespace + + rb.T().Logf("Validate editing new namespace in a cluster member created project with PSA labels as %v", role) + labels := map[string]string{ + psaWarn: pssRestrictedPolicy, + psaEnforce: pssRestrictedPolicy, + psaAudit: pssRestrictedPolicy, + } + updateNS, err := getAndConvertNamespace(rb.stdUserNamespace, rb.steveAdminClient) + require.NoError(rb.T(), err) + updateNS.Labels = labels + + relogin, err = rb.nonAdminUserClient.ReLogin() + require.NoError(rb.T(), err) + rb.nonAdminUserClient = relogin + + steveStdUserclient, err = rb.nonAdminUserClient.Steve.ProxyDownstream(rb.cluster.ID) + require.NoError(rb.T(), err) + rb.steveNonAdminClient = steveStdUserclient + + response, err := rb.steveNonAdminClient.SteveType(namespaces.NamespaceSteveType).Update(rb.stdUserNamespace, updateNS) + + switch role { + case rbac.ClusterOwner.String(), psaRole: + require.NoError(rb.T(), err) + expectedLabels := getPSALabels(response, labels) + assert.Equal(rb.T(), labels, expectedLabels) + _, err = createDeploymentAndWait(rb.steveNonAdminClient, containerName, containerImage, rb.stdUserNamespace.Name) + require.Error(rb.T(), err) + case rbac.ClusterMember.String(): + require.Error(rb.T(), err) + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + updateNS, err := getAndConvertNamespace(rb.stdUserNamespace, rb.steveAdminClient) + require.NoError(rb.T(), err) + updateNS.Labels = labels + _, err = rb.steveAdminClient.SteveType(namespaces.NamespaceSteveType).Update(rb.stdUserNamespace, updateNS) + require.NoError(rb.T(), err) + } + + rb.T().Logf("Validate deletion of PSA labels in namespace in a cluster member created project as %v", role) + + deletePSALabels(labels) + deleteLabelsNS, err := getAndConvertNamespace(rb.stdUserNamespace, rb.steveAdminClient) + require.NoError(rb.T(), err) + deleteLabelsNS.Labels = labels + + _, err = rb.steveNonAdminClient.SteveType(namespaces.NamespaceSteveType).Update(rb.stdUserNamespace, deleteLabelsNS) + + switch role { + case rbac.ClusterOwner.String(), psaRole: + require.NoError(rb.T(), err) + expectedLabels := getPSALabels(response, labels) + assert.Equal(rb.T(), labels, expectedLabels) + _, err = createDeploymentAndWait(rb.steveNonAdminClient, containerName, containerImage, rb.stdUserNamespace.Name) + require.NoError(rb.T(), err) + case rbac.ClusterMember.String(): + require.Error(rb.T(), err) + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + } +} + +func (rb *PSATestSuite) ValidateEditPsactCluster(role string, psact string) { + clusterType, err := editPsactCluster(rb.nonAdminUserClient, rb.clusterName, rbac.DefaultNamespace, psact) + switch role { + case rbac.ClusterOwner.String(), rbac.RestrictedAdmin.String(): + require.NoError(rb.T(), err) + err = psadeploy.CreateNginxDeployment(rb.nonAdminUserClient, rb.clusterID, psact) + require.NoError(rb.T(), err) + case rbac.ClusterMember.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(), rbac.ReadOnly.String(): + require.Error(rb.T(), err) + if clusterType == "RKE2K3S" { + assert.Equal(rb.T(), "Resource type [provisioning.cattle.io.cluster] is not updatable", err.Error()) + } else { + errStatus := strings.Split(err.Error(), ".")[1] + rgx := regexp.MustCompile(`\[(.*?)\]`) + errorMsg := rgx.FindStringSubmatch(errStatus) + assert.Equal(rb.T(), "403 Forbidden", errorMsg[1]) + } + } +} + +func (rb *PSATestSuite) TestPSA() { + nonAdminUserRoles := [...]string{rbac.ClusterMember.String(), rbac.RestrictedAdmin.String(), rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ReadOnly.String(), rbac.ProjectMember.String(), rbac.CreateNS.String()} + for _, role := range nonAdminUserRoles { + var customRole bool + if role == rbac.CreateNS.String() { + customRole = true + } + createProjectAsAdmin, err := createProject(rb.client, rb.cluster.ID) + rb.adminProject = createProjectAsAdmin + require.NoError(rb.T(), err) + + steveAdminClient, err := rb.client.Steve.ProxyDownstream(rb.cluster.ID) + require.NoError(rb.T(), err) + rb.steveAdminClient = steveAdminClient + namespaceName := namegen.AppendRandomString("testns-") + labels := map[string]string{ + psaWarn: pssRestrictedPolicy, + psaEnforce: pssRestrictedPolicy, + psaAudit: pssRestrictedPolicy, + } + adminNamespace, err := namespaces.CreateNamespace(rb.client, namespaceName+"-admin", "{}", labels, map[string]string{}, rb.adminProject) + require.NoError(rb.T(), err) + expectedPSALabels := getPSALabels(adminNamespace, labels) + assert.Equal(rb.T(), labels, expectedPSALabels) + rb.adminNamespace = adminNamespace + _, err = createDeploymentAndWait(rb.steveAdminClient, containerName, containerImage, rb.adminNamespace.Name) + require.Error(rb.T(), err) + + rb.Run("Create a user with global role "+role, func() { + var userRole string + if role == rbac.RestrictedAdmin.String() { + userRole = rbac.RestrictedAdmin.String() + } else { + userRole = rbac.StandardUser.String() + } + newUser, err := users.CreateUserWithRole(rb.client, users.UserConfig(), userRole) + + require.NoError(rb.T(), err) + rb.nonAdminUser = newUser + rb.T().Logf("Created user: %v", rb.nonAdminUser.Username) + rb.nonAdminUserClient, err = rb.client.AsUser(newUser) + require.NoError(rb.T(), err) + + subSession := rb.session.NewSession() + defer subSession.Cleanup() + + log.Info("Adding user as " + role + " to the downstream cluster.") + if role != rbac.RestrictedAdmin.String() { + if strings.Contains(role, "project") || role == rbac.ReadOnly.String() || role == rbac.CreateNS.String() { + err := users.AddProjectMember(rb.client, rb.adminProject, rb.nonAdminUser, role, nil) + require.NoError(rb.T(), err) + } else { + err := users.AddClusterRoleToUser(rb.client, rb.cluster, rb.nonAdminUser, role, nil) + require.NoError(rb.T(), err) + } + rb.nonAdminUserClient, err = rb.nonAdminUserClient.ReLogin() + require.NoError(rb.T(), err) + } + + steveClient, err := rb.nonAdminUserClient.Steve.ProxyDownstream(rb.cluster.ID) + require.NoError(rb.T(), err) + rb.steveNonAdminClient = steveClient + }) + + rb.Run("Testcase - Validate if members with roles "+role+"can add/edit/delete labesl from admin created namespace", func() { + + rb.ValidatePSA(role, customRole) + }) + + if strings.Contains(role, "cluster") { + rb.Run("Additional testcase - Validate if members with roles "+role+"can add/edit/delete labels from admin created namespace", func() { + rb.ValidateAdditionalPSA(role) + }) + } + + if strings.Contains(role, "project") || role == rbac.CreateNS.String() { + rb.Run("Additional testcase - Validate if "+role+" with an additional role update-psa can add/edit/delete labels from admin created namespace", func() { + err := users.AddClusterRoleToUser(rb.client, rb.cluster, rb.nonAdminUser, rb.psaRole.ID, nil) + require.NoError(rb.T(), err) + rb.ValidatePSA(psaRole, customRole) + }) + } + } +} + +func (rb *PSATestSuite) TestPsactRBAC() { + tests := []struct { + name string + role string + member string + }{ + {"Cluster Owner", rbac.ClusterOwner.String(), rbac.StandardUser.String()}, + {"Cluster Member", rbac.ClusterMember.String(), rbac.StandardUser.String()}, + {"Project Owner", rbac.ProjectOwner.String(), rbac.StandardUser.String()}, + {"Project Member", rbac.ProjectMember.String(), rbac.StandardUser.String()}, + {"Project Read Only", rbac.ReadOnly.String(), rbac.StandardUser.String()}, + {"Restricted Admin", rbac.RestrictedAdmin.String(), rbac.RestrictedAdmin.String()}, + } + for _, tt := range tests { + rb.Run("Set up User with Cluster Role "+tt.name, func() { + newUser, err := users.CreateUserWithRole(rb.client, users.UserConfig(), tt.member) + require.NoError(rb.T(), err) + rb.nonAdminUser = newUser + rb.T().Logf("Created user: %v", rb.nonAdminUser.Username) + rb.nonAdminUserClient, err = rb.client.AsUser(newUser) + require.NoError(rb.T(), err) + + subSession := rb.session.NewSession() + defer subSession.Cleanup() + + createProjectAsAdmin, err := createProject(rb.client, rb.cluster.ID) + rb.adminProject = createProjectAsAdmin + require.NoError(rb.T(), err) + }) + rb.Run("Adding user as "+tt.name+" to the downstream cluster.", func() { + if tt.member == rbac.StandardUser.String() { + if strings.Contains(tt.role, "project") || tt.role == rbac.ReadOnly.String() { + err := users.AddProjectMember(rb.client, rb.adminProject, rb.nonAdminUser, tt.role, nil) + require.NoError(rb.T(), err) + } else { + err := users.AddClusterRoleToUser(rb.client, rb.cluster, rb.nonAdminUser, tt.role, nil) + require.NoError(rb.T(), err) + } + } + relogin, err := rb.nonAdminUserClient.ReLogin() + require.NoError(rb.T(), err) + rb.nonAdminUserClient = relogin + }) + + rb.T().Logf("Starting validations for %v", tt.role) + rb.Run("Test case - Edit cluster as a "+tt.name+" and disable psact.", func() { + rb.ValidateEditPsactCluster(tt.role, "") + }) + rb.Run("Test case - Edit cluster as a "+tt.name+" and set psact to rancher-restricted.", func() { + rb.ValidateEditPsactCluster(tt.role, "rancher-restricted") + }) + } +} + +func TestRBACPSATestSuite(t *testing.T) { + suite.Run(t, new(PSATestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/rbac_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/rbac_test.go new file mode 100644 index 0000000..418124a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/rbac_test.go @@ -0,0 +1,185 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress && !extended + +package rbac + +import ( + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type RBTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (rb *RBTestSuite) TearDownSuite() { + rb.session.Cleanup() +} + +func (rb *RBTestSuite) SetupSuite() { + testSession := session.NewSession() + rb.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(rb.T(), err) + + rb.client = client + + log.Info("Getting cluster name from the config file and append cluster details in rb") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(rb.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(rb.client, clusterName) + require.NoError(rb.T(), err, "Error getting cluster ID") + rb.cluster, err = rb.client.Management.Cluster.ByID(clusterID) + require.NoError(rb.T(), err) + +} + +func (rb *RBTestSuite) sequentialTestRBAC(role rbac.Role, member string, user *management.User) { + standardClient, err := rb.client.AsUser(user) + require.NoError(rb.T(), err) + + adminProject, err := rb.client.Management.Project.Create(projects.NewProjectConfig(rb.cluster.ID)) + require.NoError(rb.T(), err) + + if member == rbac.StandardUser.String() { + if strings.Contains(role.String(), "project") { + err := users.AddProjectMember(rb.client, adminProject, user, role.String(), nil) + require.NoError(rb.T(), err) + } else { + err := users.AddClusterRoleToUser(rb.client, rb.cluster, user, role.String(), nil) + require.NoError(rb.T(), err) + } + } + + standardClient, err = standardClient.ReLogin() + require.NoError(rb.T(), err) + + additionalUser, err := users.CreateUserWithRole(rb.client, users.UserConfig(), rbac.StandardUser.String()) + require.NoError(rb.T(), err) + + rb.Run("Validating Global Role Binding is created for "+role.String(), func() { + rbac.VerifyGlobalRoleBindingsForUser(rb.T(), user, rb.client) + }) + rb.Run("Validating if "+role.String()+" can list any downstream clusters", func() { + rbac.VerifyUserCanListCluster(rb.T(), rb.client, standardClient, rb.cluster.ID, role) + }) + rb.Run("Validating if members with role "+role.String()+" are able to list all projects", func() { + rbac.VerifyUserCanListProject(rb.T(), rb.client, standardClient, rb.cluster.ID, adminProject.Name, role) + }) + rb.Run("Validating if members with role "+role.String()+" is able to create a project in the cluster", func() { + rbac.VerifyUserCanCreateProjects(rb.T(), rb.client, standardClient, rb.cluster.ID, role) + }) + rb.Run("Validate namespaces checks for members with role "+role.String(), func() { + rbac.VerifyUserCanCreateNamespace(rb.T(), rb.client, standardClient, adminProject, rb.cluster.ID, role) + }) + rb.Run("Validating if "+role.String()+" can lists all namespaces in a cluster.", func() { + rbac.VerifyUserCanListNamespace(rb.T(), rb.client, standardClient, adminProject, rb.cluster.ID, role) + }) + rb.Run("Validating if "+role.String()+" can delete a namespace from a project they own.", func() { + rbac.VerifyUserCanDeleteNamespace(rb.T(), rb.client, standardClient, adminProject, rb.cluster.ID, role) + }) + rb.Run("Validating if member with role "+role.String()+" can add members to the cluster", func() { + rbac.VerifyUserCanAddClusterRoles(rb.T(), rb.client, standardClient, rb.cluster, role) + }) + rb.Run("Validating if member with role "+role.String()+" can add members to the project", func() { + if strings.Contains(role.String(), "project") { + rbac.VerifyUserCanAddProjectRoles(rb.T(), standardClient, adminProject, additionalUser, rbac.ProjectOwner.String(), rb.cluster.ID, role) + } + }) + rb.Run("Validating if member with role "+role.String()+" can delete a project they are not owner of ", func() { + rbac.VerifyUserCanDeleteProject(rb.T(), standardClient, adminProject, role) + }) + rb.Run("Validating if member with role "+role.String()+" is removed from the cluster and returns nil clusters", func() { + if strings.Contains(role.String(), "cluster") { + rbac.VerifyUserCanRemoveClusterRoles(rb.T(), rb.client, user) + } + }) +} + +func (rb *RBTestSuite) TestRBAC() { + tests := []struct { + name string + role rbac.Role + member string + }{ + {"Cluster Owner", rbac.ClusterOwner, rbac.StandardUser.String()}, + {"Cluster Member", rbac.ClusterMember, rbac.StandardUser.String()}, + {"Project Owner", rbac.ProjectOwner, rbac.StandardUser.String()}, + {"Project Member", rbac.ProjectMember, rbac.StandardUser.String()}, + {"Restricted Admin", rbac.RestrictedAdmin, rbac.RestrictedAdmin.String()}, + } + + for _, tt := range tests { + var newUser *management.User + rb.Run("Validate conditions for user with role "+tt.name, func() { + user, err := users.CreateUserWithRole(rb.client, users.UserConfig(), tt.member) + require.NoError(rb.T(), err) + newUser = user + rb.T().Logf("Created user: %v", newUser.Username) + }) + + if newUser != nil { + rb.sequentialTestRBAC(tt.role, tt.member, newUser) + subSession := rb.session.NewSession() + defer subSession.Cleanup() + } + } +} + +func (rb *RBTestSuite) TestRBACDynamicInput() { + roles := map[string]string{ + "cluster-owner": rbac.ClusterOwner.String(), + "cluster-member": rbac.ClusterMember.String(), + "project-owner": rbac.ProjectOwner.String(), + "project-member": rbac.ProjectMember.String(), + "restricted-admin": rbac.RestrictedAdmin.String(), + } + var member string + userConfig := new(rbac.Config) + config.LoadConfig(rbac.ConfigurationFileKey, userConfig) + username := userConfig.Username + userByName, err := users.GetUserIDByName(rb.client, username) + require.NoError(rb.T(), err) + user, err := rb.client.Management.User.ByID(userByName) + require.NoError(rb.T(), err) + + user.Password = userConfig.Password + + role := userConfig.Role + if userConfig.Role == "" { + rb.T().Skip() + } else { + val, ok := roles[role.String()] + if !ok { + rb.FailNow("Incorrect usage of roles. Please go through the readme for correct role configurations") + } + role = rbac.Role(val) + } + + if role == rbac.RestrictedAdmin { + member = rbac.RestrictedAdmin.String() + } else { + member = rbac.StandardUser.String() + } + rb.sequentialTestRBAC(role, member, user) + +} + +func TestRBACTestSuite(t *testing.T) { + suite.Run(t, new(RBTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/README.md new file mode 100644 index 0000000..7162518 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/README.md @@ -0,0 +1,20 @@ +# RBAC Secrets + +## Pre-requisites + +- Ensure you have an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, create one first before running this test. + +## Test Setup + +Your GO suite should be set to `-run ^TestRbacSecretTestSuite$`. + +In your config file, set the following: + +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True #optional + cleanup: True #optional + clusterName: "cluster_name" +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/rbac_secrets_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/rbac_secrets_test.go new file mode 100644 index 0000000..66e2310 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/secrets/rbac_secrets_test.go @@ -0,0 +1,367 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package secrets + +import ( + "testing" + + projectsapi "github.com/rancher/rancher/tests/v2/actions/projects" + rbac "github.com/rancher/rancher/tests/v2/actions/rbac" + secret "github.com/rancher/rancher/tests/v2/actions/secrets" + deployment "github.com/rancher/rancher/tests/v2/actions/workloads/deployment" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wrangler" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type RbacSecretTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster + downstreamContext *wrangler.Context +} + +func (rbs *RbacSecretTestSuite) TearDownSuite() { + rbs.session.Cleanup() +} + +func (rbs *RbacSecretTestSuite) SetupSuite() { + rbs.session = session.NewSession() + + client, err := rancher.NewClient("", rbs.session) + assert.NoError(rbs.T(), err) + rbs.client = client + + log.Info("Getting cluster name from the config file and append cluster details in rb") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(rbs.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(rbs.client, clusterName) + require.NoError(rbs.T(), err, "Error getting cluster ID") + rbs.cluster, err = rbs.client.Management.Cluster.ByID(clusterID) + assert.NoError(rbs.T(), err) +} + +func (rbs *RbacSecretTestSuite) TestCreateSecretAsEnvVar() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + role rbac.Role + member string + }{ + {rbac.ClusterOwner, rbac.StandardUser.String()}, + {rbac.ClusterMember, rbac.StandardUser.String()}, + {rbac.ProjectOwner, rbac.StandardUser.String()}, + {rbac.ProjectMember, rbac.StandardUser.String()}, + {rbac.ReadOnly, rbac.StandardUser.String()}, + } + + for _, tt := range tests { + rbs.Run("Validate secret creation for user with role "+tt.role.String(), func() { + log.Info("Create a project and a namespace in the project.") + adminProject, namespace, err := projectsapi.CreateProjectAndNamespace(rbs.client, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("Create a standard user and add the user to a cluster/project role %s", tt.role) + newUser, standardUserClient, err := rbac.AddUserWithRoleToCluster(rbs.client, tt.member, tt.role.String(), rbs.cluster, adminProject) + assert.NoError(rbs.T(), err) + rbs.T().Logf("Created user: %v", newUser.Username) + + log.Infof("As a %v, create a secret in the project %v", tt.role.String(), adminProject.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(standardUserClient, rbs.cluster.ID, namespace.Name, secretData) + switch tt.role.String() { + case rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + assert.NoError(rbs.T(), err, "failed to create secret") + log.Infof("As a %v, create a deployment using the secret as an environment variable.", tt.role.String()) + _, err = deployment.CreateDeployment(standardUserClient, rbs.cluster.ID, namespace.Name, 1, createdSecret.Name, "", true, false) + assert.NoError(rbs.T(), err, "failed to create deployment with secret") + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + assert.Error(rbs.T(), err) + assert.True(rbs.T(), errors.IsForbidden(err)) + } + }) + } +} + +func (rbs *RbacSecretTestSuite) TestCreateSecretAsVolume() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + role rbac.Role + member string + }{ + {rbac.ClusterOwner, rbac.StandardUser.String()}, + {rbac.ClusterMember, rbac.StandardUser.String()}, + {rbac.ProjectOwner, rbac.StandardUser.String()}, + {rbac.ProjectMember, rbac.StandardUser.String()}, + {rbac.ReadOnly, rbac.StandardUser.String()}, + } + + for _, tt := range tests { + rbs.Run("Validate secret creation for user with role "+tt.role.String(), func() { + log.Info("Create a project and a namespace in the project.") + adminProject, namespace, err := projectsapi.CreateProjectAndNamespace(rbs.client, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("Create a standard user and add the user to a cluster/project role %s", tt.role) + newUser, standardUserClient, err := rbac.AddUserWithRoleToCluster(rbs.client, tt.member, tt.role.String(), rbs.cluster, adminProject) + assert.NoError(rbs.T(), err) + rbs.T().Logf("Created user: %v", newUser.Username) + + log.Infof("As a %v, create a secret in the project %v", tt.role.String(), adminProject.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(standardUserClient, rbs.cluster.ID, namespace.Name, secretData) + switch tt.role.String() { + case rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + assert.NoError(rbs.T(), err, "failed to create secret") + log.Infof("As a %v, create a deployment using the secret as an environment variable.", tt.role.String()) + _, err = deployment.CreateDeployment(standardUserClient, rbs.cluster.ID, namespace.Name, 1, createdSecret.Name, "", false, true) + assert.NoError(rbs.T(), err, "failed to create deployment with secret") + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + assert.Error(rbs.T(), err) + assert.True(rbs.T(), errors.IsForbidden(err)) + } + }) + } +} + +func (rbs *RbacSecretTestSuite) TestListSecret() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + role rbac.Role + member string + }{ + {rbac.ClusterOwner, rbac.StandardUser.String()}, + {rbac.ClusterMember, rbac.StandardUser.String()}, + {rbac.ProjectOwner, rbac.StandardUser.String()}, + {rbac.ProjectMember, rbac.StandardUser.String()}, + {rbac.ReadOnly, rbac.StandardUser.String()}, + } + + for _, tt := range tests { + rbs.Run("Validate listing secret for user with role "+tt.role.String(), func() { + log.Info("Create a project and a namespace in the project.") + adminProject, namespace, err := projectsapi.CreateProjectAndNamespace(rbs.client, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("Create a standard user and add the user to a cluster/project role %s", tt.role) + newUser, standardUserClient, err := rbac.AddUserWithRoleToCluster(rbs.client, tt.member, tt.role.String(), rbs.cluster, adminProject) + assert.NoError(rbs.T(), err) + rbs.T().Logf("Created user: %v", newUser.Username) + + log.Infof("As a %v, create a secret in the project %v", rbac.Admin, adminProject.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(rbs.client, rbs.cluster.ID, namespace.Name, secretData) + assert.NoError(rbs.T(), err, "failed to create secret") + + log.Infof("As a %v, list the secret.", tt.role.String()) + standardUserContext, err := standardUserClient.WranglerContext.DownStreamClusterWranglerContext(rbs.cluster.ID) + assert.NoError(rbs.T(), err) + secretList, err := standardUserContext.Core.Secret().List(namespace.Name, metav1.ListOptions{}) + switch tt.role.String() { + case rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + assert.NoError(rbs.T(), err, "failed to list secret") + assert.Equal(rbs.T(), len(secretList.Items), 1) + assert.Equal(rbs.T(), secretList.Items[0].Name, createdSecret.Name) + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + assert.Error(rbs.T(), err) + assert.True(rbs.T(), errors.IsForbidden(err)) + } + }) + } +} + +func (rbs *RbacSecretTestSuite) TestUpdateSecret() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + role rbac.Role + member string + }{ + {rbac.ClusterOwner, rbac.StandardUser.String()}, + {rbac.ClusterMember, rbac.StandardUser.String()}, + {rbac.ProjectOwner, rbac.StandardUser.String()}, + {rbac.ProjectMember, rbac.StandardUser.String()}, + {rbac.ReadOnly, rbac.StandardUser.String()}, + } + + for _, tt := range tests { + rbs.Run("Validate updating secret as user with role "+tt.role.String(), func() { + log.Info("Create a project and a namespace in the project.") + adminProject, namespace, err := projectsapi.CreateProjectAndNamespace(rbs.client, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("Create a standard user and add the user to a cluster/project role %s", tt.role) + newUser, standardUserClient, err := rbac.AddUserWithRoleToCluster(rbs.client, tt.member, tt.role.String(), rbs.cluster, adminProject) + assert.NoError(rbs.T(), err) + rbs.T().Logf("Created user: %v", newUser.Username) + + log.Infof("As a %v, create a secret in the project %v", rbac.Admin, adminProject.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(rbs.client, rbs.cluster.ID, namespace.Name, secretData) + assert.NoError(rbs.T(), err, "failed to create secret") + + log.Infof("As a %v, update the secret.", tt.role.String()) + standardUserContext, err := standardUserClient.WranglerContext.DownStreamClusterWranglerContext(rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + newData := map[string][]byte{ + "foo": []byte("bar"), + } + updatedSecretObj := secret.UpdateSecretData(createdSecret, newData) + updatedSecret, err := standardUserContext.Core.Secret().Update(updatedSecretObj) + switch tt.role.String() { + case rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + assert.NoError(rbs.T(), err, "failed to update secret") + assert.NotNil(rbs.T(), updatedSecret) + assert.Contains(rbs.T(), updatedSecret.Data, "foo") + assert.Equal(rbs.T(), updatedSecret.Data["foo"], []byte("bar")) + + log.Infof("As a %v, create a deployment using the updated secret.", tt.role.String()) + _, err = deployment.CreateDeployment(standardUserClient, rbs.cluster.ID, namespace.Name, 1, updatedSecret.Name, "", true, false) + assert.NoError(rbs.T(), err, "failed to create deployment with secret") + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + assert.Error(rbs.T(), err) + assert.True(rbs.T(), errors.IsForbidden(err)) + } + }) + } +} + +func (rbs *RbacSecretTestSuite) TestDeleteSecret() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + role rbac.Role + member string + }{ + {rbac.ClusterOwner, rbac.StandardUser.String()}, + {rbac.ClusterMember, rbac.StandardUser.String()}, + {rbac.ProjectOwner, rbac.StandardUser.String()}, + {rbac.ProjectMember, rbac.StandardUser.String()}, + {rbac.ReadOnly, rbac.StandardUser.String()}, + } + + for _, tt := range tests { + rbs.Run("Validate deleting secret as user with role "+tt.role.String(), func() { + log.Info("Create a project and a namespace in the project.") + adminProject, namespace, err := projectsapi.CreateProjectAndNamespace(rbs.client, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("Create a standard user and add the user to a cluster/project role %s", tt.role) + newUser, standardUserClient, err := rbac.AddUserWithRoleToCluster(rbs.client, tt.member, tt.role.String(), rbs.cluster, adminProject) + assert.NoError(rbs.T(), err) + rbs.T().Logf("Created user: %v", newUser.Username) + + log.Infof("As a %v, create a secret in the project %v", rbac.Admin, adminProject.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(rbs.client, rbs.cluster.ID, namespace.Name, secretData) + assert.NoError(rbs.T(), err, "failed to create secret") + + log.Infof("As a %v, delete the secret.", tt.role.String()) + standardUserContext, err := standardUserClient.WranglerContext.DownStreamClusterWranglerContext(rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + err = standardUserContext.Core.Secret().Delete(namespace.Name, createdSecret.Name, &metav1.DeleteOptions{}) + switch tt.role.String() { + case rbac.ClusterOwner.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + assert.NoError(rbs.T(), err, "failed to delete secret") + secretList, err := rbs.client.WranglerContext.Core.Secret().List(namespace.Name, metav1.ListOptions{}) + assert.NoError(rbs.T(), err) + assert.Equal(rbs.T(), len(secretList.Items), 0) + case rbac.ClusterMember.String(), rbac.ReadOnly.String(): + assert.Error(rbs.T(), err) + assert.True(rbs.T(), errors.IsForbidden(err)) + } + }) + } +} + +func (rbs *RbacSecretTestSuite) TestCrudSecretAsClusterMember() { + subSession := rbs.session.NewSession() + defer subSession.Cleanup() + + role := rbac.ClusterMember.String() + log.Infof("Create a standard user.") + user, standardUserClient, err := rbac.SetupUser(rbs.client, rbac.StandardUser.String()) + assert.NoError(rbs.T(), err) + + log.Infof("Add the user to the downstream cluster with role %s", role) + err = users.AddClusterRoleToUser(rbs.client, rbs.cluster, user, role, nil) + assert.NoError(rbs.T(), err) + + log.Infof("As a %v, create a project and a namespace in the project.", role) + project, namespace, err := projectsapi.CreateProjectAndNamespace(standardUserClient, rbs.cluster.ID) + assert.NoError(rbs.T(), err) + + log.Infof("As a %v, create a secret in the project %v", role, project.Name) + secretData := map[string][]byte{ + "hello": []byte("world"), + } + createdSecret, err := secret.CreateSecret(standardUserClient, rbs.cluster.ID, namespace.Name, secretData) + require.NoError(rbs.T(), err, "failed to create secret") + + log.Infof("As a %v, create a deployment using the secret as an environment variable.", role) + _, err = deployment.CreateDeployment(standardUserClient, rbs.cluster.ID, namespace.Name, 1, createdSecret.Name, "", true, false) + require.NoError(rbs.T(), err, "failed to create deployment with secret") + + log.Infof("As a %v, list the secret.", role) + standardUserContext, err := standardUserClient.WranglerContext.DownStreamClusterWranglerContext(rbs.cluster.ID) + assert.NoError(rbs.T(), err) + secretList, err := standardUserContext.Core.Secret().List(namespace.Name, metav1.ListOptions{}) + require.NoError(rbs.T(), err, "failed to list secret") + require.Equal(rbs.T(), len(secretList.Items), 1) + require.Equal(rbs.T(), secretList.Items[0].Name, createdSecret.Name) + + log.Infof("As a %v, update the secret.", role) + newData := map[string][]byte{ + "foo": []byte("bar"), + } + updatedSecretObj := secret.UpdateSecretData(createdSecret, newData) + updatedSecret, err := standardUserContext.Core.Secret().Update(updatedSecretObj) + require.NoError(rbs.T(), err, "failed to list secret") + assert.NotNil(rbs.T(), updatedSecret) + assert.Contains(rbs.T(), updatedSecret.Data, "foo") + assert.Equal(rbs.T(), updatedSecret.Data["foo"], []byte("bar")) + + log.Infof("As a %v, create a deployment using the secret as an environment variable.", role) + _, err = deployment.CreateDeployment(standardUserClient, rbs.cluster.ID, namespace.Name, 1, updatedSecret.Name, "", true, false) + require.NoError(rbs.T(), err, "failed to create deployment with secret") + + log.Infof("As a %v, delete the secret.", role) + err = standardUserContext.Core.Secret().Delete(namespace.Name, updatedSecret.Name, &metav1.DeleteOptions{}) + require.NoError(rbs.T(), err, "failed to delete secret") + secretList, err = standardUserContext.Core.Secret().List(namespace.Name, metav1.ListOptions{}) + assert.NoError(rbs.T(), err) + assert.Equal(rbs.T(), len(secretList.Items), 0) +} + +func TestRbacSecretTestSuite(t *testing.T) { + suite.Run(t, new(RbacSecretTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/README.md new file mode 100644 index 0000000..43db233 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/README.md @@ -0,0 +1,16 @@ +# etcdbackup + +## Getting Started +Your GO suite should be set to `-run ^TestSnapshotRBACTestSuite$`. +In your config file, set the following: + +```json +"rancher": { + "host": "rancher_server_address", + "adminToken": "rancher_admin_token", + "clusterName": "cluster_to_run_tests_on", + "insecure": true/optional, + "cleanup": false/optional, +} +``` + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/snapshot_rbac_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/snapshot_rbac_test.go new file mode 100644 index 0000000..5e68c13 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/rbac/snapshotrbac/snapshot_rbac_test.go @@ -0,0 +1,109 @@ +//go:build (validation || infra.any || cluster.any || stress) && !sanity && !extended + +package snapshotrbac + +import ( + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + "github.com/rancher/shepherd/extensions/projects" + rbac "github.com/rancher/shepherd/extensions/rbac" + "github.com/rancher/shepherd/extensions/users" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type SnapshotRBACTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (etcd *SnapshotRBACTestSuite) TearDownSuite() { + etcd.session.Cleanup() +} + +func (etcd *SnapshotRBACTestSuite) SetupSuite() { + etcd.session = session.NewSession() + + client, err := rancher.NewClient("", etcd.session) + require.NoError(etcd.T(), err) + + etcd.client = client + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(etcd.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(etcd.client, clusterName) + require.NoError(etcd.T(), err, "Error getting cluster ID") + etcd.cluster, err = etcd.client.Management.Cluster.ByID(clusterID) + require.NoError(etcd.T(), err) +} + +func (etcd *SnapshotRBACTestSuite) testRKE2K3SSnapshotRBAC(role string, standardUserClient *rancher.Client) { + log.Info("Test case - Take Etcd snapshot of a cluster as a " + role) + err := etcdsnapshot.CreateRKE2K3SSnapshot(standardUserClient, etcd.cluster.Name) + switch role { + case rbac.ClusterOwner.String(), rbac.RestrictedAdmin.String(): + require.NoError(etcd.T(), err) + + case rbac.ClusterMember.String(), rbac.ProjectOwner.String(), rbac.ProjectMember.String(): + require.Error(etcd.T(), err) + assert.Equal(etcd.T(), "Resource type [provisioning.cattle.io.cluster] is not updatable", err.Error()) + } +} + +func (etcd *SnapshotRBACTestSuite) TestRKE2K3SSnapshotRBAC() { + subSession := etcd.session.NewSession() + defer subSession.Cleanup() + + tests := []struct { + name string + role string + member string + }{ + {"Cluster Owner", rbac.ClusterOwner.String(), rbac.StandardUser.String()}, + {"Cluster Member", rbac.ClusterMember.String(), rbac.StandardUser.String()}, + {"Project Owner", rbac.ProjectOwner.String(), rbac.StandardUser.String()}, + {"Project Member", rbac.ProjectMember.String(), rbac.StandardUser.String()}, + {"Restricted Admin", rbac.RestrictedAdmin.String(), rbac.RestrictedAdmin.String()}, + } + for _, tt := range tests { + if !(strings.Contains(etcd.cluster.ID, "c-m-")) { + etcd.T().Skip("Skipping tests since cluster is not of type - k3s or RKE2") + } + etcd.Run("Set up User with Role "+tt.name, func() { + clusterUser, clusterClient, err := rbac.SetupUser(etcd.client, tt.member) + require.NoError(etcd.T(), err) + + adminProject, err := etcd.client.Management.Project.Create(projects.NewProjectConfig(etcd.cluster.ID)) + require.NoError(etcd.T(), err) + + if tt.member == rbac.StandardUser.String() { + if strings.Contains(tt.role, "project") { + err := users.AddProjectMember(etcd.client, adminProject, clusterUser, tt.role, nil) + require.NoError(etcd.T(), err) + } else { + err := users.AddClusterRoleToUser(etcd.client, etcd.cluster, clusterUser, tt.role, nil) + require.NoError(etcd.T(), err) + } + } + + relogin, err := clusterClient.ReLogin() + require.NoError(etcd.T(), err) + clusterClient = relogin + + etcd.testRKE2K3SSnapshotRBAC(tt.role, clusterClient) + }) + } +} + +func TestSnapshotRBACTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotRBACTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/README.md new file mode 100644 index 0000000..f1dd198 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/README.md @@ -0,0 +1,20 @@ +# Schemas + +## Pre-requisites + +- Ensure you have an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, create one first before running this test. + +## Test Setup + +Your GO suite should be set to `-run ^TestSchemaChangesTestSuite$`. + +In your config file, set the following: + +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: True #optional + cleanup: True #optional + clusterName: "downstream_cluster_name" +``` diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas.go new file mode 100644 index 0000000..5714d2e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas.go @@ -0,0 +1,289 @@ +package schemas + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "regexp" + "strings" + "time" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/kubectl" +) + +const ( + schema = "schema" + schemaDefinition = "schemaDefinition" + apiGroupEndpoint = "apigroup" + localCluster = "local" + projectSchemaID = "management.cattle.io.project" + namespaceSchemaID = "namespace" + autoscalingSchemaID = "autoscaling.horizontalpodautoscaler" + customSchemaID = "stable.example.com.crontab" + customCrdName = "crontabs.stable.example.com" + crdCreateFilePath = "./resources/crd_create.yaml" + twoSecondTimeout = 2 * time.Second +) + +var exceptionMap = map[string]bool{ + "applyOutput": true, + "applyInput": true, + "apiRoot": true, + "chartActionOutput": true, + "chartInstall": true, + "chartInstallAction": true, + "chartUpgrade": true, + "chartUpgradeAction": true, + "chartUninstallAction": true, + "count": true, + "generateKubeconfigOutput": true, + "schema": true, + "schemaDefinition": true, + "subscribe": true, + "userpreference": true, +} + +func getSchemaByID(client *rancher.Client, clusterID, existingSchemaID string) (map[string]interface{}, error) { + return getJSONResponse(client, clusterID, schema, existingSchemaID) +} + +func getSchemaDefinitionByID(client *rancher.Client, clusterID, existingSchemaID string) (map[string]interface{}, error) { + return getJSONResponse(client, clusterID, schemaDefinition, existingSchemaID) +} + +func getAPIGroupInfoByAPIGroupName(client *rancher.Client, clusterID, apiGroupName string) (map[string]interface{}, error) { + return getJSONResponse(client, clusterID, apiGroupEndpoint, apiGroupName) +} + +func accessSchemaDefinitionForEachSchema(client *rancher.Client, schemasCollection *v1.SteveCollection, clusterID string) ([]string, error) { + var failedSchemaDefinitions []string + var err error + var schemaID string + + for _, schema := range schemasCollection.Data { + schemaID = schema.JSONResp["id"].(string) + + if _, exists := exceptionMap[schemaID]; !exists { + _, err = getSchemaByID(client, clusterID, schemaID) + if err != nil { + return nil, err + } + _, err = getSchemaDefinitionByID(client, clusterID, schemaID) + if err != nil { + failedSchemaDefinitions = append(failedSchemaDefinitions, schemaID) + } + } + } + return failedSchemaDefinitions, nil +} + +func checkPreferredVersion(client *rancher.Client, schemasCollection *v1.SteveCollection, clusterID string) ([][]string, error) { + var failedSchemaPreferredVersionCheck [][]string + + for _, schema := range schemasCollection.Data { + schemaID := schema.JSONResp["id"].(string) + + if _, exists := exceptionMap[schemaID]; !exists { + schemaInfo, err := getSchemaByID(client, clusterID, schemaID) + if err != nil { + return nil, err + } + schemaVersion := schemaInfo["attributes"].(map[string]interface{})["version"].(string) + + apiGroupName := schemaInfo["attributes"].(map[string]interface{})["group"].(string) + if apiGroupName == "" { + continue + } + apiGroupInfo, err := getAPIGroupInfoByAPIGroupName(client, clusterID, apiGroupName) + if err != nil { + return nil, err + } + preferredVersion := apiGroupInfo["preferredVersion"].(map[string]interface{})["version"].(string) + + if schemaVersion != preferredVersion { + failedSchemaPreferredVersionCheck = append(failedSchemaPreferredVersionCheck, []string{ + "Schema ID: " + schemaID + ",", + "Schema Version: " + schemaVersion + ";", + "API Group Name: " + apiGroupName + ",", + "API Group Version: " + preferredVersion, + }) + } + } + } + return failedSchemaPreferredVersionCheck, nil +} + +func getJSONResponse(client *rancher.Client, clusterID, endpointType, existingID string) (map[string]interface{}, error) { + rancherURL := client.RancherConfig.Host + token := client.RancherConfig.AdminToken + + baseURL := fmt.Sprintf("https://%s", rancherURL) + if clusterID != localCluster { + baseURL = fmt.Sprintf("%s/k8s/clusters/%s", baseURL, clusterID) + } + + var httpURL string + if endpointType == apiGroupEndpoint { + httpURL = fmt.Sprintf("%s/apis/%s", baseURL, existingID) + } else { + httpURL = fmt.Sprintf("%s/v1/%s/%s", baseURL, endpointType, existingID) + } + + req, err := http.NewRequest("GET", httpURL, nil) + if err != nil { + return nil, err + } + + req.Header.Add("Authorization", "Bearer "+token) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + byteObject, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var jsonObject map[string]interface{} + if err := json.Unmarshal(byteObject, &jsonObject); err != nil { + return nil, err + } + + return jsonObject, nil +} + +func checkSchemaFields(schemasCollection *v1.SteveCollection) error { + for _, schema := range schemasCollection.Data { + schemaID := schema.JSONResp["id"].(string) + if !exceptionMap[schemaID] { + if schema.JSONResp["resourceFields"] != nil { + return errors.New("resourceFields should be null for schema " + schemaID) + } + + if match, _ := regexp.MatchString(`\.[vV][0-9]+`, schemaID); match { + return errors.New("child schema should not be listed") + } + } + } + return nil +} + +func checkChildSchemasNotListed(client *rancher.Client, clusterID string, childSchemas map[string]bool, schemaResponse map[string]interface{}) error { + for childSchemaID := range childSchemas { + if _, found := schemaResponse[childSchemaID]; found { + return errors.New("child schema should not be listed") + } + + _, err := getSchemaByID(client, clusterID, childSchemaID) + if err == nil { + return errors.New("expected an error when fetching child schema") + } + errStatus := strings.Split(err.Error(), ": ")[1] + if errStatus != "404" { + return errors.New("unexpected error status: " + errStatus) + } + } + return nil +} + +func checkExpectedDefinitions(expectedDefinitions map[string]bool, schemaResponse map[string]interface{}) error { + for definitionID := range expectedDefinitions { + definitionData, exists := schemaResponse["definitions"].(map[string]interface{})[definitionID] + if !exists { + return fmt.Errorf("Expected definition %s not found in schemaResponse", definitionID) + } + + resourceFields, resourceFieldsExist := definitionData.(map[string]interface{})["resourceFields"] + if !resourceFieldsExist || resourceFields == nil { + return fmt.Errorf("ResourceFields are nil for definition %s", definitionID) + } + + _, resourceMethodsExist := definitionData.(map[string]interface{})["resourceMethods"] + if resourceMethodsExist { + return fmt.Errorf("ResourceMethods field exists for definition %s", definitionID) + } + + _, collectionMethodsExist := definitionData.(map[string]interface{})["collectionMethods"] + if collectionMethodsExist { + return fmt.Errorf("CollectionMethods field exists for definition %s", definitionID) + } + + for fieldName, fieldData := range resourceFields.(map[string]interface{}) { + fieldType := fieldData.(map[string]interface{})["type"].(string) + if fieldType == "integer" || fieldType == "number" { + return fmt.Errorf("field %s should not be of type %s in definition %s", fieldName, fieldType, definitionID) + } + } + } + return nil +} + +func getChildSchemasForProject() map[string]bool { + return map[string]bool{ + "io.cattle.management.v3.Project": true, + "io.cattle.management.v3.Project.spec": true, + "io.cattle.management.v3.Project.spec.resourceQuota": true, + "io.cattle.management.v3.Project.spec.resourceQuota.usedLimit": true, + "io.cattle.management.v3.Project.spec.resourceQuota.limit": true, + "io.cattle.management.v3.Project.spec.namespaceDefaultResourceQuota": true, + "io.cattle.management.v3.Project.spec.namespaceDefaultResourceQuota.limit": true, + "io.cattle.management.v3.Project.spec.containerDefaultResourceLimit": true, + "io.cattle.management.v3.Project.status": true, + "io.cattle.management.v3.Project.status.conditions": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": true, + } +} + +func getChildSchemasForNamespace() map[string]bool { + return map[string]bool{ + "io.k8s.api.core.v1.NamespaceCondition": true, + "io.k8s.api.core.v1.NamespaceSpec": true, + "io.k8s.api.core.v1.NamespaceStatus": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": true, + } +} + +func getChildSchemasForCronTab() map[string]bool { + return map[string]bool{ + "com.example.stable.v2.CronTab": true, + "com.example.stable.v2.CronTab.spec": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": true, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": true, + } +} + +func createCRD(client *rancher.Client, crdCreateFilePath string) error { + crdYAML, err := os.ReadFile(crdCreateFilePath) + if err != nil { + return err + } + + yamlInput := &management.ImportClusterYamlInput{ + YAML: string(crdYAML), + } + apply := []string{"kubectl", "apply", "-f", "/root/.kube/my-pod.yaml"} + _, err = kubectl.Command(client, yamlInput, localCluster, apply, "") + if err != nil { + return err + } + + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas_test.go new file mode 100644 index 0000000..fae90e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/schemas/schemas_test.go @@ -0,0 +1,340 @@ +//go:build (validation || infra.any || cluster.any || extended) && !sanity && !stress + +package schemas + +import ( + "context" + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/kubeapi/customresourcedefinitions" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +type SchemaChangesTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (sc *SchemaChangesTestSuite) TearDownSuite() { + sc.session.Cleanup() +} + +func (sc *SchemaChangesTestSuite) SetupSuite() { + sc.session = session.NewSession() + + client, err := rancher.NewClient("", sc.session) + require.NoError(sc.T(), err) + + sc.client = client + + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(sc.T(), clusterName, "Cluster name to install should be set") + clusterID, err := clusters.GetClusterIDByName(sc.client, clusterName) + require.NoError(sc.T(), err, "Error getting cluster ID") + sc.cluster, err = sc.client.Management.Cluster.ByID(clusterID) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestSchemaEndpointLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access the schemas endpoint on the local cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := sc.client.Steve.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Verify that each listed schema's resourceFields are set to null and ensure the schemas endpoint exclusively lists top-level types without including child schemas for resources.") + err = checkSchemaFields(schemasCollection) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestSchemaEndpointDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + steveAdminClient, err := sc.client.Steve.ProxyDownstream(sc.cluster.ID) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint on the downstream cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := steveAdminClient.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Verify that each listed schema's resourceFields are set to null and ensure the schemas endpoint exclusively lists top-level types without including child schemas for resources.") + err = checkSchemaFields(schemasCollection) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestExistingSchemaLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access an existing schema on the local cluster and verify that it can be accessed successfully without any errors.") + schemaResponse, err := getSchemaByID(sc.client, localCluster, projectSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify that the schema's resourceFields field is set to null.") + id := schemaResponse["id"].(string) + require.Nil(sc.T(), schemaResponse["resourceFields"], "ResourceFields should be null for schema "+id) + + log.Info("Verify that the schemas endpoint for Project does not list the child schemas and trying to access any of the child schemas results in a '404 Not Found' error.") + childSchemas := getChildSchemasForProject() + err = checkChildSchemasNotListed(sc.client, localCluster, childSchemas, schemaResponse) + require.NoError(sc.T(), err) + + log.Info("Verify that the data returned from the schemas endpoint has the resourceMethods and collectionMethods fields.") + require.NotNil(sc.T(), schemaResponse["resourceMethods"], "resourceMethods should be present in this schema") + require.NotNil(sc.T(), schemaResponse["collectionMethods"], "collectionMethods should be present in this schema") +} + +func (sc *SchemaChangesTestSuite) TestExistingSchemaDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access an existing schema on the downstream cluster and verify that it can be accessed successfully without any errors.") + schemaResponse, err := getSchemaByID(sc.client, sc.cluster.ID, namespaceSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify that the schema's resourceFields field is set to null.") + id := schemaResponse["id"].(string) + require.Nil(sc.T(), schemaResponse["resourceFields"], "ResourceFields should be null for schema "+id) + + log.Info("Verify that the schemas endpoint for Namespace does not list the child schemas and trying to access any of the child schemas results in a '404 Not Found' error.") + childSchemas := getChildSchemasForNamespace() + err = checkChildSchemasNotListed(sc.client, sc.cluster.ID, childSchemas, schemaResponse) + require.NoError(sc.T(), err) + + log.Info("Verify that the data returned from the schemas endpoint has the resourceMethods and collectionMethods fields.") + require.NotNil(sc.T(), schemaResponse["resourceMethods"], "resourceMethods should be present in this schema") + require.NotNil(sc.T(), schemaResponse["collectionMethods"], "collectionMethods should be present in this schema") +} + +func (sc *SchemaChangesTestSuite) TestSchemaDefinitionsEndpointLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access schemadefinitions endpoint on the local cluster without providing the schema and verify that it fails with an error.") + _, err := sc.client.Steve.SteveType(schemaDefinition).List(nil) + require.Error(sc.T(), err) + errMessage := strings.Split(err.Error(), ":")[0] + require.Equal(sc.T(), "Resource type [schemaDefinition] has no method GET", errMessage) +} + +func (sc *SchemaChangesTestSuite) TestSchemaDefinitionsEndpointDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + steveAdminClient, err := sc.client.Steve.ProxyDownstream(sc.cluster.ID) + require.NoError(sc.T(), err) + + log.Info("Access schemadefinitions endpoint on the downstream cluster without providing the schema and verify that it fails with an error.") + _, err = steveAdminClient.SteveType(schemaDefinition).List(nil) + require.Error(sc.T(), err) + errMessage := strings.Split(err.Error(), ":")[0] + require.Equal(sc.T(), "Resource type [schemaDefinition] has no method GET", errMessage) +} + +func (sc *SchemaChangesTestSuite) TestExistingSchemaDefinitionLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access the schema definition for an existing schema on the local cluster and verify that it can be accessed successfully without any errors.") + schemaResponse, err := getSchemaDefinitionByID(sc.client, localCluster, projectSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify data returned has definitions with resourceFields for each definition type.") + expectedDefinitions := getChildSchemasForProject() + err = checkExpectedDefinitions(expectedDefinitions, schemaResponse) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestExistingSchemaDefinitionDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access the schema definition for an existing schema on the downstream cluster and verify that it can be accessed successfully without any errors.") + schemaResponse, err := getSchemaDefinitionByID(sc.client, sc.cluster.ID, namespaceSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify data returned has definitions with resourceFields for each definition type.") + expectedDefinitions := getChildSchemasForNamespace() + err = checkExpectedDefinitions(expectedDefinitions, schemaResponse) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestSchemaDefinitionsExistenceForSchemaLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access the schemas and schema definition endpoint on the local cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := sc.client.Steve.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Access the schema definition for each schema in the list using the schemadefinitions endpoint.") + failedSchemaDefinitions, err := accessSchemaDefinitionForEachSchema(sc.client, schemasCollection, localCluster) + require.NoError(sc.T(), err) + require.Emptyf(sc.T(), failedSchemaDefinitions, "Failed to access schema definitions for schemas: %s", strings.Join(failedSchemaDefinitions, ", ")) +} + +func (sc *SchemaChangesTestSuite) TestSchemaDefinitionsExistenceForSchemaDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + steveAdminClient, err := sc.client.Steve.ProxyDownstream(sc.cluster.ID) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint on the downstream cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := steveAdminClient.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Access the schema definition for each schema in the list using the schemadefinitions endpoint.") + failedSchemaDefinitions, err := accessSchemaDefinitionForEachSchema(sc.client, schemasCollection, sc.cluster.ID) + require.NoError(sc.T(), err) + require.Emptyf(sc.T(), failedSchemaDefinitions, "Failed to access schema definitions for schemas: %s", strings.Join(failedSchemaDefinitions, ", ")) +} + +func (sc *SchemaChangesTestSuite) TestPreferredVersionCheckLocalCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Access the schemas endpoint on the local cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := sc.client.Steve.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Verify that the version in each schema is the preferred version.") + failedSchemaPreferredVersionCheck, err := checkPreferredVersion(sc.client, schemasCollection, localCluster) + require.NoError(sc.T(), err) + require.Emptyf(sc.T(), failedSchemaPreferredVersionCheck, "Failed preferred version checks: %v", failedSchemaPreferredVersionCheck) +} + +func (sc *SchemaChangesTestSuite) TestPreferredVersionCheckDownstreamCluster() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + steveAdminClient, err := sc.client.Steve.ProxyDownstream(sc.cluster.ID) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint on the downstream cluster and verify that it can be accessed successfully without any errors.") + schemasCollection, err := steveAdminClient.SteveType(schema).List(nil) + require.NoError(sc.T(), err) + log.Infof("Number of schemas: %d", len(schemasCollection.Data)) + + log.Info("Verify that the version in each schema is the preferred version.") + failedSchemaPreferredVersionCheck, err := checkPreferredVersion(sc.client, schemasCollection, sc.cluster.ID) + require.NoError(sc.T(), err) + require.Emptyf(sc.T(), failedSchemaPreferredVersionCheck, "Failed preferred version checks: %v", failedSchemaPreferredVersionCheck) +} + +func (sc *SchemaChangesTestSuite) TestCRDCreateOperation() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a new Custom Resource Definition (CRD).") + err := createCRD(sc.client, crdCreateFilePath) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint for the newly created CRD and verify that it can be accessed successfully without any errors.") + err = kwait.PollUntilContextTimeout(context.Background(), twoSecondTimeout, defaults.FiveSecondTimeout, false, func(ctx context.Context) (done bool, pollErr error) { + _, pollErr = getSchemaByID(sc.client, localCluster, customSchemaID) + if pollErr != nil { + return false, pollErr + } + return true, nil + }) + schemaResponse, err := getSchemaByID(sc.client, localCluster, customSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify that the schema's resourceFields field is set to null.") + id := schemaResponse["id"].(string) + require.Nil(sc.T(), schemaResponse["resourceFields"], "ResourceFields should be null for schema "+id) + + log.Info("Verify that the schemas endpoint for the new CRD does not list the child schemas.") + childSchemas := getChildSchemasForCronTab() + err = checkChildSchemasNotListed(sc.client, localCluster, childSchemas, schemaResponse) + require.NoError(sc.T(), err) + + log.Info("Verify that the data returned from the schemas endpoint has the resourceMethods and collectionMethods fields.") + require.NotNil(sc.T(), schemaResponse["resourceMethods"], "resourceMethods should be present in this schema") + require.NotNil(sc.T(), schemaResponse["collectionMethods"], "collectionMethods should be present in this schema") + + log.Info("Access the schema definition for the new CRD and verify that it can be accessed successfully without any errors.") + err = kwait.PollUntilContextTimeout(context.Background(), twoSecondTimeout, defaults.FiveSecondTimeout, false, func(ctx context.Context) (done bool, pollErr error) { + _, pollErr = getSchemaDefinitionByID(sc.client, localCluster, customSchemaID) + if pollErr != nil { + return false, pollErr + } + return true, nil + }) + schemaResponse, err = getSchemaDefinitionByID(sc.client, localCluster, customSchemaID) + require.NoError(sc.T(), err) + + log.Info("Verify that the data returned has definitions with resourceFields for each definition type, and the resourceMethods and collectionMethods fields are present.") + expectedDefinitions := getChildSchemasForCronTab() + err = checkExpectedDefinitions(expectedDefinitions, schemaResponse) + require.NoError(sc.T(), err) +} + +func (sc *SchemaChangesTestSuite) TestCRDDeleteOperation() { + subSession := sc.session.NewSession() + defer subSession.Cleanup() + + log.Info("Create a new Custom Resource Definition (CRD).") + err := createCRD(sc.client, crdCreateFilePath) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint for the newly created CRD and verify that it can be accessed successfully without any errors.") + err = kwait.PollUntilContextTimeout(context.Background(), twoSecondTimeout, defaults.FiveSecondTimeout, false, func(ctx context.Context) (done bool, pollErr error) { + _, pollErr = getSchemaByID(sc.client, localCluster, customSchemaID) + if pollErr != nil { + return false, pollErr + } + return true, nil + }) + + log.Info("Delete the CRD.") + err = customresourcedefinitions.DeleteCustomResourceDefinition(sc.client, localCluster, "", customCrdName) + require.NoError(sc.T(), err) + + log.Info("Access the schemas endpoint for the CRD and verify that it fails with a 404 error.") + err = kwait.PollUntilContextTimeout(context.Background(), twoSecondTimeout, defaults.OneMinuteTimeout, true, func(ctx context.Context) (done bool, pollErr error) { + _, pollErr = getSchemaByID(sc.client, localCluster, customSchemaID) + if pollErr != nil { + return true, pollErr + } + return false, nil + }) + require.Error(sc.T(), err) + errStatus := strings.Split(err.Error(), ": ")[1] + require.Equal(sc.T(), "404", errStatus) + + log.Info("Access the schema definition for the CRD and verify that it fails with a 404 error.") + err = kwait.PollUntilContextTimeout(context.Background(), twoSecondTimeout, defaults.OneMinuteTimeout, true, func(ctx context.Context) (done bool, pollErr error) { + _, pollErr = getSchemaDefinitionByID(sc.client, localCluster, customSchemaID) + if pollErr != nil { + return true, pollErr + } + return false, nil + }) + require.Error(sc.T(), err) + errStatus = strings.Split(err.Error(), ": ")[1] + require.Equal(sc.T(), "404", errStatus) +} + +func TestSchemaChangesTestSuite(t *testing.T) { + suite.Run(t, new(SchemaChangesTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/README.md new file mode 100644 index 0000000..344f7cf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/README.md @@ -0,0 +1,14 @@ +Shell Configs +Getting Started +Your GO test_package should be set to shell. Your GO suite should be set to -run ^TestShellTestSuite$. + +In your config file, set the following: + +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + insecure: true/optional + cleanup: true/optional + shellImage : "rancher/shell:" + +While validating the shell P0 checks, set the shellImage version to the latest version. We validate the shell latest image that is available to that of the image we have on our rancher server. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/shell_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/shell_test.go new file mode 100644 index 0000000..32885e3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/shell/shell_test.go @@ -0,0 +1,76 @@ +//go:build (validation || infra.any || cluster.any) && !stress && !sanity && !extended + +package shell + +import ( + "strings" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + + "github.com/rancher/shepherd/pkg/session" + + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/settings" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" +) + +const ( + cattleSystemNameSpace = "cattle-system" + shellName = "shell-image" + clusterName = "local" +) + +type ShellTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session +} + +func (s *ShellTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *ShellTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *ShellTestSuite) TestShell() { + subSession := s.session.NewSession() + defer subSession.Cleanup() + + s.Run("Verify the version of shell on local cluster", func() { + shellImage, err := settings.ShellVersion(s.client, clusterName, shellName) + require.NoError(s.T(), err) + assert.Equal(s.T(), shellImage, s.client.RancherConfig.ShellImage) + }) + + s.Run("Verify the helm operations for the shell succeeded", func() { + steveClient := s.client.Steve + pods, err := steveClient.SteveType(pods.PodResourceSteveType).NamespacedSteveClient(cattleSystemNameSpace).List(nil) + require.NoError(s.T(), err) + + for _, pod := range pods.Data { + if strings.Contains(pod.Name, "helm") { + podStatus := &corev1.PodStatus{} + err = steveV1.ConvertToK8sType(pod.Status, podStatus) + require.NoError(s.T(), err) + assert.Equal(s.T(), "Succeeded", string(podStatus.Phase)) + } + } + }) +} + +func TestShellTestSuite(t *testing.T) { + suite.Run(t, new(ShellTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/README.md new file mode 100644 index 0000000..b2d6d4f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/README.md @@ -0,0 +1,46 @@ +# Snapshot + +For the snapshot tests, these tests are designed to accept an existing cluster that the user has access to. If you do not have a downstream cluster in Rancher, you should create one first before running these tests. It is recommended to have a cluster configuration of 3 etcd, 2 controlplane, 3 workers. + +Please see below for more details for your config. Please note that the config can be in either JSON or YAML (all examples are illustrated in YAML). + +## Table of Contents +1. [Getting Started](#Getting-Started) + +## Getting Started +In your config file, set the following: +```yaml +rancher: + host: "rancher_server_address" + adminToken: "rancher_admin_token" + clusterName: "cluster_to_run_tests_on" + insecure: true/optional + cleanup: false/optional +snapshotInput: + upgradeKubernetesVersion: "" # If left blank, the default version in Rancher will be used. + snapshotRestore: "all" # Options include none, kubernetesVersion, all. Option 'none' means that only the etcd will be restored. + controlPlaneConcurrencyValue: "15%" + workerConcurrencyValue: "20%" + controlPlaneUnavailableValue: "1" + workerUnavailableValue: "10%" + recurringRestores: 1 # By default, this is set to 1 if this field is not included in the config. +``` + +Additionally, S3 is a supported restore option. If you choose to use S3, then you must have it already enabled on the downstream cluster. + +These tests utilize Go build tags. Due to this, see the below example on how to run the tests: + +### Snapshot restore +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreETCDOnlyTestSuite/TestSnapshotRestoreETCDOnly"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreETCDOnlyTestSuite/TestSnapshotRestoreETCDOnlyDynamicInput"` + +### Snapshot restore with K8s upgrade +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreK8sUpgradeTestSuite/TestSnapshotRestoreK8sUpgrade"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreK8sUpgradeTestSuite/TestSnapshotRestoreK8sUpgradeDynamicInput"` + +### Sanpshot restore with upgrade strategy +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreUpgradeStrategyTestSuite/TestSnapshotRestoreUpgradeStrategy"` \ +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotRestoreUpgradeStrategyTestSuite/TestSnapshotRestoreUpgradeStrategyDynamicInput"` + +### Sanpshot additional tests +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/snapshot --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestSnapshotAdditionalTestsTestSuite$"` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot.go new file mode 100644 index 0000000..07e75f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot.go @@ -0,0 +1,445 @@ +package snapshot + +import ( + "strings" + "testing" + "time" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/generated/norman/apps/v1" + scaling "github.com/rancher/rancher/tests/v2/validation/nodescaling" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/kubernetesversions" + "github.com/rancher/shepherd/extensions/defaults" + extdefault "github.com/rancher/shepherd/extensions/defaults" + "github.com/rancher/shepherd/extensions/defaults/stevetypes" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + "github.com/rancher/shepherd/extensions/ingresses" + nodestat "github.com/rancher/shepherd/extensions/nodes" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/services" + "github.com/rancher/shepherd/extensions/workloads" + deploy "github.com/rancher/shepherd/extensions/workloads/deployment" + "github.com/rancher/shepherd/extensions/workloads/pods" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + networking "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + all = "all" + containerImage = "nginx" + containerName = "nginx" + defaultNamespace = "default" + DeploymentSteveType = "apps.deployment" + isCattleLabeled = true + initialIngress = "ingress-before-restore" + initialWorkload = "wload-before-restore" + ingressSteveType = "networking.k8s.io.ingress" + ingressPath = "/index.html" + K3S = "k3s" + kubernetesVersion = "kubernetesVersion" + namespace = "fleet-default" + port = "port" + postWorkload = "wload-after-backup" + ProvisioningSteveResouceType = "provisioning.cattle.io.cluster" + RKE1 = "rke1" + RKE2 = "rke2" + serviceAppendName = "service-" + serviceType = "service" +) + +func snapshotRestore(t *testing.T, client *rancher.Client, clusterName string, etcdRestore *etcdsnapshot.Config) { + initialIngressName := namegen.AppendRandomString(initialIngress) + initialWorkloadName := namegen.AppendRandomString(initialWorkload) + + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + + steveclient, err := client.Steve.ProxyDownstream(clusterID) + require.NoError(t, err) + + var isRKE1 = false + + clusterObject, _, _ := clusters.GetProvisioningClusterByName(client, clusterName, namespace) + if clusterObject == nil { + _, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + isRKE1 = true + } + + containerTemplate := workloads.NewContainer(containerName, containerImage, corev1.PullAlways, []corev1.VolumeMount{}, []corev1.EnvFromSource{}, nil, nil, nil) + podTemplate := workloads.NewPodTemplate([]corev1.Container{containerTemplate}, []corev1.Volume{}, []corev1.LocalObjectReference{}, nil) + deployment := workloads.NewDeploymentTemplate(initialWorkloadName, defaultNamespace, podTemplate, isCattleLabeled, nil) + + service := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceAppendName + initialWorkloadName, + Namespace: defaultNamespace, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + Ports: []corev1.ServicePort{ + { + Name: port, + Port: 80, + }, + }, + Selector: deployment.Spec.Template.Labels, + }, + } + + deploymentResp, err := deploy.CreateDeployment(steveclient, initialWorkloadName, deployment) + require.NoError(t, err) + + err = deploy.VerifyDeployment(steveclient, deploymentResp) + require.NoError(t, err) + require.Equal(t, initialWorkloadName, deploymentResp.ObjectMeta.Name) + + serviceResp, err := services.CreateService(steveclient, service) + require.NoError(t, err) + + err = services.VerifyService(steveclient, serviceResp) + require.NoError(t, err) + require.Equal(t, serviceAppendName+initialWorkloadName, serviceResp.ObjectMeta.Name) + + path := ingresses.NewIngressPathTemplate(networking.PathTypeExact, ingressPath, serviceAppendName+initialWorkloadName, 80) + ingressTemplate := ingresses.NewIngressTemplate(initialIngressName, defaultNamespace, "", []networking.HTTPIngressPath{path}) + + ingressResp, err := ingresses.CreateIngress(steveclient, initialIngressName, ingressTemplate) + require.NoError(t, err) + + err = ingresses.VerifyIngress(steveclient, ingressResp, initialIngressName) + require.NoError(t, err) + require.Equal(t, initialIngressName, ingressResp.ObjectMeta.Name) + + if isRKE1 { + cluster, snapshotName, postDeploymentResp, postServiceResp := snapshotRKE1(t, client, podTemplate, deployment, clusterName, clusterID, etcdRestore, isRKE1) + restoreRKE1(t, client, snapshotName, etcdRestore, cluster, clusterID) + + _, err = steveclient.SteveType(DeploymentSteveType).ByID(postDeploymentResp.ID) + require.Error(t, err) + + _, err = steveclient.SteveType(serviceType).ByID(postServiceResp.ID) + require.Error(t, err) + + } else { + cluster, snapshotName, postDeploymentResp, postServiceResp := snapshotV2Prov(t, client, podTemplate, deployment, clusterName, clusterID, etcdRestore, isRKE1) + restoreV2Prov(t, client, snapshotName, etcdRestore, cluster, clusterID) + + _, err = steveclient.SteveType(DeploymentSteveType).ByID(postDeploymentResp.ID) + require.Error(t, err) + + _, err = steveclient.SteveType(serviceType).ByID(postServiceResp.ID) + require.Error(t, err) + } + + logrus.Infof("Deleting created workloads...") + err = steveclient.SteveType(DeploymentSteveType).Delete(deploymentResp) + require.NoError(t, err) + + err = steveclient.SteveType(serviceType).Delete(serviceResp) + require.NoError(t, err) + + err = steveclient.SteveType(ingressSteveType).Delete(ingressResp) + require.NoError(t, err) +} + +func snapshotRKE1(t *testing.T, client *rancher.Client, podTemplate corev1.PodTemplateSpec, deployment *v1.Deployment, clusterName, clusterID string, + etcdRestore *etcdsnapshot.Config, isRKE1 bool) (*management.Cluster, string, *steveV1.SteveAPIObject, *steveV1.SteveAPIObject) { + existingSnapshots, err := etcdsnapshot.GetRKE1Snapshots(client, clusterID) + require.NoError(t, err) + + err = etcdsnapshot.CreateRKE1Snapshot(client, clusterName) + require.NoError(t, err) + + cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + if etcdRestore.ReplaceWorkerNode { + scaling.ReplaceRKE1Nodes(t, client, clusterName, false, false, true) + } + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + + postDeploymentResp, postServiceResp := createPostBackupWorkloads(t, client, clusterID, podTemplate, deployment) + + etcdNodeCount, _ := etcdsnapshot.MatchNodeToAnyEtcdRole(client, clusterID) + snapshotToRestore, err := provisioning.VerifySnapshots(client, clusterName, etcdNodeCount+len(existingSnapshots), isRKE1) + require.NoError(t, err) + + if etcdRestore.SnapshotRestore == kubernetesVersion || etcdRestore.SnapshotRestore == all { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + + clusterResp, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + if etcdRestore.UpgradeKubernetesVersion == "" { + defaultVersion, err := kubernetesversions.Default(client, clusters.RKE1ClusterType.String(), nil) + etcdRestore.UpgradeKubernetesVersion = defaultVersion[0] + require.NoError(t, err) + } + + clusterResp.RancherKubernetesEngineConfig.Version = etcdRestore.UpgradeKubernetesVersion + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneUnavailableValue != "" && etcdRestore.WorkerUnavailableValue != "" { + clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane = etcdRestore.ControlPlaneUnavailableValue + clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker = etcdRestore.WorkerUnavailableValue + } + + _, err = client.Management.Cluster.Update(clusterResp, &clusterResp) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, clusterID) + require.NoError(t, err) + + logrus.Infof("Cluster version is upgraded to: %s", clusterResp.RancherKubernetesEngineConfig.Version) + + nodestat.AllManagementNodeReady(client, clusterResp.ID, extdefault.ThirtyMinuteTimeout) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + require.Equal(t, etcdRestore.UpgradeKubernetesVersion, clusterResp.RancherKubernetesEngineConfig.Version) + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneUnavailableValue != "" && etcdRestore.WorkerUnavailableValue != "" { + logrus.Infof("Control plane unavailable value is set to: %s", clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane) + logrus.Infof("Worker unavailable value is set to: %s", clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker) + + require.Equal(t, etcdRestore.ControlPlaneUnavailableValue, clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane) + require.Equal(t, etcdRestore.WorkerUnavailableValue, clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker) + } + } + + return cluster, snapshotToRestore, postDeploymentResp, postServiceResp +} + +func restoreRKE1(t *testing.T, client *rancher.Client, snapshotName string, etcdRestore *etcdsnapshot.Config, oldCluster *management.Cluster, clusterID string) { + // Give the option to restore the same snapshot multiple times. By default, it is set to 1. + for i := 0; i < etcdRestore.RecurringRestores; i++ { + snapshotRKE1Restore := &management.RestoreFromEtcdBackupInput{ + EtcdBackupID: snapshotName, + RestoreRkeConfig: etcdRestore.SnapshotRestore, + } + + err := etcdsnapshot.RestoreRKE1Snapshot(client, oldCluster.Name, snapshotRKE1Restore) + require.NoError(t, err) + + nodestat.AllManagementNodeReady(client, oldCluster.ID, defaults.ThirtyMinuteTimeout) + + clusterResp, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + require.Equal(t, oldCluster.RancherKubernetesEngineConfig.Version, clusterResp.RancherKubernetesEngineConfig.Version) + logrus.Infof("Cluster version is restored to: %s", clusterResp.RancherKubernetesEngineConfig.Version) + + client, err = client.ReLogin() + require.NoError(t, err) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneUnavailableValue != "" && etcdRestore.WorkerUnavailableValue != "" { + logrus.Infof("Control plane unavailable value is restored to: %s", clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane) + logrus.Infof("Worker unavailable value is restored to: %s", clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker) + + require.Equal(t, oldCluster.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane, clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableControlplane) + require.Equal(t, oldCluster.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker, clusterResp.RancherKubernetesEngineConfig.UpgradeStrategy.MaxUnavailableWorker) + } + } +} + +func snapshotV2Prov(t *testing.T, client *rancher.Client, podTemplate corev1.PodTemplateSpec, deployment *v1.Deployment, clusterName, clusterID string, + etcdRestore *etcdsnapshot.Config, isRKE1 bool) (*apisV1.Cluster, string, *steveV1.SteveAPIObject, *steveV1.SteveAPIObject) { + existingSnapshots, err := etcdsnapshot.GetRKE2K3SSnapshots(client, clusterName) + require.NoError(t, err) + + err = etcdsnapshot.CreateRKE2K3SSnapshot(client, clusterName) + require.NoError(t, err) + + cluster, _, err := clusters.GetProvisioningClusterByName(client, clusterName, namespace) + require.NoError(t, err) + + if etcdRestore.ReplaceWorkerNode { + scaling.ReplaceNodes(t, client, clusterName, false, false, true) + } + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + + postDeploymentResp, postServiceResp := createPostBackupWorkloads(t, client, clusterID, podTemplate, deployment) + + etcdNodeCount, _ := etcdsnapshot.MatchNodeToAnyEtcdRole(client, clusterID) + snapshotToRestore, err := provisioning.VerifySnapshots(client, clusterName, etcdNodeCount+len(existingSnapshots), isRKE1) + require.NoError(t, err) + + if etcdRestore.SnapshotRestore == kubernetesVersion || etcdRestore.SnapshotRestore == all { + clusterObject, clusterResponse, err := clusters.GetProvisioningClusterByName(client, clusterName, namespace) + require.NoError(t, err) + + initialKubernetesVersion := clusterObject.Spec.KubernetesVersion + + if etcdRestore.UpgradeKubernetesVersion == "" { + if strings.Contains(initialKubernetesVersion, RKE2) { + defaultVersion, err := kubernetesversions.Default(client, clusters.RKE2ClusterType.String(), nil) + etcdRestore.UpgradeKubernetesVersion = defaultVersion[0] + require.NoError(t, err) + } else if strings.Contains(initialKubernetesVersion, K3S) { + defaultVersion, err := kubernetesversions.Default(client, clusters.K3SClusterType.String(), nil) + etcdRestore.UpgradeKubernetesVersion = defaultVersion[0] + require.NoError(t, err) + } + } + + clusterObject.Spec.KubernetesVersion = etcdRestore.UpgradeKubernetesVersion + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneConcurrencyValue != "" && etcdRestore.WorkerConcurrencyValue != "" { + clusterObject.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency = etcdRestore.ControlPlaneConcurrencyValue + clusterObject.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency = etcdRestore.WorkerConcurrencyValue + } + + _, err = client.Steve.SteveType(ProvisioningSteveResouceType).Update(clusterResponse, clusterObject) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, clusterID) + require.NoError(t, err) + + logrus.Infof("Cluster version is upgraded to: %s", clusterObject.Spec.KubernetesVersion) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + require.Equal(t, etcdRestore.UpgradeKubernetesVersion, clusterObject.Spec.KubernetesVersion) + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneConcurrencyValue != "" && etcdRestore.WorkerConcurrencyValue != "" { + logrus.Infof("Control plane concurrency value is set to: %s", clusterObject.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency) + logrus.Infof("Worker concurrency value is set to: %s", clusterObject.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency) + + require.Equal(t, etcdRestore.ControlPlaneConcurrencyValue, clusterObject.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency) + require.Equal(t, etcdRestore.WorkerConcurrencyValue, clusterObject.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency) + } + } + + return cluster, snapshotToRestore, postDeploymentResp, postServiceResp +} + +func restoreV2Prov(t *testing.T, client *rancher.Client, snapshotName string, etcdRestore *etcdsnapshot.Config, cluster *apisV1.Cluster, clusterID string) { + clusterObject, _, err := clusters.GetProvisioningClusterByName(client, cluster.Name, namespace) + require.NoError(t, err) + + // Give the option to restore the same snapshot multiple times. By default, it is set to 1. + for i := 0; i < etcdRestore.RecurringRestores; i++ { + generation := int(1) + if clusterObject.Spec.RKEConfig.ETCDSnapshotRestore != nil { + generation = clusterObject.Spec.RKEConfig.ETCDSnapshotRestore.Generation + 1 + } + + snapshotRKE2K3SRestore := &rkev1.ETCDSnapshotRestore{ + Name: snapshotName, + Generation: generation, + RestoreRKEConfig: etcdRestore.SnapshotRestore, + } + + err := etcdsnapshot.RestoreRKE2K3SSnapshot(client, snapshotRKE2K3SRestore, clusterObject.Name) + require.NoError(t, err) + + clusterObject, _, err = clusters.GetProvisioningClusterByName(client, cluster.Name, namespace) + require.NoError(t, err) + + require.Equal(t, cluster.Spec.KubernetesVersion, clusterObject.Spec.KubernetesVersion) + logrus.Infof("Cluster version is restored to: %s", clusterObject.Spec.KubernetesVersion) + + podErrors := pods.StatusPods(client, clusterID) + assert.Empty(t, podErrors) + + if etcdRestore.SnapshotRestore == all && etcdRestore.ControlPlaneConcurrencyValue != "" && etcdRestore.WorkerConcurrencyValue != "" { + logrus.Infof("Control plane concurrency value is restored to: %s", clusterObject.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency) + logrus.Infof("Worker concurrency value is restored to: %s", clusterObject.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency) + + require.Equal(t, cluster.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency, clusterObject.Spec.RKEConfig.UpgradeStrategy.ControlPlaneConcurrency) + require.Equal(t, cluster.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency, clusterObject.Spec.RKEConfig.UpgradeStrategy.WorkerConcurrency) + } + } +} + +func createPostBackupWorkloads(t *testing.T, client *rancher.Client, clusterID string, podTemplate corev1.PodTemplateSpec, deployment *v1.Deployment) (*steveV1.SteveAPIObject, *steveV1.SteveAPIObject) { + workloadNamePostBackup := namegen.AppendRandomString(postWorkload) + + postBackupDeployment := workloads.NewDeploymentTemplate(workloadNamePostBackup, defaultNamespace, podTemplate, isCattleLabeled, nil) + postBackupService := corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceAppendName + workloadNamePostBackup, + Namespace: defaultNamespace, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeClusterIP, + Ports: []corev1.ServicePort{ + { + Name: port, + Port: 80, + }, + }, + Selector: deployment.Spec.Template.Labels, + }, + } + + steveclient, err := client.Steve.ProxyDownstream(clusterID) + require.NoError(t, err) + + postDeploymentResp, err := deploy.CreateDeployment(steveclient, workloadNamePostBackup, postBackupDeployment) + require.NoError(t, err) + + err = deploy.VerifyDeployment(steveclient, postDeploymentResp) + require.NoError(t, err) + require.Equal(t, workloadNamePostBackup, postDeploymentResp.ObjectMeta.Name) + + postServiceResp, err := services.CreateService(steveclient, postBackupService) + require.NoError(t, err) + + err = services.VerifyService(steveclient, postServiceResp) + require.NoError(t, err) + require.Equal(t, serviceAppendName+workloadNamePostBackup, postServiceResp.ObjectMeta.Name) + + return postDeploymentResp, postServiceResp +} + +// This function waits for retentionlimit+1 automatic snapshots to be taken before verifying that the retention limit is respected +func createSnapshotsUntilRetentionLimit(t *testing.T, client *rancher.Client, clusterName string, retentionLimit int, timeBetweenSnapshots int) { + v1ClusterID, err := clusters.GetV1ProvisioningClusterByName(client, clusterName) + if v1ClusterID == "" { + v3ClusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + v1ClusterID = "fleet-default/" + v3ClusterID + } + require.NoError(t, err) + + fleetCluster, err := client.Steve.SteveType(stevetypes.FleetCluster).ByID(v1ClusterID) + require.NoError(t, err) + + provider := fleetCluster.ObjectMeta.Labels["provider.cattle.io"] + if provider == "rke" { + sleepNum := (retentionLimit + 1) * timeBetweenSnapshots + logrus.Infof("Waiting %v hours for %v automatic snapshots to be taken", sleepNum, (retentionLimit + 1)) + time.Sleep(time.Duration(sleepNum)*time.Hour + time.Minute*5) + + err := etcdsnapshot.RKE1RetentionLimitCheck(client, clusterName) + require.NoError(t, err) + + } else { + sleepNum := (retentionLimit + 1) * timeBetweenSnapshots + logrus.Infof("Waiting %v minutes for %v automatic snapshots to be taken", sleepNum, (retentionLimit + 1)) + time.Sleep(time.Duration(sleepNum)*time.Minute + time.Minute*5) + + err := etcdsnapshot.RKE2K3SRetentionLimitCheck(client, clusterName) + require.NoError(t, err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_additional_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_additional_test.go new file mode 100644 index 0000000..de4973b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_additional_test.go @@ -0,0 +1,185 @@ +//go:build validation + +package snapshot + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type SnapshotAdditionalTestsTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clustersConfig *etcdsnapshot.Config +} + +func (s *SnapshotAdditionalTestsTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *SnapshotAdditionalTestsTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.clustersConfig = new(etcdsnapshot.Config) + config.LoadConfig(etcdsnapshot.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *SnapshotAdditionalTestsTestSuite) TestSnapshotReplaceWorkerNode() { + snapshotRestoreAll := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "all", + RecurringRestores: 1, + ReplaceWorkerNode: true, + } + + snapshotRestoreK8sVersion := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "kubernetesVersion", + RecurringRestores: 1, + ReplaceWorkerNode: true, + } + + snapshotRestoreNone := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "none", + RecurringRestores: 1, + ReplaceWorkerNode: true, + } + + tests := []struct { + name string + etcdSnapshot *etcdsnapshot.Config + client *rancher.Client + }{ + {"Replace worker nodes and restore cluster config, Kubernetes version and etcd", snapshotRestoreAll, s.client}, + {"Replace worker nodes and restore Kubernetes version and etcd", snapshotRestoreK8sVersion, s.client}, + {"Replace worker nodes and restore etcd only", snapshotRestoreNone, s.client}, + } + + for _, tt := range tests { + clusterObject, _, _ := clusters.GetProvisioningClusterByName(tt.client, s.client.RancherConfig.ClusterName, namespace) + if clusterObject == nil { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + clusterResp, err := tt.client.Management.Cluster.ByID(clusterID) + require.NoError(s.T(), err) + + if clusterResp.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + tt.name = "RKE1 S3 " + tt.name + } else { + tt.name = "RKE1 Local " + tt.name + } + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if updatedCluster.Spec.RKEConfig.ETCD.S3 != nil { + tt.name = "S3 " + tt.name + } else { + tt.name = "Local " + tt.name + } + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "RKE2 " + tt.name + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + tt.name = "K3S " + tt.name + } + } + + s.Run(tt.name, func() { + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.etcdSnapshot) + }) + } +} + +func (s *SnapshotAdditionalTestsTestSuite) TestSnapshotRecurringRestores() { + snapshotRestoreFiveTimes := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "none", + RecurringRestores: 5, + } + + tests := []struct { + name string + etcdSnapshot *etcdsnapshot.Config + client *rancher.Client + }{ + {"Restore snapshot 5 times", snapshotRestoreFiveTimes, s.client}, + } + + for _, tt := range tests { + clusterObject, _, _ := clusters.GetProvisioningClusterByName(tt.client, s.client.RancherConfig.ClusterName, namespace) + if clusterObject == nil { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + clusterResp, err := tt.client.Management.Cluster.ByID(clusterID) + require.NoError(s.T(), err) + + if clusterResp.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + tt.name = "RKE1 S3 " + tt.name + } else { + tt.name = "RKE1 Local " + tt.name + } + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if updatedCluster.Spec.RKEConfig.ETCD.S3 != nil { + tt.name = "S3 " + tt.name + } else { + tt.name = "Local " + tt.name + } + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "RKE2 " + tt.name + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + tt.name = "K3S " + tt.name + } + } + + s.Run(tt.name, func() { + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.etcdSnapshot) + }) + } +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestSnapshotAdditionalTestsTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotAdditionalTestsTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_k8s_upgrade_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_k8s_upgrade_test.go new file mode 100644 index 0000000..9c7b81c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_k8s_upgrade_test.go @@ -0,0 +1,117 @@ +//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress + +package snapshot + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type SnapshotRestoreK8sUpgradeTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clustersConfig *etcdsnapshot.Config +} + +func (s *SnapshotRestoreK8sUpgradeTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *SnapshotRestoreK8sUpgradeTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.clustersConfig = new(etcdsnapshot.Config) + config.LoadConfig(etcdsnapshot.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *SnapshotRestoreK8sUpgradeTestSuite) TestSnapshotRestoreK8sUpgrade() { + snapshotRestoreK8sVersion := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "kubernetesVersion", + RecurringRestores: 1, + } + + tests := []struct { + name string + etcdSnapshot *etcdsnapshot.Config + client *rancher.Client + }{ + {"Restore Kubernetes version and etcd", snapshotRestoreK8sVersion, s.client}, + } + + for _, tt := range tests { + clusterObject, _, _ := clusters.GetProvisioningClusterByName(tt.client, s.client.RancherConfig.ClusterName, namespace) + if clusterObject == nil { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + clusterResp, err := tt.client.Management.Cluster.ByID(clusterID) + require.NoError(s.T(), err) + + if clusterResp.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + tt.name = "RKE1 S3 " + tt.name + } else { + tt.name = "RKE1 Local " + tt.name + } + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if updatedCluster.Spec.RKEConfig.ETCD.S3 != nil { + tt.name = "S3 " + tt.name + } else { + tt.name = "Local " + tt.name + } + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "RKE2 " + tt.name + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + tt.name = "K3S " + tt.name + } + } + + s.Run(tt.name, func() { + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.etcdSnapshot) + }) + } +} + +func (s *SnapshotRestoreK8sUpgradeTestSuite) TestSnapshotRestoreK8sUpgradeDynamicInput() { + if s.clustersConfig == nil { + s.T().Skip() + } + + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, s.clustersConfig) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestSnapshotRestoreK8sUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotRestoreK8sUpgradeTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_test.go new file mode 100644 index 0000000..ec35544 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_test.go @@ -0,0 +1,117 @@ +//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress + +package snapshot + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type SnapshotRestoreTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clustersConfig *etcdsnapshot.Config +} + +func (s *SnapshotRestoreTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *SnapshotRestoreTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.clustersConfig = new(etcdsnapshot.Config) + config.LoadConfig(etcdsnapshot.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *SnapshotRestoreTestSuite) TestSnapshotRestoreETCDOnly() { + snapshotRestoreNone := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "none", + RecurringRestores: 1, + } + + tests := []struct { + name string + etcdSnapshot *etcdsnapshot.Config + client *rancher.Client + }{ + {"Restore etcd only", snapshotRestoreNone, s.client}, + } + + for _, tt := range tests { + clusterObject, _, _ := clusters.GetProvisioningClusterByName(tt.client, s.client.RancherConfig.ClusterName, namespace) + if clusterObject == nil { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + clusterResp, err := tt.client.Management.Cluster.ByID(clusterID) + require.NoError(s.T(), err) + + if clusterResp.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + tt.name = "RKE1 S3 " + tt.name + } else { + tt.name = "RKE1 Local " + tt.name + } + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if updatedCluster.Spec.RKEConfig.ETCD.S3 != nil { + tt.name = "S3 " + tt.name + } else { + tt.name = "Local " + tt.name + } + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "RKE2 " + tt.name + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + tt.name = "K3S " + tt.name + } + } + + s.Run(tt.name, func() { + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.etcdSnapshot) + }) + } +} + +func (s *SnapshotRestoreTestSuite) TestSnapshotRestoreETCDOnlyDynamicInput() { + if s.clustersConfig == nil { + s.T().Skip() + } + + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, s.clustersConfig) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestSnapshotRestoreETCDOnlyTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotRestoreTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_upgrade_strategy_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_upgrade_strategy_test.go new file mode 100644 index 0000000..667a1cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_restore_upgrade_strategy_test.go @@ -0,0 +1,121 @@ +//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress + +package snapshot + +import ( + "strings" + "testing" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/etcdsnapshot" + + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type SnapshotRestoreUpgradeStrategyTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clustersConfig *etcdsnapshot.Config +} + +func (s *SnapshotRestoreUpgradeStrategyTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *SnapshotRestoreUpgradeStrategyTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.clustersConfig = new(etcdsnapshot.Config) + config.LoadConfig(etcdsnapshot.ConfigurationFileKey, s.clustersConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client +} + +func (s *SnapshotRestoreUpgradeStrategyTestSuite) TestSnapshotRestoreUpgradeStrategy() { + snapshotRestoreAll := &etcdsnapshot.Config{ + UpgradeKubernetesVersion: "", + SnapshotRestore: "all", + ControlPlaneConcurrencyValue: "15%", + ControlPlaneUnavailableValue: "3", + WorkerConcurrencyValue: "20%", + WorkerUnavailableValue: "15%", + RecurringRestores: 1, + } + + tests := []struct { + name string + etcdSnapshot *etcdsnapshot.Config + client *rancher.Client + }{ + {"Restore cluster config, Kubernetes version and etcd", snapshotRestoreAll, s.client}, + } + + for _, tt := range tests { + clusterObject, _, _ := clusters.GetProvisioningClusterByName(tt.client, s.client.RancherConfig.ClusterName, namespace) + if clusterObject == nil { + clusterID, err := clusters.GetClusterIDByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + clusterResp, err := tt.client.Management.Cluster.ByID(clusterID) + require.NoError(s.T(), err) + + if clusterResp.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.S3BackupConfig != nil { + tt.name = "RKE1 S3 " + tt.name + } else { + tt.name = "RKE1 Local " + tt.name + } + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(s.client, s.client.RancherConfig.ClusterName) + require.NoError(s.T(), err) + + cluster, err := tt.client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(s.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(cluster, &updatedCluster) + require.NoError(s.T(), err) + + if updatedCluster.Spec.RKEConfig.ETCD.S3 != nil { + tt.name = "S3 " + tt.name + } else { + tt.name = "Local " + tt.name + } + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + tt.name = "RKE2 " + tt.name + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + tt.name = "K3S " + tt.name + } + } + + s.Run(tt.name, func() { + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, tt.etcdSnapshot) + }) + } +} + +func (s *SnapshotRestoreUpgradeStrategyTestSuite) TestSnapshotRestoreUpgradeStrategyDynamicInput() { + if s.clustersConfig == nil { + s.T().Skip() + } + + snapshotRestore(s.T(), s.client, s.client.RancherConfig.ClusterName, s.clustersConfig) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestSnapshotRestoreUpgradeStrategyTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotRestoreUpgradeStrategyTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_retention_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_retention_test.go new file mode 100644 index 0000000..5d6ea2f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/snapshot/snapshot_retention_test.go @@ -0,0 +1,118 @@ +//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress + +package snapshot + +import ( + "fmt" + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/defaults/stevetypes" + "github.com/rancher/shepherd/pkg/config" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +// For SnapshotInterval this will be hours for rke1 and minutes for rke2 +type SnapshotRetentionConfig struct { + ClusterName string `json:"clusterName" yaml:"clusterName"` + SnapshotInterval int `json:"snapshotInterval" yaml:"snapshotInterval"` + SnapshotRetention int `json:"snapshotRetention" yaml:"snapshotRetention"` +} + +type SnapshotRetentionTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + snapshotConfig *SnapshotRetentionConfig + provider string +} + +func (s *SnapshotRetentionTestSuite) TearDownSuite() { + s.session.Cleanup() +} + +func (s *SnapshotRetentionTestSuite) SetupSuite() { + testSession := session.NewSession() + s.session = testSession + + s.snapshotConfig = new(SnapshotRetentionConfig) + config.LoadConfig("retentionTest", s.snapshotConfig) + + client, err := rancher.NewClient("", testSession) + require.NoError(s.T(), err) + + s.client = client + + v1ClusterID, err := clusters.GetV1ProvisioningClusterByName(client, s.snapshotConfig.ClusterName) + var v3ClusterID string + if v1ClusterID == "" { + v3ClusterID, err = clusters.GetClusterIDByName(client, s.snapshotConfig.ClusterName) + require.NoError(s.T(), err) + v1ClusterID = "fleet-default/" + v3ClusterID + } + + require.NoError(s.T(), err) + fleetCluster, err := s.client.Steve.SteveType(stevetypes.FleetCluster).ByID(v1ClusterID) + require.NoError(s.T(), err) + + s.provider = fleetCluster.ObjectMeta.Labels["provider.cattle.io"] + + if s.provider == "rke" { + clusterObject, err := s.client.Management.Cluster.ByID(v3ClusterID) + require.NoError(s.T(), err) + + updatedClusterObject := clusterObject + updatedClusterObject.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.Retention = int64(s.snapshotConfig.SnapshotRetention) + updatedClusterObject.RancherKubernetesEngineConfig.Services.Etcd.BackupConfig.IntervalHours = int64(s.snapshotConfig.SnapshotInterval) + + _, err = s.client.Management.Cluster.Update(clusterObject, updatedClusterObject) + require.NoError(s.T(), err) + } else { + if s.snapshotConfig.SnapshotInterval < 5 { + logrus.Info("Snapshot cron schedules below 2 minutes can cause unexpected behaviors in rancher") + } + + clusterObject, clusterResponse, err := clusters.GetProvisioningClusterByName(s.client, s.snapshotConfig.ClusterName, "fleet-default") + require.NoError(s.T(), err) + + clusterObject.Spec.RKEConfig.ETCD.SnapshotRetention = s.snapshotConfig.SnapshotRetention + cronSchedule := fmt.Sprintf("%s%v%s", "*/", s.snapshotConfig.SnapshotInterval, " * * * *") + clusterObject.Spec.RKEConfig.ETCD.SnapshotScheduleCron = cronSchedule + _, err = s.client.Steve.SteveType(stevetypes.Provisioning).Update(clusterResponse, clusterObject) + require.NoError(s.T(), err) + } +} + +func (s *SnapshotRetentionTestSuite) TestAutomaticSnapshotRetention() { + tests := []struct { + testName string + client *rancher.Client + clusterName string + retentionLimit int + intervalBetweenSnapshots int + }{ + {"Retention limit test", s.client, s.snapshotConfig.ClusterName, 2, 1}, + } + + for _, tt := range tests { + s.Run(tt.testName, func() { + config := s.snapshotConfig + createSnapshotsUntilRetentionLimit(s.T(), s.client, config.ClusterName, config.SnapshotRetention, config.SnapshotInterval) + }) + } +} + +func (s *SnapshotRetentionTestSuite) TestAutomaticSnapshotRetentionDynamic() { + config := s.snapshotConfig + createSnapshotsUntilRetentionLimit(s.T(), s.client, config.ClusterName, config.SnapshotRetention, config.SnapshotInterval) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestSnapshotRetentionTestSuite(t *testing.T) { + suite.Run(t, new(SnapshotRetentionTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/README.md new file mode 100644 index 0000000..4c64356 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/README.md @@ -0,0 +1,23 @@ +# Standalone Configs - Corral + +## Getting Started +You should have a basic understanding of Corral before running these tests. Your GO suite should be set to `-run ^TestCorralStandaloneTestSuite$`. +In your config file, set the following: +```yaml +corralPackages: + corralPackageImages: + : + ... + hasDebug: + hasCleanup: + hasCustomRepo: + +corralConfigs: + corralConfigUser: + corralConfigVars: + : + ... + corralSSHPath: +``` +Note: `corralConfigUser` will be the prefix for all resources created in your provider. +From there, your `corralConfigVars` should contain the parameters necessary to run the test. You can see what variables need to be set by navigating to your corral package folder and checking the `manifest.yaml` variables. \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/corral_generic_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/corral_generic_test.go new file mode 100644 index 0000000..da8c795 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/standalone/corral_generic_test.go @@ -0,0 +1,57 @@ +//go:build validation + +package standalone + +import ( + "testing" + + "github.com/rancher/shepherd/clients/corral" + + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type CorralStandaloneTestSuite struct { + suite.Suite + session *session.Session +} + +func (r *CorralStandaloneTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *CorralStandaloneTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + corralConfig := corral.Configurations() + err := corral.SetupCorralConfig(corralConfig.CorralConfigVars, corralConfig.CorralConfigUser, corralConfig.CorralSSHPath) + require.NoError(r.T(), err, "error reading corral configs") +} + +func (r *CorralStandaloneTestSuite) TestGenericCorralPackage() { + corralPackage := corral.PackagesConfig() + // Expecting in the future, we will be mainly running from publically available corral images + if corralPackage.HasCustomRepo != "" { + err := corral.SetCustomRepo(corralPackage.HasCustomRepo) + require.Nil(r.T(), err, "error setting remote repo") + } + newPackages := []string{} + if len(corralPackage.CorralPackageImages) == 0 { + r.T().Error("No Corral Packages to Test") + } + for packageName, packageImage := range corralPackage.CorralPackageImages { + newPackageName := namegen.AppendRandomString(packageName) + newPackages = append(newPackages, newPackageName) + corralRun, err := corral.CreateCorral(r.session, newPackageName, packageImage, corralPackage.HasDebug, corralPackage.HasDebug) + require.NoError(r.T(), err, "error creating corral %v", packageName) + r.T().Logf("Corral %v created successfully", packageName) + require.NotNil(r.T(), corralRun, "corral run had no restConfig") + } +} + +func TestCorralStandaloneTestSuite(t *testing.T) { + suite.Run(t, new(CorralStandaloneTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/pod_filter_test_cases.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/pod_filter_test_cases.go new file mode 100644 index 0000000..ee99add --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/pod_filter_test_cases.go @@ -0,0 +1,133 @@ +package vai + +import ( + "fmt" + "net/url" + + namegen "github.com/rancher/shepherd/pkg/namegenerator" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type podFilterTestCase struct { + name string + createPods func() ([]v1.Pod, []string, []string, []string) + filter func(namespaces []string) url.Values + expectFound bool + supportedWithVai bool +} + +func (p podFilterTestCase) SupportedWithVai() bool { + return p.supportedWithVai +} + +// Helper function to create a pod +func createPod(name, namespace, image string) v1.Pod { + return v1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}, + Spec: v1.PodSpec{ + Containers: []v1.Container{{Name: image, Image: image}}, + }, + } +} + +var podFilterTestCases = []podFilterTestCase{ + { + name: "Filter by nginx image", + createPods: func() ([]v1.Pod, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + name1 := fmt.Sprintf("nginx-pod-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("busybox-pod-%s", namegen.RandStringLower(randomStringLength)) + name3 := fmt.Sprintf("alpine-pod-%s", namegen.RandStringLower(randomStringLength)) + + pods := []v1.Pod{ + createPod(name1, ns1, "nginx"), + createPod(name2, ns2, "busybox"), + createPod(name3, ns1, "alpine"), + } + + expectedNames := []string{name1} + allNamespaces := []string{ns1, ns2} + expectedNamespaces := []string{ns1, ns2} + + return pods, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"spec.containers.image=nginx"}, + "projectsornamespaces": namespaces, + } + }, + expectFound: true, + supportedWithVai: true, + }, + { + name: "Filter by busybox image", + createPods: func() ([]v1.Pod, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + name1 := fmt.Sprintf("nginx-pod-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("busybox-pod-%s", namegen.RandStringLower(randomStringLength)) + name3 := fmt.Sprintf("alpine-pod-%s", namegen.RandStringLower(randomStringLength)) + + pods := []v1.Pod{ + createPod(name1, ns1, "nginx"), + createPod(name2, ns2, "busybox"), + createPod(name3, ns1, "alpine"), + } + + expectedNames := []string{name2} + allNamespaces := []string{ns1, ns2} + expectedNamespaces := []string{ns2} + + return pods, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"spec.containers.image=busybox"}, + "projectsornamespaces": namespaces, + } + }, + expectFound: true, + supportedWithVai: true, + }, + { + name: "Filter by non-existent image", + createPods: func() ([]v1.Pod, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + name1 := fmt.Sprintf("nginx-pod-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("busybox-pod-%s", namegen.RandStringLower(randomStringLength)) + name3 := fmt.Sprintf("alpine-pod-%s", namegen.RandStringLower(randomStringLength)) + + pods := []v1.Pod{ + createPod(name1, ns1, "nginx"), + createPod(name2, ns2, "busybox"), + createPod(name3, ns1, "alpine"), + } + + // Add NodeName to pods + pods[0].Spec.NodeName = "node1" + pods[1].Spec.NodeName = "node2" + pods[2].Spec.NodeName = "node1" + + expectedNames := []string{} + allNamespaces := []string{ns1, ns2} + expectedNamespaces := []string{ns1, ns2} + + return pods, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"spec.containers.image=redis"}, + "projectsornamespaces": namespaces, + } + }, + expectFound: false, + supportedWithVai: true, + }, +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/scripts/script.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/scripts/script.sh new file mode 100644 index 0000000..df1de4e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/scripts/script.sh @@ -0,0 +1,102 @@ +#!/bin/sh +set -e + +echo "Starting script execution..." + +# Function to check if Go is installed and working +check_go() { + if /usr/local/go/bin/go version >/dev/null 2>&1; then + return 0 + fi + return 1 +} + +# Install Go if not already installed +if ! check_go; then + echo "Go not found. Installing Go..." + curl -L -o go1.22.4.linux-amd64.tar.gz https://go.dev/dl/go1.22.4.linux-amd64.tar.gz --insecure + tar -C /usr/local -xzf go1.22.4.linux-amd64.tar.gz + rm go1.22.4.linux-amd64.tar.gz + echo "Go installed successfully." +else + echo "Go is already installed." +fi + +# Always set the PATH to include Go +export PATH=$PATH:/usr/local/go/bin + +echo "Checking Go version:" +go version + +# Check if vai-query already exists +if [ ! -f /usr/local/bin/vai-query ]; then + echo "vai-query not found. Building vai-query program..." + mkdir -p /root/vai-query + cd /root/vai-query + + # Initialize Go module if it doesn't exist + if [ ! -f go.mod ]; then + go mod init vai-query + fi + + # Create or update main.go + cat << EOF > main.go +package main + +import ( + "database/sql" + "fmt" + "log" + "os" + "strings" + + "github.com/pkg/errors" + _ "modernc.org/sqlite" +) + +func main() { + tableName := strings.ReplaceAll(os.Getenv("TABLE_NAME"), "\"", "") + resourceName := os.Getenv("RESOURCE_NAME") + + db, err := sql.Open("sqlite", "/var/lib/rancher/informer_object_fields.db") + if err != nil { + log.Fatal(err) + } + defer db.Close() + + query := fmt.Sprintf("SELECT \"metadata.name\" FROM \"%s\" WHERE \"metadata.name\" = ?", tableName) + stmt, err := db.Prepare(query) + if err != nil { + log.Fatal(err) + } + defer stmt.Close() + + var result string + err = stmt.QueryRow(resourceName).Scan(&result) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + fmt.Println("Resource not found") + } else { + log.Fatal(err) + } + } else { + fmt.Println("Found resource:", result) + } +} +EOF + + # Get dependencies + go get github.com/pkg/errors + go get modernc.org/sqlite + + # Build the program + go build -o /usr/local/bin/vai-query main.go + echo "Pure Go vai-query program built successfully." +else + echo "vai-query program already exists. Using existing binary." +fi + +echo "Executing the query program..." +TABLE_NAME="${TABLE_NAME}" RESOURCE_NAME="${RESOURCE_NAME}" /usr/local/bin/vai-query + +echo "Script execution completed." diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_filter_test_cases.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_filter_test_cases.go new file mode 100644 index 0000000..e7b2218 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_filter_test_cases.go @@ -0,0 +1,220 @@ +package vai + +import ( + "fmt" + "net/url" + + namegen "github.com/rancher/shepherd/pkg/namegenerator" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type secretFilterTestCase struct { + name string + createSecrets func() ([]v1.Secret, []string, []string, []string) + filter func(namespaces []string) url.Values + supportedWithVai bool +} + +func (s secretFilterTestCase) SupportedWithVai() bool { + return s.supportedWithVai +} + +var secretFilterTestCases = []secretFilterTestCase{ + { + name: "Filter with negation and namespace", + createSecrets: func() ([]v1.Secret, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("namespace-%s", suffix) + + name1 := fmt.Sprintf("secret1-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("secret2-%s", namegen.RandStringLower(randomStringLength)) + name3 := fmt.Sprintf("config3-%s", namegen.RandStringLower(randomStringLength)) + + secrets := []v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{Name: name1, Namespace: ns}, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: name2, Namespace: ns}, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: name3, Namespace: ns}, + Type: v1.SecretTypeOpaque, + }, + } + + expectedNames := []string{name1, name2} + allNamespaces := []string{ns} + expectedNamespaces := []string{ns} + + return secrets, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"metadata.name!=config"}, + "projectsornamespaces": namespaces, + } + }, + supportedWithVai: true, + }, + { + name: "Filter by namespace", + createSecrets: func() ([]v1.Secret, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + name1 := fmt.Sprintf("secret1-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("secret2-%s", namegen.RandStringLower(randomStringLength)) + + secrets := []v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{Name: name1, Namespace: ns1}, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: name2, Namespace: ns2}, + Type: v1.SecretTypeOpaque, + }, + } + + expectedNames := []string{name1} + allNamespaces := []string{ns1, ns2} + expectedNamespaces := []string{ns1} + + return secrets, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "projectsornamespaces": []string{namespaces[0]}, + } + }, + supportedWithVai: true, + }, + { + name: "Filter by name and namespace", + createSecrets: func() ([]v1.Secret, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("namespace-%s", suffix) + name1 := fmt.Sprintf("secret1-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("config2-%s", namegen.RandStringLower(randomStringLength)) + + secrets := []v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{Name: name1, Namespace: ns}, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: name2, Namespace: ns}, + Type: v1.SecretTypeOpaque, + }, + } + + expectedNames := []string{name1} + allNamespaces := []string{ns} + expectedNamespaces := []string{ns} + + return secrets, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"metadata.name=secret1"}, + "projectsornamespaces": namespaces, + } + }, + supportedWithVai: true, + }, + { + name: "Filter by single label", + createSecrets: func() ([]v1.Secret, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("namespace-%s", suffix) + name1 := fmt.Sprintf("secret1-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("secret2-%s", namegen.RandStringLower(randomStringLength)) + + secrets := []v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: name1, + Namespace: ns, + Labels: map[string]string{"key1": "value1"}, + }, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: name2, + Namespace: ns, + Labels: map[string]string{"key1": "value2"}, + }, + Type: v1.SecretTypeOpaque, + }, + } + + expectedNames := []string{name1} + allNamespaces := []string{ns} + expectedNamespaces := []string{ns} + + return secrets, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"metadata.labels.key1=value1"}, + "projectsornamespaces": namespaces, + } + }, + supportedWithVai: false, + }, + { + name: "Filter by multiple labels", + createSecrets: func() ([]v1.Secret, []string, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("namespace-%s", suffix) + name1 := fmt.Sprintf("secret1-%s", namegen.RandStringLower(randomStringLength)) + name2 := fmt.Sprintf("secret2-%s", namegen.RandStringLower(randomStringLength)) + name3 := fmt.Sprintf("secret3-%s", namegen.RandStringLower(randomStringLength)) + + secrets := []v1.Secret{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: name1, + Namespace: ns, + Labels: map[string]string{"key1": "value1", "key2": "value2"}, + }, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: name2, + Namespace: ns, + Labels: map[string]string{"key1": "value1"}, + }, + Type: v1.SecretTypeOpaque, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: name3, + Namespace: ns, + Labels: map[string]string{"key2": "value2"}, + }, + Type: v1.SecretTypeOpaque, + }, + } + + expectedNames := []string{name1} + allNamespaces := []string{ns} + expectedNamespaces := []string{ns} + + return secrets, expectedNames, allNamespaces, expectedNamespaces + }, + filter: func(namespaces []string) url.Values { + return url.Values{ + "filter": []string{"metadata.labels.key1=value1", "metadata.labels.key2=value2"}, + "projectsornamespaces": namespaces, + } + }, + supportedWithVai: false, + }, +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_limit_test_cases.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_limit_test_cases.go new file mode 100644 index 0000000..f6187be --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_limit_test_cases.go @@ -0,0 +1,87 @@ +package vai + +import ( + "fmt" + + namegen "github.com/rancher/shepherd/pkg/namegenerator" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type secretLimitTestCase struct { + name string + createSecrets func() ([]v1.Secret, string) + limit int + expectedTotal int + supportedWithVai bool +} + +func (s secretLimitTestCase) SupportedWithVai() bool { + return s.supportedWithVai +} + +var secretLimitTestCases = []secretLimitTestCase{ + { + name: "Paginate 50 secrets with limit 10", + createSecrets: func() ([]v1.Secret, string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("pagination-ns-%s", suffix) + numSecrets := 50 + secrets := make([]v1.Secret, numSecrets) + for i := 0; i < numSecrets; i++ { + secrets[i] = v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("pagination-secret%d-%s", i+1, suffix), + Namespace: ns, + }, + } + } + return secrets, ns + }, + limit: 10, + expectedTotal: 50, + supportedWithVai: true, + }, + { + name: "Paginate 100 secrets with limit 25", + createSecrets: func() ([]v1.Secret, string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("pagination-ns-%s", suffix) + numSecrets := 100 + secrets := make([]v1.Secret, numSecrets) + for i := 0; i < numSecrets; i++ { + secrets[i] = v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("pagination-secret%d-%s", i+1, suffix), + Namespace: ns, + }, + } + } + return secrets, ns + }, + limit: 25, + expectedTotal: 100, + supportedWithVai: true, + }, + { + name: "Paginate 30 secrets with limit 50", + createSecrets: func() ([]v1.Secret, string) { + suffix := namegen.RandStringLower(randomStringLength) + ns := fmt.Sprintf("pagination-ns-%s", suffix) + numSecrets := 30 + secrets := make([]v1.Secret, numSecrets) + for i := 0; i < numSecrets; i++ { + secrets[i] = v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("pagination-secret%d-%s", i+1, suffix), + Namespace: ns, + }, + } + } + return secrets, ns + }, + limit: 50, + expectedTotal: 30, + supportedWithVai: true, + }, +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_sort_test_cases.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_sort_test_cases.go new file mode 100644 index 0000000..3134f33 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/secret_sort_test_cases.go @@ -0,0 +1,218 @@ +package vai + +import ( + "fmt" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "net/url" + "sort" + "strings" + + v1 "k8s.io/api/core/v1" +) + +type secretSortTestCase struct { + name string + createSecrets func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) + sort func() url.Values + supportedWithVai bool +} + +func (s secretSortTestCase) SupportedWithVai() bool { + return s.supportedWithVai +} + +// getSortedSecretNames is a helper function to sort secrets based on the provided sort parameters +func getSortedSecretNames(secrets []v1.Secret, sortFunc func() url.Values) []string { + sortValues := sortFunc() + sortFields := strings.Split(sortValues.Get("sort"), ",") + + sort.Slice(secrets, func(firstIndex, secondIndex int) bool { + for _, field := range sortFields { + ascending := true + if strings.HasPrefix(field, "-") { + ascending = false + field = field[1:] + } + + var firstValue, secondValue string + switch field { + case "metadata.name": + firstValue, secondValue = secrets[firstIndex].Name, secrets[secondIndex].Name + case "metadata.namespace": + firstValue, secondValue = secrets[firstIndex].Namespace, secrets[secondIndex].Namespace + default: + continue + } + + if firstValue != secondValue { + if ascending { + return firstValue < secondValue + } + return firstValue > secondValue + } + } + return false + }) + + sortedNames := make([]string, len(secrets)) + for index, secret := range secrets { + sortedNames[index] = secret.Name + } + return sortedNames +} + +var secretSortTestCases = []secretSortTestCase{ + { + name: "Sort by name ascending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"metadata.name"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by name descending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"-metadata.name"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by namespace ascending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"metadata.namespace"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by namespace descending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"-metadata.namespace,metadata.name"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by name and namespace ascending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"metadata.name,metadata.namespace"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by namespace and name ascending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"metadata.namespace,metadata.name"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by name ascending and namespace descending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"metadata.name,-metadata.namespace"}} + }, + supportedWithVai: true, + }, + { + name: "Sort by namespace descending and name ascending", + createSecrets: func(sortFunc func() url.Values) ([]v1.Secret, []string, []string) { + suffix := namegen.RandStringLower(randomStringLength) + ns1 := fmt.Sprintf("namespace1-%s", suffix) + ns2 := fmt.Sprintf("namespace2-%s", suffix) + secrets := []v1.Secret{ + {ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret2", Namespace: ns1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret3", Namespace: ns2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "secret4", Namespace: ns2}}, + } + return secrets, getSortedSecretNames(secrets, sortFunc), []string{ns1, ns2} + }, + sort: func() url.Values { + return url.Values{"sort": []string{"-metadata.namespace,metadata.name"}} + }, + supportedWithVai: true, + }, +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai.go new file mode 100644 index 0000000..735308c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai.go @@ -0,0 +1,90 @@ +package vai + +import ( + "fmt" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/vai" + "strings" + "sync" +) + +const ( + randomStringLength = 8 + uiSQLCacheResource = "ui-sql-cache" +) + +type SupportedWithVai interface { + SupportedWithVai() bool +} + +func isVaiEnabled(client *rancher.Client) (bool, error) { + managementClient := client.Steve.SteveType("management.cattle.io.feature") + steveCacheFlagResp, err := managementClient.ByID(uiSQLCacheResource) + if err != nil { + return false, err + } + spec, ok := steveCacheFlagResp.Spec.(map[string]interface{}) + if !ok { + return false, fmt.Errorf("unable to access Spec field") + } + + valueInterface, exists := spec["value"] + if !exists { + return false, nil + } + + if valueInterface == nil { + return false, nil + } + + value, ok := valueInterface.(bool) + if !ok { + return false, fmt.Errorf("value field is not a boolean") + } + + return value, nil +} + +func enableVAI(client *rancher.Client, vaiEnabled *bool, once *sync.Once) error { + var enableErr error + once.Do(func() { + if err := vai.EnableVaiCaching(client); err != nil { + enableErr = fmt.Errorf("failed to enable VAI caching: %w", err) + return + } + *vaiEnabled = true + }) + return enableErr +} + +func filterTestCases[T SupportedWithVai](testCases []T, vaiEnabled bool) []T { + if !vaiEnabled { + return testCases + } + + var supported []T + for _, tc := range testCases { + if tc.SupportedWithVai() { + supported = append(supported, tc) + } + } + return supported +} + +func listRancherPods(client *rancher.Client) ([]string, error) { + // Use the Steve client to list all pods + podList, err := client.Steve.SteveType("pod").NamespacedSteveClient("cattle-system").List(nil) + if err != nil { + return nil, fmt.Errorf("failed to list pods: %w", err) + } + + var rancherPodNames []string + for _, pod := range podList.Data { + + // Filter for Rancher pods, excluding the webhook + if pod.Labels["app"] == "rancher" && !strings.Contains(pod.Name, "webhook") { + rancherPodNames = append(rancherPodNames, pod.Name) + } + } + return rancherPodNames, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai_test.go new file mode 100644 index 0000000..3c55567 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/steve/vai/vai_test.go @@ -0,0 +1,565 @@ +//go:build (validation || infra.any || cluster.any || extended) && !stress + +package vai + +import ( + "fmt" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/kubectl" + "github.com/rancher/shepherd/extensions/vai" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + coreV1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "net/url" + "strings" + "sync" + "testing" + "time" +) + +const scriptURL = "https://raw.githubusercontent.com/rancher/rancher/release/v2.9/tests/v2/validation/steve/vai/scripts/script.sh" + +type VaiTestSuite struct { + suite.Suite + client *rancher.Client + steveClient *steveV1.Client + session *session.Session + cluster management.Cluster + vaiEnabled bool + once sync.Once +} + +func (v *VaiTestSuite) SetupSuite() { + testSession := session.NewSession() + v.session = testSession + + client, err := rancher.NewClient("", v.session) + require.NoError(v.T(), err) + + v.client = client + v.steveClient = client.Steve + + enabled, err := isVaiEnabled(v.client) + + require.NoError(v.T(), err) + v.vaiEnabled = enabled +} + +func (v *VaiTestSuite) TearDownSuite() { + v.session.Cleanup() +} + +func (v *VaiTestSuite) enableVai() error { + logrus.Info("Enabling VAI caching") + startTime := time.Now() + err := enableVAI(v.client, &v.vaiEnabled, &v.once) + if err != nil { + return err + } + duration := time.Since(startTime) + logrus.Infof("Enabling VAI took %s", formatDuration(duration)) + v.vaiEnabled = true + return nil +} + +func (v *VaiTestSuite) disableVai() error { + logrus.Info("Disabling VAI caching") + startTime := time.Now() + err := vai.DisableVaiCaching(v.client) + if err != nil { + return err + } + duration := time.Since(startTime) + logrus.Infof("Disabling VAI took %s", formatDuration(duration)) + v.vaiEnabled = false + return nil +} + +func formatDuration(d time.Duration) string { + d = d.Round(time.Second) + h := d / time.Hour + d -= h * time.Hour + m := d / time.Minute + d -= m * time.Minute + s := d / time.Second + if h > 0 { + return fmt.Sprintf("%d hours %d minutes %d seconds", h, m, s) + } else if m > 0 { + return fmt.Sprintf("%d minutes %d seconds", m, s) + } else { + return fmt.Sprintf("%d seconds", s) + } +} + +func (v *VaiTestSuite) TestVAI() { + v.Run("InitialState", func() { + if v.vaiEnabled { + v.Run("TestWithVaiInitiallyEnabled", v.testWithVaiEnabled) + } else { + v.Run("TestWithVaiInitiallyDisabled", v.testWithVaiDisabled) + } + }) + + v.Run("ToggleVaiAndRetest", func() { + initialState := v.vaiEnabled + if initialState { + err := v.disableVai() + require.NoError(v.T(), err) + v.testWithVaiDisabled() + } else { + err := v.enableVai() + require.NoError(v.T(), err) + v.testWithVaiEnabled() + } + }) +} + +func (v *VaiTestSuite) testWithVaiEnabled() { + v.Run("SecretFilters", func() { + supportedWithVai := filterTestCases(secretFilterTestCases, v.vaiEnabled) + v.runSecretFilterTestCases(supportedWithVai) + }) + + v.Run("PodFilters", func() { + supportedWithVai := filterTestCases(podFilterTestCases, v.vaiEnabled) + v.runPodFilterTestCases(supportedWithVai) + }) + + v.Run("SecretSorting", func() { + supportedWithVai := filterTestCases(secretSortTestCases, v.vaiEnabled) + v.runSecretSortTestCases(supportedWithVai) + }) + + v.Run("SecretLimit", func() { + supportedWithVai := filterTestCases(secretLimitTestCases, v.vaiEnabled) + v.runSecretLimitTestCases(supportedWithVai) + }) + + v.Run("CheckDBFilesInPods", v.checkDBFilesInPods) + v.Run("CheckSecretInDB", v.checkSecretInVAIDatabase) + v.Run("CheckNamespaceInAllVAIDatabases", v.checkNamespaceInAllVAIDatabases) +} + +func (v *VaiTestSuite) testWithVaiDisabled() { + v.Run("SecretFilters", func() { + unsupportedWithVai := filterTestCases(secretFilterTestCases, v.vaiEnabled) + v.runSecretFilterTestCases(unsupportedWithVai) + }) + + v.Run("PodFilters", func() { + unsupportedWithVai := filterTestCases(podFilterTestCases, v.vaiEnabled) + v.runPodFilterTestCases(unsupportedWithVai) + }) + + v.Run("SecretSorting", func() { + unsupportedWithVai := filterTestCases(secretSortTestCases, v.vaiEnabled) + v.runSecretSortTestCases(unsupportedWithVai) + }) + + v.Run("SecretLimit", func() { + unsupportedWithVai := filterTestCases(secretLimitTestCases, v.vaiEnabled) + v.runSecretLimitTestCases(unsupportedWithVai) + }) + + v.Run("NormalOperations", v.testNormalOperationsWithVaiDisabled) +} + +func (v *VaiTestSuite) testNormalOperationsWithVaiDisabled() { + pods, err := v.client.Steve.SteveType("pod").List(nil) + require.NoError(v.T(), err) + assert.NotEmpty(v.T(), pods.Data, "Should be able to list pods even with VAI disabled") +} + +func (v *VaiTestSuite) runSecretFilterTestCases(testCases []secretFilterTestCase) { + secretClient := v.steveClient.SteveType("secret") + namespaceClient := v.steveClient.SteveType("namespace") + + for _, tc := range testCases { + v.Run(tc.name, func() { + logrus.Infof("Starting case: %s", tc.name) + logrus.Infof("Running with vai enabled: [%v]", v.vaiEnabled) + + secrets, expectedNames, allNamespaces, expectedNamespaces := tc.createSecrets() + + for _, ns := range allNamespaces { + logrus.Infof("Creating namespace: %s", ns) + _, err := namespaceClient.Create(&coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + }, + }) + require.NoError(v.T(), err) + } + + createdSecrets := make([]steveV1.SteveAPIObject, len(secrets)) + for i, secret := range secrets { + created, err := secretClient.Create(&secret) + require.NoError(v.T(), err) + createdSecrets[i] = *created + } + + filterValues := tc.filter(expectedNamespaces) + + secretCollection, err := secretClient.List(filterValues) + require.NoError(v.T(), err) + + var actualNames []string + for _, item := range secretCollection.Data { + actualNames = append(actualNames, item.GetName()) + } + + require.Equal(v.T(), len(expectedNames), len(actualNames), "Number of returned secrets doesn't match expected") + for _, expectedName := range expectedNames { + require.Contains(v.T(), actualNames, expectedName, fmt.Sprintf("Expected secret %s not found in actual secrets", expectedName)) + } + }) + } +} + +func (v *VaiTestSuite) runPodFilterTestCases(testCases []podFilterTestCase) { + podClient := v.steveClient.SteveType("pod") + namespaceClient := v.steveClient.SteveType("namespace") + + for _, tc := range testCases { + v.Run(tc.name, func() { + logrus.Infof("Starting case: %s", tc.name) + logrus.Infof("Running with vai enabled: [%v]", v.vaiEnabled) + + pods, expectedNames, allNamespaces, expectedNamespaces := tc.createPods() + + for _, ns := range allNamespaces { + logrus.Infof("Creating namespace: %s", ns) + _, err := namespaceClient.Create(&coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + }, + }) + require.NoError(v.T(), err) + } + + createdPods := make([]steveV1.SteveAPIObject, len(pods)) + for i, pod := range pods { + created, err := podClient.Create(&pod) + require.NoError(v.T(), err) + createdPods[i] = *created + } + + filterValues := tc.filter(expectedNamespaces) + + podCollection, err := podClient.List(filterValues) + require.NoError(v.T(), err) + + var actualNames []string + for _, item := range podCollection.Data { + actualNames = append(actualNames, item.GetName()) + } + + if tc.expectFound { + require.Equal(v.T(), len(expectedNames), len(actualNames), "Number of returned pods doesn't match expected") + for _, expectedName := range expectedNames { + require.Contains(v.T(), actualNames, expectedName, fmt.Sprintf("Expected pod %s not found in actual pods", expectedName)) + } + } else { + require.Empty(v.T(), actualNames, "Expected no pods to be found, but some were returned") + } + }) + } +} + +func (v *VaiTestSuite) runSecretSortTestCases(testCases []secretSortTestCase) { + secretClient := v.steveClient.SteveType("secret") + namespaceClient := v.steveClient.SteveType("namespace") + + for _, tc := range testCases { + v.Run(tc.name, func() { + logrus.Infof("Starting case: %s", tc.name) + logrus.Infof("Running with vai enabled: [%v]", v.vaiEnabled) + + secrets, sortedNames, namespaces := tc.createSecrets(tc.sort) + + for _, ns := range namespaces { + _, err := namespaceClient.Create(&coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + }, + }) + require.NoError(v.T(), err) + } + + for _, secret := range secrets { + _, err := secretClient.Create(&secret) + require.NoError(v.T(), err) + } + + sortValues := tc.sort() + sortValues.Add("projectsornamespaces", strings.Join(namespaces, ",")) + + secretCollection, err := secretClient.List(sortValues) + require.NoError(v.T(), err) + + var actualNames []string + for _, item := range secretCollection.Data { + actualNames = append(actualNames, item.GetName()) + } + + require.Equal(v.T(), len(sortedNames), len(actualNames), "Number of returned secrets doesn't match expected") + for i, expectedName := range sortedNames { + require.Equal(v.T(), expectedName, actualNames[i], fmt.Sprintf("Secret at position %d doesn't match expected order", i)) + } + }) + } +} + +func (v *VaiTestSuite) runSecretLimitTestCases(testCases []secretLimitTestCase) { + for _, tc := range testCases { + v.Run(tc.name, func() { + logrus.Infof("Starting case: %s", tc.name) + logrus.Infof("Running with vai enabled: [%v]", v.vaiEnabled) + + secrets, ns := tc.createSecrets() + + namespaceClient := v.steveClient.SteveType("namespace") + _, err := namespaceClient.Create(&coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns, + }, + }) + require.NoError(v.T(), err) + + secretClient := v.steveClient.SteveType("secret").NamespacedSteveClient(ns) + for _, secret := range secrets { + _, err := secretClient.Create(&secret) + require.NoError(v.T(), err) + } + + var retrievedSecrets []coreV1.Secret + var continueToken string + for { + params := url.Values{} + params.Set("limit", fmt.Sprintf("%d", tc.limit)) + if continueToken != "" { + params.Set("continue", continueToken) + } + + secretCollection, err := secretClient.List(params) + require.NoError(v.T(), err) + + for _, obj := range secretCollection.Data { + var secret coreV1.Secret + err := steveV1.ConvertToK8sType(obj.JSONResp, &secret) + require.NoError(v.T(), err) + retrievedSecrets = append(retrievedSecrets, secret) + } + + if secretCollection.Pagination == nil || secretCollection.Pagination.Next == "" { + break + } + nextURL, err := url.Parse(secretCollection.Pagination.Next) + require.NoError(v.T(), err) + continueToken = nextURL.Query().Get("continue") + } + + require.Equal(v.T(), tc.expectedTotal, len(retrievedSecrets), "Number of retrieved secrets doesn't match expected") + + expectedSecrets := make(map[string]bool) + for _, secret := range secrets { + expectedSecrets[secret.Name] = false + } + + for _, secret := range retrievedSecrets { + _, ok := expectedSecrets[secret.Name] + require.True(v.T(), ok, "Unexpected secret: %s", secret.Name) + expectedSecrets[secret.Name] = true + } + + for name, found := range expectedSecrets { + require.True(v.T(), found, "Expected secret not found: %s", name) + } + }) + } +} + +func (v *VaiTestSuite) checkDBFilesInPods() { + expectedDBFiles := []string{"informer_object_cache.db", "informer_object_fields.db"} + + rancherPods, err := listRancherPods(v.client) + require.NoError(v.T(), err) + + for _, pod := range rancherPods { + v.T().Run(fmt.Sprintf("Checking pod %s", pod), func(t *testing.T) { + lsCmd := []string{"kubectl", "exec", pod, "-n", "cattle-system", "--", "ls"} + output, err := kubectl.Command(v.client, nil, "local", lsCmd, "") + if err != nil { + t.Errorf("Error executing command in pod %s: %v", pod, err) + return + } + + files := strings.Fields(output) + var dbFiles []string + for _, file := range files { + if strings.HasSuffix(file, ".db") { + dbFiles = append(dbFiles, file) + } + } + + for _, expectedFile := range expectedDBFiles { + found := false + for _, dbFile := range dbFiles { + if dbFile == expectedFile { + found = true + break + } + } + if !found { + t.Errorf("Expected file %s not found in pod %s", expectedFile, pod) + } + } + }) + } +} + +func (v *VaiTestSuite) checkSecretInVAIDatabase() { + v.T().Log("Starting checkSecretInVAIDatabase test") + + secretName := fmt.Sprintf("db-secret-%s", namegen.RandStringLower(randomStringLength)) + v.T().Logf("Generated secret name: %s", secretName) + + secret := &coreV1.Secret{ + ObjectMeta: metav1.ObjectMeta{Name: secretName, Namespace: "default"}, + Type: coreV1.SecretTypeOpaque, + } + + secretClient := v.steveClient.SteveType("secret") + v.T().Log("Creating secret...") + _, err := secretClient.Create(secret) + require.NoError(v.T(), err) + v.T().Log("Secret created successfully") + + v.T().Log("Listing Rancher pods...") + rancherPods, err := listRancherPods(v.client) + require.NoError(v.T(), err) + v.T().Logf("Found %d Rancher pods", len(rancherPods)) + + v.T().Logf("Using script URL: %s", scriptURL) + + secretFound := false + var outputs []string + + v.T().Log("List all secrets to hydrate database...") + _, err = v.client.Steve.SteveType("secret").List(nil) + require.NoError(v.T(), err) + + for i, pod := range rancherPods { + v.T().Logf("Processing pod %d: %s", i+1, pod) + cmd := []string{ + "kubectl", "exec", pod, "-n", "cattle-system", "--", + "sh", "-c", + fmt.Sprintf("curl -k -sSL %s | TABLE_NAME='_v1_Secret_fields' RESOURCE_NAME='%s' sh", scriptURL, secretName), + } + + v.T().Logf("Executing command on pod %s", pod) + output, err := kubectl.Command(v.client, nil, "local", cmd, "") + if err != nil { + v.T().Logf("Error executing script on pod %s: %v", pod, err) + continue + } + v.T().Logf("Command executed successfully on pod %s", pod) + + outputs = append(outputs, fmt.Sprintf("Output from pod %s:\n%s", pod, output)) + + if strings.Contains(output, secretName) { + v.T().Logf("Secret found in pod %s", pod) + secretFound = true + break + } else { + v.T().Logf("Secret not found in pod %s", pod) + } + } + + v.T().Log("Logging all outputs:") + for i, output := range outputs { + v.T().Logf("Output %d:\n%s", i+1, output) + } + + v.T().Logf("Secret found status: %v", secretFound) + assert.True(v.T(), secretFound, fmt.Sprintf("Secret %s not found in any of the Rancher pods' databases", secretName)) + v.T().Log("checkSecretInVAIDatabase test completed") +} + +func (v *VaiTestSuite) checkNamespaceInAllVAIDatabases() { + v.T().Log("Starting TestCheckNamespaceInAllVAIDatabases test") + + namespaceName := fmt.Sprintf("db-namespace-%s", namegen.RandStringLower(randomStringLength)) + v.T().Logf("Generated namespace name: %s", namespaceName) + + namespace := &coreV1.Namespace{ + ObjectMeta: metav1.ObjectMeta{Name: namespaceName}, + } + + namespaceClient := v.steveClient.SteveType("namespace") + v.T().Log("Creating namespace...") + _, err := namespaceClient.Create(namespace) + require.NoError(v.T(), err) + v.T().Log("Namespace created successfully") + + _, err = v.client.Steve.SteveType("namespace").List(nil) + require.NoError(v.T(), err) + + v.T().Log("Listing Rancher pods...") + rancherPods, err := listRancherPods(v.client) + require.NoError(v.T(), err) + v.T().Logf("Found %d Rancher pods", len(rancherPods)) + + v.T().Logf("Using script URL: %s", scriptURL) + + var outputs []string + namespaceFoundCount := 0 + + for i, pod := range rancherPods { + v.T().Logf("Processing pod %d: %s", i+1, pod) + cmd := []string{ + "kubectl", "exec", pod, "-n", "cattle-system", "--", + "sh", "-c", + fmt.Sprintf("curl -k -sSL %s | TABLE_NAME='_v1_Namespace_fields' RESOURCE_NAME='%s' sh", scriptURL, namespaceName), + } + + v.T().Logf("Executing command on pod %s", pod) + output, err := kubectl.Command(v.client, nil, "local", cmd, "") + if err != nil { + v.T().Logf("Error executing script on pod %s: %v", pod, err) + continue + } + v.T().Logf("Command executed successfully on pod %s", pod) + + outputs = append(outputs, fmt.Sprintf("Output from pod %s:\n%s", pod, output)) + + if strings.Contains(output, namespaceName) { + v.T().Logf("Namespace found in pod %s", pod) + namespaceFoundCount++ + } else { + v.T().Logf("Namespace not found in pod %s", pod) + } + } + + v.T().Log("Logging all outputs:") + for i, output := range outputs { + v.T().Logf("Output %d:\n%s", i+1, output) + } + + v.T().Logf("Namespace found count: %d", namespaceFoundCount) + assert.Equal(v.T(), len(rancherPods), namespaceFoundCount, + fmt.Sprintf("Namespace %s not found in all Rancher pods' databases. Found in %d out of %d pods.", + namespaceName, namespaceFoundCount, len(rancherPods))) + v.T().Log("TestCheckNamespaceInAllVAIDatabases test completed") +} + +func TestVaiTestSuite(t *testing.T) { + suite.Run(t, new(VaiTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/token/token_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/token/token_test.go new file mode 100644 index 0000000..35eea1f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/token/token_test.go @@ -0,0 +1,65 @@ +//go:build (validation || infra.any || cluster.any || sanity) && !stress + +package token + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + fv3 "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/kubeapi/tokens" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + initialTokenDesc = "my-token" + updatedTokenDesc = "changed-token" + localClusterID = "local" +) + +type TokenTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (t *TokenTestSuite) TearDownSuite() { + t.session.Cleanup() +} + +func (t *TokenTestSuite) SetupSuite() { + testSession := session.NewSession() + t.session = testSession + + client, err := rancher.NewClient("", t.session) + require.NoError(t.T(), err) + + t.client = client +} + +func (t *TokenTestSuite) TestPatchToken() { + tokenToCreate := &fv3.Token{Description: initialTokenDesc} + createdToken, err := t.client.Management.Token.Create(tokenToCreate) + require.NoError(t.T(), err) + + assert.Equal(t.T(), initialTokenDesc, createdToken.Description) + + patchedToken, unstructuredRes, err := tokens.PatchToken(t.client, localClusterID, createdToken.Name, "replace", "/description", updatedTokenDesc) + require.NoError(t.T(), err) + + assert.Equal(t.T(), updatedTokenDesc, patchedToken.Description) + + uc := unstructuredRes.UnstructuredContent() + if val, ok := uc["groupPrincipals"]; ok { + assert.NotEmpty(t.T(), val) + } +} + +func TestTokenTestSuite(t *testing.T) { + suite.Run(t, new(TokenTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/README.md new file mode 100644 index 0000000..a4d1a3f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/README.md @@ -0,0 +1,86 @@ +# Upgrade Configs + +## Table of Contents +1. [Getting Started](#Getting-Started) +2. [Cloud Provider Migration](#cloud-provider-migration) + +## Getting Started +Kubernetes and pre/post upgrade workload tests use the same single shared configuration as shown below. You can find the correct suite name below by checking the test file you plan to run. +In your config file, set the following, this will run each test in parallel both for Post/Pre and Kubernetes tests: + +```yaml +upgradeInput: + clusters: + - name: "" # Cluster name that is already provisioned in Rancher + psact: "" # Values are rancher-privileged, rancher-restricted or rancher-baseline + enabledFeatures: + chart: false # Boolean, pre/post upgrade checks, default is false + ingress: false # Boolean, pre/post upgrade checks, default is false + provisioningInput: # See the [Hosted Provider Provisioning](hosted/README.md) + rke1KubernetesVersion: [""] + rke2KubernetesVersion: [""] + k3sKubernetesVersion: [""] +``` +Note: To see the `provisioningInput` in further detail, please review over the [Provisioning README](../provisioning/README.md). +See below how to run the test: + +### Kubernetes Upgrade +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/upgrade --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestKubernetesUpgradeTestSuite/TestUpgradeKubernetes"` + +## Cloud Provider Migration +Migrates a cluster's cloud provider from in-tree to out-of-tree + +### Current Support: +* AWS + * RKE1 + * RKE2 + +### Pre-Requisites in the provided cluster +* in-tree provider is enabled +* out-of-tree provider is supported with your selected kubernetes version + +### Running the test +```yaml +rancher: + host: + adminToken: + insecure: true/false + cleanup: false/true + clusterName: "" +``` + +**note** that no `upgradeInput` is required. See below how to run each of the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/upgrade --junitfile results.xml -- -timeout=60m -tags=validation -v -run "TestCloudProviderMigrationTestSuite/TestAWS"` + + +## Cloud Provider Upgrade +Upgrades the chart version of cloud provider (CPI/CSI) + +### Current Support: +* Vsphere + * RKE1 + +### Pre-Requisites on the cluster +* cluster should have upgradeable CPI/CSI charts installed. You can do this via automation in provisioning/rke1 with the following option, chartUpgrade, which will install a version of the chart (latest - 1) that can later be upgraded to the latest version. +```yaml +chartUpgrade: + isUpgradable: true +``` + +### Running the test +```yaml +rancher: + host: + adminToken: + insecure: true/false + cleanup: false/true + clusterName: "" +vmwarevsphereCredentials: + ... +vmwarevsphereConfig: + ... +``` +See below how to run each of the tests: + +`gotestsum --format standard-verbose --packages=github.com/rancher/rancher/tests/v2/validation/upgrade --junitfile results.xml -- -timeout=60m -tags=validation -v -run ^TestCloudProviderVersionUpgradeSuite$"` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration.go new file mode 100644 index 0000000..96c19ef --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration.go @@ -0,0 +1,293 @@ +package upgrade + +import ( + "os" + "testing" + + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + v1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubectl" + "github.com/rancher/shepherd/extensions/services" + "github.com/rancher/shepherd/extensions/workloads" + "github.com/rancher/shepherd/extensions/workloads/pods" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + rancherShellSettingID = "shell-image" + controlPlaneMatchLabelKey = "rke.cattle.io/control-plane-role" + kubeControllerManagerArgKey = "kube-controller-manager-arg" + enableLeaderMigration = "enable-leader-migration" + fleetNamespace = "fleet-default" + + outOfTreeAWSYamlPath = "../provisioning/resources/out-of-tree/aws.yml" +) + +var ( + group int64 + user int64 +) + +// runKubectlCommand is a helper that takes a client of a cluster and a command, then creates all needed +// resources in order to run the command on the cluster via a corev1.job +func runKubectlCommand(client *rancher.Client, cmd, v3ClusterName string) error { + jobName := namegen.AppendRandomString("job") + imageSetting, err := client.Management.Setting.ByID(rancherShellSettingID) + if err != nil { + return err + } + + jobTemplate := workloads.NewJobTemplate(jobName, kubectl.Namespace) + args := []string{ + cmd, + } + + command := []string{"/bin/sh", "-c"} + securityContext := &corev1.SecurityContext{ + RunAsUser: &user, + RunAsGroup: &group, + } + volumeMount := []corev1.VolumeMount{ + {Name: "config", MountPath: "/root/.kube/"}, + } + container := workloads.NewContainer( + jobName, imageSetting.Value, corev1.PullAlways, volumeMount, nil, command, securityContext, args) + jobTemplate.Spec.Template.Spec.Containers = append(jobTemplate.Spec.Template.Spec.Containers, container) + + return kubectl.CreateJobAndRunKubectlCommands(v3ClusterName, jobName, jobTemplate, client) +} + +// enableLeaderMigrationInMachineSelector adds the enable-leader-migration flag to the kube-controller-manager-arg-key +// in the provided []RKESystemConfig in order to enable leader migration. Returns the updated []RKESystemConfig. +func enableLeaderMigrationInMachineSelector(existingMachineSelectorConfig []v1.RKESystemConfig) []v1.RKESystemConfig { + isExistingControlPlaneSelector := false + for _, selectorConfig := range existingMachineSelectorConfig { + if selectorConfig.MachineLabelSelector != nil { + for key := range selectorConfig.MachineLabelSelector.MatchLabels { + logrus.Info(key) + if key == controlPlaneMatchLabelKey { + selectorConfig.Config.Data[kubeControllerManagerArgKey] = append( + selectorConfig.Config.Data[kubeControllerManagerArgKey].([]string), enableLeaderMigration) + logrus.Infof("Output1: %v", selectorConfig) + isExistingControlPlaneSelector = true + break + } + } + } + } + + if !isExistingControlPlaneSelector { + controlPlaneSelector := v1.RKESystemConfig{ + MachineLabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + controlPlaneMatchLabelKey: "true", + }, + }, + Config: v1.GenericMap{ + Data: map[string]interface{}{ + kubeControllerManagerArgKey: []string{enableLeaderMigration}, + }, + }, + } + existingMachineSelectorConfig = append(existingMachineSelectorConfig, controlPlaneSelector) + } + + return existingMachineSelectorConfig +} + +// enableLeaderMigrationRKE1 adds the kubeControllerService to the cluster with settings to enable leader migration +// returns the updated management.Cluster +func enableLeaderMigrationRKE1(rke1Cluster *management.Cluster) *management.Cluster { + rke1ClusterUpdates := rke1Cluster + rke1ClusterUpdates.RancherKubernetesEngineConfig.Services.KubeController = &management.KubeControllerService{ + ExtraArgs: map[string]string{ + enableLeaderMigration: "true", + }, + } + return rke1Cluster +} + +// rke1AWSCloudProviderMigration is a helper function to migrate from aws in-tree to out-of-tree on rke1 clusters +func rke1AWSCloudProviderMigration(t *testing.T, client *rancher.Client, clusterName string) { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + + rke1Cluster, err := client.Management.Cluster.ByID(clusterID) + require.NoError(t, err) + + clusterName = rke1Cluster.ID + + _, steveClusterObject, err := clusters.GetProvisioningClusterByName(client, clusterName, fleetNamespace) + require.NoError(t, err) + + lbServiceResponse := permutations.CreateCloudProviderWorkloadAndServicesLB(t, client, steveClusterObject) + + status := &provv1.ClusterStatus{} + require.NotNil(t, steveClusterObject) + err = steveV1.ConvertToK8sType(steveClusterObject.Status, status) + require.NoError(t, err) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponse, status.ClusterName) + + spec := &provv1.ClusterSpec{} + require.NotNil(t, steveClusterObject) + err = steveV1.ConvertToK8sType(steveClusterObject.Spec, spec) + require.NoError(t, err) + + newRKE1Cluster := rke1Cluster + + logrus.Info("Enabling leader migration on the cluster.") + + newRKE1Cluster = enableLeaderMigrationRKE1(newRKE1Cluster) + rke1Cluster, err = client.Management.Cluster.Update(rke1Cluster, newRKE1Cluster) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, status.ClusterName) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, status.ClusterName) + require.Empty(t, podErrors) + + logrus.Info("Cordoning all control plane nodes in the cluster.") + + err = runKubectlCommand( + client, "kubectl cordon -l \"node-role.kubernetes.io/controlplane=true\"", status.ClusterName) + require.NoError(t, err) + + logrus.Info("Upgrading the cluster to preform in-tree to out-of-tree migration.") + + clusterMeta, err := clusters.NewClusterMeta(client, status.ClusterName) + require.NoError(t, err) + + err = permutations.CreateAndInstallAWSExternalCharts(client, clusterMeta, true) + require.NoError(t, err) + + newRKE1Cluster = rke1Cluster + trueBool := true + newCloudProvider := management.CloudProvider{ + UseInstanceMetadataHostname: &trueBool, + Name: "external-aws", + } + + newRKE1Cluster.RancherKubernetesEngineConfig.CloudProvider = &newCloudProvider + + _, err = client.Management.Cluster.Update(rke1Cluster, newRKE1Cluster) + require.NoError(t, err) + + podErrors = pods.StatusPods(client, status.ClusterName) + require.Empty(t, podErrors) + + err = clusters.WaitClusterToBeUpgraded(client, status.ClusterName) + require.NoError(t, err) + + podErrors = pods.StatusPods(client, status.ClusterName) + require.Empty(t, podErrors) + + // rke1 clusters go have a false positive during the upgrade, running it 2x adresses this issue + err = clusters.WaitClusterToBeUpgraded(client, status.ClusterName) + require.NoError(t, err) + _, steveClusterObject, err = clusters.GetProvisioningClusterByName(client, clusterName, fleetNamespace) + require.NoError(t, err) + + logrus.Info("Verifying in-tree LB persists.") + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponse, status.ClusterName) + + lbServiceResponseOOT := permutations.CreateCloudProviderWorkloadAndServicesLB(t, client, steveClusterObject) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponseOOT, status.ClusterName) +} + +// rke2AWSCloudProviderMigration is a helper function to migrate from aws in-tree to out-of-tree on rke2 clusters +func rke2AWSCloudProviderMigration(t *testing.T, client *rancher.Client, steveClusterObject *steveV1.SteveAPIObject) { + lbServiceResponse := permutations.CreateCloudProviderWorkloadAndServicesLB(t, client, steveClusterObject) + + status := &provv1.ClusterStatus{} + require.NotNil(t, steveClusterObject) + err := steveV1.ConvertToK8sType(steveClusterObject.Status, status) + require.NoError(t, err) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponse, status.ClusterName) + + spec := &provv1.ClusterSpec{} + require.NotNil(t, steveClusterObject) + err = steveV1.ConvertToK8sType(steveClusterObject.Spec, spec) + require.NoError(t, err) + + newSteveCluster := steveClusterObject + + logrus.Info("Enabling leader migration on the cluster.") + + spec.RKEConfig.MachineSelectorConfig = enableLeaderMigrationInMachineSelector(spec.RKEConfig.MachineSelectorConfig) + newSteveCluster.Spec = spec + + steveClusterObject, err = client.Steve.SteveType( + clusters.ProvisioningSteveResourceType).Update(steveClusterObject, newSteveCluster) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, status.ClusterName) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, status.ClusterName) + require.Empty(t, podErrors) + + logrus.Info("Cordoning all control plane nodes in the cluster.") + + err = runKubectlCommand( + client, "kubectl cordon -l \"node-role.kubernetes.io/control-plane=true\"", status.ClusterName) + require.NoError(t, err) + + logrus.Info("Upgrading the cluster to preform in-tree to out-of-tree migration.") + + require.NotNil(t, steveClusterObject) + err = steveV1.ConvertToK8sType(steveClusterObject.Spec, spec) + require.NoError(t, err) + + outOfTreeSystemConfig := clusters.OutOfTreeSystemConfig("aws") + spec.RKEConfig.MachineSelectorConfig = enableLeaderMigrationInMachineSelector(outOfTreeSystemConfig) + + byteYaml, err := os.ReadFile(outOfTreeAWSYamlPath) + require.NoError(t, err) + spec.RKEConfig.AdditionalManifest = string(byteYaml) + + logrus.Info("Enabling out-of-tree provider on the cluster") + + _, steveClusterObject, err = clusters.GetProvisioningClusterByName(client, steveClusterObject.Name, fleetNamespace) + require.NoError(t, err) + + newSteveCluster = steveClusterObject + newSteveCluster.Spec = spec + + steveClusterObject, err = client.Steve.SteveType( + clusters.ProvisioningSteveResourceType).Update(steveClusterObject, newSteveCluster) + require.NoError(t, err) + + err = clusters.WaitClusterToBeUpgraded(client, status.ClusterName) + require.NoError(t, err) + + logrus.Info("Uncordoning rke2 after an upgrade doesn't happen automatically - manually uncording control-plane nodes.") + + err = runKubectlCommand( + client, "kubectl uncordon -l \"node-role.kubernetes.io/control-plane=true\"", status.ClusterName) + require.NoError(t, err) + + podErrors = pods.StatusPods(client, status.ClusterName) + require.Empty(t, podErrors) + + logrus.Info("Verifying in-tree LB persists.") + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponse, status.ClusterName) + + lbServiceResponseOOT := permutations.CreateCloudProviderWorkloadAndServicesLB(t, client, steveClusterObject) + + services.VerifyAWSLoadBalancer(t, client, lbServiceResponseOOT, status.ClusterName) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration_test.go new file mode 100644 index 0000000..281bac3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_aws_migration_test.go @@ -0,0 +1,55 @@ +//go:build validation || extended + +package upgrade + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +const ( + providerLabel = "provider.cattle.io" +) + +type MigrateCloudProviderSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clusters []string +} + +func (u *MigrateCloudProviderSuite) TearDownSuite() { + u.session.Cleanup() +} + +func (u *MigrateCloudProviderSuite) SetupSuite() { + testSession := session.NewSession() + u.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(u.T(), err) + + u.client = client +} + +func (u *MigrateCloudProviderSuite) TestAWS() { + _, steveClusterObject, err := clusters.GetProvisioningClusterByName(u.client, u.client.RancherConfig.ClusterName, fleetNamespace) + if err != nil { + u.Run("RKE1", func() { + rke1AWSCloudProviderMigration(u.T(), u.client, u.client.RancherConfig.ClusterName) + }) + } else { + u.Run("RKE2", func() { + rke2AWSCloudProviderMigration(u.T(), u.client, steveClusterObject) + }) + } +} + +func TestCloudProviderMigrationTestSuite(t *testing.T) { + suite.Run(t, new(MigrateCloudProviderSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version.go new file mode 100644 index 0000000..3334451 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version.go @@ -0,0 +1,35 @@ +package upgrade + +import ( + "testing" + + "github.com/rancher/rancher/tests/v2/validation/provisioning/permutations" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/provisioninginput" + "github.com/rancher/shepherd/extensions/workloads/pods" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" +) + +func upgradeVsphereCloudProviderCharts(t *testing.T, client *rancher.Client, clusterName string) { + logrus.Info("Starting upgrade test...") + err := charts.UpgradeVsphereOutOfTreeCharts(client, catalog.RancherChartRepo, clusterName) + require.NoError(t, err) + + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + + podErrors := pods.StatusPods(client, clusterID) + require.Empty(t, podErrors) + + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + require.NoError(t, err) + + clusterObject, err := adminClient.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(provisioninginput.Namespace + "/" + clusterID) + require.NoError(t, err) + + permutations.CreatePVCWorkload(t, client, clusterObject) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version_test.go new file mode 100644 index 0000000..d72fe70 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/cloud_provider_version_test.go @@ -0,0 +1,47 @@ +//go:build validation || extended + +package upgrade + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type UpgradeCloudProviderSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clusters []string +} + +func (u *UpgradeCloudProviderSuite) TearDownSuite() { + u.session.Cleanup() +} + +func (u *UpgradeCloudProviderSuite) SetupSuite() { + testSession := session.NewSession() + u.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(u.T(), err) + + u.client = client +} + +func (u *UpgradeCloudProviderSuite) TestVsphere() { + _, _, err := clusters.GetProvisioningClusterByName(u.client, u.client.RancherConfig.ClusterName, fleetNamespace) + if err != nil { + u.Run("RKE1", func() { + upgradeVsphereCloudProviderCharts(u.T(), u.client, u.client.RancherConfig.ClusterName) + }) + } +} + +func TestCloudProviderVersionUpgradeSuite(t *testing.T) { + suite.Run(t, new(UpgradeCloudProviderSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes.go new file mode 100644 index 0000000..960f796 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes.go @@ -0,0 +1,214 @@ +package upgrade + +import ( + "context" + "strings" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + apisV1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + provv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + steveV1 "github.com/rancher/shepherd/clients/rancher/v1" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/clusters/bundledclusters" + "github.com/rancher/shepherd/extensions/defaults" + kcluster "github.com/rancher/shepherd/extensions/kubeapi/cluster" + "github.com/rancher/shepherd/extensions/provisioning" + "github.com/rancher/shepherd/extensions/upgradeinput" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + local = "local" + namespace = "fleet-default" + provider = "provider.cattle.io" + rke = "rke" + rke2 = "rke2" + controllersVersion = "management.cattle.io/current-cluster-controllers-version" +) + +// upgradeLocalCluster is a function to upgrade a local cluster. +func upgradeLocalCluster(u *suite.Suite, testName string, client *rancher.Client, clusterName string, testConfig *clusters.ClusterConfig, cluster upgradeinput.Cluster) { + clusterObject, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(u.T(), err) + + clusterResp, err := client.Management.Cluster.ByID(clusterObject) + require.NoError(u.T(), err) + + if clusterResp.Labels[provider] == rke { + testConfig.KubernetesVersion = cluster.ProvisioningInput.RKE1KubernetesVersions[0] + testName += "Local cluster from " + clusterResp.Version.GitVersion + " to " + testConfig.KubernetesVersion + } else if clusterResp.Labels[provider] == rke2 { + testConfig.KubernetesVersion = cluster.ProvisioningInput.RKE2KubernetesVersions[0] + testName += "Local cluster from " + clusterResp.Version.GitVersion + " to " + testConfig.KubernetesVersion + } else { + testConfig.KubernetesVersion = cluster.ProvisioningInput.K3SKubernetesVersions[0] + testName += "Local cluster from " + clusterResp.Version.GitVersion + " to " + testConfig.KubernetesVersion + } + + u.Run(testName, func() { + createPreUpgradeWorkloads(u.T(), client, clusterName, cluster.FeaturesToTest) + + clusterMeta, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(u.T(), err) + + initCluster, err := bundledclusters.NewWithClusterMeta(clusterMeta) + require.NoError(u.T(), err) + + initClusterResp, err := initCluster.Get(client) + require.NoError(u.T(), err) + + logrus.Infof("Upgrading local cluster to: %s", testConfig.KubernetesVersion) + updatedCluster, err := initClusterResp.UpdateKubernetesVersion(client, &testConfig.KubernetesVersion) + require.NoError(u.T(), err) + + err = waitForLocalClusterUpgrade(client, clusterName) + require.NoError(u.T(), err) + + upgradedCluster, err := client.Management.Cluster.ByID(updatedCluster.V3.ID) + require.NoError(u.T(), err) + require.Equal(u.T(), testConfig.KubernetesVersion, upgradedCluster.Version.GitVersion) + + logrus.Infof("Local cluster has been upgraded to: %s", upgradedCluster.Version.GitVersion) + + createPostUpgradeWorkloads(u.T(), client, clusterName, cluster.FeaturesToTest) + }) +} + +// upgradeDownstreamCluster is a function to upgrade a downstream cluster. +func upgradeDownstreamCluster(u *suite.Suite, testName string, client *rancher.Client, clusterName string, testConfig *clusters.ClusterConfig, cluster upgradeinput.Cluster) { + var isRKE1 = false + + clusterObject, _, _ := clusters.GetProvisioningClusterByName(client, clusterName, namespace) + if clusterObject == nil { + isRKE1 = true + + clusterObject, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(u.T(), err) + + clusterResp, err := client.Management.Cluster.ByID(clusterObject) + require.NoError(u.T(), err) + + testConfig.KubernetesVersion = cluster.ProvisioningInput.RKE1KubernetesVersions[0] + testName += "RKE1 cluster from " + clusterResp.RancherKubernetesEngineConfig.Version + " to " + testConfig.KubernetesVersion + } else { + clusterID, err := clusters.GetV1ProvisioningClusterByName(client, clusterName) + require.NoError(u.T(), err) + + clusterResp, err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterID) + require.NoError(u.T(), err) + + updatedCluster := new(apisV1.Cluster) + err = v1.ConvertToK8sType(clusterResp, &updatedCluster) + require.NoError(u.T(), err) + + if strings.Contains(updatedCluster.Spec.KubernetesVersion, "rke2") { + testConfig.KubernetesVersion = cluster.ProvisioningInput.RKE2KubernetesVersions[0] + testName += "RKE2 cluster from " + updatedCluster.Spec.KubernetesVersion + " to " + testConfig.KubernetesVersion + } else if strings.Contains(updatedCluster.Spec.KubernetesVersion, "k3s") { + testConfig.KubernetesVersion = cluster.ProvisioningInput.K3SKubernetesVersions[0] + testName += "K3S cluster from " + updatedCluster.Spec.KubernetesVersion + " to " + testConfig.KubernetesVersion + } + } + + u.Run(testName, func() { + createPreUpgradeWorkloads(u.T(), client, clusterName, cluster.FeaturesToTest) + + if isRKE1 { + upgradedCluster, err := upgradeRKE1Cluster(u.T(), client, cluster, testConfig) + require.NoError(u.T(), err) + + clusterResp, err := clusters.GetClusterIDByName(client, upgradedCluster.Name) + require.NoError(u.T(), err) + + upgradedRKE1Cluster, err := client.Management.Cluster.ByID(clusterResp) + require.NoError(u.T(), err) + + provisioning.VerifyRKE1Cluster(u.T(), client, testConfig, upgradedRKE1Cluster) + } else { + upgradedCluster, err := upgradeRKE2K3SCluster(u.T(), client, cluster, testConfig) + require.NoError(u.T(), err) + + provisioning.VerifyCluster(u.T(), client, testConfig, upgradedCluster) + } + + createPostUpgradeWorkloads(u.T(), client, clusterName, cluster.FeaturesToTest) + }) +} + +// upgradeRKE1Cluster is a function to upgrade a downstream RKE1 cluster. +func upgradeRKE1Cluster(t *testing.T, client *rancher.Client, cluster upgradeinput.Cluster, clustersConfig *clusters.ClusterConfig) (*management.Cluster, error) { + clusterObj, err := clusters.GetClusterIDByName(client, cluster.Name) + require.NoError(t, err) + + clusterResp, err := client.Management.Cluster.ByID(clusterObj) + require.NoError(t, err) + + updatedCluster := clusters.UpdateRKE1ClusterConfig(clusterResp.Name, client, clustersConfig) + + updatedClusterResp, err := clusters.UpdateRKE1Cluster(client, clusterResp, updatedCluster) + require.NoError(t, err) + + upgradedCluster, err := client.Management.Cluster.ByID(updatedClusterResp.ID) + require.NoError(t, err) + require.Equal(t, clustersConfig.KubernetesVersion, upgradedCluster.RancherKubernetesEngineConfig.Version) + + logrus.Infof("Cluster has been upgraded to: %s", upgradedCluster.RancherKubernetesEngineConfig.Version) + + return updatedClusterResp, nil +} + +// upgradeRKE2K3SCluster is a function to upgrade a downstream RKE2 or K3S cluster. +func upgradeRKE2K3SCluster(t *testing.T, client *rancher.Client, cluster upgradeinput.Cluster, clustersConfig *clusters.ClusterConfig) (*v1.SteveAPIObject, error) { + clusterObj, err := clusters.GetV1ProvisioningClusterByName(client, cluster.Name) + require.NoError(t, err) + + clusterResp, err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(clusterObj) + require.NoError(t, err) + + updatedCluster := clusters.UpdateK3SRKE2ClusterConfig(clusterResp, clustersConfig) + + updatedClusterObj := new(apisV1.Cluster) + err = v1.ConvertToK8sType(updatedCluster, &updatedClusterObj) + require.NoError(t, err) + + updatedClusterResp, err := clusters.UpdateK3SRKE2Cluster(client, updatedCluster, updatedClusterObj) + require.NoError(t, err) + + updatedClusterSpec := &provv1.ClusterSpec{} + err = steveV1.ConvertToK8sType(updatedClusterResp.Spec, updatedClusterSpec) + require.NoError(t, err) + require.Equal(t, clustersConfig.KubernetesVersion, updatedClusterSpec.KubernetesVersion) + + logrus.Infof("Cluster has been upgraded to: %s", updatedClusterSpec.KubernetesVersion) + + return updatedClusterResp, nil +} + +// waitForLocalClusterUpgrade is a function to wait for the local cluster to upgrade. +func waitForLocalClusterUpgrade(client *rancher.Client, clusterName string) error { + return kwait.PollUntilContextTimeout(context.TODO(), 1*time.Second, defaults.ThirtyMinuteTimeout, true, func(ctx context.Context) (done bool, err error) { + isConnected, err := client.IsConnected() + if err != nil { + return false, nil + } + + if isConnected { + ready, err := kcluster.IsClusterActive(client, clusterName) + if err != nil { + return false, nil + } + + return ready, nil + } + + return false, nil + }) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes_test.go new file mode 100644 index 0000000..29764ea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/kubernetes_test.go @@ -0,0 +1,63 @@ +package upgrade + +import ( + "testing" + + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/upgradeinput" + "github.com/rancher/shepherd/pkg/session" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type UpgradeKubernetesTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clusters []upgradeinput.Cluster +} + +func (u *UpgradeKubernetesTestSuite) TearDownSuite() { + u.session.Cleanup() +} + +func (u *UpgradeKubernetesTestSuite) SetupSuite() { + testSession := session.NewSession() + u.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(u.T(), err) + + u.client = client + + clusters, err := upgradeinput.LoadUpgradeKubernetesConfig(client) + require.NoError(u.T(), err) + + u.clusters = clusters +} + +func (u *UpgradeKubernetesTestSuite) TestUpgradeKubernetes() { + tests := []struct { + name string + client *rancher.Client + }{ + {"Upgrading ", u.client}, + } + + for _, tt := range tests { + for _, cluster := range u.clusters { + testConfig := clusters.ConvertConfigToClusterConfig(&cluster.ProvisioningInput) + + if cluster.Name == local { + upgradeLocalCluster(&u.Suite, tt.name, tt.client, cluster.Name, testConfig, cluster) + } else { + upgradeDownstreamCluster(&u.Suite, tt.name, tt.client, cluster.Name, testConfig, cluster) + } + } + } +} + +func TestKubernetesUpgradeTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeKubernetesTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/workload.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/workload.go new file mode 100644 index 0000000..315b7ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/upgrade/workload.go @@ -0,0 +1,648 @@ +package upgrade + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/rancher/norman/types" + "github.com/rancher/rancher/pkg/api/scheme" + "github.com/rancher/shepherd/clients/rancher" + "github.com/rancher/shepherd/clients/rancher/catalog" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/charts" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/ingresses" + kubeingress "github.com/rancher/shepherd/extensions/kubeapi/ingresses" + "github.com/rancher/shepherd/extensions/namespaces" + "github.com/rancher/shepherd/extensions/projects" + "github.com/rancher/shepherd/extensions/secrets" + "github.com/rancher/shepherd/extensions/services" + "github.com/rancher/shepherd/extensions/upgradeinput" + "github.com/rancher/shepherd/extensions/workloads" + "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/wait" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + kubewait "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" +) + +type resourceNames struct { + core map[string]string + coreWithSuffix map[string]string + random map[string]string +} + +const ( + containerImage = "ranchertest/mytestcontainer" + containerName = "test1" + daemonsetName = "daemonsetName" + daemonsetNameForEnvironmentVariableSecret = "daemonsetNameForEnvironmentVariableSecret" + daemonsetNameForIngress = "daemonsetNameForIngress" + daemonsetNameForVolumeSecret = "daemonsetNameForVolumeSecret" + deploymentName = "deploymentName" + deploymentNameForIngress = "deploymentNameForIngress" + deploymentNameForEnvironmentVariableSecret = "deploymentNameForEnvironmentVariableSecret" + deploymentNameForVolumeSecret = "deploymentNameForVolumeSecret" + ingressHostName = "sslip.io" + ingressNameForDaemonset = "ingressNameForDaemonset" + ingressNameForDeployment = "ingressNameForDeployment" + namespaceName = "namespaceName" + projectName = "projectName" + secretAsVolumeName = "secret-as-volume" + secretName = "secretName" + serviceNameForDaemonset = "serviceNameForDaemonset" + serviceNameForDeployment = "serviceNameForDeployment" + servicePortName = "port" + servicePortNumber = 80 + volumeMountPath = "/root/usr/" +) + +// createPreUpgradeWorkloads creates workloads in the downstream cluster before the upgrade. +func createPreUpgradeWorkloads(t *testing.T, client *rancher.Client, clusterName string, featuresToTest upgradeinput.Features) { + isCattleLabeled := true + names := newNames() + + project, err := getProject(client, clusterName, names.core[projectName]) + require.NoError(t, err) + + steveClient, err := client.Steve.ProxyDownstream(project.ClusterID) + require.NoError(t, err) + + logrus.Infof("Creating namespace: %v", names.random[namespaceName]) + namespace, err := namespaces.CreateNamespace(client, names.random[namespaceName], "{}", map[string]string{}, map[string]string{}, project) + require.NoError(t, err) + assert.Equal(t, namespace.Name, names.random[namespaceName]) + + testContainerPodTemplate := newPodTemplateWithTestContainer() + + logrus.Infof("Creating deployment: %v", names.random[deploymentName]) + deploymentTemplate := workloads.NewDeploymentTemplate(names.random[deploymentName], namespace.Name, testContainerPodTemplate, isCattleLabeled, nil) + createdDeployment, err := steveClient.SteveType(workloads.DeploymentSteveType).Create(deploymentTemplate) + require.NoError(t, err) + assert.Equal(t, createdDeployment.Name, names.random[deploymentName]) + + logrus.Infof("Waiting for deployment %v to have expected number of available replicas...", names.random[deploymentName]) + err = charts.WatchAndWaitDeployments(client, project.ClusterID, namespace.Name, metav1.ListOptions{}) + require.NoError(t, err) + + logrus.Infof("Creating daemonset: %v", names.random[daemonsetName]) + daemonsetTemplate := workloads.NewDaemonSetTemplate(names.random[daemonsetName], namespace.Name, testContainerPodTemplate, isCattleLabeled, nil) + createdDaemonSet, err := steveClient.SteveType(workloads.DaemonsetSteveType).Create(daemonsetTemplate) + require.NoError(t, err) + assert.Equal(t, createdDaemonSet.Name, names.random[daemonsetName]) + + logrus.Infof("Waiting for daemonset %v to have the expected number of available replicas...", names.random[daemonsetName]) + err = charts.WatchAndWaitDaemonSets(client, project.ClusterID, namespace.Name, metav1.ListOptions{}) + require.NoError(t, err) + + logrus.Infof("Validating daemonset %v available replicas number are equal to the worker nodes...", names.random[daemonsetName]) + validateDaemonset(t, client, project.ClusterID, namespace.Name, names.random[daemonsetName]) + + secretTemplate := secrets.NewSecretTemplate(names.random[secretName], namespace.Name, map[string][]byte{"test": []byte("test")}, corev1.SecretTypeOpaque) + + logrus.Infof("Creating secret: %v", names.random[secretName]) + createdSecret, err := steveClient.SteveType(secrets.SecretSteveType).Create(secretTemplate) + require.NoError(t, err) + assert.Equal(t, createdSecret.Name, names.random[secretName]) + + podTemplateWithSecretVolume := newPodTemplateWithSecretVolume(names.random[secretName]) + + logrus.Infof("Creating deployment %v with the test container and secret as volume...", names.random[deploymentNameForVolumeSecret]) + deploymentWithSecretTemplate := workloads.NewDeploymentTemplate(names.random[deploymentNameForVolumeSecret], namespace.Name, podTemplateWithSecretVolume, isCattleLabeled, nil) + createdDeploymentWithSecretVolume, err := steveClient.SteveType(workloads.DeploymentSteveType).Create(deploymentWithSecretTemplate) + require.NoError(t, err) + assert.Equal(t, createdDeploymentWithSecretVolume.Name, names.random[deploymentNameForVolumeSecret]) + + logrus.Infof("Creating daemonset %v with the test container and secret as volume...", names.random[daemonsetNameForVolumeSecret]) + daemonsetWithSecretTemplate := workloads.NewDaemonSetTemplate(names.random[daemonsetNameForVolumeSecret], namespace.Name, podTemplateWithSecretVolume, isCattleLabeled, nil) + createdDaemonSetWithSecretVolume, err := steveClient.SteveType(workloads.DaemonsetSteveType).Create(daemonsetWithSecretTemplate) + require.NoError(t, err) + assert.Equal(t, createdDaemonSetWithSecretVolume.Name, names.random[daemonsetNameForVolumeSecret]) + + logrus.Infof("Waiting for daemonset %v to have the expected number of available replicas", names.random[daemonsetNameForVolumeSecret]) + err = charts.WatchAndWaitDaemonSets(client, project.ClusterID, namespace.Name, metav1.ListOptions{}) + require.NoError(t, err) + + logrus.Infof("Validating daemonset %v available replicas number are equal to the worker nodes...", names.random[daemonsetNameForVolumeSecret]) + validateDaemonset(t, client, project.ClusterID, namespace.Name, names.random[daemonsetNameForVolumeSecret]) + + podTemplateWithSecretEnvironmentVariable := newPodTemplateWithSecretEnvironmentVariable(names.random[secretName]) + + logrus.Infof("Creating deployment %v with the test container and secret as environment variable...", names.random[deploymentNameForEnvironmentVariableSecret]) + deploymentEnvironmentWithSecretTemplate := workloads.NewDeploymentTemplate(names.random[deploymentNameForEnvironmentVariableSecret], namespace.Name, podTemplateWithSecretEnvironmentVariable, isCattleLabeled, nil) + createdDeploymentEnvironmentVariableSecret, err := steveClient.SteveType(workloads.DeploymentSteveType).Create(deploymentEnvironmentWithSecretTemplate) + require.NoError(t, err) + assert.Equal(t, createdDeploymentEnvironmentVariableSecret.Name, names.random[deploymentNameForEnvironmentVariableSecret]) + + logrus.Infof("Creating daemonset %v with the test container and secret as environment variable...", names.random[daemonsetNameForEnvironmentVariableSecret]) + daemonSetEnvironmentWithSecretTemplate := workloads.NewDaemonSetTemplate(names.random[daemonsetNameForEnvironmentVariableSecret], namespace.Name, podTemplateWithSecretEnvironmentVariable, isCattleLabeled, nil) + createdDaemonSetEnvironmentVariableSecret, err := steveClient.SteveType(workloads.DaemonsetSteveType).Create(daemonSetEnvironmentWithSecretTemplate) + require.NoError(t, err) + assert.Equal(t, createdDaemonSetEnvironmentVariableSecret.Name, names.random[daemonsetNameForEnvironmentVariableSecret]) + + logrus.Infof("Waiting daemonset %v to have expected number of available replicas", names.random[daemonsetNameForEnvironmentVariableSecret]) + err = charts.WatchAndWaitDaemonSets(client, project.ClusterID, namespace.Name, metav1.ListOptions{}) + require.NoError(t, err) + + logrus.Infof("Validating daemonset %v available replicas number is equal to worker nodes...", names.random[daemonsetNameForEnvironmentVariableSecret]) + validateDaemonset(t, client, project.ClusterID, namespace.Name, names.random[daemonsetNameForEnvironmentVariableSecret]) + + if *featuresToTest.Ingress { + logrus.Infof("Creating deployment %v with the test container for ingress...", names.random[deploymentNameForIngress]) + deploymentForIngressTemplate := workloads.NewDeploymentTemplate(names.random[deploymentNameForIngress], namespace.Name, testContainerPodTemplate, isCattleLabeled, nil) + createdDeploymentForIngress, err := steveClient.SteveType(workloads.DeploymentSteveType).Create(deploymentForIngressTemplate) + require.NoError(t, err) + assert.Equal(t, createdDeploymentForIngress.Name, names.random[deploymentNameForIngress]) + + deploymentForIngressSpec := &appv1.DeploymentSpec{} + err = v1.ConvertToK8sType(createdDeploymentForIngress.Spec, deploymentForIngressSpec) + require.NoError(t, err) + + logrus.Infof("Creating service %v linked to the deployment...", names.random[serviceNameForDeployment]) + serviceTemplateForDeployment := newServiceTemplate(names.random[serviceNameForDeployment], namespace.Name, deploymentForIngressSpec.Template.Labels) + createdServiceForDeployment, err := steveClient.SteveType(services.ServiceSteveType).Create(serviceTemplateForDeployment) + require.NoError(t, err) + assert.Equal(t, createdServiceForDeployment.Name, names.random[serviceNameForDeployment]) + + ingressTemplateForDeployment := newIngressTemplate(names.random[ingressNameForDeployment], namespace.Name, names.random[serviceNameForDeployment]) + + logrus.Infof("Creating ingress %v linked to the service %v", names.random[ingressNameForDeployment], names.random[serviceNameForDeployment]) + createdIngressForDeployment, err := steveClient.SteveType(ingresses.IngressSteveType).Create(ingressTemplateForDeployment) + require.NoError(t, err) + assert.Equal(t, createdIngressForDeployment.Name, names.random[ingressNameForDeployment]) + + logrus.Infof("Waiting for ingress %v hostname to be ready...", names.random[ingressNameForDeployment]) + err = waitUntilIngressHostnameUpdates(client, project.ClusterID, namespace.Name, names.random[ingressNameForDeployment]) + require.NoError(t, err) + + logrus.Infof("Checking if ingress %v is accessible...", names.random[ingressNameForDeployment]) + ingressForDeploymentID := getSteveID(namespace.Name, names.random[ingressNameForDeployment]) + ingressForDeploymentResp, err := steveClient.SteveType(ingresses.IngressSteveType).ByID(ingressForDeploymentID) + require.NoError(t, err) + + ingressForDeploymentSpec := &networkingv1.IngressSpec{} + err = v1.ConvertToK8sType(ingressForDeploymentResp.Spec, ingressForDeploymentSpec) + require.NoError(t, err) + + isIngressForDeploymentAccessible, err := waitUntilIngressIsAccessible(client, ingressForDeploymentSpec.Rules[0].Host) + require.NoError(t, err) + assert.True(t, isIngressForDeploymentAccessible) + + logrus.Infof("Creating daemonset %v with the test container for ingress...", names.random[daemonsetNameForIngress]) + daemonSetForIngressTemplate := workloads.NewDaemonSetTemplate(names.random[daemonsetNameForIngress], namespace.Name, testContainerPodTemplate, isCattleLabeled, nil) + createdDaemonSetForIngress, err := steveClient.SteveType(workloads.DaemonsetSteveType).Create(daemonSetForIngressTemplate) + require.NoError(t, err) + assert.Equal(t, createdDaemonSetForIngress.Name, names.random[daemonsetNameForIngress]) + + daemonSetForIngressSpec := &appv1.DaemonSetSpec{} + err = v1.ConvertToK8sType(createdDaemonSetForIngress.Spec, daemonSetForIngressSpec) + require.NoError(t, err) + + serviceTemplateForDaemonset := newServiceTemplate(names.random[serviceNameForDaemonset], namespace.Name, daemonSetForIngressSpec.Template.Labels) + + logrus.Infof("Creating service %v linked to the daemonset...", names.random[serviceNameForDaemonset]) + createdServiceForDaemonset, err := steveClient.SteveType(services.ServiceSteveType).Create(serviceTemplateForDaemonset) + require.NoError(t, err) + assert.Equal(t, createdServiceForDaemonset.Name, names.random[serviceNameForDaemonset]) + + ingressTemplateForDaemonset := newIngressTemplate(names.random[ingressNameForDaemonset], namespace.Name, names.random[serviceNameForDaemonset]) + + logrus.Infof("Creating ingress %v linked to the service...", names.random[ingressNameForDaemonset]) + createdIngressForDaemonset, err := steveClient.SteveType(ingresses.IngressSteveType).Create(ingressTemplateForDaemonset) + require.NoError(t, err) + assert.Equal(t, createdIngressForDaemonset.Name, names.random[ingressNameForDaemonset]) + + logrus.Infof("Waiting for ingress %v hostname to be ready...", names.random[ingressNameForDaemonset]) + err = waitUntilIngressHostnameUpdates(client, project.ClusterID, namespace.Name, names.random[ingressNameForDaemonset]) + require.NoError(t, err) + + logrus.Infof("Checking if ingress %v is accessible", names.random[ingressNameForDaemonset]) + ingressForDaemonsetID := getSteveID(namespace.Name, names.random[ingressNameForDaemonset]) + ingressForDaemonsetResp, err := steveClient.SteveType(ingresses.IngressSteveType).ByID(ingressForDaemonsetID) + require.NoError(t, err) + ingressForDaemonsetSpec := &networkingv1.IngressSpec{} + err = v1.ConvertToK8sType(ingressForDaemonsetResp.Spec, ingressForDaemonsetSpec) + require.NoError(t, err) + + isIngressForDaemonsetAccessible, err := waitUntilIngressIsAccessible(client, ingressForDaemonsetSpec.Rules[0].Host) + require.NoError(t, err) + assert.True(t, isIngressForDaemonsetAccessible) + } + + if *featuresToTest.Chart { + logrus.Infof("Checking if the logging chart is installed in cluster: %v", project.ClusterID) + loggingChart, err := charts.GetChartStatus(client, project.ClusterID, charts.RancherLoggingNamespace, charts.RancherLoggingName) + require.NoError(t, err) + + if !loggingChart.IsAlreadyInstalled { + cluster, err := clusters.NewClusterMeta(client, clusterName) + require.NoError(t, err) + latestLoggingVersion, err := client.Catalog.GetLatestChartVersion(charts.RancherLoggingName, catalog.RancherChartRepo) + require.NoError(t, err) + + loggingChartInstallOption := &charts.InstallOptions{ + Cluster: cluster, + Version: latestLoggingVersion, + ProjectID: project.ID, + } + + loggingChartFeatureOption := &charts.RancherLoggingOpts{ + AdditionalLoggingSources: true, + } + + logrus.Infof("Installing logging chart's latest version: %v", latestLoggingVersion) + err = charts.InstallRancherLoggingChart(client, loggingChartInstallOption, loggingChartFeatureOption) + require.NoError(t, err) + + logrus.Infof("Successfully installed logging chart in cluster: %v", project.ClusterID) + } else { + logrus.Infof("Logging chart is already installed in cluster: %v", project.ClusterID) + } + } +} + +// createPostUpgradeWorkloads creates workloads in the downstream cluster after the upgrade. +func createPostUpgradeWorkloads(t *testing.T, client *rancher.Client, clusterName string, featuresToTest upgradeinput.Features) { + names := newNames() + + project, err := getProject(client, clusterName, names.core[projectName]) + require.NoError(t, err) + + steveClient, err := client.Steve.ProxyDownstream(project.ClusterID) + require.NoError(t, err) + + namespaceList, err := steveClient.SteveType(namespaces.NamespaceSteveType).List(nil) + require.NoError(t, err) + doesNamespaceExist := containsItemWithPrefix(namespaceList.Names(), names.core[namespaceName]) + assert.True(t, doesNamespaceExist) + + if !doesNamespaceExist { + t.Skipf("Namespace with prefix %s doesn't exist", names.core[namespaceName]) + } + + logrus.Infof("Checking if the namespace %s does exist...", names.core[namespaceName]) + namespaceID := getItemWithPrefix(namespaceList.Names(), names.core[namespaceName]) + namespace, err := steveClient.SteveType(namespaces.NamespaceSteveType).ByID(namespaceID) + require.NoError(t, err) + + logrus.Infof("Checking deployments in namespace: %s", namespace.Name) + deploymentList, err := steveClient.SteveType(workloads.DeploymentSteveType).List(nil) + require.NoError(t, err) + deploymentNames := []string{ + names.coreWithSuffix[deploymentNameForVolumeSecret], + names.coreWithSuffix[deploymentNameForEnvironmentVariableSecret], + } + + for _, expectedDeploymentName := range deploymentNames { + doesContainDeployment := containsItemWithPrefix(deploymentList.Names(), expectedDeploymentName) + assert.Truef(t, doesContainDeployment, "Deployment with prefix %s doesn't exist", expectedDeploymentName) + } + + logrus.Infof("Checking daemonsets in namespace %s", namespace.Name) + daemonsetList, err := steveClient.SteveType(workloads.DaemonsetSteveType).List(nil) + require.NoError(t, err) + daemonsetNames := []string{ + names.coreWithSuffix[daemonsetName], + } + + for _, expectedDaemonsetName := range daemonsetNames { + doesContainDaemonset := containsItemWithPrefix(daemonsetList.Names(), expectedDaemonsetName) + assert.Truef(t, doesContainDaemonset, "Daemonset with prefix %s doesn't exist", expectedDaemonsetName) + } + + if *featuresToTest.Ingress { + logrus.Infof("Checking deployment for ingress in namespace %s", namespace.Name) + doesContainDeploymentForIngress := containsItemWithPrefix(deploymentList.Names(), names.coreWithSuffix[deploymentNameForIngress]) + assert.Truef(t, doesContainDeploymentForIngress, "Deployment with prefix %s doesn't exist", names.coreWithSuffix[deploymentNameForIngress]) + + logrus.Infof("Checking daemonset for ingress in namespace %s", namespace.Name) + doesContainDaemonsetForIngress := containsItemWithPrefix(daemonsetList.Names(), names.coreWithSuffix[daemonsetNameForIngress]) + assert.Truef(t, doesContainDaemonsetForIngress, "Daemonset with prefix %s doesn't exist", names.coreWithSuffix[daemonsetNameForIngress]) + + logrus.Infof("Checking ingresses in namespace %s", namespace.Name) + ingressList, err := steveClient.SteveType(ingresses.IngressSteveType).List(nil) + require.NoError(t, err) + ingressNames := []string{ + names.coreWithSuffix[ingressNameForDeployment], + names.coreWithSuffix[ingressNameForDaemonset], + } + + for _, expectedIngressName := range ingressNames { + doesContainIngress := containsItemWithPrefix(ingressList.Names(), expectedIngressName) + assert.Truef(t, doesContainIngress, "Ingress with prefix %s doesn't exist", expectedIngressName) + + if doesContainIngress { + ingressName := getItemWithPrefix(ingressList.Names(), expectedIngressName) + ingressID := getSteveID(namespace.Name, ingressName) + ingressResp, err := steveClient.SteveType(ingresses.IngressSteveType).ByID(ingressID) + require.NoError(t, err) + + ingressSpec := &networkingv1.IngressSpec{} + err = v1.ConvertToK8sType(ingressResp.Spec, ingressSpec) + require.NoError(t, err) + + logrus.Infof("Checking if the ingress %s is accessible", ingressResp.Name) + isIngressAcessible, err := waitUntilIngressIsAccessible(client, ingressSpec.Rules[0].Host) + require.NoError(t, err) + assert.True(t, isIngressAcessible) + } + } + } + + logrus.Infof("Checking the secret in namespace %s", namespace.Name) + secretList, err := steveClient.SteveType(secrets.SecretSteveType).List(nil) + require.NoError(t, err) + + doesContainSecret := containsItemWithPrefix(secretList.Names(), names.core[secretName]) + assert.Truef(t, doesContainSecret, "Secret with prefix %s doesn't exist", names.core[secretName]) + + if *featuresToTest.Chart { + logrus.Infof("Checking if the logging chart is installed...") + loggingChart, err := charts.GetChartStatus(client, project.ClusterID, charts.RancherLoggingNamespace, charts.RancherLoggingName) + require.NoError(t, err) + assert.True(t, loggingChart.IsAlreadyInstalled) + } +} + +func getSteveID(namespaceName, resourceName string) string { + return fmt.Sprintf(namespaceName + "/" + resourceName) +} + +func getProject(client *rancher.Client, clusterName, projectName string) (project *management.Project, err error) { + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + if err != nil { + return + } + + project, err = projects.GetProjectByName(client, clusterID, projectName) + if err != nil { + return + } + + if project == nil { + projectConfig := &management.Project{ + ClusterID: clusterID, + Name: projectName, + } + + project, err = client.Management.Project.Create(projectConfig) + if err != nil { + return nil, err + } + } + + return +} + +// newIngressTemplate is a private constructor that returns ingress spec for specific services +func newIngressTemplate(ingressName, namespaceName, serviceNameForBackend string) networkingv1.Ingress { + pathTypePrefix := networkingv1.PathTypeImplementationSpecific + paths := []networkingv1.HTTPIngressPath{ + { + Path: "/", + PathType: &pathTypePrefix, + Backend: networkingv1.IngressBackend{ + Service: &networkingv1.IngressServiceBackend{ + Name: serviceNameForBackend, + Port: networkingv1.ServiceBackendPort{ + Number: servicePortNumber, + }, + }, + }, + }, + } + + return ingresses.NewIngressTemplate(ingressName, namespaceName, ingressHostName, paths) +} + +// newServiceTemplate is a private constructor that returns service spec for specific workloads +func newServiceTemplate(serviceName, namespaceName string, selector map[string]string) corev1.Service { + serviceType := corev1.ServiceTypeNodePort + ports := []corev1.ServicePort{ + { + Name: servicePortName, + Port: servicePortNumber, + }, + } + + return services.NewServiceTemplate(serviceName, namespaceName, serviceType, ports, selector) +} + +// newTestContainerMinimal is a private constructor that returns container for minimal workload creations +func newTestContainerMinimal() corev1.Container { + pullPolicy := corev1.PullAlways + return workloads.NewContainer(containerName, containerImage, pullPolicy, nil, nil, nil, nil, nil) +} + +// newPodTemplateWithTestContainer is a private constructor that returns pod template spec for workload creations +func newPodTemplateWithTestContainer() corev1.PodTemplateSpec { + testContainer := newTestContainerMinimal() + containers := []corev1.Container{testContainer} + return workloads.NewPodTemplate(containers, nil, nil, nil) +} + +// newPodTemplateWithSecretVolume is a private constructor that returns pod template spec with volume option for workload creations +func newPodTemplateWithSecretVolume(secretName string) corev1.PodTemplateSpec { + testContainer := newTestContainerMinimal() + testContainer.VolumeMounts = []corev1.VolumeMount{{Name: secretAsVolumeName, MountPath: volumeMountPath}} + containers := []corev1.Container{testContainer} + volumes := []corev1.Volume{ + { + Name: secretAsVolumeName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: secretName, + }, + }, + }, + } + + return workloads.NewPodTemplate(containers, volumes, nil, nil) +} + +// newPodTemplateWithSecretEnvironmentVariable is a private constructor that returns pod template spec with envFrom option for workload creations +func newPodTemplateWithSecretEnvironmentVariable(secretName string) corev1.PodTemplateSpec { + pullPolicy := corev1.PullAlways + envFrom := []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, + }, + }, + } + container := workloads.NewContainer(containerName, containerImage, pullPolicy, nil, envFrom, nil, nil, nil) + containers := []corev1.Container{container} + + return workloads.NewPodTemplate(containers, nil, nil, nil) +} + +// waitUntilIngressIsAccessible waits until the ingress is accessible +func waitUntilIngressIsAccessible(client *rancher.Client, hostname string) (bool, error) { + err := kubewait.Poll(500*time.Millisecond, 2*time.Minute, func() (done bool, err error) { + isIngressAccessible, err := ingresses.IsIngressExternallyAccessible(client, hostname, "", false) + if err != nil { + return false, err + } + + return isIngressAccessible, nil + }) + + if err != nil && strings.Contains(err.Error(), kubewait.ErrWaitTimeout.Error()) { + return false, nil + } + + return true, nil +} + +// waitUntilIngressHostnameUpdates is a private function to wait until the ingress hostname updates +func waitUntilIngressHostnameUpdates(client *rancher.Client, clusterID, namespace, ingressName string) error { + timeout := int64(60 * 5) + adminClient, err := rancher.NewClient(client.RancherConfig.AdminToken, client.Session) + if err != nil { + return err + } + adminDynamicClient, err := adminClient.GetDownStreamClusterClient(clusterID) + if err != nil { + return err + } + adminIngressResource := adminDynamicClient.Resource(kubeingress.IngressesGroupVersionResource).Namespace(namespace) + + watchAppInterface, err := adminIngressResource.Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + ingressName, + TimeoutSeconds: &timeout, + }) + if err != nil { + return err + } + + return wait.WatchWait(watchAppInterface, func(event watch.Event) (ready bool, err error) { + ingressUnstructured := event.Object.(*unstructured.Unstructured) + ingress := &networkingv1.Ingress{} + + err = scheme.Scheme.Convert(ingressUnstructured, ingress, ingressUnstructured.GroupVersionKind()) + if err != nil { + return false, err + } + + if ingress.Spec.Rules[0].Host != ingressHostName { + return true, nil + } + return false, nil + }) +} + +// containsItemWithPrefix returns true if the given slice contains an item with the given prefix +func containsItemWithPrefix(slice []string, expected string) bool { + for _, s := range slice { + if checkPrefix(s, expected) { + return true + } + } + return false +} + +// getItemWithPrefix returns the item with the given prefix +func getItemWithPrefix(slice []string, expected string) string { + for _, s := range slice { + if checkPrefix(s, expected) { + return s + } + } + return "" +} + +// checkPrefix checks if the given string starts with the given prefix +func checkPrefix(name string, prefix string) bool { + return strings.HasPrefix(name, prefix) +} + +// validateDaemonset checks that the available number of daemonsets equals the number of workers in a downstream cluster or the number of nodes in the local cluster +func validateDaemonset(t *testing.T, client *rancher.Client, clusterID, namespaceName, daemonsetName string) { + t.Helper() + + listFilter := &types.ListOpts{ + Filters: map[string]interface{}{ + "clusterId": clusterID, + }, + } + + if clusterID != local { + listFilter.Filters["worker"] = true + } + + nodesCollection, err := client.Management.Node.List(listFilter) + require.NoError(t, err) + + steveClient, err := client.Steve.ProxyDownstream(clusterID) + require.NoError(t, err) + + daemonSetID := getSteveID(namespaceName, daemonsetName) + daemonsetResp, err := steveClient.SteveType(workloads.DaemonsetSteveType).ByID(daemonSetID) + require.NoError(t, err) + + daemonsetStatus := &appv1.DaemonSetStatus{} + err = v1.ConvertToK8sType(daemonsetResp.Status, daemonsetStatus) + require.NoError(t, err) + + assert.Equalf(t, int(daemonsetStatus.NumberAvailable), len(nodesCollection.Data), "Daemonset %v doesn't have the required ready", daemonsetName) +} + +// newNames returns a new resourceNames struct +// it creates a random names with random suffix for each resource by using core and coreWithSuffix names +func newNames() *resourceNames { + const ( + projectName = "upgrade-wl-project" + namespaceName = "namespace" + deploymentName = "deployment" + daemonsetName = "daemonset" + secretName = "secret" + serviceName = "service" + ingressName = "ingress" + defaultRandStringLength = 3 + ) + + names := &resourceNames{ + core: map[string]string{ + "projectName": projectName, + "namespaceName": namespaceName, + "deploymentName": deploymentName, + "daemonsetName": daemonsetName, + "secretName": secretName, + "serviceName": serviceName, + "ingressName": ingressName, + }, + coreWithSuffix: map[string]string{ + "deploymentNameForVolumeSecret": deploymentName + "-volume-secret", + "deploymentNameForEnvironmentVariableSecret": deploymentName + "-envar-secret", + "deploymentNameForIngress": deploymentName + "-ingress", + "daemonsetNameForIngress": daemonsetName + "-ingress", + "daemonsetNameForVolumeSecret": daemonsetName + "-volume-secret", + "daemonsetNameForEnvironmentVariableSecret": daemonsetName + "-envar-secret", + "serviceNameForDeployment": serviceName + "-deployment", + "serviceNameForDaemonset": serviceName + "-daemonset", + "ingressNameForDeployment": ingressName + "-deployment", + "ingressNameForDaemonset": ingressName + "-daemonset", + }, + } + + names.random = map[string]string{} + for k, v := range names.coreWithSuffix { + names.random[k] = v + "-" + namegenerator.RandStringLower(defaultRandStringLength) + } + for k, v := range names.core { + names.random[k] = v + "-" + namegenerator.RandStringLower(defaultRandStringLength) + } + + return names +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/v2prov/encryption_key_rotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/v2prov/encryption_key_rotation_test.go new file mode 100644 index 0000000..87084ac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/v2prov/encryption_key_rotation_test.go @@ -0,0 +1,231 @@ +//go:build (validation || infra.rke2k3s || cluster.any || stress) && !infra.any && !infra.aks && !infra.eks && !infra.gke && !infra.rke1 && !sanity && !extended + +package v2prov + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + apiv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/tests/integration/pkg/defaults" + "github.com/rancher/shepherd/clients/rancher" + v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/kubeapi" + "github.com/rancher/shepherd/extensions/kubeapi/secrets" + "github.com/rancher/shepherd/pkg/environmentflag" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + "github.com/rancher/shepherd/pkg/wait" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kwait "k8s.io/apimachinery/pkg/util/wait" +) + +type V2ProvEncryptionKeyRotationTestSuite struct { + suite.Suite + session *session.Session + client *rancher.Client + clusterName string +} + +const ( + namespace = "fleet-default" + totalSecrets = 10000 +) + +var phases = []rkev1.RotateEncryptionKeysPhase{ + rkev1.RotateEncryptionKeysPhasePrepare, + rkev1.RotateEncryptionKeysPhasePostPrepareRestart, + rkev1.RotateEncryptionKeysPhaseRotate, + rkev1.RotateEncryptionKeysPhasePostRotateRestart, + rkev1.RotateEncryptionKeysPhaseReencrypt, + rkev1.RotateEncryptionKeysPhasePostReencryptRestart, + rkev1.RotateEncryptionKeysPhaseDone, +} + +func (r *V2ProvEncryptionKeyRotationTestSuite) TearDownSuite() { + r.session.Cleanup() +} + +func (r *V2ProvEncryptionKeyRotationTestSuite) SetupSuite() { + testSession := session.NewSession() + r.session = testSession + + client, err := rancher.NewClient("", testSession) + require.NoError(r.T(), err) + + r.client = client + + r.clusterName = r.client.RancherConfig.ClusterName +} + +func setEncryptSecret(t *testing.T, client *rancher.Client, steveID string) { + t.Logf("Set secret encryption key for cluster %s", steveID) + + cluster, err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(steveID) + require.NoError(t, err) + + clusterSpec := &apiv1.ClusterSpec{} + err = v1.ConvertToK8sType(cluster.Spec, clusterSpec) + require.NoError(t, err) + + updatedCluster := *cluster + + secretEncryption := clusterSpec.RKEConfig.MachineGlobalConfig.Data["secrets-encryption"] + if secretEncryption == nil { + clusterSpec.RKEConfig.MachineGlobalConfig.Data["secrets-encryption"] = true + + updatedCluster.Spec = *clusterSpec + + cluster, err = client.Steve.SteveType(clusters.ProvisioningSteveResourceType).Update(cluster, updatedCluster) + require.NoError(t, err) + + err = clusters.WatchAndWaitForCluster(client, steveID) + require.NoError(t, err) + + t.Logf("Successfully set secret encryption key for %s", cluster.ObjectMeta.Name) + } +} + +func rotateEncryptionKeys(t *testing.T, client *rancher.Client, steveID string, generation int64, timeout time.Duration) { + t.Logf("Applying encryption key rotation generation %d for cluster %s", generation, steveID) + + kubeProvisioningClient, err := client.GetKubeAPIProvisioningClient() + require.NoError(t, err) + + cluster, err := client.Steve.SteveType(clusters.ProvisioningSteveResourceType).ByID(steveID) + require.NoError(t, err) + + clusterSpec := &apiv1.ClusterSpec{} + err = v1.ConvertToK8sType(cluster.Spec, clusterSpec) + require.NoError(t, err) + + updatedCluster := *cluster + + clusterSpec.RKEConfig.RotateEncryptionKeys = &rkev1.RotateEncryptionKeys{ + Generation: generation, + } + + updatedCluster.Spec = *clusterSpec + + cluster, err = client.Steve.SteveType(clusters.ProvisioningSteveResourceType).Update(cluster, updatedCluster) + require.NoError(t, err) + + for _, phase := range phases { + err = kwait.Poll(10*time.Second, timeout, isAtLeast(t, client, namespace, cluster.ObjectMeta.Name, phase)) + require.NoError(t, err) + } + + clusterWait, err := kubeProvisioningClient.Clusters(namespace).Watch(context.TODO(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + cluster.ObjectMeta.Name, + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + require.NoError(t, err) + + err = wait.WatchWait(clusterWait, clusters.IsProvisioningClusterReady) + require.NoError(t, err) + + t.Logf("Successfully completed encryption key rotation for %s", cluster.ObjectMeta.Name) +} + +func createSecretsForCluster(t *testing.T, client *rancher.Client, steveID string, scale int) { + t.Logf("Creating %d secrets in namespace default for encryption key rotation", scale) + + _, clusterName, found := strings.Cut(steveID, "/") + require.True(t, found) + + clusterID, err := clusters.GetClusterIDByName(client, clusterName) + require.NoError(t, err) + secretResource, err := kubeapi.ResourceForClient(client, clusterID, "default", secrets.SecretGroupVersionResource) + require.NoError(t, err) + + for i := 0; i < scale; i++ { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: fmt.Sprintf("encryption-key-rotation-test-%d-", i), + }, + Data: map[string][]byte{ + "key": []byte(namegen.RandStringLower(5)), + }, + } + _, err = secrets.CreateSecret(secretResource, secret) + require.NoError(t, err) + } +} + +func (r *V2ProvEncryptionKeyRotationTestSuite) TestEncryptionKeyRotation() { + subSession := r.session.NewSession() + defer subSession.Cleanup() + + id, err := clusters.GetV1ProvisioningClusterByName(r.client, r.clusterName) + require.NoError(r.T(), err) + + setEncryptSecret(r.T(), r.client, id) + + prefix := "encryption-key-rotation-" + r.Run(prefix+"new-cluster", func() { + rotateEncryptionKeys(r.T(), r.client, id, 1, 10*time.Minute) + }) + + if r.client.Flags.GetValue(environmentflag.Long) { + // create 10k secrets for stress test, takes ~30 minutes + createSecretsForCluster(r.T(), r.client, id, totalSecrets) + + r.Run(prefix+"stress-test", func() { + rotateEncryptionKeys(r.T(), r.client, id, 2, 1*time.Hour) // takes ~45 minutes for HA + }) + } +} + +func isAtLeast(t *testing.T, client *rancher.Client, namespace, name string, phase rkev1.RotateEncryptionKeysPhase) kwait.ConditionFunc { + return func() (ready bool, err error) { + kubeRKEClient, err := client.GetKubeAPIRKEClient() + if err != nil { + return false, err + } + + controlPlane, err := kubeRKEClient.RKEControlPlanes(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + return false, err + } + + if controlPlane.Status.RotateEncryptionKeysPhase == rkev1.RotateEncryptionKeysPhaseFailed { + t.Errorf("Encryption key rotation failed waiting to reach %s", phase) + return ready, fmt.Errorf("encryption key rotation failed") + } + + desiredPhase := -1 + currentPhase := -1 + + for i, v := range phases { + if v == phase { + desiredPhase = i + } + if v == controlPlane.Status.RotateEncryptionKeysPhase { + currentPhase = i + } + if desiredPhase != -1 && currentPhase != -1 { + break + } + } + + if currentPhase < desiredPhase { + return false, nil + } + + t.Logf("Encryption key rotation successfully entered %s", phase) + + return true, nil + } +} + +func TestEncryptionKeyRotation(t *testing.T) { + suite.Run(t, new(V2ProvEncryptionKeyRotationTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/workloads/workload_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/workloads/workload_test.go new file mode 100644 index 0000000..3bc60b7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2/validation/workloads/workload_test.go @@ -0,0 +1,111 @@ +package workloads + +import ( + "testing" + + projectsapi "github.com/rancher/rancher/tests/v2/actions/projects" + "github.com/rancher/rancher/tests/v2/actions/workloads/deamonset" + deployment "github.com/rancher/rancher/tests/v2/actions/workloads/deployment" + "github.com/rancher/rancher/tests/v2/actions/workloads/pods" + "github.com/rancher/shepherd/clients/rancher" + management "github.com/rancher/shepherd/clients/rancher/generated/management/v3" + "github.com/rancher/shepherd/extensions/clusters" + "github.com/rancher/shepherd/extensions/workloads" + namegen "github.com/rancher/shepherd/pkg/namegenerator" + "github.com/rancher/shepherd/pkg/session" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + corev1 "k8s.io/api/core/v1" +) + +type WorkloadTestSuite struct { + suite.Suite + client *rancher.Client + session *session.Session + cluster *management.Cluster +} + +func (w *WorkloadTestSuite) TearDownSuite() { + w.session.Cleanup() +} + +func (w *WorkloadTestSuite) SetupSuite() { + w.session = session.NewSession() + + client, err := rancher.NewClient("", w.session) + require.NoError(w.T(), err) + + w.client = client + + log.Info("Getting cluster name from the config file and append cluster details in connection") + clusterName := client.RancherConfig.ClusterName + require.NotEmptyf(w.T(), clusterName, "Cluster name to install should be set") + + clusterID, err := clusters.GetClusterIDByName(w.client, clusterName) + require.NoError(w.T(), err, "Error getting cluster ID") + + w.cluster, err = w.client.Management.Cluster.ByID(clusterID) + require.NoError(w.T(), err) +} + +func (w *WorkloadTestSuite) TestWorkloadDeployment() { + subSession := w.session.NewSession() + defer subSession.Cleanup() + + _, namespace, err := projectsapi.CreateProjectAndNamespace(w.client, w.cluster.ID) + require.NoError(w.T(), err) + + _, err = deployment.CreateDeployment(w.client, w.cluster.ID, namespace.Name, 1, "", "", false, false) + require.NoError(w.T(), err) +} + +func (w *WorkloadTestSuite) TestWorkloadSideKick() { + subSession := w.session.NewSession() + defer subSession.Cleanup() + + _, namespace, err := projectsapi.CreateProjectAndNamespace(w.client, w.cluster.ID) + require.NoError(w.T(), err) + + createdDeployment, err := deployment.CreateDeployment(w.client, w.cluster.ID, namespace.Name, 1, "", "", false, false) + require.NoError(w.T(), err) + + countRunning, err := pods.CountPodContainerRunning(w.client, w.cluster.ID, namespace.Name) + require.NoError(w.T(), err) + require.Equal(w.T(), 1, countRunning) + + containerName := namegen.AppendRandomString("updatetestcontainer") + newContainerTemplate := workloads.NewContainer(containerName, + "redis", + corev1.PullAlways, + []corev1.VolumeMount{}, + []corev1.EnvFromSource{}, + nil, + nil, + nil, + ) + + createdDeployment.Spec.Template.Spec.Containers = append(createdDeployment.Spec.Template.Spec.Containers, newContainerTemplate) + + _, err = deployment.UpdateDeployment(w.client, w.cluster.ID, namespace.Name, createdDeployment) + require.NoError(w.T(), err) + + countRunning, err = pods.CountPodContainerRunning(w.client, w.cluster.ID, namespace.Name) + require.NoError(w.T(), err) + require.Equal(w.T(), 2, countRunning) +} + +func (w *WorkloadTestSuite) TestWorkloadDaemonSet() { + subSession := w.session.NewSession() + defer subSession.Cleanup() + + _, namespace, err := projectsapi.CreateProjectAndNamespace(w.client, w.cluster.ID) + require.NoError(w.T(), err) + + _, err = deamonset.CreateDeamonset(w.client, w.cluster.ID, namespace.Name, 1, "", "", false, false) + require.NoError(w.T(), err) +} + +func TestWorkloadTestSuite(t *testing.T) { + suite.Run(t, new(WorkloadTestSuite)) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/DEBUG.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/DEBUG.md new file mode 100644 index 0000000..ef63c9b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/DEBUG.md @@ -0,0 +1,14 @@ +# Interpreting Debug Data + +## General +The debug data is going to be printed out as json that is gzipped then base64'ed. You can +``` +echo 'blob' | base64 --decode | gzip -d | jq -r +``` +to get to something readable. + +## Pod Logs +Pod logs are again gzip and base64'ed, but they have literal "\n" rendered in. For consumable logs, try +``` +echo 'podlogblob' | base64 --decode | gzip -d | sed -e 's/SnewlineG/\n/g' +``` \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/README.md new file mode 100644 index 0000000..d7eb4e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/README.md @@ -0,0 +1,54 @@ +# v2prov Integration Tests + +These are a set of provisioning-v2 integration tests. + +These tests are designed to be run on a single-node cluster (due to the usage of HostPath volumes), and perform e2e validations of v2prov + CAPR using systemd-node. + +## Test Categories + +There are three major categories of tests that are contained within this test suite. + +### General + +General tests, for example, ensuring system-agent version is as expected. + +### Provisioning_MP + +Provisioning tests encompass creation and deletion of v2prov clusters. MP stands for machine-provisioned, and will use nodepools to manage the test infrastructure. + +### Provisioning_Custom + +Provisioning tests encompass creation and deletion of v2prov clusters. Custom will use a "Custom" cluster and the framework manually creates systemd-node pods. + +### Operation_MP + +Operation tests are day 2 operation tests like encryption key rotation, certificate rotation, and etcd snapshot creation/restore. MP stands for machine-provisioned, and will use nodepools to manage the test infrastructure. + +### Operation_Custom + +Operation tests are day 2 operation tests like encryption key rotation, certificate rotation, and etcd snapshot creation/restore. Custom will use a "Custom" cluster and the framework manually creates systemd-node pods. + +## Test Naming Format + +Within the `tests` folder, there are mutliple types of tests. They notably all have a format like to ensure we do not clog up individual pipeline stages as they are resource intensive. + +`Test__` + +`` corresponds to the categories listed above. + +## Running Locally + +You can run these tests locally on a machine that can support running systemd within containers. + +If you invoke `make provisioning-tests`, it will run all of the provisioning/general tests. + +You can customize the tests you run through the use of the environment variables: `V2PROV_TEST_RUN_REGEX` and `V2PROV_TEST_DIST`. + +`V2PROV_TEST_DIST` can be either `k3s` (default) or `rke2` +`V2PROV_TEST_RUN_REGEX` is a regex string indicating the pattern of tests to match. You can selectively run tests by setting this, for example: + +``` +V2PROV_TEST_RUN_REGEX=Test_Operation_Custom_EncryptionKeyRotation V2PROV_TEST_DIST=rke2 make provisioning-tests +``` + +would specifically run the `Test_Operation_Custom_EncryptionKeyRotation` test with RKE2. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/clients/clients.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/clients/clients.go new file mode 100644 index 0000000..9d965d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/clients/clients.go @@ -0,0 +1,85 @@ +package clients + +import ( + "context" + "time" + + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/wrangler/v3/pkg/kubeconfig" + "github.com/rancher/wrangler/v3/pkg/ratelimit" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/tools/clientcmd" +) + +type Clients struct { + *wrangler.Context + Dynamic dynamic.Interface + + // Ctx is canceled when the Close() is called + Ctx context.Context + cancel func() + onClose []func() +} + +func (c *Clients) Close() { + for i := len(c.onClose); i > 0; i-- { + c.onClose[i-1]() + } + c.cancel() +} + +func (c *Clients) OnClose(f func()) { + c.onClose = append(c.onClose, f) +} + +func (c *Clients) ForCluster(namespace, name string) (*Clients, error) { + secret, err := c.Core.Secret().Get(namespace, name+"-kubeconfig", metav1.GetOptions{}) + if err != nil { + return nil, err + } + + config, err := clientcmd.NewClientConfigFromBytes(secret.Data["value"]) + if err != nil { + return nil, err + } + + return NewForConfig(c.Ctx, config) +} + +func New() (*Clients, error) { + config := kubeconfig.GetNonInteractiveClientConfig("") + return NewForConfig(context.Background(), config) +} + +func NewForConfig(ctx context.Context, config clientcmd.ClientConfig) (*Clients, error) { + ctx, cancel := context.WithCancel(ctx) + + rest, err := config.ClientConfig() + if err != nil { + cancel() + return nil, err + } + + rest.Timeout = 30 * time.Minute + rest.RateLimiter = ratelimit.None + + wranglerCtx, err := wrangler.NewContext(ctx, config, rest) + if err != nil { + cancel() + return nil, err + } + + dynamic, err := dynamic.NewForConfig(rest) + if err != nil { + cancel() + return nil, err + } + + return &Clients{ + Context: wranglerCtx, + Dynamic: dynamic, + Ctx: ctx, + cancel: cancel, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/cluster/clusters.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/cluster/clusters.go new file mode 100644 index 0000000..bd3496e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/cluster/clusters.go @@ -0,0 +1,634 @@ +package cluster + +import ( + "bufio" + "context" + "encoding/base64" + "fmt" + "os" + "os/exec" + "path" + "regexp" + "strings" + "time" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + provisioningv1api "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/pkg/controllers/capr/machineprovision" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/namespace" + "github.com/rancher/rancher/tests/v2prov/nodeconfig" + "github.com/rancher/rancher/tests/v2prov/registry" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/wrangler/v3/pkg/condition" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/sirupsen/logrus" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +const ConflictMessageRegex = `\[K8s\] encountered an error while attempting to update the secret: Operation cannot be fulfilled on secrets.*: the object has been modified; please apply your changes to the latest version and try again` +const SaneConflictMessageThreshold = 3 + +func New(clients *clients.Clients, cluster *provisioningv1api.Cluster) (*provisioningv1api.Cluster, error) { + cluster = cluster.DeepCopy() + if cluster.Namespace == "" { + newNs, err := namespace.Random(clients) + if err != nil { + return nil, err + } + cluster.Namespace = newNs.Name + } + + if cluster.Name == "" && cluster.GenerateName == "" { + cluster.GenerateName = "test-cluster-" + } + + if cluster.Spec.KubernetesVersion == "" { + cluster.Spec.KubernetesVersion = defaults.SomeK8sVersion + } + + if cluster.Spec.RKEConfig != nil { + if cluster.Spec.RKEConfig.MachineGlobalConfig.Data == nil { + cluster.Spec.RKEConfig.MachineGlobalConfig.Data = map[string]interface{}{} + } + for k, v := range defaults.CommonClusterConfig { + cluster.Spec.RKEConfig.MachineGlobalConfig.Data[k] = v + } + + for i, mp := range cluster.Spec.RKEConfig.MachinePools { + if mp.NodeConfig == nil { + podConfig, err := nodeconfig.NewPodConfig(clients, cluster.Namespace) + if err != nil { + return nil, err + } + cluster.Spec.RKEConfig.MachinePools[i].NodeConfig = podConfig + } + if mp.Name == "" { + cluster.Spec.RKEConfig.MachinePools[i].Name = fmt.Sprintf("pool-%d", i) + } + } + + if cluster.Spec.RKEConfig.Registries == nil { + registryConfig, err := registry.CreateOrGetRegistry(clients, cluster.Namespace, "registry-cache", false) + if err != nil { + return nil, err + } + cluster.Spec.RKEConfig.Registries = ®istryConfig + } + + if cluster.Spec.RKEConfig.ETCD == nil { + cluster.Spec.RKEConfig.ETCD = &rkev1.ETCD{ + DisableSnapshots: true, + } + } + + // If an override is specified for a data directory, and one is not explicitly set for the cluster, use it + if cluster.Spec.RKEConfig.DataDirectories.K8sDistro == "" { + cluster.Spec.RKEConfig.DataDirectories.K8sDistro = defaults.DistroDataDir + } + + if cluster.Spec.RKEConfig.DataDirectories.Provisioning == "" { + cluster.Spec.RKEConfig.DataDirectories.Provisioning = defaults.ProvisioningDataDir + } + + if cluster.Spec.RKEConfig.DataDirectories.SystemAgent == "" { + cluster.Spec.RKEConfig.DataDirectories.SystemAgent = defaults.SystemAgentDataDir + } + } + + c, err := clients.Provisioning.Cluster().Create(cluster) + if err != nil { + return nil, err + } + + clients.OnClose(func() { + clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + }) + + return c, nil +} + +func Machines(clients *clients.Clients, cluster *provisioningv1api.Cluster) (*capi.MachineList, error) { + return clients.CAPI.Machine().List(cluster.Namespace, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + cluster.Name, + }) +} + +func MachineSets(clients *clients.Clients, cluster *provisioningv1api.Cluster) (*capi.MachineSetList, error) { + return clients.CAPI.MachineSet().List(cluster.Namespace, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + cluster.Name, + }) +} + +func PodInfraMachines(clients *clients.Clients, cluster *provisioningv1api.Cluster) (*unstructured.UnstructuredList, error) { + return clients.Dynamic.Resource(schema.GroupVersionResource{ + Group: "rke-machine.cattle.io", + Version: "v1", + Resource: "podmachines", + }).Namespace(cluster.Namespace).List(clients.Ctx, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + cluster.Name, + }) +} + +func WaitForCreate(clients *clients.Clients, c *provisioningv1api.Cluster) (_ *provisioningv1api.Cluster, err error) { + defer func() { + if err != nil { + data, newErr := GatherDebugData(clients, c) + if newErr != nil { + logrus.Error(newErr) + } + err = fmt.Errorf("cluster %s creation wait failed on: %w\ncluster %s test data bundle: \n%s", c.Name, err, c.Name, data) + } + }() + + err = wait.Object(clients.Ctx, clients.Provisioning.Cluster().Watch, c, func(obj runtime.Object) (bool, error) { + c = obj.(*provisioningv1api.Cluster) + return c.Status.ClusterName != "" && c.Status.Ready && c.Status.ObservedGeneration == c.Generation && capr.Ready.IsTrue(c) && capr.Provisioned.IsTrue(c), nil + }) + if err != nil { + return nil, fmt.Errorf("prov cluster is not ready: %w", err) + } + + if len(c.Spec.RKEConfig.MachinePools) > 0 { + machineSets, err := MachineSets(clients, c) + if err != nil { + return nil, err + } + + for _, machineSet := range machineSets.Items { + // retrieve the corresponding machinedeployment and verify that it is "sane" + mpName, ok := machineSet.Labels[capr.RKEMachinePoolNameLabel] + if !ok { + return nil, fmt.Errorf("machineset %s/%s did not have a corresponding machine pool name label", machineSet.Namespace, machineSet.Name) + } + md, err := clients.CAPI.MachineDeployment().Get(c.Namespace, name.SafeConcatName(c.Name, mpName), metav1.GetOptions{}) + if err != nil { + return nil, err + } + err = wait.Object(clients.Ctx, clients.CAPI.MachineDeployment().Watch, md, func(obj runtime.Object) (bool, error) { + md = obj.(*capi.MachineDeployment) + for _, mp := range c.Spec.RKEConfig.MachinePools { + if mpName == mp.Name { + mpQuantityMatches := true + if mp.Quantity != nil { + mpQuantityMatches = *mp.Quantity == *md.Spec.Replicas + } + return mpQuantityMatches && md.Status.Phase == "Running" && capr.Ready.IsTrue(md), nil + } + } + return false, nil + }) + if err != nil { + return nil, fmt.Errorf("MachineDeployment %s/%s was not ready: %w", md.Namespace, md.Name, err) + } + } + } + + machines, err := Machines(clients, c) + if err != nil { + return nil, err + } + + for _, machine := range machines.Items { + if !machine.DeletionTimestamp.IsZero() { + continue + } + err = wait.Object(clients.Ctx, clients.CAPI.Machine().Watch, &machine, func(obj runtime.Object) (bool, error) { + machine = *obj.(*capi.Machine) + return machine.Status.NodeRef != nil, nil + }) + if err != nil { + return nil, fmt.Errorf("noderef not assigned to %s/%s: %w", machine.Namespace, machine.Name, err) + } + } + + mgmtCluster, err := clients.Mgmt.Cluster().Get(c.Status.ClusterName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + err = wait.Object(clients.Ctx, func(namespace string, opts metav1.ListOptions) (watch.Interface, error) { + return clients.Mgmt.Cluster().Watch(opts) + }, mgmtCluster, func(obj runtime.Object) (bool, error) { + mgmtCluster = obj.(*v3.Cluster) + return condition.Cond("Ready").IsTrue(mgmtCluster), nil + }) + if err != nil { + return nil, fmt.Errorf("mgmt cluster is not ready: %w", err) + } + + return c, nil +} + +func WaitForControlPlane(clients *clients.Clients, c *provisioningv1api.Cluster, errorPrefix string, rkeControlPlaneCheckFunc func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error)) (_ *rkev1.RKEControlPlane, err error) { + defer func() { + if err != nil { + data, newErr := GatherDebugData(clients, c) + if newErr != nil { + logrus.Error(newErr) + } + err = fmt.Errorf("cluster %s %s wait failed on: %w\ncluster %s test data bundle: \n%s", c.Name, errorPrefix, err, c.Name, data) + } + }() + + controlPlane, err := clients.RKE.RKEControlPlane().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("%s wait did not succeed : %w", errorPrefix, err) + } + + err = wait.Object(clients.Ctx, clients.RKE.RKEControlPlane().Watch, controlPlane, func(obj runtime.Object) (bool, error) { + controlPlane = obj.(*rkev1.RKEControlPlane) + return rkeControlPlaneCheckFunc(controlPlane) + }) + if err != nil { + return nil, fmt.Errorf("%s wait did not succeed : %w", errorPrefix, err) + } + + return controlPlane, nil +} + +func WaitForDelete(clients *clients.Clients, c *provisioningv1api.Cluster) (_ *provisioningv1api.Cluster, err error) { + defer func() { + if err != nil { + data, newErr := GatherDebugData(clients, c) + if newErr != nil { + logrus.Error(newErr) + } + err = fmt.Errorf("cluster %s delete wait failed on: %w\ncluster %s test data bundle: \n%s", c.Name, err, c.Name, data) + } + }() + + err = wait.Object(clients.Ctx, clients.Provisioning.Cluster().Watch, c, func(obj runtime.Object) (bool, error) { + c = obj.(*provisioningv1api.Cluster) + return !c.DeletionTimestamp.IsZero(), nil + }) + if err != nil { + return nil, fmt.Errorf("cluster not deleted: %w", err) + } + + machines, err := Machines(clients, c) + if err != nil { + return nil, err + } + + for _, machine := range machines.Items { + gvk := schema.FromAPIVersionAndKind(machine.Spec.InfrastructureRef.APIVersion, machine.Spec.InfrastructureRef.Kind) + gvr := schema.GroupVersionResource{ + Group: gvk.Group, + Version: gvk.Version, + Resource: strings.ToLower(gvk.Kind) + "s", + } + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Dynamic.Resource(gvr).Namespace(machine.Spec.InfrastructureRef.Namespace).Get(clients.Ctx, machine.Spec.InfrastructureRef.Name, metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("infra machine %s/%s not deleted: %w", machine.Spec.InfrastructureRef.Namespace, machine.Spec.InfrastructureRef.Name, err) + } + + if machine.Spec.Bootstrap.ConfigRef != nil { + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.RKE.RKEBootstrap().Get(machine.Spec.Bootstrap.ConfigRef.Namespace, machine.Spec.Bootstrap.ConfigRef.Name, metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("bootstrap config %s/%s not deleted: %w", machine.Spec.Bootstrap.ConfigRef.Namespace, machine.Spec.Bootstrap.ConfigRef.Name, err) + } + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Batch.Job().Get(machine.Namespace, machineprovision.GetJobName(machine.Name), metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("machine provision job %s/%s not deleted: %w", machine.Namespace, machineprovision.GetJobName(machine.Name), err) + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.CAPI.Machine().Get(machine.Namespace, machine.Name, metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("machine not deleted: %w", err) + } + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Mgmt.Cluster().Get(c.Status.ClusterName, metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("mgmt cluster not cleaned up: %w", err) + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + }); err != nil { + return nil, fmt.Errorf("cluster not cleaned up: %w", err) + } + + return c, nil +} + +func CustomCommand(clients *clients.Clients, c *provisioningv1api.Cluster) (string, error) { + err := wait.Object(clients.Ctx, clients.Provisioning.Cluster().Watch, c, func(obj runtime.Object) (bool, error) { + c = obj.(*provisioningv1api.Cluster) + return c.Status.ClusterName != "", nil + }) + if err != nil { + return "", err + } + + for i := 0; i < 15; i++ { + tokens, err := clients.Mgmt.ClusterRegistrationToken().List(c.Status.ClusterName, metav1.ListOptions{}) + if err != nil || len(tokens.Items) == 0 || tokens.Items[0].Status.NodeCommand == "" { + time.Sleep(time.Second) + continue + } + return strings.Replace(tokens.Items[0].Status.InsecureNodeCommand, "curl", "curl --retry-connrefused --retry-delay 5 --retry 30", -1), nil + } + + return "", fmt.Errorf("timeout getting custom command") +} + +// getPodLogs gathers the logs from the specified pod in a manner similar to `kubectl logs` +func getPodLogs(clients *clients.Clients, podNamespace, podName string) (string, error) { + plr := clients.K8s.CoreV1().Pods(podNamespace).GetLogs(podName, &corev1.PodLogOptions{}) + stream, err := plr.Stream(context.TODO()) + if err != nil { + return "", fmt.Errorf("error streaming pod logs for pod %s/%s: %v", podNamespace, podName, err) + } + defer stream.Close() + + reader := bufio.NewScanner(stream) + var logs string + for reader.Scan() { + logs = logs + fmt.Sprintf("%sSnewlineG", reader.Text()) + } + return capr.CompressInterface(logs) +} + +// countPodLogRegexOccurances gathers the logs from the specified pod in a manner similar to `kubectl logs` and counts the number of times the log matches the given regex. +func countPodLogRegexOccurances(clients *clients.Clients, podNamespace, podName, regex string) (int, error) { + count := 0 + plr := clients.K8s.CoreV1().Pods(podNamespace).GetLogs(podName, &corev1.PodLogOptions{}) + stream, err := plr.Stream(context.TODO()) + if err != nil { + return count, fmt.Errorf("error streaming pod logs for pod %s/%s: %v", podNamespace, podName, err) + } + defer stream.Close() + + re := regexp.MustCompile(regex) + + reader := bufio.NewScanner(stream) + for reader.Scan() { + if re.Match(reader.Bytes()) { + count++ + } + } + return count, nil +} + +// getPodFileContents executes a corresponding `kubectl cp` and gathers data for the purposes of helping increasing debug data. +func getPodFileContents(podNamespace, podName, podPath string) (string, error) { + destFile := fmt.Sprintf("/tmp/%s", base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s/%s/%s", podNamespace, podName, podPath)))) + kcp := []string{ + "-n", + podNamespace, + "cp", + fmt.Sprintf("%s:%s", podName, podPath), + destFile, + } + + cmd := exec.Command("kubectl", kcp...) + if err := cmd.Run(); err != nil { + logrus.Errorf("error running kubectl -n %s cp %s:%s %s", podNamespace, podName, podPath, destFile) + return "", nil + } + + file, err := os.Open(destFile) + if err != nil { + logrus.Errorf("error retrieving destination file %s: %v", destFile, err) + return "", nil + } + defer file.Close() + reader := bufio.NewScanner(file) + var logs string + for reader.Scan() { + logs = logs + fmt.Sprintf("%sSnewlineG", reader.Text()) + } + return capr.CompressInterface(logs) +} + +// GatherDebugData gathers debug data that is relevant to the current cluster and returns a gzip compressed + base64 encoded string of the json. +func GatherDebugData(clients *clients.Clients, c *provisioningv1api.Cluster) (string, error) { + newC, newErr := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get cluster %s/%s to print error: %v", c.Namespace, c.Name, newErr) + newC = nil + } + + newControlPlane, newErr := clients.RKE.RKEControlPlane().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get controlplane %s/%s to print error: %v", c.Namespace, c.Name, newErr) + newControlPlane = nil + } + + var rkeBootstraps []*rkev1.RKEBootstrap + var infraMachines []*unstructured.Unstructured + var machineSecrets []*corev1.Secret + + var podLogs = make(map[string]map[string]string) + + machines, newErr := Machines(clients, c) + if newErr != nil { + logrus.Errorf("failed to get machines for %s/%s to print error: %v", c.Namespace, c.Name, newErr) + } else { + for _, machine := range machines.Items { + rb, newErr := clients.RKE.RKEBootstrap().Get(machine.Spec.Bootstrap.ConfigRef.Namespace, machine.Spec.Bootstrap.ConfigRef.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get RKEBootstrap %s/%s to print error: %v", c.Namespace, c.Name, newErr) + } else { + rkeBootstraps = append(rkeBootstraps, rb) + } + im, newErr := clients.Dynamic.Resource(schema.GroupVersionResource{ + Group: machine.Spec.InfrastructureRef.GroupVersionKind().Group, + Version: machine.Spec.InfrastructureRef.GroupVersionKind().Version, + Resource: strings.ToLower(fmt.Sprintf("%ss", machine.Spec.InfrastructureRef.GroupVersionKind().Kind)), + }).Namespace(machine.Spec.InfrastructureRef.Namespace).Get(context.TODO(), machine.Spec.InfrastructureRef.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get %s %s/%s to print error: %v", machine.Spec.InfrastructureRef.GroupVersionKind().String(), machine.Spec.InfrastructureRef.Namespace, machine.Spec.InfrastructureRef.Name, newErr) + } else { + infraMachines = append(infraMachines, im) + if machine.Spec.InfrastructureRef.GroupVersionKind().Kind == "PodMachine" { + // In the case of a podmachine, the pod name will be strings.ReplaceAll(infra.meta.GetName(), ".", "-") + podName := strings.ReplaceAll(im.GetName(), ".", "-") + podLogs[podName] = populatePodLogs(clients, newControlPlane, im.GetNamespace(), podName) + } + } + ms, newErr := clients.Core.Secret().List(machine.Namespace, metav1.ListOptions{ + LabelSelector: fmt.Sprintf("cluster.x-k8s.io/cluster-name=%s,rke.cattle.io/machine-name=", machine.Name), + }) + if newErr != nil { + logrus.Errorf("failed to get secrets for machine %s: %v", machine.Name, newErr) + } else { + for _, s := range ms.Items { + machineSecrets = append(machineSecrets, s.DeepCopy()) + } + } + } + } + + customPods, newErr := clients.Core.Pod().List(c.Namespace, metav1.ListOptions{ + LabelSelector: "custom-cluster-name=" + c.Name, + }) + if newErr != nil { + logrus.Errorf("failed to list custommachine pods: %v", newErr) + } else { + for _, pod := range customPods.Items { + podLogs[pod.Name] = populatePodLogs(clients, newControlPlane, pod.Namespace, pod.Name) + } + } + + rkeBootstrapTemplates, newErr := clients.RKE.RKEBootstrapTemplate().List(c.Namespace, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + c.Name, + }) + if newErr != nil { + logrus.Errorf("failed to get rkebootstrap templates for %s/%s to print error: %v", c.Namespace, c.Name, newErr) + } + + mgmtCluster, newErr := clients.Mgmt.Cluster().Get(c.Status.ClusterName, metav1.GetOptions{}) + if apierrors.IsNotFound(newErr) { + mgmtCluster = nil + } else if newErr != nil { + logrus.Errorf("failed to get mgmt cluster %s/%s to print error: %v", c.Namespace, c.Name, newErr) + } + + var infraCluster *unstructured.Unstructured + var machineDeployments *capi.MachineDeploymentList + var machineSets *capi.MachineSetList + + capiCluster, newErr := clients.CAPI.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if apierrors.IsNotFound(newErr) { + capiCluster = nil + } else if newErr != nil { + logrus.Errorf("failed to get capi cluster %s/%s to print error: %v", c.Namespace, c.Name, newErr) + } else { + infraCluster, newErr = clients.Dynamic.Resource(schema.GroupVersionResource{ + Group: capiCluster.Spec.InfrastructureRef.GroupVersionKind().Group, + Version: capiCluster.Spec.InfrastructureRef.GroupVersionKind().Version, + Resource: strings.ToLower(fmt.Sprintf("%ss", capiCluster.Spec.InfrastructureRef.GroupVersionKind().Kind)), + }).Namespace(capiCluster.Spec.InfrastructureRef.Namespace).Get(context.TODO(), capiCluster.Spec.InfrastructureRef.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get %s %s/%s to print error: %v", capiCluster.Spec.InfrastructureRef.GroupVersionKind().String(), capiCluster.Spec.InfrastructureRef.Namespace, capiCluster.Spec.InfrastructureRef.Name, newErr) + infraCluster = nil + } + machineDeployments, newErr = clients.CAPI.MachineDeployment().List(c.Namespace, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + c.Name, + }) + if newErr != nil { + logrus.Error(newErr) + machineDeployments = nil + } + machineSets, newErr = clients.CAPI.MachineSet().List(c.Namespace, metav1.ListOptions{ + LabelSelector: "cluster.x-k8s.io/cluster-name=" + c.Name, + }) + if newErr != nil { + logrus.Error(newErr) + machineSets = nil + } + } + + snapshots, newErr := clients.RKE.ETCDSnapshot().List(c.Namespace, metav1.ListOptions{}) + if newErr != nil { + logrus.Error(newErr) + snapshots = nil + } + + return capr.CompressInterface(map[string]interface{}{ + "cluster": newC, + "rkecontrolplane": newControlPlane, + "mgmtCluster": mgmtCluster, + "capiCluster": capiCluster, + "machineDeployments": machineDeployments, + "machineSets": machineSets, + "machines": machines, + "rkeBootstraps": rkeBootstraps, + "rkeBootstrapTemplates": rkeBootstrapTemplates, + "infraCluster": infraCluster, + "infraMachines": infraMachines, + "podLogs": podLogs, + "snapshots": snapshots, + }) +} + +// populatePodLogs creates a map[string]string of logs that correspond to the pod in question. If the pod is an RKE2 pod, it also collects the kubelet logs from the pod filesystem. +func populatePodLogs(clients *clients.Clients, controlPlane *rkev1.RKEControlPlane, podNamespace, podName string) map[string]string { + var logMap = make(map[string]string) + + logs, err := getPodLogs(clients, podNamespace, podName) + if err != nil { + logrus.Errorf("error while retrieving pod logs: %v", err) + } else { + logMap["logs"] = logs + } + + if controlPlane != nil && capr.GetRuntime(controlPlane.Spec.KubernetesVersion) == capr.RuntimeRKE2 { + kubeletLogs, err := getPodFileContents(podNamespace, podName, path.Join(capr.GetDistroDataDir(controlPlane), "agent/logs/kubelet.log")) + if err != nil { + logrus.Errorf("error while retrieving pod kubelet logs: %v", err) + } else { + logMap["kubeletLogs"] = kubeletLogs + } + } + + return logMap +} + +// EnsureMinimalConflictsWithThreshold walks through pod logs and ensures a minimal number of conflict messages have occurred. +func EnsureMinimalConflictsWithThreshold(clients *clients.Clients, c *provisioningv1api.Cluster, threshold int) error { + customPods, newErr := clients.Core.Pod().List(c.Namespace, metav1.ListOptions{ + LabelSelector: "custom-cluster-name=" + c.Name, + }) + if newErr != nil { + logrus.Errorf("failed to list custommachine pods: %v", newErr) + } else { + for _, pod := range customPods.Items { + count, err := countPodLogRegexOccurances(clients, pod.Namespace, pod.Name, ConflictMessageRegex) + if err != nil { + return err + } + if count > threshold { + return fmt.Errorf("pod %s/%s had %d occurrences of conflicts which was greater than the threshold of %d", pod.Namespace, pod.Name, count, threshold) + } + } + } + + machines, newErr := Machines(clients, c) + if newErr != nil { + logrus.Errorf("failed to get machines for %s/%s to count conflicts: %v", c.Namespace, c.Name, newErr) + } + for _, machine := range machines.Items { + im, newErr := clients.Dynamic.Resource(schema.GroupVersionResource{ + Group: machine.Spec.InfrastructureRef.GroupVersionKind().Group, + Version: machine.Spec.InfrastructureRef.GroupVersionKind().Version, + Resource: strings.ToLower(fmt.Sprintf("%ss", machine.Spec.InfrastructureRef.GroupVersionKind().Kind)), + }).Namespace(machine.Spec.InfrastructureRef.Namespace).Get(context.TODO(), machine.Spec.InfrastructureRef.Name, metav1.GetOptions{}) + if newErr != nil { + logrus.Errorf("failed to get %s %s/%s to print error: %v", machine.Spec.InfrastructureRef.GroupVersionKind().String(), machine.Spec.InfrastructureRef.Namespace, machine.Spec.InfrastructureRef.Name, newErr) + } else { + if machine.Spec.InfrastructureRef.GroupVersionKind().Kind == "PodMachine" { + // In the case of a podmachine, the pod name will be strings.ReplaceAll(infra.meta.GetName(), ".", "-") + podName := strings.ReplaceAll(im.GetName(), ".", "-") + count, err := countPodLogRegexOccurances(clients, im.GetNamespace(), podName, ConflictMessageRegex) + if err != nil { + return err + } + if count > threshold { + return fmt.Errorf("pod %s/%s had %d occurrences of conflicts which was greater than the threshold of %d", im.GetNamespace(), podName, count, threshold) + } + } + } + } + return nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/defaults/defaults.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/defaults/defaults.go new file mode 100644 index 0000000..0970c04 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/defaults/defaults.go @@ -0,0 +1,34 @@ +package defaults + +import ( + "os" + "time" + + "k8s.io/apimachinery/pkg/util/wait" +) + +var ( + PodTestImage = "rancher/systemd-node:v0.0.5-rc2" + ObjectStoreServerImage = "rancher/mirrored-minio-minio:RELEASE.2022-12-12T19-27-27Z" + ObjectStoreUtilImage = "rancher/mirrored-minio-mc:RELEASE.2022-12-13T00-23-28Z" + SomeK8sVersion = os.Getenv("SOME_K8S_VERSION") + DistroDataDir = os.Getenv("V2PROV_DISTRO_DATA_DIR") + ProvisioningDataDir = os.Getenv("V2PROV_PROVISIONING_DATA_DIR") + SystemAgentDataDir = os.Getenv("V2PROV_SYSTEM_AGENT_DATA_DIR") + WatchTimeoutSeconds = int64(2700) // 45 minutes. + CommonClusterConfig = map[string]interface{}{ + "service-cidr": "10.45.0.0/16", + "cluster-cidr": "10.44.0.0/16", + "garbage": "value", + } + + One = int32(1) + Two = int32(2) + Three = int32(3) + DownstreamRetry = wait.Backoff{ + Steps: 10, + Duration: 30 * time.Second, + Factor: 1.0, + Jitter: 0.1, + } +) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/namespace/namespace.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/namespace/namespace.go new file mode 100644 index 0000000..519cd62 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/namespace/namespace.go @@ -0,0 +1,23 @@ +package namespace + +import ( + "github.com/rancher/rancher/tests/v2prov/clients" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Random(clients *clients.Clients) (*corev1.Namespace, error) { + ns, err := clients.Core.Namespace().Create(&corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "test-ns-", + }, + }) + if err != nil { + return nil, err + } + clients.OnClose(func() { + clients.Core.Namespace().Delete(ns.Name, nil) + }) + + return ns, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/nodeconfig/nodeconfig.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/nodeconfig/nodeconfig.go new file mode 100644 index 0000000..1684557 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/nodeconfig/nodeconfig.go @@ -0,0 +1,119 @@ +package nodeconfig + +import ( + "encoding/json" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/wrangler/v3/pkg/condition" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func FromNode(node *corev1.Node) ([]string, error) { + var args []string + str := node.Annotations["rke2.io/node-args"] + if str == "" { + str = node.Annotations["k3s.io/node-args"] + } + + return args, json.Unmarshal([]byte(str), &args) +} + +func NewPodConfig(clients *clients.Clients, namespace string) (*corev1.ObjectReference, error) { + _, err := clients.RBAC.Role().Create(&rbacv1.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rke2-machine-provisioner", + Namespace: namespace, + }, + Rules: []rbacv1.PolicyRule{ + { + Verbs: []string{"*"}, + APIGroups: []string{"*"}, + Resources: []string{"*"}, + }, + }, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return nil, err + } + clients.OnClose(func() { + _ = clients.RBAC.Role().Delete(namespace, "rke2-machine-provisioner", nil) + }) + + _, err = clients.Mgmt.NodeDriver().Create(&v3.NodeDriver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pod", + }, + Spec: v3.NodeDriverSpec{ + DisplayName: "pod", + URL: "local://", + Builtin: true, + Active: true, + }, + }) + if err != nil && !apierrors.IsAlreadyExists(err) { + return nil, err + } + + err = wait.ClusterScopedList(clients.Ctx, clients.CRD.CustomResourceDefinition().Watch, func(obj runtime.Object) (bool, error) { + crd := obj.(*v1.CustomResourceDefinition) + return crd.Name == "podconfigs.rke-machine-config.cattle.io" && condition.Cond("Established").IsTrue(crd), nil + }) + if err != nil { + return nil, err + } + + podConfig := &unstructured.Unstructured{} + podConfig.SetAPIVersion("rke-machine-config.cattle.io/v1") + podConfig.SetKind("PodConfig") + podConfig.SetNamespace(namespace) + podConfig.SetGenerateName("pod-config-") + podConfig.Object["image"] = defaults.PodTestImage + // We are providing custom userdata to force K3s/RKE2 to use the cgroupfs cgroup driver, rather than systemd + // We have to set invocation disabling on the rancher-system-agent because it runs rke2/k3s server on restore and this has cgroup issues + podConfig.Object["userdata"] = `#cloud-config +write_files: +- content: | + INVOCATION_ID= + path: /etc/default/rke2-server +- content: | + INVOCATION_ID= + path: /etc/default/rke2-agent +- content: | + INVOCATION_ID= + path: /etc/default/k3s +- content: | + INVOCATION_ID= + path: /etc/default/k3s-agent +- content: | + INVOCATION_ID= + path: /etc/default/rancher-system-agent` + + podConfigClient := clients.Dynamic.Resource(schema.GroupVersionResource{ + Group: "rke-machine-config.cattle.io", + Version: "v1", + Resource: "podconfigs", + }) + result, err := podConfigClient.Namespace(namespace).Create(clients.Ctx, podConfig, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + + clients.OnClose(func() { + _ = podConfigClient.Delete(clients.Ctx, result.GetName(), metav1.DeleteOptions{}) + }) + + return &corev1.ObjectReference{ + Kind: result.GetKind(), + Name: result.GetName(), + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/objectstore/objectstore.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/objectstore/objectstore.go new file mode 100644 index 0000000..a16b636 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/objectstore/objectstore.go @@ -0,0 +1,408 @@ +package objectstore + +import ( + "encoding/base64" + "fmt" + "net" + "sync" + + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/rke/pki/cert" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" +) + +var ( + objectStoreServiceNameTemplate = "%s.%s.svc.cluster.local" + objectStoreLock sync.Mutex +) + +const ( + secretKeyCredAccessKey = "MINIO_ROOT_USER" + secretKeyCredSecretKey = "MINIO_ROOT_PASSWORD" + secretKeyTLSPublicCrt = "public.crt" + secretKeyTLSPrivateKey = "private.key" +) + +const setupMinioBucket = ` +#!/bin/sh + +while ! curl -ksf https://127.0.0.1:9000/minio/health/live; do + sleep 2 +done + +mc config host --insecure add myminio https://127.0.0.1:9000 $%s $%s + +while true; do + mc ready --insecure myminio + if [ $? = 0 ]; then + break; + fi; +done; + +mc mb --insecure myminio/%s + +sleep infinity +` + +// createTLSSecret creates a TLS Secret with a self signed cert + key for the given service FQDN + IP. +func createTLSSecret(clients *clients.Clients, namespace, objectStore, serviceFQDN, serviceIP string) (*corev1.Secret, error) { + objectStoreTLSSecretName := objectStore + "-tls" + secret, err := clients.Core.Secret().Get(namespace, objectStoreTLSSecretName, metav1.GetOptions{}) + if err == nil { + return secret, nil + } else if !apierrors.IsNotFound(err) { + return nil, err + } + + cert, key, err := cert.GenerateSelfSignedCertKey(serviceFQDN, []net.IP{net.ParseIP(serviceIP)}, nil) + if err != nil { + return nil, err + } + + secret, err = clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: objectStoreTLSSecretName, + Namespace: namespace, + }, + Data: map[string][]byte{ + secretKeyTLSPublicCrt: cert, + secretKeyTLSPrivateKey: key, + }, + }) + if err == nil { + clients.OnClose(func() { + clients.Core.Secret().Delete(secret.Namespace, secret.Name, &metav1.DeleteOptions{}) + }) + return secret, nil + } else if apierrors.IsAlreadyExists(err) { + return clients.Core.Secret().Get(namespace, objectStoreTLSSecretName, metav1.GetOptions{}) + } + return nil, err +} + +// createCredSecret creates a credential secret for the +func createCredSecret(clients *clients.Clients, namespace, objectStore string) (*corev1.Secret, error) { + objectStoreCredSecretName := objectStore + "-cred" + secret, err := clients.Core.Secret().Get(namespace, objectStoreCredSecretName, metav1.GetOptions{}) + if err == nil { + return secret, nil + } else if !apierrors.IsNotFound(err) { + return nil, err + } + + accessKey, err := randomtoken.Generate() + if err != nil { + return nil, err + } + accessKey = accessKey[:16] + + secretKey, err := randomtoken.Generate() + if err != nil { + return nil, err + } + + secret, err = clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: objectStoreCredSecretName, + Namespace: namespace, + }, + Data: map[string][]byte{ + secretKeyCredAccessKey: []byte(accessKey), + secretKeyCredSecretKey: []byte(secretKey), + }, + }) + if err == nil { + clients.OnClose(func() { + clients.Core.Secret().Delete(secret.Namespace, secret.Name, &metav1.DeleteOptions{}) + }) + return secret, nil + } else if apierrors.IsAlreadyExists(err) { + return clients.Core.Secret().Get(namespace, objectStoreCredSecretName, metav1.GetOptions{}) + } + return nil, err +} + +func createCloudCredentialSecret(clients *clients.Clients, namespace, name string, credentials *corev1.Secret) (*corev1.Secret, error) { + cc, err := clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{ + "accessKey": credentials.Data[secretKeyCredAccessKey], + "secretKey": credentials.Data[secretKeyCredSecretKey], + }, + }) + if apierrors.IsAlreadyExists(err) { + return clients.Core.Secret().Get(namespace, name, metav1.GetOptions{}) + } else if err == nil { + clients.OnClose(func() { + clients.Core.Secret().Delete(namespace, name, &metav1.DeleteOptions{}) + }) + } + return cc, err +} + +func createHelperConfigmap(clients *clients.Clients, namespace, objectStore, bucketName string) (*corev1.ConfigMap, error) { + objectStoreHelperCMName := objectStore + "-helper" + cm, err := clients.Core.ConfigMap().Get(namespace, objectStoreHelperCMName, metav1.GetOptions{}) + if err == nil { + return cm, nil + } else if !apierrors.IsNotFound(err) { + return nil, err + } + + cm, err = clients.Core.ConfigMap().Create(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: objectStoreHelperCMName, + Namespace: namespace, + }, + Data: map[string]string{ + "setup.sh": fmt.Sprintf(setupMinioBucket, secretKeyCredAccessKey, secretKeyCredSecretKey, bucketName), + }, + }) + if apierrors.IsAlreadyExists(err) { + return clients.Core.ConfigMap().Get(namespace, objectStoreHelperCMName, metav1.GetOptions{}) + } else if err == nil { + clients.OnClose(func() { + clients.Core.ConfigMap().Delete(cm.Namespace, cm.Name, &metav1.DeleteOptions{}) + }) + } + return cm, err +} + +func createService(clients *clients.Clients, namespace, objectStore string) (*corev1.Service, error) { + svc, err := clients.Core.Service().Create(&corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: objectStore, + Namespace: namespace, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{ + Name: "http", + Protocol: corev1.ProtocolTCP, + AppProtocol: &[]string{"https"}[0], + Port: 9000, + TargetPort: intstr.FromInt(9000), + }}, + Selector: map[string]string{ + "app": objectStore, + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + svc, err = clients.Core.Service().Get(namespace, objectStore, metav1.GetOptions{}) + if err != nil { + return nil, err + } + } + + clients.OnClose(func() { + clients.Core.Service().Delete(svc.Namespace, svc.Name, &metav1.DeleteOptions{}) + }) + + err = wait.Object(clients.Ctx, clients.Core.Service().Watch, svc, func(obj runtime.Object) (bool, error) { + latestSvc := obj.(*corev1.Service) + if latestSvc.Spec.ClusterIP != "" { + svc = latestSvc + return true, nil + } + return false, nil + }) + if err != nil { + return nil, err + } + + return svc, err +} + +func getPod(clients *clients.Clients, namespace, objectStore string) (*corev1.Pod, error) { + objectStoreCredSecretName := objectStore + "-cred" + objectStoreTLSSecretName := objectStore + "-tls" + objectStoreHelperCMName := objectStore + "-helper" + pod, err := clients.Core.Pod().Get(namespace, objectStore, metav1.GetOptions{}) + if err == nil || !apierrors.IsNotFound(err) { + return pod, err + } + + pod, err = clients.Core.Pod().Create(&corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: objectStore, + Namespace: namespace, + Labels: map[string]string{ + "app": objectStore, + }, + }, + Spec: corev1.PodSpec{ + EnableServiceLinks: new(bool), + Volumes: []corev1.Volume{ + { + Name: "tls", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: objectStoreTLSSecretName, + }, + }, + }, + { + Name: "cred", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: objectStoreCredSecretName, + }, + }, + }, + { + Name: "helper", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: objectStoreHelperCMName, + }, + }, + }, + }, + }, + Containers: []corev1.Container{ + { + Name: "minio", + Image: defaults.ObjectStoreServerImage, + Env: []corev1.EnvVar{}, + Command: []string{ + "/bin/bash", + "-c", + }, + Args: []string{ + "minio server /data --certs-dir /etc/minio/tls", + }, + EnvFrom: []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: objectStoreCredSecretName, + }, + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "tls", + MountPath: "/etc/minio/tls/" + secretKeyTLSPrivateKey, + SubPath: secretKeyTLSPrivateKey, + }, + { + Name: "tls", + MountPath: "/etc/minio/tls/" + secretKeyTLSPublicCrt, + SubPath: secretKeyTLSPublicCrt, + }, + }, + Ports: []corev1.ContainerPort{ + { + ContainerPort: 9000, + }, + }, + }, + { + Name: "setupbucket", + Image: defaults.ObjectStoreUtilImage, + Command: []string{ + "/bin/bash", + "-x", + }, + EnvFrom: []corev1.EnvFromSource{ + { + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: objectStoreCredSecretName, + }, + }, + }, + }, + Args: []string{ + "/helper/setup.sh", + }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "helper", + ReadOnly: true, + MountPath: "/helper", + }}, + }, + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + return clients.Core.Pod().Get(namespace, objectStore, metav1.GetOptions{}) + } else if err == nil { + clients.OnClose(func() { + clients.Core.Pod().Delete(pod.Namespace, pod.Name, &metav1.DeleteOptions{}) + }) + } + return pod, err +} + +type Info struct { + AccessKey, SecretKey, Bucket, Endpoint, Cert, CloudCredentialName string +} + +func GetObjectStore(clients *clients.Clients, namespace, identifier, bucket string) (Info, error) { + objectStoreLock.Lock() + defer objectStoreLock.Unlock() + hid := name.Hex(identifier, 5) + objectStore := name.SafeConcatName("objectstore", hid) + + cs, err := createCredSecret(clients, namespace, objectStore) + if err != nil { + return Info{}, err + } + + ccName := name.SafeConcatName("cc", objectStore) + cc, err := createCloudCredentialSecret(clients, namespace, ccName, cs) + if err != nil { + return Info{}, err + } + + _, err = createHelperConfigmap(clients, namespace, objectStore, bucket) + if err != nil { + return Info{}, err + } + + svc, err := createService(clients, namespace, objectStore) + if err != nil { + return Info{}, err + } + + tls, err := createTLSSecret(clients, namespace, objectStore, fmt.Sprintf(objectStoreServiceNameTemplate, objectStore, namespace), svc.Spec.ClusterIP) + if err != nil { + return Info{}, err + } + + pod, err := getPod(clients, namespace, objectStore) + if err != nil { + return Info{}, err + } + + err = wait.Object(clients.Ctx, clients.Core.Pod().Watch, pod, func(obj runtime.Object) (bool, error) { + pod := obj.(*corev1.Pod) + return pod.Status.PodIP != "" && pod.Status.Phase == corev1.PodRunning, nil + }) + if err != nil { + return Info{}, err + } + + return Info{ + AccessKey: string(cs.Data[secretKeyCredAccessKey]), + SecretKey: string(cs.Data[secretKeyCredSecretKey]), + Bucket: bucket, + Endpoint: fmt.Sprintf("%s:9000", svc.Spec.ClusterIP), + Cert: base64.StdEncoding.EncodeToString(tls.Data[secretKeyTLSPublicCrt]), + CloudCredentialName: cc.Name, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/certificaterotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/certificaterotation.go new file mode 100644 index 0000000..8971be2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/certificaterotation.go @@ -0,0 +1,74 @@ +package operations + +import ( + "context" + "testing" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +// RunCertificateRotationTest expects a "created" v2prov cluster and will run a certificate rotation on it and perform assertions. +func RunCertificateRotationTest(t *testing.T, clients *clients.Clients, c *v1.Cluster) { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.RotateCertificates = &rkev1.RotateCertificates{ + Generation: 1, + } + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "rotate certificates", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return rkeControlPlane.Status.CertificateRotationGeneration == 1 && capr.Reconciled.IsTrue(rkeControlPlane.Status), nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + clientset, err := GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + _, err = clientset.CoreV1().ConfigMaps(corev1.NamespaceDefault).Create(context.TODO(), &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myspecialconfigmap", + }, + Data: map[string]string{ + "test": "wow", + }, + }, metav1.CreateOptions{}) + if err != nil { + t.Fatal(err) + } + + configMap, err := clientset.CoreV1().ConfigMaps(corev1.NamespaceDefault).Get(context.TODO(), "myspecialconfigmap", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + assert.NotNil(t, configMap) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/downstream_kc.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/downstream_kc.go new file mode 100644 index 0000000..d2ffbbe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/downstream_kc.go @@ -0,0 +1,60 @@ +package operations + +import ( + "context" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/controllers/dashboardapi/settings" + "github.com/rancher/rancher/pkg/provisioningv2/kubeconfig" + "github.com/rancher/rancher/pkg/wrangler" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/defaults" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/util/retry" +) + +func getDownstreamClientset(clients *clients.Clients, c *v1.Cluster) (*kubernetes.Clientset, error) { + wContext, err := wrangler.NewContext(context.TODO(), clients.ClientConfig, clients.RESTConfig) + if err != nil { + return nil, err + } + // Register settings so that the provider is set and we can retrieve the internal server URL + CA for the kubeconfig manager below. + err = settings.Register(wContext.Mgmt.Setting()) + if err != nil { + return nil, err + } + kcManager := kubeconfig.New(wContext) + + // Get kubeconfig for the downstream cluster to create test resources + restConfig, err := kcManager.GetRESTConfig(c, c.Status) + if err != nil { + return nil, err + } + + return kubernetes.NewForConfig(restConfig) +} + +func GetAndVerifyDownstreamClientset(clients *clients.Clients, c *v1.Cluster) (*kubernetes.Clientset, error) { + clientset, err := getDownstreamClientset(clients, c) + if err != nil { + return nil, err + } + // Try to continuously get the kubernetes default service + err = retry.OnError(defaults.DownstreamRetry, func(err error) bool { + if apierrors.IsForbidden(err) { + return false + } + return true + }, func() error { + _, err = clientset.CoreV1().Services(corev1.NamespaceDefault).Get(context.TODO(), "kubernetes", metav1.GetOptions{}) + return err + }) + if err != nil { + return nil, err + } + + return clientset, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/encryptionkeyrotation.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/encryptionkeyrotation.go new file mode 100644 index 0000000..f1984d7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/encryptionkeyrotation.go @@ -0,0 +1,75 @@ +package operations + +import ( + "context" + "testing" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +func RunRotateEncryptionKeysTest(t *testing.T, clients *clients.Clients, c *v1.Cluster) { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.RotateEncryptionKeys = &rkev1.RotateEncryptionKeys{ + Generation: 1, + } + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "rotate encryption keys", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return rkeControlPlane.Status.RotateEncryptionKeys != nil && rkeControlPlane.Status.RotateEncryptionKeys.Generation == 1 && capr.Reconciled.IsTrue(rkeControlPlane.Status), nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + clientset, err := GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + configmapName := "my-configmap-" + name.Hex(time.Now().String(), 10) + + _, err = clientset.CoreV1().ConfigMaps(corev1.NamespaceDefault).Create(context.TODO(), &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configmapName, + }, + Data: map[string]string{ + "test": "wow", + }, + }, metav1.CreateOptions{}) + if err != nil { + t.Fatal(err) + } + + configMap, err := clientset.CoreV1().ConfigMaps(corev1.NamespaceDefault).Get(context.TODO(), configmapName, metav1.GetOptions{}) + assert.NoError(t, err) + assert.NotNil(t, configMap) + assert.Equal(t, configmapName, configMap.Name) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/etcdsnapshot.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/etcdsnapshot.go new file mode 100644 index 0000000..4d8d194 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/etcdsnapshot.go @@ -0,0 +1,320 @@ +package operations + +import ( + "context" + "crypto/sha256" + "encoding/base32" + "fmt" + "regexp" + "sort" + "strconv" + "strings" + "testing" + "time" + + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" +) + +func RunSnapshotCreateTest(t *testing.T, clients *clients.Clients, c *v1.Cluster, configMap corev1.ConfigMap, targetNode string) *rkev1.ETCDSnapshot { + defer func() { + if t.Failed() { + data, newErr := cluster.GatherDebugData(clients, c) + if newErr != nil { + logrus.Error(newErr) + } + fmt.Printf("cluster %s etcd snapshot creation operation failed\ncluster %s test data bundle: \n%s", c.Name, c.Name, data) + } + }() + + clientset, err := GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + ns := corev1.NamespaceDefault + + if configMap.Namespace != "" { + ns = configMap.Namespace + } + _, err = clientset.CoreV1().ConfigMaps(ns).Create(context.TODO(), &configMap, metav1.CreateOptions{}) + if err != nil { + t.Fatal(err) + } + + _, err = clientset.CoreV1().ConfigMaps(ns).Get(context.TODO(), configMap.Name, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + hasher := sha256.New() + hasher.Write([]byte(fmt.Sprintf("system://provisioning/%s/%s", c.Namespace, c.Name))) + sha := base32.StdEncoding.WithPadding(-1).EncodeToString(hasher.Sum(nil))[:10] + ciSAName := "cattle-impersonation-u-" + strings.ToLower(sha) + + if err := retry.OnError(retry.DefaultRetry, func(err error) bool { + if apierrors.IsNotFound(err) || err == nil { + return true + } + return false + }, func() error { + _, e := clientset.CoreV1().ServiceAccounts("cattle-impersonation-system").Get(context.TODO(), ciSAName, metav1.GetOptions{}) + if e != nil { + return e + } + return nil + }); err != nil { + t.Fatal(err) + } + + // Create an etcd snapshot + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.ETCDSnapshotCreate = &rkev1.ETCDSnapshotCreate{ + Generation: 1, + } + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }); err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "first etcd snapshot creation", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return rkeControlPlane.Status.ETCDSnapshotCreate != nil && rkeControlPlane.Status.ETCDSnapshotCreate.Generation == 1 && rkeControlPlane.Status.ETCDSnapshotCreatePhase == rkev1.ETCDSnapshotPhaseFinished && capr.Ready.IsTrue(rkeControlPlane), nil + }) + if err != nil { + t.Fatal(err) + } + + // Workaround in response to K3s/RKE2 bug around etcd snapshot configmap existence: https://github.com/k3s-io/k3s/issues/9047 + if err := retry.OnError(wait.Backoff{ + Steps: 10, + Duration: 30 * time.Second, + Factor: 1.0, + Jitter: 0.1, + }, func(err error) bool { + if apierrors.IsForbidden(err) { + return false + } + return true + }, + func() error { + clientset, err = GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + return err + } + etcdSnapshotsConfigMap, err := clientset.CoreV1().ConfigMaps("kube-system").Get(clients.Ctx, fmt.Sprintf("%s-etcd-snapshots", capr.GetRuntime(c.Spec.KubernetesVersion)), metav1.GetOptions{}) + if err != nil { + return err + } + if etcdSnapshotsConfigMap != nil && len(etcdSnapshotsConfigMap.Data) > 0 { + return nil + } + return fmt.Errorf("etcd snapshots config map was not usable") + }); err != nil { + t.Fatal(err) + } + + snapshotsValidTime := time.Now() + + // Create a second etcd snapshot + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.ETCDSnapshotCreate = &rkev1.ETCDSnapshotCreate{ + Generation: 2, + } + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }); err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "second etcd snapshot creation", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return rkeControlPlane.Status.ETCDSnapshotCreate != nil && rkeControlPlane.Status.ETCDSnapshotCreate.Generation == 2 && rkeControlPlane.Status.ETCDSnapshotCreatePhase == rkev1.ETCDSnapshotPhaseFinished && capr.Ready.IsTrue(rkeControlPlane), nil + }) + if err != nil { + t.Fatal(err) + } + + var snapshot *rkev1.ETCDSnapshot + re := regexp.MustCompile(".*-([0-9]+)$") + // Get the etcd snapshot object + if err := retry.OnError(wait.Backoff{ + Steps: 30, + Duration: 30 * time.Second, + Factor: 1.0, + Jitter: 0.1, + }, func(err error) bool { + if apierrors.IsForbidden(err) { + return false + } + return true + }, + func() error { + snapshotsList, err := clients.RKE.ETCDSnapshot().List(c.Namespace, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", capr.ClusterNameLabel, c.Name)}) + if err != nil { + return err + } + var snapshots []*rkev1.ETCDSnapshot + // Parse the snapshot time from the snapshot file name + for _, s := range snapshotsList.Items { + if s.SnapshotFile.NodeName == targetNode && s.SnapshotFile.Size > 0 { + // Workaround in response to K3s/RKE2 bug around etcd snapshot configmap existence: https://github.com/k3s-io/k3s/issues/9047 + // Ensure that there are at least 2 snapshots for the given target node, as the first snapshot is not usable. + spec, err := capr.ParseSnapshotClusterSpecOrError(&s) + if err != nil || spec == nil { + continue // ignore errors parsing the snapshot + } + // Parse the unix time out of the snapshot file name as CreatedAt is not set on S3 snapshots on older K3s/RKE2 versions + matches := re.FindStringSubmatch(s.SnapshotFile.Name) + if len(matches) != 2 { + continue + } + rawTime, err := strconv.ParseInt(matches[1], 10, 64) + if err != nil { + continue + } + snapshotTime := metav1.NewTime(time.Unix(rawTime, 0)) + // Only count snapshots that were created after the first snapshots were taken. + if snapshotTime.After(snapshotsValidTime) { + sCopy := s.DeepCopy() + if sCopy.SnapshotFile.CreatedAt == nil { + sCopy.SnapshotFile.CreatedAt = &snapshotTime + } + snapshots = append(snapshots, s.DeepCopy()) + } + } + } + if len(snapshots) > 0 { + sort.Slice(snapshots, func(i, j int) bool { + return snapshots[i].SnapshotFile.CreatedAt.Before(snapshots[j].SnapshotFile.CreatedAt) + }) + snapshot = snapshots[len(snapshots)-1] + return nil + } + + return fmt.Errorf("snapshot of target was not found") + }); err != nil { + t.Fatal(err) + } + + assert.NotNil(t, snapshot) + assert.NotEqual(t, "failed", strings.ToLower(snapshot.SnapshotFile.Status)) + + err = clientset.CoreV1().ConfigMaps(ns).Delete(context.TODO(), configMap.Name, metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + newCM, expectedErr := clientset.CoreV1().ConfigMaps(ns).Get(context.TODO(), configMap.Name, metav1.GetOptions{}) + if !apierrors.IsNotFound(expectedErr) { + t.Fatal(expectedErr) + } + + // The client will return a configmap object but it will not have anything populated. + assert.Equal(t, "", newCM.Name) + return snapshot +} + +func RunSnapshotRestoreTest(t *testing.T, clients *clients.Clients, c *v1.Cluster, snapshotName string, expectedConfigMap corev1.ConfigMap, expectedNodeCount int) { + defer func() { + if t.Failed() { + data, newErr := cluster.GatherDebugData(clients, c) + if newErr != nil { + logrus.Error(newErr) + } + fmt.Printf("cluster %s etcd snapshot restore operation failed\ncluster %s test data bundle: \n%s", c.Name, c.Name, data) + } + }() + + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.ETCDSnapshotRestore = &rkev1.ETCDSnapshotRestore{ + Name: snapshotName, + Generation: 1, + RestoreRKEConfig: "none", + } + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "etcd snapshot restore", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return rkeControlPlane.Status.ETCDSnapshotRestorePhase == rkev1.ETCDSnapshotPhaseFinished && capr.Ready.IsTrue(rkeControlPlane), nil + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + clientset, err := GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + ns := corev1.NamespaceDefault + + if expectedConfigMap.Namespace != "" { + ns = expectedConfigMap.Namespace + } + + // Check for the configmap! + retrievedConfigMap, err := clientset.CoreV1().ConfigMaps(ns).Get(context.TODO(), expectedConfigMap.Name, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, expectedConfigMap.Name, retrievedConfigMap.Name) + assert.Equal(t, expectedConfigMap.Data, retrievedConfigMap.Data) + + allNodes, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + t.Fatal(err) + } + + // Nodes can be left in a `Deleting` state, so only check that our expected node count equals the number of nodes that are not deleting. + nonDeletingNodes := 0 + for _, n := range allNodes.Items { + if n.GetDeletionTimestamp() == nil { + nonDeletingNodes++ + } + } + assert.Equal(t, expectedNodeCount, nonDeletingNodes) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/scale.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/scale.go new file mode 100644 index 0000000..3193c30 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/operations/scale.go @@ -0,0 +1,34 @@ +package operations + +import ( + v1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/util/retry" +) + +func Scale(clients *clients.Clients, c *v1.Cluster, index int, quantity int32, waitForCreate bool) (*v1.Cluster, error) { + err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + newC, err := clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + if err != nil { + return err + } + newC.Spec.RKEConfig.MachinePools[index].Quantity = &quantity + newC, err = clients.Provisioning.Cluster().Update(newC) + if err != nil { + return err + } + c = newC + return nil + }) + + if err != nil { + return c, err + } + + if waitForCreate { + return cluster.WaitForCreate(clients, c) + } + return c, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/registry/registry.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/registry/registry.go new file mode 100644 index 0000000..11b9160 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/registry/registry.go @@ -0,0 +1,276 @@ +package registry + +import ( + "fmt" + "sync" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/rke/pki/cert" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" +) + +var ( + registryNamespace = "default" + cacheLock sync.Mutex +) + +func newRegistryServiceName(baseName string) string { + return fmt.Sprintf("%s.default.svc.cluster.local", baseName) +} + +func createPasswordSecret(clients *clients.Clients, namespace string) (*corev1.Secret, error) { + secret, err := clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "registry-secret-", + Namespace: namespace, + }, + StringData: map[string]string{ + "username": "admin", + "password": "admin", + }, + Type: "rke.cattle.io/auth-config", + }) + if err != nil { + return nil, err + } + clients.OnClose(func() { + _ = clients.Core.Secret().Delete(namespace, secret.Name, nil) + }) + return secret, nil +} + +func createTLSSecret(clients *clients.Clients, namespace string, registryTLSSecret *corev1.Secret) (*corev1.Secret, error) { + secret, err := clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "registry-secret-", + Namespace: namespace, + }, + Data: registryTLSSecret.Data, + Type: corev1.SecretTypeTLS, + }) + if err != nil { + return nil, err + } + clients.OnClose(func() { + _ = clients.Core.Secret().Delete(namespace, secret.Name, nil) + }) + return secret, nil +} + +func createRegistrySecret(clients *clients.Clients, podName string) (*corev1.Secret, error) { + secret, err := clients.Core.Secret().Get(registryNamespace, podName, metav1.GetOptions{}) + if err == nil { + return secret, nil + } else if !apierrors.IsNotFound(err) { + return nil, err + } + + cert, key, err := cert.GenerateSelfSignedCertKey(newRegistryServiceName(podName), nil, nil) + if err != nil { + return nil, err + } + + secret, err = clients.Core.Secret().Create(&corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + Namespace: registryNamespace, + }, + Data: map[string][]byte{ + // admin:admin + "htpasswd": []byte("admin:$2y$05$vhD/ZtPIUBFrSR4BRyWaDeWAj7NOa5/xZRCjijO6XRRBaiRTLQ/76"), + corev1.TLSCertKey: cert, + corev1.TLSPrivateKeyKey: key, + }, + }) + if err == nil { + return secret, nil + } else if apierrors.IsAlreadyExists(err) { + return clients.Core.Secret().Get(registryNamespace, podName, metav1.GetOptions{}) + } + return nil, err +} + +func createService(clients *clients.Clients, name string) error { + _, err := clients.Core.Service().Create(&corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: registryNamespace, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{ + Name: "http", + Protocol: corev1.ProtocolTCP, + AppProtocol: &[]string{"https"}[0], + Port: 5000, + TargetPort: intstr.FromInt(5000), + }}, + Selector: map[string]string{ + "app": name, + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + return nil + } + return err +} + +func createOrGetPod(clients *clients.Clients, podName string, pullThrough bool) (*corev1.Pod, error) { + pod, err := clients.Core.Pod().Get(registryNamespace, podName, metav1.GetOptions{}) + if err == nil || !apierrors.IsNotFound(err) { + return pod, err + } + + podEnv := []corev1.EnvVar{ + { + Name: "REGISTRY_AUTH", + Value: "htpasswd", + }, + { + Name: "REGISTRY_AUTH_HTPASSWD_REALM", + Value: "Registry Realm", + }, + { + Name: "REGISTRY_AUTH_HTPASSWD_PATH", + Value: "/etc/auth/htpasswd", + }, + { + Name: "REGISTRY_HTTP_TLS_CERTIFICATE", + Value: "/etc/auth/tls.crt", + }, + { + Name: "REGISTRY_HTTP_TLS_KEY", + Value: "/etc/auth/tls.key", + }, + } + + // Configure the pod as a pull-through cache, if necessary. When proxy.remoteUrl on the registry config, it will + // act as a proxy for the upstream registry and cache images it downloads, but you will not be able to push images + // to it! For that, you'd need another registry. + if pullThrough { + podEnv = append(podEnv, corev1.EnvVar{ + Name: "REGISTRY_PROXY_REMOTEURL", + Value: "https://registry-1.docker.io", + }) + } + + pod, err = clients.Core.Pod().Create(&corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + Namespace: registryNamespace, + Labels: map[string]string{ + "app": podName, + }, + }, + Spec: corev1.PodSpec{ + EnableServiceLinks: new(bool), + Volumes: []corev1.Volume{{ + Name: "htpasswd", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: podName, + }, + }, + }}, + Containers: []corev1.Container{ + { + Name: "cache", + Image: "registry", + Env: podEnv, + VolumeMounts: []corev1.VolumeMount{{ + Name: "htpasswd", + ReadOnly: true, + MountPath: "/etc/auth", + }}, + }, + }, + }, + }) + if apierrors.IsAlreadyExists(err) { + return clients.Core.Pod().Get(registryNamespace, podName, metav1.GetOptions{}) + } + return pod, err +} + +func createSharedObjects(clients *clients.Clients, podName string, pullThrough bool) (*corev1.Secret, error) { + cacheLock.Lock() + defer cacheLock.Unlock() + + registrySecret, err := createRegistrySecret(clients, podName) + if err != nil { + return nil, err + } + + pod, err := createOrGetPod(clients, podName, pullThrough) + if err != nil { + return nil, err + } + + err = createService(clients, podName) + if err != nil { + return nil, err + } + + err = wait.Object(clients.Ctx, clients.Core.Pod().Watch, pod, func(obj runtime.Object) (bool, error) { + pod := obj.(*corev1.Pod) + return pod.Status.PodIP != "" && pod.Status.Phase == corev1.PodRunning, nil + }) + return registrySecret, err +} + +// CreateOrGetRegistry gets existing registry config, or creates a new one and returns the config. The registry will +// be created with the given name in the "default" namespace, and its secrets will be created in the given namespace so +// that pods created in that namespace can rely on images sourced from the new registry. If pullThrough is set to true, +// the registry will be configured as a proxy (a.k.a pull-through cache) for docker.io. +func CreateOrGetRegistry(clients *clients.Clients, namespace, name string, pullThrough bool) (rkev1.Registry, error) { + registrySecret, err := createSharedObjects(clients, name, pullThrough) + if err != nil { + return rkev1.Registry{}, err + } + + passwordSecret, err := createPasswordSecret(clients, namespace) + if err != nil { + return rkev1.Registry{}, err + } + + tlsSecret, err := createTLSSecret(clients, namespace, registrySecret) + if err != nil { + return rkev1.Registry{}, err + } + + serviceName := newRegistryServiceName(name) + + // Specify dummy.io registries to ensure we can deliver the same data twice without thrashing. + return rkev1.Registry{ + Mirrors: map[string]rkev1.Mirror{ + "docker.io": { + Endpoints: []string{ + fmt.Sprintf("https://%s:5000", serviceName), + }, + }, + "dummy.cattle.io": { + Endpoints: []string{ + "https://dummy.cattle.io", + }, + }, + }, + Configs: map[string]rkev1.RegistryConfig{ + serviceName + ":5000": { + AuthConfigSecretName: passwordSecret.Name, + TLSSecretName: tlsSecret.Name, + CABundle: tlsSecret.Data[corev1.TLSCertKey], + }, + "dummy.cattle.io": { + AuthConfigSecretName: passwordSecret.Name, + TLSSecretName: tlsSecret.Name, + CABundle: tlsSecret.Data[corev1.TLSCertKey], + }, + }, + }, nil +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/systemdnode/systemnode.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/systemdnode/systemnode.go new file mode 100644 index 0000000..3a3755f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/systemdnode/systemnode.go @@ -0,0 +1,161 @@ +package systemdnode + +import ( + "fmt" + "strings" + + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/defaults" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// New is used to create a new instance of systemd-node as a pod in a Kubernetes cluster. Notably, this is used for the +// v2prov integration tests for custom clusters to simulate custom cluster nodes. If extraDirs is defined, it expects a slice of elements of format "host-source:pod-mount". +func New(clients *clients.Clients, namespace, script string, labels map[string]string, extraDirs []string) (*corev1.Pod, error) { + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + GenerateName: "test-node-data-", + }, + Data: map[string]string{ + "user-data": script, + }, + } + cm, err := clients.Core.ConfigMap().Create(cm) + if err != nil { + return nil, err + } + + // We are providing the following files/configmap in order to force K3s/RKE2 to use the cgroupfs cgroup driver, + // rather than systemd. + cmConfigure := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + GenerateName: "test-node-configure-systemd-", + }, + Data: map[string]string{ + "disable": `INVOCATION_ID= +`}, + } + cmConfigure, err = clients.Core.ConfigMap().Create(cmConfigure) + if err != nil { + return nil, err + } + + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + GenerateName: "test-node-", + Labels: labels, + }, + Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "seed", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cm.Name, + }, + }, + }, + }, + { + Name: "systemd", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: cmConfigure.Name, + }, + }, + }, + }, + }, + Containers: []corev1.Container{{ + Name: "container", + Image: defaults.PodTestImage, + SecurityContext: &corev1.SecurityContext{ + Privileged: &[]bool{true}[0], + }, + Stdin: true, + StdinOnce: true, + TTY: true, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "seed", + MountPath: "/var/lib/cloud/seed/nocloud/user-data", + SubPath: "user-data", + }, + { // We have to set invocation disabling on the rancher-system-agent because it runs rke2/k3s server on restore and this has cgroup issues + Name: "systemd", + MountPath: "/etc/default/rancher-system-agent", + SubPath: "disable", + }, + { + Name: "systemd", + MountPath: "/etc/default/rke2-server", + SubPath: "disable", + }, + { + Name: "systemd", + MountPath: "/etc/default/rke2-agent", + SubPath: "disable", + }, + { + Name: "systemd", + MountPath: "/etc/default/k3s", + SubPath: "disable", + }, + { + Name: "systemd", + MountPath: "/etc/default/k3s-agent", + SubPath: "disable", + }, + }, + }}, + AutomountServiceAccountToken: new(bool), + }, + } + + for i, v := range extraDirs { + hostSource, mountPath, ok := strings.Cut(v, ":") + if !ok { + // TODO: log + continue + } + pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ + Name: fmt.Sprintf("extra-directory-%d", i), + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: hostSource, + Type: &[]corev1.HostPathType{corev1.HostPathDirectoryOrCreate}[0], + }, + }, + }) + + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{ + Name: fmt.Sprintf("extra-directory-%d", i), + MountPath: mountPath, + }) + + } + + pod, err = clients.Core.Pod().Create(pod) + if err != nil { + return nil, err + } + clients.OnClose(func() { + clients.Core.Pod().Delete(pod.Namespace, pod.Name, nil) + }) + + cm.OwnerReferences = []metav1.OwnerReference{{ + APIVersion: "v1", + Kind: "Pod", + Name: pod.Name, + UID: pod.UID, + }} + + _, err = clients.Core.ConfigMap().Update(cm) + return pod, err +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/custom_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/custom_test.go new file mode 100644 index 0000000..fe43969 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/custom_test.go @@ -0,0 +1,328 @@ +package custom + +import ( + "encoding/json" + "os" + "strings" + "testing" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Provisioning_Custom_OneNodeWithDelete(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-one-node", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker --etcd --controlplane --label foo=bar --label ball=life", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Len(t, machines.Items, 1) + assert.Equal(t, machines.Items[0].Labels[capr.WorkerRoleLabel], "true") + assert.Equal(t, machines.Items[0].Labels[capr.ControlPlaneRoleLabel], "true") + assert.Equal(t, machines.Items[0].Labels[capr.EtcdRoleLabel], "true") + assert.Len(t, machines.Items[0].Status.Addresses, 2) + assert.NotNil(t, machines.Items[0].Spec.Bootstrap.ConfigRef) + + secret, err := clients.Core.Secret().Get(machines.Items[0].Namespace, capr.PlanSecretFromBootstrapName(machines.Items[0].Spec.Bootstrap.ConfigRef.Name), metav1.GetOptions{}) + assert.NoError(t, err) + + assert.NotEmpty(t, secret.Annotations[capr.LabelsAnnotation]) + var labels map[string]string + if err := json.Unmarshal([]byte(secret.Annotations[capr.LabelsAnnotation]), &labels); err != nil { + t.Error(err) + } + assert.Equal(t, labels, map[string]string{"cattle.io/os": "linux", "foo": "bar", "ball": "life"}) + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } + + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_Custom_ThreeNode(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-three-node", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + for i := 0; i < 3; i++ { + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker --etcd --controlplane --label rancher=awesome", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Len(t, machines.Items, 3) + for _, m := range machines.Items { + assert.Equal(t, m.Labels[capr.WorkerRoleLabel], "true") + assert.Equal(t, m.Labels[capr.ControlPlaneRoleLabel], "true") + assert.Equal(t, m.Labels[capr.EtcdRoleLabel], "true") + assert.NotNil(t, machines.Items[0].Spec.Bootstrap.ConfigRef) + + secret, err := clients.Core.Secret().Get(machines.Items[0].Namespace, capr.PlanSecretFromBootstrapName(machines.Items[0].Spec.Bootstrap.ConfigRef.Name), metav1.GetOptions{}) + assert.NoError(t, err) + + assert.NotEmpty(t, secret.Annotations[capr.LabelsAnnotation]) + var labels map[string]string + if err := json.Unmarshal([]byte(secret.Annotations[capr.LabelsAnnotation]), &labels); err != nil { + t.Error(err) + } + assert.Equal(t, labels, map[string]string{"cattle.io/os": "linux", "rancher": "awesome"}) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_Custom_UniqueRoles(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-unique-roles", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + for i := 0; i < 3; i++ { + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + } + + for i := 0; i < 1; i++ { + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Len(t, machines.Items, 5) + var ( + worker = 0 + controlPlane = 0 + etcd = 0 + ) + for _, m := range machines.Items { + if m.Labels[capr.WorkerRoleLabel] == "true" { + worker++ + } + if m.Labels[capr.ControlPlaneRoleLabel] == "true" { + controlPlane++ + } + if m.Labels[capr.EtcdRoleLabel] == "true" { + etcd++ + } + } + + assert.Equal(t, worker, 1) + assert.Equal(t, etcd, 3) + assert.Equal(t, controlPlane, 1) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_Custom_ThreeNodeWithTaints(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-three-node-with-taints", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + for i := 0; i < 3; i++ { + var taint string + // Put a taint on one of the nodes. + if i == 1 { + taint = " --taint key=value:NoExecute" + } + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker --etcd --controlplane --label rancher=awesome"+taint, map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + var taintFound bool + assert.Len(t, machines.Items, 3) + for _, m := range machines.Items { + assert.Equal(t, m.Labels[capr.WorkerRoleLabel], "true") + assert.Equal(t, m.Labels[capr.ControlPlaneRoleLabel], "true") + assert.Equal(t, m.Labels[capr.EtcdRoleLabel], "true") + assert.NotNil(t, m.Spec.Bootstrap.ConfigRef) + + secret, err := clients.Core.Secret().Get(m.Namespace, capr.PlanSecretFromBootstrapName(m.Spec.Bootstrap.ConfigRef.Name), metav1.GetOptions{}) + assert.NoError(t, err) + + assert.NotEmpty(t, secret.Annotations[capr.LabelsAnnotation]) + var labels map[string]string + if err := json.Unmarshal([]byte(secret.Annotations[capr.LabelsAnnotation]), &labels); err != nil { + t.Error(err) + } + assert.Equal(t, labels, map[string]string{"cattle.io/os": "linux", "rancher": "awesome"}) + + if len(secret.Annotations[capr.TaintsAnnotation]) != 0 { + // Only one node should have the taint + assert.False(t, taintFound) + + var taints []corev1.Taint + if err := json.Unmarshal([]byte(secret.Annotations[capr.TaintsAnnotation]), &taints); err != nil { + t.Error(err) + } + + assert.Equal(t, len(taints), 1) + assert.Equal(t, taints[0].Key, "key") + assert.Equal(t, taints[0].Value, "value") + assert.Equal(t, taints[0].Effect, corev1.TaintEffect("NoExecute")) + taintFound = true + } + } + + assert.True(t, taintFound) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_certificaterotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_certificaterotation_test.go new file mode 100644 index 0000000..20443e8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_certificaterotation_test.go @@ -0,0 +1,65 @@ +package custom + +import ( + "github.com/rancher/rancher/tests/v2prov/operations" + "testing" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Operation_SetA_Custom_CertificateRotation(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-certificate-rotation-operations", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + operations.RunCertificateRotationTest(t, clients, c) + + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_encryptionkeyrotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_encryptionkeyrotation_test.go new file mode 100644 index 0000000..e4ab73b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_encryptionkeyrotation_test.go @@ -0,0 +1,71 @@ +package custom + +import ( + "os" + "strings" + "testing" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Operation_SetA_Custom_EncryptionKeyRotation(t *testing.T) { + // Encryption Key rotation is only possible with "stock configuration" on RKE2. + if strings.ToLower(os.Getenv("DIST")) != "rke2" { + t.Skip("encryption key rotation") + } + + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-encryption-key-rotation-operations", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{}, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + operations.RunRotateEncryptionKeysTest(t, clients, c) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_inplace_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_inplace_test.go new file mode 100644 index 0000000..3de6047 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_inplace_test.go @@ -0,0 +1,83 @@ +package custom + +import ( + "testing" + "time" + + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Test_Operation_SetA_Custom_EtcdSnapshotCreationRestoreInPlace creates a custom 2 node cluster with a controlplane+worker and +// etcd node, creates a configmap, takes a snapshot of the cluster, deletes the configmap, then restores from snapshot. +// This validates that it is possible to restore a snapshot. +func Test_Operation_SetA_Custom_EtcdSnapshotCreationRestoreInPlace(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-etcd-snapshot-operations-inplace", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker --controlplane", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd --node-name etcd-test-node", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, "etcd-test-node") + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.Name, cm, 2) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_combined_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_combined_test.go new file mode 100644 index 0000000..a6c05c9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_combined_test.go @@ -0,0 +1,142 @@ +package custom + +import ( + "fmt" + "os" + "strings" + "testing" + "time" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Test_Operation_SetB_Custom_EtcdSnapshotOperationsOnNewCombinedNode creates a custom 2 node cluster with a worker and +// controlplane+etcd node, creates a configmap, takes a snapshot of the cluster, deletes the configmap, then deletes the etcd machine/node +// It then creates a new controlplane+etcd node and restores from local snapshot file. This validates that it is possible to restore +// a snapshot on a completely new etcd node from file (without a corresponding snapshot file) +func Test_Operation_SetB_Custom_EtcdSnapshotOperationsOnNewCombinedNode(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-etcd-snapshot-operations-on-new-combined-node", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --worker", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + tmpDirSeed, err := randomtoken.Generate() + if err != nil { + t.Fatal(err) + } + tmpDir := os.TempDir() + "/snapshot-" + tmpDirSeed[:32] + + // store the snapshots in a universal directory + etcdSnapshotDir := []string{ + fmt.Sprintf("%s:/var/lib/rancher/%s/server/db/snapshots", tmpDir, capr.GetRuntime(c.Spec.KubernetesVersion)), + } + + var etcdNodePodName string + if etcdNode, err := systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane --etcd --node-name control-etcd-test-node", map[string]string{"custom-cluster-name": c.Name}, etcdSnapshotDir); err != nil { + t.Fatal(err) + } else { + etcdNodePodName = etcdNode.Name + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, "control-etcd-test-node") + assert.NotNil(t, snapshot) + + err = clients.Core.Pod().Delete(c.Namespace, etcdNodePodName, &metav1.DeleteOptions{PropagationPolicy: &[]metav1.DeletionPropagation{metav1.DeletePropagationForeground}[0]}) + if err != nil { + t.Fatal(err) + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Core.Pod().Get(c.Namespace, etcdNodePodName, metav1.GetOptions{}) + }); err != nil { + t.Fatal(err) + } + + // Delete the machine from the cluster too... + oldEtcdMachines, err := clients.CAPI.Machine().List(c.Namespace, metav1.ListOptions{LabelSelector: capr.EtcdRoleLabel + "=true"}) + if err != nil { + t.Fatal(err) + } + + for _, machine := range oldEtcdMachines.Items { + err = clients.CAPI.Machine().Delete(machine.Namespace, machine.Name, &metav1.DeleteOptions{PropagationPolicy: &[]metav1.DeletionPropagation{metav1.DeletePropagationForeground}[0]}) + if err != nil { + t.Fatal(err) + } + } + + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating insane cluster", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "waiting for at least one control plane, etcd, and worker node to be registered"), nil + }) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane --etcd", map[string]string{"custom-cluster-name": c.Name}, etcdSnapshotDir) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating restoration required", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "rkecontrolplane was already initialized but no etcd machines exist that have plans, indicating the etcd plane has been entirely replaced. Restoration from etcd snapshot is required."), nil + }) + + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.SnapshotFile.Name, cm, 2) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_test.go new file mode 100644 index 0000000..295fa92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/custom/operation_etcdsnapshot_newnode_test.go @@ -0,0 +1,142 @@ +package custom + +import ( + "fmt" + "os" + "strings" + "testing" + "time" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/rancher/tests/v2prov/systemdnode" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/rancher/wrangler/v3/pkg/randomtoken" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Test_Operation_SetB_Custom_EtcdSnapshotOperationsOnNewNode creates a custom 2 node cluster with a controlplane+worker and +// etcd node, creates a configmap, takes a snapshot of the cluster, deletes the configmap, then deletes the etcd machine/node +// It then creates a new etcd node and restores from local snapshot file. This validates that it is possible to restore +// a snapshot on a completely new etcd node from file (without a corresponding snapshot file) +func Test_Operation_SetB_Custom_EtcdSnapshotOperationsOnNewNode(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-custom-etcd-snapshot-operations-on-new-node", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + command, err := cluster.CustomCommand(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, command) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --controlplane --worker", map[string]string{"custom-cluster-name": c.Name}, nil) + if err != nil { + t.Fatal(err) + } + + tmpDirSeed, err := randomtoken.Generate() + if err != nil { + t.Fatal(err) + } + tmpDir := os.TempDir() + "/snapshot-" + tmpDirSeed[:32] + + // store the snapshots in a universal directory + etcdSnapshotDir := []string{ + fmt.Sprintf("%s:/var/lib/rancher/%s/server/db/snapshots", tmpDir, capr.GetRuntime(c.Spec.KubernetesVersion)), + } + + var etcdNodePodName string + if etcdNode, err := systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd --node-name etcd-test-node", map[string]string{"custom-cluster-name": c.Name}, etcdSnapshotDir); err != nil { + t.Fatal(err) + } else { + etcdNodePodName = etcdNode.Name + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, "etcd-test-node") + assert.NotNil(t, snapshot) + + err = clients.Core.Pod().Delete(c.Namespace, etcdNodePodName, &metav1.DeleteOptions{PropagationPolicy: &[]metav1.DeletionPropagation{metav1.DeletePropagationForeground}[0]}) + if err != nil { + t.Fatal(err) + } + + if err := wait.EnsureDoesNotExist(clients.Ctx, func() (runtime.Object, error) { + return clients.Core.Pod().Get(c.Namespace, etcdNodePodName, metav1.GetOptions{}) + }); err != nil { + t.Fatal(err) + } + + // Delete the machine from the cluster too... + oldEtcdMachines, err := clients.CAPI.Machine().List(c.Namespace, metav1.ListOptions{LabelSelector: capr.EtcdRoleLabel + "=true"}) + if err != nil { + t.Fatal(err) + } + + for _, machine := range oldEtcdMachines.Items { + err = clients.CAPI.Machine().Delete(machine.Namespace, machine.Name, &metav1.DeleteOptions{PropagationPolicy: &[]metav1.DeletionPropagation{metav1.DeletePropagationForeground}[0]}) + if err != nil { + t.Fatal(err) + } + } + + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating insane cluster", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "waiting for at least one control plane, etcd, and worker node to be registered"), nil + }) + + _, err = systemdnode.New(clients, c.Namespace, "#!/usr/bin/env sh\n"+command+" --etcd", map[string]string{"custom-cluster-name": c.Name}, etcdSnapshotDir) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating restoration required", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "rkecontrolplane was already initialized but no etcd machines exist that have plans, indicating the etcd plane has been entirely replaced. Restoration from etcd snapshot is required."), nil + }) + + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.SnapshotFile.Name, cm, 2) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/cluster_bootstrap_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/cluster_bootstrap_test.go new file mode 100644 index 0000000..aafe32c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/cluster_bootstrap_test.go @@ -0,0 +1,107 @@ +package fleetcluster_test + +import ( + "testing" + "time" + + fleetv1api "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + apimgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + provv1api "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Fleet_ClusterBootstrap(t *testing.T) { + const waitFor = 5 * time.Minute + const tick = 2 * time.Second + assert := assert.New(t) + require := require.New(t) + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + t.Run("fleet local cluster and cluster group present", func(t *testing.T) { + lc := &fleetv1api.Cluster{} + require.Eventually(func() bool { + lc, err = clients.Fleet.Cluster().Get("fleet-local", "local", metav1.GetOptions{}) + return err == nil && lc != nil && lc.Status.Summary.Ready > 0 + }, waitFor, tick) + require.Contains(lc.Labels, "name") + require.Equal(lc.Labels["name"], "local") + assert.Equal(lc.Spec.KubeConfigSecret, "local-kubeconfig") + + lcg := &fleetv1api.ClusterGroup{} + require.Eventually(func() bool { + lcg, err = clients.Fleet.ClusterGroup().Get("fleet-local", "default", metav1.GetOptions{}) + return err == nil && lcg != nil + }, waitFor, tick) + require.Contains(lcg.Spec.Selector.MatchLabels, "name") + assert.Equal(lcg.Spec.Selector.MatchLabels["name"], "local") + }) + + c, err := cluster.New(clients, &provv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "downstream-cluster", + }, + Spec: provv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provv1api.RKEConfig{ + MachinePools: []provv1api.RKEMachinePool{{ + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + mgmtCluster := &apimgmtv3.Cluster{} + require.Eventually(func() bool { + mgmtCluster, err = clients.Mgmt.Cluster().Get(c.Status.ClusterName, metav1.GetOptions{}) + return err == nil && mgmtCluster != nil + }, waitFor, tick) + + t.Run("fleet downstream cluster present", func(t *testing.T) { + fc := &fleetv1api.Cluster{ObjectMeta: metav1.ObjectMeta{Name: c.Name, Namespace: c.Namespace}} + require.Eventually(func() bool { + fc, err = clients.Fleet.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + return err == nil && fc.Status.Summary.Ready > 0 + }, waitFor, tick) + + require.NotNil(fc) + assert.Equal(fc.Spec.AgentEnvVars, mgmtCluster.Spec.AgentEnvVars) + assert.Equal(c.Status.ClientSecretName, fc.Spec.KubeConfigSecret) + require.Contains(fc.Labels, "management.cattle.io/cluster-name") + assert.Equal(fc.Labels["management.cattle.io/cluster-name"], mgmtCluster.Name) + require.Contains(fc.Labels, "management.cattle.io/cluster-display-name") + assert.Equal(fc.Labels["management.cattle.io/cluster-display-name"], mgmtCluster.Spec.DisplayName) + }) + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/fleetcluster_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/fleetcluster_test.go new file mode 100644 index 0000000..ed58335 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/fleet/fleetcluster_test.go @@ -0,0 +1,137 @@ +package fleetcluster_test + +import ( + "testing" + "time" + + fleetv1api "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1" + mgmt "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/tests/v2prov/clients" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + waitFor = 5 * time.Minute + tick = 2 * time.Second +) + +var ( + builtinAffinity = corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + PreferredDuringSchedulingIgnoredDuringExecution: []corev1.PreferredSchedulingTerm{ + { + Weight: 1, + Preference: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "fleet.cattle.io/agent", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + } + linuxAffinity = corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + } + resourceReq = &corev1.ResourceRequirements{ + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + }, + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + } + tolerations = []corev1.Toleration{ + { + Key: "key", + Operator: corev1.TolerationOpEqual, + Value: "value", + }, + } +) + +func Test_Fleet_Cluster(t *testing.T) { + require := require.New(t) + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + cluster := &fleetv1api.Cluster{} + // wait for fleet local cluster with default affinity + require.Eventually(func() bool { + cluster, err = clients.Fleet.Cluster().Get("fleet-local", "local", metav1.GetOptions{}) + return err == nil && cluster != nil && cluster.Status.Summary.Ready > 0 + }, waitFor, tick) + require.Equal(cluster.Spec.AgentAffinity, &builtinAffinity) + require.Nil(cluster.Spec.AgentResources) + require.Empty(cluster.Spec.AgentTolerations) + + // fleet-agent deployment has affinity + agent, err := clients.Apps.Deployment().Get(cluster.Status.Agent.Namespace, "fleet-agent", metav1.GetOptions{}) + require.NoError(err) + require.Equal(agent.Spec.Template.Spec.Affinity, &builtinAffinity) + require.Len(agent.Spec.Template.Spec.Containers, 1) + require.Empty(agent.Spec.Template.Spec.Containers[0].Resources) + require.NotEmpty(agent.Spec.Template.Spec.Tolerations) // Fleet has built-in tolerations + + // change settings on management cluster, results should show up in fleet-agent deployment + mc, err := clients.Mgmt.Cluster().Get("local", metav1.GetOptions{}) + require.NoError(err) + + mc.Spec.FleetAgentDeploymentCustomization = &mgmt.AgentDeploymentCustomization{ + OverrideAffinity: &linuxAffinity, + OverrideResourceRequirements: resourceReq, + AppendTolerations: tolerations, + } + + _, err = clients.Mgmt.Cluster().Update(mc) + require.NoError(err) + + // changes propagate to fleet cluster + require.Eventually(func() bool { + cluster, err = clients.Fleet.Cluster().Get("fleet-local", "local", metav1.GetOptions{}) + if err == nil && cluster != nil && cluster.Status.Summary.Ready > 0 { + assert.Equal(t, cluster.Spec.AgentAffinity, &linuxAffinity) + } + return false + }, waitFor, tick) + + require.Equal(cluster.Spec.AgentAffinity, &linuxAffinity) + require.Equal(cluster.Spec.AgentResources, resourceReq) + require.Contains(cluster.Spec.AgentTolerations, tolerations[0]) + + // changes are present in deployment + agent, err = clients.Apps.Deployment().Get(cluster.Status.Agent.Namespace, "fleet-agent", metav1.GetOptions{}) + require.NoError(err) + require.Equal(agent.Spec.Template.Spec.Affinity, &linuxAffinity) + require.Len(agent.Spec.Template.Spec.Containers, 1) + require.Equal(agent.Spec.Template.Spec.Containers[0].Resources.Limits, resourceReq.Limits) + require.Equal(agent.Spec.Template.Spec.Containers[0].Resources.Requests, resourceReq.Requests) + require.Contains(agent.Spec.Template.Spec.Tolerations, tolerations[0]) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/general/general_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/general/general_test.go new file mode 100644 index 0000000..fd4b1aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/general/general_test.go @@ -0,0 +1,58 @@ +package general + +import ( + "os" + "testing" + + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_General_SystemAgentVersion(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + setting, err := clients.Mgmt.Setting().Get("system-agent-version", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, setting.Value) + assert.True(t, setting.Value == os.Getenv("CATTLE_SYSTEM_AGENT_VERSION")) +} + +func Test_General_WinsAgentVersion(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + setting, err := clients.Mgmt.Setting().Get("wins-agent-version", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, setting.Value) + assert.True(t, setting.Value == os.Getenv("CATTLE_WINS_AGENT_VERSION")) +} + +func Test_General_CSIProxyAgentVersion(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + setting, err := clients.Mgmt.Setting().Get("csi-proxy-agent-version", metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + assert.NotEmpty(t, setting.Value) + assert.True(t, setting.Value == os.Getenv("CATTLE_CSI_PROXY_AGENT_VERSION")) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/machine_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/machine_test.go new file mode 100644 index 0000000..0af8132 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/machine_test.go @@ -0,0 +1,650 @@ +package machineprovisioning + +import ( + "context" + "fmt" + "os" + "strings" + "sync/atomic" + "testing" + + provisioningv1api "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/nodeconfig" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/rancher/tests/v2prov/wait" + "github.com/stretchr/testify/assert" + errgroup2 "golang.org/x/sync/errgroup" + corev1 "k8s.io/api/core/v1" + apierror "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/util/retry" + capi "sigs.k8s.io/cluster-api/api/v1beta1" +) + +func Test_Provisioning_MP_SingleNodeAllRolesWithDelete(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-single-node-all-roles-with-delete", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{{ + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, len(machines.Items), 1) + machine := machines.Items[0] + + clusterClients, err := clients.ForCluster(c.Namespace, c.Name) + if err != nil { + t.Fatal(err) + } + + node, err := clusterClients.Core.Node().Get(machines.Items[0].Status.NodeRef.Name, metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + + args, err := nodeconfig.FromNode(node) + if err != nil { + t.Fatal(err) + } + + // This shouldn't be one, fix when node args starts returning what is from the config file + assert.Greater(t, len(args), 10) + assert.Len(t, machine.Status.Addresses, 2) + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_MachineTemplateClonedAnnotations(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-machine-template-cloned-annotations", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{{ + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + infraMachines, err := cluster.PodInfraMachines(clients, c) + if err != nil { + t.Fatal(err) + } + + for _, infraMachine := range infraMachines.Items { + templateGroupKind := schema.ParseGroupKind(infraMachine.GetAnnotations()[capi.TemplateClonedFromGroupKindAnnotation]) + + machineTemplate, err := clients.Dynamic. + Resource(schema.GroupVersionResource{Group: templateGroupKind.Group, Version: "v1", Resource: strings.ToLower(templateGroupKind.Kind) + "s"}). + Namespace(infraMachine.GetNamespace()). + Get(clients.Ctx, infraMachine.GetAnnotations()[capi.TemplateClonedFromNameAnnotation], metav1.GetOptions{}) + if err != nil { + t.Fatal(err) + } + gv, err := schema.ParseGroupVersion(machineTemplate.GetAnnotations()[capr.MachineTemplateClonedFromGroupVersionAnn]) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, gv.String(), capr.DefaultMachineConfigAPIVersion) + assert.Equal(t, machineTemplate.GetAnnotations()[capr.MachineTemplateClonedFromKindAnn], c.Spec.RKEConfig.MachinePools[0].NodeConfig.Kind) + assert.Equal(t, machineTemplate.GetAnnotations()[capr.MachineTemplateClonedFromNameAnn], c.Spec.RKEConfig.MachinePools[0].NodeConfig.Name) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_MachineSetDeletePolicyOldestSet(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-machine-set-delete-policy-oldest-set", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }, + { + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + RollingUpdate: &provisioningv1api.RKEMachinePoolRollingUpdate{ + MaxUnavailable: &intstr.IntOrString{ + Type: intstr.String, + StrVal: "10%", + }, + MaxSurge: &intstr.IntOrString{ + Type: intstr.String, + StrVal: "10%", + }, + }, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machineSets, err := cluster.MachineSets(clients, c) + if err != nil { + t.Fatal(err) + } + + for _, machineSet := range machineSets.Items { + assert.Equal(t, string(capi.OldestMachineSetDeletePolicy), machineSet.Spec.DeletePolicy) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_MultipleEtcdNodesScaledDownThenDelete(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "etcd-scaled-down", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + ControlPlaneRole: false, + WorkerRole: false, + Quantity: &defaults.Two, + }, + { + EtcdRole: false, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + ClusterAgentDeploymentCustomization: &provisioningv1api.AgentDeploymentCustomization{ + OverrideAffinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-role.kubernetes.io/control-plane", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"true"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + kc, err := operations.GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + // wait for all nodes to be ready + err = retry.OnError(defaults.DownstreamRetry, func(error) bool { return true }, func() error { + nodes, err := kc.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + if len(nodes.Items) != 3 { + return fmt.Errorf("nodes did not match 3: actual: %d", len(nodes.Items)) + } + for _, n := range nodes.Items { + if !capr.Ready.IsTrue(n) { + return fmt.Errorf("node %s was not ready", n.Name) + } + } + return nil + }) + if err != nil { + t.Fatal(err) + } + + c, err = operations.Scale(clients, c, 0, 1, true) + if err != nil { + t.Fatal(err) + } + + _, err = operations.GetAndVerifyDownstreamClientset(clients, c) + if err != nil { + t.Fatal(err) + } + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_FiveNodesUniqueRolesWithDelete(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-five-nodes-unique-roles-with-delete", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + Quantity: &defaults.Three, + }, + { + ControlPlaneRole: true, + Quantity: &defaults.One, + }, + { + WorkerRole: true, + Quantity: &defaults.One, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_FourNodesServerAndWorkerRolesWithDelete(t *testing.T) { + if strings.ToLower(os.Getenv("DIST")) == "rke2" { + t.Skip() + } + t.Parallel() + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-worker-roles-with-delete", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + ControlPlaneRole: true, + Quantity: &defaults.Three, + }, + { + WorkerRole: true, + Quantity: &defaults.One, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + // Delete the cluster and wait for cleanup. + err = clients.Provisioning.Cluster().Delete(c.Namespace, c.Name, &metav1.DeleteOptions{}) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForDelete(clients, c) + if err != nil { + t.Fatal(err) + } + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_Drain(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + drainOpt := rkev1.DrainOptions{ + IgnoreDaemonSets: &[]bool{true}[0], + DeleteEmptyDirData: true, + Enabled: true, + Force: true, + SkipWaitForDeleteTimeoutSeconds: 30, + GracePeriod: 5, + PreDrainHooks: []rkev1.DrainHook{ + { + Annotation: "test.io/pre-hook1", + }, + { + Annotation: "test.io/pre-hook2", + }, + }, + PostDrainHooks: []rkev1.DrainHook{ + { + Annotation: "test.io/post-hook1", + }, + { + Annotation: "test.io/post-hook2", + }, + }, + } + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-drain", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + UpgradeStrategy: rkev1.ClusterUpgradeStrategy{ + ControlPlaneDrainOptions: drainOpt, + WorkerDrainOptions: drainOpt, + }, + }, + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + ControlPlaneRole: true, + }, + { + WorkerRole: true, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, len(machines.Items), 2) + + for { + c.Spec.RKEConfig.ProvisionGeneration = 1 + newC, err := clients.Provisioning.Cluster().Update(c) + if apierror.IsConflict(err) { + c, _ = clients.Provisioning.Cluster().Get(c.Namespace, c.Name, metav1.GetOptions{}) + } else if err != nil { + t.Fatal(err) + } else { + c = newC + break + } + } + + var doneHooks int32 + runHooks := func(machine *capi.Machine) error { + var secret *corev1.Secret + err = retry.OnError(retry.DefaultBackoff, func(err error) bool { return !apierror.IsNotFound(err) }, func() error { + bootstrap, err := clients.RKE.RKEBootstrap().Get(machine.Spec.Bootstrap.ConfigRef.Namespace, machine.Spec.Bootstrap.ConfigRef.Name, metav1.GetOptions{}) + if err != nil { + return err + } + secret, err = clients.Core.Secret().Get(bootstrap.Namespace, capr.PlanSecretFromBootstrapName(bootstrap.Name), metav1.GetOptions{}) + return err + }) + return wait.Object(clients.Ctx, clients.Core.Secret().Watch, secret, func(obj runtime.Object) (bool, error) { + secret := obj.(*corev1.Secret) + if secret.Annotations[capr.PreDrainAnnotation] != "" && + secret.Annotations[capr.PreDrainAnnotation] != secret.Annotations["test.io/pre-hook1"] { + secret.Annotations["test.io/pre-hook1"] = secret.Annotations[capr.PreDrainAnnotation] + secret.Annotations["test.io/pre-hook2"] = secret.Annotations[capr.PreDrainAnnotation] + _, err := clients.Core.Secret().Update(secret) + return false, err + } + if secret.Annotations[capr.PostDrainAnnotation] != "" && + secret.Annotations[capr.PostDrainAnnotation] != secret.Annotations["test.io/post-hook1"] { + secret.Annotations["test.io/post-hook1"] = secret.Annotations[capr.PostDrainAnnotation] + secret.Annotations["test.io/post-hook2"] = secret.Annotations[capr.PostDrainAnnotation] + _, err := clients.Core.Secret().Update(secret) + if err != nil { + return false, err + } + atomic.AddInt32(&doneHooks, 1) + return true, nil + } + return false, nil + }) + } + + errgroup, _ := errgroup2.WithContext(clients.Ctx) + errgroup.Go(func() error { + return runHooks(&machines.Items[0]) + }) + errgroup.Go(func() error { + return runHooks(&machines.Items[1]) + }) + if err := errgroup.Wait(); err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, int32(2), atomic.LoadInt32(&doneHooks)) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} + +func Test_Provisioning_MP_DrainNoDelete(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1api.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-drain-no-delete", + }, + Spec: provisioningv1api.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1api.RKEConfig{ + MachinePools: []provisioningv1api.RKEMachinePool{ + { + EtcdRole: true, + ControlPlaneRole: true, + Quantity: &defaults.One, + DrainBeforeDelete: false, + }, + { + WorkerRole: true, + Quantity: &defaults.One, + DrainBeforeDelete: true, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := cluster.Machines(clients, c) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, len(machines.Items), 2) + + excludeNodeDraining, ok := machines.Items[0].Annotations[capi.ExcludeNodeDrainingAnnotation] + assert.True(t, ok) + assert.Equal(t, excludeNodeDraining, "true") + + _, ok = machines.Items[1].Annotations[capi.ExcludeNodeDrainingAnnotation] + assert.False(t, ok) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_certificaterotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_certificaterotation_test.go new file mode 100644 index 0000000..ed28d5e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_certificaterotation_test.go @@ -0,0 +1,50 @@ +package machineprovisioning + +import ( + "github.com/stretchr/testify/assert" + "testing" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/operations" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Operation_SetA_MP_CertificateRotation(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-mp-certificate-rotation-operations", + }, + Spec: provisioningv1.ClusterSpec{ + KubernetesVersion: defaults.SomeK8sVersion, + RKEConfig: &provisioningv1.RKEConfig{ + MachinePools: []provisioningv1.RKEMachinePool{{ + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + operations.RunCertificateRotationTest(t, clients, c) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_encryptionkeyrotation_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_encryptionkeyrotation_test.go new file mode 100644 index 0000000..be39acd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_encryptionkeyrotation_test.go @@ -0,0 +1,56 @@ +package machineprovisioning + +import ( + "github.com/stretchr/testify/assert" + "os" + "strings" + "testing" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/operations" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Operation_SetA_MP_EncryptionKeyRotation(t *testing.T) { + // Encryption Key rotation is only possible with "stock configuration" on RKE2. + if strings.ToLower(os.Getenv("DIST")) != "rke2" { + t.Skip("encryption key rotation") + } + + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-mp-encryption-key-rotation-operations", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + MachinePools: []provisioningv1.RKEMachinePool{{ + EtcdRole: true, + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }}, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + operations.RunRotateEncryptionKeysTest(t, clients, c) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_inplace_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_inplace_test.go new file mode 100644 index 0000000..3acd3e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_inplace_test.go @@ -0,0 +1,91 @@ +package machineprovisioning + +import ( + "fmt" + "testing" + "time" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Test_Operation_SetA_MP_EtcdSnapshotCreationRestoreInPlace(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-mp-etcd-snapshot-operations-inplace", + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + }, + }, + MachinePools: []provisioningv1.RKEMachinePool{ + { + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + RKECommonNodeConfig: rkev1.RKECommonNodeConfig{ + Labels: map[string]string{ + "node-type": "etcd", + }, + }, + }, + { + EtcdRole: true, + Quantity: &defaults.One, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + _, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + machines, err := clients.CAPI.Machine().List(c.Namespace, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", capr.EtcdRoleLabel, "true")}) + if err != nil { + t.Fatal(err) + } + + if len(machines.Items) != 1 { + t.Fatal(fmt.Errorf("length of etcd machines is not 1")) + } + + assert.NotNil(t, machines.Items[0].Status.NodeRef) + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, machines.Items[0].Status.NodeRef.Name) + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.Name, cm, 2) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_multietcd_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_multietcd_test.go new file mode 100644 index 0000000..add938c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_multietcd_test.go @@ -0,0 +1,117 @@ +package machineprovisioning + +import ( + "strings" + "testing" + "time" + + "github.com/rancher/rancher/pkg/capr" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/namespace" + "github.com/rancher/rancher/tests/v2prov/objectstore" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Test_Operation_SetB_MP_EtcdSnapshotOperationsWithThreeEtcdNodesOnNewNode uses Minio as an object store to store S3 snapshots. +// It creates a 5 node machine provisioned cluster with 3 controlplane+etcd nodes and 2 workers, creates a configmap, +// takes a snapshot of the cluster, deletes the configmap, then scales down the controlplane/etcd nodes. +// It then creates a new etcd node and restores from local snapshot file, then scales the cluster back up to desired state. +func Test_Operation_SetB_MP_EtcdSnapshotOperationsWithThreeEtcdNodesOnNewNode(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + newNs, err := namespace.Random(clients) + if err != nil { + t.Fatal(err) + } + + osInfo, err := objectstore.GetObjectStore(clients, newNs.Name, "store0", "s3snapshots") + if err != nil { + t.Fatal(err) + } + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-mp-etcd-snapshot-conventional-arch-new-node", + Namespace: newNs.Name, + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + S3: &rkev1.ETCDSnapshotS3{ + Endpoint: osInfo.Endpoint, + EndpointCA: osInfo.Cert, + Bucket: osInfo.Bucket, + CloudCredentialName: osInfo.CloudCredentialName, + Folder: "testfolder", + }, + }, + }, + MachinePools: []provisioningv1.RKEMachinePool{ + { + ControlPlaneRole: true, + EtcdRole: true, + Quantity: &defaults.Three, + }, + { + WorkerRole: true, + Quantity: &defaults.Two, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, "s3") + assert.NotNil(t, snapshot) + // Scale controlplane/etcd nodes to 0 + c, err = operations.Scale(clients, c, 0, 0, false) + if err != nil { + t.Fatal(err) + } + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating insane cluster", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "waiting for at least one control plane, etcd, and worker node to be registered"), nil + }) + // Scale etcd nodes to 1 + c, err = operations.Scale(clients, c, 0, 1, false) + if err != nil { + t.Fatal(err) + } + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating restoration required", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "rkecontrolplane was already initialized but no etcd machines exist that have plans, indicating the etcd plane has been entirely replaced. Restoration from etcd snapshot is required."), nil + }) + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.Name, cm, 3) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_test.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_test.go new file mode 100644 index 0000000..fb97aac --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/tests/machineprovisioning/operation_etcdsnapshot_newnode_test.go @@ -0,0 +1,115 @@ +package machineprovisioning + +import ( + "strings" + "testing" + "time" + + provisioningv1 "github.com/rancher/rancher/pkg/apis/provisioning.cattle.io/v1" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" + "github.com/rancher/rancher/pkg/capr" + "github.com/rancher/rancher/tests/v2prov/clients" + "github.com/rancher/rancher/tests/v2prov/cluster" + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/rancher/rancher/tests/v2prov/namespace" + "github.com/rancher/rancher/tests/v2prov/objectstore" + "github.com/rancher/rancher/tests/v2prov/operations" + "github.com/rancher/wrangler/v3/pkg/name" + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Test_Operation_SetB_MP_EtcdSnapshotOperationsOnNewNode uses Minio as an object store to store S3 snapshots. It creates a 2 node machine provisioned cluster with a controlplane+worker and +// etcd node, creates a configmap, takes a snapshot of the cluster, deletes the configmap, then deletes the etcd machine/node. +// It then creates a new etcd node and restores from local snapshot file. +func Test_Operation_SetB_MP_EtcdSnapshotOperationsOnNewNode(t *testing.T) { + clients, err := clients.New() + if err != nil { + t.Fatal(err) + } + defer clients.Close() + + newNs, err := namespace.Random(clients) + if err != nil { + t.Fatal(err) + } + + osInfo, err := objectstore.GetObjectStore(clients, newNs.Name, "store0", "s3snapshots") + if err != nil { + t.Fatal(err) + } + + c, err := cluster.New(clients, &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-mp-etcd-snapshot-operations-on-new-node", + Namespace: newNs.Name, + }, + Spec: provisioningv1.ClusterSpec{ + RKEConfig: &provisioningv1.RKEConfig{ + RKEClusterSpecCommon: rkev1.RKEClusterSpecCommon{ + ETCD: &rkev1.ETCD{ + DisableSnapshots: true, + S3: &rkev1.ETCDSnapshotS3{ + Endpoint: osInfo.Endpoint, + EndpointCA: osInfo.Cert, + Bucket: osInfo.Bucket, + CloudCredentialName: osInfo.CloudCredentialName, + Folder: "testfolder", + }, + }, + }, + MachinePools: []provisioningv1.RKEMachinePool{ + { + EtcdRole: true, + Quantity: &defaults.One, + }, + { + ControlPlaneRole: true, + WorkerRole: true, + Quantity: &defaults.One, + }, + }, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + c, err = cluster.WaitForCreate(clients, c) + if err != nil { + t.Fatal(err) + } + + cm := corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-configmap-" + name.Hex(time.Now().String(), 10), + }, + Data: map[string]string{ + "test": "wow", + }, + } + + snapshot := operations.RunSnapshotCreateTest(t, clients, c, cm, "s3") + assert.NotNil(t, snapshot) + // Scale etcd nodes to 0 + c, err = operations.Scale(clients, c, 0, 0, false) + if err != nil { + t.Fatal(err) + } + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating insane cluster", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "waiting for at least one control plane, etcd, and worker node to be registered"), nil + }) + // Scale etcd nodes to 1 + c, err = operations.Scale(clients, c, 0, 1, false) + if err != nil { + t.Fatal(err) + } + _, err = cluster.WaitForControlPlane(clients, c, "rkecontrolplane ready condition indicating restoration required", func(rkeControlPlane *rkev1.RKEControlPlane) (bool, error) { + return strings.Contains(capr.Ready.GetMessage(&rkeControlPlane.Status), "rkecontrolplane was already initialized but no etcd machines exist that have plans, indicating the etcd plane has been entirely replaced. Restoration from etcd snapshot is required."), nil + }) + operations.RunSnapshotRestoreTest(t, clients, c, snapshot.Name, cm, 2) + err = cluster.EnsureMinimalConflictsWithThreshold(clients, c, cluster.SaneConflictMessageThreshold) + assert.NoError(t, err) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/wait/wait.go b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/wait/wait.go new file mode 100644 index 0000000..0c941ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/v2prov/wait/wait.go @@ -0,0 +1,109 @@ +package wait + +import ( + "context" + "fmt" + "time" + + "github.com/rancher/rancher/tests/v2prov/defaults" + "github.com/sirupsen/logrus" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" +) + +type WatchFunc func(namespace string, opts metav1.ListOptions) (watch.Interface, error) +type WatchClusterScopedFunc func(opts metav1.ListOptions) (watch.Interface, error) +type watchFunc func() (watch.Interface, error) + +func ClusterScopedList(ctx context.Context, watchFunc WatchClusterScopedFunc, cb func(obj runtime.Object) (bool, error)) error { + return retryWatch(ctx, func() (watch.Interface, error) { + return watchFunc(metav1.ListOptions{}) + }, cb) +} + +func doWatch(ctx context.Context, watchFunc watchFunc, cb func(obj runtime.Object) (bool, error)) (bool, error) { + result, err := watchFunc() + if err != nil { + logrus.Error("watch failed", err) + time.Sleep(2 * time.Second) + return false, nil + } + defer func() { + result.Stop() + for range result.ResultChan() { + } + }() + + for { + select { + case <-ctx.Done(): + return false, fmt.Errorf("timeout waiting condition: %w", ctx.Err()) + case event, open := <-result.ResultChan(): + if !open { + return false, nil + } + switch event.Type { + case watch.Added, watch.Modified, watch.Deleted: + done, err := cb(event.Object) + if err != nil || done { + if apierrors.IsConflict(err) { + // if we got a conflict, return a false (not done) and nil for error + return false, nil + } + return true, err + } + } + } + } +} + +func retryWatch(ctx context.Context, watchFunc watchFunc, cb func(obj runtime.Object) (bool, error)) error { + ctx, cancel := context.WithTimeout(ctx, time.Duration(defaults.WatchTimeoutSeconds)*time.Second) + defer cancel() + for { + if done, err := doWatch(ctx, watchFunc, cb); err != nil || done { + return err + } + } +} + +func Object(ctx context.Context, watchFunc WatchFunc, obj runtime.Object, cb func(obj runtime.Object) (bool, error)) error { + if done, err := cb(obj); err != nil || done { + return err + } + + meta, err := meta.Accessor(obj) + if err != nil { + return err + } + + return retryWatch(ctx, func() (watch.Interface, error) { + return watchFunc(meta.GetNamespace(), metav1.ListOptions{ + FieldSelector: "metadata.name=" + meta.GetName(), + TimeoutSeconds: &defaults.WatchTimeoutSeconds, + }) + }, cb) +} + +func EnsureDoesNotExist(ctx context.Context, getter func() (runtime.Object, error)) error { + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + ctx, cancel := context.WithTimeout(ctx, time.Duration(defaults.WatchTimeoutSeconds)*time.Second) + defer cancel() + for { + select { + case <-ctx.Done(): + return fmt.Errorf("timeout waiting for deletion: %w", ctx.Err()) + case <-ticker.C: + _, err := getter() + if apierrors.IsNotFound(err) { + return nil + } else if err != nil { + return err + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/.gitignore new file mode 100644 index 0000000..c3e8e5d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/.gitignore @@ -0,0 +1,104 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# Local test generation +.DS_store +.ssh diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.rke b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.rke new file mode 100644 index 0000000..5cc1161 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.rke @@ -0,0 +1,18 @@ +FROM python:3.11 + +ARG RKE_VERSION=v1.0.2 +ARG KUBECTL_VERSION=v1.27.10 +ENV WORKSPACE /src/rancher-validation +WORKDIR $WORKSPACE + +COPY [".", "$WORKSPACE"] + +RUN wget https://github.com/rancher/rke/releases/download/$RKE_VERSION/rke_linux-amd64 && \ + wget https://storage.googleapis.com/kubernetes-release/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl && \ + mv rke_linux-amd64 /bin/rke && \ + chmod +x /bin/rke && \ + mv kubectl /bin/kubectl && \ + chmod +x /bin/kubectl && \ + cd $WORKSPACE && \ + pip install --upgrade pip && \ + pip install -r requirements.txt diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.v3api b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.v3api new file mode 100644 index 0000000..75c6911 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/Dockerfile.v3api @@ -0,0 +1,65 @@ +FROM python:3.11 + +ARG KUBECTL_VERSION=v1.27.10 +ENV WORKSPACE /src/rancher-validation +WORKDIR $WORKSPACE +ENV PYTHONPATH /src/rancher-validation +ARG RKE_VERSION=v1.0.2 +ARG CLI_VERSION=v2.3.2 +ARG RANCHER_HELM_VERSION=v3.9.0 +ARG SONOBUOY_VERSION=0.18.2 +ARG TERRAFORM_VERSION=0.12.10 + +ARG EXTERNAL_ENCODED_VPN +ARG VPN_ENCODED_LOGIN + + +COPY [".", "$WORKSPACE"] + +RUN wget https://storage.googleapis.com/kubernetes-release/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl && \ + mv kubectl /bin/kubectl && \ + chmod +x /bin/kubectl && \ + wget https://github.com/rancher/rke/releases/download/$RKE_VERSION/rke_linux-amd64 && \ + mv rke_linux-amd64 /bin/rke && \ + chmod +x /bin/rke && \ + wget https://github.com/rancher/cli/releases/download/$CLI_VERSION/rancher-linux-amd64-$CLI_VERSION.tar.gz && \ + tar -x -f rancher-linux-amd64-$CLI_VERSION.tar.gz && \ + mv rancher-$CLI_VERSION/rancher /bin/rancherctl && \ + chmod +x /bin/rancherctl && \ + wget https://get.helm.sh/helm-$RANCHER_HELM_VERSION-linux-amd64.tar.gz && \ + tar -x -f helm-$RANCHER_HELM_VERSION-linux-amd64.tar.gz && \ + mv linux-amd64/helm /bin/helm_v3 && \ + chmod +x /bin/helm_v3 && \ + wget https://releases.hashicorp.com/terraform/$TERRAFORM_VERSION/terraform_"$TERRAFORM_VERSION"_linux_amd64.zip && \ + apt-get update && \ + apt-get install unzip && \ + unzip terraform_"$TERRAFORM_VERSION"_linux_amd64.zip && \ + chmod u+x terraform && \ + mv terraform /usr/local/bin && \ + wget "https://github.com/vmware-tanzu/sonobuoy/releases/download/v$SONOBUOY_VERSION/sonobuoy_$SONOBUOY_VERSION"_linux_amd64.tar.gz && \ + tar -xzf "sonobuoy_$SONOBUOY_VERSION"_linux_amd64.tar.gz -C /tmp && \ + mv /tmp/sonobuoy /usr/local/bin && \ + chmod +x /usr/local/bin/sonobuoy && \ + wget https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip && \ + unzip awscli-exe-linux-x86_64.zip && \ + ./aws/install && \ + # curl -sL https://aka.ms/InstallAzureCLIDeb | bash && \ + cd $WORKSPACE && \ + pip install --upgrade pip && \ + pip install -r requirements_v3api.txt + +# necessary to run if statements using [[ ]] +SHELL ["/bin/bash", "-c"] + +RUN if [[ -z '$EXTERNAL_ENCODED_VPN' ]] ; then \ + echo 'no vpn provided' ; \ + else \ + apt-get update && apt-get -y install openvpn net-tools && \ + echo $EXTERNAL_ENCODED_VPN | base64 -d > external.ovpn && \ + if [[ -z '$VPN_ENCODED_LOGIN' ]] ; then \ + echo 'no passcode provided' ; \ + else \ + echo 'adding passfile' && echo $VPN_ENCODED_LOGIN | base64 -d > passfile && \ + sed -i 's/auth-user-pass/auth-user-pass passfile/g' external.ovpn; \ + fi; \ + fi; diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/Dockerfile new file mode 100644 index 0000000..db05917 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:22.04 +COPY . /app +WORKDIR /app +EXPOSE 5000 22 + +RUN apt-get update -y && \ + apt-get install -y python3-pip python-dev-is-python3 build-essential curl dnsutils iputils-ping openssh-server net-tools && \ + mkdir /var/run/sshd && echo 'root:screencast' | chpasswd && \ + sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \ + pip install -r requirements.txt + +CMD ["/app/start.sh"] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/app.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/app.py new file mode 100644 index 0000000..e2fffe0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/app.py @@ -0,0 +1,112 @@ +from flask import Flask, request +import os +import random +import requests +import socket +from string import ascii_letters, digits +from subprocess import call + + +TEMP_DIR = os.path.dirname(os.path.realpath(__file__)) + '/temp' +app = Flask(__name__) + + +def generate_random_file_name(): + name = ''.join(random.choice(ascii_letters + digits) for _ in list(range(35))) + return "{0}/{1}.txt".format(TEMP_DIR, name) + + +@app.route('/') +def home(): + return "welcome to container-utils" + +@app.route('/metadata/', methods=['GET']) +def get_metadata(path): + accept_type = request.headers.get('Accept') + headers = {'Accept': accept_type} if accept_type else None + url = "http://rancher-metadata/%s" % path + try: + response = requests.get(url=url, headers=headers) + except Exception as e: + return "Error: {0}".format(e), 400 + if not response.ok: + return response.content, response.status_code + return response.content, 200 + + +@app.route('/hostname', methods=['GET']) +def get_hostname(): + return str(socket.gethostname()) + + +@app.route('/env', methods=['GET']) +def get_environment_varable(): + if 'var' not in request.args: + return "Required param 'var' is missing", 400 + + var = request.args['var'] + if var not in os.environ: + return "Not found '{0}' in environment variables".format(var), 404 + return str(os.environ[var]) + + +@app.route('/proxy', methods=['GET']) +def proxy(): + url = request.args.get('url') + link = request.args.get('link') + port = request.args.get('port') + path = request.args.get('path') + + if link is not None and port is not None and path is not None: + link = link.upper() + dest_port = os.environ.get(link + "_PORT_" + port + "_TCP_PORT") + dest_host = os.environ.get(link + "_PORT_" + port + "_TCP_ADDR") + err_msg = "Not found '{0}' in environment variables" + if dest_port is None: + return err_msg.format(dest_port), 404 + if dest_host is None: + return err_msg.format(dest_host), 404 + url = 'http://{0}:{1}/{2}'.format(dest_host, dest_port, path) + + if url is None: + return ("Required param missing: Either 'url', or all params " + "'link', 'port' and 'path' are required"), 400 + try: + response = requests.get(url=url) + except Exception as e: + return "Error: {0}".format(e), 400 + if not response.ok: + return response.content, response.status_code + return response.content, 200 + + +@app.route('/dig', methods=['GET']) +def get_dig_info(): + if 'host' not in request.args: + return "Required param 'host' is missing", 400 + host = request.args['host'] + + temp_file = generate_random_file_name() + try: + with open(temp_file, 'w') as f: + call(['dig', host, '+short'], stdout=f) + + with open(temp_file, 'r') as f: + content = f.read() + except Exception as e: + content = "Error: {0}".format(e) + finally: + if os.path.isfile(temp_file): + os.remove(temp_file) + return content + + +@app.route('/ping', methods=['GET']) +def health_check(): + return 'ping' + + +if __name__ == '__main__': + if not os.path.isdir(TEMP_DIR): + os.makedirs(TEMP_DIR) + app.run(debug=True, host='0.0.0.0') diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/requirements.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/requirements.txt new file mode 100644 index 0000000..c68dd60 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/requirements.txt @@ -0,0 +1,2 @@ +flask==2.2.5 +requests==2.31.0 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/start.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/start.sh new file mode 100755 index 0000000..54575b1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/images/container-utils/start.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +/usr/sbin/sshd -D & + +python3.11 app.py + +sleep infinity \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/aws.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/aws.py new file mode 100644 index 0000000..25db5a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/aws.py @@ -0,0 +1,727 @@ +import base64 +import boto3 +import logging +import os +import rsa +import time +from boto3.exceptions import Boto3Error +from botocore.exceptions import ClientError +from .cloud_provider import CloudProviderBase +from .node import Node + +logging.getLogger('boto3').setLevel(logging.CRITICAL) +logging.getLogger('botocore').setLevel(logging.CRITICAL) + +AWS_REGION = os.environ.get("AWS_REGION", "us-east-2") +AWS_REGION_AZ = os.environ.get("AWS_REGION_AZ", "us-east-2a") +AWS_SECURITY_GROUP = os.environ.get("AWS_SECURITY_GROUPS", + 'sg-04f28c5d02555da26') +AWS_SUBNET = os.environ.get("AWS_SUBNET", "subnet-ee8cac86") +AWS_HOSTED_ZONE_ID = os.environ.get("AWS_HOSTED_ZONE_ID", "") +AWS_VPC_ID = os.environ.get("AWS_VPC_ID", "vpc-bfccf4d7") +AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID") +AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY") +AWS_SSH_KEY_NAME = os.environ.get("AWS_SSH_KEY_NAME") +AWS_CICD_INSTANCE_TAG = os.environ.get("AWS_CICD_INSTANCE_TAG", + 'rancher-validation') +AWS_IAM_PROFILE = os.environ.get("AWS_IAM_PROFILE", "") +# by default the public Ubuntu 20.04 AMI is used +AWS_DEFAULT_AMI = "ami-012fd49f6b0c404c7" +AWS_DEFAULT_USER = "ubuntu" +AWS_AMI = os.environ.get("AWS_AMI", AWS_DEFAULT_AMI) +AWS_USER = os.environ.get("AWS_USER", AWS_DEFAULT_USER) +AWS_VOLUME_SIZE = os.environ.get("AWS_VOLUME_SIZE", "50") +AWS_INSTANCE_TYPE = os.environ.get("AWS_INSTANCE_TYPE", 't3a.medium') +AWS_BASTION_INSTANCE_TYPE = os.environ.get("AWS_INSTANCE_TYPE", 'c5.2xlarge') + +AWS_WINDOWS_VOLUME_SIZE = os.environ.get("AWS_WINDOWS_VOLUME_SIZE", "100") +AWS_WINDOWS_INSTANCE_TYPE = 't3.xlarge' + +EKS_VERSION = os.environ.get("RANCHER_EKS_K8S_VERSION") +EKS_ROLE_ARN = os.environ.get("RANCHER_EKS_ROLE_ARN") +EKS_WORKER_ROLE_ARN = os.environ.get("RANCHER_EKS_WORKER_ROLE_ARN") + +AWS_SUBNETS = [] +if ',' in AWS_SUBNET: + AWS_SUBNETS = AWS_SUBNET.split(',') +else: + AWS_SUBNETS = [AWS_SUBNET] + + +class AmazonWebServices(CloudProviderBase): + + def __init__(self): + self._client = boto3.client( + 'ec2', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION) + + self._elbv2_client = boto3.client( + 'elbv2', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION) + + self._route53_client = boto3.client( + 'route53', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY) + + self._db_client = boto3.client( + 'rds', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION) + + self._eks_client = boto3.client( + 'eks', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION) + + self._ec2_resource = boto3.resource( + 'ec2', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION + ) + + self.master_ssh_key = None + self.master_ssh_key_path = None + + if AWS_SSH_KEY_NAME: + self.master_ssh_key = self.get_ssh_key(AWS_SSH_KEY_NAME) + self.master_ssh_key_path = self.get_ssh_key_path(AWS_SSH_KEY_NAME) + + # Used for cleanup + self.created_node = [] + self.created_keys = [] + + def create_node(self, node_name, ami=AWS_AMI, ssh_user=AWS_USER, + key_name=None, wait_for_ready=True, public_ip=True, for_bastion=False): + volume_size = AWS_VOLUME_SIZE + instance_type = AWS_BASTION_INSTANCE_TYPE if for_bastion else AWS_INSTANCE_TYPE + if ssh_user == "Administrator": + volume_size = AWS_WINDOWS_VOLUME_SIZE + instance_type = AWS_WINDOWS_INSTANCE_TYPE + + ipv6_addresses = 0 + if public_ip: + ipv6_addresses += 1 + if key_name: + # if cert private key + if key_name.endswith('.pem'): + ssh_private_key_name = key_name + ssh_private_key = self.get_ssh_key(key_name) + ssh_private_key_path = self.get_ssh_key_path(key_name) + else: + # get private key + ssh_private_key_name = key_name.replace('.pub', '') + ssh_private_key = self.get_ssh_key(ssh_private_key_name) + ssh_private_key_path = self.get_ssh_key_path( + ssh_private_key_name) + else: + key_name = AWS_SSH_KEY_NAME.replace('.pem', '') + ssh_private_key_name = key_name + ssh_private_key = self.master_ssh_key + ssh_private_key_path = self.master_ssh_key_path + + args = {"ImageId": ami, + "InstanceType": instance_type, + "MinCount": 1, + "MaxCount": 1, + "TagSpecifications": [ + {'ResourceType': 'instance', + 'Tags': [ + {'Key': 'Name', 'Value': node_name}, + {'Key': 'CICD', 'Value': AWS_CICD_INSTANCE_TAG} + ]} + ], + "KeyName": key_name, + "NetworkInterfaces": [ + {'DeviceIndex': 0, + 'AssociatePublicIpAddress': public_ip, + 'Groups': [AWS_SECURITY_GROUP], + 'Ipv6AddressCount': ipv6_addresses + } + ], + "Placement": {'AvailabilityZone': AWS_REGION_AZ}, + "BlockDeviceMappings": + [{"DeviceName": "/dev/sda1", + "Ebs": {"DeleteOnTermination": True, + "Iops": 6000 if for_bastion else 3000, + "VolumeSize": int(volume_size), + "VolumeType": 'gp3', + "Throughput": 500 if for_bastion else 125 + } + }] + } + + if len(AWS_IAM_PROFILE) > 0: + args["IamInstanceProfile"] = {'Name': AWS_IAM_PROFILE} + args["TagSpecifications"][0]["Tags"].append( + {'Key': 'kubernetes.io/cluster/c-abcde', 'Value': "owned"} + ) + + instance = self._client.run_instances(**args) + node = Node( + provider_node_id=instance['Instances'][0]['InstanceId'], + state=instance['Instances'][0]['State']['Name'], + ssh_user=ssh_user, + ssh_key_name=ssh_private_key_name, + ssh_key_path=ssh_private_key_path, + ssh_key=ssh_private_key, + docker_version=self.DOCKER_VERSION, + docker_installed=self.DOCKER_INSTALLED) + + # mark for clean up at the end + self.created_node.append(node.provider_node_id) + + if wait_for_ready: + node = self.wait_for_node_state(node) + if public_ip: + node.ready_node() + else: + time.sleep(60) + return node + + def create_multiple_nodes(self, number_of_nodes, node_name_prefix, + ami=AWS_AMI, ssh_user=AWS_USER, + key_name=None, wait_for_ready=True, + public_ip=True): + nodes = [] + for i in range(number_of_nodes): + node_name = "{}-{}".format(node_name_prefix, i) + nodes.append(self.create_node(node_name, + ami=ami, ssh_user=ssh_user, + key_name=key_name, + wait_for_ready=False, + public_ip=public_ip)) + + if wait_for_ready: + nodes = self.wait_for_nodes_state(nodes) + # wait for window nodes to come up so we can decrypt the password + if ssh_user == "Administrator": + time.sleep(60 * 6) + for node in nodes: + node.ssh_password = \ + self.decrypt_windows_password(node.provider_node_id) + + if public_ip: + for node in nodes: + node.ready_node() + else: + time.sleep(60) + + return nodes + + def get_node(self, provider_id, ssh_access=False): + node_filter = [{ + 'Name': 'instance-id', 'Values': [provider_id]}] + try: + response = self._client.describe_instances(Filters=node_filter) + nodes = response.get('Reservations', []) + if len(nodes) == 0: + return None # no node found + + aws_node = nodes[0]['Instances'][0] + node = Node( + provider_node_id=provider_id, + # node_name= aws_node tags?, + host_name=aws_node.get('PublicDnsName'), + public_ip_address=aws_node.get('PublicIpAddress'), + private_ip_address=aws_node.get('PrivateIpAddress'), + state=aws_node['State']['Name']) + if ssh_access: + node.ssh_user = AWS_USER + node.ssh_key_name = AWS_SSH_KEY_NAME.replace('.pem', '') + node.ssh_key_path = self.master_ssh_key_path + node.ssh_key = self.master_ssh_key + return node + except Boto3Error as e: + msg = "Failed while querying instance '{}' state!: {}".format( + node.node_id, str(e)) + raise RuntimeError(msg) + + def update_node(self, node): + node_filter = [{ + 'Name': 'instance-id', 'Values': [node.provider_node_id]}] + try: + response = self._client.describe_instances(Filters=node_filter) + nodes = response.get('Reservations', []) + if len(nodes) == 0 or len(nodes[0]['Instances']) == 0: + return node + + aws_node = nodes[0]['Instances'][0] + node.state = aws_node['State']['Name'] + node.host_name = aws_node.get('PublicDnsName') + node.public_ip_address = aws_node.get('PublicIpAddress') + node.private_ip_address = aws_node.get('PrivateIpAddress') + return node + except Boto3Error as e: + msg = "Failed while querying instance '{}' state!: {}".format( + node.node_id, str(e)) + raise RuntimeError(msg) + + def start_node(self, node, wait_for_start=True): + self._client.start_instances( + InstanceIds=[node.provider_node_id]) + if wait_for_start: + node = self.wait_for_node_state(node) + return node + + def reboot_nodes(self, nodes): + instances = [node.provider_node_id for node in nodes] + self._client.reboot_instances( + InstanceIds=instances) + return + + def stop_node(self, node, wait_for_stopped=False): + self._client.stop_instances( + InstanceIds=[node.provider_node_id]) + if wait_for_stopped: + node = self.wait_for_node_state(node, 'stopped') + return node + + def delete_node(self, node, wait_for_deleted=False): + self._client.terminate_instances( + InstanceIds=[node.provider_node_id]) + if wait_for_deleted: + node = self.wait_for_node_state(node, 'terminated') + return node + + def delete_eks_cluster(self, cluster_name): + ng_names = self._eks_client.list_nodegroups(clusterName=cluster_name) + for node_group in ng_names['nodegroups']: + print("Deleting node group: " + node_group) + delete_ng_response = self._eks_client.delete_nodegroup( + clusterName=cluster_name, + nodegroupName=node_group) + waiter_ng = self._eks_client.get_waiter('nodegroup_deleted') + for node_group in ng_names['nodegroups']: + print("Waiting for deletion of: " + node_group) + waiter_ng.wait(clusterName=cluster_name, nodegroupName=node_group) + print("Deleting cluster: "+ cluster_name) + delete_response = self._eks_client.delete_cluster(name=cluster_name) + return delete_response + + def wait_for_node_state(self, node, state='running'): + # 'running', 'stopped', 'terminated' + timeout = 300 + start_time = time.time() + while time.time() - start_time < timeout: + node = self.update_node(node) + if node.state == state: + return node + time.sleep(5) + + def wait_for_nodes_state(self, nodes, state='running'): + # 'running', 'stopped', 'terminated' + timeout = 300 + start_time = time.time() + completed_nodes = [] + while time.time() - start_time < timeout: + for node in nodes: + if len(completed_nodes) == len(nodes): + time.sleep(20) # Give the node some extra time + return completed_nodes + if node in completed_nodes: + continue + node = self.update_node(node) + if node.state == state: + completed_nodes.append(node) + time.sleep(1) + time.sleep(4) + + def import_ssh_key(self, ssh_key_name, public_ssh_key): + self._client.delete_key_pair(KeyName=ssh_key_name) + self._client.import_key_pair( + KeyName=ssh_key_name, + PublicKeyMaterial=public_ssh_key) + # mark keys for cleanup + self.created_keys.append(ssh_key_name) + + def delete_ssh_key(self, ssh_key_name): + self._client.delete_key_pair(KeyName=ssh_key_name) + + def get_nodes(self, filters): + try: + response = self._client.describe_instances(Filters=filters) + nodes = response.get('Reservations', []) + if len(nodes) == 0: + return None # no node found + ret_nodes = [] + for aws_node_i in nodes: + aws_node = aws_node_i['Instances'][0] + node = Node( + provider_node_id=aws_node.get('InstanceId'), + # node_name= aws_node tags?, + host_name=aws_node.get('PublicDnsName'), + public_ip_address=aws_node.get('PublicIpAddress'), + private_ip_address=aws_node.get('PrivateIpAddress'), + state=aws_node['State']['Name']) + ret_nodes.append(node) + return ret_nodes + except Boto3Error as e: + msg = "Failed while getting instances: {}".format(str(e)) + raise RuntimeError(msg) + + def delete_nodes(self, nodes, wait_for_deleted=False): + instance_ids = [node.provider_node_id for node in nodes] + self._client.terminate_instances(InstanceIds=instance_ids) + if wait_for_deleted: + for node in nodes: + node = self.wait_for_node_state(node, 'terminated') + + def delete_keypairs(self, name_prefix): + if len(name_prefix) > 0: + key_pairs = self._client.describe_key_pairs() + print(key_pairs["KeyPairs"]) + key_pair_list = key_pairs["KeyPairs"] + print(len(key_pair_list)) + for key in key_pair_list: + keyName = key["KeyName"] + if keyName.startswith(name_prefix): + print(keyName) + self._client.delete_key_pair(KeyName=keyName) + + def _s3_list_files(self, client): + """List files in specific S3 URL""" + response = client.list_objects( + Bucket=os.environ.get("AWS_S3_BUCKET_NAME", ""), + Prefix=os.environ.get("AWS_S3_BUCKET_FOLDER_NAME", "")) + + for content in response.get('Contents', []): + yield content.get('Key') + + def s3_backup_check(self, filename=""): + print(AWS_REGION) + print(AWS_REGION_AZ) + client = boto3.client( + 's3', + aws_access_key_id=AWS_ACCESS_KEY_ID, + aws_secret_access_key=AWS_SECRET_ACCESS_KEY, + region_name=AWS_REGION) + file_list = self._s3_list_files(client) + found = False + for file in file_list: + print(file) + if filename in file: + found = True + break + return found + + def register_targets(self, targets, target_group_arn): + self._elbv2_client.register_targets( + TargetGroupArn=target_group_arn, + Targets=targets) + + def describe_target_health(self, target_group_arn): + return self._elbv2_client.describe_target_health( + TargetGroupArn=target_group_arn) + + def deregister_all_targets(self, target_group_arn): + target_health_descriptions = \ + self.describe_target_health(target_group_arn) + + if len(target_health_descriptions["TargetHealthDescriptions"]) > 0: + targets = [] + + for target in \ + target_health_descriptions["TargetHealthDescriptions"]: + target_obj = target["Target"] + targets.append(target_obj) + + self._elbv2_client.deregister_targets( + TargetGroupArn=target_group_arn, + Targets=targets) + + def create_network_lb(self, name, scheme='internet-facing'): + return self._elbv2_client.create_load_balancer( + Name=name, Subnets=[AWS_SUBNET], Scheme=scheme, Type='network' + ) + + def delete_lb(self, loadBalancerARN): + self._elbv2_client.delete_load_balancer( + LoadBalancerArn=loadBalancerARN + ) + + def create_ha_target_group(self, port, name): + return self._elbv2_client.create_target_group( + Name=name, + Protocol='TCP', + Port=port, + VpcId=AWS_VPC_ID, + HealthCheckProtocol='HTTP', + HealthCheckPort='80', + HealthCheckEnabled=True, + HealthCheckPath='/healthz', + HealthCheckIntervalSeconds=10, + HealthCheckTimeoutSeconds=6, + HealthyThresholdCount=3, + UnhealthyThresholdCount=3, + Matcher={ + 'HttpCode': '200-399' + }, + TargetType='instance' + ) + + def delete_target_group(self, targetGroupARN): + self._elbv2_client.delete_target_group( + TargetGroupArn=targetGroupARN + ) + + def create_ha_nlb_listener(self, loadBalancerARN, port, targetGroupARN): + return self._elbv2_client.create_listener( + LoadBalancerArn=loadBalancerARN, + Protocol='TCP', + Port=port, + DefaultActions=[{'Type': 'forward', + 'TargetGroupArn': targetGroupARN}] + ) + + def upsert_route_53_record_cname( + self, record_name, record_value, action='UPSERT', + record_type='CNAME', record_ttl=300): + return self._route53_client.change_resource_record_sets( + HostedZoneId=AWS_HOSTED_ZONE_ID, + ChangeBatch={ + 'Comment': 'Record created or updated for automation', + 'Changes': [{ + 'Action': action, + 'ResourceRecordSet': { + 'Name': record_name, + 'Type': record_type, + 'TTL': record_ttl, + 'ResourceRecords': [{ + 'Value': record_value + }] + } + }] + } + ) + + def upsert_route_53_record_a( + self, record_name, record_value, action='UPSERT', + record_type='A', record_ttl=300): + return self._route53_client.change_resource_record_sets( + HostedZoneId=AWS_HOSTED_ZONE_ID, + ChangeBatch={ + 'Comment': 'Record created or updated for automation', + 'Changes': [{ + 'Action': action, + 'ResourceRecordSet': { + 'Name': record_name, + 'Type': record_type, + 'TTL': record_ttl, + 'ResourceRecords': [{ + 'Value': record_value + }] + } + }] + } + ) + + def delete_route_53_record(self, record_name): + record = None + try: + res = self._route53_client.list_resource_record_sets( + HostedZoneId=AWS_HOSTED_ZONE_ID, + StartRecordName=record_name, + MaxItems='1') + if len(res["ResourceRecordSets"]) > 0: + record = res["ResourceRecordSets"][0] + except ClientError as e: + print(e.response) + + if record is not None and record["Name"] == record_name: + self._route53_client.change_resource_record_sets( + HostedZoneId=AWS_HOSTED_ZONE_ID, + ChangeBatch={ + 'Comment': 'delete record', + 'Changes': [{ + 'Action': 'DELETE', + 'ResourceRecordSet': record}] + } + ) + + def decrypt_windows_password(self, instance_id): + password = "" + password_data = self._client. \ + get_password_data(InstanceId=instance_id)['PasswordData'] + if password_data: + password = base64.b64decode(password_data) + with open(self.get_ssh_key_path(AWS_SSH_KEY_NAME), 'r') \ + as privkeyfile: + priv = rsa.PrivateKey.load_pkcs1(privkeyfile.read()) + password = rsa.decrypt(password, priv).decode('utf-8') + + return password + + def get_ebs_volumes(self, provider_node_id): + node_filter = [{ + 'Name': 'attachment.instance-id', 'Values': [provider_node_id]}] + try: + response = self._client.describe_volumes(Filters=node_filter) + volumes = response.get('Volumes', []) + return volumes + except (Boto3Error, RuntimeError) as e: + msg = "Failed while querying instance '{}' volumes!: {}".format( + provider_node_id, str(e)) + raise RuntimeError(msg) + + def get_security_group_name(self, security_group_id): + sg_filter = [{ + 'Name': 'group-id', 'Values': [security_group_id]}] + try: + response = self._client.describe_security_groups(Filters=sg_filter) + security_groups = response.get('SecurityGroups', []) + if len(security_groups) > 0: + return security_groups[0]['GroupName'] + except Boto3Error as e: + msg = "Failed while querying security group name for '{}' " \ + "in region {}: {}".format(security_group_id, + AWS_REGION, str(e)) + raise RuntimeError(msg) + + def get_target_groups(self, lb_arn): + tg_list = [] + try: + res = self._elbv2_client.describe_listeners( + LoadBalancerArn=lb_arn) + except ClientError: + return tg_list + if res is not None: + for item in res["Listeners"]: + tg_arn = item["DefaultActions"][0]["TargetGroupArn"] + tg_list.append(tg_arn) + return tg_list + + def get_lb(self, name): + try: + res = self._elbv2_client.describe_load_balancers(Names=[name]) + return res['LoadBalancers'][0]['LoadBalancerArn'] + except ClientError: + return None + + def get_db(self, db_id): + try: + res = self._db_client.\ + describe_db_instances(DBInstanceIdentifier=db_id) + return res['DBInstances'][0]['DBInstanceIdentifier'] + except ClientError: + return None + + def delete_db(self, db_id): + try: + self._db_client.delete_db_instance(DBInstanceIdentifier=db_id, + SkipFinalSnapshot=True, + DeleteAutomatedBackups=True) + except ClientError: + return None + + def create_eks_cluster(self, name): + for sn in AWS_SUBNETS: + self.set_subnet_tag(sn, name) + kubeconfig_path = self.create_eks_controlplane(name) + self.create_eks_nodegroup(name, '{}-ng'.format(name)) + return kubeconfig_path + + def create_eks_controlplane(self, name): + vpcConfiguration = { + "subnetIds": AWS_SUBNETS, + "securityGroupIds": [AWS_SECURITY_GROUP], + "endpointPublicAccess": True, + "endpointPrivateAccess": False + } + + self._eks_client.\ + create_cluster(name=name, + version=EKS_VERSION, + roleArn=EKS_ROLE_ARN, + resourcesVpcConfig=vpcConfiguration) + + return self.wait_for_eks_cluster_state(name, "ACTIVE") + + def create_eks_nodegroup(self, cluster_name, name): + scaling_config = { + "minSize": 3, + "maxSize": 3, + "desiredSize": 3 + } + + remote_access = { + "ec2SshKey": AWS_SSH_KEY_NAME.replace('.pem', '') + } + + ng = self._eks_client.\ + create_nodegroup(clusterName=cluster_name, + nodegroupName=name, + scalingConfig=scaling_config, + diskSize=20, + subnets=AWS_SUBNETS, + instanceTypes=[AWS_INSTANCE_TYPE], + nodeRole=EKS_WORKER_ROLE_ARN, + remoteAccess=remote_access) + waiter_ng = self._eks_client.get_waiter('nodegroup_active') + waiter_ng.wait(clusterName=cluster_name, nodegroupName=name) + return ng + + def describe_eks_cluster(self, name): + try: + return self._eks_client.describe_cluster(name=name) + except ClientError: + return None + + def describe_eks_nodegroup(self, cluster_name, nodegroup_name): + try: + return self._eks_client.describe_nodegroup( + clusterName=cluster_name, + nodegroupName=nodegroup_name + ) + except ClientError: + return None + + def set_subnet_tag(self, subnet_id, cluster_name): + subnet = self._ec2_resource.Subnet(subnet_id) + cluster_tag = 'kubernetes.io/cluster/{0}'.format(cluster_name) + subnet.create_tags( + Tags=[ + { + 'Key': cluster_tag, + 'Value': 'shared' + } + ] + ) + + def wait_for_eks_cluster_state(self, name, target_state, timeout=1200): + start = time.time() + cluster = self.describe_eks_cluster(name)['cluster'] + status = cluster['status'] + while status != target_state: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to " + target_state) + + time.sleep(5) + cluster = self.describe_eks_cluster(name)['cluster'] + status = cluster['status'] + print(status) + return cluster + + def wait_for_delete_eks_cluster(self, cluster_name): + ng_names = self._eks_client.list_nodegroups(clusterName=cluster_name) + waiter_ng = self._eks_client.get_waiter('nodegroup_deleted') + for node_group in ng_names['nodegroups']: + print ("Waiting for deletion of nodegroup: {}".format(node_group)) + waiter_ng.wait(clusterName=cluster_name, nodegroupName=node_group) + print ("Waiting for deletion of cluster: {}".format(cluster_name)) + waiter = self._eks_client.get_waiter('cluster_deleted') + waiter.wait(name=cluster_name) + + def disable_source_dest_check(self, instance_id): + response = self._client.modify_instance_attribute( + SourceDestCheck={'Value': False}, + InstanceId=instance_id) + return response diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/cloud_provider.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/cloud_provider.py new file mode 100644 index 0000000..ec38306 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/cloud_provider.py @@ -0,0 +1,58 @@ +import abc +import os +from invoke import run + + +class CloudProviderBase(object, metaclass=abc.ABCMeta): + DOCKER_VERSION = os.environ.get("DOCKER_VERSION", '26.1') + DOCKER_INSTALLED = os.environ.get("DOCKER_INSTALLED", "false") + + @abc.abstractmethod + def create_node(self, node_name, wait_for_ready=False): + raise NotImplementedError + + @abc.abstractmethod + def stop_node(self, node, wait_for_stop=False): + raise NotImplementedError + + @abc.abstractmethod + def delete_node(self, wait_for_delete=False): + raise NotImplementedError + + @abc.abstractmethod + def import_ssh_key(self, ssh_key_name, public_ssh_key): + raise NotImplementedError + + @abc.abstractmethod + def delete_ssh_key(self, ssh_key_name): + raise NotImplementedError + + def save_master_key(self, ssh_key_name, ssh_key): + if not os.path.isfile('.ssh/{}'.format(ssh_key_name)): + run('mkdir -p .ssh') + with open('.ssh/{}'.format(ssh_key_name), 'w') as f: + f.write(ssh_key) + run("chmod 0600 .ssh/{0}".format(ssh_key_name)) + run("cat .ssh/{}".format(ssh_key_name)) + + def generate_ssh_key(self, ssh_key_name, ssh_key_passphrase=''): + try: + if not os.path.isfile('.ssh/{}'.format(ssh_key_name)): + run('mkdir -p .ssh && rm -rf .ssh/{}'.format(ssh_key_name)) + run("ssh-keygen -N '{1}' -C '{0}' -f .ssh/{0}".format( + ssh_key_name, ssh_key_passphrase)) + run("chmod 0600 .ssh/{0}".format(ssh_key_name)) + + public_ssh_key = self.get_ssh_key(ssh_key_name + '.pub') + except Exception as e: + raise Exception("Failed to generate ssh key: {0}".format(e)) + return public_ssh_key + + def get_ssh_key(self, ssh_key_name): + with open(self.get_ssh_key_path(ssh_key_name), 'r') as f: + ssh_key = f.read() + return ssh_key + + def get_ssh_key_path(self, ssh_key_name): + key_path = os.path.abspath('.ssh/{}'.format(ssh_key_name)) + return key_path diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/digital_ocean.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/digital_ocean.py new file mode 100644 index 0000000..5e2a6eb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/digital_ocean.py @@ -0,0 +1,160 @@ +import digitalocean +import os +import time + +from .cloud_provider import CloudProviderBase +from .node import Node + + +PRIVATE_IMAGES = { + "ubuntu-16.04-docker-1.12.6": { + 'image': 30447985, 'ssh_user': 'ubuntu'}, + "ubuntu-16.04-docker-17.03": { + 'image': 30473722, 'ssh_user': 'ubuntu'}, + "ubuntu-16.04-docker-1.13.1": { + 'image': 30473815, 'ssh_user': 'ubuntu'}} + +DO_TOKEN = os.environ.get("DO_TOKEN") +DO_SSH_KEY_ID = os.environ.get("DO_SSH_KEY_ID") +DO_SSH_KEY_NAME = os.environ.get("DO_SSH_KEY_NAME") + + +class DigitalOcean(CloudProviderBase): + DROPLET_STATE_MAP = { + 'running': 'create', + 'stopped': 'shutdown', + 'terminated': 'destroy' + } + + def __init__(self): + self._manager = digitalocean.Manager(token=DO_TOKEN) + self._token = DO_TOKEN + + if DO_SSH_KEY_NAME: + self.master_ssh_private_key = self.get_ssh_key(DO_SSH_KEY_NAME) + self.master_ssh_public_key = self.get_ssh_key( + DO_SSH_KEY_NAME + '.pub') + self.master_ssh_private_key_path = self.get_ssh_key_path( + DO_SSH_KEY_NAME) + + def _select_ami(self, os_version=None, docker_version=None): + os_version = os_version or self.OS_VERSION + docker_version = docker_version or self.DOCKER_VERSION + image = PRIVATE_IMAGES[ + "{}-docker-{}".format(os_version, docker_version)] + return image['image'], image['ssh_user'] + + def create_node( + self, node_name, key_name=None, os_version=None, docker_version=None, + wait_for_ready=True): + + os_version = os_version or self.OS_VERSION + docker_version = docker_version or self.DOCKER_VERSION + image, ssh_user = self._select_ami(os_version, docker_version) + + if key_name: + # get private key + ssh_private_key_name = key_name.replace('.pub', '') + ssh_private_key = self.get_ssh_key(ssh_private_key_name) + ssh_private_key_path = self.get_ssh_key_path(ssh_private_key_name) + + ssh_key_id = self._get_ssh_key_id(key_name) + + droplet = digitalocean.Droplet( + token=self._token, + name=node_name, + region='sfo1', + image=image, + size_slug='2gb', + ssh_keys=[ssh_key_id], + backups=False) + droplet.create() + + node = Node( + provider_node_id=droplet.id, + state=droplet.status, + ssh_user=ssh_user, + ssh_key_name=ssh_private_key_name, + ssh_key_path=ssh_private_key_path, + ssh_key=ssh_private_key, + os_version=os_version, + docker_version=docker_version) + + if wait_for_ready: + self.wait_for_node_state(node) + node.wait_for_ssh_ready() + return node + + def create_multiple_nodes( + self, number_of_nodes, node_name_prefix, os_version=None, + docker_version=None, key_name=None, wait_for_ready=True): + + nodes = [] + for i in range(number_of_nodes): + node_name = "{}_{}".format(node_name_prefix, i) + nodes.append(self.create_node( + node_name, key_name=key_name, os_version=os_version, + docker_version=docker_version, wait_for_ready=False)) + + if wait_for_ready: + nodes = self.wait_for_nodes_state(nodes) + for node in nodes: + node.wait_for_ssh_ready() + return nodes + + def get_node(self, provider_id): + droplet = self._manager.get_droplet(provider_id) + node = Node( + provider_node_id=droplet.id, + node_name=droplet.name, + ip_address=droplet.ip_address, + state=droplet.status, + labels=droplet.tags) + return node + + def stop_node(self, node, wait_for_stopped=False): + droplet = self._manager.get_droplet(node.provider_node_id) + droplet.shutdown() + + if wait_for_stopped: + self.wait_for_node_state(node, 'stopped') + + def delete_node(self, node, wait_for_deleted=False): + droplet = self._manager.get_droplet(node.provider_node_id) + droplet.destroy() + + if wait_for_deleted: + self.wait_for_node_state(node, 'terminated') + + def wait_for_node_state(self, node, state='running'): + action_type = self.DROPLET_STATE_MAP[state] + droplet = self._manager.get_droplet(node.provider_node_id) + actions = droplet.get_actions() + + action = None + for item in actions: + if item.type == action_type: + action = item + break + else: + raise Exception( + "Unable to find action for {0}: {1}".format( + state, action_type)) + + timeout = 300 + start_time = start_time = time.time() + while action.status != "completed": + if time.time() - start_time > timeout: + raise Exception("{0} node timed out".format(state)) + action.load() + + if action_type == "create": + droplet.load() + node.host_name = droplet.name + node.ip_address = droplet.ip_address + node.labels = droplet.tags + node.state = action_type + + def _get_ssh_key_id(self, key_name): + pass + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/kubectl_client.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/kubectl_client.py new file mode 100644 index 0000000..703e66a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/kubectl_client.py @@ -0,0 +1,232 @@ +import os +import json +import time +import subprocess + +DEBUG = os.environ.get('DEBUG', 'false') +CONFORMANCE_YAML = ("tests/kubernetes_conformance/resources/k8s_ymls/" + "sonobuoy-conformance.yaml") + + +class KubectlClient(object): + + def __init__(self): + self._kube_config_path = None + self._hide = False if DEBUG.lower() == 'true' else True + + @property + def kube_config_path(self): + return self._kube_config_path + + @kube_config_path.setter + def kube_config_path(self, value): + self._kube_config_path = value + + @staticmethod + def _load_json(output): + if output == '': + return None + return json.loads(output) + + def _default_output_json(self, **cli_options): + """ + Adds --output=json to options + Does not override if output is passed in! + """ + if 'output' not in list(cli_options.keys()): + cli_options['output'] = 'json' + return cli_options + + def _cli_options(self, **kwargs): + """ + Pass through any kubectl option + A couple of exceptions for the keyword args mapping to the + cli options names: + 1) if option flag has a '-', replace with '_' + e.i. '--all-namespaces' can be passed in all_namespaces=True + 2) reserved words: + For cli option: 'as' => 'as_user' + """ + command_options = "" + for k, v in kwargs.items(): + # Do not include values that are none + if v is None: + continue + # reserved word + k = 'as' if k == 'as_user' else k + # k = 'all' if k == 'all_' else k + if v is False or v is True: + value = str(v).lower() + else: + value = v + command_options += " --{}={}".format(k.replace('_', '-'), value) + return command_options + + def execute_kubectl_cmd(self, cmd, json_out=True): + command = 'kubectl --kubeconfig {0} {1}'.format( + self.kube_config_path, cmd) + if json_out: + command += ' -o json' + print("Running kubectl command: {}".format(command)) + start_time = time.time() + result = self.run_command(command) + end_time = time.time() + print('Run time for command {0}: {1} seconds'.format( + command, end_time - start_time)) + return result + + def execute_kubectl(self, cmd, **cli_options): + # always add kubeconfig + cli_options['kubeconfig'] = self.kube_config_path + command = 'kubectl {0}{1}'.format( + cmd, self._cli_options(**cli_options)) + print("Running kubectl command: {}".format(command)) + start_time = time.time() + result = self.run_command_with_stderr(command) + end_time = time.time() + print('Run time for command {0}: {1} seconds'.format( + command, end_time - start_time)) + return result + + def exec_cmd(self, pod, cmd, namespace): + result = self.execute_kubectl_cmd( + 'exec {0} --namespace={1} -- {2}'.format(pod, namespace, cmd), + json_out=False) + return result + + def logs(self, pod='', **cli_options): + command = 'logs {0}'.format(pod) if pod else "logs" + result = self.execute_kubectl(command, **cli_options) + return result + + def cp_from_pod(self, pod, namespace, path_in_pod, local_path): + command = "cp {}/{}:{} {}".format( + namespace, pod, path_in_pod, local_path) + return self.execute_kubectl(command) + + def list_namespaces(self): + ns = self.get_resource("namespace") + return [n['metadata']['name'] for n in ns['items']] + + def get_nodes(self): + nodes = self.get_resource("nodes") + return nodes + + def create_ns(self, namespace): + self.create_resource("namespace", namespace) + # Verify namespace is created + ns = self.get_resource("namespace", name=namespace) + assert ns["metadata"]["name"] == namespace + assert ns["status"]["phase"] == "Active" + return ns + + def run(self, name, **cli_options): + command = "run {0}".format(name) + result = self.execute_kubectl(command, **cli_options) + return result + + def create_resourse_from_yml(self, file_yml, namespace=None): + cmd = "create -f {0}".format(file_yml) + if namespace: + cmd += ' --namespace={0}'.format(namespace) + return self.execute_kubectl_cmd(cmd) + + def delete_resourse_from_yml(self, file_yml, namespace=None): + cmd = "delete -f {0}".format(file_yml) + if namespace: + cmd += ' --namespace={0}'.format(namespace) + return self.execute_kubectl_cmd(cmd, json_out=False) + + def create_resource(self, resource, name=None, **cli_options): + cli_options = self._default_output_json(**cli_options) + command = "create {0}".format(resource) + if name: + command += ' {0}'.format(name) + result = self.execute_kubectl(command, **cli_options) + return self._load_json(result) + + def get_resource(self, resource, name=None, **cli_options): + cli_options = self._default_output_json(**cli_options) + command = "get {0}".format(resource) + if name: + command += ' {0}'.format(name) + result = self.execute_kubectl(command, **cli_options) + return self._load_json(result) + + def delete_resourse(self, resource, name=None, **cli_options): + command = "delete {0}".format(resource) + if name: + command += ' {0}'.format(name) + return self.execute_kubectl(command, **cli_options) + + def wait_for_pods(self, number_of_pods=1, state='Running', **cli_options): + start_time = int(time.time()) + while True: + pods = self.get_resource('pods', **cli_options) + print("pods:") + print(pods) + print (len(pods['items'])) + if len(pods['items']) == number_of_pods: + running_pods = 0 + for pod in pods['items']: + print (pod['status']['phase']) + if pod['status']['phase'] != state: + print("Pod '{0}' not {1} is {2}!".format( + pod['metadata']['name'], state, + pod['status']['phase'])) + break + else: + running_pods += 1 + if running_pods == number_of_pods: + return pods + if int(time.time()) - start_time > 300: + pod_states = {} + for p in pods.get('items', []): + pod_states[p['metadata']['name']] = p['status']['phase'] + raise Exception( + 'Timeout Exception: pods did not start\n' + 'Expect number of pods {0} vs number of pods found {1}:\n' + 'Pod states: {2}'.format( + number_of_pods, len(pod_states), pod_states)) + time.sleep(5) + + def wait_for_pod(self, name, state='Running', **cli_options): + """ + If a pod name is known, wait for pod to start + """ + start_time = int(time.time()) + while True: + pod = self.get_resource('pod', name=name, **cli_options) + if pod['status']['phase'] != state: + print("Pod '{0}' not {1} is {2}!".format( + pod['metadata']['name'], state, pod['status']['phase'])) + else: + time.sleep(15) + return pod + if int(time.time()) - start_time > 300: + raise Exception( + 'Timeout Exception: pod {} did not start\n'.format(name)) + time.sleep(5) + + def apply_conformance_tests(self): + command = "apply -f {0}".format(CONFORMANCE_YAML) + result = self.execute_kubectl_cmd(command) + assert result.ok, ( + "Failed to apply sonobuoy-conformance.yaml.\nCommand: '{0}'\n" + "stdout: {1}\nstderr:{2}\n".format( + command, result.stdout, result.stderr)) + return result + + def run_command(self, command): + return subprocess.check_output(command, shell=True, text=True) + + def run_command_with_stderr(self, command): + try: + return subprocess.check_output(command, shell=True, + stderr=subprocess.PIPE) + except subprocess.CalledProcessError as e: + print(e.output) + print(e.stderr) + output = e.output + returncode = e.returncode + print(returncode) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/node.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/node.py new file mode 100644 index 0000000..9450b63 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/node.py @@ -0,0 +1,165 @@ +import json +import logging +import paramiko +import time + + +logging.getLogger("paramiko").setLevel(logging.CRITICAL) +DOCKER_INSTALL_CMD = ( + "curl https://releases.rancher.com/install-docker/{0}.sh | sh") + + +class Node(object): + def __init__(self, provider_node_id=None, host_name=None, node_name=None, + public_ip_address=None, private_ip_address=None, state=None, + labels=None, host_name_override=None, ssh_key=None, + ssh_key_name=None, ssh_key_path=None, ssh_user=None, + docker_version=None, docker_installed="false"): + + self.provider_node_id = provider_node_id + # node name giving to k8s node, hostname override + self.node_name = node_name + # Depending on the RKE config, this can be updated to be + # either the internal IP, external IP address or FQDN name + self.node_address = None + self.host_name = host_name + self.host_name_override = host_name_override + self.public_ip_address = public_ip_address + self.private_ip_address = private_ip_address + self.ssh_user = ssh_user + self.ssh_key = ssh_key + self.ssh_key_name = ssh_key_name + self.ssh_key_path = ssh_key_path + self.docker_version = docker_version + self.docker_installed = docker_installed + self._roles = [] + self.labels = labels or {} + self.state = state + self._ssh_client = paramiko.SSHClient() + self._ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.ssh_port = '22' + self._ssh_password = None + + @property + def ssh_password(self): + return self._ssh_password + + @ssh_password.setter + def ssh_password(self, password): + self._ssh_password = password + + @property + def roles(self): + return self._roles + + @roles.setter + def roles(self, r): + self._roles = r + + def wait_for_ssh_ready(self): + command = 'whoami' + start_time = int(time.time()) + logs_while_waiting = '' + while int(time.time()) - start_time < 100: + try: + self._ssh_client.connect( + self.public_ip_address, username=self.ssh_user, + key_filename=self.ssh_key_path, port=int(self.ssh_port)) + result = self._ssh_client.exec_command(command) + if result and len(result) == 3 and result[1].readable(): + result = [result[1].read(), result[2].read()] + self._ssh_client.close() + return True + except Exception as e: + self._ssh_client.close() + time.sleep(3) + logs_while_waiting += str(e) + '\n' + continue + raise Exception( + "Unable to connect to node '{0}' by SSH: {1}".format( + self.public_ip_address, logs_while_waiting)) + + def execute_command(self, command): + result = None + try: + if self.ssh_password is not None: + self._ssh_client.connect( + self.public_ip_address, username=self.ssh_user, + password=self.ssh_password, port=int(self.ssh_port)) + else: + self._ssh_client.connect( + self.public_ip_address, username=self.ssh_user, + key_filename=self.ssh_key_path, port=int(self.ssh_port)) + + result = self._ssh_client.exec_command(command) + if result and len(result) == 3 and result[1].readable(): + result = [str(result[1].read(), 'utf-8'), + str(result[2].read(), 'utf-8')] + finally: + self._ssh_client.close() + return result + + def install_docker(self): + # TODO: Fix to install native on RHEL 7.4 + command = ( + "{} && sudo usermod -aG docker {} && sudo systemctl enable docker" + .format( + DOCKER_INSTALL_CMD.format(self.docker_version), + self.ssh_user)) + return self.execute_command(command) + + def ready_node(self): + # ignore Windows node + if self.ssh_user == "Administrator": + return + + self.wait_for_ssh_ready() + if self.docker_installed.lower() == 'false': + self.install_docker() + + def docker_ps(self, all=False, includeall=False): + result = self.execute_command( + 'docker ps --format "{{.Names}}\t{{.Image}}"') + if includeall: + print("Docker ps including all containers") + result = self.execute_command( + 'docker ps -a --format "{{.Names}}\t{{.Image}}"') + if result[1] != '': + raise Exception( + "Error:'docker ps' command received this stderr output: " + "{0}".format(result[1])) + parse_out = result[0].strip('\n').split('\n') + ret_dict = {} + if parse_out == '': + return ret_dict + for item in parse_out: + item0, item1 = item.split('\t') + ret_dict[item0] = item1 + return ret_dict + + def docker_inspect(self, container_name, output_format=None): + if output_format: + command = 'docker inspect --format \'{0}\' {1}'.format( + output_format, container_name) + else: + command = 'docker inspect {0}'.format(container_name) + result = self.execute_command(command) + if result[1] != '': + raise Exception( + "Error:'docker inspect' command received this stderr output: " + "{0}".format(result[1])) + result = json.loads(result[0]) + return result + + def docker_exec(self, container_name, cmd): + command = 'docker exec {0} {1}'.format(container_name, cmd) + result = self.execute_command(command) + print(result) + if result[1] != '': + raise Exception( + "Error:'docker exec' command received this stderr output: " + "{0}".format(result[1])) + return result[0] + + def get_public_ip(self): + return self.public_ip_address diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/rke_client.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/rke_client.py new file mode 100644 index 0000000..4a25947 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/lib/rke_client.py @@ -0,0 +1,147 @@ +import os +import jinja2 +import logging +import tempfile +import time +import subprocess +from yaml import safe_load + + +logging.getLogger('invoke').setLevel(logging.WARNING) +DEBUG = os.environ.get('DEBUG', 'false') + +DEFAULT_CONFIG_NAME = 'cluster.yml' +DEFAULT_NETWORK_PLUGIN = os.environ.get('DEFAULT_NETWORK_PLUGIN', 'canal') +K8S_VERSION = os.environ.get('RANCHER_K8S_VERSION', "") + + +class RKEClient(object): + """ + Wrapper to interact with the RKE cli + """ + def __init__(self, master_ssh_key_path, template_path): + self.master_ssh_key_path = master_ssh_key_path + self.template_path = template_path + self._working_dir = tempfile.mkdtemp() + self._hide = False if DEBUG.lower() == 'true' else True + + def _run(self, command): + print('Running command: {}'.format(command)) + start_time = time.time() + result = self.run_command('cd {0} && {1}'.format(self._working_dir, + command)) + end_time = time.time() + print('Run time for command {0}: {1} seconds'.format( + command, end_time - start_time)) + return result + + def up(self, config_yml, config=None): + yml_name = config if config else DEFAULT_CONFIG_NAME + self._save_cluster_yml(yml_name, config_yml) + cli_args = '' if config is None else ' --config {0}'.format(config) + result = self._run("rke up {0}".format(cli_args)) + print( + "RKE kube_config:\n{0}".format(self.get_kube_config_for_config())) + return result + + def remove(self, config=None): + result = self._run("rke remove --force") + return result + + def build_rke_template(self, template, nodes, **kwargs): + """ + This method builds RKE cluster.yml from a template, + and updates the list of nodes in update_nodes + """ + render_dict = { + 'master_ssh_key_path': self.master_ssh_key_path, + 'network_plugin': DEFAULT_NETWORK_PLUGIN, + 'k8s_version': K8S_VERSION + } + render_dict.update(kwargs) # will up master_key if passed in + node_index = 0 + for node in nodes: + node_dict = { + 'ssh_user_{}'.format(node_index): node.ssh_user, + 'ip_address_{}'.format(node_index): node.public_ip_address, + 'dns_hostname_{}'.format(node_index): node.host_name, + 'ssh_key_path_{}'.format(node_index): node.ssh_key_path, + 'ssh_key_{}'.format(node_index): node.ssh_key, + 'internal_address_{}'.format(node_index): + node.private_ip_address, + 'hostname_override_{}'.format(node_index): + node.node_name + } + render_dict.update(node_dict) + node_index += 1 + yml_contents = jinja2.Environment( + loader=jinja2.FileSystemLoader(self.template_path) + ).get_template(template).render(render_dict) + print("Generated cluster.yml contents:\n", yml_contents) + nodes = self.update_nodes(yml_contents, nodes) + return yml_contents, nodes + + @staticmethod + def convert_to_dict(yml_contents): + return safe_load(yml_contents) + + def update_nodes(self, yml_contents, nodes): + """ + This maps some rke logic for how the k8s nodes is configured to + the nodes created by the cloud provider, so that the nodes list + is the source of truth to validated against kubectl calls + """ + yml_dict = self.convert_to_dict(yml_contents) + for dict_node in yml_dict['nodes']: + for node in nodes: + if node.public_ip_address == dict_node['address'] or \ + node.host_name == dict_node['address']: + # dep + node.host_name = dict_node['address'] + if dict_node.get('hostname_override'): + node.node_name = dict_node['hostname_override'] + else: + node.node_name = node.host_name + node.roles = dict_node['role'] + + # if internal_address is given, used to communicate + # this is the expected ip/value in nginx.conf + node.node_address = node.host_name + if dict_node.get('internal_address'): + node.node_address = dict_node['internal_address'] + break + return nodes + + def _save_cluster_yml(self, yml_name, yml_contents): + file_path = "{}/{}".format(self._working_dir, yml_name) + with open(file_path, 'w') as f: + f.write(yml_contents) + + def get_kube_config_for_config(self, yml_name=DEFAULT_CONFIG_NAME): + file_path = "{}/kube_config_{}".format(self._working_dir, yml_name) + with open(file_path, 'r') as f: + kube_config = f.read() + return kube_config + + def kube_config_path(self, yml_name=DEFAULT_CONFIG_NAME): + return os.path.abspath( + "{}/kube_config_{}".format(self._working_dir, yml_name)) + + def save_kube_config_locally(self, yml_name=DEFAULT_CONFIG_NAME): + file_name = 'kube_config_{}'.format(yml_name) + contents = self.get_kube_config_for_config(yml_name) + with open(file_name, 'w') as f: + f.write(contents) + + def run_command(self, command): + return subprocess.check_output(command, shell=True, text=True) + + def run_command_with_stderr(self, command): + try: + output = subprocess.check_output(command, shell=True, + stderr=subprocess.PIPE) + returncode = 0 + except subprocess.CalledProcessError as e: + output = e.output + returncode = e.returncode + print(returncode) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/readme.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/readme.md new file mode 100644 index 0000000..62bfddb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/readme.md @@ -0,0 +1,151 @@ +# Validation scripts for Rancher + +Validation tests are run in a similar way to integration tests. + +From tests/validation dir: + +* Setup virtualenv and enter it +* `pip install -r requirements_v3api.txt` +* Export any needed environment vars, many of these like `CATTLE_TEST_URL` are required. See below for more info. + +Now run a test: +* File: `pytest -v -s tests/v3_api/test_app.py` +* Single test:`pytest -k test_tiller` + +# General Notes about this framework current status: + +## Linting +Uses [Flake8](http://flake8.pycqa.org/en/latest/) to lint your tests + +## ENV Variables: +If you add any new ENV variables, check the scripts/rke/configure.sh will pass them into the container for Jenkins. Running on your own machine, export these variables as needed. + +### General +DEBUG defaults to 'false', Prints the output from kubectl and rke commands when 'true' + +### Base Cloud Provider variables: +``` +OS_VERSION defaults to 'ubuntu-16.04', Used to select which image to use +DOCKER_VERSION defaults to '1.12.6', Used to select image to use if DOCKER_INSTALLED is 'true' +DOCKER_INSTALLED defaults to 'true', When false, base image is used for OS_VERSION, and docker version DOCKER_VERSION is installed +``` + +### Digital Ocean specific variables: +``` +DO_ACCESS_KEY no default, your DO access key +``` + +### AWS specific variables: +``` +AWS_ACCESS_KEY_ID no default, your AWS access key id +AWS_SECRET_ACCESS_KEY no default, your AWS secret access key +AWS_SSH_KEY_NAME no default, the filename of the private key, e.i. jenkins-rke-validation.pem +AWS_CICD_INSTANCE_TAG defaults to 'rancher-validation', Tags the instance with CICD=AWS_CICD_INSTANCE_TAG +AWS_INSTANCE_TYPE defaults to 't3a.medium', selects the instance type and size +AWS_REGION no default, the region for your ec2 instances +AWS_SUBNET no default, the subnet for your ec2 instances +AWS_VPC no default, the VPC for your ec2 instances +AWS_SG no default, the SG for your ec2 instances +AWS_ZONE no default, the zone for your ec2 instances +AWS_IAM_PROFILE no default, the IAM profile for your ec2 instances +``` + +### Azure specific variables: +``` +AZURE_SUBSCRIPTION_ID no default, your Azure subscription id +AZURE_CLIENT_ID no default, your app / client id +AZURE_CLIENT_SECRET no default, your app / client secret +AZURE_TENANT_ID no default your Azure tenant id, for use with Azure cloud provider +``` + +### v3_api test variables: +``` +CATTLE_TEST_URL no default. The Rancher server for test execution. +ADMIN_TOKEN no default. Required to create resources during test execution +RANCHER_CLEANUP_CLUSTER default true. Cleans up clusters after test execution +RANCHER_CLEANUP_PROJECT default true. Cleans up projects after test execution +RANCHER_CLUSTER_NAME no default. Some tests allow test resources to be created in a specific cluster. If not provided, tests will default to the first cluster found. +``` +### vmwarevsphere_driver test +Because our vSphere servers are behind a VPN you will need to connect to the VPN and run these tests from your laptop +or run them from a Rancher installation inside of vSphere. When running locally on your laptop you will need to connect +the VPN and start an ngrok tunnel and set your SERVER_URL by hand to get vSphere nodes to talk back to the Rancher Server + +Environment variables for this test +``` +CATTLE_TEST_URL no default. The Rancher server for test execution. +RANCHER_CLUSTER_NAME defaults to a random cluster name if not set +RANCHER_CLEANUP_CLUSTER defaults to "True", set to "False" to leave the cluster after the test +RANCHER_VSPHERE_USERNAME username used to login to vSphere Admin Interface +RANCHER_VSPHERE_PASSWORD password used to login to vSphere Admin Interface +RANCHER_VSPHERE_VCENTER URL of vCenter web interface +RANCHER_VSPHERE_VCENTER_PORT port of vCenter web interface, defaults to 443 +RANCHER_ENGINE_INSTALL_URL defaults to https://get.docker.com/, docker installer engine script +RANCHER_CLONE_FROM defaults to ubuntu-bionic-18.04-cloudimg, vm to clone from. +RANCHER_RESOURCE_POOL defaults to the validation-tests pool resource pool to put the vms in +``` +### oke_cluster test +Environment variables for the Oracle Container Engine (OKE) cluster test +``` +CATTLE_TEST_URL no default. The Rancher server for test execution. +USER_TOKEN user token used for /meta/oci/ calls +RANCHER_OCI_TENANCY_OCID required OCID of the tenancy in which to create the cluster and resources +RANCHER_OCI_COMPARTMENT_OCID required OCID of the compartment in which to create the cluster and resources +RANCHER_OCI_USER_OCID required OCID of a user who has access to the specified tenancy/compartment +RANCHER_OCI_FINGERPRINT URL required fingerprint corresponding to the specified user's private API Key +RANCHER_OCI_PRIVATE_KEY_PATH required private API key path for the specified OCI user, in PEM format +RANCHER_OCI_PRIVATE_KEY_PASSPHRASE required if user private key is protected with a passphrase +RANCHER_OCI_REGION defaults to us-phoenix-1 +RANCHER_OKE_VERSION defaults to latest version +RANCHER_OKE_NODE_SHAPE defaults to random OKE node shape +RANCHER_OKE_NODE_IMAGE defaults to latest Oracle Linux node image +``` + +## RKE template defaults variables: +``` +DEFAULT_K8S_IMAGE defaults to 'rancher/k8s:v1.8.7-rancher1-1', defaults the templates service images +DEFAULT_NETWORK_PLUGIN defaults to 'canal', defaults the templates to use the select network plugin +``` + +## Passing other pytest command line options +In the Jenkins job parameters PYTEST_OPTIONS can be used to pass additional command line options to pytest like test filtering or run in parallel: + +Run tests methods that match 'install_roles' +PYTEST_OPTION = -k install_roles + +Run in parallel: +PYTEST_OPTION = -n auto + +Multiple options can be passed in '-k install_roles -n auto' + +## Issue 316 +Currently an issue with Ubuntu-16.04, https://github.com/rancher/rke/issues/316 +prevents us from using a AMI where docker is already installed. + +At first we tried rebooting in rancher validation/lib/aws.py: +``` + if wait_for_ready: + nodes = self.wait_for_nodes_state(nodes) + # hack for instances + # self.reboot_nodes(nodes) + # time.sleep(5) + # nodes = self.wait_for_nodes_state(nodes) + for node in nodes: + node.ready_node() + return nodes +``` +After a while I still ran into the issue. If you need to get around this, the setting the ENV variable: DOCKER_INSTALLED=false will instead use +the base ubuntu-16.04 image provided by AWS and install the version of docker specificed by DOCKER_VERSION + +## Docker image container-util +I added files images/container-utils as tool to test DNS and Intercommunication between pods/containers. It is a simple flask application, but the image also includes cli tools like 'curl', 'dig', and 'ping' + +## Helpful docs: +AWS boto3 package docs: +https://boto3.readthedocs.io/en/latest/reference/services/ec2.html + +DigitalOcean package docs: +https://github.com/koalalorenzo/python-digitalocean + +Invoke docs (used to run commands like 'kubectl' and 'rke'): +http://docs.pyinvoke.org/en/latest/ diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements.txt new file mode 100644 index 0000000..2031e5c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements.txt @@ -0,0 +1,13 @@ +pytest==6.2.5 +pytest-repeat==0.8.0 +pytest-xdist==2.0.0 +boto3==1.21.46 +cryptography==42.0.4 +flake8==3.5.0 +invoke==1.2.0 +Jinja2==3.1.3 +kubernetes==12.0.1 +paramiko==3.4.0 +python-digitalocean==1.13.2 +PyYAML==6.0.1 +packaging==23.1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements_v3api.txt b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements_v3api.txt new file mode 100644 index 0000000..b27e571 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/requirements_v3api.txt @@ -0,0 +1,24 @@ +git+https://github.com/rancher/client-python.git@master#egg=client-python +boto3==1.21.46 +cryptography==42.0.4 +flake8==3.5.0 +invoke==1.2.0 +Jinja2==3.1.3 +kubernetes==12.0.1 +netaddr==0.8.0 +paramiko==3.4.0 +PyJWT==2.4.0 +pytest==6.2.5 +pytest-repeat==0.8.0 +pytest-xdist==2.0.0 +pytest-html==3.2.0 +pytest-ordering>=0.6 +python-digitalocean==1.13.2 +python-terraform==0.10.1 +PyYAML==6.0.1 +requests==2.31.0 +rsa==4.7.2 +websocket-client==0.57.0 +semver==2.13.0 +packaging==23.1 +pluggy==1.2.0 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/Dockerfile new file mode 100644 index 0000000..b394596 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/Dockerfile @@ -0,0 +1,18 @@ +FROM nginx + +RUN apt-get update + +RUN apt-get install -y wget +RUN apt-get install -y curl +RUN apt-get install -y iptables +RUN apt-get install -y dnsutils +RUN apt-get install -y iputils-ping + +COPY ./run.sh /scripts/run.sh +RUN chmod 777 /scripts/run.sh + +COPY ./nginx.conf /etc/nginx/conf.d/default.conf +RUN chmod 644 /etc/nginx/conf.d/default.conf + +ENTRYPOINT [ "/scripts/run.sh" ] +CMD ["nginx", "-g", "daemon off;"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/nginx.conf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/nginx.conf new file mode 100644 index 0000000..a588265 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/nginx.conf @@ -0,0 +1,15 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/run.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/run.sh new file mode 100644 index 0000000..bfa4fbb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/testcontainer/run.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ -z "$CONTAINER_NAME" ]; then + hostname > /usr/share/nginx/html/name.html + hostname > /usr/share/nginx/html/service1.html + hostname > /usr/share/nginx/html/service2.html +else + echo ${CONTAINER_NAME} > /usr/share/nginx/html/name.html + echo ${CONTAINER_NAME} > /usr/share/nginx/html/service1.html + echo ${CONTAINER_NAME} > /usr/share/nginx/html/service2.html +fi +exec "$@" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/Dockerfile new file mode 100644 index 0000000..e21a74a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/Dockerfile @@ -0,0 +1,22 @@ +FROM nginxinc/nginx-unprivileged as base + +USER root +RUN apt-get update + +RUN apt-get install -y wget +RUN apt-get install -y curl +RUN apt-get install -y iptables +RUN apt-get install -y dnsutils +RUN apt-get install -y iputils-ping + +COPY ./run.sh /scripts/run.sh +RUN chmod 777 /scripts/run.sh +RUN chmod 777 /usr/share/nginx/html + +COPY ./nginx.conf /etc/nginx/conf.d/default.conf +RUN chmod 644 /etc/nginx/conf.d/default.conf + +USER 101 + +ENTRYPOINT [ "/scripts/run.sh" ] +CMD ["nginx", "-g", "daemon off;"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/nginx.conf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/nginx.conf new file mode 100644 index 0000000..d2efa8d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/nginx.conf @@ -0,0 +1,15 @@ +server { + listen 8080; + listen [::]:8080; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/run.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/run.sh new file mode 100644 index 0000000..bfa4fbb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/unprivileged-testcontainer/run.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ -z "$CONTAINER_NAME" ]; then + hostname > /usr/share/nginx/html/name.html + hostname > /usr/share/nginx/html/service1.html + hostname > /usr/share/nginx/html/service2.html +else + echo ${CONTAINER_NAME} > /usr/share/nginx/html/name.html + echo ${CONTAINER_NAME} > /usr/share/nginx/html/service1.html + echo ${CONTAINER_NAME} > /usr/share/nginx/html/service2.html +fi +exec "$@" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/Dockerfile new file mode 100644 index 0000000..81283ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/Dockerfile @@ -0,0 +1,25 @@ +ARG SERVERCORE + +FROM mcr.microsoft.com/windows/servercore:$SERVERCORE as builder +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +ENV NODE_VERSION 10.16.0 +RUN $URL = ('https://nodejs.org/dist/v{0}/node-v{0}-win-x64.zip' -f $env:NODE_VERSION); \ + \ + Write-Host ('Downloading Nodejs from {0} ...' -f $URL); \ + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ + Invoke-WebRequest -UseBasicParsing -OutFile c:\node.zip -Uri $URL; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive -Force -Path c:\node.zip -DestinationPath c:\; \ + Rename-Item -Path $('c:\node-v{0}-win-x64' -f $env:NODE_VERSION) -NewName 'c:\nodejs'; \ + \ + Write-Host 'Cleaning ...'; \ + Remove-Item -Force -Recurse -Path c:\node.zip; \ + \ + Write-Host 'Complete.' + +SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +COPY ["app.js", "c:/web/"] +EXPOSE 8080 +WORKDIR /web +CMD ["powershell", "Start-Process", "-NoNewWindow", "-Wait", "-FilePath", "c:/nodejs/node.exe", "-ArgumentList", "c:/web/app.js"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/app.js b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/app.js new file mode 100644 index 0000000..a4c0c36 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/metrics/app.js @@ -0,0 +1,18 @@ +var http = require('http'); +var url = require('url'); +var number = 0; + +http.createServer(function (req, res) { + var urlParts = url.parse(req.url); + if (urlParts.pathname !== '/favicon.ico') { + if ( urlParts.pathname === '/metrics' ) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('web_app_online_user_count ' + number + '\n'); + } else { + number++; + console.log('logan'); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello There!' + number + '\n'); + } + } +}).listen(8080); diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/nginx/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/nginx/Dockerfile new file mode 100644 index 0000000..4b43600 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/nginx/Dockerfile @@ -0,0 +1,14 @@ +ARG SERVERCORE + +FROM mcr.microsoft.com/windows/servercore:$SERVERCORE +SHELL ["powershell", "-NoLogo", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +ENV NGINX_WORKDIR "c:\\Program Files\\nginx" +ENV NGINX_VERSION "1.16.0" +RUN [Environment]::SetEnvironmentVariable('PATH', ('{0};{1}' -f $env:NGINX_WORKDIR, $env:PATH), [EnvironmentVariableTarget]::Machine); \ + Invoke-WebRequest -Uri ('https://nginx.org/download/nginx-{0}.zip' -f $env:NGINX_VERSION) -OutFile nginx.zip; \ + Expand-Archive nginx.zip -DestinationPath $env:ProgramFiles; \ + Remove-Item -Force nginx.zip; \ + Move-Item $env:ProgramFiles\nginx-* $env:NGINX_WORKDIR +EXPOSE 80 443 +WORKDIR $NGINX_WORKDIR +CMD ["powershell", "Start-Process", "-NoNewWindow", "-FilePath", "nginx.exe", ";", "Add-Content", "logs/access.log", "'nginx started...'", ";", "Get-Content", "-Wait", "logs/access.log", ";"] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/Dockerfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/Dockerfile new file mode 100644 index 0000000..80fd6e4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/Dockerfile @@ -0,0 +1,9 @@ +ARG SERVERCORE + +FROM mcr.microsoft.com/windows/servercore:$SERVERCORE +SHELL ["powershell", "-NoLogo", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] +RUN Add-WindowsFeature Web-Server; \ + Invoke-WebRequest -UseBasicParsing -Uri "https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe" -OutFile "c:\svcm.exe" +COPY ["run.ps1", "c:/scripts/"] +EXPOSE 80 +CMD ["powershell", "c:/scripts/run.ps1"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/run.ps1 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/run.ps1 new file mode 100644 index 0000000..e68d50b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/Dockerfiles/windows/testcontainer/run.ps1 @@ -0,0 +1,13 @@ +#Requires -Version 5.0 +$ErrorActionPreference = "Stop" + +$STATIC_CONTENT_PATH = "c:\inetpub\wwwroot" +$CONTAINER_NAME = $env:CONTAINER_NAME +if (-not $CONTAINER_NAME) { + $CONTAINER_NAME = hostname +} +$CONTAINER_NAME | Out-File -Encoding ascii -Force -FilePath "$STATIC_CONTENT_PATH\name.html" +$CONTAINER_NAME | Out-File -Encoding ascii -Force -FilePath "$STATIC_CONTENT_PATH\service1.html" +$CONTAINER_NAME | Out-File -Encoding ascii -Force -FilePath "$STATIC_CONTENT_PATH\service2.html" + +c:\svcm.exe w3svc \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/common.py new file mode 100644 index 0000000..ed4c341 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/common.py @@ -0,0 +1,43 @@ +import os +import random +import time + +CATTLE_TEST_URL = os.environ.get('CATTLE_TEST_URL', "") +ADMIN_TOKEN = os.environ.get('ADMIN_TOKEN', "None") +USER_TOKEN = os.environ.get('USER_TOKEN', "None") +CLUSTER_NAME = os.environ.get("RANCHER_CLUSTER_NAME", "") +DEFAULT_TIMEOUT = 120 + + +def random_int(start, end): + return random.randint(start, end) + + +def random_test_name(name="test"): + return name + "-" + str(random_int(10000, 99999)) + + +def random_str(): + return 'random-{0}-{1}'.format(random_num(), int(time.time())) + + +def random_num(): + return random.randint(0, 1000000) + + +def random_name(): + return "test" + "-" + str(random_int(10000, 99999)) + + +def wait_for(callback, timeout=DEFAULT_TIMEOUT, timeout_message=None): + start = time.time() + ret = callback() + while ret is None or ret is False: + time.sleep(.5) + if time.time() - start > timeout: + if timeout_message: + raise Exception(timeout_message) + else: + raise Exception('Timeout waiting for condition') + ret = callback() + return ret diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/Jenkinsfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/Jenkinsfile new file mode 100644 index 0000000..d4fdbc4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/Jenkinsfile @@ -0,0 +1,34 @@ +node { + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + checkout scm + + stage('Configure and Build') { + sh "./tests/kubernetes_conformance/scripts/configure.sh" + sh "mkdir -p .ssh && echo \"${AWS_SSH_PEM_KEY}\" > .ssh/${AWS_SSH_KEY_NAME} && chmod 400 .ssh/*" + sh "echo \"${KUBE_CONFIG}\" > kube_config_cluster.yml" + sh "./tests/kubernetes_conformance/scripts/build.sh" + } + try { + stage('Run Validation Tests') { + try { + sh "docker run --name ${JOB_NAME}${env.BUILD_NUMBER} --env-file .env " + + "rancher-validation-tests /bin/bash -c \'pytest -v -s ${PYTEST_OPTIONS} tests/kubernetes_conformance/\'" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + + } + + stage('Test Report') { + sh "docker cp ${JOB_NAME}${env.BUILD_NUMBER}:/src/rancher-validation/conformance_results.tar.gz ." + sh 'tar xvzf conformance_results.tar.gz' + step([$class: 'JUnitResultArchiver', testResults: '**/plugins/e2e/results/junit_01.xml']) + sh "docker rm -v ${JOB_NAME}${env.BUILD_NUMBER}" + } + } catch(err) { + sh "docker stop ${JOB_NAME}${env.BUILD_NUMBER}" + sh "docker rm -v ${JOB_NAME}${env.BUILD_NUMBER}" + } + + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/conftest.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/conftest.py new file mode 100644 index 0000000..3e55244 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/conftest.py @@ -0,0 +1,38 @@ +import os +import pytest +import random + +from lib.aws import AmazonWebServices +from lib.rke_client import RKEClient +from lib.kubectl_client import KubectlClient + + +CLOUD_PROVIDER = os.environ.get("CLOUD_PROVIDER", 'AWS') +TEMPLATE_PATH = os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'resources/rke_templates') + + +@pytest.fixture(scope='session') +def cloud_provider(): + if CLOUD_PROVIDER == 'AWS': + return AmazonWebServices() + + +@pytest.fixture(scope='function') +def rke_client(cloud_provider): + return RKEClient( + master_ssh_key_path=cloud_provider.master_ssh_key_path, + template_path=TEMPLATE_PATH) + + +@pytest.fixture(scope='function') +def kubectl(): + return KubectlClient() + + +@pytest.fixture(scope='function') +def test_name(request): + name = request.function.__name__.replace('test_', '').replace('_', '-') + # limit name length + name = name[0:20] if len(name) > 20 else name + return '{0}-{1}'.format(name, random.randint(100000, 1000000)) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/k8s_ymls/sonobuoy-conformance.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/k8s_ymls/sonobuoy-conformance.yaml new file mode 100644 index 0000000..659fb14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/k8s_ymls/sonobuoy-conformance.yaml @@ -0,0 +1,194 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: sonobuoy +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + component: sonobuoy + name: sonobuoy-serviceaccount + namespace: sonobuoy +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + component: sonobuoy + name: sonobuoy-serviceaccount +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: sonobuoy-serviceaccount +subjects: +- kind: ServiceAccount + name: sonobuoy-serviceaccount + namespace: sonobuoy +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + component: sonobuoy + name: sonobuoy-serviceaccount + namespace: sonobuoy +rules: +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + component: sonobuoy + name: sonobuoy-config-cm + namespace: sonobuoy +data: + config.json: | + { + "Description": "CNCF v1.8 or v1.9 Conformance Results", + "Filters": { + "LabelSelector": "", + "Namespaces": ".*" + }, + "PluginNamespace": "sonobuoy", + "Plugins": [ + { + "name": "e2e" + } + ], + "Resources": [ + ], + "ResultsDir": "/tmp/sonobuoy", + "Server": { + "advertiseaddress": "sonobuoy-master:8080", + "bindaddress": "0.0.0.0", + "bindport": 8080, + "timeoutseconds": 5400 + }, + "Version": "v0.9.0" + } +--- +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + component: sonobuoy + name: sonobuoy-plugins-cm + namespace: sonobuoy +data: + e2e.yaml: | + driver: Job + name: e2e + resultType: e2e + spec: + containers: + - env: + - name: E2E_FOCUS + value: '\[Conformance\]' + image: gcr.io/heptio-images/kube-conformance:v1.9 + imagePullPolicy: Always + name: e2e + volumeMounts: + - mountPath: /tmp/results + name: results + - command: + - sh + - -c + - /sonobuoy worker global -v 5 --logtostderr + env: + - name: NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: RESULTS_DIR + value: /tmp/results + image: gcr.io/heptio-images/sonobuoy:v0.9.0 + imagePullPolicy: Always + name: sonobuoy-worker + volumeMounts: + - mountPath: /etc/sonobuoy + name: config + - mountPath: /tmp/results + name: results + restartPolicy: Never + serviceAccountName: sonobuoy-serviceaccount + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/controlplane + operator: Exists + - key: CriticalAddonsOnly + operator: Exists + volumes: + - emptyDir: {} + name: results + - configMap: + name: __SONOBUOY_CONFIGMAP__ + name: config +--- +apiVersion: v1 +kind: Pod +metadata: + labels: + component: sonobuoy + run: sonobuoy-master + tier: analysis + name: sonobuoy + namespace: sonobuoy +spec: + containers: + - command: + - /bin/bash + - -c + - /sonobuoy master --no-exit=true -v 3 --logtostderr + env: + - name: SONOBUOY_ADVERTISE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: gcr.io/heptio-images/sonobuoy:v0.9.0 + imagePullPolicy: Always + name: kube-sonobuoy + volumeMounts: + - mountPath: /etc/sonobuoy + name: sonobuoy-config-volume + - mountPath: /plugins.d + name: sonobuoy-plugins-volume + - mountPath: /tmp/sonobuoy + name: output-volume + restartPolicy: Never + serviceAccountName: sonobuoy-serviceaccount + volumes: + - configMap: + name: sonobuoy-config-cm + name: sonobuoy-config-volume + - configMap: + name: sonobuoy-plugins-cm + name: sonobuoy-plugins-volume + - emptyDir: {} + name: output-volume +--- +apiVersion: v1 +kind: Service +metadata: + labels: + component: sonobuoy + run: sonobuoy-master + name: sonobuoy-master + namespace: sonobuoy +spec: + ports: + - port: 8080 + protocol: TCP + targetPort: 8080 + selector: + run: sonobuoy-master + type: ClusterIP + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/rke_templates/cluster_install_config_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/rke_templates/cluster_install_config_1.yml.j2 new file mode 100644 index 0000000..597448e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/resources/rke_templates/cluster_install_config_1.yml.j2 @@ -0,0 +1,28 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + kube-controller: + image: {{ k8_rancher_image }} + scheduler: + image: {{ k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + kubeproxy: + image: {{ k8_rancher_image }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/build.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/build.sh new file mode 100755 index 0000000..3b61ae3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" +RKE_VERSION="${RKE_VERSION:-v0.0.8-dev}" +KUBECTL_VERSION="${KUBECTL_VERSION:-v1.27.10}" + +if [ "false" != "${DEBUG}" ]; then + echo "Environment:" + env | sort +fi + +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../../" && pwd )" + +count=0 +while [[ 3 -gt $count ]]; do + docker build --rm --build-arg RKE_VERSION=$RKE_VERSION -f Dockerfile.rke -t rancher-validation-tests . + if [[ $? -eq 0 ]]; then break; fi + count=$(($count + 1)) + echo "Repeating failed Docker build ${count} of 3..." +done \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/configure.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/configure.sh new file mode 100755 index 0000000..81e6e17 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/scripts/configure.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -eu + +DEBUG="${DEBUG:-false}" + +env | egrep '^(RANCHER_|AWS_|DEBUG|DEFAULT_|OS_|DOCKER_|CLOUD_|KUBE|BUILD_NUMBER).*\=.+' | sort > .env + +if [ "false" != "${DEBUG}" ]; then + cat .env +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/test_rke_k8s_conformance.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/test_rke_k8s_conformance.py new file mode 100644 index 0000000..aa1688e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/kubernetes_conformance/test_rke_k8s_conformance.py @@ -0,0 +1,70 @@ +import os +import time + +from .conftest import * # NOQA +from tests.rke.common import create_rke_cluster, delete_nodes + + +KUBE_CONFIG_PATH = os.environ.get( + 'KUBE_CONFIG_PATH', 'kube_config_cluster.yml') +CONFORMANCE_DONE = "no-exit was specified, sonobuoy is now blocking" + + +def extract_file_results_path(logs): + log_lines = logs.splitlines() + for line in log_lines: + if "Results available at" in line: + path_line = line.split(' ') + abs_file_path = path_line[-1].replace('"', '') + return abs_file_path + else: + raise Exception( + "Unable to find test result file in logs: {0}".format(logs)) + + +def delete_all_jobs(kubectl): + namespaces = kubectl.list_namespaces() + for namespace in namespaces: + result = kubectl.delete_resourse("jobs", namespace=namespace, all=True) + assert result.ok, "{}".format(result) + + +def run_conformance(kubectl, kube_config): + kubectl.kube_config_path = kube_config + delete_all_jobs(kubectl) + kubectl.apply_conformance_tests() + kubectl.wait_for_pod('sonobuoy', namespace='sonobuoy') + conformance_tests_complete = False + while not conformance_tests_complete: + result = kubectl.logs( + 'sonobuoy', namespace='sonobuoy', tail=10) + assert result.ok, ( + "Failed to read logs for conformance tests pod:\n{0}".format( + result.stdout + result.stderr)) + if CONFORMANCE_DONE in result.stdout: + break + time.sleep(60) + + test_results_path = extract_file_results_path(result.stdout) + result = kubectl.cp_from_pod('sonobuoy', 'sonobuoy', test_results_path, + './conformance_results.tar.gz') + assert result.ok, "{}".format(result) + + +def test_run_conformance_from_config(kubectl): + """ + Runs conformance tests against an existing cluster + """ + run_conformance(kubectl, KUBE_CONFIG_PATH) + + +def test_create_cluster_run_conformance( + test_name, cloud_provider, rke_client, kubectl): + """ + Creates an RKE cluster, runs conformance tests against that cluster + """ + rke_template = 'cluster_install_config_1.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_rke_cluster(rke_client, kubectl, nodes, rke_template) + run_conformance(kubectl, rke_client.kube_config_path()) + delete_nodes(cloud_provider, nodes) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/Jenkinsfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/Jenkinsfile new file mode 100644 index 0000000..718490d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/Jenkinsfile @@ -0,0 +1,49 @@ +node { + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY') + ]){ + checkout scm + dir ("tests/validation") { + stage('Configure and Build') { + sh "./tests/rke/scripts/configure.sh" + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/rke/scripts/build.sh" + } + + try { + stage('Run Validation Tests') { + try { + sh "docker run --name ${job_name}${env.BUILD_NUMBER} --env-file .env " + + "rancher-validation-tests /bin/bash -c \'pytest -v -s --junit-xml=results.xml ${PYTEST_OPTIONS} tests/rke/\'" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + + stage('Test Report') { + sh "docker cp ${job_name}${env.BUILD_NUMBER}:/src/rancher-validation/results.xml ." + step([$class: 'JUnitResultArchiver', testResults: '**/results.xml']) + sh "docker rm -v ${job_name}${env.BUILD_NUMBER}" + } + } catch(err){ + sh "docker stop ${job_name}${env.BUILD_NUMBER}" + sh "docker rm -v ${job_name}${env.BUILD_NUMBER}" + } + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/README.md new file mode 100644 index 0000000..ddab12e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/README.md @@ -0,0 +1,67 @@ +## To use locally: + +### General Setup: +- To run locally (not as container), setup a python virtualenv and pip install -r requirements.txt +- create .ssh/ in main validations/ directory to store a ssh key or cert + +#### For AWS: +- For AWS create a Key Pair cert and download it to validations/.ssh/ +- export key filename with environment variable AWS_SSH_KEY_NAME + + +### Setup: +- create .ssh/ in main validations/ directory +- create a aws.pem cert for tests +- rke and kubectl need to be in your path +- pip install requirements.txt (recommend using virtualenv before this step) +- export following variables: + +``` +DEBUG=[true|false] to see the output while running +OS_VERSION=[ubuntu-16.04|rhel-7.4] +DOCKER_VERSION=[latest|17.03|1.13.1|1.12.6] +CLOUD_PROVIDER=AWS +AWS_SSH_KEY_NAME=aws_cert.pem +AWS_ACCESS_KEY_ID=your AWS access key id +AWS_SECRET_ACCESS_KEY=your AWS secret jet +``` + +### Run: + pytest -s rke_tests/ + + +## To run locally in container: +- save ssh pem file from AWS in validations/.ssh +- export following variables: + +``` +OS_VERSION=[ubuntu-16.04|rhel-7.4] +DOCKER_VERSION=[latest|17.03|1.13.1|1.12.6] +KUBECTL_VERSION= +RKE_VERSION= +CLOUD_PROVIDER=AWS +AWS_SSH_KEY_NAME=aws_cert.pem +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +``` +- run scripts/rke/configure.sh +- run scripts/rke/build.sh +- run docker run --rm -v ~/path/to/rancher-validation:/src/rancher-validation rancher-validation-tests -c pytest -s rke_tests/ + + +## RKE Template Referenece + +All other fields will be replaced if passed in to build_rke_template as key value pairs +For Nodes, the 'N' should be replace with index starting at 0 + +| TEMPLATE_FIELD_NAME | Description | +| ------------------------ |:---------------------------------------------:| +| ip_address_N | Replaced with node N's IP Address | +| dns_hostname_N | Replaced with node N's FQDN | +| ssh_user_N | Replaced with node N's ssh user | +| ssh_key_N | Replaced with node N's actual private key | +| ssh_key_path_N | Replaced with node N's path to ssh key | +| internal_address_N | Replaced with node N's private IP Address | +| k8_rancher_image | Used to determine k8s images used in services | +| network_plugin | Used to determine rke network plugin | +| master_ssh_key_path | Replaced by path of the master ssh for tests | diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/common.py new file mode 100644 index 0000000..568f31b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/common.py @@ -0,0 +1,651 @@ +import time +import os +import json +from packaging import version + +k8s_resource_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "resources/k8s_ymls/") +k8s_rancher_version = str(os.environ.get("RANCHER_K8S_VERSION").split("-")[0][1:]) +k8s_rancher_version = version.parse(k8s_rancher_version) +k8s_rancher_version = version.parse(f"{str(k8s_rancher_version.major)}.{str(k8s_rancher_version.minor)}") +k8s_fixed_version = version.parse("1.21") + +# Global expectedimagesdict declared to store the images for a specific +# k8s Version +expectedimagesdict = {} + + +def create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + base_namespace="ns", network_validation=None, dns_validation=None, + teardown=False, remove_nodes=False, etcd_private_ip=False): + + create_rke_cluster(rke_client, kubectl, nodes, rke_template) + network_validation, dns_validation = validate_rke_cluster( + rke_client, kubectl, nodes, base_ns=base_namespace, + network_validation=network_validation, dns_validation=dns_validation, + teardown=teardown, etcd_private_ip=etcd_private_ip) + + if remove_nodes: + delete_nodes(cloud_provider, nodes) + + return network_validation, dns_validation + + +def delete_nodes(cloud_provider, nodes): + for node in nodes: + cloud_provider.delete_node(node) + + +def create_rke_cluster( + rke_client, kubectl, nodes, rke_template, **rke_template_kwargs): + """ + Creates a cluster and returns the rke config as a python dictionary + """ + + # create rke cluster yml + config_yml, nodes = rke_client.build_rke_template( + rke_template, nodes, **rke_template_kwargs) + + # run rke up + result = rke_client.up(config_yml) + + # validate k8s reachable + kubectl.kube_config_path = rke_client.kube_config_path() + + return rke_client.convert_to_dict(config_yml) + + +def validate_rke_cluster(rke_client, kubectl, nodes, base_ns='one', + network_validation=None, dns_validation=None, + teardown=False, etcd_private_ip=False): + """ + General rke up test validation, runs validations methods for: + - node roles validation + - intercommuincation per pod + - dns service discovery validation + If teardown is true, removes any resources created for validation + """ + + validation_node_roles(nodes, kubectl.get_nodes(), etcd_private_ip) + if network_validation is None: + network_validation = PodIntercommunicationValidation(kubectl, base_ns) + network_validation.setup() + if dns_validation is None: + dns_validation = DNSServiceDiscoveryValidation(kubectl, base_ns) + dns_validation.setup() + + network_validation.validate() + dns_validation.validate() + + if teardown: + network_validation.teardown() + dns_validation.teardown() + + return network_validation, dns_validation + + +def match_nodes(nodes, k8s_nodes): + """ + Builds a list of tuples, where: + nodes_to_k8s_nodes[0][0] is the node object matched to + nodes_to_k8s_nodes[0][1] is the k8s info for the same node + """ + k8s_node_names = [] + for k8s_node in k8s_nodes['items']: + k8s_node_names.append( + k8s_node['metadata']['labels']['kubernetes.io/hostname']) + + nodes_to_k8s_nodes = [] + for node in nodes: + for k8s_node in k8s_nodes['items']: + hostname = k8s_node['metadata']['labels']['kubernetes.io/hostname'] + if hostname in node.node_name: + nodes_to_k8s_nodes.append((node, k8s_node)) + break + else: + raise Exception( + "Did not find provisioned node's '{0}' corresponding nodes " + "resourse in cluster: {1}".format( + node.node_name, k8s_node_names)) + return nodes_to_k8s_nodes + + +def assert_containers_exist_for_roles(roles, containers): + # All nodes will have these containers: + expect_containers = ['kubelet', 'kube-proxy'] + + # Add extra containers depending on roles present + if 'controlplane' in roles: + expect_containers.extend( + ['kube-scheduler', 'kube-controller-manager', 'kube-apiserver']) + else: + expect_containers.extend(['nginx-proxy']) + if 'etcd' in roles: + expect_containers.extend(['etcd']) + + missing_containers = expect_containers[:] + for container in containers: + if container in expect_containers: + missing_containers.remove(container) + assert len(missing_containers) == 0, \ + "Missing expected containers for role '{0}': {1}".format( + roles, missing_containers) + + +def wait_for_etcd_cluster_health(node, etcd_private_ip=False): + result = '' + endpoints = "127.0.0.1" + if etcd_private_ip: + endpoints = node.private_ip_address + if k8s_rancher_version <= k8s_fixed_version: + etcd_tls_cmd = ( + 'etcdctl --endpoints "https://' + endpoints + ':2379" ' + ' --ca-file /etc/kubernetes/ssl/kube-ca.pem --cert-file ' + ' $ETCDCTL_CERT --key-file ' + ' $ETCDCTL_KEY cluster-health ETCDCTL_API=2' + ) + else: + etcd_tls_cmd = ( + 'etcdctl endpoint health --cluster ETCDCTL_API=3' + ) + + print(etcd_tls_cmd) + start_time = time.time() + while start_time - time.time() < 120: + result = node.docker_exec('etcd', etcd_tls_cmd) + print("**RESULT**") + print(result) + if k8s_rancher_version <= k8s_fixed_version: + if 'cluster is healthy' in result: + break + else: + if 'is healthy' in result: + break + time.sleep(5) + return result + + +def verify_metrics_server_addon_images(k8sversion, kubectl, + namespace, selector): + + metricserver = get_component_version(k8sversion, + "rancher/metrics-server") + # Sleep to allow the metrics server component to get to running state + time.sleep(10) + verify_component_status_with_kubectl(kubectl, namespace, selector, + metricserver) + + +def verify_ingress_addon_images(k8sversion, kubectl, namespace, + selector1, selector2): + + ingressdefaultbackend = \ + get_component_version(k8sversion, + "rancher/nginx-ingress-controller-defaultbackend" + ) + nginxingresscontoller =\ + get_component_version(k8sversion, + "rancher/nginx-ingress-controller") + # Sleep to allow the ingress addon components to get to running state + time.sleep(5) + verify_component_status_with_kubectl(kubectl, namespace, selector1, + nginxingresscontoller) + verify_component_status_with_kubectl(kubectl, namespace, selector2, + ingressdefaultbackend) + + +def verify_dns_addon_images(k8sversion, kubectl, namespace, + selector): + + coredns = get_component_version(k8sversion, + "rancher/coredns-coredns") + # Sleep to allow the dns addon component to get to running state + time.sleep(5) + + verify_component_status_with_kubectl(kubectl, namespace, selector, coredns) + + +def verify_networking_addon_images(k8sversion, kubectl, + namespace, selector): + + flannel = get_component_version(k8sversion, + "rancher/coreos-flannel") + + calico = get_component_version(k8sversion, + "rancher/calico-node") + # Sleep to allow the network addon component to get to running state + time.sleep(5) + verify_component_status_with_kubectl(kubectl, namespace, selector, calico, + flannel) + + +def verify_component_status_with_kubectl(kubectl, namespace, selector, *args): + # Method to verify addon status and images + + command = "get pod --namespace " + namespace + " -l " + selector + + res = kubectl.execute_kubectl_cmd(command, json_out=True) + result = json.loads(res) + timeout = 180 + start = time.time() + # Check if the pod is running + for pod in result["items"]: + podstatus = pod["status"]["phase"] + podname = pod["metadata"]["name"] + print("Pod name is " + podname) + podreloadcommand = "get pod " + podname + " --namespace " + namespace + while (podstatus != "Running"): + if time.time() - start > timeout: + raise AssertionError("Timed out waiting to reach running state") + time.sleep(.5) + podresult = kubectl.execute_kubectl_cmd(podreloadcommand, + json_out=True) + podresult = json.loads(podresult) + podname = podresult["metadata"]["name"] + print("Pod name is " + podname) + podstatus = podresult["status"]["phase"] + print("Pod status is " + podstatus) + assert True + + # Verify the component images in the pods + testresult = kubectl.execute_kubectl_cmd(command, json_out=True) + updatedresult = json.loads(testresult) + for pod in updatedresult["items"]: + print("Required Resource Image: ") + print(args[0]) + podstatus = pod["status"]["phase"] + if(podstatus == "Running"): + for i in range(0, len(args)): + print(pod["status"]["containerStatuses"][i]["image"]) + assert pod["status"]["containerStatuses"][i]["image"] == args[i] + + +def get_system_images(rke_client, k8s_version): + + # Method to obtain the system images for a k8s version from rke cli + + command = ("rke config --system-images --version " + k8s_version) + print(command) + rke_system_images_dict = rke_client.run_command(command) + result = rke_system_images_dict.split("\n") + # Removing the first item which is not required + result.pop(0) + print(result) + return result + + +def get_component_version(k8s_version, componentname): + # Method to obtain the image version for a specific component + + systemimageslist = expectedimagesdict[k8s_version]["rkesystemimages"] + print(systemimageslist) + for item in systemimageslist: + itemlist = item.split(":") + if componentname == itemlist[0]: + print(componentname) + componentversion = item + print("VERSION IS " + componentversion) + return componentversion + + +def build_expectedimages_dict(k8s_version, rke_client): + # Build the expected image list from rke system images list + + if k8s_version in expectedimagesdict.keys(): + return expectedimagesdict[k8s_version] + else: + expectedimagesdict[k8s_version] = {} + result = get_system_images(rke_client, k8s_version) + for item in result: + itemlist = item.split(":") + if "rancher/hyperkube" == itemlist[0]: + expectedimagesdict[k8s_version]["kube-proxy"] = item + expectedimagesdict[k8s_version]["kube-scheduler"] = item + expectedimagesdict[k8s_version]["kube-controller-manager"] \ + = item + expectedimagesdict[k8s_version]["kube-apiserver"] = item + expectedimagesdict[k8s_version]["kubelet"] = item + if "rancher/coreos-etc[k8s_version]" == itemlist[0]: + expectedimagesdict[k8s_version]["etcd"] = item + if "rancher/rke-tools" == itemlist[0]: + expectedimagesdict[k8s_version]["service-sidekick"] = item + + expectedimagesdict[k8s_version]["rkesystemimages"] = result + return expectedimagesdict[k8s_version] + + +def validation_node_roles(nodes, k8s_nodes, etcd_private_ip=False): + """ + Validates each node's labels for match its roles + Validates each node's running containers match its role + Validates etcd etcdctl cluster-health command + Validates worker nodes nginx-proxy conf file for controlplane ips + """ + + role_matcher = { + 'worker': 'node-role.kubernetes.io/worker', + 'etcd': 'node-role.kubernetes.io/etcd', + 'controlplane': 'node-role.kubernetes.io/controlplane'} + + controlplane_ips = [] + etcd_members = [] + for node in nodes: + if 'controlplane' in node.roles: + controlplane_ips.append(node.node_address) + if 'etcd' in node.roles: + etcd_members.append(node.node_address) + + nodes_to_k8s_nodes = match_nodes(nodes, k8s_nodes) + for node, k8s_node in nodes_to_k8s_nodes: + containers = list(node.docker_ps().keys()) + assert_containers_exist_for_roles(node.roles, containers) + k8s_node_labels = list(k8s_node['metadata']['labels'].keys()) + for role in node.roles: + assert role_matcher[role] in k8s_node_labels, \ + "Expected label '{0}' not in labels: {1}".format( + role_matcher[role], k8s_node_labels) + + # nodes with controlplane roles do not have nginx-proxy + if (role == 'worker' or role == 'etcd') and \ + ('controlplane' not in node.roles): + result = node.docker_exec( + 'nginx-proxy', 'cat /etc/nginx/nginx.conf') + for ip in controlplane_ips: + assert 'server {0}:6443'.format(ip) in result, ( + "Expected to find all controlplane node addresses {0}" + "in nginx.conf: {1}".format(controlplane_ips, result)) + if role == 'etcd': + if len(node.roles) == 1: + for taint in k8s_node['spec']['taints']: + if taint['key'] == 'node-role.kubernetes.io/etcd': + assert taint['effect'] == 'NoExecute', ( + "{0} etcd-only node's taint is not 'NoExecute'" + ": {1}".format(node.node_name, taint['effect']) + ) + # found, do not complete for loop + # or else an assertion will be raised + break + else: + assert False, \ + "Expected to find taint for etcd-only node" + # check etcd membership and cluster health + result = wait_for_etcd_cluster_health(node, etcd_private_ip) + if k8s_rancher_version <= k8s_fixed_version: + for member in etcd_members: + expect = "got healthy result from https://{}".format(member) + assert expect in result, result + assert 'cluster is healthy' in result, result + else: + for member in etcd_members: + expect = "https://{}:2379 is healthy: successfully committed proposal".format(member) + assert expect in result, result + assert 'is healthy' in result, result + + +class PodIntercommunicationValidation(object): + def __init__(self, kubectl, base_namespace): + self.kubectl = kubectl + self.yml_file = ( + k8s_resource_dir + 'daemonset_pods_per_node.yml') + self.ns_out = 'daemonset-out-{}'.format(base_namespace) + self.ns_in = 'daemonset-in-{}'.format(base_namespace) + self.selector = 'name=daemonset-test1' + + def setup(self): + self.kubectl.create_ns(self.ns_out) + result = self.kubectl.create_resourse_from_yml( + self.yml_file, namespace=self.ns_out) + + self.kubectl.create_ns(self.ns_in) + result = self.kubectl.create_resourse_from_yml( + self.yml_file, namespace=self.ns_in) + + def validate(self): + """ + Gets pod name, pod ip, host ip, and containers + For each pod, use kubectl exec to ping all other pod ips + Asserts that each ping is successful + Tears down daemonset + """ + # get number of expected pods + worker_nodes = self.kubectl.get_resource( + 'nodes', selector='node-role.kubernetes.io/worker=true') + master_nodes = self.kubectl.get_resource( + 'nodes', selector='node-role.kubernetes.io/controlplane=true') + node_names = [n['metadata']['name'] for n in worker_nodes['items']] + expected_number_pods = len(worker_nodes['items']) + """ + for master_node in master_nodes['items']: + if master_node['metadata']['name'] not in node_names: + expected_number_pods += 1 + """ + # get pods on each node/namespaces to test intercommunication + # with pods on different nodes + pods_to_ping = self.kubectl.wait_for_pods( + selector=self.selector, namespace=self.ns_in, + number_of_pods=expected_number_pods) + pods_from_which_ping = self.kubectl.wait_for_pods( + selector=self.selector, namespace=self.ns_out, + number_of_pods=expected_number_pods) + + # verify daemonset pods are on all worker nodes + assert len(pods_to_ping['items']) == expected_number_pods, ( + "DaemonSet number of pods '{0}', does not match number of worker " + "nodes '{1}'".format( + len(pods_to_ping['items']), expected_number_pods)) + assert len(pods_from_which_ping['items']) == expected_number_pods, ( + "DaemonSet number of pods '{0}', does not match number of worker " + "nodes '{1}'".format( + len(pods_from_which_ping['items']), expected_number_pods)) + + pod_ips_to_ping = [] + for pod in pods_to_ping['items']: + pod_ips_to_ping.append(pod['status']['podIP']) + + pod_names_to_ping_from = [] + for pod in pods_from_which_ping['items']: + pod_names_to_ping_from.append(pod['metadata']['name']) + + # From each pod of daemonset in namespace ns_out, ping all pods + # in from second daemonset in ns_in + expect_result = \ + '1 packets transmitted, 1 received, 0% packet loss' + for pod_name in pod_names_to_ping_from: + for pod_ip in pod_ips_to_ping: + cmd = 'ping -c 1 {0}'.format(pod_ip) + for _ in range(10): + result = self.kubectl.exec_cmd(pod_name, cmd, self.ns_out) + assert expect_result in result, ( + "Could not ping pod with ip {0} from pod {1}:\n" + "stdout: {2}\n".format( + pod_ip, pod_name, result)) + + def teardown(self): + """ + Deletes a daemonset of pods and namespace + """ + result = self.kubectl.delete_resourse_from_yml( + self.yml_file, namespace=self.ns_out) + result = self.kubectl.delete_resourse_from_yml( + self.yml_file, namespace=self.ns_in) + self.kubectl.delete_resourse('namespace', self.ns_out) + self.kubectl.delete_resourse('namespace', self.ns_in) + + +class DNSServiceDiscoveryValidation(object): + def __init__(self, kubectl, base_namespace): + namespace_one = 'nsone-{}'.format(base_namespace) + namespace_two = 'nstwo-{}'.format(base_namespace) + self.namespace = namespace_one + self.services = { + 'k8test1': { + 'namespace': namespace_one, + 'selector': 'k8s-app=k8test1-service', + 'yml_file': k8s_resource_dir + 'service_k8test1.yml', + }, + 'k8test2': { + 'namespace': namespace_two, + 'selector': 'k8s-app=k8test2-service', + 'yml_file': k8s_resource_dir + 'service_k8test2.yml', + } + } + self.pod_selector = 'k8s-app=pod-test-util' + self.kubectl = kubectl + + def setup(self): + + for service_name, service_info in self.services.items(): + # create service + result = self.kubectl.create_ns(service_info['namespace']) + + result = self.kubectl.create_resourse_from_yml( + service_info['yml_file'], namespace=service_info['namespace']) + + result = self.kubectl.create_resourse_from_yml( + k8s_resource_dir + 'single_pod.yml', + namespace=self.namespace) + + def validate(self): + # wait for exec pod to be ready before validating + pods = self.kubectl.wait_for_pods( + selector=self.pod_selector, namespace=self.namespace) + exec_pod_name = pods['items'][0]['metadata']['name'] + + # Get Cluster IP and pod names per service + dns_records = {} + for service_name, service_info in self.services.items(): + # map expected IP to dns service name + dns = "{0}.{1}.svc.cluster.local".format( + service_name, service_info['namespace']) + svc = self.kubectl.get_resource( + 'svc', name=service_name, namespace=service_info['namespace']) + service_pods = self.kubectl.wait_for_pods( + selector=service_info['selector'], + namespace=service_info['namespace'], number_of_pods=2) + svc_cluster_ip = svc["spec"]["clusterIP"] + dns_records[dns] = { + 'ip': svc_cluster_ip, + 'pods': [p['metadata']['name'] for p in service_pods['items']] + } + + for dns_record, dns_info in dns_records.items(): + # Check dns resolution + expected_ip = dns_info['ip'] + cmd = 'dig {0} +short'.format(dns_record) + result = self.kubectl.exec_cmd(exec_pod_name, cmd, self.namespace) + assert expected_ip in result, ( + "Unable to test DNS resolution for service {0}: {1}".format( + dns_record, result.stderr)) + + # Check Cluster IP reaches pods in service + pods_names = dns_info['pods'] + cmd = 'curl "http://{0}/name.html"'.format(dns_record) + result = self.kubectl.exec_cmd(exec_pod_name, cmd, self.namespace) + print(result) + print(pods_names) + assert result.rstrip() in pods_names, ( + "Service ClusterIP does not reach pods {0}".format( + dns_record)) + + def teardown(self): + self.kubectl.delete_resourse( + 'pod', 'pod-test-util', namespace=self.namespace) + + for service_name, service_info in self.services.items(): + self.kubectl.delete_resourse_from_yml( + service_info['yml_file'], namespace=service_info['namespace']) + self.kubectl.delete_resourse( + 'namespace', service_info['namespace']) + + +def validate_k8s_service_images(nodes, k8s_version, rke_client, kubectl): + """ + expectedimages dictionary will be built in this method + This verifies that the nodes have the correct image version + This does not validate containers per role, + assert_containers_exist_for_roles method does that + """ + expectedimagesdict = build_expectedimages_dict(k8s_version, rke_client) + print(expectedimagesdict) + + for node in nodes: + containers = node.docker_ps() + allcontainers = node.docker_ps(includeall=True) + print("Container Dictionary ") + print(containers) + print("All containers dictionary") + print(allcontainers) + sidekickservice = "service-sidekick" + for key in expectedimagesdict.keys(): + servicename = key + if servicename in containers: + print("Service name") + print(servicename) + print(expectedimagesdict[servicename]) + print(containers[servicename]) + assert expectedimagesdict[servicename] == \ + containers[servicename], ( + "K8s service '{0}' does not match config version " + "{1}, found {2} on node {3}".format( + servicename, expectedimagesdict[servicename], + containers[servicename], node.node_name)) + if sidekickservice in expectedimagesdict.keys(): + if sidekickservice in allcontainers: + print("sidekick-service in allcontainers") + print(sidekickservice) + print(expectedimagesdict[sidekickservice]) + print(allcontainers[sidekickservice]) + assert expectedimagesdict[sidekickservice] == \ + allcontainers[sidekickservice], ( + "K8s service '{0}' does not match config version " + "{1}, found {2} on node {3}".format( + sidekickservice, expectedimagesdict[sidekickservice], + allcontainers[sidekickservice], node.node_name)) + + verify_ingress_addon_images(k8s_version, kubectl, + "ingress-nginx", "app=ingress-nginx", + "app=default-http-backend") + verify_networking_addon_images(k8s_version, kubectl, + "kube-system", "k8s-app=canal") + verify_metrics_server_addon_images(k8s_version, kubectl, + "kube-system", "k8s-app=metrics-server") + verify_dns_addon_images(k8s_version, kubectl, + "kube-system", "k8s-app=kube-dns") + + +def validate_remove_cluster(nodes): + """ + Removes all k8s services containers on each node: + ['kubelet', 'kube-proxy', 'kube-scheduler', 'kube-controller-manager', + 'kube-apiserver', 'nginx-proxy'] + Removes files from these directories: + ['/etc/kubernetes/ssl', '/var/lib/etcd' + '/etc/cni', '/opt/cni', '/var/run/calico'] + """ + k8s_services = [ + 'kubelet', 'kube-proxy', 'kube-scheduler', 'kube-controller-manager', + 'kube-apiserver', 'nginx-proxy' + ] + rke_cleaned_directories = [ + '/etc/kubernetes/ssl', '/var/lib/etcd' '/etc/cni', '/opt/cni', + '/var/run/calico' + ] + for node in nodes: + containers = node.docker_ps() + for service in k8s_services: + assert service not in list(containers.keys()), ( + "Found kubernetes service '{0}' still running on node '{1}'" + .format(service, node.node_name)) + + for directory in rke_cleaned_directories: + result = node.execute_command('ls ' + directory) + assert result[0] == '', ( + "Found a non-empty directory '{0}' after remove on node '{1}'" + .format(directory, node.node_name)) + + +def validate_dashboard(kubectl): + # Start dashboard + # Validated it is reachable + pass diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/conftest.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/conftest.py new file mode 100644 index 0000000..3e55244 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/conftest.py @@ -0,0 +1,38 @@ +import os +import pytest +import random + +from lib.aws import AmazonWebServices +from lib.rke_client import RKEClient +from lib.kubectl_client import KubectlClient + + +CLOUD_PROVIDER = os.environ.get("CLOUD_PROVIDER", 'AWS') +TEMPLATE_PATH = os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'resources/rke_templates') + + +@pytest.fixture(scope='session') +def cloud_provider(): + if CLOUD_PROVIDER == 'AWS': + return AmazonWebServices() + + +@pytest.fixture(scope='function') +def rke_client(cloud_provider): + return RKEClient( + master_ssh_key_path=cloud_provider.master_ssh_key_path, + template_path=TEMPLATE_PATH) + + +@pytest.fixture(scope='function') +def kubectl(): + return KubectlClient() + + +@pytest.fixture(scope='function') +def test_name(request): + name = request.function.__name__.replace('test_', '').replace('_', '-') + # limit name length + name = name[0:20] if len(name) > 20 else name + return '{0}-{1}'.format(name, random.randint(100000, 1000000)) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_templates/validation.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_templates/validation.yml.j2 new file mode 100644 index 0000000..523ec8e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_templates/validation.yml.j2 @@ -0,0 +1,203 @@ +# Pod +--- +apiVersion: v1 +kind: Pod +metadata: + name: nginx-pod + labels: + app: nginx-pod +spec: + containers: + - name: nginx + image: husseingalal/nginx-curl + ports: + - containerPort: 80 + +# RC +--- + +apiVersion: v1 +kind: ReplicationController +metadata: + name: nginx +spec: + replicas: 2 + selector: + name: nginx + type: rc + template: + metadata: + labels: + type: rc + name: nginx + spec: + containers: + - name: nginx + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 + +# service LoadBalancer +--- + +apiVersion: v1 +kind: Service +metadata: + name: nginx-lb + labels: + name: nginx-lb +spec: + type: LoadBalancer + ports: + - port: {{ k8s_base_lb_port }}{{ port_ext }} + nodePort: {{ k8s_base_lb_node_port }}{{ port_ext }} + targetPort: 80 + selector: + name: nginx + +# service external +--- + +apiVersion: v1 +kind: Service +metadata: + name: nginx-external + labels: + name: nginx-external +spec: + type: NodePort + externalIPs: ['{{ external_node }}'] + ports: + - port: 80 + targetPort: 80 + nodePort: {{ k8s_base_external_port }}{{ port_ext }} + selector: + name: nginx + +# service cluster ip +--- + +apiVersion: v1 +kind: Service +metadata: + name: nginx-clusterip + labels: + name: nginx-clusterip +spec: + sessionAffinity: ClientIP + type: ClusterIP + clusterIP: 10.233.0.1{{ port_ext }} + ports: + - port: 8000 + targetPort: 80 + selector: + name: nginx + +# service nodeport +--- +apiVersion: v1 +kind: Service +metadata: + name: nodeport-nginx + labels: + name: nodeport-nginx +spec: + type: NodePort + ports: + - port: 80 + targetPort: 80 + nodePort: {{ k8s_base_node_port }}{{ port_ext }} + selector: + name: nginx + +# Ingress testing +--- + +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: ingress1 + annotations: + http.port: "{{ k8s_base_ingress_port }}{{ port_ext }}" +spec: + rules: + - host: foo.bar.com + http: + paths: + - path: /service3.html + backend: + serviceName: k8test1 + servicePort: 81 + - path: /name.html + backend: + serviceName: k8test2 + servicePort: 80 + +--- + +apiVersion: v1 +kind: Service +metadata: + name: k8test1 + labels: + k8s-app: k8test1-service +spec: + ports: + - port: 81 + targetPort: 81 + protocol: TCP + name: http + selector: + k8s-app: k8test1-service + +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: k8testrc1 +spec: + replicas: 1 + selector: + k8s-app: k8test1-service + template: + metadata: + labels: + k8s-app: k8test1-service + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: ranchertest/mytestcontainer + ports: + - containerPort: 81 + tty: true + +--- +apiVersion: v1 +kind: Service +metadata: + name: k8test2 + labels: + k8s-app: k8test2-service +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: k8test2-service + +--- +apiVersion: v1 +kind: Pod +metadata: + name: nginx-ingress2 + labels: + k8s-app: k8test2-service +spec: + containers: + - name: testcontainer + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrole.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrole.yml new file mode 100644 index 0000000..bde0704 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrole.yml @@ -0,0 +1,9 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + # "namespace" omitted since ClusterRoles are not namespaced + name: read-pods-global +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrolebinding.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrolebinding.yml new file mode 100644 index 0000000..004738d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/clusterrolebinding.yml @@ -0,0 +1,12 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: read-pods-global +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: read-pods-global + apiGroup: rbac.authorization.k8s.io diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/daemonset_pods_per_node.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/daemonset_pods_per_node.yml new file mode 100644 index 0000000..a809fea --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/daemonset_pods_per_node.yml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: daemonset-test1 + labels: + k8s-app: daemonset-test1 +spec: + selector: + matchLabels: + name: daemonset-test1 + template: + metadata: + labels: + name: daemonset-test1 + spec: + tolerations: + - key: node-role.kubernetes.io/controlplane + effect: NoSchedule + containers: + - name: daemonset-test1 + image: sangeetha/mytestcontainer + terminationGracePeriodSeconds: 30 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/dashboard.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/dashboard.yaml new file mode 100644 index 0000000..39b8d03 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/dashboard.yaml @@ -0,0 +1,96 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard-certs + namespace: kube-system +type: Opaque +--- +# ------------------- Dashboard Service Account ------------------- # +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kube-system +--- +# ------------------- Dashboard Deployment ------------------- # +kind: Deployment +apiVersion: apps/v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kube-system +spec: + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + k8s-app: kubernetes-dashboard + template: + metadata: + labels: + k8s-app: kubernetes-dashboard + spec: + initContainers: + - name: kubernetes-dashboard-init + image: gcr.io/google_containers/kubernetes-dashboard-init-amd64:v1.0.1 + volumeMounts: + - name: kubernetes-dashboard-certs + mountPath: /certs + containers: + - name: kubernetes-dashboard + image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.7.1 + ports: + - containerPort: 8443 + protocol: TCP + args: + - --tls-key-file=/certs/dashboard.key + - --tls-cert-file=/certs/dashboard.crt + # Uncomment the following line to manually specify Kubernetes API server Host + # If not specified, Dashboard will attempt to auto discover the API server and connect + # to it. Uncomment only if the default does not work. + # - --apiserver-host=http://my-address:port + volumeMounts: + - name: kubernetes-dashboard-certs + mountPath: /certs + readOnly: true + # Create on-disk volume to store exec logs + - mountPath: /tmp + name: tmp-volume + livenessProbe: + httpGet: + scheme: HTTPS + path: / + port: 8443 + initialDelaySeconds: 30 + timeoutSeconds: 30 + volumes: + - name: kubernetes-dashboard-certs + secret: + secretName: kubernetes-dashboard-certs + - name: tmp-volume + emptyDir: {} + serviceAccountName: kubernetes-dashboard + # Comment the following tolerations if Dashboard must not be deployed on master + tolerations: + - key: node-role.kubernetes.io/controlplane + effect: NoSchedule +--- +# ------------------- Dashboard Service ------------------- # +kind: Service +apiVersion: v1 +metadata: + labels: + k8s-app: kubernetes-dashboard + name: kubernetes-dashboard + namespace: kube-system +spec: + ports: + - port: 443 + targetPort: 8443 + selector: + k8s-app: kubernetes-dashboard diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/role.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/role.yml new file mode 100644 index 0000000..e5f95cd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/role.yml @@ -0,0 +1,9 @@ +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + namespace: default + name: pod-reader +rules: +- apiGroups: [""] # "" indicates the core API group + resources: ["pods", "services", "replicationcontrollers"] + verbs: ["get", "watch", "list"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/rolebinding.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/rolebinding.yml new file mode 100644 index 0000000..60d3cff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/rolebinding.yml @@ -0,0 +1,13 @@ +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: read-pods + namespace: default +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: pod-reader + apiGroup: rbac.authorization.k8s.io diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test1.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test1.yml new file mode 100644 index 0000000..59bd14c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test1.yml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: Service +metadata: + name: k8test1 + labels: + k8s-app: k8test1-service +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: k8test1-service +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: k8testrc1 +spec: + replicas: 2 + selector: + k8s-app: k8test1-service + template: + metadata: + labels: + k8s-app: k8test1-service + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test2.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test2.yml new file mode 100644 index 0000000..0837a53 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_k8test2.yml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: Service +metadata: + name: k8test2 + labels: + k8s-app: k8test2-service +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: k8test2-service +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: k8testrc2 +spec: + replicas: 2 + selector: + k8s-app: k8test2-service + template: + metadata: + labels: + k8s-app: k8test2-service + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: sangeetha/mytestcontainer + ports: + - containerPort: 80 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_redis.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_redis.yml new file mode 100644 index 0000000..686a4e5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/service_redis.yml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis + labels: + k8s-app: redis-service +spec: + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + selector: + k8s-app: redis-service +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: redisrc +spec: + replicas: 2 + selector: + k8s-app: redis-service + template: + metadata: + labels: + k8s-app: redis-service + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: testcontainer + image: redis + ports: + - containerPort: 80 + tty: true \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/single_pod.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/single_pod.yml new file mode 100644 index 0000000..a7a984a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/single_pod.yml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: pod-test-util + labels: + k8s-app: pod-test-util +spec: + replicas: 1 + selector: + k8s-app: pod-test-util + template: + metadata: + name: pod-test-util + labels: + k8s-app: pod-test-util + spec: + containers: + - name: pod-test-util + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/two_container_pod.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/two_container_pod.yaml new file mode 100644 index 0000000..8f5b7b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/k8s_ymls/two_container_pod.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: pod-test-util + labels: + k8s-app: pod-test-util +spec: + replicas: 1 + selector: + k8s-app: pod-test-util + template: + metadata: + name: pod-test-util + labels: + k8s-app: pod-test-util + spec: + containers: + - name: pod-test-util + image: ranchertest/mytestcontainer + ports: + - containerPort: 80 + - name: nginx + image: nginx + ports: + - containerPort: 80 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_10.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_10.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_10.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_11.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_11.yml.j2 new file mode 100644 index 0000000..f75ed14 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_11.yml.j2 @@ -0,0 +1,16 @@ +ignore_docker_version: true +kubernetes_version: {{ k8s_version }} +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_2.yml.j2 new file mode 100644 index 0000000..ad3f4e1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_2.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ dns_hostname_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ dns_hostname_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ dns_hostname_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_3.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_3.yml.j2 new file mode 100644 index 0000000..fe5c156 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_3.yml.j2 @@ -0,0 +1,31 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + hostname_override: {{ hostname_override_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + hostname_override: {{ hostname_override_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + hostname_override: {{ hostname_override_2 }} +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + kube-controller: + image: {{ k8_rancher_image }} + scheduler: + image: {{ k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + kubeproxy: + image: {{ k8_rancher_image }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_4.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_4.yml.j2 new file mode 100644 index 0000000..d740701 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_4.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + hostname_override: {{ hostname_override_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + hostname_override: {{ hostname_override_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + hostname_override: {{ hostname_override_2 }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_5.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_5.yml.j2 new file mode 100644 index 0000000..0d94df2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_5.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + internal_address: {{ internal_address_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + internal_address: {{ internal_address_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + internal_address: {{ internal_address_2 }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_6.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_6.yml.j2 new file mode 100644 index 0000000..9e897c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_6.yml.j2 @@ -0,0 +1,21 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + internal_address: {{ internal_address_0 }} + hostname_override: {{ hostname_override_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + internal_address: {{ internal_address_1 }} + hostname_override: {{ hostname_override_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + internal_address: {{ internal_address_2 }} + hostname_override: {{ hostname_override_2 }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_7.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_7.yml.j2 new file mode 100644 index 0000000..9e897c7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_7.yml.j2 @@ -0,0 +1,21 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + internal_address: {{ internal_address_0 }} + hostname_override: {{ hostname_override_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + internal_address: {{ internal_address_1 }} + hostname_override: {{ hostname_override_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + internal_address: {{ internal_address_2 }} + hostname_override: {{ hostname_override_2 }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_8.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_8.yml.j2 new file mode 100644 index 0000000..f62af16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_8.yml.j2 @@ -0,0 +1,12 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_9.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_9.yml.j2 new file mode 100644 index 0000000..3c17efd --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_config_9.yml.j2 @@ -0,0 +1,17 @@ +ignore_docker_version: true +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + ssh_key_path: {{ ssh_key_path_0 }} + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + ssh_key_path: {{ ssh_key_path_1 }} + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + ssh_key_path: {{ ssh_key_path_2 }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_rbac_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_rbac_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_rbac_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_1.yml.j2 new file mode 100644 index 0000000..872e4df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_1.yml.j2 @@ -0,0 +1,9 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_2.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_2.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_3.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_3.yml.j2 new file mode 100644 index 0000000..1ffec32 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_3.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane,etcd,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_4.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_4.yml.j2 new file mode 100644 index 0000000..5caf698 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_install_roles_4.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd,worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane,worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [controlplane,etcd,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_2.yml.j2 new file mode 100644 index 0000000..276449b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_10_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_2.yml.j2 new file mode 100644 index 0000000..276449b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_11_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_1.yml.j2 new file mode 100644 index 0000000..b949c75 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_1.yml.j2 @@ -0,0 +1,21 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [controlplane] + - address: {{ ip_address_4 }} + user: {{ ssh_user_4 }} + role: [controlplane] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_2.yml.j2 new file mode 100644 index 0000000..195a27d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_12_2.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_1.yml.j2 new file mode 100644 index 0000000..6ec0cec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_1.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker,etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_2.yml.j2 new file mode 100644 index 0000000..864d86b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_13_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane,etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_1.yml.j2 new file mode 100644 index 0000000..6ec0cec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_1.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker,etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_2.yml.j2 new file mode 100644 index 0000000..cfaaa7d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_14_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker,etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_1.yml.j2 new file mode 100644 index 0000000..6ec0cec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_1.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker,etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_2.yml.j2 new file mode 100644 index 0000000..d70d686 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_15_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [etcd] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker,etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_2.yml.j2 new file mode 100644 index 0000000..1886b2a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_1_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_2.yml.j2 new file mode 100644 index 0000000..1886b2a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_3.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_3.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_2_3.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_2.yml.j2 new file mode 100644 index 0000000..162ba68 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_3_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [controlplane] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_1.yml.j2 new file mode 100644 index 0000000..190b558 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_2.yml.j2 new file mode 100644 index 0000000..162ba68 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [controlplane] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_3.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_3.yml.j2 new file mode 100644 index 0000000..195a27d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_4_3.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [controlplane] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_1.yml.j2 new file mode 100644 index 0000000..872e4df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_1.yml.j2 @@ -0,0 +1,9 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_2.yml.j2 new file mode 100644 index 0000000..ecdf4da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_5_2.yml.j2 @@ -0,0 +1,12 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_1.yml.j2 new file mode 100644 index 0000000..872e4df --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_1.yml.j2 @@ -0,0 +1,9 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_2.yml.j2 new file mode 100644 index 0000000..568b443 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_6_2.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_1.yml.j2 new file mode 100644 index 0000000..687fd3e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [etcd] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_2.yml.j2 new file mode 100644 index 0000000..5ebb8ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_7_2.yml.j2 @@ -0,0 +1,25 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + kube-controller: + image: {{ k8_rancher_image }} + scheduler: + image: {{ k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + kubeproxy: + image: {{ k8_rancher_image }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_1.yml.j2 new file mode 100644 index 0000000..52265af --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_1.yml.j2 @@ -0,0 +1,9 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_2.yml.j2 new file mode 100644 index 0000000..dcfb526 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_8_2.yml.j2 @@ -0,0 +1,12 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd,worker] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [controlplane,etcd,worker] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_1.yml.j2 new file mode 100644 index 0000000..905a957 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_1.yml.j2 @@ -0,0 +1,15 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_2.yml.j2 new file mode 100644 index 0000000..06abc8c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_update_roles_9_2.yml.j2 @@ -0,0 +1,18 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [etcd] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [controlplane,worker] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_1_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_1_1.yml.j2 new file mode 100644 index 0000000..2ed1c84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_1_1.yml.j2 @@ -0,0 +1,17 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + +kubernetes_version: {{k8_rancher_image}} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_1.yml.j2 new file mode 100644 index 0000000..2ed1c84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_1.yml.j2 @@ -0,0 +1,17 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + +kubernetes_version: {{k8_rancher_image}} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_2.yml.j2 new file mode 100644 index 0000000..8494329 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_2_2.yml.j2 @@ -0,0 +1,20 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + - address: {{ ip_address_3 }} + user: {{ ssh_user_3 }} + role: [worker] + +kubernetes_version: {{k8_rancher_image}} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_1.yml.j2 new file mode 100644 index 0000000..2ed1c84 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_1.yml.j2 @@ -0,0 +1,17 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] + +kubernetes_version: {{k8_rancher_image}} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_2.yml.j2 new file mode 100644 index 0000000..3d77bf9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_3_2.yml.j2 @@ -0,0 +1,14 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + +kubernetes_version: {{k8_rancher_image}} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_1.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_1.yml.j2 new file mode 100644 index 0000000..2696b3b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_1.yml.j2 @@ -0,0 +1,28 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + kube-controller: + image: {{ k8_rancher_image }} + scheduler: + image: {{ k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + kubeproxy: + image: {{ k8_rancher_image }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_2.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_2.yml.j2 new file mode 100644 index 0000000..1e4c321 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/cluster_upgrade_4_2.yml.j2 @@ -0,0 +1,28 @@ +ignore_docker_version: true +ssh_key_path: {{ master_ssh_key_path }} +network: + plugin: {{ network_plugin }} + {{ network_plugin_options }} +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane,etcd] + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + - address: {{ ip_address_2 }} + user: {{ ssh_user_2 }} + role: [worker] +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + kube-controller: + image: {{ k8_rancher_image }} + scheduler: + image: {{ upgrade_k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + kubeproxy: + image: {{ k8_rancher_image }} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/full_options_flannel_cluster_template.yml.j2 b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/full_options_flannel_cluster_template.yml.j2 new file mode 100644 index 0000000..4a00af9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/resources/rke_templates/full_options_flannel_cluster_template.yml.j2 @@ -0,0 +1,81 @@ +--- +auth: + strategy: x509 + options: + foo: bar + +network: + plugin: flannel + options: + flannel_image: quay.io/coreos/flannel:v0.9.1 + flannel_cni_image: quay.io/coreos/flannel-cni:v0.2.0 + +ssh_key_path: {{ master_ssh_key_path }} +ignore_docker_version: {{ ignore_docker_version }} +authorization: + mode: rbac + options: + +nodes: + - address: {{ ip_address_0 }} + user: {{ ssh_user_0 }} + role: [controlplane, etcd] + ssh_key_path: /home/user/.ssh/id_rsa + - address: {{ ip_address_1 }} + user: {{ ssh_user_1 }} + role: [worker] + ssh_key: |- +{{ ssh_key_1 }} + - address: {{ dns_hostname_2 }} + user: {{ ssh_user_2 }} + role: [worker] + hostname_override: node3 + internal_address: {{ internal_address_2 }} + +services: + etcd: + image: quay.io/coreos/etcd:latest + kube-api: + image: {{ k8_rancher_image }} + service_cluster_ip_range: 10.233.0.0/18 + pod_security_policy: false + extra_args: + v: 4 + kube-controller: + image: {{ k8_rancher_image }} + cluster_cidr: 10.233.64.0/18 + service_cluster_ip_range: 10.233.0.0/18 + scheduler: + image: {{ k8_rancher_image }} + kubelet: + image: {{ k8_rancher_image }} + cluster_domain: cluster.local + cluster_dns_server: 10.233.0.3 + infra_container_image: gcr.io/google_containers/pause-amd64:3.0 + kubeproxy: + image: {{ k8_rancher_image }} + + +system_images: + alpine: alpine:latest + nginx_proxy: rancher/rke-nginx-proxy:0.1.0 + cert_downloader: rancher/rke-cert-deployer:0.1.0 + kubedns_image: gcr.io/google_containers/k8s-dns-kube-dns-amd64:1.14.5 + dnsmasq_image: gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:1.14.5 + kubedns_sidecar_image: gcr.io/google_containers/k8s-dns-sidecar-amd64:1.14.5 + kubedns_autoscaler_image: gcr.io/google_containers/cluster-proportional-autoscaler-amd64:1.0.0 + +# all addon manifests MUST specify a namespace +addons: |- + --- + apiVersion: v1 + kind: Pod + metadata: + name: my-nginx + namespace: default + spec: + containers: + - name: my-nginx + image: nginx + ports: + - containerPort: 80 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/build.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/build.sh new file mode 100755 index 0000000..3f83d26 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" +RKE_VERSION="${RKE_VERSION:-v1.0.2}" +KUBECTL_VERSION="${KUBECTL_VERSION:-v1.27.10}" + +if [ "false" != "${DEBUG}" ]; then + echo "Environment:" + env | sort +fi + +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../../" && pwd )" + +count=0 +while [[ 3 -gt $count ]]; do + docker build --rm --build-arg RKE_VERSION=$RKE_VERSION --build-arg KUBECTL_VERSION=$KUBECTL_VERSION -f Dockerfile.rke -t rancher-validation-tests . + if [[ $? -eq 0 ]]; then break; fi + count=$(($count + 1)) + echo "Repeating failed Docker build ${count} of 3..." +done \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/configure.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/configure.sh new file mode 100755 index 0000000..81e6e17 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/scripts/configure.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -eu + +DEBUG="${DEBUG:-false}" + +env | egrep '^(RANCHER_|AWS_|DEBUG|DEFAULT_|OS_|DOCKER_|CLOUD_|KUBE|BUILD_NUMBER).*\=.+' | sort > .env + +if [ "false" != "${DEBUG}" ]; then + cat .env +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_config.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_config.py new file mode 100644 index 0000000..21d8da3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_config.py @@ -0,0 +1,135 @@ +from .conftest import * # NOQA +from .common import * # NOQA + + +def test_install_config_1(test_name, cloud_provider, rke_client, kubectl): + """ + Node Address specified as just IP and using only this in the node spec + Specific kubernetes_version can be used + """ + rke_template = 'cluster_install_config_11.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_config_2(test_name, cloud_provider, rke_client, kubectl): + """ + Node Address specified as FQDN and using only this in the node spec + """ + rke_template = 'cluster_install_config_2.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_config_3(test_name, cloud_provider, rke_client, kubectl): + """ + Hostname override specified as a non resolvable name + """ + rke_template = 'cluster_install_config_3.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + # set node_name to non-resolvable name for hostname_override + index = 0 + for node in nodes: + node.node_name = "{0}-{1}".format(test_name, index) + index += 1 + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_config_4(test_name, cloud_provider, rke_client, kubectl): + """ + Hostname override specified as a resolvable name + """ + rke_template = 'cluster_install_config_4.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + # set node_name to the resolvable host_name for hostname_override + for node in nodes: + node.node_name = node.host_name + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_config_5(test_name, cloud_provider, rke_client, kubectl): + """ + Internal address provided + """ + rke_template = 'cluster_install_config_5.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True, etcd_private_ip=True) + + +def test_install_config_6(test_name, cloud_provider, rke_client, kubectl): + """ + Providing address, hostname override(resolvable) and internal address + """ + rke_template = 'cluster_install_config_6.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + # set node_name to the resolvable host_name for hostname_override + for node in nodes: + node.node_name = node.host_name + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True, etcd_private_ip=True) + + +def test_install_config_7(test_name, cloud_provider, rke_client, kubectl): + """ + Providing address, hostname override(non-resolvable) and internal address + """ + rke_template = 'cluster_install_config_7.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + # set node_name to non-resolvable name for hostname_override + index = 0 + for node in nodes: + node.node_name = "{0}-{1}".format(test_name, index) + index += 1 + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True, etcd_private_ip=True) + + +def test_install_config_8(test_name, cloud_provider, rke_client, kubectl): + """ + Create a cluster with minimum possible values, will use the defaulted + network plugin for RKE + """ + rke_template = 'cluster_install_config_8.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_config_9(test_name, cloud_provider, rke_client, kubectl): + """ + Launch a cluster with unencrypted ssh keys + """ + key_name = 'install-config-9' + rke_template = 'cluster_install_config_9.yml.j2' + public_key = cloud_provider.generate_ssh_key(key_name) + cloud_provider.import_ssh_key(key_name + '.pub', public_key) + nodes = cloud_provider.create_multiple_nodes( + 3, test_name, key_name=key_name + '.pub') + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +# def test_install_config_10(test_name, cloud_provider, rke_client, kubectl): +# """ +# Launch a cluster with encrypted ssh keys +# """ +# rke_template = 'cluster_install_config_10.yml.j2' +# nodes = cloud_provider.create_multiple_nodes(3, test_name) +# create_rke_cluster(rke_client, kubectl, nodes, rke_template) +# validate_rke_cluster(rke_client, kubectl, nodes) +# for node in nodes: +# cloud_provider.delete_node(node) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_rbac.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_rbac.py new file mode 100644 index 0000000..9e3fc1a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_rbac.py @@ -0,0 +1,67 @@ +from .conftest import * # NOQA +from .common import * # NOQA + + +@pytest.mark.skip("Use as an example of how to test RBAC") +def test_install_rbac_1(test_name, cloud_provider, rke_client, kubectl): + """ + Create a three node cluster and runs validation to create pods + Removes cluster and validates components are removed + """ + rke_template = 'cluster_install_rbac_1.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_rke_cluster(rke_client, kubectl, nodes, rke_template) + + result = kubectl.create_resourse_from_yml( + 'resources/k8s_ymls/daemonset_pods_per_node.yml', namespace='default') + assert result.ok, result.stderr + kubectl.create_ns('outside-role') + result = kubectl.create_resourse_from_yml( + 'resources/k8s_ymls/daemonset_pods_per_node.yml', + namespace='outside-role') + assert result.ok, result.stderr + + # Create role and rolebinding to user1 in namespace 'default' + # namespace is coded in role.yml and rolebinding.yml + result = kubectl.create_resourse_from_yml('resources/k8s_ymls/role.yml') + assert result.ok, result.stderr + result = kubectl.create_resourse_from_yml( + 'resources/k8s_ymls/rolebinding.yml') + assert result.ok, result.stderr + + # verify read in namespace + admin_call_pods = kubectl.get_resource('pods', namespace='default') + user_call_pods = kubectl.get_resource( + 'pods', as_user='user1', namespace='default') + + # Make sure the number of pods returned with out user is the same as user + # for this namespace + assert len(admin_call_pods['items']) > 0, "Pods should be greater than 0" + assert (len(admin_call_pods['items']) == len(user_call_pods['items'])), ( + "Did not retrieve correct number of pods for 'user1'. Expected {0}," + "Retrieved {1}".format( + len(admin_call_pods['items']), len(user_call_pods['items']))) + + # verify restrictions no pods return in get pods in different namespaces + user_call_pods = kubectl.get_resource( + 'pods', as_user='user1', namespace='outside-role') + assert len(user_call_pods['items']) == 0, ( + "Should not be able to get pods outside of defined user1 namespace") + + # verify create fails as user for any namespace + result = kubectl.run(test_name + '-pod2', image='nginx', as_user='user1', + namespace='outside-role') + assert result.ok is False, ( + "'user1' should not be able to create pods in other namespaces:\n{0}" + .format(result.stdout + result.stderr)) + assert "cannot create" in result.stdout + result.stderr + + result = kubectl.run(test_name + '-pod3', image='nginx', as_user='user1', + namespace='default') + assert result.ok is False, ( + "'user1' should not be able to create pods in its own namespace:\n{0}" + .format(result.stdout + result.stderr)) + assert "cannot create" in result.stdout + result.stderr + + for node in nodes: + cloud_provider.delete_node(node) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_roles.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_roles.py new file mode 100644 index 0000000..6b74414 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_install_roles.py @@ -0,0 +1,51 @@ +from .conftest import * # NOQA +from .common import * # NOQA + + +def test_install_roles_1(test_name, cloud_provider, rke_client, kubectl): + """ + Create cluster with single node with roles controlplane, worker, etcd + """ + rke_template = 'cluster_install_roles_1.yml.j2' + nodes = cloud_provider.create_multiple_nodes(1, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_roles_2(test_name, cloud_provider, rke_client, kubectl): + """ + Create cluster with 3 nodes having each with single role: + node0 - controlplane, node1 - etcd, node2 - worker + """ + rke_template = 'cluster_install_roles_2.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_roles_3(test_name, cloud_provider, rke_client, kubectl): + """ + Create cluster with 3 nodes having all three roles + """ + rke_template = 'cluster_install_roles_3.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) + + +def test_install_roles_4(test_name, cloud_provider, rke_client, kubectl): + """ + Create a 4 node node cluster with nodes having these roles: + node0 - etcd, controlplane + node1 - etcd, worker + node2 - controlplane, worker + node3 - controlplane, etcd, worker + """ + rke_template = 'cluster_install_roles_4.yml.j2' + nodes = cloud_provider.create_multiple_nodes(4, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_remove_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_remove_cluster.py new file mode 100644 index 0000000..691dbab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_remove_cluster.py @@ -0,0 +1,21 @@ +from .conftest import * # NOQA +from .common import * # NOQA + + +def test_remove_1(test_name, cloud_provider, rke_client, kubectl): + """ + Create a three node cluster and runs validation to create pods + Removes cluster and validates components are removed + Then creates new cluster on the same nodes and validates + """ + rke_template = 'cluster_install_config_1.yml.j2' + nodes = cloud_provider.create_multiple_nodes(3, test_name) + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes) + rke_client.remove() + + validate_remove_cluster(nodes) + + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, nodes, + remove_nodes=True) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_update_roles.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_update_roles.py new file mode 100644 index 0000000..58e9297 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_update_roles.py @@ -0,0 +1,558 @@ +from .conftest import * # NOQA +from .common import * # NOQA + + +def test_update_roles_1(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a worker node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a worker + node0 - controlplane + node1 - etcd + node2 - worker + node3 - worker + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + + # Only use three nodes at first + before_update_nodes = all_nodes[0:-1] + rke_template = 'cluster_update_roles_1_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding worker node, rerun on existing validation pods + rke_template = 'cluster_update_roles_1_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_2(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a worker node, then remove original worker node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a worker + node0 - controlplane + node1 - etcd + node2 - worker <- will be deleted on next update + node3 - worker + After 2nd Update: Deletes original worker + node0 - controlplane + node1 - etcd + node3 - worker + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] + removed_node_nodes = all_nodes[0:2] + all_nodes[3:] + # all_nodes[0:2] = [node0, node1] + # all_nodes[3:] = [node3] + + # Only use three nodes at first + rke_template = 'cluster_update_roles_2_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding worker node, rerun on existing validation pods + rke_template = 'cluster_update_roles_2_2.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + network_update1, dns_discovery_update1 = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupdate1') + + # Update removing original worker node, rerun on existing validation pods + rke_template = 'cluster_update_roles_2_3.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, removed_node_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate1', + network_validation=network_update1, + dns_validation=dns_discovery_update1) + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate2') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_3(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a controlplane node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a controlplane + node0 - controlplane + node1 - etcd + node2 - worker + node3 - controlplane + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] # only use three nodes at first + + # Only use three nodes at first + rke_template = 'cluster_update_roles_3_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding controlplane node, rerun on existing validation pods + rke_template = 'cluster_update_roles_3_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_4(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a controlplane node, remove original controlplane + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a controlplane + node0 - controlplane <- will be deleted on next update + node1 - etcd + node2 - worker + node3 - controlplane + After 2nd Update: Deletes original controlplane + node1 - etcd + node2 - worker + node3 - controlplane + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] # only use three nodes at first + removed_node_nodes = all_nodes[1:] + + rke_template = 'cluster_update_roles_4_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding controlplane node, rerun on existing validation pods + rke_template = 'cluster_update_roles_4_2.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + network_update1, dns_discovery_update1 = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupdate1') + + # Update removing original controlplane node + # rerun on existing validation pods + # all_nodes[1:] = [node1, node2, node3] + rke_template = 'cluster_update_roles_4_3.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, removed_node_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate1', + network_validation=network_update1, + dns_validation=dns_discovery_update1) + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate2') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_5(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a etcd node to a single node cluster + Before Update: Create single node cluster with all roles + node0 - controlplane, etcd, worker + After Update: Adds a etcd + node0 - controlplane, etcd, worker + node1 - etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(2, test_name) + before_update_nodes = all_nodes[0:-1] # only use one node at first + + rke_template = 'cluster_update_roles_5_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding etcd node, rerun on existing validation pods + rke_template = 'cluster_update_roles_5_2.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_6(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding two etcd nodes to a single node cluster + Before Update: Create single node cluster with all roles + node0 - controlplane, etcd, worker + After Update: Adds two etcd nodes + node0 - controlplane, etcd, worker + node1 - etcd + node2 - etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(3, test_name) + before_update_nodes = all_nodes[0:-2] # only use one node at first + + rke_template = 'cluster_update_roles_6_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adding 2 etcd nodes, rerun on existing validation pods + rke_template = 'cluster_update_roles_6_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_7(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster deleting one node with all roles in three node cluster + Before Update: Create three node cluster with all roles + node0 - controlplane, etcd, worker + node1 - worker + node2 - etcd + After Update: Remove last node + node0 - controlplane, etcd, worker + node1 - worker + """ + all_nodes = cloud_provider.create_multiple_nodes(3, test_name) + removed_node_nodes = all_nodes[0:-1] + + rke_template = 'cluster_update_roles_7_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate') + + # Update remove etcd node, rerun on existing validation pods + rke_template = 'cluster_update_roles_7_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, removed_node_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + + # Create another validation setup on updated cluster + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate') + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_8(test_name, cloud_provider, rke_client, kubectl): + """ + Create a single node cluster, add second node with all roles, and then + delete the original node + Before Update: Create single node cluster with all roles + node0 - controlplane, etcd, worker + After Update: Add second node with all roles + node0 - controlplane, etcd, worker + node1 - controlplane, etcd, worker + After second Update: Remove original node0 + node1 - controlplane, etcd, worker + """ + all_nodes = cloud_provider.create_multiple_nodes(2, test_name) + before_update_nodes = all_nodes[0:-1] + removed_node_nodes = all_nodes[1:] + + # Inital cluster + rke_template = 'cluster_update_roles_8_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update create a second node will all roles + rke_template = 'cluster_update_roles_8_2.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + network_update1, dns_discovery_update1 = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupdate1') + + # Update remove original node with all roles + rke_template = 'cluster_update_roles_8_1.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, removed_node_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate1', + network_validation=network_update1, + dns_validation=dns_discovery_update1) + # Create another validation setup on updated cluster + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate2') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_9(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a controlplane,worker node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a controlplane, worker + node0 - controlplane + node1 - etcd + node2 - worker + node3 - controlplane, worker + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] # only use three nodes at first + + # Inital cluster + rke_template = 'cluster_update_roles_9_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adds node with roles [controlplane,worker] + rke_template = 'cluster_update_roles_9_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_10(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a controlplane,worker node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a controlplane, etcd + node0 - controlplane + node1 - etcd + node2 - worker + node3 - controlplane, etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] # only use three nodes at first + + # Inital cluster + rke_template = 'cluster_update_roles_10_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adds node with roles [controlplane,etcd] + rke_template = 'cluster_update_roles_10_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_11(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a worker, etcd node + Before Update: Create three node cluster, each node with a single role + node0 - controlplane + node1 - etcd + node2 - worker + After Update: Adds a etcd, worker + node0 - controlplane + node1 - etcd + node2 - worker + node3 - worker, etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_update_nodes = all_nodes[0:-1] # only use three nodes at first + + # Inital cluster + rke_template = 'cluster_update_roles_11_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update adds node with roles [worker,etcd] + rke_template = 'cluster_update_roles_11_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_12(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster adding a controlplane,worker node + Before Update: + node0 - etcd + node1 - worker + node2 - controlplane + node3 - controlplane + node4 - controlplane + After Update: Adds a controlplane, worker + node0 - etcd + node1 - worker + node5 - controlplane <- New contolplane node + """ + all_nodes = cloud_provider.create_multiple_nodes(6, test_name) + before_update_nodes = all_nodes[0:-1] # only use five nodes at first + # all_nodes[0:2] = [node0, node1] + # all_nodes[5:] = [node5] + removed_node_nodes = all_nodes[0:2] + all_nodes[5:] + + # Inital cluster + rke_template = 'cluster_update_roles_12_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, before_update_nodes, + base_namespace='beforeupdate') + + # Update removes all existing controlplane nodes, + # adds node with [controlplane] + rke_template = 'cluster_update_roles_12_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, removed_node_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster( + rke_client, kubectl, removed_node_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_13(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster changing a worker role to controlplane + Before Update: Create four node cluster, each node with these roles: + node0 - controlplane + node1 - controlplane, etcd + node2 - worker, etcd + node3 - worker, etcd + After Update: Change node2 worker to controlplane + node0 - controlplane + node1 - controlplane, etcd + node2 - controlplane, etcd + node3 - worker, etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + + rke_template = 'cluster_update_roles_13_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate') + + # Update changes role worker to controlplane on node2 + rke_template = 'cluster_update_roles_13_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_14(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster changing a controlplane, etcd to etcd only + Before Update: Create four node cluster, each node with these roles: + node0 - controlplane + node1 - controlplane, etcd + node2 - worker, etcd + node3 - worker, etcd + After Update: Change node1 controlplane, etcd to etcd + node0 - controlplane + node1 - etcd + node2 - worker, etcd + node3 - worker, etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + + rke_template = 'cluster_update_roles_14_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate') + + # Update remove controlplane on node1 + rke_template = 'cluster_update_roles_14_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) + + +def test_update_roles_15(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster remove worker role from [worker,etcd] node + Before Update: Create four node cluster, each node with these roles: + node0 - controlplane + node1 - controlplane, etcd + node2 - worker, etcd + node3 - worker, etcd + After Update: Change remove worker role node2 + node0 - controlplane + node1 - controlplane, etcd + node2 - etcd + node3 - worker, etcd + """ + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + + rke_template = 'cluster_update_roles_15_1.yml.j2' + network, dns_discovery = create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate') + + # Update remove worker role node2 + rke_template = 'cluster_update_roles_15_2.yml.j2' + create_and_validate( + cloud_provider, rke_client, kubectl, rke_template, all_nodes, + base_namespace='beforeupdate', network_validation=network, + dns_validation=dns_discovery) + # Create another validation setup on updated cluster + validate_rke_cluster(rke_client, kubectl, all_nodes, 'afterupdate') + + delete_nodes(cloud_provider, all_nodes) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_upgrade.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_upgrade.py new file mode 100644 index 0000000..7772d6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/rke/test_upgrade.py @@ -0,0 +1,164 @@ +import os + +from .conftest import * # NOQA +from .common import * # NOQA +import pytest + +K8S_PREUPGRADE_IMAGE = os.environ.get( + 'RANCHER_K8S_PREUPGRADE_IMAGE', 'v1.16.8-rancher1-3') +K8S_UPGRADE_IMAGE = os.environ.get( + 'RANCHER_K8S_UPGRADE_IMAGE', 'v1.17.4-rancher1-3') + + +def test_upgrade_1(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster k8s service images, cluster config: + node0 - controlplane, etcd + node1 - worker + node2 - worker + """ + print(K8S_UPGRADE_IMAGE) + print(K8S_PREUPGRADE_IMAGE) + + rke_template = 'cluster_upgrade_1_1.yml.j2' + all_nodes = cloud_provider.create_multiple_nodes(3, test_name) + + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_PREUPGRADE_IMAGE) + + network, dns_discovery = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade') + + validate_k8s_service_images(all_nodes, K8S_PREUPGRADE_IMAGE, + rke_client, kubectl) + + # New cluster needs to keep controlplane and etcd nodes the same + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_UPGRADE_IMAGE) + # The updated images versions need to be validated + validate_k8s_service_images(all_nodes, K8S_UPGRADE_IMAGE, + rke_client, kubectl) + # Rerun validation on existing and new resources + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade', + network_validation=network, dns_validation=dns_discovery) + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupgrade') + delete_nodes(cloud_provider, all_nodes) + + +def test_upgrade_2(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster k8s service images and add worker node, cluster config: + node0 - controlplane, etcd + node1 - worker + node2 - worker + Upgrade adds a worker node: + node0 - controlplane, etcd + node1 - worker + node2 - worker + node3 - worker + """ + rke_template = 'cluster_upgrade_2_1.yml.j2' + all_nodes = cloud_provider.create_multiple_nodes(4, test_name) + before_upgrade_nodes = all_nodes[0:-1] + rke_config = create_rke_cluster( + rke_client, kubectl, before_upgrade_nodes, rke_template, + k8_rancher_image=K8S_PREUPGRADE_IMAGE) + network, dns_discovery = validate_rke_cluster( + rke_client, kubectl, before_upgrade_nodes, 'beforeupgrade') + validate_k8s_service_images(before_upgrade_nodes, K8S_PREUPGRADE_IMAGE, + rke_client, kubectl) + + # New cluster needs to keep controlplane and etcd nodes the same + rke_template = 'cluster_upgrade_2_2.yml.j2' + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_UPGRADE_IMAGE) + validate_k8s_service_images(all_nodes, K8S_UPGRADE_IMAGE, + rke_client, kubectl) + + # Rerun validation on existing and new resources + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade', + network_validation=network, dns_validation=dns_discovery) + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupgrade') + delete_nodes(cloud_provider, all_nodes) + + +def test_upgrade_3(test_name, cloud_provider, rke_client, kubectl): + """ + Update cluster k8s service images and remove worker node, cluster config: + node0 - controlplane, etcd + node1 - worker + node2 - worker + Upgrade removes a worker node: + node0 - controlplane, etcd + node1 - worker + """ + rke_template = 'cluster_upgrade_3_1.yml.j2' + all_nodes = cloud_provider.create_multiple_nodes(3, test_name) + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_PREUPGRADE_IMAGE) + network, dns_discovery = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade') + validate_k8s_service_images(all_nodes, K8S_PREUPGRADE_IMAGE, + rke_client, kubectl) + + # New cluster needs to keep controlplane and etcd nodes the same + rke_template = 'cluster_upgrade_3_2.yml.j2' + after_upgrade_nodes = all_nodes[0:-1] + rke_config = create_rke_cluster( + rke_client, kubectl, after_upgrade_nodes, rke_template, + k8_rancher_image=K8S_UPGRADE_IMAGE) + validate_k8s_service_images(after_upgrade_nodes, K8S_UPGRADE_IMAGE, + rke_client, kubectl) + + # Rerun validation on existing and new resources + validate_rke_cluster( + rke_client, kubectl, after_upgrade_nodes, 'beforeupgrade', + network_validation=network, dns_validation=dns_discovery) + validate_rke_cluster( + rke_client, kubectl, after_upgrade_nodes, 'afterupgrade') + delete_nodes(cloud_provider, all_nodes) + + +@pytest.mark.skipif( + True, reason="This test is skipped for now") +def test_upgrade_4(test_name, cloud_provider, rke_client, kubectl): + """ + Update only one service in cluster k8s system images, cluster config: + node0 - controlplane, etcd + node1 - worker + node2 - worker + """ + rke_template = 'cluster_upgrade_4_1.yml.j2' + all_nodes = cloud_provider.create_multiple_nodes(3, test_name) + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_PREUPGRADE_IMAGE) + network, dns_discovery = validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade') + validate_k8s_service_images(all_nodes, K8S_PREUPGRADE_IMAGE, + rke_client, kubectl) + + # Upgrade only the scheduler, yaml will replace `upgrade_k8_rancher_image` + # for scheduler image only, the rest will keep pre-upgrade image + rke_config = create_rke_cluster( + rke_client, kubectl, all_nodes, rke_template, + k8_rancher_image=K8S_PREUPGRADE_IMAGE, + upgrade_k8_rancher_image=K8S_UPGRADE_IMAGE) + validate_k8s_service_images(all_nodes, K8S_UPGRADE_IMAGE, + rke_client, kubectl) + # Rerun validation on existing and new resources + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'beforeupgrade', + network_validation=network, dns_validation=dns_discovery) + validate_rke_cluster( + rke_client, kubectl, all_nodes, 'afterupgrade') + + delete_nodes(cloud_provider, all_nodes) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/README.md new file mode 100644 index 0000000..332c492 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/README.md @@ -0,0 +1,37 @@ +# New rancher client for new API v1 +Before we dive into the technical details, let's clarify a confusion here: + +Yes, the new API is v1, and the old API is v3. + +The new API is v1 because it is the beginning of Rancher's new API framework +which is used for Rancher's new UI, i.e. the cluster explorer, to talk with the backend. + +The support for the new v1 API is added to the [Rancher client module](https://github.com/rancher/client-python). + +There are two levels of the client: admin client and cluster client. + +In fact, the admin client is the cluster client of the local cluster which only the admin can access to. + +# Naming the testing methods + +The format + + test_{resource_name}_[with_{field}]_{operation}[_{order_number}] +where: +- resource_name: [required] the name of the resource to test. + Examples: namespace, deployment, monitoring +- field: [optional] The name of the additional field added to the basic. + Examples: secret, lb, label +- operation: [required] the verb of operation. + Examples: create, update, delete +- order_number: [optional] when there are more than 1 test case, the number starts from 2 + +Examples: +- test_deployment() +- test_deployment_update() +- test_deployment_update_2() +- test_deployment_with_secret_create() +- test_deployment_with_secret_update() +- test_monitoring_enable() +- test_monitoring_update() +- test_notifier_create() diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/common.py new file mode 100644 index 0000000..8734fb8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/common.py @@ -0,0 +1,79 @@ +from ..common import * # NOQA +import pprint +import json +import yaml +import rancher + +TEST_IMAGE_V1 = os.environ.get('RANCHER_TEST_IMAGE_V1', "ranchertest/mytestcontainer") + + +def get_admin_client_v1(): + url = CATTLE_TEST_URL + "/v1" + # in fact, we get the cluster client for the local cluster + return rancher.Client(url=url, token=ADMIN_TOKEN, verify=False) + + +def get_cluster_client_for_token_v1(cluster_id=None, token=None): + if cluster_id is None: + cluster = get_cluster_by_name(get_admin_client_v1(), CLUSTER_NAME) + cluster_id = cluster["id"] + if token is None: + token = USER_TOKEN + + url = CATTLE_TEST_URL + "/k8s/clusters/" + cluster_id + "/v1/schemas" + return rancher.Client(url=url, token=token, verify=False) + + +def get_cluster_by_name(client, cluster_name): + res = client.list_management_cattle_io_cluster() + assert "data" in res.keys(), "failed to find any cluster in the setup" + for cluster in res["data"]: + if cluster["spec"]["displayName"] == cluster_name: + return cluster + assert False, "failed to find the cluster {}".format(cluster_name) + + +def display(res): + if res is None: + print("None object is returned") + return + if isinstance(res, dict) and "data" in res.keys(): + print("count of data {}".format(len(res.data))) + for item in res.get("data"): + print("-------") + pprint.pprint(item) + return + else: + print("This is a instance of {}".format(type(res))) + pprint.pprint(res) + + +def read_json_from_resource_dir(filename): + dir_path = os.path.dirname(os.path.realpath(__file__)) + try: + with open('{}/resource/{}'.format(dir_path, filename)) as f: + data = json.load(f) + return data + except FileNotFoundError as e: + assert False, e + + +def read_yaml_from_resource_dir(filename): + dir_path = os.path.dirname(os.path.realpath(__file__)) + try: + with open('{}/resource/{}'.format(dir_path, filename)) as f: + data = yaml.safe_load(f) + return data + except FileNotFoundError as e: + assert False, e + + +def create_project(cluster, project_name): + admin_client = get_admin_client_v1() + project = read_yaml_from_resource_dir("project.yaml") + project["metadata"]["name"] = project_name + project["metadata"]["namespace"] = cluster["id"] + project["spec"]["clusterName"] = cluster["id"] + project["spec"]["displayName"] = project_name + res = admin_client.create_management_cattle_io_project(project) + return res diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/daemonset_1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/daemonset_1.json new file mode 100644 index 0000000..c868cb6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/daemonset_1.json @@ -0,0 +1,43 @@ +{ + "type": "apps.daemonset", + "metadata": { + "namespace": "", + "name": "" + }, + "metadata.annotations": { + }, + "metadata.labels": { + }, + "spec": { + "template": { + "spec": { + "restartPolicy": "Always", + "containers": [ + { + "imagePullPolicy": "Always", + "volumeMounts": [ + ], + "image": "", + "name": "" + } + ], + "imagePullSecrets": [ + ], + "volumes": [ + ], + "affinity": { + } + }, + "metadata": { + "labels": { + "workload.user.cattle.io/workloadselector": "" + } + } + }, + "selector": { + "matchLabels": { + "workload.user.cattle.io/workloadselector": "" + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/deployment_1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/deployment_1.json new file mode 100644 index 0000000..7d74b18 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/deployment_1.json @@ -0,0 +1,38 @@ +{ + "type": "apps.deployment", + "metadata": { + "namespace": "", + "name": "" + }, + "metadata.annotations": {}, + "metadata.labels": {}, + "spec": { + "replicas": 3, + "template": { + "spec": { + "restartPolicy": "Always", + "containers": [ + { + "imagePullPolicy": "Always", + "volumeMounts": [], + "image": "", + "name": "" + } + ], + "imagePullSecrets": [], + "volumes": [], + "affinity": {} + }, + "metadata": { + "labels": { + "workload.user.cattle.io/workloadselector": "" + } + } + }, + "selector": { + "matchLabels": { + "workload.user.cattle.io/workloadselector": "" + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/fleet_1.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/fleet_1.json new file mode 100644 index 0000000..fb1a55f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/fleet_1.json @@ -0,0 +1,28 @@ +{ + "type": "fleet.cattle.io.gitrepo", + "metadata": { + "namespace": "fleet-default", + "name": "" + }, + "metadata.annotations": { + }, + "metadata.labels": { + }, + "spec": { + "repo": "https://github.com/rancher/fleet-examples", + "branch": "master", + "paths": [ + "/simple" + ], + "targets": [ + { + "clusterSelector": { + "matchLabels": { + "management.cattle.io/cluster-name": "" + } + } + } + ], + "insecureSkipTLSVerify": false + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/monitoring_v2_values.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/monitoring_v2_values.json new file mode 100644 index 0000000..7dfd9c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/monitoring_v2_values.json @@ -0,0 +1,69 @@ +{ + "charts":[ + { + "chartName":"rancher-monitoring-crd", + "version":"", + "releaseName":"rancher-monitoring-crd", + "projectId":"", + "values":{ + "global":{ + "cattle":{ + "clusterId":"", + "clusterName":"", + "systemDefaultRegistry":"" + }, + "systemDefaultRegistry":"" + } + }, + "annotations":{ + "catalog.cattle.io/ui-source-repo-type":"cluster", + "catalog.cattle.io/ui-source-repo":"rancher-charts" + } + }, + { + "chartName":"rancher-monitoring", + "version":"", + "releaseName":"rancher-monitoring", + "annotations":{ + "catalog.cattle.io/ui-source-repo-type":"cluster", + "catalog.cattle.io/ui-source-repo":"rancher-charts" + }, + "values":{ + "prometheus":{ + "prometheusSpec":{ + "evaluationInterval":"1m", + "retentionSize":"50GiB", + "scrapeInterval":"1m" + } + }, + "rkeControllerManager":{ + "enabled":true + }, + "rkeEtcd":{ + "enabled":true + }, + "rkeProxy":{ + "enabled":true + }, + "rkeScheduler":{ + "enabled":true + }, + "global":{ + "cattle":{ + "clusterId":"", + "clusterName":"", + "systemDefaultRegistry":"" + }, + "systemDefaultRegistry":"" + } + } + } + ], + "noHooks":false, + "timeout":"600s", + "wait":true, + "namespace":"cattle-monitoring-system", + "projectId":"", + "disableOpenAPIValidation":false, + "skipCRDs":false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/namespace.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/namespace.yaml new file mode 100644 index 0000000..02ac922 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/namespace.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: "" + annotations: + "field.cattle.io/projectId": "" + labels: + "field.cattle.io/projectId": "" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/project.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/project.yaml new file mode 100644 index 0000000..4dcc737 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/resource/project.yaml @@ -0,0 +1,8 @@ +apiVersion: management.cattle.io/v3 +kind: Project +metadata: + name: "" + namespace: "" +spec: + clusterName: "" + displayName: "" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_daemonset.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_daemonset.py new file mode 100644 index 0000000..672bc41 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_daemonset.py @@ -0,0 +1,71 @@ +from .common import * # NOQA +import pytest + +namespace = {"client": None, "ns": None} + + +def test_daemonset(): + client = namespace["client"] + ns = namespace["ns"] + template = read_json_from_resource_dir("daemonset_1.json") + name = random_name() + # set name + template["metadata"]["name"] = name + # set namespace + template["metadata"]["namespace"] = ns.id + # set container image and name + template["spec"]["template"]["spec"]["containers"][0]["image"] = TEST_IMAGE_V1 + template["spec"]["template"]["spec"]["containers"][0]["name"] = name + # set label and selector + label_value = "apps.daemonset-{}-{}".format(ns.id, name) + labels = template["spec"]["template"]["metadata"]["labels"] + labels["workload.user.cattle.io/workloadselector"] = label_value + matches = template["spec"]["selector"]["matchLabels"] + matches["workload.user.cattle.io/workloadselector"] = label_value + + res = client.create_apps_daemonset(template) + res = validate_daemonset(client, res) + client.delete(res) + + +def get_worker_node(client): + nodes = client.list_node( + labelSelector="node-role.kubernetes.io/worker=true") + return nodes.data + + +def validate_daemonset(client, daemonset): + # wait for the deployment to be active + wait_for(lambda: client.reload(daemonset).metadata.state.name == "active", + timeout_message="time out waiting for deployment to be ready") + res = client.reload(daemonset) + name = res["metadata"]["name"] + namespace = res["metadata"]["namespace"] + node_count = len(get_worker_node(client)) + # Rancher Dashboard gets pods by passing the label selector + label_key = 'workload.user.cattle.io/workloadselector' + label_value = 'apps.daemonset-{}-{}'.format(namespace, name) + pods = client.list_pod( + labelSelector='{}={}'.format(label_key, label_value)) + assert "data" in pods.keys(), "failed to get pods" + assert len(pods.data) == node_count, "wrong number of pods" + for pod in pods.data: + assert label_value == pod.metadata.labels[label_key] + assert pod.metadata.state.name == "running" + return res + + +@pytest.fixture(scope='module', autouse="True") +def create_client(request): + client = get_cluster_client_for_token_v1() + template = read_yaml_from_resource_dir("namespace.yaml") + template["metadata"]["name"] = random_test_name() + ns = client.create_namespace(template) + + namespace["client"] = client + namespace["ns"] = ns + + def fin(): + client.delete(namespace["ns"]) + + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_deployment.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_deployment.py new file mode 100644 index 0000000..e625b48 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_deployment.py @@ -0,0 +1,79 @@ +from .common import * # NOQA +import pytest + +namespace = {"client": None, "ns": None} + + +def test_namespace_create(): + template = read_yaml_from_resource_dir("namespace.yaml") + template["metadata"]["name"] = random_test_name() + client = namespace["client"] + res = client.create_namespace(template) + # validate the namespace is created + ns = client.by_id_namespace(res.id) + assert ns.id == res.id + # delete the namespace at the end + client.delete(ns) + + +def test_deployment(): + client = namespace["client"] + ns = namespace["ns"] + template = read_json_from_resource_dir("deployment_1.json") + name = random_name() + # set name + template["metadata"]["name"] = name + # set namespace + template["metadata"]["namespace"] = ns.id + # set container image and name + template["spec"]["template"]["spec"]["containers"][0]["image"] = TEST_IMAGE_V1 + template["spec"]["template"]["spec"]["containers"][0]["name"] = name + # set label and selector + label_value = "apps.deployment-{}-{}".format(ns.id, name) + labels = template["spec"]["template"]["metadata"]["labels"] + labels["workload.user.cattle.io/workloadselector"] = label_value + matches = template["spec"]["selector"]["matchLabels"] + matches["workload.user.cattle.io/workloadselector"] = label_value + + deployment = client.create_apps_deployment(template) + deployment = validate_deployment(client, deployment) + # scale up to 5 pods + deployment.spec.replicas = 5 + deployment = client.update(deployment, deployment) + deployment = validate_deployment(client, deployment) + client.delete(deployment) + + +def validate_deployment(client, deployment): + # wait for the deployment to be active + wait_for(lambda: client.reload(deployment).metadata.state.name == "active", + timeout_message="time out waiting for deployment to be ready") + res = client.reload(deployment) + name = res["metadata"]["name"] + namespace = res["metadata"]["namespace"] + replicas = res["spec"]["replicas"] + # Rancher Dashboard gets pods by passing the label selector + target_label = 'workload.user.cattle.io/workloadselector=apps.deployment-{}-{}' + pods = client.list_pod( + labelSelector=target_label.format(namespace, name)) + assert "data" in pods.keys(), "failed to get pods" + assert len(pods.data) == replicas, "failed to get the right number of pods" + for pod in pods.data: + assert pod.metadata.state.name == "running" + return res + + +@pytest.fixture(scope='module', autouse="True") +def create_client(request): + client = get_cluster_client_for_token_v1() + template = read_yaml_from_resource_dir("namespace.yaml") + template["metadata"]["name"] = random_test_name() + ns = client.create_namespace(template) + + namespace["client"] = client + namespace["ns"] = ns + + def fin(): + client.delete(namespace["ns"]) + + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_fleet.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_fleet.py new file mode 100644 index 0000000..e9601a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_fleet.py @@ -0,0 +1,69 @@ +from .common import * # NOQA +import pytest + +namespace = {'client': None, 'cluster': None} + + +def test_fleet_simple(): + client = namespace['client'] + + template = read_json_from_resource_dir("fleet_1.json") + name = random_name() + # set name + template['metadata']['name'] = name + # set target + cluster_id = namespace['cluster']['id'] + match_labels = template['spec']['targets'][0]['clusterSelector']['matchLabels'] + match_labels['management.cattle.io/cluster-name'] = cluster_id + res = client.create_fleet_cattle_io_gitrepo(template) + res = validate_fleet(client, res) + # delete the fleet + client.delete(res) + + +def validate_fleet(client, fleet): + # the gitRepo's state shows active at the beginning + # which is not the actual state + time.sleep(10) + try: + wait_for(lambda: client.reload(fleet).metadata.state.name == 'active', + timeout_message='time out waiting for gitRepo to be ready') + except Exception as e: + assert False, str(e) + fleet = client.reload(fleet) + # validate the bundle is active + bundle = get_bundle_by_fleet_name(client, fleet.metadata.name) + wait_for(lambda: client.reload(bundle).metadata.state.name == 'active', + timeout_message='time out waiting for the bundle to be ready') + return fleet + + +def get_bundle_by_fleet_name(client, name): + start_time = time.time() + while time.time() - start_time < 30: + res = client.list_fleet_cattle_io_bundle() + for bundle in res['data']: + keys = bundle['metadata']['labels'].keys() + print("------") + print(keys) + if 'fleet.cattle.io/repo-name' in keys: + bundle_name = \ + bundle['metadata']['labels']['fleet.cattle.io/repo-name'] + if bundle_name == name: + return bundle + time.sleep(5) + return None + + +@pytest.fixture(scope='module', autouse='True') +def create_client(request): + if CLUSTER_NAME == '': + assert False, 'no cluster is provided, cannot run tests for fleet' + client = get_admin_client_v1() + namespace['client'] = client + res = client.list_management_cattle_io_cluster() + for cluster in res.data: + if cluster['spec']['displayName'] == CLUSTER_NAME: + namespace['cluster'] = cluster + if namespace['cluster'] is None: + assert False, 'cannot find the target cluster' diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_monitoring_v2.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_monitoring_v2.py new file mode 100644 index 0000000..6496ef0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v1_api/test_monitoring_v2.py @@ -0,0 +1,142 @@ +from .common import * # NOQA +import pytest +import requests +import semver + +namespace = {'client': None, + 'cluster': None, + 'rancher_catalog': None, + 'project': None} +m_chart_name = 'rancher-monitoring' +m_version = os.environ.get('RANCHER_MONITORING_V2_VERSION', None) +m_app = 'cattle-monitoring-system/rancher-monitoring' +m_crd = 'cattle-monitoring-system/rancher-monitoring-crd' +m_namespace = "cattle-monitoring-system" + + +def test_install_monitoring_v2(): + install_monitoring() + + +def install_monitoring(): + client = namespace['client'] + rancher_catalog = namespace['rancher_catalog'] + # install the monitoring v2 app into the new project + project_id = namespace["project"]["id"] + cluster_id = namespace["cluster"]["id"] + cluster_name = namespace["cluster"]["spec"]["displayName"] + values = read_json_from_resource_dir("monitoring_v2_values.json") + values["projectId"] = project_id + for chart in values["charts"]: + chart["version"] = m_version + chart["projectId"] = project_id + chart["values"]["global"]["cattle"]["clusterId"] = cluster_id + chart["values"]["global"]["cattle"]["clusterName"] = cluster_name + client.action(rancher_catalog, "install", values) + # wait 2 minutes for the app to be fully deployed + time.sleep(120) + # check the app rancher-monitoring-crd first then rancher-monitoring + wait_for( + lambda: client.by_id_catalog_cattle_io_app(m_crd).status.summary.state == "deployed", + timeout_message="time out waiting for app to be ready") + wait_for( + lambda: client.by_id_catalog_cattle_io_app(m_app).status.summary.state == "deployed", + timeout_message="time out waiting for app to be ready") + + +def uninstall_monitoring(): + client = namespace['client'] + # firstly, uninstall the monitoring app + app = client.by_id_catalog_cattle_io_app(m_app) + if app is not None: + client.action(app, "uninstall") + wait_for( + lambda: client.by_id_catalog_cattle_io_app(m_app) is None, + timeout_message="Timeout waiting for uninstalling monitoring") + # then, clean up the secrets left in the namespace + res = client.list_secret() + if "data" in res.keys(): + for item in res.get("data"): + if m_namespace in item['id']: + client.delete(item) + # then, the crd app + app = client.by_id_catalog_cattle_io_app(m_crd) + if app is not None: + client.action(app, "uninstall") + wait_for( + lambda: client.by_id_catalog_cattle_io_app(m_crd) is None, + timeout_message="Timeout waiting for uninstalling monitoring crd") + # finally, the namespace + ns = client.by_id_namespace(m_namespace) + if ns is not None: + client.delete(ns) + wait_for( + lambda: client.by_id_namespace(m_namespace) is None, + timeout_message="Timeout waiting for deleting the namespace") + + +def check_monitoring_exist(): + client = namespace['client'] + ns = client.by_id_namespace(m_namespace) + app = client.by_id_catalog_cattle_io_app(m_app) + crd = client.by_id_catalog_cattle_io_app(m_crd) + + ns_exist = False if ns is None else True + app_deployed = False if app is None else True + crd_app_deployed = False if crd is None else True + return ns_exist or app_deployed or crd_app_deployed + + +def get_chart_latest_version(catalog, chart_name): + headers = {"Accept": "application/json", + "Authorization": "Bearer " + USER_TOKEN} + url = catalog["links"]["index"] + response = requests.get(url=url, verify=False, headers=headers) + assert response.status_code == 200, \ + "failed to get the response from {}".format(url) + assert response.content is not None, \ + "no chart is returned from {}".format(url) + res = json.loads(response.content) + assert chart_name in res["entries"].keys(), \ + "failed to find the chart {} from the chart repo".format(chart_name) + charts = res['entries'][chart_name] + versions = [] + for chart in charts: + versions.append(chart["version"]) + latest = versions[0] + for version in versions: + if semver.compare(latest, version) < 0: + latest = version + return latest + + +@pytest.fixture(scope='module', autouse="True") +def create_client(request): + client = get_cluster_client_for_token_v1() + admin_client = get_admin_client_v1() + cluster = get_cluster_by_name(admin_client, CLUSTER_NAME) + namespace["client"] = client + namespace["cluster"] = cluster + rancher_catalog = \ + client.by_id_catalog_cattle_io_clusterrepo(id="rancher-charts") + if rancher_catalog is None: + assert False, "rancher-charts is not available" + namespace["rancher_catalog"] = rancher_catalog + # set the monitoring chart version the latest if it is not provided + global m_version + if m_version is None: + m_version = \ + get_chart_latest_version(rancher_catalog, m_chart_name) + print("chart version is not provided, " + "get chart version from repo: {}".format(m_version)) + + project = create_project(cluster, random_name()) + namespace["project"] = project + if check_monitoring_exist() is True: + uninstall_monitoring() + + def fin(): + uninstall_monitoring() + client.delete(namespace["project"]) + + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/.gitignore b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/.gitignore new file mode 100644 index 0000000..ed930b4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/.gitignore @@ -0,0 +1,2 @@ +k8s_kube_config +*_kubeconfig diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile new file mode 100644 index 0000000..bba75b8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile @@ -0,0 +1,136 @@ +// Job Params +// Requires: PYTEST_OPTIONS, CATTLE_TEST_URL, ADMIN_TOKEN +// Optional: AWS_SSH_PEM_KEY, AWS_SSH_KEY_NAME, DEBUG + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + + def setupResultsOut = "setup-results.xml" + def testResultsOut = "results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + if (it.value && it.value.trim() != "") { + paramsMap << "$it.key=$it.value" + } + } + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_PRIVATE_CA_CERT', variable: 'RANCHER_PRIVATE_CA_CERT'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DB_PASSWORD', variable: 'RANCHER_DB_PASSWORD'), + string(credentialsId: 'RANCHER_RHEL_PASSWORD', variable: 'RANCHER_RHEL_PASSWORD'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ARM_SUBSCRIPTION_ID', variable: 'ARM_SUBSCRIPTION_ID'), + string(credentialsId: 'ARM_TENANT_ID', variable: 'ARM_TENANT_ID'), + string(credentialsId: 'ARM_CLIENT_ID', variable: 'ARM_CLIENT_ID'), + string(credentialsId: 'ARM_CLIENT_SECRET', variable: 'ARM_CLIENT_SECRET'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY") + ]) { + + withEnv(paramsMap) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + try { + stage('Run Validation Tests') { + try { + sh "docker run --name ${testContainer} --env-file .env " + + "${imageName} /bin/bash -c \'pytest -v -s --junit-xml=${testResultsOut} ${PYTEST_OPTIONS} ${testsDir}\'" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + + stage('Test Report') { + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } catch(err){ + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } + } + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test new file mode 100644 index 0000000..11b4d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test @@ -0,0 +1,206 @@ +#!groovy + +node { + def rootPath = "/src/rancher-validation/" + + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def deleteContainer = "${job_name}${env.BUILD_NUMBER}_delete" + + def deployPytestOptions = "-k test_deploy_rancher_server" + def deletePytestOptions = "-k test_delete_rancher_server" + + def setupResultsOut = "setup-results.xml" + def testResultsOut = "results.xml" + def deleteResultsOut = "delete-results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_LINODE_ACCESSKEY', variable: "RANCHER_LINODE_ACCESSKEY")]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher Server') { + try { + if (!env.CATTLE_TEST_URL || !env.ADMIN_TOKEN || !env.USER_TOKEN || + (env.CATTLE_TEST_URL == "" && env.ADMIN_TOKEN == "" && env.USER_TOKEN == "")) { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + RANCHER_DEPLOYED = true + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + + } + else { + echo "User Provided Rancher Server" + RANCHER_DEPLOYED = false + } + } + catch(err) { + echo "Error: " + err + RANCHER_DEPLOYED = false + } + } + + stage('Run Validation Tests') { + try { + // run tests + def clusterName="${env.RANCHER_CLUSTER_NAME}" + if (RANCHER_DEPLOYED) { + clusterName="${env.CLUSTER_NAME}" + } + sh "docker run --name ${testContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} " + + "&& export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} "+ + "&& export RANCHER_CLUSTER_NAME=${clusterName} " + "&& pytest -v -s --junit-xml=${testResultsOut} " + + "${PYTEST_OPTIONS} ${testsDir}\'" + } catch(err) { + echo "Error: " + err + echo 'Test run had failures. Collecting results...' + } + } + } catch(err) { + echo "Error: " + err + } finally { + stage('Delete Rancher Server') { + try { + if (env.RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) { + sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} && "+ + "pytest -v -s --junit-xml=${deleteResultsOut} " + + "${deletePytestOptions} ${testsDir}\'" + sh "docker cp ${deleteContainer}:${rootPath}${deleteResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${deleteResultsOut}"]) + } + else { + echo "Rancher server not deployed, skipping delete." + } + } catch(err) { + echo "Error: " + err + currentBuild.result = 'FAILURE' + } + } + + stage('Test Report') { + // copy and archive test results + if (RANCHER_DEPLOYED) { + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + + } + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + + } + if (RANCHER_DEPLOYED) { + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + } + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + + if (env.RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) { + sh "docker stop ${deleteContainer}" + sh "docker rm -v ${deleteContainer}" + } + + sh "docker rmi ${imageName}" + } // finally + } // dir + } // creds + } //env + } // folder properties + } // wrap +} // node \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_ontag b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_ontag new file mode 100644 index 0000000..d897495 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_ontag @@ -0,0 +1,144 @@ +#!groovy + +// RANCHER_VERSION resolution is first via Jenkins Build Parameter RANCHER_VERSION fed in from console, +// then from $DOCKER_TRIGGER_TAG which is sourced from the Docker Hub Jenkins plugin webhook. +def rancher_version() { + try { if ('' != RANCHER_VERSION) { return RANCHER_VERSION } } + catch (MissingPropertyException e) {} + + try { return DOCKER_TRIGGER_TAG } + catch (MissingPropertyException e) {} + + echo 'Neither RANCHER_VERSION nor DOCKER_TRIGGER_TAG have been specified!' + error() +} + +def lastBuildResult() { + def previous_build = currentBuild.getPreviousBuild() + if ( null != previous_build ) { return previous_build.result } else { return 'UKNOWN' } +} + +def via_webhook() { + try { + def foo = DOCKER_TRIGGER_TAG + return true + } catch(MissingPropertyException) { + return false + } +} + +// Filter out Docker Hub tags like 'latest', 'master', 'enterprise'. +// Just want things like v1.2* +def rancher_version = rancher_version() +def String rancher_version_regex = "^v[\\d]\\.[\\d]\\.[\\d][\\-rc\\d]+\$" + +if ( true == via_webhook() && (!(rancher_version ==~ rancher_version_regex)) ) { + println("Received RANCHER_VERSION \'${rancher_version}\' via webhook which does not match regex \'${rancher_version_regex}\'.") + println("** This will **not** result in a pipeline run.") + currentBuild.result = lastBuildResult() +} else { + def branch = "v2.1" + if (rancher_version.startsWith("v2.2") || rancher_version == "master" ) { + branch = "release/v2.8" + } + try { + node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + + def deployPytestOptions = "-k test_deploy_rancher_server" + + def setupResultsOut = "setup-results.xml" + def testResultsOut = "results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + try { + stage('Run Validation Tests') { + try { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_SERVER_VERSION=${rancher_version} && " + + "pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + + // run tests + sh "docker run --name ${testContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} " + + "&& export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} " + + "&& pytest -v -s --junit-xml=${testResultsOut} " + + "${PYTEST_OPTIONS} ${testsDir}\'" + } catch(err) { + echo "Error: " + err + echo 'Test run had failures. Collecting results...' + } + } + + stage('Test Report') { + // copy and archive test results + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + + sh "docker rm -v ${setupContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } catch(err){ + sh "docker stop ${setupContainer}" + sh "docker stop ${testContainer}" + + sh "docker rm -v ${setupContainer}" + sh "docker rm -v ${testContainer}" + + sh "docker rmi ${imageName}" + } + } + } + } + } + } catch(err) { + echo "Error: " + err + error() + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_support_matrix b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_support_matrix new file mode 100644 index 0000000..263dbf9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_deploy_and_test_support_matrix @@ -0,0 +1,249 @@ +#!groovy + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def clusterSetupContainer = "${job_name}${env.BUILD_NUMBER}_cluster_setup" + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + def deleteContainer = "${job_name}${env.BUILD_NUMBER}_delete" + + def deployPytestOptions = "-k test_deploy_rancher_server" + def deletePytestOptions = "-k test_delete_rancher_server" + def deployClusterPytestOptions = "-k test_deploy_clusters" + + def setupResultsOut = "setup-results.xml" + def clusterSetupResultsOut = "cluster-setup-results.xml" + def deleteResultsOut = "delete-results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY')]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher Server') { + try { + if (!env.CATTLE_TEST_URL || !env.ADMIN_TOKEN || !env.USER_TOKEN || + (env.CATTLE_TEST_URL == "" && env.ADMIN_TOKEN == "" && env.USER_TOKEN == "")) { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + RANCHER_DEPLOYED = true + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } + else { + echo "User Provided Rancher Server" + RANCHER_DEPLOYED = false + } + + } catch(err) { + echo "Error: " + err + RANCHER_DEPLOYED = false + } + } + + stage('Deploy Clusters') { + try { + if (!env.RANCHER_CLUSTER_NAMES || env.RANCHER_CLUSTER_NAMES == "") { + // deploy clusters of different versions + sh "docker run --name ${clusterSetupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} " + + "&& export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} "+ + "&& pytest -v -s --junit-xml=${clusterSetupResultsOut} " + + "${deployClusterPytestOptions} ${testsDir}\'" + + CLUSTERS_CREATED = true + // copy file containing RANCHER_CLUSTER_NAMES and load into environment variables + sh "docker cp ${clusterSetupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } + else { + echo "Given clusters: ${env.RANCHER_CLUSTER_NAMES}" + CLUSTERS_CREATED = false + } + } catch(err) { + echo "Error: " + err + CLUSTERS_CREATED = true + sh "docker cp ${clusterSetupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + currentBuild.result = 'UNSTABLE' + } + } + + stage('Run Validation Tests in Parallel') { + try { + jobs = [:] + cluster_arr = env.RANCHER_CLUSTER_NAMES.split(",") + cluster_count = cluster_arr.size() + if (!env.RANCHER_UPGRADE_CHECK || env.RANCHER_UPGRADE_CHECK == "") { + RANCHER_UPGRADE_CHECK = "preupgrade" + } + if (!env.RANCHER_VALIDATE_RESOURCES_PREFIX || env.RANCHER_VALIDATE_RESOURCES_PREFIX == "") { + RANCHER_VALIDATE_RESOURCES_PREFIX = "mystep1" + } + if (!env.RANCHER_CREATE_RESOURCES_PREFIX || env.RANCHER_CREATE_RESOURCES_PREFIX == "") { + RANCHER_CREATE_RESOURCES_PREFIX = "mystep1" + } + for (int i = 0; i < cluster_count; i++) { + def params = [ + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_CLUSTER_NAME', value: "${cluster_arr[i]}"), + string(name: 'PYTEST_OPTIONS', value: "${PYTEST_OPTIONS}"), + string(name: 'RANCHER_UPGRADE_CHECK', value: "${RANCHER_UPGRADE_CHECK}"), + string(name: 'RANCHER_VALIDATE_RESOURCES_PREFIX', value: "${RANCHER_VALIDATE_RESOURCES_PREFIX}"), + string(name: 'RANCHER_CREATE_RESOURCES_PREFIX', value: "${RANCHER_CREATE_RESOURCES_PREFIX}"), + ] + echo "Params are: ${params}" + jobs["test-${i}"] = { build job: 'rancher-v3_needs_cluster', parameters: params } + } + parallel jobs + } catch(err) { + echo "Error: " + err + currentBuild.result = 'UNSTABLE' + } + } + + } catch(err) { + echo "Error: " + err + } finally { + stage('Delete Rancher Server') { + try { + if (RANCHER_DEPLOYED && env.RANCHER_DELETE_SERVER && env.RANCHER_DELETE_SERVER.toLowerCase() == "true") { + sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} && "+ + "pytest -v -s --junit-xml=${deleteResultsOut} " + + "${deletePytestOptions} ${testsDir}\'" + sh "docker cp ${deleteContainer}:${rootPath}${deleteResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${deleteResultsOut}"]) + } + else { + echo "Skipping Rancher server deletion." + } + } catch(err) { + echo "Error: " + err + currentBuild.result = 'FAILURE' + } + } + + stage('Test Report') { + // copy and archive test results + if (RANCHER_DEPLOYED) { + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + } + + if (CLUSTERS_CREATED) { + sh "docker cp ${clusterSetupContainer}:${rootPath}${clusterSetupResultsOut} ." + sh "docker stop ${clusterSetupContainer}" + sh "docker rm -v ${clusterSetupContainer}" + step([$class: 'JUnitResultArchiver', testResults: "**/${clusterSetupResultsOut}"]) + } + } + + if (RANCHER_DEPLOYED && env.RANCHER_DELETE_SERVER && env.RANCHER_DELETE_SERVER.toLowerCase() == "true") { + sh "docker stop ${deleteContainer}" + sh "docker rm -v ${deleteContainer}" + } + + sh "docker rmi ${imageName}" + } // finally + } // dir + } // creds + } // env + } // folder properties + } // wrap +} // node diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests new file mode 100644 index 0000000..f49daec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests @@ -0,0 +1,124 @@ +jobs = [:] +def job_name = "${JOB_NAME}" +if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] +} + +def deleteContainer = "${job_name}${BUILD_NUMBER}_delete" +def deletePytestOptions = "-k test_delete_rancher_server" +def deleteResultsOut = "delete-results.xml" +def testsDir = "tests/v3_api/" +def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" +def envFile = ".env" +def RANCHER_DEPLOYED = false + +def branch = "release/v2.8" +if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" +} + +node { + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD') ]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + try { + try { + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher server') { + sh "docker run --name ${job_name}${BUILD_NUMBER} -t --env-file .env ${imageName} /bin/bash " + + "-c \'export RANCHER_SERVER_VERSION=${rancher_version} && " + + "pytest -v -s --junit-xml=setup.xml -k test_deploy_rancher_server tests/v3_api/\'" + + sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/tests/v3_api/rancher_env.config ." + load "rancher_env.config" + + RANCHER_DEPLOYED = true + } + } + } catch (err) { + RANCHER_DEPLOYED = false + echo "Error: " + err + currentBuild.result = 'FAILURE' + error() + } + + stage('Run provisioning tests') { + params = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), string(name: 'BRANCH', value: branch) ] + + jobs["custom"] = { build job: 'rancher-v3_custom_provisioning', parameters: params} + jobs["do"] = { build job: 'rancher-v3_do_provisioning', parameters: params } + jobs["ec2"] = { build job: 'rancher-v3_ec2_provisioning', parameters: params } + jobs["az"] = { build job: 'rancher-v3_az_provisioning', parameters: params } + + parallel jobs + } + } catch(err) { + echo "Error: " + err + } finally { + stage('Delete Rancher Server') { + try { + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) { + echo "Sleeping for ${RANCHER_DELETE_DELAY} hours before deleting Rancher server" + sleep(time: RANCHER_DELETE_DELAY.toInteger(), unit: "HOURS") + sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && export USER_TOKEN=${USER_TOKEN} &&" + + "pytest -v -s --junit-xml=${deleteResultsOut} " + + "${deletePytestOptions} ${testsDir}\'" + } + else { + echo "Rancher server not deployed, skipping delete." + } + } catch(err) { + echo "Error: " + err + currentBuild.result = 'FAILURE' + } + } + + stage('Test Report') { + sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/setup.xml ." + step([$class: 'JUnitResultArchiver', testResults: '**/setup.xml']) + } + + stage('Cleanup') { + sh "docker stop ${job_name}${BUILD_NUMBER}" + sh "docker rm -v ${job_name}${BUILD_NUMBER}" + sh "docker rmi ${imageName}" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests_ontag b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests_ontag new file mode 100644 index 0000000..b3485ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_provisioning_tests_ontag @@ -0,0 +1,148 @@ +#!groovy + +jobs = [:] +def job_name = "${JOB_NAME}" +if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] +} + +def deleteContainer = "${job_name}${BUILD_NUMBER}_delete" +def deletePytestOptions = "-k test_delete_rancher_server" +def deleteResultsOut = "delete-results.xml" +def testsDir = "tests/v3_api/" +def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" +def envFile = ".env" +def RANCHER_DEPLOYED = false + +// RANCHER_VERSION resolution is first via Jenkins Build Parameter RANCHER_VERSION fed in from console, +// then from $DOCKER_TRIGGER_TAG which is sourced from the Docker Hub Jenkins plugin webhook. +def rancher_version() { + try { if ('' != RANCHER_VERSION) { return RANCHER_VERSION } } + catch (MissingPropertyException e) {} + + try { return DOCKER_TRIGGER_TAG } + catch (MissingPropertyException e) {} + + echo 'Neither RANCHER_VERSION nor DOCKER_TRIGGER_TAG have been specified!' + error() +} + +def lastBuildResult() { + def previous_build = currentBuild.getPreviousBuild() + if ( null != previous_build ) { return previous_build.result } else { return 'UNKNOWN' } +} + +def via_webhook() { + try { + def foo = DOCKER_TRIGGER_TAG + return true + } catch(MissingPropertyException) { + return false + } +} + +// Filter out Docker Hub tags like 'latest', 'master', 'enterprise'. +// Just want things like v1.2* +def rancher_version = rancher_version() +def String rancher_version_regex = "^v[\\d]\\.[\\d]\\.[\\d][\\-rc\\d]+\$" + +if ( true == via_webhook() && (!(rancher_version ==~ rancher_version_regex)) ) { + println("Received RANCHER_VERSION \'${rancher_version}\' via webhook which does not match regex \'${rancher_version_regex}\'.") + println("** This will **not** result in a pipeline run.") + currentBuild.result = lastBuildResult() +} else { + def branch = "v2.1" + if (rancher_version.startsWith("v2.2") || rancher_version == "master" ) { + branch = "release/v2.8" + } + node { + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + try { + try { + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher server') { + sh "docker run --name ${job_name}${BUILD_NUMBER} -t --env-file .env ${imageName} /bin/bash " + + "-c \'export RANCHER_SERVER_VERSION=${rancher_version} && pytest -v -s --junit-xml=setup.xml -k test_deploy_rancher_server tests/v3_api/\'" + sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/tests/v3_api/rancher_env.config ." + load "rancher_env.config" + RANCHER_DEPLOYED = true + } + } catch (err) { + RANCHER_DEPLOYED = false + echo "Error: " + err + currentBuild.result = 'FAILURE' + error() + } + + stage('Run provisioning tests') { + params = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), string(name: 'BRANCH', value: branch) ] + + jobs["custom"] = { build job: 'rancher-v3_test_custom_cluster', parameters: params} + jobs["do"] = { build job: 'rancher-v3_test_do_cluster', parameters: params } + jobs["ec2"] = { build job: 'rancher-v3_test_ec2_cluster', parameters: params } + jobs["az"] = { build job: 'rancher-v3_test_az_cluster', parameters: params } + + parallel jobs + } + } catch(err) { + echo "Error: " + err + } finally { + stage('Delete Rancher Server') { + try { + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && RANCHER_DEPLOYED) { + echo "Sleeping for ${RANCHER_DELETE_DELAY} hours before deleting Rancher server" + sleep(time: RANCHER_DELETE_DELAY.toInteger(), unit: "HOURS") + sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && export USER_TOKEN=${USER_TOKEN} && "+ + "pytest -v -s --junit-xml=${deleteResultsOut} " + + "${deletePytestOptions} ${testsDir}\'" + } + else { + echo "Rancher server not deployed, skipping delete." + } + } catch(err) { + echo "Error: " + err + currentBuild.result = 'FAILURE' + } + } + + stage('Test Report') { + sh "docker cp ${job_name}${BUILD_NUMBER}:/src/rancher-validation/setup.xml ." + step([$class: 'JUnitResultArchiver', testResults: '**/setup.xml']) + } + + stage('Cleanup') { + sh "docker stop ${job_name}${BUILD_NUMBER}" + sh "docker rm -v ${job_name}${BUILD_NUMBER}" + sh "docker rmi ${imageName}" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_vpn b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_vpn new file mode 100644 index 0000000..02fb5d1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/Jenkinsfile_vpn @@ -0,0 +1,139 @@ +// Job Params +// Requires: PYTEST_OPTIONS, CATTLE_TEST_URL, ADMIN_TOKEN +// Optional: AWS_SSH_PEM_KEY, AWS_SSH_KEY_NAME, DEBUG + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + + def setupResultsOut = "setup-results.xml" + def testResultsOut = "results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL'), + string(credentialsId: 'RANCHER_VALID_TLS_CERT', variable: 'RANCHER_VALID_TLS_CERT'), + string(credentialsId: 'RANCHER_VALID_TLS_KEY', variable: 'RANCHER_VALID_TLS_KEY'), + string(credentialsId: 'RANCHER_BYO_TLS_CERT', variable: 'RANCHER_BYO_TLS_CERT'), + string(credentialsId: 'RANCHER_BYO_TLS_KEY', variable: 'RANCHER_BYO_TLS_KEY'), + string(credentialsId: 'RANCHER_PRIVATE_CA_CERT', variable: 'RANCHER_PRIVATE_CA_CERT'), + string(credentialsId: 'RANCHER_AUTH_USER_PASSWORD', variable: 'RANCHER_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_CA_CERTIFICATE', variable: 'RANCHER_CA_CERTIFICATE'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_AD_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_USER_SEARCH_BASE', variable: 'RANCHER_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_DB_PASSWORD', variable: 'RANCHER_DB_PASSWORD'), + string(credentialsId: 'RANCHER_RHEL_PASSWORD', variable: 'RANCHER_RHEL_PASSWORD'), + string(credentialsId: 'RANCHER_DEFAULT_LOGIN_DOMAIN', variable: 'RANCHER_DEFAULT_LOGIN_DOMAIN'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_USER_SEARCH_BASE', variable: 'RANCHER_OPENLDAP_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD', variable: 'RANCHER_OPENLDAP_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME'), + string(credentialsId: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD', variable: 'RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_USER_SEARCH_BASE', variable: 'RANCHER_FREEIPA_USER_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE', variable: 'RANCHER_FREEIPA_GROUP_SEARCH_BASE'), + string(credentialsId: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD', variable: 'RANCHER_FREEIPA_AUTH_USER_PASSWORD'), + string(credentialsId: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS', variable: 'RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS'), + string(credentialsId: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD', variable: 'RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD'), + string(credentialsId: 'ARM_SUBSCRIPTION_ID', variable: 'ARM_SUBSCRIPTION_ID'), + string(credentialsId: 'ARM_TENANT_ID', variable: 'ARM_TENANT_ID'), + string(credentialsId: 'ARM_CLIENT_ID', variable: 'ARM_CLIENT_ID'), + string(credentialsId: 'ARM_CLIENT_SECRET', variable: 'ARM_CLIENT_SECRET'), + string(credentialsId: 'EXTERNAL_ENCODED_VPN', variable: 'EXTERNAL_ENCODED_VPN'), + string(credentialsId: 'VPN_ENCODED_LOGIN', variable: 'VPN_ENCODED_LOGIN') + ]) { + + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + def runArgs = "" + if (env.EXTERNAL_ENCODED_VPN) { + runArgs = runArgs + "openvpn --daemon --config external.ovpn && sleep 10 && " + } + runArgs = runArgs + "pytest -v -s --junit-xml=${testResultsOut} ${PYTEST_OPTIONS} ${testsDir}" + try { + stage('Run Validation Tests') { + try { + sh "docker run --name ${testContainer} --env-file .env --privileged " + + "${imageName} /bin/bash -c \'${runArgs}\'" + } catch(err) { + echo 'Test run had failures. Collecting results...' + } + } + + stage('Test Report') { + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } catch(err){ + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } + } + } + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/README.md b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/README.md new file mode 100644 index 0000000..77c8ed6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/README.md @@ -0,0 +1,47 @@ +# how to write RBAC-related testing functions +A set of global variables and functions are introduced to make it easy +to write tests for rancher's features around RBAC. + +When the testing environment is initializing, the following resources are created: +- a new project that new users and user roles are bound to +- a namespace in that project +- five standard users +- another unshared project that no of those users are bound to +- a namespace and a workload in this project + +Those users are assigned to different roles: + - cluster owner + - cluster member + - project owner + - project member + - project read-only member + +The following functions are provided: +- to get a specific user: `rbac_get_user_by_role(role_template_id)` +- to get a specific user's token: `rbac_get_user_token_by_role(role_template_id)` +- to get the project: `rbac_get_project()` +- to get the namespace in the project: `rbac_get_namespace()` +- to get the unshared proejct: `rbac_get_unshared_project()` +- to get the unshared namespace: `rbac_get_unshared_ns()` +- to get the unshared workload: `rbac_get_unshared_workload()` + + +The following are some functions using the above resources in `test_workload.py`: +- test_wl_rbac_cluster_owner +- test_wl_rbac_cluster_member +- test_wl_rbac_project_member + + +# how to use the new fixture: `remove_resource` +This fixture handles the deletion of any resource that is created in the +function. Here is an example: +``` +def test_wl_rbac_project_member(remove_resource): + ... + workload = p_client.create_workload(name=name, containers=con, namespaceId=ns.id) + remove_resource(workload) + ... +``` +First, we need to pass the fixture as an argument to the function to registry it to the scope of the function; +second, we need to call this fixture after creating a new resource, in this example it is a workload. +In such way, the workload will be removed automatically when this test finishes no matter it succeeds or fails. diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/__init__.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_common.py new file mode 100644 index 0000000..0916719 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_common.py @@ -0,0 +1,100 @@ +import os +import logging +import sys +import time + +from .common import run_command, run_command_with_stderr + +logging.basicConfig(stream=sys.stdout, + level=os.environ.get("LOGLEVEL", "INFO"), + format='%(asctime)s - %(filename)s:%(funcName)s' + ':%(lineno)d - [%(levelname)5s]: %(message)s', + datefmt="%H:%M:%S") +DEFAULT_TIMEOUT = 60 + + +class BaseCli: + log = logging.getLogger(__name__) + DEFAULT_CONTEXT = os.environ.get('DEFAULT_CONTEXT', None) + + @classmethod + def run_command(cls, command, expect_error=False): + command = "rancherctl {}".format(command) + cls.log.debug("run cmd:\t%s", command) + if expect_error: + result = run_command_with_stderr(command, log_out=False) + else: + result = run_command(command, log_out=False) + cls.log.debug("returns:\t%s", result) + return result + + def set_log_level(self, level): + self.log.setLevel(level) + + def login(self, url, token, **kwargs): + context = kwargs.get("context", self.DEFAULT_CONTEXT) + if context is None: + raise ValueError("No context supplied for rancher login!") + cmd = "login {} --token {} --context {} --skip-verify".format( + url, token, context) + self.run_command(cmd, expect_error=True) + + def switch_context(self, project_id): + self.run_command("context switch {}".format(project_id), + expect_error=True) + + def get_context(self): + result = self.run_command("context current") + cluster_name = result[8:result.index(" ")].strip() + project_name = result[result.index("Project:") + 8:].strip() + return cluster_name, project_name + + def get_cluster_by_name(self, name): + for c in self.get_clusters(): + if c["name"] == name: + return c + + def get_current_cluster(self): + for c in self.get_clusters(): + if c["current"]: + return c + + def get_clusters(self): + result = self.run_command("clusters ls --format '{{.Cluster.ID}}" + "|{{.Cluster.Name}}|{{.Current}}|{{.Cluster.UUID}}'") + clusters = [] + for c in result.splitlines(): + c = c.split("|") + cluster = { + "id": c[0], + "name": c[1], + "current": c[2] == "*", + "uuid": c[3] + } + clusters.append(cluster) + return clusters + + def inspect(self, resource_type, resource_id, **kwargs): + resource_format = kwargs.get("format", "{{.id}}") + result = self.run_command("inspect --type {} --format '{}' {}".format( + resource_type, resource_format, resource_id)) + return result.strip() + + def ps(self): + return self.run_command( + "ps --format '{{.NameSpace}}|{{.Name}}|{{.Image}}|{{.Scale}}'") + + def kubectl(self, cmd): + return self.run_command("kubectl {}".format(cmd)) + + def wait_for_ready(self, command, val_to_check, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + condition_func = kwargs.get("condition_func", + lambda val, l: val in l.splitlines()) + done = False + start_time = time.time() + while not done and time.time() - start_time < timeout: + result = self.run_command(command) + if condition_func(val_to_check, result): + done = True + return done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_objects.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_objects.py new file mode 100644 index 0000000..e2d5df2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/cli_objects.py @@ -0,0 +1,428 @@ +import os +import time +import subprocess +from pathlib import Path + +from .common import get_user_client, random_test_name, \ + DATA_SUBDIR, run_command, random_str +from .cli_common import DEFAULT_TIMEOUT, BaseCli + + +class RancherCli(BaseCli): + def __init__(self, url, token, context): + self.login(url, token, context=context) + self.projects = ProjectCli() + self.apps = AppCli() + self.mcapps = MultiClusterAppCli() + self.catalogs = CatalogCli() + self.clusters = ClusterCli() + self.nodes = NodeCli() + self.default_project = self.projects.create_project() + self.default_namespace = self.projects.create_namespace( + random_test_name("testdefault")) + BaseCli.DEFAULT_CONTEXT = self.default_project["id"] + self.switch_context(self.DEFAULT_CONTEXT) + + def cleanup(self): + self.log.info("Cleaning up created test project: {}".format( + self.default_project["name"])) + self.switch_context(self.default_project["id"]) + self.run_command("project delete {}".format( + self.default_project["id"]), expect_error=True) + + +class ProjectCli(BaseCli): + def create_project(self, name=None, + cluster_id=None, use_context=True): + if name is None: + name = random_test_name("ptest") + if cluster_id is None: + cluster = self.get_context()[0] + cluster_id = self.get_cluster_by_name(cluster)["id"] + self.run_command("projects create --cluster {} {}".format(cluster_id, + name)) + project = None + for p in self.get_current_projects(): + if p["name"] == name: + project = p + self.log.info("Project '%s' created successfully " + "in cluster '%s'", name, cluster_id) + break + if project is None: + self.log.error("Failed to create project '%s' " + "in cluster '%s'", name, cluster_id) + return project + + if use_context: + self.log.info("Switching context to newly created project: " + "%s", name) + for p in self.get_current_projects(): + if p["name"] == name: + self.switch_context(p["id"]) + break + return project + + def delete_project(self, name): + self.run_command("projects rm {}".format(name)) + + @classmethod + def get_current_projects(cls): + """This uses the Rancher Python Client to retrieve the current projects + as there is not a CLI way to do this without passing stdin at the time + of creation (2/13/2020, Rancher v2.3.5). + Returns array of dictionaries containing id, name, clusterid, & uuid""" + client = get_user_client() + projects = client.list_project() + current_projects = [] + for project in projects: + p = { + "id": project["id"], + "name": project["name"], + "clusterId": project["clusterId"], + "state": project["state"], + "uuid": project["uuid"] + } + current_projects.append(p) + return current_projects + + def create_namespace(self, name=None): + if name is None: + name = random_test_name("nstest") + self.run_command("namespace create {}".format(name)) + return name + + def delete_namespace(self, name): + self.run_command("namespace delete {}".format(name)) + + self.log.info("Waiting for the namespace to be deleted") + deleted = self.wait_for_ready("namespace ls -q", name, condition_func= + lambda val, l: val not in l.splitlines()) + return deleted + + def get_namespaces(self): + namespaces = self.run_command("namespace ls --format " + "'{{.Namespace.Name}}" + "|{{.Namespace.State}}'") + return namespaces.splitlines() + + def move_namespace(self, name, project_id): + self.run_command("namespace move {} {}".format(name, project_id)) + + +class AppCli(BaseCli): + def install(self, app_name, namespace, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + version = kwargs.get("version", None) + context = kwargs.get("context", self.DEFAULT_CONTEXT) + values = kwargs.get("values", None) + cmd = "apps install {} --no-prompt -n {}".format(app_name, namespace) + if version is not None: + cmd = cmd + " --version {}".format(version) + if values is not None: + cmd = cmd + " --values {}".format(values) + + self.switch_context(context) + app = self.run_command(cmd) + app = app.split('"')[1].split(" ")[2] + self.log.info("App is: {}".format(app)) + + self.log.info("Waiting for the app to be created") + # Wait for app to be "deploying" + self.wait_for_ready("apps ls --format '{{.App.Name}} {{.App.State}}' " + "| grep deploying | awk '{print $1}'", app, + timeout=timeout) + # Wait for app to be "active" + created = self.wait_for_ready("apps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app, + timeout=timeout) + if not created: + self.log.warn("Failed to install app {} within timeout of {} " + "seconds.".format(app_name, timeout)) + return self.get(app) + + def get(self, app_name): + app = self.run_command("apps ls --format '{{.App.Name}}|{{.App.ID}}" + "|{{.App.State}}|{{.Version}}|{{.Template}}' " + "| grep " + app_name) + app = app.split("|") + return {"name": app[0], "id": app[1], + "state": app[2], "version": app[3], "template": app[4]} + + def upgrade(self, app, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + version = kwargs.get("version", None) + if version is None: + version = self.run_command("apps st {} | tail -1".format( + app["template"])) + self.run_command("apps upgrade {} {}".format(app["name"], version)) + + self.log.info("Waiting for the app to be upgraded") + # Wait for app to be "deploying" + self.wait_for_ready("apps ls --format '{{.App.Name}} {{.App.State}}' " + "| grep deploying | awk '{print $1}'", app["name"]) + # Wait for app to be "active" + upgraded = self.wait_for_ready("apps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app["name"]) + if not upgraded: + self.log.warn("Failed to upgrade app {} within timeout of {} " + "seconds.".format(app["name"], timeout)) + return self.get(app["name"]) + + def rollback(self, app, desired_version, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + # Retrieve non-current versions that match desired version + revision = self.run_command( + "apps rollback -r %s | grep %s | awk '{print $1}'" % + (app["name"], desired_version)).splitlines()[0] + + self.run_command("apps rollback {} {}".format(app["name"], revision)) + + self.log.info("Waiting for the app to be rolled back") + # Wait for app to be "deploying" + self.wait_for_ready("apps ls --format '{{.App.Name}} {{.App.State}}' " + "| grep deploying | awk '{print $1}'", app["name"]) + # Wait for app to be "active" + rolled_back = self.wait_for_ready("apps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app["name"]) + if not rolled_back: + self.log.warn("Failed to rollback app {} within timeout of {} " + "seconds.".format(app["name"], timeout)) + return self.get(app["name"]) + + def delete(self, app, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + self.run_command("apps delete {}".format(app["name"])) + + self.log.info("Waiting for the app to be deleted") + deleted = self.wait_for_ready("apps ls -q", app["name"], + timeout=timeout, condition_func= + lambda val, l: val not in l.splitlines()) + return deleted + + def install_local_dir(self, catalog_url, branch, chart, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + context = kwargs.get("context", self.DEFAULT_CONTEXT) + version = kwargs.get("version", None) + current_dir = os.getcwd() + os.chdir(DATA_SUBDIR) + get_charts_cmd = \ + run_command("git clone -b {} {}".format(branch, catalog_url)) + time.sleep(5) + os.chdir("{}/integration-test-charts/charts/{}/{}". + format(DATA_SUBDIR, chart, version)) + app_name = random_str() + self.switch_context(context) + app = self.run_command("apps install . {}".format(app_name)) + app = app.split('"')[1].split(" ")[2] + self.log.info("App is: {}".format(app)) + self.log.info("Waiting for the app to be created") + self.wait_for_ready("apps ls --format '{{.App.Name}} {{.App.State}}' " + "| grep deploying | awk '{print $1}'", app, + timeout=timeout) + # Wait for app to be "active" + created = self.wait_for_ready("apps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app, + timeout=timeout) + if not created: + self.log.warn("Failed to install app {} within timeout of {} " + "seconds.".format(app_name, timeout)) + os.chdir(current_dir) + return self.get(app) + + +class MultiClusterAppCli(BaseCli): + def install(self, template_name, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + version = kwargs.get("version", None) + targets = kwargs.get("targets", [self.DEFAULT_CONTEXT]) + values = kwargs.get("values", None) + role = kwargs.get("role", "project-member") + cmd = "mcapps install {} --no-prompt --role {}".format(template_name, role) + for t in targets: + cmd += " --target {}".format(t) + if version is not None: + cmd += " --version {}".format(version) + if values is not None: + for k, v in values.items(): + cmd += " --set {}={}".format(k, v) + + app = self.run_command(cmd) + app = app.split('"')[1] + self.log.info("Multi-Cluster App is: {}".format(app)) + # Wait for multi-cluster app to be "deploying" + self.wait_for_ready("mcapps ls --format '{{.App.Name}} {{.App.State}}'" + " | grep deploying | awk '{print $1}'", + app, timeout=timeout) + # Wait for multi-cluster app to be "active" + self.log.info("Waiting for the multi-cluster app to be created") + created = self.wait_for_ready("mcapps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app, + timeout=timeout) + if not created: + self.log.warn("Failed to install multi-cluster app {} within " + "timeout of {} seconds.".format( + template_name, timeout)) + return self.get(app) + + def get(self, app_name): + app = self.run_command("mcapps ls --format '{{.App.Name}}|{{.App.ID}}" + "|{{.App.State}}|{{.Version}}" + "|{{.App.TemplateVersionID}}|" + "{{- range $key, $value := .App.Targets}}" + "{{$value.AppID}} {{$value.ProjectID}} " + "{{$value.State}};;{{- end}}' " + "| grep " + app_name) + app = app.split("|") + targets = [] + for t in app[5].split(";;")[:-1]: + t = t.split() + self.switch_context(t[1]) + t_app = AppCli.get(AppCli(), t[0]) + targets.append(t_app) + + revision = self.run_command("mcapps rollback -r %s | grep '*' | awk " + "'{print $2}'" % app_name).splitlines()[0] + + return {"name": app[0], "id": app[1], "state": app[2], + "version": app[3], "template": app[4][:-(len(app[3]) + 1)], + "targets": targets, "revision": revision} + + def upgrade(self, app, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + version = kwargs.get("version", None) + if version is None: + version = self.run_command("mcapps st {} | tail -1".format( + app["template"])) + self.run_command("mcapps upgrade {} {}".format(app["name"], version)) + + self.log.info("Waiting for the multi-cluster app to be upgraded") + # Wait for multi-cluster app to be "deploying" + self.wait_for_ready("mcapps ls --format '{{.App.Name}} {{.App.State}}'" + " | grep deploying | awk '{print $1}'", + app["name"], timeout=timeout) + # Wait for multi-cluster app to be "active" + upgraded = self.wait_for_ready("mcapps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app["name"]) + if not upgraded: + self.log.warn("Failed to upgrade multi-cluster app {} within " + "timeout of {} seconds.".format( + app["name"], timeout)) + return self.get(app["name"]) + + def rollback(self, app_name, revision, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + self.run_command("mcapps rollback {} {}".format(app_name, revision)) + + self.log.info("Waiting for the multi-cluster app to be rolled back") + # Wait for multi-cluster app to be "deploying" + self.wait_for_ready("mcapps ls --format '{{.App.Name}} {{.App.State}}'" + " | grep deploying | awk '{print $1}'", + app_name, timeout=timeout) + # Wait for multi-cluster app to be "active" + rolled_back = self.wait_for_ready("mcapps ls --format '{{.App.Name}} " + "{{.App.State}}' | grep active " + "| awk '{print $1}'", app_name) + if not rolled_back: + self.log.warn("Failed to rollback multi-cluster app {} within " + "timeout of {} seconds.".format(app_name, timeout)) + return self.get(app_name) + + def delete(self, app, **kwargs): + timeout = kwargs.get("timeout", DEFAULT_TIMEOUT) + self.run_command("mcapps delete {}".format(app["name"])) + + self.log.info("Waiting for the app to be deleted") + deleted = self.wait_for_ready("mcapps ls -q", app["name"], + timeout=timeout, condition_func= + lambda val, l: val not in l.splitlines()) + apps_deleted = False + for target in app["targets"]: + apps_deleted = self.wait_for_ready("apps ls -q", target["name"], + timeout=timeout, condition_func= + lambda val, l: + val not in l.splitlines()) + if not apps_deleted: + break + return deleted, apps_deleted + + +class CatalogCli(BaseCli): + def add(self, url, **kwargs): + branch = kwargs.get("branch", None) + catalog_name = random_test_name("ctest") + cmd = "catalog add {} {}".format(catalog_name, url) + if branch is not None: + cmd = cmd + " --branch " + branch + self.run_command(cmd) + return self.get(catalog_name) + + def delete(self, name): + self.run_command("catalog delete " + name) + deleted = self.get(name) is None + return deleted + + def get(self, name): + catalog = self.run_command("catalog ls --format '{{.Catalog.Name}}" + "|{{.Catalog.ID}}|{{.Catalog.URL}}" + "|{{.Catalog.Branch}}' | grep " + name) + if catalog is None: + return None + catalog = catalog.split("|") + return {"name": catalog[0], "id": catalog[1], + "url": catalog[2], "branch": catalog[3]} + + +class ClusterCli(BaseCli): + def delete(self, c_id): + self.run_command("clusters delete {}".format(c_id)) + + self.log.info("Waiting for the cluster to be deleted") + deleted = self.wait_for_ready("cluster ls -q", c_id, condition_func= + lambda val, l: val not in l.splitlines()) + return deleted + + +class NodeCli(BaseCli): + def get(self): + result = self.run_command( + "nodes ls --format '{{.Name}}|{{.Node.IPAddress}}'").splitlines() + nodes = [] + for n in result: + nodes.append({ + "name": n.split("|")[0], + "ip": n.split("|")[1] + }) + return nodes + + def ssh(self, node, cmd, known=False, is_jenkins=False): + if is_jenkins: + home = str(Path.home()) + tilde = home + else: + tilde = '~' + if not known: + self.log.debug("Determining if host is already known") + known_hosts = os.path.expanduser( + "{}/.ssh/known_hosts".format(tilde)) + with open(known_hosts) as file: + for line in file: + if node["ip"] in line: + known = True + break + if not known: + self.log.debug("Host is not known. Attempting to add it to file") + try: + self.log.debug("Storing ecdsa key in known hosts") + subprocess.run("ssh-keyscan -t ecdsa {} >> {}" + "/.ssh/known_hosts".format(node["ip"], tilde), + shell=True, stderr=subprocess.PIPE) + except subprocess.CalledProcessError as e: + self.log.info("Error storing ecdsa key! Result: %s", e.stderr) + ssh_result = self.run_command('ssh {} "{}"'.format(node["name"], cmd)) + return ssh_result diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/common.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/common.py new file mode 100644 index 0000000..03936a3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/common.py @@ -0,0 +1,3078 @@ +from ..common import * # NOQA +import inspect +import json +import os +import random +import subprocess +import ssl +import time +import requests +import ast +import paramiko +import rancher +import pytest +from urllib.parse import urlparse +from rancher import ApiError +from lib.aws import AmazonWebServices +from copy import deepcopy +from threading import Lock +from threading import Thread +import websocket +import base64 + +DEFAULT_CATALOG_TIMEOUT = 15 +DEFAULT_MONITORING_TIMEOUT = 180 +DEFAULT_CLUSTER_STATE_TIMEOUT = 320 +DEFAULT_MULTI_CLUSTER_APP_TIMEOUT = 300 +DEFAULT_APP_DELETION_TIMEOUT = 360 +DEFAULT_APP_V2_TIMEOUT = 60 + +CATTLE_API_URL = CATTLE_TEST_URL + "/v3" +CATTLE_AUTH_URL = \ + CATTLE_TEST_URL + "/v3-public/localproviders/local?action=login" + +DNS_REGEX = "(https*://)(.*[^/])" + +USER_PASSWORD = os.environ.get('USER_PASSWORD', "None") +ADMIN_PASSWORD = os.environ.get('ADMIN_PASSWORD', "None") + +kube_fname = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "k8s_kube_config") +MACHINE_TIMEOUT = float(os.environ.get('RANCHER_MACHINE_TIMEOUT', "1200")) + +HARDENED_CLUSTER = ast.literal_eval( + os.environ.get('RANCHER_HARDENED_CLUSTER', "False")) +TEST_OS = os.environ.get('RANCHER_TEST_OS', "linux") +TEST_IMAGE = os.environ.get( + 'RANCHER_TEST_IMAGE', "ranchertest/mytestcontainer") +TEST_IMAGE_PORT = os.environ.get('RANCHER_TEST_IMAGE_PORT', "80") +TEST_IMAGE_REDIS = os.environ.get('RANCHER_TEST_IMAGE_REDIS', "redis:latest") +TEST_IMAGE_OS_BASE = os.environ.get('RANCHER_TEST_IMAGE_OS_BASE', "ubuntu") +if TEST_OS == "windows": + DEFAULT_TIMEOUT = 300 +skip_test_windows_os = pytest.mark.skipif( + TEST_OS == "windows", + reason='Tests Skipped for including Windows nodes cluster') +skip_test_hardened = pytest.mark.skipif( + HARDENED_CLUSTER, + reason='Tests Skipped due to being a hardened cluster') + +UPDATE_KDM = ast.literal_eval(os.environ.get('RANCHER_UPDATE_KDM', "False")) +KDM_URL = os.environ.get("RANCHER_KDM_URL", "") +CLUSTER_NAME = os.environ.get("RANCHER_CLUSTER_NAME", "") +RANCHER_CLEANUP_CLUSTER = \ + ast.literal_eval(os.environ.get('RANCHER_CLEANUP_CLUSTER', "True")) +env_file = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "rancher_env.config") + +AWS_SSH_KEY_NAME = os.environ.get("AWS_SSH_KEY_NAME") +AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID") +AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY") +AWS_REGION = os.environ.get("AWS_REGION") +AWS_SUBNET = os.environ.get("AWS_SUBNET") +AWS_VPC = os.environ.get("AWS_VPC") +AWS_SG = os.environ.get("AWS_SG") +AWS_ZONE = os.environ.get("AWS_ZONE") +AWS_IAM_PROFILE = os.environ.get("AWS_IAM_PROFILE", "") +AWS_S3_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME", "") +AWS_S3_BUCKET_FOLDER_NAME = os.environ.get("AWS_S3_BUCKET_FOLDER_NAME", "") +LINODE_ACCESSKEY = os.environ.get('RANCHER_LINODE_ACCESSKEY', "None") +NFS_SERVER_MOUNT_PATH = "/nfs" + +TEST_RBAC = ast.literal_eval(os.environ.get('RANCHER_TEST_RBAC', "False")) +if_test_rbac = pytest.mark.skipif(TEST_RBAC is False, + reason='rbac tests are skipped') + +TEST_ALL_SNAPSHOT = ast.literal_eval( + os.environ.get('RANCHER_TEST_ALL_SNAPSHOT', "False") +) +if_test_all_snapshot = \ + pytest.mark.skipif(TEST_ALL_SNAPSHOT is False, + reason='Snapshots check tests are skipped') +DATA_SUBDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') +# As of release 2.4 default rke scan profile is "rke-cis-1.4" +CIS_SCAN_PROFILE = os.environ.get('RANCHER_CIS_SCAN_PROFILE', "rke-cis-1.4") + +# here are all supported roles for RBAC testing +CLUSTER_MEMBER = "cluster-member" +CLUSTER_OWNER = "cluster-owner" +PROJECT_MEMBER = "project-member" +PROJECT_OWNER = "project-owner" +PROJECT_READ_ONLY = "read-only" + +rbac_data = { + "project": None, + "namespace": None, + "workload": None, + "p_unshared": None, + "ns_unshared": None, + "wl_unshared": None, + "users": { + CLUSTER_OWNER: {}, + CLUSTER_MEMBER: {}, + PROJECT_OWNER: {}, + PROJECT_MEMBER: {}, + PROJECT_READ_ONLY: {}, + } +} + +auth_rbac_data = { + "project": None, + "namespace": None, + "users": {} +} + +# here are the global role templates used for +# testing globalRoleBinding and groupRoleBinding +TEMPLATE_MANAGE_CATALOG = { + "newUserDefault": "false", + "rules": [ + { + "type": "/v3/schemas/policyRule", + "apiGroups": [ + "management.cattle.io" + ], + "verbs": [ + "*" + ], + "resources": [ + "catalogs", + "templates", + "templateversions" + ] + } + ], + "name": "gr-test-manage-catalog", +} + +TEMPLATE_LIST_CLUSTER = { + "newUserDefault": "false", + "rules": [ + { + "type": "/v3/schemas/policyRule", + "apiGroups": [ + "management.cattle.io" + ], + "verbs": [ + "get", + "list", + "watch" + ], + "resources": [ + "clusters" + ] + } + ], + "name": "gr-test-list-cluster", +} + +# this is used when testing users from a auth provider +AUTH_PROVIDER = os.environ.get('RANCHER_AUTH_PROVIDER', "") +if AUTH_PROVIDER not in ["activeDirectory", "freeIpa", "openLdap", ""]: + pytest.fail("Invalid RANCHER_AUTH_PROVIDER. Please provide one of: " + "activeDirectory, freeIpa, or openLdap (case sensitive).") +NESTED_GROUP_ENABLED = ast.literal_eval( + os.environ.get('RANCHER_NESTED_GROUP_ENABLED', "False")) +# Admin Auth username and the shared password for all auth users +AUTH_USER_PASSWORD = os.environ.get('RANCHER_AUTH_USER_PASSWORD', "") + +# the link to log in as an auth user +LOGIN_AS_AUTH_USER_URL = \ + CATTLE_TEST_URL + "/v3-public/" \ + + AUTH_PROVIDER + "Providers/" \ + + AUTH_PROVIDER.lower() + "?action=login" +CATTLE_AUTH_PRINCIPAL_URL = CATTLE_TEST_URL + "/v3/principals?action=search" + +# This is used for nested group when a third part Auth is enabled +nested_group = { + "auth_info": None, + "users": None, + "group_dic": None, + "groups": None +} +auth_requirements = not AUTH_PROVIDER or not AUTH_USER_PASSWORD +if_test_group_rbac = pytest.mark.skipif( + auth_requirements, + reason='Group RBAC tests are skipped.' + 'Required AUTH env variables ' + 'have not been set.' +) + +# ----------------------------------------------------------------------------- +# global variables from test_create_ha.py +test_run_id = "test" + str(random.randint(10000, 99999)) +RANCHER_HOSTNAME_PREFIX = os.environ.get("RANCHER_HOSTNAME_PREFIX", + test_run_id) +CERT_MANAGER_VERSION = os.environ.get("RANCHER_CERT_MANAGER_VERSION", "v1.0.1") +# ----------------------------------------------------------------------------- + +# this is used for testing rbac v2 +test_rbac_v2 = os.environ.get("RANCHER_TEST_RBAC_V2", "False") +if_test_rbac_v2 = pytest.mark.skipif(test_rbac_v2 != "True", + reason='test for rbac v2 is skipped') + + +def is_windows(os_type=TEST_OS): + return os_type == "windows" + + +def get_cluster_client_for_token_v1(cluster_id, token): + url = CATTLE_TEST_URL + "/k8s/clusters/" + cluster_id + "/v1/schemas" + return rancher.Client(url=url, token=token, verify=False) + + +def get_admin_client(): + return rancher.Client(url=CATTLE_API_URL, token=ADMIN_TOKEN, verify=False) + + +def get_user_client(): + return rancher.Client(url=CATTLE_API_URL, token=USER_TOKEN, verify=False) + + +def get_client_for_token(token, url=CATTLE_API_URL): + return rancher.Client(url=url, token=token, verify=False) + + +def get_project_client_for_token(project, token): + p_url = project.links['self'] + '/schemas' + p_client = rancher.Client(url=p_url, token=token, verify=False) + return p_client + + +def get_cluster_client_for_token(cluster, token): + c_url = cluster.links['self'] + '/schemas' + c_client = rancher.Client(url=c_url, token=token, verify=False) + return c_client + + +def up(cluster, token): + c_url = cluster.links['self'] + '/schemas' + c_client = rancher.Client(url=c_url, token=token, verify=False) + return c_client + + +def wait_state(client, obj, state, timeout=DEFAULT_TIMEOUT): + wait_for(lambda: client.reload(obj).state == state, timeout) + return client.reload(obj) + + +def wait_for_condition(client, resource, check_function, fail_handler=None, + timeout=DEFAULT_TIMEOUT): + start = time.time() + resource = client.reload(resource) + while not check_function(resource): + if time.time() - start > timeout: + exceptionMsg = 'Timeout waiting for ' + resource.baseType + \ + ' to satisfy condition: ' + \ + inspect.getsource(check_function) + if fail_handler: + exceptionMsg = exceptionMsg + fail_handler(resource) + raise Exception(exceptionMsg) + time.sleep(.5) + resource = client.reload(resource) + return resource + + +def get_setting_value_by_name(name): + settings_url = CATTLE_API_URL + "/settings/" + name + head = {'Authorization': 'Bearer ' + ADMIN_TOKEN} + response = requests.get(settings_url, verify=False, headers=head) + return response.json()["value"] + + +# Return value is negative if v1 < v2, zero if v1 == v2 and positive if v1 > v2 +def compare_versions(v1, v2): + if tuple(map(int, (v1.split(".")))) > tuple(map(int, (v2.split(".")))): + return 1 + elif tuple(map(int, (v1.split(".")))) < tuple(map(int, (v2.split(".")))): + return -1 + else: + return 0 + + +def create_project_and_ns(token, cluster, project_name=None, ns_name=None): + server_url = cluster.links['self'].split("/clusters")[0] + client = get_client_for_token(token, server_url) + p = create_project(client, cluster, project_name) + c_client = get_cluster_client_for_token(cluster, token) + ns = create_ns(c_client, cluster, p, ns_name) + return p, ns + + +def create_project(client, cluster, project_name=None): + if project_name is None: + project_name = random_name() + p = client.create_project(name=project_name, + clusterId=cluster.id) + time.sleep(5) + p = wait_until_available(client, p) + assert p.state == 'active' + return p + + +def create_project_with_pspt(client, cluster, pspt): + p = client.create_project(name=random_name(), + clusterId=cluster.id) + p = wait_until_available(client, p) + assert p.state == 'active' + return set_pspt_for_project(p, client, pspt) + + +def set_pspt_for_project(project, client, pspt): + project.setpodsecuritypolicytemplate(podSecurityPolicyTemplateId=pspt.id) + project = wait_until_available(client, project) + assert project.state == 'active' + return project + + +def create_ns(client, cluster, project, ns_name=None): + if ns_name is None: + ns_name = random_name() + ns = client.create_namespace(name=ns_name, + clusterId=cluster.id, + projectId=project.id) + wait_for_ns_to_become_active(client, ns) + ns = client.reload(ns) + assert ns.state == 'active' + return ns + + +def assign_members_to_cluster(client, user, cluster, role_template_id): + crtb = client.create_cluster_role_template_binding( + clusterId=cluster.id, + roleTemplateId=role_template_id, + subjectKind="User", + userId=user.id) + return crtb + + +def assign_members_to_project(client, user, project, role_template_id): + prtb = client.create_project_role_template_binding( + projectId=project.id, + roleTemplateId=role_template_id, + subjectKind="User", + userId=user.id) + return prtb + + +def change_member_role_in_cluster(client, user, crtb, role_template_id): + client.delete(crtb) + crtb = client.create_cluster_role_template_binding( + clusterId=crtb.clusterId, + roleTemplateId=role_template_id, + subjectKind="User", + userId=user.id + ) + return crtb + + +def change_member_role_in_project(client, user, prtb, role_template_id): + client.delete(prtb) + prtb = client.create_project_role_template_binding( + projectId=prtb.projectId, + roleTemplateId=role_template_id, + subjectKind="User", + userId=user.id + ) + return prtb + + +def create_kubeconfig(cluster, file_name=kube_fname): + generateKubeConfigOutput = cluster.generateKubeconfig() + print(generateKubeConfigOutput.config) + file = open(file_name, "w") + file.write(generateKubeConfigOutput.config) + file.close() + + +def validate_psp_error_worklaod(p_client, workload, error_message): + workload = wait_for_wl_transitioning(p_client, workload) + assert workload.state == "updating" + assert workload.transitioning == "error" + print(workload.transitioningMessage) + assert error_message in workload.transitioningMessage + + +def validate_all_workload_image_from_rancher(project_client, ns, pod_count=1, + ignore_pod_count=False, + deployment_list=None, + daemonset_list=None, + cronjob_list=None, job_list=None): + if cronjob_list is None: + cronjob_list = [] + if daemonset_list is None: + daemonset_list = [] + if deployment_list is None: + deployment_list = [] + if job_list is None: + job_list = [] + workload_list = deployment_list + daemonset_list + cronjob_list + job_list + + wls = [dep.name for dep in project_client.list_workload( + namespaceId=ns.id).data] + assert len(workload_list) == len(wls), \ + "Expected {} workload(s) to be present in {} namespace " \ + "but there were {}".format(len(workload_list), ns.name, len(wls)) + + for workload_name in workload_list: + workloads = project_client.list_workload(name=workload_name, + namespaceId=ns.id).data + assert len(workloads) == workload_list.count(workload_name), \ + "Expected {} workload(s) to be present with name {} " \ + "but there were {}".format(workload_list.count(workload_name), + workload_name, len(workloads)) + for workload in workloads: + for container in workload.containers: + assert str(container.image).startswith("rancher/") + if workload_name in deployment_list: + validate_workload(project_client, workload, "deployment", + ns.name, pod_count=pod_count, + ignore_pod_count=ignore_pod_count) + deployment_list.remove(workload_name) + if workload_name in daemonset_list: + validate_workload(project_client, workload, "daemonSet", + ns.name, pod_count=pod_count, + ignore_pod_count=ignore_pod_count) + daemonset_list.remove(workload_name) + if workload_name in cronjob_list: + validate_workload(project_client, workload, "cronJob", + ns.name, pod_count=pod_count, + ignore_pod_count=ignore_pod_count) + cronjob_list.remove(workload_name) + if workload_name in job_list: + validate_workload(project_client, workload, "job", + ns.name, pod_count=pod_count, + ignore_pod_count=ignore_pod_count) + job_list.remove(workload_name) + # Final assertion to ensure all expected workloads have been validated + assert not deployment_list + daemonset_list + cronjob_list + + +def validate_workload(p_client, workload, type, ns_name, pod_count=1, + wait_for_cron_pods=60, ignore_pod_count=False): + workload = wait_for_wl_to_active(p_client, workload) + assert workload.state == "active" + # For cronjob, wait for the first pod to get created after + # scheduled wait time + if type == "cronJob": + time.sleep(wait_for_cron_pods) + if ignore_pod_count: + pods = p_client.list_pod(workloadId=workload.id).data + else: + pods = wait_for_pods_in_workload(p_client, workload, pod_count) + assert len(pods) == pod_count + pods = p_client.list_pod(workloadId=workload.id).data + assert len(pods) == pod_count + for pod in pods: + if type == "job": + job_type = True + expected_status = "Succeeded" + else: + job_type = False + expected_status = "Running" + p = wait_for_pod_to_running(p_client, pod, job_type=job_type) + assert p["status"]["phase"] == expected_status + + wl_result = execute_kubectl_cmd( + "get " + type + " " + workload.name + " -n " + ns_name) + if type == "deployment" or type == "statefulSet": + assert wl_result["status"]["readyReplicas"] == len(pods) + if type == "daemonSet": + assert wl_result["status"]["currentNumberScheduled"] == len(pods) + if type == "cronJob": + assert len(wl_result["status"]["active"]) >= len(pods) + if type == "job": + assert wl_result["status"]["succeeded"] == len(pods) + + +def validate_workload_with_sidekicks(p_client, workload, type, ns_name, + pod_count=1): + workload = wait_for_wl_to_active(p_client, workload) + assert workload.state == "active" + pods = wait_for_pods_in_workload(p_client, workload, pod_count) + assert len(pods) == pod_count + for pod in pods: + wait_for_pod_to_running(p_client, pod) + wl_result = execute_kubectl_cmd( + "get " + type + " " + workload.name + " -n " + ns_name) + assert wl_result["status"]["readyReplicas"] == pod_count + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns_name + execute_kubectl_cmd(get_pods) + pods_result = execute_kubectl_cmd(get_pods) + assert len(pods_result["items"]) == pod_count + for pod in pods_result["items"]: + assert pod["status"]["phase"] == "Running" + assert len(pod["status"]["containerStatuses"]) == 2 + assert "running" in pod["status"]["containerStatuses"][0]["state"] + assert "running" in pod["status"]["containerStatuses"][1]["state"] + + +def validate_workload_paused(p_client, workload, expectedstatus): + workloadStatus = p_client.list_workload(uuid=workload.uuid).data[0].paused + assert workloadStatus == expectedstatus + + +def validate_pod_images(expectedimage, workload, ns_name): + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns_name + pods = execute_kubectl_cmd(get_pods) + + for pod in pods["items"]: + assert pod["spec"]["containers"][0]["image"] == expectedimage + + +def validate_pods_are_running_by_id(expectedpods, workload, ns_name): + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns_name + pods = execute_kubectl_cmd(get_pods) + + curpodnames = [] + for pod in pods["items"]: + curpodnames.append(pod["metadata"]["name"]) + + for expectedpod in expectedpods["items"]: + assert expectedpod["metadata"]["name"] in curpodnames + + +def validate_workload_image(client, workload, expectedImage, ns): + workload = client.list_workload(uuid=workload.uuid).data[0] + assert workload.containers[0].image == expectedImage + validate_pod_images(expectedImage, workload, ns.name) + + +def execute_kubectl_cmd(cmd, json_out=True, stderr=False, + kubeconfig=kube_fname): + command = 'kubectl --kubeconfig {0} {1}'.format( + kubeconfig, cmd) + if json_out: + command += ' -o json' + print("run cmd: \t{0}".format(command)) + + if stderr: + result = run_command_with_stderr(command, False) + else: + result = run_command(command, False) + print("returns: \t{0}".format(result)) + + if json_out: + result = json.loads(result) + return result + + +def run_command(command, log_out=True): + if log_out: + print("run cmd: \t{0}".format(command)) + + try: + return subprocess.check_output(command, shell=True, text=True) + except subprocess.CalledProcessError as e: + return None + + +def run_command_with_stderr(command, log_out=True): + if log_out: + print("run cmd: \t{0}".format(command)) + + try: + output = subprocess.check_output(command, shell=True, + stderr=subprocess.PIPE) + returncode = 0 + except subprocess.CalledProcessError as e: + output = e.stderr + returncode = e.returncode + + if log_out: + print("return code: \t{0}".format(returncode)) + if returncode != 0: + print("output: \t{0}".format(output)) + + return output + + +def wait_for_wl_to_active(client, workload, timeout=DEFAULT_TIMEOUT): + start = time.time() + timeout = start + timeout + workloads = client.list_workload(uuid=workload.uuid).data + assert len(workloads) == 1 + wl = workloads[0] + while wl.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + workloads = client.list_workload(uuid=workload.uuid).data + assert len(workloads) == 1 + wl = workloads[0] + return wl + + +def wait_for_ingress_to_active(client, ingress, timeout=DEFAULT_TIMEOUT): + start = time.time() + ingresses = client.list_ingress(uuid=ingress.uuid).data + assert len(ingresses) == 1 + wl = ingresses[0] + while wl.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + ingresses = client.list_ingress(uuid=ingress.uuid).data + assert len(ingresses) == 1 + wl = ingresses[0] + return wl + + +def wait_for_wl_transitioning(client, workload, timeout=DEFAULT_TIMEOUT, + state="error"): + start = time.time() + workloads = client.list_workload(uuid=workload.uuid).data + assert len(workloads) == 1 + wl = workloads[0] + while wl.transitioning != state: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + workloads = client.list_workload(uuid=workload.uuid).data + assert len(workloads) == 1 + wl = workloads[0] + return wl + + +def wait_for_pod_to_running(client, pod, timeout=DEFAULT_TIMEOUT, job_type=False): + start = time.time() + pods = client.list_pod(uuid=pod.uuid).data + assert len(pods) == 1 + p = pods[0] + if job_type: + expected_state = "succeeded" + else: + expected_state = "running" + while p.state != expected_state: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + pods = client.list_pod(uuid=pod.uuid).data + assert len(pods) == 1 + p = pods[0] + return p + + +def get_schedulable_nodes(cluster, client=None, os_type=TEST_OS): + if not client: + client = get_user_client() + nodes = client.list_node(clusterId=cluster.id).data + schedulable_nodes = [] + for node in nodes: + if not node.unschedulable: + shouldSchedule = True + # node.taints doesn't exist if the node has no taints. + try: + for tval in node.taints: + if str(tval).find("PreferNoSchedule") == -1: + if str(tval).find("NoExecute") > -1 or str(tval).find("NoSchedule") > -1: + shouldSchedule = False + break + except AttributeError: + pass + if not shouldSchedule: + continue + for key, val in node.labels.items(): + # Either one of the labels should be present on the node + if key == 'kubernetes.io/os' or key == 'beta.kubernetes.io/os': + if val == os_type: + schedulable_nodes.append(node) + break + return schedulable_nodes + + +def get_etcd_nodes(cluster, client=None): + if not client: + client = get_user_client() + nodes = client.list_node(clusterId=cluster.id).data + etcd_nodes = [] + for node in nodes: + if node.etcd: + etcd_nodes.append(node) + return etcd_nodes + + +def get_role_nodes(cluster, role, client=None): + etcd_nodes = [] + control_nodes = [] + worker_nodes = [] + node_list = [] + if not client: + client = get_user_client() + nodes = client.list_node(clusterId=cluster.id).data + for node in nodes: + if node.etcd: + etcd_nodes.append(node) + if node.controlPlane: + control_nodes.append(node) + if node.worker: + worker_nodes.append(node) + if role == "etcd": + node_list = etcd_nodes + if role == "control": + node_list = control_nodes + if role == "worker": + node_list = worker_nodes + return node_list + + +def validate_ingress(p_client, cluster, workloads, host, path, + insecure_redirect=False): + time.sleep(10) + curl_args = " " + if (insecure_redirect): + curl_args = " -L --insecure " + if len(host) > 0: + curl_args += " --header 'Host: " + host + "'" + nodes = get_schedulable_nodes(cluster, os_type="linux") + target_name_list = get_target_names(p_client, workloads) + for node in nodes: + host_ip = resolve_node_ip(node) + url = "http://" + host_ip + path + if not insecure_redirect: + wait_until_ok(url, timeout=300, headers={ + "Host": host + }) + cmd = curl_args + " " + url + validate_http_response(cmd, target_name_list) + + +def validate_ingress_using_endpoint(p_client, ingress, workloads, + timeout=300, + certcheck=False, is_insecure=False): + target_name_list = get_target_names(p_client, workloads) + start = time.time() + fqdn_available = False + url = None + while not fqdn_available: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for endpoint to be available") + time.sleep(.5) + ingress_list = p_client.list_ingress(uuid=ingress.uuid).data + assert len(ingress_list) == 1 + ingress = ingress_list[0] + if hasattr(ingress, 'publicEndpoints'): + for public_endpoint in ingress.publicEndpoints: + if public_endpoint["hostname"].startswith(ingress.name) \ + or certcheck: + fqdn_available = True + url = \ + public_endpoint["protocol"].lower() + "://" + \ + public_endpoint["hostname"] + if "path" in public_endpoint.keys(): + url += public_endpoint["path"] + time.sleep(10) + validate_http_response(url, target_name_list, insecure=is_insecure) + + +def get_target_names(p_client, workloads): + pods = [] + for workload in workloads: + pod_list = p_client.list_pod(workloadId=workload.id).data + pods.extend(pod_list) + target_name_list = [] + for pod in pods: + target_name_list.append(pod.name) + print("target name list:" + str(target_name_list)) + return target_name_list + + +def get_endpoint_url_for_workload(p_client, workload, timeout=600): + fqdn_available = False + url = "" + start = time.time() + while not fqdn_available: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for endpoint to be available") + time.sleep(.5) + workload_list = p_client.list_workload(uuid=workload.uuid).data + assert len(workload_list) == 1 + workload = workload_list[0] + if hasattr(workload, 'publicEndpoints'): + assert len(workload.publicEndpoints) > 0 + url = "http://" + url = url + workload.publicEndpoints[0]["addresses"][0] + ":" + url = url + str(workload.publicEndpoints[0]["port"]) + fqdn_available = True + return url + + +def wait_until_lb_is_active(url, timeout=300): + start = time.time() + while check_for_no_access(url): + time.sleep(.5) + print("No access yet") + if time.time() - start > timeout: + raise Exception('Timed out waiting for LB to become active') + return + + +def check_for_no_access(url, verify=False): + try: + requests.get(url, verify=verify) + return False + except requests.ConnectionError: + print("Connection Error - " + url) + return True + + +def wait_until_active(url, timeout=120): + start = time.time() + while check_for_no_access(url): + time.sleep(.5) + print("No access yet") + if time.time() - start > timeout: + raise Exception('Timed out waiting for url ' + 'to become active') + return + + +def wait_until_ok(url, timeout=120, headers={}): + start = time.time() + while not check_if_ok(url, headers=headers): + time.sleep(.5) + if time.time() - start > timeout: + raise Exception( + 'Timed out waiting for {0} to become ok'.format(url) + ) + return + + +def wait_for_status_code(url, expected_code=200, timeout=DEFAULT_TIMEOUT): + start = time.time() + r = requests.get(url, verify=False) + while r.status_code != expected_code: + time.sleep(1) + r = requests.get(url, verify=False) + if time.time() - start > timeout: + raise Exception( + 'Timed out waiting for status code {0}' + ', actual code {1}'.format( + expected_code, r.status_code + ) + ) + return + + +def check_if_ok(url, verify=False, headers={}): + try: + res = requests.head(url, verify=verify, headers=headers) + if res.status_code == 200: + return True + return False + except requests.ConnectionError: + print("Connection Error - " + url) + return False + +def retry_cmd_validate_expected(pod, cmd, expected, timeout=300): + start = time.time() + timeout = start + timeout + cmd_output = kubectl_pod_exec(pod, cmd) + decode_cmd = cmd_output.decode('utf-8') + while time.time() < timeout: + if any(x in str(cmd_output) for x in expected): + return decode_cmd + time.sleep(5) + cmd_output = kubectl_pod_exec(pod, cmd) + decode_cmd = cmd_output.decode('utf-8') + raise AssertionError( + "Timed out waiting to get expected output") + +def validate_http_response(cmd, target_name_list, client_pod=None, + insecure=False): + if client_pod is None and cmd.startswith("http://"): + wait_until_active(cmd, 60) + target_hit_list = target_name_list[:] + while len(target_hit_list) != 0: + if len(target_hit_list) == 0: + break + if client_pod is None: + curl_cmd = "curl " + cmd + if insecure: + curl_cmd += "\t--insecure" + result = run_command(curl_cmd) + else: + if is_windows(): + wget_cmd = 'powershell -NoLogo -NonInteractive -Command ' \ + '"& {{ (Invoke-WebRequest -UseBasicParsing -Uri ' \ + '{0}).Content }}"'.format(cmd) + else: + wget_cmd = "wget -qO- " + cmd + time.sleep(6) + result = retry_cmd_validate_expected(client_pod, wget_cmd, target_name_list) + if result is not None: + result = result.rstrip() + assert result in target_name_list + if result in target_hit_list: + target_hit_list.remove(result) + print("After removing all, the rest is: ", target_hit_list) + assert len(target_hit_list) == 0 + + +def validate_cluster(client, cluster, intermediate_state="provisioning", + check_intermediate_state=True, skipIngresscheck=True, + nodes_not_in_active_state=[], k8s_version="", + userToken=USER_TOKEN, timeout=MACHINE_TIMEOUT): + # Allow sometime for the "cluster_owner" CRTB to take effect + time.sleep(5) + cluster = validate_cluster_state( + client, cluster, + check_intermediate_state=check_intermediate_state, + intermediate_state=intermediate_state, + nodes_not_in_active_state=nodes_not_in_active_state, + timeout=timeout) + create_kubeconfig(cluster) + if k8s_version != "": + check_cluster_version(cluster, k8s_version) + if hasattr(cluster, 'rancherKubernetesEngineConfig'): + check_cluster_state(len(get_role_nodes(cluster, "etcd", client))) + # check all workloads under the system project are active + # wait for workloads to be active + # time.sleep(DEFAULT_TIMEOUT) + print("checking if workloads under the system project are active") + sys_project = client.list_project(name='System', + clusterId=cluster.id).data[0] + sys_p_client = get_project_client_for_token(sys_project, userToken) + for wl in sys_p_client.list_workload().data: + """to help run KDM job faster (when there are many clusters), + timeout=300 is set""" + wait_for_wl_to_active(sys_p_client, wl, timeout=300) + # Create Daemon set workload and have an Ingress with Workload + # rule pointing to this daemonSet + project, ns = create_project_and_ns(userToken, cluster) + p_client = get_project_client_for_token(project, userToken) + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster, client))) + if not skipIngresscheck: + pods = p_client.list_pod(workloadId=workload["id"]).data + scale = len(pods) + # test service discovery + validate_service_discovery(workload, scale, p_client, ns, pods) + host = "test" + str(random_int(10000, 99999)) + ".com" + path = "/name.html" + rule = {"host": host, + "paths": + [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + wait_for_ingress_to_active(p_client, ingress) + validate_ingress(p_client, cluster, [workload], host, path) + return cluster + + +def check_cluster_version(cluster, version): + cluster_k8s_version = \ + cluster.appliedSpec["rancherKubernetesEngineConfig"][ + "kubernetesVersion"] + assert cluster_k8s_version == version, \ + "cluster_k8s_version: " + cluster_k8s_version + \ + " Expected: " + version + expected_k8s_version = version[:version.find("-rancher")] + k8s_version = execute_kubectl_cmd("version") + kubectl_k8s_version = k8s_version["serverVersion"]["gitVersion"] + assert kubectl_k8s_version == expected_k8s_version, \ + "kubectl version: " + kubectl_k8s_version + \ + " Expected: " + expected_k8s_version + + +def check_cluster_state(etcd_count): + css_resp = execute_kubectl_cmd("get cs") + css = css_resp["items"] + components = ["scheduler", "controller-manager"] + for i in range(0, etcd_count): + components.append("etcd-" + str(i)) + print("components to check - " + str(components)) + for cs in css: + component_name = cs["metadata"]["name"] + assert component_name in components + components.remove(component_name) + assert cs["conditions"][0]["status"] == "True" + assert cs["conditions"][0]["type"] == "Healthy" + assert len(components) == 0 + + +def validate_dns_record(pod, record, expected, port=TEST_IMAGE_PORT): + # requires pod with `dig` available - TEST_IMAGE + host = '{0}.{1}.svc.cluster.local'.format( + record["name"], record["namespaceId"]) + validate_dns_entry(pod, host, expected, port=port) + +def retry_dig(host, pod, expected, timeout=300): + start = 0 + while start < timeout: + dig_cmd = 'dig {0} +short'.format(host) + dig_output = kubectl_pod_exec(pod, dig_cmd) + decode_dig = dig_output.decode('utf-8') + split_dig = decode_dig.splitlines() + dig_length = len(split_dig) + expected_length = len(expected) + if dig_length >= expected_length: + return dig_output + start += 5 + time.sleep(5) + raise AssertionError( + "Timed out waiting to get expected output") + +def validate_dns_entry(pod, host, expected, port=TEST_IMAGE_PORT, retry_count=3): + if is_windows(): + validate_dns_entry_windows(pod, host, expected) + return + + # requires pod with `dig` available - TEST_IMAGE + if HARDENED_CLUSTER: + cmd = 'curl -vs {}:{} 2>&1'.format(host, port) + else: + cmd = 'ping -c 2 -W 2 {0}'.format(host) + cmd_output = retry_cmd_validate_expected(pod, cmd, expected) + + connectivity_validation_pass = False + for expected_value in expected: + if expected_value in str(cmd_output): + connectivity_validation_pass = True + break + + assert connectivity_validation_pass is True + if HARDENED_CLUSTER: + assert " 200 OK" in str(cmd_output) + else: + assert " 0% packet loss" in str(cmd_output) + + dig_output = retry_dig(host, pod, expected) + + for expected_value in expected: + assert expected_value in str(dig_output), \ + "Error the dig command returned: {0}".format(dig_output) + + +def validate_dns_entry_windows(pod, host, expected): + def ping_check(): + ping_cmd = 'ping -w 1 -n 1 {0}'.format(host) + ping_output = kubectl_pod_exec(pod, ping_cmd) + ping_validation_pass = False + for expected_value in expected: + if expected_value in str(ping_output): + ping_validation_pass = True + break + return ping_validation_pass and (" (0% loss)" in str(ping_output)) + + wait_for(callback=ping_check, + timeout_message="Failed to ping {0}".format(host)) + + def dig_check(): + dig_cmd = 'powershell -NoLogo -NonInteractive -Command ' \ + '"& {{ (Resolve-DnsName {0}).IPAddress }}"'.format(host) + dig_output = kubectl_pod_exec(pod, dig_cmd) + dig_validation_pass = True + for expected_value in expected: + if expected_value not in str(dig_output): + dig_validation_pass = False + break + return dig_validation_pass + + wait_for(callback=dig_check, + timeout_message="Failed to resolve {0}".format(host)) + + +def validate_dns_record_deleted(client, dns_record, timeout=DEFAULT_TIMEOUT): + """ + Checks whether dns_record got deleted successfully. + Validates if dns_record is null in for current object client. + @param client: Object client use to create dns_record + @param dns_record: record object subjected to be deleted + @param timeout: Max time to keep checking whether record is deleted or not + """ + time.sleep(2) + start = time.time() + records = client.list_dns_record(name=dns_record.name, ).data + while len(records) != 0: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for record {} to be deleted" + "".format(dns_record.name)) + time.sleep(.5) + records = client.list_dns_record(name=dns_record.name, ).data + + +def wait_for_nodes_to_become_active(client, cluster, exception_list=[], + retry_count=0): + nodes = client.list_node(clusterId=cluster.id).data + node_auto_deleted = False + for node in nodes: + if node.requestedHostname not in exception_list: + node = wait_for_node_status(client, node, "active") + if node is None: + print("Need to re-evalauate new node list") + node_auto_deleted = True + retry_count += 1 + print("Retry Count:" + str(retry_count)) + if node_auto_deleted and retry_count < 5: + wait_for_nodes_to_become_active(client, cluster, exception_list, + retry_count) + + +def wait_for_node_status(client, node, state): + uuid = node.uuid + start = time.time() + nodes = client.list_node(uuid=uuid).data + node_count = len(nodes) + # Handle the case of nodes getting auto deleted when they are part of + # nodepools + if node_count == 1: + node_status = nodes[0].state + else: + print("Node does not exist anymore -" + uuid) + return None + while node_status != state: + if time.time() - start > MACHINE_TIMEOUT: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(5) + nodes = client.list_node(uuid=uuid).data + node_count = len(nodes) + if node_count == 1: + node_status = nodes[0].state + else: + print("Node does not exist anymore -" + uuid) + return None + return node + + +def wait_for_node_to_be_deleted(client, node, timeout=300): + uuid = node.uuid + start = time.time() + nodes = client.list_node(uuid=uuid).data + node_count = len(nodes) + while node_count != 0: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for node delete") + time.sleep(.5) + nodes = client.list_node(uuid=uuid).data + node_count = len(nodes) + + +def wait_for_cluster_node_count(client, cluster, expected_node_count, + timeout=300): + start = time.time() + nodes = client.list_node(clusterId=cluster.id).data + node_count = len(nodes) + while node_count != expected_node_count: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + nodes = client.list_node(clusterId=cluster.id).data + node_count = len(nodes) + + +def get_custom_host_registration_cmd(client, cluster, roles, node): + allowed_roles = ["etcd", "worker", "controlplane"] + cluster_tokens = client.list_cluster_registration_token( + clusterId=cluster.id).data + if len(cluster_tokens) > 0: + cluster_token = cluster_tokens[0] + else: + cluster_token = create_custom_host_registration_token(client, cluster) + + additional_options = " --address " + node.public_ip_address + \ + " --internal-address " + node.private_ip_address + + if 'Administrator' == node.ssh_user: + cmd = cluster_token.windowsNodeCommand + cmd = cmd.replace('| iex', '--worker' + additional_options + ' | iex ') + else: + cmd = cluster_token.nodeCommand + for role in roles: + assert role in allowed_roles + cmd += " --" + role + + cmd += additional_options + return cmd + + +def create_custom_host_registration_token(client, cluster): + # Allow sometime for the "cluster_owner" CRTB to take effect + time.sleep(5) + cluster_token = client.create_cluster_registration_token( + clusterId=cluster.id) + cluster_token = client.wait_success(cluster_token) + assert cluster_token.state == 'active' + return cluster_token + + +def get_cluster_by_name(client, name): + clusters = client.list_cluster(name=name).data + assert len(clusters) == 1, "Cluster " + name + " does not exist" + return clusters[0] + + +def get_cluster_type(client, cluster): + cluster_configs = [ + "amazonElasticContainerServiceConfig", + "azureKubernetesServiceConfig", + "googleKubernetesEngineConfig", + "rancherKubernetesEngineConfig" + ] + if "rancherKubernetesEngineConfig" in cluster: + nodes = client.list_node(clusterId=cluster.id).data + if len(nodes) > 0: + if nodes[0].nodeTemplateId is None: + return "Custom" + for cluster_config in cluster_configs: + if cluster_config in cluster: + return cluster_config + return "Imported" + + +def delete_cluster(client, cluster): + nodes = client.list_node(clusterId=cluster.id).data + # Delete nodes(in cluster) from AWS for Imported and Custom Cluster + if len(nodes) > 0: + cluster_type = get_cluster_type(client, cluster) + print(cluster_type) + if get_cluster_type(client, cluster) in ["Imported", "Custom"]: + filters = [ + {'Name': 'tag:Name', + 'Values': ['testcustom*', 'teststress*', 'testsa*']}] + ip_filter = {} + ip_list = [] + ip_filter['Name'] = \ + 'network-interface.addresses.association.public-ip' + ip_filter['Values'] = ip_list + filters.append(ip_filter) + for node in nodes: + host_ip = resolve_node_ip(node) + ip_list.append(host_ip) + assert len(ip_filter) > 0 + print(ip_filter) + aws_nodes = AmazonWebServices().get_nodes(filters) + if aws_nodes is None: + # search instances by IPs in case names do not follow patterns + aws_nodes = AmazonWebServices().get_nodes(filters=[ip_filter]) + if aws_nodes is None: + print("no instance is found in AWS") + else: + for node in aws_nodes: + print(node.public_ip_address) + AmazonWebServices().delete_nodes(aws_nodes) + # Delete Cluster + client.delete(cluster) + + +def check_connectivity_between_workloads(p_client1, workload1, p_client2, + workload2, allow_connectivity=True): + wl1_pods = p_client1.list_pod(workloadId=workload1.id).data + wl2_pods = p_client2.list_pod(workloadId=workload2.id).data + for pod in wl1_pods: + for o_pod in wl2_pods: + check_connectivity_between_pods(pod, o_pod, allow_connectivity) + + +def check_connectivity_between_workload_pods(p_client, workload): + pods = p_client.list_pod(workloadId=workload.id).data + for pod in pods: + for o_pod in pods: + check_connectivity_between_pods(pod, o_pod) + + +def check_connectivity_between_pods(pod1, pod2, allow_connectivity=True): + pod_ip = pod2.status.podIp + + if is_windows(): + cmd = 'ping -w 1 -n 1 {0}'.format(pod_ip) + elif HARDENED_CLUSTER: + cmd = 'curl -I {}:{}'.format(pod_ip, TEST_IMAGE_PORT) + else: + cmd = "ping -c 1 -W 1 " + pod_ip + + response = retry_cmd_validate_expected(pod1, cmd, pod_ip) + if not HARDENED_CLUSTER: + assert pod_ip in str(response) + if allow_connectivity: + if is_windows(): + assert " (0% loss)" in str(response) + elif HARDENED_CLUSTER: + assert " 200 OK" in str(response) + else: + assert " 0% packet loss" in str(response) + else: + if is_windows(): + assert " (100% loss)" in str(response) + elif HARDENED_CLUSTER: + assert " 200 OK" not in str(response) + else: + assert " 100% packet loss" in str(response) + + +def kubectl_pod_exec(pod, cmd): + command = "exec " + pod.name + " -n " + pod.namespaceId + " -- " + cmd + return execute_kubectl_cmd(command, json_out=False, stderr=True) + + +def exec_shell_command(ip, port, cmd, password, user="root", sshKey=None): + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + if sshKey: + ssh.connect(ip, username=user, key_filename=sshKey, port=port) + else: + ssh.connect(ip, username=user, password=password, port=port) + + stdin, stdout, stderr = ssh.exec_command(cmd) + response = stdout.readlines() + return response + + +def wait_for_ns_to_become_active(client, ns, timeout=DEFAULT_TIMEOUT): + start = time.time() + time.sleep(10) + nss = client.list_namespace(uuid=ns.uuid).data + assert len(nss) == 1 + ns = nss[0] + while ns.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + nss = client.list_namespace(uuid=ns.uuid).data + assert len(nss) == 1 + ns = nss[0] + return ns + + +def wait_for_pod_images(p_client, workload, ns_name, expectedimage, numofpods, + timeout=DEFAULT_TIMEOUT): + start = time.time() + + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns_name + pods = execute_kubectl_cmd(get_pods) + + for x in range(0, numofpods - 1): + pod = pods["items"][x] + podimage = pod["spec"]["containers"][0]["image"] + while podimage != expectedimage: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for correct pod images") + time.sleep(.5) + pods = execute_kubectl_cmd(get_pods) + pod = pods["items"][x] + podimage = pod["spec"]["containers"][0]["image"] + + +def wait_for_pods_in_workload(p_client, workload, pod_count, + timeout=DEFAULT_TIMEOUT): + start = time.time() + pods = p_client.list_pod(workloadId=workload.id).data + while len(pods) != pod_count: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for pods in workload {}. Expected {}. " + "Got {}".format(workload.name, pod_count, len(pods))) + time.sleep(.5) + pods = p_client.list_pod(workloadId=workload.id).data + return pods + + +def get_user_client_and_cluster(client=None): + if not client: + client = get_user_client() + if CLUSTER_NAME == "": + clusters = client.list_cluster().data + else: + clusters = client.list_cluster(name=CLUSTER_NAME).data + assert len(clusters) > 0 + cluster = clusters[0] + return client, cluster + + +def get_global_admin_client_and_cluster(): + client = get_admin_client() + if CLUSTER_NAME == "": + clusters = client.list_cluster().data + else: + clusters = client.list_cluster(name=CLUSTER_NAME).data + assert len(clusters) > 0 + cluster = clusters[0] + return client, cluster + + +def validate_cluster_state(client, cluster, + check_intermediate_state=True, + intermediate_state="provisioning", + nodes_not_in_active_state=[], + timeout=MACHINE_TIMEOUT): + start_time = time.time() + if check_intermediate_state: + cluster = wait_for_condition( + client, cluster, + lambda x: x.state == intermediate_state, + lambda x: 'State is: ' + x.state, + timeout=timeout) + if intermediate_state != "updating": + assert cluster.state == intermediate_state + cluster = wait_for_condition( + client, cluster, + lambda x: x.state == "active", + lambda x: 'State is: ' + x.state, + timeout=timeout) + assert cluster.state == "active" + wait_for_nodes_to_become_active(client, cluster, + exception_list=nodes_not_in_active_state) + timeout = 60 + start = time.time() + while "version" not in cluster.keys(): + time.sleep(1) + cluster = client.reload(cluster) + delta = time.time() - start + if delta > timeout: + msg = "Timeout waiting for K8s version to be synced" + raise Exception(msg) + end_time = time.time() + diff = time.strftime("%H:%M:%S", time.gmtime(end_time - start_time)) + print("The total time for provisioning/updating the cluster {} : {}". + format(cluster.name, diff)) + return cluster + + +def wait_until_available(client, obj, timeout=DEFAULT_TIMEOUT): + start = time.time() + sleep = 0.01 + while True: + time.sleep(sleep) + sleep *= 2 + if sleep > 2: + sleep = 2 + try: + obj = client.reload(obj) + except ApiError as e: + if e.error.status != 403: + raise e + else: + return obj + delta = time.time() - start + if delta > timeout: + msg = 'Timeout waiting for [{}:{}] for condition after {}' \ + ' seconds'.format(obj.type, obj.id, delta) + raise Exception(msg) + + +def delete_node(aws_nodes): + for node in aws_nodes: + AmazonWebServices().delete_node(node) + + +def cluster_cleanup(client, cluster, aws_nodes=None): + if RANCHER_CLEANUP_CLUSTER: + start = time.time() + client.delete(cluster) + if cluster.rancherKubernetesEngineConfig.cloudProvider.name == "azure": + time.sleep(20) + print("-------sleep time after cluster deletion--------", time.time() - start) + if aws_nodes is not None: + delete_node(aws_nodes) + else: + env_details = "env.CATTLE_TEST_URL='" + CATTLE_TEST_URL + "'\n" + env_details += "env.ADMIN_TOKEN='" + ADMIN_TOKEN + "'\n" + env_details += "env.USER_TOKEN='" + USER_TOKEN + "'\n" + env_details += "env.CLUSTER_NAME='" + cluster.name + "'\n" + create_config_file(env_details) + + +def hosted_cluster_cleanup(client, cluster, cluster_name): + if RANCHER_CLEANUP_CLUSTER: + client.delete(cluster) + else: + env_details = "env.CATTLE_TEST_URL='" + CATTLE_TEST_URL + "'\n" + env_details += "env.ADMIN_TOKEN='" + ADMIN_TOKEN + "'\n" + env_details += "env.USER_TOKEN='" + USER_TOKEN + "'\n" + env_details += "env.CLUSTER_NAME='" + cluster_name + "'\n" + create_config_file(env_details) + + +def create_config_file(env_details): + file = open(env_file, "w") + file.write(env_details) + file.close() + + +def validate_hostPort(p_client, workload, source_port, cluster): + get_endpoint_url_for_workload(p_client, workload) + wl = p_client.list_workload(uuid=workload.uuid).data[0] + source_port_wk = wl.publicEndpoints[0]["port"] + assert source_port == source_port_wk, "Source ports do not match" + pods = p_client.list_pod(workloadId=workload.id).data + nodes = get_schedulable_nodes(cluster) + for node in nodes: + target_name_list = [] + for pod in pods: + print(pod.nodeId + " check " + node.id) + if pod.nodeId == node.id: + target_name_list.append(pod.name) + break + if len(target_name_list) > 0: + host_ip = resolve_node_ip(node) + curl_cmd = " http://" + host_ip + ":" + \ + str(source_port) + "/name.html" + validate_http_response(curl_cmd, target_name_list) + + +def validate_lb(p_client, workload, source_port): + url = get_endpoint_url_for_workload(p_client, workload) + wl = p_client.list_workload(uuid=workload.uuid).data[0] + source_port_wk = wl.publicEndpoints[0]["port"] + assert source_port == source_port_wk, "Source ports do not match" + target_name_list = get_target_names(p_client, [workload]) + wait_until_lb_is_active(url) + validate_http_response(url + "/name.html", target_name_list) + + +def validate_nodePort(p_client, workload, cluster, source_port): + get_endpoint_url_for_workload(p_client, workload, 600) + wl = p_client.list_workload(uuid=workload.uuid).data[0] + source_port_wk = wl.publicEndpoints[0]["port"] + assert source_port == source_port_wk, "Source ports do not match" + nodes = get_schedulable_nodes(cluster) + pods = p_client.list_pod(workloadId=wl.id).data + target_name_list = [] + for pod in pods: + target_name_list.append(pod.name) + print("target name list:" + str(target_name_list)) + for node in nodes: + host_ip = resolve_node_ip(node) + curl_cmd = " http://" + host_ip + ":" + \ + str(source_port_wk) + "/name.html" + validate_http_response(curl_cmd, target_name_list) + + +def validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port): + pods = p_client.list_pod(workloadId=workload.id).data + target_name_list = [] + for pod in pods: + target_name_list.append(pod["name"]) + curl_cmd = "http://" + cluster_ip + ":" + \ + str(source_port) + "/name.html" + for pod in test_pods: + validate_http_response(curl_cmd, target_name_list, pod) + + +def wait_for_pv_to_be_available(c_client, pv_object, timeout=DEFAULT_TIMEOUT): + start = time.time() + time.sleep(2) + list = c_client.list_persistent_volume(uuid=pv_object.uuid).data + assert len(list) == 1 + pv = list[0] + while pv.state != "available": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to available") + time.sleep(.5) + list = c_client.list_persistent_volume(uuid=pv_object.uuid).data + assert len(list) == 1 + pv = list[0] + return pv + + +def wait_for_pvc_to_be_bound(p_client, pvc_object, timeout=DEFAULT_TIMEOUT): + start = time.time() + time.sleep(2) + list = p_client.list_persistent_volume_claim(uuid=pvc_object.uuid).data + assert len(list) == 1 + pvc = list[0] + while pvc.state != "bound": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to bound") + time.sleep(.5) + list = p_client.list_persistent_volume_claim(uuid=pvc_object.uuid).data + assert len(list) == 1 + pvc = list[0] + return pvc + + +def create_wl_with_nfs(p_client, ns_id, pvc_name, wl_name, + mount_path, sub_path, is_daemonSet=False): + volumes = [{"type": "volume", + "name": "vol1", + "persistentVolumeClaim": { + "readOnly": "false", + "type": "persistentVolumeClaimVolumeSource", + "persistentVolumeClaimId": pvc_name + }}] + volumeMounts = [{"readOnly": "False", + "type": "volumeMount", + "mountPath": mount_path, + "subPath": sub_path, + "name": "vol1" + }] + con = [{"name": "test1", + "image": TEST_IMAGE, + "volumeMounts": volumeMounts + }] + if is_daemonSet: + workload = p_client.create_workload(name=wl_name, + containers=con, + namespaceId=ns_id, + volumes=volumes, + daemonSetConfig={}) + else: + workload = p_client.create_workload(name=wl_name, + containers=con, + namespaceId=ns_id, + volumes=volumes) + return workload + + +def write_content_to_file(pod, content, filename): + cmd_write = "/bin/bash -c 'echo {1} > {0}'".format(filename, content) + if is_windows(): + cmd_write = \ + 'powershell -NoLogo -NonInteractive -Command ' \ + '"& { echo {1} > {0} }"'.format(filename, content) + output = kubectl_pod_exec(pod, cmd_write) + assert output.strip().decode('utf-8') == "" + + +def validate_file_content(pod, content, filename): + cmd_get_content = "/bin/bash -c 'cat {0}' ".format(filename) + if is_windows(): + cmd_get_content = 'powershell -NoLogo -NonInteractive -Command ' \ + '"& { cat {0} }"'.format(filename) + output = kubectl_pod_exec(pod, cmd_get_content) + assert output.strip().decode('utf-8') == content + + +def wait_for_mcapp_to_active(client, multiClusterApp, + timeout=DEFAULT_MULTI_CLUSTER_APP_TIMEOUT): + time.sleep(5) + # When the app is deployed it goes into Active state for a short + # period of time and then into installing/deploying. + mcapps = client.list_multiClusterApp(uuid=multiClusterApp.uuid, + name=multiClusterApp.name).data + start = time.time() + assert len(mcapps) == 1, "Cannot find multi cluster app" + mapp = mcapps[0] + while mapp.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + multiclusterapps = client.list_multiClusterApp( + uuid=multiClusterApp.uuid, name=multiClusterApp.name).data + assert len(multiclusterapps) == 1 + mapp = multiclusterapps[0] + return mapp + + +def wait_for_app_to_active(client, app_id, + timeout=DEFAULT_MULTI_CLUSTER_APP_TIMEOUT): + """ + First wait for app to come in deployment state, then wait for it get + in active state. This is to avoid wrongly conclude that app is active + as app goes to state installing > active > deploying > active + @param client: Project client + @param app_id: App id of deployed app. + @param timeout: Max time allowed to wait for app to become active. + @return: app object + """ + start = time.time() + app_data = client.list_app(id=app_id).data + while len(app_data) == 0: + if time.time() - start > timeout / 10: + raise AssertionError( + "Timed out waiting for listing the app from API") + time.sleep(.2) + app_data = client.list_app(id=app_id).data + + application = app_data[0] + while application.state != "deploying": + if time.time() - start > timeout / 3: + break + time.sleep(.2) + app_data = client.list_app(id=app_id).data + application = app_data[0] + while application.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for {0} to get to active," + " the actual state: {1}".format(application.name, + application.state)) + time.sleep(.5) + app = client.list_app(id=app_id).data + assert len(app) >= 1 + application = app[0] + return application + + +def wait_for_app_to_remove(client, app_id, + timeout=DEFAULT_MULTI_CLUSTER_APP_TIMEOUT): + start = time.time() + app_data = client.list_app(id=app_id).data + if len(app_data) == 0: + return + application = app_data[0] + while application.state == "removing" or application.state == "active": + if time.time() - start > timeout / 10: + raise AssertionError( + "Timed out waiting for app to not be installed") + time.sleep(.2) + app_data = client.list_app(id=app_id).data + if len(app_data) == 0: + break + application = app_data[0] + + +def validate_response_app_endpoint(p_client, appId, + timeout=DEFAULT_MULTI_CLUSTER_APP_TIMEOUT): + ingress_list = p_client.list_ingress(namespaceId=appId).data + assert len(ingress_list) == 1 + ingress = ingress_list[0] + if hasattr(ingress, 'publicEndpoints'): + for public_endpoint in ingress.publicEndpoints: + url = \ + public_endpoint["protocol"].lower() + "://" + \ + public_endpoint["hostname"] + print(url) + start = time.time() + try: + while True: + r = requests.head(url) + print(r.status_code) + if r.status_code == 200: + return + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting response to be 200.") + time.sleep(.5) + except requests.ConnectionError: + print("failed to connect") + assert False, "failed to connect to the app" + + +def resolve_node_ip(node): + if hasattr(node, 'externalIpAddress'): + node_ip = node.externalIpAddress + else: + node_ip = node.ipAddress + return node_ip + + +def provision_nfs_server(): + node = AmazonWebServices().create_node(random_test_name("nfs-server")) + node.wait_for_ssh_ready() + c_path = os.getcwd() + cmd_path = c_path + "/tests/v3_api/scripts/nfs-setup.sh" + command = open(cmd_path, 'r').read() + node.execute_command(command) + return node + + +def get_defaut_question_answers(client, externalId): + def get_answer(quest): + if "default" in quest.keys(): + answer = quest["default"] + else: + answer = "" + # If required and no default value is available, set fake value + # only for type string . For other types error out + if "required" in quest.keys(): + if quest["required"]: + if quest["type"] == "enum" and "options" in quest.keys(): + answer = quest["options"][0] + elif quest["type"] == "password": + answer = "R@ncher135" + elif quest["type"] == "string": + answer = "fake" + else: + assert False, \ + "Cannot set default for types {}" \ + "".format(quest["type"]) + return answer + + def check_if_question_needed(questions_and_answers, ques): + add_question = False + match_string = ques["showIf"] + match_q_as = match_string.split("&&") + for q_a in match_q_as: + items = q_a.split("=") + if len(items) == 1: + items.append("") + if items[0] in questions_and_answers.keys(): + if questions_and_answers[items[0]] == items[1]: + add_question = True + else: + add_question = False + break + return add_question + + questions_and_answers = {} + print("external id = {}".format(externalId)) + template_revs = client.list_template_version(externalId=externalId).data + assert len(template_revs) == 1 + template_rev = template_revs[0] + questions = template_rev.questions + for ques in questions: + add_question = True + if "showIf" in ques.keys(): + add_question = \ + check_if_question_needed(questions_and_answers, ques) + if add_question: + question = ques["variable"] + answer = get_answer(ques) + questions_and_answers[question] = get_answer(ques) + if "showSubquestionIf" in ques.keys(): + if ques["showSubquestionIf"] == answer: + sub_questions = ques["subquestions"] + for sub_question in sub_questions: + question = sub_question["variable"] + questions_and_answers[question] = \ + get_answer(sub_question) + print("questions_and_answers = {}".format(questions_and_answers)) + return questions_and_answers + + +def validate_app_deletion(client, app_id, + timeout=DEFAULT_APP_DELETION_TIMEOUT): + app_data = client.list_app(id=app_id).data + start = time.time() + if len(app_data) == 0: + return + application = app_data[0] + while application.state == "removing": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for app to delete") + time.sleep(.5) + app_data = client.list_app(id=app_id).data + if len(app_data) == 0: + break + application = app_data[0] + + +def validate_catalog_app(proj_client, app, external_id, answer=None): + """ + This method validates all the workloads deployed are in active state, + have correct version and validates the answers. + @param proj_client: Project client object of a existing project. + @param app: Deployed app object. + @param external_id: URl of app API. + @param answer: answer, app seek while deploying, body of the post call. + @return: Deployed app object. + """ + if answer is None: + answers = get_defaut_question_answers(get_user_client(), external_id) + else: + answers = answer + # validate app is active + app = wait_for_app_to_active(proj_client, app.id) + assert app.externalId == external_id, \ + "the version of the app is not correct" + # check if associated workloads are active + ns = app.targetNamespace + parameters = external_id.split('&') + assert len(parameters) > 1, \ + "Incorrect list of parameters from catalog external ID" + chart_prefix = parameters[len(parameters) - 2].split("=")[1] + chart_suffix = parameters[len(parameters) - 1].split("=")[1] + chart = chart_prefix + "-" + chart_suffix + app_name = parameters[len(parameters) - 2].split("=")[1] + workloads = proj_client.list_workload(namespaceId=ns).data + + # For longhorn app, only active state of workloads is verified as longhorn + # workloads do not have the field workloadLabels + # For all other apps active state of workloads & chart version are verified + if "longhorn" in app.externalId: + print("validating the Longhorn app, it may take longer than others") + for wl in workloads: + wait_for_wl_to_active(proj_client, wl) + else: + for wl in workloads: + print("Workload {} , state - {}".format(wl.id, wl.state)) + assert wl.state == "active" + chart_deployed = get_chart_info(wl.workloadLabels) + print("Chart detail of app - {}".format(chart_deployed)) + # '-' check is to make sure chart has both app name and version. + if app_name in chart_deployed and '-' in chart_deployed: + assert chart_deployed == chart, "the chart version is wrong" + # Validate_app_answers + assert len(answers.items() - app["answers"].items()) == 0, \ + "Answers are not same as the original catalog answers" + return app + + +def get_chart_info(workloadlabels): + """ + This method finds either 'chart' tag or + 'helm.sh/chart' tag from workload API + @param workloadlabels: workloadslabel object + @return: chart value of workload e.g. 'app_name-version' + """ + if "chart" in workloadlabels.keys(): + return workloadlabels.chart + elif "helm.sh/chart" in workloadlabels.keys(): + return workloadlabels["helm.sh/chart"] + else: + return '' + + +def create_user(client, cattle_auth_url=CATTLE_AUTH_URL): + user_name = random_name() + user = client.create_user(username=user_name, + password=USER_PASSWORD) + client.create_global_role_binding(globalRoleId="user", + subjectKind="User", + userId=user.id) + user_token = get_user_token(user.username, USER_PASSWORD, cattle_auth_url) + return user, user_token + + +def get_user_token(username, password, cattle_auth_url=CATTLE_AUTH_URL): + r = requests.post(cattle_auth_url, json={ + 'username': username, + 'password': password, + 'responseType': 'json', + }, verify=False) + print(r.json()) + return r.json()["token"] + + +def rbac_get_user_by_role(role): + if role in rbac_data["users"].keys(): + return rbac_data["users"][role]["user"] + return None + + +def rbac_get_user_token_by_role(role): + if role in rbac_data["users"].keys(): + return rbac_data["users"][role]["token"] + return None + + +def rbac_get_kubeconfig_by_role(role): + if role in rbac_data["users"].keys(): + return rbac_data["users"][role]["kubeconfig"] + return None + + +def rbac_get_project(): + return rbac_data["project"] + + +def rbac_get_namespace(): + return rbac_data["namespace"] + + +def rbac_get_workload(): + return rbac_data["workload"] + + +def rbac_get_unshared_project(): + return rbac_data["p_unshared"] + + +def rbac_get_unshared_ns(): + return rbac_data["ns_unshared"] + + +def rbac_get_unshared_workload(): + return rbac_data["wl_unshared"] + + +def rbac_prepare(): + """this function creates one project, one namespace, + and four users with different roles""" + admin_client, cluster = get_global_admin_client_and_cluster() + create_kubeconfig(cluster) + # create a new project in the cluster + project, ns = create_project_and_ns(ADMIN_TOKEN, + cluster, + random_test_name("p-test-rbac")) + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + p_client = get_project_client_for_token(project, ADMIN_TOKEN) + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + validate_workload(p_client, workload, "deployment", ns.name) + rbac_data["workload"] = workload + rbac_data["project"] = project + rbac_data["namespace"] = ns + # create new users + for key in rbac_data["users"]: + user1, token1 = create_user(admin_client) + rbac_data["users"][key]["user"] = user1 + rbac_data["users"][key]["token"] = token1 + + # assign different role to each user + assign_members_to_cluster(admin_client, + rbac_data["users"][CLUSTER_OWNER]["user"], + cluster, + CLUSTER_OWNER) + assign_members_to_cluster(admin_client, + rbac_data["users"][CLUSTER_MEMBER]["user"], + cluster, + CLUSTER_MEMBER) + assign_members_to_project(admin_client, + rbac_data["users"][PROJECT_MEMBER]["user"], + project, + PROJECT_MEMBER) + assign_members_to_project(admin_client, + rbac_data["users"][PROJECT_OWNER]["user"], + project, + PROJECT_OWNER) + assign_members_to_project(admin_client, + rbac_data["users"][PROJECT_READ_ONLY]["user"], + project, + PROJECT_READ_ONLY) + # create kubeconfig files for each user + for key in rbac_data["users"]: + user_client = get_client_for_token(rbac_data["users"][key]["token"]) + _, user_cluster = get_user_client_and_cluster(user_client) + rbac_data["users"][key]["kubeconfig"] = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + key + "_kubeconfig") + create_kubeconfig(user_cluster, rbac_data["users"][key]["kubeconfig"]) + + # create another project that none of the above users are assigned to + p2, ns2 = create_project_and_ns(ADMIN_TOKEN, + cluster, + random_test_name("p-unshared")) + name = random_test_name("default") + p_client = get_project_client_for_token(p2, ADMIN_TOKEN) + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns2.id) + validate_workload(p_client, workload, "deployment", ns2.name) + rbac_data["p_unshared"] = p2 + rbac_data["ns_unshared"] = ns2 + rbac_data["wl_unshared"] = workload + + +def rbac_cleanup(): + """ remove the project, namespace and users created for the RBAC tests""" + try: + client = get_admin_client() + except Exception: + print("Not able to get admin client. Not performing RBAC cleanup") + return + for _, value in rbac_data["users"].items(): + try: + client.delete(value["user"]) + except Exception: + pass + client.delete(rbac_data["project"]) + client.delete(rbac_data["wl_unshared"]) + client.delete(rbac_data["p_unshared"]) + + +def check_condition(condition_type, status): + def _find_condition(resource): + if not hasattr(resource, "conditions"): + return False + + if resource.conditions is None: + return False + + for condition in resource.conditions: + if condition.type == condition_type and condition.status == status: + return True + return False + + return _find_condition + + +def create_catalog_external_id(catalog_name, template, version, + project_cluster_id=None, catalog_type=None): + if catalog_type is None: + return "catalog://?catalog=" + catalog_name + \ + "&template=" + template + "&version=" + version + elif catalog_type == "project" or catalog_type == "cluster": + return "catalog://?catalog=" + project_cluster_id + "/" \ + + catalog_name + "&type=" + catalog_type \ + + "Catalog&template=" + template + "&version=" + version + + +def wait_for_catalog_active(client, catalog, timeout=DEFAULT_CATALOG_TIMEOUT): + time.sleep(2) + catalog_data = client.list_catalog(name=catalog.name) + print(catalog_data) + start = time.time() + assert len(catalog_data["data"]) >= 1, "Cannot find catalog" + catalog = catalog_data["data"][0] + while catalog.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + catalog_data = client.list_catalog(name=catalog.name) + assert len(catalog_data["data"]) >= 1 + catalog = catalog_data["data"][0] + return catalog + + +def readDataFile(data_dir, name): + fname = os.path.join(data_dir, name) + print("File: " + fname) + is_file = os.path.isfile(fname) + assert is_file + with open(fname) as f: + return f.read() + + +def set_url_password_token(rancher_url, server_url=None, version=""): + """Returns a ManagementContext for the default global admin user.""" + auth_url = \ + rancher_url + "/v3-public/localproviders/local?action=login" + rpassword = 'admin' + print(auth_url) + if "master" in version or \ + "2.6" in version or \ + "2.7" in version or \ + "2.8" in version or \ + "2.9" in version: + rpassword = ADMIN_PASSWORD + print("on 2.6 or later") + retries = 5 + for attempt in range(1, retries): + try: + r = requests.post(auth_url, json={ + 'username': 'admin', + 'password': rpassword, + 'responseType': 'json', + }, verify=False) + except requests.exceptions.RequestException: + print("password request failed. Retry attempt: ", + "{} of {}".format(attempt, retries)) + time.sleep(2) + else: + break + print(r.json()) + token = r.json()['token'] + print(token) + # Change admin password + client = rancher.Client(url=rancher_url + "/v3", + token=token, verify=False) + admin_user = client.list_user(username="admin").data + admin_user[0].setpassword(newPassword=ADMIN_PASSWORD) + + # Set server-url settings + serverurl = client.list_setting(name="server-url").data + if server_url: + client.update(serverurl[0], value=server_url) + else: + client.update(serverurl[0], value=rancher_url) + return token + + +def validate_create_catalog(token, catalog_name, branch, url, permission=True): + """ + This function validates if the user has the permission to create a + global catalog. + + :param token: user's token + :param catalog_name: the name of the catalog + :param branch: the branch of the git repo + :param url: the url of the git repo + :param permission: boolean value, True if the user can create catalog + :return: the catalog object or None + """ + client = get_client_for_token(token) + if not permission: + with pytest.raises(ApiError) as e: + client.create_catalog(name=catalog_name, + branch=branch, + url=url) + error_msg = "user with no permission should receive 403: Forbidden" + error_code = e.value.error.code + error_status = e.value.error.status + assert error_status == 403 and error_code == 'Forbidden', error_msg + return None + else: + try: + client.create_catalog(name=catalog_name, + branch=branch, + url=url) + except ApiError as e: + assert False, "user with permission should receive no exception:" \ + + str(e.error.status) + " " + e.error.code + + catalog_list = client.list_catalog(name=catalog_name).data + assert len(catalog_list) == 1 + return catalog_list[0] + + +def generate_template_global_role(name, new_user_default=False, template=None): + """ generate a template that is used for creating a global role""" + if template is None: + template = TEMPLATE_MANAGE_CATALOG + template = deepcopy(template) + if new_user_default: + template["newUserDefault"] = "true" + else: + template["newUserDefault"] = "false" + if name is None: + name = random_name() + template["name"] = name + return template + + +def wait_for_backup_to_active(cluster, backupname, + timeout=DEFAULT_TIMEOUT): + start = time.time() + timeout = start + timeout + etcdbackups = cluster.etcdBackups(name=backupname) + assert len(etcdbackups) == 1 + etcdbackupdata = etcdbackups['data'] + etcdbackupstate = etcdbackupdata[0]['state'] + while etcdbackupstate != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + etcdbackups = cluster.etcdBackups(name=backupname) + assert len(etcdbackups) == 1 + etcdbackupdata = etcdbackups['data'] + etcdbackupstate = etcdbackupdata[0]['state'] + print("BACKUP STATE") + print(etcdbackupstate) + return etcdbackupstate + + +def wait_for_backup_to_delete(cluster, backupname, + timeout=DEFAULT_TIMEOUT): + start = time.time() + etcdbackups = cluster.etcdBackups(name=backupname) + while len(etcdbackups) == 1: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for backup to be deleted") + time.sleep(.5) + etcdbackups = cluster.etcdBackups(name=backupname) + + +def validate_backup_create(namespace, backup_info, backup_mode=None): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + name = random_test_name("default") + + if not hasattr(cluster, 'rancherKubernetesEngineConfig'): + assert False, "Cluster is not of type RKE" + + con = [{"name": "test1", + "image": TEST_IMAGE}] + backup_info["workload"] = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, backup_info["workload"], "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + host = "test" + str(random_int(10000, 99999)) + ".com" + namespace["host"] = host + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [backup_info["workload"].id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(p_client, cluster, [backup_info["workload"]], host, path) + + # Perform Backup + user_client = get_user_client() + cluster = user_client.reload(cluster) + backup = cluster.backupEtcd() + backup_info["backupname"] = backup['metadata']['name'] + wait_for_backup_to_active(cluster, backup_info["backupname"]) + + # Get all the backup info + etcdbackups = cluster.etcdBackups(name=backup_info["backupname"]) + backup_info["etcdbackupdata"] = etcdbackups['data'] + backup_info["backup_id"] = backup_info["etcdbackupdata"][0]['id'] + + if backup_mode == "s3": + backupfileurl = backup_info["etcdbackupdata"][0]['filename'] + # Check the backup filename exists in S3 + parseurl = urlparse(backupfileurl) + backup_info["backupfilename"] = os.path.basename(parseurl.path) + backup_found = AmazonWebServices().s3_backup_check( + backup_info["backupfilename"]) + assert backup_found, "the backup was not found in the S3 bucket" + elif backup_mode == 'filesystem': + for node in namespace['nodes']: + if 'etcd' not in node.roles: + continue + get_filesystem_snapshots = 'ls /opt/rke/etcd-snapshots' + response = node.execute_command(get_filesystem_snapshots)[0] + assert backup_info["etcdbackupdata"][0]['filename'] in response, \ + "The filename doesn't match any of the files locally" + return namespace, backup_info + + +def validate_backup_restore(namespace, backup_info): + p_client = namespace["p_client"] + ns = namespace["ns"] + client = get_user_client() + cluster = namespace["cluster"] + name = random_test_name("default") + + host = namespace["host"] + path = "/name.html" + con = [{"name": "test1", + "image": TEST_IMAGE}] + + # Create workload after backup + testworkload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + + validate_workload(p_client, testworkload, "deployment", ns.name) + + # Perform Restore + cluster.restoreFromEtcdBackup(etcdBackupId=backup_info["backup_id"]) + # After restore, validate cluster + validate_cluster(client, cluster, intermediate_state="updating", + check_intermediate_state=True, + skipIngresscheck=False) + + # Verify the ingress created before taking the snapshot + validate_ingress(p_client, cluster, [backup_info["workload"]], host, path) + + # Verify the workload created after getting a snapshot does not exist + # after restore + workload_list = p_client.list_workload(uuid=testworkload.uuid).data + print(len(workload_list)) + assert len(workload_list) == 0, "workload shouldn't exist after restore" + return namespace, backup_info + + +def validate_backup_delete(namespace, backup_info, backup_mode=None): + client = get_user_client() + cluster = namespace["cluster"] + client.delete( + cluster.etcdBackups(name=backup_info["backupname"])['data'][0] + ) + wait_for_backup_to_delete(cluster, backup_info["backupname"]) + assert len(cluster.etcdBackups(name=backup_info["backupname"])) == 0, \ + "backup shouldn't be listed in the Cluster backups" + if backup_mode == "s3": + # Check the backup reference is deleted in Rancher and S3 + backup_found = AmazonWebServices().s3_backup_check( + backup_info["backupfilename"]) + assert_message = "The backup should't exist in the S3 bucket" + assert backup_found is False, assert_message + elif backup_mode == 'filesystem': + for node in namespace['nodes']: + if 'etcd' not in node.roles: + continue + get_filesystem_snapshots = 'ls /opt/rke/etcd-snapshots' + response = node.execute_command(get_filesystem_snapshots)[0] + filename = backup_info["etcdbackupdata"][0]['filename'] + assert filename not in response, \ + "The file still exist in the filesystem" + + +def apply_crd(ns, file, kubectl_context): + return execute_kubectl_cmd('apply -f ' + file + ' -n ' + ns.name, + json_out=False, stderr=True, + kubeconfig=kubectl_context).decode("ascii") + + +def get_crd(ns, crd_name, kubectl_context): + return execute_kubectl_cmd('get ' + crd_name + ' -n ' + ns.name, + json_out=False, stderr=True, + kubeconfig=kubectl_context).decode("ascii") + + +def delete_crd(ns, file, kubectl_context): + return execute_kubectl_cmd('delete -f ' + file + ' -n ' + ns.name, + json_out=False, stderr=True, + kubeconfig=kubectl_context).decode("ascii") + + +def prepare_auth_data(): + name = \ + os.path.join(os.path.dirname(os.path.realpath(__file__)) + "/resource", + AUTH_PROVIDER.lower() + ".json") + with open(name) as reader: + auth_data = reader.read() + raw = json.loads(auth_data).get("nested_group_info") + + nested_group["auth_info"] = raw.copy() + nested_group["users"] = raw.get("users") + raw.pop("users") + nested_group["group_dic"] = raw + nested_group["groups"] = raw.keys() + + +def is_nested(): + """ check if the provided groups are nested groups, + return True if at least one of the groups contains other groups + """ + count = 0 + for user, group in nested_group["group_dic"].items(): + if len(group) == 0: + count += 1 + if count < len(nested_group["group_dic"]): + return True + return False + + +def get_group(nested=False): + """ return a group or a nested group""" + if nested: + # return the name of a group that contains at least one other group + for item in nested_group["groups"]: + if len(nested_group["group_dic"].get(item).get("users")) == 0: + pass + sub_groups = nested_group["group_dic"].get(item).get("groups") + if len(sub_groups) == 0: + pass + for g in sub_groups: + if len(nested_group["group_dic"].get(g).get("users")) > 0: + return item + assert False, "cannot find any valid nested group" + + else: + # return the name of a group that has at least one direct user + for group in nested_group["groups"]: + if len(nested_group["group_dic"].get(group).get("users")) > 0: + return group + assert False, "cannot find any valid non-nested group" + + +def get_user_by_group(group, nested=False): + """ return the list of uses in the group or nested group + + if nested is False, return the direct users in the group; + otherwise, return all users including those from nested groups + """ + + def get_user_in_nested_group(group, source): + if group == "": + return [] + users = source["group_dic"].get(group).get("users") + for sub_group in source["group_dic"].get(group).get("groups"): + temp = get_user_in_nested_group(sub_group, source) + for user in temp: + if user not in users: + users.append(user) + return users + + if nested: + users = get_user_in_nested_group(group, nested_group) + assert len(users) > 0, "no user in the group" + else: + users = nested_group["group_dic"].get(group).get("users") + assert users is not None, "no user in the group" + print("group: {}, users: {}".format(group, users)) + return users + + +def get_a_group_and_a_user_not_in_it(nested=False): + """ return a group or a nested group and a user that is not in the group""" + all_users = nested_group["users"] + for group in nested_group["groups"]: + group_users = get_user_by_group(group, nested) + for user in all_users: + if user not in group_users: + print("group: {}, user not in it: {}".format(group, user)) + return group, user + assert False, "cannot find a group and a user not in it" + + +def get_group_principal_id(group_name, token=ADMIN_TOKEN, expected_status=200): + """ get the group's principal id from the auth provider""" + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_PRINCIPAL_URL, + json={'name': group_name, + 'principalType': 'group', + 'responseType': 'json'}, + verify=False, headers=headers) + assert r.status_code == expected_status + return r.json()['data'][0]["id"] + + +def login_as_auth_user(username, password, login_url=LOGIN_AS_AUTH_USER_URL): + """ login with the user account from the auth provider, + and return the user token""" + r = requests.post(login_url, json={ + 'username': username, + 'password': password, + 'responseType': 'json', + }, verify=False) + assert r.status_code in [200, 201] + return r.json() + + +def validate_service_discovery(workload, scale, + p_client=None, ns=None, testclient_pods=None): + expected_ips = [] + pods = p_client.list_pod(workloadId=workload["id"]).data + assert len(pods) == scale + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + host = '{0}.{1}.svc.cluster.local'.format(workload.name, ns.id) + for pod in testclient_pods: + validate_dns_entry(pod, host, expected_ips) + + +def auth_get_project(): + return auth_rbac_data["project"] + + +def auth_get_namespace(): + return auth_rbac_data["namespace"] + + +def auth_get_user_token(username): + if username in auth_rbac_data["users"].keys(): + return auth_rbac_data["users"][username].token + return None + + +def add_role_to_user(user, role): + """this function adds a user from the auth provider to given cluster""" + admin_client, cluster = get_global_admin_client_and_cluster() + project = auth_get_project() + ns = auth_get_namespace() + if not (project and ns): + project, ns = create_project_and_ns(ADMIN_TOKEN, cluster, + random_test_name("p-test-auth")) + auth_rbac_data["project"] = project + auth_rbac_data["namespace"] = ns + if role in [PROJECT_OWNER, PROJECT_MEMBER, PROJECT_READ_ONLY]: + assign_members_to_project(admin_client, user, project, role) + else: + assign_members_to_cluster(admin_client, user, cluster, role) + auth_rbac_data["users"][user.username] = user + + +def auth_resource_cleanup(): + """ remove the project and namespace created for the AUTH tests""" + client, cluster = get_global_admin_client_and_cluster() + client.delete(auth_rbac_data["project"]) + auth_rbac_data["project"] = None + auth_rbac_data["ns"] = None + for username, user in auth_rbac_data["users"].items(): + user_crtbs = client.list_cluster_role_template_binding(userId=user.id) + for crtb in user_crtbs: + client.delete(crtb) + + +class WebsocketLogParse: + """ + the class is used for receiving and parsing the message + received from the websocket + """ + + def __init__(self): + self.lock = Lock() + self._last_message = '' + + def receiver(self, socket, skip, b64=True): + """ + run a thread to receive and save the message from the web socket + :param socket: the socket connection + :param skip: if True skip the first char of the received message + """ + while True and socket.connected: + try: + data = socket.recv() + # the message from the kubectl contains an extra char + if skip: + data = data[1:] + if len(data) < 5: + pass + if b64: + data = base64.b64decode(data).decode() + self.lock.acquire() + self._last_message += data + self.lock.release() + except websocket.WebSocketConnectionClosedException: + print("Connection closed") + break + except websocket.WebSocketProtocolException as wpe: + print("Error: {}".format(wpe)) + break + + @staticmethod + def start_thread(target, args): + thread = Thread(target=target, args=args) + thread.daemon = True + thread.start() + time.sleep(1) + + @property + def last_message(self): + return self._last_message + + @last_message.setter + def last_message(self, value): + self.lock.acquire() + self._last_message = value + self.lock.release() + + +def wait_for_cluster_delete(client, cluster_name, timeout=DEFAULT_TIMEOUT): + start = time.time() + cluster = client.list_cluster(name=cluster_name).data + cluster_count = len(cluster) + while cluster_count != 0: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for cluster to get deleted") + time.sleep(.5) + cluster = client.list_cluster(name=cluster_name).data + cluster_count = len(cluster) + + +def create_connection(url, subprotocols): + """ + create a webscoket connection and check if it is connected + :param url: the url to connect to + :param subprotocols: the list of subprotocols + :return: + """ + ws = websocket.create_connection( + url=url, + sslopt={"cert_reqs": ssl.CERT_NONE}, + subprotocols=subprotocols, + timeout=20, + cookie="R_SESS=" + USER_TOKEN + ) + assert ws.connected, "failed to build the websocket" + return ws + + +def wait_for_hpa_to_active(client, hpa, timeout=DEFAULT_TIMEOUT): + start = time.time() + hpalist = client.list_horizontalPodAutoscaler(uuid=hpa.uuid).data + assert len(hpalist) == 1 + hpa = hpalist[0] + while hpa.state != "active": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to active") + time.sleep(.5) + hpas = client.list_horizontalPodAutoscaler(uuid=hpa.uuid).data + assert len(hpas) == 1 + hpa = hpas[0] + return hpa + + +def create_pv_pvc(client, ns, nfs_ip, cluster_client): + pv_object = create_pv(cluster_client, nfs_ip) + + pvc_name = random_test_name("pvc") + pvc_config = {"accessModes": ["ReadWriteOnce"], + "name": pvc_name, + "volumeId": pv_object.id, + "namespaceId": ns.id, + "storageClassId": "", + "resources": {"requests": {"storage": "10Gi"}} + } + pvc_object = client.create_persistent_volume_claim(pvc_config) + pvc_object = wait_for_pvc_to_be_bound(client, pvc_object, timeout=300) + + return pv_object, pvc_object + + +def create_pv(client, nfs_ip): + pv_name = random_test_name("pv") + pv_config = {"type": "persistentVolume", + "accessModes": ["ReadWriteOnce"], + "name": pv_name, + "nfs": {"readOnly": "false", + "type": "nfsvolumesource", + "path": NFS_SERVER_MOUNT_PATH, + "server": nfs_ip + }, + "capacity": {"storage": "50Gi"} + } + pv_object = client.create_persistent_volume(pv_config) + capacitydict = pv_object['capacity'] + assert capacitydict['storage'] == '50Gi' + assert pv_object['type'] == 'persistentVolume' + return pv_object + + +def delete_resource_in_AWS_by_prefix(resource_prefix): + """ + :param resource_prefix: the prefix of resource name + :return: None + """ + # delete nodes of both local and custom clusters + node_filter = [{ + 'Name': 'tag:Name', + 'Values': [resource_prefix + "-*"] + }] + nodes = AmazonWebServices().get_nodes(filters=node_filter) + if nodes is None: + print("deleting the following instances: None") + else: + print("deleting the following instances: {}" + .format([node.public_ip_address for node in nodes])) + AmazonWebServices().delete_nodes(nodes) + + # delete load balancer and target groups + tg_list = [] + lb_list = [] + lb_names = [resource_prefix + '-nlb', + resource_prefix + '-k3s-nlb', + resource_prefix + '-internal-nlb'] + for name in lb_names: + lb_arn = AmazonWebServices().get_lb(name) + if lb_arn is not None: + lb_list.append(lb_arn) + res = AmazonWebServices().get_target_groups(lb_arn) + tg_list.extend(res) + + print("deleting the following load balancers: {}".format(lb_list)) + print("deleting the following target groups: {}".format(tg_list)) + for lb in lb_list: + AmazonWebServices().delete_lb(lb) + for tg in tg_list: + AmazonWebServices().delete_target_group(tg) + + # delete rds + db_name = resource_prefix + "-db" + print("deleting the database (if it exists): {}".format(db_name)) + AmazonWebServices().delete_db(db_name) + + # delete the route 53 record + route53_names = [resource_prefix + ".qa.rancher.space.", + resource_prefix + "-internal.qa.rancher.space."] + for name in route53_names: + print("deleting the route53 record (if it exists): {}".format(name)) + AmazonWebServices().delete_route_53_record(name) + + print("deletion is done") + return None + + +def configure_cis_requirements(aws_nodes, profile, node_roles, client, + cluster): + prepare_hardened_nodes( + aws_nodes, profile, node_roles, client, cluster, True) + cluster = validate_cluster_state(client, cluster) + + # the workloads under System project to get active + time.sleep(20) + create_kubeconfig(cluster) + prepare_hardened_cluster('rke-cis-1.5', kube_fname) + return cluster + + +def get_node_details(cluster, client): + """ + lists the nodes from the cluster. This cluster has only 1 node. + :return: client and node object + """ + create_kubeconfig(cluster) + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) > 0 + for node in nodes: + if node.worker: + break + return client, node + + +def create_service_account_configfile(): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + name = random_name() + # create a service account + execute_kubectl_cmd(cmd="create sa {}".format(name), json_out=False) + # get the ca and token + res = execute_kubectl_cmd(cmd="get secret -o name", json_out=False) + secret_name = "" + for item in res.split("\n"): + if name in item: + secret_name = item.split("/")[1] + break + res = execute_kubectl_cmd(cmd="get secret {}".format(secret_name)) + ca = res["data"]["ca.crt"] + token = res["data"]["token"] + token = base64.b64decode(token).decode() + + server = None + nodes = client.list_node(clusterId=cluster.id).data + for node in nodes: + if node.controlPlane: + server = "https://" + node.externalIpAddress + ":6443" + break + assert server is not None, 'failed to get the public ip of control plane' + + config = """ + apiVersion: v1 + kind: Config + clusters: + - name: test-cluster + cluster: + server: {server} + certificate-authority-data: {ca} + contexts: + - name: default-context + context: + cluster: test-cluster + namespace: default + user: test-user + current-context: default-context + users: + - name: test-user + user: + token: {token} + """ + config = config.format(server=server, ca=ca, token=token) + config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), + name + ".yaml") + with open(config_file, "w") as file: + file.write(config) + + return name + + +def rbac_test_file_reader(file_path=None): + """ + This method generates test cases from an input file and return the result + that can be used to parametrize pytest cases + :param file_path: the path to the JSON file for test cases + :return: a list of tuples of + (cluster_role, command, authorization, service account name) + """ + if test_rbac_v2 == "False": + return [] + + if file_path is None: + pytest.fail("no file is provided") + with open(file_path) as reader: + test_cases = json.loads(reader.read().replace("{resource_root}", + DATA_SUBDIR)) + output = [] + for cluster_role, checks in test_cases.items(): + # create a service account for each role + name = create_service_account_configfile() + # create the cluster role binding + cmd = "create clusterrolebinding {} " \ + "--clusterrole {} " \ + "--serviceaccount {}".format(name, cluster_role, + "default:" + name) + execute_kubectl_cmd(cmd, json_out=False) + for command in checks["should_pass"]: + output.append((cluster_role, command, True, name)) + for command in checks["should_fail"]: + output.append((cluster_role, command, False, name)) + + return output + + +def validate_cluster_role_rbac(cluster_role, command, authorization, name): + """ + This methods creates a new service account to validate the permissions + both before and after creating the cluster role binding between the + service account and the cluster role + :param cluster_role: the cluster role + :param command: the kubectl command to run + :param authorization: if the service account has the permission: True/False + :param name: the name of the service account, cluster role binding, and the + kubeconfig file + """ + + config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), + name + ".yaml") + result = execute_kubectl_cmd(command, + json_out=False, + kubeconfig=config_file, + stderr=True).decode('utf_8') + if authorization: + assert "Error from server (Forbidden)" not in result, \ + "{} should have the authorization to run {}".format(cluster_role, + command) + else: + assert "Error from server (Forbidden)" in result, \ + "{} should NOT have the authorization to run {}".format( + cluster_role, command) + + +def wait_until_app_v2_deployed(client, app_name, timeout=DEFAULT_APP_V2_TIMEOUT): + """ + List all installed apps and check for the state of "app_name" to see + if it == "deployed" + :param client: cluster client for the user + :param app_name: app which is being installed + :param timeout: time for the app to come to Deployed state + :return: + """ + start = time.time() + app = client.list_catalog_cattle_io_app() + while True: + app_list = [] + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to Deployed") + time.sleep(.5) + for app in app["data"]: + app_list.append(app["metadata"]["name"]) + if app["metadata"]["name"] == app_name: + if app["status"]["summary"]["state"] == "deployed": + return app_list + app = client.list_catalog_cattle_io_app() + return + + +def wait_until_app_v2_uninstall(client, app_name, timeout=DEFAULT_APP_V2_TIMEOUT): + """ + list all installed apps. search for "app_name" in the list + if app_name is NOT in list, indicates the app has been uninstalled successfully + :param client: cluster client for the user + :param app_name: app which is being unstalled + :param timeout: time for app to be uninstalled + """ + start = time.time() + app = client.list_catalog_cattle_io_app() + while True: + app_list = [] + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state to get to Uninstalled") + time.sleep(.5) + for app in app["data"]: + app_list.append(app["metadata"]["name"]) + if app_name not in app_list: + return app_list + app = client.list_catalog_cattle_io_app() + return + + +def check_v2_app_and_uninstall(client, chart_name): + app = client.list_catalog_cattle_io_app() + for app in app["data"]: + if app["metadata"]["name"] == chart_name: + response = client.action(obj=app, action_name="uninstall") + app_list = wait_until_app_v2_uninstall(client, chart_name) + assert chart_name not in app_list, \ + "App has not uninstalled" + + +def update_and_validate_kdm(kdm_url, admin_token=ADMIN_TOKEN, + rancher_api_url=CATTLE_API_URL): + print("Updating KDM to use {}".format(kdm_url)) + header = {'Authorization': 'Bearer ' + admin_token} + api_url = rancher_api_url + "/settings/rke-metadata-config" + kdm_json = { + "name": "rke-metadata-config", + "value": json.dumps({ + "refresh-interval-minutes": "1440", + "url": kdm_url + }) + } + r = requests.put(api_url, verify=False, headers=header, json=kdm_json) + r_content = json.loads(r.content) + assert r.ok + assert r_content['name'] == kdm_json['name'] + assert r_content['value'] == kdm_json['value'] + time.sleep(2) + + # Refresh Kubernetes Metadata + kdm_refresh_url = rancher_api_url + "/kontainerdrivers?action=refresh" + response = requests.post(kdm_refresh_url, verify=False, headers=header) + assert response.ok + + +def prepare_hardened_nodes(aws_nodes, profile, node_roles, + client=None, cluster=None, custom_cluster=False): + i = 0 + conf_file = DATA_SUBDIR + "/sysctl-config" + if profile == 'rke-cis-1.4': + for aws_node in aws_nodes: + file1 = open(conf_file, 'r') + while True: + line = file1.readline() + if not line: + break + aws_node.execute_command(line.strip()) + if "etcd" in node_roles[i]: + aws_node.execute_command("sudo useradd etcd") + if custom_cluster: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, + cluster, + node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + elif profile == 'rke-cis-1.5': + for aws_node in aws_nodes: + file1 = open(conf_file, 'r') + while True: + line = file1.readline() + if not line: + break + aws_node.execute_command(line.strip()) + if "etcd" in node_roles[i]: + aws_node.execute_command("sudo groupadd -g 52034 etcd") + aws_node.execute_command("sudo useradd -u 52034 -g 52034 etcd") + if custom_cluster: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, + cluster, + node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + time.sleep(5) + file1.close() + return aws_nodes + + +def prepare_hardened_cluster(profile, kubeconfig_path): + if profile == 'rke-cis-1.5': + network_policy_file = DATA_SUBDIR + "/default-allow-all.yaml" + account_update_file = DATA_SUBDIR + "/account_update.yaml" + items = execute_kubectl_cmd("get namespaces -A", + kubeconfig=kubeconfig_path)["items"] + all_ns = [item["metadata"]["name"] for item in items] + for ns in all_ns: + execute_kubectl_cmd("apply -f {0} -n {1}". + format(network_policy_file, ns), + kubeconfig=kubeconfig_path) + execute_kubectl_cmd('patch serviceaccount default' + ' -n {0} -p "$(cat {1})"'. + format(ns, account_update_file), + kubeconfig=kubeconfig_path) + + +def print_kubeconfig(kpath): + kubeconfig_file = open(kpath, "r") + kubeconfig_contents = kubeconfig_file.read() + kubeconfig_file.close() + kubeconfig_contents_encoded = base64.b64encode( + kubeconfig_contents.encode("utf-8")).decode("utf-8") + print("\n\n" + kubeconfig_contents + "\n\n") + print("\nBase64 encoded: \n\n" + kubeconfig_contents_encoded + "\n\n") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/conftest.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/conftest.py new file mode 100644 index 0000000..8c02427 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/conftest.py @@ -0,0 +1,47 @@ +import urllib3 +from .common import * # NOQA + +# This stops ssl warnings for insecure certs +urllib3.disable_warnings() + + +def pytest_configure(config): + if TEST_RBAC and CATTLE_TEST_URL: + rbac_prepare() + if AUTH_PROVIDER != "": + prepare_auth_data() + + +def pytest_unconfigure(config): + if TEST_RBAC and CATTLE_TEST_URL: + rbac_cleanup() + + +@pytest.fixture +def remove_resource(request): + """Remove a resource after a test finishes even if the test fails. + + How to use: + pass this function as an argument of your testing function, + then call this function with the new resource as argument after + creating any new resource + + """ + + client = get_admin_client() + + def _cleanup(resource): + def clean(): + try: + client.delete(resource) + except ApiError as e: + code = e.error.status + if code == 409 and "namespace will automatically be purged " \ + in e.error.message: + pass + elif code != 404: + raise e + + request.addfinalizer(clean) + + return _cleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/account_update.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/account_update.yaml new file mode 100644 index 0000000..7db6b9e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/account_update.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: default +automountServiceAccountToken: false diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/activedirectory.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/activedirectory.json new file mode 100644 index 0000000..f02710e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/activedirectory.json @@ -0,0 +1,104 @@ +{ + "admin_user": "testautoadmin", + "standard_user": "testautouser", + "allowed_users": [ + "testauto2" + ], + "allowed_groups": [ + "testautogroup3" + ], + "allowed_nestedgroups": [ + "testautogroupnested1" + ], + "users_under_nestedgroups": [ + "testauto2", + "testauto5", + "testauto3", + "testauto4" + ], + "dis_allowed_users": [ + "testauto3", + "testauto4" + ], + "dis_allowed_groups": [ + "testautogroup4" + ], + "groups_added_to_cluster": [ + "testautogroup1" + ], + "groups_added_to_project": [ + "testautogroup2" + ], + "users_added_to_cluster": [ + "testauto5" + ], + "users_added_to_project": [ + "testauto6" + ], + "testautogroup1": [ + "testauto1", + "testauto2" + ], + "testautogroup2": [ + "testauto3", + "testauto4" + ], + "testautogroup3": [ + "testauto5", + "testauto6" + ], + "testautogroup4": [ + "testauto7", + "testauto8" + ], + "testautogroupnested1": [ + "testauto1" + ], + "specialchar_in_username": [ + "testauto(san)&abc" + ], + "specialchar_in_password": [ + "test1" + ], + "specialchar_in_userdn": [ + "craigcomma", + "firstcomma" + ], + "specialchar_in_groupname": [ + "test(group&)abc" + ], + "test(group&)abc": [ + "testcommagroup", + "testuser1", + "test(san)&abc" + ], + "nested_group_info": { + "users": [ + "nestedtestuser1", + "nestedtestuser2", + "nestedtestuser3" + ], + "nestgroup1": { + "users": [ + "nestedtestuser1" + ], + "groups": [ + "nestgroup2" + ] + }, + "nestgroup2": { + "users": [ + "nestedtestuser2" + ], + "groups": [ + "nestgroup3" + ] + }, + "nestgroup3": { + "users": [ + "nestedtestuser3" + ], + "groups": [] + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/docker-compose.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/docker-compose.yml new file mode 100644 index 0000000..018853a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/docker-compose.yml @@ -0,0 +1,16 @@ +web: + image: nginx + ports: + - 443:443 + + links: + - registry:registry + volumes: + - ./nginx_config:/etc/nginx/conf.d/ + +registry: + # v2.6 is needed to support Windoes images in the registry, otherwise will get 500 Internal Server Error + image: registry:2.6 + ports: + - 127.0.0.1:5000:5000 + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/nginx_config/nginx.conf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/nginx_config/nginx.conf new file mode 100644 index 0000000..f637cd6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/basic-registry/nginx_config/nginx.conf @@ -0,0 +1,38 @@ +upstream docker-registry { + server registry:5000; +} + +server { + listen 443 ssl; + server_name _; + + # SSL + ssl_certificate /etc/nginx/conf.d/domain.crt; + ssl_certificate_key /etc/nginx/conf.d/domain.key; + + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) + chunked_transfer_encoding on; + + location /v2/ { + # Do not allow connections from docker 1.5 and earlier + # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents + if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { + return 404; + } + + # To add basic authentication to v2 use auth_basic setting plus add_header + auth_basic "registry.localhost"; + auth_basic_user_file /etc/nginx/conf.d/registry.password; + add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always; + + proxy_pass http://docker-registry; + proxy_set_header Host $http_host; # required for docker client's sake + proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 900; + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_body.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_body.yaml new file mode 100644 index 0000000..8487b05 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_body.yaml @@ -0,0 +1,6 @@ + user: ubuntu + role: + - controlplane + - etcd + - worker + ssh_key_path: /home/ubuntu/jenkins-elliptic-validation.pem \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_end.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_end.yaml new file mode 100644 index 0000000..2bebe92 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/config_yamls/config_end.yaml @@ -0,0 +1,7 @@ + +snapshot: true +creation: 6h +retention: 24h +private_registries: +- url: {} + is_default: true \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/registries.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/registries.yaml new file mode 100644 index 0000000..1b001ca --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/airgap/registries.yaml @@ -0,0 +1,15 @@ +--- +mirrors: + docker.io: + endpoint: + - "https://$PRIVATE_REG" + k8s.gcr.io: + endpoint: + - "https://$PRIVATE_REG" +configs: + "$PRIVATE_REG": + auth: + username: $USERNAME + password: $PASSWORD + tls: + ca_file: /home/ubuntu/ca.pem \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/aks_nlb.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/aks_nlb.yml new file mode 100644 index 0000000..b80c8d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/aks_nlb.yml @@ -0,0 +1,639 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + name: ingress-nginx +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resourceNames: + - ingress-controller-leader + resources: + - configmaps + verbs: + - get + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create +- apiGroups: + - coordination.k8s.io + resourceNames: + - ingress-controller-leader + resources: + - leases + verbs: + - get + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets + - namespaces + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +rules: +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: v1 +data: + allow-snippet-annotations: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + externalTrafficPolicy: Local + ports: + - appProtocol: http + name: http + port: 80 + protocol: TCP + targetPort: http + - appProtocol: https + name: https + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: LoadBalancer +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller-admission + namespace: ingress-nginx +spec: + ports: + - appProtocol: https + name: https-webhook + port: 443 + targetPort: webhook + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + minReadySeconds: 0 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + template: + metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + spec: + containers: + - args: + - /nginx-ingress-controller + - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller + - --election-id=ingress-controller-leader + - --controller-class=k8s.io/ingress-nginx + - --ingress-class=nginx + - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller + - --validating-webhook=:8443 + - --validating-webhook-certificate=/usr/local/certificates/cert + - --validating-webhook-key=/usr/local/certificates/key + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: controller + ports: + - containerPort: 80 + name: http + protocol: TCP + - containerPort: 443 + name: https + protocol: TCP + - containerPort: 8443 + name: webhook + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 90Mi + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 + volumeMounts: + - mountPath: /usr/local/certificates/ + name: webhook-cert + readOnly: true + dnsPolicy: ClusterFirst + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: ingress-nginx + terminationGracePeriodSeconds: 300 + volumes: + - name: webhook-cert + secret: + secretName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + spec: + containers: + - args: + - create + - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc + - --namespace=$(POD_NAMESPACE) + - --secret-name=ingress-nginx-admission + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: create + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + spec: + containers: + - args: + - patch + - --webhook-name=ingress-nginx-admission + - --namespace=$(POD_NAMESPACE) + - --patch-mutating=false + - --secret-name=ingress-nginx-admission + - --patch-failure-policy=Fail + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: patch + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: nginx +spec: + controller: k8s.io/ingress-nginx +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: ingress-nginx-controller-admission + namespace: ingress-nginx + path: /networking/v1/ingresses + failurePolicy: Fail + matchPolicy: Equivalent + name: validate.nginx.ingress.kubernetes.io + rules: + - apiGroups: + - networking.k8s.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - ingresses + sideEffects: None \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/appvalues.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/appvalues.yaml new file mode 100644 index 0000000..4ad261c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/appvalues.yaml @@ -0,0 +1,41 @@ +--- + defaultImage: true + image: + repository: "ranchercharts/chartmuseum-chartmuseum" + tag: "v0.9.0" + env: + open: + STORAGE: "local" + STORAGE_AMAZON_BUCKET: "" + STORAGE_AMAZON_PREFIX: "" + STORAGE_AMAZON_REGION: "" + STORAGE_ALIBABA_BUCKET: "" + STORAGE_ALIBABA_ENDPOINT: "" + STORAGE_ALIBABA_PREFIX: "" + STORAGE_GOOGLE_BUCKET: "" + STORAGE_GOOGLE_PREFIX: "" + STORAGE_MICROSOFT_CONTAINER: "" + STORAGE_MICROSOFT_PREFIX: "" + STORAGE_OPENSTACK_CONTAINER: "" + STORAGE_OPENSTACK_PREFIX: "" + STORAGE_OPENSTACK_REGION: "" + SHOW_ADVANCED: false + CHART_URL: "" + DEPTH: "0" + ALLOW_OVERWRITE: false + AUTH_ANONYMOUS_GET: false + DISABLE_METRICS: true + existingSecret: "" + fakevar: "fakeval" + persistence: + enabled: false + size: "10Gi" + storageClass: "" + existingClaim: "" + ingress: + enabled: false + hosts: + - + name: "xip.io" + service: + type: "NodePort" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cataloglib_appversion.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cataloglib_appversion.json new file mode 100644 index 0000000..314b467 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cataloglib_appversion.json @@ -0,0 +1,29 @@ +{ + "artifactory-jcr": "0.1.0", + "chartmuseum": "2.3.1", + "citrix-k8s-cpx-ingress-controller": "1.6.1", + "citrix-k8s-ingress-controller": "1.6.1", + "datadog": "1.33.0", + "docker-registry": "1.8.1", + "drone": "2.0.7", + "efk": "7.3.0", + "etcd-operator": "0.9.0", + "fluentd-aggregator": "0.3.1", + "grafana": "3.8.6", + "hadoop": "1.1.1", + "harbor": "1.2.0", + "instana-agent": "1.0.16", + "magento": "5.1.4", + "mariadb": "6.7.4", + "memcached" : "2.9.0", + "mongodb-replicaset" : "3.9.6", + "mongodb": "7.2.6", + "mysql": "1.3.1", + "openebs": "1.6.0", + "prometheus": "9.1.0", + "redis": "9.0.2", + "redskyops": "0.1.2", + "traefik": "1.0.0", + "vault-operator": "0.1.3", + "wordpress": "7.3.8" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster-ha.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster-ha.yml new file mode 100644 index 0000000..f111863 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster-ha.yml @@ -0,0 +1,70 @@ +ssh_key_path: .ssh/$AWS_SSH_KEY_NAME +kubernetes_version: $KUBERNETES_VERSION +nodes: + - address: $ip1 + internal_address: $internalIp1 + user: $user1 + role: [etcd, controlplane,worker] + - address: $ip2 + internal_address: $internalIp2 + user: $user2 + role: [etcd, controlplane,worker] + - address: $ip3 + internal_address: $internalIp3 + user: $user3 + role: [etcd, controlplane,worker] +services: + kube-api: + admission_configuration: + apiVersion: apiserver.config.k8s.io/v1 + kind: AdmissionConfiguration + plugins: + - name: PodSecurity + configuration: + apiVersion: pod-security.admission.config.k8s.io/v1beta1 + kind: PodSecurityConfiguration + defaults: + enforce: restricted + enforce-version: latest + exemptions: + namespaces: + - cattle-provisioning-capi-system + - calico-apiserver + - calico-system + - cattle-alerting + - cattle-csp-adapter-system + - cattle-elemental-system + - cattle-epinio-system + - cattle-externalip-system + - cattle-fleet-local-system + - cattle-fleet-system + - cattle-gatekeeper-system + - cattle-global-data + - cattle-global-nt + - cattle-impersonation-system + - cattle-istio + - cattle-istio-system + - cattle-logging + - cattle-logging-system + - cattle-monitoring-system + - cattle-neuvector-system + - cattle-prometheus + - cattle-resources-system + - cattle-sriov-system + - cattle-system + - cattle-ui-plugin-system + - cattle-windows-gmsa-system + - cert-manager + - cis-operator-system + - fleet-default + - ingress-nginx + - istio-system + - kube-node-lease + - kube-public + - kube-system + - longhorn-system + - rancher-alerting-drivers + - security-scan + - tigera-operator + runtimeClasses: [] + usernames: [] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster.yml new file mode 100644 index 0000000..374a39f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/cluster.yml @@ -0,0 +1,54 @@ +ssh_key_path: .ssh/$AWS_SSH_KEY_NAME +kubernetes_version: $KUBERNETES_VERSION +auth: + strategy: x509 +nodes: + - address: $ip0 + internal_address: $intip0 + user: ubuntu + role: [etcd, controlplane,worker] + - address: $ip1 + internal_address: $intip1 + user: ubuntu + role: [etcd, controlplane,worker] + - address: $ip2 + internal_address: $intip2 + user: ubuntu + role: [etcd, controlplane,worker] +services: + kube-api: + admission_configuration: + apiVersion: apiserver.config.k8s.io/v1 + kind: AdmissionConfiguration + plugins: + - name: PodSecurity + configuration: + apiVersion: pod-security.admission.config.k8s.io/v1beta1 + kind: PodSecurityConfiguration + defaults: + enforce: restricted + enforce-version: latest + exemptions: + namespaces: + - ingress-nginx + - kube-system + - cattle-system + - cattle-epinio-system + - cattle-fleet-system + - longhorn-system + - cattle-neuvector-system + - cattle-monitoring-system + - rancher-alerting-drivers + - cis-operator-system + - cattle-csp-adapter-system + - cattle-externalip-system + - cattle-gatekeeper-system + - istio-system + - cattle-istio-system + - cattle-logging-system + - cattle-windows-gmsa-system + - cattle-sriov-system + - cattle-ui-plugin-system + - tigera-operator + runtimeClasses: [] + usernames: [] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/default-allow-all.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/default-allow-all.yaml new file mode 100644 index 0000000..80e26dc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/default-allow-all.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-allow-all +spec: + podSelector: {} + ingress: + - {} + egress: + - {} + policyTypes: + - Ingress + - Egress diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/eks_nlb.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/eks_nlb.yml new file mode 100644 index 0000000..b80c8d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/eks_nlb.yml @@ -0,0 +1,639 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + name: ingress-nginx +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resourceNames: + - ingress-controller-leader + resources: + - configmaps + verbs: + - get + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create +- apiGroups: + - coordination.k8s.io + resourceNames: + - ingress-controller-leader + resources: + - leases + verbs: + - get + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets + - namespaces + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +rules: +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: v1 +data: + allow-snippet-annotations: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + externalTrafficPolicy: Local + ports: + - appProtocol: http + name: http + port: 80 + protocol: TCP + targetPort: http + - appProtocol: https + name: https + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: LoadBalancer +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller-admission + namespace: ingress-nginx +spec: + ports: + - appProtocol: https + name: https-webhook + port: 443 + targetPort: webhook + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + minReadySeconds: 0 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + template: + metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + spec: + containers: + - args: + - /nginx-ingress-controller + - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller + - --election-id=ingress-controller-leader + - --controller-class=k8s.io/ingress-nginx + - --ingress-class=nginx + - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller + - --validating-webhook=:8443 + - --validating-webhook-certificate=/usr/local/certificates/cert + - --validating-webhook-key=/usr/local/certificates/key + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: controller + ports: + - containerPort: 80 + name: http + protocol: TCP + - containerPort: 443 + name: https + protocol: TCP + - containerPort: 8443 + name: webhook + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 90Mi + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 + volumeMounts: + - mountPath: /usr/local/certificates/ + name: webhook-cert + readOnly: true + dnsPolicy: ClusterFirst + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: ingress-nginx + terminationGracePeriodSeconds: 300 + volumes: + - name: webhook-cert + secret: + secretName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + spec: + containers: + - args: + - create + - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc + - --namespace=$(POD_NAMESPACE) + - --secret-name=ingress-nginx-admission + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: create + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + spec: + containers: + - args: + - patch + - --webhook-name=ingress-nginx-admission + - --namespace=$(POD_NAMESPACE) + - --patch-mutating=false + - --secret-name=ingress-nginx-admission + - --patch-failure-policy=Fail + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: patch + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: nginx +spec: + controller: k8s.io/ingress-nginx +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: ingress-nginx-controller-admission + namespace: ingress-nginx + path: /networking/v1/ingresses + failurePolicy: Fail + matchPolicy: Equivalent + name: validate.nginx.ingress.kubernetes.io + rules: + - apiGroups: + - networking.k8s.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - ingresses + sideEffects: None \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/freeipa.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/freeipa.json new file mode 100644 index 0000000..194769a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/freeipa.json @@ -0,0 +1,100 @@ +{ + "admin_user": "testautoadmin", + "standard_user": "testautouser", + "allowed_users": [ + "testauto2" + ], + "allowed_groups": [ + "testautogroup3" + ], + "allowed_nestedgroups": [ + "testautogroupnested1" + ], + "users_under_nestedgroups": [ + "testauto2", + "testauto5", + "testauto3", + "testauto4" + ], + "dis_allowed_users": [ + "testauto3", + "testauto4" + ], + "dis_allowed_groups": [ + "testautogroup4" + ], + "groups_added_to_cluster": [ + "testautogroup1" + ], + "groups_added_to_project": [ + "testautogroup2" + ], + "users_added_to_cluster": [ + "testauto5" + ], + "users_added_to_project": [ + "testauto6" + ], + "testautogroup1": [ + "testauto1", + "testauto2" + ], + "testautogroup2": [ + "testauto3", + "testauto4" + ], + "testautogroup3": [ + "testauto5", + "testauto6" + ], + "testautogroup4": [ + "testauto7", + "testauto8" + ], + "testautogroupnested1": [ + "testauto1" + ], + "specialchar_in_users": [ + "testauto20$", + "testauto21", + "testauto22" + ], + "specialchar_in_password": [ + "testuser23" + ], + "specialchar_in_groupname": [ + "specialgroup1-_.$" + ], + "specialgroup1-_.$": [ + "testauto25" + ], + "nested_group_info": { + "users": [ + "nestedtestuser1", + "nestedtestuser2", + "nestedtestuser3" + ], + "nestgroup1": { + "users": [ + "nestedtestuser1" + ], + "groups": [ + "nestgroup2" + ] + }, + "nestgroup2": { + "users": [ + "nestedtestuser2" + ], + "groups": [ + "nestgroup3" + ] + }, + "nestgroup3": { + "users": [ + "nestedtestuser3" + ], + "groups": [] + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/gke_nlb.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/gke_nlb.yml new file mode 100644 index 0000000..b80c8d2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/gke_nlb.yml @@ -0,0 +1,639 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + name: ingress-nginx +--- +apiVersion: v1 +automountServiceAccountToken: true +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resourceNames: + - ingress-controller-leader + resources: + - configmaps + verbs: + - get + - update +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create +- apiGroups: + - coordination.k8s.io + resourceNames: + - ingress-controller-leader + resources: + - leases + verbs: + - get + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +rules: +- apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets + - namespaces + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - get +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +rules: +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx +subjects: +- kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ingress-nginx-admission +subjects: +- kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +--- +apiVersion: v1 +data: + allow-snippet-annotations: "true" +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + externalTrafficPolicy: Local + ports: + - appProtocol: http + name: http + port: 80 + protocol: TCP + targetPort: http + - appProtocol: https + name: https + port: 443 + protocol: TCP + targetPort: https + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: LoadBalancer +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller-admission + namespace: ingress-nginx +spec: + ports: + - appProtocol: https + name: https-webhook + port: 443 + targetPort: webhook + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +spec: + minReadySeconds: 0 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + template: + metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + spec: + containers: + - args: + - /nginx-ingress-controller + - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller + - --election-id=ingress-controller-leader + - --controller-class=k8s.io/ingress-nginx + - --ingress-class=nginx + - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller + - --validating-webhook=:8443 + - --validating-webhook-certificate=/usr/local/certificates/cert + - --validating-webhook-key=/usr/local/certificates/key + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + image: registry.k8s.io/ingress-nginx/controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + name: controller + ports: + - containerPort: 80 + name: http + protocol: TCP + - containerPort: 443 + name: https + protocol: TCP + - containerPort: 8443 + name: webhook + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + requests: + cpu: 100m + memory: 90Mi + securityContext: + allowPrivilegeEscalation: true + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 + volumeMounts: + - mountPath: /usr/local/certificates/ + name: webhook-cert + readOnly: true + dnsPolicy: ClusterFirst + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: ingress-nginx + terminationGracePeriodSeconds: 300 + volumes: + - name: webhook-cert + secret: + secretName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-create + spec: + containers: + - args: + - create + - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc + - --namespace=$(POD_NAMESPACE) + - --secret-name=ingress-nginx-admission + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: create + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + namespace: ingress-nginx +spec: + template: + metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission-patch + spec: + containers: + - args: + - patch + - --webhook-name=ingress-nginx-admission + - --namespace=$(POD_NAMESPACE) + - --patch-mutating=false + - --secret-name=ingress-nginx-admission + - --patch-failure-policy=Fail + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660 + imagePullPolicy: IfNotPresent + name: patch + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux + restartPolicy: OnFailure + securityContext: + fsGroup: 2000 + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: nginx +spec: + controller: k8s.io/ingress-nginx +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/component: admission-webhook + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: ingress-nginx-controller-admission + namespace: ingress-nginx + path: /networking/v1/ingresses + failurePolicy: Fail + matchPolicy: Equivalent + name: validate.nginx.ingress.kubernetes.io + rules: + - apiGroups: + - networking.k8s.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - ingresses + sideEffects: None \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/hardened-cluster.yml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/hardened-cluster.yml new file mode 100644 index 0000000..143f323 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/hardened-cluster.yml @@ -0,0 +1,253 @@ +services: + etcd: + image: "" + extra_args: {} + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] + external_urls: [] + ca_cert: "" + cert: "" + key: "" + path: "" + uid: 52034 + gid: 52034 + snapshot: true + retention: "" + creation: "" + backup_config: null + kube-api: + image: "" + extra_args: {} + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] + service_cluster_ip_range: "" + service_node_port_range: "" + pod_security_policy: true + always_pull_images: false + secrets_encryption_config: + enabled: true + custom_config: null + audit_log: + enabled: true + configuration: null + admission_configuration: null + event_rate_limit: + enabled: true + configuration: null + kube-controller: + image: "" + extra_args: + feature-gates: RotateKubeletServerCertificate=true + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] + cluster_cidr: "" + service_cluster_ip_range: "" + scheduler: + image: "" + extra_args: {} + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] + kubelet: + image: "" + extra_args: + feature-gates: RotateKubeletServerCertificate=true + protect-kernel-defaults: "true" + tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256 + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] + cluster_domain: cluster.local + infra_container_image: "" + cluster_dns_server: "" + fail_swap_on: false + generate_serving_certificate: true + kubeproxy: + image: "" + extra_args: {} + extra_binds: [] + extra_env: [] + win_extra_args: {} + win_extra_binds: [] + win_extra_env: [] +network: + plugin: "" + options: {} + mtu: 0 + node_selector: {} + update_strategy: null +authentication: + strategy: "" + sans: [] + webhook: null +addons: | + apiVersion: policy/v1beta1 + kind: PodSecurityPolicy + metadata: + name: restricted + spec: + requiredDropCapabilities: + - NET_RAW + privileged: false + allowPrivilegeEscalation: false + defaultAllowPrivilegeEscalation: false + fsGroup: + rule: RunAsAny + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - emptyDir + - secret + - persistentVolumeClaim + - downwardAPI + - configMap + - projected + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: psp:restricted + rules: + - apiGroups: + - extensions + resourceNames: + - restricted + resources: + - podsecuritypolicies + verbs: + - use + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: psp:restricted + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp:restricted + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:serviceaccounts + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:authenticated + --- + apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: default-allow-all + spec: + podSelector: {} + ingress: + - {} + egress: + - {} + policyTypes: + - Ingress + - Egress + --- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: default + automountServiceAccountToken: false +addons_include: [] +system_images: + etcd: "" + alpine: "" + nginx_proxy: "" + cert_downloader: "" + kubernetes_services_sidecar: "" + kubedns: "" + dnsmasq: "" + kubedns_sidecar: "" + kubedns_autoscaler: "" + coredns: "" + coredns_autoscaler: "" + nodelocal: "" + kubernetes: "" + flannel: "" + flannel_cni: "" + calico_node: "" + calico_cni: "" + calico_controllers: "" + calico_ctl: "" + calico_flexvol: "" + canal_node: "" + canal_cni: "" + canal_controllers: "" + canal_flannel: "" + canal_flexvol: "" + weave_node: "" + weave_cni: "" + pod_infra_container: "" + ingress: "" + ingress_backend: "" + metrics_server: "" + windows_pod_infra_container: "" +authorization: + mode: "" + options: {} +ignore_docker_version: false +private_registries: [] +ingress: + provider: "" + options: {} + node_selector: {} + extra_args: {} + dns_policy: "" + extra_envs: [] + extra_volumes: [] + extra_volume_mounts: [] + update_strategy: null + http_port: 0 + https_port: 0 + network_mode: "" +cluster_name: +cloud_provider: + name: "" +prefix_path: "" +win_prefix_path: "" +addon_job_timeout: 0 +bastion_host: + address: "" + port: "" + user: "" + ssh_key: "" + ssh_key_path: "" + ssh_cert: "" + ssh_cert_path: "" +monitoring: + provider: "" + options: {} + node_selector: {} + update_strategy: null + replicas: null +restore: + restore: false + snapshot_name: "" +dns: null +upgrade_strategy: + max_unavailable_worker: "" + max_unavailable_controlplane: "" + drain: null + node_drain_input: null + \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/bookinfo.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/bookinfo.yaml new file mode 100644 index 0000000..e9f8a40 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/bookinfo.yaml @@ -0,0 +1,231 @@ +# Copyright 2017 Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +################################################################################################## +# Details service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: details + labels: + app: details + service: details +spec: + ports: + - port: 9080 + name: http + selector: + app: details +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: details-v1 + labels: + app: details + version: v1 +spec: + selector: + matchLabels: + app: details + replicas: 1 + template: + metadata: + labels: + app: details + version: v1 + spec: + containers: + - name: details + image: istio/examples-bookinfo-details-v1:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 +--- +################################################################################################## +# Ratings service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: ratings + labels: + app: ratings + service: ratings +spec: + ports: + - port: 9080 + name: http + selector: + app: ratings +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ratings-v1 + labels: + app: ratings + version: v1 +spec: + selector: + matchLabels: + app: ratings + replicas: 1 + template: + metadata: + labels: + app: ratings + version: v1 + spec: + containers: + - name: ratings + image: istio/examples-bookinfo-ratings-v1:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 +--- +################################################################################################## +# Reviews service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: reviews + labels: + app: reviews + service: reviews +spec: + ports: + - port: 9080 + name: http + selector: + app: reviews +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v1 + labels: + app: reviews + version: v1 +spec: + selector: + matchLabels: + app: reviews + replicas: 1 + template: + metadata: + labels: + app: reviews + version: v1 + spec: + containers: + - name: reviews + image: istio/examples-bookinfo-reviews-v1:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v2 + labels: + app: reviews + version: v2 +spec: + selector: + matchLabels: + app: reviews + replicas: 1 + template: + metadata: + labels: + app: reviews + version: v2 + spec: + containers: + - name: reviews + image: istio/examples-bookinfo-reviews-v2:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v3 + labels: + app: reviews + version: v3 +spec: + selector: + matchLabels: + app: reviews + replicas: 1 + template: + metadata: + labels: + app: reviews + version: v3 + spec: + containers: + - name: reviews + image: istio/examples-bookinfo-reviews-v3:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 +--- +################################################################################################## +# Productpage services +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: productpage + labels: + app: productpage + service: productpage +spec: + ports: + - port: 9080 + name: http + selector: + app: productpage +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: productpage-v1 + labels: + app: productpage + version: v1 +spec: + selector: + matchLabels: + app: productpage + replicas: 1 + template: + metadata: + labels: + app: productpage + version: v1 + spec: + containers: + - name: productpage + image: istio/examples-bookinfo-productpage-v1:1.13.0 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/adapter.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/adapter.yaml new file mode 100644 index 0000000..9ed9db2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/adapter.yaml @@ -0,0 +1,11 @@ +apiVersion: "config.istio.io/v1alpha2" +kind: adapter +metadata: + name: test +spec: + description: test + session_based: false + templates: + - apigee-authorization + - apigee-analytics + config: fake \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/attributemanifest.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/attributemanifest.yaml new file mode 100644 index 0000000..ee9d04d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/attributemanifest.yaml @@ -0,0 +1,56 @@ +apiVersion: "config.istio.io/v1alpha2" +kind: attributemanifest +metadata: + name: test +spec: + attributes: + source.ip: + valueType: IP_ADDRESS + source.labels: + valueType: STRING_MAP + source.name: + valueType: STRING + source.namespace: + valueType: STRING + source.owner: + valueType: STRING + source.serviceAccount: + valueType: STRING + source.services: + valueType: STRING + source.workload.uid: + valueType: STRING + source.workload.name: + valueType: STRING + source.workload.namespace: + valueType: STRING + destination.ip: + valueType: IP_ADDRESS + destination.labels: + valueType: STRING_MAP + destination.metadata: + valueType: STRING_MAP + destination.name: + valueType: STRING + destination.namespace: + valueType: STRING + destination.owner: + valueType: STRING + destination.service.uid: + valueType: STRING + destination.service.name: + valueType: STRING + destination.service.namespace: + valueType: STRING + destination.service.host: + valueType: STRING + destination.serviceAccount: + valueType: STRING + destination.workload.uid: + valueType: STRING + destination.workload.name: + valueType: STRING + destination.workload.namespace: + valueType: STRING + destination.container.name: + valueType: STRING \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authenticationpolicy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authenticationpolicy.yaml new file mode 100644 index 0000000..f4f0bbe --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authenticationpolicy.yaml @@ -0,0 +1,7 @@ +apiVersion: "authentication.istio.io/v1alpha1" +kind: "Policy" +metadata: + name: "default" +spec: + peers: + - mtls: {} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authorizationpolicy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authorizationpolicy.yaml new file mode 100644 index 0000000..554e61a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/authorizationpolicy.yaml @@ -0,0 +1,25 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: test +spec: + selector: + matchLabels: + app: httpbin + version: v1 + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/sleep"] + - source: + namespaces: ["test"] + to: + - operation: + methods: ["GET"] + paths: ["/info*"] + - operation: + methods: ["POST"] + paths: ["/data"] + when: + - key: request.auth.claims[iss] + values: ["https://accounts.google.com"] \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/certificate.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/certificate.yaml new file mode 100644 index 0000000..460a684 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/certificate.yaml @@ -0,0 +1,14 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: Certificate +metadata: + name: example +spec: + secretName: example-tls + duration: 24h + renewBefore: 12h + dnsNames: + - foo.example.com + - bar.example.com + issuerRef: + name: my-internal-ca + kind: Issuer \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/challenge.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/challenge.yaml new file mode 100644 index 0000000..5bf54f1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/challenge.yaml @@ -0,0 +1,17 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: Challenge +metadata: + name: fake-challenge +spec: + authzURL: https://acme-v02.api.letsencrypt.org/authz + dnsName: fake.com + solver: + ingress: testing + issuerRef: + group: fake + kind: Issuer + name: test + key: key + token: token + type: http01 + url: https://acme-v02.api.letsencrypt.org/challenge \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/clusterissuer.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/clusterissuer.yaml new file mode 100644 index 0000000..89bcc08 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/clusterissuer.yaml @@ -0,0 +1,10 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: ClusterIssuer +metadata: + name: example +spec: + acme: + http01: {} + privateKeySecretRef: + name: letsencrypt + server: https://acme-v02.api.letsencrypt.org/directory \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/destinationrule.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/destinationrule.yaml new file mode 100644 index 0000000..80b2849 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/destinationrule.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: test +spec: + host: fake.test.svc.cluster.local + trafficPolicy: + loadBalancer: + simple: LEAST_CONN \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/envoyfilter.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/envoyfilter.yaml new file mode 100644 index 0000000..898b5e0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/envoyfilter.yaml @@ -0,0 +1,38 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: test-ef +spec: + workloadSelector: + labels: + app: reviews + configPatches: + # The first patch adds the lua filter to the listener/http connection manager + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + listener: + portNumber: 8080 + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: # lua filter specification + name: envoy.lua + config: + inlineCode: | + function envoy_on_request(request_handle) + -- Make an HTTP call to an upstream host with the following headers, body, and timeout. + local headers, body = request_handle:httpCall( + "lua_cluster", + { + [":method"] = "POST", + [":path"] = "/acl", + [":authority"] = "internal.org.net" + }, + "authorize call", + 5000) + end \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/gateway.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/gateway.yaml new file mode 100644 index 0000000..0db507c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/gateway.yaml @@ -0,0 +1,15 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: test-gateway +spec: + selector: + app: my-gateway-controller + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - "ns1/*" + - "ns2/foo.bar.com" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/handler.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/handler.yaml new file mode 100644 index 0000000..bb58157 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/handler.yaml @@ -0,0 +1,16 @@ +apiVersion: "config.istio.io/v1alpha2" +kind: handler +metadata: + name: test +spec: + compiledAdapter: prometheus + params: + metrics: + - name: request_count + instance_name: requestcount.metric.istio-system + kind: COUNTER + label_names: + - source_service + - source_version + - destination_service + - destination_version \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispec.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispec.yaml new file mode 100644 index 0000000..b0f2e38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispec.yaml @@ -0,0 +1,38 @@ +apiVersion: config.istio.io/v1alpha2 +kind: HTTPAPISpec +metadata: + name: petstore-test +spec: + attributes: + attributes: + api.service: + stringValue: petstore.swagger.io + api.version: + stringValue: 1.0.0 + patterns: + - attributes: + attributes: + api.operation: + stringValue: findPets + httpMethod: GET + uriTemplate: /api/pets + - attributes: + attributes: + api.operation: + stringValue: addPet + httpMethod: POST + uriTemplate: /api/pets + - attributes: + attributes: + api.operation: + stringValue: findPetById + httpMethod: GET + uriTemplate: /api/pets/{id} + - attributes: + attributes: + api.operation: + stringValue: deletePet + httpMethod: DELETE + uriTemplate: /api/pets/{id} + apiKeys: + - query: api-key diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispecbinding.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispecbinding.yaml new file mode 100644 index 0000000..c83859e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/httpapispecbinding.yaml @@ -0,0 +1,12 @@ +apiVersion: config.istio.io/v1alpha2 +kind: HTTPAPISpecBinding +metadata: + name: my-binding + namespace: default +spec: + services: + - name: foo + namespace: bar + apiSpecs: + - name: petstore + namespace: default diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/instance.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/instance.yaml new file mode 100644 index 0000000..4a1640e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/instance.yaml @@ -0,0 +1,13 @@ +apiVersion: config.istio.io/v1alpha2 +kind: instance +metadata: + name: requestduration +spec: + compiledTemplate: metric + params: + value: response.duration | "0ms" + dimensions: + destination_service: destination.service.host | "unknown" + destination_version: destination.labels["version"] | "unknown" + response_code: response.code | 200 + monitored_resource_type: '"UNSPECIFIED"' \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/issuer.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/issuer.yaml new file mode 100644 index 0000000..20425a4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/issuer.yaml @@ -0,0 +1,10 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: Issuer +metadata: + name: example +spec: + acme: + http01: {} + privateKeySecretRef: + name: letsencrypt + server: https://acme-v02.api.letsencrypt.org/directory \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/order.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/order.yaml new file mode 100644 index 0000000..cf23dff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/order.yaml @@ -0,0 +1,11 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: Order +metadata: + name: fake-order +spec: + commanName: testorder + csr: abcdef12345ghijk + issuerRef: + group: fake + kind: Issuer + name: test \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/peerauthentication.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/peerauthentication.yaml new file mode 100644 index 0000000..8e28ddc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/peerauthentication.yaml @@ -0,0 +1,7 @@ +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: default-pa +spec: + mtls: + mode: STRICT diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspec.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspec.yaml new file mode 100644 index 0000000..8691076 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspec.yaml @@ -0,0 +1,9 @@ +apiVersion: config.istio.io/v1alpha2 +kind: QuotaSpec +metadata: + name: request-count +spec: + rules: + - quotas: + - charge: 1 + quota: requestcount \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspecbinding.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspecbinding.yaml new file mode 100644 index 0000000..83d936f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/quotaspecbinding.yaml @@ -0,0 +1,9 @@ +apiVersion: config.istio.io/v1alpha2 +kind: QuotaSpecBinding +metadata: + name: request-count +spec: + quotaSpecs: + - name: request-count + services: + - name: productpage \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rbacconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rbacconfig.yaml new file mode 100644 index 0000000..416b095 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rbacconfig.yaml @@ -0,0 +1,8 @@ +apiVersion: "rbac.istio.io/v1alpha1" +kind: RbacConfig +metadata: + name: default +spec: + mode: ON_WITH_INCLUSION + inclusion: + namespaces: [] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/requestauthentication.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/requestauthentication.yaml new file mode 100644 index 0000000..e3f0499 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/requestauthentication.yaml @@ -0,0 +1,11 @@ +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: httpbin +spec: + selector: + matchLabels: + app: httpbin + jwtRules: + - issuer: "issuer-foo" + - issuer: "issuer-bar" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rule.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rule.yaml new file mode 100644 index 0000000..d283049 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/rule.yaml @@ -0,0 +1,9 @@ +apiVersion: config.istio.io/v1alpha2 +kind: rule +metadata: + name: test +spec: + actions: + - handler: fakehandler + instances: + - fakeinstance \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/serviceentry.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/serviceentry.yaml new file mode 100644 index 0000000..c3baeb2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/serviceentry.yaml @@ -0,0 +1,13 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: ServiceEntry +metadata: + name: test +spec: + hosts: + - www.googleapis.com + location: MESH_EXTERNAL + ports: + - number: 443 + name: https + protocol: TLS + resolution: DNS diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerole.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerole.yaml new file mode 100644 index 0000000..6f69c5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerole.yaml @@ -0,0 +1,11 @@ +apiVersion: "rbac.istio.io/v1alpha1" +kind: ServiceRole +metadata: + name: test +spec: + rules: + - services: ["products.svc.cluster.local"] + methods: ["GET", "HEAD"] + constraints: + - key: "destination.labels[version]" + values: ["v1", "v2"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerolebinding.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerolebinding.yaml new file mode 100644 index 0000000..d1c1881 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/servicerolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: "rbac.istio.io/v1alpha1" +kind: ServiceRoleBinding +metadata: + name: test-binding +spec: + subjects: + - user: alice@yahoo.com + - properties: + source.namespace: "abc" + roleRef: + kind: ServiceRole + name: "products-viewer" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/sidecar.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/sidecar.yaml new file mode 100644 index 0000000..69816f0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/sidecar.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: Sidecar +metadata: + name: default +spec: + egress: + - hosts: + - "./*" + - "istio-system/*" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/template.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/template.yaml new file mode 100644 index 0000000..9b6c6ec --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/template.yaml @@ -0,0 +1,8 @@ +apiVersion: "config.istio.io/v1alpha2" +kind: template +metadata: + name: checknothing +spec: + descriptor: "fake" + foo: "bar" +--- \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/virtualservice.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/virtualservice.yaml new file mode 100644 index 0000000..11c9795 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/virtualservice.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: test-reviews-routing +spec: + hosts: + - reviews.prod.svc.cluster.local + http: + - name: "reviews-v2-routes" + match: + - uri: + prefix: "/consumercatalog" + rewrite: + uri: "/newcatalog" + route: + - destination: + host: reviews.prod.svc.cluster.local + subset: v2 + - name: "reviews-v1-route" + route: + - destination: + host: reviews.prod.svc.cluster.local + subset: v1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/workloadentry.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/workloadentry.yaml new file mode 100644 index 0000000..77109d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/crds/workloadentry.yaml @@ -0,0 +1,6 @@ +apiVersion: networking.istio.io/v1beta1 +kind: WorkloadEntry +metadata: + name: wle-1 +spec: + address: 1.1.1.1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/nginx-custom-sidecar.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/nginx-custom-sidecar.yaml new file mode 100644 index 0000000..86a41a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/istio/nginx-custom-sidecar.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-v1 + labels: + app: nginx + version: v1 +spec: + selector: + matchLabels: + app: nginx + replicas: 1 + template: + metadata: + labels: + app: nginx + version: v1 + annotations: + sidecar.istio.io/proxyImage: "rancher/istio-proxyv2:1.4.3" + spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/openldap.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/openldap.json new file mode 100644 index 0000000..74ff531 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/openldap.json @@ -0,0 +1,101 @@ +{ + "admin_user": "testautoadmin", + "standard_user": "testautouser", + "allowed_users": [ + "testauto2" + ], + "allowed_groups": [ + "testautogroup3" + ], + "allowed_nestedgroups": [ + "testautogroupnested1" + ], + "users_under_nestedgroups": [ + "testauto2", + "testauto5", + "testauto3", + "testauto4" + ], + "dis_allowed_users": [ + "testauto3", + "testauto4" + ], + "dis_allowed_groups": [ + "testautogroup4" + ], + "groups_added_to_cluster": [ + "testautogroup1" + ], + "groups_added_to_project": [ + "testautogroup2" + ], + "users_added_to_cluster": [ + "testauto5" + ], + "users_added_to_project": [ + "testauto6" + ], + "testautogroup1": [ + "testauto1", + "testauto2" + ], + "testautogroup2": [ + "testauto3", + "testauto4" + ], + "testautogroup3": [ + "testauto5", + "testauto6" + ], + "testautogroup4": [ + "testauto7", + "testauto8" + ], + "testautogroupnested1": [ + "testauto1" + ], + "specialchar_in_user_cn_sn":[ + "testuser9" + ], + "specialchar_in_uid":[ + "test(san)&abc" + ], + "specialchar_in_password": [ + "testuser4" + ], + "specialchar_in_groupname": [ + "test(group&)abc(group)" + ], + "test(group&)abc(group)": [ + "testuser9" + ], + "nested_group_info": { + "users": [ + "nestedtestuser1", + "nestedtestuser2", + "nestedtestuser3" + ], + "nestgroup1": { + "users": [ + "nestedtestuser1" + ], + "groups": [ + "nestgroup2" + ] + }, + "nestgroup2": { + "users": [ + "nestedtestuser2" + ], + "groups": [ + "nestgroup3" + ] + }, + "nestgroup3": { + "users": [ + "nestedtestuser3" + ], + "groups": [] + } + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cis_rbac.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cis_rbac.json new file mode 100644 index 0000000..ed7e027 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cis_rbac.json @@ -0,0 +1,75 @@ +{ + "cis-admin": { + "should_pass": [ + "create -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "get clusterscans", + "apply -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "get clusterscanprofiles", + "apply -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "get clusterscanbenchmarks", + "apply -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "get clusterscanreports", + "apply -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml" + ], + "should_fail": [] + }, + "cis-edit": { + "should_pass": [ + "create -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "get clusterscans", + "apply -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "get clusterscanprofiles", + "apply -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "get clusterscanbenchmarks", + "apply -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "get clusterscanreports", + "apply -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml" + ], + "should_fail": [] + }, + "cis-view": { + "should_pass": [ + "get clusterscans", + "get clusterscanprofiles", + "get clusterscanbenchmarks", + "get clusterscanreports" + ], + "should_fail": [ + "create -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "apply -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscans.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "apply -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanprofiles.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "apply -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanbenchmarks.yaml", + + "create -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "apply -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml", + "delete -f {resource_root}/rbac/cis/cr_clusterscanreports.yaml" + ] + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanbenchmarks.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanbenchmarks.yaml new file mode 100644 index 0000000..3997d66 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanbenchmarks.yaml @@ -0,0 +1,7 @@ +apiVersion: cis.cattle.io/v1 +kind: ClusterScanBenchmark +metadata: + name: benchmark-sample +spec: + clusterProvider: rke + minKubernetesVersion: 1.15.0 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanprofiles.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanprofiles.yaml new file mode 100644 index 0000000..5007b3d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanprofiles.yaml @@ -0,0 +1,6 @@ +apiVersion: cis.cattle.io/v1 +kind: ClusterScanProfile +metadata: + name: profile-sample +spec: + benchmarkVersion: rke-cis-1.5-permissive \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanreports.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanreports.yaml new file mode 100644 index 0000000..6b62dcf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscanreports.yaml @@ -0,0 +1,6 @@ +apiVersion: cis.cattle.io/v1 +kind: ClusterScanReport +metadata: + name: report-sample +spec: + benchmarkVersion: rke-cis-1.5-permissive \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscans.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscans.yaml new file mode 100644 index 0000000..a00757d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_clusterscans.yaml @@ -0,0 +1,6 @@ +apiVersion: cis.cattle.io/v1 +kind: ClusterScan +metadata: + name: scan-sample +spec: + scanProfileName: '' \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_scans.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_scans.yaml new file mode 100644 index 0000000..6f60235 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/cis/cr_scans.yaml @@ -0,0 +1,6 @@ +apiVersion: cis.cattle.io/v1 +kind: ClusterScan +metadata: + name: scan +spec: + scanProfileName: '' \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/istio/istio_rbac.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/istio/istio_rbac.json new file mode 100644 index 0000000..77be5b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/istio/istio_rbac.json @@ -0,0 +1,318 @@ +{ + "istio-admin": { + "should_pass": [ + "create -f {resource_root}/istio/crds/virtualservice.yaml", + "get virtualservices", + "apply -f {resource_root}/istio/crds/virtualservice.yaml", + "delete -f {resource_root}/istio/crds/virtualservice.yaml", + + "create -f {resource_root}/istio/crds/destinationrule.yaml", + "get destinationrules", + "apply -f {resource_root}/istio/crds/destinationrule.yaml", + "delete -f {resource_root}/istio/crds/destinationrule.yaml", + + "create -f {resource_root}/istio/crds/envoyfilter.yaml", + "get envoyfilters", + "apply -f {resource_root}/istio/crds/envoyfilter.yaml", + "delete -f {resource_root}/istio/crds/envoyfilter.yaml", + + "create -f {resource_root}/istio/crds/gateway.yaml", + "get gateways", + "apply -f {resource_root}/istio/crds/gateway.yaml", + "delete -f {resource_root}/istio/crds/gateway.yaml", + + "create -f {resource_root}/istio/crds/serviceentry.yaml", + "get serviceentry", + "apply -f {resource_root}/istio/crds/serviceentry.yaml", + "delete -f {resource_root}/istio/crds/serviceentry.yaml", + + "create -f {resource_root}/istio/crds/sidecar.yaml", + "get sidecars", + "apply -f {resource_root}/istio/crds/sidecar.yaml", + "delete -f {resource_root}/istio/crds/sidecar.yaml", + + "create -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "get authorizationpolicy", + "apply -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "delete -f {resource_root}/istio/crds/authorizationpolicy.yaml", + + "create -f {resource_root}/istio/crds/peerauthentication.yaml", + "get peerauthentication", + "apply -f {resource_root}/istio/crds/peerauthentication.yaml", + "delete -f {resource_root}/istio/crds/peerauthentication.yaml", + + "create -f {resource_root}/istio/crds/requestauthentication.yaml", + "get requestauthentication", + "apply -f {resource_root}/istio/crds/requestauthentication.yaml", + "delete -f {resource_root}/istio/crds/requestauthentication.yaml", + + "create -f {resource_root}/istio/crds/workloadentry.yaml", + "get workloadentry", + "apply -f {resource_root}/istio/crds/workloadentry.yaml", + "delete -f {resource_root}/istio/crds/workloadentry.yaml", + + "get adapters", + "get attributemanifests", + "get handlers", + "get httpapispecbindings", + "get httpapispecs", + "get instances", + "get quotaspecbindings", + "get quotaspecs", + "get rules", + "get templates" + ], + "should_fail": [ + "create -f {resource_root}/istio/crds/adapter.yaml", + "apply -f {resource_root}/istio/crds/adapter.yaml", + "delete -f {resource_root}/istio/crds/adapter.yaml", + + "create -f {resource_root}/istio/crds/attributemanifest.yaml", + "apply -f {resource_root}/istio/crds/attributemanifest.yaml", + "delete -f {resource_root}/istio/crds/attributemanifest.yaml", + + "create -f {resource_root}/istio/crds/handler.yaml", + "apply -f {resource_root}/istio/crds/handler.yaml", + "delete -f {resource_root}/istio/crds/handler.yaml", + + "create -f {resource_root}/istio/crds/httpapispec.yaml", + "apply -f {resource_root}/istio/crds/httpapispec.yaml", + "delete -f {resource_root}/istio/crds/httpapispec.yaml", + + "create -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "apply -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "delete -f {resource_root}/istio/crds/httpapispecbinding.yaml", + + "create -f {resource_root}/istio/crds/instance.yaml", + "apply -f {resource_root}/istio/crds/instance.yaml", + "delete -f {resource_root}/istio/crds/instance.yaml", + + "create -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "apply -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "delete -f {resource_root}/istio/crds/quotaspecbinding.yaml", + + "create -f {resource_root}/istio/crds/quotaspec.yaml", + "apply -f {resource_root}/istio/crds/quotaspec.yaml", + "delete -f {resource_root}/istio/crds/quotaspec.yaml", + + "create -f {resource_root}/istio/crds/rule.yaml", + "apply -f {resource_root}/istio/crds/rule.yaml", + "delete -f {resource_root}/istio/crds/rule.yaml", + + "create -f {resource_root}/istio/crds/template.yaml", + "apply -f {resource_root}/istio/crds/template.yaml", + "delete -f {resource_root}/istio/crds/template.yaml" + ] + }, + "istio-edit": { + "should_pass": [ + "create -f {resource_root}/istio/crds/virtualservice.yaml", + "get virtualservices", + "apply -f {resource_root}/istio/crds/virtualservice.yaml", + "delete -f {resource_root}/istio/crds/virtualservice.yaml", + + "create -f {resource_root}/istio/crds/destinationrule.yaml", + "get destinationrules", + "apply -f {resource_root}/istio/crds/destinationrule.yaml", + "delete -f {resource_root}/istio/crds/destinationrule.yaml", + + "create -f {resource_root}/istio/crds/envoyfilter.yaml", + "get envoyfilters", + "apply -f {resource_root}/istio/crds/envoyfilter.yaml", + "delete -f {resource_root}/istio/crds/envoyfilter.yaml", + + "create -f {resource_root}/istio/crds/gateway.yaml", + "get gateways", + "apply -f {resource_root}/istio/crds/gateway.yaml", + "delete -f {resource_root}/istio/crds/gateway.yaml", + + "create -f {resource_root}/istio/crds/serviceentry.yaml", + "get serviceentry", + "apply -f {resource_root}/istio/crds/serviceentry.yaml", + "delete -f {resource_root}/istio/crds/serviceentry.yaml", + + "create -f {resource_root}/istio/crds/sidecar.yaml", + "get sidecars", + "apply -f {resource_root}/istio/crds/sidecar.yaml", + "delete -f {resource_root}/istio/crds/sidecar.yaml", + + "create -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "get authorizationpolicy", + "apply -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "delete -f {resource_root}/istio/crds/authorizationpolicy.yaml", + + "create -f {resource_root}/istio/crds/peerauthentication.yaml", + "get peerauthentication", + "apply -f {resource_root}/istio/crds/peerauthentication.yaml", + "delete -f {resource_root}/istio/crds/peerauthentication.yaml", + + "create -f {resource_root}/istio/crds/requestauthentication.yaml", + "get requestauthentication", + "apply -f {resource_root}/istio/crds/requestauthentication.yaml", + "delete -f {resource_root}/istio/crds/requestauthentication.yaml", + + "create -f {resource_root}/istio/crds/workloadentry.yaml", + "get workloadentry", + "apply -f {resource_root}/istio/crds/workloadentry.yaml", + "delete -f {resource_root}/istio/crds/workloadentry.yaml", + + "get adapters", + "get attributemanifests", + "get handlers", + "get httpapispecbindings", + "get httpapispecs", + "get instances", + "get quotaspecbindings", + "get quotaspecs", + "get rules", + "get templates" + ], + "should_fail": [ + "create -f {resource_root}/istio/crds/adapter.yaml", + "apply -f {resource_root}/istio/crds/adapter.yaml", + "delete -f {resource_root}/istio/crds/adapter.yaml", + + "create -f {resource_root}/istio/crds/attributemanifest.yaml", + "apply -f {resource_root}/istio/crds/attributemanifest.yaml", + "delete -f {resource_root}/istio/crds/attributemanifest.yaml", + + "create -f {resource_root}/istio/crds/handler.yaml", + "apply -f {resource_root}/istio/crds/handler.yaml", + "delete -f {resource_root}/istio/crds/handler.yaml", + + "create -f {resource_root}/istio/crds/httpapispec.yaml", + "apply -f {resource_root}/istio/crds/httpapispec.yaml", + "delete -f {resource_root}/istio/crds/httpapispec.yaml", + + "create -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "apply -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "delete -f {resource_root}/istio/crds/httpapispecbinding.yaml", + + "create -f {resource_root}/istio/crds/instance.yaml", + "apply -f {resource_root}/istio/crds/instance.yaml", + "delete -f {resource_root}/istio/crds/instance.yaml", + + "create -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "apply -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "delete -f {resource_root}/istio/crds/quotaspecbinding.yaml", + + "create -f {resource_root}/istio/crds/quotaspec.yaml", + "apply -f {resource_root}/istio/crds/quotaspec.yaml", + "delete -f {resource_root}/istio/crds/quotaspec.yaml", + + "create -f {resource_root}/istio/crds/rule.yaml", + "apply -f {resource_root}/istio/crds/rule.yaml", + "delete -f {resource_root}/istio/crds/rule.yaml", + + "create -f {resource_root}/istio/crds/template.yaml", + "apply -f {resource_root}/istio/crds/template.yaml", + "delete -f {resource_root}/istio/crds/template.yaml" + ] + }, + "istio-view": { + "should_pass": [ + "get virtualservices", + "get destinationrules", + "get envoyfilters", + "get gateways", + "get serviceentry", + "get sidecars", + "get authorizationpolicy", + "get peerauthentication", + "get requestauthentication", + "get workloadentry", + + "get adapters", + "get attributemanifests", + "get handlers", + "get httpapispecbindings", + "get httpapispecs", + "get instances", + "get quotaspecbindings", + "get quotaspecs", + "get rules", + "get templates" + ], + "should_fail": [ + "create -f {resource_root}/istio/crds/virtualservice.yaml", + "apply -f {resource_root}/istio/crds/virtualservice.yaml", + "delete -f {resource_root}/istio/crds/virtualservice.yaml", + + "create -f {resource_root}/istio/crds/destinationrule.yaml", + "apply -f {resource_root}/istio/crds/destinationrule.yaml", + "delete -f {resource_root}/istio/crds/destinationrule.yaml", + + "create -f {resource_root}/istio/crds/envoyfilter.yaml", + "apply -f {resource_root}/istio/crds/envoyfilter.yaml", + "delete -f {resource_root}/istio/crds/envoyfilter.yaml", + + "create -f {resource_root}/istio/crds/gateway.yaml", + "apply -f {resource_root}/istio/crds/gateway.yaml", + "delete -f {resource_root}/istio/crds/gateway.yaml", + + "create -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "apply -f {resource_root}/istio/crds/authorizationpolicy.yaml", + "delete -f {resource_root}/istio/crds/authorizationpolicy.yaml", + + "create -f {resource_root}/istio/crds/serviceentry.yaml", + "apply -f {resource_root}/istio/crds/serviceentry.yaml", + "delete -f {resource_root}/istio/crds/serviceentry.yaml", + + "create -f {resource_root}/istio/crds/sidecar.yaml", + "apply -f {resource_root}/istio/crds/sidecar.yaml", + "delete -f {resource_root}/istio/crds/sidecar.yaml", + + "create -f {resource_root}/istio/crds/peerauthentication.yaml", + "apply -f {resource_root}/istio/crds/peerauthentication.yaml", + "delete -f {resource_root}/istio/crds/peerauthentication.yaml", + + "create -f {resource_root}/istio/crds/requestauthentication.yaml", + "apply -f {resource_root}/istio/crds/requestauthentication.yaml", + "delete -f {resource_root}/istio/crds/requestauthentication.yaml", + + "create -f {resource_root}/istio/crds/workloadentry.yaml", + "apply -f {resource_root}/istio/crds/workloadentry.yaml", + "delete -f {resource_root}/istio/crds/workloadentry.yaml", + + "create -f {resource_root}/istio/crds/adapter.yaml", + "apply -f {resource_root}/istio/crds/adapter.yaml", + "delete -f {resource_root}/istio/crds/adapter.yaml", + + "create -f {resource_root}/istio/crds/attributemanifest.yaml", + "apply -f {resource_root}/istio/crds/attributemanifest.yaml", + "delete -f {resource_root}/istio/crds/attributemanifest.yaml", + + "create -f {resource_root}/istio/crds/handler.yaml", + "apply -f {resource_root}/istio/crds/handler.yaml", + "delete -f {resource_root}/istio/crds/handler.yaml", + + "create -f {resource_root}/istio/crds/httpapispec.yaml", + "apply -f {resource_root}/istio/crds/httpapispec.yaml", + "delete -f {resource_root}/istio/crds/httpapispec.yaml", + + "create -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "apply -f {resource_root}/istio/crds/httpapispecbinding.yaml", + "delete -f {resource_root}/istio/crds/httpapispecbinding.yaml", + + "create -f {resource_root}/istio/crds/instance.yaml", + "apply -f {resource_root}/istio/crds/instance.yaml", + "delete -f {resource_root}/istio/crds/instance.yaml", + + "create -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "apply -f {resource_root}/istio/crds/quotaspecbinding.yaml", + "delete -f {resource_root}/istio/crds/quotaspecbinding.yaml", + + "create -f {resource_root}/istio/crds/quotaspec.yaml", + "apply -f {resource_root}/istio/crds/quotaspec.yaml", + "delete -f {resource_root}/istio/crds/quotaspec.yaml", + + "create -f {resource_root}/istio/crds/rule.yaml", + "apply -f {resource_root}/istio/crds/rule.yaml", + "delete -f {resource_root}/istio/crds/rule.yaml", + + "create -f {resource_root}/istio/crds/template.yaml", + "apply -f {resource_root}/istio/crds/template.yaml", + "delete -f {resource_root}/istio/crds/template.yaml" + ] + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusterflow.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusterflow.yaml new file mode 100644 index 0000000..3362319 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusterflow.yaml @@ -0,0 +1,8 @@ +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterFlow +metadata: + name: flow-sample + namespace: cattle-logging-system +spec: + outputRefs: + - es-output-sample diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusteroutput.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusteroutput.yaml new file mode 100644 index 0000000..ec63bfc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_clusteroutput.yaml @@ -0,0 +1,10 @@ +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterOutput +metadata: + name: es-output-sample + namespace: cattle-logging-system +spec: + elasticsearch: + host: myhostname + port: 9200 + scheme: http diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_flow.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_flow.yaml new file mode 100644 index 0000000..a69c448 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_flow.yaml @@ -0,0 +1,10 @@ +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Flow +metadata: + name: do-flow + namespace: default +spec: + match: + - select: {} + outputRefs: + - do-output diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_logging.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_logging.yaml new file mode 100644 index 0000000..354c87a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_logging.yaml @@ -0,0 +1,8 @@ +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Logging +metadata: + name: logging-example +spec: + controlNamespace: cattle-logging-system + fluentbit: {} + fluentd: {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_output.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_output.yaml new file mode 100644 index 0000000..cc63f0e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_output.yaml @@ -0,0 +1,12 @@ +apiVersion: logging.banzaicloud.io/v1beta1 +kind: Output +metadata: + name: do-output + namespace: default +spec: + splunkHec: + hec_host: 192.168.0.1 + hec_port: 8088 + protocol: http + hec_token: + value: dummy-token diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_resourcedefinition.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_resourcedefinition.yaml new file mode 100644 index 0000000..c9feede --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/cr_resourcedefinition.yaml @@ -0,0 +1,31 @@ +# Sample CRD from https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: crontabs.stable.example.com +spec: + group: stable.example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + cronSpec: + type: string + image: + type: string + replicas: + type: integer + scope: Namespaced + names: + plural: crontabs + singular: crontab + kind: CronTab + shortNames: + - ct diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/logging_rbac.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/logging_rbac.json new file mode 100644 index 0000000..0517944 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/logging/logging_rbac.json @@ -0,0 +1,153 @@ +{ + "logging-admin": { + "should_pass": [ + + "create -f {resource_root}/rbac/logging/cr_output.yaml", + "get output do-output", + "apply -f {resource_root}/rbac/logging/cr_output.yaml", + "delete -f {resource_root}/rbac/logging/cr_output.yaml", + + "create -f {resource_root}/rbac/logging/cr_flow.yaml", + "get flow do-flow", + "apply -f {resource_root}/rbac/logging/cr_flow.yaml", + "delete -f {resource_root}/rbac/logging/cr_flow.yaml" + ], + "should_fail": [ + "get loggings", + "create -f {resource_root}/rbac/logging/cr_logging.yaml", + "apply -f {resource_root}/rbac/logging/cr_logging.yaml", + "delete -f {resource_root}/rbac/logging/cr_logging.yaml", + + "get clusteroutputs", + "create -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + + "get clusterflows", + "create -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusterflow.yaml" + ] + }, + "logging-edit": { + "should_pass": [ + "get output", + "create -f {resource_root}/rbac/logging/cr_output.yaml", + "apply -f {resource_root}/rbac/logging/cr_output.yaml", + "delete -f {resource_root}/rbac/logging/cr_output.yaml", + + "get flow", + "create -f {resource_root}/rbac/logging/cr_flow.yaml", + "apply -f {resource_root}/rbac/logging/cr_flow.yaml", + "delete -f {resource_root}/rbac/logging/cr_flow.yaml" + + ], + "should_fail": [ + "get loggings", + "create -f {resource_root}/rbac/logging/cr_logging.yaml", + "apply -f {resource_root}/rbac/logging/cr_logging.yaml", + "delete -f {resource_root}/rbac/logging/cr_logging.yaml", + + "get clusteroutputs", + "create -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + + "get clusterflows", + "create -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusterflow.yaml" + ] + }, + "logging-view": { + "should_pass": [ + "get flows", + "get outputs" + ], + "should_fail": [ + "get loggings", + "create -f {resource_root}/rbac/logging/cr_logging.yaml", + "apply -f {resource_root}/rbac/logging/cr_logging.yaml", + "delete -f {resource_root}/rbac/logging/cr_logging.yaml", + + "get clusteroutputs", + "create -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + + "get clusterflows", + "create -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + + "create -f {resource_root}/rbac/logging/cr_output.yaml", + "apply -f {resource_root}/rbac/logging/cr_output.yaml", + "delete -f {resource_root}/rbac/logging/cr_output.yaml", + + "create -f {resource_root}/rbac/logging/cr_flow.yaml", + "apply -f {resource_root}/rbac/logging/cr_flow.yaml", + "delete -f {resource_root}/rbac/logging/cr_flow.yaml" + ] + }, + "rancher-logging-fluentbit": { + "should_pass": [ + "get pods", + "get namespaces" + ], + "should_fail": [ + "get pv", + "get secrets", + "get configmaps", + + "get loggings", + "create -f {resource_root}/rbac/logging/cr_logging.yaml", + "apply -f {resource_root}/rbac/logging/cr_logging.yaml", + "delete -f {resource_root}/rbac/logging/cr_logging.yaml", + + "get clusteroutputs", + "create -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + + "get clusterflows", + "create -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + + "get outputs", + "create -f {resource_root}/rbac/logging/cr_output.yaml", + "apply -f {resource_root}/rbac/logging/cr_output.yaml", + "delete -f {resource_root}/rbac/logging/cr_output.yaml", + + "get flows", + "create -f {resource_root}/rbac/logging/cr_flow.yaml", + "apply -f {resource_root}/rbac/logging/cr_flow.yaml", + "delete -f {resource_root}/rbac/logging/cr_flow.yaml" + ] + }, + "rancher-logging": { + "should_pass": [ + "get crd", + "get loggings", + "create -f {resource_root}/rbac/logging/cr_logging.yaml", + "apply -f {resource_root}/rbac/logging/cr_logging.yaml", + "delete -f {resource_root}/rbac/logging/cr_logging.yaml", + + "get clusteroutputs", + "create -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusteroutput.yaml", + + "get clusterflows", + "create -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "apply -f {resource_root}/rbac/logging/cr_clusterflow.yaml", + "delete -f {resource_root}/rbac/logging/cr_clusterflow.yaml" + + ], + "should_fail": [ + "create -f {resource_root}/rbac/logging/cr_resourcedefinition.yaml", + "apply -f {resource_root}/rbac/logging/cr_resourcedefinition.yaml", + "delete -f {resource_root}/rbac/logging/cr_resourcedefinition.yaml" + ] + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_alert_manager.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_alert_manager.yaml new file mode 100644 index 0000000..f01ef7a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_alert_manager.yaml @@ -0,0 +1,6 @@ +apiVersion: monitoring.coreos.com/v1 +kind: Alertmanager +metadata: + name: test-example-1 +spec: + replicas: 1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_base.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_base.yaml new file mode 100644 index 0000000..2a2e8e2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_base.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + key1: config1 +kind: ConfigMap +metadata: + name: test-example-1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_upgrade.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_upgrade.yaml new file mode 100644 index 0000000..4b7158b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_configmap_upgrade.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + key1: config1 +kind: ConfigMap +metadata: + name: test-example-1 + labels: + label-1: val-1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_base.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_base.yaml new file mode 100644 index 0000000..22012cb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_base.yaml @@ -0,0 +1,10 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: test-example-1 +spec: + selector: + matchLabels: + app: example-app + podMetricsEndpoints: + - port: web diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_upgrade.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_upgrade.yaml new file mode 100644 index 0000000..8013809 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_pod_monitor_upgrade.yaml @@ -0,0 +1,12 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: test-example-1 + labels: + team: frontend +spec: + selector: + matchLabels: + app: example-app + podMetricsEndpoints: + - port: web diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus.yaml new file mode 100644 index 0000000..ac90253 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus.yaml @@ -0,0 +1,13 @@ +apiVersion: monitoring.coreos.com/v1 +kind: Prometheus +metadata: + name: test-example-1 +spec: + serviceAccountName: prometheus + serviceMonitorSelector: + matchLabels: + team: frontend + resources: + requests: + memory: 400Mi + enableAdminAPI: true diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_base.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_base.yaml new file mode 100644 index 0000000..2f0b18f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_base.yaml @@ -0,0 +1,10 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: test-example-1 +spec: + groups: + - name: ./example.rules + rules: + - alert: ExampleAlert + expr: vector(1) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_upgrade.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_upgrade.yaml new file mode 100644 index 0000000..0585a21 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_prometheus_rule_upgrade.yaml @@ -0,0 +1,13 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + prometheus: example + role: alert-rules + name: test-example-1 +spec: + groups: + - name: ./example.rules + rules: + - alert: ExampleAlert + expr: vector(1) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_base.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_base.yaml new file mode 100644 index 0000000..8bc2cd8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_base.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + password: bXlwYXNz +kind: Secret +metadata: + name: test-example-1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_upgrade.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_upgrade.yaml new file mode 100644 index 0000000..d5e7cfc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_secret_upgrade.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + password: bXlwYXNz +kind: Secret +metadata: + name: test-example-1 + labels: + label-1: val-1 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_base.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_base.yaml new file mode 100644 index 0000000..7f8e7a1 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_base.yaml @@ -0,0 +1,10 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: test-example-1 +spec: + selector: + matchLabels: + app: example-app + endpoints: + - port: web diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_upgrade.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_upgrade.yaml new file mode 100644 index 0000000..ca08afc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/cr_service_monitor_upgrade.yaml @@ -0,0 +1,12 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: test-example-1 + labels: + team: frontend +spec: + selector: + matchLabels: + app: example-app + endpoints: + - port: web diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/monitoring_rbac.json b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/monitoring_rbac.json new file mode 100644 index 0000000..00ea186 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/rbac/monitoring/monitoring_rbac.json @@ -0,0 +1,248 @@ +{ + "monitoring-admin": { + "should_pass": [ + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "get configmap", + "get configmap test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "get secret", + "get secret test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + }, + "monitoring-edit": { + "should_pass": [ + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "get configmap", + "get configmap test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "get secret", + "get secret test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + }, + "monitoring-view": { + "should_pass": [ + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "get configmap", + "get configmap my-config", + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "get secret", + "get secret mysecret", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + }, + "admin": { + "should_pass": [ + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "get configmap", + "get configmap test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "get secret", + "get secret test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + }, + "edit": { + "should_pass": [ + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "get configmap", + "get configmap test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "get secret", + "get secret test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + }, + "view": { + "should_pass": [ + "get configmap", + "get configmap my-config", + "get podmonitors.monitoring.coreos.com", + "get podmonitors.monitoring.coreos.com test-example-1", + "get prometheusrules.monitoring.coreos.com", + "get prometheusrules.monitoring.coreos.com test-example-1", + "get servicemonitors.monitoring.coreos.com", + "get servicemonitors.monitoring.coreos.com test-example-1", + "get alertmanagers.monitoring.coreos.com", + "get alertmanagers.monitoring.coreos.com test-example-1", + "get prometheuses.monitoring.coreos.com", + "get prometheuses.monitoring.coreos.com test-example-1" + ], + "should_fail": [ + "create -f {resource_root}/rbac/monitoring/cr_configmap_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_configmap_upgrade.yaml", + "get secret", + "get secret mysecret", + "create -f {resource_root}/rbac/monitoring/cr_secret_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_secret_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_pod_monitor_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_pod_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus_rule_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus_rule_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_service_monitor_base.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_service_monitor_upgrade.yaml", + "create -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_alert_manager.yaml", + "create -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "apply -f {resource_root}/rbac/monitoring/cr_prometheus.yaml", + "delete -f {resource_root}/rbac/monitoring/cr_prometheus.yaml" + ] + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/squid/squid.conf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/squid/squid.conf new file mode 100644 index 0000000..e562984 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/squid/squid.conf @@ -0,0 +1,69 @@ +# +# Recommended minimum configuration: +# + +# Example rule allowing access from your local networks. +# Adapt to list your (internal) IP networks from where browsing +# should be allowed +acl localnet src 10.0.0.0/8 # RFC1918 possible internal network +acl localnet src 172.16.0.0/12 # RFC1918 possible internal network +acl localnet src 192.168.0.0/16 # RFC1918 possible internal network +acl localnet src fc00::/7 # RFC 4193 local private network range +acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + +acl Safe_ports port 22 # ssh +acl Safe_ports port 2376 # docker port +acl SSL_ports port 22 +acl SSL_ports port 2376 +acl SSL_ports port 443 +acl SSL_ports port 6443 +acl Safe_ports port 80 # http +acl Safe_ports port 21 # ftp +acl Safe_ports port 443 # https +acl Safe_ports port 70 # gopher +acl Safe_ports port 210 # wais +acl Safe_ports port 1025-65535 # unregistered ports +acl Safe_ports port 280 # http-mgmt +acl Safe_ports port 488 # gss-http +acl Safe_ports port 591 # filemaker +acl Safe_ports port 777 # multiling http +acl Safe_ports port 6443 # k8s +acl CONNECT method CONNECT + +# Recommended minimum Access Permission configuration: +# Deny requests to certain unsafe ports +http_access deny !Safe_ports + +# Deny CONNECT to other than secure SSL ports +http_access deny CONNECT !SSL_ports + +# Only allow cachemgr access from localhost +http_access allow localhost manager +http_access deny manager + +# We strongly recommend the following be uncommented to protect innocent +# web applications running on the proxy server who think the only +# one who can access services on "localhost" is a local user +#http_access deny to_localhost + +# Example rule allowing access from your local networks. +# Adapt localnet in the ACL section to list your (internal) IP networks +# from where browsing should be allowed +http_access allow localnet +http_access allow localhost +http_access allow all + +# Squid normally listens to port 3128 +http_port 3128 + +# Uncomment and adjust the following to add a disk cache directory. +#cache_dir ufs /var/cache/squid 100 16 256 + +# Leave coredumps in the first cache dir +coredump_dir /var/cache/squid + +# Add any of your own refresh_pattern entries above these. +refresh_pattern ^ftp: 1440 20% 10080 +refresh_pattern ^gopher: 1440 0% 1440 +refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 +refresh_pattern . 0 20% 4320 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/sysctl-config b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/sysctl-config new file mode 100644 index 0000000..288ddd9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/sysctl-config @@ -0,0 +1,5 @@ +sudo sysctl vm.overcommit_memory=1 +sudo sysctl vm.panic_on_oom=0 +sudo sysctl kernel.panic=10 +sudo sysctl kernel.panic_on_oops=1 +sudo sysctl kernel.keys.root_maxbytes=25000000 \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/aks.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/aks.tf new file mode 100644 index 0000000..97d58d6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/aks.tf @@ -0,0 +1,50 @@ +provider "azurerm" { + features {} +} + +resource "random_string" "random" { + length = 5 + special = false + upper = false + lower = false + min_numeric = 5 +} + +resource "azurerm_resource_group" "default" { + name = "testautoaks${random_string.random.result}" + location = var.location + + tags = { + environment = "automation" + } +} + +resource "azurerm_kubernetes_cluster" "default" { + name = var.cluster_name + location = azurerm_resource_group.default.location + resource_group_name = azurerm_resource_group.default.name + dns_prefix = "taaks${random_string.random.result}" + kubernetes_version = var.kubernetes_version + sku_tier = var.sku_tier + + default_node_pool { + name = "taaks${random_string.random.result}" + node_count = var.node_count + vm_size = var.vm_size + os_disk_size_gb = var.disk_capacity + } + + service_principal { + client_id = "id_placeholder" + client_secret = "secret_placeholder" + } + + tags = { + environment = "automation" + } +} + +output "kube_config" { + value = azurerm_kubernetes_cluster.default.kube_config_raw + sensitive = true +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/variables.tf new file mode 100644 index 0000000..dd49682 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/aks/variables.tf @@ -0,0 +1,32 @@ +variable "kubernetes_version" { + description = "Azure Kubernetes Cluster K8s version" + default = "1.23.5" +} + +variable "location" { + description = "Azure Kubernetes location (US Central, US East, etc)" + default = "East US 2" +} + +variable "node_count" { + description = "Number of nodes in the Cluster" + default = 3 +} + +variable "vm_size" { + description = "VM Size for the nodes in the cluster" + default = "Standard_D3_v2" +} + +variable "disk_capacity" { + description = "VM System Volume size" + default = 30 +} + +variable "cluster_name" { + default = "testautoaks" +} + +variable "sku_tier" { + default = "Paid" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/gke.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/gke.tf new file mode 100644 index 0000000..2ae8850 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/gke.tf @@ -0,0 +1,50 @@ +provider "google" { + region = var.region + version = "~> 4.53.1" + credentials = var.credentials + project = "ei-container-platform-qa" +} + +module "gke_auth" { + source = "terraform-google-modules/kubernetes-engine/google//modules/auth" + project_id = "ei-container-platform-qa" + cluster_name = var.cluster_name + location = var.location + depends_on = [google_container_cluster.default] +} + +data "google_client_config" "current" {} + +data "google_container_engine_versions" "default" { + location = var.location +} + +resource "google_container_cluster" "default" { + name = var.cluster_name + location = var.location + initial_node_count = 3 + min_master_version = var.kubernetes_version + monitoring_service = "none" + logging_service = "none" + + node_config { + machine_type = var.machine_type + disk_size_gb = var.disk_size + } +} + +output "cluster_name" { + value = google_container_cluster.default.name +} + +output "cluster_region" { + value = var.region +} + +output "cluster_location" { + value = google_container_cluster.default.location +} + +output "kube_config" { + value = module.gke_auth.kubeconfig_raw +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/variables.tf new file mode 100644 index 0000000..1e616b5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/gke/variables.tf @@ -0,0 +1,28 @@ +variable "region" { + default = "us-central1" +} + +variable "location" { + default = "us-central1-f" +} + +variable "kubernetes_version" { + default = "1.20.8-gke.2100" +} + +variable "disk_size" { + default = 50 +} + +variable "machine_type" { + default = "e2-standard-2" +} + +variable "cluster_name" { + default = "qaautogke" +} + +variable "credentials" { + default = "" +} + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/audit.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/audit.yaml new file mode 100644 index 0000000..9ec0d3c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/audit.yaml @@ -0,0 +1,4 @@ +apiVersion: audit.k8s.io/v1 +kind: Policy +rules: +- level: Metadata \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_masterconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_masterconfig.yaml new file mode 100644 index 0000000..fa3b60a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_masterconfig.yaml @@ -0,0 +1,16 @@ +secrets-encryption: true +kube-apiserver-arg: + - 'audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log' + - 'audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml' + - 'audit-log-maxage=30' + - 'audit-log-maxbackup=10' + - 'audit-log-maxsize=100' + - 'request-timeout=300s' + - 'service-account-lookup=true' + - 'enable-admission-plugins=NodeRestriction,PodSecurityPolicy,NamespaceLifecycle,ServiceAccount' +kube-controller-manager-arg: + - 'terminated-pod-gc-threshold=10' + - 'use-service-account-credentials=true' +kubelet-arg: + - 'streaming-connection-idle-timeout=5m' + - 'make-iptables-util-chains=true' diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_v125_masterconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_v125_masterconfig.yaml new file mode 100644 index 0000000..cadafd3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/cis_v125_masterconfig.yaml @@ -0,0 +1,17 @@ +secrets-encryption: true +kube-apiserver-arg: + - 'audit-log-path=/var/lib/rancher/k3s/server/logs/audit.log' + - 'audit-policy-file=/var/lib/rancher/k3s/server/audit.yaml' + - 'audit-log-maxage=30' + - 'audit-log-maxbackup=10' + - 'audit-log-maxsize=100' + - 'request-timeout=300s' + - 'service-account-lookup=true' + - 'enable-admission-plugins=NodeRestriction,NamespaceLifecycle,ServiceAccount' + - 'admission-control-config-file=/etc/rancher/k3s/custom-psa.yaml' +kube-controller-manager-arg: + - 'terminated-pod-gc-threshold=10' + - 'use-service-account-credentials=true' +kubelet-arg: + - 'streaming-connection-idle-timeout=5m' + - 'make-iptables-util-chains=true' diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/install_k3s_master.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/install_k3s_master.sh new file mode 100644 index 0000000..6d153c6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/install_k3s_master.sh @@ -0,0 +1,157 @@ +#!/bin/bash +echo "$@" + +mkdir -p /etc/rancher/k3s +mkdir -p /var/lib/rancher/k3s/server/logs +token=$(openssl rand -base64 21) +cat << EOF >/etc/rancher/k3s/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +token: ${token} +EOF + +if [[ -n "${8}" ]] && [[ "${8}" == *":"* ]] +then + echo "$" + echo -e "$8" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi + +if [[ -n "${8}" ]] && [[ "${8}" == *"protect-kernel-defaults"* ]] +then + mkdir -p /var/lib/rancher/k3s/server/manifests + if [[ "${1}" == *"centos"* ]] || [[ "${1}" == *"rhel"* ]] || [[ "${1}" == *"rocky"* ]] + then + yum -y install bc + fi + calc(){ awk "BEGIN { print "$*" }"; } + version=`echo ${4}|cut -c2-5` + conversion=$(calc $version*1) + if (( $(echo "$conversion >= 1.25" | bc -l) )) + then + cat /tmp/cis_v125_masterconfig.yaml >> /etc/rancher/k3s/config.yaml + cat /tmp/v125_policy.yaml > /var/lib/rancher/k3s/server/manifests/policy.yaml + else + cat /tmp/cis_masterconfig.yaml >> /etc/rancher/k3s/config.yaml + cat /tmp/policy.yaml > /var/lib/rancher/k3s/server/manifests/policy.yaml + fi + echo -e "vm.panic_on_oom=0" >>/etc/sysctl.d/90-kubelet.conf + echo -e "vm.overcommit_memory=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic=10" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic_on_oops=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.keys.root_maxbytes=25000000" >>/etc/sysctl.d/90-kubelet.conf + sysctl -p /etc/sysctl.d/90-kubelet.conf + systemctl restart systemd-sysctl + cat /tmp/audit.yaml > /var/lib/rancher/k3s/server/audit.yaml + + if [[ "${4}" == *"v1.18"* ]] || [[ "${4}" == *"v1.19"* ]] || [[ "${4}" == *"v1.20"* ]] + then + cat /tmp/v120ingresspolicy.yaml > /var/lib/rancher/k3s/server/manifests/v120ingresspolicy.yaml + else + cat /tmp/v121ingresspolicy.yaml > /var/lib/rancher/k3s/server/manifests/v121ingresspolicy.yaml + fi +fi + + +if [[ "${8}" == *"traefik"* ]] +then + mkdir -p /var/lib/rancher/k3s/server/manifests + cat /tmp/nginx-ingress.yaml> /var/lib/rancher/k3s/server/manifests/nginx-ingress.yaml +fi + +if [ "${1}" = "rhel" ] +then + subscription-manager register --auto-attach --username="${9}" --password="${10}" + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +export "${3}"="${4}" + +if [ "${5}" = "etcd" ] +then + echo "CLUSTER TYPE is etcd" + if [[ "${4}" == *"v1.18"* ]] || [[ "${4}" == *"v1.17"* ]] && [[ -n "${8}" ]] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --cluster-init --node-external-ip="${6}" ${8} --tls-san "${2}" --write-kubeconfig-mode "0644" + else + if [ ${11} != "null" ] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${11} INSTALL_K3S_TYPE='server' sh -s - server --cluster-init --node-external-ip="${6}" + else + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --cluster-init --node-external-ip="${6}" + fi + fi +else + echo "CLUSTER TYPE is external db" + if [[ "${4}" == *"v1.18"* ]] || [[ "${4}" == *"v1.17"* ]] && [[ -n "${8}" ]] + then + curl -sfL https://get.k3s.io | sh -s - server --node-external-ip="${6}" --datastore-endpoint="${7}" ${8} --tls-san "${2}" --write-kubeconfig-mode "0644" + else + if [ ${11} != "null" ] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${11} sh -s - server --node-external-ip="${6}" --datastore-endpoint="${7}" + else + curl -sfL https://get.k3s.io | sh -s - server --node-external-ip="${6}" --datastore-endpoint="${7}" + fi + fi +fi + +export PATH=$PATH:/usr/local/bin +timeElapsed=0 +while ! $(kubectl get nodes >/dev/null 2>&1) && [[ $timeElapsed -lt 300 ]] +do + sleep 5 + timeElapsed=$(expr $timeElapsed + 5) +done + +IFS=$'\n' +timeElapsed=0 +sleep 10 +while [[ $timeElapsed -lt 420 ]] +do + notready=false + for rec in $(kubectl get nodes) + do + if [[ "$rec" == *"NotReady"* ]] + then + notready=true + fi + done + if [[ $notready == false ]] + then + break + fi + sleep 20 + timeElapsed=$(expr $timeElapsed + 20) +done + +IFS=$'\n' +timeElapsed=0 +while [[ $timeElapsed -lt 420 ]] +do + helmPodsNR=false + systemPodsNR=false + for rec in $(kubectl get pods -A --no-headers) + do + if [[ "$rec" == *"helm-install"* ]] && [[ "$rec" != *"Completed"* ]] + then + helmPodsNR=true + elif [[ "$rec" != *"helm-install"* ]] && [[ "$rec" != *"Running"* ]] + then + systemPodsNR=true + else + echo "" + fi + done + + if [[ $systemPodsNR == false ]] && [[ $helmPodsNR == false ]] + then + break + fi + sleep 20 + timeElapsed=$(expr $timeElapsed + 20) +done +cat /etc/rancher/k3s/config.yaml> /tmp/joinflags +cat /var/lib/rancher/k3s/server/node-token >/tmp/nodetoken +cat /etc/rancher/k3s/k3s.yaml >/tmp/config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/instances_server.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/instances_server.tf new file mode 100644 index 0000000..19d3963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/instances_server.tf @@ -0,0 +1,405 @@ +resource "aws_db_parameter_group" "db-parameters" { + count = (var.cluster_type == "etcd" ? 0 : (var.external_db != "aurora-mysql" ? 1 : 0)) + name = "${var.resource_name}-dbparameter" + family = var.db_group_name + parameter { + apply_method = "pending-reboot" + name = "max_connections" + value = var.max_connections + } +} + +resource "aws_db_instance" "db" { + count = (var.cluster_type == "etcd" ? 0 : (var.external_db != "aurora-mysql" ? 1 : 0)) + identifier = "${var.resource_name}-db" + allocated_storage = 20 + storage_type = "gp2" + engine = var.external_db + engine_version = var.external_db_version + instance_class = var.instance_class + name = "mydb" + #parameter_group_name = var.db_group_name + username = var.db_username + password = var.db_password + availability_zone = var.availability_zone + parameter_group_name = "${aws_db_parameter_group.db-parameters[count.index].name}" + tags = { + Environment = var.environment + } + skip_final_snapshot = true +} + +resource "aws_rds_cluster" "db" { + count = (var.external_db == "aurora-mysql" ? 1 : 0) + cluster_identifier = "${var.resource_name}-db" + engine = var.external_db + engine_version = var.external_db_version + availability_zones = [var.availability_zone] + database_name = "mydb" + master_username = var.db_username + master_password = var.db_password + engine_mode = var.engine_mode + tags = { + Environment = var.environment + } + skip_final_snapshot = true +} + +resource "aws_rds_cluster_instance" "db" { + count = (var.external_db == "aurora-mysql" ? 1 : 0) + #count = "${var.external_db == "aurora-mysql" ? 1 : 0}" + cluster_identifier = "${aws_rds_cluster.db[0].id}" + identifier = "${var.resource_name}-instance1" + instance_class = var.instance_class + engine = aws_rds_cluster.db[0].engine + engine_version = aws_rds_cluster.db[0].engine_version +} + +resource "aws_instance" "master" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-server" + } + + provisioner "file" { + source = "install_k3s_master.sh" + destination = "/tmp/install_k3s_master.sh" + } + + provisioner "file" { + source = "cis_masterconfig.yaml" + destination = "/tmp/cis_masterconfig.yaml" + } + + provisioner "file" { + source = "policy.yaml" + destination = "/tmp/policy.yaml" + } + + provisioner "file" { + source = "cis_v125_masterconfig.yaml" + destination = "/tmp/cis_v125_masterconfig.yaml" + } + + provisioner "file" { + source = "v125_policy.yaml" + destination = "/tmp/v125_policy.yaml" + } + + provisioner "file" { + source = "audit.yaml" + destination = "/tmp/audit.yaml" + } + + provisioner "file" { + source = "v120ingresspolicy.yaml" + destination = "/tmp/v120ingresspolicy.yaml" + } + + provisioner "file" { + source = "v121ingresspolicy.yaml" + destination = "/tmp/v121ingresspolicy.yaml" + } + + provisioner "file" { + source = "nginx-ingress.yaml" + destination = "/tmp/nginx-ingress.yaml" + } + provisioner "file" { + source = "../../scripts/optional_write_files.sh" + destination = "/tmp/optional_write_files.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/optional_write_files.sh", + "sudo /tmp/optional_write_files.sh \"${var.optional_files}\"", + ] + } + + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/install_k3s_master.sh", + "sudo /tmp/install_k3s_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : "fake.fqdn.value"} ${var.install_mode} ${var.k3s_version} ${var.cluster_type} ${self.public_ip} \"${data.template_file.test.rendered}\" \"${var.server_flags}\" ${var.username} ${var.password} ${var.k3s_channel} ${var.enforce_mode}", + ] + } + + provisioner "local-exec" { + command = "echo ${aws_instance.master.public_ip} >/tmp/${var.resource_name}_master_ip" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/nodetoken /tmp/${var.resource_name}_nodetoken" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/config /tmp/${var.resource_name}_config" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/joinflags /tmp/${var.resource_name}_joinflags" + } + provisioner "local-exec" { + command = "sed s/127.0.0.1/\"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\"/g /tmp/${var.resource_name}_config >/tmp/${var.resource_name}_kubeconfig" + + } +} + +data "template_file" "test" { + template = (var.cluster_type == "etcd" ? "NULL": (var.external_db == "postgres" ? "postgres://${aws_db_instance.db[0].username}:${aws_db_instance.db[0].password}@${aws_db_instance.db[0].endpoint}/${aws_db_instance.db[0].name}" : (var.external_db == "aurora-mysql" ? "mysql://${aws_rds_cluster.db[0].master_username}:${aws_rds_cluster.db[0].master_password}@tcp(${aws_rds_cluster.db[0].endpoint})/${aws_rds_cluster.db[0].database_name}" : "mysql://${aws_db_instance.db[0].username}:${aws_db_instance.db[0].password}@tcp(${aws_db_instance.db[0].endpoint})/${aws_db_instance.db[0].name}"))) + depends_on = [data.template_file.test_status] +} + +data "template_file" "test_status" { + template = (var.cluster_type == "etcd" ? "NULL": ((var.external_db == "postgres" ? aws_db_instance.db[0].endpoint : (var.external_db == "aurora-mysql" ? aws_rds_cluster_instance.db[0].endpoint : aws_db_instance.db[0].endpoint)))) +} + +data "local_file" "token" { + filename = "/tmp/${var.resource_name}_nodetoken" + depends_on = [aws_instance.master] +} + +locals { + node_token = trimspace("${data.local_file.token.content}") +} + +resource "aws_instance" "master2-ha" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_server_nodes + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.access_key_name + depends_on = [aws_instance.master] + tags = { + Name = "${var.resource_name}-servers" + } + provisioner "file" { + source = "join_k3s_master.sh" + destination = "/tmp/join_k3s_master.sh" + } + + provisioner "file" { + source = "cis_masterconfig.yaml" + destination = "/tmp/cis_masterconfig.yaml" + } + + provisioner "file" { + source = "cis_v125_masterconfig.yaml" + destination = "/tmp/cis_v125_masterconfig.yaml" + } + + provisioner "file" { + source = "policy.yaml" + destination = "/tmp/policy.yaml" + } + + provisioner "file" { + source = "v125_policy.yaml" + destination = "/tmp/v125_policy.yaml" + } + + provisioner "file" { + source = "audit.yaml" + destination = "/tmp/audit.yaml" + } + + provisioner "file" { + source = "v120ingresspolicy.yaml" + destination = "/tmp/v120ingresspolicy.yaml" + } + + provisioner "file" { + source = "v121ingresspolicy.yaml" + destination = "/tmp/v121ingresspolicy.yaml" + } + provisioner "file" { + source = "../../scripts/optional_write_files.sh" + destination = "/tmp/optional_write_files.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/optional_write_files.sh", + "sudo /tmp/optional_write_files.sh \"${var.optional_files}\"", + ] + } + + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_k3s_master.sh", + "sudo /tmp/join_k3s_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip} ${var.install_mode} ${var.k3s_version} ${var.cluster_type} ${self.public_ip} ${aws_instance.master.public_ip} ${local.node_token} \"${data.template_file.test.rendered}\" \"${var.server_flags}\" ${var.username} ${var.password} ${var.k3s_channel} ${var.enforce_mode}", + ] + } +} + +resource "aws_lb_target_group" "aws_tg_80" { + port = 80 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-80" + health_check { + protocol = "HTTP" + port = "traffic-port" + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80" { + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + target_id = "${aws_instance.master.id}" + port = 80 + depends_on = ["aws_instance.master"] + count = var.create_lb ? 1 : 0 +} + + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 80 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group" "aws_tg_443" { + port = 443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-443" + health_check { + protocol = "HTTP" + port = 80 + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443" { + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 443 + depends_on = ["aws_instance.master"] + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb_target_group" "aws_tg_6443" { + port = 6443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-6443" + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443" { + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 6443 + depends_on = ["aws_instance.master"] + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + count = var.create_lb ? length(aws_instance.master2-ha) : 0 + target_id = "${aws_instance.master2-ha[count.index].id}" + port = 6443 + depends_on = ["aws_instance.master"] +} + +resource "aws_lb" "aws_nlb" { + internal = false + load_balancer_type = "network" + subnets = ["${var.subnets}"] + name = "${var.resource_name}-nlb" + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_80" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "80" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_443" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_6443" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "6443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_route53_record" "aws_route53" { + zone_id = "${data.aws_route53_zone.selected.zone_id}" + name = "${var.resource_name}" + type = "CNAME" + ttl = "300" + records = ["${aws_lb.aws_nlb[0].dns_name}"] + count = var.create_lb ? 1 : 0 +} + +data "aws_route53_zone" "selected" { + name = "${var.qa_space}" + private_zone = false +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/join_k3s_master.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/join_k3s_master.sh new file mode 100644 index 0000000..d45ca4c --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/join_k3s_master.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# This script is used to join one or more nodes as masters +echo "$@" + +mkdir -p /etc/rancher/k3s +mkdir -p /var/lib/rancher/k3s/server/logs +cat <>/etc/rancher/k3s/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +token: ${8} +EOF + +if [[ -n "${10}" ]] && [[ "${10}" == *":"* ]] +then + echo -e "${10}" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi + +if [[ -n "${10}" ]] && [[ "${10}" == *"protect-kernel-defaults"* ]] +then + mkdir -p /var/lib/rancher/k3s/server/manifests + if [[ "${1}" == *"centos"* ]] || [[ "${1}" == *"rhel"* ]] || [[ "${1}" == *"rocky"* ]] + then + yum -y install bc + fi + calc(){ awk "BEGIN { print "$*" }"; } + version=`echo ${4}|cut -c2-5` + conversion=$(calc $version*1) + if (( $(echo "$conversion >= 1.25" | bc -l) )) + then + cat /tmp/cis_v125_masterconfig.yaml >> /etc/rancher/k3s/config.yaml + cat /tmp/v125_policy.yaml > /var/lib/rancher/k3s/server/manifests/policy.yaml + else + cat /tmp/cis_masterconfig.yaml >> /etc/rancher/k3s/config.yaml + cat /tmp/policy.yaml > /var/lib/rancher/k3s/server/manifests/policy.yaml + fi + echo -e "vm.panic_on_oom=0" >>/etc/sysctl.d/90-kubelet.conf + echo -e "vm.overcommit_memory=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic=10" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic_on_oops=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.keys.root_maxbytes=25000000" >>/etc/sysctl.d/90-kubelet.conf + sysctl -p /etc/sysctl.d/90-kubelet.conf + systemctl restart systemd-sysctl + cat /tmp/audit.yaml > /var/lib/rancher/k3s/server/audit.yaml + if [[ "${4}" == *"v1.18"* ]] || [[ "${4}" == *"v1.19"* ]] || [[ "${4}" == *"v1.20"* ]] || [[ "${4}" == *"v1.21"* ]] || [[ "${4}" == *"v1.22"* ]] + then + cat /tmp/v120ingresspolicy.yaml > /var/lib/rancher/k3s/server/manifests/v120ingresspolicy.yaml + else + cat /tmp/v121ingresspolicy.yaml > /var/lib/rancher/k3s/server/manifests/v121ingresspolicy.yaml + fi +fi + +if [ "${1}" = "rhel" ] +then + subscription-manager register --auto-attach --username="${11}" --password="${12}" + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi +export "${3}"="${4}" +if [ "${5}" = "etcd" ] +then + if [[ "${4}" == *"v1.18"* ]] || [["${4}" == *"v1.17"* ]] && [[ -n "${10}" ]] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --server https://"${7}":6443 --token "${8}" --node-external-ip="${6}" --tls-san "${2}" --write-kubeconfig-mode "0644" + else + if [ ${13} != "null" ] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${13} INSTALL_K3S_TYPE='server' sh -s - server --server https://"${7}":6443 --node-external-ip="${6}" + else + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --server https://"${7}":6443 --node-external-ip="${6}" + fi + fi +else + if [[ "${4}" == *"v1.18"* ]] || [["${4}" == *"v1.17"* ]] && [[ -n "${10}" ]] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --node-external-ip="${6}" --datastore-endpoint="${9}" --tls-san "${2}" --write-kubeconfig-mode "0644" + else + if [ ${13} != "null" ] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${13} INSTALL_K3S_TYPE='server' sh -s - server --node-external-ip="${6}" --datastore-endpoint="${9}" + else + curl -sfL https://get.k3s.io | INSTALL_K3S_TYPE='server' sh -s - server --node-external-ip="${6}" --datastore-endpoint="${9}" + fi + fi +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/nginx-ingress.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/nginx-ingress.yaml new file mode 100644 index 0000000..a0a47fb --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/nginx-ingress.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ingress-nginx +--- +apiVersion: helm.cattle.io/v1 +kind: HelmChart +metadata: + name: ingress-nginx + namespace: kube-system +spec: + chart: ingress-nginx + repo: https://kubernetes.github.io/ingress-nginx + targetNamespace: ingress-nginx + version: v4.0.19 + set: + valuesContent: |- + fullnameOverride: ingress-nginx + controller: + kind: DaemonSet + admissionWebhooks: + failurePolicy: Ignore + dnsPolicy: ClusterFirstWithHostNet + watchIngressWithoutClass: true + allowSnippetAnnotations: false + hostNetwork: true + hostPort: + enabled: true + publishService: + enabled: false + service: + enabled: false + metrics: + enabled: true + config: + use-forwarded-headers: "true" + server-tokens: "false" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/output.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/output.tf new file mode 100644 index 0000000..9f16afa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/output.tf @@ -0,0 +1,9 @@ +output "Route53_info" { + value = aws_route53_record.aws_route53.* + description = "List of DNS records" +} + +output "masters_public_ip" { + value = "${aws_instance.master.*.public_ip}" + description = "The public IP of the AWS node" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/policy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/policy.yaml new file mode 100644 index 0000000..ffef937 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/policy.yaml @@ -0,0 +1,219 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-network-dns-policy + namespace: kube-system +spec: + ingress: + - ports: + - port: 53 + protocol: TCP + - port: 53 + protocol: UDP + podSelector: + matchLabels: + k8s-app: kube-dns + policyTypes: + - Ingress +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: restricted-psp +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'csi' + - 'persistentVolumeClaim' + - 'ephemeral' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: psp:restricted-psp + labels: + addonmanager.kubernetes.io/mode: EnsureExists +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - restricted-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: default:restricted-psp + labels: + addonmanager.kubernetes.io/mode: EnsureExists +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp:restricted-psp +subjects: +- kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: kube-system +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: kube-system +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: default +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: default +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: kube-public +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: kube-public +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: system-unrestricted-psp +spec: + allowPrivilegeEscalation: true + allowedCapabilities: + - '*' + fsGroup: + rule: RunAsAny + hostIPC: true + hostNetwork: true + hostPID: true + hostPorts: + - max: 65535 + min: 0 + privileged: true + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: system-unrestricted-node-psp-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system-unrestricted-psp-role +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:nodes +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: system-unrestricted-psp-role +rules: +- apiGroups: + - policy + resourceNames: + - system-unrestricted-psp + resources: + - podsecuritypolicies + verbs: + - use +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: system-unrestricted-svc-acct-psp-rolebinding + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system-unrestricted-psp-role +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:serviceaccounts +--- +# Reference https://rancher.com/docs/k3s/latest/en/security/hardening_guide/#networkpolicies +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-svclbtraefik-ingress + namespace: kube-system +spec: + podSelector: + matchLabels: + svccontroller.k3s.cattle.io/svcname: traefik + ingress: + - {} + policyTypes: + - Ingress +--- +# Reference https://rancher.com/docs/k3s/latest/en/security/hardening_guide/#networkpolicies +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-metrics-server + namespace: kube-system +spec: + podSelector: + matchLabels: + k8s-app: metrics-server + ingress: + - {} + policyTypes: + - Ingress +--- diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/providers.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/providers.tf new file mode 100644 index 0000000..0ced9d7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "${var.region}" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v120ingresspolicy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v120ingresspolicy.yaml new file mode 100644 index 0000000..50c1483 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v120ingresspolicy.yaml @@ -0,0 +1,15 @@ +# 1.20 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-traefik-v120-ingress + namespace: kube-system +spec: + podSelector: + matchLabels: + app: traefik + ingress: + - {} + policyTypes: + - Ingress + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v121ingresspolicy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v121ingresspolicy.yaml new file mode 100644 index 0000000..06fdb07 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v121ingresspolicy.yaml @@ -0,0 +1,14 @@ +# 1.21 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-traefik-v121-ingress + namespace: kube-system +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: traefik + ingress: + - {} + policyTypes: + - Ingress diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v125_policy.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v125_policy.yaml new file mode 100644 index 0000000..156aa38 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/v125_policy.yaml @@ -0,0 +1,88 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-network-dns-policy + namespace: kube-system +spec: + ingress: + - ports: + - port: 53 + protocol: TCP + - port: 53 + protocol: UDP + podSelector: + matchLabels: + k8s-app: kube-dns + policyTypes: + - Ingress +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: kube-system +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: kube-system +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: default +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: default +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: intra-namespace + namespace: kube-public +spec: + podSelector: {} + ingress: + - from: + - namespaceSelector: + matchLabels: + name: kube-public +--- +# Reference https://rancher.com/docs/k3s/latest/en/security/hardening_guide/#networkpolicies +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-svclbtraefik-ingress + namespace: kube-system +spec: + podSelector: + matchLabels: + svccontroller.k3s.cattle.io/svcname: traefik + ingress: + - {} + policyTypes: + - Ingress +--- +# Reference https://rancher.com/docs/k3s/latest/en/security/hardening_guide/#networkpolicies +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-all-metrics-server + namespace: kube-system +spec: + podSelector: + matchLabels: + k8s-app: metrics-server + ingress: + - {} + policyTypes: + - Ingress +--- + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/variables.tf new file mode 100644 index 0000000..e79e287 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/master/variables.tf @@ -0,0 +1,40 @@ +variable "access_key" {} +variable "access_key_name" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "region" {} +variable "qa_space" {} +variable "sg_id" {} +variable "subnets" {} +variable "vpc_id" {} +variable "availability_zone" {} +variable "ec2_instance_class" {} +variable "volume_size" {} +variable "resource_name" {} + +variable "username" {} +variable "password" {} +variable "install_mode" {} +variable "k3s_version" {} +variable "k3s_channel" {} +variable "no_of_server_nodes" {} +variable "server_flags" {} +variable "cluster_type" {} +variable "node_os" {} +variable "enforce_mode" {} +variable "optional_files" {} + +variable "create_lb" { + description = "Create Network Load Balancer if set to true" + type = bool +} + +variable "external_db" {} +variable "external_db_version" {} +variable "db_group_name" {} +variable "db_username" {} +variable "db_password" {} +variable "environment" {} +variable "engine_mode" {} +variable "instance_class" {} +variable "max_connections" {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/cis_workerconfig.yaml b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/cis_workerconfig.yaml new file mode 100644 index 0000000..15b87a7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/cis_workerconfig.yaml @@ -0,0 +1,3 @@ +kubelet-arg: + - 'streaming-connection-idle-timeout=5m' + - 'make-iptables-util-chains=true' diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/instances_worker.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/instances_worker.tf new file mode 100644 index 0000000..fc2ef25 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/instances_worker.tf @@ -0,0 +1,59 @@ +resource "aws_instance" "worker" { + depends_on = [ + var.dependency + ] + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_worker_nodes + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = file(var.access_key) + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [var.sg_id] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-worker" + } + provisioner "file" { + source = "join_k3s_agent.sh" + destination = "/tmp/join_k3s_agent.sh" + } + provisioner "file" { + source = "cis_workerconfig.yaml" + destination = "/tmp/cis_workerconfig.yaml" + } + + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_k3s_agent.sh", + "sudo /tmp/join_k3s_agent.sh ${var.node_os} ${var.install_mode} ${var.k3s_version} ${local.master_ip} ${local.node_token} ${self.public_ip} \"${var.worker_flags}\" ${var.username} ${var.password} ${var.k3s_channel} ", + ] + } +} + +data "local_file" "master_ip" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_master_ip" +} + +locals { + master_ip = trimspace(data.local_file.master_ip.content) +} + +data "local_file" "token" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_nodetoken" +} + +locals { + node_token = trimspace(data.local_file.token.content) +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/join_k3s_agent.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/join_k3s_agent.sh new file mode 100644 index 0000000..2af51c5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/join_k3s_agent.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# This script is used to join one or more nodes as agents +echo $@ + +mkdir -p /etc/rancher/k3s +cat <>/etc/rancher/k3s/config.yaml +server: https://${4}:6443 +token: "${5}" +EOF + +if [[ ! -z "${7}" ]] && [[ "${7}" == *":"* ]] +then + echo -e "${7}" >> /etc/rancher/k3s/config.yaml + cat /etc/rancher/k3s/config.yaml +fi +if [[ -n "${7}" ]] && [[ "${7}" == *"protect-kernel-defaults"* ]] +then + cat /tmp/cis_workerconfig.yaml >> /etc/rancher/k3s/config.yaml + echo -e "vm.panic_on_oom=0" >>/etc/sysctl.d/90-kubelet.conf + echo -e "vm.overcommit_memory=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic=10" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.panic_on_oops=1" >>/etc/sysctl.d/90-kubelet.conf + echo -e "kernel.keys.root_maxbytes=25000000" >>/etc/sysctl.d/90-kubelet.conf + sysctl -p /etc/sysctl.d/90-kubelet.conf + systemctl restart systemd-sysctl +fi + +if [ ${1} = "rhel" ] +then + subscription-manager register --auto-attach --username=${8} --password=${9} + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +export "${2}"="${3}" +if [[ "${3}" == *"v1.18"* ]] || [[ "${3}" == *"v1.17"* ]] && [[ -n "${7}" ]] +then + echo "curl -sfL https://get.k3s.io | sh -s - ${7} --node-external-ip=${6} --server https://${4}:6443 --token ${5} ${7}" + curl -sfL https://get.k3s.io | sh -s - ${7} --node-external-ip=${6} --server https://"${4}":6443 --token "${5}" +else + if [ ${10} != "null" ] + then + curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=${10} sh -s - agent --node-external-ip=${6} + else + curl -sfL https://get.k3s.io | sh -s - agent --node-external-ip=${6} + fi +fi +sleep 20 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/outputs.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/outputs.tf new file mode 100644 index 0000000..a94688a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/outputs.tf @@ -0,0 +1,12 @@ +output "Registration_address" { + value = "${data.local_file.master_ip.content}" +} + +output "master_node_token" { + value = "${data.local_file.token.content}" +} + +output "workers_public_ip" { + value = "${aws_instance.worker.*.public_ip}" + description = "The public IP of the AWS node" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/providers.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/providers.tf new file mode 100644 index 0000000..0ced9d7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/providers.tf @@ -0,0 +1,3 @@ +provider "aws" { + region = "${var.region}" +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/variables.tf new file mode 100644 index 0000000..13dce72 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/k3s/worker/variables.tf @@ -0,0 +1,27 @@ +variable "dependency" { + type = any + default = null +} +variable "region" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "volume_size" {} +variable "vpc_id" {} +variable "sg_id" {} +variable "subnets" {} +variable "access_key" {} +variable "access_key_name" {} +variable "ec2_instance_class" {} +variable "availability_zone" {} +variable "resource_name" {} + +variable "username" {} +variable "password" {} +variable "k3s_version" {} +variable "k3s_channel" {} +variable "no_of_worker_nodes" {} +variable "worker_flags" {} +variable "node_os" {} +variable "install_mode" {} + + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/define_node_role.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/define_node_role.sh new file mode 100644 index 0000000..6080b43 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/define_node_role.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# This script defines which role this node will be and writes that to a file +# that is readable by rke2 + + +if [ $# != 8 ]; then + echo "Usage: define_node_roles.sh node_index role_order all_role_nodes etcd_only_nodes etcd_cp_nodes etcd_worker_nodes cp_only_nodes cp_worker_nodes" + exit 1 +fi + +let node_index=$1+1 +role_order=$2 +all_role_nodes=$3 +etcd_only_nodes=$4 +etcd_cp_nodes=$5 +etcd_worker_nodes=$6 +cp_only_nodes=$7 +cp_worker_nodes=$8 + +# Set the desired role into an array based on the index +order_array=($(echo "$role_order" | tr ',' '\n')) +role_array=() +for order_num in "${order_array[@]}" +do + if [[ "$order_num" = "1" ]] + then + until [ $all_role_nodes -le "0" ] + do + role_array+=("all-roles") + let "all_role_nodes-=1" + done + elif [[ "$order_num" = "2" ]] + then + until [ $etcd_only_nodes -le "0" ] + do + role_array+=("etcd-only") + let "etcd_only_nodes-=1" + done + elif [[ "$order_num" = "3" ]] + then + until [ $etcd_cp_nodes -le "0" ] + do + role_array+=("etcd-cp") + let "etcd_cp_nodes-=1" + done + elif [[ "$order_num" = "4" ]] + then + until [ $etcd_worker_nodes -le "0" ] + do + role_array+=("etcd-worker") + let "etcd_worker_nodes-=1" + done + elif [[ "$order_num" = "5" ]] + then + until [ $cp_only_nodes -le "0" ] + do + role_array+=("cp-only") + let "cp_only_nodes-=1" + done + elif [[ "$order_num" = "6" ]] + then + until [ $cp_worker_nodes -le "0" ] + do + role_array+=("cp-worker") + let "cp_worker_nodes-=1" + done + fi +done + +# Get role based on which node is being created +role="${role_array[$node_index]}" +echo "Writing config for a ${role} node." + +# Write config +mkdir -p /etc/rancher/rke2/config.yaml.d +if [[ $role == "etcd-only" ]] +then +cat << EOF > /etc/rancher/rke2/config.yaml.d/role_config.yaml +disable-apiserver: true +disable-controller-manager: true +disable-scheduler: true +node-taint: + - node-role.kubernetes.io/etcd:NoExecute +EOF + +elif [[ $role == "etcd-cp" ]] +then +cat << EOF > /etc/rancher/rke2/config.yaml.d/role_config.yaml +node-taint: + - node-role.kubernetes.io/control-plane:NoSchedule + - node-role.kubernetes.io/etcd:NoExecute +EOF + +elif [[ $role == "etcd-worker" ]] +then +cat << EOF > /etc/rancher/rke2/config.yaml.d/role_config.yaml +disable-apiserver: true +disable-controller-manager: true +disable-scheduler: true +EOF + +elif [[ $role == "cp-only" ]] +then +cat << EOF > /etc/rancher/rke2/config.yaml.d/role_config.yaml +disable-etcd: true +node-taint: + - node-role.kubernetes.io/control-plane:NoSchedule +EOF + +elif [[ $role == "cp-worker" ]] +then +cat << EOF > /etc/rancher/rke2/config.yaml.d/role_config.yaml +disable-etcd: true +EOF +fi \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/install_rke2_master.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/install_rke2_master.sh new file mode 100755 index 0000000..49c0e1e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/install_rke2_master.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# This script installs the first master, ensuring first master is installed +# and ready before proceeding to install other nodes +set -x +echo $@ +hostname=`hostname -f` +mkdir -p /etc/rancher/rke2 +cat << EOF >/etc/rancher/rke2/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +node-name: ${hostname} +EOF + +if [ ! -z "${7}" ] && [[ "${7}" == *":"* ]] +then + echo "${7}" + echo -e "${7}" >> /etc/rancher/rke2/config.yaml + if [[ "${7}" != *"cloud-provider-name"* ]] + then + echo -e "node-external-ip: ${4}" >> /etc/rancher/rke2/config.yaml + fi + cat /etc/rancher/rke2/config.yaml +else + echo -e "node-external-ip: ${4}" >> /etc/rancher/rke2/config.yaml +fi + +if [[ ${1} = "rhel" ]] +then + subscription-manager register --auto-attach --username=${9} --password=${10} + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +if [ ${1} = "centos8" ] || [ ${1} = "rhel8" ] +then + yum install tar -y + yum install iptables -y + workaround="[keyfile]\nunmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:flannel*" + if [ ! -e /etc/NetworkManager/conf.d/canal.conf ]; then + echo -e $workaround > /etc/NetworkManager/conf.d/canal.conf + else + echo -e $workaround >> /etc/NetworkManager/conf.d/canal.conf + fi + sudo systemctl reload NetworkManager +fi + +export "${8}"="${3}" +if [ ! -z "${11}" ] +then + export INSTALL_RKE2_METHOD="${11}" +fi + +if [ ${6} = "rke2" ] +then + if [ ${5} != "null" ] + then + curl -sfL https://get.rke2.io | INSTALL_RKE2_CHANNEL=${5} sh - + else + curl -sfL https://get.rke2.io | sh - + fi + sleep 10 + if [ ! -z "${7}" ] && [[ "${7}" == *"cis"* ]] + then + if [[ ${1} == *"rhel"* ]] || [[ ${1} == *"centos"* ]] + then + cp -f /usr/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + else + cp -f /usr/local/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + fi + systemctl restart systemd-sysctl + useradd -r -c "etcd user" -s /sbin/nologin -M etcd -U + fi + sudo systemctl enable rke2-server + sudo systemctl start rke2-server +else + curl -sfL https://get.rancher.io | INSTALL_RANCHERD_VERSION=${3} sh - + sudo systemctl enable rancherd-server + sudo systemctl start rancherd-server +fi + +timeElapsed=0 +while [[ $timeElapsed -lt 600 ]] +do + notready=false + if [[ ! -f /var/lib/rancher/rke2/server/node-token ]] || [[ ! -f /etc/rancher/rke2/rke2.yaml ]] + then + notready=true + fi + if [[ $notready == false ]] + then + break + fi + sleep 5 + timeElapsed=`expr $timeElapsed + 5` +done + +cat /etc/rancher/rke2/config.yaml> /tmp/joinflags +cat /var/lib/rancher/rke2/server/node-token >/tmp/nodetoken +cat /etc/rancher/rke2/rke2.yaml >/tmp/config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/instances_server.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/instances_server.tf new file mode 100644 index 0000000..6b2dca2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/instances_server.tf @@ -0,0 +1,329 @@ +resource "aws_instance" "master" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + iam_instance_profile = "${var.iam_role}" + connection { + type = "ssh" + user = "${var.aws_user}" + host = self.public_ip + private_key = "${file(var.access_key)}" + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = ["${var.sg_id}"] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-server" + "kubernetes.io/cluster/clusterid" = "owned" + } + provisioner "file" { + source = "../../scripts/optional_write_files.sh" + destination = "/tmp/optional_write_files.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/optional_write_files.sh", + "sudo /tmp/optional_write_files.sh \"${var.optional_files}\"", + ] + } + provisioner "file" { + source = "define_node_role.sh" + destination = "/tmp/define_node_role.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/define_node_role.sh", + "sudo /tmp/define_node_role.sh -1 \"${var.role_order}\" ${var.all_role_nodes} ${var.etcd_only_nodes} ${var.etcd_cp_nodes} ${var.etcd_worker_nodes} ${var.cp_only_nodes} ${var.cp_worker_nodes}", + ] + } + provisioner "file" { + source = "install_rke2_master.sh" + destination = "/tmp/install_rke2_master.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/install_rke2_master.sh", + "sudo /tmp/install_rke2_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : "fake.fqdn.value"} ${var.rke2_version} ${self.public_ip} ${var.rke2_channel} ${var.cluster_type} \"${var.server_flags}\" ${var.install_mode} ${var.username} ${var.password} \"${var.install_method}\"", + ] + } + provisioner "local-exec" { + command = "echo ${aws_instance.master.public_ip} >/tmp/${var.resource_name}_master_ip" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/nodetoken /tmp/${var.resource_name}_nodetoken" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/config /tmp/${var.resource_name}_config" + } + provisioner "local-exec" { + command = "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${var.access_key} ${var.aws_user}@${aws_instance.master.public_ip}:/tmp/joinflags /tmp/${var.resource_name}_joinflags" + } + provisioner "local-exec" { + command = "sed s/127.0.0.1/\"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\"/g /tmp/${var.resource_name}_config >/tmp/${var.resource_name}_kubeconfig" + } +} + +resource "aws_instance" "master2" { + ami = var.aws_ami + instance_type = var.ec2_instance_class + iam_instance_profile = "${var.iam_role}" + count = var.no_of_server_nodes + connection { + type = "ssh" + user = "${var.aws_user}" + host = self.public_ip + private_key = "${file(var.access_key)}" + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = ["${var.sg_id}"] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-servers" + "kubernetes.io/cluster/clusterid" = "owned" + } + depends_on = ["aws_instance.master"] + provisioner "file" { + source = "../../scripts/optional_write_files.sh" + destination = "/tmp/optional_write_files.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/optional_write_files.sh", + "sudo /tmp/optional_write_files.sh \"${var.optional_files}\"", + ] + } + provisioner "file" { + source = "define_node_role.sh" + destination = "/tmp/define_node_role.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/define_node_role.sh", + "sudo /tmp/define_node_role.sh ${count.index} \"${var.role_order}\" ${var.all_role_nodes} ${var.etcd_only_nodes} ${var.etcd_cp_nodes} ${var.etcd_worker_nodes} ${var.cp_only_nodes} ${var.cp_worker_nodes}", + ] + } + provisioner "file" { + source = "join_rke2_master.sh" + destination = "/tmp/join_rke2_master.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_rke2_master.sh", + "sudo /tmp/join_rke2_master.sh ${var.node_os} ${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip} ${aws_instance.master.public_ip} ${local.node_token} ${var.rke2_version} ${self.public_ip} ${var.rke2_channel} ${var.cluster_type} \"${var.server_flags}\" ${var.install_mode} ${var.username} ${var.password} \"${var.install_method}\"", + ] + } +} + +data "local_file" "token" { + filename = "/tmp/${var.resource_name}_nodetoken" + depends_on = [aws_instance.master] +} + +locals { + node_token = trimspace("${data.local_file.token.content}") +} + +resource "local_file" "master_ips" { + content = join("," , aws_instance.master.*.public_ip,aws_instance.master2.*.public_ip) + filename = "/tmp/${var.resource_name}_master_ips" +} + +resource "aws_lb_target_group" "aws_tg_6443" { + port = 6443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-6443" + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group" "aws_tg_9345" { + port = 9345 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-9345" + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group" "aws_tg_80" { + port = 80 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-80" + health_check { + protocol = "HTTP" + port = "traffic-port" + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group" "aws_tg_443" { + port = 443 + protocol = "TCP" + vpc_id = "${var.vpc_id}" + name = "${var.resource_name}-tg-443" + health_check { + protocol = "HTTP" + port = 80 + path = "/ping" + interval = 10 + timeout = 6 + healthy_threshold = 3 + unhealthy_threshold = 3 + matcher = "200-399" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443" { + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 6443 + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_6443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + count = var.create_lb ? length(aws_instance.master2) : 0 + target_id = "${aws_instance.master2[count.index].id}" + port = 6443 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_9345" { + target_group_arn = "${aws_lb_target_group.aws_tg_9345[0].arn}" + target_id = "${aws_instance.master.id}" + port = 9345 + count = var.create_lb ? 1 : 0 +} +resource "aws_lb_target_group_attachment" "aws_tg_attachment_9345_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_9345[0].arn}" + count = var.create_lb ? length(aws_instance.master2) : 0 + target_id = "${aws_instance.master2[count.index].id}" + port = 9345 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80" { + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + target_id = "${aws_instance.master.id}" + port = 80 + depends_on = [aws_instance.master] + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_80_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + count = var.create_lb ? length(aws_instance.master2) : 0 + target_id = "${aws_instance.master2[count.index].id}" + port = 80 + depends_on = [aws_instance.master] +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443" { + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + target_id = "${aws_instance.master.id}" + port = 443 + depends_on = [aws_instance.master] + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_target_group_attachment" "aws_tg_attachment_443_2" { + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + count = var.create_lb ? length(aws_instance.master2) : 0 + target_id = "${aws_instance.master2[count.index].id}" + port = 443 + depends_on = [aws_instance.master] +} + +resource "aws_lb" "aws_nlb" { + internal = false + load_balancer_type = "network" + subnets = ["${var.subnets}"] + name = "${var.resource_name}-nlb" + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_6443" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "6443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_6443[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_9345" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "9345" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_9345[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_80" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "80" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_80[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_lb_listener" "aws_nlb_listener_443" { + load_balancer_arn = "${aws_lb.aws_nlb[0].arn}" + port = "443" + protocol = "TCP" + default_action { + type = "forward" + target_group_arn = "${aws_lb_target_group.aws_tg_443[0].arn}" + } + count = var.create_lb ? 1 : 0 +} + +resource "aws_route53_record" "aws_route53" { + zone_id = "${data.aws_route53_zone.selected.zone_id}" + name = "${var.resource_name}" + type = "CNAME" + ttl = "300" + records = ["${aws_lb.aws_nlb[0].dns_name}"] + count = var.create_lb ? 1 : 0 +} + +data "aws_route53_zone" "selected" { + name = "${var.qa_space}" + private_zone = false +} + +resource "null_resource" "update_kubeconfig" { + provisioner "local-exec" { + command = "sed s/127.0.0.1/\"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\"/g /tmp/\"${var.resource_name}_config\" >/tmp/${var.resource_name}_kubeconfig" + } + depends_on = [aws_instance.master] +} + +resource "null_resource" "store_fqdn" { + provisioner "local-exec" { + command = "echo \"${var.create_lb ? aws_route53_record.aws_route53[0].fqdn : aws_instance.master.public_ip}\" >/tmp/${var.resource_name}_fixed_reg_addr" + } + depends_on = [aws_instance.master] +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/join_rke2_master.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/join_rke2_master.sh new file mode 100755 index 0000000..8edaa4a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/join_rke2_master.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# This script is used to join one or more nodes as masters to the first master +set -x +echo $@ +hostname=`hostname -f` +mkdir -p /etc/rancher/rke2 +cat <>/etc/rancher/rke2/config.yaml +write-kubeconfig-mode: "0644" +tls-san: + - ${2} +server: https://${3}:9345 +token: "${4}" +node-name: "${hostname}" +EOF + +if [ ! -z "${9}" ] && [[ "${9}" == *":"* ]] +then + echo "${9}" + echo -e "${9}" >> /etc/rancher/rke2/config.yaml + if [[ "${9}" != *"cloud-provider-name"* ]] + then + echo -e "node-external-ip: ${6}" >> /etc/rancher/rke2/config.yaml + fi + cat /etc/rancher/rke2/config.yaml +else + echo -e "node-external-ip: ${6}" >> /etc/rancher/rke2/config.yaml +fi + +if [[ ${1} = "rhel" ]] +then + subscription-manager register --auto-attach --username=${11} --password=${12} + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +if [ ${1} = "centos8" ] || [ ${1} = "rhel8" ] +then + yum install tar -y + yum install iptables -y + workaround="[keyfile]\nunmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:flannel*" + if [ ! -e /etc/NetworkManager/conf.d/canal.conf ]; then + echo -e $workaround > /etc/NetworkManager/conf.d/canal.conf + else + echo -e $workaround >> /etc/NetworkManager/conf.d/canal.conf + fi + sudo systemctl reload NetworkManager +fi + +export "${10}"="${5}" +if [ ! -z "${13}" ] +then + export INSTALL_RKE2_METHOD="${13}" +fi + +if [ ${8} = "rke2" ] +then + if [ ${7} != "null" ] + then + curl -sfL https://get.rke2.io | INSTALL_RKE2_CHANNEL=${7} sh - + else + curl -sfL https://get.rke2.io | sh - + fi + sleep 10 + if [ ! -z "${9}" ] && [[ "${9}" == *"cis"* ]] + then + if [[ ${1} == *"rhel"* ]] || [[ ${1} == *"centos"* ]] + then + cp -f /usr/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + else + cp -f /usr/local/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + fi + systemctl restart systemd-sysctl + useradd -r -c "etcd user" -s /sbin/nologin -M etcd -U + fi + sudo systemctl enable rke2-server + sudo systemctl start rke2-server +else + curl -sfL https://get.rancher.io | INSTALL_RANCHERD_VERSION=${5} sh - + sudo systemctl enable rancherd-server + sudo systemctl start rancherd-server +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/outputs.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/outputs.tf new file mode 100644 index 0000000..c97e5d4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/outputs.tf @@ -0,0 +1,13 @@ +output "Route53_info" { + value = aws_route53_record.aws_route53.* + description = "List of DNS records" +} + +output "kubeconfig" { + value = var.resource_name + description = "kubeconfig of the cluster created" +} + +output "master_ips" { + value = join("," , aws_instance.master.*.public_ip,aws_instance.master2.*.public_ip) +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/variables.tf new file mode 100644 index 0000000..c732d6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/master/variables.tf @@ -0,0 +1,47 @@ +variable "access_key" {} +variable "access_key_name" {} +variable "availability_zone" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "cluster_type" {} +variable "ec2_instance_class" {} +variable "volume_size" {} +variable "iam_role" {} +variable "node_os" {} +variable "no_of_server_nodes" {} +variable "password" { + default = "password" +} +variable "qa_space" {} +variable "region" {} +variable "resource_name" {} +variable "rke2_version" {} +variable "install_mode" {} +variable "install_method" {} +variable "rke2_channel" {} +variable "server_flags" {} +variable "sg_id" {} +variable "subnets" {} +variable "vpc_id" {} +variable "username" { + default = "username" +} +variable "create_lb" { + description = "Create Network Load Balancer if set to true" + type = bool +} +variable "split_roles" { + description = "When true, server nodes may be a mix of etcd, cp, and worker" + type = bool +} +variable "role_order" { + description = "Comma separated order of how to bring the nodes up when split roles" + type = string +} +variable "all_role_nodes" {} +variable "etcd_only_nodes" {} +variable "etcd_cp_nodes" {} +variable "etcd_worker_nodes" {} +variable "cp_only_nodes" {} +variable "cp_worker_nodes" {} +variable "optional_files" {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/instances_worker.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/instances_worker.tf new file mode 100644 index 0000000..0448c5f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/instances_worker.tf @@ -0,0 +1,37 @@ +resource "aws_instance" "windows_worker" { + depends_on = [ + var.dependency + ] + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_windows_worker_nodes + iam_instance_profile = "${var.iam_role}" + get_password_data = true + user_data = templatefile("join-rke2.tftpl", {serverIP: "${local.master_ip}", token: "${local.node_token}", version: "${var.rke2_version}"}) + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = ["${var.sg_id}"] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-windows-worker" + "kubernetes.io/cluster/clusterid" = "owned" + } +} + +data "local_file" "master_ip" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_master_ip" +} + +locals { + master_ip = trimspace("${data.local_file.master_ip.content}") +} + +data "local_file" "token" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_nodetoken" +} + +locals { + node_token = trimspace("${data.local_file.token.content}") +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/join-rke2.tftpl b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/join-rke2.tftpl new file mode 100644 index 0000000..811058e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/join-rke2.tftpl @@ -0,0 +1,11 @@ + +# Set default shell to powershell +New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force +Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 +Start-Service sshd +Set-Service -Name sshd -StartupType 'Automatic' +Write-Output "[INFO] Dowloading quickstart script..." +Invoke-WebRequest -Uri https://raw.githubusercontent.com/rancher/rke2/master/windows/rke2-quickstart.ps1 -Outfile C:\Users\Administrator\rke2-quickstart.ps1 +Invoke-Expression -Command "C:\Users\Administrator\rke2-quickstart.ps1 -ServerIP ${serverIP} -Token ${token} -Version ${version}" + + diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/outputs.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/outputs.tf new file mode 100644 index 0000000..7bbd0f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/outputs.tf @@ -0,0 +1,9 @@ +output "windows_worker_ips" { + value = join(",", aws_instance.windows_worker.*.public_ip) +} + +output "windows_worker_password_decrypted" { + value = [ + for agent in aws_instance.windows_worker : rsadecrypt(agent.password_data, file(var.access_key)) + ] +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/variables.tf new file mode 100644 index 0000000..f7169f4 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/windows_worker/variables.tf @@ -0,0 +1,26 @@ +variable "access_key" {} +variable "access_key_name" {} +variable "availability_zone" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "cluster_type" {} +variable "dependency" { + type = any + default = null +} +variable "ec2_instance_class" {} +variable "iam_role" {} +variable "node_os" {} +variable "no_of_windows_worker_nodes" {} +variable "password" { + default = "password" +} +variable "region" {} +variable "resource_name" {} +variable "rke2_version" {} +variable "sg_id" {} +variable "subnets" {} +variable "username" { + default = "username" +} +variable "vpc_id" {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/instances_worker.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/instances_worker.tf new file mode 100644 index 0000000..0c8f986 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/instances_worker.tf @@ -0,0 +1,66 @@ +resource "aws_instance" "worker" { + depends_on = [ + var.dependency + ] + ami = var.aws_ami + instance_type = var.ec2_instance_class + count = var.no_of_worker_nodes + iam_instance_profile = "${var.iam_role}" + connection { + type = "ssh" + user = var.aws_user + host = self.public_ip + private_key = "${file(var.access_key)}" + } + root_block_device { + volume_size = var.volume_size + volume_type = "standard" + } + subnet_id = var.subnets + availability_zone = var.availability_zone + vpc_security_group_ids = [ + "${var.sg_id}" + ] + key_name = var.access_key_name + tags = { + Name = "${var.resource_name}-worker" + "kubernetes.io/cluster/clusterid" = "owned" + } + provisioner "file" { + source = "join_rke2_agent.sh" + destination = "/tmp/join_rke2_agent.sh" + } + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/join_rke2_agent.sh", + "sudo /tmp/join_rke2_agent.sh ${var.node_os} ${local.master_fixed_reg_addr} ${local.master_ip} \"${local.node_token}\" ${var.rke2_version} ${self.public_ip} ${var.rke2_channel} ${var.cluster_type} \"${var.worker_flags}\" ${var.install_mode} ${var.username} ${var.password} \"${var.install_method}\"", + ] + } +} + +data "local_file" "master_ip" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_master_ip" +} + +locals { + master_ip = trimspace("${data.local_file.master_ip.content}") +} + +data "local_file" "token" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_nodetoken" +} + +locals { + node_token = trimspace("${data.local_file.token.content}") +} + +data "local_file" "master_fixed_reg_addr" { + depends_on = [var.dependency] + filename = "/tmp/${var.resource_name}_fixed_reg_addr" +} + +locals { + master_fixed_reg_addr = trimspace("${data.local_file.master_fixed_reg_addr.content}") +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/join_rke2_agent.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/join_rke2_agent.sh new file mode 100755 index 0000000..37e34a5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/join_rke2_agent.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# This script is used to join one or more nodes as agents +set -x +echo $@ +hostname=`hostname -f` +mkdir -p /etc/rancher/rke2 +cat <>/etc/rancher/rke2/config.yaml +server: https://${3}:9345 +token: "${4}" +node-name: "${hostname}" +EOF + +if [ ! -z "${9}" ] && [[ "${9}" == *":"* ]] +then + echo "${9}" + echo -e "${9}" >> /etc/rancher/rke2/config.yaml + if [[ "${9}" != *"cloud-provider-name"* ]] + then + echo -e "node-external-ip: ${6}" >> /etc/rancher/rke2/config.yaml + fi + cat /etc/rancher/rke2/config.yaml +else + echo -e "node-external-ip: ${6}" >> /etc/rancher/rke2/config.yaml +fi + +if [[ ${1} = "rhel" ]] +then + subscription-manager register --auto-attach --username=${11} --password=${12} + subscription-manager repos --enable=rhel-7-server-extras-rpms +fi + +if [ ${1} = "centos8" ] || [ ${1} = "rhel8" ] +then + yum install tar -y + yum install iptables -y + workaround="[keyfile]\nunmanaged-devices=interface-name:cali*;interface-name:tunl*;interface-name:vxlan.calico;interface-name:flannel*" + if [ ! -e /etc/NetworkManager/conf.d/canal.conf ]; then + echo -e $workaround > /etc/NetworkManager/conf.d/canal.conf + else + echo -e $workaround >> /etc/NetworkManager/conf.d/canal.conf + fi + sudo systemctl reload NetworkManager +fi + +export "${10}"="${5}" +if [ ! -z "${13}" ] +then + export INSTALL_RKE2_METHOD="${13}" +fi + +if [ ${8} = "rke2" ] +then + if [ ${7} != "null" ] + then + curl -sfL https://get.rke2.io | INSTALL_RKE2_CHANNEL=${7} INSTALL_RKE2_TYPE='agent' sh - + else + curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE='agent' sh - + fi + if [ ! -z "${9}" ] && [[ "${9}" == *"cis"* ]] + then + if [[ ${1} == *"rhel"* ]] || [[ ${1} == *"centos"* ]] + then + cp -f /usr/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + else + cp -f /usr/local/share/rke2/rke2-cis-sysctl.conf /etc/sysctl.d/60-rke2-cis.conf + fi + systemctl restart systemd-sysctl + fi + sudo systemctl enable rke2-agent + sudo systemctl start rke2-agent +else + curl -sfL https://get.rancher.io | INSTALL_RANCHERD_VERSION=${5} INSTALL_RKE2_TYPE='agent' sh - + sudo systemctl enable rancherd-agent + sudo systemctl start rancherd-agent +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/outputs.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/outputs.tf new file mode 100644 index 0000000..87238ee --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/outputs.tf @@ -0,0 +1,3 @@ +output "worker_ips" { + value = join(",", aws_instance.worker.*.public_ip) +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/variables.tf b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/variables.tf new file mode 100644 index 0000000..6c93cd7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/rke2/worker/variables.tf @@ -0,0 +1,31 @@ +variable "access_key" {} +variable "access_key_name" {} +variable "availability_zone" {} +variable "aws_ami" {} +variable "aws_user" {} +variable "cluster_type" {} +variable "dependency" { + type = any + default = null +} +variable "ec2_instance_class" {} +variable "volume_size" {} +variable "iam_role" {} +variable "node_os" {} +variable "no_of_worker_nodes" {} +variable "password" { + default = "password" +} +variable "region" {} +variable "resource_name" {} +variable "rke2_version" {} +variable "install_mode" {} +variable "install_method" {} +variable "rke2_channel" {} +variable "sg_id" {} +variable "subnets" {} +variable "username" { + default = "username" +} +variable "vpc_id" {} +variable "worker_flags" {} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/scripts/optional_write_files.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/scripts/optional_write_files.sh new file mode 100644 index 0000000..809b454 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/resource/terraform/scripts/optional_write_files.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# This script pulls raw files and writes to specified locations. +# For example, it can be used to write HelmChartConfig or custom PSA files. + + +files=$1 + +if [ -n "$files" ] +then + file_array=($(echo "$files" | tr ' ' '\n')) + for current_file in "${file_array[@]}"; do + file_location=$(echo "$current_file" | awk -F, '{print $1}') + mkdir -p "$(dirname "$file_location")" + + raw_data=$(echo "$current_file" | awk -F, '{print $2}') + curl -s "$raw_data" -o "$file_location" + done + +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/build.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/build.sh new file mode 100755 index 0000000..23172f3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/build.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" +RKE_VERSION="${RKE_VERSION:-v1.0.2}" +RANCHER_HELM_VERSION="${RANCHER_HELM_VERSION:-v3.8.0}" +KUBECTL_VERSION="${KUBECTL_VERSION:-v1.27.10}" +CLI_VERSION="${CLI_VERSION:-v2.4.5}" +SONOBUOY_VERSION="${SONOBUOY_VERSION:-0.18.2}" +TERRAFORM_VERSION="${TERRAFORM_VERSION:-0.12.10}" +EXTERNAL_ENCODED_VPN="${EXTERNAL_ENCODED_VPN:-1234}" +VPN_ENCODED_LOGIN="${VPN_ENCODED_LOGIN:-5678}" + +TRIM_JOB_NAME=$(basename "$JOB_NAME") + +if [ "false" != "${DEBUG}" ]; then + echo "Environment:" + env | sort +fi + +cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../../" && pwd )" + +count=0 +while [[ 3 -gt $count ]]; do + docker build -q -f Dockerfile.v3api --build-arg CLI_VERSION="$CLI_VERSION" --build-arg RKE_VERSION="$RKE_VERSION" --build-arg RANCHER_HELM_VERSION="$RANCHER_HELM_VERSION" --build-arg KUBECTL_VERSION="$KUBECTL_VERSION" --build-arg SONOBUOY_VERSION="$SONOBUOY_VERSION" --build-arg TERRAFORM_VERSION="$TERRAFORM_VERSION" --build-arg EXTERNAL_ENCODED_VPN="$EXTERNAL_ENCODED_VPN" --build-arg VPN_ENCODED_LOGIN="$VPN_ENCODED_LOGIN" -t rancher-validation-"${TRIM_JOB_NAME}""${BUILD_NUMBER}" . + + if [[ $? -eq 0 ]]; then break; fi + count=$(($count + 1)) + echo "Repeating failed Docker build ${count} of 3..." +done diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/configure.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/configure.sh new file mode 100755 index 0000000..e98eb47 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/configure.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -x +set -eu + +DEBUG="${DEBUG:-false}" + +env | egrep '^(ARM_|CATTLE_|ADMIN|USER|DO|RANCHER_|K3S_|RKE2_|AWS_|DEBUG|LOGLEVEL|DEFAULT_|OS_|DOCKER_|CLOUD_|KUBE|BUILD_NUMBER|RKE_|AZURE).*\=.+' | sort > .env + +if [ "false" != "${DEBUG}" ]; then + cat .env +fi diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/nfs-setup.sh b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/nfs-setup.sh new file mode 100644 index 0000000..7fba452 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/nfs-setup.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -x + +sudo apt-get update +if sudo apt-get install -y nfs-kernel-server ; then + echo "install nfs-kernel-server successfully, continue " +else + echo "fixing the error" + sudo rm /var/lib/apt/lists/lock /var/cache/apt/archives/lock /var/lib/dpkg/lock* + sudo dpkg --configure -a + sudo apt-get install -y nfs-kernel-server +fi + +sudo mkdir -p /nfs +sudo chown nobody:nogroup /nfs +echo "/nfs *(rw,sync,no_subtree_check)" | sudo tee /etc/exports +sudo exportfs -a +sudo service nfs-kernel-server start +sudo ufw allow 2049 diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_custom_cluster_matrix b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_custom_cluster_matrix new file mode 100644 index 0000000..37fe044 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_custom_cluster_matrix @@ -0,0 +1,133 @@ +#!groovy + +// RANCHER_VERSION resolution is first via Jenkins Build Parameter RANCHER_VERSION fed in from console, +// then from $DOCKER_TRIGGER_TAG which is sourced from the Docker Hub Jenkins plugin webhook. +def rancher_version() { + try { if ('' != RANCHER_VERSION) { return RANCHER_VERSION } } + catch (MissingPropertyException e) {} + + try { return DOCKER_TRIGGER_TAG } + catch (MissingPropertyException e) {} + + echo 'Neither RANCHER_VERSION nor DOCKER_TRIGGER_TAG have been specified!' + error() +} + +node { + def TESTS_TO_RUN = [ "test_wl", "test_dns_record", "test_rbac","test_connectivity", "test_ingress", + "test_secrets", "test_registry", "test_service_discovery"] + + if (env.RANCHER_SKIP_INGRESS == "True") { + TESTS_TO_RUN = TESTS_TO_RUN - ["test_ingress"] + } + // convert the list into pytest parameter format + def PYTEST_OPTIONS = "-k \"" + TESTS_TO_RUN.join(" or ") +"\"" + + // set the branch for the testing code + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + println "Branch env: ${env.branch}" + println "Branch: ${branch}" + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + ]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + // change the current directory + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(env.AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: env.AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('install Rancher') { + // skip provisioning a new Rancher Server + // if CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN are provided + if(env.CATTLE_TEST_URL != "" || env.ADMIN_TOKEN != "" || env.USER_TOKEN != "") { + println "Rancher Server is provided: ${env.CATTLE_TEST_URL}" + } + else { + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + def rancherContainerName = "${job_name}${env.BUILD_NUMBER}_rancher_server" + def envFile = ".env" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def rancher_version = rancher_version() + def deployPytestOptions = "-k test_deploy_rancher_server" + def setupResultsOut = "setup-results.xml" + def testResultsOut = "results.xml" + def testsDir = "tests/v3_api/" + def rancherConfig = "rancher_env.config" + def rootPath = "/src/rancher-validation/" + // deploy rancher server + sh "docker run --name ${rancherContainerName} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_SERVER_VERSION=${rancher_version} && " + + "pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN + // and load into environment variables + sh "docker cp ${rancherContainerName}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + println "Rancher Server ip: ${env.CATTLE_TEST_URL}" + } + } + + stage('run subjobs in parallel') { + try { + jobs = [:] + // get the list of versions + def versions = RANCHER_CLUSTER_OS_DOCKER_VERSION.split(',') + for(int i = 0; i < versions.size(); i++) { + def items = versions[i].split(':') + def name = items[0].trim() + def ami = items[1].trim() + def user = items[2].trim() + def docker_installed = items[3].trim() + def params = [ + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'BRANCH', value: branch), + string(name: 'AWS_AMI', value: "${ami}"), + string(name: 'AWS_USER', value: "${user}"), + string(name: 'DOCKER_INSTALLED', value: "${docker_installed}"), + string(name: 'RANCHER_K8S_VERSION', value: "${env.RANCHER_K8S_VERSION}") + ] + println "parameters: ${params}" + jobs["${name}"] = { build job: 'rancher-v3_ontag_custom_certification', parameters: params } + } + parallel jobs + } catch(err) { + echo "Error: " + err + } + } + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_k3s_upgrade b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_k3s_upgrade new file mode 100644 index 0000000..8d80144 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_k3s_upgrade @@ -0,0 +1,189 @@ +#!groovy + +def needs_cluster(py_options, upgrade_check, create_resource_prefix) { + try { + jobs = [:] + cluster_arr = env.RANCHER_CLUSTER_NAMES.split(",") + version_arr = env.RANCHER_CLUSTER_UPGRADE_VERSIONS.split(",") + cluster_count = cluster_arr.size() + RANCHER_UPGRADE_CHECK = "upgrade_cluster" + RANCHER_VALIDATE_RESOURCES_PREFIX = "mystep1" + for (int i = 0; i < cluster_count; i++) { + def params = [ + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_CLUSTER_NAME', value: "${cluster_arr[i]}", trim: true), + string(name: 'PYTEST_OPTIONS', value: "-k ${py_options}"), + string(name: 'RANCHER_UPGRADE_CHECK', value: "${upgrade_check}"), + string(name: 'RANCHER_CLUSTER_UPGRADE_VERSION', value: "${version_arr[i]}", trim: true), + string(name: 'RANCHER_VALIDATE_RESOURCES_PREFIX', value: "${RANCHER_VALIDATE_RESOURCES_PREFIX}"), + string(name: 'RANCHER_CREATE_RESOURCES_PREFIX', value: "${create_resource_prefix}"), + ] + echo "Params are: ${params}" + jobs["test-${i}"] = { build job: 'rancher-v3_needs_cluster', parameters: params } + } + parallel jobs + } catch(err) { + echo "Error: " + err + currentBuild.result = 'UNSTABLE' + } +} + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def clusterSetupContainer = "${job_name}${env.BUILD_NUMBER}_cluster_setup" + + def deployPytestOptions = "-k test_deploy_rancher_server" + def deployClusterPytestOptions = "-k test_deploy_k3s" + + def setupResultsOut = "setup-results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD')]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher Server') { + try { + if (!env.CATTLE_TEST_URL.trim() && !env.ADMIN_TOKEN.trim() && !env.USER_TOKEN.trim()) { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_AUTO_DEPLOY_CUSTOM_CLUSTER=False " + + "&& pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + RANCHER_DEPLOYED = true + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } + else { + echo "User Provided Rancher Server" + RANCHER_DEPLOYED = false + } + + } catch(err) { + echo "Error: " + err + RANCHER_DEPLOYED = false + } + } + + stage('Deploy k3s Clusters') { + try { + echo "Deploying k3s clusters. Versions: ${RANCHER_K3S_VERSIONS}. Names: ${RANCHER_CLUSTER_NAMES}" + jobs = [:] + k3s_versions = RANCHER_K3S_VERSIONS.split(",") + cluster_arr = RANCHER_CLUSTER_NAMES.split(",") + cluster_count = cluster_arr.size() + for (int i = 0; i < cluster_count; i++) { + def params = [ + string(name: 'RANCHER_HOSTNAME_PREFIX', value: "${cluster_arr[i]}", trim: true), + string(name: 'RANCHER_CLUSTER_NAME', value: "${cluster_arr[i]}", trim: true), + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_K3S_NO_OF_SERVER_NODES', value: "${RANCHER_K3S_NO_OF_SERVER_NODES}"), + string(name: 'RANCHER_K3S_NO_OF_WORKER_NODES', value: "${RANCHER_K3S_NO_OF_WORKER_NODES}"), + string(name: 'RANCHER_K3S_VERSION', value: "${k3s_versions[i]}", trim: true), + string(name: 'RANCHER_NODE_OS', value: "${RANCHER_NODE_OS}"), + string(name: 'AWS_AMI', value: "${K3S_AWS_AMI}"), + string(name: 'RANCHER_K3S_SERVER_FLAGS', value: "${RANCHER_K3S_SERVER_FLAGS}"), + string(name: 'RANCHER_K3S_WORKER_FLAGS', value: "${RANCHER_K3S_WORKER_FLAGS}"), + string(name: 'RANCHER_DB_USERNAME', value: "${RANCHER_DB_USERNAME}"), + string(name: 'AWS_USER', value: "${AWS_USER}"), + string(name: 'RANCHER_EXTERNAL_DB', value: "${RANCHER_EXTERNAL_DB}"), + string(name: 'RANCHER_EXTERNAL_DB_VERSION', value: "${RANCHER_EXTERNAL_DB_VERSION}"), + string(name: 'RANCHER_INSTANCE_CLASS', value: "${RANCHER_INSTANCE_CLASS}"), + string(name: 'RANCHER_DB_GROUP_NAME', value: "${RANCHER_DB_GROUP_NAME}"), + string(name: 'AWS_VOLUME_SIZE', value: "${AWS_VOLUME_SIZE}"), + ] + echo "Params are: ${params}" + jobs["test-${i}"] = { build job: 'import_k3s_ha_cluster', parameters: params } + } + parallel jobs + CLUSTERS_CREATED = true + } catch(err) { + echo "Error: " + err + currentBuild.result = 'UNSTABLE' + } + } + + stage('Run Preupgrade Tests in Parallel') { + needs_cluster("test_upgrade", "preupgrade", "mystep1") + } + + stage('Upgrade Clusters') { + echo "Upgrading clusters from versions: ${RANCHER_K3S_VERSIONS} to ${RANCHER_CLUSTER_UPGRADE_VERSIONS}" + needs_cluster("test_cluster_upgrade", "upgrade_cluster", "mystep1") + } + + stage('Run Postupgrade Tests in Parallel') { + needs_cluster("test_upgrade", "postupgrade", "mystep2") + } + + } catch(err) { + echo "Error: " + err + } finally { + + stage('Test Report') { + // copy and archive test results + if (RANCHER_DEPLOYED) { + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + } + } + + sh "docker rmi ${imageName}" + } // finally + } // dir + } // creds + } // folder properties + } // wrap +} // node diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_ontag_matrix b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_ontag_matrix new file mode 100644 index 0000000..cc7cb16 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_ontag_matrix @@ -0,0 +1,327 @@ +#!groovy + +// RANCHER_VERSION resolution is first via Jenkins Build Parameter RANCHER_VERSION fed in from console, +// then from $DOCKER_TRIGGER_TAG which is sourced from the Docker Hub Jenkins plugin webhook. + +def rancher_version() { + try { if ('' != RANCHER_VERSION) { return RANCHER_VERSION } } + catch (MissingPropertyException e) {} + + try { return DOCKER_TRIGGER_TAG } + catch (MissingPropertyException e) {} + + echo 'Neither RANCHER_VERSION nor DOCKER_TRIGGER_TAG have been specified!' + error() +} + +def lastBuildResult() { + def previous_build = currentBuild.getPreviousBuild() + if ( null != previous_build ) { return previous_build.result } else { return 'UNKNOWN' } +} + +def via_webhook() { + try { + def foo = DOCKER_TRIGGER_TAG + return true + } catch(MissingPropertyException) { + return false + } +} + +// Filter out Docker Hub tags like 'latest', 'master', 'enterprise'. +// Just want things like v1.2* +def branch = "v2.1" +def rancher_version = rancher_version() +def String rancher_version_regex = "^v[\\d]\\.[\\d]\\.[\\d][\\-rc\\d]+\$" + +if ( true == via_webhook() && (!(rancher_version ==~ rancher_version_regex)) ) { + println("Received RANCHER_VERSION \'${rancher_version}\' via webhook which does not match regex \'${rancher_version_regex}\'.") + println("** This will **not** result in a pipeline run.") + currentBuild.result = lastBuildResult() +} else { + if (rancher_version.startsWith("v2.2") || rancher_version.startsWith("v2.3") || rancher_version == "master-head") { + branch = "release/v2.8" + } + if (env.BRANCH) { + branch = "${BRANCH}" + } + try { + node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def setupContainer2 = "${job_name}${env.BUILD_NUMBER}_setup2" + def deleteContainer = "${job_name}${env.BUILD_NUMBER}_delete" + def deleteContainer2 = "${job_name}${env.BUILD_NUMBER}_delete2" + + def deployPytestOptions = "-k test_deploy_rancher_server" + + def deletePytestOptions = "-k test_delete_rancher_server" + + def setupResultsOut = "setup-results.xml" + def setupResultsOut2 = "setup-results-2.xml" + def deleteResultsOut = "delete-results.xml" + def deleteResultsOut2 = "delete-results-2.xml" + + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + def CATTLE_TEST_URL_2 = "" + def ADMIN_TOKEN_2 = "" + def USER_TOKEN_2 = "" + + def TIMEOUT = "6h" + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD')]) { + + println "Branch: ${branch}" + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation/") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh/") { + def decoded = new String(env.AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: env.AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + try { + stage('Deploy Rancher server 1') { + try { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_SERVER_VERSION=${rancher_version} && " + + "pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + + CATTLE_TEST_URL_2 = "${CATTLE_TEST_URL}" + ADMIN_TOKEN_2 = "${ADMIN_TOKEN}" + USER_TOKEN_2 = "${USER_TOKEN}" + } catch(err) { + echo "Error: " + err + echo 'Test run had failures. Collecting results...' + currentBuild.result = 'FAILURE' + } + } + + stage('Deploy Rancher server 2') { + try { + // deploy rancher server + sh "docker run --name ${setupContainer2} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_SERVER_VERSION=${rancher_version} && " + + "pytest -v -s --junit-xml=${setupResultsOut2} " + + "${deployPytestOptions} ${testsDir}\'" + + // copy file containing CATTLE_TEST_URL & ADMIN_TOKEN and load into environment variables + sh "docker cp ${setupContainer2}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } catch(err) { + echo "Error: " + err + echo 'Test run had failures. Collecting results...' + currentBuild.result = 'FAILURE' + } + } + + // AWS_USER and AWS_AMI are currently not set in the environmental variables. + def GO_CATTLE_TEST_URL = env.CATTLE_TEST_URL.replace('https://', '') + env.CONFIG = env.CONFIG.replace('${CATTLE_TEST_URL}', "${GO_CATTLE_TEST_URL}") + env.CONFIG = env.CONFIG.replace('${ADMIN_TOKEN}', env.ADMIN_TOKEN) + env.CONFIG = env.CONFIG.replace('${AZURE_CLIENT_ID}', env.AZURE_CLIENT_ID) + env.CONFIG = env.CONFIG.replace('${AZURE_CLIENT_SECRET}', env.AZURE_CLIENT_SECRET) + env.CONFIG = env.CONFIG.replace('${AZURE_SUBSCRIPTION_ID}', env.AZURE_SUBSCRIPTION_ID) + env.CONFIG = env.CONFIG.replace('${AWS_SECRET_ACCESS_KEY}', env.AWS_SECRET_ACCESS_KEY) + env.CONFIG = env.CONFIG.replace('${AWS_ACCESS_KEY_ID}', env.AWS_ACCESS_KEY_ID) + env.CONFIG = env.CONFIG.replace('${AWS_IAM_PROFILE}', env.AWS_IAM_PROFILE) + env.CONFIG = env.CONFIG.replace('${AWS_REGION}', env.AWS_REGION) + env.CONFIG = env.CONFIG.replace('${AWS_INSTANCE_TYPE}', env.AWS_INSTANCE_TYPE) + env.CONFIG = env.CONFIG.replace('${AWS_VPC}', env.AWS_VPC) + env.CONFIG = env.CONFIG.replace('${AWS_SECURITY_GROUPS}', env.AWS_SECURITY_GROUPS) + env.CONFIG = env.CONFIG.replace('${AWS_SSH_PEM_KEY}', env.AWS_SSH_KEY_NAME) + + stage('Execute subjobs') { + try { + jobs = [:] + println "Branch: ${branch}" + if (rancher_version.startsWith("v2.5")){ + if (!env.RKE_VERSION) { + RKE_VERSION = "v1.2.22" + } + if (!env.RANCHER_K3S_VERSION) { + RANCHER_K3S_VERSION = "v1.20.15+k3s1" + } + } + else if (rancher_version.startsWith("v2.6")){ + if (!env.RKE_VERSION) { + RKE_VERSION = "v1.3.19" + } + if (!env.RANCHER_K3S_VERSION) { + RANCHER_K3S_VERSION = "v1.24.11+k3s1" + } + } + else if (rancher_version.startsWith("v2.7")){ + if (!env.RKE_VERSION) { + RKE_VERSION = "v1.4.4" + } + if (!env.RANCHER_K3S_VERSION) { + RANCHER_K3S_VERSION = "v1.26.4+k3s1" + } + } + else if (rancher_version.startsWith("v2.8")){ + if (!env.RKE_VERSION) { + RKE_VERSION = "v1.5.0-rc4" + } + if (!env.RANCHER_K3S_VERSION) { + RANCHER_K3S_VERSION = "v1.28.6+k3s2" + } + } + else if (rancher_version.startsWith("v2.9")){ + if (!env.RKE_VERSION) { + RKE_VERSION = "v1.6.0-rc4" + } + if (!env.RANCHER_K3S_VERSION) { + RANCHER_K3S_VERSION = "v1.30.1+k3s1" + } + } + + params = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_SERVER_VERSION', value: "${rancher_version}"), + string(name: 'BRANCH', value: branch) ] + + params2 = [ string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL_2}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN_2}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN_2}"), + string(name: 'RANCHER_SERVER_VERSION', value: "${rancher_version}"), + string(name: 'RKE_VERSION', value: "${RKE_VERSION}"), + string(name: 'RANCHER_K3S_VERSION', value: "${RANCHER_K3S_VERSION}"), + string(name: 'BRANCH', value: branch) ] + + goParams = [ string(name: 'TIMEOUT', value: "${TIMEOUT}"), + text(name: 'CONFIG', value: "${env.CONFIG}"), + string(name: 'REPO', value: "https://github.com/rancher/rancher.git"), + string(name: 'BRANCH', value: branch), + string(name: 'TEST_PACKAGE', value: "provisioning/..."), + string(name: 'GOTEST_TESTCASE', value: "${env.GOTEST_TESTCASE}") ] + + // Rancher server 1 is used to test RKE1, RKE2 and K3s clusters. + // DO Note: https://github.com/rancher/qa-tasks/issues/318 + // jobs["do"] = { build job: 'rancher-v3_ontag_do_certification', parameters: params } + jobs["ec2"] = { build job: 'rancher-v3_ontag_ec2_certification', parameters: params } + jobs["az"] = { build job: 'rancher-v3_ontag_az_certification', parameters: params } + jobs["custom"] = { build job: 'rancher-v3_ontag_custom_certification', parameters: params} + jobs["go-provisioning"] = { build job: 'rancher_ontag_go_certification', parameters: goParams } + // windows note: https://github.com/rancher/dashboard/issues/6549 + // jobs["windows"] = { build job: 'rancher-v3_ontag_windows_certification', parameters: params} + // Rancher server 2 is used to test GKE, EKS, AKS and Imported clusters. + jobs["eks"] = { build job: 'rancher-v3_ontag_eks_certification', parameters: params2 } + jobs["aks"] = { build job: 'rancher-v3_ontag_aks_certification', parameters: params2 } + // gke note: https://github.com/rancher/qa-tasks/issues/429 + // jobs["gke"] = { build job: 'rancher-v3_ontag_gke_certification', parameters: params2 } + + jobs["import"] = { build job: 'rancher-v3_ontag_import_certification', parameters: params2} + jobs["importk3s"] = { build job: 'rancher-v3_ontag_import_k3s_certification', parameters: params2} + + parallel jobs + } catch(err) { + echo "Error: " + err + } + } + + stage('Delete Rancher Server') { + if (env.RANCHER_DELETE_SERVER.toLowerCase() == "true") { + try { + sh "docker run --name ${deleteContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${env.CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${env.ADMIN_TOKEN} && export USER_TOKEN=${env.USER_TOKEN} &&"+ + "pytest -v -s --junit-xml=${deleteResultsOut} " + + "${deletePytestOptions} ${testsDir}\'" + } catch(err) { + echo "Error: " + err + } + + try { + sh "docker run --name ${deleteContainer2} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export CATTLE_TEST_URL=${CATTLE_TEST_URL_2} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN_2} && export USER_TOKEN=${USER_TOKEN_2} &&" + + "pytest -v -s --junit-xml=${deleteResultsOut2} " + + "${deletePytestOptions} ${testsDir}\'" + } catch(err) { + echo "Error: " + err + } + } + } + + stage('Test Report') { + // copy and archive test results + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + sh "docker cp ${setupContainer2}:${rootPath}${setupResultsOut2} ." + sh "docker cp ${deleteContainer}:${rootPath}${deleteResultsOut} ." + sh "docker cp ${deleteContainer2}:${rootPath}${deleteResultsOut2} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut2}"]) + step([$class: 'JUnitResultArchiver', testResults: "**/${deleteResultsOut}"]) + step([$class: 'JUnitResultArchiver', testResults: "**/${deleteResultsOut2}"]) + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + sh "docker stop ${setupContainer2}" + sh "docker rm -v ${setupContainer2}" + sh "docker stop ${deleteContainer}" + sh "docker rm -v ${deleteContainer}" + sh "docker stop ${deleteContainer2}" + sh "docker rm -v ${deleteContainer2}" + sh "docker rmi ${imageName}" + } + } catch(err){ + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + sh "docker stop ${setupContainer2}" + sh "docker rm -v ${setupContainer2}" + sh "docker stop ${deleteContainer}" + sh "docker rm -v ${deleteContainer}" + sh "docker stop ${deleteContainer2}" + sh "docker rm -v ${deleteContainer2}" + sh "docker rmi ${imageName}" + } + } + } + } + } + } + } catch(err) { + echo "Error: " + err + } +} diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_provision_and_test b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_provision_and_test new file mode 100644 index 0000000..ff5aff7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_provision_and_test @@ -0,0 +1,130 @@ +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def provisionContainer = "${job_name}${env.BUILD_NUMBER}_prov" + def testContainer = "${job_name}${env.BUILD_NUMBER}_test" + + def provisionResultsOut = "provision-results.xml" + def testResultsOut = "api-results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + def rancherConfig = "rancher_env.config" + + def TESTS_TO_RUN = [ "test_wl", "test_dns_record", "test_rbac","test_connectivity", "test_ingress", + "test_secrets", "test_registry", "test_service_discovery", "test_websocket"] + + def WINDOWS_PYTEST_OPTIONS = "-k \"test_ingress or test_rbac or test_sa or test_secrets or test_service_discovery or test_workload\"" + + if (env.RANCHER_SKIP_INGRESS == "True") { + TESTS_TO_RUN = TESTS_TO_RUN - ["test_ingress"] + } + + def LINUX_PYTEST_OPTIONS = "-k \"" + TESTS_TO_RUN.join(" or ") +"\"" + def PYTEST_OPTIONS = LINUX_PYTEST_OPTIONS + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + println "Branch env: ${env.branch}" + println "Branch: ${branch}" + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL')]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(env.AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: env.AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + try { + stage('Run provisioning and validation Tests') { + try { + sh "docker run --name ${provisionContainer} --env-file .env " + + "${imageName} /bin/bash -c \'pytest -v -s --junit-xml=${provisionResultsOut} ${PYTEST_PROVISION_OPTIONS} ${testsDir}\'" + + // copy file containing CATTLE_TEST_URL & ADMIN_TOKEN and load into environment variables + sh "docker cp ${provisionContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + + if (env.RANCHER_TEST_OS == 'windows') { + PYTEST_OPTIONS = WINDOWS_PYTEST_OPTIONS + } + + sh "docker run --name ${testContainer} --env-file .env " + + "${imageName} /bin/bash -c \'export RANCHER_CLUSTER_NAME=${env.CLUSTER_NAME} && pytest -v -s --junit-xml=${testResultsOut} ${PYTEST_OPTIONS} ${testsDir}\'" + } catch(err) { + echo 'Test run had failures. Collecting results...' + echo "Error: " + err + } + + } + + stage('Test report') { + sh "docker cp ${provisionContainer}:${rootPath}${provisionResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${provisionResultsOut}"]) + + sh "docker cp ${testContainer}:${rootPath}${testResultsOut} ." + step([$class: 'JUnitResultArchiver', testResults: "**/${testResultsOut}"]) + + sh "docker rm -v ${provisionContainer}" + sh "docker rm -v ${testContainer}" + sh "docker rmi ${imageName}" + } + } catch(err){ + sh "docker stop ${provisionContainer}" + sh "docker rm -v ${provisionContainer}" + + sh "docker stop ${testContainer}" + sh "docker rm -v ${testContainer}" + + sh "docker rmi ${imageName}" + + echo "Error: " + err + } + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_rke2_upgrade b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_rke2_upgrade new file mode 100644 index 0000000..d3c21d8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_rke2_upgrade @@ -0,0 +1,197 @@ +#!groovy + +def needs_cluster(py_options, upgrade_check, create_resource_prefix) { + try { + jobs = [:] + cluster_arr = env.RANCHER_CLUSTER_NAMES.split(",") + version_arr = env.RANCHER_CLUSTER_UPGRADE_VERSIONS.split(",") + cluster_count = cluster_arr.size() + RANCHER_UPGRADE_CHECK = "upgrade_cluster" + RANCHER_VALIDATE_RESOURCES_PREFIX = "mystep1" + for (int i = 0; i < cluster_count; i++) { + def params = [ + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_CLUSTER_NAME', value: "${cluster_arr[i]}", trim: true), + string(name: 'PYTEST_OPTIONS', value: "-k ${py_options}"), + string(name: 'RANCHER_UPGRADE_CHECK', value: "${upgrade_check}"), + string(name: 'RANCHER_CLUSTER_UPGRADE_VERSION', value: "${version_arr[i]}", trim: true), + string(name: 'RANCHER_VALIDATE_RESOURCES_PREFIX', value: "${RANCHER_VALIDATE_RESOURCES_PREFIX}"), + string(name: 'RANCHER_CREATE_RESOURCES_PREFIX', value: "${create_resource_prefix}"), + string(name: 'RANCHER_TEST_IMAGE', value: "${RANCHER_TEST_IMAGE}"), + string(name: 'RANCHER_TEST_IMAGE_PORT', value: "${RANCHER_TEST_IMAGE_PORT}"), + string(name: 'RANCHER_HARDENED_CLUSTER', value: "${RANCHER_HARDENED_CLUSTER}"), + string(name: 'RANCHER_TEST_IMAGE_REDIS', value: "${RANCHER_TEST_IMAGE_REDIS}"), + ] + echo "Params are: ${params}" + jobs["test-${i}"] = { build job: 'rancher-v3_needs_cluster', parameters: params } + } + parallel jobs + } catch(err) { + echo "Error: " + err + currentBuild.result = 'UNSTABLE' + } +} + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def setupContainer = "${job_name}${env.BUILD_NUMBER}_setup" + def clusterSetupContainer = "${job_name}${env.BUILD_NUMBER}_cluster_setup" + + def deployPytestOptions = "-k test_deploy_rancher_server" + + def setupResultsOut = "setup-results.xml" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def envFile = ".env" + def rancherConfig = "rancher_env.config" + + def branch = "release/v2.8" + if ("${env.branch}" != "null" && "${env.branch}" != "") { + branch = "${env.branch}" + } + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + paramsMap = [] + params.each { + paramsMap << "$it.key=$it.value" + } + withEnv(paramsMap) { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD')]) { + stage('Checkout') { + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + } + + dir ("tests/validation") { + try { + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher Server') { + try { + if (!env.CATTLE_TEST_URL.trim() && !env.ADMIN_TOKEN.trim() && !env.USER_TOKEN.trim()) { + // deploy rancher server + sh "docker run --name ${setupContainer} -t --env-file ${envFile} " + + "${imageName} /bin/bash -c \'export RANCHER_AUTO_DEPLOY_CUSTOM_CLUSTER=False " + + "&& pytest -v -s --junit-xml=${setupResultsOut} " + + "${deployPytestOptions} ${testsDir}\'" + RANCHER_DEPLOYED = true + + // copy file containing CATTLE_TEST_URL, ADMIN_TOKEN, USER_TOKEN and load into environment variables + sh "docker cp ${setupContainer}:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } + else { + echo "User Provided Rancher Server" + RANCHER_DEPLOYED = false + } + + } catch(err) { + echo "Error: " + err + RANCHER_DEPLOYED = false + } + } + + stage('Deploy rke2 Clusters') { + try { + echo "Deploying rke2 clusters. Versions: ${RANCHER_RKE2_VERSIONS}. Names: ${RANCHER_CLUSTER_NAMES}" + jobs = [:] + rke2_versions = RANCHER_RKE2_VERSIONS.split(",") + cluster_arr = RANCHER_CLUSTER_NAMES.split(",") + cluster_count = cluster_arr.size() + for (int i = 0; i < cluster_count; i++) { + def params = [ + string(name: 'RANCHER_HOSTNAME_PREFIX', value: "${cluster_arr[i]}", trim: true), + string(name: 'RANCHER_CLUSTER_NAME', value: "${cluster_arr[i]}", trim: true), + string(name: 'RANCHER_RKE2_VERSION', value: "${rke2_versions[i]}", trim: true), + string(name: 'CATTLE_TEST_URL', value: "${CATTLE_TEST_URL}"), + string(name: 'ADMIN_TOKEN', value: "${ADMIN_TOKEN}"), + string(name: 'USER_TOKEN', value: "${USER_TOKEN}"), + string(name: 'RANCHER_RKE2_NO_OF_SERVER_NODES', value: "${RANCHER_RKE2_NO_OF_SERVER_NODES}"), + string(name: 'RANCHER_RKE2_NO_OF_WORKER_NODES', value: "${RANCHER_RKE2_NO_OF_WORKER_NODES}"), + string(name: 'AWS_AMI', value: "${RKE2_AWS_AMI}"), + string(name: 'AWS_USER', value: "${RKE2_AWS_USER}"), + string(name: 'RANCHER_RKE2_OPERATING_SYSTEM', value: "${RANCHER_RKE2_OPERATING_SYSTEM}"), + string(name: 'RANCHER_RKE2_SERVER_FLAGS', value: "${RANCHER_RKE2_SERVER_FLAGS}"), + string(name: 'RANCHER_RKE2_WORKER_FLAGS', value: "${RANCHER_RKE2_WORKER_FLAGS}"), + string(name: 'RANCHER_RKE2_INSTALLATION_MODE', value: "${RANCHER_RKE2_INSTALLATION_MODE}"), + string(name: 'RANCHER_RKE2_CHANNEL', value: "${RANCHER_RKE2_CHANNEL}"), + string(name: 'RANCHER_TEST_IMAGE', value: "${RANCHER_TEST_IMAGE}"), + string(name: 'RANCHER_TEST_IMAGE_PORT', value: "${RANCHER_TEST_IMAGE_PORT}"), + string(name: 'AWS_VOLUME_SIZE', value: "${AWS_VOLUME_SIZE}"), + ] + echo "Params are: ${params}" + jobs["test-${i}"] = { build job: 'import_rke2_cluster', parameters: params } + } + parallel jobs + CLUSTERS_CREATED = true + } catch(err) { + echo "Error: " + err + currentBuild.result = 'UNSTABLE' + } + } + + stage('Run Preupgrade Tests in Parallel') { + needs_cluster("test_upgrade", "preupgrade", "mystep1") + } + + stage('Upgrade Clusters') { + echo "Upgrading clusters from versions: ${RANCHER_RKE2_VERSIONS} to ${RANCHER_CLUSTER_UPGRADE_VERSIONS}" + needs_cluster("test_cluster_upgrade", "upgrade_cluster", "mystep1") + } + + stage('Run Postupgrade Tests in Parallel') { + needs_cluster("test_upgrade", "postupgrade", "mystep2") + } + + } catch(err) { + echo "Error: " + err + } finally { + + stage('Test Report') { + // copy and archive test results + if (RANCHER_DEPLOYED) { + sh "docker cp ${setupContainer}:${rootPath}${setupResultsOut} ." + sh "docker stop ${setupContainer}" + sh "docker rm -v ${setupContainer}" + step([$class: 'JUnitResultArchiver', testResults: "**/${setupResultsOut}"]) + } + } + + sh "docker rmi ${imageName}" + } // finally + } // dir + } // creds + } // env + } // folder properties + } // wrap +} // node diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade new file mode 100644 index 0000000..2e7580e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade @@ -0,0 +1,314 @@ +#!groovy + +node { + def rootPath = "/src/rancher-validation/" + def job_name = "${JOB_NAME}" + if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] + } + + def containerPrefix = "${job_name}${BUILD_NUMBER}" + + def rancherConfig = "rancher_env.config" + def imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" + def testsDir = "tests/v3_api/" + + def pre_branch = PREUPGRADE_BRANCH + def post_branch = POSTUPGRADE_BRANCH + + def buildFail = false + + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL')]) { + stage('Prechecks & checkout preupgrade branch') { + if (RANCHER_SERVER_VERSION == "") { + currentBuild.result = 'ABORTED' + error("RANCHER_SERVER_VERSION must be provided!") + } + + if (RANCHER_SERVER_VERSION_UPGRADE == "") { + currentBuild.result = 'ABORTED' + error("RANCHER_SERVER_VERSION_UPGRADE must be provided!") + } + + if (PREUPGRADE_BRANCH == "") { + currentBuild.result = 'ABORTED' + error("PREUPGRADE_BRANCH must be provided!") + } + + if (POSTUPGRADE_BRANCH == "") { + currentBuild.result = 'ABORTED' + error("POSTUPGRADE_BRANCH must be provided!") + } + + deleteDir() + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${pre_branch}"]], + extensions: scm.extensions + [[$class: 'CleanCheckout']], + userRemoteConfigs: scm.userRemoteConfigs + ]) + + if (RANCHER_EXTRA_VARS != "" && RANCHER_EXTRA_VARS != null) { + echo "${RANCHER_EXTRA_VARS}" + writeFile(file: "preenv.config", text: "${RANCHER_EXTRA_VARS}") + load "preenv.config" + } + } + + stage('Configure and Build') { + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + sh "./tests/validation/tests/v3_api/scripts/configure.sh" + sh "./tests/validation/tests/v3_api/scripts/build.sh" + } + + stage('Deploy Rancher server') { + try { + sh "docker run --name ${containerPrefix}_deploy -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "pytest -v -s --junit-xml=deploy.xml " + + "-k test_deploy_rancher_server ${testsDir}\'" + + sh "docker cp ${containerPrefix}_deploy:${rootPath}${testsDir}${rancherConfig} ." + load rancherConfig + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Deploy Rancher server failed" + currentBuild.result = 'FAILURE' + } + } + + stage('Provision cluster') { + try { + sh "docker run --name ${containerPrefix}_provision --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "pytest -v -s --junit-xml=provision.xml -k test_rke_${RANCHER_CLUSTER_TYPE}_host_${RANCHER_CLUSTER_PROFILE} ${testsDir}\'" + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Provision cluster failed." + currentBuild.result = 'FAILURE' + } + } + + stage('Run preupgrade') { + try { + sh "docker run --name ${containerPrefix}_preupgrade --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_VALIDATE_RESOURCES_PREFIX=autopre && " + + "export RANCHER_CREATE_RESOURCES_PREFIX=autopre && " + + "export RANCHER_UPGRADE_CHECK=preupgrade && " + + "export RANCHER_INGRESS_CHECK=True && " + + "export RANCHER_ENABLE_HOST_NODE_PORT_TESTS=True && " + + "export RANCHER_SKIP_INGRESS=False && " + + "export RANCHER_CHECK_FOR_LB=False && " + + "pytest -v -s --junit-xml=preupgrade.xml -k test_upgrade ${testsDir}\'" + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Preupgrade tests failed" + currentBuild.result = 'UNSTABLE' + } + } + + stage('Checkout postupgrade branch & rebuild') { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${post_branch}"]], + extensions: scm.extensions, + userRemoteConfigs: scm.userRemoteConfigs + ]) + + if (env.AWS_SSH_PEM_KEY && env.AWS_SSH_KEY_NAME) { + dir("./tests/validation/.ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + } + + sh "./tests/validation/tests/v3_api/scripts/configure.sh" + sh "./tests/validation/tests/v3_api/scripts/build.sh" + } + + stage('Run upgrade') { + try { + sh "docker run --name ${containerPrefix}_upgrade --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_UPGRADE_CHECK=upgrade_rancher && " + + "pytest -v -s --junit-xml=upgrade.xml -k test_rancher_upgrade ${testsDir}\'" + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Upgrade Rancher failed." + currentBuild.result = 'FAILURE' + } + } + + stage('Run postupgrade tests') { + try { + sleep(time: 5, unit: "MINUTES") + sh "docker run --name ${containerPrefix}_postupgrade --env-file .env " + \ + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_VALIDATE_RESOURCES_PREFIX=autopre && " + + "export RANCHER_CREATE_RESOURCES_PREFIX=autopost && " + + "export RANCHER_UPGRADE_CHECK=postupgrade && " + + "export RANCHER_INGRESS_CHECK=True && " + + "export RANCHER_ENABLE_HOST_NODE_PORT_TESTS=True && " + + "export RANCHER_SKIP_INGRESS=False && " + + "export RANCHER_CHECK_FOR_LB=False && " + + "pytest -v -s --junit-xml=postupgrade.xml -k test_upgrade ${testsDir}\'" + } catch(err) { + buildFail = true + currentBuild.result = 'UNSTABLE' + echo "Error: " + err + echo "Postupgrade tests failed" + } + } + + stage('Upgrade k8s') { + try { + if (RANCHER_K8S_VERSION_UPGRADE != null && RANCHER_K8S_VERSION_UPGRADE != "") { + sh "docker run --name ${containerPrefix}_k8supgrade --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "pytest -v -s --junit-xml=k8supgrade.xml -k test_edit_cluster_k8s_version ${testsDir}\'" + } + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Upgrade cluster k8s failed." + currentBuild.result = 'FAILURE' + } + } + + stage('Run postupgrade scripts') { + try { + if (RANCHER_K8S_VERSION_UPGRADE != null && RANCHER_K8S_VERSION_UPGRADE != "") { + sh "docker run --name ${containerPrefix}_k8spostupgrade --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_VALIDATE_RESOURCES_PREFIX=autopost && " + + "export RANCHER_CREATE_RESOURCES_PREFIX=autopost2 && " + + "export RANCHER_UPGRADE_CHECK=postupgrade && " + + "export RANCHER_INGRESS_CHECK=True && " + + "export RANCHER_ENABLE_HOST_NODE_PORT_TESTS=True && " + + "export RANCHER_SKIP_INGRESS=False && " + + "export RANCHER_CHECK_FOR_LB=False && " + + "pytest -v -s --junit-xml=k8spostupgrade.xml -k test_upgrade ${testsDir}\'" + } + } catch(err) { + buildFail = true + echo "Error: " + err + echo "k8s postupgrade scripts failed" + currentBuild.result = 'UNSTABLE' + } + } + + stage('Delete Rancher Server') { + try { + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && buildFail == false) { + sh "docker run --name ${containerPrefix}_delete -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "pytest -v -s --junit-xml=delete.xml " + + "-k test_delete_rancher_server ${testsDir}\'" + } else { + echo "Build failed or RANCHER_DELETE_SERVER is set to false" + echo "SERVER IS NOT DELETED" + } + } catch(err) { + echo "Error: " + err + error() + currentBuild.result = 'FAILURE' + } + } + + stage('Test Reports') { + try { + sh "docker cp ${containerPrefix}_deploy:${rootPath}deploy.xml ." + sh "docker cp ${containerPrefix}_provision:${rootPath}provision.xml ." + sh "docker cp ${containerPrefix}_preupgrade:${rootPath}preupgrade.xml ." + sh "docker cp ${containerPrefix}_upgrade:${rootPath}upgrade.xml ." + sh "docker cp ${containerPrefix}_postupgrade:${rootPath}postupgrade.xml ." + + if (RANCHER_K8S_VERSION_UPGRADE != null && RANCHER_K8S_VERSION_UPGRADE != "") { + sh "docker cp ${containerPrefix}_k8supgrade:${rootPath}k8supgrade.xml ." + sh "docker cp ${containerPrefix}_k8spostupgrade:${rootPath}k8spostupgrade.xml ." + } + + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && buildFail == false) { + sh "docker cp ${containerPrefix}_delete:${rootPath}delete.xml ." + } + + step([$class: 'JUnitResultArchiver', testResults: "**/*.xml"]) + } catch(err) { + echo "Error: " + err + } + } + + stage('Cleanup') { + sh "docker rm ${containerPrefix}_deploy" + sh "docker rm ${containerPrefix}_provision" + sh "docker rm ${containerPrefix}_preupgrade" + sh "docker rm ${containerPrefix}_upgrade" + sh "docker rm ${containerPrefix}_postupgrade" + + if (RANCHER_K8S_VERSION_UPGRADE != null && RANCHER_K8S_VERSION_UPGRADE != "") { + sh "docker rm ${containerPrefix}_k8supgrade" + sh "docker rm ${containerPrefix}_k8spostupgrade" + } + + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && buildFail == false) { + sh "docker rm ${containerPrefix}_delete" + } + + sh "docker rmi ${imageName}" + } + } + } + } +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade_multiple b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade_multiple new file mode 100644 index 0000000..69a5ae9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/scripts/pipeline/Jenkinsfile_single_upgrade_multiple @@ -0,0 +1,611 @@ +#!groovy + +rootPath = "/src/rancher-validation/" +def job_name = "${JOB_NAME}" +if (job_name.contains('/')) { + job_names = job_name.split('/') + job_name = job_names[job_names.size() - 1] +} + +containerPrefix = "${job_name}${BUILD_NUMBER}" +rancherConfig = "rancher_env.config" +imageName = "rancher-validation-${job_name}${env.BUILD_NUMBER}" +testsDir = "tests/v3_api/" +paramsConfigFile = "params_env.config" + +containerName = containerPrefix + "-validation" + +// If tests fail, set to `true` in the catch in order to prevent +// Rancher server from being deleted if RANCHER_SERVER_DELETE is true +buildFail = false + +// We add the clusters the user selected as they are created +// This is used to iterate through the clusters in some stages +clusters = [:] + +htmlString = "" + +node { + try { + wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm', 'defaultFg': 2, 'defaultBg':1]) { + withFolderProperties { + withCredentials([ string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'AWS_ACCESS_KEY_ID'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'AWS_SECRET_ACCESS_KEY'), + string(credentialsId: 'AWS_ACCESS_KEY_ID', variable: 'RANCHER_EKS_ACCESS_KEY'), + string(credentialsId: 'AWS_SECRET_ACCESS_KEY', variable: 'RANCHER_EKS_SECRET_KEY'), + string(credentialsId: 'DO_ACCESSKEY', variable: 'DO_ACCESSKEY'), + string(credentialsId: 'AWS_SSH_PEM_KEY', variable: 'AWS_SSH_PEM_KEY'), + string(credentialsId: 'RANCHER_SSH_KEY', variable: 'RANCHER_SSH_KEY'), + string(credentialsId: 'AZURE_SUBSCRIPTION_ID', variable: 'AZURE_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'AZURE_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'AZURE_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'AZURE_CLIENT_SECRET'), + string(credentialsId: 'AZURE_AKS_SUBSCRIPTION_ID', variable: 'RANCHER_AKS_SUBSCRIPTION_ID'), + string(credentialsId: 'AZURE_TENANT_ID', variable: 'RANCHER_AKS_TENANT_ID'), + string(credentialsId: 'AZURE_CLIENT_ID', variable: 'RANCHER_AKS_CLIENT_ID'), + string(credentialsId: 'AZURE_CLIENT_SECRET', variable: 'RANCHER_AKS_SECRET_KEY'), + string(credentialsId: 'RANCHER_REGISTRY_USER_NAME', variable: 'RANCHER_REGISTRY_USER_NAME'), + string(credentialsId: 'RANCHER_REGISTRY_PASSWORD', variable: 'RANCHER_REGISTRY_PASSWORD'), + string(credentialsId: 'ADMIN_PASSWORD', variable: 'ADMIN_PASSWORD'), + string(credentialsId: 'USER_PASSWORD', variable: 'USER_PASSWORD'), + string(credentialsId: 'RANCHER_GKE_CREDENTIAL', variable: 'RANCHER_GKE_CREDENTIAL')]) { + deleteDir() + + stage('Prechecks / Checkout') { + setEnvFromParams() + checkParams() + checkoutBranch(PREUPGRADE_BRANCH) + } + + dir ("tests/validation") { + stage('Build container / Deploy Rancher Server') { + buildContainer() + deployRancherServer() + } + + stage('Provision Cluster(s)') { + try { + loadClusterConfig() + + clusters.each { type, params -> + runProvision(type, params) + } + } catch(err) { + buildFail = true + echo "Error: " + err + } + if (clusters == [:]) { + error "All clusters failed to provision. Aborting." + currentBuild.result = 'ABORTED' + } + } + + stage('Enable logging') { + try { + if (RANCHER_ELASTIC_SEARCH_ENDPOINT != "") { + clusters.each { type, params -> + enableLogging(type) + } + } + } catch(err) { + buildFail = true + echo "Error: " + err + } + } + + stage('Run Preupgrade') { + try { + clusters.each { cluster, param -> + runPreupgradeTests(cluster, "auto-pre", "auto-pre") + } + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Preupgrade tests failed" + currentBuild.result = 'UNSTABLE' + } + } + } + + stage('Stash reports') { + stash name: "reportsstash", includes: "**/reports/*" + } + + stage('Checkout Post Branch') { + checkoutBranch(POSTUPGRADE_BRANCH) + } + + stage('Unstash reports') { + unstash name: "reportsstash" + } + + dir ("tests/validation") { + stage('Rebuild / Run Upgrade') { + buildContainer() + upgradeRancher() + } + + stage('Run postupgrade tests') { + try { + // Sleep for x minutes as a safeguard to ensure + // all clusters are available + sleep(time: POSTUPGRADE_SLEEP.toInteger(), unit: "MINUTES") + + // Run the postupgrade checks on all provisioned clusters + clusters.each { cluster, params -> + runPostupgradeTests(cluster, "auto-pre", "auto-post") + } + } catch(err) { + buildFail = true + currentBuild.result = 'UNSTABLE' + echo "Error: " + err + echo "Postupgrade tests failed" + } + } + + // For each cluster type, if it has been selected and has + // a k8s postupgrade version specified, upgrade the k8s version + stage('Upgrade k8s') { + try { + if (run_ec2 && k8s_post_ec2 != "") { + run_k8s_upgrade("ec2", k8s_post_ec2) + } + if (run_do && k8s_post_do != "") { + run_k8s_upgrade("do", k8s_post_do) + } + if (run_az && k8s_post_az != "") { + run_k8s_upgrade("az", k8s_post_az) + } + if (run_custom && k8s_post_custom != "") { + run_k8s_upgrade("custom", k8s_post_custom) + } + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Upgrade cluster k8s failed." + currentBuild.result = 'FAILURE' + } + } + + // For each cluster type, if it has been selected and has + // a k8s postupgrade version specified, run the postupgrade + // checks after the k8s version has been updated. + // This prevents running the postupgrade scripts unnecessarily + // + // If the final param (xmlPrefix) is supplied, the test report + // name will be prepended with this prefix. This allows to use + // the same postupgrade method post k8s without overwriting existing + // test reports + stage('Run k8s postupgrade scripts') { + try { + if (run_ec2 && k8s_post_ec2 != "") { + runPostupgradeTests("ec2", "auto-post", "auto-post-k8s", "k8s") + } + if (run_do && k8s_post_do != "") { + runPostupgradeTests("do", "auto-post", "auto-post-k8s", "k8s") + } + if (run_az && k8s_post_az != "") { + runPostupgradeTests("az", "auto-post", "auto-post-k8s", "k8s") + } + if (run_custom && k8s_post_custom != "") { + runPostupgradeTests("custom", "auto-post", "auto-post-k8s", "k8s") + } + } catch(err) { + buildFail = true + echo "Error: " + err + echo "k8s postupgrade scripts failed" + currentBuild.result = 'UNSTABLE' + } + } + + // If RANCHER_DELETE_SERVER is true and no tests have failed (buildFail = true), + // delete Rancher server and all clusters + stage('Delete Rancher Server') { + deleteRancherServer() + } + } + } + } + } + } catch (e) { + // do nothing + } finally { + stage('Publish reports') { + try { + publishReports() + } catch(err) { + echo "Error: " + err + } + } + + if (buildFail == true) { + currentBuild.result = 'UNSTABLE' + } + + containerCleanup() + sh "docker rmi ${imageName}" + } +} + +def setEnvFromParams() { + // CLUSTER_TYPES, EXTRA_VARS, K8S_UPGRADE_VERSIONS are parameters + // from the Jenkins job -- these are written to a file and loaded + // to expose the environment variables + dir('.') { + def vars = "${CLUSTER_TYPES}\n\n${EXTRA_VARS}\n\n${K8S_UPGRADE_VERSIONS}" + writeFile(file: "pre_${paramsConfigFile}", text: vars) + + def paramsConfigFileContents = readFile("pre_${paramsConfigFile}") + def paramsList = paramsConfigFileContents.split('\n') + + def newParams = [] + + paramsList.each { param -> + if (param != '' && param != null) { + newParams << "env.${param}" + } + } + finalParamsList = newParams.join('\n') + + println(finalParamsList) + writeFile(file: paramsConfigFile, text: finalParamsList) + } + + load paramsConfigFile +} + +// Enforce that the params in `requiredParams` are present +def checkParams() { + requiredParams = ["RANCHER_SERVER_VERSION":RANCHER_SERVER_VERSION, + "RANCHER_SERVER_VERSION_UPGRADE":RANCHER_SERVER_VERSION_UPGRADE, + "PREUPGRADE_BRANCH":PREUPGRADE_BRANCH, + "POSTUPGRADE_BRANCH":POSTUPGRADE_BRANCH, + "RANCHER_CLUSTER_NAME":RANCHER_CLUSTER_NAME] + + requiredParams.each { param, paramValue -> + if (paramValue == "") { + error "${param} must be provided! Aborting." + currentBuild.result = 'Aborted' + } + + // Enforce that at least one cluster must be specified + if (!run_ec2 && !run_az && !run_custom && !run_do) { + error("At least one cluster type must be provided!") + currentBuild.result = 'ABORTED' + } + } +} + +def buildContainer() { + try { + dir(".ssh") { + def decoded = new String(AWS_SSH_PEM_KEY.decodeBase64()) + writeFile file: AWS_SSH_KEY_NAME, text: decoded + } + + sh "./tests/v3_api/scripts/configure.sh" + sh "./tests/v3_api/scripts/build.sh" + } catch(error) { + echo "Error: " + err + } +} + +def checkoutBranch(def branch) { + checkout([ + $class: 'GitSCM', + branches: [[name: "*/${branch}"]], + extensions: scm.extensions, + userRemoteConfigs: scm.userRemoteConfigs + ]) +} + +def loadClusterConfig() { + def params = "" + if (run_ec2.toLowerCase() == 'true') + { + if (k8s_pre_ec2 != '') { + params = "export RANCHER_K8S_VERSION=${k8s_pre_ec2} && " + } + clusters << ["ec2":"${params}"] + } + + if (run_do.toLowerCase() == 'true') + { + if (k8s_pre_do != '') { + params = "export RANCHER_K8S_VERSION=${k8s_pre_do} && " + } + clusters << ["do":"${params}"] + } + + if (run_az.toLowerCase() == 'true') + { + if (k8s_pre_az != '') { + params = "export RANCHER_K8S_VERSION=${k8s_pre_az} && " + } + clusters << ["az":"${params}"] + } + + if (run_custom.toLowerCase() == 'true') + { + if (k8s_pre_custom != '') { + params = "export RANCHER_K8S_VERSION=${k8s_pre_custom} && " + } + clusters << ["custom":"${params}"] + } +} + +def deployRancherServer() { + try { + def reportName = "deploy" + htmlString = "--html=reports/${reportName}.html" + + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "pytest -v -s -k test_deploy_rancher_server ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + + sh "docker cp ${containerName}:${rootPath}${testsDir}${rancherConfig} ." + + load rancherConfig + } catch(err) { + echo "Error: " + err + echo "Deploy rancher failed" + buildFail = true + currentBuild.result = 'ABORTED' + } finally { + collectReports() + containerCleanup() + } +} + +// If the exportString is provided, it will pass these additional +// variables to the test container +def runProvision(def cluster, def exportString) { + try { + // Append the cluster type to RANCHER_CLUSTER_NAME to avoid + // duplicate cluster names + def cluster_name = RANCHER_CLUSTER_NAME + "-${cluster}" + def reportName = "provision-${cluster}" + htmlString = "--html=reports/${reportName}.html" + + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "${exportString}" + + "pytest -v -s -k test_rke_${cluster}_host_${CLUSTER_PROFILE} ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + } catch (err) { + echo "Error: " + err + echo "Provision cluster failed" + currentBuild.result = 'FAILURE' + buildFail = true + } finally { + collectReports() + containerCleanup() + } +} + +def enableLogging(def cluster) { + try { + def cluster_name = RANCHER_CLUSTER_NAME + "-${cluster}" + def reportName = "enable-logging-${cluster}" + htmlString = "--html=reports/${reportName}.html" + runString = "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_ELASTIC_SEARCH_ENDPOINT=${RANCHER_ELASTIC_SEARCH_ENDPOINT} && " + + "pytest -v -s -k test_cluster_enable_logging_elasticsearch ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + print("Running: ") + print(runString) + sh runString + } catch (err) { + echo "Error: " + err + echo "Enable logging failed" + currentBuild.result = 'FAILURE' + buildFail = true + } finally { + collectReports() + containerCleanup() + } +} + +def runPreupgradeTests(def cluster, def validate, def create) { + try { + // Append the cluster type to RANCHER_CLUSTER_NAME to get the correct cluster + def cluster_name = RANCHER_CLUSTER_NAME + "-${cluster}" + def reportName = "preupgrade-${cluster}" + htmlString = "--html=reports/${reportName}.html" + + // Set the upgrade-specific variables for pre-upgrade + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_VALIDATE_RESOURCES_PREFIX=${validate} && " + + "export RANCHER_CREATE_RESOURCES_PREFIX=${create} && " + + "export RANCHER_UPGRADE_CHECK=preupgrade && " + + "export RANCHER_INGRESS_CHECK=True && " + + "export RANCHER_ENABLE_HOST_NODE_PORT_TESTS=True && " + + "export RANCHER_SKIP_INGRESS=False && " + + "export RANCHER_CHECK_FOR_LB=False && " + + "pytest -v -s -k test_upgrade ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + + } catch(err) { + buildFail = true + echo "Error: " + err + echo "Preupgrade tests failed" + currentBuild.result = 'UNSTABLE' + } finally { + collectReports() + containerCleanup() + } +} + +def upgradeRancher() { + try { + // The fixture in test_upgrade.py requires a cluster name + // in order to create a client. Though the `test_rancher_upgrade` + // test doesn't need a cluster name, we supply the first provisioned + def existing_cluster_name = "" + clusters.each { type,param -> + existing_cluster_name = type + } + def cluster_name = RANCHER_CLUSTER_NAME + "-" + existing_cluster_name + def reportName = "upgrade" + htmlString = "--html=reports/${reportName}.html" + + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_UPGRADE_CHECK=upgrade_rancher && " + + "pytest -v -s -k test_rancher_upgrade ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + } catch(err) { + echo "Error: " + err + echo "Upgrade rancher failed" + buildFail = true + currentBuild.result == 'FAILURE' + } finally { + collectReports() + containerCleanup() + } +} + +// validate = the resource prefix for validation +// create = the resource prefix for creation +// xmlPrefix, if supplied, prepends the prefix to the report name +def runPostupgradeTests(def cluster, def validate, def create, def xmlPrefix="") { + try { + // Append the cluster type to RANCHER_CLUSTER_NAME to get the correct cluster + def cluster_name = RANCHER_CLUSTER_NAME + "-${cluster}" + def reportName = "${xmlPrefix}postupgrade-${cluster}" + htmlString = "--html=reports/${reportName}.html" + + // Set the upgrade-specific variables for pre-upgrade + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "export RANCHER_VALIDATE_RESOURCES_PREFIX=${validate} && " + + "export RANCHER_CREATE_RESOURCES_PREFIX=${create} && " + + "export RANCHER_UPGRADE_CHECK=postupgrade && " + + "export RANCHER_INGRESS_CHECK=True && " + + "export RANCHER_ENABLE_HOST_NODE_PORT_TESTS=True && " + + "export RANCHER_SKIP_INGRESS=False && " + + "export RANCHER_CHECK_FOR_LB=False && " + + "pytest -v -s -k test_upgrade ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + } catch (err) { + buildFail = true + echo "Error: " + err + echo "Error running postupgrade tests" + currentBuild.result = 'UNSTABLE' + } finally { + collectReports() + containerCleanup() + } +} + +// k8s_version is the version to upgrade to +def run_k8s_upgrade(def cluster, def k8s_version) { + try { + // Get the correct cluster + def cluster_name = RANCHER_CLUSTER_NAME + "-${cluster}" + def reportName = "k8supgrade-${cluster}" + htmlString = "--html=reports/${reportName}.html" + + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export RANCHER_CLUSTER_NAME=${cluster_name} && " + + "export RANCHER_K8S_VERSION_UPGRADE=${k8s_version} && " + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "pytest -v -s -k test_edit_cluster_k8s_version ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + } catch(err) { + echo "Error: " + err + echo "k8s upgrade failed" + currentBuild.result = 'UNSTABLE' + buildFail = true + } finally { + collectReports() + containerCleanup() + } +} + +def deleteRancherServer() { + try { + if (RANCHER_DELETE_SERVER.toLowerCase() == "true" && buildFail == false || DELETE_SERVER_OVERRIDE.toLowerCase() == "true") { + def reportName="delete" + htmlString = "--html=reports/${reportName}.html" + + sh "docker run --name ${containerName} -t --env-file .env " + + "${imageName} /bin/bash -c \'" + + "export CATTLE_TEST_URL=${CATTLE_TEST_URL} && " + + "export ADMIN_TOKEN=${ADMIN_TOKEN} && " + + "export USER_TOKEN=${USER_TOKEN} && " + + "pytest -v -s -k test_delete_rancher_server ${testsDir} " + + "--junit-xml=reports/${reportName}.xml " + + "${htmlString}\'" + } else { + echo "Build failed or RANCHER_DELETE_SERVER is set to false" + echo "SERVER IS NOT DELETED" + } + } catch(err) { + echo "Error: " + err + error() + currentBuild.result = 'UNSTABLE' + } finally { + collectReports() + containerCleanup() + } +} + +def collectReports() { + sh "docker cp ${containerName}:${rootPath}reports/ ." +} + +def publishReports() { + dir('.') { + def reportFilesString = sh(script: 'find ./tests/validation/reports -name "*.html"', returnStdout: true).split().join(',') + echo "reportFiles: " + reportFilesString + + publishHTML (target: [ + allowMissing: false, + alwaysLinkToLastBuild: true, + keepAll: true, + reportDir: ".", + reportFiles: reportFilesString, + reportName: "Single-click Upgrade Test Results" + ]) + // Archive all test reports (currently combines all into one report) + step([$class: 'JUnitResultArchiver', testResults: "**/*.xml"]) + } +} + +def containerCleanup() { + sh "docker stop ${containerName} || true && docker rm ${containerName} || true" +} \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ad_custom_filter.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ad_custom_filter.py new file mode 100644 index 0000000..4249eda --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ad_custom_filter.py @@ -0,0 +1,164 @@ +from .common import * # NOQA + +import requests + +AUTH_PROVIDER = os.environ.get('RANCHER_AUTH_PROVIDER', "") + +''' +Prerequisite: +Enable AD without TLS, and using testuser1 as admin user. + +Description: +In this test, we are testing the customized user and group search filter +functionalities. +1) For customized user search filter: +The filter looks like: +(&(objectClass=person)(|(sAMAccountName=test*)(sn=test*)(givenName=test*)) +[user customized filter]) +Here, after we add +userSearchFilter = (memberOf=CN=testgroup5,CN=Users,DC=tad,DC=rancher,DC=io) +we will filter out only testuser40 and testuser41, otherwise, all users start +with search keyword "testuser" will be listed out. + +2) For customized group search filter: +The filter looks like: +(&(objectClass=group)(sAMAccountName=test)[group customized filter]) +Here, after we add groupSearchFilter = (cn=testgroup2) +we will filter out only testgroup2, otherwise, all groups has search +keyword "testgroup" will be listed out. +''' + +# Config Fields +HOSTNAME_OR_IP_ADDRESS = os.environ.get("RANCHER_HOSTNAME_OR_IP_ADDRESS") +PORT = os.environ.get("RANCHER_PORT") +CONNECTION_TIMEOUT = os.environ.get("RANCHER_CONNECTION_TIMEOUT") +SERVICE_ACCOUNT_NAME = os.environ.get("RANCHER_SERVICE_ACCOUNT_NAME") +SERVICE_ACCOUNT_PASSWORD = os.environ.get("RANCHER_SERVICE_ACCOUNT_PASSWORD") +DEFAULT_LOGIN_DOMAIN = os.environ.get("RANCHER_DEFAULT_LOGIN_DOMAIN") +USER_SEARCH_BASE = os.environ.get("RANCHER_USER_SEARCH_BASE") +GROUP_SEARCH_BASE = os.environ.get("RANCHER_GROUP_SEARCH_BASE") +PASSWORD = os.environ.get('RANCHER_USER_PASSWORD', "") + +CATTLE_AUTH_URL = \ + CATTLE_TEST_URL + \ + "/v3-public/"+AUTH_PROVIDER+"Providers/" + \ + AUTH_PROVIDER.lower()+"?action=login" + +CATTLE_AUTH_PROVIDER_URL = \ + CATTLE_TEST_URL + "/v3/"+AUTH_PROVIDER+"Configs/"+AUTH_PROVIDER.lower() + +CATTLE_AUTH_PRINCIPAL_URL = CATTLE_TEST_URL + "/v3/principals?action=search" + +CATTLE_AUTH_ENABLE_URL = CATTLE_AUTH_PROVIDER_URL + "?action=testAndApply" + +CATTLE_AUTH_DISABLE_URL = CATTLE_AUTH_PROVIDER_URL + "?action=disable" + + +def test_custom_user_and_group_filter_for_AD(): + disable_ad("testuser1", ADMIN_TOKEN) + enable_ad_with_customized_filter( + "testuser1", + "(memberOf=CN=testgroup5,CN=Users,DC=tad,DC=rancher,DC=io)", + "", ADMIN_TOKEN) + search_ad_users("testuser", ADMIN_TOKEN) + + disable_ad("testuser1", ADMIN_TOKEN) + enable_ad_with_customized_filter( + "testuser1", "", "(cn=testgroup2)", ADMIN_TOKEN) + search_ad_groups("testgroup", ADMIN_TOKEN) + + +def disable_ad(username, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_DISABLE_URL, json={ + "enabled": False, + "username": username, + "password": PASSWORD + }, verify=False, headers=headers) + assert r.status_code == expected_status + print("Disable ActiveDirectory request for " + + username + " " + str(expected_status)) + + +def enable_ad_with_customized_filter(username, usersearchfilter, + groupsearchfilter, token, + expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + activeDirectoryConfig = { + "accessMode": "unrestricted", + "userSearchFilter": usersearchfilter, + "groupSearchFilter": groupsearchfilter, + "connectionTimeout": CONNECTION_TIMEOUT, + "defaultLoginDomain": DEFAULT_LOGIN_DOMAIN, + "groupDNAttribute": "distinguishedName", + "groupMemberMappingAttribute": "member", + "groupMemberUserAttribute": "distinguishedName", + "groupNameAttribute": "name", + "groupObjectClass": "group", + "groupSearchAttribute": "sAMAccountName", + "nestedGroupMembershipEnabled": False, + "port": PORT, + "servers": [ + HOSTNAME_OR_IP_ADDRESS + ], + "serviceAccountUsername": SERVICE_ACCOUNT_NAME, + "userDisabledBitMask": 2, + "userEnabledAttribute": "userAccountControl", + "userLoginAttribute": "sAMAccountName", + "userNameAttribute": "name", + "userObjectClass": "person", + "userSearchAttribute": "sAMAccountName|sn|givenName", + "userSearchBase": USER_SEARCH_BASE, + "serviceAccountPassword": SERVICE_ACCOUNT_PASSWORD + } + + r = requests.post(CATTLE_AUTH_ENABLE_URL, json={ + "activeDirectoryConfig": activeDirectoryConfig, + "enabled": True, + "username": username, + "password": PASSWORD + }, verify=False, headers=headers) + assert r.status_code == expected_status + print("Enable ActiveDirectory request for " + + username + " " + str(expected_status)) + + +def search_ad_users(searchkey, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_PRINCIPAL_URL, + json={'name': searchkey, 'principalType': 'user', + 'responseType': 'json'}, + verify=False, headers=headers) + assert r.status_code == expected_status + + if r.status_code == 200: + print(r.json()) + data = r.json()['data'] + print(data) + assert len(data) == 2 + print(data) + assert \ + data[0].get('id') == \ + "activedirectory_user://CN=test user40," \ + "CN=Users,DC=tad,DC=rancher,DC=io" + assert \ + data[1].get('id') == \ + "activedirectory_user://CN=test user41," \ + "CN=Users,DC=tad,DC=rancher,DC=io" + + +def search_ad_groups(searchkey, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_PRINCIPAL_URL, + json={'name': searchkey, 'principalType': 'group', + 'responseType': 'json'}, + verify=False, headers=headers) + assert r.status_code == expected_status + + if r.status_code == 200: + data = r.json()['data'] + assert len(data) == 1 + assert \ + data[0].get('id') == \ + "activedirectory_group://CN=testgroup2," \ + "CN=Users,DC=tad,DC=rancher,DC=io" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap.py new file mode 100644 index 0000000..7b7c0b3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap.py @@ -0,0 +1,809 @@ +import base64 +import os +import pytest +import re +import time +from lib.aws import AWS_USER +from .common import ( + ADMIN_PASSWORD, AmazonWebServices, run_command, wait_for_status_code, + TEST_IMAGE, TEST_IMAGE_REDIS, TEST_IMAGE_OS_BASE, readDataFile, + DEFAULT_CLUSTER_STATE_TIMEOUT, compare_versions +) +from .test_custom_host_reg import ( + random_test_name, RANCHER_SERVER_VERSION, HOST_NAME, AGENT_REG_CMD +) +from .test_create_ha import ( + set_url_and_password, + RANCHER_HA_CERT_OPTION, RANCHER_VALID_TLS_CERT, RANCHER_VALID_TLS_KEY +) + +PRIVATE_REGISTRY_USERNAME = os.environ.get("RANCHER_BASTION_USERNAME") +PRIVATE_REGISTRY_PASSWORD = \ + os.environ.get("RANCHER_BASTION_PASSWORD", ADMIN_PASSWORD) +BASTION_ID = os.environ.get("RANCHER_BASTION_ID", "") +NUMBER_OF_INSTANCES = int(os.environ.get("RANCHER_AIRGAP_INSTANCE_COUNT", "1")) +IMAGE_LIST = os.environ.get("RANCHER_IMAGE_LIST", ",".join( + [TEST_IMAGE, TEST_IMAGE_REDIS, TEST_IMAGE_OS_BASE])).split(",") +TARBALL_TYPE = os.environ.get("K3S_TARBALL_TYPE", "tar.gz") +ARCH = os.environ.get("K3S_ARCH", "amd64") + +AG_HOST_NAME = random_test_name(HOST_NAME) +RANCHER_AG_INTERNAL_HOSTNAME = AG_HOST_NAME + "-internal.qa.rancher.space" +RANCHER_AG_HOSTNAME = AG_HOST_NAME + ".qa.rancher.space" +RESOURCE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') +SSH_KEY_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + '.ssh') + + +def test_deploy_bastion(): + node = deploy_bastion_server() + assert node.public_ip_address is not None + + +def test_deploy_airgap_rancher(check_hostname_length): + bastion_node = deploy_bastion_server() + save_res, load_res = add_rancher_images_to_private_registry(bastion_node) + assert "Image pull success: rancher/rancher:{}".format( + RANCHER_SERVER_VERSION) in save_res[0] + assert "The push refers to repository [{}/rancher/rancher]".format( + bastion_node.host_name) in load_res[0] + ag_node = deploy_airgap_rancher(bastion_node) + public_dns = create_nlb_and_add_targets([ag_node]) + print( + "\nConnect to bastion node with:\nssh -i {}.pem {}@{}\n" + "Connect to rancher node by connecting to bastion, then run:\n" + "ssh -i {}.pem {}@{}\n\nOpen the Rancher UI with: https://{}\n" + "** IMPORTANT: SET THE RANCHER SERVER URL UPON INITIAL LOGIN TO: {} **" + "\nWhen creating a cluster, enable private registry with below" + " settings:\nPrivate Registry URL: {}\nPrivate Registry User: {}\n" + "Private Registry Password: (default admin password or " + "whatever you set in RANCHER_BASTION_PASSWORD)\n".format( + bastion_node.ssh_key_name, AWS_USER, bastion_node.host_name, + bastion_node.ssh_key_name, AWS_USER, ag_node.private_ip_address, + public_dns, RANCHER_AG_INTERNAL_HOSTNAME, + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME)) + time.sleep(180) + setup_rancher_server() + + +def test_prepare_airgap_nodes(): + bastion_node = get_bastion_node() + ag_nodes = prepare_airgap_node(bastion_node, NUMBER_OF_INSTANCES) + assert len(ag_nodes) == NUMBER_OF_INSTANCES + + print( + '{} airgapped instance(s) created.\n' + 'Connect to these and run commands by connecting to bastion node, ' + 'then running the following command (with the quotes):\n' + 'ssh -i {}.pem {}@NODE_PRIVATE_IP ' + '"docker login {} -u {} -p {} && COMMANDS"'.format( + NUMBER_OF_INSTANCES, bastion_node.ssh_key_name, AWS_USER, + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD)) + for ag_node in ag_nodes: + assert ag_node.private_ip_address is not None + assert ag_node.public_ip_address is None + + +def test_deploy_airgap_nodes(): + bastion_node = get_bastion_node() + ag_nodes = prepare_airgap_node(bastion_node, NUMBER_OF_INSTANCES) + assert len(ag_nodes) == NUMBER_OF_INSTANCES + + print( + '{} airgapped instance(s) created.\n' + 'Connect to these and run commands by connecting to bastion node, ' + 'then running the following command (with the quotes):\n' + 'ssh -i {}.pem {}@NODE_PRIVATE_IP ' + '"docker login {} -u {} -p {} && COMMANDS"'.format( + NUMBER_OF_INSTANCES, bastion_node.ssh_key_name, AWS_USER, + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD)) + for ag_node in ag_nodes: + assert ag_node.private_ip_address is not None + assert ag_node.public_ip_address is None + results = [] + for ag_node in ag_nodes: + deploy_result = run_command_on_airgap_node(bastion_node, ag_node, + AGENT_REG_CMD) + results.append(deploy_result) + for result in results: + assert "Downloaded newer image for " in result[1] + assert "/rancher/rancher-agent" in result[1] + + +def test_add_rancher_images_to_private_registry(): + bastion_node = get_bastion_node() + save_res, load_res = add_rancher_images_to_private_registry(bastion_node) + assert "Image pull success: rancher/rancher:{}".format( + RANCHER_SERVER_VERSION) in save_res[0] + assert "The push refers to repository " in load_res[0] + assert "/rancher/rancher]" in load_res[0] + + +def test_add_images_to_private_registry(): + bastion_node = get_bastion_node() + failures = add_images_to_private_registry(bastion_node, IMAGE_LIST) + assert failures == [], "Failed to add images: {}".format(failures) + + +def test_deploy_private_registry_without_image_push(): + bastion_node = deploy_bastion_server() + save_res, load_res = add_rancher_images_to_private_registry( + bastion_node, push_images=False) + assert "Image pull success: rancher/rancher:{}".format( + RANCHER_SERVER_VERSION) in save_res[0] + assert load_res is None + + +def setup_rancher_server(): + base_url = "https://" + RANCHER_AG_HOSTNAME + wait_for_status_code(url=base_url + "/v3", expected_code=401) + auth_url = base_url + "/v3-public/localproviders/local?action=login" + wait_for_status_code(url=auth_url, expected_code=200) + set_url_and_password(base_url, "https://" + RANCHER_AG_INTERNAL_HOSTNAME, version=RANCHER_SERVER_VERSION) + + +def deploy_noauth_bastion_server(): + node_name = AG_HOST_NAME + "-noauthbastion" + # Create Bastion Server in AWS + bastion_node = AmazonWebServices().create_node(node_name, for_bastion=True) + setup_ssh_key(bastion_node) + + # Generate self signed certs + generate_certs_command = \ + 'mkdir -p certs && sudo openssl req -newkey rsa:4096 -nodes -sha256 ' \ + '-keyout certs/domain.key -x509 -days 365 -out certs/domain.crt ' \ + '-subj "/C=US/ST=AZ/O=Rancher QA/CN={0}" ' \ + '-addext "subjectAltName = DNS:{0}"'.format(bastion_node.host_name) + bastion_node.execute_command(generate_certs_command) + + # Ensure docker uses the certs that were generated + update_docker_command = \ + 'sudo mkdir -p /etc/docker/certs.d/{0} && ' \ + 'sudo cp ~/certs/domain.crt /etc/docker/certs.d/{0}/ca.crt && ' \ + 'sudo service docker restart'.format(bastion_node.host_name) + bastion_node.execute_command(update_docker_command) + + # Run private registry + run_private_registry_command = \ + 'sudo docker run -d --restart=always --name registry ' \ + '-v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 ' \ + '-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt ' \ + '-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -p 443:443 registry:2' + bastion_node.execute_command(run_private_registry_command) + time.sleep(5) + + print("Bastion Server Details:\nNAME: {}\nHOST NAME: {}\n" + "INSTANCE ID: {}\n".format(node_name, bastion_node.host_name, + bastion_node.provider_node_id)) + + return bastion_node + + +def deploy_bastion_server(): + node_name = AG_HOST_NAME + "-bastion" + # Create Bastion Server in AWS + bastion_node = AmazonWebServices().create_node(node_name, for_bastion=True) + setup_ssh_key(bastion_node) + + # Get resources for private registry and generate self signed certs + get_resources_command = \ + 'scp -q -i {}/{}.pem -o StrictHostKeyChecking=no ' \ + '-o UserKnownHostsFile=/dev/null -r {}/airgap/basic-registry ' \ + '{}@{}:~/basic-registry'.format( + SSH_KEY_DIR, bastion_node.ssh_key_name, RESOURCE_DIR, + AWS_USER, bastion_node.host_name) + run_command(get_resources_command, log_out=False) + + generate_certs_command = \ + 'docker run -v $PWD/certs:/certs ' \ + '-e CA_SUBJECT="My own root CA" ' \ + '-e CA_EXPIRE="1825" -e SSL_EXPIRE="365" ' \ + '-e SSL_SUBJECT="{}" -e SSL_DNS="{}" ' \ + '-e SILENT="true" ' \ + 'superseb/omgwtfssl'.format(bastion_node.host_name, + bastion_node.host_name) + bastion_node.execute_command(generate_certs_command) + + move_certs_command = \ + 'sudo cat certs/cert.pem certs/ca.pem > ' \ + 'basic-registry/nginx_config/domain.crt && ' \ + 'sudo cat certs/key.pem > basic-registry/nginx_config/domain.key' + bastion_node.execute_command(move_certs_command) + + # Add credentials for private registry + store_creds_command = \ + 'docker run --rm melsayed/htpasswd "{}" "{}" >> ' \ + 'basic-registry/nginx_config/registry.password'.format( + PRIVATE_REGISTRY_USERNAME, PRIVATE_REGISTRY_PASSWORD) + bastion_node.execute_command(store_creds_command) + + # Ensure docker uses the certs that were generated + update_docker_command = \ + 'sudo mkdir -p /etc/docker/certs.d/{} && ' \ + 'sudo cp ~/certs/ca.pem /etc/docker/certs.d/{}/ca.crt && ' \ + 'sudo service docker restart'.format( + bastion_node.host_name, bastion_node.host_name) + bastion_node.execute_command(update_docker_command) + + # Run private registry + docker_compose_command = \ + 'cd basic-registry && ' \ + 'sudo curl -L "https://github.com/docker/compose/releases/' \ + 'download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" ' \ + '-o /usr/local/bin/docker-compose && ' \ + 'sudo chmod +x /usr/local/bin/docker-compose && ' \ + 'sudo docker-compose up -d' + bastion_node.execute_command(docker_compose_command) + time.sleep(5) + + print("Bastion Server Details:\nNAME: {}\nHOST NAME: {}\n" + "INSTANCE ID: {}\n".format(node_name, bastion_node.host_name, + bastion_node.provider_node_id)) + + return bastion_node + + +def add_rancher_images_to_private_registry(bastion_node, push_images=True): + get_images_command = \ + 'wget -O rancher-images.txt https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-images.txt && ' \ + 'wget -O rancher-save-images.sh https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-save-images.sh && ' \ + 'wget -O rancher-load-images.sh https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-load-images.sh'.format( + RANCHER_SERVER_VERSION) + bastion_node.execute_command(get_images_command) + + # comment out the "docker save" and "docker load" lines to save time + edit_save_and_load_command = \ + "sudo sed -i -e 's/docker save /# docker/g' rancher-save-images.sh && " \ + "sudo sed -i -e 's/docker load /# docker/g' rancher-load-images.sh && " \ + "chmod +x rancher-save-images.sh && chmod +x rancher-load-images.sh" + bastion_node.execute_command(edit_save_and_load_command) + + save_images_command = \ + "./rancher-save-images.sh --image-list ./rancher-images.txt" \ + + save_res = bastion_node.execute_command(save_images_command) + + if push_images: + load_images_command = \ + "docker login {} -u \"{}\" -p \"{}\" && " \ + "./rancher-load-images.sh --image-list ./rancher-images.txt " \ + "--registry {}".format( + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD, bastion_node.host_name) + load_res = bastion_node.execute_command(load_images_command) + print(load_res) + else: + load_res = None + + return save_res, load_res + + +def add_cleaned_images(bastion_node, images): + failures = [] + for image in images: + pull_image(bastion_node, image) + cleaned_image = re.search(".*(rancher/.*)", image).group(1) + tag_image(bastion_node, cleaned_image) + push_image(bastion_node, cleaned_image) + + validate_result = validate_image(bastion_node, cleaned_image) + if bastion_node.host_name not in validate_result[0]: + failures.append(image) + return failures + + +def add_images_to_private_registry(bastion_node, image_list): + failures = [] + for image in image_list: + pull_image(bastion_node, image) + tag_image(bastion_node, image) + push_image(bastion_node, image) + + validate_result = validate_image(bastion_node, image) + if bastion_node.host_name not in validate_result[0]: + failures.append(image) + return failures + + +def pull_image(bastion_node, image): + pull_image_command = "docker pull {}".format(image) + bastion_node.execute_command(pull_image_command) + + +def tag_image(bastion_node, image): + tag_image_command = "docker image tag {0} {1}/{0}".format( + image, bastion_node.host_name) + bastion_node.execute_command(tag_image_command) + + +def push_image(bastion_node, image): + push_image_command = \ + "docker login {} -u \"{}\" -p \"{}\" && docker push {}/{}".format( + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD, bastion_node.host_name, image) + bastion_node.execute_command(push_image_command) + + +def validate_image(bastion_node, image): + validate_image_command = "docker image ls {}/{}".format( + bastion_node.host_name, image) + return bastion_node.execute_command(validate_image_command) + + +def prepare_airgap_node(bastion_node, number_of_nodes): + node_name = AG_HOST_NAME + "-airgap" + # Create Airgap Node in AWS + ag_nodes = AmazonWebServices().create_multiple_nodes( + number_of_nodes, node_name, public_ip=False) + + for num, ag_node in enumerate(ag_nodes): + # Update docker for the user in node + ag_node_update_docker = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo usermod -aG docker {}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, AWS_USER) + bastion_node.execute_command(ag_node_update_docker) + + # Update docker in node with bastion cert details + ag_node_create_dir = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo mkdir -p /etc/docker/certs.d/{} && ' \ + 'sudo chown {} /etc/docker/certs.d/{}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, bastion_node.host_name, + AWS_USER, bastion_node.host_name) + bastion_node.execute_command(ag_node_create_dir) + + ag_node_write_cert = \ + 'scp -i "{}.pem" -o StrictHostKeyChecking=no ' \ + '/etc/docker/certs.d/{}/ca.crt ' \ + '{}@{}:/etc/docker/certs.d/{}/ca.crt'.format( + bastion_node.ssh_key_name, bastion_node.host_name, + AWS_USER, ag_node.private_ip_address, bastion_node.host_name) + bastion_node.execute_command(ag_node_write_cert) + + ag_node_restart_docker = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo service docker restart"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_restart_docker) + + ag_node_user_own_docker = \ + 'ssh -i "{0}.pem" -o StrictHostKeyChecking=no {1}@{2} ' \ + '"sudo chown {1}:{1} /home/{1}/.docker -R && ' \ + 'sudo chmod g+rwx "/home/{1}/.docker" -R"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_user_own_docker) + + print("Airgapped Instance Details:\nNAME: {}-{}\nPRIVATE IP: {}\n" + "".format(node_name, num, ag_node.private_ip_address)) + return ag_nodes + + +def copy_certs_to_node(bastion_node, ag_node): + ag_node_copy_certs = \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no certs/* ' \ + '{1}@{2}:~/'.format(bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_copy_certs) + + +# Note this only works on Ubuntu currently. There is a future enhancement +# to enable this to work for any OS. +def trust_certs_on_node(bastion_node, ag_node): + ag_node_update_certs = \ + 'sudo cp domain.crt ' \ + '/usr/local/share/ca-certificates/domain.crt && ' \ + 'sudo update-ca-certificates' + run_command_on_airgap_node(bastion_node, ag_node, + ag_node_update_certs) + + +def add_tarball_to_node(bastion_node, ag_node, tar_file, cluster_type): + ag_node_copy_tarball = \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no ./{3} ' \ + '{1}@{2}:~/{3}'.format(bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, tar_file) + bastion_node.execute_command(ag_node_copy_tarball) + ag_node_add_tarball_to_dir = \ + 'sudo mkdir -p /var/lib/rancher/{0}/agent/images/ && ' \ + 'sudo cp ./{1} /var/lib/rancher/{0}/agent/images/'.format(cluster_type, + tar_file) + run_command_on_airgap_node(bastion_node, ag_node, + ag_node_add_tarball_to_dir) + + +def prepare_private_registry(bastion_node, version): + if 'k3s' in version: + # Get k3s files associated with the specified version + k3s_binary = 'k3s' + if ARCH == 'arm64': + k3s_binary = 'k3s-arm64' + + get_images_command = \ + 'wget -O k3s-images.txt https://github.com/k3s-io/k3s/' \ + 'releases/download/{0}/k3s-images.txt && ' \ + 'wget -O k3s-install.sh https://get.k3s.io/ && ' \ + 'wget -O k3s https://github.com/k3s-io/k3s/' \ + 'releases/download/{0}/{1}'.format(version, k3s_binary) + bastion_node.execute_command(get_images_command) + + images = bastion_node.execute_command( + 'cat k3s-images.txt')[0].strip().split("\n") + elif 'rke2' in version: + stripped_version = re.search("v(\d+.\d+.\d+)", version).group(1) + if compare_versions(stripped_version, "1.21.2") < 0: + get_images_command = \ + 'wget -O rke2-images.txt https://github.com/rancher/rke2/' \ + 'releases/download/{0}/rke2-images.linux-amd64.txt && ' \ + 'wget -O rke2 https://github.com/rancher/rke2/' \ + 'releases/download/{0}/rke2.linux-amd64'.format(version) + else: + get_images_command = \ + 'wget -O rke2-images.txt https://github.com/rancher/rke2/' \ + 'releases/download/{0}/rke2-images-all.linux-amd64.txt && ' \ + 'wget -O rke2 https://github.com/rancher/rke2/' \ + 'releases/download/{0}/rke2.linux-amd64'.format(version) + bastion_node.execute_command(get_images_command) + + images = bastion_node.execute_command( + 'cat rke2-images.txt')[0].strip().split("\n") + else: + images = False + pytest.fail("{} is not valid. Please provide a valid " + "k3s or rke2 version.".format(version)) + + assert images + failures = add_cleaned_images(bastion_node, images) + assert failures == [], "Failed to add images: {}".format(failures) + + +def prepare_registries_mirror_on_node(bastion_node, ag_node, cluster_type): + # Ensure registry file has correct data + reg_file = readDataFile(RESOURCE_DIR, "airgap/registries.yaml") + reg_file = reg_file.replace("$PRIVATE_REG", bastion_node.host_name) + reg_file = reg_file.replace("$USERNAME", PRIVATE_REGISTRY_USERNAME) + reg_file = reg_file.replace("$PASSWORD", PRIVATE_REGISTRY_PASSWORD) + # Add registry file to node + ag_node_create_dir = \ + 'sudo mkdir -p /etc/rancher/{0} && ' \ + 'sudo chown {1} /etc/rancher/{0}'.format(cluster_type, AWS_USER) + run_command_on_airgap_node(bastion_node, ag_node, + ag_node_create_dir) + write_reg_file_command = \ + "cat <> /etc/rancher/{}/registries.yaml\n{}\nEOT".format( + cluster_type, reg_file) + run_command_on_airgap_node(bastion_node, ag_node, + write_reg_file_command) + + +def deploy_airgap_cluster(bastion_node, ag_nodes, k8s, server_ops, agent_ops): + token = "" + server_ip = ag_nodes[0].private_ip_address + if not any(x == k8s for x in ["k3s", "rke2"]): + raise ValueError("Please only use k3s or rke2, not {}".format(k8s)) + for num, ag_node in enumerate(ag_nodes): + if num == 0: + if k8s == "k3s": + install_server = \ + 'INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh {} && sudo ' \ + 'chmod 644 /etc/rancher/k3s/k3s.yaml'.format(server_ops) + else: + install_server = \ + 'sudo rke2 server --write-kubeconfig-mode 644 {} ' \ + '> /dev/null 2>&1 &'.format(server_ops) + + print("Install server command: {}".format(install_server)) + run_command_on_airgap_node(bastion_node, ag_node, install_server) + time.sleep(30) + token_command = 'sudo cat /var/lib/rancher/{}/server/node-token'.format(k8s) + token = run_command_on_airgap_node(bastion_node, ag_node, + token_command)[0].strip() + else: + if k8s == "k3s": + install_worker = \ + 'INSTALL_K3S_SKIP_DOWNLOAD=true K3S_URL=https://{}:6443 ' \ + 'K3S_TOKEN={} ./install.sh {}'.format(server_ip, token, + agent_ops) + else: + install_worker = \ + 'sudo rke2 agent --server https://{}:9345 ' \ + '--token {} {} > /dev/null 2>&1 &'.format(server_ip, token, + agent_ops) + print("Install worker command: {}".format(install_worker)) + run_command_on_airgap_node(bastion_node, ag_node, + install_worker) + time.sleep(15) + if k8s == "k3s": + wait_for_airgap_pods_ready(bastion_node, ag_nodes) + else: + time.sleep(60) + wait_for_airgap_pods_ready(bastion_node, ag_nodes, + kubectl='/var/lib/rancher/rke2/bin/kubectl', + kubeconfig='/etc/rancher/rke2/rke2.yaml') + + +def optionally_add_cluster_to_rancher(bastion_node, ag_nodes, prep="none"): + if AGENT_REG_CMD: + if prep == "k3s": + for num, ag_node in enumerate(ag_nodes): + prepare_registries_mirror_on_node(bastion_node, ag_node, 'k3s') + restart_k3s = 'sudo systemctl restart k3s-agent' + if num == 0: + restart_k3s = 'sudo systemctl restart k3s && ' \ + 'sudo chmod 644 /etc/rancher/k3s/k3s.yaml' + run_command_on_airgap_node(bastion_node, ag_node, restart_k3s) + print("Adding to rancher server") + result = run_command_on_airgap_node(bastion_node, ag_nodes[0], + AGENT_REG_CMD) + assert "deployment.apps/cattle-cluster-agent created" in result + + +def deploy_airgap_rancher(bastion_node): + ag_node = prepare_airgap_node(bastion_node, 1)[0] + privileged = "--privileged" + if RANCHER_HA_CERT_OPTION == 'byo-valid': + write_cert_command = "cat <> fullchain.pem\n{}\nEOT".format( + base64.b64decode(RANCHER_VALID_TLS_CERT).decode("utf-8")) + run_command_on_airgap_node(bastion_node, ag_node, + write_cert_command) + write_key_command = "cat <> privkey.pem\n{}\nEOT".format( + base64.b64decode(RANCHER_VALID_TLS_KEY).decode("utf-8")) + run_command_on_airgap_node(bastion_node, ag_node, + write_key_command) + deploy_rancher_command = \ + 'sudo docker run -d {} --restart=unless-stopped ' \ + '-p 80:80 -p 443:443 ' \ + '-v ${{PWD}}/fullchain.pem:/etc/rancher/ssl/cert.pem ' \ + '-v ${{PWD}}/privkey.pem:/etc/rancher/ssl/key.pem ' \ + '-e CATTLE_SYSTEM_DEFAULT_REGISTRY={} ' \ + '-e CATTLE_SYSTEM_CATALOG=bundled ' \ + '-e CATTLE_BOOTSTRAP_PASSWORD=\\\"{}\\\" ' \ + '{}/rancher/rancher:{} --no-cacerts --trace'.format( + privileged, bastion_node.host_name, ADMIN_PASSWORD, + bastion_node.host_name, RANCHER_SERVER_VERSION) + else: + deploy_rancher_command = \ + 'sudo docker run -d {} --restart=unless-stopped ' \ + '-p 80:80 -p 443:443 ' \ + '-e CATTLE_SYSTEM_DEFAULT_REGISTRY={} ' \ + '-e CATTLE_BOOTSTRAP_PASSWORD=\\\"{}\\\" ' \ + '-e CATTLE_SYSTEM_CATALOG=bundled {}/rancher/rancher:{} --trace'.format( + privileged, bastion_node.host_name, + ADMIN_PASSWORD, + bastion_node.host_name, + RANCHER_SERVER_VERSION) + deploy_result = run_command_on_airgap_node(bastion_node, ag_node, + deploy_rancher_command, + log_out=True) + assert "Downloaded newer image for {}/rancher/rancher:{}".format( + bastion_node.host_name, RANCHER_SERVER_VERSION) in deploy_result[1] + return ag_node + + +def run_docker_command_on_airgap_node(bastion_node, ag_node, cmd, + log_out=False): + docker_login_command = "docker login {} -u \\\"{}\\\" -p \\\"{}\\\"".format( + bastion_node.host_name, + PRIVATE_REGISTRY_USERNAME, PRIVATE_REGISTRY_PASSWORD) + if cmd.startswith("sudo"): + docker_login_command = "sudo " + docker_login_command + ag_command = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"{} && {}"'.format( + bastion_node.ssh_key_name, AWS_USER, ag_node.private_ip_address, + docker_login_command, cmd) + result = bastion_node.execute_command(ag_command) + if log_out: + print("Running command: {}".format(ag_command)) + print("Result: {}".format(result)) + return result + + +def run_command_on_airgap_node(bastion_node, ag_node, cmd, log_out=False): + if cmd.startswith("docker") or cmd.startswith("sudo docker"): + return run_docker_command_on_airgap_node( + bastion_node, ag_node, cmd, log_out) + ag_command = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"{}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, cmd) + result = bastion_node.execute_command(ag_command) + if log_out: + print("Running command: {}".format(ag_command)) + print("Result:\n{}".format("\n---\n".join(result))) + return result + + +def wait_for_airgap_pods_ready(bastion_node, ag_nodes, + kubectl='kubectl', kubeconfig=None): + if kubeconfig: + node_cmd = "{} get nodes --kubeconfig {}".format(kubectl, kubeconfig) + command = "{} get pods -A --kubeconfig {}".format(kubectl, kubeconfig) + else: + node_cmd = "{} get nodes".format(kubectl) + command = "{} get pods -A".format(kubectl) + start = time.time() + wait_for_pods_to_be_ready = True + while wait_for_pods_to_be_ready: + unready_pods = [] + unready_nodes = [] + if time.time() - start > DEFAULT_CLUSTER_STATE_TIMEOUT: + print_cluster_state(bastion_node, ag_nodes, kubectl, kubeconfig) + raise AssertionError("Timed out waiting for cluster to be ready") + time.sleep(10) + nodes = run_command_on_airgap_node(bastion_node, ag_nodes[0], node_cmd) + nodes_arr = nodes[0].strip().split("\n")[1:] + missing_nodes = NUMBER_OF_INSTANCES - len(nodes_arr) + if missing_nodes: + print("Waiting for {} more node(s) to join the cluster.".format( + missing_nodes)) + unready_nodes.append(missing_nodes) + for node in nodes_arr: + if "NotReady" in node: + print("Waiting for node: {}".format(node)) + unready_nodes.append(node) + if unready_nodes or not nodes_arr: + continue + pods = run_command_on_airgap_node(bastion_node, ag_nodes[0], command) + pods_arr = pods[0].strip().split("\n")[1:] + for pod in pods_arr: + if "Completed" not in pod and "Running" not in pod: + print("Waiting for pod: {}".format(pod)) + unready_pods.append(pod) + if unready_pods or not pods_arr: + wait_for_pods_to_be_ready = True + else: + wait_for_pods_to_be_ready = False + print_cluster_state(bastion_node, ag_nodes, kubectl, kubeconfig) + + +def print_cluster_state(bastion_node, ag_nodes, kubectl='kubectl', + kubeconfig=None): + if kubeconfig: + cmd = "{} get nodes,pods -A -o wide --kubeconfig {}".format(kubectl, + kubeconfig) + else: + cmd = "{} get nodes,pods -A -o wide".format(kubectl) + run_command_on_airgap_node(bastion_node, ag_nodes[0], cmd, log_out=True) + + +def create_nlb_and_add_targets(aws_nodes): + # Create internet-facing nlb and grab ARN & dns name + lb = AmazonWebServices().create_network_lb(name=AG_HOST_NAME + "-nlb") + lb_arn = lb["LoadBalancers"][0]["LoadBalancerArn"] + public_dns = lb["LoadBalancers"][0]["DNSName"] + # Create internal nlb and grab ARN & dns name + internal_lb = AmazonWebServices().create_network_lb( + name=AG_HOST_NAME + "-internal-nlb", scheme='internal') + internal_lb_arn = internal_lb["LoadBalancers"][0]["LoadBalancerArn"] + internal_lb_dns = internal_lb["LoadBalancers"][0]["DNSName"] + + # Upsert the route53 record -- if it exists, update, if not, insert + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_AG_INTERNAL_HOSTNAME, internal_lb_dns) + if RANCHER_HA_CERT_OPTION == 'byo-valid': + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_AG_HOSTNAME, public_dns) + public_dns = RANCHER_AG_HOSTNAME + + # Create the target groups + tg80 = AmazonWebServices(). \ + create_ha_target_group(80, AG_HOST_NAME + "-tg-80") + tg443 = AmazonWebServices(). \ + create_ha_target_group(443, AG_HOST_NAME + "-tg-443") + tg80_arn = tg80["TargetGroups"][0]["TargetGroupArn"] + tg443_arn = tg443["TargetGroups"][0]["TargetGroupArn"] + # Create the internal target groups + internal_tg80 = AmazonWebServices(). \ + create_ha_target_group(80, AG_HOST_NAME + "-internal-tg-80") + internal_tg443 = AmazonWebServices(). \ + create_ha_target_group(443, AG_HOST_NAME + "-internal-tg-443") + internal_tg80_arn = internal_tg80["TargetGroups"][0]["TargetGroupArn"] + internal_tg443_arn = internal_tg443["TargetGroups"][0]["TargetGroupArn"] + + # Create listeners for the load balancers, to forward to the target groups + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=80, targetGroupARN=tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=443, targetGroupARN=tg443_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=80, + targetGroupARN=internal_tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=443, + targetGroupARN=internal_tg443_arn) + + targets = [] + + for aws_node in aws_nodes: + targets.append(aws_node.provider_node_id) + + # Register the nodes to the internet-facing targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + health80 = AmazonWebServices().describe_target_health( + tg80_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + tg443_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + time.sleep(1) + + # Register the nodes to the internal targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + try: + health80 = AmazonWebServices().describe_target_health( + internal_tg80_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + internal_tg443_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + except Exception: + print("Target group healthchecks unavailable...") + time.sleep(1) + + return public_dns + + +def get_bastion_node(auth=True): + if BASTION_ID: + bastion_node = AmazonWebServices().get_node(BASTION_ID, ssh_access=True) + print("Bastion Server Details:\nHOST NAME: {}\n" + "INSTANCE ID: {}\n".format(bastion_node.host_name, + bastion_node.provider_node_id)) + elif auth: + bastion_node = deploy_bastion_server() + else: + bastion_node = deploy_noauth_bastion_server() + if bastion_node is None: + pytest.fail("Did not provide a valid Provider ID for the bastion node") + return bastion_node + + +def setup_ssh_key(bastion_node): + # Copy SSH Key to Bastion and local dir and give it proper permissions + write_key_command = "cat <> {}.pem\n{}\nEOT".format( + bastion_node.ssh_key_name, bastion_node.ssh_key) + bastion_node.execute_command(write_key_command) + local_write_key_command = \ + "mkdir -p {} && cat <> {}/{}.pem\n{}\nEOT".format( + SSH_KEY_DIR, SSH_KEY_DIR, + bastion_node.ssh_key_name, bastion_node.ssh_key) + run_command(local_write_key_command, log_out=False) + + set_key_permissions_command = "chmod 400 {}.pem".format( + bastion_node.ssh_key_name) + bastion_node.execute_command(set_key_permissions_command) + local_set_key_permissions_command = "chmod 400 {}/{}.pem".format( + SSH_KEY_DIR, bastion_node.ssh_key_name) + run_command(local_set_key_permissions_command, log_out=False) + + +@pytest.fixture() +def check_hostname_length(): + print("Host Name: {}".format(AG_HOST_NAME)) + assert len(AG_HOST_NAME) < 17, "Provide hostname that is 16 chars or less" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap_ha.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap_ha.py new file mode 100644 index 0000000..2577f6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_airgap_ha.py @@ -0,0 +1,594 @@ +from base64 import b64decode +import os +import pytest +import time + +from .common import ( + ADMIN_PASSWORD, + AmazonWebServices, + run_command, wait_for_status_code +) +from .test_custom_host_reg import RANCHER_SERVER_VERSION + +from .test_create_ha import ( + set_url_and_password, + RANCHER_HA_CERT_OPTION, + RANCHER_VALID_TLS_CERT, + RANCHER_VALID_TLS_KEY, + KUBERNETES_VERSION +) +from lib.aws import AWS_USER + +AWS_AMI = os.environ.get("AWS_AMI", "ami-012fd49f6b0c404c7") +DOCKER_COMPOSE_VERSION = os.environ.get("DOCKER_COMPOSE_VERSION", "1.24.1") +RKE_VERSION = os.environ.get("RKE_VERSION", "v1.3.11") + +# airgap variables +RANCHER_HELM_EXTRA_SETTINGS = os.environ.get("RANCHER_HELM_EXTRA_SETTINGS") +NUMBER_OF_INSTANCES = int(os.environ.get("RANCHER_AIRGAP_INSTANCE_COUNT", "3")) +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "testsa") +AG_HOST_NAME = HOST_NAME +RANCHER_AG_INTERNAL_HOSTNAME = AG_HOST_NAME + "-internal.qa.rancher.space" +RANCHER_AG_HOSTNAME = AG_HOST_NAME + ".qa.rancher.space" +RANCHER_HELM_REPO = os.environ.get("RANCHER_HELM_REPO", "latest") +RANCHER_HELM_URL = os.environ.get("RANCHER_HELM_URL", "https://releases.rancher.com/server-charts/") + +RESOURCE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') +SSH_KEY_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + '.ssh') + +# bastion/ registry variables +PRIVATE_REGISTRY_USERNAME = os.environ.get("RANCHER_BASTION_USERNAME") +PRIVATE_REGISTRY_PASSWORD = \ + os.environ.get("RANCHER_BASTION_PASSWORD", ADMIN_PASSWORD) +RANCHER_EXTERNAL_BASTION = os.environ.get("RANCHER_EXTERNAL_BASTION", "") +RANCHER_EXTERNAL_HOST_NAME = os.environ.get( + "RANCHER_EXTERNAL_HOST_NAME", AG_HOST_NAME) +REG_HOST_NAME = RANCHER_EXTERNAL_HOST_NAME + "-registry" + ".qa.rancher.space" +REGISTRY_HOSTNAME = os.environ.get("RANCHER_BASTION_REGISTRY", REG_HOST_NAME) +INSTALL_DEPENDENCIES_FLAG=os.environ.get("INSTALL_DEPENDENCIES_FLAG", "True") + + +def test_deploy_airgap_ha_rancher(check_hostname_length): + # check for user entered bastion/registry + if len(RANCHER_EXTERNAL_BASTION) > 5: + bastion_node = AmazonWebServices().get_node( + RANCHER_EXTERNAL_BASTION, + ssh_access=True) + print("using external node for private registry", REGISTRY_HOSTNAME) + else: + bastion_node = deploy_bastion_server() + add_rancher_images_to_private_registry( + bastion_node, + noauth_reg_name=REGISTRY_HOSTNAME) + print("using new node for private registry") + + kube_config = 'export KUBECONFIG="kube_config_config.yaml && ' + # check for registry, images, private IP + assert len(bastion_node.private_ip_address) > 5, \ + "the bastion node does not have a private IP" + assert bastion_node.execute_command("docker pull {}/{}:{}".format( + REGISTRY_HOSTNAME, + "rancher/rancher-agent", + RANCHER_SERVER_VERSION))[1].find("not found") < 0, \ + "registry is missing rancher-agent image" + + # checks for and installs dependencies if missing from bastion node + if INSTALL_DEPENDENCIES_FLAG.lower() != "false": + if bastion_node.execute_command( + "rke --version")[0].find("version") == -1: + install_rke(bastion_node) + if bastion_node.execute_command( + '/snap/bin/helm')[0].find("Flags:") == -1: + install_helm(bastion_node) + if bastion_node.execute_command( + kube_config+"/snap/bin/kubectl version")[0].find("Version") == -1: + install_kubectl(bastion_node) + + # check kubectl, helm, rke + assert bastion_node.execute_command( + "rke --version")[1].find("not found") < 0, \ + "registry does not have RKE installed" + assert bastion_node.execute_command( + "/snap/bin/helm version")[1].find("not found") < 0, \ + "registry does not have helm installed" + assert bastion_node.execute_command( + '/snap/bin/helm')[0].find("Flags:") > -1, \ + "helm is not installed correctly" + assert bastion_node.execute_command( + kube_config+"/snap/bin/kubectl version")[1].find("not found") < 0, \ + "registry does not have kubectl installed" + + ag_nodes = setup_airgap_rancher(bastion_node) + public_dns = create_nlb_and_add_targets(ag_nodes) + print( + "\nConnect to bastion node with:\nssh -i {}.pem {}@{}\n" + "Connect to rancher node by connecting to bastion, then run:\n" + "ssh -i {}.pem {}@{}\n\nOpen the Rancher UI with: https://{}\n" + "** IMPORTANT: SET THE RANCHER SERVER URL UPON INITIAL LOGIN TO: {} **" + "\nWhen creating a cluster, enable private registry with below" + " settings:\nPrivate Registry URL: {}\nPrivate Registry is not" + "using basic auth (no login required) \n".format( + bastion_node.ssh_key_name, AWS_USER, bastion_node.host_name, + bastion_node.ssh_key_name, AWS_USER, + ag_nodes[0].private_ip_address, + public_dns, RANCHER_AG_INTERNAL_HOSTNAME, + REGISTRY_HOSTNAME)) + time.sleep(180) + setup_rancher_server(bastion_node) + + +def setup_rancher_server(bastion_node): + base_url = "https://" + RANCHER_AG_HOSTNAME + wait_for_status_code(url=base_url + "/v3", expected_code=401) + auth_url = base_url + "/v3-public/localproviders/local?action=login" + wait_for_status_code(url=auth_url, expected_code=200) + get_bootstrap_passwd = "export KUBECONFIG=~/kube_config_config.yaml && " \ + "/snap/bin/kubectl get secret --namespace cattle-system bootstrap-secret -o " \ + """go-template='{{.data.bootstrapPassword|base64decode}}{{"\\n"}}'""" + bootstrap_passwd = bastion_node.execute_command(get_bootstrap_passwd)[0] + print("bootstrap password:", bootstrap_passwd.replace(" ", "")) + # currently can't set password in airgap setup without reworking below function + set_url_and_password(base_url, "https://" + RANCHER_AG_INTERNAL_HOSTNAME) + + +def deploy_bastion_server(): + node_name = AG_HOST_NAME + "-bastion" + node_name = REG_HOST_NAME + # Create Registry Server in AWS + registry_node = AmazonWebServices().create_node(node_name, for_bastion=True) + setup_ssh_key(registry_node) + # update a record if it exists + AmazonWebServices().upsert_route_53_record_a( + REGISTRY_HOSTNAME, registry_node.private_ip_address) + # Get resources for private registry + get_registry_resources(registry_node) + # use valid certs + overwrite_tls_certs(registry_node) + # remove auth from nginx.conf + overwrite_word_in_file_command = \ + "sed -i -e 's/{}/{}/g' ~/basic-registry/nginx_config/nginx.conf" + registry_node.execute_command(overwrite_word_in_file_command.format( + "auth_basic", "#auth_basic")) + registry_node.execute_command(overwrite_word_in_file_command.format( + "add_header", "#add_header")) + # Run private registry + run_docker_registry(registry_node) + print("Registry Server Details:\nNAME: {}\nHOST NAME: {}\n" + "INSTANCE ID: {}\n".format(node_name, registry_node.host_name, + registry_node.provider_node_id)) + return registry_node + + +def overwrite_tls_certs(external_node): + overwrite_server_name_command = \ + "sed -i -e '0,/_;/s//{};/' basic-registry/nginx_config/nginx.conf && "\ + 'echo \"{}\" >> ~/basic-registry/nginx_config/domain.crt && ' \ + 'echo \"{}\" >> ~/basic-registry/nginx_config/domain.key' + external_node.execute_command(overwrite_server_name_command.format( + REGISTRY_HOSTNAME, + b64decode(RANCHER_VALID_TLS_CERT).decode("utf-8"), + b64decode(RANCHER_VALID_TLS_KEY).decode("utf-8"))) + + +def get_registry_resources(external_node): + get_resources_command = \ + 'scp -q -i {}/{}.pem -o StrictHostKeyChecking=no ' \ + '-o UserKnownHostsFile=/dev/null -r {}/airgap/basic-registry ' \ + '{}@{}:~/basic-registry'.format( + SSH_KEY_DIR, external_node.ssh_key_name, RESOURCE_DIR, + AWS_USER, external_node.host_name) + run_command(get_resources_command, log_out=False) + + +def install_rke(external_node): + docker_compose_command = \ + 'cd ~/ && sudo wget ' \ + 'https://github.com/rancher/rke/releases/download/{}' \ + '/rke_linux-amd64 && ' \ + 'sudo mv rke_linux-amd64 rke && ' \ + 'sudo chmod +x rke && ' \ + 'sudo mv rke /usr/local/bin'.format(RKE_VERSION) + return external_node.execute_command(docker_compose_command) + + +def install_helm(external_node): + return external_node.execute_command( + 'sudo snap install helm --classic') + + +def install_kubectl(external_node): + return external_node.execute_command( + 'sudo snap install kubectl --classic') + + +def run_docker_registry(external_node): + docker_compose_command = \ + 'cd ~/basic-registry && ' \ + 'sudo curl -L "https://github.com/docker/compose/releases/' \ + 'download/{}/docker-compose-$(uname -s)-$(uname -m)" ' \ + '-o /usr/local/bin/docker-compose && ' \ + 'sudo chmod +x /usr/local/bin/docker-compose && ' \ + 'sudo docker-compose up -d'.format(DOCKER_COMPOSE_VERSION) + external_node.execute_command(docker_compose_command) + time.sleep(5) + + +def add_rancher_images_to_private_registry( + bastion_node, push_images=True, noauth_reg_name=""): + get_images_command = \ + 'wget -O rancher-images.txt https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-images.txt && ' \ + 'wget -O rancher-save-images.sh https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-save-images.sh && ' \ + 'wget -O rancher-load-images.sh https://github.com/rancher/rancher/' \ + 'releases/download/{0}/rancher-load-images.sh'.format( + RANCHER_SERVER_VERSION) + bastion_node.execute_command(get_images_command) + + # comment out the "docker save" and "docker load" lines to save time + edit_save_and_load_command = \ + "sudo sed -i -e 's/docker save /# docker/g' rancher-save-images.sh && " \ + "sudo sed -i -e 's/docker load /# docker/g' rancher-load-images.sh && " \ + "chmod +x rancher-save-images.sh && chmod +x rancher-load-images.sh" + bastion_node.execute_command(edit_save_and_load_command) + + save_images_command = \ + "./rancher-save-images.sh --image-list ./rancher-images.txt" + save_res = bastion_node.execute_command(save_images_command) + + if push_images: + if len(noauth_reg_name) == 0: + load_images_command = \ + "docker login {} -u {} -p {} && " \ + "./rancher-load-images.sh --image-list ./rancher-images.txt " \ + "--registry {}".format( + bastion_node.host_name, PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD, bastion_node.host_name) + load_res = bastion_node.execute_command(load_images_command) + else: + load_images_command = \ + "./rancher-load-images.sh --image-list ./rancher-images.txt " \ + "--registry {}".format(noauth_reg_name) + load_res = bastion_node.execute_command(load_images_command) + print(load_res) + else: + load_res = None + + return save_res, load_res + + +def prepare_airgap_node(bastion_node, number_of_nodes): + node_name = AG_HOST_NAME + "-agha" + # Create Airgap Node in AWS + ag_nodes = AmazonWebServices().create_multiple_nodes( + number_of_nodes, node_name, ami=AWS_AMI, public_ip=False) + + for num, ag_node in enumerate(ag_nodes): + # Update docker for the user in node + ag_node_update_docker = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo usermod -aG docker {}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, AWS_USER) + bastion_node.execute_command(ag_node_update_docker) + if PRIVATE_REGISTRY_USERNAME is not None: + # assuming that we setup the auth-enabled registry from the other + # airgap job, which uses self signed certs on the registry. We + # now need to login and move the certs to each downstream node. + ss_certs_command = \ + 'scp -i "{}.pem" ~/certs/ca.pem {}@{}:/home/{}/ca.pem && ' \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo mkdir -p /etc/docker/certs.d/{} && ' \ + 'sudo cp ~/ca.pem /etc/docker/certs.d/{}/ca.crt && ' \ + 'sudo service docker restart"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, AWS_USER, + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, bastion_node.host_name, + bastion_node.host_name) + bastion_node.execute_command(ss_certs_command) + return ag_nodes + + +def setup_airgap_rancher(bastion_node, number_of_nodes=NUMBER_OF_INSTANCES): + # remove old setup files, if any + bastion_node.execute_command("rm ingress* config.* kube_config_* tls*") + # need an odd number of nodes for HA setup + if number_of_nodes % 2 == 0: + number_of_nodes += 1 + print("automatically setting number of nodes to odd number: ", + number_of_nodes) + if number_of_nodes < 3: + number_of_nodes = 3 + print("automatically setting number of nodes to at least ", + number_of_nodes) + ag_nodes = prepare_airgap_node(bastion_node, number_of_nodes) + # create RKE config based on number of nodes + rke_template_node = "" + if KUBERNETES_VERSION: + rke_template_node = f'kubernetes_version: {KUBERNETES_VERSION}\n' + rke_template_node += "nodes:" + with open(RESOURCE_DIR+'/airgap/config_yamls/config_body.yaml') as f2: + rke_template_node_body = f2.read() + + for x in range(number_of_nodes): + rke_template_node += '\n - address: ' \ + + ag_nodes[x].private_ip_address + "\n" + rke_template_node_body + + with open(RESOURCE_DIR+'/airgap/config_yamls/config_end.yaml') as f3: + rke_template_node_end = f3.read() + registry_credentials=REGISTRY_HOSTNAME + if PRIVATE_REGISTRY_USERNAME is not None: + registry_credentials+='\n user: {}\n' \ + ' password: {}'.format( + PRIVATE_REGISTRY_USERNAME, + PRIVATE_REGISTRY_PASSWORD) + rke_template_node +=\ + rke_template_node_end.format(registry_credentials) + # write config, and run rke up + print(f'RKE Template:\n{rke_template_node}') + bastion_node.execute_command( + "echo '{}' > config.yaml".format(rke_template_node)) + bastion_node.execute_command( + 'cd ~/ && /usr/local/bin/rke up --config config.yaml && sleep 240') + assert bastion_node.execute_command( + "cd ~ && cat kube_config_config.yaml")[0].find(".") > -1, \ + "rke up failed, config file likely incorrect" + # setup helm and rancher template + assert bastion_node.execute_command( + '/snap/bin/helm')[0].find("Flags:") > -1, \ + "helm is not installed correctly" + + repo_name = "rancher-" + RANCHER_HELM_REPO + repo_url = RANCHER_HELM_URL + RANCHER_HELM_REPO + bastion_node.execute_command( + '/snap/bin/helm repo add ' + repo_name + ' ' + repo_url) + assert bastion_node.execute_command( + "/snap/bin/helm repo list")[0].find("rancher") > -1, \ + "helm was unable to add rancher repo" + bastion_node.execute_command( + "/snap/bin/helm fetch " + repo_name + "/rancher") + bastion_node.execute_command( + "/snap/bin/helm fetch {}/rancher --version={}".format( + repo_name, + RANCHER_SERVER_VERSION)) + # remove `v` from the version tag for helm formatting + new_rancher_version = RANCHER_SERVER_VERSION + if RANCHER_SERVER_VERSION[0] == 'v': + new_rancher_version = RANCHER_SERVER_VERSION[1:] + helm_template = \ + "cd ~/ && /snap/bin/helm template rancher ./rancher-{3}.tgz " \ + "--output-dir . --namespace cattle-system --set hostname={1} " \ + "--set rancherImage={2}/rancher/rancher " \ + "--set systemDefaultRegistry={2} " \ + "--set useBundledSystemChart=true --set ingress.tls.source=secret " \ + "--set rancherImageTag={0} --no-hooks --validate".format( + RANCHER_SERVER_VERSION, + RANCHER_AG_INTERNAL_HOSTNAME, + REGISTRY_HOSTNAME, + new_rancher_version) + extra_settings = [] + if RANCHER_HELM_EXTRA_SETTINGS: + extra_settings.append(RANCHER_HELM_EXTRA_SETTINGS) + if extra_settings: + for setting in extra_settings: + helm_template = helm_template + " " + setting + + print("Executing helm install: \n", helm_template) + print("\nUsing the following kube config: \n") + print(bastion_node.execute_command("cat ~/kube_config_config.yaml")[0]) + bastion_node.execute_command(helm_template) + kube_config = 'export KUBECONFIG=~/kube_config_config.yaml && ' + # install rancher + bastion_node.execute_command( + kube_config+"/snap/bin/kubectl create namespace cattle-system && 10") + create_tls_secrets(bastion_node) + bootstrap_password="" + if RANCHER_HELM_EXTRA_SETTINGS: + for setting in RANCHER_HELM_EXTRA_SETTINGS.split("--set "): + settings_keypair = RANCHER_HELM_EXTRA_SETTINGS.split("=") + if "bootstrapPassword" in settings_keypair[0]: + bootstrap_password = settings_keypair[1] + print ("bootstrap password: ", bootstrap_password) + execution = bastion_node.execute_command( + kube_config+ + "/snap/bin/kubectl create secret" + + " generic -n cattle-system " + + "bootstrap-secret --from-literal=bootstrapPassword=" + + bootstrap_password + " && 10") + print(execution[0], execution[1]) + assert execution[0].find("create") > -1, \ + "bootstrap password secret not created" + break + + bastion_node.execute_command( + kube_config + "/snap/bin/kubectl -n cattle-system apply -R -f" + + " ./rancher && sleep 60") + print("applying rancher template: \n", + "/snap/bin/kubectl -n cattle-system apply -R -f", + " ./rancher && sleep 60") + assert bastion_node.execute_command( + kube_config+"/snap/bin/kubectl get pods -A")[0].find( + "cattle-system") > 0, \ + "install of rancher failed. cattle-system has no pods" + + # modify ingress to include internal and external LBs + bastion_node.execute_command( + kube_config + "/snap/bin/kubectl get ingress rancher " + + " -n cattle-system -o yaml > ingress.yaml") + ingress_yaml = bastion_node.execute_command("cat ingress.yaml")[0] + beginning_ingress = ingress_yaml[:ingress_yaml.find(" tls:")] + beginning_ingress += " - host: {}".format(RANCHER_AG_HOSTNAME) + beginning_ingress += """\n http: + paths: + - backend: + service: + name: rancher + port: + number: 80 + pathType: ImplementationSpecific + tls: + - hosts:""" + beginning_ingress += "\n - {}\n".format(RANCHER_AG_HOSTNAME) + \ + ingress_yaml[ingress_yaml.find("- hosts:")+9:] + bastion_node.execute_command( + "echo '{}' > ingress2.yaml".format(beginning_ingress)) + bastion_node.execute_command( + kube_config+"/snap/bin/kubectl apply -f ingress2.yaml") + + assert bastion_node.execute_command( + kube_config+"/snap/bin/kubectl get ingress -n cattle-system")[0].find( + RANCHER_AG_HOSTNAME) > 0, \ + "Ingress modification failed. " + print("in order to upgrade, you will need to modify the ingress to have ", + "both hosts, public and private. Here is the modified ingress: \n", + beginning_ingress) + return ag_nodes + + +def create_nlb_and_add_targets(aws_nodes): + # Create internet-facing nlb and grab ARN & dns name + lb = AmazonWebServices().create_network_lb(name=AG_HOST_NAME + "-nlb") + lb_arn = lb["LoadBalancers"][0]["LoadBalancerArn"] + public_dns = lb["LoadBalancers"][0]["DNSName"] + # Create internal nlb and grab ARN & dns name + internal_lb = AmazonWebServices().create_network_lb( + name=AG_HOST_NAME + "-internal-nlb", scheme='internal') + internal_lb_arn = internal_lb["LoadBalancers"][0]["LoadBalancerArn"] + internal_lb_dns = internal_lb["LoadBalancers"][0]["DNSName"] + + # Upsert the route53 record -- if it exists, update, if not, insert + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_AG_INTERNAL_HOSTNAME, internal_lb_dns) + if RANCHER_HA_CERT_OPTION == 'byo-valid': + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_AG_HOSTNAME, public_dns) + public_dns = RANCHER_AG_HOSTNAME + + # Create the target groups + tg80 = AmazonWebServices(). \ + create_ha_target_group(80, AG_HOST_NAME + "-tg-80") + tg443 = AmazonWebServices(). \ + create_ha_target_group(443, AG_HOST_NAME + "-tg-443") + tg80_arn = tg80["TargetGroups"][0]["TargetGroupArn"] + tg443_arn = tg443["TargetGroups"][0]["TargetGroupArn"] + # Create the internal target groups + internal_tg80 = AmazonWebServices(). \ + create_ha_target_group(80, AG_HOST_NAME + "-internal-tg-80") + internal_tg443 = AmazonWebServices(). \ + create_ha_target_group(443, AG_HOST_NAME + "-internal-tg-443") + internal_tg80_arn = internal_tg80["TargetGroups"][0]["TargetGroupArn"] + internal_tg443_arn = internal_tg443["TargetGroups"][0]["TargetGroupArn"] + + # Create listeners for the load balancers, to forward to the target groups + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=80, targetGroupARN=tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=443, targetGroupARN=tg443_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=80, + targetGroupARN=internal_tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=443, + targetGroupARN=internal_tg443_arn) + + targets = [] + + for aws_node in aws_nodes: + targets.append(aws_node.provider_node_id) + + # Register the nodes to the internet-facing targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + health80 = AmazonWebServices().describe_target_health( + tg80_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + tg443_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + time.sleep(1) + + # Register the nodes to the internal targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + try: + health80 = AmazonWebServices().describe_target_health( + internal_tg80_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + internal_tg443_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + except Exception: + print("Target group healthchecks unavailable...") + time.sleep(1) + + return public_dns + + +def setup_ssh_key(bastion_node): + # Copy SSH Key to Bastion and local dir and give it proper permissions + write_key_command = "cat <> {}.pem\n{}\nEOT".format( + bastion_node.ssh_key_name, bastion_node.ssh_key) + bastion_node.execute_command(write_key_command) + local_write_key_command = \ + "mkdir -p {} && cat <> {}/{}.pem\n{}\nEOT".format( + SSH_KEY_DIR, SSH_KEY_DIR, + bastion_node.ssh_key_name, bastion_node.ssh_key) + run_command(local_write_key_command, log_out=False) + + set_key_permissions_command = "chmod 400 {}.pem".format( + bastion_node.ssh_key_name) + bastion_node.execute_command(set_key_permissions_command) + local_set_key_permissions_command = "chmod 400 {}/{}.pem".format( + SSH_KEY_DIR, bastion_node.ssh_key_name) + run_command(local_set_key_permissions_command, log_out=False) + + +def create_tls_secrets(bastion_node): + # currently hard coded for byo-valid certs + cert_path = "~/tls.crt" + key_path = "~/tls.key" + + bastion_write_encoded_certs(cert_path, + RANCHER_VALID_TLS_CERT, + bastion_node) + bastion_write_encoded_certs(key_path, + RANCHER_VALID_TLS_KEY, + bastion_node) + kube_config = 'cd ~/ && export KUBECONFIG=kube_config_config.yaml ' + tls_command = kube_config+" && /snap/bin/kubectl -n cattle-system " \ + "create secret tls tls-rancher-ingress " \ + "--cert=tls.crt" + " --key=tls.key" + + tls_output = bastion_node.execute_command(tls_command) + bastion_node.execute_command("sleep 2") + print(tls_output) + + assert tls_output[0].find("secret/tls-rancher-ingress created") > -1 + + +def bastion_write_encoded_certs(path, contents, bastion_node): + bastion_node.execute_command( + "echo '{}' > {}".format(b64decode(contents).decode("utf-8"), path)) + assert bastion_node.execute_command( + "cat {}".format(path))[1].find("not found") < 0 + + +@pytest.fixture() +def check_hostname_length(): + print("Host Name: {}".format(AG_HOST_NAME)) + assert len(AG_HOST_NAME) < 17, "Provide hostname that is 16 chars or less" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_cluster.py new file mode 100644 index 0000000..4aedaf5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_cluster.py @@ -0,0 +1,103 @@ +from .common import * # NOQA +import pytest +import requests + +AKS_CLUSTER_VERSION = os.environ.get('RANCHER_AKS_CLUSTER_VERSION', '') +SSH_KEY = os.environ.get('RANCHER_SSH_KEY', "") +SUBSCRIPTION_ID = os.environ.get('RANCHER_AKS_SUBSCRIPTION_ID', '') +TENANT_ID = os.environ.get('RANCHER_AKS_TENANT_ID', '') +CLIENT_ID = os.environ.get('RANCHER_AKS_CLIENT_ID', '') +SECRET_KEY = os.environ.get('RANCHER_AKS_SECRET_KEY', '') +RESOURCE_GROUP = os.environ.get('RANCHER_AKS_RESOURCE_GROUP', '') +AKS_REGION = os.environ.get('RANCHER_AKS_REGION', 'eastus') +akscredential = pytest.mark.skipif(not (SUBSCRIPTION_ID and TENANT_ID and + CLIENT_ID and SECRET_KEY), + reason='AKS Credentials not provided, ' + 'cannot create cluster') + + +@akscredential +def test_create_aks_cluster(): + version = get_aks_version() + client, cluster = create_and_validate_aks_cluster(version) + cluster_cleanup(client, cluster) + + +def create_and_validate_aks_cluster(version): + client = get_user_client() + aks_config = get_aks_config(version) + + print("Cluster creation") + cluster = client.create_cluster(aks_config) + cluster = validate_cluster(client, cluster, check_intermediate_state=True, + skipIngresscheck=True) + return client, cluster + + +def get_aks_version(multiple_versions=False): + + if not AKS_CLUSTER_VERSION: + data_test = { + "region": "eastus", + "subscriptionId": SUBSCRIPTION_ID, + "tenantId": TENANT_ID, + "clientId": CLIENT_ID, + "clientSecret": SECRET_KEY + } + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + USER_TOKEN} + + aks_version_url = CATTLE_TEST_URL + "/meta/aksVersions" + print(aks_version_url) + response = requests.post(aks_version_url, json=data_test, + verify=False, headers=headers) + + assert response.status_code == 200 + assert response.content is not None + print("JSON RESPONSE IS") + print(response.content) + json_response = json.loads(response.content) + + # Getting the second highest version from the list to avoid K8s versions in preview. + if multiple_versions and len(json_response) > 1: + aksclusterversion = [json_response[0], json_response[-2]] + else: + aksclusterversion = json_response[-2] + else: + aksclusterversion = AKS_CLUSTER_VERSION + + print(aksclusterversion) + return aksclusterversion + + +def get_aks_config(version): + aks_config = { + "azureKubernetesServiceConfig": { + "adminUsername": "azureuser", + "agentPoolName": "rancher", + "agentVmSize": "Standard_D2_v2", + "clientId": CLIENT_ID, + "clientSecret": SECRET_KEY, + "count": 3, + "dnsServiceIp": None, + "dockerBridgeCidr": None, + "kubernetesVersion": version, + "location": AKS_REGION, + "osDiskSizeGb": 100, + "resourceGroup": RESOURCE_GROUP, + "serviceCidr": None, + "sshPublicKeyContents": SSH_KEY, + "subnet": None, + "subscriptionId": SUBSCRIPTION_ID, + "tenantId": TENANT_ID, + "type": "azureKubernetesServiceConfig", + "virtualNetwork": None, + "virtualNetworkResourceGroup": None, + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + }, + "name": random_test_name("test-auto-aks"), + "type": "cluster" + } + return aks_config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_v2_hosted_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_v2_hosted_cluster.py new file mode 100644 index 0000000..78d0538 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_aks_v2_hosted_cluster.py @@ -0,0 +1,124 @@ +import os +from .common import * +import pytest + +AZURE_SUBSCRIPTION_ID = os.environ.get("AZURE_SUBSCRIPTION_ID") +AZURE_CLIENT_ID = os.environ.get("AZURE_CLIENT_ID") +AZURE_CLIENT_SECRET = os.environ.get("AZURE_CLIENT_SECRET") +RANCHER_AKS_K8S_VERSION = os.environ.get("RANCHER_AKS_K8S_VERSION", "1.21.2") +RANCHER_AKS_DNS_PREFIX = os.environ.get("RANCHER_AKS_DNS_PREFIX") +RANCHER_AKS_RESOURCE_GROUP = os.environ.get("RANCHER_AKS_RESOURCE_GROUP") +RANCHER_AKS_RESOURCE_LOCATION = os.environ.get("RANCHER_AKS_RESOURCE_LOCATION") +aks_credentials = pytest.mark.skipif(not (AZURE_SUBSCRIPTION_ID and AZURE_CLIENT_ID and AZURE_CLIENT_SECRET), + reason='Azure credentials not provided, ' + 'cannot create cluster') +aks_resources = pytest.mark.skipif(not (RANCHER_AKS_DNS_PREFIX and RANCHER_AKS_RESOURCE_GROUP and RANCHER_AKS_RESOURCE_LOCATION), + reason='AKS resources not provided, ' + 'cannot create cluster') +DEFAULT_TIMEOUT_AKS = 600 +cluster_details = {} + +aks_config = { + "imported": False, + "dnsPrefix": RANCHER_AKS_DNS_PREFIX, + "kubernetesVersion": RANCHER_AKS_K8S_VERSION, + "linuxAdminUsername": "azureuser", + "loadBalancerSku": "Standard", + "networkPlugin": "kubenet", + "privateCluster": False, + "resourceGroup": RANCHER_AKS_RESOURCE_GROUP, + "resourceLocation": RANCHER_AKS_RESOURCE_LOCATION, + "tags": {}, + "type": "aksclusterconfigspec", + "nodePools": [ + { + "availabilityZones": ["1", "2", "3"], + "count": 3, + "enableAutoScaling": False, + "maxPods": 110, + "mode": "System", + "name": "agentpool", + "orchestratorVersion": RANCHER_AKS_K8S_VERSION, + "osDiskSizeGB": 128, + "osDiskType": "Managed", + "osType": "Linux", + "type": "aksnodepool", + "vmSize": "Standard_DS2_v2", + "isNew": True + } + ] +} + + +@aks_credentials +@aks_resources +def test_aks_v2_hosted_cluster_create_basic(): + """ + Create a hosted AKS v2 cluster with basic UI parameters + """ + client = get_user_client() + cluster_name = random_test_name("test-auto-aks") + aks_config_temp = get_aks_config(cluster_name) + cluster_config = { + "aksConfig": aks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + cluster = create_and_validate_aks_cluster(cluster_config) + hosted_cluster_cleanup(client, cluster, cluster_name) + + +def get_aks_config(cluster_name): + """ + Adding required params for a basic AKS v2 cluster + :param cluster_name: + :return: aks_config_temp + """ + azure_cloud_credential = get_azure_cloud_credential() + global aks_config + aks_config_temp = aks_config.copy() + aks_config_temp["clusterName"] = cluster_name + aks_config_temp["azureCredentialSecret"] = azure_cloud_credential.id + return aks_config_temp + + +def get_azure_cloud_credential(): + """ + Create an Azure cloud credentials + :return: azure_cloud_credential + """ + client = get_user_client() + azure_cloud_credential_config = { + "subscriptionId": AZURE_SUBSCRIPTION_ID, + "clientId": AZURE_CLIENT_ID, + "clientSecret": AZURE_CLIENT_SECRET + } + azure_cloud_credential = client.create_cloud_credential( + azurecredentialConfig=azure_cloud_credential_config + ) + return azure_cloud_credential + + +def create_and_validate_aks_cluster(cluster_config, imported=False): + """ + Create and validate an AKS cluster + :param cluster_config: config of the cluster + :param imported: imported is true when user creates an imported cluster + :return: client, cluster + """ + client = get_user_client() + print("Creating AKS cluster") + print("\nAKS Configuration: {}".format(cluster_config)) + cluster = client.create_cluster(cluster_config) + print(cluster) + cluster_details[cluster["name"]] = cluster + intermediate_state = False if imported else True + cluster = validate_cluster(client, cluster, + check_intermediate_state=intermediate_state, + skipIngresscheck=True, + timeout=DEFAULT_TIMEOUT_AKS) + return client, cluster \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_app.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_app.py new file mode 100644 index 0000000..1fa9293 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_app.py @@ -0,0 +1,824 @@ +from .common import * # NOQA +import pytest +from .test_rbac import create_user +from .test_rke_cluster_provisioning import create_and_validate_custom_host + +project_detail = {"cluster1": {"project1": None, "namespace1": None, + "project2": None, "namespace2": None, + "cluster": None}, + "cluster2": {"project1": None, "namespace1": None, + "cluster": None}} +user_token = {"user_c1_p1_owner": {"user": None, "token": None}, + "user_c1_p1_member": {"user": None, "token": None}, + "user_c1_p2_owner": {"user": None, "token": None}, + "user_c2_p1_owner": {"user": None, "token": None}, + "user_c1_owner": {"user": None, "token": None}, + "user_c1_member": {"user": None, "token": None}, + "user_c2_owner": {"user": None, "token": None}, + "user_standard": {"user": None, "token": None}} +CATALOG_NAME = random_test_name("test-catalog") +PROJECT_CATALOG = random_test_name("test-pj") +CLUSTER_CATALOG = random_test_name("test-cl") +CATALOG_URL = "https://github.com/rancher/integration-test-charts.git" +BRANCH = "validation-tests" +MYSQL_EXTERNALID_131 = create_catalog_external_id(CATALOG_NAME, + "mysql", "1.3.1") +MYSQL_EXTERNALID_132 = create_catalog_external_id(CATALOG_NAME, + "mysql", + "1.3.2") +WORDPRESS_EXTID = create_catalog_external_id(CATALOG_NAME, + "wordpress", + "7.3.8") + + +def cluster_and_client(cluster_id, mgmt_client): + cluster = mgmt_client.by_id_cluster(cluster_id) + url = cluster.links.self + '/schemas' + client = rancher.Client(url=url, + verify=False, + token=mgmt_client.token) + return cluster, client + + +def wait_for_template_to_be_created(client, name, timeout=45): + found = False + start = time.time() + interval = 0.5 + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for templates") + templates = client.list_template(catalogId=name) + if len(templates) > 0: + found = True + time.sleep(interval) + interval *= 2 + + +def check_condition(condition_type, status): + def _find_condition(resource): + if not hasattr(resource, "conditions"): + return False + + if resource.conditions is None: + return False + + for condition in resource.conditions: + if condition.type == condition_type and condition.status == status: + return True + return False + + return _find_condition + + +@if_test_rbac +def test_tiller(): + name = random_test_name() + admin_client = get_user_client() + + clusters = admin_client.list_cluster(name=CLUSTER_NAME).data + assert len(clusters) > 0 + cluster_id = clusters[0].id + + p = admin_client. \ + create_project(name="test-" + random_str(), + clusterId=cluster_id, + resourceQuota={ + "limit": { + "secrets": "1"}}, + namespaceDefaultResourceQuota={ + "limit": { + "secrets": "1"}} + ) + + p = admin_client.reload(p) + proj_client = rancher.Client(url=p.links.self + + '/schemas', verify=False, + token=USER_TOKEN) + # need a cluster scoped client to create a namespace + _cluster, cluster_client = cluster_and_client(cluster_id, admin_client) + ns = cluster_client.create_namespace(name=random_str(), + projectId=p.id, + resourceQuota={ + "limit": { + "secrets": "1" + }} + ) + wait_for_template_to_be_created(admin_client, "library") + app = proj_client.create_app( + name=name, + externalId=WORDPRESS_EXTID, + targetNamespace=ns.name, + projectId=p.id, + answers=get_defaut_question_answers(admin_client, WORDPRESS_EXTID) + ) + + app = proj_client.reload(app) + # test for tiller to be stuck on bad installs + wait_for_condition(proj_client, app, check_condition('Installed', 'False')) + # cleanup by deleting project + admin_client.delete(p) + + +@if_test_rbac +def test_app_deploy(): + admin_client = get_user_client() + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_131) + wait_for_template_to_be_created(admin_client, "library") + app = proj_client.create_app( + name=random_test_name(), + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answer) + print("App is active") + validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + proj_client.delete(app) + + +@if_test_rbac +def test_app_delete(): + admin_client = get_user_client() + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + wait_for_template_to_be_created(admin_client, "library") + answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_131) + app = proj_client.create_app( + name=random_test_name(), + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answer) + print("App is active") + validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + app = proj_client.delete(app) + validate_app_deletion(proj_client, app.id) + + +@if_test_rbac +def test_app_upgrade_version(): + admin_client = get_user_client() + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + wait_for_template_to_be_created(admin_client, "library") + answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_131) + app = proj_client.create_app( + name=random_test_name(), + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answer) + print("App is active") + validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + new_answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_132) + app = proj_client.update( + obj=app, + externalId=MYSQL_EXTERNALID_132, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=new_answer) + app = proj_client.reload(app) + validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_132) + assert app.externalId == MYSQL_EXTERNALID_132, "incorrect template version" + proj_client.delete(app) + + +@if_test_rbac +def test_app_rollback(): + admin_client = get_user_client() + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + wait_for_template_to_be_created(admin_client, "library") + answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_131) + app = proj_client.create_app( + name=random_test_name(), + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answer) + print("App is active") + app = validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + rev_id = app.appRevisionId + new_answer = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_132) + app = proj_client.update( + obj=app, + externalId=MYSQL_EXTERNALID_132, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=new_answer) + app = proj_client.reload(app) + app = validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_132) + assert app.externalId == MYSQL_EXTERNALID_132, "incorrect template version" + proj_client.action(obj=app, + action_name='rollback', + revisionId=rev_id) + app = proj_client.reload(app) + validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + assert app.externalId == MYSQL_EXTERNALID_131, "incorrect template version" + proj_client.delete(app) + + +@if_test_rbac +def test_app_answer_override(): + admin_client = get_user_client() + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + wait_for_template_to_be_created(admin_client, "library") + answers = get_defaut_question_answers( + admin_client, + MYSQL_EXTERNALID_131) + app = proj_client.create_app( + name=random_test_name(), + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answers) + print("App is active") + app = validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + answers["mysqlUser"] = "admin1234" + app = proj_client.update( + obj=app, + externalId=MYSQL_EXTERNALID_131, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id, + answers=answers) + app = proj_client.reload(app) + app = validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131, answers) + assert app["answers"].mysqlUser == "admin1234", \ + "incorrect answer upgrade" + proj_client.delete(app) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_1(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c1_p1_owner CAN list the added catalog + validate_user_list_catalog("user_c1_p1_owner", clustercatalog=False) + # deploy an app + proj_client_user = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_p1_owner"]["token"]) + validate_catalog_app_deploy(proj_client_user, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + project_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_2(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c1_p1_member CAN list the added catalog + validate_user_list_catalog("user_c1_p1_member", clustercatalog=False) + + proj_client_user2 = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_p1_member"]["token"]) + validate_catalog_app_deploy(proj_client_user2, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + project_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_3(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c1_p2_owner CANNOT list the added catalog + validate_user_list_catalog("user_c1_p2_owner", False, False) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_4(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_standard CANNOT list the added catalog + validate_user_list_catalog("user_standard", False, False) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_5(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c2_p1_owner CANNOT list the added catalog + validate_user_list_catalog("user_c2_p1_owner", False, False) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_6(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c1_owner CAN list the added catalog + validate_user_list_catalog("user_c1_owner", clustercatalog=False) + proj_client_user3 = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_owner"]["token"]) + validate_catalog_app_deploy(proj_client_user3, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + project_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_project_catalog_list_7(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c1_member CANNOT list the added catalog + validate_user_list_catalog("user_c1_member", False, False) + + + +@if_test_rbac +def test_rbac_app_project_catalog_list_8(): + catalog, project_catalog_external_id = create_project_catalog() + # Verify user_c2_owner CANNOT list the added catalog + validate_user_list_catalog("user_c2_owner", False, False) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_1(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p1_owner CAN list the catalog + validate_user_list_catalog("user_c1_p1_owner") + + proj_client_user = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_p1_owner"]["token"]) + validate_catalog_app_deploy(proj_client_user, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + cluster_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_2(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p1_member CAN list the catalog + validate_user_list_catalog("user_c1_p1_member") + proj_client_user = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_p1_member"]["token"]) + validate_catalog_app_deploy(proj_client_user, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + cluster_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_3(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p2_owner CAN list the catalog + validate_user_list_catalog("user_c1_p2_owner") + proj_client_user = get_project_client_for_token( + project_detail["cluster1"]["project2"], + user_token["user_c1_p2_owner"]["token"]) + validate_catalog_app_deploy(proj_client_user, + project_detail["cluster1"]["namespace2"].name, + project_detail["cluster1"]["project2"].id, + cluster_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_4(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c2_p1_owner CANNOT list the catalog + validate_user_list_catalog("user_c2_p1_owner", False) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_5(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_standard CANNOT list the catalog + validate_user_list_catalog("user_standard", False) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_6(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # user_c1_owner CAN list the catalog + validate_user_list_catalog("user_c1_owner") + proj_client_user = get_project_client_for_token( + project_detail["cluster1"]["project1"], + user_token["user_c1_owner"]["token"]) + validate_catalog_app_deploy(proj_client_user, + project_detail["cluster1"]["namespace1"].name, + project_detail["cluster1"]["project1"].id, + cluster_catalog_external_id) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_7(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # user_c1_member CAN list the catalog + validate_user_list_catalog("user_c1_member") + p3, n3 = create_project_and_ns( + user_token["user_c1_member"]["token"], + project_detail["cluster1"]["cluster"], + random_test_name("testapp")) + proj_client_user = get_project_client_for_token( + p3, user_token["user_c1_member"]["token"]) + validate_catalog_app_deploy(proj_client_user, + n3.name, + p3.id, + cluster_catalog_external_id) + user_client = get_user_client() + user_client.delete(p3) + + +@if_test_rbac +def test_rbac_app_cluster_catalog_list_8(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # user_c2_owner CANNOT list the catalog + validate_user_list_catalog("user_c2_owner", False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_1(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_p1_owner CAN delete the added catalog + validate_catalog_deletion(catalog, "user_c1_p1_owner", True, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_2(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_p1_member CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c1_p1_member", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_3(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_p1_member CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c1_p1_member", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_4(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_p2_owner CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c1_p2_owner", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_5(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c2_p1_owner CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c2_p1_owner", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_6(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_owner CAN delete the added catalog + validate_catalog_deletion(catalog, "user_c1_owner", True, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_7(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c1_member CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c1_member", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_8(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_c2_owner CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_c2_owner", False, False) + + +@if_test_rbac +def test_rbac_app_project_scope_delete_9(): + catalog, cluster_catalog_external_id = create_project_catalog() + # Verify user_standard CANNOT delete the added catalog + validate_catalog_deletion(catalog, "user_standard", False, False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_1(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p1_owner CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c1_p1_owner", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_2(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p1_member CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c1_p1_member", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_3(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_p2_owner CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c1_p2_owner", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_4(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c2_p1_owner CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c2_p1_owner", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_5(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_owner CAN delete the catalog + validate_catalog_deletion(catalog, "user_c1_owner", True) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_6(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c1_member CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c1_member", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_7(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_c2_owner CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_c2_owner", False) + + +@if_test_rbac +def test_rbac_app_cluster_scope_delete_8(): + catalog, cluster_catalog_external_id = create_cluster_catalog() + # verify user_standard CANNOT delete the catalog + validate_catalog_deletion(catalog, "user_standard", False) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + user_token["user_c1_p1_owner"]["user"] = \ + rbac_data["users"][PROJECT_OWNER]["user"] + user_token["user_c1_p1_owner"]["token"] = \ + rbac_data["users"][PROJECT_OWNER]["token"] + user_token["user_c1_p1_member"]["user"] = \ + rbac_data["users"][PROJECT_MEMBER]["user"] + user_token["user_c1_p1_member"]["token"] = \ + rbac_data["users"][PROJECT_MEMBER]["token"] + user_token["user_c1_owner"]["user"] = \ + rbac_data["users"][CLUSTER_OWNER]["user"] + user_token["user_c1_owner"]["token"] = \ + rbac_data["users"][CLUSTER_OWNER]["token"] + user_token["user_c1_member"]["user"] = \ + rbac_data["users"][CLUSTER_MEMBER]["user"] + user_token["user_c1_member"]["token"] = \ + rbac_data["users"][CLUSTER_MEMBER]["token"] + # create a cluster + node_roles = [["controlplane", "etcd", "worker"], + ["worker"], ["worker"]] + cluster_list = [] + cluster, aws_nodes = create_and_validate_custom_host(node_roles, True) + client, cluster_existing = get_user_client_and_cluster() + admin_client = get_admin_client() + cluster_list.append(cluster_existing) + cluster_list.append(cluster) + assert len(cluster_list) > 1 + + project_detail["cluster1"]["project2"], \ + project_detail["cluster1"]["namespace2"] = \ + create_project_and_ns(USER_TOKEN, + cluster_list[0], + random_test_name("testapp")) + project_detail["cluster2"]["project1"], \ + project_detail["cluster2"]["namespace1"] = \ + create_project_and_ns(USER_TOKEN, + cluster_list[1], + random_test_name("testapp")) + project_detail["cluster1"]["cluster"] = cluster_list[0] + project_detail["cluster2"]["cluster"] = cluster_list[1] + + catalog = admin_client.create_catalog( + name=CATALOG_NAME, + baseType="catalog", + branch=BRANCH, + kind="helm", + url=CATALOG_URL) + time.sleep(5) + + user_c_client = get_cluster_client_for_token(cluster_list[0], USER_TOKEN) + project_detail["cluster1"]["project1"] = rbac_data["project"] + project_detail["cluster1"]["namespace1"] = \ + create_ns(user_c_client, cluster_list[0], rbac_data["project"]) + + # create users + user_token["user_c1_p2_owner"]["user"], \ + user_token["user_c1_p2_owner"]["token"] = create_user(admin_client) + user_token["user_c2_p1_owner"]["user"], \ + user_token["user_c2_p1_owner"]["token"] = create_user(admin_client) + user_token["user_c2_owner"]["user"], \ + user_token["user_c2_owner"]["token"] = create_user(admin_client) + user_token["user_standard"]["user"], \ + user_token["user_standard"]["token"] = create_user(admin_client) + + # Assign roles to the users + assign_members_to_project(admin_client, + user_token["user_c1_p2_owner"]["user"], + project_detail["cluster1"]["project2"], + "project-owner") + assign_members_to_project(admin_client, + user_token["user_c2_p1_owner"]["user"], + project_detail["cluster2"]["project1"], + "project-owner") + assign_members_to_cluster(admin_client, + user_token["user_c2_owner"]["user"], + project_detail["cluster2"]["cluster"], + "cluster-owner") + + def fin(): + admin_client.delete(project_detail["cluster1"]["project2"]) + admin_client.delete(project_detail["cluster2"]["project1"]) + admin_client.delete(catalog) + admin_client.delete(user_token["user_c1_p2_owner"]["user"]) + admin_client.delete(user_token["user_c2_p1_owner"]["user"]) + admin_client.delete(user_token["user_c2_owner"]["user"]) + admin_client.delete(user_token["user_standard"]["user"]) + admin_client.delete(cluster) + if aws_nodes is not None: + delete_node(aws_nodes) + + request.addfinalizer(fin) + + +def validate_user_list_catalog(user, listcatalog=True, clustercatalog=True): + user_client = get_client_for_token( + user_token[user]["token"]) + if clustercatalog: + catalogs_list = user_client.list_clusterCatalog(name=CLUSTER_CATALOG) + catalogName = CLUSTER_CATALOG + else: + catalogs_list = user_client.list_projectCatalog(name=PROJECT_CATALOG) + catalogName = PROJECT_CATALOG + + if listcatalog: + print("Length of catalog list:", len(catalogs_list)) + assert len(catalogs_list) == 1, \ + "Catalog not found for the user" + assert catalogs_list["data"][0]["name"] == catalogName, \ + "Incorrect catalog found" + else: + assert len(catalogs_list) == 0, \ + "Catalog found for the user" + + +def validate_catalog_app_deploy(proj_client_user, namespace, + projectid, catalog_ext_id): + try: + app = proj_client_user.create_app(name=random_test_name(), + externalId=catalog_ext_id, + answers=get_defaut_question_answers( + get_user_client(), + catalog_ext_id), + targetNamespace=namespace, + projectId=projectid) + pass + except: + assert False, "User is not able to deploy app from catalog" + validate_catalog_app(proj_client_user, app, catalog_ext_id) + proj_client_user.delete(app) + + +def validate_catalog_deletion(catalog, + user, candelete=True, clustercatalog=True): + user_client = get_client_for_token(user_token[user]["token"]) + catalog_name = catalog.name + if not candelete: + with pytest.raises(ApiError) as e: + user_client.delete(catalog) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + user_client.delete(catalog) + if clustercatalog: + catalogs_list = user_client.list_clusterCatalog(name=catalog_name) + else: + catalogs_list = user_client.list_projectCatalog(name=catalog_name) + assert len(catalogs_list) == 0, \ + "Catalog has not been deleted for the user" + + +def create_project_catalog(): + """create a catalog by user1 at the project level + and allow other users to access it""" + added_catalog = None + catalog_external_id = None + user_client = get_user_client() + catalogs_list = user_client.list_projectCatalog(name=PROJECT_CATALOG) + pId = project_detail["cluster1"]["project1"].id.split(":")[1] + if len(catalogs_list["data"]) != 0: + catalog_proj_scoped_ext_id = \ + create_catalog_external_id(catalogs_list["data"][0]["name"], + "mysql", + "1.3.2", + pId, + "project") + added_catalog = catalogs_list["data"][0] + catalog_external_id = catalog_proj_scoped_ext_id + else: + catalog = user_client.create_projectCatalog( + name=PROJECT_CATALOG, + baseType="projectCatalog", + branch=BRANCH, + url=CATALOG_URL, + projectId=project_detail["cluster1"]["project1"].id) + time.sleep(10) + assert catalog.state == "active", "Catalog is not in Active state." + + catalog_proj_scoped_ext_id = \ + create_catalog_external_id(catalog.name, + "mysql", + "1.3.2", + pId, + "project") + print(catalog_proj_scoped_ext_id) + answers = get_defaut_question_answers( + user_client, + catalog_proj_scoped_ext_id) + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + app = proj_client.create_app( + name=random_test_name(), + externalId=catalog_proj_scoped_ext_id, + answers=answers, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id) + validate_catalog_app(proj_client, app, catalog_proj_scoped_ext_id) + proj_client.delete(app) + added_catalog = catalog + catalog_external_id = catalog_proj_scoped_ext_id + + return added_catalog, catalog_external_id + + +def create_cluster_catalog(): + """create a catalog by user1 at the cluster level + and allow other users to access it""" + added_catalog = None + catalog_external_id = None + user_client = get_user_client() + catalogs_list = user_client.list_clusterCatalog(name=CLUSTER_CATALOG) + pId = project_detail["cluster1"]["cluster"].id + # catalog = catalogs_list[0] + if len(catalogs_list["data"]) != 0: + catalog_cluster_scoped_ext_id = \ + create_catalog_external_id(catalogs_list["data"][0]["name"], + "mysql", + "1.3.2", + pId, + "cluster") + added_catalog = catalogs_list["data"][0] + catalog_external_id = catalog_cluster_scoped_ext_id + else: + proj_client = get_project_client_for_token( + project_detail["cluster1"]["project1"], + USER_TOKEN) + print(project_detail["cluster1"]["cluster"].id) + print(project_detail["cluster1"]["cluster"]) + catalog = user_client.create_clusterCatalog( + name=CLUSTER_CATALOG, + baseType="clustercatalog", + branch=BRANCH, + url=CATALOG_URL, + clusterId=project_detail["cluster1"]["cluster"].id) + time.sleep(10) + assert catalog.state == "active", "Catalog is not in Active state." + catalog_cluster_scoped_ext_id = \ + create_catalog_external_id(catalog.name, + "mysql", + "1.3.2", + pId, + "cluster") + answers = get_defaut_question_answers( + user_client, + catalog_cluster_scoped_ext_id) + app = proj_client.create_app( + name=random_test_name(), + externalId=catalog_cluster_scoped_ext_id, + answers=answers, + targetNamespace=project_detail["cluster1"]["namespace1"].name, + projectId=project_detail["cluster1"]["project1"].id) + validate_catalog_app(proj_client, app, catalog_cluster_scoped_ext_id) + proj_client.delete(app) + added_catalog = catalog + catalog_external_id = catalog_cluster_scoped_ext_id + + return added_catalog, catalog_external_id diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_auth.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_auth.py new file mode 100644 index 0000000..d466623 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_auth.py @@ -0,0 +1,841 @@ +import json +import os +import pytest +import requests + +from .common import ADMIN_TOKEN +from .common import AUTH_PROVIDER +from .common import AUTH_USER_PASSWORD +from .common import CATTLE_TEST_URL +from .common import cluster_cleanup +from .common import create_project_and_ns +from .common import get_admin_client +from .common import get_client_for_token +from .test_rke_cluster_provisioning import create_and_validate_custom_host + +''' +Prerequisite: +1. testautoadmin as your admin user, if the fixture detects the auth + is disabled it will be enabled automatically. +2. Two clusters in your setup, if none or one are detected by the fixture + will create clusters to match two +''' + + +# Config Fields +HOSTNAME_OR_IP_ADDRESS = os.environ.get("RANCHER_HOSTNAME_OR_IP_ADDRESS") +PORT = os.environ.get("RANCHER_PORT", "") +CA_CERTIFICATE = os.environ.get("RANCHER_CA_CERTIFICATE", "") +OPENLDAP_CA_CERTIFICATE = os.environ.get("RANCHER_OPENLDAP_CA_CERTIFICATE", "") +FREEIPA_CA_CERTIFICATE = os.environ.get("RANCHER_FREEIPA_CA_CERTIFICATE", "") +CONNECTION_TIMEOUT = os.environ.get("RANCHER_CONNECTION_TIMEOUT", 5000) +SERVICE_ACCOUNT_NAME = os.environ.get("RANCHER_SERVICE_ACCOUNT_NAME") +SERVICE_ACCOUNT_PASSWORD = os.environ.get("RANCHER_SERVICE_ACCOUNT_PASSWORD") +DEFAULT_LOGIN_DOMAIN = os.environ.get("RANCHER_DEFAULT_LOGIN_DOMAIN") +USER_SEARCH_BASE = os.environ.get("RANCHER_USER_SEARCH_BASE") +GROUP_SEARCH_BASE = os.environ.get("RANCHER_GROUP_SEARCH_BASE") +AD_SPECIAL_CHAR_PASSWORD = os.environ.get("RANCHER_AD_SPECIAL_CHAR_PASSWORD") +OPENLDAP_SPECIAL_CHAR_PASSWORD = \ + os.environ.get("RANCHER_OPENLDAP_SPECIAL_CHAR_PASSWORD") +FREEIPA_SPECIAL_CHAR_PASSWORD = \ + os.environ.get("RANCHER_FREEIPA_SPECIAL_CHAR_PASSWORD") +OPENLDAP_HOSTNAME_OR_IP_ADDRESS = \ + os.environ.get("RANCHER_OPENLDAP_HOSTNAME_OR_IP_ADDRESS") +OPENLDAP_SERVICE_ACCOUNT_NAME = \ + os.environ.get("RANCHER_OPENLDAP_SERVICE_ACCOUNT_NAME") +OPENLDAP_SERVICE_ACCOUNT_PASSWORD = \ + os.environ.get("RANCHER_OPENLDAP_SERVICE_ACCOUNT_PASSWORD") +OPENLDAP_USER_SEARCH_BASE = os.environ.get("RANCHER_OPENLDAP_USER_SEARCH_BASE") +OPENLDAP_AUTH_USER_PASSWORD = \ + os.environ.get("RANCHER_OPENLDAP_AUTH_USER_PASSWORD") + +FREEIPA_HOSTNAME_OR_IP_ADDRESS = \ + os.environ.get("RANCHER_FREEIPA_HOSTNAME_OR_IP_ADDRESS") +FREEIPA_SERVICE_ACCOUNT_NAME = \ + os.environ.get("RANCHER_FREEIPA_SERVICE_ACCOUNT_NAME") +FREEIPA_SERVICE_ACCOUNT_PASSWORD = \ + os.environ.get("RANCHER_FREEIPA_SERVICE_ACCOUNT_PASSWORD") +FREEIPA_USER_SEARCH_BASE = os.environ.get("RANCHER_FREEIPA_USER_SEARCH_BASE") +FREEIPA_GROUP_SEARCH_BASE = os.environ.get("RANCHER_FREEIPA_GROUP_SEARCH_BASE") + +FREEIPA_AUTH_USER_PASSWORD = \ + os.environ.get("RANCHER_FREEIPA_AUTH_USER_PASSWORD") + +PASSWORD = "" + +if AUTH_PROVIDER == "activeDirectory": + PASSWORD = AUTH_USER_PASSWORD +elif AUTH_PROVIDER == "openLdap": + PASSWORD = OPENLDAP_AUTH_USER_PASSWORD +elif AUTH_PROVIDER == "freeIpa": + PASSWORD = FREEIPA_AUTH_USER_PASSWORD + +CATTLE_AUTH_URL = \ + CATTLE_TEST_URL + \ + "/v3-public/" + AUTH_PROVIDER + "Providers/" + \ + AUTH_PROVIDER.lower() + "?action=login" + +CATTLE_AUTH_PROVIDER_URL = \ + CATTLE_TEST_URL + "/v3/" + AUTH_PROVIDER + "Configs/" +\ + AUTH_PROVIDER.lower() + +CATTLE_AUTH_PRINCIPAL_URL = CATTLE_TEST_URL + "/v3/principals?action=search" + +CATTLE_AUTH_ENABLE_URL = CATTLE_AUTH_PROVIDER_URL + "?action=testAndApply" + +CATTLE_AUTH_DISABLE_URL = CATTLE_AUTH_PROVIDER_URL + "?action=disable" + +setup = {"cluster1": None, + "project1": None, + "ns1": None, + "cluster2": None, + "project2": None, + "ns2": None, + "auth_setup_data": {}, + "permission_denied_code": 403} + +auth_setup_fname = \ + os.path.join(os.path.dirname(os.path.realpath(__file__)) + "/resource", + AUTH_PROVIDER.lower() + ".json") + + +def test_access_control_required_set_access_mode_required(): + access_mode = "required" + validate_access_control_set_access_mode(access_mode) + + +def test_access_control_restricted_set_access_mode_required(): + access_mode = "restricted" + validate_access_control_set_access_mode(access_mode) + + +def test_access_control_required_add_users_and_groups_to_cluster(): + access_mode = "required" + validate_add_users_and_groups_to_cluster_or_project( + access_mode, add_users_to_cluster=True) + + +def test_access_control_restricted_add_users_and_groups_to_cluster(): + access_mode = "restricted" + validate_add_users_and_groups_to_cluster_or_project( + access_mode, add_users_to_cluster=True) + + +def test_access_control_required_add_users_and_groups_to_project(): + access_mode = "required" + validate_add_users_and_groups_to_cluster_or_project( + access_mode, add_users_to_cluster=False) + + +def test_access_control_restricted_add_users_and_groups_to_project(): + access_mode = "restricted" + validate_add_users_and_groups_to_cluster_or_project( + access_mode, add_users_to_cluster=False) + + +def test_disable_and_enable_auth_set_access_control_required(): + access_mode = "required" + validate_access_control_disable_and_enable_auth(access_mode) + + +def test_disable_and_enable_auth_set_access_control_restricted(): + access_mode = "restricted" + validate_access_control_disable_and_enable_auth(access_mode) + + +# By default nestedgroup is disabled for ad and openldap, enabled for freeipa +def test_disable_and_enable_nestedgroups_set_access_control_required(): + access_mode = "required" + validate_access_control_disable_and_enable_nestedgroups(access_mode) + + +def test_disable_and_enable_nestedgroup_set_access_control_restricted(): + access_mode = "restricted" + validate_access_control_disable_and_enable_nestedgroups(access_mode) + + +def test_ad_service_account_login(): + delete_project_users() + delete_cluster_users() + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + # admin_user here is the AD admin user + if AUTH_PROVIDER == "activeDirectory": + admin_token = login(admin_user, AUTH_USER_PASSWORD) + disable_ad(admin_user, admin_token) + enable_ad(admin_user, admin_token) + login(SERVICE_ACCOUNT_NAME, SERVICE_ACCOUNT_PASSWORD) + + +def test_special_character_users_login_access_mode_required(): + access_mode = "required" + special_character_users_login(access_mode) + + +def test_special_character_users_login_access_mode_restricted(): + access_mode = "restricted" + special_character_users_login(access_mode) + + +def special_character_users_login(access_mode): + delete_project_users() + delete_cluster_users() + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + admin_token = login(admin_user, PASSWORD) + allowed_principal_ids = [] + if AUTH_PROVIDER == "activeDirectory": + disable_ad(admin_user, admin_token) + enable_ad(admin_user, admin_token) + if AUTH_PROVIDER == "openLdap": + disable_openldap(admin_user, admin_token) + enable_openldap(admin_user, admin_token) + if AUTH_PROVIDER == "freeIpa": + disable_freeipa(admin_user, admin_token) + enable_freeipa(admin_user, admin_token) + + if AUTH_PROVIDER == "activeDirectory": + for user in auth_setup_data["specialchar_in_username"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for user in auth_setup_data["specialchar_in_password"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for user in auth_setup_data["specialchar_in_userdn"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for group in auth_setup_data["specialchar_in_groupname"]: + allowed_principal_ids.append(principal_lookup(group, admin_token)) + + allowed_principal_ids.append( + principal_lookup(admin_user, admin_token)) + add_users_to_site_access( + admin_token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["specialchar_in_username"]: + login(user, PASSWORD) + for user in auth_setup_data["specialchar_in_password"]: + login(user, AD_SPECIAL_CHAR_PASSWORD) + for user in auth_setup_data["specialchar_in_userdn"]: + login(user, PASSWORD) + for group in auth_setup_data["specialchar_in_groupname"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + if AUTH_PROVIDER == "openLdap": + for user in auth_setup_data["specialchar_in_user_cn_sn"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for user in auth_setup_data["specialchar_in_uid"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for user in auth_setup_data["specialchar_in_password"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for group in auth_setup_data["specialchar_in_groupname"]: + allowed_principal_ids.append(principal_lookup(group, admin_token)) + + allowed_principal_ids.append(principal_lookup(admin_user, admin_token)) + add_users_to_site_access( + admin_token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["specialchar_in_user_cn_sn"]: + login(user, PASSWORD) + for user in auth_setup_data["specialchar_in_uid"]: + login(user, PASSWORD) + for user in auth_setup_data["specialchar_in_password"]: + login(user, OPENLDAP_SPECIAL_CHAR_PASSWORD) + for group in auth_setup_data["specialchar_in_groupname"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + if AUTH_PROVIDER == "freeIpa": + for user in auth_setup_data["specialchar_in_users"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for user in auth_setup_data["specialchar_in_password"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + for group in auth_setup_data["specialchar_in_groupname"]: + allowed_principal_ids.append(principal_lookup(group, admin_token)) + + allowed_principal_ids.append( + principal_lookup(admin_user, admin_token)) + add_users_to_site_access( + admin_token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["specialchar_in_users"]: + login(user, PASSWORD) + for user in auth_setup_data["specialchar_in_password"]: + login(user, FREEIPA_SPECIAL_CHAR_PASSWORD) + for group in auth_setup_data["specialchar_in_groupname"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + +def validate_access_control_set_access_mode(access_mode): + + delete_cluster_users() + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + token = login(admin_user, PASSWORD) + allowed_principal_ids = [] + for user in auth_setup_data["allowed_users"]: + allowed_principal_ids.append(principal_lookup(user, token)) + for group in auth_setup_data["allowed_groups"]: + allowed_principal_ids.append(principal_lookup(group, token)) + allowed_principal_ids.append(principal_lookup(admin_user, token)) + + # Add users and groups in allowed list to access rancher-server + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["allowed_users"]: + login(user, PASSWORD) + + for group in auth_setup_data["allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + for user in auth_setup_data["dis_allowed_users"]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + for group in auth_setup_data["dis_allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + # Add users and groups from dis allowed list to access rancher-server + + for user in auth_setup_data["dis_allowed_users"]: + allowed_principal_ids.append(principal_lookup(user, token)) + + for group in auth_setup_data["dis_allowed_groups"]: + for user in auth_setup_data[group]: + allowed_principal_ids.append(principal_lookup(user, token)) + + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["allowed_users"]: + login(user, PASSWORD) + + for group in auth_setup_data["allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + for user in auth_setup_data["dis_allowed_users"]: + login(user, PASSWORD) + + for group in auth_setup_data["dis_allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + # Remove users and groups from allowed list to access rancher-server + allowed_principal_ids = [principal_lookup(admin_user, token)] + + for user in auth_setup_data["dis_allowed_users"]: + allowed_principal_ids.append(principal_lookup(user, token)) + for group in auth_setup_data["dis_allowed_groups"]: + for user in auth_setup_data[group]: + allowed_principal_ids.append(principal_lookup(user, token)) + + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["allowed_users"]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + for group in auth_setup_data["allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + for user in auth_setup_data["dis_allowed_users"]: + login(user, PASSWORD) + + for group in auth_setup_data["dis_allowed_groups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + +def validate_add_users_and_groups_to_cluster_or_project( + access_mode, add_users_to_cluster=True): + delete_cluster_users() + client = get_admin_client() + for project in client.list_project(): + delete_existing_users_in_project(client, project) + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + token = login(admin_user, PASSWORD) + allowed_principal_ids = [principal_lookup(admin_user, token)] + + # Add users and groups in allowed list to access rancher-server + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + if add_users_to_cluster: + groups_to_check = auth_setup_data["groups_added_to_cluster"] + users_to_check = auth_setup_data["users_added_to_cluster"] + else: + groups_to_check = auth_setup_data["groups_added_to_project"] + users_to_check = auth_setup_data["users_added_to_project"] + for group in groups_to_check: + for user in auth_setup_data[group]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + for user in users_to_check: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + client = get_client_for_token(token) + for group in groups_to_check: + if add_users_to_cluster: + assign_user_to_cluster(client, principal_lookup(group, token), + setup["cluster1"], "cluster-owner") + else: + assign_user_to_project(client, principal_lookup(group, token), + setup["project2"], "project-owner") + for user in users_to_check: + if add_users_to_cluster: + assign_user_to_cluster(client, principal_lookup(user, token), + setup["cluster1"], "cluster-owner") + else: + assign_user_to_project(client, principal_lookup(user, token), + setup["project2"], "project-owner") + expected_status = setup["permission_denied_code"] + + if access_mode == "required": + expected_status = setup["permission_denied_code"] + + if access_mode == "restricted": + expected_status = 201 + + for group in groups_to_check: + for user in auth_setup_data[group]: + login(user, PASSWORD, expected_status) + + for user in users_to_check: + login(user, PASSWORD, expected_status) + + +def validate_access_control_disable_and_enable_auth(access_mode): + + delete_cluster_users() + delete_project_users() + auth_setup_data = setup["auth_setup_data"] + + # Login as admin user to disable auth, should be success, then enable it. + admin_user = auth_setup_data["admin_user"] + admin_token = login(admin_user, PASSWORD) + if AUTH_PROVIDER == "activeDirectory": + disable_ad(admin_user, admin_token) + enable_ad(admin_user, admin_token) + if AUTH_PROVIDER == "openLdap": + disable_openldap(admin_user, admin_token) + enable_openldap(admin_user, admin_token) + if AUTH_PROVIDER == "freeIpa": + disable_freeipa(admin_user, admin_token) + enable_freeipa(admin_user, admin_token) + + # Login as users within allowed principal id list, which cannot perform + # disable action. + allowed_principal_ids = [] + for user in auth_setup_data["allowed_users"]: + allowed_principal_ids.append(principal_lookup(user, admin_token)) + allowed_principal_ids.append(principal_lookup(admin_user, admin_token)) + + # Add users in allowed list to access rancher-server + add_users_to_site_access(admin_token, access_mode, allowed_principal_ids) + + for user in auth_setup_data["allowed_users"]: + token = login(user, PASSWORD) + if AUTH_PROVIDER == "activeDirectory": + disable_ad(user, token, + expected_status=setup["permission_denied_code"]) + enable_ad(user, token, + expected_status=setup["permission_denied_code"]) + if AUTH_PROVIDER == "openLdap": + disable_openldap(user, token, + expected_status=setup["permission_denied_code"]) + enable_openldap(user, token, + expected_status=setup["permission_denied_code"]) + if AUTH_PROVIDER == "freeIpa": + disable_freeipa(user, token, + expected_status=setup["permission_denied_code"]) + enable_freeipa(user, token, + expected_status=setup["permission_denied_code"]) + + +def validate_access_control_disable_and_enable_nestedgroups(access_mode): + delete_project_users() + delete_cluster_users() + + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + token = login(admin_user, PASSWORD) + if AUTH_PROVIDER == "activeDirectory": + enable_ad(admin_user, token) + if AUTH_PROVIDER == "openLdap": + enable_openldap(admin_user, token) + if AUTH_PROVIDER == "freeIpa": + enable_freeipa(admin_user, token) + + allowed_principal_ids = [] + for group in auth_setup_data["allowed_nestedgroups"]: + allowed_principal_ids.append(principal_lookup(group, token)) + + allowed_principal_ids.append(principal_lookup(admin_user, token)) + + # Add users in allowed list to access rancher-server + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + for group in auth_setup_data["allowed_nestedgroups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + if AUTH_PROVIDER == "freeIpa": + for user in auth_setup_data["users_under_nestedgroups"]: + login(user, PASSWORD) + + if AUTH_PROVIDER == "activeDirectory" or AUTH_PROVIDER == "openLdap": + for user in auth_setup_data["users_under_nestedgroups"]: + login(user, PASSWORD, + expected_status=setup["permission_denied_code"]) + + # Enable nestedgroup feature, so users under nestedgroups can login + # successfully + if AUTH_PROVIDER == "activeDirectory": + enable_ad(admin_user, token, nested=True) + if AUTH_PROVIDER == "openLdap": + enable_openldap(admin_user, token, nested=True) + + allowed_principal_ids = [] + for group in auth_setup_data["allowed_nestedgroups"]: + allowed_principal_ids.append(principal_lookup(group, token)) + allowed_principal_ids.append(principal_lookup(admin_user, token)) + + # Add users in allowed list to access rancher-server + add_users_to_site_access(token, access_mode, allowed_principal_ids) + + for group in auth_setup_data["allowed_nestedgroups"]: + for user in auth_setup_data[group]: + login(user, PASSWORD) + + for user in auth_setup_data["users_under_nestedgroups"]: + login(user, PASSWORD) + + +def login(username, password, expected_status=201): + token = "" + r = requests.post(CATTLE_AUTH_URL, json={ + 'username': username, + 'password': password, + 'responseType': 'json', + }, verify=False) + assert r.status_code == expected_status + print("Login request for " + username + " " + str(expected_status)) + if expected_status == 201: + token = r.json()['token'] + return token + + +def get_tls(certificate): + if len(certificate) != 0: + tls = True + else: + tls = False + return tls + + +def enable_openldap(username, token, enable_url=CATTLE_AUTH_ENABLE_URL, + password=PASSWORD, nested=False, + expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + ldap_config = { + "accessMode": "unrestricted", + "connectionTimeout": CONNECTION_TIMEOUT, + "certificate": OPENLDAP_CA_CERTIFICATE, + "groupDNAttribute": "entryDN", + "groupMemberMappingAttribute": "member", + "groupMemberUserAttribute": "entryDN", + "groupNameAttribute": "cn", + "groupObjectClass": "groupOfNames", + "groupSearchAttribute": "cn", + "nestedGroupMembershipEnabled": nested, + "enabled": True, + "port": PORT, + "servers": [OPENLDAP_HOSTNAME_OR_IP_ADDRESS], + "serviceAccountDistinguishedName": OPENLDAP_SERVICE_ACCOUNT_NAME, + "tls": get_tls(OPENLDAP_CA_CERTIFICATE), + "userDisabledBitMask": 0, + "userLoginAttribute": "uid", + "userMemberAttribute": "memberOf", + "userNameAttribute": "cn", + "userObjectClass": "inetOrgPerson", + "userSearchAttribute": "uid|sn|givenName", + "userSearchBase": OPENLDAP_USER_SEARCH_BASE, + "serviceAccountPassword": OPENLDAP_SERVICE_ACCOUNT_PASSWORD + } + ca_cert = ldap_config["certificate"] + ldap_config["certificate"] = ca_cert.replace('\\n', '\n') + + r = requests.post(enable_url, + json={ + "ldapConfig": ldap_config, + "username": username, + "password": password}, + verify=False, headers=headers) + nested_msg = " nested group " if nested else " " + print(f"Enable OpenLDAP{nested_msg}request for {username} " + f"{expected_status}") + assert r.status_code == expected_status + + +def disable_openldap(username, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_DISABLE_URL, json={ + 'username': username, + 'password': PASSWORD + }, verify=False, headers=headers) + assert r.status_code == expected_status + print("Disable openLdap request for " + + username + " " + str(expected_status)) + + +def enable_ad(username, token, enable_url=CATTLE_AUTH_ENABLE_URL, + password=AUTH_USER_PASSWORD, nested=False, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + active_directory_config = { + "accessMode": "unrestricted", + "certificate": CA_CERTIFICATE, + "connectionTimeout": CONNECTION_TIMEOUT, + "defaultLoginDomain": DEFAULT_LOGIN_DOMAIN, + "groupDNAttribute": "distinguishedName", + "groupMemberMappingAttribute": "member", + "groupMemberUserAttribute": "distinguishedName", + "groupNameAttribute": "name", + "groupObjectClass": "group", + "groupSearchAttribute": "sAMAccountName", + "nestedGroupMembershipEnabled": nested, + "port": PORT, + "servers": [HOSTNAME_OR_IP_ADDRESS, HOSTNAME_OR_IP_ADDRESS], + "serviceAccountUsername": SERVICE_ACCOUNT_NAME, + "tls": get_tls(CA_CERTIFICATE), + "userDisabledBitMask": 2, + "userEnabledAttribute": "userAccountControl", + "userLoginAttribute": "sAMAccountName", + "userNameAttribute": "name", + "userObjectClass": "person", + "userSearchAttribute": "sAMAccountName|sn|givenName", + "userSearchBase": USER_SEARCH_BASE, + "serviceAccountPassword": SERVICE_ACCOUNT_PASSWORD + } + + ca_cert = active_directory_config["certificate"] + active_directory_config["certificate"] = ca_cert.replace('\\n', '\n') + + r = requests.post(enable_url, + json={"activeDirectoryConfig": active_directory_config, + "enabled": True, + "username": username, + "password": password}, + verify=False, headers=headers) + nested_msg = " nested group " if nested else " " + print(f"Enable ActiveDirectory{nested_msg}request for {username} " + f"{expected_status}") + assert r.status_code == expected_status + + +def disable_ad(username, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_DISABLE_URL, + json={"enabled": False, + "username": username, + "password": AUTH_USER_PASSWORD + }, + verify=False, headers=headers) + print("Disable ActiveDirectory request for " + + username + " " + str(expected_status)) + assert r.status_code == expected_status + + +def enable_freeipa(username, token, enable_url=CATTLE_AUTH_ENABLE_URL, + password=PASSWORD, nested=False, + expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(enable_url, json={ + "ldapConfig": { + "accessMode": "unrestricted", + "certificate": FREEIPA_CA_CERTIFICATE, + "connectionTimeout": CONNECTION_TIMEOUT, + "groupDNAttribute": "entrydn", + "groupMemberMappingAttribute": "member", + "groupMemberUserAttribute": "entrydn", + "groupNameAttribute": "cn", + "groupObjectClass": "groupofnames", + "groupSearchAttribute": "cn", + "groupSearchBase": FREEIPA_GROUP_SEARCH_BASE, + "enabled": True, + "nestedGroupMembershipEnabled": nested, + "port": PORT, + "servers": [FREEIPA_HOSTNAME_OR_IP_ADDRESS], + "serviceAccountDistinguishedName": FREEIPA_SERVICE_ACCOUNT_NAME, + "tls": get_tls(FREEIPA_CA_CERTIFICATE), + "userDisabledBitMask": 0, + "userLoginAttribute": "uid", + "userMemberAttribute": "memberOf", + "userNameAttribute": "givenName", + "userObjectClass": "inetorgperson", + "userSearchAttribute": "uid|sn|givenName", + "userSearchBase": FREEIPA_USER_SEARCH_BASE, + "serviceAccountPassword": FREEIPA_SERVICE_ACCOUNT_PASSWORD + }, + "username": username, + "password": password + }, verify=False, headers=headers) + + print("Enable freeIpa request for " + + username + " " + str(expected_status)) + assert r.status_code == expected_status + + +def disable_freeipa(username, token, expected_status=200): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_DISABLE_URL, json={ + "enabled": False, + "username": username, + "password": AUTH_USER_PASSWORD + }, verify=False, headers=headers) + assert r.status_code == expected_status + print("Disable freeIpa request for " + + username + " " + str(expected_status)) + + +def principal_lookup(name, token): + headers = {'Authorization': 'Bearer ' + token} + r = requests.post(CATTLE_AUTH_PRINCIPAL_URL, + json={'name': name, 'responseType': 'json'}, + verify=False, headers=headers) + assert r.status_code == 200 + principals = r.json()['data'] + for principal in principals: + if principal['principalType'] == "user": + if principal['loginName'] == name: + return principal["id"] + if principal['principalType'] == "group": + if principal['name'] == name: + return principal["id"] + assert False + + +def add_users_to_site_access(token, access_mode, allowed_principal_ids): + headers = {'Authorization': 'Bearer ' + token} + r = requests.put(CATTLE_AUTH_PROVIDER_URL, json={ + 'allowedPrincipalIds': allowed_principal_ids, + 'accessMode': access_mode, + 'responseType': 'json', + }, verify=False, headers=headers) + print(r.json()) + + +def assign_user_to_cluster(client, principal_id, cluster, role_template_id): + crtb = client.create_cluster_role_template_binding( + clusterId=cluster.id, + roleTemplateId=role_template_id, + userPrincipalId=principal_id) + return crtb + + +def assign_user_to_project(client, principal_id, project, role_template_id): + prtb = client.create_project_role_template_binding( + projectId=project.id, + roleTemplateId=role_template_id, + userPrincipalId=principal_id) + return prtb + + +def delete_existing_users_in_cluster(client, cluster): + crtbs = client.list_cluster_role_template_binding(clusterId=cluster.id) + for crtb in crtbs: + client.delete(crtb) + + +def delete_existing_users_in_project(client, project): + prtbs = client.list_project_role_template_binding(projectId=project.id) + for prtb in prtbs: + client.delete(prtb) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + + ''' + This method enables auth on the Rancher server setup. Two clusters are + required in the setup. If two clusters are not present, it will create + the clusters. + ''' + + if AUTH_PROVIDER not in ("activeDirectory", "openLdap", "freeIpa"): + assert False, "Auth Provider set is not supported" + setup["auth_setup_data"] = load_setup_data() + client = get_admin_client() + configs = client.list_auth_config(name=AUTH_PROVIDER.lower()) + if not configs.data[0].enabled: + auth_setup_data = setup["auth_setup_data"] + admin_user = auth_setup_data["admin_user"] + if AUTH_PROVIDER == 'activeDirectory': + enable_ad(admin_user, ADMIN_TOKEN) + elif AUTH_PROVIDER == 'openLdap': + enable_openldap(admin_user, ADMIN_TOKEN) + elif AUTH_PROVIDER == 'freeIpa': + enable_freeipa(admin_user, ADMIN_TOKEN) + + cluster_total = len(client.list_cluster().data) + node_roles = [["controlplane", "etcd", "worker"]] + kargs = {'node_roles': node_roles, + 'random_cluster_name': True, + 'validate': False} + aws_nodes1 = cluster1 = None + aws_nodes2 = cluster2 = None + if cluster_total == 0: + cluster1, aws_nodes1 = create_and_validate_custom_host(**kargs) + cluster2, aws_nodes2 = create_and_validate_custom_host(**kargs) + if cluster_total == 1: + cluster2, aws_nodes2 = create_and_validate_custom_host(**kargs) + + clusters = client.list_cluster().data + assert len(clusters) >= 2 + cluster1 = cluster1 if cluster1 else clusters[0] + for project in client.list_project(): + delete_existing_users_in_project(client, project) + p1, ns1 = create_project_and_ns(ADMIN_TOKEN, cluster1) + cluster2 = cluster2 if cluster2 else clusters[1] + p2, ns2 = create_project_and_ns(ADMIN_TOKEN, cluster2) + setup["cluster1"] = cluster1 + setup["project1"] = p1 + setup["ns1"] = ns1 + setup["cluster2"] = cluster2 + setup["project2"] = p2 + setup["ns2"] = ns2 + + def fin(): + client.delete(setup["project1"]) + client.delete(setup["project2"]) + delete_cluster_users() + if cluster_total == 0: + if aws_nodes1 and aws_nodes2: + cluster_cleanup(client, cluster1, aws_nodes1) + cluster_cleanup(client, cluster2, aws_nodes2) + if cluster_total == 1: + if aws_nodes2: + cluster_cleanup(client, cluster2, aws_nodes2) + request.addfinalizer(fin) + + +def delete_cluster_users(): + delete_existing_users_in_cluster(get_admin_client(), setup["cluster1"]) + delete_existing_users_in_cluster(get_admin_client(), setup["cluster2"]) + + +def delete_project_users(): + delete_existing_users_in_project(get_admin_client(), setup["project1"]) + delete_existing_users_in_project(get_admin_client(), setup["project2"]) + + +def load_setup_data(): + auth_setup_file = open(auth_setup_fname) + auth_setup_str = auth_setup_file.read() + auth_setup_data = json.loads(auth_setup_str) + return auth_setup_data diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local.py new file mode 100644 index 0000000..351d963 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local.py @@ -0,0 +1,179 @@ +import pytest +from rancher import ApiError +from .common import * # NOQA + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "nodes": []} +backup_info = {"backupname": None, "backup_id": None, "workload": None, + "backupfilename": None, "etcdbackupdata": None} + +rbac_roles = [CLUSTER_MEMBER, PROJECT_OWNER, PROJECT_MEMBER, PROJECT_READ_ONLY] + + +def test_bkp_restore_local_create(): + validate_backup_create(namespace, backup_info) + + +def test_bkp_restore_local_restore(): + ns , binfo = validate_backup_create(namespace, backup_info) + validate_backup_restore(ns, binfo) + + +def test_bkp_restore_local_delete(): + ns , binfo = validate_backup_create(namespace, backup_info) + ns, binfo = validate_backup_restore(ns, binfo) + validate_backup_delete(ns, binfo) + + +@if_test_rbac +def test_rbac_bkp_restore_create_cluster_owner(): + """ Only cluster-owner should be allowed to create backups """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + wait_for_backup_to_active(user_cluster, backupname) + assert len(user_cluster.etcdBackups(name=backupname)) == 1 + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_roles) +def test_rbac_bkp_restore_create(role): + """ + Only cluster-owner should be allowed to create backups + unprivileged user should get 403 PermissionDenied + """ + user_token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + if not hasattr(user_cluster, 'backupEtcd'): + assert hasattr(user_cluster, 'backupEtcd') == False + else: + with pytest.raises(ApiError) as e: + user_cluster.backupEtcd() + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + +@if_test_rbac +def test_rbac_bkp_restore_list_cluster_owner(): + """ Only cluster-owner should be allowed to list backups """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + assert len(user_cluster.etcdBackups(name=backupname)) == 1 + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_roles) +def test_rbac_bkp_restore_list(role): + """ + unprivileged user should not be allowed to list backups + cluster etcdBackups() should always return length zero + """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + assert len(user_cluster.etcdBackups(name=backupname)) == 1 + wait_for_backup_to_active(user_cluster, backupname) + user_token2 = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(user_token2) + user_cluster2 = user_client.list_cluster(name=CLUSTER_NAME).data[0] + assert len(user_cluster2.etcdBackups()) == 0 + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_roles) +def test_rbac_bkp_restore_restore(role): + """ + unprivileged user should not be allowed to restore backups + """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + etcdbackup = user_cluster.etcdBackups(name=backupname) + backup_id = etcdbackup['data'][0]['id'] + wait_for_backup_to_active(user_cluster, backupname) + + user_token2 = rbac_get_user_token_by_role(role) + user_client2 = get_client_for_token(user_token2) + user_cluster2 = user_client2.list_cluster(name=CLUSTER_NAME).data[0] + if not hasattr(user_cluster2, 'restoreFromEtcdBackup'): + assert hasattr(user_cluster2, 'restoreFromEtcdBackup') == False + else: + with pytest.raises(ApiError) as e: + user_cluster2.restoreFromEtcdBackup(etcdBackupId=backup_id) + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + +@if_test_rbac +def test_rbac_bkp_restore_delete_cluster_owner(): + """ Only cluster-owner should be allowed to delete backups """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + wait_for_backup_to_active(user_cluster, backupname) + assert len(user_cluster.etcdBackups(name=backupname)) == 1 + user_client.delete( + user_cluster.etcdBackups(name=backupname)['data'][0] + ) + wait_for_backup_to_delete(user_cluster, backupname) + assert len(user_cluster.etcdBackups(name=backupname)) == 0 + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_roles) +def test_rbac_bkp_restore_delete(role): + """ + Only cluster-owner should be allowed to delete backups + unprivileged user shouldn't be allowed to delete + """ + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + backup = user_cluster.backupEtcd() + backupname = backup['metadata']['name'] + wait_for_backup_to_active(user_cluster, backupname) + + user_token2 = rbac_get_user_token_by_role(role) + user_client2 = get_client_for_token(user_token2) + user_cluster2 = user_client2.list_cluster(name=CLUSTER_NAME).data[0] + + assert len(user_cluster2.etcdBackups(name=backupname)) == 0 + backup_to_delete = user_cluster.etcdBackups(name=backupname)['data'][0] + if not hasattr(user_cluster2, 'delete'): + assert hasattr(user_cluster2, 'delete') == False + else: + with pytest.raises(ApiError) as e: + user_client2.delete(backup_to_delete) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testsecret") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + client.delete(p) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local_with_snapshot_check.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local_with_snapshot_check.py new file mode 100644 index 0000000..cef0a93 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_local_with_snapshot_check.py @@ -0,0 +1,48 @@ +import pytest +from .common import * # NOQA +from .test_rke_cluster_provisioning import create_and_validate_custom_host + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "nodes": []} +backup_info = {"backupname": None, "backup_id": None, "workload": None, + "backupfilename": None, "etcdbackupdata": None} + + +@if_test_all_snapshot +def test_bkp_restore_local_with_snapshot_check_create(): + validate_backup_create(namespace, backup_info, "filesystem") + + +@if_test_all_snapshot +def test_bkp_restore_local_with_snapshot_check_restore(): + ns, binfo = validate_backup_create(namespace, backup_info, "filesystem") + validate_backup_restore(ns, binfo) + + +@if_test_all_snapshot +def test_bkp_restore_local_with_snapshot_check_delete(): + ns, binfo = validate_backup_create(namespace, backup_info, "filesystem") + ns, binfo = validate_backup_restore(ns, binfo) + validate_backup_delete(ns, binfo, "filesystem") + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client_ec2(request): + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + cluster, aws_nodes = create_and_validate_custom_host(node_roles, True) + client = get_user_client() + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testsecret") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + namespace["nodes"] = aws_nodes.copy() + + def fin(): + client.delete(p) + cluster_cleanup(client, cluster, aws_nodes) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_recover.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_recover.py new file mode 100644 index 0000000..74bf960 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_recover.py @@ -0,0 +1,195 @@ +import pytest +from .common import * # NOQA +from .test_rke_cluster_provisioning import HOST_NAME +from .test_rke_cluster_provisioning import create_and_validate_custom_host +from .test_rke_cluster_provisioning import rke_config + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "nodes": []} +backup_info = {"backupname": None, "backup_id": None, "workload": None, + "backupfilename": None, "etcdbackupdata": None} + + +@if_test_all_snapshot +def test_bkp_restore_s3_recover_validate(): + """ + - This test create 1 cluster with s3 backups enabled + - 1 ControlPlane/worker node + - 2 worker nodes + - 3 etcd nodes + - Creates an Ingress pointing to a workload + - Snapshots the cluster and checks the backup is in S3 + - Stops the etcd nodes in ec2 + - Waits for the cluster to go into unavailable state + - Removes all 3 etcd nodes + - Creates 3 new etcd nodes and waits until the cluster + asks to restore from backup. + - Restores from S3 backup + - Cluster is validated after it gets in Active state. + - Checks the Ingress created before the backup is functional after restore. + - Removes cluster if RANCHER_CLEANUP_CLUSTER=True + """ + + cluster = namespace["cluster"] + client = namespace["client"] + ns, b_info = validate_backup_create(namespace, backup_info, "s3") + ips_to_remove = [] + etcd_nodes = get_etcd_nodes(client, cluster) + assert len(etcd_nodes) > 0, "Make sure we have etcd nodes in the cluster" + + # stop the etcd ec2 instances + [stop_node_from_ec2(etcd_node.externalIpAddress) + for etcd_node in etcd_nodes] + # wait for cluster to get into unavailable state + cluster = wait_for_cluster_unavailable_or_error(client, cluster) + for etcd_node in etcd_nodes: + ips_to_remove.append(etcd_node.customConfig['internalAddress']) + client.delete(etcd_node) + # Also remove the ec2 instances + for ip_to_remove in ips_to_remove: + delete_node_from_ec2(ip_to_remove) + namespace["nodes"] = [node for node + in namespace["nodes"] + if node.private_ip_address != ip_to_remove] + ips_to_remove.clear() + cluster = client.reload(cluster) + wait_for_cluster_node_count(client, cluster, 3) + # Add completely new etcd nodes to the cluster + cluster = add_new_etcd_nodes(client, cluster) + cluster = client.reload(cluster) + wait_for_cluster_node_count(client, cluster, 6, 500) + # This message is expected to appear after we add new etcd nodes + # The cluster will require the user to perform a backup to recover + # this is appears in the cluster object in cluster.transitioningMessage + message = "Please restore your cluster from backup" + cluster = wait_for_cluster_transitioning_message(client, cluster, message) + etcd_nodes = get_etcd_nodes(client, cluster) + assert len(etcd_nodes) == 3, "Make sure the cluster now has 3 etcd nodes" + cluster = restore_backup_to_recover(client, cluster, b_info) + # validate the ingress that was created in the first backup + # after restoring and recovering the cluster + validate_ingress(namespace["p_client"], cluster, + [b_info["workload"]], ns["host"], + "/name.html") + + +@pytest.fixture(scope='module', autouse=True) +def create_project_client_and_cluster_s3_three_etcd(request): + node_roles = [ + ["controlplane", "worker"], + ["etcd"], ["etcd"], ["etcd"], + ["worker"], ["worker"] + ] + rke_config["services"]["etcd"]["backupConfig"] = { + "enabled": "true", + "intervalHours": 6, + "retention": 3, + "type": "backupConfig", + "s3BackupConfig": { + "type": "s3BackupConfig", + "accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY, + "bucketName": AWS_S3_BUCKET_NAME, + "folder": AWS_S3_BUCKET_FOLDER_NAME, + "region": AWS_REGION, + "endpoint": "s3.us-east-2.amazonaws.com" + } + } + cluster, aws_nodes = create_and_validate_custom_host( + node_roles, + random_cluster_name=True + ) + client = get_user_client() + namespace["nodes"].extend(aws_nodes) + + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testrecover") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + namespace["client"] = client + + def fin(): + cluster_cleanup(client, cluster, namespace["nodes"]) + request.addfinalizer(fin) + + +def wait_for_cluster_unavailable_or_error(client, cluster): + return wait_for_condition( + client, + cluster, + lambda x: x.state == "unavailable" or x.state == "error", + lambda x: "State is: " + x.state, + timeout=DEFAULT_CLUSTER_STATE_TIMEOUT, + ) + + +def wait_for_cluster_transitioning_message(client, cluster, message): + start = time.time() + while message not in cluster.transitioningMessage: + print(cluster.transitioningMessage) + time.sleep(5) + cluster = client.reload(cluster) + # We are waiting 4 minutes for the transitioning message to appear + # this could be impacted by environmental factors + if time.time() - start > DEFAULT_CLUSTER_STATE_TIMEOUT: + raise Exception('Timeout waiting for condition') + return cluster + + +def add_new_etcd_nodes(client, cluster, no_of_nodes=3): + aws_nodes = AmazonWebServices().create_multiple_nodes( + no_of_nodes, random_test_name(HOST_NAME)) + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, ["etcd"], + aws_node) + print("Docker run command: " + docker_run_cmd) + aws_node.roles.append("etcd") + + result = aws_node.execute_command(docker_run_cmd) + namespace["nodes"].append(aws_node) + print(result) + return cluster + + +def delete_node_from_ec2(internal_ip): + + filters = [ + {'Name': 'private-ip-address', + 'Values': [internal_ip]} + ] + aws_node = AmazonWebServices().get_nodes(filters) + if len(aws_node) > 0: + AmazonWebServices().delete_node(aws_node[0]) + + +def stop_node_from_ec2(address): + filters = [ + {'Name': 'ip-address', + 'Values': [address]} + ] + aws_node = AmazonWebServices().get_nodes(filters) + if len(aws_node) > 0: + AmazonWebServices().stop_node(aws_node[0]) + + +def restore_backup_to_recover(client, cluster, b_info): + cluster.restoreFromEtcdBackup(etcdBackupId=b_info["backup_id"]) + return validate_cluster(client, cluster, intermediate_state="updating", + check_intermediate_state=True, + skipIngresscheck=False) + + +def get_etcd_nodes(client, cluster): + nodes = client.list_node(clusterId=cluster.id).data + return [node for node in nodes if node.etcd is True] + + +def get_worker_nodes(client, cluster): + nodes = client.list_node(clusterId=cluster.id).data + return [node for node in nodes if node.worker is True] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_creds.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_creds.py new file mode 100644 index 0000000..bc19442 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_creds.py @@ -0,0 +1,67 @@ +import pytest +from .common import * # NOQA +from .test_rke_cluster_provisioning import rke_config, validate_rke_dm_host_2,\ + node_template_linode + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "nodes": []} +backup_info = {"backupname": None, "backup_id": None, "workload": None, + "backupfilename": None, "etcdbackupdata": None} + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_creds_create(): + validate_backup_create(namespace, backup_info, "s3") + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_creds_restore(): + ns, binfo = validate_backup_create(namespace, backup_info, "s3") + validate_backup_restore(ns, binfo) + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_creds_delete(): + ns, binfo = validate_backup_create(namespace, backup_info, "s3") + ns, binfo = validate_backup_restore(ns, binfo) + validate_backup_delete(ns, binfo, "s3") + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client_and_cluster_s3_with_creds(node_template_linode, + request): + rke_config["services"]["etcd"]["backupConfig"] = { + "enabled": "true", + "intervalHours": 12, + "retention": 6, + "type": "backupConfig", + "s3BackupConfig": { + "type": "s3BackupConfig", + "accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY, + "bucketName": AWS_S3_BUCKET_NAME, + "folder": AWS_S3_BUCKET_FOLDER_NAME, + "region": AWS_REGION, + "endpoint": "s3.us-east-2.amazonaws.com" + } + } + cluster_name = random_name() + validate_rke_dm_host_2(node_template_linode, + rke_config, False, cluster_name) + client = get_user_client() + cluster = get_cluster_by_name(client, cluster_name) + + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testnoiam") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + cluster_cleanup(client, cluster) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_iam.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_iam.py new file mode 100644 index 0000000..2eb448e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_bkp_restore_s3_with_iam.py @@ -0,0 +1,99 @@ +import pytest +from .common import * # NOQA +from .test_rke_cluster_provisioning import rke_config, engine_install_url, \ + validate_rke_dm_host_2 + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "nodes": []} +backup_info = {"backupname": None, "backup_id": None, "workload": None, + "backupfilename": None, "etcdbackupdata": None} + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_iam_create(): + validate_backup_create(namespace, backup_info, "s3") + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_iam_restore(): + ns, binfo = validate_backup_create(namespace, backup_info, "s3") + validate_backup_restore(ns, binfo) + + +@if_test_all_snapshot +def test_bkp_restore_s3_with_iam_delete(): + ns, binfo = validate_backup_create(namespace, backup_info, "s3") + ns, binfo = validate_backup_restore(ns, binfo) + validate_backup_delete(ns, binfo, "s3") + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client_and_cluster_s3_with_iam(request): + rke_config["services"]["etcd"]["backupConfig"] = { + "enabled": "true", + "intervalHours": 12, + "retention": 6, + "type": "backupConfig", + "s3BackupConfig": { + "type": "s3BackupConfig", + "accessKey": "", + "secretKey": "", + "bucketName": AWS_S3_BUCKET_NAME, + "folder": AWS_S3_BUCKET_FOLDER_NAME, + "region": AWS_REGION, + "endpoint": "s3.us-east-2.amazonaws.com" + } + } + cluster_name = random_name() + validate_rke_dm_host_2(node_template_ec2_iam(), + rke_config, False, cluster_name) + client = get_user_client() + cluster = get_cluster_by_name(client, cluster_name) + + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testiam") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + cluster_cleanup(client, cluster) + request.addfinalizer(fin) + + +def node_template_ec2_iam(): + client = get_user_client() + ec2_cloud_credential_config = {"accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY} + ec2_cloud_credential = client.create_cloud_credential( + amazonec2credentialConfig=ec2_cloud_credential_config + ) + amazonec2Config = { + "iamInstanceProfile": AWS_IAM_PROFILE, + "instanceType": "t3a.medium", + "region": AWS_REGION, + "rootSize": "16", + "securityGroup": [AWS_SG], + "sshUser": "ubuntu", + "subnetId": AWS_SUBNET, + "usePrivateAddress": False, + "volumeType": "gp2", + "vpcId": AWS_VPC, + "zone": AWS_ZONE + } + node_template = client.create_node_template( + amazonec2Config=amazonec2Config, + name=random_name(), + useInternalIpAddress=True, + driver="amazonec2", + engineInstallURL=engine_install_url, + cloudCredentialId=ec2_cloud_credential.id + + ) + node_template = client.wait_success(node_template) + return node_template diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_boto_create_eks.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_boto_create_eks.py new file mode 100644 index 0000000..921f0a2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_boto_create_eks.py @@ -0,0 +1,47 @@ +import base64 + +from .common import run_command_with_stderr +from .test_eks_cluster import ekscredential +from .test_eks_cluster import \ + DATA_SUBDIR, EKS_ACCESS_KEY, EKS_SECRET_KEY, EKS_REGION +from .test_rke_cluster_provisioning import evaluate_clustername +from lib.aws import AmazonWebServices + + +@ekscredential +def test_boto_create_eks(): + cluster_name = evaluate_clustername() + AmazonWebServices().create_eks_cluster(cluster_name) + kc_path = get_eks_kubeconfig(cluster_name) + out = run_command_with_stderr( + 'kubectl --kubeconfig {} get svc'.format(kc_path)) + print(out) + out = run_command_with_stderr( + 'kubectl --kubeconfig {} get nodes'.format(kc_path)) + print(out) + + +def get_eks_kubeconfig(cluster_name): + kubeconfig_path = DATA_SUBDIR + "/kube_config_hosted_eks.yml" + + exports = 'export AWS_ACCESS_KEY_ID={} && ' + \ + 'export AWS_SECRET_ACCESS_KEY={}'.format( + EKS_ACCESS_KEY, EKS_SECRET_KEY) + + # log_out=False so we don't write the keys to the console + run_command_with_stderr(exports, log_out=False) + + command = 'aws eks --region {} update-kubeconfig '.format(EKS_REGION) + \ + '--name {} --kubeconfig {}'.format(cluster_name, kubeconfig_path) + run_command_with_stderr(command) + + print("\n\nKubeconfig:") + kubeconfig_file = open(kubeconfig_path, "r") + kubeconfig_contents = kubeconfig_file.read() + kubeconfig_file.close() + kubeconfig_contents_encoded = base64.b64encode( + kubeconfig_contents.encode("utf-8")).decode("utf-8") + print("\n\n" + kubeconfig_contents + "\n\n") + print("\nBase64 encoded: \n\n" + kubeconfig_contents_encoded + "\n\n") + + return kubeconfig_path diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_catalog_library.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_catalog_library.py new file mode 100644 index 0000000..1dab059 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_catalog_library.py @@ -0,0 +1,98 @@ +""" +This file has tests to deploy apps in a project created in a cluster. +Test requirements: +Env variables - Cattle_url, Admin Token, User Token, Cluster Name +Test on at least 3 worker nodes +App versions are given in 'cataloglib_appversion.json' file +""" + + +import json +from .common import os +from .common import pytest +from .common import create_ns +from .common import create_catalog_external_id +from .common import validate_app_deletion +from .common import get_user_client_and_cluster +from .common import create_kubeconfig +from .common import get_cluster_client_for_token +from .common import create_project +from .common import random_test_name +from .common import get_defaut_question_answers +from .common import validate_catalog_app +from .common import get_project_client_for_token +from .common import USER_TOKEN +from .common import get_user_client + +# Skipping all the tests from this module because the library_catalog charts are not supported on latest +# rancher versions +pytest.skip(allow_module_level=True) + +cluster_info = {"cluster": None, "cluster_client": None, + "project": None, "project_client": None, + "user_client": None} +catalog_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), + "./resource/cataloglib_appversion.json") +with open(catalog_filename, "r") as app_v: + app_data = json.load(app_v) + + +@pytest.mark.parametrize('app_name, app_version', app_data.items()) +def test_catalog_app_deploy(app_name, app_version): + """ + Runs for app from 'cataloglib_appversion.json', + creates relevant namespace and deploy them. + Validates status of the app, version and answer. + try block is to make sure apps are deleted even + after they fail to validate. + """ + user_client = cluster_info["user_client"] + project_client = cluster_info["project_client"] + cluster_client = cluster_info["cluster_client"] + cluster = cluster_info["cluster"] + project = cluster_info["project"] + + ns = create_ns(cluster_client, cluster, project, app_name) + app_ext_id = create_catalog_external_id('library', + app_name, app_version) + answer = get_defaut_question_answers(user_client, app_ext_id) + try: + app = project_client.create_app( + name=random_test_name(), + externalId=app_ext_id, + targetNamespace=ns.name, + projectId=ns.projectId, + answers=answer) + validate_catalog_app(project_client, app, app_ext_id, answer) + except (AssertionError, RuntimeError): + assert False, "App {} deployment/Validation failed.".format(app_name) + finally: + project_client.delete(app) + validate_app_deletion(project_client, app.id) + user_client.delete(ns) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + """ + Creates project in a cluster and collects details of + user, project and cluster + """ + user_client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + cluster_client = get_cluster_client_for_token(cluster, USER_TOKEN) + project = create_project(user_client, cluster, + random_test_name("App-deployment")) + project_client = get_project_client_for_token(project, USER_TOKEN) + + cluster_info["cluster"] = cluster + cluster_info["cluster_client"] = cluster_client + cluster_info["project"] = project + cluster_info["project_client"] = project_client + cluster_info["user_client"] = user_client + + def fin(): + client = get_user_client() + client.delete(cluster_info["project"]) + + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cert_rotation.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cert_rotation.py new file mode 100644 index 0000000..21bacff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cert_rotation.py @@ -0,0 +1,206 @@ +import pytest +import datetime +import time +import os +import ast +from .common import rbac_get_user_token_by_role +from .common import get_client_for_token +from .common import get_user_client_and_cluster +from .common import validate_cluster_state +from .common import get_etcd_nodes +from rancher import ApiError + + +# Globals +# Master list of all certs +ALL_CERTS = ["kube-apiserver", "kube-controller-manager", + "kube-node", "kube-proxy", "kube-scheduler", + "kube-etcd", "kube-ca"] +TEST_RBAC = ast.literal_eval(os.environ.get('RANCHER_TEST_RBAC', "False")) +if_test_rbac = pytest.mark.skipif(TEST_RBAC is False, + reason='rbac tests are skipped') +CLUSTER_NAME = os.environ.get("RANCHER_CLUSTER_NAME", "") +# here are all supported roles for RBAC testing +CLUSTER_MEMBER = "cluster-member" +CLUSTER_OWNER = "cluster-owner" +PROJECT_MEMBER = "project-member" +PROJECT_OWNER = "project-owner" +PROJECT_READ_ONLY = "read-only" +rbac_data = { + "project": None, + "namespace": None, + "workload": None, + "p_unshared": None, + "ns_unshared": None, + "wl_unshared": None, + "users": { + CLUSTER_OWNER: {}, + CLUSTER_MEMBER: {}, + PROJECT_OWNER: {}, + PROJECT_MEMBER: {}, + PROJECT_READ_ONLY: {}, + } +} +# --------------------- rbac test ----------------------- +@if_test_rbac +@pytest.mark.parametrize("role", [CLUSTER_MEMBER, + PROJECT_MEMBER, PROJECT_OWNER, + PROJECT_READ_ONLY, CLUSTER_OWNER]) +def test_rbac_cert_rotation(role): + user_token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(user_token) + user_cluster = user_client.list_cluster(name=CLUSTER_NAME).data[0] + if role == CLUSTER_OWNER: + now = datetime.datetime.now() + user_cluster.rotateCertificates() + changed = ALL_CERTS.copy() + changed.remove("kube-ca") + client, cluster = get_user_client_and_cluster() + validate_cluster_state(client, cluster, + intermediate_state="updating") + certs2 = get_certs() + compare_changed(certs2, now, changed) + return None + if not hasattr(user_cluster, 'rotateCertificates'): + assert hasattr(user_cluster, 'rotateCertificates') == False + else: + with pytest.raises(ApiError) as e: + user_cluster.rotateCertificates() + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + +def test_rotate_all_certs(): + changed = ALL_CERTS.copy() + changed.remove("kube-ca") + unchanged = ["kube-ca"] + rotate_and_compare(unchanged, changed) + + +def test_rotate_kube_apiserver(): + changed = ["kube-apiserver"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-apiserver") + rotate_and_compare(unchanged, changed, "kube-apiserver") + + +def test_rotate_kube_controller_manager(): + changed = ["kube-controller-manager"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-controller-manager") + rotate_and_compare(unchanged, changed, "kube-controller-manager") + + +def test_rotate_kube_etcd(): + changed = ["kube-etcd"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-etcd") + rotate_and_compare(unchanged, changed, "etcd") + + +def test_rotate_kube_node(): + changed = ["kube-node"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-node") + rotate_and_compare(unchanged, changed, "kubelet") + + +def test_rotate_kube_proxy(): + changed = ["kube-proxy"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-proxy") + rotate_and_compare(unchanged, changed, "kube-proxy") + + +def test_rotate_kube_scheduler(): + changed = ["kube-scheduler"] + unchanged = ALL_CERTS.copy() + unchanged.remove("kube-scheduler") + rotate_and_compare(unchanged, changed, "kube-scheduler") + + +def test_rotate_kube_ca(): + changed = ALL_CERTS + unchanged = [] + rotate_and_compare(unchanged, changed, "kube-ca") + + +# Gets the certificate expiration date and cert name. Stores them in a dict. +def get_certs(): + certs = {} + client, cluster = get_user_client_and_cluster() + for key in cluster.certificatesExpiration: + if "kube-etcd" not in key: + certs[key] = parse_datetime(cluster.certificatesExpiration[key] + ["expirationDate"]) + + # Get etcd node certs from node IP + nodes = get_etcd_nodes(cluster) + for node in nodes: + if node["labels"]["node-role.kubernetes.io/etcd"] == "true": + ipKey = "kube-etcd-"+node["ipAddress"].replace(".", "-") + certs[ipKey] = parse_datetime(cluster.certificatesExpiration[ipKey] + ["expirationDate"]) + return certs + + +# Turn expiration string into datetime +def parse_datetime(expiration_string): + return datetime.datetime.strptime(expiration_string, '%Y-%m-%dT%H:%M:%SZ') + + +def compare_changed(certs2, time_now, changed): + if "kube-etcd" in changed: + for key in certs2: + if "kube-etcd" in key: + changed.append(key) + changed.remove("kube-etcd") + for i in changed: + assert(certs2[i] > (time_now + datetime.timedelta(days=3650))) + + +def compare_unchanged(certs1, certs2, unchanged): + if "kube-etcd" in unchanged: + for key in certs2: + if "kube-etcd" in key: + unchanged.append(key) + unchanged.remove("kube-etcd") + for i in unchanged: + assert(certs1[i] == certs2[i]) + + +def rotate_certs(service=""): + client, cluster = get_user_client_and_cluster() + if service: + if service == "kube-ca": + cluster.rotateCertificates(caCertificates=True) + else: + cluster.rotateCertificates(services=service) + else: + cluster.rotateCertificates() + + +def rotate_and_compare(unchanged, changed, service=""): + client, cluster = get_user_client_and_cluster() + # Grab certs before rotation + certs1 = get_certs() + now = datetime.datetime.now() + # Rotate certs + rotate_certs(service) + # wait for cluster to update + cluster = validate_cluster_state(client, cluster, + intermediate_state="updating") + if service == "kube-ca": + time.sleep(60) + # Grab certs after rotate + certs2 = get_certs() + # Checks the new certs against old certs. + compare_changed(certs2, now, changed) + compare_unchanged(certs1, certs2, unchanged) + time.sleep(120) + # get all nodes and assert status + nodes = client.list_node(clusterId=cluster.id).data + for node in nodes: + if node["state"] != "active": + raise AssertionError( + "Timed out waiting for state to get to active") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_certificate.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_certificate.py new file mode 100644 index 0000000..3d1b114 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_certificate.py @@ -0,0 +1,781 @@ +""" +This test suite contains tests to validate certificate create/edit/delete with +different possible way and with different roles of users. +Test requirement: +Below Env variables need to be set +CATTLE_TEST_URL - url to rancher server +ADMIN_TOKEN - Admin token from rancher +USER_TOKEN - User token from rancher +RANCHER_CLUSTER_NAME - Cluster name to run test on +RANCHER_VALID_TLS_KEY - takes authentic certificate key base64 encoded +RANCHER_VALID_TLS_CERT - takes authentic certificate base64 encoded +RANCHER_BYO_TLS_KEY - takes self signed certificate key base64 encoded +RANCHER_BYO_TLS_CERT - takes self signed certificate base64 encoded +AWS_HOSTED_ZONE_ID - Zone Id in AWS route53 where route53 will be created. +RANCHER_TEST_RBAC - To enable rbac tests +""" + +from .common import (ApiError, CLUSTER_MEMBER, CLUSTER_OWNER, create_kubeconfig, + create_ns, create_project_and_ns, + get_cluster_client_for_token, get_project_client_for_token, + get_user_client, get_user_client_and_cluster, if_test_rbac, + PROJECT_OWNER, PROJECT_MEMBER, PROJECT_READ_ONLY, + random_test_name, rbac_get_namespace, rbac_get_project, + rbac_get_user_token_by_role, TEST_IMAGE, USER_TOKEN, + validate_ingress_using_endpoint, validate_workload, + wait_for_ingress_to_active, base64, TEST_IMAGE_PORT) +from lib.aws import AmazonWebServices +from pathlib import Path +import pytest +import os +import time + + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "c_client": None, "cert_valid": None, "cert_ssc": None, + "cert_allns_valid": None, "cert_allns_ssc": None, "node_id": None} + +route_entry_53_1 = random_test_name('auto-valid') + '.qa.rancher.space' +route_entry_53_2 = random_test_name('auto-ssc') + '.qa.rancher.space' + + +def get_ssh_key(ssh_key_name): + home = str(Path.home()) + path = '{}/.ssh/{}'.format(home, ssh_key_name) + if os.path.exists(path): + with open(path, 'r') as f: + ssh_key = f.read() + return ssh_key + + +def get_private_key(env_var, key_name): + key = os.environ.get(env_var) + if key is not None: + return base64.b64decode(key).decode("utf-8") + else: + return get_ssh_key(key_name) + + +rancher_private_key = get_private_key('RANCHER_VALID_TLS_KEY', + 'privkey.pem') +rancher_cert = get_private_key('RANCHER_VALID_TLS_CERT', 'fullchain.pem') +rancher_ssc_private_key = get_private_key('RANCHER_BYO_TLS_KEY', + 'key.pem') +rancher_ssc_cert = get_private_key('RANCHER_BYO_TLS_CERT', 'cert.pem') + +rbac_role_list = [ + CLUSTER_OWNER, + CLUSTER_MEMBER, + PROJECT_OWNER, + PROJECT_MEMBER, + PROJECT_READ_ONLY + ] + + +@pytest.mark.usefixtures("create_project_client") +class TestCertificate: + + @pytest.fixture(autouse="True") + def certificate_test_setup(self): + """ + Test set up which runs before and after all the tests in the class + Creates Workload_2 if required and delete all the workload and ingres + created after test execution. + """ + self.p_client = namespace["p_client"] + self.ns = namespace["ns"] + self.c_client = namespace["c_client"] + self.cluster = namespace["cluster"] + self.project = namespace["project"] + self.certificate_valid = namespace["cert_valid"] + self.certificate_ssc = namespace["cert_ssc"] + self.certificate_all_ns_valid = namespace["cert_allns_valid"] + self.certificate_all_ns_ssc = namespace["cert_allns_ssc"] + self.node_id = namespace["node_id"] + wl_name = random_test_name("workload-test") + wl_con = [{"name": "wk1-test", + "image": TEST_IMAGE}] + scheduling = {"node": {"nodeId": self.node_id}} + self.workload = self.p_client.create_workload( + name=wl_name, containers=wl_con, namespaceId=self.ns.id, + scheduling=scheduling + ) + self.ingress = None + self.workload_2 = None + yield + self.p_client.delete(self.workload) + if self.workload_2 is not None: + self.p_client.delete(self.workload_2) + if self.ingress is not None: + self.p_client.delete(self.ingress) + + def test_certificate_create_validcert_for_single_ns(self): + """ + Test steps: + 1. Validate the workload available in ns-certificate namespace + 2. Create an ingress including trusted certificate scoped for current + namespace and route53 host. + 3. validate the ingress using endpoint + """ + ingress_name = random_test_name("ingress-test") + host = route_entry_53_1 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}]} + tls = {"certificateId": self.certificate_valid.id, "hosts": [host]} + validate_workload(self.p_client, self.workload, "deployment", + self.ns.name) + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule], tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True) + + def test_certificate_create_validcert_for_all_ns(self): + """ + Test steps: + 1. Validate the workload available in ns-certificate namespace + 2. Create an ingress including trusted certificate scoped for all + namespace and route53 host. + 3. validate the ingress using endpoint + """ + ingress_name = random_test_name("ingress-test") + host = route_entry_53_1 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}] + } + tls = {"certificateId": self.certificate_all_ns_valid.id, + "hosts": [host] + } + validate_workload(self.p_client, self.workload, "deployment", + self.ns.name) + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule], tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True) + + def test_certificate_create_validcert_for_all_ns_2(self): + """ + Test steps: + 1. Create a namespace + 2. Create a workload in namespace created above. + 3. Validate the workload. + 4. Create an ingress including trusted certificate scoped for all + namespace and route53 host. + 5. validate the ingress using endpoint + """ + wl_name = random_test_name("workload-test") + wl_con = [{"name": "wk2-test", + "image": TEST_IMAGE}] + scheduling = {"node": {"nodeId": self.node_id}} + ns_2 = create_ns(self.c_client, self.cluster, self.project) + self.workload_2 = self.p_client.create_workload( + name=wl_name, containers=wl_con, namespaceId=ns_2.id, + scheduling=scheduling + ) + validate_workload(self.p_client, self.workload_2, "deployment", + ns_2.name) + ingress_name = random_test_name("ingress-test") + host = route_entry_53_1 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload_2.id], + "targetPort": TEST_IMAGE_PORT}] + } + tls = {"certificateId": self.certificate_all_ns_valid.id, + "hosts": [host] + } + self.ingress = self.p_client.create_ingress( + name="{}-2".format(ingress_name), namespaceId=ns_2.id, + rules=[rule], tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload_2], certcheck=True) + + def test_certificate_create_ssc_for_single_ns(self): + """ + Test steps: + 1. Validate the workload available in ns-certificate namespace + 2. Create an ingress including self signed certificate scoped for + current namespace and route53 host. + 3. validate the ingress using endpoint + """ + validate_workload(self.p_client, self.workload, "deployment", + self.ns.name) + ingress_name = random_test_name("ingress-test") + host = route_entry_53_2 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}]} + tls = {"certificateId": self.certificate_ssc.id, "hosts": [host]} + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule], tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + # validate_ingress(host, path) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True, + is_insecure=True + ) + + def test_certificate_create_ssc_for_all_ns(self): + """ + Test steps: + 1. Validate the workload available in ns-certificate namespace + 2. Create an ingress including self signed certificate scoped for + all namespace and route53 host. + 3. validate the ingress using endpoint + """ + ingress_name = random_test_name("ingress-test") + host = route_entry_53_2 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}] + } + tls = {"certificateId": self.certificate_all_ns_ssc.id, "hosts": [host]} + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule], tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True, + is_insecure=True + ) + + def test_certificate_create_ssc_for_all_ns_2(self): + """ + Test steps: + 1. Create a namespace + 2. Create a workload in namespace created above. + 3. Validate the workload. + 4. Create an ingress including trusted certificate scoped for all + namespace and route53 host. + 5. validate the ingress using endpoint + """ + wl_name = random_test_name("workload-test") + wl_con = [{"name": "wk2-test", + "image": TEST_IMAGE}] + scheduling = {"node": {"nodeId": self.node_id}} + ns_2 = create_ns(self.c_client, self.cluster, self.project) + self.workload_2 = self.p_client.create_workload( + name=wl_name, containers=wl_con, namespaceId=ns_2.id, + scheduling=scheduling + ) + validate_workload(self.p_client, self.workload_2, "deployment", + ns_2.name) + ingress_name = random_test_name("ingress-test") + host = route_entry_53_2 + path = "/name.html" + rule = {"host": host, + "paths": [{"path": path, "workloadIds": [self.workload_2.id], + "targetPort": TEST_IMAGE_PORT}] + } + tls = {"certificateId": self.certificate_all_ns_ssc.id, "hosts": [host]} + self.ingress = self.p_client.create_ingress( + name="{}-2".format(ingress_name), namespaceId=ns_2.id, rules=[rule], + tls=[tls]) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload_2], certcheck=True, + is_insecure=True + ) + + def test_certificate_edit_ssc_to_valid_for_single_ns(self): + """ + Test steps: + 1. Create an ingress pointing to self signed certificate scoped to + current namespace. + 2. Update the certificate key to trusted. + 3. Reload the certificate. + 4. Update the ingress. + 5. validate the ingress using endpoint. + """ + ingress_name = random_test_name("ingress-test") + host_1 = route_entry_53_2 + host_2 = route_entry_53_1 + path = "/name.html" + rule_1 = {"host": host_1, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}]} + rule_2 = {"host": host_2, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}]} + tls = {"certificateId": self.certificate_ssc.id, "hosts": [host_1]} + tls_2 = {"certificateId": self.certificate_ssc.id, "hosts": [host_2]} + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule_1], + tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + self.p_client.update( + self.certificate_ssc, key=rancher_private_key, certs=rancher_cert + ) + self.p_client.reload(self.certificate_ssc) + self.p_client.update(self.ingress, rules=[rule_2], tls=[tls_2]) + self.p_client.reload(self.ingress) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True) + + def test_certificate_edit_ssc_to_valid_cert_for_all_ns(self): + """ + Test steps: + 1. Create an ingress pointing to self signed certificate scoped to + all namespace. + 2. Update the certificate key to trusted. + 3. Reload the certificate. + 4. Update the ingress. + 5. validate the ingress using endpoint. + """ + ingress_name = random_test_name("ingress-test") + host_1 = route_entry_53_2 + host_2 = route_entry_53_1 + path = "/name.html" + rule_1 = {"host": host_1, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}] + } + rule_2 = {"host": host_2, + "paths": [{"path": path, "workloadIds": [self.workload.id], + "targetPort": TEST_IMAGE_PORT}] + } + tls = {"certificateId": self.certificate_all_ns_ssc.id, + "hosts": [host_1]} + tls_2 = {"certificateId": self.certificate_all_ns_ssc.id, + "hosts": [host_2]} + self.ingress = self.p_client.create_ingress( + name=ingress_name, namespaceId=self.ns.id, rules=[rule_1], + tls=[tls] + ) + wait_for_ingress_to_active(self.p_client, self.ingress) + self.p_client.update( + self.certificate_all_ns_ssc, key=rancher_private_key, + certs=rancher_cert + ) + self.p_client.reload(self.certificate_all_ns_ssc) + self.p_client.update(self.ingress, rules=[rule_2], tls=[tls_2]) + self.p_client.reload(self.ingress) + wait_for_ingress_to_active(self.p_client, self.ingress) + validate_ingress_using_endpoint( + self.p_client, self.ingress, [self.workload], certcheck=True) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_create_certificate(self, role): + """ + Test steps: + 1. Create certificate all namespace for all role + 2. Delete the certificate + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + cert_name = random_test_name("cert-rbac") + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.create_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert + ) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + certificate_allns_valid = p_client.create_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert + ) + assert certificate_allns_valid.issuer == 'R3' + # Delete the certificate + p_client.delete(certificate_allns_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_create_namespaced_certificate(self, role): + """ + Test steps: + 1. Create certificate for single namespace for all role + 2. Delete the certificate + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + cert_name = random_test_name("cert-rbac") + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.create_namespaced_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert, + namespaceId=ns['name'] + ) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + certificate_valid = p_client.create_namespaced_certificate( + name=cert_name, key=rancher_private_key, certs=rancher_cert, + namespaceId=ns['name'] + ) + assert certificate_valid.issuer == 'R3' + # Delete the certificate + p_client.delete(certificate_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_list_namespaced_certificate(self, role): + """ + Test steps: + 1. Create certificate for single namespace for all role as + cluster owner + 2. List the created certificate for all roles + 3. Delete the certificate + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_valid = p_client_owner.create_namespaced_certificate( + name=cert_name, key=rancher_private_key, certs=rancher_cert, + namespaceId=ns['name'] + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + cert_count = p_client.list_namespaced_certificate(name=cert_name) + assert len(cert_count) == 0, '{} is able to list the ' \ + 'certificate'.format(role) + else: + cert_count = p_client.list_namespaced_certificate(name=cert_name) + assert len(cert_count) > 0, "{} couldn't to list the " \ + "certificate".format(role) + + # Delete the resources + p_client.delete(certificate_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_list_certificate(self, role): + """ + Test steps: + 1. Create certificate for all namespace for all role as + cluster owner + 2. List the created certificate for all roles + 3. Delete the certificate + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, + c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_allns_valid = p_client_owner.create_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + cert_count = p_client.list_certificate(name=cert_name) + assert len(cert_count) == 0, '{} is able to list the ' \ + 'certificate'.format(role) + else: + cert_count = p_client.list_certificate(name=cert_name) + assert len(cert_count) > 0, "{} couldn't to list the " \ + "certificate".format(role) + + # Delete the resources + p_client.delete(certificate_allns_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_edit_certificate(self, role): + """ + Test steps: + 1. Create certificate for single and all namespace for all role as + cluster owner + 2. Update the created certificate for all roles + 3. Delete the certificate + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, + c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_allns_valid = p_client_owner.create_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.update( + certificate_allns_valid, key=rancher_ssc_private_key, + certs=rancher_ssc_cert) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + certificate_allns_valid = p_client.update( + certificate_allns_valid, key=rancher_ssc_private_key, + certs=rancher_ssc_cert) + p_client.reload(certificate_allns_valid) + assert certificate_allns_valid.issuer == 'Rancher QA CA' + # Delete the resources + p_client.delete(certificate_allns_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_edit_namespaced_certificate(self, role): + """ + Test steps: + 1. Create certificate for single namespace for all role as + cluster owner + 2. Update the created certificate for all roles + 3. Delete the certificate + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, + c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_valid = p_client_owner.create_namespaced_certificate( + name=cert_name, key=rancher_private_key, certs=rancher_cert, + namespaceId=ns['name'] + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.update(certificate_valid, key=rancher_ssc_private_key, + certs=rancher_ssc_cert) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + certificate_valid = p_client.update( + certificate_valid, key=rancher_ssc_private_key, + certs=rancher_ssc_cert) + p_client.reload(certificate_valid) + assert certificate_valid.issuer == 'Rancher QA CA' + # Delete the resources + p_client.delete(certificate_valid) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_delete_certificate(self, role): + """ + Test steps: + 1. Create certificate for single and all namespace for all role as + cluster owner + 2. Delete the certificate as different roles. + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, + c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_allns_valid = p_client_owner.create_certificate( + name=cert_name, key=rancher_private_key, + certs=rancher_cert + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.delete(certificate_allns_valid) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + p_client_owner.delete(certificate_allns_valid) + else: + p_client.delete(certificate_allns_valid) + time.sleep(2) + cert_count = p_client.list_certificate(name=cert_name) + assert len(cert_count) == 0, '{} is not able to delete the ' \ + 'certificate'.format(role) + + @if_test_rbac + @pytest.mark.parametrize("role", rbac_role_list) + def test_delete_namespaced_certificate(self, role): + """ + Test steps: + 1. Create certificate for single namespace for all role as + cluster owner + 2. Delete the certificate as different roles. + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + p_client_owner = get_project_client_for_token(project, + c_owner_token) + cert_name = random_test_name("cert-rbac") + certificate_valid = p_client_owner.create_namespaced_certificate( + name=cert_name, key=rancher_private_key, certs=rancher_cert, + namespaceId=ns['name'] + ) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.delete(certificate_valid) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + p_client_owner.delete(certificate_valid) + else: + p_client.delete(certificate_valid) + time.sleep(2) + cert_count = p_client.list_namespaced_certificate(name=cert_name) + assert len(cert_count) == 0, '{} is not able to delete the ' \ + 'certificate'.format(role) + + @if_test_rbac + @pytest.mark.parametrize("role", [PROJECT_OWNER, PROJECT_MEMBER]) + def test_list_certificate_cross_project(self, role): + """ + Test steps: + 1. List the created all namespaced certificate present in + Test-certificate project by test-certificate project owner and the + users created by rbac test set up. + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + default_p_client = self.p_client + cert_count_by_role = p_client.list_certificate(name='cert-all-ns-valid') + cert_count_default = default_p_client.list_certificate( + name='cert-all-ns-valid') + assert len(cert_count_default) > 0, "{} couldn't to list the " \ + "certificate".format(role) + assert len(cert_count_by_role) == 0, "{} could list certificate in " \ + "'Test Certificate' project." + + @if_test_rbac + @pytest.mark.parametrize("role", [PROJECT_OWNER, PROJECT_MEMBER]) + def test_list_ns_certificate_cross_project(self, role): + """ + Test steps: + 1. List the created certificate present in Test-certificate project + by test-certificate project owner and the users created by rbac test + set up. + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + default_p_client = self.p_client + cert_count_by_role = p_client.list_namespaced_certificate( + name='cert-valid') + cert_count_default = default_p_client.list_namespaced_certificate( + name='cert-valid') + assert len(cert_count_default) > 0, "{} couldn't to list the " \ + "certificate".format(role) + assert len(cert_count_by_role) == 0, "{} could list certificate in " \ + "'Test Certificate' project." + + @if_test_rbac + @pytest.mark.parametrize("role", [PROJECT_OWNER, PROJECT_MEMBER]) + def test_edit_namespaced_certificate_cross_project(self, role): + """ + Test steps: + 1. Update the created certificate present in Test-certificate project + by the users created by rbac test set up. + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + certificate_valid = self.certificate_ssc + with pytest.raises(ApiError) as e: + p_client.update(certificate_valid, key=rancher_private_key, + certs=rancher_cert) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + @if_test_rbac + @pytest.mark.parametrize("role", [PROJECT_OWNER, PROJECT_MEMBER]) + def test_edit_certificate_cross_project(self, role): + """ + Test steps: + 1. Update the created certificate present in Test-certificate project + by the users created by rbac test set up. + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + certificate_valid = self.certificate_all_ns_ssc + with pytest.raises(ApiError) as e: + p_client.update(certificate_valid, key=rancher_private_key, + certs=rancher_cert) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + project, ns = create_project_and_ns(USER_TOKEN, cluster, + project_name="test-certificate", + ns_name="ns-certificate") + p_client = get_project_client_for_token(project, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + certificate_valid = p_client.create_namespaced_certificate( + name="cert-valid", key=rancher_private_key, certs=rancher_cert, + namespaceId=ns['name'] + ) + assert certificate_valid.issuer == 'R3' + + certificate_allns_valid = p_client.create_certificate( + name="cert-all-ns-valid", key=rancher_private_key, + certs=rancher_cert + ) + certificate_ssc = p_client.create_namespaced_certificate( + name="cert-ssc", key=rancher_ssc_private_key, certs=rancher_ssc_cert, + namespaceId=ns['name'] + ) + assert certificate_ssc.issuer == 'Rancher QA CA' + certificate_allns_ssc = p_client.create_certificate( + name="cert-all-ns-ssc", key=rancher_ssc_private_key, + certs=rancher_ssc_cert + ) + + nodes = client.list_node(clusterId=cluster.id).data + node_ip, node_id = None, None + for i in range(len(nodes)): + if nodes[i].worker: + node_ip = nodes[i].externalIpAddress + node_id = nodes[i].nodePoolId + break + aws_services = AmazonWebServices() + + aws_services.upsert_route_53_record_cname( + route_entry_53_1, node_ip, record_type='A', record_ttl=60) + aws_services.upsert_route_53_record_cname( + route_entry_53_2, node_ip, record_type='A', record_ttl=60) + + namespace["p_client"] = p_client + namespace["c_client"] = c_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = project + namespace["cert_valid"] = certificate_valid + namespace["cert_ssc"] = certificate_ssc + namespace["cert_allns_valid"] = certificate_allns_valid + namespace["cert_allns_ssc"] = certificate_allns_ssc + namespace["node_id"] = node_id + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + aws_services.upsert_route_53_record_cname( + route_entry_53_1, node_ip, action='DELETE', record_type='A', + record_ttl=60) + aws_services.upsert_route_53_record_cname( + route_entry_53_2, node_ip, action='DELETE', record_type='A', + record_ttl=60) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cis_scan.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cis_scan.py new file mode 100644 index 0000000..7cea712 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cis_scan.py @@ -0,0 +1,472 @@ +import pytest +import requests +import time +from rancher import ApiError +from lib.aws import AmazonWebServices +from .common import CLUSTER_MEMBER, configure_cis_requirements +from .common import CLUSTER_OWNER +from .common import CIS_SCAN_PROFILE +from .common import cluster_cleanup +from .common import get_user_client +from .common import get_user_client_and_cluster +from .common import get_custom_host_registration_cmd +from .common import get_project_client_for_token +from .common import get_client_for_token +from .common import get_cluster_by_name +from .common import if_test_rbac +from .common import PROJECT_OWNER +from .common import PROJECT_MEMBER +from .common import PROJECT_READ_ONLY +from .common import random_test_name +from .common import rbac_get_user_token_by_role +from .common import USER_TOKEN +from .common import validate_cluster_state +from .common import wait_for_cluster_node_count +from .test_rke_cluster_provisioning import HOST_NAME, \ + POD_SECURITY_POLICY_TEMPLATE, get_cis_rke_config # NOQA + +# Skipping all the tests from this module since CIS 1.5 and CIS 1.4 profile are not supported on latest k8s versions. +pytest.skip(allow_module_level=True) + +scan_results = { + "rke-cis-1.4": { + "permissive": {"pass": 63, "skip": 15}, + "hardened": {"pass": 78, "skip": 0}, + "not_applicable": 19, "total": 97, "fail": 0 + }, + "rke-cis-1.5": { + "permissive": {"pass": 58, "fail": 0, "skip": 14}, + "hardened": {"pass": 72, "fail": 0, "skip": 0}, + "not_applicable": 20, "total": 92, "fail": 0 + } +} +DEFAULT_TIMEOUT = 120 +cluster_detail = { + "cluster_14": None, "nodes_14": None, "name": None, + "cluster_15": None, "nodes_15": None +} + + +def test_cis_scan_run_scan_hardened_14(): + cluster = cluster_detail["cluster_14"] + scan_detail = run_scan(cluster, USER_TOKEN, "hardened") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "hardened") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + +def test_cis_scan_run_scan_hardened_15(): + """ + This will fail because of 2 tests which fail - 5.1.5 and 5.3.2 + :return: + """ + cluster = cluster_detail["cluster_15"] + scan_detail = run_scan(cluster, USER_TOKEN, "hardened", + scan_tool_version="rke-cis-1.5") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.5", "hardened") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + +def test_cis_scan_run_scan_permissive_14(): + client, cluster = get_user_client_and_cluster() + scan_detail = run_scan(cluster, USER_TOKEN, "permissive") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "permissive") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + +def test_cis_scan_run_scan_permissive_15(): + """ + This will fail because of 1 tests which fails - 5.1.5 + :return: + """ + client, cluster = get_user_client_and_cluster() + scan_detail = run_scan(cluster, USER_TOKEN, "permissive", + scan_tool_version="rke-cis-1.5") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.5", "permissive") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + +def test_cis_scan_skip_test_ui(): + client = get_user_client() + cluster = cluster_detail["cluster_14"] + # run security scan + scan_detail = run_scan(cluster, USER_TOKEN, "hardened") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "hardened") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + # get system project + system_project = cluster.projects(name="System")["data"][0] + system_project_id = system_project["id"] + print(system_project) + p_client = get_project_client_for_token(system_project, USER_TOKEN) + + # check config map is NOT generated for first scan + try: + p_client.list_configMap(projectId=system_project_id, + namespaceId="security-scan") + except ApiError as e: + assert e.error.status == 404, "Config Map is generated for first scan" + + # delete security-scan-cf config if present + security_scan_config = \ + p_client.list_configMap(projectId=system_project_id, + namespaceId="security-scan", + id="security-scan:security-scan-cfg", + name="security-scan-cfg") + print(security_scan_config) + if len(security_scan_config["data"]) != 0: + p_client.delete(security_scan_config["data"][0]) + # skip action as on UI + cm_data = {"config.json": "{\"skip\":{\"rke-cis-1.4\":[\"1.1.2\"]}}"} + p_client.create_configMap(projectId=system_project_id, + name="security-scan-cfg", + namespaceId="security-scan", + id="security-scan:security-scan-cfg", + data=cm_data) + # run security scan + scan_detail_2 = run_scan(cluster, USER_TOKEN, "hardened") + client.reload(scan_detail_2) + report_link = scan_detail_2["links"]["report"] + report = verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed - 1, + tests_skipped=tests_skipped + 1, + tests_failed=tests_failed, + tests_na=tests_na + ) + print(report["results"][0]["checks"][0]["state"]) + assert report["results"][0]["checks"][0]["state"] == "skip", \ + "State of the test is not as expected" + + """As part of clean up + delete security-scan-cf config + """ + security_scan_config = \ + p_client.list_configMap(projectId=system_project_id, + namespaceId="security-scan", + id="security-scan:security-scan-cfg", + name="security-scan-cfg") + print(security_scan_config) + if len(security_scan_config["data"]) != 0: + p_client.delete(security_scan_config["data"][0]) + + +def test_cis_scan_skip_test_api(): + client = get_user_client() + cluster = cluster_detail["cluster_14"] + # run security scan + scan_detail = run_scan(cluster, USER_TOKEN, "hardened") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "hardened") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + # skip test 1.1.3 + cluster.runSecurityScan(overrideSkip=["1.1.3"], + profile="hardened", + overrideBenchmarkVersion="rke-cis-1.4") + cluster = client.reload(cluster) + cluster_scan_report_id = cluster["currentCisRunName"] + print(cluster_scan_report_id) + scan_detail = wait_for_scan_active(cluster_scan_report_id, client) + wait_for_cis_pod_remove(cluster, cluster_scan_report_id) + report_link = scan_detail["links"]["report"] + report = verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed - 1, + tests_skipped=tests_skipped + 1, + tests_failed=tests_failed, + tests_na=tests_na + ) + assert report["results"][0]["checks"][1]["state"] == "skip", \ + "State of the test is not as expected" + + +def test_cis_scan_edit_cluster(): + aws_nodes = cluster_detail["nodes_14"] + client = get_user_client() + cluster = cluster_detail["cluster_14"] + # Add 2 etcd nodes to the cluster + for i in range(0, 2): + aws_node = aws_nodes[3 + i] + aws_node.execute_command("sudo sysctl -w vm.overcommit_memory=1") + aws_node.execute_command("sudo sysctl -w kernel.panic=10") + aws_node.execute_command("sudo sysctl -w kernel.panic_on_oops=1") + docker_run_cmd = get_custom_host_registration_cmd(client, + cluster, + ["etcd"], + aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 5) + validate_cluster_state(client, cluster, intermediate_state="updating") + cluster = client.reload(cluster) + + # run CIS Scan + scan_detail = run_scan(cluster, USER_TOKEN, "hardened") + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "hardened") + report = verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed - 2, + tests_skipped=tests_skipped, + tests_failed=tests_failed + 2, + tests_na=tests_na + ) + print(report["results"][3]["checks"][18]) + assert report["results"][3]["checks"][18]["state"] == "mixed" + + # edit nodes and run command + for i in range(0, 2): + aws_node = aws_nodes[3 + i] + aws_node.execute_command("sudo useradd etcd") + + # run CIS Scan + scan_detail = run_scan(cluster, USER_TOKEN, "hardened") + report_link = scan_detail["links"]["report"] + report = verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + print(report["results"][3]["checks"][18]["state"]) + assert report["results"][3]["checks"][18]["state"] == "pass" + + +@if_test_rbac +def test_rbac_run_scan_cluster_owner(): + client, cluster = get_user_client_and_cluster() + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + # run a permissive scan run + scan_detail = run_scan(cluster, user_token) + report_link = scan_detail["links"]["report"] + test_total, tests_passed, tests_skipped, tests_failed, tests_na = \ + get_scan_results("rke-cis-1.4", "permissive") + verify_cis_scan_report( + report_link, token=USER_TOKEN, + test_total=test_total, + tests_passed=tests_passed, + tests_skipped=tests_skipped, + tests_failed=tests_failed, + tests_na=tests_na + ) + + +@if_test_rbac +def test_rbac_run_scan_cluster_member(): + client, cluster = get_user_client_and_cluster() + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + run_scan(cluster, user_token, can_run_scan=False) + + +@if_test_rbac +def test_rbac_run_scan_project_owner(): + client, cluster = get_user_client_and_cluster() + user_token = rbac_get_user_token_by_role(PROJECT_OWNER) + run_scan(cluster, user_token, can_run_scan=False) + + +@if_test_rbac +def test_rbac_run_scan_project_member(): + client, cluster = get_user_client_and_cluster() + user_token = rbac_get_user_token_by_role(PROJECT_MEMBER) + run_scan(cluster, user_token, can_run_scan=False) + + +@if_test_rbac +def test_rbac_run_scan_project_read_only(): + client, cluster = get_user_client_and_cluster() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + run_scan(cluster, user_token, can_run_scan=False) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client = get_user_client() + # create cluster for running rke-cis-1.4 + cluster_14, aws_nodes_14 = create_cluster_cis() + cluster_detail["cluster_14"] = cluster_14 + cluster_detail["nodes_14"] = aws_nodes_14 + + # create cluster for running rke-cis-1.5 + cluster_15, aws_nodes_15 = create_cluster_cis("rke-cis-1.5") + cluster_detail["cluster_15"] = cluster_15 + cluster_detail["nodes_15"] = aws_nodes_15 + + def fin(): + cluster_cleanup(client, cluster_14, aws_nodes_14) + cluster_cleanup(client, cluster_15, aws_nodes_15) + + request.addfinalizer(fin) + + +def verify_cis_scan_report( + report_link, token, test_total, + tests_passed, tests_skipped, + tests_failed, tests_na): + head = {'Authorization': 'Bearer ' + token} + response = requests.get(report_link, verify=False, headers=head) + report = response.json() + assert report["total"] == test_total, \ + "Incorrect number of tests run" + assert report["pass"] == tests_passed, \ + "Incorrect number of tests passed" + assert report["fail"] == tests_failed, \ + "Incorrect number of failed tests" + assert report["skip"] == tests_skipped, \ + "Incorrect number of tests skipped" + assert report["notApplicable"] == tests_na, \ + "Incorrect number of tests marked Not Applicable" + return report + + +def run_scan(cluster, user_token, profile="permissive", + can_run_scan=True, scan_tool_version=CIS_SCAN_PROFILE): + client = get_client_for_token(user_token) + cluster = get_cluster_by_name(client, cluster.name) + if can_run_scan: + cluster.runSecurityScan(profile=profile, + overrideBenchmarkVersion=scan_tool_version) + cluster = client.reload(cluster) + cluster_scan_report_id = cluster["currentCisRunName"] + print(cluster_scan_report_id) + scan_detail = wait_for_scan_active(cluster_scan_report_id, client) + wait_for_cis_pod_remove(cluster, cluster_scan_report_id) + return scan_detail + else: + assert "runSecurityScan" not in list(cluster.actions.keys()), \ + "User has Run CIS Scan permission" + + +def wait_for_scan_active(cluster_scan_report_id, + client, + timeout=DEFAULT_TIMEOUT): + scan_detail_data = client.list_clusterScan(name=cluster_scan_report_id) + scan_detail = scan_detail_data.data[0] + # wait until scan is active + start = time.time() + state_scan = scan_detail["state"] + while state_scan != "pass" and state_scan != "fail": + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for state of scan report to get to active") + time.sleep(.5) + scan_detail_data = client.list_clusterScan(name=cluster_scan_report_id) + scan_detail = scan_detail_data.data[0] + state_scan = scan_detail["state"] + print(state_scan) + scan_detail_data = client.list_clusterScan(name=cluster_scan_report_id) + scan_detail = scan_detail_data.data[0] + return scan_detail + + +def wait_for_cis_pod_remove(cluster, + cluster_scan_report_id, + timeout=DEFAULT_TIMEOUT): + system_project = cluster.projects(name="System")["data"][0] + p_client = get_project_client_for_token(system_project, USER_TOKEN) + pod = p_client.list_pod(namespaceId="security-scan", + name="security-scan-runner-" + + cluster_scan_report_id) + start = time.time() + while len(pod["data"]) != 0: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for removal of security scan pod") + time.sleep(.5) + pod = p_client.list_pod(namespaceId="security-scan", + name="security-scan-runner-" + + cluster_scan_report_id) + time.sleep(.5) + + +def create_cluster_cis(scan_tool_version="rke-cis-1.4"): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 5, random_test_name(HOST_NAME)) + node_roles = [ + ["controlplane"], ["etcd"], ["worker"] + ] + rke_config_temp = get_cis_rke_config(profile=scan_tool_version) + client = get_user_client() + cluster = client.create_cluster( + name=random_test_name(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config_temp, + defaultPodSecurityPolicyTemplateId=POD_SECURITY_POLICY_TEMPLATE + ) + assert cluster.state == "provisioning" + # In the original design creates 5 nodes but only 3 are used + # the other 2 nodes are for test_cis_scan_edit_cluster + cluster = configure_cis_requirements(aws_nodes[:3], + scan_tool_version, + node_roles, + client, + cluster + ) + return cluster, aws_nodes + + +def get_scan_results(scan_tool_version, profile): + return scan_results[scan_tool_version]["total"], \ + scan_results[scan_tool_version][profile]["pass"], \ + scan_results[scan_tool_version][profile]["skip"], \ + scan_results[scan_tool_version]["fail"], \ + scan_results[scan_tool_version]["not_applicable"] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cli.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cli.py new file mode 100644 index 0000000..c6561ed --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cli.py @@ -0,0 +1,469 @@ +import ast +import os +import pytest + +from .test_rke_cluster_provisioning import (create_and_validate_custom_host, + cluster_cleanup) +from .cli_objects import RancherCli +from .common import (ADMIN_TOKEN, USER_TOKEN, CATTLE_TEST_URL, CLUSTER_NAME, + DATA_SUBDIR, get_admin_client, get_user_client, + get_user_client_and_cluster, random_str, + get_project_client_for_token) + +KNOWN_HOST = ast.literal_eval(os.environ.get('RANCHER_KNOWN_HOST', "False")) +if_test_multicluster = pytest.mark.skipif(ast.literal_eval( + os.environ.get('RANCHER_SKIP_MULTICLUSTER', "False")), + reason='Multi-Cluster tests are skipped in the interest of time/cost.') + +SYSTEM_CHART_URL = "https://git.rancher.io/system-charts" +SYSTEM_CHART_BRANCH = os.environ.get("RANCHER_SYSTEM_CHART_BRANCH", "dev") +OPENEBS_CHART = 'openebs' +OPENEBS_CHART_VERSION = '1.5.0' +OPENEBS_CHART_VERSION_UPGRADE = '1.6.0' +CHARTMUSEUM_CHART = 'chartmuseum' +CHARTMUSEUM_CHART_VERSION = '2.3.1' +APP_TIMEOUT = 120 +CATALOG_URL = "https://github.com/rancher/integration-test-charts.git" +BRANCH = "validation-tests" +CHARTMUSEUM_CHART_VERSION_CATALOG = 'latest' + +# Supplying default answers due to issue with multi-cluster app install: +# https://github.com/rancher/rancher/issues/25514 +MULTICLUSTER_APP_ANSWERS = { + "analytics.enabled": "true", + "defaultImage": "true", + "defaultPorts": "true", + "ndm.filters.excludePaths": "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md", + "ndm.filters.excludeVendors": "CLOUDBYT,OpenEBS", + "ndm.sparse.count": "0", + "ndm.sparse.enabled": "true", + "ndm.sparse.path": "/var/openebs/sparse", + "ndm.sparse.size": "10737418240", "policies.monitoring.enabled": "true" +} + + +def test_cli_context_switch(rancher_cli: RancherCli): + rancher_cli.log.info("Testing Context Switching") + clusters = rancher_cli.get_clusters() + client = get_user_client() + projects = client.list_project() + assert len(projects) > 0 + for project in projects: + rancher_cli.switch_context(project['id']) + cluster_name, project_name = rancher_cli.get_context() + assert any(cluster["id"] == project['clusterId'] + and cluster["name"] == cluster_name for cluster in clusters) + assert project_name == project['name'] + + +def test_cli_project_create(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Creating Projects") + initial_projects = rancher_cli.projects.get_current_projects() + project = rancher_cli.projects.create_project(use_context=False) + remove_cli_resource("project", project["id"]) + assert project is not None + assert len(initial_projects) == len( + rancher_cli.projects.get_current_projects()) - 1 + + +def test_cli_project_delete(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Deleting Projects") + initial_projects = rancher_cli.projects.get_current_projects() + project = rancher_cli.projects.create_project(use_context=False) + remove_cli_resource("project", project["id"]) + assert project is not None + rancher_cli.projects.delete_project(project["name"]) + assert len(initial_projects) == len( + rancher_cli.projects.get_current_projects()) + + +def test_cli_namespace_create(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Creating Namespaces") + p1 = rancher_cli.projects.create_project() + remove_cli_resource("project", p1["id"]) + namespace = rancher_cli.projects.create_namespace() + remove_cli_resource("namespace", namespace) + assert len(rancher_cli.projects.get_namespaces()) == 1 + assert "{}|active".format( + namespace) in rancher_cli.projects.get_namespaces() + + +def test_cli_namespace_move(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Moving Namespaces") + p1 = rancher_cli.projects.create_project() + remove_cli_resource("project", p1["id"]) + namespace = rancher_cli.projects.create_namespace() + remove_cli_resource("namespace", namespace) + assert len(rancher_cli.projects.get_namespaces()) == 1 + + p2 = rancher_cli.projects.create_project(use_context=False) + remove_cli_resource("project", p2["id"]) + rancher_cli.projects.move_namespace(namespace, p2["id"]) + assert len(rancher_cli.projects.get_namespaces()) == 0 + rancher_cli.projects.switch_context(p2["id"]) + assert len(rancher_cli.projects.get_namespaces()) == 1 + assert "{}|active".format( + namespace) in rancher_cli.projects.get_namespaces() + + +def test_cli_namespace_delete(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Deleting Namespaces") + p1 = rancher_cli.projects.create_project() + remove_cli_resource("project", p1["id"]) + namespace = rancher_cli.projects.create_namespace() + remove_cli_resource("namespace", namespace) + assert len(rancher_cli.projects.get_namespaces()) == 1 + assert "{}|active".format( + namespace) in rancher_cli.projects.get_namespaces() + deleted = rancher_cli.projects.delete_namespace(namespace) + assert deleted + + +def test_cli_app_install(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Upgrading Apps") + initial_app = rancher_cli.apps.install( + OPENEBS_CHART, "openebs", version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("apps", initial_app["id"]) + assert initial_app["state"] == "active" + assert initial_app["version"] == OPENEBS_CHART_VERSION + + +def test_cli_app_values_install(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Upgrading Apps") + initial_app = rancher_cli.apps.install( + CHARTMUSEUM_CHART, random_str(), version=CHARTMUSEUM_CHART_VERSION, + timeout=APP_TIMEOUT, values=DATA_SUBDIR + "/appvalues.yaml") + remove_cli_resource("apps", initial_app["id"]) + assert initial_app["state"] == "active" + assert initial_app["version"] == CHARTMUSEUM_CHART_VERSION + + +def test_cli_app_upgrade(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Rolling Back Apps") + initial_app = rancher_cli.apps.install( + OPENEBS_CHART, "openebs", version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("apps", initial_app["id"]) + assert initial_app["version"] == OPENEBS_CHART_VERSION + upgraded_app = rancher_cli.apps.upgrade( + initial_app, version=OPENEBS_CHART_VERSION_UPGRADE) + assert upgraded_app["state"] == "active" + assert upgraded_app["version"] == OPENEBS_CHART_VERSION_UPGRADE + + +def test_cli_app_rollback(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Deleting Apps") + initial_app = rancher_cli.apps.install( + OPENEBS_CHART, "openebs", version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("apps", initial_app["id"]) + assert initial_app["version"] == OPENEBS_CHART_VERSION + upgraded_app = rancher_cli.apps.upgrade( + initial_app, version=OPENEBS_CHART_VERSION_UPGRADE) + assert upgraded_app["version"] == OPENEBS_CHART_VERSION_UPGRADE + rolled_back_app = rancher_cli.apps.rollback(upgraded_app, + OPENEBS_CHART_VERSION) + assert rolled_back_app["state"] == "active" + assert rolled_back_app["version"] == OPENEBS_CHART_VERSION + + +def test_cli_app_delete(rancher_cli: RancherCli): + rancher_cli.log.info("Testing Deleting Apps") + initial_app = rancher_cli.apps.install( + OPENEBS_CHART, "openebs", version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + deleted = rancher_cli.apps.delete(initial_app) + assert deleted + + +def test_cli_app_install_local_dir(remove_cli_resource, rancher_cli: RancherCli): + rancher_cli.log.info("Testing Installing of an App from Local directory") + initial_app = rancher_cli.apps.install_local_dir( + CATALOG_URL, BRANCH, CHARTMUSEUM_CHART, + version=CHARTMUSEUM_CHART_VERSION_CATALOG, timeout=APP_TIMEOUT) + remove_cli_resource("apps", initial_app["id"]) + assert initial_app["state"] == "active" + + +@if_test_multicluster +def test_cli_multiclusterapp_install(custom_cluster, remove_cli_resource, + rancher_cli: RancherCli): + rancher_cli.log.info("Testing Installing Multi-Cluster Apps") + # Get list of projects to use and ensure that it is 2 or greater + client = get_admin_client() + projects = client.list_project() + targets = [] + for project in projects: + if project["name"] == "Default": + rancher_cli.switch_context(project['id']) + cluster_name, project_name = rancher_cli.get_context() + if cluster_name in [custom_cluster.name, CLUSTER_NAME]: + rancher_cli.log.debug("Using cluster: %s", cluster_name) + targets.append(project["id"]) + assert len(targets) > 1 + + initial_app = rancher_cli.mcapps.install( + OPENEBS_CHART, targets=targets, role="cluster-owner", + values=MULTICLUSTER_APP_ANSWERS, version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("mcapps", initial_app["name"]) + assert initial_app["state"] == "active" + assert initial_app["version"] == OPENEBS_CHART_VERSION + assert len(initial_app["targets"]) == len(targets) + for target in initial_app["targets"]: + assert target["state"] == "active" + assert target["version"] == OPENEBS_CHART_VERSION + + +@if_test_multicluster +def test_cli_multiclusterapp_upgrade(custom_cluster, remove_cli_resource, + rancher_cli: RancherCli): + rancher_cli.log.info("Testing Upgrading Multi-Cluster Apps") + # Get list of projects to use and ensure that it is 2 or greater + client = get_admin_client() + projects = client.list_project() + targets = [] + for project in projects: + if project["name"] == "Default": + rancher_cli.switch_context(project['id']) + cluster_name, project_name = rancher_cli.get_context() + if cluster_name in [custom_cluster.name, CLUSTER_NAME]: + rancher_cli.log.debug("Using cluster: %s", cluster_name) + targets.append(project["id"]) + assert len(targets) > 1 + + initial_app = rancher_cli.mcapps.install( + OPENEBS_CHART, targets=targets, role="cluster-owner", + values=MULTICLUSTER_APP_ANSWERS, version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("mcapps", initial_app["name"]) + assert initial_app["version"] == OPENEBS_CHART_VERSION + + upgraded_app = rancher_cli.mcapps.upgrade( + initial_app, version=OPENEBS_CHART_VERSION_UPGRADE, + timeout=APP_TIMEOUT) + assert upgraded_app["state"] == "active" + assert upgraded_app["version"] == OPENEBS_CHART_VERSION_UPGRADE + assert upgraded_app["id"] == initial_app["id"] + assert len(upgraded_app["targets"]) == len(targets) + for target in upgraded_app["targets"]: + assert target["state"] == "active" + assert target["version"] == OPENEBS_CHART_VERSION_UPGRADE + + +@if_test_multicluster +def test_cli_multiclusterapp_rollback(custom_cluster, remove_cli_resource, + rancher_cli: RancherCli): + rancher_cli.log.info("Testing Rolling Back Multi-Cluster Apps") + # Get list of projects to use and ensure that it is 2 or greater + client = get_admin_client() + projects = client.list_project() + targets = [] + for project in projects: + if project["name"] == "Default": + rancher_cli.switch_context(project['id']) + cluster_name, project_name = rancher_cli.get_context() + if cluster_name in [custom_cluster.name, CLUSTER_NAME]: + rancher_cli.log.debug("Using cluster: %s", cluster_name) + targets.append(project["id"]) + assert len(targets) > 1 + + initial_app = rancher_cli.mcapps.install( + OPENEBS_CHART, targets=targets, role="cluster-owner", + values=MULTICLUSTER_APP_ANSWERS, version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + remove_cli_resource("mcapps", initial_app["name"]) + assert initial_app["version"] == OPENEBS_CHART_VERSION + upgraded_app = rancher_cli.mcapps.upgrade( + initial_app, version=OPENEBS_CHART_VERSION_UPGRADE, + timeout=APP_TIMEOUT) + assert upgraded_app["version"] == OPENEBS_CHART_VERSION_UPGRADE + + rolled_back_app = rancher_cli.mcapps.rollback( + upgraded_app["name"], initial_app["revision"], timeout=APP_TIMEOUT) + assert rolled_back_app["state"] == "active" + assert rolled_back_app["version"] == OPENEBS_CHART_VERSION + assert rolled_back_app["id"] == upgraded_app["id"] + assert len(rolled_back_app["targets"]) == len(targets) + for target in rolled_back_app["targets"]: + assert target["state"] == "active" + assert target["version"] == OPENEBS_CHART_VERSION + + +@if_test_multicluster +def test_cli_multiclusterapp_delete(custom_cluster, remove_cli_resource, + rancher_cli: RancherCli): + rancher_cli.log.info("Testing Deleting Multi-Cluster Apps") + # Get list of projects to use and ensure that it is 2 or greater + client = get_admin_client() + projects = client.list_project() + targets = [] + for project in projects: + if project["name"] == "Default": + rancher_cli.switch_context(project['id']) + cluster_name, project_name = rancher_cli.get_context() + if cluster_name in [custom_cluster.name, CLUSTER_NAME]: + rancher_cli.log.debug("Using cluster: %s", cluster_name) + targets.append(project["id"]) + assert len(targets) > 1 + + initial_app = rancher_cli.mcapps.install( + OPENEBS_CHART, targets=targets, role="cluster-owner", + values=MULTICLUSTER_APP_ANSWERS, version=OPENEBS_CHART_VERSION, + timeout=APP_TIMEOUT) + assert initial_app["version"] == OPENEBS_CHART_VERSION + deleted, apps_deleted = rancher_cli.mcapps.delete(initial_app) + assert deleted + assert apps_deleted + + +def test_cli_catalog(admin_cli: RancherCli): + admin_cli.log.info("Testing Creating and Deleting Catalogs") + admin_cli.login(CATTLE_TEST_URL, ADMIN_TOKEN) + catalog = admin_cli.catalogs.add(SYSTEM_CHART_URL, + branch=SYSTEM_CHART_BRANCH) + assert catalog is not None + deleted = admin_cli.catalogs.delete(catalog["name"]) + assert deleted + + +@if_test_multicluster +def test_cluster_removal(custom_cluster, admin_cli: RancherCli): + admin_cli.log.info("Testing Cluster Removal") + deleted = admin_cli.clusters.delete(custom_cluster.name) + assert deleted + + +def test_inspection(rancher_cli: RancherCli): + # Test inspect on the default project used for cli tests + # Validate it has the expected clusterid, id, type, and active state + rancher_cli.log.info("Testing Inspect Resource") + resource = rancher_cli.inspect( + "project", rancher_cli.default_project["id"], + format="{{.clusterId}}|{{.id}}|{{.type}}|{{.state}}") + assert resource is not None + resource_arr = resource.split("|") + assert resource_arr[0] == rancher_cli.default_project["clusterId"] + assert resource_arr[1] == rancher_cli.default_project["id"] + assert resource_arr[2] == "project" + assert resource_arr[3] == "active" + + +def test_ps(custom_workload, rancher_cli: RancherCli): + rancher_cli.log.info("Testing rancher ps") + # Deploy a workload and validate that the ps command shows it in the + # correct namespace with the correct name + rancher_cli.switch_context(rancher_cli.DEFAULT_CONTEXT) + ps = rancher_cli.ps() + expected_value = "{}|{}|nginx|2".format( + rancher_cli.default_namespace, custom_workload.name) + assert expected_value in ps.splitlines() + + +def test_kubectl(custom_workload, rancher_cli: RancherCli): + rancher_cli.log.info("Testing kubectl commands from the CLI") + rancher_cli.switch_context(rancher_cli.DEFAULT_CONTEXT) + jsonpath = "-o jsonpath='{.spec.template.spec.containers[0].image}'" + result = rancher_cli.kubectl("get deploy -n {} {} {}".format( + rancher_cli.default_namespace, custom_workload.name, jsonpath)) + assert result == "nginx" + + +# Note this expects nodes not to be Windows due to usage of ifconfig.me +@pytest.mark.skip(reason="Fails in Jenkins") +def test_ssh(rancher_cli: RancherCli): + rancher_cli.log.info("Testing ssh into nodes.") + failures = [] + rancher_cli.switch_context(rancher_cli.DEFAULT_CONTEXT) + nodes = rancher_cli.nodes.get() + rancher_cli.log.debug("Nodes is: {}".format(nodes)) + + is_jenkins = False + if os.environ.get("RANCHER_IS_JENKINS", None): + is_jenkins = True + for node in nodes: + ip = rancher_cli.nodes.ssh(node, "curl -s ifconfig.me", + known=KNOWN_HOST, is_jenkins=is_jenkins) + if node["ip"] != ip: + failures.append(node["ip"]) + assert failures == [] + + +@pytest.fixture(scope='module') +def custom_workload(rancher_cli): + client, cluster = get_user_client_and_cluster() + project = client.list_project(name=rancher_cli.default_project["name"], + clusterId=cluster.id).data[0] + p_client = get_project_client_for_token(project, USER_TOKEN) + workload = p_client.create_workload( + name=random_str(), + namespaceId=rancher_cli.default_namespace, + scale=2, + containers=[{ + 'name': 'one', + 'image': 'nginx', + }]) + return workload + + +@pytest.fixture(scope='module') +def custom_cluster(request, rancher_cli): + rancher_cli.log.info("Creating cluster in AWS to test CLI actions that " + "require more than one cluster. Please be patient, " + "as this takes some time...") + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + cluster, aws_nodes = create_and_validate_custom_host( + node_roles, random_cluster_name=True) + + def fin(): + cluster_cleanup(get_admin_client(), cluster, aws_nodes) + request.addfinalizer(fin) + return cluster + + +@pytest.fixture +def admin_cli(request, rancher_cli) -> RancherCli: + """ + Login occurs at a global scope, so need to ensure we log back in as the + user in a finalizer so that future tests have no issues. + """ + rancher_cli.login(CATTLE_TEST_URL, ADMIN_TOKEN) + + def fin(): + rancher_cli.login(CATTLE_TEST_URL, USER_TOKEN) + request.addfinalizer(fin) + return rancher_cli + + +@pytest.fixture(scope='module', autouse="True") +def rancher_cli(request) -> RancherCli: + client, cluster = get_user_client_and_cluster() + project_id = client.list_project(name='Default', + clusterId=cluster.id).data[0]["id"] + cli = RancherCli(CATTLE_TEST_URL, USER_TOKEN, project_id) + + def fin(): + cli.cleanup() + request.addfinalizer(fin) + return cli + + +@pytest.fixture +def remove_cli_resource(request, rancher_cli): + """Remove a resource after a test finishes even if the test fails. + + How to use: + pass this function as an argument of your testing function, + then call this function with the resource type and its id + as arguments after creating any new resource + """ + def _cleanup(resource, r_id): + def clean(): + rancher_cli.switch_context(rancher_cli.DEFAULT_CONTEXT) + rancher_cli.log.info("Cleaning up {}: {}".format(resource, r_id)) + rancher_cli.run_command("{} delete {}".format(resource, r_id), + expect_error=True) + request.addfinalizer(clean) + return _cleanup diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cluster_templates.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cluster_templates.py new file mode 100644 index 0000000..4f42eb3 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_cluster_templates.py @@ -0,0 +1,1131 @@ +import copy +import os +import pytest +import requests +from rancher import ApiError +from .common import * # NOQA +from .test_monitoring import cluster_query_template +from .test_monitoring import validate_cluster_graph +from .test_monitoring import C_MONITORING_ANSWERS +from .test_monitoring import CLUSTER_MONITORING_APP +from .test_monitoring import MONITORING_OPERATOR_APP +from .test_monitoring import MONITORING_TEMPLATE_ID +from .test_monitoring import MONITORING_VERSION +from .test_monitoring import validate_cluster_monitoring_apps +from .test_rbac import create_user +from .test_rke_cluster_provisioning import engine_install_url + + +RANCHER_S3_BUCKETNAME = os.environ.get('RANCHER_S3_BUCKETNAME', "None") +RANCHER_S3_ENDPOINT = os.environ.get('RANCHER_S3_ENDPOINT', "None") +AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', "None") +AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', "None") + + +user_token = {"stduser_with_createrketemplate_role": {"user": None, + "token": None}, + "standard_user": {"user": None, "token": None}} + + +@pytest.fixture(scope='module', autouse="True") +def setup(request): + + client = get_admin_client() + + # create users + user_token["stduser_with_createrketemplate_role"]["user"], \ + user_token["stduser_with_createrketemplate_role"]["token"] = \ + create_user(client) + user_token["standard_user"]["user"], \ + user_token["standard_user"]["token"] = create_user(client) + + stduser_with_createrketemplate_role_id = \ + user_token["stduser_with_createrketemplate_role"]["user"].id + + # Add clustertemplates-create global role binding to the standard user + client.create_global_role_binding( + globalRoleId="clustertemplates-create", + subjectKind="User", + userId=stduser_with_createrketemplate_role_id) + + +def get_k8s_versionlist(): + + # Get the list of K8s version supported by the rancher server + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + ADMIN_TOKEN} + json_data = { + 'responseType': 'json' + } + settings_url = CATTLE_TEST_URL + "/v3/settings/k8s-versions-current" + response = requests.get(settings_url, json=json_data, + verify=False, headers=headers) + json_response = (json.loads(response.content)) + k8sversionstring = json_response['value'] + k8sversionlist = k8sversionstring.split(",") + assert len(k8sversionlist) > 1 + return k8sversionlist + + +def get_cluster_config(k8sversion, enableMonitoring="false"): + + rke_config = getRKEConfig(k8sversion) + cluster_config = { + "dockerRootDir": "/var/lib/docker123", + "enableClusterAlerting": "false", + "enableClusterMonitoring": enableMonitoring, + "enableNetworkPolicy": "false", + "type": "clusterSpecBase", + "localClusterAuthEndpoint": { + "enabled": "true", + "type": "localClusterAuthEndpoint" + }, + "rancherKubernetesEngineConfig": rke_config + } + return cluster_config + + +def get_cisscan_enabled_clusterconfig(k8sversion): + rke_config = getRKEConfig(k8sversion) + + cluster_config = { + "dockerRootDir": "/var/lib/docker123", + "enableClusterAlerting": "false", + "enableClusterMonitoring": "false", + "enableNetworkPolicy": "false", + "type": "clusterSpecBase", + "localClusterAuthEndpoint": { + "enabled": "true", + "type": "localClusterAuthEndpoint" + }, + "scheduledClusterScan": { + "enabled": "true", + "scanConfig": { + "cisScanConfig": { + "debugMaster": "false", + "debugWorker": "false", + "overrideBenchmarkVersion": CIS_SCAN_PROFILE, + "overrideSkip": "None", + "profile": "permissive", + "type": "/v3/schemas/cisScanConfig" + }, + "type": "/v3/schemas/clusterScanConfig" + }, + "scheduleConfig": { + "cronSchedule": "0 */1 * * *", + "retention": 24, + "type": "/v3/schemas/scheduledClusterScanConfig" + }, + "type": "/v3/schemas/scheduledClusterScan" + }, + "rancherKubernetesEngineConfig": rke_config + } + return cluster_config + + +def test_cluster_template_create_with_questions(): + + # Create a cluster template and revision with questions and create a + # cluster with the revision + k8sversionlist = get_k8s_versionlist() + cluster_config = get_cluster_config(k8sversionlist[0]) + + questions = [{ + "variable": "rancherKubernetesEngineConfig.kubernetesVersion", + "required": "true", + "type": "string", + "default": k8sversionlist[0] + }, + { + "variable": "rancherKubernetesEngineConfig.network.plugin", + "required": "true", + "type": "string", + "default": "canal" + }, + { + "variable": "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.bucketName", + "required": "true", + "type": "string", + "default": "" + }, + { + "variable": "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.endpoint", + "required": "true", + "type": "string", + "default": "" + + }, + { + "variable": "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.accessKey", + "required": "true", + "type": "string", + "default": "" + }, + { + "variable": "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.secretKey", + "required": "true", + "type": "string", + "default": "" + }] + + answers = { + "values": { + "rancherKubernetesEngineConfig.kubernetesVersion": + k8sversionlist[1], + "rancherKubernetesEngineConfig.network.plugin": "flannel", + "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.bucketName": RANCHER_S3_BUCKETNAME, + "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.endpoint": RANCHER_S3_ENDPOINT, + "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.accessKey": AWS_ACCESS_KEY_ID, + "rancherKubernetesEngineConfig.services.etcd.backupConfig." + "s3BackupConfig.secretKey": AWS_SECRET_ACCESS_KEY + } + } + + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + cluster_template = \ + standard_user_client.create_cluster_template( + name=random_test_name("template"), + description="test-template") + clusterTemplateId = cluster_template.id + + revision_name = random_test_name("revision") + cluster_template_revision = \ + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config, + clusterTemplateId=clusterTemplateId, + enabled="true", questions=questions) + time.sleep(2) + cluster_template_revision = standard_user_client.reload( + cluster_template_revision) + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + cluster = create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=cluster_template_revision.id, + answers=answers, userToken=userToken) + + # Verify that the cluster's applied spec has the parameters set as expected + assert cluster.appliedSpec.dockerRootDir == "/var/lib/docker123" + assert cluster.appliedSpec.localClusterAuthEndpoint.enabled is True + assert cluster.appliedSpec.rancherKubernetesEngineConfig.\ + kubernetesVersion == k8sversionlist[1] + assert cluster.appliedSpec.rancherKubernetesEngineConfig.services.etcd.\ + backupConfig.s3BackupConfig.bucketName == RANCHER_S3_BUCKETNAME + assert cluster.appliedSpec.rancherKubernetesEngineConfig.services.\ + etcd.backupConfig.s3BackupConfig.endpoint == RANCHER_S3_ENDPOINT + assert cluster.appliedSpec.rancherKubernetesEngineConfig.services.etcd.\ + backupConfig.s3BackupConfig.accessKey == AWS_ACCESS_KEY_ID + assert cluster.appliedSpec.rancherKubernetesEngineConfig.services.etcd.\ + backupConfig.s3BackupConfig.type == "/v3/schemas/s3BackupConfig" + assert cluster.appliedSpec.rancherKubernetesEngineConfig.network.plugin ==\ + "flannel" + + check_cluster_version(cluster, k8sversionlist[1]) + + # Verify flannel pod in the kube-system namespace + cmd = "get pods -l k8s-app=flannel --namespace kube-system" + pod_result = execute_kubectl_cmd(cmd) + + assert (len(["items"])) == 1 + + for pod in pod_result["items"]: + print(pod["metadata"]["name"]) + assert "flannel" in (pod["metadata"]["name"]) + + # Perform Backup + backup = cluster.backupEtcd() + backupname = backup['metadata']['name'] + etcdbackups = cluster.etcdBackups(name=backupname) + etcdbackupdata = etcdbackups['data'] + s3backupconfig = etcdbackupdata[0]['backupConfig']['s3BackupConfig'] + assert s3backupconfig['type'] == '/v3/schemas/s3BackupConfig' + backupId = etcdbackupdata[0]['id'] + print("BackupId", backupId) + wait_for_backup_to_active(cluster, backupname) + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_create_edit_adminuser(): + + # Create an admin client . As an admin, create a RKE template and + # revisions R1 and R2. Create a cluster using R1. + # Edit and change revision to R2 + + cluster_template_create_edit(ADMIN_TOKEN) + + +def test_cluster_template_create_edit_stduser(): + # Create a standard user client . As a standard user, create a RKE + # template and revisions R1 and R2. Create a cluster using R1. + # Edit and change revision to R2 + + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + cluster_template_create_edit(userToken) + + +def test_cluster_template_add_owner(): + + # This test case tests the owner member role of the cluster template + k8sversionlist = get_k8s_versionlist() + cluster_config1 = get_cluster_config(k8sversionlist[0]) + cluster_config2 = get_cluster_config(k8sversionlist[1]) + client = get_admin_client() + + # As an Admin, create a cluster template and update the members + # list with the new user as owner + template_name = random_test_name("template") + cluster_template = client.create_cluster_template( + name=template_name, description="test-template") + + principalid = user_token["standard_user"]["user"]["principalIds"] + members = [{ + "type": "member", + "accessType": "owner", + "userPrincipalId": principalid + }] + + cluster_template = client.update(cluster_template, + name=template_name, + members=members) + standard_user_client = \ + get_client_for_token(user_token["standard_user"]["token"]) + # As an owner of the template, create a revision using the template + # and also create a cluster using the template revision + revision_name = random_test_name("revision1") + cluster_template_revision = \ + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision = standard_user_client.reload( + cluster_template_revision) + userToken = user_token["standard_user"]["token"] + cluster = create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=cluster_template_revision.id, + userToken=userToken) + + # As an admin, create another template and a revision. + cluster_template_new = client.create_cluster_template( + name="new_template", description="newtest-template") + newrevision_name = random_test_name("revision2") + cluster_template_newrevision = \ + client.create_cluster_template_revision( + name=newrevision_name, + clusterConfig=cluster_config2, + clusterTemplateId=cluster_template_new.id) + time.sleep(2) + cluster_template_newrevision = client.reload( + cluster_template_newrevision) + # Verify that the existing standard user cannot create a new revision using + # this template + with pytest.raises(ApiError) as e: + standard_user_client.create_cluster_template_revision( + name=random_test_name("userrevision"), + clusterConfig=cluster_config2, + clusterTemplateId=cluster_template_new.id) + + print(e.value.error.status) + print(e.value.error.code) + assert e.value.error.status == 404 + assert e.value.error.code == "NotFound" + + userToken = user_token["standard_user"]["token"] + + # Verify that the existing standard user cannot create a cluster + # using the new revision + with pytest.raises(ApiError) as e: + create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=cluster_template_newrevision.id, + userToken=userToken) + print(e) + assert e.value.error.status == 404 + assert e.value.error.code == "NotFound" + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_add_readonly_member(): + + # This test case tests a read-only member role of the cluster template + k8sversionlist = get_k8s_versionlist() + cluster_config1 = get_cluster_config(k8sversionlist[0]) + client = get_admin_client() + + # As an Admin, create a cluster template and update the members + # list with the new standard user as read-only user + template_name = random_test_name("usertemplate") + cluster_template = client.create_cluster_template( + name=template_name, description="test-template") + + principalid = user_token["standard_user"]["user"]["principalIds"] + members = [{ + "type": "member", + "accessType": "read-only", + "userPrincipalId": principalid + }] + + cluster_template = client.update(cluster_template, + name=template_name, members=members) + + revision_name = random_test_name("revision1") + cluster_template_revision1 = client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + + time.sleep(2) + cluster_template_revision1 = client.reload( + cluster_template_revision1) + + standard_user_client = \ + get_client_for_token(user_token["standard_user"]["token"]) + + # As a read-only member of the rke template, verify that + # adding another revision to the template fails + revision_name = "userrevision" + with pytest.raises(ApiError) as e: + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + userToken = user_token["standard_user"]["token"] + + # Verify that the read-only user can create a cluster with the existing + # template revision + cluster = create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=cluster_template_revision1.id, + userToken=userToken) + + # As an admin, create another template and a revision. + cluster_template_new = client.create_cluster_template( + name="new_template", description="newtest-template") + revision_name = random_test_name("revision2") + cluster_template_newrevision = \ + client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template_new.id) + + # Verify that the existing standard user cannot create a cluster + # using the new revision + with pytest.raises(ApiError) as e: + create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=cluster_template_newrevision.id, + userToken=userToken) + print(e) + assert e.value.error.status == 404 + assert e.value.error.code == "NotFound" + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_export(): + + # Create a DO cluster using rke config. Save a rketemplate from this + # cluster (with template name and revision V1). + # Create another cluster using the cluster template revision V1 + + k8sversionlist = get_k8s_versionlist() + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + + rke_config = getRKEConfig(k8sversionlist[0]) + + cluster_name = random_test_name("test-auto-export") + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + cluster = create_node_cluster(standard_user_client, cluster_name, + rancherKubernetesEngineConfig=rke_config, + userToken=userToken) + + # Export a Template + cluster.saveAsTemplate(clusterTemplateName="testnewrketemplate", + clusterTemplateRevisionName="v1") + cluster = standard_user_client.reload(cluster) + templateid = cluster.clusterTemplateId + revisionid = cluster.clusterTemplateRevisionId + + # Create a new cluster using the template revision just exported + newcluster = create_node_cluster( + standard_user_client, name=random_test_name("test-auto"), + clusterTemplateRevisionId=revisionid, userToken=userToken) + newcluster = standard_user_client.reload(newcluster) + assert newcluster.appliedSpec.clusterTemplateId == templateid + assert newcluster.appliedSpec.clusterTemplateRevisionId == revisionid + + cluster_cleanup(standard_user_client, cluster) + cluster_cleanup(standard_user_client, newcluster) + + +def test_cluster_template_enforcement_on_admin(request): + + # As an admin turn ON enforcement and ensure that admin can create clusters + # using rke config and also using rke template + try: + enforcement_settings_url = CATTLE_TEST_URL + \ + "/v3/settings/cluster-template-enforcement" + data_test = { + "name": "cluster-template-enforcement", + "value": "true" + } + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + ADMIN_TOKEN} + response = requests.put(enforcement_settings_url, json=data_test, + verify=False, headers=headers) + print(response.content) + k8sversionlist = get_k8s_versionlist() + cluster_config1 = get_cluster_config(k8sversionlist[0]) + rke_config = getRKEConfig(k8sversionlist[0]) + + # Verify creating cluster using rkeconfig succeeds + + client = get_admin_client() + cluster_name = random_test_name("test-auto-rkeconfig") + + rkecluster = \ + create_node_cluster(client, cluster_name, + rancherKubernetesEngineConfig=rke_config, + userToken=ADMIN_TOKEN) + + # Verify creating cluster using rke template succeeds + cluster_template = client.create_cluster_template( + name=random_test_name("template"), description="test-template") + revision_name = random_test_name("revision1") + cluster_template_revision1 = client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision1 = client.reload( + cluster_template_revision1) + cluster_name = random_test_name("test-auto") + cluster = create_node_cluster( + client, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision1.id, + userToken=ADMIN_TOKEN) + check_cluster_version(cluster, k8sversionlist[0]) + + # Reset the enforcement flag to false + finally: + + data_test = { + "name": "cluster-template-enforcement", + "value": "false" + } + requests.put(enforcement_settings_url, json=data_test, + verify=False, headers=headers) + + cluster_cleanup(client, cluster) + cluster_cleanup(client, rkecluster) + + +def test_cluster_template_enforcement_on_stduser(): + + # As an admin turn ON enforcement and ensure that standandard users + # can create clusters only using rke template. Creating clusters using + # regular rke config should not be allowed + + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + k8sversionlist = get_k8s_versionlist() + cluster_config1 = get_cluster_config(k8sversionlist[0]) + rke_config = getRKEConfig(k8sversionlist[0]) + try: + enforcement_settings_url = CATTLE_TEST_URL + \ + "/v3/settings/cluster-template-enforcement" + data_test = { + "name": "cluster-template-enforcement", + "value": "true" + } + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + ADMIN_TOKEN} + response = requests.put(enforcement_settings_url, json=data_test, + verify=False, headers=headers) + print(response.content) + + # Verify creating cluster using rke template succeeds + + cluster_template = standard_user_client.create_cluster_template( + name=random_test_name("template"), description="test-template") + revision_name = random_test_name("revision1") + + cluster_template_revision1 = \ + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision1 = standard_user_client.reload( + cluster_template_revision1) + cluster_name = random_test_name("test-auto") + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + cluster = create_node_cluster( + standard_user_client, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision1.id, + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[0]) + + # Verify creating cluster using rkeconfig fails. API returns error as: + # "MissingRequired : A clusterTemplateRevision to create a cluster" + + cluster_name = random_test_name("test-auto-rkeconfig") + with pytest.raises(ApiError) as e: + create_node_cluster(standard_user_client, cluster_name, + rancherKubernetesEngineConfig=rke_config, + userToken=userToken) + print(e) + assert e.value.error.status == 422 + assert e.value.error.code == "MissingRequired" + + # Reset the enforcement flag to false + finally: + data_test = { + "name": "cluster-template-enforcement", + "value": "false" + } + requests.put(enforcement_settings_url, json=data_test, + verify=False, headers=headers) + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_create_with_cisscan_enabled(): + + k8sversionlist = get_k8s_versionlist() + # Obtain cluster config with cisscan enabled + cluster_config = get_cisscan_enabled_clusterconfig(k8sversionlist[0]) + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + + # Create a cluster template + cluster_template = standard_user_client.create_cluster_template( + name=random_test_name("template"), description="cis-enabled-template") + revision_name = random_test_name("revision1") + # Create a cluster template revision with the cis enabled cluster config + cluster_template_revision = \ + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision = standard_user_client.reload( + cluster_template_revision) + cluster_name = random_test_name("test-auto") + # Create a cluster using the cluster template revision + cluster = create_node_cluster( + standard_user_client, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision.id, + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[0]) + + # Verify that the cluster's applied spec has the cis scan parameters + # set as expected + assert cluster.appliedSpec. \ + scheduledClusterScan.enabled == True + assert cluster.appliedSpec.scheduledClusterScan.\ + scanConfig.type == "/v3/schemas/clusterScanConfig" + assert cluster.appliedSpec. \ + scheduledClusterScan.scanConfig.\ + cisScanConfig.overrideBenchmarkVersion == "rke-cis-1.4" + assert cluster.appliedSpec. \ + scheduledClusterScan.scanConfig.cisScanConfig.profile == "permissive" + assert cluster.appliedSpec.scheduledClusterScan.scheduleConfig.\ + cronSchedule == "0 */1 * * *" + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_create_with_monitoring(): + + k8sversionlist = get_k8s_versionlist() + # Obtain cluster config with monitoring enabled + cluster_config = get_cluster_config(k8sversionlist[0], + enableMonitoring="true") + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + + # Create a cluster template + cluster_template = standard_user_client.\ + create_cluster_template(name=random_test_name("template"), + description="test-template") + revision_name = random_test_name("revision1") + # Create cluster template revision with monitoring enabled cluster config + cluster_template_revision = \ + standard_user_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision = standard_user_client.reload( + cluster_template_revision) + cluster_name = random_test_name("test-auto") + # Create a cluster using the cluster template revision + cluster = create_node_cluster( + standard_user_client, name=cluster_name, nodecount=3, nodesize="s-4vcpu-8gb", + clusterTemplateRevisionId=cluster_template_revision.id, + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[0]) + assert cluster.appliedSpec.enableClusterMonitoring == True + + # Verify the monitoring apps are deployed and active + system_project = \ + standard_user_client.list_project(clusterId=cluster.id, + name="System").data[0] + sys_proj_client = get_project_client_for_token(system_project, USER_TOKEN) + wait_for_app_to_active(sys_proj_client, CLUSTER_MONITORING_APP, 1000) + wait_for_app_to_active(sys_proj_client, MONITORING_OPERATOR_APP, 1000) + # wait for all graphs to be available + time.sleep(60 * 3) + cluster_monitoring_obj = standard_user_client.list_clusterMonitorGraph() + # generate the request payload + query1 = copy.deepcopy(cluster_query_template) + query1["obj"] = cluster_monitoring_obj + query1["filters"]["clusterId"] = cluster.id + query1["filters"]["resourceType"] = "cluster" + # Verify graphs are generated + validate_cluster_graph(query1, "cluster") + + cluster_cleanup(standard_user_client, cluster) + + +def test_cluster_template_create_update_with_monitoring(): + + ''' + Create an RKE template/revision T1/R1 with enable_cluster_monitoring:false + Create a cluster using revision R1. + Enable monitoring after cluster is active. + Create another revision R2 and update the cluster using R2 and setting + enableClusterMonitoring=false. The user will be able to upgrade the cluster + to this revision R2 but enable_cluster_monitoring flag from the template + should be ignored. Monitoring should continue to function in the cluster + ''' + global MONITORING_VERSION + + k8sversionlist = get_k8s_versionlist() + # Obtain cluster config with monitoring disabled enabled + cluster_config1 = get_cluster_config(k8sversionlist[0]) + cluster_config2 = get_cluster_config(k8sversionlist[1]) + + standard_user_client = \ + get_client_for_token( + user_token["stduser_with_createrketemplate_role"]["token"]) + userToken = user_token["stduser_with_createrketemplate_role"]["token"] + + # Create a cluster template + cluster_template = standard_user_client.\ + create_cluster_template(name=random_test_name("template"), + description="test-template") + revision_name1 = random_test_name("revision1") + revision_name2 = random_test_name("revision2") + + # Create cluster template revision without enabling monitoring + cluster_template_revision1 = \ + standard_user_client.create_cluster_template_revision( + name=revision_name1, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision1 = standard_user_client.reload( + cluster_template_revision1) + cluster_name = random_test_name("test-auto") + + # Create a cluster using the cluster template revision created + cluster = create_node_cluster( + standard_user_client, name=cluster_name, nodecount=3, nodesize="s-4vcpu-8gb", + clusterTemplateRevisionId=cluster_template_revision1.id, + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[0]) + assert cluster.clusterTemplateRevisionId == cluster_template_revision1.id + + monitoring_template = standard_user_client.list_template( + id=MONITORING_TEMPLATE_ID).data[0] + + if MONITORING_VERSION == "": + MONITORING_VERSION = monitoring_template.defaultVersion + print("MONITORING_VERSION=" + MONITORING_VERSION) + + # Enable cluster monitoring using the standard user client + if cluster["enableClusterMonitoring"] is False: + standard_user_client.action(cluster, "enableMonitoring", + answers=C_MONITORING_ANSWERS, + version=MONITORING_VERSION) + system_project = standard_user_client.list_project(clusterId=cluster.id, + name="System").data[0] + sys_proj_client = get_project_client_for_token(system_project, userToken) + + # Validate Cluster Monitoring Apps + validate_cluster_monitoring_apps(client=sys_proj_client) + + # Create another cluster template revision with K8s version v2 and having + # the default setting enableClusterMonitoring=false + cluster_template_revision2 = \ + standard_user_client.create_cluster_template_revision( + name=revision_name2, + clusterConfig=cluster_config2, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision2 = standard_user_client.reload( + cluster_template_revision2) + # Update cluster with with Revision R2 + cluster = \ + standard_user_client.update( + cluster, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision2.id) + time.sleep(2) + cluster = standard_user_client.reload(cluster) + + cluster = validate_cluster_with_template(standard_user_client, + cluster, + intermediate_state="updating", + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[1]) + assert cluster.clusterTemplateRevisionId == cluster_template_revision2.id + # Reload cluster object after an update + cluster = standard_user_client.reload(cluster) + + # Validate Cluster Monitoring Apps + validate_cluster_monitoring_apps(client=sys_proj_client) + + cluster_cleanup(standard_user_client, cluster) + + +def test_clustertemplate_readonly_member_edit_delete(): + + # As an admin, create cluster template/revision and provide "user/read-only + # access" to standard user. The user should not be able to edit/delete + # cluster template/revision + + k8sversionlist = get_k8s_versionlist() + admin_client = get_admin_client() + cluster_config = get_cluster_config(k8sversionlist[0]) + + # Obtain the principal ID of the standard user + principalId = user_token["standard_user"]["user"]["principalIds"] + + # Create a cluster template and provide standard user "user access" to the + # cluster template + members = [{"type": "member", "accessType": "read-only", + "userPrincipalId": principalId}] + + cluster_template_name = random_test_name("template") + cluster_template = \ + admin_client.create_cluster_template(name=cluster_template_name, + description="test-template", + members=members) + clusterTemplateId = cluster_template.id + # Create Cluster template revision + revision_name = random_test_name("revision") + cluster_template_revision = \ + admin_client.create_cluster_template_revision( + name=revision_name, + clusterConfig=cluster_config, + clusterTemplateId=clusterTemplateId, + enabled="true") + + standard_user_client = \ + get_client_for_token( + user_token["standard_user"]["token"]) + + # Verify the standard user does not have permission to edit/update the + # template as he has only user access + members = [{"type": "member", "accessType": "read-only", + "userPrincipalId": principalId}, + {"type": "member", "accessType": "read-only", + "groupPrincipalId": "*"}] + with pytest.raises(ApiError) as e: + standard_user_client.update(cluster_template, + name="sjtest", + description="test-template", + members=members) + assert e.value.error.status == 403 + assert e.value.error.code == "PermissionDenied" + + # Verify the standard user does not have permission to delete the + # revision as he has only user/read-only access + with pytest.raises(ApiError) as e: + standard_user_client.delete(cluster_template_revision) + assert e.value.error.status == 403 + assert e.value.error.code == "PermissionDenied" + + # Verify the standard user does not have permission to delete the + # template as he has only user access + with pytest.raises(ApiError) as e: + standard_user_client.delete(cluster_template) + assert e.value.error.status == 403 + assert e.value.error.code == "PermissionDenied" + + +def validate_cluster_with_template(client, cluster, + intermediate_state="provisioning", + check_intermediate_state=True, + nodes_not_in_active_state=[], + k8s_version="", userToken=USER_TOKEN): + ''' + In this method, we are checking cluster state, verifying state of workloads + in system project. For user workloads, we are just checking the state. We + are skipping the kubectl verification for user workloads because of this + issue: https://github.com/rancher/rancher/issues/27788 + Hence this method is introduced locally in test_cluster_templates.py and + we are not using validate_cluster method from common.py + ''' + + # Allow sometime for the "cluster_owner" CRTB to take effect + time.sleep(5) + cluster = validate_cluster_state( + client, cluster, + check_intermediate_state=check_intermediate_state, + intermediate_state=intermediate_state, + nodes_not_in_active_state=nodes_not_in_active_state) + create_kubeconfig(cluster) + if k8s_version != "": + check_cluster_version(cluster, k8s_version) + if hasattr(cluster, 'rancherKubernetesEngineConfig'): + check_cluster_state(len(get_role_nodes(cluster, "etcd", client))) + # check all workloads under the system project are active + # wait for workloads to be active + # time.sleep(DEFAULT_TIMEOUT) + print("checking if workloads under the system project are active") + sys_project = client.list_project(name='System', + clusterId=cluster.id).data[0] + sys_p_client = get_project_client_for_token(sys_project, userToken) + for wl in sys_p_client.list_workload().data: + wait_for_wl_to_active(sys_p_client, wl, + timeout=DEFAULT_CLUSTER_STATE_TIMEOUT) + # Create Daemon set workload and have an Ingress with Workload + # rule pointing to this daemonSet + project, ns = create_project_and_ns(userToken, cluster) + p_client = get_project_client_for_token(project, userToken) + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + workload = wait_for_wl_to_active(p_client, workload) + assert workload.state == "active" + + return cluster + + +def cluster_template_create_edit(userToken): + + # Method to create cluster template revisions R1, R2. + # Create a cluster with a RKE template revision R1. + # Then edit the cluster and change the revision to R2 + + k8sversionlist = get_k8s_versionlist() + cluster_config1 = get_cluster_config(k8sversionlist[0]) + cluster_config2 = get_cluster_config(k8sversionlist[1]) + + client = get_client_for_token(userToken) + cluster_template = client.create_cluster_template( + name=random_test_name("template"), description="test-template") + revision1_name = random_test_name("revision1") + cluster_template_revision1 = client.create_cluster_template_revision( + name=revision1_name, + clusterConfig=cluster_config1, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision1 = client.reload( + cluster_template_revision1) + cluster_name = random_test_name("test-auto") + cluster = create_node_cluster( + client, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision1.id, + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[0]) + assert cluster.clusterTemplateRevisionId == cluster_template_revision1.id + + revision2_name = random_test_name("revision2") + cluster_template_revision2 = client.create_cluster_template_revision( + name=revision2_name, + clusterConfig=cluster_config2, + clusterTemplateId=cluster_template.id) + time.sleep(2) + cluster_template_revision2 = client.reload( + cluster_template_revision2) + cluster = \ + client.update( + cluster, name=cluster_name, + clusterTemplateRevisionId=cluster_template_revision2.id) + + cluster = validate_cluster_with_template(client, + cluster, + intermediate_state="updating", + userToken=userToken) + check_cluster_version(cluster, k8sversionlist[1]) + assert cluster.clusterTemplateRevisionId == cluster_template_revision2.id + cluster_cleanup(client, cluster) + + +def node_template_linode(userclient, nodesize): + client = userclient + linode_cloud_credential_config = {"token": LINODE_ACCESSKEY} + linode_cloud_credential = client.create_cloud_credential( + linodecredentialConfig=linode_cloud_credential_config) + time.sleep(3) + node_template = client.create_node_template( + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-west", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}, + name=random_name(), + driver="linode", + namespaceId="lin", + cloudCredentialId=linode_cloud_credential.id, + engineInstallURL=engine_install_url, + useInternalIpAddress=True) + node_template = client.wait_success(node_template) + return node_template + + +def create_node_cluster(userclient, name, nodecount=1, nodesize="s-2vcpu-4gb", + clusterTemplateRevisionId=None, + rancherKubernetesEngineConfig=None, answers=None, + userToken=None): + client = userclient + if(rancherKubernetesEngineConfig is not None): + cluster = client.create_cluster( + name=name, + rancherKubernetesEngineConfig=rancherKubernetesEngineConfig) + else: + cluster = \ + client.create_cluster( + name=name, + clusterTemplateRevisionId=clusterTemplateRevisionId, + answers=answers) + nodetemplate = node_template_linode(client, nodesize) + nodes = [] + node = {"hostnamePrefix": random_test_name("test-auto"), + "nodeTemplateId": nodetemplate.id, + "requestedHostname": "test-auto-template", + "controlPlane": True, + "etcd": True, + "worker": True, + "quantity": nodecount, + "clusterId": None} + nodes.append(node) + node_pools = [] + for node in nodes: + node["clusterId"] = cluster.id + success = False + start = time.time() + while not success: + if time.time() - start > 10: + raise AssertionError( + "Timed out waiting for cluster owner global Roles") + try: + time.sleep(1) + node_pool = client.create_node_pool(**node) + success = True + except ApiError: + success = False + node_pool = client.wait_success(node_pool) + node_pools.append(node_pool) + cluster = validate_cluster(client, cluster, userToken=userToken) + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) == len(nodes) + for node in nodes: + assert node.state == "active" + + return cluster + + +def getRKEConfig(k8sversion): + rke_config = { + "addonJobTimeout": 30, + "ignoreDockerVersion": "true", + "sshAgentAuth": "false", + "type": "rancherKubernetesEngineConfig", + "kubernetesVersion": k8sversion, + "authentication": { + "strategy": "x509", + "type": "authnConfig" + }, + "network": { + "plugin": "canal", + "type": "networkConfig", + "options": { + "flannel_backend_type": "vxlan" + } + }, + "ingress": { + "provider": "nginx", + "type": "ingressConfig" + }, + "monitoring": { + "provider": "metrics-server", + "type": "monitoringConfig" + }, + "services": { + "type": "rkeConfigServices", + "kubeApi": { + "alwaysPullImages": "false", + "podSecurityPolicy": "false", + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService" + }, + "etcd": { + "creation": "12h", + "extraArgs": { + "heartbeat-interval": 500, + "election-timeout": 5000 + }, + "retention": "72h", + "snapshot": "false", + "type": "etcdService", + "backupConfig": { + "enabled": "true", + "intervalHours": 12, + "retention": 6, + "type": "backupConfig", + "s3BackupConfig": { + "type": "s3BackupConfig", + "accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY, + "bucketName": "test-auto-s3", + "endpoint": "s3.us-east-2.amazonaws.com" + } + } + } + } + } + return rke_config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_configmaps.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_configmaps.py new file mode 100644 index 0000000..2f9922d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_configmaps.py @@ -0,0 +1,544 @@ +from .common import * # NOQA +from rancher import ApiError + +CLUSTER_NAME = os.environ.get("CLUSTER_NAME", "") + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} + + +def test_cmap_create_single_ns_volume(): + + """ + Create a configmap.Create and validate workload using + the configmap as a volume. Create and validate the workload with config + map as environment variable + """ + + p_client = namespace["p_client"] + ns = namespace["ns"] + value = "valueall" + keyvaluepair = {"testall": value} + configmap = create_configmap(keyvaluepair, p_client, ns) + + # Create workloads with configmap in existing namespace + create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, keyvaluepair) + + +def test_cmap_create_single_ns_env_variable(): + + """ + Create a configmap.Create and validate workload using + the configmap as a volume. Create and validate the workload with config + map as environment variable + """ + + p_client = namespace["p_client"] + ns = namespace["ns"] + value = "valueall" + keyvaluepair = {"testall": value} + configmap = create_configmap(keyvaluepair, p_client, ns) + + # Create workloads with configmap in existing namespace + create_and_validate_workload_with_configmap_as_env_variable(p_client, + configmap, + ns, + keyvaluepair) + + +def test_cmap_delete_single_ns(): + + # Create a configmap and delete the configmap + p_client = namespace["p_client"] + ns = namespace["ns"] + value = "valuetest" + keyvaluepair = {"testalldelete": value} + + configmap = create_configmap(keyvaluepair, p_client, ns) + delete_configmap(p_client, configmap, ns, keyvaluepair) + + +def test_cmap_edit_single_ns(): + + """ + Create a configmap and update the configmap. + Create and validate workload using the updated configmap + """ + + p_client = namespace["p_client"] + ns = namespace["ns"] + name = random_test_name("default") + value = "valueall" + keyvaluepair = {"testall": value} + + configmap = create_configmap(keyvaluepair, p_client, ns) + + value1 = ("valueall") + value2 = ("valueallnew") + updated_dict = {"testall": value1, "testallnew": value2} + updated_configmap = p_client.update(configmap, name=name, + namespaceId=ns['name'], + data=updated_dict) + updatedconfigmapdata = updated_configmap['data'] + + assert updatedconfigmapdata.data_dict() == updated_dict + + # Create a workload with the updated configmap in the existing namespace + create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, + updatedconfigmapdata) + create_and_validate_workload_with_configmap_as_env_variable( + p_client, configmap, ns, updatedconfigmapdata) + + +# Cluster member is not added in the role list below as this role does not +# have access to the rbac created project and he has to create his own project + +rbac_role_list = [ + (CLUSTER_OWNER), + (PROJECT_OWNER), + (PROJECT_MEMBER), +] + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_cmap_create(role): + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_create(p_client, ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_cmap_edit(role): + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_edit(p_client, ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_cmap_delete(role): + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_delete(p_client, ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_cmap_list(remove_resource, role): + cluster_owner_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + configmap = rbac_configmap_create(cluster_owner_p_client, ns) + cmapname = configmap["name"] + cmapdict = cluster_owner_p_client.list_configMap(name=cmapname) + print(cmapdict) + assert cmapdict.resourceType == "configMap" + configmapdata = cmapdict.get('data') + assert len(configmapdata) == 1 + assert configmapdata[0].name == cmapname + remove_resource(configmap) + + +@if_test_rbac +def test_rbac_cmap_cluster_member_create(remove_resource): + + """ + Verify cluster member can create config map and deploy workload + using config map + """ + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_create(p_client, ns) + remove_resource(project) + + +@if_test_rbac +def test_rbac_cmap_cluster_member_edit(remove_resource): + + """ + Verify cluster member can create config map and deploy workload + using config map + """ + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_edit(p_client, ns) + remove_resource(project) + + +@if_test_rbac +def test_rbac_cmap_cluster_member_list(remove_resource): + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + configmap = rbac_configmap_create(p_client, ns) + cmapname = configmap["name"] + print(cmapname) + cmapdict = p_client.list_configMap(name=cmapname) + print(cmapdict) + assert cmapdict.resourceType == "configMap" + configmapdata = cmapdict.get('data') + assert len(configmapdata) == 1 + assert configmapdata[0].name == cmapname + remove_resource(project) + remove_resource(configmap) + + +@if_test_rbac +def test_rbac_cmap_cluster_member_delete(remove_resource): + + """ + Verify cluster member can create config map and deploy workload + using config map + """ + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_configmap_delete(p_client, ns) + remove_resource(project) + + +@if_test_rbac +def test_rbac_cmap_project_readonly_member_create(): + + project = rbac_get_project() + ns = rbac_get_namespace() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + value = "valueall" + keyvaluepair = {"testall": value} + + # Read Only member cannot create config maps + with pytest.raises(ApiError) as e: + create_configmap(keyvaluepair, readonly_user_client, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_cmap_project_readonly_member_edit(remove_resource): + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + ns = rbac_get_namespace() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + value = "valueall" + keyvaluepair = {"testall": value} + + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + # As a cluster owner, create a config map + configmap = create_configmap(keyvaluepair, cluster_owner_p_client, ns) + + # Readonly member cannot edit configmap + value1 = ("valueall") + value2 = ("valueallnew") + updated_dict = {"testall": value1, "testallnew": value2} + + with pytest.raises(ApiError) as e: + readonly_user_client.update(configmap, + namespaceId=ns['name'], + data=updated_dict) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + remove_resource(configmap) + + +@if_test_rbac +def test_rbac_cmap_project_readonly_delete(remove_resource): + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + ns = rbac_get_namespace() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + value = "valueall" + keyvaluepair = {"testall": value} + + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + + # As a cluster owner, create a config map + configmap = create_configmap(keyvaluepair, cluster_owner_p_client, ns) + + # Assert read-only user cannot delete the config map + with pytest.raises(ApiError) as e: + delete_configmap(readonly_user_client, configmap, ns, keyvaluepair) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + remove_resource(configmap) + + +@if_test_rbac +def test_rbac_cmap_readonly_list(remove_resource): + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + project = rbac_get_project() + ns = rbac_get_namespace() + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + configmap = rbac_configmap_create(cluster_owner_p_client, ns) + p_client = get_project_client_for_token(project, user_token) + cmapname = configmap["name"] + cmapdict = p_client.list_configMap(name=cmapname) + print(cmapdict) + assert cmapdict.resourceType == "configMap" + configmapdata = cmapdict.get('data') + assert len(configmapdata) == 1 + assert configmapdata[0].name == cmapname + remove_resource(configmap) + + +def rbac_configmap_create(p_client, ns): + + """ + Verify creating, editing and deleting config maps is functional. + The p_client passed as the parameter would be as per the role assigned + """ + + value = "valueall" + keyvaluepair = {"testall": value} + configmap = create_configmap(keyvaluepair, p_client, ns) + + # Create workloads with configmap in existing namespace + create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, keyvaluepair) + + return configmap + + +def rbac_configmap_edit(p_client, ns): + + """ + Verify creating, editing and deleting config maps is functional. + The p_client passed as the parameter would be as per the role assigned + """ + + value = "valueall" + keyvaluepair = {"testall": value} + configmap = create_configmap(keyvaluepair, p_client, ns) + + # Create workloads with configmap in existing namespace + create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, keyvaluepair) + + # Verify editing of configmap in the project + value1 = ("valueall") + value2 = ("valueallnew") + updated_dict = {"testall": value1, "testallnew": value2} + updated_configmap = p_client.update(configmap, + namespaceId=ns['name'], + data=updated_dict) + updatedconfigmapdata = updated_configmap['data'] + create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, + updatedconfigmapdata) + p_client.delete(updated_configmap) + + +def rbac_configmap_delete(p_client, ns): + + """ + Verify creating, editing and deleting config maps is functional. + The p_client passed as the parameter would be as per the role assigned + """ + value = "valueall" + keyvaluepair = {"testall": value} + configmap = create_configmap(keyvaluepair, p_client, ns) + # Verify deletion of config map + delete_configmap(p_client, configmap, ns, keyvaluepair) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testconfigmap") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) + + +def validate_workload_with_configmap(p_client, workload, + type, ns_name, keyvaluepair, + workloadwithconfigmapasvolume=False, + workloadwitconfigmapasenvvar=False, + podcount=1): + + validate_workload(p_client, workload, type, ns_name, pod_count=podcount) + + pod_list = p_client.list_pod(workloadId=workload.id).data + mountpath = "/test" + for i in range(0, len(keyvaluepair)): + key = list(keyvaluepair.keys())[i] + if workloadwithconfigmapasvolume: + key_file_in_pod = mountpath + "/" + key + print(key_file_in_pod) + command = "cat " + key_file_in_pod + '' + print(" Command to display configmap value from container is: ") + print(command) + result = kubectl_pod_exec(pod_list[0], command) + assert result.decode("utf-8") == (list(keyvaluepair.values())[i]) + elif workloadwitconfigmapasenvvar: + command = 'env' + result = kubectl_pod_exec(pod_list[0], command) + print(list(keyvaluepair.values())[i]) + if list(keyvaluepair.values())[i] in result.decode("utf-8"): + assert True + + +def delete_configmap(client, configmap, ns, keyvaluepair): + + key = list(keyvaluepair.keys())[0] + print("Delete Configmap") + client.delete(configmap) + # Sleep to allow for the configmap to be deleted + time.sleep(5) + timeout = 30 + configmapname = configmap.name + print("Config Map list after deleting config map") + configmapdict = client.list_configMap(name=configmapname) + start = time.time() + if len(configmapdict.get('data')) > 0: + testdata = configmapdict.get('data') + print("TESTDATA") + print(testdata[0]['data']) + while key in testdata[0]['data']: + if time.time() - start > timeout: + raise AssertionError("Timed out waiting for deletion") + time.sleep(.5) + configmapdict = client.list_configMap(name=configmapname) + testdata = configmapdict.get('data') + assert True + + if len(configmapdict.get('data')) == 0: + assert True + + # Verify configmap is deleted by "kubectl get configmap" command + command = " get configmap " + configmap['name'] + " --namespace=" + ns.name + print("Command to obtain the configmap") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + + print("Verify that the configmap does not exist " + "and the error code returned is non zero ") + if result != 0: + assert True + + +def create_and_validate_workload_with_configmap_as_volume(p_client, configmap, + ns, keyvaluepair): + workload_name = random_test_name("test") + # Create Workload with configmap as volume + mountpath = "/test" + volumeMounts = [{"readOnly": False, "type": "volumeMount", + "mountPath": mountpath, "name": "vol1"}] + con = [{"name": "test1", + "image": TEST_IMAGE, + "volumeMounts": volumeMounts}] + + configmapname = configmap['name'] + + volumes = [{"type": "volume", "name": "vol1", + "configMap": {"type": "configMapVolumeSource", + "defaultMode": 256, + "name": configmapname, + "optional": False}}] + + workload = p_client.create_workload(name=workload_name, + containers=con, + namespaceId=ns.id, volumes=volumes) + validate_workload_with_configmap(p_client, workload, "deployment", + ns.name, keyvaluepair, + workloadwithconfigmapasvolume=True) + + # Delete workload + p_client.delete(workload) + + +def create_and_validate_workload_with_configmap_as_env_variable(p_client, + configmap, + ns, + keyvaluepair): + workload_name = random_test_name("test") + + # Create Workload with configmap as env variable + configmapname = configmap['name'] + + environmentdata = [{ + "source": "configMap", + "sourceKey": None, + "sourceName": configmapname + }] + con = [{"name": "test", + "image": TEST_IMAGE, + "envFrom": [{"configMapRef": { + "name": configmapname}}] + }] + + workload = p_client.create_workload(name=workload_name, + containers=con, + namespaceId=ns.id) + validate_workload_with_configmap(p_client, workload, "deployment", + ns.name, keyvaluepair, + workloadwitconfigmapasenvvar=True) + # Delete workload + p_client.delete(workload) + + +def create_configmap(keyvaluepair, p_client=None, ns=None): + + if p_client is None: + p_client = namespace["p_client"] + + if ns is None: + ns = namespace["ns"] + + name = random_test_name("testconfigmap") + + configmap = p_client.create_configMap(name=name, namespaceId=ns['name'], + data=keyvaluepair) + assert configmap['baseType'] == "configMap" + print(configmap) + configdata = configmap['data'] + assert configdata.data_dict() == keyvaluepair + + return configmap diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_create_ha.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_create_ha.py new file mode 100644 index 0000000..3aa288e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_create_ha.py @@ -0,0 +1,625 @@ +from python_terraform import * # NOQA +from pkg_resources import packaging + +from .common import * # NOQA +from .test_boto_create_eks import get_eks_kubeconfig +from .test_import_k3s_cluster import create_multiple_control_cluster +from .test_import_rke2_cluster import ( + RANCHER_RKE2_VERSION, create_rke2_multiple_control_cluster +) +from .test_rke_cluster_provisioning import AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, rke_config +from packaging import version + +# RANCHER_HA_KUBECONFIG and RANCHER_HA_HOSTNAME are provided +# when installing Rancher into a k3s setup +RANCHER_HA_KUBECONFIG = os.environ.get("RANCHER_HA_KUBECONFIG") +RANCHER_HA_HARDENED = ast.literal_eval(os.environ.get("RANCHER_HA_HARDENED", "False")) +RANCHER_PSP_ENABLED = ast.literal_eval(os.environ.get("RANCHER_PSP_ENABLED", "True")) +RANCHER_HA_HOSTNAME = os.environ.get( + "RANCHER_HA_HOSTNAME", RANCHER_HOSTNAME_PREFIX + ".qa.rancher.space") +resource_prefix = RANCHER_HA_HOSTNAME.split(".qa.rancher.space")[0] +RANCHER_SERVER_URL = "https://" + RANCHER_HA_HOSTNAME + +RANCHER_CHART_VERSION = os.environ.get("RANCHER_CHART_VERSION") +RANCHER_HELM_EXTRA_SETTINGS = os.environ.get("RANCHER_HELM_EXTRA_SETTINGS") +RANCHER_IMAGE_TAG = os.environ.get("RANCHER_IMAGE_TAG") +RANCHER_HELM_REPO = os.environ.get("RANCHER_HELM_REPO", "latest") +RANCHER_HELM_URL = os.environ.get("RANCHER_HELM_URL", "https://releases.rancher.com/server-charts/") +RANCHER_LETSENCRYPT_EMAIL = os.environ.get("RANCHER_LETSENCRYPT_EMAIL") +# Here is the list of cert types for HA install +# [rancher-self-signed, byo-valid, byo-self-signed, letsencrypt] +RANCHER_HA_CERT_OPTION = os.environ.get("RANCHER_HA_CERT_OPTION", + "rancher-self-signed") +RANCHER_VALID_TLS_CERT = os.environ.get("RANCHER_VALID_TLS_CERT") +RANCHER_VALID_TLS_KEY = os.environ.get("RANCHER_VALID_TLS_KEY") +RANCHER_BYO_TLS_CERT = os.environ.get("RANCHER_BYO_TLS_CERT") +RANCHER_BYO_TLS_KEY = os.environ.get("RANCHER_BYO_TLS_KEY") +RANCHER_PRIVATE_CA_CERT = os.environ.get("RANCHER_PRIVATE_CA_CERT") + +RANCHER_LOCAL_CLUSTER_TYPE = os.environ.get("RANCHER_LOCAL_CLUSTER_TYPE") +RANCHER_ADD_CUSTOM_CLUSTER = os.environ.get("RANCHER_ADD_CUSTOM_CLUSTER", + "True") +KUBERNETES_VERSION = os.environ.get("RANCHER_LOCAL_KUBERNETES_VERSION","") + +kubeconfig_path = DATA_SUBDIR + "/kube_config_cluster-ha-filled.yml" +export_cmd = "export KUBECONFIG=" + kubeconfig_path + + +def test_remove_rancher_ha(): + assert CATTLE_TEST_URL.endswith(".qa.rancher.space"), \ + "the CATTLE_TEST_URL need to end with .qa.rancher.space" + if not check_if_ok(CATTLE_TEST_URL): + print("skip deleting clusters within the setup") + else: + print("the CATTLE_TEST_URL is accessible") + admin_token = get_user_token("admin", ADMIN_PASSWORD) + client = get_client_for_token(admin_token) + + # delete clusters except the local cluster + clusters = client.list_cluster(id_ne="local").data + print("deleting the following clusters: {}" + .format([cluster.name for cluster in clusters])) + for cluster in clusters: + print("deleting the following cluster : {}".format(cluster.name)) + delete_cluster(client, cluster) + + resource_prefix = \ + CATTLE_TEST_URL.split(".qa.rancher.space")[0].split("//")[1] + delete_resource_in_AWS_by_prefix(resource_prefix) + + +def test_install_rancher_ha(precheck_certificate_options): + cm_install = True + extra_settings = [] + profile = 'rke-cis-1.5' + if "byo-" in RANCHER_HA_CERT_OPTION: + cm_install = False + print("The hostname is: {}".format(RANCHER_HA_HOSTNAME)) + + # prepare an RKE cluster and other resources + # if no kubeconfig file is provided + if RANCHER_HA_KUBECONFIG is None: + if RANCHER_LOCAL_CLUSTER_TYPE == "RKE": + print("RKE cluster is provisioning for the local cluster") + nodes = create_resources() + if RANCHER_HA_HARDENED: + node_role = [["worker", "controlplane", "etcd"]] + node_roles =[] + for role in node_role: + node_roles.extend([role, role, role]) + prepare_hardened_nodes(nodes, profile, node_roles) + config_path = create_rke_cluster_config(nodes) + create_rke_cluster(config_path) + elif RANCHER_LOCAL_CLUSTER_TYPE == "K3S": + print("K3S cluster is provisioning for the local cluster") + k3s_kubeconfig_path = \ + create_multiple_control_cluster() + cmd = "cp {0} {1}".format(k3s_kubeconfig_path, kubeconfig_path) + run_command_with_stderr(cmd) + elif RANCHER_LOCAL_CLUSTER_TYPE == "RKE2": + print("RKE2 cluster is provisioning for the local cluster") + rke2_kubeconfig_path = \ + create_rke2_multiple_control_cluster("rke2", + RANCHER_RKE2_VERSION) + cmd = "cp {0} {1}".format(rke2_kubeconfig_path, kubeconfig_path) + run_command_with_stderr(cmd) + elif RANCHER_LOCAL_CLUSTER_TYPE == "EKS": + create_resources_eks() + eks_kubeconfig_path = get_eks_kubeconfig(resource_prefix + + "-ekscluster") + cmd = "cp {0} {1}".format(eks_kubeconfig_path, kubeconfig_path) + run_command_with_stderr(cmd) + install_eks_ingress() + extra_settings.append( + "--set ingress." + "extraAnnotations.\"kubernetes\\.io/ingress\\.class\"=nginx" + ) + elif RANCHER_LOCAL_CLUSTER_TYPE == "AKS": + create_aks_cluster() + install_aks_ingress() + extra_settings.append( + "--set ingress." + "extraAnnotations.\"kubernetes\\.io/ingress\\.class\"=nginx" + ) + elif RANCHER_LOCAL_CLUSTER_TYPE == "GKE": + create_gke_cluster() + install_gke_ingress() + extra_settings.append( + "--set ingress." + "extraAnnotations.\"kubernetes\\.io/ingress\\.class\"=nginx" + ) + else: + write_kubeconfig() + + # wait until the cluster is ready + def valid_response(): + output = run_command_with_stderr(export_cmd + " && kubectl get nodes") + return "Ready" in output.decode() + + try: + wait_for(valid_response) + except Exception as e: + print("Error: {0}".format(e)) + assert False, "check the logs in console for details" + + print_kubeconfig(kubeconfig_path) + if (RANCHER_HA_HARDENED and RANCHER_LOCAL_CLUSTER_TYPE == "RKE") and RANCHER_HA_KUBECONFIG == "" and RANCHER_HA_HOSTNAME=="": + prepare_hardened_cluster(profile, kubeconfig_path) + if RANCHER_LOCAL_CLUSTER_TYPE == "RKE": + check_rke_ingress_rollout() + elif RANCHER_LOCAL_CLUSTER_TYPE in ["K3S", "RKE2"]: + print("Skipping ingress rollout check for k3s and rke2 clusters") + else: + check_ingress_rollout() + if cm_install: + install_cert_manager() + add_repo_create_namespace() + # Here we use helm to install the Rancher chart + install_rancher(extra_settings=extra_settings) + set_route53_with_ingress() + wait_for_status_code(url=RANCHER_SERVER_URL + "/v3", expected_code=401) + auth_url = \ + RANCHER_SERVER_URL + "/v3-public/localproviders/local?action=login" + wait_for_status_code(url=auth_url, expected_code=200) + admin_client = set_url_and_password(RANCHER_SERVER_URL) + cluster = get_cluster_by_name(admin_client, "local") + validate_cluster_state(admin_client, cluster, False) + print("Local HA Rancher cluster created successfully! " + "Access the UI via:\n{}".format(RANCHER_SERVER_URL)) + if RANCHER_ADD_CUSTOM_CLUSTER.upper() == "TRUE": + print("creating an custom cluster") + create_custom_cluster(admin_client) + + +def create_custom_cluster(admin_client): + auth_url = RANCHER_SERVER_URL + \ + "/v3-public/localproviders/local?action=login" + wait_for_status_code(url=auth_url, expected_code=200) + user, user_token = create_user(admin_client, auth_url) + + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 5, random_test_name(resource_prefix + "-custom")) + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + client = rancher.Client(url=RANCHER_SERVER_URL + "/v3", + token=user_token, verify=False) + cluster = client.create_cluster( + name=random_name(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd( + client, cluster, node_roles[i], aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + validate_cluster(client, cluster, userToken=user_token) + + +def test_upgrade_rancher_ha(precheck_upgrade_options): + write_kubeconfig() + add_repo_create_namespace() + install_rancher(upgrade=True) + + +def create_resources_eks(): + cluster_name = resource_prefix + "-ekscluster" + AmazonWebServices().create_eks_cluster(cluster_name) + AmazonWebServices().wait_for_eks_cluster_state(cluster_name, "ACTIVE") + + +def create_resources(): + # Create nlb and grab ARN & dns name + lb = AmazonWebServices().create_network_lb(name=resource_prefix + "-nlb") + lbArn = lb["LoadBalancers"][0]["LoadBalancerArn"] + lbDns = lb["LoadBalancers"][0]["DNSName"] + + # Upsert the route53 record -- if it exists, update, if not, insert + AmazonWebServices().upsert_route_53_record_cname(RANCHER_HA_HOSTNAME, + lbDns) + + # Create the target groups + tg80 = AmazonWebServices(). \ + create_ha_target_group(80, resource_prefix + "-tg-80") + tg443 = AmazonWebServices(). \ + create_ha_target_group(443, resource_prefix + "-tg-443") + tg80Arn = tg80["TargetGroups"][0]["TargetGroupArn"] + tg443Arn = tg443["TargetGroups"][0]["TargetGroupArn"] + + # Create listeners for the load balancer, to forward to the target groups + AmazonWebServices().create_ha_nlb_listener(loadBalancerARN=lbArn, + port=80, + targetGroupARN=tg80Arn) + AmazonWebServices().create_ha_nlb_listener(loadBalancerARN=lbArn, + port=443, + targetGroupARN=tg443Arn) + targets = [] + aws_nodes = AmazonWebServices().\ + create_multiple_nodes(3, resource_prefix + "-server") + assert len(aws_nodes) == 3 + + for aws_node in aws_nodes: + print(aws_node.public_ip_address) + targets.append(aws_node.provider_node_id) + + # Register the nodes to the target groups + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg80Arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg443Arn) + return aws_nodes + + +def install_cert_manager(): + manifests = "https://github.com/jetstack/cert-manager/releases/download/" \ + "{0}/cert-manager.crds.yaml".format(CERT_MANAGER_VERSION) + cm_repo = "https://charts.jetstack.io" + + run_command_with_stderr(export_cmd + " && kubectl apply -f " + manifests) + run_command_with_stderr("helm_v3 repo add jetstack " + cm_repo) + run_command_with_stderr("helm_v3 repo update") + run_command_with_stderr(export_cmd + " && " + + "kubectl create namespace cert-manager") + run_command_with_stderr(export_cmd + " && " + + "helm_v3 install cert-manager " + "jetstack/cert-manager " + "--namespace cert-manager " + "--version {0}".format(CERT_MANAGER_VERSION)) + time.sleep(120) + + +def install_eks_ingress(): + run_command_with_stderr(export_cmd + " && kubectl apply -f " + + DATA_SUBDIR + "/eks_nlb.yml") + + +def set_route53_with_ingress(): + ingress_address = None + if RANCHER_LOCAL_CLUSTER_TYPE == "EKS": + kubectl_ingress = "kubectl get ingress -n cattle-system -o " \ + "jsonpath=\"" \ + "{.items[0].status.loadBalancer.ingress[0].hostname}\"" + time.sleep(10) + ingress_address = run_command_with_stderr(export_cmd + + " && " + + kubectl_ingress).decode() + AmazonWebServices().upsert_route_53_record_cname(RANCHER_HA_HOSTNAME, + ingress_address) + + elif RANCHER_LOCAL_CLUSTER_TYPE == "AKS": + kubectl_ingress = "kubectl get svc -n ingress-nginx " \ + "ingress-nginx-controller -o " \ + "jsonpath=\"" \ + "{.status.loadBalancer.ingress[0].ip}\"" + time.sleep(10) + ingress_address = run_command_with_stderr(export_cmd + + " && " + + kubectl_ingress).decode() + + AmazonWebServices().upsert_route_53_record_cname(RANCHER_HA_HOSTNAME, + ingress_address, + record_type='A') + elif RANCHER_LOCAL_CLUSTER_TYPE == "GKE": + kubectl_ingress = "kubectl get svc -n ingress-nginx " \ + "ingress-nginx-controller -o " \ + "jsonpath=\"" \ + "{.status.loadBalancer.ingress[0].ip}\"" + time.sleep(10) + ingress_address = run_command_with_stderr(export_cmd + + " && " + + kubectl_ingress).decode() + + AmazonWebServices().upsert_route_53_record_cname(RANCHER_HA_HOSTNAME, + ingress_address, + record_type='A') + elif RANCHER_LOCAL_CLUSTER_TYPE in ["RKE", "K3S", "RKE2"]: + return + else: + pytest.fail("Wrong RANCHER_LOCAL_CLUSTER_TYPE: {}" + .format(RANCHER_LOCAL_CLUSTER_TYPE)) + + print("INGRESS ADDRESS:") + print(ingress_address) + time.sleep(60) + + +def add_repo_create_namespace(repo=RANCHER_HELM_REPO, url=RANCHER_HELM_URL): + repo_name = "rancher-" + repo + repo_url = url + repo + + run_command_with_stderr("helm_v3 repo add " + repo_name + " " + repo_url) + run_command_with_stderr("helm_v3 repo update") + run_command_with_stderr(export_cmd + " && " + + "kubectl create namespace cattle-system") + + +def install_rancher(type=RANCHER_HA_CERT_OPTION, repo=RANCHER_HELM_REPO, + upgrade=False, extra_settings=[]): + operation = "install" + + if upgrade: + operation = "upgrade" + + helm_rancher_cmd = \ + export_cmd + " && helm_v3 " + operation + " rancher " + \ + "rancher-" + repo + "/rancher " + \ + "--version " + RANCHER_CHART_VERSION + " " + \ + "--namespace cattle-system " + \ + "--set hostname=" + RANCHER_HA_HOSTNAME + + if version.parse(RANCHER_CHART_VERSION) > version.parse("2.7.1"): + helm_rancher_cmd = helm_rancher_cmd + " --set global.cattle.psp.enabled=" + str(RANCHER_PSP_ENABLED).lower() + + if type == 'letsencrypt': + helm_rancher_cmd = \ + helm_rancher_cmd + \ + " --set ingress.tls.source=letsEncrypt " + \ + "--set letsEncrypt.email=" + \ + RANCHER_LETSENCRYPT_EMAIL + elif type == 'byo-self-signed': + helm_rancher_cmd = \ + helm_rancher_cmd + \ + " --set ingress.tls.source=secret " + \ + "--set privateCA=true" + elif type == 'byo-valid': + helm_rancher_cmd = \ + helm_rancher_cmd + \ + " --set ingress.tls.source=secret" + + if RANCHER_IMAGE_TAG != "" and RANCHER_IMAGE_TAG is not None: + helm_rancher_cmd = \ + helm_rancher_cmd + \ + " --set rancherImageTag=" + RANCHER_IMAGE_TAG + + if operation == "install": + if type == "byo-self-signed": + create_tls_secrets(valid_cert=False) + elif type == "byo-valid": + create_tls_secrets(valid_cert=True) + + if RANCHER_HELM_EXTRA_SETTINGS: + extra_settings.append(RANCHER_HELM_EXTRA_SETTINGS) + + if extra_settings: + for setting in extra_settings: + helm_rancher_cmd = helm_rancher_cmd + " " + setting + + run_command_with_stderr(helm_rancher_cmd) + time.sleep(120) + + # set trace logging + set_trace_cmd = "kubectl -n cattle-system get pods -l app=rancher " + \ + "--no-headers -o custom-columns=name:.metadata.name | " + \ + "while read rancherpod; do kubectl -n cattle-system " + \ + "exec $rancherpod -c rancher -- loglevel --set trace; done" + run_command_with_stderr(set_trace_cmd) + + +def create_tls_secrets(valid_cert): + cert_path = DATA_SUBDIR + "/tls.crt" + key_path = DATA_SUBDIR + "/tls.key" + ca_path = DATA_SUBDIR + "/cacerts.pem" + + if valid_cert: + # write files from env var + write_encoded_certs(cert_path, RANCHER_VALID_TLS_CERT) + write_encoded_certs(key_path, RANCHER_VALID_TLS_KEY) + else: + write_encoded_certs(cert_path, RANCHER_BYO_TLS_CERT) + write_encoded_certs(key_path, RANCHER_BYO_TLS_KEY) + write_encoded_certs(ca_path, RANCHER_PRIVATE_CA_CERT) + + tls_command = export_cmd + " && kubectl -n cattle-system " \ + "create secret tls tls-rancher-ingress " \ + "--cert=" + cert_path + " --key=" + key_path + ca_command = export_cmd + " && kubectl -n cattle-system " \ + "create secret generic tls-ca " \ + "--from-file=" + ca_path + + run_command_with_stderr(tls_command) + + if not valid_cert: + run_command_with_stderr(ca_command) + + +def write_encoded_certs(path, contents): + file = open(path, "w") + file.write(base64.b64decode(contents).decode("utf-8")) + file.close() + + +def write_kubeconfig(): + file = open(kubeconfig_path, "w") + file.write(base64.b64decode(RANCHER_HA_KUBECONFIG).decode("utf-8")) + file.close() + + +def set_url_and_password(rancher_url, server_url=None, version=""): + admin_token = set_url_password_token(rancher_url, server_url, version=version) + admin_client = rancher.Client(url=rancher_url + "/v3", + token=admin_token, verify=False) + auth_url = rancher_url + "/v3-public/localproviders/local?action=login" + user, user_token = create_user(admin_client, auth_url) + env_details = "env.CATTLE_TEST_URL='" + rancher_url + "'\n" + env_details += "env.ADMIN_TOKEN='" + admin_token + "'\n" + env_details += "env.USER_TOKEN='" + user_token + "'\n" + create_config_file(env_details) + return admin_client + + +def create_rke_cluster(config_path): + rke_cmd = "rke --version && rke up --config " + config_path + run_command_with_stderr(rke_cmd) + + +def check_ingress_rollout(): + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx rollout status deploy/ingress-nginx-controller") + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx wait --for=condition=complete job/ingress-nginx-admission-create") + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx wait --for=condition=complete job/ingress-nginx-admission-patch") + + +def check_rke_ingress_rollout(): + rke_version = run_command_with_stderr('rke -v | cut -d " " -f 3') + rke_version = ''.join(rke_version.decode('utf-8').split()) + print("RKE VERSION: " + rke_version) + k8s_version = run_command_with_stderr(export_cmd + " && " + + 'kubectl version --short | grep -i server | cut -d " " -f 3') + k8s_version = ''.join(k8s_version.decode('utf-8').split()) + print("KUBERNETES VERSION: " + k8s_version) + if packaging.version.parse(rke_version) > packaging.version.parse("v1.2"): + if packaging.version.parse(k8s_version) >= packaging.version.parse("v1.21"): + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx rollout status ds/nginx-ingress-controller") + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx wait --for=condition=complete job/ingress-nginx-admission-create") + run_command_with_stderr( + export_cmd + " && " + + "kubectl -n ingress-nginx wait --for=condition=complete job/ingress-nginx-admission-patch") + + +def create_rke_cluster_config(aws_nodes): + configfile = "cluster-ha.yml" + + rkeconfig = readDataFile(DATA_SUBDIR, configfile) + rkeconfig = rkeconfig.replace("$ip1", aws_nodes[0].public_ip_address) + rkeconfig = rkeconfig.replace("$ip2", aws_nodes[1].public_ip_address) + rkeconfig = rkeconfig.replace("$ip3", aws_nodes[2].public_ip_address) + + rkeconfig = rkeconfig.replace("$internalIp1", + aws_nodes[0].private_ip_address) + rkeconfig = rkeconfig.replace("$internalIp2", + aws_nodes[1].private_ip_address) + rkeconfig = rkeconfig.replace("$internalIp3", + aws_nodes[2].private_ip_address) + + rkeconfig = rkeconfig.replace("$user1", aws_nodes[0].ssh_user) + rkeconfig = rkeconfig.replace("$user2", aws_nodes[1].ssh_user) + rkeconfig = rkeconfig.replace("$user3", aws_nodes[2].ssh_user) + + rkeconfig = rkeconfig.replace("$AWS_SSH_KEY_NAME", AWS_SSH_KEY_NAME) + rkeconfig = rkeconfig.replace("$KUBERNETES_VERSION", KUBERNETES_VERSION) + + if RANCHER_HA_HARDENED: + rkeconfig_hardened = readDataFile(DATA_SUBDIR, "hardened-cluster.yml") + rkeconfig += "\n" + rkeconfig += rkeconfig_hardened + print("cluster-ha-filled.yml: \n" + rkeconfig + "\n") + + clusterfilepath = DATA_SUBDIR + "/" + "cluster-ha-filled.yml" + + f = open(clusterfilepath, "w") + f.write(rkeconfig) + f.close() + return clusterfilepath + + +def create_aks_cluster(): + tf_dir = DATA_SUBDIR + "/" + "terraform/aks" + aks_k8_s_version = os.environ.get('RANCHER_AKS_K8S_VERSION', '') + aks_location = os.environ.get('RANCHER_AKS_LOCATION', '') + client_id = os.environ.get('AZURE_CLIENT_ID', '') + client_secret = os.environ.get('AZURE_CLIENT_SECRET', '') + + tf = Terraform(working_dir=tf_dir, + variables={'kubernetes_version': aks_k8_s_version, + 'location': aks_location, + 'cluster_name': resource_prefix}) + + tffile = tf_dir + "/aks.tf" + + config = readDataFile(DATA_SUBDIR, tffile) + config = config.replace('id_placeholder', AZURE_CLIENT_ID) + config = config.replace('secret_placeholder', AZURE_CLIENT_SECRET) + + f = open(tffile, "w") + f.write(config) + f.close() + + print("Creating cluster") + tf.init() + print(tf.plan(out="aks_plan_server.out")) + print("\n\n") + print(tf.apply("--auto-approve")) + print("\n\n") + out_string = tf.output("kube_config", full_value=True) + with open(kubeconfig_path, "w") as kubefile: + kubefile.write(out_string) + + +def create_gke_cluster(): + tf_dir = DATA_SUBDIR + "/" + "terraform/gke" + credentials = os.environ.get('RANCHER_GKE_CREDENTIAL', '') + gke_k8_s_version = os.environ.get('RANCHER_GKE_K8S_VERSION', '') + + tf = Terraform(working_dir=tf_dir, + variables={'kubernetes_version': gke_k8_s_version, + 'credentials': credentials, + 'cluster_name': resource_prefix}) + + print("Creating cluster") + tf.init() + print(tf.plan(out="gks_plan_server.out")) + print("\n\n") + print(tf.apply("--auto-approve")) + print("\n\n") + out_string = tf.output("kube_config", full_value=True) + print("GKE KUBECONFIG") + print("\n\n") + print(out_string) + print("\n\n") + with open(kubeconfig_path, "w") as kubefile: + kubefile.write(out_string) + + +def install_aks_ingress(): + run_command_with_stderr(export_cmd + " && kubectl apply -f " + + DATA_SUBDIR + "/aks_nlb.yml") + + +def install_gke_ingress(): + run_command_with_stderr(export_cmd + " && kubectl apply -f " + + DATA_SUBDIR + "/gke_nlb.yml") + + +@pytest.fixture(scope='module') +def precheck_certificate_options(): + if RANCHER_HA_CERT_OPTION == 'byo-valid': + if RANCHER_VALID_TLS_CERT == '' or \ + RANCHER_VALID_TLS_KEY == '' or \ + RANCHER_VALID_TLS_CERT is None or \ + RANCHER_VALID_TLS_KEY is None: + raise pytest.skip( + 'Valid certificates not found in environment variables') + elif RANCHER_HA_CERT_OPTION == 'byo-self-signed': + if RANCHER_BYO_TLS_CERT == '' or \ + RANCHER_BYO_TLS_KEY == '' or \ + RANCHER_PRIVATE_CA_CERT == '' or \ + RANCHER_BYO_TLS_CERT is None or \ + RANCHER_BYO_TLS_KEY is None or \ + RANCHER_PRIVATE_CA_CERT is None: + raise pytest.skip( + 'Self signed certificates not found in environment variables') + elif RANCHER_HA_CERT_OPTION == 'letsencrypt': + if RANCHER_LETSENCRYPT_EMAIL == '' or \ + RANCHER_LETSENCRYPT_EMAIL is None: + raise pytest.skip( + 'LetsEncrypt email is not found in environment variables') + + +@pytest.fixture(scope='module') +def precheck_upgrade_options(): + if RANCHER_HA_KUBECONFIG == '' or RANCHER_HA_KUBECONFIG is None: + raise pytest.skip('Kubeconfig is not found for upgrade!') + if RANCHER_HA_HOSTNAME == '' or RANCHER_HA_HOSTNAME is None: + raise pytest.skip('Hostname is not found for upgrade!') diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_custom_host_reg.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_custom_host_reg.py new file mode 100644 index 0000000..d4d2141 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_custom_host_reg.py @@ -0,0 +1,201 @@ +from .test_auth import enable_ad, load_setup_data, enable_openldap, \ + OPENLDAP_AUTH_USER_PASSWORD, enable_freeipa, FREEIPA_AUTH_USER_PASSWORD +from .common import * # NOQA +import ast + +AGENT_REG_CMD = os.environ.get('RANCHER_AGENT_REG_CMD', "") +HOST_COUNT = int(os.environ.get('RANCHER_HOST_COUNT', 1)) +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "testsa") +RANCHER_SERVER_VERSION = os.environ.get('RANCHER_SERVER_VERSION', + "master-head") +rke_config = {"authentication": {"type": "authnConfig", "strategy": "x509"}, + "ignoreDockerVersion": False, + "network": {"type": "networkConfig", "plugin": "canal"}, + "type": "rancherKubernetesEngineConfig" + } +AUTO_DEPLOY_CUSTOM_CLUSTER = ast.literal_eval( + os.environ.get('RANCHER_AUTO_DEPLOY_CUSTOM_CLUSTER', "True")) +KEYPAIR_NAME_PREFIX = os.environ.get('RANCHER_KEYPAIR_NAME_PREFIX', "") +RANCHER_CLUSTER_NAME = os.environ.get('RANCHER_CLUSTER_NAME', "") +RANCHER_ELASTIC_SEARCH_ENDPOINT = os.environ.get( + 'RANCHER_ELASTIC_SEARCH_ENDPOINT', "") +K8S_VERSION = os.environ.get('RANCHER_K8S_VERSION', "") +RANCHER_REPOSITORY_IMAGE = os.environ.get('RANCHER_REPOSITORY_IMAGE', "rancher/rancher") + + +def test_add_custom_host(): + aws_nodes = AmazonWebServices().create_multiple_nodes( + HOST_COUNT, random_test_name("testsa" + HOST_NAME)) + if AGENT_REG_CMD != "": + for aws_node in aws_nodes: + additional_options = " --address " + aws_node.public_ip_address + \ + " --internal-address " + \ + aws_node.private_ip_address + if 'Administrator' == aws_node.ssh_user: + agent_cmd_temp = AGENT_REG_CMD.replace('| iex', ' ' + additional_options + ' | iex ') + agent_cmd = agent_cmd_temp + additional_options + else: + agent_cmd = AGENT_REG_CMD + additional_options + aws_node.execute_command(agent_cmd) + print("Nodes: " + aws_node.public_ip_address) + + +def test_delete_keypair(): + AmazonWebServices().delete_keypairs(KEYPAIR_NAME_PREFIX) + + +def test_deploy_rancher_server(): + + RANCHER_SERVER_CMD = \ + 'sudo docker run -d --privileged --name="rancher-server" ' \ + '--restart=unless-stopped -p 80:80 -p 443:443 ' \ + '-e CATTLE_BOOTSTRAP_PASSWORD="{}" ' \ + '{}:{} --trace'.format(ADMIN_PASSWORD,RANCHER_REPOSITORY_IMAGE,RANCHER_SERVER_VERSION) + + print(RANCHER_SERVER_CMD) + aws_nodes = AmazonWebServices().create_multiple_nodes( + 1, random_test_name("testsa" + HOST_NAME)) + result = aws_nodes[0].execute_command(RANCHER_SERVER_CMD) + print(result) + time.sleep(120) + RANCHER_SERVER_URL = "https://" + aws_nodes[0].public_ip_address + print(RANCHER_SERVER_URL) + wait_until_active(RANCHER_SERVER_URL, timeout=300) + + RANCHER_SET_DEBUG_CMD = \ + "sudo docker exec rancher-server loglevel --set debug" + aws_nodes[0].execute_command(RANCHER_SET_DEBUG_CMD) + + token = set_url_password_token(RANCHER_SERVER_URL, + version=RANCHER_SERVER_VERSION) + t_end = time.time() + 30 + while time.time() < t_end: + try: + admin_client = rancher.Client(url=RANCHER_SERVER_URL + "/v3", + token=token, verify=False) + except requests.exceptions: + print("Got exception while creating admin client - retry") + else: + break + + if AUTH_PROVIDER: + enable_url = \ + RANCHER_SERVER_URL + "/v3/" + AUTH_PROVIDER + \ + "Configs/" + AUTH_PROVIDER.lower() + "?action=testAndApply" + auth_admin_user = load_setup_data()["admin_user"] + auth_user_login_url = \ + RANCHER_SERVER_URL + "/v3-public/" + AUTH_PROVIDER + "Providers/" \ + + AUTH_PROVIDER.lower() + "?action=login" + + if AUTH_PROVIDER == "activeDirectory": + + enable_ad(auth_admin_user, token, enable_url=enable_url, + password=AUTH_USER_PASSWORD, nested=NESTED_GROUP_ENABLED) + user_token = login_as_auth_user( + load_setup_data()["standard_user"], + AUTH_USER_PASSWORD, + login_url=auth_user_login_url)["token"] + elif AUTH_PROVIDER == "openLdap": + + enable_openldap(auth_admin_user, token, enable_url=enable_url, + password=OPENLDAP_AUTH_USER_PASSWORD, + nested=NESTED_GROUP_ENABLED) + user_token = login_as_auth_user( + load_setup_data()["standard_user"], + OPENLDAP_AUTH_USER_PASSWORD, + login_url=auth_user_login_url)["token"] + elif AUTH_PROVIDER == "freeIpa": + + enable_freeipa(auth_admin_user, token, enable_url=enable_url, + password=FREEIPA_AUTH_USER_PASSWORD, + nested=NESTED_GROUP_ENABLED) + user_token = login_as_auth_user( + load_setup_data()["standard_user"], + FREEIPA_AUTH_USER_PASSWORD, + login_url=auth_user_login_url)["token"] + else: + AUTH_URL = \ + RANCHER_SERVER_URL + "/v3-public/localproviders/local?action=login" + user, user_token = create_user(admin_client, AUTH_URL) + + env_details = "env.CATTLE_TEST_URL='" + RANCHER_SERVER_URL + "'\n" + env_details += "env.ADMIN_TOKEN='" + token + "'\n" + env_details += "env.USER_TOKEN='" + user_token + "'\n" + + if UPDATE_KDM: + update_and_validate_kdm(KDM_URL, admin_token=token, + rancher_api_url=RANCHER_SERVER_URL + "/v3") + + if AUTO_DEPLOY_CUSTOM_CLUSTER: + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 5, random_test_name("testcustom")) + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + client = rancher.Client(url=RANCHER_SERVER_URL + "/v3", + token=user_token, verify=False) + if K8S_VERSION != "": + rke_config["kubernetesVersion"] = K8S_VERSION + print("the rke config for creating the cluster:") + print(rke_config) + cluster = client.create_cluster( + name=random_name(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd( + client, cluster, node_roles[i], aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + validate_cluster_state(client, cluster) + env_details += "env.CLUSTER_NAME='" + cluster.name + "'\n" + + create_config_file(env_details) + + +def test_delete_rancher_server(): + client = get_admin_client() + clusters = client.list_cluster().data + for cluster in clusters: + delete_cluster(client, cluster) + clusters = client.list_cluster().data + start = time.time() + while len(clusters) > 0: + time.sleep(30) + clusters = client.list_cluster().data + if time.time() - start > MACHINE_TIMEOUT: + exceptionMsg = 'Timeout waiting for clusters to be removed' + raise Exception(exceptionMsg) + ip_address = CATTLE_TEST_URL[8:] + print("Ip Address:" + ip_address) + filters = [ + {'Name': 'network-interface.addresses.association.public-ip', + 'Values': [ip_address]}] + aws_nodes = AmazonWebServices().get_nodes(filters) + assert len(aws_nodes) == 1 + AmazonWebServices().delete_nodes(aws_nodes, wait_for_deleted=True) + + +def test_cluster_enable_logging_elasticsearch(): + client = get_user_client() + cluster = get_cluster_by_name(client, RANCHER_CLUSTER_NAME) + cluster_name = cluster.name + client.create_cluster_logging(name=random_test_name("elasticsearch"), + clusterId=cluster.id, + elasticsearchConfig={ + "dateFormat": "YYYY-MM-DD", + "sslVerify": False, + "sslVersion": "TLSv1_2", + "indexPrefix": cluster_name, + "endpoint": + RANCHER_ELASTIC_SEARCH_ENDPOINT} + ) + projects = client.list_project(name="System", + clusterId=cluster.id).data + assert len(projects) == 1 + project = projects[0] + p_client = get_project_client_for_token(project, USER_TOKEN) + wait_for_app_to_active(p_client, "rancher-logging") diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_deploy_clusters.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_deploy_clusters.py new file mode 100644 index 0000000..0ae57f6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_deploy_clusters.py @@ -0,0 +1,191 @@ +from .common import * # NOQA +from .test_aks_cluster import get_aks_version, create_and_validate_aks_cluster +from .test_eks_cluster import EKS_K8S_VERSIONS, create_and_validate_eks_cluster +from .test_gke_cluster import get_gke_config, \ + create_and_validate_gke_cluster, get_gke_version_credentials +from .test_rke_cluster_provisioning import create_and_validate_custom_host +from .test_import_cluster import create_and_validate_import_cluster + +env_details = "env.RANCHER_CLUSTER_NAMES='" +cluster_details = {"rke": {}, "rke_import": {}, + "eks": {}, "aks": {}, "gke": {}} + +if_not_auto_deploy_rke = pytest.mark.skipif( + ast.literal_eval( + os.environ.get( + 'RANCHER_TEST_DEPLOY_RKE', "False")) is False, + reason='auto deploy RKE tests are skipped') +if_not_auto_deploy_eks = pytest.mark.skipif( + ast.literal_eval( + os.environ.get( + 'RANCHER_TEST_DEPLOY_EKS', "False")) is False, + reason='auto deploy EKS tests are skipped') +if_not_auto_deploy_gke = pytest.mark.skipif( + ast.literal_eval( + os.environ.get( + 'RANCHER_TEST_DEPLOY_GKE', "False")) is False, + reason='auto deploy GKE tests are skipped') +if_not_auto_deploy_aks = pytest.mark.skipif( + ast.literal_eval( + os.environ.get( + 'RANCHER_TEST_DEPLOY_AKS', "False")) is False, + reason='auto deploy AKS tests are skipped') +if_not_auto_deploy_rke_import = pytest.mark.skipif( + ast.literal_eval( + os.environ.get( + 'RANCHER_TEST_DEPLOY_RKE_IMPORT', "False")) is False, + reason='auto deploy RKE import tests are skipped') + + +@if_not_auto_deploy_rke +def test_deploy_rke(): + print("Deploying RKE Clusters") + global env_details + global cluster_details + + rancher_version = get_setting_value_by_name('server-version') + if str(rancher_version).startswith('v2.2'): + k8s_v = get_setting_value_by_name('k8s-version-to-images') + default_k8s_versions = json.loads(k8s_v).keys() + else: + k8s_v = get_setting_value_by_name('k8s-versions-current') + default_k8s_versions = k8s_v.split(",") + + # Create clusters + for k8s_version in default_k8s_versions: + if env_details != "env.RANCHER_CLUSTER_NAMES='": + env_details += "," + print("Deploying RKE Cluster using kubernetes version {}".format( + k8s_version)) + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + cluster, aws_nodes = create_and_validate_custom_host( + node_roles, random_cluster_name=True, version=k8s_version) + env_details += cluster.name + print("Successfully deployed {} with kubernetes version {}".format( + cluster.name, k8s_version)) + cluster_details["rke"][cluster.name] = k8s_version + + +@if_not_auto_deploy_rke_import +def test_deploy_rke_import(): + print("Deploying RKE import Clusters") + global env_details + global cluster_details + errors = [] + # get rke k8s versions + rkecommand = "rke config --list-version -a" + result = run_command_with_stderr(rkecommand) + result = result.decode('ascii') + import_k8s_versions = result.split('\n') + import_k8s_versions = list(filter(None, import_k8s_versions)) + print(import_k8s_versions) + + for version in import_k8s_versions: + if env_details != "env.RANCHER_CLUSTER_NAMES='": + env_details += "," + try: + print("Deploying RKE import Cluster using kubernetes version {}". + format(version)) + client, cluster, \ + aws_nodes = \ + create_and_validate_import_cluster(version, supportmatrix=True) + env_details += cluster.name + cluster_details["rke_import"][cluster.name] = version + except Exception as e: + errors.append(e) + + +@if_not_auto_deploy_eks +def test_deploy_eks(): + print("Deploying EKS Clusters") + global env_details + errors = [] + if len(EKS_K8S_VERSIONS) > 1: + k8s_versions = [EKS_K8S_VERSIONS[0], EKS_K8S_VERSIONS[-1]] + else: + k8s_versions = [EKS_K8S_VERSIONS[0]] + + for version in k8s_versions: + if env_details != "env.RANCHER_CLUSTER_NAMES='": + env_details += "," + try: + print("Deploying EKS Cluster using kubernetes version {}".format( + version)) + client, cluster = create_and_validate_eks_cluster(version) + env_details += cluster.name + cluster_details["eks"][cluster.name] = version + except Exception as e: + errors.append(e) + + assert not errors + + +@if_not_auto_deploy_gke +def test_deploy_gke(): + print("Deploying GKE Clusters") + global env_details + errors = [] + + gke_versions, creds = get_gke_version_credentials(multiple_versions=True) + + for i, version in enumerate(gke_versions, start=1): + c_name = "test-auto-gke-{}".format(i) + if env_details != "env.RANCHER_CLUSTER_NAMES='": + env_details += "," + try: + print("Deploying GKE Cluster using kubernetes version {}".format( + version)) + client, cluster = create_and_validate_gke_cluster(c_name, + version, creds) + env_details += cluster.name + cluster_details["gke"][cluster.name] = version + except Exception as e: + errors.append(e) + + assert not errors + + +@if_not_auto_deploy_aks +def test_deploy_aks(): + print("Deploying AKS Clusters") + global env_details + errors = [] + + aks_versions = get_aks_version(multiple_versions=True) + + for version in aks_versions: + if env_details != "env.RANCHER_CLUSTER_NAMES='": + env_details += "," + try: + print("Deploying AKS Cluster using kubernetes version {}".format( + version)) + client, cluster = create_and_validate_aks_cluster(version) + env_details += cluster.name + cluster_details["aks"][cluster.name] = version + except Exception as e: + errors.append(e) + + assert not errors + + +@pytest.fixture(scope='module', autouse="True") +def set_data(request): + if UPDATE_KDM is True: + update_and_validate_kdm(KDM_URL) + + def fin(): + global env_details + global cluster_details + env_details += "'" + print("\n{}".format(env_details)) + print("\n Cluster Details") + for cluster_type in cluster_details: + print(cluster_type + ": " + str(cluster_details[cluster_type])) + for cluster_type in cluster_details: + for cluster_name in cluster_details[cluster_type]: + print(cluster_type + " --> " + + str(cluster_details[cluster_type][cluster_name])) + create_config_file(env_details) + + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ebs_volume_backed_instance.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ebs_volume_backed_instance.py new file mode 100644 index 0000000..8f2bc70 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ebs_volume_backed_instance.py @@ -0,0 +1,146 @@ +import os +import pytest +import time +from lib.aws import AmazonWebServices +from rancher import ApiError + +from .common import ( + AWS_ACCESS_KEY_ID, + AWS_SECRET_ACCESS_KEY, + AWS_REGION, + AWS_SG, + AWS_SUBNET, + AWS_VPC, + AWS_ZONE, + DEFAULT_TIMEOUT, + cluster_cleanup, + get_user_client, + random_name, + wait_for_cluster_delete, + wait_for_nodes_to_become_active +) +from .test_rke_cluster_provisioning import ( + validate_rke_dm_host_1, + engine_install_url +) + + +def test_provision_encrypted_instance(client, + encrypted_cluster_nodepool): + """ + Provisions an EC2 nodepool with encrypted EBS volume backed instances by providing + a flag on the node template and ensures that the provisioned instances are encrypted + """ + cluster, nodepools = encrypted_cluster_nodepool + aws_nodes = get_aws_nodes_from_nodepools(client, cluster, nodepools) + check_if_volumes_are_encrypted(aws_nodes) + + +def get_aws_nodes_from_nodepools(client, cluster, nodepools): + """ + Retrieves the AWS Nodes related to the nodes in the nodepool so that + methods invoking the AWS CLI defined in aws.py can be called on the nodes + """ + wait_for_nodes_to_become_active(client, cluster) + aws_nodes = [] + for nodepool in nodepools: + nodes = nodepool.nodes().data + for node in nodes: + node_ip_address = node['ipAddress'] + ip_address_filter = [{ + 'Name': 'private-ip-address', 'Values': [node_ip_address]}] + nodes = AmazonWebServices().get_nodes(ip_address_filter) + assert len(nodes) == 1, \ + "Multiple aws_nodes seem to have private-ip-address %s" \ + % node_ip_address + aws_nodes.append(nodes[0]) + return aws_nodes + + +def check_if_volumes_are_encrypted(aws_nodes): + """ + Given a set of AWS Nodes, return whether the nodes have encrypted EBS volumes + """ + for aws_node in aws_nodes: + provider_node_id = aws_node.provider_node_id + volumes = AmazonWebServices().get_ebs_volumes(provider_node_id) + for volume in volumes: + assert volume['Encrypted'] + + +@pytest.fixture(scope='module') +def client(): + """ + A user client to be used in tests + """ + return get_user_client() + + +@pytest.fixture(scope='module') +def node_template_ec2_with_encryption(client): + """ + A node template that defines a set of encrypted EC2 volume backed instances + """ + def _attempt_delete_node_template(client, node_template, + timeout=DEFAULT_TIMEOUT, + sleep_time=.5): + start = time.time() + while node_template: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for node template %s to get deleted" + % node_template["name"]) + time.sleep(sleep_time) + client.reload(node_template) + try: + client.delete(node_template) + break + except ApiError: + pass + except Exception as e: + raise e + + ec2_cloud_credential_config = {"accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY} + ec2_cloud_credential = client.create_cloud_credential( + amazonec2credentialConfig=ec2_cloud_credential_config + ) + amazonec2Config = { + "instanceType": "t3a.medium", + "region": AWS_REGION, + "rootSize": "16", + "securityGroup": [AWS_SG], + "sshUser": "ubuntu", + "subnetId": AWS_SUBNET, + "usePrivateAddress": False, + "volumeType": "gp2", + "vpcId": AWS_VPC, + "zone": AWS_ZONE, + "encryptEbsVolume": True + } + + node_template = client.create_node_template( + amazonec2Config=amazonec2Config, + name=random_name(), + useInternalIpAddress=True, + driver="amazonec2", + engineInstallURL=engine_install_url, + cloudCredentialId=ec2_cloud_credential.id + + ) + node_template = client.wait_success(node_template) + yield node_template + _attempt_delete_node_template(client, node_template) + + +@pytest.fixture(scope='module') +def encrypted_cluster_nodepool(client, node_template_ec2_with_encryption): + """ + Returns a cluster with a single nodepool of encrypted EBS volume backed EC2 instances + """ + cluster, nodepools = validate_rke_dm_host_1( + node_template_ec2_with_encryption, + attemptDelete=False) + yield (cluster, nodepools) + cluster_cleanup(client, cluster) + wait_for_cluster_delete(client, cluster["name"]) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_cluster.py new file mode 100644 index 0000000..3f6a704 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_cluster.py @@ -0,0 +1,68 @@ +from .common import * # NOQA +import pytest + +EKS_ACCESS_KEY = os.environ.get('RANCHER_EKS_ACCESS_KEY', "") +EKS_SECRET_KEY = os.environ.get('RANCHER_EKS_SECRET_KEY', "") +EKS_AMI = os.environ.get('RANCHER_EKS_AMI', "") +EKS_REGION = os.environ.get('RANCHER_EKS_REGION', "us-west-2") +EKS_K8S_VERSION = os.environ.get('RANCHER_EKS_K8S_VERSION', "1.17") + +# Hardcoded to follow UI-style: +# https://github.com/rancher/ui/blob/master/lib/shared/addon/components/cluster-driver/driver-amazoneks/component.js +EKS_K8S_VERSIONS = os.environ.get('RANCHER_EKS_K8S_VERSIONS', + "1.17,1.16,1.15").split(",") + +ekscredential = pytest.mark.skipif(not (EKS_ACCESS_KEY and EKS_SECRET_KEY), + reason='EKS Credentials not provided, ' + 'cannot create cluster') + + +@ekscredential +def test_create_eks_cluster(): + client, cluster = create_and_validate_eks_cluster(EKS_K8S_VERSION) + cluster_cleanup(client, cluster) + + +def create_and_validate_eks_cluster(k8s_version): + client = get_user_client() + eks_config = get_eks_config(k8s_version) + + print("Cluster creation") + cluster = client.create_cluster(eks_config) + print(cluster) + cluster = validate_cluster(client, cluster, check_intermediate_state=True, + skipIngresscheck=True) + return client, cluster + + +def get_eks_config(version): + + amazon_config = { + "accessKey": EKS_ACCESS_KEY, + "secretKey": EKS_SECRET_KEY, + "instanceType": "m4.large", + "maximumNodes": 3, + "minimumNodes": 1, + "kubernetesVersion": version, + "region": EKS_REGION, + "subnets": [], + "type": "amazonElasticContainerServiceConfig", + "virtualNetwork": None, + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + } + + if EKS_AMI is not None: + amazon_config.update({"ami": EKS_AMI}) + + # Generate the config for EKS cluster + eks_config = { + + "amazonElasticContainerServiceConfig": amazon_config, + "name": random_test_name("test-auto-eks"), + "type": "cluster" + } + print("\nEKS Configuration") + print(eks_config) + + return eks_config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_v2_hosted_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_v2_hosted_cluster.py new file mode 100644 index 0000000..625af12 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_eks_v2_hosted_cluster.py @@ -0,0 +1,444 @@ +import os +from .common import * +from .test_create_ha import resource_prefix +from lib.aws import AmazonWebServices +import pytest + +EKS_ACCESS_KEY = os.environ.get('RANCHER_EKS_ACCESS_KEY', "") +EKS_SECRET_KEY = os.environ.get('RANCHER_EKS_SECRET_KEY', "") +EKS_REGION = os.environ.get('RANCHER_EKS_REGION', "us-east-2") +EKS_K8S_VERSION = os.environ.get('RANCHER_EKS_K8S_VERSION', "1.17") +EKS_NODESIZE = os.environ.get('RANCHER_EKS_NODESIZE', 2) +KMS_KEY = os.environ.get('RANCHER_KMS_KEY', None) +SECRET_ENCRYPTION = os.environ.get('RANCHER_SECRET_ENCRYPTION', False) +LOGGING_TYPES = os.environ.get('RANCHER_LOGGING_TYPES', None) +EKS_SERVICE_ROLE = os.environ.get('RANCHER_EKS_SERVICE_ROLE', None) +EKS_SUBNETS = os.environ.get('RANCHER_EKS_SUBNETS', None) +EKS_SECURITYGROUP = os.environ.get('RANCHER_EKS_SECURITYGROUP', None) +AWS_SSH_KEY_NAME = os.environ.get("AWS_SSH_KEY_NAME") +EKS_PUBLIC_ACCESS_SOURCES = \ + os.environ.get('RANCHER_EKS_PUBLIC_ACCESS_SOURCES', None) +ekscredential = pytest.mark.skipif(not (EKS_ACCESS_KEY and EKS_SECRET_KEY), + reason='EKS Credentials not provided, ' + 'cannot create cluster') +DEFAULT_TIMEOUT_EKS = 1200 +IMPORTED_EKS_CLUSTERS = [] + +cluster_details = {} + +eks_config = { + "imported": False, + "kubernetesVersion": EKS_K8S_VERSION, + "privateAccess": False, + "publicAccess": True, + "publicAccessSources": [], + "securityGroups": [], + "serviceRole": "", + "subnets": [], + "tags": {}, + "loggingTypes": [], + "secretsEncryption": False, + "kmsKey": "", + "region": EKS_REGION, + "type": "eksclusterconfigspec", + "nodeGroups": [{ + "version": EKS_K8S_VERSION, + "desiredSize": EKS_NODESIZE, + "diskSize": 20, + "gpu": False, + "instanceType": "t3.medium", + "maxSize": EKS_NODESIZE, + "minSize": EKS_NODESIZE, + "nodegroupName": random_test_name("test-ng"), + "requestSpotInstances": False, + "resourceTags": {}, + "type": "nodeGroup", + "subnets": [], + "tags": {}, + "labels": {}, + "ec2SshKey": "" + + }] + } + + +@ekscredential +def test_eks_v2_hosted_cluster_create_basic(): + """ + Create a hosted EKS v2 cluster with all default values from the UI + """ + client = get_user_client() + cluster_name = random_test_name("test-auto-eks") + eks_config_temp = get_eks_config_basic(cluster_name) + cluster_config = { + "eksConfig": eks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + cluster = create_and_validate_eks_cluster(cluster_config) + + # validate cluster created + validate_eks_cluster(cluster_name, eks_config_temp) + + # validate nodegroups created + validate_nodegroup(eks_config_temp["nodeGroups"], cluster_name) + hosted_cluster_cleanup(client, cluster, cluster_name) + + +@ekscredential +def test_eks_v2_hosted_cluster_create_all(): + """ + Create a hosted EKS v2 cluster by giving in value of + every param of eks config from UI + """ + cluster_name = random_test_name("test-auto-eks") + eks_config_temp = get_eks_config_all(cluster_name) + cluster_config = { + "eksConfig": eks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + create_and_validate_eks_cluster(cluster_config) + + # validate cluster created + validate_eks_cluster(cluster_name, eks_config_temp) + + # validate nodegroups created + validate_nodegroup(eks_config_temp["nodeGroups"], cluster_name) + + +@ekscredential +def test_eks_v2_hosted_cluster_edit(): + """ + Create a hosted EKS v2 cluster. + Edit the following input fields: + cluster level tags, add node groups, + add/delete logging types, add new cloud cred + """ + cluster_name = random_test_name("test-auto-eks") + eks_config_temp = get_eks_config_basic(cluster_name) + cluster_config = { + "eksConfig": eks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + client, cluster = create_and_validate_eks_cluster(cluster_config) + + # edit cluster + cluster = edit_eks_cluster(cluster, eks_config_temp) + + # validate cluster created + validate_eks_cluster(cluster_name, eks_config_temp) + + # validate nodegroups created + validate_nodegroup(eks_config_temp["nodeGroups"], cluster_name) + + +@ekscredential +def test_eks_v2_hosted_cluster_delete(): + """ + Delete a created hosted EKS v2 cluster and verify it is deleted in the backend + """ + cluster_name = random_test_name("test-auto-eks") + eks_config_temp = get_eks_config_basic(cluster_name) + cluster_config = { + "eksConfig": eks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + client, cluster = create_and_validate_eks_cluster(cluster_config) + # delete cluster + client.delete(cluster) + wait_for_cluster_delete(client, cluster) + AmazonWebServices().wait_for_delete_eks_cluster(cluster_name) + + +@ekscredential +def test_eks_v2_create_import_cluster(): + """ + Create an imported EKS cluster with some default values in EKS config + """ + display_name = create_resources_eks() + cluster_name = random_test_name("test-auto-eks") + eks_config_temp = get_eks_config_basic(cluster_name) + eks_config_temp["imported"] = True + + cluster_config = { + "eksConfig": eks_config_temp, + "name": cluster_name, + "type": "cluster", + "dockerRootDir": "/var/lib/docker", + "enableNetworkPolicy": False, + "enableClusterAlerting": False, + "enableClusterMonitoring": False + } + create_and_validate_eks_cluster(cluster_config, + imported=True) + + +def create_resources_eks(): + """ + Create an EKS cluster from the EKS console + """ + cluster_name = resource_prefix + "-ekscluster" + AmazonWebServices().create_eks_cluster(cluster_name) + IMPORTED_EKS_CLUSTERS.append(cluster_name) + AmazonWebServices().wait_for_eks_cluster_state(cluster_name, "ACTIVE") + return cluster_name + + +def create_and_validate_eks_cluster(cluster_config, imported=False): + """ + Create and validate EKS cluster + :param cluster_config: config of the cluster + :param imported: imported is true when user creates an imported cluster + :return: client, cluster + """ + client = get_user_client() + print("Creating EKS cluster") + print("\nEKS Configuration: {}".format(cluster_config)) + cluster = client.create_cluster(cluster_config) + print(cluster) + cluster_details[cluster["name"]] = cluster + intermediate_state = False if imported else True + cluster = validate_cluster(client, cluster, + check_intermediate_state=intermediate_state, + skipIngresscheck=True, + timeout=DEFAULT_TIMEOUT_EKS) + return client, cluster + + +def get_aws_cloud_credential(): + """ + Create an AWS cloud creds + :return: ec2_cloud_credential + """ + client = get_user_client() + ec2_cloud_credential_config = { + "accessKey": EKS_ACCESS_KEY, + "secretKey": EKS_SECRET_KEY + } + ec2_cloud_credential = client.create_cloud_credential( + amazonec2credentialConfig=ec2_cloud_credential_config + ) + return ec2_cloud_credential + + +def get_logging_types(): + """ + Split all logging types + :return: logging_types + """ + logging_types = [] + if LOGGING_TYPES is not None: + temp = LOGGING_TYPES.split(",") + for logging in temp: + logging_types.append(logging) + return logging_types + + +def get_eks_config_basic(cluster_name): + """ + FIlling in params for a basic EKS v2 cluster + created through UI with default values + :param cluster_name: + :return: eks_config + """ + ec2_cloud_credential = get_aws_cloud_credential() + global eks_config + eks_config_temp = eks_config.copy() + eks_config_temp["displayName"] = cluster_name + eks_config_temp["amazonCredentialSecret"] = ec2_cloud_credential.id + eks_config_temp["subnets"] = [] \ + if EKS_SUBNETS is None else EKS_SUBNETS.split(",") + eks_config_temp["securityGroups"] = [] \ + if EKS_SECURITYGROUP is None else EKS_SECURITYGROUP.split(",") + eks_config_temp["nodeGroups"][0]["requestedSpotInstances"] = False + eks_config_temp["nodeGroups"][0]["resourceTags"] = {} + eks_config_temp["nodeGroups"][0]["version"] = EKS_K8S_VERSION + return eks_config_temp + + +def get_eks_config_all(cluster_name): + """ + FIlling in params for a EKS v2 cluster + created through UI with all values give + :param cluster_name: + :return: eks_config + """ + ec2_cloud_credential = get_aws_cloud_credential() + global eks_config + public_access = [] if EKS_PUBLIC_ACCESS_SOURCES \ + is None else EKS_PUBLIC_ACCESS_SOURCES.split(",") + eks_config_temp = eks_config.copy() + eks_config_temp["displayName"] = cluster_name + eks_config_temp["amazonCredentialSecret"] = ec2_cloud_credential.id + if KMS_KEY is not None: eks_config_temp["kmsKey"] = KMS_KEY + if SECRET_ENCRYPTION: eks_config_temp["secretsEncryption"] = \ + SECRET_ENCRYPTION + eks_config_temp["subnets"] = [] \ + if EKS_SUBNETS is None else EKS_SUBNETS.split(",") + eks_config_temp["securityGroups"] = [] \ + if EKS_SECURITYGROUP is None else EKS_SECURITYGROUP.split(",") + eks_config_temp["publicAccessSources"] = public_access + eks_config_temp["tags"] = {"cluster-level": "tag1"} + eks_config_temp["nodeGroups"] = [] + eks_config_temp["nodeGroups"].append(get_new_node()) + eks_config_temp["nodeGroups"][0]["tags"] = \ + {"nodegroup-level": "tag1", "nodegroup-level": "tag2"} + eks_config_temp["nodeGroups"][0]["labels"] = {"label1": "value1"} + eks_config_temp["loggingTypes"] = get_logging_types() + eks_config_temp["serviceRole"] = EKS_SERVICE_ROLE + eks_config_temp["ec2SshKey"] = AWS_SSH_KEY_NAME + return eks_config_temp + + +def get_new_node(): + """ + Create a new node group + :return: new_nodegroup + """ + new_nodegroup = { + "desiredSize": EKS_NODESIZE, + "diskSize": 20, + "gpu": False, + "instanceType": "t3.medium", + "maxSize": EKS_NODESIZE, + "minSize": EKS_NODESIZE, + "nodegroupName": random_test_name("test-ng"), + "ec2SshKey": AWS_SSH_KEY_NAME.split(".pem")[0], + "type": "nodeGroup" + } + return new_nodegroup + + +def validate_eks_cluster(cluster_name, eks_config_temp): + """ + Validate EKS cluster details + :param cluster_name: cluster name to be validated + :param eks_config_temp: eks_config + :return: + """ + eks_cluster = AmazonWebServices().describe_eks_cluster(cluster_name) + print("\nEKS cluster deployed in EKS Console: {}". + format(eks_cluster["cluster"])) + + # check k8s version + assert eks_cluster["cluster"]["version"] == \ + eks_config_temp["kubernetesVersion"], "K8s version is incorrect" + + # check cluster status + assert eks_cluster["cluster"]["status"] == "ACTIVE", \ + "Cluster is NOT in active state" + + # verify security groups + assert eks_cluster["cluster"]["resourcesVpcConfig"]["securityGroupIds"].sort() \ + == eks_config_temp["securityGroups"].sort()\ + , "Mismatch in Security Groups" + + # verify subnets + if "subnets" in eks_config_temp.keys(): + assert \ + eks_cluster["cluster"]["resourcesVpcConfig"]["subnetIds"].sort() \ + == eks_config_temp["subnets"].sort(), "Mismatch in Security Groups" + + # verify logging types + if "loggingTypes" in eks_config_temp.keys(): + for logging in eks_cluster["cluster"]["logging"]["clusterLogging"]: + if logging["enabled"]: + assert logging["types"].sort() \ + == eks_config_temp["loggingTypes"].sort() , \ + "Mismatch in Logging types set" + + # verify serviceRole + if "serviceRole" in eks_config_temp.keys(): + assert eks_config_temp["serviceRole"] in \ + eks_cluster["cluster"]["roleArn"] + + # verify publicAccessSources + if "publicAccessSources" in eks_config_temp.keys(): + assert eks_config_temp["publicAccessSources"].sort() == \ + eks_cluster["cluster"]["resourcesVpcConfig"]["publicAccessCidrs"].sort() + + +def edit_eks_cluster(cluster, eks_config_temp): + """ + Edit EKS v2 cluster + :param cluster: cluster + :param eks_config_temp: eks_config + :return: cluster + """ + # edit eks_config_temp + # add new cloud cred + ec2_cloud_credential_new = get_aws_cloud_credential() + eks_config_temp["amazonCredentialSecret"] = ec2_cloud_credential_new.id + # add cluster level tags + eks_config_temp["tags"] = {"cluster-level-2": "tag2"} + # add node group + new_nodegroup = get_new_node() + eks_config_temp["nodeGroups"].append(new_nodegroup) + # modify logging + eks_config_temp["loggingTypes"] = ["audit","api","authenticator"] + client = get_user_client() + client.update(cluster, name=cluster.name, eksConfig=eks_config_temp) + cluster = validate_cluster(client, cluster, intermediate_state="updating", + check_intermediate_state=True, + skipIngresscheck=True, + timeout=DEFAULT_TIMEOUT_EKS) + return cluster + + +def validate_nodegroup(nodegroup_list, cluster_name): + """ + Validate nodegroup details + :param nodegroup_list: list of nodegroups + :param cluster_name: cluster name + :return: + """ + for nodegroup in nodegroup_list: + print("nodegroup:", nodegroup) + eks_nodegroup = AmazonWebServices().describe_eks_nodegroup( + cluster_name, nodegroup["nodegroupName"] + ) + print("\nNode Group from EKS console: {}".format(eks_nodegroup)) + + # k8s version check + eks_cluster = AmazonWebServices().describe_eks_cluster(cluster_name) + assert eks_cluster["cluster"]["version"] == \ + eks_nodegroup["nodegroup"]["version"], \ + "Mismatch between K8s version of cluster and nodegroup" + + # status of nodegroup + assert eks_nodegroup["nodegroup"]["status"] == "ACTIVE", \ + "Nodegroups are not in active status" + + # check scalingConfig + assert int(nodegroup["maxSize"]) \ + == eks_nodegroup["nodegroup"]["scalingConfig"]["maxSize"], \ + "maxSize is incorrect on the nodes" + assert int(nodegroup["minSize"]) \ + == eks_nodegroup["nodegroup"]["scalingConfig"]["minSize"], \ + "minSize is incorrect on the nodes" + + # check ec2SshKey + if "ec2SshKey" in nodegroup.keys() and \ + nodegroup["ec2SshKey"] is not "": + assert nodegroup["ec2SshKey"] \ + == eks_nodegroup["nodegroup"]["remoteAccess"]["ec2SshKey"], \ + "Ssh key is incorrect on the nodes" \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_gke_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_gke_cluster.py new file mode 100644 index 0000000..90dcfcc --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_gke_cluster.py @@ -0,0 +1,107 @@ +from .common import * # NOQA +import requests +import pytest + +CREDENTIALS = os.environ.get('RANCHER_GKE_CREDENTIAL', "") +GKE_MASTER_VERSION = os.environ.get('RANCHER_GKE_MASTER_VERSION', "") + +gkecredential = pytest.mark.skipif(not CREDENTIALS, reason='GKE Credentials ' + 'not provided, cannot create cluster') + + +@gkecredential +def test_create_gke_cluster(): + # Obtain GKE config data + gke_version, credential_data = get_gke_version_credentials() + client, cluster = create_and_validate_gke_cluster("test-auto-gke", + gke_version, + credential_data) + cluster_cleanup(client, cluster) + + +def create_and_validate_gke_cluster(name, version, credential_data): + gke_config = get_gke_config(name, version, credential_data) + client = get_user_client() + print("Cluster creation") + cluster = client.create_cluster(gke_config) + print(cluster) + cluster = validate_cluster(client, cluster, check_intermediate_state=True, + skipIngresscheck=True) + return client, cluster + + +def get_gke_version_credentials(multiple_versions=False): + credfilename = "credential.txt" + PATH = os.path.dirname(os.path.realpath(__file__)) + credfilepath = PATH + "/" + credfilename + + # The json GKE credentials file is being written to a file and then re-read + + f = open(credfilepath, "w") + f.write(CREDENTIALS) + f.close() + + credentialdata = readDataFile(os.path.dirname(os.path.realpath(__file__)) + + "/", credfilename) + print(credentialdata) + + if not GKE_MASTER_VERSION: + data_test = { + "credentials": credentialdata, + "zone": "us-central1-f", + "projectId": "rancher-qa" + } + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + USER_TOKEN} + + gke_version_url = CATTLE_TEST_URL + "/meta/gkeVersions" + print(gke_version_url) + response = requests.post(gke_version_url, json=data_test, + verify=False, headers=headers) + + assert response.status_code == 200 + assert response.content is not None + print(response.content) + json_response = json.loads(response.content) + validMasterVersions = json_response["validMasterVersions"] + if multiple_versions and len(validMasterVersions) > 1: + gkemasterversion = [validMasterVersions[0], + validMasterVersions[-1]] + else: + gkemasterversion = validMasterVersions[0] + else: + gkemasterversion = GKE_MASTER_VERSION + print(gkemasterversion) + return gkemasterversion, credentialdata + + +def get_gke_config(name, version, credential_data): + + # Get GKE configuration + gke_config = { + "googleKubernetesEngineConfig": { + "diskSizeGb": 100, + "enableAlphaFeature": False, + "enableHorizontalPodAutoscaling": True, + "enableHttpLoadBalancing": True, + "enableKubernetesDashboard": False, + "enableLegacyAbac": False, + "enableNetworkPolicyConfig": True, + "enableStackdriverLogging": True, + "enableStackdriverMonitoring": True, + "masterVersion": version, + "machineType": "g1-small", + "type": "googleKubernetesEngineConfig", + "nodeCount": 3, + "zone": "us-central1-f", + "clusterIpv4Cidr": " ", + "credential": credential_data, + "projectId": "rancher-qa", + + }, + "name": name, + "type": "cluster" + } + + return gke_config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_global_role.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_global_role.py new file mode 100644 index 0000000..81af0c8 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_global_role.py @@ -0,0 +1,419 @@ +from .common import * # NOQA +from rancher import ApiError +import pytest + +# values used to create a catalog +BRANCH = "dev" +URL = "https://git.rancher.io/system-charts" + + +def test_global_role_create_1(remove_resource): + """ test that admin can create a new global role, assign it + to a standard user, then the user get the newly-assigned permission + + a global role for managing catalogs is used for this test. + """ + + # create a new global role that permits creating catalogs + gr = validate_create_global_role(ADMIN_TOKEN, True, True) + remove_resource(gr) + # create a new user + client = get_admin_client() + user, token = create_user(client) + remove_resource(user) + # check that the user can NOT create catalogs + name = random_name() + validate_create_catalog(token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=False) + client.create_global_role_binding(globalRoleId=gr.id, userId=user.id) + # check that the user has the global role + target_grb = client.list_global_role_binding(userId=user.id, + globalRoleId=gr.id).data + assert len(target_grb) == 1 + # the user can create catalogs + obj = validate_create_catalog(token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=True) + remove_resource(obj) + + +def test_global_role_create_2(remove_resource): + """ test that admin can create a new global role, assign it + to a standard user, then the user get the newly-assigned permission + + a global role for listing clusters is used for this test. + """ + + # create a new global role that permits listing clusters + gr = validate_create_global_role(ADMIN_TOKEN, True, True, + TEMPLATE_LIST_CLUSTER) + remove_resource(gr) + # create a new user + client = get_admin_client() + user, token = create_user(client) + remove_resource(user) + # check that the new user can not list cluster + user_client = get_client_for_token(token) + data = user_client.list_cluster().data + assert len(data) == 0, "the user should not be able to list any cluster" + client.create_global_role_binding(globalRoleId=gr.id, userId=user.id) + # check that the user has the global role + target_grb = client.list_global_role_binding(userId=user.id, + globalRoleId=gr.id).data + assert len(target_grb) == 1 + # check that the new user can list cluster + data = user_client.list_cluster().data + assert len(data) > 0 + + +def test_global_role_edit(remove_resource): + """ test that admin can edit a global role, and permissions of user who + binds to this role reflect the change""" + + gr = validate_create_global_role(ADMIN_TOKEN, True, True) + remove_resource(gr) + client = get_admin_client() + user, user_token = create_user(client) + remove_resource(user) + # check that the user can NOT create catalogs + name = random_name() + validate_create_catalog(user_token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=False) + client.create_global_role_binding(globalRoleId=gr.id, userId=user.id) + # now he can create catalogs + catalog = validate_create_catalog(user_token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=True) + remove_resource(catalog) + # edit the global role + validate_edit_global_role(ADMIN_TOKEN, gr, True) + # the user can not create new catalog + validate_create_catalog(user_token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=False) + + +def test_global_role_delete(remove_resource): + """ test that admin can edit a global role, and permissions of user who + binds to this role reflect the change""" + + gr = validate_create_global_role(ADMIN_TOKEN, True, True) + remove_resource(gr) + client = get_admin_client() + user, token = create_user(client) + remove_resource(user) + client.create_global_role_binding(globalRoleId=gr.id, userId=user.id) + name = random_name() + catalog = validate_create_catalog(token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=True) + remove_resource(catalog) + validate_delete_global_role(ADMIN_TOKEN, gr, True) + # the user can not create new catalog + validate_create_catalog(token, + catalog_name=name, + branch=BRANCH, + url=URL, + permission=False) + + +def test_builtin_global_role(): + # builtin global role can not be deleted + client = get_admin_client() + gr_list = client.list_global_role(name="Manage Users").data + assert len(gr_list) == 1 + gr = gr_list[0] + try: + client.delete(gr) + except ApiError as e: + assert e.error.status == 403 + assert e.error.code == 'PermissionDenied' + # builtin global role can be set as new user default + gr = client.update(gr, {"newUserDefault": "true"}) + gr = client.reload(gr) + assert gr.newUserDefault is True + gr = client.update(gr, {"newUserDefault": "false"}) + gr = client.reload(gr) + assert gr.newUserDefault is False + + +def validate_list_global_role(token, permission=False): + client = get_client_for_token(token) + res = client.list_global_role().data + if not permission: + assert len(res) == 0 + else: + assert len(res) > 0 + + +@if_test_rbac +def test_rbac_global_role_list_cluster_owner(): + # cluster owner can not list global roles + token = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_list_global_role(token, False) + + +@if_test_rbac +def test_rbac_global_role_list_cluster_member(): + # cluster member can not list global roles + token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_list_global_role(token, False) + + +@if_test_rbac +def test_rbac_global_role_list_project_owner(): + # project owner can not list global roles + token = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_list_global_role(token, False) + + +@if_test_rbac +def test_rbac_global_role_list_project_member(): + # project member can not list global roles + token = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_list_global_role(token, False) + + +@if_test_rbac +def test_rbac_global_role_list_project_read_only(): + # project read-only can not list global roles + token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_list_global_role(token, False) + + +@if_test_rbac +def test_rbac_global_role_create_cluster_owner(): + # cluster owner can not create global roles + token = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_create_global_role(token, permission=False) + + +@if_test_rbac +def test_rbac_global_role_create_cluster_member(): + # cluster member can not create global roles + token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_create_global_role(token, permission=False) + + +@if_test_rbac +def test_rbac_global_role_create_project_owner(): + # project owner can not create global roles + token = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_create_global_role(token, permission=False) + + +@if_test_rbac +def test_rbac_global_role_create_project_member(): + # project member can not create global roles + token = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_create_global_role(token, permission=False) + + +@if_test_rbac +def test_rbac_global_role_create_project_read_only(): + # project read-only can not create global roles + token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_create_global_role(token, permission=False) + + +@if_test_rbac +def test_rbac_global_role_delete_cluster_owner(remove_resource): + # cluster owner can not delete global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_delete_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_delete_cluster_member(remove_resource): + # cluster member can not delete global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_delete_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_delete_project_owner(remove_resource): + # project owner can not delete global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_delete_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_delete_project_member(remove_resource): + # project member can not delete global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_delete_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_delete_project_read_only(remove_resource): + # project read-only can not delete global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_delete_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_edit_cluster_owner(remove_resource): + # cluster owner can not edit global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_edit_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_edit_cluster_member(remove_resource): + # cluster member can not edit global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_edit_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_edit_project_owner(remove_resource): + # project owner can not edit global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_edit_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_edit_project_member(remove_resource): + # project member can not edit global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_edit_global_role(token, gr, False) + + +@if_test_rbac +def test_rbac_global_role_edit_project_read_only(remove_resource): + # project read-only can not edit global roles + gr = create_gr() + remove_resource(gr) + token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_edit_global_role(token, gr, False) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_global_admin_client_and_cluster() + create_kubeconfig(cluster) + + +def create_gr(): + return validate_create_global_role(ADMIN_TOKEN, False, True) + + +def validate_create_global_role(token, new_user_default=False, + permission=False, template=None): + """ validate if the user has the permission to create global role.""" + + if template is None: + template = TEMPLATE_MANAGE_CATALOG + client = get_client_for_token(token) + t_name = random_name() + template = generate_template_global_role(t_name, new_user_default, + template) + # catch the expected error if the user has no permission to create + if not permission: + with pytest.raises(ApiError) as e: + client.create_global_role(template) + assert e.value.error.status == 403 and \ + e.value.error.code == 'Forbidden', \ + "user with no permission should receive 403: Forbidden" + return None + else: + try: + client.create_global_role(template) + except ApiError as e: + assert False, "user with permission should receive no exception:" \ + + e.error.status + " " + e.error.code + + # check that the global role is created + gr_list = client.list_global_role(name=t_name).data + assert len(gr_list) == 1 + gr = gr_list[0] + # check that the global role is set to be the default + assert gr.newUserDefault == new_user_default + return gr + + +def validate_delete_global_role(token, global_role, permission=False): + """ validate if the user has the permission to delete global role.""" + + client = get_client_for_token(token) + # catch the expected error if the user has no permission to delete + if not permission: + with pytest.raises(ApiError) as e: + client.delete(global_role) + assert e.value.error.status == 403 and \ + e.value.error.code == 'Forbidden', \ + "user with no permission should receive 403: Forbidden" + return + else: + try: + client.delete(global_role) + except ApiError as e: + assert False, "user with permission should receive no exception:" \ + + e.error.status + " " + e.error.code + # check that the global role is removed + client = get_client_for_token(ADMIN_TOKEN) + assert client.reload(global_role) is None + + +def validate_edit_global_role(token, global_role, permission=False): + """ for the testing purpose, this method removes all permissions in + the global role and unset it as new user default.""" + + client = get_client_for_token(token) + # edit the global role + template = deepcopy(TEMPLATE_MANAGE_CATALOG) + template["newUserDefault"] = "false" + template["rules"] = [] + # catch the expected error if the user has no permission to edit + if not permission: + with pytest.raises(ApiError) as e: + client.update(global_role, template) + assert e.value.error.status == 403 and \ + e.value.error.code == 'Forbidden', \ + "user with no permission should receive 403: Forbidden" + return None + else: + try: + client.update(global_role, template) + except ApiError as e: + assert False, "user with permission should receive no exception:" \ + + e.error.status + " " + e.error.code + + # check that the global role is not the new user default + gr = client.reload(global_role) + assert gr.newUserDefault is False + # check that there is no rule left + assert (gr.rules is None or gr.rules == []) + return gr diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_group_grb.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_group_grb.py new file mode 100644 index 0000000..354351b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_group_grb.py @@ -0,0 +1,313 @@ +from .test_auth import enable_ad, load_setup_data +from .common import * # NOQA +from rancher import ApiError +import pytest +import requests + +''' +Prerequisite: + - Enable Auth + - Optional: searching nested group enabled + - All users used for testing global group role binding should not be used + to create the cluster when preparing the Rancher setup +''' + +# values used to create a catalog +BRANCH = "dev" +URL = "https://git.rancher.io/system-charts" +# the link to search principals in the auth provider + + +@if_test_group_rbac +def test_ggrb_1(remove_resource): + """ test that when a global role is assigned to a group, + all users in the group will get the permission; + when the ggrb is removed, all users in the group will lose + the permission. + + the default global role "catalogs-manage" is used + """ + + target_group_name = get_group(NESTED_GROUP_ENABLED) + users = get_user_by_group(target_group_name, NESTED_GROUP_ENABLED) + # check that users can not create catalogs + for user in users: + validate_permission_create_catalog(user, False) + auth_admin = login_as_auth_user(load_setup_data()["admin_user"], + AUTH_USER_PASSWORD) + g_id = get_group_principal_id(target_group_name, token=auth_admin['token']) + ggrb = get_admin_client().create_global_role_binding( + globalRoleId="catalogs-manage", groupPrincipalId=g_id) + # check that users can create catalogs now + for user in users: + catalog = validate_permission_create_catalog(user, True) + remove_resource(catalog) + # delete the ggrb + get_admin_client().delete(ggrb) + # check that users can not create catalogs + for user in users: + validate_permission_create_catalog(user, False) + + +@if_test_group_rbac +def test_ggrb_2(remove_resource): + """ test that after editing the global role, users' + permissions reflect the changes + + Steps: + - users in group1 cannot list clusters or create catalogs + - create a custom global role gr1 that permits creating catalogs + - create the global group role binding ggrb1 to bind gr1 to group1 + - users in group1 can create catalogs now + - edit gr1 to remove the permission of creating catalogs, add the + permission of listing clusters + - users in group1 cannot create catalogs, but can list clusters + """ + + target_group_name = get_group(NESTED_GROUP_ENABLED) + users = get_user_by_group(target_group_name, NESTED_GROUP_ENABLED) + # check that users can not create catalogs or list clusters + for user in users: + validate_permission_create_catalog(user, False) + validate_permission_list_cluster(user, 0) + # create a custom global role that permits create catalogs + admin_c = get_admin_client() + template = generate_template_global_role(name=random_name(), + template=TEMPLATE_MANAGE_CATALOG) + gr = admin_c.create_global_role(template) + remove_resource(gr) + auth_admin = login_as_auth_user(load_setup_data()["admin_user"], + AUTH_USER_PASSWORD) + g_id = get_group_principal_id(target_group_name, token=auth_admin['token']) + ggrb = get_admin_client().create_global_role_binding( + globalRoleId=gr["id"], groupPrincipalId=g_id) + # check that users can create catalogs now, but not list clusters + for user in users: + validate_permission_list_cluster(user, 0) + catalog = validate_permission_create_catalog(user, True) + remove_resource(catalog) + # edit the global role + rules = [ + { + "type": "/v3/schemas/policyRule", + "apiGroups": [ + "management.cattle.io" + ], + "verbs": [ + "get", + "list", + "watch" + ], + "resources": [ + "clusters" + ] + } + ] + admin_c.update(gr, rules=rules) + target_num = len(admin_c.list_cluster().data) + # check that users can list clusters, but not create catalogs + for user in users: + validate_permission_create_catalog(user, False) + validate_permission_list_cluster(user, target_num) + # delete the ggrb + admin_c.delete(ggrb) + for user in users: + validate_permission_list_cluster(user, 0) + + +@if_test_group_rbac +def test_ggrb_3(remove_resource): + """ test that when a global role is assigned to a group, + all users in the group get the permission from the role, + users not in the group do not get the permission + + Steps: + - users in the group cannot list clusters + - users not in the group cannot list clusters + - create a custom global role gr1 that permits listing clusters + - create the global group role binding ggrb1 to bind gr1 to the group + - users in the group can list clusters now + - users not in group still cannot list clusters + - delete the ggrb1 + - users in the group can not list clusters + """ + + target_g, user1 = get_a_group_and_a_user_not_in_it(NESTED_GROUP_ENABLED) + users = get_user_by_group(target_g, NESTED_GROUP_ENABLED) + # check that users in the group can not list clusters + for user in users: + validate_permission_list_cluster(user, 0) + # check that user not in the group can not list clusters + validate_permission_list_cluster(user1, 0) + + auth_admin = login_as_auth_user(load_setup_data()["admin_user"], + AUTH_USER_PASSWORD) + g_id = get_group_principal_id(target_g, token=auth_admin['token']) + # create a custom global role that permits listing clusters + admin_c = get_admin_client() + template = generate_template_global_role(name=random_name(), + template=TEMPLATE_LIST_CLUSTER) + gr = admin_c.create_global_role(template) + remove_resource(gr) + ggrb = admin_c.create_global_role_binding(globalRoleId=gr["id"], + groupPrincipalId=g_id) + remove_resource(ggrb) + target_num = len(admin_c.list_cluster().data) + # check that users in the group can list clusters + for user in users: + validate_permission_list_cluster(user, target_num) + # check that user not in the group can not list clusters + validate_permission_list_cluster(user1, 0) + # delete the ggrb + admin_c.delete(ggrb) + # check that users in the group can not list clusters + for user in users: + validate_permission_list_cluster(user, 0) + + +# cluster owner, cluster member, project owner, project member +# and project read-only can not list ggrb +rbac_list_ggrb = [ + (CLUSTER_OWNER, 0), + (CLUSTER_MEMBER, 0), + (PROJECT_OWNER, 0), + (PROJECT_MEMBER, 0), + (PROJECT_READ_ONLY, 0), +] + +# cluster owner, cluster member, project owner, project member +# and project read-only can not create or delete ggrb +rbac_create_delete_ggrb = [ + (CLUSTER_OWNER, False), + (CLUSTER_MEMBER, False), + (PROJECT_OWNER, False), + (PROJECT_MEMBER, False), + (PROJECT_READ_ONLY, False), +] + + +@if_test_rbac +@pytest.mark.parametrize(["role", "expected_count"], rbac_list_ggrb) +def test_rbac_ggrb_list(role, expected_count): + token = rbac_get_user_token_by_role(role) + validate_permission_list_ggrb(token, expected_count) + + +@if_test_rbac +@pytest.mark.parametrize(["role", "permission"], rbac_create_delete_ggrb) +def test_rbac_ggrb_create(role, permission): + token = rbac_get_user_token_by_role(role) + validate_permission_create_ggrb(token, permission) + + +@if_test_rbac +@pytest.mark.parametrize(["role", "permission"], rbac_create_delete_ggrb) +def test_rbac_ggrb_delete(role, permission): + token = rbac_get_user_token_by_role(role) + validate_permission_delete_ggrb(token, permission) + + +def validate_permission_list_cluster(username, num=0): + """ check if the user from auth provider has the permission to + list clusters + + :param username: username from the auth provider + :param num: expected number of clusters + """ + token = login_as_auth_user(username, AUTH_USER_PASSWORD)['token'] + user_client = get_client_for_token(token) + clusters = user_client.list_cluster().data + assert len(clusters) == num + + +def validate_permission_create_catalog(username, permission=False): + """ check if the user from auth provider has the permission to + create new catalog + """ + name = random_name() + token = login_as_auth_user(username, AUTH_USER_PASSWORD)['token'] + return validate_create_catalog(token, catalog_name=name, branch=BRANCH, + url=URL, permission=permission) + + +def validate_permission_list_ggrb(token, num=0): + """ check if the user from auth provider has the permission to + list global role bindings + """ + user_client = get_client_for_token(token) + clusters = user_client.list_global_role_binding().data + assert len(clusters) == num + + +def validate_permission_create_ggrb(token, permission=False): + """ check if the user from auth provider has the permission to + create group global role bindings + """ + target_group_name = get_group() + auth_admin = login_as_auth_user(load_setup_data()["admin_user"], + AUTH_USER_PASSWORD) + g_id = get_group_principal_id(target_group_name, token=auth_admin['token']) + role = generate_a_global_role() + client = get_client_for_token(token) + if not permission: + with pytest.raises(ApiError) as e: + client.create_global_role_binding(globalRoleId=role["id"], + groupPrincipalId=g_id) + assert e.value.error.status == 403 and \ + e.value.error.code == 'Forbidden', \ + "user with no permission should receive 403: Forbidden" + return None + else: + try: + rtn = \ + client.create_global_role_binding(globalRoleId=role["id"], + groupPrincipalId=g_id) + return rtn + except ApiError as e: + assert False, "user with permission should receive no exception:" \ + + str(e.error.status) + " " + e.error.code + + +def validate_permission_delete_ggrb(token, permission=False): + """ check if the user from auth provider has the permission to + deleting group global role bindings + """ + ggrb = validate_permission_create_ggrb(ADMIN_TOKEN, True) + client = get_client_for_token(token) + if not permission: + with pytest.raises(ApiError) as e: + client.delete(ggrb) + assert e.value.error.status == 403 and \ + e.value.error.code == 'Forbidden', \ + "user with no permission should receive 403: Forbidden" + get_admin_client().delete(ggrb) + else: + try: + client.delete(ggrb) + except ApiError as e: + get_admin_client().delete(ggrb) + assert False, "user with permission should receive no exception:" \ + + str(e.error.status) + " " + e.error.code + + +def generate_a_global_role(): + """ return a global role with the permission of listing cluster""" + admin_c = get_admin_client() + template = generate_template_global_role(name=random_name(), + template=TEMPLATE_LIST_CLUSTER) + return admin_c.create_global_role(template) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + + admin_client = get_admin_client() + ad_enabled = admin_client.by_id_auth_config("activedirectory").enabled + if AUTH_PROVIDER == "activeDirectory" and not ad_enabled: + enable_ad(load_setup_data()["admin_user"], ADMIN_TOKEN, + password=AUTH_USER_PASSWORD, nested=NESTED_GROUP_ENABLED) + + if NESTED_GROUP_ENABLED: + assert is_nested(), "no nested group is found" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_helm_v3.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_helm_v3.py new file mode 100644 index 0000000..c4e3327 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_helm_v3.py @@ -0,0 +1,174 @@ +from .common import * # NOQA +import pytest + +CATALOG_NAME = random_test_name("test-v3") +CATALOG_URL = "https://github.com/rancher/integration-test-charts.git" +BRANCH = "validation-tests" +MYSQL_EXTERNALID_131 = \ + create_catalog_external_id(CATALOG_NAME, "mysql", "1.3.1") +MYSQL_EXTERNALID_132 = \ + create_catalog_external_id(CATALOG_NAME, "mysql", "1.3.2") +cluster_detail = {"cluster1": {"project1": None, "namespace1": None, + "cluster": None}} + + +def test_helm_v3_app_deploy(): + client = get_user_client() + answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + proj_client, ns, project = get_project_details("cluster1") + app = create_and_validate_app( + proj_client, MYSQL_EXTERNALID_131, ns, project, answer) + proj_client.delete(app) + + +def test_helm_v3_app_delete(): + client = get_user_client() + answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + proj_client, ns, project = get_project_details("cluster1") + app = create_and_validate_app( + proj_client, MYSQL_EXTERNALID_131, ns, project, answer) + app = proj_client.delete(app) + validate_app_deletion(proj_client, app.id) + + +def test_helm_v3_app_upgrade_version(): + client = get_user_client() + answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + proj_client, ns, project = get_project_details("cluster1") + # deploy app + app = create_and_validate_app( + proj_client, MYSQL_EXTERNALID_131, ns, project, answer) + + new_answers = get_defaut_question_answers(client, MYSQL_EXTERNALID_132) + # update app + app = update_and_validate_app( + app, proj_client, MYSQL_EXTERNALID_132, ns, project, new_answers) + proj_client.delete(app) + + +def test_helm_v3_app_rollback(): + client = get_user_client() + answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + proj_client, ns, project = get_project_details("cluster1") + # deploy app + app = create_and_validate_app( + proj_client, MYSQL_EXTERNALID_131, ns, project, answer) + rev_id = app.appRevisionId + new_answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_132) + # update app + app = update_and_validate_app( + app, proj_client, MYSQL_EXTERNALID_132, ns, project, new_answer) + proj_client.action(obj=app, + action_name='rollback', + revisionId=rev_id) + app = proj_client.reload(app) + app = validate_catalog_app(proj_client, app, MYSQL_EXTERNALID_131) + proj_client.delete(app) + + +def test_helm_v3_app_answer_override(): + client = get_user_client() + answer = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + proj_client, ns, project = get_project_details("cluster1") + # deploy app + app = create_and_validate_app( + proj_client, MYSQL_EXTERNALID_131, ns, project, answer + ) + answer["mysqlUser"] = "admin1234" + # update app + app = update_and_validate_app( + app, proj_client, MYSQL_EXTERNALID_132, ns, project, answer + ) + assert app["answers"].mysqlUser == "admin1234", \ + "incorrect answer upgrade" + proj_client.delete(app) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster_existing = get_user_client_and_cluster() + cluster_detail["cluster1"]["cluster"] = cluster_existing + cluster_detail["cluster1"]["project1"], \ + cluster_detail["cluster1"]["namespace1"] =\ + create_project_and_ns( + USER_TOKEN, + cluster_existing, + random_test_name("test-helmv3") + ) + # add catalog + admin_client = get_admin_client() + v3_catalog = admin_client.create_catalog( + name=CATALOG_NAME, + baseType="catalog", + branch=BRANCH, + kind="helm", + url=CATALOG_URL, + helmVersion="helm_v3") + assert v3_catalog["helmVersion"] == \ + "helm_v3", "Helm version is not helm_v3" + time.sleep(5) + + def fin(): + admin_client.delete(v3_catalog) + admin_client.delete(cluster_detail["cluster1"]["namespace1"]) + admin_client.delete(cluster_detail["cluster1"]["project1"]) + + request.addfinalizer(fin) + + +def create_and_validate_app(proj_client, externalid, ns, project, answer): + """ + :param proj_client: Project client of the project + where the app will be deployed + :param externalid: App's external ID + :param ns: namespace + :param project: project + :param answer: answers for the app with external_id: externalid + :return: app + """ + app = proj_client.create_app( + name=random_test_name(), + externalId=externalid, + targetNamespace=ns, + projectId=project, + answers=answer) + app = validate_catalog_app(proj_client, app, externalid) + assert app["helmVersion"] == "helm_v3", "Helm version is not helm_v3" + return app + + +def update_and_validate_app(app, proj_client, externalid, ns, project, answer): + """ + :param app: app object to be updated + :param proj_client: Project client of the project + where the app will be deployed + :param externalid: App's external ID + :param ns: namespace + :param project: project + :param answer: answers for the app with external_id: externalid + :return: app + """ + app = proj_client.update( + obj=app, + externalId=externalid, + targetNamespace=ns, + projectId=project, + answers=answer) + app = validate_catalog_app(proj_client, app, externalid, answer) + assert app["helmVersion"] == "helm_v3", "Helm version is not helm_v3" + return app + + +def get_project_details(cluster): + """ + :param cluster: cluster is a "key" in the + cluster_detail pointing to the cluster + :return: proj_client, ns, project + """ + proj_client = get_project_client_for_token( + cluster_detail[cluster]["project1"], + USER_TOKEN + ) + ns = cluster_detail["cluster1"]["namespace1"].name + project = cluster_detail["cluster1"]["project1"].id + return proj_client, ns, project diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_hpa.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_hpa.py new file mode 100644 index 0000000..28170ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_hpa.py @@ -0,0 +1,538 @@ +import pytest +from rancher import ApiError +from .common import * # NOQA + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} + + +def test_create_hpa(): + p_client = namespace["p_client"] + ns = namespace["ns"] + hpa, workload = create_hpa(p_client, ns) + p_client.delete(hpa, workload) + + +def test_edit_hpa(): + p_client = namespace["p_client"] + ns = namespace["ns"] + hpa, workload = edit_hpa(p_client, ns) + p_client.delete(hpa, workload) + + +def test_delete_hpa(): + p_client = namespace["p_client"] + ns = namespace["ns"] + hpa, workload = create_hpa(p_client, ns) + delete_hpa(p_client, hpa, ns) + p_client.delete(workload) + + +rbac_role_list = [ + (CLUSTER_OWNER), + (PROJECT_OWNER), + (PROJECT_MEMBER), + (PROJECT_READ_ONLY), + (CLUSTER_MEMBER), +] + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_create(role, remove_resource): + user_project = None + if(role == CLUSTER_MEMBER): + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = create_project_and_ns(user_token, + namespace["cluster"], + random_test_name( + "cluster-mem")) + p_client = get_project_client_for_token(user_project, user_token) + else: + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + + if (role != PROJECT_READ_ONLY): + newhpa, newworkload = create_hpa(p_client, ns) + remove_resource(newhpa) + remove_resource(newworkload) + else: + project = rbac_get_project() + ns = rbac_get_namespace() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, + user_token) + # Verify Read Only member cannot create hpa objects + with pytest.raises(ApiError) as e: + create_hpa(readonly_user_client, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + if(user_project is not None): + remove_resource(user_project) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_create_negative(role, remove_resource): + if (role == CLUSTER_OWNER): + print(role) + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + hpa, workload = create_hpa(p_client, ns) + remove_resource(hpa) + remove_resource(workload) + else: + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_client = get_project_client_for_token(unshared_project, + cluster_owner_token) + # Workload created by cluster owner in unshared project is passed as + # parameter to create HPA + workload = create_workload(owner_client, ns) + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + with pytest.raises(ApiError) as e: + create_hpa(p_client, ns, workload=workload) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_edit(role, remove_resource): + if (role == PROJECT_READ_ONLY): + verify_hpa_project_readonly_edit(remove_resource) + elif(role == CLUSTER_MEMBER): + verify_hpa_cluster_member_edit(remove_resource) + else: + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + hpa, workload = edit_hpa(p_client, ns) + remove_resource(hpa) + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_edit_negative(role, remove_resource): + if (role == CLUSTER_OWNER): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + hpa, workload = edit_hpa(p_client, ns) + remove_resource(hpa) + remove_resource(workload) + else: + unshared_project = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(role) + unshared_ns = rbac_get_unshared_ns() + user_client = get_project_client_for_token(unshared_project, + user_token) + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + + # Cluster owner client created in the unshared project + cluster_owner_p_client = \ + get_project_client_for_token(unshared_project, cluster_owner_token) + # Verify that some users cannot edit hpa created by cluster owner + verify_edit_forbidden(user_client, remove_resource, + cluster_owner_client=cluster_owner_p_client, + ns=unshared_ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_delete(role, remove_resource): + user_project = None + if(role == CLUSTER_MEMBER): + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = create_project_and_ns(user_token, + namespace["cluster"], + random_test_name( + "cluster-mem")) + p_client = get_project_client_for_token(user_project, user_token) + else: + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + + if (role != PROJECT_READ_ONLY): + hpa, workload = create_hpa(p_client, ns) + delete_hpa(p_client, hpa, ns) + remove_resource(workload) + remove_resource(hpa) + if user_project is not None: + remove_resource(user_project) + + if (role == PROJECT_READ_ONLY): + project = rbac_get_project() + ns = rbac_get_namespace() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_p_client = \ + get_project_client_for_token(project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + user_client = get_project_client_for_token(project, user_token) + + # As a Cluster owner create a HPA object + hpa, workload = create_hpa(cluster_owner_p_client, ns) + # Verify that the Read Only member cannot delete the HPA objects + # created by Cluster Owner + with pytest.raises(ApiError) as e: + delete_hpa(user_client, hpa, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(hpa) + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_delete_negative(role, remove_resource): + if (role == CLUSTER_OWNER): + print(role) + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + hpa, workload = create_hpa(p_client, ns) + delete_hpa(p_client, hpa, ns) + remove_resource(hpa) + remove_resource(workload) + else: + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_client = get_project_client_for_token(unshared_project, + cluster_owner_token) + workload = create_workload(owner_client, ns) + user_token = rbac_get_user_token_by_role(role) + # Workload created by cluster owner in unshared project is passed as + # parameter to create HPA + hpa, workload = create_hpa(owner_client, ns, workload=workload) + p_client = get_project_client_for_token(unshared_project, user_token) + with pytest.raises(ApiError) as e: + delete_hpa(p_client, hpa, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(hpa) + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_list(remove_resource, role): + user_project = None + if(role == CLUSTER_MEMBER): + cluster_member_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = \ + create_project_and_ns(cluster_member_token, + namespace["cluster"], + random_test_name("cluster-mem")) + + user_client = get_project_client_for_token(user_project, + cluster_member_token) + # As a cluster member create a HPA and he should be able to list it + hpa, workload = create_hpa(user_client, ns) + else: + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + cluster_owner_p_client = \ + get_project_client_for_token(project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + user_client = get_project_client_for_token(project, user_token) + hpa, workload = create_hpa(cluster_owner_p_client, ns) + + hpaname = hpa.name + hpadict = user_client.list_horizontalPodAutoscaler(name=hpaname) + print(hpadict) + hpadata = hpadict.get('data') + assert len(hpadata) == 1 + assert hpadata[0].type == "horizontalPodAutoscaler" + assert hpadata[0].name == hpaname + remove_resource(hpa) + remove_resource(workload) + if user_client is not None: + remove_resource(user_project) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_hpa_list_negative(remove_resource, role): + if (role == CLUSTER_OWNER): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + hpa, workload = create_hpa(p_client, ns) + hpaname = hpa.name + hpadict = p_client.list_horizontalPodAutoscaler(name=hpaname) + hpadata = hpadict.get('data') + assert len(hpadata) == 1 + assert hpadata[0].type == "horizontalPodAutoscaler" + assert hpadata[0].name == hpaname + remove_resource(hpa) + remove_resource(workload) + else: + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + cluster_owner_client = \ + get_project_client_for_token(unshared_project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(role) + user_client = get_project_client_for_token(unshared_project, + user_token) + hpa, workload = create_hpa(cluster_owner_client, ns) + hpaname = hpa.name + # Verify length of HPA list is zero + hpadict = user_client.list_horizontalPodAutoscaler(name=hpaname) + hpadata = hpadict.get('data') + assert len(hpadata) == 0 + remove_resource(hpa) + remove_resource(workload) + + +def verify_hpa_cluster_member_edit(remove_resource): + cluster_member_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = create_project_and_ns(cluster_member_token, + namespace["cluster"], + random_test_name("cluster-mem")) + cluster_member_client = get_project_client_for_token(user_project, + cluster_member_token) + # Verify the cluster member can edit the hpa he created + hpa, workload = edit_hpa(cluster_member_client, ns) + + # Verify that cluster member cannot edit the hpa created by cluster owner + verify_edit_forbidden(cluster_member_client, remove_resource) + + remove_resource(hpa) + remove_resource(workload) + remove_resource(user_project) + + +def verify_hpa_project_readonly_edit(remove_resource): + project = rbac_get_project() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token) + # Verify that read -only user cannot edit the hpa created by cluster owner + verify_edit_forbidden(readonly_user_client, remove_resource) + + +def verify_edit_forbidden(user_client, remove_resource, + cluster_owner_client=None, ns=None): + metrics = [{ + 'name': 'cpu', + 'type': 'Resource', + 'target': { + 'type': 'Utilization', + 'utilization': '50', + }, + }] + + if(cluster_owner_client is None and ns is None): + project = rbac_get_project() + ns = rbac_get_namespace() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_client = \ + get_project_client_for_token(project, cluster_owner_token) + + # Create HPA as a cluster owner + hpa, workload = create_hpa(cluster_owner_client, ns) + # Verify editing HPA fails + with pytest.raises(ApiError) as e: + user_client.update(hpa, + name=hpa['name'], + namespaceId=ns.id, + maxReplicas=10, + minReplicas=3, + workload=workload.id, + metrics=metrics) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + remove_resource(hpa) + remove_resource(workload) + + +def create_hpa(p_client, ns, workload=None): + + # Create workload of scale 1 with CPU reservation + # Create hpa pointing to the workload. + if workload is None: + workload = create_workload(p_client, ns) + name = random_test_name("hpa") + + metrics = [{'name': 'cpu', + 'type': 'Resource', + 'target': { + 'type': 'Utilization', + 'utilization': '50', + }, + }] + + hpa = p_client.create_horizontalPodAutoscaler( + name=name, + namespaceId=ns.id, + maxReplicas=5, + minReplicas=2, + workloadId=workload.id, + metrics=metrics + ) + hpa = wait_for_hpa_to_active(p_client, hpa) + assert hpa.type == "horizontalPodAutoscaler" + assert hpa.name == name + assert hpa.minReplicas == 2 + assert hpa.maxReplicas == 5 + # After hpa becomes active, the workload scale should be equal to the + # minReplicas set in HPA object + workloadlist = p_client.list_workload(uuid=workload.uuid).data + validate_workload(p_client, workloadlist[0], "deployment", ns.name, + pod_count=hpa.minReplicas) + + return (hpa, workload) + + +def edit_hpa(p_client, ns): + + # Create workload of scale 1 with memory reservation + # Create hpa pointing to the workload.Edit HPA and verify HPA is functional + + workload = create_workload(p_client, ns) + name = random_test_name("default") + + metrics = [{ + "type": "Resource", + "name": "memory", + "target": { + "type": "AverageValue", + "value": None, + "averageValue": "32Mi", + "utilization": None, + "stringValue": "32" + } + }] + + hpa = p_client.create_horizontalPodAutoscaler( + name=name, + namespaceId=ns.id, + maxReplicas=4, + minReplicas=2, + workloadId=workload.id, + metrics=metrics + ) + wait_for_hpa_to_active(p_client, hpa) + + # After hpa becomes active, the workload scale should be equal to the + # minReplicas set in HPA + workloadlist = p_client.list_workload(uuid=workload.uuid).data + validate_workload(p_client, workloadlist[0], "deployment", ns.name, + pod_count=hpa.minReplicas) + + # Edit the HPA + updated_hpa = p_client.update(hpa, + name=hpa['name'], + namespaceId=ns.id, + maxReplicas=6, + minReplicas=3, + workloadId=workload.id, + metrics=metrics) + wait_for_hpa_to_active(p_client, updated_hpa) + assert updated_hpa.type == "horizontalPodAutoscaler" + assert updated_hpa.minReplicas == 3 + assert updated_hpa.maxReplicas == 6 + + # After hpa becomes active, the workload scale should be equal to the + # minReplicas set in the updated HPA + wait_for_pods_in_workload(p_client, workload, 3) + workloadlist = p_client.list_workload(uuid=workload.uuid).data + validate_workload(p_client, workloadlist[0], "deployment", ns.name, + pod_count=updated_hpa.minReplicas) + + return (updated_hpa, workload) + + +def delete_hpa(p_client, hpa, ns): + hpaname = hpa['name'] + p_client.delete(hpa) + # Sleep to allow HPA to be deleted + time.sleep(5) + timeout = 30 + hpadict = p_client.list_horizontalPodAutoscaler(name=hpaname) + print(hpadict.get('data')) + start = time.time() + if len(hpadict.get('data')) > 0: + testdata = hpadict.get('data') + while hpaname in testdata[0]['data']: + if time.time() - start > timeout: + raise AssertionError("Timed out waiting for deletion") + time.sleep(.5) + hpadict = p_client.list_horizontalPodAutoscaler(name=hpaname) + testdata = hpadict.get('data') + assert True + if len(hpadict.get('data')) == 0: + assert True + + # Verify hpa is deleted by "kubectl get hpa" command + command = "get hpa {} --namespace {}".format(hpa['name'], ns.name) + print("Command to obtain the hpa") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + + print("Verify that the hpa does not exist " + "and the error code returned is non zero ") + if result != 0: + assert True + + +def create_workload(p_client, ns): + con = [{"name": "test1", + "image": TEST_IMAGE, + "resources": { + "requests": { + "memory": "64Mi", + "cpu": "100m" + }, + "limits": { + "memory": "512Mi", + "cpu": "1000m" + } + } + }] + + name = random_test_name("workload") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + print(workload.scale) + validate_workload(p_client, workload, "deployment", ns.name) + + return workload + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns( + ADMIN_TOKEN, cluster, random_test_name("testhpa")) + p_client = get_project_client_for_token(p, ADMIN_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + + def fin(): + client = get_admin_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_cluster.py new file mode 100644 index 0000000..bdf269b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_cluster.py @@ -0,0 +1,136 @@ +import os +from lib.aws import AmazonWebServices +from .common import get_user_client +from .common import run_command +from .common import random_test_name +from .common import run_command_with_stderr +from .common import create_custom_host_registration_token +from .common import validate_cluster +from .common import cluster_cleanup +from .common import readDataFile + + +RANCHER_CLEANUP_CLUSTER = os.environ.get('RANCHER_CLEANUP_CLUSTER', "True") + +DATA_SUBDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') +AWS_SSH_KEY_NAME = os.environ.get("AWS_SSH_KEY_NAME") +AWS_NODE_COUNT = int(os.environ.get("AWS_NODE_COUNT", 3)) +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "testcustom") +RKE_K8S_VERSION = os.environ.get("RANCHER_RKE_K8S_VERSION","") + + +def test_import_rke_cluster(): + client, cluster, aws_nodes = create_and_validate_import_cluster() + cluster_cleanup(client, cluster, aws_nodes) + + +def create_and_validate_import_cluster(k8s_version="", supportmatrix=False): + client = get_user_client() + + # Create AWS nodes for the cluster + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + AWS_NODE_COUNT, random_test_name(HOST_NAME)) + assert len(aws_nodes) == AWS_NODE_COUNT + # Create RKE config + cluster_filename = random_test_name("cluster") + clusterfilepath = create_rke_cluster_config(aws_nodes, cluster_filename) + is_file = os.path.isfile(clusterfilepath) + assert is_file + + # update clusterfilepath with k8s version + if supportmatrix: + file_object = open(clusterfilepath, 'a') + version = "kubernetes_version: " + k8s_version + file_object.write(version) + # Close the file + file_object.close() + + # Print config file to be used for rke cluster create + configfile = run_command("cat " + clusterfilepath) + print("RKE Config file generated:\n") + print(configfile) + + # Create RKE K8s Cluster + clustername = random_test_name("testimport") + rkecommand = "rke up --config {}".format(clusterfilepath) + print(rkecommand) + result = run_command_with_stderr(rkecommand) + print("RKE up result: ", result) + + # Import the RKE cluster + cluster = client.create_cluster(name=clustername) + print(cluster) + cluster_token = create_custom_host_registration_token(client, cluster) + command = cluster_token.insecureCommand + print(command) + rke_config_file = "kube_config_" + cluster_filename + ".yml" + finalimportcommand = "{} --kubeconfig {}/{}".format(command, DATA_SUBDIR, + rke_config_file) + print("Final command to import cluster is:") + print(finalimportcommand) + result = run_command(finalimportcommand) + print(result) + clusters = client.list_cluster(name=clustername).data + assert len(clusters) > 0 + print("Cluster is") + print(clusters[0]) + + # Validate the cluster + cluster = validate_cluster(client, clusters[0], + check_intermediate_state=False) + + return client, cluster, aws_nodes + + +def test_generate_rke_config(): + + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + AWS_NODE_COUNT, random_test_name(HOST_NAME)) + assert len(aws_nodes) == AWS_NODE_COUNT + # Create RKE config + cluster_filename = random_test_name("cluster") + rkeconfigpath = create_rke_cluster_config(aws_nodes, cluster_filename) + rkeconfig = run_command("cat " + rkeconfigpath) + print("RKE Config file generated\n") + print(rkeconfig) + + +def create_rke_cluster_config(aws_nodes, cluster_filename): + + """ + Generates RKE config file with a minimum of 3 nodes with ALL roles(etcd, + worker and control plane). If the requested number of nodes is greater + than 3, additional nodes with worker role are created + """ + # Create RKE Config file + configfile = "cluster.yml" + rkeconfig = readDataFile(DATA_SUBDIR, configfile) + print(rkeconfig) + for i in range(0, AWS_NODE_COUNT): + ipstring = "$ip" + str(i) + intipstring = "$intip" + str(i) + rkeconfig = rkeconfig.replace(ipstring, aws_nodes[i].public_ip_address) + rkeconfig = rkeconfig.replace(intipstring, + aws_nodes[i].private_ip_address) + rkeconfig = rkeconfig.replace("$AWS_SSH_KEY_NAME", AWS_SSH_KEY_NAME) + rkeconfig = rkeconfig.replace("$KUBERNETES_VERSION", RKE_K8S_VERSION) + + clusterfilepath = DATA_SUBDIR + "/" + cluster_filename + ".yml" + print(clusterfilepath) + f = open(clusterfilepath, "w") + f.write(rkeconfig) + if AWS_NODE_COUNT > 3: + for i in range(3, AWS_NODE_COUNT): + for j in range(i, i + 1): + f.write(" - address: {}\n".format( + aws_nodes[j].public_ip_address)) + f.write(" internaladdress: {}\n".format( + aws_nodes[j].private_ip_address)) + f.write(" user: ubuntu\n") + f.write(" role: [worker]\n") + + f.close() + return clusterfilepath diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_k3s_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_k3s_cluster.py new file mode 100644 index 0000000..74f9493 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_k3s_cluster.py @@ -0,0 +1,309 @@ +from python_terraform import * # NOQA +from .common import * # NOQA + +RANCHER_REGION = os.environ.get("AWS_REGION") +RANCHER_VPC_ID = os.environ.get("AWS_VPC") +RANCHER_SUBNETS = os.environ.get("AWS_SUBNET") +RANCHER_AWS_SG = os.environ.get("AWS_SECURITY_GROUPS") +RANCHER_AVAILABILITY_ZONE = os.environ.get("AWS_AVAILABILITY_ZONE") +RANCHER_AWS_AMI = os.environ.get("AWS_AMI", "") +RANCHER_AWS_USER = os.environ.get("AWS_USER", "ubuntu") +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "sa") + +K3S_CHANNEL = os.environ.get("K3S_CHANNEL", "null") +RANCHER_K3S_VERSION = os.environ.get("RANCHER_K3S_VERSION", "") +RANCHER_K3S_VERSIONS = os.environ.get('RANCHER_K3S_VERSIONS', "").split(",") +RANCHER_K3S_NO_OF_SERVER_NODES = \ + os.environ.get("RANCHER_K3S_NO_OF_SERVER_NODES", 2) +RANCHER_K3S_NO_OF_WORKER_NODES = \ + os.environ.get("RANCHER_K3S_NO_OF_WORKER_NODES", 0) +RANCHER_K3S_SERVER_FLAGS = os.environ.get("RANCHER_K3S_SERVER_FLAGS", "") +RANCHER_K3S_WORKER_FLAGS = os.environ.get("RANCHER_K3S_WORKER_FLAGS", "agent") +RANCHER_QA_SPACE = os.environ.get("RANCHER_QA_SPACE", "qa.rancher.space.") +RANCHER_EC2_INSTANCE_CLASS = os.environ.get("AWS_INSTANCE_TYPE", "t3a.medium") + +RANCHER_EXTERNAL_DB = os.environ.get("RANCHER_EXTERNAL_DB", "mysql") +RANCHER_EXTERNAL_DB_VERSION = os.environ.get("RANCHER_EXTERNAL_DB_VERSION") +RANCHER_DB_GROUP_NAME = os.environ.get("RANCHER_DB_GROUP_NAME") +RANCHER_DB_MAX_CONNECTIONS = os.environ.get("RANCHER_DB_MAX_CONNECTIONS", 80) +RANCHER_INSTANCE_CLASS = os.environ.get("RANCHER_INSTANCE_CLASS", + "db.t2.micro") +RANCHER_DB_USERNAME = os.environ.get("RANCHER_DB_USERNAME", "adminuser") +RANCHER_DB_PASSWORD = os.environ.get("RANCHER_DB_PASSWORD", "") +RANCHER_K3S_KUBECONFIG_PATH = DATA_SUBDIR + "/k3s_kubeconfig.yaml" +RANCHER_NODE_OS = os.environ.get("RANCHER_NODE_OS", "ubuntu") +RANCHER_INSTALL_MODE = os.environ.get("RANCHER_INSTALL_MODE", "INSTALL_K3S_VERSION") +RANCHER_RDS_ENVIRONMENT = os.environ.get("RANCHER_RDS_ENVIRONMENT", "dev") +RANCHER_RDS_ENGINE_MODE = os.environ.get("RANCHER_RDS_ENGINE_MODE", "provisioned") +RANCHER_CLUSTER_TYPE = os.environ.get("RANCHER_CLUSTER_TYPE", "external_db") +AWS_VOLUME_SIZE = os.environ.get("AWS_VOLUME_SIZE", "8") +RANCHER_RHEL_USERNAME = os.environ.get("RANCHER_RHEL_USERNAME") +RANCHER_RHEL_PASSWORD = os.environ.get("RANCHER_RHEL_PASSWORD") +K3S_CREATE_LB = os.environ.get("K3S_CREATE_LB", False) +RANCHER_ENFORCE_MODE = os.environ.get("RANCHER_ENFORCE_MODE", "privileged") +RANCHER_OPTIONAL_FILES = os.environ.get("RANCHER_OPTIONAL_FILES") + + + +def test_create_k3s_single_control_cluster(): + aws_nodes, client, k3s_clusterfilepath = create_single_control_cluster() + + +def test_create_k3s_multiple_control_cluster(): + k3s_clusterfilepath = create_multiple_control_cluster() + + +def test_import_k3s_single_control_cluster(): + aws_nodes, client, k3s_clusterfilepath = create_single_control_cluster() + cluster = create_rancher_cluster(client, k3s_clusterfilepath) + cluster_cleanup(client, cluster, aws_nodes) + + +def test_import_k3s_multiple_control_cluster(): + client = get_user_client() + k3s_clusterfilepath = create_multiple_control_cluster() + cluster = create_rancher_cluster(client, k3s_clusterfilepath) + + +def test_delete_k3s(): + delete_resource_in_AWS_by_prefix(RANCHER_HOSTNAME_PREFIX) + + +def create_single_control_cluster(): + # Get URL and User_Token + client = get_user_client() + # Create nodes in AWS + aws_nodes = create_nodes() + + # Install k3s on master node + kubeconfig, node_token = install_k3s_master_node(aws_nodes[0]) + + # Join worker nodes + join_k3s_worker_nodes(aws_nodes[0], aws_nodes[1:], node_token) + + # Verify cluster health + verify_cluster_health(aws_nodes[0]) + + # Update master node IP in kubeconfig file + localhost = "127.0.0.1" + kubeconfig = kubeconfig.replace(localhost, aws_nodes[0].public_ip_address) + + k3s_kubeconfig_file = "k3s_kubeconfig.yaml" + k3s_clusterfilepath = create_kube_config_file(kubeconfig, k3s_kubeconfig_file) + print(k3s_clusterfilepath) + + k3s_kubeconfig_file = "k3s_kubeconfig.yaml" + k3s_clusterfilepath = DATA_SUBDIR + "/" + k3s_kubeconfig_file + is_file = os.path.isfile(k3s_clusterfilepath) + assert is_file + with open(k3s_clusterfilepath, 'r') as f: + print(f.read()) + cmd = "kubectl get nodes -o wide --kubeconfig=" + k3s_clusterfilepath + print(run_command(cmd)) + cmd = "kubectl get pods -A -o wide --kubeconfig=" + k3s_clusterfilepath + print(run_command(cmd)) + return aws_nodes, client, k3s_clusterfilepath + + +def create_multiple_control_cluster(): + global RANCHER_EXTERNAL_DB_VERSION + global RANCHER_DB_GROUP_NAME + k3s_kubeconfig_file = "k3s_kubeconfig.yaml" + k3s_clusterfilepath = DATA_SUBDIR + "/" + k3s_kubeconfig_file + + tf_dir = DATA_SUBDIR + "/" + "terraform/k3s/master" + keyPath = os.path.abspath('.') + '/.ssh/' + AWS_SSH_KEY_NAME + os.chmod(keyPath, 0o400) + no_of_servers = int(RANCHER_K3S_NO_OF_SERVER_NODES) + no_of_servers = no_of_servers - 1 + + if RANCHER_EXTERNAL_DB == "MariaDB": + RANCHER_EXTERNAL_DB_VERSION = "10.3.20" if not RANCHER_EXTERNAL_DB_VERSION \ + else RANCHER_EXTERNAL_DB_VERSION + RANCHER_DB_GROUP_NAME = "mariadb10.3" if not RANCHER_DB_GROUP_NAME \ + else RANCHER_DB_GROUP_NAME + elif RANCHER_EXTERNAL_DB == "postgres": + RANCHER_EXTERNAL_DB_VERSION = "11.5" if not RANCHER_EXTERNAL_DB_VERSION \ + else RANCHER_EXTERNAL_DB_VERSION + RANCHER_DB_GROUP_NAME = "postgres11" if not RANCHER_DB_GROUP_NAME \ + else RANCHER_DB_GROUP_NAME + elif RANCHER_EXTERNAL_DB == "aurora-mysql": + RANCHER_EXTERNAL_DB_VERSION = "5.7.mysql_aurora.2.09.0" if not RANCHER_EXTERNAL_DB_VERSION \ + else RANCHER_EXTERNAL_DB_VERSION + RANCHER_DB_GROUP_NAME = "aurora-mysql5.7" if not RANCHER_DB_GROUP_NAME \ + else RANCHER_DB_GROUP_NAME + else: + RANCHER_EXTERNAL_DB_VERSION = "5.7" if not RANCHER_EXTERNAL_DB_VERSION \ + else RANCHER_EXTERNAL_DB_VERSION + RANCHER_DB_GROUP_NAME = "mysql5.7" if not RANCHER_DB_GROUP_NAME \ + else RANCHER_DB_GROUP_NAME + tf = Terraform(working_dir=tf_dir, + variables={'region': RANCHER_REGION, + 'vpc_id': RANCHER_VPC_ID, + 'subnets': RANCHER_SUBNETS, + 'sg_id': RANCHER_AWS_SG, + 'availability_zone': RANCHER_AVAILABILITY_ZONE, + 'aws_ami': RANCHER_AWS_AMI, + 'aws_user': RANCHER_AWS_USER, + 'resource_name': RANCHER_HOSTNAME_PREFIX, + 'access_key': keyPath, + 'access_key_name': AWS_SSH_KEY_NAME.replace(".pem", ""), + 'external_db': RANCHER_EXTERNAL_DB, + 'external_db_version': RANCHER_EXTERNAL_DB_VERSION, + 'db_group_name': RANCHER_DB_GROUP_NAME, + 'instance_class': RANCHER_INSTANCE_CLASS, + 'max_connections': RANCHER_DB_MAX_CONNECTIONS, + 'ec2_instance_class': RANCHER_EC2_INSTANCE_CLASS, + 'db_username': RANCHER_DB_USERNAME, + 'db_password': RANCHER_DB_PASSWORD, + 'k3s_version': RANCHER_K3S_VERSION, + 'k3s_channel': K3S_CHANNEL, + 'no_of_server_nodes': no_of_servers, + 'server_flags': RANCHER_K3S_SERVER_FLAGS, + 'qa_space': RANCHER_QA_SPACE, + 'node_os': RANCHER_NODE_OS, + 'username': RANCHER_RHEL_USERNAME, + 'password': RANCHER_RHEL_PASSWORD, + 'install_mode': RANCHER_INSTALL_MODE, + 'engine_mode': RANCHER_RDS_ENGINE_MODE, + 'environment': RANCHER_RDS_ENVIRONMENT, + 'cluster_type': RANCHER_CLUSTER_TYPE, + 'volume_size': AWS_VOLUME_SIZE, + 'create_lb': str(K3S_CREATE_LB).lower(), + 'enforce_mode': RANCHER_ENFORCE_MODE, + 'optional_files': RANCHER_OPTIONAL_FILES}) + print("Creating cluster") + tf.init() + tf.plan(out="plan_server.out") + print(tf.apply("--auto-approve")) + + if int(RANCHER_K3S_NO_OF_WORKER_NODES) > 0: + tf_dir = DATA_SUBDIR + "/" + "terraform/k3s/worker" + tf = Terraform(working_dir=tf_dir, + variables={'region': RANCHER_REGION, + 'vpc_id': RANCHER_VPC_ID, + 'subnets': RANCHER_SUBNETS, + 'sg_id': RANCHER_AWS_SG, + 'availability_zone': RANCHER_AVAILABILITY_ZONE, + 'aws_ami': RANCHER_AWS_AMI, + 'aws_user': RANCHER_AWS_USER, + 'ec2_instance_class': RANCHER_EC2_INSTANCE_CLASS, + 'resource_name': RANCHER_HOSTNAME_PREFIX, + 'access_key': keyPath, + 'access_key_name': AWS_SSH_KEY_NAME.replace(".pem", ""), + 'k3s_version': RANCHER_K3S_VERSION, + 'k3s_channel': K3S_CHANNEL, + 'no_of_worker_nodes': int(RANCHER_K3S_NO_OF_WORKER_NODES), + 'node_os': RANCHER_NODE_OS, + 'username': RANCHER_RHEL_USERNAME, + 'password': RANCHER_RHEL_PASSWORD, + 'install_mode': RANCHER_INSTALL_MODE, + 'volume_size': AWS_VOLUME_SIZE, + 'worker_flags': RANCHER_K3S_WORKER_FLAGS}) + + print("Joining worker nodes") + tf.init() + tf.plan(out="plan_worker.out") + print(tf.apply("--auto-approve")) + + cmd = "cp /tmp/" + RANCHER_HOSTNAME_PREFIX + "_kubeconfig " + k3s_clusterfilepath + os.system(cmd) + is_file = os.path.isfile(k3s_clusterfilepath) + assert is_file + print_kubeconfig(k3s_clusterfilepath) + print("K3s Cluster Created") + cmd = "kubectl get nodes -o wide --kubeconfig=" + k3s_clusterfilepath + print(run_command(cmd)) + cmd = "kubectl get pods -o wide -A --kubeconfig=" + k3s_clusterfilepath + print(run_command(cmd)) + return k3s_clusterfilepath + + +def create_rancher_cluster(client, k3s_clusterfilepath): + if CLUSTER_NAME: + clustername = CLUSTER_NAME + else: + clustername = random_test_name("testcustom-k3s") + cluster = client.create_cluster(name=clustername) + cluster_token = create_custom_host_registration_token(client, cluster) + command = cluster_token.insecureCommand + finalimportcommand = command + " --kubeconfig " + k3s_clusterfilepath + + result = run_command(finalimportcommand) + + clusters = client.list_cluster(name=clustername).data + assert len(clusters) > 0 + print("Cluster is") + print(clusters[0]) + + # Validate the cluster + cluster = validate_cluster(client, clusters[0], + check_intermediate_state=False) + + return cluster + + +def create_nodes(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + int(RANCHER_K3S_NO_OF_WORKER_NODES), + random_test_name("testcustom-k3s"+"-"+HOST_NAME)) + assert len(aws_nodes) == int(RANCHER_K3S_NO_OF_WORKER_NODES) + for aws_node in aws_nodes: + print("AWS NODE PUBLIC IP {}".format(aws_node.public_ip_address)) + return aws_nodes + + +def install_k3s_master_node(master): + # Connect to the node and install k3s on master + print("K3s VERSION {}".format(RANCHER_K3S_VERSION)) + cmd = "curl -sfL https://get.k3s.io | \ + {} sh -s - server --node-external-ip {}".\ + format("INSTALL_K3S_VERSION={}".format(RANCHER_K3S_VERSION) if RANCHER_K3S_VERSION \ + else "", master.public_ip_address) + print("Master Install {}".format(cmd)) + install_result = master.execute_command(cmd) + print(install_result) + + # Get node token from master + cmd = "sudo cat /var/lib/rancher/k3s/server/node-token" + print(cmd) + node_token = master.execute_command(cmd) + print(node_token) + + # Get kube_config from master + cmd = "sudo cat /etc/rancher/k3s/k3s.yaml" + kubeconfig = master.execute_command(cmd) + print(kubeconfig) + print("NO OF WORKER NODES: {}".format(RANCHER_K3S_NO_OF_WORKER_NODES)) + print("NODE TOKEN: \n{}".format(node_token)) + print("KUBECONFIG: \n{}".format(kubeconfig)) + + return kubeconfig[0].strip("\n"), node_token[0].strip("\n") + + +def join_k3s_worker_nodes(master, workers, node_token): + for worker in workers: + cmd = "curl -sfL https://get.k3s.io | \ + {} K3S_URL=https://{}:6443 K3S_TOKEN={} sh -s - ". \ + format("INSTALL_K3S_VERSION={}".format(RANCHER_K3S_VERSION) \ + if RANCHER_K3S_VERSION else "", master.public_ip_address, node_token) + cmd = cmd + " {} {}".format("--node-external-ip", worker.public_ip_address) + print("Joining k3s master") + print(cmd) + install_result = worker.execute_command(cmd) + print(install_result) + + +def verify_cluster_health(master): + cmd = "sudo k3s kubectl get nodes" + install_result = master.execute_command(cmd) + print(install_result) + + +def create_kube_config_file(kubeconfig, k3s_kubeconfig_file): + k3s_clusterfilepath = DATA_SUBDIR + "/" + k3s_kubeconfig_file + f = open(k3s_clusterfilepath, "w") + f.write(kubeconfig) + f.close() + return k3s_clusterfilepath diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_rke2_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_rke2_cluster.py new file mode 100644 index 0000000..9776915 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_import_rke2_cluster.py @@ -0,0 +1,359 @@ +from python_terraform import * # NOQA +from .common import * # NOQA + + +RANCHER_AWS_AMI = os.environ.get("AWS_AMI", "") +RANCHER_AWS_USER = os.environ.get("AWS_USER", "ubuntu") +RANCHER_AWS_WINDOWS_AMI = os.environ.get("AWS_WINDOWS_AMI", "") +RANCHER_AWS_WINDOWS_USER = os.environ.get("AWS_WINDOWS_USER", "Administrator") +RANCHER_REGION = os.environ.get("AWS_REGION") +RANCHER_VPC_ID = os.environ.get("AWS_VPC") +RANCHER_SUBNETS = os.environ.get("AWS_SUBNET") +RANCHER_AWS_SG = os.environ.get("AWS_SECURITY_GROUPS") +RANCHER_AVAILABILITY_ZONE = os.environ.get("AWS_AVAILABILITY_ZONE") +RANCHER_QA_SPACE = os.environ.get("RANCHER_QA_SPACE", "qa.rancher.space.") +RANCHER_EC2_INSTANCE_CLASS = os.environ.get("AWS_INSTANCE_TYPE", "t3a.medium") +RANCHER_EC2_WINDOWS_INSTANCE_CLASS = os.environ.get("AWS_WINDOWS_INSTANCE_TYPE", "t3.xlarge") +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "sa") +RANCHER_IAM_ROLE = os.environ.get("RANCHER_IAM_ROLE") +RKE2_CREATE_LB = os.environ.get("RKE2_CREATE_LB", False) + +RANCHER_RKE2_VERSION = os.environ.get("RANCHER_RKE2_VERSION", "") +RANCHER_RKE2_CHANNEL = os.environ.get("RANCHER_RKE2_CHANNEL", "null") +RANCHER_RANCHERD_VERSION = os.environ.get("RANCHER_RANCHERD_VERSION", "") +RANCHER_RKE2_NO_OF_SERVER_NODES = \ + os.environ.get("RANCHER_RKE2_NO_OF_SERVER_NODES", 3) +RANCHER_RKE2_NO_OF_WORKER_NODES = \ + os.environ.get("RANCHER_RKE2_NO_OF_WORKER_NODES", 0) +RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES = \ + os.environ.get("RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES", 0) +RANCHER_RKE2_SERVER_FLAGS = os.environ.get("RANCHER_RKE2_SERVER_FLAGS", "server") +RANCHER_RKE2_WORKER_FLAGS = os.environ.get("RANCHER_RKE2_WORKER_FLAGS", "agent") +RANCHER_RKE2_OPERATING_SYSTEM = os.environ.get("RANCHER_RKE2_OPERATING_SYSTEM") +AWS_VOLUME_SIZE = os.environ.get("AWS_VOLUME_SIZE", "20") +RANCHER_RKE2_RHEL_USERNAME = os.environ.get("RANCHER_RKE2_RHEL_USERNAME", "") +RANCHER_RKE2_RHEL_PASSWORD = os.environ.get("RANCHER_RKE2_RHEL_PASSWORD", "") +RANCHER_RKE2_KUBECONFIG_PATH = DATA_SUBDIR + "/rke2_kubeconfig.yaml" +RKE2_INSTALL_MODE = os.environ.get("RKE2_INSTALL_MODE", "INSTALL_RKE2_VERSION") +RKE2_INSTALL_METHOD = os.environ.get("RKE2_INSTALL_METHOD", "") + +RKE2_SPLIT_ROLES = os.environ.get("RKE2_SPLIT_ROLES", False) +RKE2_ETCD_ONLY_NODES = os.environ.get("RKE2_ETCD_ONLY_NODES", 0) +RKE2_ETCD_CP_NODES = os.environ.get("RKE2_ETCD_CP_NODES", 0) +RKE2_ETCD_WORKER_NODES = os.environ.get("RKE2_ETCD_WORKER_NODES", 0) +RKE2_CP_ONLY_NODES = os.environ.get("RKE2_CP_ONLY_NODES", 0) +RKE2_CP_WORKER_NODES = os.environ.get("RKE2_CP_WORKER_NODES", 0) +# Role order corresponds to 1=RANCHER_RKE2_NO_OF_SERVER_NODES, +# 2=RKE2_ETCD_ONLY_NODES 3=RKE2_ETCD_CP_NODES, 4=RKE2_ETCD_WORKER_NODES, +# 5=RKE2_CP_ONLY_NODES, 6=RKE2_CP_WORKER_NODES +RKE2_ROLE_ORDER = os.environ.get("RKE2_ROLE_ORDER", "1,2,3,4,5,6") +RANCHER_OPTIONAL_FILES = os.environ.get("RANCHER_OPTIONAL_FILES") + + +def test_create_rancherd_multiple_control_cluster(): + cluster_version = RANCHER_RANCHERD_VERSION + cluster_type = "rancherd" + rke2_clusterfilepath = create_rke2_multiple_control_cluster(cluster_type, \ + cluster_version) + fqdn_file = "/tmp/" + RANCHER_HOSTNAME_PREFIX + "_fixed_reg_addr" + with open(fqdn_file, 'r') as f: + fqdn = f.read() + fqdn = fqdn.strip() + print("RANCHERD URL\nhttps://{0}:8443\n".format(fqdn), flush=True) + ip_file = "/tmp/" + RANCHER_HOSTNAME_PREFIX + "_master_ip" + with open(ip_file, 'r') as f: + ip = f.read() + ip = ip.strip() + keyPath = os.path.abspath('.') + '/.ssh/' + AWS_SSH_KEY_NAME + os.chmod(keyPath, 0o400) + print("\n\nRANCHERD USERNAME AND PASSWORD\n", flush=True) + cmd = "ssh -o StrictHostKeyChecking=no -i " + keyPath + " " + RANCHER_AWS_USER + \ + "@" + ip + " rancherd reset-admin" + result = run_command(cmd, True) + print(result) + + +def test_create_rke2_multiple_control_cluster(): + cluster_version = RANCHER_RKE2_VERSION + cluster_type = "rke2" + create_rke2_multiple_control_cluster(cluster_type, cluster_version) + + +def test_import_rke2_multiple_control_cluster(): + client = get_user_client() + cluster_version = RANCHER_RKE2_VERSION + cluster_type = "rke2" + rke2_clusterfilepath = create_rke2_multiple_control_cluster( + cluster_type, cluster_version) + cluster = create_rancher_cluster(client, rke2_clusterfilepath) + + +def create_rke2_multiple_control_cluster(cluster_type, cluster_version): + + rke2_kubeconfig_file = "rke2_kubeconfig.yaml" + rke2_clusterfilepath = DATA_SUBDIR + "/" + rke2_kubeconfig_file + + tf_dir = DATA_SUBDIR + "/" + "terraform/rke2/master" + keyPath = os.path.abspath('.') + '/.ssh/' + AWS_SSH_KEY_NAME + os.chmod(keyPath, 0o400) + + split_roles = str(RKE2_SPLIT_ROLES).lower() + if split_roles == "true": + no_of_servers = int(RANCHER_RKE2_NO_OF_SERVER_NODES) + \ + int(RKE2_ETCD_ONLY_NODES) + int(RKE2_ETCD_CP_NODES) + \ + int(RKE2_ETCD_WORKER_NODES) + int(RKE2_CP_ONLY_NODES) + \ + int(RKE2_CP_WORKER_NODES) - 1 + + role_order = RKE2_ROLE_ORDER.split(",") + if int(RANCHER_RKE2_NO_OF_SERVER_NODES) > 0: + assert "1" in role_order + if int(RKE2_ETCD_ONLY_NODES) > 0: + assert "2" in role_order + if int(RKE2_ETCD_CP_NODES) > 0: + assert "3" in role_order + if int(RKE2_ETCD_WORKER_NODES) > 0: + assert "4" in role_order + if int(RKE2_CP_ONLY_NODES) > 0: + assert "5" in role_order + if int(RKE2_CP_WORKER_NODES) > 0: + assert "6" in role_order + else: + no_of_servers = int(RANCHER_RKE2_NO_OF_SERVER_NODES) - 1 + + # Server nodes + tf = Terraform(working_dir=tf_dir, + variables={'region': RANCHER_REGION, + 'vpc_id': RANCHER_VPC_ID, + 'subnets': RANCHER_SUBNETS, + 'sg_id': RANCHER_AWS_SG, + 'availability_zone': RANCHER_AVAILABILITY_ZONE, + 'aws_ami': RANCHER_AWS_AMI, + 'aws_user': RANCHER_AWS_USER, + 'resource_name': RANCHER_HOSTNAME_PREFIX, + 'access_key': keyPath, + 'access_key_name': AWS_SSH_KEY_NAME.replace(".pem", ""), + 'ec2_instance_class': RANCHER_EC2_INSTANCE_CLASS, + 'username': RANCHER_RKE2_RHEL_USERNAME, + 'password': RANCHER_RKE2_RHEL_PASSWORD, + 'rke2_version': cluster_version, + 'install_mode': RKE2_INSTALL_MODE, + 'install_method': RKE2_INSTALL_METHOD, + 'rke2_channel': RANCHER_RKE2_CHANNEL, + 'no_of_server_nodes': no_of_servers, + 'server_flags': RANCHER_RKE2_SERVER_FLAGS, + 'qa_space': RANCHER_QA_SPACE, + 'node_os': RANCHER_RKE2_OPERATING_SYSTEM, + 'cluster_type': cluster_type, + 'iam_role': RANCHER_IAM_ROLE, + 'volume_size': AWS_VOLUME_SIZE, + 'create_lb': str(RKE2_CREATE_LB).lower(), + 'split_roles': split_roles, + 'all_role_nodes': RANCHER_RKE2_NO_OF_SERVER_NODES, + 'etcd_only_nodes': RKE2_ETCD_ONLY_NODES, + 'etcd_cp_nodes': RKE2_ETCD_CP_NODES, + 'etcd_worker_nodes': RKE2_ETCD_WORKER_NODES, + 'cp_only_nodes': RKE2_CP_ONLY_NODES, + 'cp_worker_nodes': RKE2_CP_WORKER_NODES, + 'role_order': RKE2_ROLE_ORDER, + 'optional_files': RANCHER_OPTIONAL_FILES}) + print("Creating cluster") + tf.init() + tf.plan(out="plan_server.out") + print(tf.apply("--auto-approve")) + print("\n\n") + + # Worker nodes + if int(RANCHER_RKE2_NO_OF_WORKER_NODES) > 0: + tf_dir = DATA_SUBDIR + "/" + "terraform/rke2/worker" + tf = Terraform(working_dir=tf_dir, + variables={'region': RANCHER_REGION, + 'vpc_id': RANCHER_VPC_ID, + 'subnets': RANCHER_SUBNETS, + 'sg_id': RANCHER_AWS_SG, + 'availability_zone': RANCHER_AVAILABILITY_ZONE, + 'aws_ami': RANCHER_AWS_AMI, + 'aws_user': RANCHER_AWS_USER, + 'ec2_instance_class': RANCHER_EC2_INSTANCE_CLASS, + 'resource_name': RANCHER_HOSTNAME_PREFIX, + 'access_key': keyPath, + 'access_key_name': AWS_SSH_KEY_NAME.replace(".pem", ""), + 'rke2_version': cluster_version, + 'install_mode': RKE2_INSTALL_MODE, + 'install_method': RKE2_INSTALL_METHOD, + 'rke2_channel': RANCHER_RKE2_CHANNEL, + 'username': RANCHER_RKE2_RHEL_USERNAME, + 'password': RANCHER_RKE2_RHEL_PASSWORD, + 'node_os': RANCHER_RKE2_OPERATING_SYSTEM, + 'cluster_type': cluster_type, + 'no_of_worker_nodes': int(RANCHER_RKE2_NO_OF_WORKER_NODES), + 'worker_flags': RANCHER_RKE2_WORKER_FLAGS, + 'iam_role': RANCHER_IAM_ROLE, + 'volume_size': AWS_VOLUME_SIZE}) + + print("Creating worker nodes") + tf.init() + tf.plan(out="plan_worker.out") + print(tf.apply("--auto-approve")) + print("Finished Creating worker nodes") + print("\n\n") + + # Windows worker nodes + if int(RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES) > 0: + tf_dir = DATA_SUBDIR + "/" + "terraform/rke2/windows_worker" + tf = Terraform(working_dir=tf_dir, + variables={'region': RANCHER_REGION, + 'vpc_id': RANCHER_VPC_ID, + 'subnets': RANCHER_SUBNETS, + 'sg_id': RANCHER_AWS_SG, + 'availability_zone': RANCHER_AVAILABILITY_ZONE, + 'aws_ami': RANCHER_AWS_WINDOWS_AMI, + 'aws_user': RANCHER_AWS_WINDOWS_USER, + 'ec2_instance_class': RANCHER_EC2_WINDOWS_INSTANCE_CLASS, + 'resource_name': RANCHER_HOSTNAME_PREFIX, + 'access_key': keyPath, + 'access_key_name': AWS_SSH_KEY_NAME.replace(".pem", ""), + 'rke2_version': cluster_version, + 'node_os': "windows", + 'cluster_type': cluster_type, + 'no_of_windows_worker_nodes': int(RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES), + 'iam_role': RANCHER_IAM_ROLE}) + + print("Creating Windows worker nodes") + tf.init() + tf.plan(out="plan_windows_worker.out") + print(tf.apply("--auto-approve")) + print("Finished Creating Windows worker nodes") + print("\n\n") + + cmd = "cp /tmp/" + RANCHER_HOSTNAME_PREFIX + "_kubeconfig " + \ + rke2_clusterfilepath + os.system(cmd) + is_file = os.path.isfile(rke2_clusterfilepath) + assert is_file + print_kubeconfig(rke2_clusterfilepath) + check_cluster_status(rke2_clusterfilepath) + print("\n\nRKE2 Cluster Created\n") + cmd = "kubectl get nodes --kubeconfig=" + rke2_clusterfilepath + print(run_command(cmd)) + cmd = "kubectl get pods -A --kubeconfig=" + rke2_clusterfilepath + print(run_command(cmd)) + print("\n\n") + return rke2_clusterfilepath + + +def create_rancher_cluster(client, rke2_clusterfilepath): + if CLUSTER_NAME: + clustername = CLUSTER_NAME + else: + clustername = random_test_name("testcustom-rke2") + cluster = client.create_cluster(name=clustername) + cluster_token = create_custom_host_registration_token(client, cluster) + command = cluster_token.insecureCommand + finalimportcommand = command + " --kubeconfig " + rke2_clusterfilepath + print(finalimportcommand) + + result = run_command(finalimportcommand) + + clusters = client.list_cluster(name=clustername).data + assert len(clusters) > 0 + print("Cluster is") + print(clusters[0]) + + # Validate the cluster + cluster = validate_cluster(client, clusters[0], + check_intermediate_state=False) + + return cluster + + +def check_cluster_status(kubeconfig): + print("Checking cluster status for {} server and {} agents nodes...".format(RANCHER_RKE2_NO_OF_SERVER_NODES, (int(RANCHER_RKE2_NO_OF_WORKER_NODES) + int(RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES)))) + retries = 0 + actual_count_of_nodes = 0 + expected_count_of_nodes = int(RANCHER_RKE2_NO_OF_SERVER_NODES) + \ + int(RANCHER_RKE2_NO_OF_WORKER_NODES) + \ + int(RANCHER_RKE2_NO_OF_WINDOWS_WORKER_NODES) + try: + # Retry logic for matching node count for 5 mins + while (actual_count_of_nodes < expected_count_of_nodes): + actual_count_of_nodes = len(get_states("nodes",kubeconfig)) + print("Retrying for 1 min to check node count...") + time.sleep(60) + retries = retries + 1 + print("Waiting for agent nodes to join the cluster, retry count: {}".format(retries)) + if (actual_count_of_nodes == expected_count_of_nodes): + break + if (retries == 5): + if (actual_count_of_nodes < expected_count_of_nodes): + raise AssertionError("Nodes failed to join the cluster after 5 min, \ + Expected: {} Actual: {}".format(expected_count_of_nodes, actual_count_of_nodes)) + + # Retry logic for node status to be Ready for 5 mins + print("Checking node status....") + states = get_states("nodes",kubeconfig) + if 'NotReady' in states: + nodeNotReady = True + print("Found one or more nodes in 'NotReady' state") + retries = 0 + while nodeNotReady and (retries < 5): + print("Retrying for 1 min to check node status...") + time.sleep(60) + retries = retries + 1 + print("Waiting for agent nodes to be ready, retry count: {}".format(retries)) + states = get_states("nodes",kubeconfig) + if not 'NotReady' in states: + nodeNotReady = False + if (retries == 5): + if nodeNotReady: + raise AssertionError("Nodes failed to be in Ready state after 5 min, please check logs...") + print('All nodes found to be in Ready state') + + # Retry logic for pods status to be Ready or Completed for 5 mins + print('Checking pods status...') + states = get_states("pods",kubeconfig) + retries = 0 + if not all(state in ['Running','Completed'] for state in states): + print("Found one or more pods in un-desired status") + podsNotReady = True + while podsNotReady and (retries < 5): + print("Retrying for 1 min to check pod status...") + time.sleep(60) + retries = retries + 1 + print("Waiting for pods to be in desired state, retry count: {}".format(retries)) + states = get_states("pods",kubeconfig) + if all(state in ['Running','Completed'] for state in states): + podsNotReady = False + if (retries == 5): + if podsNotReady: + raise AssertionError("Pods are not found to be in desired state after 5 min, please check logs...") + print('All pods found to be in desired state') + except AssertionError as e: + print("FAIL: {}".format(str(e))) + + +def execute_command(command, log_out=True): + if log_out: + print("run cmd: \t{0}".format(command)) + for i in range(3): + try: + res = subprocess.check_output(command, shell=True, text=True) + except subprocess.CalledProcessError: + print("Re-trying...") + time.sleep(10) + return res + +def get_states(type, kubeconfig): + if type == "nodes": + cmd = "kubectl get nodes --no-headers -A --kubeconfig=" + kubeconfig + cmd_res = execute_command(cmd, False) + nodes = cmd_res.strip().split("\n") + states = [node.split()[1] for node in nodes] + return states + elif type == "pods": + cmd = "kubectl get pods --no-headers -A --kubeconfig=" + kubeconfig + cmd_res = execute_command(cmd, False) + pods = cmd_res.strip().split("\n") + states = [pod.split()[3] for pod in pods] + return states + else: + raise AssertionError("Invalid type: {}, only nodes and pods are allowed".format(type)) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ingress.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ingress.py new file mode 100644 index 0000000..a79e661 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_ingress.py @@ -0,0 +1,555 @@ +""" +This test suite contains tests to validate ingress create/edit/delete with +different possible way and with different roles of users. +Test requirement: +Below Env variables need to set +CATTLE_TEST_URL - url to rancher server +ADMIN_TOKEN - Admin token from rancher +USER_TOKEN - User token from rancher +RANCHER_CLUSTER_NAME - Cluster name to run test on +RANCHER_TEST_RBAC - Boolean (Optional), To run role based tests. +""" + +from .common import CLUSTER_MEMBER +from .common import CLUSTER_OWNER +from .common import PROJECT_READ_ONLY +from .common import PROJECT_OWNER +from .common import PROJECT_MEMBER +from .common import TEST_IMAGE +from .common import TEST_IMAGE_PORT +from .common import random_test_name +from .common import validate_workload +from .common import get_schedulable_nodes +from .common import validate_ingress +from .common import wait_for_pods_in_workload +from .common import validate_ingress_using_endpoint +from .common import rbac_get_user_token_by_role +from .common import pytest +from .common import rbac_get_project +from .common import rbac_get_namespace +from .common import if_test_rbac +from .common import get_project_client_for_token +from .common import ApiError +from .common import time +from .common import get_user_client_and_cluster +from .common import create_kubeconfig +from .common import create_project_and_ns +from .common import USER_TOKEN +from .common import get_user_client +from .common import DEFAULT_TIMEOUT +from .common import rbac_get_workload +from .common import wait_for_ingress_to_active +from .common import get_setting_value_by_name +from .test_import_k3s_cluster import RANCHER_K3S_VERSION +from .test_secrets import is_version_greater_than_v25 +from packaging import version + +domain_ip_v25 = "xip.ip" +domain_ip_v26 = "sslip.io" + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} +rbac_role_list = [ + CLUSTER_OWNER, + CLUSTER_MEMBER, + PROJECT_OWNER, + PROJECT_MEMBER, + PROJECT_READ_ONLY + ] + + +def test_ingress(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + host = "test1.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + + +def test_ingress_with_same_rules_having_multiple_targets(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "testm1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload1 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload1, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + name = random_test_name("default") + workload2 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload2, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + host = "testm1.com" + path = "/name.html" + rule1 = {"host": host, + "paths": [{"workloadIds": [workload1.id], + "targetPort": TEST_IMAGE_PORT}]} + rule2 = {"host": host, + "paths": [{"workloadIds": [workload2.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule1, rule2]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload1, workload2], host, path) + + +def test_ingress_edit_target(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload1 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload1, "deployment", ns.name, pod_count=2) + name = random_test_name("default") + workload2 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload2, "deployment", ns.name, pod_count=2) + + host = "test2.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload1.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload1], host, path) + + rule = {"host": host, + "paths": [{"workloadIds": [workload2.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.update(ingress, rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload2], host, path) + + +def test_ingress_edit_host(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + host = "test3.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + host = "test4.com" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.update(ingress, rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + + +def test_ingress_edit_path(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + host = "test5.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + path = "/service1.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.update(ingress, rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + + +def test_ingress_edit_add_more_rules(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload1 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload1, "deployment", ns.name, pod_count=2) + name = random_test_name("default") + workload2 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload2, "deployment", ns.name, pod_count=2) + + host1 = "test6.com" + path = "/name.html" + rule1 = {"host": host1, + "paths": [{"workloadIds": [workload1.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule1]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload1], host1, path) + + host2 = "test7.com" + rule2 = {"host": host2, + "paths": [{"workloadIds": [workload2.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.update(ingress, rules=[rule1, rule2]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload2], host2, path) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload1], host1, path) + + +def test_ingress_scale_up_target(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=2) + + host = "test8.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + workload = p_client.update(workload, scale=4, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=4) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + + +def test_ingress_upgrade_target(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = {"name": "test1", + "image": TEST_IMAGE} + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=[con], + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=2) + + host = "test9.com" + path = "/name.html" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + if(is_version_greater_than_v25()): + con["env"] = {"test1": "value1"} + else: + con["environment"] = {"test1": "value1"} + workload = p_client.update(workload, containers=[con]) + wait_for_pods_in_workload(p_client, workload, pod_count=2) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=2) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, path) + + +def test_ingress_rule_with_only_path(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = {"name": "test1", + "image": TEST_IMAGE} + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=[con], + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=2) + + host = "" + path = "/service2.html" + if RANCHER_K3S_VERSION != "": + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT, "pathType": "Prefix", "path": "/"}]} + else: + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], "", path, True) + + +def test_ingress_rule_with_only_host(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = {"name": "test1", + "image": TEST_IMAGE} + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=[con], + namespaceId=ns.id, + scale=2) + validate_workload(p_client, workload, "deployment", ns.name, pod_count=2) + + host = "test10.com" + rule = {"host": host, + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, "/name.html") + validate_ingress(namespace["p_client"], namespace["cluster"], + [workload], host, "/service1.html") + + +def get_ingress_ip_domain(): + current_server_version = get_setting_value_by_name('server-version') + + if current_server_version.startswith('v'): + if "head" in current_server_version: + current_server_version = ''.join(current_server_version.split("-")[0]) + else: + current_server_version = '.'.join(current_server_version.split(".")[:3]) + if(version.parse(current_server_version) > version.parse('v2.5.9')): + return domain_ip_v26 + else: + return domain_ip_v25 + +def test_ingress_ip_domain(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + path = "/name.html" + + + rule = {"host": get_ingress_ip_domain(), + "paths": [{"path": path, + "workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + validate_ingress_using_endpoint(namespace["p_client"], ingress, [workload]) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_ingress_create(role): + """ + This test creates first workload as cluster owner and then creates ingress + as user i.e. role in parameter and validates the ingress created. + @param role: User role in rancher eg. project owner, project member etc + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload = rbac_get_workload() + p_client = get_project_client_for_token(project, token) + name = random_test_name("default") + + rule = {"host": get_ingress_ip_domain(), + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + ingress = p_client.create_ingress(name=name, + namespaceId=ns.id, + rules=[rule]) + wait_for_ingress_to_active(p_client, ingress) + p_client.delete(ingress) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_ingress_edit(role): + """ + This test creates two workloads and then creates ingress with two targets + and validates it. + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload = rbac_get_workload() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + p_client = get_project_client_for_token(project, token) + + path = "/name.html" + rule_1 = {"host": get_ingress_ip_domain(), + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + rule_2 = {"host": get_ingress_ip_domain(), + "paths": [{"path": path, "workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + name = random_test_name("default") + ingress = p_client_for_c_owner.create_ingress(name=name, namespaceId=ns.id, + rules=[rule_1]) + wait_for_ingress_to_active(p_client_for_c_owner, ingress) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + ingress = p_client.update(ingress, rules=[rule_2]) + wait_for_ingress_to_active(p_client, ingress) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + ingress = p_client.update(ingress, rules=[rule_2]) + wait_for_ingress_to_active(p_client, ingress) + p_client_for_c_owner.delete(ingress) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_ingress_delete(role): + """ + This test creates two workloads and then creates ingress with two targets + and validates it. + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload = rbac_get_workload() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + p_client = get_project_client_for_token(project, token) + name = random_test_name("default") + + rule = {"host": get_ingress_ip_domain(), + "paths": [{"workloadIds": [workload.id], + "targetPort": TEST_IMAGE_PORT}]} + + ingress = p_client_for_c_owner.create_ingress(name=name, namespaceId=ns.id, + rules=[rule]) + wait_for_ingress_to_active(p_client_for_c_owner, ingress) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.delete(ingress) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + p_client_for_c_owner.delete(ingress) + else: + p_client.delete(ingress) + validate_ingress_deleted(p_client, ingress) + + +def validate_ingress_deleted(client, ingress, timeout=DEFAULT_TIMEOUT): + """ + Checks whether ingress got deleted successfully. + Validates if ingress is null in for current object client. + @param client: Object client use to create ingress + @param ingress: ingress object subjected to be deleted + @param timeout: Max time to keep checking whether ingress is deleted or not + """ + time.sleep(2) + start = time.time() + ingresses = client.list_ingress(uuid=ingress.uuid).data + while len(ingresses) != 0: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for ingress to be deleted") + time.sleep(.5) + ingresses = client.list_ingress(uuid=ingress.uuid).data + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testingress") + p_client = get_project_client_for_token(p, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_istio.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_istio.py new file mode 100644 index 0000000..d1baeaf --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_istio.py @@ -0,0 +1,1036 @@ +import copy +import os +import re + +import pytest +import time + +from subprocess import CalledProcessError + +from rancher import ApiError + +from .test_auth import enable_ad, load_setup_data +from .common import add_role_to_user +from .common import auth_get_user_token +from .common import auth_resource_cleanup +from .common import AUTH_PROVIDER +from .common import AUTH_USER_PASSWORD +from .common import apply_crd +from .common import check_condition +from .common import compare_versions +from .common import CLUSTER_MEMBER +from .common import CLUSTER_OWNER +from .common import create_kubeconfig +from .common import create_project_and_ns +from .common import create_ns +from .common import DEFAULT_TIMEOUT +from .common import delete_crd +from .common import execute_kubectl_cmd +from .common import get_a_group_and_a_user_not_in_it +from .common import get_admin_client +from .common import get_client_for_token +from .common import get_cluster_client_for_token +from .common import get_crd +from .common import get_group_principal_id +from .common import get_project_client_for_token +from .common import get_user_by_group +from .common import get_user_client +from .common import get_user_client_and_cluster +from .common import if_test_group_rbac +from .common import if_test_rbac +from .common import login_as_auth_user +from .common import NESTED_GROUP_ENABLED +from .common import PROJECT_MEMBER +from .common import PROJECT_OWNER +from .common import PROJECT_READ_ONLY +from .common import random_test_name +from .common import rbac_get_kubeconfig_by_role +from .common import rbac_get_namespace +from .common import rbac_get_user_token_by_role +from .common import requests +from .common import run_command as run_command_common +from .common import ADMIN_TOKEN +from .common import USER_TOKEN +from .common import validate_all_workload_image_from_rancher +from .common import validate_app_deletion +from .common import wait_for_condition +from .common import wait_for_pod_to_running +from .common import wait_for_pods_in_workload +from .common import wait_for_wl_to_active + +from .test_monitoring import C_MONITORING_ANSWERS + +ISTIO_PATH = os.path.join( + os.path.dirname(os.path.realpath(__file__)), "resource/istio") +ISTIO_CRD_PATH = os.path.join(ISTIO_PATH, "crds") +ISTIO_TEMPLATE_ID = "cattle-global-data:system-library-rancher-istio" +ISTIO_VERSION = os.environ.get('RANCHER_ISTIO_VERSION', "") +ISTIO_INGRESSGATEWAY_NODEPORT = os.environ.get( + 'RANCHER_ISTIO_INGRESSGATEWAY_NODEPORT', 31380) +ISTIO_BOOKINFO_QUERY_RESULT = "Simple Bookstore App" +ISTIO_EXTERNAL_ID = "catalog://?catalog=system-library" \ + "&template=rancher-istio&version=" + +DEFAULT_ANSWERS = { + "enableCRDs": "true", + "gateways.enabled": "true", + "gateways.istio-ingressgateway.type": "NodePort", + "gateways.istio-ingressgateway.ports[0].nodePort": + ISTIO_INGRESSGATEWAY_NODEPORT, + "gateways.istio-ingressgateway.ports[0].port": 80, + "gateways.istio-ingressgateway.ports[0].targetPort": 80, + "gateways.istio-ingressgateway.ports[0].name": "http2", + "global.monitoring.type": "cluster-monitoring"} +namespace = {"app_client": None, "app_ns": None, "gateway_url": None, + "system_ns": None, "system_project": None, + "istio_version": None, "istio_app": None} + + +crd_test_data = [ + ("policy.authentication.istio.io", "authenticationpolicy.yaml"), + # ("adapter.config.istio.io", "adapter.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("attributemanifest.config.istio.io", "attributemanifest.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + ("handler.config.istio.io", "handler.yaml"), + # ("httpapispecbinding.config.istio.io", "httpapispecbinding.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("httpapispec.config.istio.io", "httpapispec.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("instance.config.istio.io", "instance.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + ("quotaspecbinding.config.istio.io", "quotaspecbinding.yaml"), + ("quotaspec.config.istio.io", "quotaspec.yaml"), + ("rule.config.istio.io", "rule.yaml"), + # ("template.config.istio.io", "template.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + ("destinationrule.networking.istio.io", "destinationrule.yaml"), + ("envoyfilter.networking.istio.io", "envoyfilter.yaml"), + ("gateway.networking.istio.io", "gateway.yaml"), + ("serviceentry.networking.istio.io", "serviceentry.yaml"), + ("sidecar.networking.istio.io", "sidecar.yaml"), + ("virtualservice.networking.istio.io", "virtualservice.yaml"), + ("rbacconfig.rbac.istio.io", "rbacconfig.yaml"), + ("servicerolebinding.rbac.istio.io", "servicerolebinding.yaml"), + ("servicerole.rbac.istio.io", "servicerole.yaml"), + ("authorizationpolicy.security.istio.io", "authorizationpolicy.yaml"), + # ("certificate.certmanager.k8s.io", "certificate.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("challenge.certmanager.k8s.io", "challenge.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("clusterissuer.certmanager.k8s.io", "clusterissuer.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("issuer.certmanager.k8s.io", "issuer.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 + # ("order.certmanager.k8s.io", "order.yaml"), + # ABOVE FAILS in current state: Rancher v2.3.5 +] + + +def test_istio_resources(): + app_client = namespace["app_client"] + app_ns = namespace["app_ns"] + gateway_url = namespace["gateway_url"] + + create_and_test_bookinfo_services(app_client, app_ns) + create_bookinfo_virtual_service(app_client, app_ns) + create_and_test_bookinfo_gateway(app_client, app_ns, gateway_url) + create_and_test_bookinfo_routing(app_client, app_ns, gateway_url) + + +def test_istio_deployment_options(): + file_path = ISTIO_PATH + '/nginx-custom-sidecar.yaml' + expected_image = "rancher/istio-proxyv2:1.4.3" + p_client = namespace["app_client"] + ns = namespace["app_ns"] + + execute_kubectl_cmd('apply -f ' + file_path + ' -n ' + ns.name, False) + result = execute_kubectl_cmd('get deployment -n ' + ns.name, True) + + for deployment in result['items']: + wl = p_client.list_workload(id='deployment:' + + deployment['metadata']['namespace'] + + ':' + + deployment['metadata']['name']).data[ + 0] + wl = wait_for_wl_to_active(p_client, wl, 60) + wl_pods = wait_for_pods_in_workload(p_client, wl, 1) + wait_for_pod_to_running(p_client, wl_pods[0]) + workload = p_client.list_workload(name="nginx-v1", + namespaceId=ns.id).data[0] + pod = p_client.list_pod(workloadId=workload.id).data[0] + try: + assert any(container.image == expected_image + for container in pod.containers) + except AssertionError as e: + retrieved_images = "" + for container in pod.containers: + retrieved_images += container.image + " " + retrieved_images = retrieved_images.strip().split(" ") + raise AssertionError("None of {} matches '{}'".format( + retrieved_images, expected_image)) + + +# Enables all possible istio custom answers with the exception of certmanager +def test_istio_custom_answers(skipif_unsupported_istio_version, + enable_all_options_except_certmanager): + + expected_deployments = [ + "grafana", "istio-citadel", "istio-egressgateway", "istio-galley", + "istio-ilbgateway", "istio-ingressgateway", "istio-pilot", + "istio-policy", "istio-sidecar-injector", "istio-telemetry", + "istio-tracing", "istiocoredns", "kiali", "prometheus" + ] + expected_daemonsets = ["istio-nodeagent"] + expected_job_list = ["istio-onefive-migration" if int(namespace["istio_version"].split(".")[1]) >= 5 else None] + + validate_all_workload_image_from_rancher( + get_system_client(USER_TOKEN), namespace["system_ns"], + ignore_pod_count=True, deployment_list=expected_deployments, + daemonset_list=expected_daemonsets, job_list=expected_job_list) + + +# This is split out separately from test_istio_custom_answers because +# certmanager creates its own crds outside of istio +@pytest.mark.skip(reason="To be removed, no support from 1.7.000") +def test_istio_certmanager_enables(skipif_unsupported_istio_version, + enable_certmanager): + expected_deployments = [ + "certmanager", "istio-citadel", "istio-galley", "istio-ingressgateway", + "istio-pilot", "istio-policy", "istio-sidecar-injector", + "istio-telemetry", "istio-tracing", "kiali" + ] + validate_all_workload_image_from_rancher( + get_system_client(USER_TOKEN), namespace["system_ns"], + ignore_pod_count=True, deployment_list=expected_deployments) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_all_cluster_owner(allow_all_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_owner = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_access(kiali_url, cluster_owner) + validate_access(tracing_url, cluster_owner) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_all_cluster_owner(allow_all_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_owner = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_access(grafana_url, cluster_owner) + validate_access(prometheus_url, cluster_owner) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_all_cluster_member(allow_all_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_access(kiali_url, cluster_member) + validate_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_all_cluster_member(allow_all_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_all_project_owner(allow_all_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_access(kiali_url, cluster_member) + validate_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_all_project_owner(allow_all_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_all_project_member(allow_all_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_access(kiali_url, cluster_member) + validate_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_all_project_member(allow_all_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_all_project_read(allow_all_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_access(kiali_url, cluster_member) + validate_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_all_project_read(allow_all_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_none_cluster_owner(default_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_owner = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_access(kiali_url, cluster_owner) + validate_access(tracing_url, cluster_owner) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_none_cluster_owner(default_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_owner = rbac_get_user_token_by_role(CLUSTER_OWNER) + validate_access(grafana_url, cluster_owner) + validate_access(prometheus_url, cluster_owner) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_none_cluster_member(default_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_no_access(kiali_url, cluster_member) + validate_no_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_none_cluster_member(default_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(CLUSTER_MEMBER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_none_project_owner(default_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_no_access(kiali_url, cluster_member) + validate_no_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_none_project_owner(default_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_OWNER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_none_project_member(default_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_no_access(kiali_url, cluster_member) + validate_no_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_none_project_member(default_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_MEMBER) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_metrics_allow_none_project_read(default_access): + kiali_url, tracing_url, _, _ = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_no_access(kiali_url, cluster_member) + validate_no_access(tracing_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_monitoring_allow_none_project_read(default_access): + _, _, grafana_url, prometheus_url = get_urls() + cluster_member = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + validate_no_access(grafana_url, cluster_member) + validate_no_access(prometheus_url, cluster_member) + + +@if_test_rbac +def test_rbac_istio_update_cluster_member(): + user = rbac_get_user_token_by_role(CLUSTER_MEMBER) + with pytest.raises(ApiError) as e: + update_istio_app({"FOO": "BAR"}, user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_disable_cluster_member(): + user = rbac_get_user_token_by_role(CLUSTER_MEMBER) + with pytest.raises(ApiError) as e: + delete_istio_app(user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_update_project_owner(): + user = rbac_get_user_token_by_role(PROJECT_OWNER) + with pytest.raises(ApiError) as e: + update_istio_app({"FOO": "BAR"}, user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_disable_project_owner(): + user = rbac_get_user_token_by_role(PROJECT_OWNER) + with pytest.raises(ApiError) as e: + delete_istio_app(user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_update_project_member(): + user = rbac_get_user_token_by_role(PROJECT_MEMBER) + with pytest.raises(ApiError) as e: + update_istio_app({"FOO": "BAR"}, user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_disable_project_member(): + user = rbac_get_user_token_by_role(PROJECT_MEMBER) + with pytest.raises(ApiError) as e: + delete_istio_app(user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_update_project_read(): + user = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + with pytest.raises(ApiError) as e: + update_istio_app({"FOO": "BAR"}, user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_istio_disable_project_read(): + user = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + with pytest.raises(ApiError) as e: + delete_istio_app(user) + + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("crd,manifest", crd_test_data) +def test_rbac_istio_crds_project_owner(skipif_unsupported_istio_version, + update_answers, crd, manifest): + if "certmanager" in crd: + update_answers("enable_certmanager") + else : + update_answers("default_access") + kubectl_context = rbac_get_kubeconfig_by_role(PROJECT_OWNER) + file = ISTIO_CRD_PATH + '/' + manifest + ns = rbac_get_namespace() + assert re.match("{}.* created".format(crd), + apply_crd(ns, file, kubectl_context)) + assert "Forbidden" not in get_crd(ns, crd, kubectl_context) + assert re.match("{}.* deleted".format(crd), + delete_crd(ns, file, kubectl_context)) + + +@if_test_rbac +@pytest.mark.parametrize("crd,manifest", crd_test_data) +def test_rbac_istio_crds_project_member(skipif_unsupported_istio_version, + update_answers, crd, manifest): + if "certmanager" in crd: + update_answers("enable_certmanager") + else : + update_answers("default_access") + kubectl_context = rbac_get_kubeconfig_by_role(PROJECT_MEMBER) + file = ISTIO_CRD_PATH + '/' + manifest + ns = rbac_get_namespace() + assert re.match("{}.* created".format(crd), + apply_crd(ns, file, kubectl_context)) + assert "Forbidden" not in get_crd(ns, crd, kubectl_context) + assert re.match("{}.* deleted".format(crd), + delete_crd(ns, file, kubectl_context)) + + +@if_test_rbac +@pytest.mark.parametrize("crd,manifest", crd_test_data) +def test_rbac_istio_crds_project_read(skipif_unsupported_istio_version, + update_answers, crd, manifest): + if "certmanager" in crd: + update_answers("enable_certmanager") + else : + update_answers("default_access") + kubectl_context = rbac_get_kubeconfig_by_role(PROJECT_READ_ONLY) + file = ISTIO_CRD_PATH + '/' + manifest + ns = rbac_get_namespace() + assert str(apply_crd(ns, file, kubectl_context)).startswith( + "Error from server (Forbidden)") + assert "Forbidden" not in get_crd(ns, crd, kubectl_context) + assert str(delete_crd(ns, file, kubectl_context)).startswith( + "Error from server (Forbidden)") + + +@if_test_group_rbac +def test_rbac_istio_group_access(auth_cluster_access, update_answers): + group, users, noauth_user = auth_cluster_access + update_answers("allow_group_access", group=group) + kiali_url, tracing_url, grafana_url, prometheus_url = get_urls() + for user in users: + user_token = auth_get_user_token(user) + print("Validating {} has access.".format(user)) + validate_access(kiali_url, user_token) + validate_access(tracing_url, user_token) + validate_no_access(grafana_url, user_token) + validate_no_access(prometheus_url, user_token) + + print("Validating {} does not have access.".format(noauth_user)) + noauth_token = auth_get_user_token(noauth_user) + validate_no_access(kiali_url, noauth_token) + validate_no_access(tracing_url, noauth_token) + validate_no_access(grafana_url, noauth_token) + validate_no_access(prometheus_url, noauth_token) + + +def validate_access(url, user): + headers = {'Authorization': 'Bearer ' + user} + response = requests.get(headers=headers, url=url, verify=False) + + assert response.ok + return response + + +def validate_no_access(url, user): + headers = {'Authorization': 'Bearer ' + user} + response = requests.get(headers=headers, url=url, verify=False) + + assert not response.ok + return response + + +def update_istio_app(answers, user, app=None, ns=None, project=None): + if app is None: + app = namespace["istio_app"] + if ns is None: + ns = namespace["system_ns"] + if project is None: + project = namespace["system_project"] + p_client = get_system_client(user) + updated_answers = copy.deepcopy(DEFAULT_ANSWERS) + updated_answers.update(answers) + namespace["istio_app"] = p_client.update( + obj=app, + externalId=ISTIO_EXTERNAL_ID, + targetNamespace=ns.name, + projectId=project.id, + answers=updated_answers) + verify_istio_app_ready(p_client, namespace["istio_app"], 120, 120) + + +def create_and_verify_istio_app(p_client, ns, project): + print("creating istio catalog app") + app = p_client.create_app( + name="cluster-istio", + externalId=ISTIO_EXTERNAL_ID, + targetNamespace=ns.name, + projectId=project.id, + answers=DEFAULT_ANSWERS + ) + verify_istio_app_ready(p_client, app, 120, 600) + return app + + +def delete_istio_app(user): + p_client = get_system_client(user) + p_client.delete(namespace["istio_app"]) + + +def verify_istio_app_ready(p_client, app, install_timeout, deploy_timeout, + initial_run=True): + if initial_run: + print("Verify Istio App has installed and deployed properly") + if install_timeout <= 0 or deploy_timeout <= 0: + raise TimeoutError("Timeout waiting for istio to be properly " + "installed and deployed.") from None + elif 'conditions' in app and not initial_run: + for cond in app['conditions']: + if "False" in cond['status'] and 'message' in cond \ + and "failed" in cond['message']: + raise AssertionError( + "Failed to properly install/deploy app. Reason: {}".format( + cond['message'])) from None + try: + wait_for_condition(p_client, app, check_condition('Installed', 'True'), + timeout=2) + except (Exception, TypeError): + verify_istio_app_ready(p_client, p_client.list_app( + name='cluster-istio').data[0], install_timeout-2, deploy_timeout, + initial_run=False) + try: + wait_for_condition(p_client, app, check_condition('Deployed', 'True'), + timeout=2) + except (Exception, TypeError): + verify_istio_app_ready(p_client, p_client.list_app( + name='cluster-istio').data[0], 2, deploy_timeout-2, + initial_run=False) + + +def get_urls(): + _, cluster = get_user_client_and_cluster() + if namespace["istio_version"] == "0.1.0" \ + or namespace["istio_version"] == "0.1.1": + kiali_url = os.environ.get('CATTLE_TEST_URL', "") + \ + "/k8s/clusters/" + cluster.id + \ + "/api/v1/namespaces/istio-system/services/" \ + "http:kiali-http:80/proxy/" + else: + kiali_url = os.environ.get('CATTLE_TEST_URL', "") + \ + "/k8s/clusters/" + cluster.id + \ + "/api/v1/namespaces/istio-system/services/" \ + "http:kiali:20001/proxy/" + tracing_url = os.environ.get('CATTLE_TEST_URL', "") + \ + "/k8s/clusters/" + cluster.id + \ + "/api/v1/namespaces/istio-system/services/" \ + "http:tracing:80/proxy/jaeger/search" + grafana_url = os.environ.get('CATTLE_TEST_URL', "") + \ + "/k8s/clusters/" + cluster.id + \ + "/api/v1/namespaces/cattle-prometheus/services/" \ + "http:access-grafana:80/proxy/dashboards/" + prometheus_url = os.environ.get('CATTLE_TEST_URL', "") + \ + "/k8s/clusters/" + cluster.id + \ + "/api/v1/namespaces/cattle-prometheus/services/" \ + "http:access-prometheus:80/proxy/" + return kiali_url, tracing_url, grafana_url, prometheus_url + + +def verify_admission_webhook(): + has_admission_webhook = execute_kubectl_cmd( + 'api-versions | grep admissionregistration', False) + if len(has_admission_webhook) == 0: + raise AssertionError( + "MutatingAdmissionWebhook and ValidatingAdmissionWebhook plugins " + "are not listed in the kube-apiserver --enable-admission-plugins") + + +def add_istio_label_to_ns(c_client, ns): + labels = { + "istio-injection": "enabled" + } + ns = c_client.update_by_id_namespace(ns.id, labels=labels) + return ns + + +def create_and_test_bookinfo_services(p_client, ns, timeout=DEFAULT_TIMEOUT): + book_info_file_path = ISTIO_PATH + '/bookinfo.yaml' + execute_kubectl_cmd('apply -f ' + book_info_file_path + ' -n ' + + ns.name, False) + result = execute_kubectl_cmd('get deployment -n ' + ns.name, True) + + for deployment in result['items']: + wl = p_client.list_workload(id='deployment:' + + deployment['metadata']['namespace'] + + ':' + + deployment['metadata']['name']).data[0] + wl = wait_for_wl_to_active(p_client, wl, 60) + wl_pods = wait_for_pods_in_workload(p_client, wl, 1) + wait_for_pod_to_running(p_client, wl_pods[0]) + + rating_pod = execute_kubectl_cmd('get pod -l app=ratings -n' + ns.name) + assert len(rating_pod['items']) == 1 + + rating_pod_name = rating_pod['items'][0]['metadata']['name'] + try: + result = execute_kubectl_cmd( + 'exec -it -n ' + ns.name + ' ' + rating_pod_name + + ' -c ratings -- curl productpage:9080/productpage' + + ' | grep -o ".*"', False) + except CalledProcessError: + result = None + + start = time.time() + while result is None or result.rstrip() != ISTIO_BOOKINFO_QUERY_RESULT: + if time.time() - start > timeout: + raise AssertionError( + "Timed out and failed to get bookinfo service ready") + time.sleep(.5) + try: + result = execute_kubectl_cmd( + 'exec -it -n ' + ns.name + ' ' + rating_pod_name + + ' -c ratings -- curl productpage:9080/productpage' + + ' | grep -o ".*"', False) + except CalledProcessError: + result = None + assert result.rstrip() == ISTIO_BOOKINFO_QUERY_RESULT + return result + + +def create_and_test_bookinfo_gateway(app_client, namespace, + gateway_url, timeout=DEFAULT_TIMEOUT): + servers = [{ + "hosts": ["*"], + "port": { + "number": "80", + "protocol": "HTTP", + "name": "http" + } + }] + selector = {"istio": "ingressgateway"} + app_client.create_gateway(name="bookinfo-gateway", + namespaceId=namespace.id, + selector=selector, + servers=servers) + + gateways = execute_kubectl_cmd('get gateway -n' + namespace.name, True) + assert len(gateways['items']) == 1 + + curl_cmd = 'curl -s http://' + gateway_url \ + + '/productpage | grep -o ".*"' + + result = run_command(curl_cmd) + + start = time.time() + while result is None or result.rstrip() != ISTIO_BOOKINFO_QUERY_RESULT: + if time.time() - start > timeout: + raise AssertionError( + "Timed out and failed to get bookinfo gateway ready") + time.sleep(.5) + result = run_command(curl_cmd) + assert result.rstrip() == ISTIO_BOOKINFO_QUERY_RESULT + + return result + + +def create_bookinfo_virtual_service(app_client, namespace): + http = [{ + "route": [{ + "destination": { + "host": "productpage", + "port": {"number": 9080} + }, + "weight": 100, + "portNumberOrName": "9080" + }], + "match": [ + {"uri": {"exact": "/productpage"}}, + {"uri": {"exact": "/login"}}, + {"uri": {"exact": "/logout"}}, + {"uri": {"prefix": "/api/v1/products"}} + ] + }] + + app_client.create_virtual_service(name="bookinfo", + namespaceId=namespace.id, + gateways=["bookinfo-gateway"], + http=http, + hosts=["*"]) + + +def create_bookinfo_destination_rules(app_client, namespace): + subsets = [ + { + "name": "v1", + "labels": { + "version": "v1" + } + }, + { + "name": "v2", + "labels": { + "version": "v2" + } + }, + { + "name": "v3", + "labels": { + "version": "v3" + } + } + ] + app_client.create_destination_rule(namespaceId=namespace.id, + name="reviews", + host="reviews", + subsets=subsets) + + +def create_and_test_bookinfo_routing(app_client, namespace, + gateway_url, timeout=30): + http = [{ + "route": [{ + "destination": { + "subset": "v3", + "host": "reviews", + "port": {"number": 9080} + }, + "weight": 100, + "portNumberOrName": "9080" + }] + }] + + create_bookinfo_destination_rules(app_client, namespace) + app_client.create_virtual_service(name="reviews", + namespaceId=namespace.id, + http=http, + hosts=["reviews"]) + + curl_cmd = 'curl -s http://' + gateway_url \ + + '/productpage | grep -o "glyphicon-star"' + + result = run_command(curl_cmd) + + start = time.time() + while result is None or "glyphicon-star" not in result: + if time.time() - start > timeout: + raise AssertionError( + "Timed out and failed to get correct reviews version") + time.sleep(.5) + result = run_command(curl_cmd) + assert "glyphicon-star" in result + + return result + + +# if grep returns no output, subprocess.check_output raises CalledProcessError +def run_command(command): + try: + return run_command_common(command) + except CalledProcessError: + return None + + +def get_system_client(user): + # Gets client and cluster using USER_TOKEN, who is a CLUSTER_OWNER + client, cluster = get_user_client_and_cluster() + projects = client.list_project(name='System', clusterId=cluster.id) + if len(projects.data) == 0: + raise AssertionError( + "System project not found in the cluster " + cluster.Name) + p = projects.data[0] + return get_project_client_for_token(p, user) + + +def add_user_to_cluster(username): + class User(object): + def __init__(self, u_name, user_id, token): + self.username = u_name + self.id = user_id + self.token = token + user_data = login_as_auth_user(username, AUTH_USER_PASSWORD) + u_id = user_data['userId'] + u_token = user_data['token'] + user_obj = User(username, u_id, u_token) + add_role_to_user(user_obj, CLUSTER_MEMBER) + # Enable one of these two below options to get around Issue #25365 + get_client_for_token(u_token) + # headers = {'Authorization': 'Bearer ' + u_token} + # url = os.environ.get('CATTLE_TEST_URL', "") + "/v3/users?me=true" + # response = requests.get(headers=headers, url=url, verify=False) + + +@pytest.fixture() +def update_answers(): + def _update_answers(answer_type, group=None): + answers = { + "kiali.enabled": "true", + "tracing.enabled": "true", + } + if answer_type == "allow_all_access": + additional_answers = { + "global.members[0].kind": "Group", + "global.members[0].name": "system:authenticated", + } + answers.update(additional_answers) + elif answer_type == "allow_group_access": + auth_admin = login_as_auth_user(load_setup_data()["admin_user"], + AUTH_USER_PASSWORD) + group_id = get_group_principal_id(group, token=auth_admin['token']) + additional_answers = { + "global.members[0].kind": "Group", + "global.members[0].name": group_id, + } + answers.update(additional_answers) + elif answer_type == "enable_certmanager": + additional_answers = {"certmanager.enabled": "true"} + answers.update(additional_answers) + elif answer_type == "enable_all_options_except_certmanager": + additional_answers = { + "gateways.istio-egressgateway.enabled": "true", + "gateways.istio-ilbgateway.enabled": "true", + "gateways.istio-ingressgateway.sds.enabled": "true", + "global.proxy.accessLogFile": "/dev/stdout", + "grafana.enabled": "true", + "istiocoredns.enabled": "true", + "kiali.dashboard.grafanaURL": "", + "kiali.prometheusAddr": "http://prometheus:9090", + "nodeagent.enabled": "true", + "nodeagent.env.CA_ADDR": "istio-citadel:8060", + "nodeagent.env.CA_PROVIDER": "Citadel", + "prometheus.enabled": "true", + } + answers.update(additional_answers) + update_istio_app(answers, USER_TOKEN) + return _update_answers + + +@pytest.fixture() +def default_access(update_answers): + update_answers("default_access") + + +@pytest.fixture() +def allow_all_access(update_answers): + update_answers("allow_all_access") + + +@pytest.fixture() +def enable_certmanager(update_answers): + update_answers("enable_certmanager") + + +@pytest.fixture() +def enable_all_options_except_certmanager(update_answers): + update_answers("enable_all_options_except_certmanager") + + +@pytest.fixture(scope='function') +def skipif_unsupported_istio_version(request): + if ISTIO_VERSION != "": + istio_version = ISTIO_VERSION + else: + client, _ = get_user_client_and_cluster() + istio_versions = list(client.list_template( + id=ISTIO_TEMPLATE_ID).data[0].versionLinks.keys()) + istio_version = istio_versions[len(istio_versions) - 1] + if compare_versions(istio_version, "1.4.3") < 0: + pytest.skip("This test is not supported for older Istio versions") + + +@pytest.fixture(scope='function') +def auth_cluster_access(request): + group, noauth_user = get_a_group_and_a_user_not_in_it( + NESTED_GROUP_ENABLED) + users = get_user_by_group(group, NESTED_GROUP_ENABLED) + for user in users: + add_user_to_cluster(user) + add_user_to_cluster(noauth_user) + + def fin(): + auth_resource_cleanup() + request.addfinalizer(fin) + return group, users, noauth_user + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + global DEFAULT_ANSWERS + global ISTIO_EXTERNAL_ID + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + + admin_client = get_admin_client() + ad_enabled = admin_client.by_id_auth_config("activedirectory").enabled + if AUTH_PROVIDER == "activeDirectory" and not ad_enabled: + enable_ad(load_setup_data()["admin_user"], ADMIN_TOKEN, + password=AUTH_USER_PASSWORD, nested=NESTED_GROUP_ENABLED) + + projects = client.list_project(name='System', clusterId=cluster.id) + if len(projects.data) == 0: + raise AssertionError( + "System project not found in the cluster " + cluster.name) + p = projects.data[0] + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + istio_versions = list(client.list_template( + id=ISTIO_TEMPLATE_ID).data[0].versionLinks.keys()) + istio_version = istio_versions[len(istio_versions) - 1] + + if ISTIO_VERSION != "": + istio_version = ISTIO_VERSION + ISTIO_EXTERNAL_ID += istio_version + answers = {"global.rancher.clusterId": p.clusterId} + DEFAULT_ANSWERS.update(answers) + + monitoring_answers = copy.deepcopy(C_MONITORING_ANSWERS) + monitoring_answers["prometheus.persistence.enabled"] = "false" + monitoring_answers["grafana.persistence.enabled"] = "false" + + if cluster["enableClusterMonitoring"] is False: + client.action(cluster, "enableMonitoring", + answers=monitoring_answers) + + if cluster["istioEnabled"] is False: + verify_admission_webhook() + + ns = create_ns(c_client, cluster, p, 'istio-system') + app = create_and_verify_istio_app(p_client, ns, p) + else: + app = p_client.list_app(name='cluster-istio').data[0] + ns = c_client.list_namespace(name='istio-system').data[0] + update_istio_app(DEFAULT_ANSWERS, USER_TOKEN, + app=app, ns=ns, project=p) + + istio_project, app_ns = create_project_and_ns( + USER_TOKEN, cluster, + random_test_name("istio-app"), + random_test_name("istio-app-ns")) + add_istio_label_to_ns(c_client, app_ns) + + app_client = get_project_client_for_token(istio_project, USER_TOKEN) + + istio_gateway_wl = p_client.by_id_workload('deployment:' + + ns.name + + ':istio-ingressgateway') + assert istio_gateway_wl is not None + endpoints = istio_gateway_wl['publicEndpoints'][0] + gateway_url = endpoints['addresses'][0] + ':' + str(endpoints['port']) + + namespace["gateway_url"] = gateway_url + namespace["app_ns"] = app_ns + namespace["app_client"] = app_client + namespace["system_ns"] = ns + namespace["system_project"] = p + namespace["istio_version"] = istio_version + namespace["istio_app"] = app + + def fin(): + client = get_user_client() + # delete the istio app + app = p_client.delete(namespace["istio_app"]) + validate_app_deletion(p_client, app.id) + # delete the istio ns + p_client.delete(namespace["system_ns"]) + # disable the cluster monitoring + c = client.reload(cluster) + if c["enableClusterMonitoring"] is True: + client.action(c, "disableMonitoring") + # delete the istio testing project + client.delete(istio_project) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k3s_airgap.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k3s_airgap.py new file mode 100644 index 0000000..acdf71a --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k3s_airgap.py @@ -0,0 +1,110 @@ +import os +from lib.aws import AWS_USER +from .common import AmazonWebServices +from .test_airgap import (AG_HOST_NAME, ARCH, NUMBER_OF_INSTANCES, + TARBALL_TYPE, + get_bastion_node, prepare_registries_mirror_on_node, + run_command_on_airgap_node, prepare_private_registry, + copy_certs_to_node, deploy_airgap_cluster, + trust_certs_on_node, add_tarball_to_node, + optionally_add_cluster_to_rancher) + +RANCHER_K3S_VERSION = os.environ.get("RANCHER_K3S_VERSION", "") +K3S_SERVER_OPTIONS = os.environ.get("K3S_SERVER_OPTIONS", "") +K3S_AGENT_OPTIONS = os.environ.get("K3S_AGENT_OPTIONS", "") + + +def test_deploy_airgap_k3s_system_default_registry(): + bastion_node = get_bastion_node(auth=False) + prepare_private_registry(bastion_node, RANCHER_K3S_VERSION) + ag_nodes = prepare_airgap_k3s(bastion_node, NUMBER_OF_INSTANCES, + 'system_default_registry') + server_ops = K3S_SERVER_OPTIONS + " --system-default-registry={}".format( + bastion_node.host_name) + agent_ops = K3S_AGENT_OPTIONS + deploy_airgap_cluster(bastion_node, ag_nodes, "k3s", server_ops, agent_ops) + + +def test_deploy_airgap_k3s_private_registry(): + bastion_node = get_bastion_node(auth=True) + prepare_private_registry(bastion_node, RANCHER_K3S_VERSION) + ag_nodes = prepare_airgap_k3s(bastion_node, NUMBER_OF_INSTANCES, + 'private_registry') + deploy_airgap_cluster(bastion_node, ag_nodes, "k3s", + K3S_SERVER_OPTIONS, K3S_AGENT_OPTIONS) + optionally_add_cluster_to_rancher(bastion_node, ag_nodes) + + +def test_deploy_airgap_k3s_tarball(): + bastion_node = get_bastion_node() + add_k3s_tarball_to_bastion(bastion_node, RANCHER_K3S_VERSION) + ag_nodes = prepare_airgap_k3s(bastion_node, NUMBER_OF_INSTANCES, 'tarball') + deploy_airgap_cluster(bastion_node, ag_nodes, "k3s", + K3S_SERVER_OPTIONS, K3S_AGENT_OPTIONS) + optionally_add_cluster_to_rancher(bastion_node, ag_nodes, prep="k3s") + + +def add_k3s_tarball_to_bastion(bastion_node, k3s_version): + # Get k3s files associated with the specified version + k3s_binary = 'k3s' + if ARCH == 'arm64': + k3s_binary = 'k3s-arm64' + + get_tarball_command = \ + 'wget -O k3s-airgap-images-{1}.{3} https://github.com/k3s-io/k3s/' \ + 'releases/download/{0}/k3s-airgap-images-{1}.{3} && ' \ + 'wget -O k3s-install.sh https://get.k3s.io/ && ' \ + 'wget -O k3s https://github.com/k3s-io/k3s/' \ + 'releases/download/{0}/{2}'.format(k3s_version, ARCH, k3s_binary, + TARBALL_TYPE) + bastion_node.execute_command(get_tarball_command) + + +def prepare_airgap_k3s(bastion_node, number_of_nodes, method): + node_name = AG_HOST_NAME + "-k3s-airgap" + # Create Airgap Node in AWS + ag_nodes = AmazonWebServices().create_multiple_nodes( + number_of_nodes, node_name, public_ip=False) + + for num, ag_node in enumerate(ag_nodes): + # Copy relevant k3s files to airgapped node + ag_node_copy_files = \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no ./k3s-install.sh ' \ + '{1}@{2}:~/install.sh && ' \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no ./k3s ' \ + '{1}@{2}:~/k3s && ' \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no certs/* ' \ + '{1}@{2}:~/'.format(bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_copy_files) + + ag_node_make_executable = \ + 'sudo mv ./k3s /usr/local/bin/k3s && ' \ + 'sudo chmod +x /usr/local/bin/k3s && sudo chmod +x install.sh' + run_command_on_airgap_node(bastion_node, ag_node, + ag_node_make_executable) + + if method == 'private_registry': + prepare_registries_mirror_on_node(bastion_node, ag_node, 'k3s') + elif method == 'system_default_registry': + copy_certs_to_node(bastion_node, ag_node) + trust_certs_on_node(bastion_node, ag_node) + elif method == 'tarball': + add_tarball_to_node(bastion_node, ag_node, + 'k3s-airgap-images-{0}.{1}'.format( + ARCH, TARBALL_TYPE), 'k3s') + + print("Airgapped K3S Instance Details:\nNAME: {}-{}\nPRIVATE IP: {}\n" + "".format(node_name, num, ag_node.private_ip_address)) + + assert len(ag_nodes) == NUMBER_OF_INSTANCES + print( + '{} airgapped k3s instance(s) created.\n' + 'Connect to these and run commands by connecting to bastion node, ' + 'then connecting to these:\n' + 'ssh -i {}.pem {}@NODE_PRIVATE_IP'.format( + NUMBER_OF_INSTANCES, bastion_node.ssh_key_name, AWS_USER)) + for ag_node in ag_nodes: + assert ag_node.private_ip_address is not None + assert ag_node.public_ip_address is None + return ag_nodes diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k8s_version_networkmodes.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k8s_version_networkmodes.py new file mode 100644 index 0000000..a5a27aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_k8s_version_networkmodes.py @@ -0,0 +1,66 @@ +from lib.aws import AmazonWebServices + +from .common import * # NOQA + +k8s_version = "v1.10.1-rancher1" +rke_config = {"authentication": {"type": "authnConfig", "strategy": "x509"}, + "ignoreDockerVersion": False, + "type": "rancherKubernetesEngineConfig"} +RANCHER_CLEANUP_CLUSTER = os.environ.get('RANCHER_CLEANUP_CLUSTER', "True") +NETWORK_PLUGIN = os.environ.get('NETWORK_PLUGIN', "canal") + + +def test_rke_custom_k8s_1_8_10(): + validate_k8s_version("v1.8.10-rancher1-1", plugin=NETWORK_PLUGIN) + + +def test_rke_custom_k8s_1_8_11(): + validate_k8s_version("v1.8.11-rancher1", plugin=NETWORK_PLUGIN) + + +def test_rke_custom_k8s_1_9_5(): + validate_k8s_version("v1.9.5-rancher1-1", plugin=NETWORK_PLUGIN) + + +def test_rke_custom_k8s_1_9_7(): + validate_k8s_version("v1.9.7-rancher1", plugin=NETWORK_PLUGIN) + + +def test_rke_custom_k8s_1_10_0(): + validate_k8s_version("v1.10.0-rancher1-1", plugin=NETWORK_PLUGIN) + + +def test_rke_custom_k8s_1_10_1(): + validate_k8s_version("v1.10.1-rancher1", plugin=NETWORK_PLUGIN) + + +def validate_k8s_version(k8s_version, plugin="canal"): + rke_config["kubernetesVersion"] = k8s_version + rke_config["network"] = {"type": "networkConfig", "plugin": plugin} + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 8, random_test_name("testcustom")) + node_roles = [["controlplane"], ["controlplane"], + ["etcd"], ["etcd"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + client = get_user_client() + cluster = client.create_cluster(name=random_name(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "active" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, + node_roles[i], aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + cluster = validate_cluster(client, cluster) + if RANCHER_CLEANUP_CLUSTER == "True": + delete_cluster(client, cluster) + delete_node(aws_nodes) + + +def delete_node(aws_nodes): + for node in aws_nodes: + AmazonWebServices().delete_node(node) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_kdm_changes.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_kdm_changes.py new file mode 100644 index 0000000..9c634a0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_kdm_changes.py @@ -0,0 +1,218 @@ +from copy import deepcopy +import os +import ast +import requests +from .common import json +from .common import CATTLE_API_URL +from .common import create_config_file +from .common import CATTLE_TEST_URL +from .common import ADMIN_TOKEN +from .common import get_setting_value_by_name +from .common import get_user_client +from .common import USER_TOKEN +from .common import validate_cluster +from .test_rke_cluster_provisioning import HOST_NAME +from .test_rke_cluster_provisioning import random_name +from .test_rke_cluster_provisioning import rke_config +from .test_rke_cluster_provisioning import K8S_VERSION +from .test_rke_cluster_provisioning import random_test_name +from .test_rke_cluster_provisioning import get_custom_host_registration_cmd + +from lib.aws import AmazonWebServices +import multiprocessing + + +K8S_VERSION_URL = "/settings/k8s-versions-current" +NETWORK_PLUGINS = ["calico", "canal", "flannel", "weave"] +DNS_PROVIDERS = ["coredns", "kube-dns"] +CLUSTER_LIST = [] +NODE_COUNT_KDM_CLUSTER = \ + int(os.environ.get("RANCHER_NODE_COUNT_KDM_CLUSTER", 4)) +DNS_MATRIX = \ + ast.literal_eval(os.environ.get('RANCHER_DNS_PROVIDER_MATRIX', "False")) + + +def test_clusters_for_kdm(): + """ + This fuction is used to check the KDM changes. + It deploys all the different types of k8s clusters - default_k8s_versions, + across all the network provider types - + NETWORK_PLUGINS, and all dns provider types - DNS_PROVIDERS + It then deploys a workload on each cluster, + checks service discovery - DNS resolution and + checks the ingress when enabled + Helper function - validate_custom_cluster_kdm() to create the AWS nodes + and add to the cluster + """ + rancher_version = get_setting_value_by_name('server-version') + if K8S_VERSION == "": + if str(rancher_version).startswith('v2.2'): + k8s_v = get_setting_value_by_name('k8s-version-to-images') + default_k8s_versions = json.loads(k8s_v).keys() + else: + k8s_v = get_setting_value_by_name('k8s-versions-current') + default_k8s_versions = k8s_v.split(",") + + else: + default_k8s_versions = K8S_VERSION.split(",") + list_process = [] + network_plugins = NETWORK_PLUGINS + dns_providers = DNS_PROVIDERS + print("default_k8s_versions: ", default_k8s_versions) + for k8s_version in default_k8s_versions: + rke_config_new = deepcopy(rke_config) + rke_config_new["kubernetesVersion"] = k8s_version + node_count = NODE_COUNT_KDM_CLUSTER * len(network_plugins) + if DNS_MATRIX: + node_count = node_count * len(dns_providers) * 2 + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + node_count, random_test_name(HOST_NAME)) + i = 0 + for network_plugin in network_plugins: + if network_plugin == "calico" or \ + network_plugin == "canal" or network_plugin == "weave": + rke_config_new["network"]["options"] = \ + {"flannel_backend_type": "vxlan"} + rke_config_new["network"] = {"type": "networkConfig", + "plugin": network_plugin} + if DNS_MATRIX: + for dns_provider in dns_providers: + for nodelocaldns in True, False: + dns_entry, cluster_name = get_dns_rke_config( + dns_provider, + network_plugin, + nodelocaldns + ) + rke_config_new.update(dns_entry) + list_process = create_kdm_clusters( + cluster_name, + rke_config_new, + aws_nodes, + i, + list_process + ) + i = i + NODE_COUNT_KDM_CLUSTER + else: + cluster_name = random_test_name(network_plugin) + list_process = create_kdm_clusters( + cluster_name, + rke_config_new, + aws_nodes, + i, + list_process + ) + i = i + NODE_COUNT_KDM_CLUSTER + failed_cluster = {} + passed_cluster = {} + for process in list_process: + process.join() + # setting environment variables + env_details = "env.CATTLE_TEST_URL='" + CATTLE_TEST_URL + "'\n" + env_details += "env.ADMIN_TOKEN='" + ADMIN_TOKEN + "'\n" + env_details += "env.USER_TOKEN='" + USER_TOKEN + "'\n" + names = "" + i = 0 + for cluster in CLUSTER_LIST: + env_details += \ + "env.CLUSTER_NAME_" + str(i) + "='" + cluster.name + "'\n" + names += cluster.name + "," + i = i + 1 + create_config_file(env_details) + print("env_details:", env_details) + print("list of cluster names: " + names[:-1]) + client = get_user_client() + for cluster in CLUSTER_LIST: + try: + validate_cluster(client, cluster, cluster.state, False, False) + # details of cluster that have passed + passed_cluster = save_cluster_details(passed_cluster, cluster) + + except Exception as e: + print("Issue in {}:\n{}".format(cluster.name, e)) + # details of cluster that have failed + failed_cluster = save_cluster_details(failed_cluster, cluster) + + # printing results + print("--------------Passed Cluster information--------------'\n") + print("Clusters: " + ''.join('{0},'.format(key) for key, value in passed_cluster.items())) + for key, value in passed_cluster.items(): + print(key + "-->" + str(value) + "\n") + print("--------------Failed Cluster information--------------'\n") + for key, value in failed_cluster.items(): + print(key + "-->" + str(value) + "\n") + assert len(failed_cluster) == 0, "Clusters have failed to provision. " \ + "Check logs for more info" + + +def validate_custom_cluster_kdm(cluster, aws_nodes): + if NODE_COUNT_KDM_CLUSTER == 4: + node_roles = [["controlplane"], ["etcd"], ["worker"], ["worker"]] + elif NODE_COUNT_KDM_CLUSTER == 2: + node_roles = [["controlplane", "etcd", "worker"], ["worker"]] + else: + node_roles = [["worker", "controlplane", "etcd"]] + client = get_user_client() + assert cluster.state == "provisioning" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, + cluster, + node_roles[i], + aws_node) + for nr in node_roles[i]: + aws_node.roles.append(nr) + aws_node.execute_command(docker_run_cmd) + i += 1 + + +def get_dns_rke_config(dns_provider, network_plugin, nodelocaldns): + dns_entry = dict() + dns_entry["dns"] = {"type": "dnsConfig", + "provider": dns_provider} + cluster_options = network_plugin + "-" + dns_provider + if nodelocaldns: + dns_entry["dns"]["nodelocal"] = \ + {"type": "nodelocal", "ipAddress": "169.254.20.10"} + cluster_options += "-nodelocaldns" + cluster_name = random_test_name(cluster_options) + return dns_entry, cluster_name + + +def create_kdm_clusters(cluster_name, rke_config_new, + aws_nodes, aws_nodes_index, list_process): + client = get_user_client() + cluster = client.create_cluster(name=cluster_name, + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig= + rke_config_new) + p1 = multiprocessing.Process( + target=validate_custom_cluster_kdm, + args=( + cluster, + aws_nodes[aws_nodes_index:aws_nodes_index + NODE_COUNT_KDM_CLUSTER] + ) + ) + CLUSTER_LIST.append(cluster) + list_process.append(p1) + p1.start() + return list_process + + +def save_cluster_details(cluster_detail, cluster): + cluster_detail[cluster.name] = {} + cluster_detail[cluster.name]["k8s"] = \ + cluster["rancherKubernetesEngineConfig"]["kubernetesVersion"] + cluster_detail[cluster.name]["network"] = \ + cluster["rancherKubernetesEngineConfig"]["network"]["plugin"] + if DNS_MATRIX: + cluster_detail[cluster.name]["dns"] = \ + cluster["rancherKubernetesEngineConfig"]["dns"]["provider"] + if "-nodelocaldns" in cluster.name: + cluster_detail[cluster.name]["nodelocaldns"] = \ + "enabled" + else: + cluster_detail[cluster.name]["nodelocaldns"] = \ + "disabled" + return cluster_detail diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_logging_e2e.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_logging_e2e.py new file mode 100644 index 0000000..c10cfb5 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_logging_e2e.py @@ -0,0 +1,206 @@ +import time +import urllib + +import pytest + +from .common import CATTLE_TEST_URL +from .common import DEFAULT_TIMEOUT +from .common import USER_TOKEN +from .common import WebsocketLogParse +from .common import create_connection +from .common import create_kubeconfig +from .common import create_project_and_ns +from .common import get_project_client_for_token +from .common import get_user_client_and_cluster +from .common import random_test_name +from .common import wait_for_app_to_active + +# Skipping this test module because library-fluentd-aggregator from library catalog is not supported on latest +# rancher versions +pytest.skip(allow_module_level=True) + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "name_prefix": None, "admin_client": None, "sys_p_client": None, + "pod": None} +fluentd_aggregator_answers = {"defaultImage": "true", + "replicas": "1", + "service.type": "ClusterIP", + "persistence.enabled": "false", + "extraPersistence.enabled": "false", + "extraPersistence.size": "10Gi", + "extraPersistence.mountPath": "/extra", + "extraPersistence.storageClass": "", + "output.type": "custom", + "output.flushInterval": "5s", + "output.customConf": "\n @type stdout\n"} + +FLUENTD_AGGREGATOR_CATALOG_ID = "catalog://?catalog=library&template=fluentd-aggregator&version=0.3.1" + + +fluentd_app_name = "rancher-logging" +endpoint_port = "24224" +weight = 100 + + +def test_fluentd_target_logs(setup_fluentd_aggregator, request): + cluster_logging = create_cluster_logging(fluentd_target_without_ssl()) + request.addfinalizer(lambda: delete_logging(cluster_logging)) + wait_for_logging_app() + + # wait for config to sync + time.sleep(90) + validate_websocket_view_logs() + + +def test_project_fluentd_target_logs(setup_fluentd_aggregator, request): + project_logging = create_project_logging(fluentd_target_without_ssl()) + request.addfinalizer(lambda: delete_logging(project_logging)) + wait_for_logging_app() + + # wait for config to sync + # wait for project logs to start being forwarded + time.sleep(90) + validate_websocket_view_logs() + + +def wait_for_logging_app(): + sys_p_client = namespace["sys_p_client"] + wait_for_app_to_active(sys_p_client, fluentd_app_name) + + +def fluentd_target_without_ssl(): + return {"compress": True, + "enableTls": False, + "sslVerify": False, + "fluentServers": [ + { + "endpoint": namespace["hostname"]+ ":" + endpoint_port, + "weight": weight + } + ], + } + + +def get_system_project_client(): + cluster = namespace["cluster"] + admin_client = namespace["admin_client"] + projects = admin_client.list_project(name="System", + clusterId=cluster.id).data + assert len(projects) == 1 + project = projects[0] + sys_p_client = get_project_client_for_token(project, USER_TOKEN) + return sys_p_client + + +def create_cluster_logging(config, json_parsing=False): + cluster = namespace["cluster"] + admin_client = namespace["admin_client"] + name = random_test_name("fluentd") + return admin_client.create_cluster_logging(name=name, + clusterId=cluster.id, + fluentForwarderConfig=config, + enableJSONParsing=json_parsing, + outputFlushInterval=5 + ) + + +def create_project_logging(config, json_parsing=False): + admin_client = namespace["admin_client"] + cluster = namespace["cluster"] + projects = admin_client.list_project(name="System", + clusterId=cluster.id).data + assert len(projects) == 1 + project = projects[0] + name = random_test_name("project-fluentd") + return admin_client.create_project_logging(name=name, + projectId=project.id, + fluentForwarderConfig=config, + enableJSONParsing=json_parsing, + outputFlushInterval=5 + ) + + +def delete_logging(logging_project): + admin_client = namespace["admin_client"] + admin_client.delete(logging_project) + + +def validate_websocket_view_logs(): + url_base = 'wss://' + CATTLE_TEST_URL[8:] + \ + '/k8s/clusters/' + namespace["cluster"].id + \ + '/api/v1/namespaces/' + namespace["ns"].name + \ + '/pods/' + namespace["pod"].name + \ + '/log?container=' + namespace["pod"].containers[0].name + params_dict = { + "tailLines": 500, + "follow": True, + "timestamps": True, + "previous": False, + } + params = urllib.parse.urlencode(params_dict, doseq=True, + quote_via=urllib.parse.quote, safe='()') + + url = url_base + "&" + params + wait_for_match(WebsocketLogParse(), url) + + +def wait_for_match(wslog, url, timeout=DEFAULT_TIMEOUT): + start = time.time() + found = False + + ws = create_connection(url, ["base64.binary.k8s.io"]) + assert ws.connected, "failed to build the websocket" + wslog.start_thread(target=wslog.receiver, args=(ws, False)) + while not found: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for string to match in logs") + time.sleep(1) + print('shell command and output:\n' + wslog.last_message + '\n') + if 'log_type' in wslog.last_message or '{"log"' in wslog.last_message: + found = True + wslog.last_message = '' + break + ws.close() + assert found == True + + +@pytest.fixture(autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + project_name = random_test_name("testlogging") + p, ns = create_project_and_ns(USER_TOKEN, cluster, + project_name) + p_client = get_project_client_for_token(p, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["admin_client"] = client + namespace["sys_p_client"] = get_system_project_client() + + def fin(): + client.delete(namespace["project"]) + request.addfinalizer(fin) + + +@pytest.fixture +def setup_fluentd_aggregator(): + p_client = namespace["p_client"] + ns = namespace["ns"] + name = random_test_name("fluentd-aggregator") + namespace["name_prefix"] = name + app = p_client.create_app(name=name, + answers=fluentd_aggregator_answers, + targetNamespace=ns.name, + externalId=FLUENTD_AGGREGATOR_CATALOG_ID, + namespaceId=ns.id) + wait_for_app_to_active(p_client, app.name) + namespace["hostname"] = namespace["name_prefix"] + \ + "." + namespace["ns"].name + \ + ".svc.cluster.local" + + wl = p_client.list_workload(name=name).data[0] + pod = p_client.list_pod(workloadId=wl.id).data[0] + namespace["pod"] = pod diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_multi_cluster_app.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_multi_cluster_app.py new file mode 100644 index 0000000..9dc2b9b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_multi_cluster_app.py @@ -0,0 +1,606 @@ +from .common import create_catalog_external_id +from .common import create_project_and_ns +from .common import get_admin_client +from .common import get_defaut_question_answers +from .common import get_project_client_for_token +from .common import get_user_client +from .common import get_user_client_and_cluster +from .test_rke_cluster_provisioning import create_and_validate_custom_host +from .common import random_test_name +from .common import random_name +from .common import USER_TOKEN +from .common import validate_app_deletion +from .common import validate_response_app_endpoint +from .common import wait_for_app_to_active +from .common import wait_for_catalog_active +from .common import wait_for_mcapp_to_active +from .common import delete_node +import pytest +import time + +# Skipping all the tests from this module because Multi-Cluster Apps have been deprecated as of Rancher v2.5.0 +pytest.skip(allow_module_level=True) + +project = {} +project_detail = {"c0_id": None, "c1_id": None, "c2_id": None, + "p0_id": None, "p1_id": None, "p2_id": None, + "p_client0": None, "namespace0": None, + "cluster0": None, "project0": None, + "p_client1": None, "namespace1": None, + "cluster1": None, "project1": None, + "p_client2": None, "namespace2": None, + "cluster2": None, "project2": None} + +global_client = {"cluster_count": False} +PROJECT_ROLE = ["project-member"] +CATALOG_URL = "https://github.com/rancher/integration-test-charts.git" +BRANCH = "validation-tests" +CATALOG_NAME = random_test_name("test-catalog") +WORDPRESS_TEMPLATE_VID_738 = \ + "cattle-global-data:" + CATALOG_NAME + "-wordpress-7.3.8" +MYSQL_TEMPLATE_VID_131 = "cattle-global-data:" + CATALOG_NAME + "-mysql-1.3.1" +MYSQL_TEMPLATE_VID_132 = "cattle-global-data:" + CATALOG_NAME + "-mysql-1.3.2" +GRAFANA_TEMPLATE_VID = "cattle-global-data:" + CATALOG_NAME + "-grafana-3.8.6" +WORDPRESS_EXTID = create_catalog_external_id(CATALOG_NAME, + "wordpress", "7.3.8") +MYSQL_EXTERNALID_131 = create_catalog_external_id(CATALOG_NAME, + "mysql", "1.3.1") +MYSQL_EXTERNALID_132 = create_catalog_external_id(CATALOG_NAME, + "mysql", "1.3.2") +GRAFANA_EXTERNALID = create_catalog_external_id(CATALOG_NAME, + "grafana", "3.8.6") +ROLLING_UPGRADE_STRATEGY = { + 'rollingUpdate': { + 'batchSize': 1, + 'interval': 20, + 'type': '/v3/schemas/rollingUpdate'}, + 'type': '/v3/schemas/upgradeStrategy'} + +skip_test_rolling_update = pytest.mark.skipif( + reason="Skipping this test always " + "as for now its not in scope for automation") + + +def test_multi_cluster_app_create(): + client = get_user_client() + assert_if_valid_cluster_count() + targets = [] + for project_id in project: + targets.append({"projectId": project_id, "type": "target"}) + answer_values = get_defaut_question_answers(client, WORDPRESS_EXTID) + mcapp = client.create_multiClusterApp( + templateVersionId=WORDPRESS_TEMPLATE_VID_738, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster_wordpress(mcapp) + client.delete(mcapp) + + +def test_multi_cluster_app_edit_template_upgrade(): + client = get_user_client() + assert_if_valid_cluster_count() + targets = [] + for project_id in project: + targets.append({"projectId": project_id, "type": "target"}) + answer_values = \ + get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + answer_values_new = get_defaut_question_answers(client, + MYSQL_EXTERNALID_132) + mcapp = client.update(mcapp, + roles=PROJECT_ROLE, + templateVersionId=MYSQL_TEMPLATE_VID_132, + answers=[{"values": answer_values_new}]) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + client.delete(mcapp) + + +def test_multi_cluster_app_delete(): + assert_if_valid_cluster_count() + targets = [] + for project_id in project: + targets.append({"projectId": project_id, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + delete_multi_cluster_app(mcapp, True) + + +def test_multi_cluster_app_template_rollback(): + assert_if_valid_cluster_count() + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + first_id = mcapp["status"]["revisionId"] + assert mcapp.templateVersionId == MYSQL_TEMPLATE_VID_131 + answer_values_new = get_defaut_question_answers( + client, MYSQL_EXTERNALID_132) + mcapp = client.update(mcapp, + roles=PROJECT_ROLE, + templateVersionId=MYSQL_TEMPLATE_VID_132, + answers=[{"values": answer_values_new}]) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + assert mcapp.templateVersionId == MYSQL_TEMPLATE_VID_132 + mcapp.rollback(revisionId=first_id) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + assert mcapp.templateVersionId == MYSQL_TEMPLATE_VID_131 + client.delete(mcapp) + + +def test_multi_cluster_upgrade_and_add_target(): + assert_if_valid_cluster_count() + project_id = project_detail["p0_id"] + targets = [{"projectId": project_id, "type": "target"}] + project_id_2 = project_detail["p1_id"] + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + uuid = mcapp.uuid + name = mcapp.name + assert len(client.list_multiClusterApp( + uuid=uuid, name=name).data[0]["targets"]) == 1, \ + "did not start with 1 target" + mcapp.addProjects(projects=[project_id_2]) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + assert len(client.list_multiClusterApp( + uuid=uuid, name=name).data[0]["targets"]) == 2, "did not add target" + validate_multi_cluster_app_cluster(mcapp) + client.delete(mcapp) + + +def test_multi_cluster_upgrade_and_delete_target(): + assert_if_valid_cluster_count() + project_id = project_detail["p0_id"] + targets = [] + for project_id in project: + targets.append({"projectId": project_id, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + uuid = mcapp.uuid + name = mcapp.name + assert len(client.list_multiClusterApp( + uuid=uuid, name=name).data[0]["targets"]) == 2, \ + "did not start with 2 targets" + project_client = project_detail["p_client0"] + app = mcapp.targets[0].projectId.split(":") + app1id = app[1] + ":" + mcapp.targets[0].appId + client.action(obj=mcapp, action_name="removeProjects", + projects=[project_id]) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + assert len(mcapp["targets"]) == 1, "did not delete target" + validate_app_deletion(project_client, app1id) + client.delete(mcapp) + + +def test_multi_cluster_role_change(): + assert_if_valid_cluster_count() + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + client = get_user_client() + original_role = ["project-member"] + answer_values = get_defaut_question_answers(client, GRAFANA_EXTERNALID) + mcapp = client.create_multiClusterApp( + templateVersionId=GRAFANA_TEMPLATE_VID, + targets=targets, + roles=original_role, + name=random_name(), + answers=[{"values": answer_values}]) + try: + mcapp = wait_for_mcapp_to_active(client, mcapp, 10) + except AssertionError: + print("expected failure as project member") + pass # expected fail + mcapp = client.update(mcapp, roles=["cluster-owner"]) + client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + client.delete(mcapp) + + +def test_multi_cluster_project_answer_override(): + assert_if_valid_cluster_count() + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + answers_override = { + "clusterId": None, + "projectId": project_detail["p0_id"], + "type": "/v3/schemas/answer", + "values": { + "mysqlUser": "test_override"} + } + mysql_override = [] + mysql_override.extend([{"values": answer_values}, answers_override]) + mcapp = client.update(mcapp, + roles=PROJECT_ROLE, + answers=mysql_override) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + projectId_answer_override = project_detail["p0_id"] + validate_answer_override(mcapp, + projectId_answer_override, + answers_override, + False) + client.delete(mcapp) + + +def test_multi_cluster_cluster_answer_override(): + assert_if_valid_cluster_count() + client = get_user_client() + cluster1 = project_detail["cluster1"] + p3, ns3 = create_project_and_ns( + USER_TOKEN, cluster1, random_test_name("mcapp-3")) + p_client2 = get_project_client_for_token(p3, USER_TOKEN) + project_detail["c2_id"] = cluster1.id + project_detail["namespace2"] = ns3 + project_detail["p2_id"] = p3.id + project_detail["p_client2"] = p_client2 + project_detail["cluster2"] = cluster1 + project_detail["project2"] = p3 + project[p3.id] = project_detail + client = global_client["client"] + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + answers_override_cluster = { + "clusterId": project_detail["c0_id"], + "projectId": None, + "type": "/v3/schemas/answer", + "values": { + "mysqlUser": "test_override"} + } + mysql_override_cluster = [] + mysql_override_cluster.extend([{"values": answer_values}, + answers_override_cluster]) + clusterId_answer_override = project_detail["c0_id"] + mcapp = client.update(mcapp, + roles=PROJECT_ROLE, + answers=mysql_override_cluster) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + validate_answer_override(mcapp, + clusterId_answer_override, + answers_override_cluster) + client.delete(mcapp) + + +def test_multi_cluster_all_answer_override(): + assert_if_valid_cluster_count() + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}]) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + new_answers = {"values": answer_values} + new_answers["values"]["mysqlUser"] = "root" + mcapp = client.update(mcapp, + roles=PROJECT_ROLE, + answers=[new_answers]) + mcapp = client.reload(mcapp) + mcapp = wait_for_mcapp_to_active(client, mcapp) + validate_multi_cluster_app_cluster(mcapp) + validate_all_answer_override_mca(mcapp) + client.delete(mcapp) + + +@skip_test_rolling_update +def test_multi_cluster_rolling_upgrade(): + assert_if_valid_cluster_count() + targets = [] + for projectid in project: + targets.append({"projectId": projectid, "type": "target"}) + client = get_user_client() + answer_values = get_defaut_question_answers(client, MYSQL_EXTERNALID_131) + mcapp = client.create_multiClusterApp( + templateVersionId=MYSQL_TEMPLATE_VID_131, + targets=targets, + roles=PROJECT_ROLE, + name=random_name(), + answers=[{"values": answer_values}], + upgradeStrategy=ROLLING_UPGRADE_STRATEGY) + mcapp = wait_for_mcapp_to_active(client, mcapp) + new_answers = {"values": answer_values} + new_answers["values"]["mysqlUser"] = "admin1234" + mcapp = client.update(mcapp, + roles=["cluster-owner"], + answers=[new_answers]) + mcapp = client.reload(mcapp) + app_info = {"p_client": None, "app_id": None} + app_info_2 = {"p_client": None, "app_id": None} + start = time.time() + end = time.time() + time.sleep(5) + app_state = [] + for i in range(0, len(mcapp.targets)): + app_id = mcapp.targets[i].appId + assert app_id is not None, "app_id is None" + project_client = project_detail["p_client" + str(i)] + app_detail = project_client.list_app(id=app_id).data[0] + app_state.append(app_detail.state) + if app_detail.state == "active": + app_info["p_client"] = project_client + app_info["app_id"] = app_id + else: + app_info_2["p_client"] = project_client + app_info_2["app_id"] = app_id + assert app_state.count("active") == 1, "Only one app should be upgrading" + print("app_state: ", app_state) + # check interval time is 20 seconds + while True: + app = app_info["p_client"].list_app(id=app_info["app_id"]).data[0] + app2 = app_info_2["p_client"].list_app(id=app_info_2["app_id"]).data[0] + if app2.state == "active": + start_1 = time.time() + if app.state != "active": + end = time.time() + break + print("Start: ", start) + print("Start_1: ", start_1) + print("End: ", end) + print(end - start) + print(end - start_1) + validate_multi_cluster_app_cluster(mcapp) + client.delete(mcapp) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + node_roles = [["controlplane", "etcd", "worker"], + ["worker"], ["worker"]] + cluster_list = [] + cluster, aws_nodes = create_and_validate_custom_host(node_roles, True) + client, cluster_existing = get_user_client_and_cluster() + admin_client = get_admin_client() + cluster_list.append(cluster_existing) + cluster_list.append(cluster) + if len(cluster_list) > 1: + global_client["cluster_count"] = True + assert_if_valid_cluster_count() + p1, ns1 = create_project_and_ns( + USER_TOKEN, cluster_list[0], random_test_name("mcapp-1")) + p_client1 = get_project_client_for_token(p1, USER_TOKEN) + p2, ns2 = create_project_and_ns( + USER_TOKEN, cluster_list[1], random_test_name("mcapp-2")) + p_client2 = get_project_client_for_token(p2, USER_TOKEN) + project_detail["c0_id"] = cluster_list[0].id + project_detail["p0_id"] = p1.id + project_detail["namespace0"] = ns1 + project_detail["p_client0"] = p_client1 + project_detail["cluster0"] = cluster_list[0] + project_detail["project0"] = p1 + project[p1.id] = project_detail + project_detail["c1_id"] = cluster_list[1].id + project_detail["namespace1"] = ns2 + project_detail["p1_id"] = p2.id + project_detail["p_client1"] = p_client2 + project_detail["cluster1"] = cluster_list[1] + project_detail["project1"] = p2 + project[p2.id] = project_detail + global_client["client"] = client + catalog = admin_client.create_catalog( + name=CATALOG_NAME, + baseType="catalog", + branch=BRANCH, + kind="helm", + url=CATALOG_URL) + catalog = wait_for_catalog_active(admin_client, catalog) + + def fin(): + admin_client.delete(catalog) + admin_client.delete(p1) + admin_client.delete(p2) + admin_client.delete(project_detail["project2"]) + admin_client.delete(cluster) + if aws_nodes is not None: + delete_node(aws_nodes) + + request.addfinalizer(fin) + + +def assert_if_valid_cluster_count(): + assert global_client["cluster_count"], \ + "Setup Failure. Tests require at least 2 clusters" + + +def validate_multi_cluster_app_cluster_wordpress(multiclusterapp): + for i in range(0, len(multiclusterapp.targets)): + app_id = multiclusterapp.targets[i].appId + assert app_id is not None, "app_id is None" + project_client = project_detail["p_client"+str(i)] + wait_for_app_to_active(project_client, app_id) + validate_app_version(project_client, multiclusterapp, app_id) + validate_response_app_endpoint(project_client, app_id) + + +def validate_multi_cluster_app_cluster(multiclusterapp): + for i in range(0, len(multiclusterapp.targets)): + app_id = multiclusterapp.targets[i].appId + assert app_id is not None, "app_id is None" + project_client = project_detail["p_client"+str(i)] + wait_for_app_to_active(project_client, app_id) + validate_app_version(project_client, multiclusterapp, app_id) + + +def delete_multi_cluster_app(multiclusterapp, validation=False): + client = global_client["client"] + uuid = multiclusterapp.uuid + name = multiclusterapp.name + client.delete(multiclusterapp) + if validation: + mcapps = client.list_multiClusterApp(uuid=uuid, name=name).data + assert len(mcapps) == 0, "Multi Cluster App is not deleted" + for i in range(1, len(multiclusterapp.targets)): + app_id = multiclusterapp.targets[i].appId + assert app_id is not None, "app_id is None" + project_client = project_detail["p_client" + str(i)] + validate_app_deletion(project_client, app_id) + + +def validate_app_version(project_client, multiclusterapp, app_id): + temp_version = multiclusterapp.templateVersionId + app = temp_version.split(":")[1].split("-") + catalog_name = app[0] + "-" + app[1] + "-" + app[2] + mcapp_template_version = "catalog://?catalog=" + catalog_name + \ + "&template=" + app[3] + "&version=" + app[4] + app_template_version = \ + project_client.list_app(name=app_id).data[0].externalId + assert mcapp_template_version == app_template_version, \ + "App Id is different from the Multi cluster app id" + + +def return_application_status_and_upgrade(client1, app_id1, client2, app_id2): + app_data1 = client1.list_app(id=app_id1).data + application1 = app_data1[0] + app_data2 = client2.list_app(id=app_id2).data + application2 = app_data2[0] + a = application1.state == "active" \ + and application1.answers["mysqlUser"] == "admin1234" + b = application2.state == "active" \ + and application2.answers["mysqlUser"] == "admin1234" + return a is True and b is not True + + +def validate_app_upgrade_mca(multiclusterapp): + for i in range(0, len(multiclusterapp.targets)): + project_client = project_detail["p_client" + str(i)] + app = multiclusterapp.targets[0].projectId.split(":") + appid = app[1] + ":" + multiclusterapp.targets[i].appId + temp_version = multiclusterapp.templateVersionId + app = temp_version.split(":")[1].split("-") + mcapp_template_version = "catalog://?catalog=" + app[0] + \ + "&template=" + app[1] + "&version=" \ + + app[2] + app_template_version = \ + project_client.list_app(id=appid).data[0].externalId + assert mcapp_template_version == app_template_version, \ + "App Id is different from the Multi cluster app id" + + +def validate_deletion_mca(multiclusterapp): + for i in range(0, len(multiclusterapp.targets)): + app_id = multiclusterapp.targets[i].appId + assert app_id is not None, "app_id is None" + project_client = project_detail["p_client"+str(i)] + app = multiclusterapp.targets[i].projectId.split(":") + app1id = app[1] + ":" + multiclusterapp.targets[i].appId + validate_app_deletion(project_client, app1id) + + +def validate_all_answer_override_mca(multiclusterapp): + for i in range(0, len(multiclusterapp.targets)): + project_client = project_detail["p_client" + str(i)] + app = multiclusterapp.targets[0].projectId.split(":") + appid = app[1] + ":" + multiclusterapp.targets[i].appId + hold = multiclusterapp['answers'][0] + val = hold["values"] + app_answers = \ + project_client.list_app(id=appid).data[0].answers + assert str(val) == str(app_answers), \ + "App answers are different than the Multi cluster answers" + + +def validate_answer_override(multiclusterapp, id, + answers_override, cluster=True): + for i in range(0, len(multiclusterapp.targets)): + project_client = project_detail["p_client"+str(i)] + app_id = multiclusterapp.targets[i].appId + target_project_id = multiclusterapp.targets[i].projectId + target_clusterId = target_project_id.split(":")[0] + app_answers = project_client.list_app(id=app_id).data[0].answers + if not cluster: + if target_project_id == id: + assert answers_override["values"]["mysqlUser"] == \ + app_answers.get("mysqlUser"), \ + "Answers are not available on the expected project" + else: + assert app_answers.get("mysqlUser") == "admin", \ + "answers should not have changed" + else: + if target_clusterId == id: + assert answers_override["values"]["mysqlUser"] == \ + app_answers.get("mysqlUser"), \ + "Answers are not available on the expected project" + else: + assert app_answers.get("mysqlUser") == "admin", \ + "answers should not have changed" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_network_policy.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_network_policy.py new file mode 100644 index 0000000..9c1a0da --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_network_policy.py @@ -0,0 +1,86 @@ +import pytest + +from .common import * # NOQA + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} +random_password = random_test_name("pass") + +PROJECT_ISOLATION = os.environ.get('RANCHER_PROJECT_ISOLATION', "disabled") + + +def test_connectivity_between_pods(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + + con = [{"name": "test1", + "image": TEST_IMAGE, + }] + name = random_test_name("default") + schedulable_node_count = len(get_schedulable_nodes(cluster)) + + # Check connectivity between pods in the same namespace + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + validate_workload(p_client, workload, "daemonSet", ns.name, + schedulable_node_count) + check_connectivity_between_workload_pods(p_client, workload) + + # Create another namespace in the same project + # Deploy workloads in this namespace + # Check that pods belonging to different namespace within the + # same project can communicate + + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + ns1 = create_ns(c_client, cluster, namespace["project"]) + workload1 = p_client.create_workload(name=name, + containers=con, + namespaceId=ns1.id, + daemonSetConfig={}) + validate_workload(p_client, workload1, "daemonSet", ns1.name, + schedulable_node_count) + check_connectivity_between_workload_pods(p_client, workload1) + check_connectivity_between_workloads(p_client, workload, p_client, + workload1) + + # Create new project in the same cluster + # Create namespace and deploy workloads + # Check communication between pods belonging to different namespace across + # different projects + + p2, ns2 = create_project_and_ns(USER_TOKEN, cluster) + p2_client = get_project_client_for_token(p2, USER_TOKEN) + + workload2 = p2_client.create_workload(name=name, + containers=con, + namespaceId=ns2.id, + daemonSetConfig={}) + validate_workload(p2_client, workload2, "daemonSet", ns2.name, + schedulable_node_count) + check_connectivity_between_workload_pods(p2_client, workload2) + allow_connectivity = True + if PROJECT_ISOLATION == "enabled": + allow_connectivity = False + check_connectivity_between_workloads( + p_client, workload, p2_client, workload2, + allow_connectivity=allow_connectivity) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testnp") + p_client = get_project_client_for_token(p, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_nfs.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_nfs.py new file mode 100644 index 0000000..ba36544 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_nfs.py @@ -0,0 +1,182 @@ +import pytest +from .common import * # NOQA + +namespace = {"p_client": None, + "ns": None, + "cluster": None, + "project": None, + "pv": None, + "pvc": None} + +# this is the path to the mounted dir in the NFS server +NFS_SERVER_MOUNT_PATH = "/nfs" +# this is the path to the mounted dir in the pod(workload) +MOUNT_PATH = "/var/nfs" +# if True then delete the NFS after finishing tests, otherwise False +DELETE_NFS = eval(os.environ.get('RANCHER_DELETE_NFS', "True")) + + +def test_nfs_wl_deployment(): + p_client = namespace["p_client"] + ns = namespace["ns"] + pvc_name = namespace["pvc"].name + wl_name = sub_path = random_test_name("deployment") + content = "from-test-wl-deployment" + file_path = MOUNT_PATH + "/wl-deployment.txt" + + # deploy the first workload + wl = create_wl_with_nfs(p_client, ns.id, pvc_name, wl_name, + mount_path=MOUNT_PATH, sub_path=sub_path) + validate_workload(p_client, wl, "deployment", ns.name) + + # check if it can write data + pods = p_client.list_pod(workloadId=wl.id).data + assert len(pods) == 1 + pod = pods[0] + write_content_to_file(pod, content, file_path) + validate_file_content(pod, content, file_path) + # delete the workload + p_client.delete(wl) + + # deploy second workload for testing + wl2 = create_wl_with_nfs(p_client, ns.id, pvc_name, "deployment-wl2", + mount_path=MOUNT_PATH, sub_path=sub_path) + validate_workload(p_client, wl2, "deployment", ns.name) + # check if it can read existing data + pods.clear() + pods = p_client.list_pod(workloadId=wl2.id).data + assert len(pods) == 1 + pod = pods[0] + validate_file_content(pod, content, file_path) + + +def test_nfs_wl_scale_up(): + p_client = namespace["p_client"] + ns = namespace["ns"] + pvc_name = namespace["pvc"].name + wl_name = sub_path = random_test_name("scale-up") + content = "from-nfs-wl-scale-up" + file_path = MOUNT_PATH + "/wl-scale-up.txt" + # deploy the workload + wl = create_wl_with_nfs(p_client, ns.id, pvc_name, wl_name, + mount_path=MOUNT_PATH, sub_path=sub_path) + validate_workload(p_client, wl, "deployment", ns.name) + + # write some data + pods = p_client.list_pod(workloadId=wl.id).data + assert len(pods) == 1 + pod = pods[0] + write_content_to_file(pod, content, file_path) + validate_file_content(pod, content, file_path) + + # scale up the workload + p_client.update(wl, scale=2) + wl = wait_for_wl_to_active(p_client, wl) + pods.clear() + pods = wait_for_pods_in_workload(p_client, wl, 2) + assert len(pods) == 2 + for pod in pods: + validate_file_content(pod, content, file_path) + + +def test_nfs_wl_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + pvc_name = namespace["pvc"].name + wl_name = sub_path = random_test_name("upgrade") + content = "from-nfs-wl-upgrade" + file_path = MOUNT_PATH + "/wl-upgrade.txt" + # deploy the workload + wl = create_wl_with_nfs(p_client, ns.id, pvc_name, wl_name, + mount_path=MOUNT_PATH, sub_path=sub_path) + validate_workload(p_client, wl, "deployment", ns.name) + + pods = p_client.list_pod(workloadId=wl.id).data + assert len(pods) == 1 + pod = pods[0] + # write some data + write_content_to_file(pod, content, file_path) + validate_file_content(pod, content, file_path) + + # upgrade the workload + con = [{"name": "test1", + "image": TEST_IMAGE, + "volumeMounts": [{"readOnly": "False", + "type": "volumeMount", + "mountPath": "/var/nfs", + "subPath": sub_path, + "name": "vol1" + }], + "env": {"REASON": "upgrade"} + }] + p_client.update(wl, containers=con) + wl = wait_for_wl_to_active(p_client, wl) + # check if it can read existing data + pods.clear() + pods = wait_for_pods_in_workload(p_client, wl, 1) + assert len(pods) == 1 + pod = pods[0] + validate_file_content(pod, content, file_path) + + # check if it can write some data + content = content + "+after-upgrade" + write_content_to_file(pod, content, file_path) + validate_file_content(pod, content, file_path) + + +def test_nfs_wl_daemonSet(): + p_client = namespace["p_client"] + cluster = namespace["cluster"] + ns = namespace["ns"] + pvc_name = namespace["pvc"].name + wl_name = sub_path = random_test_name("daemon-set") + content = "from-nfs-wl-daemon-set" + file_path = MOUNT_PATH + "/" + "/wl-daemon-set.txt" + + # deploy the workload + wl = create_wl_with_nfs(p_client, ns.id, pvc_name, wl_name, + MOUNT_PATH, sub_path, is_daemonSet=True) + schedulable_node_count = len(get_schedulable_nodes(cluster)) + validate_workload(p_client, wl, "daemonSet", + ns.name, schedulable_node_count) + + # for each pod, write some data to the file, + # then check if changes can be seen in all pods + pods = p_client.list_pod(workloadId=wl.id).data + for pod in pods: + content = content + "+" + pod.name + write_content_to_file(pod, content, file_path) + for item in pods: + validate_file_content(item, content, file_path) + + +@pytest.fixture(scope="module", autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "project-test-nfs") + p_client = get_project_client_for_token(p, USER_TOKEN) + nfs_node = provision_nfs_server() + nfs_ip = nfs_node.get_public_ip() + print("the IP of the NFS: ", nfs_ip) + + # add persistent volume to the cluster + cluster_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + pv_object, pvc_object = create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["pv"] = pv_object + namespace["pvc"] = pvc_object + + def fin(): + cluster_client = get_cluster_client_for_token(namespace["cluster"], + USER_TOKEN) + cluster_client.delete(namespace["project"]) + cluster_client.delete(namespace["pv"]) + if DELETE_NFS is True: + AmazonWebServices().delete_node(nfs_node) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_annotation.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_annotation.py new file mode 100644 index 0000000..3437c6e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_annotation.py @@ -0,0 +1,828 @@ +import pytest +import time +from .common import create_kubeconfig +from .common import CLUSTER_MEMBER +from .common import CLUSTER_OWNER +from .common import PROJECT_MEMBER +from .common import PROJECT_OWNER +from .common import PROJECT_READ_ONLY +from .common import get_client_for_token +from .common import get_node_details +from .common import get_user_client_and_cluster +from .common import execute_kubectl_cmd +from .common import if_test_rbac +from .common import random_name +from .common import rbac_get_user_token_by_role +from rancher import ApiError + +cluster_detail = {"cluster": None, "client": None} +roles = [CLUSTER_MEMBER, CLUSTER_OWNER, PROJECT_OWNER, PROJECT_MEMBER, + PROJECT_READ_ONLY] + + +def test_node_annotation_add(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation through API + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # delete annotation + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_add_multiple(): + annotation_key_1 = random_name() + annotation_value_1 = random_name() + annotation_key_2 = random_name() + annotation_value_2 = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation through API + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key_1] = annotation_value_1 + node_annotations[annotation_key_2] = annotation_value_2 + client.update(node, annotations=node_annotations) + time.sleep(2) + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key_1, + annotation_value_1) + validate_annotation_set_on_node(client, node, + annotation_key_2, + annotation_value_2) + + # delete annotation + del node_annotations[annotation_key_1] + del node_annotations[annotation_key_2] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_edit(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation through API + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # edit annotation through API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + new_value = random_name() + node_annotations[annotation_key] = new_value + client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + validate_annotation_set_on_node(client, node, + annotation_key, + new_value) + + # delete annotation + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_delete(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation on node + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # delete annotation + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be deleted + validate_annotation_deleted_on_node(client, node, annotation_key) + + +def test_node_annotation_delete_multiple(): + annotation_key_1 = random_name() + annotation_value_1 = random_name() + annotation_key_2 = random_name() + annotation_value_2 = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation on node + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key_1] = annotation_value_1 + node_annotations[annotation_key_2] = annotation_value_2 + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key_1, + annotation_value_1) + validate_annotation_set_on_node(client, node, + annotation_key_2, + annotation_value_2) + + # delete annotation + del node_annotations[annotation_key_1] + del node_annotations[annotation_key_2] + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be deleted + validate_annotation_deleted_on_node(client, node, annotation_key_1) + validate_annotation_deleted_on_node(client, node, annotation_key_2) + + +def test_node_annotation_kubectl_add(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # remove annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_kubectl_edit(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # edit annotation through kubectl + new_value = random_name() + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + new_value + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + node = client.reload(node) + time.sleep(2) + + # New annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value=new_value) + + # remove annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_kubectl_delete(): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # remove annotation through kubectl + command = "annotate node " + node_name + " " + annotation_key + "-" + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotationv should be deleted + validate_annotation_deleted_on_node(client, node, annotation_key) + + +def test_node_annotation_k_add_a_delete_k_add(): + """Add via kubectl, Delete via API, Add via kubectl""" + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # delete annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be deleted + validate_annotation_deleted_on_node(client, node, annotation_key) + + # Add annotation via kubectl + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # clean up annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_k_add_a_edit_k_edit(): + """Add via kubectl, edit via API, edit via kubectl""" + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # edit annotation through API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + new_value = random_name() + node_annotations[annotation_key] = new_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + new_value) + + # edit annotation through kubectl + new_value_2 = random_name() + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + new_value_2 + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # New annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + new_value_2) + + # remove annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotations_a_add_k_delete_a_add(): + """Add via API, Delete via kubectl, Add via API""" + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # delete annotation + command = " annotate node " + node_name + " " + annotation_key + "-" + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be deleted + node = client.reload(node) + validate_annotation_deleted_on_node(client, node, annotation_key) + + # Add annotation via API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # clean up annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +def test_node_annotation_a_add_k_edit_a_edit(): + """Add via API, Edit via kubectl, Edit via API""" + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # edit annotation through kubectl + new_value = random_name() + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + new_value + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + node = client.reload(node) + time.sleep(2) + + # New annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value=new_value) + + # edit annotation through API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + new_value_2 = random_name() + node_annotations[annotation_key] = new_value_2 + client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + new_value_2) + + # clean up annotation + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_add(role): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_annotations = node.annotations.data_dict() + + # get user token and client + token = rbac_get_user_token_by_role(role) + print("token: ", token) + user_client = get_client_for_token(token) + + node_annotations[annotation_key] = annotation_value + + if role == CLUSTER_OWNER: + user_client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(user_client, node, + annotation_key, + annotation_value) + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + else: + with pytest.raises(ApiError) as e: + user_client.update(node, annotations=node_annotations) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_delete(role): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation on node + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # delete annotation + del node_annotations[annotation_key] + + # get user token and client + token = rbac_get_user_token_by_role(role) + print("token: ", token) + user_client = get_client_for_token(token) + + if role == CLUSTER_OWNER: + user_client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_deleted_on_node(user_client, node, annotation_key) + else: + with pytest.raises(ApiError) as e: + user_client.update(node, annotations=node_annotations) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + if role != CLUSTER_OWNER: + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_edit(role): + annotation_key = random_name() + annotation_value = random_name() + annotation_value_new = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add annotation on node + node_annotations = node.annotations.data_dict() + node_annotations[annotation_key] = annotation_value + client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value) + + # edit annotation + node_annotations[annotation_key] = annotation_value_new + + # get user token and client + token = rbac_get_user_token_by_role(role) + print("token: ", token) + user_client = get_client_for_token(token) + + if role == CLUSTER_OWNER: + user_client.update(node, annotations=node_annotations) + node = client.reload(node) + time.sleep(2) + + # annotation should be added + validate_annotation_set_on_node(user_client, node, + annotation_key, + annotation_value_new) + else: + with pytest.raises(ApiError) as e: + user_client.update(node, annotations=node_annotations) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + delete_node_annotation(annotation_key, node, client) + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_add_kubectl(role): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # get user token and client + token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(token) + print(cluster_detail["cluster"]["id"]) + print(cluster_detail["cluster"]) + cluster = user_client.list_cluster(id=cluster_detail["cluster"]["id"]).data + print(cluster) + create_kubeconfig(cluster[0]) + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + + if role == CLUSTER_OWNER: + execute_kubectl_cmd(command, False) + node = client.reload(node) + time.sleep(2) + # annotation should be added + validate_annotation_set_on_node(user_client, node, + annotation_key, + annotation_value) + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + elif role == CLUSTER_MEMBER or role == PROJECT_OWNER: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot patch resource \"nodes\"" in result + assert "forbidden" in result + else: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot get resource \"nodes\"" in result + assert "forbidden" in result + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_delete_kubectl(role): + annotation_key = random_name() + annotation_value = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + + # get user token and client + token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(token) + print(cluster_detail["cluster"]["id"]) + print(cluster_detail["cluster"]) + cluster = user_client.list_cluster(id=cluster_detail["cluster"]["id"]).data + print(cluster) + create_kubeconfig(cluster[0]) + + # remove annotation through kubectl + command = "annotate node " + node_name + " " + annotation_key + "-" + + if role == CLUSTER_OWNER: + execute_kubectl_cmd(command, False) + time.sleep(2) + # annotation should be deleted + validate_annotation_deleted_on_node(user_client, node, annotation_key) + elif role == CLUSTER_MEMBER or role == PROJECT_OWNER: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot patch resource \"nodes\"" in result + assert "forbidden" in result + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + else: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot get resource \"nodes\"" in result + assert "forbidden" in result + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_annotation_edit_kubectl(role): + annotation_key = random_name() + annotation_value = random_name() + annotation_value_new = random_name() + # get node details + client, node = \ + get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add annotation on node + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # annotation should be added + node = client.reload(node) + + # get user token and client + token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(token) + print(cluster_detail["cluster"]["id"]) + print(cluster_detail["cluster"]) + cluster = user_client.list_cluster(id=cluster_detail["cluster"]["id"]).data + print(cluster) + create_kubeconfig(cluster[0]) + + # edit annotation through kubectl + command = "annotate nodes " + node_name + " " + \ + annotation_key + "=" + annotation_value_new + " --overwrite" + + if role == CLUSTER_OWNER: + execute_kubectl_cmd(command, False) + time.sleep(2) + # annotation should be deleted + validate_annotation_set_on_node(user_client, node, + annotation_key, + annotation_value_new) + elif role == CLUSTER_MEMBER or role == PROJECT_OWNER: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot patch resource \"nodes\"" in result + assert "forbidden" in result + # cleanup annotation + else: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot get resource \"nodes\"" in result + assert "forbidden" in result + # cleanup annotation + delete_node_annotation(annotation_key, node, client) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + cluster_detail["client"], cluster_detail["cluster"] = \ + get_user_client_and_cluster() + + +def validate_annotation_set_on_node(client, node, + annotation_key, + annotation_value): + """ + This method checks if the annotation is + added on the node via API and kubectl + :param client: user client + :param node: node on which user has to validate if the annotation is added + :param annotation_key: annotation to be validated on the node + :param annotation_value: annotaton value to be checked + :return: None + """ + print("annotaton_value: ", annotation_value) + # check via API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + assert node_annotations[annotation_key] == annotation_value + + # check via kubectl + node_name = node.nodeName + command = " get nodes " + node_name + node_detail = execute_kubectl_cmd(command) + print(node_detail["metadata"]["annotations"]) + assert annotation_key in node_detail["metadata"]["annotations"], \ + "Annotation is not set in kubectl" + assert node_detail["metadata"]["annotations"][annotation_key] \ + == annotation_value + + +def validate_annotation_deleted_on_node(client, node, annotation_key): + """ + This method checks if the annotation is deleted + on the node via API and kubectl + :param client: user client + :param node: node on which user has to validate if the + annotation is deleted + :param annotation_key: annotation to be validated on the node + :return: None + """ + # check via API + node = client.reload(node) + node_annotations = node.annotations.data_dict() + assert annotation_key not in node_annotations + + # check via kubectl + node_name = node.nodeName + command = " get nodes " + node_name + print(command) + node_detail = execute_kubectl_cmd(command) + print(node_detail["metadata"]["annotations"]) + assert annotation_key not in node_detail["metadata"]["annotations"] + + +def delete_node_annotation(annotation_key, node, client): + """ + + :param annotation_key: annotation to be deleted on the node + :param node: node in cluster + :param client: client + :return: + """ + node = client.reload(node) + node_annotations = node.annotations.data_dict() + del node_annotations[annotation_key] + client.update(node, annotations=node_annotations) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_label.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_label.py new file mode 100644 index 0000000..fe8c363 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_label.py @@ -0,0 +1,1214 @@ +import pytest +import time +from .common import create_kubeconfig +from .common import CLUSTER_MEMBER +from .common import CLUSTER_OWNER +from .common import PROJECT_MEMBER +from .common import PROJECT_OWNER +from .common import PROJECT_READ_ONLY +from .common import get_client_for_token +from .common import delete_node +from .common import get_node_details +from .common import get_user_client +from .common import get_user_client_and_cluster +from .common import execute_kubectl_cmd +from .common import if_test_rbac +from .common import LINODE_ACCESSKEY +from .common import RANCHER_CLEANUP_CLUSTER +from .common import random_name +from .common import random_test_name +from .common import rbac_get_user_token_by_role +from .common import validate_cluster_state +from .common import wait_for_condition +from .conftest import wait_for_cluster_delete +from rancher import ApiError +from .test_rke_cluster_provisioning import evaluate_clustername +from .test_rke_cluster_provisioning import get_custom_host_registration_cmd +from .test_rke_cluster_provisioning import HOST_NAME +from .test_rke_cluster_provisioning import random_node_name +from .test_rke_cluster_provisioning import rke_config +from .test_rke_cluster_provisioning import wait_for_cluster_node_count +from lib.aws import AmazonWebServices + +cluster_detail = {"cluster": None, "client": None} +cluster_node_template = {"cluster": None, "node_pools": None, + "node_template": None, "linode_cloud_credential": None, + "label_value": None, "test_label": None} +cluster_custom = {"cluster": None, "test_label": None, + "label_value": None, "aws_node": None} +custom_cluster_add_edit = {"cluster": None, "aws_node": []} +cluster_node_template_2 = {"cluster": [], "node_template": []} +roles = [CLUSTER_MEMBER, CLUSTER_OWNER, PROJECT_OWNER, PROJECT_MEMBER, + PROJECT_READ_ONLY] +engine_install_url = "https://releases.rancher.com/install-docker/26.1.sh" + + +def test_node_label_add(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add label through API + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # delete label + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_edit(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add label through API + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # edit label through API + node = client.reload(node) + node_labels = node.labels.data_dict() + new_value = random_name() + node_labels[test_label] = new_value + client.update(node, labels=node_labels) + node = client.reload(node) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, new_value) + + # delete label + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_delete(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + + # add labels on node + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # delete label + del node_labels[test_label] + client.update(node, labels=node_labels) + time.sleep(2) + + # label should be deleted + wait_for_condition(client, node, check_label_removed(test_label), None, 10) + validate_label_deleted_on_node(client, node, test_label) + + +def test_node_label_kubectl_add(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add label on node + command = "label nodes " + node_name + " " + test_label + "=" + label_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # remove label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_kubectl_edit(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add label on node + command = "label nodes " + node_name + " " + test_label + "=" + label_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # edit label through kubectl + new_value = random_name() + command = "label nodes " + node_name + " " + \ + test_label + "=" + new_value + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + node = client.reload(node) + time.sleep(2) + + # New Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value=new_value) + + # remove label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_kubectl_delete(): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # add label on node + command = "label nodes " + node_name + " " + test_label + "=" + label_value + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # remove label through kubectl + command = " label node " + node_name + " " + test_label + "-" + execute_kubectl_cmd(command, False) + time.sleep(2) + + # label should be deleted + wait_for_condition(client, node, check_label_removed(test_label), None, 10) + validate_label_deleted_on_node(client, node, test_label) + + +def test_node_label_k_add_a_delete_k_add(): + """Add via kubectl, Delete via API, Add via kubectl""" + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + command = "label nodes " + node_name + " " + test_label + "=" + label_value + print(command) + execute_kubectl_cmd(command, False) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # delete label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + # label should be deleted + wait_for_condition(client, node, check_label_removed(test_label), None, 10) + validate_label_deleted_on_node(client, node, test_label) + + # Add label via kubectl + execute_kubectl_cmd(command, False) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # clean up label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_k_add_a_edit_k_edit(): + """Add via kubectl, edit via API, edit via kubectl""" + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + command = "label nodes " + node_name + " " + test_label + "=" + label_value + execute_kubectl_cmd(command, False) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # edit label through API + node = client.reload(node) + node_labels = node.labels.data_dict() + new_value = random_name() + node_labels[test_label] = new_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, new_value) + + # edit label through kubectl + new_value_2 = random_name() + command = "label nodes " + node_name + " " + \ + test_label + "=" + new_value_2 + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + time.sleep(2) + + # New Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, new_value_2) + + # remove label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_a_add_k_delete_a_add(): + """Add via API, Delete via kubectl, Add via API""" + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # delete label + command = " label node " + node_name + " " + test_label + "-" + execute_kubectl_cmd(command, False) + time.sleep(2) + + # label should be deleted + node = client.reload(node) + wait_for_condition(client, node, check_label_removed(test_label), None, 10) + validate_label_deleted_on_node(client, node, test_label) + + # Add label via API + node = client.reload(node) + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # clean up label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_a_add_k_edit_a_edit(): + """Add via API, Edit via kubectl, Edit via API""" + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + node_labels = node.labels.data_dict() + node_labels[test_label] = label_value + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + node = client.reload(node) + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value) + + # edit label through kubectl + new_value = random_name() + command = "label nodes " + node_name + " " + \ + test_label + "=" + new_value + " --overwrite" + print(command) + execute_kubectl_cmd(command, False) + node = client.reload(node) + time.sleep(2) + + # New Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, label_value=new_value) + + # edit label through API + node = client.reload(node) + node_labels = node.labels.data_dict() + new_value_2 = random_name() + node_labels[test_label] = new_value_2 + client.update(node, labels=node_labels) + node = client.reload(node) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, new_value_2) + + # clean up label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + + +def test_node_label_custom_add_edit_addnode(): + """ Create a custom cluster, Add node labels via register command + Edit via API and change the existing label value ONLY + Add a control plane node with label same as the ORIGINAL one + And check the labels on all the nodes.""" + test_label = random_name() + label_value = random_name() + cluster_custom["test_label"] = test_label + cluster_custom["label_value"] = label_value + client = cluster_detail["client"] + node_roles = [["worker", "controlplane", "etcd"]] + aws_nodes_list = [] + cluster, aws_nodes = \ + create_custom_node_label(node_roles, test_label, label_value, True) + create_kubeconfig(cluster) + for node in aws_nodes: + aws_nodes_list.append(node) + + nodes = client.list_node(clusterId=cluster.id).data + node = nodes[0] + + validate_label_set_on_node(client, node, test_label, label_value) + + node_name_1 = node.nodeName + # edit label through API + node = client.reload(node) + node_labels = node.labels.data_dict() + new_value_2 = random_name() + node_labels[test_label] = new_value_2 + client.update(node, labels=node_labels) + # cluster will go into updating state + cluster = validate_cluster_state(client, cluster, True, + intermediate_state="updating", + nodes_not_in_active_state=[], + timeout=600) + + node = client.reload(node) + # Label should be added + validate_label_set_on_node(client, node, test_label, new_value_2) + + # add a control plane node with original label + aws_nodes = \ + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 1, random_test_name(HOST_NAME)) + for node in aws_nodes: + aws_nodes_list.append(node) + + aws_node = aws_nodes[0] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["controlplane"], + aws_node) + docker_run_cmd = \ + docker_run_cmd + " --label " + test_label + "=" + label_value + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 2) + cluster = validate_cluster_state(client, cluster, + intermediate_state="updating") + nodes = client.list_node(clusterId=cluster.id).data + # cluster cleanup + custom_cluster_add_edit["cluster"] = cluster + custom_cluster_add_edit["aws_node"] = aws_nodes_list + + for node in nodes: + if node.nodeName != node_name_1: + validate_label_set_on_node(client, node, test_label, label_value) + else: + validate_label_set_on_node(client, node, test_label, new_value_2) + + +def test_node_label_node_template_add(): + """ + This test validates label added through node template, + add label on node template, and validates the label + is available on the scaled up node + :return: None + """ + client = cluster_detail["client"] + cluster = cluster_node_template["cluster"] + create_kubeconfig(cluster) + nodes = client.list_node(clusterId=cluster.id).data + # get existing nodes info + existing_labels = {} + for node in nodes: + existing_labels[node.nodeName] = {} + existing_labels[node.nodeName] = node.labels.data_dict() + + test_label = random_name() + label_value = random_name() + # create a node template with a label + node_template_new, linode_cloud_credential = \ + create_node_template_label(client, test_label, label_value) + # Add a node in cluster + cluster, node_pools = add_node_cluster(node_template_new, cluster) + nodes = client.list_node(clusterId=cluster.id).data + + # validate labels on nodes + for node in nodes: + if node.nodeName not in existing_labels.keys(): + # check if label is set on node + validate_label_set_on_node(client, node, test_label, label_value) + else: + # check if the labels on the existing nodes are intact + assert existing_labels[node.nodeName] == node.labels.data_dict(), \ + "Labels on existing nodes have changed" + + +@pytest.mark.run(after='test_node_label_node_template_add') +def test_node_label_node_template_edit(): + """ + This test validates label added through node template, + edit label on node template, and validates new label + is available on the scaled up node + :param remove_resource: to delete the resource + :return: + """ + client = cluster_detail["client"] + cluster = cluster_node_template["cluster"] + node_template = cluster_node_template["node_template"] + linode_cloud_credential = cluster_node_template["linode_cloud_credential"] + test_label = cluster_node_template["test_label"] + create_kubeconfig(cluster) + nodes = client.list_node(clusterId=cluster.id).data + + existing_labels = {} + for node in nodes: + existing_labels[node.nodeName] = {} + existing_labels[node.nodeName] = node.labels.data_dict() + + template_label = node_template.labels.data_dict() + assert test_label in template_label, \ + "Label is NOT available on the node template" + + new_value = random_name() + template_label[test_label] = new_value + node_template_new = client.update(node_template, labels=template_label, + cloudCredentialId=linode_cloud_credential.id, + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-east", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}) + node_template_new = client.wait_success(node_template_new) + assert test_label in node_template_new["labels"], \ + "Label is not set on node template" + assert node_template_new["labels"][test_label] == new_value + + # Add a node in cluster + cluster, node_pools = add_node_cluster(node_template_new, cluster) + + nodes = client.list_node(clusterId=cluster.id).data + """check original label on the first node, + and the new label on the added node""" + + # validate labels on nodes + for node in nodes: + if node.nodeName not in existing_labels.keys(): + # check if label is set on node + validate_label_set_on_node(client, node, test_label, new_value) + else: + # check if the labels on the existing nodes are intact + assert existing_labels[node.nodeName] == node.labels.data_dict(), \ + "Labels on existing nodes have changed" + + +@pytest.mark.run(after='test_node_label_node_template_edit') +def test_node_label_node_template_delete(): + """ + This test validates label added through node template, + delete label on node template, and validates the label + is NOT available on the scaled up node + :return: None + """ + client = cluster_detail["client"] + cluster = cluster_node_template["cluster"] + node_template = cluster_node_template["node_template"] + linode_cloud_credential = cluster_node_template["linode_cloud_credential"] + test_label = cluster_node_template["test_label"] + create_kubeconfig(cluster_node_template["cluster"]) + + nodes = client.list_node(clusterId=cluster.id).data + + existing_labels = {} + for node in nodes: + existing_labels[node.nodeName] = {} + existing_labels[node.nodeName] = node.labels.data_dict() + + # delete label in node template + template_label = node_template.labels.data_dict() + del template_label[test_label] + + # update node template + node_template_new = client.update(node_template, labels=template_label, + cloudCredentialId=linode_cloud_credential.id, + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-east", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}) + node_template_new = client.wait_success(node_template_new) + assert test_label not in node_template_new["labels"], \ + "Label is available on the node template" + + # Add a node in cluster with new node template + cluster, node_pools = add_node_cluster(node_template_new, cluster) + + nodes = client.list_node(clusterId=cluster.id).data + + # validate labels on nodes + for node in nodes: + if node.nodeName not in existing_labels.keys(): + node_labels = node.labels.data_dict() + assert test_label not in node_labels, \ + "Label is NOT deleted on the node" + else: + # check if the labels on the existing nodes are intact + assert existing_labels[node.nodeName] == node.labels.data_dict(), \ + "Labels on existing nodes have changed" + + +def test_node_label_node_template_edit_api(): + """ + This test validates edit of label via API + which is added through node template + :return: None + """ + test_label = random_name() + label_value = random_name() + cluster, node_pools, node_template, linode_cloud_credential = \ + create_cluster_node_template_label(test_label, label_value) + client = get_user_client() + cluster_node_template_2["cluster"].append(cluster) + cluster_node_template_2["node_template"].append(node_template) + create_kubeconfig(cluster) + + node = client.list_node(clusterId=cluster.id).data + node_id = node[0].id + node = client.by_id_node(node_id) + # Edit label on node via API + node_labels = node.labels.data_dict() + assert node_labels[test_label] == label_value + + # edit label through API + new_value = random_name() + node_labels[test_label] = new_value + client.update(node, labels=node_labels) + node = client.reload(node) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, test_label, new_value) + + +def test_node_label_node_template_delete_api(): + """ + This test validates delete of label via API + which is added through node template + :return: None + Expected failure because of issue - + https://github.com/rancher/rancher/issues/26604 + """ + test_label = random_name() + label_value = random_name() + cluster, node_pools, node_template, linode_cloud_credential = \ + create_cluster_node_template_label(test_label, label_value) + client = get_user_client() + cluster_node_template_2["cluster"].append(cluster) + cluster_node_template_2["node_template"].append(node_template) + create_kubeconfig(cluster) + + node = client.list_node(clusterId=cluster.id).data + node_id = node[0].id + node = client.by_id_node(node_id) + node_labels = node.labels.data_dict() + assert node_labels[test_label] == label_value + + # delete label + del node_labels[test_label] + client.update(node, labels=node_labels) + # cluster will go into updating state + cluster = validate_cluster_state(client, cluster, True, + intermediate_state="updating", + nodes_not_in_active_state=[], + timeout=600) + + node = client.reload(node) + # label should be deleted + validate_label_deleted_on_node(client, node, test_label) + + +def test_node_label_custom_add(): + """ + This test validates the label on a custom node + added through the registration command + :return: + """ + test_label = random_name() + label_value = random_name() + cluster_custom["test_label"] = test_label + cluster_custom["label_value"] = label_value + client = cluster_detail["client"] + node_roles = [["worker", "controlplane", "etcd"]] + if cluster_custom["cluster"] is None: + cluster_custom["cluster"], aws_nodes = \ + create_custom_node_label(node_roles, test_label, label_value, True) + cluster = cluster_custom["cluster"] + cluster_custom["aws_node"] = aws_nodes + else: + cluster = cluster_custom["cluster"] + create_kubeconfig(cluster_custom["cluster"]) + nodes = client.list_node(clusterId=cluster.id).data + node = nodes[0] + + validate_label_set_on_node(client, node, test_label, label_value) + + +@pytest.mark.run(after='test_node_label_custom_add') +def test_node_label_custom_edit(): + """ + This test validates edit on the label on the node - + added through custom registration command + :return: None + """ + create_kubeconfig(cluster_custom["cluster"]) + client = cluster_detail["client"] + cluster = cluster_custom["cluster"] + test_label = cluster_custom["test_label"] + + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) > 0 + node_id = nodes[0].id + node = client.by_id_node(node_id) + + # edit label through API + node = client.reload(node) + node_labels = node.labels.data_dict() + new_value = random_name() + node_labels[test_label] = new_value + client.update(node, labels=node_labels) + # cluster will go into updating state + cluster = validate_cluster_state(client, cluster, True, + intermediate_state="updating", + nodes_not_in_active_state=[], + timeout=600) + node = client.reload(node) + validate_label_set_on_node(client, node, test_label, new_value) + cluster_custom["label_value"] = new_value + + +@pytest.mark.run(after='test_node_label_custom_edit') +def test_node_label_custom_add_additional(): + """ + This test validates addition of labels on the custom nodes + :return: None + """ + create_kubeconfig(cluster_custom["cluster"]) + client = cluster_detail["client"] + cluster = cluster_custom["cluster"] + test_label = cluster_custom["test_label"] + label_value = cluster_custom["label_value"] + new_label = random_name() + label_value_new = random_name() + + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) > 0 + node_id = nodes[0].id + node = client.by_id_node(node_id) + + node_labels = node.labels.data_dict() + node_labels[new_label] = label_value_new + client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + wait_for_condition(client, node, check_label_added(test_label), None, 10) + validate_label_set_on_node(client, node, new_label, label_value_new) + validate_label_set_on_node(client, node, test_label, label_value) + + # remove label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[new_label] + client.update(node, labels=node_labels) + + +@pytest.mark.run(after='test_node_label_custom_add_additional') +def test_node_label_custom_delete(): + """ + This test deletes the label on the node via API + :return: None + Expected failure because of issue - + https://github.com/rancher/rancher/issues/26604 + """ + create_kubeconfig(cluster_custom["cluster"]) + client = cluster_detail["client"] + cluster = cluster_custom["cluster"] + test_label = cluster_custom["test_label"] + + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) > 0 + node_id = nodes[0].id + node = client.by_id_node(node_id) + + # remove label + node = client.reload(node) + node_labels = node.labels.data_dict() + del node_labels[test_label] + client.update(node, labels=node_labels) + # cluster will go into updating state + cluster = validate_cluster_state(client, cluster, True, + intermediate_state="updating", + nodes_not_in_active_state=[], + timeout=600) + + node = client.reload(node) + # label should be deleted + validate_label_deleted_on_node(client, node, test_label) + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_label_add(role): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_labels = node.labels.data_dict() + + # get user token and client + token = rbac_get_user_token_by_role(role) + print("token: ", token) + user_client = get_client_for_token(token) + + node_labels[test_label] = label_value + + if role == CLUSTER_OWNER: + user_client.update(node, labels=node_labels) + time.sleep(2) + + # Label should be added + wait_for_condition(user_client, node, + check_label_added(test_label), None, 10) + validate_label_set_on_node(user_client, node, test_label, label_value) + else: + with pytest.raises(ApiError) as e: + user_client.update(node, labels=node_labels) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", roles) +def test_rbac_node_label_add_kubectl(role): + test_label = random_name() + label_value = random_name() + # get node details + client, node = get_node_details(cluster_detail["cluster"], cluster_detail["client"]) + node_name = node.nodeName + + # get user token and client + token = rbac_get_user_token_by_role(role) + user_client = get_client_for_token(token) + print(cluster_detail["cluster"]["id"]) + print(cluster_detail["cluster"]) + cluster = user_client.list_cluster(id=cluster_detail["cluster"]["id"]).data + print(cluster) + create_kubeconfig(cluster[0]) + + # add label on node + command = "label nodes " + node_name + " " + test_label + "=" + label_value + + if role == CLUSTER_OWNER: + execute_kubectl_cmd(command, False) + time.sleep(2) + # Label should be added + wait_for_condition(user_client, node, + check_label_added(test_label), None, 10) + validate_label_set_on_node(user_client, node, test_label, label_value) + elif role == CLUSTER_MEMBER: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot patch resource \"nodes\"" in result + assert "forbidden" in result + else: + result = execute_kubectl_cmd(command, False, stderr=True) + result = result.decode('ascii') + assert "cannot get resource \"nodes\"" in result + assert "forbidden" in result + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + cluster_detail["client"], cluster_detail["cluster"] = \ + get_user_client_and_cluster() + test_label = random_name() + label_value = random_name() + + """ + Create a cluster for node template related test cases + """ + cluster_node_template["cluster"], \ + node_pools, \ + cluster_node_template["node_template"], \ + cluster_node_template["linode_cloud_credential"] = \ + create_cluster_node_template_label(test_label, label_value) + cluster_node_template["node_pools"] = node_pools[0] + cluster_node_template["test_label"] = test_label + cluster_node_template["label_value"] = label_value + def fin(): + client = get_user_client() + cluster = cluster_node_template["cluster"] + if cluster is not None: + node_pools_list = client.list_nodePool(clusterId=cluster.id).data + # get unique node template ids + client.delete(cluster_node_template["cluster"]) + wait_for_cluster_delete(client, cluster["name"]) + time.sleep(10) + unique_node_pool = {} + for node_pool in node_pools_list: + if node_pool.nodeTemplateId not in unique_node_pool.keys(): + unique_node_pool[node_pool.nodeTemplateId] = \ + client.list_node_template( + id=node_pool.nodeTemplateId).data[0] + print("unique_node_pool: ", unique_node_pool) + for key, value in unique_node_pool.items(): + client.delete(value) + if cluster_custom["cluster"] is not None: + client.delete(cluster_custom["cluster"]) + if cluster_custom["aws_node"] is not None: + delete_node(cluster_custom["aws_node"]) + if custom_cluster_add_edit["cluster"] is not None: + client.delete(custom_cluster_add_edit["cluster"]) + if custom_cluster_add_edit["aws_node"] is not None: + delete_node(custom_cluster_add_edit["aws_node"]) + if len(cluster_node_template_2["cluster"]) != 0: + for cluster in cluster_node_template_2["cluster"]: + client.delete(cluster) + wait_for_cluster_delete(client, cluster.name) + time.sleep(10) + for node_template in cluster_node_template_2["node_template"]: + client.reload(node_template) + client.delete(node_template) + if RANCHER_CLEANUP_CLUSTER: + request.addfinalizer(fin) + + +def check_cluster_deleted(client): + def _find_condition(resource): + cluster = client.reload(resource) + if len(cluster["data"]) == 0: + return True + else: + return False + + return _find_condition + + +def check_label_added(test_label): + def _find_condition(resource): + node_labels = resource.labels.data_dict() + + if test_label in node_labels: + return True + else: + return False + + return _find_condition + + +def check_label_removed(test_label): + def _find_condition(resource): + node_labels = resource.labels.data_dict() + + if test_label not in node_labels: + return True + else: + return False + + return _find_condition + + +def validate_label_set_on_node(client, node, test_label, label_value): + """ + This method checks if the label is added on the node via API and kubectl + :param client: user client + :param node: node on which user has to validate if the label is added + :param test_label: Label to be validated on the node + :param label_value: label value to be checked + :return: None + """ + print("label_value: ", label_value) + # check via API + node = client.reload(node) + node_labels = node.labels.data_dict() + assert node_labels[test_label] == label_value + + # check via kubectl + node_name = node.nodeName + command = " get nodes " + node_name + node_detail = execute_kubectl_cmd(command) + print(node_detail["metadata"]["labels"]) + assert test_label in node_detail["metadata"]["labels"], \ + "Label is not set in kubectl" + assert node_detail["metadata"]["labels"][test_label] == label_value + + +def validate_label_deleted_on_node(client, node, test_label): + """ + This method checks if the label is deleted on the node via API and kubectl + :param client: user client + :param node: node on which user has to validate if the label is deleted + :param test_label: Label to be validated on the node + :return: None + """ + # check via API + node = client.reload(node) + node_labels = node.labels.data_dict() + assert test_label not in node_labels + + # check via kubectl + node_name = node.nodeName + command = " get nodes " + node_name + print(command) + node_detail = execute_kubectl_cmd(command) + print(node_detail["metadata"]["labels"]) + assert test_label not in node_detail["metadata"]["labels"] + + +def add_node_cluster(node_template, cluster): + """ + This method adds a node pool to a given cluster + :param node_template: node pool uses this to create a node + :param cluster: node pool is added to this cluster + :return: cluster, node_pools + """ + client = get_user_client() + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "controlPlane": False, + "etcd": False, + "worker": True, + "quantity": 1, + "clusterId": None} + nodes.append(node) + node_pools = [] + for node in nodes: + node["clusterId"] = cluster.id + success = False + start = time.time() + while not success: + if time.time() - start > 10: + raise AssertionError( + "Timed out waiting for cluster owner global Roles") + try: + time.sleep(1) + node_pool = client.create_node_pool(**node) + success = True + except ApiError: + success = False + node_pool = client.wait_success(node_pool) + node_pools.append(node_pool) + + cluster = validate_cluster_state(client, cluster, + check_intermediate_state=False) + return cluster, node_pools + + +def create_cluster_node_template_label(test_label, label_value): + """ + This method create a node template with the label key and value provided. + Creates a cluster with nodepool, which uses the above node template. + Cluster spec: 1 node all roles + :param test_label: label to add in the node template + :param label_value: label value + :return: cluster, node_pools, node_template, linode_cloud_credential + """ + client = get_user_client() + node_template, linode_cloud_credential = \ + create_node_template_label(client, test_label, label_value) + assert test_label in node_template["labels"], \ + "Label is not set on node template" + assert node_template["labels"][test_label] == label_value + + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "controlPlane": True, + "etcd": True, + "worker": True, + "quantity": 1, + "clusterId": None} + nodes.append(node) + cluster = client.create_cluster( + name=random_name(), + rancherKubernetesEngineConfig=rke_config) + node_pools = [] + for node in nodes: + node["clusterId"] = cluster.id + success = False + start = time.time() + while not success: + if time.time() - start > 10: + raise AssertionError( + "Timed out waiting for cluster owner global Roles") + try: + time.sleep(1) + node_pool = client.create_node_pool(**node) + success = True + except ApiError: + success = False + node_pool = client.wait_success(node_pool) + node_pools.append(node_pool) + cluster = validate_cluster_state(client, cluster) + + return cluster, node_pools, node_template, linode_cloud_credential + + +def create_custom_node_label(node_roles, test_label, + label_value, random_cluster_name=False): + """ + This method creates nodes from AWS and adds the label key and value to + the register command and deploys a custom cluster. + :param node_roles: list of node roles for the cluster + :param test_label: label to add in the docker register command + :param label_value: label value to add in the docker register command + :param random_cluster_name: cluster name + :return: cluster and aws nodes created + """ + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + len(node_roles), random_test_name(HOST_NAME)) + + client = get_user_client() + cluster_name = random_name() if random_cluster_name \ + else evaluate_clustername() + cluster = client.create_cluster(name=cluster_name, + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + for nr in node_roles[i]: + aws_node.roles.append(nr) + docker_run_cmd = docker_run_cmd + " --label " + \ + test_label + "=" + label_value + aws_node.execute_command(docker_run_cmd) + i += 1 + cluster = validate_cluster_state(client, cluster) + return cluster, aws_nodes + + +def create_node_template_label(client, test_label, label_value): + """ + This method adds a given label with key: test_label and value: label_value + to a node template and returns the node template + :param client: user client + :param test_label: label to add in the node template + :param label_value: value of the label to add in the node template + :return: node template and do cloud credential value + """ + linode_cloud_credential_config = {"token": LINODE_ACCESSKEY} + linode_cloud_credential = client.create_cloud_credential( + linodecredentialConfig=linode_cloud_credential_config + ) + node_template = client.create_node_template( + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-east", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}, + name=random_name(), + driver="linode", + cloudCredentialId=linode_cloud_credential.id, + engineInstallURL=engine_install_url, + useInternalIpAddress=True, + labels={"cattle.io/creator": "norman", test_label: label_value}) + node_template = client.wait_success(node_template) + return node_template, linode_cloud_credential diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_template.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_template.py new file mode 100644 index 0000000..c2fe835 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_node_template.py @@ -0,0 +1,279 @@ +import os +import pytest +from rancher import ApiError +from .common import * # NOQA +from .test_rke_cluster_provisioning import rke_config +from .test_rke_cluster_provisioning import random_node_name +from .test_rke_cluster_provisioning import create_and_validate_cluster + +engine_install_url = "https://releases.rancher.com/install-docker/26.1.sh" +user_clients = {"admin": None, "standard_user_1": None, + "standard_user_2": None} + + +# --------------------- rbac tests for node template ----------------------- + +@if_test_rbac +def test_rbac_node_template_create(remove_resource): + # As std user, create a node template + node_template = create_node_template_linode(user_clients["standard_user_1"]) + remove_resource(node_template) + templates = user_clients["standard_user_1"].list_node_template( + name=node_template.name) + assert len(templates) == 1 + + +@if_test_rbac +def test_rbac_node_template_list(remove_resource): + # User client should be able to list template it has created + node_template = create_node_template_linode(user_clients["standard_user_1"]) + templates = user_clients["standard_user_1"].list_node_template( + name=node_template.name) + remove_resource(node_template) + assert len(templates) == 1 + # Admin should be able to list template + templates = user_clients["admin"].list_node_template( + name=node_template.name) + assert len(templates) == 1 + # User 2 should not be able to list templates + templates2 = user_clients["standard_user_2"].list_node_template( + name=node_template.name) + assert len(templates2) == 0 + + +@if_test_rbac +def test_rbac_node_template_delete(remove_resource): + # User client should be able to delete template it has created + node_template = create_node_template_linode(user_clients["standard_user_1"]) + # User1 should be able to delete own template + user_clients["standard_user_1"].delete(node_template) + templates = user_clients["standard_user_1"].list_node_template( + name=node_template.name) + assert len(templates) == 0 + # Admin should be able to delete template created by user1 + node_template2 = create_node_template_linode(user_clients["standard_user_1"]) + user_clients["admin"].delete(node_template2) + templates = user_clients["standard_user_1"].list_node_template( + name=node_template2.name) + assert len(templates) == 0 + # User 2 should not be able to delete template created by user1 + node_template3 = create_node_template_linode(user_clients["standard_user_1"]) + remove_resource(node_template3) + with pytest.raises(ApiError) as e: + user_clients["standard_user_2"].delete(node_template3) + assert e.value.error.status == 403 + + +@if_test_rbac +def test_rbac_node_template_edit(remove_resource): + # User client should be able to edit template it has created + node_template = create_node_template_linode(user_clients["standard_user_1"]) + remove_resource(node_template) + # User1 should be able to edit own template + name_edit=random_name() + user_clients["standard_user_1"].update(node_template, name=name_edit, + digitaloceanConfig= + {"region": "nyc3", + "size": "2gb", + "image": "ubuntu-16-04-x64"}) + templates = user_clients["standard_user_1"].list_node_template( + name=name_edit) + assert len(templates) == 1 + # Admin should be able to edit template created by user1 + name_edit=random_name() + user_clients["admin"].update(node_template, name=name_edit, + digitaloceanConfig= + {"region": "nyc3", + "size": "2gb", + "image": "ubuntu-16-04-x64"}) + templates = user_clients["standard_user_1"].list_node_template( + name=name_edit) + assert len(templates) == 1 + # User 2 should not be able to edit template created by user1 + with pytest.raises(ApiError) as e: + user_clients["standard_user_2"].update(node_template, + name=random_name(), + digitaloceanConfig= + {"region": "nyc3", + "size": "2gb", + "image": "ubuntu-16-04-x64"}) + assert e.value.error.status == 403 + + +@if_test_rbac +def test_rbac_node_template_deploy_cluster(remove_resource): + # Admin should be able to use template to create cluster + node_template = create_node_template_linode(user_clients["standard_user_1"]) + create_and_validate_linode_cluster(node_template) + + +# -------------- rbac tests for cloud credentials -------------- + + +@if_test_rbac +def test_rbac_cloud_credential_create(remove_resource): + # As std user, create a node template + cloud_credential = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + remove_resource(cloud_credential) + credentials = user_clients["standard_user_1"].list_cloud_credential( + name=cloud_credential.name) + assert len(credentials) == 1 + + +@if_test_rbac +def test_rbac_cloud_credential_list(remove_resource): + # User client should be able to list credential it has created + cloud_credential = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + remove_resource(cloud_credential) + credentials = user_clients["standard_user_1"].list_cloud_credential( + name=cloud_credential.name) + assert len(credentials) == 1 + # Admin should be able to list credential + credentials = user_clients["admin"].list_cloud_credential( + name=cloud_credential.name) + assert len(credentials) == 1 + # User 2 should not be able to list credential + credentials2 = user_clients["standard_user_2"].list_cloud_credential( + name=cloud_credential.name) + assert len(credentials2) == 0 + + +@if_test_rbac +def test_rbac_cloud_credential_delete(remove_resource): + # User client should be able to delete credential it has created + cloud_credential = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + # User1 should be able to delete own credential + user_clients["standard_user_1"].delete(cloud_credential) + credentials = user_clients["standard_user_1"].list_cloud_credential( + name=cloud_credential.name) + assert len(credentials) == 0 + # Admin should be able to delete credential created by user1 + cloud_credential2 = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + user_clients["admin"].delete(cloud_credential2) + credentials = user_clients["standard_user_1"].list_cloud_credential( + name=cloud_credential2.name) + assert len(credentials) == 0 + # User 2 should not be able to delete credential created by user1 + cloud_credential3 = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + remove_resource(cloud_credential3) + with pytest.raises(ApiError) as e: + user_clients["standard_user_2"].delete(cloud_credential3) + assert e.value.error.status == 403 + + +@if_test_rbac +def test_rbac_cloud_credential_edit(remove_resource): + # User client should be able to edit credential it has created + cloud_credential = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + remove_resource(cloud_credential) + # User1 should be able to edit own credential + linode_cloud_credential_config = {"name": "testName1"} + user_clients["standard_user_1"].update(cloud_credential, + linodeConfig= + linode_cloud_credential_config) + # Admin should be able to edit credential created by user1 + linode_cloud_credential_config = {"name": "testname2"} + user_clients["admin"].update(cloud_credential, + linodeConfig= + linode_cloud_credential_config) + # User 2 should not be able to edit credential created by user1 + with pytest.raises(ApiError) as e: + linode_cloud_credential_config = {"name": "testname3"} + user_clients["standard_user_2"].update(cloud_credential, + linodeConfig= + linode_cloud_credential_config) + assert e.value.error.status == 403 + + +@if_test_rbac +def test_rbac_cloud_credential_deploy_cluster(remove_resource): + # Admin should be able to use credential created by user1 + # to create a cluster using a node template + cloud_credential = create_cloud_credential_linode(user_clients[ + "standard_user_1"]) + node_template = create_node_template_linode(user_clients["standard_user_1"], + cloud_credential) + create_and_validate_linode_cluster(node_template) + + +# --------------------- helper functions ----------------------- + +def create_node_template_linode(client, cloud_credential=None): + if cloud_credential: + linode_cloud_credential = cloud_credential + else: + linode_cloud_credential_config = {"token": LINODE_ACCESSKEY} + linode_cloud_credential = client.create_cloud_credential( + linodecredentialConfig=linode_cloud_credential_config + ) + node_template = client.create_node_template( + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-east", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}, + name=random_name(), + driver="linode", + cloudCredentialId=linode_cloud_credential.id, + engineInstallURL=engine_install_url, + useInternalIpAddress=True) + node_template = client.wait_success(node_template) + return node_template + + +def create_cloud_credential_linode(client): + linode_cloud_credential_config = {"token": LINODE_ACCESSKEY} + linode_cloud_credential = client.create_cloud_credential( + linodecredentialConfig=linode_cloud_credential_config + ) + return linode_cloud_credential + + +def create_and_validate_linode_cluster(node_template, + rancherKubernetesEngineConfig=rke_config, + attemptDelete=True): + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "controlPlane": True, + "etcd": True, + "worker": True, + "quantity": 1, + "clusterId": None} + nodes.append(node) + cluster, node_pools = create_and_validate_cluster( + user_clients["admin"], nodes, rancherKubernetesEngineConfig, + clusterName=random_name()) + if attemptDelete: + cluster_cleanup(user_clients["admin"], cluster) + else: + return cluster, node_pools + + +@pytest.fixture(autouse="True") +def create_project_client(request): + + user_clients["standard_user_1"] = get_user_client() + user_clients["admin"] = get_admin_client() + user1, user1_token = create_user(user_clients["admin"]) + user_clients["standard_user_2"] = get_client_for_token(user1_token) + + def fin(): + user_clients["admin"].delete(user1) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_oke_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_oke_cluster.py new file mode 100644 index 0000000..ce89500 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_oke_cluster.py @@ -0,0 +1,204 @@ +import pytest +from .common import * # NOQA + +OCI_TENANCY_OCID = os.environ.get('RANCHER_OCI_TENANCY_OCID', "") +OCI_COMPARTMENT_OCID = os.environ.get('RANCHER_OCI_COMPARTMENT_OCID', "") +OCI_USER_OCID = os.environ.get('RANCHER_OCI_USER_OCID', "") +OCI_FINGERPRINT = os.environ.get('RANCHER_OCI_FINGERPRINT', "") +OCI_PRIVATE_KEY_PATH = os.environ.get('RANCHER_OCI_PRIVATE_KEY_PATH', "") +OCI_PRIVATE_KEY_PASSPHRASE = os.environ.get('RANCHER_OCI_PRIVATE_KEY_PASSPHRASE', "") +OCI_REGION = os.environ.get('RANCHER_OCI_REGION', None) +OKE_VERSION = os.environ.get('RANCHER_OKE_VERSION', None) +OKE_NODE_SHAPE = os.environ.get('RANCHER_OKE_NODE_SHAPE', None) +OKE_NODE_IMAGE = os.environ.get('RANCHER_OKE_NODE_IMAGE', None) + +okecredential = pytest.mark.skipif(not ( + OCI_TENANCY_OCID and OCI_COMPARTMENT_OCID and OCI_USER_OCID and OCI_FINGERPRINT and OCI_PRIVATE_KEY_PATH), + reason='OKE Credentials not provided, ' + 'cannot create cluster') + + +def test_error_get_oke_latest_versions_missing_key(): + oci_cred_body = { + "tenancyOCID": "ocid1.tenancy.oc1..aaaaaa", + "userOCID": "ocid1.user.oc1..aaaaaaaa", + "region": "us-ashburn-1", + "fingerprint": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx", + } + response = get_oci_meta_response("/meta/oci/okeVersions", oci_cred_body) + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + assert response.status_code == 422 + assert json_response['message'] == "OCI API private key is required" + + +def test_error_get_oke_images_missing_tenancy(): + oci_cred_body = { + "userOCID": "ocid1.user.oc1..aaaaaaaa", + "region": "us-phoenix-1", + "fingerprint": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx", + "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIE...ewBQ==\n-----END RSA PRIVATE KEY-----" + } + + response = get_oci_meta_response("/meta/oci/nodeOkeImages", oci_cred_body) + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + assert response.status_code == 422 + assert json_response['message'] == "OCI tenancy is required" + + +def test_error_get_invalid_endpoint(): + oci_cred_body = { + "tenancyOCID": "ocid1.tenancy.oc1..aaaaaa", + "userOCID": "ocid1.user.oc1..aaaaaaaa", + "region": "ap-tokyo-1", + "fingerprint": "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx", + "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIE...ewBQ==\n-----END RSA PRIVATE KEY-----" + } + response = get_oci_meta_response("/meta/oci/dne", oci_cred_body) + assert response.status_code == 404 + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + assert "invalid endpoint" in json_response['message'] + + +@okecredential +def test_get_oke_latest_versions(): + oci_cred_body = { + "tenancyOCID": OCI_TENANCY_OCID, + "userOCID": OCI_USER_OCID, + "region": OCI_REGION, + "fingerprint": OCI_FINGERPRINT, + "privateKey": get_ssh_key_contents(OCI_PRIVATE_KEY_PATH) + } + response = get_oci_meta_response("/meta/oci/okeVersions", oci_cred_body) + + assert response.status_code == 200 + assert response.content is not None + json_response = json.loads(response.content) + latest_oke_version = json_response[-1] + + print(latest_oke_version) + + +@okecredential +def test_create_oke_cluster(): + client, cluster = create_and_validate_oke_cluster("test-auto-oke") + cluster_cleanup(client, cluster) + + +def create_and_validate_oke_cluster(name): + oci_cred_body = { + "tenancyOCID": OCI_TENANCY_OCID, + "userOCID": OCI_USER_OCID, + "region": OCI_REGION, + "fingerprint": OCI_FINGERPRINT, + "privateKey": get_ssh_key_contents(OCI_PRIVATE_KEY_PATH) + } + client = get_user_client() + print("Cluster creation") + # Get the region + if OCI_REGION is None: + region = "us-phoenix-1" + else: + region = OCI_REGION + # Get the node shape + if OKE_NODE_SHAPE is None: + response = get_oci_meta_response("/meta/oci/nodeShapes", oci_cred_body) + print(response.content) + assert response.status_code == 200 + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + shape = json_response[-1] + else: + shape = OKE_NODE_SHAPE + + # Get the node image + if OKE_NODE_IMAGE is None: + response = get_oci_meta_response("/meta/oci/nodeOkeImages", oci_cred_body) + assert response.status_code == 200 + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + latest_oke_image = json_response[-1] + else: + latest_oke_image = OKE_NODE_IMAGE + + # Get the OKE version + if OKE_VERSION is None: + response = get_oci_meta_response("/meta/oci/okeVersions", oci_cred_body) + assert response.status_code == 200 + assert response.content is not None + json_response = json.loads(response.content) + print(json_response) + latest_oke_version = json_response[-1] + else: + latest_oke_version = OKE_VERSION + + cluster = client.create_cluster( + name=name, + okeEngineConfig={ + "availabilityDomain": "", + "compartmentId": OCI_COMPARTMENT_OCID, + "displayName": name, + "driverName": "oraclecontainerengine", + "enableKubernetesDashboard": False, + "enablePrivateNodes": False, + "enableTiller": False, + "fingerprint": OCI_FINGERPRINT, + "kubernetesVersion": latest_oke_version, + "loadBalancerSubnetName1": "", + "loadBalancerSubnetName2": "", + "name": name, + "nodeImage": latest_oke_image, + "nodePoolDnsDomainName": "nodedns", + "nodePoolSecurityListName": "Node Security List", + "nodePoolSubnetName": "nodedns", + "nodePublicKeyContents": "", + "nodePublicKeyPath": "", + "nodeShape": shape, + "privateKeyContents": get_ssh_key_contents(OCI_PRIVATE_KEY_PATH), + "privateKeyPassphrase": OCI_PRIVATE_KEY_PASSPHRASE, + "privateKeyPath": "", + "quantityOfNodeSubnets": 1, + "quantityPerSubnet": 1, + "region": region, + "serviceDnsDomainName": "svcdns", + "serviceSecurityListName": "Service Security List", + "skipVcnDelete": False, + "tenancyId": OCI_TENANCY_OCID, + "tenancyName": "", + "type": "okeEngineConfig", + "userOcid": OCI_USER_OCID, + "vcnName": "", + "waitNodesActive": 0, + "workerNodeIngressCidr": "" + }) + print(cluster) + cluster = validate_cluster(client, cluster, check_intermediate_state=True, + skipIngresscheck=True) + return client, cluster + + +def get_oci_meta_response(endpoint, oci_cred_body): + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + USER_TOKEN} + + oke_version_url = CATTLE_TEST_URL + endpoint + + response = requests.post(oke_version_url, json=oci_cred_body, + verify=False, headers=headers) + + return response + + +def get_ssh_key_contents(path): + if os.path.exists(path): + with open(path, 'r') as f: + ssh_key = f.read() + return ssh_key diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_project_quota.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_project_quota.py new file mode 100644 index 0000000..8c01190 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_project_quota.py @@ -0,0 +1,205 @@ +import os +import pytest +from .common import * # NOQA + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} + +CLUSTER_NAME = os.environ.get("CLUSTER_NAME", "") +RANCHER_CLEANUP_PROJECT = os.environ.get("RANCHER_CLEANUP_PROJECT", "True") + + +@pytest.fixture +def ns_default_quota(): + return {"limit": {"pods": "5", + "requestsCpu": "500m"}} + + +@pytest.fixture +def default_project_quota(): + return {"limit": {"pods": "20", + "requestsCpu": "2000m"}} + + +def ns_quota(): + return {"limit": {"pods": "10", + "requestsCpu": "500m"}} + + +def test_create_project_quota(): + # Create Project Resource Quota and verify quota is created + # successfully. Verify namespacedefault resource quota is set + + cluster = namespace["cluster"] + client = get_user_client() + c_client = namespace["c_client"] + + quota = default_project_quota() + nsquota = ns_default_quota() + proj = client.create_project(name='test-' + random_str(), + clusterId=cluster.id, + resourceQuota=quota, + namespaceDefaultResourceQuota=nsquota) + proj = client.wait_success(proj) + + assert proj.resourceQuota is not None + assert proj.resourceQuota.limit.pods == quota["limit"]["pods"] + assert proj.resourceQuota.limit.requestsCpu == \ + quota["limit"]["requestsCpu"] + assert proj.namespaceDefaultResourceQuota is not None + assert proj.namespaceDefaultResourceQuota.limit.pods == \ + nsquota["limit"]["pods"] + + ns = create_ns(c_client, cluster, proj) + print(ns) + + assert ns is not None + assert ns.resourceQuota is not None + assert ns.resourceQuota.limit.pods == nsquota["limit"]["pods"] + assert ns.resourceQuota.limit.requestsCpu == \ + nsquota["limit"]["requestsCpu"] + + validate_resoucequota_thru_kubectl(ns) + + +def test_resource_quota_create_namespace_with_ns_quota(): + + # Create project quota and namspaces and verify + # namespace creation is allowed within the quota + + cluster = namespace["cluster"] + client = get_user_client() + c_client = namespace["c_client"] + + quota = default_project_quota() + nsquota = ns_quota() + proj = client.create_project(name='test-' + random_str(), + clusterId=cluster.id, + resourceQuota=quota, + namespaceDefaultResourceQuota=quota) + proj = client.wait_success(proj) + + assert proj.resourceQuota is not None + + # Create a namespace with namespace resource quota + ns_name = random_str() + ns = c_client.create_namespace(name=ns_name, + projectId=proj.id, + resourceQuota=ns_quota()) + ns = c_client.wait_success(ns) + + assert ns is not None + assert ns.resourceQuota is not None + assert ns.resourceQuota.limit.pods == nsquota["limit"]["pods"] + assert ns.resourceQuota.limit.requestsCpu == \ + nsquota["limit"]["requestsCpu"] + + validate_resoucequota_thru_kubectl(ns) + + # Create another namespace with quota and it should succeed + + ns1 = c_client.create_namespace(name=random_str(), + projectId=proj.id, + resourceQuota=nsquota) + ns1 = c_client.wait_success(ns1) + print(ns1) + + assert ns1 is not None + assert ns1.resourceQuota is not None + assert ns1.resourceQuota.limit.pods == nsquota["limit"]["pods"] + assert ns1.resourceQuota.limit.requestsCpu == \ + nsquota["limit"]["requestsCpu"] + + validate_resoucequota_thru_kubectl(ns1) + + # Creating another namespace should fail as it exceeds the allotted limit + try: + c_client.create_namespace(name=random_str(), + projectId=proj.id, + resourceQuota=ns_quota()) + except Exception as e: + errorstring = str(e) + print(str(e)) + assert "MaxLimitExceeded" in errorstring + +def test_namespace_quota_edit(remove_resource): + client, cluster = get_global_admin_client_and_cluster() + + pj1 = client.create_project(name=random_str(), + clusterId=cluster.id, + resourceQuota={"limit": {"limitsCpu": "20m"}}, + namespaceDefaultResourceQuota={ + "limit": {"limitsCpu": "10m"}}) + + pj2 = client.create_project(name=random_str(), + clusterId=cluster.id, + resourceQuota={"limit": {"limitsCpu": "15m"}}, + namespaceDefaultResourceQuota={ + "limit": {"limitsCpu": "15m"}}) + + + p_client = get_cluster_client_for_token(cluster, ADMIN_TOKEN) + + ns1 = p_client.create_namespace(name=random_str(), + clusterId=cluster.id, + projectId=pj1.id) + + ns2 = p_client.create_namespace(name=random_str(), + clusterId=cluster.id, + projectId=pj2.id) + + ns1 = p_client.wait_success(ns1) + ns2 = p_client.wait_success(ns2) + + p_client.action(obj=ns2, + action_name="move", + projectId=None) + + ns1 = p_client.update(ns1, + resourceQuota={"limit": {"limitsCpu": "11m"}}) + + ns1_limitsCpu = ns1.resourceQuota.limit.limitsCpu + assert ns1_limitsCpu == "11m" + + remove_resource(pj1) + remove_resource(pj2) + remove_resource(ns2) + +def validate_resoucequota_thru_kubectl(namespace): + + # This method executes `kubectl describe quota command` and verifies if the + # resource quota from kubectl and the quota assigned for the namespace + # through API are the same + + command = "get quota --namespace " + namespace['id'] + print(command) + + result = execute_kubectl_cmd(command, json_out=True) + print("Kubectl command result") + print(result) + testdict = namespace['resourceQuota'] + + response = result["items"] + assert "spec" in response[0] + quotadict = (response[0]["spec"]) + assert quotadict['hard']['pods'] == testdict['limit']['pods'] + assert \ + quotadict['hard']['requests.cpu'] == testdict['limit']['requestsCpu'] + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testworkload") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_proxy.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_proxy.py new file mode 100644 index 0000000..73b075e --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_proxy.py @@ -0,0 +1,295 @@ +import os +import time +from lib.aws import AWS_USER +from .common import ( + ADMIN_PASSWORD, AmazonWebServices, run_command +) +from .test_airgap import get_bastion_node +from .test_custom_host_reg import ( + random_test_name, RANCHER_SERVER_VERSION, HOST_NAME, AGENT_REG_CMD +) +BASTION_ID = os.environ.get("RANCHER_BASTION_ID", "") +NUMBER_OF_INSTANCES = int(os.environ.get("RANCHER_AIRGAP_INSTANCE_COUNT", "1")) + +PROXY_HOST_NAME = random_test_name(HOST_NAME) +RANCHER_PROXY_INTERNAL_HOSTNAME = \ + PROXY_HOST_NAME + "-internal.qa.rancher.space" +RANCHER_PROXY_HOSTNAME = PROXY_HOST_NAME + ".qa.rancher.space" + +RESOURCE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') +SSH_KEY_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + '.ssh') + +RANCHER_PROXY_PORT = os.environ.get("RANCHER_PROXY_PORT", "3131") +RANCHER_CIDR_OVERRIDE = os.environ.get("RANCHER_CIDR_OVERRIDE", "") + + +def deploy_proxy_server(): + node_name = PROXY_HOST_NAME + "-proxy" + proxy_node = AmazonWebServices().create_node(node_name) + + # Copy SSH Key to proxy and local dir and give it proper permissions + write_key_command = "cat <> {}.pem\n{}\nEOT".format( + proxy_node.ssh_key_name, proxy_node.ssh_key) + proxy_node.execute_command(write_key_command) + local_write_key_command = \ + "mkdir -p {} && cat <> {}/{}.pem\n{}\nEOT".format( + SSH_KEY_DIR, SSH_KEY_DIR, + proxy_node.ssh_key_name, proxy_node.ssh_key) + run_command(local_write_key_command, log_out=False) + + set_key_permissions_command = "chmod 400 {}.pem".format( + proxy_node.ssh_key_name) + proxy_node.execute_command(set_key_permissions_command) + local_set_key_permissions_command = "chmod 400 {}/{}.pem".format( + SSH_KEY_DIR, proxy_node.ssh_key_name) + run_command(local_set_key_permissions_command, log_out=False) + + # Write the proxy config to the node and run the proxy + proxy_node.execute_command("mkdir -p /home/ubuntu/squid/") + + copy_cfg_command = \ + 'scp -q -i {}/{}.pem -o StrictHostKeyChecking=no ' \ + '-o UserKnownHostsFile=/dev/null {}/squid/squid.conf ' \ + '{}@{}:~/squid/squid.conf'.format( + SSH_KEY_DIR, proxy_node.ssh_key_name, RESOURCE_DIR, + AWS_USER, proxy_node.host_name) + run_command(copy_cfg_command, log_out=True) + + squid_cmd = "sudo docker run -d " \ + "-v /home/ubuntu/squid/squid.conf:/etc/squid/squid.conf " \ + "-p {}:3128 wernight/squid".format(RANCHER_PROXY_PORT) + + proxy_node.execute_command(squid_cmd) + + print("Proxy Server Details:\nNAME: {}\nHOST NAME: {}\n" + "INSTANCE ID: {}\n".format(node_name, proxy_node.host_name, + proxy_node.provider_node_id)) + return proxy_node + + +def run_command_on_proxy_node(bastion_node, ag_node, cmd, log_out=False): + ag_command = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"{}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, cmd) + result = bastion_node.execute_command(ag_command) + if log_out: + print("Running command: {}".format(ag_command)) + print("Result: {}".format(result)) + return result + + +def prepare_airgap_proxy_node(bastion_node, number_of_nodes): + node_name = PROXY_HOST_NAME + "-agproxy" + ag_nodes = AmazonWebServices().create_multiple_nodes( + number_of_nodes, node_name, public_ip=False) + + for num, ag_node in enumerate(ag_nodes): + ag_node_update_docker = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo usermod -aG docker {}"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address, AWS_USER) + bastion_node.execute_command(ag_node_update_docker) + + proxy_url = bastion_node.host_name + ":" + RANCHER_PROXY_PORT + proxy_info = '[Service]\nEnvironment=\"HTTP_PROXY={}\" ' \ + '\"HTTPS_PROXY={}\" ' \ + '\"NO_PROXY=localhost,127.0.0.1,0.0.0.0,10.0.0.0/8,' \ + 'cattle-system.svc,{}\"' \ + .format(proxy_url, proxy_url, RANCHER_CIDR_OVERRIDE) + + bastion_node.execute_command('echo "{}" > http-proxy.conf' + .format(proxy_info)) + + ag_node_create_dir = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no {}@{} ' \ + '"sudo mkdir -p /etc/systemd/system/docker.service.d"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_create_dir) + + copy_conf_cmd = \ + 'scp -q -i "{}".pem -o StrictHostKeyChecking=no -o ' \ + 'UserKnownHostsFile=/dev/null ~/http-proxy.conf ' \ + '{}@{}:~/'.format(bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(copy_conf_cmd) + + ag_node_mv_conf = \ + 'ssh -i "{}.pem" -o StrictHostKeyChecking=no ' \ + '-o UserKnownHostsFile=/dev/null {}@{} ' \ + '"sudo mv http-proxy.conf /etc/systemd/system/docker.service.d/ ' \ + '&& sudo systemctl daemon-reload && ' \ + 'sudo systemctl restart docker"'.format( + bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_mv_conf) + + print("Airgapped Proxy Instance Details:\n" + "NAME: {}-{}\nPRIVATE IP: {}\n" + "".format(node_name, num, ag_node.private_ip_address)) + return ag_nodes + + +def deploy_proxy_rancher(bastion_node): + ag_node = prepare_airgap_proxy_node(bastion_node, 1)[0] + proxy_url = bastion_node.host_name + ":" + RANCHER_PROXY_PORT + deploy_rancher_command = \ + 'sudo docker run -d --privileged --restart=unless-stopped ' \ + '-p 80:80 -p 443:443 ' \ + '-e HTTP_PROXY={} ' \ + '-e HTTPS_PROXY={} ' \ + '-e NO_PROXY="localhost,127.0.0.1,0.0.0.0,10.0.0.0/8,' \ + 'cattle-system.svc,{}" ' \ + '-e CATTLE_BOOTSTRAP_PASSWORD=\\\"{}\\\" ' \ + 'rancher/rancher:{} --trace'.format( + proxy_url, proxy_url, RANCHER_CIDR_OVERRIDE, + ADMIN_PASSWORD, RANCHER_SERVER_VERSION) + + deploy_result = run_command_on_proxy_node(bastion_node, ag_node, + deploy_rancher_command, + log_out=True) + assert "Downloaded newer image for rancher/rancher:{}".format( + RANCHER_SERVER_VERSION) in deploy_result[1] + return ag_node + + +def register_cluster_nodes(bastion_node, ag_nodes): + results = [] + for ag_node in ag_nodes: + deploy_result = run_command_on_proxy_node(bastion_node, ag_node, + AGENT_REG_CMD) + results.append(deploy_result) + return results + + +def create_nlb_and_add_targets(aws_nodes): + # Create internet-facing nlb and grab ARN & dns name + lb = AmazonWebServices().create_network_lb(name=PROXY_HOST_NAME + "-nlb") + lb_arn = lb["LoadBalancers"][0]["LoadBalancerArn"] + public_dns = lb["LoadBalancers"][0]["DNSName"] + # Create internal nlb and grab ARN & dns name + internal_lb = AmazonWebServices().create_network_lb( + name=PROXY_HOST_NAME + "-internal-nlb", scheme='internal') + internal_lb_arn = internal_lb["LoadBalancers"][0]["LoadBalancerArn"] + internal_lb_dns = internal_lb["LoadBalancers"][0]["DNSName"] + + # Upsert the route53 record -- if it exists, update, if not, insert + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_PROXY_INTERNAL_HOSTNAME, internal_lb_dns) + + AmazonWebServices().upsert_route_53_record_cname( + RANCHER_PROXY_HOSTNAME, public_dns) + public_dns = RANCHER_PROXY_HOSTNAME + + # Create the target groups + tg80 = AmazonWebServices(). \ + create_ha_target_group(80, PROXY_HOST_NAME + "-tg-80") + tg443 = AmazonWebServices(). \ + create_ha_target_group(443, PROXY_HOST_NAME + "-tg-443") + tg80_arn = tg80["TargetGroups"][0]["TargetGroupArn"] + tg443_arn = tg443["TargetGroups"][0]["TargetGroupArn"] + # Create the internal target groups + internal_tg80 = AmazonWebServices(). \ + create_ha_target_group(80, PROXY_HOST_NAME + "-internal-tg-80") + internal_tg443 = AmazonWebServices(). \ + create_ha_target_group(443, PROXY_HOST_NAME + "-internal-tg-443") + internal_tg80_arn = internal_tg80["TargetGroups"][0]["TargetGroupArn"] + internal_tg443_arn = internal_tg443["TargetGroups"][0]["TargetGroupArn"] + + # Create listeners for the load balancers, to forward to the target groups + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=80, targetGroupARN=tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=lb_arn, port=443, targetGroupARN=tg443_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=80, + targetGroupARN=internal_tg80_arn) + AmazonWebServices().create_ha_nlb_listener( + loadBalancerARN=internal_lb_arn, port=443, + targetGroupARN=internal_tg443_arn) + + targets = [] + + for aws_node in aws_nodes: + targets.append(aws_node.provider_node_id) + + # Register the nodes to the internet-facing targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + health80 = AmazonWebServices().describe_target_health( + tg80_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + tg443_arn)['TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + time.sleep(1) + + # Register the nodes to the internal targets + targets_list = [dict(Id=target_id, Port=80) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg80_arn) + targets_list = [dict(Id=target_id, Port=443) for target_id in targets] + AmazonWebServices().register_targets(targets_list, internal_tg443_arn) + # Wait up to approx. 5 minutes for targets to begin health checks + for i in range(300): + try: + health80 = AmazonWebServices().describe_target_health( + internal_tg80_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + health443 = AmazonWebServices().describe_target_health( + internal_tg443_arn)[ + 'TargetHealthDescriptions'][0]['TargetHealth']['State'] + if health80 in ['initial', 'healthy'] \ + and health443 in ['initial', 'healthy']: + break + except Exception: + print("Target group healthchecks unavailable...") + time.sleep(1) + return public_dns + + +def test_deploy_proxied_rancher(): + proxy_node = deploy_proxy_server() + proxy_rancher_node = deploy_proxy_rancher(proxy_node) + public_dns = create_nlb_and_add_targets([proxy_rancher_node]) + print( + "\nConnect to bastion node with:\nssh -i {}.pem {}@{}\n" + "Connect to rancher node by connecting to bastion, then run:\n" + "ssh -i {}.pem {}@{}\n\nOpen the Rancher UI with: https://{}\n" + "".format( + proxy_node.ssh_key_name, AWS_USER, + proxy_node.host_name, + proxy_node.ssh_key_name, AWS_USER, + proxy_rancher_node.private_ip_address, + public_dns)) + + +def test_deploy_proxy_nodes(): + bastion_node = get_bastion_node(BASTION_ID) + ag_nodes = prepare_airgap_proxy_node(bastion_node, NUMBER_OF_INSTANCES) + assert len(ag_nodes) == NUMBER_OF_INSTANCES + + print( + '{} airgapped instance(s) created.\n' + 'Connect to these and run commands by connecting to bastion node, ' + 'then running the following command (with the quotes):\n' + 'ssh -i {}.pem {}@NODE_PRIVATE_IP '.format( + NUMBER_OF_INSTANCES, bastion_node.ssh_key_name, + AWS_USER)) + + for ag_node in ag_nodes: + assert ag_node.private_ip_address is not None + assert ag_node.public_ip_address is None + + results = register_cluster_nodes(bastion_node, ag_nodes) + for result in results: + assert "Downloaded newer image for rancher/rancher-agent" in result[1] diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac.py new file mode 100644 index 0000000..e1d35aa --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac.py @@ -0,0 +1,329 @@ +import pytest +from rancher import ApiError, Client + +from .common import ( + ADMIN_TOKEN, + CATTLE_API_URL, + assign_members_to_cluster, + assign_members_to_project, + change_member_role_in_cluster, + change_member_role_in_project, + create_ns, + create_project, + create_project_and_ns, + get_user_client, + get_admin_client, + get_client_for_token, + get_cluster_client_for_token, + create_user, + get_user_client_and_cluster +) + + +def test_rbac_cluster_owner(): + client, cluster = get_user_client_and_cluster() + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin , add user1 as cluster member of this cluster + client = get_user_client() + assign_members_to_cluster(client, user1, cluster, "cluster-owner") + validate_cluster_owner(user1_token, cluster) + + +def test_rbac_cluster_member(): + client, cluster = get_user_client_and_cluster() + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # Add user1 as cluster member of this cluster + client = get_user_client() + assign_members_to_cluster(client, user1, cluster, "cluster-member") + validate_cluster_member(user1_token, cluster) + + +def test_rbac_project_owner(): + client, cluster = get_user_client_and_cluster() + # As admin user create a project and namespace + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin user, Add user1 as project member of this project + client = get_user_client() + assign_members_to_project(client, user1, a_p, "project-owner") + validate_project_owner(user1_token, cluster, a_p, a_ns) + + +def test_rbac_project_member(): + client, cluster = get_user_client_and_cluster() + + # As admin user create a project and namespace + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + + user1, user1_token = create_user(get_admin_client()) + user2, user2_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin user, Add user1 as project member of this project + client = get_user_client() + assign_members_to_project(client, user1, a_p, "project-member") + validate_project_member(user1_token, cluster, a_p, a_ns) + + +def test_rbac_change_cluster_owner_to_cluster_member(): + client, cluster = get_user_client_and_cluster() + + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin , add user1 as cluster member of this cluster + client = get_user_client() + crtb = assign_members_to_cluster( + client, user1, cluster, "cluster-owner") + validate_cluster_owner(user1_token, cluster) + change_member_role_in_cluster( + client, user1, crtb, "cluster-member") + validate_cluster_member(user1_token, cluster) + + +def test_rbac_change_cluster_member_to_cluster_owner(): + client, cluster = get_user_client_and_cluster() + + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # Add user1 as cluster member of this cluster + crtb = assign_members_to_cluster( + get_user_client(), user1, cluster, "cluster-member") + validate_cluster_member(user1_token, cluster) + change_member_role_in_cluster( + get_user_client(), user1, crtb, "cluster-owner") + validate_cluster_owner(user1_token, cluster) + + +def test_rbac_change_project_owner_to_project_member(): + client, cluster = get_user_client_and_cluster() + + # As admin user create a project and namespace + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + + user1, user1_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin user, Add user1 as project member of this project + prtb = assign_members_to_project( + get_user_client(), user1, a_p, "project-owner") + validate_project_owner(user1_token, cluster, a_p, a_ns) + change_member_role_in_project( + get_user_client(), user1, prtb, "project-member") + validate_project_member(user1_token, cluster, a_p, a_ns) + + +def test_rbac_change_project_member_to_project_cluster(): + client, cluster = get_user_client_and_cluster() + + # As admin user create a project and namespace + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + + user1, user1_token = create_user(get_admin_client()) + user2, user2_token = create_user(get_admin_client()) + + # Assert that user1 is not able to list cluster + user1_client = get_client_for_token(user1_token) + clusters = user1_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 0 + + # As admin user, Add user1 as project member of this project + prtb = assign_members_to_project( + get_user_client(), user1, a_p, "project-member") + validate_project_member(user1_token, cluster, a_p, a_ns) + change_member_role_in_project( + get_user_client(), user1, prtb, "project-owner") + validate_project_owner(user1_token, cluster, a_p, a_ns) + + +def validate_cluster_owner(user_token, cluster): + # As admin user create a project and namespace and a user + user2, user2_token = create_user(get_admin_client()) + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + + # Assert that user1 is able to see cluster + user_client = get_client_for_token(user_token) + clusters = user_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 1 + + # Assert that user1 is allowed to assign member to the cluster + assign_members_to_cluster(user_client, user2, cluster, "cluster-member") + + # Assert that user1 is able to see projects he does not own + project = user_client.list_project( # pylint: disable=no-member + name=a_p.name).data + assert len(project) == 1 + + # Assert that user1 is able to see namespaces that are in projects + # that he does not own + user_c_client = get_cluster_client_for_token(cluster, user_token) + ns = user_c_client.list_namespace( # pylint: disable=no-member + uuid=a_ns.uuid).data + assert len(ns) == 1 + + # Assert that user1 is able to create namespaces in the projects + # that he does not own + create_ns(user_c_client, cluster, a_p) + + # Assert that user1 is able create projects and namespace in that project + create_project_and_ns(user_token, cluster) + + +def validate_cluster_member(user_token, cluster): + # As admin user create a project and namespace and a user + a_p, a_ns = create_project_and_ns(ADMIN_TOKEN, cluster) + user2, user2_token = create_user(get_admin_client()) + + # Assert that user1 is able to see cluster + user_client = get_client_for_token(user_token) + clusters = user_client.list_cluster( # pylint: disable=no-member + name=cluster.name).data + assert len(clusters) == 1 + assert clusters[0].name == cluster.name + + # Assert that user1 is NOT able to assign member to the cluster + with pytest.raises(ApiError) as e: + assign_members_to_cluster( + user_client, user2, cluster, "cluster-member") + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + # Assert that user1 is NOT able to see projects he does not own + project = user_client.list_project( # pylint: disable=no-member + name=a_p.name).data + assert len(project) == 0 + + """ + # Assert that user1 is NOT able to access projects that he does not own + with pytest.raises(ApiError) as e: + get_project_client_for_token(a_p, user_token) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + """ + # Assert that user1 is able create projects and namespace in that project + create_project_and_ns(user_token, cluster) + + +def validate_project_owner(user_token, cluster, project, namespace): + user2, user2_token = create_user(get_admin_client()) + + # Assert that user1 is now able to see cluster + user_client = get_client_for_token(user_token) + clusters = user_client.list_cluster( # pylint: disable=no-member + name=cluster.name).data + assert len(clusters) == 1 + assert clusters[0].name == cluster.name + + # Assert that user1 is NOT able to assign member to the cluster + with pytest.raises(ApiError) as e: + assign_members_to_cluster(user_client, user2, + cluster, "cluster-member") + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + # Assert that user1 is able to see projects he is made the owner of + projects = user_client.list_project( # pylint: disable=no-member + name=project.name).data + assert len(projects) == 1 + + # Assert that user1 is able to access this project + p_user_client = get_cluster_client_for_token(cluster, user_token) + + # Assert that user1 is able to see the existing namespace in this project + nss = p_user_client.list_namespace( # pylint: disable=no-member + uuid=namespace.uuid).data + assert len(nss) == 1 + + # Assert that user1 is able to access this project + create_ns(p_user_client, cluster, project) + + # Assert that user1 is able to assign member to the project + assign_members_to_project(user_client, user2, project, "project-member") + + # Assert that user1 is NOT able to create project + with pytest.raises(ApiError) as e: + create_project(user_client, cluster) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +def validate_project_member(user_token, cluster, project, namespace): + user2, user2_token = create_user(get_admin_client()) + # Assert that user1 is able to see cluster + user_client = Client(url=CATTLE_API_URL, token=user_token, + verify=False) + clusters = user_client.list_cluster().data # pylint: disable=no-member + assert len(clusters) == 1 + assert clusters[0].name == cluster.name + + # Assert that user1 is NOT able to assign member to the cluster + with pytest.raises(ApiError) as e: + assign_members_to_cluster(user_client, user2, + cluster, "cluster-member") + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + # Assert that user1 is able to see projects he is made member of + projects = user_client.list_project( # pylint: disable=no-member + name=project.name).data + assert len(projects) == 1 + + # Assert that user1 is able to access this project + p_user_client = get_cluster_client_for_token(cluster, user_token) + + # Assert that user1 is able to see the existing namespace in this project + nss = p_user_client.list_namespace( # pylint: disable=no-member + uuid=namespace.uuid).data + assert len(nss) == 1 + + # Assert that user1 is able create namespace in this project + create_ns(p_user_client, cluster, project) + + # Assert that user1 is NOT able to assign member to the project + with pytest.raises(ApiError) as e: + assign_members_to_project(user_client, user2, + project, "project-member") + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + # Assert that user1 is NOT able to create project + with pytest.raises(ApiError) as e: + create_project(user_client, cluster) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac_2.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac_2.py new file mode 100644 index 0000000..af95f55 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rbac_2.py @@ -0,0 +1,50 @@ +import pytest +import os +from .common import create_kubeconfig +from .common import DATA_SUBDIR +from .common import get_user_client_and_cluster +from .common import rbac_test_file_reader +from .common import validate_cluster_role_rbac +from .common import if_test_rbac_v2 + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + + +@if_test_rbac_v2 +@pytest.mark.parametrize("cluster_role, command, authorization, name", + rbac_test_file_reader(os.path.join( + DATA_SUBDIR, + 'rbac/monitoring/monitoring_rbac.json'))) +def test_monitoring_rbac_v2(cluster_role, command, authorization, name): + validate_cluster_role_rbac(cluster_role, command, authorization, name) + + +@if_test_rbac_v2 +@pytest.mark.parametrize("cluster_role, command, authorization, name", + rbac_test_file_reader(os.path.join( + DATA_SUBDIR, + 'rbac/istio/istio_rbac.json'))) +def test_istio_rbac_v2(cluster_role, command, authorization, name): + validate_cluster_role_rbac(cluster_role, command, authorization, name) + + +@if_test_rbac_v2 +@pytest.mark.parametrize("cluster_role, command, authorization, name", + rbac_test_file_reader(os.path.join( + DATA_SUBDIR, + 'rbac/logging/logging_rbac.json'))) +def test_logging_rbac_v2(cluster_role, command, authorization, name): + validate_cluster_role_rbac(cluster_role, command, authorization, name) + + +@if_test_rbac_v2 +@pytest.mark.parametrize("cluster_role, command, authorization, name", + rbac_test_file_reader(os.path.join( + DATA_SUBDIR, + 'rbac/cis/cis_rbac.json'))) +def test_cis_rbac_v2(cluster_role, command, authorization, name): + validate_cluster_role_rbac(cluster_role, command, authorization, name) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_registry.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_registry.py new file mode 100644 index 0000000..52da1ab --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_registry.py @@ -0,0 +1,544 @@ +""" +This file contains test related to add registry and +deploying workloads with those registry. +Test requirement: +Below Env variables need to set +CATTLE_TEST_URL - url to rancher server +ADMIN_TOKEN - Admin token from rancher +USER_TOKEN - User token from rancher +RANCHER_CLUSTER_NAME - Cluster name to run test on +RANCHER_REGISTRY - quay.io, dockerhub, custom etc +RANCHER_TEST_CLIENT_IMAGE - Path to image eg. quay.io/myimage/ubuntuimage +RANCHER_TEST_RBAC - Boolean (Optional), To run rbac tests +""" + +from .common import * # NOQA + +CLUSTER_NAME = os.environ.get("CLUSTER_NAME", "") +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} +REGISTRY_USER_NAME = os.environ.get('RANCHER_REGISTRY_USER_NAME', "None") +REGISTRY_PASSWORD = os.environ.get('RANCHER_REGISTRY_PASSWORD', "None") +TEST_CLIENT_IMAGE = os.environ.get('RANCHER_TEST_CLIENT_IMAGE', "None") +REGISTRY = os.environ.get('RANCHER_REGISTRY', "None") + +rbac_role_list = [ + CLUSTER_OWNER, + CLUSTER_MEMBER, + PROJECT_OWNER, + PROJECT_MEMBER, + PROJECT_READ_ONLY + ] + + +def test_create_registry_single_namespace(): + """ + This test creates a namespace and creates a registry. + Validates the workload created in same namespace using registry image + comes up active. + """ + p_client = namespace["p_client"] + ns = namespace["ns"] + registry = create_registry_validate_workload(p_client, ns) + delete_registry(p_client, registry) + + +def test_create_registry_all_namespace(): + p_client = namespace["p_client"] + c_client = namespace["c_client"] + cluster = namespace["cluster"] + project = namespace["project"] + + ns = namespace["ns"] + registry = create_registry_validate_workload(p_client, ns, allns=True) + + # Create and validate workload in a new namespace + new_ns = create_ns(c_client, cluster, project) + create_validate_workload(p_client, new_ns) + delete_registry(p_client, registry) + + +def test_delete_registry_all_namespace(): + p_client = namespace["p_client"] + c_client = namespace["c_client"] + cluster = namespace["cluster"] + project = namespace["project"] + ns = namespace["ns"] + new_ns = create_ns(c_client, cluster, project) + + registry = create_registry_validate_workload(p_client, ns, allns=True) + delete_registry(p_client, registry) + + print("Verify workloads cannot be created in all the namespaces") + create_validate_workload_with_invalid_registry(p_client, ns) + create_validate_workload_with_invalid_registry(p_client, new_ns) + + +def test_delete_registry_single_namespace(): + p_client = namespace["p_client"] + ns = namespace["ns"] + + registry = create_registry_validate_workload(p_client, ns) + delete_registry(p_client, registry) + + print("Verify workload cannot be created in the namespace after registry") + "deletion" + create_validate_workload_with_invalid_registry(p_client, ns) + + +def test_edit_registry_single_namespace(): + p_client = namespace["p_client"] + ns = namespace["ns"] + + name = random_test_name("registry") + # Create registry with invalid username and password + registries = {REGISTRY: {"username": "testabc", + "password": "abcdef"}} + + registry = p_client.create_namespacedDockerCredential( + registries=registries, name=name, + namespaceId=ns.id) + + create_validate_workload_with_invalid_registry(p_client, ns) + + # Update registry with valid username and password + new_registries = {REGISTRY: {"username": REGISTRY_USER_NAME, + "password": REGISTRY_PASSWORD}} + p_client.update(registry, name=registry.name, + namespaceId=ns['name'], + registries=new_registries) + + # Validate workload after registry update + create_validate_workload(p_client, ns) + delete_registry(p_client, registry) + + +def test_edit_registry_all_namespace(): + p_client = namespace["p_client"] + c_client = namespace["c_client"] + cluster = namespace["cluster"] + project = namespace["project"] + ns = namespace["ns"] + + name = random_test_name("registry") + + # Create registry with invalid username and password + registries = {REGISTRY: {"username": "testabc", + "password": "abcdef"}} + + registry = p_client.create_dockerCredential( + registries=registries, name=name) + + create_validate_workload_with_invalid_registry(p_client, ns) + + # Update registry with correct username and password + new_registries = {REGISTRY: {"username": REGISTRY_USER_NAME, + "password": REGISTRY_PASSWORD}} + + p_client.update(registry, name=registry.name, + registries=new_registries) + + new_ns = create_ns(c_client, cluster, project) + + # Validate workload in all namespaces after registry update + create_validate_workload(p_client, ns) + create_validate_workload(p_client, new_ns) + delete_registry(p_client, registry) + + +def test_registry_cross_namespace_access(): + """ + This test creates two namespace and creates registry for first namespace. + It creates two workload in each namespace. + Validates workload created in first namespace comes up healthy but workload + in 2nd workspace doesn't become healthy. + """ + p_client = namespace["p_client"] + c_client = namespace["c_client"] + cluster = namespace["cluster"] + project = namespace["project"] + ns_1 = namespace["ns"] + ns_2 = create_ns(c_client, cluster, project) + registry = create_registry_validate_workload(p_client, ns_1) + create_validate_workload_with_invalid_registry(p_client, ns_2) + delete_registry(p_client, registry) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_create_single_namespace(role): + """ + Creates registry with given role to a single namespace + Runs only if RANCHER_TEST_RBAC is True in env. variable + @param role: User role in rancher eg. project owner, project member etc + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + registry = create_registry_validate_workload(p_client, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + else: + registry = create_registry_validate_workload(p_client, ns) + delete_registry(p_client, registry) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_create_all_namespace(role): + """ + Runs only if RANCHER_TEST_RBAC is True in env. variable. + Creates registry scoped all namespace and for + multiple role passed in parameter. + @param role: User role in rancher eg. project owner, project member etc + """ + c_client = namespace["c_client"] + cluster = namespace["cluster"] + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + registry = \ + create_registry_validate_workload(p_client, ns, allns=True) + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + else: + registry = create_registry_validate_workload(p_client, ns, allns=True) + + # Create and validate workload in a new namespace + new_ns = create_ns(c_client, cluster, project) + create_validate_workload(p_client, new_ns) + delete_registry(p_client, registry) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_delete_single_namespace(role): + """ + Runs only if RANCHER_TEST_RBAC is True in env. variable. + Creates a registry for single namespace, deploys a workload + and delete registry afterwards. + Validates the workload which has become invalid on registry deletion. + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(rbac_role_list[0]) + project = rbac_get_project() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + token = rbac_get_user_token_by_role(role) + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + + registry = create_registry_validate_workload(p_client_for_c_owner, ns) + + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + delete_registry(p_client, registry) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + delete_registry(p_client_for_c_owner, registry) + else: + delete_registry(p_client, registry) + + print("Verify workload cannot be created in the namespace after " + "registry deletion") + create_validate_workload_with_invalid_registry(p_client, ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_delete_all_namespace(role): + """ + Runs only if RANCHER_TEST_RBAC is True in env. variable. + Creates a registry scoped for all namespace, deploys a workload + and delete registry afterwards. + Validates the workload which has become invalid on registry deletion. + @param role: User role in rancher eg. project owner, project member etc + """ + c_client = namespace["c_client"] + cluster = namespace["cluster"] + c_owner_token = rbac_get_user_token_by_role(rbac_role_list[0]) + project = rbac_get_project() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(project, token) + ns = rbac_get_namespace() + new_ns = create_ns(c_client, cluster, project) + registry = \ + create_registry_validate_workload(p_client_for_c_owner, ns) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + delete_registry(p_client, registry) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + delete_registry(p_client_for_c_owner, registry) + else: + delete_registry(p_client, registry) + + print("Verify workloads cannot be created in all the namespaces") + create_validate_workload_with_invalid_registry(p_client, ns) + create_validate_workload_with_invalid_registry(p_client, new_ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_edit_single_namespace(role): + """ + Runs only if RANCHER_TEST_RBAC is True in env. variable. + Creates registry with invalid credential for single namespace, + deploys workload with invalid registry and validate the workload + is not up. + Update the registry with correct credential and validates workload. + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(rbac_role_list[0]) + project = rbac_get_project() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + token = rbac_get_user_token_by_role(role) + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + + name = random_test_name("registry") + # registry with invalid username and password + registries = {REGISTRY: {"username": "testabc", + "password": "abcdef"}} + # registry with valid username and password + new_registries = {REGISTRY: {"username": REGISTRY_USER_NAME, + "password": REGISTRY_PASSWORD}} + # Create registry with wrong credentials + registry = p_client_for_c_owner.create_namespacedDockerCredential( + registries=registries, name=name, namespaceId=ns.id) + + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.update(registry, name=registry.name, + namespaceId=ns['name'], + registries=new_registries) + assert e.value.error.status == 404 + assert e.value.error.code == 'NotFound' + delete_registry(p_client_for_c_owner, registry) + else: + create_validate_workload_with_invalid_registry(p_client, ns) + # Update registry with valid username and password + p_client.update(registry, name=registry.name, + namespaceId=ns['name'], + registries=new_registries) + + # Validate workload after registry update + create_validate_workload(p_client, ns) + delete_registry(p_client, registry) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_registry_edit_all_namespace(role): + """ + Runs only if RANCHER_TEST_RBAC is True in env. variable. + Creates registry with invalid credential scoped for all namespace, + deploys workload with invalid registry and validate the workload + is not up. + Update the registry with correct credential and validates workload. + @param role: User role in rancher eg. project owner, project member etc + @param role: + """ + c_client = namespace["c_client"] + cluster = namespace["cluster"] + c_owner_token = rbac_get_user_token_by_role(rbac_role_list[0]) + project = rbac_get_project() + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, token) + ns = rbac_get_namespace() + + name = random_test_name("registry") + registries = {REGISTRY: {"username": "testabc", + "password": "abcdef"}} + new_registries = {REGISTRY: {"username": REGISTRY_USER_NAME, + "password": REGISTRY_PASSWORD}} + # Create registry with invalid username and password + registry = p_client_for_c_owner.create_dockerCredential( + registries=registries, name=name) + + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.update(registry, name=registry.name, + registries=new_registries) + assert e.value.error.status == 404 + assert e.value.error.code == 'NotFound' + delete_registry(p_client_for_c_owner, registry) + else: + create_validate_workload_with_invalid_registry(p_client, ns) + # Update registry with correct username and password + p_client.update(registry, name=registry.name, + registries=new_registries) + + new_ns = create_ns(c_client, cluster, project) + + # Validate workload in all namespaces after registry update + create_validate_workload(p_client, ns) + create_validate_workload(p_client, new_ns) + delete_registry(p_client_for_c_owner, registry) + + +@if_test_rbac +def test_rbac_registry_cross_project_access(): + """ + Get project1 and namespace1 from project owner role + Creates project2 and namespace2 using same user. + Creates registry in project1 and try to creates workload + in project2. + """ + cluster = namespace["cluster"] + token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + + project_2, ns_2 = create_project_and_ns(token, cluster, "testproject2") + p2_client = get_project_client_for_token(project_2, token) + # Create registry in project 1 + registry = create_registry_validate_workload(p_client, ns, allns=True) + # Create workload in project 2 and validate + create_validate_workload_with_invalid_registry(p2_client, ns_2) + delete_registry(p_client, registry) + p_client.delete(project_2) + + +def delete_registry(client, registry): + + c_client = namespace["c_client"] + project = namespace["project"] + print("Project ID") + print(project.id) + registryname = registry.name + client.delete(registry) + time.sleep(5) + # Sleep to allow for the registry to be deleted + print("Registry list after deleting registry") + registrydict = client.list_dockerCredential(name=registryname).data + print(registrydict) + assert len(registrydict) == 0, "Unable to delete registry" + + namespacedict = c_client.list_namespace(projectId=project.id).data + print("List of namespaces") + print(namespacedict) + len_namespace = len(namespacedict) + namespaceData = namespacedict + + # Registry is essentially a secret, deleting the registry should delete + # the secret. Verify secret is deleted by "kubectl get secret" command + # for each of the namespaces + for i in range(0, len_namespace): + ns_name = namespaceData[i]['name'] + print(i, ns_name) + + command = " get secret " + registryname + " --namespace=" + ns_name + print("Command to obtain the secret") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + + print("Verify that the secret does not exist " + "and the error code returned is non zero ") + assert result != 0, "Error code is 0!" + + +def create_registry_validate_workload(p_client, ns=None, allns=False): + + name = random_test_name("registry") + print(REGISTRY_USER_NAME) + print(REGISTRY_PASSWORD) + registries = {REGISTRY: {"username": REGISTRY_USER_NAME, + "password": REGISTRY_PASSWORD}} + if allns: + registry = p_client.create_dockerCredential( + registries=registries, name=name) + else: + registry = p_client.create_namespacedDockerCredential( + registries=registries, name=name, + namespaceId=ns.id) + + create_validate_workload(p_client, ns) + return registry + + +def create_workload(p_client, ns): + workload_name = random_test_name("newtestwk") + con = [{"name": "test", + "image": TEST_CLIENT_IMAGE, + "runAsNonRoot": False, + "stdin": True, + "imagePullPolicy": "Always" + }] + workload = p_client.create_workload(name=workload_name, + containers=con, + namespaceId=ns.id) + return workload + + +def create_validate_workload(p_client, ns): + + workload = create_workload(p_client, ns) + workload = p_client.reload(workload) + + validate_workload(p_client, workload, "deployment", ns.name) + p_client.delete(workload) + + +def create_validate_workload_with_invalid_registry(p_client, ns): + + workload = create_workload(p_client, ns) + # Validate workload fails to come up active + validate_wl_fail_to_pullimage(p_client, workload) + workload = p_client.reload(workload) + print(workload) + assert workload.state != "active", "Invalid workload came up active!" + p_client.delete(workload) + + +def validate_wl_fail_to_pullimage(client, workload, timeout=DEFAULT_TIMEOUT): + """ + This method checks if workload is failing to pull image + @param client: Project client object + @param workload: Workload to test on + @param timeout: Max time of waiting for failure + """ + time.sleep(2) + start = time.time() + pods = client.list_pod(workloadId=workload.id).data + assert len(pods) != 0, "No pods in workload - {}".format(workload) + message = pods[0].containers[0].transitioningMessage + + while 'ImagePullBackOff:' not in message: + if time.time() - start > timeout: + raise AssertionError( + "Timed out waiting for workload to get " + "'ImagePullBackOff' error") + time.sleep(1) + pods = client.list_pod(workloadId=workload.id).data + assert len(pods) != 0, "No pods in workload - {}".format(workload) + message = pods[0].containers[0].transitioningMessage + print("{} - fails to pull image".format(workload)) + + +@ pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testregistry") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke2_airgap.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke2_airgap.py new file mode 100644 index 0000000..30cd88f --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke2_airgap.py @@ -0,0 +1,165 @@ +import os +from lib.aws import AWS_USER +from .common import AmazonWebServices +from .test_airgap import (AG_HOST_NAME, NUMBER_OF_INSTANCES, TARBALL_TYPE, + get_bastion_node, prepare_registries_mirror_on_node, + run_command_on_airgap_node, deploy_airgap_cluster, + prepare_private_registry, copy_certs_to_node, + trust_certs_on_node, add_tarball_to_node, + optionally_add_cluster_to_rancher) + +RANCHER_RKE2_VERSION = os.environ.get("RANCHER_RKE2_VERSION", "") +RKE2_SERVER_OPTIONS = os.environ.get("RKE2_SERVER_OPTIONS", "") +RKE2_AGENT_OPTIONS = os.environ.get("RKE2_AGENT_OPTIONS", "") + + +def test_deploy_airgap_rke2_all(): + reg_bastion_node = get_bastion_node(auth=True) + noauth_bastion_node = get_bastion_node(auth=False) + add_rke2_tarball_to_bastion(noauth_bastion_node, RANCHER_RKE2_VERSION) + prepare_private_registry(noauth_bastion_node, RANCHER_RKE2_VERSION) + prepare_private_registry(reg_bastion_node, RANCHER_RKE2_VERSION) + + ag_nodes = prepare_airgap_rke2(noauth_bastion_node, NUMBER_OF_INSTANCES, + 'tarball+mirror+system-default') + for ag_node in ag_nodes: + copy_certs_to_node(reg_bastion_node, ag_node) + prepare_registries_mirror_on_node(reg_bastion_node, ag_node, 'rke2') + + server_ops = RKE2_SERVER_OPTIONS + " --system-default-registry={}".format( + noauth_bastion_node.host_name) + agent_ops = RKE2_AGENT_OPTIONS + " --system-default-registry={}".format( + noauth_bastion_node.host_name) + deploy_airgap_cluster(noauth_bastion_node, ag_nodes, "rke2", + server_ops, agent_ops) + optionally_add_cluster_to_rancher(noauth_bastion_node, ag_nodes) + + +def test_deploy_airgap_rke2_system_default_registry(): + bastion_node = get_bastion_node(auth=False) + prepare_private_registry(bastion_node, RANCHER_RKE2_VERSION) + ag_nodes = prepare_airgap_rke2(bastion_node, NUMBER_OF_INSTANCES, + 'system_default_registry') + server_ops = RKE2_SERVER_OPTIONS + " --system-default-registry={}".format( + bastion_node.host_name) + agent_ops = RKE2_AGENT_OPTIONS + " --system-default-registry={}".format( + bastion_node.host_name) + deploy_airgap_cluster(bastion_node, ag_nodes, "rke2", + server_ops, agent_ops) + + +def test_deploy_airgap_rke2_private_registry(): + bastion_node = get_bastion_node(auth=True) + prepare_private_registry(bastion_node, RANCHER_RKE2_VERSION) + ag_nodes = prepare_airgap_rke2(bastion_node, NUMBER_OF_INSTANCES, + 'private_registry') + deploy_airgap_cluster(bastion_node, ag_nodes, "rke2", + RKE2_SERVER_OPTIONS, RKE2_AGENT_OPTIONS) + optionally_add_cluster_to_rancher(bastion_node, ag_nodes) + + +def test_deploy_airgap_rke2_tarball(): + bastion_node = get_bastion_node() + add_rke2_tarball_to_bastion(bastion_node, RANCHER_RKE2_VERSION) + ag_nodes = prepare_airgap_rke2( + bastion_node, NUMBER_OF_INSTANCES, 'tarball') + deploy_airgap_cluster(bastion_node, ag_nodes, "rke2", + RKE2_SERVER_OPTIONS, RKE2_AGENT_OPTIONS) + + +def add_rke2_tarball_to_bastion(bastion_node, rke2_version): + get_tarball_command = \ + 'wget -O rke2-airgap-images.{1} https://github.com/rancher/rke2/' \ + 'releases/download/{0}/rke2-images.linux-amd64.{1} && ' \ + 'wget -O rke2 https://github.com/rancher/rke2/releases/' \ + 'download/{0}/rke2.linux-amd64'.format(rke2_version, TARBALL_TYPE) + bastion_node.execute_command(get_tarball_command) + if 'calico' in RKE2_SERVER_OPTIONS: + get_calico_tarball_command = \ + 'wget -O rke2-airgap-images-calico.{1} ' \ + 'https://github.com/rancher/rke2/releases/download/{0}/' \ + 'rke2-images-calico.linux-amd64.{1}'.format(rke2_version, + TARBALL_TYPE) + bastion_node.execute_command(get_calico_tarball_command) + if 'cilium' in RKE2_SERVER_OPTIONS: + get_cilium_tarball_command = \ + 'wget -O rke2-airgap-images-cilium.{1} ' \ + 'https://github.com/rancher/rke2/releases/download/{0}/' \ + 'rke2-images-cilium.linux-amd64.{1}'.format(rke2_version, + TARBALL_TYPE) + bastion_node.execute_command(get_cilium_tarball_command) + if 'multus' in RKE2_SERVER_OPTIONS: + get_multus_tarball_command = \ + 'wget -O rke2-airgap-images-multus.{1} ' \ + 'https://github.com/rancher/rke2/releases/download/{0}/' \ + 'rke2-images-multus.linux-amd64.{1}'.format(rke2_version, + TARBALL_TYPE) + bastion_node.execute_command(get_multus_tarball_command) + + +def prepare_airgap_rke2(bastion_node, number_of_nodes, method): + node_name = AG_HOST_NAME + "-rke2-airgap" + # Create Airgap Node in AWS + ag_nodes = AmazonWebServices().create_multiple_nodes( + number_of_nodes, node_name, public_ip=False) + + for num, ag_node in enumerate(ag_nodes): + # Copy relevant rke2 files to airgapped node + ag_node_copy_files = \ + 'scp -i "{0}.pem" -o StrictHostKeyChecking=no ./rke2 ' \ + '{1}@{2}:~/rke2'.format(bastion_node.ssh_key_name, AWS_USER, + ag_node.private_ip_address) + bastion_node.execute_command(ag_node_copy_files) + + ag_node_make_executable = \ + 'sudo mv ./rke2 /usr/local/bin/rke2 && ' \ + 'sudo chmod +x /usr/local/bin/rke2' + run_command_on_airgap_node(bastion_node, ag_node, + ag_node_make_executable) + + if method == 'private_registry': + copy_certs_to_node(bastion_node, ag_node) + prepare_registries_mirror_on_node(bastion_node, ag_node, 'rke2') + elif method == 'system_default_registry': + copy_certs_to_node(bastion_node, ag_node) + trust_certs_on_node(bastion_node, ag_node) + elif method == 'tarball+mirror': + copy_certs_to_node(bastion_node, ag_node) + prepare_registries_mirror_on_node(bastion_node, ag_node, 'rke2') + else: + copy_certs_to_node(bastion_node, ag_node) + trust_certs_on_node(bastion_node, ag_node) + if 'tarball' in method: + add_tarball_to_node(bastion_node, ag_node, + 'rke2-airgap-images.{}'.format(TARBALL_TYPE), + 'rke2') + if 'calico' in RKE2_SERVER_OPTIONS: + add_tarball_to_node( + bastion_node, ag_node, + 'rke2-airgap-images-calico.{}'.format(TARBALL_TYPE), + 'rke2') + if 'cilium' in RKE2_SERVER_OPTIONS: + add_tarball_to_node( + bastion_node, ag_node, + 'rke2-airgap-images-cilium.{}'.format(TARBALL_TYPE), + 'rke2') + if 'multus' in RKE2_SERVER_OPTIONS: + add_tarball_to_node( + bastion_node, ag_node, + 'rke2-airgap-images-multus.{}'.format(TARBALL_TYPE), + 'rke2') + + print("Airgapped RKE2 Instance Details:\nNAME: {}-{}\nPRIVATE IP: {}\n" + "".format(node_name, num, ag_node.private_ip_address)) + + assert len(ag_nodes) == NUMBER_OF_INSTANCES + print( + '{} airgapped rke2 instance(s) created.\n' + 'Connect to these and run commands by connecting to bastion node, ' + 'then connecting to these:\n' + 'ssh -i {}.pem {}@NODE_PRIVATE_IP'.format( + NUMBER_OF_INSTANCES, bastion_node.ssh_key_name, AWS_USER)) + for ag_node in ag_nodes: + assert ag_node.private_ip_address is not None + assert ag_node.public_ip_address is None + return ag_nodes diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke_cluster_provisioning.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke_cluster_provisioning.py new file mode 100644 index 0000000..99c94e7 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_rke_cluster_provisioning.py @@ -0,0 +1,1212 @@ +from threading import Thread +import pytest +from .common import * # NOQA +from rancher import ApiError + +K8S_VERSION = os.environ.get('RANCHER_K8S_VERSION', "") +K8S_VERSION_UPGRADE = os.environ.get('RANCHER_K8S_VERSION_UPGRADE', "") +POD_SECURITY_POLICY_TEMPLATE = \ + os.environ.get('RANCHER_POD_SECURITY_POLICY_TEMPLATE', + "restricted") +DO_ACCESSKEY = os.environ.get('DO_ACCESSKEY', "None") +AZURE_SUBSCRIPTION_ID = os.environ.get("AZURE_SUBSCRIPTION_ID") +AZURE_CLIENT_ID = os.environ.get("AZURE_CLIENT_ID") +AZURE_CLIENT_SECRET = os.environ.get("AZURE_CLIENT_SECRET") +AZURE_TENANT_ID = os.environ.get("AZURE_TENANT_ID") +worker_count = int(os.environ.get('RANCHER_STRESS_TEST_WORKER_COUNT', 1)) +HOST_NAME = os.environ.get('RANCHER_HOST_NAME', "testcustom") +engine_install_url = "https://releases.rancher.com/install-docker/26.1.sh" + +rke_config = { + "addonJobTimeout": 30, + "authentication": + {"strategy": "x509", + "type": "authnConfig"}, + "ignoreDockerVersion": True, + "ingress": + {"provider": "nginx", + "type": "ingressConfig"}, + "monitoring": + {"provider": "metrics-server", + "type": "monitoringConfig"}, + "network": + {"plugin": "canal", + "type": "networkConfig", + "options": {"flannel_backend_type": "vxlan"}}, + "services": { + "etcd": { + "extraArgs": + {"heartbeat-interval": 500, + "election-timeout": 5000}, + "snapshot": False, + "backupConfig": + {"intervalHours": 12, "retention": 6, "type": "backupConfig"}, + "creation": "12h", + "retention": "72h", + "type": "etcdService"}, + "kubeApi": { + "alwaysPullImages": False, + "podSecurityPolicy": False, + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService"}}, + "sshAgentAuth": False} + +rke_config_windows = { + "addonJobTimeout": 30, + "authentication": + {"strategy": "x509", + "type": "authnConfig"}, + "ignoreDockerVersion": True, + "ingress": + {"provider": "nginx", + "type": "ingressConfig"}, + "monitoring": + {"provider": "metrics-server", + "type": "monitoringConfig"}, + "network": { + "mtu": 0, + "plugin": "flannel", + "type": "networkConfig", + "options": { + "flannel_backend_type": "vxlan", + "flannel_backend_port": "4789", + "flannel_backend_vni": "4096" + } + }, + "services": { + "etcd": { + "extraArgs": + {"heartbeat-interval": 500, + "election-timeout": 5000}, + "snapshot": False, + "backupConfig": + {"intervalHours": 12, "retention": 6, "type": "backupConfig"}, + "creation": "12h", + "retention": "72h", + "type": "etcdService"}, + "kubeApi": { + "alwaysPullImages": False, + "podSecurityPolicy": False, + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService"}}, + "sshAgentAuth": False} + +rke_config_windows_host_gw = { + "addonJobTimeout": 30, + "authentication": + {"strategy": "x509", + "type": "authnConfig"}, + "ignoreDockerVersion": True, + "ingress": + {"provider": "nginx", + "type": "ingressConfig"}, + "monitoring": + {"provider": "metrics-server", + "type": "monitoringConfig"}, + "network": { + "mtu": 0, + "plugin": "flannel", + "type": "networkConfig", + "options": { + "flannel_backend_type": "host-gw" + } + }, + "services": { + "etcd": { + "extraArgs": + {"heartbeat-interval": 500, + "election-timeout": 5000}, + "snapshot": False, + "backupConfig": + {"intervalHours": 12, "retention": 6, "type": "backupConfig"}, + "creation": "12h", + "retention": "72h", + "type": "etcdService"}, + "kubeApi": { + "alwaysPullImages": False, + "podSecurityPolicy": False, + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService"}}, + "sshAgentAuth": False} + +rke_config_cis_1_4 = { + "addonJobTimeout": 30, + "authentication": + {"strategy": "x509", + "type": "authnConfig"}, + "ignoreDockerVersion": True, + "ingress": + {"provider": "nginx", + "type": "ingressConfig"}, + "monitoring": + {"provider": "metrics-server", + "type": "monitoringConfig"}, + "network": + {"plugin": "canal", + "type": "networkConfig", + "options": {"flannel_backend_type": "vxlan"}}, + "services": { + "etcd": { + "extraArgs": + {"heartbeat-interval": 500, + "election-timeout": 5000}, + "snapshot": False, + "backupConfig": + {"intervalHours": 12, "retention": 6, "type": "backupConfig"}, + "creation": "12h", + "retention": "72h", + "type": "etcdService", + "gid": 1001, + "uid": 1001}, + "kubeApi": { + "alwaysPullImages": True, + "auditLog": + {"enabled": True}, + "eventRateLimit": + {"enabled": True}, + "extraArgs": + {"anonymous-auth": False, + "enable-admission-plugins": "ServiceAccount," + "NamespaceLifecycle," + "LimitRanger," + "PersistentVolumeLabel," + "DefaultStorageClass," + "ResourceQuota," + "DefaultTolerationSeconds," + "AlwaysPullImages," + "DenyEscalatingExec," + "NodeRestriction," + "PodSecurityPolicy," + "MutatingAdmissionWebhook," + "ValidatingAdmissionWebhook," + "Priority," + "TaintNodesByCondition," + "PersistentVolumeClaimResize," + "EventRateLimit", + "profiling": False, + "service-account-lookup": True, + "tls-cipher-suites": "TLS_ECDHE_ECDSA_WITH_AES_" + "128_GCM_SHA256," + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305," + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384," + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305," + "TLS_ECDHE_ECDSA_WITH_AES_" + "256_GCM_SHA384," + "TLS_RSA_WITH_AES_256_GCM_SHA384," + "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + "extraBinds": ["/opt/kubernetes:/opt/kubernetes"], + "podSecurityPolicy": True, + "secretsEncryptionConfig": + {"enabled": True}, + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService"}, + "kubeController": { + "extraArgs": { + "address": "127.0.0.1", + "feature-gates": "RotateKubeletServerCertificate=true", + "profiling": "false", + "terminated-pod-gc-threshold": "1000" + }, + }, + "kubelet": { + "extraArgs": { + "protect-kernel-defaults": True, + "feature-gates": "RotateKubeletServerCertificate=true" + }, + "generateServingCertificate": True + }, + "scheduler": { + "extraArgs": { + "address": "127.0.0.1", + "profiling": False + } + }}, + "sshAgentAuth": False} + +rke_config_cis_1_5 = { + "addonJobTimeout": 30, + "ignoreDockerVersion": True, + "services": { + "etcd": { + "gid": 52034, + "uid": 52034, + "type": "etcdService"}, + "kubeApi": { + "podSecurityPolicy": True, + "secretsEncryptionConfig": + {"enabled": True}, + "auditLog": + {"enabled": True}, + "eventRateLimit": + {"enabled": True}, + "type": "kubeAPIService"}, + "kubeController": { + "extraArgs": { + "feature-gates": "RotateKubeletServerCertificate=true", + }, + }, + "scheduler": { + "image": "", + "extraArgs": {}, + "extraBinds": [], + "extraEnv": [] + }, + "kubelet": { + "generateServingCertificate": True, + "extraArgs": { + "feature-gates": "RotateKubeletServerCertificate=true", + "protect-kernel-defaults": True, + "tls-cipher-suites": "TLS_ECDHE_ECDSA_WITH_AES_" + "128_GCM_SHA256," + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305," + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384," + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305," + "TLS_ECDHE_ECDSA_WITH_AES_" + "256_GCM_SHA384," + "TLS_RSA_WITH_AES_256_GCM_SHA384," + "TLS_RSA_WITH_AES_128_GCM_SHA256" + }, + "extraBinds": [], + "extraEnv": [], + "clusterDomain": "", + "infraContainerImage": "", + "clusterDnsServer": "", + "failSwapOn": False + }, + }, + "network": + {"plugin": "", + "options": {}, + "mtu": 0, + "nodeSelector": {}}, + "authentication": { + "strategy": "", + "sans": [], + "webhook": None, + }, + "sshAgentAuth": False, + "windowsPreferredCluster": False +} + +if K8S_VERSION != "": + rke_config["kubernetesVersion"] = K8S_VERSION + rke_config_cis_1_4["kubernetesVersion"] = K8S_VERSION + rke_config_cis_1_5["kubernetesVersion"] = K8S_VERSION + +rke_config_windows_host_gw_aws_provider = rke_config_windows_host_gw.copy() +rke_config_windows_host_gw_aws_provider["cloudProvider"] = {"name": "aws", + "type": "cloudProvider", + "awsCloudProvider": + {"type": "awsCloudProvider"}} + +rke_config_aws_provider = rke_config.copy() +rke_config_aws_provider["cloudProvider"] = {"name": "aws", + "type": "cloudProvider", + "awsCloudProvider": + {"type": "awsCloudProvider"}} + +rke_config_aws_provider_2 = rke_config.copy() +rke_config_aws_provider_2["cloudProvider"] = {"name": "aws", + "type": "cloudProvider"} + +rke_config_azure_provider = rke_config.copy() +rke_config_azure_provider["cloudProvider"] = { + "name": "azure", + "azureCloudProvider": { + "aadClientId": AZURE_CLIENT_ID, + "aadClientSecret": AZURE_CLIENT_SECRET, + "subscriptionId": AZURE_SUBSCRIPTION_ID, + "tenantId": AZURE_TENANT_ID}} + +if_stress_enabled = pytest.mark.skipif( + not os.environ.get('RANCHER_STRESS_TEST_WORKER_COUNT'), + reason='Stress test not enabled') + +if_test_edit_cluster = pytest.mark.skipif( + CLUSTER_NAME == "", + reason='Edit cluster tests not enabled') + + +def test_cis_complaint(): + # rke_config_cis + node_roles = [ + ["controlplane"], ["controlplane"], + ["etcd"], ["etcd"], ["etcd"], + ["worker"], ["worker"], ["worker"] + ] + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + len(node_roles), random_test_name(HOST_NAME)) + rke_config_cis = get_cis_rke_config() + client = get_admin_client() + cluster = client.create_cluster( + name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config_cis, + enableNetworkPolicy=True, + defaultPodSecurityPolicyTemplateId=POD_SECURITY_POLICY_TEMPLATE) + assert cluster.state == "provisioning" + configure_cis_requirements(aws_nodes, + CIS_SCAN_PROFILE, + node_roles, + client, + cluster + ) + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_az_host_1(node_template_az): + validate_rke_dm_host_1(node_template_az, rke_config) + + +def test_rke_az_host_2(node_template_az): + validate_rke_dm_host_2(node_template_az, rke_config) + + +def test_rke_az_host_3(node_template_az): + validate_rke_dm_host_3(node_template_az, rke_config) + + +def test_rke_az_host_4(node_template_az): + validate_rke_dm_host_4(node_template_az, rke_config) + + +def test_rke_az_host_with_provider_1(node_template_az): + validate_rke_dm_host_1(node_template_az, rke_config_azure_provider) + + +def test_rke_az_host_with_provider_2(node_template_az): + validate_rke_dm_host_2(node_template_az, rke_config_azure_provider) + + +@pytest.mark.skip(reason="https://github.com/rancher/qa-tasks/issues/318") +def test_rke_do_host_1(node_template_do): + validate_rke_dm_host_1(node_template_do, rke_config) + + +@pytest.mark.skip(reason="https://github.com/rancher/qa-tasks/issues/318") +def test_rke_do_host_2(node_template_do): + validate_rke_dm_host_2(node_template_do, rke_config) + + +@pytest.mark.skip(reason="https://github.com/rancher/qa-tasks/issues/318") +def test_rke_do_host_3(node_template_do): + validate_rke_dm_host_3(node_template_do, rke_config) + + +@pytest.mark.skip(reason="https://github.com/rancher/qa-tasks/issues/318") +def test_rke_do_host_4(node_template_do): + validate_rke_dm_host_4(node_template_do, rke_config) + + +def test_rke_linode_host_1(node_template_linode): + validate_rke_dm_host_1(node_template_linode, rke_config) + + +def test_rke_linode_host_2(node_template_linode): + validate_rke_dm_host_2(node_template_linode, rke_config) + + +def test_rke_linode_host_3(node_template_linode): + validate_rke_dm_host_3(node_template_linode, rke_config) + + +def test_rke_ec2_host_1(node_template_ec2): + validate_rke_dm_host_1(node_template_ec2, rke_config) + + +def test_rke_ec2_host_2(node_template_ec2): + validate_rke_dm_host_2(node_template_ec2, rke_config) + + +def test_rke_ec2_host_3(node_template_ec2): + validate_rke_dm_host_3(node_template_ec2, rke_config) + + +def test_rke_ec2_host_with_aws_provider_1(node_template_ec2_with_provider): + validate_rke_dm_host_1(node_template_ec2_with_provider, + rke_config_aws_provider) + + +def test_rke_ec2_host_with_aws_provider_2(node_template_ec2_with_provider): + validate_rke_dm_host_2(node_template_ec2_with_provider, + rke_config_aws_provider) + + +def test_rke_ec2_host_with_aws_provider_3(node_template_ec2_with_provider): + validate_rke_dm_host_1(node_template_ec2_with_provider, + rke_config_aws_provider_2) + + +def test_rke_ec2_host_4(node_template_ec2): + validate_rke_dm_host_4(node_template_ec2, rke_config) + + +def test_rke_custom_host_1(): + node_roles = [["worker", "controlplane", "etcd"]] + cluster, aws_nodes = create_and_validate_custom_host(node_roles) + cluster_cleanup(get_user_client(), cluster, aws_nodes) + + +def test_rke_custom_host_2(): + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + cluster, aws_nodes = create_and_validate_custom_host(node_roles) + cluster_cleanup(get_user_client(), cluster, aws_nodes) + + +def test_rke_custom_host_3(): + node_roles = [ + ["controlplane"], ["controlplane"], + ["etcd"], ["etcd"], ["etcd"], + ["worker"], ["worker"], ["worker"] + ] + cluster, aws_nodes = create_and_validate_custom_host(node_roles) + cluster_cleanup(get_user_client(), cluster, aws_nodes) + + +def test_rke_custom_host_4(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 8, random_test_name(HOST_NAME)) + node_roles = [ + {"roles": ["controlplane"], + "nodes":[aws_nodes[0], aws_nodes[1]]}, + {"roles": ["etcd"], + "nodes": [aws_nodes[2], aws_nodes[3], aws_nodes[4]]}, + {"roles": ["worker"], + "nodes": [aws_nodes[5], aws_nodes[6], aws_nodes[7]]} + ] + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + delay = 120 + host_threads = [] + for node_role in node_roles: + host_thread = Thread(target=register_host_after_delay, + args=(client, cluster, node_role, delay)) + host_threads.append(host_thread) + host_thread.start() + time.sleep(30) + for host_thread in host_threads: + host_thread.join() + cluster = validate_cluster(client, cluster, + check_intermediate_state=False, + k8s_version=K8S_VERSION) + cluster_cleanup(client, cluster, aws_nodes) + + +@if_stress_enabled +def test_rke_custom_host_stress(): + aws_nodes = AmazonWebServices().create_multiple_nodes( + worker_count + 4, random_test_name("teststress")) + + node_roles = [["controlplane"], ["etcd"], ["etcd"], ["etcd"]] + worker_role = ["worker"] + for int in range(0, worker_count): + node_roles.append(worker_role) + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + i += 1 + cluster = validate_cluster(client, cluster, + check_intermediate_state=False) + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_custom_host_etcd_plane_changes(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 7, random_test_name(HOST_NAME)) + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for i in range(0, 5): + aws_node = aws_nodes[i] + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + cluster = validate_cluster(client, cluster) + etcd_nodes = get_role_nodes(cluster, "etcd") + assert len(etcd_nodes) == 1 + + # Add 1 more etcd node + aws_node = aws_nodes[5] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["etcd"], aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 6) + validate_cluster(client, cluster, intermediate_state="updating") + + # Add 1 more etcd node + aws_node = aws_nodes[6] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["etcd"], aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 7) + validate_cluster(client, cluster, intermediate_state="updating") + + # Delete the first etcd node + client.delete(etcd_nodes[0]) + validate_cluster(client, cluster, intermediate_state="updating") + + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_custom_host_etcd_plane_changes_1(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 7, random_test_name(HOST_NAME)) + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for i in range(0, 5): + aws_node = aws_nodes[i] + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, + node_roles[i], aws_node) + aws_node.execute_command(docker_run_cmd) + cluster = validate_cluster(client, cluster) + etcd_nodes = get_role_nodes(cluster, "etcd") + assert len(etcd_nodes) == 1 + + # Add 2 more etcd node + aws_node = aws_nodes[5] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["etcd"], aws_node) + aws_node.execute_command(docker_run_cmd) + + aws_node = aws_nodes[6] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["etcd"], aws_node) + aws_node.execute_command(docker_run_cmd) + + wait_for_cluster_node_count(client, cluster, 7) + validate_cluster(client, cluster, intermediate_state="updating") + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_custom_host_control_plane_changes(): + aws_nodes = \ + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 6, random_test_name(HOST_NAME)) + + node_roles = [["controlplane"], ["etcd"], + ["worker"], ["worker"], ["worker"]] + + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for i in range(0, 5): + aws_node = aws_nodes[i] + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, + node_roles[i], aws_node) + aws_node.execute_command(docker_run_cmd) + cluster = validate_cluster(client, cluster) + control_nodes = get_role_nodes(cluster, "control") + assert len(control_nodes) == 1 + + # Add 1 more control node + aws_node = aws_nodes[5] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["controlplane"], + aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 6) + validate_cluster(client, cluster, intermediate_state="updating") + + # Delete the first control node + client.delete(control_nodes[0]) + validate_cluster(client, cluster, intermediate_state="updating") + + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_custom_host_worker_plane_changes(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 4, random_test_name(HOST_NAME)) + node_roles = [["controlplane"], ["etcd"], + ["worker"]] + + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for i in range(0, 3): + aws_node = aws_nodes[i] + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + cluster = validate_cluster(client, cluster) + worker_nodes = get_role_nodes(cluster, "worker") + assert len(worker_nodes) == 1 + + # Add 1 more worker node + aws_node = aws_nodes[3] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["worker"], aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 4) + validate_cluster(client, cluster, check_intermediate_state=False) + + # Delete the first worker node + client.delete(worker_nodes[0]) + validate_cluster(client, cluster, check_intermediate_state=False) + + cluster_cleanup(client, cluster, aws_nodes) + + +def test_rke_custom_host_control_node_power_down(): + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + 5, random_test_name(HOST_NAME)) + node_roles = [["controlplane"], ["etcd"], + ["worker"]] + + client = get_user_client() + cluster = client.create_cluster(name=evaluate_clustername(), + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=rke_config) + assert cluster.state == "provisioning" + i = 0 + for i in range(0, 3): + aws_node = aws_nodes[i] + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + aws_node.execute_command(docker_run_cmd) + cluster = validate_cluster(client, cluster) + control_nodes = get_role_nodes(cluster, "control") + assert len(control_nodes) == 1 + + # Add 1 more control node + aws_node = aws_nodes[3] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["controlplane"], + aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 4) + validate_cluster(client, cluster, check_intermediate_state=False) + + # Power Down the first control node + aws_control_node = aws_nodes[0] + AmazonWebServices().stop_node(aws_control_node, wait_for_stopped=True) + control_node = control_nodes[0] + wait_for_node_status(client, control_node, "unavailable") + validate_cluster( + client, cluster, + check_intermediate_state=False, + nodes_not_in_active_state=[control_node.requestedHostname]) + + # Add 1 more worker node + aws_node = aws_nodes[4] + docker_run_cmd = get_custom_host_registration_cmd(client, cluster, + ["worker"], aws_node) + aws_node.execute_command(docker_run_cmd) + wait_for_cluster_node_count(client, cluster, 4) + validate_cluster(client, cluster, check_intermediate_state=False) + + cluster_cleanup(client, cluster, aws_nodes) + + +@if_test_edit_cluster +def test_edit_cluster_k8s_version(): + client = get_user_client() + clusters = client.list_cluster(name=evaluate_clustername()).data + assert len(clusters) == 1 + cluster = clusters[0] + rke_config = cluster.rancherKubernetesEngineConfig + rke_updated_config = rke_config.copy() + rke_updated_config["kubernetesVersion"] = K8S_VERSION_UPGRADE + cluster = client.update(cluster, + name=cluster.name, + rancherKubernetesEngineConfig=rke_updated_config) + cluster = validate_cluster(client, cluster, intermediate_state="updating", + k8s_version=K8S_VERSION_UPGRADE) + + +def test_delete_cluster(): + client = get_user_client() + cluster = get_cluster_by_name(client, CLUSTER_NAME) + delete_cluster(client, cluster) + + +def validate_rke_dm_host_1(node_template, + rancherKubernetesEngineConfig=rke_config, + attemptDelete=True): + client = get_user_client() + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "controlPlane": True, + "etcd": True, + "worker": True, + "quantity": 1, + "clusterId": None} + nodes.append(node) + cluster, node_pools = create_and_validate_cluster( + client, nodes, rancherKubernetesEngineConfig) + if attemptDelete: + cluster_cleanup(client, cluster) + else: + return cluster, node_pools + + +def validate_rke_dm_host_2(node_template, + rancherKubernetesEngineConfig=rke_config, + attemptDelete=True, clusterName=None): + client = get_user_client() + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "controlPlane": True, + "quantity": 1} + nodes.append(node) + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "etcd": True, + "quantity": 1} + nodes.append(node) + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "worker": True, + "quantity": 3} + nodes.append(node) + cluster, node_pools = create_and_validate_cluster( + client, nodes, rancherKubernetesEngineConfig, clusterName) + if attemptDelete: + cluster_cleanup(client, cluster) + + +def validate_rke_dm_host_3(node_template, + rancherKubernetesEngineConfig=rke_config): + client = get_user_client() + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "controlPlane": True, + "quantity": 2} + nodes.append(node) + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "etcd": True, + "quantity": 3} + nodes.append(node) + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "worker": True, + "quantity": 3} + nodes.append(node) + cluster, node_pools = create_and_validate_cluster( + client, nodes, rancherKubernetesEngineConfig) + cluster_cleanup(client, cluster) + + +def validate_rke_dm_host_4(node_template, + rancherKubernetesEngineConfig=rke_config): + client = get_user_client() + + # Create cluster and add a node pool to this cluster + nodes = [] + node_name = random_node_name() + node = {"hostnamePrefix": node_name, + "nodeTemplateId": node_template.id, + "requestedHostname": node_name, + "controlPlane": True, + "etcd": True, + "worker": True, + "quantity": 1} + nodes.append(node) + cluster, node_pools = create_and_validate_cluster( + client, nodes, rancherKubernetesEngineConfig) + assert len(cluster.nodes()) == 1 + node1 = cluster.nodes().data[0] + assert len(node_pools) == 1 + node_pool = node_pools[0] + + # Increase the scale of the node pool to 3 + node_pool = client.update(node_pool, nodeTemplateId=node_template.id, + quantity=3) + cluster = validate_cluster(client, cluster, intermediate_state="updating") + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) == 3 + + # Delete node1 + node1 = client.delete(node1) + wait_for_node_to_be_deleted(client, node1) + + cluster = validate_cluster(client, cluster, intermediate_state="updating") + nodes = client.list_node(clusterId=cluster.id).data + assert len(nodes) == 3 + cluster_cleanup(client, cluster) + + +def create_and_validate_cluster(client, nodes, + rancherKubernetesEngineConfig=rke_config, + clusterName=None): + + cluster = client.create_cluster( + name=clusterName + if clusterName is not None else evaluate_clustername(), + rancherKubernetesEngineConfig=rancherKubernetesEngineConfig) + node_pools = [] + for node in nodes: + node["clusterId"] = cluster.id + success = False + start = time.time() + while not success: + if time.time() - start > 10: + raise AssertionError( + "Timed out waiting for cluster owner global Roles") + try: + time.sleep(1) + node_pool = client.create_node_pool(**node) + success = True + except ApiError: + success = False + node_pool = client.wait_success(node_pool) + node_pools.append(node_pool) + + cluster = validate_cluster(client, cluster) + return cluster, node_pools + + +def random_node_name(): + if not HOST_NAME or HOST_NAME == "testcustom": + return "testauto" + "-" + str(random_int(100000, 999999)) + else: + return HOST_NAME + "-" + str(random_int(100000, 999999)) + + +def evaluate_clustername(): + if CLUSTER_NAME == "": + cluster_name = random_name() + else: + cluster_name = CLUSTER_NAME + return cluster_name + + +@pytest.fixture(scope='session') +def node_template_az(): + client = get_user_client() + ec2_cloud_credential_config = { + "clientId": AZURE_CLIENT_ID, + "clientSecret": AZURE_CLIENT_SECRET, + "subscriptionId": AZURE_SUBSCRIPTION_ID + } + azure_cloud_credential = client.create_cloud_credential( + azurecredentialConfig=ec2_cloud_credential_config + ) + azConfig = { + "availabilitySet": "docker-machine", + "customData": "", + "diskSize": "30", + "dns": "", + "dockerPort": "2376", + "environment": "AzurePublicCloud", + "faultDomainCount": "3", + "image": "Canonical:0001-com-ubuntu-server-jammy:22_04-lts:latest", + "location": "westus", + "managedDisks": False, + "noPublicIp": False, + "plan": "", + "privateIpAddress": "", + "resourceGroup": "docker-machine", + "size": "Standard_D2_v2", + "sshUser": "docker-user", + "staticPublicIp": False, + "storageType": "Standard_LRS", + "subnet": "docker-machine", + "subnetPrefix": "192.168.0.0/16", + "updateDomainCount": "5", + "usePrivateIp": False, + "vnet": "docker-machine-vnet", + "type": "azureConfig", + "openPort": [ + "6443/tcp", + "2379/tcp", + "2380/tcp", + "8472/udp", + "4789/udp", + "9796/tcp", + "10256/tcp", + "10250/tcp", + "10251/tcp", + "10252/tcp", + "80/tcp", + "443/tcp", + "9999/tcp", + "8888/tcp", + "30456/tcp", + "30457/tcp", + "30458/tcp", + "30459/tcp", + "9001/tcp" + ] + } + node_template = client.create_node_template( + azureConfig=azConfig, + name=random_name(), + driver="azure", + cloudCredentialId=azure_cloud_credential.id, + useInternalIpAddress=True) + node_template = client.wait_success(node_template) + return node_template + + +@pytest.mark.skip(reason="https://github.com/rancher/qa-tasks/issues/318") +@pytest.fixture(scope='session') +def node_template_do(): + client = get_user_client() + do_cloud_credential_config = {"accessToken": DO_ACCESSKEY} + do_cloud_credential = client.create_cloud_credential( + digitaloceancredentialConfig=do_cloud_credential_config + ) + node_template = client.create_node_template( + digitaloceanConfig={"region": "nyc3", + "size": "s-2vcpu-2gb-intel", + "image": "ubuntu-18-04-x64"}, + name=random_name(), + driver="digitalocean", + cloudCredentialId=do_cloud_credential.id, + engineInstallURL=engine_install_url, + useInternalIpAddress=True) + node_template = client.wait_success(node_template) + return node_template + + +@pytest.fixture(scope='session') +def node_template_linode(): + client = get_user_client() + linode_cloud_credential_config = {"token": LINODE_ACCESSKEY} + linode_cloud_credential = client.create_cloud_credential( + linodecredentialConfig=linode_cloud_credential_config + ) + node_template = client.create_node_template( + linodeConfig={"authorizedUsers": "", + "createPrivateIp": False, + "dockerPort": "2376", + "image": "linode/ubuntu18.04", + "instanceType": "g6-standard-2", + "label": "", + "region": "us-west", + "sshPort": "22", + "sshUser": "", + "stackscript": "", + "stackscriptData": "", + "swapSize": "512", + "tags": "", + "uaPrefix": "Rancher"}, + name=random_name(), + driver="linode", + cloudCredentialId=linode_cloud_credential.id, + engineInstallURL=engine_install_url, + useInternalIpAddress=True) + node_template = client.wait_success(node_template) + return node_template + + +@pytest.fixture(scope='session') +def node_template_ec2(): + client = get_user_client() + ec2_cloud_credential_config = {"accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY} + ec2_cloud_credential = client.create_cloud_credential( + amazonec2credentialConfig=ec2_cloud_credential_config + ) + amazonec2Config = { + "instanceType": "t3.medium", + "region": AWS_REGION, + "rootSize": "16", + "securityGroup": [AWS_SG], + "sshUser": "ubuntu", + "subnetId": AWS_SUBNET, + "usePrivateAddress": False, + "volumeType": "gp2", + "vpcId": AWS_VPC, + "zone": AWS_ZONE + } + + node_template = client.create_node_template( + amazonec2Config=amazonec2Config, + name=random_name(), + useInternalIpAddress=True, + driver="amazonec2", + engineInstallURL=engine_install_url, + cloudCredentialId=ec2_cloud_credential.id + + ) + node_template = client.wait_success(node_template) + return node_template + + +@pytest.fixture(scope='session') +def node_template_ec2_with_provider(): + client = get_user_client() + ec2_cloud_credential_config = {"accessKey": AWS_ACCESS_KEY_ID, + "secretKey": AWS_SECRET_ACCESS_KEY} + ec2_cloud_credential = client.create_cloud_credential( + amazonec2credentialConfig=ec2_cloud_credential_config + ) + amazonec2Config = { + "instanceType": "t3a.medium", + "region": AWS_REGION, + "rootSize": "16", + "securityGroup": [AWS_SG], + "sshUser": "ubuntu", + "subnetId": AWS_SUBNET, + "usePrivateAddress": False, + "volumeType": "gp2", + "vpcId": AWS_VPC, + "zone": AWS_ZONE, + "iamInstanceProfile": AWS_IAM_PROFILE + } + + node_template = client.create_node_template( + amazonec2Config=amazonec2Config, + name=random_name(), + useInternalIpAddress=True, + driver="amazonec2", + engineInstallURL=engine_install_url, + cloudCredentialId=ec2_cloud_credential.id + ) + node_template = client.wait_success(node_template) + return node_template + + +def register_host_after_delay(client, cluster, node_role, delay): + aws_nodes = node_role["nodes"] + for aws_node in aws_nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd( + client, cluster, node_role["roles"], aws_node) + aws_node.execute_command(docker_run_cmd) + time.sleep(delay) + + +def create_and_validate_custom_host(node_roles, random_cluster_name=False, + validate=True, version=K8S_VERSION): + + client = get_user_client() + aws_nodes = \ + AmazonWebServices().create_multiple_nodes( + len(node_roles), random_test_name(HOST_NAME)) + + cluster, nodes = create_custom_host_from_nodes(aws_nodes, node_roles, + random_cluster_name, + version=version) + if validate: + cluster = validate_cluster(client, cluster, + check_intermediate_state=False, + k8s_version=version) + return cluster, nodes + + +def create_custom_host_from_nodes(nodes, node_roles, + random_cluster_name=False, windows=False, + windows_flannel_backend='vxlan', + version=K8S_VERSION): + client = get_user_client() + cluster_name = random_name() if random_cluster_name \ + else evaluate_clustername() + + if windows: + if windows_flannel_backend == "host-gw": + config = rke_config_windows_host_gw_aws_provider + else: + config = rke_config_windows + + else: + config = rke_config + if version != "": + config["kubernetesVersion"] = version + + cluster = client.create_cluster(name=cluster_name, + driver="rancherKubernetesEngine", + rancherKubernetesEngineConfig=config, + windowsPreferedCluster=windows) + assert cluster.state == "provisioning" + + i = 0 + for aws_node in nodes: + docker_run_cmd = \ + get_custom_host_registration_cmd(client, cluster, node_roles[i], + aws_node) + print("Docker run command: " + docker_run_cmd) + + for nr in node_roles[i]: + aws_node.roles.append(nr) + + result = aws_node.execute_command(docker_run_cmd) + print(result) + i += 1 + + cluster = validate_cluster_state(client, cluster, + check_intermediate_state=False) + + return cluster, nodes + + +def get_cis_rke_config(profile=CIS_SCAN_PROFILE): + rke_tmp_config = None + rke_config_dict = None + try: + rke_config_dict = { + 'rke-cis-1.4': rke_config_cis_1_4, + 'rke-cis-1.5': rke_config_cis_1_5 + } + rke_tmp_config = rke_config_dict[profile] + except KeyError: + print('Invalid RKE CIS profile. Supported profiles: ') + for k in rke_config_dict.keys(): + print("{0}".format(k)) + else: + print('Valid RKE CIS Profile loaded: {0}'.format(profile)) + return rke_tmp_config diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_run_sonobuoy.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_run_sonobuoy.py new file mode 100644 index 0000000..c241be6 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_run_sonobuoy.py @@ -0,0 +1,67 @@ +import base64 +import os +import time +from .common import * + +RANCHER_SONOBUOY_VERSION = os.environ.get("RANCHER_SONOBUOY_VERSION", "0.18.2") +RANCHER_K8S_VERSION = os.environ.get("RANCHER_K8S_VERSION", "v1.18.2") +RANCHER_SONOBUOY_MODE = os.environ.get("RANCHER_SONOBUOY_MODE", + "certified-conformance") +RANCHER_KUBECONFIG = os.environ.get("RANCHER_KUBECONFIG") +RANCHER_FAILED_TEST = os.environ.get("RANCHER_FAILED_TEST") +DATA_SUBDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), + 'resource') + +def test_sonobuoy_results(): + config = base64.b64decode(RANCHER_KUBECONFIG).decode("utf-8") + kubeconfig = DATA_SUBDIR + "/config" + print(kubeconfig) + + with open(kubeconfig, 'w') as f: + f.write(config) + + run_sonobuoy_test(kubeconfig) + get_sonobuoy_results(kubeconfig) + delete_sonobuoy_from_cluster(kubeconfig) + + +def run_sonobuoy_test(kubeconfig): + if not RANCHER_FAILED_TEST: + cmd = "sonobuoy run --mode={0} --kube-conformance-image-version={1} --kubeconfig={2}".format(RANCHER_SONOBUOY_MODE, RANCHER_K8S_VERSION, kubeconfig) + else: + cmd = "sonobuoy run {0} --kube-conformance-image-version={1} --kubeconfig={2}".format(RANCHER_FAILED_TEST, RANCHER_K8S_VERSION, kubeconfig) + status = run_command(cmd) + time.sleep(60) + + +def get_sonobuoy_results(kubeconfig): + cmd = "sonobuoy status --kubeconfig={0}".format(kubeconfig) + status = run_command(cmd) + print(status) + while "running" in status or "Pending" in status: + status = run_command(cmd, log_out=False) + time.sleep(120) + + cmd = "sonobuoy status --kubeconfig={0}".format(kubeconfig) + status = run_command(cmd) + print(status) + + cmd = "sonobuoy retrieve --kubeconfig={0}".format(kubeconfig) + result = run_command(cmd, log_out=False) + + cmd = "tar xzf {0}".format(result) + status = run_command(cmd, log_out=False) + + filepath = "./plugins/e2e/results/global/e2e.log" + is_file = os.path.isfile(filepath) + assert is_file + + cmd = "sonobuoy results {0}".format(result) + result = run_command(cmd) + print(result) + + +def delete_sonobuoy_from_cluster(kubeconfig): + cmd = "sonobuoy delete --all --wait --kubeconfig={0}".format(kubeconfig) + result = run_command(cmd) + print(result) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_sa.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_sa.py new file mode 100644 index 0000000..665b509 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_sa.py @@ -0,0 +1,26 @@ +import pytest + +from .common import * # NOQA + +do_test_sa = \ + ast.literal_eval(os.environ.get('RANCHER_SA_CHECK', "True")) + +if_test_sa = pytest.mark.skipif( + do_test_sa is not True, + reason="This test should not be executed on imported clusters") + + +@if_test_sa +def test_sa_for_user_clusters(): + cmd = "get serviceaccounts -n default" + out = execute_kubectl_cmd(cmd, False, False) + assert "netes-default" not in out + cmd = "get serviceaccounts -n cattle-system" + out = execute_kubectl_cmd(cmd, False, False) + assert "kontainer-engine" in out + + +@pytest.fixture(scope='module', autouse="True") +def create_cluster_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_secrets.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_secrets.py new file mode 100644 index 0000000..1f85870 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_secrets.py @@ -0,0 +1,828 @@ +import base64 +from rancher import ApiError +import pytest +from packaging import version + +from .common import * # NOQA + +CLUSTER_NAME = os.environ.get("CLUSTER_NAME", "") + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} + +def test_secret_create_all_ns(): + + """ + Verify creation of secrets is functional + """ + + p_client = namespace["p_client"] + ns = namespace["ns"] + + # Value is base64 encoded + value = base64.b64encode(b"valueall") + keyvaluepair = {"testall": value.decode('utf-8')} + cluster = namespace["cluster"] + project = namespace["project"] + c_client = namespace["c_client"] + + new_ns = create_ns(c_client, cluster, project) + namespacelist = [ns, new_ns] + secret = create_secret(keyvaluepair) + + # Create workloads with secret in existing namespaces + for ns in namespacelist: + + create_and_validate_workload_with_secret_as_volume(p_client, secret, + ns, + keyvaluepair) + create_and_validate_workload_with_secret_as_env_variable(p_client, + secret, + ns, + keyvaluepair) + + # Create a new namespace and workload in the new namespace using the secret + + new_ns1 = create_ns(c_client, cluster, project) + create_and_validate_workload_with_secret_as_volume(p_client, + secret, + new_ns1, + keyvaluepair) + create_and_validate_workload_with_secret_as_env_variable(p_client, + secret, + new_ns1, + keyvaluepair) + c_client.delete(new_ns) + + +def test_secret_create_single_ns(): + + """ + Verify editing secrets is functional + """ + + p_client = namespace["p_client"] + ns = namespace["ns"] + # Value is base64 encoded + value = base64.b64encode(b"valueall") + keyvaluepair = {"testall": value.decode('utf-8')} + + secret = create_secret(keyvaluepair, singlenamespace=True) + + # Create workloads with secret in existing namespace + create_and_validate_workload_with_secret_as_volume(p_client, secret, ns, + keyvaluepair) + create_and_validate_workload_with_secret_as_env_variable(p_client, secret, + ns, keyvaluepair) + + +def test_secret_delete_all_ns(): + + """ + Verify Deletion of secrets is functional + """ + p_client = namespace["p_client"] + ns = namespace["ns"] + # Value is base64 encoded + value = base64.b64encode(b"valuealldelete") + keyvaluepair = {"testalldelete": value.decode('utf-8')} + secret = create_secret(keyvaluepair) + delete_secret(p_client, secret, ns, keyvaluepair) + + +def test_secret_delete_single_ns(): + + p_client = namespace["p_client"] + ns = namespace["ns"] + # Value is base64 encoded + value = base64.b64encode(b"valuealldelete") + keyvaluepair = {"testalldelete": value.decode('utf-8')} + + secret = create_secret(keyvaluepair, singlenamespace=True) + delete_secret(p_client, secret, ns, keyvaluepair) + + +def test_secret_edit_all_ns(): + + p_client = namespace["p_client"] + name = random_test_name("default") + # Value is base64 encoded + value = base64.b64encode(b"valueall") + keyvaluepair = {"testall": value.decode('utf-8')} + cluster = namespace["cluster"] + project = namespace["project"] + c_client = namespace["c_client"] + + # Create a namespace + new_ns = create_ns(c_client, cluster, project) + secret = create_secret(keyvaluepair) + + # Value is base64 encoded + value1 = base64.b64encode(b"valueall") + value2 = base64.b64encode(b"valueallnew") + updated_dict = {"testall": value1.decode( + 'utf-8'), "testallnew": value2.decode('utf-8')} + updated_secret = p_client.update(secret, name=name, namespaceId='NULL', + data=updated_dict) + + assert updated_secret['baseType'] == "secret" + updatedsecretdata = updated_secret['data'] + + print("UPDATED SECRET DATA") + print(updatedsecretdata) + + assert updatedsecretdata.data_dict() == updated_dict + + # Create workloads using updated secret in the existing namespace + create_and_validate_workload_with_secret_as_volume(p_client, secret, + new_ns, + updatedsecretdata) + + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, new_ns, updatedsecretdata) + + # Create a new namespace and workloads in the new namespace using secret + new_ns1 = create_ns(c_client, cluster, project) + + create_and_validate_workload_with_secret_as_volume(p_client, secret, + new_ns1, + updatedsecretdata) + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, new_ns1, updatedsecretdata) + c_client.delete(new_ns) + + +def test_secret_edit_single_ns(): + + p_client = namespace["p_client"] + ns = namespace["ns"] + name = random_test_name("default") + # Value is base64 encoded + value = base64.b64encode(b"valueall") + keyvaluepair = {"testall": value.decode('utf-8')} + + secret = create_secret(keyvaluepair, singlenamespace=True) + + value1 = base64.b64encode(b"valueall") + value2 = base64.b64encode(b"valueallnew") + updated_dict = {"testall": value1.decode( + 'utf-8'), "testallnew": value2.decode('utf-8')} + updated_secret = p_client.update(secret, name=name, + namespaceId=ns['name'], + data=updated_dict) + assert updated_secret['baseType'] == "namespacedSecret" + updatedsecretdata = updated_secret['data'] + + print("UPDATED SECRET DATA") + print(updatedsecretdata) + + assert updatedsecretdata.data_dict() == updated_dict + + # Create a workload with the updated secret in the existing namespace + create_and_validate_workload_with_secret_as_volume(p_client, secret, + ns, + updatedsecretdata) + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, ns, updatedsecretdata) + + +rbac_role_list = [ + (CLUSTER_OWNER), + (PROJECT_OWNER), + (PROJECT_MEMBER), +] + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_secret_create(role): + """ + Verify creation of secrets for Cluster owner, project owner and project + member + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + rbac_secret_create(p_client, ns) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_secret_edit(role): + """ + Verify editing of secrets for Cluster owner, project owner and project + member + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, token) + rbac_secret_edit(p_client, ns, project=project) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_secret_delete(role): + """ + Verify deletion of secrets for Cluster owner, project owner and project + member + """ + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + rbac_secret_delete(p_client, ns) + + +@if_test_rbac +def test_rbac_secret_create_cluster_member(remove_resource): + + """ + Verify cluster member can create secret and deploy workload using secret + in the project he created + """ + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = \ + create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem"), + ns_name=random_test_name("ns-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_secret_create(p_client, ns) + + # Create a project as cluster owner and verify the cluster member cannot + # create secret in this project + + keyvaluepair = {"testall": "valueall"} + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + ownerproject, ns = \ + create_project_and_ns(cluster_owner_token, + namespace["cluster"], + random_test_name("rbac-cluster-owner")) + cluster_member_client = get_project_client_for_token(ownerproject, + user_token) + remove_resource(project) + remove_resource(ownerproject) + with pytest.raises(ApiError) as e: + create_secret(keyvaluepair, singlenamespace=False, + p_client=cluster_member_client) + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + +@if_test_rbac +def test_rbac_secret_edit_cluster_member(remove_resource): + + """ + Verify cluster member can create secret and edit secret in the project he + created + """ + + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = \ + create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem"), + ns_name=random_test_name("ns-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_secret_edit(p_client, ns, project=project) + + # Create a project as cluster owner and verify the cluster member cannot + # edit secret in this project + + keyvaluepair = {"testall": "valueall"} + + value1 = ("valueall") + value2 = ("valueallnew") + updated_dict = {"testall": value1, "testallnew": value2} + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + ownerproject, ns = create_project_and_ns( + cluster_owner_token, + namespace["cluster"], + random_test_name("rbac-cluster-owner")) + cluster_owner_client = get_project_client_for_token(ownerproject, + cluster_owner_token) + cluster_member_client = get_project_client_for_token(ownerproject, + user_token) + ownersecret = create_secret(keyvaluepair, singlenamespace=False, + p_client=cluster_owner_client) + remove_resource(project) + remove_resource(ownerproject) + + with pytest.raises(ApiError) as e: + cluster_member_client.update(ownersecret, namespaceId='NULL', + data=updated_dict) + assert e.value.error.status == 404 + assert e.value.error.code == 'NotFound' + + +@if_test_rbac +def test_rbac_secret_delete_cluster_member(remove_resource): + + """ + Verify cluster member can create secret and delete secret in the project he + created + """ + + keyvaluepair = {"testall": "valueall"} + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = \ + create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem"), + ns_name=random_test_name("ns-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_secret_delete(p_client, ns) + + # Create a project as cluster owner and verify the cluster member cannot + # delete secret in this project + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + ownerproject, ns = create_project_and_ns( + cluster_owner_token, + namespace["cluster"], + random_test_name("rbac-cluster-owner")) + cluster_owner_client = get_project_client_for_token(ownerproject, + cluster_owner_token) + cluster_member_client = get_project_client_for_token(ownerproject, + user_token) + ownersecret = create_secret(keyvaluepair, singlenamespace=False, + p_client=cluster_owner_client) + remove_resource(project) + remove_resource(ownerproject) + + with pytest.raises(ApiError) as e: + delete_secret(cluster_member_client, ownersecret, ns, keyvaluepair) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_secret_create_project_readonly(): + + """ + Verify read-only user cannot create secret + """ + + project = rbac_get_project() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + keyvaluepair = {"testall": "valueall"} + + # Read Only member cannot create secrets + with pytest.raises(ApiError) as e: + create_secret(keyvaluepair, singlenamespace=False, + p_client=readonly_user_client) + assert e.value.error.status == 403 + assert e.value.error.code == 'PermissionDenied' + + +@if_test_rbac +def test_rbac_secret_edit_project_readonly_member(remove_resource): + + """ + Verify read-only user cannot edit secret + """ + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + ns = rbac_get_namespace() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + keyvaluepair = {"testall": "valueall"} + + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + # As a cluster owner, create a secret + secret = create_secret(keyvaluepair, p_client=cluster_owner_p_client, + ns=ns) + + # Readonly member cannot edit secret + value1 = ("valueall") + value2 = ("valueallnew") + updated_dict = {"testall": value1, "testallnew": value2} + + remove_resource(secret) + with pytest.raises(ApiError) as e: + readonly_user_client.update(secret, + namespaceId=ns['name'], + data=updated_dict) + assert e.value.error.status == 404 + assert e.value.error.code == 'NotFound' + + +@if_test_rbac +def test_rbac_secret_delete_project_readonly(remove_resource): + + """ + Verify read-only user cannot delete secret + """ + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + ns = rbac_get_namespace() + user_token1 = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, user_token1) + + keyvaluepair = {"testall": "valueall"} + + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + # As a cluster owner, create a secret + secret = create_secret(keyvaluepair, p_client=cluster_owner_p_client, + ns=ns) + remove_resource(secret) + # Assert read-only user cannot delete the secret + with pytest.raises(ApiError) as e: + delete_secret(readonly_user_client, secret, ns, keyvaluepair) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_secret_list(remove_resource, role): + + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + p_client = get_project_client_for_token(project, user_token) + rbac_secret_list(p_client) + + +@if_test_rbac +def test_rbac_secret_list_cluster_member(remove_resource): + + """ + Verify cluster member can list secret in the project he created + """ + + keyvaluepair = {"testall": "valueall"} + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + project, ns = \ + create_project_and_ns(user_token, namespace["cluster"], + random_test_name("rbac-cluster-mem"), + ns_name=random_test_name("ns-cluster-mem")) + p_client = get_project_client_for_token(project, user_token) + rbac_secret_list(p_client) + + # Create a project as cluster owner and verify the cluster member cannot + # list secret in this project + + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + ownerproject, ns = create_project_and_ns( + cluster_owner_token, + namespace["cluster"], + random_test_name("rbac-cluster-owner")) + cluster_owner_client = get_project_client_for_token(ownerproject, + cluster_owner_token) + cluster_member_client = get_project_client_for_token(ownerproject, + user_token) + ownersecret = create_secret(keyvaluepair, singlenamespace=False, + p_client=cluster_owner_client) + + secretdict = cluster_member_client.list_secret(name=ownersecret.name) + secretdata = secretdict.get('data') + assert len(secretdata) == 0 + cluster_owner_client.delete(ownersecret) + remove_resource(project) + remove_resource(ownerproject) + + +@if_test_rbac +def test_rbac_secret_list_project_readonly(): + + """ + Verify read-only user cannot list secret + """ + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + readonly_user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, + readonly_user_token) + keyvaluepair = {"testall": "valueall"} + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + # As a cluster owner, create a secret + secret = create_secret(keyvaluepair, p_client=cluster_owner_p_client) + # Verify Read-Only user cannot list the secret + secretdict = readonly_user_client.list_secret(name=secret.name) + secretdata = secretdict.get('data') + assert len(secretdata) == 0 + cluster_owner_p_client.delete(secret) + + +def rbac_secret_create(p_client, ns): + + """ + Verify creating secret is functional. + The p_client passed as the parameter would be as per the role assigned + """ + + keyvaluepair = {"testall": "valueall"} + secret = create_secret(keyvaluepair, singlenamespace=False, + p_client=p_client) + + # Create workloads with secret in existing namespace + create_and_validate_workload_with_secret_as_volume(p_client, secret, + ns, keyvaluepair) + + +def rbac_secret_edit(p_client, ns, project=None): + + """ + Verify creating, editing secret is functional. + The p_client passed as the parameter would be as per the role assigned + """ + + value = base64.b64encode(b"valueall") + keyvaluepair = {"testall": value.decode('utf-8')} + cluster = namespace["cluster"] + c_client = namespace["c_client"] + + # Create a namespace + secret = create_secret(keyvaluepair, singlenamespace=False, + p_client=p_client) + # Value is base64 encoded + value1 = base64.b64encode(b"valueall") + value2 = base64.b64encode(b"valueallnew") + updated_dict = {"testall": value1.decode( + 'utf-8'), "testallnew": value2.decode('utf-8')} + updated_secret = p_client.update(secret, namespaceId='NULL', + data=updated_dict) + + assert updated_secret['baseType'] == "secret" + updatedsecretdata = updated_secret['data'] + + print("UPDATED SECRET DATA") + print(updatedsecretdata) + + assert updatedsecretdata.data_dict() == updated_dict + + # Create workloads using updated secret in the existing namespace + create_and_validate_workload_with_secret_as_volume(p_client, secret, + ns, + updatedsecretdata) + + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, ns, updatedsecretdata) + + # Create a new namespace and workloads in the new namespace using secret + new_ns1 = create_ns(c_client, cluster, project) + + create_and_validate_workload_with_secret_as_volume(p_client, secret, + new_ns1, + updatedsecretdata) + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, new_ns1, updatedsecretdata) + + +def rbac_secret_delete(p_client, ns): + + """ + Verify creating, deleting secret is functional. + The p_client passed as the parameter would be as per the role assigned + """ + keyvaluepair = {"testall": "valueall"} + secret = create_secret(keyvaluepair, singlenamespace=False, + p_client=p_client) + # Verify deletion of secret + delete_secret(p_client, secret, ns, keyvaluepair) + + +def rbac_secret_list(p_client): + ''' + Create a secret and list the secret + ''' + keyvaluepair = {"testall": "valueall"} + secret = create_secret(keyvaluepair, singlenamespace=False, + p_client=p_client) + secretname = secret.name + secretdict = p_client.list_secret(name=secretname) + secretlist = secretdict.get('data') + testsecret = secretlist[0] + testsecret_data = testsecret['data'] + assert len(secretlist) == 1 + assert testsecret.type == "secret" + assert testsecret.name == secretname + assert testsecret_data.data_dict() == keyvaluepair + p_client.delete(testsecret) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testsecret") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + namespace["c_client"] = c_client + + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + + request.addfinalizer(fin) + + +def is_version_greater_than_v25(): + # Checks if rancher version is greater than v2.5 + # eg: v2.5-head, v2.5 etc. + + rancher_version = get_setting_value_by_name('server-version') + + version_check = False + if rancher_version.startswith('v'): + if "head" in rancher_version: + rancher_version = ''.join(rancher_version.split("-")[0]) + else: + rancher_version = '.'.join(rancher_version.split(".")[:2]) + + if version.parse(rancher_version) > version.parse('v2.5'): + version_check = True + + return version_check + + +def validate_workload_with_secret(p_client, workload, + type, ns_name, keyvaluepair, + workloadwithsecretasVolume=False, + workloadwithsecretasenvvar=False, + podcount=1): + + validate_workload(p_client, workload, type, ns_name, pod_count=podcount) + + pod_list = p_client.list_pod(workloadId=workload.id).data + mountpath = "/test" + for i in range(0, len(keyvaluepair)): + key = list(keyvaluepair.keys())[i] + if workloadwithsecretasVolume: + key_file_in_pod = mountpath + "/" + key + command = "cat " + key_file_in_pod + '' + if is_windows(): + command = 'powershell -NoLogo -NonInteractive -Command "& {{ cat {0} }}"'.format(key_file_in_pod) + result = kubectl_pod_exec(pod_list[0], command) + assert result.rstrip() == base64.b64decode(list(keyvaluepair.values())[i]) + elif workloadwithsecretasenvvar: + command = 'env' + if is_windows(): + command = 'powershell -NoLogo -NonInteractive -Command \'& {{ (Get-Item -Path Env:).Name | ' \ + '% { "$_=$((Get-Item -Path Env:\\$_).Value)" }}\'' + result = kubectl_pod_exec(pod_list[0], command) + if base64.b64decode(list(keyvaluepair.values())[i]) in result: + assert True + + +def delete_secret(client, secret, ns, keyvaluepair): + + key = list(keyvaluepair.keys())[0] + secretname = secret.name + print("Delete Secret") + client.delete(secret) + + # Sleep to allow for the secret to be deleted + time.sleep(5) + timeout = 30 + print("Secret list after deleting secret") + secretdict = client.list_secret(name=secretname) + print(secretdict) + print(secretdict.get('data')) + start = time.time() + if len(secretdict.get('data')) > 0: + testdata = secretdict.get('data') + print("TESTDATA") + print(testdata[0]['data']) + while key in testdata[0]['data']: + if time.time() - start > timeout: + raise AssertionError("Timed out waiting for deletion") + time.sleep(.5) + secretdict = client.list_secret(name=secretname) + testdata = secretdict.get('data') + assert True + if len(secretdict.get('data')) == 0: + assert True + + # Verify secret is deleted by "kubectl get secret" command + command = " get secret " + secret['name'] + " --namespace=" + ns.name + print("Command to obtain the secret") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + + print("Verify that the secret does not exist " + "and the error code returned is non zero ") + if result != 0: + assert True + + +def create_and_validate_workload_with_secret_as_volume(p_client, secret, ns, + keyvaluepair, + name=None): + if name is None: + name = random_test_name("test") + + # Create Workload with secret as volume + mountpath = "/test" + volumeMounts = [{"readOnly": False, "type": "volumeMount", + "mountPath": mountpath, "name": "vol1"}] + con = [{"name": "test1", + "image": TEST_IMAGE, + "volumeMounts": volumeMounts}] + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + secretName = secret['name'] + + volumes = [{"type": "volume", "name": "vol1", + "secret": {"type": "secretVolumeSource", "defaultMode": 256, + "secretName": secretName, + "optional": False, "items": "NULL"}}] + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + volumes=volumes, + scheduling=sel) + validate_workload_with_secret(p_client, workload, "deployment", + ns.name, keyvaluepair, + workloadwithsecretasVolume=True) + + +def create_and_validate_workload_with_secret_as_env_variable(p_client, secret, + ns, keyvaluepair, + name=None): + if name is None: + name = random_test_name("test") + + # Create Workload with secret as env variable + secretName = secret['name'] + + # Checking if rancher version is 26 and above. + # If yes env should be "environment" and envFrom should be "environmentFrom" + rancher_version_26 = is_version_greater_than_v25() + if rancher_version_26: + env_str = "envFrom" + environment_data = [{ + "secretRef": { + "name": secretName, + "optional": False + } + }] + else: + env_str = "environmentFrom" + environment_data = [{ + "source": "secret", + "sourceKey": None, + "sourceName": secretName + }] + con = [{"name": "test", + "image": TEST_IMAGE, + env_str: environment_data }] + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scheduling=sel) + validate_workload_with_secret(p_client, workload, "deployment", + ns.name, keyvaluepair, + workloadwithsecretasenvvar=True) + + +def create_secret(keyvaluepair, singlenamespace=False, + p_client=None, ns=None, name=None): + + if p_client is None: + p_client = namespace["p_client"] + + if name is None: + name = random_test_name("default") + if ns is None: + ns = namespace["ns"] + + if not singlenamespace: + secret = p_client.create_secret(name=name, data=keyvaluepair) + assert secret['baseType'] == "secret" + else: + secret = p_client.create_namespaced_secret(name=name, + namespaceId=ns['name'], + data=keyvaluepair) + assert secret['baseType'] == "namespacedSecret" + + print(secret) + secretdata = secret['data'] + print("SECRET DATA") + print(secretdata) + assert secretdata.data_dict() == keyvaluepair + + return secret diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_service_discovery.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_service_discovery.py new file mode 100644 index 0000000..f56edf2 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_service_discovery.py @@ -0,0 +1,584 @@ +""" +This file contains tests for service discovery. +This file also has rbac tests based on different roles +Test requirement: +Below Env variables need to set +CATTLE_TEST_URL - url to rancher server +ADMIN_TOKEN - Admin token from rancher +USER_TOKEN - User token from rancher +RANCHER_CLUSTER_NAME - Cluster name to run test on +RANCHER_TEST_RBAC - Boolean (Optional), To run role based tests. +""" + + +from .common import ApiError +from .common import ast +from .common import CLUSTER_MEMBER +from .common import CLUSTER_OWNER +from .common import create_kubeconfig +from .common import create_ns +from .common import create_project_and_ns +from .common import get_cluster_client_for_token +from .common import get_project_client_for_token +from .common import get_user_client +from .common import get_user_client_and_cluster +from .common import if_test_rbac +from .common import os +from .common import PROJECT_MEMBER +from .common import PROJECT_OWNER +from .common import PROJECT_READ_ONLY +from .common import pytest +from .common import random_test_name +from .common import rbac_get_namespace +from .common import rbac_get_project +from .common import rbac_get_user_token_by_role +from .common import rbac_get_workload +from .common import skip_test_windows_os +from .common import TEST_IMAGE +from .common import TEST_IMAGE_REDIS +from .common import time +from .common import USER_TOKEN +from .common import validate_dns_record +from .common import validate_dns_record_deleted +from .common import validate_service_discovery +from .common import validate_workload +from .common import validate_workload_image +from .common import wait_for_condition +from .common import wait_for_pod_images +from .common import wait_for_pods_in_workload +from .common import wait_for_pod_to_running +from .common import wait_for_wl_to_active + + +RANCHER_CLEANUP_PROJECT = os.environ.get("RANCHER_CLEANUP_PROJECT", "True") +namespace = {"p_client": None, "ns": None, "cluster": None, + "project": None, "testclient_pods": [], "workload": None} +rbac_role_list = [ + CLUSTER_OWNER, + CLUSTER_MEMBER, + PROJECT_OWNER, + PROJECT_MEMBER, + PROJECT_READ_ONLY + ] +DNS_RESOLUTION_DEFAULT_SECONDS = \ + os.environ.get("RANCHER_DNS_RESOLUTION_SECONDS", 30) +SKIP_PING_CHECK_TEST = \ + ast.literal_eval(os.environ.get('RANCHER_SKIP_PING_CHECK_TEST', "False")) +if_skip_ping_check_test = pytest.mark.skipif( + SKIP_PING_CHECK_TEST, + reason='For skipping tests in clusters that ' \ + 'are deployed with security groups that will not allow ping') + + +def create_and_validate_wl(name, con, scale, type, p_client=None, ns=None): + if p_client is None: + p_client = namespace["p_client"] + if ns is None: + ns = namespace["ns"] + + workload = p_client.create_workload(name=name, containers=con, + namespaceId=ns.id, scale=scale) + wait_for_pods_in_workload(p_client, workload, scale) + validate_workload(p_client, workload, type, ns.id, pod_count=scale) + return workload + + +def update_and_validate_workload(workload, con, scale, p_client=None, ns=None): + if p_client is None: + p_client = namespace["p_client"] + if ns is None: + ns = namespace["ns"] + + p_client.update(workload, containers=con, scale=scale) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pod_images(p_client, workload, ns.name, con[0]["image"], scale) + wait_for_pods_in_workload(p_client, workload, scale) + validate_workload(p_client, workload, "deployment", ns.name, scale) + validate_workload_image(p_client, workload, con[0]["image"], ns) + + +def validate_dns_record_for_workload(workload, scale, record, + p_client=None, testclient_pods=None): + if p_client is None: + p_client = namespace["p_client"] + if testclient_pods is None: + testclient_pods = namespace["testclient_pods"] + + expected_ips = [] + pods = p_client.list_pod(workloadId=workload["id"]).data + assert len(pods) == scale + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + for pod in testclient_pods: + validate_dns_record(pod, record, expected_ips) + + +def test_service_discovery_when_workload_scale_up(): + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-sd-up") + type = "deployment" + + # deploy a workload + scale = 2 + workload = create_and_validate_wl(name, con, scale, type) + # test service discovery + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + # workload scales up to 3 pods + scale = 3 + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + +def test_service_discovery_when_workload_scale_down(): + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-sd-dw") + type = "deployment" + + # deploy a workload + scale = 3 + workload = create_and_validate_wl(name, con, scale, type) + # test service discovery + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + # workload scale down to 2 pods + scale = 2 + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + +def test_service_discovery_when_workload_upgrade(): + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-sd-upgrade") + type = "deployment" + scale = 2 + + # deploy a workload + workload = create_and_validate_wl(name, con, scale, type) + # test service discovery + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + # upgrade + con = [{"name": "test1", + "image": TEST_IMAGE_REDIS}] + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + # upgrade again + con = [{"name": "test1", + "image": TEST_IMAGE}] + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_service_discovery(workload, scale, namespace["p_client"], + namespace["ns"], namespace["testclient_pods"]) + + +def test_dns_record_type_workload_when_workload_scale_up(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-dns-up") + type = "deployment" + + # deploy a workload + scale = 2 + workload = create_and_validate_wl(name, con, scale, type) + record = {"type": "dnsRecord", "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + create_dns_record(record, p_client) + # test dns record for the workload + validate_dns_record_for_workload(workload, scale, record) + + # workload scale up to 3 pods + scale = 3 + update_and_validate_workload(workload, con, scale) + + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_dns_record_for_workload(workload, scale, record) + + +def test_dns_record_type_workload_when_workload_scale_down(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-dns-dw") + type = "deployment" + + # deploy a workload + scale = 3 + workload = create_and_validate_wl(name, con, scale, type) + record = {"type": "dnsRecord", + "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), + "namespaceId": ns.id} + create_dns_record(record, p_client) + # test service discovery + validate_dns_record_for_workload(workload, scale, record) + + # workload scale down to 2 pods + scale = 2 + update_and_validate_workload(workload, con, scale) + + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_dns_record_for_workload(workload, scale, record) + + +def test_dns_record_type_workload_when_workload_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("test-dns-upgrade") + scale = 2 + type = "deployment" + + # deploy a workload + workload = create_and_validate_wl(name, con, scale, type) + record = {"type": "dnsRecord", "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + create_dns_record(record, p_client) + # test service discovery + validate_dns_record_for_workload(workload, scale, record) + + # upgrade the workload + con = [{"name": "test1", + "image": TEST_IMAGE_REDIS}] + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_dns_record_for_workload(workload, scale, record) + + # upgrade the workload again + con = [{"name": "test1", + "image": TEST_IMAGE}] + update_and_validate_workload(workload, con, scale) + # test service discovery + time.sleep(DNS_RESOLUTION_DEFAULT_SECONDS) + validate_dns_record_for_workload(workload, scale, record) + + +# Windows could not transpose the remote ICMP packages, +# since TCP/UDP packets can still be transposed, +# one can substitute ping with curl to be able +# to debug connectivity to outside +@skip_test_windows_os +@if_skip_ping_check_test +def test_dns_record_type_external_ip(): + ns = namespace["ns"] + record = {"type": "dnsRecord", "ipAddresses": ["8.8.8.8"], + "name": random_test_name("record"), "namespaceId": ns.id} + expected = record["ipAddresses"] + create_and_validate_dns_record(record, expected) + + +# Windows could not transpose the remote ICMP packages, +# since TCP/UDP packets can still be transposed, +# one can substitute ping with curl to be able +# to debug connectivity to outside +@skip_test_windows_os +@if_skip_ping_check_test +def test_dns_record_type_multiple_external_ips(): + ns = namespace["ns"] + record = {"type": "dnsRecord", "ipAddresses": ["8.8.8.8", "8.8.4.4"], + "name": random_test_name("record"), "namespaceId": ns.id} + expected = record["ipAddresses"] + create_and_validate_dns_record(record, expected) + + +# Windows could not transpose the remote ICMP packages, +# since TCP/UDP packets can still be transposed, +# one can substitute ping with curl to be able +# to debug connectivity to outside +@skip_test_windows_os +@if_skip_ping_check_test +def test_dns_record_type_hostname(): + ns = namespace["ns"] + record = {"type": "dnsRecord", "hostname": "google.com", + "name": random_test_name("record"), "namespaceId": ns.id} + expected = [record["hostname"]] + create_and_validate_dns_record(record, expected) + + +# Windows could not transpose the remote ICMP packages, +# since TCP/UDP packets can still be transposed, +# one can substitute ping with curl to be able +# to debug connectivity to outside +@skip_test_windows_os +@if_skip_ping_check_test +def test_dns_record_type_alias(): + ns = namespace["ns"] + + first_record = {"type": "dnsRecord", "hostname": "google.com", + "name": random_test_name("record"), "namespaceId": ns.id} + target_record = create_dns_record(first_record) + + record = {"type": "dnsRecord", "targetDnsRecordIds": [target_record["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + + expected = [first_record["hostname"]] + create_and_validate_dns_record(record, expected) + + +def test_dns_record_type_workload(): + ns = namespace["ns"] + workload = namespace["workload"] + p_client = namespace["p_client"] + + record = {"type": "dnsRecord", "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + + expected_ips = [] + pods = p_client.list_pod(workloadId=workload["id"]).data + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + + create_and_validate_dns_record(record, expected_ips) + + +def test_dns_record_type_multiple_workloads(): + ns = namespace["ns"] + workload = namespace["workload"] + p_client = namespace["p_client"] + + wlname = random_test_name("default") + + con = [{"name": "test1", + "image": TEST_IMAGE}] + + additional_workload = p_client.create_workload(name=wlname, + containers=con, + namespaceId=ns.id, + scale=1) + wait_for_wl_to_active(p_client, additional_workload) + awl_pods = wait_for_pods_in_workload(p_client, additional_workload, 1) + wait_for_pod_to_running(p_client, awl_pods[0]) + + record = {"type": "dnsRecord", + "targetWorkloadIds": [workload["id"], additional_workload["id"]], + "name": random_test_name("record"), + "namespaceId": ns.id} + + workloads = [workload, additional_workload] + expected_ips = [] + + for wl in workloads: + pods = p_client.list_pod(workloadId=wl["id"]).data + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + + create_and_validate_dns_record(record, expected_ips) + + +def test_dns_record_type_selector(): + ns = namespace["ns"] + workload = namespace["workload"] + p_client = namespace["p_client"] + + selector = \ + workload["labels"]["workload.user.cattle.io/workloadselector"] + + record = {"type": "dnsRecord", + "selector": + {"workload.user.cattle.io/workloadselector": selector}, + "name": random_test_name("record"), "namespaceId": ns.id} + + expected_ips = [] + pods = p_client.list_pod(workloadId=workload["id"]).data + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + + create_and_validate_dns_record(record, expected_ips) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_service_discovery_create(role): + """ + Creates dns record and validates it for different roles passed in parameter + @param role: User role in rancher eg. project owner, project member etc + """ + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload = rbac_get_workload() + p_client = get_project_client_for_token(project, token) + + record = {"type": "dnsRecord", "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + dns_record = create_dns_record(record, p_client) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + dns_record = create_dns_record(record, p_client) + # test dns record for the workload + validate_dns_record_for_workload(workload, 1, + record, p_client=p_client) + p_client.delete(dns_record) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_service_discovery_edit(role): + """ + Creates dns record with cluster owner role and edit it with different roles + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload_1 = rbac_get_workload() + p_client = get_project_client_for_token(project, token) + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + wlname = random_test_name("default") + + con = [{"name": "test1", + "image": TEST_IMAGE}] + + workload_2 = p_client_for_c_owner.create_workload(name=wlname, + containers=con, + namespaceId=ns.id, + scale=1) + wait_for_wl_to_active(p_client_for_c_owner, workload_2) + + record_1 = {"type": "dnsRecord", "targetWorkloadIds": [workload_1["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + dns_record = create_dns_record(record_1, p_client_for_c_owner) + validate_dns_record_for_workload(workload_1, 1, + record_1, p_client=p_client_for_c_owner) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.update(dns_record, targetWorkloadIds=workload_2["id"]) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + p_client.update(dns_record, type="dnsRecord", + targetWorkloadIds=[workload_2["id"]]) + p_client.reload(dns_record) + p_client_for_c_owner.delete(dns_record) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_service_discovery_delete(role): + """ + Creates dns record with cluster owner and delete with different roles. + @param role: User role in rancher eg. project owner, project member etc + """ + c_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + workload = rbac_get_workload() + p_client = get_project_client_for_token(project, token) + p_client_for_c_owner = get_project_client_for_token(project, c_owner_token) + + record = {"type": "dnsRecord", "targetWorkloadIds": [workload["id"]], + "name": random_test_name("record"), "namespaceId": ns.id} + dns_record = create_dns_record(record, p_client_for_c_owner) + validate_dns_record_for_workload(workload, 1, + record, p_client=p_client_for_c_owner) + if role in (CLUSTER_MEMBER, PROJECT_READ_ONLY): + with pytest.raises(ApiError) as e: + p_client.delete(dns_record) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + else: + p_client.delete(dns_record) + validate_dns_record_deleted(p_client, dns_record) + + +def create_and_validate_dns_record(record, expected, p_client=None, + testclient_pods=None): + if testclient_pods is None: + testclient_pods = namespace["testclient_pods"] + create_dns_record(record, p_client) + assert len(testclient_pods) > 0 + for pod in testclient_pods: + validate_dns_record(pod, record, expected) + + +def create_dns_record(record, p_client=None): + if p_client is None: + p_client = namespace["p_client"] + created_record = p_client.create_dns_record(record) + + wait_for_condition( + p_client, created_record, + lambda x: x.state == "active", + lambda x: 'State is: ' + x.state) + + return created_record + + +@pytest.fixture(scope='module', autouse="True") +def setup(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + + p, ns = create_project_and_ns(USER_TOKEN, cluster, "testsd") + p_client = get_project_client_for_token(p, USER_TOKEN) + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + new_ns = create_ns(c_client, cluster, p) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + + wlname = random_test_name("default") + + con = [{"name": "test1", + "image": TEST_IMAGE}] + + workload = p_client.create_workload(name=wlname, + containers=con, + namespaceId=ns.id, + scale=2) + wait_for_wl_to_active(p_client, workload) + namespace["workload"] = workload + + pods = wait_for_pods_in_workload(p_client, workload, 2) + pod = wait_for_pod_to_running(p_client, pods[0]) + namespace["testclient_pods"].append(pod) + + workload = p_client.create_workload(name=wlname, + containers=con, + namespaceId=new_ns.id, + scale=1) + wait_for_wl_to_active(p_client, workload) + pods = wait_for_pods_in_workload(p_client, workload, 1) + pod = wait_for_pod_to_running(p_client, pods[0]) + namespace["testclient_pods"].append(pod) + + assert len(namespace["testclient_pods"]) == 2 + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + + if RANCHER_CLEANUP_PROJECT == "True": + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_upgrade.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_upgrade.py new file mode 100644 index 0000000..a178b37 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_upgrade.py @@ -0,0 +1,762 @@ +import base64 +import pytest +from .test_ingress import get_ingress_ip_domain + + +from .common import * # NOQA +from .test_secrets import ( + create_and_validate_workload_with_secret_as_env_variable, + create_and_validate_workload_with_secret_as_volume, + validate_workload_with_secret, + create_secret) +from .test_service_discovery import create_dns_record + +cluster_name = CLUSTER_NAME +validate_prefix = os.environ.get('RANCHER_VALIDATE_RESOURCES_PREFIX', "step0") +create_prefix = os.environ.get('RANCHER_CREATE_RESOURCES_PREFIX', "step1") +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None, + "testclient_pods": []} +upgrade_check_stage = os.environ.get('RANCHER_UPGRADE_CHECK', "preupgrade") +validate_ingress = \ + ast.literal_eval(os.environ.get('RANCHER_INGRESS_CHECK', "True")) + +sshUser = os.environ.get('RANCHER_SSH_USER', "ubuntu") +rancherVersion = os.environ.get('RANCHER_SERVER_VERSION', "master") +upgradeVersion = os.environ.get('RANCHER_SERVER_VERSION_UPGRADE', "master") +upgradeImage = os.environ.get('RANCHER_UPGRADE_IMAGE', "rancher/rancher") +CLUSTER_VERSION = os.environ.get('RANCHER_CLUSTER_UPGRADE_VERSION', "") + +value = base64.b64encode(b"valueall") +keyvaluepair = {"testall": value.decode('utf-8')} + +wl_name = "-testwl" +sd_name = "-testsd" +sd_wlname1 = "-testsd1" +sd_wlname2 = "-testsd2" +ingress_name1 = "-testingress1" +ingress_name2 = "-testingress2" +ingress_wlname1 = "-testingresswl1" +ingress_wlname2 = "-testingresswl2" +project_name = "-p1" +ns_name1 = "-ns1" +ns_name2 = "-ns2" + + +wl_name_create = create_prefix + wl_name +sd_name_create = create_prefix + sd_name +sd_wlname1_create = create_prefix + sd_wlname1 +sd_wlname2_create = create_prefix + sd_wlname2 +ingress_name1_create = create_prefix + ingress_name1 +ingress_name2_create = create_prefix + ingress_name2 +ingress_wlname1_create = create_prefix + ingress_wlname1 +ingress_wlname2_create = create_prefix + ingress_wlname2 + +wl_name_validate = validate_prefix + wl_name +sd_name_validate = validate_prefix + sd_name +sd_wlname1_validate = validate_prefix + sd_wlname1 +sd_wlname2_validate = validate_prefix + sd_wlname2 +ingress_name1_validate = validate_prefix + ingress_name1 +ingress_name2_validate = validate_prefix + ingress_name2 +ingress_wlname1_validate = validate_prefix + ingress_wlname1 +ingress_wlname2_validate = validate_prefix + ingress_wlname2 + +secret_name = create_prefix + "-testsecret" +secret_wl_name1_create = create_prefix + "-testwl1withsec" +secret_wl_name2_create = create_prefix + "-testwl2withsec" + +secret_wl_name1_validate = validate_prefix + "-testwl1withsec" +secret_wl_name2_validate = validate_prefix + "-testwl2withsec" + +app_ns = create_prefix + "-app-ns" +app_create_name = create_prefix + "-app" +app_validate_name = validate_prefix + "-app" +# the pre_upgrade_externalId is for launching an app +pre_upgrade_externalId = \ + create_catalog_external_id("test-catalog", "mysql", "1.3.1") +# the post_upgrade_externalId is for upgrading the existing app +post_upgrade_externalId = \ + create_catalog_external_id("test-catalog", "mysql", "1.3.2") +catalogUrl = "https://github.com/rancher/integration-test-charts.git" +catalogBranch = "validation-tests" + +if_post_upgrade = pytest.mark.skipif( + upgrade_check_stage != "postupgrade", + reason='This test is not executed for PreUpgrade checks') +if_pre_upgrade = pytest.mark.skipif( + upgrade_check_stage != "preupgrade", + reason='This test is not executed for PreUpgrade checks') +if_validate_ingress = pytest.mark.skipif( + validate_ingress is False, + reason='This test is not executed') +if_upgrade_rancher = pytest.mark.skipif( + upgrade_check_stage != "upgrade_rancher", + reason='This test is only for testing upgrading Rancher') +if_upgrade_cluster = pytest.mark.skipif( + upgrade_check_stage != "upgrade_cluster", + reason='This test is only for testing upgrading clusters') + + +@if_post_upgrade +@pytest.mark.run(order=1) +def test_validate_existing_project_resources(): + validate_existing_project_resources() + + +@if_post_upgrade +@pytest.mark.run(order=2) +def test_validate_existing_wl(): + validate_wl(wl_name_validate) + + +@if_post_upgrade +@pytest.mark.run(order=2) +def test_validate_existing_service_discovery(): + validate_service_discovery_upgrade(sd_name_validate, + [sd_wlname1_validate, sd_wlname2_validate]) + + +@if_post_upgrade +@pytest.mark.run(order=2) +def test_validate_existing_wl_with_secret(): + validate_worklaods_with_secret( + secret_wl_name1_validate, secret_wl_name2_validate) + + +# It's hard to find an App to support Windows case for now. +# Could we make an App to support both Windows and Linux? +@skip_test_windows_os +@skip_test_hardened +@if_post_upgrade +@pytest.mark.run(order=2) +def test_validate_existing_catalog_app(): + validate_catalog_app(app_validate_name, pre_upgrade_externalId) + + +@if_post_upgrade +@if_validate_ingress +@pytest.mark.run(order=2) +def test_validate_existing_ingress_daemon(): + validate_ingress_io(ingress_name1_validate, + ingress_wlname1_validate) + + +@if_post_upgrade +@if_validate_ingress +@pytest.mark.run(order=2) +def test_validate_existing_ingress_wl(): + validate_ingress_io(ingress_name2_validate, + ingress_wlname2_validate) + + +@if_post_upgrade +@pytest.mark.run(order=3) +def test_modify_workload_validate_deployment(): + modify_workload_validate_deployment() + + +@if_post_upgrade +@pytest.mark.run(order=3) +def test_modify_workload_validate_sd(): + modify_workload_validate_sd() + + +@if_post_upgrade +@pytest.mark.run(order=3) +def test_modify_workload_validate_secret(): + modify_workload_validate_secret() + + +# It's hard to find an App to support Windows case for now. +# Could we make an App to support both Windows and Linux? +@skip_test_windows_os +@skip_test_hardened +@if_post_upgrade +@pytest.mark.run(order=3) +def test_modify_catalog_app(): + modify_catalog_app() + + +@if_post_upgrade +@if_validate_ingress +@pytest.mark.run(order=3) +def test_modify_workload_validate_ingress(): + modify_workload_validate_ingress() + + +@pytest.mark.run(order=4) +def test_create_project_resources(): + create_project_resources() + + +@pytest.mark.run(order=5) +def test_create_and_validate_wl(): + create_and_validate_wl() + + +@pytest.mark.run(order=5) +def test_create_and_validate_service_discovery(): + create_and_validate_service_discovery() + + +@pytest.mark.run(order=5) +def test_create_validate_wokloads_with_secret(): + create_validate_wokloads_with_secret() + + +@if_validate_ingress +@pytest.mark.run(order=5) +def test_create_and_validate_ingress_io_daemon(): + create_and_validate_ingress_io_daemon() + + +@if_validate_ingress +@pytest.mark.run(order=5) +def test_create_and_validate_ingress_io_wl(): + create_and_validate_ingress_io_wl() + + +# It's hard to find an App to support Windows case for now. +# Could we make an App to support both Windows and Linux? +@skip_test_hardened +@skip_test_windows_os +@pytest.mark.run(order=5) +def test_create_and_validate_catalog_app(): + create_and_validate_catalog_app() + + +@pytest.mark.run(order=6) +def test_create_and_validate_ip_address_pods(): + create_and_validate_ip_address_pods() + + +# the flag if_upgarde_rancher is false all the time +# because we do not have this option for the variable RANCHER_UPGRADE_CHECK +# instead, we will have a new pipeline that calls this function directly +@if_upgrade_rancher +def test_rancher_upgrade(): + upgrade_rancher_server(CATTLE_TEST_URL) + client = get_user_client() + version = client.list_setting(name="server-version").data[0].value + assert version == upgradeVersion + + +# the flag if_upgrade_cluster is false all the time +# because we do not have this option for the variable RANCHER_UPGRADE_CHECK +# instead, we will have a new pipeline that calls this function directly +@if_upgrade_cluster +def test_cluster_upgrade(): + upgrade_cluster() + wait_for_ready_nodes() + + +def create_and_validate_wl(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + p_client.create_workload(name=wl_name_create, containers=con, + namespaceId=ns.id, scale=2, scheduling=sel) + validate_wl(wl_name_create) + + +def validate_wl(workload_name, pod_count=2): + p_client = namespace["p_client"] + ns = namespace["ns"] + workloads = p_client.list_workload(name=workload_name, + namespaceId=ns.id).data + assert len(workloads) == 1 + workload = workloads[0] + validate_workload( + p_client, workload, "deployment", ns.name, pod_count=pod_count) + validate_service_discovery_upgrade(workload_name, [workload_name]) + + +def create_and_validate_ingress_io_daemon(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + + # Ingress with daemonSet target + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + workload = p_client.create_workload(name=ingress_wlname1_create, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}, + scheduling=sel) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + path = "/name.html" + rule = {"host": get_ingress_ip_domain(), + "paths": + [{"workloadIds": [workload.id], "targetPort": TEST_IMAGE_PORT, + "path": path}]} + p_client.create_ingress(name=ingress_name1_create, + namespaceId=ns.id, + rules=[rule]) + validate_ingress_io(ingress_name1_create, ingress_wlname1_create) + + +def create_and_validate_ingress_io_wl(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + + # Ingress with Deployment target + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + workload = p_client.create_workload(name=ingress_wlname2_create, + containers=con, + namespaceId=ns.id, scale=2, + scheduling=sel) + validate_wl(ingress_wlname2_create, 2) + path = "/name.html" + rule = {"host": get_ingress_ip_domain(), + "paths": + [{"workloadIds": [workload.id], "targetPort": TEST_IMAGE_PORT, + "path": path}]} + p_client.create_ingress(name=ingress_name2_create, + namespaceId=ns.id, + rules=[rule]) + validate_ingress_io(ingress_name2_create, ingress_wlname2_create) + + +def modify_workload_validate_deployment(): + + # This method increments the deployment scale and validates it + p_client = namespace["p_client"] + ns = namespace["ns"] + + workload = p_client.list_workload( + name=wl_name_validate, namespace=validate_prefix + ns.id).data[0] + p_client.update(workload, scale=4, containers=workload.containers) + validate_wl(wl_name_validate, 4) + + +def modify_workload_validate_ingress(): + + # This method increments the workload scale and validates the ingress + # pointing to it + p_client = namespace["p_client"] + ns = namespace["ns"] + + # Get workload and update + ing_workload = p_client.list_workload( + name=ingress_wlname2_validate, namespace=ns.id).data[0] + print(ing_workload) + # Increment workload + ing_workload = p_client.update(ing_workload, scale=4, + containers=ing_workload.containers) + wait_for_pods_in_workload(p_client, ing_workload, 4) + validate_wl(ing_workload.name, 4) + + # Validate ingress after workload scale up + validate_ingress_io(ingress_name2_validate, ingress_wlname2_validate) + + +def modify_workload_validate_sd(): + + # This method increments the workload scale and validates + # service discovery + p_client = namespace["p_client"] + ns = namespace["ns"] + # Get sd workloads and validate service discovery + sd_workload = p_client.list_workload( + name=sd_wlname2_validate, namespace=ns.id).data[0] + p_client.update(sd_workload, scale=3, containers=sd_workload.containers) + validate_wl(sd_wlname2_validate, 3) + + validate_service_discovery_upgrade(sd_name_validate, + [sd_wlname1_validate, + sd_wlname2_validate]) + + +def modify_workload_validate_secret(): + + # This method increments the scale of worlkoad with secret and validates it + + p_client = namespace["p_client"] + ns = namespace["ns"] + + secret_workload1 = p_client.list_workload( + name=secret_wl_name1_validate, namespace=ns.id).data[0] + + secret_workload1 = p_client.update(secret_workload1, scale=3, + containers=secret_workload1.containers) + wait_for_pods_in_workload(p_client, secret_workload1, 3) + validate_workload_with_secret( + p_client, secret_workload1, "deployment", ns.name, + keyvaluepair, workloadwithsecretasVolume=True, podcount=3) + + secret_workload2 = p_client.list_workload(name=secret_wl_name2_validate, + namespace=ns.id).data[0] + + secret_workload2 = p_client.update(secret_workload2, scale=3, + containers=secret_workload2.containers) + wait_for_pods_in_workload(p_client, secret_workload2, 3) + validate_workload_with_secret( + p_client, secret_workload2, "deployment", ns.name, + keyvaluepair, workloadwithsecretasenvvar=True, podcount=3) + + +def validate_ingress_io(ing_name, workload_name): + p_client = namespace["p_client"] + ns = namespace["ns"] + workloads = p_client.list_workload(name=workload_name, + namespaceId=ns.id).data + assert len(workloads) == 1 + workload = workloads[0] + ingresses = p_client.list_ingress(name=ing_name, + namespaceId=ns.id).data + assert len(ingresses) == 1 + ingress = ingresses[0] + + validate_ingress_using_endpoint(p_client, ingress, [workload]) + + +def create_and_validate_service_discovery(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + + con = [{"name": "test1", + "image": TEST_IMAGE}] + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + workload = p_client.create_workload(name=sd_wlname1_create, + containers=con, + namespaceId=ns.id, + scheduling=sel, + daemonSetConfig={},) + validate_workload(p_client, workload, "daemonSet", ns.name, + len(get_schedulable_nodes(cluster))) + + additional_workload = p_client.create_workload(name=sd_wlname2_create, + containers=con, + namespaceId=ns.id, + scale=1, scheduling=sel) + wait_for_wl_to_active(p_client, additional_workload) + awl_pods = wait_for_pods_in_workload(p_client, additional_workload, 1) + wait_for_pod_to_running(p_client, awl_pods[0]) + + record = {"type": "dnsRecord", + "targetWorkloadIds": [workload["id"], additional_workload["id"]], + "name": sd_name_create, + "namespaceId": ns.id} + + create_dns_record(record, p_client) + validate_service_discovery_upgrade(sd_name_create, + [sd_wlname1_create, sd_wlname2_create]) + + +def validate_service_discovery_upgrade(sd_record_name, workload_names): + p_client = namespace["p_client"] + ns = namespace["ns"] + target_wls = [] + for wl_name_create in workload_names: + workloads = p_client.list_workload( + name=wl_name_create, namespaceId=ns.id).data + assert len(workloads) == 1 + workload = workloads[0] + target_wls.append(workload) + + records = p_client.list_dns_record( + name=sd_record_name, namespaceId=ns.id).data + assert len(records) == 1 + record = records[0] + + testclient_pods = namespace["testclient_pods"] + expected_ips = [] + for wl in target_wls: + pods = p_client.list_pod(workloadId=wl["id"]).data + for pod in pods: + expected_ips.append(pod["status"]["podIp"]) + + assert len(testclient_pods) > 0 + for pod in testclient_pods: + validate_dns_record(pod, record, expected_ips) + + +def create_validate_wokloads_with_secret(): + + p_client = namespace["p_client"] + ns = namespace["ns"] + + secret_name = create_prefix + "-testsecret" + + secret_wl_name_create1 = create_prefix + "-testwl1withsec" + secret_wl_name_create2 = create_prefix + "-testwl2withsec" + + secret = create_secret(keyvaluepair, p_client=p_client, name=secret_name) + create_and_validate_workload_with_secret_as_volume( + p_client, secret, ns, keyvaluepair, name=secret_wl_name_create1) + create_and_validate_workload_with_secret_as_env_variable( + p_client, secret, ns, keyvaluepair, name=secret_wl_name_create2) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client = get_user_client() + admin_client = get_admin_client() + clusters = client.list_cluster(name=cluster_name).data + assert len(clusters) == 1 + cluster = clusters[0] + create_kubeconfig(cluster) + namespace["cluster"] = cluster + if len(admin_client.list_catalog(name="test-catalog")) == 0: + catalog = admin_client.create_catalog( + name="test-catalog", + baseType="catalog", + branch=catalogBranch, + kind="helm", + url=catalogUrl) + catalog = wait_for_catalog_active(admin_client, catalog) + + +def create_project_resources(): + cluster = namespace["cluster"] + p, ns = create_project_and_ns(USER_TOKEN, cluster, + project_name=create_prefix + project_name, + ns_name=create_prefix + ns_name1) + p_client = get_project_client_for_token(p, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["project"] = p + namespace["testclient_pods"] = [] + + # Create pods in existing namespace and new namespace that will be used + # as test clients from which DNS resolution will be tested + + wlname = create_prefix + "-testsdclient" + + con = [{"name": "test1", + "image": TEST_IMAGE}] + sel = {"node": { + "nodeId": "null", + "requireAll": ["kubernetes.io/os =" + TEST_OS] + }} + workload = p_client.create_workload(name=wlname, + containers=con, + namespaceId=ns.id, + scale=1, scheduling=sel) + wait_for_wl_to_active(p_client, workload) + namespace["workload"] = workload + + pods = wait_for_pods_in_workload(p_client, workload, 1) + pod = wait_for_pod_to_running(p_client, pods[0]) + namespace["testclient_pods"].append(pod) + + new_ns = create_ns(get_cluster_client_for_token(cluster, USER_TOKEN), + cluster, p, ns_name=create_prefix + ns_name2) + + workload = p_client.create_workload(name=wlname, + containers=con, + namespaceId=new_ns.id, + scale=1, scheduling=sel) + wait_for_wl_to_active(p_client, workload) + pods = wait_for_pods_in_workload(p_client, workload, 1) + pod = wait_for_pod_to_running(p_client, pods[0]) + namespace["testclient_pods"].append(pod) + assert len(namespace["testclient_pods"]) == 2 + + +def validate_existing_project_resources(): + cluster = namespace["cluster"] + p_name = validate_prefix + project_name + ns_name = validate_prefix + ns_name1 + ns2_name = validate_prefix + ns_name2 + + # Get existing project + client = get_user_client() + projects = client.list_project(name=p_name, + clusterId=cluster.id).data + assert len(projects) == 1 + project = projects[0] + + c_client = get_cluster_client_for_token(cluster, USER_TOKEN) + p_client = get_project_client_for_token(project, USER_TOKEN) + + # Get existing namespace + nss = c_client.list_namespace(name=ns_name).data + assert len(nss) == 1 + ns = nss[0] + + # 2nd namespace + nss = c_client.list_namespace(name=ns2_name).data + assert len(nss) == 1 + ns2 = nss[0] + + # Get existing SD client pods + workload_name = validate_prefix + "-testsdclient" + workloads = p_client.list_workload(name=workload_name, + namespaceId=ns.id).data + assert len(workloads) == 1 + wl1_pods = p_client.list_pod(workloadId=workloads[0].id).data + assert len(wl1_pods) == 1 + + workload_name = validate_prefix + "-testsdclient" + + workloads = p_client.list_workload(name=workload_name, + namespaceId=ns2.id).data + assert len(workloads) == 1 + wl2_pods = p_client.list_pod(workloadId=workloads[0].id).data + assert len(wl2_pods) == 1 + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["project"] = project + namespace["testclient_pods"] = [wl1_pods[0], wl2_pods[0]] + + +def validate_worklaods_with_secret(workload_name1, workload_name2): + p_client = namespace["p_client"] + ns = namespace["ns"] + + wk1 = p_client.list_workload(name=workload_name1, namespace=ns.id).data[0] + wk2 = p_client.list_workload(name=workload_name2, namespace=ns.id).data[0] + validate_workload_with_secret( + p_client, wk1, "deployment", ns.name, keyvaluepair, + workloadwithsecretasVolume=True) + validate_workload_with_secret( + p_client, wk2, "deployment", ns.name, keyvaluepair, + workloadwithsecretasenvvar=True) + + +def upgrade_rancher_server(serverIp, + sshKeyPath=".ssh/jenkins-elliptic-validation.pem", + containerName="rancher-server"): + if serverIp.startswith('https://'): + serverIp = serverIp[8:] + + stopCommand = "docker stop " + containerName + print(exec_shell_command(serverIp, 22, stopCommand, "", + sshUser, sshKeyPath)) + + createVolumeCommand = "docker create --volumes-from " + containerName + \ + " --name rancher-data rancher/rancher:" + \ + rancherVersion + + print(exec_shell_command(serverIp, 22, createVolumeCommand, "", + sshUser, sshKeyPath)) + + removeCommand = "docker rm " + containerName + print(exec_shell_command(serverIp, 22, removeCommand, "", + sshUser, sshKeyPath)) + + runCommand = "docker run -d --volumes-from rancher-data " \ + "--restart=unless-stopped " \ + "-p 80:80 -p 443:443 " + upgradeImage + ":" + upgradeVersion + \ + " --trace" + print(exec_shell_command(serverIp, 22, runCommand, "", + sshUser, sshKeyPath)) + + wait_until_active(CATTLE_TEST_URL) + + +def upgrade_cluster(): + print("Upgrading cluster {} to version {}".format( + CLUSTER_NAME, CLUSTER_VERSION)) + client, cluster = get_user_client_and_cluster() + if "k3sConfig" in cluster: + k3s_config = cluster.k3sConfig + k3s_updated_config = k3s_config.copy() + k3s_updated_config["kubernetesVersion"] = CLUSTER_VERSION + client.update(cluster, name=cluster.name, k3sConfig=k3s_updated_config) + cluster = get_cluster_by_name(client, CLUSTER_NAME) + assert cluster.k3sConfig["kubernetesVersion"] == CLUSTER_VERSION + elif "rke2Config" in cluster: + rke2_config = cluster.rke2Config + rke2_updated_config = rke2_config.copy() + rke2_updated_config["kubernetesVersion"] = CLUSTER_VERSION + client.update(cluster, name=cluster.name, + rke2Config=rke2_updated_config) + cluster = get_cluster_by_name(client, CLUSTER_NAME) + assert cluster.rke2Config["kubernetesVersion"] == CLUSTER_VERSION + + +def wait_for_ready_nodes(): + client, cluster = get_user_client_and_cluster() + start = time.time() + nodes = client.list_node(clusterId=cluster.id).data + unready_nodes = [] + for node in nodes: + unready_nodes.append(node.id) + while unready_nodes and time.time() - start < MACHINE_TIMEOUT: + nodes = client.list_node(clusterId=cluster.id).data + for node in nodes: + if node.info.kubernetes.kubeletVersion == CLUSTER_VERSION: + time.sleep(5) + wait_for_node_status(client, node, "active") + if node.id in unready_nodes: + unready_nodes.remove(node.id) + assert not unready_nodes, "Nodes did not successfully upgrade " \ + "within the timeout" + + +def create_and_validate_catalog_app(): + cluster = namespace["cluster"] + p_client = namespace['p_client'] + ns = create_ns(get_cluster_client_for_token(cluster, USER_TOKEN), + cluster, namespace["project"], ns_name=app_ns) + print(pre_upgrade_externalId) + app = p_client.create_app( + answers=get_defaut_question_answers(get_user_client(), + pre_upgrade_externalId), + externalId=pre_upgrade_externalId, + name=app_create_name, + projectId=namespace["project"].id, + prune=False, + targetNamespace=ns.id + ) + validate_catalog_app(app.name, pre_upgrade_externalId) + + +def modify_catalog_app(): + p_client = namespace["p_client"] + app = wait_for_app_to_active(p_client, app_validate_name) + # upgrade the catalog app to a newer version + p_client.action(obj=app, action_name="upgrade", + answers=get_defaut_question_answers( + get_user_client(), + post_upgrade_externalId), + externalId=post_upgrade_externalId) + validate_catalog_app(app.name, post_upgrade_externalId) + + +def validate_catalog_app(app_name, external_id): + p_client = namespace["p_client"] + app = wait_for_app_to_active(p_client, app_name) + assert app.externalId == external_id, \ + "the version of the app is not correct" + # check if associated workloads are active + ns = app.targetNamespace + pramaters = external_id.split('&') + chart = pramaters[1].split("=")[1] + "-" + pramaters[2].split("=")[1] + workloads = p_client.list_workload(namespaceId=ns).data + assert len(workloads) == 1, "expected only 1 workload in the namespace" + for wl in workloads: + assert wl.state == "active" + assert wl.workloadLabels.chart == chart, \ + "the chart version is wrong" + + +def create_and_validate_ip_address_pods(): + get_pods = "get pods --all-namespaces -o wide | grep ' 172.17'" + pods_result = execute_kubectl_cmd(get_pods, json_out=False, stderr=True) + print(pods_result.decode('ascii')) + assert pods_result.decode('ascii') is '', "Pods have 172 IP address" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_v2_cis_scan.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_v2_cis_scan.py new file mode 100644 index 0000000..f25e2ff --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_v2_cis_scan.py @@ -0,0 +1,89 @@ +import pytest +import os +from .common import USER_TOKEN +from .common import get_cluster_client_for_token_v1 +from .common import execute_kubectl_cmd +from .common import get_user_client_and_cluster +from .common import wait_until_app_v2_deployed +from .common import check_v2_app_and_uninstall + +CIS_CHART_VERSION = os.environ.get('RANCHER_CIS_CHART_VERSION', "1.0.100") +SCAN_PROFILE = os.environ.get('RANCHER_SCAN_PROFILE', "rke-profile-permissive") + +cluster_detail = {"cluster": None} +cis_annotations = \ + { + "catalog.cattle.io/ui-source-repo": "rancher-charts", + "catalog.cattle.io/ui-source-repo-type": "cluster" + } +cis_charts = { + "values": + { "global": {"cattle":{"clusterId": None, "clusterName": None}}}, + "version": CIS_CHART_VERSION, + "projectId": None +} +CHART_NAME = "rancher-cis-benchmark" + +def test_install_v2_cis_benchmark(): + """ + List installed apps + Check if the app is installed + If installed, delete the app and the CRDs + Create namespace + Install App and the CRDs + :return: + """ + client = \ + get_cluster_client_for_token_v1( + cluster_detail["cluster"]["id"],USER_TOKEN + ) + rancherrepo = \ + client.list_catalog_cattle_io_clusterrepo(id="rancher-charts") + cluster_id = cluster_detail["cluster"]["id"] + cluster_name = cluster_detail["cluster"]["name"] + rancher_repo = rancherrepo["data"][0] + + # check if CIS is already installed and uninstall the app + check_v2_app_and_uninstall(client, CHART_NAME) + check_v2_app_and_uninstall(client, CHART_NAME + "-crd") + + # create namespace + ns = "cis-operator-system" + command = "create namespace " + ns + execute_kubectl_cmd(command, False) + + # install CIS v2 + cis_charts["annotations"] = cis_annotations + cis_charts["values"]["global"]["cattle"]["clusterId"] = cluster_id + cis_charts["values"]["global"]["cattle"]["clusterName"] = cluster_name + cis_charts["chartName"] = CHART_NAME + "-crd" + cis_charts["releaseName"] = CHART_NAME + "-crd" + + install_v2_app(client, rancher_repo, cis_charts, CHART_NAME + "-crd", ns) + + + # install app + cis_charts["chartName"] = CHART_NAME + cis_charts["releaseName"] = CHART_NAME + install_v2_app(client, rancher_repo, cis_charts, CHART_NAME, ns) + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster_detail["cluster"] = get_user_client_and_cluster() + + +def install_v2_app(client, rancher_repo, chart_values, chart_name, ns): + # install CRD + response = client.action(obj=rancher_repo, action_name="install", + charts=[chart_values], + namespace=ns, + disableOpenAPIValidation=False, + noHooks=False, + projectId=None, + skipCRDs=False, + timeout="600s", + wait=True) + print("response", response) + app_list = wait_until_app_v2_deployed(client, chart_name) + assert chart_name in app_list diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_vmwarevsphere_driver.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_vmwarevsphere_driver.py new file mode 100644 index 0000000..8d22eb0 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_vmwarevsphere_driver.py @@ -0,0 +1,230 @@ +import pytest, copy +from .common import * # NOQA + +RANCHER_VSPHERE_USERNAME = os.environ.get("RANCHER_VSPHERE_USERNAME", "") +RANCHER_VSPHERE_PASSWORD = os.environ.get("RANCHER_VSPHERE_PASSWORD", "") +RANCHER_VSPHERE_VCENTER = os.environ.get("RANCHER_VSPHERE_VCENTER", "") +RANCHER_VSPHERE_VCENTER_PORT = \ + os.environ.get("RANCHER_VSPHERE_VCENTER_PORT", 443) +RANCHER_CLEANUP_CLUSTER = \ + ast.literal_eval(os.environ.get('RANCHER_CLEANUP_CLUSTER', "True")) +CLUSTER_NAME = os.environ.get("RANCHER_CLUSTER_NAME", + random_name() + "-cluster") +ENGINE_INSTALL_URL = os.environ.get("RANCHER_ENGINE_INSTALL_URL", + "https://get.docker.com/") +CLONE_FROM = \ + os.environ.get("RANCHER_CLONE_FROM", + "/RNCH-HE-FMT/vm/ubuntu-bionic-18.04-cloudimg") +RESOURCE_POOL = \ + os.environ.get("RANCHER_RESOURCE_POOL", + "/RNCH-HE-FMT/host/FMT2.R620.1/Resources/validation-tests") +DATASTORE = \ + os.environ.get("RANCHER_DATASTORE", + "/RNCH-HE-FMT/datastore/ranch01-silo01-vm01") + +DATASTORE_CLUSTER = \ + os.environ.get("RANCHER_DATASTORE_CLUSTER", + "/RNCH-HE-FMT/datastore/ds_cluster") + +CLOUD_CONFIG = \ + os.environ.get("RANCHER_CLOUD_CONFIG", + "#cloud-config\r\npackages:\r\n - redis-server") + +rke_config = { + "addonJobTimeout": 30, + "authentication": + {"strategy": "x509", + "type": "authnConfig"}, + "ignoreDockerVersion": True, + "ingress": + {"provider": "nginx", + "type": "ingressConfig"}, + "monitoring": + {"provider": "metrics-server", + "type": "monitoringConfig"}, + "network": + {"plugin": "canal", + "type": "networkConfig", + "options": {"flannelBackendType": "vxlan"}}, + "services": { + "etcd": { + "extraArgs": + {"heartbeat-interval": 500, + "election-timeout": 5000}, + "snapshot": False, + "backupConfig": + {"intervalHours": 12, "retention": 6, "type": "backupConfig"}, + "creation": "12h", + "retention": "72h", + "type": "etcdService"}, + "kubeApi": { + "alwaysPullImages": False, + "podSecurityPolicy": False, + "serviceNodePortRange": "30000-32767", + "type": "kubeAPIService"}}, + "sshAgentAuth": False} + +vsphereConfig = { + "cfgparam": ["disk.enableUUID=TRUE"], + "cloneFrom": CLONE_FROM, + "cloudinit": "", + "contentLibrary": "", + "cpuCount": "4", + "creationType": "vm", + "customAttribute": ["203=CustomA", "204=CustomB"], + "datacenter": "/RNCH-HE-FMT", + "datastore": "", + "datastoreCluster": "", + "diskSize": "20000", + "folder": "/", + "hostsystem": "", + "memorySize": "16000", + "network": ["/RNCH-HE-FMT/network/Private Range 172.16.128.1-21"], + "password": "", + "pool": RESOURCE_POOL, + "sshPassword": "tcuser", + "sshPort": "22", + "sshUser": "docker", + "sshUserGroup": "staff", + "tag": [ + "urn:vmomi:InventoryServiceTag:04ffafd0-d7de-440c-a32c-5cd98761f812:GLOBAL", + "urn:vmomi:InventoryServiceTag:d00f1cf2-6822-46a0-9602-679ea56efd57:GLOBAL" + ], + "type": "vmwarevsphereConfig", + "username": "", + "vappIpallocationpolicy": "", + "vappIpprotocol": "", + "vappProperty": "", + "vappTransport": "", + "vcenter": "", + "vcenterPort": "443", +} + +if_vsphere_var_present = pytest.mark.skipif( + RANCHER_VSPHERE_USERNAME == '' or + RANCHER_VSPHERE_PASSWORD == '' or + RANCHER_VSPHERE_VCENTER == '', + reason='required env variables are not present') + + +@if_vsphere_var_present +@pytest.mark.usefixtures("create_cluster") +def test_vsphere_provisioning(): + client = get_client_for_token(USER_TOKEN) + cluster = get_cluster_by_name(client=client, name=CLUSTER_NAME) + nodes = client.list_node(clusterId=cluster.id).data + assert 4 == len(nodes) + validate_cluster(client, cluster, skipIngresscheck=False) + + +@pytest.fixture(scope='module', autouse="True") +def create_cluster(request): + client = get_client_for_token(USER_TOKEN) + cloud_cred = create_vsphere_credential(client) + nt = create_vsphere_nodetemplate( + client, cloud_cred, datastore=DATASTORE) + ntcc = create_vsphere_nodetemplate( + client, cloud_cred, datastore=DATASTORE, cloud_config=CLOUD_CONFIG) + ntdsc = create_vsphere_nodetemplate( + client, cloud_cred, datastore_cluster=DATASTORE_CLUSTER) + cluster = client.create_cluster( + name=CLUSTER_NAME, + rancherKubernetesEngineConfig=rke_config) + # Allow sometime for the "cluster_owner" CRTB to take effect + time.sleep(5) + + request.addfinalizer(cluster_cleanup) + master_pool = client.create_node_pool({ + "type": "nodetemplate", + "clusterId": cluster.id, + "controlPlane": True, + "etcd": True, + "hostnamePrefix": CLUSTER_NAME + "-master", + "nodeTemplateId": nt.id, + "quantity": 1, + "worker": False, + }) + + worker_pool1 = client.create_node_pool({ + "type": "nodetemplate", + "clusterId": cluster.id, + "controlPlane": False, + "etcd": False, + "hostnamePrefix": CLUSTER_NAME + "-worker", + "nodeTemplateId": nt.id, + "quantity": 1, + "worker": True, + }) + + worker_pool2 = client.create_node_pool({ + "type": "nodetemplate", + "clusterId": cluster.id, + "controlPlane": False, + "etcd": False, + "hostnamePrefix": CLUSTER_NAME + "-worker-cc", + "nodeTemplateId": ntcc.id, + "quantity": 1, + "worker": True, + }) + + worker_pool3 = client.create_node_pool({ + "type": "nodetemplate", + "clusterId": cluster.id, + "controlPlane": False, + "etcd": False, + "hostnamePrefix": CLUSTER_NAME + "-worker-dsc", + "nodeTemplateId": ntdsc.id, + "quantity": 1, + "worker": True, + }) + + client.wait_success(master_pool) + client.wait_success(worker_pool1) + client.wait_success(worker_pool2) + client.wait_success(worker_pool3) + + wait_for_cluster_node_count(client, cluster, 4, timeout=900) + + +def create_vsphere_credential(client): + return client.create_cloud_credential( + name=random_name(), + vmwarevspherecredentialConfig={ + "username": RANCHER_VSPHERE_USERNAME, + "password": RANCHER_VSPHERE_PASSWORD, + "vcenter": RANCHER_VSPHERE_VCENTER, + "vcenterPort": RANCHER_VSPHERE_VCENTER_PORT, + } + ) + + +def cluster_cleanup(): + if not RANCHER_CLEANUP_CLUSTER: + return + client = get_client_for_token(USER_TOKEN) + cluster = get_cluster_by_name(client=client, name=CLUSTER_NAME) + nodes = get_schedulable_nodes(cluster) + delete_cluster(client, cluster) + for node in nodes: + wait_for_node_to_be_deleted(client, node) + + +def create_vsphere_nodetemplate( + client, cloud_cred, cloud_config="", datastore="", + datastore_cluster=""): + vc = copy.copy(vsphereConfig) + if cloud_config != "": + vc["cloudConfig"] = cloud_config + if datastore != "": + vc["datastore"] = datastore + if datastore_cluster != "": + vc["datastoreCluster"] = datastore_cluster + return client.create_node_template({ + "vmwarevsphereConfig": vc, + "name": random_name(), + "namespaceId": "fixme", + "useInternalIpAddress": True, + "driver": "vmwarevsphere", + "engineInstallURL": ENGINE_INSTALL_URL, + "cloudCredentialId": cloud_cred.id, + }) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_volumes.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_volumes.py new file mode 100644 index 0000000..88cac6b --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_volumes.py @@ -0,0 +1,547 @@ +import pytest +from rancher import ApiError +from .common import * # NOQA + +namespace = {"p_client": None, + "ns": None, + "cluster": None, + "project": None, + "pv": None, + "pvc": None} + +# this is the path to the mounted dir in the pod(workload) +MOUNT_PATH = "/var/nfs" +# if True then delete the NFS after finishing tests, otherwise False +DELETE_NFS = eval(os.environ.get('RANCHER_DELETE_NFS', "True")) + + +rbac_role_list = [ + (CLUSTER_OWNER), + (PROJECT_OWNER), + (PROJECT_MEMBER), + (PROJECT_READ_ONLY), + (CLUSTER_MEMBER), +] + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pv_create(role, remove_resource): + nfs_ip = namespace["nfs_ip"] + cluster = namespace["cluster"] + url = CATTLE_TEST_URL + "/v3/clusters/" + cluster.id + "/persistentvolume" + if (role == CLUSTER_OWNER): + user_token = rbac_get_user_token_by_role(role) + # Persistent volume can be created only using cluster client + owner_clusterclient = get_cluster_client_for_token(cluster, user_token) + pv = create_pv(owner_clusterclient, nfs_ip) + remove_resource(pv) + else: + # Users other than cluster owner cannot create persistent volume + # Other user clients do not have attribute to create persistent volume + # Hence a post request is made as below + user_token = rbac_get_user_token_by_role(role) + headers = {"Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + user_token} + pv_config = {"type": "persistentVolume", + "accessModes": ["ReadWriteOnce"], + "name": "testpv", + "nfs": {"readOnly": "false", + "type": "nfsvolumesource", + "path": NFS_SERVER_MOUNT_PATH, + "server": nfs_ip + }, + "capacity": {"storage": "10Gi"} + } + + response = requests.post(url, json=pv_config, verify=False, + headers=headers) + assert response.status_code == 403 + jsonresponse = json.loads(response.content) + assert jsonresponse['code'] == "Forbidden" + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pv_list(role, remove_resource): + # All users can list the persistent volume which is at the cluster level + # A get request is performed as user clients do not have attrribute to list + # persistent volumes + nfs_ip = namespace["nfs_ip"] + cluster = namespace["cluster"] + + user_token = rbac_get_user_token_by_role(role) + owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_clusterclient = get_cluster_client_for_token(cluster, owner_token) + pv = create_pv(owner_clusterclient, nfs_ip) + pvname = pv['name'] + url = CATTLE_TEST_URL + "/v3/cluster/" + cluster.id +\ + "/persistentvolumes/" + pvname + + headers = { + "Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer " + user_token + } + response = requests.get(url, verify=False, + headers=headers) + jsonresponse = json.loads(response.content) + assert response.status_code == 200 + assert jsonresponse['type'] == "persistentVolume" + assert jsonresponse['name'] == pvname + remove_resource(pv) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pv_edit(role): + nfs_ip = namespace["nfs_ip"] + cluster = namespace["cluster"] + clusterowner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_clusterclient = get_cluster_client_for_token(cluster, + clusterowner_token) + if(role == CLUSTER_OWNER): + # Verify editing of PV as a Cluster Owner succeeds + edit_pv(owner_clusterclient, nfs_ip, owner_clusterclient) + + else: + user_token = rbac_get_user_token_by_role(role) + user_clusterclient = get_cluster_client_for_token(cluster, + user_token) + # Verify editing of PV is forbidden for other roles + with pytest.raises(ApiError) as e: + edit_pv(user_clusterclient, nfs_ip, owner_clusterclient) + print(e.value.error.code) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pv_delete(role, remove_resource): + nfs_ip = namespace["nfs_ip"] + cluster = namespace["cluster"] + clusterowner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_clusterclient = get_cluster_client_for_token(cluster, + clusterowner_token) + if(role == CLUSTER_OWNER): + pv = create_pv(owner_clusterclient, nfs_ip) + delete_pv(owner_clusterclient, pv) + else: + user_token = rbac_get_user_token_by_role(role) + user_clusterclient = get_cluster_client_for_token(cluster, + user_token) + # As a Cluster Owner create PV object using cluster client + pv = create_pv(owner_clusterclient, nfs_ip) + # Verify other roles cannot delete the PV object + with pytest.raises(ApiError) as e: + delete_pv(user_clusterclient, pv) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(pv) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_create(role, remove_resource): + user_project = None + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + if(role == CLUSTER_MEMBER): + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = create_project_and_ns(user_token, + namespace["cluster"], + random_test_name( + "cluster-mem")) + p_client = get_project_client_for_token(user_project, user_token) + else: + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + + if (role != PROJECT_READ_ONLY): + pv, pvc = create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + remove_resource(pv) + remove_resource(pvc) + else: + project = rbac_get_project() + ns = rbac_get_namespace() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_user_client = get_project_client_for_token(project, + user_token) + # Verify Read Only member cannot create PVC objects + with pytest.raises(ApiError) as e: + create_pv_pvc(readonly_user_client, ns, nfs_ip, cluster_client) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + if(user_project is not None): + remove_resource(user_project) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_create_negative(role, remove_resource): + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + if (role == CLUSTER_OWNER): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + pv, pvc = create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + remove_resource(pv) + remove_resource(pvc) + else: + unshared_project = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(role) + ns = rbac_get_unshared_ns() + p_client = get_project_client_for_token(unshared_project, user_token) + # Verify other members cannot create PVC objects + with pytest.raises(ApiError) as e: + create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_edit_negative(role, remove_resource): + # Editing of volume claims is not allowed for any role, + # We are verifying that editing is forbidden in shared + # and unshared projects + + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + # Cluster owner client created in the shared project + owner_client = \ + get_project_client_for_token(project, cluster_owner_token) + edit_pvc(p_client, ns, nfs_ip, cluster_client, owner_client) + + unshared_project = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(role) + unshared_ns = rbac_get_unshared_ns() + user_client = get_project_client_for_token(unshared_project, + user_token) + + # Cluster owner client created in the unshared project + owner_client = \ + get_project_client_for_token(unshared_project, cluster_owner_token) + + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + edit_pvc(user_client, unshared_ns, nfs_ip, cluster_client, + owner_client) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_delete(role, remove_resource): + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + user_project = None + if(role == CLUSTER_MEMBER): + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = create_project_and_ns(user_token, + namespace["cluster"], + random_test_name( + "cluster-mem")) + p_client = get_project_client_for_token(user_project, user_token) + else: + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + + if (role != PROJECT_READ_ONLY): + pv, pvc = create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + delete_pvc(p_client, pvc, ns) + remove_resource(pv) + if user_project is not None: + remove_resource(user_project) + + if (role == PROJECT_READ_ONLY): + project = rbac_get_project() + ns = rbac_get_namespace() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_p_client = \ + get_project_client_for_token(project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + readonly_client = get_project_client_for_token(project, user_token) + + # As a Cluster owner create a PVC object + pv, pvc = create_pv_pvc(cluster_owner_p_client, ns, nfs_ip, + cluster_client) + # Verify that the Read Only member cannot delete the PVC objects + # created by Cluster Owner + with pytest.raises(ApiError) as e: + delete_pvc(readonly_client, pvc, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(pv) + remove_resource(pvc) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_delete_negative(role, remove_resource): + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + if (role == CLUSTER_OWNER): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + pv, pvc = create_pv_pvc(p_client, ns, nfs_ip, + cluster_client) + delete_pvc(p_client, pvc, ns) + remove_resource(pv) + else: + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + owner_client = get_project_client_for_token(unshared_project, + cluster_owner_token) + user_token = rbac_get_user_token_by_role(role) + # As a Cluster Owner create pv, pvc + pv, pvc = create_pv_pvc(owner_client, ns, nfs_ip, + cluster_client) + user_client = get_project_client_for_token(unshared_project, + user_token) + with pytest.raises(ApiError) as e: + delete_pvc(user_client, pvc, ns) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(pv) + remove_resource(pvc) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_list(remove_resource, role): + user_project = None + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + if(role == CLUSTER_MEMBER): + cluster_member_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + user_project, ns = \ + create_project_and_ns(cluster_member_token, + namespace["cluster"], + random_test_name("cluster-mem")) + + user_client = get_project_client_for_token(user_project, + cluster_member_token) + # As a cluster member create a PVC and he should be able to list it + pv, pvc = create_pv_pvc(user_client, ns, nfs_ip, cluster_client) + else: + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_project() + cluster_owner_p_client = \ + get_project_client_for_token(project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(role) + project = rbac_get_project() + ns = rbac_get_namespace() + user_client = get_project_client_for_token(project, user_token) + # As a Cluster Owner create pv, pvc + pv, pvc = create_pv_pvc(cluster_owner_p_client, ns, nfs_ip, + cluster_client) + + pvcname = pvc["name"] + pvcdict = user_client.list_persistentVolumeClaim(name=pvcname) + print(pvcdict) + pvcdata = pvcdict['data'] + assert len(pvcdata) == 1 + assert pvcdata[0].type == "persistentVolumeClaim" + assert pvcdata[0].name == pvcname + remove_resource(pvc) + remove_resource(pv) + if user_client is not None: + remove_resource(user_project) + + +@if_test_rbac +@pytest.mark.parametrize("role", rbac_role_list) +def test_rbac_pvc_list_negative(remove_resource, role): + nfs_ip = namespace["nfs_ip"] + cluster_client = namespace["cluster_client"] + if (role == CLUSTER_OWNER): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(unshared_project, user_token) + pv, pvc = create_pv_pvc(p_client, ns, nfs_ip, cluster_client) + pvcname = pvc['name'] + pvcdict = p_client.list_persistentVolumeClaim(name=pvcname) + pvcdata = pvcdict.get('data') + assert len(pvcdata) == 1 + assert pvcdata[0].type == "persistentVolumeClaim" + assert pvcdata[0].name == pvcname + remove_resource(pv) + remove_resource(pvc) + else: + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + cluster_owner_client = \ + get_project_client_for_token(unshared_project, cluster_owner_token) + user_token = rbac_get_user_token_by_role(role) + user_client = get_project_client_for_token(unshared_project, + user_token) + # As a Cluster Owner create pv, pvc + pv, pvc = create_pv_pvc(cluster_owner_client, ns, nfs_ip, + cluster_client) + pvcname = pvc['name'] + # Verify length of PVC list is zero for users with other roles + pvcdict = user_client.list_horizontalPodAutoscaler(name=pvcname) + pvcdata = pvcdict.get('data') + assert len(pvcdata) == 0 + remove_resource(pv) + remove_resource(pvcname) + + +def edit_pvc(user_client, ns, nfs_ip, cluster_client, + cluster_owner_client): + # Create pv and pvc as cluster owner which will be used during edit_pvc + # negative test cases since roles other than cluster owner cannot + # create pvc in unshared projects + + pv, pvc = create_pv_pvc(cluster_owner_client, ns, nfs_ip, cluster_client) + + updated_pvc_config = { + "accessModes": ["ReadWriteOnce"], + "name": pvc['name'], + "volumeId": pv.id, + "namespaceId": ns.id, + "storageClassId": "", + "resources": {"requests": {"storage": "15Gi"}} + } + with pytest.raises(ApiError) as e: + user_client.update(pvc, updated_pvc_config) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + cluster_owner_client.delete(pvc) + cluster_client.delete(pv) + + +def delete_pvc(client, pvc, ns): + pvcname = pvc['name'] + print(pvcname) + client.delete(pvc) + # Sleep to allow PVC to be deleted + time.sleep(5) + timeout = 30 + pvcdict = client.list_persistentVolumeClaim(name=pvcname) + start = time.time() + if len(pvcdict.get('data')) > 0: + testdata = pvcdict.get('data') + print(testdata) + while pvcname in testdata[0]: + if time.time() - start > timeout: + raise AssertionError("Timed out waiting for deletion") + time.sleep(.5) + pvcdict = client.list_persistentVolumeClaim(name=pvcname) + testdata = pvcdict.get('data') + assert True + assert len(pvcdict.get('data')) == 0, "Failed to delete the PVC" + + # Verify pvc is deleted by "kubectl get pvc" command + command = "get pvc {} --namespace {}".format(pvc['name'], ns.name) + print("Command to obtain the pvc") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + + print("Verify that the pvc does not exist " + "and the error code returned is non zero ") + assert result != 0, "Result should be a non zero value" + + +def delete_pv(cluster_client, pv): + pvname = pv['name'] + print(pvname) + cluster_client.delete(pv) + # Sleep to allow PVC to be deleted + time.sleep(5) + timeout = 30 + pvdict = cluster_client.list_persistent_volume(name=pvname) + print(pvdict) + start = time.time() + if len(pvdict.get('data')) > 0: + testdata = pvdict.get('data') + print(testdata) + while pvname in testdata[0]: + if time.time() - start > timeout: + raise AssertionError("Timed out waiting for deletion") + time.sleep(.5) + pvcdict = cluster_client.list_persistent_volume(name=pvname) + testdata = pvcdict.get('data') + assert True + assert len(pvdict.get('data')) == 0, "Failed to delete the PV" + + # Verify pv is deleted by "kubectl get pv" command + command = "get pv {} ".format(pv['name']) + print("Command to obtain the pvc") + print(command) + result = execute_kubectl_cmd(command, json_out=False, stderr=True) + print(result) + print("Verify that the pv does not exist " + "and the error code returned is non zero ") + assert result != 0, "Result should be a non zero value" + + +def edit_pv(client, nfs_ip, cluster_owner_client): + pv = create_pv(cluster_owner_client, nfs_ip) + + updated_pv_config = { + "type": "persistentVolume", + "accessModes": ["ReadWriteOnce"], + "name": pv['name'], + "nfs": {"readOnly": "false", + "type": "nfsvolumesource", + "path": NFS_SERVER_MOUNT_PATH, + "server": nfs_ip + }, + "capacity": {"storage": "20Gi"} + } + updated_pv = client.update(pv, updated_pv_config) + capacitydict = updated_pv['capacity'] + assert capacitydict['storage'] == '20Gi' + assert pv['type'] == 'persistentVolume' + cluster_owner_client.delete(updated_pv) + + +@pytest.fixture(scope="module", autouse="True") +def volumes_setup(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + project, ns = create_project_and_ns(USER_TOKEN, cluster, "project-volumes") + p_client = get_project_client_for_token(project, USER_TOKEN) + nfs_node = provision_nfs_server() + nfs_ip = nfs_node.get_public_ip() + print("IP of the NFS Server: ", nfs_ip) + + # add persistent volume to the cluster + cluster_client = get_cluster_client_for_token(cluster, USER_TOKEN) + + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = project + namespace["nfs_ip"] = nfs_ip + namespace["cluster_client"] = cluster_client + + def fin(): + cluster_client = get_cluster_client_for_token(namespace["cluster"], + USER_TOKEN) + cluster_client.delete(namespace["project"]) + cluster_client.delete(namespace["pv"]) + if DELETE_NFS is True: + AmazonWebServices().delete_node(nfs_node) + request.addfinalizer(fin) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_websocket.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_websocket.py new file mode 100644 index 0000000..8e3876d --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_websocket.py @@ -0,0 +1,152 @@ +import base64 +import pytest +import time +import urllib +from .common import CATTLE_TEST_URL +from .common import USER_TOKEN +from .common import TEST_IMAGE +from .common import create_kubeconfig +from .common import create_connection +from .common import create_project_and_ns +from .common import get_user_client_and_cluster +from .common import get_project_client_for_token +from .common import random_test_name +from .common import validate_workload +from .common import WebsocketLogParse + +namespace = {"cluster": None, "shell_url": None, "pod": None, "ns": ""} + + +def test_websocket_launch_kubectl(): + ws = create_connection(namespace["shell_url"], ["base64.channel.k8s.io"]) + logparse = WebsocketLogParse() + logparse.start_thread(target=logparse.receiver, args=(ws, True)) + + cmd = "kubectl version" + checks = ["Client Version", "Server Version"] + validate_command_execution(ws, cmd, logparse, checks) + logparse.last_message = '' + + cmd = "kubectl get ns -o name" + checks = ["namespace/kube-system"] + validate_command_execution(ws, cmd, logparse, checks) + logparse.last_message = '' + + ws.close() + + +def test_websocket_exec_shell(): + url_base = 'wss://' + CATTLE_TEST_URL[8:] + \ + '/k8s/clusters/' + namespace["cluster"].id + \ + '/api/v1/namespaces/' + namespace["ns"] + \ + '/pods/' + namespace["pod"].name + \ + '/exec?container=' + namespace["pod"].containers[0].name + params_dict = { + "stdout": 1, + "stdin": 1, + "stderr": 1, + "tty": 1, + "command": [ + '/bin/sh', + '-c', + 'TERM=xterm-256color; export TERM; [ -x /bin/bash ] && ([ -x ' + '/usr/bin/script ] && /usr/bin/script -q -c "/bin/bash" ' + '/dev/null || exec /bin/bash) || exec /bin/sh ' + ] + } + params = urllib.parse.urlencode(params_dict, doseq=True, + quote_via=urllib.parse.quote, safe='()') + url = url_base + "&" + params + ws = create_connection(url, ["base64.channel.k8s.io"]) + logparse = WebsocketLogParse() + logparse.start_thread(target=logparse.receiver, args=(ws, True)) + + cmd = "ls" + checks = ["bin", "boot", "dev"] + validate_command_execution(ws, cmd, logparse, checks) + logparse.last_message = '' + + ws.close() + + +def test_websocket_view_logs(): + url_base = 'wss://' + CATTLE_TEST_URL[8:] + \ + '/k8s/clusters/' + namespace["cluster"].id + \ + '/api/v1/namespaces/' + namespace["ns"] + \ + '/pods/' + namespace["pod"].name + \ + '/log?container=' + namespace["pod"].containers[0].name + params_dict = { + "tailLines": 500, + "follow": True, + "timestamps": True, + "previous": False, + } + params = urllib.parse.urlencode(params_dict, doseq=True, + quote_via=urllib.parse.quote, safe='()') + url = url_base + "&" + params + ws = create_connection(url, ["base64.binary.k8s.io"]) + logparse = WebsocketLogParse() + logparse.start_thread(target=logparse.receiver, args=(ws, False)) + + print('\noutput:\n' + logparse.last_message + '\n') + assert 'websocket' in logparse.last_message, \ + "failed to view logs" + logparse.last_message = '' + + ws.close() + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + project, ns = create_project_and_ns(USER_TOKEN, + cluster, + random_test_name("websocket")) + p_client = get_project_client_for_token(project, USER_TOKEN) + con = [{"name": random_test_name(), + "image": TEST_IMAGE, + "entrypoint": ["/bin/sh"], + "command": ["-c", + "while true; do echo websocket; sleep 1s; done;" + ], + }] + wl = p_client.create_workload(name=random_test_name(), + containers=con, + namespaceId=ns.id) + validate_workload(p_client, wl, "deployment", ns.name) + pod = p_client.list_pod(workloadId=wl.id).data[0] + namespace["ns"] = ns.name + namespace["pod"] = pod + namespace["cluster"] = cluster + namespace["shell_url"] = cluster.get("links").get("shell") + + def fin(): + client.delete(project) + + request.addfinalizer(fin) + + +def send_a_command(ws_connection, command): + cmd_enc = base64.b64encode(command.encode('utf-8')).decode('utf-8') + ws_connection.send('0' + cmd_enc) + # sends the command to the webSocket + ws_connection.send('0DQ==') + time.sleep(5) + + +def validate_command_execution(websocket, command, log_obj, checking): + """ + validate that a command is send via the websocket + and the response contains expected results + :param websocket: the websocket object + :param command: the command to run + :param log_obj: the logparse object to receive the message + :param checking: the list of string to be checked in the response message + :return: + """ + + send_a_command(websocket, command) + print('\nshell command and output:\n' + log_obj.last_message + '\n') + for i in checking: + assert i in log_obj.last_message, "failed to run the command" diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_windows_cluster.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_windows_cluster.py new file mode 100644 index 0000000..22ded48 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_windows_cluster.py @@ -0,0 +1,67 @@ +from .common import TEST_IMAGE +from .common import TEST_IMAGE_REDIS +from .common import TEST_IMAGE_OS_BASE +from .common import cluster_cleanup +from .common import get_user_client +from .common import random_test_name +from .test_rke_cluster_provisioning import create_custom_host_from_nodes +from .test_rke_cluster_provisioning import HOST_NAME + +from lib.aws import AmazonWebServices, AWS_DEFAULT_AMI, AWS_DEFAULT_USER + + +def provision_windows_nodes(): + node_roles_linux = [["controlplane"], ["etcd"], ["worker"]] + node_roles_windows = [["worker"], ["worker"], ["worker"]] + + win_nodes = \ + AmazonWebServices().create_multiple_nodes( + len(node_roles_windows), random_test_name(HOST_NAME)) + + linux_nodes = \ + AmazonWebServices().create_multiple_nodes( + len(node_roles_linux), random_test_name(HOST_NAME), + ami=AWS_DEFAULT_AMI, ssh_user=AWS_DEFAULT_USER) + + nodes = linux_nodes + win_nodes + node_roles = node_roles_linux + node_roles_windows + + for node in win_nodes: + pull_images(node) + + return nodes, node_roles + + +def test_windows_provisioning_vxlan(): + nodes, node_roles = provision_windows_nodes() + + cluster, nodes = create_custom_host_from_nodes(nodes, node_roles, + random_cluster_name=True, + windows=True, + windows_flannel_backend='vxlan') + + cluster_cleanup(get_user_client(), cluster, nodes) + + +def test_windows_provisioning_gw_host(): + nodes, node_roles = provision_windows_nodes() + + for node in nodes: + AmazonWebServices().disable_source_dest_check(node.provider_node_id) + + cluster, nodes = create_custom_host_from_nodes(nodes, node_roles, + random_cluster_name=True, + windows=True, + windows_flannel_backend='host-gw') + + cluster_cleanup(get_user_client(), cluster, nodes) + + +def pull_images(node): + print("Pulling images on node: " + node.host_name) + pull_result = node.execute_command("docker pull " + TEST_IMAGE + + " && " + + "docker pull " + TEST_IMAGE_REDIS + + " && " + + "docker pull " + TEST_IMAGE_OS_BASE) + print(pull_result) diff --git a/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_workload.py b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_workload.py new file mode 100644 index 0000000..4ca19d9 --- /dev/null +++ b/on-premise/main/rancher_v2.9.1/source/rancher-2.9.1/tests/validation/tests/v3_api/test_workload.py @@ -0,0 +1,1143 @@ +import pytest + +from .common import * # NOQA +from rancher import ApiError + +namespace = {"p_client": None, "ns": None, "cluster": None, "project": None} +RBAC_ROLES = [CLUSTER_OWNER, PROJECT_MEMBER, PROJECT_OWNER, + PROJECT_READ_ONLY, CLUSTER_MEMBER] +WORKLOAD_TYPES = ["daemonSet", "statefulSet", "cronJob", "job"] + +if_check_lb = os.environ.get('RANCHER_CHECK_FOR_LB', "False") +if_check_lb = pytest.mark.skipif( + if_check_lb != "True", + reason='Lb test case skipped') + +ENABLE_HOST_NODE_PORT_TESTS = ast.literal_eval( + os.environ.get('RANCHER_ENABLE_HOST_NODE_PORT_TESTS', "True")) +skip_host_node_port = pytest.mark.skipif( + not ENABLE_HOST_NODE_PORT_TESTS, + reason='Tests Skipped for AKS,GKE,EKS Clusters') + +#Converted to go test in TestWorkloadSideKick +def test_wl_sidekick(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("sidekick") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + validate_workload(p_client, workload, "deployment", ns.name) + + side_con = {"name": "test2", + "image": TEST_IMAGE_REDIS, + "stdin": True, + "tty": True} + con.append(side_con) + workload = p_client.update(workload, + containers=con) + time.sleep(90) + validate_workload_with_sidekicks( + p_client, workload, "deployment", ns.name) + +#Converted to go test in TestWorkloadDeployment +def test_wl_deployment(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + validate_workload(p_client, workload, "deployment", ns.name) + + +def test_wl_statefulset(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + statefulSetConfig={} + ) + validate_workload(p_client, workload, "statefulSet", ns.name) + +#Converted to go test in TestWorkloadDaemonSet +def test_wl_daemonset(): + p_client = namespace["p_client"] + ns = namespace["ns"] + cluster = namespace["cluster"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + schedulable_node_count = len(get_schedulable_nodes(cluster)) + validate_workload(p_client, workload, "daemonSet", + ns.name, schedulable_node_count) + + +def test_wl_cronjob(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + cronJobConfig={ + "concurrencyPolicy": "Allow", + "failedJobsHistoryLimit": 10, + "schedule": "*/1 * * * *", + "successfulJobsHistoryLimit": 10}) + validate_workload(p_client, workload, "cronJob", ns.name) + + +def test_wl_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + revisions = workload.revisions() + assert len(revisions) == 1 + for revision in revisions: + if revision["containers"][0]["image"] == TEST_IMAGE: + firstrevision = revision.id + + con = [{"name": "test1", + "image": TEST_IMAGE_REDIS}] + p_client.update(workload, containers=con) + wait_for_pod_images(p_client, workload, ns.name, TEST_IMAGE_REDIS, 2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, TEST_IMAGE_REDIS, ns) + revisions = workload.revisions() + assert len(revisions) == 2 + for revision in revisions: + if revision["containers"][0]["image"] == TEST_IMAGE_REDIS: + secondrevision = revision.id + + con = [{"name": "test1", + "image": TEST_IMAGE_OS_BASE, + "tty": True, + "stdin": True}] + p_client.update(workload, containers=con) + wait_for_pod_images(p_client, workload, ns.name, TEST_IMAGE_OS_BASE, 2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, TEST_IMAGE_OS_BASE, ns) + revisions = workload.revisions() + assert len(revisions) == 3 + for revision in revisions: + if revision["containers"][0]["image"] == TEST_IMAGE_OS_BASE: + thirdrevision = revision.id + + p_client.action(workload, "rollback", replicaSetId=firstrevision) + wait_for_pod_images(p_client, workload, ns.name, TEST_IMAGE, 2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, TEST_IMAGE, ns) + + p_client.action(workload, "rollback", replicaSetId=secondrevision) + wait_for_pod_images(p_client, workload, ns.name, TEST_IMAGE_REDIS, 2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, TEST_IMAGE_REDIS, ns) + + p_client.action(workload, "rollback", replicaSetId=thirdrevision) + wait_for_pod_images(p_client, workload, ns.name, TEST_IMAGE_OS_BASE, 2) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, TEST_IMAGE_OS_BASE, ns) + + +def test_wl_pod_scale_up(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + workload = wait_for_wl_to_active(p_client, workload) + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns.name + allpods = execute_kubectl_cmd(get_pods) + wait_for_pods_in_workload(p_client, workload, 1) + + p_client.update(workload, scale=2, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_pods_are_running_by_id(allpods, workload, ns.name) + + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + allpods = execute_kubectl_cmd(get_pods) + wait_for_pods_in_workload(p_client, workload, 2) + p_client.update(workload, scale=3, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 3) + validate_pods_are_running_by_id(allpods, workload, ns.name) + + +def test_wl_pod_scale_down(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=3) + wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 3) + + p_client.update(workload, scale=2, containers=con) + wait_for_pods_in_workload(p_client, workload, 2) + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + get_pods = "get pods -l" + label + " -n " + ns.name + allpods = execute_kubectl_cmd(get_pods) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_pods_are_running_by_id(allpods, workload, ns.name) + + p_client.update(workload, scale=1, containers=con) + wait_for_pods_in_workload(p_client, workload, 1) + for key, value in workload.workloadLabels.items(): + label = key + "=" + value + allpods = execute_kubectl_cmd(get_pods) + validate_workload(p_client, workload, "deployment", ns.name) + validate_pods_are_running_by_id(allpods, workload, ns.name) + + +def test_wl_pause_orchestration(): + p_client = namespace["p_client"] + ns = namespace["ns"] + con = [{"name": "test1", + "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=2) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + p_client.action(workload, "pause") + validate_workload_paused(p_client, workload, True) + con = [{"name": "test1", + "image": TEST_IMAGE_REDIS}] + p_client.update(workload, containers=con) + validate_pod_images(TEST_IMAGE, workload, ns.name) + p_client.action(workload, "resume") + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_workload_paused(p_client, workload, False) + validate_pod_images(TEST_IMAGE_REDIS, workload, ns.name) + + +# Windows could not support host port for now. +@skip_test_windows_os +@skip_host_node_port +def test_wl_with_hostPort(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 9999 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "HostPort", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("default") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + workload = wait_for_wl_to_active(p_client, workload) + validate_hostPort(p_client, workload, source_port, namespace["cluster"]) + + +@skip_host_node_port +def test_wl_with_nodePort(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 30456 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "NodePort", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("default") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + + workload = wait_for_wl_to_active(p_client, workload) + validate_nodePort(p_client, workload, namespace["cluster"], source_port) + + +def test_wl_with_clusterIp(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 30458 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "ClusterIP", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("default") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + workload = wait_for_wl_to_active(p_client, workload) + + # Get cluster Ip + sd_records = p_client.list_dns_record(name=name).data + assert len(sd_records) == 1 + cluster_ip = sd_records[0].clusterIp + + # Deploy test pods used for clusteIp resolution check + wlname = random_test_name("testclusterip-client") + con = [{"name": "test1", + "image": TEST_IMAGE}] + + workload_for_test = p_client.create_workload(name=wlname, + containers=con, + namespaceId=ns.id, + scale=2) + wait_for_wl_to_active(p_client, workload_for_test) + test_pods = wait_for_pods_in_workload(p_client, workload_for_test, 2) + validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port) + + +@if_check_lb +def test_wl_with_lb(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 9001 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "LoadBalancer", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("default") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + workload = wait_for_wl_to_active(p_client, workload) + validate_lb(p_client, workload, source_port) + + +def test_wl_with_clusterIp_scale_and_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 30459 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "ClusterIP", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test-cluster-ip", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("cluster-ip-scale-upgrade") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=1) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + sd_records = p_client.list_dns_record(name=name).data + assert len(sd_records) == 1 + cluster_ip = sd_records[0].clusterIp + # get test pods + wlname = random_test_name("testclusterip-client") + wl_con = [{"name": "test1", "image": TEST_IMAGE}] + workload_for_test = p_client.create_workload(name=wlname, + containers=wl_con, + namespaceId=ns.id, + scale=2) + wait_for_wl_to_active(p_client, workload_for_test) + test_pods = wait_for_pods_in_workload(p_client, workload_for_test, 2) + validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port) + + # scale up + p_client.update(workload, scale=3, caontainers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 3) + validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port) + + # scale down + p_client.update(workload, scale=2, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port) + # upgrade + con = [{"name": "test-cluster-ip-upgrade-new", + "image": TEST_IMAGE, + "ports": [port]}] + p_client.update(workload, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_clusterIp(p_client, workload, cluster_ip, test_pods, source_port) + + +@skip_host_node_port +def test_wl_with_nodePort_scale_and_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 30457 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "NodePort", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("test-node-port-scale-upgrade") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=1) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + validate_nodePort(p_client, workload, namespace["cluster"], source_port) + + # scale up + p_client.update(workload, scale=3, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 3) + validate_nodePort(p_client, workload, namespace["cluster"], source_port) + + # scale down + p_client.update(workload, scale=2, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_nodePort(p_client, workload, namespace["cluster"], source_port) + + # upgrade + con = [{"name": "test-node-port-scale-upgrade-new", + "image": TEST_IMAGE, + "ports": [port]}] + p_client.update(workload, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_nodePort(p_client, workload, namespace["cluster"], source_port) + + +# Windows could not support host port for now. +@skip_test_windows_os +@skip_host_node_port +def test_wl_with_hostPort_scale_and_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 8888 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "HostPort", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test-host-port-upgrade", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("hostport-scale") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=1) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + validate_hostPort(p_client, workload, source_port, namespace["cluster"]) + + # scale up + p_client.update(workload, scale=2, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_hostPort(p_client, workload, source_port, namespace["cluster"]) + + # scale down + p_client.update(workload, scale=1, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + validate_hostPort(p_client, workload, source_port, namespace["cluster"]) + # From my observation, it is necessary to wait until + # the number of pod equals to the expected number, + # since the workload's state is 'active' but pods + # are not ready yet especially after scaling down and upgrading. + + # upgrade + con = [{"name": "test-host-port-upgrade-new", + "image": TEST_IMAGE, + "ports": [port]}] + p_client.update(workload, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + validate_hostPort(p_client, workload, source_port, namespace["cluster"]) + + +@if_check_lb +def test_wl_with_lb_scale_and_upgrade(): + p_client = namespace["p_client"] + ns = namespace["ns"] + source_port = 9001 + port = {"containerPort": TEST_IMAGE_PORT, + "type": "containerPort", + "kind": "LoadBalancer", + "protocol": "TCP", + "sourcePort": source_port} + con = [{"name": "test1", + "image": TEST_IMAGE, + "ports": [port]}] + name = random_test_name("lb-scale-upgrade") + + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + scale=1) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 1) + validate_lb(p_client, workload, source_port) + + # scale up + p_client.update(workload, scale=3, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 3) + validate_lb(p_client, workload, source_port) + + # scale down + p_client.update(workload, scale=2, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_lb(p_client, workload, source_port) + + # upgrade + con = [{"name": "test-load-balance-upgrade-new", + "image": TEST_IMAGE, + "ports": [port]}] + p_client.update(workload, containers=con) + workload = wait_for_wl_to_active(p_client, workload) + wait_for_pods_in_workload(p_client, workload, 2) + validate_lb(p_client, workload, source_port) + + +# --------------------- rbac tests for cluster owner ----------------------- +@if_test_rbac +def test_rbac_cluster_owner_wl_create(remove_resource): + # cluster owner can create project and deploy workload in it + p_client, project, ns, workload = setup_project_by_role(CLUSTER_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + + +@if_test_rbac +def test_rbac_cluster_owner_wl_create_2(remove_resource): + # cluster owner can deploy workload in any project in the cluster + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p2 = rbac_get_unshared_project() + p_client2 = get_project_client_for_token(p2, user_token) + ns2 = rbac_get_unshared_ns() + name = random_test_name("default") + con = [{"name": "test1", + "image": TEST_IMAGE}] + wl = p_client2.create_workload(name=name, containers=con, + namespaceId=ns2.id) + validate_workload(p_client2, wl, "deployment", ns2.name) + + remove_resource(wl) + + +@if_test_rbac +def test_rbac_cluster_owner_wl_edit(remove_resource): + p_client, project, ns, workload = setup_project_by_role(CLUSTER_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # cluster owner can edit workload in the project + p_client.update(workload, scale=2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + con = [{"name": "test1", + "image": "nginx"}] + p_client.update(workload, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, "nginx", ns) + + +@if_test_rbac +def test_rbac_cluster_owner_wl_delete(remove_resource): + p_client, project, ns, workload = setup_project_by_role(CLUSTER_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # cluster owner can delete workload in the project + p_client.delete(workload) + assert len(p_client.list_workload(uuid=workload.uuid).data) == 0 + + +# --------------------- rbac tests for cluster member ----------------------- +@if_test_rbac +def test_rbac_cluster_member_wl_create(remove_resource): + # cluster member can create project and deploy workload in it + p_client, project, ns, workload = setup_project_by_role(CLUSTER_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + + +@if_test_rbac +def test_rbac_cluster_member_wl_create_2(): + user_token = rbac_get_user_token_by_role(CLUSTER_MEMBER) + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + # cluster member can NOT deploy workload in the project he can NOT access + with pytest.raises(ApiError) as e: + p2 = rbac_get_unshared_project() + ns2 = rbac_get_unshared_ns() + new_p_client = get_project_client_for_token(p2, user_token) + new_p_client.create_workload(name=name, containers=con, + namespaceId=ns2.id) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_cluster_member_wl_edit(remove_resource): + p_client, project, ns, workload = setup_project_by_role(CLUSTER_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # cluster member can edit workload in the project + p_client.update(workload, scale=2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + con = [{"name": "test1", "image": "nginx"}] + p_client.update(workload, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, "nginx", ns) + + +@if_test_rbac +def test_rbac_cluster_member_wl_delete(remove_resource): + p_client, project, ns, workload = setup_project_by_role(CLUSTER_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # cluster member can delete workload in the project + p_client.delete(workload) + assert len(p_client.list_workload(uuid=workload.uuid).data) == 0 + + +# --------------------- rbac tests for project member ----------------------- +@if_test_rbac +def test_rbac_project_member_wl_create(remove_resource): + # project member can deploy workload in his project + p_client, project, ns, workload = setup_project_by_role(PROJECT_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + + +@if_test_rbac +def test_rbac_project_member_wl_create_2(): + # project member can NOT deploy workload in the project he can NOT access + user_token = rbac_get_user_token_by_role(PROJECT_MEMBER) + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + with pytest.raises(ApiError) as e: + p2 = rbac_get_unshared_project() + ns2 = rbac_get_unshared_ns() + new_p_client = get_project_client_for_token(p2, user_token) + new_p_client.create_workload(name=name, containers=con, + namespaceId=ns2.id) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_project_member_wl_edit(remove_resource): + p_client, project, ns, workload = setup_project_by_role(PROJECT_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # project member can edit workload in the project + p_client.update(workload, scale=2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + con = [{"name": "test1", "image": "nginx"}] + p_client.update(workload, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, "nginx", ns) + + +@if_test_rbac +def test_rbac_project_member_wl_delete(remove_resource): + p_client, project, ns, workload = setup_project_by_role(PROJECT_MEMBER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # project member can delete workload in the project + p_client.delete(workload) + assert len(p_client.list_workload(uuid=workload.uuid).data) == 0 + + +# --------------------- rbac tests for project owner ----------------------- +@if_test_rbac +def test_rbac_project_owner_wl_create(remove_resource): + # project owner can deploy workload in his project + p_client, project, ns, workload = setup_project_by_role(PROJECT_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + + +@if_test_rbac +def test_rbac_project_owner_wl_create_2(): + # project owner can NOT deploy workload in the project he can NOT access + user_token = rbac_get_user_token_by_role(PROJECT_OWNER) + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + with pytest.raises(ApiError) as e: + p2 = rbac_get_unshared_project() + ns2 = rbac_get_unshared_ns() + new_p_client = get_project_client_for_token(p2, user_token) + new_p_client.create_workload(name=name, containers=con, + namespaceId=ns2.id) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_project_owner_wl_edit(remove_resource): + p_client, project, ns, workload = setup_project_by_role(PROJECT_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # project owner can edit workload in his project + p_client.update(workload, scale=2) + validate_workload(p_client, workload, "deployment", ns.name, 2) + con = [{"name": "test1", "image": "nginx"}] + p_client.update(workload, containers=con) + validate_workload(p_client, workload, "deployment", ns.name, 2) + validate_workload_image(p_client, workload, "nginx", ns) + + +@if_test_rbac +def test_rbac_project_owner_wl_delete(remove_resource): + p_client, project, ns, workload = setup_project_by_role(PROJECT_OWNER, + remove_resource) + validate_workload(p_client, workload, "deployment", ns.name) + # project owner can delete workload in his project + p_client.delete(workload) + assert len(p_client.list_workload(uuid=workload.uuid).data) == 0 + + +# --------------------- rbac tests for project read-only -------------------- +@if_test_rbac +def test_rbac_project_read_only_wl_create(): + # project read-only can NOT deploy workloads in the project + project = rbac_get_project() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + p_client = get_project_client_for_token(project, user_token) + ns = rbac_get_namespace() + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + with pytest.raises(ApiError) as e: + p_client.create_workload(name=name, containers=con, + namespaceId=ns.id) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +def test_rbac_project_read_only_wl_edit(remove_resource): + project = rbac_get_project() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + p_client = get_project_client_for_token(project, user_token) + # deploy a workload as cluster owner + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_p_client = get_project_client_for_token(project, + cluster_owner_token) + ns = rbac_get_namespace() + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + workload = cluster_owner_p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id) + # project read-only can NOT edit existing workload + with pytest.raises(ApiError) as e: + p_client.update(workload, scale=2) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + remove_resource(workload) + + +@if_test_rbac +def test_rbac_project_read_only_wl_list(): + # project read-only can NOT see workloads in the project he has no access + p2 = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(PROJECT_READ_ONLY) + p_client = get_project_client_for_token(p2, user_token) + workloads = p_client.list_workload().data + assert len(workloads) == 0 + + +@pytest.fixture(scope='module', autouse="True") +def create_project_client(request): + client, cluster = get_user_client_and_cluster() + create_kubeconfig(cluster) + p, ns = create_project_and_ns( + USER_TOKEN, cluster, random_test_name("testworkload")) + p_client = get_project_client_for_token(p, USER_TOKEN) + namespace["p_client"] = p_client + namespace["ns"] = ns + namespace["cluster"] = cluster + namespace["project"] = p + + def fin(): + client = get_user_client() + client.delete(namespace["project"]) + request.addfinalizer(fin) + + +def setup_project_by_role(role, remove_resource): + """ set up a project for a specific role used for rbac testing + + - for cluster owner or cluster member: + it creates a project and namespace, then deploys a workload + - for project owner or project member: + it deploys a workload to the existing project and namespace + """ + user_token = rbac_get_user_token_by_role(role) + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + + if role in [CLUSTER_OWNER, CLUSTER_MEMBER]: + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("test-rbac")) + p_client = get_project_client_for_token(project, user_token) + workload = p_client.create_workload(name=name, containers=con, + namespaceId=ns.id) + + remove_resource(project) + remove_resource(ns) + remove_resource(workload) + return p_client, project, ns, workload + + elif role in [PROJECT_OWNER, PROJECT_MEMBER]: + project = rbac_get_project() + ns = rbac_get_namespace() + p_client = get_project_client_for_token(project, user_token) + workload = p_client.create_workload(name=name, containers=con, + namespaceId=ns.id) + + remove_resource(workload) + return p_client, project, ns, workload + + else: + return None, None, None, None + +# --------------------- rbac tests by workload types ----------------------- + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametarize_create(role, config, remove_resource): + p_client, project, ns = setup_wl_project_by_role(role) + cluster = namespace["cluster"] + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + if role != PROJECT_READ_ONLY: + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + remove_resource(workload) + if role == CLUSTER_MEMBER: + remove_resource(project) + return None + else: + with pytest.raises(ApiError) as e: + workload = create_workload_by_type(p_client, name, con, ns, config) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_create_negative(role, remove_resource, config): + if role == CLUSTER_OWNER: + # cluster owner can deploy workloads in any project in the cluster + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p2 = rbac_get_unshared_project() + p_client2 = get_project_client_for_token(p2, user_token) + ns2 = rbac_get_unshared_ns() + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + wl = create_workload_by_type(p_client2, name, con, ns2, config) + wait_for_wl_to_active(p_client2, wl) + remove_resource(wl) + else: + # roles cannot deploy workloads in projects they cannot access + user_token = rbac_get_user_token_by_role(role) + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + with pytest.raises(ApiError) as e: + p2 = rbac_get_unshared_project() + ns2 = rbac_get_unshared_ns() + new_p_client = get_project_client_for_token(p2, user_token) + workload = create_workload_by_type(new_p_client, name, con, ns2, config) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_list(role, remove_resource, config): + if role == CLUSTER_MEMBER: + p_client, project, ns = setup_wl_project_by_role(role) + else: + p_client, project, ns = setup_wl_project_by_role(CLUSTER_OWNER) + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + # switch to rbac role + user_token = rbac_get_user_token_by_role(role) + p_client_rbac = get_project_client_for_token(project, user_token) + assert len(p_client_rbac.list_workload(uuid=workload.uuid).data) == 1 + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_list_negative(role, remove_resource, config): + unshared_project = rbac_get_unshared_project() + ns = rbac_get_unshared_ns() + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p_client = get_project_client_for_token(unshared_project, user_token) + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + workload = p_client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + wait_for_wl_to_active(p_client, workload) + + # switch to rbac role + user_token = rbac_get_user_token_by_role(role) + p_client_rbac = get_project_client_for_token(unshared_project, user_token) + if role != CLUSTER_OWNER: + assert len(p_client_rbac.list_workload(uuid=workload.uuid).data) == 0 + else: + assert len(p_client_rbac.list_workload(uuid=workload.uuid).data) == 1 + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_update(role, remove_resource, config): + # workloads of type job cannot be edited + if config == "job": + return + p_client, project, ns = setup_wl_project_by_role(role) + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + if role != PROJECT_READ_ONLY: + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + con = [{"name": "test1", "image": os.environ.get('RANCHER_TEST_IMAGE', + "nginx")}] + p_client.update(workload, containers=con) + remove_resource(workload) + if role == CLUSTER_MEMBER: + remove_resource(project) + else: + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p_client = get_project_client_for_token(project, user_token) + ns = rbac_get_namespace() + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + with pytest.raises(ApiError) as e: + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(project, user_token) + con = [{"name": "test1", "image": os.environ.get('RANCHER_TEST_IMAGE', + "nginx")}] + p_client.update(workload, containers=con) + wait_for_pods_in_workload(p_client, workload) + validate_workload(p_client, workload, config, ns.name) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_update_negative(role, remove_resource, config): + # workloads of type job cannot be edited + if config == "job": + return + if role == CLUSTER_OWNER: + # cluster owner can edit workloads in any project in the cluster + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p_client, project, ns = setup_wl_project_by_role(role) + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + con = [{"name": "test1", "image": "nginx"}] + p_client.update(workload, containers=con) + remove_resource(workload) + else: + project2 = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(role) + # roles cannot edit workloads in projects they cannot access + # deploy a workload as cluster owner + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_p_client = get_project_client_for_token( + project2, cluster_owner_token) + ns = rbac_get_unshared_ns() + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + workload = create_workload_by_type(cluster_owner_p_client, + name, con, ns, config) + with pytest.raises(ApiError) as e: + p_client = get_project_client_for_token(project2, user_token) + con = [{"name": "test1", "image": "nginx"}] + p_client.update(workload, containers=con) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(workload) + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_delete(role, remove_resource, config): + p_client, project, ns = setup_wl_project_by_role(role) + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + if role != PROJECT_READ_ONLY: + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + p_client.delete(workload) + assert len(p_client.list_workload(uuid=workload.uuid).data) == 0 + remove_resource(workload) + else: + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + p_client = get_project_client_for_token(project, user_token) + ns = rbac_get_namespace() + workload = create_workload_by_type(p_client, name, con, ns, config) + wait_for_wl_to_active(p_client, workload) + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(project, user_token) + with pytest.raises(ApiError) as e: + p_client.delete(workload) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(workload) + if role == CLUSTER_MEMBER: + remove_resource(project) + + +@if_test_rbac +@pytest.mark.parametrize("role", RBAC_ROLES) +@pytest.mark.parametrize("config", WORKLOAD_TYPES) +def test_rbac_wl_parametrize_delete_negative(role, remove_resource, config): + if role == CLUSTER_OWNER: + # cluster owner can delete workloads in any project in the cluster + user_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + project = rbac_get_unshared_project() + p_client = get_project_client_for_token(project, user_token) + ns = rbac_get_namespace() + name = random_test_name("default") + con = [{"name": "test1", "image": TEST_IMAGE}] + workload = create_workload_by_type(p_client, name, con, ns, config) + p_client.delete(workload) + else: + project = rbac_get_unshared_project() + user_token = rbac_get_user_token_by_role(role) + # roles cannot delete workloads in projects they cannot access + # deploy a workload as cluster owner + cluster_owner_token = rbac_get_user_token_by_role(CLUSTER_OWNER) + cluster_owner_p_client = get_project_client_for_token( + project, cluster_owner_token) + ns = rbac_get_unshared_ns() + con = [{"name": "test1", "image": TEST_IMAGE}] + name = random_test_name("default") + workload = create_workload_by_type(cluster_owner_p_client, + name, con, ns, config) + p_client = get_project_client_for_token(project, user_token) + with pytest.raises(ApiError) as e: + p_client.delete(workload) + assert e.value.error.status == 403 + assert e.value.error.code == 'Forbidden' + remove_resource(workload) + + +def setup_wl_project_by_role(role): + if role == CLUSTER_MEMBER: + user_token = rbac_get_user_token_by_role(role) + project, ns = create_project_and_ns(user_token, namespace["cluster"], + random_test_name("test-rbac")) + p_client = get_project_client_for_token(project, user_token) + return p_client, project, ns + else: + project = rbac_get_project() + user_token = rbac_get_user_token_by_role(role) + p_client = get_project_client_for_token(project, user_token) + ns = rbac_get_namespace() + return p_client, project, ns + +def create_workload_by_type(client, name, con, ns, config): + if config == "daemonSet": + return client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + daemonSetConfig={}) + elif config == "statefulSet": + return client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + statefulSetConfig={}) + elif config == "cronJob": + return client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + cronJobConfig={ + "concurrencyPolicy": "Allow", + "failedJobsHistoryLimit": 10, + "schedule": "*/1 * * * *", + "successfulJobsHistoryLimit": 10}) + elif config == "job": + return client.create_workload(name=name, + containers=con, + namespaceId=ns.id, + jobConfig={}) \ No newline at end of file diff --git a/on-premise/main/rancher_v2.9.1/source/v2.9.1.tar.gz b/on-premise/main/rancher_v2.9.1/source/v2.9.1.tar.gz new file mode 100644 index 0000000..1df12f1 Binary files /dev/null and b/on-premise/main/rancher_v2.9.1/source/v2.9.1.tar.gz differ